diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 65bbd26..2214f12 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -7,8 +7,8 @@ Please try and keep the descriptions small enough to fit on one line.
 
 Following translations are available on the WWW:
 
-   - Japanese, maintained by the JF Project (JF@linux.or.jp), at
-     http://www.linux.or.jp/JF/
+   - Japanese, maintained by the JF Project (jf@listserv.linux.or.jp), at
+     http://linuxjf.sourceforge.jp/
 
 00-INDEX
 	- this file.
@@ -104,6 +104,8 @@ cpuidle/
 	- info on CPU_IDLE, CPU idle state management subsystem.
 cputopology.txt
 	- documentation on how CPU topology info is exported via sysfs.
+crc32.txt
+	- brief tutorial on CRC computation
 cris/
 	- directory with info about Linux on CRIS architecture.
 crypto/
diff --git a/Documentation/ABI/removed/devfs b/Documentation/ABI/removed/devfs
index 8ffd28b..0020c49 100644
--- a/Documentation/ABI/removed/devfs
+++ b/Documentation/ABI/removed/devfs
@@ -1,6 +1,6 @@
 What:		devfs
 Date:		July 2005 (scheduled), finally removed in kernel v2.6.18
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 	devfs has been unmaintained for a number of years, has unfixable
 	races, contains a naming policy within the kernel that is
diff --git a/Documentation/ABI/stable/sysfs-driver-usb-usbtmc b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc
index 9a75fb2..23a43b8 100644
--- a/Documentation/ABI/stable/sysfs-driver-usb-usbtmc
+++ b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc
@@ -1,7 +1,7 @@
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities
 Date:		August 2008
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		These files show the various USB TMC capabilities as described
 		by the device itself.  The full description of the bitfields
@@ -15,7 +15,7 @@ Description:
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities
 Date:		August 2008
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		These files show the various USB TMC capabilities as described
 		by the device itself.  The full description of the bitfields
@@ -29,7 +29,7 @@ Description:
 
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/TermChar
 Date:		August 2008
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		This file is the TermChar value to be sent to the USB TMC
 		device as described by the document, "Universal Serial Bus Test
@@ -42,7 +42,7 @@ Description:
 
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
 Date:		August 2008
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		This file determines if the TermChar is to be sent to the
 		device on every transaction or not.  For more details about
@@ -53,7 +53,7 @@ Description:
 
 What:		/sys/bus/usb/drivers/usbtmc/devices/*/auto_abort
 Date:		August 2008
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		This file determines if the the transaction of the USB TMC
 		device is to be automatically aborted if there is any error.
diff --git a/Documentation/ABI/testing/debugfs-olpc b/Documentation/ABI/testing/debugfs-olpc
new file mode 100644
index 0000000..49b9a4e
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-olpc
@@ -0,0 +1,16 @@
+What:		/sys/kernel/debug/olpc-ec/generic
+Date:		Dec 2011
+KernelVersion:	3.3
+Contact:	devel@lists.laptop.org
+Description:
+
+A generic interface for executing OLPC Embedded Controller commands and
+reading their responses.
+
+To execute a command, write data with the format: CC:N A A A A
+CC is the (hex) command, N is the count of expected reply bytes, and A A A A
+are optional (hex) arguments.
+
+To read the response (if any), read from the generic node after executing
+a command. Hex reply bytes will be returned, *whether or not* they came from
+the immediately previous command.
diff --git a/Documentation/ABI/testing/sysfs-block-dm b/Documentation/ABI/testing/sysfs-block-dm
new file mode 100644
index 0000000..87ca569
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-block-dm
@@ -0,0 +1,25 @@
+What:		/sys/block/dm-<num>/dm/name
+Date:		January 2009
+KernelVersion:	2.6.29
+Contact:	dm-devel@redhat.com
+Description:	Device-mapper device name.
+		Read-only string containing mapped device name.
+Users:		util-linux, device-mapper udev rules
+
+What:		/sys/block/dm-<num>/dm/uuid
+Date:		January 2009
+KernelVersion:	2.6.29
+Contact:	dm-devel@redhat.com
+Description:	Device-mapper device UUID.
+		Read-only string containing DM-UUID or empty string
+		if DM-UUID is not set.
+Users:		util-linux, device-mapper udev rules
+
+What:		/sys/block/dm-<num>/dm/suspended
+Date:		June 2009
+KernelVersion:	2.6.31
+Contact:	dm-devel@redhat.com
+Description:	Device-mapper device suspend state.
+		Contains the value 1 while the device is suspended.
+		Otherwise it contains 0. Read-only attribute.
+Users:		util-linux, device-mapper udev rules
diff --git a/Documentation/ABI/testing/sysfs-bus-rpmsg b/Documentation/ABI/testing/sysfs-bus-rpmsg
new file mode 100644
index 0000000..189e419
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-rpmsg
@@ -0,0 +1,75 @@
+What:		/sys/bus/rpmsg/devices/.../name
+Date:		June 2011
+KernelVersion:	3.3
+Contact:	Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+		Every rpmsg device is a communication channel with a remote
+		processor. Channels are identified with a (textual) name,
+		which is maximum 32 bytes long (defined as RPMSG_NAME_SIZE in
+		rpmsg.h).
+
+		This sysfs entry contains the name of this channel.
+
+What:		/sys/bus/rpmsg/devices/.../src
+Date:		June 2011
+KernelVersion:	3.3
+Contact:	Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+		Every rpmsg device is a communication channel with a remote
+		processor. Channels have a local ("source") rpmsg address,
+		and remote ("destination") rpmsg address. When an entity
+		starts listening on one end of a channel, it assigns it with
+		a unique rpmsg address (a 32 bits integer). This way when
+		inbound messages arrive to this address, the rpmsg core
+		dispatches them to the listening entity (a kernel driver).
+
+		This sysfs entry contains the src (local) rpmsg address
+		of this channel. If it contains 0xffffffff, then an address
+		wasn't assigned (can happen if no driver exists for this
+		channel).
+
+What:		/sys/bus/rpmsg/devices/.../dst
+Date:		June 2011
+KernelVersion:	3.3
+Contact:	Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+		Every rpmsg device is a communication channel with a remote
+		processor. Channels have a local ("source") rpmsg address,
+		and remote ("destination") rpmsg address. When an entity
+		starts listening on one end of a channel, it assigns it with
+		a unique rpmsg address (a 32 bits integer). This way when
+		inbound messages arrive to this address, the rpmsg core
+		dispatches them to the listening entity.
+
+		This sysfs entry contains the dst (remote) rpmsg address
+		of this channel. If it contains 0xffffffff, then an address
+		wasn't assigned (can happen if the kernel driver that
+		is attached to this channel is exposing a service to the
+		remote processor. This make it a local rpmsg server,
+		and it is listening for inbound messages that may be sent
+		from any remote rpmsg client; it is not bound to a single
+		remote entity).
+
+What:		/sys/bus/rpmsg/devices/.../announce
+Date:		June 2011
+KernelVersion:	3.3
+Contact:	Ohad Ben-Cohen <ohad@wizery.com>
+Description:
+		Every rpmsg device is a communication channel with a remote
+		processor. Channels are identified by a textual name (see
+		/sys/bus/rpmsg/devices/.../name above) and have a local
+		("source") rpmsg address, and remote ("destination") rpmsg
+		address.
+
+		A channel is first created when an entity, whether local
+		or remote, starts listening on it for messages (and is thus
+		called an rpmsg server).
+
+		When that happens, a "name service" announcement is sent
+		to the other processor, in order to let it know about the
+		creation of the channel (this way remote clients know they
+		can start sending messages).
+
+		This sysfs entry tells us whether the channel is a local
+		server channel that is announced (values are either
+		true or false).
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index b4f5487..7c22a53 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -182,3 +182,14 @@ Description:
 		USB2 hardware LPM is enabled for the device. Developer can
 		write y/Y/1 or n/N/0 to the file to enable/disable the
 		feature.
+
+What:		/sys/bus/usb/devices/.../removable
+Date:		February 2012
+Contact:	Matthew Garrett <mjg@redhat.com>
+Description:
+		Some information about whether a given USB device is
+		physically fixed to the platform can be inferred from a
+		combination of hub decriptor bits and platform-specific data
+		such as ACPI. This file will read either "removable" or
+		"fixed" if the information is available, and "unknown"
+		otherwise.
\ No newline at end of file
diff --git a/Documentation/ABI/testing/sysfs-class b/Documentation/ABI/testing/sysfs-class
index 4b0cb89..676530f 100644
--- a/Documentation/ABI/testing/sysfs-class
+++ b/Documentation/ABI/testing/sysfs-class
@@ -1,6 +1,6 @@
 What:		/sys/class/
 Date:		Febuary 2006
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		The /sys/class directory will consist of a group of
 		subdirectories describing individual classes of devices
diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh
index b020014..b218e0f 100644
--- a/Documentation/ABI/testing/sysfs-class-net-mesh
+++ b/Documentation/ABI/testing/sysfs-class-net-mesh
@@ -65,6 +65,13 @@ Description:
 		Defines the penalty which will be applied to an
 		originator message's tq-field on every hop.
 
+What:		/sys/class/net/<mesh_iface>/mesh/routing_algo
+Date:		Dec 2011
+Contact:	Marek Lindner <lindner_marek@yahoo.de>
+Description:
+		Defines the routing procotol this mesh instance
+		uses to find the optimal paths through the mesh.
+
 What:           /sys/class/net/<mesh_iface>/mesh/vis_mode
 Date:           May 2010
 Contact:        Marek Lindner <lindner_marek@yahoo.de>
diff --git a/Documentation/ABI/testing/sysfs-devices b/Documentation/ABI/testing/sysfs-devices
index 6a25671..5fcc943 100644
--- a/Documentation/ABI/testing/sysfs-devices
+++ b/Documentation/ABI/testing/sysfs-devices
@@ -1,6 +1,6 @@
 What:		/sys/devices
 Date:		February 2006
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 		The /sys/devices tree contains a snapshot of the
 		internal state of the kernel device tree.  Devices will
diff --git a/Documentation/ABI/testing/sysfs-devices-soc b/Documentation/ABI/testing/sysfs-devices-soc
new file mode 100644
index 0000000..6d9cc25
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-soc
@@ -0,0 +1,58 @@
+What:		/sys/devices/socX
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		The /sys/devices/ directory contains a sub-directory for each
+		System-on-Chip (SoC) device on a running platform. Information
+		regarding each SoC can be obtained by reading sysfs files. This
+		functionality is only available if implemented by the platform.
+
+		The directory created for each SoC will also house information
+		about devices which are commonly contained in /sys/devices/platform.
+		It has been agreed that if an SoC device exists, its supported
+		devices would be better suited to appear as children of that SoC.
+
+What:		/sys/devices/socX/machine
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		Read-only attribute common to all SoCs. Contains the SoC machine
+		name (e.g. Ux500).
+
+What:		/sys/devices/socX/family
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		Read-only attribute common to all SoCs. Contains SoC family name
+		(e.g. DB8500).
+
+What:		/sys/devices/socX/soc_id
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		Read-only attribute supported by most SoCs. In the case of
+		ST-Ericsson's chips this contains the SoC serial number.
+
+What:		/sys/devices/socX/revision
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		Read-only attribute supported by most SoCs. Contains the SoC's
+		manufacturing revision number.
+
+What:		/sys/devices/socX/process
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		Read-only attribute supported ST-Ericsson's silicon. Contains the
+		the process by which the silicon chip was manufactured.
+
+What:		/sys/bus/soc
+Date:		January 2012
+contact:	Lee Jones <lee.jones@linaro.org>
+Description:
+		The /sys/bus/soc/ directory contains the usual sub-folders
+		expected under most buses. /sys/bus/soc/devices is of particular
+		interest, as it contains a symlink for each SoC device found on
+		the system. Each symlink points back into the aforementioned
+		/sys/devices/socX devices.
diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
index 0a81023..e82e7c2 100644
--- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
@@ -1,7 +1,7 @@
 What:		/sys/devices/platform/samsung/performance_level
 Date:		January 1, 2010
 KernelVersion:	2.6.33
-Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:	Some Samsung laptops have different "performance levels"
 		that are can be modified by a function key, and by this
 		sysfs file.  These values don't always make a whole lot
diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-cleancache b/Documentation/ABI/testing/sysfs-kernel-mm-cleancache
deleted file mode 100644
index 662ae64..0000000
--- a/Documentation/ABI/testing/sysfs-kernel-mm-cleancache
+++ /dev/null
@@ -1,11 +0,0 @@
-What:		/sys/kernel/mm/cleancache/
-Date:		April 2011
-Contact:	Dan Magenheimer <dan.magenheimer@oracle.com>
-Description:
-		/sys/kernel/mm/cleancache/ contains a number of files which
-		record a count of various cleancache operations
-		(sum across all filesystems):
-			succ_gets
-			failed_gets
-			puts
-			flushes
diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index b768cc0..9120de2 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -31,3 +31,22 @@ may be weakly ordered, that is that reads and writes may pass each other.
 Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING,
 those that do not will simply ignore the attribute and exhibit default
 behavior.
+
+DMA_ATTR_WRITE_COMBINE
+----------------------
+
+DMA_ATTR_WRITE_COMBINE specifies that writes to the mapping may be
+buffered to improve performance.
+
+Since it is optional for platforms to implement DMA_ATTR_WRITE_COMBINE,
+those that do not will simply ignore the attribute and exhibit default
+behavior.
+
+DMA_ATTR_NON_CONSISTENT
+-----------------------
+
+DMA_ATTR_NON_CONSISTENT lets the platform to choose to return either
+consistent or non-consistent memory as it sees fit.  By using this API,
+you are guaranteeing to the platform that you have all the correct and
+necessary sync points for this memory in the driver should it choose to
+return non-consistent memory.
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 2014155..c5ac692 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -129,7 +129,6 @@
 !Finclude/net/cfg80211.h cfg80211_pmksa
 !Finclude/net/cfg80211.h cfg80211_send_rx_auth
 !Finclude/net/cfg80211.h cfg80211_send_auth_timeout
-!Finclude/net/cfg80211.h __cfg80211_auth_canceled
 !Finclude/net/cfg80211.h cfg80211_send_rx_assoc
 !Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
 !Finclude/net/cfg80211.h cfg80211_send_deauth
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 9c27e51..7514dbf 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -446,4 +446,21 @@ X!Idrivers/video/console/fonts.c
 !Edrivers/i2c/i2c-core.c
   </chapter>
 
+  <chapter id="hsi">
+     <title>High Speed Synchronous Serial Interface (HSI)</title>
+
+     <para>
+	High Speed Synchronous Serial Interface (HSI) is a
+	serial interface mainly used for connecting application
+	engines (APE) with cellular modem engines (CMT) in cellular
+	handsets.
+
+	HSI provides multiplexing for up to 16 logical channels,
+	low-latency and full duplex communication.
+     </para>
+
+!Iinclude/linux/hsi/hsi.h
+!Edrivers/hsi/hsi.c
+  </chapter>
+
 </book>
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml
index c736380..c93298f 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2393,6 +2393,10 @@ details.</para>
 	    to the <link linkend="control">User controls class</link>.
 	  </para>
         </listitem>
+        <listitem>
+	  <para>Added the device_caps field to struct v4l2_capabilities and added the new
+	  V4L2_CAP_DEVICE_CAPS capability.</para>
+        </listitem>
       </orderedlist>
     </section>
 
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index a1be378..3f3d2e2 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -1286,6 +1286,49 @@ produce a slight hiss, but in the encoder itself, guaranteeing a fixed
 and reproducible audio bitstream. 0 = unmuted, 1 = muted.</entry>
 	      </row>
 	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-dec-playback">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_dec_playback</entry>
+	      </row><row><entry spanname="descr">Determines how monolingual audio should be played back.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO</constant>&nbsp;</entry>
+		      <entry>Automatically determines the best playback mode.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO</constant>&nbsp;</entry>
+		      <entry>Stereo playback.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT</constant>&nbsp;</entry>
+		      <entry>Left channel playback.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT</constant>&nbsp;</entry>
+		      <entry>Right channel playback.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO</constant>&nbsp;</entry>
+		      <entry>Mono playback.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO</constant>&nbsp;</entry>
+		      <entry>Stereo playback with swapped left and right channels.</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-dec-multilingual-playback">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_dec_playback</entry>
+	      </row><row><entry spanname="descr">Determines how multilingual audio should be played back.</entry>
+	      </row>
+	      <row><entry></entry></row>
 	      <row id="v4l2-mpeg-video-encoding">
 		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ENCODING</constant>&nbsp;</entry>
 		<entry>enum&nbsp;v4l2_mpeg_video_encoding</entry>
@@ -1447,6 +1490,22 @@ of the video. The supplied 32-bit integer is interpreted as follows (bit
 		  </tbody>
 		</entrytbl>
 	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-video-dec-pts">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DEC_PTS</constant>&nbsp;</entry>
+		<entry>integer64</entry>
+	      </row><row><entry spanname="descr">This read-only control returns the
+33-bit video Presentation Time Stamp as defined in ITU T-REC-H.222.0 and ISO/IEC 13818-1 of
+the currently displayed frame. This is the same PTS as is used in &VIDIOC-DECODER-CMD;.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-video-dec-frame">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_DEC_FRAME</constant>&nbsp;</entry>
+		<entry>integer64</entry>
+	      </row><row><entry spanname="descr">This read-only control returns the
+frame counter of the frame that is currently displayed (decoded). This value is reset to 0 whenever
+the decoder is started.</entry>
+	      </row>
 
 
 	      <row><entry></entry></row>
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml
index e97c512..dcf9e33 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -128,6 +128,13 @@ structs, ioctls) must be noted in more detail in the history chapter
 applications. -->
 
       <revision>
+	<revnumber>3.3</revnumber>
+	<date>2012-01-11</date>
+	<authorinitials>hv</authorinitials>
+	<revremark>Added device_caps field to struct v4l2_capabilities.</revremark>
+      </revision>
+
+      <revision>
 	<revnumber>3.2</revnumber>
 	<date>2011-08-26</date>
 	<authorinitials>hv</authorinitials>
@@ -417,7 +424,7 @@ and discussions on the V4L mailing list.</revremark>
 </partinfo>
 
 <title>Video for Linux Two API Specification</title>
- <subtitle>Revision 3.2</subtitle>
+ <subtitle>Revision 3.3</subtitle>
 
   <chapter id="common">
     &sub-common;
@@ -473,6 +480,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-cropcap;
     &sub-dbg-g-chip-ident;
     &sub-dbg-g-register;
+    &sub-decoder-cmd;
     &sub-dqevent;
     &sub-encoder-cmd;
     &sub-enumaudio;
diff --git a/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml b/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
new file mode 100644
index 0000000..466fe27
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
@@ -0,0 +1,256 @@
+<refentry id="vidioc-decoder-cmd">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_DECODER_CMD</refname>
+    <refname>VIDIOC_TRY_DECODER_CMD</refname>
+    <refpurpose>Execute an decoder command</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_decoder_cmd *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_DECODER_CMD, VIDIOC_TRY_DECODER_CMD</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+
+      <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+    </note>
+
+    <para>These ioctls control an audio/video (usually MPEG-) decoder.
+<constant>VIDIOC_DECODER_CMD</constant> sends a command to the
+decoder, <constant>VIDIOC_TRY_DECODER_CMD</constant> can be used to
+try a command without actually executing it. To send a command applications
+must initialize all fields of a &v4l2-decoder-cmd; and call
+<constant>VIDIOC_DECODER_CMD</constant> or <constant>VIDIOC_TRY_DECODER_CMD</constant>
+with a pointer to this structure.</para>
+
+    <para>The <structfield>cmd</structfield> field must contain the
+command code. Some commands use the <structfield>flags</structfield> field for
+additional information.
+</para>
+
+    <para>A <function>write</function>() or &VIDIOC-STREAMON; call sends an implicit
+START command to the decoder if it has not been started yet.
+</para>
+
+    <para>A <function>close</function>() or &VIDIOC-STREAMOFF; call of a streaming
+file descriptor sends an implicit immediate STOP command to the decoder, and all
+buffered data is discarded.</para>
+
+    <para>These ioctls are optional, not all drivers may support
+them. They were introduced in Linux 3.3.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-decoder-cmd">
+      <title>struct <structname>v4l2_decoder_cmd</structname></title>
+      <tgroup cols="5">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>cmd</structfield></entry>
+            <entry></entry>
+            <entry></entry>
+	    <entry>The decoder command, see <xref linkend="decoder-cmds" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+            <entry></entry>
+            <entry></entry>
+	    <entry>Flags to go with the command. If no flags are defined for
+this command, drivers and applications must set this field to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry>(anonymous)</entry>
+            <entry></entry>
+	    <entry></entry>
+            <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct</entry>
+            <entry><structfield>start</structfield></entry>
+            <entry></entry>
+            <entry>Structure containing additional data for the
+<constant>V4L2_DEC_CMD_START</constant> command.</entry>
+	  </row>
+	  <row>
+            <entry></entry>
+            <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>speed</structfield></entry>
+            <entry>Playback speed and direction. The playback speed is defined as
+<structfield>speed</structfield>/1000 of the normal speed. So 1000 is normal playback.
+Negative numbers denote reverse playback, so -1000 does reverse playback at normal
+speed. Speeds -1, 0 and 1 have special meanings: speed 0 is shorthand for 1000
+(normal playback). A speed of 1 steps just one frame forward, a speed of -1 steps
+just one frame back.
+	    </entry>
+	  </row>
+	  <row>
+            <entry></entry>
+            <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>format</structfield></entry>
+            <entry>Format restrictions. This field is set by the driver, not the
+application. Possible values are <constant>V4L2_DEC_START_FMT_NONE</constant> if
+there are no format restrictions or <constant>V4L2_DEC_START_FMT_GOP</constant>
+if the decoder operates on full GOPs (<wordasword>Group Of Pictures</wordasword>).
+This is usually the case for reverse playback: the decoder needs full GOPs, which
+it can then play in reverse order. So to implement reverse playback the application
+must feed the decoder the last GOP in the video file, then the GOP before that, etc. etc.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct</entry>
+            <entry><structfield>stop</structfield></entry>
+            <entry></entry>
+            <entry>Structure containing additional data for the
+<constant>V4L2_DEC_CMD_STOP</constant> command.</entry>
+	  </row>
+	  <row>
+            <entry></entry>
+            <entry></entry>
+	    <entry>__u64</entry>
+	    <entry><structfield>pts</structfield></entry>
+            <entry>Stop playback at this <structfield>pts</structfield> or immediately
+if the playback is already past that timestamp. Leave to 0 if you want to stop after the
+last frame was decoded.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct</entry>
+            <entry><structfield>raw</structfield></entry>
+            <entry></entry>
+            <entry></entry>
+	  </row>
+	  <row>
+            <entry></entry>
+            <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>data</structfield>[16]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="decoder-cmds">
+      <title>Decoder Commands</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_DEC_CMD_START</constant></entry>
+	    <entry>0</entry>
+	    <entry>Start the decoder. When the decoder is already
+running or paused, this command will just change the playback speed.
+That means that calling <constant>V4L2_DEC_CMD_START</constant> when
+the decoder was paused will <emphasis>not</emphasis> resume the decoder.
+You have to explicitly call <constant>V4L2_DEC_CMD_RESUME</constant> for that.
+This command has one flag:
+<constant>V4L2_DEC_CMD_START_MUTE_AUDIO</constant>. If set, then audio will
+be muted when playing back at a non-standard speed.
+            </entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_DEC_CMD_STOP</constant></entry>
+	    <entry>1</entry>
+	    <entry>Stop the decoder. When the decoder is already stopped,
+this command does nothing. This command has two flags:
+if <constant>V4L2_DEC_CMD_STOP_TO_BLACK</constant> is set, then the decoder will
+set the picture to black after it stopped decoding. Otherwise the last image will
+repeat. If <constant>V4L2_DEC_CMD_STOP_IMMEDIATELY</constant> is set, then the decoder
+stops immediately (ignoring the <structfield>pts</structfield> value), otherwise it
+will keep decoding until timestamp >= pts or until the last of the pending data from
+its internal buffers was decoded.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_DEC_CMD_PAUSE</constant></entry>
+	    <entry>2</entry>
+	    <entry>Pause the decoder. When the decoder has not been
+started yet, the driver will return an &EPERM;. When the decoder is
+already paused, this command does nothing. This command has one flag:
+if <constant>V4L2_DEC_CMD_PAUSE_TO_BLACK</constant> is set, then set the
+decoder output to black when paused.
+</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_DEC_CMD_RESUME</constant></entry>
+	    <entry>3</entry>
+	    <entry>Resume decoding after a PAUSE command. When the
+decoder has not been started yet, the driver will return an &EPERM;.
+When the decoder is already running, this command does nothing. No
+flags are defined for this command.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <structfield>cmd</structfield> field is invalid.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EPERM</errorcode></term>
+	<listitem>
+	  <para>The application sent a PAUSE or RESUME command when
+the decoder was not running.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
diff --git a/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml b/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
index af7f3f2..f431b3b 100644
--- a/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-encoder-cmd.xml
@@ -74,15 +74,16 @@ only used by the STOP command and contains one bit: If the
 encoding will continue until the end of the current <wordasword>Group
 Of Pictures</wordasword>, otherwise it will stop immediately.</para>
 
-    <para>A <function>read</function>() call sends a START command to
-the encoder if it has not been started yet. After a STOP command,
+    <para>A <function>read</function>() or &VIDIOC-STREAMON; call sends an implicit
+START command to the encoder if it has not been started yet. After a STOP command,
 <function>read</function>() calls will read the remaining data
 buffered by the driver. When the buffer is empty,
 <function>read</function>() will return zero and the next
 <function>read</function>() call will restart the encoder.</para>
 
-    <para>A <function>close</function>() call sends an immediate STOP
-to the encoder, and all buffered data is discarded.</para>
+    <para>A <function>close</function>() or &VIDIOC-STREAMOFF; call of a streaming
+file descriptor sends an implicit immediate STOP to the encoder, and all buffered
+data is discarded.</para>
 
     <para>These ioctls are optional, not all drivers may support
 them. They were introduced in Linux 2.6.21.</para>
diff --git a/Documentation/DocBook/media/v4l/vidioc-querycap.xml b/Documentation/DocBook/media/v4l/vidioc-querycap.xml
index e3664d6..4643505 100644
--- a/Documentation/DocBook/media/v4l/vidioc-querycap.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-querycap.xml
@@ -124,12 +124,35 @@ printf ("Version: %u.%u.%u\n",
 	  <row>
 	    <entry>__u32</entry>
 	    <entry><structfield>capabilities</structfield></entry>
-	    <entry>Device capabilities, see <xref
-		linkend="device-capabilities" />.</entry>
+	    <entry>Available capabilities of the physical device as a whole, see <xref
+		linkend="device-capabilities" />. The same physical device can export
+		multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and /dev/radioZ).
+		The <structfield>capabilities</structfield> field should contain a union
+		of all capabilities available around the several V4L2 devices exported
+		to userspace.
+		For all those devices the <structfield>capabilities</structfield> field
+		returns the same set of	capabilities. This allows applications to open
+		just one of the devices (typically the video device) and discover whether
+		video, vbi and/or radio are also supported.
+	    </entry>
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
-	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry><structfield>device_caps</structfield></entry>
+	    <entry>Device capabilities of the opened device, see <xref
+		linkend="device-capabilities" />. Should contain the available capabilities
+		of that specific device node. So, for example, <structfield>device_caps</structfield>
+		of a radio device will only contain radio related capabilities and
+		no video or vbi capabilities. This field is only set if the <structfield>capabilities</structfield>
+		field contains the <constant>V4L2_CAP_DEVICE_CAPS</constant> capability.
+		Only the <structfield>capabilities</structfield> field can have the
+		<constant>V4L2_CAP_DEVICE_CAPS</constant> capability, <structfield>device_caps</structfield>
+		will never set <constant>V4L2_CAP_DEVICE_CAPS</constant>.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[3]</entry>
 	    <entry>Reserved for future extensions. Drivers must set
 this array to zero.</entry>
 	  </row>
@@ -276,6 +299,13 @@ linkend="async">asynchronous</link> I/O methods.</entry>
 	    <entry>The device supports the <link
 linkend="mmap">streaming</link> I/O method.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_DEVICE_CAPS</constant></entry>
+	    <entry>0x80000000</entry>
+	    <entry>The driver fills the <structfield>device_caps</structfield>
+	    field. This capability can only appear in the <structfield>capabilities</structfield>
+	    field and never in the <structfield>device_caps</structfield> field.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
new file mode 100644
index 0000000..27dcaab
--- /dev/null
+++ b/Documentation/IRQ-domain.txt
@@ -0,0 +1,117 @@
+irq_domain interrupt number mapping library
+
+The current design of the Linux kernel uses a single large number
+space where each separate IRQ source is assigned a different number.
+This is simple when there is only one interrupt controller, but in
+systems with multiple interrupt controllers the kernel must ensure
+that each one gets assigned non-overlapping allocations of Linux
+IRQ numbers.
+
+The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of
+irq numbers, but they don't provide any support for reverse mapping of
+the controller-local IRQ (hwirq) number into the Linux IRQ number
+space.
+
+The irq_domain library adds mapping between hwirq and IRQ numbers on
+top of the irq_alloc_desc*() API.  An irq_domain to manage mapping is
+preferred over interrupt controller drivers open coding their own
+reverse mapping scheme.
+
+irq_domain also implements translation from Device Tree interrupt
+specifiers to hwirq numbers, and can be easily extended to support
+other IRQ topology data sources.
+
+=== irq_domain usage ===
+An interrupt controller driver creates and registers an irq_domain by
+calling one of the irq_domain_add_*() functions (each mapping method
+has a different allocator function, more on that later).  The function
+will return a pointer to the irq_domain on success.  The caller must
+provide the allocator function with an irq_domain_ops structure with
+the .map callback populated as a minimum.
+
+In most cases, the irq_domain will begin empty without any mappings
+between hwirq and IRQ numbers.  Mappings are added to the irq_domain
+by calling irq_create_mapping() which accepts the irq_domain and a
+hwirq number as arguments.  If a mapping for the hwirq doesn't already
+exist then it will allocate a new Linux irq_desc, associate it with
+the hwirq, and call the .map() callback so the driver can perform any
+required hardware setup.
+
+When an interrupt is received, irq_find_mapping() function should
+be used to find the Linux IRQ number from the hwirq number.
+
+If the driver has the Linux IRQ number or the irq_data pointer, and
+needs to know the associated hwirq number (such as in the irq_chip
+callbacks) then it can be directly obtained from irq_data->hwirq.
+
+=== Types of irq_domain mappings ===
+There are several mechanisms available for reverse mapping from hwirq
+to Linux irq, and each mechanism uses a different allocation function.
+Which reverse map type should be used depends on the use case.  Each
+of the reverse map types are described below:
+
+==== Linear ====
+irq_domain_add_linear()
+
+The linear reverse map maintains a fixed size table indexed by the
+hwirq number.  When a hwirq is mapped, an irq_desc is allocated for
+the hwirq, and the IRQ number is stored in the table.
+
+The Linear map is a good choice when the maximum number of hwirqs is
+fixed and a relatively small number (~ < 256).  The advantages of this
+map are fixed time lookup for IRQ numbers, and irq_descs are only
+allocated for in-use IRQs.  The disadvantage is that the table must be
+as large as the largest possible hwirq number.
+
+The majority of drivers should use the linear map.
+
+==== Tree ====
+irq_domain_add_tree()
+
+The irq_domain maintains a radix tree map from hwirq numbers to Linux
+IRQs.  When an hwirq is mapped, an irq_desc is allocated and the
+hwirq is used as the lookup key for the radix tree.
+
+The tree map is a good choice if the hwirq number can be very large
+since it doesn't need to allocate a table as large as the largest
+hwirq number.  The disadvantage is that hwirq to IRQ number lookup is
+dependent on how many entries are in the table.
+
+Very few drivers should need this mapping.  At the moment, powerpc
+iseries is the only user.
+
+==== No Map ===-
+irq_domain_add_nomap()
+
+The No Map mapping is to be used when the hwirq number is
+programmable in the hardware.  In this case it is best to program the
+Linux IRQ number into the hardware itself so that no mapping is
+required.  Calling irq_create_direct_mapping() will allocate a Linux
+IRQ number and call the .map() callback so that driver can program the
+Linux IRQ number into the hardware.
+
+Most drivers cannot use this mapping.
+
+==== Legacy ====
+irq_domain_add_legacy()
+irq_domain_add_legacy_isa()
+
+The Legacy mapping is a special case for drivers that already have a
+range of irq_descs allocated for the hwirqs.  It is used when the
+driver cannot be immediately converted to use the linear mapping.  For
+example, many embedded system board support files use a set of #defines
+for IRQ numbers that are passed to struct device registrations.  In that
+case the Linux IRQ numbers cannot be dynamically assigned and the legacy
+mapping should be used.
+
+The legacy map assumes a contiguous range of IRQ numbers has already
+been allocated for the controller and that the IRQ number can be
+calculated by adding a fixed offset to the hwirq number, and
+visa-versa.  The disadvantage is that it requires the interrupt
+controller to manage IRQ allocations and it requires an irq_desc to be
+allocated for every hwirq, even if it is unused.
+
+The legacy map should only be used if fixed IRQ mappings must be
+supported.  For example, ISA controllers would use the legacy map for
+mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
+numbers.
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 9b4bc5c..30b656e 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -1,3 +1,3 @@
 obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
 	filesystems/ filesystems/configfs/ ia64/ laptops/ networking/ \
-	pcmcia/ spi/ timers/ vm/ watchdog/src/
+	pcmcia/ spi/ timers/ watchdog/src/
diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt
index c43460d..7c1dfb1 100644
--- a/Documentation/RCU/RTFP.txt
+++ b/Documentation/RCU/RTFP.txt
@@ -1,9 +1,10 @@
-Read the F-ing Papers!
+Read the Fscking Papers!
 
 
 This document describes RCU-related publications, and is followed by
 the corresponding bibtex entries.  A number of the publications may
-be found at http://www.rdrop.com/users/paulmck/RCU/.
+be found at http://www.rdrop.com/users/paulmck/RCU/.  For others, browsers
+and search engines will usually find what you are looking for.
 
 The first thing resembling RCU was published in 1980, when Kung and Lehman
 [Kung80] recommended use of a garbage collector to defer destruction
@@ -160,7 +161,26 @@ which Mathieu Desnoyers is now maintaining [MathieuDesnoyers2009URCU]
 [MathieuDesnoyersPhD].  TINY_RCU [PaulEMcKenney2009BloatWatchRCU] made
 its appearance, as did expedited RCU [PaulEMcKenney2009expeditedRCU].
 The problem of resizeable RCU-protected hash tables may now be on a path
-to a solution [JoshTriplett2009RPHash].
+to a solution [JoshTriplett2009RPHash].  A few academic researchers are now
+using RCU to solve their parallel problems [HariKannan2009DynamicAnalysisRCU].
+
+2010 produced a simpler preemptible-RCU implementation
+based on TREE_RCU [PaulEMcKenney2010SimpleOptRCU], lockdep-RCU
+[PaulEMcKenney2010LockdepRCU], another resizeable RCU-protected hash
+table [HerbertXu2010RCUResizeHash] (this one consuming more memory,
+but allowing arbitrary changes in hash function, as required for DoS
+avoidance in the networking code), realization of the 2009 RCU-protected
+hash table with atomic node move [JoshTriplett2010RPHash], an update on
+the RCU API [PaulEMcKenney2010RCUAPI].
+
+2011 marked the inclusion of Nick Piggin's fully lockless dentry search
+[LinusTorvalds2011Linux2:6:38:rc1:NPigginVFS], an RCU-protected red-black
+tree using software transactional memory to protect concurrent updates
+(strange, but true!) [PhilHoward2011RCUTMRBTree], yet another variant of
+RCU-protected resizeable hash tables [Triplett:2011:RPHash], the 3.0 RCU
+trainwreck [PaulEMcKenney2011RCU3.0trainwreck], and Neil Brown's "Meet the
+Lockers" LWN article [NeilBrown2011MeetTheLockers].
+
 
 Bibtex Entries
 
@@ -173,6 +193,14 @@ Bibtex Entries
 ,volume="5"
 ,number="3"
 ,pages="354-382"
+,note="Available:
+\url{http://portal.acm.org/citation.cfm?id=320619&dl=GUIDE,}
+[Viewed December 3, 2007]"
+,annotation={
+	Use garbage collector to clean up data after everyone is done with it.
+	.
+	Oldest use of something vaguely resembling RCU that I have found.
+}
 }
 
 @techreport{Manber82
@@ -184,6 +212,31 @@ Bibtex Entries
 ,number="82-01-01"
 ,month="January"
 ,pages="28"
+,annotation={
+	.
+	Superseded by Manber84.
+	.
+	Describes concurrent AVL tree implementation.  Uses a
+	garbage-collection mechanism to handle concurrent use and deletion
+	of nodes in the tree, but lacks the summary-of-execution-history
+	concept of read-copy locking.
+	.
+	Keeps full list of processes that were active when a given
+	node was to be deleted, and waits until all such processes have
+	-terminated- before allowing this node to be reused.  This is
+	not described in great detail -- one could imagine using process
+	IDs for this if the ID space was large enough that overlapping
+	never occurred.
+	.
+	This restriction makes this algorithm unsuitable for use in
+	systems comprised of long-lived processes.  It also produces
+	completely unacceptable overhead in systems with large numbers
+	of processes.  Finally, it is specific to AVL trees.
+	.
+	Cites Kung80, so not an independent invention, but the first
+	RCU-like usage that does not rely on an automatic garbage
+	collector.
+}
 }
 
 @article{Manber84
@@ -195,6 +248,74 @@ Bibtex Entries
 ,volume="9"
 ,number="3"
 ,pages="439-455"
+,annotation={
+	Describes concurrent AVL tree implementation.  Uses a
+	garbage-collection mechanism to handle concurrent use and deletion
+	of nodes in the tree, but lacks the summary-of-execution-history
+	concept of read-copy locking.
+	.
+	Keeps full list of processes that were active when a given
+	node was to be deleted, and waits until all such processes have
+	-terminated- before allowing this node to be reused.  This is
+	not described in great detail -- one could imagine using process
+	IDs for this if the ID space was large enough that overlapping
+	never occurred.
+	.
+	This restriction makes this algorithm unsuitable for use in
+	systems comprised of long-lived processes.  It also produces
+	completely unacceptable overhead in systems with large numbers
+	of processes.  Finally, it is specific to AVL trees.
+}
+}
+
+@Conference{RichardRashid87a
+,Author="Richard Rashid and Avadis Tevanian and Michael Young and
+David Golub and Robert Baron and David Black and William Bolosky and
+Jonathan Chew"
+,Title="Machine-Independent Virtual Memory Management for Paged
+Uniprocessor and Multiprocessor Architectures"
+,Booktitle="{2\textsuperscript{nd} Symposium on Architectural Support
+for Programming Languages and Operating Systems}"
+,Publisher="Association for Computing Machinery"
+,Month="October"
+,Year="1987"
+,pages="31-39"
+,Address="Palo Alto, CA"
+,note="Available:
+\url{http://www.cse.ucsc.edu/~randal/221/rashid-machvm.pdf}
+[Viewed February 17, 2005]"
+,annotation={
+	Describes lazy TLB flush, where one waits for each CPU to pass
+	through a scheduling-clock interrupt before reusing a given range
+	of virtual address.  Does not describe how one determines that
+	all CPUs have in fact taken such an interrupt, though there are
+	no shortage of straightforward methods for accomplishing this.
+	.
+	Note that it does not make sense to just wait a fixed amount of
+	time, since a given CPU might have interrupts disabled for an
+	extended amount of time.
+}
+}
+
+@article{BarbaraLiskov1988ArgusCACM
+,author = {Barbara Liskov}
+,title = {Distributed programming in {Argus}}
+,journal = {Commun. ACM}
+,volume = {31}
+,number = {3}
+,year = {1988}
+,issn = {0001-0782}
+,pages = {300--312}
+,doi = {http://doi.acm.org/10.1145/42392.42399}
+,publisher = {ACM}
+,address = {New York, NY, USA}
+,annotation= {
+	At the top of page 307: "Conflicts with deposits and withdrawals
+	are necessary if the reported total is to be up to date.  They
+	could be avoided by having total return a sum that is slightly
+	out of date."  Relies on semantics -- approximate numerical
+	values sometimes OK.
+}
 }
 
 @techreport{Hennessy89
@@ -216,6 +337,13 @@ Bibtex Entries
 ,year="1990"
 ,number="CS-TR-2222.1"
 ,month="June"
+,annotation={
+	Concurrent access to skip lists.  Has both weak and strong search.
+	Uses concept of ``garbage queue'', but has no real way of cleaning
+	the garbage efficiently.
+	.
+	Appears to be an independent invention of an RCU-like mechanism.
+}
 }
 
 @Book{Adams91
@@ -223,20 +351,15 @@ Bibtex Entries
 ,title="Concurrent Programming, Principles, and Practices"
 ,Publisher="Benjamin Cummins"
 ,Year="1991"
+,annotation={
+	Has a few paragraphs describing ``chaotic relaxation'', a
+	numerical analysis technique that allows multiprocessors to
+	avoid synchronization overhead by using possibly-stale data.
+	.
+	Seems like this is descended from yet another independent
+	invention of RCU-like function -- but this is restricted
+	in that reclamation is not necessary.
 }
-
-@phdthesis{HMassalinPhD
-,author="H. Massalin"
-,title="Synthesis: An Efficient Implementation of Fundamental Operating
-System Services"
-,school="Columbia University"
-,address="New York, NY"
-,year="1992"
-,annotation="
-	Mondo optimizing compiler.
-	Wait-free stuff.
-	Good advice: defer work to avoid synchronization.
-"
 }
 
 @unpublished{Jacobson93
@@ -244,7 +367,13 @@ System Services"
 ,title="Avoid Read-Side Locking Via Delayed Free"
 ,year="1993"
 ,month="September"
-,note="Verbal discussion"
+,note="private communication"
+,annotation={
+	Use fixed time delay to approximate grace period.  Very simple,
+	but subject to random memory corruption under heavy load.
+	.
+	Independent invention of RCU-like mechanism.
+}
 }
 
 @Conference{AjuJohn95
@@ -256,6 +385,17 @@ System Services"
 ,Year="1995"
 ,pages="11-23"
 ,Address="New Orleans, LA"
+,note="Available:
+\url{https://www.usenix.org/publications/library/proceedings/neworl/full_papers/john.a}
+[Viewed October 1, 2010]"
+,annotation={
+	Age vnodes out of the cache, and have a fixed time set by a kernel
+	parameter.  Not clear that all races were in fact correctly handled.
+	Used a 20-minute time by default, which would most definitely not
+	be suitable during DoS attacks or virus scans.
+	.
+	Apparently independent invention of RCU-like mechanism.
+}
 }
 
 @conference{Pu95a,
@@ -301,31 +441,47 @@ Utilizing Execution History and Thread Monitoring"
 ,institution="US Patent and Trademark Office"
 ,address="Washington, DC"
 ,year="1995"
-,number="US Patent 5,442,758 (contributed under GPL)"
+,number="US Patent 5,442,758"
 ,month="August"
+,annotation={
+	Describes the parallel RCU infrastructure.  Includes NUMA aspect
+	(structure of bitmap can reflect bus structure of computer system).
+	.
+	Another independent invention of an RCU-like mechanism, but the
+	"real" RCU this time!
+}
 }
 
 @techreport{Slingwine97
 ,author="John D. Slingwine and Paul E. McKenney"
-,title="Method for maintaining data coherency using thread
-activity summaries in a multicomputer system"
+,title="Method for Maintaining Data Coherency Using Thread Activity
+Summaries in a Multicomputer System"
 ,institution="US Patent and Trademark Office"
 ,address="Washington, DC"
 ,year="1997"
-,number="US Patent 5,608,893 (contributed under GPL)"
+,number="US Patent 5,608,893"
 ,month="March"
+,pages="19"
+,annotation={
+	Describes use of RCU to synchronize data between a pair of
+	SMP/NUMA computer systems.
+}
 }
 
 @techreport{Slingwine98
 ,author="John D. Slingwine and Paul E. McKenney"
-,title="Apparatus and method for achieving reduced overhead
-mutual exclusion and maintaining coherency in a multiprocessor
-system utilizing execution history and thread monitoring"
+,title="Apparatus and Method for Achieving Reduced Overhead Mutual
+Exclusion and Maintaining Coherency in a Multiprocessor System
+Utilizing Execution History and Thread Monitoring"
 ,institution="US Patent and Trademark Office"
 ,address="Washington, DC"
 ,year="1998"
-,number="US Patent 5,727,209 (contributed under GPL)"
+,number="US Patent 5,727,209"
 ,month="March"
+,annotation={
+	Describes doing an atomic update by copying the data item and
+	then substituting it into the data structure.
+}
 }
 
 @Conference{McKenney98
@@ -337,6 +493,15 @@ Problems"
 ,Year="1998"
 ,pages="509-518"
 ,Address="Las Vegas, NV"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/rclockpdcsproof.pdf}
+[Viewed December 3, 2007]"
+,annotation={
+	Describes and analyzes RCU mechanism in DYNIX/ptx.  Describes
+	application to linked list update and log-buffer flushing.
+	Defines 'quiescent state'.  Includes both measured and analytic
+	evaluation.
+}
 }
 
 @Conference{Gamsa99
@@ -349,18 +514,76 @@ Operating System Design and Implementation}"
 ,Year="1999"
 ,pages="87-100"
 ,Address="New Orleans, LA"
+,note="Available:
+\url{http://www.usenix.org/events/osdi99/full_papers/gamsa/gamsa.pdf}
+[Viewed August 30, 2006]"
+,annotation={
+	Use of RCU-like facility in K42/Tornado.  Another independent
+	invention of RCU.
+	See especially pages 7-9 (Section 5).
+}
+}
+
+@unpublished{RustyRussell2000a
+,Author="Rusty Russell"
+,Title="Re: modular net drivers"
+,month="June"
+,year="2000"
+,day="23"
+,note="Available:
+\url{http://oss.sgi.com/projects/netdev/archive/2000-06/msg00250.html}
+[Viewed April 10, 2006]"
+,annotation={
+	Proto-RCU proposal from Phil Rumpf and Rusty Russell.
+	Yet another independent invention of RCU.
+	Outline of algorithm to unload modules...
+	.
+	Appeared on net-dev mailing list.
+}
+}
+
+@unpublished{RustyRussell2000b
+,Author="Rusty Russell"
+,Title="Re: modular net drivers"
+,month="June"
+,year="2000"
+,day="24"
+,note="Available:
+\url{http://oss.sgi.com/projects/netdev/archive/2000-06/msg00254.html}
+[Viewed April 10, 2006]"
+,annotation={
+	Proto-RCU proposal from Phil Rumpf and Rusty Russell.
+	.
+	Appeared on net-dev mailing list.
+}
+}
+
+@unpublished{McKenney01b
+,Author="Paul E. McKenney and Dipankar Sarma"
+,Title="Read-Copy Update Mutual Exclusion in {Linux}"
+,month="February"
+,year="2001"
+,note="Available:
+\url{http://lse.sourceforge.net/locking/rcu/rcupdate_doc.html}
+[Viewed October 18, 2004]"
+,annotation={
+	Prototypical Linux documentation for RCU.
+}
 }
 
 @techreport{Slingwine01
 ,author="John D. Slingwine and Paul E. McKenney"
-,title="Apparatus and method for achieving reduced overhead
-mutual exclusion and maintaining coherency in a multiprocessor
-system utilizing execution history and thread monitoring"
+,title="Apparatus and Method for Achieving Reduced Overhead Mutual
+Exclusion and Maintaining Coherency in a Multiprocessor System
+Utilizing Execution History and Thread Monitoring"
 ,institution="US Patent and Trademark Office"
 ,address="Washington, DC"
 ,year="2001"
-,number="US Patent 5,219,690 (contributed under GPL)"
+,number="US Patent 6,219,690"
 ,month="April"
+,annotation={
+	'Change in mode' aspect of RCU.  Can be thought of as a lazy barrier.
+}
 }
 
 @Conference{McKenney01a
@@ -372,14 +595,61 @@ Orran Krieger and Rusty Russell and Dipankar Sarma and Maneesh Soni"
 ,Year="2001"
 ,note="Available:
 \url{http://www.linuxsymposium.org/2001/abstracts/readcopy.php}
-\url{http://www.rdrop.com/users/paulmck/rclock/rclock_OLS.2001.05.01c.pdf}
+\url{http://www.rdrop.com/users/paulmck/RCU/rclock_OLS.2001.05.01c.pdf}
 [Viewed June 23, 2004]"
-annotation="
-Described RCU, and presented some patches implementing and using it in
-the Linux kernel.
+,annotation={
+	Described RCU, and presented some patches implementing and using
+	it in the Linux kernel.
+}
+}
+
+@unpublished{McKenney01f
+,Author="Paul E. McKenney"
+,Title="{RFC:} patch to allow lock-free traversal of lists with insertion"
+,month="October"
+,year="2001"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=100259266316456&w=2}
+[Viewed June 23, 2004]"
+,annotation="
+	Memory-barrier and Alpha thread.  100 messages, not too bad...
+"
+}
+
+@unpublished{Spraul01
+,Author="Manfred Spraul"
+,Title="Re: {RFC:} patch to allow lock-free traversal of lists with insertion"
+,month="October"
+,year="2001"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=100264675012867&w=2}
+[Viewed June 23, 2004]"
+,annotation="
+	Suggested burying memory barriers in Linux's list-manipulation
+	primitives.
 "
 }
 
+@unpublished{LinusTorvalds2001a
+,Author="Linus Torvalds"
+,Title="{Re:} {[Lse-tech]} {Re:} {RFC:} patch to allow lock-free traversal of lists with insertion"
+,month="October"
+,year="2001"
+,note="Available:
+\url{http://lkml.org/lkml/2001/10/13/105}
+[Viewed August 21, 2004]"
+}
+
+@unpublished{Blanchard02a
+,Author="Anton Blanchard"
+,Title="some RCU dcache and ratcache results"
+,month="March"
+,year="2002"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=101637107412972&w=2}
+[Viewed October 18, 2004]"
+}
+
 @Conference{Linder02a
 ,Author="Hanna Linder and Dipankar Sarma and Maneesh Soni"
 ,Title="Scalability of the Directory Entry Cache"
@@ -387,6 +657,10 @@ the Linux kernel.
 ,Month="June"
 ,Year="2002"
 ,pages="289-300"
+,annotation="
+	Measured scalability of Linux 2.4 kernel's directory-entry cache
+	(dcache), and measured some scalability enhancements.
+"
 }
 
 @Conference{McKenney02a
@@ -400,49 +674,76 @@ Andrea Arcangeli and Andi Kleen and Orran Krieger and Rusty Russell"
 ,note="Available:
 \url{http://www.linux.org.uk/~ajh/ols2002_proceedings.pdf.gz}
 [Viewed June 23, 2004]"
+,annotation="
+	Presented and compared a number of RCU implementations for the
+	Linux kernel.
+"
 }
 
-@conference{Michael02a
-,author="Maged M. Michael"
-,title="Safe Memory Reclamation for Dynamic Lock-Free Objects Using Atomic
-Reads and Writes"
-,Year="2002"
-,Month="August"
-,booktitle="{Proceedings of the 21\textsuperscript{st} Annual ACM
-Symposium on Principles of Distributed Computing}"
-,pages="21-30"
+@unpublished{Sarma02a
+,Author="Dipankar Sarma"
+,Title="specweb99: dcache scalability results"
+,month="July"
+,year="2002"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=102645767914212&w=2}
+[Viewed June 23, 2004]"
 ,annotation="
-	Each thread keeps an array of pointers to items that it is
-	currently referencing.	Sort of an inside-out garbage collection
-	mechanism, but one that requires the accessing code to explicitly
-	state its needs.  Also requires read-side memory barriers on
-	most architectures.
+	Compare fastwalk and RCU for dcache.  RCU won.
 "
 }
 
-@conference{Michael02b
-,author="Maged M. Michael"
-,title="High Performance Dynamic Lock-Free Hash Tables and List-Based Sets"
-,Year="2002"
-,Month="August"
-,booktitle="{Proceedings of the 14\textsuperscript{th} Annual ACM
-Symposium on Parallel
-Algorithms and Architecture}"
-,pages="73-82"
+@unpublished{Barbieri02
+,Author="Luca Barbieri"
+,Title="Re: {[PATCH]} Initial support for struct {vfs\_cred}"
+,month="August"
+,year="2002"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=103082050621241&w=2}
+[Viewed: June 23, 2004]"
 ,annotation="
-	Like the title says...
+	Suggested RCU for vfs\_shared\_cred.
 "
 }
 
-@InProceedings{HerlihyLM02
-,author={Maurice Herlihy and Victor Luchangco and Mark Moir}
-,title="The Repeat Offender Problem: A Mechanism for Supporting Dynamic-Sized,
-Lock-Free Data Structures"
-,booktitle={Proceedings of 16\textsuperscript{th} International
-Symposium on Distributed Computing}
-,year=2002
+@unpublished{Dickins02a
+,author="Hugh Dickins"
+,title="Use RCU for System-V IPC"
+,year="2002"
+,month="October"
+,note="private communication"
+}
+
+@unpublished{Sarma02b
+,Author="Dipankar Sarma"
+,Title="Some dcache\_rcu benchmark numbers"
 ,month="October"
-,pages="339-353"
+,year="2002"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=103462075416638&w=2}
+[Viewed June 23, 2004]"
+,annotation="
+	Performance of dcache RCU on kernbench for 16x NUMA-Q and 1x,
+	2x, and 4x systems.  RCU does no harm, and helps on 16x.
+"
+}
+
+@unpublished{LinusTorvalds2003a
+,Author="Linus Torvalds"
+,Title="Re: {[PATCH]} small fixes in brlock.h"
+,month="March"
+,year="2003"
+,note="Available:
+\url{http://lkml.org/lkml/2003/3/9/205}
+[Viewed March 13, 2006]"
+,annotation="
+	Linus suggests replacing brlock with RCU and/or seqlocks:
+	.
+	'It's entirely possible that the current user could be replaced
+	by RCU and/or seqlocks, and we could get rid of brlocks entirely.'
+	.
+	Steve Hemminger responds by replacing them with RCU.
+"
 }
 
 @article{Appavoo03a
@@ -457,6 +758,20 @@ B. Rosenburg and M. Stumm and J. Xenidis"
 ,volume="42"
 ,number="1"
 ,pages="60-76"
+,annotation="
+	Use of RCU to enable hot-swapping for autonomic behavior in K42.
+"
+}
+
+@unpublished{Seigh03
+,author="Joseph W. {Seigh II}"
+,title="Read Copy Update"
+,Year="2003"
+,Month="March"
+,note="email correspondence"
+,annotation="
+	Described the relationship of the VM/XA passive serialization to RCU.
+"
 }
 
 @Conference{Arcangeli03
@@ -470,6 +785,27 @@ Dipankar Sarma"
 ,year="2003"
 ,month="June"
 ,pages="297-310"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/rcu.FREENIX.2003.06.14.pdf}
+[Viewed November 21, 2007]"
+,annotation="
+	Compared updated RCU implementations for the Linux kernel, and
+	described System V IPC use of RCU, including order-of-magnitude
+	performance improvements.
+"
+}
+
+@Conference{Soules03a
+,Author="Craig A. N. Soules and Jonathan Appavoo and Kevin Hui and
+Dilma {Da Silva} and Gregory R. Ganger and Orran Krieger and
+Michael Stumm and Robert W. Wisniewski and Marc Auslander and
+Michal Ostrowski and Bryan Rosenburg and Jimi Xenidis"
+,Title="System Support for Online Reconfiguration"
+,Booktitle="Proceedings of the 2003 USENIX Annual Technical Conference"
+,Publisher="USENIX Association"
+,year="2003"
+,month="June"
+,pages="141-154"
 }
 
 @article{McKenney03a
@@ -481,6 +817,22 @@ Dipankar Sarma"
 ,volume="1"
 ,number="114"
 ,pages="18-26"
+,note="Available:
+\url{http://www.linuxjournal.com/article/6993}
+[Viewed November 14, 2007]"
+,annotation="
+	Reader-friendly intro to RCU, with the infamous old-man-and-brat
+	cartoon.
+"
+}
+
+@unpublished{Sarma03a
+,Author="Dipankar Sarma"
+,Title="RCU low latency patches"
+,month="December"
+,year="2003"
+,note="Message ID: 20031222180114.GA2248@in.ibm.com"
+,annotation="dipankar/ct.2004.03.27/RCUll.2003.12.22.patch"
 }
 
 @techreport{Friedberg03a
@@ -489,9 +841,14 @@ Dipankar Sarma"
 ,institution="US Patent and Trademark Office"
 ,address="Washington, DC"
 ,year="2003"
-,number="US Patent 6,662,184 (contributed under GPL)"
+,number="US Patent 6,662,184"
 ,month="December"
 ,pages="112"
+,annotation="
+	Applies RCU to a wildcard-search Patricia tree in order to permit
+	synchronization-free lookup.  RCU is used to retain removed nodes
+	for a grace period before freeing them.
+"
 }
 
 @article{McKenney04a
@@ -503,6 +860,12 @@ Dipankar Sarma"
 ,volume="1"
 ,number="118"
 ,pages="38-46"
+,note="Available:
+\url{http://www.linuxjournal.com/node/7124}
+[Viewed December 26, 2010]"
+,annotation="
+	Reader friendly intro to dcache and RCU.
+"
 }
 
 @Conference{McKenney04b
@@ -514,152 +877,824 @@ Dipankar Sarma"
 ,Address="Adelaide, Australia"
 ,note="Available:
 \url{http://www.linux.org.au/conf/2004/abstracts.html#90}
-\url{http://www.rdrop.com/users/paulmck/rclock/lockperf.2004.01.17a.pdf}
+\url{http://www.rdrop.com/users/paulmck/RCU/lockperf.2004.01.17a.pdf}
 [Viewed June 23, 2004]"
+,annotation="
+	Compares performance of RCU to that of other locking primitives
+	over a number of CPUs (x86, Opteron, Itanium, and PPC).
+"
 }
 
-@phdthesis{PaulEdwardMcKenneyPhD
-,author="Paul E. McKenney"
-,title="Exploiting Deferred Destruction:
-An Analysis of Read-Copy-Update Techniques
-in Operating System Kernels"
-,school="OGI School of Science and Engineering at
-Oregon Health and Sciences University"
+@unpublished{Sarma04a
+,Author="Dipankar Sarma"
+,Title="{[PATCH]} {RCU} for low latency (experimental)"
+,month="March"
+,year="2004"
+,note="\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108003746402892&w=2}"
+,annotation="Head of thread: dipankar/2004.03.23/rcu-low-lat.1.patch"
+}
+
+@unpublished{Sarma04b
+,Author="Dipankar Sarma"
+,Title="Re: {[PATCH]} {RCU} for low latency (experimental)"
+,month="March"
+,year="2004"
+,note="\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108016474829546&w=2}"
+,annotation="dipankar/rcuth.2004.03.24/rcu-throttle.patch"
+}
+
+@unpublished{Spraul04a
+,Author="Manfred Spraul"
+,Title="[RFC] 0/5 rcu lock update"
+,month="May"
 ,year="2004"
 ,note="Available:
-\url{http://www.rdrop.com/users/paulmck/RCU/RCUdissertation.2004.07.14e1.pdf}
-[Viewed October 15, 2004]"
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108546407726602&w=2}
+[Viewed June 23, 2004]"
+,annotation="
+	Hierarchical-bitmap patch for RCU infrastructure.
+"
+}
+
+@unpublished{Steiner04a
+,Author="Jack Steiner"
+,Title="Re: [Lse-tech] [RFC, PATCH] 1/5 rcu lock update:
+Add per-cpu batch counter"
+,month="May"
+,year="2004"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=108551764515332&w=2}
+[Viewed June 23, 2004]"
+,annotation={
+	RCU runs reasonably on a 512-CPU SGI using Manfred Spraul's patches,
+	which may be found at:
+	https://lkml.org/lkml/2004/5/20/49 (split vars into cachelines)
+	https://lkml.org/lkml/2004/5/22/114 (cpu_quiet() patch)
+	https://lkml.org/lkml/2004/5/25/24 (0/5)
+	https://lkml.org/lkml/2004/5/25/23 (1/5)
+		https://lkml.org/lkml/2004/5/25/265 (works for Jack)
+	https://lkml.org/lkml/2004/5/25/20 (2/5)
+	https://lkml.org/lkml/2004/5/25/22 (3/5)
+	https://lkml.org/lkml/2004/5/25/19 (4/5)
+	https://lkml.org/lkml/2004/5/25/21 (5/5)
+}
 }
 
 @Conference{Sarma04c
 ,Author="Dipankar Sarma and Paul E. McKenney"
-,Title="Making RCU Safe for Deep Sub-Millisecond Response Realtime Applications"
+,Title="Making {RCU} Safe for Deep Sub-Millisecond Response
+Realtime Applications"
 ,Booktitle="Proceedings of the 2004 USENIX Annual Technical Conference
 (FREENIX Track)"
 ,Publisher="USENIX Association"
 ,year="2004"
 ,month="June"
 ,pages="182-191"
+,annotation="
+	Describes and compares a number of modifications to the Linux RCU
+	implementation that make it friendly to realtime applications.
+"
 }
 
-@unpublished{JamesMorris04b
-,Author="James Morris"
-,Title="Recent Developments in {SELinux} Kernel Performance"
-,month="December"
+@phdthesis{PaulEdwardMcKenneyPhD
+,author="Paul E. McKenney"
+,title="Exploiting Deferred Destruction:
+An Analysis of Read-Copy-Update Techniques
+in Operating System Kernels"
+,school="OGI School of Science and Engineering at
+Oregon Health and Sciences University"
 ,year="2004"
 ,note="Available:
-\url{http://www.livejournal.com/users/james_morris/2153.html}
-[Viewed December 10, 2004]"
+\url{http://www.rdrop.com/users/paulmck/RCU/RCUdissertation.2004.07.14e1.pdf}
+[Viewed October 15, 2004]"
+,annotation="
+	Describes RCU implementations and presents design patterns
+	corresponding to common uses of RCU in several operating-system
+	kernels.
+"
 }
 
-@unpublished{PaulMcKenney05a
-,Author="Paul E. McKenney"
-,Title="{[RFC]} {RCU} and {CONFIG\_PREEMPT\_RT} progress"
-,month="May"
-,year="2005"
+@unpublished{PaulEMcKenney2004rcu:dereference
+,Author="Dipankar Sarma"
+,Title="{Re: RCU : Abstracted RCU dereferencing [5/5]}"
+,month="August"
+,year="2004"
 ,note="Available:
-\url{http://lkml.org/lkml/2005/5/9/185}
-[Viewed May 13, 2005]"
+\url{http://lkml.org/lkml/2004/8/6/237}
+[Viewed June 8, 2010]"
 ,annotation="
-	First publication of working lock-based deferred free patches
-	for the CONFIG_PREEMPT_RT environment.
+	Introduce rcu_dereference().
 "
 }
 
-@conference{PaulMcKenney05b
-,Author="Paul E. McKenney and Dipankar Sarma"
-,Title="Towards Hard Realtime Response from the Linux Kernel on SMP Hardware"
-,Booktitle="linux.conf.au 2005"
-,month="April"
-,year="2005"
-,address="Canberra, Australia"
+@unpublished{JimHouston04a
+,Author="Jim Houston"
+,Title="{[RFC\&PATCH] Alternative {RCU} implementation}"
+,month="August"
+,year="2004"
 ,note="Available:
-\url{http://www.rdrop.com/users/paulmck/RCU/realtimeRCU.2005.04.23a.pdf}
-[Viewed May 13, 2005]"
+\url{http://lkml.org/lkml/2004/8/30/87}
+[Viewed February 17, 2005]"
 ,annotation="
-	Realtime turns into making RCU yet more realtime friendly.
+	Uses active code in rcu_read_lock() and rcu_read_unlock() to
+	make RCU happen, allowing RCU to function on CPUs that do not
+	receive a scheduling-clock interrupt.
 "
 }
 
-@conference{ThomasEHart2006a
-,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown"
-,Title="Making Lockless Synchronization Fast: Performance Implications
-of Memory Reclamation"
-,Booktitle="20\textsuperscript{th} {IEEE} International Parallel and
-Distributed Processing Symposium"
-,month="April"
-,year="2006"
-,day="25-29"
-,address="Rhodes, Greece"
+@unpublished{TomHart04a
+,Author="Thomas E. Hart"
+,Title="Master's Thesis: Applying Lock-free Techniques to the {Linux} Kernel"
+,month="October"
+,year="2004"
+,note="Available:
+\url{http://www.cs.toronto.edu/~tomhart/masters_thesis.html}
+[Viewed October 15, 2004]"
 ,annotation="
-	Compares QSBR (AKA "classic RCU"), HPBR, EBR, and lock-free
-	reference counting.
+	Proposes comparing RCU to lock-free methods for the Linux kernel.
 "
 }
 
-@Conference{PaulEMcKenney2006b
-,Author="Paul E. McKenney and Dipankar Sarma and Ingo Molnar and
-Suparna Bhattacharya"
-,Title="Extending RCU for Realtime and Embedded Workloads"
-,Booktitle="{Ottawa Linux Symposium}"
-,Month="July"
-,Year="2006"
-,pages="v2 123-138"
+@unpublished{Vaddagiri04a
+,Author="Srivatsa Vaddagiri"
+,Title="Subject: [RFC] Use RCU for tcp\_ehash lookup"
+,month="October"
+,year="2004"
 ,note="Available:
-\url{http://www.linuxsymposium.org/2006/index_2006.php}
-\url{http://www.rdrop.com/users/paulmck/RCU/OLSrtRCU.2006.08.11a.pdf}
-[Viewed January 1, 2007]"
+\url{http://marc.theaimsgroup.com/?t=109395731700004&r=1&w=2}
+[Viewed October 18, 2004]"
 ,annotation="
-	Described how to improve the -rt implementation of realtime RCU.
+	Srivatsa's RCU patch for tcp_ehash lookup.
 "
 }
 
-@unpublished{PaulEMcKenney2006c
-,Author="Paul E. McKenney"
-,Title="Sleepable {RCU}"
+@unpublished{Thirumalai04a
+,Author="Ravikiran Thirumalai"
+,Title="Subject: [patchset] Lockfree fd lookup 0 of 5"
 ,month="October"
-,day="9"
-,year="2006"
+,year="2004"
 ,note="Available:
-\url{http://lwn.net/Articles/202847/}
-Revised:
-\url{http://www.rdrop.com/users/paulmck/RCU/srcu.2007.01.14a.pdf}
-[Viewed August 21, 2006]"
+\url{http://marc.theaimsgroup.com/?t=109144217400003&r=1&w=2}
+[Viewed October 18, 2004]"
 ,annotation="
-	LWN article introducing SRCU.
+	Ravikiran's lockfree FD patch.
+"
+}
+
+@unpublished{Thirumalai04b
+,Author="Ravikiran Thirumalai"
+,Title="Subject: Re: [patchset] Lockfree fd lookup 0 of 5"
+,month="October"
+,year="2004"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=109152521410459&w=2}
+[Viewed October 18, 2004]"
+,annotation="
+	Ravikiran's lockfree FD patch.
+"
+}
+
+@unpublished{PaulEMcKenney2004rcu:assign:pointer
+,Author="Paul E. McKenney"
+,Title="{[PATCH 1/3] RCU: \url{rcu_assign_pointer()} removal of memory barriers}"
+,month="October"
+,year="2004"
+,note="Available:
+\url{http://lkml.org/lkml/2004/10/23/241}
+[Viewed June 8, 2010]"
+,annotation="
+	Introduce rcu_assign_pointer().
+"
+}
+
+@unpublished{JamesMorris04a
+,Author="James Morris"
+,Title="{[PATCH 2/3] SELinux} scalability - convert {AVC} to {RCU}"
+,day="15"
+,month="November"
+,year="2004"
+,note="Available:
+\url{http://marc.theaimsgroup.com/?l=linux-kernel&m=110054979416004&w=2}
+[Viewed December 10, 2004]"
+,annotation="
+	James Morris posts Kaigai Kohei's patch to LKML.
+"
+}
+
+@unpublished{JamesMorris04b
+,Author="James Morris"
+,Title="Recent Developments in {SELinux} Kernel Performance"
+,month="December"
+,year="2004"
+,note="Available:
+\url{http://www.livejournal.com/users/james_morris/2153.html}
+[Viewed December 10, 2004]"
+,annotation="
+	RCU helps SELinux performance.  ;-)  Made LWN.
+"
+}
+
+@unpublished{PaulMcKenney2005RCUSemantics
+,Author="Paul E. McKenney and Jonathan Walpole"
+,Title="{RCU} Semantics: A First Attempt"
+,month="January"
+,year="2005"
+,day="30"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/rcu-semantics.2005.01.30a.pdf}
+[Viewed December 6, 2009]"
+,annotation="
+	Early derivation of RCU semantics.
+"
+}
+
+@unpublished{PaulMcKenney2005e
+,Author="Paul E. McKenney"
+,Title="Real-Time Preemption and {RCU}"
+,month="March"
+,year="2005"
+,day="17"
+,note="Available:
+\url{http://lkml.org/lkml/2005/3/17/199}
+[Viewed September 5, 2005]"
+,annotation="
+	First posting showing how RCU can be safely adapted for
+	preemptable RCU read side critical sections.
+"
+}
+
+@unpublished{EsbenNeilsen2005a
+,Author="Esben Neilsen"
+,Title="Re: Real-Time Preemption and {RCU}"
+,month="March"
+,year="2005"
+,day="18"
+,note="Available:
+\url{http://lkml.org/lkml/2005/3/18/122}
+[Viewed March 30, 2006]"
+,annotation="
+	Esben Neilsen suggests read-side suppression of grace-period
+	processing for crude-but-workable realtime RCU.  The downside
+	is indefinite grace periods...But this is OK for experimentation
+	and testing.
+"
+}
+
+@unpublished{TomHart05a
+,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown"
+,Title="Efficient Memory Reclamation is Necessary for Fast Lock-Free
+Data Structures"
+,month="March"
+,year="2005"
+,note="Available:
+\url{ftp://ftp.cs.toronto.edu/csrg-technical-reports/515/}
+[Viewed March 4, 2005]"
+,annotation="
+	Comparison of RCU, QBSR, and EBSR.  RCU wins for read-mostly
+	workloads.  ;-)
+"
+}
+
+@unpublished{JonCorbet2005DeprecateSyncKernel
+,Author="Jonathan Corbet"
+,Title="API change: synchronize_kernel() deprecated"
+,month="May"
+,day="3"
+,year="2005"
+,note="Available:
+\url{http://lwn.net/Articles/134484/}
+[Viewed May 3, 2005]"
+,annotation="
+	Jon Corbet describes deprecation of synchronize_kernel()
+	in favor of synchronize_rcu() and synchronize_sched().
+"
+}
+
+@unpublished{PaulMcKenney05a
+,Author="Paul E. McKenney"
+,Title="{[RFC]} {RCU} and {CONFIG\_PREEMPT\_RT} progress"
+,month="May"
+,year="2005"
+,note="Available:
+\url{http://lkml.org/lkml/2005/5/9/185}
+[Viewed May 13, 2005]"
+,annotation="
+	First publication of working lock-based deferred free patches
+	for the CONFIG_PREEMPT_RT environment.
+"
+}
+
+@conference{PaulMcKenney05b
+,Author="Paul E. McKenney and Dipankar Sarma"
+,Title="Towards Hard Realtime Response from the {Linux} Kernel on {SMP} Hardware"
+,Booktitle="linux.conf.au 2005"
+,month="April"
+,year="2005"
+,address="Canberra, Australia"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/realtimeRCU.2005.04.23a.pdf}
+[Viewed May 13, 2005]"
+,annotation="
+	Realtime turns into making RCU yet more realtime friendly.
+	http://lca2005.linux.org.au/Papers/Paul%20McKenney/Towards%20Hard%20Realtime%20Response%20from%20the%20Linux%20Kernel/LKS.2005.04.22a.pdf
+"
+}
+
+@unpublished{PaulEMcKenneyHomePage
+,Author="Paul E. McKenney"
+,Title="{Paul} {E.} {McKenney}"
+,month="May"
+,year="2005"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/}
+[Viewed May 25, 2005]"
+,annotation="
+	Paul McKenney's home page.
+"
+}
+
+@unpublished{PaulEMcKenneyRCUPage
+,Author="Paul E. McKenney"
+,Title="Read-Copy Update {(RCU)}"
+,month="May"
+,year="2005"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU}
+[Viewed May 25, 2005]"
+,annotation="
+	Paul McKenney's RCU page.
+"
+}
+
+@unpublished{JosephSeigh2005a
+,Author="Joseph Seigh"
+,Title="{RCU}+{SMR} (hazard pointers)"
+,month="July"
+,year="2005"
+,note="Personal communication"
+,annotation="
+	Joe Seigh announcing his atomic-ptr-plus project.
+	http://sourceforge.net/projects/atomic-ptr-plus/
+"
+}
+
+@unpublished{JosephSeigh2005b
+,Author="Joseph Seigh"
+,Title="Lock-free synchronization primitives"
+,month="July"
+,day="6"
+,year="2005"
+,note="Available:
+\url{http://sourceforge.net/projects/atomic-ptr-plus/}
+[Viewed August 8, 2005]"
+,annotation="
+	Joe Seigh's atomic-ptr-plus project.
+"
+}
+
+@unpublished{PaulMcKenney2005c
+,Author="Paul E.McKenney"
+,Title="{[RFC,PATCH] RCU} and {CONFIG\_PREEMPT\_RT} sane patch"
+,month="August"
+,day="1"
+,year="2005"
+,note="Available:
+\url{http://lkml.org/lkml/2005/8/1/155}
+[Viewed March 14, 2006]"
+,annotation="
+	First operating counter-based realtime RCU patch posted to LKML.
+"
+}
+
+@unpublished{PaulMcKenney2005d
+,Author="Paul E. McKenney"
+,Title="Re: [Fwd: Re: [patch] Real-Time Preemption, -RT-2.6.13-rc4-V0.7.52-01]"
+,month="August"
+,day="8"
+,year="2005"
+,note="Available:
+\url{http://lkml.org/lkml/2005/8/8/108}
+[Viewed March 14, 2006]"
+,annotation="
+	First operating counter-based realtime RCU patch posted to LKML,
+	but fixed so that various unusual combinations of configuration
+	parameters all function properly.
+"
+}
+
+@unpublished{PaulMcKenney2005rcutorture
+,Author="Paul E. McKenney"
+,Title="{[PATCH]} {RCU} torture testing"
+,month="October"
+,day="1"
+,year="2005"
+,note="Available:
+\url{http://lkml.org/lkml/2005/10/1/70}
+[Viewed March 14, 2006]"
+,annotation="
+	First rcutorture patch.
+"
+}
+
+@conference{ThomasEHart2006a
+,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown"
+,Title="Making Lockless Synchronization Fast: Performance Implications
+of Memory Reclamation"
+,Booktitle="20\textsuperscript{th} {IEEE} International Parallel and
+Distributed Processing Symposium"
+,month="April"
+,year="2006"
+,day="25-29"
+,address="Rhodes, Greece"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/hart_ipdps06.pdf}
+[Viewed April 28, 2008]"
+,annotation="
+	Compares QSBR, HPBR, EBR, and lock-free reference counting.
+	http://www.cs.toronto.edu/~tomhart/perflab/ipdps06.tgz
+"
+}
+
+@unpublished{NickPiggin2006radixtree
+,Author="Nick Piggin"
+,Title="[patch 3/3] radix-tree: {RCU} lockless readside"
+,month="June"
+,day="20"
+,year="2006"
+,note="Available:
+\url{http://lkml.org/lkml/2006/6/20/238}
+[Viewed March 25, 2008]"
+,annotation="
+	RCU-protected radix tree.
+"
+}
+
+@Conference{PaulEMcKenney2006b
+,Author="Paul E. McKenney and Dipankar Sarma and Ingo Molnar and
+Suparna Bhattacharya"
+,Title="Extending {RCU} for Realtime and Embedded Workloads"
+,Booktitle="{Ottawa Linux Symposium}"
+,Month="July"
+,Year="2006"
+,pages="v2 123-138"
+,note="Available:
+\url{http://www.linuxsymposium.org/2006/view_abstract.php?content_key=184}
+\url{http://www.rdrop.com/users/paulmck/RCU/OLSrtRCU.2006.08.11a.pdf}
+[Viewed January 1, 2007]"
+,annotation="
+	Described how to improve the -rt implementation of realtime RCU.
+"
+}
+
+@unpublished{WikipediaRCU
+,Author="Paul E. McKenney and Chris Purcell and Algae and Ben Schumin and
+Gaius Cornelius and Qwertyus and Neil Conway and Sbw and Blainster and
+Canis Rufus and Zoicon5 and Anome and Hal Eisen"
+,Title="Read-Copy Update"
+,month="July"
+,day="8"
+,year="2006"
+,note="Available:
+\url{http://en.wikipedia.org/wiki/Read-copy-update}
+[Viewed August 21, 2006]"
+,annotation="
+	Wikipedia RCU page as of July 8 2006.
+"
+}
+
+@Conference{NickPiggin2006LocklessPageCache
+,Author="Nick Piggin"
+,Title="A Lockless Pagecache in Linux---Introduction, Progress, Performance"
+,Booktitle="{Ottawa Linux Symposium}"
+,Month="July"
+,Year="2006"
+,pages="v2 249-254"
+,note="Available:
+\url{http://www.linuxsymposium.org/2006/view_abstract.php?content_key=184}
+[Viewed January 11, 2009]"
+,annotation="
+	Uses RCU-protected radix tree for a lockless page cache.
+"
+}
+
+@unpublished{PaulEMcKenney2006c
+,Author="Paul E. McKenney"
+,Title="Sleepable {RCU}"
+,month="October"
+,day="9"
+,year="2006"
+,note="Available:
+\url{http://lwn.net/Articles/202847/}
+Revised:
+\url{http://www.rdrop.com/users/paulmck/RCU/srcu.2007.01.14a.pdf}
+[Viewed August 21, 2006]"
+,annotation="
+	LWN article introducing SRCU.
 "
 }
 
 @unpublished{RobertOlsson2006a
 ,Author="Robert Olsson and Stefan Nilsson"
 ,Title="{TRASH}: A dynamic {LC}-trie and hash data structure"
-,month="August"
-,day="18"
-,year="2006"
+,month="August"
+,day="18"
+,year="2006"
+,note="Available:
+\url{http://www.nada.kth.se/~snilsson/publications/TRASH/trash.pdf}
+[Viewed March 4, 2011]"
+,annotation="
+	RCU-protected dynamic trie-hash combination.
+"
+}
+
+@unpublished{ChristophHellwig2006RCU2SRCU
+,Author="Christoph Hellwig"
+,Title="Re: {[-mm PATCH 1/4]} {RCU}: split classic rcu"
+,month="September"
+,day="28"
+,year="2006"
+,note="Available:
+\url{http://lkml.org/lkml/2006/9/28/160}
+[Viewed March 27, 2008]"
+}
+
+@unpublished{PaulEMcKenneyRCUusagePage
+,Author="Paul E. McKenney"
+,Title="{RCU} {Linux} Usage"
+,month="October"
+,year="2006"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/linuxusage.html}
+[Viewed January 14, 2007]"
+,annotation="
+	Paul McKenney's RCU page showing graphs plotting Linux-kernel
+	usage of RCU.
+"
+}
+
+@unpublished{PaulEMcKenneyRCUusageRawDataPage
+,Author="Paul E. McKenney"
+,Title="Read-Copy Update {(RCU)} Usage in {Linux} Kernel"
+,month="October"
+,year="2006"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/linuxusage/rculocktab.html}
+[Viewed January 14, 2007]"
+,annotation="
+	Paul McKenney's RCU page showing Linux usage of RCU in tabular
+	form, with links to corresponding cscope databases.
+"
+}
+
+@unpublished{GauthamShenoy2006RCUrwlock
+,Author="Gautham R. Shenoy"
+,Title="[PATCH 4/5] lock\_cpu\_hotplug: Redesign - Lightweight implementation of lock\_cpu\_hotplug"
+,month="October"
+,year="2006"
+,day=26
+,note="Available:
+\url{http://lkml.org/lkml/2006/10/26/73}
+[Viewed January 26, 2009]"
+,annotation="
+	RCU-based reader-writer lock that allows readers to proceed with
+	no memory barriers or atomic instruction in absence of writers.
+	If writer do show up, readers must of course wait as required by
+	the semantics of reader-writer locking.  This is a recursive
+	lock.
+"
+}
+
+@unpublished{JensAxboe2006SlowSRCU
+,Author="Jens Axboe"
+,Title="Re: [patch] cpufreq: mark \url{cpufreq_tsc()} as
+\url{core_initcall_sync}"
+,month="November"
+,year="2006"
+,day=17
+,note="Available:
+\url{http://lkml.org/lkml/2006/11/17/56}
+[Viewed May 28, 2007]"
+,annotation="
+	SRCU's grace periods are too slow for Jens, even after a
+	factor-of-three speedup.
+	Sped-up version of SRCU at http://lkml.org/lkml/2006/11/17/359.
+"
+}
+
+@unpublished{OlegNesterov2006QRCU
+,Author="Oleg Nesterov"
+,Title="Re: [patch] cpufreq: mark {\tt cpufreq\_tsc()} as
+{\tt core\_initcall\_sync}"
+,month="November"
+,year="2006"
+,day=19
+,note="Available:
+\url{http://lkml.org/lkml/2006/11/19/69}
+[Viewed May 28, 2007]"
+,annotation="
+	First cut of QRCU.  Expanded/corrected versions followed.
+	Used to be OlegNesterov2007QRCU, now time-corrected.
+"
+}
+
+@unpublished{OlegNesterov2006aQRCU
+,Author="Oleg Nesterov"
+,Title="Re: [RFC, PATCH 1/2] qrcu: {"quick"} srcu implementation"
+,month="November"
+,year="2006"
+,day=30
+,note="Available:
+\url{http://lkml.org/lkml/2006/11/29/330}
+[Viewed November 26, 2008]"
+,annotation="
+	Expanded/corrected version of QRCU.
+	Used to be OlegNesterov2007aQRCU, now time-corrected.
+"
+}
+
+@unpublished{EvgeniyPolyakov2006RCUslowdown
+,Author="Evgeniy Polyakov"
+,Title="Badness in postponing work"
+,month="December"
+,year="2006"
+,day=05
+,note="Available:
+\url{http://www.ioremap.net/node/41}
+[Viewed October 28, 2008]"
+,annotation="
+	Using RCU as a pure delay leads to a 2.5x slowdown in skbs in
+	the Linux kernel.
+"
+}
+
+@inproceedings{ChrisMatthews2006ClusteredObjectsRCU
+,author = {Matthews, Chris and Coady, Yvonne and Appavoo, Jonathan}
+,title = {Portability events: a programming model for scalable system infrastructures}
+,booktitle = {PLOS '06: Proceedings of the 3rd workshop on Programming languages and operating systems}
+,year = {2006}
+,isbn = {1-59593-577-0}
+,pages = {11}
+,location = {San Jose, California}
+,doi = {http://doi.acm.org/10.1145/1215995.1216006}
+,publisher = {ACM}
+,address = {New York, NY, USA}
+,annotation={
+	Uses K42's RCU-like functionality to manage clustered-object
+	lifetimes.
+}}
+
+@article{DilmaDaSilva2006K42
+,author = {Silva, Dilma Da and Krieger, Orran and Wisniewski, Robert W. and Waterland, Amos and Tam, David and Baumann, Andrew}
+,title = {K42: an infrastructure for operating system research}
+,journal = {SIGOPS Oper. Syst. Rev.}
+,volume = {40}
+,number = {2}
+,year = {2006}
+,issn = {0163-5980}
+,pages = {34--42}
+,doi = {http://doi.acm.org/10.1145/1131322.1131333}
+,publisher = {ACM}
+,address = {New York, NY, USA}
+,annotation={
+	Describes relationship of K42 generations to RCU.
+}}
+
+# CoreyMinyard2007list_splice_rcu
+@unpublished{CoreyMinyard2007list:splice:rcu
+,Author="Corey Minyard and Paul E. McKenney"
+,Title="{[PATCH]} add an {RCU} version of list splicing"
+,month="January"
+,year="2007"
+,day=3
+,note="Available:
+\url{http://lkml.org/lkml/2007/1/3/112}
+[Viewed May 28, 2007]"
+,annotation="
+	Patch for list_splice_rcu().
+"
+}
+
+@unpublished{PaulEMcKenney2007rcubarrier
+,Author="Paul E. McKenney"
+,Title="{RCU} and Unloadable Modules"
+,month="January"
+,day="14"
+,year="2007"
+,note="Available:
+\url{http://lwn.net/Articles/217484/}
+[Viewed November 22, 2007]"
+,annotation="
+	LWN article introducing the rcu_barrier() primitive.
+"
+}
+
+@unpublished{PeterZijlstra2007SyncBarrier
+,Author="Peter Zijlstra and Ingo Molnar"
+,Title="{[PATCH 3/7]} barrier: a scalable synchonisation barrier"
+,month="January"
+,year="2007"
+,day=28
+,note="Available:
+\url{http://lkml.org/lkml/2007/1/28/34}
+[Viewed March 27, 2008]"
+,annotation="
+	RCU-like implementation for frequent updaters and rare readers(!).
+	Subsumed into QRCU.  Maybe...
+"
+}
+
+@unpublished{PaulEMcKenney2007BoostRCU
+,Author="Paul E. McKenney"
+,Title="Priority-Boosting {RCU} Read-Side Critical Sections"
+,month="February"
+,day="5"
+,year="2007"
+,note="Available:
+\url{http://lwn.net/Articles/220677/}
+Revised:
+\url{http://www.rdrop.com/users/paulmck/RCU/RCUbooststate.2007.04.16a.pdf}
+[Viewed September 7, 2007]"
+,annotation="
+	LWN article introducing RCU priority boosting.
+"
+}
+
+@unpublished{PaulMcKenney2007QRCUpatch
+,Author="Paul E. McKenney"
+,Title="{[PATCH]} {QRCU} with lockless fastpath"
+,month="February"
+,year="2007"
+,day=24
+,note="Available:
+\url{http://lkml.org/lkml/2007/2/25/18}
+[Viewed March 27, 2008]"
+,annotation="
+	Patch for QRCU supplying lock-free fast path.
+"
+}
+
+@article{JonathanAppavoo2007K42RCU
+,author = {Appavoo, Jonathan and Silva, Dilma Da and Krieger, Orran and Auslander, Marc and Ostrowski, Michal and Rosenburg, Bryan and Waterland, Amos and Wisniewski, Robert W. and Xenidis, Jimi and Stumm, Michael and Soares, Livio}
+,title = {Experience distributing objects in an SMMP OS}
+,journal = {ACM Trans. Comput. Syst.}
+,volume = {25}
+,number = {3}
+,year = {2007}
+,issn = {0734-2071}
+,pages = {6/1--6/52}
+,doi = {http://doi.acm.org/10.1145/1275517.1275518}
+,publisher = {ACM}
+,address = {New York, NY, USA}
+,annotation={
+	Role of RCU in K42.
+}}
+
+@conference{RobertOlsson2007Trash
+,Author="Robert Olsson and Stefan Nilsson"
+,Title="{TRASH}: A dynamic {LC}-trie and hash data structure"
+,booktitle="Workshop on High Performance Switching and Routing (HPSR'07)"
+,month="May"
+,year="2007"
 ,note="Available:
-\url{http://www.nada.kth.se/~snilsson/public/papers/trash/trash.pdf}
-[Viewed February 24, 2007]"
+\url{http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4281239}
+[Viewed October 1, 2010]"
 ,annotation="
 	RCU-protected dynamic trie-hash combination.
 "
 }
 
-@unpublished{ThomasEHart2007a
-,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown and Jonathan Walpole"
-,Title="Performance of memory reclamation for lockless synchronization"
-,journal="J. Parallel Distrib. Comput."
+@conference{PeterZijlstra2007ConcurrentPagecacheRCU
+,Author="Peter Zijlstra"
+,Title="Concurrent Pagecache"
+,Booktitle="Linux Symposium"
+,month="June"
+,year="2007"
+,address="Ottawa, Canada"
+,note="Available:
+\url{http://ols.108.redhat.com/2007/Reprints/zijlstra-Reprint.pdf}
+[Viewed April 14, 2008]"
+,annotation="
+	Page-cache modifications permitting RCU readers and concurrent
+	updates.
+"
+}
+
+@unpublished{PaulEMcKenney2007whatisRCU
+,Author="Paul E. McKenney"
+,Title="What is {RCU}?"
 ,year="2007"
-,note="To appear in J. Parallel Distrib. Comput.
-       \url{doi=10.1016/j.jpdc.2007.04.010}"
+,month="07"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/whatisRCU.html}
+[Viewed July 6, 2007]"
 ,annotation={
-	Compares QSBR (AKA "classic RCU"), HPBR, EBR, and lock-free
-	reference counting.  Journal version of ThomasEHart2006a.
+	Describes RCU in Linux kernel.
 }
 }
 
 @unpublished{PaulEMcKenney2007QRCUspin
 ,Author="Paul E. McKenney"
-,Title="Using Promela and Spin to verify parallel algorithms"
+,Title="Using {Promela} and {Spin} to verify parallel algorithms"
 ,month="August"
 ,day="1"
 ,year="2007"
@@ -669,6 +1704,50 @@ Revised:
 ,annotation="
 	LWN article describing Promela and spin, and also using Oleg
 	Nesterov's QRCU as an example (with Paul McKenney's fastpath).
+	Merged patch at: http://lkml.org/lkml/2007/2/25/18
+"
+}
+
+@unpublished{PaulEMcKenney2007WG21DDOatomics
+,Author="Paul E. McKenney and Hans-J. Boehm and Lawrence Crowl"
+,Title="C++ Data-Dependency Ordering: Atomics and Memory Model"
+,month="August"
+,day="3"
+,year="2007"
+,note="Preprint:
+\url{http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm}
+[Viewed December 7, 2009]"
+,annotation="
+	RCU for C++, parts 1 and 2.
+"
+}
+
+@unpublished{PaulEMcKenney2007WG21DDOannotation
+,Author="Paul E. McKenney and Lawrence Crowl"
+,Title="C++ Data-Dependency Ordering: Function Annotation"
+,month="September"
+,day="18"
+,year="2008"
+,note="Preprint:
+\url{http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2782.htm}
+[Viewed December 7, 2009]"
+,annotation="
+	RCU for C++, part 2, updated many times.
+"
+}
+
+@unpublished{PaulEMcKenney2007PreemptibleRCUPatch
+,Author="Paul E. McKenney"
+,Title="[PATCH RFC 0/9] {RCU}: Preemptible {RCU}"
+,month="September"
+,day="10"
+,year="2007"
+,note="Available:
+\url{http://lkml.org/lkml/2007/9/10/213}
+[Viewed October 25, 2007]"
+,annotation="
+	Final patch for preemptable RCU to -rt.  (Later patches were
+	to mainline, eventually incorporated.)
 "
 }
 
@@ -686,10 +1765,46 @@ Revised:
 "
 }
 
+@article{ThomasEHart2007a
+,Author="Thomas E. Hart and Paul E. McKenney and Angela Demke Brown and Jonathan Walpole"
+,Title="Performance of memory reclamation for lockless synchronization"
+,journal="J. Parallel Distrib. Comput."
+,volume={67}
+,number="12"
+,year="2007"
+,issn="0743-7315"
+,pages="1270--1285"
+,doi="http://dx.doi.org/10.1016/j.jpdc.2007.04.010"
+,publisher="Academic Press, Inc."
+,address="Orlando, FL, USA"
+,annotation={
+	Compares QSBR, HPBR, EBR, and lock-free reference counting.
+	Journal version of ThomasEHart2006a.
+}
+}
+
+@unpublished{MathieuDesnoyers2007call:rcu:schedNeeded
+,Author="Mathieu Desnoyers"
+,Title="Re: [patch 1/2] {Linux} Kernel Markers - Support Multiple Probes"
+,month="December"
+,day="20"
+,year="2007"
+,note="Available:
+\url{http://lkml.org/lkml/2007/12/20/244}
+[Viewed March 27, 2008]"
+,annotation="
+	Request for call_rcu_sched() and rcu_barrier_sched().
+"
+}
+
+
 ########################################################################
 #
 #	"What is RCU?" LWN series.
 #
+#	http://lwn.net/Articles/262464/ (What is RCU, Fundamentally?)
+#	http://lwn.net/Articles/263130/ (What is RCU's Usage?)
+#	http://lwn.net/Articles/264090/ (What is RCU's API?)
 
 @unpublished{PaulEMcKenney2007WhatIsRCUFundamentally
 ,Author="Paul E. McKenney and Jonathan Walpole"
@@ -723,7 +1838,7 @@ Revised:
 	3. RCU is a Bulk Reference-Counting Mechanism
 	4. RCU is a Poor Man's Garbage Collector
 	5. RCU is a Way of Providing Existence Guarantees
-	6. RCU is a Way of Waiting for Things to Finish 
+	6. RCU is a Way of Waiting for Things to Finish
 "
 }
 
@@ -747,20 +1862,96 @@ Revised:
 #
 ########################################################################
 
+
+@unpublished{SteveRostedt2008dyntickRCUpatch
+,Author="Steven Rostedt and Paul E. McKenney"
+,Title="{[PATCH]} add support for dynamic ticks and preempt rcu"
+,month="January"
+,day="29"
+,year="2008"
+,note="Available:
+\url{http://lkml.org/lkml/2008/1/29/208}
+[Viewed March 27, 2008]"
+,annotation="
+	Patch that prevents preemptible RCU from unnecessarily waking
+	up dynticks-idle CPUs.
+"
+}
+
+@unpublished{PaulEMcKenney2008LKMLDependencyOrdering
+,Author="Paul E. McKenney"
+,Title="Re: [PATCH 02/22 -v7] Add basic support for gcc profiler instrumentation"
+,month="February"
+,day="1"
+,year="2008"
+,note="Available:
+\url{http://lkml.org/lkml/2008/2/2/255}
+[Viewed October 18, 2008]"
+,annotation="
+	Explanation of compilers violating dependency ordering.
+"
+}
+
+@Conference{PaulEMcKenney2008Beijing
+,Author="Paul E. McKenney"
+,Title="Introducing Technology Into {Linux} Or:
+Introducing your technology Into {Linux} will require introducing a
+lot of {Linux} into your technology!!!"
+,Booktitle="2008 Linux Developer Symposium - China"
+,Publisher="OSS China"
+,Month="February"
+,Year="2008"
+,Address="Beijing, China"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/TechIntroLinux.2008.02.19a.pdf}
+[Viewed August 12, 2008]"
+}
+
+@unpublished{PaulEMcKenney2008dynticksRCU
+,Author="Paul E. McKenney and Steven Rostedt"
+,Title="Integrating and Validating dynticks and Preemptable RCU"
+,month="April"
+,day="24"
+,year="2008"
+,note="Available:
+\url{http://lwn.net/Articles/279077/}
+[Viewed April 24, 2008]"
+,annotation="
+	Describes use of Promela and Spin to validate (and fix!) the
+	dynticks/RCU interface.
+"
+}
+
 @article{DinakarGuniguntala2008IBMSysJ
 ,author="D. Guniguntala and P. E. McKenney and J. Triplett and J. Walpole"
 ,title="The read-copy-update mechanism for supporting real-time applications on shared-memory multiprocessor systems with {Linux}"
 ,Year="2008"
-,Month="April"
+,Month="April-June"
 ,journal="IBM Systems Journal"
 ,volume="47"
 ,number="2"
-,pages="@@-@@"
+,pages="221-236"
 ,annotation="
 	RCU, realtime RCU, sleepable RCU, performance.
 "
 }
 
+@unpublished{LaiJiangshan2008NewClassicAlgorithm
+,Author="Lai Jiangshan"
+,Title="[{RFC}][{PATCH}] rcu classic: new algorithm for callbacks-processing"
+,month="June"
+,day="3"
+,year="2008"
+,note="Available:
+\url{http://lkml.org/lkml/2008/6/2/539}
+[Viewed December 10, 2008]"
+,annotation="
+	Updated RCU classic algorithm.  Introduced multi-tailed list
+	for RCU callbacks and also pulling common code into
+	__call_rcu().
+"
+}
+
 @article{PaulEMcKenney2008RCUOSR
 ,author="Paul E. McKenney and Jonathan Walpole"
 ,title="Introducing technology into the {Linux} kernel: a case study"
@@ -778,6 +1969,52 @@ Revised:
 }
 }
 
+@unpublished{ManfredSpraul2008StateMachineRCU
+,Author="Manfred Spraul"
+,Title="[{RFC}, {PATCH}] state machine based rcu"
+,month="August"
+,day="21"
+,year="2008"
+,note="Available:
+\url{http://lkml.org/lkml/2008/8/21/336}
+[Viewed December 8, 2008]"
+,annotation="
+	State-based RCU.  One key thing that this patch does is to
+	separate the dynticks handling of NMIs and IRQs.
+"
+}
+
+@unpublished{ManfredSpraul2008dyntickIRQNMI
+,Author="Manfred Spraul"
+,Title="Re: [{RFC}, {PATCH}] v4 scalable classic {RCU} implementation"
+,month="September"
+,day="6"
+,year="2008"
+,note="Available:
+\url{http://lkml.org/lkml/2008/9/6/86}
+[Viewed December 8, 2008]"
+,annotation="
+	Manfred notes a fix required to my attempt to separate irq
+	and NMI processing for hierarchical RCU's dynticks interface.
+"
+}
+
+@techreport{PaulEMcKenney2008cyclicRCU
+,author="Paul E. McKenney"
+,title="Efficient Support of Consistent Cyclic Search With Read-Copy Update"
+,institution="US Patent and Trademark Office"
+,address="Washington, DC"
+,year="2008"
+,number="US Patent 7,426,511"
+,month="September"
+,pages="23"
+,annotation="
+	Maintains an additional level of indirection to allow
+	readers to confine themselves to the desired snapshot of the
+	data structure.  Only permits one update at a time.
+"
+}
+
 @unpublished{PaulEMcKenney2008HierarchicalRCU
 ,Author="Paul E. McKenney"
 ,Title="Hierarchical {RCU}"
@@ -793,6 +2030,21 @@ Revised:
 "
 }
 
+@unpublished{PaulEMcKenney2009BloatwatchRCU
+,Author="Paul E. McKenney"
+,Title="Re: [PATCH fyi] RCU: the bloatwatch edition"
+,month="January"
+,day="14"
+,year="2009"
+,note="Available:
+\url{http://lkml.org/lkml/2009/1/14/449}
+[Viewed January 15, 2009]"
+,annotation="
+	Small-footprint implementation of RCU for uniprocessor
+	embedded applications -- and also for exposition purposes.
+"
+}
+
 @conference{PaulEMcKenney2009MaliciousURCU
 ,Author="Paul E. McKenney"
 ,Title="Using a Malicious User-Level {RCU} to Torture {RCU}-Based Algorithms"
@@ -816,15 +2068,17 @@ Revised:
 ,year="2009"
 ,note="Available:
 \url{http://lkml.org/lkml/2009/2/5/572}
-\url{git://lttng.org/userspace-rcu.git}
+\url{http://lttng.org/urcu}
 [Viewed February 20, 2009]"
 ,annotation="
 	Mathieu Desnoyers's user-space RCU implementation.
 	git://lttng.org/userspace-rcu.git
+	http://lttng.org/cgi-bin/gitweb.cgi?p=userspace-rcu.git
+	http://lttng.org/urcu
 "
 }
 
-@unpublished{PaulEMcKenney2009BloatWatchRCU
+@unpublished{PaulEMcKenney2009LWNBloatWatchRCU
 ,Author="Paul E. McKenney"
 ,Title="{RCU}: The {Bloatwatch} Edition"
 ,month="March"
@@ -852,14 +2106,29 @@ Revised:
 "
 }
 
-@unpublished{JoshTriplett2009RPHash
+@unpublished{PaulEMcKenney2009fastRTRCU
+,Author="Paul E. McKenney"
+,Title="[{PATCH} {RFC} -tip 0/4] {RCU} cleanups and simplified preemptable {RCU}"
+,month="July"
+,day="23"
+,year="2009"
+,note="Available:
+\url{http://lkml.org/lkml/2009/7/23/294}
+[Viewed August 15, 2009]"
+,annotation="
+	First posting of simple and fast preemptable RCU.
+"
+}
+
+@InProceedings{JoshTriplett2009RPHash
 ,Author="Josh Triplett"
 ,Title="Scalable concurrent hash tables via relativistic programming"
 ,month="September"
 ,year="2009"
-,note="Linux Plumbers Conference presentation"
+,booktitle="Linux Plumbers Conference 2009"
 ,annotation="
 	RP fun with hash tables.
+	See also JoshTriplett2010RPHash
 "
 }
 
@@ -872,4 +2141,323 @@ Revised:
 ,note="Available:
 \url{http://www.lttng.org/pub/thesis/desnoyers-dissertation-2009-12.pdf}
 [Viewed December 9, 2009]"
+,annotation={
+	Chapter 6 (page 97) covers user-level RCU.
+}
+}
+
+@unpublished{RelativisticProgrammingWiki
+,Author="Josh Triplett and Paul E. McKenney and Jonathan Walpole"
+,Title="Relativistic Programming"
+,month="September"
+,year="2009"
+,note="Available:
+\url{http://wiki.cs.pdx.edu/rp/}
+[Viewed December 9, 2009]"
+,annotation="
+	Main Relativistic Programming Wiki.
+"
+}
+
+@conference{PaulEMcKenney2009DeterministicRCU
+,Author="Paul E. McKenney"
+,Title="Deterministic Synchronization in Multicore Systems: the Role of {RCU}"
+,Booktitle="Eleventh Real Time Linux Workshop"
+,month="September"
+,year="2009"
+,address="Dresden, Germany"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/realtime/paper/DetSyncRCU.2009.08.18a.pdf}
+[Viewed January 14, 2009]"
+}
+
+@unpublished{PaulEMcKenney2009HuntingHeisenbugs
+,Author="Paul E. McKenney"
+,Title="Hunting Heisenbugs"
+,month="November"
+,year="2009"
+,day="1"
+,note="Available:
+\url{http://paulmck.livejournal.com/14639.html}
+[Viewed June 4, 2010]"
+,annotation="
+	Day-one bug in Tree RCU that took forever to track down.
+"
+}
+
+@unpublished{MathieuDesnoyers2009defer:rcu
+,Author="Mathieu Desnoyers"
+,Title="Kernel RCU: shrink the size of the struct rcu\_head"
+,month="December"
+,year="2009"
+,note="Available:
+\url{http://lkml.org/lkml/2009/10/18/129}
+[Viewed December 29, 2009]"
+,annotation="
+	Mathieu proposed defer_rcu() with fixed-size per-thread pool
+	of RCU callbacks.
+"
+}
+
+@unpublished{MathieuDesnoyers2009VerifPrePub
+,Author="Mathieu Desnoyers and Paul E. McKenney and Michel R. Dagenais"
+,Title="Multi-Core Systems Modeling for Formal Verification of Parallel Algorithms"
+,month="December"
+,year="2009"
+,note="Submitted to IEEE TPDS"
+,annotation="
+	OOMem model for Mathieu's user-level RCU mechanical proof of
+	correctness.
+"
+}
+
+@unpublished{MathieuDesnoyers2009URCUPrePub
+,Author="Mathieu Desnoyers and Paul E. McKenney and Alan Stern and Michel R. Dagenais and Jonathan Walpole"
+,Title="User-Level Implementations of Read-Copy Update"
+,month="December"
+,year="2010"
+,url=\url{http://www.computer.org/csdl/trans/td/2012/02/ttd2012020375-abs.html}
+,annotation="
+	RCU overview, desiderata, semi-formal semantics, user-level RCU
+	usage scenarios, three classes of RCU implementation, wait-free
+	RCU updates, RCU grace-period batching, update overhead,
+	http://www.rdrop.com/users/paulmck/RCU/urcu-main-accepted.2011.08.30a.pdf
+	http://www.rdrop.com/users/paulmck/RCU/urcu-supp-accepted.2011.08.30a.pdf
+	Superseded by MathieuDesnoyers2012URCU.
+"
+}
+
+@inproceedings{HariKannan2009DynamicAnalysisRCU
+,author = {Kannan, Hari}
+,title = {Ordering decoupled metadata accesses in multiprocessors}
+,booktitle = {MICRO 42: Proceedings of the 42nd Annual IEEE/ACM International Symposium on Microarchitecture}
+,year = {2009}
+,isbn = {978-1-60558-798-1}
+,pages = {381--390}
+,location = {New York, New York}
+,doi = {http://doi.acm.org/10.1145/1669112.1669161}
+,publisher = {ACM}
+,address = {New York, NY, USA}
+,annotation={
+	Uses RCU to protect metadata used in dynamic analysis.
+}}
+
+@conference{PaulEMcKenney2010SimpleOptRCU
+,Author="Paul E. McKenney"
+,Title="Simplicity Through Optimization"
+,Booktitle="linux.conf.au 2010"
+,month="January"
+,year="2010"
+,address="Wellington, New Zealand"
+,note="Available:
+\url{http://www.rdrop.com/users/paulmck/RCU/SimplicityThruOptimization.2010.01.21f.pdf}
+[Viewed October 10, 2010]"
+,annotation="
+	TREE_PREEMPT_RCU optimizations greatly simplified the old
+	PREEMPT_RCU implementation.
+"
+}
+
+@unpublished{PaulEMcKenney2010LockdepRCU
+,Author="Paul E. McKenney"
+,Title="Lockdep-{RCU}"
+,month="February"
+,year="2010"
+,day="1"
+,note="Available:
+\url{https://lwn.net/Articles/371986/}
+[Viewed June 4, 2010]"
+,annotation="
+	CONFIG_PROVE_RCU, or at least an early version.
+"
+}
+
+@unpublished{AviKivity2010KVM2RCU
+,Author="Avi Kivity"
+,Title="[{PATCH} 37/40] {KVM}: Bump maximum vcpu count to 64"
+,month="February"
+,year="2010"
+,note="Available:
+\url{http://www.mail-archive.com/kvm@vger.kernel.org/msg28640.html}
+[Viewed March 20, 2010]"
+,annotation="
+	Use of RCU permits KVM to increase the size of guest OSes from
+	16 CPUs to 64 CPUs.
+"
+}
+
+@unpublished{HerbertXu2010RCUResizeHash
+,Author="Herbert Xu"
+,Title="bridge: Add core IGMP snooping support"
+,month="February"
+,year="2010"
+,note="Available:
+\url{http://kerneltrap.com/mailarchive/linux-netdev/2010/2/26/6270589}
+[Viewed March 20, 2011]"
+,annotation={
+	Use a pair of list_head structures to support RCU-protected
+	resizable hash tables.
+}}
+
+@article{JoshTriplett2010RPHash
+,author="Josh Triplett and Paul E. McKenney and Jonathan Walpole"
+,title="Scalable Concurrent Hash Tables via Relativistic Programming"
+,journal="ACM Operating Systems Review"
+,year=2010
+,volume=44
+,number=3
+,month="July"
+,annotation={
+	RP fun with hash tables.
+	http://portal.acm.org/citation.cfm?id=1842733.1842750
+}}
+
+@unpublished{PaulEMcKenney2010RCUAPI
+,Author="Paul E. McKenney"
+,Title="The {RCU} {API}, 2010 Edition"
+,month="December"
+,day="8"
+,year="2010"
+,note="Available:
+\url{http://lwn.net/Articles/418853/}
+[Viewed December 8, 2010]"
+,annotation="
+	Includes updated software-engineering features.
+"
+}
+
+@mastersthesis{AndrejPodzimek2010masters
+,author="Andrej Podzimek"
+,title="Read-Copy-Update for OpenSolaris"
+,school="Charles University in Prague"
+,year="2010"
+,note="Available:
+\url{https://andrej.podzimek.org/thesis.pdf}
+[Viewed January 31, 2011]"
+,annotation={
+	Reviews RCU implementations and creates a few for OpenSolaris.
+	Drives quiescent-state detection from RCU read-side primitives,
+	in a manner roughly similar to that of Jim Houston.
+}}
+
+@unpublished{LinusTorvalds2011Linux2:6:38:rc1:NPigginVFS
+,Author="Linus Torvalds"
+,Title="Linux 2.6.38-rc1"
+,month="January"
+,year="2011"
+,note="Available:
+\url{https://lkml.org/lkml/2011/1/18/322}
+[Viewed March 4, 2011]"
+,annotation={
+	"The RCU-based name lookup is at the other end of the spectrum - the
+	absolute anti-gimmick. It's some seriously good stuff, and gets rid of
+	the last main global lock that really tends to hurt some kernel loads.
+	The dentry lock is no longer a big serializing issue. What's really
+	nice about it is that it actually improves performance a lot even for
+	single-threaded loads (on an SMP kernel), because it gets rid of some
+	of the most expensive parts of path component lookup, which was the
+	d_lock on every component lookup. So I'm seeing improvements of 30-50%
+	on some seriously pathname-lookup intensive loads."
+}}
+
+@techreport{JoshTriplett2011RPScalableCorrectOrdering
+,author = {Josh Triplett and Philip W. Howard and Paul E. McKenney and Jonathan Walpole}
+,title = {Scalable Correct Memory Ordering via Relativistic Programming}
+,year = {2011}
+,number = {11-03}
+,institution = {Portland State University}
+,note = {\url{http://www.cs.pdx.edu/pdfs/tr1103.pdf}}
+}
+
+@inproceedings{PhilHoward2011RCUTMRBTree
+,author = {Philip W. Howard and Jonathan Walpole}
+,title = {A Relativistic Enhancement to Software Transactional Memory}
+,booktitle = {Proceedings of the 3rd USENIX conference on Hot topics in parallelism}
+,series = {HotPar'11}
+,year = {2011}
+,location = {Berkeley, CA}
+,pages = {1--6}
+,numpages = {6}
+,url = {http://www.usenix.org/event/hotpar11/tech/final_files/Howard.pdf}
+,publisher = {USENIX Association}
+,address = {Berkeley, CA, USA}
+}
+
+@techreport{PaulEMcKenney2011cyclicparallelRCU
+,author="Paul E. McKenney and Jonathan Walpole"
+,title="Efficient Support of Consistent Cyclic Search With Read-Copy Update and Parallel Updates"
+,institution="US Patent and Trademark Office"
+,address="Washington, DC"
+,year="2011"
+,number="US Patent 7,953,778"
+,month="May"
+,pages="34"
+,annotation="
+	Maintains an array of generation numbers to track in-flight
+	updates and keeps an additional level of indirection to allow
+	readers to confine themselves to the desired snapshot of the
+	data structure.
+"
+}
+
+@inproceedings{Triplett:2011:RPHash
+,author = {Triplett, Josh and McKenney, Paul E. and Walpole, Jonathan}
+,title = {Resizable, Scalable, Concurrent Hash Tables via Relativistic Programming}
+,booktitle = {Proceedings of the 2011 USENIX Annual Technical Conference}
+,month = {June}
+,year = {2011}
+,pages = {145--158}
+,numpages = {14}
+,url={http://www.usenix.org/event/atc11/tech/final_files/atc11_proceedings.pdf}
+,publisher = {The USENIX Association}
+,address = {Portland, OR USA}
+}
+
+@unpublished{PaulEMcKenney2011RCU3.0trainwreck
+,Author="Paul E. McKenney"
+,Title="3.0 and {RCU:} what went wrong"
+,month="July"
+,day="27"
+,year="2011"
+,note="Available:
+\url{http://lwn.net/Articles/453002/}
+[Viewed July 27, 2011]"
+,annotation="
+	Analysis of the RCU trainwreck in Linux kernel 3.0.
+"
+}
+
+@unpublished{NeilBrown2011MeetTheLockers
+,Author="Neil Brown"
+,Title="Meet the Lockers"
+,month="August"
+,day="3"
+,year="2011"
+,note="Available:
+\url{http://lwn.net/Articles/453685/}
+[Viewed September 2, 2011]"
+,annotation="
+	The Locker family as an analogy for locking, reference counting,
+	RCU, and seqlock.
+"
+}
+
+@article{MathieuDesnoyers2012URCU
+,Author="Mathieu Desnoyers and Paul E. McKenney and Alan Stern and Michel R. Dagenais and Jonathan Walpole"
+,Title="User-Level Implementations of Read-Copy Update"
+,journal="IEEE Transactions on Parallel and Distributed Systems"
+,volume={23}
+,year="2012"
+,issn="1045-9219"
+,pages="375-382"
+,doi="http://doi.ieeecomputersociety.org/10.1109/TPDS.2011.159"
+,publisher="IEEE Computer Society"
+,address="Los Alamitos, CA, USA"
+,annotation={
+	RCU overview, desiderata, semi-formal semantics, user-level RCU
+	usage scenarios, three classes of RCU implementation, wait-free
+	RCU updates, RCU grace-period batching, update overhead,
+	http://www.rdrop.com/users/paulmck/RCU/urcu-main-accepted.2011.08.30a.pdf
+	http://www.rdrop.com/users/paulmck/RCU/urcu-supp-accepted.2011.08.30a.pdf
+}
 }
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index bff2d8b..5c8d749 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -180,6 +180,20 @@ over a rather long period of time, but improvements are always welcome!
 	operations that would not normally be undertaken while a real-time
 	workload is running.
 
+	In particular, if you find yourself invoking one of the expedited
+	primitives repeatedly in a loop, please do everyone a favor:
+	Restructure your code so that it batches the updates, allowing
+	a single non-expedited primitive to cover the entire batch.
+	This will very likely be faster than the loop containing the
+	expedited primitive, and will be much much easier on the rest
+	of the system, especially to real-time workloads running on
+	the rest of the system.
+
+	In addition, it is illegal to call the expedited forms from
+	a CPU-hotplug notifier, or while holding a lock that is acquired
+	by a CPU-hotplug notifier.  Failing to observe this restriction
+	will result in deadlock.
+
 7.	If the updater uses call_rcu() or synchronize_rcu(), then the
 	corresponding readers must use rcu_read_lock() and
 	rcu_read_unlock().  If the updater uses call_rcu_bh() or
diff --git a/Documentation/RCU/stallwarn.txt b/Documentation/RCU/stallwarn.txt
index 083d88c..523364e 100644
--- a/Documentation/RCU/stallwarn.txt
+++ b/Documentation/RCU/stallwarn.txt
@@ -12,14 +12,38 @@ CONFIG_RCU_CPU_STALL_TIMEOUT
 	This kernel configuration parameter defines the period of time
 	that RCU will wait from the beginning of a grace period until it
 	issues an RCU CPU stall warning.  This time period is normally
-	ten seconds.
+	sixty seconds.
 
-RCU_SECONDS_TILL_STALL_RECHECK
+	This configuration parameter may be changed at runtime via the
+	/sys/module/rcutree/parameters/rcu_cpu_stall_timeout, however
+	this parameter is checked only at the beginning of a cycle.
+	So if you are 30 seconds into a 70-second stall, setting this
+	sysfs parameter to (say) five will shorten the timeout for the
+	-next- stall, or the following warning for the current stall
+	(assuming the stall lasts long enough).  It will not affect the
+	timing of the next warning for the current stall.
 
-	This macro defines the period of time that RCU will wait after
-	issuing a stall warning until it issues another stall warning
-	for the same stall.  This time period is normally set to three
-	times the check interval plus thirty seconds.
+	Stall-warning messages may be enabled and disabled completely via
+	/sys/module/rcutree/parameters/rcu_cpu_stall_suppress.
+
+CONFIG_RCU_CPU_STALL_VERBOSE
+
+	This kernel configuration parameter causes the stall warning to
+	also dump the stacks of any tasks that are blocking the current
+	RCU-preempt grace period.
+
+RCU_CPU_STALL_INFO
+
+	This kernel configuration parameter causes the stall warning to
+	print out additional per-CPU diagnostic information, including
+	information on scheduling-clock ticks and RCU's idle-CPU tracking.
+
+RCU_STALL_DELAY_DELTA
+
+	Although the lockdep facility is extremely useful, it does add
+	some overhead.  Therefore, under CONFIG_PROVE_RCU, the
+	RCU_STALL_DELAY_DELTA macro allows five extra seconds before
+	giving an RCU CPU stall warning message.
 
 RCU_STALL_RAT_DELAY
 
@@ -64,6 +88,54 @@ INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffi
 
 This is rare, but does happen from time to time in real life.
 
+If the CONFIG_RCU_CPU_STALL_INFO kernel configuration parameter is set,
+more information is printed with the stall-warning message, for example:
+
+	INFO: rcu_preempt detected stall on CPU
+	0: (63959 ticks this GP) idle=241/3fffffffffffffff/0
+	   (t=65000 jiffies)
+
+In kernels with CONFIG_RCU_FAST_NO_HZ, even more information is
+printed:
+
+	INFO: rcu_preempt detected stall on CPU
+	0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 drain=0 . timer=-1
+	   (t=65000 jiffies)
+
+The "(64628 ticks this GP)" indicates that this CPU has taken more
+than 64,000 scheduling-clock interrupts during the current stalled
+grace period.  If the CPU was not yet aware of the current grace
+period (for example, if it was offline), then this part of the message
+indicates how many grace periods behind the CPU is.
+
+The "idle=" portion of the message prints the dyntick-idle state.
+The hex number before the first "/" is the low-order 12 bits of the
+dynticks counter, which will have an even-numbered value if the CPU is
+in dyntick-idle mode and an odd-numbered value otherwise.  The hex
+number between the two "/"s is the value of the nesting, which will
+be a small positive number if in the idle loop and a very large positive
+number (as shown above) otherwise.
+
+For CONFIG_RCU_FAST_NO_HZ kernels, the "drain=0" indicates that the
+CPU is not in the process of trying to force itself into dyntick-idle
+state, the "." indicates that the CPU has not given up forcing RCU
+into dyntick-idle mode (it would be "H" otherwise), and the "timer=-1"
+indicates that the CPU has not recented forced RCU into dyntick-idle
+mode (it would otherwise indicate the number of microseconds remaining
+in this forced state).
+
+
+Multiple Warnings From One Stall
+
+If a stall lasts long enough, multiple stall-warning messages will be
+printed for it.  The second and subsequent messages are printed at
+longer intervals, so that the time between (say) the first and second
+message will be about three times the interval between the beginning
+of the stall and the first message.
+
+
+What Causes RCU CPU Stall Warnings?
+
 So your kernel printed an RCU CPU stall warning.  The next question is
 "What caused it?"  The following problems can result in RCU CPU stall
 warnings:
@@ -128,4 +200,5 @@ is occurring, which will usually be in the function nearest the top of
 that portion of the stack which remains the same from trace to trace.
 If you can reliably trigger the stall, ftrace can be quite helpful.
 
-RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
+RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE
+and with RCU's event tracing.
diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt
index d67068d..375d3fb 100644
--- a/Documentation/RCU/torture.txt
+++ b/Documentation/RCU/torture.txt
@@ -69,6 +69,13 @@ onoff_interval
 		CPU-hotplug operations regardless of what value is
 		specified for onoff_interval.
 
+onoff_holdoff	The number of seconds to wait until starting CPU-hotplug
+		operations.  This would normally only be used when
+		rcutorture was built into the kernel and started
+		automatically at boot time, in which case it is useful
+		in order to avoid confusing boot-time code with CPUs
+		coming and going.
+
 shuffle_interval
 		The number of seconds to keep the test threads affinitied
 		to a particular subset of the CPUs, defaults to 3 seconds.
@@ -79,6 +86,24 @@ shutdown_secs	The number of seconds to run the test before terminating
 		zero, which disables test termination and system shutdown.
 		This capability is useful for automated testing.
 
+stall_cpu	The number of seconds that a CPU should be stalled while
+		within both an rcu_read_lock() and a preempt_disable().
+		This stall happens only once per rcutorture run.
+		If you need multiple stalls, use modprobe and rmmod to
+		repeatedly run rcutorture.  The default for stall_cpu
+		is zero, which prevents rcutorture from stalling a CPU.
+
+		Note that attempts to rmmod rcutorture while the stall
+		is ongoing will hang, so be careful what value you
+		choose for this module parameter!  In addition, too-large
+		values for stall_cpu might well induce failures and
+		warnings in other parts of the kernel.  You have been
+		warned!
+
+stall_cpu_holdoff
+		The number of seconds to wait after rcutorture starts
+		before stalling a CPU.  Defaults to 10 seconds.
+
 stat_interval	The number of seconds between output of torture
 		statistics (via printk()).  Regardless of the interval,
 		statistics are printed when the module is unloaded.
@@ -271,11 +296,13 @@ The following script may be used to torture RCU:
 	#!/bin/sh
 
 	modprobe rcutorture
-	sleep 100
+	sleep 3600
 	rmmod rcutorture
 	dmesg | grep torture:
 
 The output can be manually inspected for the error flag of "!!!".
 One could of course create a more elaborate script that automatically
-checked for such errors.  The "rmmod" command forces a "SUCCESS" or
-"FAILURE" indication to be printk()ed.
+checked for such errors.  The "rmmod" command forces a "SUCCESS",
+"FAILURE", or "RCU_HOTPLUG" indication to be printk()ed.  The first
+two are self-explanatory, while the last indicates that while there
+were no RCU failures, CPU-hotplug problems were detected.
diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt
index 49587ab..f6f15ce 100644
--- a/Documentation/RCU/trace.txt
+++ b/Documentation/RCU/trace.txt
@@ -33,23 +33,23 @@ rcu/rcuboost:
 The output of "cat rcu/rcudata" looks as follows:
 
 rcu_sched:
-  0 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=545/1/0 df=50 of=0 ri=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0
-  1 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=967/1/0 df=58 of=0 ri=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0
-  2 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1081/1/0 df=175 of=0 ri=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0
-  3 c=20942 g=20943 pq=1 pgp=20942 qp=1 dt=1846/0/0 df=404 of=0 ri=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0
-  4 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=369/1/0 df=83 of=0 ri=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0
-  5 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=381/1/0 df=64 of=0 ri=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0
-  6 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1037/1/0 df=183 of=0 ri=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0
-  7 c=20897 g=20897 pq=1 pgp=20896 qp=0 dt=1572/0/0 df=382 of=0 ri=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0
+  0 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=545/1/0 df=50 of=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0
+  1 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=967/1/0 df=58 of=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0
+  2 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1081/1/0 df=175 of=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0
+  3 c=20942 g=20943 pq=1 pgp=20942 qp=1 dt=1846/0/0 df=404 of=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0
+  4 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=369/1/0 df=83 of=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0
+  5 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=381/1/0 df=64 of=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0
+  6 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1037/1/0 df=183 of=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0
+  7 c=20897 g=20897 pq=1 pgp=20896 qp=0 dt=1572/0/0 df=382 of=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0
 rcu_bh:
-  0 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=545/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0
-  1 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=967/1/0 df=3 of=0 ri=1 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0
-  2 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1081/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0
-  3 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1846/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0
-  4 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=369/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0
-  5 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=381/1/0 df=4 of=0 ri=1 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0
-  6 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1037/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0
-  7 c=1474 g=1474 pq=1 pgp=1473 qp=0 dt=1572/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0
+  0 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=545/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0
+  1 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=967/1/0 df=3 of=0 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0
+  2 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1081/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0
+  3 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1846/0/0 df=8 of=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0
+  4 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=369/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0
+  5 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=381/1/0 df=4 of=0 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0
+  6 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1037/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0
+  7 c=1474 g=1474 pq=1 pgp=1473 qp=0 dt=1572/0/0 df=8 of=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0
 
 The first section lists the rcu_data structures for rcu_sched, the second
 for rcu_bh.  Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
@@ -119,10 +119,6 @@ o	"of" is the number of times that some other CPU has forced a
 	CPU is offline when it is really alive and kicking) is a fatal
 	error, so it makes sense to err conservatively.
 
-o	"ri" is the number of times that RCU has seen fit to send a
-	reschedule IPI to this CPU in order to get it to report a
-	quiescent state.
-
 o	"ql" is the number of RCU callbacks currently residing on
 	this CPU.  This is the total number of callbacks, regardless
 	of what state they are in (new, waiting for grace period to
diff --git a/Documentation/backlight/lp855x-driver.txt b/Documentation/backlight/lp855x-driver.txt
new file mode 100644
index 0000000..321351e
--- /dev/null
+++ b/Documentation/backlight/lp855x-driver.txt
@@ -0,0 +1,81 @@
+Kernel driver lp855x
+====================
+
+Backlight driver for LP855x ICs
+
+Supported chips:
+	Texas Instruments LP8550, LP8551, LP8552, LP8553 and LP8556
+
+Author: Milo(Woogyom) Kim <milo.kim@ti.com>
+
+Description
+-----------
+
+* Brightness control
+
+Brightness can be controlled by the pwm input or the i2c command.
+The lp855x driver supports both cases.
+
+* Device attributes
+
+1) bl_ctl_mode
+Backlight control mode.
+Value : pwm based or register based
+
+2) chip_id
+The lp855x chip id.
+Value : lp8550/lp8551/lp8552/lp8553/lp8556
+
+Platform data for lp855x
+------------------------
+
+For supporting platform specific data, the lp855x platform data can be used.
+
+* name : Backlight driver name. If it is not defined, default name is set.
+* mode : Brightness control mode. PWM or register based.
+* device_control : Value of DEVICE CONTROL register.
+* initial_brightness : Initial value of backlight brightness.
+* max_brightness : Maximum value of backlight brightness.
+* pwm_data : Platform specific pwm generation functions.
+	     Only valid when brightness is pwm input mode.
+	     Functions should be implemented by PWM driver.
+	     - pwm_set_intensity() : set duty of PWM
+	     - pwm_get_intensity() : get current duty of PWM
+* load_new_rom_data :
+	0 : use default configuration data
+	1 : update values of eeprom or eprom registers on loading driver
+* size_program : Total size of lp855x_rom_data.
+* rom_data : List of new eeprom/eprom registers.
+
+example 1) lp8552 platform data : i2c register mode with new eeprom data
+
+#define EEPROM_A5_ADDR	0xA5
+#define EEPROM_A5_VAL	0x4f	/* EN_VSYNC=0 */
+
+static struct lp855x_rom_data lp8552_eeprom_arr[] = {
+	{EEPROM_A5_ADDR, EEPROM_A5_VAL},
+};
+
+static struct lp855x_platform_data lp8552_pdata = {
+	.name = "lcd-bl",
+	.mode = REGISTER_BASED,
+	.device_control = I2C_CONFIG(LP8552),
+	.initial_brightness = INITIAL_BRT,
+	.max_brightness = MAX_BRT,
+	.load_new_rom_data = 1,
+	.size_program = ARRAY_SIZE(lp8552_eeprom_arr),
+	.rom_data = lp8552_eeprom_arr,
+};
+
+example 2) lp8556 platform data : pwm input mode with default rom data
+
+static struct lp855x_platform_data lp8556_pdata = {
+	.mode = PWM_BASED,
+	.device_control = PWM_CONFIG(LP8556),
+	.initial_brightness = INITIAL_BRT,
+	.max_brightness = MAX_BRT,
+	.pwm_data = {
+		     .pwm_set_intensity = platform_pwm_set_intensity,
+		     .pwm_get_intensity = platform_pwm_get_intensity,
+		     },
+};
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index a7c96ae..8e74980 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -558,8 +558,7 @@ Each subsystem may export the following methods. The only mandatory
 methods are create/destroy. Any others that are null are presumed to
 be successful no-ops.
 
-struct cgroup_subsys_state *create(struct cgroup_subsys *ss,
-				   struct cgroup *cgrp)
+struct cgroup_subsys_state *create(struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
 Called to create a subsystem state object for a cgroup. The
@@ -574,7 +573,7 @@ identified by the passed cgroup object having a NULL parent (since
 it's the root of the hierarchy) and may be an appropriate place for
 initialization code.
 
-void destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
+void destroy(struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
 The cgroup system is about to destroy the passed cgroup; the subsystem
@@ -585,7 +584,7 @@ cgroup->parent is still valid. (Note - can also be called for a
 newly-created cgroup if an error occurs after this subsystem's
 create() method has been called for the new cgroup).
 
-int pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+int pre_destroy(struct cgroup *cgrp);
 
 Called before checking the reference count on each subsystem. This may
 be useful for subsystems which have some extra references even if
@@ -593,8 +592,7 @@ there are not tasks in the cgroup. If pre_destroy() returns error code,
 rmdir() will fail with it. From this behavior, pre_destroy() can be
 called multiple times against a cgroup.
 
-int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-	       struct cgroup_taskset *tset)
+int can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 (cgroup_mutex held by caller)
 
 Called prior to moving one or more tasks into a cgroup; if the
@@ -615,8 +613,7 @@ fork. If this method returns 0 (success) then this should remain valid
 while the caller holds cgroup_mutex and it is ensured that either
 attach() or cancel_attach() will be called in future.
 
-void cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-		   struct cgroup_taskset *tset)
+void cancel_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 (cgroup_mutex held by caller)
 
 Called when a task attach operation has failed after can_attach() has succeeded.
@@ -625,23 +622,22 @@ function, so that the subsystem can implement a rollback. If not, not necessary.
 This will be called only about subsystems whose can_attach() operation have
 succeeded. The parameters are identical to can_attach().
 
-void attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-	    struct cgroup_taskset *tset)
+void attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 (cgroup_mutex held by caller)
 
 Called after the task has been attached to the cgroup, to allow any
 post-attachment activity that requires memory allocations or blocking.
 The parameters are identical to can_attach().
 
-void fork(struct cgroup_subsy *ss, struct task_struct *task)
+void fork(struct task_struct *task)
 
 Called when a task is forked into a cgroup.
 
-void exit(struct cgroup_subsys *ss, struct task_struct *task)
+void exit(struct task_struct *task)
 
 Called during task exit.
 
-int populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
+int populate(struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
 Called after creation of a cgroup to allow a subsystem to populate
@@ -651,7 +647,7 @@ include/linux/cgroup.h for details).  Note that although this
 method can return an error code, the error code is currently not
 always handled well.
 
-void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
+void post_clone(struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
 Called during cgroup_create() to do any parameter
@@ -659,7 +655,7 @@ initialization which might be required before a task could attach.  For
 example in cpusets, no task may attach before 'cpus' and 'mems' are set
 up.
 
-void bind(struct cgroup_subsys *ss, struct cgroup *root)
+void bind(struct cgroup *root)
 (cgroup_mutex and ss->hierarchy_mutex held by caller)
 
 Called when a cgroup subsystem is rebound to a different hierarchy
diff --git a/Documentation/crc32.txt b/Documentation/crc32.txt
new file mode 100644
index 0000000..1885f7a
--- /dev/null
+++ b/Documentation/crc32.txt
@@ -0,0 +1,183 @@
+A brief CRC tutorial.
+
+A CRC is a long-division remainder.  You add the CRC to the message,
+and the whole thing (message+CRC) is a multiple of the given
+CRC polynomial.  To check the CRC, you can either check that the
+CRC matches the recomputed value, *or* you can check that the
+remainder computed on the message+CRC is 0.  This latter approach
+is used by a lot of hardware implementations, and is why so many
+protocols put the end-of-frame flag after the CRC.
+
+It's actually the same long division you learned in school, except that
+- We're working in binary, so the digits are only 0 and 1, and
+- When dividing polynomials, there are no carries.  Rather than add and
+  subtract, we just xor.  Thus, we tend to get a bit sloppy about
+  the difference between adding and subtracting.
+
+Like all division, the remainder is always smaller than the divisor.
+To produce a 32-bit CRC, the divisor is actually a 33-bit CRC polynomial.
+Since it's 33 bits long, bit 32 is always going to be set, so usually the
+CRC is written in hex with the most significant bit omitted.  (If you're
+familiar with the IEEE 754 floating-point format, it's the same idea.)
+
+Note that a CRC is computed over a string of *bits*, so you have
+to decide on the endianness of the bits within each byte.  To get
+the best error-detecting properties, this should correspond to the
+order they're actually sent.  For example, standard RS-232 serial is
+little-endian; the most significant bit (sometimes used for parity)
+is sent last.  And when appending a CRC word to a message, you should
+do it in the right order, matching the endianness.
+
+Just like with ordinary division, you proceed one digit (bit) at a time.
+Each step of the division you take one more digit (bit) of the dividend
+and append it to the current remainder.  Then you figure out the
+appropriate multiple of the divisor to subtract to being the remainder
+back into range.  In binary, this is easy - it has to be either 0 or 1,
+and to make the XOR cancel, it's just a copy of bit 32 of the remainder.
+
+When computing a CRC, we don't care about the quotient, so we can
+throw the quotient bit away, but subtract the appropriate multiple of
+the polynomial from the remainder and we're back to where we started,
+ready to process the next bit.
+
+A big-endian CRC written this way would be coded like:
+for (i = 0; i < input_bits; i++) {
+	multiple = remainder & 0x80000000 ? CRCPOLY : 0;
+	remainder = (remainder << 1 | next_input_bit()) ^ multiple;
+}
+
+Notice how, to get at bit 32 of the shifted remainder, we look
+at bit 31 of the remainder *before* shifting it.
+
+But also notice how the next_input_bit() bits we're shifting into
+the remainder don't actually affect any decision-making until
+32 bits later.  Thus, the first 32 cycles of this are pretty boring.
+Also, to add the CRC to a message, we need a 32-bit-long hole for it at
+the end, so we have to add 32 extra cycles shifting in zeros at the
+end of every message,
+
+These details lead to a standard trick: rearrange merging in the
+next_input_bit() until the moment it's needed.  Then the first 32 cycles
+can be precomputed, and merging in the final 32 zero bits to make room
+for the CRC can be skipped entirely.  This changes the code to:
+
+for (i = 0; i < input_bits; i++) {
+	remainder ^= next_input_bit() << 31;
+	multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
+	remainder = (remainder << 1) ^ multiple;
+}
+
+With this optimization, the little-endian code is particularly simple:
+for (i = 0; i < input_bits; i++) {
+	remainder ^= next_input_bit();
+	multiple = (remainder & 1) ? CRCPOLY : 0;
+	remainder = (remainder >> 1) ^ multiple;
+}
+
+The most significant coefficient of the remainder polynomial is stored
+in the least significant bit of the binary "remainder" variable.
+The other details of endianness have been hidden in CRCPOLY (which must
+be bit-reversed) and next_input_bit().
+
+As long as next_input_bit is returning the bits in a sensible order, we don't
+*have* to wait until the last possible moment to merge in additional bits.
+We can do it 8 bits at a time rather than 1 bit at a time:
+for (i = 0; i < input_bytes; i++) {
+	remainder ^= next_input_byte() << 24;
+	for (j = 0; j < 8; j++) {
+		multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
+		remainder = (remainder << 1) ^ multiple;
+	}
+}
+
+Or in little-endian:
+for (i = 0; i < input_bytes; i++) {
+	remainder ^= next_input_byte();
+	for (j = 0; j < 8; j++) {
+		multiple = (remainder & 1) ? CRCPOLY : 0;
+		remainder = (remainder >> 1) ^ multiple;
+	}
+}
+
+If the input is a multiple of 32 bits, you can even XOR in a 32-bit
+word at a time and increase the inner loop count to 32.
+
+You can also mix and match the two loop styles, for example doing the
+bulk of a message byte-at-a-time and adding bit-at-a-time processing
+for any fractional bytes at the end.
+
+To reduce the number of conditional branches, software commonly uses
+the byte-at-a-time table method, popularized by Dilip V. Sarwate,
+"Computation of Cyclic Redundancy Checks via Table Look-Up", Comm. ACM
+v.31 no.8 (August 1998) p. 1008-1013.
+
+Here, rather than just shifting one bit of the remainder to decide
+in the correct multiple to subtract, we can shift a byte at a time.
+This produces a 40-bit (rather than a 33-bit) intermediate remainder,
+and the correct multiple of the polynomial to subtract is found using
+a 256-entry lookup table indexed by the high 8 bits.
+
+(The table entries are simply the CRC-32 of the given one-byte messages.)
+
+When space is more constrained, smaller tables can be used, e.g. two
+4-bit shifts followed by a lookup in a 16-entry table.
+
+It is not practical to process much more than 8 bits at a time using this
+technique, because tables larger than 256 entries use too much memory and,
+more importantly, too much of the L1 cache.
+
+To get higher software performance, a "slicing" technique can be used.
+See "High Octane CRC Generation with the Intel Slicing-by-8 Algorithm",
+ftp://download.intel.com/technology/comms/perfnet/download/slicing-by-8.pdf
+
+This does not change the number of table lookups, but does increase
+the parallelism.  With the classic Sarwate algorithm, each table lookup
+must be completed before the index of the next can be computed.
+
+A "slicing by 2" technique would shift the remainder 16 bits at a time,
+producing a 48-bit intermediate remainder.  Rather than doing a single
+lookup in a 65536-entry table, the two high bytes are looked up in
+two different 256-entry tables.  Each contains the remainder required
+to cancel out the corresponding byte.  The tables are different because the
+polynomials to cancel are different.  One has non-zero coefficients from
+x^32 to x^39, while the other goes from x^40 to x^47.
+
+Since modern processors can handle many parallel memory operations, this
+takes barely longer than a single table look-up and thus performs almost
+twice as fast as the basic Sarwate algorithm.
+
+This can be extended to "slicing by 4" using 4 256-entry tables.
+Each step, 32 bits of data is fetched, XORed with the CRC, and the result
+broken into bytes and looked up in the tables.  Because the 32-bit shift
+leaves the low-order bits of the intermediate remainder zero, the
+final CRC is simply the XOR of the 4 table look-ups.
+
+But this still enforces sequential execution: a second group of table
+look-ups cannot begin until the previous groups 4 table look-ups have all
+been completed.  Thus, the processor's load/store unit is sometimes idle.
+
+To make maximum use of the processor, "slicing by 8" performs 8 look-ups
+in parallel.  Each step, the 32-bit CRC is shifted 64 bits and XORed
+with 64 bits of input data.  What is important to note is that 4 of
+those 8 bytes are simply copies of the input data; they do not depend
+on the previous CRC at all.  Thus, those 4 table look-ups may commence
+immediately, without waiting for the previous loop iteration.
+
+By always having 4 loads in flight, a modern superscalar processor can
+be kept busy and make full use of its L1 cache.
+
+Two more details about CRC implementation in the real world:
+
+Normally, appending zero bits to a message which is already a multiple
+of a polynomial produces a larger multiple of that polynomial.  Thus,
+a basic CRC will not detect appended zero bits (or bytes).  To enable
+a CRC to detect this condition, it's common to invert the CRC before
+appending it.  This makes the remainder of the message+crc come out not
+as zero, but some fixed non-zero value.  (The CRC of the inversion
+pattern, 0xffffffff.)
+
+The same problem applies to zero bits prepended to the message, and a
+similar solution is used.  Instead of starting the CRC computation with
+a remainder of 0, an initial remainder of all ones is used.  As long as
+you start the same way on decoding, it doesn't make a difference.
+
diff --git a/Documentation/cris/README b/Documentation/cris/README
index d9b0868..8dbdb1a 100644
--- a/Documentation/cris/README
+++ b/Documentation/cris/README
@@ -1,38 +1,34 @@
-Linux 2.4 on the CRIS architecture
-==================================
-$Id: README,v 1.7 2001/04/19 12:38:32 bjornw Exp $
+Linux on the CRIS architecture
+==============================
 
-This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded 
-network CPU. For more information about CRIS and ETRAX please see further
-below.
+This is a port of Linux to Axis Communications ETRAX 100LX,
+ETRAX FS and ARTPEC-3 embedded network CPUs.
+
+For more information about CRIS and ETRAX please see further below.
 
 In order to compile this you need a version of gcc with support for the
-ETRAX chip family. Please see this link for more information on how to 
+ETRAX chip family. Please see this link for more information on how to
 download the compiler and other tools useful when building and booting
 software for the ETRAX platform:
 
-http://developer.axis.com/doc/software/devboard_lx/install-howto.html
-
-<more specific information should come in this document later>
+http://developer.axis.com/wiki/doku.php?id=axis:install-howto-2_20
 
 What is CRIS ?
 --------------
 
 CRIS is an acronym for 'Code Reduced Instruction Set'. It is the CPU
 architecture in Axis Communication AB's range of embedded network CPU's,
-called ETRAX. The latest CPU is called ETRAX 100LX, where LX stands for
-'Linux' because the chip was designed to be a good host for the Linux
-operating system.
+called ETRAX.
 
 The ETRAX 100LX chip
 --------------------
 
-For reference, please see the press-release:
+For reference, please see the following link:
 
-http://www.axis.com/news/us/001101_etrax.htm
+http://www.axis.com/products/dev_etrax_100lx/index.htm
 
-The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad 
-range of  built-in interfaces, all with modern scatter/gather DMA.
+The ETRAX 100LX is a 100 MIPS processor with 8kB cache, MMU, and a very broad
+range of built-in interfaces, all with modern scatter/gather DMA.
 
 Memory interfaces:
 
@@ -51,20 +47,28 @@ I/O interfaces:
 	* SCSI
 	* two parallel-ports
 	* two generic 8-bit ports
-	
-	(not all interfaces are available at the same time due to chip pin 
+
+	(not all interfaces are available at the same time due to chip pin
          multiplexing)
 
-The previous version of the ETRAX, the ETRAX 100, sits in almost all of
-Axis shipping thin-servers like the Axis 2100 web camera or the ETRAX 100
-developer-board. It lacks an MMU so the Linux we run on that is a version
-of uClinux (Linux 2.0 without MM-support) ported to the CRIS architecture.
-The new Linux 2.4 port has full MM and needs a CPU with an MMU, so it will
-not run on the ETRAX 100.
+ETRAX 100LX is CRISv10 architecture.
+
+
+The ETRAX FS and ARTPEC-3 chips
+-------------------------------
 
-A version of the Axis developer-board with ETRAX 100LX (running Linux
-2.4) is now available. For more information please see developer.axis.com.
+The ETRAX FS is a 200MHz 32-bit RISC processor with on-chip 16kB
+I-cache and 16kB D-cache and with a wide range of device interfaces
+including multiple high speed serial ports and an integrated USB 1.1 PHY.
 
+The ARTPEC-3 is a variant of the ETRAX FS with additional IO-units
+used by the Axis Communications network cameras.
+
+See below link for more information:
+
+http://www.axis.com/products/dev_etrax_fs/index.htm
+
+ETRAX FS and ARTPEC-3 are both CRISv32 architectures.
 
 Bootlog
 -------
@@ -182,10 +186,6 @@ SwapFree:            0 kB
 -rwxr-xr-x  1 342      100         16252  Jan 01 00:00 telnetd
 
 
-(All programs are statically linked to the libc at this point - we have not ported the
- shared libraries yet)
-
-
 
 
 
diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt
index 801d9d1..1ff044d 100644
--- a/Documentation/device-mapper/thin-provisioning.txt
+++ b/Documentation/device-mapper/thin-provisioning.txt
@@ -1,7 +1,7 @@
 Introduction
 ============
 
-This document descibes a collection of device-mapper targets that
+This document describes a collection of device-mapper targets that
 between them implement thin-provisioning and snapshots.
 
 The main highlight of this implementation, compared to the previous
diff --git a/Documentation/devicetree/bindings/arm/exynos/power_domain.txt b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
new file mode 100644
index 0000000..6528e21
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/exynos/power_domain.txt
@@ -0,0 +1,21 @@
+* Samsung Exynos Power Domains
+
+Exynos processors include support for multiple power domains which are used
+to gate power to one or more peripherals on the processor.
+
+Required Properties:
+- compatiable: should be one of the following.
+    * samsung,exynos4210-pd - for exynos4210 type power domain.
+- reg: physical base address of the controller and length of memory mapped
+    region.
+
+Optional Properties:
+- samsung,exynos4210-pd-off: Specifies that the power domain is in turned-off
+    state during boot and remains to be turned-off until explicitly turned-on.
+
+Example:
+
+	lcd0: power-domain-lcd0 {
+		compatible = "samsung,exynos4210-pd";
+		reg = <0x10023C00 0x10>;
+	};
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
index dbdab40..ce78498 100644
--- a/Documentation/devicetree/bindings/arm/omap/omap.txt
+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -41,3 +41,9 @@ Boards:
 
 - OMAP4 PandaBoard : Low cost community board
   compatible = "ti,omap4-panda", "ti,omap4430"
+
+- OMAP3 EVM : Software Developement Board for OMAP35x, AM/DM37x
+  compatible = "ti,omap3-evm", "ti,omap3"
+
+- AM335X EVM : Software Developement Board for AM335x
+  compatible = "ti,am335x-evm", "ti,am33xx", "ti,omap3"
diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt
new file mode 100644
index 0000000..09335f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt
@@ -0,0 +1,100 @@
+Embedded Memory Controller
+
+Properties:
+- name : Should be emc
+- #address-cells : Should be 1
+- #size-cells : Should be 0
+- compatible : Should contain "nvidia,tegra20-emc".
+- reg : Offset and length of the register set for the device
+- nvidia,use-ram-code : If present, the sub-nodes will be addressed
+  and chosen using the ramcode board selector. If omitted, only one
+  set of tables can be present and said tables will be used
+  irrespective of ram-code configuration.
+
+Child device nodes describe the memory settings for different configurations and clock rates.
+
+Example:
+
+	emc@7000f400 {
+		#address-cells = < 1 >;
+		#size-cells = < 0 >;
+		compatible = "nvidia,tegra20-emc";
+		reg = <0x7000f4000 0x200>;
+	}
+
+
+Embedded Memory Controller ram-code table
+
+If the emc node has the nvidia,use-ram-code property present, then the
+next level of nodes below the emc table are used to specify which settings
+apply for which ram-code settings.
+
+If the emc node lacks the nvidia,use-ram-code property, this level is omitted
+and the tables are stored directly under the emc node (see below).
+
+Properties:
+
+- name : Should be emc-tables
+- nvidia,ram-code : the binary representation of the ram-code board strappings
+  for which this node (and children) are valid.
+
+
+
+Embedded Memory Controller configuration table
+
+This is a table containing the EMC register settings for the various
+operating speeds of the memory controller. They are always located as
+subnodes of the emc controller node.
+
+There are two ways of specifying which tables to use:
+
+* The simplest is if there is just one set of tables in the device tree,
+  and they will always be used (based on which frequency is used).
+  This is the preferred method, especially when firmware can fill in
+  this information based on the specific system information and just
+  pass it on to the kernel.
+
+* The slightly more complex one is when more than one memory configuration
+  might exist on the system.  The Tegra20 platform handles this during
+  early boot by selecting one out of possible 4 memory settings based
+  on a 2-pin "ram code" bootstrap setting on the board. The values of
+  these strappings can be read through a register in the SoC, and thus
+  used to select which tables to use.
+
+Properties:
+- name : Should be emc-table
+- compatible : Should contain "nvidia,tegra20-emc-table".
+- reg : either an opaque enumerator to tell different tables apart, or
+  the valid frequency for which the table should be used (in kHz).
+- clock-frequency : the clock frequency for the EMC at which this
+  table should be used (in kHz).
+- nvidia,emc-registers : a 46 word array of EMC registers to be programmed
+  for operation at the 'clock-frequency' setting.
+  The order and contents of the registers are:
+    RC, RFC, RAS, RP, R2W, W2R, R2P, W2P, RD_RCD, WR_RCD, RRD, REXT,
+    WDV, QUSE, QRST, QSAFE, RDV, REFRESH, BURST_REFRESH_NUM, PDEX2WR,
+    PDEX2RD, PCHG2PDEN, ACT2PDEN, AR2PDEN, RW2PDEN, TXSR, TCKE, TFAW,
+    TRPAB, TCLKSTABLE, TCLKSTOP, TREFBW, QUSE_EXTRA, FBIO_CFG6, ODT_WRITE,
+    ODT_READ, FBIO_CFG5, CFG_DIG_DLL, DLL_XFORM_DQS, DLL_XFORM_QUSE,
+    ZCAL_REF_CNT, ZCAL_WAIT_CNT, AUTO_CAL_INTERVAL, CFG_CLKTRIM_0,
+    CFG_CLKTRIM_1, CFG_CLKTRIM_2
+
+		emc-table@166000 {
+			reg = <166000>;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 166000 >;
+			nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+						 0 0 0 0 >;
+		};
+
+		emc-table@333000 {
+			reg = <333000>;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 333000 >;
+			nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+						 0 0 0 0 >;
+		};
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
new file mode 100644
index 0000000..b5846e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
@@ -0,0 +1,19 @@
+NVIDIA Tegra Power Management Controller (PMC)
+
+Properties:
+- name : Should be pmc
+- compatible : Should contain "nvidia,tegra<chip>-pmc".
+- reg : Offset and length of the register set for the device
+- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
+  The PMU is an external Power Management Unit, whose interrupt output
+  signal is fed into the PMC. This signal is optionally inverted, and then
+  fed into the ARM GIC. The PMC is not involved in the detection or
+  handling of this interrupt signal, merely its inversion.
+
+Example:
+
+pmc@7000f400 {
+	compatible = "nvidia,tegra20-pmc";
+	reg = <0x7000e400 0x400>;
+	nvidia,invert-interrupt;
+};
diff --git a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt
new file mode 100644
index 0000000..90fa7da
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt
@@ -0,0 +1,30 @@
+* NVIDIA Tegra APB DMA controller
+
+Required properties:
+- compatible: Should be "nvidia,<chip>-apbdma"
+- reg: Should contain DMA registers location and length. This shuld include
+  all of the per-channel registers.
+- interrupts: Should contain all of the per-channel DMA interrupts.
+
+Examples:
+
+apbdma: dma@6000a000 {
+	compatible = "nvidia,tegra20-apbdma";
+	reg = <0x6000a000 0x1200>;
+	interrupts = < 0 136 0x04
+		       0 137 0x04
+		       0 138 0x04
+		       0 139 0x04
+		       0 140 0x04
+		       0 141 0x04
+		       0 142 0x04
+		       0 143 0x04
+		       0 144 0x04
+		       0 145 0x04
+		       0 146 0x04
+		       0 147 0x04
+		       0 148 0x04
+		       0 149 0x04
+		       0 150 0x04
+		       0 151 0x04 >;
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
index eb4b530..023c952 100644
--- a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
@@ -1,8 +1,40 @@
-NVIDIA Tegra 2 GPIO controller
+NVIDIA Tegra GPIO controller
 
 Required properties:
-- compatible : "nvidia,tegra20-gpio"
+- compatible : "nvidia,tegra<chip>-gpio"
+- reg : Physical base address and length of the controller's registers.
+- interrupts : The interrupt outputs from the controller. For Tegra20,
+  there should be 7 interrupts specified, and for Tegra30, there should
+  be 8 interrupts specified.
 - #gpio-cells : Should be two. The first cell is the pin number and the
   second cell is used to specify optional parameters:
   - bit 0 specifies polarity (0 for normal, 1 for inverted)
 - gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+  The first cell is the GPIO number.
+  The second cell is used to specify flags:
+    bits[3:0] trigger type and level flags:
+      1 = low-to-high edge triggered.
+      2 = high-to-low edge triggered.
+      4 = active high level-sensitive.
+      8 = active low level-sensitive.
+      Valid combinations are 1, 2, 3, 4, 8.
+- interrupt-controller : Marks the device node as an interrupt controller.
+
+Example:
+
+gpio: gpio@6000d000 {
+	compatible = "nvidia,tegra20-gpio";
+	reg = < 0x6000d000 0x1000 >;
+	interrupts = < 0 32 0x04
+		       0 33 0x04
+		       0 34 0x04
+		       0 35 0x04
+		       0 55 0x04
+		       0 87 0x04
+		       0 89 0x04 >;
+	#gpio-cells = <2>;
+	gpio-controller;
+	#interrupt-cells = <2>;
+	interrupt-controller;
+};
diff --git a/Documentation/devicetree/bindings/gpio/sodaville.txt b/Documentation/devicetree/bindings/gpio/sodaville.txt
new file mode 100644
index 0000000..563eff2
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/sodaville.txt
@@ -0,0 +1,48 @@
+GPIO controller on CE4100 / Sodaville SoCs
+==========================================
+
+The bindings for CE4100's GPIO controller match the generic description
+which is covered by the gpio.txt file in this folder.
+
+The only additional property is the intel,muxctl property which holds the
+value which is written into the MUXCNTL register.
+
+There is no compatible property for now because the driver is probed via
+PCI id (vendor 0x8086 device 0x2e67).
+
+The interrupt specifier consists of two cells encoded as follows:
+ - <1st cell>: The interrupt-number that identifies the interrupt source.
+ - <2nd cell>: The level-sense information, encoded as follows:
+		4 - active high level-sensitive
+		8 - active low level-sensitive
+
+Example of the GPIO device and one user:
+
+	pcigpio: gpio@b,1 {
+			/* two cells for GPIO and interrupt */
+			#gpio-cells = <2>;
+			#interrupt-cells = <2>;
+			compatible = "pci8086,2e67.2",
+					   "pci8086,2e67",
+					   "pciclassff0000",
+					   "pciclassff00";
+
+			reg = <0x15900 0x0 0x0 0x0 0x0>;
+			/* Interrupt line of the gpio device */
+			interrupts = <15 1>;
+			/* It is an interrupt and GPIO controller itself */
+			interrupt-controller;
+			gpio-controller;
+			intel,muxctl = <0>;
+	};
+
+	testuser@20 {
+			compatible = "example,testuser";
+			/* User the 11th GPIO line as an active high triggered
+			 * level interrupt
+			 */
+			interrupts = <11 8>;
+			interrupt-parent = <&pcigpio>;
+			/* Use this GPIO also with the gpio functions */
+			gpios = <&pcigpio 11 0>;
+	};
diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
new file mode 100644
index 0000000..8cbdd29
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
@@ -0,0 +1,70 @@
+* Samsung's SDHCI Controller device tree bindings
+
+Samsung's SDHCI controller is used as a connectivity interface with external
+MMC, SD and eMMC storage mediums.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+  - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
+    controller.
+  - "samsung,exynos4210-sdhci": For controller compatible with Exynos4 sdhci
+    controller.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+  depends on the interrupt controller.
+
+
+Required Board Specific Properties:
+- gpios: Should specify the gpios used for clock, command and data lines. The
+  gpio specifier format depends on the gpio controller. Note: There is no
+  particular order in which the gpio's have to be listed.
+
+
+Optional Board Specific Properties:
+- samsung,sdhci-bus-width: Number of data lines connected to the controller.
+  Note: This excludes the clock,command and card detect lines. If this property
+  is not specified, default value is 1.
+
+- samsung,cd-gpio-invert: If 'samsung,sdhci-cd-gpio' card detect method is
+  selected, this property can be optionally specified to invert the value of
+  external card detect gpio line.
+
+- One of the following properties for card detect type.
+  - samsung,sdhci-cd-internal: Card detect line from the card slot  is
+    connected to the card detect pad of the sdhci controller. A gpio is
+    used for this connection (with possible pin function settings).
+  - samsung,sdhci-cd-gpio: A gpio line (with possible pin function settings)
+    is used a card detect line. This gpio line is not connected to card detect
+    pad of the sdhci controller.
+  - samsung,sdhci-cd-none: There is no card detect line. Polling is used to
+    detect the presence of the card. (DEFAULT, if no card detect property
+    is specified).
+  - samsung,sdhci-cd-permanent: There is no card detect line. The card is
+    permanently connected to the sdhci controller.
+
+- gpio-cd: The gpio to be used as card detect line for
+  'samsung,sdhci-cd-internal' or 'samsung,sdhci-cd-gpio' card detection method.
+  The gpio specifier format depends on the gpio controller.
+
+Example:
+	sdhci@12530000 {
+		compatible = "samsung,exynos4210-sdhci";
+		reg = <0x12530000 0x100>;
+		interrupts = <139>;
+		samsung,sdhci-bus-width = <4>;
+		samsung,sdhci-cd-internal;
+		gpio-cd = <&gpk2 2 2 3 3>;
+		gpios = <&gpk2 0 2 0 3>,  /* clock line */
+			<&gpk2 1 2 0 3>,  /* command line */
+			<&gpk2 3 2 3 3>,  /* data line 0 */
+			<&gpk2 4 2 3 3>,  /* data line 1 */
+			<&gpk2 5 2 3 3>,  /* data line 2 */
+			<&gpk2 6 2 3 3>;  /* data line 3 */
+	};
+
+	Note: This example shows both SoC specific and board specific properties
+	in a single device node. The properties can be actually be seperated
+	into SoC specific node and board specific node.
diff --git a/Documentation/devicetree/bindings/sound/alc5632.txt b/Documentation/devicetree/bindings/sound/alc5632.txt
new file mode 100644
index 0000000..8608f74
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/alc5632.txt
@@ -0,0 +1,24 @@
+ALC5632 audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+  - compatible : "realtek,alc5632"
+
+  - reg : the I2C address of the device.
+
+  - gpio-controller : Indicates this device is a GPIO controller.
+
+  - #gpio-cells : Should be two. The first cell is the pin number and the
+    second cell is used to specify optional parameters (currently unused).
+
+Example:
+
+alc5632: alc5632@1e {
+	compatible = "realtek,alc5632";
+	reg = <0x1a>;
+
+	gpio-controller;
+	#gpio-cells = <2>;
+};
diff --git a/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt b/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt
new file mode 100644
index 0000000..65b001e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt
@@ -0,0 +1,57 @@
+NVIDIA Tegra audio complex
+
+Required properties:
+- compatible : "nvidia,tegra-audio-alc5632"
+- nvidia,model : The user-visible name of this sound complex.
+- nvidia,audio-routing : A list of the connections between audio components.
+  Each entry is a pair of strings, the first being the connection's sink,
+  the second being the connection's source. Valid names for sources and
+  sinks are the ALC5632's pins:
+
+  ALC5632 pins:
+
+  * SPK_OUTP
+  * SPK_OUTN
+  * HP_OUT_L
+  * HP_OUT_R
+  * AUX_OUT_P
+  * AUX_OUT_N
+  * LINE_IN_L
+  * LINE_IN_R
+  * PHONE_P
+  * PHONE_N
+  * MIC1_P
+  * MIC1_N
+  * MIC2_P
+  * MIC2_N
+  * MICBIAS1
+
+  Board connectors:
+
+  * Headset Stereophone
+  * Int Spk
+  * Headset Mic
+
+- nvidia,i2s-controller : The phandle of the Tegra I2S controller
+- nvidia,audio-codec : The phandle of the ALC5632 audio codec
+
+Example:
+
+sound {
+	compatible = "nvidia,tegra-audio-alc5632-paz00",
+				 "nvidia,tegra-audio-alc5632";
+
+	nvidia,model = "Compal PAZ00";
+
+	nvidia,audio-routing =
+				"Int Spk", "SPK_OUTP",
+				"Int Spk", "SPK_OUTN",
+				"Headset Mic","MICBIAS1",
+				"MIC1_N", "Headset Mic",
+				"MIC1_P", "Headset Mic",
+				"Headset Stereophone", "HP_OUT_R",
+				"Headset Stereophone", "HP_OUT_L";
+
+	nvidia,i2s-controller = <&tegra_i2s1>;
+	nvidia,audio-codec = <&alc5632>;
+};
diff --git a/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt
new file mode 100644
index 0000000..6588b69
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt
@@ -0,0 +1,14 @@
+* Energymicro efm32 UART
+
+Required properties:
+- compatible : Should be "efm32,uart"
+- reg : Address and length of the register set
+- interrupts : Should contain uart interrupt
+
+Example:
+
+uart@0x4000c400 {
+	compatible = "efm32,uart";
+	reg = <0x4000c400 0x400>;
+	interrupts = <15>;
+};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index ecc6a6c..ca8ee14 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -33,6 +33,7 @@ nxp	NXP Semiconductors
 powervr	Imagination Technologies
 qcom	Qualcomm, Inc.
 ramtron	Ramtron International
+realtek Realtek Semiconductor Corp.
 samsung	Samsung Semiconductor
 sbs	Smart Battery System
 schindler	Schindler
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 41c0c5d..2a596a4 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -271,3 +271,8 @@ IOMAP
   pcim_iounmap()
   pcim_iomap_table()	: array of mapped addresses indexed by BAR
   pcim_iomap_regions()	: do request_region() and iomap() on multiple BARs
+
+REGULATOR
+  devm_regulator_get()
+  devm_regulator_put()
+  devm_regulator_bulk_get()
diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt
index f959909..74e6c77 100644
--- a/Documentation/dynamic-debug-howto.txt
+++ b/Documentation/dynamic-debug-howto.txt
@@ -12,7 +12,7 @@ dynamically enabled per-callsite.
 Dynamic debug has even more useful features:
 
  * Simple query language allows turning on and off debugging statements by
-   matching any combination of:
+   matching any combination of 0 or 1 of:
 
    - source filename
    - function name
@@ -79,31 +79,24 @@ Command Language Reference
 ==========================
 
 At the lexical level, a command comprises a sequence of words separated
-by whitespace characters.  Note that newlines are treated as word
-separators and do *not* end a command or allow multiple commands to
-be done together.  So these are all equivalent:
+by spaces or tabs.  So these are all equivalent:
 
 nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
 				<debugfs>/dynamic_debug/control
 nullarbor:~ # echo -c '  file   svcsock.c     line  1603 +p  ' >
 				<debugfs>/dynamic_debug/control
-nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
-				<debugfs>/dynamic_debug/control
 nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
 				<debugfs>/dynamic_debug/control
 
-Commands are bounded by a write() system call.  If you want to do
-multiple commands you need to do a separate "echo" for each, like:
+Command submissions are bounded by a write() system call.
+Multiple commands can be written together, separated by ';' or '\n'.
 
-nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
-> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
+  ~# echo "func pnpacpi_get_resources +p; func pnp_assign_mem +p" \
+     > <debugfs>/dynamic_debug/control
 
-or even like:
+If your query set is big, you can batch them too:
 
-nullarbor:~ # (
-> echo 'file svcsock.c line 1603 +p' ;\
-> echo 'file svcsock.c line 1563 +p' ;\
-> ) > /proc/dprintk
+  ~# cat query-batch-file > <debugfs>/dynamic_debug/control
 
 At the syntactical level, a command comprises a sequence of match
 specifications, followed by a flags change specification.
@@ -144,11 +137,12 @@ func
     func svc_tcp_accept
 
 file
-    The given string is compared against either the full
-    pathname or the basename of the source file of each
-    callsite.  Examples:
+    The given string is compared against either the full pathname, the
+    src-root relative pathname, or the basename of the source file of
+    each callsite.  Examples:
 
     file svcsock.c
+    file kernel/freezer.c
     file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
 
 module
diff --git a/Documentation/edac.txt b/Documentation/edac.txt
index 249822c..fdcc49f 100644
--- a/Documentation/edac.txt
+++ b/Documentation/edac.txt
@@ -334,8 +334,8 @@ Sdram memory scrubbing rate:
 
 	Reading the file will return the actual scrubbing rate employed.
 
-	If configuration fails or memory scrubbing is not implemented, the value
-	of the attribute file will be -1.
+	If configuration fails or memory scrubbing is not implemented, accessing
+	that attribute will fail.
 
 
 
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a0ffac0..8c136f7 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -513,14 +513,8 @@ Who:	Bjorn Helgaas <bhelgaas@google.com>
 
 ----------------------------
 
-What:	The CAP9 SoC family will be removed
-When:	3.4
-Files:	arch/arm/mach-at91/at91cap9.c
-	arch/arm/mach-at91/at91cap9_devices.c
-	arch/arm/mach-at91/include/mach/at91cap9.h
-	arch/arm/mach-at91/include/mach/at91cap9_matrix.h
-	arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
-	arch/arm/mach-at91/board-cap9adk.c
-Why:	The code is not actively maintained and platforms are now hard to find.
-Who:	Nicolas Ferre <nicolas.ferre@atmel.com>
-	Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+What:	kmap_atomic(page, km_type)
+When:	3.5
+Why:	The old kmap_atomic() with two arguments is deprecated, we only
+	keep it for backward compatibility for few cycles and then drop it.
+Who:	Cong Wang <amwang@redhat.com>
diff --git a/Documentation/filesystems/debugfs.txt b/Documentation/filesystems/debugfs.txt
index 6872c91..4e25758 100644
--- a/Documentation/filesystems/debugfs.txt
+++ b/Documentation/filesystems/debugfs.txt
@@ -14,7 +14,10 @@ Debugfs is typically mounted with a command like:
 
     mount -t debugfs none /sys/kernel/debug
 
-(Or an equivalent /etc/fstab line). 
+(Or an equivalent /etc/fstab line).
+The debugfs root directory is accessible by anyone by default. To
+restrict access to the tree the "uid", "gid" and "mode" mount
+options can be used.
 
 Note that the debugfs API is exported GPL-only to modules.
 
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 10ec463..990219c 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -144,9 +144,6 @@ journal_async_commit	Commit block can be written to disk without waiting
 			mount the device. This will enable 'journal_checksum'
 			internally.
 
-journal=update		Update the ext4 file system's journal to the current
-			format.
-
 journal_dev=devnum	When the external journal device's major/minor numbers
 			have changed, this option allows the user to specify
 			the new journal location.  The journal device is
@@ -356,11 +353,6 @@ nouid32			Disables 32-bit UIDs and GIDs.  This is for
 			interoperability  with  older kernels which only
 			store and expect 16-bit values.
 
-resize			Allows to resize filesystem to the end of the last
-			existing block group, further resize has to be done
-			with resize2fs either online, or offline. It can be
-			used only with conjunction with remount.
-
 block_validity		This options allows to enables/disables the in-kernel
 noblock_validity	facility for tracking filesystem metadata blocks
 			within internal data structures. This allows multi-
diff --git a/Documentation/filesystems/nfs/idmapper.txt b/Documentation/filesystems/nfs/idmapper.txt
index 120fd3c..fe03d10 100644
--- a/Documentation/filesystems/nfs/idmapper.txt
+++ b/Documentation/filesystems/nfs/idmapper.txt
@@ -4,13 +4,21 @@ ID Mapper
 =========
 Id mapper is used by NFS to translate user and group ids into names, and to
 translate user and group names into ids.  Part of this translation involves
-performing an upcall to userspace to request the information.  Id mapper will
-user request-key to perform this upcall and cache the result.  The program
-/usr/sbin/nfs.idmap should be called by request-key, and will perform the
-translation and initialize a key with the resulting information.
+performing an upcall to userspace to request the information.  There are two
+ways NFS could obtain this information: placing a call to /sbin/request-key
+or by placing a call to the rpc.idmap daemon.
+
+NFS will attempt to call /sbin/request-key first.  If this succeeds, the
+result will be cached using the generic request-key cache.  This call should
+only fail if /etc/request-key.conf is not configured for the id_resolver key
+type, see the "Configuring" section below if you wish to use the request-key
+method.
+
+If the call to /sbin/request-key fails (if /etc/request-key.conf is not
+configured with the id_resolver key type), then the idmapper will ask the
+legacy rpc.idmap daemon for the id mapping.  This result will be stored
+in a custom NFS idmap cache.
 
- NFS_USE_NEW_IDMAPPER must be selected when configuring the kernel to use this
- feature.
 
 ===========
 Configuring
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index b4a3d76..74acd96 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -429,3 +429,9 @@ filemap_write_and_wait_range() so that all dirty pages are synced out properly.
 You must also keep in mind that ->fsync() is not called with i_mutex held
 anymore, so if you require i_mutex locking you must make sure to take it and
 release it yourself.
+
+--
+[mandatory]
+	d_alloc_root() is gone, along with a lot of bugs caused by code
+misusing it.  Replacement: d_make_root(inode).  The difference is,
+d_make_root() drops the reference to inode if dentry allocation fails.  
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a76a26a..976ebb2 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -40,6 +40,7 @@ Table of Contents
   3.4	/proc/<pid>/coredump_filter - Core dump filtering settings
   3.5	/proc/<pid>/mountinfo - Information about mounts
   3.6	/proc/<pid>/comm  & /proc/<pid>/task/<tid>/comm
+  3.7   /proc/<pid>/task/<tid>/children - Information about task children
 
   4	Configuring procfs
   4.1	Mount options
@@ -310,6 +311,11 @@ Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
   start_data    address above which program data+bss is placed
   end_data      address below which program data+bss is placed
   start_brk     address above which program heap can be expanded with brk()
+  arg_start     address above which program command line is placed
+  arg_end       address below which program command line is placed
+  env_start     address above which program environment is placed
+  env_end       address below which program environment is placed
+  exit_code     the thread's exit_code in the form reported by the waitpid system call
 ..............................................................................
 
 The /proc/PID/maps file containing the currently mapped memory regions and
@@ -1549,6 +1555,23 @@ then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated
 comm value.
 
 
+3.7	/proc/<pid>/task/<tid>/children - Information about task children
+-------------------------------------------------------------------------
+This file provides a fast way to retrieve first level children pids
+of a task pointed by <pid>/<tid> pair. The format is a space separated
+stream of pids.
+
+Note the "first level" here -- if a child has own children they will
+not be listed here, one needs to read /proc/<children-pid>/task/<tid>/children
+to obtain the descendants.
+
+Since this interface is intended to be fast and cheap it doesn't
+guarantee to provide precise results and some children might be
+skipped, especially if they've exited right after we printed their
+pids, so one need to either stop or freeze processes being inspected
+if precise results are needed.
+
+
 ------------------------------------------------------------------------------
 Configuring procfs
 ------------------------------------------------------------------------------
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
index a8273d5..59b4a09 100644
--- a/Documentation/filesystems/ramfs-rootfs-initramfs.txt
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -297,7 +297,7 @@ the above threads) is:
    either way about the archive format, and there are alternative tools,
    such as:
 
-     http://freshmeat.net/projects/afio/
+     http://freecode.com/projects/afio
 
 2) The cpio archive format chosen by the kernel is simpler and cleaner (and
    thus easier to create and parse) than any of the (literally dozens of)
diff --git a/Documentation/hwmon/lm80 b/Documentation/hwmon/lm80
index cb5b407..a60b43e 100644
--- a/Documentation/hwmon/lm80
+++ b/Documentation/hwmon/lm80
@@ -7,6 +7,11 @@ Supported chips:
     Addresses scanned: I2C 0x28 - 0x2f
     Datasheet: Publicly available at the National Semiconductor website
                http://www.national.com/
+  * National Semiconductor LM96080
+    Prefix: 'lm96080'
+    Addresses scanned: I2C 0x28 - 0x2f
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
 
 Authors:
         Frodo Looijaard <frodol@dds.nl>,
@@ -17,7 +22,9 @@ Description
 
 This driver implements support for the National Semiconductor LM80.
 It is described as a 'Serial Interface ACPI-Compatible Microprocessor
-System Hardware Monitor'.
+System Hardware Monitor'. The LM96080 is a more recent incarnation,
+it is pin and register compatible, with a few additional features not
+yet supported by the driver.
 
 The LM80 implements one temperature sensor, two fan rotation speed sensors,
 seven voltage sensors, alarms, and some miscellaneous stuff.
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
index 9cd14cfe..b466974 100644
--- a/Documentation/hwmon/lm90
+++ b/Documentation/hwmon/lm90
@@ -118,6 +118,10 @@ Supported chips:
     Addresses scanned: I2C 0x48 through 0x4F
     Datasheet: Publicly available at NXP website
                http://ics.nxp.com/products/interface/datasheet/sa56004x.pdf
+  * GMT G781
+    Prefix: 'g781'
+    Addresses scanned: I2C 0x4c, 0x4d
+    Datasheet: Not publicly available from GMT
 
 Author: Jean Delvare <khali@linux-fr.org>
 
diff --git a/Documentation/hwmon/mc13783-adc b/Documentation/hwmon/mc13783-adc
index 044531a..d0e7b3f 100644
--- a/Documentation/hwmon/mc13783-adc
+++ b/Documentation/hwmon/mc13783-adc
@@ -3,8 +3,11 @@ Kernel driver mc13783-adc
 
 Supported chips:
   * Freescale Atlas MC13783
-    Prefix: 'mc13783_adc'
+    Prefix: 'mc13783'
     Datasheet: http://www.freescale.com/files/rf_if/doc/data_sheet/MC13783.pdf?fsrch=1
+  * Freescale Atlas MC13892
+    Prefix: 'mc13892'
+    Datasheet: http://cache.freescale.com/files/analog/doc/data_sheet/MC13892.pdf?fsrch=1&sr=1
 
 Authors:
     Sascha Hauer <s.hauer@pengutronix.de>
@@ -13,20 +16,21 @@ Authors:
 Description
 -----------
 
-The Freescale MC13783 is a Power Management and Audio Circuit. Among
-other things it contains a 10-bit A/D converter. The converter has 16
-channels which can be used in different modes.
-The A/D converter has a resolution of 2.25mV. Channels 0-4 have
-a dedicated meaning with chip internal scaling applied. Channels 5-7
-can be used as general purpose inputs or alternatively in a dedicated
-mode. Channels 12-15 are occupied by the touchscreen if it's active.
+The Freescale MC13783 and MC13892 are Power Management and Audio Circuits.
+Among other things they contain a 10-bit A/D converter. The converter has 16
+(MC13783) resp. 12 (MC13892) channels which can be used in different modes. The
+A/D converter has a resolution of 2.25mV.
 
-Currently the driver only supports channels 2 and 5-15 with no alternative
-modes for channels 5-7.
+Some channels can be used as General Purpose inputs or in a dedicated mode with
+a chip internal scaling applied .
 
-See this table for the meaning of the different channels and their chip
-internal scaling:
+Currently the driver only supports the Application Supply channel (BP / BPSNS),
+the General Purpose inputs and touchscreen.
 
+See the following tables for the meaning of the different channels and their
+chip internal scaling:
+
+MC13783:
 Channel	Signal						Input Range	Scaling
 -------------------------------------------------------------------------------
 0	Battery Voltage (BATT)				2.50 - 4.65V	-2.40V
@@ -34,7 +38,7 @@ Channel	Signal						Input Range	Scaling
 2	Application Supply (BP)				2.50 - 4.65V	-2.40V
 3	Charger Voltage (CHRGRAW)			0 - 10V /	/5
 							0 - 20V		/10
-4	Charger Current (CHRGISNSP-CHRGISNSN)		-0.25V - 0.25V	x4
+4	Charger Current (CHRGISNSP-CHRGISNSN)		-0.25 - 0.25V	x4
 5	General Purpose ADIN5 / Battery Pack Thermistor	0 - 2.30V	No
 6	General Purpose ADIN6 / Backup Voltage (LICELL)	0 - 2.30V /	No /
 							1.50 - 3.50V	-1.20V
@@ -48,3 +52,23 @@ Channel	Signal						Input Range	Scaling
 13	General Purpose TSX2 / Touchscreen X-plate 2	0 - 2.30V	No
 14	General Purpose TSY1 / Touchscreen Y-plate 1	0 - 2.30V	No
 15	General Purpose TSY2 / Touchscreen Y-plate 2	0 - 2.30V	No
+
+MC13892:
+Channel	Signal						Input Range	Scaling
+-------------------------------------------------------------------------------
+0	Battery Voltage (BATT)				0 - 4.8V	/2
+1	Battery Current (BATT - BATTISNSCC)		-60 - 60 mV	x20
+2	Application Supply (BPSNS)			0 - 4.8V	/2
+3	Charger Voltage (CHRGRAW)			0 - 12V /	/5
+							0 - 20V		/10
+4	Charger Current (CHRGISNS-BPSNS) /		-0.3 - 0.3V /	x4 /
+	Touchscreen X-plate 1				0 - 2.4V	No
+5	General Purpose ADIN5 /	Battery Pack Thermistor	0 - 2.4V	No
+6	General Purpose ADIN6 / Backup Voltage (LICELL)	0 - 2.4V /	No
+	Backup Voltage (LICELL)                        	0 - 3.6V	x2/3
+7	General Purpose ADIN7 / UID / Die Temperature	0 - 2.4V /	No /
+							0 - 4.8V	/2
+12	General Purpose TSX1 / Touchscreen X-plate 1	0 - 2.4V	No
+13	General Purpose TSX2 / Touchscreen X-plate 2	0 - 2.4V	No
+14	General Purpose TSY1 / Touchscreen Y-plate 1	0 - 2.4V	No
+15	General Purpose TSY2 / Touchscreen Y-plate 2	0 - 2.4V	No
diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801
index 2871fd5..71f55bb 100644
--- a/Documentation/i2c/busses/i2c-i801
+++ b/Documentation/i2c/busses/i2c-i801
@@ -20,6 +20,7 @@ Supported adapters:
   * Intel Patsburg (PCH)
   * Intel DH89xxCC (PCH)
   * Intel Panther Point (PCH)
+  * Intel Lynx Point (PCH)
    Datasheets: Publicly available at the Intel website
 
 On Intel Patsburg and later chipsets, both the normal host SMBus controller
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 4840334..d35ff2f 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -189,7 +189,7 @@ Code  Seq#(hex)	Include File		Comments
 'Y'	all	linux/cyclades.h
 'Z'	14-15	drivers/message/fusion/mptctl.h
 '['	00-07	linux/usb/tmc.h		USB Test and Measurement Devices
-					<mailto:gregkh@suse.de>
+					<mailto:gregkh@linuxfoundation.org>
 'a'	all	linux/atm*.h, linux/sonet.h	ATM on linux
 					<http://lrcwww.epfl.ch/>
 'b'	00-FF				conflict! bit3 vme host bridge
@@ -224,6 +224,7 @@ Code  Seq#(hex)	Include File		Comments
 'j'	00-3F	linux/joystick.h
 'k'	00-0F	linux/spi/spidev.h	conflict!
 'k'	00-05	video/kyro.h		conflict!
+'k'	10-17	linux/hsi/hsi_char.h	HSI character device
 'l'	00-3F	linux/tcfs_fs.h		transparent cryptographic file system
 					<http://web.archive.org/web/*/http://mikonos.dia.unisa.it/tcfs>
 'l'	40-7F	linux/udf_fs_i.h	in development:
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 033d4e6..9677556 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -950,7 +950,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			     controller
 	i8042.nopnp	[HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
 			     controllers
-	i8042.notimeout	[HW] Ignore timeout condition signalled by conroller
+	i8042.notimeout	[HW] Ignore timeout condition signalled by controller
 	i8042.reset	[HW] Reset the controller during init and cleanup
 	i8042.unlock	[HW] Unlock (ignore) the keylock
 
@@ -1311,6 +1311,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			If there are multiple matching configurations changing
 			the same attribute, the last one is used.
 
+	libsas.force_hard_reset=
+			[LIBSAS] Clear SATA affiliations with every reset, for
+			cases where affiliation errors are causing boot
+			failures, otherwise use sysfs hard_reset interface to
+			clear individual phys.
+
 	memblock=debug	[KNL] Enable memblock debug messages.
 
 	load_ramdisk=	[RAM] List of ramdisks to load from floppy
@@ -1657,6 +1663,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			of returning the full 64-bit number.
 			The default is to return 64-bit inode numbers.
 
+	nfs.max_session_slots=
+			[NFSv4.1] Sets the maximum number of session slots
+			the client will attempt to negotiate with the server.
+			This limits the number of simultaneous RPC requests
+			that the client can send to the NFSv4.1 server.
+			Note that there is little point in setting this
+			value higher than the max_tcp_slot_table_limit.
+
 	nfs.nfs4_disable_idmapping=
 			[NFSv4] When set to the default of '1', this option
 			ensures that both the RPC level authentication
@@ -1833,6 +1847,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			shutdown the other cpus.  Instead use the REBOOT_VECTOR
 			irq.
 
+	nomodule	Disable module load
+
 	nopat		[X86] Disable PAT (page attribute table extension of
 			pagetables) support.
 
@@ -2211,6 +2227,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 			default: off.
 
+	printk.always_kmsg_dump=
+			Trigger kmsg_dump for cases other than kernel oops or
+			panics
+			Format: <bool>  (1/Y/y=enable, 0/N/n=disable)
+			default: disabled
+
 	printk.time=	Show timing data prefixed to each printk message line
 			Format: <bool>  (1/Y/y=enable, 0/N/n=disable)
 
@@ -2434,7 +2456,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			For more information see Documentation/vm/slub.txt.
 
 	slub_min_order=	[MM, SLUB]
-			Determines the mininum page order for slabs. Must be
+			Determines the minimum page order for slabs. Must be
 			lower than slub_max_order.
 			For more information see Documentation/vm/slub.txt.
 
@@ -2600,7 +2622,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 	threadirqs	[KNL]
 			Force threading of all interrupt handlers except those
-			marked explicitely IRQF_NO_THREAD.
+			marked explicitly IRQF_NO_THREAD.
 
 	topology=	[S390]
 			Format: {off | on}
diff --git a/Documentation/ko_KR/HOWTO b/Documentation/ko_KR/HOWTO
index ab5189a..2f48f20 100644
--- a/Documentation/ko_KR/HOWTO
+++ b/Documentation/ko_KR/HOWTO
@@ -354,7 +354,7 @@ Andrew Morton에 의해 배포된 실험적인 커널 패치들이다. Andrew는
     git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
   quilt trees:
-    - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman < gregkh@suse.de>
+    - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman < gregkh@linuxfoundation.org>
     kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
     - x86-64, partly i386, Andi Kleen < ak@suse.de>
         ftp.firstfloor.org:/pub/ak/x86_64/quilt/
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index 3ab2472..49578cf 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -1,6 +1,6 @@
 Everything you never wanted to know about kobjects, ksets, and ktypes
 
-Greg Kroah-Hartman <gregkh@suse.de>
+Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
 Based on an original article by Jon Corbet for lwn.net written October 1,
 2003 and located at http://lwn.net/Articles/51437/
diff --git a/Documentation/laptops/sony-laptop.txt b/Documentation/laptops/sony-laptop.txt
index 2bd4e82..0d5ac7f 100644
--- a/Documentation/laptops/sony-laptop.txt
+++ b/Documentation/laptops/sony-laptop.txt
@@ -17,6 +17,11 @@ subsystem. See the logs of acpid or /proc/acpi/event and
 devices are created by the driver. Additionally, loading the driver with the
 debug option will report all events in the kernel log.
 
+The "scancodes" passed to the input system (that can be remapped with udev)
+are indexes to the table "sony_laptop_input_keycode_map" in the sony-laptop.c
+module.  For example the "FN/E" key combination (EJECTCD on some models)
+generates the scancode 20 (0x14).
+
 Backlight control:
 ------------------
 If your laptop model supports it, you will find sysfs files in the
diff --git a/Documentation/leds/leds-lp5521.txt b/Documentation/leds/leds-lp5521.txt
index c4d8d15..0e542ab 100644
--- a/Documentation/leds/leds-lp5521.txt
+++ b/Documentation/leds/leds-lp5521.txt
@@ -43,17 +43,23 @@ Format: 10x mA i.e 10 means 1.0 mA
 example platform data:
 
 Note: chan_nr can have values between 0 and 2.
+The name of each channel can be configurable.
+If the name field is not defined, the default name will be set to 'xxxx:channelN'
+(XXXX : pdata->label or i2c client name, N : channel number)
 
 static struct lp5521_led_config lp5521_led_config[] = {
         {
+		.name = "red",
                 .chan_nr        = 0,
                 .led_current    = 50,
 		.max_current    = 130,
         }, {
+		.name = "green",
                 .chan_nr        = 1,
                 .led_current    = 0,
 		.max_current    = 130,
         }, {
+		.name = "blue",
                 .chan_nr        = 2,
                 .led_current    = 0,
 		.max_current    = 130,
@@ -86,3 +92,60 @@ static struct lp5521_platform_data lp5521_platform_data = {
 
 If the current is set to 0 in the platform data, that channel is
 disabled and it is not visible in the sysfs.
+
+The 'update_config' : CONFIG register (ADDR 08h)
+This value is platform-specific data.
+If update_config is not defined, the CONFIG register is set with
+'LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT'.
+(Enable auto-powersave, set charge pump to auto, red to battery)
+
+example of update_config :
+
+#define LP5521_CONFIGS	(LP5521_PWM_HF | LP5521_PWRSAVE_EN | \
+			LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT | \
+			LP5521_CLK_INT)
+
+static struct lp5521_platform_data lp5521_pdata = {
+	.led_config = lp5521_led_config,
+	.num_channels = ARRAY_SIZE(lp5521_led_config),
+	.clock_mode = LP5521_CLOCK_INT,
+	.update_config = LP5521_CONFIGS,
+};
+
+LED patterns : LP5521 has autonomous operation without external control.
+Pattern data can be defined in the platform data.
+
+example of led pattern data :
+
+/* RGB(50,5,0) 500ms on, 500ms off, infinite loop */
+static u8 pattern_red[] = {
+		0x40, 0x32, 0x60, 0x00,	0x40, 0x00, 0x60, 0x00,
+		};
+
+static u8 pattern_green[] = {
+		0x40, 0x05, 0x60, 0x00, 0x40, 0x00, 0x60, 0x00,
+		};
+
+static struct lp5521_led_pattern board_led_patterns[] = {
+	{
+		.r = pattern_red,
+		.g = pattern_green,
+		.size_r = ARRAY_SIZE(pattern_red),
+		.size_g = ARRAY_SIZE(pattern_green),
+	},
+};
+
+static struct lp5521_platform_data lp5521_platform_data = {
+        .led_config     = lp5521_led_config,
+        .num_channels   = ARRAY_SIZE(lp5521_led_config),
+        .clock_mode     = LP5521_CLOCK_EXT,
+	.patterns = board_led_patterns,
+	.num_patterns = ARRAY_SIZE(board_led_patterns),
+};
+
+Then predefined led pattern(s) can be executed via the sysfs.
+To start the pattern #1,
+# echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern
+(xxxx : i2c bus & slave address)
+To end the pattern,
+# echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern
diff --git a/Documentation/lockup-watchdogs.txt b/Documentation/lockup-watchdogs.txt
new file mode 100644
index 0000000..d2a3660
--- /dev/null
+++ b/Documentation/lockup-watchdogs.txt
@@ -0,0 +1,63 @@
+===============================================================
+Softlockup detector and hardlockup detector (aka nmi_watchdog)
+===============================================================
+
+The Linux kernel can act as a watchdog to detect both soft and hard
+lockups.
+
+A 'softlockup' is defined as a bug that causes the kernel to loop in
+kernel mode for more than 20 seconds (see "Implementation" below for
+details), without giving other tasks a chance to run. The current
+stack trace is displayed upon detection and, by default, the system
+will stay locked up. Alternatively, the kernel can be configured to
+panic; a sysctl, "kernel.softlockup_panic", a kernel parameter,
+"softlockup_panic" (see "Documentation/kernel-parameters.txt" for
+details), and a compile option, "BOOTPARAM_HARDLOCKUP_PANIC", are
+provided for this.
+
+A 'hardlockup' is defined as a bug that causes the CPU to loop in
+kernel mode for more than 10 seconds (see "Implementation" below for
+details), without letting other interrupts have a chance to run.
+Similarly to the softlockup case, the current stack trace is displayed
+upon detection and the system will stay locked up unless the default
+behavior is changed, which can be done through a compile time knob,
+"BOOTPARAM_HARDLOCKUP_PANIC", and a kernel parameter, "nmi_watchdog"
+(see "Documentation/kernel-parameters.txt" for details).
+
+The panic option can be used in combination with panic_timeout (this
+timeout is set through the confusingly named "kernel.panic" sysctl),
+to cause the system to reboot automatically after a specified amount
+of time.
+
+=== Implementation ===
+
+The soft and hard lockup detectors are built on top of the hrtimer and
+perf subsystems, respectively. A direct consequence of this is that,
+in principle, they should work in any architecture where these
+subsystems are present.
+
+A periodic hrtimer runs to generate interrupts and kick the watchdog
+task. An NMI perf event is generated every "watchdog_thresh"
+(compile-time initialized to 10 and configurable through sysctl of the
+same name) seconds to check for hardlockups. If any CPU in the system
+does not receive any hrtimer interrupt during that time the
+'hardlockup detector' (the handler for the NMI perf event) will
+generate a kernel warning or call panic, depending on the
+configuration.
+
+The watchdog task is a high priority kernel thread that updates a
+timestamp every time it is scheduled. If that timestamp is not updated
+for 2*watchdog_thresh seconds (the softlockup threshold) the
+'softlockup detector' (coded inside the hrtimer callback function)
+will dump useful debug information to the system log, after which it
+will call panic if it was instructed to do so or resume execution of
+other kernel code.
+
+The period of the hrtimer is 2*watchdog_thresh/5, which means it has
+two or three chances to generate an interrupt before the hardlockup
+detector kicks in.
+
+As explained above, a kernel knob is provided that allows
+administrators to configure the period of the hrtimer and the perf
+event. The right value for a particular environment is a trade-off
+between fast response to lockups and detection overhead.
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index abf481f..82761a3 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -89,7 +89,7 @@ TTY_DRIVER_MAGIC      0x5402      tty_driver        include/linux/tty_driver.h
 MGSLPC_MAGIC          0x5402      mgslpc_info       drivers/char/pcmcia/synclink_cs.c
 TTY_LDISC_MAGIC       0x5403      tty_ldisc         include/linux/tty_ldisc.h
 USB_SERIAL_MAGIC      0x6702      usb_serial        drivers/usb/serial/usb-serial.h
-FULL_DUPLEX_MAGIC     0x6969                        drivers/net/tulip/de2104x.c
+FULL_DUPLEX_MAGIC     0x6969                        drivers/net/ethernet/dec/tulip/de2104x.c
 USB_BLUETOOTH_MAGIC   0x6d02      usb_bluetooth     drivers/usb/class/bluetty.c
 RFCOMM_TTY_MAGIC      0x6d02                        net/bluetooth/rfcomm/tty.c
 USB_SERIAL_PORT_MAGIC 0x7301      usb_serial_port   drivers/usb/serial/usb-serial.h
diff --git a/Documentation/networking/LICENSE.qlge b/Documentation/networking/LICENSE.qlge
index 123b6ed..ce64e4d 100644
--- a/Documentation/networking/LICENSE.qlge
+++ b/Documentation/networking/LICENSE.qlge
@@ -1,46 +1,288 @@
-Copyright (c)  2003-2008 QLogic Corporation
-QLogic Linux Networking HBA Driver
+Copyright (c) 2003-2011 QLogic Corporation
+QLogic Linux qlge NIC Driver
 
-This program includes a device driver for Linux 2.6 that may be
-distributed with QLogic hardware specific firmware binary file.
 You may modify and redistribute the device driver code under the
-GNU General Public License as published by the Free Software
-Foundation (version 2 or a later version).
-
-You may redistribute the hardware specific firmware binary file
-under the following terms:
-
-	1. Redistribution of source code (only if applicable),
-	   must retain the above copyright notice, this list of
-	   conditions and the following disclaimer.
-
-	2. Redistribution in binary form must reproduce the above
-	   copyright notice, this list of conditions and the
-	   following disclaimer in the documentation and/or other
-	   materials provided with the distribution.
-
-	3. The name of QLogic Corporation may not be used to
-	   endorse or promote products derived from this software
-	   without specific prior written permission
-
-REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
-THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
-CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
-OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
-TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
-ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
-COMBINATION WITH THIS PROGRAM.
+GNU General Public License (a copy of which is attached hereto as
+Exhibit A) published by the Free Software Foundation (version 2).
 
+
+EXHIBIT A
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/Documentation/networking/dns_resolver.txt b/Documentation/networking/dns_resolver.txt
index 7f531ad..d86adcd 100644
--- a/Documentation/networking/dns_resolver.txt
+++ b/Documentation/networking/dns_resolver.txt
@@ -102,6 +102,10 @@ implemented in the module can be called after doing:
      If _expiry is non-NULL, the expiry time (TTL) of the result will be
      returned also.
 
+The kernel maintains an internal keyring in which it caches looked up keys.
+This can be cleared by any process that has the CAP_SYS_ADMIN capability by
+the use of KEYCTL_KEYRING_CLEAR on the keyring ID.
+
 
 ===============================
 READING DNS KEYS FROM USERSPACE
diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt
index 9eb1ba5..95e5f59 100644
--- a/Documentation/networking/phy.txt
+++ b/Documentation/networking/phy.txt
@@ -62,7 +62,8 @@ The MDIO bus
  5) The bus must also be declared somewhere as a device, and registered.
 
  As an example for how one driver implemented an mdio bus driver, see
- drivers/net/gianfar_mii.c and arch/ppc/syslib/mpc85xx_devices.c
+ drivers/net/ethernet/freescale/fsl_pq_mdio.c and an associated DTS file
+ for one of the users. (e.g. "git grep fsl,.*-mdio arch/powerpc/boot/dts/")
 
 Connecting to a PHY
 
diff --git a/Documentation/nmi_watchdog.txt b/Documentation/nmi_watchdog.txt
deleted file mode 100644
index bf9f80a..0000000
--- a/Documentation/nmi_watchdog.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-
-[NMI watchdog is available for x86 and x86-64 architectures]
-
-Is your system locking up unpredictably? No keyboard activity, just
-a frustrating complete hard lockup? Do you want to help us debugging
-such lockups? If all yes then this document is definitely for you.
-
-On many x86/x86-64 type hardware there is a feature that enables
-us to generate 'watchdog NMI interrupts'.  (NMI: Non Maskable Interrupt
-which get executed even if the system is otherwise locked up hard).
-This can be used to debug hard kernel lockups.  By executing periodic
-NMI interrupts, the kernel can monitor whether any CPU has locked up,
-and print out debugging messages if so.
-
-In order to use the NMI watchdog, you need to have APIC support in your
-kernel. For SMP kernels, APIC support gets compiled in automatically. For
-UP, enable either CONFIG_X86_UP_APIC (Processor type and features -> Local
-APIC support on uniprocessors) or CONFIG_X86_UP_IOAPIC (Processor type and
-features -> IO-APIC support on uniprocessors) in your kernel config.
-CONFIG_X86_UP_APIC is for uniprocessor machines without an IO-APIC.
-CONFIG_X86_UP_IOAPIC is for uniprocessor with an IO-APIC. [Note: certain
-kernel debugging options, such as Kernel Stack Meter or Kernel Tracer,
-may implicitly disable the NMI watchdog.]
-
-For x86-64, the needed APIC is always compiled in.
-
-Using local APIC (nmi_watchdog=2) needs the first performance register, so
-you can't use it for other purposes (such as high precision performance
-profiling.) However, at least oprofile and the perfctr driver disable the
-local APIC NMI watchdog automatically.
-
-To actually enable the NMI watchdog, use the 'nmi_watchdog=N' boot
-parameter.  Eg. the relevant lilo.conf entry:
-
-        append="nmi_watchdog=1"
-
-For SMP machines and UP machines with an IO-APIC use nmi_watchdog=1.
-For UP machines without an IO-APIC use nmi_watchdog=2, this only works
-for some processor types.  If in doubt, boot with nmi_watchdog=1 and
-check the NMI count in /proc/interrupts; if the count is zero then
-reboot with nmi_watchdog=2 and check the NMI count.  If it is still
-zero then log a problem, you probably have a processor that needs to be
-added to the nmi code.
-
-A 'lockup' is the following scenario: if any CPU in the system does not
-execute the period local timer interrupt for more than 5 seconds, then
-the NMI handler generates an oops and kills the process. This
-'controlled crash' (and the resulting kernel messages) can be used to
-debug the lockup. Thus whenever the lockup happens, wait 5 seconds and
-the oops will show up automatically. If the kernel produces no messages
-then the system has crashed so hard (eg. hardware-wise) that either it
-cannot even accept NMI interrupts, or the crash has made the kernel
-unable to print messages.
-
-Be aware that when using local APIC, the frequency of NMI interrupts
-it generates, depends on the system load. The local APIC NMI watchdog,
-lacking a better source, uses the "cycles unhalted" event. As you may
-guess it doesn't tick when the CPU is in the halted state (which happens
-when the system is idle), but if your system locks up on anything but the
-"hlt" processor instruction, the watchdog will trigger very soon as the
-"cycles unhalted" event will happen every clock tick. If it locks up on
-"hlt", then you are out of luck -- the event will not happen at all and the
-watchdog won't trigger. This is a shortcoming of the local APIC watchdog
--- unfortunately there is no "clock ticks" event that would work all the
-time. The I/O APIC watchdog is driven externally and has no such shortcoming.
-But its NMI frequency is much higher, resulting in a more significant hit
-to the overall system performance.
-
-On x86 nmi_watchdog is disabled by default so you have to enable it with
-a boot time parameter.
-
-It's possible to disable the NMI watchdog in run-time by writing "0" to
-/proc/sys/kernel/nmi_watchdog. Writing "1" to the same file will re-enable
-the NMI watchdog. Notice that you still need to use "nmi_watchdog=" parameter
-at boot time.
-
-NOTE: In kernels prior to 2.4.2-ac18 the NMI-oopser is enabled unconditionally
-on x86 SMP boxes.
-
-[ feel free to send bug reports, suggestions and patches to
-  Ingo Molnar <mingo@redhat.com> or the Linux SMP mailing
-  list at <linux-smp@vger.kernel.org> ]
-
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
index 150fd38..ee3266b 100644
--- a/Documentation/pinctrl.txt
+++ b/Documentation/pinctrl.txt
@@ -208,6 +208,8 @@ unconnected.
 
 For example, a platform may do this:
 
+#include <linux/pinctrl/consumer.h>
+
 ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP);
 
 To pull up a pin to VDD. The pin configuration driver implements callbacks for
@@ -726,19 +728,19 @@ same time.
 All the above functions are mandatory to implement for a pinmux driver.
 
 
-Pinmux interaction with the GPIO subsystem
-==========================================
+Pin control interaction with the GPIO subsystem
+===============================================
 
-The public pinmux API contains two functions named pinmux_request_gpio()
-and pinmux_free_gpio(). These two functions shall *ONLY* be called from
+The public pinmux API contains two functions named pinctrl_request_gpio()
+and pinctrl_free_gpio(). These two functions shall *ONLY* be called from
 gpiolib-based drivers as part of their gpio_request() and
-gpio_free() semantics. Likewise the pinmux_gpio_direction_[input|output]
+gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output]
 shall only be called from within respective gpio_direction_[input|output]
 gpiolib implementation.
 
 NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be
-muxed in. Instead, implement a proper gpiolib driver and have that driver
-request proper muxing for its pins.
+controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have
+that driver request proper muxing and other control for its pins.
 
 The function list could become long, especially if you can convert every
 individual pin into a GPIO pin independent of any other pins, and then try
@@ -747,7 +749,7 @@ the approach to define every pin as a function.
 In this case, the function array would become 64 entries for each GPIO
 setting and then the device functions.
 
-For this reason there are two functions a pinmux driver can implement
+For this reason there are two functions a pin control driver can implement
 to enable only GPIO on an individual pin: .gpio_request_enable() and
 .gpio_disable_free().
 
@@ -762,7 +764,7 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction
 will be passed along to this function.
 
 Alternatively to using these special functions, it is fully allowed to use
-named functions for each GPIO pin, the pinmux_request_gpio() will attempt to
+named functions for each GPIO pin, the pinctrl_request_gpio() will attempt to
 obtain the function "gpioN" where "N" is the global GPIO pin number if no
 special GPIO-handler is registered.
 
@@ -781,7 +783,7 @@ spi on the second function mapping:
 
 #include <linux/pinctrl/machine.h>
 
-static const struct pinmux_map __initdata pmx_mapping[] = {
+static const struct pinctrl_map __initdata mapping[] = {
 	{
 		.ctrl_dev_name = "pinctrl-foo",
 		.function = "spi0",
@@ -805,21 +807,18 @@ must match a function provided by the pinmux driver handling this pin range.
 
 As you can see we may have several pin controllers on the system and thus
 we need to specify which one of them that contain the functions we wish
-to map. The map can also use struct device * directly, so there is no
-inherent need to use strings to specify .dev_name or .ctrl_dev_name, these
-are for the situation where you do not have a handle to the struct device *,
-for example if they are not yet instantiated or cumbersome to obtain.
+to map.
 
 You register this pinmux mapping to the pinmux subsystem by simply:
 
-       ret = pinmux_register_mappings(pmx_mapping, ARRAY_SIZE(pmx_mapping));
+       ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping));
 
 Since the above construct is pretty common there is a helper macro to make
 it even more compact which assumes you want to use pinctrl-foo and position
 0 for mapping, for example:
 
-static struct pinmux_map __initdata pmx_mapping[] = {
-       PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"),
+static struct pinctrl_map __initdata mapping[] = {
+       PIN_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"),
 };
 
 
@@ -902,7 +901,7 @@ case), we define a mapping like this:
 The result of grabbing this mapping from the device with something like
 this (see next paragraph):
 
-	pmx = pinmux_get(&device, "8bit");
+	p = pinctrl_get(&device, "8bit");
 
 Will be that you activate all the three bottom records in the mapping at
 once. Since they share the same name, pin controller device, funcion and
@@ -914,44 +913,44 @@ pinmux core.
 Pinmux requests from drivers
 ============================
 
-Generally it is discouraged to let individual drivers get and enable pinmuxes.
-So if possible, handle the pinmuxes in platform code or some other place where
-you have access to all the affected struct device * pointers. In some cases
-where a driver needs to switch between different mux mappings at runtime
-this is not possible.
+Generally it is discouraged to let individual drivers get and enable pin
+control. So if possible, handle the pin control in platform code or some other
+place where you have access to all the affected struct device * pointers. In
+some cases where a driver needs to e.g. switch between different mux mappings
+at runtime this is not possible.
 
-A driver may request a certain mux to be activated, usually just the default
-mux like this:
+A driver may request a certain control state to be activated, usually just the
+default state like this:
 
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
 
 struct foo_state {
-       struct pinmux *pmx;
+       struct pinctrl *p;
        ...
 };
 
 foo_probe()
 {
 	/* Allocate a state holder named "state" etc */
-	struct pinmux pmx;
+	struct pinctrl p;
 
-	pmx = pinmux_get(&device, NULL);
-	if IS_ERR(pmx)
-		return PTR_ERR(pmx);
-	pinmux_enable(pmx);
+	p = pinctrl_get(&device, NULL);
+	if IS_ERR(p)
+		return PTR_ERR(p);
+	pinctrl_enable(p);
 
-	state->pmx = pmx;
+	state->p = p;
 }
 
 foo_remove()
 {
-	pinmux_disable(state->pmx);
-	pinmux_put(state->pmx);
+	pinctrl_disable(state->p);
+	pinctrl_put(state->p);
 }
 
-If you want to grab a specific mux mapping and not just the first one found for
-this device you can specify a specific mapping name, for example in the above
-example the second i2c0 setting: pinmux_get(&device, "spi0-pos-B");
+If you want to grab a specific control mapping and not just the first one
+found for this device you can specify a specific mapping name, for example in
+the above example the second i2c0 setting: pinctrl_get(&device, "spi0-pos-B");
 
 This get/enable/disable/put sequence can just as well be handled by bus drivers
 if you don't want each and every driver to handle it and you know the
@@ -959,52 +958,52 @@ arrangement on your bus.
 
 The semantics of the get/enable respective disable/put is as follows:
 
-- pinmux_get() is called in process context to reserve the pins affected with
+- pinctrl_get() is called in process context to reserve the pins affected with
   a certain mapping and set up the pinmux core and the driver. It will allocate
   a struct from the kernel memory to hold the pinmux state.
 
-- pinmux_enable()/pinmux_disable() is quick and can be called from fastpath
+- pinctrl_enable()/pinctrl_disable() is quick and can be called from fastpath
   (irq context) when you quickly want to set up/tear down the hardware muxing
   when running a device driver. Usually it will just poke some values into a
   register.
 
-- pinmux_disable() is called in process context to tear down the pin requests
-  and release the state holder struct for the mux setting.
+- pinctrl_disable() is called in process context to tear down the pin requests
+  and release the state holder struct for the mux setting etc.
 
-Usually the pinmux core handled the get/put pair and call out to the device
-drivers bookkeeping operations, like checking available functions and the
-associated pins, whereas the enable/disable pass on to the pin controller
+Usually the pin control core handled the get/put pair and call out to the
+device drivers bookkeeping operations, like checking available functions and
+the associated pins, whereas the enable/disable pass on to the pin controller
 driver which takes care of activating and/or deactivating the mux setting by
 quickly poking some registers.
 
-The pins are allocated for your device when you issue the pinmux_get() call,
+The pins are allocated for your device when you issue the pinctrl_get() call,
 after this you should be able to see this in the debugfs listing of all pins.
 
 
-System pinmux hogging
-=====================
+System pin control hogging
+==========================
 
-A system pinmux map entry, i.e. a pinmux setting that does not have a device
-associated with it, can be hogged by the core when the pin controller is
-registered. This means that the core will attempt to call pinmux_get() and
-pinmux_enable() on it immediately after the pin control device has been
+A system pin control map entry, i.e. a pin control setting that does not have
+a device associated with it, can be hogged by the core when the pin controller
+is registered. This means that the core will attempt to call pinctrl_get() and
+pinctrl_enable() on it immediately after the pin control device has been
 registered.
 
-This is enabled by simply setting the .hog_on_boot field in the map to true,
-like this:
+This is enabled by simply setting the .dev_name field in the map to the name
+of the pin controller itself, like this:
 
 {
 	.name = "POWERMAP"
 	.ctrl_dev_name = "pinctrl-foo",
 	.function = "power_func",
-	.hog_on_boot = true,
+	.dev_name = "pinctrl-foo",
 },
 
 Since it may be common to request the core to hog a few always-applicable
 mux settings on the primary pin controller, there is a convenience macro for
 this:
 
-PINMUX_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func")
+PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "pinctrl-foo", "power_func")
 
 This gives the exact same result as the above construction.
 
@@ -1022,25 +1021,27 @@ function, but with different named in the mapping as described under
 This snippet first muxes the function in the pins defined by group A, enables
 it, disables and releases it, and muxes it in on the pins defined by group B:
 
+#include <linux/pinctrl/consumer.h>
+
 foo_switch()
 {
-	struct pinmux *pmx;
+	struct pinctrl *p;
 
 	/* Enable on position A */
-	pmx = pinmux_get(&device, "spi0-pos-A");
-	if IS_ERR(pmx)
-		return PTR_ERR(pmx);
-	pinmux_enable(pmx);
+	p = pinctrl_get(&device, "spi0-pos-A");
+	if IS_ERR(p)
+		return PTR_ERR(p);
+	pinctrl_enable(p);
 
 	/* This releases the pins again */
-	pinmux_disable(pmx);
-	pinmux_put(pmx);
+	pinctrl_disable(p);
+	pinctrl_put(p);
 
 	/* Enable on position B */
-	pmx = pinmux_get(&device, "spi0-pos-B");
-	if IS_ERR(pmx)
-		return PTR_ERR(pmx);
-	pinmux_enable(pmx);
+	p = pinctrl_get(&device, "spi0-pos-B");
+	if IS_ERR(p)
+		return PTR_ERR(p);
+	pinctrl_enable(p);
 	...
 }
 
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 20af7de..872815c 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -96,6 +96,12 @@ struct dev_pm_ops {
 	int (*thaw)(struct device *dev);
 	int (*poweroff)(struct device *dev);
 	int (*restore)(struct device *dev);
+	int (*suspend_late)(struct device *dev);
+	int (*resume_early)(struct device *dev);
+	int (*freeze_late)(struct device *dev);
+	int (*thaw_early)(struct device *dev);
+	int (*poweroff_late)(struct device *dev);
+	int (*restore_early)(struct device *dev);
 	int (*suspend_noirq)(struct device *dev);
 	int (*resume_noirq)(struct device *dev);
 	int (*freeze_noirq)(struct device *dev);
@@ -305,7 +311,7 @@ Entering System Suspend
 -----------------------
 When the system goes into the standby or memory sleep state, the phases are:
 
-		prepare, suspend, suspend_noirq.
+		prepare, suspend, suspend_late, suspend_noirq.
 
     1.	The prepare phase is meant to prevent races by preventing new devices
 	from being registered; the PM core would never know that all the
@@ -324,7 +330,12 @@ When the system goes into the standby or memory sleep state, the phases are:
 	appropriate low-power state, depending on the bus type the device is on,
 	and they may enable wakeup events.
 
-    3.	The suspend_noirq phase occurs after IRQ handlers have been disabled,
+    3	For a number of devices it is convenient to split suspend into the
+	"quiesce device" and "save device state" phases, in which cases
+	suspend_late is meant to do the latter.  It is always executed after
+	runtime power management has been disabled for all devices.
+
+    4.	The suspend_noirq phase occurs after IRQ handlers have been disabled,
 	which means that the driver's interrupt handler will not be called while
 	the callback method is running.  The methods should save the values of
 	the device's registers that weren't saved previously and finally put the
@@ -359,7 +370,7 @@ Leaving System Suspend
 ----------------------
 When resuming from standby or memory sleep, the phases are:
 
-		resume_noirq, resume, complete.
+		resume_noirq, resume_early, resume, complete.
 
     1.	The resume_noirq callback methods should perform any actions needed
 	before the driver's interrupt handlers are invoked.  This generally
@@ -375,14 +386,18 @@ When resuming from standby or memory sleep, the phases are:
 	device driver's ->pm.resume_noirq() method to perform device-specific
 	actions.
 
-    2.	The resume methods should bring the the device back to its operating
+    2.	The resume_early methods should prepare devices for the execution of
+	the resume methods.  This generally involves undoing the actions of the
+	preceding suspend_late phase.
+
+    3	The resume methods should bring the the device back to its operating
 	state, so that it can perform normal I/O.  This generally involves
 	undoing the actions of the suspend phase.
 
-    3.	The complete phase uses only a bus callback.  The method should undo the
-	actions of the prepare phase.  Note, however, that new children may be
-	registered below the device as soon as the resume callbacks occur; it's
-	not necessary to wait until the complete phase.
+    4.	The complete phase should undo the actions of the prepare phase.  Note,
+	however, that new children may be registered below the device as soon as
+	the resume callbacks occur; it's not necessary to wait until the
+	complete phase.
 
 At the end of these phases, drivers should be as functional as they were before
 suspending: I/O can be performed using DMA and IRQs, and the relevant clocks are
@@ -429,8 +444,8 @@ an image of the system memory while everything is stable, reactivate all
 devices (thaw), write the image to permanent storage, and finally shut down the
 system (poweroff).  The phases used to accomplish this are:
 
-	prepare, freeze, freeze_noirq, thaw_noirq, thaw, complete,
-	prepare, poweroff, poweroff_noirq
+	prepare, freeze, freeze_late, freeze_noirq, thaw_noirq, thaw_early,
+	thaw, complete, prepare, poweroff, poweroff_late, poweroff_noirq
 
     1.	The prepare phase is discussed in the "Entering System Suspend" section
 	above.
@@ -441,7 +456,11 @@ system (poweroff).  The phases used to accomplish this are:
 	save time it's best not to do so.  Also, the device should not be
 	prepared to generate wakeup events.
 
-    3.	The freeze_noirq phase is analogous to the suspend_noirq phase discussed
+    3.	The freeze_late phase is analogous to the suspend_late phase described
+	above, except that the device should not be put in a low-power state and
+	should not be allowed to generate wakeup events by it.
+
+    4.	The freeze_noirq phase is analogous to the suspend_noirq phase discussed
 	above, except again that the device should not be put in a low-power
 	state and should not be allowed to generate wakeup events.
 
@@ -449,15 +468,19 @@ At this point the system image is created.  All devices should be inactive and
 the contents of memory should remain undisturbed while this happens, so that the
 image forms an atomic snapshot of the system state.
 
-    4.	The thaw_noirq phase is analogous to the resume_noirq phase discussed
+    5.	The thaw_noirq phase is analogous to the resume_noirq phase discussed
 	above.  The main difference is that its methods can assume the device is
 	in the same state as at the end of the freeze_noirq phase.
 
-    5.	The thaw phase is analogous to the resume phase discussed above.  Its
+    6.	The thaw_early phase is analogous to the resume_early phase described
+	above.  Its methods should undo the actions of the preceding
+	freeze_late, if necessary.
+
+    7.	The thaw phase is analogous to the resume phase discussed above.  Its
 	methods should bring the device back to an operating state, so that it
 	can be used for saving the image if necessary.
 
-    6.	The complete phase is discussed in the "Leaving System Suspend" section
+    8.	The complete phase is discussed in the "Leaving System Suspend" section
 	above.
 
 At this point the system image is saved, and the devices then need to be
@@ -465,16 +488,19 @@ prepared for the upcoming system shutdown.  This is much like suspending them
 before putting the system into the standby or memory sleep state, and the phases
 are similar.
 
-    7.	The prepare phase is discussed above.
+    9.	The prepare phase is discussed above.
+
+    10.	The poweroff phase is analogous to the suspend phase.
 
-    8.	The poweroff phase is analogous to the suspend phase.
+    11.	The poweroff_late phase is analogous to the suspend_late phase.
 
-    9.	The poweroff_noirq phase is analogous to the suspend_noirq phase.
+    12.	The poweroff_noirq phase is analogous to the suspend_noirq phase.
 
-The poweroff and poweroff_noirq callbacks should do essentially the same things
-as the suspend and suspend_noirq callbacks.  The only notable difference is that
-they need not store the device register values, because the registers should
-already have been stored during the freeze or freeze_noirq phases.
+The poweroff, poweroff_late and poweroff_noirq callbacks should do essentially
+the same things as the suspend, suspend_late and suspend_noirq callbacks,
+respectively.  The only notable difference is that they need not store the
+device register values, because the registers should already have been stored
+during the freeze, freeze_late or freeze_noirq phases.
 
 
 Leaving Hibernation
@@ -518,22 +544,25 @@ To achieve this, the image kernel must restore the devices' pre-hibernation
 functionality.  The operation is much like waking up from the memory sleep
 state, although it involves different phases:
 
-	restore_noirq, restore, complete
+	restore_noirq, restore_early, restore, complete
 
     1.	The restore_noirq phase is analogous to the resume_noirq phase.
 
-    2.	The restore phase is analogous to the resume phase.
+    2.	The restore_early phase is analogous to the resume_early phase.
+
+    3.	The restore phase is analogous to the resume phase.
 
-    3.	The complete phase is discussed above.
+    4.	The complete phase is discussed above.
 
-The main difference from resume[_noirq] is that restore[_noirq] must assume the
-device has been accessed and reconfigured by the boot loader or the boot kernel.
-Consequently the state of the device may be different from the state remembered
-from the freeze and freeze_noirq phases.  The device may even need to be reset
-and completely re-initialized.  In many cases this difference doesn't matter, so
-the resume[_noirq] and restore[_norq] method pointers can be set to the same
-routines.  Nevertheless, different callback pointers are used in case there is a
-situation where it actually matters.
+The main difference from resume[_early|_noirq] is that restore[_early|_noirq]
+must assume the device has been accessed and reconfigured by the boot loader or
+the boot kernel.  Consequently the state of the device may be different from the
+state remembered from the freeze, freeze_late and freeze_noirq phases.  The
+device may even need to be reset and completely re-initialized.  In many cases
+this difference doesn't matter, so the resume[_early|_noirq] and
+restore[_early|_norq] method pointers can be set to the same routines.
+Nevertheless, different callback pointers are used in case there is a situation
+where it actually does matter.
 
 
 Device Power Management Domains
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt
index ebd7490..ec715cd 100644
--- a/Documentation/power/freezing-of-tasks.txt
+++ b/Documentation/power/freezing-of-tasks.txt
@@ -63,6 +63,27 @@ devices have been reinitialized, the function thaw_processes() is called in
 order to clear the PF_FROZEN flag for each frozen task.  Then, the tasks that
 have been frozen leave __refrigerator() and continue running.
 
+
+Rationale behind the functions dealing with freezing and thawing of tasks:
+-------------------------------------------------------------------------
+
+freeze_processes():
+  - freezes only userspace tasks
+
+freeze_kernel_threads():
+  - freezes all tasks (including kernel threads) because we can't freeze
+    kernel threads without freezing userspace tasks
+
+thaw_kernel_threads():
+  - thaws only kernel threads; this is particularly useful if we need to do
+    anything special in between thawing of kernel threads and thawing of
+    userspace tasks, or if we want to postpone the thawing of userspace tasks
+
+thaw_processes():
+  - thaws all tasks (including kernel threads) because we can't thaw userspace
+    tasks without thawing kernel threads
+
+
 III. Which kernel threads are freezable?
 
 Kernel threads are not freezable by default.  However, a kernel thread may clear
diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
index 8fb1ba7..a0b9d8e 100644
--- a/Documentation/ramoops.txt
+++ b/Documentation/ramoops.txt
@@ -3,7 +3,7 @@ Ramoops oops/panic logger
 
 Sergiu Iordache <sergiu@chromium.org>
 
-Updated: 8 August 2011
+Updated: 17 November 2011
 
 0. Introduction
 
@@ -71,6 +71,6 @@ timestamp and a new line. The dump then continues with the actual data.
 
 4. Reading the data
 
-The dump data can be read from memory (through /dev/mem or other means).
-Getting the module parameters, which are needed in order to parse the data, can
-be done through /sys/module/ramoops/parameters/* .
+The dump data can be read from the pstore filesystem. The format for these
+files is "dmesg-ramoops-N", where N is the record number in memory. To delete
+a stored record from RAM, simply unlink the respective pstore file.
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt
new file mode 100644
index 0000000..23ff734
--- /dev/null
+++ b/Documentation/remoteproc.txt
@@ -0,0 +1,324 @@
+Remote Processor Framework
+
+1. Introduction
+
+Modern SoCs typically have heterogeneous remote processor devices in asymmetric
+multiprocessing (AMP) configurations, which may be running different instances
+of operating system, whether it's Linux or any other flavor of real-time OS.
+
+OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP.
+In a typical configuration, the dual cortex-A9 is running Linux in a SMP
+configuration, and each of the other three cores (two M3 cores and a DSP)
+is running its own instance of RTOS in an AMP configuration.
+
+The remoteproc framework allows different platforms/architectures to
+control (power on, load firmware, power off) those remote processors while
+abstracting the hardware differences, so the entire driver doesn't need to be
+duplicated. In addition, this framework also adds rpmsg virtio devices
+for remote processors that supports this kind of communication. This way,
+platform-specific remoteproc drivers only need to provide a few low-level
+handlers, and then all rpmsg drivers will then just work
+(for more information about the virtio-based rpmsg bus and its drivers,
+please read Documentation/rpmsg.txt).
+
+2. User API
+
+  int rproc_boot(struct rproc *rproc)
+    - Boot a remote processor (i.e. load its firmware, power it on, ...).
+      If the remote processor is already powered on, this function immediately
+      returns (successfully).
+      Returns 0 on success, and an appropriate error value otherwise.
+      Note: to use this function you should already have a valid rproc
+      handle. There are several ways to achieve that cleanly (devres, pdata,
+      the way remoteproc_rpmsg.c does this, or, if this becomes prevalent, we
+      might also consider using dev_archdata for this). See also
+      rproc_get_by_name() below.
+
+  void rproc_shutdown(struct rproc *rproc)
+    - Power off a remote processor (previously booted with rproc_boot()).
+      In case @rproc is still being used by an additional user(s), then
+      this function will just decrement the power refcount and exit,
+      without really powering off the device.
+      Every call to rproc_boot() must (eventually) be accompanied by a call
+      to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug.
+      Notes:
+      - we're not decrementing the rproc's refcount, only the power refcount.
+        which means that the @rproc handle stays valid even after
+        rproc_shutdown() returns, and users can still use it with a subsequent
+        rproc_boot(), if needed.
+      - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly
+        because rproc_shutdown() _does not_ decrement the refcount of @rproc.
+        To decrement the refcount of @rproc, use rproc_put() (but _only_ if
+        you acquired @rproc using rproc_get_by_name()).
+
+  struct rproc *rproc_get_by_name(const char *name)
+    - Find an rproc handle using the remote processor's name, and then
+      boot it. If it's already powered on, then just immediately return
+      (successfully). Returns the rproc handle on success, and NULL on failure.
+      This function increments the remote processor's refcount, so always
+      use rproc_put() to decrement it back once rproc isn't needed anymore.
+      Note: currently rproc_get_by_name() and rproc_put() are not used anymore
+      by the rpmsg bus and its drivers. We need to scrutinize the use cases
+      that still need them, and see if we can migrate them to use the non
+      name-based boot/shutdown interface.
+
+  void rproc_put(struct rproc *rproc)
+    - Decrement @rproc's power refcount and shut it down if it reaches zero
+      (essentially by just calling rproc_shutdown), and then decrement @rproc's
+      validity refcount too.
+      After this function returns, @rproc may _not_ be used anymore, and its
+      handle should be considered invalid.
+      This function should be called _iff_ the @rproc handle was grabbed by
+      calling rproc_get_by_name().
+
+3. Typical usage
+
+#include <linux/remoteproc.h>
+
+/* in case we were given a valid 'rproc' handle */
+int dummy_rproc_example(struct rproc *my_rproc)
+{
+	int ret;
+
+	/* let's power on and boot our remote processor */
+	ret = rproc_boot(my_rproc);
+	if (ret) {
+		/*
+		 * something went wrong. handle it and leave.
+		 */
+	}
+
+	/*
+	 * our remote processor is now powered on... give it some work
+	 */
+
+	/* let's shut it down now */
+	rproc_shutdown(my_rproc);
+}
+
+4. API for implementors
+
+  struct rproc *rproc_alloc(struct device *dev, const char *name,
+				const struct rproc_ops *ops,
+				const char *firmware, int len)
+    - Allocate a new remote processor handle, but don't register
+      it yet. Required parameters are the underlying device, the
+      name of this remote processor, platform-specific ops handlers,
+      the name of the firmware to boot this rproc with, and the
+      length of private data needed by the allocating rproc driver (in bytes).
+
+      This function should be used by rproc implementations during
+      initialization of the remote processor.
+      After creating an rproc handle using this function, and when ready,
+      implementations should then call rproc_register() to complete
+      the registration of the remote processor.
+      On success, the new rproc is returned, and on failure, NULL.
+
+      Note: _never_ directly deallocate @rproc, even if it was not registered
+      yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free().
+
+  void rproc_free(struct rproc *rproc)
+    - Free an rproc handle that was allocated by rproc_alloc.
+      This function should _only_ be used if @rproc was only allocated,
+      but not registered yet.
+      If @rproc was already successfully registered (by calling
+      rproc_register()), then use rproc_unregister() instead.
+
+  int rproc_register(struct rproc *rproc)
+    - Register @rproc with the remoteproc framework, after it has been
+      allocated with rproc_alloc().
+      This is called by the platform-specific rproc implementation, whenever
+      a new remote processor device is probed.
+      Returns 0 on success and an appropriate error code otherwise.
+      Note: this function initiates an asynchronous firmware loading
+      context, which will look for virtio devices supported by the rproc's
+      firmware.
+      If found, those virtio devices will be created and added, so as a result
+      of registering this remote processor, additional virtio drivers might get
+      probed.
+      Currently, though, we only support a single RPMSG virtio vdev per remote
+      processor.
+
+  int rproc_unregister(struct rproc *rproc)
+    - Unregister a remote processor, and decrement its refcount.
+      If its refcount drops to zero, then @rproc will be freed. If not,
+      it will be freed later once the last reference is dropped.
+
+      This function should be called when the platform specific rproc
+      implementation decides to remove the rproc device. it should
+      _only_ be called if a previous invocation of rproc_register()
+      has completed successfully.
+
+      After rproc_unregister() returns, @rproc is _not_ valid anymore and
+      it shouldn't be used. More specifically, don't call rproc_free()
+      or try to directly free @rproc after rproc_unregister() returns;
+      none of these are needed, and calling them is a bug.
+
+      Returns 0 on success and -EINVAL if @rproc isn't valid.
+
+5. Implementation callbacks
+
+These callbacks should be provided by platform-specific remoteproc
+drivers:
+
+/**
+ * struct rproc_ops - platform-specific device handlers
+ * @start:	power on the device and boot it
+ * @stop:	power off the device
+ * @kick:	kick a virtqueue (virtqueue id given as a parameter)
+ */
+struct rproc_ops {
+	int (*start)(struct rproc *rproc);
+	int (*stop)(struct rproc *rproc);
+	void (*kick)(struct rproc *rproc, int vqid);
+};
+
+Every remoteproc implementation should at least provide the ->start and ->stop
+handlers. If rpmsg functionality is also desired, then the ->kick handler
+should be provided as well.
+
+The ->start() handler takes an rproc handle and should then power on the
+device and boot it (use rproc->priv to access platform-specific private data).
+The boot address, in case needed, can be found in rproc->bootaddr (remoteproc
+core puts there the ELF entry point).
+On success, 0 should be returned, and on failure, an appropriate error code.
+
+The ->stop() handler takes an rproc handle and powers the device down.
+On success, 0 is returned, and on failure, an appropriate error code.
+
+The ->kick() handler takes an rproc handle, and an index of a virtqueue
+where new message was placed in. Implementations should interrupt the remote
+processor and let it know it has pending messages. Notifying remote processors
+the exact virtqueue index to look in is optional: it is easy (and not
+too expensive) to go through the existing virtqueues and look for new buffers
+in the used rings.
+
+6. Binary Firmware Structure
+
+At this point remoteproc only supports ELF32 firmware binaries. However,
+it is quite expected that other platforms/devices which we'd want to
+support with this framework will be based on different binary formats.
+
+When those use cases show up, we will have to decouple the binary format
+from the framework core, so we can support several binary formats without
+duplicating common code.
+
+When the firmware is parsed, its various segments are loaded to memory
+according to the specified device address (might be a physical address
+if the remote processor is accessing memory directly).
+
+In addition to the standard ELF segments, most remote processors would
+also include a special section which we call "the resource table".
+
+The resource table contains system resources that the remote processor
+requires before it should be powered on, such as allocation of physically
+contiguous memory, or iommu mapping of certain on-chip peripherals.
+Remotecore will only power up the device after all the resource table's
+requirement are met.
+
+In addition to system resources, the resource table may also contain
+resource entries that publish the existence of supported features
+or configurations by the remote processor, such as trace buffers and
+supported virtio devices (and their configurations).
+
+Currently the resource table is just an array of:
+
+/**
+ * struct fw_resource - describes an entry from the resource section
+ * @type: resource type
+ * @id: index number of the resource
+ * @da: device address of the resource
+ * @pa: physical address of the resource
+ * @len: size, in bytes, of the resource
+ * @flags: properties of the resource, e.g. iommu protection required
+ * @reserved: must be 0 atm
+ * @name: name of resource
+ */
+struct fw_resource {
+	u32 type;
+	u32 id;
+	u64 da;
+	u64 pa;
+	u32 len;
+	u32 flags;
+	u8 reserved[16];
+	u8 name[48];
+} __packed;
+
+Some resources entries are mere announcements, where the host is informed
+of specific remoteproc configuration. Other entries require the host to
+do something (e.g. reserve a requested resource) and possibly also reply
+by overwriting a member inside 'struct fw_resource' with info about the
+allocated resource.
+
+Different resource entries use different members of this struct,
+with different meanings. This is pretty limiting and error-prone,
+so the plan is to move to variable-length TLV-based resource entries,
+where each resource will begin with a type and length fields, followed by
+its own specific structure.
+
+Here are the resource types that are currently being used:
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT:   request for allocation of a physically contiguous
+ *		    memory region.
+ * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE:	    announces the availability of a trace buffer into which
+ *		    the remote processor will be writing logs. In this case,
+ *		    'da' indicates the device address where logs are written to,
+ *		    and 'len' is the size of the trace buffer.
+ * @RSC_VRING:	    request for allocation of a virtio vring (address should
+ *		    be indicated in 'da', and 'len' should contain the number
+ *		    of buffers supported by the vring).
+ * @RSC_VIRTIO_DEV: announces support for a virtio device, and serves as
+ *		    the virtio header. 'da' contains the virtio device
+ *		    features, 'pa' holds the virtio guest features (host
+ *		    will write them here after they're negotiated), 'len'
+ *		    holds the virtio status, and 'flags' holds the virtio
+ *		    device id (currently only VIRTIO_ID_RPMSG is supported).
+ */
+enum fw_resource_type {
+	RSC_CARVEOUT	= 0,
+	RSC_DEVMEM	= 1,
+	RSC_TRACE	= 2,
+	RSC_VRING	= 3,
+	RSC_VIRTIO_DEV	= 4,
+	RSC_VIRTIO_CFG	= 5,
+};
+
+Most of the resource entries share the basic idea of address/length
+negotiation with the host: the firmware usually asks for memory
+of size 'len' bytes, and the host needs to allocate it and provide
+the device/physical address (when relevant) in 'da'/'pa' respectively.
+
+If the firmware is compiled with hard coded device addresses, and
+can't handle dynamically allocated 'da' values, then the 'da' field
+will contain the expected device addresses (today we actually only support
+this scheme, as there aren't yet any use cases for dynamically allocated
+device addresses).
+
+We also expect that platform-specific resource entries will show up
+at some point. When that happens, we could easily add a new RSC_PLAFORM
+type, and hand those resources to the platform-specific rproc driver to handle.
+
+7. Virtio and remoteproc
+
+The firmware should provide remoteproc information about virtio devices
+that it supports, and their configurations: a RSC_VIRTIO_DEV resource entry
+should specify the virtio device id, and subsequent RSC_VRING resource entries
+should indicate the vring size (i.e. how many buffers do they support) and
+where should they be mapped (i.e. which device address). Note: the alignment
+between the consumer and producer parts of the vring is assumed to be 4096.
+
+At this point we only support a single virtio rpmsg device per remote
+processor, but the plan is to remove this limitation. In addition, once we
+move to TLV-based resource table, the plan is to have a single RSC_VIRTIO
+entry per supported virtio device, which will include the virtio header,
+the vrings information and the virtio config space.
+
+Of course, RSC_VIRTIO resource entries are only good enough for static
+allocation of virtio devices. Dynamic allocations will also be made possible
+using the rpmsg bus (similar to how we already do dynamic allocations of
+rpmsg channels; read more about it in rpmsg.txt).
diff --git a/Documentation/rpmsg.txt b/Documentation/rpmsg.txt
new file mode 100644
index 0000000..409d9f9
--- /dev/null
+++ b/Documentation/rpmsg.txt
@@ -0,0 +1,293 @@
+Remote Processor Messaging (rpmsg) Framework
+
+Note: this document describes the rpmsg bus and how to write rpmsg drivers.
+To learn how to add rpmsg support for new platforms, check out remoteproc.txt
+(also a resident of Documentation/).
+
+1. Introduction
+
+Modern SoCs typically employ heterogeneous remote processor devices in
+asymmetric multiprocessing (AMP) configurations, which may be running
+different instances of operating system, whether it's Linux or any other
+flavor of real-time OS.
+
+OMAP4, for example, has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP.
+Typically, the dual cortex-A9 is running Linux in a SMP configuration,
+and each of the other three cores (two M3 cores and a DSP) is running
+its own instance of RTOS in an AMP configuration.
+
+Typically AMP remote processors employ dedicated DSP codecs and multimedia
+hardware accelerators, and therefore are often used to offload CPU-intensive
+multimedia tasks from the main application processor.
+
+These remote processors could also be used to control latency-sensitive
+sensors, drive random hardware blocks, or just perform background tasks
+while the main CPU is idling.
+
+Users of those remote processors can either be userland apps (e.g. multimedia
+frameworks talking with remote OMX components) or kernel drivers (controlling
+hardware accessible only by the remote processor, reserving kernel-controlled
+resources on behalf of the remote processor, etc..).
+
+Rpmsg is a virtio-based messaging bus that allows kernel drivers to communicate
+with remote processors available on the system. In turn, drivers could then
+expose appropriate user space interfaces, if needed.
+
+When writing a driver that exposes rpmsg communication to userland, please
+keep in mind that remote processors might have direct access to the
+system's physical memory and other sensitive hardware resources (e.g. on
+OMAP4, remote cores and hardware accelerators may have direct access to the
+physical memory, gpio banks, dma controllers, i2c bus, gptimers, mailbox
+devices, hwspinlocks, etc..). Moreover, those remote processors might be
+running RTOS where every task can access the entire memory/devices exposed
+to the processor. To minimize the risks of rogue (or buggy) userland code
+exploiting remote bugs, and by that taking over the system, it is often
+desired to limit userland to specific rpmsg channels (see definition below)
+it can send messages on, and if possible, minimize how much control
+it has over the content of the messages.
+
+Every rpmsg device is a communication channel with a remote processor (thus
+rpmsg devices are called channels). Channels are identified by a textual name
+and have a local ("source") rpmsg address, and remote ("destination") rpmsg
+address.
+
+When a driver starts listening on a channel, its rx callback is bound with
+a unique rpmsg local address (a 32-bit integer). This way when inbound messages
+arrive, the rpmsg core dispatches them to the appropriate driver according
+to their destination address (this is done by invoking the driver's rx handler
+with the payload of the inbound message).
+
+
+2. User API
+
+  int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len);
+   - sends a message across to the remote processor on a given channel.
+     The caller should specify the channel, the data it wants to send,
+     and its length (in bytes). The message will be sent on the specified
+     channel, i.e. its source and destination address fields will be
+     set to the channel's src and dst addresses.
+
+     In case there are no TX buffers available, the function will block until
+     one becomes available (i.e. until the remote processor consumes
+     a tx buffer and puts it back on virtio's used descriptor ring),
+     or a timeout of 15 seconds elapses. When the latter happens,
+     -ERESTARTSYS is returned.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst);
+   - sends a message across to the remote processor on a given channel,
+     to a destination address provided by the caller.
+     The caller should specify the channel, the data it wants to send,
+     its length (in bytes), and an explicit destination address.
+     The message will then be sent to the remote processor to which the
+     channel belongs, using the channel's src address, and the user-provided
+     dst address (thus the channel's dst address will be ignored).
+
+     In case there are no TX buffers available, the function will block until
+     one becomes available (i.e. until the remote processor consumes
+     a tx buffer and puts it back on virtio's used descriptor ring),
+     or a timeout of 15 seconds elapses. When the latter happens,
+     -ERESTARTSYS is returned.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+							void *data, int len);
+   - sends a message across to the remote processor, using the src and dst
+     addresses provided by the user.
+     The caller should specify the channel, the data it wants to send,
+     its length (in bytes), and explicit source and destination addresses.
+     The message will then be sent to the remote processor to which the
+     channel belongs, but the channel's src and dst addresses will be
+     ignored (and the user-provided addresses will be used instead).
+
+     In case there are no TX buffers available, the function will block until
+     one becomes available (i.e. until the remote processor consumes
+     a tx buffer and puts it back on virtio's used descriptor ring),
+     or a timeout of 15 seconds elapses. When the latter happens,
+     -ERESTARTSYS is returned.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len);
+   - sends a message across to the remote processor on a given channel.
+     The caller should specify the channel, the data it wants to send,
+     and its length (in bytes). The message will be sent on the specified
+     channel, i.e. its source and destination address fields will be
+     set to the channel's src and dst addresses.
+
+     In case there are no TX buffers available, the function will immediately
+     return -ENOMEM without waiting until one becomes available.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
+   - sends a message across to the remote processor on a given channel,
+     to a destination address provided by the user.
+     The user should specify the channel, the data it wants to send,
+     its length (in bytes), and an explicit destination address.
+     The message will then be sent to the remote processor to which the
+     channel belongs, using the channel's src address, and the user-provided
+     dst address (thus the channel's dst address will be ignored).
+
+     In case there are no TX buffers available, the function will immediately
+     return -ENOMEM without waiting until one becomes available.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+							void *data, int len);
+   - sends a message across to the remote processor, using source and
+     destination addresses provided by the user.
+     The user should specify the channel, the data it wants to send,
+     its length (in bytes), and explicit source and destination addresses.
+     The message will then be sent to the remote processor to which the
+     channel belongs, but the channel's src and dst addresses will be
+     ignored (and the user-provided addresses will be used instead).
+
+     In case there are no TX buffers available, the function will immediately
+     return -ENOMEM without waiting until one becomes available.
+     The function can only be called from a process context (for now).
+     Returns 0 on success and an appropriate error value on failure.
+
+  struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev,
+		void (*cb)(struct rpmsg_channel *, void *, int, void *, u32),
+		void *priv, u32 addr);
+   - every rpmsg address in the system is bound to an rx callback (so when
+     inbound messages arrive, they are dispatched by the rpmsg bus using the
+     appropriate callback handler) by means of an rpmsg_endpoint struct.
+
+     This function allows drivers to create such an endpoint, and by that,
+     bind a callback, and possibly some private data too, to an rpmsg address
+     (either one that is known in advance, or one that will be dynamically
+     assigned for them).
+
+     Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
+     is already created for them when they are probed by the rpmsg bus
+     (using the rx callback they provide when they registered to the rpmsg bus).
+
+     So things should just work for simple drivers: they already have an
+     endpoint, their rx callback is bound to their rpmsg address, and when
+     relevant inbound messages arrive (i.e. messages which their dst address
+     equals to the src address of their rpmsg channel), the driver's handler
+     is invoked to process it.
+
+     That said, more complicated drivers might do need to allocate
+     additional rpmsg addresses, and bind them to different rx callbacks.
+     To accomplish that, those drivers need to call this function.
+     Drivers should provide their channel (so the new endpoint would bind
+     to the same remote processor their channel belongs to), an rx callback
+     function, an optional private data (which is provided back when the
+     rx callback is invoked), and an address they want to bind with the
+     callback. If addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
+     dynamically assign them an available rpmsg address (drivers should have
+     a very good reason why not to always use RPMSG_ADDR_ANY here).
+
+     Returns a pointer to the endpoint on success, or NULL on error.
+
+  void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
+   - destroys an existing rpmsg endpoint. user should provide a pointer
+     to an rpmsg endpoint that was previously created with rpmsg_create_ept().
+
+  int register_rpmsg_driver(struct rpmsg_driver *rpdrv);
+   - registers an rpmsg driver with the rpmsg bus. user should provide
+     a pointer to an rpmsg_driver struct, which contains the driver's
+     ->probe() and ->remove() functions, an rx callback, and an id_table
+     specifying the names of the channels this driver is interested to
+     be probed with.
+
+  void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv);
+   - unregisters an rpmsg driver from the rpmsg bus. user should provide
+     a pointer to a previously-registered rpmsg_driver struct.
+     Returns 0 on success, and an appropriate error value on failure.
+
+
+3. Typical usage
+
+The following is a simple rpmsg driver, that sends an "hello!" message
+on probe(), and whenever it receives an incoming message, it dumps its
+content to the console.
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+
+static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
+						void *priv, u32 src)
+{
+	print_hex_dump(KERN_INFO, "incoming message:", DUMP_PREFIX_NONE,
+						16, 1, data, len, true);
+}
+
+static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
+{
+	int err;
+
+	dev_info(&rpdev->dev, "chnl: 0x%x -> 0x%x\n", rpdev->src, rpdev->dst);
+
+	/* send a message on our channel */
+	err = rpmsg_send(rpdev, "hello!", 6);
+	if (err) {
+		pr_err("rpmsg_send failed: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev)
+{
+	dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+	{ .name	= "rpmsg-client-sample" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_client = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.owner	= THIS_MODULE,
+	.id_table	= rpmsg_driver_sample_id_table,
+	.probe		= rpmsg_sample_probe,
+	.callback	= rpmsg_sample_cb,
+	.remove		= __devexit_p(rpmsg_sample_remove),
+};
+
+static int __init init(void)
+{
+	return register_rpmsg_driver(&rpmsg_sample_client);
+}
+module_init(init);
+
+static void __exit fini(void)
+{
+	unregister_rpmsg_driver(&rpmsg_sample_client);
+}
+module_exit(fini);
+
+Note: a similar sample which can be built and loaded can be found
+in samples/rpmsg/.
+
+4. Allocations of rpmsg channels:
+
+At this point we only support dynamic allocations of rpmsg channels.
+
+This is possible only with remote processors that have the VIRTIO_RPMSG_F_NS
+virtio device feature set. This feature bit means that the remote
+processor supports dynamic name service announcement messages.
+
+When this feature is enabled, creation of rpmsg devices (i.e. channels)
+is completely dynamic: the remote processor announces the existence of a
+remote rpmsg service by sending a name service message (which contains
+the name and rpmsg addr of the remote service, see struct rpmsg_ns_msg).
+
+This message is then handled by the rpmsg bus, which in turn dynamically
+creates and registers an rpmsg channel (which represents the remote service).
+If/when a relevant rpmsg driver is registered, it will be immediately probed
+by the bus, and can then start sending messages to the remote service.
+
+The plan is also to add static creation of rpmsg channels via the virtio
+config space, but it's not implemented yet.
diff --git a/Documentation/scheduler/sched-stats.txt b/Documentation/scheduler/sched-stats.txt
index 1cd5d51..8259b34 100644
--- a/Documentation/scheduler/sched-stats.txt
+++ b/Documentation/scheduler/sched-stats.txt
@@ -38,7 +38,8 @@ First field is a sched_yield() statistic:
      1) # of times sched_yield() was called
 
 Next three are schedule() statistics:
-     2) # of times we switched to the expired queue and reused it
+     2) This field is a legacy array expiration count field used in the O(1)
+	scheduler. We kept it for ABI compatibility, but it is always set to zero.
      3) # of times schedule() was called
      4) # of times schedule() left the processor idle
 
diff --git a/Documentation/scsi/LICENSE.qla2xxx b/Documentation/scsi/LICENSE.qla2xxx
index 19e7cd4..ce0fdf3 100644
--- a/Documentation/scsi/LICENSE.qla2xxx
+++ b/Documentation/scsi/LICENSE.qla2xxx
@@ -1,48 +1,11 @@
 Copyright (c) 2003-2011 QLogic Corporation
-QLogic Linux/ESX Fibre Channel HBA Driver
+QLogic Linux FC-FCoE Driver
 
-This program includes a device driver for Linux 2.6/ESX that may be
-distributed with QLogic hardware specific firmware binary file.
+This program includes a device driver for Linux 3.x.
 You may modify and redistribute the device driver code under the
 GNU General Public License (a copy of which is attached hereto as
 Exhibit A) published by the Free Software Foundation (version 2).
 
-You may redistribute the hardware specific firmware binary file
-under the following terms:
-
-	1. Redistribution of source code (only if applicable),
-	   must retain the above copyright notice, this list of
-	   conditions and the following disclaimer.
-
-	2. Redistribution in binary form must reproduce the above
-	   copyright notice, this list of conditions and the
-	   following disclaimer in the documentation and/or other
-	   materials provided with the distribution.
-
-	3. The name of QLogic Corporation may not be used to
-	   endorse or promote products derived from this software
-	   without specific prior written permission
-
-REGARDLESS OF WHAT LICENSING MECHANISM IS USED OR APPLICABLE,
-THIS PROGRAM IS PROVIDED BY QLOGIC CORPORATION "AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-USER ACKNOWLEDGES AND AGREES THAT USE OF THIS PROGRAM WILL NOT
-CREATE OR GIVE GROUNDS FOR A LICENSE BY IMPLICATION, ESTOPPEL, OR
-OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS (PATENT, COPYRIGHT,
-TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
-ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
-COMBINATION WITH THIS PROGRAM.
 
 
 EXHIBIT A
diff --git a/Documentation/scsi/bfa.txt b/Documentation/scsi/bfa.txt
new file mode 100644
index 0000000..f2d6e9d
--- /dev/null
+++ b/Documentation/scsi/bfa.txt
@@ -0,0 +1,82 @@
+Linux driver for Brocade FC/FCOE adapters
+
+
+Supported Hardware
+------------------
+
+bfa 3.0.2.2 driver supports all Brocade FC/FCOE adapters. Below is a list of
+adapter models with corresponding PCIIDs.
+
+	PCIID		  	Model
+
+	1657:0013:1657:0014	425 4Gbps dual port FC HBA
+	1657:0013:1657:0014	825 8Gbps PCIe dual port FC HBA
+	1657:0013:103c:1742	HP 82B 8Gbps PCIedual port FC HBA
+	1657:0013:103c:1744	HP 42B 4Gbps dual port FC HBA
+	1657:0017:1657:0014	415 4Gbps single port FC HBA
+	1657:0017:1657:0014	815 8Gbps single port FC HBA
+	1657:0017:103c:1741	HP 41B 4Gbps single port FC HBA
+	1657:0017:103c 1743	HP 81B 8Gbps single port FC HBA
+	1657:0021:103c:1779	804 8Gbps FC HBA for HP Bladesystem c-class
+
+	1657:0014:1657:0014	1010 10Gbps single port CNA - FCOE
+	1657:0014:1657:0014	1020 10Gbps dual port CNA - FCOE
+	1657:0014:1657:0014	1007 10Gbps dual port CNA - FCOE
+	1657:0014:1657:0014	1741 10Gbps dual port CNA - FCOE
+
+	1657:0022:1657:0024	1860 16Gbps FC HBA
+	1657:0022:1657:0022	1860 10Gbps CNA - FCOE
+
+
+Firmware download
+-----------------
+
+The latest Firmware package for 3.0.2.2 bfa driver can be found at:
+
+http://www.brocade.com/services-support/drivers-downloads/adapters/Linux.page
+
+and then click following respective util package link:
+
+	Version			Link
+
+	v3.0.0.0	Linux Adapter Firmware package for RHEL 6.2, SLES 11SP2
+
+
+Configuration & Management utility download
+-------------------------------------------
+
+The latest driver configuration & management utility for 3.0.2.2 bfa driver can
+be found at:
+
+http://www.brocade.com/services-support/drivers-downloads/adapters/Linux.page
+
+and then click following respective util pacakge link
+
+	Version			Link
+
+	v3.0.2.0	Linux Adapter Firmware package for RHEL 6.2, SLES 11SP2
+
+
+Documentation
+-------------
+
+The latest Administration's Guide, Installation and Reference Manual,
+Troubleshooting Guide, and Release Notes for the corresponding out-of-box
+driver can be found at:
+
+http://www.brocade.com/services-support/drivers-downloads/adapters/Linux.page
+
+and use the following inbox and out-of-box driver version mapping to find
+the corresponding documentation:
+
+	Inbox Version		Out-of-box Version
+
+	v3.0.2.2		v3.0.0.0
+
+
+Support
+-------
+
+For general product and support info, go to the Brocade website at:
+
+http://www.brocade.com/services-support/index.page
diff --git a/Documentation/scsi/libsas.txt b/Documentation/scsi/libsas.txt
index aa54f54..3cc9c78 100644
--- a/Documentation/scsi/libsas.txt
+++ b/Documentation/scsi/libsas.txt
@@ -398,21 +398,6 @@ struct sas_task {
 	task_done -- callback when the task has finished execution
 };
 
-When an external entity, entity other than the LLDD or the
-SAS Layer, wants to work with a struct domain_device, it
-_must_ call kobject_get() when getting a handle on the
-device and kobject_put() when it is done with the device.
-
-This does two things:
-     A) implements proper kfree() for the device;
-     B) increments/decrements the kref for all players:
-     domain_device
-	all domain_device's ... (if past an expander)
-	    port
-		host adapter
-		     pci device
-			 and up the ladder, etc.
-
 DISCOVERY
 ---------
 
diff --git a/Documentation/scsi/scsi-generic.txt b/Documentation/scsi/scsi-generic.txt
index 0a22ab8..51be20a 100644
--- a/Documentation/scsi/scsi-generic.txt
+++ b/Documentation/scsi/scsi-generic.txt
@@ -62,7 +62,7 @@ There are two packages of sg utilities:
                 and earlier
 Both packages will work in the lk 2.4 series however sg3_utils offers more
 capabilities. They can be found at: http://sg.danny.cz/sg/sg3_utils.html and 
-freshmeat.net
+freecode.com
 
 Another approach is to look at the applications that use the sg driver.
 These include cdrecord, cdparanoia, SANE and cdrdao.
diff --git a/Documentation/security/00-INDEX b/Documentation/security/00-INDEX
index 99b85d3..eeed1de 100644
--- a/Documentation/security/00-INDEX
+++ b/Documentation/security/00-INDEX
@@ -6,6 +6,8 @@ SELinux.txt
 	- how to get started with the SELinux security enhancement.
 Smack.txt
 	- documentation on the Smack Linux Security Module.
+Yama.txt
+	- documentation on the Yama Linux Security Module.
 apparmor.txt
 	- documentation on the AppArmor security extension.
 credentials.txt
diff --git a/Documentation/security/Yama.txt b/Documentation/security/Yama.txt
new file mode 100644
index 0000000..a9511f1
--- /dev/null
+++ b/Documentation/security/Yama.txt
@@ -0,0 +1,65 @@
+Yama is a Linux Security Module that collects a number of system-wide DAC
+security protections that are not handled by the core kernel itself. To
+select it at boot time, specify "security=yama" (though this will disable
+any other LSM).
+
+Yama is controlled through sysctl in /proc/sys/kernel/yama:
+
+- ptrace_scope
+
+==============================================================
+
+ptrace_scope:
+
+As Linux grows in popularity, it will become a larger target for
+malware. One particularly troubling weakness of the Linux process
+interfaces is that a single user is able to examine the memory and
+running state of any of their processes. For example, if one application
+(e.g. Pidgin) was compromised, it would be possible for an attacker to
+attach to other running processes (e.g. Firefox, SSH sessions, GPG agent,
+etc) to extract additional credentials and continue to expand the scope
+of their attack without resorting to user-assisted phishing.
+
+This is not a theoretical problem. SSH session hijacking
+(http://www.storm.net.nz/projects/7) and arbitrary code injection
+(http://c-skills.blogspot.com/2007/05/injectso.html) attacks already
+exist and remain possible if ptrace is allowed to operate as before.
+Since ptrace is not commonly used by non-developers and non-admins, system
+builders should be allowed the option to disable this debugging system.
+
+For a solution, some applications use prctl(PR_SET_DUMPABLE, ...) to
+specifically disallow such ptrace attachment (e.g. ssh-agent), but many
+do not. A more general solution is to only allow ptrace directly from a
+parent to a child process (i.e. direct "gdb EXE" and "strace EXE" still
+work), or with CAP_SYS_PTRACE (i.e. "gdb --pid=PID", and "strace -p PID"
+still work as root).
+
+For software that has defined application-specific relationships
+between a debugging process and its inferior (crash handlers, etc),
+prctl(PR_SET_PTRACER, pid, ...) can be used. An inferior can declare which
+other process (and its descendents) are allowed to call PTRACE_ATTACH
+against it. Only one such declared debugging process can exists for
+each inferior at a time. For example, this is used by KDE, Chromium, and
+Firefox's crash handlers, and by Wine for allowing only Wine processes
+to ptrace each other. If a process wishes to entirely disable these ptrace
+restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...)
+so that any otherwise allowed process (even those in external pid namespaces)
+may attach.
+
+The sysctl settings are:
+
+0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other
+    process running under the same uid, as long as it is dumpable (i.e.
+    did not transition uids, start privileged, or have called
+    prctl(PR_SET_DUMPABLE...) already).
+
+1 - restricted ptrace: a process must have a predefined relationship
+    with the inferior it wants to call PTRACE_ATTACH on. By default,
+    this relationship is that of only its descendants when the above
+    classic criteria is also met. To change the relationship, an
+    inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare
+    an allowed debugger PID to call PTRACE_ATTACH on the inferior.
+
+The original children-only logic was based on the restrictions in grsecurity.
+
+==============================================================
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 4d75931..713ec23 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -554,6 +554,10 @@ The keyctl syscall functions are:
      process must have write permission on the keyring, and it must be a
      keyring (or else error ENOTDIR will result).
 
+     This function can also be used to clear special kernel keyrings if they
+     are appropriately marked if the user has CAP_SYS_ADMIN capability.  The
+     DNS resolver cache keyring is an example of this.
+
 
  (*) Link a key into a keyring:
 
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index c8c5454..d97d992 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -8,37 +8,10 @@ ALC880
   5stack-digout	5-jack in back, 2-jack in front, a SPDIF out
   6stack	6-jack in back, 2-jack in front
   6stack-digout	6-jack with a SPDIF out
-  w810		3-jack
-  z71v		3-jack (HP shared SPDIF)
-  asus		3-jack (ASUS Mobo)
-  asus-w1v	ASUS W1V
-  asus-dig	ASUS with SPDIF out
-  asus-dig2	ASUS with SPDIF out (using GPIO2)
-  uniwill	3-jack
-  fujitsu	Fujitsu Laptops (Pi1536)
-  F1734		2-jack
-  lg		LG laptop (m1 express dual)
-  lg-lw		LG LW20/LW25 laptop
-  tcl		TCL S700
-  clevo		Clevo laptops (m520G, m665n)
-  medion	Medion Rim 2150
-  test		for testing/debugging purpose, almost all controls can be
-		adjusted.  Appearing only when compiled with
-		$CONFIG_SND_DEBUG=y
-  auto		auto-config reading BIOS (default)
 
 ALC260
 ======
-  fujitsu	Fujitsu S7020
-  acer		Acer TravelMate
-  will		Will laptops (PB V7900)
-  replacer	Replacer 672V
-  favorit100	Maxdata Favorit 100XS
-  basic		fixed pin assignment (old default model)
-  test		for testing/debugging purpose, almost all controls can
-		adjusted.  Appearing only when compiled with
-		$CONFIG_SND_DEBUG=y
-  auto		auto-config reading BIOS (default)
+  N/A
 
 ALC262
 ======
@@ -70,55 +43,7 @@ ALC680
 
 ALC882/883/885/888/889
 ======================
-  3stack-dig	3-jack with SPDIF I/O
-  6stack-dig	6-jack digital with SPDIF I/O
-  arima		Arima W820Di1
-  targa		Targa T8, MSI-1049 T8
-  asus-a7j	ASUS A7J
-  asus-a7m	ASUS A7M
-  macpro	MacPro support
-  mb5		Macbook 5,1
-  macmini3	Macmini 3,1
-  mba21		Macbook Air 2,1
-  mbp3		Macbook Pro rev3
-  imac24	iMac 24'' with jack detection
-  imac91	iMac 9,1
-  w2jc		ASUS W2JC
-  3stack-2ch-dig	3-jack with SPDIF I/O (ALC883)
-  alc883-6stack-dig	6-jack digital with SPDIF I/O (ALC883)
-  3stack-6ch    3-jack 6-channel
-  3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
-  6stack-dig-demo  6-jack digital for Intel demo board
-  acer		Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
-  acer-aspire	Acer Aspire 9810
-  acer-aspire-4930g Acer Aspire 4930G
-  acer-aspire-6530g Acer Aspire 6530G
-  acer-aspire-7730g Acer Aspire 7730G
-  acer-aspire-8930g Acer Aspire 8930G
-  medion	Medion Laptops
-  targa-dig	Targa/MSI
-  targa-2ch-dig	Targa/MSI with 2-channel
-  targa-8ch-dig Targa/MSI with 8-channel (MSI GX620)
-  laptop-eapd   3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
-  lenovo-101e	Lenovo 101E
-  lenovo-nb0763	Lenovo NB0763
-  lenovo-ms7195-dig Lenovo MS7195
-  lenovo-sky	Lenovo Sky
-  haier-w66	Haier W66
-  3stack-hp	HP machines with 3stack (Lucknow, Samba boards)
-  6stack-dell	Dell machines with 6stack (Inspiron 530)
-  mitac		Mitac 8252D
-  clevo-m540r	Clevo M540R (6ch + digital)
-  clevo-m720	Clevo M720 laptop series
-  fujitsu-pi2515 Fujitsu AMILO Pi2515
-  fujitsu-xa3530 Fujitsu AMILO XA3530
-  3stack-6ch-intel Intel DG33* boards
-  intel-alc889a	Intel IbexPeak with ALC889A
-  intel-x58	Intel DX58 with ALC889
-  asus-p5q	ASUS P5Q-EM boards
-  mb31		MacBook 3,1
-  sony-vaio-tt  Sony VAIO TT
-  auto		auto-config reading BIOS (default)
+  N/A
 
 ALC861/660
 ==========
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index 96f0ee8..9c11d97 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -28,6 +28,7 @@ Currently, these files are in /proc/sys/vm:
 - dirty_writeback_centisecs
 - drop_caches
 - extfrag_threshold
+- extra_free_kbytes
 - hugepages_treat_as_movable
 - hugetlb_shm_group
 - laptop_mode
@@ -168,6 +169,21 @@ fragmentation index is <= extfrag_threshold. The default value is 500.
 
 ==============================================================
 
+extra_free_kbytes
+
+This parameter tells the VM to keep extra free memory between the threshold
+where background reclaim (kswapd) kicks in, and the threshold where direct
+reclaim (by allocating processes) kicks in.
+
+This is useful for workloads that require low latency memory allocations
+and have a bounded burstiness in memory allocations, for example a
+realtime application that receives and transmits network traffic
+(causing in-kernel memory allocations) with a maximum total message burst
+size of 200MB may need 200MB of extra free memory to avoid direct reclaim
+related latencies.
+
+==============================================================
+
 hugepages_treat_as_movable
 
 This parameter is only useful when kernelcore= is specified at boot time to
diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py
index 6e21b8b..a78879b 100755
--- a/Documentation/target/tcm_mod_builder.py
+++ b/Documentation/target/tcm_mod_builder.py
@@ -775,7 +775,7 @@ def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
 			buf += "	struct " + fabric_mod_name + "_nacl *nacl;\n\n"
 			buf += "	nacl = kzalloc(sizeof(struct " + fabric_mod_name + "_nacl), GFP_KERNEL);\n"
 			buf += "	if (!nacl) {\n"
-			buf += "		printk(KERN_ERR \"Unable to alocate struct " + fabric_mod_name + "_nacl\\n\");\n"
+			buf += "		printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_nacl\\n\");\n"
 			buf += "		return NULL;\n"
 			buf += "	}\n\n"
 			buf += "	return &nacl->se_node_acl;\n"
diff --git a/Documentation/trace/events-power.txt b/Documentation/trace/events-power.txt
index 96d87b6..cf794af 100644
--- a/Documentation/trace/events-power.txt
+++ b/Documentation/trace/events-power.txt
@@ -57,7 +57,7 @@ power_end		"cpu_id=%lu"
 The 'type' parameter takes one of those macros:
  . POWER_NONE	= 0,
  . POWER_CSTATE	= 1,	/* C-State */
- . POWER_PSTATE	= 2,	/* Fequency change or DVFS */
+ . POWER_PSTATE	= 2,	/* Frequency change or DVFS */
 
 The 'state' parameter is set depending on the type:
  . Target C-state for type=POWER_CSTATE,
diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt
new file mode 100644
index 0000000..457932f
--- /dev/null
+++ b/Documentation/trace/uprobetracer.txt
@@ -0,0 +1,93 @@
+		Uprobe-tracer: Uprobe-based Event Tracing
+		=========================================
+                 Documentation is written by Srikar Dronamraju
+
+Overview
+--------
+These events are similar to kprobe based events.
+To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.
+
+Similar to the kprobe-event tracer, this doesn't need to be activated via
+current_tracer. Instead of that, add probe points via
+/sys/kernel/debug/tracing/uprobe_events, and enable it via
+/sys/kernel/debug/tracing/events/uprobes/<EVENT>/enabled.
+
+
+Synopsis of uprobe_tracer
+-------------------------
+  p[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS]	: Set a probe
+
+ GRP		: Group name. If omitted, use "uprobes" for it.
+ EVENT		: Event name. If omitted, the event name is generated
+		  based on SYMBOL+offs.
+ PATH		: path to an executable or a library.
+ SYMBOL[+offs]	: Symbol+offset where the probe is inserted.
+
+ FETCHARGS	: Arguments. Each probe can have up to 128 args.
+  %REG		: Fetch register REG
+
+Event Profiling
+---------------
+ You can check the total number of probe hits and probe miss-hits via
+/sys/kernel/debug/tracing/uprobe_profile.
+ The first column is event name, the second is the number of probe hits,
+the third is the number of probe miss-hits.
+
+Usage examples
+--------------
+To add a probe as a new event, write a new definition to uprobe_events
+as below.
+
+  echo 'p: /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events
+
+ This sets a uprobe at an offset of 0x4245c0 in the executable /bin/bash
+
+
+  echo > /sys/kernel/debug/tracing/uprobe_events
+
+ This clears all probe points.
+
+The following example shows how to dump the instruction pointer and %ax
+a register at the probed text address.  Here we are trying to probe
+function zfree in /bin/zsh
+
+    # cd /sys/kernel/debug/tracing/
+    # cat /proc/`pgrep  zsh`/maps | grep /bin/zsh | grep r-xp
+    00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
+    # objdump -T /bin/zsh | grep -w zfree
+    0000000000446420 g    DF .text  0000000000000012  Base        zfree
+
+0x46420 is the offset of zfree in object /bin/zsh that is loaded at
+0x00400000. Hence the command to probe would be :
+
+    # echo 'p /bin/zsh:0x46420 %ip %ax' > uprobe_events
+
+We can see the events that are registered by looking at the uprobe_events
+file.
+
+    # cat uprobe_events
+    p:uprobes/p_zsh_0x46420 /bin/zsh:0x0000000000046420
+
+Right after definition, each event is disabled by default. For tracing these
+events, you need to enable it by:
+
+    # echo 1 > events/uprobes/enable
+
+Lets disable the event after sleeping for some time.
+    # sleep 20
+    # echo 0 > events/uprobes/enable
+
+And you can see the traced information via /sys/kernel/debug/tracing/trace.
+
+    # cat trace
+    # tracer: nop
+    #
+    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
+    #              | |       |          |         |
+                 zsh-24842 [006] 258544.995456: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
+                 zsh-24842 [007] 258545.000270: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
+                 zsh-24842 [002] 258545.043929: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
+                 zsh-24842 [004] 258547.046129: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
+
+Each line shows us probes were triggered for a pid 24842 with ip being
+0x446421 and contents of ax register being 79.
diff --git a/Documentation/usb/mtouchusb.txt b/Documentation/usb/mtouchusb.txt
index 86302cd..a91adb2 100644
--- a/Documentation/usb/mtouchusb.txt
+++ b/Documentation/usb/mtouchusb.txt
@@ -1,7 +1,7 @@
 CHANGES
 
 - 0.3 - Created based off of scanner & INSTALL from the original touchscreen
-  driver on freshmeat (http://freshmeat.net/projects/3mtouchscreendriver)
+  driver on freecode (http://freecode.com/projects/3mtouchscreendriver)
 - Amended for linux-2.4.18, then 2.4.19
 
 - 0.5 - Complete rewrite using Linux Input in 2.6.3
diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt
index 12511c9..817df29 100644
--- a/Documentation/usb/power-management.txt
+++ b/Documentation/usb/power-management.txt
@@ -345,7 +345,7 @@ autosuspend the device.
 Drivers need not be concerned about balancing changes to the usage
 counter; the USB core will undo any remaining "get"s when a driver
 is unbound from its interface.  As a corollary, drivers must not call
-any of the usb_autopm_* functions after their diconnect() routine has
+any of the usb_autopm_* functions after their disconnect() routine has
 returned.
 
 Drivers using the async routines are responsible for their own
diff --git a/Documentation/usb/proc_usb_info.txt b/Documentation/usb/proc_usb_info.txt
index afe596d..c9c3f0f 100644
--- a/Documentation/usb/proc_usb_info.txt
+++ b/Documentation/usb/proc_usb_info.txt
@@ -7,7 +7,7 @@ The usbfs filesystem for USB devices is traditionally mounted at
 /proc/bus/usb.  It provides the /proc/bus/usb/devices file, as well as
 the /proc/bus/usb/BBB/DDD files.
 
-In many modern systems the usbfs filsystem isn't used at all.  Instead
+In many modern systems the usbfs filesystem isn't used at all.  Instead
 USB device nodes are created under /dev/usb/ or someplace similar.  The
 "devices" file is available in debugfs, typically as
 /sys/kernel/debug/usb/devices.
diff --git a/Documentation/virtual/virtio-spec.txt b/Documentation/virtual/virtio-spec.txt
index a350ae1..401ffd0 100644
--- a/Documentation/virtual/virtio-spec.txt
+++ b/Documentation/virtual/virtio-spec.txt
@@ -1,11 +1,11 @@
 [Generated file: see http://ozlabs.org/~rusty/virtio-spec/]
 Virtio PCI Card Specification
-v0.9.1 DRAFT
+v0.9.4 DRAFT
 -
 
-Rusty Russell <rusty@rustcorp.com.au>IBM Corporation (Editor)
+Rusty Russell <rusty@rustcorp.com.au> IBM Corporation (Editor)
 
-2011 August 1.
+2012February 7.
 
 Purpose and Description
 
@@ -68,11 +68,11 @@ and consists of three parts:
 +-------------------+-----------------------------------+-----------+
 
 
-When the driver wants to send buffers to the device, it puts them
-in one or more slots in the descriptor table, and writes the
-descriptor indices into the available ring. It then notifies the
-device. When the device has finished with the buffers, it writes
-the descriptors into the used ring, and sends an interrupt.
+When the driver wants to send a buffer to the device, it fills in
+a slot in the descriptor table (or chains several together), and
+writes the descriptor index into the available ring. It then
+notifies the device. When the device has finished a buffer, it
+writes the descriptor into the used ring, and sends an interrupt.
 
 Specification
 
@@ -106,6 +106,10 @@ for informational purposes by the guest).
 +----------------------+--------------------+---------------+
 |          6           |     ioMemory       |       -       |
 +----------------------+--------------------+---------------+
+|          7           |       rpmsg        |       -       |
++----------------------+--------------------+---------------+
+|          8           |     SCSI host      |  Appendix H   |
++----------------------+--------------------+---------------+
 |          9           |   9P transport     |       -       |
 +----------------------+--------------------+---------------+
 
@@ -127,7 +131,7 @@ Note that this is possible because while the virtio header is PCI
 the native endian of the guest (where such distinction is
 applicable).
 
-  Device Initialization Sequence
+  Device Initialization Sequence<sub:Device-Initialization-Sequence>
 
 We start with an overview of device initialization, then expand
 on the details of the device and how each step is preformed.
@@ -177,7 +181,10 @@ The virtio header looks as follows:
 
 
 If MSI-X is enabled for the device, two additional fields
-immediately follow this header:
+immediately follow this header:[footnote:
+ie. once you enable MSI-X on the device, the other fields move.
+If you turn it off again, they move back!
+]
 
 
 +------------++----------------+--------+
@@ -191,20 +198,6 @@ immediately follow this header:
 +------------++----------------+--------+
 
 
-Finally, if feature bits (VIRTIO_F_FEATURES_HI) this is
-immediately followed by two additional fields:
-
-
-+------------++----------------------+----------------------
-| Bits       || 32                   | 32
-+------------++----------------------+----------------------
-| Read/Write || R                    | R+W
-+------------++----------------------+----------------------
-| Purpose    || Device               | Guest
-|            || Features bits 32:63  | Features bits 32:63
-+------------++----------------------+----------------------
-
-
 Immediately following these general headers, there may be
 device-specific headers:
 
@@ -238,31 +231,25 @@ at least one bit should be set:
   may be a significant (or infinite) delay before setting this
   bit.
 
-  DRIVER_OK (3) Indicates that the driver is set up and ready to
+  DRIVER_OK (4) Indicates that the driver is set up and ready to
   drive the device.
 
-  FAILED (8) Indicates that something went wrong in the guest,
+  FAILED (128) Indicates that something went wrong in the guest,
   and it has given up on the device. This could be an internal
   error, or the driver didn't like the device for some reason, or
   even a fatal error during device operation. The device must be
   reset before attempting to re-initialize.
 
-  Feature Bits
+  Feature Bits<sub:Feature-Bits>
 
-The least significant 31 bits of the first configuration field
-indicates the features that the device supports (the high bit is
-reserved, and will be used to indicate the presence of future
-feature bits elsewhere). If more than 31 feature bits are
-supported, the device indicates so by setting feature bit 31 (see
-[cha:Reserved-Feature-Bits]). The bits are allocated as follows:
+Thefirst configuration field indicates the features that the
+device supports. The bits are allocated as follows:
 
   0 to 23 Feature bits for the specific device type
 
-  24 to 40 Feature bits reserved for extensions to the queue and
+  24 to 32 Feature bits reserved for extensions to the queue and
   feature negotiation mechanisms
 
-  41 to 63 Feature bits reserved for future extensions
-
 For example, feature bit 0 for a network device (i.e. Subsystem
 Device ID 1) indicates that the device supports checksumming of
 packets.
@@ -286,10 +273,6 @@ will not see that feature bit in the Device Features field and
 can go into backwards compatibility mode (or, for poor
 implementations, set the FAILED Device Status bit).
 
-Access to feature bits 32 to 63 is enabled by Guest by setting
-feature bit 31. If this bit is unset, Device must assume that all
-feature bits > 31 are unset.
-
   Configuration/Queue Vectors
 
 When MSI-X capability is present and enabled in the device
@@ -324,7 +307,7 @@ success, the previously written value is returned, and on
 failure, NO_VECTOR is returned. If a mapping failure is detected,
 the driver can retry mapping with fewervectors, or disable MSI-X.
 
-  Virtqueue Configuration
+  Virtqueue Configuration<sec:Virtqueue-Configuration>
 
 As a device can have zero or more virtqueues for bulk data
 transport (for example, the network driver has two), the driver
@@ -587,7 +570,7 @@ and Red Hat under the (3-clause) BSD license so that it can be
 freely used by all other projects, and is reproduced (with slight
 variation to remove Linux assumptions) in Appendix A.
 
-  Device Operation
+  Device Operation<sec:Device-Operation>
 
 There are two parts to device operation: supplying new buffers to
 the device, and processing used buffers from the device. As an
@@ -813,7 +796,7 @@ vring.used->ring[vq->last_seen_used%vsz];
 
 }
 
-  Dealing With Configuration Changes
+  Dealing With Configuration Changes<sub:Dealing-With-Configuration>
 
 Some virtio PCI devices can change the device configuration
 state, as reflected in the virtio header in the PCI configuration
@@ -1260,18 +1243,6 @@ Currently there are five device-independent feature bits defined:
   driver should ignore the used_event field; the device should
   ignore the avail_event field; the flags field is used
 
-  VIRTIO_F_BAD_FEATURE(30) This feature should never be
-  negotiated by the guest; doing so is an indication that the
-  guest is faulty[footnote:
-An experimental virtio PCI driver contained in Linux version
-2.6.25 had this problem, and this feature bit can be used to
-detect it.
-]
-
-  VIRTIO_F_FEATURES_HIGH(31) This feature indicates that the
-  device supports feature bits 32:63. If unset, feature bits
-  32:63 are unset.
-
 Appendix C: Network Device
 
 The virtio network device is a virtual ethernet card, and is the
@@ -1335,11 +1306,17 @@ were required.
 
   VIRTIO_NET_F_CTRL_VLAN (19) Control channel VLAN filtering.
 
+  VIRTIO_NET_F_GUEST_ANNOUNCE(21) Guest can send gratuitous
+    packets.
+
   Device configuration layout Two configuration fields are
   currently defined. The mac address field always exists (though
   is only valid if VIRTIO_NET_F_MAC is set), and the status field
-  only exists if VIRTIO_NET_F_STATUS is set. Only one bit is
-  currently defined for the status field: VIRTIO_NET_S_LINK_UP. #define VIRTIO_NET_S_LINK_UP	1
+  only exists if VIRTIO_NET_F_STATUS is set. Two bits are
+  currently defined for the status field: VIRTIO_NET_S_LINK_UP
+  and VIRTIO_NET_S_ANNOUNCE. #define VIRTIO_NET_S_LINK_UP	1
+
+#define VIRTIO_NET_S_ANNOUNCE	2
 
 
 
@@ -1377,12 +1354,19 @@ struct virtio_net_config {
   packets by negotating the VIRTIO_NET_F_CSUM feature. This “
   checksum offload” is a common feature on modern network cards.
 
-  If that feature is negotiated, a driver can use TCP or UDP
-  segmentation offload by negotiating the VIRTIO_NET_F_HOST_TSO4
-  (IPv4 TCP), VIRTIO_NET_F_HOST_TSO6 (IPv6 TCP) and
-  VIRTIO_NET_F_HOST_UFO (UDP fragmentation) features. It should
-  not send TCP packets requiring segmentation offload which have
-  the Explicit Congestion Notification bit set, unless the
+  If that feature is negotiated[footnote:
+ie. VIRTIO_NET_F_HOST_TSO* and VIRTIO_NET_F_HOST_UFO are
+dependent on VIRTIO_NET_F_CSUM; a dvice which offers the offload
+features must offer the checksum feature, and a driver which
+accepts the offload features must accept the checksum feature.
+Similar logic applies to the VIRTIO_NET_F_GUEST_TSO4 features
+depending on VIRTIO_NET_F_GUEST_CSUM.
+], a driver can use TCP or UDP segmentation offload by
+  negotiating the VIRTIO_NET_F_HOST_TSO4 (IPv4 TCP),
+  VIRTIO_NET_F_HOST_TSO6 (IPv6 TCP) and VIRTIO_NET_F_HOST_UFO
+  (UDP fragmentation) features. It should not send TCP packets
+  requiring segmentation offload which have the Explicit
+  Congestion Notification bit set, unless the
   VIRTIO_NET_F_HOST_ECN feature is negotiated.[footnote:
 This is a common restriction in real, older network cards.
 ]
@@ -1462,9 +1446,10 @@ It will have a 14 byte ethernet header and 20 byte IP header
 followed by the TCP header (with the TCP checksum field 16 bytes
 into that header). csum_start will be 14+20 = 34 (the TCP
 checksum includes the header), and csum_offset will be 16. The
-value in the TCP checksum field will be the sum of the TCP pseudo
-header, so that replacing it by the ones' complement checksum of
-the TCP header and body will give the correct result.
+value in the TCP checksum field should be initialized to the sum
+of the TCP pseudo header, so that replacing it by the ones'
+complement checksum of the TCP header and body will give the
+correct result.
 ]
 
   <enu:If-the-driver>If the driver negotiated
@@ -1483,8 +1468,8 @@ Due to various bugs in implementations, this field is not useful
 as a guarantee of the transport header size.
 ]
 
-  gso_size is the size of the packet beyond that header (ie.
-    MSS).
+  gso_size is the maximum size of each packet beyond that header
+    (ie. MSS).
 
   If the driver negotiated the VIRTIO_NET_F_HOST_ECN feature, the
     VIRTIO_NET_HDR_GSO_ECN bit may be set in “gso_type” as well,
@@ -1567,7 +1552,9 @@ Processing packet involves:
   If the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options were
   negotiated, then the “gso_type” may be something other than
   VIRTIO_NET_HDR_GSO_NONE, and the “gso_size” field indicates the
-  desired MSS (see [enu:If-the-driver]).Control Virtqueue
+  desired MSS (see [enu:If-the-driver]).
+
+  Control Virtqueue
 
 The driver uses the control virtqueue (if VIRTIO_NET_F_VTRL_VQ is
 negotiated) to send commands to manipulate various features of
@@ -1665,6 +1652,24 @@ can control a VLAN filter table in the device.
 Both the VIRTIO_NET_CTRL_VLAN_ADD and VIRTIO_NET_CTRL_VLAN_DEL
 command take a 16-bit VLAN id as the command-specific-data.
 
+  Gratuitous Packet Sending
+
+If the driver negotiates the VIRTIO_NET_F_GUEST_ANNOUNCE, it can
+ask the guest to send gratuitous packets; this is usually done
+after the guest has been physically migrated, and needs to
+announce its presence on the new network links. (As hypervisor
+does not have the knowledge of guest network configuration (eg.
+tagged vlan) it is simplest to prod the guest in this way).
+
+The Guest needs to check VIRTIO_NET_S_ANNOUNCE bit in status
+field when it notices the changes of device configuration.
+
+Processing this notification involves:
+
+  Clearing VIRTIO_NET_S_ANNOUNCE bit in the status field.
+
+  Sending the gratuitous packets.
+
 Appendix D: Block Device
 
 The virtio block device is a simple virtual block device (ie.
@@ -1699,8 +1704,6 @@ device except where noted.
 
   VIRTIO_BLK_F_FLUSH (9) Cache flush command support.
 
-
-
   Device configuration layout The capacity of the device
   (expressed in 512-byte sectors) is always present. The
   availability of the others all depend on various feature bits
@@ -1743,8 +1746,6 @@ device except where noted.
   If the VIRTIO_BLK_F_RO feature is set by the device, any write
   requests will fail.
 
-
-
   Device Operation
 
 The driver queues requests to the virtqueue, and they are used by
@@ -2198,3 +2199,856 @@ as follows:
   VIRTIO_BALLOON_S_MEMTOT The total amount of memory available
   (in bytes).
 
+Appendix H: SCSI Host Device
+
+The virtio SCSI host device groups together one or more virtual
+logical units (such as disks), and allows communicating to them
+using the SCSI protocol. An instance of the device represents a
+SCSI host to which many targets and LUNs are attached.
+
+The virtio SCSI device services two kinds of requests:
+
+  command requests for a logical unit;
+
+  task management functions related to a logical unit, target or
+  command.
+
+The device is also able to send out notifications about added and
+removed logical units. Together, these capabilities provide a
+SCSI transport protocol that uses virtqueues as the transfer
+medium. In the transport protocol, the virtio driver acts as the
+initiator, while the virtio SCSI host provides one or more
+targets that receive and process the requests.
+
+  Configuration
+
+  Subsystem Device ID 7
+
+  Virtqueues 0:controlq; 1:eventq; 2..n:request queues.
+
+  Feature bits
+
+  VIRTIO_SCSI_F_INOUT (0) A single request can include both
+    read-only and write-only data buffers.
+
+  VIRTIO_SCSI_F_HOTPLUG (1) The host should enable
+    hot-plug/hot-unplug of new LUNs and targets on the SCSI bus.
+
+  Device configuration layout All fields of this configuration
+  are always available. sense_size and cdb_size are writable by
+  the guest.struct virtio_scsi_config {
+
+    u32 num_queues;
+
+    u32 seg_max;
+
+    u32 max_sectors;
+
+    u32 cmd_per_lun;
+
+    u32 event_info_size;
+
+    u32 sense_size;
+
+    u32 cdb_size;
+
+    u16 max_channel;
+
+    u16 max_target;
+
+    u32 max_lun;
+
+};
+
+  num_queues is the total number of request virtqueues exposed by
+    the device. The driver is free to use only one request queue,
+    or it can use more to achieve better performance.
+
+  seg_max is the maximum number of segments that can be in a
+    command. A bidirectional command can include seg_max input
+    segments and seg_max output segments.
+
+  max_sectors is a hint to the guest about the maximum transfer
+    size it should use.
+
+  cmd_per_lun is a hint to the guest about the maximum number of
+    linked commands it should send to one LUN. The actual value
+    to be used is the minimum of cmd_per_lun and the virtqueue
+    size.
+
+  event_info_size is the maximum size that the device will fill
+    for buffers that the driver places in the eventq. The driver
+    should always put buffers at least of this size. It is
+    written by the device depending on the set of negotated
+    features.
+
+  sense_size is the maximum size of the sense data that the
+    device will write. The default value is written by the device
+    and will always be 96, but the driver can modify it. It is
+    restored to the default when the device is reset.
+
+  cdb_size is the maximum size of the CDB that the driver will
+    write. The default value is written by the device and will
+    always be 32, but the driver can likewise modify it. It is
+    restored to the default when the device is reset.
+
+  max_channel, max_target and max_lun can be used by the driver
+    as hints to constrain scanning the logical units on the
+    host.h
+
+  Device Initialization
+
+The initialization routine should first of all discover the
+device's virtqueues.
+
+If the driver uses the eventq, it should then place at least a
+buffer in the eventq.
+
+The driver can immediately issue requests (for example, INQUIRY
+or REPORT LUNS) or task management functions (for example, I_T
+RESET).
+
+  Device Operation: request queues
+
+The driver queues requests to an arbitrary request queue, and
+they are used by the device on that same queue. It is the
+responsibility of the driver to ensure strict request ordering
+for commands placed on different queues, because they will be
+consumed with no order constraints.
+
+Requests have the following format:
+
+struct virtio_scsi_req_cmd {
+
+    // Read-only
+
+    u8 lun[8];
+
+    u64 id;
+
+    u8 task_attr;
+
+    u8 prio;
+
+    u8 crn;
+
+    char cdb[cdb_size];
+
+    char dataout[];
+
+    // Write-only part
+
+    u32 sense_len;
+
+    u32 residual;
+
+    u16 status_qualifier;
+
+    u8 status;
+
+    u8 response;
+
+    u8 sense[sense_size];
+
+    char datain[];
+
+};
+
+
+
+/* command-specific response values */
+
+#define VIRTIO_SCSI_S_OK                0
+
+#define VIRTIO_SCSI_S_OVERRUN           1
+
+#define VIRTIO_SCSI_S_ABORTED           2
+
+#define VIRTIO_SCSI_S_BAD_TARGET        3
+
+#define VIRTIO_SCSI_S_RESET             4
+
+#define VIRTIO_SCSI_S_BUSY              5
+
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6
+
+#define VIRTIO_SCSI_S_TARGET_FAILURE    7
+
+#define VIRTIO_SCSI_S_NEXUS_FAILURE     8
+
+#define VIRTIO_SCSI_S_FAILURE           9
+
+
+
+/* task_attr */
+
+#define VIRTIO_SCSI_S_SIMPLE            0
+
+#define VIRTIO_SCSI_S_ORDERED           1
+
+#define VIRTIO_SCSI_S_HEAD              2
+
+#define VIRTIO_SCSI_S_ACA               3
+
+The lun field addresses a target and logical unit in the
+virtio-scsi device's SCSI domain. The only supported format for
+the LUN field is: first byte set to 1, second byte set to target,
+third and fourth byte representing a single level LUN structure,
+followed by four zero bytes. With this representation, a
+virtio-scsi device can serve up to 256 targets and 16384 LUNs per
+target.
+
+The id field is the command identifier (“tag”).
+
+task_attr, prio and crn should be left to zero. task_attr defines
+the task attribute as in the table above, but all task attributes
+may be mapped to SIMPLE by the device; crn may also be provided
+by clients, but is generally expected to be 0. The maximum CRN
+value defined by the protocol is 255, since CRN is stored in an
+8-bit integer.
+
+All of these fields are defined in SAM. They are always
+read-only, as are the cdb and dataout field. The cdb_size is
+taken from the configuration space.
+
+sense and subsequent fields are always write-only. The sense_len
+field indicates the number of bytes actually written to the sense
+buffer. The residual field indicates the residual size,
+calculated as “data_length - number_of_transferred_bytes”, for
+read or write operations. For bidirectional commands, the
+number_of_transferred_bytes includes both read and written bytes.
+A residual field that is less than the size of datain means that
+the dataout field was processed entirely. A residual field that
+exceeds the size of datain means that the dataout field was
+processed partially and the datain field was not processed at
+all.
+
+The status byte is written by the device to be the status code as
+defined in SAM.
+
+The response byte is written by the device to be one of the
+following:
+
+  VIRTIO_SCSI_S_OK when the request was completed and the status
+  byte is filled with a SCSI status code (not necessarily
+  "GOOD").
+
+  VIRTIO_SCSI_S_OVERRUN if the content of the CDB requires
+  transferring more data than is available in the data buffers.
+
+  VIRTIO_SCSI_S_ABORTED if the request was cancelled due to an
+  ABORT TASK or ABORT TASK SET task management function.
+
+  VIRTIO_SCSI_S_BAD_TARGET if the request was never processed
+  because the target indicated by the lun field does not exist.
+
+  VIRTIO_SCSI_S_RESET if the request was cancelled due to a bus
+  or device reset (including a task management function).
+
+  VIRTIO_SCSI_S_TRANSPORT_FAILURE if the request failed due to a
+  problem in the connection between the host and the target
+  (severed link).
+
+  VIRTIO_SCSI_S_TARGET_FAILURE if the target is suffering a
+  failure and the guest should not retry on other paths.
+
+  VIRTIO_SCSI_S_NEXUS_FAILURE if the nexus is suffering a failure
+  but retrying on other paths might yield a different result.
+
+  VIRTIO_SCSI_S_BUSY if the request failed but retrying on the
+  same path should work.
+
+  VIRTIO_SCSI_S_FAILURE for other host or guest error. In
+  particular, if neither dataout nor datain is empty, and the
+  VIRTIO_SCSI_F_INOUT feature has not been negotiated, the
+  request will be immediately returned with a response equal to
+  VIRTIO_SCSI_S_FAILURE.
+
+  Device Operation: controlq
+
+The controlq is used for other SCSI transport operations.
+Requests have the following format:
+
+struct virtio_scsi_ctrl {
+
+    u32 type;
+
+    ...
+
+    u8 response;
+
+};
+
+
+
+/* response values valid for all commands */
+
+#define VIRTIO_SCSI_S_OK                       0
+
+#define VIRTIO_SCSI_S_BAD_TARGET               3
+
+#define VIRTIO_SCSI_S_BUSY                     5
+
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE        6
+
+#define VIRTIO_SCSI_S_TARGET_FAILURE           7
+
+#define VIRTIO_SCSI_S_NEXUS_FAILURE            8
+
+#define VIRTIO_SCSI_S_FAILURE                  9
+
+#define VIRTIO_SCSI_S_INCORRECT_LUN            12
+
+The type identifies the remaining fields.
+
+The following commands are defined:
+
+  Task management function
+#define VIRTIO_SCSI_T_TMF                      0
+
+
+
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK           0
+
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET       1
+
+#define VIRTIO_SCSI_T_TMF_CLEAR_ACA            2
+
+#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET       3
+
+#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET      4
+
+#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET   5
+
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK           6
+
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET       7
+
+
+
+struct virtio_scsi_ctrl_tmf
+
+{
+
+    // Read-only part
+
+    u32 type;
+
+    u32 subtype;
+
+    u8 lun[8];
+
+    u64 id;
+
+    // Write-only part
+
+    u8 response;
+
+}
+
+
+
+/* command-specific response values */
+
+#define VIRTIO_SCSI_S_FUNCTION_COMPLETE        0
+
+#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED       10
+
+#define VIRTIO_SCSI_S_FUNCTION_REJECTED        11
+
+  The type is VIRTIO_SCSI_T_TMF; the subtype field defines. All
+  fields except response are filled by the driver. The subtype
+  field must always be specified and identifies the requested
+  task management function.
+
+  Other fields may be irrelevant for the requested TMF; if so,
+  they are ignored but they should still be present. The lun
+  field is in the same format specified for request queues; the
+  single level LUN is ignored when the task management function
+  addresses a whole I_T nexus. When relevant, the value of the id
+  field is matched against the id values passed on the requestq.
+
+  The outcome of the task management function is written by the
+  device in the response field. The command-specific response
+  values map 1-to-1 with those defined in SAM.
+
+  Asynchronous notification query
+#define VIRTIO_SCSI_T_AN_QUERY                    1
+
+
+
+struct virtio_scsi_ctrl_an {
+
+    // Read-only part
+
+    u32 type;
+
+    u8  lun[8];
+
+    u32 event_requested;
+
+    // Write-only part
+
+    u32 event_actual;
+
+    u8  response;
+
+}
+
+
+
+#define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE  2
+
+#define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT          4
+
+#define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST    8
+
+#define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE        16
+
+#define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST          32
+
+#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY         64
+
+  By sending this command, the driver asks the device which
+  events the given LUN can report, as described in paragraphs 6.6
+  and A.6 of the SCSI MMC specification. The driver writes the
+  events it is interested in into the event_requested; the device
+  responds by writing the events that it supports into
+  event_actual.
+
+  The type is VIRTIO_SCSI_T_AN_QUERY. The lun and event_requested
+  fields are written by the driver. The event_actual and response
+  fields are written by the device.
+
+  No command-specific values are defined for the response byte.
+
+  Asynchronous notification subscription
+#define VIRTIO_SCSI_T_AN_SUBSCRIBE                2
+
+
+
+struct virtio_scsi_ctrl_an {
+
+    // Read-only part
+
+    u32 type;
+
+    u8  lun[8];
+
+    u32 event_requested;
+
+    // Write-only part
+
+    u32 event_actual;
+
+    u8  response;
+
+}
+
+  By sending this command, the driver asks the specified LUN to
+  report events for its physical interface, again as described in
+  the SCSI MMC specification. The driver writes the events it is
+  interested in into the event_requested; the device responds by
+  writing the events that it supports into event_actual.
+
+  Event types are the same as for the asynchronous notification
+  query message.
+
+  The type is VIRTIO_SCSI_T_AN_SUBSCRIBE. The lun and
+  event_requested fields are written by the driver. The
+  event_actual and response fields are written by the device.
+
+  No command-specific values are defined for the response byte.
+
+  Device Operation: eventq
+
+The eventq is used by the device to report information on logical
+units that are attached to it. The driver should always leave a
+few buffers ready in the eventq. In general, the device will not
+queue events to cope with an empty eventq, and will end up
+dropping events if it finds no buffer ready. However, when
+reporting events for many LUNs (e.g. when a whole target
+disappears), the device can throttle events to avoid dropping
+them. For this reason, placing 10-15 buffers on the event queue
+should be enough.
+
+Buffers are placed in the eventq and filled by the device when
+interesting events occur. The buffers should be strictly
+write-only (device-filled) and the size of the buffers should be
+at least the value given in the device's configuration
+information.
+
+Buffers returned by the device on the eventq will be referred to
+as "events" in the rest of this section. Events have the
+following format:
+
+#define VIRTIO_SCSI_T_EVENTS_MISSED   0x80000000
+
+
+
+struct virtio_scsi_event {
+
+    // Write-only part
+
+    u32 event;
+
+    ...
+
+}
+
+If bit 31 is set in the event field, the device failed to report
+an event due to missing buffers. In this case, the driver should
+poll the logical units for unit attention conditions, and/or do
+whatever form of bus scan is appropriate for the guest operating
+system.
+
+Other data that the device writes to the buffer depends on the
+contents of the event field. The following events are defined:
+
+  No event
+#define VIRTIO_SCSI_T_NO_EVENT         0
+
+  This event is fired in the following cases:
+
+  When the device detects in the eventq a buffer that is shorter
+    than what is indicated in the configuration field, it might
+    use it immediately and put this dummy value in the event
+    field. A well-written driver will never observe this
+    situation.
+
+  When events are dropped, the device may signal this event as
+    soon as the drivers makes a buffer available, in order to
+    request action from the driver. In this case, of course, this
+    event will be reported with the VIRTIO_SCSI_T_EVENTS_MISSED
+    flag.
+
+  Transport reset
+#define VIRTIO_SCSI_T_TRANSPORT_RESET  1
+
+
+
+struct virtio_scsi_event_reset {
+
+    // Write-only part
+
+    u32 event;
+
+    u8  lun[8];
+
+    u32 reason;
+
+}
+
+
+
+#define VIRTIO_SCSI_EVT_RESET_HARD         0
+
+#define VIRTIO_SCSI_EVT_RESET_RESCAN       1
+
+#define VIRTIO_SCSI_EVT_RESET_REMOVED      2
+
+  By sending this event, the device signals that a logical unit
+  on a target has been reset, including the case of a new device
+  appearing or disappearing on the bus.The device fills in all
+  fields. The event field is set to
+  VIRTIO_SCSI_T_TRANSPORT_RESET. The lun field addresses a
+  logical unit in the SCSI host.
+
+  The reason value is one of the three #define values appearing
+  above:
+
+  VIRTIO_SCSI_EVT_RESET_REMOVED (“LUN/target removed”) is used if
+    the target or logical unit is no longer able to receive
+    commands.
+
+  VIRTIO_SCSI_EVT_RESET_HARD (“LUN hard reset”) is used if the
+    logical unit has been reset, but is still present.
+
+  VIRTIO_SCSI_EVT_RESET_RESCAN (“rescan LUN/target”) is used if a
+    target or logical unit has just appeared on the device.
+
+  The “removed” and “rescan” events, when sent for LUN 0, may
+  apply to the entire target. After receiving them the driver
+  should ask the initiator to rescan the target, in order to
+  detect the case when an entire target has appeared or
+  disappeared. These two events will never be reported unless the
+  VIRTIO_SCSI_F_HOTPLUG feature was negotiated between the host
+  and the guest.
+
+  Events will also be reported via sense codes (this obviously
+  does not apply to newly appeared buses or targets, since the
+  application has never discovered them):
+
+  “LUN/target removed” maps to sense key ILLEGAL REQUEST, asc
+    0x25, ascq 0x00 (LOGICAL UNIT NOT SUPPORTED)
+
+  “LUN hard reset” maps to sense key UNIT ATTENTION, asc 0x29
+    (POWER ON, RESET OR BUS DEVICE RESET OCCURRED)
+
+  “rescan LUN/target” maps to sense key UNIT ATTENTION, asc 0x3f,
+    ascq 0x0e (REPORTED LUNS DATA HAS CHANGED)
+
+  The preferred way to detect transport reset is always to use
+  events, because sense codes are only seen by the driver when it
+  sends a SCSI command to the logical unit or target. However, in
+  case events are dropped, the initiator will still be able to
+  synchronize with the actual state of the controller if the
+  driver asks the initiator to rescan of the SCSI bus. During the
+  rescan, the initiator will be able to observe the above sense
+  codes, and it will process them as if it the driver had
+  received the equivalent event.
+
+  Asynchronous notification
+#define VIRTIO_SCSI_T_ASYNC_NOTIFY     2
+
+
+
+struct virtio_scsi_event_an {
+
+    // Write-only part
+
+    u32 event;
+
+    u8  lun[8];
+
+    u32 reason;
+
+}
+
+  By sending this event, the device signals that an asynchronous
+  event was fired from a physical interface.
+
+  All fields are written by the device. The event field is set to
+  VIRTIO_SCSI_T_ASYNC_NOTIFY. The lun field addresses a logical
+  unit in the SCSI host. The reason field is a subset of the
+  events that the driver has subscribed to via the "Asynchronous
+  notification subscription" command.
+
+  When dropped events are reported, the driver should poll for
+  asynchronous events manually using SCSI commands.
+
+Appendix X: virtio-mmio
+
+Virtual environments without PCI support (a common situation in
+embedded devices models) might use simple memory mapped device (“
+virtio-mmio”) instead of the PCI device.
+
+The memory mapped virtio device behaviour is based on the PCI
+device specification. Therefore most of operations like device
+initialization, queues configuration and buffer transfers are
+nearly identical. Existing differences are described in the
+following sections.
+
+  Device Initialization
+
+Instead of using the PCI IO space for virtio header, the “
+virtio-mmio” device provides a set of memory mapped control
+registers, all 32 bits wide, followed by device-specific
+configuration space. The following list presents their layout:
+
+  Offset from the device base address | Direction | Name
+ Description
+
+  0x000 | R | MagicValue
+ “virt” string.
+
+  0x004 | R | Version
+ Device version number. Currently must be 1.
+
+  0x008 | R | DeviceID
+ Virtio Subsystem Device ID (ie. 1 for network card).
+
+  0x00c | R | VendorID
+ Virtio Subsystem Vendor ID.
+
+  0x010 | R | HostFeatures
+ Flags representing features the device supports.
+ Reading from this register returns 32 consecutive flag bits,
+  first bit depending on the last value written to
+  HostFeaturesSel register. Access to this register returns bits HostFeaturesSel*32
+   to (HostFeaturesSel*32)+31, eg. feature bits 0 to 31 if
+  HostFeaturesSel is set to 0 and features bits 32 to 63 if
+  HostFeaturesSel is set to 1. Also see [sub:Feature-Bits]
+
+  0x014 | W | HostFeaturesSel
+ Device (Host) features word selection.
+ Writing to this register selects a set of 32 device feature bits
+  accessible by reading from HostFeatures register. Device driver
+  must write a value to the HostFeaturesSel register before
+  reading from the HostFeatures register.
+
+  0x020 | W | GuestFeatures
+ Flags representing device features understood and activated by
+  the driver.
+ Writing to this register sets 32 consecutive flag bits, first
+  bit depending on the last value written to GuestFeaturesSel
+  register. Access to this register sets bits GuestFeaturesSel*32
+  to (GuestFeaturesSel*32)+31, eg. feature bits 0 to 31 if
+  GuestFeaturesSel is set to 0 and features bits 32 to 63 if
+  GuestFeaturesSel is set to 1. Also see [sub:Feature-Bits]
+
+  0x024 | W | GuestFeaturesSel
+ Activated (Guest) features word selection.
+ Writing to this register selects a set of 32 activated feature
+  bits accessible by writing to the GuestFeatures register.
+  Device driver must write a value to the GuestFeaturesSel
+  register before writing to the GuestFeatures register.
+
+  0x028 | W | GuestPageSize
+ Guest page size.
+ Device driver must write the guest page size in bytes to the
+  register during initialization, before any queues are used.
+  This value must be a power of 2 and is used by the Host to
+  calculate Guest address of the first queue page (see QueuePFN).
+
+  0x030 | W | QueueSel
+ Virtual queue index (first queue is 0).
+ Writing to this register selects the virtual queue that the
+  following operations on QueueNum, QueueAlign and QueuePFN apply
+  to.
+
+  0x034 | R | QueueNumMax
+ Maximum virtual queue size.
+ Reading from the register returns the maximum size of the queue
+  the Host is ready to process or zero (0x0) if the queue is not
+  available. This applies to the queue selected by writing to
+  QueueSel and is allowed only when QueuePFN is set to zero
+  (0x0), so when the queue is not actively used.
+
+  0x038 | W | QueueNum
+ Virtual queue size.
+ Queue size is a number of elements in the queue, therefore size
+  of the descriptor table and both available and used rings.
+ Writing to this register notifies the Host what size of the
+  queue the Guest will use. This applies to the queue selected by
+  writing to QueueSel.
+
+  0x03c | W | QueueAlign
+ Used Ring alignment in the virtual queue.
+ Writing to this register notifies the Host about alignment
+  boundary of the Used Ring in bytes. This value must be a power
+  of 2 and applies to the queue selected by writing to QueueSel.
+
+  0x040 | RW | QueuePFN
+ Guest physical page number of the virtual queue.
+ Writing to this register notifies the host about location of the
+  virtual queue in the Guest's physical address space. This value
+  is the index number of a page starting with the queue
+  Descriptor Table. Value zero (0x0) means physical address zero
+  (0x00000000) and is illegal. When the Guest stops using the
+  queue it must write zero (0x0) to this register.
+ Reading from this register returns the currently used page
+  number of the queue, therefore a value other than zero (0x0)
+  means that the queue is in use.
+ Both read and write accesses apply to the queue selected by
+  writing to QueueSel.
+
+  0x050 | W | QueueNotify
+ Queue notifier.
+ Writing a queue index to this register notifies the Host that
+  there are new buffers to process in the queue.
+
+  0x60 | R | InterruptStatus
+Interrupt status.
+Reading from this register returns a bit mask of interrupts
+  asserted by the device. An interrupt is asserted if the
+  corresponding bit is set, ie. equals one (1).
+
+  Bit 0 | Used Ring Update
+This interrupt is asserted when the Host has updated the Used
+    Ring in at least one of the active virtual queues.
+
+  Bit 1 | Configuration change
+This interrupt is asserted when configuration of the device has
+    changed.
+
+  0x064 | W | InterruptACK
+ Interrupt acknowledge.
+ Writing to this register notifies the Host that the Guest
+  finished handling interrupts. Set bits in the value clear the
+  corresponding bits of the InterruptStatus register.
+
+  0x070 | RW | Status
+ Device status.
+ Reading from this register returns the current device status
+  flags.
+ Writing non-zero values to this register sets the status flags,
+  indicating the Guest progress. Writing zero (0x0) to this
+  register triggers a device reset.
+ Also see [sub:Device-Initialization-Sequence]
+
+  0x100+ | RW | Config
+ Device-specific configuration space starts at an offset 0x100
+  and is accessed with byte alignment. Its meaning and size
+  depends on the device and the driver.
+
+Virtual queue size is a number of elements in the queue,
+therefore size of the descriptor table and both available and
+used rings.
+
+The endianness of the registers follows the native endianness of
+the Guest. Writing to registers described as “R” and reading from
+registers described as “W” is not permitted and can cause
+undefined behavior.
+
+The device initialization is performed as described in [sub:Device-Initialization-Sequence]
+ with one exception: the Guest must notify the Host about its
+page size, writing the size in bytes to GuestPageSize register
+before the initialization is finished.
+
+The memory mapped virtio devices generate single interrupt only,
+therefore no special configuration is required.
+
+  Virtqueue Configuration
+
+The virtual queue configuration is performed in a similar way to
+the one described in [sec:Virtqueue-Configuration] with a few
+additional operations:
+
+  Select the queue writing its index (first queue is 0) to the
+  QueueSel register.
+
+  Check if the queue is not already in use: read QueuePFN
+  register, returned value should be zero (0x0).
+
+  Read maximum queue size (number of elements) from the
+  QueueNumMax register. If the returned value is zero (0x0) the
+  queue is not available.
+
+  Allocate and zero the queue pages in contiguous virtual memory,
+  aligning the Used Ring to an optimal boundary (usually page
+  size). Size of the allocated queue may be smaller than or equal
+  to the maximum size returned by the Host.
+
+  Notify the Host about the queue size by writing the size to
+  QueueNum register.
+
+  Notify the Host about the used alignment by writing its value
+  in bytes to QueueAlign register.
+
+  Write the physical number of the first page of the queue to the
+  QueuePFN register.
+
+The queue and the device are ready to begin normal operations
+now.
+
+  Device Operation
+
+The memory mapped virtio device behaves in the same way as
+described in [sec:Device-Operation], with the following
+exceptions:
+
+  The device is notified about new buffers available in a queue
+  by writing the queue index to register QueueNum instead of the
+  virtio header in PCI I/O space ([sub:Notifying-The-Device]).
+
+  The memory mapped virtio device is using single, dedicated
+  interrupt signal, which is raised when at least one of the
+  interrupts described in the InterruptStatus register
+  description is asserted. After receiving an interrupt, the
+  driver must read the InterruptStatus register to check what
+  caused the interrupt (see the register description). After the
+  interrupt is handled, the driver must acknowledge it by writing
+  a bit mask corresponding to the serviced interrupt to the
+  InterruptACK register.
+
diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile
deleted file mode 100644
index 3fa4d06..0000000
--- a/Documentation/vm/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# kbuild trick to avoid linker error. Can be omitted if a module is built.
-obj- := dummy.o
-
-# List of programs to build
-hostprogs-y := page-types hugepage-mmap hugepage-shm map_hugetlb
-
-# Tell kbuild to always build the programs
-always := $(hostprogs-y)
diff --git a/Documentation/vm/cleancache.txt b/Documentation/vm/cleancache.txt
index 36c367c..142fbb0 100644
--- a/Documentation/vm/cleancache.txt
+++ b/Documentation/vm/cleancache.txt
@@ -46,10 +46,11 @@ a negative return value indicates failure.  A "put_page" will copy a
 the pool id, a file key, and a page index into the file.  (The combination
 of a pool id, a file key, and an index is sometimes called a "handle".)
 A "get_page" will copy the page, if found, from cleancache into kernel memory.
-A "flush_page" will ensure the page no longer is present in cleancache;
-a "flush_inode" will flush all pages associated with the specified file;
-and, when a filesystem is unmounted, a "flush_fs" will flush all pages in
-all files specified by the given pool id and also surrender the pool id.
+An "invalidate_page" will ensure the page no longer is present in cleancache;
+an "invalidate_inode" will invalidate all pages associated with the specified
+file; and, when a filesystem is unmounted, an "invalidate_fs" will invalidate
+all pages in all files specified by the given pool id and also surrender
+the pool id.
 
 An "init_shared_fs", like init_fs, obtains a pool id but tells cleancache
 to treat the pool as shared using a 128-bit UUID as a key.  On systems
@@ -62,12 +63,12 @@ of the kernel (e.g. by "tools" that control cleancache).  Or a
 cleancache implementation can simply disable shared_init by always
 returning a negative value.
 
-If a get_page is successful on a non-shared pool, the page is flushed (thus
-making cleancache an "exclusive" cache).  On a shared pool, the page
-is NOT flushed on a successful get_page so that it remains accessible to
+If a get_page is successful on a non-shared pool, the page is invalidated
+(thus making cleancache an "exclusive" cache).  On a shared pool, the page
+is NOT invalidated on a successful get_page so that it remains accessible to
 other sharers.  The kernel is responsible for ensuring coherency between
 cleancache (shared or not), the page cache, and the filesystem, using
-cleancache flush operations as required.
+cleancache invalidate operations as required.
 
 Note that cleancache must enforce put-put-get coherency and get-get
 coherency.  For the former, if two puts are made to the same handle but
@@ -77,22 +78,22 @@ if a get for a given handle fails, subsequent gets for that handle will
 never succeed unless preceded by a successful put with that handle.
 
 Last, cleancache provides no SMP serialization guarantees; if two
-different Linux threads are simultaneously putting and flushing a page
+different Linux threads are simultaneously putting and invalidating a page
 with the same handle, the results are indeterminate.  Callers must
 lock the page to ensure serial behavior.
 
 CLEANCACHE PERFORMANCE METRICS
 
-Cleancache monitoring is done by sysfs files in the
-/sys/kernel/mm/cleancache directory.  The effectiveness of cleancache
+If properly configured, monitoring of cleancache is done via debugfs in
+the /sys/kernel/debug/mm/cleancache directory.  The effectiveness of cleancache
 can be measured (across all filesystems) with:
 
 succ_gets	- number of gets that were successful
 failed_gets	- number of gets that failed
 puts		- number of puts attempted (all "succeed")
-flushes		- number of flushes attempted
+invalidates	- number of invalidates attempted
 
-A backend implementatation may provide additional metrics.
+A backend implementation may provide additional metrics.
 
 FAQ
 
@@ -143,7 +144,7 @@ systems.
 
 The core hooks for cleancache in VFS are in most cases a single line
 and the minimum set are placed precisely where needed to maintain
-coherency (via cleancache_flush operations) between cleancache,
+coherency (via cleancache_invalidate operations) between cleancache,
 the page cache, and disk.  All hooks compile into nothingness if
 cleancache is config'ed off and turn into a function-pointer-
 compare-to-NULL if config'ed on but no backend claims the ops
@@ -184,15 +185,15 @@ or for real kernel-addressable RAM, it makes perfect sense for
 transcendent memory.
 
 4) Why is non-shared cleancache "exclusive"?  And where is the
-   page "flushed" after a "get"? (Minchan Kim)
+   page "invalidated" after a "get"? (Minchan Kim)
 
 The main reason is to free up space in transcendent memory and
-to avoid unnecessary cleancache_flush calls.  If you want inclusive,
+to avoid unnecessary cleancache_invalidate calls.  If you want inclusive,
 the page can be "put" immediately following the "get".  If
 put-after-get for inclusive becomes common, the interface could
-be easily extended to add a "get_no_flush" call.
+be easily extended to add a "get_no_invalidate" call.
 
-The flush is done by the cleancache backend implementation.
+The invalidate is done by the cleancache backend implementation.
 
 5) What's the performance impact?
 
@@ -222,7 +223,7 @@ Some points for a filesystem to consider:
   as tmpfs should not enable cleancache)
 - To ensure coherency/correctness, the FS must ensure that all
   file removal or truncation operations either go through VFS or
-  add hooks to do the equivalent cleancache "flush" operations
+  add hooks to do the equivalent cleancache "invalidate" operations
 - To ensure coherency/correctness, either inode numbers must
   be unique across the lifetime of the on-disk file OR the
   FS must provide an "encode_fh" function.
@@ -243,11 +244,11 @@ If cleancache would use the inode virtual address instead of
 inode/filehandle, the pool id could be eliminated.  But, this
 won't work because cleancache retains pagecache data pages
 persistently even when the inode has been pruned from the
-inode unused list, and only flushes the data page if the file
+inode unused list, and only invalidates the data page if the file
 gets removed/truncated.  So if cleancache used the inode kva,
 there would be potential coherency issues if/when the inode
 kva is reused for a different file.  Alternately, if cleancache
-flushed the pages when the inode kva was freed, much of the value
+invalidated the pages when the inode kva was freed, much of the value
 of cleancache would be lost because the cache of pages in cleanache
 is potentially much larger than the kernel pagecache and is most
 useful if the pages survive inode cache removal.
diff --git a/Documentation/vm/frontswap.txt b/Documentation/vm/frontswap.txt
new file mode 100644
index 0000000..5a1a00c
--- /dev/null
+++ b/Documentation/vm/frontswap.txt
@@ -0,0 +1,210 @@
+Frontswap provides a "transcendent memory" interface for swap pages.
+In some environments, dramatic performance savings may be obtained because
+swapped pages are saved in RAM (or a RAM-like device) instead of a swap disk.
+
+Frontswap is so named because it can be thought of as the opposite of
+a "backing" store for a swap device.  The storage is assumed to be
+a synchronous concurrency-safe page-oriented "pseudo-RAM device" conforming
+to the requirements of transcendent memory (such as Xen's "tmem", or
+in-kernel compressed memory, aka "zcache", or future RAM-like devices);
+this pseudo-RAM device is not directly accessible or addressable by the
+kernel and is of unknown and possibly time-varying size.  The driver
+links itself to frontswap by calling frontswap_register_ops to set the
+frontswap_ops funcs appropriately and the functions it provides must
+conform to certain policies as follows:
+
+An "init" prepares the device to receive frontswap pages associated
+with the specified swap device number (aka "type").  A "put_page" will
+copy the page to transcendent memory and associate it with the type and
+offset associated with the page. A "get_page" will copy the page, if found,
+from transcendent memory into kernel memory, but will NOT remove the page
+from from transcendent memory.  An "invalidate_page" will remove the page
+from transcendent memory and an "invalidate_area" will remove ALL pages
+associated with the swap type (e.g., like swapoff) and notify the "device"
+to refuse further puts with that swap type.
+
+Once a page is successfully put, a matching get on the page will normally
+succeed.  So when the kernel finds itself in a situation where it needs
+to swap out a page, it first attempts to use frontswap.  If the put returns
+success, the data has been successfully saved to transcendent memory and
+a disk write and, if the data is later read back, a disk read are avoided.
+If a put returns failure, transcendent memory has rejected the data, and the
+page can be written to swap as usual.
+
+Note that if a page is put and the page already exists in transcendent memory
+(a "duplicate" put), either the put succeeds and the data is overwritten,
+or the put fails AND the page is invalidated.  This ensures stale data may
+never be obtained from frontswap.
+
+If properly configured, monitoring of frontswap is done via debugfs in
+the /sys/kernel/debug/frontswap directory.  The effectiveness of
+frontswap can be measured (across all swap devices) with:
+
+failed_puts	- how many put attempts have failed
+gets		- how many gets were attempted (all should succeed)
+succ_puts	- how many put attempts have succeeded
+invalidates	- how many invalidates were attempted
+
+A backend implementation may provide additional metrics.
+
+FAQ
+
+1) Where's the value?
+
+When a workload starts swapping, performance falls through the floor.
+Frontswap significantly increases performance in many such workloads by
+providing a clean, dynamic interface to read and write swap pages to
+"transcendent memory" that is otherwise not directly addressable to the kernel.
+This interface is ideal when data is transformed to a different form
+and size (such as with compression) or secretly moved (as might be
+useful for write-balancing for some RAM-like devices).  Swap pages (and
+evicted page-cache pages) are a great use for this kind of slower-than-RAM-
+but-much-faster-than-disk "pseudo-RAM device" and the frontswap (and
+cleancache) interface to transcendent memory provides a nice way to read
+and write -- and indirectly "name" -- the pages.
+
+In the virtual case, the whole point of virtualization is to statistically
+multiplex physical resources acrosst the varying demands of multiple
+virtual machines.  This is really hard to do with RAM and efforts to do
+it well with no kernel changes have essentially failed (except in some
+well-publicized special-case workloads).  Frontswap -- and cleancache --
+with a fairly small impact on the kernel, provides a huge amount
+of flexibility for more dynamic, flexible RAM multiplexing.
+Specifically, the Xen Transcendent Memory backend allows otherwise
+"fallow" hypervisor-owned RAM to not only be "time-shared" between multiple
+virtual machines, but the pages can be compressed and deduplicated to
+optimize RAM utilization.  And when guest OS's are induced to surrender
+underutilized RAM (e.g. with "self-ballooning"), sudden unexpected
+memory pressure may result in swapping; frontswap allows those pages
+to be swapped to and from hypervisor RAM if overall host system memory
+conditions allow.
+
+2) Sure there may be performance advantages in some situations, but
+   what's the space/time overhead of frontswap?
+
+If CONFIG_FRONTSWAP is disabled, every frontswap hook compiles into
+nothingness and the only overhead is a few extra bytes per swapon'ed
+swap device.  If CONFIG_FRONTSWAP is enabled but no frontswap "backend"
+registers, there is one extra global variable compared to zero for
+every swap page read or written.  If CONFIG_FRONTSWAP is enabled
+AND a frontswap backend registers AND the backend fails every "put"
+request (i.e. provides no memory despite claiming it might),
+CPU overhead is still negligible -- and since every frontswap fail
+precedes a swap page write-to-disk, the system is highly likely
+to be I/O bound and using a small fraction of a percent of a CPU
+will be irrelevant anyway.
+
+As for space, if CONFIG_FRONTSWAP is enabled AND a frontswap backend
+registers, one bit is allocated for every swap page for every swap
+device that is swapon'd.  This is added to the EIGHT bits (which
+was sixteen until about 2.6.34) that the kernel already allocates
+for every swap page for every swap device that is swapon'd.  (Hugh
+Dickins has observed that frontswap could probably steal one of
+the existing eight bits, but let's worry about that minor optimization
+later.)  For very large swap disks (which are rare) on a standard
+4K pagesize, this is 1MB per 32GB swap.
+
+3) OK, how about a quick overview of what this frontswap patch does
+   in terms that a kernel hacker can grok?
+
+Let's assume that a frontswap "backend" has registered during
+kernel initialization; this registration indicates that this
+frontswap backend has access to some "memory" that is not directly
+accessible by the kernel.  Exactly how much memory it provides is
+entirely dynamic and random.
+
+Whenever a swap-device is swapon'd frontswap_init() is called,
+passing the swap device number (aka "type") as a parameter.
+This notifies frontswap to expect attempts to "put" swap pages
+associated with that number.
+
+Whenever the swap subsystem is readying a page to write to a swap
+device (c.f swap_writepage()), frontswap_put_page is called.  Frontswap
+consults with the frontswap backend and if the backend says it does NOT
+have room, frontswap_put_page returns -1 and the kernel swaps the page
+to the swap device as normal.  Note that the response from the frontswap
+backend is unpredictable to the kernel; it may choose to never accept a
+page, it could accept every ninth page, or it might accept every
+page.  But if the backend does accept a page, the data from the page
+has already been copied and associated with the type and offset,
+and the backend guarantees the persistence of the data.  In this case,
+frontswap sets a bit in the "frontswap_map" for the swap device
+corresponding to the page offset on the swap device to which it would
+otherwise have written the data.
+
+When the swap subsystem needs to swap-in a page (swap_readpage()),
+it first calls frontswap_get_page() which checks the frontswap_map to
+see if the page was earlier accepted by the frontswap backend.  If
+it was, the page of data is filled from the frontswap backend and
+the swap-in is complete.  If not, the normal swap-in code is
+executed to obtain the page of data from the real swap device.
+
+So every time the frontswap backend accepts a page, a swap device read
+and (potentially) a swap device write are replaced by a "frontswap backend
+put" and (possibly) a "frontswap backend get", which are presumably much
+faster.
+
+4) Can't frontswap be configured as a "special" swap device that is
+   just higher priority than any real swap device (e.g. like zswap)?
+
+No.  Recall that acceptance of any swap page by the frontswap
+backend is entirely unpredictable. This is critical to the definition
+of frontswap because it grants completely dynamic discretion to the
+backend.  But since any "put" might fail, there must always be a real
+slot on a real swap device to swap the page.  Thus frontswap must be
+implemented as a "shadow" to every swapon'd device with the potential
+capability of holding every page that the swap device might have held
+and the possibility that it might hold no pages at all.
+On the downside, this also means that frontswap cannot contain more
+pages than the total of swapon'd swap devices.  For example, if NO
+swap device is configured on some installation, frontswap is useless.
+
+Further, frontswap is entirely synchronous whereas a real swap
+device is, by definition, asynchronous and uses block I/O.  The
+block I/O layer is not only unnecessary, but may perform "optimizations"
+that are inappropriate for a RAM-oriented device including delaying
+the write of some pages for a significant amount of time.  Synchrony is
+required to ensure the dynamicity of the backend and to avoid thorny race
+conditions that would unnecessarily and greatly complicate frontswap
+and/or the block I/O subsystem.
+
+In a virtualized environment, the dynamicity allows the hypervisor
+(or host OS) to do "intelligent overcommit".  For example, it can
+choose to accept pages only until host-swapping might be imminent,
+then force guests to do their own swapping.  In zcache, "poorly"
+compressible pages can be rejected, where "poorly" can itself be defined
+dynamically depending on current memory constraints.
+
+5) Why this weird definition about "duplicate puts"?  If a page
+   has been previously successfully put, can't it always be
+   successfully overwritten?
+
+Nearly always it can, but no, sometimes it cannot.  Consider an example
+where data is compressed and the original 4K page has been compressed
+to 1K.  Now an attempt is made to overwrite the page with data that
+is non-compressible and so would take the entire 4K.  But the backend
+has no more space.  In this case, the put must be rejected.  Whenever
+frontswap rejects a put that would overwrite, it also must invalidate
+the old data and ensure that it is no longer accessible.  Since the
+swap subsystem then writes the new data to the read swap device,
+this is the correct course of action to ensure coherency.
+
+6) What is frontswap_shrink for?
+
+When the (non-frontswap) swap subsystem swaps out a page to a real
+swap device, that page is only taking up low-value pre-allocated disk
+space.  But if frontswap has placed a page in transcendent memory, that
+page may be taking up valuable real estate.  The frontswap_shrink
+routine allows code outside of the swap subsystem (such as Xen tmem
+or zcache or some future tmem backend) to force pages out of the memory
+managed by frontswap and back into kernel-addressable memory.
+
+7) Why does the frontswap patch create the new include file swapfile.h?
+
+The frontswap code depends on some swap-subsystem-internal data
+structures that have, over the years, moved back and forth between
+static and global.  This seemed a reasonable compromise:  Define
+them as global but declare them in a new include file that isn't
+included by the large number of source files that include swap.h.
+
+Dan Magenheimer, last updated September 12, 2011
diff --git a/Documentation/vm/hugepage-mmap.c b/Documentation/vm/hugepage-mmap.c
deleted file mode 100644
index db0dd9a..0000000
--- a/Documentation/vm/hugepage-mmap.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * hugepage-mmap:
- *
- * Example of using huge page memory in a user application using the mmap
- * system call.  Before running this application, make sure that the
- * administrator has mounted the hugetlbfs filesystem (on some directory
- * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
- * example, the app is requesting memory of size 256MB that is backed by
- * huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages.  That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required.  If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#define FILE_NAME "/mnt/hugepagefile"
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define FLAGS (MAP_SHARED | MAP_FIXED)
-#else
-#define ADDR (void *)(0x0UL)
-#define FLAGS (MAP_SHARED)
-#endif
-
-static void check_bytes(char *addr)
-{
-	printf("First hex is %x\n", *((unsigned int *)addr));
-}
-
-static void write_bytes(char *addr)
-{
-	unsigned long i;
-
-	for (i = 0; i < LENGTH; i++)
-		*(addr + i) = (char)i;
-}
-
-static void read_bytes(char *addr)
-{
-	unsigned long i;
-
-	check_bytes(addr);
-	for (i = 0; i < LENGTH; i++)
-		if (*(addr + i) != (char)i) {
-			printf("Mismatch at %lu\n", i);
-			break;
-		}
-}
-
-int main(void)
-{
-	void *addr;
-	int fd;
-
-	fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
-	if (fd < 0) {
-		perror("Open failed");
-		exit(1);
-	}
-
-	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
-	if (addr == MAP_FAILED) {
-		perror("mmap");
-		unlink(FILE_NAME);
-		exit(1);
-	}
-
-	printf("Returned address is %p\n", addr);
-	check_bytes(addr);
-	write_bytes(addr);
-	read_bytes(addr);
-
-	munmap(addr, LENGTH);
-	close(fd);
-	unlink(FILE_NAME);
-
-	return 0;
-}
diff --git a/Documentation/vm/hugepage-shm.c b/Documentation/vm/hugepage-shm.c
deleted file mode 100644
index 07956d8..0000000
--- a/Documentation/vm/hugepage-shm.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * hugepage-shm:
- *
- * Example of using huge page memory in a user application using Sys V shared
- * memory system calls.  In this example the app is requesting 256MB of
- * memory that is backed by huge pages.  The application uses the flag
- * SHM_HUGETLB in the shmget system call to inform the kernel that it is
- * requesting huge pages.
- *
- * For the ia64 architecture, the Linux kernel reserves Region number 4 for
- * huge pages.  That means that if one requires a fixed address, a huge page
- * aligned address starting with 0x800000... will be required.  If a fixed
- * address is not required, the kernel will select an address in the proper
- * range.
- * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
- *
- * Note: The default shared memory limit is quite low on many kernels,
- * you may need to increase it via:
- *
- * echo 268435456 > /proc/sys/kernel/shmmax
- *
- * This will increase the maximum size per shared memory segment to 256MB.
- * The other limit that you will hit eventually is shmall which is the
- * total amount of shared memory in pages. To set it to 16GB on a system
- * with a 4kB pagesize do:
- *
- * echo 4194304 > /proc/sys/kernel/shmall
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/mman.h>
-
-#ifndef SHM_HUGETLB
-#define SHM_HUGETLB 04000
-#endif
-
-#define LENGTH (256UL*1024*1024)
-
-#define dprintf(x)  printf(x)
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define SHMAT_FLAGS (SHM_RND)
-#else
-#define ADDR (void *)(0x0UL)
-#define SHMAT_FLAGS (0)
-#endif
-
-int main(void)
-{
-	int shmid;
-	unsigned long i;
-	char *shmaddr;
-
-	if ((shmid = shmget(2, LENGTH,
-			    SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 0) {
-		perror("shmget");
-		exit(1);
-	}
-	printf("shmid: 0x%x\n", shmid);
-
-	shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
-	if (shmaddr == (char *)-1) {
-		perror("Shared memory attach failure");
-		shmctl(shmid, IPC_RMID, NULL);
-		exit(2);
-	}
-	printf("shmaddr: %p\n", shmaddr);
-
-	dprintf("Starting the writes:\n");
-	for (i = 0; i < LENGTH; i++) {
-		shmaddr[i] = (char)(i);
-		if (!(i % (1024 * 1024)))
-			dprintf(".");
-	}
-	dprintf("\n");
-
-	dprintf("Starting the Check...");
-	for (i = 0; i < LENGTH; i++)
-		if (shmaddr[i] != (char)i)
-			printf("\nIndex %lu mismatched\n", i);
-	dprintf("Done.\n");
-
-	if (shmdt((const void *)shmaddr) != 0) {
-		perror("Detach failure");
-		shmctl(shmid, IPC_RMID, NULL);
-		exit(3);
-	}
-
-	shmctl(shmid, IPC_RMID, NULL);
-
-	return 0;
-}
diff --git a/Documentation/vm/map_hugetlb.c b/Documentation/vm/map_hugetlb.c
deleted file mode 100644
index eda1a6d..0000000
--- a/Documentation/vm/map_hugetlb.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Example of using hugepage memory in a user application using the mmap
- * system call with MAP_HUGETLB flag.  Before running this program make
- * sure the administrator has allocated enough default sized huge pages
- * to cover the 256 MB allocation.
- *
- * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
- * That means the addresses starting with 0x800000... will need to be
- * specified.  Specifying a fixed address is not required on ppc64, i386
- * or x86_64.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-
-#define LENGTH (256UL*1024*1024)
-#define PROTECTION (PROT_READ | PROT_WRITE)
-
-#ifndef MAP_HUGETLB
-#define MAP_HUGETLB 0x40000 /* arch specific */
-#endif
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define ADDR (void *)(0x8000000000000000UL)
-#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
-#else
-#define ADDR (void *)(0x0UL)
-#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
-#endif
-
-static void check_bytes(char *addr)
-{
-	printf("First hex is %x\n", *((unsigned int *)addr));
-}
-
-static void write_bytes(char *addr)
-{
-	unsigned long i;
-
-	for (i = 0; i < LENGTH; i++)
-		*(addr + i) = (char)i;
-}
-
-static void read_bytes(char *addr)
-{
-	unsigned long i;
-
-	check_bytes(addr);
-	for (i = 0; i < LENGTH; i++)
-		if (*(addr + i) != (char)i) {
-			printf("Mismatch at %lu\n", i);
-			break;
-		}
-}
-
-int main(void)
-{
-	void *addr;
-
-	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
-	if (addr == MAP_FAILED) {
-		perror("mmap");
-		exit(1);
-	}
-
-	printf("Returned address is %p\n", addr);
-	check_bytes(addr);
-	write_bytes(addr);
-	read_bytes(addr);
-
-	munmap(addr, LENGTH);
-
-	return 0;
-}
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c
deleted file mode 100644
index 7445caa..0000000
--- a/Documentation/vm/page-types.c
+++ /dev/null
@@ -1,1100 +0,0 @@
-/*
- * page-types: Tool for querying page flags
- *
- * 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; version 2.
- *
- * 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 find a copy of v2 of the GNU General Public License somewhere on
- * your Linux system; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * Copyright (C) 2009 Intel corporation
- *
- * Authors: Wu Fengguang <fengguang.wu@intel.com>
- */
-
-#define _LARGEFILE64_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <string.h>
-#include <getopt.h>
-#include <limits.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/statfs.h>
-#include "../../include/linux/magic.h"
-
-
-#ifndef MAX_PATH
-# define MAX_PATH 256
-#endif
-
-#ifndef STR
-# define _STR(x) #x
-# define STR(x) _STR(x)
-#endif
-
-/*
- * pagemap kernel ABI bits
- */
-
-#define PM_ENTRY_BYTES      sizeof(uint64_t)
-#define PM_STATUS_BITS      3
-#define PM_STATUS_OFFSET    (64 - PM_STATUS_BITS)
-#define PM_STATUS_MASK      (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
-#define PM_STATUS(nr)       (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK)
-#define PM_PSHIFT_BITS      6
-#define PM_PSHIFT_OFFSET    (PM_STATUS_OFFSET - PM_PSHIFT_BITS)
-#define PM_PSHIFT_MASK      (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET)
-#define PM_PSHIFT(x)        (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK)
-#define PM_PFRAME_MASK      ((1LL << PM_PSHIFT_OFFSET) - 1)
-#define PM_PFRAME(x)        ((x) & PM_PFRAME_MASK)
-
-#define PM_PRESENT          PM_STATUS(4LL)
-#define PM_SWAP             PM_STATUS(2LL)
-
-
-/*
- * kernel page flags
- */
-
-#define KPF_BYTES		8
-#define PROC_KPAGEFLAGS		"/proc/kpageflags"
-
-/* copied from kpageflags_read() */
-#define KPF_LOCKED		0
-#define KPF_ERROR		1
-#define KPF_REFERENCED		2
-#define KPF_UPTODATE		3
-#define KPF_DIRTY		4
-#define KPF_LRU			5
-#define KPF_ACTIVE		6
-#define KPF_SLAB		7
-#define KPF_WRITEBACK		8
-#define KPF_RECLAIM		9
-#define KPF_BUDDY		10
-
-/* [11-20] new additions in 2.6.31 */
-#define KPF_MMAP		11
-#define KPF_ANON		12
-#define KPF_SWAPCACHE		13
-#define KPF_SWAPBACKED		14
-#define KPF_COMPOUND_HEAD	15
-#define KPF_COMPOUND_TAIL	16
-#define KPF_HUGE		17
-#define KPF_UNEVICTABLE		18
-#define KPF_HWPOISON		19
-#define KPF_NOPAGE		20
-#define KPF_KSM			21
-
-/* [32-] kernel hacking assistances */
-#define KPF_RESERVED		32
-#define KPF_MLOCKED		33
-#define KPF_MAPPEDTODISK	34
-#define KPF_PRIVATE		35
-#define KPF_PRIVATE_2		36
-#define KPF_OWNER_PRIVATE	37
-#define KPF_ARCH		38
-#define KPF_UNCACHED		39
-
-/* [48-] take some arbitrary free slots for expanding overloaded flags
- * not part of kernel API
- */
-#define KPF_READAHEAD		48
-#define KPF_SLOB_FREE		49
-#define KPF_SLUB_FROZEN		50
-#define KPF_SLUB_DEBUG		51
-
-#define KPF_ALL_BITS		((uint64_t)~0ULL)
-#define KPF_HACKERS_BITS	(0xffffULL << 32)
-#define KPF_OVERLOADED_BITS	(0xffffULL << 48)
-#define BIT(name)		(1ULL << KPF_##name)
-#define BITS_COMPOUND		(BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL))
-
-static const char *page_flag_names[] = {
-	[KPF_LOCKED]		= "L:locked",
-	[KPF_ERROR]		= "E:error",
-	[KPF_REFERENCED]	= "R:referenced",
-	[KPF_UPTODATE]		= "U:uptodate",
-	[KPF_DIRTY]		= "D:dirty",
-	[KPF_LRU]		= "l:lru",
-	[KPF_ACTIVE]		= "A:active",
-	[KPF_SLAB]		= "S:slab",
-	[KPF_WRITEBACK]		= "W:writeback",
-	[KPF_RECLAIM]		= "I:reclaim",
-	[KPF_BUDDY]		= "B:buddy",
-
-	[KPF_MMAP]		= "M:mmap",
-	[KPF_ANON]		= "a:anonymous",
-	[KPF_SWAPCACHE]		= "s:swapcache",
-	[KPF_SWAPBACKED]	= "b:swapbacked",
-	[KPF_COMPOUND_HEAD]	= "H:compound_head",
-	[KPF_COMPOUND_TAIL]	= "T:compound_tail",
-	[KPF_HUGE]		= "G:huge",
-	[KPF_UNEVICTABLE]	= "u:unevictable",
-	[KPF_HWPOISON]		= "X:hwpoison",
-	[KPF_NOPAGE]		= "n:nopage",
-	[KPF_KSM]		= "x:ksm",
-
-	[KPF_RESERVED]		= "r:reserved",
-	[KPF_MLOCKED]		= "m:mlocked",
-	[KPF_MAPPEDTODISK]	= "d:mappedtodisk",
-	[KPF_PRIVATE]		= "P:private",
-	[KPF_PRIVATE_2]		= "p:private_2",
-	[KPF_OWNER_PRIVATE]	= "O:owner_private",
-	[KPF_ARCH]		= "h:arch",
-	[KPF_UNCACHED]		= "c:uncached",
-
-	[KPF_READAHEAD]		= "I:readahead",
-	[KPF_SLOB_FREE]		= "P:slob_free",
-	[KPF_SLUB_FROZEN]	= "A:slub_frozen",
-	[KPF_SLUB_DEBUG]	= "E:slub_debug",
-};
-
-
-static const char *debugfs_known_mountpoints[] = {
-	"/sys/kernel/debug",
-	"/debug",
-	0,
-};
-
-/*
- * data structures
- */
-
-static int		opt_raw;	/* for kernel developers */
-static int		opt_list;	/* list pages (in ranges) */
-static int		opt_no_summary;	/* don't show summary */
-static pid_t		opt_pid;	/* process to walk */
-
-#define MAX_ADDR_RANGES	1024
-static int		nr_addr_ranges;
-static unsigned long	opt_offset[MAX_ADDR_RANGES];
-static unsigned long	opt_size[MAX_ADDR_RANGES];
-
-#define MAX_VMAS	10240
-static int		nr_vmas;
-static unsigned long	pg_start[MAX_VMAS];
-static unsigned long	pg_end[MAX_VMAS];
-
-#define MAX_BIT_FILTERS	64
-static int		nr_bit_filters;
-static uint64_t		opt_mask[MAX_BIT_FILTERS];
-static uint64_t		opt_bits[MAX_BIT_FILTERS];
-
-static int		page_size;
-
-static int		pagemap_fd;
-static int		kpageflags_fd;
-
-static int		opt_hwpoison;
-static int		opt_unpoison;
-
-static char		hwpoison_debug_fs[MAX_PATH+1];
-static int		hwpoison_inject_fd;
-static int		hwpoison_forget_fd;
-
-#define HASH_SHIFT	13
-#define HASH_SIZE	(1 << HASH_SHIFT)
-#define HASH_MASK	(HASH_SIZE - 1)
-#define HASH_KEY(flags)	(flags & HASH_MASK)
-
-static unsigned long	total_pages;
-static unsigned long	nr_pages[HASH_SIZE];
-static uint64_t 	page_flags[HASH_SIZE];
-
-
-/*
- * helper functions
- */
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-
-#define min_t(type, x, y) ({			\
-	type __min1 = (x);			\
-	type __min2 = (y);			\
-	__min1 < __min2 ? __min1 : __min2; })
-
-#define max_t(type, x, y) ({			\
-	type __max1 = (x);			\
-	type __max2 = (y);			\
-	__max1 > __max2 ? __max1 : __max2; })
-
-static unsigned long pages2mb(unsigned long pages)
-{
-	return (pages * page_size) >> 20;
-}
-
-static void fatal(const char *x, ...)
-{
-	va_list ap;
-
-	va_start(ap, x);
-	vfprintf(stderr, x, ap);
-	va_end(ap);
-	exit(EXIT_FAILURE);
-}
-
-static int checked_open(const char *pathname, int flags)
-{
-	int fd = open(pathname, flags);
-
-	if (fd < 0) {
-		perror(pathname);
-		exit(EXIT_FAILURE);
-	}
-
-	return fd;
-}
-
-/*
- * pagemap/kpageflags routines
- */
-
-static unsigned long do_u64_read(int fd, char *name,
-				 uint64_t *buf,
-				 unsigned long index,
-				 unsigned long count)
-{
-	long bytes;
-
-	if (index > ULONG_MAX / 8)
-		fatal("index overflow: %lu\n", index);
-
-	if (lseek(fd, index * 8, SEEK_SET) < 0) {
-		perror(name);
-		exit(EXIT_FAILURE);
-	}
-
-	bytes = read(fd, buf, count * 8);
-	if (bytes < 0) {
-		perror(name);
-		exit(EXIT_FAILURE);
-	}
-	if (bytes % 8)
-		fatal("partial read: %lu bytes\n", bytes);
-
-	return bytes / 8;
-}
-
-static unsigned long kpageflags_read(uint64_t *buf,
-				     unsigned long index,
-				     unsigned long pages)
-{
-	return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages);
-}
-
-static unsigned long pagemap_read(uint64_t *buf,
-				  unsigned long index,
-				  unsigned long pages)
-{
-	return do_u64_read(pagemap_fd, "/proc/pid/pagemap", buf, index, pages);
-}
-
-static unsigned long pagemap_pfn(uint64_t val)
-{
-	unsigned long pfn;
-
-	if (val & PM_PRESENT)
-		pfn = PM_PFRAME(val);
-	else
-		pfn = 0;
-
-	return pfn;
-}
-
-
-/*
- * page flag names
- */
-
-static char *page_flag_name(uint64_t flags)
-{
-	static char buf[65];
-	int present;
-	int i, j;
-
-	for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
-		present = (flags >> i) & 1;
-		if (!page_flag_names[i]) {
-			if (present)
-				fatal("unknown flag bit %d\n", i);
-			continue;
-		}
-		buf[j++] = present ? page_flag_names[i][0] : '_';
-	}
-
-	return buf;
-}
-
-static char *page_flag_longname(uint64_t flags)
-{
-	static char buf[1024];
-	int i, n;
-
-	for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++) {
-		if (!page_flag_names[i])
-			continue;
-		if ((flags >> i) & 1)
-			n += snprintf(buf + n, sizeof(buf) - n, "%s,",
-					page_flag_names[i] + 2);
-	}
-	if (n)
-		n--;
-	buf[n] = '\0';
-
-	return buf;
-}
-
-
-/*
- * page list and summary
- */
-
-static void show_page_range(unsigned long voffset,
-			    unsigned long offset, uint64_t flags)
-{
-	static uint64_t      flags0;
-	static unsigned long voff;
-	static unsigned long index;
-	static unsigned long count;
-
-	if (flags == flags0 && offset == index + count &&
-	    (!opt_pid || voffset == voff + count)) {
-		count++;
-		return;
-	}
-
-	if (count) {
-		if (opt_pid)
-			printf("%lx\t", voff);
-		printf("%lx\t%lx\t%s\n",
-				index, count, page_flag_name(flags0));
-	}
-
-	flags0 = flags;
-	index  = offset;
-	voff   = voffset;
-	count  = 1;
-}
-
-static void show_page(unsigned long voffset,
-		      unsigned long offset, uint64_t flags)
-{
-	if (opt_pid)
-		printf("%lx\t", voffset);
-	printf("%lx\t%s\n", offset, page_flag_name(flags));
-}
-
-static void show_summary(void)
-{
-	int i;
-
-	printf("             flags\tpage-count       MB"
-		"  symbolic-flags\t\t\tlong-symbolic-flags\n");
-
-	for (i = 0; i < ARRAY_SIZE(nr_pages); i++) {
-		if (nr_pages[i])
-			printf("0x%016llx\t%10lu %8lu  %s\t%s\n",
-				(unsigned long long)page_flags[i],
-				nr_pages[i],
-				pages2mb(nr_pages[i]),
-				page_flag_name(page_flags[i]),
-				page_flag_longname(page_flags[i]));
-	}
-
-	printf("             total\t%10lu %8lu\n",
-			total_pages, pages2mb(total_pages));
-}
-
-
-/*
- * page flag filters
- */
-
-static int bit_mask_ok(uint64_t flags)
-{
-	int i;
-
-	for (i = 0; i < nr_bit_filters; i++) {
-		if (opt_bits[i] == KPF_ALL_BITS) {
-			if ((flags & opt_mask[i]) == 0)
-				return 0;
-		} else {
-			if ((flags & opt_mask[i]) != opt_bits[i])
-				return 0;
-		}
-	}
-
-	return 1;
-}
-
-static uint64_t expand_overloaded_flags(uint64_t flags)
-{
-	/* SLOB/SLUB overload several page flags */
-	if (flags & BIT(SLAB)) {
-		if (flags & BIT(PRIVATE))
-			flags ^= BIT(PRIVATE) | BIT(SLOB_FREE);
-		if (flags & BIT(ACTIVE))
-			flags ^= BIT(ACTIVE) | BIT(SLUB_FROZEN);
-		if (flags & BIT(ERROR))
-			flags ^= BIT(ERROR) | BIT(SLUB_DEBUG);
-	}
-
-	/* PG_reclaim is overloaded as PG_readahead in the read path */
-	if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM))
-		flags ^= BIT(RECLAIM) | BIT(READAHEAD);
-
-	return flags;
-}
-
-static uint64_t well_known_flags(uint64_t flags)
-{
-	/* hide flags intended only for kernel hacker */
-	flags &= ~KPF_HACKERS_BITS;
-
-	/* hide non-hugeTLB compound pages */
-	if ((flags & BITS_COMPOUND) && !(flags & BIT(HUGE)))
-		flags &= ~BITS_COMPOUND;
-
-	return flags;
-}
-
-static uint64_t kpageflags_flags(uint64_t flags)
-{
-	flags = expand_overloaded_flags(flags);
-
-	if (!opt_raw)
-		flags = well_known_flags(flags);
-
-	return flags;
-}
-
-/* verify that a mountpoint is actually a debugfs instance */
-static int debugfs_valid_mountpoint(const char *debugfs)
-{
-	struct statfs st_fs;
-
-	if (statfs(debugfs, &st_fs) < 0)
-		return -ENOENT;
-	else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
-		return -ENOENT;
-
-	return 0;
-}
-
-/* find the path to the mounted debugfs */
-static const char *debugfs_find_mountpoint(void)
-{
-	const char **ptr;
-	char type[100];
-	FILE *fp;
-
-	ptr = debugfs_known_mountpoints;
-	while (*ptr) {
-		if (debugfs_valid_mountpoint(*ptr) == 0) {
-			strcpy(hwpoison_debug_fs, *ptr);
-			return hwpoison_debug_fs;
-		}
-		ptr++;
-	}
-
-	/* give up and parse /proc/mounts */
-	fp = fopen("/proc/mounts", "r");
-	if (fp == NULL)
-		perror("Can't open /proc/mounts for read");
-
-	while (fscanf(fp, "%*s %"
-		      STR(MAX_PATH)
-		      "s %99s %*s %*d %*d\n",
-		      hwpoison_debug_fs, type) == 2) {
-		if (strcmp(type, "debugfs") == 0)
-			break;
-	}
-	fclose(fp);
-
-	if (strcmp(type, "debugfs") != 0)
-		return NULL;
-
-	return hwpoison_debug_fs;
-}
-
-/* mount the debugfs somewhere if it's not mounted */
-
-static void debugfs_mount(void)
-{
-	const char **ptr;
-
-	/* see if it's already mounted */
-	if (debugfs_find_mountpoint())
-		return;
-
-	ptr = debugfs_known_mountpoints;
-	while (*ptr) {
-		if (mount(NULL, *ptr, "debugfs", 0, NULL) == 0) {
-			/* save the mountpoint */
-			strcpy(hwpoison_debug_fs, *ptr);
-			break;
-		}
-		ptr++;
-	}
-
-	if (*ptr == NULL) {
-		perror("mount debugfs");
-		exit(EXIT_FAILURE);
-	}
-}
-
-/*
- * page actions
- */
-
-static void prepare_hwpoison_fd(void)
-{
-	char buf[MAX_PATH + 1];
-
-	debugfs_mount();
-
-	if (opt_hwpoison && !hwpoison_inject_fd) {
-		snprintf(buf, MAX_PATH, "%s/hwpoison/corrupt-pfn",
-			hwpoison_debug_fs);
-		hwpoison_inject_fd = checked_open(buf, O_WRONLY);
-	}
-
-	if (opt_unpoison && !hwpoison_forget_fd) {
-		snprintf(buf, MAX_PATH, "%s/hwpoison/unpoison-pfn",
-			hwpoison_debug_fs);
-		hwpoison_forget_fd = checked_open(buf, O_WRONLY);
-	}
-}
-
-static int hwpoison_page(unsigned long offset)
-{
-	char buf[100];
-	int len;
-
-	len = sprintf(buf, "0x%lx\n", offset);
-	len = write(hwpoison_inject_fd, buf, len);
-	if (len < 0) {
-		perror("hwpoison inject");
-		return len;
-	}
-	return 0;
-}
-
-static int unpoison_page(unsigned long offset)
-{
-	char buf[100];
-	int len;
-
-	len = sprintf(buf, "0x%lx\n", offset);
-	len = write(hwpoison_forget_fd, buf, len);
-	if (len < 0) {
-		perror("hwpoison forget");
-		return len;
-	}
-	return 0;
-}
-
-/*
- * page frame walker
- */
-
-static int hash_slot(uint64_t flags)
-{
-	int k = HASH_KEY(flags);
-	int i;
-
-	/* Explicitly reserve slot 0 for flags 0: the following logic
-	 * cannot distinguish an unoccupied slot from slot (flags==0).
-	 */
-	if (flags == 0)
-		return 0;
-
-	/* search through the remaining (HASH_SIZE-1) slots */
-	for (i = 1; i < ARRAY_SIZE(page_flags); i++, k++) {
-		if (!k || k >= ARRAY_SIZE(page_flags))
-			k = 1;
-		if (page_flags[k] == 0) {
-			page_flags[k] = flags;
-			return k;
-		}
-		if (page_flags[k] == flags)
-			return k;
-	}
-
-	fatal("hash table full: bump up HASH_SHIFT?\n");
-	exit(EXIT_FAILURE);
-}
-
-static void add_page(unsigned long voffset,
-		     unsigned long offset, uint64_t flags)
-{
-	flags = kpageflags_flags(flags);
-
-	if (!bit_mask_ok(flags))
-		return;
-
-	if (opt_hwpoison)
-		hwpoison_page(offset);
-	if (opt_unpoison)
-		unpoison_page(offset);
-
-	if (opt_list == 1)
-		show_page_range(voffset, offset, flags);
-	else if (opt_list == 2)
-		show_page(voffset, offset, flags);
-
-	nr_pages[hash_slot(flags)]++;
-	total_pages++;
-}
-
-#define KPAGEFLAGS_BATCH	(64 << 10)	/* 64k pages */
-static void walk_pfn(unsigned long voffset,
-		     unsigned long index,
-		     unsigned long count)
-{
-	uint64_t buf[KPAGEFLAGS_BATCH];
-	unsigned long batch;
-	long pages;
-	unsigned long i;
-
-	while (count) {
-		batch = min_t(unsigned long, count, KPAGEFLAGS_BATCH);
-		pages = kpageflags_read(buf, index, batch);
-		if (pages == 0)
-			break;
-
-		for (i = 0; i < pages; i++)
-			add_page(voffset + i, index + i, buf[i]);
-
-		index += pages;
-		count -= pages;
-	}
-}
-
-#define PAGEMAP_BATCH	(64 << 10)
-static void walk_vma(unsigned long index, unsigned long count)
-{
-	uint64_t buf[PAGEMAP_BATCH];
-	unsigned long batch;
-	unsigned long pages;
-	unsigned long pfn;
-	unsigned long i;
-
-	while (count) {
-		batch = min_t(unsigned long, count, PAGEMAP_BATCH);
-		pages = pagemap_read(buf, index, batch);
-		if (pages == 0)
-			break;
-
-		for (i = 0; i < pages; i++) {
-			pfn = pagemap_pfn(buf[i]);
-			if (pfn)
-				walk_pfn(index + i, pfn, 1);
-		}
-
-		index += pages;
-		count -= pages;
-	}
-}
-
-static void walk_task(unsigned long index, unsigned long count)
-{
-	const unsigned long end = index + count;
-	unsigned long start;
-	int i = 0;
-
-	while (index < end) {
-
-		while (pg_end[i] <= index)
-			if (++i >= nr_vmas)
-				return;
-		if (pg_start[i] >= end)
-			return;
-
-		start = max_t(unsigned long, pg_start[i], index);
-		index = min_t(unsigned long, pg_end[i], end);
-
-		assert(start < index);
-		walk_vma(start, index - start);
-	}
-}
-
-static void add_addr_range(unsigned long offset, unsigned long size)
-{
-	if (nr_addr_ranges >= MAX_ADDR_RANGES)
-		fatal("too many addr ranges\n");
-
-	opt_offset[nr_addr_ranges] = offset;
-	opt_size[nr_addr_ranges] = min_t(unsigned long, size, ULONG_MAX-offset);
-	nr_addr_ranges++;
-}
-
-static void walk_addr_ranges(void)
-{
-	int i;
-
-	kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
-
-	if (!nr_addr_ranges)
-		add_addr_range(0, ULONG_MAX);
-
-	for (i = 0; i < nr_addr_ranges; i++)
-		if (!opt_pid)
-			walk_pfn(0, opt_offset[i], opt_size[i]);
-		else
-			walk_task(opt_offset[i], opt_size[i]);
-
-	close(kpageflags_fd);
-}
-
-
-/*
- * user interface
- */
-
-static const char *page_flag_type(uint64_t flag)
-{
-	if (flag & KPF_HACKERS_BITS)
-		return "(r)";
-	if (flag & KPF_OVERLOADED_BITS)
-		return "(o)";
-	return "   ";
-}
-
-static void usage(void)
-{
-	int i, j;
-
-	printf(
-"page-types [options]\n"
-"            -r|--raw                   Raw mode, for kernel developers\n"
-"            -d|--describe flags        Describe flags\n"
-"            -a|--addr    addr-spec     Walk a range of pages\n"
-"            -b|--bits    bits-spec     Walk pages with specified bits\n"
-"            -p|--pid     pid           Walk process address space\n"
-#if 0 /* planned features */
-"            -f|--file    filename      Walk file address space\n"
-#endif
-"            -l|--list                  Show page details in ranges\n"
-"            -L|--list-each             Show page details one by one\n"
-"            -N|--no-summary            Don't show summary info\n"
-"            -X|--hwpoison              hwpoison pages\n"
-"            -x|--unpoison              unpoison pages\n"
-"            -h|--help                  Show this usage message\n"
-"flags:\n"
-"            0x10                       bitfield format, e.g.\n"
-"            anon                       bit-name, e.g.\n"
-"            0x10,anon                  comma-separated list, e.g.\n"
-"addr-spec:\n"
-"            N                          one page at offset N (unit: pages)\n"
-"            N+M                        pages range from N to N+M-1\n"
-"            N,M                        pages range from N to M-1\n"
-"            N,                         pages range from N to end\n"
-"            ,M                         pages range from 0 to M-1\n"
-"bits-spec:\n"
-"            bit1,bit2                  (flags & (bit1|bit2)) != 0\n"
-"            bit1,bit2=bit1             (flags & (bit1|bit2)) == bit1\n"
-"            bit1,~bit2                 (flags & (bit1|bit2)) == bit1\n"
-"            =bit1,bit2                 flags == (bit1|bit2)\n"
-"bit-names:\n"
-	);
-
-	for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
-		if (!page_flag_names[i])
-			continue;
-		printf("%16s%s", page_flag_names[i] + 2,
-				 page_flag_type(1ULL << i));
-		if (++j > 3) {
-			j = 0;
-			putchar('\n');
-		}
-	}
-	printf("\n                                   "
-		"(r) raw mode bits  (o) overloaded bits\n");
-}
-
-static unsigned long long parse_number(const char *str)
-{
-	unsigned long long n;
-
-	n = strtoll(str, NULL, 0);
-
-	if (n == 0 && str[0] != '0')
-		fatal("invalid name or number: %s\n", str);
-
-	return n;
-}
-
-static void parse_pid(const char *str)
-{
-	FILE *file;
-	char buf[5000];
-
-	opt_pid = parse_number(str);
-
-	sprintf(buf, "/proc/%d/pagemap", opt_pid);
-	pagemap_fd = checked_open(buf, O_RDONLY);
-
-	sprintf(buf, "/proc/%d/maps", opt_pid);
-	file = fopen(buf, "r");
-	if (!file) {
-		perror(buf);
-		exit(EXIT_FAILURE);
-	}
-
-	while (fgets(buf, sizeof(buf), file) != NULL) {
-		unsigned long vm_start;
-		unsigned long vm_end;
-		unsigned long long pgoff;
-		int major, minor;
-		char r, w, x, s;
-		unsigned long ino;
-		int n;
-
-		n = sscanf(buf, "%lx-%lx %c%c%c%c %llx %x:%x %lu",
-			   &vm_start,
-			   &vm_end,
-			   &r, &w, &x, &s,
-			   &pgoff,
-			   &major, &minor,
-			   &ino);
-		if (n < 10) {
-			fprintf(stderr, "unexpected line: %s\n", buf);
-			continue;
-		}
-		pg_start[nr_vmas] = vm_start / page_size;
-		pg_end[nr_vmas] = vm_end / page_size;
-		if (++nr_vmas >= MAX_VMAS) {
-			fprintf(stderr, "too many VMAs\n");
-			break;
-		}
-	}
-	fclose(file);
-}
-
-static void parse_file(const char *name)
-{
-}
-
-static void parse_addr_range(const char *optarg)
-{
-	unsigned long offset;
-	unsigned long size;
-	char *p;
-
-	p = strchr(optarg, ',');
-	if (!p)
-		p = strchr(optarg, '+');
-
-	if (p == optarg) {
-		offset = 0;
-		size   = parse_number(p + 1);
-	} else if (p) {
-		offset = parse_number(optarg);
-		if (p[1] == '\0')
-			size = ULONG_MAX;
-		else {
-			size = parse_number(p + 1);
-			if (*p == ',') {
-				if (size < offset)
-					fatal("invalid range: %lu,%lu\n",
-							offset, size);
-				size -= offset;
-			}
-		}
-	} else {
-		offset = parse_number(optarg);
-		size   = 1;
-	}
-
-	add_addr_range(offset, size);
-}
-
-static void add_bits_filter(uint64_t mask, uint64_t bits)
-{
-	if (nr_bit_filters >= MAX_BIT_FILTERS)
-		fatal("too much bit filters\n");
-
-	opt_mask[nr_bit_filters] = mask;
-	opt_bits[nr_bit_filters] = bits;
-	nr_bit_filters++;
-}
-
-static uint64_t parse_flag_name(const char *str, int len)
-{
-	int i;
-
-	if (!*str || !len)
-		return 0;
-
-	if (len <= 8 && !strncmp(str, "compound", len))
-		return BITS_COMPOUND;
-
-	for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) {
-		if (!page_flag_names[i])
-			continue;
-		if (!strncmp(str, page_flag_names[i] + 2, len))
-			return 1ULL << i;
-	}
-
-	return parse_number(str);
-}
-
-static uint64_t parse_flag_names(const char *str, int all)
-{
-	const char *p    = str;
-	uint64_t   flags = 0;
-
-	while (1) {
-		if (*p == ',' || *p == '=' || *p == '\0') {
-			if ((*str != '~') || (*str == '~' && all && *++str))
-				flags |= parse_flag_name(str, p - str);
-			if (*p != ',')
-				break;
-			str = p + 1;
-		}
-		p++;
-	}
-
-	return flags;
-}
-
-static void parse_bits_mask(const char *optarg)
-{
-	uint64_t mask;
-	uint64_t bits;
-	const char *p;
-
-	p = strchr(optarg, '=');
-	if (p == optarg) {
-		mask = KPF_ALL_BITS;
-		bits = parse_flag_names(p + 1, 0);
-	} else if (p) {
-		mask = parse_flag_names(optarg, 0);
-		bits = parse_flag_names(p + 1, 0);
-	} else if (strchr(optarg, '~')) {
-		mask = parse_flag_names(optarg, 1);
-		bits = parse_flag_names(optarg, 0);
-	} else {
-		mask = parse_flag_names(optarg, 0);
-		bits = KPF_ALL_BITS;
-	}
-
-	add_bits_filter(mask, bits);
-}
-
-static void describe_flags(const char *optarg)
-{
-	uint64_t flags = parse_flag_names(optarg, 0);
-
-	printf("0x%016llx\t%s\t%s\n",
-		(unsigned long long)flags,
-		page_flag_name(flags),
-		page_flag_longname(flags));
-}
-
-static const struct option opts[] = {
-	{ "raw"       , 0, NULL, 'r' },
-	{ "pid"       , 1, NULL, 'p' },
-	{ "file"      , 1, NULL, 'f' },
-	{ "addr"      , 1, NULL, 'a' },
-	{ "bits"      , 1, NULL, 'b' },
-	{ "describe"  , 1, NULL, 'd' },
-	{ "list"      , 0, NULL, 'l' },
-	{ "list-each" , 0, NULL, 'L' },
-	{ "no-summary", 0, NULL, 'N' },
-	{ "hwpoison"  , 0, NULL, 'X' },
-	{ "unpoison"  , 0, NULL, 'x' },
-	{ "help"      , 0, NULL, 'h' },
-	{ NULL        , 0, NULL, 0 }
-};
-
-int main(int argc, char *argv[])
-{
-	int c;
-
-	page_size = getpagesize();
-
-	while ((c = getopt_long(argc, argv,
-				"rp:f:a:b:d:lLNXxh", opts, NULL)) != -1) {
-		switch (c) {
-		case 'r':
-			opt_raw = 1;
-			break;
-		case 'p':
-			parse_pid(optarg);
-			break;
-		case 'f':
-			parse_file(optarg);
-			break;
-		case 'a':
-			parse_addr_range(optarg);
-			break;
-		case 'b':
-			parse_bits_mask(optarg);
-			break;
-		case 'd':
-			describe_flags(optarg);
-			exit(0);
-		case 'l':
-			opt_list = 1;
-			break;
-		case 'L':
-			opt_list = 2;
-			break;
-		case 'N':
-			opt_no_summary = 1;
-			break;
-		case 'X':
-			opt_hwpoison = 1;
-			prepare_hwpoison_fd();
-			break;
-		case 'x':
-			opt_unpoison = 1;
-			prepare_hwpoison_fd();
-			break;
-		case 'h':
-			usage();
-			exit(0);
-		default:
-			usage();
-			exit(1);
-		}
-	}
-
-	if (opt_list && opt_pid)
-		printf("voffset\t");
-	if (opt_list == 1)
-		printf("offset\tlen\tflags\n");
-	if (opt_list == 2)
-		printf("offset\tflags\n");
-
-	walk_addr_ranges();
-
-	if (opt_list == 1)
-		show_page_range(0, 0, 0);  /* drain the buffer */
-
-	if (opt_no_summary)
-		return 0;
-
-	if (opt_list)
-		printf("\n\n");
-
-	show_summary();
-
-	return 0;
-}
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index df09b96..4600cbe 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -60,6 +60,7 @@ There are three components to pagemap:
     19. HWPOISON
     20. NOPAGE
     21. KSM
+    22. THP
 
 Short descriptions to the page flags:
 
@@ -97,6 +98,9 @@ Short descriptions to the page flags:
 21. KSM
     identical memory pages dynamically shared between one or more processes
 
+22. THP
+    contiguous pages which construct transparent hugepages
+
     [IO related page flags]
  1. ERROR     IO error occurred
  3. UPTODATE  page has up-to-date data
diff --git a/Documentation/vm/unevictable-lru.txt b/Documentation/vm/unevictable-lru.txt
index 97bae3c..609d1a3 100644
--- a/Documentation/vm/unevictable-lru.txt
+++ b/Documentation/vm/unevictable-lru.txt
@@ -538,7 +538,7 @@ different reverse map mechanisms.
      process because mlocked pages are migratable.  However, for reclaim, if
      the page is mapped into a VM_LOCKED VMA, the scan stops.
 
-     try_to_unmap_anon() attempts to acquire in read mode the mmap semphore of
+     try_to_unmap_anon() attempts to acquire in read mode the mmap semaphore of
      the mm_struct to which the VMA belongs.  If this is successful, it will
      mlock the page via mlock_vma_page() - we wouldn't have gotten to
      try_to_unmap_anon() if the page were already mlocked - and will return
@@ -623,7 +623,7 @@ mapped file pages with an additional argument specifing unlock versus unmap
 processing.  Again, these functions walk the respective reverse maps looking
 for VM_LOCKED VMAs.  When such a VMA is found for anonymous pages and file
 pages mapped in linear VMAs, as in the try_to_unmap() case, the functions
-attempt to acquire the associated mmap semphore, mlock the page via
+attempt to acquire the associated mmap semaphore, mlock the page via
 mlock_vma_page() and return SWAP_MLOCK.  This effectively undoes the
 pre-clearing of the page's PG_mlocked done by munlock_vma_page.
 
@@ -641,7 +641,7 @@ with it - the usual fallback position.
 Note that try_to_munlock()'s reverse map walk must visit every VMA in a page's
 reverse map to determine that a page is NOT mapped into any VM_LOCKED VMA.
 However, the scan can terminate when it encounters a VM_LOCKED VMA and can
-successfully acquire the VMA's mmap semphore for read and mlock the page.
+successfully acquire the VMA's mmap semaphore for read and mlock the page.
 Although try_to_munlock() might be called a great many times when munlocking a
 large region or tearing down a large address space that has been mlocked via
 mlockall(), overall this is a fairly rare event.
diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
index 4b93c28..9e16246 100644
--- a/Documentation/watchdog/watchdog-kernel-api.txt
+++ b/Documentation/watchdog/watchdog-kernel-api.txt
@@ -167,4 +167,4 @@ driver specific data to and a pointer to the data itself.
 
 The watchdog_get_drvdata function allows you to retrieve driver specific data.
 The argument of this function is the watchdog device where you want to retrieve
-data from. The function retruns the pointer to the driver specific data.
+data from. The function returns the pointer to the driver specific data.
diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO
index faf976c..7fba5aa 100644
--- a/Documentation/zh_CN/HOWTO
+++ b/Documentation/zh_CN/HOWTO
@@ -316,7 +316,7 @@ linux-kernel邮件列表中提供反馈，告诉大家你遇到了问题还是
 	git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
   使用quilt管理的补丁集：
-    - USB, PCI, 驱动程序核心和I2C, Greg Kroah-Hartman <gregkh@suse.de>
+    - USB, PCI, 驱动程序核心和I2C, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 	kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
     - x86-64, 部分i386, Andi Kleen <ak@suse.de>
 	ftp.firstfloor.org:/pub/ak/x86_64/quilt/
diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt
index c278f41..f606ba8 100644
--- a/Documentation/zh_CN/magic-number.txt
+++ b/Documentation/zh_CN/magic-number.txt
@@ -89,7 +89,7 @@ TTY_DRIVER_MAGIC      0x5402      tty_driver        include/linux/tty_driver.h
 MGSLPC_MAGIC          0x5402      mgslpc_info       drivers/char/pcmcia/synclink_cs.c
 TTY_LDISC_MAGIC       0x5403      tty_ldisc         include/linux/tty_ldisc.h
 USB_SERIAL_MAGIC      0x6702      usb_serial        drivers/usb/serial/usb-serial.h
-FULL_DUPLEX_MAGIC     0x6969                        drivers/net/tulip/de2104x.c
+FULL_DUPLEX_MAGIC     0x6969                        drivers/net/ethernet/dec/tulip/de2104x.c
 USB_BLUETOOTH_MAGIC   0x6d02      usb_bluetooth     drivers/usb/class/bluetty.c
 RFCOMM_TTY_MAGIC      0x6d02                        net/bluetooth/rfcomm/tty.c
 USB_SERIAL_PORT_MAGIC 0x7301      usb_serial_port   drivers/usb/serial/usb-serial.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 9a648eb..467f8c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -163,7 +163,7 @@ M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:	linux-serial@vger.kernel.org
 W:	http://serial.sourceforge.net
 S:	Maintained
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
 F:	drivers/tty/serial/8250*
 F:	include/linux/serial_8250.h
 
@@ -504,7 +504,7 @@ F:	arch/x86/include/asm/geode.h
 AMD IOMMU (AMD-VI)
 M:	Joerg Roedel <joerg.roedel@amd.com>
 L:	iommu@lists.linux-foundation.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
 S:	Supported
 F:	drivers/iommu/amd_iommu*.[ch]
 F:	include/linux/amd-iommu.h
@@ -1311,7 +1311,7 @@ F:	drivers/atm/
 F:	include/linux/atm*
 
 ATMEL AT91 MCI DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@atmel.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.atmel.com/products/AT91/
 W:	http://www.at91.com/
@@ -1319,7 +1319,7 @@ S:	Maintained
 F:	drivers/mmc/host/at91_mci.c
 
 ATMEL AT91 / AT32 MCI DRIVER
-M:	Nicolas Ferre <nicolas.ferre@atmel.com>
+M:	Ludovic Desroches <ludovic.desroches@atmel.com>
 S:	Maintained
 F:	drivers/mmc/host/atmel-mci.c
 F:	drivers/mmc/host/atmel-mci-regs.h
@@ -1406,7 +1406,7 @@ F:	net/ax25/
 B43 WIRELESS DRIVER
 M:	Stefano Brivio <stefano.brivio@polimi.it>
 L:	linux-wireless@vger.kernel.org
-L:	b43-dev@lists.infradead.org (moderated for non-subscribers)
+L:	b43-dev@lists.infradead.org
 W:	http://linuxwireless.org/en/users/Drivers/b43
 S:	Maintained
 F:	drivers/net/wireless/b43/
@@ -1415,6 +1415,7 @@ B43LEGACY WIRELESS DRIVER
 M:	Larry Finger <Larry.Finger@lwfinger.net>
 M:	Stefano Brivio <stefano.brivio@polimi.it>
 L:	linux-wireless@vger.kernel.org
+L:	b43-dev@lists.infradead.org
 W:	http://linuxwireless.org/en/users/Drivers/b43
 S:	Maintained
 F:	drivers/net/wireless/b43legacy/
@@ -1502,7 +1503,7 @@ F:	drivers/i2c/busses/i2c-bfin-twi.c
 
 BLOCK LAYER
 M:	Jens Axboe <axboe@kernel.dk>
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
 S:	Maintained
 F:	block/
 
@@ -1517,7 +1518,7 @@ M:	Marcel Holtmann <marcel@holtmann.org>
 M:	"Gustavo F. Padovan" <padovan@profusion.mobi>
 L:	linux-bluetooth@vger.kernel.org
 W:	http://www.bluez.org/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git
 S:	Maintained
 F:	drivers/bluetooth/
 
@@ -1526,7 +1527,7 @@ M:	Marcel Holtmann <marcel@holtmann.org>
 M:	"Gustavo F. Padovan" <padovan@profusion.mobi>
 L:	linux-bluetooth@vger.kernel.org
 W:	http://www.bluez.org/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git
 S:	Maintained
 F:	net/bluetooth/
 F:	include/net/bluetooth/
@@ -1637,7 +1638,7 @@ BTTV VIDEO4LINUX DRIVER
 M:	Mauro Carvalho Chehab <mchehab@infradead.org>
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	Documentation/video4linux/bttv/
 F:	drivers/media/video/bt8xx/bttv*
@@ -1667,7 +1668,7 @@ F:	fs/cachefiles/
 CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
 M:	Jonathan Corbet <corbet@lwn.net>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	Documentation/video4linux/cafe_ccic
 F:	drivers/media/video/marvell-ccic/
@@ -1798,7 +1799,8 @@ F:	Documentation/zh_CN/
 CISCO VIC ETHERNET NIC DRIVER
 M:	Christian Benvenuti <benve@cisco.com>
 M:	Roopa Prabhu <roprabhu@cisco.com>
-M:	David Wang <dwang2@cisco.com>
+M:	Neel Patel <neepatel@cisco.com>
+M:	Nishank Trivedi <nistrive@cisco.com>
 S:	Supported
 F:	drivers/net/ethernet/cisco/enic/
 
@@ -2017,7 +2019,7 @@ CX18 VIDEO4LINUX DRIVER
 M:	Andy Walls <awalls@md.metrocast.net>
 L:	ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://linuxtv.org
 W:	http://www.ivtvdriver.org/index.php/Cx18
 S:	Maintained
@@ -2315,7 +2317,7 @@ F:	Documentation/blockdev/drbd/
 
 DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git
 S:	Supported
 F:	Documentation/kobject.txt
 F:	drivers/base/
@@ -2337,7 +2339,7 @@ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
 M:	Keith Packard <keithp@keithp.com>
 L:	intel-gfx@lists.freedesktop.org (subscribers-only)
 L:	dri-devel@lists.freedesktop.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/keithp/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/keithp/linux.git
 S:	Supported
 F:	drivers/gpu/drm/i915
 F:	include/drm/i915*
@@ -2910,8 +2912,8 @@ GFS2 FILE SYSTEM
 M:	Steven Whitehouse <swhiteho@redhat.com>
 L:	cluster-devel@redhat.com
 W:	http://sources.redhat.com/cluster/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw.git
 S:	Supported
 F:	Documentation/filesystems/gfs2*.txt
 F:	fs/gfs2/
@@ -2952,42 +2954,42 @@ F:	drivers/net/ethernet/aeroflex/
 GSPCA FINEPIX SUBDRIVER
 M:	Frank Zago <frank@zago.net>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/finepix.c
 
 GSPCA GL860 SUBDRIVER
 M:	Olivier Lorin <o.lorin@laposte.net>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/gl860/
 
 GSPCA M5602 SUBDRIVER
 M:	Erik Andren <erik.andren@gmail.com>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/m5602/
 
 GSPCA PAC207 SONIXB SUBDRIVER
 M:	Hans de Goede <hdegoede@redhat.com>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/pac207.c
 
 GSPCA SN9C20X SUBDRIVER
 M:	Brian Johnson <brijohn@gmail.com>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/sn9c20x.c
 
 GSPCA T613 SUBDRIVER
 M:	Leandro Costantino <lcostantino@gmail.com>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/t613.c
 
@@ -2995,7 +2997,7 @@ GSPCA USB WEBCAM DRIVER
 M:	Jean-Francois Moine <moinejf@free.fr>
 W:	http://moinejf.free.fr
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/gspca/
 
@@ -3282,7 +3284,7 @@ IDE SUBSYSTEM
 M:	"David S. Miller" <davem@davemloft.net>
 L:	linux-ide@vger.kernel.org
 Q:	http://patchwork.ozlabs.org/project/linux-ide/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide.git
 S:	Maintained
 F:	Documentation/ide/
 F:	drivers/ide/
@@ -3394,7 +3396,7 @@ F:	firmware/isci/
 INTEL IDLE DRIVER
 M:	Len Brown <lenb@kernel.org>
 L:	linux-pm@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git
 S:	Supported
 F:	drivers/idle/intel_idle.c
 
@@ -3640,6 +3642,15 @@ S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
 F:	kernel/irq/
 
+IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
+M:	Benjamin Herrenschmidt <benh@kernel.crashing.org>
+M:	Grant Likely <grant.likely@secretlab.ca>
+T:	git git://git.secretlab.ca/git/linux-2.6.git irqdomain/next
+S:	Maintained
+F:	Documentation/IRQ-domain.txt
+F:	include/linux/irqdomain.h
+F:	kernel/irq/irqdomain.c
+
 ISAPNP
 M:	Jaroslav Kysela <perex@perex.cz>
 S:	Maintained
@@ -3692,7 +3703,7 @@ IVTV VIDEO4LINUX DRIVER
 M:	Andy Walls <awalls@md.metrocast.net>
 L:	ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://www.ivtvdriver.org
 S:	Maintained
 F:	Documentation/video4linux/*.ivtv
@@ -3788,8 +3799,8 @@ F:	fs/autofs4/
 
 KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
 M:	Michal Marek <mmarek@suse.cz>
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git for-next
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git rc-fixes
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git for-next
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git rc-fixes
 L:	linux-kbuild@vger.kernel.org
 S:	Maintained
 F:	Documentation/kbuild/
@@ -4212,7 +4223,7 @@ MAC80211
 M:	Johannes Berg <johannes@sipsolutions.net>
 L:	linux-wireless@vger.kernel.org
 W:	http://linuxwireless.org/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
 S:	Maintained
 F:	Documentation/networking/mac80211-injection.txt
 F:	include/net/mac80211.h
@@ -4223,7 +4234,7 @@ M:	Stefano Brivio <stefano.brivio@polimi.it>
 M:	Mattias Nissler <mattias.nissler@gmx.de>
 L:	linux-wireless@vger.kernel.org
 W:	http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
 S:	Maintained
 F:	net/mac80211/rc80211_pid*
 
@@ -4295,7 +4306,7 @@ P:	LinuxTV.org Project
 L:	linux-media@vger.kernel.org
 W:	http://linuxtv.org
 Q:	http://patchwork.kernel.org/project/linux-media/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	Documentation/dvb/
 F:	Documentation/video4linux/
@@ -4352,6 +4363,13 @@ T:	git git://git.monstr.eu/linux-2.6-microblaze.git
 S:	Supported
 F:	arch/microblaze/
 
+MICROCHANNEL ARCHITECTURE (MCA)
+M:	James Bottomley <James.Bottomley@HansenPartnership.com>
+S:	Maintained
+F:	Documentation/mca.txt
+F:	drivers/mca/
+F:	include/linux/mca*
+
 MICROTEK X6 SCANNER
 M:	Oliver Neukum <oliver@neukum.name>
 S:	Maintained
@@ -4367,14 +4385,6 @@ S:	Supported
 F:	Documentation/mips/
 F:	arch/mips/
 
-MISCELLANEOUS MCA-SUPPORT
-M:	James Bottomley <James.Bottomley@HansenPartnership.com>
-S:	Maintained
-F:	Documentation/ia64/mca.txt
-F:	Documentation/mca.txt
-F:	drivers/mca/
-F:	include/linux/mca*
-
 MODULE SUPPORT
 M:	Rusty Russell <rusty@rustcorp.com.au>
 S:	Maintained
@@ -4475,6 +4485,14 @@ L:	alsa-devel@alsa-project.org
 W:	http://www.native-instruments.com
 F:	sound/usb/caiaq/
 
+NATIVE LINUX KVM TOOL
+M:	Pekka Enberg <penberg@kernel.org>
+M:	Sasha Levin <levinsasha928@gmail.com>
+M:	Asias He <asias.hejun@gmail.com>
+L:	kvm@vger.kernel.org
+S:	Maintained
+F:	tools/kvm/
+
 NCP FILESYSTEM
 M:	Petr Vandrovec <petr@vandrovec.name>
 S:	Odd Fixes
@@ -4582,7 +4600,7 @@ M:	James Morris <jmorris@namei.org>
 M:	Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
 M:	Patrick McHardy <kaber@trash.net>
 L:	netdev@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
 S:	Maintained
 F:	net/ipv4/
 F:	net/ipv6/
@@ -4598,7 +4616,7 @@ NETWORKING [WIRELESS]
 M:	"John W. Linville" <linville@tuxdriver.com>
 L:	linux-wireless@vger.kernel.org
 Q:	http://patchwork.kernel.org/project/linux-wireless/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git
 S:	Maintained
 F:	net/mac80211/
 F:	net/rfkill/
@@ -4611,8 +4629,8 @@ F:	drivers/net/wireless/
 NETWORKING DRIVERS
 L:	netdev@vger.kernel.org
 W:	http://www.linuxfoundation.org/en/Net
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
 S:	Odd Fixes
 F:	drivers/net/
 F:	include/linux/if_*
@@ -4687,7 +4705,7 @@ NTFS FILESYSTEM
 M:	Anton Altaparmakov <anton@tuxera.com>
 L:	linux-ntfs-dev@lists.sourceforge.net
 W:	http://www.tuxera.com/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs.git
 S:	Supported
 F:	Documentation/filesystems/ntfs.txt
 F:	fs/ntfs/
@@ -4828,7 +4846,7 @@ F:	drivers/char/pcmcia/cm4040_cs.*
 OMNIVISION OV7670 SENSOR DRIVER
 M:	Jonathan Corbet <corbet@lwn.net>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	drivers/media/video/ov7670.c
 
@@ -4912,8 +4930,6 @@ F:	fs/ocfs2/
 
 ORINOCO DRIVER
 L:	linux-wireless@vger.kernel.org
-L:	orinoco-users@lists.sourceforge.net
-L:	orinoco-devel@lists.sourceforge.net
 W:	http://linuxwireless.org/en/users/Drivers/orinoco
 W:	http://www.nongnu.org/orinoco/
 S:	Orphan
@@ -5006,7 +5022,7 @@ M:	"James E.J. Bottomley" <jejb@parisc-linux.org>
 L:	linux-parisc@vger.kernel.org
 W:	http://www.parisc-linux.org/
 Q:	http://patchwork.kernel.org/project/linux-parisc/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
 S:	Maintained
 F:	arch/parisc/
 F:	drivers/parisc/
@@ -5062,7 +5078,7 @@ PCI SUBSYSTEM
 M:	Jesse Barnes <jbarnes@virtuousgeek.org>
 L:	linux-pci@vger.kernel.org
 Q:	http://patchwork.kernel.org/project/linux-pci/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci.git
 S:	Supported
 F:	Documentation/PCI/
 F:	drivers/pci/
@@ -5336,7 +5352,7 @@ M:	Mike Isely <isely@pobox.com>
 L:	pvrusb2@isely.net	(subscribers-only)
 L:	linux-media@vger.kernel.org
 W:	http://www.isely.net/pvrusb2/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	Documentation/video4linux/README.pvrusb2
 F:	drivers/media/video/pvrusb2/
@@ -5502,7 +5518,7 @@ RCUTORTURE MODULE
 M:	Josh Triplett <josh@freedesktop.org>
 M:	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 S:	Supported
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:	Documentation/RCU/torture.txt
 F:	kernel/rcutorture.c
 
@@ -5527,7 +5543,7 @@ M:	Dipankar Sarma <dipankar@in.ibm.com>
 M:	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
 W:	http://www.rdrop.com/users/paulmck/rclock/
 S:	Supported
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-2.6-rcu.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
 F:	Documentation/RCU/
 F:	include/linux/rcu*
 F:	include/linux/srcu*
@@ -5556,6 +5572,13 @@ S:	Supported
 F:	drivers/base/regmap/
 F:	include/linux/regmap.h
 
+REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM
+M:	Ohad Ben-Cohen <ohad@wizery.com>
+S:	Maintained
+F:	drivers/remoteproc/
+F:	Documentation/remoteproc.txt
+F:	include/linux/remoteproc.h
+
 RFKILL
 M:	Johannes Berg <johannes@sipsolutions.net>
 L:	linux-wireless@vger.kernel.org
@@ -5681,7 +5704,7 @@ F:	drivers/mmc/host/s3cmci.*
 SAA7146 VIDEO4LINUX-2 DRIVER
 M:	Michael Hunold <michael@mihu.de>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://www.mihu.de/linux/saa7146
 S:	Maintained
 F:	drivers/media/common/saa7146*
@@ -6103,7 +6126,7 @@ F:	arch/ia64/sn/
 SOC-CAMERA V4L2 SUBSYSTEM
 M:	Guennadi Liakhovetski <g.liakhovetski@gmx.de>
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 S:	Maintained
 F:	include/media/v4l2*
 F:	drivers/media/video/v4l2*
@@ -6175,8 +6198,8 @@ SPARC + UltraSPARC (sparc/sparc64)
 M:	"David S. Miller" <davem@davemloft.net>
 L:	sparclinux@vger.kernel.org
 Q:	http://patchwork.ozlabs.org/project/sparclinux/list/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git
 S:	Maintained
 F:	arch/sparc/
 F:	drivers/sbus/
@@ -6184,11 +6207,11 @@ F:	drivers/sbus/
 SPARC SERIAL DRIVERS
 M:	"David S. Miller" <davem@davemloft.net>
 L:	sparclinux@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git
 S:	Maintained
+F:	include/linux/sunserialcore.h
 F:	drivers/tty/serial/suncore.c
-F:	drivers/tty/serial/suncore.h
 F:	drivers/tty/serial/sunhv.c
 F:	drivers/tty/serial/sunsab.c
 F:	drivers/tty/serial/sunsab.h
@@ -6475,7 +6498,7 @@ L:	linux-scsi@vger.kernel.org
 L:	target-devel@vger.kernel.org
 L:	http://groups.google.com/group/linux-iscsi-target-dev
 W:	http://www.linux-iscsi.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core-2.6.git master
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core.git master
 S:	Supported
 F:	drivers/target/
 F:	include/target/
@@ -6666,7 +6689,7 @@ K:	^Subject:.*(?i)trivial
 TTY LAYER
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 S:	Supported
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
 F:	drivers/tty/
 F:	drivers/tty/serial/serial_core.c
 F:	include/linux/serial_core.h
@@ -6834,7 +6857,7 @@ USB ET61X[12]51 DRIVER
 M:	Luca Risolia <luca.risolia@studio.unibo.it>
 L:	linux-usb@vger.kernel.org
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://www.linux-projects.org
 S:	Maintained
 F:	drivers/media/video/et61x251/
@@ -6990,7 +7013,7 @@ USB SN9C1xx DRIVER
 M:	Luca Risolia <luca.risolia@studio.unibo.it>
 L:	linux-usb@vger.kernel.org
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://www.linux-projects.org
 S:	Maintained
 F:	Documentation/video4linux/sn9c102.txt
@@ -7000,7 +7023,7 @@ USB SUBSYSTEM
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 L:	linux-usb@vger.kernel.org
 W:	http://www.linux-usb.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
 S:	Supported
 F:	Documentation/usb/
 F:	drivers/net/usb/
@@ -7026,7 +7049,7 @@ USB VIDEO CLASS
 M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 L:	linux-uvc-devel@lists.berlios.de (subscribers-only)
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://www.ideasonboard.org/uvc/
 S:	Maintained
 F:	drivers/media/video/uvc/
@@ -7035,7 +7058,7 @@ USB W996[87]CF DRIVER
 M:	Luca Risolia <luca.risolia@studio.unibo.it>
 L:	linux-usb@vger.kernel.org
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://www.linux-projects.org
 S:	Maintained
 F:	Documentation/video4linux/w9968cf.txt
@@ -7064,7 +7087,7 @@ USB ZR364XX DRIVER
 M:	Antoine Jacquet <royale@zerezo.com>
 L:	linux-usb@vger.kernel.org
 L:	linux-media@vger.kernel.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media.git
 W:	http://royale.zerezo.com/zr364xx/
 S:	Maintained
 F:	Documentation/video4linux/zr364xx.txt
@@ -7214,7 +7237,7 @@ M:	Liam Girdwood <lrg@ti.com>
 M:	Mark Brown <broonie@opensource.wolfsonmicro.com>
 W:	http://opensource.wolfsonmicro.com/node/15
 W:	http://www.slimlogic.co.uk/?p=48
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/regulator.git
 S:	Supported
 F:	drivers/regulator/
 F:	include/linux/regulator/
@@ -7461,6 +7484,12 @@ S:	Supported
 F:	Documentation/filesystems/xfs.txt
 F:	fs/xfs/
 
+XILINX AXI ETHERNET DRIVER
+M:	Ariane Keller <ariane.keller@tik.ee.ethz.ch>
+M:	Daniel Borkmann <daniel.borkmann@tik.ee.ethz.ch>
+S:	Maintained
+F:	drivers/net/ethernet/xilinx/xilinx_axienet*
+
 XILINX SYSTEMACE DRIVER
 M:	Grant Likely <grant.likely@secretlab.ca>
 W:	http://www.secretlab.ca/
diff --git a/Next/SHA1s b/Next/SHA1s
new file mode 100644
index 0000000..3697b2c
--- /dev/null
+++ b/Next/SHA1s
@@ -0,0 +1,184 @@
+Name		SHA1
+----		----
+origin		27e74da9800289e69ba907777df1e2085231eff7
+fixes		2b7957488253f5c5c7f122f1036b3c07659074f6
+kbuild-current	6c635224602d760c1208ada337562f40d8ae93a5
+arm-current	5180bb392a8aab5233e6db858ac1d8371533e20f
+m68k-current	2a3535069e33d8b416f406c159ce924427315303
+powerpc-merge	9a45a9407c69d068500923480884661e2b9cc421
+52xx-and-virtex-current	c49f8789f532ae39019135ca038e9bc0d15aaa4a
+sparc		e51e07e0ac7e3ff847d640f41b7527db04d4a4e7
+scsi-rc-fixes	fea6d607e154cf96ab22254ccb48addfd43d4cb5
+net		84338a6c9dbb6ff3de4749864020f8f25d86fc81
+sound-current	fe879e2f6d65648b6398ac27f4c623ebd2e867f7
+pci-current	3682a3946d2b0bad621db871e3bead83e523a238
+wireless	0dee00686da88cc32753e02e4e8efdd9e326e4d2
+driver-core.current	29bb5d4fd3140a7d5d02d858118c74a45f15c296
+tty.current	b01543dfe67bb1d191998e90d20534dc354de059
+usb.current	b9e44fe5ecda4158c22bc1ea4bffa378a4f83f65
+staging.current	b01543dfe67bb1d191998e90d20534dc354de059
+char-misc.current	b5266ea675c5a041e2852c7ccec4cf2d4f5e0cf4
+cpufreq-current	5983fe2b29df5885880d7fa3b91aca306c7564ef
+input-current	82b982c9a697e7be0745523a53334fe38a4582c8
+md-current	db91ff55bdf06736b849afc1b1fce5763bbb8d5d
+audit-current	c158a35c8a681cf68d36f22f058f9f5466386c71
+crypto-current	f2ea0f5f04c97b48c88edccba52b0682fbe45087
+ide		0ab3d8b3213c8bb55370b11fcc5321ee4f2c5e92
+dwmw2		244dc4e54b73567fae7f8fd9ba56584be9375442
+devicetree-current	2261cc627f5453004042b4f694612edae27e492e
+spi-current	c88db233251b026fda775428f0250c760553e216
+gpio-current	7e3a70fb7bccada029c188c89bfbf3c0a63c1500
+arm		cb63a5b3ae7131284f2b76be6c38e2f0516dee28
+arm-perf	cdd2a5b530a008f64d86631c40e38c6dc9419b91
+davinci		fe0d42203cb5616eeff68b14576a0f7e2dd56625
+samsung		9edb240696bacd53f4331119d2dfd13d4cd4852f
+s5p		e8a4c2f77d8051f5691ddb6a15fafe70591321f6
+tegra		90482018f4271a5b8de6412dbc152e090c06fe70
+xilinx		b85a3ef4ac65169b65fd2fe9bec7912bbf475ba4
+blackfin	e651fe5202da3dd618a72133f3040cc125f64681
+c6x		62e37ca78b1a4ca2eb77875bfd7ac63a7e068c67
+cris		ea78f5b898555ddfbab494c7755130362fe3cf46
+hexagon		110b3723837f231b7dda418df975bcc09e780825
+ia64		0f261ede311bfd718d84bdf50dd7fcee585e82c7
+m68k		2a3535069e33d8b416f406c159ce924427315303
+m68knommu	97202276714e4e8dd93befaad56c6a3a099a0a8a
+microblaze	8597559a78e1cde158b999212bc9543682638eb1
+mips		2fea3778a54e5407527677bc326afd4e34985b62
+openrisc	754d5c2bf65847f7ff4e0047a830154abe666112
+parisc		fc99a914318c60cc9fa9c7347529f4e07dec67d8
+powerpc		ef88e3911c0e0301e73fa3b3b2567aabdbe17cc4
+4xx		ef88e3911c0e0301e73fa3b3b2567aabdbe17cc4
+52xx-and-virtex	c1395f4cf4a1944236f0f28cdf718c4aacc88f2d
+galak		ef88e3911c0e0301e73fa3b3b2567aabdbe17cc4
+s390		486f0b4f8029fd63637b76d9d18f2c6ff320680a
+sparc-next	b4096504c2b6945c41eae99f85f4ec64ac19bfce
+tile		0c90547b4a3fcee184db4d54ffc1a4fb17fd54d6
+unicore32	099469502f62fbe0d7e4f0b83a2f22538367f734
+ceph		83eb26af0db71f2dfe551405c55d982288fa6178
+cifs		4903062b5485f0e2c286a23b44c9b59d9b017d53
+configfs	b930c26416c4ea6855726fd977145ccea9afbdda
+ecryptfs	6cfd4b42f29db32426499c9dca8885ea04b04839
+ext3		62aa2b537c6f5957afd98e29f96897419ed5ebab
+ext4		9ee4930259abf3641ae85c19498eabe97cf6abad
+fuse		03c9693db0ea5605e23b8f4bbd4f7212a6fad982
+gfs2		b3e8048654f583c2d9577c999dae07994280fd2b
+logfs		8ebbfb49574818f07a25bc119b1bbdf1c2853a39
+nfs		36925a2daaa0964270c20f74176e0420420f06a5
+nfsd		03cfb42025a16dc45195dbdd6d368daaa8367429
+ocfs2		939255798a468e1a92f03546de6e87be7b491e57
+omfs		976d167615b64e14bc1491ca51d424e2ba9a5e84
+squashfs	3d4a1c80c4eb97187b3a61b3bfa8c804327f7a45
+v9fs		f766619db2be059cd0dbba8a36176fe01a29d588
+ubifs		72d3ef6846b6cf3b88f680ea2e4ff671e1efa2b5
+xfs		33e0edafd78d83273c14b14501cff063fac528e5
+vfs		9a3b4c1d5078e47c0fe1b82cf8add4be12cd49ca
+pci		5b415f1e79e0c09366f26e3eabe751642059285a
+hid		40e1df89a6221641d1c6a9679da9296c65542929
+i2c		c3632e0590532f1cc50f6851d896c6511687e6bd
+bjdooks-i2c	fc84fe19ffb9eee7e6b3301bc6cd45b22f187bd7
+jdelvare-hwmon	127e71ef2b143dd7bbd6b25d90477e3b68087100
+hwmon-staging	fa753a17be22eeed9abd911f0bd354c4ba52045b
+kernel-doc	7e7b32ac24949774b0c19cafa353390a0eead92b
+docs		5c24d8b2bf99ee93049a6f8154ef9cd7897a6e36
+v4l-dvb		d3450663096a798ae1918e0b427db7b249f114b0
+kbuild		75cb742fa2ea05f1f48c1b86a8cebd78d5645086
+kconfig		eae1c36aea9cfe4d123b8af3ffe54109c6579810
+libata		96c4d2965023fed2d219e0b1b411cdce712c8be3
+infiniband	715252d41912941efb791a7b7bad94d2614dc5c3
+acpi		eb7004e623637a6c2b32317c000d4b617b5cb053
+ieee1394	6e01490dfebe03df873e6153c25660f624ea541d
+ubi		ecaabdb615178dd7207f05265eb6409e7aa37865
+dlm		60f98d1839376d30e13f3e452dce2433fad3060e
+scsi		50824d6c5657ce340e3911171865a8d99fdd8eba
+target-updates	24d2f085fc6c3437ae2c2f631cef7459a83460de
+target-merge	d65b4e98d7ea3038b767b70fe8be959b2913f16d
+ibft		935a9fee51c945b8942be2d7b4bae069167b4886
+isci		57872c25d27817494b58fc396f8fd4bf950c593a
+slave-dma	b63fd6ce71226e5e048e2035ba202b53f89a1825
+dmaengine	d07a74a546981a09ba490936645fbf0d1340b96c
+net-next	8de65c2aaa1faf8e57e1b29b4265b6a57fae4136
+wireless-next	ca994a36f585432458ead9133fcfe05440edbb7b
+bluetooth	c5993de864d96b3656e9fca38c377b130105d97a
+mtd		3c3e51d5451036b1d697f0f3b73c567c5cbdc4c5
+l2-mtd		783dbd63b6b0010068e03e7fda6812021e707d53
+crypto		d97055e62dd8c6f2150b6062ffbd4a6d836658ff
+sound		e40bcf0b8d08cba580a4bb6f4e9a2c46bea701d3
+sound-asoc	30c66eebec08f4dc6dfa407ee27d72047e1a87fb
+cpufreq		6c523c614c13b84a3dc64f7a56d6855b03e6b292
+rr		42d5bdd92057af9f2008edb3d5af7deedcbd17b1
+input		023cea0ecfa2df034096c3f4afa796a0b2d1188a
+input-mt	7491f3dffd99fadf1239011c0ab5346925618dae
+block		b3021da8f53746bc90d76694ded195e890ac9220
+device-mapper	1e5f0dafe293f819884e50f4cdbc6138447d79d7
+embedded	4744b43431e8613f920c5cba88346756f53c5165
+firmware	6e03a201bbe8137487f340d26aa662110e324b20
+battery		913272b3864d6da89c70d9fc2c30ccb57794b369
+mmc		fcd9bdae386753531a9cb6b2577359a83f4e121c
+kgdb		880ba694f6161ce4b8e14fb7be64f3d446dd5ae6
+slab		96438bc4c9e16113d1a5af1744f548d1e437c2e6
+uclinux		5e442a493fc59fa536c76db1fff5b49ca36a88c5
+md		fae8cc5ed0714953b1ad7cf86f030d2177278424
+mfd		a0afdbc2665bbad5ebc81a43b820e97f56ea0582
+drm		019d96cb55ade38a4b4a52bba0304e8cd681f30a
+fbdev		94f61a7666224ab307e387ff0d146055ae77e6ab
+viafb		c572c8bbff13591f6c9f249d4413f79ddda21e61
+omap_dss2	9a9016832d2601a290db4dce6dd55552bdae5b1a
+regulator	13e8a7a1d5919d553a56c1f998651e08c8647025
+security	b0d5de4d58803bbcce2b8175a8dd21c559a3abc1
+selinux		a9ab18a8d687276dd0647443c3f9ed52e2816209
+lblnet		7e27d6e778cd87b6f2415515d7127eba53fe5d02
+watchdog	1776b7d06df7c3edfb086278dea744d3d4ca5d34
+dwmw2-iommu	c3b92c8787367a8bb53d57d9789b558f1295cc96
+iommu		48d211675a2dd82e9de75665013f43b84a9d24ed
+osd		0aa436b78b6c7f3bfc814b78ea752369af311c3a
+jc_docs		5c050fb96380a87a85aad9084b68fdcd2b84c193
+trivial		202e0116b4700a6d51dc251bd1dbd0a8309806da
+audit		dcd6c92267155e70a94b3927bce681ce74b80d1f
+pm		98f7e952c9a1961bbdf695a0a30dbb5e4bb8c974
+apm		b4a133da2eaccb844a7beaef16ffd9c76a0d21d3
+fsnotify	ef9bf3b7144bee6ce1da5616015cabc8771206af
+edac		4d096ca7e65584dd5845e64c6400f920e694f672
+edac-amd	5a4239490efe43529c5c6be9c0f04aa6fd81f08b
+devicetree	0f22dd395fc473cee252b9af50249b8e0f32fde7
+spi		14af60b6fb3b76634278364b697dae2f9f360abf
+gpio		ff64abefb6680dfc2aca7ecaa5e695949e7335c9
+tip		630e0fd110eb2694b14685d7e0d32af91b885754
+rcu		eb7f2020857058a4df9ba6a5ec84b8798a0d8e43
+cputime		c3e0ef9a298e028a82ada28101ccd5cf64d209ee
+uprobes		4e447982abd57131841a26faa6738c805c399ff6
+cgroup		3ce3230a0cff484e5130153f244d4fb8a56b3a8b
+kmemleak	d65b4e98d7ea3038b767b70fe8be959b2913f16d
+kvm		4b99f72c2a9c622ad8b346bd1593b19b789d5638
+oprofile	b9e7f8e9382a93e41305caa914f160d15c464b19
+xen		59e9a6b1ee9fa3992860eb6c48a37b163e97d205
+xen-two		53eaea00d9a05b72ecd2388ebe4a06e48d009d53
+xen-pvhvm	b056b6a0144de90707cd22cf7b4f60bf69c86d59
+percpu		e920d5971d706290c5a6281f719e16c25021f964
+workqueues	6b3da11b3c36fdafce3a72e0e90d6c4e99e9aad5
+hwpoison	46e387bbd82d438b9131e237e6e2cb55a825da49
+sysctl		4e75732035d7e97e001bdf6e3149d3967c0221de
+regmap		02c1ee398c2eca671f872298427d6791220ba8cf
+hsi		43139a61fc68f4b0af7327a0e63f340a7c81c69a
+driver-core	8bf11938459ff8ceb8643258d0a35e0f2bc9be17
+tty		6816383a09b5be8d35f14f4c25dedb64498e4959
+usb		5407a3c3d942e75d4d123d213fd692bce5acc961
+staging		3e809144efc37f950606c827f992b653286f5533
+char-misc	838d51bfa31540d474b9562056379b6325ec07d7
+arm-soc		8a6b82f9fb5537b940836c96f55d1e655b631dbb
+tmem		b05b561f1dd2b8f36120c92184057b50804611a0
+writeback	977b7e3a52a7421ad33a393a38ece59f3d41c2fa
+arm-dt		ede338f4ce2fb5ee99d18751df32fbd3b10df268
+hwspinlock	8b37fcfc9b3400b647748783a2cafff67793e0ad
+pinctrl		334e235eb5a7f53074c156f9b4c95ec1aec24ab1
+moduleh		6aec187a90aeb883533c9180e2acac1e54c87f7d
+vhost		1e05b62ae4bd4c1209229de367b0989b39644f88
+kmap_atomic	019e9ad394b1ec0293210a651fa242e50f790188
+modem-shm	3cff1cc0d7703b289fc2e1dbf6cc7790ccac9d5e
+memblock	7bd0b0f0da3b1ec11cbcc798eb0ef747a1184077
+remoteproc	6c7b643c995ff106416ffd38131f5a60056abb2a
+irqdomain	2462bacd0334d918f9fcd79fc59c403b76b36f8a
+kvmtool		52b7a79022db726569ca4fcef2aa10beae3bf053
+dma-mapping	e9725412a39567abe9fd98fe929c7d634212f3d0
+ktest		be405f95f0a090d1dfc26a5bb4d781c00f34479c
+scsi-post-merge	65112dccf8a113737684366349d7f9ec373ddc47
+akpm		44f131fd8c3182afe2af7cae1db616f926dc4e1a
diff --git a/Next/Trees b/Next/Trees
new file mode 100644
index 0000000..b33d76a
--- /dev/null
+++ b/Next/Trees
@@ -0,0 +1,186 @@
+Trees included into this release:
+
+Name		Type	URL
+----		----	---
+origin		git	git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git#master
+fixes		git	git://git.kernel.org/pub/scm/linux/kernel/git/sfr/next-fixes.git#master
+kbuild-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git#rc-fixes
+arm-current	git	git://ftp.arm.linux.org.uk/~rmk/linux-next.git#fixes
+m68k-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-linus
+powerpc-merge	git	git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git#merge
+52xx-and-virtex-current	git	git://git.secretlab.ca/git/linux-2.6#powerpc/merge
+sparc		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git#master
+scsi-rc-fixes	git	git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6.git#master
+net		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git#master
+sound-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-linus
+pci-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci#for-linus
+wireless	git	git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git#master
+driver-core.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git#driver-core-linus
+tty.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-linus
+usb.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-linus
+staging.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-linus
+char-misc.current	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-linus
+cpufreq-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git#fixes
+input-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#for-linus
+md-current	git	git://neil.brown.name/md#for-linus
+audit-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit.git#for-linus
+crypto-current	git	git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6.git#master
+ide		git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide.git#master
+dwmw2		git	git://git.infradead.org/users/dwmw2/random-2.6.git#master
+devicetree-current	git	git://git.secretlab.ca/git/linux-2.6#devicetree/merge
+spi-current	git	git://git.secretlab.ca/git/linux-2.6#spi/merge
+gpio-current	git	git://git.secretlab.ca/git/linux-2.6#gpio/merge
+arm		git	git://ftp.arm.linux.org.uk/~rmk/linux-next.git#for-next
+arm-perf	git	git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git#for-next/perf
+davinci		git	git://gitorious.org/linux-davinci/linux-davinci.git#davinci-next
+samsung		git	git://git.fluff.org/bjdooks/linux.git#next-samsung
+s5p		git	git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git#for-next
+tegra		git	git://git.kernel.org/pub/scm/linux/kernel/git/olof/tegra.git#for-next
+xilinx		git	git://git.xilinx.com/linux-2.6-xlnx.git#arm-next
+blackfin	git	git://git.kernel.org/pub/scm/linux/kernel/git/lliubbo/blackfin.git#for-linus
+c6x		git	git://linux-c6x.org/git/projects/linux-c6x-upstreaming.git#for-linux-next
+cris		git	git://www.jni.nu/cris.git#for-next
+hexagon		quilt	https://www.codeaurora.org/patches/quic/hlk/linux-next/
+ia64		git	git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git#next
+m68k		git	git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git#for-next
+m68knommu	git	git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu.git#for-next
+microblaze	git	git://git.monstr.eu/linux-2.6-microblaze.git#next
+mips		git	git://git.linux-mips.org/pub/scm/ralf/upstream-sfr.git#mips-for-linux-next
+openrisc	git	git://openrisc.net/jonas/linux#for-upstream
+parisc		git	git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git#for-next
+powerpc		git	git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git#next
+4xx		git	git://git.infradead.org/users/jwboyer/powerpc-4xx.git#next
+52xx-and-virtex	git	git://git.secretlab.ca/git/linux-2.6#powerpc/next
+galak		git	git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git#next
+s390		git	git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#features
+sparc-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next.git#master
+tile		git	git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile.git#master
+unicore32	git	git://github.com/gxt/linux.git#unicore32
+ceph		git	git://github.com/NewDreamNetwork/ceph-client.git#for-next
+cifs		git	git://git.samba.org/sfrench/cifs-2.6.git#master
+configfs	git	git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/configfs.git#linux-next
+ecryptfs	git	git://git.kernel.org/pub/scm/linux/kernel/git/tyhicks/ecryptfs.git#next
+ext3		git	git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git#for_next
+ext4		git	git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git#dev
+fuse		git	git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git#for-next
+gfs2		git	git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw.git#master
+logfs		git	git://github.com/prasad-joshi/logfs_upstream.git#master
+nfs		git	git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git#linux-next
+nfsd		git	git://git.linux-nfs.org/~bfields/linux.git#nfsd-next
+ocfs2		git	git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2.git#linux-next
+omfs		git	git://github.com/bcopeland/omfs.git#for-next
+squashfs	git	git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-next.git#master
+v9fs		git	git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs.git#for-next
+ubifs		git	git://git.infradead.org/ubifs-2.6.git#linux-next
+xfs		git	git://oss.sgi.com/xfs/xfs.git#for-next
+vfs		git	git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6.git#for-next
+pci		git	git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci#linux-next
+hid		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git#for-next
+i2c		quilt	http://khali.linux-fr.org/devel/linux-3/jdelvare-i2c/
+bjdooks-i2c	git	git://git.fluff.org/bjdooks/linux.git#next-i2c
+jdelvare-hwmon	quilt	http://khali.linux-fr.org/devel/linux-3/jdelvare-hwmon/
+hwmon-staging	git	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git#hwmon-next
+kernel-doc	quilt	http://www.xenotime.net/kernel-doc-patches/current/
+docs		git	git://git.kernel.org/pub/scm/linux/kernel/git/rdunlap/linux-docs.git#docs-move
+v4l-dvb		git	git://linuxtv.org/mchehab/media-next.git#master
+kbuild		git	git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild.git#for-next
+kconfig		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-kconfig.git#for-next
+libata		git	git://github.com/jgarzik/libata-dev.git#NEXT
+infiniband	git	git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git#for-next
+acpi		git	git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git#next
+ieee1394	git	git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394.git#for-next
+ubi		git	git://git.infradead.org/ubi-2.6.git#linux-next
+dlm		git	git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git#next
+scsi		git	git://bedivere.hansenpartnership.com/git/scsi-misc-2.6.git#master
+target-updates	git	git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git#for-next
+target-merge	git	git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git#for-next-merge
+ibft		git	git://git.kernel.org/pub/scm/linux/kernel/git/konrad/ibft.git#linux-next
+isci		git	git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git#all
+slave-dma	git	git://git.infradead.org/users/vkoul/slave-dma.git#next
+dmaengine	git	git://git.kernel.org/pub/scm/linux/kernel/git/djbw/dmaengine.git#next
+net-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git#master
+wireless-next	git	git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next.git#master
+bluetooth	git	git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next.git#master
+mtd		git	git://git.infradead.org/mtd-2.6.git#master
+l2-mtd		git	git://git.infradead.org/users/dedekind/l2-mtd-2.6.git#master
+crypto		git	git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git#master
+sound		git	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git#for-next
+sound-asoc	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git#for-next
+cpufreq		git	git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git#next
+rr		quilt	http://ozlabs.org/~rusty/kernel/rr-latest/
+input		git	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git#next
+input-mt	git	git://github.com/rydberg/linux.git#for-next
+block		git	git://git.kernel.dk/linux-block.git#for-next
+device-mapper	quilt	http://people.redhat.com/agk/patches/linux/editing/
+embedded	git	git://git.infradead.org/embedded-2.6.git#master
+firmware	git	git://git.infradead.org/users/dwmw2/firmware-2.6.git#master
+battery		git	git://git.infradead.org/battery-2.6.git#master
+mmc		git	git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc.git#mmc-next
+kgdb		git	git://github.com/jwessel/linux-kgdb.git#kgdb-next
+slab		git	git://github.com/penberg/linux.git#for-next
+uclinux		git	git://git.kernel.org/pub/scm/linux/kernel/git/gerg/uclinux.git#for-next
+md		git	git://neil.brown.name/md#for-next
+mfd		git	git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git#for-next
+drm		git	git://people.freedesktop.org/~airlied/linux.git#drm-next
+fbdev		git	git://github.com/schandinat/linux-2.6.git#fbdev-next
+viafb		git	git://github.com/schandinat/linux-2.6.git#viafb-next
+omap_dss2	git	git://gitorious.org/linux-omap-dss2/linux.git#for-next
+regulator	git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git#for-next
+security	git	git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git#next
+selinux		git	git://git.infradead.org/users/eparis/selinux.git#master
+lblnet		git	git://git.infradead.org/users/pcmoore/lblnet-2.6_next#master
+watchdog	git	git://www.linux-watchdog.org/linux-watchdog.git#linux-next
+dwmw2-iommu	git	git://git.infradead.org/iommu-2.6.git#master
+iommu		git	git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git#next
+osd		git	git://git.open-osd.org/linux-open-osd.git#linux-next
+jc_docs		git	git://git.lwn.net/linux-2.6.git#docs-next
+trivial		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git#for-next
+audit		git	git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit.git#for-next
+pm		git	git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git#linux-next
+apm		git	git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm.git#for-next
+fsnotify	git	git://git.infradead.org/users/eparis/notify.git#for-next
+edac		git	git://git.infradead.org/users/mchehab/edac.git#linux_next
+edac-amd	git	git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git#for-next
+devicetree	git	git://git.secretlab.ca/git/linux-2.6#devicetree/next
+spi		git	git://git.secretlab.ca/git/linux-2.6#spi/next
+gpio		git	git://git.secretlab.ca/git/linux-2.6#gpio/next
+tip		git	git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#auto-latest
+rcu		git	git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git#rcu/next
+cputime		git	git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git#cputime
+uprobes		git	git://github.com/srikard/linux.git#for-next
+cgroup		git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git#for-next
+kmemleak	git	git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux.git#kmemleak
+kvm		git	git://git.kernel.org/pub/scm/virt/kvm/kvm.git#linux-next
+oprofile	git	git://amd64.org/linux/rric.git#for-next
+xen		git	git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git#upstream/xen
+xen-two		git	git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen.git#linux-next
+xen-pvhvm	git	git://xenbits.xen.org/people/sstabellini/linux-pvhvm.git#linux-next
+percpu		git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git#for-next
+workqueues	git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git#for-next
+hwpoison	git	git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6.git#hwpoison
+sysctl		git	git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/sysctl.git#master
+regmap		git	git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git#for-next
+hsi		git	git://gitorious.org/kernel-hsi/kernel-hsi.git#for-next
+driver-core	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git#driver-core-next
+tty		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git#tty-next
+usb		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git#usb-next
+staging		git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git#staging-next
+char-misc	git	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git#char-misc-next
+arm-soc		git	git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git#for-next
+tmem		git	git://git.kernel.org/pub/scm/linux/kernel/git/konrad/mm.git#linux-next
+writeback	git	git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux.git#writeback-for-next
+arm-dt		git	git://git.secretlab.ca/git/linux-2.6#devicetree/arm-next
+hwspinlock	git	git://github.com/ohadbc/hwspinlock-next.git#linux-next
+pinctrl		git	git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git#for-next
+moduleh		git	git://openlinux.windriver.com/people/paulg/linux-next#for-sfr
+vhost		git	git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git#linux-next
+kmap_atomic	git	git://github.com/congwang/linux.git#kmap_atomic
+modem-shm	git	git://github.com/sjurbren/modem-ipc.git#for-next
+memblock	git	git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc.git#memblock-kill-early_node_map
+remoteproc	git	git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc.git#for-next
+irqdomain	git	git://git.secretlab.ca/git/linux-2.6.git#irqdomain/next
+kvmtool		git	git://github.com/penberg/linux-kvm.git#master
+dma-mapping	git	git://git.infradead.org/users/kmpark/linux-samsung#dma-mapping-next
+ktest		git	git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-ktest.git#for-next
+scsi-post-merge	git	git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-post-merge-2.6.git#master
+akpm		mmotm	http://userweb.kernel.org/~akpm/mmotm/
diff --git a/Next/merge.log b/Next/merge.log
new file mode 100644
index 0000000..0c6ed9e
--- /dev/null
+++ b/Next/merge.log
@@ -0,0 +1,7662 @@
+$ date
+Wed Feb 22 10:44:17 EST 2012
+$ git checkout master
+Already on 'master'
+$ git reset --hard stable
+HEAD is now at b01543d Linux 3.3-rc4
+Merging origin/master (27e74da i387: export 'fpu_owner_task' per-cpu variable)
+$ git merge origin/master
+Updating b01543d..27e74da
+Fast-forward
+ arch/s390/kernel/process.c       |    5 ++-
+ arch/s390/kernel/time.c          |    7 +++-
+ arch/s390/mm/pgtable.c           |    2 +-
+ arch/x86/include/asm/i387.h      |   53 +++++++++++++++++++++++++----------
+ arch/x86/include/asm/processor.h |    3 +-
+ arch/x86/kernel/cpu/common.c     |    5 +++
+ arch/x86/kernel/process_32.c     |    3 +-
+ arch/x86/kernel/process_64.c     |    3 +-
+ arch/x86/kernel/traps.c          |   40 +++++---------------------
+ drivers/s390/char/con3215.c      |   22 ++++++++++-----
+ fs/autofs4/expire.c              |    2 +
+ fs/compat.c                      |   56 +++++++++++++++++---------------------
+ fs/dcache.c                      |    8 +++---
+ fs/inode.c                       |    8 +++---
+ fs/namei.c                       |    4 ++-
+ fs/ocfs2/namei.c                 |    2 +-
+ fs/quota/quota.c                 |   24 ++++++++++++++--
+ fs/super.c                       |   22 +++++++++++++++
+ include/linux/digsig.h           |    4 +-
+ include/linux/fs.h               |    1 +
+ kernel/pid.c                     |    4 +-
+ mm/page_alloc.c                  |    1 +
+ net/ipv4/tcp.c                   |    5 ++-
+ 23 files changed, 172 insertions(+), 112 deletions(-)
+Merging fixes/master (2b79574 tty/powerpc: early udbg consoles can't be modules)
+$ git merge fixes/master
+Merge made by the 'recursive' strategy.
+ drivers/tty/Kconfig |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+Merging kbuild-current/rc-fixes (6c63522 builddeb: Don't create files in /tmp with predictable names)
+$ git merge kbuild-current/rc-fixes
+Merge made by the 'recursive' strategy.
+ scripts/depmod.sh        |    6 ------
+ scripts/package/builddeb |   12 ++++++------
+ 2 files changed, 6 insertions(+), 12 deletions(-)
+Merging arm-current/fixes (5180bb3 ARM/audit: include audit header and fix audit arch)
+$ git merge arm-current/fixes
+Merge made by the 'recursive' strategy.
+ arch/arm/common/it8152.c                      |    7 -------
+ arch/arm/common/pl330.c                       |    3 ++-
+ arch/arm/include/asm/assembler.h              |    5 +++++
+ arch/arm/include/asm/hardware/pl330.h         |    2 +-
+ arch/arm/include/asm/processor.h              |    1 +
+ arch/arm/kernel/ptrace.c                      |    9 ++++++++-
+ arch/arm/kernel/smp_twd.c                     |    2 +-
+ arch/arm/mach-omap2/voltagedomains3xxx_data.c |    2 ++
+ arch/arm/mach-omap2/voltagedomains44xx_data.c |    2 ++
+ arch/arm/mm/Kconfig                           |    3 ++-
+ arch/arm/mm/cache-v7.S                        |    2 +-
+ scripts/mod/modpost.c                         |    9 +++++++++
+ 12 files changed, 34 insertions(+), 13 deletions(-)
+Merging m68k-current/for-linus (2a35350 m68k: Fix assembler constraint to prevent overeager gcc optimisation)
+$ git merge m68k-current/for-linus
+Already up-to-date.
+Merging powerpc-merge/merge (9a45a94 powerpc/perf: power_pmu_start restores incorrect values, breaking frequency events)
+$ git merge powerpc-merge/merge
+Already up-to-date.
+Merging 52xx-and-virtex-current/powerpc/merge (c49f878 dtc/powerpc: remove obsolete .gitignore entries)
+$ git merge 52xx-and-virtex-current/powerpc/merge
+Already up-to-date.
+Merging sparc/master (e51e07e sparc32: forced setting of mode of sun4m per-cpu timers)
+$ git merge sparc/master
+Already up-to-date.
+Merging scsi-rc-fixes/master (fea6d60 [SCSI] scsi_pm: Fix bug in the SCSI power management handler)
+$ git merge scsi-rc-fixes/master
+Merge made by the 'recursive' strategy.
+ drivers/scsi/ipr.c                  |   24 ++++++++++++----
+ drivers/scsi/isci/host.c            |    4 ++-
+ drivers/scsi/mpt2sas/mpt2sas_base.c |    3 +-
+ drivers/scsi/qla2xxx/qla_attr.c     |   13 +++------
+ drivers/scsi/qla2xxx/qla_bsg.c      |   50 ++++++----------------------------
+ drivers/scsi/qla2xxx/qla_dbg.c      |    3 +-
+ drivers/scsi/qla2xxx/qla_def.h      |    1 +
+ drivers/scsi/qla2xxx/qla_inline.h   |   13 +++++++++
+ drivers/scsi/qla2xxx/qla_isr.c      |    1 -
+ drivers/scsi/qla2xxx/qla_mbx.c      |    7 ++++-
+ drivers/scsi/qla2xxx/qla_nx.c       |   15 +----------
+ drivers/scsi/qla2xxx/qla_os.c       |   19 +++++-------
+ drivers/scsi/qla2xxx/qla_version.h  |    2 +-
+ drivers/scsi/scsi_pm.c              |   16 +++++++++++
+ drivers/scsi/scsi_priv.h            |    1 +
+ drivers/scsi/scsi_scan.c            |    4 +-
+ 16 files changed, 87 insertions(+), 89 deletions(-)
+Merging net/master (84338a6 neighbour: Fixed race condition at tbl->nht)
+$ git merge net/master
+Merge made by the 'recursive' strategy.
+ drivers/atm/solos-pci.c                         |    4 +-
+ drivers/bluetooth/btusb.c                       |    4 +--
+ drivers/net/can/sja1000/sja1000.c               |   13 +++++++++++-
+ drivers/net/ethernet/atheros/atl1c/atl1c_main.c |    4 ---
+ drivers/net/ethernet/broadcom/b44.c             |    2 +-
+ drivers/net/ethernet/mellanox/mlx4/eq.c         |    8 +++---
+ drivers/net/ethernet/mellanox/mlx4/main.c       |   10 +++++---
+ drivers/net/ethernet/mellanox/mlx4/mlx4.h       |    2 +-
+ drivers/net/ethernet/micrel/ks8851_mll.c        |    2 +-
+ drivers/net/usb/zaurus.c                        |    5 ++++
+ drivers/net/vmxnet3/vmxnet3_drv.c               |    4 +-
+ drivers/net/wireless/ath/ath9k/rc.c             |    2 +-
+ drivers/net/wireless/mwifiex/cfg80211.c         |    8 ++++++-
+ include/net/bluetooth/bluetooth.h               |    2 +
+ include/net/bluetooth/hci_core.h                |    6 ++--
+ include/net/bluetooth/l2cap.h                   |   12 +++++-----
+ net/bluetooth/af_bluetooth.c                    |   12 ++++------
+ net/bluetooth/hci_conn.c                        |    4 +++
+ net/bluetooth/hci_core.c                        |    3 +-
+ net/bluetooth/l2cap_core.c                      |   24 +++++++++++++---------
+ net/bluetooth/l2cap_sock.c                      |    4 ++-
+ net/bluetooth/rfcomm/core.c                     |   18 +++++++++++-----
+ net/bluetooth/rfcomm/sock.c                     |    2 +
+ net/core/neighbour.c                            |    2 +
+ net/mac80211/debugfs_sta.c                      |    4 +-
+ net/mac80211/rate.c                             |    2 +-
+ net/mac80211/rate.h                             |    3 +-
+ net/mac80211/sta_info.h                         |    2 +
+ net/sched/sch_netem.c                           |    6 +---
+ 29 files changed, 107 insertions(+), 67 deletions(-)
+Merging sound-current/for-linus (fe879e2 Merge tag 'asoc-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus)
+$ git merge sound-current/for-linus
+Merge made by the 'recursive' strategy.
+ sound/pci/hda/patch_realtek.c |   19 ++++++++++++++++---
+ sound/soc/codecs/ak4642.c     |   31 ++++++++++++++++---------------
+ sound/soc/codecs/wm8962.c     |    2 +-
+ sound/usb/card.h              |    1 +
+ sound/usb/format.c            |    4 +---
+ sound/usb/quirks.c            |    6 +++++-
+ 6 files changed, 40 insertions(+), 23 deletions(-)
+Merging pci-current/for-linus (3682a39 PCI: Fix pci cardbus removal)
+$ git merge pci-current/for-linus
+Already up-to-date.
+Merging wireless/master (0dee006 mac80211: Fix a warning on changing to monitor mode from STA)
+$ git merge wireless/master
+Merge made by the 'recursive' strategy.
+ drivers/net/wireless/ath/ath9k/ar5008_phy.c |   25 +------------------------
+ drivers/net/wireless/ath/ath9k/ar9002_hw.c  |   19 +++++++++++++++++++
+ drivers/net/wireless/ath/ath9k/hw.h         |    1 -
+ drivers/net/wireless/iwlwifi/iwl-agn-sta.c  |   10 +++++++++-
+ drivers/net/wireless/rt2x00/rt2x00dev.c     |    3 ++-
+ net/mac80211/iface.c                        |    3 +++
+ net/mac80211/rate.c                         |    2 +-
+ 7 files changed, 35 insertions(+), 28 deletions(-)
+Merging driver-core.current/driver-core-linus (29bb5d4 driver-core: cpu: fix kobject warning when hotplugging a cpu)
+$ git merge driver-core.current/driver-core-linus
+Already up-to-date.
+Merging tty.current/tty-linus (b01543d Linux 3.3-rc4)
+$ git merge tty.current/tty-linus
+Already up-to-date.
+Merging usb.current/usb-linus (b9e44fe USB: option: cleanup zte 3g-dongle's pid in option.c)
+$ git merge usb.current/usb-linus
+Merge made by the 'recursive' strategy.
+ drivers/usb/core/hcd-pci.c  |    5 +-
+ drivers/usb/core/hcd.c      |    6 +-
+ drivers/usb/host/xhci-hub.c |    2 +-
+ drivers/usb/host/xhci.c     |    5 ++
+ drivers/usb/serial/option.c |  143 ++++---------------------------------------
+ include/linux/usb/ch11.h    |   10 +---
+ 6 files changed, 29 insertions(+), 142 deletions(-)
+Merging staging.current/staging-linus (b01543d Linux 3.3-rc4)
+$ git merge staging.current/staging-linus
+Already up-to-date.
+Merging char-misc.current/char-misc-linus (b5266ea mmc: cb710 core: Add missing spin_lock_init for irq_lock of struct cb710_chip)
+$ git merge char-misc.current/char-misc-linus
+Already up-to-date.
+Merging cpufreq-current/fixes (5983fe2 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net)
+$ git merge cpufreq-current/fixes
+Already up-to-date.
+Merging input-current/for-linus (82b982c Input: i8042 - add Lenovo Ideapad U455 to 'reset' blacklist)
+$ git merge input-current/for-linus
+Already up-to-date.
+Merging md-current/for-linus (db91ff5 md: two small fixes to handling interrupt resync.)
+$ git merge md-current/for-linus
+Already up-to-date.
+Merging audit-current/for-linus (c158a35 audit: no leading space in audit_log_d_path prefix)
+$ git merge audit-current/for-linus
+Already up-to-date.
+Merging crypto-current/master (f2ea0f5 crypto: sha512 - use standard ror64())
+$ git merge crypto-current/master
+Already up-to-date.
+Merging ide/master (0ab3d8b cy82c693: fix PCI device selection)
+$ git merge ide/master
+Already up-to-date.
+Merging dwmw2/master (244dc4e Merge git://git.infradead.org/users/dwmw2/random-2.6)
+$ git merge dwmw2/master
+Already up-to-date.
+Merging devicetree-current/devicetree/merge (2261cc6 dt: add empty of_find_compatible_node function)
+$ git merge devicetree-current/devicetree/merge
+Merge made by the 'recursive' strategy.
+ arch/arm/boot/.gitignore |    1 +
+ include/linux/of.h       |    8 ++++++++
+ 2 files changed, 9 insertions(+), 0 deletions(-)
+Merging spi-current/spi/merge (c88db23 spi-topcliff-pch: rename pch_spi_pcidev to pch_spi_pcidev_driver)
+$ git merge spi-current/spi/merge
+Already up-to-date.
+Merging gpio-current/gpio/merge (7e3a70f gpio: Add missing spin_lock_init in gpio-ml-ioh driver)
+$ git merge gpio-current/gpio/merge
+Already up-to-date.
+Merging arm/for-next (cb63a5b Merge branch 'devel-stable' into for-next)
+$ git merge arm/for-next
+Auto-merging drivers/pcmcia/sa1111_neponset.c
+Auto-merging drivers/pcmcia/sa1111_lubbock.c
+Auto-merging drivers/pcmcia/sa1111_jornada720.c
+Auto-merging drivers/pcmcia/sa1111_badge4.c
+Removing arch/arm/plat-spear/include/plat/system.h
+Removing arch/arm/plat-omap/include/plat/system.h
+Removing arch/arm/plat-mxc/include/mach/system.h
+Removing arch/arm/mach-zynq/include/mach/system.h
+Removing arch/arm/mach-w90x900/include/mach/system.h
+Removing arch/arm/mach-vexpress/include/mach/system.h
+Removing arch/arm/mach-versatile/include/mach/system.h
+Removing arch/arm/mach-ux500/include/mach/system.h
+Removing arch/arm/mach-u300/include/mach/system.h
+Removing arch/arm/mach-tegra/include/mach/system.h
+Removing arch/arm/mach-spear6xx/include/mach/system.h
+Removing arch/arm/mach-spear3xx/include/mach/system.h
+Removing arch/arm/mach-shark/include/mach/system.h
+Removing arch/arm/mach-sa1100/include/mach/system.h
+Removing arch/arm/mach-sa1100/include/mach/dma.h
+Removing arch/arm/mach-sa1100/dma.c
+Removing arch/arm/mach-s5pv210/include/mach/system.h
+Removing arch/arm/mach-s5pc100/include/mach/system.h
+Removing arch/arm/mach-s5p64x0/include/mach/system.h
+Removing arch/arm/mach-s3c64xx/include/mach/system.h
+Removing arch/arm/mach-s3c2410/include/mach/system.h
+Removing arch/arm/mach-rpc/include/mach/system.h
+Removing arch/arm/mach-realview/include/mach/system.h
+Removing arch/arm/mach-pxa/include/mach/system.h
+Removing arch/arm/mach-prima2/include/mach/system.h
+Removing arch/arm/mach-pnx4008/include/mach/system.h
+Removing arch/arm/mach-picoxcell/include/mach/system.h
+Removing arch/arm/mach-picoxcell/include/mach/irqs.h
+Removing arch/arm/mach-orion5x/include/mach/system.h
+Auto-merging arch/arm/mach-omap2/pm24xx.c
+Removing arch/arm/mach-omap2/include/mach/system.h
+Removing arch/arm/mach-omap1/include/mach/system.h
+Removing arch/arm/mach-nomadik/include/mach/system.h
+Removing arch/arm/mach-netx/include/mach/system.h
+Removing arch/arm/mach-mxs/include/mach/system.h
+Removing arch/arm/mach-mv78xx0/include/mach/system.h
+Removing arch/arm/mach-msm/idle.S
+Removing arch/arm/mach-mmp/include/mach/system.h
+Removing arch/arm/mach-lpc32xx/include/mach/system.h
+Removing arch/arm/mach-ks8695/include/mach/system.h
+Removing arch/arm/mach-kirkwood/include/mach/system.h
+Removing arch/arm/mach-ixp4xx/include/mach/system.h
+Removing arch/arm/mach-ixp23xx/include/mach/system.h
+Removing arch/arm/mach-ixp2000/include/mach/system.h
+Removing arch/arm/mach-iop33x/include/mach/system.h
+Removing arch/arm/mach-iop32x/include/mach/system.h
+Removing arch/arm/mach-iop13xx/include/mach/system.h
+Removing arch/arm/mach-integrator/include/mach/system.h
+Removing arch/arm/mach-highbank/include/mach/system.h
+Removing arch/arm/mach-highbank/include/mach/irqs.h
+Removing arch/arm/mach-h720x/include/mach/system.h
+Removing arch/arm/mach-footbridge/include/mach/system.h
+Removing arch/arm/mach-exynos/include/mach/system.h
+Removing arch/arm/mach-ep93xx/include/mach/system.h
+Removing arch/arm/mach-ebsa110/include/mach/system.h
+Removing arch/arm/mach-dove/include/mach/system.h
+Removing arch/arm/mach-davinci/include/mach/system.h
+Removing arch/arm/mach-cns3xxx/include/mach/system.h
+Removing arch/arm/mach-clps711x/include/mach/system.h
+Removing arch/arm/mach-bcmring/include/mach/system.h
+Removing arch/arm/mach-at91/include/mach/system.h
+Merge made by the 'recursive' strategy.
+ arch/arm/Kconfig                                   |   21 +-
+ arch/arm/Kconfig.debug                             |  156 ++--
+ arch/arm/boot/compressed/.gitignore                |    2 +
+ arch/arm/boot/compressed/Makefile                  |   15 +-
+ arch/arm/boot/compressed/decompress.c              |    6 +
+ arch/arm/boot/compressed/piggy.xzkern.S            |    6 +
+ arch/arm/common/gic.c                              |   13 +-
+ arch/arm/common/sa1111.c                           |  281 ++++--
+ arch/arm/configs/integrator_defconfig              |    8 +
+ arch/arm/include/asm/cp15.h                        |   87 ++
+ arch/arm/include/asm/elf.h                         |    4 -
+ arch/arm/include/asm/hardware/cache-l2x0.h         |    6 +-
+ arch/arm/include/asm/hardware/it8152.h             |    3 +
+ arch/arm/include/asm/hardware/sa1111.h             |  156 +---
+ arch/arm/include/asm/irq.h                         |    8 +-
+ arch/arm/include/asm/mc146818rtc.h                 |    4 +-
+ arch/arm/include/asm/mmu_context.h                 |   29 +-
+ arch/arm/include/asm/opcodes.h                     |   59 +
+ arch/arm/include/asm/page.h                        |    2 +
+ arch/arm/include/asm/perf_event.h                  |    1 +
+ arch/arm/include/asm/prom.h                        |    2 -
+ arch/arm/include/asm/system.h                      |   78 +--
+ arch/arm/include/asm/tlbflush.h                    |  136 +--
+ arch/arm/include/asm/traps.h                       |    2 +-
+ arch/arm/kernel/Makefile                           |   13 +-
+ arch/arm/kernel/ecard.c                            |    6 +-
+ arch/arm/kernel/fiq.c                              |    2 +-
+ arch/arm/kernel/ftrace.c                           |   90 +--
+ arch/arm/kernel/head-nommu.S                       |    2 +-
+ arch/arm/kernel/head.S                             |    2 +-
+ arch/arm/kernel/insn.c                             |   61 ++
+ arch/arm/kernel/insn.h                             |   19 +
+ arch/arm/kernel/irq.c                              |    5 +-
+ arch/arm/kernel/kprobes.c                          |   86 +--
+ arch/arm/kernel/machine_kexec.c                    |   25 +
+ arch/arm/kernel/patch.c                            |   75 ++
+ arch/arm/kernel/patch.h                            |    7 +
+ arch/arm/kernel/perf_event.c                       |    3 +
+ arch/arm/kernel/perf_event_v7.c                    |  145 +++
+ arch/arm/kernel/process.c                          |   65 +-
+ arch/arm/kernel/sched_clock.c                      |   18 +
+ arch/arm/kernel/setup.c                            |    3 +-
+ arch/arm/kernel/smp.c                              |   17 +-
+ arch/arm/kernel/time.c                             |    4 -
+ arch/arm/kernel/traps.c                            |   19 +-
+ arch/arm/mach-at91/at91cap9.c                      |    8 +
+ arch/arm/mach-at91/at91rm9200.c                    |   10 +
+ arch/arm/mach-at91/at91sam9260.c                   |    8 +
+ arch/arm/mach-at91/at91sam9261.c                   |    8 +
+ arch/arm/mach-at91/at91sam9263.c                   |    8 +
+ arch/arm/mach-at91/at91sam9g45.c                   |    7 +
+ arch/arm/mach-at91/at91sam9rl.c                    |    8 +
+ arch/arm/mach-at91/at91x40.c                       |   12 +
+ arch/arm/mach-at91/include/mach/system.h           |   50 -
+ arch/arm/mach-bcmring/core.c                       |   23 +-
+ arch/arm/mach-bcmring/include/mach/system.h        |   28 -
+ arch/arm/mach-clps711x/common.c                    |   16 +
+ arch/arm/mach-clps711x/include/mach/system.h       |   35 -
+ arch/arm/mach-cns3xxx/include/mach/system.h        |   25 -
+ arch/arm/mach-davinci/include/mach/system.h        |   21 -
+ arch/arm/mach-davinci/time.c                       |   28 +-
+ arch/arm/mach-dove/include/mach/system.h           |   17 -
+ arch/arm/mach-ebsa110/core.c                       |   38 +-
+ arch/arm/mach-ebsa110/core.h                       |   41 +
+ arch/arm/mach-ebsa110/include/mach/hardware.h      |   39 -
+ arch/arm/mach-ebsa110/include/mach/system.h        |   37 -
+ arch/arm/mach-ebsa110/io.c                         |   20 +
+ arch/arm/mach-ebsa110/leds.c                       |    2 +
+ arch/arm/mach-ep93xx/core.c                        |   46 +-
+ arch/arm/mach-ep93xx/include/mach/system.h         |    7 -
+ arch/arm/mach-exynos/common.c                      |   12 -
+ arch/arm/mach-exynos/dma.c                         |   38 +-
+ arch/arm/mach-exynos/hotplug.c                     |    1 +
+ arch/arm/mach-exynos/include/mach/system.h         |   20 -
+ arch/arm/mach-footbridge/include/mach/system.h     |   13 -
+ arch/arm/mach-gemini/Makefile                      |    2 +-
+ arch/arm/mach-gemini/idle.c                        |   29 +
+ arch/arm/mach-gemini/include/mach/system.h         |   14 -
+ arch/arm/mach-gemini/irq.c                         |    4 +-
+ arch/arm/mach-h720x/common.c                       |   18 +
+ arch/arm/mach-h720x/include/mach/system.h          |   27 -
+ arch/arm/mach-highbank/highbank.c                  |    1 -
+ arch/arm/mach-highbank/include/mach/irqs.h         |    6 -
+ arch/arm/mach-highbank/include/mach/system.h       |   24 -
+ arch/arm/mach-imx/mm-imx3.c                        |   52 +-
+ arch/arm/mach-imx/mm-imx5.c                        |   28 +-
+ arch/arm/mach-imx/pm-imx27.c                       |    3 +-
+ arch/arm/mach-integrator/core.c                    |   70 +-
+ arch/arm/mach-integrator/impd1.c                   |    9 +-
+ arch/arm/mach-integrator/include/mach/system.h     |   33 -
+ arch/arm/mach-integrator/integrator_ap.c           |    7 +
+ arch/arm/mach-integrator/integrator_cp.c           |   49 +-
+ arch/arm/mach-iop13xx/include/mach/system.h        |   13 -
+ arch/arm/mach-iop32x/include/mach/system.h         |   13 -
+ arch/arm/mach-iop33x/include/mach/system.h         |   13 -
+ arch/arm/mach-ixp2000/include/mach/system.h        |   14 -
+ arch/arm/mach-ixp23xx/core.c                       |    3 +
+ arch/arm/mach-ixp23xx/include/mach/system.h        |   16 -
+ arch/arm/mach-ixp4xx/common.c                      |    6 +
+ arch/arm/mach-ixp4xx/include/mach/system.h         |   19 -
+ arch/arm/mach-kirkwood/include/mach/system.h       |   17 -
+ arch/arm/mach-ks8695/include/mach/system.h         |   27 -
+ arch/arm/mach-lpc32xx/include/mach/system.h        |   27 -
+ arch/arm/mach-lpc32xx/phy3250.c                    |   32 +-
+ arch/arm/mach-mmp/aspenite.c                       |    5 +-
+ arch/arm/mach-mmp/avengers_lite.c                  |    1 +
+ arch/arm/mach-mmp/brownstone.c                     |    4 +-
+ arch/arm/mach-mmp/flint.c                          |    3 +-
+ arch/arm/mach-mmp/gplugd.c                         |    2 +-
+ arch/arm/mach-mmp/include/mach/irqs.h              |    3 +-
+ arch/arm/mach-mmp/include/mach/system.h            |   16 -
+ arch/arm/mach-mmp/irq-mmp2.c                       |    1 +
+ arch/arm/mach-mmp/jasper.c                         |    5 +-
+ arch/arm/mach-mmp/tavorevb.c                       |    1 +
+ arch/arm/mach-mmp/teton_bga.c                      |    3 +-
+ arch/arm/mach-mmp/ttc_dkb.c                        |    4 +-
+ arch/arm/mach-msm/idle.S                           |   36 -
+ arch/arm/mach-msm/idle.c                           |   49 +
+ arch/arm/mach-msm/include/mach/system.h            |    1 -
+ arch/arm/mach-mv78xx0/include/mach/system.h        |   17 -
+ arch/arm/mach-mxs/devices.c                        |    8 +-
+ arch/arm/mach-mxs/devices/amba-duart.c             |    2 +-
+ arch/arm/mach-mxs/include/mach/system.h            |   25 -
+ arch/arm/mach-mxs/pm.c                             |    3 +-
+ arch/arm/mach-netx/fb.c                            |   13 +-
+ arch/arm/mach-netx/include/mach/system.h           |   28 -
+ arch/arm/mach-nomadik/board-nhk8815.c              |   17 +-
+ arch/arm/mach-nomadik/cpu-8815.c                   |    9 +-
+ arch/arm/mach-nomadik/include/mach/system.h        |   32 -
+ arch/arm/mach-omap1/include/mach/system.h          |    5 -
+ arch/arm/mach-omap1/pm.c                           |   19 +-
+ arch/arm/mach-omap2/emu.c                          |   26 +-
+ arch/arm/mach-omap2/include/mach/system.h          |    5 -
+ arch/arm/mach-omap2/pm24xx.c                       |    4 +-
+ arch/arm/mach-omap2/pm34xx.c                       |    6 +-
+ arch/arm/mach-omap2/pm44xx.c                       |    8 +-
+ arch/arm/mach-omap2/prm_common.c                   |    1 -
+ arch/arm/mach-orion5x/include/mach/system.h        |   19 -
+ arch/arm/mach-picoxcell/include/mach/irqs.h        |   20 -
+ arch/arm/mach-picoxcell/include/mach/system.h      |   26 -
+ arch/arm/mach-pnx4008/include/mach/system.h        |   29 -
+ arch/arm/mach-prima2/include/mach/system.h         |   17 -
+ arch/arm/mach-prima2/timer.c                       |   21 +-
+ arch/arm/mach-pxa/capc7117.c                       |    1 +
+ arch/arm/mach-pxa/cm-x300.c                        |    1 +
+ arch/arm/mach-pxa/colibri-pxa270.c                 |    2 +
+ arch/arm/mach-pxa/colibri-pxa300.c                 |    1 +
+ arch/arm/mach-pxa/colibri-pxa320.c                 |    1 +
+ arch/arm/mach-pxa/corgi.c                          |    3 +
+ arch/arm/mach-pxa/csb726.c                         |    1 +
+ arch/arm/mach-pxa/devices.c                        |    1 +
+ arch/arm/mach-pxa/em-x270.c                        |    2 +
+ arch/arm/mach-pxa/gumstix.c                        |    1 +
+ arch/arm/mach-pxa/h5000.c                          |    1 +
+ arch/arm/mach-pxa/himalaya.c                       |    1 +
+ arch/arm/mach-pxa/icontrol.c                       |    1 +
+ arch/arm/mach-pxa/idp.c                            |    1 +
+ arch/arm/mach-pxa/include/mach/balloon3.h          |    1 -
+ arch/arm/mach-pxa/include/mach/irqs.h              |    2 +-
+ arch/arm/mach-pxa/include/mach/system.h            |   15 -
+ arch/arm/mach-pxa/lubbock.c                        |    1 +
+ arch/arm/mach-pxa/mioa701.c                        |    1 +
+ arch/arm/mach-pxa/mp900.c                          |    1 +
+ arch/arm/mach-pxa/palmld.c                         |    1 +
+ arch/arm/mach-pxa/palmt5.c                         |    1 +
+ arch/arm/mach-pxa/palmtc.c                         |    1 +
+ arch/arm/mach-pxa/palmte2.c                        |    1 +
+ arch/arm/mach-pxa/palmtreo.c                       |    2 +
+ arch/arm/mach-pxa/palmtx.c                         |    1 +
+ arch/arm/mach-pxa/palmz72.c                        |    1 +
+ arch/arm/mach-pxa/pxa3xx.c                         |    1 +
+ arch/arm/mach-pxa/raumfeld.c                       |    3 +
+ arch/arm/mach-pxa/saar.c                           |    1 +
+ arch/arm/mach-pxa/spitz.c                          |    3 +
+ arch/arm/mach-pxa/stargate2.c                      |    1 +
+ arch/arm/mach-pxa/tavorevb.c                       |    1 +
+ arch/arm/mach-pxa/time.c                           |    1 +
+ arch/arm/mach-pxa/trizeps4.c                       |    2 +
+ arch/arm/mach-pxa/viper.c                          |    1 +
+ arch/arm/mach-pxa/vpac270.c                        |    1 +
+ arch/arm/mach-pxa/xcep.c                           |    1 +
+ arch/arm/mach-pxa/z2.c                             |    1 +
+ arch/arm/mach-realview/core.h                      |   20 +-
+ arch/arm/mach-realview/hotplug.c                   |    1 +
+ arch/arm/mach-realview/include/mach/irqs-eb.h      |   23 +-
+ arch/arm/mach-realview/include/mach/irqs-pb1176.h  |    2 +-
+ arch/arm/mach-realview/include/mach/system.h       |   33 -
+ arch/arm/mach-realview/realview_eb.c               |   78 +-
+ arch/arm/mach-realview/realview_pb1176.c           |   78 +-
+ arch/arm/mach-realview/realview_pb11mp.c           |   78 +-
+ arch/arm/mach-realview/realview_pba8.c             |   78 +-
+ arch/arm/mach-realview/realview_pbx.c              |   78 +-
+ arch/arm/mach-rpc/include/mach/system.h            |   13 -
+ arch/arm/mach-s3c2410/include/mach/system.h        |   54 -
+ arch/arm/mach-s3c2412/s3c2412.c                    |    4 +-
+ arch/arm/mach-s3c2416/s3c2416.c                    |    3 -
+ arch/arm/mach-s3c64xx/include/mach/system.h        |   19 -
+ arch/arm/mach-s5p64x0/common.c                     |   15 +-
+ arch/arm/mach-s5p64x0/dma.c                        |   22 +-
+ arch/arm/mach-s5p64x0/include/mach/system.h        |   21 -
+ arch/arm/mach-s5pc100/common.c                     |   12 -
+ arch/arm/mach-s5pc100/dma.c                        |   38 +-
+ arch/arm/mach-s5pc100/include/mach/system.h        |   19 -
+ arch/arm/mach-s5pv210/common.c                     |   12 -
+ arch/arm/mach-s5pv210/dma.c                        |   38 +-
+ arch/arm/mach-s5pv210/include/mach/system.h        |   21 -
+ arch/arm/mach-sa1100/Makefile                      |    2 +-
+ arch/arm/mach-sa1100/assabet.c                     |  191 +++-
+ arch/arm/mach-sa1100/badge4.c                      |   41 +-
+ arch/arm/mach-sa1100/cerf.c                        |   14 +-
+ arch/arm/mach-sa1100/collie.c                      |   52 +-
+ arch/arm/mach-sa1100/dma.c                         |  348 ------
+ arch/arm/mach-sa1100/generic.c                     |  147 ++--
+ arch/arm/mach-sa1100/generic.h                     |    7 +-
+ arch/arm/mach-sa1100/h3100.c                       |   23 +-
+ arch/arm/mach-sa1100/h3600.c                       |   32 +-
+ arch/arm/mach-sa1100/h3xxx.c                       |   13 +-
+ arch/arm/mach-sa1100/hackkit.c                     |    7 +-
+ arch/arm/mach-sa1100/include/mach/SA-1100.h        |  229 +----
+ arch/arm/mach-sa1100/include/mach/assabet.h        |   15 +-
+ arch/arm/mach-sa1100/include/mach/cerf.h           |   15 +-
+ arch/arm/mach-sa1100/include/mach/dma.h            |  117 --
+ arch/arm/mach-sa1100/include/mach/irqs.h           |   24 +-
+ arch/arm/mach-sa1100/include/mach/mcp.h            |    2 +-
+ arch/arm/mach-sa1100/include/mach/nanoengine.h     |   12 +-
+ arch/arm/mach-sa1100/include/mach/neponset.h       |   52 +-
+ arch/arm/mach-sa1100/include/mach/shannon.h        |   14 +-
+ arch/arm/mach-sa1100/include/mach/simpad.h         |    6 +-
+ arch/arm/mach-sa1100/include/mach/system.h         |    9 -
+ arch/arm/mach-sa1100/irq.c                         |    7 +-
+ arch/arm/mach-sa1100/jornada720.c                  |   40 +-
+ arch/arm/mach-sa1100/lart.c                        |   80 ++
+ arch/arm/mach-sa1100/nanoengine.c                  |   11 +-
+ arch/arm/mach-sa1100/neponset.c                    |  546 ++++++----
+ arch/arm/mach-sa1100/pci-nanoengine.c              |    8 +-
+ arch/arm/mach-sa1100/pleb.c                        |   24 +-
+ arch/arm/mach-sa1100/shannon.c                     |   25 +-
+ arch/arm/mach-sa1100/simpad.c                      |   19 +-
+ arch/arm/mach-sa1100/sleep.S                       |   37 +-
+ arch/arm/mach-shark/core.c                         |    6 +
+ arch/arm/mach-shark/include/mach/system.h          |   13 -
+ arch/arm/mach-shmobile/Kconfig                     |    4 +
+ arch/arm/mach-shmobile/board-ag5evm.c              |    1 +
+ arch/arm/mach-shmobile/board-bonito.c              |    1 +
+ arch/arm/mach-shmobile/board-g3evm.c               |    1 +
+ arch/arm/mach-shmobile/board-g4evm.c               |    1 +
+ arch/arm/mach-shmobile/board-kota2.c               |    1 +
+ arch/arm/mach-shmobile/board-mackerel.c            |    1 +
+ arch/arm/mach-shmobile/board-marzen.c              |    1 +
+ arch/arm/mach-shmobile/include/mach/irqs.h         |    6 +-
+ arch/arm/mach-shmobile/include/mach/system.h       |    5 -
+ arch/arm/mach-shmobile/intc-r8a7740.c              |    1 +
+ arch/arm/mach-shmobile/intc-sh7367.c               |    1 +
+ arch/arm/mach-shmobile/intc-sh7372.c               |    1 +
+ arch/arm/mach-shmobile/intc-sh7377.c               |    1 +
+ arch/arm/mach-shmobile/intc-sh73a0.c               |    1 +
+ arch/arm/mach-shmobile/setup-r8a7740.c             |    1 +
+ arch/arm/mach-shmobile/setup-r8a7779.c             |    1 +
+ arch/arm/mach-shmobile/setup-sh7367.c              |    1 +
+ arch/arm/mach-shmobile/setup-sh7372.c              |    1 +
+ arch/arm/mach-shmobile/setup-sh7377.c              |    1 +
+ arch/arm/mach-shmobile/setup-sh73a0.c              |    1 +
+ arch/arm/mach-spear3xx/include/mach/system.h       |   19 -
+ arch/arm/mach-spear3xx/spear300.c                  |   14 +-
+ arch/arm/mach-spear3xx/spear3xx.c                  |   27 +-
+ arch/arm/mach-spear6xx/include/mach/system.h       |   19 -
+ arch/arm/mach-spear6xx/spear6xx.c                  |   10 +-
+ arch/arm/mach-tegra/common.c                       |    3 +-
+ arch/arm/mach-tegra/hotplug.c                      |    1 +
+ arch/arm/mach-tegra/include/mach/system.h          |   28 -
+ arch/arm/mach-u300/core.c                          |   85 +--
+ arch/arm/mach-u300/include/mach/system.h           |   14 -
+ arch/arm/mach-ux500/board-mop500-sdi.c             |   21 +-
+ arch/arm/mach-ux500/devices-common.c               |   13 +-
+ arch/arm/mach-ux500/include/mach/system.h          |   20 -
+ arch/arm/mach-versatile/core.c                     |   70 +-
+ arch/arm/mach-versatile/core.h                     |   20 +-
+ arch/arm/mach-versatile/include/mach/system.h      |   33 -
+ arch/arm/mach-versatile/versatile_pb.c             |   18 +-
+ arch/arm/mach-vexpress/core.h                      |   17 -
+ arch/arm/mach-vexpress/ct-ca9x4.c                  |    8 +-
+ arch/arm/mach-vexpress/hotplug.c                   |    2 +-
+ arch/arm/mach-vexpress/include/mach/ct-ca9x4.h     |    2 +-
+ arch/arm/mach-vexpress/include/mach/io.h           |    1 -
+ arch/arm/mach-vexpress/include/mach/system.h       |   33 -
+ arch/arm/mach-vexpress/v2m.c                       |   20 +-
+ arch/arm/mach-vt8500/include/mach/system.h         |    5 -
+ arch/arm/mach-w90x900/dev.c                        |    1 +
+ arch/arm/mach-w90x900/include/mach/system.h        |   19 -
+ arch/arm/mach-zynq/include/mach/system.h           |   23 -
+ arch/arm/mm/alignment.c                            |    2 +-
+ arch/arm/mm/cache-feroceon-l2.c                    |    1 +
+ arch/arm/mm/cache-l2x0.c                           |   22 +-
+ arch/arm/mm/cache-tauros2.c                        |    1 +
+ arch/arm/mm/cache-xsc3l2.c                         |    2 +-
+ arch/arm/mm/copypage-v4mc.c                        |    9 +-
+ arch/arm/mm/copypage-v6.c                          |   20 +-
+ arch/arm/mm/copypage-xscale.c                      |    9 +-
+ arch/arm/mm/dma-mapping.c                          |   20 +-
+ arch/arm/mm/fault.c                                |    3 +-
+ arch/arm/mm/flush.c                                |   14 +-
+ arch/arm/mm/highmem.c                              |   21 +-
+ arch/arm/mm/init.c                                 |    4 +
+ arch/arm/mm/ioremap.c                              |    1 +
+ arch/arm/mm/mm.h                                   |   26 +-
+ arch/arm/mm/mmu.c                                  |    8 +-
+ arch/arm/mm/pgd.c                                  |    1 +
+ arch/arm/mm/vmregion.c                             |   76 ++-
+ arch/arm/mm/vmregion.h                             |    5 +-
+ arch/arm/plat-mxc/include/mach/system.h            |   25 -
+ arch/arm/plat-nomadik/Kconfig                      |    1 -
+ arch/arm/plat-omap/include/plat/system.h           |   15 -
+ arch/arm/plat-s3c24xx/cpu.c                        |   27 +
+ arch/arm/plat-spear/include/plat/system.h          |   26 -
+ arch/arm/plat-versatile/Kconfig                    |    3 +-
+ arch/arm/vfp/vfpmodule.c                           |    1 +
+ arch/c6x/Kconfig                                   |    2 +-
+ arch/powerpc/Kconfig                               |    2 +-
+ arch/sh/Kconfig                                    |    2 +-
+ arch/sh/include/asm/irq.h                          |   11 -
+ arch/x86/Kconfig                                   |    1 -
+ drivers/amba/bus.c                                 |  105 ++-
+ drivers/dma/Kconfig                                |    9 +
+ drivers/dma/Makefile                               |    1 +
+ drivers/dma/sa11x0-dma.c                           | 1117 ++++++++++++++++++++
+ drivers/gpio/gpio-pxa.c                            |    2 +
+ drivers/input/serio/sa1111ps2.c                    |   59 +-
+ drivers/mfd/Kconfig                                |    5 +-
+ drivers/mfd/mcp-core.c                             |   49 +-
+ drivers/mfd/mcp-sa11x0.c                           |  198 +++--
+ drivers/mfd/ucb1x00-assabet.c                      |   46 +-
+ drivers/mfd/ucb1x00-core.c                         |  433 ++++----
+ drivers/mfd/ucb1x00-ts.c                           |   39 +-
+ drivers/mmc/host/mmci.c                            |  168 +++-
+ drivers/mmc/host/mmci.h                            |   15 +-
+ drivers/mtd/maps/sa1100-flash.c                    |  112 --
+ drivers/net/ethernet/smsc/smc91x.c                 |    2 +-
+ drivers/net/irda/Kconfig                           |    2 +-
+ drivers/net/irda/sa1100_ir.c                       |  957 ++++++++++--------
+ drivers/of/platform.c                              |    6 +-
+ drivers/pcmcia/Kconfig                             |    8 +-
+ drivers/pcmcia/Makefile                            |   14 +-
+ drivers/pcmcia/pxa2xx_balloon3.c                   |   22 +-
+ drivers/pcmcia/pxa2xx_base.c                       |    5 +-
+ drivers/pcmcia/pxa2xx_cm_x255.c                    |   39 +-
+ drivers/pcmcia/pxa2xx_cm_x270.c                    |   23 +-
+ drivers/pcmcia/pxa2xx_colibri.c                    |   21 +-
+ drivers/pcmcia/pxa2xx_e740.c                       |   71 +-
+ drivers/pcmcia/pxa2xx_mainstone.c                  |   31 +-
+ drivers/pcmcia/pxa2xx_palmld.c                     |    8 +-
+ drivers/pcmcia/pxa2xx_palmtc.c                     |    8 +-
+ drivers/pcmcia/pxa2xx_palmtx.c                     |    8 +-
+ drivers/pcmcia/pxa2xx_sharpsl.c                    |   30 +-
+ drivers/pcmcia/pxa2xx_stargate2.c                  |   34 +-
+ drivers/pcmcia/pxa2xx_trizeps4.c                   |   62 +-
+ drivers/pcmcia/pxa2xx_viper.c                      |   39 +-
+ drivers/pcmcia/pxa2xx_vpac270.c                    |   54 +-
+ drivers/pcmcia/sa1100_assabet.c                    |   65 +-
+ drivers/pcmcia/sa1100_cerf.c                       |   52 +-
+ drivers/pcmcia/sa1100_h3600.c                      |   94 +--
+ drivers/pcmcia/sa1100_nanoengine.c                 |  132 +--
+ drivers/pcmcia/sa1100_shannon.c                    |   56 +-
+ drivers/pcmcia/sa1100_simpad.c                     |   27 +-
+ .../pcmcia/{sa1100_badge4.c => sa1111_badge4.c}    |    3 +-
+ drivers/pcmcia/sa1111_generic.c                    |  111 ++-
+ drivers/pcmcia/sa1111_generic.h                    |    1 -
+ .../{sa1100_jornada720.c => sa1111_jornada720.c}   |    8 +-
+ .../pcmcia/{pxa2xx_lubbock.c => sa1111_lubbock.c}  |    1 -
+ .../{sa1100_neponset.c => sa1111_neponset.c}       |   18 +-
+ drivers/pcmcia/sa11xx_base.c                       |    5 +-
+ drivers/pcmcia/soc_common.c                        |  193 +++--
+ drivers/pcmcia/soc_common.h                        |   23 +-
+ drivers/scsi/arm/arxescsi.c                        |    2 +-
+ drivers/scsi/arm/fas216.c                          |    4 +-
+ drivers/scsi/arm/fas216.h                          |    4 -
+ drivers/sh/intc/balancing.c                        |    2 +-
+ drivers/sh/intc/core.c                             |    2 +-
+ drivers/sh/intc/handle.c                           |    2 +-
+ drivers/sh/intc/virq.c                             |    2 +-
+ drivers/usb/host/ohci-sa1111.c                     |  297 +++---
+ drivers/video/sa1100fb.c                           |  493 +++------
+ drivers/video/sa1100fb.h                           |   76 +--
+ include/linux/amba/bus.h                           |   36 +
+ include/linux/amba/mmci.h                          |   22 +-
+ include/linux/mfd/mcp.h                            |   14 +-
+ include/linux/mfd/ucb1x00.h                        |   38 +-
+ include/linux/sa11x0-dma.h                         |   24 +
+ include/linux/sh_intc.h                            |   17 +
+ include/sound/soc-dmaengine.h                      |   26 +
+ include/video/sa1100fb.h                           |   63 ++
+ kernel/irq/Kconfig                                 |    5 +-
+ sound/arm/pxa2xx-ac97-lib.c                        |    2 +-
+ sound/soc/Kconfig                                  |    4 +
+ sound/soc/Makefile                                 |    3 +
+ sound/soc/sa11x0/Kconfig                           |   14 +
+ sound/soc/sa11x0/Makefile                          |    5 +
+ sound/soc/sa11x0/sa11x0-assabet.c                  |  432 ++++++++
+ sound/soc/sa11x0/sa11x0-ssp.c                      |  345 ++++++
+ sound/soc/sa11x0/sa11x0-ssp.h                      |   11 +
+ sound/soc/soc-dmaengine.c                          |  576 ++++++++++
+ 400 files changed, 7570 insertions(+), 6942 deletions(-)
+ create mode 100644 arch/arm/boot/compressed/piggy.xzkern.S
+ create mode 100644 arch/arm/include/asm/cp15.h
+ create mode 100644 arch/arm/kernel/insn.c
+ create mode 100644 arch/arm/kernel/insn.h
+ create mode 100644 arch/arm/kernel/patch.c
+ create mode 100644 arch/arm/kernel/patch.h
+ delete mode 100644 arch/arm/mach-at91/include/mach/system.h
+ delete mode 100644 arch/arm/mach-bcmring/include/mach/system.h
+ delete mode 100644 arch/arm/mach-clps711x/include/mach/system.h
+ delete mode 100644 arch/arm/mach-cns3xxx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-davinci/include/mach/system.h
+ delete mode 100644 arch/arm/mach-dove/include/mach/system.h
+ create mode 100644 arch/arm/mach-ebsa110/core.h
+ delete mode 100644 arch/arm/mach-ebsa110/include/mach/system.h
+ delete mode 100644 arch/arm/mach-ep93xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-exynos/include/mach/system.h
+ delete mode 100644 arch/arm/mach-footbridge/include/mach/system.h
+ create mode 100644 arch/arm/mach-gemini/idle.c
+ delete mode 100644 arch/arm/mach-h720x/include/mach/system.h
+ delete mode 100644 arch/arm/mach-highbank/include/mach/irqs.h
+ delete mode 100644 arch/arm/mach-highbank/include/mach/system.h
+ delete mode 100644 arch/arm/mach-integrator/include/mach/system.h
+ delete mode 100644 arch/arm/mach-iop13xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-iop32x/include/mach/system.h
+ delete mode 100644 arch/arm/mach-iop33x/include/mach/system.h
+ delete mode 100644 arch/arm/mach-ixp2000/include/mach/system.h
+ delete mode 100644 arch/arm/mach-ixp23xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-ixp4xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-kirkwood/include/mach/system.h
+ delete mode 100644 arch/arm/mach-ks8695/include/mach/system.h
+ delete mode 100644 arch/arm/mach-lpc32xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-mmp/include/mach/system.h
+ delete mode 100644 arch/arm/mach-msm/idle.S
+ create mode 100644 arch/arm/mach-msm/idle.c
+ delete mode 100644 arch/arm/mach-mv78xx0/include/mach/system.h
+ delete mode 100644 arch/arm/mach-mxs/include/mach/system.h
+ delete mode 100644 arch/arm/mach-netx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-nomadik/include/mach/system.h
+ delete mode 100644 arch/arm/mach-omap1/include/mach/system.h
+ delete mode 100644 arch/arm/mach-omap2/include/mach/system.h
+ delete mode 100644 arch/arm/mach-orion5x/include/mach/system.h
+ delete mode 100644 arch/arm/mach-picoxcell/include/mach/irqs.h
+ delete mode 100644 arch/arm/mach-picoxcell/include/mach/system.h
+ delete mode 100644 arch/arm/mach-pnx4008/include/mach/system.h
+ delete mode 100644 arch/arm/mach-prima2/include/mach/system.h
+ delete mode 100644 arch/arm/mach-pxa/include/mach/system.h
+ delete mode 100644 arch/arm/mach-realview/include/mach/system.h
+ delete mode 100644 arch/arm/mach-rpc/include/mach/system.h
+ delete mode 100644 arch/arm/mach-s3c2410/include/mach/system.h
+ delete mode 100644 arch/arm/mach-s3c64xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-s5p64x0/include/mach/system.h
+ delete mode 100644 arch/arm/mach-s5pc100/include/mach/system.h
+ delete mode 100644 arch/arm/mach-s5pv210/include/mach/system.h
+ delete mode 100644 arch/arm/mach-sa1100/dma.c
+ delete mode 100644 arch/arm/mach-sa1100/include/mach/dma.h
+ delete mode 100644 arch/arm/mach-sa1100/include/mach/system.h
+ delete mode 100644 arch/arm/mach-shark/include/mach/system.h
+ delete mode 100644 arch/arm/mach-spear3xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-spear6xx/include/mach/system.h
+ delete mode 100644 arch/arm/mach-tegra/include/mach/system.h
+ delete mode 100644 arch/arm/mach-u300/include/mach/system.h
+ delete mode 100644 arch/arm/mach-ux500/include/mach/system.h
+ delete mode 100644 arch/arm/mach-versatile/include/mach/system.h
+ delete mode 100644 arch/arm/mach-vexpress/include/mach/system.h
+ delete mode 100644 arch/arm/mach-w90x900/include/mach/system.h
+ delete mode 100644 arch/arm/mach-zynq/include/mach/system.h
+ delete mode 100644 arch/arm/plat-mxc/include/mach/system.h
+ delete mode 100644 arch/arm/plat-omap/include/plat/system.h
+ delete mode 100644 arch/arm/plat-spear/include/plat/system.h
+ create mode 100644 drivers/dma/sa11x0-dma.c
+ rename drivers/pcmcia/{sa1100_badge4.c => sa1111_badge4.c} (98%)
+ rename drivers/pcmcia/{sa1100_jornada720.c => sa1111_jornada720.c} (94%)
+ rename drivers/pcmcia/{pxa2xx_lubbock.c => sa1111_lubbock.c} (99%)
+ rename drivers/pcmcia/{sa1100_neponset.c => sa1111_neponset.c} (90%)
+ create mode 100644 include/linux/sa11x0-dma.h
+ create mode 100644 include/sound/soc-dmaengine.h
+ create mode 100644 include/video/sa1100fb.h
+ create mode 100644 sound/soc/sa11x0/Kconfig
+ create mode 100644 sound/soc/sa11x0/Makefile
+ create mode 100644 sound/soc/sa11x0/sa11x0-assabet.c
+ create mode 100644 sound/soc/sa11x0/sa11x0-ssp.c
+ create mode 100644 sound/soc/sa11x0/sa11x0-ssp.h
+ create mode 100644 sound/soc/soc-dmaengine.c
+Merging arm-perf/for-next/perf (cdd2a5b Merge branches 'perf/updates' and 'perf/fixes' into for-next/perf)
+$ git merge arm-perf/for-next/perf
+Merge made by the 'recursive' strategy.
+Merging davinci/davinci-next (fe0d422 Linux 3.0-rc6)
+$ git merge davinci/davinci-next
+Already up-to-date.
+Merging samsung/next-samsung (9edb240 ARM: H1940/RX1950: Change default LED triggers)
+$ git merge samsung/next-samsung
+Already up-to-date.
+Merging s5p/for-next (e8a4c2f Merge branch 'v3.4-for-rafael' into for-next)
+$ git merge s5p/for-next
+Removing arch/arm/mach-exynos/dev-pd.c
+Merge made by the 'recursive' strategy.
+ .../bindings/arm/exynos/power_domain.txt           |   21 ++
+ arch/arm/mach-exynos/Kconfig                       |   15 +-
+ arch/arm/mach-exynos/Makefile                      |    2 +-
+ arch/arm/mach-exynos/clock-exynos4210.c            |    2 +-
+ arch/arm/mach-exynos/clock-exynos4212.c            |    2 +-
+ arch/arm/mach-exynos/clock.c                       |    2 +-
+ arch/arm/mach-exynos/common.c                      |    2 +-
+ arch/arm/mach-exynos/dev-pd.c                      |  139 --------------
+ arch/arm/mach-exynos/dma.c                         |   16 +-
+ arch/arm/mach-exynos/include/mach/map.h            |    3 +
+ arch/arm/mach-exynos/mach-nuri.c                   |   77 +++++++-
+ arch/arm/mach-exynos/mach-origen.c                 |   52 ++++--
+ arch/arm/mach-exynos/mach-smdkv310.c               |   13 +--
+ arch/arm/mach-exynos/mach-universal_c210.c         |   96 ++++++++---
+ arch/arm/mach-exynos/pm_domains.c                  |  195 ++++++++++++++++++++
+ arch/arm/mach-s3c2410/mach-h1940.c                 |   12 +-
+ arch/arm/mach-s3c2416/clock.c                      |    6 -
+ arch/arm/mach-s3c2416/mach-smdk2416.c              |    8 +-
+ arch/arm/mach-s3c2416/s3c2416.c                    |    2 +
+ arch/arm/mach-s3c2440/mach-gta02.c                 |    4 +-
+ arch/arm/mach-s3c2440/mach-rx1950.c                |   12 +-
+ arch/arm/mach-s3c2443/s3c2443.c                    |    2 +
+ arch/arm/mach-s3c64xx/Kconfig                      |    1 +
+ arch/arm/mach-s3c64xx/Makefile                     |    1 +
+ arch/arm/mach-s3c64xx/clock.c                      |  121 +++++++++++-
+ arch/arm/mach-s3c64xx/common.h                     |    2 -
+ arch/arm/mach-s3c64xx/cpuidle.c                    |   91 +++++++++
+ arch/arm/mach-s3c64xx/irq-pm.c                     |    2 +-
+ arch/arm/mach-s3c64xx/mach-crag6410-module.c       |   27 +++-
+ arch/arm/mach-s3c64xx/mach-crag6410.c              |   67 +++++++-
+ arch/arm/mach-s5p64x0/clock.c                      |   11 +-
+ arch/arm/mach-s5p64x0/dma.c                        |   12 +-
+ arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h |    7 -
+ arch/arm/mach-s5pc100/clock.c                      |   28 ++--
+ arch/arm/mach-s5pc100/dma.c                        |   16 +-
+ arch/arm/mach-s5pv210/dma.c                        |   16 +-
+ arch/arm/mach-s5pv210/mach-aquila.c                |    1 +
+ arch/arm/mach-s5pv210/mach-goni.c                  |    2 +-
+ arch/arm/mach-s5pv210/mach-smdkv210.c              |    2 +-
+ arch/arm/plat-s3c24xx/s3c2443-clock.c              |    2 +-
+ arch/arm/plat-s5p/Kconfig                          |    5 +
+ arch/arm/plat-s5p/irq-eint.c                       |    2 +-
+ arch/arm/plat-s5p/irq-gpioint.c                    |    2 +-
+ arch/arm/plat-samsung/clock.c                      |   12 +-
+ arch/arm/plat-samsung/dev-backlight.c              |    2 +
+ arch/arm/plat-samsung/devs.c                       |   41 +++--
+ arch/arm/plat-samsung/dma-ops.c                    |    2 +-
+ arch/arm/plat-samsung/include/plat/devs.h          |    1 +
+ arch/arm/plat-samsung/include/plat/regs-rtc.h      |   81 +++++----
+ arch/arm/plat-samsung/include/plat/rtc-core.h      |   27 +++
+ arch/arm/plat-samsung/include/plat/sdhci.h         |    2 +
+ arch/arm/plat-samsung/platformdata.c               |    2 +
+ drivers/base/power/domain.c                        |   32 ++++
+ drivers/mmc/host/sdhci-s3c.c                       |    6 +-
+ drivers/rtc/rtc-s3c.c                              |   71 ++++++--
+ include/linux/pm_domain.h                          |   12 ++
+ 56 files changed, 1007 insertions(+), 385 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/arm/exynos/power_domain.txt
+ delete mode 100644 arch/arm/mach-exynos/dev-pd.c
+ create mode 100644 arch/arm/mach-exynos/pm_domains.c
+ create mode 100644 arch/arm/mach-s3c64xx/cpuidle.c
+ create mode 100644 arch/arm/plat-samsung/include/plat/rtc-core.h
+Merging tegra/for-next (9048201 Merge branch 'for-3.4/soc-drivers' into for-next)
+$ git merge tegra/for-next
+Auto-merging arch/arm/mach-tegra/common.c
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/arm/tegra/emc.txt          |  100 +
+ .../bindings/arm/tegra/nvidia,tegra20-pmc.txt      |   19 +
+ .../devicetree/bindings/dma/tegra20-apbdma.txt     |   30 +
+ .../devicetree/bindings/gpio/gpio_nvidia.txt       |   36 +-
+ arch/arm/boot/dts/tegra-harmony.dts                |   45 +-
+ arch/arm/boot/dts/tegra-paz00.dts                  |   56 +
+ arch/arm/boot/dts/tegra-seaboard.dts               |   78 +
+ arch/arm/boot/dts/tegra-trimslice.dts              |   12 +
+ arch/arm/boot/dts/tegra-ventana.dts                |   42 +
+ arch/arm/boot/dts/tegra20.dtsi                     |   43 +-
+ arch/arm/boot/dts/tegra30.dtsi                     |   53 +-
+ arch/arm/mach-tegra/Makefile                       |    6 +-
+ arch/arm/mach-tegra/apbio.c                        |  145 +
+ arch/arm/mach-tegra/apbio.h                        |   39 +
+ arch/arm/mach-tegra/board-dt-tegra30.c             |   24 +-
+ arch/arm/mach-tegra/board-harmony-power.c          |   15 -
+ arch/arm/mach-tegra/board-harmony.c                |    2 +-
+ arch/arm/mach-tegra/board-seaboard.c               |    5 +-
+ arch/arm/mach-tegra/clock.c                        |   22 +
+ arch/arm/mach-tegra/clock.h                        |   15 +
+ arch/arm/mach-tegra/common.c                       |   21 +
+ arch/arm/mach-tegra/cpuidle.c                      |  107 +
+ arch/arm/mach-tegra/dma.c                          |  128 +-
+ arch/arm/mach-tegra/flowctrl.h                     |   37 +
+ arch/arm/mach-tegra/fuse.c                         |  107 +-
+ arch/arm/mach-tegra/fuse.h                         |   34 +-
+ arch/arm/mach-tegra/include/mach/clk.h             |   10 +
+ arch/arm/mach-tegra/include/mach/debug-macro.S     |   88 +-
+ arch/arm/mach-tegra/include/mach/gpio-tegra.h      |    2 -
+ arch/arm/mach-tegra/include/mach/iomap.h           |    3 +
+ arch/arm/mach-tegra/include/mach/irammap.h         |   35 +
+ arch/arm/mach-tegra/include/mach/irqs.h            |    7 +-
+ arch/arm/mach-tegra/include/mach/uncompress.h      |  118 +-
+ arch/arm/mach-tegra/irq.c                          |   20 +-
+ arch/arm/mach-tegra/pmc.c                          |   76 +
+ arch/arm/mach-tegra/pmc.h                          |   23 +
+ arch/arm/mach-tegra/sleep.S                        |   91 +
+ arch/arm/mach-tegra/tegra2_clocks.c                |    2 +-
+ arch/arm/mach-tegra/tegra2_emc.c                   |  224 ++-
+ arch/arm/mach-tegra/tegra2_emc.h                   |   11 +-
+ arch/arm/mach-tegra/tegra30_clocks.c               | 3099 ++++++++++++++++++++
+ drivers/gpio/gpio-tegra.c                          |   61 +-
+ include/linux/platform_data/tegra_emc.h            |   34 +
+ 43 files changed, 4924 insertions(+), 201 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/arm/tegra/emc.txt
+ create mode 100644 Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
+ create mode 100644 Documentation/devicetree/bindings/dma/tegra20-apbdma.txt
+ create mode 100644 arch/arm/mach-tegra/apbio.c
+ create mode 100644 arch/arm/mach-tegra/apbio.h
+ create mode 100644 arch/arm/mach-tegra/cpuidle.c
+ create mode 100644 arch/arm/mach-tegra/flowctrl.h
+ create mode 100644 arch/arm/mach-tegra/include/mach/irammap.h
+ create mode 100644 arch/arm/mach-tegra/pmc.c
+ create mode 100644 arch/arm/mach-tegra/pmc.h
+ create mode 100644 arch/arm/mach-tegra/sleep.S
+ create mode 100644 arch/arm/mach-tegra/tegra30_clocks.c
+ create mode 100644 include/linux/platform_data/tegra_emc.h
+Merging xilinx/arm-next (b85a3ef ARM: Xilinx: Adding Xilinx board support)
+$ git merge xilinx/arm-next
+Already up-to-date.
+Merging blackfin/for-linus (e651fe5 Blackfin: wire up new process_vm syscalls)
+$ git merge blackfin/for-linus
+Merge made by the 'recursive' strategy.
+ arch/blackfin/configs/BF518F-EZBRD_defconfig     |   25 ++--
+ arch/blackfin/configs/BF526-EZBRD_defconfig      |   26 ++--
+ arch/blackfin/configs/BF527-EZKIT-V2_defconfig   |   26 ++--
+ arch/blackfin/configs/BF527-EZKIT_defconfig      |   27 ++--
+ arch/blackfin/configs/BF533-EZKIT_defconfig      |   23 +--
+ arch/blackfin/configs/BF533-STAMP_defconfig      |   22 +-
+ arch/blackfin/configs/BF537-STAMP_defconfig      |   27 ++--
+ arch/blackfin/configs/BF548-EZKIT_defconfig      |   16 +-
+ arch/blackfin/configs/BF561-EZKIT-SMP_defconfig  |   35 ++--
+ arch/blackfin/configs/BF561-EZKIT_defconfig      |   23 +--
+ arch/blackfin/include/asm/bfin5xx_spi.h          |    1 -
+ arch/blackfin/include/asm/bfin_simple_timer.h    |   10 +-
+ arch/blackfin/include/asm/bfin_sport.h           |    3 +
+ arch/blackfin/include/asm/blackfin.h             |   44 ++---
+ arch/blackfin/include/asm/kgdb.h                 |    1 +
+ arch/blackfin/include/asm/mmu_context.h          |    5 +-
+ arch/blackfin/include/asm/thread_info.h          |    2 +
+ arch/blackfin/include/asm/unistd.h               |    4 +-
+ arch/blackfin/kernel/cplb-mpu/cplbmgr.c          |    2 +
+ arch/blackfin/mach-bf537/boards/stamp.c          |   24 +++-
+ arch/blackfin/mach-bf548/boards/ezkit.c          |    2 +
+ arch/blackfin/mach-bf561/atomic.S                |    7 +
+ arch/blackfin/mach-bf561/include/mach/defBF561.h |  220 +++++++++++-----------
+ arch/blackfin/mach-common/entry.S                |    2 +
+ 24 files changed, 309 insertions(+), 268 deletions(-)
+Merging c6x/for-linux-next (62e37ca Kbuild: Use dtc's -d (dependency) option)
+$ git merge c6x/for-linux-next
+Merge made by the 'recursive' strategy.
+ arch/c6x/boot/Makefile |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+Merging cris/for-next (ea78f5b CRIS: Update documentation)
+$ git merge cris/for-next
+Auto-merging drivers/net/cris/eth_v10.c
+Auto-merging arch/cris/arch-v32/drivers/cryptocop.c
+Merge made by the 'recursive' strategy.
+ Documentation/cris/README               |   62 +++++++++++++++---------------
+ arch/cris/arch-v32/drivers/cryptocop.c  |    6 +--
+ arch/cris/arch-v32/kernel/ptrace.c      |    2 -
+ arch/cris/include/arch-v32/arch/cache.h |    2 +-
+ drivers/net/cris/eth_v10.c              |    1 -
+ 5 files changed, 34 insertions(+), 39 deletions(-)
+Merging quilt/hexagon (110b372 Remove unneeded include of version.h from arch/hexagon/include/asm/spinlock_types.h)
+$ git merge quilt/hexagon
+Resolved 'arch/hexagon/Kconfig' using previous resolution.
+Auto-merging arch/hexagon/Kconfig
+CONFLICT (content): Merge conflict in arch/hexagon/Kconfig
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 8604b67] Merge branch 'quilt/hexagon'
+$ git diff -M --stat --summary HEAD^..
+ arch/hexagon/Kconfig                      |   23 ++++-------------------
+ arch/hexagon/Makefile                     |    4 ----
+ arch/hexagon/include/asm/spinlock_types.h |    2 --
+ arch/hexagon/kernel/dma.c                 |    1 +
+ arch/hexagon/kernel/ptrace.c              |    1 +
+ arch/hexagon/kernel/time.c                |    7 +++----
+ arch/hexagon/kernel/vdso.c                |    1 +
+ 7 files changed, 10 insertions(+), 29 deletions(-)
+Merging ia64/next (0f261ed [IA64] disable interrupts when exiting from ia64_mca_cmc_int_handler())
+$ git merge ia64/next
+Merge made by the 'recursive' strategy.
+ arch/ia64/kernel/mca.c |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+Merging m68k/for-next (2a35350 m68k: Fix assembler constraint to prevent overeager gcc optimisation)
+$ git merge m68k/for-next
+Already up-to-date.
+Merging m68knommu/for-next (9720227 m68knommu: clean up linker script)
+$ git merge m68knommu/for-next
+Merge made by the 'recursive' strategy.
+ arch/m68k/include/asm/mcf_pgtable.h |    3 +-
+ arch/m68k/kernel/vmlinux-nommu.lds  |  200 +++++++++--------------------------
+ arch/m68k/mm/mcfmmu.c               |    9 +-
+ arch/m68k/platform/coldfire/entry.S |    4 +-
+ arch/m68k/platform/coldfire/head.S  |    4 +
+ 5 files changed, 61 insertions(+), 159 deletions(-)
+Merging microblaze/next (8597559 Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6)
+$ git merge microblaze/next
+Already up-to-date.
+Merging mips/mips-for-linux-next (2fea377 Merge branch 'fixes-for-linus' into mips-for-linux-next)
+$ git merge mips/mips-for-linux-next
+Merge made by the 'recursive' strategy.
+ arch/mips/alchemy/common/time.c                 |    2 +-
+ arch/mips/ath79/dev-wmac.c                      |    2 +-
+ arch/mips/configs/nlm_xlp_defconfig             |    4 +-
+ arch/mips/configs/nlm_xlr_defconfig             |    4 +-
+ arch/mips/configs/powertv_defconfig             |    2 +-
+ arch/mips/include/asm/mach-au1x00/gpio-au1300.h |   20 ++++++++++++-
+ arch/mips/include/asm/page.h                    |    3 --
+ arch/mips/kernel/smp-bmips.c                    |    1 -
+ arch/mips/kernel/traps.c                        |    2 +-
+ arch/mips/kernel/vmlinux.lds.S                  |    1 -
+ arch/mips/mm/fault.c                            |   36 ++++++++++++++++++----
+ arch/mips/pci/pci.c                             |    5 +--
+ arch/mips/pmc-sierra/yosemite/ht-irq.c          |   10 ------
+ arch/mips/txx9/generic/7segled.c                |    2 +-
+ 14 files changed, 58 insertions(+), 36 deletions(-)
+Merging openrisc/for-upstream (754d5c2 openrisc: Set shortest clock event to 100 ticks)
+$ git merge openrisc/for-upstream
+Merge made by the 'recursive' strategy.
+ arch/openrisc/include/asm/ptrace.h  |    8 +++++-
+ arch/openrisc/include/asm/uaccess.h |    1 -
+ arch/openrisc/kernel/head.S         |   17 ++++++++++++-
+ arch/openrisc/kernel/init_task.c    |    1 +
+ arch/openrisc/kernel/irq.c          |    1 +
+ arch/openrisc/kernel/ptrace.c       |   12 +++------
+ arch/openrisc/kernel/setup.c        |   18 +++++++-------
+ arch/openrisc/kernel/signal.c       |   45 ++++++++++++++--------------------
+ arch/openrisc/kernel/time.c         |   13 ++++------
+ arch/openrisc/mm/init.c             |    3 +-
+ 10 files changed, 63 insertions(+), 56 deletions(-)
+Merging parisc/for-next (fc99a91 futex: Use same lock set as lws calls)
+$ git merge parisc/for-next
+Merge made by the 'recursive' strategy.
+ arch/parisc/include/asm/futex.h |   31 +++++++++++++++++++++++++++----
+ 1 files changed, 27 insertions(+), 4 deletions(-)
+Merging powerpc/next (ef88e39 powerpc: fix compile error with 85xx/p1010rdb.c)
+$ git merge powerpc/next
+Already up-to-date.
+Merging 4xx/next (ef88e39 powerpc: fix compile error with 85xx/p1010rdb.c)
+$ git merge 4xx/next
+Already up-to-date.
+Merging 52xx-and-virtex/powerpc/next (c1395f4 dtc/powerpc: remove obsolete .gitignore entries)
+$ git merge 52xx-and-virtex/powerpc/next
+Merge made by the 'recursive' strategy.
+Merging galak/next (ef88e39 powerpc: fix compile error with 85xx/p1010rdb.c)
+$ git merge galak/next
+Already up-to-date.
+Merging s390/features (486f0b4 [S390] irq: external interrupt code passing)
+$ git merge s390/features
+Removing arch/s390/kernel/switch_cpu64.S
+Removing arch/s390/kernel/switch_cpu.S
+Removing arch/s390/include/asm/sigp.h
+Merge made by the 'recursive' strategy.
+ arch/s390/include/asm/cputime.h  |    9 +-
+ arch/s390/include/asm/hardirq.h  |    1 +
+ arch/s390/include/asm/irq.h      |    7 +-
+ arch/s390/include/asm/lowcore.h  |  104 ++--
+ arch/s390/include/asm/sigp.h     |  132 -----
+ arch/s390/include/asm/smp.h      |   63 +--
+ arch/s390/include/asm/timer.h    |    4 +-
+ arch/s390/include/asm/vdso.h     |    4 +-
+ arch/s390/kernel/Makefile        |    2 -
+ arch/s390/kernel/asm-offsets.c   |   27 +-
+ arch/s390/kernel/entry.S         |  158 +++---
+ arch/s390/kernel/entry.h         |   17 +-
+ arch/s390/kernel/entry64.S       |  138 +++--
+ arch/s390/kernel/ipl.c           |   51 +--
+ arch/s390/kernel/irq.c           |   14 +-
+ arch/s390/kernel/machine_kexec.c |   43 +--
+ arch/s390/kernel/nmi.c           |    2 -
+ arch/s390/kernel/process.c       |    7 +-
+ arch/s390/kernel/setup.c         |   58 +-
+ arch/s390/kernel/smp.c           | 1118 +++++++++++++++++++-------------------
+ arch/s390/kernel/switch_cpu.S    |   58 --
+ arch/s390/kernel/switch_cpu64.S  |   51 --
+ arch/s390/kernel/swsusp_asm64.S  |   16 +-
+ arch/s390/kernel/time.c          |    4 +-
+ arch/s390/kernel/topology.c      |    8 +-
+ arch/s390/kernel/vdso.c          |   12 +-
+ arch/s390/kernel/vtime.c         |  168 ++-----
+ arch/s390/kvm/interrupt.c        |    6 +-
+ arch/s390/lib/delay.c            |   31 +-
+ arch/s390/lib/spinlock.c         |   30 +-
+ arch/s390/mm/fault.c             |    4 +-
+ arch/s390/oprofile/hwsampler.c   |    6 +-
+ drivers/s390/block/dasd_diag.c   |    8 +-
+ drivers/s390/char/sclp.c         |    4 +-
+ drivers/s390/char/sclp_quiesce.c |    1 -
+ drivers/s390/char/sclp_sdias.c   |  101 +++-
+ drivers/s390/char/zcore.c        |    1 -
+ drivers/s390/cio/cio.c           |    2 -
+ drivers/s390/kvm/kvm_virtio.c    |    6 +-
+ net/iucv/iucv.c                  |    2 +-
+ 40 files changed, 1072 insertions(+), 1406 deletions(-)
+ delete mode 100644 arch/s390/include/asm/sigp.h
+ delete mode 100644 arch/s390/kernel/switch_cpu.S
+ delete mode 100644 arch/s390/kernel/switch_cpu64.S
+Merging sparc-next/master (b409650 arch/sparc/kernel/unaligned_64.c: included linux/bitops.h twice)
+$ git merge sparc-next/master
+Merge made by the 'recursive' strategy.
+ arch/sparc/kernel/unaligned_64.c |    1 -
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+Merging tile/master (0c90547 arch/tile: use new generic {enable,disable}_percpu_irq() routines)
+$ git merge tile/master
+Already up-to-date.
+Merging unicore32/unicore32 (0994695 Merge branch 'akpm' (aka "Andrew's patch-bomb, take two"))
+$ git merge unicore32/unicore32
+Already up-to-date.
+Merging ceph/for-next (83eb26a ceph: ensure prealloc_blob is in place when removing xattr)
+$ git merge ceph/for-next
+Already up-to-date.
+Merging cifs/master (4903062 i387: move AMD K7/K8 fpu fxsave/fxrstor workaround from save to restore)
+$ git merge cifs/master
+Already up-to-date.
+Merging configfs/linux-next (b930c26 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs)
+$ git merge configfs/linux-next
+Already up-to-date.
+Merging ecryptfs/next (6cfd4b4 ecryptfs: remove the second argument of k[un]map_atomic())
+$ git merge ecryptfs/next
+Resolved 'fs/ecryptfs/ecryptfs_kernel.h' using previous resolution.
+Auto-merging fs/ecryptfs/mmap.c
+Auto-merging fs/ecryptfs/ecryptfs_kernel.h
+CONFLICT (content): Merge conflict in fs/ecryptfs/ecryptfs_kernel.h
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master d0cc256] Merge remote-tracking branch 'ecryptfs/next'
+$ git diff -M --stat --summary HEAD^..
+ fs/ecryptfs/mmap.c |   12 ++++++++++--
+ 1 files changed, 10 insertions(+), 2 deletions(-)
+Merging ext3/for_next (62aa2b5 Linux 3.3-rc2)
+$ git merge ext3/for_next
+Already up-to-date.
+Merging ext4/dev (9ee4930 ext4: format flag in dx_probe())
+$ git merge ext4/dev
+Merge made by the 'recursive' strategy.
+ Documentation/filesystems/ext4.txt |    8 -
+ fs/ext4/balloc.c                   |   63 ++++++---
+ fs/ext4/dir.c                      |    8 +-
+ fs/ext4/ext4.h                     |   15 ++-
+ fs/ext4/ext4_jbd2.h                |  128 ++++++++++++++----
+ fs/ext4/ialloc.c                   |  235 +++++++++++++-------------------
+ fs/ext4/inode.c                    |   46 ++++---
+ fs/ext4/mballoc.c                  |  265 ++++++++++++++----------------------
+ fs/ext4/mballoc.h                  |   20 ++--
+ fs/ext4/migrate.c                  |    2 +-
+ fs/ext4/namei.c                    |    2 +-
+ fs/ext4/page-io.c                  |    2 +
+ fs/ext4/resize.c                   |   14 +-
+ fs/ext4/super.c                    |   73 ++++-------
+ fs/ext4/xattr.c                    |   12 +-
+ fs/jbd2/checkpoint.c               |    4 +-
+ fs/jbd2/commit.c                   |    2 +-
+ fs/jbd2/journal.c                  |   74 ++---------
+ fs/jbd2/revoke.c                   |   12 +-
+ fs/jbd2/transaction.c              |   38 +++++-
+ include/linux/jbd2.h               |    5 +
+ include/trace/events/jbd2.h        |   28 ++++
+ 22 files changed, 525 insertions(+), 531 deletions(-)
+Merging fuse/for-next (03c9693 cuse: implement memory mapping)
+$ git merge fuse/for-next
+Auto-merging fs/fuse/inode.c
+Auto-merging fs/fuse/fuse_i.h
+Merge made by the 'recursive' strategy.
+ fs/fuse/cuse.c       |  426 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ fs/fuse/dev.c        |  155 ++-----------------
+ fs/fuse/fuse_i.h     |   35 ++++-
+ fs/fuse/inode.c      |  167 +++++++++++++++++++-
+ include/linux/fuse.h |   25 +++
+ 5 files changed, 656 insertions(+), 152 deletions(-)
+Merging gfs2/master (b3e8048 GFS2: Make bd_cmp() static)
+$ git merge gfs2/master
+Merge made by the 'recursive' strategy.
+ fs/gfs2/file.c              |    7 ++
+ fs/gfs2/glock.c             |  224 ++++++++++++++++++++++++++++++++++++++++---
+ fs/gfs2/incore.h            |   49 +++++++++-
+ fs/gfs2/inode.c             |   13 ++-
+ fs/gfs2/lock_dlm.c          |  123 +++++++++++++++++++++++-
+ fs/gfs2/log.c               |  117 ++++-------------------
+ fs/gfs2/log.h               |    5 +-
+ fs/gfs2/lops.c              |   94 ++++++++++++++++++-
+ fs/gfs2/ops_fstype.c        |    8 ++
+ fs/gfs2/rgrp.c              |  164 ++++++++++++++++++++++++++-----
+ fs/gfs2/rgrp.h              |   10 +-
+ fs/gfs2/super.c             |    2 +-
+ fs/gfs2/trace_gfs2.h        |   60 +++++++++++-
+ fs/gfs2/xattr.c             |    4 +-
+ include/linux/gfs2_ondisk.h |    1 +
+ 15 files changed, 719 insertions(+), 162 deletions(-)
+Merging logfs/master (8ebbfb4 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs)
+$ git merge logfs/master
+Already up-to-date.
+Merging nfs/linux-next (36925a2 Merge branch 'nfs-for-next' into linux-next)
+$ git merge nfs/linux-next
+Merge made by the 'recursive' strategy.
+ Documentation/filesystems/nfs/idmapper.txt |   20 +-
+ Documentation/kernel-parameters.txt        |    8 +
+ fs/lockd/clnt4xdr.c                        |    2 +-
+ fs/lockd/clntlock.c                        |    3 +-
+ fs/lockd/clntxdr.c                         |    8 +-
+ fs/lockd/host.c                            |   42 ++-
+ fs/lockd/mon.c                             |   21 +-
+ fs/lockd/netns.h                           |   12 +
+ fs/lockd/svc.c                             |  117 ++++++-
+ fs/nfs/Kconfig                             |   13 +-
+ fs/nfs/blocklayout/blocklayout.c           |  152 ++++++++--
+ fs/nfs/blocklayout/blocklayout.h           |    3 +-
+ fs/nfs/blocklayout/blocklayoutdev.c        |    7 +-
+ fs/nfs/blocklayout/blocklayoutdm.c         |    9 +-
+ fs/nfs/blocklayout/extents.c               |    2 +-
+ fs/nfs/cache_lib.c                         |   61 +++-
+ fs/nfs/cache_lib.h                         |   10 +-
+ fs/nfs/callback.c                          |   12 +-
+ fs/nfs/callback.h                          |    3 +-
+ fs/nfs/callback_proc.c                     |   58 +++--
+ fs/nfs/callback_xdr.c                      |   15 +-
+ fs/nfs/client.c                            |  198 +++++++-----
+ fs/nfs/dir.c                               |   25 ++-
+ fs/nfs/dns_resolve.c                       |  129 ++++++--
+ fs/nfs/dns_resolve.h                       |   14 +-
+ fs/nfs/file.c                              |    2 +
+ fs/nfs/idmap.c                             |  356 +++++++++++++++------
+ fs/nfs/inode.c                             |   49 +++-
+ fs/nfs/internal.h                          |   13 +-
+ fs/nfs/mount_clnt.c                        |   14 +-
+ fs/nfs/namespace.c                         |    5 +-
+ fs/nfs/netns.h                             |   20 ++
+ fs/nfs/nfs2xdr.c                           |    2 +-
+ fs/nfs/nfs3xdr.c                           |    4 +-
+ fs/nfs/nfs4_fs.h                           |   35 +--
+ fs/nfs/nfs4filelayout.c                    |   31 ++-
+ fs/nfs/nfs4filelayoutdev.c                 |   88 ++----
+ fs/nfs/nfs4namespace.c                     |   10 +-
+ fs/nfs/nfs4proc.c                          |  405 ++++++++++++++----------
+ fs/nfs/nfs4state.c                         |  205 +++++-------
+ fs/nfs/nfs4xdr.c                           |   45 ++-
+ fs/nfs/objlayout/objio_osd.c               |    6 +-
+ fs/nfs/objlayout/objlayout.c               |    6 +-
+ fs/nfs/pagelist.c                          |    1 +
+ fs/nfs/pnfs.c                              |   16 +-
+ fs/nfs/read.c                              |    2 +-
+ fs/nfs/super.c                             |   31 ++-
+ fs/nfs/sysctl.c                            |    2 -
+ fs/nfs/unlink.c                            |    4 +-
+ fs/nfs/write.c                             |    2 +-
+ fs/nfsd/nfs4callback.c                     |    8 +-
+ fs/nfsd/nfs4state.c                        |    2 +-
+ fs/nfsd/nfsctl.c                           |    6 +-
+ fs/nfsd/nfssvc.c                           |    4 +-
+ fs/nfsd/stats.c                            |    5 +-
+ include/linux/lockd/bind.h                 |    1 +
+ include/linux/lockd/lockd.h                |    7 +-
+ include/linux/lockd/xdr4.h                 |    2 +-
+ include/linux/nfs.h                        |    2 +-
+ include/linux/nfs_fs_i.h                   |    4 -
+ include/linux/nfs_fs_sb.h                  |   18 +-
+ include/linux/nfs_idmap.h                  |   22 +-
+ include/linux/nfs_iostat.h                 |    2 +-
+ include/linux/nfs_xdr.h                    |   15 +-
+ include/linux/sunrpc/auth.h                |    2 +
+ include/linux/sunrpc/cache.h               |    8 +-
+ include/linux/sunrpc/clnt.h                |   36 +-
+ include/linux/sunrpc/debug.h               |    9 +-
+ include/linux/sunrpc/metrics.h             |    6 +-
+ include/linux/sunrpc/rpc_pipe_fs.h         |   44 ++-
+ include/linux/sunrpc/sched.h               |   24 ++-
+ include/linux/sunrpc/stats.h               |   22 +-
+ include/linux/sunrpc/svc.h                 |   13 +-
+ include/linux/sunrpc/svc_xprt.h            |    3 +-
+ include/linux/sunrpc/svcauth_gss.h         |    2 +
+ include/linux/sunrpc/svcsock.h             |    2 +-
+ include/linux/sunrpc/xprt.h                |    9 +-
+ include/trace/events/sunrpc.h              |  177 ++++++++++
+ net/sunrpc/addr.c                          |   26 +-
+ net/sunrpc/auth_gss/auth_gss.c             |  216 +++++++++----
+ net/sunrpc/auth_gss/svcauth_gss.c          |  165 +++++++---
+ net/sunrpc/cache.c                         |   44 ++-
+ net/sunrpc/clnt.c                          |  219 +++++++++----
+ net/sunrpc/netns.h                         |   14 +
+ net/sunrpc/rpc_pipe.c                      |  478 +++++++++++++++++-----------
+ net/sunrpc/rpcb_clnt.c                     |  144 +++++----
+ net/sunrpc/sched.c                         |   58 +++-
+ net/sunrpc/stats.c                         |   29 +-
+ net/sunrpc/sunrpc.h                        |    2 +
+ net/sunrpc/sunrpc_syms.c                   |   20 +-
+ net/sunrpc/svc.c                           |   98 ++++---
+ net/sunrpc/svc_xprt.c                      |   51 ++-
+ net/sunrpc/svcauth_unix.c                  |  126 ++++----
+ net/sunrpc/svcsock.c                       |    3 +-
+ net/sunrpc/sysctl.c                        |    4 +-
+ net/sunrpc/xprt.c                          |   65 +++--
+ net/sunrpc/xprtsock.c                      |   23 +-
+ 97 files changed, 2977 insertions(+), 1561 deletions(-)
+ create mode 100644 fs/lockd/netns.h
+ create mode 100644 fs/nfs/netns.h
+ create mode 100644 include/trace/events/sunrpc.h
+Merging nfsd/nfsd-next (03cfb42 NFSD: Clean up the test_stateid function)
+$ git merge nfsd/nfsd-next
+Auto-merging net/sunrpc/svcsock.c
+Auto-merging net/sunrpc/svcauth_unix.c
+Auto-merging net/sunrpc/cache.c
+Auto-merging fs/nfsd/nfssvc.c
+Auto-merging fs/nfsd/nfs4state.c
+Auto-merging fs/lockd/svc.c
+Merge made by the 'recursive' strategy.
+ fs/lockd/svc.c                           |    2 +-
+ fs/nfsd/current_stateid.h                |   28 ++++++
+ fs/nfsd/export.c                         |    2 +-
+ fs/nfsd/nfs4proc.c                       |   64 +++++++++++---
+ fs/nfsd/nfs4state.c                      |  146 ++++++++++++++++++++++++++----
+ fs/nfsd/nfs4xdr.c                        |   90 ++++++++-----------
+ fs/nfsd/nfssvc.c                         |   44 +++++----
+ fs/nfsd/state.h                          |    8 +-
+ fs/nfsd/xdr4.h                           |   29 +++++-
+ include/linux/sunrpc/svc_rdma.h          |    2 +-
+ net/sunrpc/cache.c                       |    2 +
+ net/sunrpc/svcauth_unix.c                |    2 +-
+ net/sunrpc/svcsock.c                     |    2 -
+ net/sunrpc/xprtrdma/svc_rdma.c           |    1 +
+ net/sunrpc/xprtrdma/svc_rdma_marshal.c   |   66 ++++----------
+ net/sunrpc/xprtrdma/svc_rdma_recvfrom.c  |   20 +++--
+ net/sunrpc/xprtrdma/svc_rdma_sendto.c    |   26 +++---
+ net/sunrpc/xprtrdma/svc_rdma_transport.c |   10 +--
+ net/sunrpc/xprtrdma/xprt_rdma.h          |    7 ++
+ 19 files changed, 354 insertions(+), 197 deletions(-)
+ create mode 100644 fs/nfsd/current_stateid.h
+Merging ocfs2/linux-next (9392557 ocfs2: avoid unaligned access to dqc_bitmap)
+$ git merge ocfs2/linux-next
+Already up-to-date.
+Merging omfs/for-next (976d167 Linux 3.1-rc9)
+$ git merge omfs/for-next
+Already up-to-date.
+Merging squashfs/master (3d4a1c8 Squashfs: fix i_blocks calculation with extended regular files)
+$ git merge squashfs/master
+Already up-to-date.
+Merging v9fs/for-next (f766619 fs/9p: iattr_valid flags are kernel internal flags map them to 9p values.)
+$ git merge v9fs/for-next
+Already up-to-date.
+Merging ubifs/linux-next (72d3ef6 UBIFS: do not use inc_link when i_nlink is zero)
+$ git merge ubifs/linux-next
+Merge made by the 'recursive' strategy.
+ fs/ubifs/debug.c    |  410 +++++++++++++++++++++++++-------------------------
+ fs/ubifs/debug.h    |    3 -
+ fs/ubifs/dir.c      |   18 +-
+ fs/ubifs/recovery.c |    3 +-
+ 4 files changed, 216 insertions(+), 218 deletions(-)
+Merging xfs/for-next (33e0eda xfs: make inode quota check more general)
+$ git merge xfs/for-next
+Auto-merging fs/xfs/xfs_qm.c
+Auto-merging fs/xfs/xfs_dquot.c
+Merge made by the 'recursive' strategy.
+ fs/xfs/xfs_dquot.c       |   61 +++++++++++++++++----------------------------
+ fs/xfs/xfs_dquot.h       |   30 +++++++++++++++++++---
+ fs/xfs/xfs_log_recover.c |    8 +++---
+ fs/xfs/xfs_mount.c       |    8 ++++--
+ fs/xfs/xfs_mount.h       |    2 +-
+ fs/xfs/xfs_qm.c          |    2 +-
+ fs/xfs/xfs_qm_syscalls.c |    4 +-
+ fs/xfs/xfs_quota.h       |    2 +
+ fs/xfs/xfs_sb.h          |    1 -
+ fs/xfs/xfs_super.c       |    7 ++---
+ fs/xfs/xfs_trans.c       |    4 +-
+ fs/xfs/xfs_trans_dquot.c |   10 ++++---
+ 12 files changed, 75 insertions(+), 64 deletions(-)
+Merging vfs/for-next (9a3b4c1 qnx4fs: small cleanup)
+$ git merge vfs/for-next
+Auto-merging net/sunrpc/rpc_pipe.c
+Auto-merging fs/xfs/xfs_super.c
+Auto-merging fs/gfs2/ops_fstype.c
+Auto-merging fs/fuse/inode.c
+Auto-merging fs/ext4/super.c
+Auto-merging fs/ecryptfs/super.c
+Merge made by the 'recursive' strategy.
+ Documentation/filesystems/porting         |    6 ++++
+ arch/powerpc/platforms/cell/spufs/inode.c |    4 +-
+ arch/s390/hypfs/inode.c                   |    6 +---
+ drivers/misc/ibmasm/ibmasmfs.c            |   16 ++++-------
+ drivers/oprofile/oprofilefs.c             |   11 ++------
+ drivers/usb/core/inode.c                  |   13 +--------
+ drivers/usb/gadget/f_fs.c                 |    8 +----
+ drivers/usb/gadget/inode.c                |    4 +--
+ fs/9p/vfs_super.c                         |    3 +-
+ fs/adfs/super.c                           |    3 +-
+ fs/affs/super.c                           |    7 +----
+ fs/afs/super.c                            |    7 +----
+ fs/autofs4/inode.c                        |   10 +------
+ fs/befs/linuxvfs.c                        |    3 +-
+ fs/bfs/inode.c                            |    3 +-
+ fs/btrfs/super.c                          |    8 +----
+ fs/ceph/super.c                           |    3 +-
+ fs/cifs/cifsfs.c                          |    7 +----
+ fs/coda/inode.c                           |    6 +----
+ fs/configfs/mount.c                       |    3 +-
+ fs/cramfs/inode.c                         |    6 +---
+ fs/dcache.c                               |   24 ------------------
+ fs/devpts/inode.c                         |    3 +-
+ fs/ecryptfs/main.c                        |    3 +-
+ fs/ecryptfs/super.c                       |    1 -
+ fs/efs/super.c                            |    3 +-
+ fs/exofs/namei.c                          |   13 +---------
+ fs/exofs/super.c                          |    4 +-
+ fs/ext2/namei.c                           |   13 +---------
+ fs/ext2/super.c                           |    4 +-
+ fs/ext3/super.c                           |    3 +-
+ fs/ext4/super.c                           |    3 +-
+ fs/fat/inode.c                            |    8 +++---
+ fs/file_table.c                           |    3 +-
+ fs/freevxfs/vxfs_super.c                  |    3 +-
+ fs/fuse/inode.c                           |    9 +-----
+ fs/gfs2/ops_fstype.c                      |    3 +-
+ fs/hfs/super.c                            |    6 +---
+ fs/hfsplus/super.c                        |   17 +++++++------
+ fs/hostfs/hostfs_kern.c                   |    4 +-
+ fs/hpfs/super.c                           |    6 +---
+ fs/hppfs/hppfs.c                          |    9 +-----
+ fs/hugetlbfs/inode.c                      |   13 +--------
+ fs/inode.c                                |   11 --------
+ fs/isofs/inode.c                          |    3 +-
+ fs/jffs2/fs.c                             |    6 +---
+ fs/jfs/namei.c                            |   13 ----------
+ fs/jfs/super.c                            |    4 +-
+ fs/libfs.c                                |    6 +---
+ fs/logfs/dir.c                            |    3 --
+ fs/logfs/super.c                          |    7 ++---
+ fs/minix/inode.c                          |   38 +++++++++++++----------------
+ fs/minix/minix.h                          |    1 -
+ fs/minix/namei.c                          |   14 +----------
+ fs/namei.c                                |   13 ++++++++++
+ fs/ncpfs/inode.c                          |    6 +---
+ fs/nfs/getroot.c                          |    6 +---
+ fs/nilfs2/namei.c                         |   11 --------
+ fs/nilfs2/super.c                         |    4 +-
+ fs/ntfs/super.c                           |    7 +++--
+ fs/ocfs2/dlmfs/dlmfs.c                    |   14 +---------
+ fs/ocfs2/super.c                          |   11 +++-----
+ fs/omfs/inode.c                           |    6 +---
+ fs/openpromfs/inode.c                     |    3 +-
+ fs/proc/inode.c                           |   16 ++----------
+ fs/pstore/inode.c                         |   25 +++++-------------
+ fs/qnx4/inode.c                           |   33 +-----------------------
+ fs/qnx4/namei.c                           |    4 ---
+ fs/ramfs/inode.c                          |   30 +++++-----------------
+ fs/reiserfs/super.c                       |    6 +---
+ fs/romfs/super.c                          |    6 +---
+ fs/squashfs/super.c                       |    3 +-
+ fs/sysfs/mount.c                          |    3 +-
+ fs/sysv/namei.c                           |   12 +--------
+ fs/sysv/super.c                           |   27 ++++++++++----------
+ fs/sysv/sysv.h                            |    1 -
+ fs/ubifs/super.c                          |    6 +---
+ fs/udf/namei.c                            |   13 ----------
+ fs/udf/super.c                            |    6 +++-
+ fs/ufs/namei.c                            |   14 +----------
+ fs/ufs/super.c                            |    7 ++---
+ fs/xfs/xfs_rename.c                       |   11 --------
+ fs/xfs/xfs_super.c                        |    7 ++---
+ fs/xfs/xfs_utils.c                        |    2 -
+ fs/xfs/xfs_vnodeops.c                     |   16 ------------
+ include/linux/dcache.h                    |    1 -
+ include/linux/file.h                      |    1 -
+ include/linux/fs.h                        |    6 ++++-
+ ipc/mqueue.c                              |   24 +++++-------------
+ kernel/cgroup.c                           |    8 +----
+ mm/shmem.c                                |   10 ++-----
+ net/sunrpc/rpc_pipe.c                     |    8 +----
+ 92 files changed, 212 insertions(+), 573 deletions(-)
+Merging pci/linux-next (5b415f1 PCI / PM: Disable wakeup during shutdown for devices not enabled to wake up)
+$ git merge pci/linux-next
+Auto-merging drivers/xen/xen-pciback/pci_stub.c
+Merge made by the 'recursive' strategy.
+ arch/x86/pci/acpi.c                  |    7 +-
+ arch/x86/pci/i386.c                  |   83 ++++++-
+ drivers/pci/hotplug/acpiphp_glue.c   |   29 +-
+ drivers/pci/hotplug/cpcihp_generic.c |    2 +-
+ drivers/pci/hotplug/ibmphp_ebda.c    |    6 +-
+ drivers/pci/hotplug/pciehp_hpc.c     |  133 ++++++++--
+ drivers/pci/iov.c                    |    8 +-
+ drivers/pci/pci-driver.c             |   10 +
+ drivers/pci/pci-sysfs.c              |    5 +-
+ drivers/pci/pci.c                    |   32 ++-
+ drivers/pci/pci.h                    |    2 +
+ drivers/pci/pcie/Kconfig             |   25 ++
+ drivers/pci/pcie/aspm.c              |    8 +
+ drivers/pci/probe.c                  |   73 +++---
+ drivers/pci/quirks.c                 |   57 ++++-
+ drivers/pci/remove.c                 |   10 +-
+ drivers/pci/setup-bus.c              |  505 +++++++++++++++++++++++-----------
+ drivers/pci/setup-res.c              |   90 +++----
+ drivers/xen/xen-pciback/pci_stub.c   |   41 +++-
+ drivers/xen/xen-pciback/pciback.h    |    1 +
+ include/linux/ioport.h               |    6 -
+ include/linux/pci.h                  |    5 +-
+ 22 files changed, 826 insertions(+), 312 deletions(-)
+Merging hid/for-next (40e1df8 Merge branch 'upstream' into for-next)
+$ git merge hid/for-next
+Auto-merging drivers/hid/hid-wacom.c
+Merge made by the 'recursive' strategy.
+ drivers/hid/Kconfig             |   67 +++-----------
+ drivers/hid/Makefile            |   12 +--
+ drivers/hid/hid-chicony.c       |    7 ++
+ drivers/hid/hid-core.c          |    8 ++
+ drivers/hid/hid-ids.h           |   14 +++-
+ drivers/hid/hid-input.c         |    9 ++-
+ drivers/hid/hid-logitech-dj.c   |    2 +-
+ drivers/hid/hid-magicmouse.c    |    2 +
+ drivers/hid/hid-multitouch.c    |  102 +++++++++++++++++++--
+ drivers/hid/hid-sjoy.c          |    6 +-
+ drivers/hid/hid-tivo.c          |   89 ++++++++++++++++++
+ drivers/hid/hid-wacom.c         |    1 +
+ drivers/hid/hid-waltop.c        |  192 +++++++++++++++++++++++++++++++++++++++
+ drivers/hid/usbhid/hid-quirks.c |    1 +
+ 14 files changed, 437 insertions(+), 75 deletions(-)
+ create mode 100644 drivers/hid/hid-tivo.c
+Merging quilt/i2c (c3632e0 i2c-i801: Use usleep_range to wait for command completion)
+$ git merge quilt/i2c
+Merge made by the 'recursive' strategy.
+ Documentation/i2c/busses/i2c-i801 |    1 +
+ drivers/i2c/busses/Kconfig        |    1 +
+ drivers/i2c/busses/i2c-gpio.c     |    3 +--
+ drivers/i2c/busses/i2c-i801.c     |   27 +++++++++++++++------------
+ drivers/i2c/busses/i2c-isch.c     |   10 +++++-----
+ drivers/i2c/i2c-core.c            |   12 ++++++++----
+ 6 files changed, 31 insertions(+), 23 deletions(-)
+Merging bjdooks-i2c/next-i2c (fc84fe1 Merge branch 'for_3.3/i2c/misc' of git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into for-33/i2c/omap)
+$ git merge bjdooks-i2c/next-i2c
+Resolved 'drivers/i2c/busses/i2c-omap.c' using previous resolution.
+Auto-merging drivers/i2c/busses/i2c-omap.c
+CONFLICT (content): Merge conflict in drivers/i2c/busses/i2c-omap.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master e845bc4] Merge remote-tracking branch 'bjdooks-i2c/next-i2c'
+$ git diff -M --stat --summary HEAD^..
+Merging quilt/jdelvare-hwmon (127e71e hwmon: (mc13xxx-adc) Add support for the MC13892 PMIC)
+$ git merge quilt/jdelvare-hwmon
+Merge made by the 'recursive' strategy.
+ Documentation/hwmon/lm90        |    4 +
+ Documentation/hwmon/mc13783-adc |   50 +++-
+ drivers/hwmon/Kconfig           |   18 +-
+ drivers/hwmon/fam15h_power.c    |   10 +-
+ drivers/hwmon/lm63.c            |  586 ++++++++++++++++++++++-----------------
+ drivers/hwmon/lm90.c            |   77 ++++--
+ drivers/hwmon/mc13783-adc.c     |  103 ++++++--
+ drivers/hwmon/w83795.c          |  132 ++++++---
+ 8 files changed, 609 insertions(+), 371 deletions(-)
+Merging hwmon-staging/hwmon-next (fa753a1 hwmon: (hwmon-vid) Fix checkpatch issues)
+$ git merge hwmon-staging/hwmon-next
+Auto-merging drivers/hwmon/w83795.c
+Auto-merging drivers/hwmon/lm90.c
+Auto-merging drivers/hwmon/lm63.c
+Auto-merging drivers/hwmon/Kconfig
+Merge made by the 'recursive' strategy.
+ Documentation/hwmon/lm80         |    9 +-
+ drivers/hwmon/Kconfig            |    4 +-
+ drivers/hwmon/abituguru.c        |  584 ++++++++++++++---------
+ drivers/hwmon/abituguru3.c       |  267 +++++++----
+ drivers/hwmon/ad7314.c           |   12 +-
+ drivers/hwmon/ad7414.c           |   21 +-
+ drivers/hwmon/ad7418.c           |   25 +-
+ drivers/hwmon/adcxx.c            |   13 +-
+ drivers/hwmon/adm1021.c          |   97 +++--
+ drivers/hwmon/adm1025.c          |   76 ++--
+ drivers/hwmon/adm1026.c          |  504 +++++++++++++--------
+ drivers/hwmon/adm1029.c          |   47 +--
+ drivers/hwmon/adm1031.c          |   73 ++--
+ drivers/hwmon/adm9240.c          |   86 ++--
+ drivers/hwmon/ads1015.c          |   13 +-
+ drivers/hwmon/ads7828.c          |   59 ++--
+ drivers/hwmon/ads7871.c          |   39 +-
+ drivers/hwmon/adt7411.c          |   14 +-
+ drivers/hwmon/adt7462.c          |   30 +-
+ drivers/hwmon/adt7470.c          |   19 +-
+ drivers/hwmon/adt7475.c          |  105 +++--
+ drivers/hwmon/amc6821.c          |   74 ++--
+ drivers/hwmon/applesmc.c         |   14 +-
+ drivers/hwmon/asb100.c           |  200 +++++----
+ drivers/hwmon/asc7621.c          |    8 +-
+ drivers/hwmon/asus_atk0110.c     |   18 +-
+ drivers/hwmon/atxp1.c            |  173 ++++---
+ drivers/hwmon/coretemp.c         |    4 +-
+ drivers/hwmon/dme1737.c          |  506 ++++++++++++---------
+ drivers/hwmon/ds1621.c           |   93 ++--
+ drivers/hwmon/ds620.c            |   13 +-
+ drivers/hwmon/emc1403.c          |   25 +-
+ drivers/hwmon/emc2103.c          |   63 ++--
+ drivers/hwmon/emc6w201.c         |   12 +-
+ drivers/hwmon/f71805f.c          |  201 ++++++---
+ drivers/hwmon/f71882fg.c         |   63 ++-
+ drivers/hwmon/f75375s.c          |   13 +-
+ drivers/hwmon/fschmd.c           |  231 ++++++----
+ drivers/hwmon/g760a.c            |   48 +--
+ drivers/hwmon/gl518sm.c          |  115 +++--
+ drivers/hwmon/gl520sm.c          |  243 ++++++----
+ drivers/hwmon/hwmon-vid.c        |  159 +++----
+ drivers/hwmon/hwmon.c            |   25 +-
+ drivers/hwmon/i5k_amb.c          |   18 +-
+ drivers/hwmon/ibmaem.c           |    2 +-
+ drivers/hwmon/it87.c             |  176 +++++---
+ drivers/hwmon/jc42.c             |   19 +-
+ drivers/hwmon/k10temp.c          |    2 +-
+ drivers/hwmon/k8temp.c           |   17 +-
+ drivers/hwmon/lineage-pem.c      |   13 +-
+ drivers/hwmon/lm63.c             |   13 +-
+ drivers/hwmon/lm70.c             |   38 +-
+ drivers/hwmon/lm73.c             |   15 +-
+ drivers/hwmon/lm75.c             |   17 +-
+ drivers/hwmon/lm77.c             |  172 ++++---
+ drivers/hwmon/lm78.c             |  206 ++++++---
+ drivers/hwmon/lm80.c             |  247 +++++++---
+ drivers/hwmon/lm83.c             |   30 +-
+ drivers/hwmon/lm85.c             |  374 +++++++++------
+ drivers/hwmon/lm87.c             |  958 ++++++++++++++++++++------------------
+ drivers/hwmon/lm90.c             |   13 +-
+ drivers/hwmon/lm92.c             |  111 +++--
+ drivers/hwmon/lm93.c             |  696 +++++++++++++++++-----------
+ drivers/hwmon/lm95241.c          |   13 +-
+ drivers/hwmon/lm95245.c          |   13 +-
+ drivers/hwmon/ltc4151.c          |   16 +-
+ drivers/hwmon/ltc4215.c          |   28 +-
+ drivers/hwmon/ltc4245.c          |   22 +-
+ drivers/hwmon/ltc4261.c          |   13 +-
+ drivers/hwmon/max1111.c          |   15 +-
+ drivers/hwmon/max16065.c         |   13 +-
+ drivers/hwmon/max1619.c          |   34 +-
+ drivers/hwmon/max1668.c          |   51 +--
+ drivers/hwmon/max6639.c          |   13 +-
+ drivers/hwmon/max6642.c          |   13 +-
+ drivers/hwmon/max6650.c          |  177 ++++----
+ drivers/hwmon/pc87360.c          |  602 ++++++++++++++----------
+ drivers/hwmon/pc87427.c          |   72 ++--
+ drivers/hwmon/pcf8591.c          |  143 ++++---
+ drivers/hwmon/pmbus/adm1275.c    |   12 +-
+ drivers/hwmon/pmbus/lm25066.c    |   12 +-
+ drivers/hwmon/pmbus/ltc2978.c    |   12 +-
+ drivers/hwmon/pmbus/max16064.c   |   12 +-
+ drivers/hwmon/pmbus/max34440.c   |   12 +-
+ drivers/hwmon/pmbus/max8688.c    |   12 +-
+ drivers/hwmon/pmbus/pmbus.c      |   12 +-
+ drivers/hwmon/pmbus/pmbus_core.c |    2 +-
+ drivers/hwmon/pmbus/ucd9000.c    |   12 +-
+ drivers/hwmon/pmbus/ucd9200.c    |   12 +-
+ drivers/hwmon/pmbus/zl6100.c     |   12 +-
+ drivers/hwmon/sht15.c            |    2 +-
+ drivers/hwmon/sht21.c            |   23 +-
+ drivers/hwmon/sis5595.c          |  307 ++++++++-----
+ drivers/hwmon/smm665.c           |   22 +-
+ drivers/hwmon/smsc47b397.c       |   64 ++--
+ drivers/hwmon/smsc47m1.c         |  291 ++++++++-----
+ drivers/hwmon/smsc47m192.c       |  145 ++++---
+ drivers/hwmon/thmc50.c           |   84 ++--
+ drivers/hwmon/tmp102.c           |   12 +-
+ drivers/hwmon/tmp401.c           |   13 +-
+ drivers/hwmon/tmp421.c           |   13 +-
+ drivers/hwmon/ultra45_env.c      |   34 +-
+ drivers/hwmon/via686a.c          |  357 +++++++++------
+ drivers/hwmon/vt1211.c           |  389 ++++++++--------
+ drivers/hwmon/vt8231.c           |  285 +++++++-----
+ drivers/hwmon/w83627ehf.c        |  189 +++++----
+ drivers/hwmon/w83627hf.c         |  272 +++++++----
+ drivers/hwmon/w83781d.c          |  475 +++++++++++--------
+ drivers/hwmon/w83791d.c          |  331 ++++++++------
+ drivers/hwmon/w83792d.c          |  397 +++++++++-------
+ drivers/hwmon/w83793.c           |  453 ++++++++++--------
+ drivers/hwmon/w83795.c           |   13 +-
+ drivers/hwmon/w83l785ts.c        |   30 +-
+ drivers/hwmon/w83l786ng.c        |  190 +++++----
+ drivers/hwmon/wm831x-hwmon.c     |    8 +-
+ drivers/hwmon/wm8350-hwmon.c     |    2 +-
+ 116 files changed, 7492 insertions(+), 5804 deletions(-)
+Merging quilt/kernel-doc (7e7b32a Update quilt tree location for Documentation/ patches.)
+$ git merge quilt/kernel-doc
+Merge made by the 'recursive' strategy.
+Merging docs/docs-move (5c24d8b Merge branch 'docs/docbook/drm' of git://github.com/mfwitten/linux into docs-move)
+$ git merge docs/docs-move
+Already up-to-date.
+Merging v4l-dvb/master (d345066 Merge /home/v4l/v4l/patchwork)
+$ git merge v4l-dvb/master
+Auto-merging drivers/hid/hid-ids.h
+Auto-merging drivers/hid/hid-core.c
+Merge made by the 'recursive' strategy.
+ Documentation/DocBook/media/v4l/compat.xml         |    4 +
+ Documentation/DocBook/media/v4l/controls.xml       |   59 ++
+ Documentation/DocBook/media/v4l/v4l2.xml           |   10 +-
+ .../DocBook/media/v4l/vidioc-decoder-cmd.xml       |  256 +++++++++
+ .../DocBook/media/v4l/vidioc-encoder-cmd.xml       |    9 +-
+ .../DocBook/media/v4l/vidioc-querycap.xml          |   36 ++-
+ drivers/hid/hid-core.c                             |   10 +
+ drivers/hid/hid-ids.h                              |    1 +
+ drivers/media/common/tuners/max2165.c              |    9 +-
+ drivers/media/common/tuners/mt2063.c               |    4 +-
+ drivers/media/common/tuners/tuner-types.c          |    4 +
+ drivers/media/common/tuners/xc5000.c               |   47 ++-
+ drivers/media/common/tuners/xc5000.h               |    5 +
+ drivers/media/dvb/ddbridge/ddbridge-core.c         |    1 +
+ drivers/media/dvb/ddbridge/ddbridge.h              |    2 -
+ drivers/media/dvb/dvb-core/dvb_frontend.c          |    2 +
+ drivers/media/dvb/dvb-usb/Kconfig                  |    8 +
+ drivers/media/dvb/dvb-usb/Makefile                 |    4 +-
+ drivers/media/dvb/dvb-usb/anysee.c                 |   38 ++-
+ drivers/media/dvb/dvb-usb/az6007.c                 |  582 ++++++++++++++++++++
+ drivers/media/dvb/dvb-usb/dvb-usb-ids.h            |    3 +
+ drivers/media/dvb/dvb-usb/it913x.c                 |  128 ++++--
+ drivers/media/dvb/dvb-usb/lmedm04.c                |    9 +-
+ drivers/media/dvb/frontends/drxk.h                 |   23 +-
+ drivers/media/dvb/frontends/drxk_hard.c            |   47 +-
+ drivers/media/dvb/frontends/drxk_hard.h            |    1 +
+ drivers/media/dvb/frontends/tda1004x.c             |    4 +-
+ drivers/media/dvb/ngene/ngene-cards.c              |    1 +
+ drivers/media/radio/Kconfig                        |  123 ++---
+ drivers/media/radio/Makefile                       |    2 +
+ drivers/media/radio/radio-aimslab.c                |  439 ++++-----------
+ drivers/media/radio/radio-aztech.c                 |  371 +++----------
+ drivers/media/radio/radio-gemtek.c                 |  493 ++++-------------
+ drivers/media/radio/radio-isa.c                    |  339 ++++++++++++
+ drivers/media/radio/radio-isa.h                    |  105 ++++
+ drivers/media/radio/radio-keene.c                  |  427 ++++++++++++++
+ drivers/media/radio/radio-rtrack2.c                |  332 +++---------
+ drivers/media/radio/radio-terratec.c               |  364 ++----------
+ drivers/media/radio/radio-trust.c                  |  387 ++++----------
+ drivers/media/radio/radio-typhoon.c                |  365 +++----------
+ drivers/media/radio/radio-zoltrix.c                |  441 ++++-----------
+ drivers/media/radio/wl128x/Kconfig                 |    4 +-
+ drivers/media/rc/fintek-cir.c                      |   26 +-
+ drivers/media/rc/fintek-cir.h                      |    4 +-
+ drivers/media/rc/imon.c                            |   26 +-
+ drivers/media/rc/keymaps/Makefile                  |    2 +
+ drivers/media/rc/keymaps/rc-it913x-v1.c            |   95 ++++
+ drivers/media/rc/keymaps/rc-it913x-v2.c            |   94 ++++
+ .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c  |   52 ++
+ drivers/media/video/bt8xx/bttv-driver.c            |    4 -
+ drivers/media/video/cx18/cx18-driver.h             |    2 -
+ drivers/media/video/cx18/cx18-ioctl.c              |    4 -
+ drivers/media/video/cx231xx/cx231xx-417.c          |    1 -
+ drivers/media/video/davinci/vpif.h                 |    2 -
+ drivers/media/video/davinci/vpif_display.c         |    2 -
+ drivers/media/video/hdpvr/hdpvr-core.c             |   18 +-
+ drivers/media/video/hdpvr/hdpvr-video.c            |   46 ++-
+ drivers/media/video/hdpvr/hdpvr.h                  |    1 +
+ drivers/media/video/ivtv/ivtv-controls.c           |   62 ++
+ drivers/media/video/ivtv/ivtv-controls.h           |    2 +
+ drivers/media/video/ivtv/ivtv-driver.c             |   37 ++-
+ drivers/media/video/ivtv/ivtv-driver.h             |   13 +-
+ drivers/media/video/ivtv/ivtv-fileops.c            |    2 +-
+ drivers/media/video/ivtv/ivtv-ioctl.c              |  193 +++----
+ drivers/media/video/ivtv/ivtv-streams.c            |   23 +-
+ drivers/media/video/omap/omap_vout.c               |    3 +-
+ drivers/media/video/omap3isp/ispccdc.c             |    2 +-
+ drivers/media/video/ov6650.c                       |    2 +-
+ drivers/media/video/pvrusb2/pvrusb2-v4l2.c         |    1 -
+ drivers/media/video/pwc/pwc-v4l.c                  |   10 +-
+ drivers/media/video/s5p-tv/hdmi_drv.c              |    4 +-
+ drivers/media/video/s5p-tv/mixer_drv.c             |    2 +-
+ drivers/media/video/saa7164/saa7164-encoder.c      |    6 -
+ drivers/media/video/saa7164/saa7164-vbi.c          |    6 -
+ drivers/media/video/tm6000/tm6000-input.c          |    3 +-
+ drivers/media/video/tuner-core.c                   |   15 +
+ drivers/media/video/tveeprom.c                     |    2 +-
+ drivers/media/video/v4l2-compat-ioctl32.c          |    2 +
+ drivers/media/video/v4l2-ctrls.c                   |   55 ++
+ drivers/media/video/v4l2-ioctl.c                   |   40 ++-
+ drivers/media/video/v4l2-subdev.c                  |   12 +-
+ drivers/media/video/vivi.c                         |   26 +-
+ drivers/staging/media/easycap/easycap_main.c       |    1 +
+ include/linux/ivtv.h                               |    6 +-
+ include/linux/videodev2.h                          |   95 +++-
+ include/media/davinci/vpif_types.h                 |    2 +
+ include/media/rc-map.h                             |    2 +
+ include/media/tuner.h                              |    1 +
+ include/media/v4l2-ctrls.h                         |   13 +
+ include/media/v4l2-ioctl.h                         |    4 +
+ 90 files changed, 3625 insertions(+), 2900 deletions(-)
+ create mode 100644 Documentation/DocBook/media/v4l/vidioc-decoder-cmd.xml
+ create mode 100644 drivers/media/dvb/dvb-usb/az6007.c
+ create mode 100644 drivers/media/radio/radio-isa.c
+ create mode 100644 drivers/media/radio/radio-isa.h
+ create mode 100644 drivers/media/radio/radio-keene.c
+ create mode 100644 drivers/media/rc/keymaps/rc-it913x-v1.c
+ create mode 100644 drivers/media/rc/keymaps/rc-it913x-v2.c
+Merging kbuild/for-next (75cb742 Merge branch 'kbuild/rc-fixes' into kbuild/for-next)
+$ git merge kbuild/for-next
+Merge made by the 'recursive' strategy.
+ scripts/Makefile.build     |    2 ++
+ scripts/coccicheck         |   13 ++++---------
+ scripts/kconfig/confdata.c |   26 ++++++--------------------
+ scripts/kconfig/symbol.c   |    9 ++++++++-
+ 4 files changed, 20 insertions(+), 30 deletions(-)
+Merging kconfig/for-next (eae1c36 Merge branch 'kconfig/for-linus-2' into kconfig/for-next)
+$ git merge kconfig/for-next
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Merging libata/NEXT (96c4d29 pata_legacy: correctly mask recovery field for HT6560B)
+$ git merge libata/NEXT
+Merge made by the 'recursive' strategy.
+ drivers/acpi/dock.c         |   98 +++++++++++++++
+ drivers/acpi/glue.c         |    2 +
+ drivers/ata/ahci.c          |    8 ++
+ drivers/ata/ata_piix.c      |    8 ++
+ drivers/ata/libata-acpi.c   |  273 +++++++++++++++++++++++++-----------------
+ drivers/ata/libata-core.c   |    6 +-
+ drivers/ata/libata-pmp.c    |    4 -
+ drivers/ata/libata-scsi.c   |    3 +
+ drivers/ata/libata.h        |   13 ++-
+ drivers/ata/pata_acpi.c     |    4 +-
+ drivers/ata/pata_legacy.c   |    3 +-
+ drivers/scsi/scsi_lib.c     |   11 ++
+ include/acpi/acpi_drivers.h |   11 ++
+ include/linux/libata.h      |    7 +-
+ include/scsi/scsi.h         |   10 ++
+ 15 files changed, 329 insertions(+), 132 deletions(-)
+Merging infiniband/for-next (715252d IB/srpt: Don't return freed pointer from srpt_alloc_ioctx_ring())
+$ git merge infiniband/for-next
+Already up-to-date.
+Merging acpi/next (eb7004e Merge branches 'atomicio-apei', 'hotplug', 'sony-nvs-nosave' and 'thermal-netlink' into release)
+$ git merge acpi/next
+Already up-to-date.
+Merging ieee1394/for-next (6e01490 Merge branch 'fixes' into for-next)
+$ git merge ieee1394/for-next
+Merge made by the 'recursive' strategy.
+ drivers/firewire/core-device.c |    2 +
+ drivers/firewire/core.h        |   13 +++
+ drivers/firewire/ohci.c        |  185 +++++++++++++++++++++++-----------------
+ drivers/firewire/sbp2.c        |   93 +++++++++++---------
+ include/linux/firewire.h       |   12 ---
+ sound/firewire/isight.c        |    4 +-
+ sound/firewire/speakers.c      |    4 -
+ 7 files changed, 173 insertions(+), 140 deletions(-)
+Merging ubi/linux-next (ecaabdb UBI: fix error handling in ubi_scan())
+$ git merge ubi/linux-next
+Merge made by the 'recursive' strategy.
+ drivers/mtd/ubi/scan.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+Merging dlm/next (60f98d1 dlm: add recovery callbacks)
+$ git merge dlm/next
+Already up-to-date.
+Merging scsi/master (50824d6 [SCSI] libsas: async ata-eh)
+$ git merge scsi/master
+Auto-merging include/linux/libata.h
+Auto-merging drivers/scsi/scsi_lib.c
+Auto-merging drivers/ata/libata.h
+Merge made by the 'recursive' strategy.
+ Documentation/scsi/LICENSE.qla2xxx   |   41 +--
+ Documentation/scsi/bfa.txt           |   82 +++
+ Documentation/scsi/libsas.txt        |   15 -
+ drivers/ata/libata-eh.c              |    1 +
+ drivers/ata/libata.h                 |    1 -
+ drivers/scsi/Kconfig                 |    8 +
+ drivers/scsi/Makefile                |    1 +
+ drivers/scsi/aacraid/aachba.c        |    4 +
+ drivers/scsi/aacraid/aacraid.h       |   27 +-
+ drivers/scsi/aacraid/comminit.c      |   21 +-
+ drivers/scsi/aacraid/commsup.c       |   26 +
+ drivers/scsi/aacraid/linit.c         |   28 +-
+ drivers/scsi/aacraid/rx.c            |    1 +
+ drivers/scsi/aacraid/sa.c            |    1 +
+ drivers/scsi/aacraid/src.c           |  293 +++++++--
+ drivers/scsi/aic94xx/aic94xx.h       |    2 +
+ drivers/scsi/aic94xx/aic94xx_dev.c   |   38 +-
+ drivers/scsi/aic94xx/aic94xx_init.c  |    5 +-
+ drivers/scsi/bfa/bfad_bsg.c          |    4 +-
+ drivers/scsi/bnx2fc/bnx2fc.h         |    8 +-
+ drivers/scsi/bnx2fc/bnx2fc_fcoe.c    |   20 +-
+ drivers/scsi/bnx2i/bnx2i_hwi.c       |   12 +-
+ drivers/scsi/bnx2i/bnx2i_init.c      |    9 +-
+ drivers/scsi/cxgbi/libcxgbi.c        |   13 +-
+ drivers/scsi/fcoe/fcoe.c             |  167 ++++--
+ drivers/scsi/fcoe/fcoe.h             |    3 -
+ drivers/scsi/fcoe/fcoe_transport.c   |    4 +-
+ drivers/scsi/hpsa.c                  |  344 ++++++-----
+ drivers/scsi/hpsa.h                  |    3 +-
+ drivers/scsi/hpsa_cmd.h              |    9 +-
+ drivers/scsi/isci/host.c             |   17 +-
+ drivers/scsi/isci/init.c             |    8 +-
+ drivers/scsi/isci/registers.h        |   27 +-
+ drivers/scsi/isci/request.c          |  150 +++++-
+ drivers/scsi/isci/scu_task_context.h |   55 ++-
+ drivers/scsi/isci/task.c             |    6 +-
+ drivers/scsi/isci/task.h             |   36 -
+ drivers/scsi/iscsi_tcp.c             |   13 +-
+ drivers/scsi/libfc/fc_disc.c         |    7 +
+ drivers/scsi/libfc/fc_elsct.c        |    3 +-
+ drivers/scsi/libfc/fc_exch.c         |    7 +-
+ drivers/scsi/libfc/fc_lport.c        |  227 +++++++-
+ drivers/scsi/libiscsi.c              |   28 +-
+ drivers/scsi/libiscsi_tcp.c          |   18 +
+ drivers/scsi/libsas/sas_ata.c        |  583 +++++++-----------
+ drivers/scsi/libsas/sas_discover.c   |  158 ++++--
+ drivers/scsi/libsas/sas_event.c      |   89 +++-
+ drivers/scsi/libsas/sas_expander.c   |   94 ++-
+ drivers/scsi/libsas/sas_init.c       |  192 +++++-
+ drivers/scsi/libsas/sas_internal.h   |   69 ++-
+ drivers/scsi/libsas/sas_phy.c        |   12 +-
+ drivers/scsi/libsas/sas_port.c       |   19 +-
+ drivers/scsi/libsas/sas_scsi_host.c  |  263 ++++-----
+ drivers/scsi/lpfc/lpfc.h             |   13 +-
+ drivers/scsi/lpfc/lpfc_attr.c        |   12 +-
+ drivers/scsi/lpfc/lpfc_bsg.c         |   18 +-
+ drivers/scsi/lpfc/lpfc_crtn.h        |    1 +
+ drivers/scsi/lpfc/lpfc_ct.c          |    4 +-
+ drivers/scsi/lpfc/lpfc_debugfs.c     |   19 +
+ drivers/scsi/lpfc/lpfc_els.c         |    5 +-
+ drivers/scsi/lpfc/lpfc_hbadisc.c     |   12 +-
+ drivers/scsi/lpfc/lpfc_hw.h          |    5 +-
+ drivers/scsi/lpfc/lpfc_hw4.h         |   49 ++-
+ drivers/scsi/lpfc/lpfc_init.c        |  137 ++++-
+ drivers/scsi/lpfc/lpfc_nportdisc.c   |   77 +++-
+ drivers/scsi/lpfc/lpfc_scsi.c        | 1178 +++++++++++++++++++++++++++++-----
+ drivers/scsi/lpfc/lpfc_sli.c         |  240 +++++---
+ drivers/scsi/lpfc/lpfc_sli.h         |    1 +
+ drivers/scsi/lpfc/lpfc_sli4.h        |    3 +-
+ drivers/scsi/lpfc/lpfc_version.h     |    2 +-
+ drivers/scsi/mpt2sas/mpt2sas_base.c  |    5 +
+ drivers/scsi/mpt2sas/mpt2sas_scsih.c |    6 +-
+ drivers/scsi/mvsas/mv_init.c         |    1 -
+ drivers/scsi/mvsas/mv_sas.c          |    8 +-
+ drivers/scsi/pm8001/pm8001_hwi.c     |  281 +++++++--
+ drivers/scsi/pm8001/pm8001_init.c    |    1 -
+ drivers/scsi/pm8001/pm8001_sas.c     |  108 +++-
+ drivers/scsi/pm8001/pm8001_sas.h     |    6 +
+ drivers/scsi/qla2xxx/qla_attr.c      |  177 +-----
+ drivers/scsi/qla2xxx/qla_bsg.c       |  120 ++--
+ drivers/scsi/qla2xxx/qla_dbg.c       |  630 +++++++++++++++++-
+ drivers/scsi/qla2xxx/qla_dbg.h       |   63 ++
+ drivers/scsi/qla2xxx/qla_def.h       |  117 ++--
+ drivers/scsi/qla2xxx/qla_dfs.c       |    2 +-
+ drivers/scsi/qla2xxx/qla_fw.h        |   13 +
+ drivers/scsi/qla2xxx/qla_gbl.h       |   22 +-
+ drivers/scsi/qla2xxx/qla_gs.c        |   86 ++-
+ drivers/scsi/qla2xxx/qla_init.c      |  540 ++++++----------
+ drivers/scsi/qla2xxx/qla_inline.h    |   51 ++-
+ drivers/scsi/qla2xxx/qla_iocb.c      |  167 +++---
+ drivers/scsi/qla2xxx/qla_isr.c       |  445 ++++++--------
+ drivers/scsi/qla2xxx/qla_mbx.c       |  410 ++++++++++---
+ drivers/scsi/qla2xxx/qla_mid.c       |    2 +-
+ drivers/scsi/qla2xxx/qla_nx.c        |   90 +--
+ drivers/scsi/qla2xxx/qla_nx.h        |    3 +-
+ drivers/scsi/qla2xxx/qla_os.c        |  432 ++++++++-----
+ drivers/scsi/qla2xxx/qla_sup.c       |  148 ++++-
+ drivers/scsi/qla4xxx/ql4_def.h       |   41 ++-
+ drivers/scsi/qla4xxx/ql4_fw.h        |   24 +
+ drivers/scsi/qla4xxx/ql4_glbl.h      |    7 +
+ drivers/scsi/qla4xxx/ql4_init.c      |    5 +
+ drivers/scsi/qla4xxx/ql4_iocb.c      |   92 +++
+ drivers/scsi/qla4xxx/ql4_isr.c       |   78 +++
+ drivers/scsi/qla4xxx/ql4_mbx.c       |    2 +
+ drivers/scsi/qla4xxx/ql4_nx.c        |   17 +-
+ drivers/scsi/qla4xxx/ql4_nx.h        |    1 +
+ drivers/scsi/qla4xxx/ql4_os.c        |  287 ++++++++-
+ drivers/scsi/qla4xxx/ql4_version.h   |    2 +-
+ drivers/scsi/scsi.c                  |    6 -
+ drivers/scsi/scsi_debug.c            |    6 +-
+ drivers/scsi/scsi_error.c            |   24 +-
+ drivers/scsi/scsi_lib.c              |    5 +-
+ drivers/scsi/scsi_transport_fc.c     |   30 +-
+ drivers/scsi/scsi_transport_iscsi.c  |  159 +++++-
+ drivers/scsi/scsi_transport_sas.c    |   36 +-
+ drivers/scsi/sd.c                    |   86 +++-
+ drivers/scsi/sd.h                    |   35 +
+ drivers/scsi/st.c                    |   11 +
+ drivers/scsi/virtio_scsi.c           |  594 +++++++++++++++++
+ include/linux/libata.h               |    1 +
+ include/linux/virtio_ids.h           |    1 +
+ include/linux/virtio_scsi.h          |  114 ++++
+ include/scsi/fc/fc_ms.h              |  213 ++++++
+ include/scsi/fc_encode.h             |  363 ++++++++++-
+ include/scsi/iscsi_if.h              |   47 ++
+ include/scsi/libfc.h                 |   11 +
+ include/scsi/libiscsi.h              |    3 +-
+ include/scsi/libiscsi_tcp.h          |    2 +-
+ include/scsi/libsas.h                |   57 +-
+ include/scsi/sas_ata.h               |   26 +-
+ include/scsi/scsi_cmnd.h             |   12 +-
+ include/scsi/scsi_driver.h           |    1 +
+ include/scsi/scsi_transport_fc.h     |   32 +-
+ include/scsi/scsi_transport_iscsi.h  |   18 +
+ include/scsi/scsi_transport_sas.h    |    6 +-
+ 135 files changed, 8480 insertions(+), 2957 deletions(-)
+ create mode 100644 Documentation/scsi/bfa.txt
+ create mode 100644 drivers/scsi/virtio_scsi.c
+ create mode 100644 include/linux/virtio_scsi.h
+ create mode 100644 include/scsi/fc/fc_ms.h
+Merging target-updates/for-next (24d2f08 tcm_fc: Remove cmd->cdb data member)
+$ git merge target-updates/for-next
+Auto-merging include/scsi/scsi.h
+Merge made by the 'recursive' strategy.
+ drivers/infiniband/ulp/srpt/ib_srpt.c      |   13 ++-
+ drivers/scsi/bnx2fc/bnx2fc_io.c            |    4 +-
+ drivers/scsi/libfc/fc_fcp.c                |    5 +-
+ drivers/target/iscsi/iscsi_target.c        |   10 +-
+ drivers/target/iscsi/iscsi_target_device.c |   19 ----
+ drivers/target/iscsi/iscsi_target_device.h |    2 -
+ drivers/target/iscsi/iscsi_target_erl1.c   |    2 +-
+ drivers/target/iscsi/iscsi_target_tmr.c    |    6 +-
+ drivers/target/iscsi/iscsi_target_tq.c     |    6 -
+ drivers/target/target_core_configfs.c      |    6 +-
+ drivers/target/target_core_device.c        |    5 -
+ drivers/target/target_core_iblock.c        |   78 +++++++--------
+ drivers/target/target_core_iblock.h        |    7 +-
+ drivers/target/target_core_pr.c            |    6 +-
+ drivers/target/target_core_tmr.c           |   24 ++--
+ drivers/target/target_core_transport.c     |  150 +++++++++++++---------------
+ drivers/target/tcm_fc/tcm_fc.h             |    2 -
+ drivers/target/tcm_fc/tfc_cmd.c            |   91 +++++++----------
+ include/scsi/fc/fc_fcp.h                   |    6 +-
+ include/scsi/scsi.h                        |    1 +
+ include/target/target_core_base.h          |   34 +++----
+ 21 files changed, 202 insertions(+), 275 deletions(-)
+Merging target-merge/for-next-merge (d65b4e9 Linux 3.3-rc3)
+$ git merge target-merge/for-next-merge
+Already up-to-date.
+Merging ibft/linux-next (935a9fe ibft: Fix finding IBFT ACPI table on UEFI)
+$ git merge ibft/linux-next
+Already up-to-date.
+Merging isci/all (57872c2 Merge branches 'devel' and 'fixes' into all)
+$ git merge isci/all
+Resolved 'drivers/scsi/isci/registers.h' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_ata.c' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_discover.c' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_event.c' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_expander.c' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_init.c' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_internal.h' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_port.c' using previous resolution.
+Resolved 'drivers/scsi/libsas/sas_scsi_host.c' using previous resolution.
+Resolved 'include/scsi/libsas.h' using previous resolution.
+Resolved 'include/scsi/sas_ata.h' using previous resolution.
+Auto-merging include/scsi/scsi_transport_sas.h
+Auto-merging include/scsi/sas_ata.h
+CONFLICT (content): Merge conflict in include/scsi/sas_ata.h
+Auto-merging include/scsi/libsas.h
+CONFLICT (content): Merge conflict in include/scsi/libsas.h
+Auto-merging include/linux/libata.h
+Auto-merging drivers/scsi/scsi_transport_sas.c
+Auto-merging drivers/scsi/pm8001/pm8001_sas.c
+Auto-merging drivers/scsi/pm8001/pm8001_init.c
+Auto-merging drivers/scsi/mvsas/mv_sas.c
+Auto-merging drivers/scsi/mvsas/mv_init.c
+Auto-merging drivers/scsi/libsas/sas_scsi_host.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_scsi_host.c
+Auto-merging drivers/scsi/libsas/sas_port.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_port.c
+Auto-merging drivers/scsi/libsas/sas_internal.h
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_internal.h
+Auto-merging drivers/scsi/libsas/sas_init.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_init.c
+Auto-merging drivers/scsi/libsas/sas_expander.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_expander.c
+Auto-merging drivers/scsi/libsas/sas_event.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_event.c
+Auto-merging drivers/scsi/libsas/sas_discover.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_discover.c
+Auto-merging drivers/scsi/libsas/sas_ata.c
+CONFLICT (content): Merge conflict in drivers/scsi/libsas/sas_ata.c
+Auto-merging drivers/scsi/isci/task.h
+Auto-merging drivers/scsi/isci/task.c
+Auto-merging drivers/scsi/isci/request.c
+Auto-merging drivers/scsi/isci/registers.h
+CONFLICT (content): Merge conflict in drivers/scsi/isci/registers.h
+Auto-merging drivers/scsi/isci/init.c
+Auto-merging drivers/scsi/isci/host.c
+Auto-merging drivers/scsi/aic94xx/aic94xx_init.c
+Auto-merging drivers/ata/libata.h
+Auto-merging drivers/ata/libata-scsi.c
+Auto-merging drivers/ata/libata-core.c
+Auto-merging Documentation/kernel-parameters.txt
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 2575cdb9] Merge remote-tracking branch 'isci/all'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/kernel-parameters.txt     |    6 +
+ drivers/ata/libata-core.c               |   34 ++--
+ drivers/ata/libata-scsi.c               |   13 ++
+ drivers/ata/libata.h                    |    1 +
+ drivers/scsi/aic94xx/aic94xx_init.c     |    1 -
+ drivers/scsi/aic94xx/aic94xx_tmf.c      |   11 +-
+ drivers/scsi/isci/host.c                |    1 -
+ drivers/scsi/isci/host.h                |   19 +--
+ drivers/scsi/isci/init.c                |   19 +-
+ drivers/scsi/isci/phy.c                 |  171 ++++++++++-------
+ drivers/scsi/isci/phy.h                 |  155 ++++++----------
+ drivers/scsi/isci/port.c                |  263 ++++++++++++++------------
+ drivers/scsi/isci/port.h                |  114 +++++-------
+ drivers/scsi/isci/remote_device.c       |   82 ++++-----
+ drivers/scsi/isci/remote_device.h       |  212 +++++++++------------
+ drivers/scsi/isci/remote_node_context.c |   19 +-
+ drivers/scsi/isci/remote_node_context.h |   97 +++++------
+ drivers/scsi/isci/request.c             |  220 ++-------------------
+ drivers/scsi/isci/request.h             |  228 +++++++++-------------
+ drivers/scsi/isci/task.c                |  152 +++------------
+ drivers/scsi/isci/task.h                |    4 -
+ drivers/scsi/libsas/sas_ata.c           |  315 +++++++++++++++++++++----------
+ drivers/scsi/libsas/sas_discover.c      |   98 ++++++++--
+ drivers/scsi/libsas/sas_event.c         |   19 ++-
+ drivers/scsi/libsas/sas_expander.c      |  304 ++++++++++++++++++------------
+ drivers/scsi/libsas/sas_host_smp.c      |   11 +-
+ drivers/scsi/libsas/sas_init.c          |   95 +++++++---
+ drivers/scsi/libsas/sas_internal.h      |   34 ++++-
+ drivers/scsi/libsas/sas_port.c          |   15 +-
+ drivers/scsi/libsas/sas_scsi_host.c     |  170 +++++++++--------
+ drivers/scsi/mvsas/mv_init.c            |    1 -
+ drivers/scsi/mvsas/mv_sas.c             |   23 ++-
+ drivers/scsi/pm8001/pm8001_init.c       |    1 -
+ drivers/scsi/pm8001/pm8001_sas.c        |   49 +++---
+ drivers/scsi/scsi_transport_sas.c       |   24 +++
+ include/linux/libata.h                  |    1 +
+ include/scsi/libsas.h                   |   29 ++-
+ include/scsi/sas.h                      |    4 +-
+ include/scsi/sas_ata.h                  |   32 ++--
+ include/scsi/scsi_transport_sas.h       |    6 +
+ 40 files changed, 1537 insertions(+), 1516 deletions(-)
+Merging slave-dma/next (b63fd6c i.MX SDMA: Fix burstsize settings)
+$ git merge slave-dma/next
+Auto-merging drivers/dma/imx-sdma.c
+Merge made by the 'recursive' strategy.
+ drivers/dma/amba-pl08x.c        |    2 +-
+ drivers/dma/imx-dma.c           |    9 +--
+ drivers/dma/imx-sdma.c          |  140 +++++++++++++++++++-------------------
+ drivers/dma/pl330.c             |   17 +++--
+ drivers/mmc/host/mxcmmc.c       |    1 +
+ sound/soc/imx/imx-pcm-dma-mx2.c |    1 +
+ 6 files changed, 88 insertions(+), 82 deletions(-)
+Merging dmaengine/next (d07a74a dmaengine: fix missing 'cnt' in ?: in dmatest)
+$ git merge dmaengine/next
+Already up-to-date.
+Merging net-next/master (8de65c2 Merge branch '20120221_isdn' of git://repo.or.cz/linux-2.6/trivial-mods)
+$ git merge net-next/master
+Resolved 'net/mac80211/debugfs_sta.c' using previous resolution.
+Resolved 'net/mac80211/sta_info.h' using previous resolution.
+Auto-merging net/mac80211/sta_info.h
+CONFLICT (content): Merge conflict in net/mac80211/sta_info.h
+Auto-merging net/mac80211/rate.h
+Auto-merging net/mac80211/rate.c
+Auto-merging net/mac80211/iface.c
+Auto-merging net/mac80211/debugfs_sta.c
+CONFLICT (content): Merge conflict in net/mac80211/debugfs_sta.c
+Auto-merging net/core/neighbour.c
+Auto-merging net/batman-adv/bat_algo.h
+Auto-merging drivers/net/wireless/mwifiex/cfg80211.c
+Auto-merging drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+Auto-merging drivers/net/vmxnet3/vmxnet3_drv.c
+Auto-merging drivers/net/ethernet/smsc/smc91x.c
+Removing drivers/net/ethernet/sfc/mac.h
+Auto-merging drivers/net/ethernet/micrel/ks8851_mll.c
+Auto-merging drivers/net/ethernet/mellanox/mlx4/mlx4.h
+Auto-merging drivers/net/ethernet/mellanox/mlx4/main.c
+Auto-merging drivers/net/ethernet/intel/e1000e/mac.c
+Auto-merging drivers/net/ethernet/broadcom/b44.c
+Auto-merging drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+Auto-merging drivers/net/can/sja1000/sja1000.c
+Auto-merging arch/blackfin/mach-bf537/boards/stamp.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master a1b7d03] Merge remote-tracking branch 'net-next/master'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/ABI/testing/sysfs-class-net-mesh     |    7 +
+ Documentation/magic-number.txt                     |    2 +-
+ Documentation/networking/LICENSE.qlge              |  328 +-
+ Documentation/networking/phy.txt                   |    3 +-
+ Documentation/zh_CN/magic-number.txt               |    2 +-
+ MAINTAINERS                                        |   12 +-
+ arch/alpha/include/asm/socket.h                    |    1 +
+ arch/arm/include/asm/socket.h                      |    1 +
+ arch/avr32/include/asm/socket.h                    |    1 +
+ arch/blackfin/mach-bf518/boards/ezbrd.c            |    3 +-
+ arch/blackfin/mach-bf518/boards/tcm-bf518.c        |    5 +-
+ arch/blackfin/mach-bf527/boards/ad7160eval.c       |    3 +-
+ arch/blackfin/mach-bf527/boards/cm_bf527.c         |    5 +-
+ arch/blackfin/mach-bf527/boards/ezbrd.c            |    3 +-
+ arch/blackfin/mach-bf527/boards/ezkit.c            |    3 +-
+ arch/blackfin/mach-bf527/boards/tll6527m.c         |    3 +-
+ arch/blackfin/mach-bf537/boards/cm_bf537e.c        |    5 +-
+ arch/blackfin/mach-bf537/boards/cm_bf537u.c        |    5 +-
+ arch/blackfin/mach-bf537/boards/dnp5370.c          |    3 +-
+ arch/blackfin/mach-bf537/boards/pnav10.c           |    5 +-
+ arch/blackfin/mach-bf537/boards/stamp.c            |    3 +-
+ arch/blackfin/mach-bf537/boards/tcm_bf537.c        |    5 +-
+ arch/cris/include/asm/socket.h                     |    1 +
+ arch/frv/include/asm/socket.h                      |    1 +
+ arch/h8300/include/asm/socket.h                    |    1 +
+ arch/ia64/include/asm/socket.h                     |    1 +
+ arch/m32r/include/asm/socket.h                     |    1 +
+ arch/m68k/include/asm/socket.h                     |    1 +
+ arch/mips/include/asm/socket.h                     |    1 +
+ arch/mn10300/include/asm/socket.h                  |    1 +
+ arch/parisc/include/asm/socket.h                   |    1 +
+ arch/powerpc/include/asm/socket.h                  |    1 +
+ arch/s390/include/asm/qeth.h                       |    7 +
+ arch/s390/include/asm/socket.h                     |    1 +
+ arch/sparc/include/asm/socket.h                    |    1 +
+ arch/um/drivers/net_kern.c                         |   11 +-
+ arch/xtensa/include/asm/socket.h                   |    1 +
+ drivers/atm/lanai.c                                |    2 +-
+ drivers/bcma/sprom.c                               |  180 +-
+ drivers/infiniband/core/addr.c                     |   14 +-
+ drivers/infiniband/hw/cxgb4/cm.c                   |   10 +-
+ drivers/infiniband/hw/nes/nes_cm.c                 |    8 +-
+ drivers/isdn/act2000/act2000.h                     |   28 +-
+ drivers/isdn/act2000/act2000_isa.c                 |  394 +-
+ drivers/isdn/act2000/act2000_isa.h                 |   32 +-
+ drivers/isdn/act2000/capi.c                        |  998 +-
+ drivers/isdn/act2000/capi.h                        |   50 +-
+ drivers/isdn/act2000/module.c                      |  806 +-
+ drivers/isdn/capi/capi.c                           |  178 +-
+ drivers/isdn/capi/capidrv.c                        |  956 +-
+ drivers/isdn/capi/capidrv.h                        |   42 +-
+ drivers/isdn/capi/capilib.c                        |   16 +-
+ drivers/isdn/capi/capiutil.c                       |  628 +-
+ drivers/isdn/capi/kcapi.c                          |  116 +-
+ drivers/isdn/capi/kcapi.h                          |   11 +-
+ drivers/isdn/capi/kcapi_proc.c                     |   14 +-
+ drivers/isdn/divert/divert_init.c                  |   75 +-
+ drivers/isdn/divert/divert_procfs.c                |  152 +-
+ drivers/isdn/divert/isdn_divert.c                  | 1475 +-
+ drivers/isdn/divert/isdn_divert.h                  |  116 +-
+ drivers/isdn/gigaset/asyncdata.c                   |    4 +-
+ drivers/isdn/gigaset/bas-gigaset.c                 |   42 +-
+ drivers/isdn/gigaset/capi.c                        |  228 +-
+ drivers/isdn/gigaset/common.c                      |   14 +-
+ drivers/isdn/gigaset/ev-layer.c                    |  328 +-
+ drivers/isdn/gigaset/gigaset.h                     |   30 +-
+ drivers/isdn/gigaset/i4l.c                         |    8 +-
+ drivers/isdn/gigaset/interface.c                   |   20 +-
+ drivers/isdn/gigaset/isocdata.c                    |  192 +-
+ drivers/isdn/gigaset/proc.c                        |    4 +-
+ drivers/isdn/gigaset/ser-gigaset.c                 |    6 +-
+ drivers/isdn/gigaset/usb-gigaset.c                 |    8 +-
+ drivers/isdn/hardware/avm/avm_cs.c                 |  134 +-
+ drivers/isdn/hardware/avm/avmcard.h                |  286 +-
+ drivers/isdn/hardware/avm/b1.c                     |  192 +-
+ drivers/isdn/hardware/avm/b1dma.c                  |  178 +-
+ drivers/isdn/hardware/avm/b1isa.c                  |   18 +-
+ drivers/isdn/hardware/avm/b1pci.c                  |   44 +-
+ drivers/isdn/hardware/avm/b1pcmcia.c               |   28 +-
+ drivers/isdn/hardware/avm/c4.c                     |  348 +-
+ drivers/isdn/hardware/avm/t1isa.c                  |  100 +-
+ drivers/isdn/hardware/avm/t1pci.c                  |   32 +-
+ drivers/isdn/hardware/eicon/capi20.h               |  514 +-
+ drivers/isdn/hardware/eicon/capidtmf.c             | 1094 +-
+ drivers/isdn/hardware/eicon/capidtmf.h             |   78 +-
+ drivers/isdn/hardware/eicon/capifunc.c             |  222 +-
+ drivers/isdn/hardware/eicon/capifunc.h             |    4 +-
+ drivers/isdn/hardware/eicon/capimain.c             |   10 +-
+ drivers/isdn/hardware/eicon/cardtype.h             | 1476 +-
+ drivers/isdn/hardware/eicon/cp_vers.h              |   32 +-
+ drivers/isdn/hardware/eicon/dadapter.c             |  576 +-
+ drivers/isdn/hardware/eicon/dadapter.h             |   36 +-
+ drivers/isdn/hardware/eicon/debug.c                | 3519 ++--
+ drivers/isdn/hardware/eicon/debug_if.h             |   82 +-
+ drivers/isdn/hardware/eicon/debuglib.c             |  176 +-
+ drivers/isdn/hardware/eicon/debuglib.h             |  272 +-
+ drivers/isdn/hardware/eicon/dfifo.h                |   56 +-
+ drivers/isdn/hardware/eicon/di.c                   | 1430 +-
+ drivers/isdn/hardware/eicon/di.h                   |  156 +-
+ drivers/isdn/hardware/eicon/di_dbg.h               |   34 +-
+ drivers/isdn/hardware/eicon/di_defs.h              |  144 +-
+ drivers/isdn/hardware/eicon/did_vers.h             |   32 +-
+ drivers/isdn/hardware/eicon/diddfunc.c             |   22 +-
+ drivers/isdn/hardware/eicon/diva.c                 |  160 +-
+ drivers/isdn/hardware/eicon/diva_didd.c            |   16 +-
+ drivers/isdn/hardware/eicon/diva_dma.c             |  116 +-
+ drivers/isdn/hardware/eicon/diva_dma.h             |   62 +-
+ drivers/isdn/hardware/eicon/diva_pci.h             |    6 +-
+ drivers/isdn/hardware/eicon/divacapi.h             |  630 +-
+ drivers/isdn/hardware/eicon/divamnt.c              |   15 +-
+ drivers/isdn/hardware/eicon/divasfunc.c            |   34 +-
+ drivers/isdn/hardware/eicon/divasi.c               |   56 +-
+ drivers/isdn/hardware/eicon/divasmain.c            |  118 +-
+ drivers/isdn/hardware/eicon/divasproc.c            |   58 +-
+ drivers/isdn/hardware/eicon/divasync.h             |  562 +-
+ drivers/isdn/hardware/eicon/dqueue.c               |   14 +-
+ drivers/isdn/hardware/eicon/dqueue.h               |   14 +-
+ drivers/isdn/hardware/eicon/dsp_defs.h             |  256 +-
+ drivers/isdn/hardware/eicon/dsp_tst.h              |    8 +-
+ drivers/isdn/hardware/eicon/dspdids.h              |   30 +-
+ drivers/isdn/hardware/eicon/dsrv4bri.h             |   34 +-
+ drivers/isdn/hardware/eicon/dsrv_bri.h             |   44 +-
+ drivers/isdn/hardware/eicon/dsrv_pri.h             |   46 +-
+ drivers/isdn/hardware/eicon/entity.h               |   14 +-
+ drivers/isdn/hardware/eicon/helpers.h              |   68 +-
+ drivers/isdn/hardware/eicon/idifunc.c              |   22 +-
+ drivers/isdn/hardware/eicon/io.c                   | 1414 +-
+ drivers/isdn/hardware/eicon/io.h                   |  514 +-
+ drivers/isdn/hardware/eicon/istream.c              |  352 +-
+ drivers/isdn/hardware/eicon/kst_ifc.h              |  227 +-
+ drivers/isdn/hardware/eicon/maintidi.c             | 2277 +-
+ drivers/isdn/hardware/eicon/maintidi.h             |  105 +-
+ drivers/isdn/hardware/eicon/man_defs.h             |   36 +-
+ drivers/isdn/hardware/eicon/mdm_msg.h              |   72 +-
+ drivers/isdn/hardware/eicon/message.c              |28300 ++++++++++----------
+ drivers/isdn/hardware/eicon/mi_pc.h                |   86 +-
+ drivers/isdn/hardware/eicon/mntfunc.c              |  186 +-
+ drivers/isdn/hardware/eicon/os_4bri.c              |  352 +-
+ drivers/isdn/hardware/eicon/os_4bri.h              |    2 +-
+ drivers/isdn/hardware/eicon/os_bri.c               |  262 +-
+ drivers/isdn/hardware/eicon/os_bri.h               |    2 +-
+ drivers/isdn/hardware/eicon/os_capi.h              |   10 +-
+ drivers/isdn/hardware/eicon/os_pri.c               |  390 +-
+ drivers/isdn/hardware/eicon/os_pri.h               |    2 +-
+ drivers/isdn/hardware/eicon/pc.h                   |  268 +-
+ drivers/isdn/hardware/eicon/pc_init.h              |   48 +-
+ drivers/isdn/hardware/eicon/pc_maint.h             |  158 +-
+ drivers/isdn/hardware/eicon/pkmaint.h              |   43 +-
+ drivers/isdn/hardware/eicon/platform.h             |  156 +-
+ drivers/isdn/hardware/eicon/pr_pc.h                |  116 +-
+ drivers/isdn/hardware/eicon/s_4bri.c               |  488 +-
+ drivers/isdn/hardware/eicon/s_bri.c                |  288 +-
+ drivers/isdn/hardware/eicon/s_pri.c                |  314 +-
+ drivers/isdn/hardware/eicon/sdp_hdr.h              |  130 +-
+ drivers/isdn/hardware/eicon/um_idi.c               |  224 +-
+ drivers/isdn/hardware/eicon/um_idi.h               |    2 +-
+ drivers/isdn/hardware/eicon/xdi_adapter.h          |   12 +-
+ drivers/isdn/hardware/eicon/xdi_msg.h              |    2 +-
+ drivers/isdn/hardware/eicon/xdi_vers.h             |   32 +-
+ drivers/isdn/hardware/mISDN/avmfritz.c             |   68 +-
+ drivers/isdn/hardware/mISDN/hfc_multi.h            |   47 +-
+ drivers/isdn/hardware/mISDN/hfc_multi_8xx.h        |   28 +-
+ drivers/isdn/hardware/mISDN/hfc_pci.h              |   18 +-
+ drivers/isdn/hardware/mISDN/hfcmulti.c             | 1364 +-
+ drivers/isdn/hardware/mISDN/hfcpci.c               |  356 +-
+ drivers/isdn/hardware/mISDN/hfcsusb.c              |  415 +-
+ drivers/isdn/hardware/mISDN/hfcsusb.h              |  120 +-
+ drivers/isdn/hardware/mISDN/iohelper.h             |  136 +-
+ drivers/isdn/hardware/mISDN/isar.h                 |    2 +-
+ drivers/isdn/hardware/mISDN/mISDNinfineon.c        |   36 +-
+ drivers/isdn/hardware/mISDN/mISDNipac.c            |  112 +-
+ drivers/isdn/hardware/mISDN/mISDNisar.c            |  208 +-
+ drivers/isdn/hardware/mISDN/netjet.c               |   98 +-
+ drivers/isdn/hardware/mISDN/netjet.h               |    1 -
+ drivers/isdn/hardware/mISDN/speedfax.c             |   22 +-
+ drivers/isdn/hardware/mISDN/w6692.c                |   86 +-
+ drivers/isdn/hisax/amd7930_fn.c                    |  786 +-
+ drivers/isdn/hisax/arcofi.c                        |   88 +-
+ drivers/isdn/hisax/arcofi.h                        |    2 +-
+ drivers/isdn/hisax/asuscom.c                       |  110 +-
+ drivers/isdn/hisax/avm_a1.c                        |   42 +-
+ drivers/isdn/hisax/avm_a1p.c                       |  152 +-
+ drivers/isdn/hisax/avm_pci.c                       |  324 +-
+ drivers/isdn/hisax/avma1_cs.c                      |  124 +-
+ drivers/isdn/hisax/bkm_a4t.c                       |   92 +-
+ drivers/isdn/hisax/bkm_a8.c                        |  184 +-
+ drivers/isdn/hisax/bkm_ax.h                        |   78 +-
+ drivers/isdn/hisax/callc.c                         | 1074 +-
+ drivers/isdn/hisax/config.c                        |  126 +-
+ drivers/isdn/hisax/diva.c                          |  334 +-
+ drivers/isdn/hisax/elsa.c                          |  500 +-
+ drivers/isdn/hisax/elsa_cs.c                       |  164 +-
+ drivers/isdn/hisax/elsa_ser.c                      |  178 +-
+ drivers/isdn/hisax/enternow_pci.c                  |  200 +-
+ drivers/isdn/hisax/fsm.c                           |   38 +-
+ drivers/isdn/hisax/fsm.h                           |    4 +-
+ drivers/isdn/hisax/gazel.c                         |  518 +-
+ drivers/isdn/hisax/hfc4s8s_l1.c                    |  648 +-
+ drivers/isdn/hisax/hfc4s8s_l1.h                    |    8 +-
+ drivers/isdn/hisax/hfc_2bds0.c                     |  484 +-
+ drivers/isdn/hisax/hfc_2bds0.h                     |   28 +-
+ drivers/isdn/hisax/hfc_2bs0.c                      |  284 +-
+ drivers/isdn/hisax/hfc_2bs0.h                      |    6 +-
+ drivers/isdn/hisax/hfc_pci.c                       |  714 +-
+ drivers/isdn/hisax/hfc_pci.h                       |   96 +-
+ drivers/isdn/hisax/hfc_sx.c                        | 1126 +-
+ drivers/isdn/hisax/hfc_sx.h                        |   30 +-
+ drivers/isdn/hisax/hfc_usb.c                       |  586 +-
+ drivers/isdn/hisax/hfc_usb.h                       |   10 +-
+ drivers/isdn/hisax/hfcscard.c                      |   96 +-
+ drivers/isdn/hisax/hisax.h                         |  172 +-
+ drivers/isdn/hisax/hisax_cfg.h                     |    6 +-
+ drivers/isdn/hisax/hisax_debug.h                   |   42 +-
+ drivers/isdn/hisax/hisax_fcpcipnp.c                |   92 +-
+ drivers/isdn/hisax/hisax_fcpcipnp.h                |    3 +-
+ drivers/isdn/hisax/hisax_if.h                      |    4 +-
+ drivers/isdn/hisax/hisax_isac.c                    |   44 +-
+ drivers/isdn/hisax/hscx.c                          |  136 +-
+ drivers/isdn/hisax/hscx.h                          |    2 +-
+ drivers/isdn/hisax/hscx_irq.c                      |   18 +-
+ drivers/isdn/hisax/icc.c                           |  314 +-
+ drivers/isdn/hisax/icc.h                           |    6 +-
+ drivers/isdn/hisax/ipac.h                          |    2 +-
+ drivers/isdn/hisax/ipacx.c                         |  675 +-
+ drivers/isdn/hisax/isac.c                          |  320 +-
+ drivers/isdn/hisax/isac.h                          |    2 +-
+ drivers/isdn/hisax/isar.c                          | 1796 +-
+ drivers/isdn/hisax/isar.h                          |   14 +-
+ drivers/isdn/hisax/isdnl1.c                        |  262 +-
+ drivers/isdn/hisax/isdnl2.c                        |  342 +-
+ drivers/isdn/hisax/isdnl2.h                        |    1 -
+ drivers/isdn/hisax/isdnl3.c                        |  174 +-
+ drivers/isdn/hisax/isdnl3.h                        |    3 +-
+ drivers/isdn/hisax/isurf.c                         |  118 +-
+ drivers/isdn/hisax/ix1_micro.c                     |  100 +-
+ drivers/isdn/hisax/jade.c                          |  209 +-
+ drivers/isdn/hisax/jade.h                          |  156 +-
+ drivers/isdn/hisax/jade_irq.c                      |   48 +-
+ drivers/isdn/hisax/l3_1tr6.c                       |  196 +-
+ drivers/isdn/hisax/l3dss1.c                        | 1900 +-
+ drivers/isdn/hisax/l3dss1.h                        |   20 +-
+ drivers/isdn/hisax/l3ni1.c                         | 1838 +-
+ drivers/isdn/hisax/l3ni1.h                         |   28 +-
+ drivers/isdn/hisax/lmgr.c                          |   28 +-
+ drivers/isdn/hisax/mic.c                           |   64 +-
+ drivers/isdn/hisax/netjet.c                        |  623 +-
+ drivers/isdn/hisax/netjet.h                        |    5 +-
+ drivers/isdn/hisax/niccy.c                         |   78 +-
+ drivers/isdn/hisax/nj_s.c                          |  112 +-
+ drivers/isdn/hisax/nj_u.c                          |  100 +-
+ drivers/isdn/hisax/q931.c                          |  240 +-
+ drivers/isdn/hisax/s0box.c                         |  132 +-
+ drivers/isdn/hisax/saphir.c                        |  122 +-
+ drivers/isdn/hisax/sedlbauer.c                     |  328 +-
+ drivers/isdn/hisax/sedlbauer_cs.c                  |  176 +-
+ drivers/isdn/hisax/sportster.c                     |  126 +-
+ drivers/isdn/hisax/st5481.h                        |   98 +-
+ drivers/isdn/hisax/st5481_b.c                      |  124 +-
+ drivers/isdn/hisax/st5481_d.c                      |  194 +-
+ drivers/isdn/hisax/st5481_init.c                   |   64 +-
+ drivers/isdn/hisax/st5481_usb.c                    |  269 +-
+ drivers/isdn/hisax/tei.c                           |   76 +-
+ drivers/isdn/hisax/teleint.c                       |  126 +-
+ drivers/isdn/hisax/teles0.c                        |  126 +-
+ drivers/isdn/hisax/teles3.c                        |  156 +-
+ drivers/isdn/hisax/teles_cs.c                      |  134 +-
+ drivers/isdn/hisax/telespci.c                      |   80 +-
+ drivers/isdn/hisax/w6692.c                         |  412 +-
+ drivers/isdn/hisax/w6692.h                         |   10 +-
+ drivers/isdn/hysdn/boardergo.c                     |   28 +-
+ drivers/isdn/hysdn/boardergo.h                     |   30 +-
+ drivers/isdn/hysdn/hycapi.c                        |  374 +-
+ drivers/isdn/hysdn/hysdn_boot.c                    |  302 +-
+ drivers/isdn/hysdn/hysdn_defs.h                    |   30 +-
+ drivers/isdn/hysdn/hysdn_init.c                    |    4 +-
+ drivers/isdn/hysdn/hysdn_net.c                     |   20 +-
+ drivers/isdn/hysdn/hysdn_pof.h                     |   26 +-
+ drivers/isdn/hysdn/hysdn_procconf.c                |   10 +-
+ drivers/isdn/hysdn/hysdn_proclog.c                 |   26 +-
+ drivers/isdn/hysdn/hysdn_sched.c                   |   54 +-
+ drivers/isdn/hysdn/ince1pc.h                       |   72 +-
+ drivers/isdn/i4l/isdn_audio.c                      |  126 +-
+ drivers/isdn/i4l/isdn_bsdcomp.c                    |  374 +-
+ drivers/isdn/i4l/isdn_common.c                     | 1502 +-
+ drivers/isdn/i4l/isdn_common.h                     |   18 +-
+ drivers/isdn/i4l/isdn_concap.c                     |   36 +-
+ drivers/isdn/i4l/isdn_concap.h                     |    4 +-
+ drivers/isdn/i4l/isdn_net.c                        | 1498 +-
+ drivers/isdn/i4l/isdn_net.h                        |   11 +-
+ drivers/isdn/i4l/isdn_ppp.c                        | 1446 +-
+ drivers/isdn/i4l/isdn_ppp.h                        |    2 -
+ drivers/isdn/i4l/isdn_tty.c                        | 2442 +-
+ drivers/isdn/i4l/isdn_tty.h                        |   10 +-
+ drivers/isdn/i4l/isdn_ttyfax.c                     | 1092 +-
+ drivers/isdn/i4l/isdn_ttyfax.h                     |    1 -
+ drivers/isdn/i4l/isdn_v110.c                       |  294 +-
+ drivers/isdn/i4l/isdn_v110.h                       |    8 +-
+ drivers/isdn/i4l/isdn_x25iface.c                   |  226 +-
+ drivers/isdn/i4l/isdn_x25iface.h                   |   16 +-
+ drivers/isdn/i4l/isdnhdlc.c                        |   54 +-
+ drivers/isdn/icn/icn.c                             |  806 +-
+ drivers/isdn/icn/icn.h                             |   32 +-
+ drivers/isdn/isdnloop/isdnloop.c                   |  958 +-
+ drivers/isdn/isdnloop/isdnloop.h                   |    6 +-
+ drivers/isdn/mISDN/clock.c                         |   25 +-
+ drivers/isdn/mISDN/core.c                          |   37 +-
+ drivers/isdn/mISDN/core.h                          |    8 +-
+ drivers/isdn/mISDN/dsp.h                           |   25 +-
+ drivers/isdn/mISDN/dsp_audio.c                     |    5 +-
+ drivers/isdn/mISDN/dsp_biquad.h                    |    6 +-
+ drivers/isdn/mISDN/dsp_blowfish.c                  |  112 +-
+ drivers/isdn/mISDN/dsp_cmx.c                       | 1040 +-
+ drivers/isdn/mISDN/dsp_core.c                      |  183 +-
+ drivers/isdn/mISDN/dsp_dtmf.c                      |   66 +-
+ drivers/isdn/mISDN/dsp_ecdis.h                     |   26 +-
+ drivers/isdn/mISDN/dsp_hwec.c                      |   11 +-
+ drivers/isdn/mISDN/dsp_hwec.h                      |    1 -
+ drivers/isdn/mISDN/dsp_pipeline.c                  |   56 +-
+ drivers/isdn/mISDN/dsp_tones.c                     |  165 +-
+ drivers/isdn/mISDN/fsm.c                           |   42 +-
+ drivers/isdn/mISDN/hwchannel.c                     |   22 +-
+ drivers/isdn/mISDN/l1oip.h                         |   21 +-
+ drivers/isdn/mISDN/l1oip_codec.c                   |   36 +-
+ drivers/isdn/mISDN/l1oip_core.c                    |  597 +-
+ drivers/isdn/mISDN/layer1.c                        |   16 +-
+ drivers/isdn/mISDN/layer1.h                        |    1 -
+ drivers/isdn/mISDN/layer2.c                        |   97 +-
+ drivers/isdn/mISDN/layer2.h                        |   12 +-
+ drivers/isdn/mISDN/socket.c                        |   89 +-
+ drivers/isdn/mISDN/stack.c                         |  124 +-
+ drivers/isdn/mISDN/tei.c                           |  114 +-
+ drivers/isdn/mISDN/timerdev.c                      |   12 +-
+ drivers/isdn/pcbit/callbacks.c                     |  303 +-
+ drivers/isdn/pcbit/callbacks.h                     |   28 +-
+ drivers/isdn/pcbit/capi.c                          |  585 +-
+ drivers/isdn/pcbit/capi.h                          |   46 +-
+ drivers/isdn/pcbit/drv.c                           |  248 +-
+ drivers/isdn/pcbit/edss1.c                         |  414 +-
+ drivers/isdn/pcbit/edss1.h                         |   13 +-
+ drivers/isdn/pcbit/layer2.c                        |   36 +-
+ drivers/isdn/pcbit/layer2.h                        |  265 +-
+ drivers/isdn/pcbit/module.c                        |   35 +-
+ drivers/isdn/pcbit/pcbit.h                         |   32 +-
+ drivers/isdn/sc/card.h                             |    2 +-
+ drivers/isdn/sc/command.c                          |  132 +-
+ drivers/isdn/sc/event.c                            |   24 +-
+ drivers/isdn/sc/hardware.h                         |    2 +-
+ drivers/isdn/sc/init.c                             |  122 +-
+ drivers/isdn/sc/interrupt.c                        |  144 +-
+ drivers/isdn/sc/ioctl.c                            |  220 +-
+ drivers/isdn/sc/message.c                          |  126 +-
+ drivers/isdn/sc/message.h                          |   18 +-
+ drivers/isdn/sc/packet.c                           |  129 +-
+ drivers/isdn/sc/scioc.h                            |    5 +-
+ drivers/isdn/sc/shmem.c                            |   52 +-
+ drivers/isdn/sc/timer.c                            |   25 +-
+ drivers/net/bonding/bond_3ad.c                     |    2 +-
+ drivers/net/bonding/bond_alb.c                     |   12 +-
+ drivers/net/caif/caif_hsi.c                        |  145 +-
+ drivers/net/can/Kconfig                            |    6 +-
+ drivers/net/can/bfin_can.c                         |   36 +-
+ drivers/net/can/dev.c                              |   33 +-
+ drivers/net/can/flexcan.c                          |   61 +-
+ drivers/net/can/mcp251x.c                          |    3 +-
+ drivers/net/can/mscan/mscan.c                      |   33 +-
+ drivers/net/can/pch_can.c                          |    2 +-
+ drivers/net/can/sja1000/Kconfig                    |    1 +
+ drivers/net/can/sja1000/plx_pci.c                  |   22 +-
+ drivers/net/can/sja1000/sja1000.c                  |   19 +-
+ drivers/net/can/slcan.c                            |    6 +-
+ drivers/net/can/ti_hecc.c                          |   32 +-
+ drivers/net/can/usb/ems_usb.c                      |   63 +-
+ drivers/net/can/usb/esd_usb2.c                     |   27 +-
+ drivers/net/dummy.c                                |    3 +-
+ drivers/net/ethernet/3com/3c501.c                  |    2 +-
+ drivers/net/ethernet/3com/3c509.c                  |    2 +-
+ drivers/net/ethernet/3com/3c515.c                  |   10 +-
+ drivers/net/ethernet/3com/3c574_cs.c               |    2 +-
+ drivers/net/ethernet/3com/3c589_cs.c               |    2 +-
+ drivers/net/ethernet/3com/3c59x.c                  |   10 +-
+ drivers/net/ethernet/3com/Kconfig                  |    2 +-
+ drivers/net/ethernet/3com/typhoon.c                |    5 +-
+ drivers/net/ethernet/8390/ax88796.c                |    2 +-
+ drivers/net/ethernet/8390/axnet_cs.c               |    4 +-
+ drivers/net/ethernet/8390/lib8390.c                |    2 +-
+ drivers/net/ethernet/8390/pcnet_cs.c               |    2 +-
+ drivers/net/ethernet/adaptec/starfire.c            |   13 +-
+ drivers/net/ethernet/adi/bfin_mac.c                |   27 +-
+ drivers/net/ethernet/adi/bfin_mac.h                |    2 +-
+ drivers/net/ethernet/aeroflex/greth.c              |    3 +-
+ drivers/net/ethernet/alteon/acenic.c               |    5 +-
+ drivers/net/ethernet/amd/7990.c                    |    2 +-
+ drivers/net/ethernet/amd/Kconfig                   |    2 +-
+ drivers/net/ethernet/amd/a2065.c                   |    2 +-
+ drivers/net/ethernet/amd/am79c961a.c               |    4 +-
+ drivers/net/ethernet/amd/am79c961a.h               |    2 +-
+ drivers/net/ethernet/amd/amd8111e.c                |    7 +-
+ drivers/net/ethernet/amd/ariadne.c                 |    2 +-
+ drivers/net/ethernet/amd/atarilance.c              |    2 +-
+ drivers/net/ethernet/amd/au1000_eth.c              |   12 +-
+ drivers/net/ethernet/amd/declance.c                |    4 +-
+ drivers/net/ethernet/amd/depca.c                   |    2 +-
+ drivers/net/ethernet/amd/ni65.c                    |    6 +-
+ drivers/net/ethernet/amd/nmclan_cs.c               |    2 +-
+ drivers/net/ethernet/amd/pcnet32.c                 |   16 +-
+ drivers/net/ethernet/amd/sun3lance.c               |    2 +-
+ drivers/net/ethernet/amd/sunlance.c                |    4 +-
+ drivers/net/ethernet/apple/bmac.c                  |   19 +-
+ drivers/net/ethernet/apple/mace.c                  |    9 +-
+ drivers/net/ethernet/apple/macmace.c               |    2 +-
+ drivers/net/ethernet/atheros/atl1c/atl1c_hw.c      |    2 +-
+ drivers/net/ethernet/atheros/atl1c/atl1c_main.c    |   12 +-
+ drivers/net/ethernet/atheros/atl1e/atl1e_main.c    |    1 -
+ drivers/net/ethernet/atheros/atlx/atl1.c           |   12 +-
+ drivers/net/ethernet/atheros/atlx/atlx.c           |    1 +
+ drivers/net/ethernet/broadcom/b44.c                |    1 -
+ drivers/net/ethernet/broadcom/bnx2.c               |  106 +-
+ drivers/net/ethernet/broadcom/bnx2.h               |    3 +
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x.h        |   33 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c    |  261 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h    |  122 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c    |    2 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h    |    2 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h   |    2 +-
+ .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c    |  100 +-
+ .../net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h    |    2 +-
+ .../ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h    |    2 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h    |   59 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h   |    2 +-
+ .../net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h   |   55 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c   |  324 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h   |    6 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c   |  365 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h    |   21 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c     |    6 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h     |    7 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c  |  342 +-
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h  |  154 +-
+ drivers/net/ethernet/broadcom/cnic.c               |   42 +-
+ drivers/net/ethernet/broadcom/cnic_defs.h          |   27 +-
+ drivers/net/ethernet/broadcom/cnic_if.h            |    4 +-
+ drivers/net/ethernet/broadcom/sb1250-mac.c         |    2 -
+ drivers/net/ethernet/broadcom/tg3.c                | 9055 ++++----
+ drivers/net/ethernet/broadcom/tg3.h                |   13 +-
+ drivers/net/ethernet/brocade/bna/bfa_cee.c         |    8 +-
+ drivers/net/ethernet/brocade/bna/bfa_defs.h        |    1 +
+ drivers/net/ethernet/brocade/bna/bfa_ioc.c         |    2 +-
+ drivers/net/ethernet/brocade/bna/bnad.c            |    1 -
+ drivers/net/ethernet/brocade/bna/bnad_debugfs.c    |   21 +-
+ drivers/net/ethernet/brocade/bna/bnad_ethtool.c    |   42 +
+ drivers/net/ethernet/cadence/at91_ether.c          |    2 +-
+ drivers/net/ethernet/cadence/macb.c                |    8 +-
+ drivers/net/ethernet/calxeda/xgmac.c               |    3 +-
+ drivers/net/ethernet/chelsio/cxgb3/version.h       |    4 +-
+ .../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c    |    2 -
+ drivers/net/ethernet/cirrus/cs89x0.c               |    4 +-
+ drivers/net/ethernet/cirrus/ep93xx_eth.c           |    4 +-
+ drivers/net/ethernet/cisco/enic/enic.h             |    4 +-
+ drivers/net/ethernet/cisco/enic/enic_main.c        |   50 +-
+ drivers/net/ethernet/cisco/enic/enic_pp.c          |    4 +-
+ drivers/net/ethernet/cisco/enic/enic_res.c         |    2 +-
+ drivers/net/ethernet/cisco/enic/vnic_dev.c         |   76 +-
+ drivers/net/ethernet/cisco/enic/vnic_dev.h         |    3 +-
+ drivers/net/ethernet/cisco/enic/vnic_devcmd.h      |   11 +-
+ drivers/net/ethernet/cisco/enic/vnic_rq.c          |    4 +-
+ drivers/net/ethernet/cisco/enic/vnic_wq.c          |    4 +-
+ drivers/net/ethernet/davicom/dm9000.c              |    8 +-
+ drivers/net/ethernet/dec/ewrk3.c                   |    4 +-
+ drivers/net/ethernet/dec/tulip/21142.c             |    2 +-
+ drivers/net/ethernet/dec/tulip/de2104x.c           |    6 +-
+ drivers/net/ethernet/dec/tulip/de4x5.c             |    4 +-
+ drivers/net/ethernet/dec/tulip/dmfe.c              |   20 +-
+ drivers/net/ethernet/dec/tulip/eeprom.c            |    2 +-
+ drivers/net/ethernet/dec/tulip/interrupt.c         |   10 +-
+ drivers/net/ethernet/dec/tulip/media.c             |    2 +-
+ drivers/net/ethernet/dec/tulip/pnic.c              |    2 +-
+ drivers/net/ethernet/dec/tulip/pnic2.c             |    2 +-
+ drivers/net/ethernet/dec/tulip/timer.c             |    2 +-
+ drivers/net/ethernet/dec/tulip/tulip.h             |    2 +-
+ drivers/net/ethernet/dec/tulip/tulip_core.c        |    9 +-
+ drivers/net/ethernet/dec/tulip/uli526x.c           |   21 +-
+ drivers/net/ethernet/dec/tulip/winbond-840.c       |    6 +-
+ drivers/net/ethernet/dec/tulip/xircom_cb.c         |    7 +-
+ drivers/net/ethernet/dlink/de600.c                 |    2 +-
+ drivers/net/ethernet/dlink/de620.c                 |    2 +-
+ drivers/net/ethernet/dlink/sundance.c              |    9 +-
+ drivers/net/ethernet/dnet.c                        |    8 +-
+ drivers/net/ethernet/emulex/benet/be.h             |   71 +-
+ drivers/net/ethernet/emulex/benet/be_cmds.c        |  104 +-
+ drivers/net/ethernet/emulex/benet/be_cmds.h        |   54 +-
+ drivers/net/ethernet/emulex/benet/be_ethtool.c     |  160 +-
+ drivers/net/ethernet/emulex/benet/be_main.c        |  858 +-
+ drivers/net/ethernet/ethoc.c                       |   23 +-
+ drivers/net/ethernet/faraday/ftgmac100.c           |    2 +-
+ drivers/net/ethernet/faraday/ftmac100.c            |    2 +-
+ drivers/net/ethernet/fealnx.c                      |    8 +-
+ drivers/net/ethernet/freescale/fec.c               |   21 +-
+ drivers/net/ethernet/freescale/fec_mpc52xx.c       |    4 +-
+ drivers/net/ethernet/freescale/fec_mpc52xx.h       |    2 +-
+ .../net/ethernet/freescale/fs_enet/fs_enet-main.c  |   12 +-
+ drivers/net/ethernet/freescale/gianfar.c           |    2 +-
+ drivers/net/ethernet/freescale/gianfar.h           |    2 +-
+ drivers/net/ethernet/freescale/gianfar_ethtool.c   |    2 +-
+ drivers/net/ethernet/freescale/gianfar_sysfs.c     |    2 +-
+ drivers/net/ethernet/freescale/ucc_geth.c          |    7 +-
+ drivers/net/ethernet/fujitsu/at1700.c              |    2 +-
+ drivers/net/ethernet/fujitsu/eth16i.c              |    2 +-
+ drivers/net/ethernet/fujitsu/fmvj18x_cs.c          |    2 +-
+ drivers/net/ethernet/hp/hp100.c                    |    6 +-
+ drivers/net/ethernet/i825xx/3c505.c                |    2 +-
+ drivers/net/ethernet/i825xx/3c507.c                |    2 +-
+ drivers/net/ethernet/i825xx/3c523.c                |    2 +-
+ drivers/net/ethernet/i825xx/3c527.c                |    4 +-
+ drivers/net/ethernet/i825xx/82596.c                |    8 +-
+ drivers/net/ethernet/i825xx/eepro.c                |    2 +-
+ drivers/net/ethernet/i825xx/eexpress.c             |    2 +-
+ drivers/net/ethernet/i825xx/ether1.c               |    2 +-
+ drivers/net/ethernet/i825xx/lp486e.c               |    4 +-
+ drivers/net/ethernet/i825xx/ni52.c                 |    2 +-
+ drivers/net/ethernet/i825xx/sun3_82586.c           |   27 +-
+ drivers/net/ethernet/i825xx/znet.c                 |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea.h               |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea_ethtool.c       |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea_hw.h            |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea_main.c          |    3 +-
+ drivers/net/ethernet/ibm/ehea/ehea_phyp.c          |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea_phyp.h          |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea_qmr.c           |    2 +-
+ drivers/net/ethernet/ibm/ehea/ehea_qmr.h           |    2 +-
+ drivers/net/ethernet/ibm/emac/core.c               |    8 +-
+ drivers/net/ethernet/ibm/emac/core.h               |    2 +-
+ drivers/net/ethernet/ibm/emac/debug.c              |    2 +-
+ drivers/net/ethernet/ibm/emac/debug.h              |    2 +-
+ drivers/net/ethernet/ibm/emac/emac.h               |    2 +-
+ drivers/net/ethernet/ibm/emac/mal.c                |    2 +-
+ drivers/net/ethernet/ibm/emac/mal.h                |    2 +-
+ drivers/net/ethernet/ibm/emac/phy.c                |    2 +-
+ drivers/net/ethernet/ibm/emac/phy.h                |    2 +-
+ drivers/net/ethernet/ibm/emac/rgmii.c              |    7 +-
+ drivers/net/ethernet/ibm/emac/rgmii.h              |    2 +-
+ drivers/net/ethernet/ibm/emac/tah.c                |    7 +-
+ drivers/net/ethernet/ibm/emac/tah.h                |    2 +-
+ drivers/net/ethernet/ibm/emac/zmii.c               |    7 +-
+ drivers/net/ethernet/ibm/emac/zmii.h               |    2 +-
+ drivers/net/ethernet/ibm/iseries_veth.c            |    4 +-
+ drivers/net/ethernet/icplus/ipg.c                  |    4 -
+ drivers/net/ethernet/intel/e100.c                  |    5 +-
+ drivers/net/ethernet/intel/e1000/e1000.h           |    1 +
+ drivers/net/ethernet/intel/e1000/e1000_hw.h        |   10 +
+ drivers/net/ethernet/intel/e1000/e1000_main.c      |  228 +-
+ drivers/net/ethernet/intel/e1000e/80003es2lan.c    |   79 +-
+ drivers/net/ethernet/intel/e1000e/82571.c          |  123 +-
+ drivers/net/ethernet/intel/e1000e/Makefile         |    5 +-
+ drivers/net/ethernet/intel/e1000e/defines.h        |   10 +-
+ drivers/net/ethernet/intel/e1000e/e1000.h          |   33 +-
+ drivers/net/ethernet/intel/e1000e/ethtool.c        |  201 +-
+ drivers/net/ethernet/intel/e1000e/hw.h             |   11 +-
+ drivers/net/ethernet/intel/e1000e/ich8lan.c        |  397 +-
+ drivers/net/ethernet/intel/e1000e/{lib.c => mac.c} | 1099 +-
+ drivers/net/ethernet/intel/e1000e/manage.c         |  367 +
+ drivers/net/ethernet/intel/e1000e/netdev.c         |  628 +-
+ drivers/net/ethernet/intel/e1000e/nvm.c            |  643 +
+ drivers/net/ethernet/intel/e1000e/param.c          |   50 +-
+ drivers/net/ethernet/intel/e1000e/phy.c            |  258 +-
+ drivers/net/ethernet/intel/igb/igb_main.c          |    4 +
+ drivers/net/ethernet/intel/igbvf/ethtool.c         |   19 +-
+ drivers/net/ethernet/intel/igbvf/igbvf.h           |   27 +-
+ drivers/net/ethernet/intel/igbvf/netdev.c          |  143 +-
+ drivers/net/ethernet/intel/ixgb/ixgb_ee.c          |   12 +-
+ drivers/net/ethernet/intel/ixgb/ixgb_main.c        |    4 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe.h           |   29 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c     |    4 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c   |    4 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c      |   59 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c      |  694 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c       |   14 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c     |    2 +-
+ drivers/net/ethernet/intel/ixgbe/ixgbe_type.h      |    1 +
+ drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c      |    2 +-
+ drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c  |   34 +-
+ drivers/net/ethernet/jme.c                         |    1 -
+ drivers/net/ethernet/korina.c                      |    6 +-
+ drivers/net/ethernet/lantiq_etop.c                 |   15 +-
+ drivers/net/ethernet/marvell/mv643xx_eth.c         |    2 +-
+ drivers/net/ethernet/marvell/pxa168_eth.c          |   15 +-
+ drivers/net/ethernet/marvell/skge.c                |    4 +-
+ drivers/net/ethernet/marvell/sky2.c                |    4 +-
+ drivers/net/ethernet/mellanox/mlx4/cmd.c           |    2 +-
+ drivers/net/ethernet/mellanox/mlx4/en_netdev.c     |    4 +-
+ drivers/net/ethernet/mellanox/mlx4/en_rx.c         |    8 +-
+ drivers/net/ethernet/mellanox/mlx4/en_tx.c         |    6 +-
+ drivers/net/ethernet/mellanox/mlx4/main.c          |    4 +-
+ drivers/net/ethernet/mellanox/mlx4/mcg.c           |   38 +-
+ drivers/net/ethernet/mellanox/mlx4/mlx4.h          |    1 -
+ drivers/net/ethernet/mellanox/mlx4/port.c          |    2 -
+ drivers/net/ethernet/micrel/ks8695net.c            |    8 +-
+ drivers/net/ethernet/micrel/ks8842.c               |    3 +-
+ drivers/net/ethernet/micrel/ks8851.c               |   11 +-
+ drivers/net/ethernet/micrel/ks8851.h               |    2 +-
+ drivers/net/ethernet/micrel/ks8851_mll.c           |   11 +-
+ drivers/net/ethernet/micrel/ksz884x.c              |    8 +-
+ drivers/net/ethernet/microchip/enc28j60.c          |    9 +-
+ drivers/net/ethernet/mipsnet.c                     |    4 +-
+ drivers/net/ethernet/myricom/myri10ge/myri10ge.c   |    4 +-
+ drivers/net/ethernet/natsemi/ibmlana.c             |    2 +-
+ drivers/net/ethernet/natsemi/macsonic.c            |    2 +-
+ drivers/net/ethernet/natsemi/natsemi.c             |    5 +-
+ drivers/net/ethernet/natsemi/sonic.c               |    4 +-
+ drivers/net/ethernet/neterion/s2io.c               |    7 +-
+ drivers/net/ethernet/netx-eth.c                    |    5 +-
+ drivers/net/ethernet/nuvoton/w90p910_ether.c       |    2 +-
+ drivers/net/ethernet/nvidia/forcedeth.c            |   11 +-
+ .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c   |   13 +-
+ drivers/net/ethernet/packetengines/hamachi.c       |    8 +-
+ drivers/net/ethernet/packetengines/yellowfin.c     |   13 +-
+ drivers/net/ethernet/pasemi/pasemi_mac.c           |    4 +-
+ drivers/net/ethernet/qlogic/netxen/netxen_nic.h    |  437 +-
+ .../net/ethernet/qlogic/netxen/netxen_nic_ctx.c    |  296 +-
+ .../ethernet/qlogic/netxen/netxen_nic_ethtool.c    |  109 +
+ .../net/ethernet/qlogic/netxen/netxen_nic_hdr.h    |    1 +
+ drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c |  629 +-
+ .../net/ethernet/qlogic/netxen/netxen_nic_init.c   |   17 +-
+ .../net/ethernet/qlogic/netxen/netxen_nic_main.c   |  132 +-
+ drivers/net/ethernet/qlogic/qla3xxx.c              |    1 -
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic.h        |    2 +-
+ .../net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c    |   14 +-
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c   |   10 +-
+ drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |   17 +-
+ drivers/net/ethernet/qlogic/qlge/qlge.h            |    2 +-
+ drivers/net/ethernet/qlogic/qlge/qlge_dbg.c        |    4 +-
+ drivers/net/ethernet/qlogic/qlge/qlge_main.c       |   86 +-
+ drivers/net/ethernet/racal/ni5010.c                |    2 +-
+ drivers/net/ethernet/rdc/r6040.c                   |    3 +-
+ drivers/net/ethernet/realtek/8139too.c             |    5 +-
+ drivers/net/ethernet/realtek/Kconfig               |   10 +-
+ drivers/net/ethernet/realtek/atp.c                 |    2 +-
+ drivers/net/ethernet/realtek/r8169.c               |  569 +-
+ drivers/net/ethernet/renesas/sh_eth.c              |  439 +-
+ drivers/net/ethernet/renesas/sh_eth.h              |   15 +-
+ drivers/net/ethernet/s6gmac.c                      |   15 +-
+ drivers/net/ethernet/seeq/ether3.c                 |    2 +-
+ drivers/net/ethernet/seeq/seeq8005.c               |    2 +-
+ drivers/net/ethernet/seeq/sgiseeq.c                |    1 -
+ drivers/net/ethernet/sfc/Kconfig                   |   21 +-
+ drivers/net/ethernet/sfc/Makefile                  |    3 +-
+ drivers/net/ethernet/sfc/bitfield.h                |   18 +-
+ drivers/net/ethernet/sfc/efx.c                     |  859 +-
+ drivers/net/ethernet/sfc/efx.h                     |   11 +-
+ drivers/net/ethernet/sfc/ethtool.c                 |  200 +-
+ drivers/net/ethernet/sfc/falcon.c                  |   54 +-
+ drivers/net/ethernet/sfc/falcon_boards.c           |   12 +-
+ drivers/net/ethernet/sfc/falcon_xmac.c             |   15 +-
+ drivers/net/ethernet/sfc/filter.c                  |  255 +-
+ drivers/net/ethernet/sfc/filter.h                  |   20 +-
+ drivers/net/ethernet/sfc/mac.h                     |   21 -
+ drivers/net/ethernet/sfc/mcdi.c                    |  149 +-
+ drivers/net/ethernet/sfc/mcdi.h                    |   36 +-
+ drivers/net/ethernet/sfc/mcdi_mac.c                |   65 +-
+ drivers/net/ethernet/sfc/mcdi_mon.c                |  415 +
+ drivers/net/ethernet/sfc/mcdi_pcol.h               | 3542 ++-
+ drivers/net/ethernet/sfc/mcdi_phy.c                |   36 +-
+ drivers/net/ethernet/sfc/mdio_10g.c                |    2 +-
+ drivers/net/ethernet/sfc/mtd.c                     |   15 +-
+ drivers/net/ethernet/sfc/net_driver.h              |  312 +-
+ drivers/net/ethernet/sfc/nic.c                     |  593 +-
+ drivers/net/ethernet/sfc/nic.h                     |  122 +-
+ drivers/net/ethernet/sfc/qt202x_phy.c              |    6 +-
+ drivers/net/ethernet/sfc/regs.h                    |   20 +-
+ drivers/net/ethernet/sfc/rx.c                      |  126 +-
+ drivers/net/ethernet/sfc/selftest.c                |  110 +-
+ drivers/net/ethernet/sfc/selftest.h                |    1 -
+ drivers/net/ethernet/sfc/siena.c                   |   47 +-
+ drivers/net/ethernet/sfc/siena_sriov.c             | 1642 ++
+ drivers/net/ethernet/sfc/spi.h                     |    2 +-
+ drivers/net/ethernet/sfc/tenxpress.c               |    2 +-
+ drivers/net/ethernet/sfc/tx.c                      |    6 +-
+ drivers/net/ethernet/sfc/txc43128_phy.c            |    2 +-
+ drivers/net/ethernet/sfc/vfdi.h                    |  254 +
+ drivers/net/ethernet/sis/sis190.c                  |    2 -
+ drivers/net/ethernet/sis/sis900.c                  |    9 +-
+ drivers/net/ethernet/smsc/epic100.c                |   11 +-
+ drivers/net/ethernet/smsc/smc911x.c                |    3 +-
+ drivers/net/ethernet/smsc/smc9194.c                |    2 +-
+ drivers/net/ethernet/smsc/smc91c92_cs.c            |    2 +-
+ drivers/net/ethernet/smsc/smc91x.c                 |    3 +-
+ drivers/net/ethernet/smsc/smsc911x.c               |    4 +-
+ drivers/net/ethernet/smsc/smsc9420.c               |   11 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   11 +-
+ drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c   |    2 +-
+ drivers/net/ethernet/sun/cassini.c                 |    4 +-
+ drivers/net/ethernet/sun/niu.c                     |    4 +-
+ drivers/net/ethernet/sun/sunbmac.c                 |    2 +-
+ drivers/net/ethernet/sun/sungem.c                  |    1 -
+ drivers/net/ethernet/sun/sunhme.c                  |    2 +-
+ drivers/net/ethernet/sun/sunqe.c                   |    2 +-
+ drivers/net/ethernet/sun/sunvnet.c                 |   13 +-
+ drivers/net/ethernet/tehuti/tehuti.c               |    8 +-
+ drivers/net/ethernet/ti/cpmac.c                    |    5 +-
+ drivers/net/ethernet/ti/davinci_emac.c             |    9 +-
+ drivers/net/ethernet/ti/tlan.c                     |    1 -
+ drivers/net/ethernet/tile/tilepro.c                |    7 +-
+ drivers/net/ethernet/toshiba/ps3_gelic_wireless.c  |    5 +-
+ drivers/net/ethernet/toshiba/tc35815.c             |    9 +-
+ drivers/net/ethernet/tundra/tsi108_eth.c           |    4 +-
+ drivers/net/ethernet/via/via-rhine.c               |    5 +-
+ drivers/net/ethernet/via/via-velocity.c            |    6 +-
+ drivers/net/ethernet/xilinx/Kconfig                |    8 +
+ drivers/net/ethernet/xilinx/Makefile               |    2 +
+ drivers/net/ethernet/xilinx/ll_temac_main.c        |    9 +-
+ drivers/net/ethernet/xilinx/xilinx_axienet.h       |  508 +
+ drivers/net/ethernet/xilinx/xilinx_axienet_main.c  | 1669 ++
+ drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c  |  238 +
+ drivers/net/ethernet/xilinx/xilinx_emaclite.c      |    6 +-
+ drivers/net/ethernet/xircom/xirc2ps_cs.c           |    3 +-
+ drivers/net/hamradio/baycom_epp.c                  |    2 +-
+ drivers/net/hamradio/baycom_par.c                  |    2 +-
+ drivers/net/hamradio/yam.c                         |    1 -
+ drivers/net/hippi/rrunner.c                        |    8 +-
+ drivers/net/hyperv/netvsc_drv.c                    |    7 +-
+ drivers/net/hyperv/rndis_filter.c                  |   60 +-
+ drivers/net/ifb.c                                  |    2 +-
+ drivers/net/irda/donauboe.c                        |    2 -
+ drivers/net/macvlan.c                              |    3 +-
+ drivers/net/netconsole.c                           |    8 +-
+ drivers/net/phy/broadcom.c                         |    6 +-
+ drivers/net/plip/plip.c                            |    4 +-
+ drivers/net/ppp/ppp_generic.c                      |    2 +-
+ drivers/net/ppp/pptp.c                             |    4 +-
+ drivers/net/rionet.c                               |    2 -
+ drivers/net/slip/slip.c                            |    4 +-
+ drivers/net/team/team.c                            |    3 +-
+ drivers/net/tokenring/3c359.c                      |    4 -
+ drivers/net/tokenring/madgemc.c                    |    1 -
+ drivers/net/tokenring/tms380tr.c                   |  179 +-
+ drivers/net/tun.c                                  |    2 +-
+ drivers/net/usb/Kconfig                            |   22 +
+ drivers/net/usb/Makefile                           |    1 +
+ drivers/net/usb/pegasus.c                          |    4 +-
+ drivers/net/usb/qmi_wwan.c                         |  228 +
+ drivers/net/usb/rtl8150.c                          |    4 +-
+ drivers/net/usb/smsc75xx.c                         |    2 +-
+ drivers/net/usb/smsc95xx.c                         |    2 +-
+ drivers/net/usb/usbnet.c                           |    4 +-
+ drivers/net/veth.c                                 |    4 +-
+ drivers/net/virtio_net.c                           |    9 +-
+ drivers/net/vmxnet3/vmxnet3_drv.c                  |   44 +-
+ drivers/net/wan/c101.c                             |    4 +-
+ drivers/net/wan/dscc4.c                            |    8 +-
+ drivers/net/wan/hdlc_fr.c                          |    2 +-
+ drivers/net/wan/hdlc_raw_eth.c                     |    2 +-
+ drivers/net/wan/lmc/lmc_main.c                     |    1 -
+ drivers/net/wan/n2.c                               |    4 +-
+ drivers/net/wan/pc300too.c                         |    1 -
+ drivers/net/wan/pci200syn.c                        |    1 -
+ drivers/net/wan/wanxl.c                            |    1 -
+ drivers/net/wan/x25_asy.c                          |    4 +-
+ drivers/net/wireless/ath/ath5k/ani.c               |    8 +-
+ drivers/net/wireless/ath/ath5k/base.c              |    5 +-
+ drivers/net/wireless/ath/ath5k/mac80211-ops.c      |    8 +
+ drivers/net/wireless/ath/ath9k/ani.c               |    6 +-
+ drivers/net/wireless/ath/ath9k/hif_usb.c           |  154 +-
+ drivers/net/wireless/ath/ath9k/hif_usb.h           |    3 +-
+ drivers/net/wireless/ath/ath9k/htc_drv_init.c      |    2 +
+ drivers/net/wireless/ath/ath9k/htc_drv_main.c      |   15 +
+ drivers/net/wireless/ath/ath9k/htc_hst.c           |    5 +-
+ drivers/net/wireless/ath/ath9k/hw-ops.h            |    2 +-
+ drivers/net/wireless/ath/ath9k/hw.c                |    5 +-
+ drivers/net/wireless/ath/ath9k/main.c              |    4 +-
+ drivers/net/wireless/ath/carl9170/carl9170.h       |    2 +-
+ drivers/net/wireless/ath/carl9170/fw.c             |   33 -
+ drivers/net/wireless/ath/carl9170/mac.c            |   35 +
+ drivers/net/wireless/ath/carl9170/main.c           |   18 +-
+ drivers/net/wireless/ath/carl9170/phy.c            |   36 +-
+ drivers/net/wireless/ath/carl9170/tx.c             |    2 +
+ drivers/net/wireless/atmel.c                       |    5 +-
+ drivers/net/wireless/b43/b43.h                     |   12 +
+ drivers/net/wireless/b43/main.c                    |   67 +-
+ drivers/net/wireless/b43/phy_n.c                   |  532 +-
+ drivers/net/wireless/b43/phy_n.h                   |    1 +
+ drivers/net/wireless/b43/tables_nphy.c             |   76 +-
+ drivers/net/wireless/b43/tables_nphy.h             |   14 +-
+ drivers/net/wireless/brcm80211/Makefile            |    2 +-
+ drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c   |    2 +
+ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c |    3 +
+ drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |    4 +-
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c  |    2 +
+ .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |   17 +-
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h  |   20 +-
+ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   10 +-
+ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |  232 +-
+ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c    |    2 +
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |    6 +-
+ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |   36 +-
+ drivers/net/wireless/brcm80211/brcmsmac/aiutils.c  |    4 +-
+ drivers/net/wireless/brcm80211/brcmsmac/ampdu.c    |    2 +-
+ drivers/net/wireless/brcm80211/brcmsmac/dma.c      |    8 +-
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  |   24 +-
+ .../net/wireless/brcm80211/brcmsmac/mac80211_if.h  |    2 +-
+ drivers/net/wireless/brcm80211/brcmsmac/main.c     |  198 +-
+ drivers/net/wireless/brcm80211/brcmsmac/main.h     |    6 +-
+ .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c    |    7 +-
+ drivers/net/wireless/brcm80211/brcmutil/utils.c    |   26 +-
+ .../net/wireless/brcm80211/include/brcmu_utils.h   |   15 +-
+ drivers/net/wireless/hostap/hostap_hw.c            |   18 +-
+ drivers/net/wireless/ipw2x00/ipw2100.c             |    5 +-
+ drivers/net/wireless/ipw2x00/libipw_module.c       |    5 +-
+ drivers/net/wireless/iwlwifi/iwl-1000.c            |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-2000.c            |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-5000.c            |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-6000.c            |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-calib.c       |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-calib.h       |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-hw.h          |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-lib.c         |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-rs.c          |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-rs.h          |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-rx.c          |   30 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-rxon.c        |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-sta.c         |   13 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-tt.c          |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-tt.h          |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-tx.c          |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-agn.c             |  103 +-
+ drivers/net/wireless/iwlwifi/iwl-agn.h             |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-bus.h             |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-cfg.h             |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-commands.h        |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-core.c            |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-core.h            |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-csr.h             |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-debug.h           |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-debugfs.c         |    9 +-
+ drivers/net/wireless/iwlwifi/iwl-dev.h             |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-devtrace.c        |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-devtrace.h        |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-eeprom.c          |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-eeprom.h          |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-fh.h              |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-io.c              |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-io.h              |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-led.c             |    6 +-
+ drivers/net/wireless/iwlwifi/iwl-led.h             |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-mac80211.c        |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-pci.c             |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-power.c           |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-power.h           |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-prph.h            |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-scan.c            |   23 +-
+ drivers/net/wireless/iwlwifi/iwl-shared.h          |    8 +-
+ drivers/net/wireless/iwlwifi/iwl-testmode.c        |   64 +-
+ drivers/net/wireless/iwlwifi/iwl-testmode.h        |   32 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h  |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c   |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c   |    6 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c      |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-trans.c           |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-trans.h           |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-ucode.c           |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-wifi.h            |    4 +-
+ drivers/net/wireless/libertas/if_cs.c              |    5 +-
+ drivers/net/wireless/libertas/if_usb.c             |    4 +-
+ drivers/net/wireless/libertas_tf/if_usb.c          |    4 +-
+ drivers/net/wireless/mwifiex/11n_aggr.c            |    3 +-
+ drivers/net/wireless/mwifiex/cfg80211.c            |   37 +-
+ drivers/net/wireless/mwifiex/cmdevt.c              |    3 +-
+ drivers/net/wireless/mwifiex/decl.h                |    6 +-
+ drivers/net/wireless/mwifiex/init.c                |    5 +-
+ drivers/net/wireless/mwifiex/main.c                |   25 +-
+ drivers/net/wireless/mwifiex/main.h                |    4 +-
+ drivers/net/wireless/mwifiex/pcie.c                |    4 +-
+ drivers/net/wireless/mwifiex/scan.c                |    8 +-
+ drivers/net/wireless/mwifiex/sdio.c                |    4 +-
+ drivers/net/wireless/mwifiex/sta_rx.c              |    6 +-
+ drivers/net/wireless/mwifiex/sta_tx.c              |    3 +-
+ drivers/net/wireless/mwifiex/txrx.c                |    6 +-
+ drivers/net/wireless/mwifiex/util.c                |    3 +-
+ drivers/net/wireless/mwifiex/wmm.c                 |    5 +-
+ drivers/net/wireless/mwifiex/wmm.h                 |    4 +-
+ drivers/net/wireless/mwl8k.c                       |    7 +-
+ drivers/net/wireless/orinoco/main.c                |    6 +-
+ drivers/net/wireless/orinoco/orinoco_usb.c         |    5 -
+ drivers/net/wireless/p54/main.c                    |    3 +-
+ drivers/net/wireless/prism54/islpci_mgt.c          |    6 +-
+ drivers/net/wireless/rt2x00/rt2800lib.c            |   23 +-
+ drivers/net/wireless/rt2x00/rt2800pci.c            |    2 +-
+ drivers/net/wireless/rt2x00/rt2800usb.c            |    4 +-
+ drivers/net/wireless/rtlwifi/Kconfig               |    5 +
+ drivers/net/wireless/rtlwifi/base.c                |   67 +-
+ drivers/net/wireless/rtlwifi/base.h                |    2 +-
+ drivers/net/wireless/rtlwifi/cam.c                 |   85 +-
+ drivers/net/wireless/rtlwifi/cam.h                 |    2 +-
+ drivers/net/wireless/rtlwifi/core.c                |  174 +-
+ drivers/net/wireless/rtlwifi/core.h                |    6 +-
+ drivers/net/wireless/rtlwifi/debug.c               |    4 +-
+ drivers/net/wireless/rtlwifi/debug.h               |  121 +-
+ drivers/net/wireless/rtlwifi/efuse.c               |   65 +-
+ drivers/net/wireless/rtlwifi/efuse.h               |    2 +-
+ drivers/net/wireless/rtlwifi/pci.c                 |  243 +-
+ drivers/net/wireless/rtlwifi/pci.h                 |    3 +-
+ drivers/net/wireless/rtlwifi/ps.c                  |   39 +-
+ drivers/net/wireless/rtlwifi/ps.h                  |    2 +-
+ drivers/net/wireless/rtlwifi/rc.c                  |    4 +-
+ drivers/net/wireless/rtlwifi/rc.h                  |    2 +-
+ drivers/net/wireless/rtlwifi/regd.c                |   14 +-
+ drivers/net/wireless/rtlwifi/regd.h                |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c  |  195 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h  |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c  |   99 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h  |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/main.c       |    4 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c |  221 +-
+ drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/def.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/dm.c        |   26 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/dm.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/hw.c        |  288 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/hw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/led.c       |   18 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/led.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/phy.c       |  113 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/phy.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/reg.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/rf.c        |   87 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/rf.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/sw.c        |   37 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/sw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/table.c     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/table.h     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/trx.c       |   25 +-
+ drivers/net/wireless/rtlwifi/rtl8192ce/trx.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/def.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/dm.c        |   26 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/dm.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/hw.c        |  464 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/hw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/led.c       |   17 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/led.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/mac.c       |  133 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/mac.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/phy.c       |  126 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/phy.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/reg.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/rf.c        |   75 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/rf.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c        |   34 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/sw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/table.c     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/table.h     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/trx.c       |   44 +-
+ drivers/net/wireless/rtlwifi/rtl8192cu/trx.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/def.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/dm.c        |  243 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/dm.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/fw.c        |  137 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/fw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/hw.c        |  202 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/hw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/led.c       |   16 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/led.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/phy.c       |  695 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/phy.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/reg.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/rf.c        |   99 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/rf.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/sw.c        |   57 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/sw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/table.c     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/table.h     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/trx.c       |   28 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/trx.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/def.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/dm.c        |   32 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/dm.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/fw.c        |   76 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/fw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/hw.c        |  272 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/hw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/led.c       |   22 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/led.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/phy.c       |  221 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/phy.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/reg.h       |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/rf.c        |   66 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/rf.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/sw.c        |   87 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/sw.h        |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/table.c     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/table.h     |    2 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/trx.c       |   20 +-
+ drivers/net/wireless/rtlwifi/rtl8192se/trx.h       |    2 +-
+ drivers/net/wireless/rtlwifi/usb.c                 |   92 +-
+ drivers/net/wireless/rtlwifi/usb.h                 |    3 +-
+ drivers/net/wireless/rtlwifi/wifi.h                |    8 +-
+ drivers/net/wireless/wl1251/main.c                 |    7 +-
+ drivers/net/wireless/wl12xx/main.c                 |    5 +-
+ drivers/net/xen-netback/netback.c                  |    4 +-
+ drivers/net/xen-netfront.c                         |   62 +-
+ drivers/nfc/nfcwilink.c                            |  305 +-
+ drivers/s390/net/qeth_core.h                       |    1 +
+ drivers/s390/net/qeth_core_main.c                  |  100 +
+ drivers/s390/net/qeth_core_mpc.h                   |   13 +
+ drivers/s390/net/qeth_l2_main.c                    |    3 +
+ drivers/s390/net/qeth_l3_main.c                    |   38 +-
+ drivers/scsi/bnx2fc/bnx2fc_constants.h             |    2 +-
+ drivers/scsi/bnx2fc/bnx2fc_hwi.c                   |   12 +-
+ drivers/ssb/pci.c                                  |   40 +-
+ include/asm-generic/socket.h                       |    1 +
+ include/linux/can/dev.h                            |    2 +-
+ include/linux/etherdevice.h                        |   13 +-
+ include/linux/in.h                                 |    1 +
+ include/linux/in6.h                                |    1 +
+ include/linux/ipv6.h                               |    8 +-
+ include/linux/net.h                                |    1 +
+ include/linux/netlink.h                            |   18 +-
+ include/linux/nfc.h                                |    7 +
+ include/linux/nl80211.h                            |    8 +
+ include/linux/pkt_sched.h                          |   21 +
+ include/linux/sh_eth.h                             |    1 +
+ include/linux/skbuff.h                             |   29 +-
+ include/linux/snmp.h                               |    1 +
+ include/linux/ssb/ssb.h                            |    8 +
+ include/linux/ssb/ssb_regs.h                       |   34 +
+ include/linux/tcp.h                                |    5 +-
+ include/net/addrconf.h                             |    1 -
+ include/net/arp.h                                  |    4 +-
+ include/net/caif/caif_hsi.h                        |    1 +
+ include/net/cfg80211.h                             |    6 +-
+ include/net/dn.h                                   |    1 +
+ include/net/genetlink.h                            |   31 +-
+ include/net/inet_sock.h                            |    3 +
+ include/net/iucv/af_iucv.h                         |    2 +
+ include/net/mac80211.h                             |   44 +-
+ include/net/ndisc.h                                |    1 -
+ include/net/netlink.h                              |   35 -
+ include/net/nfc/nci.h                              |   53 +-
+ include/net/nfc/nci_core.h                         |   26 +-
+ include/net/nfc/nfc.h                              |    9 +-
+ include/net/sock.h                                 |   25 +
+ include/net/tcp.h                                  |   66 +-
+ net/atm/clip.c                                     |   17 +-
+ net/batman-adv/{bat_ogm.h => bat_algo.h}           |   20 +-
+ net/batman-adv/bat_debugfs.c                       |   22 +
+ net/batman-adv/bat_iv_ogm.c                        |  245 +-
+ net/batman-adv/bat_sysfs.c                         |    9 +
+ net/batman-adv/hard-interface.c                    |   24 +-
+ net/batman-adv/icmp_socket.c                       |    6 +-
+ net/batman-adv/main.c                              |  107 +
+ net/batman-adv/main.h                              |   15 +
+ net/batman-adv/originator.c                        |    1 +
+ net/batman-adv/packet.h                            |   38 +-
+ net/batman-adv/routing.c                           |   24 +-
+ net/batman-adv/send.c                              |    7 +-
+ net/batman-adv/soft-interface.c                    |   23 +-
+ net/batman-adv/translation-table.c                 |   67 +-
+ net/batman-adv/types.h                             |   21 +
+ net/batman-adv/unicast.c                           |   16 +-
+ net/batman-adv/vis.c                               |   14 +-
+ net/bridge/br_device.c                             |    3 +-
+ net/caif/caif_dev.c                                |    2 -
+ net/caif/caif_socket.c                             |  113 +-
+ net/caif/chnl_net.c                                |   15 +-
+ net/core/datagram.c                                |   26 +-
+ net/core/dev.c                                     |   94 +-
+ net/core/neighbour.c                               |   90 +-
+ net/core/netpoll.c                                 |   71 +-
+ net/core/skbuff.c                                  |    3 +-
+ net/core/sock.c                                    |   13 +
+ net/decnet/dn_neigh.c                              |   24 +-
+ net/decnet/dn_route.c                              |    3 +-
+ net/ethernet/eth.c                                 |    2 +
+ net/ipv4/af_inet.c                                 |    1 +
+ net/ipv4/ip_gre.c                                  |   21 +-
+ net/ipv4/ip_sockglue.c                             |   37 +
+ net/ipv4/ipip.c                                    |    3 +-
+ net/ipv4/ping.c                                    |    3 +-
+ net/ipv4/proc.c                                    |    1 +
+ net/ipv4/raw.c                                     |    3 +-
+ net/ipv4/route.c                                   |    7 +-
+ net/ipv4/tcp_ipv4.c                                |  297 +-
+ net/ipv4/tcp_minisocks.c                           |   12 +-
+ net/ipv4/tcp_output.c                              |    4 +-
+ net/ipv4/udp.c                                     |    7 +-
+ net/ipv6/af_inet6.c                                |    1 +
+ net/ipv6/anycast.c                                 |   29 -
+ net/ipv6/datagram.c                                |    2 +-
+ net/ipv6/icmp.c                                    |    4 +
+ net/ipv6/ip6_fib.c                                 |   19 +-
+ net/ipv6/ip6_output.c                              |   10 +-
+ net/ipv6/ipv6_sockglue.c                           |   38 +
+ net/ipv6/ndisc.c                                   |   30 +-
+ net/ipv6/raw.c                                     |    2 +
+ net/ipv6/reassembly.c                              |    7 +-
+ net/ipv6/route.c                                   |   15 +-
+ net/ipv6/sit.c                                     |   20 +-
+ net/ipv6/tcp_ipv6.c                                |  231 +-
+ net/ipv6/udp.c                                     |    7 +-
+ net/ipv6/xfrm6_output.c                            |    2 +-
+ net/iucv/af_iucv.c                                 |  202 +-
+ net/l2tp/l2tp_eth.c                                |    2 +-
+ net/mac80211/cfg.c                                 |   46 +-
+ net/mac80211/chan.c                                |   28 +-
+ net/mac80211/debugfs.c                             |    4 -
+ net/mac80211/debugfs_netdev.c                      |   35 +
+ net/mac80211/debugfs_sta.c                         |    5 +-
+ net/mac80211/ibss.c                                |   94 +-
+ net/mac80211/ieee80211_i.h                         |    3 +-
+ net/mac80211/iface.c                               |   13 +-
+ net/mac80211/main.c                                |    3 +-
+ net/mac80211/mesh_hwmp.c                           |    2 +-
+ net/mac80211/mesh_plink.c                          |    6 +-
+ net/mac80211/mlme.c                                |   25 +-
+ net/mac80211/rate.c                                |  151 +-
+ net/mac80211/rate.h                                |    4 -
+ net/mac80211/rx.c                                  |   11 +-
+ net/mac80211/sta_info.c                            |   84 +-
+ net/mac80211/sta_info.h                            |   17 +-
+ net/mac80211/status.c                              |    6 +-
+ net/mac80211/tx.c                                  |    5 +
+ net/mac80211/util.c                                |   21 +-
+ net/mac80211/work.c                                |    5 +-
+ net/netlink/af_netlink.c                           |   18 +
+ net/netlink/genetlink.c                            |   31 +
+ net/nfc/core.c                                     |    5 -
+ net/nfc/nci/core.c                                 |  118 +-
+ net/nfc/nci/data.c                                 |    4 +
+ net/nfc/nci/ntf.c                                  |  337 +-
+ net/nfc/nci/rsp.c                                  |   28 +-
+ net/nfc/netlink.c                                  |    6 +
+ net/nfc/rawsock.c                                  |   12 -
+ net/openvswitch/vport-internal_dev.c               |    3 +-
+ net/sched/Kconfig                                  |   26 +
+ net/sched/Makefile                                 |    1 +
+ net/sched/sch_plug.c                               |  233 +
+ net/tipc/bcast.c                                   |  324 +-
+ net/tipc/bcast.h                                   |    2 +-
+ net/tipc/link.c                                    |  148 +-
+ net/tipc/name_distr.c                              |    4 -
+ net/tipc/node.c                                    |   14 +-
+ net/tipc/node.h                                    |   18 +-
+ net/tipc/port.c                                    |    5 +-
+ net/unix/af_unix.c                                 |   50 +-
+ net/wireless/mesh.c                                |    1 +
+ net/wireless/nl80211.c                             |   74 +-
+ net/wireless/reg.c                                 |   19 +-
+ 1144 files changed, 79899 insertions(+), 68757 deletions(-)
+ rename drivers/net/ethernet/intel/e1000e/{lib.c => mac.c} (63%)
+ create mode 100644 drivers/net/ethernet/intel/e1000e/manage.c
+ create mode 100644 drivers/net/ethernet/intel/e1000e/nvm.c
+ delete mode 100644 drivers/net/ethernet/sfc/mac.h
+ create mode 100644 drivers/net/ethernet/sfc/mcdi_mon.c
+ create mode 100644 drivers/net/ethernet/sfc/siena_sriov.c
+ create mode 100644 drivers/net/ethernet/sfc/vfdi.h
+ create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet.h
+ create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+ create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
+ create mode 100644 drivers/net/usb/qmi_wwan.c
+ rename net/batman-adv/{bat_ogm.h => bat_algo.h} (51%)
+ create mode 100644 net/sched/sch_plug.c
+Merging wireless-next/master (ca994a3 Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless)
+$ git merge wireless-next/master
+Resolved 'net/mac80211/debugfs_sta.c' using previous resolution.
+Resolved 'net/mac80211/sta_info.h' using previous resolution.
+Auto-merging net/mac80211/sta_info.h
+CONFLICT (content): Merge conflict in net/mac80211/sta_info.h
+Auto-merging net/mac80211/rate.c
+Auto-merging net/mac80211/iface.c
+Auto-merging net/mac80211/debugfs_sta.c
+CONFLICT (content): Merge conflict in net/mac80211/debugfs_sta.c
+Auto-merging drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+Auto-merging drivers/net/wireless/rt2x00/rt2x00dev.c
+Auto-merging drivers/net/wireless/mwl8k.c
+Auto-merging drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+Auto-merging MAINTAINERS
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master c1379fc] Merge remote-tracking branch 'wireless-next/master'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/DocBook/80211.tmpl                  |    1 -
+ MAINTAINERS                                       |    2 -
+ arch/mips/pci/pci-bcm47xx.c                       |   49 +-
+ drivers/bcma/bcma_private.h                       |    8 +-
+ drivers/bcma/driver_pci.c                         |  168 ++--
+ drivers/bcma/driver_pci_host.c                    |  578 +++++++++-
+ drivers/bcma/host_pci.c                           |    4 +-
+ drivers/bcma/main.c                               |   14 +-
+ drivers/bcma/scan.c                               |   24 +-
+ drivers/bcma/sprom.c                              |    7 +
+ drivers/net/wireless/ath/ath6kl/Kconfig           |   25 +-
+ drivers/net/wireless/ath/ath6kl/Makefile          |   30 +-
+ drivers/net/wireless/ath/ath6kl/bmi.c             |   10 +-
+ drivers/net/wireless/ath/ath6kl/cfg80211.c        |  606 ++++++---
+ drivers/net/wireless/ath/ath6kl/cfg80211.h        |   12 +-
+ drivers/net/wireless/ath/ath6kl/common.h          |    3 -
+ drivers/net/wireless/ath/ath6kl/core.c            |  316 +++++
+ drivers/net/wireless/ath/ath6kl/core.h            |  107 ++-
+ drivers/net/wireless/ath/ath6kl/debug.c           |  114 +-
+ drivers/net/wireless/ath/ath6kl/debug.h           |   28 +-
+ drivers/net/wireless/ath/ath6kl/hif.c             |   15 +-
+ drivers/net/wireless/ath/ath6kl/htc.c             |   11 +-
+ drivers/net/wireless/ath/ath6kl/init.c            |  472 +++----
+ drivers/net/wireless/ath/ath6kl/main.c            |  182 +++-
+ drivers/net/wireless/ath/ath6kl/sdio.c            |  140 ++-
+ drivers/net/wireless/ath/ath6kl/testmode.c        |  102 +--
+ drivers/net/wireless/ath/ath6kl/testmode.h        |    6 +-
+ drivers/net/wireless/ath/ath6kl/txrx.c            |  534 ++++++--
+ drivers/net/wireless/ath/ath6kl/usb.c             |  431 +++++++
+ drivers/net/wireless/ath/ath6kl/wmi.c             |  148 ++-
+ drivers/net/wireless/ath/ath6kl/wmi.h             |   67 +-
+ drivers/net/wireless/ath/ath9k/hif_usb.c          |    2 +-
+ drivers/net/wireless/ipw2x00/libipw_rx.c          |    2 +-
+ drivers/net/wireless/iwlegacy/3945-mac.c          |  186 ++--
+ drivers/net/wireless/iwlegacy/3945-rs.c           |    7 +-
+ drivers/net/wireless/iwlegacy/3945.c              |  111 +-
+ drivers/net/wireless/iwlegacy/3945.h              |    6 +-
+ drivers/net/wireless/iwlegacy/4965-calib.c        |   24 +-
+ drivers/net/wireless/iwlegacy/4965-mac.c          |  512 ++++----
+ drivers/net/wireless/iwlegacy/4965-rs.c           |   48 +-
+ drivers/net/wireless/iwlegacy/4965.c              |  328 ++----
+ drivers/net/wireless/iwlegacy/4965.h              |   22 +-
+ drivers/net/wireless/iwlegacy/common.c            |  656 ++++------
+ drivers/net/wireless/iwlegacy/common.h            |  234 ++---
+ drivers/net/wireless/iwlegacy/debug.c             |   43 +-
+ drivers/net/wireless/iwlwifi/iwl-1000.c           |    6 +-
+ drivers/net/wireless/iwlwifi/iwl-2000.c           |    4 +-
+ drivers/net/wireless/iwlwifi/iwl-5000.c           |    6 +-
+ drivers/net/wireless/iwlwifi/iwl-6000.c           |   10 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-rx.c         |    8 +-
+ drivers/net/wireless/iwlwifi/iwl-agn-tt.c         |   14 +-
+ drivers/net/wireless/iwlwifi/iwl-agn.c            |  713 +----------
+ drivers/net/wireless/iwlwifi/iwl-agn.h            |    3 +-
+ drivers/net/wireless/iwlwifi/iwl-bus.h            |   64 -
+ drivers/net/wireless/iwlwifi/iwl-core.c           |  128 +--
+ drivers/net/wireless/iwlwifi/iwl-core.h           |    6 -
+ drivers/net/wireless/iwlwifi/iwl-debug.h          |   16 +-
+ drivers/net/wireless/iwlwifi/iwl-debugfs.c        |    6 +-
+ drivers/net/wireless/iwlwifi/iwl-dev.h            |  109 --
+ drivers/net/wireless/iwlwifi/iwl-eeprom.c         |   65 +-
+ drivers/net/wireless/iwlwifi/iwl-io.c             |  193 ++--
+ drivers/net/wireless/iwlwifi/iwl-io.h             |   60 +-
+ drivers/net/wireless/iwlwifi/iwl-led.c            |    9 +-
+ drivers/net/wireless/iwlwifi/iwl-mac80211.c       |   36 +-
+ drivers/net/wireless/iwlwifi/iwl-pci.c            |  229 +---
+ drivers/net/wireless/iwlwifi/iwl-power.c          |    2 +-
+ drivers/net/wireless/iwlwifi/iwl-shared.h         |    2 -
+ drivers/net/wireless/iwlwifi/iwl-testmode.c       |   36 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h |   18 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c  |  103 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c  |   55 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c     |  661 ++++++++--
+ drivers/net/wireless/iwlwifi/iwl-trans.h          |  133 ++-
+ drivers/net/wireless/iwlwifi/iwl-ucode.c          |  740 ++++++++++--
+ drivers/net/wireless/iwlwifi/iwl-ucode.h          |  178 +++
+ drivers/net/wireless/iwmc3200wifi/trace.h         |    2 +-
+ drivers/net/wireless/mwifiex/cfg80211.c           |   15 +-
+ drivers/net/wireless/mwifiex/init.c               |    1 +
+ drivers/net/wireless/mwifiex/main.h               |    2 +-
+ drivers/net/wireless/mwifiex/scan.c               |    6 -
+ drivers/net/wireless/mwifiex/sta_cmd.c            |   60 +-
+ drivers/net/wireless/mwifiex/sta_cmdresp.c        |    3 +
+ drivers/net/wireless/mwl8k.c                      |   38 +-
+ drivers/net/wireless/rt2x00/rt2800.h              |   49 +-
+ drivers/net/wireless/rt2x00/rt2800lib.c           |  159 ++-
+ drivers/net/wireless/rt2x00/rt2800pci.c           |    1 +
+ drivers/net/wireless/rt2x00/rt2800usb.c           |    1 +
+ drivers/net/wireless/rt2x00/rt2x00.h              |   15 +-
+ drivers/net/wireless/rt2x00/rt2x00dev.c           |   18 +
+ drivers/net/wireless/rtlwifi/core.c               |    4 +-
+ drivers/net/wireless/rtlwifi/pci.c                |   39 +-
+ drivers/net/wireless/rtlwifi/rtl8192de/dm.c       |    2 +-
+ drivers/ssb/driver_chipcommon_pmu.c               |   48 +-
+ drivers/ssb/driver_mipscore.c                     |    3 +
+ drivers/ssb/main.c                                |    3 +
+ drivers/ssb/scan.c                                |    3 +
+ drivers/ssb/ssb_private.h                         |    4 +
+ include/linux/bcma/bcma.h                         |    2 +
+ include/linux/bcma/bcma_driver_chipcommon.h       |   16 +
+ include/linux/bcma/bcma_driver_pci.h              |  125 ++-
+ include/linux/bcma/bcma_regs.h                    |   27 +
+ include/net/cfg80211.h                            |   58 +-
+ include/net/mac80211.h                            |   35 +
+ net/mac80211/Makefile                             |    4 +-
+ net/mac80211/cfg.c                                |    6 +-
+ net/mac80211/debugfs.c                            |    2 +
+ net/mac80211/debugfs_sta.c                        |    4 +-
+ net/mac80211/driver-ops.h                         |   33 +
+ net/mac80211/driver-trace.h                       |   32 +
+ net/mac80211/ibss.c                               |    6 +-
+ net/mac80211/ieee80211_i.h                        |   79 +-
+ net/mac80211/iface.c                              |    7 +-
+ net/mac80211/key.c                                |   38 +-
+ net/mac80211/main.c                               |   16 +-
+ net/mac80211/mesh_pathtbl.c                       |    6 +-
+ net/mac80211/mlme.c                               | 1390 +++++++++++++++------
+ net/mac80211/pm.c                                 |   11 +-
+ net/mac80211/rate.c                               |    2 +-
+ net/mac80211/rx.c                                 |   22 +-
+ net/mac80211/sta_info.c                           |  252 ++--
+ net/mac80211/sta_info.h                           |   42 +-
+ net/mac80211/util.c                               |   11 +-
+ net/mac80211/work.c                               |  815 ------------
+ net/wireless/core.h                               |   14 +-
+ net/wireless/mlme.c                               |  322 +----
+ net/wireless/nl80211.c                            |   40 +-
+ net/wireless/scan.c                               |   12 +
+ net/wireless/sme.c                                |   41 +-
+ 128 files changed, 7897 insertions(+), 6057 deletions(-)
+ create mode 100644 drivers/net/wireless/ath/ath6kl/core.c
+ create mode 100644 drivers/net/wireless/ath/ath6kl/usb.c
+ create mode 100644 drivers/net/wireless/iwlwifi/iwl-ucode.h
+Merging bluetooth/master (04f1017 Bluetooth: Add AR30XX device ID on Asus laptops)
+$ git merge bluetooth/master
+Merge made by the 'recursive' strategy.
+ drivers/bluetooth/ath3k.c          |    1 +
+ drivers/bluetooth/bfusb.c          |   23 +-
+ drivers/bluetooth/bluecard_cs.c    |   20 +-
+ drivers/bluetooth/bpa10x.c         |   35 +-
+ drivers/bluetooth/bt3c_cs.c        |   14 +-
+ drivers/bluetooth/btmrvl_debugfs.c |   26 +-
+ drivers/bluetooth/btmrvl_main.c    |   17 +-
+ drivers/bluetooth/btsdio.c         |   23 +-
+ drivers/bluetooth/btuart_cs.c      |   14 +-
+ drivers/bluetooth/btusb.c          |   47 +-
+ drivers/bluetooth/btwilink.c       |   18 +-
+ drivers/bluetooth/dtl1_cs.c        |   34 +-
+ drivers/bluetooth/hci_ath.c        |    2 +-
+ drivers/bluetooth/hci_bcsp.c       |    2 +-
+ drivers/bluetooth/hci_h4.c         |    2 +-
+ drivers/bluetooth/hci_ldisc.c      |   20 +-
+ drivers/bluetooth/hci_ll.c         |    2 +-
+ drivers/bluetooth/hci_vhci.c       |   17 +-
+ include/net/bluetooth/bluetooth.h  |   40 +-
+ include/net/bluetooth/hci.h        |   61 +-
+ include/net/bluetooth/hci_core.h   |  279 ++++--
+ include/net/bluetooth/hci_mon.h    |   51 ++
+ include/net/bluetooth/l2cap.h      |   15 +-
+ include/net/bluetooth/mgmt.h       |  188 +++--
+ include/net/bluetooth/smp.h        |    2 +-
+ net/bluetooth/hci_conn.c           |   71 +-
+ net/bluetooth/hci_core.c           |  594 ++++++++++---
+ net/bluetooth/hci_event.c          |  476 ++++++++---
+ net/bluetooth/hci_sock.c           |  472 ++++++++--
+ net/bluetooth/hci_sysfs.c          |   53 +-
+ net/bluetooth/l2cap_core.c         |  149 ++--
+ net/bluetooth/l2cap_sock.c         |   15 +-
+ net/bluetooth/lib.c                |   27 +-
+ net/bluetooth/mgmt.c               | 1693 ++++++++++++++++++++++++++----------
+ net/bluetooth/smp.c                |   87 ++-
+ 35 files changed, 3211 insertions(+), 1379 deletions(-)
+ create mode 100644 include/net/bluetooth/hci_mon.h
+$ git reset --hard HEAD^
+HEAD is now at c1379fc Merge remote-tracking branch 'wireless-next/master'
+Merging refs/next/20120221/bluetooth
+$ git merge refs/next/20120221/bluetooth
+Already up-to-date.
+Merging mtd/master (3c3e51d Merge ../linux-2.6 to bring in 3.3-rc fixes already merged)
+$ git merge mtd/master
+Merge made by the 'recursive' strategy.
+ drivers/mtd/chips/cfi_cmdset_0002.c |  240 +++++++++++++++++++++++++++++++++++
+ 1 files changed, 240 insertions(+), 0 deletions(-)
+Merging l2-mtd/master (783dbd6 sfc: mtd: Use MTD_FAIL_ADDR_UNKNOWN instead of 0xffffffff)
+$ git merge l2-mtd/master
+Resolved 'drivers/mtd/chips/cfi_cmdset_0002.c' using previous resolution.
+Removing include/linux/mtd/pmc551.h
+Auto-merging drivers/net/ethernet/sfc/mtd.c
+Auto-merging drivers/mtd/chips/cfi_cmdset_0002.c
+CONFLICT (content): Merge conflict in drivers/mtd/chips/cfi_cmdset_0002.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 90cc30f] Merge remote-tracking branch 'l2-mtd/master'
+$ git diff -M --stat --summary HEAD^..
+ drivers/mtd/Kconfig                    |    3 -
+ drivers/mtd/chips/cfi_cmdset_0001.c    |   66 +-
+ drivers/mtd/chips/cfi_cmdset_0002.c    |   47 +-
+ drivers/mtd/chips/cfi_cmdset_0020.c    |   33 +-
+ drivers/mtd/chips/cfi_util.c           |    6 -
+ drivers/mtd/chips/fwh_lock.h           |    4 +-
+ drivers/mtd/chips/map_absent.c         |   10 +-
+ drivers/mtd/chips/map_ram.c            |   14 +-
+ drivers/mtd/chips/map_rom.c            |   13 +-
+ drivers/mtd/devices/Kconfig            |    7 +
+ drivers/mtd/devices/Makefile           |    1 +
+ drivers/mtd/devices/block2mtd.c        |   28 +-
+ drivers/mtd/devices/doc2000.c          |   24 +-
+ drivers/mtd/devices/doc2001.c          |   21 +-
+ drivers/mtd/devices/doc2001plus.c      |   21 +-
+ drivers/mtd/devices/docg3.c            |   14 +-
+ drivers/mtd/devices/lart.c             |   17 +-
+ drivers/mtd/devices/m25p80.c           |   56 +--
+ drivers/mtd/devices/ms02-nv.c          |   12 +-
+ drivers/mtd/devices/mtd_dataflash.c    |   50 +-
+ drivers/mtd/devices/mtdram.c           |   35 +-
+ drivers/mtd/devices/phram.c            |   43 +-
+ drivers/mtd/devices/pmc551.c           |   99 ++--
+ drivers/mtd/devices/slram.c            |   41 +-
+ drivers/mtd/devices/spear_smi.c        | 1091 +++++++++++++++++++++++++
+ drivers/mtd/devices/sst25l.c           |   40 +-
+ drivers/mtd/inftlcore.c                |    2 +-
+ drivers/mtd/lpddr/lpddr_cmds.c         |   37 +-
+ drivers/mtd/maps/ixp4xx.c              |    5 +-
+ drivers/mtd/maps/uclinux.c             |    2 +-
+ drivers/mtd/maps/vmu-flash.c           |   14 +-
+ drivers/mtd/mtd_blkdevs.c              |    1 +
+ drivers/mtd/mtdblock.c                 |    8 +-
+ drivers/mtd/mtdchar.c                  |    4 +-
+ drivers/mtd/mtdconcat.c                |  104 +--
+ drivers/mtd/mtdcore.c                  |  270 ++++++-
+ drivers/mtd/mtdoops.c                  |    9 +-
+ drivers/mtd/mtdpart.c                  |  141 ++---
+ drivers/mtd/nand/Kconfig               |   20 +
+ drivers/mtd/nand/Makefile              |    1 +
+ drivers/mtd/nand/alauda.c              |    8 +-
+ drivers/mtd/nand/docg4.c               | 1378 ++++++++++++++++++++++++++++++++
+ drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
+ drivers/mtd/nand/nand_base.c           |  180 +++---
+ drivers/mtd/nftlcore.c                 |    7 -
+ drivers/mtd/onenand/onenand_base.c     |   65 +-
+ drivers/mtd/onenand/samsung.c          |    4 +-
+ drivers/mtd/redboot.c                  |    6 +-
+ drivers/mtd/ubi/gluebi.c               |   29 +-
+ drivers/net/ethernet/sfc/mtd.c         |   10 +-
+ fs/jffs2/compr.c                       |    2 +-
+ fs/jffs2/compr_lzo.c                   |    1 -
+ fs/jffs2/compr_zlib.c                  |    6 +-
+ fs/jffs2/os-linux.h                    |    4 +-
+ fs/jffs2/scan.c                        |   22 +-
+ fs/romfs/storage.c                     |    2 +-
+ include/linux/mtd/bbm.h                |    5 +
+ include/linux/mtd/blktrans.h           |    1 +
+ include/linux/mtd/mtd.h                |  301 ++-----
+ include/linux/mtd/nand.h               |    5 +-
+ include/linux/mtd/pmc551.h             |   78 --
+ include/linux/mtd/spear_smi.h          |   62 ++
+ 62 files changed, 3368 insertions(+), 1224 deletions(-)
+ create mode 100644 drivers/mtd/devices/spear_smi.c
+ create mode 100644 drivers/mtd/nand/docg4.c
+ delete mode 100644 include/linux/mtd/pmc551.h
+ create mode 100644 include/linux/mtd/spear_smi.h
+Merging crypto/master (d97055e Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6)
+$ git merge crypto/master
+Resolved 'arch/arm/mach-tegra/fuse.c' using previous resolution.
+Auto-merging crypto/crypto_user.c
+Auto-merging arch/arm/mach-tegra/fuse.c
+CONFLICT (content): Merge conflict in arch/arm/mach-tegra/fuse.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 054fc0a] Merge remote-tracking branch 'crypto/master'
+$ git diff -M --stat --summary HEAD^..
+ arch/arm/mach-tegra/fuse.c                   |    2 +
+ arch/x86/crypto/blowfish_glue.c              |   30 +
+ arch/x86/crypto/serpent-sse2-i586-asm_32.S   |   29 +-
+ arch/x86/crypto/serpent-sse2-x86_64-asm_64.S |   29 +-
+ arch/x86/crypto/serpent_sse2_glue.c          |    1 -
+ arch/x86/crypto/twofish_glue_3way.c          |   48 ++-
+ crypto/algapi.c                              |   35 +
+ crypto/crypto_user.c                         |    2 +-
+ drivers/char/hw_random/tx4939-rng.c          |    5 +-
+ drivers/crypto/Kconfig                       |   11 +
+ drivers/crypto/Makefile                      |    1 +
+ drivers/crypto/caam/caamalg.c                |  126 +++-
+ drivers/crypto/caam/ctrl.c                   |    2 +-
+ drivers/crypto/geode-aes.c                   |    6 +-
+ drivers/crypto/hifn_795x.c                   |    3 +-
+ drivers/crypto/ixp4xx_crypto.c               |    4 +-
+ drivers/crypto/mv_cesa.c                     |   12 +-
+ drivers/crypto/n2_core.c                     |    7 +-
+ drivers/crypto/omap-aes.c                    |    8 +-
+ drivers/crypto/omap-sham.c                   |    4 +
+ drivers/crypto/picoxcell_crypto.c            |   46 +-
+ drivers/crypto/s5p-sss.c                     |    6 +-
+ drivers/crypto/talitos.c                     |    1 +
+ drivers/crypto/tegra-aes.c                   | 1096 ++++++++++++++++++++++++++
+ drivers/crypto/tegra-aes.h                   |  103 +++
+ include/linux/crypto.h                       |    7 +
+ 26 files changed, 1554 insertions(+), 70 deletions(-)
+ create mode 100644 drivers/crypto/tegra-aes.c
+ create mode 100644 drivers/crypto/tegra-aes.h
+Merging sound/for-next (e40bcf0 Merge branch 'for-linus' into for-next)
+$ git merge sound/for-next
+Removing sound/soc/omap/sdp4430.c
+Removing sound/pci/hda/alc_quirks.c
+Removing sound/pci/hda/alc882_quirks.c
+Removing sound/pci/hda/alc880_quirks.c
+Removing sound/pci/hda/alc260_quirks.c
+Auto-merging drivers/base/regmap/regcache.c
+Auto-merging arch/arm/mach-s3c64xx/mach-crag6410-module.c
+Auto-merging arch/arm/mach-omap2/board-omap4panda.c
+Auto-merging arch/arm/mach-omap2/board-4430sdp.c
+Auto-merging arch/arm/mach-ep93xx/core.c
+Merge made by the 'recursive' strategy.
+ Documentation/driver-model/devres.txt          |    3 +
+ Documentation/sound/alsa/HD-Audio-Models.txt   |   79 +-
+ arch/arm/mach-ep93xx/core.c                    |   19 +-
+ arch/arm/mach-ep93xx/include/mach/platform.h   |    2 +-
+ arch/arm/mach-omap2/board-4430sdp.c            |   29 +
+ arch/arm/mach-omap2/board-omap4panda.c         |   60 +-
+ arch/arm/mach-s3c64xx/mach-crag6410-module.c   |    1 +
+ arch/mips/jz4740/board-qi_lb60.c               |    6 +
+ drivers/base/regmap/internal.h                 |    3 +
+ drivers/base/regmap/regcache.c                 |   11 +
+ drivers/base/regmap/regmap.c                   |   58 +
+ drivers/regulator/core.c                       |  108 +
+ include/linux/platform_data/omap-abe-twl6040.h |   49 +
+ include/linux/regmap.h                         |    3 +
+ include/linux/regulator/consumer.h             |   12 +
+ include/sound/pcm.h                            |    4 +
+ include/sound/soc-dapm.h                       |    9 +
+ include/sound/soc.h                            |    2 +
+ include/sound/version.h                        |    2 +-
+ include/sound/wm2200.h                         |   41 +
+ include/sound/wm8962.h                         |    6 +
+ sound/aoa/codecs/onyx.c                        |   13 +-
+ sound/aoa/codecs/tas.c                         |   13 +-
+ sound/core/misc.c                              |    2 +-
+ sound/core/pcm.c                               |   99 +-
+ sound/pci/au88x0/au88x0.h                      |   13 +-
+ sound/pci/au88x0/au88x0_core.c                 |   18 +-
+ sound/pci/au88x0/au88x0_pcm.c                  |  127 +-
+ sound/pci/hda/alc260_quirks.c                  |  968 -------
+ sound/pci/hda/alc880_quirks.c                  | 1707 -----------
+ sound/pci/hda/alc882_quirks.c                  |  866 ------
+ sound/pci/hda/alc_quirks.c                     |  480 ---
+ sound/pci/hda/hda_codec.c                      |   21 +-
+ sound/pci/hda/hda_codec.h                      |    1 +
+ sound/pci/hda/hda_intel.c                      |   28 +-
+ sound/pci/hda/hda_jack.c                       |   16 +
+ sound/pci/hda/hda_jack.h                       |   13 +-
+ sound/pci/hda/hda_local.h                      |    3 +-
+ sound/pci/hda/patch_analog.c                   |   66 +-
+ sound/pci/hda/patch_conexant.c                 |   36 +-
+ sound/pci/hda/patch_realtek.c                  | 1750 ++++++++----
+ sound/pci/hda/patch_sigmatel.c                 |   29 +-
+ sound/pci/hda/patch_via.c                      |   28 +-
+ sound/soc/atmel/atmel-pcm.c                    |    4 +-
+ sound/soc/codecs/Kconfig                       |    4 +
+ sound/soc/codecs/Makefile                      |    2 +
+ sound/soc/codecs/adau1373.c                    |    3 +-
+ sound/soc/codecs/adau1701.c                    |    2 +-
+ sound/soc/codecs/alc5623.c                     |    4 +-
+ sound/soc/codecs/alc5632.c                     |    2 +-
+ sound/soc/codecs/cq93vc.c                      |    2 -
+ sound/soc/codecs/sgtl5000.c                    |   19 +-
+ sound/soc/codecs/sn95031.c                     |    3 +-
+ sound/soc/codecs/tlv320aic3x.c                 |    2 +-
+ sound/soc/codecs/tlv320dac33.c                 |    8 +-
+ sound/soc/codecs/twl4030.c                     |    9 +-
+ sound/soc/codecs/twl6040.c                     |   29 +-
+ sound/soc/codecs/twl6040.h                     |    1 +
+ sound/soc/codecs/wm2200.c                      | 2285 +++++++++++++++
+ sound/soc/codecs/wm2200.h                      | 3674 ++++++++++++++++++++++++
+ sound/soc/codecs/wm5100.c                      |  613 ++---
+ sound/soc/codecs/wm8731.c                      |  109 +-
+ sound/soc/codecs/wm8753.c                      |  186 +-
+ sound/soc/codecs/wm8770.c                      |    3 +-
+ sound/soc/codecs/wm8804.c                      |  148 +-
+ sound/soc/codecs/wm8904.c                      |  840 ++----
+ sound/soc/codecs/wm8904.h                      |   11 +
+ sound/soc/codecs/wm8940.c                      |   14 +-
+ sound/soc/codecs/wm8955.c                      |  247 +-
+ sound/soc/codecs/wm8962.c                      | 1838 +++++--------
+ sound/soc/codecs/wm8971.c                      |   37 +-
+ sound/soc/codecs/wm8974.c                      |   45 +-
+ sound/soc/codecs/wm8978.c                      |  185 +-
+ sound/soc/codecs/wm8978.h                      |    2 +
+ sound/soc/codecs/wm8983.c                      |    5 -
+ sound/soc/codecs/wm8985.c                      |  315 ++-
+ sound/soc/codecs/wm8988.c                      |   29 +-
+ sound/soc/codecs/wm8993.c                      |  599 +++--
+ sound/soc/codecs/wm8994.c                      |   10 +-
+ sound/soc/codecs/wm8995.c                      |    2 +-
+ sound/soc/codecs/wm8996.c                      |   46 +-
+ sound/soc/codecs/wm9090.c                      |  266 +-
+ sound/soc/davinci/davinci-pcm.c                |    4 +-
+ sound/soc/ep93xx/edb93xx.c                     |    4 +-
+ sound/soc/ep93xx/ep93xx-pcm.c                  |    4 +-
+ sound/soc/ep93xx/snappercl15.c                 |    4 +-
+ sound/soc/fsl/fsl_dma.c                        |   10 +-
+ sound/soc/fsl/mpc5200_dma.c                    |   16 +-
+ sound/soc/imx/mx27vis-aic32x4.c                |  104 +
+ sound/soc/jz4740/qi_lb60.c                     |   56 +-
+ sound/soc/kirkwood/kirkwood-dma.c              |    4 +-
+ sound/soc/omap/Kconfig                         |   13 +-
+ sound/soc/omap/Makefile                        |    4 +-
+ sound/soc/omap/omap-abe-twl6040.c              |  349 +++
+ sound/soc/omap/omap-dmic.c                     |    7 +-
+ sound/soc/omap/omap-mcpdm.c                    |    2 +
+ sound/soc/omap/sdp4430.c                       |  279 --
+ sound/soc/s6000/s6000-pcm.c                    |    5 +-
+ sound/soc/samsung/dma.c                        |    2 +-
+ sound/soc/soc-core.c                           |   33 +-
+ sound/soc/soc-dapm.c                           |   86 +-
+ sound/soc/soc-io.c                             |    1 +
+ sound/soc/soc-pcm.c                            |   38 +
+ sound/soc/soc-utils.c                          |   20 +-
+ sound/soc/tegra/tegra_pcm.c                    |    2 +-
+ sound/spi/at73c213.c                           |   12 +-
+ sound/usb/usx2y/usbusx2yaudio.c                |    4 +-
+ sound/usb/usx2y/usx2yhwdeppcm.c                |    2 +-
+ 108 files changed, 11176 insertions(+), 8296 deletions(-)
+ create mode 100644 include/linux/platform_data/omap-abe-twl6040.h
+ create mode 100644 include/sound/wm2200.h
+ delete mode 100644 sound/pci/hda/alc260_quirks.c
+ delete mode 100644 sound/pci/hda/alc880_quirks.c
+ delete mode 100644 sound/pci/hda/alc882_quirks.c
+ delete mode 100644 sound/pci/hda/alc_quirks.c
+ create mode 100644 sound/soc/codecs/wm2200.c
+ create mode 100644 sound/soc/codecs/wm2200.h
+ create mode 100644 sound/soc/omap/omap-abe-twl6040.c
+ delete mode 100644 sound/soc/omap/sdp4430.c
+Merging sound-asoc/for-next (30c66ee Merge branch 'for-3.4' into asoc-next)
+$ git merge sound-asoc/for-next
+Resolved 'sound/soc/codecs/wm5100.c' using previous resolution.
+Auto-merging sound/soc/imx/imx-pcm-dma-mx2.c
+Auto-merging sound/soc/codecs/wm5100.c
+CONFLICT (content): Merge conflict in sound/soc/codecs/wm5100.c
+Auto-merging sound/soc/codecs/twl6040.c
+Auto-merging arch/arm/mach-shmobile/board-mackerel.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master bb918e2] Merge remote-tracking branch 'sound-asoc/for-next'
+$ git diff -M --stat --summary HEAD^..
+ .../devicetree/bindings/sound/alc5632.txt          |   24 +
+ .../bindings/sound/tegra-audio-alc5632.txt         |   57 ++
+ .../devicetree/bindings/vendor-prefixes.txt        |    1 +
+ arch/arm/mach-kirkwood/openrd-setup.c              |    6 +
+ arch/arm/mach-kirkwood/t5325-setup.c               |    6 +
+ arch/arm/mach-shmobile/board-ap4evb.c              |   30 +-
+ arch/arm/mach-shmobile/board-mackerel.c            |   18 +-
+ arch/sh/boards/mach-ecovec24/setup.c               |    4 +-
+ arch/sh/boards/mach-se/7724/setup.c                |    4 +-
+ drivers/base/regmap/regmap.c                       |   15 +
+ include/linux/mfd/wm8994/pdata.h                   |    3 +
+ include/linux/regmap.h                             |    1 +
+ include/sound/control.h                            |    2 +-
+ include/sound/max9768.h                            |   24 +
+ include/sound/sh_fsi.h                             |   12 +-
+ include/sound/soc-dai.h                            |    4 +
+ include/sound/soc-dapm.h                           |   24 +-
+ include/sound/soc.h                                |   42 +-
+ sound/soc/atmel/snd-soc-afeb9260.c                 |   37 +-
+ sound/soc/blackfin/bf5xx-ad1836.c                  |   17 +-
+ sound/soc/blackfin/bf5xx-ad193x.c                  |   17 +-
+ sound/soc/blackfin/bf5xx-ad73311.c                 |   29 +-
+ sound/soc/blackfin/bf5xx-ssm2602.c                 |   20 +-
+ sound/soc/blackfin/bfin-eval-adau1373.c            |   13 +-
+ sound/soc/blackfin/bfin-eval-adau1701.c            |   16 +-
+ sound/soc/blackfin/bfin-eval-adav80x.c             |   13 +-
+ sound/soc/codecs/Kconfig                           |    4 +
+ sound/soc/codecs/Makefile                          |    2 +
+ sound/soc/codecs/ad1836.c                          |    6 +-
+ sound/soc/codecs/ad1980.c                          |    2 +-
+ sound/soc/codecs/adau1373.c                        |    4 +-
+ sound/soc/codecs/ak4104.c                          |   13 +-
+ sound/soc/codecs/ak4535.c                          |   98 ++-
+ sound/soc/codecs/ak4535.h                          |    2 -
+ sound/soc/codecs/ak4642.c                          |    2 +-
+ sound/soc/codecs/ak4671.c                          |    2 +-
+ sound/soc/codecs/alc5623.c                         |    8 +-
+ sound/soc/codecs/alc5632.c                         |  195 +++--
+ sound/soc/codecs/alc5632.h                         |    1 +
+ sound/soc/codecs/cq93vc.c                          |    2 +-
+ sound/soc/codecs/cs4270.c                          |    2 +-
+ sound/soc/codecs/cs4271.c                          |    2 +-
+ sound/soc/codecs/lm4857.c                          |    2 +-
+ sound/soc/codecs/max9768.c                         |  247 ++++++
+ sound/soc/codecs/max98088.c                        |    4 +-
+ sound/soc/codecs/max98095.c                        |    6 +-
+ sound/soc/codecs/max9877.c                         |    2 +-
+ sound/soc/codecs/sn95031.c                         |    2 +-
+ sound/soc/codecs/ssm2602.c                         |    2 +-
+ sound/soc/codecs/stac9766.c                        |    2 +-
+ sound/soc/codecs/tlv320aic23.c                     |    2 +-
+ sound/soc/codecs/tlv320aic26.c                     |    2 +-
+ sound/soc/codecs/tlv320aic32x4.c                   |    2 +-
+ sound/soc/codecs/tlv320aic3x.c                     |   64 +--
+ sound/soc/codecs/tlv320aic3x.h                     |    9 -
+ sound/soc/codecs/tlv320dac33.c                     |    2 +-
+ sound/soc/codecs/tpa6130a2.c                       |    4 +-
+ sound/soc/codecs/twl4030.c                         |   33 +-
+ sound/soc/codecs/twl6040.c                         |    2 +-
+ sound/soc/codecs/uda134x.c                         |    6 +-
+ sound/soc/codecs/wl1273.c                          |    2 +-
+ sound/soc/codecs/wm2200.c                          |    3 +-
+ sound/soc/codecs/wm5100.c                          |   40 +-
+ sound/soc/codecs/wm8737.c                          |    2 +-
+ sound/soc/codecs/wm8770.c                          |    2 +-
+ sound/soc/codecs/wm8776.c                          |    8 +-
+ sound/soc/codecs/wm8904.c                          |   16 +-
+ sound/soc/codecs/wm8940.c                          |    2 +-
+ sound/soc/codecs/wm8958-dsp2.c                     |   14 +-
+ sound/soc/codecs/wm8960.c                          |    2 +-
+ sound/soc/codecs/wm8961.c                          |    2 +-
+ sound/soc/codecs/wm8962.c                          |  230 ++---
+ sound/soc/codecs/wm8988.c                          |  142 +++-
+ sound/soc/codecs/wm8990.c                          |    2 +-
+ sound/soc/codecs/wm8991.c                          |    2 +-
+ sound/soc/codecs/wm8993.c                          |   54 +-
+ sound/soc/codecs/wm8993.h                          |    9 +
+ sound/soc/codecs/wm8994.c                          |  195 ++++-
+ sound/soc/codecs/wm8994.h                          |    5 +-
+ sound/soc/codecs/wm8995.c                          |    2 +-
+ sound/soc/codecs/wm8996.c                          |   72 +--
+ sound/soc/codecs/wm9081.c                          |   80 +--
+ sound/soc/codecs/wm9090.c                          |    8 +-
+ sound/soc/codecs/wm9705.c                          |    2 +-
+ sound/soc/codecs/wm9712.c                          |   16 +-
+ sound/soc/codecs/wm9713.c                          |    2 +-
+ sound/soc/codecs/wm_hubs.c                         |  144 +++-
+ sound/soc/codecs/wm_hubs.h                         |   11 +
+ sound/soc/imx/Kconfig                              |    1 -
+ sound/soc/imx/imx-pcm-dma-mx2.c                    |   20 -
+ sound/soc/kirkwood/kirkwood-openrd.c               |   46 +-
+ sound/soc/kirkwood/kirkwood-t5325.c                |   47 +-
+ sound/soc/mid-x86/mfld_machine.c                   |    2 +-
+ sound/soc/mxs/Kconfig                              |    1 -
+ sound/soc/mxs/mxs-pcm.c                            |    5 -
+ sound/soc/mxs/mxs-pcm.h                            |    4 -
+ sound/soc/mxs/mxs-saif.c                           |   51 +-
+ sound/soc/omap/ams-delta.c                         |    2 +-
+ sound/soc/omap/n810.c                              |   17 +-
+ sound/soc/omap/omap-mcbsp.c                        |    8 +-
+ sound/soc/omap/omap-mcbsp.h                        |    2 +-
+ sound/soc/omap/rx51.c                              |   25 +-
+ sound/soc/pxa/corgi.c                              |   14 +-
+ sound/soc/pxa/magician.c                           |    2 +-
+ sound/soc/pxa/poodle.c                             |   14 +-
+ sound/soc/pxa/pxa2xx-ac97.c                        |   10 +-
+ sound/soc/pxa/spitz.c                              |   14 +-
+ sound/soc/pxa/tosa.c                               |    2 +-
+ sound/soc/samsung/littlemill.c                     |    3 +
+ sound/soc/samsung/neo1973_wm8753.c                 |    4 +-
+ sound/soc/samsung/s3c24xx_simtec.c                 |    6 +-
+ sound/soc/sh/fsi.c                                 |  912 +++++++++++++-------
+ sound/soc/soc-core.c                               |  341 ++++++--
+ sound/soc/soc-dapm.c                               |  309 +++++---
+ sound/soc/soc-io.c                                 |    6 +
+ sound/soc/soc-pcm.c                                |   66 +-
+ sound/soc/tegra/tegra_alc5632.c                    |  130 +++-
+ 117 files changed, 2764 insertions(+), 1546 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/sound/alc5632.txt
+ create mode 100644 Documentation/devicetree/bindings/sound/tegra-audio-alc5632.txt
+ create mode 100644 include/sound/max9768.h
+ create mode 100644 sound/soc/codecs/max9768.c
+Merging cpufreq/next (6c523c6 [CPUFREQ] EXYNOS: Removed useless headers and codes)
+$ git merge cpufreq/next
+Already up-to-date.
+Merging quilt/rr (42d5bdd virtio: update documentation to v0.9.4 of spec)
+$ git merge quilt/rr
+Auto-merging Documentation/kernel-parameters.txt
+Merge made by the 'recursive' strategy.
+ Documentation/kernel-parameters.txt   |    2 +
+ Documentation/virtual/virtio-spec.txt | 1000 ++++++++++++++++++++++++++++++---
+ arch/powerpc/mm/hugetlbpage.c         |    3 +-
+ include/asm-generic/vmlinux.lds.h     |   35 +-
+ include/linux/module.h                |   32 +-
+ include/linux/moduleparam.h           |   58 ++-
+ init/main.c                           |   65 ++-
+ kernel/module.c                       |   37 ++-
+ kernel/params.c                       |   39 +-
+ 9 files changed, 1099 insertions(+), 172 deletions(-)
+Merging input/next (023cea0 Input: tegra-kbc - allow skipping setting up some of GPIO pins)
+$ git merge input/next
+Auto-merging kernel/time/timekeeping.c
+Auto-merging drivers/input/tablet/wacom_wac.c
+Auto-merging drivers/input/tablet/wacom_sys.c
+Auto-merging drivers/input/serio/at32psif.c
+Auto-merging drivers/input/keyboard/samsung-keypad.c
+Auto-merging drivers/input/keyboard/nomadik-ske-keypad.c
+Auto-merging drivers/input/evdev.c
+Auto-merging drivers/hid/hid-ids.h
+Auto-merging drivers/hid/hid-core.c
+Merge made by the 'recursive' strategy.
+ arch/arm/mach-tegra/include/mach/kbc.h      |   13 +-
+ arch/m68k/q40/config.c                      |   13 +
+ drivers/hid/hid-core.c                      |   10 +
+ drivers/hid/hid-ids.h                       |   11 +
+ drivers/input/evdev.c                       |   25 +-
+ drivers/input/keyboard/nomadik-ske-keypad.c |   17 +-
+ drivers/input/keyboard/samsung-keypad.c     |    6 +-
+ drivers/input/keyboard/tegra-kbc.c          |   51 ++-
+ drivers/input/misc/Kconfig                  |    2 +-
+ drivers/input/mouse/Kconfig                 |   17 +
+ drivers/input/mouse/Makefile                |    1 +
+ drivers/input/mouse/synaptics_usb.c         |  568 ++++++++++++++++++++++++
+ drivers/input/serio/at32psif.c              |   22 +-
+ drivers/input/serio/q40kbd.c                |  139 ++++---
+ drivers/input/tablet/wacom_sys.c            |    6 +-
+ drivers/input/tablet/wacom_wac.c            |   28 +-
+ drivers/input/tablet/wacom_wac.h            |    2 +
+ drivers/input/touchscreen/Kconfig           |   32 ++-
+ drivers/input/touchscreen/Makefile          |    5 +-
+ drivers/input/touchscreen/cyttsp_core.c     |  625 +++++++++++++++++++++++++++
+ drivers/input/touchscreen/cyttsp_core.h     |  149 +++++++
+ drivers/input/touchscreen/cyttsp_i2c.c      |  146 +++++++
+ drivers/input/touchscreen/cyttsp_spi.c      |  210 +++++++++
+ include/linux/input.h                       |    2 +
+ include/linux/input/cyttsp.h                |   58 +++
+ kernel/time/timekeeping.c                   |    2 +
+ 26 files changed, 2042 insertions(+), 118 deletions(-)
+ create mode 100644 drivers/input/mouse/synaptics_usb.c
+ create mode 100644 drivers/input/touchscreen/cyttsp_core.c
+ create mode 100644 drivers/input/touchscreen/cyttsp_core.h
+ create mode 100644 drivers/input/touchscreen/cyttsp_i2c.c
+ create mode 100644 drivers/input/touchscreen/cyttsp_spi.c
+ create mode 100644 include/linux/input/cyttsp.h
+Merging input-mt/for-next (7491f3d bcm5974: Add pointer and buttonpad properties)
+$ git merge input-mt/for-next
+Auto-merging include/linux/input.h
+Auto-merging drivers/input/evdev.c
+Merge made by the 'recursive' strategy.
+ drivers/input/evdev.c         |   27 ++++++++++++++++++++++++++-
+ drivers/input/input.c         |    2 +-
+ drivers/input/mouse/bcm5974.c |    1 +
+ include/linux/input.h         |   25 +++++++++++++++++++++++++
+ include/linux/input/mt.h      |    8 ++++++--
+ 5 files changed, 59 insertions(+), 4 deletions(-)
+Merging block/for-next (b3021da Merge branch 'for-3.3/core' into for-next)
+$ git merge block/for-next
+Merge made by the 'recursive' strategy.
+Merging quilt/device-mapper (1e5f0da Commit unwritten data every second to prevent too much building up. In future we might make the commit interval tunable.)
+$ git merge quilt/device-mapper
+Merge made by the 'recursive' strategy.
+ Documentation/ABI/testing/sysfs-block-dm       |   25 +++++++++
+ drivers/md/dm-bufio.c                          |    1 -
+ drivers/md/dm-io.c                             |   23 ++++++---
+ drivers/md/dm-ioctl.c                          |    2 +-
+ drivers/md/dm-mpath.c                          |    4 +-
+ drivers/md/dm-raid.c                           |   69 +++++++++++++++++++++---
+ drivers/md/dm-thin-metadata.c                  |   25 +++++++--
+ drivers/md/dm-thin.c                           |   28 +++++++++-
+ drivers/md/persistent-data/dm-btree-internal.h |    7 +--
+ drivers/md/persistent-data/dm-btree-remove.c   |   28 +++++-----
+ drivers/md/persistent-data/dm-btree.c          |   27 +++++-----
+ 11 files changed, 181 insertions(+), 58 deletions(-)
+ create mode 100644 Documentation/ABI/testing/sysfs-block-dm
+Merging embedded/master (4744b43 embedded: fix vc_translate operator precedence)
+$ git merge embedded/master
+Already up-to-date.
+Merging firmware/master (6e03a20 firmware: speed up request_firmware(), v3)
+$ git merge firmware/master
+Already up-to-date.
+Merging battery/master (913272b Merge git://git.infradead.org/users/cbou/battery-urgent)
+$ git merge battery/master
+Already up-to-date.
+Merging mmc/mmc-next (fcd9bda Merge branch 'v3.4-for-cjb' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into mmc-next)
+$ git merge mmc/mmc-next
+Recorded preimage for 'drivers/mmc/host/sdhci-s3c.c'
+Auto-merging include/linux/mmc/dw_mmc.h
+Auto-merging include/linux/mmc/card.h
+Auto-merging drivers/mmc/host/sdhci-s3c.c
+CONFLICT (content): Merge conflict in drivers/mmc/host/sdhci-s3c.c
+Auto-merging drivers/mmc/host/dw_mmc.c
+Auto-merging drivers/mmc/host/atmel-mci.c
+Auto-merging drivers/mmc/core/mmc.c
+Auto-merging drivers/mmc/core/core.c
+Auto-merging drivers/mmc/card/block.c
+Auto-merging arch/arm/plat-samsung/platformdata.c
+Auto-merging arch/arm/plat-samsung/include/plat/sdhci.h
+Auto-merging arch/arm/plat-samsung/devs.c
+Auto-merging arch/arm/mach-omap2/hsmmc.c
+Auto-merging arch/arm/mach-exynos/mach-universal_c210.c
+Auto-merging arch/arm/mach-exynos/mach-smdkv310.c
+Auto-merging arch/arm/mach-exynos/mach-origen.c
+Auto-merging arch/arm/mach-exynos/mach-nuri.c
+Auto-merging arch/arm/mach-exynos/common.c
+Auto-merging arch/arm/mach-exynos/clock.c
+Auto-merging MAINTAINERS
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+Recorded resolution for 'drivers/mmc/host/sdhci-s3c.c'.
+[master 023f301] Merge remote-tracking branch 'mmc/mmc-next'
+$ git diff -M --stat --summary HEAD^..
+ .../devicetree/bindings/mmc/samsung-sdhci.txt      |   70 +++++
+ MAINTAINERS                                        |    4 +-
+ arch/arm/mach-exynos/clock.c                       |   24 +-
+ arch/arm/mach-exynos/common.c                      |    5 +
+ arch/arm/mach-exynos/mach-armlex4210.c             |    3 -
+ arch/arm/mach-exynos/mach-nuri.c                   |    3 -
+ arch/arm/mach-exynos/mach-origen.c                 |    2 -
+ arch/arm/mach-exynos/mach-smdk4x12.c               |    2 -
+ arch/arm/mach-exynos/mach-smdkv310.c               |    4 -
+ arch/arm/mach-exynos/mach-universal_c210.c         |    2 -
+ arch/arm/mach-omap2/hsmmc.c                        |    1 +
+ arch/arm/mach-omap2/hsmmc.h                        |    2 +
+ arch/arm/plat-samsung/devs.c                       |    4 -
+ arch/arm/plat-samsung/include/plat/sdhci.h         |   35 ++-
+ arch/arm/plat-samsung/platformdata.c               |    2 -
+ drivers/mmc/card/block.c                           |   21 ++-
+ drivers/mmc/core/core.c                            |    6 +
+ drivers/mmc/core/mmc.c                             |   14 +
+ drivers/mmc/host/Kconfig                           |   25 ++
+ drivers/mmc/host/Makefile                          |    2 +
+ drivers/mmc/host/atmel-mci.c                       |   23 +-
+ drivers/mmc/host/dw_mmc-pci.c                      |  158 +++++++++++
+ drivers/mmc/host/dw_mmc-pltfm.c                    |  134 ++++++++++
+ drivers/mmc/host/dw_mmc.c                          |  280 +++++++++++---------
+ drivers/mmc/host/dw_mmc.h                          |    7 +
+ drivers/mmc/host/omap_hsmmc.c                      |    8 +-
+ drivers/mmc/host/sdhci-of-esdhc.c                  |   37 +++-
+ drivers/mmc/host/sdhci-s3c.c                       |  235 ++++++++++++++++-
+ drivers/mmc/host/sdhci-tegra.c                     |  100 ++++++-
+ drivers/mmc/host/sdhci.c                           |    6 +
+ drivers/mmc/host/sdhci.h                           |    2 +
+ include/linux/mmc/card.h                           |    2 +
+ include/linux/mmc/dw_mmc.h                         |    8 +-
+ include/linux/mmc/mmc.h                            |    3 +
+ 34 files changed, 1018 insertions(+), 216 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
+ create mode 100644 drivers/mmc/host/dw_mmc-pci.c
+ create mode 100644 drivers/mmc/host/dw_mmc-pltfm.c
+Merging kgdb/kgdb-next (880ba69 lib: rename pack_hex_byte() to hex_byte_pack())
+$ git merge kgdb/kgdb-next
+Merge made by the 'recursive' strategy.
+Merging slab/for-next (96438bc Merge branch 'slub/cleanups' into for-next)
+$ git merge slab/for-next
+Merge made by the 'recursive' strategy.
+ include/linux/slub_def.h |    7 +-
+ mm/slab.c                |    5 +-
+ mm/slub.c                |  192 ++++++++++++++++++++++++++--------------------
+ 3 files changed, 116 insertions(+), 88 deletions(-)
+Merging uclinux/for-next (5e442a4 Revert "proc: fix races against execve() of /proc/PID/fd**")
+$ git merge uclinux/for-next
+Already up-to-date.
+Merging md/for-next (fae8cc5 md/raid10: fix handling of error on last working device in array.)
+$ git merge md/for-next
+Merge made by the 'recursive' strategy.
+ drivers/md/raid1.c  |    2 +-
+ drivers/md/raid10.c |   37 +++++++++++++++++++++++++++----------
+ 2 files changed, 28 insertions(+), 11 deletions(-)
+Merging mfd/for-next (a0afdbc mfd/Input/ASoC: twl6040 kconfig fixes)
+$ git merge mfd/for-next
+Auto-merging sound/soc/codecs/twl6040.c
+Auto-merging sound/soc/codecs/Kconfig
+Auto-merging drivers/mfd/Kconfig
+Auto-merging drivers/input/misc/Kconfig
+Auto-merging drivers/hwmon/mc13783-adc.c
+Auto-merging arch/arm/mach-omap2/board-omap4panda.c
+Auto-merging arch/arm/mach-omap2/board-4430sdp.c
+Merge made by the 'recursive' strategy.
+ arch/arm/mach-omap2/board-4430sdp.c                |   12 +-
+ arch/arm/mach-omap2/board-generic.c                |    2 +-
+ arch/arm/mach-omap2/board-omap4panda.c             |    4 +-
+ arch/arm/mach-omap2/twl-common.c                   |   37 +-
+ arch/arm/mach-omap2/twl-common.h                   |   10 +-
+ .../mach-ux500/include/mach/irqs-board-mop500.h    |    2 +-
+ drivers/cpufreq/db8500-cpufreq.c                   |   13 +-
+ drivers/gpio/gpio-stmpe.c                          |   41 +-
+ drivers/hwmon/mc13783-adc.c                        |    2 +-
+ drivers/input/misc/Kconfig                         |    3 +-
+ drivers/input/misc/twl6040-vibra.c                 |    4 +-
+ drivers/input/touchscreen/mc13783_ts.c             |   11 +-
+ drivers/mfd/Kconfig                                |   26 +-
+ drivers/mfd/Makefile                               |    1 +
+ drivers/mfd/ab5500-core.c                          |    1 -
+ drivers/mfd/ab8500-core.c                          |  301 ++++++--
+ drivers/mfd/ab8500-i2c.c                           |   15 +-
+ drivers/mfd/asic3.c                                |    6 +
+ drivers/mfd/da9052-i2c.c                           |    7 +-
+ drivers/mfd/da9052-spi.c                           |    9 +-
+ drivers/mfd/db8500-prcmu.c                         |  927 ++++++++++++++++----
+ drivers/mfd/dbx500-prcmu-regs.h                    |  128 ++-
+ drivers/mfd/mc13xxx-core.c                         |   11 +-
+ drivers/mfd/s5m-core.c                             |   49 +-
+ drivers/mfd/s5m-irq.c                              |   14 +-
+ drivers/mfd/stmpe.c                                |  134 ++-
+ drivers/mfd/tps65217.c                             |  242 +++++
+ drivers/mfd/tps65910-irq.c                         |   11 +
+ drivers/mfd/tps65910.c                             |    2 +-
+ drivers/mfd/twl-core.c                             |   66 +-
+ drivers/mfd/twl4030-irq.c                          |   26 +-
+ drivers/mfd/twl6040-core.c                         |  155 +++--
+ drivers/mfd/wm8350-irq.c                           |    1 -
+ drivers/mfd/wm8994-core.c                          |   16 +-
+ drivers/mfd/wm8994-regmap.c                        |    1 +
+ include/linux/i2c/twl.h                            |   12 -
+ include/linux/mfd/abx500.h                         |    7 -
+ include/linux/mfd/abx500/ab8500-gpio.h             |    4 +-
+ include/linux/mfd/abx500/ab8500-sysctrl.h          |   43 +
+ include/linux/mfd/abx500/ab8500.h                  |  114 +++-
+ include/linux/mfd/db8500-prcmu.h                   |  142 +++-
+ include/linux/mfd/dbx500-prcmu.h                   |  359 +++++++-
+ include/linux/mfd/mc13xxx.h                        |   16 +-
+ include/linux/mfd/stmpe.h                          |    1 +
+ include/linux/mfd/tps65217.h                       |  283 ++++++
+ include/linux/mfd/twl6040.h                        |   29 +
+ include/linux/regulator/ab8500.h                   |   70 ++-
+ sound/soc/codecs/Kconfig                           |    3 +-
+ sound/soc/codecs/twl6040.c                         |    3 +-
+ 49 files changed, 2799 insertions(+), 577 deletions(-)
+ create mode 100644 drivers/mfd/tps65217.c
+ create mode 100644 include/linux/mfd/tps65217.h
+Merging drm/drm-next (019d96c drm: add some caps for userspace to discover more info for dumb KMS driver (v2))
+$ git merge drm/drm-next
+Auto-merging drivers/gpu/drm/radeon/r100.c
+Auto-merging drivers/gpu/drm/radeon/evergreen.c
+Auto-merging drivers/gpu/drm/i915/intel_dp.c
+Auto-merging drivers/gpu/drm/i915/intel_display.c
+Removing drivers/gpu/drm/i915/i915_mem.c
+Merge made by the 'recursive' strategy.
+ drivers/char/agp/intel-agp.c                |    1 +
+ drivers/gpu/drm/drm_crtc.c                  |  201 +++---
+ drivers/gpu/drm/drm_crtc_helper.c           |   12 +-
+ drivers/gpu/drm/drm_drv.c                   |   12 +-
+ drivers/gpu/drm/drm_edid.c                  |    7 +-
+ drivers/gpu/drm/drm_fb_helper.c             |   88 +--
+ drivers/gpu/drm/drm_ioctl.c                 |    8 +
+ drivers/gpu/drm/drm_modes.c                 |    2 -
+ drivers/gpu/drm/drm_pci.c                   |    2 -
+ drivers/gpu/drm/exynos/exynos_drm_fbdev.c   |   28 +-
+ drivers/gpu/drm/gma500/framebuffer.c        |   11 +-
+ drivers/gpu/drm/gma500/intel_gmbus.c        |    2 +-
+ drivers/gpu/drm/gma500/psb_drv.c            |    2 +
+ drivers/gpu/drm/gma500/psb_intel_sdvo.c     |   28 +-
+ drivers/gpu/drm/i2c/ch7006_drv.c            |    5 +-
+ drivers/gpu/drm/i810/i810_dma.c             |    2 +
+ drivers/gpu/drm/i915/Makefile               |    2 +-
+ drivers/gpu/drm/i915/i915_debugfs.c         |  242 ++++----
+ drivers/gpu/drm/i915/i915_dma.c             |   21 +-
+ drivers/gpu/drm/i915/i915_drv.c             |    8 +-
+ drivers/gpu/drm/i915/i915_drv.h             |   68 +-
+ drivers/gpu/drm/i915/i915_gem.c             |  398 +++++-------
+ drivers/gpu/drm/i915/i915_gem_evict.c       |    2 +-
+ drivers/gpu/drm/i915/i915_gem_execbuffer.c  |  150 +++--
+ drivers/gpu/drm/i915/i915_gem_gtt.c         |    2 +-
+ drivers/gpu/drm/i915/i915_gem_tiling.c      |    4 +-
+ drivers/gpu/drm/i915/i915_irq.c             |  116 ++--
+ drivers/gpu/drm/i915/i915_mem.c             |  387 -----------
+ drivers/gpu/drm/i915/i915_reg.h             |   30 +-
+ drivers/gpu/drm/i915/intel_acpi.c           |    2 +-
+ drivers/gpu/drm/i915/intel_bios.c           |    2 +-
+ drivers/gpu/drm/i915/intel_display.c        |  299 ++++++---
+ drivers/gpu/drm/i915/intel_dp.c             |   13 +-
+ drivers/gpu/drm/i915/intel_drv.h            |    1 +
+ drivers/gpu/drm/i915/intel_fb.c             |    6 +-
+ drivers/gpu/drm/i915/intel_i2c.c            |    4 +-
+ drivers/gpu/drm/i915/intel_modes.c          |   28 +-
+ drivers/gpu/drm/i915/intel_overlay.c        |    6 +-
+ drivers/gpu/drm/i915/intel_panel.c          |    4 +-
+ drivers/gpu/drm/i915/intel_ringbuffer.c     |   97 +---
+ drivers/gpu/drm/i915/intel_ringbuffer.h     |   20 +-
+ drivers/gpu/drm/i915/intel_sdvo.c           |   30 +-
+ drivers/gpu/drm/i915/intel_sprite.c         |    4 +-
+ drivers/gpu/drm/mga/mga_dma.c               |    2 +
+ drivers/gpu/drm/nouveau/nouveau_display.c   |   20 +-
+ drivers/gpu/drm/nouveau/nouveau_fbcon.c     |    6 +-
+ drivers/gpu/drm/nouveau/nouveau_state.c     |    2 +
+ drivers/gpu/drm/r128/r128_drv.c             |    1 +
+ drivers/gpu/drm/radeon/Makefile             |    2 +-
+ drivers/gpu/drm/radeon/atombios_crtc.c      |   20 +-
+ drivers/gpu/drm/radeon/atombios_i2c.c       |  139 ++++
+ drivers/gpu/drm/radeon/evergreen.c          |   31 +
+ drivers/gpu/drm/radeon/evergreen_blit_kms.c |   12 +-
+ drivers/gpu/drm/radeon/evergreen_cs.c       |  958 +++++++++++++++++++++++++--
+ drivers/gpu/drm/radeon/evergreend.h         |  377 +++++++++++
+ drivers/gpu/drm/radeon/r100.c               |   58 +-
+ drivers/gpu/drm/radeon/r200.c               |   29 +-
+ drivers/gpu/drm/radeon/r600_blit_kms.c      |   15 +-
+ drivers/gpu/drm/radeon/r600_cs.c            |  282 +++++++--
+ drivers/gpu/drm/radeon/r600d.h              |   20 +
+ drivers/gpu/drm/radeon/radeon.h             |   13 +
+ drivers/gpu/drm/radeon/radeon_benchmark.c   |   12 +-
+ drivers/gpu/drm/radeon/radeon_blit_common.h |   44 ++
+ drivers/gpu/drm/radeon/radeon_cp.c          |    2 +
+ drivers/gpu/drm/radeon/radeon_display.c     |   73 +--
+ drivers/gpu/drm/radeon/radeon_drv.c         |    5 +-
+ drivers/gpu/drm/radeon/radeon_fb.c          |    6 +-
+ drivers/gpu/drm/radeon/radeon_i2c.c         |   27 +-
+ drivers/gpu/drm/radeon/radeon_kms.c         |    2 +
+ drivers/gpu/drm/radeon/radeon_object.c      |   46 ++
+ drivers/gpu/drm/radeon/reg_srcs/cayman      |   11 +-
+ drivers/gpu/drm/radeon/reg_srcs/evergreen   |   11 +-
+ drivers/gpu/drm/radeon/reg_srcs/r600        |   19 +-
+ drivers/gpu/drm/sis/sis_drv.c               |    2 +
+ drivers/gpu/drm/via/via_map.c               |    2 +
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c         |   55 ++
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h         |   10 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c     |   15 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_fb.c          |   22 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_fence.c       |  252 ++++---
+ drivers/gpu/drm/vmwgfx/vmwgfx_fence.h       |    9 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.c         |   91 +++-
+ drivers/gpu/drm/vmwgfx/vmwgfx_kms.h         |    8 +
+ drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c         |    4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c        |   38 +-
+ include/drm/drm.h                           |    2 +
+ include/drm/drm_crtc.h                      |   16 +-
+ include/drm/drm_fb_helper.h                 |    2 -
+ include/drm/i915_drm.h                      |    1 +
+ include/drm/radeon_drm.h                    |   24 +-
+ 90 files changed, 3319 insertions(+), 1836 deletions(-)
+ delete mode 100644 drivers/gpu/drm/i915/i915_mem.c
+ create mode 100644 drivers/gpu/drm/radeon/atombios_i2c.c
+ create mode 100644 drivers/gpu/drm/radeon/radeon_blit_common.h
+Merging fbdev/fbdev-next (94f61a7 i740fb: fix compile error when CONFIG_MTRR is not selected)
+$ git merge fbdev/fbdev-next
+Merge made by the 'recursive' strategy.
+ arch/arm/plat-samsung/include/plat/regs-fb.h       |    9 +
+ drivers/video/Kconfig                              |   14 +-
+ drivers/video/Makefile                             |    3 +
+ drivers/video/atmel_lcdfb.c                        |   12 +-
+ drivers/video/au1100fb.c                           |   32 +-
+ drivers/video/au1200fb.c                           |    9 +-
+ drivers/video/bf537-lq035.c                        |   12 +-
+ drivers/video/bf54x-lq043fb.c                      |    4 +-
+ drivers/video/bfin-lq035q1-fb.c                    |    8 +-
+ drivers/video/bfin_adv7393fb.c                     |    5 +-
+ drivers/video/da8xx-fb.c                           |   37 +-
+ drivers/video/exynos/Kconfig                       |   37 +
+ drivers/video/exynos/Makefile                      |    8 +
+ drivers/video/exynos/exynos_dp_core.c              | 1058 ++++++++++++++++
+ drivers/video/exynos/exynos_dp_core.h              |  206 +++
+ drivers/video/exynos/exynos_dp_reg.c               | 1173 +++++++++++++++++
+ drivers/video/exynos/exynos_dp_reg.h               |  335 +++++
+ drivers/video/exynos/exynos_mipi_dsi.c             |  600 +++++++++
+ drivers/video/exynos/exynos_mipi_dsi_common.c      |  896 +++++++++++++
+ drivers/video/exynos/exynos_mipi_dsi_common.h      |   46 +
+ drivers/video/exynos/exynos_mipi_dsi_lowlevel.c    |  618 +++++++++
+ drivers/video/exynos/exynos_mipi_dsi_lowlevel.h    |  112 ++
+ drivers/video/exynos/exynos_mipi_dsi_regs.h        |  149 +++
+ drivers/video/exynos/s6e8ax0.c                     |  898 +++++++++++++
+ drivers/video/exynos/s6e8ax0.h                     |   21 +
+ drivers/video/fbmem.c                              |   18 +-
+ drivers/video/i740_reg.h                           |  309 +++++
+ drivers/video/i740fb.c                             | 1337 ++++++++++++++++++++
+ drivers/video/msm/mddi_client_nt35399.c            |    7 +-
+ drivers/video/msm/mddi_client_toshiba.c            |    7 +-
+ drivers/video/omap/lcd_inn1610.c                   |   10 +-
+ drivers/video/omap/lcd_mipid.c                     |   14 +-
+ drivers/video/omap2/displays/panel-acx565akm.c     |   13 +-
+ .../omap2/displays/panel-lgphilips-lb035q02.c      |   12 +-
+ .../omap2/displays/panel-nec-nl8048hl11-01b.c      |   12 +-
+ drivers/video/omap2/displays/panel-taal.c          |    4 +-
+ .../video/omap2/displays/panel-tpo-td043mtea1.c    |   24 +-
+ drivers/video/riva/fbdev.c                         |    5 +-
+ drivers/video/s3c-fb.c                             |   76 +-
+ drivers/video/udlfb.c                              |    2 +-
+ include/linux/fb.h                                 |    1 +
+ include/video/exynos_dp.h                          |  131 ++
+ include/video/exynos_mipi_dsim.h                   |  359 ++++++
+ 43 files changed, 8458 insertions(+), 185 deletions(-)
+ create mode 100644 drivers/video/exynos/Kconfig
+ create mode 100644 drivers/video/exynos/Makefile
+ create mode 100644 drivers/video/exynos/exynos_dp_core.c
+ create mode 100644 drivers/video/exynos/exynos_dp_core.h
+ create mode 100644 drivers/video/exynos/exynos_dp_reg.c
+ create mode 100644 drivers/video/exynos/exynos_dp_reg.h
+ create mode 100644 drivers/video/exynos/exynos_mipi_dsi.c
+ create mode 100644 drivers/video/exynos/exynos_mipi_dsi_common.c
+ create mode 100644 drivers/video/exynos/exynos_mipi_dsi_common.h
+ create mode 100644 drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
+ create mode 100644 drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
+ create mode 100644 drivers/video/exynos/exynos_mipi_dsi_regs.h
+ create mode 100644 drivers/video/exynos/s6e8ax0.c
+ create mode 100644 drivers/video/exynos/s6e8ax0.h
+ create mode 100644 drivers/video/i740_reg.h
+ create mode 100644 drivers/video/i740fb.c
+ create mode 100644 include/video/exynos_dp.h
+ create mode 100644 include/video/exynos_mipi_dsim.h
+Merging viafb/viafb-next (c572c8b viafb: NULL dereference on allocation failure in query_edid())
+$ git merge viafb/viafb-next
+Merge made by the 'recursive' strategy.
+ drivers/video/via/Makefile         |    5 ++-
+ drivers/video/via/chip.h           |    2 -
+ drivers/video/via/dvi.c            |    5 +-
+ drivers/video/via/dvi.h            |    3 +-
+ drivers/video/via/hw.c             |   85 +++++++++++++++---------------
+ drivers/video/via/hw.h             |    3 +-
+ drivers/video/via/lcd.c            |   18 +++---
+ drivers/video/via/lcd.h            |    3 +-
+ drivers/video/via/via_aux.c        |   88 +++++++++++++++++++++++++++++++
+ drivers/video/via/via_aux.h        |   93 +++++++++++++++++++++++++++++++++
+ drivers/video/via/via_aux_ch7301.c |   50 ++++++++++++++++++
+ drivers/video/via/via_aux_edid.c   |  100 ++++++++++++++++++++++++++++++++++++
+ drivers/video/via/via_aux_sii164.c |   54 +++++++++++++++++++
+ drivers/video/via/via_aux_vt1621.c |   44 ++++++++++++++++
+ drivers/video/via/via_aux_vt1622.c |   50 ++++++++++++++++++
+ drivers/video/via/via_aux_vt1625.c |   50 ++++++++++++++++++
+ drivers/video/via/via_aux_vt1631.c |   46 ++++++++++++++++
+ drivers/video/via/via_aux_vt1632.c |   54 +++++++++++++++++++
+ drivers/video/via/via_aux_vt1636.c |   46 ++++++++++++++++
+ drivers/video/via/via_i2c.c        |   10 +++-
+ drivers/video/via/viafbdev.c       |   53 ++++++++++++++++---
+ drivers/video/via/viafbdev.h       |    6 ++
+ 22 files changed, 800 insertions(+), 68 deletions(-)
+ create mode 100644 drivers/video/via/via_aux.c
+ create mode 100644 drivers/video/via/via_aux.h
+ create mode 100644 drivers/video/via/via_aux_ch7301.c
+ create mode 100644 drivers/video/via/via_aux_edid.c
+ create mode 100644 drivers/video/via/via_aux_sii164.c
+ create mode 100644 drivers/video/via/via_aux_vt1621.c
+ create mode 100644 drivers/video/via/via_aux_vt1622.c
+ create mode 100644 drivers/video/via/via_aux_vt1625.c
+ create mode 100644 drivers/video/via/via_aux_vt1631.c
+ create mode 100644 drivers/video/via/via_aux_vt1632.c
+ create mode 100644 drivers/video/via/via_aux_vt1636.c
+Merging omap_dss2/for-next (9a90168 OMAPDSS: HDMI: Disable DDC internal pull up)
+$ git merge omap_dss2/for-next
+Already up-to-date.
+Merging regulator/for-next (13e8a7a Merge branch 'regulator-core' into regulator-next)
+$ git merge regulator/for-next
+Auto-merging include/linux/i2c/twl.h
+Auto-merging drivers/mfd/twl-core.c
+Merge made by the 'recursive' strategy.
+ Documentation/driver-model/devres.txt  |    2 +
+ arch/arm/mach-u300/i2c.c               |    2 -
+ drivers/mfd/twl-core.c                 |   16 +-
+ drivers/regulator/Kconfig              |   35 ++-
+ drivers/regulator/Makefile             |    5 +
+ drivers/regulator/core.c               |   84 ++---
+ drivers/regulator/db8500-prcmu.c       |  118 ++----
+ drivers/regulator/dbx500-prcmu.c       |  241 +++++++++
+ drivers/regulator/dbx500-prcmu.h       |   63 +++
+ drivers/regulator/max8649.c            |    2 +-
+ drivers/regulator/max8997.c            |    8 +-
+ drivers/regulator/s5m8767.c            |  832 ++++++++++++++++++++++++++++++++
+ drivers/regulator/tps62360-regulator.c |  472 ++++++++++++++++++
+ drivers/regulator/tps65023-regulator.c |    4 -
+ drivers/regulator/tps65217-regulator.c |  493 +++++++++++++++++++
+ drivers/regulator/tps65910-regulator.c |  289 ++++++++++--
+ drivers/regulator/twl-regulator.c      |   53 ++-
+ drivers/regulator/wm8350-regulator.c   |    4 +-
+ drivers/regulator/wm8994-regulator.c   |    4 +-
+ include/linux/i2c/twl.h                |    7 +
+ include/linux/mfd/tps65910.h           |    8 +
+ include/linux/regulator/consumer.h     |   12 +-
+ include/linux/regulator/driver.h       |    6 +-
+ include/linux/regulator/machine.h      |    2 -
+ include/linux/regulator/tps62360.h     |   57 +++
+ 25 files changed, 2611 insertions(+), 208 deletions(-)
+ create mode 100644 drivers/regulator/dbx500-prcmu.c
+ create mode 100644 drivers/regulator/dbx500-prcmu.h
+ create mode 100644 drivers/regulator/s5m8767.c
+ create mode 100644 drivers/regulator/tps62360-regulator.c
+ create mode 100644 drivers/regulator/tps65217-regulator.c
+ create mode 100644 include/linux/regulator/tps62360.h
+Merging security/next (b0d5de4 IMA: fix audit res field to indicate 1 for success and 0 for failure)
+$ git merge security/next
+Auto-merging mm/shmem.c
+Auto-merging kernel/fork.c
+Auto-merging include/net/sock.h
+Auto-merging fs/super.c
+Auto-merging fs/nfs/idmap.c
+Auto-merging fs/nfs/client.c
+Auto-merging drivers/target/iscsi/iscsi_target.c
+Merge made by the 'recursive' strategy.
+ Documentation/networking/dns_resolver.txt |    4 +
+ Documentation/security/00-INDEX           |    2 +
+ Documentation/security/Yama.txt           |   65 ++++++
+ Documentation/security/keys.txt           |    4 +
+ drivers/char/tpm/Kconfig                  |    1 -
+ drivers/char/tpm/tpm.c                    |    3 +-
+ drivers/char/tpm/tpm.h                    |    2 +
+ drivers/char/tpm/tpm_tis.c                |   17 +-
+ drivers/net/macvtap.c                     |    1 +
+ drivers/target/iscsi/iscsi_target.c       |    1 +
+ drivers/target/iscsi/iscsi_target_login.c |    1 +
+ fs/cifs/cifsacl.c                         |    1 +
+ fs/nfs/client.c                           |    1 +
+ fs/nfs/idmap.c                            |    1 +
+ fs/proc/proc_sysctl.c                     |    2 +
+ fs/quota/dquot.c                          |    1 +
+ fs/super.c                                |    1 +
+ include/linux/key.h                       |    1 +
+ include/linux/prctl.h                     |    7 +
+ include/linux/security.h                  |   80 ++++----
+ include/net/sock.h                        |    2 +
+ ipc/msgutil.c                             |    2 +
+ kernel/cred.c                             |    1 +
+ kernel/exit.c                             |    1 +
+ kernel/fork.c                             |    3 +-
+ kernel/sched/core.c                       |    1 +
+ kernel/sysctl.c                           |    1 +
+ mm/mmap.c                                 |   17 ++-
+ mm/mprotect.c                             |    2 +-
+ mm/mremap.c                               |    2 +-
+ mm/shmem.c                                |    4 +-
+ mm/swapfile.c                             |    4 +-
+ net/dns_resolver/dns_key.c                |    1 +
+ security/Kconfig                          |    6 +
+ security/Makefile                         |    2 +
+ security/capability.c                     |    5 +
+ security/commoncap.c                      |    1 +
+ security/integrity/ima/Kconfig            |    2 +-
+ security/integrity/ima/ima_audit.c        |    2 +-
+ security/integrity/ima/ima_policy.c       |    3 +-
+ security/keys/keyctl.c                    |   15 ++-
+ security/security.c                       |   21 +--
+ security/selinux/hooks.c                  |    2 +
+ security/smack/smack_lsm.c                |    3 +
+ security/yama/Kconfig                     |   13 ++
+ security/yama/Makefile                    |    3 +
+ security/yama/yama_lsm.c                  |  323 +++++++++++++++++++++++++++++
+ 47 files changed, 561 insertions(+), 77 deletions(-)
+ create mode 100644 Documentation/security/Yama.txt
+ create mode 100644 security/yama/Kconfig
+ create mode 100644 security/yama/Makefile
+ create mode 100644 security/yama/yama_lsm.c
+Merging selinux/master (a9ab18a selinux: include flow.h where used rather than get it indirectly)
+$ git merge selinux/master
+Auto-merging security/selinux/selinuxfs.c
+Auto-merging net/xfrm/xfrm_policy.c
+Merge made by the 'recursive' strategy.
+ net/xfrm/xfrm_policy.c          |    1 +
+ security/selinux/include/xfrm.h |    2 ++
+ security/selinux/selinuxfs.c    |    3 ++-
+ 3 files changed, 5 insertions(+), 1 deletions(-)
+Merging lblnet/master (7e27d6e Linux 2.6.35-rc3)
+$ git merge lblnet/master
+Already up-to-date.
+Merging watchdog/linux-next (1776b7d watchdog: fix error in probe() of s3c2410_wdt (reset at booting))
+$ git merge watchdog/linux-next
+Merge made by the 'recursive' strategy.
+ drivers/watchdog/hpwdt.c       |    5 ++-
+ drivers/watchdog/s3c2410_wdt.c |   57 +++++++++++++++++++++------------------
+ 2 files changed, 34 insertions(+), 28 deletions(-)
+Merging dwmw2-iommu/master (c3b92c8 Linux 3.1)
+$ git merge dwmw2-iommu/master
+Already up-to-date.
+Merging iommu/next (48d2116 Merge branches 'iommu/fixes' and 'arm/tegra' into next)
+$ git merge iommu/next
+Merge made by the 'recursive' strategy.
+ arch/arm/mach-tegra/include/mach/smmu.h |   63 ++
+ drivers/iommu/Kconfig                   |   20 +
+ drivers/iommu/Makefile                  |    2 +
+ drivers/iommu/tegra-gart.c              |  451 ++++++++++++++
+ drivers/iommu/tegra-smmu.c              | 1034 +++++++++++++++++++++++++++++++
+ 5 files changed, 1570 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-tegra/include/mach/smmu.h
+ create mode 100644 drivers/iommu/tegra-gart.c
+ create mode 100644 drivers/iommu/tegra-smmu.c
+Merging osd/linux-next (0aa436b exofs: Cap on the memcpy() size)
+$ git merge osd/linux-next
+Auto-merging fs/exofs/super.c
+Merge made by the 'recursive' strategy.
+ drivers/scsi/osd/osd_uld.c |    4 ++--
+ fs/exofs/super.c           |    7 ++++---
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+Merging jc_docs/docs-next (5c050fb docs: update the development process document)
+$ git merge jc_docs/docs-next
+Already up-to-date.
+Merging trivial/for-next (202e011 power: bq27x00: Fix typos in comment)
+$ git merge trivial/for-next
+Auto-merging sound/pci/hda/patch_conexant.c
+Auto-merging fs/cramfs/inode.c
+Auto-merging drivers/scsi/qla2xxx/qla_bsg.c
+Auto-merging drivers/scsi/pm8001/pm8001_hwi.c
+Auto-merging drivers/power/bq27x00_battery.c
+Auto-merging drivers/net/wireless/zd1211rw/zd_mac.c
+Auto-merging drivers/net/wireless/hostap/hostap_hw.c
+Auto-merging drivers/infiniband/ulp/srpt/ib_srpt.c
+Auto-merging drivers/hwmon/tmp401.c
+Auto-merging drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+Auto-merging arch/arm/mm/init.c
+Auto-merging arch/arm/mach-spear3xx/spear300.c
+Auto-merging arch/arm/mach-bcmring/dma.c
+Auto-merging Documentation/kernel-parameters.txt
+Merge made by the 'recursive' strategy.
+ Documentation/00-INDEX                             |    4 +-
+ Documentation/device-mapper/thin-provisioning.txt  |    2 +-
+ .../filesystems/ramfs-rootfs-initramfs.txt         |    2 +-
+ Documentation/kernel-parameters.txt                |    6 ++--
+ Documentation/scsi/scsi-generic.txt                |    2 +-
+ Documentation/target/tcm_mod_builder.py            |    2 +-
+ Documentation/trace/events-power.txt               |    2 +-
+ Documentation/usb/mtouchusb.txt                    |    2 +-
+ Documentation/usb/power-management.txt             |    2 +-
+ Documentation/usb/proc_usb_info.txt                |    2 +-
+ Documentation/vm/cleancache.txt                    |    2 +-
+ Documentation/vm/unevictable-lru.txt               |    6 ++--
+ Documentation/watchdog/watchdog-kernel-api.txt     |    2 +-
+ arch/arm/mach-bcmring/dma.c                        |    1 -
+ arch/arm/mach-ks8695/leds.c                        |    1 -
+ arch/arm/mach-omap1/lcd_dma.c                      |    2 +-
+ arch/arm/mach-orion5x/db88f5281-setup.c            |    4 +-
+ arch/arm/mach-orion5x/rd88f5182-setup.c            |    4 +-
+ arch/arm/mach-spear3xx/spear300.c                  |    2 +-
+ arch/arm/mach-spear3xx/spear310.c                  |    2 +-
+ arch/arm/mach-spear3xx/spear320.c                  |    2 +-
+ arch/arm/mm/init.c                                 |    1 -
+ arch/arm/plat-s3c24xx/pm-simtec.c                  |    2 +-
+ arch/ia64/xen/irq_xen.c                            |    2 +-
+ arch/mips/bcm63xx/setup.c                          |    2 +-
+ arch/powerpc/include/asm/keylargo.h                |    2 +-
+ arch/score/Kconfig.debug                           |    2 +-
+ arch/sh/drivers/pci/pci-sh7780.c                   |    2 +-
+ arch/x86/platform/scx200/scx200_32.c               |   24 +++++++++----------
+ drivers/block/nvme.c                               |    1 -
+ drivers/char/nvram.c                               |    2 +-
+ drivers/char/rtc.c                                 |    4 +-
+ drivers/char/tlclk.c                               |    2 +-
+ drivers/char/viotape.c                             |    2 +-
+ drivers/dma/iop-adma.c                             |    2 +-
+ drivers/gpu/drm/gma500/psb_intel_lvds.c            |    9 +++----
+ drivers/gpu/drm/radeon/rv515.c                     |    4 +-
+ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c                |    2 +-
+ drivers/hwmon/tmp401.c                             |    2 +-
+ drivers/infiniband/ulp/srpt/ib_srpt.c              |    2 +-
+ drivers/iommu/intel-iommu.c                        |    2 +-
+ drivers/macintosh/mediabay.c                       |    2 +-
+ drivers/media/dvb/mantis/mantis_hif.c              |    2 +-
+ drivers/media/radio/radio-sf16fmr2.c               |    2 +-
+ drivers/media/video/davinci/dm355_ccdc.c           |    2 +-
+ drivers/mmc/host/s3cmci.c                          |    4 +-
+ drivers/net/wireless/hostap/hostap_hw.c            |    4 +-
+ drivers/net/wireless/mac80211_hwsim.c              |    8 +++---
+ drivers/net/wireless/zd1211rw/zd_mac.c             |    2 +-
+ drivers/net/wireless/zd1211rw/zd_usb.c             |    2 +-
+ drivers/platform/x86/hdaps.c                       |    4 +-
+ drivers/power/bq27x00_battery.c                    |    4 +-
+ drivers/power/max8998_charger.c                    |    1 -
+ drivers/scsi/aic7xxx/aic79xx_core.c                |    4 +-
+ drivers/scsi/aic7xxx/aic7xxx_core.c                |    2 +-
+ drivers/scsi/mpt2sas/mpt2sas_config.c              |    2 +-
+ drivers/scsi/pm8001/pm8001_hwi.c                   |    2 +-
+ drivers/scsi/pmcraid.h                             |    6 ++--
+ drivers/scsi/qla2xxx/qla_bsg.c                     |    2 +-
+ drivers/staging/iio/dac/ad5686.c                   |    1 -
+ drivers/staging/mei/interrupt.c                    |    2 +-
+ drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c  |    2 +-
+ drivers/tty/serial/sn_console.c                    |    4 +-
+ drivers/tty/synclink_gt.c                          |    2 +-
+ drivers/usb/host/ehci-dbg.c                        |    2 +-
+ drivers/watchdog/Kconfig                           |    2 +-
+ drivers/watchdog/pnx4008_wdt.c                     |    2 +-
+ fs/btrfs/check-integrity.c                         |    1 -
+ fs/btrfs/free-space-cache.c                        |    2 +-
+ fs/cramfs/inode.c                                  |    6 ++--
+ fs/ntfs/layout.h                                   |    4 +-
+ fs/ntfs/mft.c                                      |    4 +-
+ fs/reiserfs/lbalance.c                             |    2 +-
+ include/trace/events/power.h                       |    1 -
+ kernel/resource.c                                  |    3 +-
+ net/rds/ib_recv.c                                  |    2 +-
+ net/rds/iw_recv.c                                  |    2 +-
+ sound/pci/hda/patch_conexant.c                     |    2 +-
+ tools/testing/ktest/ktest.pl                       |    2 +-
+ 79 files changed, 108 insertions(+), 120 deletions(-)
+Merging audit/for-next (dcd6c92 Linux 3.3-rc1)
+$ git merge audit/for-next
+Already up-to-date.
+Merging pm/linux-next (98f7e95 PM / Hibernate: Enable usermodehelpers in hibernate() error path)
+$ git merge pm/linux-next
+Merge made by the 'recursive' strategy.
+ Documentation/power/devices.txt           |   93 +++++++----
+ Documentation/power/freezing-of-tasks.txt |   21 +++
+ arch/x86/kernel/apm_32.c                  |   11 +-
+ drivers/base/power/domain.c               |  157 +++++++++++++------
+ drivers/base/power/generic_ops.c          |  157 ++++++++++++------
+ drivers/base/power/main.c                 |  247 ++++++++++++++++++++++++++---
+ drivers/base/power/wakeup.c               |   41 +++--
+ drivers/devfreq/devfreq.c                 |   70 ++++++++
+ drivers/devfreq/exynos4_bus.c             |   17 +--
+ drivers/devfreq/governor_performance.c    |    5 +-
+ drivers/devfreq/governor_powersave.c      |    2 +-
+ drivers/devfreq/governor_simpleondemand.c |   12 +-
+ drivers/devfreq/governor_userspace.c      |   15 ++-
+ drivers/xen/manage.c                      |    6 +-
+ include/linux/devfreq.h                   |    9 +-
+ include/linux/pm.h                        |   58 ++++++-
+ include/linux/pm_domain.h                 |    6 +-
+ include/linux/pm_qos.h                    |   55 ++------
+ include/linux/suspend.h                   |    4 +
+ kernel/kexec.c                            |    8 +-
+ kernel/power/Makefile                     |    3 +-
+ kernel/power/hibernate.c                  |   47 +++---
+ kernel/power/main.c                       |   20 +--
+ kernel/power/power.h                      |    7 +-
+ kernel/power/process.c                    |   16 +-
+ kernel/power/qos.c                        |   23 ++--
+ kernel/power/snapshot.c                   |    7 +-
+ kernel/power/suspend.c                    |   84 +++++-----
+ kernel/power/user.c                       |   12 +-
+ 29 files changed, 841 insertions(+), 372 deletions(-)
+Merging apm/for-next (b4a133d Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm)
+$ git merge apm/for-next
+Already up-to-date.
+Merging fsnotify/for-next (ef9bf3b fanotify: only destroy a mark if both its mask and its ignored_mask are cleared)
+$ git merge fsnotify/for-next
+Auto-merging include/linux/fsnotify_backend.h
+Auto-merging fs/notify/mark.c
+Auto-merging fs/notify/group.c
+Auto-merging fs/notify/fanotify/fanotify_user.c
+Auto-merging fs/nfsd/vfs.c
+Auto-merging fs/cachefiles/namei.c
+Merge made by the 'recursive' strategy.
+ fs/cachefiles/namei.c              |    1 -
+ fs/cachefiles/xattr.c              |    1 -
+ fs/nfsd/vfs.c                      |    3 -
+ fs/notify/dnotify/dnotify.c        |   15 +++---
+ fs/notify/fanotify/fanotify.c      |   24 +++++----
+ fs/notify/fanotify/fanotify_user.c |  101 +++++++++++++++++++++++++-----------
+ fs/notify/group.c                  |    1 +
+ fs/notify/mark.c                   |   36 +++++--------
+ include/linux/fanotify.h           |    5 ++-
+ include/linux/fsnotify_backend.h   |   14 ++++-
+ 10 files changed, 121 insertions(+), 80 deletions(-)
+Merging edac/linux_next (4d096ca MAINTAINERS: add an entry for Edac Sandy Bridge driver)
+$ git merge edac/linux_next
+Already up-to-date.
+Merging edac-amd/for-next (5a42394 Merge remote-tracking branch 'kepek/3.3-edac-dbam' into edac-for-next)
+$ git merge edac-amd/for-next
+Merge made by the 'recursive' strategy.
+ Documentation/edac.txt       |    4 +-
+ drivers/edac/amd64_edac.c    |   32 ++++++-
+ drivers/edac/edac_mc_sysfs.c |    4 +-
+ drivers/edac/mce_amd.c       |  208 +++++++++++++-----------------------------
+ drivers/edac/mce_amd.h       |   13 +--
+ 5 files changed, 102 insertions(+), 159 deletions(-)
+Merging devicetree/devicetree/next (0f22dd3 of: Only compile OF_DYNAMIC on PowerPC pseries and iseries)
+$ git merge devicetree/devicetree/next
+Auto-merging include/linux/of.h
+Auto-merging drivers/base/core.c
+Auto-merging arch/powerpc/platforms/pseries/Kconfig
+Merge made by the 'recursive' strategy.
+ .../devicetree/bindings/arm/omap/omap.txt          |    6 +++
+ arch/arm/boot/dts/testcases/tests-phandle.dtsi     |    2 +
+ arch/powerpc/kernel/ibmebus.c                      |    2 +-
+ arch/powerpc/platforms/8xx/Kconfig                 |    1 +
+ arch/powerpc/platforms/iseries/Kconfig             |    1 +
+ arch/powerpc/platforms/pseries/Kconfig             |    1 +
+ arch/powerpc/platforms/wsp/Kconfig                 |    1 +
+ drivers/base/core.c                                |    5 ++
+ drivers/base/platform.c                            |    2 +-
+ drivers/macintosh/macio_asic.c                     |    2 +-
+ drivers/of/Kconfig                                 |    5 +-
+ drivers/of/base.c                                  |   40 +++++++++++++++++++-
+ drivers/of/device.c                                |   30 ++++++++-------
+ drivers/of/selftest.c                              |   29 ++++++++++++++
+ include/linux/of.h                                 |   17 ++++----
+ include/linux/of_device.h                          |    8 +++-
+ 16 files changed, 121 insertions(+), 31 deletions(-)
+Merging spi/spi/next (14af60b spi/pl022: Add high priority message pump support)
+$ git merge spi/spi/next
+Merge made by the 'recursive' strategy.
+ drivers/spi/spi-nuc900.c   |    2 -
+ drivers/spi/spi-pl022.c    |   77 ++++++++++++++++++++----------
+ drivers/spi/spi-s3c64xx.c  |  114 +++++++++++++++++++++++++++++++++++++++----
+ include/linux/amba/pl022.h |    3 +
+ 4 files changed, 158 insertions(+), 38 deletions(-)
+Merging gpio/gpio/next (ff64abe of_gpio: add support of of_gpio_named_count to be able to count named gpio)
+$ git merge gpio/gpio/next
+Resolved 'include/linux/mfd/tps65910.h' using previous resolution.
+Auto-merging include/linux/mfd/tps65910.h
+CONFLICT (content): Merge conflict in include/linux/mfd/tps65910.h
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master b8767f1] Merge remote-tracking branch 'gpio/gpio/next'
+$ git diff -M --stat --summary HEAD^..
+ .../devicetree/bindings/gpio/sodaville.txt         |   48 +++
+ arch/x86/platform/ce4100/falconfalls.dts           |    7 +-
+ drivers/gpio/Kconfig                               |   14 +
+ drivers/gpio/Makefile                              |    2 +
+ drivers/gpio/gpio-mc9s08dz60.c                     |  161 +++++++++++
+ drivers/gpio/gpio-sodaville.c                      |  302 ++++++++++++++++++++
+ drivers/gpio/gpio-tps65910.c                       |   20 ++-
+ drivers/of/gpio.c                                  |    9 +-
+ include/linux/mfd/tps65910.h                       |    8 +
+ include/linux/of_gpio.h                            |   27 ++-
+ 10 files changed, 588 insertions(+), 10 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/gpio/sodaville.txt
+ create mode 100644 drivers/gpio/gpio-mc9s08dz60.c
+ create mode 100644 drivers/gpio/gpio-sodaville.c
+Merging tip/auto-latest (630e0fd Merge branch 'x86/urgent' into auto-latest)
+$ git merge tip/auto-latest
+Auto-merging kernel/sched/core.c
+Auto-merging block/blk.h
+Removing arch/x86/platform/mrst/pmu.h
+Removing arch/x86/platform/mrst/pmu.c
+Auto-merging arch/x86/Kconfig
+Auto-merging arch/powerpc/kernel/perf_event.c
+Auto-merging arch/arm/include/asm/perf_event.h
+Removing Documentation/nmi_watchdog.txt
+Merge made by the 'recursive' strategy.
+ Documentation/lockup-watchdogs.txt                 |   63 ++
+ Documentation/nmi_watchdog.txt                     |   83 --
+ Documentation/scheduler/sched-stats.txt            |    3 +-
+ arch/arm/include/asm/perf_event.h                  |    4 -
+ arch/frv/include/asm/perf_event.h                  |    2 -
+ arch/hexagon/include/asm/perf_event.h              |    2 -
+ arch/powerpc/include/asm/perf_event_server.h       |    2 -
+ arch/powerpc/kernel/perf_event.c                   |    6 +
+ arch/s390/include/asm/perf_event.h                 |    1 -
+ arch/x86/Kconfig                                   |   22 +-
+ arch/x86/boot/boot.h                               |    2 +-
+ arch/x86/include/asm/alternative.h                 |    6 +
+ arch/x86/include/asm/atomic64_32.h                 |  146 ++--
+ arch/x86/include/asm/e820.h                        |    7 +
+ arch/x86/include/asm/efi.h                         |    5 -
+ arch/x86/include/asm/inat.h                        |    5 +-
+ arch/x86/include/asm/insn.h                        |   18 +-
+ arch/x86/include/asm/mrst.h                        |    4 +-
+ arch/x86/include/asm/perf_event.h                  |    2 -
+ arch/x86/include/asm/spinlock.h                    |    4 +-
+ arch/x86/include/asm/spinlock_types.h              |    1 -
+ arch/x86/kernel/cpu/amd.c                          |    3 +
+ arch/x86/kernel/cpu/intel_cacheinfo.c              |   44 +-
+ arch/x86/kernel/cpu/mcheck/mce-severity.c          |   16 +-
+ arch/x86/kernel/cpu/mcheck/mce.c                   |  179 +++--
+ arch/x86/kernel/cpu/perf_event.c                   |   82 ++
+ arch/x86/kernel/cpu/perf_event.h                   |    8 +
+ arch/x86/kernel/crash.c                            |    8 -
+ arch/x86/kernel/e820.c                             |    3 +-
+ arch/x86/kernel/microcode_amd.c                    |    1 -
+ arch/x86/kernel/reboot.c                           |  277 ++++----
+ arch/x86/kernel/setup.c                            |   21 +-
+ arch/x86/lib/atomic64_32.c                         |   59 +--
+ arch/x86/lib/atomic64_386_32.S                     |    6 +-
+ arch/x86/lib/atomic64_cx8_32.S                     |   29 +-
+ arch/x86/lib/copy_page_64.S                        |   12 +-
+ arch/x86/lib/inat.c                                |   36 +-
+ arch/x86/lib/insn.c                                |   13 +-
+ arch/x86/lib/memcpy_64.S                           |   44 +-
+ arch/x86/lib/memset_64.S                           |   33 +-
+ arch/x86/platform/efi/efi.c                        |   37 +-
+ arch/x86/platform/efi/efi_64.c                     |   17 -
+ arch/x86/platform/mrst/Makefile                    |    1 -
+ arch/x86/platform/mrst/mrst.c                      |   70 +-
+ arch/x86/platform/mrst/pmu.c                       |  817 --------------------
+ arch/x86/platform/mrst/pmu.h                       |  234 ------
+ block/blk-softirq.c                                |   16 +-
+ block/blk.h                                        |   16 -
+ drivers/base/memory.c                              |    2 +-
+ include/linux/jump_label.h                         |   32 +
+ include/linux/mm.h                                 |    4 +-
+ include/linux/perf_event.h                         |   11 +-
+ include/linux/sched.h                              |   24 +-
+ include/trace/events/signal.h                      |   85 +--
+ kernel/events/core.c                               |   53 +-
+ kernel/events/hw_breakpoint.c                      |    7 +
+ kernel/sched/core.c                                |    6 +-
+ kernel/sched/debug.c                               |    1 -
+ kernel/sched/fair.c                                |   24 +-
+ kernel/sched/sched.h                               |    1 -
+ kernel/sched/stats.c                               |    4 +-
+ kernel/signal.c                                    |   28 +-
+ kernel/watchdog.c                                  |   24 +-
+ lib/Kconfig.debug                                  |   18 +-
+ mm/hwpoison-inject.c                               |    4 +-
+ mm/madvise.c                                       |    2 +-
+ mm/memory-failure.c                                |   96 ++--
+ tools/perf/Documentation/Makefile                  |   86 ++-
+ tools/perf/Documentation/perf-lock.txt             |   20 +-
+ tools/perf/Documentation/perf-record.txt           |    4 +
+ tools/perf/Documentation/perf-script.txt           |    5 +-
+ tools/perf/Documentation/perf-top.txt              |    4 +
+ tools/perf/Makefile                                |    5 +-
+ tools/perf/bench/bench.h                           |    1 +
+ tools/perf/bench/mem-memcpy-x86-64-asm-def.h       |    8 +
+ tools/perf/bench/mem-memcpy-x86-64-asm.S           |    6 +-
+ tools/perf/bench/mem-memcpy.c                      |   12 +-
+ tools/perf/bench/mem-memset-arch.h                 |   12 +
+ tools/perf/bench/mem-memset-x86-64-asm-def.h       |   12 +
+ tools/perf/bench/mem-memset-x86-64-asm.S           |   13 +
+ tools/perf/bench/mem-memset.c                      |  297 +++++++
+ tools/perf/builtin-bench.c                         |    3 +
+ tools/perf/builtin-lock.c                          |    4 +-
+ tools/perf/builtin-probe.c                         |   12 +-
+ tools/perf/builtin-record.c                        |   40 +-
+ tools/perf/builtin-script.c                        |   80 ++-
+ tools/perf/builtin-stat.c                          |   12 +-
+ tools/perf/builtin-test.c                          |  185 +++++-
+ tools/perf/builtin-top.c                           |   22 +-
+ tools/perf/perf.h                                  |    1 +
+ tools/perf/python/twatch.py                        |    2 +-
+ tools/perf/util/cpumap.c                           |   11 +
+ tools/perf/util/cpumap.h                           |    4 +
+ tools/perf/util/evlist.c                           |   12 +-
+ tools/perf/util/evlist.h                           |    7 +-
+ tools/perf/util/evsel.c                            |    2 +-
+ tools/perf/util/header.h                           |    1 +
+ tools/perf/util/hist.h                             |    1 +
+ tools/perf/util/include/asm/dwarf2.h               |    4 +-
+ tools/perf/util/map.c                              |   15 +
+ tools/perf/util/map.h                              |    1 +
+ tools/perf/util/probe-event.c                      |   32 +-
+ tools/perf/util/probe-finder.c                     |    1 -
+ tools/perf/util/python.c                           |   10 +-
+ .../util/scripting-engines/trace-event-python.c    |    1 -
+ tools/perf/util/session.c                          |   39 +-
+ tools/perf/util/session.h                          |    2 +-
+ tools/perf/util/symbol.c                           |   22 +
+ tools/perf/util/symbol.h                           |    4 +
+ tools/perf/util/thread_map.c                       |  109 +++-
+ tools/perf/util/thread_map.h                       |    7 +-
+ tools/perf/util/top.c                              |    3 +
+ tools/perf/util/top.h                              |    2 +
+ tools/perf/util/trace-event-parse.c                |    1 -
+ tools/perf/util/trace-event-read.c                 |    1 -
+ tools/perf/util/trace-event-scripting.c            |    1 -
+ tools/perf/util/ui/browsers/hists.c                |    3 +
+ tools/perf/util/ui/browsers/map.c                  |    2 +-
+ tools/perf/util/usage.c                            |   39 +
+ tools/perf/util/util.h                             |    2 +
+ 120 files changed, 2026 insertions(+), 2055 deletions(-)
+ create mode 100644 Documentation/lockup-watchdogs.txt
+ delete mode 100644 Documentation/nmi_watchdog.txt
+ delete mode 100644 arch/x86/platform/mrst/pmu.c
+ delete mode 100644 arch/x86/platform/mrst/pmu.h
+ create mode 100644 tools/perf/bench/mem-memset-arch.h
+ create mode 100644 tools/perf/bench/mem-memset-x86-64-asm-def.h
+ create mode 100644 tools/perf/bench/mem-memset-x86-64-asm.S
+ create mode 100644 tools/perf/bench/mem-memset.c
+Merging rcu/rcu/next (eb7f202 rcu: stop spurious warnings from synchronize_sched_expedited)
+$ git merge rcu/rcu/next
+Auto-merging net/mac80211/mesh_pathtbl.c
+Auto-merging net/ipv4/ip_sockglue.c
+Auto-merging lib/Kconfig.debug
+Auto-merging include/linux/sched.h
+Auto-merging arch/s390/kernel/irq.c
+Merge made by the 'recursive' strategy.
+ Documentation/RCU/RTFP.txt       | 1902 ++++++++++++++++++++++++++++++++++----
+ Documentation/RCU/checklist.txt  |   14 +
+ Documentation/RCU/stallwarn.txt  |   87 ++-
+ Documentation/RCU/torture.txt    |   33 +-
+ Documentation/RCU/trace.txt      |   36 +-
+ arch/s390/kernel/irq.c           |    9 +-
+ drivers/target/tcm_fc/tfc_sess.c |   12 +-
+ include/linux/rcupdate.h         |   83 ++-
+ include/linux/rcutiny.h          |   10 +-
+ include/linux/rcutree.h          |   19 +
+ include/linux/sched.h            |    3 +-
+ include/linux/srcu.h             |   15 +-
+ include/trace/events/rcu.h       |   63 +-
+ init/Kconfig                     |    9 -
+ kernel/lockdep.c                 |    8 +-
+ kernel/rcu.h                     |   26 +-
+ kernel/rcupdate.c                |    5 +
+ kernel/rcutiny.c                 |   26 +-
+ kernel/rcutiny_plugin.h          |   77 ++-
+ kernel/rcutorture.c              |   91 ++-
+ kernel/rcutree.c                 |  507 ++++++++---
+ kernel/rcutree.h                 |   27 +-
+ kernel/rcutree_plugin.h          |  450 ++++++----
+ kernel/rcutree_trace.c           |   12 +-
+ kernel/srcu.c                    |   33 +-
+ lib/Kconfig.debug                |   24 +
+ net/ipv4/cipso_ipv4.c            |   11 +-
+ net/ipv4/ip_sockglue.c           |    7 +-
+ net/mac80211/mesh_pathtbl.c      |    8 +-
+ 29 files changed, 2965 insertions(+), 642 deletions(-)
+Merging cputime/cputime (c3e0ef9 [S390] fix cputime overflow in uptime_proc_show)
+$ git merge cputime/cputime
+Already up-to-date.
+Merging uprobes/for-next (4e44798 perf: perf interface for uprobes)
+$ git merge uprobes/for-next
+Resolved 'tools/perf/builtin-probe.c' using previous resolution.
+Resolved 'tools/perf/util/probe-event.c' using previous resolution.
+Auto-merging tools/perf/util/symbol.h
+Auto-merging tools/perf/util/symbol.c
+Auto-merging tools/perf/util/probe-event.c
+CONFLICT (content): Merge conflict in tools/perf/util/probe-event.c
+Auto-merging tools/perf/builtin-probe.c
+CONFLICT (content): Merge conflict in tools/perf/builtin-probe.c
+Auto-merging mm/mmap.c
+Auto-merging kernel/signal.c
+Auto-merging kernel/fork.c
+Auto-merging include/linux/sched.h
+Auto-merging arch/x86/include/asm/thread_info.h
+Auto-merging arch/x86/Kconfig
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master c861f5f] Merge remote-tracking branch 'uprobes/for-next'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/trace/uprobetracer.txt    |   93 ++
+ arch/Kconfig                            |    3 +
+ arch/x86/Kconfig                        |    5 +-
+ arch/x86/include/asm/thread_info.h      |    2 +
+ arch/x86/include/asm/uprobes.h          |   58 ++
+ arch/x86/kernel/Makefile                |    1 +
+ arch/x86/kernel/signal.c                |    6 +
+ arch/x86/kernel/uprobes.c               |  674 ++++++++++++++
+ include/linux/mm_types.h                |    5 +
+ include/linux/sched.h                   |    4 +
+ include/linux/uprobes.h                 |  171 ++++
+ kernel/Makefile                         |    1 +
+ kernel/fork.c                           |   15 +
+ kernel/signal.c                         |    3 +
+ kernel/trace/Kconfig                    |   20 +
+ kernel/trace/Makefile                   |    2 +
+ kernel/trace/trace.h                    |    5 +
+ kernel/trace/trace_kprobe.c             |  899 +-----------------
+ kernel/trace/trace_probe.c              |  786 ++++++++++++++++
+ kernel/trace/trace_probe.h              |  162 ++++
+ kernel/trace/trace_uprobe.c             |  772 +++++++++++++++
+ kernel/uprobes.c                        | 1546 +++++++++++++++++++++++++++++++
+ mm/mmap.c                               |   33 +-
+ tools/perf/Documentation/perf-probe.txt |   14 +
+ tools/perf/builtin-probe.c              |   41 +-
+ tools/perf/util/probe-event.c           |  415 +++++++--
+ tools/perf/util/probe-event.h           |   12 +-
+ tools/perf/util/symbol.c                |    8 +
+ tools/perf/util/symbol.h                |    1 +
+ 29 files changed, 4779 insertions(+), 978 deletions(-)
+ create mode 100644 Documentation/trace/uprobetracer.txt
+ create mode 100644 arch/x86/include/asm/uprobes.h
+ create mode 100644 arch/x86/kernel/uprobes.c
+ create mode 100644 include/linux/uprobes.h
+ create mode 100644 kernel/trace/trace_probe.c
+ create mode 100644 kernel/trace/trace_probe.h
+ create mode 100644 kernel/trace/trace_uprobe.c
+ create mode 100644 kernel/uprobes.c
+Merging cgroup/for-next (3ce3230 cgroup: Walk task list under tasklist_lock in cgroup_enable_task_cg_list)
+$ git merge cgroup/for-next
+Auto-merging net/core/sock.c
+Auto-merging net/core/netprio_cgroup.c
+Auto-merging mm/memcontrol.c
+Auto-merging kernel/sched/core.c
+Auto-merging kernel/events/core.c
+Auto-merging kernel/cgroup.c
+Auto-merging include/net/sock.h
+Auto-merging block/blk-cgroup.c
+Merge made by the 'recursive' strategy.
+ Documentation/cgroups/cgroups.txt |   26 ++--
+ block/blk-cgroup.c                |   22 +--
+ include/linux/cgroup.h            |   70 ++-------
+ include/net/sock.h                |    7 +-
+ include/net/tcp_memcontrol.h      |    2 +-
+ kernel/cgroup.c                   |  327 +++++++++++++++---------------------
+ kernel/cgroup_freezer.c           |   11 +-
+ kernel/cpuset.c                   |   16 +--
+ kernel/events/core.c              |   13 +-
+ kernel/sched/core.c               |   20 +--
+ mm/memcontrol.c                   |   48 ++----
+ net/core/netprio_cgroup.c         |   10 +-
+ net/core/sock.c                   |    6 +-
+ net/ipv4/tcp_memcontrol.c         |    2 +-
+ net/sched/cls_cgroup.c            |   10 +-
+ security/device_cgroup.c          |   10 +-
+ 16 files changed, 228 insertions(+), 372 deletions(-)
+Merging kmemleak/kmemleak (d65b4e9 Linux 3.3-rc3)
+$ git merge kmemleak/kmemleak
+Already up-to-date.
+Merging kvm/linux-next (4b99f72 KVM: mmu_notifier: Flush TLBs before releasing mmu_lock)
+$ git merge kvm/linux-next
+Merge made by the 'recursive' strategy.
+ arch/s390/kvm/intercept.c |   20 ++++++++++++--------
+ arch/s390/kvm/kvm-s390.c  |    2 +-
+ arch/x86/kvm/x86.c        |   11 +++++------
+ virt/kvm/kvm_main.c       |   19 ++++++++++---------
+ 4 files changed, 28 insertions(+), 24 deletions(-)
+Merging oprofile/for-next (b9e7f8e Merge branches 'oprofile/urgent' and 'oprofile/core' into oprofile/master)
+$ git merge oprofile/for-next
+Merge made by the 'recursive' strategy.
+ arch/x86/include/asm/msr-index.h         |    5 +
+ arch/x86/include/asm/perf_event.h        |    2 +
+ arch/x86/kernel/cpu/perf_event_amd_ibs.c |  438 +++++++++++++++++++++++++++++-
+ tools/perf/scripts/perl/bin/ibs-record   |   23 ++
+ tools/perf/scripts/perl/bin/ibs-report   |    6 +
+ tools/perf/scripts/perl/ibs.pl           |   47 ++++
+ tools/perf/util/header.c                 |  443 +++++++++++++++++++-----------
+ tools/perf/util/header.h                 |    1 +
+ tools/perf/util/parse-events.c           |   84 ++++++-
+ 9 files changed, 875 insertions(+), 174 deletions(-)
+ create mode 100644 tools/perf/scripts/perl/bin/ibs-record
+ create mode 100644 tools/perf/scripts/perl/bin/ibs-report
+ create mode 100644 tools/perf/scripts/perl/ibs.pl
+Merging xen/upstream/xen (59e9a6b Merge branch 'upstream/ticketlock-cleanup' into upstream/xen)
+$ git merge xen/upstream/xen
+Resolved 'arch/x86/include/asm/cmpxchg.h' using previous resolution.
+Auto-merging arch/x86/include/asm/cmpxchg.h
+CONFLICT (content): Merge conflict in arch/x86/include/asm/cmpxchg.h
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master ba58652] Merge remote-tracking branch 'xen/upstream/xen'
+$ git diff -M --stat --summary HEAD^..
+Merging xen-two/linux-next (53eaea0 Merge branch 'stable/for-linus-fixes-3.3' into linux-next)
+$ git merge xen-two/linux-next
+Merge made by the 'recursive' strategy.
+ arch/x86/pci/xen.c              |   27 +++++++++++++++++++++++++++
+ arch/x86/xen/enlighten.c        |    6 +++---
+ arch/x86/xen/irq.c              |    8 ++++----
+ arch/x86/xen/mmu.c              |   20 ++++++++++----------
+ arch/x86/xen/multicalls.h       |    2 +-
+ arch/x86/xen/smp.c              |    2 +-
+ drivers/xen/cpu_hotplug.c       |   15 ++++++++-------
+ include/xen/interface/physdev.h |    7 +++++++
+ 8 files changed, 61 insertions(+), 26 deletions(-)
+Merging xen-pvhvm/linux-next (b056b6a xen: suspend: remove xen_hvm_suspend)
+$ git merge xen-pvhvm/linux-next
+Already up-to-date.
+Merging percpu/for-next (e920d59 percpu: use raw_local_irq_* in _this_cpu op)
+$ git merge percpu/for-next
+Merge made by the 'recursive' strategy.
+ include/linux/percpu.h |   23 ++++++++++++-----------
+ mm/percpu-vm.c         |    3 +--
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+Merging workqueues/for-next (6b3da11 Merge branch 'for-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu)
+$ git merge workqueues/for-next
+Already up-to-date.
+Merging hwpoison/hwpoison (46e387b Merge branch 'hwpoison-hugepages' into hwpoison)
+$ git merge hwpoison/hwpoison
+Already up-to-date.
+Merging sysctl/master (4e75732 sysctl: Don't call sysctl_follow_link unless we are a link.)
+$ git merge sysctl/master
+Resolved 'fs/proc/proc_sysctl.c' using previous resolution.
+Auto-merging lib/Kconfig.debug
+Removing kernel/sysctl_check.c
+Auto-merging kernel/sysctl.c
+Auto-merging kernel/Makefile
+Auto-merging fs/proc/proc_sysctl.c
+CONFLICT (content): Merge conflict in fs/proc/proc_sysctl.c
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 1bff485] Merge remote-tracking branch 'sysctl/master'
+$ git diff -M --stat --summary HEAD^..
+ fs/proc/internal.h     |    3 +
+ fs/proc/proc_sysctl.c  | 1257 +++++++++++++++++++++++++++++++++++++++++++++---
+ include/linux/sysctl.h |  106 +++--
+ kernel/Makefile        |    1 -
+ kernel/sysctl.c        |  501 +-------------------
+ kernel/sysctl_check.c  |  160 ------
+ lib/Kconfig.debug      |    8 -
+ net/sysctl_net.c       |   24 +-
+ 8 files changed, 1264 insertions(+), 796 deletions(-)
+ delete mode 100644 kernel/sysctl_check.c
+Merging regmap/for-next (02c1ee3 Merge branch 'regmap-core' into regmap-next)
+$ git merge regmap/for-next
+Auto-merging sound/soc/codecs/wm8994.c
+Removing drivers/tty/serial/m32r_sio_reg.h
+Removing drivers/tty/serial/m32r_sio.h
+Removing drivers/tty/serial/m32r_sio.c
+Auto-merging drivers/mfd/wm8994-core.c
+Auto-merging drivers/base/regmap/regmap.c
+Merge made by the 'recursive' strategy.
+ drivers/base/regmap/internal.h       |    9 +-
+ drivers/base/regmap/regcache.c       |   26 +-
+ drivers/base/regmap/regmap-debugfs.c |    9 +
+ drivers/base/regmap/regmap-i2c.c     |   17 +
+ drivers/base/regmap/regmap-spi.c     |   17 +
+ drivers/base/regmap/regmap.c         |  233 ++++++-
+ drivers/mfd/wm831x-core.c            |   20 +-
+ drivers/mfd/wm831x-i2c.c             |    2 +-
+ drivers/mfd/wm831x-spi.c             |    2 +-
+ drivers/mfd/wm8400-core.c            |    7 +-
+ drivers/mfd/wm8994-core.c            |   81 ++-
+ drivers/tty/serial/m32r_sio.c        | 1191 ----------------------------------
+ drivers/tty/serial/m32r_sio.h        |   48 --
+ drivers/tty/serial/m32r_sio_reg.h    |  152 -----
+ include/linux/regmap.h               |  118 ++++
+ sound/soc/codecs/wm8994.c            |   25 +-
+ 16 files changed, 476 insertions(+), 1481 deletions(-)
+ delete mode 100644 drivers/tty/serial/m32r_sio.c
+ delete mode 100644 drivers/tty/serial/m32r_sio.h
+ delete mode 100644 drivers/tty/serial/m32r_sio_reg.h
+Merging hsi/for-next (43139a6 HSI: hsi_char: Update ioctl-number.txt)
+$ git merge hsi/for-next
+Auto-merging include/linux/Kbuild
+Auto-merging drivers/Makefile
+Auto-merging drivers/Kconfig
+Auto-merging Documentation/ioctl/ioctl-number.txt
+Auto-merging Documentation/DocBook/device-drivers.tmpl
+Merge made by the 'recursive' strategy.
+ Documentation/DocBook/device-drivers.tmpl |   17 +
+ Documentation/ioctl/ioctl-number.txt      |    1 +
+ drivers/Kconfig                           |    2 +
+ drivers/Makefile                          |    1 +
+ drivers/hsi/Kconfig                       |   19 +
+ drivers/hsi/Makefile                      |    6 +
+ drivers/hsi/clients/Kconfig               |   13 +
+ drivers/hsi/clients/Makefile              |    5 +
+ drivers/hsi/clients/hsi_char.c            |  802 +++++++++++++++++++++++++++++
+ drivers/hsi/hsi.c                         |  494 ++++++++++++++++++
+ drivers/hsi/hsi_boardinfo.c               |   62 +++
+ drivers/hsi/hsi_core.h                    |   35 ++
+ include/linux/Kbuild                      |    1 +
+ include/linux/hsi/Kbuild                  |    1 +
+ include/linux/hsi/hsi.h                   |  410 +++++++++++++++
+ include/linux/hsi/hsi_char.h              |   63 +++
+ 16 files changed, 1932 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/hsi/Kconfig
+ create mode 100644 drivers/hsi/Makefile
+ create mode 100644 drivers/hsi/clients/Kconfig
+ create mode 100644 drivers/hsi/clients/Makefile
+ create mode 100644 drivers/hsi/clients/hsi_char.c
+ create mode 100644 drivers/hsi/hsi.c
+ create mode 100644 drivers/hsi/hsi_boardinfo.c
+ create mode 100644 drivers/hsi/hsi_core.h
+ create mode 100644 include/linux/hsi/Kbuild
+ create mode 100644 include/linux/hsi/hsi.h
+ create mode 100644 include/linux/hsi/hsi_char.h
+Merging driver-core/driver-core-next (8bf1193 intel_idle: Revert change of auto_demotion_disable_flags for Nehalem)
+$ git merge driver-core/driver-core-next
+Resolved 'drivers/base/cpu.c' using previous resolution.
+Auto-merging scripts/mod/file2alias.c
+Auto-merging include/linux/pci.h
+Auto-merging include/linux/hyperv.h
+Auto-merging fs/sysfs/mount.c
+Auto-merging drivers/ssb/main.c
+Auto-merging drivers/pcmcia/ds.c
+Auto-merging drivers/pci/xen-pcifront.c
+Auto-merging drivers/pci/pci-driver.c
+Auto-merging drivers/hwmon/coretemp.c
+Removing drivers/hv/hv_kvp.h
+Auto-merging drivers/hid/hid-core.c
+Auto-merging drivers/base/cpu.c
+CONFLICT (content): Merge conflict in drivers/base/cpu.c
+Auto-merging drivers/acpi/processor_driver.c
+Auto-merging arch/x86/Kconfig
+Auto-merging Documentation/ioctl/ioctl-number.txt
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 9918270] Merge remote-tracking branch 'driver-core/driver-core-next'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/ABI/removed/devfs                    |    2 +-
+ Documentation/ABI/stable/sysfs-driver-usb-usbtmc   |   10 +-
+ Documentation/ABI/testing/sysfs-class              |    2 +-
+ Documentation/ABI/testing/sysfs-devices            |    2 +-
+ Documentation/ABI/testing/sysfs-devices-soc        |   58 +++++
+ .../ABI/testing/sysfs-driver-samsung-laptop        |    2 +-
+ Documentation/dynamic-debug-howto.txt              |   30 +--
+ Documentation/filesystems/debugfs.txt              |    5 +-
+ Documentation/ioctl/ioctl-number.txt               |    2 +-
+ Documentation/ko_KR/HOWTO                          |    2 +-
+ Documentation/kobject.txt                          |    2 +-
+ Documentation/zh_CN/HOWTO                          |    2 +-
+ arch/x86/Kconfig                                   |    3 +
+ arch/x86/crypto/aesni-intel_glue.c                 |   12 +-
+ arch/x86/crypto/crc32c-intel.c                     |   11 +-
+ arch/x86/crypto/ghash-clmulni-intel_glue.c         |   12 +-
+ arch/x86/include/asm/cpu_device_id.h               |   13 +
+ arch/x86/include/asm/cpufeature.h                  |    1 +
+ arch/x86/kernel/cpu/Makefile                       |    1 +
+ arch/x86/kernel/cpu/match.c                        |   91 +++++++
+ arch/x86/kernel/cpu/scattered.c                    |    1 +
+ arch/x86/kernel/microcode_core.c                   |   15 +
+ drivers/acpi/processor_driver.c                    |    1 +
+ drivers/acpi/processor_perflib.c                   |   22 ++
+ drivers/base/Kconfig                               |    3 +
+ drivers/base/Makefile                              |    1 +
+ drivers/base/bus.c                                 |    6 +-
+ drivers/base/cpu.c                                 |   11 +
+ drivers/base/driver.c                              |   35 +---
+ drivers/base/soc.c                                 |  183 +++++++++++++
+ drivers/cpufreq/cpufreq-nforce2.c                  |    8 +
+ drivers/cpufreq/e_powersaver.c                     |   20 +-
+ drivers/cpufreq/elanfreq.c                         |   14 +-
+ drivers/cpufreq/gx-suspmod.c                       |    9 +-
+ drivers/cpufreq/longhaul.c                         |    8 +-
+ drivers/cpufreq/longrun.c                          |   13 +-
+ drivers/cpufreq/p4-clockmod.c                      |   17 +-
+ drivers/cpufreq/powernow-k6.c                      |   12 +-
+ drivers/cpufreq/powernow-k7.c                      |   14 +-
+ drivers/cpufreq/powernow-k8.c                      |   19 +-
+ drivers/cpufreq/sc520_freq.c                       |   14 +-
+ drivers/cpufreq/speedstep-centrino.c               |   24 ++-
+ drivers/cpufreq/speedstep-ich.c                    |   15 +
+ drivers/cpufreq/speedstep-lib.c                    |    1 +
+ drivers/cpufreq/speedstep-smi.c                    |   15 +
+ drivers/crypto/padlock-aes.c                       |    9 +-
+ drivers/crypto/padlock-sha.c                       |   16 +-
+ drivers/hid/hid-core.c                             |    6 +-
+ drivers/hv/channel_mgmt.c                          |   87 -------
+ drivers/hv/hv.c                                    |    4 +-
+ drivers/hv/hv_kvp.c                                |   43 ++--
+ drivers/hv/hv_kvp.h                                |  184 -------------
+ drivers/hv/hv_util.c                               |    3 -
+ drivers/hv/hyperv_vmbus.h                          |    5 +-
+ drivers/hwmon/coretemp.c                           |   17 +-
+ drivers/hwmon/via-cputemp.c                        |   16 +-
+ drivers/idle/intel_idle.c                          |  112 +++++----
+ drivers/input/gameport/gameport.c                  |    1 -
+ drivers/input/serio/serio.c                        |    1 -
+ drivers/media/video/cx18/cx18-alsa-main.c          |    1 -
+ drivers/media/video/ivtv/ivtvfb.c                  |    2 -
+ drivers/media/video/s5p-fimc/fimc-mdevice.c        |    5 +-
+ drivers/media/video/s5p-tv/mixer_video.c           |    1 -
+ drivers/net/phy/phy_device.c                       |    6 +-
+ drivers/pci/pci-driver.c                           |   52 ++---
+ drivers/pci/xen-pcifront.c                         |    3 +-
+ drivers/pcmcia/ds.c                                |   11 +-
+ drivers/s390/cio/ccwgroup.c                        |    2 -
+ drivers/s390/cio/device.c                          |    8 +-
+ drivers/s390/net/smsgiucv_app.c                    |    9 +-
+ drivers/ssb/main.c                                 |   20 +--
+ drivers/usb/core/driver.c                          |   66 ++----
+ drivers/usb/dwc3/dwc3-pci.c                        |   12 +-
+ drivers/w1/masters/w1-gpio.c                       |    3 +-
+ drivers/w1/slaves/w1_bq27000.c                     |   17 +-
+ fs/debugfs/inode.c                                 |  149 +++++++++++-
+ fs/sysfs/dir.c                                     |  228 +++++++++--------
+ fs/sysfs/inode.c                                   |    3 -
+ fs/sysfs/mount.c                                   |    2 +-
+ fs/sysfs/sysfs.h                                   |   18 +-
+ include/acpi/processor.h                           |    1 +
+ include/linux/connector.h                          |    1 +
+ include/linux/cpu.h                                |    7 +
+ include/linux/device.h                             |   10 +-
+ include/linux/dynamic_debug.h                      |   19 +-
+ include/linux/hyperv.h                             |  146 +++++++++++
+ include/linux/mod_devicetable.h                    |   21 ++
+ include/linux/netdevice.h                          |    8 +-
+ include/linux/pci.h                                |   13 +
+ include/linux/printk.h                             |    8 +-
+ include/linux/sys_soc.h                            |   37 +++
+ lib/dma-debug.c                                    |    3 +-
+ lib/dynamic_debug.c                                |  270 ++++++++++++++------
+ scripts/mod/file2alias.c                           |   25 ++
+ tools/hv/hv_kvp_daemon.c                           |   62 ++----
+ 95 files changed, 1564 insertions(+), 933 deletions(-)
+ create mode 100644 Documentation/ABI/testing/sysfs-devices-soc
+ create mode 100644 arch/x86/include/asm/cpu_device_id.h
+ create mode 100644 arch/x86/kernel/cpu/match.c
+ create mode 100644 drivers/base/soc.c
+ delete mode 100644 drivers/hv/hv_kvp.h
+ create mode 100644 include/linux/sys_soc.h
+Merging tty/tty-next (6816383 tty: sparc: rename drivers/tty/serial/suncore.h -> include/linux/sunserialcore.h)
+$ git merge tty/tty-next
+Auto-merging include/linux/sunserialcore.h
+Auto-merging fs/devpts/inode.c
+CONFLICT (modify/delete): drivers/tty/serial/m32r_sio.c deleted in HEAD and modified in tty/tty-next. Version tty/tty-next of drivers/tty/serial/m32r_sio.c left in tree.
+Auto-merging drivers/isdn/capi/capi.c
+Auto-merging MAINTAINERS
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master bb3aaf2] Merge remote-tracking branch 'tty/tty-next'
+$ git diff -M --stat --summary HEAD^..
+ .../devicetree/bindings/tty/serial/efm32-uart.txt  |   14 +
+ MAINTAINERS                                        |    2 +-
+ drivers/isdn/capi/capi.c                           |    9 +-
+ drivers/misc/pti.c                                 |    6 +-
+ drivers/mmc/card/sdio_uart.c                       |    9 +-
+ drivers/tty/hvc/hvc_beat.c                         |    2 +-
+ drivers/tty/hvc/hvc_rtas.c                         |    2 +-
+ drivers/tty/hvc/hvc_udbg.c                         |    2 +-
+ drivers/tty/hvc/hvc_xen.c                          |    2 +-
+ drivers/tty/hvc/hvcs.c                             |    4 +-
+ drivers/tty/hvc/hvsi.c                             |    2 +-
+ drivers/tty/nozomi.c                               |    8 +-
+ drivers/tty/pty.c                                  |   68 +-
+ drivers/tty/serial/21285.c                         |    4 +-
+ drivers/tty/serial/8250/8250.c                     |   28 +-
+ drivers/tty/serial/Kconfig                         |   13 +
+ drivers/tty/serial/Makefile                        |    3 +-
+ drivers/tty/serial/altera_uart.c                   |   47 +-
+ drivers/tty/serial/efm32-uart.c                    |  830 ++++++++++++++
+ drivers/tty/serial/m32r_sio.c                      | 1184 ++++++++++++++++++++
+ drivers/tty/serial/mpc52xx_uart.c                  |    4 +-
+ drivers/tty/serial/mux.c                           |    2 +-
+ drivers/tty/serial/pch_uart.c                      |  115 ++-
+ drivers/tty/serial/pmac_zilog.c                    |    2 +-
+ drivers/tty/serial/suncore.c                       |    2 +-
+ drivers/tty/serial/sunhv.c                         |    3 +-
+ drivers/tty/serial/sunsab.c                        |    2 +-
+ drivers/tty/serial/sunsu.c                         |    3 +-
+ drivers/tty/serial/sunzilog.c                      |   12 +-
+ drivers/tty/serial/ucc_uart.c                      |    2 +-
+ drivers/tty/serial/vr41xx_siu.c                    |    4 +-
+ drivers/tty/sysrq.c                                |   11 +-
+ drivers/tty/tty_io.c                               |   44 +-
+ drivers/usb/serial/usb-serial.c                    |   16 +-
+ fs/devpts/inode.c                                  |   85 ++-
+ include/linux/altera_uart.h                        |    4 -
+ include/linux/platform_data/efm32-uart.h           |   18 +
+ include/linux/serial_core.h                        |    2 +
+ .../suncore.h => include/linux/sunserialcore.h     |    2 +-
+ include/linux/tty.h                                |    6 +-
+ 40 files changed, 2344 insertions(+), 234 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/tty/serial/efm32-uart.txt
+ create mode 100644 drivers/tty/serial/efm32-uart.c
+ create mode 100644 drivers/tty/serial/m32r_sio.c
+ create mode 100644 include/linux/platform_data/efm32-uart.h
+ rename drivers/tty/serial/suncore.h => include/linux/sunserialcore.h (98%)
+Merging usb/usb-next (5407a3c usb: host: ehci: allow ehci_* symbols to be unused)
+$ git merge usb/usb-next
+Auto-merging drivers/usb/core/driver.c
+Auto-merging drivers/scsi/sd.c
+Auto-merging drivers/scsi/scsi_scan.c
+Merge made by the 'recursive' strategy.
+ Documentation/ABI/testing/sysfs-bus-usb |   11 +
+ drivers/scsi/scsi_scan.c                |    4 +
+ drivers/scsi/sd.c                       |    2 +-
+ drivers/usb/Kconfig                     |    1 +
+ drivers/usb/class/cdc-wdm.c             |  119 ++++++------
+ drivers/usb/core/driver.c               |  120 ++++++++----
+ drivers/usb/core/hub.c                  |  202 +++++++++++++++-----
+ drivers/usb/core/sysfs.c                |   23 +++
+ drivers/usb/core/urb.c                  |   21 +--
+ drivers/usb/core/usb.c                  |    2 +-
+ drivers/usb/core/usb.h                  |    1 +
+ drivers/usb/host/ehci-fsl.c             |   14 ++
+ drivers/usb/host/ehci-fsl.h             |    2 +
+ drivers/usb/host/ehci-hcd.c             |    5 +
+ drivers/usb/host/ehci-hub.c             |    8 +-
+ drivers/usb/host/ehci-ls1x.c            |  159 +++++++++++++++
+ drivers/usb/host/imx21-dbg.c            |    2 +-
+ drivers/usb/host/uhci-hcd.c             |    3 +
+ drivers/usb/host/xhci-hub.c             |   41 ++++
+ drivers/usb/host/xhci-mem.c             |   11 +-
+ drivers/usb/host/xhci-ring.c            |   74 ++++++--
+ drivers/usb/host/xhci.h                 |    1 +
+ drivers/usb/serial/cp210x.c             |   13 +-
+ drivers/usb/serial/cypress_m8.c         |    2 +-
+ drivers/usb/serial/digi_acceleport.c    |    4 +-
+ drivers/usb/serial/generic.c            |    2 +-
+ drivers/usb/serial/io_edgeport.c        |    4 +-
+ drivers/usb/serial/io_ti.c              |    4 +-
+ drivers/usb/serial/mos7720.c            |    4 +-
+ drivers/usb/serial/mos7840.c            |    4 +-
+ drivers/usb/serial/omninet.c            |    2 +-
+ drivers/usb/serial/oti6858.c            |    6 +-
+ drivers/usb/serial/ti_usb_3410_5052.c   |    5 +-
+ drivers/usb/serial/whiteheat.c          |    2 +-
+ drivers/usb/storage/alauda.c            |    1 +
+ drivers/usb/storage/cypress_atacb.c     |    1 +
+ drivers/usb/storage/datafab.c           |    1 +
+ drivers/usb/storage/ene_ub6250.c        |    1 +
+ drivers/usb/storage/freecom.c           |    1 +
+ drivers/usb/storage/isd200.c            |    1 +
+ drivers/usb/storage/jumpshot.c          |    1 +
+ drivers/usb/storage/karma.c             |    1 +
+ drivers/usb/storage/onetouch.c          |    1 +
+ drivers/usb/storage/realtek_cr.c        |    1 +
+ drivers/usb/storage/scsiglue.c          |   55 +++---
+ drivers/usb/storage/sddr09.c            |    1 +
+ drivers/usb/storage/sddr55.c            |    1 +
+ drivers/usb/storage/shuttle_usbat.c     |    1 +
+ drivers/usb/storage/uas.c               |  328 ++++++++++++++++++++-----------
+ drivers/usb/storage/usb.c               |   21 ++-
+ include/linux/usb.h                     |    8 +
+ include/linux/usb/ch11.h                |    5 +
+ include/linux/usb/hcd.h                 |    2 +
+ include/linux/usb/serial.h              |   15 ++
+ include/linux/usb/uas.h                 |   69 +++++++
+ include/scsi/scsi_device.h              |    7 +-
+ 56 files changed, 1050 insertions(+), 351 deletions(-)
+ create mode 100644 drivers/usb/host/ehci-ls1x.c
+ create mode 100644 include/linux/usb/uas.h
+Merging staging/staging-next (3e80914 Staging: ramster: mark BROKEN)
+$ git merge staging/staging-next
+Removing drivers/staging/tidspbridge/rmgr/drv_interface.h
+Removing drivers/staging/tidspbridge/include/dspbridge/dbc.h
+Removing drivers/staging/sep/sep_driver.c
+Auto-merging drivers/staging/mei/interrupt.c
+Removing drivers/staging/hv/TODO
+Removing drivers/staging/hv/Makefile
+Removing drivers/staging/hv/Kconfig
+Auto-merging drivers/scsi/storvsc_drv.c
+Auto-merging drivers/scsi/Makefile
+Auto-merging drivers/scsi/Kconfig
+Auto-merging drivers/Makefile
+Auto-merging drivers/Kconfig
+Merge made by the 'recursive' strategy.
+ drivers/Kconfig                                    |    2 -
+ drivers/Makefile                                   |    1 -
+ drivers/scsi/Kconfig                               |    7 +
+ drivers/scsi/Makefile                              |    3 +
+ drivers/{staging/hv => scsi}/storvsc_drv.c         | 1300 +++---
+ drivers/staging/Kconfig                            |    8 +-
+ drivers/staging/Makefile                           |    5 +-
+ drivers/staging/android/Kconfig                    |   26 +
+ drivers/staging/android/Makefile                   |    2 +
+ drivers/staging/android/TODO                       |    2 +-
+ drivers/staging/android/alarm-dev.c                |  297 ++
+ drivers/staging/android/alarm.c                    |  601 +++
+ drivers/staging/android/android_alarm.h            |  121 +
+ drivers/staging/android/ashmem.c                   |    4 +-
+ drivers/staging/android/binder.c                   |    2 +-
+ drivers/staging/android/logger.c                   |   73 +-
+ drivers/staging/android/lowmemorykiller.c          |   75 +-
+ drivers/staging/android/ram_console.c              |    7 +-
+ drivers/staging/android/timed_gpio.c               |    6 +-
+ drivers/staging/bcm/Bcmchar.c                      |   41 +-
+ drivers/staging/bcm/CmHost.c                       | 3094 ++++++--------
+ drivers/staging/bcm/led_control.h                  |   80 +-
+ drivers/staging/comedi/Kconfig                     |    5 +-
+ drivers/staging/comedi/drivers/adv_pci_dio.c       |   29 +-
+ drivers/staging/comedi/drivers/dt2801.c            |   12 +-
+ drivers/staging/comedi/drivers/dt9812.c            |    4 +-
+ drivers/staging/comedi/drivers/me4000.c            |   12 +-
+ drivers/staging/comedi/drivers/ni_pcidio.c         |   61 +-
+ drivers/staging/comedi/drivers/ni_pcimio.c         |   27 +-
+ drivers/staging/crystalhd/crystalhd_hw.c           |    3 +-
+ drivers/staging/crystalhd/crystalhd_misc.h         |   46 +-
+ drivers/staging/et131x/README                      |    2 +-
+ drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c |    6 +-
+ drivers/staging/hv/Kconfig                         |    5 -
+ drivers/staging/hv/Makefile                        |    3 -
+ drivers/staging/hv/TODO                            |    5 -
+ .../staging/iio/Documentation/iio_event_monitor.c  |  241 ++
+ drivers/staging/iio/Makefile                       |    2 +-
+ drivers/staging/iio/accel/adis16201_ring.c         |    2 -
+ drivers/staging/iio/accel/adis16203_ring.c         |    2 -
+ drivers/staging/iio/accel/adis16204_ring.c         |    2 -
+ drivers/staging/iio/accel/adis16209_ring.c         |    2 -
+ drivers/staging/iio/accel/adis16240_ring.c         |    2 -
+ drivers/staging/iio/accel/lis3l02dq.h              |    2 -
+ drivers/staging/iio/accel/lis3l02dq_ring.c         |    2 -
+ drivers/staging/iio/adc/Kconfig                    |    9 +
+ drivers/staging/iio/adc/Makefile                   |    1 +
+ drivers/staging/iio/adc/ad7192.c                   |   45 +-
+ drivers/staging/iio/adc/ad7291.c                   |   14 +-
+ drivers/staging/iio/adc/ad7298_ring.c              |    3 -
+ drivers/staging/iio/adc/ad7476_ring.c              |    2 -
+ drivers/staging/iio/adc/ad7606_core.c              |   83 +-
+ drivers/staging/iio/adc/ad7606_ring.c              |    2 -
+ drivers/staging/iio/adc/ad7793.c                   |    2 -
+ drivers/staging/iio/adc/ad7887_ring.c              |    2 -
+ drivers/staging/iio/adc/ad799x_core.c              |    4 +-
+ drivers/staging/iio/adc/ad799x_ring.c              |    2 -
+ drivers/staging/iio/adc/adt7310.c                  |   21 +-
+ drivers/staging/iio/adc/adt7410.c                  |   21 +-
+ drivers/staging/iio/adc/lpc32xx_adc.c              |  237 +
+ drivers/staging/iio/adc/max1363_core.c             |   12 +-
+ drivers/staging/iio/adc/max1363_ring.c             |    2 -
+ drivers/staging/iio/cdc/ad7150.c                   |   10 +-
+ drivers/staging/iio/dac/ad5360.c                   |    4 +-
+ drivers/staging/iio/dac/ad5380.c                   |    4 +-
+ drivers/staging/iio/dac/ad5446.c                   |   33 +-
+ drivers/staging/iio/dds/ad9834.c                   |   53 +-
+ drivers/staging/iio/events.h                       |    4 +-
+ drivers/staging/iio/gyro/adis16260_ring.c          |    2 -
+ drivers/staging/iio/iio_core.h                     |    4 +
+ drivers/staging/iio/iio_simple_dummy_buffer.c      |    2 -
+ drivers/staging/iio/impedance-analyzer/ad5933.c    |    3 -
+ drivers/staging/iio/imu/adis16400_ring.c           |    2 -
+ drivers/staging/iio/industrialio-core.c            |  458 --
+ drivers/staging/iio/industrialio-event.c           |  453 ++
+ drivers/staging/iio/kfifo_buf.c                    |   46 +-
+ drivers/staging/iio/kfifo_buf.h                    |    2 -
+ drivers/staging/iio/light/isl29018.c               |    7 +
+ drivers/staging/iio/magnetometer/ak8975.c          |    8 +
+ drivers/staging/iio/meter/ade7758_ring.c           |    2 -
+ drivers/staging/iio/ring_sw.c                      |   22 +-
+ drivers/staging/iio/ring_sw.h                      |    5 -
+ drivers/staging/keucr/TODO                         |    2 +-
+ drivers/staging/line6/capture.c                    |   54 +-
+ drivers/staging/line6/capture.h                    |    2 +-
+ drivers/staging/line6/driver.c                     |    2 +-
+ drivers/staging/line6/pcm.c                        |  109 +-
+ drivers/staging/line6/pcm.h                        |  167 +-
+ drivers/staging/line6/playback.c                   |   68 +-
+ drivers/staging/line6/playback.h                   |    2 +-
+ drivers/staging/line6/toneport.c                   |   12 +-
+ drivers/staging/line6/usbdefs.h                    |   44 +-
+ drivers/staging/mei/TODO                           |    3 +
+ drivers/staging/mei/hw.h                           |    2 +-
+ drivers/staging/mei/init.c                         |    2 +-
+ drivers/staging/mei/interface.c                    |   25 +-
+ drivers/staging/mei/interface.h                    |    5 +-
+ drivers/staging/mei/interrupt.c                    |   18 +-
+ drivers/staging/mei/iorw.c                         |    2 +-
+ drivers/staging/mei/main.c                         |    2 +-
+ drivers/staging/mei/mei-amt-version.c              |  479 +++
+ drivers/staging/mei/mei.h                          |  125 +-
+ drivers/staging/mei/mei_dev.h                      |    8 +-
+ drivers/staging/mei/mei_version.h                  |    2 +-
+ drivers/staging/mei/wd.c                           |    2 +-
+ drivers/staging/nvec/Kconfig                       |    6 +-
+ drivers/staging/nvec/nvec.c                        |   19 +-
+ drivers/staging/nvec/nvec_ps2.c                    |   53 +-
+ drivers/staging/omapdrm/omap_gem_helpers.c         |    2 +-
+ drivers/staging/quickstart/quickstart.c            |  370 +-
+ drivers/staging/ramster/Kconfig                    |   13 +
+ drivers/staging/ramster/Makefile                   |    1 +
+ drivers/staging/ramster/TODO                       |   13 +
+ drivers/staging/ramster/cluster/Makefile           |    3 +
+ drivers/staging/ramster/cluster/heartbeat.c        |  464 ++
+ drivers/staging/ramster/cluster/heartbeat.h        |   87 +
+ drivers/staging/ramster/cluster/masklog.c          |  155 +
+ drivers/staging/ramster/cluster/masklog.h          |  220 +
+ drivers/staging/ramster/cluster/nodemanager.c      |  992 +++++
+ drivers/staging/ramster/cluster/nodemanager.h      |   88 +
+ .../staging/ramster/cluster/ramster_nodemanager.h  |   39 +
+ drivers/staging/ramster/cluster/tcp.c              | 2256 ++++++++++
+ drivers/staging/ramster/cluster/tcp.h              |  159 +
+ drivers/staging/ramster/cluster/tcp_internal.h     |  248 ++
+ drivers/staging/ramster/r2net.c                    |  401 ++
+ drivers/staging/ramster/ramster.h                  |  118 +
+ drivers/staging/ramster/tmem.c                     |  851 ++++
+ drivers/staging/ramster/tmem.h                     |  244 ++
+ drivers/staging/{zram => ramster}/xvmalloc.c       |    0
+ drivers/staging/{zram => ramster}/xvmalloc.h       |    0
+ drivers/staging/{zram => ramster}/xvmalloc_int.h   |    0
+ drivers/staging/ramster/zcache-main.c              | 3320 ++++++++++++++
+ drivers/staging/ramster/zcache.h                   |   22 +
+ drivers/staging/rtl8192e/rtllib_rx.c               |    2 +-
+ drivers/staging/rtl8192e/rtllib_softmac.c          |    3 +-
+ drivers/staging/rtl8712/Kconfig                    |    7 -
+ drivers/staging/rtl8712/drv_types.h                |    1 -
+ drivers/staging/rtl8712/os_intfs.c                 |    1 -
+ drivers/staging/rtl8712/osdep_service.h            |   17 -
+ drivers/staging/rtl8712/rtl8712_recv.c             |    2 -
+ drivers/staging/rtl8712/rtl871x_io.c               |    1 -
+ drivers/staging/rtl8712/rtl871x_io.h               |    1 -
+ drivers/staging/rtl8712/rtl871x_pwrctrl.c          |   11 +-
+ drivers/staging/rtl8712/rtl871x_pwrctrl.h          |    1 -
+ drivers/staging/rtl8712/rtl871x_recv.c             |    1 -
+ drivers/staging/rtl8712/rtl871x_recv.h             |    3 -
+ drivers/staging/rtl8712/rtl871x_sta_mgt.c          |    4 -
+ drivers/staging/rtl8712/rtl871x_xmit.c             |    3 -
+ drivers/staging/rtl8712/rtl871x_xmit.h             |    3 -
+ drivers/staging/rtl8712/sta_info.h                 |    4 -
+ drivers/staging/rtl8712/usb_intf.c                 |    1 -
+ drivers/staging/rts5139/ms.h                       |    4 +-
+ drivers/staging/rts5139/rts51x_chip.c              |   14 +-
+ drivers/staging/rts5139/rts51x_chip.h              |    6 +-
+ drivers/staging/rts5139/rts51x_fop.h               |    2 +-
+ drivers/staging/rts5139/rts51x_transport.c         |    2 +-
+ drivers/staging/rts5139/rts51x_transport.h         |    2 +-
+ drivers/staging/rts5139/sd_cprm.c                  |    2 +-
+ drivers/staging/sbe-2t3e3/intr.c                   |    2 +-
+ drivers/staging/sep/Kconfig                        |    3 +-
+ drivers/staging/sep/Makefile                       |    5 +-
+ drivers/staging/sep/TODO                           |    5 +-
+ drivers/staging/sep/sep_crypto.c                   | 4058 ++++++++++++++++++
+ drivers/staging/sep/sep_crypto.h                   |  359 ++
+ drivers/staging/sep/sep_dev.h                      |   98 +-
+ drivers/staging/sep/sep_driver.c                   | 2932 -------------
+ drivers/staging/sep/sep_driver_api.h               |  293 ++-
+ drivers/staging/sep/sep_driver_config.h            |   79 +-
+ drivers/staging/sep/sep_driver_hw_defs.h           |  185 +-
+ drivers/staging/sep/sep_main.c                     | 4518 ++++++++++++++++++++
+ drivers/staging/sep/sep_trace_events.h             |  188 +
+ drivers/staging/slicoss/README                     |    2 +-
+ drivers/staging/sm7xx/smtcfb.c                     |    3 +-
+ drivers/staging/sm7xx/smtcfb.h                     |    2 +-
+ drivers/{ => staging}/telephony/Kconfig            |    0
+ drivers/{ => staging}/telephony/Makefile           |    0
+ drivers/staging/telephony/TODO                     |   10 +
+ drivers/{ => staging}/telephony/ixj-ver.h          |    0
+ drivers/{ => staging}/telephony/ixj.c              |    0
+ drivers/{ => staging}/telephony/ixj.h              |    0
+ drivers/{ => staging}/telephony/ixj_pcmcia.c       |    0
+ drivers/{ => staging}/telephony/phonedev.c         |    0
+ drivers/staging/tidspbridge/Kconfig                |    6 -
+ drivers/staging/tidspbridge/Makefile               |    4 +-
+ drivers/staging/tidspbridge/core/chnl_sm.c         |   34 +-
+ drivers/staging/tidspbridge/core/dsp-clock.c       |    3 -
+ drivers/staging/tidspbridge/core/io_sm.c           |   29 +-
+ drivers/staging/tidspbridge/core/msg_sm.c          |    3 -
+ drivers/staging/tidspbridge/core/tiomap3430.c      |    9 -
+ drivers/staging/tidspbridge/core/tiomap3430_pwr.c  |    1 -
+ drivers/staging/tidspbridge/core/tiomap_io.c       |   18 -
+ drivers/staging/tidspbridge/gen/uuidutil.c         |    7 -
+ .../staging/tidspbridge/include/dspbridge/dbc.h    |   46 -
+ .../staging/tidspbridge/include/dspbridge/io_sm.h  |    2 -
+ drivers/staging/tidspbridge/pmgr/chnl.c            |   19 -
+ drivers/staging/tidspbridge/pmgr/cmm.c             |   68 +-
+ drivers/staging/tidspbridge/pmgr/cod.c             |   74 -
+ drivers/staging/tidspbridge/pmgr/dbll.c            |  113 +-
+ drivers/staging/tidspbridge/pmgr/dev.c             |  132 -
+ drivers/staging/tidspbridge/pmgr/dmm.c             |   14 -
+ drivers/staging/tidspbridge/pmgr/dspapi.c          |    7 -
+ drivers/staging/tidspbridge/pmgr/io.c              |   17 -
+ drivers/staging/tidspbridge/pmgr/msg.c             |   17 -
+ drivers/staging/tidspbridge/rmgr/dbdcd.c           |   88 -
+ drivers/staging/tidspbridge/rmgr/disp.c            |   44 -
+ drivers/staging/tidspbridge/rmgr/drv.c             |   48 -
+ drivers/staging/tidspbridge/rmgr/drv_interface.c   |  366 +-
+ drivers/staging/tidspbridge/rmgr/drv_interface.h   |   28 -
+ drivers/staging/tidspbridge/rmgr/dspdrv.c          |    5 -
+ drivers/staging/tidspbridge/rmgr/mgr.c             |   36 -
+ drivers/staging/tidspbridge/rmgr/nldr.c            |   71 -
+ drivers/staging/tidspbridge/rmgr/node.c            |   98 -
+ drivers/staging/tidspbridge/rmgr/proc.c            |   91 -
+ drivers/staging/tidspbridge/rmgr/rmm.c             |   36 -
+ drivers/staging/tidspbridge/rmgr/strm.c            |   86 +-
+ drivers/staging/usbip/stub.h                       |    1 -
+ drivers/staging/usbip/stub_rx.c                    |    9 -
+ drivers/staging/usbip/usbip_common.c               |   11 +-
+ drivers/staging/usbip/usbip_common.h               |    2 +-
+ drivers/staging/usbip/vhci_hcd.c                   |   39 -
+ drivers/staging/usbip/vhci_rx.c                    |    3 +-
+ drivers/staging/vme/vme.h                          |    2 +-
+ drivers/staging/vt6655/ioctl.c                     |   23 +-
+ drivers/staging/vt6656/iwctl.c                     |  230 +-
+ drivers/staging/vt6656/iwctl.h                     |   13 +-
+ drivers/staging/vt6656/main_usb.c                  |   13 +-
+ drivers/staging/vt6656/wpactl.c                    |  937 ++---
+ drivers/staging/wlan-ng/prism2mgmt.c               |    1 +
+ drivers/staging/xgifb/XGI_main.h                   |   78 +-
+ drivers/staging/xgifb/XGI_main_26.c                |  208 +-
+ drivers/staging/xgifb/XGIfb.h                      |    2 +-
+ drivers/staging/xgifb/vb_def.h                     |  178 +-
+ drivers/staging/xgifb/vb_init.c                    |   20 +-
+ drivers/staging/xgifb/vb_setmode.c                 |  836 ++--
+ drivers/staging/xgifb/vb_struct.h                  |   79 +-
+ drivers/staging/xgifb/vb_table.h                   |  346 +-
+ drivers/staging/xgifb/vgatypes.h                   |    9 +
+ drivers/staging/zcache/Kconfig                     |   11 +-
+ drivers/staging/zcache/zcache-main.c               |  231 +-
+ drivers/staging/zram/Kconfig                       |   10 +-
+ drivers/staging/zram/Makefile                      |    1 -
+ drivers/staging/zram/zram_drv.c                    |  116 +-
+ drivers/staging/zram/zram_drv.h                    |   12 +-
+ drivers/staging/zram/zram_sysfs.c                  |    4 +-
+ drivers/staging/zsmalloc/Kconfig                   |   14 +
+ drivers/staging/zsmalloc/Makefile                  |    3 +
+ drivers/staging/zsmalloc/zsmalloc-main.c           |  757 ++++
+ drivers/staging/zsmalloc/zsmalloc.h                |   31 +
+ drivers/staging/zsmalloc/zsmalloc_int.h            |  126 +
+ 249 files changed, 27362 insertions(+), 10555 deletions(-)
+ rename drivers/{staging/hv => scsi}/storvsc_drv.c (84%)
+ create mode 100644 drivers/staging/android/alarm-dev.c
+ create mode 100644 drivers/staging/android/alarm.c
+ create mode 100644 drivers/staging/android/android_alarm.h
+ delete mode 100644 drivers/staging/hv/Kconfig
+ delete mode 100644 drivers/staging/hv/Makefile
+ delete mode 100644 drivers/staging/hv/TODO
+ create mode 100644 drivers/staging/iio/Documentation/iio_event_monitor.c
+ create mode 100644 drivers/staging/iio/adc/lpc32xx_adc.c
+ create mode 100644 drivers/staging/iio/industrialio-event.c
+ create mode 100644 drivers/staging/mei/mei-amt-version.c
+ create mode 100644 drivers/staging/ramster/Kconfig
+ create mode 100644 drivers/staging/ramster/Makefile
+ create mode 100644 drivers/staging/ramster/TODO
+ create mode 100644 drivers/staging/ramster/cluster/Makefile
+ create mode 100644 drivers/staging/ramster/cluster/heartbeat.c
+ create mode 100644 drivers/staging/ramster/cluster/heartbeat.h
+ create mode 100644 drivers/staging/ramster/cluster/masklog.c
+ create mode 100644 drivers/staging/ramster/cluster/masklog.h
+ create mode 100644 drivers/staging/ramster/cluster/nodemanager.c
+ create mode 100644 drivers/staging/ramster/cluster/nodemanager.h
+ create mode 100644 drivers/staging/ramster/cluster/ramster_nodemanager.h
+ create mode 100644 drivers/staging/ramster/cluster/tcp.c
+ create mode 100644 drivers/staging/ramster/cluster/tcp.h
+ create mode 100644 drivers/staging/ramster/cluster/tcp_internal.h
+ create mode 100644 drivers/staging/ramster/r2net.c
+ create mode 100644 drivers/staging/ramster/ramster.h
+ create mode 100644 drivers/staging/ramster/tmem.c
+ create mode 100644 drivers/staging/ramster/tmem.h
+ rename drivers/staging/{zram => ramster}/xvmalloc.c (100%)
+ rename drivers/staging/{zram => ramster}/xvmalloc.h (100%)
+ rename drivers/staging/{zram => ramster}/xvmalloc_int.h (100%)
+ create mode 100644 drivers/staging/ramster/zcache-main.c
+ create mode 100644 drivers/staging/ramster/zcache.h
+ create mode 100644 drivers/staging/sep/sep_crypto.c
+ create mode 100644 drivers/staging/sep/sep_crypto.h
+ delete mode 100644 drivers/staging/sep/sep_driver.c
+ create mode 100644 drivers/staging/sep/sep_main.c
+ create mode 100644 drivers/staging/sep/sep_trace_events.h
+ rename drivers/{ => staging}/telephony/Kconfig (100%)
+ rename drivers/{ => staging}/telephony/Makefile (100%)
+ create mode 100644 drivers/staging/telephony/TODO
+ rename drivers/{ => staging}/telephony/ixj-ver.h (100%)
+ rename drivers/{ => staging}/telephony/ixj.c (100%)
+ rename drivers/{ => staging}/telephony/ixj.h (100%)
+ rename drivers/{ => staging}/telephony/ixj_pcmcia.c (100%)
+ rename drivers/{ => staging}/telephony/phonedev.c (100%)
+ delete mode 100644 drivers/staging/tidspbridge/include/dspbridge/dbc.h
+ delete mode 100644 drivers/staging/tidspbridge/rmgr/drv_interface.h
+ create mode 100644 drivers/staging/zsmalloc/Kconfig
+ create mode 100644 drivers/staging/zsmalloc/Makefile
+ create mode 100644 drivers/staging/zsmalloc/zsmalloc-main.c
+ create mode 100644 drivers/staging/zsmalloc/zsmalloc.h
+ create mode 100644 drivers/staging/zsmalloc/zsmalloc_int.h
+Merging char-misc/char-misc-next (838d51b char: Fix typo in tlclk.c)
+$ git merge char-misc/char-misc-next
+Auto-merging drivers/misc/cs5535-mfgpt.c
+Merge made by the 'recursive' strategy.
+ drivers/misc/ad525x_dpot-i2c.c         |   12 +-----------
+ drivers/misc/ad525x_dpot-spi.c         |   12 +-----------
+ drivers/misc/apds9802als.c             |   12 +-----------
+ drivers/misc/apds990x.c                |   13 +------------
+ drivers/misc/bh1770glc.c               |   13 +------------
+ drivers/misc/bh1780gli.c               |   15 ++-------------
+ drivers/misc/bmp085.c                  |   14 +-------------
+ drivers/misc/carma/carma-fpga.c        |   17 +----------------
+ drivers/misc/cs5535-mfgpt.c            |    2 +-
+ drivers/misc/ds1682.c                  |   13 +------------
+ drivers/misc/eeprom/at25.c             |   12 +-----------
+ drivers/misc/eeprom/eeprom.c           |   14 +-------------
+ drivers/misc/eeprom/eeprom_93xx46.c    |   12 +-----------
+ drivers/misc/eeprom/max6875.c          |   14 +-------------
+ drivers/misc/fsa9480.c                 |   12 +-----------
+ drivers/misc/hmc6352.c                 |   13 +------------
+ drivers/misc/ics932s401.c              |   13 +------------
+ drivers/misc/isl29003.c                |   14 +-------------
+ drivers/misc/isl29020.c                |   13 +------------
+ drivers/misc/lis3lv02d/lis3lv02d_i2c.c |   13 +------------
+ drivers/misc/lis3lv02d/lis3lv02d_spi.c |   13 +------------
+ drivers/misc/max8997-muic.c            |   12 +-----------
+ drivers/misc/spear13xx_pcie_gadget.c   |   12 +-----------
+ drivers/misc/ti-st/st_kim.c            |   13 +------------
+ drivers/misc/ti_dac7512.c              |   13 +------------
+ drivers/misc/tsl2550.c                 |   13 +------------
+ 26 files changed, 27 insertions(+), 302 deletions(-)
+Merging arm-soc/for-next (8a6b82f Merge branch 'next/fixes-non-critical' into for-next)
+$ git merge arm-soc/for-next
+Auto-merging arch/arm/mach-ux500/board-mop500-sdi.c
+Removing arch/arm/mach-nomadik/include/mach/setup.h
+Removing arch/arm/mach-highbank/include/mach/memory.h
+Auto-merging arch/arm/mach-highbank/highbank.c
+Removing arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+Removing arch/arm/mach-at91/include/mach/at91cap9.h
+Removing arch/arm/mach-at91/board-cap9adk.c
+Auto-merging arch/arm/mach-at91/at91sam9263_devices.c
+Removing arch/arm/mach-at91/at91cap9_devices.c
+Removing arch/arm/mach-at91/at91cap9.c
+Removing arch/arm/configs/at91cap9_defconfig
+Auto-merging arch/arm/Kconfig
+Merge made by the 'recursive' strategy.
+ Documentation/feature-removal-schedule.txt         |   14 -
+ arch/arm/Kconfig                                   |    3 +-
+ arch/arm/Kconfig.debug                             |    2 +-
+ arch/arm/arm-soc-for-next-contents.txt             |   33 +
+ arch/arm/boot/dts/at91sam9g25ek.dts                |   37 +
+ arch/arm/boot/dts/at91sam9x5.dtsi                  |  172 +++
+ arch/arm/boot/dts/at91sam9x5cm.dtsi                |   14 +
+ arch/arm/common/timer-sp.c                         |   17 +-
+ arch/arm/configs/at91cap9_defconfig                |  108 --
+ arch/arm/configs/lpc32xx_defconfig                 |  145 +++
+ arch/arm/configs/mxs_defconfig                     |   20 +-
+ arch/arm/include/asm/hardware/timer-sp.h           |   15 +-
+ arch/arm/mach-at91/Kconfig                         |   23 +-
+ arch/arm/mach-at91/Makefile                        |    5 +-
+ arch/arm/mach-at91/Makefile.boot                   |    6 +-
+ arch/arm/mach-at91/at91cap9.c                      |  404 -------
+ arch/arm/mach-at91/at91cap9_devices.c              | 1273 --------------------
+ arch/arm/mach-at91/at91sam9263_devices.c           |   13 +-
+ arch/arm/mach-at91/at91sam9g45_devices.c           |  113 ++-
+ arch/arm/mach-at91/at91sam9rl_devices.c            |    8 +-
+ arch/arm/mach-at91/at91sam9x5.c                    |  373 ++++++
+ arch/arm/mach-at91/board-cap9adk.c                 |  396 ------
+ arch/arm/mach-at91/board-dt.c                      |    1 +
+ arch/arm/mach-at91/board-flexibity.c               |   12 +-
+ arch/arm/mach-at91/board-sam9m10g45ek.c            |   80 ++-
+ arch/arm/mach-at91/clock.c                         |   88 +-
+ arch/arm/mach-at91/cpuidle.c                       |   11 +-
+ arch/arm/mach-at91/generic.h                       |    1 -
+ arch/arm/mach-at91/include/mach/at91_pmc.h         |   72 +-
+ arch/arm/mach-at91/include/mach/at91cap9.h         |  122 --
+ arch/arm/mach-at91/include/mach/at91cap9_matrix.h  |  137 ---
+ arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h  |   10 -
+ arch/arm/mach-at91/include/mach/at91sam9x5.h       |   80 ++
+ .../arm/mach-at91/include/mach/at91sam9x5_matrix.h |   53 +
+ arch/arm/mach-at91/include/mach/board.h            |    6 +-
+ arch/arm/mach-at91/include/mach/cpu.h              |   21 -
+ arch/arm/mach-at91/include/mach/hardware.h         |    6 +-
+ arch/arm/mach-at91/pm.c                            |   17 +-
+ arch/arm/mach-at91/pm.h                            |   91 +-
+ arch/arm/mach-at91/pm_slowclock.S                  |   12 +-
+ arch/arm/mach-at91/setup.c                         |   17 -
+ arch/arm/mach-at91/soc.h                           |    5 -
+ arch/arm/mach-highbank/highbank.c                  |    2 +-
+ arch/arm/mach-highbank/include/mach/memory.h       |    1 -
+ arch/arm/mach-imx/mach-mx31moboard.c               |    2 +-
+ arch/arm/mach-imx/pm-imx5.c                        |    4 +-
+ arch/arm/mach-lpc32xx/clock.c                      |   62 +-
+ arch/arm/mach-lpc32xx/common.h                     |    1 -
+ arch/arm/mach-lpc32xx/phy3250.c                    |    2 +
+ arch/arm/mach-mxs/Kconfig                          |   16 +
+ arch/arm/mach-mxs/Makefile                         |    1 +
+ arch/arm/mach-mxs/clock-mx23.c                     |   34 +-
+ arch/arm/mach-mxs/clock-mx28.c                     |   57 +-
+ arch/arm/mach-mxs/devices/platform-mxs-mmc.c       |    2 +
+ arch/arm/mach-mxs/include/mach/common.h            |    2 +
+ arch/arm/mach-mxs/include/mach/digctl.h            |    1 +
+ arch/arm/mach-mxs/include/mach/mxs.h               |   29 +-
+ arch/arm/mach-mxs/include/mach/uncompress.h        |   13 +-
+ arch/arm/mach-mxs/mach-apx4devkit.c                |  260 ++++
+ arch/arm/mach-mxs/mach-m28evk.c                    |    7 +-
+ arch/arm/mach-mxs/mach-mx28evk.c                   |   80 +-
+ arch/arm/mach-mxs/system.c                         |   16 +
+ arch/arm/mach-nomadik/board-nhk8815.c              |    7 +-
+ arch/arm/mach-nomadik/include/mach/setup.h         |   19 -
+ arch/arm/mach-ux500/Kconfig                        |    1 +
+ arch/arm/mach-ux500/board-mop500-sdi.c             |   31 +-
+ arch/arm/mach-ux500/board-mop500.c                 |   74 +-
+ arch/arm/mach-ux500/board-mop500.h                 |    8 +-
+ arch/arm/mach-ux500/board-u5500-sdi.c              |    4 +-
+ arch/arm/mach-ux500/board-u5500.c                  |   27 +-
+ arch/arm/mach-ux500/cpu-db5500.c                   |   36 +-
+ arch/arm/mach-ux500/cpu-db8500.c                   |   44 +-
+ arch/arm/mach-ux500/cpu.c                          |   75 ++
+ arch/arm/mach-ux500/devices-common.c               |   78 +-
+ arch/arm/mach-ux500/devices-common.h               |   83 +-
+ arch/arm/mach-ux500/devices-db5500.h               |  116 ++-
+ arch/arm/mach-ux500/devices-db8500.h               |  176 ++--
+ arch/arm/mach-ux500/dma-db5500.c                   |    3 +-
+ arch/arm/mach-ux500/include/mach/db8500-regs.h     |    3 +
+ arch/arm/mach-ux500/include/mach/setup.h           |   11 +-
+ arch/arm/mach-ux500/include/mach/usb.h             |    4 +-
+ arch/arm/mach-ux500/timer.c                        |    7 +-
+ arch/arm/mach-ux500/usb.c                          |    7 +-
+ arch/arm/plat-mxc/audmux-v2.c                      |    8 +-
+ arch/arm/plat-mxc/devices/platform-ahci-imx.c      |   16 +-
+ arch/arm/plat-mxc/epit.c                           |    2 +-
+ arch/arm/plat-mxc/pwm.c                            |    4 +-
+ arch/arm/plat-mxc/system.c                         |    2 +-
+ arch/arm/plat-mxc/time.c                           |    2 +-
+ arch/arm/plat-nomadik/include/plat/mtu.h           |    4 +-
+ arch/arm/plat-nomadik/timer.c                      |   33 +-
+ arch/avr32/mach-at32ap/include/mach/cpu.h          |    3 -
+ drivers/i2c/busses/i2c-imx.c                       |    4 +-
+ drivers/mmc/host/at91_mci.c                        |    1 -
+ drivers/mmc/host/sdhci-esdhc-imx.c                 |    6 +-
+ drivers/tty/serial/imx.c                           |    7 +-
+ drivers/usb/gadget/Kconfig                         |    4 +-
+ 97 files changed, 2251 insertions(+), 3287 deletions(-)
+ create mode 100644 arch/arm/arm-soc-for-next-contents.txt
+ create mode 100644 arch/arm/boot/dts/at91sam9g25ek.dts
+ create mode 100644 arch/arm/boot/dts/at91sam9x5.dtsi
+ create mode 100644 arch/arm/boot/dts/at91sam9x5cm.dtsi
+ delete mode 100644 arch/arm/configs/at91cap9_defconfig
+ create mode 100644 arch/arm/configs/lpc32xx_defconfig
+ delete mode 100644 arch/arm/mach-at91/at91cap9.c
+ delete mode 100644 arch/arm/mach-at91/at91cap9_devices.c
+ create mode 100644 arch/arm/mach-at91/at91sam9x5.c
+ delete mode 100644 arch/arm/mach-at91/board-cap9adk.c
+ delete mode 100644 arch/arm/mach-at91/include/mach/at91cap9.h
+ delete mode 100644 arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+ create mode 100644 arch/arm/mach-at91/include/mach/at91sam9x5.h
+ create mode 100644 arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h
+ delete mode 100644 arch/arm/mach-highbank/include/mach/memory.h
+ create mode 100644 arch/arm/mach-mxs/mach-apx4devkit.c
+ delete mode 100644 arch/arm/mach-nomadik/include/mach/setup.h
+Merging tmem/linux-next (b05b561 Merge branch 'devel/frontswap.v13' into linux-next)
+$ git merge tmem/linux-next
+Auto-merging mm/swapfile.c
+Auto-merging mm/filemap.c
+Auto-merging include/linux/swap.h
+Auto-merging fs/super.c
+Auto-merging drivers/staging/zcache/zcache-main.c
+Auto-merging Documentation/vm/cleancache.txt
+Removing Documentation/ABI/testing/sysfs-kernel-mm-cleancache
+Merge made by the 'recursive' strategy.
+ .../ABI/testing/sysfs-kernel-mm-cleancache         |   11 -
+ Documentation/vm/cleancache.txt                    |   41 ++--
+ Documentation/vm/frontswap.txt                     |  210 +++++++++++++++
+ drivers/staging/zcache/zcache-main.c               |   10 +-
+ drivers/xen/tmem.c                                 |   10 +-
+ fs/block_dev.c                                     |    2 +-
+ fs/super.c                                         |    2 +-
+ include/linux/cleancache.h                         |   24 +-
+ include/linux/frontswap.h                          |  126 +++++++++
+ include/linux/swap.h                               |    4 +
+ include/linux/swapfile.h                           |   13 +
+ mm/Kconfig                                         |   17 ++
+ mm/Makefile                                        |    1 +
+ mm/cleancache.c                                    |   98 +++-----
+ mm/filemap.c                                       |    2 +-
+ mm/frontswap.c                                     |  273 ++++++++++++++++++++
+ mm/page_io.c                                       |   12 +
+ mm/swapfile.c                                      |   64 ++++-
+ mm/truncate.c                                      |   10 +-
+ 19 files changed, 796 insertions(+), 134 deletions(-)
+ delete mode 100644 Documentation/ABI/testing/sysfs-kernel-mm-cleancache
+ create mode 100644 Documentation/vm/frontswap.txt
+ create mode 100644 include/linux/frontswap.h
+ create mode 100644 include/linux/swapfile.h
+ create mode 100644 mm/frontswap.c
+$ git am -3 ../patches/0001-mm-frontswap-update-for-security_vm_enough_memory-AP.patch
+Applying: mm: frontswap: update for security_vm_enough_memory API change
+$ git reset HEAD^
+Unstaged changes after reset:
+M	mm/frontswap.c
+$ git add .
+$ git commit -v -a --amend
+[master 2755356] Merge remote-tracking branch 'tmem/linux-next'
+Merging writeback/writeback-for-next (977b7e3 writeback: fix dereferencing NULL bdi->dev on trace_writeback_queue)
+$ git merge writeback/writeback-for-next
+Already up-to-date.
+Merging arm-dt/devicetree/arm-next (ede338f dt: add documentation of ARM dt boot interface)
+$ git merge arm-dt/devicetree/arm-next
+Already up-to-date.
+Merging hwspinlock/linux-next (8b37fcf hwspinlock: add MAINTAINERS entries)
+$ git merge hwspinlock/linux-next
+Already up-to-date.
+Merging pinctrl/for-next (334e235 Merge branch 'pinctrl-tegra-for-next-diet' into for-next)
+$ git merge pinctrl/for-next
+Auto-merging arch/arm/mach-u300/core.c
+Merge made by the 'recursive' strategy.
+ Documentation/pinctrl.txt                        |  135 +-
+ arch/arm/mach-tegra/Kconfig                      |    4 +
+ arch/arm/mach-tegra/include/mach/pinconf-tegra.h |   63 +
+ arch/arm/mach-u300/core.c                        |   54 +-
+ arch/arm/mach-u300/include/mach/gpio-u300.h      |    2 +
+ drivers/pinctrl/Kconfig                          |   37 +
+ drivers/pinctrl/Makefile                         |    7 +
+ drivers/pinctrl/core.c                           |  647 ++++-
+ drivers/pinctrl/core.h                           |   40 +-
+ drivers/pinctrl/pinconf.c                        |   39 +-
+ drivers/pinctrl/pinconf.h                        |    5 +-
+ drivers/pinctrl/pinctrl-coh901.c                 |   16 +-
+ drivers/pinctrl/pinctrl-mmp2.c                   |  722 +++++
+ drivers/pinctrl/pinctrl-pxa168.c                 |  651 ++++
+ drivers/pinctrl/pinctrl-pxa3xx.c                 |  244 ++
+ drivers/pinctrl/pinctrl-pxa3xx.h                 |  264 ++
+ drivers/pinctrl/pinctrl-pxa910.c                 | 1007 ++++++
+ drivers/pinctrl/pinctrl-tegra.c                  |  559 ++++
+ drivers/pinctrl/pinctrl-tegra.h                  |  163 +
+ drivers/pinctrl/pinctrl-tegra20.c                | 2860 +++++++++++++++++
+ drivers/pinctrl/pinctrl-tegra30.c                | 3726 ++++++++++++++++++++++
+ drivers/pinctrl/pinctrl-u300.c                   |   20 +-
+ drivers/pinctrl/pinmux.c                         |  787 +----
+ drivers/pinctrl/pinmux.h                         |   71 +-
+ drivers/tty/serial/sirfsoc_uart.c                |   20 +-
+ drivers/tty/serial/sirfsoc_uart.h                |    2 +-
+ include/linux/pinctrl/consumer.h                 |  118 +
+ include/linux/pinctrl/machine.h                  |   54 +-
+ include/linux/pinctrl/pinconf.h                  |   39 -
+ include/linux/pinctrl/pinmux.h                   |   52 -
+ 30 files changed, 11437 insertions(+), 971 deletions(-)
+ create mode 100644 arch/arm/mach-tegra/include/mach/pinconf-tegra.h
+ create mode 100644 drivers/pinctrl/pinctrl-mmp2.c
+ create mode 100644 drivers/pinctrl/pinctrl-pxa168.c
+ create mode 100644 drivers/pinctrl/pinctrl-pxa3xx.c
+ create mode 100644 drivers/pinctrl/pinctrl-pxa3xx.h
+ create mode 100644 drivers/pinctrl/pinctrl-pxa910.c
+ create mode 100644 drivers/pinctrl/pinctrl-tegra.c
+ create mode 100644 drivers/pinctrl/pinctrl-tegra.h
+ create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
+ create mode 100644 drivers/pinctrl/pinctrl-tegra30.c
+ create mode 100644 include/linux/pinctrl/consumer.h
+Merging moduleh/for-sfr (6aec187 drivers/media: video/a5k6aa is a module and so needs module.h)
+$ git merge moduleh/for-sfr
+Already up-to-date.
+Merging vhost/linux-next (1e05b62 sh: use the the PCI channels's io_map_base)
+$ git merge vhost/linux-next
+Already up-to-date.
+Merging kmap_atomic/kmap_atomic (019e9ad feature-removal-schedule.txt: schedule the deprecated form of kmap_atomic() for removal)
+$ git merge kmap_atomic/kmap_atomic
+Resolved 'Documentation/feature-removal-schedule.txt' using previous resolution.
+Resolved 'drivers/net/ethernet/intel/e1000e/netdev.c' using previous resolution.
+Resolved 'drivers/scsi/storvsc_drv.c' using previous resolution.
+Resolved 'drivers/staging/zcache/zcache-main.c' using previous resolution.
+Resolved 'drivers/staging/zram/zram_drv.c' using previous resolution.
+Auto-merging net/rds/iw_recv.c
+Auto-merging net/rds/ib_recv.c
+Auto-merging mm/swapfile.c
+Auto-merging mm/shmem.c
+Auto-merging mm/filemap.c
+Auto-merging kernel/power/snapshot.c
+Auto-merging fs/ntfs/super.c
+Auto-merging fs/nfs/nfs4proc.c
+Auto-merging fs/nfs/dir.c
+Auto-merging fs/namei.c
+Auto-merging fs/logfs/dir.c
+Auto-merging fs/jbd2/transaction.c
+Auto-merging fs/jbd2/journal.c
+Auto-merging fs/jbd2/commit.c
+Auto-merging fs/gfs2/lops.c
+Auto-merging fs/fuse/dev.c
+Auto-merging drivers/target/target_core_transport.c
+Auto-merging drivers/staging/zram/zram_drv.c
+CONFLICT (content): Merge conflict in drivers/staging/zram/zram_drv.c
+Auto-merging drivers/staging/zcache/zcache-main.c
+CONFLICT (content): Merge conflict in drivers/staging/zcache/zcache-main.c
+Removing drivers/staging/rtl8192u/ieee80211/kmap_types.h
+Auto-merging drivers/staging/ramster/xvmalloc.c
+Auto-merging drivers/scsi/storvsc_drv.c
+CONFLICT (content): Merge conflict in drivers/scsi/storvsc_drv.c
+Auto-merging drivers/scsi/scsi_lib.c
+Auto-merging drivers/scsi/scsi_debug.c
+Auto-merging drivers/scsi/mvsas/mv_sas.c
+Auto-merging drivers/scsi/libsas/sas_host_smp.c
+Auto-merging drivers/scsi/libiscsi_tcp.c
+Auto-merging drivers/scsi/libfc/fc_lport.c
+Auto-merging drivers/scsi/libfc/fc_fcp.c
+Auto-merging drivers/scsi/isci/request.c
+Auto-merging drivers/scsi/fcoe/fcoe_transport.c
+Auto-merging drivers/scsi/fcoe/fcoe.c
+Auto-merging drivers/scsi/cxgbi/libcxgbi.c
+Auto-merging drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+Auto-merging drivers/net/ethernet/sun/cassini.c
+Auto-merging drivers/net/ethernet/intel/e1000e/netdev.c
+CONFLICT (content): Merge conflict in drivers/net/ethernet/intel/e1000e/netdev.c
+Auto-merging drivers/net/ethernet/intel/e1000/e1000_main.c
+Auto-merging drivers/crypto/hifn_795x.c
+Auto-merging drivers/block/loop.c
+Auto-merging arch/x86/kvm/x86.c
+Auto-merging arch/x86/crypto/aesni-intel_glue.c
+Auto-merging arch/powerpc/mm/hugetlbpage.c
+Auto-merging arch/arm/mm/highmem.c
+Auto-merging arch/arm/mm/copypage-xscale.c
+Auto-merging arch/arm/mm/copypage-v6.c
+Auto-merging arch/arm/mm/copypage-v4mc.c
+Auto-merging Documentation/feature-removal-schedule.txt
+CONFLICT (content): Merge conflict in Documentation/feature-removal-schedule.txt
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 9eda5c5] Merge remote-tracking branch 'kmap_atomic/kmap_atomic'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/feature-removal-schedule.txt       |    8 ++
+ arch/arm/include/asm/highmem.h                   |    2 +-
+ arch/arm/mm/copypage-fa.c                        |   12 ++--
+ arch/arm/mm/copypage-feroceon.c                  |   12 ++--
+ arch/arm/mm/copypage-v3.c                        |   12 ++--
+ arch/arm/mm/copypage-v4mc.c                      |    8 +-
+ arch/arm/mm/copypage-v4wb.c                      |   12 ++--
+ arch/arm/mm/copypage-v4wt.c                      |   12 ++--
+ arch/arm/mm/copypage-v6.c                        |   12 ++--
+ arch/arm/mm/copypage-xsc3.c                      |   12 ++--
+ arch/arm/mm/copypage-xscale.c                    |    8 +-
+ arch/arm/mm/highmem.c                            |    4 +-
+ arch/frv/include/asm/highmem.h                   |    2 +-
+ arch/frv/mm/highmem.c                            |    4 +-
+ arch/mips/include/asm/highmem.h                  |    2 +-
+ arch/mips/mm/c-r4k.c                             |    4 +-
+ arch/mips/mm/highmem.c                           |    4 +-
+ arch/mips/mm/init.c                              |    8 +-
+ arch/mn10300/include/asm/highmem.h               |    2 +-
+ arch/parisc/include/asm/cacheflush.h             |    2 +-
+ arch/powerpc/include/asm/highmem.h               |    2 +-
+ arch/powerpc/kvm/book3s_pr.c                     |    4 +-
+ arch/powerpc/mm/dma-noncoherent.c                |    5 +-
+ arch/powerpc/mm/hugetlbpage.c                    |    4 +-
+ arch/powerpc/mm/mem.c                            |    4 +-
+ arch/sh/mm/cache-sh4.c                           |    4 +-
+ arch/sh/mm/cache.c                               |   12 ++--
+ arch/sparc/include/asm/highmem.h                 |    2 +-
+ arch/sparc/mm/highmem.c                          |    4 +-
+ arch/tile/include/asm/highmem.h                  |    2 +-
+ arch/tile/mm/highmem.c                           |    4 +-
+ arch/um/kernel/skas/uaccess.c                    |    4 +-
+ arch/x86/crypto/aesni-intel_glue.c               |   24 +++---
+ arch/x86/include/asm/highmem.h                   |    2 +-
+ arch/x86/kernel/crash_dump_32.c                  |    6 +-
+ arch/x86/kvm/lapic.c                             |    8 +-
+ arch/x86/kvm/paging_tmpl.h                       |    4 +-
+ arch/x86/kvm/x86.c                               |    8 +-
+ arch/x86/lib/usercopy_32.c                       |    4 +-
+ arch/x86/mm/highmem_32.c                         |    4 +-
+ crypto/ahash.c                                   |    4 +-
+ crypto/async_tx/async_memcpy.c                   |    8 +-
+ crypto/blkcipher.c                               |    8 +-
+ crypto/ccm.c                                     |    4 +-
+ crypto/scatterwalk.c                             |    8 +-
+ crypto/shash.c                                   |    8 +-
+ drivers/ata/libata-sff.c                         |    8 +-
+ drivers/block/brd.c                              |   20 +++---
+ drivers/block/drbd/drbd_bitmap.c                 |   50 ++++++------
+ drivers/block/drbd/drbd_nl.c                     |    4 +-
+ drivers/block/loop.c                             |   16 ++--
+ drivers/block/pktcdvd.c                          |    8 +-
+ drivers/crypto/hifn_795x.c                       |   10 +-
+ drivers/edac/edac_mc.c                           |    4 +-
+ drivers/gpu/drm/drm_cache.c                      |    8 +-
+ drivers/gpu/drm/gma500/mmu.c                     |   30 ++++----
+ drivers/gpu/drm/ttm/ttm_tt.c                     |   16 ++--
+ drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c              |    6 +-
+ drivers/ide/ide-taskfile.c                       |    4 +-
+ drivers/infiniband/ulp/iser/iser_memory.c        |    8 +-
+ drivers/md/bitmap.c                              |   42 +++++-----
+ drivers/md/dm-crypt.c                            |    8 +-
+ drivers/media/video/ivtv/ivtv-udma.c             |    4 +-
+ drivers/memstick/host/jmb38x_ms.c                |    4 +-
+ drivers/memstick/host/tifm_ms.c                  |    4 +-
+ drivers/net/ethernet/intel/e1000/e1000_main.c    |    6 +-
+ drivers/net/ethernet/intel/e1000e/netdev.c       |   11 +--
+ drivers/net/ethernet/sun/cassini.c               |    4 +-
+ drivers/scsi/arcmsr/arcmsr_hba.c                 |    8 +-
+ drivers/scsi/bnx2fc/bnx2fc_fcoe.c                |    5 +-
+ drivers/scsi/cxgbi/libcxgbi.c                    |    5 +-
+ drivers/scsi/fcoe/fcoe.c                         |    4 +-
+ drivers/scsi/fcoe/fcoe_transport.c               |    5 +-
+ drivers/scsi/gdth.c                              |    4 +-
+ drivers/scsi/ips.c                               |    6 +-
+ drivers/scsi/isci/request.c                      |   16 ++--
+ drivers/scsi/libfc/fc_fcp.c                      |    8 +-
+ drivers/scsi/libfc/fc_libfc.c                    |    8 +-
+ drivers/scsi/libfc/fc_libfc.h                    |    2 +-
+ drivers/scsi/libfc/fc_lport.c                    |    2 +-
+ drivers/scsi/libiscsi_tcp.c                      |    4 +-
+ drivers/scsi/libsas/sas_host_smp.c               |    8 +-
+ drivers/scsi/megaraid.c                          |    4 +-
+ drivers/scsi/mvsas/mv_sas.c                      |    4 +-
+ drivers/scsi/scsi_debug.c                        |   24 +++---
+ drivers/scsi/scsi_lib.c                          |    4 +-
+ drivers/scsi/sd_dif.c                            |   12 ++--
+ drivers/scsi/storvsc_drv.c                       |   34 ++++-----
+ drivers/staging/ramster/xvmalloc.c               |   39 +++++-----
+ drivers/staging/rtl8192u/ieee80211/cipher.c      |    8 +-
+ drivers/staging/rtl8192u/ieee80211/digest.c      |    8 +-
+ drivers/staging/rtl8192u/ieee80211/internal.h    |   17 ----
+ drivers/staging/rtl8192u/ieee80211/kmap_types.h  |   20 -----
+ drivers/staging/rtl8192u/ieee80211/scatterwalk.c |   19 +---
+ drivers/staging/zcache/zcache-main.c             |   12 ++--
+ drivers/staging/zram/zram_drv.c                  |   32 ++++----
+ drivers/target/target_core_transport.c           |    4 +-
+ drivers/target/tcm_fc/tfc_io.c                   |   10 +--
+ drivers/vhost/vhost.c                            |    4 +-
+ fs/afs/fsclient.c                                |    8 +-
+ fs/afs/mntpt.c                                   |    4 +-
+ fs/aio.c                                         |   30 ++++----
+ fs/bio-integrity.c                               |   10 +-
+ fs/btrfs/compression.c                           |   12 ++--
+ fs/btrfs/extent_io.c                             |   16 ++--
+ fs/btrfs/file-item.c                             |    4 +-
+ fs/btrfs/inode.c                                 |   26 +++---
+ fs/btrfs/lzo.c                                   |    4 +-
+ fs/btrfs/scrub.c                                 |    8 +-
+ fs/btrfs/zlib.c                                  |    4 +-
+ fs/exec.c                                        |    4 +-
+ fs/exofs/dir.c                                   |    4 +-
+ fs/ext2/dir.c                                    |    4 +-
+ fs/fuse/dev.c                                    |    4 +-
+ fs/fuse/file.c                                   |    4 +-
+ fs/gfs2/aops.c                                   |   12 ++--
+ fs/gfs2/lops.c                                   |    8 +-
+ fs/gfs2/quota.c                                  |    4 +-
+ fs/jbd/journal.c                                 |   12 ++--
+ fs/jbd/transaction.c                             |    4 +-
+ fs/jbd2/commit.c                                 |    4 +-
+ fs/jbd2/journal.c                                |   12 ++--
+ fs/jbd2/transaction.c                            |    4 +-
+ fs/logfs/dir.c                                   |   18 ++--
+ fs/logfs/readwrite.c                             |   38 +++++-----
+ fs/logfs/segment.c                               |    4 +-
+ fs/minix/dir.c                                   |    4 +-
+ fs/namei.c                                       |    4 +-
+ fs/nfs/dir.c                                     |    8 +-
+ fs/nfs/nfs4proc.c                                |    4 +-
+ fs/nilfs2/cpfile.c                               |   94 +++++++++++-----------
+ fs/nilfs2/dat.c                                  |   38 +++++-----
+ fs/nilfs2/dir.c                                  |    4 +-
+ fs/nilfs2/ifile.c                                |    4 +-
+ fs/nilfs2/mdt.c                                  |    4 +-
+ fs/nilfs2/page.c                                 |    8 +-
+ fs/nilfs2/recovery.c                             |    4 +-
+ fs/nilfs2/segbuf.c                               |    4 +-
+ fs/nilfs2/sufile.c                               |   68 ++++++++--------
+ fs/ntfs/aops.c                                   |   20 +++---
+ fs/ntfs/attrib.c                                 |   20 +++---
+ fs/ntfs/file.c                                   |   16 ++--
+ fs/ntfs/super.c                                  |    8 +-
+ fs/ocfs2/aops.c                                  |   16 ++--
+ fs/pipe.c                                        |    8 +-
+ fs/reiserfs/stree.c                              |    4 +-
+ fs/reiserfs/tail_conversion.c                    |    4 +-
+ fs/splice.c                                      |    7 +-
+ fs/squashfs/file.c                               |    8 +-
+ fs/squashfs/symlink.c                            |    4 +-
+ fs/ubifs/file.c                                  |    4 +-
+ fs/udf/file.c                                    |    4 +-
+ include/crypto/scatterwalk.h                     |   28 +------
+ include/linux/bio.h                              |    8 +-
+ include/linux/highmem.h                          |   79 +++++++++++++-----
+ kernel/debug/kdb/kdb_support.c                   |    4 +-
+ kernel/power/snapshot.c                          |   28 +++---
+ lib/scatterlist.c                                |    4 +-
+ lib/swiotlb.c                                    |    5 +-
+ mm/bounce.c                                      |    4 +-
+ mm/filemap.c                                     |    8 +-
+ mm/ksm.c                                         |   12 ++--
+ mm/memory.c                                      |    4 +-
+ mm/shmem.c                                       |    4 +-
+ mm/swapfile.c                                    |   30 ++++----
+ mm/vmalloc.c                                     |    8 +-
+ net/core/kmap_skb.h                              |    4 +-
+ net/rds/ib_recv.c                                |    7 +-
+ net/rds/info.c                                   |    6 +-
+ net/rds/iw_recv.c                                |    7 +-
+ net/rds/loop.c                                   |    2 +-
+ net/rds/rds.h                                    |    2 +-
+ net/rds/recv.c                                   |    2 +-
+ net/rds/tcp_recv.c                               |   11 +--
+ net/sunrpc/auth_gss/gss_krb5_wrap.c              |    4 +-
+ net/sunrpc/socklib.c                             |    4 +-
+ net/sunrpc/xdr.c                                 |   20 +++---
+ net/sunrpc/xprtrdma/rpc_rdma.c                   |    8 +-
+ security/tomoyo/domain.c                         |    4 +-
+ 179 files changed, 900 insertions(+), 952 deletions(-)
+ delete mode 100644 drivers/staging/rtl8192u/ieee80211/kmap_types.h
+Merging modem-shm/for-next (3cff1cc caif_shm: Add CAIF driver for Shared memory for M7400)
+$ git merge modem-shm/for-next
+Auto-merging include/linux/Kbuild
+Auto-merging drivers/Makefile
+Auto-merging drivers/Kconfig
+Merge made by the 'recursive' strategy.
+ drivers/Kconfig                             |    2 +
+ drivers/Makefile                            |    1 +
+ drivers/modem_shm/Kconfig                   |   62 ++
+ drivers/modem_shm/Makefile                  |    5 +
+ drivers/modem_shm/dummy_c2c_genio.c         |   76 ++
+ drivers/modem_shm/shm_boot.c                | 1208 ++++++++++++++++++++++++++
+ drivers/modem_shm/shm_bus.c                 |  113 +++
+ drivers/modem_shm/shm_chr.c                 | 1242 +++++++++++++++++++++++++++
+ drivers/modem_shm/shm_dev.c                 |  527 ++++++++++++
+ drivers/modem_shm/shm_ipctoc.h              |  154 ++++
+ drivers/net/caif/Kconfig                    |   12 +-
+ drivers/net/caif/Makefile                   |    3 +-
+ drivers/net/caif/caif_shm.c                 |  900 +++++++++++++++++++
+ include/linux/Kbuild                        |    1 +
+ include/linux/c2c_genio.h                   |  195 +++++
+ include/linux/modem_shm/Kbuild              |    1 +
+ include/linux/modem_shm/modem_shm_netlink.h |   95 ++
+ include/linux/modem_shm/shm_dev.h           |  245 ++++++
+ 18 files changed, 4840 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/modem_shm/Kconfig
+ create mode 100644 drivers/modem_shm/Makefile
+ create mode 100644 drivers/modem_shm/dummy_c2c_genio.c
+ create mode 100644 drivers/modem_shm/shm_boot.c
+ create mode 100644 drivers/modem_shm/shm_bus.c
+ create mode 100644 drivers/modem_shm/shm_chr.c
+ create mode 100644 drivers/modem_shm/shm_dev.c
+ create mode 100644 drivers/modem_shm/shm_ipctoc.h
+ create mode 100644 drivers/net/caif/caif_shm.c
+ create mode 100644 include/linux/c2c_genio.h
+ create mode 100644 include/linux/modem_shm/Kbuild
+ create mode 100644 include/linux/modem_shm/modem_shm_netlink.h
+ create mode 100644 include/linux/modem_shm/shm_dev.h
+Merging memblock/memblock-kill-early_node_map (7bd0b0f memblock: Reimplement memblock allocation using reverse free area iterator)
+$ git merge memblock/memblock-kill-early_node_map
+Already up-to-date.
+Merging remoteproc/for-next (6c7b643 remoteproc: s/big switch/lookup table/)
+$ git merge remoteproc/for-next
+Resolved 'include/linux/virtio_ids.h' using previous resolution.
+Auto-merging include/linux/virtio_ids.h
+CONFLICT (content): Merge conflict in include/linux/virtio_ids.h
+Auto-merging include/linux/mod_devicetable.h
+Auto-merging drivers/Makefile
+Auto-merging drivers/Kconfig
+Auto-merging MAINTAINERS
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master f5eccd0] Merge remote-tracking branch 'remoteproc/for-next'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/ABI/testing/sysfs-bus-rpmsg    |   75 ++
+ Documentation/remoteproc.txt                 |  324 ++++++
+ Documentation/rpmsg.txt                      |  293 ++++++
+ MAINTAINERS                                  |    7 +
+ arch/arm/plat-omap/include/plat/remoteproc.h |   57 +
+ drivers/Kconfig                              |    4 +
+ drivers/Makefile                             |    2 +
+ drivers/remoteproc/Kconfig                   |   29 +
+ drivers/remoteproc/Makefile                  |    9 +
+ drivers/remoteproc/omap_remoteproc.c         |  238 +++++
+ drivers/remoteproc/omap_remoteproc.h         |   69 ++
+ drivers/remoteproc/remoteproc_core.c         | 1450 ++++++++++++++++++++++++++
+ drivers/remoteproc/remoteproc_debugfs.c      |  179 ++++
+ drivers/remoteproc/remoteproc_internal.h     |   44 +
+ drivers/remoteproc/remoteproc_rpmsg.c        |  299 ++++++
+ drivers/rpmsg/Kconfig                        |   10 +
+ drivers/rpmsg/Makefile                       |    1 +
+ drivers/rpmsg/virtio_rpmsg_bus.c             | 1026 ++++++++++++++++++
+ include/linux/mod_devicetable.h              |    9 +
+ include/linux/remoteproc.h                   |  271 +++++
+ include/linux/rpmsg.h                        |  326 ++++++
+ include/linux/virtio_ids.h                   |    1 +
+ samples/Kconfig                              |    8 +
+ samples/Makefile                             |    2 +-
+ samples/rpmsg/Makefile                       |    1 +
+ samples/rpmsg/rpmsg_client_sample.c          |  100 ++
+ 26 files changed, 4833 insertions(+), 1 deletions(-)
+ create mode 100644 Documentation/ABI/testing/sysfs-bus-rpmsg
+ create mode 100644 Documentation/remoteproc.txt
+ create mode 100644 Documentation/rpmsg.txt
+ create mode 100644 arch/arm/plat-omap/include/plat/remoteproc.h
+ create mode 100644 drivers/remoteproc/Kconfig
+ create mode 100644 drivers/remoteproc/Makefile
+ create mode 100644 drivers/remoteproc/omap_remoteproc.c
+ create mode 100644 drivers/remoteproc/omap_remoteproc.h
+ create mode 100644 drivers/remoteproc/remoteproc_core.c
+ create mode 100644 drivers/remoteproc/remoteproc_debugfs.c
+ create mode 100644 drivers/remoteproc/remoteproc_internal.h
+ create mode 100644 drivers/remoteproc/remoteproc_rpmsg.c
+ create mode 100644 drivers/rpmsg/Kconfig
+ create mode 100644 drivers/rpmsg/Makefile
+ create mode 100644 drivers/rpmsg/virtio_rpmsg_bus.c
+ create mode 100644 include/linux/remoteproc.h
+ create mode 100644 include/linux/rpmsg.h
+ create mode 100644 samples/rpmsg/Makefile
+ create mode 100644 samples/rpmsg/rpmsg_client_sample.c
+Merging irqdomain/irqdomain/next (2462bac irq_domain/microblaze: Convert microblaze to use irq_domains)
+$ git merge irqdomain/irqdomain/next
+Resolved 'arch/arm/common/gic.c' using previous resolution.
+Resolved 'arch/c6x/Kconfig' using previous resolution.
+Auto-merging drivers/mfd/twl-core.c
+Auto-merging arch/powerpc/kernel/irq.c
+Auto-merging arch/powerpc/Kconfig
+Auto-merging arch/c6x/Kconfig
+CONFLICT (content): Merge conflict in arch/c6x/Kconfig
+Auto-merging arch/arm/mach-versatile/core.c
+Auto-merging arch/arm/mach-omap2/board-generic.c
+Auto-merging arch/arm/mach-exynos/common.c
+Auto-merging arch/arm/common/gic.c
+CONFLICT (content): Merge conflict in arch/arm/common/gic.c
+Auto-merging MAINTAINERS
+Automatic merge failed; fix conflicts and then commit the result.
+$ git commit -v -a
+[master 6c18d6b] Merge remote-tracking branch 'irqdomain/irqdomain/next'
+$ git diff -M --stat --summary HEAD^..
+ Documentation/IRQ-domain.txt                     |  117 +++
+ MAINTAINERS                                      |    9 +
+ arch/arm/common/gic.c                            |   95 ++--
+ arch/arm/common/vic.c                            |   16 +-
+ arch/arm/include/asm/hardware/gic.h              |    4 +-
+ arch/arm/include/asm/hardware/vic.h              |    2 +
+ arch/arm/mach-exynos/common.c                    |    2 +-
+ arch/arm/mach-imx/imx51-dt.c                     |    4 +-
+ arch/arm/mach-imx/imx53-dt.c                     |    4 +-
+ arch/arm/mach-imx/mach-imx6q.c                   |    3 +-
+ arch/arm/mach-msm/board-msm8x60.c                |    8 +-
+ arch/arm/mach-omap2/board-generic.c              |    2 +-
+ arch/arm/mach-prima2/irq.c                       |    2 +-
+ arch/arm/mach-versatile/core.c                   |    7 +-
+ arch/c6x/Kconfig                                 |    1 +
+ arch/c6x/include/asm/irq.h                       |  245 +-------
+ arch/c6x/kernel/irq.c                            |  612 +----------------
+ arch/c6x/platforms/megamod-pic.c                 |   25 +-
+ arch/microblaze/Kconfig                          |    1 +
+ arch/microblaze/include/asm/hardirq.h            |   16 -
+ arch/microblaze/include/asm/irq.h                |   42 +-
+ arch/microblaze/kernel/intc.c                    |   61 +-
+ arch/microblaze/kernel/irq.c                     |   24 +-
+ arch/microblaze/kernel/setup.c                   |    2 -
+ arch/powerpc/Kconfig                             |    1 +
+ arch/powerpc/include/asm/ehv_pic.h               |    2 +-
+ arch/powerpc/include/asm/i8259.h                 |    2 +-
+ arch/powerpc/include/asm/irq.h                   |  247 +-------
+ arch/powerpc/include/asm/mpic.h                  |    2 +-
+ arch/powerpc/include/asm/xics.h                  |    2 +-
+ arch/powerpc/kernel/irq.c                        |  617 +----------------
+ arch/powerpc/platforms/512x/mpc5121_ads_cpld.c   |   12 +-
+ arch/powerpc/platforms/52xx/media5200.c          |   15 +-
+ arch/powerpc/platforms/52xx/mpc52xx_gpt.c        |   16 +-
+ arch/powerpc/platforms/52xx/mpc52xx_pic.c        |   12 +-
+ arch/powerpc/platforms/82xx/pq2ads-pci-pic.c     |   14 +-
+ arch/powerpc/platforms/85xx/socrates_fpga_pic.c  |   15 +-
+ arch/powerpc/platforms/86xx/gef_pic.c            |   15 +-
+ arch/powerpc/platforms/cell/axon_msi.c           |   29 +-
+ arch/powerpc/platforms/cell/beat_interrupt.c     |   16 +-
+ arch/powerpc/platforms/cell/interrupt.c          |   16 +-
+ arch/powerpc/platforms/cell/spider-pic.c         |   14 +-
+ arch/powerpc/platforms/embedded6xx/flipper-pic.c |   30 +-
+ arch/powerpc/platforms/embedded6xx/hlwd-pic.c    |   35 +-
+ arch/powerpc/platforms/iseries/irq.c             |   11 +-
+ arch/powerpc/platforms/powermac/pic.c            |   26 +-
+ arch/powerpc/platforms/powermac/smp.c            |    9 +-
+ arch/powerpc/platforms/ps3/interrupt.c           |   11 +-
+ arch/powerpc/platforms/wsp/opb_pic.c             |   26 +-
+ arch/powerpc/sysdev/cpm1.c                       |    9 +-
+ arch/powerpc/sysdev/cpm2_pic.c                   |   23 +-
+ arch/powerpc/sysdev/ehv_pic.c                    |   14 +-
+ arch/powerpc/sysdev/fsl_msi.c                    |   10 +-
+ arch/powerpc/sysdev/fsl_msi.h                    |    2 +-
+ arch/powerpc/sysdev/i8259.c                      |   15 +-
+ arch/powerpc/sysdev/ipic.c                       |   31 +-
+ arch/powerpc/sysdev/ipic.h                       |    2 +-
+ arch/powerpc/sysdev/mpc8xx_pic.c                 |   11 +-
+ arch/powerpc/sysdev/mpic.c                       |   17 +-
+ arch/powerpc/sysdev/mpic_msi.c                   |    2 +-
+ arch/powerpc/sysdev/mv64x60_pic.c                |   11 +-
+ arch/powerpc/sysdev/qe_lib/qe_ic.c               |   26 +-
+ arch/powerpc/sysdev/qe_lib/qe_ic.h               |    2 +-
+ arch/powerpc/sysdev/tsi108_pci.c                 |   13 +-
+ arch/powerpc/sysdev/uic.c                        |   26 +-
+ arch/powerpc/sysdev/xics/xics-common.c           |   25 +-
+ arch/powerpc/sysdev/xilinx_intc.c                |   19 +-
+ drivers/gpio/gpio-mpc8xxx.c                      |   30 +-
+ drivers/mfd/twl-core.c                           |   16 +-
+ include/linux/irqdomain.h                        |  188 ++++--
+ include/linux/of_address.h                       |   33 +-
+ kernel/irq/irqdomain.c                           |  816 +++++++++++++++++++---
+ 72 files changed, 1372 insertions(+), 2468 deletions(-)
+ create mode 100644 Documentation/IRQ-domain.txt
+Merging kvmtool/master (52b7a79 kvm tools: Fix "vm setup" help text)
+$ git merge kvmtool/master
+Auto-merging scripts/kconfig/Makefile
+Auto-merging arch/x86/Kconfig
+Auto-merging MAINTAINERS
+Merge made by the 'recursive' strategy.
+ MAINTAINERS                                  |    8 +
+ arch/x86/Kconfig                             |   31 +
+ scripts/kconfig/Makefile                     |    7 +-
+ tools/kvm/.gitignore                         |   12 +
+ tools/kvm/CREDITS-Git                        |   30 +
+ tools/kvm/Documentation/kernel-debugging.txt |   15 +
+ tools/kvm/Documentation/kvm-balloon.txt      |   24 +
+ tools/kvm/Documentation/kvm-debug.txt        |   16 +
+ tools/kvm/Documentation/kvm-list.txt         |   16 +
+ tools/kvm/Documentation/kvm-pause.txt        |   16 +
+ tools/kvm/Documentation/kvm-resume.txt       |   16 +
+ tools/kvm/Documentation/kvm-run.txt          |   62 +
+ tools/kvm/Documentation/kvm-sandbox.txt      |   16 +
+ tools/kvm/Documentation/kvm-setup.txt        |   15 +
+ tools/kvm/Documentation/kvm-stat.txt         |   19 +
+ tools/kvm/Documentation/kvm-stop.txt         |   16 +
+ tools/kvm/Documentation/kvm-version.txt      |   21 +
+ tools/kvm/Documentation/virtio-console.txt   |   41 +
+ tools/kvm/Makefile                           |  425 +++++++
+ tools/kvm/README                             |  109 ++
+ tools/kvm/builtin-balloon.c                  |   80 ++
+ tools/kvm/builtin-debug.c                    |  103 ++
+ tools/kvm/builtin-help.c                     |   63 ++
+ tools/kvm/builtin-list.c                     |  149 +++
+ tools/kvm/builtin-pause.c                    |   88 ++
+ tools/kvm/builtin-resume.c                   |   88 ++
+ tools/kvm/builtin-run.c                      | 1343 ++++++++++++++++++++++
+ tools/kvm/builtin-sandbox.c                  |    9 +
+ tools/kvm/builtin-setup.c                    |  232 ++++
+ tools/kvm/builtin-stat.c                     |  127 +++
+ tools/kvm/builtin-stop.c                     |   70 ++
+ tools/kvm/builtin-version.c                  |   15 +
+ tools/kvm/code16gcc.h                        |   15 +
+ tools/kvm/command-list.txt                   |   15 +
+ tools/kvm/config/feature-tests.mak           |  168 +++
+ tools/kvm/config/utilities.mak               |  188 ++++
+ tools/kvm/disk/blk.c                         |   42 +
+ tools/kvm/disk/core.c                        |  260 +++++
+ tools/kvm/disk/qcow.c                        | 1529 ++++++++++++++++++++++++++
+ tools/kvm/disk/raw.c                         |  141 +++
+ tools/kvm/framebuffer.c                      |   75 ++
+ tools/kvm/guest/init.c                       |   38 +
+ tools/kvm/guest/init_stage2.c                |   55 +
+ tools/kvm/guest/passwd                       |    1 +
+ tools/kvm/guest_compat.c                     |   99 ++
+ tools/kvm/hw/i8042.c                         |  348 ++++++
+ tools/kvm/hw/pci-shmem.c                     |  268 +++++
+ tools/kvm/hw/rtc.c                           |  137 +++
+ tools/kvm/hw/serial.c                        |  447 ++++++++
+ tools/kvm/hw/vesa.c                          |   85 ++
+ tools/kvm/include/asm/hweight.h              |    8 +
+ tools/kvm/include/bios/memcpy.h              |    9 +
+ tools/kvm/include/kvm/8250-serial.h          |   11 +
+ tools/kvm/include/kvm/apic.h                 |   17 +
+ tools/kvm/include/kvm/brlock.h               |   41 +
+ tools/kvm/include/kvm/builtin-balloon.h      |    9 +
+ tools/kvm/include/kvm/builtin-debug.h        |   18 +
+ tools/kvm/include/kvm/builtin-help.h         |    6 +
+ tools/kvm/include/kvm/builtin-list.h         |   10 +
+ tools/kvm/include/kvm/builtin-pause.h        |    9 +
+ tools/kvm/include/kvm/builtin-resume.h       |    9 +
+ tools/kvm/include/kvm/builtin-run.h          |   11 +
+ tools/kvm/include/kvm/builtin-sandbox.h      |    6 +
+ tools/kvm/include/kvm/builtin-setup.h        |   11 +
+ tools/kvm/include/kvm/builtin-stat.h         |    9 +
+ tools/kvm/include/kvm/builtin-stop.h         |    9 +
+ tools/kvm/include/kvm/builtin-version.h      |    6 +
+ tools/kvm/include/kvm/compiler.h             |   10 +
+ tools/kvm/include/kvm/disk-image.h           |   81 ++
+ tools/kvm/include/kvm/e820.h                 |   13 +
+ tools/kvm/include/kvm/framebuffer.h          |   35 +
+ tools/kvm/include/kvm/guest_compat.h         |    9 +
+ tools/kvm/include/kvm/i8042.h                |   12 +
+ tools/kvm/include/kvm/ioeventfd.h            |   27 +
+ tools/kvm/include/kvm/ioport.h               |   69 ++
+ tools/kvm/include/kvm/irq.h                  |   33 +
+ tools/kvm/include/kvm/kvm-cmd.h              |   17 +
+ tools/kvm/include/kvm/kvm-cpu.h              |   24 +
+ tools/kvm/include/kvm/kvm-ipc.h              |   24 +
+ tools/kvm/include/kvm/kvm.h                  |   92 ++
+ tools/kvm/include/kvm/msi.h                  |   10 +
+ tools/kvm/include/kvm/mutex.h                |   33 +
+ tools/kvm/include/kvm/parse-options.h        |  214 ++++
+ tools/kvm/include/kvm/pci-shmem.h            |   28 +
+ tools/kvm/include/kvm/pci.h                  |   95 ++
+ tools/kvm/include/kvm/qcow.h                 |  133 +++
+ tools/kvm/include/kvm/rbtree-interval.h      |   28 +
+ tools/kvm/include/kvm/read-write.h           |   43 +
+ tools/kvm/include/kvm/rtc.h                  |    9 +
+ tools/kvm/include/kvm/rwsem.h                |   39 +
+ tools/kvm/include/kvm/sdl.h                  |   22 +
+ tools/kvm/include/kvm/segment.h              |   21 +
+ tools/kvm/include/kvm/strbuf.h               |   19 +
+ tools/kvm/include/kvm/symbol.h               |   30 +
+ tools/kvm/include/kvm/term.h                 |   20 +
+ tools/kvm/include/kvm/threadpool.h           |   37 +
+ tools/kvm/include/kvm/types.h                |    7 +
+ tools/kvm/include/kvm/uip.h                  |  358 ++++++
+ tools/kvm/include/kvm/util.h                 |   95 ++
+ tools/kvm/include/kvm/vesa.h                 |   18 +
+ tools/kvm/include/kvm/virtio-9p.h            |   74 ++
+ tools/kvm/include/kvm/virtio-balloon.h       |    8 +
+ tools/kvm/include/kvm/virtio-blk.h           |   12 +
+ tools/kvm/include/kvm/virtio-console.h       |    9 +
+ tools/kvm/include/kvm/virtio-net.h           |   23 +
+ tools/kvm/include/kvm/virtio-pci-dev.h       |   37 +
+ tools/kvm/include/kvm/virtio-pci.h           |   49 +
+ tools/kvm/include/kvm/virtio-rng.h           |    9 +
+ tools/kvm/include/kvm/virtio-trans.h         |   44 +
+ tools/kvm/include/kvm/virtio.h               |   67 ++
+ tools/kvm/include/kvm/vnc.h                  |   20 +
+ tools/kvm/include/linux/bitops.h             |   33 +
+ tools/kvm/include/linux/byteorder.h          |    7 +
+ tools/kvm/include/linux/compiler.h           |   19 +
+ tools/kvm/include/linux/kernel.h             |   39 +
+ tools/kvm/include/linux/module.h             |    6 +
+ tools/kvm/include/linux/prefetch.h           |    6 +
+ tools/kvm/include/linux/types.h              |   51 +
+ tools/kvm/ioeventfd.c                        |  209 ++++
+ tools/kvm/ioport.c                           |  195 ++++
+ tools/kvm/kvm-cmd.c                          |   91 ++
+ tools/kvm/kvm-cpu.c                          |  175 +++
+ tools/kvm/kvm-ipc.c                          |  231 ++++
+ tools/kvm/kvm.c                              |  587 ++++++++++
+ tools/kvm/main.c                             |   19 +
+ tools/kvm/mmio.c                             |  137 +++
+ tools/kvm/net/uip/arp.c                      |   30 +
+ tools/kvm/net/uip/buf.c                      |  114 ++
+ tools/kvm/net/uip/core.c                     |  190 ++++
+ tools/kvm/net/uip/csum.c                     |   92 ++
+ tools/kvm/net/uip/dhcp.c                     |  203 ++++
+ tools/kvm/net/uip/icmp.c                     |   29 +
+ tools/kvm/net/uip/ipv4.c                     |   29 +
+ tools/kvm/net/uip/tcp.c                      |  317 ++++++
+ tools/kvm/net/uip/udp.c                      |  236 ++++
+ tools/kvm/pci.c                              |  213 ++++
+ tools/kvm/powerpc/cpu_info.c                 |   83 ++
+ tools/kvm/powerpc/cpu_info.h                 |   43 +
+ tools/kvm/powerpc/include/kvm/barrier.h      |    6 +
+ tools/kvm/powerpc/include/kvm/kvm-arch.h     |   88 ++
+ tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h |   76 ++
+ tools/kvm/powerpc/ioport.c                   |   18 +
+ tools/kvm/powerpc/irq.c                      |   75 ++
+ tools/kvm/powerpc/kvm-cpu.c                  |  291 +++++
+ tools/kvm/powerpc/kvm.c                      |  460 ++++++++
+ tools/kvm/powerpc/spapr.h                    |   93 ++
+ tools/kvm/powerpc/spapr_hcall.c              |  134 +++
+ tools/kvm/powerpc/spapr_hvcons.c             |  102 ++
+ tools/kvm/powerpc/spapr_hvcons.h             |   19 +
+ tools/kvm/powerpc/spapr_pci.c                |  423 +++++++
+ tools/kvm/powerpc/spapr_pci.h                |   57 +
+ tools/kvm/powerpc/spapr_rtas.c               |  229 ++++
+ tools/kvm/powerpc/xics.c                     |  514 +++++++++
+ tools/kvm/powerpc/xics.h                     |   23 +
+ tools/kvm/symbol.c                           |  131 +++
+ tools/kvm/term.c                             |  166 +++
+ tools/kvm/tests/Makefile                     |   19 +
+ tools/kvm/tests/boot/Makefile                |   13 +
+ tools/kvm/tests/boot/init.c                  |   11 +
+ tools/kvm/tests/kernel/.gitignore            |    2 +
+ tools/kvm/tests/kernel/Makefile              |   20 +
+ tools/kvm/tests/kernel/README                |   16 +
+ tools/kvm/tests/kernel/kernel.S              |    8 +
+ tools/kvm/tests/pit/.gitignore               |    2 +
+ tools/kvm/tests/pit/Makefile                 |   20 +
+ tools/kvm/tests/pit/README                   |   16 +
+ tools/kvm/tests/pit/tick.S                   |  109 ++
+ tools/kvm/ui/sdl.c                           |  303 +++++
+ tools/kvm/ui/vnc.c                           |  230 ++++
+ tools/kvm/util/KVMTOOLS-VERSION-GEN          |   40 +
+ tools/kvm/util/generate-cmdlist.sh           |   23 +
+ tools/kvm/util/kvm-ifup-vbr0                 |    6 +
+ tools/kvm/util/parse-options.c               |  577 ++++++++++
+ tools/kvm/util/rbtree-interval.c             |   89 ++
+ tools/kvm/util/read-write.c                  |  344 ++++++
+ tools/kvm/util/set_private_br.sh             |   51 +
+ tools/kvm/util/strbuf.c                      |   39 +
+ tools/kvm/util/threadpool.c                  |  145 +++
+ tools/kvm/util/util.c                        |  115 ++
+ tools/kvm/virtio/9p-pdu.c                    |  287 +++++
+ tools/kvm/virtio/9p.c                        | 1326 ++++++++++++++++++++++
+ tools/kvm/virtio/balloon.c                   |  275 +++++
+ tools/kvm/virtio/blk.c                       |  290 +++++
+ tools/kvm/virtio/console.c                   |  203 ++++
+ tools/kvm/virtio/core.c                      |  158 +++
+ tools/kvm/virtio/net.c                       |  547 +++++++++
+ tools/kvm/virtio/pci.c                       |  380 +++++++
+ tools/kvm/virtio/rng.c                       |  203 ++++
+ tools/kvm/virtio/trans.c                     |   24 +
+ tools/kvm/x86/bios.c                         |  174 +++
+ tools/kvm/x86/bios/.gitignore                |    3 +
+ tools/kvm/x86/bios/bios-rom.S                |   12 +
+ tools/kvm/x86/bios/e820.c                    |   72 ++
+ tools/kvm/x86/bios/entry.S                   |   92 ++
+ tools/kvm/x86/bios/gen-offsets.sh            |   14 +
+ tools/kvm/x86/bios/int10.c                   |  110 ++
+ tools/kvm/x86/bios/int15.c                   |   18 +
+ tools/kvm/x86/bios/local.S                   |    7 +
+ tools/kvm/x86/bios/macro.S                   |   25 +
+ tools/kvm/x86/bios/memcpy.c                  |   23 +
+ tools/kvm/x86/bios/rom.ld.S                  |   10 +
+ tools/kvm/x86/cpuid.c                        |   55 +
+ tools/kvm/x86/include/kvm/assembly.h         |   24 +
+ tools/kvm/x86/include/kvm/barrier.h          |   16 +
+ tools/kvm/x86/include/kvm/bios-export.h      |   13 +
+ tools/kvm/x86/include/kvm/bios.h             |   88 ++
+ tools/kvm/x86/include/kvm/boot-protocol.h    |   16 +
+ tools/kvm/x86/include/kvm/cpufeature.h       |   41 +
+ tools/kvm/x86/include/kvm/interrupt.h        |   26 +
+ tools/kvm/x86/include/kvm/kvm-arch.h         |   65 ++
+ tools/kvm/x86/include/kvm/kvm-cpu-arch.h     |   49 +
+ tools/kvm/x86/include/kvm/mptable.h          |    9 +
+ tools/kvm/x86/interrupt.c                    |   28 +
+ tools/kvm/x86/ioport.c                       |   59 +
+ tools/kvm/x86/irq.c                          |  229 ++++
+ tools/kvm/x86/kvm-cpu.c                      |  425 +++++++
+ tools/kvm/x86/kvm.c                          |  385 +++++++
+ tools/kvm/x86/mptable.c                      |  287 +++++
+ 218 files changed, 24003 insertions(+), 1 deletions(-)
+ create mode 100644 tools/kvm/.gitignore
+ create mode 100644 tools/kvm/CREDITS-Git
+ create mode 100644 tools/kvm/Documentation/kernel-debugging.txt
+ create mode 100644 tools/kvm/Documentation/kvm-balloon.txt
+ create mode 100644 tools/kvm/Documentation/kvm-debug.txt
+ create mode 100644 tools/kvm/Documentation/kvm-list.txt
+ create mode 100644 tools/kvm/Documentation/kvm-pause.txt
+ create mode 100644 tools/kvm/Documentation/kvm-resume.txt
+ create mode 100644 tools/kvm/Documentation/kvm-run.txt
+ create mode 100644 tools/kvm/Documentation/kvm-sandbox.txt
+ create mode 100644 tools/kvm/Documentation/kvm-setup.txt
+ create mode 100644 tools/kvm/Documentation/kvm-stat.txt
+ create mode 100644 tools/kvm/Documentation/kvm-stop.txt
+ create mode 100644 tools/kvm/Documentation/kvm-version.txt
+ create mode 100644 tools/kvm/Documentation/virtio-console.txt
+ create mode 100644 tools/kvm/Makefile
+ create mode 100644 tools/kvm/README
+ create mode 100644 tools/kvm/builtin-balloon.c
+ create mode 100644 tools/kvm/builtin-debug.c
+ create mode 100644 tools/kvm/builtin-help.c
+ create mode 100644 tools/kvm/builtin-list.c
+ create mode 100644 tools/kvm/builtin-pause.c
+ create mode 100644 tools/kvm/builtin-resume.c
+ create mode 100644 tools/kvm/builtin-run.c
+ create mode 100644 tools/kvm/builtin-sandbox.c
+ create mode 100644 tools/kvm/builtin-setup.c
+ create mode 100644 tools/kvm/builtin-stat.c
+ create mode 100644 tools/kvm/builtin-stop.c
+ create mode 100644 tools/kvm/builtin-version.c
+ create mode 100644 tools/kvm/code16gcc.h
+ create mode 100644 tools/kvm/command-list.txt
+ create mode 100644 tools/kvm/config/feature-tests.mak
+ create mode 100644 tools/kvm/config/utilities.mak
+ create mode 100644 tools/kvm/disk/blk.c
+ create mode 100644 tools/kvm/disk/core.c
+ create mode 100644 tools/kvm/disk/qcow.c
+ create mode 100644 tools/kvm/disk/raw.c
+ create mode 100644 tools/kvm/framebuffer.c
+ create mode 100644 tools/kvm/guest/init.c
+ create mode 100644 tools/kvm/guest/init_stage2.c
+ create mode 100644 tools/kvm/guest/passwd
+ create mode 100644 tools/kvm/guest_compat.c
+ create mode 100644 tools/kvm/hw/i8042.c
+ create mode 100644 tools/kvm/hw/pci-shmem.c
+ create mode 100644 tools/kvm/hw/rtc.c
+ create mode 100644 tools/kvm/hw/serial.c
+ create mode 100644 tools/kvm/hw/vesa.c
+ create mode 100644 tools/kvm/include/asm/hweight.h
+ create mode 100644 tools/kvm/include/bios/memcpy.h
+ create mode 100644 tools/kvm/include/kvm/8250-serial.h
+ create mode 100644 tools/kvm/include/kvm/apic.h
+ create mode 100644 tools/kvm/include/kvm/brlock.h
+ create mode 100644 tools/kvm/include/kvm/builtin-balloon.h
+ create mode 100644 tools/kvm/include/kvm/builtin-debug.h
+ create mode 100644 tools/kvm/include/kvm/builtin-help.h
+ create mode 100644 tools/kvm/include/kvm/builtin-list.h
+ create mode 100644 tools/kvm/include/kvm/builtin-pause.h
+ create mode 100644 tools/kvm/include/kvm/builtin-resume.h
+ create mode 100644 tools/kvm/include/kvm/builtin-run.h
+ create mode 100644 tools/kvm/include/kvm/builtin-sandbox.h
+ create mode 100644 tools/kvm/include/kvm/builtin-setup.h
+ create mode 100644 tools/kvm/include/kvm/builtin-stat.h
+ create mode 100644 tools/kvm/include/kvm/builtin-stop.h
+ create mode 100644 tools/kvm/include/kvm/builtin-version.h
+ create mode 100644 tools/kvm/include/kvm/compiler.h
+ create mode 100644 tools/kvm/include/kvm/disk-image.h
+ create mode 100644 tools/kvm/include/kvm/e820.h
+ create mode 100644 tools/kvm/include/kvm/framebuffer.h
+ create mode 100644 tools/kvm/include/kvm/guest_compat.h
+ create mode 100644 tools/kvm/include/kvm/i8042.h
+ create mode 100644 tools/kvm/include/kvm/ioeventfd.h
+ create mode 100644 tools/kvm/include/kvm/ioport.h
+ create mode 100644 tools/kvm/include/kvm/irq.h
+ create mode 100644 tools/kvm/include/kvm/kvm-cmd.h
+ create mode 100644 tools/kvm/include/kvm/kvm-cpu.h
+ create mode 100644 tools/kvm/include/kvm/kvm-ipc.h
+ create mode 100644 tools/kvm/include/kvm/kvm.h
+ create mode 100644 tools/kvm/include/kvm/msi.h
+ create mode 100644 tools/kvm/include/kvm/mutex.h
+ create mode 100644 tools/kvm/include/kvm/parse-options.h
+ create mode 100644 tools/kvm/include/kvm/pci-shmem.h
+ create mode 100644 tools/kvm/include/kvm/pci.h
+ create mode 100644 tools/kvm/include/kvm/qcow.h
+ create mode 100644 tools/kvm/include/kvm/rbtree-interval.h
+ create mode 100644 tools/kvm/include/kvm/read-write.h
+ create mode 100644 tools/kvm/include/kvm/rtc.h
+ create mode 100644 tools/kvm/include/kvm/rwsem.h
+ create mode 100644 tools/kvm/include/kvm/sdl.h
+ create mode 100644 tools/kvm/include/kvm/segment.h
+ create mode 100644 tools/kvm/include/kvm/strbuf.h
+ create mode 100644 tools/kvm/include/kvm/symbol.h
+ create mode 100644 tools/kvm/include/kvm/term.h
+ create mode 100644 tools/kvm/include/kvm/threadpool.h
+ create mode 100644 tools/kvm/include/kvm/types.h
+ create mode 100644 tools/kvm/include/kvm/uip.h
+ create mode 100644 tools/kvm/include/kvm/util.h
+ create mode 100644 tools/kvm/include/kvm/vesa.h
+ create mode 100644 tools/kvm/include/kvm/virtio-9p.h
+ create mode 100644 tools/kvm/include/kvm/virtio-balloon.h
+ create mode 100644 tools/kvm/include/kvm/virtio-blk.h
+ create mode 100644 tools/kvm/include/kvm/virtio-console.h
+ create mode 100644 tools/kvm/include/kvm/virtio-net.h
+ create mode 100644 tools/kvm/include/kvm/virtio-pci-dev.h
+ create mode 100644 tools/kvm/include/kvm/virtio-pci.h
+ create mode 100644 tools/kvm/include/kvm/virtio-rng.h
+ create mode 100644 tools/kvm/include/kvm/virtio-trans.h
+ create mode 100644 tools/kvm/include/kvm/virtio.h
+ create mode 100644 tools/kvm/include/kvm/vnc.h
+ create mode 100644 tools/kvm/include/linux/bitops.h
+ create mode 100644 tools/kvm/include/linux/byteorder.h
+ create mode 100644 tools/kvm/include/linux/compiler.h
+ create mode 100644 tools/kvm/include/linux/kernel.h
+ create mode 100644 tools/kvm/include/linux/module.h
+ create mode 100644 tools/kvm/include/linux/prefetch.h
+ create mode 100644 tools/kvm/include/linux/types.h
+ create mode 100644 tools/kvm/ioeventfd.c
+ create mode 100644 tools/kvm/ioport.c
+ create mode 100644 tools/kvm/kvm-cmd.c
+ create mode 100644 tools/kvm/kvm-cpu.c
+ create mode 100644 tools/kvm/kvm-ipc.c
+ create mode 100644 tools/kvm/kvm.c
+ create mode 100644 tools/kvm/main.c
+ create mode 100644 tools/kvm/mmio.c
+ create mode 100644 tools/kvm/net/uip/arp.c
+ create mode 100644 tools/kvm/net/uip/buf.c
+ create mode 100644 tools/kvm/net/uip/core.c
+ create mode 100644 tools/kvm/net/uip/csum.c
+ create mode 100644 tools/kvm/net/uip/dhcp.c
+ create mode 100644 tools/kvm/net/uip/icmp.c
+ create mode 100644 tools/kvm/net/uip/ipv4.c
+ create mode 100644 tools/kvm/net/uip/tcp.c
+ create mode 100644 tools/kvm/net/uip/udp.c
+ create mode 100644 tools/kvm/pci.c
+ create mode 100644 tools/kvm/powerpc/cpu_info.c
+ create mode 100644 tools/kvm/powerpc/cpu_info.h
+ create mode 100644 tools/kvm/powerpc/include/kvm/barrier.h
+ create mode 100644 tools/kvm/powerpc/include/kvm/kvm-arch.h
+ create mode 100644 tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h
+ create mode 100644 tools/kvm/powerpc/ioport.c
+ create mode 100644 tools/kvm/powerpc/irq.c
+ create mode 100644 tools/kvm/powerpc/kvm-cpu.c
+ create mode 100644 tools/kvm/powerpc/kvm.c
+ create mode 100644 tools/kvm/powerpc/spapr.h
+ create mode 100644 tools/kvm/powerpc/spapr_hcall.c
+ create mode 100644 tools/kvm/powerpc/spapr_hvcons.c
+ create mode 100644 tools/kvm/powerpc/spapr_hvcons.h
+ create mode 100644 tools/kvm/powerpc/spapr_pci.c
+ create mode 100644 tools/kvm/powerpc/spapr_pci.h
+ create mode 100644 tools/kvm/powerpc/spapr_rtas.c
+ create mode 100644 tools/kvm/powerpc/xics.c
+ create mode 100644 tools/kvm/powerpc/xics.h
+ create mode 100644 tools/kvm/symbol.c
+ create mode 100644 tools/kvm/term.c
+ create mode 100644 tools/kvm/tests/Makefile
+ create mode 100644 tools/kvm/tests/boot/Makefile
+ create mode 100644 tools/kvm/tests/boot/init.c
+ create mode 100644 tools/kvm/tests/kernel/.gitignore
+ create mode 100644 tools/kvm/tests/kernel/Makefile
+ create mode 100644 tools/kvm/tests/kernel/README
+ create mode 100644 tools/kvm/tests/kernel/kernel.S
+ create mode 100644 tools/kvm/tests/pit/.gitignore
+ create mode 100644 tools/kvm/tests/pit/Makefile
+ create mode 100644 tools/kvm/tests/pit/README
+ create mode 100644 tools/kvm/tests/pit/tick.S
+ create mode 100644 tools/kvm/ui/sdl.c
+ create mode 100644 tools/kvm/ui/vnc.c
+ create mode 100755 tools/kvm/util/KVMTOOLS-VERSION-GEN
+ create mode 100755 tools/kvm/util/generate-cmdlist.sh
+ create mode 100755 tools/kvm/util/kvm-ifup-vbr0
+ create mode 100644 tools/kvm/util/parse-options.c
+ create mode 100644 tools/kvm/util/rbtree-interval.c
+ create mode 100644 tools/kvm/util/read-write.c
+ create mode 100755 tools/kvm/util/set_private_br.sh
+ create mode 100644 tools/kvm/util/strbuf.c
+ create mode 100644 tools/kvm/util/threadpool.c
+ create mode 100644 tools/kvm/util/util.c
+ create mode 100644 tools/kvm/virtio/9p-pdu.c
+ create mode 100644 tools/kvm/virtio/9p.c
+ create mode 100644 tools/kvm/virtio/balloon.c
+ create mode 100644 tools/kvm/virtio/blk.c
+ create mode 100644 tools/kvm/virtio/console.c
+ create mode 100644 tools/kvm/virtio/core.c
+ create mode 100644 tools/kvm/virtio/net.c
+ create mode 100644 tools/kvm/virtio/pci.c
+ create mode 100644 tools/kvm/virtio/rng.c
+ create mode 100644 tools/kvm/virtio/trans.c
+ create mode 100644 tools/kvm/x86/bios.c
+ create mode 100644 tools/kvm/x86/bios/.gitignore
+ create mode 100644 tools/kvm/x86/bios/bios-rom.S
+ create mode 100644 tools/kvm/x86/bios/e820.c
+ create mode 100644 tools/kvm/x86/bios/entry.S
+ create mode 100644 tools/kvm/x86/bios/gen-offsets.sh
+ create mode 100644 tools/kvm/x86/bios/int10.c
+ create mode 100644 tools/kvm/x86/bios/int15.c
+ create mode 100644 tools/kvm/x86/bios/local.S
+ create mode 100644 tools/kvm/x86/bios/macro.S
+ create mode 100644 tools/kvm/x86/bios/memcpy.c
+ create mode 100644 tools/kvm/x86/bios/rom.ld.S
+ create mode 100644 tools/kvm/x86/cpuid.c
+ create mode 100644 tools/kvm/x86/include/kvm/assembly.h
+ create mode 100644 tools/kvm/x86/include/kvm/barrier.h
+ create mode 100644 tools/kvm/x86/include/kvm/bios-export.h
+ create mode 100644 tools/kvm/x86/include/kvm/bios.h
+ create mode 100644 tools/kvm/x86/include/kvm/boot-protocol.h
+ create mode 100644 tools/kvm/x86/include/kvm/cpufeature.h
+ create mode 100644 tools/kvm/x86/include/kvm/interrupt.h
+ create mode 100644 tools/kvm/x86/include/kvm/kvm-arch.h
+ create mode 100644 tools/kvm/x86/include/kvm/kvm-cpu-arch.h
+ create mode 100644 tools/kvm/x86/include/kvm/mptable.h
+ create mode 100644 tools/kvm/x86/interrupt.c
+ create mode 100644 tools/kvm/x86/ioport.c
+ create mode 100644 tools/kvm/x86/irq.c
+ create mode 100644 tools/kvm/x86/kvm-cpu.c
+ create mode 100644 tools/kvm/x86/kvm.c
+ create mode 100644 tools/kvm/x86/mptable.c
+Merging dma-mapping/dma-mapping-next (e972541 common: DMA-mapping: add NON-CONSISTENT attribute)
+$ git merge dma-mapping/dma-mapping-next
+Auto-merging lib/swiotlb.c
+Auto-merging drivers/iommu/intel-iommu.c
+Auto-merging arch/powerpc/kernel/ibmebus.c
+Auto-merging arch/hexagon/kernel/dma.c
+Merge made by the 'recursive' strategy.
+ Documentation/DMA-attributes.txt          |   19 +++++++++++++++++++
+ arch/alpha/include/asm/dma-mapping.h      |   18 ++++++++++++------
+ arch/alpha/kernel/pci-noop.c              |   10 ++++++----
+ arch/alpha/kernel/pci_iommu.c             |   10 ++++++----
+ arch/hexagon/include/asm/dma-mapping.h    |   18 ++++++++++++------
+ arch/hexagon/kernel/dma.c                 |    9 +++++----
+ arch/ia64/hp/common/sba_iommu.c           |   11 ++++++-----
+ arch/ia64/include/asm/dma-mapping.h       |   18 ++++++++++++------
+ arch/ia64/kernel/pci-swiotlb.c            |    9 +++++----
+ arch/ia64/sn/pci/pci_dma.c                |    9 +++++----
+ arch/microblaze/include/asm/dma-mapping.h |   18 ++++++++++++------
+ arch/microblaze/kernel/dma.c              |   10 ++++++----
+ arch/mips/cavium-octeon/dma-octeon.c      |   16 ++++++++--------
+ arch/mips/include/asm/dma-mapping.h       |   18 ++++++++++++------
+ arch/mips/mm/dma-default.c                |    8 ++++----
+ arch/powerpc/include/asm/dma-mapping.h    |   24 ++++++++++++++++--------
+ arch/powerpc/kernel/dma-iommu.c           |   10 ++++++----
+ arch/powerpc/kernel/dma-swiotlb.c         |    4 ++--
+ arch/powerpc/kernel/dma.c                 |   10 ++++++----
+ arch/powerpc/kernel/ibmebus.c             |   10 ++++++----
+ arch/powerpc/kernel/vio.c                 |   14 ++++++++------
+ arch/powerpc/platforms/cell/iommu.c       |   16 +++++++++-------
+ arch/powerpc/platforms/ps3/system-bus.c   |   13 +++++++------
+ arch/sh/include/asm/dma-mapping.h         |   28 ++++++++++++++++++----------
+ arch/sh/kernel/dma-nommu.c                |    4 ++--
+ arch/sh/mm/consistent.c                   |    6 ++++--
+ arch/sparc/include/asm/dma-mapping.h      |   18 ++++++++++++------
+ arch/sparc/kernel/iommu.c                 |   10 ++++++----
+ arch/sparc/kernel/ioport.c                |   18 ++++++++++--------
+ arch/sparc/kernel/pci_sun4v.c             |    9 +++++----
+ arch/unicore32/include/asm/dma-mapping.h  |   18 ++++++++++++------
+ arch/unicore32/mm/dma-swiotlb.c           |    4 ++--
+ arch/x86/include/asm/dma-mapping.h        |   26 ++++++++++++++++----------
+ arch/x86/kernel/amd_gart_64.c             |   11 ++++++-----
+ arch/x86/kernel/pci-calgary_64.c          |    9 +++++----
+ arch/x86/kernel/pci-dma.c                 |    3 ++-
+ arch/x86/kernel/pci-nommu.c               |    6 +++---
+ arch/x86/kernel/pci-swiotlb.c             |   12 +++++++-----
+ arch/x86/xen/pci-swiotlb-xen.c            |    4 ++--
+ drivers/iommu/amd_iommu.c                 |   10 ++++++----
+ drivers/iommu/intel-iommu.c               |    9 +++++----
+ drivers/xen/swiotlb-xen.c                 |    5 +++--
+ include/linux/dma-attrs.h                 |    2 ++
+ include/linux/dma-mapping.h               |   13 +++++++++----
+ include/linux/swiotlb.h                   |    6 ++++--
+ include/xen/swiotlb-xen.h                 |    6 ++++--
+ lib/swiotlb.c                             |    5 +++--
+ 47 files changed, 338 insertions(+), 206 deletions(-)
+Merging ktest/for-next (be405f9 ktest: Add INGORE_ERRORS to ignore warnings in boot up)
+$ git merge ktest/for-next
+Already up-to-date.
+Merging scsi-post-merge/merge-base:master ()
+$ git clone -s -l -n -q . ../rebase-tmp
+$ cd ../rebase-tmp
+$ git fetch --no-tags ../next refs/heads/quilt/akpm:akpm
+From ../next
+ * [new branch]      quilt/akpm -> akpm
+$ git fetch --no-tags ../next refs/heads/quilt/akpm-base:akpm-base
+From ../next
+ * [new branch]      quilt/akpm-base -> akpm-base
+$ git checkout akpm
+Switched to branch 'akpm'
+$ git rebase --onto master akpm-base
+First, rewinding head to replay your work on top of it...
+Applying: kmsg_dump: don't run on non-error paths by default
+Applying: kprobes: return proper error code from register_kprobe()
+Applying: aio: wake up waiters when freeing unused kiocbs
+Applying: net/netfilter/nf_conntrack_netlink.c: fix Oops on container destroy
+Applying: acerhdf: add support for Aspire 1410 BIOS v1.3314
+Applying: acerhdf: add support for new hardware
+Applying: acerhdf: lowered default temp fanon/fanoff values
+Applying: arch/x86/platform/iris/iris.c: register a platform device and a platform driver
+Applying: x86, olpc-xo15-sci: enable lid close wakeup control through sysfs
+Applying: geos: platform driver for Geos and Geos2 single-board computers
+Applying: platform-drivers-x86: convert drivers/platform/x86/* to use module_platform_driver()
+Applying: drivers/platform/x86/sony-laptop.c: fix scancodes
+Applying: platform, x86: kill off Moorestown
+Applying: intel_scu_ipc: remove Moorestown support
+Applying: platform-x86: intel_mid_thermal: add msic_thermal alias
+Applying: platform-x86: intel_mid_thermal: convert to use Intel MSIC API
+Applying: platform-x86: intel_mid_thermal: turn off thermistor voltage by default
+Applying: intel_mid_powerbtn: use MSIC read/write instead of ipc_scu
+Applying: intel_mid_powerbtn: mark irq as IRQF_NO_SUSPEND
+Applying: x86, olpc: add debugfs interface for EC commands
+Applying: x86, mm: fix the size calculation of mapping tables
+Applying: alix2: supplement driver to include GPIO button support
+Applying: x86: net5501: platform driver for Soekris Engineering net5501 single-board computer
+Applying: x86: use this_cpu_xxx to replace percpu_xxx funcs
+Applying: x86: change percpu_read_stable() to this_cpu_read_stable()
+Applying: arch/arm/mach-ux500/mbox-db5500.c: world-writable sysfs fifo file
+Applying: arm, exec: remove redundant set_fs(USER_DS)
+Applying: arm: use set_current_blocked() and block_sigmask()
+Applying: avr32: don't mask signals in the error path
+Applying: avr32: use set_current_blocked() in handle_signal/sys_rt_sigreturn
+Applying: avr32: use block_sigmask()
+Applying: fs/btrfs/inode-map.c: fix warnings
+Applying: powerpc: use set_current_blocked() and block_sigmask()
+Applying: Hexagon: use set_current_blocked() and block_sigmask()
+Applying: irqs: fix long-term regression in genirq irq_set_irq_type() handling
+Applying: irqs: fix handling of pending IRQs at request time
+Applying: softirq: reduce invoke_softirq() code duplication
+Applying: tile: use set_current_blocked() and block_sigmask()
+Applying: hrtimers: Special-case zero length sleeps
+Applying: cs5535-clockevt: don't ignore MFGPT on SMP-capable kernels
+Applying: cs5535-clockevt: allow the MFGPT IRQ to be shared
+Applying: hpet: factor timer allocate from open
+Applying: ia64: use set_current_blocked() and block_sigmask()
+Applying: microblaze: don't reimplement force_sigsegv()
+Applying: microblaze: no need to reset handler if SA_ONESHOT
+Applying: microblaze: fix signal masking
+Applying: microblaze: use set_current_blocked() and block_sigmask()
+Applying: MIPS: use set_current_blocked() and block_sigmask()
+Applying: score: don't mask signals if we fail to setup signal stack
+Applying: score: use set_current_blocked() and block_sigmask()
+Applying: drivers/thermal/thermal_sys.c: fix build warning
+Applying: thermal_sys: remove unnecessary line continuations
+Applying: thermal_sys: remove obfuscating used-once macros
+Applying: thermal_sys: kernel style cleanups
+Applying: thermal_sys: convert printks to pr_<level>
+Applying: unicore32: use block_sigmask()
+Applying: blackfin: use set_current_blocked() and block_sigmask()
+Applying: bluetooth: add support for BCM20702A0 [0a5c:21e6]
+Applying: debugobjects: Fix selftest for static warnings
+Applying: ocfs2: use find_last_bit()
+Applying: ocfs2: use bitmap_weight()
+Applying: parisc: use set_current_blocked() and block_sigmask()
+Applying: S390: use block_sigmask()
+Applying: xtensa: don't reimplement force_sigsegv()
+Applying: xtensa: no need to reset handler if SA_ONESHOT
+Applying: xtensa: don't mask signals if we fail to setup signal stack
+Applying: xtensa: use set_current_blocked() and block_sigmask()
+Applying: slab: introduce kmalloc_array()
+Applying: sparc: use block_sigmask()
+Applying: mm, oom: avoid looping when chosen thread detaches its mm
+Applying: mm, oom: fold oom_kill_task() into oom_kill_process()
+Applying: mm, oom: do not emit oom killer warning if chosen thread is already exiting
+Applying: mm, oom: introduce independent oom killer ratelimit state
+Applying: mm: add rss counters consistency check
+Applying: mm/vmscan.c: cleanup with s/reclaim_mode/isolate_mode/
+Applying: mm: make get_mm_counter static-inline
+Applying: mm: vmscan: fix misused nr_reclaimed in shrink_mem_cgroup_zone()
+Applying: mm: make swapin readahead skip over holes
+Applying: make-swapin-readahead-skip-over-holes-fix
+Applying: vmscan: reclaim at order 0 when compaction is enabled
+Applying: vmscan: kswapd carefully call compaction
+Applying: vmscan-kswapd-carefully-call-compaction-fix
+Applying: vmscan: only defer compaction for failed order and higher
+Applying: compact_pgdat: workaround lockdep warning in kswapd
+Applying: mm: compaction: make compact_control order signed
+Applying: mm-compaction-make-compact_control-order-signed-fix
+Applying: hugetlbfs: fix hugetlb_get_unmapped_area()
+Applying: hugetlb: drop prev_vma in hugetlb_get_unmapped_area_topdown()
+Applying: hugetlb: try to search again if it is really needed
+Applying: hugetlb-try-to-search-again-if-it-is-really-needed-fix
+Applying: mm: do not reset cached_hole_size when vma is unmapped
+Applying: mm: search from free_area_cache for the bigger size
+Applying: pagemap: avoid splitting thp when reading /proc/pid/pagemap
+Applying: thp: optimize away unnecessary page table locking
+Applying: pagemap: export KPF_THP
+Applying: pagemap: document KPF_THP and make page-types aware of it
+Applying: pagemap: introduce data structure for pagemap entry
+Applying: mm: replace PAGE_MIGRATION with IS_ENABLED(CONFIG_MIGRATION)
+Applying: mm: vmscan: forcibly scan highmem if there are too many buffer_heads pinning highmem
+Applying: mm: hugetlb: defer freeing pages when gathering surplus pages
+Applying: mm: replace COMPACTION_BUILD with IS_ENABLED(CONFIG_COMPACTION)
+Applying: mm-replace-compaction_build-with-is_enabledconfig_compaction-fix
+Applying: mm: fix page-faults detection in swap-token logic
+Applying: mm: add extra free kbytes tunable
+Applying: mm-add-extra-free-kbytes-tunable-update
+Applying: mm-add-extra-free-kbytes-tunable-update-checkpatch-fixes
+Applying: memcg: replace MEM_CONT by MEM_RES_CTLR
+Applying: memcg: replace mem and mem_cont stragglers
+Applying: memcg: lru_size instead of MEM_CGROUP_ZSTAT
+Applying: memcg: enum lru_list lru
+Applying: memcg: remove redundant returns
+Applying: memcg: remove unnecessary thp check in page stat accounting
+Applying: idr: make idr_get_next() good for rcu_read_lock()
+Applying: cgroup: revert ss_id_lock to spinlock
+Applying: memcg: let css_get_next() rely upon rcu_read_lock()
+Applying: memcg: remove PCG_CACHE page_cgroup flag
+Applying: memcg-remove-pcg_cache-page_cgroup-flag-checkpatch-fixes
+Applying: memcg: kill dead prev_priority stubs
+Applying: frv: use set_current_blocked() and block_sigmask()
+Applying: sh: no need to reset handler if SA_ONESHOT
+Applying: sh: use set_current_blocked() and block_sigmask()
+Applying: h8300: use set_current_blocked() and block_sigmask()
+Applying: alpha: use set_current_blocked() and block_sigmask()
+Applying: m32r: use set_current_blocked() and block_sigmask()
+Applying: m68k: use set_current_blocked() and block_sigmask()
+Applying: mn10300: use set_current_blocked() and block_sigmask()
+Applying: C6X: use set_current_blocked() and block_sigmask()
+Applying: cris: use set_current_blocked() and block_sigmask()
+Applying: um: don't restore current->blocked on error
+Applying: um: use set_current_blocked() and block_sigmask()
+Applying: magic.h: move some FS magic numbers into magic.h
+Applying: nmi watchdog: do not use cpp symbol in Kconfig
+Applying: ceph, cifs, nfs, fuse: boolean and / or confusion
+Applying: net: use this_cpu_xxx replace percpu_xxx funcs
+Applying: percpu: remove percpu_xxx() functions
+Applying: prctl: add PR_{SET,GET}_CHILD_SUBREAPER to allow simple process supervision
+Applying: prctl-add-pr_setget_child_subreaper-to-allow-simple-process-supervision-fix
+Applying: prctl-add-pr_setget_child_subreaper-to-allow-simple-process-supervision-fix-fix
+Applying: kernel/exit.c: if init dies, log a signal which killed it, if any
+Applying: kernel-exitc-if-init-dies-log-a-signal-which-killed-it-if-any-fix
+Applying: posix_types: make __kernel_[ug]id32_t default to unsigned int
+Applying: posix_types: make it possible to override __kernel_fsid_t
+Applying: alpha: use generic posix_types.h
+Applying: arm: use generic posix_types.h
+Applying: avr32: use generic posix_types.h
+Applying: cris: use generic posix_types.h
+Applying: frv: use generic posix_types.h
+Applying: h8300: use generic posix_types.h
+Applying: ia64: use generic posix_types.h
+Applying: m32r: use generic posix_types.h
+Applying: m68k: use generic posix_types.h
+Applying: mips: use generic posix_types.h
+Applying: mn10300: use generic posix_types.h
+Applying: parisc: use generic posix_types.h
+Applying: powerpc: use generic posix_types.h
+Applying: s390: use generic posix_types.h
+Applying: sh: remove unnecessary posix_types.h type overrides
+Applying: sparc: use generic posix_types.h
+Applying: x86: use generic posix_types.h
+Applying: xtensa: use generic posix_types.h
+Applying: posix_types: remove fd_set macros
+Applying: posix_types-remove-fd_set-macros-checkpatch-fixes
+Applying: vfs: increment iversion when a file is truncated
+Applying: brlocks/lglocks: cleanups
+Applying: brlocks-lglocks-cleanups-checkpatch-fixes
+Applying: vfs: correctly set the dir i_mutex lockdep class
+Applying: seq_file: fix mishandling of consecutive pread() invocations.
+Applying: MAINTAINERS: fix REMOTEPROC F: typo
+Applying: MAINTAINERS: Update MCA section
+Applying: MAINTAINERS: update git urls for 2.6 deletions
+Applying: backlight: convert backlight i2c drivers to module_i2c_driver
+Applying: backlight: convert backlight spi drivers to module_spi_driver
+Applying: drivers/video/backlight/wm831x_bl.c: use devm_ functions
+Applying: drivers/video/backlight: use devm_ functions
+Applying: drivers/video/backlight/adp5520_bl.c: use devm_ functions
+Applying: backlight: new backlight driver for LP855x devices
+Applying: backlight: lp855x_bl: Add missing mutex_unlock in lp855x_read_byte error path
+Applying: backlight/lp855x_bl.c: check platform data in lp855x_probe()
+Applying: backlight/lp855x_bl.c: small cleanups
+Applying: backlight: add driver for Bachmann's ot200
+Applying: backlight-add-driver-for-bachmanns-ot200-fix
+Applying: backlight: add support for Pandora backlight
+Applying: backlight-add-support-for-pandora-backlight-v2
+Applying: bitops: rename for_each_set_bit_cont() in favor of analogous list.h function
+Applying: bitops: remove for_each_set_bit_cont()
+Applying: bitops: introduce for_each_clear_bit()
+Applying: mtd: use for_each_clear_bit()
+Applying: s390/char: use for_each_clear_bit()
+Applying: uwb: use for_each_clear_bit()
+Applying: x86: use for_each_clear_bit_from()
+Applying: drivers/leds/leds-lp5521.c: fix typo
+Applying: drivers/leds/leds-tca6507.c: cleanup error handling in tca6507_probe()
+Applying: drivers/leds/leds-lp5521.c: add 'name' in the lp5521_led_config
+Applying: drivers/leds/leds-lp5521.c: add 'update_config' in the lp5521_platform_data
+Applying: drivers/leds/leds-lp5521.c: support led pattern data
+Applying: leds-lp5521-support-led-pattern-data-checkpatch-fixes
+Applying: drivers/leds/leds-lp5521.c: redefinition of register bits
+Applying: drivers/leds/leds-lp5523.c: constify some data
+Applying: drivers/leds: add driver for PCA9633 I2C chip
+Applying: drivers-leds-add-driver-for-pca9663-i2c-chip-fix
+Applying: drivers-leds-add-driver-for-pca9663-i2c-chip-fix-2
+Applying: drivers/leds/leds-gpio.c: use linux/gpio.h rather than asm/gpio.h
+Applying: leds-lm3530: set the max_brightness to 127
+Applying: leds-lm3530: replace i2c_client with led_classdev
+Applying: leds-lm3530-replace-i2c_client-with-led_classdev-fix
+Applying: leds-lm3530: support pwm input mode
+Applying: leds-lm3530: remove LM3530_ALS_ZONE_REG code
+Applying: leds-lm3530: replace pltfm with pdata
+Applying: drivers/leds/leds-pca9633.c: remove unused 'adapter' variable
+Applying: drivers/leds/leds-lm3530.c: move the code setting gen_config to one place
+Applying: drivers-leds-leds-lm3530c-move-the-code-setting-gen_config-to-one-place-fix
+Applying: string: memchr_inv speed improvements
+Applying: prio_tree: remove unnecessary code in prio_tree_replace
+Applying: prio_tree: cleanup prio_tree_left()/prio_tree_right()
+Applying: prio_tree: simplify prio_tree_expand()
+Applying: prio_tree: introduce prio_set_parent()
+Applying: include/ and checkpatch: prefer __scanf to __attribute__((format(scanf,...)
+Applying: crc32: remove two instances of trailing whitespaces
+Applying: crc32: move long comment about crc32 fundamentals to Documentation/
+Applying: crc32-move-long-comment-about-crc32-fundamentals-to-documentation-fix
+Applying: crc32: simplify unit test code
+Applying: crc32: miscellaneous cleanups
+Applying: crc32: fix mixing of endian-specific types
+Applying: crc32: make CRC_*_BITS definition correspond to actual bit counts
+Applying: crc32: add slice-by-8 algorithm to existing code
+Applying: crc32: optimize loop counter for x86
+Applying: crc32: add note about this patchset to crc32.c
+Applying: crc32: bolt on crc32c
+Applying: crc32: Don't reference unnecessary crc32 tables in single-bit mode
+Applying: crypto: crc32c should use library implementation
+Applying: crc32: add self-test code for crc32c
+Applying: crc32: select an algorithm via Kconfig
+Applying: epoll: comment the funky #ifdef
+Applying: init/do_mounts.c: create /root if it does not exist
+Applying: rtc-spear: fix for balancing the enable_irq_wake in Power Mgmt
+Applying: rtc/spear: fix for RTC_AIE_ON and RTC_AIE_OFF ioctl errors
+Applying: rtc/rtc-spear: call platform_set_drvdata() before registering rtc device
+Applying: rtc: convert rtc spi drivers to module_spi_driver
+Applying: rtc: convert rtc i2c drivers to module_i2c_driver
+Applying: MIPS: add RTC support for loongson1B
+Applying: drivers/rtc/rtc-twl.c: optimize IRQ bit access
+Applying: drivers/rtc/rtc-twl.c: enable RTC irrespective of its prior state
+Applying: drivers/rtc/rtc-twl.c: simplify RTC interrupt clearing
+Applying: drivers/rtc/rtc-twl.c: return correct RTC event from ISR
+Applying: drivers/rtc: remove IRQF_DISABLED
+Applying: drivers/rtc/rtc-pm8xxx.c: make pm8xxx_rtc_pm_ops static
+Applying: drivers/rtc/rtc-max8925.c: fix max8925_rtc_read_alarm() return value error
+Applying: drivers/rtc/rtc-max8925.c: fix alarm->enabled mistake in max8925_rtc_read_alarm/max8925_rtc_set_alarm
+Applying: rtc: driver for DA9052/53 PMIC v1
+Applying: rtc-rtc-driver-for-da9052-53-pmic-v1-fix
+Applying: ptrace: the killed tracee should not enter the syscall
+Applying: ptrace: don't send SIGTRAP on exec if SEIZED
+Applying: ptrace: don't modify flags on PTRACE_SETOPTIONS failure
+Applying: ptrace: simplify PTRACE_foo constants and PTRACE_SETOPTIONS code
+Applying: ptrace: make PTRACE_SEIZE set ptrace options specified in 'data' parameter
+Applying: ptrace: renumber PTRACE_EVENT_STOP so that future new options and events can match
+Applying: ptrace: remove PTRACE_SEIZE_DEVEL bit
+Applying: signal: give SEND_SIG_FORCED more power to beat SIGNAL_UNKILLABLE
+Applying: signal: cosmetic, s/from_ancestor_ns/force/ in prepare_signal() paths
+Applying: signal: oom_kill_task: use SEND_SIG_FORCED instead of force_sig()
+Applying: signal: zap_pid_ns_processes: s/SEND_SIG_NOINFO/SEND_SIG_FORCED/
+Applying: usermodehelper: use UMH_WAIT_PROC consistently
+Applying: usermodehelper: introduce umh_complete(sub_info)
+Applying: usermodehelper: implement UMH_KILLABLE
+Applying: usermodehelper: kill umh_wait, renumber UMH_* constants
+Applying: usermodehelper: ____call_usermodehelper() doesn't need do_exit()
+Applying: kmod: introduce call_modprobe() helper
+Applying: kmod: make __request_module() killable
+Applying: kmod: avoid deadlock from recursive kmod call
+Applying: kmod-avoid-deadlock-by-recursive-kmod-call-fix
+Applying: fs/proc/kcore.c: make get_sparsemem_vmemmap_info() static
+Applying: proc: speedup /proc/stat handling
+Applying: procfs: add num_to_str() to speed up /proc/stat
+Applying: procfs-add-num_to_str-to-speed-up-proc-stat-fix
+Applying: procfs: avoid breaking the ABI in /proc/stat
+Applying: procfs: speed up /proc/pid/stat, statm
+Applying: procfs-speed-up-proc-pid-stat-statm-checkpatch-fixes
+Applying: proc: clean up /proc/<pid>/environ handling
+Applying: seq_file: add seq_set_overflow(), seq_overflow()
+Applying: seq_file-add-seq_set_overflow-seq_overflow-fix
+Applying: smp: introduce a generic on_each_cpu_mask() function
+Applying: arm: move arm over to generic on_each_cpu_mask
+Applying: tile: move tile to use generic on_each_cpu_mask
+Applying: smp: add func to IPI cpus based on parameter func
+Applying: smp-add-func-to-ipi-cpus-based-on-parameter-func-fix
+Applying: smp-add-func-to-ipi-cpus-based-on-parameter-func-update
+Applying: smp-add-func-to-ipi-cpus-based-on-parameter-func-update-fix
+Applying: smp: add func to IPI cpus based on parameter func
+Applying: smp-add-func-to-ipi-cpus-based-on-parameter-func-v9-fix
+Applying: slub: only IPI CPUs that have per cpu obj to flush
+Applying: fs: only send IPI to invalidate LRU BH when needed
+Applying: mm: only IPI CPUs to drain local pages if they exist
+Applying: mm-only-ipi-cpus-to-drain-local-pages-if-they-exist-update
+Applying: mm-only-ipi-cpus-to-drain-local-pages-if-they-exist-v9
+Applying: lib/cpumask.c: remove __any_online_cpu()
+Applying: arch/ia64: remove references to cpu_*_map
+Applying: cpumask: avoid mask based num_possible_cpus() and num_online_cpus()
+Applying: ipc/sem.c: alternatives to preempt_disable()
+Applying: ipc: provide generic compat versions of IPC syscalls
+Applying: ipmi: decrease the IPMI message transaction time in interrupt mode
+Applying: ipmi: increase KCS timeouts
+Applying: ipmi: use a tasklet for handling received messages
+Applying: ipmi: fix message handling during panics
+Applying: ipmi: simplify locking
+Applying: ipmi: use locks on watchdog timeout set on reboot
+Applying: sysctl: use bitmap library functions
+Applying: pidns: add reboot_pid_ns() to handle the reboot syscall
+Applying: pidns-add-reboot_pid_ns-to-handle-the-reboot-syscall-fix
+Applying: pidns-add-reboot_pid_ns-to-handle-the-reboot-syscall-checkpatch-fixes
+Applying: fs/proc/namespaces.c: prevent crash when ns_entries[] is empty
+Applying: selftests: launch individual selftests from the main Makefile
+Applying: selftests/Makefile: make `run_tests' depend on `all'
+Applying: mm: move page-types.c from Documentation to tools/vm
+Applying: mm: move slabinfo.c to tools/vm
+Applying: mm: move hugepage test examples to tools/testing/selftests/vm
+Applying: move-hugepage-test-examples-to-tools-testing-selftests-vm-fix
+Applying: move-hugepage-test-examples-to-tools-testing-selftests-vm-fix-fix
+Applying: sysctl: make kernel.ns_last_pid control dependent on CHECKPOINT_RESTORE
+Applying: fs, proc: introduce /proc/<pid>/task/<tid>/children entry
+Applying: syscalls, x86: add __NR_kcmp syscall
+Applying: c/r: procfs: add arg_start/end, env_start/end and exit_code members to /proc/$pid/stat
+Applying: c/r: prctl: extend PR_SET_MM to set up more mm_struct entries
+Applying: ramoops: use pstore interface
+Applying: ramoops: fix printk format warnings
+Applying: notify_change(): check that i_mutex is held
+Applying: syscalls-x86-add-__nr_kcmp-syscall-v8-fix
+Applying: powerpc: use generic posix_types.h fix
+$ cd ../next
+$ git fetch -f ../rebase-tmp akpm:akpm
+From ../rebase-tmp
+ + 79bad61...44f131f akpm       -> akpm  (forced update)
+$ rm -rf ../rebase-tmp
+Merging akpm (44f131f powerpc: use generic posix_types.h fix)
+$ git merge --no-ff akpm
+Auto-merging tools/vm/page-types.c
+Auto-merging tools/testing/selftests/vm/map_hugetlb.c
+Auto-merging tools/testing/selftests/vm/hugepage-shm.c
+Auto-merging tools/testing/selftests/vm/hugepage-mmap.c
+Removing tools/testing/selftests/run_tests
+Removing include/linux/rar_register.h
+Removing drivers/platform/x86/intel_rar_register.c
+Removing drivers/leds/leds-net5501.c
+Removing Documentation/vm/Makefile
+Merge made by the 'recursive' strategy.
+ Documentation/00-INDEX                             |    2 +
+ Documentation/ABI/testing/debugfs-olpc             |   16 +
+ Documentation/Makefile                             |    2 +-
+ Documentation/backlight/lp855x-driver.txt          |   81 ++
+ Documentation/crc32.txt                            |  183 +++
+ Documentation/filesystems/proc.txt                 |   23 +
+ Documentation/kernel-parameters.txt                |    6 +
+ Documentation/laptops/sony-laptop.txt              |    5 +
+ Documentation/leds/leds-lp5521.txt                 |   63 +
+ Documentation/ramoops.txt                          |    8 +-
+ Documentation/sysctl/vm.txt                        |   16 +
+ Documentation/vm/Makefile                          |    8 -
+ Documentation/vm/pagemap.txt                       |    4 +
+ MAINTAINERS                                        |  123 +-
+ arch/Kconfig                                       |    6 +
+ arch/alpha/include/asm/posix_types.h               |  113 +--
+ arch/alpha/kernel/signal.c                         |   31 +-
+ arch/arm/include/asm/posix_types.h                 |   55 +-
+ arch/arm/include/asm/processor.h                   |    1 -
+ arch/arm/kernel/signal.c                           |   24 +-
+ arch/arm/kernel/smp_tlb.c                          |   20 +-
+ arch/arm/mach-ux500/mbox-db5500.c                  |    2 +-
+ arch/avr32/include/asm/posix_types.h               |  107 +--
+ arch/avr32/kernel/signal.c                         |   26 +-
+ arch/blackfin/Kconfig                              |    1 +
+ arch/blackfin/include/asm/irq.h                    |    4 -
+ arch/blackfin/kernel/signal.c                      |   17 +-
+ arch/c6x/kernel/signal.c                           |   16 +-
+ arch/cris/arch-v10/kernel/signal.c                 |   34 +-
+ arch/cris/arch-v32/kernel/signal.c                 |   37 +-
+ arch/cris/include/asm/posix_types.h                |   50 +-
+ arch/frv/include/asm/posix_types.h                 |   53 +-
+ arch/frv/kernel/signal.c                           |   32 +-
+ arch/h8300/include/asm/posix_types.h               |   49 +-
+ arch/h8300/kernel/signal.c                         |   33 +-
+ arch/hexagon/kernel/signal.c                       |   12 +-
+ arch/ia64/include/asm/posix_types.h                |  121 +--
+ arch/ia64/kernel/acpi.c                            |    6 +-
+ arch/ia64/kernel/irq_ia64.c                        |    8 +-
+ arch/ia64/kernel/mca.c                             |    6 +-
+ arch/ia64/kernel/msi_ia64.c                        |    4 +-
+ arch/ia64/kernel/setup.c                           |    2 +-
+ arch/ia64/kernel/signal.c                          |   15 +-
+ arch/ia64/kernel/smp.c                             |    2 +-
+ arch/ia64/kernel/smpboot.c                         |   19 +-
+ arch/ia64/kernel/topology.c                        |    3 +-
+ arch/m32r/include/asm/posix_types.h                |  108 +--
+ arch/m32r/kernel/signal.c                          |   12 +-
+ arch/m68k/include/asm/posix_types.h                |   53 +-
+ arch/m68k/kernel/signal_mm.c                       |   22 +-
+ arch/m68k/kernel/signal_no.c                       |   28 +-
+ arch/microblaze/kernel/signal.c                    |   42 +-
+ arch/mips/Kconfig                                  |    1 +
+ arch/mips/include/asm/posix_types.h                |  117 +--
+ arch/mips/kernel/signal.c                          |   27 +-
+ arch/mips/kernel/signal32.c                        |   20 +-
+ arch/mips/kernel/signal_n32.c                      |   10 +-
+ arch/mn10300/Kconfig                               |    1 +
+ arch/mn10300/include/asm/posix_types.h             |  111 +--
+ arch/mn10300/include/asm/reset-regs.h              |    4 -
+ arch/mn10300/kernel/signal.c                       |   32 +-
+ arch/parisc/include/asm/posix_types.h              |  119 +--
+ arch/parisc/kernel/signal.c                        |   12 +-
+ arch/powerpc/Kconfig                               |    1 +
+ arch/powerpc/include/asm/posix_types.h             |  118 +--
+ arch/powerpc/kernel/signal.c                       |   13 +-
+ arch/powerpc/kernel/signal_32.c                    |   11 +-
+ arch/s390/Kconfig                                  |    1 +
+ arch/s390/include/asm/posix_types.h                |   70 +-
+ arch/s390/kernel/compat_signal.c                   |    6 +-
+ arch/s390/kernel/signal.c                          |    6 +-
+ arch/score/kernel/signal.c                         |   13 +-
+ arch/sh/include/asm/posix_types_32.h               |    5 -
+ arch/sh/include/asm/posix_types_64.h               |    4 -
+ arch/sh/kernel/signal_32.c                         |   35 +-
+ arch/sh/kernel/signal_64.c                         |   40 +-
+ arch/sparc/Kconfig                                 |    2 +
+ arch/sparc/include/asm/irq_64.h                    |    1 -
+ arch/sparc/include/asm/posix_types.h               |  133 +--
+ arch/sparc/kernel/signal32.c                       |    7 +-
+ arch/sparc/kernel/signal_32.c                      |    7 +-
+ arch/sparc/kernel/signal_64.c                      |    6 +-
+ arch/tile/include/asm/compat.h                     |   11 -
+ arch/tile/include/asm/smp.h                        |    7 -
+ arch/tile/kernel/compat.c                          |   43 -
+ arch/tile/kernel/compat_signal.c                   |    5 +-
+ arch/tile/kernel/signal.c                          |   13 +-
+ arch/tile/kernel/smp.c                             |   19 -
+ arch/um/kernel/signal.c                            |   26 +-
+ arch/unicore32/kernel/signal.c                     |    5 +-
+ arch/x86/Kconfig                                   |   14 +
+ arch/x86/include/asm/current.h                     |    2 +-
+ arch/x86/include/asm/desc.h                        |    1 +
+ arch/x86/include/asm/hardirq.h                     |    9 +-
+ arch/x86/include/asm/irq_regs.h                    |    4 +-
+ arch/x86/include/asm/mmu_context.h                 |   12 +-
+ arch/x86/include/asm/percpu.h                      |   24 +-
+ arch/x86/include/asm/posix_types_32.h              |   75 +-
+ arch/x86/include/asm/posix_types_64.h              |  106 +--
+ arch/x86/include/asm/smp.h                         |    4 +-
+ arch/x86/include/asm/stackprotector.h              |    4 +-
+ arch/x86/include/asm/thread_info.h                 |    2 +-
+ arch/x86/include/asm/tlbflush.h                    |    4 +-
+ arch/x86/kernel/cpu/common.c                       |    2 +-
+ arch/x86/kernel/cpu/mcheck/mce.c                   |    4 +-
+ arch/x86/kernel/cpu/perf_event.c                   |    4 +-
+ arch/x86/kernel/irqinit.c                          |    6 +-
+ arch/x86/kernel/nmi_selftest.c                     |    1 +
+ arch/x86/kernel/paravirt.c                         |   12 +-
+ arch/x86/kernel/process_32.c                       |    2 +-
+ arch/x86/kernel/process_64.c                       |   12 +-
+ arch/x86/kernel/sys_x86_64.c                       |   34 +-
+ arch/x86/mm/hugetlbpage.c                          |   31 +-
+ arch/x86/mm/init.c                                 |   21 +-
+ arch/x86/mm/tlb.c                                  |   10 +-
+ arch/x86/platform/geode/Makefile                   |    2 +
+ arch/x86/platform/geode/alix.c                     |   76 +-
+ arch/x86/platform/geode/geos.c                     |  128 ++
+ arch/x86/platform/geode/net5501.c                  |  154 +++
+ arch/x86/platform/iris/iris.c                      |   67 +-
+ arch/x86/platform/olpc/olpc-xo15-sci.c             |   67 +
+ arch/x86/platform/olpc/olpc.c                      |   86 ++
+ arch/x86/syscalls/syscall_32.tbl                   |    1 +
+ arch/x86/syscalls/syscall_64.tbl                   |    1 +
+ arch/xtensa/include/asm/posix_types.h              |   97 +--
+ arch/xtensa/kernel/signal.c                        |   35 +-
+ crypto/Kconfig                                     |    1 +
+ crypto/crc32c.c                                    |   94 +--
+ drivers/block/drbd/drbd_nl.c                       |    2 +-
+ drivers/bluetooth/btusb.c                          |    1 +
+ drivers/char/Kconfig                               |    1 +
+ drivers/char/hpet.c                                |   56 +-
+ drivers/char/ipmi/ipmi_kcs_sm.c                    |    4 +-
+ drivers/char/ipmi/ipmi_msghandler.c                |  242 ++--
+ drivers/char/ipmi/ipmi_si_intf.c                   |   72 +-
+ drivers/char/ipmi/ipmi_watchdog.c                  |   21 +-
+ drivers/char/ramoops.c                             |  204 +++-
+ drivers/clocksource/cs5535-clockevt.c              |    3 +-
+ drivers/leds/Kconfig                               |   18 +-
+ drivers/leds/Makefile                              |    2 +-
+ drivers/leds/leds-gpio.c                           |    3 +-
+ drivers/leds/leds-lm3530.c                         |  135 ++-
+ drivers/leds/leds-lp5521.c                         |  145 ++-
+ drivers/leds/leds-lp5523.c                         |    6 +-
+ drivers/leds/leds-net5501.c                        |   97 --
+ drivers/leds/leds-pca9633.c                        |  193 +++
+ drivers/leds/leds-tca6507.c                        |    8 +-
+ drivers/mtd/chips/cfi_cmdset_0001.c                |    6 +-
+ drivers/mtd/mtdchar.c                              |    2 +-
+ drivers/platform/x86/Kconfig                       |   24 +-
+ drivers/platform/x86/Makefile                      |    1 -
+ drivers/platform/x86/acerhdf.c                     |   67 +-
+ drivers/platform/x86/intel_mid_powerbtn.c          |   46 +-
+ drivers/platform/x86/intel_mid_thermal.c           |   60 +-
+ drivers/platform/x86/intel_rar_register.c          |  669 ----------
+ drivers/platform/x86/intel_scu_ipc.c               |  208 +---
+ drivers/platform/x86/intel_scu_ipcutil.c           |   32 +-
+ drivers/platform/x86/sony-laptop.c                 |   16 +-
+ drivers/platform/x86/xo1-rfkill.c                  |   13 +-
+ drivers/rtc/Kconfig                                |   17 +
+ drivers/rtc/Makefile                               |    2 +
+ drivers/rtc/rtc-at91sam9.c                         |    2 +-
+ drivers/rtc/rtc-bq32k.c                            |   12 +-
+ drivers/rtc/rtc-cmos.c                             |    2 +-
+ drivers/rtc/rtc-coh901331.c                        |    2 +-
+ drivers/rtc/rtc-da9052.c                           |  293 +++++
+ drivers/rtc/rtc-davinci.c                          |    2 +-
+ drivers/rtc/rtc-ds1305.c                           |   12 +-
+ drivers/rtc/rtc-ds1307.c                           |   12 +-
+ drivers/rtc/rtc-ds1374.c                           |   13 +-
+ drivers/rtc/rtc-ds1390.c                           |   12 +-
+ drivers/rtc/rtc-ds1511.c                           |    2 +-
+ drivers/rtc/rtc-ds1553.c                           |    2 +-
+ drivers/rtc/rtc-ds1672.c                           |   13 +-
+ drivers/rtc/rtc-ds3232.c                           |   13 +-
+ drivers/rtc/rtc-ds3234.c                           |   12 +-
+ drivers/rtc/rtc-em3027.c                           |   13 +-
+ drivers/rtc/rtc-fm3130.c                           |   12 +-
+ drivers/rtc/rtc-isl12022.c                         |   13 +-
+ drivers/rtc/rtc-isl1208.c                          |   15 +-
+ drivers/rtc/rtc-lpc32xx.c                          |    2 +-
+ drivers/rtc/rtc-ls1x.c                             |  211 ++++
+ drivers/rtc/rtc-m41t80.c                           |   13 +-
+ drivers/rtc/rtc-m41t93.c                           |   12 +-
+ drivers/rtc/rtc-m41t94.c                           |   14 +-
+ drivers/rtc/rtc-max6900.c                          |   13 +-
+ drivers/rtc/rtc-max6902.c                          |   12 +-
+ drivers/rtc/rtc-max8925.c                          |   21 +-
+ drivers/rtc/rtc-mpc5121.c                          |    4 +-
+ drivers/rtc/rtc-mrst.c                             |    2 +-
+ drivers/rtc/rtc-mv.c                               |    2 +-
+ drivers/rtc/rtc-nuc900.c                           |    2 +-
+ drivers/rtc/rtc-omap.c                             |    4 +-
+ drivers/rtc/rtc-pcf2123.c                          |   13 +-
+ drivers/rtc/rtc-pcf8563.c                          |   13 +-
+ drivers/rtc/rtc-pcf8583.c                          |   13 +-
+ drivers/rtc/rtc-pl030.c                            |    2 +-
+ drivers/rtc/rtc-pl031.c                            |    2 +-
+ drivers/rtc/rtc-pm8xxx.c                           |    2 +-
+ drivers/rtc/rtc-pxa.c                              |    4 +-
+ drivers/rtc/rtc-r9701.c                            |   12 +-
+ drivers/rtc/rtc-rs5c348.c                          |   13 +-
+ drivers/rtc/rtc-rs5c372.c                          |   13 +-
+ drivers/rtc/rtc-rv3029c2.c                         |   13 +-
+ drivers/rtc/rtc-rx8025.c                           |   13 +-
+ drivers/rtc/rtc-rx8581.c                           |   13 +-
+ drivers/rtc/rtc-s35390a.c                          |   13 +-
+ drivers/rtc/rtc-s3c.c                              |    4 +-
+ drivers/rtc/rtc-sa1100.c                           |    4 +-
+ drivers/rtc/rtc-sh.c                               |    8 +-
+ drivers/rtc/rtc-spear.c                            |  100 +-
+ drivers/rtc/rtc-stk17ta8.c                         |    2 +-
+ drivers/rtc/rtc-twl.c                              |   28 +-
+ drivers/rtc/rtc-tx4939.c                           |    2 +-
+ drivers/rtc/rtc-vr41xx.c                           |    4 +-
+ drivers/rtc/rtc-x1205.c                            |   13 +-
+ drivers/s390/char/sclp_cmd.c                       |    5 +-
+ drivers/staging/rtl8187se/r8180_core.c             |    2 +-
+ drivers/staging/rtl8192e/rtl8192e/rtl_dm.c         |    4 +-
+ drivers/thermal/thermal_sys.c                      |   90 +-
+ drivers/uwb/allocator.c                            |    6 +-
+ drivers/video/backlight/88pm860x_bl.c              |    8 +-
+ drivers/video/backlight/Kconfig                    |   21 +
+ drivers/video/backlight/Makefile                   |    4 +-
+ drivers/video/backlight/aat2870_bl.c               |    9 +-
+ drivers/video/backlight/adp5520_bl.c               |    6 +-
+ drivers/video/backlight/adp8860_bl.c               |   12 +-
+ drivers/video/backlight/adp8870_bl.c               |   12 +-
+ drivers/video/backlight/ams369fg06.c               |   13 +-
+ drivers/video/backlight/corgi_lcd.c                |   12 +-
+ drivers/video/backlight/cr_bllcd.c                 |    3 +-
+ drivers/video/backlight/da903x_bl.c                |    6 +-
+ drivers/video/backlight/l4f00242t03.c              |   13 +-
+ drivers/video/backlight/ld9040.c                   |   13 +-
+ drivers/video/backlight/lms283gf05.c               |   13 +-
+ drivers/video/backlight/lp855x_bl.c                |  322 +++++
+ drivers/video/backlight/ltv350qv.c                 |   12 +-
+ drivers/video/backlight/max8925_bl.c               |    7 +-
+ drivers/video/backlight/omap1_bl.c                 |    9 +-
+ drivers/video/backlight/ot200_bl.c                 |  175 +++
+ drivers/video/backlight/pandora_bl.c               |  171 +++
+ drivers/video/backlight/pcf50633-backlight.c       |   16 +-
+ drivers/video/backlight/pwm_bl.c                   |    7 +-
+ drivers/video/backlight/s6e63m0.c                  |   13 +-
+ drivers/video/backlight/tdo24m.c                   |   12 +-
+ drivers/video/backlight/tosa_bl.c                  |   13 +-
+ drivers/video/backlight/tosa_lcd.c                 |   13 +-
+ drivers/video/backlight/vgg2432a4.c                |   15 +-
+ drivers/video/backlight/wm831x_bl.c                |    6 +-
+ drivers/video/uvesafb.c                            |    2 +-
+ fs/aio.c                                           |    2 +
+ fs/attr.c                                          |    8 +-
+ fs/binfmt_misc.c                                   |    3 +-
+ fs/block_dev.c                                     |    3 +-
+ fs/btrfs/inode-map.c                               |    4 +-
+ fs/buffer.c                                        |   15 +-
+ fs/cifs/cifsfs.c                                   |    2 +-
+ fs/dcache.c                                        |    4 +-
+ fs/eventpoll.c                                     |   25 +
+ fs/file_table.c                                    |   17 +-
+ fs/hugetlbfs/inode.c                               |   15 +-
+ fs/inode.c                                         |    3 +-
+ fs/internal.h                                      |    3 +-
+ fs/namei.c                                         |   24 +-
+ fs/namespace.c                                     |  140 ++--
+ fs/ocfs2/cluster/heartbeat.c                       |   40 +-
+ fs/pipe.c                                          |    1 +
+ fs/pnode.c                                         |    4 +-
+ fs/proc/array.c                                    |  256 +++-
+ fs/proc/base.c                                     |   58 +-
+ fs/proc/internal.h                                 |    1 +
+ fs/proc/kcore.c                                    |    6 +-
+ fs/proc/namespaces.c                               |    6 +-
+ fs/proc/page.c                                     |    2 +
+ fs/proc/stat.c                                     |   62 +-
+ fs/proc/task_mmu.c                                 |  138 ++-
+ fs/proc_namespace.c                                |    4 +-
+ fs/seq_file.c                                      |  112 ++-
+ include/asm-generic/posix_types.h                  |   86 +--
+ include/linux/bitops.h                             |   13 +-
+ include/linux/cgroup.h                             |    2 +-
+ include/linux/compaction.h                         |   20 +-
+ include/linux/compat.h                             |   12 +-
+ include/linux/compiler-gcc.h                       |    3 +-
+ include/linux/cpumask.h                            |   12 +-
+ include/linux/crc32.h                              |    2 +
+ include/linux/hpet.h                               |    1 +
+ include/linux/huge_mm.h                            |   17 +
+ include/linux/kcmp.h                               |   17 +
+ include/linux/kernel-page-flags.h                  |    1 +
+ include/linux/kernel.h                             |   17 +-
+ include/linux/kmod.h                               |   18 +-
+ include/linux/kmsg_dump.h                          |    9 +-
+ include/linux/led-lm3530.h                         |    9 +
+ include/linux/leds-lp5521.h                        |   25 +
+ include/linux/lglock.h                             |  187 +---
+ include/linux/lp855x.h                             |  133 ++
+ include/linux/magic.h                              |   18 +-
+ include/linux/memcontrol.h                         |   17 +-
+ include/linux/migrate.h                            |    2 -
+ include/linux/mm.h                                 |   21 +-
+ include/linux/mm_types.h                           |    1 +
+ include/linux/mmzone.h                             |    3 +-
+ include/linux/nmi.h                                |    2 +-
+ include/linux/page_cgroup.h                        |    8 +-
+ include/linux/percpu.h                             |   54 -
+ include/linux/pid_namespace.h                      |    8 +-
+ include/linux/pipe_fs_i.h                          |    2 -
+ include/linux/prctl.h                              |    8 +
+ include/linux/ptrace.h                             |   44 +-
+ include/linux/rar_register.h                       |   60 -
+ include/linux/sched.h                              |   12 +
+ include/linux/seq_file.h                           |    5 +-
+ include/linux/slab.h                               |   17 +-
+ include/linux/smp.h                                |   46 +
+ include/linux/swap.h                               |   37 +-
+ include/linux/syscalls.h                           |    2 +
+ include/linux/time.h                               |   23 +
+ include/linux/topology.h                           |    4 +-
+ include/linux/tracehook.h                          |    9 +-
+ include/xen/xenbus.h                               |    4 +-
+ init/do_mounts.c                                   |    3 +
+ ipc/compat.c                                       |   70 +-
+ ipc/sem.c                                          |  250 +++--
+ kernel/Makefile                                    |    5 +-
+ kernel/cgroup.c                                    |   19 +-
+ kernel/cpu.c                                       |   13 +
+ kernel/exit.c                                      |   40 +-
+ kernel/fork.c                                      |   25 +-
+ kernel/hrtimer.c                                   |    8 +
+ kernel/irq/chip.c                                  |    3 +-
+ kernel/irq/manage.c                                |    5 +-
+ kernel/kcmp.c                                      |  187 +++
+ kernel/kmod.c                                      |  115 ++-
+ kernel/kprobes.c                                   |   12 +-
+ kernel/lglock.c                                    |  136 ++
+ kernel/pid_namespace.c                             |   47 +-
+ kernel/printk.c                                    |    6 +
+ kernel/ptrace.c                                    |   66 +-
+ kernel/signal.c                                    |   18 +-
+ kernel/smp.c                                       |   90 ++
+ kernel/softirq.c                                   |   18 +-
+ kernel/sys.c                                       |  130 ++-
+ kernel/sys_ni.c                                    |    3 +
+ kernel/sysctl.c                                    |   19 +-
+ lib/Kconfig                                        |   61 +-
+ lib/Kconfig.debug                                  |    2 +-
+ lib/cpumask.c                                      |   12 -
+ lib/crc32.c                                        | 1287 +++++++++++++++-----
+ lib/crc32defs.h                                    |   56 +-
+ lib/debugobjects.c                                 |   14 +-
+ lib/gen_crc32table.c                               |   81 +-
+ lib/idr.c                                          |    8 +-
+ lib/prio_tree.c                                    |  156 ++--
+ lib/string.c                                       |   20 +-
+ lib/vsprintf.c                                     |   20 +
+ mm/compaction.c                                    |   77 +-
+ mm/huge_memory.c                                   |  122 +-
+ mm/hugetlb.c                                       |   30 +-
+ mm/memcontrol.c                                    |  180 ++--
+ mm/memory.c                                        |   31 +-
+ mm/mmap.c                                          |   40 +-
+ mm/mprotect.c                                      |    2 +-
+ mm/mremap.c                                        |    2 -
+ mm/oom_kill.c                                      |  144 +--
+ mm/page_alloc.c                                    |   83 ++-
+ mm/rmap.c                                          |   10 +-
+ mm/slub.c                                          |   10 +-
+ mm/swap_state.c                                    |   24 +-
+ mm/swapfile.c                                      |   62 -
+ mm/vmscan.c                                        |  106 ++-
+ net/netfilter/nf_conntrack_netlink.c               |    5 +
+ net/netfilter/xt_TEE.c                             |   12 +-
+ net/socket.c                                       |    4 +-
+ scripts/checkpatch.pl                              |    6 +
+ security/keys/request_key.c                        |    2 +-
+ security/tomoyo/load_policy.c                      |    2 +-
+ tools/perf/util/include/linux/bitops.h             |    2 +-
+ tools/testing/selftests/Makefile                   |    7 +-
+ tools/testing/selftests/breakpoints/Makefile       |    7 +-
+ tools/testing/selftests/kcmp/Makefile              |   29 +
+ tools/testing/selftests/kcmp/kcmp_test.c           |   94 ++
+ tools/testing/selftests/run_tests                  |    8 -
+ tools/testing/selftests/vm/Makefile                |   14 +
+ .../testing/selftests}/vm/hugepage-mmap.c          |   13 +-
+ .../testing/selftests}/vm/hugepage-shm.c           |   10 +-
+ .../testing/selftests}/vm/map_hugetlb.c            |   10 +-
+ tools/testing/selftests/vm/run_vmtests             |   77 ++
+ tools/vm/Makefile                                  |   11 +
+ {Documentation => tools}/vm/page-types.c           |    8 +-
+ tools/{slub => vm}/slabinfo.c                      |    0
+ 391 files changed, 8130 insertions(+), 6547 deletions(-)
+ create mode 100644 Documentation/ABI/testing/debugfs-olpc
+ create mode 100644 Documentation/backlight/lp855x-driver.txt
+ create mode 100644 Documentation/crc32.txt
+ delete mode 100644 Documentation/vm/Makefile
+ create mode 100644 arch/x86/platform/geode/geos.c
+ create mode 100644 arch/x86/platform/geode/net5501.c
+ delete mode 100644 drivers/leds/leds-net5501.c
+ create mode 100644 drivers/leds/leds-pca9633.c
+ delete mode 100644 drivers/platform/x86/intel_rar_register.c
+ create mode 100644 drivers/rtc/rtc-da9052.c
+ create mode 100644 drivers/rtc/rtc-ls1x.c
+ create mode 100644 drivers/video/backlight/lp855x_bl.c
+ create mode 100644 drivers/video/backlight/ot200_bl.c
+ create mode 100644 drivers/video/backlight/pandora_bl.c
+ create mode 100644 include/linux/kcmp.h
+ create mode 100644 include/linux/lp855x.h
+ delete mode 100644 include/linux/rar_register.h
+ create mode 100644 kernel/kcmp.c
+ create mode 100644 kernel/lglock.c
+ create mode 100644 tools/testing/selftests/kcmp/Makefile
+ create mode 100644 tools/testing/selftests/kcmp/kcmp_test.c
+ delete mode 100644 tools/testing/selftests/run_tests
+ create mode 100644 tools/testing/selftests/vm/Makefile
+ rename {Documentation => tools/testing/selftests}/vm/hugepage-mmap.c (93%)
+ rename {Documentation => tools/testing/selftests}/vm/hugepage-shm.c (94%)
+ rename {Documentation => tools/testing/selftests}/vm/map_hugetlb.c (94%)
+ create mode 100644 tools/testing/selftests/vm/run_vmtests
+ create mode 100644 tools/vm/Makefile
+ rename {Documentation => tools}/vm/page-types.c (99%)
+ rename tools/{slub => vm}/slabinfo.c (100%)
+$ git revert 9e8ea74b7e79
+[master cd6aeae] Revert "posix_types-remove-fd_set-macros-checkpatch-fixes"
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+$ git revert b08641dbffe3
+[master b8b091e] Revert "posix_types: remove fd_set macros"
+ 2 files changed, 72 insertions(+), 23 deletions(-)
+$ git am -3 ../patches/0001-percpu-fixup-for-added-percpu_xxx-calls-in-i387.h.patch
+Applying: percpu: fixup for added percpu_xxx calls in i387.h
diff --git a/Next/quilt-import.log b/Next/quilt-import.log
new file mode 100644
index 0000000..04e71da
--- /dev/null
+++ b/Next/quilt-import.log
@@ -0,0 +1,12 @@
+Importing hexagon based on v3.2-rc2
+Unchanged quilt series hexagon
+Importing i2c based on ce5afed937f0a823d3b00c9459409c3f5f2fbd5d
+Unchanged quilt series i2c
+Importing jdelvare-hwmon based on 19e00f2f1d5273dbc52eab0ebc315cae3aa44b2a
+Unchanged quilt series jdelvare-hwmon
+Importing kernel-doc based on 3.3-rc2
+Unchanged quilt series kernel-doc
+Importing rr based on v3.3-rc3-273-gc38e234
+Unchanged quilt series rr
+Importing device-mapper based on v3.3-rc3
+Unchanged quilt series device-mapper
diff --git a/arch/Kconfig b/arch/Kconfig
index 4f55c73..5e403de 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -65,6 +65,9 @@ config OPTPROBES
 	depends on KPROBES && HAVE_OPTPROBES
 	depends on !PREEMPT
 
+config UPROBES
+	def_bool n
+
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
 	bool
 	help
@@ -109,6 +112,9 @@ config HAVE_KRETPROBES
 
 config HAVE_OPTPROBES
 	bool
+
+config HAVE_NMI_WATCHDOG
+	bool
 #
 # An arch should select this if it provides all these things:
 #
@@ -199,4 +205,7 @@ config HAVE_CMPXCHG_LOCAL
 config HAVE_CMPXCHG_DOUBLE
 	bool
 
+config ARCH_WANT_OLD_COMPAT_IPC
+	bool
+
 source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h
index 4567aca..dfa32f0 100644
--- a/arch/alpha/include/asm/dma-mapping.h
+++ b/arch/alpha/include/asm/dma-mapping.h
@@ -12,16 +12,22 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 
 #include <asm-generic/dma-mapping-common.h>
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t gfp)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t gfp,
+				    struct dma_attrs *attrs)
 {
-	return get_dma_ops(dev)->alloc_coherent(dev, size, dma_handle, gfp);
+	return get_dma_ops(dev)->alloc(dev, size, dma_handle, gfp, attrs);
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
-	get_dma_ops(dev)->free_coherent(dev, size, vaddr, dma_handle);
+	get_dma_ops(dev)->free(dev, size, vaddr, dma_handle, attrs);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/alpha/include/asm/posix_types.h b/arch/alpha/include/asm/posix_types.h
index db16741..24779fc 100644
--- a/arch/alpha/include/asm/posix_types.h
+++ b/arch/alpha/include/asm/posix_types.h
@@ -8,116 +8,13 @@
  */
 
 typedef unsigned int	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-typedef unsigned int	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef long long	__kernel_loff_t;
-typedef int		__kernel_pid_t;
-typedef int		__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned long	__kernel_sigset_t;	/* at least 32 bits */
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_timer_t;
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-typedef __kernel_uid_t __kernel_old_uid_t;
-typedef __kernel_gid_t __kernel_old_gid_t;
-typedef __kernel_uid_t __kernel_uid32_t;
-typedef __kernel_gid_t __kernel_gid32_t;
-
-typedef unsigned int	__kernel_old_dev_t;
-
-#ifdef __KERNEL__
-
-#ifndef __GNUC__
-
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define	__FD_ISSET(d, set)	(((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
-#define	__FD_ZERO(set)	\
-  ((void) memset ((void *) (set), 0, sizeof (__kernel_fd_set)))
-
-#else /* __GNUC__ */
-
-/* With GNU C, use inline functions instead so args are evaluated only once: */
+#define __kernel_ino_t __kernel_ino_t
 
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, const __kernel_fd_set *p)
-{ 
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned long *tmp = p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		      case 16:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			return;
-
-		      case 8:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			return;
-
-		      case 4:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
+typedef unsigned int	__kernel_nlink_t;
+#define __kernel_nlink_t __kernel_nlink_t
 
-#endif /* __GNUC__ */
+typedef unsigned long	__kernel_sigset_t;	/* at least 32 bits */
 
-#endif /* __KERNEL__ */
+#include <asm-generic/posix_types.h>
 
 #endif /* _ALPHA_POSIX_TYPES_H */
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index 082355f..16449d3 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -71,6 +71,7 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index 04eea48..df24b76 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -108,7 +108,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,
 }
 
 static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t gfp)
+				       dma_addr_t *dma_handle, gfp_t gfp,
+				       struct dma_attrs *attrs)
 {
 	void *ret;
 
@@ -123,7 +124,8 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void alpha_noop_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_addr)
+				     void *cpu_addr, dma_addr_t dma_addr,
+				     struct dma_attrs *attrs)
 {
 	free_pages((unsigned long)cpu_addr, get_order(size));
 }
@@ -174,8 +176,8 @@ static int alpha_noop_set_mask(struct device *dev, u64 mask)
 }
 
 struct dma_map_ops alpha_noop_ops = {
-	.alloc_coherent		= alpha_noop_alloc_coherent,
-	.free_coherent		= alpha_noop_free_coherent,
+	.alloc			= alpha_noop_alloc_coherent,
+	.free			= alpha_noop_free_coherent,
 	.map_page		= alpha_noop_map_page,
 	.map_sg			= alpha_noop_map_sg,
 	.mapping_error		= alpha_noop_mapping_error,
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 4361080..cd63479 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -434,7 +434,8 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr,
    else DMA_ADDRP is undefined.  */
 
 static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
-				      dma_addr_t *dma_addrp, gfp_t gfp)
+				      dma_addr_t *dma_addrp, gfp_t gfp,
+				      struct dma_attrs *attrs)
 {
 	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	void *cpu_addr;
@@ -478,7 +479,8 @@ try_again:
    DMA_ADDR past this call are illegal.  */
 
 static void alpha_pci_free_coherent(struct device *dev, size_t size,
-				    void *cpu_addr, dma_addr_t dma_addr)
+				    void *cpu_addr, dma_addr_t dma_addr,
+				    struct dma_attrs *attrs)
 {
 	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
 	pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
@@ -952,8 +954,8 @@ static int alpha_pci_set_mask(struct device *dev, u64 mask)
 }
 
 struct dma_map_ops alpha_pci_ops = {
-	.alloc_coherent		= alpha_pci_alloc_coherent,
-	.free_coherent		= alpha_pci_free_coherent,
+	.alloc			= alpha_pci_alloc_coherent,
+	.free			= alpha_pci_free_coherent,
 	.map_page		= alpha_pci_map_page,
 	.unmap_page		= alpha_pci_unmap_page,
 	.map_sg			= alpha_pci_map_sg,
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 6f7feb5..35f2ef4 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -120,12 +120,13 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
  */
 SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -238,10 +239,7 @@ do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs,
 		goto give_sigsegv;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(sc, regs, sw))
 		goto give_sigsegv;
@@ -276,10 +274,7 @@ do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs,
 		goto give_sigsegv;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
 		goto give_sigsegv;
@@ -501,14 +496,8 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	else
 		ret = setup_frame(sig, ka, oldset, regs, sw);
 
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER)) 
-			sigaddset(&current->blocked,sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a48aecc..e3ccbc3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -21,6 +21,7 @@ config ARM
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_LZMA
+	select HAVE_KERNEL_XZ
 	select HAVE_IRQ_WORK
 	select HAVE_PERF_EVENTS
 	select PERF_USE_VMALLOC
@@ -28,7 +29,6 @@ config ARM
 	select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
 	select HAVE_C_RECORDMCOUNT
 	select HAVE_GENERIC_HARDIRQS
-	select HAVE_SPARSE_IRQ
 	select GENERIC_IRQ_SHOW
 	select CPU_PM if (SUSPEND || CPU_IDLE)
 	select GENERIC_PCI_IOMAP
@@ -52,9 +52,6 @@ config MIGHT_HAVE_PCI
 config SYS_SUPPORTS_APM_EMULATION
 	bool
 
-config HAVE_SCHED_CLOCK
-	bool
-
 config GENERIC_GPIO
 	bool
 
@@ -312,6 +309,7 @@ config ARCH_VEXPRESS
 	select HAVE_CLK
 	select HAVE_PATA_PLATFORM
 	select ICST
+	select NO_IOPORT
 	select PLAT_VERSATILE
 	select PLAT_VERSATILE_CLCD
 	help
@@ -324,7 +322,7 @@ config ARCH_AT91
 	select CLKDEV_LOOKUP
 	help
 	  This enables support for systems based on the Atmel AT91RM9200,
-	  AT91SAM9 and AT91CAP9 processors.
+	  AT91SAM9 processors.
 
 config ARCH_BCMRING
 	bool "Broadcom BCMRING"
@@ -350,6 +348,7 @@ config ARCH_HIGHBANK
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU
 	select HAVE_SMP
+	select SPARSE_IRQ
 	select USE_OF
 	help
 	  Support for the Calxeda Highbank SoC based boards.
@@ -438,7 +437,6 @@ config ARCH_MXC
 	select CLKDEV_LOOKUP
 	select CLKSRC_MMIO
 	select GENERIC_IRQ_CHIP
-	select HAVE_SCHED_CLOCK
 	select MULTI_IRQ_HANDLER
 	help
 	  Support for Freescale MXC/iMX-based family of processors
@@ -530,7 +528,6 @@ config ARCH_IXP4XX
 	select CPU_XSCALE
 	select GENERIC_GPIO
 	select GENERIC_CLOCKEVENTS
-	select HAVE_SCHED_CLOCK
 	select MIGHT_HAVE_PCI
 	select DMABOUNCE if PCI
 	help
@@ -601,7 +598,6 @@ config ARCH_MMP
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select GPIO_PXA
-	select HAVE_SCHED_CLOCK
 	select TICK_ONESHOT
 	select PLAT_PXA
 	select SPARSE_IRQ
@@ -642,7 +638,6 @@ config ARCH_TEGRA
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
 	select HAVE_CLK
-	select HAVE_SCHED_CLOCK
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	select ARCH_HAS_CPUFREQ
@@ -659,7 +654,6 @@ config ARCH_PICOXCELL
 	select DW_APB_TIMER
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
-	select HAVE_SCHED_CLOCK
 	select HAVE_TCM
 	select NO_IOPORT
 	select SPARSE_IRQ
@@ -687,7 +681,6 @@ config ARCH_PXA
 	select ARCH_REQUIRE_GPIOLIB
 	select GENERIC_CLOCKEVENTS
 	select GPIO_PXA
-	select HAVE_SCHED_CLOCK
 	select TICK_ONESHOT
 	select PLAT_PXA
 	select SPARSE_IRQ
@@ -755,11 +748,11 @@ config ARCH_SA1100
 	select CPU_FREQ
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
-	select HAVE_SCHED_CLOCK
 	select TICK_ONESHOT
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_IDE
 	select NEED_MACH_MEMORY_H
+	select SPARSE_IRQ
 	help
 	  Support for StrongARM 11x0 based boards.
 
@@ -812,7 +805,6 @@ config ARCH_S5P64X0
 	select CLKSRC_MMIO
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
 	select GENERIC_CLOCKEVENTS
-	select HAVE_SCHED_CLOCK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	help
@@ -843,7 +835,6 @@ config ARCH_S5PV210
 	select CLKSRC_MMIO
 	select ARCH_HAS_CPUFREQ
 	select GENERIC_CLOCKEVENTS
-	select HAVE_SCHED_CLOCK
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -886,7 +877,6 @@ config ARCH_U300
 	depends on MMU
 	select CLKSRC_MMIO
 	select CPU_ARM926T
-	select HAVE_SCHED_CLOCK
 	select HAVE_TCM
 	select ARM_AMBA
 	select ARM_PATCH_PHYS_VIRT
@@ -944,7 +934,6 @@ config ARCH_OMAP
 	select ARCH_HAS_CPUFREQ
 	select CLKSRC_MMIO
 	select GENERIC_CLOCKEVENTS
-	select HAVE_SCHED_CLOCK
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  Support for TI's OMAP platform (OMAP1/2/3/4).
@@ -1110,13 +1099,11 @@ config ARCH_ACORN
 config PLAT_IOP
 	bool
 	select GENERIC_CLOCKEVENTS
-	select HAVE_SCHED_CLOCK
 
 config PLAT_ORION
 	bool
 	select CLKSRC_MMIO
 	select GENERIC_IRQ_CHIP
-	select HAVE_SCHED_CLOCK
 
 config PLAT_PXA
 	bool
@@ -1127,6 +1114,7 @@ config PLAT_VERSATILE
 config ARM_TIMER_SP804
 	bool
 	select CLKSRC_MMIO
+	select HAVE_SCHED_CLOCK
 
 source arch/arm/mm/Kconfig
 
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index e0d236d..b895a2a 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -81,47 +81,14 @@ choice
 	prompt "Kernel low-level debugging port"
 	depends on DEBUG_LL
 
-	config DEBUG_LL_UART_NONE
-		bool "No low-level debugging UART"
-		help
-		  Say Y here if your platform doesn't provide a UART option
-		  below. This relies on your platform choosing the right UART
-		  definition internally in order for low-level debugging to
-		  work.
-
-	config DEBUG_ICEDCC
-		bool "Kernel low-level debugging via EmbeddedICE DCC channel"
-		help
-		  Say Y here if you want the debug print routines to direct
-		  their output to the EmbeddedICE macrocell's DCC channel using
-		  co-processor 14. This is known to work on the ARM9 style ICE
-		  channel and on the XScale with the PEEDI.
-
-		  Note that the system will appear to hang during boot if there
-		  is nothing connected to read from the DCC.
-
 	config AT91_DEBUG_LL_DBGU0
 		bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
 		depends on HAVE_AT91_DBGU0
 
 	config AT91_DEBUG_LL_DBGU1
-		bool "Kernel low-level debugging on 9263, 9g45 and cap9"
+		bool "Kernel low-level debugging on 9263 and 9g45"
 		depends on HAVE_AT91_DBGU1
 
-	config DEBUG_FOOTBRIDGE_COM1
-		bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
-		depends on FOOTBRIDGE
-		help
-		  Say Y here if you want the debug print routines to direct
-		  their output to the 8250 at PCI COM1.
-
-	config DEBUG_DC21285_PORT
-		bool "Kernel low-level debugging messages via footbridge serial port"
-		depends on FOOTBRIDGE
-		help
-		  Say Y here if you want the debug print routines to direct
-		  their output to the serial port in the DC21285 (Footbridge).
-
 	config DEBUG_CLPS711X_UART1
 		bool "Kernel low-level debugging messages via UART1"
 		depends on ARCH_CLPS711X
@@ -136,6 +103,20 @@ choice
 		  Say Y here if you want the debug print routines to direct
 		  their output to the second serial port on these devices.
 
+	config DEBUG_DC21285_PORT
+		bool "Kernel low-level debugging messages via footbridge serial port"
+		depends on FOOTBRIDGE
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the serial port in the DC21285 (Footbridge).
+
+	config DEBUG_FOOTBRIDGE_COM1
+		bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
+		depends on FOOTBRIDGE
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the 8250 at PCI COM1.
+
 	config DEBUG_HIGHBANK_UART
 		bool "Kernel low-level debugging messages via Highbank UART"
 		depends on ARCH_HIGHBANK
@@ -206,38 +187,42 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX6Q.
 
-	config DEBUG_S3C_UART0
-		depends on PLAT_SAMSUNG
-		bool "Use S3C UART 0 for low-level debug"
+	config DEBUG_MSM_UART1
+		bool "Kernel low-level debugging messages via MSM UART1"
+		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to UART 0. The port must have been initialised
-		  by the boot-loader before use.
-
-		  The uncompressor code port configuration is now handled
-		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+		  their output to the first serial port on MSM devices.
 
-	config DEBUG_S3C_UART1
-		depends on PLAT_SAMSUNG
-		bool "Use S3C UART 1 for low-level debug"
+	config DEBUG_MSM_UART2
+		bool "Kernel low-level debugging messages via MSM UART2"
+		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to UART 1. The port must have been initialised
-		  by the boot-loader before use.
+		  their output to the second serial port on MSM devices.
 
-		  The uncompressor code port configuration is now handled
-		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+	config DEBUG_MSM_UART3
+		bool "Kernel low-level debugging messages via MSM UART3"
+		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the third serial port on MSM devices.
 
-	config DEBUG_S3C_UART2
-		depends on PLAT_SAMSUNG
-		bool "Use S3C UART 2 for low-level debug"
+	config DEBUG_MSM8660_UART
+		bool "Kernel low-level debugging messages via MSM 8660 UART"
+		depends on ARCH_MSM8X60
+		select MSM_HAS_DEBUG_UART_HS
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to UART 2. The port must have been initialised
-		  by the boot-loader before use.
+		  their output to the serial port on MSM 8660 devices.
 
-		  The uncompressor code port configuration is now handled
-		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+	config DEBUG_MSM8960_UART
+		bool "Kernel low-level debugging messages via MSM 8960 UART"
+		depends on ARCH_MSM8960
+		select MSM_HAS_DEBUG_UART_HS
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the serial port on MSM 8960 devices.
 
 	config DEBUG_REALVIEW_STD_PORT
 		bool "RealView Default UART"
@@ -255,42 +240,57 @@ choice
 		  their output to the standard serial port on the RealView
 		  PB1176 platform.
 
-	config DEBUG_MSM_UART1
-		bool "Kernel low-level debugging messages via MSM UART1"
-		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+	config DEBUG_S3C_UART0
+		depends on PLAT_SAMSUNG
+		bool "Use S3C UART 0 for low-level debug"
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to the first serial port on MSM devices.
+		  their output to UART 0. The port must have been initialised
+		  by the boot-loader before use.
 
-	config DEBUG_MSM_UART2
-		bool "Kernel low-level debugging messages via MSM UART2"
-		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		  The uncompressor code port configuration is now handled
+		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+	config DEBUG_S3C_UART1
+		depends on PLAT_SAMSUNG
+		bool "Use S3C UART 1 for low-level debug"
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to the second serial port on MSM devices.
+		  their output to UART 1. The port must have been initialised
+		  by the boot-loader before use.
 
-	config DEBUG_MSM_UART3
-		bool "Kernel low-level debugging messages via MSM UART3"
-		depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+		  The uncompressor code port configuration is now handled
+		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+	config DEBUG_S3C_UART2
+		depends on PLAT_SAMSUNG
+		bool "Use S3C UART 2 for low-level debug"
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to the third serial port on MSM devices.
+		  their output to UART 2. The port must have been initialised
+		  by the boot-loader before use.
 
-	config DEBUG_MSM8660_UART
-		bool "Kernel low-level debugging messages via MSM 8660 UART"
-		depends on ARCH_MSM8X60
-		select MSM_HAS_DEBUG_UART_HS
+		  The uncompressor code port configuration is now handled
+		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+	config DEBUG_LL_UART_NONE
+		bool "No low-level debugging UART"
 		help
-		  Say Y here if you want the debug print routines to direct
-		  their output to the serial port on MSM 8660 devices.
+		  Say Y here if your platform doesn't provide a UART option
+		  below. This relies on your platform choosing the right UART
+		  definition internally in order for low-level debugging to
+		  work.
 
-	config DEBUG_MSM8960_UART
-		bool "Kernel low-level debugging messages via MSM 8960 UART"
-		depends on ARCH_MSM8960
-		select MSM_HAS_DEBUG_UART_HS
+	config DEBUG_ICEDCC
+		bool "Kernel low-level debugging via EmbeddedICE DCC channel"
 		help
 		  Say Y here if you want the debug print routines to direct
-		  their output to the serial port on MSM 8960 devices.
+		  their output to the EmbeddedICE macrocell's DCC channel using
+		  co-processor 14. This is known to work on the ARM9 style ICE
+		  channel and on the XScale with the PEEDI.
+
+		  Note that the system will appear to hang during boot if there
+		  is nothing connected to read from the DCC.
 
 endchoice
 
diff --git a/arch/arm/arm-soc-for-next-contents.txt b/arch/arm/arm-soc-for-next-contents.txt
new file mode 100644
index 0000000..74e4acb
--- /dev/null
+++ b/arch/arm/arm-soc-for-next-contents.txt
@@ -0,0 +1,33 @@
+This file lists all branches that are pulled into the for-next branch
+of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git
+and their external dependencies.
+
+It also includes a couple of directly applied patches for build breaks with subject
+The next/* branches are kept in the order in which they get applied.
+
+next/fixes-non-critical:
+lpc32xx/fixup		applied from series: http://marc.info/?l=linux-arm-kernel&m=132873369523839
+			+ http://marc.info/?l=linux-arm-kernel&m=132940396030585
+
+next/cleanup:
+at91/base		git://github.com/at91linux/linux-at91.git at91-3.4-base
+at91/pm_cleanup		git://github.com/at91linux/linux-at91.git at91-3.4-base+pm_cleanup
+
+next/soc:
+ux500/timers		git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git ux500-timers
+mxs/clk			git://git.linaro.org/people/shawnguo/linux-2.6.git mxs/clk
+mxs/soc			git://git.linaro.org/people/shawnguo/linux-2.6.git mxs/defconfig
+at91/9x5		git://github.com/at91linux/linux-at91.git at91-3.4-base+9x5
+highbank/devel		git://sources.calxeda.com/kernel/linux.git for-arm-soc
+
+next/drivers:
+at91/device-board	git://github.com/at91linux/linux-at91.git at91-3.4-base+device_board
+imx/clk-prepare		git://git.pengutronix.de/git/imx/linux-2.6.git features/imx-clk-prepare
+samsung/rtc		git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git v3.4-next/devel-samsung-rtc
+
+next/boards:
+mxs/boards		git://git.linaro.org/people/shawnguo/linux-2.6.git mxs/boards
+
+next/soc2:
+depends/driver-core	git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core.git driver-core-next
+ux500/soc		patches from Lee Jones, depends on depends/driver-core
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
index ce1c5ff..3c79f85 100644
--- a/arch/arm/boot/.gitignore
+++ b/arch/arm/boot/.gitignore
@@ -3,3 +3,4 @@ zImage
 xipImage
 bootpImage
 uImage
+*.dtb
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index e0936a1..d0d441c 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -1,8 +1,10 @@
+ashldi3.S
 font.c
 lib1funcs.S
 piggy.gzip
 piggy.lzo
 piggy.lzma
+piggy.xzkern
 vmlinux
 vmlinux.lds
 
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index cf0a64c..bb26756 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -92,6 +92,7 @@ SEDFLAGS	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
 suffix_$(CONFIG_KERNEL_GZIP) = gzip
 suffix_$(CONFIG_KERNEL_LZO)  = lzo
 suffix_$(CONFIG_KERNEL_LZMA) = lzma
+suffix_$(CONFIG_KERNEL_XZ)   = xzkern
 
 # Borrowed libfdt files for the ATAG compatibility mode
 
@@ -112,10 +113,12 @@ endif
 
 targets       := vmlinux vmlinux.lds \
 		 piggy.$(suffix_y) piggy.$(suffix_y).o \
-		 lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)
+		 lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \
+		 font.o font.c head.o misc.o $(OBJS)
 
 # Make sure files are removed during clean
-extra-y       += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)
+extra-y       += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \
+		 lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs)
 
 ifeq ($(CONFIG_FUNCTION_TRACER),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
@@ -151,6 +154,12 @@ lib1funcs = $(obj)/lib1funcs.o
 $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
 	$(call cmd,shipped)
 
+# For __aeabi_llsl
+ashldi3 = $(obj)/ashldi3.o
+
+$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
+	$(call cmd,shipped)
+
 # We need to prevent any GOTOFF relocs being used with references
 # to symbols in the .bss section since we cannot relocate them
 # independently from the rest at run time.  This can be achieved by
@@ -172,7 +181,7 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
 fi
 
 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
-	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
+		$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE
 	@$(check_for_multiple_zreladdr)
 	$(call if_changed,ld)
 	@$(check_for_bad_syms)
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
index 07be5a2..f41b38c 100644
--- a/arch/arm/boot/compressed/decompress.c
+++ b/arch/arm/boot/compressed/decompress.c
@@ -44,6 +44,12 @@ extern void error(char *);
 #include "../../../../lib/decompress_unlzma.c"
 #endif
 
+#ifdef CONFIG_KERNEL_XZ
+#define memmove memmove
+#define memcpy memcpy
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
 int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
 {
 	return decompress(input, len, NULL, NULL, output, NULL, error);
diff --git a/arch/arm/boot/compressed/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S
new file mode 100644
index 0000000..5703f30
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.xzkern.S
@@ -0,0 +1,6 @@
+	.section .piggydata,#alloc
+	.globl	input_data
+input_data:
+	.incbin	"arch/arm/boot/compressed/piggy.xzkern"
+	.globl	input_data_end
+input_data_end:
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
new file mode 100644
index 0000000..e64eb93
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -0,0 +1,37 @@
+/*
+ * at91sam9g25ek.dts - Device Tree file for AT91SAM9G25-EK board
+ *
+ *  Copyright (C) 2012 Atmel,
+ *                2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9x5.dtsi"
+/include/ "at91sam9x5cm.dtsi"
+
+/ {
+	model = "Atmel AT91SAM9G25-EK";
+	compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+
+	chosen {
+		bootargs = "128M console=ttyS0,115200 mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs) root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs";
+	};
+
+	ahb {
+		apb {
+			dbgu: serial@fffff200 {
+				status = "okay";
+			};
+
+			usart0: serial@f801c000 {
+				status = "okay";
+			};
+
+			macb0: ethernet@f802c000 {
+				phy-mode = "rmii";
+				status = "okay";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
new file mode 100644
index 0000000..e91391f
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -0,0 +1,172 @@
+/*
+ * at91sam9x5.dtsi - Device Tree Include file for AT91SAM9x5 family SoC
+ *                   applies to AT91SAM9G15, AT91SAM9G25, AT91SAM9G35,
+ *                   AT91SAM9X25, AT91SAM9X35 SoC
+ *
+ *  Copyright (C) 2012 Atmel,
+ *                2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	model = "Atmel AT91SAM9x5 family SoC";
+	compatible = "atmel,at91sam9x5";
+	interrupt-parent = <&aic>;
+
+	aliases {
+		serial0 = &dbgu;
+		serial1 = &usart0;
+		serial2 = &usart1;
+		serial3 = &usart2;
+		gpio0 = &pioA;
+		gpio1 = &pioB;
+		gpio2 = &pioC;
+		gpio3 = &pioD;
+		tcb0 = &tcb0;
+		tcb1 = &tcb1;
+	};
+	cpus {
+		cpu@0 {
+			compatible = "arm,arm926ejs";
+		};
+	};
+
+	memory@20000000 {
+		reg = <0x20000000 0x10000000>;
+	};
+
+	ahb {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		apb {
+			compatible = "simple-bus";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			aic: interrupt-controller@fffff000 {
+				#interrupt-cells = <2>;
+				compatible = "atmel,at91rm9200-aic";
+				interrupt-controller;
+				interrupt-parent;
+				reg = <0xfffff000 0x200>;
+			};
+
+			pit: timer@fffffe30 {
+				compatible = "atmel,at91sam9260-pit";
+				reg = <0xfffffe30 0xf>;
+				interrupts = <1 4>;
+			};
+
+			tcb0: timer@f8008000 {
+				compatible = "atmel,at91sam9x5-tcb";
+				reg = <0xf8008000 0x100>;
+				interrupts = <17 4>;
+			};
+
+			tcb1: timer@f800c000 {
+				compatible = "atmel,at91sam9x5-tcb";
+				reg = <0xf800c000 0x100>;
+				interrupts = <17 4>;
+			};
+
+			dma0: dma-controller@ffffec00 {
+				compatible = "atmel,at91sam9g45-dma";
+				reg = <0xffffec00 0x200>;
+				interrupts = <20 4>;
+			};
+
+			dma1: dma-controller@ffffee00 {
+				compatible = "atmel,at91sam9g45-dma";
+				reg = <0xffffee00 0x200>;
+				interrupts = <21 4>;
+			};
+
+			pioA: gpio@fffff400 {
+				compatible = "atmel,at91rm9200-gpio";
+				reg = <0xfffff400 0x100>;
+				interrupts = <2 4>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+
+			pioB: gpio@fffff600 {
+				compatible = "atmel,at91rm9200-gpio";
+				reg = <0xfffff600 0x100>;
+				interrupts = <2 4>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+
+			pioC: gpio@fffff800 {
+				compatible = "atmel,at91rm9200-gpio";
+				reg = <0xfffff800 0x100>;
+				interrupts = <3 4>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+
+			pioD: gpio@fffffa00 {
+				compatible = "atmel,at91rm9200-gpio";
+				reg = <0xfffffa00 0x100>;
+				interrupts = <3 4>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+
+			dbgu: serial@fffff200 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0xfffff200 0x200>;
+				interrupts = <1 4>;
+				status = "disabled";
+			};
+
+			usart0: serial@f801c000 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0xf801c000 0x200>;
+				interrupts = <5 4>;
+				atmel,use-dma-rx;
+				atmel,use-dma-tx;
+				status = "disabled";
+			};
+
+			usart1: serial@f8020000 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0xf8020000 0x200>;
+				interrupts = <6 4>;
+				atmel,use-dma-rx;
+				atmel,use-dma-tx;
+				status = "disabled";
+			};
+
+			usart2: serial@f8024000 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0xf8024000 0x200>;
+				interrupts = <7 4>;
+				atmel,use-dma-rx;
+				atmel,use-dma-tx;
+				status = "disabled";
+			};
+
+			macb0: ethernet@f802c000 {
+				compatible = "cdns,at32ap7000-macb", "cdns,macb";
+				reg = <0xf802c000 0x100>;
+				interrupts = <24 4>;
+				status = "disabled";
+			};
+
+			macb1: ethernet@f8030000 {
+				compatible = "cdns,at32ap7000-macb", "cdns,macb";
+				reg = <0xf8030000 0x100>;
+				interrupts = <27 4>;
+				status = "disabled";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/at91sam9x5cm.dtsi b/arch/arm/boot/dts/at91sam9x5cm.dtsi
new file mode 100644
index 0000000..4ab5a77
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9x5cm.dtsi
@@ -0,0 +1,14 @@
+/*
+ * at91sam9x5cm.dtsi - Device Tree Include file for AT91SAM9x5 CPU Module
+ *
+ *  Copyright (C) 2012 Atmel,
+ *                2012 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/ {
+	memory@20000000 {
+		reg = <0x20000000 0x8000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index 80afa1b..6e8447d 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -10,19 +10,25 @@
 		reg = < 0x00000000 0x40000000 >;
 	};
 
+	pmc@7000f400 {
+		nvidia,invert-interrupt;
+	};
+
 	i2c@7000c000 {
 		clock-frequency = <400000>;
 
-		codec: wm8903@1a {
+		wm8903: wm8903@1a {
 			compatible = "wlf,wm8903";
 			reg = <0x1a>;
-			interrupts = < 347 >;
+			interrupt-parent = <&gpio>;
+			interrupts = < 187 0x04 >;
 
 			gpio-controller;
 			#gpio-cells = <2>;
 
-			/* 0x8000 = Not configured */
-			gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;
+			micdet-cfg = <0>;
+			micdet-delay = <100>;
+			gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
 		};
 	};
 
@@ -38,13 +44,32 @@
 		clock-frequency = <400000>;
 	};
 
-	sound {
-		compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903";
+	i2s@70002a00 {
+		status = "disable";
+	};
 
-		spkr-en-gpios = <&codec 2 0>;
-		hp-det-gpios = <&gpio 178 0>;
-		int-mic-en-gpios = <&gpio 184 0>;
-		ext-mic-en-gpios = <&gpio 185 0>;
+	sound {
+		compatible = "nvidia,tegra-audio-wm8903-harmony",
+			     "nvidia,tegra-audio-wm8903";
+		nvidia,model = "NVIDIA Tegra Harmony";
+
+		nvidia,audio-routing =
+			"Headphone Jack", "HPOUTR",
+			"Headphone Jack", "HPOUTL",
+			"Int Spk", "ROP",
+			"Int Spk", "RON",
+			"Int Spk", "LOP",
+			"Int Spk", "LON",
+			"Mic Jack", "MICBIAS",
+			"IN1L", "Mic Jack";
+
+		nvidia,i2s-controller = <&tegra_i2s1>;
+		nvidia,audio-codec = <&wm8903>;
+
+		nvidia,spkr-en-gpios = <&wm8903 2 0>;
+		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+		nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
 	};
 
 	serial@70006000 {
diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts
index 825d295..fc97254 100644
--- a/arch/arm/boot/dts/tegra-paz00.dts
+++ b/arch/arm/boot/dts/tegra-paz00.dts
@@ -12,6 +12,13 @@
 
 	i2c@7000c000 {
 		clock-frequency = <400000>;
+
+		alc5632: alc5632@1e {
+			compatible = "realtek,alc5632";
+			reg = <0x1e>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
 	};
 
 	i2c@7000c400 {
@@ -35,6 +42,34 @@
 
 	i2c@7000d000 {
 		clock-frequency = <400000>;
+
+		adt7461@4c {
+			compatible = "adi,adt7461";
+			reg = <0x4c>;
+		};
+	};
+
+	i2s@70002a00 {
+		status = "disable";
+	};
+
+	sound {
+		compatible = "nvidia,tegra-audio-alc5632-paz00",
+			"nvidia,tegra-audio-alc5632";
+
+		nvidia,model = "Compal PAZ00";
+
+		nvidia,audio-routing =
+			"Int Spk", "SPKOUT",
+			"Int Spk", "SPKOUTN",
+			"Headset Mic", "MICBIAS1",
+			"MIC1", "Headset Mic",
+			"Headset Stereophone", "HPR",
+			"Headset Stereophone", "HPL";
+
+		nvidia,audio-codec = <&alc5632>;
+		nvidia,i2s-controller = <&tegra_i2s1>;
+		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
 	};
 
 	serial@70006000 {
@@ -74,4 +109,25 @@
 	sdhci@c8000600 {
 		support-8bit;
 	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		power {
+			label = "Power";
+			gpios = <&gpio 79 1>; /* gpio PJ7, active low */
+			linux,code = <116>; /* KEY_POWER */
+			gpio-key,wakeup;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		wifi {
+			label = "wifi-led";
+			gpios = <&gpio 24 0>;
+			linux,default-trigger = "rfkill0";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
index b55a02e..876d5c9 100644
--- a/arch/arm/boot/dts/tegra-seaboard.dts
+++ b/arch/arm/boot/dts/tegra-seaboard.dts
@@ -13,6 +13,20 @@
 
 	i2c@7000c000 {
 		clock-frequency = <400000>;
+
+		wm8903: wm8903@1a {
+			compatible = "wlf,wm8903";
+			reg = <0x1a>;
+			interrupt-parent = <&gpio>;
+			interrupts = < 187 0x04 >;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			micdet-cfg = <0>;
+			micdet-delay = <100>;
+			gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+		};
 	};
 
 	i2c@7000c400 {
@@ -32,6 +46,32 @@
 		};
 	};
 
+	i2s@70002a00 {
+		status = "disable";
+	};
+
+	sound {
+		compatible = "nvidia,tegra-audio-wm8903-seaboard",
+			     "nvidia,tegra-audio-wm8903";
+		nvidia,model = "NVIDIA Tegra Seaboard";
+
+		nvidia,audio-routing =
+			"Headphone Jack", "HPOUTR",
+			"Headphone Jack", "HPOUTL",
+			"Int Spk", "ROP",
+			"Int Spk", "RON",
+			"Int Spk", "LOP",
+			"Int Spk", "LON",
+			"Mic Jack", "MICBIAS",
+			"IN1R", "Mic Jack";
+
+		nvidia,i2s-controller = <&tegra_i2s1>;
+		nvidia,audio-codec = <&wm8903>;
+
+		nvidia,spkr-en-gpios = <&wm8903 2 0>;
+		nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
+	};
+
 	serial@70006000 {
 		status = "disable";
 	};
@@ -93,4 +133,42 @@
 			gpio-key,wakeup;
 		};
 	};
+
+	emc@7000f400 {
+		emc-table@190000 {
+			reg = < 190000 >;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 190000 >;
+			nvidia,emc-registers = < 0x0000000c 0x00000026
+				0x00000009 0x00000003 0x00000004 0x00000004
+				0x00000002 0x0000000c 0x00000003 0x00000003
+				0x00000002 0x00000001 0x00000004 0x00000005
+				0x00000004 0x00000009 0x0000000d 0x0000059f
+				0x00000000 0x00000003 0x00000003 0x00000003
+				0x00000003 0x00000001 0x0000000b 0x000000c8
+				0x00000003 0x00000007 0x00000004 0x0000000f
+				0x00000002 0x00000000 0x00000000 0x00000002
+				0x00000000 0x00000000 0x00000083 0xa06204ae
+				0x007dc010 0x00000000 0x00000000 0x00000000
+				0x00000000 0x00000000 0x00000000 0x00000000 >;
+		};
+
+		emc-table@380000 {
+			reg = < 380000 >;
+			compatible = "nvidia,tegra20-emc-table";
+			clock-frequency = < 380000 >;
+			nvidia,emc-registers = < 0x00000017 0x0000004b
+				0x00000012 0x00000006 0x00000004 0x00000005
+				0x00000003 0x0000000c 0x00000006 0x00000006
+				0x00000003 0x00000001 0x00000004 0x00000005
+				0x00000004 0x00000009 0x0000000d 0x00000b5f
+				0x00000000 0x00000003 0x00000003 0x00000006
+				0x00000006 0x00000001 0x00000011 0x000000c8
+				0x00000003 0x0000000e 0x00000007 0x0000000f
+				0x00000002 0x00000000 0x00000000 0x00000002
+				0x00000000 0x00000000 0x00000083 0xe044048b
+				0x007d8010 0x00000000 0x00000000 0x00000000
+				0x00000000 0x00000000 0x00000000 0x00000000 >;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
index 3b3ee7d..2524768 100644
--- a/arch/arm/boot/dts/tegra-trimslice.dts
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -26,6 +26,18 @@
 		status = "disable";
 	};
 
+	i2s@70002800 {
+		status = "disable";
+	};
+
+	i2s@70002a00 {
+		status = "disable";
+	};
+
+	das@70000c00 {
+		status = "disable";
+	};
+
 	serial@70006000 {
 		clock-frequency = < 216000000 >;
 	};
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
index c7d3b87..2dcff87 100644
--- a/arch/arm/boot/dts/tegra-ventana.dts
+++ b/arch/arm/boot/dts/tegra-ventana.dts
@@ -12,6 +12,20 @@
 
 	i2c@7000c000 {
 		clock-frequency = <400000>;
+
+		wm8903: wm8903@1a {
+			compatible = "wlf,wm8903";
+			reg = <0x1a>;
+			interrupt-parent = <&gpio>;
+			interrupts = < 187 0x04 >;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			micdet-cfg = <0>;
+			micdet-delay = <100>;
+			gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+		};
 	};
 
 	i2c@7000c400 {
@@ -26,6 +40,34 @@
 		clock-frequency = <400000>;
 	};
 
+	i2s@70002a00 {
+		status = "disable";
+	};
+
+	sound {
+		compatible = "nvidia,tegra-audio-wm8903-ventana",
+			     "nvidia,tegra-audio-wm8903";
+		nvidia,model = "NVIDIA Tegra Ventana";
+
+		nvidia,audio-routing =
+			"Headphone Jack", "HPOUTR",
+			"Headphone Jack", "HPOUTL",
+			"Int Spk", "ROP",
+			"Int Spk", "RON",
+			"Int Spk", "LOP",
+			"Int Spk", "LON",
+			"Mic Jack", "MICBIAS",
+			"IN1L", "Mic Jack";
+
+		nvidia,i2s-controller = <&tegra_i2s1>;
+		nvidia,audio-codec = <&wm8903>;
+
+		nvidia,spkr-en-gpios = <&wm8903 2 0>;
+		nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+		nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+		nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+	};
+
 	serial@70006000 {
 		status = "disable";
 	};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 3da7afd..ec1f010 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -4,6 +4,11 @@
 	compatible = "nvidia,tegra20";
 	interrupt-parent = <&intc>;
 
+	pmc@7000f400 {
+		compatible = "nvidia,tegra20-pmc";
+		reg = <0x7000e400 0x400>;
+	};
+
 	intc: interrupt-controller@50041000 {
 		compatible = "arm,cortex-a9-gic";
 		interrupt-controller;
@@ -12,6 +17,27 @@
 		      < 0x50040100 0x0100 >;
 	};
 
+	apbdma: dma@6000a000 {
+		compatible = "nvidia,tegra20-apbdma";
+		reg = <0x6000a000 0x1200>;
+		interrupts = < 0 104 0x04
+			       0 105 0x04
+			       0 106 0x04
+			       0 107 0x04
+			       0 108 0x04
+			       0 109 0x04
+			       0 110 0x04
+			       0 111 0x04
+			       0 112 0x04
+			       0 113 0x04
+			       0 114 0x04
+			       0 115 0x04
+			       0 116 0x04
+			       0 117 0x04
+			       0 118 0x04
+			       0 119 0x04 >;
+	};
+
 	i2c@7000c000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -44,18 +70,18 @@
 		interrupts = < 0 53 0x04 >;
 	};
 
-	i2s@70002800 {
+	tegra_i2s1: i2s@70002800 {
 		compatible = "nvidia,tegra20-i2s";
 		reg = <0x70002800 0x200>;
 		interrupts = < 0 13 0x04 >;
-		dma-channel = < 2 >;
+		nvidia,dma-request-selector = < &apbdma 2 >;
 	};
 
-	i2s@70002a00 {
+	tegra_i2s2: i2s@70002a00 {
 		compatible = "nvidia,tegra20-i2s";
 		reg = <0x70002a00 0x200>;
 		interrupts = < 0 3 0x04 >;
-		dma-channel = < 1 >;
+		nvidia,dma-request-selector = < &apbdma 1 >;
 	};
 
 	das@70000c00 {
@@ -75,6 +101,8 @@
 			       0 89 0x04 >;
 		#gpio-cells = <2>;
 		gpio-controller;
+		#interrupt-cells = <2>;
+		interrupt-controller;
 	};
 
 	pinmux: pinmux@70000000 {
@@ -120,6 +148,13 @@
 		interrupts = < 0 91 0x04 >;
 	};
 
+	emc@7000f400 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "nvidia,tegra20-emc";
+		reg = <0x7000f400 0x200>;
+	};
+
 	sdhci@c8000000 {
 		compatible = "nvidia,tegra20-sdhci";
 		reg = <0xc8000000 0x200>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index ee7db98..ac4b75c 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,6 +4,11 @@
 	compatible = "nvidia,tegra30";
 	interrupt-parent = <&intc>;
 
+	pmc@7000f400 {
+		compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+		reg = <0x7000e400 0x400>;
+	};
+
 	intc: interrupt-controller@50041000 {
 		compatible = "arm,cortex-a9-gic";
 		interrupt-controller;
@@ -12,6 +17,43 @@
 		      < 0x50040100 0x0100 >;
 	};
 
+	apbdma: dma@6000a000 {
+		compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+		reg = <0x6000a000 0x1400>;
+		interrupts = < 0 104 0x04
+			       0 105 0x04
+			       0 106 0x04
+			       0 107 0x04
+			       0 108 0x04
+			       0 109 0x04
+			       0 110 0x04
+			       0 111 0x04
+			       0 112 0x04
+			       0 113 0x04
+			       0 114 0x04
+			       0 115 0x04
+			       0 116 0x04
+			       0 117 0x04
+			       0 118 0x04
+			       0 119 0x04
+			       0 128 0x04
+			       0 129 0x04
+			       0 130 0x04
+			       0 131 0x04
+			       0 132 0x04
+			       0 133 0x04
+			       0 134 0x04
+			       0 135 0x04
+			       0 136 0x04
+			       0 137 0x04
+			       0 138 0x04
+			       0 139 0x04
+			       0 140 0x04
+			       0 141 0x04
+			       0 142 0x04
+			       0 143 0x04 >;
+	};
+
 	i2c@7000c000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -55,9 +97,18 @@
 	gpio: gpio@6000d000 {
 		compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
 		reg = < 0x6000d000 0x1000 >;
-		interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >;
+		interrupts = < 0 32 0x04
+			       0 33 0x04
+			       0 34 0x04
+			       0 35 0x04
+			       0 55 0x04
+			       0 87 0x04
+			       0 89 0x04
+			       0 125 0x04 >;
 		#gpio-cells = <2>;
 		gpio-controller;
+		#interrupt-cells = <2>;
+		interrupt-controller;
 	};
 
 	serial@70006000 {
diff --git a/arch/arm/boot/dts/testcases/tests-phandle.dtsi b/arch/arm/boot/dts/testcases/tests-phandle.dtsi
index ec0c4e6..0007d3c 100644
--- a/arch/arm/boot/dts/testcases/tests-phandle.dtsi
+++ b/arch/arm/boot/dts/testcases/tests-phandle.dtsi
@@ -31,6 +31,8 @@
 				phandle-list-bad-phandle = <12345678 0 0>;
 				phandle-list-bad-args = <&provider2 1 0>,
 							<&provider3 0>;
+				empty-property;
+				unterminated-string = [40 41 42 43];
 			};
 		};
 	};
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index c47d619..aa52699 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -51,7 +51,6 @@ union gic_base {
 };
 
 struct gic_chip_data {
-	unsigned int irq_offset;
 	union gic_base dist_base;
 	union gic_base cpu_base;
 #ifdef CONFIG_CPU_PM
@@ -61,9 +60,7 @@ struct gic_chip_data {
 	u32 __percpu *saved_ppi_enable;
 	u32 __percpu *saved_ppi_conf;
 #endif
-#ifdef CONFIG_IRQ_DOMAIN
-	struct irq_domain domain;
-#endif
+	struct irq_domain *domain;
 	unsigned int gic_irqs;
 #ifdef CONFIG_GIC_NON_BANKED
 	void __iomem *(*get_base)(union gic_base *);
@@ -282,7 +279,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 		irqnr = irqstat & ~0x1c00;
 
 		if (likely(irqnr > 15 && irqnr < 1021)) {
-			irqnr = irq_domain_to_irq(&gic->domain, irqnr);
+			irqnr = irq_find_mapping(gic->domain, irqnr);
 			handle_IRQ(irqnr, regs);
 			continue;
 		}
@@ -314,8 +311,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
 	if (gic_irq == 1023)
 		goto out;
 
-	cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);
-	if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
+	cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
+	if (unlikely(gic_irq < 32 || gic_irq > 1020))
 		do_bad_IRQ(cascade_irq, desc);
 	else
 		generic_handle_irq(cascade_irq);
@@ -348,10 +345,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 
 static void __init gic_dist_init(struct gic_chip_data *gic)
 {
-	unsigned int i, irq;
+	unsigned int i;
 	u32 cpumask;
 	unsigned int gic_irqs = gic->gic_irqs;
-	struct irq_domain *domain = &gic->domain;
 	void __iomem *base = gic_data_dist_base(gic);
 	u32 cpu = cpu_logical_map(smp_processor_id());
 
@@ -386,23 +382,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
 	for (i = 32; i < gic_irqs; i += 32)
 		writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
-	/*
-	 * Setup the Linux IRQ subsystem.
-	 */
-	irq_domain_for_each_irq(domain, i, irq) {
-		if (i < 32) {
-			irq_set_percpu_devid(irq);
-			irq_set_chip_and_handler(irq, &gic_chip,
-						 handle_percpu_devid_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
-		} else {
-			irq_set_chip_and_handler(irq, &gic_chip,
-						 handle_fasteoi_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-		}
-		irq_set_chip_data(irq, gic);
-	}
-
 	writel_relaxed(1, base + GIC_DIST_CTRL);
 }
 
@@ -618,11 +597,27 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
 }
 #endif
 
-#ifdef CONFIG_OF
-static int gic_irq_domain_dt_translate(struct irq_domain *d,
-				       struct device_node *controller,
-				       const u32 *intspec, unsigned int intsize,
-				       unsigned long *out_hwirq, unsigned int *out_type)
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				irq_hw_number_t hw)
+{
+	if (hw < 32) {
+		irq_set_percpu_devid(irq);
+		irq_set_chip_and_handler(irq, &gic_chip,
+					 handle_percpu_devid_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+	} else {
+		irq_set_chip_and_handler(irq, &gic_chip,
+					 handle_fasteoi_irq);
+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	}
+	irq_set_chip_data(irq, d->host_data);
+	return 0;
+}
+
+static int gic_irq_domain_xlate(struct irq_domain *d,
+				struct device_node *controller,
+				const u32 *intspec, unsigned int intsize,
+				unsigned long *out_hwirq, unsigned int *out_type)
 {
 	if (d->of_node != controller)
 		return -EINVAL;
@@ -639,26 +634,23 @@ static int gic_irq_domain_dt_translate(struct irq_domain *d,
 	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
 	return 0;
 }
-#endif
 
 const struct irq_domain_ops gic_irq_domain_ops = {
-#ifdef CONFIG_OF
-	.dt_translate = gic_irq_domain_dt_translate,
-#endif
+	.map = gic_irq_domain_map,
+	.xlate = gic_irq_domain_xlate,
 };
 
 void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 			   void __iomem *dist_base, void __iomem *cpu_base,
-			   u32 percpu_offset)
+			   u32 percpu_offset, struct device_node *node)
 {
+	irq_hw_number_t hwirq_base;
 	struct gic_chip_data *gic;
-	struct irq_domain *domain;
-	int gic_irqs;
+	int gic_irqs, irq_base;
 
 	BUG_ON(gic_nr >= MAX_GIC_NR);
 
 	gic = &gic_data[gic_nr];
-	domain = &gic->domain;
 #ifdef CONFIG_GIC_NON_BANKED
 	if (percpu_offset) { /* Frankein-GIC without banked registers... */
 		unsigned int cpu;
@@ -694,13 +686,12 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 	 * For primary GICs, skip over SGIs.
 	 * For secondary GICs, skip over PPIs, too.
 	 */
-	domain->hwirq_base = 32;
-	if (gic_nr == 0) {
-		if ((irq_start & 31) > 0) {
-			domain->hwirq_base = 16;
-			if (irq_start != -1)
-				irq_start = (irq_start & ~31) + 16;
-		}
+	if (gic_nr == 0 && (irq_start & 31) > 0) {
+		hwirq_base = 16;
+		if (irq_start != -1)
+			irq_start = (irq_start & ~31) + 16;
+	} else {
+		hwirq_base = 32;
 	}
 
 	/*
@@ -713,17 +704,17 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		gic_irqs = 1020;
 	gic->gic_irqs = gic_irqs;
 
-	domain->nr_irq = gic_irqs - domain->hwirq_base;
-	domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq,
-					   numa_node_id());
-	if (IS_ERR_VALUE(domain->irq_base)) {
+	gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
+	irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
+	if (IS_ERR_VALUE(irq_base)) {
 		WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
 		     irq_start);
-		domain->irq_base = irq_start;
+		irq_base = irq_start;
 	}
-	domain->priv = gic;
-	domain->ops = &gic_irq_domain_ops;
-	irq_domain_add(domain);
+	gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
+				    hwirq_base, &gic_irq_domain_ops, gic);
+	if (WARN_ON(!gic->domain))
+		return;
 
 	gic_chip.flags |= gic_arch_extn.flags;
 	gic_dist_init(gic);
@@ -768,7 +759,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
 	void __iomem *dist_base;
 	u32 percpu_offset;
 	int irq;
-	struct irq_domain *domain = &gic_data[gic_cnt].domain;
 
 	if (WARN_ON(!node))
 		return -ENODEV;
@@ -782,9 +772,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 		percpu_offset = 0;
 
-	domain->of_node = of_node_get(node);
-
-	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset);
+	gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
 
 	if (parent) {
 		irq = irq_of_parse_and_map(node, 0);
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index d1bcd7b..fb1f1cf 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -320,13 +320,6 @@ err0:
 	return -EBUSY;
 }
 
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as we don't have even crappy BIOSes to set it properly.
- * The implementation is from arch/i386/pci/i386.c
- */
-unsigned int pcibios_max_latency = 255;
-
 /* ITE bridge requires setting latency timer to avoid early bus access
    termination by PCI bus master devices
 */
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index d8e44a4..ff3ad22 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -1502,12 +1502,13 @@ int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
 	struct pl330_thread *thrd = ch_id;
 	struct pl330_dmac *pl330;
 	unsigned long flags;
-	int ret = 0, active = thrd->req_running;
+	int ret = 0, active;
 
 	if (!thrd || thrd->free || thrd->dmac->state == DYING)
 		return -EINVAL;
 
 	pl330 = thrd->dmac;
+	active = thrd->req_running;
 
 	spin_lock_irqsave(&pl330->lock, flags);
 
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 61691cd..9173d11 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -16,6 +16,7 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -28,9 +29,8 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <asm/mach/irq.h>
+#include <asm/mach-types.h>
 #include <asm/sizes.h>
 
 #include <asm/hardware/sa1111.h>
@@ -86,8 +86,10 @@
 #define IRQ_S1_CD_VALID		(52)
 #define IRQ_S0_BVD1_STSCHG	(53)
 #define IRQ_S1_BVD1_STSCHG	(54)
+#define SA1111_IRQ_NR		(55)
 
-extern void __init sa1110_mb_enable(void);
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
 
 /*
  * We keep the following data for the overall SA1111.  Note that the
@@ -104,6 +106,7 @@ struct sa1111 {
 	int		irq_base;	/* base for cascaded on-chip IRQs */
 	spinlock_t	lock;
 	void __iomem	*base;
+	struct sa1111_platform_data *pdata;
 #ifdef CONFIG_PM
 	void		*saved_state;
 #endif
@@ -118,6 +121,7 @@ static struct sa1111 *g_sa1111;
 struct sa1111_dev_info {
 	unsigned long	offset;
 	unsigned long	skpcr_mask;
+	bool		dma;
 	unsigned int	devid;
 	unsigned int	irq[6];
 };
@@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
 	{
 		.offset		= SA1111_USB,
 		.skpcr_mask	= SKPCR_UCLKEN,
+		.dma		= true,
 		.devid		= SA1111_DEVID_USB,
 		.irq = {
 			IRQ_USBPWR,
@@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
 	{
 		.offset		= 0x0600,
 		.skpcr_mask	= SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+		.dma		= true,
 		.devid		= SA1111_DEVID_SAC,
 		.irq = {
 			AUDXMTDMADONEA,
@@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
 	{
 		.offset		= SA1111_KBD,
 		.skpcr_mask	= SKPCR_PTCLKEN,
-		.devid		= SA1111_DEVID_PS2,
+		.devid		= SA1111_DEVID_PS2_KBD,
 		.irq = {
 			IRQ_TPRXINT,
 			IRQ_TPTXINT
@@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
 	{
 		.offset		= SA1111_MSE,
 		.skpcr_mask	= SKPCR_PMCLKEN,
-		.devid		= SA1111_DEVID_PS2,
+		.devid		= SA1111_DEVID_PS2_MSE,
 		.irq = {
 			IRQ_MSRXINT,
 			IRQ_MSTXINT
@@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = {
 	.irq_set_wake	= sa1111_wake_highirq,
 };
 
-static void sa1111_setup_irq(struct sa1111 *sachip)
+static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
 {
 	void __iomem *irqbase = sachip->base + SA1111_INTC;
-	unsigned int irq;
+	unsigned i, irq;
+	int ret;
 
 	/*
 	 * We're guaranteed that this region hasn't been taken.
 	 */
 	request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
 
+	ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1);
+	if (ret <= 0) {
+		dev_err(sachip->dev, "unable to allocate %u irqs: %d\n",
+			SA1111_IRQ_NR, ret);
+		if (ret == 0)
+			ret = -EINVAL;
+		return ret;
+	}
+
+	sachip->irq_base = ret;
+
 	/* disable all IRQs */
 	sa1111_writel(0, irqbase + SA1111_INTEN0);
 	sa1111_writel(0, irqbase + SA1111_INTEN1);
@@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
 	sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
 	sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
 
-	for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+	for (i = IRQ_GPAIN0; i <= SSPROR; i++) {
+		irq = sachip->irq_base + i;
 		irq_set_chip_and_handler(irq, &sa1111_low_chip,
 					 handle_edge_irq);
 		irq_set_chip_data(irq, sachip);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
 
-	for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+	for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) {
+		irq = sachip->irq_base + i;
 		irq_set_chip_and_handler(irq, &sa1111_high_chip,
 					 handle_edge_irq);
 		irq_set_chip_data(irq, sachip);
@@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
 	irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
 	irq_set_handler_data(sachip->irq, sachip);
 	irq_set_chained_handler(sachip->irq, sa1111_irq_handler);
+
+	dev_info(sachip->dev, "Providing IRQ%u-%u\n",
+		sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1);
+
+	return 0;
 }
 
 /*
@@ -581,41 +606,10 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
 }
 #endif
 
-#ifdef CONFIG_DMABOUNCE
-/*
- * According to the "Intel StrongARM SA-1111 Microprocessor Companion
- * Chip Specification Update" (June 2000), erratum #7, there is a
- * significant bug in the SA1111 SDRAM shared memory controller.  If
- * an access to a region of memory above 1MB relative to the bank base,
- * it is important that address bit 10 _NOT_ be asserted. Depending
- * on the configuration of the RAM, bit 10 may correspond to one
- * of several different (processor-relative) address bits.
- *
- * This routine only identifies whether or not a given DMA address
- * is susceptible to the bug.
- *
- * This should only get called for sa1111_device types due to the
- * way we configure our device dma_masks.
- */
-static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
-{
-	/*
-	 * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
-	 * User's Guide" mentions that jumpers R51 and R52 control the
-	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
-	 * SDRAM bank 1 on Neponset). The default configuration selects
-	 * Assabet, so any address in bank 1 is necessarily invalid.
-	 */
-	return (machine_is_assabet() || machine_is_pfs168()) &&
-		(addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
-}
-#endif
-
 static void sa1111_dev_release(struct device *_dev)
 {
 	struct sa1111_dev *dev = SA1111_DEV(_dev);
 
-	release_resource(&dev->res);
 	kfree(dev);
 }
 
@@ -624,67 +618,58 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
 		      struct sa1111_dev_info *info)
 {
 	struct sa1111_dev *dev;
+	unsigned i;
 	int ret;
 
 	dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
 	if (!dev) {
 		ret = -ENOMEM;
-		goto out;
+		goto err_alloc;
 	}
 
+	device_initialize(&dev->dev);
 	dev_set_name(&dev->dev, "%4.4lx", info->offset);
 	dev->devid	 = info->devid;
 	dev->dev.parent  = sachip->dev;
 	dev->dev.bus     = &sa1111_bus_type;
 	dev->dev.release = sa1111_dev_release;
-	dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
 	dev->res.start   = sachip->phys + info->offset;
 	dev->res.end     = dev->res.start + 511;
 	dev->res.name    = dev_name(&dev->dev);
 	dev->res.flags   = IORESOURCE_MEM;
 	dev->mapbase     = sachip->base + info->offset;
 	dev->skpcr_mask  = info->skpcr_mask;
-	memmove(dev->irq, info->irq, sizeof(dev->irq));
-
-	ret = request_resource(parent, &dev->res);
-	if (ret) {
-		printk("SA1111: failed to allocate resource for %s\n",
-			dev->res.name);
-		dev_set_name(&dev->dev, NULL);
-		kfree(dev);
-		goto out;
-	}
-
 
-	ret = device_register(&dev->dev);
-	if (ret) {
-		release_resource(&dev->res);
-		kfree(dev);
-		goto out;
-	}
+	for (i = 0; i < ARRAY_SIZE(info->irq); i++)
+		dev->irq[i] = sachip->irq_base + info->irq[i];
 
-#ifdef CONFIG_DMABOUNCE
 	/*
-	 * If the parent device has a DMA mask associated with it,
-	 * propagate it down to the children.
+	 * If the parent device has a DMA mask associated with it, and
+	 * this child supports DMA, propagate it down to the children.
 	 */
-	if (sachip->dev->dma_mask) {
+	if (info->dma && sachip->dev->dma_mask) {
 		dev->dma_mask = *sachip->dev->dma_mask;
 		dev->dev.dma_mask = &dev->dma_mask;
+		dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
+	}
 
-		if (dev->dma_mask != 0xffffffffUL) {
-			ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
-					sa1111_needs_bounce);
-			if (ret) {
-				dev_err(&dev->dev, "SA1111: Failed to register"
-					" with dmabounce\n");
-				device_unregister(&dev->dev);
-			}
-		}
+	ret = request_resource(parent, &dev->res);
+	if (ret) {
+		dev_err(sachip->dev, "failed to allocate resource for %s\n",
+			dev->res.name);
+		goto err_resource;
 	}
-#endif
 
-out:
+	ret = device_add(&dev->dev);
+	if (ret)
+		goto err_add;
+	return 0;
+
+ err_add:
+	release_resource(&dev->res);
+ err_resource:
+	put_device(&dev->dev);
+ err_alloc:
 	return ret;
 }
 
@@ -698,16 +683,21 @@ out:
  *	Returns:
  *	%-ENODEV	device not found.
  *	%-EBUSY		physical address already marked in-use.
+ *	%-EINVAL	no platform data passed
  *	%0		successful.
  */
 static int __devinit
 __sa1111_probe(struct device *me, struct resource *mem, int irq)
 {
+	struct sa1111_platform_data *pd = me->platform_data;
 	struct sa1111 *sachip;
 	unsigned long id;
 	unsigned int has_devs;
 	int i, ret = -ENODEV;
 
+	if (!pd)
+		return -EINVAL;
+
 	sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
 	if (!sachip)
 		return -ENOMEM;
@@ -727,6 +717,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	sachip->dev = me;
 	dev_set_drvdata(sachip->dev, sachip);
 
+	sachip->pdata = pd;
 	sachip->phys = mem->start;
 	sachip->irq = irq;
 
@@ -759,6 +750,16 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	 */
 	sa1111_wake(sachip);
 
+	/*
+	 * The interrupt controller must be initialised before any
+	 * other device to ensure that the interrupts are available.
+	 */
+	if (sachip->irq != NO_IRQ) {
+		ret = sa1111_setup_irq(sachip, pd->irq_base);
+		if (ret)
+			goto err_unmap;
+	}
+
 #ifdef CONFIG_ARCH_SA1100
 	{
 	unsigned int val;
@@ -789,24 +790,14 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
 	}
 #endif
 
-	/*
-	 * The interrupt controller must be initialised before any
-	 * other device to ensure that the interrupts are available.
-	 */
-	if (sachip->irq != NO_IRQ)
-		sa1111_setup_irq(sachip);
-
 	g_sa1111 = sachip;
 
 	has_devs = ~0;
-	if (machine_is_assabet() || machine_is_jornada720() ||
-	    machine_is_badge4())
-		has_devs &= ~(1 << 4);
-	else
-		has_devs &= ~(1 << 1);
+	if (pd)
+		has_devs &= ~pd->disable_devs;
 
 	for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
-		if (has_devs & (1 << i))
+		if (sa1111_devices[i].devid & has_devs)
 			sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
 
 	return 0;
@@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
 
 static int sa1111_remove_one(struct device *dev, void *data)
 {
-	device_unregister(dev);
+	struct sa1111_dev *sadev = SA1111_DEV(dev);
+	device_del(&sadev->dev);
+	release_resource(&sadev->res);
+	put_device(&sadev->dev);
 	return 0;
 }
 
@@ -846,6 +840,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
 	if (sachip->irq != NO_IRQ) {
 		irq_set_chained_handler(sachip->irq, NULL);
 		irq_set_handler_data(sachip->irq, NULL);
+		irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
 
 		release_mem_region(sachip->phys + SA1111_INTC, 512);
 	}
@@ -904,6 +899,9 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
 	save->skpwm0   = sa1111_readl(base + SA1111_SKPWM0);
 	save->skpwm1   = sa1111_readl(base + SA1111_SKPWM1);
 
+	sa1111_writel(0, sachip->base + SA1111_SKPWM0);
+	sa1111_writel(0, sachip->base + SA1111_SKPWM1);
+
 	base = sachip->base + SA1111_INTC;
 	save->intpol0  = sa1111_readl(base + SA1111_INTPOL0);
 	save->intpol1  = sa1111_readl(base + SA1111_INTPOL1);
@@ -919,13 +917,15 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
 	 */
 	val = sa1111_readl(sachip->base + SA1111_SKCR);
 	sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR);
-	sa1111_writel(0, sachip->base + SA1111_SKPWM0);
-	sa1111_writel(0, sachip->base + SA1111_SKPWM1);
 
 	clk_disable(sachip->clk);
 
 	spin_unlock_irqrestore(&sachip->lock, flags);
 
+#ifdef CONFIG_ARCH_SA1100
+	sa1110_mb_disable();
+#endif
+
 	return 0;
 }
 
@@ -966,6 +966,11 @@ static int sa1111_resume(struct platform_device *dev)
 	 */
 	sa1111_wake(sachip);
 
+#ifdef CONFIG_ARCH_SA1100
+	/* Enable the memory bus request/grant signals */
+	sa1110_mb_enable();
+#endif
+
 	/*
 	 * Only lock for write ops. Also, sa1111_wake must be called with
 	 * released spinlock!
@@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = {
 	.resume		= sa1111_resume,
 	.driver		= {
 		.name	= "sa1111",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -1238,16 +1244,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io);
  *	sa1111_enable_device - enable an on-chip SA1111 function block
  *	@sadev: SA1111 function block device to enable
  */
-void sa1111_enable_device(struct sa1111_dev *sadev)
+int sa1111_enable_device(struct sa1111_dev *sadev)
 {
 	struct sa1111 *sachip = sa1111_chip_driver(sadev);
 	unsigned long flags;
 	unsigned int val;
+	int ret = 0;
 
-	spin_lock_irqsave(&sachip->lock, flags);
-	val = sa1111_readl(sachip->base + SA1111_SKPCR);
-	sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
-	spin_unlock_irqrestore(&sachip->lock, flags);
+	if (sachip->pdata && sachip->pdata->enable)
+		ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);
+
+	if (ret == 0) {
+		spin_lock_irqsave(&sachip->lock, flags);
+		val = sa1111_readl(sachip->base + SA1111_SKPCR);
+		sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+		spin_unlock_irqrestore(&sachip->lock, flags);
+	}
+	return ret;
 }
 EXPORT_SYMBOL(sa1111_enable_device);
 
@@ -1265,6 +1278,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
 	val = sa1111_readl(sachip->base + SA1111_SKPCR);
 	sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
 	spin_unlock_irqrestore(&sachip->lock, flags);
+
+	if (sachip->pdata && sachip->pdata->disable)
+		sachip->pdata->disable(sachip->pdata->data, sadev->devid);
 }
 EXPORT_SYMBOL(sa1111_disable_device);
 
@@ -1279,7 +1295,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv)
 	struct sa1111_dev *dev = SA1111_DEV(_dev);
 	struct sa1111_driver *drv = SA1111_DRV(_drv);
 
-	return dev->devid == drv->devid;
+	return dev->devid & drv->devid;
 }
 
 static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
@@ -1304,6 +1320,14 @@ static int sa1111_bus_resume(struct device *dev)
 	return ret;
 }
 
+static void sa1111_bus_shutdown(struct device *dev)
+{
+	struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+
+	if (drv && drv->shutdown)
+		drv->shutdown(SA1111_DEV(dev));
+}
+
 static int sa1111_bus_probe(struct device *dev)
 {
 	struct sa1111_dev *sadev = SA1111_DEV(dev);
@@ -1333,6 +1357,7 @@ struct bus_type sa1111_bus_type = {
 	.remove		= sa1111_bus_remove,
 	.suspend	= sa1111_bus_suspend,
 	.resume		= sa1111_bus_resume,
+	.shutdown	= sa1111_bus_shutdown,
 };
 EXPORT_SYMBOL(sa1111_bus_type);
 
@@ -1349,9 +1374,70 @@ void sa1111_driver_unregister(struct sa1111_driver *driver)
 }
 EXPORT_SYMBOL(sa1111_driver_unregister);
 
+#ifdef CONFIG_DMABOUNCE
+/*
+ * According to the "Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update" (June 2000), erratum #7, there is a
+ * significant bug in the SA1111 SDRAM shared memory controller.  If
+ * an access to a region of memory above 1MB relative to the bank base,
+ * it is important that address bit 10 _NOT_ be asserted. Depending
+ * on the configuration of the RAM, bit 10 may correspond to one
+ * of several different (processor-relative) address bits.
+ *
+ * This routine only identifies whether or not a given DMA address
+ * is susceptible to the bug.
+ *
+ * This should only get called for sa1111_device types due to the
+ * way we configure our device dma_masks.
+ */
+static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+{
+	/*
+	 * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+	 * User's Guide" mentions that jumpers R51 and R52 control the
+	 * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
+	 * SDRAM bank 1 on Neponset). The default configuration selects
+	 * Assabet, so any address in bank 1 is necessarily invalid.
+	 */
+	return (machine_is_assabet() || machine_is_pfs168()) &&
+		(addr >= 0xc8000000 || (addr + size) >= 0xc8000000);
+}
+
+static int sa1111_notifier_call(struct notifier_block *n, unsigned long action,
+	void *data)
+{
+	struct sa1111_dev *dev = SA1111_DEV(data);
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) {
+			int ret = dmabounce_register_dev(&dev->dev, 1024, 4096,
+					sa1111_needs_bounce);
+			if (ret)
+				dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret);
+		}
+		break;
+
+	case BUS_NOTIFY_DEL_DEVICE:
+		if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL)
+			dmabounce_unregister_dev(&dev->dev);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block sa1111_bus_notifier = {
+	.notifier_call = sa1111_notifier_call,
+};
+#endif
+
 static int __init sa1111_init(void)
 {
 	int ret = bus_register(&sa1111_bus_type);
+#ifdef CONFIG_DMABOUNCE
+	if (ret == 0)
+		bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
 	if (ret == 0)
 		platform_driver_register(&sa1111_device_driver);
 	return ret;
@@ -1360,6 +1446,9 @@ static int __init sa1111_init(void)
 static void __exit sa1111_exit(void)
 {
 	platform_driver_unregister(&sa1111_device_driver);
+#ifdef CONFIG_DMABOUNCE
+	bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier);
+#endif
 	bus_unregister(&sa1111_bus_type);
 }
 
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 8794a34..df13a3f 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -26,6 +26,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 
+#include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
 
 static long __init sp804_get_clock_rate(const char *name)
@@ -67,7 +68,16 @@ static long __init sp804_get_clock_rate(const char *name)
 	return rate;
 }
 
-void __init sp804_clocksource_init(void __iomem *base, const char *name)
+static void __iomem *sched_clock_base;
+
+static u32 sp804_read(void)
+{
+	return ~readl_relaxed(sched_clock_base + TIMER_VALUE);
+}
+
+void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
+						     const char *name,
+						     int use_sched_clock)
 {
 	long rate = sp804_get_clock_rate(name);
 
@@ -83,6 +93,11 @@ void __init sp804_clocksource_init(void __iomem *base, const char *name)
 
 	clocksource_mmio_init(base + TIMER_VALUE, name,
 		rate, 200, 32, clocksource_mmio_readl_down);
+
+	if (use_sched_clock) {
+		sched_clock_base = base;
+		setup_sched_clock(sp804_read, 32, rate);
+	}
 }
 
 
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index dcb004a..7a66311 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -56,7 +56,7 @@ struct vic_device {
 	u32		int_enable;
 	u32		soft_int;
 	u32		protect;
-	struct irq_domain domain;
+	struct irq_domain *domain;
 };
 
 /* we cannot allocate memory when VICs are initially registered */
@@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
 	v->resume_sources = resume_sources;
 	v->irq = irq;
 	vic_id++;
-
-	v->domain.irq_base = irq;
-	v->domain.nr_irq = 32;
-#ifdef CONFIG_OF_IRQ
-	v->domain.of_node = of_node_get(node);
-#endif /* CONFIG_OF */
-	v->domain.ops = &irq_domain_simple_ops;
-	irq_domain_add(&v->domain);
+	v->domain = irq_domain_add_legacy(node, 32, irq, 0,
+					  &irq_domain_simple_ops, v);
 }
 
 static void vic_ack_irq(struct irq_data *d)
@@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
 	vic_register(base, irq_start, 0, node);
 }
 
-static void __init __vic_init(void __iomem *base, unsigned int irq_start,
+void __init __vic_init(void __iomem *base, unsigned int irq_start,
 			      u32 vic_sources, u32 resume_sources,
 			      struct device_node *node)
 {
@@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
 	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
 	while (stat) {
 		irq = ffs(stat) - 1;
-		handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+		handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
 		stat &= ~(1 << irq);
 		handled = 1;
 	}
diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig
deleted file mode 100644
index 8826eb2..0000000
--- a/arch/arm/configs/at91cap9_defconfig
+++ /dev/null
@@ -1,108 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91CAP9=y
-CONFIG_MACH_AT91CAP9ADK=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
index 1103f62..a8314c3 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -57,18 +57,24 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_PCI=y
 CONFIG_E100=y
+CONFIG_SMC91X=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIAL_AMBA_PL010=y
 CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
 CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_ARMCLCD=y
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL030=y
 CONFIG_EXT2_FS=y
+CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_CRAMFS=y
@@ -78,5 +84,7 @@ CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
 CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
new file mode 100644
index 0000000..fb20881
--- /dev/null
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -0,0 +1,145 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_LPC32XX=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n81 root=/dev/ram0"
+CONFIG_CPU_IDLE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_MUSEUM_IDS=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_AT25=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_SMSC_PHY=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_LPC32XX=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PNX=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_PNX4008_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_SOC=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_LIBUSUAL=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_LPC32XX=y
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 6ee781b..1ebbf45 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -77,10 +77,10 @@ CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
-CONFIG_I2C=m
+CONFIG_I2C=y
 # CONFIG_I2C_COMPAT is not set
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_MXS=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MXS=y
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=m
 CONFIG_DEBUG_GPIO=y
@@ -90,6 +90,20 @@ CONFIG_GPIO_SYSFS=y
 CONFIG_DISPLAY_SUPPORT=m
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_DRIVERS=y
+CONFIG_SND_ARM=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MXS_SOC=y
+CONFIG_SND_SOC_MXS_SGTL5000=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_MXS=y
 CONFIG_RTC_CLASS=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 62f8095..23371b1 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -137,6 +137,11 @@
 	disable_irq
 	.endm
 
+	.macro	save_and_disable_irqs_notrace, oldcpsr
+	mrs	\oldcpsr, cpsr
+	disable_irq_notrace
+	.endm
+
 /*
  * Restore interrupt state previously stored in a register.  We don't
  * guarantee that this will preserve the flags.
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
new file mode 100644
index 0000000..3dabd8dd
--- /dev/null
+++ b/arch/arm/include/asm/cp15.h
@@ -0,0 +1,87 @@
+#ifndef __ASM_ARM_CP15_H
+#define __ASM_ARM_CP15_H
+
+#include <asm/system.h>
+
+/*
+ * CR1 bits (CP#15 CR1)
+ */
+#define CR_M	(1 << 0)	/* MMU enable				*/
+#define CR_A	(1 << 1)	/* Alignment abort enable		*/
+#define CR_C	(1 << 2)	/* Dcache enable			*/
+#define CR_W	(1 << 3)	/* Write buffer enable			*/
+#define CR_P	(1 << 4)	/* 32-bit exception handler		*/
+#define CR_D	(1 << 5)	/* 32-bit data address range		*/
+#define CR_L	(1 << 6)	/* Implementation defined		*/
+#define CR_B	(1 << 7)	/* Big endian				*/
+#define CR_S	(1 << 8)	/* System MMU protection		*/
+#define CR_R	(1 << 9)	/* ROM MMU protection			*/
+#define CR_F	(1 << 10)	/* Implementation defined		*/
+#define CR_Z	(1 << 11)	/* Implementation defined		*/
+#define CR_I	(1 << 12)	/* Icache enable			*/
+#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
+#define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
+#define CR_L4	(1 << 15)	/* LDR pc can set T bit			*/
+#define CR_DT	(1 << 16)
+#define CR_IT	(1 << 18)
+#define CR_ST	(1 << 19)
+#define CR_FI	(1 << 21)	/* Fast interrupt (lower latency mode)	*/
+#define CR_U	(1 << 22)	/* Unaligned access operation		*/
+#define CR_XP	(1 << 23)	/* Extended page tables			*/
+#define CR_VE	(1 << 24)	/* Vectored interrupts			*/
+#define CR_EE	(1 << 25)	/* Exception (Big) Endian		*/
+#define CR_TRE	(1 << 28)	/* TEX remap enable			*/
+#define CR_AFE	(1 << 29)	/* Access flag enable			*/
+#define CR_TE	(1 << 30)	/* Thumb exception enable		*/
+
+#ifndef __ASSEMBLY__
+
+#if __LINUX_ARM_ARCH__ >= 4
+#define vectors_high()	(cr_alignment & CR_V)
+#else
+#define vectors_high()	(0)
+#endif
+
+extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
+extern unsigned long cr_alignment;	/* defined in entry-armv.S */
+
+static inline unsigned int get_cr(void)
+{
+	unsigned int val;
+	asm("mrc p15, 0, %0, c1, c0, 0	@ get CR" : "=r" (val) : : "cc");
+	return val;
+}
+
+static inline void set_cr(unsigned int val)
+{
+	asm volatile("mcr p15, 0, %0, c1, c0, 0	@ set CR"
+	  : : "r" (val) : "cc");
+	isb();
+}
+
+#ifndef CONFIG_SMP
+extern void adjust_cr(unsigned long mask, unsigned long set);
+#endif
+
+#define CPACC_FULL(n)		(3 << (n * 2))
+#define CPACC_SVC(n)		(1 << (n * 2))
+#define CPACC_DISABLE(n)	(0 << (n * 2))
+
+static inline unsigned int get_copro_access(void)
+{
+	unsigned int val;
+	asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
+	  : "=r" (val) : : "cc");
+	return val;
+}
+
+static inline void set_copro_access(unsigned int val)
+{
+	asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
+	  : : "r" (val) : "cc");
+	isb();
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 0e9ce8d..38050b1 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -130,8 +130,4 @@ struct mm_struct;
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 
-extern int vectors_user_mapping(void);
-#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
-#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
-
 #endif
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 7df239b..c4c87bc 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -103,11 +103,11 @@
 #define L2X0_ADDR_FILTER_EN		1
 
 #ifndef __ASSEMBLY__
-extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
 #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
-extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask);
+extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
 #else
-static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask)
+static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
 	return -ENODEV;
 }
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4bdfe00..4b1ce6c 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -39,7 +39,7 @@ struct device_node;
 extern struct irq_chip gic_arch_extn;
 
 void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
-		    u32 offset);
+		    u32 offset, struct device_node *);
 int gic_of_init(struct device_node *node, struct device_node *parent);
 void gic_secondary_init(unsigned int);
 void gic_handle_irq(struct pt_regs *regs);
@@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
 static inline void gic_init(unsigned int nr, int start,
 			    void __iomem *dist , void __iomem *cpu)
 {
-	gic_init_bases(nr, start, dist, cpu, 0);
+	gic_init_bases(nr, start, dist, cpu, 0, NULL);
 }
 
 #endif
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h
index 43cab49..73f84fa 100644
--- a/arch/arm/include/asm/hardware/it8152.h
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -9,6 +9,9 @@
 
 #ifndef __ASM_HARDWARE_IT8152_H
 #define __ASM_HARDWARE_IT8152_H
+
+#include <mach/irqs.h>
+
 extern void __iomem *it8152_base_address;
 
 #define IT8152_IO_BASE			(it8152_base_address + 0x03e00000)
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
index 575fa81..c182138 100644
--- a/arch/arm/include/asm/hardware/pl330.h
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -41,7 +41,7 @@ enum pl330_dstcachectrl {
 	DCCTRL1, /* Bufferable only */
 	DCCTRL2, /* Cacheable, but do not allocate */
 	DCCTRL3, /* Cacheable and bufferable, but do not allocate */
-	DINVALID1 = 8,
+	DINVALID1,              /* AWCACHE = 0x1000 */
 	DINVALID2,
 	DCCTRL6, /* Cacheable write-through, allocate on writes only */
 	DCCTRL7, /* Cacheable write-back, allocate on writes only */
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
index 92ed254..7c2bbc7 100644
--- a/arch/arm/include/asm/hardware/sa1111.h
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -132,34 +132,10 @@
 #define SKPCR_DCLKEN	(1<<7)
 #define SKPCR_PWMCLKEN	(1<<8)
 
-/*
- * USB Host controller
- */
+/* USB Host controller */
 #define SA1111_USB		0x0400
 
 /*
- * Offsets from SA1111_USB_BASE
- */
-#define SA1111_USB_STATUS	0x0118
-#define SA1111_USB_RESET	0x011c
-#define SA1111_USB_IRQTEST	0x0120
-
-#define USB_RESET_FORCEIFRESET	(1 << 0)
-#define USB_RESET_FORCEHCRESET	(1 << 1)
-#define USB_RESET_CLKGENRESET	(1 << 2)
-#define USB_RESET_SIMSCALEDOWN	(1 << 3)
-#define USB_RESET_USBINTTEST	(1 << 4)
-#define USB_RESET_SLEEPSTBYEN	(1 << 5)
-#define USB_RESET_PWRSENSELOW	(1 << 6)
-#define USB_RESET_PWRCTRLLOW	(1 << 7)
-
-#define USB_STATUS_IRQHCIRMTWKUP  (1 <<  7)
-#define USB_STATUS_IRQHCIBUFFACC  (1 <<  8)
-#define USB_STATUS_NIRQHCIM       (1 <<  9)
-#define USB_STATUS_NHCIMFCLR      (1 << 10)
-#define USB_STATUS_USBPWRSENSE    (1 << 11)
-
-/*
  * Serial Audio Controller
  *
  * Registers
@@ -327,22 +303,6 @@
  *    PC_SSR		GPIO Block C Sleep State
  */
 
-#define _PA_DDR		_SA1111( 0x1000 )
-#define _PA_DRR		_SA1111( 0x1004 )
-#define _PA_DWR		_SA1111( 0x1004 )
-#define _PA_SDR		_SA1111( 0x1008 )
-#define _PA_SSR		_SA1111( 0x100c )
-#define _PB_DDR		_SA1111( 0x1010 )
-#define _PB_DRR		_SA1111( 0x1014 )
-#define _PB_DWR		_SA1111( 0x1014 )
-#define _PB_SDR		_SA1111( 0x1018 )
-#define _PB_SSR		_SA1111( 0x101c )
-#define _PC_DDR		_SA1111( 0x1020 )
-#define _PC_DRR		_SA1111( 0x1024 )
-#define _PC_DWR		_SA1111( 0x1024 )
-#define _PC_SDR		_SA1111( 0x1028 )
-#define _PC_SSR		_SA1111( 0x102c )
-
 #define SA1111_GPIO	0x1000
 
 #define SA1111_GPIO_PADDR	(0x000)
@@ -425,106 +385,30 @@
 #define SA1111_WAKEPOL0		0x0034
 #define SA1111_WAKEPOL1		0x0038
 
-/*
- * PS/2 Trackpad and Mouse Interfaces
- *
- * Registers
- *    PS2CR		Control Register
- *    PS2STAT		Status Register
- *    PS2DATA		Transmit/Receive Data register
- *    PS2CLKDIV		Clock Division Register
- *    PS2PRECNT		Clock Precount Register
- *    PS2TEST1		Test register 1
- *    PS2TEST2		Test register 2
- *    PS2TEST3		Test register 3
- *    PS2TEST4		Test register 4
- */
-
+/* PS/2 Trackpad and Mouse Interfaces */
 #define SA1111_KBD		0x0a00
 #define SA1111_MSE		0x0c00
 
-/*
- * These are offsets from the above bases.
- */
-#define SA1111_PS2CR		0x0000
-#define SA1111_PS2STAT		0x0004
-#define SA1111_PS2DATA		0x0008
-#define SA1111_PS2CLKDIV	0x000c
-#define SA1111_PS2PRECNT	0x0010
-
-#define PS2CR_ENA		0x08
-#define PS2CR_FKD		0x02
-#define PS2CR_FKC		0x01
-
-#define PS2STAT_STP		0x0100
-#define PS2STAT_TXE		0x0080
-#define PS2STAT_TXB		0x0040
-#define PS2STAT_RXF		0x0020
-#define PS2STAT_RXB		0x0010
-#define PS2STAT_ENA		0x0008
-#define PS2STAT_RXP		0x0004
-#define PS2STAT_KBD		0x0002
-#define PS2STAT_KBC		0x0001
+/* PCMCIA Interface */
+#define SA1111_PCMCIA		0x1600
 
-/*
- * PCMCIA Interface
- *
- * Registers
- *    PCSR	Status Register
- *    PCCR	Control Register
- *    PCSSR	Sleep State Register
- */
-
-#define SA1111_PCMCIA	0x1600
-
-/*
- * These are offsets from the above base.
- */
-#define SA1111_PCCR	0x0000
-#define SA1111_PCSSR	0x0004
-#define SA1111_PCSR	0x0008
-
-#define PCSR_S0_READY	(1<<0)
-#define PCSR_S1_READY	(1<<1)
-#define PCSR_S0_DETECT	(1<<2)
-#define PCSR_S1_DETECT	(1<<3)
-#define PCSR_S0_VS1	(1<<4)
-#define PCSR_S0_VS2	(1<<5)
-#define PCSR_S1_VS1	(1<<6)
-#define PCSR_S1_VS2	(1<<7)
-#define PCSR_S0_WP	(1<<8)
-#define PCSR_S1_WP	(1<<9)
-#define PCSR_S0_BVD1	(1<<10)
-#define PCSR_S0_BVD2	(1<<11)
-#define PCSR_S1_BVD1	(1<<12)
-#define PCSR_S1_BVD2	(1<<13)
-
-#define PCCR_S0_RST	(1<<0)
-#define PCCR_S1_RST	(1<<1)
-#define PCCR_S0_FLT	(1<<2)
-#define PCCR_S1_FLT	(1<<3)
-#define PCCR_S0_PWAITEN	(1<<4)
-#define PCCR_S1_PWAITEN	(1<<5)
-#define PCCR_S0_PSE	(1<<6)
-#define PCCR_S1_PSE	(1<<7)
-
-#define PCSSR_S0_SLEEP	(1<<0)
-#define PCSSR_S1_SLEEP	(1<<1)
 
 
 
 
 extern struct bus_type sa1111_bus_type;
 
-#define SA1111_DEVID_SBI	0
-#define SA1111_DEVID_SK		1
-#define SA1111_DEVID_USB	2
-#define SA1111_DEVID_SAC	3
-#define SA1111_DEVID_SSP	4
-#define SA1111_DEVID_PS2	5
-#define SA1111_DEVID_GPIO	6
-#define SA1111_DEVID_INT	7
-#define SA1111_DEVID_PCMCIA	8
+#define SA1111_DEVID_SBI	(1 << 0)
+#define SA1111_DEVID_SK		(1 << 1)
+#define SA1111_DEVID_USB	(1 << 2)
+#define SA1111_DEVID_SAC	(1 << 3)
+#define SA1111_DEVID_SSP	(1 << 4)
+#define SA1111_DEVID_PS2	(3 << 5)
+#define SA1111_DEVID_PS2_KBD	(1 << 5)
+#define SA1111_DEVID_PS2_MSE	(1 << 6)
+#define SA1111_DEVID_GPIO	(1 << 7)
+#define SA1111_DEVID_INT	(1 << 8)
+#define SA1111_DEVID_PCMCIA	(1 << 9)
 
 struct sa1111_dev {
 	struct device	dev;
@@ -548,6 +432,7 @@ struct sa1111_driver {
 	int (*remove)(struct sa1111_dev *);
 	int (*suspend)(struct sa1111_dev *, pm_message_t);
 	int (*resume)(struct sa1111_dev *);
+	void (*shutdown)(struct sa1111_dev *);
 };
 
 #define SA1111_DRV(_d)	container_of((_d), struct sa1111_driver, drv)
@@ -555,9 +440,10 @@ struct sa1111_driver {
 #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
 
 /*
- * These frob the SKPCR register.
+ * These frob the SKPCR register, and call platform specific
+ * enable/disable functions.
  */
-void sa1111_enable_device(struct sa1111_dev *);
+int sa1111_enable_device(struct sa1111_dev *);
 void sa1111_disable_device(struct sa1111_dev *);
 
 unsigned int sa1111_pll_clock(struct sa1111_dev *);
@@ -580,6 +466,10 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
 
 struct sa1111_platform_data {
 	int	irq_base;	/* base for cascaded on-chip IRQs */
+	unsigned disable_devs;
+	void	*data;
+	int	(*enable)(void *, unsigned);
+	void	(*disable)(void *, unsigned);
 };
 
 #endif  /* _ASM_ARCH_SA1111 */
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 4384d81..2dd9d3f 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -1,2 +1,15 @@
-void sp804_clocksource_init(void __iomem *, const char *);
+void __sp804_clocksource_and_sched_clock_init(void __iomem *,
+					      const char *, int);
+
+static inline void sp804_clocksource_init(void __iomem *base, const char *name)
+{
+	__sp804_clocksource_and_sched_clock_init(base, name, 0);
+}
+
+static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
+							  const char *name)
+{
+	__sp804_clocksource_and_sched_clock_init(base, name, 1);
+}
+
 void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index f42ebd6..e14af1a 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -47,6 +47,8 @@
 struct device_node;
 struct pt_regs;
 
+void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
+		u32 resume_sources, struct device_node *node);
 void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
 int vic_of_init(struct device_node *node, struct device_node *parent);
 void vic_handle_irq(struct pt_regs *regs);
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index a4edd19..8c5e828 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -57,7 +57,7 @@ static inline void *kmap_high_get(struct page *page)
 #ifdef CONFIG_HIGHMEM
 extern void *kmap(struct page *page);
 extern void kunmap(struct page *page);
-extern void *__kmap_atomic(struct page *page);
+extern void *kmap_atomic(struct page *page);
 extern void __kunmap_atomic(void *kvaddr);
 extern void *kmap_atomic_pfn(unsigned long pfn);
 extern struct page *kmap_atomic_to_page(const void *ptr);
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 5a526af..35c21c3 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -1,14 +1,18 @@
 #ifndef __ASM_ARM_IRQ_H
 #define __ASM_ARM_IRQ_H
 
+#define NR_IRQS_LEGACY	16
+
+#ifndef CONFIG_SPARSE_IRQ
 #include <mach/irqs.h>
+#else
+#define NR_IRQS NR_IRQS_LEGACY
+#endif
 
 #ifndef irq_canonicalize
 #define irq_canonicalize(i)	(i)
 #endif
 
-#define NR_IRQS_LEGACY	16
-
 /*
  * Use this value to indicate lack of interrupt
  * capability
diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h
index 6b884d2..e8567bb 100644
--- a/arch/arm/include/asm/mc146818rtc.h
+++ b/arch/arm/include/asm/mc146818rtc.h
@@ -5,7 +5,9 @@
 #define _ASM_MC146818RTC_H
 
 #include <linux/io.h>
-#include <mach/irqs.h>
+#include <linux/kernel.h>
+
+#define RTC_IRQ BUILD_BUG_ON(1)
 
 #ifndef RTC_PORT
 #define RTC_PORT(x)	(0x70 + (x))
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 71605d9..a0b3cac 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/proc-fns.h>
+#include <asm-generic/mm_hooks.h>
 
 void __check_kvm_seq(struct mm_struct *mm);
 
@@ -133,32 +134,4 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
 #define deactivate_mm(tsk,mm)	do { } while (0)
 #define activate_mm(prev,next)	switch_mm(prev, next, NULL)
 
-/*
- * We are inserting a "fake" vma for the user-accessible vector page so
- * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
- * But we also want to remove it before the generic code gets to see it
- * during process exit or the unmapping of it would  cause total havoc.
- * (the macro is used as remove_vma() is static to mm/mmap.c)
- */
-#define arch_exit_mmap(mm) \
-do { \
-	struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
-	if (high_vma) { \
-		BUG_ON(high_vma->vm_next);  /* it should be last */ \
-		if (high_vma->vm_prev) \
-			high_vma->vm_prev->vm_next = NULL; \
-		else \
-			mm->mmap = NULL; \
-		rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
-		mm->mmap_cache = NULL; \
-		mm->map_count--; \
-		remove_vma(high_vma); \
-	} \
-} while (0)
-
-static inline void arch_dup_mmap(struct mm_struct *oldmm,
-				 struct mm_struct *mm)
-{
-}
-
 #endif
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
index c0efdd6..19c48de 100644
--- a/arch/arm/include/asm/opcodes.h
+++ b/arch/arm/include/asm/opcodes.h
@@ -17,4 +17,63 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
 #define ARM_OPCODE_CONDTEST_PASS   1
 #define ARM_OPCODE_CONDTEST_UNCOND 2
 
+
+/*
+ * Opcode byteswap helpers
+ *
+ * These macros help with converting instructions between a canonical integer
+ * format and in-memory representation, in an endianness-agnostic manner.
+ *
+ * __mem_to_opcode_*() convert from in-memory representation to canonical form.
+ * __opcode_to_mem_*() convert from canonical form to in-memory representation.
+ *
+ *
+ * Canonical instruction representation:
+ *
+ *	ARM:		0xKKLLMMNN
+ *	Thumb 16-bit:	0x0000KKLL, where KK < 0xE8
+ *	Thumb 32-bit:	0xKKLLMMNN, where KK >= 0xE8
+ *
+ * There is no way to distinguish an ARM instruction in canonical representation
+ * from a Thumb instruction (just as these cannot be distinguished in memory).
+ * Where this distinction is important, it needs to be tracked separately.
+ *
+ * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
+ * represent any valid Thumb-2 instruction.  For this range,
+ * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/swab.h>
+
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define __opcode_to_mem_arm(x) swab32(x)
+#define __opcode_to_mem_thumb16(x) swab16(x)
+#define __opcode_to_mem_thumb32(x) swahb32(x)
+#else
+#define __opcode_to_mem_arm(x) ((u32)(x))
+#define __opcode_to_mem_thumb16(x) ((u16)(x))
+#define __opcode_to_mem_thumb32(x) swahw32(x)
+#endif
+
+#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
+#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
+#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
+
+/* Operations specific to Thumb opcodes */
+
+/* Instruction size checks: */
+#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL)
+#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL)
+
+/* Operations to construct or split 32-bit Thumb instructions: */
+#define __opcode_thumb32_first(x) ((u16)((x) >> 16))
+#define __opcode_thumb32_second(x) ((u16)(x))
+#define __opcode_thumb32_compose(first, second) \
+	(((u32)(u16)(first) << 16) | (u32)(u16)(second))
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* __ASM_ARM_OPCODES_H */
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 97b440c..5838361 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -151,6 +151,8 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
 #define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, const void *from);
 
+#define __HAVE_ARCH_GATE_AREA 1
+
 #ifdef CONFIG_ARM_LPAE
 #include <asm/pgtable-3level-types.h>
 #else
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index 99cfe36..00cbe10 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -12,10 +12,6 @@
 #ifndef __ARM_PERF_EVENT_H__
 #define __ARM_PERF_EVENT_H__
 
-/* ARM performance counters start from 1 (in the cp15 accesses) so use the
- * same indexes here for consistency. */
-#define PERF_EVENT_INDEX_OFFSET 1
-
 /* ARM perf PMU IDs for use by internal perf clients. */
 enum arm_perf_pmu_ids {
 	ARM_PERF_PMU_ID_XSCALE1	= 0,
@@ -26,6 +22,7 @@ enum arm_perf_pmu_ids {
 	ARM_PERF_PMU_ID_CA9,
 	ARM_PERF_PMU_ID_CA5,
 	ARM_PERF_PMU_ID_CA15,
+	ARM_PERF_PMU_ID_CA7,
 	ARM_NUM_PMU_IDS,
 };
 
diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h
index 2446d23..efdf990 100644
--- a/arch/arm/include/asm/posix_types.h
+++ b/arch/arm/include/asm/posix_types.h
@@ -19,59 +19,22 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long		__kernel_ino_t;
 typedef unsigned short		__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short		__kernel_nlink_t;
-typedef long			__kernel_off_t;
-typedef int			__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short		__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short		__kernel_uid_t;
 typedef unsigned short		__kernel_gid_t;
-typedef unsigned int		__kernel_size_t;
-typedef int			__kernel_ssize_t;
-typedef int			__kernel_ptrdiff_t;
-typedef long			__kernel_time_t;
-typedef long			__kernel_suseconds_t;
-typedef long			__kernel_clock_t;
-typedef int			__kernel_timer_t;
-typedef int			__kernel_clockid_t;
-typedef int			__kernel_daddr_t;
-typedef char *			__kernel_caddr_t;
-typedef unsigned short		__kernel_uid16_t;
-typedef unsigned short		__kernel_gid16_t;
-typedef unsigned int		__kernel_uid32_t;
-typedef unsigned int		__kernel_gid32_t;
+#define __kernel_uid_t __kernel_uid_t
 
-typedef unsigned short		__kernel_old_uid_t;
-typedef unsigned short		__kernel_old_gid_t;
 typedef unsigned short		__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#ifdef __GNUC__
-typedef long long		__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-#define __FD_SET(fd, fdsetp) \
-		(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd, fdsetp) \
-		(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd, fdsetp) \
-		((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) \
-		(memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))
-
-#endif
+#include <asm-generic/posix_types.h>
 
 #endif
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index ce280b8..d27b071 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -22,6 +22,7 @@
 #include <asm/hw_breakpoint.h>
 #include <asm/ptrace.h>
 #include <asm/types.h>
+#include <asm/system.h>
 
 #ifdef __KERNEL__
 #define STACK_TOP	((current->personality & ADDR_LIMIT_32BIT) ? \
@@ -55,7 +56,6 @@ struct thread_struct {
 #define start_thread(regs,pc,sp)					\
 ({									\
 	unsigned long *stack = (unsigned long *)sp;			\
-	set_fs(USER_DS);						\
 	memset(regs->uregs, 0, sizeof(regs->uregs));			\
 	if (current->personality & ADDR_LIMIT_32BIT)			\
 		regs->ARM_cpsr = USR_MODE;				\
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
index ee03633..aeae9c6 100644
--- a/arch/arm/include/asm/prom.h
+++ b/arch/arm/include/asm/prom.h
@@ -13,8 +13,6 @@
 
 #ifdef CONFIG_OF
 
-#include <asm/irq.h>
-
 extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
 extern void arm_dt_memblock_reserve(void);
 
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index dec6f9a..d958c74 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -64,5 +64,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index e4c96cc..f726365 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -15,37 +15,6 @@
 #define CPU_ARCH_ARMv7		9
 
 /*
- * CR1 bits (CP#15 CR1)
- */
-#define CR_M	(1 << 0)	/* MMU enable				*/
-#define CR_A	(1 << 1)	/* Alignment abort enable		*/
-#define CR_C	(1 << 2)	/* Dcache enable			*/
-#define CR_W	(1 << 3)	/* Write buffer enable			*/
-#define CR_P	(1 << 4)	/* 32-bit exception handler		*/
-#define CR_D	(1 << 5)	/* 32-bit data address range		*/
-#define CR_L	(1 << 6)	/* Implementation defined		*/
-#define CR_B	(1 << 7)	/* Big endian				*/
-#define CR_S	(1 << 8)	/* System MMU protection		*/
-#define CR_R	(1 << 9)	/* ROM MMU protection			*/
-#define CR_F	(1 << 10)	/* Implementation defined		*/
-#define CR_Z	(1 << 11)	/* Implementation defined		*/
-#define CR_I	(1 << 12)	/* Icache enable			*/
-#define CR_V	(1 << 13)	/* Vectors relocated to 0xffff0000	*/
-#define CR_RR	(1 << 14)	/* Round Robin cache replacement	*/
-#define CR_L4	(1 << 15)	/* LDR pc can set T bit			*/
-#define CR_DT	(1 << 16)
-#define CR_IT	(1 << 18)
-#define CR_ST	(1 << 19)
-#define CR_FI	(1 << 21)	/* Fast interrupt (lower latency mode)	*/
-#define CR_U	(1 << 22)	/* Unaligned access operation		*/
-#define CR_XP	(1 << 23)	/* Extended page tables			*/
-#define CR_VE	(1 << 24)	/* Vectored interrupts			*/
-#define CR_EE	(1 << 25)	/* Exception (Big) Endian		*/
-#define CR_TRE	(1 << 28)	/* TEX remap enable			*/
-#define CR_AFE	(1 << 29)	/* Access flag enable			*/
-#define CR_TE	(1 << 30)	/* Thumb exception enable		*/
-
-/*
  * This is used to ensure the compiler did actually allocate the register we
  * asked it for some inline assembly sequences.  Apparently we can't trust
  * the compiler from one version to another so a bit of paranoia won't hurt.
@@ -110,6 +79,7 @@ extern void cpu_init(void);
 
 void soft_restart(unsigned long);
 extern void (*arm_pm_restart)(char str, const char *cmd);
+extern void (*arm_pm_idle)(void);
 
 #define UDBG_UNDEFINED	(1 << 0)
 #define UDBG_SYSCALL	(1 << 1)
@@ -119,12 +89,6 @@ extern void (*arm_pm_restart)(char str, const char *cmd);
 
 extern unsigned int user_debug;
 
-#if __LINUX_ARM_ARCH__ >= 4
-#define vectors_high()	(cr_alignment & CR_V)
-#else
-#define vectors_high()	(0)
-#endif
-
 #if __LINUX_ARM_ARCH__ >= 7 ||		\
 	(__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
 #define sev()	__asm__ __volatile__ ("sev" : : : "memory")
@@ -185,46 +149,6 @@ extern unsigned int user_debug;
 #define set_mb(var, value)	do { var = value; smp_mb(); } while (0)
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
-extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
-extern unsigned long cr_alignment;	/* defined in entry-armv.S */
-
-static inline unsigned int get_cr(void)
-{
-	unsigned int val;
-	asm("mrc p15, 0, %0, c1, c0, 0	@ get CR" : "=r" (val) : : "cc");
-	return val;
-}
-
-static inline void set_cr(unsigned int val)
-{
-	asm volatile("mcr p15, 0, %0, c1, c0, 0	@ set CR"
-	  : : "r" (val) : "cc");
-	isb();
-}
-
-#ifndef CONFIG_SMP
-extern void adjust_cr(unsigned long mask, unsigned long set);
-#endif
-
-#define CPACC_FULL(n)		(3 << (n * 2))
-#define CPACC_SVC(n)		(1 << (n * 2))
-#define CPACC_DISABLE(n)	(0 << (n * 2))
-
-static inline unsigned int get_copro_access(void)
-{
-	unsigned int val;
-	asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
-	  : "=r" (val) : : "cc");
-	return val;
-}
-
-static inline void set_copro_access(unsigned int val)
-{
-	asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
-	  : : "r" (val) : "cc");
-	isb();
-}
-
 /*
  * switch_mm() may do a full cache flush over the context switch,
  * so enable interrupts over the context switch to avoid high
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index 02b2f82..85fe61e 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -318,6 +318,21 @@ extern struct cpu_tlb_fns cpu_tlb;
 
 #define tlb_flag(f)	((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
 
+#define __tlb_op(f, insnarg, arg)					\
+	do {								\
+		if (always_tlb_flags & (f))				\
+			asm("mcr " insnarg				\
+			    : : "r" (arg) : "cc");			\
+		else if (possible_tlb_flags & (f))			\
+			asm("tst %1, %2\n\t"				\
+			    "mcrne " insnarg				\
+			    : : "r" (arg), "r" (__tlb_flag), "Ir" (f)	\
+			    : "cc");					\
+	} while (0)
+
+#define tlb_op(f, regs, arg)	__tlb_op(f, "p15, 0, %0, " regs, arg)
+#define tlb_l2_op(f, regs, arg)	__tlb_op(f, "p15, 1, %0, " regs, arg)
+
 static inline void local_flush_tlb_all(void)
 {
 	const int zero = 0;
@@ -326,16 +341,11 @@ static inline void local_flush_tlb_all(void)
 	if (tlb_flag(TLB_WB))
 		dsb();
 
-	if (tlb_flag(TLB_V3_FULL))
-		asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
-	if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
-		asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
-	if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
-		asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
-	if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
-		asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
-	if (tlb_flag(TLB_V7_UIS_FULL))
-		asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
+	tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
+	tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero);
+	tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero);
+	tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero);
+	tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero);
 
 	if (tlb_flag(TLB_BARRIER)) {
 		dsb();
@@ -352,29 +362,23 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
 	if (tlb_flag(TLB_WB))
 		dsb();
 
-	if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
-		if (tlb_flag(TLB_V3_FULL))
-			asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
-		if (tlb_flag(TLB_V4_U_FULL))
-			asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
-		if (tlb_flag(TLB_V4_D_FULL))
-			asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
-		if (tlb_flag(TLB_V4_I_FULL))
-			asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+	if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) {
+		if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
+			tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
+			tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero);
+			tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero);
+			tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero);
+		}
+		put_cpu();
 	}
-	put_cpu();
-
-	if (tlb_flag(TLB_V6_U_ASID))
-		asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
-	if (tlb_flag(TLB_V6_D_ASID))
-		asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
-	if (tlb_flag(TLB_V6_I_ASID))
-		asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
-	if (tlb_flag(TLB_V7_UIS_ASID))
+
+	tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid);
+	tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid);
+	tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid);
 #ifdef CONFIG_ARM_ERRATA_720789
-		asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
+	tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", zero);
 #else
-		asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
+	tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", asid);
 #endif
 
 	if (tlb_flag(TLB_BARRIER))
@@ -392,30 +396,23 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 	if (tlb_flag(TLB_WB))
 		dsb();
 
-	if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-		if (tlb_flag(TLB_V3_PAGE))
-			asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc");
-		if (tlb_flag(TLB_V4_U_PAGE))
-			asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
-		if (tlb_flag(TLB_V4_D_PAGE))
-			asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
-		if (tlb_flag(TLB_V4_I_PAGE))
-			asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
+	if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) &&
+	    cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+		tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr);
+		tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr);
+		tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr);
+		tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr);
 		if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
 			asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 	}
 
-	if (tlb_flag(TLB_V6_U_PAGE))
-		asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
-	if (tlb_flag(TLB_V6_D_PAGE))
-		asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
-	if (tlb_flag(TLB_V6_I_PAGE))
-		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
-	if (tlb_flag(TLB_V7_UIS_PAGE))
+	tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr);
+	tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr);
+	tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr);
 #ifdef CONFIG_ARM_ERRATA_720789
-		asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc");
+	tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK);
 #else
-		asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
+	tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr);
 #endif
 
 	if (tlb_flag(TLB_BARRIER))
@@ -432,25 +429,17 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
 	if (tlb_flag(TLB_WB))
 		dsb();
 
-	if (tlb_flag(TLB_V3_PAGE))
-		asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
-	if (tlb_flag(TLB_V4_U_PAGE))
-		asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
-	if (tlb_flag(TLB_V4_D_PAGE))
-		asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
-	if (tlb_flag(TLB_V4_I_PAGE))
-		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
+	tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr);
+	tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr);
+	tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr);
+	tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr);
 	if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
 		asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
 
-	if (tlb_flag(TLB_V6_U_PAGE))
-		asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
-	if (tlb_flag(TLB_V6_D_PAGE))
-		asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
-	if (tlb_flag(TLB_V6_I_PAGE))
-		asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
-	if (tlb_flag(TLB_V7_UIS_PAGE))
-		asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
+	tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr);
+	tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr);
+	tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr);
+	tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr);
 
 	if (tlb_flag(TLB_BARRIER)) {
 		dsb();
@@ -475,13 +464,8 @@ static inline void flush_pmd_entry(void *pmd)
 {
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
-	if (tlb_flag(TLB_DCLEAN))
-		asm("mcr	p15, 0, %0, c7, c10, 1	@ flush_pmd"
-			: : "r" (pmd) : "cc");
-
-	if (tlb_flag(TLB_L2CLEAN_FR))
-		asm("mcr	p15, 1, %0, c15, c9, 1  @ L2 flush_pmd"
-			: : "r" (pmd) : "cc");
+	tlb_op(TLB_DCLEAN, "c7, c10, 1	@ flush_pmd", pmd);
+	tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1  @ L2 flush_pmd", pmd);
 
 	if (tlb_flag(TLB_WB))
 		dsb();
@@ -491,15 +475,11 @@ static inline void clean_pmd_entry(void *pmd)
 {
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
 
-	if (tlb_flag(TLB_DCLEAN))
-		asm("mcr	p15, 0, %0, c7, c10, 1	@ flush_pmd"
-			: : "r" (pmd) : "cc");
-
-	if (tlb_flag(TLB_L2CLEAN_FR))
-		asm("mcr	p15, 1, %0, c15, c9, 1  @ L2 flush_pmd"
-			: : "r" (pmd) : "cc");
+	tlb_op(TLB_DCLEAN, "c7, c10, 1	@ flush_pmd", pmd);
+	tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1  @ L2 flush_pmd", pmd);
 }
 
+#undef tlb_op
 #undef tlb_flag
 #undef always_tlb_flags
 #undef possible_tlb_flags
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index 5b29a66..f555bb3 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr)
 	return in ? : __in_irqentry_text(ptr);
 }
 
-extern void __init early_trap_init(void);
+extern void __init early_trap_init(void *);
 extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
 extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);
 
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 43b740d..bb89898 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -7,6 +7,8 @@ AFLAGS_head.o        := -DTEXT_OFFSET=$(TEXT_OFFSET)
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_insn.o = -pg
+CFLAGS_REMOVE_patch.o = -pg
 endif
 
 CFLAGS_REMOVE_return_address.o = -pg
@@ -14,8 +16,8 @@ CFLAGS_REMOVE_return_address.o = -pg
 # Object file lists.
 
 obj-y		:= elf.o entry-armv.o entry-common.o irq.o opcodes.o \
-		   process.o ptrace.o return_address.o setup.o signal.o \
-		   sys_arm.o stacktrace.o time.o traps.o
+		   process.o ptrace.o return_address.o sched_clock.o \
+		   setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
 
 obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
 
@@ -30,14 +32,13 @@ obj-$(CONFIG_ARTHUR)		+= arthur.o
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
 obj-$(CONFIG_PCI)		+= bios32.o isa.o
 obj-$(CONFIG_ARM_CPU_SUSPEND)	+= sleep.o suspend.o
-obj-$(CONFIG_HAVE_SCHED_CLOCK)	+= sched_clock.o
 obj-$(CONFIG_SMP)		+= smp.o smp_tlb.o
 obj-$(CONFIG_HAVE_ARM_SCU)	+= smp_scu.o
 obj-$(CONFIG_HAVE_ARM_TWD)	+= smp_twd.o
-obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
-obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
+obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o insn.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o insn.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
-obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-common.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-common.o patch.o
 ifdef CONFIG_THUMB2_KERNEL
 obj-$(CONFIG_KPROBES)		+= kprobes-thumb.o
 else
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 4dd0eda..ddcda2e 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -578,7 +578,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
 	for (ec = cards; ec; ec = ec->next) {
 		int pending;
 
-		if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
+		if (!ec->claimed || !ec->irq || ec->slot_no == 8)
 			continue;
 
 		if (ec->ops && ec->ops->irqpending)
@@ -805,8 +805,8 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
 
 	ec->slot_no = slot;
 	ec->easi = type == ECARD_EASI;
-	ec->irq = NO_IRQ;
-	ec->fiq = NO_IRQ;
+	ec->irq = 0;
+	ec->fiq = 0;
 	ec->dma = NO_DMA;
 	ec->ops = &ecard_default_ops;
 
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 4c164ec..c32f845 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -42,9 +42,9 @@
 #include <linux/seq_file.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <asm/fiq.h>
 #include <asm/irq.h>
-#include <asm/system.h>
 #include <asm/traps.h>
 
 static unsigned long no_fiq_insn;
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index c0062ad..858c63f 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -16,10 +16,13 @@
 #include <linux/uaccess.h>
 
 #include <asm/cacheflush.h>
+#include <asm/opcodes.h>
 #include <asm/ftrace.h>
 
+#include "insn.h"
+
 #ifdef CONFIG_THUMB2_KERNEL
-#define	NOP		0xeb04f85d	/* pop.w {lr} */
+#define	NOP		0xf85deb04	/* pop.w {lr} */
 #else
 #define	NOP		0xe8bd4000	/* pop {lr} */
 #endif
@@ -60,64 +63,9 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
 }
 #endif
 
-#ifdef CONFIG_THUMB2_KERNEL
-static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
-				       bool link)
-{
-	unsigned long s, j1, j2, i1, i2, imm10, imm11;
-	unsigned long first, second;
-	long offset;
-
-	offset = (long)addr - (long)(pc + 4);
-	if (offset < -16777216 || offset > 16777214) {
-		WARN_ON_ONCE(1);
-		return 0;
-	}
-
-	s	= (offset >> 24) & 0x1;
-	i1	= (offset >> 23) & 0x1;
-	i2	= (offset >> 22) & 0x1;
-	imm10	= (offset >> 12) & 0x3ff;
-	imm11	= (offset >>  1) & 0x7ff;
-
-	j1 = (!i1) ^ s;
-	j2 = (!i2) ^ s;
-
-	first = 0xf000 | (s << 10) | imm10;
-	second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
-	if (link)
-		second |= 1 << 14;
-
-	return (second << 16) | first;
-}
-#else
-static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
-				       bool link)
-{
-	unsigned long opcode = 0xea000000;
-	long offset;
-
-	if (link)
-		opcode |= 1 << 24;
-
-	offset = (long)addr - (long)(pc + 8);
-	if (unlikely(offset < -33554432 || offset > 33554428)) {
-		/* Can't generate branches that far (from ARM ARM). Ftrace
-		 * doesn't generate branches outside of kernel text.
-		 */
-		WARN_ON_ONCE(1);
-		return 0;
-	}
-
-	offset = (offset >> 2) & 0x00ffffff;
-
-	return opcode | offset;
-}
-#endif
-
 static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
 {
-	return ftrace_gen_branch(pc, addr, true);
+	return arm_gen_branch_link(pc, addr);
 }
 
 static int ftrace_modify_code(unsigned long pc, unsigned long old,
@@ -125,11 +73,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
 {
 	unsigned long replaced;
 
-	if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
-		return -EFAULT;
+	if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+		old = __opcode_to_mem_thumb32(old);
+		new = __opcode_to_mem_thumb32(new);
+	} else {
+		old = __opcode_to_mem_arm(old);
+		new = __opcode_to_mem_arm(new);
+	}
 
-	if (replaced != old)
-		return -EINVAL;
+	if (old) {
+		if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
+			return -EFAULT;
+
+		if (replaced != old)
+			return -EINVAL;
+	}
 
 	if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
 		return -EPERM;
@@ -141,23 +99,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
 
 int ftrace_update_ftrace_func(ftrace_func_t func)
 {
-	unsigned long pc, old;
+	unsigned long pc;
 	unsigned long new;
 	int ret;
 
 	pc = (unsigned long)&ftrace_call;
-	memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
 	new = ftrace_call_replace(pc, (unsigned long)func);
 
-	ret = ftrace_modify_code(pc, old, new);
+	ret = ftrace_modify_code(pc, 0, new);
 
 #ifdef CONFIG_OLD_MCOUNT
 	if (!ret) {
 		pc = (unsigned long)&ftrace_call_old;
-		memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
 		new = ftrace_call_replace(pc, (unsigned long)func);
 
-		ret = ftrace_modify_code(pc, old, new);
+		ret = ftrace_modify_code(pc, 0, new);
 	}
 #endif
 
@@ -249,7 +205,7 @@ static int __ftrace_modify_caller(unsigned long *callsite,
 {
 	unsigned long caller_fn = (unsigned long) func;
 	unsigned long pc = (unsigned long) callsite;
-	unsigned long branch = ftrace_gen_branch(pc, caller_fn, false);
+	unsigned long branch = arm_gen_branch(pc, caller_fn);
 	unsigned long nop = 0xe1a00000;	/* mov r0, r0 */
 	unsigned long old = enable ? nop : branch;
 	unsigned long new = enable ? branch : nop;
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index d46f259..278cfc1 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -17,8 +17,8 @@
 #include <asm/assembler.h>
 #include <asm/ptrace.h>
 #include <asm/asm-offsets.h>
+#include <asm/cp15.h>
 #include <asm/thread_info.h>
-#include <asm/system.h>
 
 /*
  * Kernel startup entry point.
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 6d57911..a2e9694 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -15,12 +15,12 @@
 #include <linux/init.h>
 
 #include <asm/assembler.h>
+#include <asm/cp15.h>
 #include <asm/domain.h>
 #include <asm/ptrace.h>
 #include <asm/asm-offsets.h>
 #include <asm/memory.h>
 #include <asm/thread_info.h>
-#include <asm/system.h>
 #include <asm/pgtable.h>
 
 #ifdef CONFIG_DEBUG_LL
diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c
new file mode 100644
index 0000000..ab312e5
--- /dev/null
+++ b/arch/arm/kernel/insn.c
@@ -0,0 +1,61 @@
+#include <linux/kernel.h>
+#include <asm/opcodes.h>
+
+static unsigned long
+__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link)
+{
+	unsigned long s, j1, j2, i1, i2, imm10, imm11;
+	unsigned long first, second;
+	long offset;
+
+	offset = (long)addr - (long)(pc + 4);
+	if (offset < -16777216 || offset > 16777214) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}
+
+	s	= (offset >> 24) & 0x1;
+	i1	= (offset >> 23) & 0x1;
+	i2	= (offset >> 22) & 0x1;
+	imm10	= (offset >> 12) & 0x3ff;
+	imm11	= (offset >>  1) & 0x7ff;
+
+	j1 = (!i1) ^ s;
+	j2 = (!i2) ^ s;
+
+	first = 0xf000 | (s << 10) | imm10;
+	second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
+	if (link)
+		second |= 1 << 14;
+
+	return __opcode_thumb32_compose(first, second);
+}
+
+static unsigned long
+__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link)
+{
+	unsigned long opcode = 0xea000000;
+	long offset;
+
+	if (link)
+		opcode |= 1 << 24;
+
+	offset = (long)addr - (long)(pc + 8);
+	if (unlikely(offset < -33554432 || offset > 33554428)) {
+		WARN_ON_ONCE(1);
+		return 0;
+	}
+
+	offset = (offset >> 2) & 0x00ffffff;
+
+	return opcode | offset;
+}
+
+unsigned long
+__arm_gen_branch(unsigned long pc, unsigned long addr, bool link)
+{
+	if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
+		return __arm_gen_branch_thumb2(pc, addr, link);
+	else
+		return __arm_gen_branch_arm(pc, addr, link);
+}
diff --git a/arch/arm/kernel/insn.h b/arch/arm/kernel/insn.h
new file mode 100644
index 0000000..994d60f
--- /dev/null
+++ b/arch/arm/kernel/insn.h
@@ -0,0 +1,19 @@
+#ifndef __ASM_ARM_INSN_H
+#define __ASM_ARM_INSN_H
+
+unsigned long
+__arm_gen_branch(unsigned long pc, unsigned long addr, bool link);
+
+static inline unsigned long
+arm_gen_branch(unsigned long pc, unsigned long addr)
+{
+	return __arm_gen_branch(pc, addr, false);
+}
+
+static inline unsigned long
+arm_gen_branch_link(unsigned long pc, unsigned long addr)
+{
+	return __arm_gen_branch(pc, addr, true);
+}
+
+#endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3efd82c..3f86ee1 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -181,10 +181,7 @@ void migrate_irqs(void)
 	local_irq_save(flags);
 
 	for_each_irq_desc(i, desc) {
-		bool affinity_broken = false;
-
-		if (!desc)
-			continue;
+		bool affinity_broken;
 
 		raw_spin_lock(&desc->lock);
 		affinity_broken = migrate_one_irq(desc);
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 129c116..ab1869d 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -29,6 +29,7 @@
 #include <asm/cacheflush.h>
 
 #include "kprobes.h"
+#include "patch.h"
 
 #define MIN_STACK_SIZE(addr) 				\
 	min((unsigned long)MAX_STACK_SIZE,		\
@@ -103,57 +104,33 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 	return 0;
 }
 
-#ifdef CONFIG_THUMB2_KERNEL
-
-/*
- * For a 32-bit Thumb breakpoint spanning two memory words we need to take
- * special precautions to insert the breakpoint atomically, especially on SMP
- * systems. This is achieved by calling this arming function using stop_machine.
- */
-static int __kprobes set_t32_breakpoint(void *addr)
-{
-	((u16 *)addr)[0] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION >> 16;
-	((u16 *)addr)[1] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION & 0xffff;
-	flush_insns(addr, 2*sizeof(u16));
-	return 0;
-}
-
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
-	uintptr_t addr = (uintptr_t)p->addr & ~1; /* Remove any Thumb flag */
-
-	if (!is_wide_instruction(p->opcode)) {
-		*(u16 *)addr = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION;
-		flush_insns(addr, sizeof(u16));
-	} else if (addr & 2) {
-		/* A 32-bit instruction spanning two words needs special care */
-		stop_machine(set_t32_breakpoint, (void *)addr, &cpu_online_map);
+	unsigned int brkp;
+	void *addr;
+
+	if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
+		/* Remove any Thumb flag */
+		addr = (void *)((uintptr_t)p->addr & ~1);
+
+		if (is_wide_instruction(p->opcode))
+			brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
+		else
+			brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION;
 	} else {
-		/* Word aligned 32-bit instruction can be written atomically */
-		u32 bkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
-#ifndef __ARMEB__ /* Swap halfwords for little-endian */
-		bkp = (bkp >> 16) | (bkp << 16);
-#endif
-		*(u32 *)addr = bkp;
-		flush_insns(addr, sizeof(u32));
-	}
-}
+		kprobe_opcode_t insn = p->opcode;
 
-#else /* !CONFIG_THUMB2_KERNEL */
+		addr = p->addr;
+		brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
 
-void __kprobes arch_arm_kprobe(struct kprobe *p)
-{
-	kprobe_opcode_t insn = p->opcode;
-	kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
-	if (insn >= 0xe0000000)
-		brkp |= 0xe0000000;  /* Unconditional instruction */
-	else
-		brkp |= insn & 0xf0000000;  /* Copy condition from insn */
-	*p->addr = brkp;
-	flush_insns(p->addr, sizeof(p->addr[0]));
-}
+		if (insn >= 0xe0000000)
+			brkp |= 0xe0000000;  /* Unconditional instruction */
+		else
+			brkp |= insn & 0xf0000000;  /* Copy condition from insn */
+	}
 
-#endif /* !CONFIG_THUMB2_KERNEL */
+	patch_text(addr, brkp);
+}
 
 /*
  * The actual disarming is done here on each CPU and synchronized using
@@ -166,25 +143,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
 int __kprobes __arch_disarm_kprobe(void *p)
 {
 	struct kprobe *kp = p;
-#ifdef CONFIG_THUMB2_KERNEL
-	u16 *addr = (u16 *)((uintptr_t)kp->addr & ~1);
-	kprobe_opcode_t insn = kp->opcode;
-	unsigned int len;
+	void *addr = (void *)((uintptr_t)kp->addr & ~1);
 
-	if (is_wide_instruction(insn)) {
-		((u16 *)addr)[0] = insn>>16;
-		((u16 *)addr)[1] = insn;
-		len = 2*sizeof(u16);
-	} else {
-		((u16 *)addr)[0] = insn;
-		len = sizeof(u16);
-	}
-	flush_insns(addr, len);
+	__patch_text(addr, kp->opcode);
 
-#else /* !CONFIG_THUMB2_KERNEL */
-	*kp->addr = kp->opcode;
-	flush_insns(kp->addr, sizeof(kp->addr[0]));
-#endif
 	return 0;
 }
 
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 764bd45..a300044 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -7,6 +7,7 @@
 #include <linux/delay.h>
 #include <linux/reboot.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -53,6 +54,29 @@ void machine_crash_nonpanic_core(void *unused)
 		cpu_relax();
 }
 
+static void machine_kexec_mask_interrupts(void)
+{
+	unsigned int i;
+	struct irq_desc *desc;
+
+	for_each_irq_desc(i, desc) {
+		struct irq_chip *chip;
+
+		chip = irq_desc_get_chip(desc);
+		if (!chip)
+			continue;
+
+		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
+			chip->irq_eoi(&desc->irq_data);
+
+		if (chip->irq_mask)
+			chip->irq_mask(&desc->irq_data);
+
+		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
+			chip->irq_disable(&desc->irq_data);
+	}
+}
+
 void machine_crash_shutdown(struct pt_regs *regs)
 {
 	unsigned long msecs;
@@ -70,6 +94,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
 		printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
 
 	crash_save_cpu(regs, smp_processor_id());
+	machine_kexec_mask_interrupts();
 
 	printk(KERN_INFO "Loading crashdump kernel...\n");
 }
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
new file mode 100644
index 0000000..07314af
--- /dev/null
+++ b/arch/arm/kernel/patch.c
@@ -0,0 +1,75 @@
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/stop_machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/opcodes.h>
+
+#include "patch.h"
+
+struct patch {
+	void *addr;
+	unsigned int insn;
+};
+
+void __kprobes __patch_text(void *addr, unsigned int insn)
+{
+	bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
+	int size;
+
+	if (thumb2 && __opcode_is_thumb16(insn)) {
+		*(u16 *)addr = __opcode_to_mem_thumb16(insn);
+		size = sizeof(u16);
+	} else if (thumb2 && ((uintptr_t)addr & 2)) {
+		u16 first = __opcode_thumb32_first(insn);
+		u16 second = __opcode_thumb32_second(insn);
+		u16 *addrh = addr;
+
+		addrh[0] = __opcode_to_mem_thumb16(first);
+		addrh[1] = __opcode_to_mem_thumb16(second);
+
+		size = sizeof(u32);
+	} else {
+		if (thumb2)
+			insn = __opcode_to_mem_thumb32(insn);
+		else
+			insn = __opcode_to_mem_arm(insn);
+
+		*(u32 *)addr = insn;
+		size = sizeof(u32);
+	}
+
+	flush_icache_range((uintptr_t)(addr),
+			   (uintptr_t)(addr) + size);
+}
+
+static int __kprobes patch_text_stop_machine(void *data)
+{
+	struct patch *patch = data;
+
+	__patch_text(patch->addr, patch->insn);
+
+	return 0;
+}
+
+void __kprobes patch_text(void *addr, unsigned int insn)
+{
+	struct patch patch = {
+		.addr = addr,
+		.insn = insn,
+	};
+
+	if (cache_ops_need_broadcast()) {
+		stop_machine(patch_text_stop_machine, &patch, cpu_online_mask);
+	} else {
+		bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL)
+				      && __opcode_is_thumb32(insn)
+				      && ((uintptr_t)addr & 2);
+
+		if (straddles_word)
+			stop_machine(patch_text_stop_machine, &patch, NULL);
+		else
+			__patch_text(addr, insn);
+	}
+}
diff --git a/arch/arm/kernel/patch.h b/arch/arm/kernel/patch.h
new file mode 100644
index 0000000..b4731f2
--- /dev/null
+++ b/arch/arm/kernel/patch.h
@@ -0,0 +1,7 @@
+#ifndef _ARM_KERNEL_PATCH_H
+#define _ARM_KERNEL_PATCH_H
+
+void patch_text(void *addr, unsigned int insn);
+void __patch_text(void *addr, unsigned int insn);
+
+#endif
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 5bb91bf..ab59c3b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -712,6 +712,9 @@ init_hw_perf_events(void)
 		case 0xC0F0:	/* Cortex-A15 */
 			cpu_pmu = armv7_a15_pmu_init();
 			break;
+		case 0xC070:	/* Cortex-A7 */
+			cpu_pmu = armv7_a7_pmu_init();
+			break;
 		}
 	/* Intel CPUs [xscale]. */
 	} else if (0x69 == implementor) {
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 6933244..9f342b6 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -610,6 +610,130 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 };
 
 /*
+ * Cortex-A7 HW events mapping
+ */
+static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]		= ARMV7_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= ARMV7_PERFCTR_INSTR_EXECUTED,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+	[PERF_COUNT_HW_CACHE_MISSES]		= ARMV7_PERFCTR_L1_DCACHE_REFILL,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= ARMV7_PERFCTR_PC_WRITE,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+	[PERF_COUNT_HW_BUS_CYCLES]		= ARMV7_PERFCTR_BUS_CYCLES,
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					[PERF_COUNT_HW_CACHE_OP_MAX]
+					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		/*
+		 * The performance counters don't differentiate between read
+		 * and write accesses/misses so this isn't strictly correct,
+		 * but it's the best we can do. Writes and reads get
+		 * combined.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_DCACHE_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_DCACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_DCACHE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_ICACHE_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L1_ICACHE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_CACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACHE_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L2_CACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_L2_CACHE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(NODE)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+/*
  * Perf Events' indices
  */
 #define	ARMV7_IDX_CYCLE_COUNTER	0
@@ -1095,6 +1219,12 @@ static int armv7_a15_map_event(struct perf_event *event)
 				&armv7_a15_perf_cache_map, 0xFF);
 }
 
+static int armv7_a7_map_event(struct perf_event *event)
+{
+	return map_cpu_event(event, &armv7_a7_perf_map,
+				&armv7_a7_perf_cache_map, 0xFF);
+}
+
 static struct arm_pmu armv7pmu = {
 	.handle_irq		= armv7pmu_handle_irq,
 	.enable			= armv7pmu_enable_event,
@@ -1155,6 +1285,16 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
 	armv7pmu.set_event_filter = armv7pmu_set_event_filter;
 	return &armv7pmu;
 }
+
+static struct arm_pmu *__init armv7_a7_pmu_init(void)
+{
+	armv7pmu.id		= ARM_PERF_PMU_ID_CA7;
+	armv7pmu.name		= "ARMv7 Cortex-A7";
+	armv7pmu.map_event	= armv7_a7_map_event;
+	armv7pmu.num_events	= armv7_read_num_pmnc_events();
+	armv7pmu.set_event_filter = armv7pmu_set_event_filter;
+	return &armv7pmu;
+}
 #else
 static struct arm_pmu *__init armv7_a8_pmu_init(void)
 {
@@ -1175,4 +1315,9 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
 {
 	return NULL;
 }
+
+static struct arm_pmu *__init armv7_a7_pmu_init(void)
+{
+	return NULL;
+}
 #endif	/* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 971d65c..1531480 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -61,8 +61,6 @@ extern void setup_mm_for_reboot(void);
 
 static volatile int hlt_counter;
 
-#include <mach/system.h>
-
 void disable_hlt(void)
 {
 	hlt_counter++;
@@ -181,13 +179,17 @@ void cpu_idle_wait(void)
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
 /*
- * This is our default idle handler.  We need to disable
- * interrupts here to ensure we don't miss a wakeup call.
+ * This is our default idle handler.
  */
+
+void (*arm_pm_idle)(void);
+
 static void default_idle(void)
 {
-	if (!need_resched())
-		arch_idle();
+	if (arm_pm_idle)
+		arm_pm_idle();
+	else
+		cpu_do_idle();
 	local_irq_enable();
 }
 
@@ -215,6 +217,10 @@ void cpu_idle(void)
 				cpu_die();
 #endif
 
+			/*
+			 * We need to disable interrupts here
+			 * to ensure we don't miss a wakeup call.
+			 */
 			local_irq_disable();
 #ifdef CONFIG_PL310_ERRATA_769419
 			wmb();
@@ -222,19 +228,18 @@ void cpu_idle(void)
 			if (hlt_counter) {
 				local_irq_enable();
 				cpu_relax();
-			} else {
+			} else if (!need_resched()) {
 				stop_critical_timings();
 				if (cpuidle_idle_call())
 					pm_idle();
 				start_critical_timings();
 				/*
-				 * This will eventually be removed - pm_idle
-				 * functions should always return with IRQs
-				 * enabled.
+				 * pm_idle functions must always
+				 * return with IRQs enabled.
 				 */
 				WARN_ON(irqs_disabled());
+			} else
 				local_irq_enable();
-			}
 		}
 		leds_event(led_idle_end);
 		rcu_idle_exit();
@@ -526,22 +531,40 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
 #ifdef CONFIG_MMU
 /*
  * The vectors page is always readable from user space for the
- * atomic helpers and the signal restart code.  Let's declare a mapping
- * for it so it is visible through ptrace and /proc/<pid>/mem.
+ * atomic helpers and the signal restart code. Insert it into the
+ * gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
  */
+static struct vm_area_struct gate_vma;
+
+static int __init gate_vma_init(void)
+{
+	gate_vma.vm_start	= 0xffff0000;
+	gate_vma.vm_end		= 0xffff0000 + PAGE_SIZE;
+	gate_vma.vm_page_prot	= PAGE_READONLY_EXEC;
+	gate_vma.vm_flags	= VM_READ | VM_EXEC |
+				  VM_MAYREAD | VM_MAYEXEC |
+				  VM_ALWAYSDUMP;
+	return 0;
+}
+arch_initcall(gate_vma_init);
+
+struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+{
+	return &gate_vma;
+}
+
+int in_gate_area(struct mm_struct *mm, unsigned long addr)
+{
+	return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end);
+}
 
-int vectors_user_mapping(void)
+int in_gate_area_no_mm(unsigned long addr)
 {
-	struct mm_struct *mm = current->mm;
-	return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
-				       VM_READ | VM_EXEC |
-				       VM_MAYREAD | VM_MAYEXEC |
-				       VM_ALWAYSDUMP | VM_RESERVED,
-				       NULL);
+	return in_gate_area(NULL, addr);
 }
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
-	return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
+	return (vma == &gate_vma) ? "[vectors]" : NULL;
 }
 #endif
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index e33870f..ede6443 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -23,6 +23,7 @@
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/regset.h>
+#include <linux/audit.h>
 
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -904,6 +905,12 @@ long arch_ptrace(struct task_struct *child, long request,
 	return ret;
 }
 
+#ifdef __ARMEB__
+#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB
+#else
+#define AUDIT_ARCH_NR AUDIT_ARCH_ARM
+#endif
+
 asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 {
 	unsigned long ip;
@@ -918,7 +925,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
 	if (!ip)
 		audit_syscall_exit(regs);
 	else
-		audit_syscall_entry(AUDIT_ARCH_ARMEB, scno, regs->ARM_r0,
+		audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0,
 				    regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
 
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 5416c7c..27d186a 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -10,6 +10,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/syscore_ops.h>
 #include <linux/timer.h>
 
 #include <asm/sched_clock.h>
@@ -164,3 +165,20 @@ void __init sched_clock_postinit(void)
 
 	sched_clock_poll(sched_clock_timer.data);
 }
+
+static int sched_clock_suspend(void)
+{
+	sched_clock_poll(sched_clock_timer.data);
+	return 0;
+}
+
+static struct syscore_ops sched_clock_ops = {
+	.suspend = sched_clock_suspend,
+};
+
+static int __init sched_clock_syscore_init(void)
+{
+	register_syscore_ops(&sched_clock_ops);
+	return 0;
+}
+device_initcall(sched_clock_syscore_init);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index a255c39..10303b3 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -33,6 +33,7 @@
 #include <linux/sort.h>
 
 #include <asm/unified.h>
+#include <asm/cp15.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/elf.h>
@@ -44,7 +45,6 @@
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/tlbflush.h>
-#include <asm/system.h>
 
 #include <asm/prom.h>
 #include <asm/mach/arch.h>
@@ -974,7 +974,6 @@ void __init setup_arch(char **cmdline_p)
 	conswitchp = &dummy_con;
 #endif
 #endif
-	early_trap_init();
 
 	if (mdesc->init_early)
 		mdesc->init_early();
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 9e617bd..7cb532f 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -66,12 +66,13 @@ const unsigned long syscall_restart_code[2] = {
  */
 asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -280,10 +281,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
 	if (err == 0) {
 		sigdelsetmask(&set, ~_BLOCKABLE);
-		spin_lock_irq(&current->sighand->siglock);
-		current->blocked = set;
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
+		set_current_blocked(&set);
 	}
 
 	__get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
@@ -636,13 +634,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
 	/*
 	 * Block the signal if we were successful.
 	 */
-	spin_lock_irq(&tsk->sighand->siglock);
-	sigorsets(&tsk->blocked, &tsk->blocked,
-		  &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&tsk->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&tsk->sighand->siglock);
+	block_sigmask(ka, sig);
 
 	return 0;
 }
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index cdeb727..3e43c5f 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -58,6 +58,8 @@ enum ipi_msg_type {
 	IPI_CPU_STOP,
 };
 
+static DECLARE_COMPLETION(cpu_running);
+
 int __cpuinit __cpu_up(unsigned int cpu)
 {
 	struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
@@ -98,20 +100,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
 	 */
 	ret = boot_secondary(cpu, idle);
 	if (ret == 0) {
-		unsigned long timeout;
-
 		/*
 		 * CPU was successfully started, wait for it
 		 * to come online or time out.
 		 */
-		timeout = jiffies + HZ;
-		while (time_before(jiffies, timeout)) {
-			if (cpu_online(cpu))
-				break;
-
-			udelay(10);
-			barrier();
-		}
+		wait_for_completion_timeout(&cpu_running,
+						 msecs_to_jiffies(1000));
 
 		if (!cpu_online(cpu)) {
 			pr_crit("CPU%u: failed to come online\n", cpu);
@@ -286,9 +280,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
 	/*
 	 * OK, now it's safe to let the boot CPU continue.  Wait for
 	 * the CPU migration code to notice that the CPU is online
-	 * before we continue.
+	 * before we continue - which happens after __cpu_up returns.
 	 */
 	set_cpu_online(cpu, true);
+	complete(&cpu_running);
 
 	/*
 	 * Setup the percpu timer for this CPU.
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
index 7dcb352..02c5d2c 100644
--- a/arch/arm/kernel/smp_tlb.c
+++ b/arch/arm/kernel/smp_tlb.c
@@ -13,18 +13,6 @@
 #include <asm/smp_plat.h>
 #include <asm/tlbflush.h>
 
-static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
-	const struct cpumask *mask)
-{
-	preempt_disable();
-
-	smp_call_function_many(mask, func, info, wait);
-	if (cpumask_test_cpu(smp_processor_id(), mask))
-		func(info);
-
-	preempt_enable();
-}
-
 /**********************************************************************/
 
 /*
@@ -87,7 +75,7 @@ void flush_tlb_all(void)
 void flush_tlb_mm(struct mm_struct *mm)
 {
 	if (tlb_ops_need_broadcast())
-		on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
+		on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1);
 	else
 		local_flush_tlb_mm(mm);
 }
@@ -98,7 +86,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 		struct tlb_args ta;
 		ta.ta_vma = vma;
 		ta.ta_start = uaddr;
-		on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
+		on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_page,
+					&ta, 1);
 	} else
 		local_flush_tlb_page(vma, uaddr);
 }
@@ -121,7 +110,8 @@ void flush_tlb_range(struct vm_area_struct *vma,
 		ta.ta_vma = vma;
 		ta.ta_start = start;
 		ta.ta_end = end;
-		on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
+		on_each_cpu_mask(mm_cpumask(vma->vm_mm), ipi_flush_tlb_range,
+					&ta, 1);
 	} else
 		local_flush_tlb_range(vma, start, end);
 }
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 4285daa..7a79b24 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -129,7 +129,7 @@ static struct notifier_block twd_cpufreq_nb = {
 
 static int twd_cpufreq_init(void)
 {
-	if (!IS_ERR(twd_clk))
+	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
 		return cpufreq_register_notifier(&twd_cpufreq_nb,
 			CPUFREQ_TRANSITION_NOTIFIER);
 
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 8c57dd3..fe31b22 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -25,8 +25,6 @@
 #include <linux/timer.h>
 #include <linux/irq.h>
 
-#include <linux/mc146818rtc.h>
-
 #include <asm/leds.h>
 #include <asm/thread_info.h>
 #include <asm/sched_clock.h>
@@ -149,8 +147,6 @@ void __init time_init(void)
 {
 	system_timer = machine_desc->timer;
 	system_timer->init();
-#ifdef CONFIG_HAVE_SCHED_CLOCK
 	sched_clock_postinit();
-#endif
 }
 
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index f84dfe6..6f417ec 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -227,6 +227,11 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
 #else
 #define S_SMP ""
 #endif
+#ifdef CONFIG_THUMB2_KERNEL
+#define S_ISA " THUMB2"
+#else
+#define S_ISA " ARM"
+#endif
 
 static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
 {
@@ -234,8 +239,8 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
 	static int die_counter;
 	int ret;
 
-	printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
-	       str, err, ++die_counter);
+	printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
+	       S_ISA "\n", str, err, ++die_counter);
 
 	/* trap and error numbers are mostly meaningless on ARM */
 	ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
@@ -784,18 +789,16 @@ static void __init kuser_get_tls_init(unsigned long vectors)
 		memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
 }
 
-void __init early_trap_init(void)
+void __init early_trap_init(void *vectors_base)
 {
-#if defined(CONFIG_CPU_USE_DOMAINS)
-	unsigned long vectors = CONFIG_VECTORS_BASE;
-#else
-	unsigned long vectors = (unsigned long)vectors_page;
-#endif
+	unsigned long vectors = (unsigned long)vectors_base;
 	extern char __stubs_start[], __stubs_end[];
 	extern char __vectors_start[], __vectors_end[];
 	extern char __kuser_helper_start[], __kuser_helper_end[];
 	int kuser_sz = __kuser_helper_end - __kuser_helper_start;
 
+	vectors_page = vectors_base;
+
 	/*
 	 * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
 	 * into the vector page, mapped at 0xffff0000, and ensure these
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 71feb00..e55cdcb 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -102,13 +102,13 @@ config ARCH_AT91SAM9G45
 	select HAVE_AT91_DBGU1
 	select AT91_SAM9G45_RESET
 
-config ARCH_AT91CAP9
-	bool "AT91CAP9"
+config ARCH_AT91SAM9X5
+	bool "AT91SAM9x5 family"
 	select CPU_ARM926T
 	select GENERIC_CLOCKEVENTS
 	select HAVE_FB_ATMEL
 	select HAVE_NET_MACB
-	select HAVE_AT91_DBGU1
+	select HAVE_AT91_DBGU0
 	select AT91_SAM9G45_RESET
 
 config ARCH_AT91X40
@@ -447,21 +447,6 @@ endif
 
 # ----------------------------------------------------------
 
-if ARCH_AT91CAP9
-
-comment "AT91CAP9 Board Type"
-
-config MACH_AT91CAP9ADK
-	bool "Atmel AT91CAP9A-DK Evaluation Kit"
-	select HAVE_AT91_DATAFLASH_CARD
-	help
-	  Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
-	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
-
-endif
-
-# ----------------------------------------------------------
-
 if ARCH_AT91X40
 
 comment "AT91X40 Board Type"
@@ -544,7 +529,7 @@ config AT91_EARLY_DBGU0
 	depends on HAVE_AT91_DBGU0
 
 config AT91_EARLY_DBGU1
-	bool "DBGU on 9263, 9g45 and cap9"
+	bool "DBGU on 9263 and 9g45"
 	depends on HAVE_AT91_DBGU1
 
 config AT91_EARLY_USART0
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 705e1fb..1b65185 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_d
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9X5)	+= at91sam9x5.o at91sam926x_time.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
 
 # AT91RM9200 board-specific support
@@ -81,9 +81,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
 # AT91SAM board with device-tree
 obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
 
-# AT91CAP9 board-specific support
-obj-$(CONFIG_MACH_AT91CAP9ADK)	+= board-cap9adk.o
-
 # AT91X40 board-specific support
 obj-$(CONFIG_MACH_AT91EB01)	+= board-eb01.o
 
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index 8ddafad..2fd051e 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -3,11 +3,7 @@
 #   PARAMS_PHYS must be within 4MB of ZRELADDR
 #   INITRD_PHYS must be in RAM
 
-ifeq ($(CONFIG_ARCH_AT91CAP9),y)
-   zreladdr-y	+= 0x70008000
-params_phys-y	:= 0x70000100
-initrd_phys-y	:= 0x70410000
-else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
+ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
    zreladdr-y	+= 0x70008000
 params_phys-y	:= 0x70000100
 initrd_phys-y	:= 0x70410000
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
deleted file mode 100644
index a42edc2..0000000
--- a/arch/arm/mach-at91/at91cap9.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * arch/arm/mach-at91/at91cap9.c
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/cpu.h>
-#include <mach/at91cap9.h>
-#include <mach/at91_pmc.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "clock.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- *  Clocks
- * -------------------------------------------------------------------- */
-
-/*
- * The peripheral clocks.
- */
-static struct clk pioABCD_clk = {
-	.name		= "pioABCD_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_PIOABCD,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb0_clk = {
-	.name		= "mpb0_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MPB0,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb1_clk = {
-	.name		= "mpb1_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MPB1,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb2_clk = {
-	.name		= "mpb2_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MPB2,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb3_clk = {
-	.name		= "mpb3_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MPB3,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb4_clk = {
-	.name		= "mpb4_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MPB4,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart0_clk = {
-	.name		= "usart0_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_US0,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart1_clk = {
-	.name		= "usart1_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_US1,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart2_clk = {
-	.name		= "usart2_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_US2,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc0_clk = {
-	.name		= "mci0_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MCI0,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc1_clk = {
-	.name		= "mci1_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_MCI1,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk can_clk = {
-	.name		= "can_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_CAN,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk twi_clk = {
-	.name		= "twi_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_TWI,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi0_clk = {
-	.name		= "spi0_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_SPI0,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi1_clk = {
-	.name		= "spi1_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_SPI1,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk ssc0_clk = {
-	.name		= "ssc0_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_SSC0,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk ssc1_clk = {
-	.name		= "ssc1_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_SSC1,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk ac97_clk = {
-	.name		= "ac97_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_AC97C,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk tcb_clk = {
-	.name		= "tcb_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_TCB,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk pwm_clk = {
-	.name		= "pwm_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_PWMC,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk macb_clk = {
-	.name		= "pclk",
-	.pmc_mask	= 1 << AT91CAP9_ID_EMAC,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk aestdes_clk = {
-	.name		= "aestdes_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_AESTDES,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk adc_clk = {
-	.name		= "adc_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_ADC,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk isi_clk = {
-	.name		= "isi_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_ISI,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk lcdc_clk = {
-	.name		= "lcdc_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_LCDC,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk dma_clk = {
-	.name		= "dma_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_DMA,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk udphs_clk = {
-	.name		= "udphs_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_UDPHS,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-static struct clk ohci_clk = {
-	.name		= "ohci_clk",
-	.pmc_mask	= 1 << AT91CAP9_ID_UHP,
-	.type		= CLK_TYPE_PERIPHERAL,
-};
-
-static struct clk *periph_clocks[] __initdata = {
-	&pioABCD_clk,
-	&mpb0_clk,
-	&mpb1_clk,
-	&mpb2_clk,
-	&mpb3_clk,
-	&mpb4_clk,
-	&usart0_clk,
-	&usart1_clk,
-	&usart2_clk,
-	&mmc0_clk,
-	&mmc1_clk,
-	&can_clk,
-	&twi_clk,
-	&spi0_clk,
-	&spi1_clk,
-	&ssc0_clk,
-	&ssc1_clk,
-	&ac97_clk,
-	&tcb_clk,
-	&pwm_clk,
-	&macb_clk,
-	&aestdes_clk,
-	&adc_clk,
-	&isi_clk,
-	&lcdc_clk,
-	&dma_clk,
-	&udphs_clk,
-	&ohci_clk,
-	// irq0 .. irq1
-};
-
-static struct clk_lookup periph_clocks_lookups[] = {
-	/* One additional fake clock for macb_hclk */
-	CLKDEV_CON_ID("hclk", &macb_clk),
-	CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
-	CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
-	CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
-	CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
-	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
-	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
-	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
-	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
-	/* fake hclk clock */
-	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
-	CLKDEV_CON_ID("pioA", &pioABCD_clk),
-	CLKDEV_CON_ID("pioB", &pioABCD_clk),
-	CLKDEV_CON_ID("pioC", &pioABCD_clk),
-	CLKDEV_CON_ID("pioD", &pioABCD_clk),
-};
-
-static struct clk_lookup usart_clocks_lookups[] = {
-	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
-	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
-	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
-	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
-};
-
-/*
- * The four programmable clocks.
- * You must configure pin multiplexing to bring these signals out.
- */
-static struct clk pck0 = {
-	.name		= "pck0",
-	.pmc_mask	= AT91_PMC_PCK0,
-	.type		= CLK_TYPE_PROGRAMMABLE,
-	.id		= 0,
-};
-static struct clk pck1 = {
-	.name		= "pck1",
-	.pmc_mask	= AT91_PMC_PCK1,
-	.type		= CLK_TYPE_PROGRAMMABLE,
-	.id		= 1,
-};
-static struct clk pck2 = {
-	.name		= "pck2",
-	.pmc_mask	= AT91_PMC_PCK2,
-	.type		= CLK_TYPE_PROGRAMMABLE,
-	.id		= 2,
-};
-static struct clk pck3 = {
-	.name		= "pck3",
-	.pmc_mask	= AT91_PMC_PCK3,
-	.type		= CLK_TYPE_PROGRAMMABLE,
-	.id		= 3,
-};
-
-static void __init at91cap9_register_clocks(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
-		clk_register(periph_clocks[i]);
-
-	clkdev_add_table(periph_clocks_lookups,
-			 ARRAY_SIZE(periph_clocks_lookups));
-	clkdev_add_table(usart_clocks_lookups,
-			 ARRAY_SIZE(usart_clocks_lookups));
-
-	clk_register(&pck0);
-	clk_register(&pck1);
-	clk_register(&pck2);
-	clk_register(&pck3);
-}
-
-static struct clk_lookup console_clock_lookup;
-
-void __init at91cap9_set_console_clock(int id)
-{
-	if (id >= ARRAY_SIZE(usart_clocks_lookups))
-		return;
-
-	console_clock_lookup.con_id = "usart";
-	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
-	clkdev_add(&console_clock_lookup);
-}
-
-/* --------------------------------------------------------------------
- *  GPIO
- * -------------------------------------------------------------------- */
-
-static struct at91_gpio_bank at91cap9_gpio[] __initdata = {
-	{
-		.id		= AT91CAP9_ID_PIOABCD,
-		.regbase	= AT91CAP9_BASE_PIOA,
-	}, {
-		.id		= AT91CAP9_ID_PIOABCD,
-		.regbase	= AT91CAP9_BASE_PIOB,
-	}, {
-		.id		= AT91CAP9_ID_PIOABCD,
-		.regbase	= AT91CAP9_BASE_PIOC,
-	}, {
-		.id		= AT91CAP9_ID_PIOABCD,
-		.regbase	= AT91CAP9_BASE_PIOD,
-	}
-};
-
-/* --------------------------------------------------------------------
- *  AT91CAP9 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91cap9_map_io(void)
-{
-	at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE);
-}
-
-static void __init at91cap9_ioremap_registers(void)
-{
-	at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC);
-	at91_ioremap_rstc(AT91CAP9_BASE_RSTC);
-	at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT);
-	at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC);
-}
-
-static void __init at91cap9_initialize(void)
-{
-	arm_pm_restart = at91sam9g45_restart;
-	at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
-
-	/* Register GPIO subsystem */
-	at91_gpio_init(at91cap9_gpio, 4);
-
-	/* Remember the silicon revision */
-	if (cpu_is_at91cap9_revB())
-		system_rev = 0xB;
-	else if (cpu_is_at91cap9_revC())
-		system_rev = 0xC;
-}
-
-/* --------------------------------------------------------------------
- *  Interrupt initialization
- * -------------------------------------------------------------------- */
-
-/*
- * The default interrupt priority levels (0 = lowest, 7 = highest).
- */
-static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
-	7,	/* Advanced Interrupt Controller (FIQ) */
-	7,	/* System Peripherals */
-	1,	/* Parallel IO Controller A, B, C and D */
-	0,	/* MP Block Peripheral 0 */
-	0,	/* MP Block Peripheral 1 */
-	0,	/* MP Block Peripheral 2 */
-	0,	/* MP Block Peripheral 3 */
-	0,	/* MP Block Peripheral 4 */
-	5,	/* USART 0 */
-	5,	/* USART 1 */
-	5,	/* USART 2 */
-	0,	/* Multimedia Card Interface 0 */
-	0,	/* Multimedia Card Interface 1 */
-	3,	/* CAN */
-	6,	/* Two-Wire Interface */
-	5,	/* Serial Peripheral Interface 0 */
-	5,	/* Serial Peripheral Interface 1 */
-	4,	/* Serial Synchronous Controller 0 */
-	4,	/* Serial Synchronous Controller 1 */
-	5,	/* AC97 Controller */
-	0,	/* Timer Counter 0, 1 and 2 */
-	0,	/* Pulse Width Modulation Controller */
-	3,	/* Ethernet */
-	0,	/* Advanced Encryption Standard, Triple DES*/
-	0,	/* Analog-to-Digital Converter */
-	0,	/* Image Sensor Interface */
-	3,	/* LCD Controller */
-	0,	/* DMA Controller */
-	2,	/* USB Device Port */
-	2,	/* USB Host port */
-	0,	/* Advanced Interrupt Controller (IRQ0) */
-	0,	/* Advanced Interrupt Controller (IRQ1) */
-};
-
-struct at91_init_soc __initdata at91cap9_soc = {
-	.map_io = at91cap9_map_io,
-	.default_irq_priority = at91cap9_default_irq_priority,
-	.ioremap_registers = at91cap9_ioremap_registers,
-	.register_clocks = at91cap9_register_clocks,
-	.init = at91cap9_initialize,
-};
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
deleted file mode 100644
index d298fb7..0000000
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * arch/arm/mach-at91/at91cap9_devices.c
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/i2c-gpio.h>
-
-#include <video/atmel_lcdc.h>
-
-#include <mach/board.h>
-#include <mach/cpu.h>
-#include <mach/at91cap9.h>
-#include <mach/at91cap9_matrix.h>
-#include <mach/at91sam9_smc.h>
-
-#include "generic.h"
-
-
-/* --------------------------------------------------------------------
- *  USB Host
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = DMA_BIT_MASK(32);
-static struct at91_usbh_data usbh_data;
-
-static struct resource usbh_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_UHP_BASE,
-		.end	= AT91CAP9_UHP_BASE + SZ_1M - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_UHP,
-		.end	= AT91CAP9_ID_UHP,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91_usbh_device = {
-	.name		= "at91_ohci",
-	.id		= -1,
-	.dev		= {
-				.dma_mask		= &ohci_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &usbh_data,
-	},
-	.resource	= usbh_resources,
-	.num_resources	= ARRAY_SIZE(usbh_resources),
-};
-
-void __init at91_add_device_usbh(struct at91_usbh_data *data)
-{
-	int i;
-
-	if (!data)
-		return;
-
-	if (cpu_is_at91cap9_revB())
-		irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
-
-	/* Enable VBus control for UHP ports */
-	for (i = 0; i < data->ports; i++) {
-		if (gpio_is_valid(data->vbus_pin[i]))
-			at91_set_gpio_output(data->vbus_pin[i], 0);
-	}
-
-	/* Enable overcurrent notification */
-	for (i = 0; i < data->ports; i++) {
-		if (data->overcurrent_pin[i])
-			at91_set_gpio_input(data->overcurrent_pin[i], 1);
-	}
-
-	usbh_data = *data;
-	platform_device_register(&at91_usbh_device);
-}
-#else
-void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  USB HS Device (Gadget)
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
-
-static struct resource usba_udc_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_UDPHS_FIFO,
-		.end	= AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_BASE_UDPHS,
-		.end	= AT91CAP9_BASE_UDPHS + SZ_1K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[2] = {
-		.start	= AT91CAP9_ID_UDPHS,
-		.end	= AT91CAP9_ID_UDPHS,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-#define EP(nam, idx, maxpkt, maxbk, dma, isoc)			\
-	[idx] = {						\
-		.name		= nam,				\
-		.index		= idx,				\
-		.fifo_size	= maxpkt,			\
-		.nr_banks	= maxbk,			\
-		.can_dma	= dma,				\
-		.can_isoc	= isoc,				\
-	}
-
-static struct usba_ep_data usba_udc_ep[] = {
-	EP("ep0", 0,   64, 1, 0, 0),
-	EP("ep1", 1, 1024, 3, 1, 1),
-	EP("ep2", 2, 1024, 3, 1, 1),
-	EP("ep3", 3, 1024, 2, 1, 1),
-	EP("ep4", 4, 1024, 2, 1, 1),
-	EP("ep5", 5, 1024, 2, 1, 0),
-	EP("ep6", 6, 1024, 2, 1, 0),
-	EP("ep7", 7, 1024, 2, 0, 0),
-};
-
-#undef EP
-
-/*
- * pdata doesn't have room for any endpoints, so we need to
- * append room for the ones we need right after it.
- */
-static struct {
-	struct usba_platform_data pdata;
-	struct usba_ep_data ep[8];
-} usba_udc_data;
-
-static struct platform_device at91_usba_udc_device = {
-	.name		= "atmel_usba_udc",
-	.id		= -1,
-	.dev		= {
-				.platform_data	= &usba_udc_data.pdata,
-	},
-	.resource	= usba_udc_resources,
-	.num_resources	= ARRAY_SIZE(usba_udc_resources),
-};
-
-void __init at91_add_device_usba(struct usba_platform_data *data)
-{
-	if (cpu_is_at91cap9_revB()) {
-		irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
-		at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
-						  AT91_MATRIX_UDPHS_BYPASS_LOCK);
-	}
-	else
-		at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);
-
-	/*
-	 * Invalid pins are 0 on AT91, but the usba driver is shared
-	 * with AVR32, which use negative values instead. Once/if
-	 * gpio_is_valid() is ported to AT91, revisit this code.
-	 */
-	usba_udc_data.pdata.vbus_pin = -EINVAL;
-	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
-	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
-
-	if (data && gpio_is_valid(data->vbus_pin)) {
-		at91_set_gpio_input(data->vbus_pin, 0);
-		at91_set_deglitch(data->vbus_pin, 1);
-		usba_udc_data.pdata.vbus_pin = data->vbus_pin;
-	}
-
-	/* Pullup pin is handled internally by USB device peripheral */
-
-	platform_device_register(&at91_usba_udc_device);
-}
-#else
-void __init at91_add_device_usba(struct usba_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  Ethernet
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
-static u64 eth_dmamask = DMA_BIT_MASK(32);
-static struct macb_platform_data eth_data;
-
-static struct resource eth_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_EMAC,
-		.end	= AT91CAP9_BASE_EMAC + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_EMAC,
-		.end	= AT91CAP9_ID_EMAC,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_eth_device = {
-	.name		= "macb",
-	.id		= -1,
-	.dev		= {
-				.dma_mask		= &eth_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &eth_data,
-	},
-	.resource	= eth_resources,
-	.num_resources	= ARRAY_SIZE(eth_resources),
-};
-
-void __init at91_add_device_eth(struct macb_platform_data *data)
-{
-	if (!data)
-		return;
-
-	if (gpio_is_valid(data->phy_irq_pin)) {
-		at91_set_gpio_input(data->phy_irq_pin, 0);
-		at91_set_deglitch(data->phy_irq_pin, 1);
-	}
-
-	/* Pins used for MII and RMII */
-	at91_set_A_periph(AT91_PIN_PB21, 0);	/* ETXCK_EREFCK */
-	at91_set_A_periph(AT91_PIN_PB22, 0);	/* ERXDV */
-	at91_set_A_periph(AT91_PIN_PB25, 0);	/* ERX0 */
-	at91_set_A_periph(AT91_PIN_PB26, 0);	/* ERX1 */
-	at91_set_A_periph(AT91_PIN_PB27, 0);	/* ERXER */
-	at91_set_A_periph(AT91_PIN_PB28, 0);	/* ETXEN */
-	at91_set_A_periph(AT91_PIN_PB23, 0);	/* ETX0 */
-	at91_set_A_periph(AT91_PIN_PB24, 0);	/* ETX1 */
-	at91_set_A_periph(AT91_PIN_PB30, 0);	/* EMDIO */
-	at91_set_A_periph(AT91_PIN_PB29, 0);	/* EMDC */
-
-	if (!data->is_rmii) {
-		at91_set_B_periph(AT91_PIN_PC25, 0);	/* ECRS */
-		at91_set_B_periph(AT91_PIN_PC26, 0);	/* ECOL */
-		at91_set_B_periph(AT91_PIN_PC22, 0);	/* ERX2 */
-		at91_set_B_periph(AT91_PIN_PC23, 0);	/* ERX3 */
-		at91_set_B_periph(AT91_PIN_PC27, 0);	/* ERXCK */
-		at91_set_B_periph(AT91_PIN_PC20, 0);	/* ETX2 */
-		at91_set_B_periph(AT91_PIN_PC21, 0);	/* ETX3 */
-		at91_set_B_periph(AT91_PIN_PC24, 0);	/* ETXER */
-	}
-
-	eth_data = *data;
-	platform_device_register(&at91cap9_eth_device);
-}
-#else
-void __init at91_add_device_eth(struct macb_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  MMC / SD
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = DMA_BIT_MASK(32);
-static struct at91_mmc_data mmc0_data, mmc1_data;
-
-static struct resource mmc0_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_MCI0,
-		.end	= AT91CAP9_BASE_MCI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_MCI0,
-		.end	= AT91CAP9_ID_MCI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_mmc0_device = {
-	.name		= "at91_mci",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &mmc0_data,
-	},
-	.resource	= mmc0_resources,
-	.num_resources	= ARRAY_SIZE(mmc0_resources),
-};
-
-static struct resource mmc1_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_MCI1,
-		.end	= AT91CAP9_BASE_MCI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_MCI1,
-		.end	= AT91CAP9_ID_MCI1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_mmc1_device = {
-	.name		= "at91_mci",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &mmc_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &mmc1_data,
-	},
-	.resource	= mmc1_resources,
-	.num_resources	= ARRAY_SIZE(mmc1_resources),
-};
-
-void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
-{
-	if (!data)
-		return;
-
-	/* input/irq */
-	if (gpio_is_valid(data->det_pin)) {
-		at91_set_gpio_input(data->det_pin, 1);
-		at91_set_deglitch(data->det_pin, 1);
-	}
-	if (gpio_is_valid(data->wp_pin))
-		at91_set_gpio_input(data->wp_pin, 1);
-	if (gpio_is_valid(data->vcc_pin))
-		at91_set_gpio_output(data->vcc_pin, 0);
-
-	if (mmc_id == 0) {		/* MCI0 */
-		/* CLK */
-		at91_set_A_periph(AT91_PIN_PA2, 0);
-
-		/* CMD */
-		at91_set_A_periph(AT91_PIN_PA1, 1);
-
-		/* DAT0, maybe DAT1..DAT3 */
-		at91_set_A_periph(AT91_PIN_PA0, 1);
-		if (data->wire4) {
-			at91_set_A_periph(AT91_PIN_PA3, 1);
-			at91_set_A_periph(AT91_PIN_PA4, 1);
-			at91_set_A_periph(AT91_PIN_PA5, 1);
-		}
-
-		mmc0_data = *data;
-		platform_device_register(&at91cap9_mmc0_device);
-	} else {			/* MCI1 */
-		/* CLK */
-		at91_set_A_periph(AT91_PIN_PA16, 0);
-
-		/* CMD */
-		at91_set_A_periph(AT91_PIN_PA17, 1);
-
-		/* DAT0, maybe DAT1..DAT3 */
-		at91_set_A_periph(AT91_PIN_PA18, 1);
-		if (data->wire4) {
-			at91_set_A_periph(AT91_PIN_PA19, 1);
-			at91_set_A_periph(AT91_PIN_PA20, 1);
-			at91_set_A_periph(AT91_PIN_PA21, 1);
-		}
-
-		mmc1_data = *data;
-		platform_device_register(&at91cap9_mmc1_device);
-	}
-}
-#else
-void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  NAND / SmartMedia
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
-static struct atmel_nand_data nand_data;
-
-#define NAND_BASE	AT91_CHIPSELECT_3
-
-static struct resource nand_resources[] = {
-	[0] = {
-		.start	= NAND_BASE,
-		.end	= NAND_BASE + SZ_256M - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_BASE_ECC,
-		.end	= AT91CAP9_BASE_ECC + SZ_512 - 1,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device at91cap9_nand_device = {
-	.name		= "atmel_nand",
-	.id		= -1,
-	.dev		= {
-				.platform_data	= &nand_data,
-	},
-	.resource	= nand_resources,
-	.num_resources	= ARRAY_SIZE(nand_resources),
-};
-
-void __init at91_add_device_nand(struct atmel_nand_data *data)
-{
-	unsigned long csa;
-
-	if (!data)
-		return;
-
-	csa = at91_sys_read(AT91_MATRIX_EBICSA);
-	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
-
-	/* enable pin */
-	if (gpio_is_valid(data->enable_pin))
-		at91_set_gpio_output(data->enable_pin, 1);
-
-	/* ready/busy pin */
-	if (gpio_is_valid(data->rdy_pin))
-		at91_set_gpio_input(data->rdy_pin, 1);
-
-	/* card detect pin */
-	if (gpio_is_valid(data->det_pin))
-		at91_set_gpio_input(data->det_pin, 1);
-
-	nand_data = *data;
-	platform_device_register(&at91cap9_nand_device);
-}
-#else
-void __init at91_add_device_nand(struct atmel_nand_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  TWI (i2c)
- * -------------------------------------------------------------------- */
-
-/*
- * Prefer the GPIO code since the TWI controller isn't robust
- * (gets overruns and underruns under load) and can only issue
- * repeated STARTs in one scenario (the driver doesn't yet handle them).
- */
-#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
-
-static struct i2c_gpio_platform_data pdata = {
-	.sda_pin		= AT91_PIN_PB4,
-	.sda_is_open_drain	= 1,
-	.scl_pin		= AT91_PIN_PB5,
-	.scl_is_open_drain	= 1,
-	.udelay			= 2,		/* ~100 kHz */
-};
-
-static struct platform_device at91cap9_twi_device = {
-	.name			= "i2c-gpio",
-	.id			= -1,
-	.dev.platform_data	= &pdata,
-};
-
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
-{
-	at91_set_GPIO_periph(AT91_PIN_PB4, 1);		/* TWD (SDA) */
-	at91_set_multi_drive(AT91_PIN_PB4, 1);
-
-	at91_set_GPIO_periph(AT91_PIN_PB5, 1);		/* TWCK (SCL) */
-	at91_set_multi_drive(AT91_PIN_PB5, 1);
-
-	i2c_register_board_info(0, devices, nr_devices);
-	platform_device_register(&at91cap9_twi_device);
-}
-
-#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
-
-static struct resource twi_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_TWI,
-		.end	= AT91CAP9_BASE_TWI + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_TWI,
-		.end	= AT91CAP9_ID_TWI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_twi_device = {
-	.name		= "at91_i2c",
-	.id		= -1,
-	.resource	= twi_resources,
-	.num_resources	= ARRAY_SIZE(twi_resources),
-};
-
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
-{
-	/* pins used for TWI interface */
-	at91_set_B_periph(AT91_PIN_PB4, 0);		/* TWD */
-	at91_set_multi_drive(AT91_PIN_PB4, 1);
-
-	at91_set_B_periph(AT91_PIN_PB5, 0);		/* TWCK */
-	at91_set_multi_drive(AT91_PIN_PB5, 1);
-
-	i2c_register_board_info(0, devices, nr_devices);
-	platform_device_register(&at91cap9_twi_device);
-}
-#else
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
-#endif
-
-/* --------------------------------------------------------------------
- *  SPI
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_SPI0,
-		.end	= AT91CAP9_BASE_SPI0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_SPI0,
-		.end	= AT91CAP9_ID_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_spi0_device = {
-	.name		= "atmel_spi",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi0_resources,
-	.num_resources	= ARRAY_SIZE(spi0_resources),
-};
-
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
-
-static struct resource spi1_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_SPI1,
-		.end	= AT91CAP9_BASE_SPI1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_SPI1,
-		.end	= AT91CAP9_ID_SPI1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_spi1_device = {
-	.name		= "atmel_spi",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &spi_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= spi1_resources,
-	.num_resources	= ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
-	int i;
-	unsigned long cs_pin;
-	short enable_spi0 = 0;
-	short enable_spi1 = 0;
-
-	/* Choose SPI chip-selects */
-	for (i = 0; i < nr_devices; i++) {
-		if (devices[i].controller_data)
-			cs_pin = (unsigned long) devices[i].controller_data;
-		else if (devices[i].bus_num == 0)
-			cs_pin = spi0_standard_cs[devices[i].chip_select];
-		else
-			cs_pin = spi1_standard_cs[devices[i].chip_select];
-
-		if (devices[i].bus_num == 0)
-			enable_spi0 = 1;
-		else
-			enable_spi1 = 1;
-
-		/* enable chip-select pin */
-		at91_set_gpio_output(cs_pin, 1);
-
-		/* pass chip-select pin to driver */
-		devices[i].controller_data = (void *) cs_pin;
-	}
-
-	spi_register_board_info(devices, nr_devices);
-
-	/* Configure SPI bus(es) */
-	if (enable_spi0) {
-		at91_set_B_periph(AT91_PIN_PA0, 0);	/* SPI0_MISO */
-		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
-		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
-
-		platform_device_register(&at91cap9_spi0_device);
-	}
-	if (enable_spi1) {
-		at91_set_A_periph(AT91_PIN_PB12, 0);	/* SPI1_MISO */
-		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
-		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
-
-		platform_device_register(&at91cap9_spi1_device);
-	}
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  Timer/Counter block
- * -------------------------------------------------------------------- */
-
-#ifdef CONFIG_ATMEL_TCLIB
-
-static struct resource tcb_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_TCB0,
-		.end	= AT91CAP9_BASE_TCB0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_TCB,
-		.end	= AT91CAP9_ID_TCB,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_tcb_device = {
-	.name		= "atmel_tcb",
-	.id		= 0,
-	.resource	= tcb_resources,
-	.num_resources	= ARRAY_SIZE(tcb_resources),
-};
-
-static void __init at91_add_device_tc(void)
-{
-	platform_device_register(&at91cap9_tcb_device);
-}
-#else
-static void __init at91_add_device_tc(void) { }
-#endif
-
-
-/* --------------------------------------------------------------------
- *  RTT
- * -------------------------------------------------------------------- */
-
-static struct resource rtt_resources[] = {
-	{
-		.start	= AT91CAP9_BASE_RTT,
-		.end	= AT91CAP9_BASE_RTT + SZ_16 - 1,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device at91cap9_rtt_device = {
-	.name		= "at91_rtt",
-	.id		= 0,
-	.resource	= rtt_resources,
-	.num_resources	= ARRAY_SIZE(rtt_resources),
-};
-
-static void __init at91_add_device_rtt(void)
-{
-	platform_device_register(&at91cap9_rtt_device);
-}
-
-
-/* --------------------------------------------------------------------
- *  Watchdog
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
-static struct resource wdt_resources[] = {
-	{
-		.start	= AT91CAP9_BASE_WDT,
-		.end	= AT91CAP9_BASE_WDT + SZ_16 - 1,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device at91cap9_wdt_device = {
-	.name		= "at91_wdt",
-	.id		= -1,
-	.resource	= wdt_resources,
-	.num_resources	= ARRAY_SIZE(wdt_resources),
-};
-
-static void __init at91_add_device_watchdog(void)
-{
-	platform_device_register(&at91cap9_wdt_device);
-}
-#else
-static void __init at91_add_device_watchdog(void) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  PWM
- * --------------------------------------------------------------------*/
-
-#if defined(CONFIG_ATMEL_PWM)
-static u32 pwm_mask;
-
-static struct resource pwm_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_PWMC,
-		.end	= AT91CAP9_BASE_PWMC + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_PWMC,
-		.end	= AT91CAP9_ID_PWMC,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_pwm0_device = {
-	.name	= "atmel_pwm",
-	.id	= -1,
-	.dev	= {
-		.platform_data		= &pwm_mask,
-	},
-	.resource	= pwm_resources,
-	.num_resources	= ARRAY_SIZE(pwm_resources),
-};
-
-void __init at91_add_device_pwm(u32 mask)
-{
-	if (mask & (1 << AT91_PWM0))
-		at91_set_A_periph(AT91_PIN_PB19, 1);	/* enable PWM0 */
-
-	if (mask & (1 << AT91_PWM1))
-		at91_set_B_periph(AT91_PIN_PB8, 1);	/* enable PWM1 */
-
-	if (mask & (1 << AT91_PWM2))
-		at91_set_B_periph(AT91_PIN_PC29, 1);	/* enable PWM2 */
-
-	if (mask & (1 << AT91_PWM3))
-		at91_set_B_periph(AT91_PIN_PA11, 1);	/* enable PWM3 */
-
-	pwm_mask = mask;
-
-	platform_device_register(&at91cap9_pwm0_device);
-}
-#else
-void __init at91_add_device_pwm(u32 mask) {}
-#endif
-
-
-
-/* --------------------------------------------------------------------
- *  AC97
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
-static u64 ac97_dmamask = DMA_BIT_MASK(32);
-static struct ac97c_platform_data ac97_data;
-
-static struct resource ac97_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_AC97C,
-		.end	= AT91CAP9_BASE_AC97C + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_AC97C,
-		.end	= AT91CAP9_ID_AC97C,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_ac97_device = {
-	.name		= "atmel_ac97c",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &ac97_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &ac97_data,
-	},
-	.resource	= ac97_resources,
-	.num_resources	= ARRAY_SIZE(ac97_resources),
-};
-
-void __init at91_add_device_ac97(struct ac97c_platform_data *data)
-{
-	if (!data)
-		return;
-
-	at91_set_A_periph(AT91_PIN_PA6, 0);	/* AC97FS */
-	at91_set_A_periph(AT91_PIN_PA7, 0);	/* AC97CK */
-	at91_set_A_periph(AT91_PIN_PA8, 0);	/* AC97TX */
-	at91_set_A_periph(AT91_PIN_PA9, 0);	/* AC97RX */
-
-	/* reset */
-	if (gpio_is_valid(data->reset_pin))
-		at91_set_gpio_output(data->reset_pin, 0);
-
-	ac97_data = *data;
-	platform_device_register(&at91cap9_ac97_device);
-}
-#else
-void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  LCD Controller
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static u64 lcdc_dmamask = DMA_BIT_MASK(32);
-static struct atmel_lcdfb_info lcdc_data;
-
-static struct resource lcdc_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_LCDC_BASE,
-		.end	= AT91CAP9_LCDC_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_LCDC,
-		.end	= AT91CAP9_ID_LCDC,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91_lcdc_device = {
-	.name		= "atmel_lcdfb",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &lcdc_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &lcdc_data,
-	},
-	.resource	= lcdc_resources,
-	.num_resources	= ARRAY_SIZE(lcdc_resources),
-};
-
-void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
-{
-	if (!data)
-		return;
-
-	if (cpu_is_at91cap9_revB())
-		irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
-
-	at91_set_A_periph(AT91_PIN_PC1, 0);	/* LCDHSYNC */
-	at91_set_A_periph(AT91_PIN_PC2, 0);	/* LCDDOTCK */
-	at91_set_A_periph(AT91_PIN_PC3, 0);	/* LCDDEN */
-	at91_set_B_periph(AT91_PIN_PB9, 0);	/* LCDCC */
-	at91_set_A_periph(AT91_PIN_PC6, 0);	/* LCDD2 */
-	at91_set_A_periph(AT91_PIN_PC7, 0);	/* LCDD3 */
-	at91_set_A_periph(AT91_PIN_PC8, 0);	/* LCDD4 */
-	at91_set_A_periph(AT91_PIN_PC9, 0);	/* LCDD5 */
-	at91_set_A_periph(AT91_PIN_PC10, 0);	/* LCDD6 */
-	at91_set_A_periph(AT91_PIN_PC11, 0);	/* LCDD7 */
-	at91_set_A_periph(AT91_PIN_PC14, 0);	/* LCDD10 */
-	at91_set_A_periph(AT91_PIN_PC15, 0);	/* LCDD11 */
-	at91_set_A_periph(AT91_PIN_PC16, 0);	/* LCDD12 */
-	at91_set_A_periph(AT91_PIN_PC17, 0);	/* LCDD13 */
-	at91_set_A_periph(AT91_PIN_PC18, 0);	/* LCDD14 */
-	at91_set_A_periph(AT91_PIN_PC19, 0);	/* LCDD15 */
-	at91_set_A_periph(AT91_PIN_PC22, 0);	/* LCDD18 */
-	at91_set_A_periph(AT91_PIN_PC23, 0);	/* LCDD19 */
-	at91_set_A_periph(AT91_PIN_PC24, 0);	/* LCDD20 */
-	at91_set_A_periph(AT91_PIN_PC25, 0);	/* LCDD21 */
-	at91_set_A_periph(AT91_PIN_PC26, 0);	/* LCDD22 */
-	at91_set_A_periph(AT91_PIN_PC27, 0);	/* LCDD23 */
-
-	lcdc_data = *data;
-	platform_device_register(&at91_lcdc_device);
-}
-#else
-void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  SSC -- Synchronous Serial Controller
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
-static u64 ssc0_dmamask = DMA_BIT_MASK(32);
-
-static struct resource ssc0_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_SSC0,
-		.end	= AT91CAP9_BASE_SSC0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_SSC0,
-		.end	= AT91CAP9_ID_SSC0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_ssc0_device = {
-	.name	= "ssc",
-	.id	= 0,
-	.dev	= {
-		.dma_mask		= &ssc0_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= ssc0_resources,
-	.num_resources	= ARRAY_SIZE(ssc0_resources),
-};
-
-static inline void configure_ssc0_pins(unsigned pins)
-{
-	if (pins & ATMEL_SSC_TF)
-		at91_set_A_periph(AT91_PIN_PB0, 1);
-	if (pins & ATMEL_SSC_TK)
-		at91_set_A_periph(AT91_PIN_PB1, 1);
-	if (pins & ATMEL_SSC_TD)
-		at91_set_A_periph(AT91_PIN_PB2, 1);
-	if (pins & ATMEL_SSC_RD)
-		at91_set_A_periph(AT91_PIN_PB3, 1);
-	if (pins & ATMEL_SSC_RK)
-		at91_set_A_periph(AT91_PIN_PB4, 1);
-	if (pins & ATMEL_SSC_RF)
-		at91_set_A_periph(AT91_PIN_PB5, 1);
-}
-
-static u64 ssc1_dmamask = DMA_BIT_MASK(32);
-
-static struct resource ssc1_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_SSC1,
-		.end	= AT91CAP9_BASE_SSC1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_SSC1,
-		.end	= AT91CAP9_ID_SSC1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device at91cap9_ssc1_device = {
-	.name	= "ssc",
-	.id	= 1,
-	.dev	= {
-		.dma_mask		= &ssc1_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= ssc1_resources,
-	.num_resources	= ARRAY_SIZE(ssc1_resources),
-};
-
-static inline void configure_ssc1_pins(unsigned pins)
-{
-	if (pins & ATMEL_SSC_TF)
-		at91_set_A_periph(AT91_PIN_PB6, 1);
-	if (pins & ATMEL_SSC_TK)
-		at91_set_A_periph(AT91_PIN_PB7, 1);
-	if (pins & ATMEL_SSC_TD)
-		at91_set_A_periph(AT91_PIN_PB8, 1);
-	if (pins & ATMEL_SSC_RD)
-		at91_set_A_periph(AT91_PIN_PB9, 1);
-	if (pins & ATMEL_SSC_RK)
-		at91_set_A_periph(AT91_PIN_PB10, 1);
-	if (pins & ATMEL_SSC_RF)
-		at91_set_A_periph(AT91_PIN_PB11, 1);
-}
-
-/*
- * SSC controllers are accessed through library code, instead of any
- * kind of all-singing/all-dancing driver.  For example one could be
- * used by a particular I2S audio codec's driver, while another one
- * on the same system might be used by a custom data capture driver.
- */
-void __init at91_add_device_ssc(unsigned id, unsigned pins)
-{
-	struct platform_device *pdev;
-
-	/*
-	 * NOTE: caller is responsible for passing information matching
-	 * "pins" to whatever will be using each particular controller.
-	 */
-	switch (id) {
-	case AT91CAP9_ID_SSC0:
-		pdev = &at91cap9_ssc0_device;
-		configure_ssc0_pins(pins);
-		break;
-	case AT91CAP9_ID_SSC1:
-		pdev = &at91cap9_ssc1_device;
-		configure_ssc1_pins(pins);
-		break;
-	default:
-		return;
-	}
-
-	platform_device_register(pdev);
-}
-
-#else
-void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- *  UART
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SERIAL_ATMEL)
-static struct resource dbgu_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_DBGU,
-		.end	= AT91CAP9_BASE_DBGU + SZ_512 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91_ID_SYS,
-		.end	= AT91_ID_SYS,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct atmel_uart_data dbgu_data = {
-	.use_dma_tx	= 0,
-	.use_dma_rx	= 0,		/* DBGU not capable of receive DMA */
-};
-
-static u64 dbgu_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_dbgu_device = {
-	.name		= "atmel_usart",
-	.id		= 0,
-	.dev		= {
-				.dma_mask		= &dbgu_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &dbgu_data,
-	},
-	.resource	= dbgu_resources,
-	.num_resources	= ARRAY_SIZE(dbgu_resources),
-};
-
-static inline void configure_dbgu_pins(void)
-{
-	at91_set_A_periph(AT91_PIN_PC30, 0);		/* DRXD */
-	at91_set_A_periph(AT91_PIN_PC31, 1);		/* DTXD */
-}
-
-static struct resource uart0_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_US0,
-		.end	= AT91CAP9_BASE_US0 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_US0,
-		.end	= AT91CAP9_ID_US0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct atmel_uart_data uart0_data = {
-	.use_dma_tx	= 1,
-	.use_dma_rx	= 1,
-};
-
-static u64 uart0_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart0_device = {
-	.name		= "atmel_usart",
-	.id		= 1,
-	.dev		= {
-				.dma_mask		= &uart0_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &uart0_data,
-	},
-	.resource	= uart0_resources,
-	.num_resources	= ARRAY_SIZE(uart0_resources),
-};
-
-static inline void configure_usart0_pins(unsigned pins)
-{
-	at91_set_A_periph(AT91_PIN_PA22, 1);		/* TXD0 */
-	at91_set_A_periph(AT91_PIN_PA23, 0);		/* RXD0 */
-
-	if (pins & ATMEL_UART_RTS)
-		at91_set_A_periph(AT91_PIN_PA24, 0);	/* RTS0 */
-	if (pins & ATMEL_UART_CTS)
-		at91_set_A_periph(AT91_PIN_PA25, 0);	/* CTS0 */
-}
-
-static struct resource uart1_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_US1,
-		.end	= AT91CAP9_BASE_US1 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_US1,
-		.end	= AT91CAP9_ID_US1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct atmel_uart_data uart1_data = {
-	.use_dma_tx	= 1,
-	.use_dma_rx	= 1,
-};
-
-static u64 uart1_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart1_device = {
-	.name		= "atmel_usart",
-	.id		= 2,
-	.dev		= {
-				.dma_mask		= &uart1_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &uart1_data,
-	},
-	.resource	= uart1_resources,
-	.num_resources	= ARRAY_SIZE(uart1_resources),
-};
-
-static inline void configure_usart1_pins(unsigned pins)
-{
-	at91_set_A_periph(AT91_PIN_PD0, 1);		/* TXD1 */
-	at91_set_A_periph(AT91_PIN_PD1, 0);		/* RXD1 */
-
-	if (pins & ATMEL_UART_RTS)
-		at91_set_B_periph(AT91_PIN_PD7, 0);	/* RTS1 */
-	if (pins & ATMEL_UART_CTS)
-		at91_set_B_periph(AT91_PIN_PD8, 0);	/* CTS1 */
-}
-
-static struct resource uart2_resources[] = {
-	[0] = {
-		.start	= AT91CAP9_BASE_US2,
-		.end	= AT91CAP9_BASE_US2 + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= AT91CAP9_ID_US2,
-		.end	= AT91CAP9_ID_US2,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct atmel_uart_data uart2_data = {
-	.use_dma_tx	= 1,
-	.use_dma_rx	= 1,
-};
-
-static u64 uart2_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart2_device = {
-	.name		= "atmel_usart",
-	.id		= 3,
-	.dev		= {
-				.dma_mask		= &uart2_dmamask,
-				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &uart2_data,
-	},
-	.resource	= uart2_resources,
-	.num_resources	= ARRAY_SIZE(uart2_resources),
-};
-
-static inline void configure_usart2_pins(unsigned pins)
-{
-	at91_set_A_periph(AT91_PIN_PD2, 1);		/* TXD2 */
-	at91_set_A_periph(AT91_PIN_PD3, 0);		/* RXD2 */
-
-	if (pins & ATMEL_UART_RTS)
-		at91_set_B_periph(AT91_PIN_PD5, 0);	/* RTS2 */
-	if (pins & ATMEL_UART_CTS)
-		at91_set_B_periph(AT91_PIN_PD6, 0);	/* CTS2 */
-}
-
-static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
-struct platform_device *atmel_default_console_device;	/* the serial console device */
-
-void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
-{
-	struct platform_device *pdev;
-	struct atmel_uart_data *pdata;
-
-	switch (id) {
-		case 0:		/* DBGU */
-			pdev = &at91cap9_dbgu_device;
-			configure_dbgu_pins();
-			break;
-		case AT91CAP9_ID_US0:
-			pdev = &at91cap9_uart0_device;
-			configure_usart0_pins(pins);
-			break;
-		case AT91CAP9_ID_US1:
-			pdev = &at91cap9_uart1_device;
-			configure_usart1_pins(pins);
-			break;
-		case AT91CAP9_ID_US2:
-			pdev = &at91cap9_uart2_device;
-			configure_usart2_pins(pins);
-			break;
-		default:
-			return;
-	}
-	pdata = pdev->dev.platform_data;
-	pdata->num = portnr;		/* update to mapped ID */
-
-	if (portnr < ATMEL_MAX_UART)
-		at91_uarts[portnr] = pdev;
-}
-
-void __init at91_set_serial_console(unsigned portnr)
-{
-	if (portnr < ATMEL_MAX_UART) {
-		atmel_default_console_device = at91_uarts[portnr];
-		at91cap9_set_console_clock(at91_uarts[portnr]->id);
-	}
-}
-
-void __init at91_add_device_serial(void)
-{
-	int i;
-
-	for (i = 0; i < ATMEL_MAX_UART; i++) {
-		if (at91_uarts[i])
-			platform_device_register(at91_uarts[i]);
-	}
-
-	if (!atmel_default_console_device)
-		printk(KERN_INFO "AT91: No default serial console defined.\n");
-}
-#else
-void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
-void __init at91_set_serial_console(unsigned portnr) {}
-void __init at91_add_device_serial(void) {}
-#endif
-
-
-/* -------------------------------------------------------------------- */
-/*
- * These devices are always present and don't need any board-specific
- * setup.
- */
-static int __init at91_add_standard_devices(void)
-{
-	at91_add_device_rtt();
-	at91_add_device_watchdog();
-	at91_add_device_tc();
-	return 0;
-}
-
-arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 99c3174..dd6e2de 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -289,6 +289,15 @@ static struct at91_gpio_bank at91rm9200_gpio[] __initdata = {
 	}
 };
 
+static void at91rm9200_idle(void)
+{
+	/*
+	 * Disable the processor clock.  The processor will be automatically
+	 * re-enabled by an interrupt or by a reset.
+	 */
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+}
+
 static void at91rm9200_restart(char mode, const char *cmd)
 {
 	/*
@@ -314,6 +323,7 @@ static void __init at91rm9200_ioremap_registers(void)
 
 static void __init at91rm9200_initialize(void)
 {
+	arm_pm_idle = at91rm9200_idle;
 	arm_pm_restart = at91rm9200_restart;
 	at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
 			| (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index d4036ba..9ac8c6f 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 
+#include <asm/proc-fns.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -328,8 +329,15 @@ static void __init at91sam9260_ioremap_registers(void)
 	at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
 }
 
+static void at91sam9260_idle(void)
+{
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+	cpu_do_idle();
+}
+
 static void __init at91sam9260_initialize(void)
 {
+	arm_pm_idle = at91sam9260_idle;
 	arm_pm_restart = at91sam9_alt_restart;
 	at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
 			| (1 << AT91SAM9260_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 023c2ff..ab76868 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 
+#include <asm/proc-fns.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -286,8 +287,15 @@ static void __init at91sam9261_ioremap_registers(void)
 	at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
 }
 
+static void at91sam9261_idle(void)
+{
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+	cpu_do_idle();
+}
+
 static void __init at91sam9261_initialize(void)
 {
+	arm_pm_idle = at91sam9261_idle;
 	arm_pm_restart = at91sam9_alt_restart;
 	at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
 			| (1 << AT91SAM9261_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 75e876c..247ab63 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 
+#include <asm/proc-fns.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -307,8 +308,15 @@ static void __init at91sam9263_ioremap_registers(void)
 	at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
 }
 
+static void at91sam9263_idle(void)
+{
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+	cpu_do_idle();
+}
+
 static void __init at91sam9263_initialize(void)
 {
+	arm_pm_idle = at91sam9263_idle;
 	arm_pm_restart = at91sam9_alt_restart;
 	at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
 
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 366a776..70709ab 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -891,7 +891,8 @@ static struct platform_device at91sam9263_isi_device = {
 	.num_resources	= ARRAY_SIZE(isi_resources),
 };
 
-void __init at91_add_device_isi(void)
+void __init at91_add_device_isi(struct isi_platform_data *data,
+		bool use_pck_as_mck)
 {
 	at91_set_A_periph(AT91_PIN_PE0, 0);	/* ISI_D0 */
 	at91_set_A_periph(AT91_PIN_PE1, 0);	/* ISI_D1 */
@@ -904,14 +905,20 @@ void __init at91_add_device_isi(void)
 	at91_set_A_periph(AT91_PIN_PE8, 0);	/* ISI_PCK */
 	at91_set_A_periph(AT91_PIN_PE9, 0);	/* ISI_HSYNC */
 	at91_set_A_periph(AT91_PIN_PE10, 0);	/* ISI_VSYNC */
-	at91_set_B_periph(AT91_PIN_PE11, 0);	/* ISI_MCK (PCK3) */
 	at91_set_B_periph(AT91_PIN_PE12, 0);	/* ISI_PD8 */
 	at91_set_B_periph(AT91_PIN_PE13, 0);	/* ISI_PD9 */
 	at91_set_B_periph(AT91_PIN_PE14, 0);	/* ISI_PD10 */
 	at91_set_B_periph(AT91_PIN_PE15, 0);	/* ISI_PD11 */
+
+	if (use_pck_as_mck) {
+		at91_set_B_periph(AT91_PIN_PE11, 0);	/* ISI_MCK (PCK3) */
+
+		/* TODO: register the PCK for ISI_MCK and set its parent */
+	}
 }
 #else
-void __init at91_add_device_isi(void) {}
+void __init at91_add_device_isi(struct isi_platform_data *data,
+		bool use_pck_as_mck) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 1cb6a96..5b12192 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -317,6 +317,12 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = {
 	}
 };
 
+static void at91sam9g45_idle(void)
+{
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+	cpu_do_idle();
+}
+
 /* --------------------------------------------------------------------
  *  AT91SAM9G45 processor initialization
  * -------------------------------------------------------------------- */
@@ -337,6 +343,7 @@ static void __init at91sam9g45_ioremap_registers(void)
 
 static void __init at91sam9g45_initialize(void)
 {
+	arm_pm_idle = at91sam9g45_idle;
 	arm_pm_restart = at91sam9g45_restart;
 	at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
 
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index b7582dd..bd4e68c 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -14,6 +14,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/gpio.h>
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-gpio.h>
 #include <linux/atmel-mci.h>
@@ -28,7 +29,10 @@
 #include <mach/at_hdmac.h>
 #include <mach/atmel-mci.h>
 
+#include <media/atmel-isi.h>
+
 #include "generic.h"
+#include "clock.h"
 
 
 /* --------------------------------------------------------------------
@@ -38,10 +42,6 @@
 #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
 static u64 hdmac_dmamask = DMA_BIT_MASK(32);
 
-static struct at_dma_platform_data atdma_pdata = {
-	.nr_channels	= 8,
-};
-
 static struct resource hdmac_resources[] = {
 	[0] = {
 		.start	= AT91SAM9G45_BASE_DMA,
@@ -56,12 +56,11 @@ static struct resource hdmac_resources[] = {
 };
 
 static struct platform_device at_hdmac_device = {
-	.name		= "at_hdmac",
+	.name		= "at91sam9g45_dma",
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &hdmac_dmamask,
 				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &atdma_pdata,
 	},
 	.resource	= hdmac_resources,
 	.num_resources	= ARRAY_SIZE(hdmac_resources),
@@ -69,9 +68,15 @@ static struct platform_device at_hdmac_device = {
 
 void __init at91_add_device_hdmac(void)
 {
-	dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
-	dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
-	platform_device_register(&at_hdmac_device);
+#if defined(CONFIG_OF)
+	struct device_node *of_node =
+		of_find_node_by_name(NULL, "dma-controller");
+
+	if (of_node)
+		of_node_put(of_node);
+	else
+#endif
+		platform_device_register(&at_hdmac_device);
 }
 #else
 void __init at91_add_device_hdmac(void) {}
@@ -869,6 +874,96 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
 void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  Image Sensor Interface
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
+static u64 isi_dmamask = DMA_BIT_MASK(32);
+static struct isi_platform_data isi_data;
+
+struct resource isi_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_ISI,
+		.end	= AT91SAM9G45_BASE_ISI + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_ISI,
+		.end	= AT91SAM9G45_ID_ISI,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_isi_device = {
+	.name		= "atmel_isi",
+	.id		= 0,
+	.dev		= {
+			.dma_mask		= &isi_dmamask,
+			.coherent_dma_mask	= DMA_BIT_MASK(32),
+			.platform_data		= &isi_data,
+	},
+	.resource	= isi_resources,
+	.num_resources	= ARRAY_SIZE(isi_resources),
+};
+
+static struct clk_lookup isi_mck_lookups[] = {
+	CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL),
+};
+
+void __init at91_add_device_isi(struct isi_platform_data *data,
+		bool use_pck_as_mck)
+{
+	struct clk *pck;
+	struct clk *parent;
+
+	if (!data)
+		return;
+	isi_data = *data;
+
+	at91_set_A_periph(AT91_PIN_PB20, 0);	/* ISI_D0 */
+	at91_set_A_periph(AT91_PIN_PB21, 0);	/* ISI_D1 */
+	at91_set_A_periph(AT91_PIN_PB22, 0);	/* ISI_D2 */
+	at91_set_A_periph(AT91_PIN_PB23, 0);	/* ISI_D3 */
+	at91_set_A_periph(AT91_PIN_PB24, 0);	/* ISI_D4 */
+	at91_set_A_periph(AT91_PIN_PB25, 0);	/* ISI_D5 */
+	at91_set_A_periph(AT91_PIN_PB26, 0);	/* ISI_D6 */
+	at91_set_A_periph(AT91_PIN_PB27, 0);	/* ISI_D7 */
+	at91_set_A_periph(AT91_PIN_PB28, 0);	/* ISI_PCK */
+	at91_set_A_periph(AT91_PIN_PB30, 0);	/* ISI_HSYNC */
+	at91_set_A_periph(AT91_PIN_PB29, 0);	/* ISI_VSYNC */
+	at91_set_B_periph(AT91_PIN_PB8, 0);	/* ISI_PD8 */
+	at91_set_B_periph(AT91_PIN_PB9, 0);	/* ISI_PD9 */
+	at91_set_B_periph(AT91_PIN_PB10, 0);	/* ISI_PD10 */
+	at91_set_B_periph(AT91_PIN_PB11, 0);	/* ISI_PD11 */
+
+	platform_device_register(&at91sam9g45_isi_device);
+
+	if (use_pck_as_mck) {
+		at91_set_B_periph(AT91_PIN_PB31, 0);	/* ISI_MCK (PCK1) */
+
+		pck = clk_get(NULL, "pck1");
+		parent = clk_get(NULL, "plla");
+
+		BUG_ON(IS_ERR(pck) || IS_ERR(parent));
+
+		if (clk_set_parent(pck, parent)) {
+			pr_err("Failed to set PCK's parent\n");
+		} else {
+			/* Register PCK as ISI_MCK */
+			isi_mck_lookups[0].clk = pck;
+			clkdev_add_table(isi_mck_lookups,
+					ARRAY_SIZE(isi_mck_lookups));
+		}
+
+		clk_put(pck);
+		clk_put(parent);
+	}
+}
+#else
+void __init at91_add_device_isi(struct isi_platform_data *data,
+		bool use_pck_as_mck) {}
+#endif
+
 
 /* --------------------------------------------------------------------
  *  LCD Controller
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index d2c91a8..fd60e22 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -11,6 +11,7 @@
 
 #include <linux/module.h>
 
+#include <asm/proc-fns.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -291,8 +292,15 @@ static void __init at91sam9rl_ioremap_registers(void)
 	at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
 }
 
+static void at91sam9rl_idle(void)
+{
+	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+	cpu_do_idle();
+}
+
 static void __init at91sam9rl_initialize(void)
 {
+	arm_pm_idle = at91sam9rl_idle;
 	arm_pm_restart = at91sam9_alt_restart;
 	at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
 
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 61908dc..9be71c1 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -33,10 +33,6 @@
 #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
 static u64 hdmac_dmamask = DMA_BIT_MASK(32);
 
-static struct at_dma_platform_data atdma_pdata = {
-	.nr_channels	= 2,
-};
-
 static struct resource hdmac_resources[] = {
 	[0] = {
 		.start	= AT91SAM9RL_BASE_DMA,
@@ -51,12 +47,11 @@ static struct resource hdmac_resources[] = {
 };
 
 static struct platform_device at_hdmac_device = {
-	.name		= "at_hdmac",
+	.name		= "at91sam9rl_dma",
 	.id		= -1,
 	.dev		= {
 				.dma_mask		= &hdmac_dmamask,
 				.coherent_dma_mask	= DMA_BIT_MASK(32),
-				.platform_data		= &atdma_pdata,
 	},
 	.resource	= hdmac_resources,
 	.num_resources	= ARRAY_SIZE(hdmac_resources),
@@ -64,7 +59,6 @@ static struct platform_device at_hdmac_device = {
 
 void __init at91_add_device_hdmac(void)
 {
-	dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
 	platform_device_register(&at_hdmac_device);
 }
 #else
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
new file mode 100644
index 0000000..1c3444d
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -0,0 +1,373 @@
+/*
+ *  Chip-specific setup code for the AT91SAM9x5 family
+ *
+ *  Copyright (C) 2010-2012 Atmel Corporation.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at91sam9x5.h>
+#include <mach/at91_pmc.h>
+#include <mach/cpu.h>
+#include <mach/board.h>
+
+#include "soc.h"
+#include "generic.h"
+#include "clock.h"
+#include "sam9_smc.h"
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioAB_clk = {
+	.name		= "pioAB_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_PIOAB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioCD_clk = {
+	.name		= "pioCD_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_PIOCD,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk smd_clk = {
+	.name		= "smd_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_SMD,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+	.name		= "usart0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_USART0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+	.name		= "usart1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_USART1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+	.name		= "usart2_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_USART2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* USART3 clock - Only for sam9g25/sam9x25 */
+static struct clk usart3_clk = {
+	.name		= "usart3_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_USART3,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+	.name		= "twi0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_TWI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+	.name		= "twi1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_TWI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi2_clk = {
+	.name		= "twi2_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_TWI2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+	.name		= "mci0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_MCI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+	.name		= "spi0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_SPI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+	.name		= "spi1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_SPI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk uart0_clk = {
+	.name		= "uart0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_UART0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk uart1_clk = {
+	.name		= "uart1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_UART1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb0_clk = {
+	.name		= "tcb0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_TCB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+	.name		= "pwm_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_PWM,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk adc_clk = {
+	.name		= "adc_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_ADC,
+	.type	= CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma0_clk = {
+	.name		= "dma0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_DMA0,
+	.type	= CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma1_clk = {
+	.name		= "dma1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_DMA1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk uhphs_clk = {
+	.name		= "uhphs_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_UHPHS,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+	.name		= "udphs_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_UDPHS,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */
+static struct clk macb0_clk = {
+	.name		= "pclk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_EMAC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* lcd clock - Only for sam9g15/sam9g35/sam9x35 */
+static struct clk lcdc_clk = {
+	.name		= "lcdc_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_LCDC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* isi clock - Only for sam9g25 */
+static struct clk isi_clk = {
+	.name		= "isi_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_ISI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+	.name		= "mci1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_MCI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* emac1 clock - Only for sam9x25 */
+static struct clk macb1_clk = {
+	.name		= "pclk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_EMAC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc_clk = {
+	.name		= "ssc_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_SSC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* can0 clock - Only for sam9x35 */
+static struct clk can0_clk = {
+	.name		= "can0_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_CAN0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+/* can1 clock - Only for sam9x35 */
+static struct clk can1_clk = {
+	.name		= "can1_clk",
+	.pmc_mask	= 1 << AT91SAM9X5_ID_CAN1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+	&pioAB_clk,
+	&pioCD_clk,
+	&smd_clk,
+	&usart0_clk,
+	&usart1_clk,
+	&usart2_clk,
+	&twi0_clk,
+	&twi1_clk,
+	&twi2_clk,
+	&mmc0_clk,
+	&spi0_clk,
+	&spi1_clk,
+	&uart0_clk,
+	&uart1_clk,
+	&tcb0_clk,
+	&pwm_clk,
+	&adc_clk,
+	&dma0_clk,
+	&dma1_clk,
+	&uhphs_clk,
+	&udphs_clk,
+	&mmc1_clk,
+	&ssc_clk,
+	// irq0
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+	/* lookup table for DT entries */
+	CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+	CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk),
+	CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
+	CLKDEV_CON_ID("pioA", &pioAB_clk),
+	CLKDEV_CON_ID("pioB", &pioAB_clk),
+	CLKDEV_CON_ID("pioC", &pioCD_clk),
+	CLKDEV_CON_ID("pioD", &pioCD_clk),
+	/* additional fake clock for macb_hclk */
+	CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk),
+	CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk),
+};
+
+/*
+ * The two programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+	.name		= "pck0",
+	.pmc_mask	= AT91_PMC_PCK0,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 0,
+};
+static struct clk pck1 = {
+	.name		= "pck1",
+	.pmc_mask	= AT91_PMC_PCK1,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 1,
+};
+
+static void __init at91sam9x5_register_clocks(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+		clk_register(periph_clocks[i]);
+
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+
+	if (cpu_is_at91sam9g25()
+	|| cpu_is_at91sam9x25())
+		clk_register(&usart3_clk);
+
+	if (cpu_is_at91sam9g25()
+	|| cpu_is_at91sam9x25()
+	|| cpu_is_at91sam9g35()
+	|| cpu_is_at91sam9x35())
+		clk_register(&macb0_clk);
+
+	if (cpu_is_at91sam9g15()
+	|| cpu_is_at91sam9g35()
+	|| cpu_is_at91sam9x35())
+		clk_register(&lcdc_clk);
+
+	if (cpu_is_at91sam9g25())
+		clk_register(&isi_clk);
+
+	if (cpu_is_at91sam9x25())
+		clk_register(&macb1_clk);
+
+	if (cpu_is_at91sam9x25()
+	|| cpu_is_at91sam9x35()) {
+		clk_register(&can0_clk);
+		clk_register(&can1_clk);
+	}
+
+	clk_register(&pck0);
+	clk_register(&pck1);
+}
+
+/* --------------------------------------------------------------------
+ *  AT91SAM9x5 processor initialization
+ * -------------------------------------------------------------------- */
+
+static void __init at91sam9x5_map_io(void)
+{
+	at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
+}
+
+static void __init at91sam9x5_ioremap_registers(void)
+{
+	if (of_at91sam926x_pit_init() < 0)
+		panic("Impossible to find PIT\n");
+}
+
+void __init at91sam9x5_initialize(void)
+{
+	arm_pm_restart = at91sam9g45_restart;
+	at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0);
+
+	/* Register GPIO subsystem (using DT) */
+	at91_gpio_init(NULL, 0);
+}
+
+/* --------------------------------------------------------------------
+ *  AT91SAM9x5 devices (temporary before modification of code)
+ * -------------------------------------------------------------------- */
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+struct platform_device *atmel_default_console_device = NULL;
+
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = {
+	7,	/* Advanced Interrupt Controller (FIQ) */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A and B */
+	1,	/* Parallel IO Controller C and D */
+	4,	/* Soft Modem */
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	5,	/* USART 3 */
+	6,	/* Two-Wire Interface 0 */
+	6,	/* Two-Wire Interface 1 */
+	6,	/* Two-Wire Interface 2 */
+	0,	/* Multimedia Card Interface 0 */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	5,	/* UART 0 */
+	5,	/* UART 1 */
+	0,	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
+	0,	/* Pulse Width Modulation Controller */
+	0,	/* ADC Controller */
+	0,	/* DMA Controller 0 */
+	0,	/* DMA Controller 1 */
+	2,	/* USB Host High Speed port */
+	2,	/* USB Device High speed port */
+	3,	/* Ethernet MAC 0 */
+	3,	/* LDC Controller or Image Sensor Interface */
+	0,	/* Multimedia Card Interface 1 */
+	3,	/* Ethernet MAC 1 */
+	4,	/* Synchronous Serial Interface */
+	4,	/* CAN Controller 0 */
+	4,	/* CAN Controller 1 */
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+};
+
+struct at91_init_soc __initdata at91sam9x5_soc = {
+	.map_io = at91sam9x5_map_io,
+	.default_irq_priority = at91sam9x5_default_irq_priority,
+	.ioremap_registers = at91sam9x5_ioremap_registers,
+	.register_clocks = at91sam9x5_register_clocks,
+	.init = at91sam9x5_initialize,
+};
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c
index 56ba3bd..0154b7f 100644
--- a/arch/arm/mach-at91/at91x40.c
+++ b/arch/arm/mach-at91/at91x40.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <asm/proc-fns.h>
 #include <asm/mach/arch.h>
 #include <mach/at91x40.h>
 #include <mach/at91_st.h>
@@ -37,8 +38,19 @@ unsigned long clk_get_rate(struct clk *clk)
 	return AT91X40_MASTER_CLOCK;
 }
 
+static void at91x40_idle(void)
+{
+	/*
+	 * Disable the processor clock.  The processor will be automatically
+	 * re-enabled by an interrupt or by a reset.
+	 */
+	at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
+	cpu_do_idle();
+}
+
 void __init at91x40_initialize(unsigned long main_clock)
 {
+	arm_pm_idle = at91x40_idle;
 	at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
 			| (1 << AT91X40_ID_IRQ2);
 }
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
deleted file mode 100644
index ac3de4f..0000000
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-cap9adk.c
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2005 SAN People
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
-#include <linux/fb.h>
-#include <linux/mtd/physmap.h>
-
-#include <video/atmel_lcdc.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/board.h>
-#include <mach/at91cap9_matrix.h>
-#include <mach/at91sam9_smc.h>
-#include <mach/system_rev.h>
-
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init cap9adk_init_early(void)
-{
-	/* Initialize processor: 12 MHz crystal */
-	at91_initialize(12000000);
-
-	/* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */
-	at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11);
-	/* ... POWER LED always on */
-	at91_set_gpio_output(AT91_PIN_PC29, 1);
-
-	/* Setup the serial ports and console */
-	at91_register_uart(0, 0, 0);		/* DBGU = ttyS0 */
-	at91_set_serial_console(0);
-}
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata cap9adk_usbh_data = {
-	.ports		= 2,
-	.vbus_pin	= {-EINVAL, -EINVAL},
-	.overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-/*
- * USB HS Device port
- */
-static struct usba_platform_data __initdata cap9adk_usba_udc_data = {
-	.vbus_pin	= AT91_PIN_PB31,
-};
-
-/*
- * ADS7846 Touchscreen
- */
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-static int ads7843_pendown_state(void)
-{
-	return !at91_get_gpio_value(AT91_PIN_PC4);	/* Touchscreen PENIRQ */
-}
-
-static struct ads7846_platform_data ads_info = {
-	.model			= 7843,
-	.x_min			= 150,
-	.x_max			= 3830,
-	.y_min			= 190,
-	.y_max			= 3830,
-	.vref_delay_usecs	= 100,
-	.x_plate_ohms		= 450,
-	.y_plate_ohms		= 250,
-	.pressure_max		= 15000,
-	.debounce_max		= 1,
-	.debounce_rep		= 0,
-	.debounce_tol		= (~0),
-	.get_pendown_state	= ads7843_pendown_state,
-};
-
-static void __init cap9adk_add_device_ts(void)
-{
-	at91_set_gpio_input(AT91_PIN_PC4, 1);	/* Touchscreen PENIRQ */
-	at91_set_gpio_input(AT91_PIN_PC5, 1);	/* Touchscreen BUSY */
-}
-#else
-static void __init cap9adk_add_device_ts(void) {}
-#endif
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info cap9adk_spi_devices[] = {
-#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
-	{	/* DataFlash card */
-		.modalias	= "mtd_dataflash",
-		.chip_select	= 0,
-		.max_speed_hz	= 15 * 1000 * 1000,
-		.bus_num	= 0,
-	},
-#endif
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-	{
-		.modalias	= "ads7846",
-		.chip_select	= 3,		/* can be 2 or 3, depending on J2 jumper */
-		.max_speed_hz	= 125000 * 26,	/* (max sample rate @ 3V) * (cmd + data + overhead) */
-		.bus_num	= 0,
-		.platform_data	= &ads_info,
-		.irq		= AT91_PIN_PC4,
-	},
-#endif
-};
-
-
-/*
- * MCI (SD/MMC)
- */
-static struct at91_mmc_data __initdata cap9adk_mmc_data = {
-	.wire4		= 1,
-	.det_pin	= -EINVAL,
-	.wp_pin		= -EINVAL,
-	.vcc_pin	= -EINVAL,
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct macb_platform_data __initdata cap9adk_macb_data = {
-	.phy_irq_pin	= -EINVAL,
-	.is_rmii	= 1,
-};
-
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
-	{
-		.name	= "NAND partition",
-		.offset	= 0,
-		.size	= MTDPART_SIZ_FULL,
-	},
-};
-
-static struct atmel_nand_data __initdata cap9adk_nand_data = {
-	.ale		= 21,
-	.cle		= 22,
-	.det_pin	= -EINVAL,
-	.rdy_pin	= -EINVAL,
-	.enable_pin	= AT91_PIN_PD15,
-	.parts		= cap9adk_nand_partitions,
-	.num_parts	= ARRAY_SIZE(cap9adk_nand_partitions),
-};
-
-static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
-	.ncs_read_setup		= 1,
-	.nrd_setup		= 2,
-	.ncs_write_setup	= 1,
-	.nwe_setup		= 2,
-
-	.ncs_read_pulse		= 6,
-	.nrd_pulse		= 4,
-	.ncs_write_pulse	= 6,
-	.nwe_pulse		= 4,
-
-	.read_cycle		= 8,
-	.write_cycle		= 8,
-
-	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
-	.tdf_cycles		= 1,
-};
-
-static void __init cap9adk_add_device_nand(void)
-{
-	unsigned long csa;
-
-	csa = at91_sys_read(AT91_MATRIX_EBICSA);
-	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
-
-	cap9adk_nand_data.bus_width_16 = board_have_nand_16bit();
-	/* setup bus-width (8 or 16) */
-	if (cap9adk_nand_data.bus_width_16)
-		cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16;
-	else
-		cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
-	/* configure chip-select 3 (NAND) */
-	sam9_smc_configure(0, 3, &cap9adk_nand_smc_config);
-
-	at91_add_device_nand(&cap9adk_nand_data);
-}
-
-
-/*
- * NOR flash
- */
-static struct mtd_partition cap9adk_nor_partitions[] = {
-	{
-		.name		= "NOR partition",
-		.offset		= 0,
-		.size		= MTDPART_SIZ_FULL,
-	},
-};
-
-static struct physmap_flash_data cap9adk_nor_data = {
-	.width		= 2,
-	.parts		= cap9adk_nor_partitions,
-	.nr_parts	= ARRAY_SIZE(cap9adk_nor_partitions),
-};
-
-#define NOR_BASE	AT91_CHIPSELECT_0
-#define NOR_SIZE	SZ_8M
-
-static struct resource nor_flash_resources[] = {
-	{
-		.start	= NOR_BASE,
-		.end	= NOR_BASE + NOR_SIZE - 1,
-		.flags	= IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device cap9adk_nor_flash = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-				.platform_data	= &cap9adk_nor_data,
-	},
-	.resource	= nor_flash_resources,
-	.num_resources	= ARRAY_SIZE(nor_flash_resources),
-};
-
-static struct sam9_smc_config __initdata cap9adk_nor_smc_config = {
-	.ncs_read_setup		= 2,
-	.nrd_setup		= 4,
-	.ncs_write_setup	= 2,
-	.nwe_setup		= 4,
-
-	.ncs_read_pulse		= 10,
-	.nrd_pulse		= 8,
-	.ncs_write_pulse	= 10,
-	.nwe_pulse		= 8,
-
-	.read_cycle		= 16,
-	.write_cycle		= 16,
-
-	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16,
-	.tdf_cycles		= 1,
-};
-
-static __init void cap9adk_add_device_nor(void)
-{
-	unsigned long csa;
-
-	csa = at91_sys_read(AT91_MATRIX_EBICSA);
-	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
-
-	/* configure chip-select 0 (NOR) */
-	sam9_smc_configure(0, 0, &cap9adk_nor_smc_config);
-
-	platform_device_register(&cap9adk_nor_flash);
-}
-
-
-/*
- * LCD Controller
- */
-#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static struct fb_videomode at91_tft_vga_modes[] = {
-	{
-	        .name           = "TX09D50VM1CCA @ 60",
-		.refresh	= 60,
-		.xres		= 240,		.yres		= 320,
-		.pixclock	= KHZ2PICOS(4965),
-
-		.left_margin	= 1,		.right_margin	= 33,
-		.upper_margin	= 1,		.lower_margin	= 0,
-		.hsync_len	= 5,		.vsync_len	= 1,
-
-		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-		.vmode		= FB_VMODE_NONINTERLACED,
-	},
-};
-
-static struct fb_monspecs at91fb_default_monspecs = {
-	.manufacturer	= "HIT",
-	.monitor        = "TX09D70VM1CCA",
-
-	.modedb		= at91_tft_vga_modes,
-	.modedb_len	= ARRAY_SIZE(at91_tft_vga_modes),
-	.hfmin		= 15000,
-	.hfmax		= 64000,
-	.vfmin		= 50,
-	.vfmax		= 150,
-};
-
-#define AT91CAP9_DEFAULT_LCDCON2 	(ATMEL_LCDC_MEMOR_LITTLE \
-					| ATMEL_LCDC_DISTYPE_TFT    \
-					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
-
-static void at91_lcdc_power_control(int on)
-{
-	if (on)
-		at91_set_gpio_value(AT91_PIN_PC0, 0);	/* power up */
-	else
-		at91_set_gpio_value(AT91_PIN_PC0, 1);	/* power down */
-}
-
-/* Driver datas */
-static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = {
-	.default_bpp			= 16,
-	.default_dmacon			= ATMEL_LCDC_DMAEN,
-	.default_lcdcon2		= AT91CAP9_DEFAULT_LCDCON2,
-	.default_monspecs		= &at91fb_default_monspecs,
-	.atmel_lcdfb_power_control	= at91_lcdc_power_control,
-	.guard_time			= 1,
-};
-
-#else
-static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
-#endif
-
-
-/*
- * AC97
- */
-static struct ac97c_platform_data cap9adk_ac97_data = {
-	.reset_pin	= -EINVAL,
-};
-
-
-static void __init cap9adk_board_init(void)
-{
-	/* Serial */
-	at91_add_device_serial();
-	/* USB Host */
-	at91_add_device_usbh(&cap9adk_usbh_data);
-	/* USB HS */
-	at91_add_device_usba(&cap9adk_usba_udc_data);
-	/* SPI */
-	at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
-	/* Touchscreen */
-	cap9adk_add_device_ts();
-	/* MMC */
-	at91_add_device_mmc(1, &cap9adk_mmc_data);
-	/* Ethernet */
-	at91_add_device_eth(&cap9adk_macb_data);
-	/* NAND */
-	cap9adk_add_device_nand();
-	/* NOR Flash */
-	cap9adk_add_device_nor();
-	/* I2C */
-	at91_add_device_i2c(NULL, 0);
-	/* LCD Controller */
-	at91_add_device_lcdc(&cap9adk_lcdc_data);
-	/* AC97 */
-	at91_add_device_ac97(&cap9adk_ac97_data);
-}
-
-MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
-	/* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
-	.timer		= &at91sam926x_timer,
-	.map_io		= at91_map_io,
-	.init_early	= cap9adk_init_early,
-	.init_irq	= at91_init_irq_default,
-	.init_machine	= cap9adk_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index bb6b434..0579315 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -109,6 +109,7 @@ static void __init at91_dt_device_init(void)
 
 static const char *at91_dt_board_compat[] __initdata = {
 	"atmel,at91sam9m10g45ek",
+	"atmel,at91sam9x5ek",
 	"calao,usb-a9g20",
 	NULL
 };
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
index eec02cd..1815152 100644
--- a/arch/arm/mach-at91/board-flexibity.c
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-at91/board-flexibity.c
  *
- *  Copyright (C) 2010 Flexibity
+ *  Copyright (C) 2010-2011 Flexibity
  *  Copyright (C) 2005 SAN People
  *  Copyright (C) 2006 Atmel
  *
@@ -62,6 +62,13 @@ static struct at91_udc_data __initdata flexibity_udc_data = {
 	.pullup_pin	= -EINVAL,		/* pull-up driven by UDC */
 };
 
+/* I2C devices */
+static struct i2c_board_info __initdata flexibity_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("ds1307", 0x68),
+	},
+};
+
 /* SPI devices */
 static struct spi_board_info flexibity_spi_devices[] = {
 	{	/* DataFlash chip */
@@ -141,6 +148,9 @@ static void __init flexibity_board_init(void)
 	at91_add_device_usbh(&flexibity_usbh_data);
 	/* USB Device */
 	at91_add_device_udc(&flexibity_udc_data);
+	/* I2C */
+	at91_add_device_i2c(flexibity_i2c_devices,
+		ARRAY_SIZE(flexibity_i2c_devices));
 	/* SPI */
 	at91_add_device_spi(flexibity_spi_devices,
 		ARRAY_SIZE(flexibity_spi_devices));
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index ea0d1b9..57497e2 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -24,11 +24,13 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/leds.h>
-#include <linux/clk.h>
 #include <linux/atmel-mci.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <video/atmel_lcdc.h>
+#include <media/soc_camera.h>
+#include <media/atmel-isi.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -185,6 +187,71 @@ static void __init ek_add_device_nand(void)
 
 
 /*
+ *  ISI
+ */
+static struct isi_platform_data __initdata isi_data = {
+	.frate			= ISI_CFG1_FRATE_CAPTURE_ALL,
+	/* to use codec and preview path simultaneously */
+	.full_mode		= 1,
+	.data_width_flags	= ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10,
+	/* ISI_MCK is provided by programmable clock or external clock */
+	.mck_hz			= 25000000,
+};
+
+
+/*
+ * soc-camera OV2640
+ */
+#if defined(CONFIG_SOC_CAMERA_OV2640) || \
+	defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
+static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link)
+{
+	/* ISI board for ek using default 8-bits connection */
+	return SOCAM_DATAWIDTH_8;
+}
+
+static int i2c_camera_power(struct device *dev, int on)
+{
+	/* enable or disable the camera */
+	pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+	at91_set_gpio_output(AT91_PIN_PD13, !on);
+
+	if (!on)
+		goto out;
+
+	/* If enabled, give a reset impulse */
+	at91_set_gpio_output(AT91_PIN_PD12, 0);
+	msleep(20);
+	at91_set_gpio_output(AT91_PIN_PD12, 1);
+	msleep(100);
+
+out:
+	return 0;
+}
+
+static struct i2c_board_info i2c_camera = {
+	I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+	.bus_id			= 0,
+	.board_info		= &i2c_camera,
+	.i2c_adapter_id		= 0,
+	.power			= i2c_camera_power,
+	.query_bus_param	= isi_camera_query_bus_param,
+};
+
+static struct platform_device isi_ov2640 = {
+	.name	= "soc-camera-pdrv",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &iclink_ov2640,
+	},
+};
+#endif
+
+
+/*
  * LCD Controller
  */
 #if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
@@ -377,7 +444,12 @@ static struct gpio_led ek_pwm_led[] = {
 #endif
 };
 
-
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_SOC_CAMERA_OV2640) || \
+	defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
+	&isi_ov2640,
+#endif
+};
 
 static void __init ek_board_init(void)
 {
@@ -399,6 +471,8 @@ static void __init ek_board_init(void)
 	ek_add_device_nand();
 	/* I2C */
 	at91_add_device_i2c(0, NULL, 0);
+	/* ISI, using programmable clock as ISI_MCK */
+	at91_add_device_isi(&isi_data, true);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
 	/* Touch Screen */
@@ -410,6 +484,8 @@ static void __init ek_board_init(void)
 	/* LEDs */
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 	at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+	/* Other platform devices */
+	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
 MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 61873f3..a5291e0 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -47,26 +47,38 @@
 /*
  * Chips have some kind of clocks : group them by functionality
  */
-#define cpu_has_utmi()		(  cpu_is_at91cap9() \
-				|| cpu_is_at91sam9rl() \
-				|| cpu_is_at91sam9g45())
+#define cpu_has_utmi()		(  cpu_is_at91sam9rl() \
+				|| cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5())
 
 #define cpu_has_800M_plla()	(  cpu_is_at91sam9g20() \
-				|| cpu_is_at91sam9g45())
+				|| cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5())
 
 #define cpu_has_300M_plla()	(cpu_is_at91sam9g10())
 
 #define cpu_has_pllb()		(!(cpu_is_at91sam9rl() \
-				|| cpu_is_at91sam9g45()))
+				|| cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5()))
 
-#define cpu_has_upll()		(cpu_is_at91sam9g45())
+#define cpu_has_upll()		(cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5())
 
 /* USB host HS & FS */
 #define cpu_has_uhp()		(!cpu_is_at91sam9rl())
 
 /* USB device FS only */
 #define cpu_has_udpfs()		(!(cpu_is_at91sam9rl() \
-				|| cpu_is_at91sam9g45()))
+				|| cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5()))
+
+#define cpu_has_plladiv2()	(cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5())
+
+#define cpu_has_mdiv3()		(cpu_is_at91sam9g45() \
+				|| cpu_is_at91sam9x5())
+
+#define cpu_has_alt_prescaler()	(cpu_is_at91sam9x5())
 
 static LIST_HEAD(clocks);
 static DEFINE_SPINLOCK(clk_lock);
@@ -139,13 +151,6 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
 {
 	unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
 
-	if (cpu_is_at91sam9g45()) {
-		if (is_on)
-			uckr |= AT91_PMC_BIASEN;
-		else
-			uckr &= ~AT91_PMC_BIASEN;
-	}
-
 	if (is_on) {
 		is_on = AT91_PMC_LOCKU;
 		at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -210,11 +215,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css)
 				return &utmi_clk;
 			else if (cpu_has_pllb())
 				return &pllb;
+			break;
+		/* alternate PMC: can use master clock */
+		case AT91_PMC_CSS_MASTER:
+			return &mck;
 	}
 
 	return NULL;
 }
 
+static int pmc_prescaler_divider(u32 reg)
+{
+	if (cpu_has_alt_prescaler()) {
+		return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET);
+	} else {
+		return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET);
+	}
+}
+
 static void __clk_enable(struct clk *clk)
 {
 	if (clk->parent)
@@ -316,12 +334,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned long	flags;
 	unsigned	prescale;
+	unsigned long	prescale_offset, css_mask;
 	unsigned long	actual;
 
 	if (!clk_is_programmable(clk))
 		return -EINVAL;
 	if (clk->users)
 		return -EBUSY;
+
+	if (cpu_has_alt_prescaler()) {
+		prescale_offset = PMC_ALT_PRES_OFFSET;
+		css_mask = AT91_PMC_ALT_PCKR_CSS;
+	} else {
+		prescale_offset = PMC_PRES_OFFSET;
+		css_mask = AT91_PMC_CSS;
+	}
+
 	spin_lock_irqsave(&clk_lock, flags);
 
 	actual = clk->parent->rate_hz;
@@ -330,8 +358,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 			u32	pckr;
 
 			pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
-			pckr &= AT91_PMC_CSS;	/* clock selection */
-			pckr |= prescale << 2;
+			pckr &= css_mask;	/* keep clock selection */
+			pckr |= prescale << prescale_offset;
 			at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
 			clk->rate_hz = actual;
 			break;
@@ -378,11 +406,17 @@ static void __init init_programmable_clock(struct clk *clk)
 {
 	struct clk	*parent;
 	u32		pckr;
+	unsigned int	css_mask;
+
+	if (cpu_has_alt_prescaler())
+		css_mask = AT91_PMC_ALT_PCKR_CSS;
+	else
+		css_mask = AT91_PMC_CSS;
 
 	pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
-	parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
+	parent = at91_css_to_clk(pckr & css_mask);
 	clk->parent = parent;
-	clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2));
+	clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr);
 }
 
 #endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -602,8 +636,6 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
 		   cpu_is_at91sam9g10()) {
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
-	} else if (cpu_is_at91cap9()) {
-		uhpck.pmc_mask = AT91CAP9_PMC_UHP;
 	}
 	at91_sys_write(AT91_CKGR_PLLBR, 0);
 
@@ -666,7 +698,7 @@ int __init at91_clock_init(unsigned long main_clock)
 	if (pll_overclock)
 		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
 
-	if (cpu_is_at91sam9g45()) {
+	if (cpu_has_plladiv2()) {
 		mckr = at91_sys_read(AT91_PMC_MCKR);
 		plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12));	/* plla divisor by 2 */
 	}
@@ -688,6 +720,10 @@ int __init at91_clock_init(unsigned long main_clock)
 		 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
 		 */
 		utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+
+		/* UTMI bias and PLL are managed at the same time */
+		if (cpu_has_upll())
+			utmi_clk.pmc_mask |= AT91_PMC_BIASEN;
 	}
 
 	/*
@@ -706,7 +742,7 @@ int __init at91_clock_init(unsigned long main_clock)
 	mckr = at91_sys_read(AT91_PMC_MCKR);
 	mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
 	freq = mck.parent->rate_hz;
-	freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2));				/* prescale */
+	freq /= pmc_prescaler_divider(mckr);					/* prescale */
 	if (cpu_is_at91rm9200()) {
 		mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
 	} else if (cpu_is_at91sam9g20()) {
@@ -714,13 +750,19 @@ int __init at91_clock_init(unsigned long main_clock)
 			freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq;	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 		if (mckr & AT91_PMC_PDIV)
 			freq /= 2;		/* processor clock division */
-	} else if (cpu_is_at91sam9g45()) {
+	} else if (cpu_has_mdiv3()) {
 		mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
 			freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
 	} else {
 		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));		/* mdiv */
 	}
 
+	if (cpu_has_alt_prescaler()) {
+		/* Programmable clocks can use MCK */
+		mck.type |= CLK_TYPE_PRIMARY;
+		mck.id = 4;
+	}
+
 	/* Register the PMC's standard clocks */
 	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
 		at91_clk_add(standard_pmc_clocks[i]);
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
index a851e6c..555d956 100644
--- a/arch/arm/mach-at91/cpuidle.c
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -39,20 +39,15 @@ static int at91_enter_idle(struct cpuidle_device *dev,
 {
 	struct timeval before, after;
 	int idle_time;
-	u32 saved_lpr;
 
 	local_irq_disable();
 	do_gettimeofday(&before);
 	if (index == 0)
 		/* Wait for interrupt state */
 		cpu_do_idle();
-	else if (index == 1) {
-		asm("b 1f; .align 5; 1:");
-		asm("mcr p15, 0, r0, c7, c10, 4");	/* drain write buffer */
-		saved_lpr = sdram_selfrefresh_enable();
-		cpu_do_idle();
-		sdram_selfrefresh_disable(saved_lpr);
-	}
+	else if (index == 1)
+		at91_standby();
+
 	do_gettimeofday(&after);
 	local_irq_enable();
 	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 5941334..7e8280e 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -45,7 +45,6 @@ extern void __init at91sam9261_set_console_clock(int id);
 extern void __init at91sam9263_set_console_clock(int id);
 extern void __init at91sam9rl_set_console_clock(int id);
 extern void __init at91sam9g45_set_console_clock(int id);
-extern void __init at91cap9_set_console_clock(int id);
 #ifdef CONFIG_AT91_PMC_UNIT
 extern int __init at91_clock_init(unsigned long main_clock);
 #else
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index e46f93e..f9fdbbe 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -23,10 +23,8 @@
 #define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
 #define		AT91RM9200_PMC_UDP	(1 <<  1)		/* USB Devcice Port Clock [AT91RM9200 only] */
 #define		AT91RM9200_PMC_MCKUDP	(1 <<  2)		/* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
-#define		AT91CAP9_PMC_DDR	(1 <<  2)		/* DDR Clock [CAP9 revC & some SAM9 only] */
 #define		AT91RM9200_PMC_UHP	(1 <<  4)		/* USB Host Port Clock [AT91RM9200 only] */
 #define		AT91SAM926x_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91SAM926x only] */
-#define		AT91CAP9_PMC_UHP	(1 <<  6)		/* USB Host Port Clock [AT91CAP9 only] */
 #define		AT91SAM926x_PMC_UDP	(1 <<  7)		/* USB Devcice Port Clock [AT91SAM926x only] */
 #define		AT91_PMC_PCK0		(1 <<  8)		/* Programmable Clock 0 */
 #define		AT91_PMC_PCK1		(1 <<  9)		/* Programmable Clock 1 */
@@ -40,16 +38,20 @@
 #define	AT91_PMC_PCDR		(AT91_PMC + 0x14)	/* Peripheral Clock Disable Register */
 #define	AT91_PMC_PCSR		(AT91_PMC + 0x18)	/* Peripheral Clock Status Register */
 
-#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [some SAM9, CAP9] */
+#define	AT91_CKGR_UCKR		(AT91_PMC + 0x1C)	/* UTMI Clock Register [some SAM9] */
 #define		AT91_PMC_UPLLEN		(1   << 16)		/* UTMI PLL Enable */
 #define		AT91_PMC_UPLLCOUNT	(0xf << 20)		/* UTMI PLL Start-up Time */
 #define		AT91_PMC_BIASEN		(1   << 24)		/* UTMI BIAS Enable */
 #define		AT91_PMC_BIASCOUNT	(0xf << 28)		/* UTMI BIAS Start-up Time */
 
 #define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register [not on SAM9RL] */
-#define		AT91_PMC_MOSCEN		(1    << 0)		/* Main Oscillator Enable */
-#define		AT91_PMC_OSCBYPASS	(1    << 1)		/* Oscillator Bypass [SAM9x, CAP9] */
-#define		AT91_PMC_OSCOUNT	(0xff << 8)		/* Main Oscillator Start-up Time */
+#define		AT91_PMC_MOSCEN		(1    <<  0)		/* Main Oscillator Enable */
+#define		AT91_PMC_OSCBYPASS	(1    <<  1)		/* Oscillator Bypass */
+#define		AT91_PMC_MOSCRCEN	(1    <<  3)		/* Main On-Chip RC Oscillator Enable [some SAM9] */
+#define		AT91_PMC_OSCOUNT	(0xff <<  8)		/* Main Oscillator Start-up Time */
+#define		AT91_PMC_KEY		(0x37 << 16)		/* MOR Writing Key */
+#define		AT91_PMC_MOSCSEL	(1    << 24)		/* Main Oscillator Selection [some SAM9] */
+#define		AT91_PMC_CFDEN		(1    << 25)		/* Clock Failure Detector Enable [some SAM9] */
 
 #define	AT91_CKGR_MCFR		(AT91_PMC + 0x24)	/* Main Clock Frequency Register */
 #define		AT91_PMC_MAINF		(0xffff <<  0)		/* Main Clock Frequency */
@@ -74,20 +76,30 @@
 #define			AT91_PMC_CSS_PLLA		(2 << 0)
 #define			AT91_PMC_CSS_PLLB		(3 << 0)
 #define			AT91_PMC_CSS_UPLL		(3 << 0)	/* [some SAM9 only] */
-#define		AT91_PMC_PRES		(7 <<  2)		/* Master Clock Prescaler */
-#define			AT91_PMC_PRES_1			(0 << 2)
-#define			AT91_PMC_PRES_2			(1 << 2)
-#define			AT91_PMC_PRES_4			(2 << 2)
-#define			AT91_PMC_PRES_8			(3 << 2)
-#define			AT91_PMC_PRES_16		(4 << 2)
-#define			AT91_PMC_PRES_32		(5 << 2)
-#define			AT91_PMC_PRES_64		(6 << 2)
+#define		PMC_PRES_OFFSET		2
+#define		AT91_PMC_PRES		(7 <<  PMC_PRES_OFFSET)		/* Master Clock Prescaler */
+#define			AT91_PMC_PRES_1			(0 << PMC_PRES_OFFSET)
+#define			AT91_PMC_PRES_2			(1 << PMC_PRES_OFFSET)
+#define			AT91_PMC_PRES_4			(2 << PMC_PRES_OFFSET)
+#define			AT91_PMC_PRES_8			(3 << PMC_PRES_OFFSET)
+#define			AT91_PMC_PRES_16		(4 << PMC_PRES_OFFSET)
+#define			AT91_PMC_PRES_32		(5 << PMC_PRES_OFFSET)
+#define			AT91_PMC_PRES_64		(6 << PMC_PRES_OFFSET)
+#define		PMC_ALT_PRES_OFFSET	4
+#define		AT91_PMC_ALT_PRES	(7 <<  PMC_ALT_PRES_OFFSET)		/* Master Clock Prescaler [alternate location] */
+#define			AT91_PMC_ALT_PRES_1		(0 << PMC_ALT_PRES_OFFSET)
+#define			AT91_PMC_ALT_PRES_2		(1 << PMC_ALT_PRES_OFFSET)
+#define			AT91_PMC_ALT_PRES_4		(2 << PMC_ALT_PRES_OFFSET)
+#define			AT91_PMC_ALT_PRES_8		(3 << PMC_ALT_PRES_OFFSET)
+#define			AT91_PMC_ALT_PRES_16		(4 << PMC_ALT_PRES_OFFSET)
+#define			AT91_PMC_ALT_PRES_32		(5 << PMC_ALT_PRES_OFFSET)
+#define			AT91_PMC_ALT_PRES_64		(6 << PMC_ALT_PRES_OFFSET)
 #define		AT91_PMC_MDIV		(3 <<  8)		/* Master Clock Division */
 #define			AT91RM9200_PMC_MDIV_1		(0 << 8)	/* [AT91RM9200 only] */
 #define			AT91RM9200_PMC_MDIV_2		(1 << 8)
 #define			AT91RM9200_PMC_MDIV_3		(2 << 8)
 #define			AT91RM9200_PMC_MDIV_4		(3 << 8)
-#define			AT91SAM9_PMC_MDIV_1		(0 << 8)	/* [SAM9,CAP9 only] */
+#define			AT91SAM9_PMC_MDIV_1		(0 << 8)	/* [SAM9 only] */
 #define			AT91SAM9_PMC_MDIV_2		(1 << 8)
 #define			AT91SAM9_PMC_MDIV_4		(2 << 8)
 #define			AT91SAM9_PMC_MDIV_6		(3 << 8)	/* [some SAM9 only] */
@@ -105,7 +117,14 @@
 #define			AT91_PMC_USBS_UPLL		(1 << 0)
 #define		AT91_PMC_OHCIUSBDIV	(0xF <<  8)		/* Divider for USB OHCI Clock */
 
+#define	AT91_PMC_SMD		(AT91_PMC + 0x3c)	/* Soft Modem Clock Register [some SAM9 only] */
+#define		AT91_PMC_SMDS		(0x1  <<  0)		/* SMD input clock selection */
+#define		AT91_PMC_SMD_DIV	(0x1f <<  8)		/* SMD input clock divider */
+#define		AT91_PMC_SMDDIV(n)	(((n) <<  8) & AT91_PMC_SMD_DIV)
+
 #define	AT91_PMC_PCKR(n)	(AT91_PMC + 0x40 + ((n) * 4))	/* Programmable Clock 0-N Registers */
+#define		AT91_PMC_ALT_PCKR_CSS	(0x7 <<  0)		/* Programmable Clock Source Selection [alternate length] */
+#define			AT91_PMC_CSS_MASTER		(4 << 0)	/* [some SAM9 only] */
 #define		AT91_PMC_CSSMCK		(0x1 <<  8)		/* CSS or Master Clock Selection */
 #define			AT91_PMC_CSSMCK_CSS		(0 << 8)
 #define			AT91_PMC_CSSMCK_MCK		(1 << 8)
@@ -117,17 +136,30 @@
 #define		AT91_PMC_LOCKA		(1 <<  1)		/* PLLA Lock */
 #define		AT91_PMC_LOCKB		(1 <<  2)		/* PLLB Lock */
 #define		AT91_PMC_MCKRDY		(1 <<  3)		/* Master Clock */
-#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [some SAM9, AT91CAP9 only] */
-#define		AT91_PMC_OSCSEL		(1 <<  7)		/* Slow Clock Oscillator [AT91CAP9 revC only] */
+#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [some SAM9] */
 #define		AT91_PMC_PCK0RDY	(1 <<  8)		/* Programmable Clock 0 */
 #define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
 #define		AT91_PMC_PCK2RDY	(1 << 10)		/* Programmable Clock 2 */
 #define		AT91_PMC_PCK3RDY	(1 << 11)		/* Programmable Clock 3 */
+#define		AT91_PMC_MOSCSELS	(1 << 16)		/* Main Oscillator Selection [some SAM9] */
+#define		AT91_PMC_MOSCRCS	(1 << 17)		/* Main On-Chip RC [some SAM9] */
+#define		AT91_PMC_CFDEV		(1 << 18)		/* Clock Failure Detector Event [some SAM9] */
 #define	AT91_PMC_IMR		(AT91_PMC + 0x6c)	/* Interrupt Mask Register */
 
-#define AT91_PMC_PROT		(AT91_PMC + 0xe4)	/* Protect Register [AT91CAP9 revC only] */
-#define		AT91_PMC_PROTKEY	0x504d4301	/* Activation Code */
+#define AT91_PMC_PROT		(AT91_PMC + 0xe4)	/* Write Protect Mode Register [some SAM9] */
+#define		AT91_PMC_WPEN		(0x1  <<  0)		/* Write Protect Enable */
+#define		AT91_PMC_WPKEY		(0xffffff << 8)		/* Write Protect Key */
+#define		AT91_PMC_PROTKEY	(0x504d43 << 8)		/* Activation Code */
+
+#define AT91_PMC_WPSR		(AT91_PMC + 0xe8)	/* Write Protect Status Register [some SAM9] */
+#define		AT91_PMC_WPVS		(0x1  <<  0)		/* Write Protect Violation Status */
+#define		AT91_PMC_WPVSRC		(0xffff  <<  8)		/* Write Protect Violation Source */
 
-#define AT91_PMC_VER		(AT91_PMC + 0xfc)	/* PMC Module Version [AT91CAP9 only] */
+#define AT91_PMC_PCR		(AT91_PMC + 0x10c)	/* Peripheral Control Register [some SAM9] */
+#define		AT91_PMC_PCR_PID	(0x3f  <<  0)		/* Peripheral ID */
+#define		AT91_PMC_PCR_CMD	(0x1  <<  12)		/* Command */
+#define		AT91_PMC_PCR_DIV	(0x3  <<  16)		/* Divisor Value */
+#define		AT91_PMC_PCRDIV(n)	(((n) <<  16) & AT91_PMC_PCR_DIV)
+#define		AT91_PMC_PCR_EN		(0x1  <<  28)		/* Enable */
 
 #endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
deleted file mode 100644
index 61d9529..0000000
--- a/arch/arm/mach-at91/include/mach/at91cap9.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9.h
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2007 Atmel Corporation.
- *
- * Common definitions.
- * Based on AT91CAP9 datasheet revision B (Preliminary).
- *
- * 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.
- */
-
-#ifndef AT91CAP9_H
-#define AT91CAP9_H
-
-/*
- * Peripheral identifiers/interrupts.
- */
-#define AT91CAP9_ID_PIOABCD	2	/* Parallel IO Controller A, B, C and D */
-#define AT91CAP9_ID_MPB0	3	/* MP Block Peripheral 0 */
-#define AT91CAP9_ID_MPB1	4	/* MP Block Peripheral 1 */
-#define AT91CAP9_ID_MPB2	5	/* MP Block Peripheral 2 */
-#define AT91CAP9_ID_MPB3	6	/* MP Block Peripheral 3 */
-#define AT91CAP9_ID_MPB4	7	/* MP Block Peripheral 4 */
-#define AT91CAP9_ID_US0		8	/* USART 0 */
-#define AT91CAP9_ID_US1		9	/* USART 1 */
-#define AT91CAP9_ID_US2		10	/* USART 2 */
-#define AT91CAP9_ID_MCI0	11	/* Multimedia Card Interface 0 */
-#define AT91CAP9_ID_MCI1	12	/* Multimedia Card Interface 1 */
-#define AT91CAP9_ID_CAN		13	/* CAN */
-#define AT91CAP9_ID_TWI		14	/* Two-Wire Interface */
-#define AT91CAP9_ID_SPI0	15	/* Serial Peripheral Interface 0 */
-#define AT91CAP9_ID_SPI1	16	/* Serial Peripheral Interface 0 */
-#define AT91CAP9_ID_SSC0	17	/* Serial Synchronous Controller 0 */
-#define AT91CAP9_ID_SSC1	18	/* Serial Synchronous Controller 1 */
-#define AT91CAP9_ID_AC97C	19	/* AC97 Controller */
-#define AT91CAP9_ID_TCB		20	/* Timer Counter 0, 1 and 2 */
-#define AT91CAP9_ID_PWMC	21	/* Pulse Width Modulation Controller */
-#define AT91CAP9_ID_EMAC	22	/* Ethernet */
-#define AT91CAP9_ID_AESTDES	23	/* Advanced Encryption Standard, Triple DES */
-#define AT91CAP9_ID_ADC		24	/* Analog-to-Digital Converter */
-#define AT91CAP9_ID_ISI		25	/* Image Sensor Interface */
-#define AT91CAP9_ID_LCDC	26	/* LCD Controller */
-#define AT91CAP9_ID_DMA		27	/* DMA Controller */
-#define AT91CAP9_ID_UDPHS	28	/* USB High Speed Device Port */
-#define AT91CAP9_ID_UHP		29	/* USB Host Port */
-#define AT91CAP9_ID_IRQ0	30	/* Advanced Interrupt Controller (IRQ0) */
-#define AT91CAP9_ID_IRQ1	31	/* Advanced Interrupt Controller (IRQ1) */
-
-/*
- * User Peripheral physical base addresses.
- */
-#define AT91CAP9_BASE_UDPHS		0xfff78000
-#define AT91CAP9_BASE_TCB0		0xfff7c000
-#define AT91CAP9_BASE_TC0		0xfff7c000
-#define AT91CAP9_BASE_TC1		0xfff7c040
-#define AT91CAP9_BASE_TC2		0xfff7c080
-#define AT91CAP9_BASE_MCI0		0xfff80000
-#define AT91CAP9_BASE_MCI1		0xfff84000
-#define AT91CAP9_BASE_TWI		0xfff88000
-#define AT91CAP9_BASE_US0		0xfff8c000
-#define AT91CAP9_BASE_US1		0xfff90000
-#define AT91CAP9_BASE_US2		0xfff94000
-#define AT91CAP9_BASE_SSC0		0xfff98000
-#define AT91CAP9_BASE_SSC1		0xfff9c000
-#define AT91CAP9_BASE_AC97C		0xfffa0000
-#define AT91CAP9_BASE_SPI0		0xfffa4000
-#define AT91CAP9_BASE_SPI1		0xfffa8000
-#define AT91CAP9_BASE_CAN		0xfffac000
-#define AT91CAP9_BASE_PWMC		0xfffb8000
-#define AT91CAP9_BASE_EMAC		0xfffbc000
-#define AT91CAP9_BASE_ADC		0xfffc0000
-#define AT91CAP9_BASE_ISI		0xfffc4000
-
-/*
- * System Peripherals (offset from AT91_BASE_SYS)
- */
-#define AT91_BCRAMC	(0xffffe400 - AT91_BASE_SYS)
-#define AT91_DDRSDRC0	(0xffffe600 - AT91_BASE_SYS)
-#define AT91_MATRIX	(0xffffea00 - AT91_BASE_SYS)
-#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR	(cpu_is_at91cap9_revB() ?	\
-			(0xfffffd50 - AT91_BASE_SYS) :	\
-			(0xfffffd60 - AT91_BASE_SYS))
-
-#define AT91CAP9_BASE_ECC	0xffffe200
-#define AT91CAP9_BASE_DMA	0xffffec00
-#define AT91CAP9_BASE_SMC	0xffffe800
-#define AT91CAP9_BASE_DBGU	AT91_BASE_DBGU1
-#define AT91CAP9_BASE_PIOA	0xfffff200
-#define AT91CAP9_BASE_PIOB	0xfffff400
-#define AT91CAP9_BASE_PIOC	0xfffff600
-#define AT91CAP9_BASE_PIOD	0xfffff800
-#define AT91CAP9_BASE_RSTC	0xfffffd00
-#define AT91CAP9_BASE_SHDWC	0xfffffd10
-#define AT91CAP9_BASE_RTT	0xfffffd20
-#define AT91CAP9_BASE_PIT	0xfffffd30
-#define AT91CAP9_BASE_WDT	0xfffffd40
-
-#define AT91_USART0	AT91CAP9_BASE_US0
-#define AT91_USART1	AT91CAP9_BASE_US1
-#define AT91_USART2	AT91CAP9_BASE_US2
-
-
-/*
- * Internal Memory.
- */
-#define AT91CAP9_SRAM_BASE	0x00100000	/* Internal SRAM base address */
-#define AT91CAP9_SRAM_SIZE	(32 * SZ_1K)	/* Internal SRAM size (32Kb) */
-
-#define AT91CAP9_ROM_BASE	0x00400000	/* Internal ROM base address */
-#define AT91CAP9_ROM_SIZE	(32 * SZ_1K)	/* Internal ROM size (32Kb) */
-
-#define AT91CAP9_LCDC_BASE	0x00500000	/* LCD Controller */
-#define AT91CAP9_UDPHS_FIFO	0x00600000	/* USB High Speed Device Port */
-#define AT91CAP9_UHP_BASE	0x00700000	/* USB Host controller */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
deleted file mode 100644
index 4b9d4af..0000000
--- a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9_matrix.h
- *
- *  Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- *  Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- *  Copyright (C) 2006 Atmel Corporation.
- *
- * Memory Controllers (MATRIX, EBI) - System peripherals registers.
- * Based on AT91CAP9 datasheet revision B (Preliminary).
- *
- * 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.
- */
-
-#ifndef AT91CAP9_MATRIX_H
-#define AT91CAP9_MATRIX_H
-
-#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
-#define AT91_MATRIX_MCFG6	(AT91_MATRIX + 0x18)	/* Master Configuration Register 6 */
-#define AT91_MATRIX_MCFG7	(AT91_MATRIX + 0x1C)	/* Master Configuration Register 7 */
-#define AT91_MATRIX_MCFG8	(AT91_MATRIX + 0x20)	/* Master Configuration Register 8 */
-#define AT91_MATRIX_MCFG9	(AT91_MATRIX + 0x24)	/* Master Configuration Register 9 */
-#define AT91_MATRIX_MCFG10	(AT91_MATRIX + 0x28)	/* Master Configuration Register 10 */
-#define AT91_MATRIX_MCFG11	(AT91_MATRIX + 0x2C)	/* Master Configuration Register 11 */
-#define		AT91_MATRIX_ULBT	(7 << 0)	/* Undefined Length Burst Type */
-#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
-#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
-#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
-#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
-#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
-
-#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
-#define AT91_MATRIX_SCFG5	(AT91_MATRIX + 0x54)	/* Slave Configuration Register 5 */
-#define AT91_MATRIX_SCFG6	(AT91_MATRIX + 0x58)	/* Slave Configuration Register 6 */
-#define AT91_MATRIX_SCFG7	(AT91_MATRIX + 0x5C)	/* Slave Configuration Register 7 */
-#define AT91_MATRIX_SCFG8	(AT91_MATRIX + 0x60)	/* Slave Configuration Register 8 */
-#define AT91_MATRIX_SCFG9	(AT91_MATRIX + 0x64)	/* Slave Configuration Register 9 */
-#define		AT91_MATRIX_SLOT_CYCLE		(0xff << 0)	/* Maximum Number of Allowed Cycles for a Burst */
-#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
-#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
-#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
-#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
-#define		AT91_MATRIX_FIXED_DEFMSTR	(0xf  << 18)	/* Fixed Index of Default Master */
-#define		AT91_MATRIX_ARBT		(3    << 24)	/* Arbitration Type */
-#define			AT91_MATRIX_ARBT_ROUND_ROBIN	(0 << 24)
-#define			AT91_MATRIX_ARBT_FIXED_PRIORITY	(1 << 24)
-
-#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRBS0	(AT91_MATRIX + 0x84)	/* Priority Register B for Slave 0 */
-#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRBS1	(AT91_MATRIX + 0x8C)	/* Priority Register B for Slave 1 */
-#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRBS2	(AT91_MATRIX + 0x94)	/* Priority Register B for Slave 2 */
-#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRBS3	(AT91_MATRIX + 0x9C)	/* Priority Register B for Slave 3 */
-#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
-#define AT91_MATRIX_PRBS4	(AT91_MATRIX + 0xA4)	/* Priority Register B for Slave 4 */
-#define AT91_MATRIX_PRAS5	(AT91_MATRIX + 0xA8)	/* Priority Register A for Slave 5 */
-#define AT91_MATRIX_PRBS5	(AT91_MATRIX + 0xAC)	/* Priority Register B for Slave 5 */
-#define AT91_MATRIX_PRAS6	(AT91_MATRIX + 0xB0)	/* Priority Register A for Slave 6 */
-#define AT91_MATRIX_PRBS6	(AT91_MATRIX + 0xB4)	/* Priority Register B for Slave 6 */
-#define AT91_MATRIX_PRAS7	(AT91_MATRIX + 0xB8)	/* Priority Register A for Slave 7 */
-#define AT91_MATRIX_PRBS7	(AT91_MATRIX + 0xBC)	/* Priority Register B for Slave 7 */
-#define AT91_MATRIX_PRAS8	(AT91_MATRIX + 0xC0)	/* Priority Register A for Slave 8 */
-#define AT91_MATRIX_PRBS8	(AT91_MATRIX + 0xC4)	/* Priority Register B for Slave 8 */
-#define AT91_MATRIX_PRAS9	(AT91_MATRIX + 0xC8)	/* Priority Register A for Slave 9 */
-#define AT91_MATRIX_PRBS9	(AT91_MATRIX + 0xCC)	/* Priority Register B for Slave 9 */
-#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
-#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
-#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
-#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
-#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
-#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
-#define		AT91_MATRIX_M6PR		(3 << 24)	/* Master 6 Priority */
-#define		AT91_MATRIX_M7PR		(3 << 28)	/* Master 7 Priority */
-#define		AT91_MATRIX_M8PR		(3 << 0)	/* Master 8 Priority (in Register B) */
-#define		AT91_MATRIX_M9PR		(3 << 4)	/* Master 9 Priority (in Register B) */
-#define		AT91_MATRIX_M10PR		(3 << 8)	/* Master 10 Priority (in Register B) */
-#define		AT91_MATRIX_M11PR		(3 << 12)	/* Master 11 Priority (in Register B) */
-
-#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
-#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
-#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
-#define		AT91_MATRIX_RCB2		(1 << 2)
-#define		AT91_MATRIX_RCB3		(1 << 3)
-#define		AT91_MATRIX_RCB4		(1 << 4)
-#define		AT91_MATRIX_RCB5		(1 << 5)
-#define		AT91_MATRIX_RCB6		(1 << 6)
-#define		AT91_MATRIX_RCB7		(1 << 7)
-#define		AT91_MATRIX_RCB8		(1 << 8)
-#define		AT91_MATRIX_RCB9		(1 << 9)
-#define		AT91_MATRIX_RCB10		(1 << 10)
-#define		AT91_MATRIX_RCB11		(1 << 11)
-
-#define AT91_MPBS0_SFR		(AT91_MATRIX + 0x114)	/* MPBlock Slave 0 Special Function Register */
-#define AT91_MPBS1_SFR		(AT91_MATRIX + 0x11C)	/* MPBlock Slave 1 Special Function Register */
-
-#define AT91_MATRIX_UDPHS	(AT91_MATRIX + 0x118)	/* USBHS Special Function Register [AT91CAP9 only] */
-#define		AT91_MATRIX_SELECT_UDPHS	(0 << 31)	/* select High Speed UDP */
-#define		AT91_MATRIX_SELECT_UDP		(1 << 31)	/* select standard UDP */
-#define		AT91_MATRIX_UDPHS_BYPASS_LOCK	(1 << 30)	/* bypass lock bit */
-
-#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x120)	/* EBI Chip Select Assignment Register */
-#define		AT91_MATRIX_EBI_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
-#define			AT91_MATRIX_EBI_CS1A_SMC		(0 << 1)
-#define			AT91_MATRIX_EBI_CS1A_BCRAMC		(1 << 1)
-#define		AT91_MATRIX_EBI_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
-#define			AT91_MATRIX_EBI_CS3A_SMC		(0 << 3)
-#define			AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
-#define		AT91_MATRIX_EBI_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
-#define			AT91_MATRIX_EBI_CS4A_SMC		(0 << 4)
-#define			AT91_MATRIX_EBI_CS4A_SMC_CF1		(1 << 4)
-#define		AT91_MATRIX_EBI_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
-#define			AT91_MATRIX_EBI_CS5A_SMC		(0 << 5)
-#define			AT91_MATRIX_EBI_CS5A_SMC_CF2		(1 << 5)
-#define		AT91_MATRIX_EBI_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
-#define		AT91_MATRIX_EBI_DQSPDC		(1 << 9)	/* Data Qualifier Strobe Pull-Down Configuration */
-#define		AT91_MATRIX_EBI_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
-#define			AT91_MATRIX_EBI_VDDIOMSEL_1_8V		(0 << 16)
-#define			AT91_MATRIX_EBI_VDDIOMSEL_3_3V		(1 << 16)
-
-#define AT91_MPBS2_SFR		(AT91_MATRIX + 0x12C)	/* MPBlock Slave 2 Special Function Register */
-#define AT91_MPBS3_SFR		(AT91_MATRIX + 0x130)	/* MPBlock Slave 3 Special Function Register */
-#define AT91_APB_SFR		(AT91_MATRIX + 0x134)	/* APB Bridge Special Function Register */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
index e2f8da8..5d4a9f8 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -59,7 +59,6 @@
 #define		AT91_DDRSDRC_TRP	(0xf << 16)		/* Row precharge delay */
 #define		AT91_DDRSDRC_TRRD	(0xf << 20)		/* Active BankA to BankB */
 #define		AT91_DDRSDRC_TWTR	(0x7 << 24)		/* Internal Write to Read delay */
-#define		AT91CAP9_DDRSDRC_TWTR	(1   << 24)		/* Internal Write to Read delay */
 #define		AT91_DDRSDRC_RED_WRRD	(0x1 << 27)		/* Reduce Write to Read Delay [SAM9 Only] */
 #define		AT91_DDRSDRC_TMRD	(0xf << 28)		/* Load mode to active/refresh delay */
 
@@ -76,7 +75,6 @@
 #define		AT91_DDRSDRC_TRTP	(0x7  << 12)		/* Read to Precharge delay */
 
 #define AT91_DDRSDRC_LPR	0x1C	/* Low Power Register */
-#define AT91CAP9_DDRSDRC_LPR	0x18	/* Low Power Register */
 #define		AT91_DDRSDRC_LPCB	(3 << 0)		/* Low-power Configurations */
 #define			AT91_DDRSDRC_LPCB_DISABLE		0
 #define			AT91_DDRSDRC_LPCB_SELF_REFRESH		1
@@ -94,11 +92,9 @@
 #define		AT91_DDRSDRC_UPD_MR	(3 << 20)	 /* Update load mode register and extended mode register */
 
 #define AT91_DDRSDRC_MDR	0x20	/* Memory Device Register */
-#define AT91CAP9_DDRSDRC_MDR	0x1C	/* Memory Device Register */
 #define		AT91_DDRSDRC_MD		(3 << 0)		/* Memory Device Type */
 #define			AT91_DDRSDRC_MD_SDR		0
 #define			AT91_DDRSDRC_MD_LOW_POWER_SDR	1
-#define			AT91CAP9_DDRSDRC_MD_DDR		2
 #define			AT91_DDRSDRC_MD_LOW_POWER_DDR	3
 #define			AT91_DDRSDRC_MD_DDR2		6	/* [SAM9 Only] */
 #define		AT91_DDRSDRC_DBW	(1 << 4)		/* Data Bus Width */
@@ -106,16 +102,10 @@
 #define			AT91_DDRSDRC_DBW_16BITS		(1 <<  4)
 
 #define AT91_DDRSDRC_DLL	0x24	/* DLL Information Register */
-#define AT91CAP9_DDRSDRC_DLL	0x20	/* DLL Information Register */
 #define		AT91_DDRSDRC_MDINC	(1 << 0)		/* Master Delay increment */
 #define		AT91_DDRSDRC_MDDEC	(1 << 1)		/* Master Delay decrement */
 #define		AT91_DDRSDRC_MDOVF	(1 << 2)		/* Master Delay Overflow */
-#define		AT91CAP9_DDRSDRC_SDCOVF	(1 << 3)		/* Slave Delay Correction Overflow */
-#define		AT91CAP9_DDRSDRC_SDCUDF	(1 << 4)		/* Slave Delay Correction Underflow */
-#define		AT91CAP9_DDRSDRC_SDERF	(1 << 5)		/* Slave Delay Correction error */
 #define		AT91_DDRSDRC_MDVAL	(0xff <<  8)		/* Master Delay value */
-#define		AT91CAP9_DDRSDRC_SDVAL	(0xff << 16)		/* Slave Delay value */
-#define		AT91CAP9_DDRSDRC_SDCVAL	(0xff << 24)		/* Slave Delay Correction value */
 
 #define AT91_DDRSDRC_HS		0x2C	/* High Speed Register [SAM9 Only] */
 #define		AT91_DDRSDRC_DIS_ATCP_RD	(1 << 2)	/* Anticip read access is disabled */
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h
new file mode 100644
index 0000000..8476871
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h
@@ -0,0 +1,80 @@
+/*
+ * Chip-specific header file for the AT91SAM9x5 family
+ *
+ *  Copyright (C) 2009-2012 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91SAM9x5 datasheet.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef AT91SAM9X5_H
+#define AT91SAM9X5_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9X5_ID_PIOAB	2	/* Parallel I/O Controller A and B */
+#define AT91SAM9X5_ID_PIOCD	3	/* Parallel I/O Controller C and D */
+#define AT91SAM9X5_ID_SMD	4	/* SMD Soft Modem (SMD) */
+#define AT91SAM9X5_ID_USART0	5	/* USART 0 */
+#define AT91SAM9X5_ID_USART1	6	/* USART 1 */
+#define AT91SAM9X5_ID_USART2	7	/* USART 2 */
+#define AT91SAM9X5_ID_USART3	8	/* USART 3 */
+#define AT91SAM9X5_ID_TWI0	9	/* Two-Wire Interface 0 */
+#define AT91SAM9X5_ID_TWI1	10	/* Two-Wire Interface 1 */
+#define AT91SAM9X5_ID_TWI2	11	/* Two-Wire Interface 2 */
+#define AT91SAM9X5_ID_MCI0	12	/* High Speed Multimedia Card Interface 0 */
+#define AT91SAM9X5_ID_SPI0	13	/* Serial Peripheral Interface 0 */
+#define AT91SAM9X5_ID_SPI1	14	/* Serial Peripheral Interface 1 */
+#define AT91SAM9X5_ID_UART0	15	/* UART 0 */
+#define AT91SAM9X5_ID_UART1	16	/* UART 1 */
+#define AT91SAM9X5_ID_TCB	17	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
+#define AT91SAM9X5_ID_PWM	18	/* Pulse Width Modulation Controller */
+#define AT91SAM9X5_ID_ADC	19	/* ADC Controller */
+#define AT91SAM9X5_ID_DMA0	20	/* DMA Controller 0 */
+#define AT91SAM9X5_ID_DMA1	21	/* DMA Controller 1 */
+#define AT91SAM9X5_ID_UHPHS	22	/* USB Host High Speed */
+#define AT91SAM9X5_ID_UDPHS	23	/* USB Device High Speed */
+#define AT91SAM9X5_ID_EMAC0	24	/* Ethernet MAC0 */
+#define AT91SAM9X5_ID_LCDC	25	/* LCD Controller */
+#define AT91SAM9X5_ID_ISI	25	/* Image Sensor Interface */
+#define AT91SAM9X5_ID_MCI1	26	/* High Speed Multimedia Card Interface 1 */
+#define AT91SAM9X5_ID_EMAC1	27	/* Ethernet MAC1 */
+#define AT91SAM9X5_ID_SSC	28	/* Synchronous Serial Controller */
+#define AT91SAM9X5_ID_CAN0	29	/* CAN Controller 0 */
+#define AT91SAM9X5_ID_CAN1	30	/* CAN Controller 1 */
+#define AT91SAM9X5_ID_IRQ0	31	/* Advanced Interrupt Controller */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9X5_BASE_USART0	0xf801c000
+#define AT91SAM9X5_BASE_USART1	0xf8020000
+#define AT91SAM9X5_BASE_USART2	0xf8024000
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_DDRSDRC0	(0xffffe800 - AT91_BASE_SYS)
+#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
+
+/*
+ * Base addresses for early serial code (uncompress.h)
+ */
+#define AT91_DBGU	AT91_BASE_DBGU0
+#define AT91_USART0	AT91SAM9X5_BASE_USART0
+#define AT91_USART1	AT91SAM9X5_BASE_USART1
+#define AT91_USART2	AT91SAM9X5_BASE_USART2
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9X5_SRAM_BASE	0x00300000	/* Internal SRAM base address */
+#define AT91SAM9X5_SRAM_SIZE	SZ_32K		/* Internal SRAM size (32Kb) */
+
+#define AT91SAM9X5_ROM_BASE	0x00400000	/* Internal ROM base address */
+#define AT91SAM9X5_ROM_SIZE	SZ_64K		/* Internal ROM size (64Kb) */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h
new file mode 100644
index 0000000..a606d39
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h
@@ -0,0 +1,53 @@
+/*
+ * Matrix-centric header file for the AT91SAM9x5 family
+ *
+ *  Copyright (C) 2009-2012 Atmel Corporation.
+ *
+ * Only EBI related registers.
+ * Write Protect register definitions may be useful.
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#ifndef AT91SAM9X5_MATRIX_H
+#define AT91SAM9X5_MATRIX_H
+
+#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x120)	/* EBI Chip Select Assignment Register */
+#define		AT91_MATRIX_EBI_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_EBI_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_EBI_CS1A_SDRAMC		(1 << 1)
+#define		AT91_MATRIX_EBI_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_EBI_CS3A_SMC		(0 << 3)
+#define			AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH	(1 << 3)
+#define		AT91_MATRIX_EBI_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+#define			AT91_MATRIX_EBI_DBPU_ON			(0 << 8)
+#define			AT91_MATRIX_EBI_DBPU_OFF		(1 << 8)
+#define		AT91_MATRIX_EBI_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
+#define			AT91_MATRIX_EBI_VDDIOMSEL_1_8V		(0 << 16)
+#define			AT91_MATRIX_EBI_VDDIOMSEL_3_3V		(1 << 16)
+#define		AT91_MATRIX_EBI_EBI_IOSR	(1 << 17)	/* EBI I/O slew rate selection */
+#define			AT91_MATRIX_EBI_EBI_IOSR_REDUCED	(0 << 17)
+#define			AT91_MATRIX_EBI_EBI_IOSR_NORMAL		(1 << 17)
+#define		AT91_MATRIX_EBI_DDR_IOSR	(1 << 18)	/* DDR2 dedicated port I/O slew rate selection */
+#define			AT91_MATRIX_EBI_DDR_IOSR_REDUCED	(0 << 18)
+#define			AT91_MATRIX_EBI_DDR_IOSR_NORMAL		(1 << 18)
+#define		AT91_MATRIX_NFD0_SELECT		(1 << 24)	/* NAND Flash Data Bus Selection */
+#define			AT91_MATRIX_NFD0_ON_D0			(0 << 24)
+#define			AT91_MATRIX_NFD0_ON_D16			(1 << 24)
+#define		AT91_MATRIX_DDR_MP_EN		(1 << 25)	/* DDR Multi-port Enable */
+#define			AT91_MATRIX_MP_OFF			(0 << 25)
+#define			AT91_MATRIX_MP_ON			(1 << 25)
+
+#define AT91_MATRIX_WPMR	(AT91_MATRIX + 0x1E4)	/* Write Protect Mode Register */
+#define		AT91_MATRIX_WPMR_WPEN		(1 << 0)	/* Write Protect ENable */
+#define			AT91_MATRIX_WPMR_WP_WPDIS		(0 << 0)
+#define			AT91_MATRIX_WPMR_WP_WPEN		(1 << 0)
+#define		AT91_MATRIX_WPMR_WPKEY		(0xFFFFFF << 8)	/* Write Protect KEY */
+
+#define AT91_MATRIX_WPSR	(AT91_MATRIX + 0x1E8)	/* Write Protect Status Register */
+#define		AT91_MATRIX_WPSR_WPVS		(1 << 0)	/* Write Protect Violation Status */
+#define			AT91_MATRIX_WPSR_NO_WPV		(0 << 0)
+#define			AT91_MATRIX_WPSR_WPV		(1 << 0)
+#define		AT91_MATRIX_WPSR_WPVSRC		(0xFFFF << 8)	/* Write Protect Violation Source */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 3b33f07..dc8d6d4 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -107,6 +107,8 @@ struct atmel_nand_data {
 	u8		ale;		/* address line number connected to ALE */
 	u8		cle;		/* address line number connected to CLE */
 	u8		bus_width_16;	/* buswidth is 16 bit */
+	u8		correction_cap; /* PMECC correction capability */
+	u16		sector_size;    /* Sector size for PMECC */
 	struct mtd_partition *parts;
 	unsigned int	num_parts;
 };
@@ -179,7 +181,9 @@ extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
 extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
 
  /* ISI */
-extern void __init at91_add_device_isi(void);
+struct isi_platform_data;
+extern void __init at91_add_device_isi(struct isi_platform_data *data,
+		bool use_pck_as_mck);
 
  /* Touchscreen Controller */
 struct at91_tsadcc_data {
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index f6ce936..0118c33 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -25,7 +25,6 @@
 #define ARCH_ID_AT91SAM9G45MRL	0x819b05a2	/* aka 9G45-ES2 & non ES lots */
 #define ARCH_ID_AT91SAM9G45ES	0x819b05a1	/* 9G45-ES (Engineering Sample) */
 #define ARCH_ID_AT91SAM9X5	0x819a05a0
-#define ARCH_ID_AT91CAP9	0x039A03A0
 
 #define ARCH_ID_AT91SAM9XE128	0x329973a0
 #define ARCH_ID_AT91SAM9XE256	0x329a93a0
@@ -51,10 +50,6 @@
 #define ARCH_FAMILY_AT91SAM9	0x01900000
 #define ARCH_FAMILY_AT91SAM9XE	0x02900000
 
-/* PMC revision */
-#define ARCH_REVISION_CAP9_B	0x399
-#define ARCH_REVISION_CAP9_C	0x601
-
 /* RM9200 type */
 #define ARCH_REVISON_9200_BGA	(0 << 0)
 #define ARCH_REVISON_9200_PQFP	(1 << 0)
@@ -63,9 +58,6 @@ enum at91_soc_type {
 	/* 920T */
 	AT91_SOC_RM9200,
 
-	/* CAP */
-	AT91_SOC_CAP9,
-
 	/* SAM92xx */
 	AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263,
 
@@ -86,9 +78,6 @@ enum at91_soc_subtype {
 	/* RM9200 */
 	AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP,
 
-	/* CAP9 */
-	AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C,
-
 	/* SAM9260 */
 	AT91_SOC_SAM9XE,
 
@@ -195,16 +184,6 @@ static inline int at91_soc_is_detected(void)
 #define cpu_is_at91sam9x25()	(0)
 #endif
 
-#ifdef CONFIG_ARCH_AT91CAP9
-#define cpu_is_at91cap9()	(at91_soc_initdata.type == AT91_SOC_CAP9)
-#define cpu_is_at91cap9_revB()	(at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B)
-#define cpu_is_at91cap9_revC()	(at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C)
-#else
-#define cpu_is_at91cap9()	(0)
-#define cpu_is_at91cap9_revB()	(0)
-#define cpu_is_at91cap9_revC()	(0)
-#endif
-
 /*
  * Since this is ARM, we will never run on any AVR32 CPU. But these
  * definitions may reduce clutter in common drivers.
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index 2d0e4e9..fd7dce4 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -19,7 +19,7 @@
 /* DBGU base */
 /* rm9200, 9260/9g20, 9261/9g10, 9rl */
 #define AT91_BASE_DBGU0	0xfffff200
-/* 9263, 9g45, cap9 */
+/* 9263, 9g45 */
 #define AT91_BASE_DBGU1	0xffffee00
 
 #if defined(CONFIG_ARCH_AT91RM9200)
@@ -34,8 +34,8 @@
 #include <mach/at91sam9rl.h>
 #elif defined(CONFIG_ARCH_AT91SAM9G45)
 #include <mach/at91sam9g45.h>
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9.h>
+#elif defined(CONFIG_ARCH_AT91SAM9X5)
+#include <mach/at91sam9x5.h>
 #elif defined(CONFIG_ARCH_AT91X40)
 #include <mach/at91x40.h>
 #else
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h
deleted file mode 100644
index cbd64f3..0000000
--- a/arch/arm/mach-at91/include/mach/system.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/system.h
- *
- *  Copyright (C) 2003 SAN People
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <mach/hardware.h>
-#include <mach/at91_st.h>
-#include <mach/at91_dbgu.h>
-#include <mach/at91_pmc.h>
-
-static inline void arch_idle(void)
-{
-	/*
-	 * Disable the processor clock.  The processor will be automatically
-	 * re-enabled by an interrupt or by a reset.
-	 */
-#ifdef AT91_PS
-	at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
-#else
-	at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-#endif
-#ifndef CONFIG_CPU_ARM920T
-	/*
-	 * Set the processor (CP15) into 'Wait for Interrupt' mode.
-	 * Post-RM9200 processors need this in conjunction with the above
-	 * to save power when idle.
-	 */
-	cpu_do_idle();
-#endif
-}
-
-#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 1606379..d554e67 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -150,11 +150,6 @@ static int at91_pm_verify_clocks(void)
 			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
-	} else if (cpu_is_at91cap9()) {
-		if ((scsr & AT91CAP9_PMC_UHP) != 0) {
-			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
-			return 0;
-		}
 	}
 
 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
@@ -203,7 +198,6 @@ extern u32 at91_slow_clock_sz;
 
 static int at91_pm_enter(suspend_state_t state)
 {
-	u32 saved_lpr;
 	at91_gpio_suspend();
 	at91_irq_suspend();
 
@@ -259,16 +253,7 @@ static int at91_pm_enter(suspend_state_t state)
 			 * For ARM 926 based chips, this requirement is weaker
 			 * as at91sam9 can access a RAM in self-refresh mode.
 			 */
-			asm volatile (	"mov r0, #0\n\t"
-					"b 1f\n\t"
-					".align 5\n\t"
-					"1: mcr p15, 0, r0, c7, c10, 4\n\t"
-					: /* no output */
-					: /* no input */
-					: "r0");
-			saved_lpr = sdram_selfrefresh_enable();
-			wait_for_interrupt_enable();
-			sdram_selfrefresh_disable(saved_lpr);
+			at91_standby();
 			break;
 
 		case PM_SUSPEND_ON:
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 7eb40d2..bba9ce1 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -1,3 +1,16 @@
+/*
+ * AT91 Power Management
+ *
+ * Copyright (C) 2005 David Brownell
+ *
+ * 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.
+ */
+#ifndef __ARCH_ARM_MACH_AT91_PM
+#define __ARCH_ARM_MACH_AT91_PM
+
 #ifdef CONFIG_ARCH_AT91RM9200
 #include <mach/at91rm9200_mc.h>
 
@@ -11,36 +24,25 @@
  * still in self-refresh is "not recommended", but seems to work.
  */
 
-static inline u32 sdram_selfrefresh_enable(void)
-{
-	u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
-
-	at91_sys_write(AT91_SDRAMC_LPR, 0);
-	at91_sys_write(AT91_SDRAMC_SRR, 1);
-	return saved_lpr;
-}
-
-#define sdram_selfrefresh_disable(saved_lpr)	at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
-#define wait_for_interrupt_enable()		asm volatile ("mcr p15, 0, %0, c7, c0, 4" \
-								: : "r" (0))
-
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91sam9_ddrsdr.h>
-
-
-static inline u32 sdram_selfrefresh_enable(void)
+static inline void at91rm9200_standby(void)
 {
-	u32 saved_lpr, lpr;
-
-	saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR);
-
-	lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
-	at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
-	return saved_lpr;
+	u32 lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+	asm volatile(
+		"b    1f\n\t"
+		".align    5\n\t"
+		"1:  mcr    p15, 0, %0, c7, c10, 4\n\t"
+		"    str    %0, [%1, %2]\n\t"
+		"    str    %3, [%1, %4]\n\t"
+		"    mcr    p15, 0, %0, c7, c0, 4\n\t"
+		"    str    %5, [%1, %2]"
+		:
+		: "r" (0), "r" (AT91_BASE_SYS), "r" (AT91_SDRAMC_LPR),
+		  "r" (1), "r" (AT91_SDRAMC_SRR),
+		  "r" (lpr));
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)	at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr)
-#define wait_for_interrupt_enable()		cpu_do_idle()
+#define at91_standby at91rm9200_standby
 
 #elif defined(CONFIG_ARCH_AT91SAM9G45)
 #include <mach/at91sam9_ddrsdr.h>
@@ -48,14 +50,12 @@ static inline u32 sdram_selfrefresh_enable(void)
 /* We manage both DDRAM/SDRAM controllers, we need more than one value to
  * remember.
  */
-static u32 saved_lpr1;
-
-static inline u32 sdram_selfrefresh_enable(void)
+static inline void at91sam9g45_standby(void)
 {
-	/* Those tow values allow us to delay self-refresh activation
+	/* Those two values allow us to delay self-refresh activation
 	 * to the maximum. */
 	u32 lpr0, lpr1;
-	u32 saved_lpr0;
+	u32 saved_lpr0, saved_lpr1;
 
 	saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
 	lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
@@ -69,15 +69,13 @@ static inline u32 sdram_selfrefresh_enable(void)
 	at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
 	at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
 
-	return saved_lpr0;
+	cpu_do_idle();
+
+	at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0);
+	at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1);
 }
 
-#define sdram_selfrefresh_disable(saved_lpr0)	\
-	do { \
-		at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \
-		at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \
-	} while (0)
-#define wait_for_interrupt_enable()		cpu_do_idle()
+#define at91_standby at91sam9g45_standby
 
 #else
 #include <mach/at91sam9_sdramc.h>
@@ -90,18 +88,23 @@ static inline u32 sdram_selfrefresh_enable(void)
 #warning Assuming EB1 SDRAM controller is *NOT* used
 #endif
 
-static inline u32 sdram_selfrefresh_enable(void)
+static inline void at91sam9_standby(void)
 {
 	u32 saved_lpr, lpr;
 
 	saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR);
 
 	lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
-	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
-	return saved_lpr;
+	at91_ramc_write(0, AT91_SDRAMC_LPR, lpr |
+			AT91_SDRAMC_LPCB_SELF_REFRESH);
+
+	cpu_do_idle();
+
+	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr);
 }
 
-#define sdram_selfrefresh_disable(saved_lpr)	at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr)
-#define wait_for_interrupt_enable()		cpu_do_idle()
+#define at91_standby at91sam9_standby
+
+#endif
 
 #endif
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 92dfb84..f8539a8 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -18,8 +18,7 @@
 
 #if defined(CONFIG_ARCH_AT91RM9200)
 #include <mach/at91rm9200_mc.h>
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-	|| defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
 #include <mach/at91sam9_ddrsdr.h>
 #else
 #include <mach/at91sam9_sdramc.h>
@@ -130,8 +129,7 @@ ENTRY(at91_slow_clock)
 	/* Put SDRAM in self-refresh mode */
 	mov	r3, #1
 	str	r3, [r2, #AT91_SDRAMC_SRR]
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-	|| defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
 
 	/* prepare for DDRAM self-refresh mode */
 	ldr	r3, [r2, #AT91_DDRSDRC_LPR]
@@ -263,8 +261,7 @@ ENTRY(at91_slow_clock)
 
 #ifdef CONFIG_ARCH_AT91RM9200
 	/* Do nothing - self-refresh is automatically disabled. */
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-	|| defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
 	/* Restore LPR on AT91 with DDRAM */
 	ldr	r3, .saved_sam9_lpr
 	str	r3, [r2, #AT91_DDRSDRC_LPR]
@@ -305,8 +302,7 @@ ENTRY(at91_slow_clock)
 #ifdef CONFIG_ARCH_AT91RM9200
 .at91_va_base_sdramc:
 	.word AT91_VA_BASE_SYS
-#elif defined(CONFIG_ARCH_AT91CAP9) \
-	|| defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
 .at91_va_base_sdramc:
 	.word AT91_VA_BASE_SYS + AT91_DDRSDRC0
 #else
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 69d3fc4..620c67e 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -86,20 +86,6 @@ static void __init soc_detect(u32 dbgu_base)
 	socid = cidr & ~AT91_CIDR_VERSION;
 
 	switch (socid) {
-	case ARCH_ID_AT91CAP9: {
-#ifdef CONFIG_AT91_PMC_UNIT
-		u32 pmc_ver = at91_sys_read(AT91_PMC_VER);
-
-		if (pmc_ver == ARCH_REVISION_CAP9_B)
-			at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B;
-		else if (pmc_ver == ARCH_REVISION_CAP9_C)
-			at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C;
-#endif
-		at91_soc_initdata.type = AT91_SOC_CAP9;
-		at91_boot_soc = at91cap9_soc;
-		break;
-	}
-
 	case ARCH_ID_AT91RM9200:
 		at91_soc_initdata.type = AT91_SOC_RM9200;
 		at91_boot_soc = at91rm9200_soc;
@@ -200,7 +186,6 @@ static void __init soc_detect(u32 dbgu_base)
 
 static const char *soc_name[] = {
 	[AT91_SOC_RM9200]	= "at91rm9200",
-	[AT91_SOC_CAP9]		= "at91cap9",
 	[AT91_SOC_SAM9260]	= "at91sam9260",
 	[AT91_SOC_SAM9261]	= "at91sam9261",
 	[AT91_SOC_SAM9263]	= "at91sam9263",
@@ -221,8 +206,6 @@ EXPORT_SYMBOL(at91_get_soc_type);
 static const char *soc_subtype_name[] = {
 	[AT91_SOC_RM9200_BGA]	= "at91rm9200 BGA",
 	[AT91_SOC_RM9200_PQFP]	= "at91rm9200 PQFP",
-	[AT91_SOC_CAP9_REV_B]	= "at91cap9 revB",
-	[AT91_SOC_CAP9_REV_C]	= "at91cap9 revC",
 	[AT91_SOC_SAM9XE]	= "at91sam9xe",
 	[AT91_SOC_SAM9G45ES]	= "at91sam9g45es",
 	[AT91_SOC_SAM9M10]	= "at91sam9m10",
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 4588ae6..5db4aa4 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -13,7 +13,6 @@ struct at91_init_soc {
 };
 
 extern struct at91_init_soc at91_boot_soc;
-extern struct at91_init_soc at91cap9_soc;
 extern struct at91_init_soc at91rm9200_soc;
 extern struct at91_init_soc at91sam9260_soc;
 extern struct at91_init_soc at91sam9261_soc;
@@ -27,10 +26,6 @@ static inline int at91_soc_is_enabled(void)
 	return at91_boot_soc.init != NULL;
 }
 
-#if !defined(CONFIG_ARCH_AT91CAP9)
-#define at91cap9_soc	at91_boot_soc
-#endif
-
 #if !defined(CONFIG_ARCH_AT91RM9200)
 #define at91rm9200_soc	at91_boot_soc
 #endif
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index 6b67b7e..22e4e0a 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -52,27 +52,8 @@
 #include <mach/csp/chipcHw_inline.h>
 #include <mach/csp/tmrHw_reg.h>
 
-#define AMBA_DEVICE(name, initname, base, plat, size)       \
-static struct amba_device name##_device = {     \
-   .dev = {                                     \
-      .coherent_dma_mask = ~0,                  \
-      .init_name = initname,                    \
-      .platform_data = plat                     \
-   },                                           \
-   .res = {                                     \
-      .start = MM_ADDR_IO_##base,               \
-		.end = MM_ADDR_IO_##base + (size) - 1,    \
-      .flags = IORESOURCE_MEM                   \
-   },                                           \
-   .dma_mask = ~0,                              \
-   .irq = {                                     \
-      IRQ_##base                                \
-   }                                            \
-}
-
-
-AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K);
-AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K);
+static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL);
+static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL);
 
 static struct clk pll1_clk = {
 	.name = "PLL1",
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
index 1024396..e5fd241 100644
--- a/arch/arm/mach-bcmring/dma.c
+++ b/arch/arm/mach-bcmring/dma.c
@@ -35,7 +35,6 @@
 
 #include <linux/pfn.h>
 #include <linux/atomic.h>
-#include <linux/sched.h>
 #include <mach/dma.h>
 
 /* ---- Public Variables ------------------------------------------------- */
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h
deleted file mode 100644
index cb78250..0000000
--- a/arch/arm/mach-bcmring/include/mach/system.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index ab1711b..8736c1a 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -225,3 +225,19 @@ void clps711x_restart(char mode, const char *cmd)
 {
 	soft_restart(0);
 }
+
+static void clps711x_idle(void)
+{
+	clps_writel(1, HALT);
+	__asm__ __volatile__(
+	"mov    r0, r0\n\
+	mov     r0, r0");
+}
+
+static int __init clps711x_idle_init(void)
+{
+	arm_pm_idle = clps711x_idle;
+	return 0;
+}
+
+arch_initcall(clps711x_idle_init);
diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h
deleted file mode 100644
index 23d6ef8..0000000
--- a/arch/arm/mach-clps711x/include/mach/system.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  arch/arm/mach-clps711x/include/mach/system.h
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/hardware/clps7111.h>
-
-static inline void arch_idle(void)
-{
-	clps_writel(1, HALT);
-	__asm__ __volatile__(
-	"mov	r0, r0\n\
-	mov	r0, r0");
-}
-
-#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h
deleted file mode 100644
index 9e56b7d..0000000
--- a/arch/arm/mach-cns3xxx/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2000 Deep Blue Solutions Ltd
- * Copyright 2003 ARM Limited
- * Copyright 2008 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- */
-
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-#include <asm/proc-fns.h>
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
deleted file mode 100644
index fcb7a01..0000000
--- a/arch/arm/mach-davinci/include/mach/system.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * DaVinci system defines
- *
- * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <mach/common.h>
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index e1969ce..75da315 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -19,11 +19,14 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 
-#include <mach/hardware.h>
+#include <asm/sched_clock.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
+
 #include <mach/cputype.h>
+#include <mach/hardware.h>
 #include <mach/time.h>
+
 #include "clock.h"
 
 static struct clock_event_device clockevent_davinci;
@@ -272,19 +275,9 @@ static cycle_t read_cycles(struct clocksource *cs)
 	return (cycles_t)timer32_read(t);
 }
 
-/*
- * Kernel assumes that sched_clock can be called early but may not have
- * things ready yet.
- */
-static cycle_t read_dummy(struct clocksource *cs)
-{
-	return 0;
-}
-
-
 static struct clocksource clocksource_davinci = {
 	.rating		= 300,
-	.read		= read_dummy,
+	.read		= read_cycles,
 	.mask		= CLOCKSOURCE_MASK(32),
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
@@ -292,12 +285,9 @@ static struct clocksource clocksource_davinci = {
 /*
  * Overwrite weak default sched_clock with something more precise
  */
-unsigned long long notrace sched_clock(void)
+static u32 notrace davinci_read_sched_clock(void)
 {
-	const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
-
-	return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
-				clocksource_davinci.shift);
+	return timer32_read(&timers[TID_CLOCKSOURCE]);
 }
 
 /*
@@ -397,12 +387,14 @@ static void __init davinci_timer_init(void)
 	davinci_clock_tick_rate = clk_get_rate(timer_clk);
 
 	/* setup clocksource */
-	clocksource_davinci.read = read_cycles;
 	clocksource_davinci.name = id_to_name[clocksource_id];
 	if (clocksource_register_hz(&clocksource_davinci,
 				    davinci_clock_tick_rate))
 		printk(err, clocksource_davinci.name);
 
+	setup_sched_clock(davinci_read_sched_clock, 32,
+			  davinci_clock_tick_rate);
+
 	/* setup clockevent */
 	clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
 	clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
diff --git a/arch/arm/mach-dove/include/mach/system.h b/arch/arm/mach-dove/include/mach/system.h
deleted file mode 100644
index 3027954..0000000
--- a/arch/arm/mach-dove/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-dove/include/mach/system.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 294aad0..e400d75 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -30,10 +30,7 @@
 
 #include <asm/mach/time.h>
 
-#define IRQ_MASK		0xfe000000	/* read */
-#define IRQ_MSET		0xfe000000	/* write */
-#define IRQ_STAT		0xff000000	/* read */
-#define IRQ_MCLR		0xff000000	/* write */
+#include "core.h"
 
 static void ebsa110_mask_irq(struct irq_data *d)
 {
@@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = {
 	{	/* IRQ_STAT/IRQ_MCLR */
 		.virtual	= IRQ_STAT,
 		.pfn		= __phys_to_pfn(TRICK4_PHYS),
-		.length		= PGDIR_SIZE,
+		.length		= TRICK4_SIZE,
 		.type		= MT_DEVICE
 	}, {	/* IRQ_MASK/IRQ_MSET */
 		.virtual	= IRQ_MASK,
 		.pfn		= __phys_to_pfn(TRICK3_PHYS),
-		.length		= PGDIR_SIZE,
+		.length		= TRICK3_SIZE,
 		.type		= MT_DEVICE
 	}, {	/* SOFT_BASE */
 		.virtual	= SOFT_BASE,
 		.pfn		= __phys_to_pfn(TRICK1_PHYS),
-		.length		= PGDIR_SIZE,
+		.length		= TRICK1_SIZE,
 		.type		= MT_DEVICE
 	}, {	/* PIT_BASE */
 		.virtual	= PIT_BASE,
 		.pfn		= __phys_to_pfn(TRICK0_PHYS),
-		.length		= PGDIR_SIZE,
+		.length		= TRICK0_SIZE,
 		.type		= MT_DEVICE
 	},
 
@@ -271,8 +268,33 @@ static struct platform_device *ebsa110_devices[] = {
 	&am79c961_device,
 };
 
+/*
+ * EBSA110 idling methodology:
+ *
+ * We can not execute the "wait for interrupt" instruction since that
+ * will stop our MCLK signal (which provides the clock for the glue
+ * logic, and therefore the timer interrupt).
+ *
+ * Instead, we spin, polling the IRQ_STAT register for the occurrence
+ * of any interrupt with core clock down to the memory clock.
+ */
+static void ebsa110_idle(void)
+{
+	const char *irq_stat = (char *)0xff000000;
+
+	/* disable clock switching */
+	asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
+
+	/* wait for an interrupt to occur */
+	while (!*irq_stat);
+
+	/* enable clock switching */
+	asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
+}
+
 static int __init ebsa110_init(void)
 {
+	arm_pm_idle = ebsa110_idle;
 	return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
 }
 
diff --git a/arch/arm/mach-ebsa110/core.h b/arch/arm/mach-ebsa110/core.h
new file mode 100644
index 0000000..c93c9e4
--- /dev/null
+++ b/arch/arm/mach-ebsa110/core.h
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (C) 1996-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the core hardware definitions of the EBSA-110.
+ */
+#ifndef CORE_H
+#define CORE_H
+
+/* Physical addresses/sizes */
+#define ISAMEM_PHYS		0xe0000000
+#define ISAMEM_SIZE		0x10000000
+
+#define ISAIO_PHYS		0xf0000000
+#define ISAIO_SIZE		PGDIR_SIZE
+
+#define TRICK0_PHYS		0xf2000000
+#define TRICK0_SIZE		PGDIR_SIZE
+#define TRICK1_PHYS		0xf2400000
+#define TRICK1_SIZE		PGDIR_SIZE
+#define TRICK2_PHYS		0xf2800000
+#define TRICK3_PHYS		0xf2c00000
+#define TRICK3_SIZE		PGDIR_SIZE
+#define TRICK4_PHYS		0xf3000000
+#define TRICK4_SIZE		PGDIR_SIZE
+#define TRICK5_PHYS		0xf3400000
+#define TRICK6_PHYS		0xf3800000
+#define TRICK7_PHYS		0xf3c00000
+
+/* Virtual addresses */
+#define PIT_BASE		0xfc000000	/* trick 0 */
+#define SOFT_BASE		0xfd000000	/* trick 1 */
+#define IRQ_MASK		0xfe000000	/* trick 3 - read */
+#define IRQ_MSET		0xfe000000	/* trick 3 - write */
+#define IRQ_STAT		0xff000000	/* trick 4 - read */
+#define IRQ_MCLR		0xff000000	/* trick 4 - write */
+
+#endif
diff --git a/arch/arm/mach-ebsa110/include/mach/hardware.h b/arch/arm/mach-ebsa110/include/mach/hardware.h
index 4b2fb77..f4e5407 100644
--- a/arch/arm/mach-ebsa110/include/mach/hardware.h
+++ b/arch/arm/mach-ebsa110/include/mach/hardware.h
@@ -12,48 +12,9 @@
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-/*
- * The EBSA110 has a weird "ISA IO" region:
- *
- * Region 0 (addr = 0xf0000000 + io << 2)
- * --------------------------------------------------------
- * Physical region	IO region
- * f0000fe0 - f0000ffc	3f8 - 3ff  ttyS0
- * f0000e60 - f0000e64	398 - 399
- * f0000de0 - f0000dfc	378 - 37f  lp0
- * f0000be0 - f0000bfc	2f8 - 2ff  ttyS1
- *
- * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
- * --------------------------------------------------------
- * Physical region	IO region
- * f00014f1             a79        pnp write data
- * f00007c0 - f00007c1	3e0 - 3e1  pcmcia
- * f00004f1		279        pnp address
- * f0000440 - f000046c  220 - 236  eth0
- * f0000405		203        pnp read data
- */
-
-#define ISAMEM_PHYS		0xe0000000
-#define ISAMEM_SIZE		0x10000000
-
-#define ISAIO_PHYS		0xf0000000
-#define ISAIO_SIZE		PGDIR_SIZE
-
-#define TRICK0_PHYS		0xf2000000
-#define TRICK1_PHYS		0xf2400000
-#define TRICK2_PHYS		0xf2800000
-#define TRICK3_PHYS		0xf2c00000
-#define TRICK4_PHYS		0xf3000000
-#define TRICK5_PHYS		0xf3400000
-#define TRICK6_PHYS		0xf3800000
-#define TRICK7_PHYS		0xf3c00000
-
 #define ISAMEM_BASE		0xe0000000
 #define ISAIO_BASE		0xf0000000
 
-#define PIT_BASE		0xfc000000
-#define SOFT_BASE		0xfd000000
-
 /*
  * RAM definitions
  */
diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h
deleted file mode 100644
index 2e4af65..0000000
--- a/arch/arm/mach-ebsa110/include/mach/system.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  arch/arm/mach-ebsa110/include/mach/system.h
- *
- *  Copyright (C) 1996-2000 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-/*
- * EBSA110 idling methodology:
- *
- * We can not execute the "wait for interrupt" instruction since that
- * will stop our MCLK signal (which provides the clock for the glue
- * logic, and therefore the timer interrupt).
- *
- * Instead, we spin, polling the IRQ_STAT register for the occurrence
- * of any interrupt with core clock down to the memory clock.
- */
-static inline void arch_idle(void)
-{
-	const char *irq_stat = (char *)0xff000000;
-
-	/* disable clock switching */
-	asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
-
-	/* wait for an interrupt to occur */
-	while (!*irq_stat);
-
-	/* enable clock switching */
-	asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
-}
-
-#endif
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index c52e304..756cc37 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -177,6 +177,26 @@ void writesl(void __iomem *addr, const void *data, int len)
 }
 EXPORT_SYMBOL(writesl);
 
+/*
+ * The EBSA110 has a weird "ISA IO" region:
+ *
+ * Region 0 (addr = 0xf0000000 + io << 2)
+ * --------------------------------------------------------
+ * Physical region	IO region
+ * f0000fe0 - f0000ffc	3f8 - 3ff  ttyS0
+ * f0000e60 - f0000e64	398 - 399
+ * f0000de0 - f0000dfc	378 - 37f  lp0
+ * f0000be0 - f0000bfc	2f8 - 2ff  ttyS1
+ *
+ * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
+ * --------------------------------------------------------
+ * Physical region	IO region
+ * f00014f1             a79        pnp write data
+ * f00007c0 - f00007c1	3e0 - 3e1  pcmcia
+ * f00004f1		279        pnp address
+ * f0000440 - f000046c  220 - 236  eth0
+ * f0000405		203        pnp read data
+ */
 #define SUPERIO_PORT(p) \
 	(((p) >> 3) == (0x3f8 >> 3) || \
 	 ((p) >> 3) == (0x2f8 >> 3) || \
diff --git a/arch/arm/mach-ebsa110/leds.c b/arch/arm/mach-ebsa110/leds.c
index 6a6ea57..d43121a 100644
--- a/arch/arm/mach-ebsa110/leds.c
+++ b/arch/arm/mach-ebsa110/leds.c
@@ -20,6 +20,8 @@
 #include <asm/system.h>
 #include <asm/mach-types.h>
 
+#include "core.h"
+
 static spinlock_t leds_lock;
 
 static void ebsa110_leds_event(led_event_t ledevt)
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 24203f9..41f0d68 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -279,48 +279,14 @@ static struct amba_pl010_data ep93xx_uart_data = {
 	.set_mctrl	= ep93xx_uart_set_mctrl,
 };
 
-static struct amba_device uart1_device = {
-	.dev		= {
-		.init_name	= "apb:uart1",
-		.platform_data	= &ep93xx_uart_data,
-	},
-	.res		= {
-		.start	= EP93XX_UART1_PHYS_BASE,
-		.end	= EP93XX_UART1_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_EP93XX_UART1, NO_IRQ },
-	.periphid	= 0x00041010,
-};
+static AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE,
+	{ IRQ_EP93XX_UART1 }, &ep93xx_uart_data);
 
-static struct amba_device uart2_device = {
-	.dev		= {
-		.init_name	= "apb:uart2",
-		.platform_data	= &ep93xx_uart_data,
-	},
-	.res		= {
-		.start	= EP93XX_UART2_PHYS_BASE,
-		.end	= EP93XX_UART2_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_EP93XX_UART2, NO_IRQ },
-	.periphid	= 0x00041010,
-};
-
-static struct amba_device uart3_device = {
-	.dev		= {
-		.init_name	= "apb:uart3",
-		.platform_data	= &ep93xx_uart_data,
-	},
-	.res		= {
-		.start	= EP93XX_UART3_PHYS_BASE,
-		.end	= EP93XX_UART3_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_EP93XX_UART3, NO_IRQ },
-	.periphid	= 0x00041010,
-};
+static AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE,
+	{ IRQ_EP93XX_UART2 }, &ep93xx_uart_data);
 
+static AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE,
+	{ IRQ_EP93XX_UART3 }, &ep93xx_uart_data);
 
 static struct resource ep93xx_rtc_resource[] = {
 	{
@@ -817,23 +783,12 @@ void __init ep93xx_register_i2s(void)
 #define EP93XX_I2SCLKDIV_MASK		(EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
 					 EP93XX_SYSCON_I2SCLKDIV_SPOL)
 
-int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
+int ep93xx_i2s_acquire(void)
 {
 	unsigned val;
 
-	/* Sanity check */
-	if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK)
-		return -EINVAL;
-	if (i2s_config & ~EP93XX_I2SCLKDIV_MASK)
-		return -EINVAL;
-
-	/* Must have only one of I2SONSSP/I2SONAC97 set */
-	if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) ==
-	    (i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97))
-		return -EINVAL;
-
-	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
-	ep93xx_devcfg_set_bits(i2s_pins);
+	ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_I2SONAC97,
+			EP93XX_SYSCON_DEVCFG_I2S_MASK);
 
 	/*
 	 * This is potentially racy with the clock api for i2s_mclk, sclk and 
@@ -843,7 +798,7 @@ int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
 	 */
 	val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
 	val &= ~EP93XX_I2SCLKDIV_MASK;
-	val |= i2s_config;
+	val |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
 	ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
 
 	return 0;
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index d4c9349..ad63d4b 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -59,7 +59,7 @@ void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
 int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
 void ep93xx_keypad_release_gpio(struct platform_device *pdev);
 void ep93xx_register_i2s(void);
-int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config);
+int ep93xx_i2s_acquire(void);
 void ep93xx_i2s_release(void);
 void ep93xx_register_ac97(void);
 
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
deleted file mode 100644
index b5bec7c..0000000
--- a/arch/arm/mach-ep93xx/include/mach/system.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/include/mach/system.h
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 5d602f6..a95146b 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -34,6 +34,7 @@ config CPU_EXYNOS4210
 	select ARM_CPU_SUSPEND if PM
 	select S5P_PM if PM
 	select S5P_SLEEP if PM
+	select PM_GENERIC_DOMAINS
 	help
 	  Enable EXYNOS4210 CPU support
 
@@ -74,11 +75,6 @@ config EXYNOS4_SETUP_FIMD0
 	help
 	  Common setup code for FIMD0.
 
-config EXYNOS4_DEV_PD
-	bool
-	help
-	  Compile in platform device definitions for Power Domain
-
 config EXYNOS4_DEV_SYSMMU
 	bool
 	help
@@ -195,7 +191,6 @@ config MACH_SMDKV310
 	select EXYNOS4_DEV_AHCI
 	select SAMSUNG_DEV_KEYPAD
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select SAMSUNG_DEV_PWM
 	select EXYNOS4_DEV_USB_OHCI
 	select EXYNOS4_DEV_SYSMMU
@@ -230,6 +225,7 @@ config MACH_UNIVERSAL_C210
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
 	select S5P_DEV_FIMC3
+	select S5P_DEV_G2D
 	select S5P_DEV_CSIS0
 	select S5P_DEV_FIMD0
 	select S3C_DEV_HSMMC
@@ -243,7 +239,6 @@ config MACH_UNIVERSAL_C210
 	select S5P_DEV_ONENAND
 	select S5P_DEV_TV
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_I2C3
@@ -268,21 +263,23 @@ config MACH_NURI
 	select S3C_DEV_I2C1
 	select S3C_DEV_I2C3
 	select S3C_DEV_I2C5
+	select S3C_DEV_I2C6
 	select S5P_DEV_CSIS0
 	select S5P_DEV_FIMC0
 	select S5P_DEV_FIMC1
 	select S5P_DEV_FIMC2
 	select S5P_DEV_FIMC3
+	select S5P_DEV_G2D
 	select S5P_DEV_MFC
 	select S5P_DEV_USB_EHCI
 	select S5P_SETUP_MIPIPHY
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_SETUP_FIMC
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_I2C1
 	select EXYNOS4_SETUP_I2C3
 	select EXYNOS4_SETUP_I2C5
+	select EXYNOS4_SETUP_I2C6
 	select EXYNOS4_SETUP_SDHCI
 	select EXYNOS4_SETUP_USB_PHY
 	select S5P_SETUP_MIPIPHY
@@ -303,6 +300,7 @@ config MACH_ORIGEN
 	select S5P_DEV_FIMC2
 	select S5P_DEV_FIMC3
 	select S5P_DEV_FIMD0
+	select S5P_DEV_G2D
 	select S5P_DEV_I2C_HDMIPHY
 	select S5P_DEV_MFC
 	select S5P_DEV_TV
@@ -310,7 +308,6 @@ config MACH_ORIGEN
 	select SAMSUNG_DEV_BACKLIGHT
 	select SAMSUNG_DEV_PWM
 	select EXYNOS4_DEV_DMA
-	select EXYNOS4_DEV_PD
 	select EXYNOS4_DEV_USB_OHCI
 	select EXYNOS4_SETUP_FIMD0
 	select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 5fc202c..d9191f9 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_CPU_EXYNOS4210)	+= clock-exynos4210.o
 obj-$(CONFIG_SOC_EXYNOS4212)	+= clock-exynos4212.o
 
 obj-$(CONFIG_PM)		+= pm.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 obj-$(CONFIG_ARCH_EXYNOS4)	+= pmu.o
@@ -45,7 +46,6 @@ obj-$(CONFIG_MACH_EXYNOS4_DT)		+= mach-exynos4-dt.o
 
 obj-$(CONFIG_ARCH_EXYNOS4)		+= dev-audio.o
 obj-$(CONFIG_EXYNOS4_DEV_AHCI)		+= dev-ahci.o
-obj-$(CONFIG_EXYNOS4_DEV_PD)		+= dev-pd.o
 obj-$(CONFIG_EXYNOS4_DEV_SYSMMU)	+= dev-sysmmu.o
 obj-$(CONFIG_EXYNOS4_DEV_DWMCI)		+= dev-dwmci.o
 obj-$(CONFIG_EXYNOS4_DEV_DMA)		+= dma.o
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
index 13312cc..54a92ef 100644
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
@@ -117,7 +117,7 @@ static void exynos4210_clock_resume(void)
 #define exynos4210_clock_resume NULL
 #endif
 
-struct syscore_ops exynos4210_clock_syscore_ops = {
+static struct syscore_ops exynos4210_clock_syscore_ops = {
 	.suspend	= exynos4210_clock_suspend,
 	.resume		= exynos4210_clock_resume,
 };
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
index 48af285..8e07ab1 100644
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
@@ -89,7 +89,7 @@ static void exynos4212_clock_resume(void)
 #define exynos4212_clock_resume NULL
 #endif
 
-struct syscore_ops exynos4212_clock_syscore_ops = {
+static struct syscore_ops exynos4212_clock_syscore_ops = {
 	.suspend	= exynos4212_clock_suspend,
 	.resume		= exynos4212_clock_resume,
 };
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
index 187287a..0dc3ca2 100644
--- a/arch/arm/mach-exynos/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -498,25 +498,25 @@ static struct clk init_clocks_off[] = {
 		.ctrlbit	= (1 << 0),
 	}, {
 		.name		= "hsmmc",
-		.devname	= "s3c-sdhci.0",
+		.devname	= "exynos4-sdhci.0",
 		.parent		= &clk_aclk_133.clk,
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 5),
 	}, {
 		.name		= "hsmmc",
-		.devname	= "s3c-sdhci.1",
+		.devname	= "exynos4-sdhci.1",
 		.parent		= &clk_aclk_133.clk,
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 6),
 	}, {
 		.name		= "hsmmc",
-		.devname	= "s3c-sdhci.2",
+		.devname	= "exynos4-sdhci.2",
 		.parent		= &clk_aclk_133.clk,
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 7),
 	}, {
 		.name		= "hsmmc",
-		.devname	= "s3c-sdhci.3",
+		.devname	= "exynos4-sdhci.3",
 		.parent		= &clk_aclk_133.clk,
 		.enable		= exynos4_clk_ip_fsys_ctrl,
 		.ctrlbit	= (1 << 8),
@@ -1189,7 +1189,7 @@ static struct clksrc_clk clk_sclk_uart3 = {
 static struct clksrc_clk clk_sclk_mmc0 = {
 	.clk		= {
 		.name		= "sclk_mmc",
-		.devname	= "s3c-sdhci.0",
+		.devname	= "exynos4-sdhci.0",
 		.parent		= &clk_dout_mmc0.clk,
 		.enable		= exynos4_clksrc_mask_fsys_ctrl,
 		.ctrlbit	= (1 << 0),
@@ -1200,7 +1200,7 @@ static struct clksrc_clk clk_sclk_mmc0 = {
 static struct clksrc_clk clk_sclk_mmc1 = {
 	.clk		= {
 		.name		= "sclk_mmc",
-		.devname	= "s3c-sdhci.1",
+		.devname	= "exynos4-sdhci.1",
 		.parent         = &clk_dout_mmc1.clk,
 		.enable		= exynos4_clksrc_mask_fsys_ctrl,
 		.ctrlbit	= (1 << 4),
@@ -1211,7 +1211,7 @@ static struct clksrc_clk clk_sclk_mmc1 = {
 static struct clksrc_clk clk_sclk_mmc2 = {
 	.clk		= {
 		.name		= "sclk_mmc",
-		.devname	= "s3c-sdhci.2",
+		.devname	= "exynos4-sdhci.2",
 		.parent         = &clk_dout_mmc2.clk,
 		.enable		= exynos4_clksrc_mask_fsys_ctrl,
 		.ctrlbit	= (1 << 8),
@@ -1222,7 +1222,7 @@ static struct clksrc_clk clk_sclk_mmc2 = {
 static struct clksrc_clk clk_sclk_mmc3 = {
 	.clk		= {
 		.name		= "sclk_mmc",
-		.devname	= "s3c-sdhci.3",
+		.devname	= "exynos4-sdhci.3",
 		.parent         = &clk_dout_mmc3.clk,
 		.enable		= exynos4_clksrc_mask_fsys_ctrl,
 		.ctrlbit	= (1 << 12),
@@ -1325,10 +1325,10 @@ static struct clk_lookup exynos4_clk_lookup[] = {
 	CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
 	CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
 	CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
-	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
-	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
-	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
-	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
+	CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
+	CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
+	CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
+	CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
 	CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
 	CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
 	CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &clk_sclk_spi0.clk),
@@ -1526,7 +1526,7 @@ static void exynos4_clock_resume(void)
 #define exynos4_clock_resume NULL
 #endif
 
-struct syscore_ops exynos4_clock_syscore_ops = {
+static struct syscore_ops exynos4_clock_syscore_ops = {
 	.suspend	= exynos4_clock_suspend,
 	.resume		= exynos4_clock_resume,
 };
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index c59e188..7f2d3b6 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -201,14 +201,6 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
 	},
 };
 
-static void exynos_idle(void)
-{
-	if (!need_resched())
-		cpu_do_idle();
-
-	local_irq_enable();
-}
-
 void exynos4_restart(char mode, const char *cmd)
 {
 	__raw_writel(0x1, S5P_SWRESET);
@@ -255,6 +247,11 @@ void __init exynos4_map_io(void)
 	s3c_fimc_setname(2, "exynos4-fimc");
 	s3c_fimc_setname(3, "exynos4-fimc");
 
+	s3c_sdhci_setname(0, "exynos4-sdhci");
+	s3c_sdhci_setname(1, "exynos4-sdhci");
+	s3c_sdhci_setname(2, "exynos4-sdhci");
+	s3c_sdhci_setname(3, "exynos4-sdhci");
+
 	/* The I2C bus controllers are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
 	s3c_i2c1_setname("s3c2440-i2c");
@@ -402,7 +399,7 @@ void __init exynos4_init_irq(void)
 	gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
 
 	if (!of_have_populated_dt())
-		gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
+		gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
 #ifdef CONFIG_OF
 	else
 		of_irq_init(exynos4_dt_irq_match);
@@ -467,10 +464,6 @@ early_initcall(exynos4_l2x0_cache_init);
 int __init exynos_init(void)
 {
 	printk(KERN_INFO "EXYNOS: Initializing architecture\n");
-
-	/* set idle function */
-	pm_idle = exynos_idle;
-
 	return device_register(&exynos4_dev);
 }
 
@@ -673,7 +666,7 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
-int __init exynos4_init_irq_eint(void)
+static int __init exynos4_init_irq_eint(void)
 {
 	int irq;
 
diff --git a/arch/arm/mach-exynos/dev-pd.c b/arch/arm/mach-exynos/dev-pd.c
deleted file mode 100644
index 3273f25..0000000
--- a/arch/arm/mach-exynos/dev-pd.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/* linux/arch/arm/mach-exynos4/dev-pd.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - Power Domain support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-
-#include <mach/regs-pmu.h>
-
-#include <plat/pd.h>
-
-static int exynos4_pd_enable(struct device *dev)
-{
-	struct samsung_pd_info *pdata =  dev->platform_data;
-	u32 timeout;
-
-	__raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
-
-	/* Wait max 1ms */
-	timeout = 10;
-	while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
-		!= S5P_INT_LOCAL_PWR_EN) {
-		if (timeout == 0) {
-			printk(KERN_ERR "Power domain %s enable failed.\n",
-				dev_name(dev));
-			return -ETIMEDOUT;
-		}
-		timeout--;
-		udelay(100);
-	}
-
-	return 0;
-}
-
-static int exynos4_pd_disable(struct device *dev)
-{
-	struct samsung_pd_info *pdata =  dev->platform_data;
-	u32 timeout;
-
-	__raw_writel(0, pdata->base);
-
-	/* Wait max 1ms */
-	timeout = 10;
-	while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
-		if (timeout == 0) {
-			printk(KERN_ERR "Power domain %s disable failed.\n",
-				dev_name(dev));
-			return -ETIMEDOUT;
-		}
-		timeout--;
-		udelay(100);
-	}
-
-	return 0;
-}
-
-struct platform_device exynos4_device_pd[] = {
-	{
-		.name		= "samsung-pd",
-		.id		= 0,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_MFC_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 1,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_G3D_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 2,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_LCD0_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 3,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_LCD1_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 4,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_TV_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 5,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_CAM_CONF,
-			},
-		},
-	}, {
-		.name		= "samsung-pd",
-		.id		= 6,
-		.dev = {
-			.platform_data = &(struct samsung_pd_info) {
-				.enable		= exynos4_pd_enable,
-				.disable	= exynos4_pd_disable,
-				.base		= S5P_PMU_GPS_CONF,
-			},
-		},
-	},
-};
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index b10fcd2..25f3ef2 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -36,7 +36,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 pdma0_peri[] = {
+static u8 pdma0_peri[] = {
 	DMACH_PCM0_RX,
 	DMACH_PCM0_TX,
 	DMACH_PCM2_RX,
@@ -69,28 +69,15 @@ u8 pdma0_peri[] = {
 	DMACH_AC97_PCMOUT,
 };
 
-struct dma_pl330_platdata exynos4_pdma0_pdata = {
+static struct dma_pl330_platdata exynos4_pdma0_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
 	.peri_id = pdma0_peri,
 };
 
-struct amba_device exynos4_device_pdma0 = {
-	.dev = {
-		.init_name = "dma-pl330.0",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &exynos4_pdma0_pdata,
-	},
-	.res = {
-		.start = EXYNOS4_PA_PDMA0,
-		.end = EXYNOS4_PA_PDMA0 + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_PDMA0, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330,
+	EXYNOS4_PA_PDMA0, {IRQ_PDMA0}, &exynos4_pdma0_pdata);
 
-u8 pdma1_peri[] = {
+static u8 pdma1_peri[] = {
 	DMACH_PCM0_RX,
 	DMACH_PCM0_TX,
 	DMACH_PCM1_RX,
@@ -118,26 +105,13 @@ u8 pdma1_peri[] = {
 	DMACH_SLIMBUS5_TX,
 };
 
-struct dma_pl330_platdata exynos4_pdma1_pdata = {
+static struct dma_pl330_platdata exynos4_pdma1_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
 	.peri_id = pdma1_peri,
 };
 
-struct amba_device exynos4_device_pdma1 = {
-	.dev = {
-		.init_name = "dma-pl330.1",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &exynos4_pdma1_pdata,
-	},
-	.res = {
-		.start = EXYNOS4_PA_PDMA1,
-		.end = EXYNOS4_PA_PDMA1 + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_PDMA1, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(exynos4_pdma1,  "dma-pl330.1", 0x00041330,
+	EXYNOS4_PA_PDMA1, {IRQ_PDMA1}, &exynos4_pdma1_pdata);
 
 static int __init exynos4_dma_init(void)
 {
@@ -146,11 +120,11 @@ static int __init exynos4_dma_init(void)
 
 	dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
-	amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+	amba_device_register(&exynos4_pdma0_device, &iomem_resource);
 
 	dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
-	amba_device_register(&exynos4_device_pdma1, &iomem_resource);
+	amba_device_register(&exynos4_pdma1_device, &iomem_resource);
 
 	return 0;
 }
diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c
index dd1ad55..9c17a0a 100644
--- a/arch/arm/mach-exynos/hotplug.c
+++ b/arch/arm/mach-exynos/hotplug.c
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <asm/smp_plat.h>
 
 #include <mach/regs-pmu.h>
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index c754a22..7df9e74 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -31,6 +31,8 @@
 #define EXYNOS4_PA_FIMC2		0x11820000
 #define EXYNOS4_PA_FIMC3		0x11830000
 
+#define EXYNOS4_PA_G2D			0x12800000
+
 #define EXYNOS4_PA_I2S0			0x03830000
 #define EXYNOS4_PA_I2S1			0xE3100000
 #define EXYNOS4_PA_I2S2			0xE2A00000
@@ -162,6 +164,7 @@
 #define S5P_PA_FIMC1			EXYNOS4_PA_FIMC1
 #define S5P_PA_FIMC2			EXYNOS4_PA_FIMC2
 #define S5P_PA_FIMC3			EXYNOS4_PA_FIMC3
+#define S5P_PA_G2D			EXYNOS4_PA_G2D
 #define S5P_PA_FIMD0			EXYNOS4_PA_FIMD0
 #define S5P_PA_HDMI			EXYNOS4_PA_HDMI
 #define S5P_PA_IIC_HDMIPHY		EXYNOS4_PA_IIC_HDMIPHY
diff --git a/arch/arm/mach-exynos/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h
deleted file mode 100644
index 0063a6d..0000000
--- a/arch/arm/mach-exynos/include/mach/system.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/system.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-exynos/mach-armlex4210.c b/arch/arm/mach-exynos/mach-armlex4210.c
index d726fcd..a1e7007 100644
--- a/arch/arm/mach-exynos/mach-armlex4210.c
+++ b/arch/arm/mach-exynos/mach-armlex4210.c
@@ -77,7 +77,6 @@ static struct s3c2410_uartcfg armlex4210_uartcfgs[] __initdata = {
 
 static struct s3c_sdhci_platdata armlex4210_hsmmc0_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
 	.max_width		= 8,
 	.host_caps		= MMC_CAP_8_BIT_DATA,
@@ -88,13 +87,11 @@ static struct s3c_sdhci_platdata armlex4210_hsmmc2_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_GPIO,
 	.ext_cd_gpio		= EXYNOS4_GPX2(5),
 	.ext_cd_gpio_invert	= 1,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 	.max_width		= 4,
 };
 
 static struct s3c_sdhci_platdata armlex4210_hsmmc3_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 	.max_width		= 4,
 };
 
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index 435261f..a6b9162 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -28,6 +28,7 @@
 
 #include <video/platform_lcd.h>
 #include <media/m5mols.h>
+#include <media/s5k6aa.h>
 #include <media/s5p_fimc.h>
 #include <media/v4l2-mediabus.h>
 
@@ -75,6 +76,7 @@ enum fixed_regulator_id {
 	FIXED_REG_ID_MAX8903,
 	FIXED_REG_ID_CAM_A28V,
 	FIXED_REG_ID_CAM_12V,
+	FIXED_REG_ID_CAM_VT_15V,
 };
 
 static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
@@ -111,7 +113,6 @@ static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
 				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
 				MMC_CAP_DISABLE | MMC_CAP_ERASE),
 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static struct regulator_consumer_supply emmc_supplies[] = {
@@ -153,7 +154,6 @@ static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
 	.ext_cd_gpio		= EXYNOS4_GPX3(3),	/* XEINT_27 */
 	.ext_cd_gpio_invert	= 1,
 	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 /* WLAN */
@@ -162,7 +162,6 @@ static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
 	.host_caps		= MMC_CAP_4_BIT_DATA |
 				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
 	.cd_type		= S3C_SDHCI_CD_EXTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static void __init nuri_sdhci_init(void)
@@ -399,6 +398,9 @@ static struct regulator_consumer_supply __initdata max8997_ldo4_[] = {
 static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
 	REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
 };
+static struct regulator_consumer_supply nuri_max8997_ldo6_consumer[] = {
+	REGULATOR_SUPPLY("vdd_reg", "6-003c"), /* S5K6AA camera */
+};
 static struct regulator_consumer_supply __initdata max8997_ldo7_[] = {
 	REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
 };
@@ -546,6 +548,8 @@ static struct regulator_init_data __initdata max8997_ldo6_data = {
 			.enabled	= 1,
 		},
 	},
+	.num_consumer_supplies	= ARRAY_SIZE(nuri_max8997_ldo6_consumer),
+	.consumer_supplies	= nuri_max8997_ldo6_consumer,
 };
 
 static struct regulator_init_data __initdata max8997_ldo7_data = {
@@ -1116,7 +1120,30 @@ static void __init nuri_ehci_init(void)
 }
 
 /* CAMERA */
+static struct regulator_consumer_supply cam_vt_cam15_supply =
+	REGULATOR_SUPPLY("vdd_core", "6-003c");
+
+static struct regulator_init_data cam_vt_cam15_reg_init_data = {
+	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+	.num_consumer_supplies = 1,
+	.consumer_supplies = &cam_vt_cam15_supply,
+};
+
+static struct fixed_voltage_config cam_vt_cam15_fixed_voltage_cfg = {
+	.supply_name	= "VT_CAM_1.5V",
+	.microvolts	= 1500000,
+	.gpio		= EXYNOS4_GPE2(2), /* VT_CAM_1.5V_EN */
+	.enable_high	= 1,
+	.init_data	= &cam_vt_cam15_reg_init_data,
+};
+
+static struct platform_device cam_vt_cam15_fixed_rdev = {
+	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_15V,
+	.dev = { .platform_data	= &cam_vt_cam15_fixed_voltage_cfg },
+};
+
 static struct regulator_consumer_supply cam_vdda_supply[] = {
+	REGULATOR_SUPPLY("vdda", "6-003c"),
 	REGULATOR_SUPPLY("a_sensor", "0-001f"),
 };
 
@@ -1173,6 +1200,21 @@ static struct s5p_platform_mipi_csis mipi_csis_platdata = {
 
 #define GPIO_CAM_MEGA_RST	EXYNOS4_GPY3(7) /* ISP_RESET */
 #define GPIO_CAM_8M_ISP_INT	EXYNOS4_GPL2(5)
+#define GPIO_CAM_VT_NSTBY	EXYNOS4_GPL2(0)
+#define GPIO_CAM_VT_NRST	EXYNOS4_GPL2(1)
+
+static struct s5k6aa_platform_data s5k6aa_pldata = {
+	.mclk_frequency	= 24000000UL,
+	.gpio_reset	= { GPIO_CAM_VT_NRST, 0 },
+	.gpio_stby	= { GPIO_CAM_VT_NSTBY, 0 },
+	.bus_type	= V4L2_MBUS_PARALLEL,
+	.horiz_flip	= 1,
+};
+
+static struct i2c_board_info s5k6aa_board_info = {
+	I2C_BOARD_INFO("S5K6AA", 0x3c),
+	.platform_data = &s5k6aa_pldata,
+};
 
 static struct m5mols_platform_data m5mols_platdata = {
 	.gpio_reset = GPIO_CAM_MEGA_RST,
@@ -1185,6 +1227,13 @@ static struct i2c_board_info m5mols_board_info = {
 
 static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
 	{
+		.flags		= V4L2_MBUS_PCLK_SAMPLE_RISING |
+				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
+		.bus_type	= FIMC_ITU_601,
+		.board_info	= &s5k6aa_board_info,
+		.clk_frequency	= 24000000UL,
+		.i2c_bus_num	= 6,
+	}, {
 		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
 				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
 		.bus_type	= FIMC_MIPI_CSI2,
@@ -1200,6 +1249,8 @@ static struct s5p_platform_fimc fimc_md_platdata = {
 };
 
 static struct gpio nuri_camera_gpios[] = {
+	{ GPIO_CAM_VT_NSTBY,	GPIOF_OUT_INIT_LOW, "CAM_VGA_NSTBY" },
+	{ GPIO_CAM_VT_NRST,	GPIOF_OUT_INIT_LOW, "CAM_VGA_NRST"  },
 	{ GPIO_CAM_8M_ISP_INT,	GPIOF_IN,           "8M_ISP_INT"  },
 	{ GPIO_CAM_MEGA_RST,	GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
 };
@@ -1224,6 +1275,8 @@ static void nuri_camera_init(void)
 		pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__);
 
 	/* Free GPIOs controlled directly by the sensor drivers. */
+	gpio_free(GPIO_CAM_VT_NRST);
+	gpio_free(GPIO_CAM_VT_NSTBY);
 	gpio_free(GPIO_CAM_MEGA_RST);
 
 	if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
@@ -1234,6 +1287,12 @@ static void nuri_camera_init(void)
 	s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
 }
 
+static struct s3c2410_platform_i2c nuri_i2c6_platdata __initdata = {
+	.frequency	= 400000U,
+	.sda_delay	= 200,
+	.bus_num	= 6,
+};
+
 static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
 	.frequency	= 400000U,
 	.sda_delay	= 200,
@@ -1243,6 +1302,7 @@ static struct platform_device *nuri_devices[] __initdata = {
 	/* Samsung Platform Devices */
 	&s3c_device_i2c5, /* PMIC should initialize first */
 	&s3c_device_i2c0,
+	&s3c_device_i2c6,
 	&emmc_fixed_voltage,
 	&s5p_device_mipi_csis0,
 	&s5p_device_fimc0,
@@ -1259,13 +1319,11 @@ static struct platform_device *nuri_devices[] __initdata = {
 	&s3c_device_i2c3,
 	&i2c9_gpio,
 	&s3c_device_adc,
+	&s5p_device_g2d,
 	&s3c_device_rtc,
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_CAM],
 	&s5p_device_fimc_md,
 
 	/* NURI Devices */
@@ -1274,6 +1332,7 @@ static struct platform_device *nuri_devices[] __initdata = {
 	&nuri_backlight_device,
 	&max8903_fixed_reg_dev,
 	&nuri_max8903_device,
+	&cam_vt_cam15_fixed_rdev,
 	&cam_vdda_fixed_rdev,
 	&cam_8m_12v_fixed_rdev,
 };
@@ -1305,6 +1364,7 @@ static void __init nuri_machine_init(void)
 	i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
 	i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
 	i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
+	s3c_i2c6_set_platdata(&nuri_i2c6_platdata);
 
 	s5p_fimd0_set_platdata(&nuri_fb_pdata);
 
@@ -1315,14 +1375,6 @@ static void __init nuri_machine_init(void)
 
 	/* Last */
 	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(NURI, "NURI")
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 0679b8a..02c242e 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -20,6 +20,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/mfd/max8997.h>
 #include <linux/lcd.h>
+#include <linux/rfkill-gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -235,6 +236,7 @@ static struct regulator_init_data __initdata max8997_ldo9_data = {
 		.min_uV		= 2800000,
 		.max_uV		= 2800000,
 		.apply_uV	= 1,
+		.always_on	= 1,
 		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
 		.state_mem	= {
 			.disabled	= 1,
@@ -278,6 +280,7 @@ static struct regulator_init_data __initdata max8997_ldo14_data = {
 		.min_uV		= 1800000,
 		.max_uV		= 1800000,
 		.apply_uV	= 1,
+		.always_on	= 1,
 		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
 		.state_mem	= {
 			.disabled	= 1,
@@ -293,6 +296,7 @@ static struct regulator_init_data __initdata max8997_ldo17_data = {
 		.min_uV		= 3300000,
 		.max_uV		= 3300000,
 		.apply_uV	= 1,
+		.always_on	= 1,
 		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
 		.state_mem	= {
 			.disabled	= 1,
@@ -412,7 +416,7 @@ static struct max8997_regulator_data __initdata origen_max8997_regulators[] = {
 	{ MAX8997_BUCK7,	&max8997_buck7_data },
 };
 
-struct max8997_platform_data __initdata origen_max8997_pdata = {
+static struct max8997_platform_data __initdata origen_max8997_pdata = {
 	.num_regulators = ARRAY_SIZE(origen_max8997_regulators),
 	.regulators	= origen_max8997_regulators,
 
@@ -468,12 +472,10 @@ static struct i2c_board_info i2c0_devs[] __initdata = {
 
 static struct s3c_sdhci_platdata origen_hsmmc0_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static struct s3c_sdhci_platdata origen_hsmmc2_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 /* USB EHCI */
@@ -602,6 +604,23 @@ static struct s3c_fb_platdata origen_lcd_pdata __initdata = {
 	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
 };
 
+/* Bluetooth rfkill gpio platform data */
+struct rfkill_gpio_platform_data origen_bt_pdata = {
+	.reset_gpio	= EXYNOS4_GPX2(2),
+	.shutdown_gpio	= -1,
+	.type		= RFKILL_TYPE_BLUETOOTH,
+	.name		= "origen-bt",
+};
+
+/* Bluetooth Platform device */
+static struct platform_device origen_device_bluetooth = {
+	.name		= "rfkill_gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &origen_bt_pdata,
+	},
+};
+
 static struct platform_device *origen_devices[] __initdata = {
 	&s3c_device_hsmmc2,
 	&s3c_device_hsmmc0,
@@ -613,7 +632,9 @@ static struct platform_device *origen_devices[] __initdata = {
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
 	&s5p_device_fimc3,
+	&s5p_device_fimc_md,
 	&s5p_device_fimd0,
+	&s5p_device_g2d,
 	&s5p_device_hdmi,
 	&s5p_device_i2c_hdmiphy,
 	&s5p_device_mfc,
@@ -621,15 +642,9 @@ static struct platform_device *origen_devices[] __initdata = {
 	&s5p_device_mfc_r,
 	&s5p_device_mixer,
 	&exynos4_device_ohci,
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_TV],
-	&exynos4_device_pd[PD_G3D],
-	&exynos4_device_pd[PD_LCD1],
-	&exynos4_device_pd[PD_CAM],
-	&exynos4_device_pd[PD_GPS],
-	&exynos4_device_pd[PD_MFC],
 	&origen_device_gpiokeys,
 	&origen_lcd_hv070wsa,
+	&origen_device_bluetooth,
 };
 
 /* LCD Backlight data */
@@ -643,6 +658,16 @@ static struct platform_pwm_backlight_data origen_bl_data = {
 	.pwm_period_ns	= 1000,
 };
 
+static void __init origen_bt_setup(void)
+{
+	gpio_request(EXYNOS4_GPA0(0), "GPIO BT_UART");
+	/* 4 UART Pins configuration */
+	s3c_gpio_cfgrange_nopull(EXYNOS4_GPA0(0), 4, S3C_GPIO_SFN(2));
+	/* Setup BT Reset, this gpio will be requesed by rfkill-gpio */
+	s3c_gpio_cfgpin(EXYNOS4_GPX2(2), S3C_GPIO_OUTPUT);
+	s3c_gpio_setpull(EXYNOS4_GPX2(2), S3C_GPIO_PULL_NONE);
+}
+
 static void s5p_tv_setup(void)
 {
 	/* Direct HPD to HDMI chip */
@@ -695,14 +720,9 @@ static void __init origen_machine_init(void)
 
 	platform_add_devices(origen_devices, ARRAY_SIZE(origen_devices));
 
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
-
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-
 	samsung_bl_set(&origen_bl_gpio_info, &origen_bl_data);
+
+	origen_bt_setup();
 }
 
 MACHINE_START(ORIGEN, "ORIGEN")
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index d00e4f0..4be083a 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -85,7 +85,6 @@ static struct s3c2410_uartcfg smdk4x12_uartcfgs[] __initdata = {
 
 static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
 	.max_width		= 8,
 	.host_caps		= MMC_CAP_8_BIT_DATA,
@@ -94,7 +93,6 @@ static struct s3c_sdhci_platdata smdk4x12_hsmmc2_pdata __initdata = {
 
 static struct s3c_sdhci_platdata smdk4x12_hsmmc3_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static struct regulator_consumer_supply max8997_buck1 =
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index b2c5557..2b71f18 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -93,7 +93,6 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
 
 static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
 	.max_width		= 8,
 	.host_caps		= MMC_CAP_8_BIT_DATA,
@@ -104,12 +103,10 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_GPIO,
 	.ext_cd_gpio		= EXYNOS4_GPK0(2),
 	.ext_cd_gpio_invert	= 1,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
 	.max_width		= 8,
 	.host_caps		= MMC_CAP_8_BIT_DATA,
@@ -120,7 +117,6 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc3_pdata __initdata = {
 	.cd_type		= S3C_SDHCI_CD_GPIO,
 	.ext_cd_gpio		= EXYNOS4_GPK2(2),
 	.ext_cd_gpio_invert	= 1,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static void lcd_lte480wv_set_power(struct plat_lcd_data *pd,
@@ -270,6 +266,7 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
 	&s5p_device_fimc3,
+	&s5p_device_fimc_md,
 	&exynos4_device_ac97,
 	&exynos4_device_i2s0,
 	&exynos4_device_ohci,
@@ -277,13 +274,6 @@ static struct platform_device *smdkv310_devices[] __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_G3D],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_LCD1],
-	&exynos4_device_pd[PD_CAM],
-	&exynos4_device_pd[PD_TV],
-	&exynos4_device_pd[PD_GPS],
 	&exynos4_device_spdif,
 	&exynos4_device_sysmmu,
 	&samsung_asoc_dma,
@@ -336,10 +326,6 @@ static void s5p_tv_setup(void)
 	WARN_ON(gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug"));
 	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
 	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-
-	/* setup dependencies between TV devices */
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
 }
 
 static void __init smdkv310_map_io(void)
@@ -379,7 +365,6 @@ static void __init smdkv310_machine_init(void)
 	clk_xusbxti.rate = 24000000;
 
 	platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
 }
 
 MACHINE_START(SMDKV310, "SMDKV310")
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 0fc65ff..6017a21 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -46,6 +46,7 @@
 #include <media/v4l2-mediabus.h>
 #include <media/s5p_fimc.h>
 #include <media/m5mols.h>
+#include <media/s5k6aa.h>
 
 #include "common.h"
 
@@ -122,8 +123,10 @@ static struct regulator_consumer_supply lp3974_buck1_consumer =
 static struct regulator_consumer_supply lp3974_buck2_consumer =
 	REGULATOR_SUPPLY("vddg3d", NULL);
 
-static struct regulator_consumer_supply lp3974_buck3_consumer =
-	REGULATOR_SUPPLY("vdet", "s5p-sdo");
+static struct regulator_consumer_supply lp3974_buck3_consumer[] = {
+	REGULATOR_SUPPLY("vdet", "s5p-sdo"),
+	REGULATOR_SUPPLY("vdd_reg", "0-003c"),
+};
 
 static struct regulator_init_data lp3974_buck1_data = {
 	.constraints	= {
@@ -168,8 +171,8 @@ static struct regulator_init_data lp3974_buck3_data = {
 			.enabled	= 1,
 		},
 	},
-	.num_consumer_supplies = 1,
-	.consumer_supplies = &lp3974_buck3_consumer,
+	.num_consumer_supplies = ARRAY_SIZE(lp3974_buck3_consumer),
+	.consumer_supplies = lp3974_buck3_consumer,
 };
 
 static struct regulator_init_data lp3974_buck4_data = {
@@ -302,6 +305,9 @@ static struct regulator_init_data lp3974_ldo8_data = {
 	.consumer_supplies = lp3974_ldo8_consumer,
 };
 
+static struct regulator_consumer_supply lp3974_ldo9_consumer =
+	REGULATOR_SUPPLY("vddio", "0-003c");
+
 static struct regulator_init_data lp3974_ldo9_data = {
 	.constraints	= {
 		.name		= "VCC_2.8V",
@@ -313,6 +319,8 @@ static struct regulator_init_data lp3974_ldo9_data = {
 			.enabled	= 1,
 		},
 	},
+	.num_consumer_supplies	= 1,
+	.consumer_supplies	= &lp3974_ldo9_consumer,
 };
 
 static struct regulator_init_data lp3974_ldo10_data = {
@@ -411,6 +419,7 @@ static struct regulator_init_data lp3974_ldo15_data = {
 };
 
 static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
+	REGULATOR_SUPPLY("vdda", "0-003c"),
 	REGULATOR_SUPPLY("a_sensor", "0-001f"),
 };
 
@@ -737,7 +746,6 @@ static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
 				MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
 				MMC_CAP_DISABLE),
 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 static struct regulator_consumer_supply mmc0_supplies[] = {
@@ -778,7 +786,6 @@ static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
 	.ext_cd_gpio		= EXYNOS4_GPX3(4),      /* XEINT_28 */
 	.ext_cd_gpio_invert	= 1,
 	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 };
 
 /* WiFi */
@@ -817,6 +824,8 @@ static struct s3c_fb_pd_win universal_fb_win0 = {
 	},
 	.max_bpp	= 32,
 	.default_bpp	= 16,
+	.virtual_x	= 480,
+	.virtual_y	= 2 * 800,
 };
 
 static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
@@ -828,6 +837,28 @@ static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
 	.setup_gpio	= exynos4_fimd0_gpio_setup_24bpp,
 };
 
+static struct regulator_consumer_supply cam_vt_dio_supply =
+	REGULATOR_SUPPLY("vdd_core", "0-003c");
+
+static struct regulator_init_data cam_vt_dio_reg_init_data = {
+	.constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
+	.num_consumer_supplies = 1,
+	.consumer_supplies = &cam_vt_dio_supply,
+};
+
+static struct fixed_voltage_config cam_vt_dio_fixed_voltage_cfg = {
+	.supply_name	= "CAM_VT_D_IO",
+	.microvolts	= 2800000,
+	.gpio		= EXYNOS4_GPE2(1), /* CAM_PWR_EN2 */
+	.enable_high	= 1,
+	.init_data	= &cam_vt_dio_reg_init_data,
+};
+
+static struct platform_device cam_vt_dio_fixed_reg_dev = {
+	.name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_DIO,
+	.dev = { .platform_data	= &cam_vt_dio_fixed_voltage_cfg },
+};
+
 static struct regulator_consumer_supply cam_i_core_supply =
 	REGULATOR_SUPPLY("core", "0-001f");
 
@@ -883,6 +914,28 @@ static struct s5p_platform_mipi_csis mipi_csis_platdata = {
 #define GPIO_CAM_LEVEL_EN(n)	EXYNOS4_GPE4(n + 3)
 #define GPIO_CAM_8M_ISP_INT	EXYNOS4_GPX1(5)	/* XEINT_13 */
 #define GPIO_CAM_MEGA_nRST	EXYNOS4_GPE2(5)
+#define GPIO_CAM_VGA_NRST	EXYNOS4_GPE4(7)
+#define GPIO_CAM_VGA_NSTBY	EXYNOS4_GPE4(6)
+
+static int s5k6aa_set_power(int on)
+{
+	gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
+	return 0;
+}
+
+static struct s5k6aa_platform_data s5k6aa_platdata = {
+	.mclk_frequency	= 21600000UL,
+	.gpio_reset	= { GPIO_CAM_VGA_NRST, 0 },
+	.gpio_stby	= { GPIO_CAM_VGA_NSTBY, 0 },
+	.bus_type	= V4L2_MBUS_PARALLEL,
+	.horiz_flip	= 1,
+	.set_power	= s5k6aa_set_power,
+};
+
+static struct i2c_board_info s5k6aa_board_info = {
+	I2C_BOARD_INFO("S5K6AA", 0x3C),
+	.platform_data = &s5k6aa_platdata,
+};
 
 static int m5mols_set_power(struct device *dev, int on)
 {
@@ -907,6 +960,14 @@ static struct s5p_fimc_isp_info universal_camera_sensors[] = {
 		.mux_id		= 0,
 		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
 				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
+		.bus_type	= FIMC_ITU_601,
+		.board_info	= &s5k6aa_board_info,
+		.i2c_bus_num	= 0,
+		.clk_frequency	= 24000000UL,
+	}, {
+		.mux_id		= 0,
+		.flags		= V4L2_MBUS_PCLK_SAMPLE_FALLING |
+				  V4L2_MBUS_VSYNC_ACTIVE_LOW,
 		.bus_type	= FIMC_MIPI_CSI2,
 		.board_info	= &m5mols_board_info,
 		.i2c_bus_num	= 0,
@@ -925,6 +986,8 @@ static struct gpio universal_camera_gpios[] = {
 	{ GPIO_CAM_LEVEL_EN(2),	GPIOF_OUT_INIT_LOW,  "CAM_LVL_EN2" },
 	{ GPIO_CAM_8M_ISP_INT,	GPIOF_IN,            "8M_ISP_INT"  },
 	{ GPIO_CAM_MEGA_nRST,	GPIOF_OUT_INIT_LOW,  "CAM_8M_NRST" },
+	{ GPIO_CAM_VGA_NRST,	GPIOF_OUT_INIT_LOW,  "CAM_VGA_NRST"  },
+	{ GPIO_CAM_VGA_NSTBY,	GPIOF_OUT_INIT_LOW,  "CAM_VGA_NSTBY" },
 };
 
 static void universal_camera_init(void)
@@ -948,6 +1011,8 @@ static void universal_camera_init(void)
 	/* Free GPIOs controlled directly by the sensor drivers. */
 	gpio_free(GPIO_CAM_MEGA_nRST);
 	gpio_free(GPIO_CAM_8M_ISP_INT);
+	gpio_free(GPIO_CAM_VGA_NRST);
+	gpio_free(GPIO_CAM_VGA_NSTBY);
 
 	if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A))
 		pr_err("Camera port A setup failed\n");
@@ -960,6 +1025,7 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
 	&s5p_device_fimc3,
+	&s5p_device_g2d,
 	&mmc0_fixed_voltage,
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc2,
@@ -969,7 +1035,6 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s3c_device_i2c5,
 	&s5p_device_i2c_hdmiphy,
 	&hdmi_fixed_voltage,
-	&exynos4_device_pd[PD_TV],
 	&s5p_device_hdmi,
 	&s5p_device_sdo,
 	&s5p_device_mixer,
@@ -982,9 +1047,7 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s5p_device_mfc,
 	&s5p_device_mfc_l,
 	&s5p_device_mfc_r,
-	&exynos4_device_pd[PD_MFC],
-	&exynos4_device_pd[PD_LCD0],
-	&exynos4_device_pd[PD_CAM],
+	&cam_vt_dio_fixed_reg_dev,
 	&cam_i_core_fixed_reg_dev,
 	&cam_s_if_fixed_reg_dev,
 	&s5p_device_fimc_md,
@@ -997,16 +1060,12 @@ static void __init universal_map_io(void)
 	s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
 }
 
-void s5p_tv_setup(void)
+static void s5p_tv_setup(void)
 {
 	/* direct HPD to HDMI chip */
 	gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
 	s3c_gpio_cfgpin(EXYNOS4_GPX3(7), S3C_GPIO_SFN(0x3));
 	s3c_gpio_setpull(EXYNOS4_GPX3(7), S3C_GPIO_PULL_NONE);
-
-	/* setup dependencies between TV devices */
-	s5p_device_hdmi.dev.parent = &exynos4_device_pd[PD_TV].dev;
-	s5p_device_mixer.dev.parent = &exynos4_device_pd[PD_TV].dev;
 }
 
 static void __init universal_reserve(void)
@@ -1040,15 +1099,6 @@ static void __init universal_machine_init(void)
 
 	/* Last */
 	platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
-
-	s5p_device_mfc.dev.parent = &exynos4_device_pd[PD_MFC].dev;
-	s5p_device_fimd0.dev.parent = &exynos4_device_pd[PD_LCD0].dev;
-
-	s5p_device_fimc0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc1.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc2.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_fimc3.dev.parent = &exynos4_device_pd[PD_CAM].dev;
-	s5p_device_mipi_csis0.dev.parent = &exynos4_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
new file mode 100644
index 0000000..0b04af2
--- /dev/null
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -0,0 +1,195 @@
+/*
+ * Exynos Generic power domain support.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Implementation of Exynos specific power domain control which is used in
+ * conjunction with runtime-pm. Support for both device-tree and non-device-tree
+ * based power domain support is included.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/pm_domain.h>
+#include <linux/delay.h>
+#include <linux/of_address.h>
+
+#include <mach/regs-pmu.h>
+#include <plat/devs.h>
+
+/*
+ * Exynos specific wrapper around the generic power domain
+ */
+struct exynos_pm_domain {
+	void __iomem *base;
+	char const *name;
+	bool is_off;
+	struct generic_pm_domain pd;
+};
+
+static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
+{
+	struct exynos_pm_domain *pd;
+	void __iomem *base;
+	u32 timeout, pwr;
+	char *op;
+
+	pd = container_of(domain, struct exynos_pm_domain, pd);
+	base = pd->base;
+
+	pwr = power_on ? S5P_INT_LOCAL_PWR_EN : 0;
+	__raw_writel(pwr, base);
+
+	/* Wait max 1ms */
+	timeout = 10;
+
+	while ((__raw_readl(base + 0x4) & S5P_INT_LOCAL_PWR_EN)	!= pwr) {
+		if (!timeout) {
+			op = (power_on) ? "enable" : "disable";
+			pr_err("Power domain %s %s failed\n", domain->name, op);
+			return -ETIMEDOUT;
+		}
+		timeout--;
+		cpu_relax();
+		usleep_range(80, 100);
+	}
+	return 0;
+}
+
+static int exynos_pd_power_on(struct generic_pm_domain *domain)
+{
+	return exynos_pd_power(domain, true);
+}
+
+static int exynos_pd_power_off(struct generic_pm_domain *domain)
+{
+	return exynos_pd_power(domain, false);
+}
+
+#define EXYNOS_GPD(PD, BASE, NAME)			\
+static struct exynos_pm_domain PD = {			\
+	.base = (void __iomem *)BASE,			\
+	.name = NAME,					\
+	.pd = {						\
+		.power_off = exynos_pd_power_off,	\
+		.power_on = exynos_pd_power_on,	\
+	},						\
+}
+
+#ifdef CONFIG_OF
+static __init int exynos_pm_dt_parse_domains(void)
+{
+	struct device_node *np;
+
+	for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
+		struct exynos_pm_domain *pd;
+
+		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+		if (!pd) {
+			pr_err("%s: failed to allocate memory for domain\n",
+					__func__);
+			return -ENOMEM;
+		}
+
+		if (of_get_property(np, "samsung,exynos4210-pd-off", NULL))
+			pd->is_off = true;
+		pd->name = np->name;
+		pd->base = of_iomap(np, 0);
+		pd->pd.power_off = exynos_pd_power_off;
+		pd->pd.power_on = exynos_pd_power_on;
+		pd->pd.of_node = np;
+		pm_genpd_init(&pd->pd, NULL, false);
+	}
+	return 0;
+}
+#else
+static __init int exynos_pm_dt_parse_domains(void)
+{
+	return 0;
+}
+#endif /* CONFIG_OF */
+
+static __init void exynos_pm_add_dev_to_genpd(struct platform_device *pdev,
+						struct exynos_pm_domain *pd)
+{
+	if (pdev->dev.bus) {
+		if (pm_genpd_add_device(&pd->pd, &pdev->dev))
+			pr_info("%s: error in adding %s device to %s power"
+				"domain\n", __func__, dev_name(&pdev->dev),
+				pd->name);
+	}
+}
+
+EXYNOS_GPD(exynos4_pd_mfc, S5P_PMU_MFC_CONF, "pd-mfc");
+EXYNOS_GPD(exynos4_pd_g3d, S5P_PMU_G3D_CONF, "pd-g3d");
+EXYNOS_GPD(exynos4_pd_lcd0, S5P_PMU_LCD0_CONF, "pd-lcd0");
+EXYNOS_GPD(exynos4_pd_lcd1, S5P_PMU_LCD1_CONF, "pd-lcd1");
+EXYNOS_GPD(exynos4_pd_tv, S5P_PMU_TV_CONF, "pd-tv");
+EXYNOS_GPD(exynos4_pd_cam, S5P_PMU_CAM_CONF, "pd-cam");
+EXYNOS_GPD(exynos4_pd_gps, S5P_PMU_GPS_CONF, "pd-gps");
+
+static struct exynos_pm_domain *exynos4_pm_domains[] = {
+	&exynos4_pd_mfc,
+	&exynos4_pd_g3d,
+	&exynos4_pd_lcd0,
+	&exynos4_pd_lcd1,
+	&exynos4_pd_tv,
+	&exynos4_pd_cam,
+	&exynos4_pd_gps,
+};
+
+static __init int exynos4_pm_init_power_domain(void)
+{
+	int idx;
+
+	if (of_have_populated_dt())
+		return exynos_pm_dt_parse_domains();
+
+	for (idx = 0; idx < ARRAY_SIZE(exynos4_pm_domains); idx++)
+		pm_genpd_init(&exynos4_pm_domains[idx]->pd, NULL,
+				exynos4_pm_domains[idx]->is_off);
+
+#ifdef CONFIG_S5P_DEV_FIMD0
+	exynos_pm_add_dev_to_genpd(&s5p_device_fimd0, &exynos4_pd_lcd0);
+#endif
+#ifdef CONFIG_S5P_DEV_TV
+	exynos_pm_add_dev_to_genpd(&s5p_device_hdmi, &exynos4_pd_tv);
+	exynos_pm_add_dev_to_genpd(&s5p_device_mixer, &exynos4_pd_tv);
+#endif
+#ifdef CONFIG_S5P_DEV_MFC
+	exynos_pm_add_dev_to_genpd(&s5p_device_mfc, &exynos4_pd_mfc);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC0
+	exynos_pm_add_dev_to_genpd(&s5p_device_fimc0, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC1
+	exynos_pm_add_dev_to_genpd(&s5p_device_fimc1, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC2
+	exynos_pm_add_dev_to_genpd(&s5p_device_fimc2, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+	exynos_pm_add_dev_to_genpd(&s5p_device_fimc3, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_CSIS0
+	exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis0, &exynos4_pd_cam);
+#endif
+#ifdef CONFIG_S5P_DEV_CSIS1
+	exynos_pm_add_dev_to_genpd(&s5p_device_mipi_csis1, &exynos4_pd_cam);
+#endif
+	return 0;
+}
+arch_initcall(exynos4_pm_init_power_domain);
+
+static __init int exynos_pm_late_initcall(void)
+{
+	pm_genpd_poweroff_unused();
+	return 0;
+}
+late_initcall(exynos_pm_late_initcall);
diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h
deleted file mode 100644
index a174a58..0000000
--- a/arch/arm/mach-footbridge/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- *  arch/arm/mach-footbridge/include/mach/system.h
- *
- *  Copyright (C) 1996-1999 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile
index c5b24b9..7355c0b 100644
--- a/arch/arm/mach-gemini/Makefile
+++ b/arch/arm/mach-gemini/Makefile
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y			:= irq.o mm.o time.o devices.o gpio.o
+obj-y			:= irq.o mm.o time.o devices.o gpio.o idle.o
 
 # Board-specific support
 obj-$(CONFIG_MACH_NAS4220B)	+= board-nas4220b.o
diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c
new file mode 100644
index 0000000..92bbd6b
--- /dev/null
+++ b/arch/arm/mach-gemini/idle.c
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-gemini/idle.c
+ */
+
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/proc-fns.h>
+
+static void gemini_idle(void)
+{
+	/*
+	 * Because of broken hardware we have to enable interrupts or the CPU
+	 * will never wakeup... Acctualy it is not very good to enable
+	 * interrupts first since scheduler can miss a tick, but there is
+	 * no other way around this. Platforms that needs it for power saving
+	 * should call enable_hlt() in init code, since by default it is
+	 * disabled.
+	 */
+	local_irq_enable();
+	cpu_do_idle();
+}
+
+static int __init gemini_idle_init(void)
+{
+	arm_pm_idle = gemini_idle;
+	return 0;
+}
+
+arch_initcall(gemini_idle_init);
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h
index 4d9c1f8..a33b5a1 100644
--- a/arch/arm/mach-gemini/include/mach/system.h
+++ b/arch/arm/mach-gemini/include/mach/system.h
@@ -14,20 +14,6 @@
 #include <mach/hardware.h>
 #include <mach/global_reg.h>
 
-static inline void arch_idle(void)
-{
-	/*
-	 * Because of broken hardware we have to enable interrupts or the CPU
-	 * will never wakeup... Acctualy it is not very good to enable
-	 * interrupts here since scheduler can miss a tick, but there is
-	 * no other way around this. Platforms that needs it for power saving
-	 * should call enable_hlt() in init code, since by default it is
-	 * disabled.
-	 */
-	local_irq_enable();
-	cpu_do_idle();
-}
-
 static inline void arch_reset(char mode, const char *cmd)
 {
 	__raw_writel(RESET_GLOBAL | RESET_CPU1,
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
index 9485a8f..ca70e5f 100644
--- a/arch/arm/mach-gemini/irq.c
+++ b/arch/arm/mach-gemini/irq.c
@@ -73,8 +73,8 @@ void __init gemini_init_irq(void)
 	unsigned int i, mode = 0, level = 0;
 
 	/*
-	 * Disable arch_idle() by default since it is buggy
-	 * For more info see arch/arm/mach-gemini/include/mach/system.h
+	 * Disable the idle handler by default since it is buggy
+	 * For more info see arch/arm/mach-gemini/idle.c
 	 */
 	disable_hlt();
 
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index f8a2f6b..e756d1a 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -247,3 +247,21 @@ void h720x_restart(char mode, const char *cmd)
 {
 	CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET;
 }
+
+static void h720x__idle(void)
+{
+	CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
+	nop();
+	nop();
+	CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
+	nop();
+	nop();
+}
+
+static int __init h720x_idle_init(void)
+{
+	arm_pm_idle = h720x__idle;
+	return 0;
+}
+
+arch_initcall(h720x_idle_init);
diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h
deleted file mode 100644
index 16ac46e..0000000
--- a/arch/arm/mach-h720x/include/mach/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * arch/arm/mach-h720x/include/mach/system.h
- *
- * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- * arch/arm/mach-h720x/include/mach/system.h
- *
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-#include <mach/hardware.h>
-
-static void arch_idle(void)
-{
-	CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
-	nop();
-	nop();
-	CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
-	nop();
-	nop();
-}
-
-#endif
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 8394d51..ffce267 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -34,7 +34,6 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <mach/irqs.h>
 
 #include "core.h"
 #include "sysregs.h"
@@ -109,7 +108,7 @@ static void __init highbank_timer_init(void)
 
 	highbank_clocks_init();
 
-	sp804_clocksource_init(timer_base + 0x20, "timer1");
+	sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
 	sp804_clockevents_init(timer_base, irq, "timer0");
 }
 
diff --git a/arch/arm/mach-highbank/include/mach/irqs.h b/arch/arm/mach-highbank/include/mach/irqs.h
deleted file mode 100644
index 9746aab..0000000
--- a/arch/arm/mach-highbank/include/mach/irqs.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __MACH_IRQS_H
-#define __MACH_IRQS_H
-
-#define NR_IRQS			192
-
-#endif
diff --git a/arch/arm/mach-highbank/include/mach/memory.h b/arch/arm/mach-highbank/include/mach/memory.h
deleted file mode 100644
index 40a8c17..0000000
--- a/arch/arm/mach-highbank/include/mach/memory.h
+++ /dev/null
@@ -1 +0,0 @@
-/* empty */
diff --git a/arch/arm/mach-highbank/include/mach/system.h b/arch/arm/mach-highbank/include/mach/system.h
deleted file mode 100644
index b1d8b5f..0000000
--- a/arch/arm/mach-highbank/include/mach/system.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2010-2011 Calxeda, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index e6bad17..1e03ef4 100644
--- a/arch/arm/mach-imx/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
@@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
 static int __init imx51_tzic_add_irq_domain(struct device_node *np,
 				struct device_node *interrupt_parent)
 {
-	irq_domain_add_simple(np, 0);
+	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
 	return 0;
 }
 
@@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
 	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
 	gpio_irq_base -= 32;
-	irq_domain_add_simple(np, gpio_irq_base);
+	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index 05ebb3e..fd5be0f 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
 static int __init imx53_tzic_add_irq_domain(struct device_node *np,
 				struct device_node *interrupt_parent)
 {
-	irq_domain_add_simple(np, 0);
+	irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
 	return 0;
 }
 
@@ -61,7 +61,7 @@ static int __init imx53_gpio_add_irq_domain(struct device_node *np,
 	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
 	gpio_irq_base -= 32;
-	irq_domain_add_simple(np, gpio_irq_base);
+	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index c257281..6075d4d 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -97,7 +97,8 @@ static int __init imx6q_gpio_add_irq_domain(struct device_node *np,
 	static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
 
 	gpio_irq_base -= 32;
-	irq_domain_add_simple(np, gpio_irq_base);
+	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
+			      NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index f225262..96e042d 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -507,7 +507,7 @@ static void mx31moboard_poweroff(void)
 	struct clk *clk = clk_get_sys("imx2-wdt.0", NULL);
 
 	if (!IS_ERR(clk))
-		clk_enable(clk);
+		clk_prepare_enable(clk);
 
 	mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST);
 
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 31807d2..8404ee7 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -34,31 +34,29 @@ static void imx3_idle(void)
 {
 	unsigned long reg = 0;
 
-	if (!need_resched())
-		__asm__ __volatile__(
-			/* disable I and D cache */
-			"mrc p15, 0, %0, c1, c0, 0\n"
-			"bic %0, %0, #0x00001000\n"
-			"bic %0, %0, #0x00000004\n"
-			"mcr p15, 0, %0, c1, c0, 0\n"
-			/* invalidate I cache */
-			"mov %0, #0\n"
-			"mcr p15, 0, %0, c7, c5, 0\n"
-			/* clear and invalidate D cache */
-			"mov %0, #0\n"
-			"mcr p15, 0, %0, c7, c14, 0\n"
-			/* WFI */
-			"mov %0, #0\n"
-			"mcr p15, 0, %0, c7, c0, 4\n"
-			"nop\n" "nop\n" "nop\n" "nop\n"
-			"nop\n" "nop\n" "nop\n"
-			/* enable I and D cache */
-			"mrc p15, 0, %0, c1, c0, 0\n"
-			"orr %0, %0, #0x00001000\n"
-			"orr %0, %0, #0x00000004\n"
-			"mcr p15, 0, %0, c1, c0, 0\n"
-			: "=r" (reg));
-	local_irq_enable();
+	__asm__ __volatile__(
+		/* disable I and D cache */
+		"mrc p15, 0, %0, c1, c0, 0\n"
+		"bic %0, %0, #0x00001000\n"
+		"bic %0, %0, #0x00000004\n"
+		"mcr p15, 0, %0, c1, c0, 0\n"
+		/* invalidate I cache */
+		"mov %0, #0\n"
+		"mcr p15, 0, %0, c7, c5, 0\n"
+		/* clear and invalidate D cache */
+		"mov %0, #0\n"
+		"mcr p15, 0, %0, c7, c14, 0\n"
+		/* WFI */
+		"mov %0, #0\n"
+		"mcr p15, 0, %0, c7, c0, 4\n"
+		"nop\n" "nop\n" "nop\n" "nop\n"
+		"nop\n" "nop\n" "nop\n"
+		/* enable I and D cache */
+		"mrc p15, 0, %0, c1, c0, 0\n"
+		"orr %0, %0, #0x00001000\n"
+		"orr %0, %0, #0x00000004\n"
+		"mcr p15, 0, %0, c1, c0, 0\n"
+		: "=r" (reg));
 }
 
 static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size,
@@ -134,8 +132,8 @@ void __init imx31_init_early(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX31);
 	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
-	pm_idle = imx3_idle;
 	imx_ioremap = imx3_ioremap;
+	arm_pm_idle = imx3_idle;
 }
 
 void __init mx31_init_irq(void)
@@ -197,7 +195,7 @@ void __init imx35_init_early(void)
 	mxc_set_cpu_type(MXC_CPU_MX35);
 	mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
 	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
-	pm_idle = imx3_idle;
+	arm_pm_idle = imx3_idle;
 	imx_ioremap = imx3_ioremap;
 }
 
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index bc17dfe..49549a7 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -26,23 +26,17 @@ static struct clk *gpc_dvfs_clk;
 
 static void imx5_idle(void)
 {
-	if (!need_resched()) {
-		/* gpc clock is needed for SRPG */
-		if (gpc_dvfs_clk == NULL) {
-			gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
-			if (IS_ERR(gpc_dvfs_clk))
-				goto err0;
-		}
-		clk_enable(gpc_dvfs_clk);
-		mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
-		if (tzic_enable_wake())
-			goto err1;
-		cpu_do_idle();
-err1:
-		clk_disable(gpc_dvfs_clk);
+	/* gpc clock is needed for SRPG */
+	if (gpc_dvfs_clk == NULL) {
+		gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+		if (IS_ERR(gpc_dvfs_clk))
+			return;
 	}
-err0:
-	local_irq_enable();
+	clk_enable(gpc_dvfs_clk);
+	mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+	if (tzic_enable_wake() != 0)
+		cpu_do_idle();
+	clk_disable(gpc_dvfs_clk);
 }
 
 /*
@@ -108,7 +102,7 @@ void __init imx51_init_early(void)
 	mxc_set_cpu_type(MXC_CPU_MX51);
 	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
 	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
-	pm_idle = imx5_idle;
+	arm_pm_idle = imx5_idle;
 }
 
 void __init imx53_init_early(void)
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
index e455d2f..6fcffa7 100644
--- a/arch/arm/mach-imx/pm-imx27.c
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -10,7 +10,6 @@
 #include <linux/kernel.h>
 #include <linux/suspend.h>
 #include <linux/io.h>
-#include <mach/system.h>
 #include <mach/hardware.h>
 
 static int mx27_suspend_enter(suspend_state_t state)
@@ -23,7 +22,7 @@ static int mx27_suspend_enter(suspend_state_t state)
 		cscr &= 0xFFFFFFFC;
 		__raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
 		/* Executes WFI */
-		arch_idle();
+		cpu_do_idle();
 		break;
 
 	default:
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c
index 6dc0934..e26a9cb 100644
--- a/arch/arm/mach-imx/pm-imx5.c
+++ b/arch/arm/mach-imx/pm-imx5.c
@@ -89,7 +89,7 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
 
 static int mx5_suspend_prepare(void)
 {
-	return clk_enable(gpc_dvfs_clk);
+	return clk_prepare_enable(gpc_dvfs_clk);
 }
 
 static int mx5_suspend_enter(suspend_state_t state)
@@ -119,7 +119,7 @@ static int mx5_suspend_enter(suspend_state_t state)
 
 static void mx5_suspend_finish(void)
 {
-	clk_disable(gpc_dvfs_clk);
+	clk_disable_unprepare(gpc_dvfs_clk);
 }
 
 static int mx5_pm_valid(suspend_state_t state)
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 019f0ab..15b87f2 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -35,67 +35,23 @@
 
 static struct amba_pl010_data integrator_uart_data;
 
-static struct amba_device rtc_device = {
-	.dev		= {
-		.init_name = "mb:15",
-	},
-	.res		= {
-		.start	= INTEGRATOR_RTC_BASE,
-		.end	= INTEGRATOR_RTC_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_RTCINT, NO_IRQ },
-};
+#define INTEGRATOR_RTC_IRQ	{ IRQ_RTCINT }
+#define INTEGRATOR_UART0_IRQ	{ IRQ_UARTINT0 }
+#define INTEGRATOR_UART1_IRQ	{ IRQ_UARTINT1 }
+#define KMI0_IRQ		{ IRQ_KMIINT0 }
+#define KMI1_IRQ		{ IRQ_KMIINT1 }
 
-static struct amba_device uart0_device = {
-	.dev		= {
-		.init_name = "mb:16",
-		.platform_data = &integrator_uart_data,
-	},
-	.res		= {
-		.start	= INTEGRATOR_UART0_BASE,
-		.end	= INTEGRATOR_UART0_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_UARTINT0, NO_IRQ },
-};
+static AMBA_APB_DEVICE(rtc, "mb:15", 0,
+	INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
 
-static struct amba_device uart1_device = {
-	.dev		= {
-		.init_name = "mb:17",
-		.platform_data = &integrator_uart_data,
-	},
-	.res		= {
-		.start	= INTEGRATOR_UART1_BASE,
-		.end	= INTEGRATOR_UART1_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_UARTINT1, NO_IRQ },
-};
+static AMBA_APB_DEVICE(uart0, "mb:16", 0,
+	INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data);
 
-static struct amba_device kmi0_device = {
-	.dev		= {
-		.init_name = "mb:18",
-	},
-	.res		= {
-		.start	= KMI0_BASE,
-		.end	= KMI0_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_KMIINT0, NO_IRQ },
-};
+static AMBA_APB_DEVICE(uart1, "mb:17", 0,
+	INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data);
 
-static struct amba_device kmi1_device = {
-	.dev		= {
-		.init_name = "mb:19",
-	},
-	.res		= {
-		.start	= KMI1_BASE,
-		.end	= KMI1_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_KMIINT1, NO_IRQ },
-};
+static AMBA_APB_DEVICE(kmi0, "mb:18", 0, KMI0_BASE, KMI0_IRQ, NULL);
+static AMBA_APB_DEVICE(kmi1, "mb:19", 0, KMI1_BASE, KMI1_IRQ, NULL);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&rtc_device,
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 8cbb75a..3e538da 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -401,24 +401,21 @@ static int impd1_probe(struct lm_device *dev)
 
 		pc_base = dev->resource.start + idev->offset;
 
-		d = kzalloc(sizeof(struct amba_device), GFP_KERNEL);
+		d = amba_device_alloc(NULL, pc_base, SZ_4K);
 		if (!d)
 			continue;
 
 		dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
 		d->dev.parent	= &dev->dev;
-		d->res.start	= dev->resource.start + idev->offset;
-		d->res.end	= d->res.start + SZ_4K - 1;
-		d->res.flags	= IORESOURCE_MEM;
 		d->irq[0]	= dev->irq;
 		d->irq[1]	= dev->irq;
 		d->periphid	= idev->id;
 		d->dev.platform_data = idev->platform_data;
 
-		ret = amba_device_register(d, &dev->resource);
+		ret = amba_device_add(d, &dev->resource);
 		if (ret) {
 			dev_err(&d->dev, "unable to register device: %d\n", ret);
-			kfree(d);
+			amba_device_put(d);
 		}
 	}
 
diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h
deleted file mode 100644
index 901514eb..0000000
--- a/arch/arm/mach-integrator/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  arch/arm/mach-integrator/include/mach/system.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 21a1d6c..4dde28b 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -42,6 +42,7 @@
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
 #include <asm/mach-types.h>
+#include <asm/sched_clock.h>
 
 #include <mach/lm.h>
 
@@ -325,6 +326,11 @@ static void __init ap_init(void)
 
 static unsigned long timer_reload;
 
+static u32 notrace integrator_read_sched_clock(void)
+{
+	return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
+}
+
 static void integrator_clocksource_init(unsigned long inrate)
 {
 	void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
@@ -341,6 +347,7 @@ static void integrator_clocksource_init(unsigned long inrate)
 
 	clocksource_mmio_init(base + TIMER_VALUE, "timer2",
 			rate, 200, 16, clocksource_mmio_readl_down);
+	setup_sched_clock(integrator_read_sched_clock, 16, rate);
 }
 
 static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index a8b6aa6..be9ead4 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -347,32 +347,14 @@ static struct mmci_platform_data mmc_data = {
 	.gpio_cd	= -1,
 };
 
-static struct amba_device mmc_device = {
-	.dev		= {
-		.init_name = "mb:1c",
-		.platform_data = &mmc_data,
-	},
-	.res		= {
-		.start	= INTEGRATOR_CP_MMC_BASE,
-		.end	= INTEGRATOR_CP_MMC_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 },
-	.periphid	= 0,
-};
+#define INTEGRATOR_CP_MMC_IRQS	{ IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
+#define INTEGRATOR_CP_AACI_IRQS	{ IRQ_CP_AACIINT }
 
-static struct amba_device aaci_device = {
-	.dev		= {
-		.init_name = "mb:1d",
-	},
-	.res		= {
-		.start	= INTEGRATOR_CP_AACI_BASE,
-		.end	= INTEGRATOR_CP_AACI_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { IRQ_CP_AACIINT, NO_IRQ },
-	.periphid	= 0,
-};
+static AMBA_APB_DEVICE(mmc, "mb:1c", 0, INTEGRATOR_CP_MMC_BASE,
+	INTEGRATOR_CP_MMC_IRQS, &mmc_data);
+
+static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE,
+	INTEGRATOR_CP_AACI_IRQS, NULL);
 
 
 /*
@@ -425,21 +407,8 @@ static struct clcd_board clcd_data = {
 	.remove		= versatile_clcd_remove_dma,
 };
 
-static struct amba_device clcd_device = {
-	.dev		= {
-		.init_name = "mb:c0",
-		.coherent_dma_mask = ~0,
-		.platform_data = &clcd_data,
-	},
-	.res		= {
-		.start	= INTCP_PA_CLCD_BASE,
-		.end	= INTCP_PA_CLCD_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.dma_mask	= ~0,
-	.irq		= { IRQ_CP_CLCDCINT, NO_IRQ },
-	.periphid	= 0,
-};
+static AMBA_AHB_DEVICE(clcd, "mb:c0", 0, INTCP_PA_CLCD_BASE,
+	{ IRQ_CP_CLCDCINT }, &clcd_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&mmc_device,
diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h
deleted file mode 100644
index 1f31ed3..0000000
--- a/arch/arm/mach-iop13xx/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-iop13xx/include/mach/system.h
- *
- *  Copyright (C) 2004 Intel Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h
deleted file mode 100644
index 4a88727..0000000
--- a/arch/arm/mach-iop32x/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/system.h
- *
- * Copyright (C) 2001 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 version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h
deleted file mode 100644
index 4f98e76..0000000
--- a/arch/arm/mach-iop33x/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-iop33x/include/mach/system.h
- *
- * Copyright (C) 2001 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 version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h
deleted file mode 100644
index a7fb08b..0000000
--- a/arch/arm/mach-ixp2000/include/mach/system.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * arch/arm/mach-ixp2000/include/mach/system.h
- *
- * Copyright (C) 2002 Intel Corp.
- * Copyricht (C) 2003-2005 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 version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 0923bb9..7c1495e 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -441,6 +441,9 @@ static struct platform_device *ixp23xx_devices[] __initdata = {
 
 void __init ixp23xx_sys_init(void)
 {
+	/* by default, the idle code is disabled */
+	disable_hlt();
+
 	*IXP23XX_EXP_UNIT_FUSE |= 0xf;
 	platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
 }
diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h
deleted file mode 100644
index 277dda7..0000000
--- a/arch/arm/mach-ixp23xx/include/mach/system.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-ixp23xx/include/mach/system.h
- *
- * Copyright (C) 2003 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-#if 0
-	if (!hlt_counter)
-		cpu_do_idle();
-#endif
-}
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 3841ab4..a6329a0 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -236,6 +236,12 @@ void __init ixp4xx_init_irq(void)
 {
 	int i = 0;
 
+	/*
+	 * ixp4xx does not implement the XScale PWRMODE register
+	 * so it must not call cpu_do_idle().
+	 */
+	disable_hlt();
+
 	/* Route all sources to IRQ instead of FIQ */
 	*IXP4XX_ICLR = 0x0;
 
diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h
deleted file mode 100644
index 140a9be..0000000
--- a/arch/arm/mach-ixp4xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/system.h
- *
- * Copyright (C) 2002 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-static inline void arch_idle(void)
-{
-	/* ixp4xx does not implement the XScale PWRMODE register,
-	 * so it must not call cpu_do_idle() here.
-	 */
-#if 0
-	cpu_do_idle();
-#endif
-}
diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h
deleted file mode 100644
index 5fddde0..0000000
--- a/arch/arm/mach-kirkwood/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/include/mach/system.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index 01f8c89..7e99c3f 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -83,6 +83,11 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
 	},
 };
 
+static struct platform_device openrd_client_audio_device = {
+	.name		= "openrd-client-audio",
+	.id		= -1,
+};
+
 static int __initdata uart1;
 
 static int __init sd_uart_selection(char *str)
@@ -172,6 +177,7 @@ static void __init openrd_init(void)
 	kirkwood_i2c_init();
 
 	if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
+		platform_device_register(&openrd_client_audio_device);
 		i2c_register_board_info(0, i2c_board_info,
 			ARRAY_SIZE(i2c_board_info));
 		kirkwood_audio_init();
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index 966b2b3..f9d2a11 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -106,6 +106,11 @@ static struct platform_device hp_t5325_button_device = {
 	}
 };
 
+static struct platform_device hp_t5325_audio_device = {
+	.name		= "t5325-audio",
+	.id		= -1,
+};
+
 static unsigned int hp_t5325_mpp_config[] __initdata = {
 	MPP0_NF_IO2,
 	MPP1_SPI_MOSI,
@@ -179,6 +184,7 @@ static void __init hp_t5325_init(void)
 	kirkwood_sata_init(&hp_t5325_sata_data);
 	kirkwood_ehci_init();
 	platform_device_register(&hp_t5325_button_device);
+	platform_device_register(&hp_t5325_audio_device);
 
 	i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info));
 	kirkwood_audio_init();
diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h
deleted file mode 100644
index 59fe992..0000000
--- a/arch/arm/mach-ks8695/include/mach/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * arch/arm/mach-s3c2410/include/mach/system.h
- *
- * Copyright (C) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * KS8695 - System function defines and includes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks,
-	 */
-	cpu_do_idle();
-
-}
-
-#endif
diff --git a/arch/arm/mach-ks8695/leds.c b/arch/arm/mach-ks8695/leds.c
index d6f6502..4bd7075 100644
--- a/arch/arm/mach-ks8695/leds.c
+++ b/arch/arm/mach-ks8695/leds.c
@@ -11,7 +11,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/gpio.h>
 
 #include <asm/leds.h>
 #include <mach/devices.h>
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index 1e02751..0e01bf4 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -82,6 +82,7 @@
  *   will also impact the individual peripheral rates.
  */
 
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/errno.h>
@@ -97,9 +98,10 @@
 #include "clock.h"
 #include "common.h"
 
+static DEFINE_SPINLOCK(global_clkregs_lock);
+
 static struct clk clk_armpll;
 static struct clk clk_usbpll;
-static DEFINE_MUTEX(clkm_lock);
 
 /*
  * Post divider values for PLLs based on selected register value
@@ -127,7 +129,7 @@ static struct clk osc_32KHz = {
 static int local_pll397_enable(struct clk *clk, int enable)
 {
 	u32 reg;
-	unsigned long timeout = 1 + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(10);
 
 	reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL);
 
@@ -142,7 +144,7 @@ static int local_pll397_enable(struct clk *clk, int enable)
 		/* Wait for PLL397 lock */
 		while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
 			LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) &&
-			(timeout > jiffies))
+			time_before(jiffies, timeout))
 			cpu_relax();
 
 		if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
@@ -156,7 +158,7 @@ static int local_pll397_enable(struct clk *clk, int enable)
 static int local_oscmain_enable(struct clk *clk, int enable)
 {
 	u32 reg;
-	unsigned long timeout = 1 + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(10);
 
 	reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL);
 
@@ -171,7 +173,7 @@ static int local_oscmain_enable(struct clk *clk, int enable)
 		/* Wait for main oscillator to start */
 		while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
 			LPC32XX_CLKPWR_MOSC_DISABLE) != 0) &&
-			(timeout > jiffies))
+			time_before(jiffies, timeout))
 			cpu_relax();
 
 		if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
@@ -383,7 +385,7 @@ static int local_usbpll_enable(struct clk *clk, int enable)
 {
 	u32 reg;
 	int ret = -ENODEV;
-	unsigned long timeout = 1 + msecs_to_jiffies(10);
+	unsigned long timeout = jiffies + msecs_to_jiffies(10);
 
 	reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
 
@@ -396,7 +398,7 @@ static int local_usbpll_enable(struct clk *clk, int enable)
 		__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
 
 		/* Wait for PLL lock */
-		while ((timeout > jiffies) & (ret == -ENODEV)) {
+		while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
 			reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
 			if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
 				ret = 0;
@@ -891,20 +893,8 @@ static struct clk clk_lcd = {
 	.enable_mask	= LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
 };
 
-static inline void clk_lock(void)
-{
-	mutex_lock(&clkm_lock);
-}
-
-static inline void clk_unlock(void)
-{
-	mutex_unlock(&clkm_lock);
-}
-
 static void local_clk_disable(struct clk *clk)
 {
-	WARN_ON(clk->usecount == 0);
-
 	/* Don't attempt to disable clock if it has no users */
 	if (clk->usecount > 0) {
 		clk->usecount--;
@@ -947,10 +937,11 @@ static int local_clk_enable(struct clk *clk)
 int clk_enable(struct clk *clk)
 {
 	int ret;
+	unsigned long flags;
 
-	clk_lock();
+	spin_lock_irqsave(&global_clkregs_lock, flags);
 	ret = local_clk_enable(clk);
-	clk_unlock();
+	spin_unlock_irqrestore(&global_clkregs_lock, flags);
 
 	return ret;
 }
@@ -961,9 +952,11 @@ EXPORT_SYMBOL(clk_enable);
  */
 void clk_disable(struct clk *clk)
 {
-	clk_lock();
+	unsigned long flags;
+
+	spin_lock_irqsave(&global_clkregs_lock, flags);
 	local_clk_disable(clk);
-	clk_unlock();
+	spin_unlock_irqrestore(&global_clkregs_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
@@ -972,13 +965,7 @@ EXPORT_SYMBOL(clk_disable);
  */
 unsigned long clk_get_rate(struct clk *clk)
 {
-	unsigned long rate;
-
-	clk_lock();
-	rate = clk->get_rate(clk);
-	clk_unlock();
-
-	return rate;
+	return clk->get_rate(clk);
 }
 EXPORT_SYMBOL(clk_get_rate);
 
@@ -994,11 +981,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	 * the actual rate set as part of the peripheral dividers
 	 * instead of high level clock control
 	 */
-	if (clk->set_rate) {
-		clk_lock();
+	if (clk->set_rate)
 		ret = clk->set_rate(clk, rate);
-		clk_unlock();
-	}
 
 	return ret;
 }
@@ -1009,15 +993,11 @@ EXPORT_SYMBOL(clk_set_rate);
  */
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
-	clk_lock();
-
 	if (clk->round_rate)
 		rate = clk->round_rate(clk, rate);
 	else
 		rate = clk->get_rate(clk);
 
-	clk_unlock();
-
 	return rate;
 }
 EXPORT_SYMBOL(clk_round_rate);
@@ -1075,10 +1055,10 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1)
 	_REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan)
 	_REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
-	_REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0)
-	_REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1)
+	_REGISTER_CLOCK(NULL, "i2s0_ck", clk_i2s0)
+	_REGISTER_CLOCK(NULL, "i2s1_ck", clk_i2s1)
 	_REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc)
-	_REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc)
+	_REGISTER_CLOCK("dev:mmc0", NULL, clk_mmc)
 	_REGISTER_CLOCK("lpc-net.0", NULL, clk_net)
 	_REGISTER_CLOCK("dev:clcd", NULL, clk_lcd)
 	_REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd)
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
index 4b4e700..75640bfb 100644
--- a/arch/arm/mach-lpc32xx/common.h
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -65,7 +65,6 @@ extern u32 clk_get_pclk_div(void);
  */
 extern void lpc32xx_get_uid(u32 devid[4]);
 
-extern void lpc32xx_watchdog_reset(void);
 extern u32 lpc32xx_return_iram_size(void);
 
 /*
diff --git a/arch/arm/mach-lpc32xx/include/mach/system.h b/arch/arm/mach-lpc32xx/include/mach/system.h
deleted file mode 100644
index bf176c9..0000000
--- a/arch/arm/mach-lpc32xx/include/mach/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/include/mach/system.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * 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.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index bfee5b4..8571d62 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -149,20 +149,8 @@ static struct clcd_board lpc32xx_clcd_data = {
 	.remove		= lpc32xx_clcd_remove,
 };
 
-static struct amba_device lpc32xx_clcd_device = {
-	.dev				= {
-		.coherent_dma_mask	= ~0,
-		.init_name		= "dev:clcd",
-		.platform_data		= &lpc32xx_clcd_data,
-	},
-	.res				= {
-		.start			= LPC32XX_LCD_BASE,
-		.end			= (LPC32XX_LCD_BASE + SZ_4K - 1),
-		.flags			= IORESOURCE_MEM,
-	},
-	.dma_mask			= ~0,
-	.irq				= {IRQ_LPC32XX_LCD, NO_IRQ},
-};
+static AMBA_AHB_DEVICE(lpc32xx_clcd, "dev:clcd", 0,
+	LPC32XX_LCD_BASE, { IRQ_LPC32XX_LCD }, &lpc32xx_clcd_data);
 
 /*
  * AMBA SSP (SPI)
@@ -191,20 +179,8 @@ static struct pl022_ssp_controller lpc32xx_ssp0_data = {
 	.enable_dma		= 0,
 };
 
-static struct amba_device lpc32xx_ssp0_device = {
-	.dev				= {
-		.coherent_dma_mask	= ~0,
-		.init_name		= "dev:ssp0",
-		.platform_data		= &lpc32xx_ssp0_data,
-	},
-	.res				= {
-		.start			= LPC32XX_SSP0_BASE,
-		.end			= (LPC32XX_SSP0_BASE + SZ_4K - 1),
-		.flags			= IORESOURCE_MEM,
-	},
-	.dma_mask			= ~0,
-	.irq				= {IRQ_LPC32XX_SSP0, NO_IRQ},
-};
+static AMBA_APB_DEVICE(lpc32xx_ssp0, "dev:ssp0", 0,
+	LPC32XX_SSP0_BASE, { IRQ_LPC32XX_SSP0 }, &lpc32xx_ssp0_data);
 
 /* AT25 driver registration */
 static int __init phy3250_spi_board_register(void)
@@ -271,6 +247,8 @@ static struct platform_device lpc32xx_gpio_led_device = {
 };
 
 static struct platform_device *phy3250_devs[] __initdata = {
+	&lpc32xx_rtc_device,
+	&lpc32xx_tsc_device,
 	&lpc32xx_i2c0_device,
 	&lpc32xx_i2c1_device,
 	&lpc32xx_i2c2_device,
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 17cb760..5483d6f 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -24,6 +24,7 @@
 #include <mach/addr-map.h>
 #include <mach/mfp-pxa168.h>
 #include <mach/pxa168.h>
+#include <mach/irqs.h>
 #include <video/pxa168fb.h>
 #include <linux/input.h>
 #include <plat/pxa27x_keypad.h>
@@ -240,7 +241,7 @@ static void __init common_init(void)
 
 MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
 	.map_io		= mmp_map_io,
-	.nr_irqs	= IRQ_BOARD_START,
+	.nr_irqs	= MMP_NR_IRQS,
 	.init_irq       = pxa168_init_irq,
 	.timer          = &pxa168_timer,
 	.init_machine   = common_init,
@@ -249,7 +250,7 @@ MACHINE_END
 
 MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
 	.map_io		= mmp_map_io,
-	.nr_irqs	= IRQ_BOARD_START,
+	.nr_irqs	= MMP_NR_IRQS,
 	.init_irq       = pxa168_init_irq,
 	.timer          = &pxa168_timer,
 	.init_machine   = common_init,
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
index b148a9d..603542a 100644
--- a/arch/arm/mach-mmp/avengers_lite.c
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -43,6 +43,7 @@ static void __init avengers_lite_init(void)
 
 MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
 	.map_io		= mmp_map_io,
+	.nr_irqs	= MMP_NR_IRQS,
 	.init_irq       = pxa168_init_irq,
 	.timer          = &pxa168_timer,
 	.init_machine   = avengers_lite_init,
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
index d839fe6..5cb769c 100644
--- a/arch/arm/mach-mmp/brownstone.c
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -28,7 +28,7 @@
 
 #include "common.h"
 
-#define BROWNSTONE_NR_IRQS	(IRQ_BOARD_START + 40)
+#define BROWNSTONE_NR_IRQS	(MMP_NR_IRQS + 40)
 
 #define GPIO_5V_ENABLE		(89)
 
@@ -158,7 +158,7 @@ static struct platform_device brownstone_v_5vp_device = {
 };
 
 static struct max8925_platform_data brownstone_max8925_info = {
-	.irq_base		= IRQ_BOARD_START,
+	.irq_base		= MMP_NR_IRQS,
 };
 
 static struct i2c_board_info brownstone_twsi1_info[] = {
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
index 2ee8cd7..8059cc0 100644
--- a/arch/arm/mach-mmp/flint.c
+++ b/arch/arm/mach-mmp/flint.c
@@ -23,10 +23,11 @@
 #include <mach/addr-map.h>
 #include <mach/mfp-mmp2.h>
 #include <mach/mmp2.h>
+#include <mach/irqs.h>
 
 #include "common.h"
 
-#define FLINT_NR_IRQS	(IRQ_BOARD_START + 48)
+#define FLINT_NR_IRQS	(MMP_NR_IRQS + 48)
 
 static unsigned long flint_pin_config[] __initdata = {
 	/* UART1 */
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
index 8776546..f516e74 100644
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -191,7 +191,7 @@ static void __init gplugd_init(void)
 
 MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
 	.map_io		= mmp_map_io,
-	.nr_irqs	= IRQ_BOARD_START,
+	.nr_irqs	= MMP_NR_IRQS,
 	.init_irq       = pxa168_init_irq,
 	.timer          = &pxa168_timer,
 	.init_machine   = gplugd_init,
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
index 34635a0..d0e7466 100644
--- a/arch/arm/mach-mmp/include/mach/irqs.h
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -223,7 +223,6 @@
 #define MMP_GPIO_TO_IRQ(gpio)		(IRQ_GPIO_START + (gpio))
 
 #define IRQ_BOARD_START			(IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
-
-#define NR_IRQS				(IRQ_BOARD_START)
+#define MMP_NR_IRQS			IRQ_BOARD_START
 
 #endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h
deleted file mode 100644
index 1d001ea..0000000
--- a/arch/arm/mach-mmp/include/mach/system.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/system.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_MACH_SYSTEM_H
-#define __ASM_MACH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-#endif /* __ASM_MACH_SYSTEM_H */
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
index d21c544..7895d27 100644
--- a/arch/arm/mach-mmp/irq-mmp2.c
+++ b/arch/arm/mach-mmp/irq-mmp2.c
@@ -15,6 +15,7 @@
 #include <linux/irq.h>
 #include <linux/io.h>
 
+#include <mach/irqs.h>
 #include <mach/regs-icu.h>
 #include <mach/mmp2.h>
 
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
index 96cf5c8..ff73249 100644
--- a/arch/arm/mach-mmp/jasper.c
+++ b/arch/arm/mach-mmp/jasper.c
@@ -19,6 +19,7 @@
 #include <linux/mfd/max8925.h>
 #include <linux/interrupt.h>
 
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/addr-map.h>
@@ -27,7 +28,7 @@
 
 #include "common.h"
 
-#define JASPER_NR_IRQS		(IRQ_BOARD_START + 48)
+#define JASPER_NR_IRQS		(MMP_NR_IRQS + 48)
 
 static unsigned long jasper_pin_config[] __initdata = {
 	/* UART1 */
@@ -135,7 +136,7 @@ static struct max8925_power_pdata jasper_power_data = {
 static struct max8925_platform_data jasper_max8925_info = {
 	.backlight		= &jasper_backlight_data,
 	.power			= &jasper_power_data,
-	.irq_base		= IRQ_BOARD_START,
+	.irq_base		= MMP_NR_IRQS,
 };
 
 static struct i2c_board_info jasper_twsi1_info[] = {
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 8e3b5af0..507e6c0 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -102,6 +102,7 @@ static void __init tavorevb_init(void)
 
 MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
 	.map_io		= mmp_map_io,
+	.nr_irqs	= MMP_NR_IRQS,
 	.init_irq       = pxa910_init_irq,
 	.timer          = &pxa910_timer,
 	.init_machine   = tavorevb_init,
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
index 0523e42..42bef66 100644
--- a/arch/arm/mach-mmp/teton_bga.c
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -26,6 +26,7 @@
 #include <mach/mfp-pxa168.h>
 #include <mach/pxa168.h>
 #include <mach/teton_bga.h>
+#include <mach/irqs.h>
 
 #include "common.h"
 
@@ -83,7 +84,7 @@ static void __init teton_bga_init(void)
 
 MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
 	.map_io		= mmp_map_io,
-	.nr_irqs	= IRQ_BOARD_START,
+	.nr_irqs	= MMP_NR_IRQS,
 	.init_irq       = pxa168_init_irq,
 	.timer          = &pxa168_timer,
 	.init_machine   = teton_bga_init,
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 5ac5d58..4c5fd5b 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -38,7 +38,7 @@
  * 16 board interrupts -- PCA9575 GPIO expander
  * 24 board interrupts -- 88PM860x PMIC
  */
-#define TTCDKB_NR_IRQS		(IRQ_BOARD_START + 16 + 16 + 24)
+#define TTCDKB_NR_IRQS		(MMP_NR_IRQS + 16 + 16 + 24)
 
 static unsigned long ttc_dkb_pin_config[] __initdata = {
 	/* UART2 */
@@ -130,7 +130,7 @@ static struct platform_device *ttc_dkb_devices[] = {
 static struct pca953x_platform_data max7312_data[] = {
 	{
 		.gpio_base	= TTCDKB_GPIO_EXT0(0),
-		.irq_base	= IRQ_BOARD_START,
+		.irq_base	= MMP_NR_IRQS,
 	},
 };
 
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 0a11342..962e711 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -80,12 +80,8 @@ static struct of_device_id msm_dt_gic_match[] __initdata = {
 
 static void __init msm8x60_dt_init(void)
 {
-	struct device_node *node;
-
-	node = of_find_matching_node_by_address(NULL, msm_dt_gic_match,
-			MSM8X60_QGIC_DIST_PHYS);
-	if (node)
-		irq_domain_add_simple(node, GIC_SPI_START);
+	irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS,
+				GIC_SPI_START);
 
 	if (of_machine_is_compatible("qcom,msm8660-surf")) {
 		printk(KERN_INFO "Init surf UART registers\n");
diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S
deleted file mode 100644
index 6a94f05..0000000
--- a/arch/arm/mach-msm/idle.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* arch/arm/mach-msm/include/mach/idle.S
- *
- * Idle processing for MSM7K - work around bugs with SWFI.
- *
- * Copyright (c) 2007 QUALCOMM Incorporated.
- * Copyright (C) 2007 Google, Inc. 
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */ 
-		
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-ENTRY(arch_idle)
-#ifdef CONFIG_MSM7X00A_IDLE
-	mrc     p15, 0, r1, c1, c0, 0    /* read current CR    */
-	bic     r0, r1, #(1 << 2)        /* clear dcache bit   */
-	bic     r0, r0, #(1 << 12)       /* clear icache bit   */
-	mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */
-
-	mov     r0, #0                   /* prepare wfi value  */
-	mcr     p15, 0, r0, c7, c10, 0   /* flush the cache    */
-	mcr     p15, 0, r0, c7, c10, 4   /* memory barrier     */
-	mcr     p15, 0, r0, c7, c0, 4    /* wait for interrupt */
-
-	mcr     p15, 0, r1, c1, c0, 0    /* restore d/i cache  */
-#endif
-	mov     pc, lr
diff --git a/arch/arm/mach-msm/idle.c b/arch/arm/mach-msm/idle.c
new file mode 100644
index 0000000..0c9e13c
--- /dev/null
+++ b/arch/arm/mach-msm/idle.c
@@ -0,0 +1,49 @@
+/* arch/arm/mach-msm/idle.c
+ *
+ * Idle processing for MSM7K - work around bugs with SWFI.
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated.
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <asm/system.h>
+
+static void msm_idle(void)
+{
+#ifdef CONFIG_MSM7X00A_IDLE
+	asm volatile (
+
+	"mrc     p15, 0, r1, c1, c0, 0    /* read current CR    */ \n\t"
+	"bic     r0, r1, #(1 << 2)        /* clear dcache bit   */ \n\t"
+	"bic     r0, r0, #(1 << 12)       /* clear icache bit   */ \n\t"
+	"mcr     p15, 0, r0, c1, c0, 0    /* disable d/i cache  */ \n\t"
+
+	"mov     r0, #0                   /* prepare wfi value  */ \n\t"
+	"mcr     p15, 0, r0, c7, c10, 0   /* flush the cache    */ \n\t"
+	"mcr     p15, 0, r0, c7, c10, 4   /* memory barrier     */ \n\t"
+	"mcr     p15, 0, r0, c7, c0, 4    /* wait for interrupt */ \n\t"
+
+	"mcr     p15, 0, r1, c1, c0, 0    /* restore d/i cache  */ \n\t"
+
+	: : : "r0","r1" );
+#endif
+}
+
+static int __init msm_idle_init(void)
+{
+	arm_pm_idle = msm_idle;
+	return 0;
+}
+
+arch_initcall(msm_idle_init);
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h
index 311db2b..f5fb2ec 100644
--- a/arch/arm/mach-msm/include/mach/system.h
+++ b/arch/arm/mach-msm/include/mach/system.h
@@ -12,7 +12,6 @@
  * GNU General Public License for more details.
  *
  */
-void arch_idle(void);
 
 /* low level hardware reset hook -- for example, hitting the
  * PSHOLD line on the PMIC to hard reset the system
diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h
deleted file mode 100644
index 8c3a538..0000000
--- a/arch/arm/mach-mv78xx0/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/system.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index cf00b3e..c57f996 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -83,6 +83,18 @@ config MODULE_M28
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_OCOTP
 
+config MODULE_APX4
+	bool
+	select SOC_IMX28
+	select LEDS_GPIO_REGISTER
+	select MXS_HAVE_AMBA_DUART
+	select MXS_HAVE_PLATFORM_AUART
+	select MXS_HAVE_PLATFORM_FEC
+	select MXS_HAVE_PLATFORM_MXS_I2C
+	select MXS_HAVE_PLATFORM_MXS_MMC
+	select MXS_HAVE_PLATFORM_MXS_SAIF
+	select MXS_OCOTP
+
 config MACH_TX28
 	bool "Ka-Ro TX28 module"
 	select MODULE_TX28
@@ -91,4 +103,8 @@ config MACH_M28EVK
 	bool "Support DENX M28EVK Platform"
 	select MODULE_M28
 
+config MACH_APX4DEVKIT
+	bool "Support Bluegiga APX4 Development Kit"
+	select MODULE_APX4
+
 endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 8c93b24..908bf9a 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
 obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
 obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
 obj-$(CONFIG_MACH_M28EVK)    += mach-m28evk.o
+obj-$(CONFIG_MACH_APX4DEVKIT) += mach-apx4devkit.o
 obj-$(CONFIG_MODULE_TX28) += module-tx28.o
 obj-$(CONFIG_MACH_TX28)    += mach-tx28.o
 
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index e12e112..293958b 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -223,7 +223,6 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 reg, bm_busy, div_max, d, f, div, frac;
 	unsigned long diff, parent_rate, calc_rate;
-	int i;
 
 	parent_rate = clk_get_rate(clk->parent);
 
@@ -275,14 +274,7 @@ static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
 	reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
 
-	for (i = 10000; i; i--)
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
-					HW_CLKCTRL_CPU) & bm_busy))
-			break;
-	if (!i)	{
-		pr_err("%s: divider writing timeout\n", __func__);
-		return -ETIMEDOUT;
-	}
+	mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
 
 	return 0;
 }
@@ -292,7 +284,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 {									\
 	u32 reg, div_max, div;						\
 	unsigned long parent_rate;					\
-	int i;								\
 									\
 	parent_rate = clk_get_rate(clk->parent);			\
 	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
@@ -310,15 +301,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 	}								\
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
 									\
-	for (i = 10000; i; i--)						\
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
-			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
-			break;						\
-	if (!i)	{							\
-		pr_err("%s: divider writing timeout\n", __func__);	\
-		return -ETIMEDOUT;					\
-	}								\
-									\
+	mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);	\
 	return 0;							\
 }
 
@@ -461,7 +444,7 @@ static struct clk_lookup lookups[] = {
 static int clk_misc_init(void)
 {
 	u32 reg;
-	int i;
+	int ret;
 
 	/* Fix up parent per register setting */
 	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -510,14 +493,7 @@ static int clk_misc_init(void)
 	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
 
-	for (i = 10000; i; i--)
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
-			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
-			break;
-	if (!i) {
-		pr_err("%s: divider writing timeout\n", __func__);
-		return -ETIMEDOUT;
-	}
+	ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
 
 	/* Gate off cpu clock in WFI for power saving */
 	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -532,7 +508,7 @@ static int clk_misc_init(void)
 	reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
 
-	return 0;
+	return ret;
 }
 
 int __init mx23_clocks_init(void)
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 5d68e41..22ad12f 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -322,7 +322,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 {									\
 	u32 reg, bm_busy, div_max, d, f, div, frac;			\
 	unsigned long diff, parent_rate, calc_rate;			\
-	int i;								\
 									\
 	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
 	bm_busy = BM_CLKCTRL_##dr##_BUSY;				\
@@ -396,16 +395,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 	}								\
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
 									\
-	for (i = 10000; i; i--)						\
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
-			HW_CLKCTRL_##dr) & bm_busy))			\
-			break;						\
-	if (!i)	{							\
-		pr_err("%s: divider writing timeout\n", __func__);	\
-		return -ETIMEDOUT;					\
-	}								\
-									\
-	return 0;							\
+	return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy);		\
 }
 
 _CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
@@ -421,7 +411,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 {									\
 	u32 reg, div_max, div;						\
 	unsigned long parent_rate;					\
-	int i;								\
 									\
 	parent_rate = clk_get_rate(clk->parent);			\
 	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
@@ -439,16 +428,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 	}								\
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
 									\
-	for (i = 10000; i; i--)						\
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
-			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
-			break;						\
-	if (!i)	{							\
-		pr_err("%s: divider writing timeout\n", __func__);	\
-		return -ETIMEDOUT;					\
-	}								\
-									\
-	return 0;							\
+	return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
 }
 
 _CLK_SET_RATE1(xbus_clk, XBUS)
@@ -461,7 +441,6 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 	u32 reg;							\
 	u64 lrate;							\
 	unsigned long parent_rate;					\
-	int i;								\
 									\
 	parent_rate = clk_get_rate(clk->parent);			\
 	if (rate > parent_rate)						\
@@ -477,18 +456,13 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)		\
 	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
 	reg &= ~BM_CLKCTRL_##rs##_DIV;					\
 	reg |= div << BP_CLKCTRL_##rs##_DIV;				\
-	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
-									\
-	for (i = 10000; i; i--)						\
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
-			HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY))	\
-			break;						\
-	if (!i) {							\
-		pr_err("%s: divider writing timeout\n", __func__);	\
-		return -ETIMEDOUT;					\
+	if (reg & (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
 	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
 									\
-	return 0;							\
+	return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
 }
 
 _CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
@@ -654,6 +628,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
 	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
 	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
+	_REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
+	_REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
 	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
 	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -676,7 +652,7 @@ static struct clk_lookup lookups[] = {
 static int clk_misc_init(void)
 {
 	u32 reg;
-	int i;
+	int ret;
 
 	/* Fix up parent per register setting */
 	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
@@ -756,14 +732,7 @@ static int clk_misc_init(void)
 	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
 
-	for (i = 10000; i; i--)
-		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
-			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
-			break;
-	if (!i) {
-		pr_err("%s: divider writing timeout\n", __func__);
-		return -ETIMEDOUT;
-	}
+	ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
 
 	/* Gate off cpu clock in WFI for power saving */
 	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
@@ -790,7 +759,7 @@ static int clk_misc_init(void)
 	reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
 
-	return 0;
+	return ret;
 }
 
 int __init mx28_clocks_init(void)
@@ -803,6 +772,8 @@ int __init mx28_clocks_init(void)
 	 */
 	clk_set_parent(&ssp0_clk, &ref_io0_clk);
 	clk_set_parent(&ssp1_clk, &ref_io0_clk);
+	clk_set_parent(&ssp2_clk, &ref_io1_clk);
+	clk_set_parent(&ssp3_clk, &ref_io1_clk);
 
 	clk_prepare_enable(&cpu_clk);
 	clk_prepare_enable(&hbus_clk);
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
index fe3e847..01faffe 100644
--- a/arch/arm/mach-mxs/devices.c
+++ b/arch/arm/mach-mxs/devices.c
@@ -77,16 +77,18 @@ err:
 
 int __init mxs_add_amba_device(const struct amba_device *dev)
 {
-	struct amba_device *adev = kmalloc(sizeof(*adev), GFP_KERNEL);
+	struct amba_device *adev = amba_device_alloc(dev->dev.init_name,
+		dev->res.start, resource_size(&dev->res));
 
 	if (!adev) {
 		pr_err("%s: failed to allocate memory", __func__);
 		return -ENOMEM;
 	}
 
-	*adev = *dev;
+	adev->irq[0] = dev->irq[0];
+	adev->irq[1] = dev->irq[1];
 
-	return amba_device_register(adev, &iomem_resource);
+	return amba_device_add(adev, &iomem_resource);
 }
 
 struct device mxs_apbh_bus = {
diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c
index a559db0..a5479f7 100644
--- a/arch/arm/mach-mxs/devices/amba-duart.c
+++ b/arch/arm/mach-mxs/devices/amba-duart.c
@@ -23,7 +23,7 @@ const struct amba_device name##_device __initconst = {		\
 		.end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1,	\
 		.flags = IORESOURCE_MEM,			\
 	},							\
-	.irq = {soc ## _INT_DUART, NO_IRQ},			\
+	.irq = {soc ## _INT_DUART},				\
 }
 
 #ifdef CONFIG_SOC_IMX23
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
index 382dacb..bef9d92 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -41,6 +41,8 @@ const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
 const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
 	mxs_mxs_mmc_data_entry(MX28, 0, 0),
 	mxs_mxs_mmc_data_entry(MX28, 1, 1),
+	mxs_mxs_mmc_data_entry(MX28, 2, 2),
+	mxs_mxs_mmc_data_entry(MX28, 3, 3),
 };
 #endif
 
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index e1237ab..c50c3ea 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -31,4 +31,6 @@ extern void mx28_init_irq(void);
 
 extern void icoll_init_irq(void);
 
+extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask);
+
 #endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h
index 49a888c..1796406 100644
--- a/arch/arm/mach-mxs/include/mach/digctl.h
+++ b/arch/arm/mach-mxs/include/mach/digctl.h
@@ -18,4 +18,5 @@
 #define HW_DIGCTL_CTRL			0x0
 #define  BP_DIGCTL_CTRL_SAIF_CLKMUX	10
 #define  BM_DIGCTL_CTRL_SAIF_CLKMUX	(0x3 << 10)
+#define HW_DIGCTL_CHIPID		0x310
 #endif
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
index bde5f66..7d4fb6d 100644
--- a/arch/arm/mach-mxs/include/mach/mxs.h
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -23,22 +23,10 @@
 #include <linux/io.h>
 #endif
 #include <asm/mach-types.h>
+#include <mach/digctl.h>
 #include <mach/hardware.h>
 
 /*
- * MXS CPU types
- */
-#define cpu_is_mx23()		(					\
-		machine_is_mx23evk() ||					\
-		machine_is_stmp378x() ||				\
-		0)
-#define cpu_is_mx28()		(					\
-		machine_is_mx28evk() ||					\
-		machine_is_m28evk() ||					\
-		machine_is_tx28() ||					\
-		0)
-
-/*
  * IO addresses common to MXS-based
  */
 #define MXS_IO_BASE_ADDR		0x80000000
@@ -109,6 +97,21 @@ static inline void __mxs_togl(u32 mask, void __iomem *reg)
 {
 	__raw_writel(mask, reg + MXS_TOG_ADDR);
 }
+
+/*
+ * MXS CPU types
+ */
+#define MXS_CHIPID (MXS_IO_ADDRESS(MXS_DIGCTL_BASE_ADDR) + HW_DIGCTL_CHIPID)
+
+static inline int cpu_is_mx23(void)
+{
+	return ((__raw_readl(MXS_CHIPID) >> 16) == 0x3780);
+}
+
+static inline int cpu_is_mx28(void)
+{
+	return ((__raw_readl(MXS_CHIPID) >> 16) == 0x2800);
+}
 #endif
 
 #endif /* __MACH_MXS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
deleted file mode 100644
index e7ad1bb..0000000
--- a/arch/arm/mach-mxs/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; 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.
- */
-
-#ifndef __MACH_MXS_SYSTEM_H__
-#define __MACH_MXS_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
index 6777674..ef28114 100644
--- a/arch/arm/mach-mxs/include/mach/uncompress.h
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -18,8 +18,6 @@
 #ifndef __MACH_MXS_UNCOMPRESS_H__
 #define __MACH_MXS_UNCOMPRESS_H__
 
-#include <asm/mach-types.h>
-
 unsigned long mxs_duart_base;
 
 #define MXS_DUART(x)	(*(volatile unsigned long *)(mxs_duart_base + (x)))
@@ -55,16 +53,17 @@ static inline void flush(void)
 
 #define MX23_DUART_BASE_ADDR	0x80070000
 #define MX28_DUART_BASE_ADDR	0x80074000
+#define MXS_DIGCTL_CHIPID	0x8001c310
 
 static inline void __arch_decomp_setup(unsigned long arch_id)
 {
-	switch (arch_id) {
-	case MACH_TYPE_MX23EVK:
+	u16 chipid = (*(volatile unsigned long *) MXS_DIGCTL_CHIPID) >> 16;
+
+	switch (chipid) {
+	case 0x3780:
 		mxs_duart_base = MX23_DUART_BASE_ADDR;
 		break;
-	case MACH_TYPE_MX28EVK:
-	case MACH_TYPE_M28EVK:
-	case MACH_TYPE_TX28:
+	case 0x2800:
 		mxs_duart_base = MX28_DUART_BASE_ADDR;
 		break;
 	default:
diff --git a/arch/arm/mach-mxs/mach-apx4devkit.c b/arch/arm/mach-mxs/mach-apx4devkit.c
new file mode 100644
index 0000000..48a7fab
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-apx4devkit.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2011-2012
+ * Lauri Hintsala, Bluegiga, <lauri.hintsala@bluegiga.com>
+ * Veli-Pekka Peltola, Bluegiga, <veli-pekka.peltola@bluegiga.com>
+ *
+ * based on: mach-mx28evk.c
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/micrel_phy.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/digctl.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+
+#define APX4DEVKIT_GPIO_USERLED	MXS_GPIO_NR(3, 28)
+
+static const iomux_cfg_t apx4devkit_pads[] __initconst = {
+	/* duart */
+	MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
+	MX28_PAD_PWM1__DUART_TX | MXS_PAD_CTRL,
+
+	/* auart0 */
+	MX28_PAD_AUART0_RX__AUART0_RX | MXS_PAD_CTRL,
+	MX28_PAD_AUART0_TX__AUART0_TX | MXS_PAD_CTRL,
+	MX28_PAD_AUART0_CTS__AUART0_CTS | MXS_PAD_CTRL,
+	MX28_PAD_AUART0_RTS__AUART0_RTS | MXS_PAD_CTRL,
+
+	/* auart1 */
+	MX28_PAD_AUART1_RX__AUART1_RX | MXS_PAD_CTRL,
+	MX28_PAD_AUART1_TX__AUART1_TX | MXS_PAD_CTRL,
+
+	/* auart2 */
+	MX28_PAD_SSP2_SCK__AUART2_RX | MXS_PAD_CTRL,
+	MX28_PAD_SSP2_MOSI__AUART2_TX | MXS_PAD_CTRL,
+
+	/* auart3 */
+	MX28_PAD_SSP2_MISO__AUART3_RX | MXS_PAD_CTRL,
+	MX28_PAD_SSP2_SS0__AUART3_TX | MXS_PAD_CTRL,
+
+#define MXS_PAD_FEC	(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP)
+	/* fec0 */
+	MX28_PAD_ENET0_MDC__ENET0_MDC | MXS_PAD_FEC,
+	MX28_PAD_ENET0_MDIO__ENET0_MDIO | MXS_PAD_FEC,
+	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MXS_PAD_FEC,
+	MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MXS_PAD_FEC,
+	MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MXS_PAD_FEC,
+	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MXS_PAD_FEC,
+	MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MXS_PAD_FEC,
+	MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MXS_PAD_FEC,
+	MX28_PAD_ENET_CLK__CLKCTRL_ENET | MXS_PAD_FEC,
+
+	/* i2c */
+	MX28_PAD_I2C0_SCL__I2C0_SCL,
+	MX28_PAD_I2C0_SDA__I2C0_SDA,
+
+	/* mmc0 */
+	MX28_PAD_SSP0_DATA0__SSP0_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA1__SSP0_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA2__SSP0_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA3__SSP0_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA4__SSP0_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA5__SSP0_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA6__SSP0_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA7__SSP0_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_CMD__SSP0_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_SSP0_SCK__SSP0_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+	/* led */
+	MX28_PAD_PWM3__GPIO_3_28 | MXS_PAD_CTRL,
+
+	/* saif0 & saif1 */
+	MX28_PAD_SAIF0_MCLK__SAIF0_MCLK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+};
+
+/* led */
+static const struct gpio_led apx4devkit_leds[] __initconst = {
+	{
+		.name = "user-led",
+		.default_trigger = "heartbeat",
+		.gpio = APX4DEVKIT_GPIO_USERLED,
+	},
+};
+
+static const struct gpio_led_platform_data apx4devkit_led_data __initconst = {
+	.leds = apx4devkit_leds,
+	.num_leds = ARRAY_SIZE(apx4devkit_leds),
+};
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+	.phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static const struct mxs_mmc_platform_data apx4devkit_mmc_pdata __initconst = {
+	.wp_gpio = -EINVAL,
+	.flags = SLOTF_4_BIT_CAPABLE,
+};
+
+static const struct i2c_board_info apx4devkit_i2c_boardinfo[] __initconst = {
+	{ I2C_BOARD_INFO("sgtl5000", 0x0a) }, /* ASoC */
+	{ I2C_BOARD_INFO("pcf8563", 0x51) }, /* RTC */
+};
+
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || \
+		defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply apx4devkit_audio_consumer_supplies[] = {
+	REGULATOR_SUPPLY("VDDA", "0-000a"),
+	REGULATOR_SUPPLY("VDDIO", "0-000a"),
+};
+
+static struct regulator_init_data apx4devkit_vdd_reg_init_data = {
+	.constraints	= {
+		.name	= "3V3",
+		.always_on = 1,
+	},
+	.consumer_supplies = apx4devkit_audio_consumer_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(apx4devkit_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config apx4devkit_vdd_pdata = {
+	.supply_name	= "board-3V3",
+	.microvolts	= 3300000,
+	.gpio		= -EINVAL,
+	.enabled_at_boot = 1,
+	.init_data	= &apx4devkit_vdd_reg_init_data,
+};
+
+static struct platform_device apx4devkit_voltage_regulator = {
+	.name		= "reg-fixed-voltage",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &apx4devkit_vdd_pdata,
+	},
+};
+
+static void __init apx4devkit_add_regulators(void)
+{
+	platform_device_register(&apx4devkit_voltage_regulator);
+}
+#else
+static void __init apx4devkit_add_regulators(void) {}
+#endif
+
+static const struct mxs_saif_platform_data
+			apx4devkit_mxs_saif_pdata[] __initconst = {
+	/* working on EXTMSTR0 mode (saif0 master, saif1 slave) */
+	{
+		.master_mode = 1,
+		.master_id = 0,
+	}, {
+		.master_mode = 0,
+		.master_id = 0,
+	},
+};
+
+static int apx4devkit_phy_fixup(struct phy_device *phy)
+{
+	phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
+	return 0;
+}
+
+static void __init apx4devkit_init(void)
+{
+	mxs_iomux_setup_multiple_pads(apx4devkit_pads,
+			ARRAY_SIZE(apx4devkit_pads));
+
+	mx28_add_duart();
+	mx28_add_auart0();
+	mx28_add_auart1();
+	mx28_add_auart2();
+	mx28_add_auart3();
+
+	/*
+	 * Register fixup for the Micrel KS8031 PHY clock
+	 * (shares same ID with KS8051)
+	 */
+	phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK,
+			apx4devkit_phy_fixup);
+
+	mx28_add_fec(0, &mx28_fec_pdata);
+
+	mx28_add_mxs_mmc(0, &apx4devkit_mmc_pdata);
+
+	gpio_led_register_device(0, &apx4devkit_led_data);
+
+	mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
+	mx28_add_saif(0, &apx4devkit_mxs_saif_pdata[0]);
+	mx28_add_saif(1, &apx4devkit_mxs_saif_pdata[1]);
+
+	apx4devkit_add_regulators();
+
+	mx28_add_mxs_i2c(0);
+	i2c_register_board_info(0, apx4devkit_i2c_boardinfo,
+			ARRAY_SIZE(apx4devkit_i2c_boardinfo));
+
+	mxs_add_platform_device("mxs-sgtl5000", 0, NULL, 0, NULL, 0);
+}
+
+static void __init apx4devkit_timer_init(void)
+{
+	mx28_clocks_init();
+}
+
+static struct sys_timer apx4devkit_timer = {
+	.init	= apx4devkit_timer_init,
+};
+
+MACHINE_START(APX4DEVKIT, "Bluegiga APX4 Development Kit")
+	.map_io		= mx28_map_io,
+	.init_irq	= mx28_init_irq,
+	.timer		= &apx4devkit_timer,
+	.init_machine	= apx4devkit_init,
+	.restart	= mxs_restart,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mach-m28evk.c b/arch/arm/mach-mxs/mach-m28evk.c
index 2f27582..06d7996 100644
--- a/arch/arm/mach-mxs/mach-m28evk.c
+++ b/arch/arm/mach-mxs/mach-m28evk.c
@@ -247,18 +247,15 @@ static int __init m28evk_fec_get_mac(void)
 	u32 val;
 	const u32 *ocotp = mxs_get_ocotp();
 
-	if (!ocotp) {
-		pr_err("%s: timeout when reading fec mac from OCOTP\n",
-			__func__);
+	if (!ocotp)
 		return -ETIMEDOUT;
-	}
 
 	/*
 	 * OCOTP only stores the last 4 octets for each mac address,
 	 * so hard-code DENX OUI (C0:E5:4E) here.
 	 */
 	for (i = 0; i < 2; i++) {
-		val = ocotp[i * 4];
+		val = ocotp[i];
 		mx28_fec_pdata[i].mac[0] = 0xC0;
 		mx28_fec_pdata[i].mac[1] = 0xE5;
 		mx28_fec_pdata[i].mac[2] = 0x4E;
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index fdb0a56..e386c14 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -223,7 +223,6 @@ static const struct gpio_led_platform_data mx28evk_led_data __initconst = {
 /* fec */
 static void __init mx28evk_fec_reset(void)
 {
-	int ret;
 	struct clk *clk;
 
 	/* Enable fec phy clock */
@@ -231,32 +230,7 @@ static void __init mx28evk_fec_reset(void)
 	if (!IS_ERR(clk))
 		clk_prepare_enable(clk);
 
-	/* Power up fec phy */
-	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
-	if (ret) {
-		pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
-		return;
-	}
-
-	ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
-	if (ret) {
-		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
-		return;
-	}
-
-	/* Reset fec phy */
-	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
-	if (ret) {
-		pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
-		return;
-	}
-
-	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
-	if (ret) {
-		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
-		return;
-	}
-
+	gpio_set_value(MX28EVK_FEC_PHY_RESET, 0);
 	mdelay(1);
 	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
 }
@@ -278,14 +252,14 @@ static int __init mx28evk_fec_get_mac(void)
 	const u32 *ocotp = mxs_get_ocotp();
 
 	if (!ocotp)
-		goto error;
+		return -ETIMEDOUT;
 
 	/*
 	 * OCOTP only stores the last 4 octets for each mac address,
 	 * so hard-code Freescale OUI (00:04:9f) here.
 	 */
 	for (i = 0; i < 2; i++) {
-		val = ocotp[i * 4];
+		val = ocotp[i];
 		mx28_fec_pdata[i].mac[0] = 0x00;
 		mx28_fec_pdata[i].mac[1] = 0x04;
 		mx28_fec_pdata[i].mac[2] = 0x9f;
@@ -295,10 +269,6 @@ static int __init mx28evk_fec_get_mac(void)
 	}
 
 	return 0;
-
-error:
-	pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
-	return -ETIMEDOUT;
 }
 
 /*
@@ -417,9 +387,14 @@ static void __init mx28evk_add_regulators(void)
 static void __init mx28evk_add_regulators(void) {}
 #endif
 
-static struct gpio mx28evk_lcd_gpios[] = {
+static const struct gpio mx28evk_gpios[] __initconst = {
 	{ MX28EVK_LCD_ENABLE, GPIOF_OUT_INIT_HIGH, "lcd-enable" },
 	{ MX28EVK_BL_ENABLE, GPIOF_OUT_INIT_HIGH, "bl-enable" },
+	{ MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT, "flexcan-switch" },
+	{ MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc0-slot-power" },
+	{ MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc1-slot-power" },
+	{ MX28EVK_FEC_PHY_POWER, GPIOF_OUT_INIT_LOW, "fec-phy-power" },
+	{ MX28EVK_FEC_PHY_RESET, GPIOF_DIR_OUT, "fec-phy-reset" },
 };
 
 static const struct mxs_saif_platform_data
@@ -447,25 +422,18 @@ static void __init mx28evk_init(void)
 	if (mx28evk_fec_get_mac())
 		pr_warn("%s: failed on fec mac setup\n", __func__);
 
+	ret = gpio_request_array(mx28evk_gpios, ARRAY_SIZE(mx28evk_gpios));
+	if (ret)
+		pr_err("One or more GPIOs failed to be requested: %d\n", ret);
+
 	mx28evk_fec_reset();
 	mx28_add_fec(0, &mx28_fec_pdata[0]);
 	mx28_add_fec(1, &mx28_fec_pdata[1]);
 
-	ret = gpio_request_one(MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT,
-				"flexcan-switch");
-	if (ret) {
-		pr_err("failed to request gpio flexcan-switch: %d\n", ret);
-	} else {
-		mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]);
-		mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]);
-	}
+	mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]);
+	mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]);
 
-	ret = gpio_request_array(mx28evk_lcd_gpios,
-				 ARRAY_SIZE(mx28evk_lcd_gpios));
-	if (ret)
-		pr_warn("failed to request gpio pins for lcd: %d\n", ret);
-	else
-		mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
+	mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
 
 	mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
 	mx28_add_saif(0, &mx28evk_mxs_saif_pdata[0]);
@@ -480,20 +448,8 @@ static void __init mx28evk_init(void)
 	mxs_add_platform_device("mxs-sgtl5000", 0, NULL, 0,
 			NULL, 0);
 
-	/* power on mmc slot by writing 0 to the gpio */
-	ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW,
-			       "mmc0-slot-power");
-	if (ret)
-		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
-	else
-		mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
-
-	ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW,
-			       "mmc1-slot-power");
-	if (ret)
-		pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
-	else
-		mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
+	mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+	mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
 
 	mx28_add_rtc_stmp3xxx();
 
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
index fb042da..a9b4bbc 100644
--- a/arch/arm/mach-mxs/pm.c
+++ b/arch/arm/mach-mxs/pm.c
@@ -15,13 +15,12 @@
 #include <linux/kernel.h>
 #include <linux/suspend.h>
 #include <linux/io.h>
-#include <mach/system.h>
 
 static int mxs_suspend_enter(suspend_state_t state)
 {
 	switch (state) {
 	case PM_SUSPEND_MEM:
-		arch_idle();
+		cpu_do_idle();
 		break;
 
 	default:
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 54f91ad..7aa5ac5 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -37,6 +37,8 @@
 #define MXS_MODULE_CLKGATE		(1 << 30)
 #define MXS_MODULE_SFTRST		(1 << 31)
 
+#define CLKCTRL_TIMEOUT		10	/* 10 ms */
+
 static void __iomem *mxs_clkctrl_reset_addr;
 
 /*
@@ -137,3 +139,17 @@ error:
 	return -ETIMEDOUT;
 }
 EXPORT_SYMBOL(mxs_reset_block);
+
+int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
+	while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
+						+ reg_offset) & mask) {
+		if (time_after(jiffies, timeout)) {
+			pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
index b991323..2cdf6ef 100644
--- a/arch/arm/mach-netx/fb.c
+++ b/arch/arm/mach-netx/fb.c
@@ -92,18 +92,7 @@ void clk_put(struct clk *clk)
 {
 }
 
-static struct amba_device fb_device = {
-	.dev		= {
-		.init_name = "fb",
-		.coherent_dma_mask = ~0,
-	},
-	.res		= {
-		.start	= 0x00104000,
-		.end	= 0x00104fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	.irq		= { NETX_IRQ_LCD, NO_IRQ },
-};
+static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL);
 
 int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel)
 {
diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h
deleted file mode 100644
index b38fa36..0000000
--- a/arch/arm/mach-netx/include/mach/system.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-netx/include/mach/system.h
- *
- * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
-
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index 7c878bf..58cacaf 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -27,11 +27,11 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
+#include <asm/mach/time.h>
 
 #include <plat/gpio-nomadik.h>
 #include <plat/mtu.h>
 
-#include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 
@@ -185,20 +185,11 @@ static void __init nhk8815_onenand_init(void)
 #endif
 }
 
-#define __MEM_4K_RESOURCE(x) \
-	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+static AMBA_APB_DEVICE(uart0, "uart0", 0, NOMADIK_UART0_BASE,
+	{ IRQ_UART0 }, NULL);
 
-static struct amba_device uart0_device = {
-	.dev = { .init_name = "uart0" },
-	__MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
-	.irq = {IRQ_UART0, NO_IRQ},
-};
-
-static struct amba_device uart1_device = {
-	.dev = { .init_name = "uart1" },
-	__MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
-	.irq = {IRQ_UART1, NO_IRQ},
-};
+static AMBA_APB_DEVICE(uart1, "uart1", 0, NOMADIK_UART1_BASE,
+	{ IRQ_UART1 }, NULL);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&uart0_device,
@@ -255,10 +246,7 @@ static void __init nomadik_timer_init(void)
 	src_cr |= SRC_CR_INIT_VAL;
 	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
 
-	/* Save global pointer to mtu, used by platform timer code */
-	mtu_base = io_p2v(NOMADIK_MTU0_BASE);
-
-	nmdk_timer_init();
+	nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE));
 }
 
 static struct sys_timer nomadik_timer = {
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 65df7b4..27f43a4 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -97,12 +97,7 @@ static struct platform_device cpu8815_platform_gpio[] = {
 	GPIO_DEVICE(3),
 };
 
-static struct amba_device cpu8815_amba_rng = {
-	.dev = {
-		.init_name = "rng",
-	},
-	__MEM_4K_RESOURCE(NOMADIK_RNG_BASE),
-};
+static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL);
 
 static struct platform_device *platform_devs[] __initdata = {
 	cpu8815_platform_gpio + 0,
@@ -112,7 +107,7 @@ static struct platform_device *platform_devs[] __initdata = {
 };
 
 static struct amba_device *amba_devs[] __initdata = {
-	&cpu8815_amba_rng
+	&cpu8815_amba_rng_device
 };
 
 static int __init cpu8815_init(void)
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h
deleted file mode 100644
index bcaeaf4..0000000
--- a/arch/arm/mach-nomadik/include/mach/setup.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/*
- * These symbols are needed for board-specific files to call their
- * own cpu-specific files
- */
-
-#ifndef __ASM_ARCH_SETUP_H
-#define __ASM_ARCH_SETUP_H
-
-#include <asm/mach/time.h>
-#include <linux/init.h>
-
-#ifdef CONFIG_NOMADIK_8815
-
-extern void nmdk_timer_init(void);
-
-#endif /* NOMADIK_8815 */
-
-#endif /*  __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h
deleted file mode 100644
index 25e198b..0000000
--- a/arch/arm/mach-nomadik/include/mach/system.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  mach-nomadik/include/mach/system.h
- *
- *  Copyright (C) 2008 STMicroelectronics
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-omap1/include/mach/system.h b/arch/arm/mach-omap1/include/mach/system.h
deleted file mode 100644
index a6c1b3a..0000000
--- a/arch/arm/mach-omap1/include/mach/system.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-omap1/include/mach/system.h
- */
-
-#include <plat/system.h>
diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c
index 4538093..4c5ce7d 100644
--- a/arch/arm/mach-omap1/lcd_dma.c
+++ b/arch/arm/mach-omap1/lcd_dma.c
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
 void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
 {
 	if (cpu_is_omap15xx()) {
-		printk(KERN_ERR "DMA virtual resulotion is not supported "
+		printk(KERN_ERR "DMA virtual resolution is not supported "
 				"in 1510 mode\n");
 		BUG();
 	}
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 89ea20c..0c2c366 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -42,9 +42,9 @@
 #include <linux/sysfs.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/atomic.h>
 
 #include <asm/irq.h>
-#include <linux/atomic.h>
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 
@@ -108,13 +108,7 @@ void omap1_pm_idle(void)
 	__u32 use_idlect1 = arm_idlect1_mask;
 	int do_sleep = 0;
 
-	local_irq_disable();
 	local_fiq_disable();
-	if (need_resched()) {
-		local_fiq_enable();
-		local_irq_enable();
-		return;
-	}
 
 #if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
 #warning Enable 32kHz OS timer in order to allow sleep states in idle
@@ -157,14 +151,12 @@ void omap1_pm_idle(void)
 		omap_writel(saved_idlect1, ARM_IDLECT1);
 
 		local_fiq_enable();
-		local_irq_enable();
 		return;
 	}
 	omap_sram_suspend(omap_readl(ARM_IDLECT1),
 			  omap_readl(ARM_IDLECT2));
 
 	local_fiq_enable();
-	local_irq_enable();
 }
 
 /*
@@ -583,8 +575,6 @@ static void omap_pm_init_proc(void)
 
 #endif /* DEBUG && CONFIG_PROC_FS */
 
-static void (*saved_idle)(void) = NULL;
-
 /*
  *	omap_pm_prepare - Do preliminary suspend work.
  *
@@ -592,8 +582,7 @@ static void (*saved_idle)(void) = NULL;
 static int omap_pm_prepare(void)
 {
 	/* We cannot sleep in idle until we have resumed */
-	saved_idle = pm_idle;
-	pm_idle = NULL;
+	disable_hlt();
 
 	return 0;
 }
@@ -630,7 +619,7 @@ static int omap_pm_enter(suspend_state_t state)
 
 static void omap_pm_finish(void)
 {
-	pm_idle = saved_idle;
+	enable_hlt();
 }
 
 
@@ -687,7 +676,7 @@ static int __init omap_pm_init(void)
 		return -ENODEV;
 	}
 
-	pm_idle = omap1_pm_idle;
+	arm_pm_idle = omap1_pm_idle;
 
 	if (cpu_is_omap7xx())
 		setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq);
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 4e90715..f5a03fa 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include <linux/usb/otg.h>
 #include <linux/spi/spi.h>
 #include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
 #include <linux/gpio_keys.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
@@ -41,6 +42,7 @@
 #include <video/omap-panel-nokia-dsi.h>
 #include <video/omap-panel-picodlp.h>
 #include <linux/wl12xx.h>
+#include <linux/platform_data/omap-abe-twl6040.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -378,12 +380,40 @@ static struct platform_device sdp4430_dmic_codec = {
 	.id	= -1,
 };
 
+static struct omap_abe_twl6040_data sdp4430_abe_audio_data = {
+	.card_name = "SDP4430",
+	.has_hs		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	.has_hf		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	.has_ep		= 1,
+	.has_aux	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	.has_vibra	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+
+	.has_dmic	= 1,
+	.has_hsmic	= 1,
+	.has_mainmic	= 1,
+	.has_submic	= 1,
+	.has_afm	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+
+	.jack_detection = 1,
+	/* MCLK input is 38.4MHz */
+	.mclk_freq	= 38400000,
+};
+
+static struct platform_device sdp4430_abe_audio = {
+	.name		= "omap-abe-twl6040",
+	.id		= -1,
+	.dev = {
+		.platform_data = &sdp4430_abe_audio_data,
+	},
+};
+
 static struct platform_device *sdp4430_devices[] __initdata = {
 	&sdp4430_gpio_keys_device,
 	&sdp4430_leds_gpio,
 	&sdp4430_leds_pwm,
 	&sdp4430_vbat,
 	&sdp4430_dmic_codec,
+	&sdp4430_abe_audio,
 };
 
 static struct omap_musb_board_data musb_board_data = {
@@ -526,7 +556,7 @@ static struct regulator_init_data sdp4430_vusim = {
 	},
 };
 
-static struct twl4030_codec_data twl6040_codec = {
+static struct twl6040_codec_data twl6040_codec = {
 	/* single-step ramp for headset and handsfree */
 	.hs_left_step	= 0x0f,
 	.hs_right_step	= 0x0f,
@@ -534,7 +564,7 @@ static struct twl4030_codec_data twl6040_codec = {
 	.hf_right_step	= 0x1d,
 };
 
-static struct twl4030_vibra_data twl6040_vibra = {
+static struct twl6040_vibra_data twl6040_vibra = {
 	.vibldrv_res = 8,
 	.vibrdrv_res = 3,
 	.viblmotor_res = 10,
@@ -543,16 +573,14 @@ static struct twl4030_vibra_data twl6040_vibra = {
 	.vddvibr_uV = 0,	/* fixed volt supply - VBAT */
 };
 
-static struct twl4030_audio_data twl6040_audio = {
+static struct twl6040_platform_data twl6040_data = {
 	.codec		= &twl6040_codec,
 	.vibra		= &twl6040_vibra,
 	.audpwron_gpio	= 127,
-	.naudint_irq	= OMAP44XX_IRQ_SYS_2N,
 	.irq_base	= TWL6040_CODEC_IRQ_BASE,
 };
 
 static struct twl4030_platform_data sdp4430_twldata = {
-	.audio		= &twl6040_audio,
 	/* Regulators */
 	.vusim		= &sdp4430_vusim,
 	.vaux1		= &sdp4430_vaux1,
@@ -583,7 +611,8 @@ static int __init omap4_i2c_init(void)
 			TWL_COMMON_REGULATOR_VCXIO |
 			TWL_COMMON_REGULATOR_VUSB |
 			TWL_COMMON_REGULATOR_CLK32KG);
-	omap4_pmic_init("twl6030", &sdp4430_twldata);
+	omap4_pmic_init("twl6030", &sdp4430_twldata,
+			&twl6040_data, OMAP44XX_IRQ_SYS_2N);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
 				ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index ad49762..bbd01b3 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -36,7 +36,7 @@ static struct twl4030_platform_data sdp4430_twldata = {
 
 static void __init omap4_i2c_init(void)
 {
-	omap4_pmic_init("twl6030", &sdp4430_twldata);
+	omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0);
 }
 #endif
 
@@ -68,7 +68,7 @@ static void __init omap_generic_init(void)
 {
 	struct device_node *node = of_find_matching_node(NULL, intc_match);
 	if (node)
-		irq_domain_add_simple(node, 0);
+		irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL);
 
 	omap_sdrc_init(NULL, NULL);
 
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 28fc271..28077ee 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -25,9 +25,11 @@
 #include <linux/gpio.h>
 #include <linux/usb/otg.h>
 #include <linux/i2c/twl.h>
+#include <linux/mfd/twl6040.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 #include <linux/wl12xx.h>
+#include <linux/platform_data/omap-abe-twl6040.h>
 
 #include <mach/hardware.h>
 #include <asm/hardware/gic.h>
@@ -91,9 +93,34 @@ static struct platform_device leds_gpio = {
 	},
 };
 
+static struct omap_abe_twl6040_data panda_abe_audio_data = {
+	/* Audio out */
+	.has_hs		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	/* HandsFree through expasion connector */
+	.has_hf		= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	/* PandaBoard: FM TX, PandaBoardES: can be connected to audio out */
+	.has_aux	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	/* PandaBoard: FM RX, PandaBoardES: audio in */
+	.has_afm	= ABE_TWL6040_LEFT | ABE_TWL6040_RIGHT,
+	/* No jack detection. */
+	.jack_detection	= 0,
+	/* MCLK input is 38.4MHz */
+	.mclk_freq	= 38400000,
+
+};
+
+static struct platform_device panda_abe_audio = {
+	.name		= "omap-abe-twl6040",
+	.id		= -1,
+	.dev = {
+		.platform_data = &panda_abe_audio_data,
+	},
+};
+
 static struct platform_device *panda_devices[] __initdata = {
 	&leds_gpio,
 	&wl1271_device,
+	&panda_abe_audio,
 };
 
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
@@ -252,8 +279,25 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
 	return 0;
 }
 
+static struct twl4030_codec_data twl6040_codec = {
+	/* single-step ramp for headset and handsfree */
+	.hs_left_step	= 0x0f,
+	.hs_right_step	= 0x0f,
+	.hf_left_step	= 0x1d,
+	.hf_right_step	= 0x1d,
+};
+
+static struct twl4030_audio_data twl6040_audio = {
+	.codec		= &twl6040_codec,
+	.audpwron_gpio	= 127,
+	.naudint_irq	= OMAP44XX_IRQ_SYS_2N,
+	.irq_base	= TWL6040_CODEC_IRQ_BASE,
+};
+
 /* Panda board uses the common PMIC configuration */
-static struct twl4030_platform_data omap4_panda_twldata;
+static struct twl4030_platform_data omap4_panda_twldata = {
+	.audio		= &twl6040_audio,
+};
 
 /*
  * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
@@ -277,7 +321,8 @@ static int __init omap4_panda_i2c_init(void)
 			TWL_COMMON_REGULATOR_VCXIO |
 			TWL_COMMON_REGULATOR_VUSB |
 			TWL_COMMON_REGULATOR_CLK32KG);
-	omap4_pmic_init("twl6030", &omap4_panda_twldata);
+	omap4_pmic_init("twl6030", &omap4_panda_twldata,
+			&twl6040_data, OMAP44XX_IRQ_SYS_2N);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	/*
 	 * Bus 3 is attached to the DVI port where devices like the pico DLP
@@ -485,6 +530,20 @@ void omap4_panda_display_init(void)
 	omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
 }
 
+static void omap4_panda_init_rev(void)
+{
+	if (cpu_is_omap4430()) {
+		/* PandaBoard 4430 */
+		/* ASoC audio configuration */
+		panda_abe_audio_data.card_name = "PandaBoard";
+		panda_abe_audio_data.has_hsmic = 1;
+	} else {
+		/* PandaBoard ES */
+		/* ASoC audio configuration */
+		panda_abe_audio_data.card_name = "PandaBoardES";
+	}
+}
+
 static void __init omap4_panda_init(void)
 {
 	int package = OMAP_PACKAGE_CBS;
@@ -498,6 +557,7 @@ static void __init omap4_panda_init(void)
 	if (ret)
 		pr_err("error setting wl12xx data: %d\n", ret);
 
+	omap4_panda_init_rev();
 	omap4_panda_i2c_init();
 	platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
 	platform_device_register(&omap_vwlan_device);
diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c
index 9c442e2..ce91aad 100644
--- a/arch/arm/mach-omap2/emu.c
+++ b/arch/arm/mach-omap2/emu.c
@@ -30,29 +30,8 @@ MODULE_AUTHOR("Alexander Shishkin");
 #define ETB_BASE	(L4_EMU_34XX_PHYS + 0x1b000)
 #define DAPCTL		(L4_EMU_34XX_PHYS + 0x1d000)
 
-static struct amba_device omap3_etb_device = {
-	.dev		= {
-		.init_name = "etb",
-	},
-	.res		= {
-		.start	= ETB_BASE,
-		.end	= ETB_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.periphid	= 0x000bb907,
-};
-
-static struct amba_device omap3_etm_device = {
-	.dev		= {
-		.init_name = "etm",
-	},
-	.res		= {
-		.start	= ETM_BASE,
-		.end	= ETM_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	.periphid	= 0x102bb921,
-};
+static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL);
+static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL);
 
 static int __init emu_init(void)
 {
@@ -66,4 +45,3 @@ static int __init emu_init(void)
 }
 
 subsys_initcall(emu_init);
-
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b40c288..deba2c2 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -316,6 +316,7 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 	mmc->slots[0].pm_caps = c->pm_caps;
 	mmc->slots[0].internal_clock = !c->ext_clock;
 	mmc->dma_mask = 0xffffffff;
+	mmc->max_freq = c->max_freq;
 	if (cpu_is_omap44xx())
 		mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
 	else
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
index c440973..0017ae2 100644
--- a/arch/arm/mach-omap2/hsmmc.h
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -26,6 +26,8 @@ struct omap2_hsmmc_info {
 	char	*name;		/* or NULL for default */
 	struct device *dev;	/* returned: pointer to mmc adapter */
 	int	ocr_mask;	/* temporary HACK */
+	int	max_freq;	/* maximum clock, if constrained by external
+				 * circuitry, or 0 for default */
 	/* Remux (pad configuration) when powering on/off */
 	void (*remux)(struct device *dev, int slot, int power_on);
 	/* init some special card */
diff --git a/arch/arm/mach-omap2/include/mach/system.h b/arch/arm/mach-omap2/include/mach/system.h
deleted file mode 100644
index d488721..0000000
--- a/arch/arm/mach-omap2/include/mach/system.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-omap2/include/mach/system.h
- */
-
-#include <plat/system.h>
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 23de98d..a4eb5c2 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -226,7 +226,6 @@ static int omap2_can_sleep(void)
 
 static void omap2_pm_idle(void)
 {
-	local_irq_disable();
 	local_fiq_disable();
 
 	if (!omap2_can_sleep()) {
@@ -243,7 +242,6 @@ static void omap2_pm_idle(void)
 
 out:
 	local_fiq_enable();
-	local_irq_enable();
 }
 
 #ifdef CONFIG_SUSPEND
@@ -462,7 +460,7 @@ static int __init omap2_pm_init(void)
 	}
 
 	suspend_set_ops(&omap_pm_ops);
-	pm_idle = omap2_pm_idle;
+	arm_pm_idle = omap2_pm_idle;
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fc69875..b77df73 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -418,10 +418,9 @@ void omap_sram_idle(void)
 
 static void omap3_pm_idle(void)
 {
-	local_irq_disable();
 	local_fiq_disable();
 
-	if (omap_irq_pending() || need_resched())
+	if (omap_irq_pending())
 		goto out;
 
 	trace_power_start(POWER_CSTATE, 1, smp_processor_id());
@@ -434,7 +433,6 @@ static void omap3_pm_idle(void)
 
 out:
 	local_fiq_enable();
-	local_irq_enable();
 }
 
 #ifdef CONFIG_SUSPEND
@@ -848,7 +846,7 @@ static int __init omap3_pm_init(void)
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
 
-	pm_idle = omap3_pm_idle;
+	arm_pm_idle = omap3_pm_idle;
 	omap3_idle_init();
 
 	/*
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index c264ef7..c840689 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -173,18 +173,16 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
  * omap_default_idle - OMAP4 default ilde routine.'
  *
  * Implements OMAP4 memory, IO ordering requirements which can't be addressed
- * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
+ * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
  * by secondary CPU with CONFIG_CPUIDLE.
  */
 static void omap_default_idle(void)
 {
-	local_irq_disable();
 	local_fiq_disable();
 
 	omap_do_wfi();
 
 	local_fiq_enable();
-	local_irq_enable();
 }
 
 /**
@@ -255,8 +253,8 @@ static int __init omap4_pm_init(void)
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
 
-	/* Overwrite the default arch_idle() */
-	pm_idle = omap_default_idle;
+	/* Overwrite the default cpu_do_idle() */
+	arm_pm_idle = omap_default_idle;
 
 	omap4_idle_init();
 
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 860118a..873b51d 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -24,7 +24,6 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 
-#include <mach/system.h>
 #include <plat/common.h>
 #include <plat/prcm.h>
 #include <plat/irqs.h>
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 10b20c6..bc03154 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -37,6 +37,16 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = {
 	.flags		= I2C_CLIENT_WAKE,
 };
 
+static struct i2c_board_info __initdata omap4_i2c1_board_info[] = {
+	{
+		.addr		= 0x48,
+		.flags		= I2C_CLIENT_WAKE,
+	},
+	{
+		I2C_BOARD_INFO("twl6040", 0x4b),
+	},
+};
+
 void __init omap_pmic_init(int bus, u32 clkrate,
 			   const char *pmic_type, int pmic_irq,
 			   struct twl4030_platform_data *pmic_data)
@@ -49,14 +59,31 @@ void __init omap_pmic_init(int bus, u32 clkrate,
 	omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
 }
 
+void omap4_pmic_init(const char *pmic_type,
+		    struct twl4030_platform_data *pmic_data,
+		    struct twl6040_platform_data *twl6040_data, int twl6040_irq)
+{
+	/* PMIC part*/
+	strncpy(omap4_i2c1_board_info[0].type, pmic_type,
+		sizeof(omap4_i2c1_board_info[0].type));
+	omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N;
+	omap4_i2c1_board_info[0].platform_data = pmic_data;
+
+	/* TWL6040 audio IC part */
+	omap4_i2c1_board_info[1].irq = twl6040_irq;
+	omap4_i2c1_board_info[1].platform_data = twl6040_data;
+
+	omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2);
+
+}
+
 void __init omap_pmic_late_init(void)
 {
 	/* Init the OMAP TWL parameters (if PMIC has been registerd) */
-	if (!pmic_i2c_board_info.irq)
-		return;
-
-	omap3_twl_init();
-	omap4_twl_init();
+	if (pmic_i2c_board_info.irq)
+		omap3_twl_init();
+	if (omap4_i2c1_board_info[0].irq)
+		omap4_twl_init();
 }
 
 #if defined(CONFIG_ARCH_OMAP3)
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h
index 275dde8..0962748 100644
--- a/arch/arm/mach-omap2/twl-common.h
+++ b/arch/arm/mach-omap2/twl-common.h
@@ -29,6 +29,7 @@
 
 
 struct twl4030_platform_data;
+struct twl6040_platform_data;
 
 void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
 		    struct twl4030_platform_data *pmic_data);
@@ -46,12 +47,9 @@ static inline void omap3_pmic_init(const char *pmic_type,
 	omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
 }
 
-static inline void omap4_pmic_init(const char *pmic_type,
-				   struct twl4030_platform_data *pmic_data)
-{
-	/* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
-	omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
-}
+void omap4_pmic_init(const char *pmic_type,
+		    struct twl4030_platform_data *pmic_data,
+		    struct twl6040_platform_data *audio_data, int twl6040_irq);
 
 void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data,
 			   u32 pdata_flags, u32 regulators_flags);
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index c005e2f..57db203 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -108,6 +108,7 @@ void __init omap3xxx_voltagedomains_init(void)
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
+#ifdef CONFIG_PM_OPP
 	if (cpu_is_omap3630()) {
 		omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data;
 		omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data;
@@ -115,6 +116,7 @@ void __init omap3xxx_voltagedomains_init(void)
 		omap3_voltdm_mpu.volt_data = omap34xx_vddmpu_volt_data;
 		omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
 	}
+#endif
 
 	if (cpu_is_omap3517() || cpu_is_omap3505())
 		voltdms = voltagedomains_am35xx;
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index 4e11d02..c3115f6 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -100,9 +100,11 @@ void __init omap44xx_voltagedomains_init(void)
 	 * XXX Will depend on the process, validation, and binning
 	 * for the currently-running IC
 	 */
+#ifdef CONFIG_PM_OPP
 	omap4_voltdm_mpu.volt_data = omap44xx_vdd_mpu_volt_data;
 	omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
 	omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
+#endif
 
 	for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
 		voltdm->sys_clk.name = sys_clk_name;
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
index a104d5a..e52108c 100644
--- a/arch/arm/mach-orion5x/db88f5281-setup.c
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -214,7 +214,7 @@ void __init db88f5281_pci_preinit(void)
 		if (gpio_direction_input(pin) == 0) {
 			irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
 		} else {
-			printk(KERN_ERR "db88f5281_pci_preinit faield to "
+			printk(KERN_ERR "db88f5281_pci_preinit failed to "
 					"set_irq_type pin %d\n", pin);
 			gpio_free(pin);
 		}
@@ -227,7 +227,7 @@ void __init db88f5281_pci_preinit(void)
 		if (gpio_direction_input(pin) == 0) {
 			irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
 		} else {
-			printk(KERN_ERR "db88f5281_pci_preinit faield "
+			printk(KERN_ERR "db88f5281_pci_preinit failed "
 					"to set_irq_type pin %d\n", pin);
 			gpio_free(pin);
 		}
diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h
deleted file mode 100644
index 825a265..0000000
--- a/arch/arm/mach-orion5x/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/system.h
- *
- * Tzachi Perelstein <tzachi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
index 96438b6..e3ce617 100644
--- a/arch/arm/mach-orion5x/rd88f5182-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -149,7 +149,7 @@ void __init rd88f5182_pci_preinit(void)
 		if (gpio_direction_input(pin) == 0) {
 			irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
 		} else {
-			printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+			printk(KERN_ERR "rd88f5182_pci_preinit failed to "
 					"set_irq_type pin %d\n", pin);
 			gpio_free(pin);
 		}
@@ -162,7 +162,7 @@ void __init rd88f5182_pci_preinit(void)
 		if (gpio_direction_input(pin) == 0) {
 			irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
 		} else {
-			printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+			printk(KERN_ERR "rd88f5182_pci_preinit failed to "
 					"set_irq_type pin %d\n", pin);
 			gpio_free(pin);
 		}
diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h
deleted file mode 100644
index 59eac1e..0000000
--- a/arch/arm/mach-picoxcell/include/mach/irqs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2011 Picochip Ltd., Jamie Iles
- *
- * 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.
- */
-#ifndef __MACH_IRQS_H
-#define __MACH_IRQS_H
-
-/* We dynamically allocate our irq_desc's. */
-#define NR_IRQS				0
-
-#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-picoxcell/include/mach/system.h b/arch/arm/mach-picoxcell/include/mach/system.h
deleted file mode 100644
index 1a5d8cb..0000000
--- a/arch/arm/mach-picoxcell/include/mach/system.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011 Picochip Ltd., Jamie Iles
- *
- * 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.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching and wait for interrupt
-	 * tricks.
-	 */
-	cpu_do_idle();
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h
deleted file mode 100644
index 60cfe71..0000000
--- a/arch/arm/mach-pnx4008/include/mach/system.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * arch/arm/mach-pnx4008/include/mach/system.h
- *
- * Copyright (C) 2003 Philips Semiconductors
- * Copyright (C) 2005 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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h
deleted file mode 100644
index 2c7d2a9..0000000
--- a/arch/arm/mach-prima2/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-prima2/include/mach/system.h
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#ifndef __MACH_SYSTEM_H__
-#define __MACH_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
index d93ceef..37c2de9 100644
--- a/arch/arm/mach-prima2/irq.c
+++ b/arch/arm/mach-prima2/irq.c
@@ -68,7 +68,7 @@ void __init sirfsoc_of_irq_init(void)
 	if (!sirfsoc_intc_base)
 		panic("unable to map intc cpu registers\n");
 
-	irq_domain_add_simple(np, 0);
+	irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
 
 	of_node_put(np);
 
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c
index b7a6091..0d024b1 100644
--- a/arch/arm/mach-prima2/timer.c
+++ b/arch/arm/mach-prima2/timer.c
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <mach/map.h>
+#include <asm/sched_clock.h>
 #include <asm/mach/time.h>
 
 #define SIRFSOC_TIMER_COUNTER_LO	0x0000
@@ -165,21 +166,9 @@ static struct irqaction sirfsoc_timer_irq = {
 };
 
 /* Overwrite weak default sched_clock with more precise one */
-unsigned long long notrace sched_clock(void)
+static u32 notrace sirfsoc_read_sched_clock(void)
 {
-	static int is_mapped;
-
-	/*
-	 * sched_clock is called earlier than .init of sys_timer
-	 * if we map timer memory in .init of sys_timer, system
-	 * will panic due to illegal memory access
-	 */
-	if (!is_mapped) {
-		sirfsoc_of_timer_map();
-		is_mapped = 1;
-	}
-
-	return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE);
+	return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff);
 }
 
 static void __init sirfsoc_clockevent_init(void)
@@ -210,6 +199,8 @@ static void __init sirfsoc_timer_init(void)
 	BUG_ON(rate < CLOCK_TICK_RATE);
 	BUG_ON(rate % CLOCK_TICK_RATE);
 
+	sirfsoc_of_timer_map();
+
 	writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
 	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
 	writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
@@ -217,6 +208,8 @@ static void __init sirfsoc_timer_init(void)
 
 	BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
 
+	setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE);
+
 	BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
 
 	sirfsoc_clockevent_init();
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
index c91727d..9a8760b 100644
--- a/arch/arm/mach-pxa/capc7117.c
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -150,6 +150,7 @@ MACHINE_START(CAPC7117,
 	      "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
 	.atag_offset = 0x100,
 	.map_io = pxa3xx_map_io,
+	.nr_irqs = PXA_NR_IRQS,
 	.init_irq = pxa3xx_init_irq,
 	.handle_irq = pxa3xx_handle_irq,
 	.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index 4b981b8..133ccee 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -853,6 +853,7 @@ static void __init cm_x300_fixup(struct tag *tags, char **cmdline,
 MACHINE_START(CM_X300, "CM-X300 module")
 	.atag_offset	= 0x100,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
index 29d5d54..b2f227d 100644
--- a/arch/arm/mach-pxa/colibri-pxa270.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -310,6 +310,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
 	.atag_offset	= 0x100,
 	.init_machine	= colibri_pxa270_init,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
@@ -320,6 +321,7 @@ MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
 	.atag_offset	= 0x100,
 	.init_machine	= colibri_pxa270_income_init,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
index 0846d21..bb6def8 100644
--- a/arch/arm/mach-pxa/colibri-pxa300.c
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -186,6 +186,7 @@ MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
 	.atag_offset	= 0x100,
 	.init_machine	= colibri_pxa300_init,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
index 6ad3359..d88e7b3 100644
--- a/arch/arm/mach-pxa/colibri-pxa320.c
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -256,6 +256,7 @@ MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
 	.atag_offset	= 0x100,
 	.init_machine	= colibri_pxa320_init,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 11f1e73..039aafa 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -730,6 +730,7 @@ static void __init fixup_corgi(struct tag *tags, char **cmdline,
 MACHINE_START(CORGI, "SHARP Corgi")
 	.fixup		= fixup_corgi,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.init_machine	= corgi_init,
@@ -742,6 +743,7 @@ MACHINE_END
 MACHINE_START(SHEPHERD, "SHARP Shepherd")
 	.fixup		= fixup_corgi,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.init_machine	= corgi_init,
@@ -754,6 +756,7 @@ MACHINE_END
 MACHINE_START(HUSKY, "SHARP Husky")
 	.fixup		= fixup_corgi,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.init_machine	= corgi_init,
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index fb5a51d..67f0de3 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -274,6 +274,7 @@ static void __init csb726_init(void)
 MACHINE_START(CSB726, "Cogent CSB726")
 	.atag_offset	= 0x100,
 	.map_io         = pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq       = pxa27x_init_irq,
 	.handle_irq       = pxa27x_handle_irq,
 	.init_machine   = csb726_init,
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 5bc1312..a450195 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -12,6 +12,7 @@
 #include <mach/pxafb.h>
 #include <mach/mmc.h>
 #include <mach/irda.h>
+#include <mach/irqs.h>
 #include <mach/ohci.h>
 #include <plat/pxa27x_keypad.h>
 #include <mach/camera.h>
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index d80c0ba..c1b65da 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -1301,6 +1301,7 @@ static void __init em_x270_init(void)
 MACHINE_START(EM_X270, "Compulab EM-X270")
 	.atag_offset	= 0x100,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
@@ -1311,6 +1312,7 @@ MACHINE_END
 MACHINE_START(EXEDA, "Compulab eXeda")
 	.atag_offset	= 0x100,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index ac3b1ce..e529a35 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -235,6 +235,7 @@ static void __init gumstix_init(void)
 MACHINE_START(GUMSTIX, "Gumstix")
 	.atag_offset	= 0x100, /* match u-boot bi_boot_params */
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
index fde6b4c..e7dec58 100644
--- a/arch/arm/mach-pxa/h5000.c
+++ b/arch/arm/mach-pxa/h5000.c
@@ -205,6 +205,7 @@ static void __init h5000_init(void)
 MACHINE_START(H5400, "HP iPAQ H5000")
 	.atag_offset = 0x100,
 	.map_io = pxa25x_map_io,
+	.nr_irqs = PXA_NR_IRQS,
 	.init_irq = pxa25x_init_irq,
 	.handle_irq = pxa25x_handle_irq,
 	.timer = &pxa_timer,
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
index 26d069a..2962de8 100644
--- a/arch/arm/mach-pxa/himalaya.c
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -160,6 +160,7 @@ static void __init himalaya_init(void)
 MACHINE_START(HIMALAYA, "HTC Himalaya")
 	.atag_offset = 0x100,
 	.map_io = pxa25x_map_io,
+	.nr_irqs = PXA_NR_IRQS,
 	.init_irq = pxa25x_init_irq,
 	.handle_irq = pxa25x_handle_irq,
 	.init_machine = himalaya_init,
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 6740019..1d02eab 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -193,6 +193,7 @@ static void __init icontrol_init(void)
 MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
 	.atag_offset	= 0x100,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 8af1840..6ff466b 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -195,6 +195,7 @@ static void __init idp_map_io(void)
 MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
 	/* Maintainer: Vibren Technologies */
 	.map_io		= idp_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h
index f02fa1e..954641e 100644
--- a/arch/arm/mach-pxa/include/mach/balloon3.h
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -174,7 +174,6 @@ enum balloon3_features {
 
 #define BALLOON3_AUX_NIRQ	PXA_GPIO_TO_IRQ(BALLOON3_GPIO_AUX_NIRQ)
 #define BALLOON3_CODEC_IRQ	PXA_GPIO_TO_IRQ(BALLOON3_GPIO_CODEC_IRQ)
-#define BALLOON3_S0_CD_IRQ	PXA_GPIO_TO_IRQ(BALLOON3_GPIO_S0_CD)
 
 #define BALLOON3_NR_IRQS	(IRQ_BOARD_START + 16)
 
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 32975ad..8765782 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -100,7 +100,7 @@
  */
 #define IRQ_BOARD_START		(PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO)
 
-#define NR_IRQS			(IRQ_BOARD_START)
+#define PXA_NR_IRQS		(IRQ_BOARD_START)
 
 #ifndef __ASSEMBLY__
 struct irq_data;
diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h
deleted file mode 100644
index c5afacd..0000000
--- a/arch/arm/mach-pxa/include/mach/system.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/system.h
- *
- * Author:	Nicolas Pitre
- * Created:	Jun 15, 2001
- * Copyright:	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 version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6ebd276..6bb3f47 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -223,6 +223,7 @@ static struct resource sa1111_resources[] = {
 
 static struct sa1111_platform_data sa1111_info = {
 	.irq_base	= LUBBOCK_SA1111_IRQ_BASE,
+	.disable_devs	= SA1111_DEVID_SAC,
 };
 
 static struct platform_device sa1111_device = {
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index e80a3db..061d570 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -758,6 +758,7 @@ MACHINE_START(MIOA701, "MIO A701")
 	.atag_offset	= 0x100,
 	.restart_mode	= 's',
 	.map_io		= &pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= &pxa27x_init_irq,
 	.handle_irq	= &pxa27x_handle_irq,
 	.init_machine	= mioa701_machine_init,
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
index 169bf8f..152efbf 100644
--- a/arch/arm/mach-pxa/mp900.c
+++ b/arch/arm/mach-pxa/mp900.c
@@ -95,6 +95,7 @@ MACHINE_START(NEC_MP900, "MobilePro900/C")
 	.atag_offset	= 0x220100,
 	.timer		= &pxa_timer,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.init_machine	= mp900c_init,
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index 1fa80f4f..31e0433 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -344,6 +344,7 @@ static void __init palmld_init(void)
 MACHINE_START(PALMLD, "Palm LifeDrive")
 	.atag_offset	= 0x100,
 	.map_io		= palmld_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 5ba1431..0f6bd4f 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -205,6 +205,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
 	.atag_offset	= 0x100,
 	.map_io		= pxa27x_map_io,
 	.reserve	= palmt5_reserve,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index 29b51b4..e2d97ee 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -539,6 +539,7 @@ static void __init palmtc_init(void)
 MACHINE_START(PALMTC, "Palm Tungsten|C")
 	.atag_offset 	= 0x100,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 5ebf49acb..c054827 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -358,6 +358,7 @@ static void __init palmte2_init(void)
 MACHINE_START(PALMTE2, "Palm Tungsten|E2")
 	.atag_offset	= 0x100,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index ec82491..fbdebee 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -448,6 +448,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
 	.atag_offset    = 0x100,
 	.map_io         = pxa27x_map_io,
 	.reserve	= treo_reserve,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq       = pxa27x_init_irq,
 	.handle_irq       = pxa27x_handle_irq,
 	.timer          = &pxa_timer,
@@ -461,6 +462,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
 	.atag_offset    = 0x100,
 	.map_io         = pxa27x_map_io,
 	.reserve	= treo_reserve,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq       = pxa27x_init_irq,
 	.handle_irq       = pxa27x_handle_irq,
 	.timer          = &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index 6170d76..9507605 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -366,6 +366,7 @@ static void __init palmtx_init(void)
 MACHINE_START(PALMTX, "Palm T|X")
 	.atag_offset	= 0x100,
 	.map_io		= palmtx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index b2dff9d..a97b599 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -401,6 +401,7 @@ static void __init palmz72_init(void)
 MACHINE_START(PALMZ72, "Palm Zire72")
 	.atag_offset	= 0x100,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4f402af..9fd5c6f 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -31,6 +31,7 @@
 #include <mach/pm.h>
 #include <mach/dma.h>
 #include <mach/smemc.h>
+#include <mach/irqs.h>
 
 #include "generic.h"
 #include "devices.h"
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 22818c7..7d691e5 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -1090,6 +1090,7 @@ MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
 	.atag_offset	= 0x100,
 	.init_machine	= raumfeld_controller_init,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
@@ -1102,6 +1103,7 @@ MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
 	.atag_offset	= 0x100,
 	.init_machine	= raumfeld_connector_init,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
@@ -1114,6 +1116,7 @@ MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
 	.atag_offset	= 0x100,
 	.init_machine	= raumfeld_speaker_init,
 	.map_io		= pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa3xx_init_irq,
 	.handle_irq	= pxa3xx_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index 0fe354e..86c95a5 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -598,6 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
 	/* Maintainer: Eric Miao <eric.miao@marvell.com> */
 	.atag_offset    = 0x100,
 	.map_io         = pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq       = pxa3xx_init_irq,
 	.handle_irq       = pxa3xx_handle_irq,
 	.timer          = &pxa_timer,
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index abf355d..df2ab0f 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -984,6 +984,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
 	.restart_mode	= 'g',
 	.fixup		= spitz_fixup,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.init_machine	= spitz_init,
@@ -997,6 +998,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
 	.restart_mode	= 'g',
 	.fixup		= spitz_fixup,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.init_machine	= spitz_init,
@@ -1010,6 +1012,7 @@ MACHINE_START(AKITA, "SHARP Akita")
 	.restart_mode	= 'g',
 	.fixup		= spitz_fixup,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.init_machine	= spitz_init,
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index b0656e15..adb601a 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -1006,6 +1006,7 @@ static void __init stargate2_init(void)
 #ifdef CONFIG_MACH_INTELMOTE2
 MACHINE_START(INTELMOTE2, "IMOTE 2")
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 9fb38e8..736bfdc 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -491,6 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
 	/* Maintainer: Eric Miao <eric.miao@marvell.com> */
 	.atag_offset    = 0x100,
 	.map_io         = pxa3xx_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq       = pxa3xx_init_irq,
 	.handle_irq       = pxa3xx_handle_irq,
 	.timer          = &pxa_timer,
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index b503049..3d6c9bd 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -22,6 +22,7 @@
 #include <asm/mach/time.h>
 #include <asm/sched_clock.h>
 #include <mach/regs-ost.h>
+#include <mach/irqs.h>
 
 /*
  * This is PXA's sched_clock implementation. This has a resolution
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 0f30af6..2b6ac00 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -558,6 +558,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
 	.atag_offset	= 0x100,
 	.init_machine	= trizeps4_init,
 	.map_io		= trizeps4_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
@@ -569,6 +570,7 @@ MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
 	.atag_offset	= 0x100,
 	.init_machine	= trizeps4_init,
 	.map_io		= trizeps4_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 023d6ca..3143c39 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -994,6 +994,7 @@ MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")
 	/* Maintainer: Marc Zyngier <maz@misterjones.org> */
 	.atag_offset	= 0x100,
 	.map_io		= viper_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= viper_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.timer          = &pxa_timer,
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index 1f5cfa9..c57ab63 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -718,6 +718,7 @@ static void __init vpac270_init(void)
 MACHINE_START(VPAC270, "Voipac PXA270")
 	.atag_offset	= 0x100,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
index 4bbe9a3..4275713 100644
--- a/arch/arm/mach-pxa/xcep.c
+++ b/arch/arm/mach-pxa/xcep.c
@@ -182,6 +182,7 @@ MACHINE_START(XCEP, "Iskratel XCEP")
 	.atag_offset	= 0x100,
 	.init_machine	= xcep_init,
 	.map_io		= pxa25x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa25x_init_irq,
 	.handle_irq	= pxa25x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index b647684..fa86199 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -721,6 +721,7 @@ static void __init z2_init(void)
 MACHINE_START(ZIPIT2, "Zipit Z2")
 	.atag_offset	= 0x100,
 	.map_io		= pxa27x_map_io,
+	.nr_irqs	= PXA_NR_IRQS,
 	.init_irq	= pxa27x_init_irq,
 	.handle_irq	= pxa27x_handle_irq,
 	.timer		= &pxa_timer,
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 735b57a..f8f2c0a 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -28,21 +28,11 @@
 #include <asm/setup.h>
 #include <asm/leds.h>
 
-#define AMBA_DEVICE(name,busid,base,plat)			\
-static struct amba_device name##_device = {			\
-	.dev		= {					\
-		.coherent_dma_mask = ~0,			\
-		.init_name = busid,				\
-		.platform_data = plat,				\
-	},							\
-	.res		= {					\
-		.start	= REALVIEW_##base##_BASE,		\
-		.end	= (REALVIEW_##base##_BASE) + SZ_4K - 1,	\
-		.flags	= IORESOURCE_MEM,			\
-	},							\
-	.dma_mask	= ~0,					\
-	.irq		= base##_IRQ,				\
-}
+#define APB_DEVICE(name, busid, base, plat)			\
+static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
+
+#define AHB_DEVICE(name, busid, base, plat)			\
+static AMBA_AHB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
 
 struct machine_desc;
 
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
index eb55f05..57d9efb 100644
--- a/arch/arm/mach-realview/hotplug.c
+++ b/arch/arm/mach-realview/hotplug.c
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <asm/smp_plat.h>
 
 extern volatile int pen_release;
diff --git a/arch/arm/mach-realview/include/mach/irqs-eb.h b/arch/arm/mach-realview/include/mach/irqs-eb.h
index 204d537..d6b5073 100644
--- a/arch/arm/mach-realview/include/mach/irqs-eb.h
+++ b/arch/arm/mach-realview/include/mach/irqs-eb.h
@@ -96,16 +96,19 @@
 #define IRQ_EB11MP_L220_SLAVE	(IRQ_EB_GIC_START + 30)
 #define IRQ_EB11MP_L220_DECODE	(IRQ_EB_GIC_START + 31)
 
-#define IRQ_EB11MP_UART2	-1
-#define IRQ_EB11MP_UART3	-1
-#define IRQ_EB11MP_CLCD		-1
-#define IRQ_EB11MP_DMA		-1
-#define IRQ_EB11MP_WDOG		-1
-#define IRQ_EB11MP_GPIO0	-1
-#define IRQ_EB11MP_GPIO1	-1
-#define IRQ_EB11MP_GPIO2	-1
-#define IRQ_EB11MP_SCI		-1
-#define IRQ_EB11MP_SSP		-1
+/*
+ * The 11MPcore tile leaves the following unconnected.
+ */
+#define IRQ_EB11MP_UART2	0
+#define IRQ_EB11MP_UART3	0
+#define IRQ_EB11MP_CLCD		0
+#define IRQ_EB11MP_DMA		0
+#define IRQ_EB11MP_WDOG		0
+#define IRQ_EB11MP_GPIO0	0
+#define IRQ_EB11MP_GPIO1	0
+#define IRQ_EB11MP_GPIO2	0
+#define IRQ_EB11MP_SCI		0
+#define IRQ_EB11MP_SSP		0
 
 #define NR_GIC_EB11MP		2
 
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
index 5c3c625..708f841 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
@@ -40,6 +40,7 @@
 #define IRQ_DC1176_L2CC		(IRQ_DC1176_GIC_START + 13)
 #define IRQ_DC1176_RTC		(IRQ_DC1176_GIC_START + 14)
 #define IRQ_DC1176_CLCD		(IRQ_DC1176_GIC_START + 15)	/* CLCD controller */
+#define IRQ_DC1176_GPIO0	(IRQ_DC1176_GIC_START + 16)
 #define IRQ_DC1176_SSP		(IRQ_DC1176_GIC_START + 17)	/* SSP port */
 #define IRQ_DC1176_UART0	(IRQ_DC1176_GIC_START + 18)	/* UART 0 on development chip */
 #define IRQ_DC1176_UART1	(IRQ_DC1176_GIC_START + 19)	/* UART 1 on development chip */
@@ -73,7 +74,6 @@
 #define IRQ_PB1176_DMAC		(IRQ_PB1176_GIC_START + 24)	/* DMA controller */
 #define IRQ_PB1176_RTC		(IRQ_PB1176_GIC_START + 25)	/* Real Time Clock */
 
-#define IRQ_PB1176_GPIO0	-1
 #define IRQ_PB1176_SCTL		-1
 
 #define NR_GIC_PB1176		2
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h
deleted file mode 100644
index 471b671..0000000
--- a/arch/arm/mach-realview/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  arch/arm/mach-realview/include/mach/system.h
- *
- *  Copyright (C) 2003 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 9578145..157e1bc 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -135,63 +135,63 @@ static struct pl022_ssp_controller ssp0_plat_data = {
 /*
  * These devices are connected via the core APB bridge
  */
-#define GPIO2_IRQ	{ IRQ_EB_GPIO2, NO_IRQ }
-#define GPIO3_IRQ	{ IRQ_EB_GPIO3, NO_IRQ }
+#define GPIO2_IRQ	{ IRQ_EB_GPIO2 }
+#define GPIO3_IRQ	{ IRQ_EB_GPIO3 }
 
-#define AACI_IRQ	{ IRQ_EB_AACI, NO_IRQ }
+#define AACI_IRQ	{ IRQ_EB_AACI }
 #define MMCI0_IRQ	{ IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
-#define KMI0_IRQ	{ IRQ_EB_KMI0, NO_IRQ }
-#define KMI1_IRQ	{ IRQ_EB_KMI1, NO_IRQ }
+#define KMI0_IRQ	{ IRQ_EB_KMI0 }
+#define KMI1_IRQ	{ IRQ_EB_KMI1 }
 
 /*
  * These devices are connected directly to the multi-layer AHB switch
  */
-#define EB_SMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define EB_CLCD_IRQ	{ IRQ_EB_CLCD, NO_IRQ }
-#define DMAC_IRQ	{ IRQ_EB_DMA, NO_IRQ }
+#define EB_SMC_IRQ	{ }
+#define MPMC_IRQ	{ }
+#define EB_CLCD_IRQ	{ IRQ_EB_CLCD }
+#define DMAC_IRQ	{ IRQ_EB_DMA }
 
 /*
  * These devices are connected via the core APB bridge
  */
-#define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
-#define EB_WATCHDOG_IRQ	{ IRQ_EB_WDOG, NO_IRQ }
-#define EB_GPIO0_IRQ	{ IRQ_EB_GPIO0, NO_IRQ }
-#define GPIO1_IRQ	{ IRQ_EB_GPIO1, NO_IRQ }
-#define EB_RTC_IRQ	{ IRQ_EB_RTC, NO_IRQ }
+#define SCTL_IRQ	{ }
+#define EB_WATCHDOG_IRQ	{ IRQ_EB_WDOG }
+#define EB_GPIO0_IRQ	{ IRQ_EB_GPIO0 }
+#define GPIO1_IRQ	{ IRQ_EB_GPIO1 }
+#define EB_RTC_IRQ	{ IRQ_EB_RTC }
 
 /*
  * These devices are connected via the DMA APB bridge
  */
-#define SCI_IRQ		{ IRQ_EB_SCI, NO_IRQ }
-#define EB_UART0_IRQ	{ IRQ_EB_UART0, NO_IRQ }
-#define EB_UART1_IRQ	{ IRQ_EB_UART1, NO_IRQ }
-#define EB_UART2_IRQ	{ IRQ_EB_UART2, NO_IRQ }
-#define EB_UART3_IRQ	{ IRQ_EB_UART3, NO_IRQ }
-#define EB_SSP_IRQ	{ IRQ_EB_SSP, NO_IRQ }
+#define SCI_IRQ		{ IRQ_EB_SCI }
+#define EB_UART0_IRQ	{ IRQ_EB_UART0 }
+#define EB_UART1_IRQ	{ IRQ_EB_UART1 }
+#define EB_UART2_IRQ	{ IRQ_EB_UART2 }
+#define EB_UART3_IRQ	{ IRQ_EB_UART3 }
+#define EB_SSP_IRQ	{ IRQ_EB_SSP }
 
 /* FPGA Primecells */
-AMBA_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
-AMBA_DEVICE(mmc0,  "fpga:mmc0",  MMCI0,    &realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0,  "fpga:kmi0",  KMI0,     NULL);
-AMBA_DEVICE(kmi1,  "fpga:kmi1",  KMI1,     NULL);
-AMBA_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
+APB_DEVICE(aaci,  "fpga:aaci",  AACI,     NULL);
+APB_DEVICE(mmc0,  "fpga:mmc0",  MMCI0,    &realview_mmc0_plat_data);
+APB_DEVICE(kmi0,  "fpga:kmi0",  KMI0,     NULL);
+APB_DEVICE(kmi1,  "fpga:kmi1",  KMI1,     NULL);
+APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
 
 /* DevChip Primecells */
-AMBA_DEVICE(smc,   "dev:smc",   EB_SMC,   NULL);
-AMBA_DEVICE(clcd,  "dev:clcd",  EB_CLCD,  &clcd_plat_data);
-AMBA_DEVICE(dmac,  "dev:dmac",  DMAC,     NULL);
-AMBA_DEVICE(sctl,  "dev:sctl",  SCTL,     NULL);
-AMBA_DEVICE(wdog,  "dev:wdog",  EB_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1,    &gpio1_plat_data);
-AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2,    &gpio2_plat_data);
-AMBA_DEVICE(rtc,   "dev:rtc",   EB_RTC,   NULL);
-AMBA_DEVICE(sci0,  "dev:sci0",  SCI,      NULL);
-AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
-AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
-AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
-AMBA_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   &ssp0_plat_data);
+AHB_DEVICE(smc,   "dev:smc",   EB_SMC,   NULL);
+AHB_DEVICE(clcd,  "dev:clcd",  EB_CLCD,  &clcd_plat_data);
+AHB_DEVICE(dmac,  "dev:dmac",  DMAC,     NULL);
+AHB_DEVICE(sctl,  "dev:sctl",  SCTL,     NULL);
+APB_DEVICE(wdog,  "dev:wdog",  EB_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1,    &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2,    &gpio2_plat_data);
+APB_DEVICE(rtc,   "dev:rtc",   EB_RTC,   NULL);
+APB_DEVICE(sci0,  "dev:sci0",  SCI,      NULL);
+APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
+APB_DEVICE(ssp0,  "dev:ssp0",  EB_SSP,   &ssp0_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index e4abe94..b1d7caf 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -132,50 +132,50 @@ static struct pl022_ssp_controller ssp0_plat_data = {
 /*
  * RealView PB1176 AMBA devices
  */
-#define GPIO2_IRQ	{ IRQ_PB1176_GPIO2, NO_IRQ }
-#define GPIO3_IRQ	{ IRQ_PB1176_GPIO3, NO_IRQ }
-#define AACI_IRQ	{ IRQ_PB1176_AACI, NO_IRQ }
+#define GPIO2_IRQ	{ IRQ_PB1176_GPIO2 }
+#define GPIO3_IRQ	{ IRQ_PB1176_GPIO3 }
+#define AACI_IRQ	{ IRQ_PB1176_AACI }
 #define MMCI0_IRQ	{ IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
-#define KMI0_IRQ	{ IRQ_PB1176_KMI0, NO_IRQ }
-#define KMI1_IRQ	{ IRQ_PB1176_KMI1, NO_IRQ }
-#define PB1176_SMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define PB1176_CLCD_IRQ	{ IRQ_DC1176_CLCD, NO_IRQ }
-#define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
-#define PB1176_WATCHDOG_IRQ	{ IRQ_DC1176_WATCHDOG, NO_IRQ }
-#define PB1176_GPIO0_IRQ	{ IRQ_PB1176_GPIO0, NO_IRQ }
-#define GPIO1_IRQ	{ IRQ_PB1176_GPIO1, NO_IRQ }
-#define PB1176_RTC_IRQ	{ IRQ_DC1176_RTC, NO_IRQ }
-#define SCI_IRQ		{ IRQ_PB1176_SCI, NO_IRQ }
-#define PB1176_UART0_IRQ	{ IRQ_DC1176_UART0, NO_IRQ }
-#define PB1176_UART1_IRQ	{ IRQ_DC1176_UART1, NO_IRQ }
-#define PB1176_UART2_IRQ	{ IRQ_DC1176_UART2, NO_IRQ }
-#define PB1176_UART3_IRQ	{ IRQ_DC1176_UART3, NO_IRQ }
-#define PB1176_UART4_IRQ	{ IRQ_PB1176_UART4, NO_IRQ }
-#define PB1176_SSP_IRQ		{ IRQ_DC1176_SSP, NO_IRQ }
+#define KMI0_IRQ	{ IRQ_PB1176_KMI0 }
+#define KMI1_IRQ	{ IRQ_PB1176_KMI1 }
+#define PB1176_SMC_IRQ	{ }
+#define MPMC_IRQ	{ }
+#define PB1176_CLCD_IRQ	{ IRQ_DC1176_CLCD }
+#define SCTL_IRQ	{ }
+#define PB1176_WATCHDOG_IRQ	{ IRQ_DC1176_WATCHDOG }
+#define PB1176_GPIO0_IRQ	{ IRQ_DC1176_GPIO0 }
+#define GPIO1_IRQ	{ IRQ_PB1176_GPIO1 }
+#define PB1176_RTC_IRQ	{ IRQ_DC1176_RTC }
+#define SCI_IRQ		{ IRQ_PB1176_SCI }
+#define PB1176_UART0_IRQ	{ IRQ_DC1176_UART0 }
+#define PB1176_UART1_IRQ	{ IRQ_DC1176_UART1 }
+#define PB1176_UART2_IRQ	{ IRQ_DC1176_UART2 }
+#define PB1176_UART3_IRQ	{ IRQ_DC1176_UART3 }
+#define PB1176_UART4_IRQ	{ IRQ_PB1176_UART4 }
+#define PB1176_SSP_IRQ		{ IRQ_DC1176_SSP }
 
 /* FPGA Primecells */
-AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
-AMBA_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
-AMBA_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
-AMBA_DEVICE(uart4,	"fpga:uart4",	PB1176_UART4,	NULL);
+APB_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
+APB_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
+APB_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
+APB_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
+APB_DEVICE(uart4,	"fpga:uart4",	PB1176_UART4,	NULL);
 
 /* DevChip Primecells */
-AMBA_DEVICE(smc,	"dev:smc",	PB1176_SMC,	NULL);
-AMBA_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
-AMBA_DEVICE(wdog,	"dev:wdog",	PB1176_WATCHDOG,	NULL);
-AMBA_DEVICE(gpio0,	"dev:gpio0",	PB1176_GPIO0,	&gpio0_plat_data);
-AMBA_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
-AMBA_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
-AMBA_DEVICE(rtc,	"dev:rtc",	PB1176_RTC,	NULL);
-AMBA_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
-AMBA_DEVICE(uart0,	"dev:uart0",	PB1176_UART0,	NULL);
-AMBA_DEVICE(uart1,	"dev:uart1",	PB1176_UART1,	NULL);
-AMBA_DEVICE(uart2,	"dev:uart2",	PB1176_UART2,	NULL);
-AMBA_DEVICE(uart3,	"dev:uart3",	PB1176_UART3,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PB1176_SSP,	&ssp0_plat_data);
-AMBA_DEVICE(clcd,	"dev:clcd",	PB1176_CLCD,	&clcd_plat_data);
+AHB_DEVICE(smc,		"dev:smc",	PB1176_SMC,	NULL);
+AHB_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
+APB_DEVICE(wdog,	"dev:wdog",	PB1176_WATCHDOG,	NULL);
+APB_DEVICE(gpio0,	"dev:gpio0",	PB1176_GPIO0,	&gpio0_plat_data);
+APB_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
+APB_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
+APB_DEVICE(rtc,		"dev:rtc",	PB1176_RTC,	NULL);
+APB_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
+APB_DEVICE(uart0,	"dev:uart0",	PB1176_UART0,	NULL);
+APB_DEVICE(uart1,	"dev:uart1",	PB1176_UART1,	NULL);
+APB_DEVICE(uart2,	"dev:uart2",	PB1176_UART2,	NULL);
+APB_DEVICE(uart3,	"dev:uart3",	PB1176_UART3,	NULL);
+APB_DEVICE(ssp0,	"dev:ssp0",	PB1176_SSP,	&ssp0_plat_data);
+AHB_DEVICE(clcd,	"dev:clcd",	PB1176_CLCD,	&clcd_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&uart0_device,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 2147335..ae7fe54 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -127,52 +127,52 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  * RealView PB11MPCore AMBA devices
  */
 
-#define GPIO2_IRQ		{ IRQ_PB11MP_GPIO2, NO_IRQ }
-#define GPIO3_IRQ		{ IRQ_PB11MP_GPIO3, NO_IRQ }
-#define AACI_IRQ		{ IRQ_TC11MP_AACI, NO_IRQ }
+#define GPIO2_IRQ		{ IRQ_PB11MP_GPIO2 }
+#define GPIO3_IRQ		{ IRQ_PB11MP_GPIO3 }
+#define AACI_IRQ		{ IRQ_TC11MP_AACI }
 #define MMCI0_IRQ		{ IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
-#define KMI0_IRQ		{ IRQ_TC11MP_KMI0, NO_IRQ }
-#define KMI1_IRQ		{ IRQ_TC11MP_KMI1, NO_IRQ }
-#define PB11MP_SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define PB11MP_CLCD_IRQ		{ IRQ_PB11MP_CLCD, NO_IRQ }
-#define DMAC_IRQ		{ IRQ_PB11MP_DMAC, NO_IRQ }
-#define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
-#define PB11MP_WATCHDOG_IRQ	{ IRQ_PB11MP_WATCHDOG, NO_IRQ }
-#define PB11MP_GPIO0_IRQ	{ IRQ_PB11MP_GPIO0, NO_IRQ }
-#define GPIO1_IRQ		{ IRQ_PB11MP_GPIO1, NO_IRQ }
-#define PB11MP_RTC_IRQ		{ IRQ_TC11MP_RTC, NO_IRQ }
-#define SCI_IRQ			{ IRQ_PB11MP_SCI, NO_IRQ }
-#define PB11MP_UART0_IRQ	{ IRQ_TC11MP_UART0, NO_IRQ }
-#define PB11MP_UART1_IRQ	{ IRQ_TC11MP_UART1, NO_IRQ }
-#define PB11MP_UART2_IRQ	{ IRQ_PB11MP_UART2, NO_IRQ }
-#define PB11MP_UART3_IRQ	{ IRQ_PB11MP_UART3, NO_IRQ }
-#define PB11MP_SSP_IRQ		{ IRQ_PB11MP_SSP, NO_IRQ }
+#define KMI0_IRQ		{ IRQ_TC11MP_KMI0 }
+#define KMI1_IRQ		{ IRQ_TC11MP_KMI1 }
+#define PB11MP_SMC_IRQ		{ }
+#define MPMC_IRQ		{ }
+#define PB11MP_CLCD_IRQ		{ IRQ_PB11MP_CLCD }
+#define DMAC_IRQ		{ IRQ_PB11MP_DMAC }
+#define SCTL_IRQ		{ }
+#define PB11MP_WATCHDOG_IRQ	{ IRQ_PB11MP_WATCHDOG }
+#define PB11MP_GPIO0_IRQ	{ IRQ_PB11MP_GPIO0 }
+#define GPIO1_IRQ		{ IRQ_PB11MP_GPIO1 }
+#define PB11MP_RTC_IRQ		{ IRQ_TC11MP_RTC }
+#define SCI_IRQ			{ IRQ_PB11MP_SCI }
+#define PB11MP_UART0_IRQ	{ IRQ_TC11MP_UART0 }
+#define PB11MP_UART1_IRQ	{ IRQ_TC11MP_UART1 }
+#define PB11MP_UART2_IRQ	{ IRQ_PB11MP_UART2 }
+#define PB11MP_UART3_IRQ	{ IRQ_PB11MP_UART3 }
+#define PB11MP_SSP_IRQ		{ IRQ_PB11MP_SSP }
 
 /* FPGA Primecells */
-AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
-AMBA_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
-AMBA_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
-AMBA_DEVICE(uart3,	"fpga:uart3",	PB11MP_UART3,	NULL);
+APB_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
+APB_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
+APB_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
+APB_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
+APB_DEVICE(uart3,	"fpga:uart3",	PB11MP_UART3,	NULL);
 
 /* DevChip Primecells */
-AMBA_DEVICE(smc,	"dev:smc",	PB11MP_SMC,	NULL);
-AMBA_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
-AMBA_DEVICE(wdog,	"dev:wdog",	PB11MP_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0,	"dev:gpio0",	PB11MP_GPIO0,	&gpio0_plat_data);
-AMBA_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
-AMBA_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
-AMBA_DEVICE(rtc,	"dev:rtc",	PB11MP_RTC,	NULL);
-AMBA_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
-AMBA_DEVICE(uart0,	"dev:uart0",	PB11MP_UART0,	NULL);
-AMBA_DEVICE(uart1,	"dev:uart1",	PB11MP_UART1,	NULL);
-AMBA_DEVICE(uart2,	"dev:uart2",	PB11MP_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PB11MP_SSP,	&ssp0_plat_data);
+AHB_DEVICE(smc,		"dev:smc",	PB11MP_SMC,	NULL);
+AHB_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
+APB_DEVICE(wdog,	"dev:wdog",	PB11MP_WATCHDOG, NULL);
+APB_DEVICE(gpio0,	"dev:gpio0",	PB11MP_GPIO0,	&gpio0_plat_data);
+APB_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
+APB_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
+APB_DEVICE(rtc,		"dev:rtc",	PB11MP_RTC,	NULL);
+APB_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
+APB_DEVICE(uart0,	"dev:uart0",	PB11MP_UART0,	NULL);
+APB_DEVICE(uart1,	"dev:uart1",	PB11MP_UART1,	NULL);
+APB_DEVICE(uart2,	"dev:uart2",	PB11MP_UART2,	NULL);
+APB_DEVICE(ssp0,	"dev:ssp0",	PB11MP_SSP,	&ssp0_plat_data);
 
 /* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd,	"issp:clcd",	PB11MP_CLCD,	&clcd_plat_data);
-AMBA_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
+AHB_DEVICE(clcd,	"issp:clcd",	PB11MP_CLCD,	&clcd_plat_data);
+AHB_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 25b2e59..5965017 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -122,52 +122,52 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  * RealView PBA8Core AMBA devices
  */
 
-#define GPIO2_IRQ		{ IRQ_PBA8_GPIO2, NO_IRQ }
-#define GPIO3_IRQ		{ IRQ_PBA8_GPIO3, NO_IRQ }
-#define AACI_IRQ		{ IRQ_PBA8_AACI, NO_IRQ }
+#define GPIO2_IRQ		{ IRQ_PBA8_GPIO2 }
+#define GPIO3_IRQ		{ IRQ_PBA8_GPIO3 }
+#define AACI_IRQ		{ IRQ_PBA8_AACI }
 #define MMCI0_IRQ		{ IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
-#define KMI0_IRQ		{ IRQ_PBA8_KMI0, NO_IRQ }
-#define KMI1_IRQ		{ IRQ_PBA8_KMI1, NO_IRQ }
-#define PBA8_SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define PBA8_CLCD_IRQ		{ IRQ_PBA8_CLCD, NO_IRQ }
-#define DMAC_IRQ		{ IRQ_PBA8_DMAC, NO_IRQ }
-#define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
-#define PBA8_WATCHDOG_IRQ	{ IRQ_PBA8_WATCHDOG, NO_IRQ }
-#define PBA8_GPIO0_IRQ		{ IRQ_PBA8_GPIO0, NO_IRQ }
-#define GPIO1_IRQ		{ IRQ_PBA8_GPIO1, NO_IRQ }
-#define PBA8_RTC_IRQ		{ IRQ_PBA8_RTC, NO_IRQ }
-#define SCI_IRQ			{ IRQ_PBA8_SCI, NO_IRQ }
-#define PBA8_UART0_IRQ		{ IRQ_PBA8_UART0, NO_IRQ }
-#define PBA8_UART1_IRQ		{ IRQ_PBA8_UART1, NO_IRQ }
-#define PBA8_UART2_IRQ		{ IRQ_PBA8_UART2, NO_IRQ }
-#define PBA8_UART3_IRQ		{ IRQ_PBA8_UART3, NO_IRQ }
-#define PBA8_SSP_IRQ		{ IRQ_PBA8_SSP, NO_IRQ }
+#define KMI0_IRQ		{ IRQ_PBA8_KMI0 }
+#define KMI1_IRQ		{ IRQ_PBA8_KMI1 }
+#define PBA8_SMC_IRQ		{ }
+#define MPMC_IRQ		{ }
+#define PBA8_CLCD_IRQ		{ IRQ_PBA8_CLCD }
+#define DMAC_IRQ		{ IRQ_PBA8_DMAC }
+#define SCTL_IRQ		{ }
+#define PBA8_WATCHDOG_IRQ	{ IRQ_PBA8_WATCHDOG }
+#define PBA8_GPIO0_IRQ		{ IRQ_PBA8_GPIO0 }
+#define GPIO1_IRQ		{ IRQ_PBA8_GPIO1 }
+#define PBA8_RTC_IRQ		{ IRQ_PBA8_RTC }
+#define SCI_IRQ			{ IRQ_PBA8_SCI }
+#define PBA8_UART0_IRQ		{ IRQ_PBA8_UART0 }
+#define PBA8_UART1_IRQ		{ IRQ_PBA8_UART1 }
+#define PBA8_UART2_IRQ		{ IRQ_PBA8_UART2 }
+#define PBA8_UART3_IRQ		{ IRQ_PBA8_UART3 }
+#define PBA8_SSP_IRQ		{ IRQ_PBA8_SSP }
 
 /* FPGA Primecells */
-AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
-AMBA_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
-AMBA_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
-AMBA_DEVICE(uart3,	"fpga:uart3",	PBA8_UART3,	NULL);
+APB_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
+APB_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
+APB_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
+APB_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
+APB_DEVICE(uart3,	"fpga:uart3",	PBA8_UART3,	NULL);
 
 /* DevChip Primecells */
-AMBA_DEVICE(smc,	"dev:smc",	PBA8_SMC,	NULL);
-AMBA_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
-AMBA_DEVICE(wdog,	"dev:wdog",	PBA8_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0,	"dev:gpio0",	PBA8_GPIO0,	&gpio0_plat_data);
-AMBA_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
-AMBA_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
-AMBA_DEVICE(rtc,	"dev:rtc",	PBA8_RTC,	NULL);
-AMBA_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
-AMBA_DEVICE(uart0,	"dev:uart0",	PBA8_UART0,	NULL);
-AMBA_DEVICE(uart1,	"dev:uart1",	PBA8_UART1,	NULL);
-AMBA_DEVICE(uart2,	"dev:uart2",	PBA8_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PBA8_SSP,	&ssp0_plat_data);
+AHB_DEVICE(smc,		"dev:smc",	PBA8_SMC,	NULL);
+AHB_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
+APB_DEVICE(wdog,	"dev:wdog",	PBA8_WATCHDOG, NULL);
+APB_DEVICE(gpio0,	"dev:gpio0",	PBA8_GPIO0,	&gpio0_plat_data);
+APB_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
+APB_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
+APB_DEVICE(rtc,		"dev:rtc",	PBA8_RTC,	NULL);
+APB_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
+APB_DEVICE(uart0,	"dev:uart0",	PBA8_UART0,	NULL);
+APB_DEVICE(uart1,	"dev:uart1",	PBA8_UART1,	NULL);
+APB_DEVICE(uart2,	"dev:uart2",	PBA8_UART2,	NULL);
+APB_DEVICE(ssp0,	"dev:ssp0",	PBA8_SSP,	&ssp0_plat_data);
 
 /* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd,	"issp:clcd",	PBA8_CLCD,	&clcd_plat_data);
-AMBA_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
+AHB_DEVICE(clcd,	"issp:clcd",	PBA8_CLCD,	&clcd_plat_data);
+AHB_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index ac71564..1cd9956 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -144,52 +144,52 @@ static struct pl022_ssp_controller ssp0_plat_data = {
  * RealView PBXCore AMBA devices
  */
 
-#define GPIO2_IRQ		{ IRQ_PBX_GPIO2, NO_IRQ }
-#define GPIO3_IRQ		{ IRQ_PBX_GPIO3, NO_IRQ }
-#define AACI_IRQ		{ IRQ_PBX_AACI, NO_IRQ }
+#define GPIO2_IRQ		{ IRQ_PBX_GPIO2 }
+#define GPIO3_IRQ		{ IRQ_PBX_GPIO3 }
+#define AACI_IRQ		{ IRQ_PBX_AACI }
 #define MMCI0_IRQ		{ IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
-#define KMI0_IRQ		{ IRQ_PBX_KMI0, NO_IRQ }
-#define KMI1_IRQ		{ IRQ_PBX_KMI1, NO_IRQ }
-#define PBX_SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define PBX_CLCD_IRQ		{ IRQ_PBX_CLCD, NO_IRQ }
-#define DMAC_IRQ		{ IRQ_PBX_DMAC, NO_IRQ }
-#define SCTL_IRQ		{ NO_IRQ, NO_IRQ }
-#define PBX_WATCHDOG_IRQ	{ IRQ_PBX_WATCHDOG, NO_IRQ }
-#define PBX_GPIO0_IRQ		{ IRQ_PBX_GPIO0, NO_IRQ }
-#define GPIO1_IRQ		{ IRQ_PBX_GPIO1, NO_IRQ }
-#define PBX_RTC_IRQ		{ IRQ_PBX_RTC, NO_IRQ }
-#define SCI_IRQ			{ IRQ_PBX_SCI, NO_IRQ }
-#define PBX_UART0_IRQ		{ IRQ_PBX_UART0, NO_IRQ }
-#define PBX_UART1_IRQ		{ IRQ_PBX_UART1, NO_IRQ }
-#define PBX_UART2_IRQ		{ IRQ_PBX_UART2, NO_IRQ }
-#define PBX_UART3_IRQ		{ IRQ_PBX_UART3, NO_IRQ }
-#define PBX_SSP_IRQ		{ IRQ_PBX_SSP, NO_IRQ }
+#define KMI0_IRQ		{ IRQ_PBX_KMI0 }
+#define KMI1_IRQ		{ IRQ_PBX_KMI1 }
+#define PBX_SMC_IRQ		{ }
+#define MPMC_IRQ		{ }
+#define PBX_CLCD_IRQ		{ IRQ_PBX_CLCD }
+#define DMAC_IRQ		{ IRQ_PBX_DMAC }
+#define SCTL_IRQ		{ }
+#define PBX_WATCHDOG_IRQ	{ IRQ_PBX_WATCHDOG }
+#define PBX_GPIO0_IRQ		{ IRQ_PBX_GPIO0 }
+#define GPIO1_IRQ		{ IRQ_PBX_GPIO1 }
+#define PBX_RTC_IRQ		{ IRQ_PBX_RTC }
+#define SCI_IRQ			{ IRQ_PBX_SCI }
+#define PBX_UART0_IRQ		{ IRQ_PBX_UART0 }
+#define PBX_UART1_IRQ		{ IRQ_PBX_UART1 }
+#define PBX_UART2_IRQ		{ IRQ_PBX_UART2 }
+#define PBX_UART3_IRQ		{ IRQ_PBX_UART3 }
+#define PBX_SSP_IRQ		{ IRQ_PBX_SSP }
 
 /* FPGA Primecells */
-AMBA_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
-AMBA_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
-AMBA_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
-AMBA_DEVICE(uart3,	"fpga:uart3",	PBX_UART3,	NULL);
+APB_DEVICE(aaci,	"fpga:aaci",	AACI,		NULL);
+APB_DEVICE(mmc0,	"fpga:mmc0",	MMCI0,		&realview_mmc0_plat_data);
+APB_DEVICE(kmi0,	"fpga:kmi0",	KMI0,		NULL);
+APB_DEVICE(kmi1,	"fpga:kmi1",	KMI1,		NULL);
+APB_DEVICE(uart3,	"fpga:uart3",	PBX_UART3,	NULL);
 
 /* DevChip Primecells */
-AMBA_DEVICE(smc,	"dev:smc",	PBX_SMC,	NULL);
-AMBA_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
-AMBA_DEVICE(wdog,	"dev:wdog",	PBX_WATCHDOG, 	NULL);
-AMBA_DEVICE(gpio0,	"dev:gpio0",	PBX_GPIO0,	&gpio0_plat_data);
-AMBA_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
-AMBA_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
-AMBA_DEVICE(rtc,	"dev:rtc",	PBX_RTC,	NULL);
-AMBA_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
-AMBA_DEVICE(uart0,	"dev:uart0",	PBX_UART0,	NULL);
-AMBA_DEVICE(uart1,	"dev:uart1",	PBX_UART1,	NULL);
-AMBA_DEVICE(uart2,	"dev:uart2",	PBX_UART2,	NULL);
-AMBA_DEVICE(ssp0,	"dev:ssp0",	PBX_SSP,	&ssp0_plat_data);
+AHB_DEVICE(smc,	"dev:smc",	PBX_SMC,	NULL);
+AHB_DEVICE(sctl,	"dev:sctl",	SCTL,		NULL);
+APB_DEVICE(wdog,	"dev:wdog",	PBX_WATCHDOG, 	NULL);
+APB_DEVICE(gpio0,	"dev:gpio0",	PBX_GPIO0,	&gpio0_plat_data);
+APB_DEVICE(gpio1,	"dev:gpio1",	GPIO1,		&gpio1_plat_data);
+APB_DEVICE(gpio2,	"dev:gpio2",	GPIO2,		&gpio2_plat_data);
+APB_DEVICE(rtc,		"dev:rtc",	PBX_RTC,	NULL);
+APB_DEVICE(sci0,	"dev:sci0",	SCI,		NULL);
+APB_DEVICE(uart0,	"dev:uart0",	PBX_UART0,	NULL);
+APB_DEVICE(uart1,	"dev:uart1",	PBX_UART1,	NULL);
+APB_DEVICE(uart2,	"dev:uart2",	PBX_UART2,	NULL);
+APB_DEVICE(ssp0,	"dev:ssp0",	PBX_SSP,	&ssp0_plat_data);
 
 /* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd,	"issp:clcd",	PBX_CLCD,	&clcd_plat_data);
-AMBA_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
+AHB_DEVICE(clcd,	"issp:clcd",	PBX_CLCD,	&clcd_plat_data);
+AHB_DEVICE(dmac,	"issp:dmac",	DMAC,		NULL);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h
deleted file mode 100644
index 359bab9..0000000
--- a/arch/arm/mach-rpc/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- *  arch/arm/mach-rpc/include/mach/system.h
- *
- *  Copyright (C) 1996-1999 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-s3c2410/include/mach/system.h b/arch/arm/mach-s3c2410/include/mach/system.h
deleted file mode 100644
index 5e215c1..0000000
--- a/arch/arm/mach-s3c2410/include/mach/system.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/system.h
- *
- * Copyright (c) 2003 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - System function defines and includes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <mach/hardware.h>
-
-#include <mach/map.h>
-#include <mach/idle.h>
-
-#include <mach/regs-clock.h>
-
-void (*s3c24xx_idle)(void);
-
-void s3c24xx_default_idle(void)
-{
-	unsigned long tmp;
-	int i;
-
-	/* idle the system by using the idle mode which will wait for an
-	 * interrupt to happen before restarting the system.
-	 */
-
-	/* Warning: going into idle state upsets jtag scanning */
-
-	__raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
-		     S3C2410_CLKCON);
-
-	/* the samsung port seems to do a loop and then unset idle.. */
-	for (i = 0; i < 50; i++) {
-		tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
-	}
-
-	/* this bit is not cleared on re-start... */
-
-	__raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
-		     S3C2410_CLKCON);
-}
-
-static void arch_idle(void)
-{
-	if (s3c24xx_idle != NULL)
-		(s3c24xx_idle)();
-	else
-		s3c24xx_default_idle();
-}
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 41245a6..6b21ba1 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -162,7 +162,7 @@ static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
 	return (latch_state >> (offset + 16)) & 1;
 }
 
-struct gpio_chip h1940_latch_gpiochip = {
+static struct gpio_chip h1940_latch_gpiochip = {
 	.base			= H1940_LATCH_GPIO(0),
 	.owner			= THIS_MODULE,
 	.label			= "H1940_LATCH",
@@ -304,7 +304,7 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
 	{ .volt = 3841, .cur = 0, .level = 0},
 };
 
-int h1940_bat_init(void)
+static int h1940_bat_init(void)
 {
 	int ret;
 
@@ -317,17 +317,17 @@ int h1940_bat_init(void)
 
 }
 
-void h1940_bat_exit(void)
+static void h1940_bat_exit(void)
 {
 	gpio_free(H1940_LATCH_SM803_ENABLE);
 }
 
-void h1940_enable_charger(void)
+static void h1940_enable_charger(void)
 {
 	gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
 }
 
-void h1940_disable_charger(void)
+static void h1940_disable_charger(void)
 {
 	gpio_set_value(H1940_LATCH_SM803_ENABLE, 0);
 }
@@ -364,7 +364,7 @@ static struct platform_device h1940_battery = {
 	},
 };
 
-DEFINE_SPINLOCK(h1940_blink_spin);
+static DEFINE_SPINLOCK(h1940_blink_spin);
 
 int h1940_led_blink_set(unsigned gpio, int state,
 	unsigned long *delay_on, unsigned long *delay_off)
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index aff6e85..c6eac98 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -32,8 +32,6 @@
 #include <asm/proc-fns.h>
 #include <asm/irq.h>
 
-#include <mach/idle.h>
-
 #include <plat/cpu-freq.h>
 
 #include <mach/regs-clock.h>
@@ -164,7 +162,7 @@ void __init s3c2412_map_io(void)
 
 	/* set our idle function */
 
-	s3c24xx_idle = s3c2412_idle;
+	arm_pm_idle = s3c2412_idle;
 
 	/* register our io-tables */
 
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
index 59f54d1..e01490d 100644
--- a/arch/arm/mach-s3c2416/clock.c
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -132,12 +132,6 @@ static struct clk hsmmc0_clk = {
 	.ctrlbit	= S3C2416_HCLKCON_HSMMC0,
 };
 
-void __init_or_cpufreq s3c2416_setup_clocks(void)
-{
-	s3c2443_common_setup_clocks(s3c2416_get_pll);
-}
-
-
 static struct clksrc_clk *clksrcs[] __initdata = {
 	&hsspi_eplldiv,
 	&hsspi_mux,
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
index eebe1e7..30a44f8 100644
--- a/arch/arm/mach-s3c2416/mach-smdk2416.c
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -125,7 +125,7 @@ static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
 	}
 };
 
-void smdk2416_hsudc_gpio_init(void)
+static void smdk2416_hsudc_gpio_init(void)
 {
 	s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
 	s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
@@ -133,20 +133,20 @@ void smdk2416_hsudc_gpio_init(void)
 	s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
 }
 
-void smdk2416_hsudc_gpio_uninit(void)
+static void smdk2416_hsudc_gpio_uninit(void)
 {
 	s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
 	s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
 	s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
 }
 
-struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
+static struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
 	.epnum = 9,
 	.gpio_init = smdk2416_hsudc_gpio_init,
 	.gpio_uninit = smdk2416_hsudc_gpio_uninit,
 };
 
-struct s3c_fb_pd_win smdk2416_fb_win[] = {
+static struct s3c_fb_pd_win smdk2416_fb_win[] = {
 	[0] = {
 		/* think this is the same as the smdk6410 */
 		.win_mode	= {
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index 5287d28..0e9a71c 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -44,7 +44,6 @@
 #include <asm/proc-fns.h>
 #include <asm/irq.h>
 
-#include <mach/idle.h>
 #include <mach/regs-s3c2443-clock.h>
 
 #include <plat/gpio-core.h>
@@ -60,6 +59,7 @@
 #include <plat/fb-core.h>
 #include <plat/nand-core.h>
 #include <plat/adc-core.h>
+#include <plat/rtc-core.h>
 
 static struct map_desc s3c2416_iodesc[] __initdata = {
 	IODESC_ENT(WATCHDOG),
@@ -88,8 +88,6 @@ int __init s3c2416_init(void)
 {
 	printk(KERN_INFO "S3C2416: Initializing architecture\n");
 
-	/* s3c24xx_idle = s3c2416_idle;	*/
-
 	/* change WDT IRQ number */
 	s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
 	s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
@@ -101,6 +99,7 @@ int __init s3c2416_init(void)
 	s3c_fb_setname("s3c2443-fb");
 
 	s3c_adc_setname("s3c2416-adc");
+	s3c_rtc_setname("s3c2416-rtc");
 
 #ifdef CONFIG_PM
 	register_syscore_ops(&s3c2416_pm_syscore_ops);
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index 5859e60..7365a44 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -258,7 +258,7 @@ static struct pcf50633_bl_platform_data gta02_backlight_data = {
 	.ramp_time = 5,
 };
 
-struct pcf50633_platform_data gta02_pcf_pdata = {
+static struct pcf50633_platform_data gta02_pcf_pdata = {
 	.resumers = {
 		[0] =	PCF50633_INT1_USBINS |
 			PCF50633_INT1_USBREM |
@@ -404,7 +404,7 @@ static struct platform_device gta02_nor_flash = {
 };
 
 
-struct platform_device s3c24xx_pwm_device = {
+static struct platform_device s3c24xx_pwm_device = {
 	.name		= "s3c24xx_pwm",
 	.num_resources	= 0,
 };
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 80077f6..4a8e2d3 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -217,7 +217,7 @@ static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
 	{ .volt = 3820, .cur = 0, .level = 0},
 };
 
-int rx1950_bat_init(void)
+static int rx1950_bat_init(void)
 {
 	int ret;
 
@@ -236,25 +236,25 @@ err_gpio1:
 	return ret;
 }
 
-void rx1950_bat_exit(void)
+static void rx1950_bat_exit(void)
 {
 	gpio_free(S3C2410_GPJ(2));
 	gpio_free(S3C2410_GPJ(3));
 }
 
-void rx1950_enable_charger(void)
+static void rx1950_enable_charger(void)
 {
 	gpio_direction_output(S3C2410_GPJ(2), 1);
 	gpio_direction_output(S3C2410_GPJ(3), 1);
 }
 
-void rx1950_disable_charger(void)
+static void rx1950_disable_charger(void)
 {
 	gpio_direction_output(S3C2410_GPJ(2), 0);
 	gpio_direction_output(S3C2410_GPJ(3), 0);
 }
 
-DEFINE_SPINLOCK(rx1950_blink_spin);
+static DEFINE_SPINLOCK(rx1950_blink_spin);
 
 static int rx1950_led_blink_set(unsigned gpio, int state,
 	unsigned long *delay_on, unsigned long *delay_off)
@@ -382,7 +382,7 @@ static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
 
 static struct pwm_device *lcd_pwm;
 
-void rx1950_lcd_power(int enable)
+static void rx1950_lcd_power(int enable)
 {
 	int i;
 	static int enabled;
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index b9deaeb..b7778a9 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -41,6 +41,7 @@
 #include <plat/fb-core.h>
 #include <plat/nand-core.h>
 #include <plat/adc-core.h>
+#include <plat/rtc-core.h>
 
 static struct map_desc s3c2443_iodesc[] __initdata = {
 	IODESC_ENT(WATCHDOG),
@@ -73,6 +74,7 @@ int __init s3c2443_init(void)
 	s3c_fb_setname("s3c2443-fb");
 
 	s3c_adc_setname("s3c2443-adc");
+	s3c_rtc_setname("s3c2443-rtc");
 
 	/* change WDT IRQ number */
 	s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index dd20c66..dc45123 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -296,5 +296,6 @@ config MACH_WLF_CRAGG_6410
 	select S3C64XX_DEV_SPI0
 	select SAMSUNG_GPIO_EXTRA128
 	select I2C
+	select LEDS_GPIO_REGISTER
 	help
 	  Machine support for the Wolfson Cragganmore S3C6410 variant.
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 1822ac2..610fe28 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_CPU_S3C6410)	+= s3c6410.o
 # PM
 
 obj-$(CONFIG_PM)		+= pm.o irq-pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 # DMA support
 
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index aebbcc2..52f079a 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -207,6 +207,15 @@ static struct clk init_clocks_off[] = {
 		.enable		= s3c64xx_sclk_ctrl,
 		.ctrlbit	= S3C_CLKCON_SCLK_MMC2_48,
 	}, {
+		.name		= "ac97",
+		.parent		= &clk_p,
+		.ctrlbit	= S3C_CLKCON_PCLK_AC97,
+	}, {
+		.name		= "cfcon",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_IHOST,
+	}, {
 		.name		= "dma0",
 		.parent		= &clk_h,
 		.enable		= s3c64xx_hclk_ctrl,
@@ -216,6 +225,107 @@ static struct clk init_clocks_off[] = {
 		.parent		= &clk_h,
 		.enable		= s3c64xx_hclk_ctrl,
 		.ctrlbit	= S3C_CLKCON_HCLK_DMA1,
+	}, {
+		.name		= "3dse",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_3DSE,
+	}, {
+		.name		= "hclk_secur",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_SECUR,
+	}, {
+		.name		= "sdma1",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_SDMA1,
+	}, {
+		.name		= "sdma0",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_SDMA0,
+	}, {
+		.name		= "hclk_jpeg",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_JPEG,
+	}, {
+		.name		= "camif",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_CAMIF,
+	}, {
+		.name		= "hclk_scaler",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_SCALER,
+	}, {
+		.name		= "2d",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_2D,
+	}, {
+		.name		= "tv",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_TV,
+	}, {
+		.name		= "post0",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_POST0,
+	}, {
+		.name		= "rot",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_ROT,
+	}, {
+		.name		= "hclk_mfc",
+		.parent		= &clk_h,
+		.enable		= s3c64xx_hclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_HCLK_MFC,
+	}, {
+		.name		= "pclk_mfc",
+		.parent		= &clk_p,
+		.enable		= s3c64xx_pclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_PCLK_MFC,
+	}, {
+		.name		= "dac27",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_DAC27,
+	}, {
+		.name		= "tv27",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_TV27,
+	}, {
+		.name		= "scaler27",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_SCALER27,
+	}, {
+		.name		= "sclk_scaler",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_SCALER,
+	}, {
+		.name		= "post0_27",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_POST0_27,
+	}, {
+		.name		= "secur",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_SECUR,
+	}, {
+		.name		= "sclk_mfc",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_MFC,
+	}, {
+		.name		= "cam",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_CAM,
+	}, {
+		.name		= "sclk_jpeg",
+		.enable		= s3c64xx_sclk_ctrl,
+		.ctrlbit	= S3C_CLKCON_SCLK_JPEG,
 	},
 };
 
@@ -289,16 +399,7 @@ static struct clk init_clocks[] = {
 		.name		= "watchdog",
 		.parent		= &clk_p,
 		.ctrlbit	= S3C_CLKCON_PCLK_WDT,
-	}, {
-		.name		= "ac97",
-		.parent		= &clk_p,
-		.ctrlbit	= S3C_CLKCON_PCLK_AC97,
-	}, {
-		.name		= "cfcon",
-		.parent		= &clk_h,
-		.enable		= s3c64xx_hclk_ctrl,
-		.ctrlbit	= S3C_CLKCON_HCLK_IHOST,
-	}
+	},
 };
 
 static struct clk clk_hsmmc0 = {
diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h
index 5eb9c9a..7a10be6 100644
--- a/arch/arm/mach-s3c64xx/common.h
+++ b/arch/arm/mach-s3c64xx/common.h
@@ -25,8 +25,6 @@ void s3c64xx_setup_clocks(void);
 
 void s3c64xx_restart(char mode, const char *cmd);
 
-extern struct syscore_ops s3c64xx_irq_syscore_ops;
-
 #ifdef CONFIG_CPU_S3C6400
 
 extern  int s3c6400_init(void);
diff --git a/arch/arm/mach-s3c64xx/cpuidle.c b/arch/arm/mach-s3c64xx/cpuidle.c
new file mode 100644
index 0000000..179460f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpuidle.c
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-s3c64xx/cpuidle.c
+ *
+ * Copyright (c) 2011 Wolfson Microelectronics, plc
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <linux/export.h>
+#include <linux/time.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-syscon-power.h>
+
+static int s3c64xx_enter_idle(struct cpuidle_device *dev,
+			      struct cpuidle_driver *drv,
+			      int index)
+{
+	struct timeval before, after;
+	unsigned long tmp;
+	int idle_time;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+
+	/* Setup PWRCFG to enter idle mode */
+	tmp = __raw_readl(S3C64XX_PWR_CFG);
+	tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+	tmp |= S3C64XX_PWRCFG_CFG_WFI_IDLE;
+	__raw_writel(tmp, S3C64XX_PWR_CFG);
+
+	cpu_do_idle();
+
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+		    (after.tv_usec - before.tv_usec);
+
+	dev->last_residency = idle_time;
+	return index;
+}
+
+static struct cpuidle_state s3c64xx_cpuidle_set[] = {
+	[0] = {
+		.enter			= s3c64xx_enter_idle,
+		.exit_latency		= 1,
+		.target_residency	= 1,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "IDLE",
+		.desc			= "System active, ARM gated",
+	},
+};
+
+static struct cpuidle_driver s3c64xx_cpuidle_driver = {
+	.name		= "s3c64xx_cpuidle",
+	.owner		= THIS_MODULE,
+	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
+};
+
+static struct cpuidle_device s3c64xx_cpuidle_device = {
+	.state_count	= ARRAY_SIZE(s3c64xx_cpuidle_set),
+};
+
+static int __init s3c64xx_init_cpuidle(void)
+{
+	int ret;
+
+	memcpy(s3c64xx_cpuidle_driver.states, s3c64xx_cpuidle_set,
+	       sizeof(s3c64xx_cpuidle_set));
+	cpuidle_register_driver(&s3c64xx_cpuidle_driver);
+
+	ret = cpuidle_register_device(&s3c64xx_cpuidle_device);
+	if (ret) {
+		pr_err("Failed to register cpuidle device: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+device_initcall(s3c64xx_init_cpuidle);
diff --git a/arch/arm/mach-s3c64xx/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h
deleted file mode 100644
index 353ed43..0000000
--- a/arch/arm/mach-s3c64xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/system.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * S3C6400 - system implementation
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
index 8bec61e..0c7e1d9 100644
--- a/arch/arm/mach-s3c64xx/irq-pm.c
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -96,7 +96,7 @@ static void s3c64xx_irq_pm_resume(void)
 	S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
 }
 
-struct syscore_ops s3c64xx_irq_syscore_ops = {
+static struct syscore_ops s3c64xx_irq_syscore_ops = {
 	.suspend = s3c64xx_irq_pm_suspend,
 	.resume	 = s3c64xx_irq_pm_resume,
 };
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410-module.c b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
index cd3c97e..618f7f4 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410-module.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410-module.c
@@ -11,6 +11,7 @@
 #include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 
 #include <linux/mfd/wm831x/irq.h>
 #include <linux/mfd/wm831x/gpio.h>
@@ -21,8 +22,25 @@
 #include <sound/wm8962.h>
 #include <sound/wm9081.h>
 
+#include <plat/s3c64xx-spi.h>
+
 #include <mach/crag6410.h>
 
+static struct s3c64xx_spi_csinfo wm0010_spi_csinfo = {
+	.set_level = gpio_set_value,
+	.line = S3C64XX_GPC(3),
+};
+
+static struct spi_board_info wm1253_devs[] = {
+	[0] = {
+		.modalias	= "wm0010",
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_0,
+		.controller_data = &wm0010_spi_csinfo,
+	},
+};
+
 static struct wm5100_pdata wm5100_pdata = {
 	.ldo_ena = S3C64XX_GPN(7),
 	.irq_flags = IRQF_TRIGGER_HIGH,
@@ -102,6 +120,7 @@ static struct wm8962_pdata wm8962_pdata __initdata = {
 		0x8000 | WM8962_GPIO_FN_DMICDAT,
 		WM8962_GPIO_FN_IRQ,    /* Open drain mode */
 	},
+	.in4_dc_measure = true,
 };
 
 static struct wm9081_pdata wm9081_pdata __initdata = {
@@ -158,6 +177,8 @@ static __devinitdata const struct {
 	const char *name;
 	const struct i2c_board_info *i2c_devs;
 	int num_i2c_devs;
+	const struct spi_board_info *spi_devs;
+	int num_spi_devs;
 } gf_mods[] = {
 	{ .id = 0x01, .name = "1250-EV1 Springbank" },
 	{ .id = 0x02, .name = "1251-EV1 Jura" },
@@ -165,7 +186,8 @@ static __devinitdata const struct {
 	{ .id = 0x11, .name = "6249-EV2 Glenfarclas", },
 	{ .id = 0x21, .name = "1275-EV1 Mortlach" },
 	{ .id = 0x25, .name = "1274-EV1 Glencadam" },
-	{ .id = 0x31, .name = "1253-EV1 Tomatin", },
+	{ .id = 0x31, .name = "1253-EV1 Tomatin",
+	  .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs) },
 	{ .id = 0x39, .name = "1254-EV1 Dallas Dhu",
 	  .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs) },
 	{ .id = 0x3a, .name = "1259-EV1 Tobermory",
@@ -197,12 +219,16 @@ static __devinit int wlf_gf_module_probe(struct i2c_client *i2c,
 	if (i < ARRAY_SIZE(gf_mods)) {
 		dev_info(&i2c->dev, "%s revision %d\n",
 			 gf_mods[i].name, rev + 1);
+
 		for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
 			if (!i2c_new_device(i2c->adapter,
 					    &(gf_mods[i].i2c_devs[j])))
 				dev_err(&i2c->dev,
 					"Failed to register dev: %d\n", ret);
 		}
+
+		spi_register_board_info(gf_mods[i].spi_devs,
+					gf_mods[i].num_spi_devs);
 	} else {
 		dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
 			 id, rev + 1);
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 8077f65..79f9934 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -19,7 +19,9 @@
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
+#include <linux/leds.h>
 #include <linux/delay.h>
+#include <linux/mmc/host.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
 #include <linux/pwm_backlight.h>
@@ -298,6 +300,7 @@ static struct platform_device littlemill_device = {
 };
 
 static struct regulator_consumer_supply wallvdd_consumers[] = {
+	REGULATOR_SUPPLY("SPKVDD", "1-001a"),
 	REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
 	REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
 	REGULATOR_SUPPLY("SPKVDDL", "1-001a"),
@@ -574,11 +577,19 @@ static struct s3c2410_platform_i2c i2c0_pdata = {
 	.frequency = 400000,
 };
 
+static struct regulator_consumer_supply pvdd_1v2_consumers[] __initdata = {
+	REGULATOR_SUPPLY("DCVDD", "spi0.0"),
+	REGULATOR_SUPPLY("AVDD", "spi0.0"),
+};
+
 static struct regulator_init_data pvdd_1v2 __initdata = {
 	.constraints = {
 		.name = "PVDD_1V2",
-		.always_on = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 	},
+
+	.consumer_supplies = pvdd_1v2_consumers,
+	.num_consumer_supplies = ARRAY_SIZE(pvdd_1v2_consumers),
 };
 
 static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
@@ -592,6 +603,7 @@ static struct regulator_consumer_supply pvdd_1v8_consumers[] __initdata = {
 	REGULATOR_SUPPLY("AVDD2", "1-001a"),
 	REGULATOR_SUPPLY("DCVDD", "1-001a"),
 	REGULATOR_SUPPLY("AVDD", "1-001a"),
+	REGULATOR_SUPPLY("DBVDD", "spi0.0"),
 };
 
 static struct regulator_init_data pvdd_1v8 __initdata = {
@@ -681,6 +693,7 @@ static void __init crag6410_map_io(void)
 static struct s3c_sdhci_platdata crag6410_hsmmc2_pdata = {
 	.max_width		= 4,
 	.cd_type		= S3C_SDHCI_CD_PERMANENT,
+	.host_caps		= MMC_CAP_POWER_OFF_CARD,
 };
 
 static void crag6410_cfg_sdhci0(struct platform_device *dev, int width)
@@ -696,6 +709,55 @@ static struct s3c_sdhci_platdata crag6410_hsmmc0_pdata = {
 	.max_width		= 4,
 	.cd_type		= S3C_SDHCI_CD_INTERNAL,
 	.cfg_gpio		= crag6410_cfg_sdhci0,
+	.host_caps		= MMC_CAP_POWER_OFF_CARD,
+};
+
+static const struct gpio_led gpio_leds[] = {
+	{
+		.name = "d13:green:",
+		.gpio = MMGPIO_GPIO_BASE + 0,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d14:green:",
+		.gpio = MMGPIO_GPIO_BASE + 1,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d15:green:",
+		.gpio = MMGPIO_GPIO_BASE + 2,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d16:green:",
+		.gpio = MMGPIO_GPIO_BASE + 3,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d17:green:",
+		.gpio = MMGPIO_GPIO_BASE + 4,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d18:green:",
+		.gpio = MMGPIO_GPIO_BASE + 5,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d19:green:",
+		.gpio = MMGPIO_GPIO_BASE + 6,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+	{
+		.name = "d20:green:",
+		.gpio = MMGPIO_GPIO_BASE + 7,
+		.default_state = LEDS_GPIO_DEFSTATE_ON,
+	},
+};
+
+static const struct gpio_led_platform_data gpio_leds_pdata = {
+	.leds = gpio_leds,
+	.num_leds = ARRAY_SIZE(gpio_leds),
 };
 
 static void __init crag6410_machine_init(void)
@@ -727,9 +789,12 @@ static void __init crag6410_machine_init(void)
 	i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
 
 	samsung_keypad_set_platdata(&crag6410_keypad_data);
+	s3c64xx_spi0_set_platdata(NULL, 0, 1);
 
 	platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
 
+	gpio_led_register_device(-1, &gpio_leds_pdata);
+
 	regulator_has_full_constraints();
 
 	s3c64xx_pm_init();
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
index 241d0e6..57e7189 100644
--- a/arch/arm/mach-s5p64x0/clock.c
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -73,7 +73,7 @@ static const u32 clock_table[][3] = {
 	{L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
 };
 
-unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
+static unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
 {
 	unsigned long rate = clk_get_rate(clk->parent);
 	u32 clkdiv;
@@ -84,7 +84,8 @@ unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
 	return rate / (clkdiv + 1);
 }
 
-unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long s5p64x0_armclk_round_rate(struct clk *clk,
+					       unsigned long rate)
 {
 	u32 iter;
 
@@ -96,7 +97,7 @@ unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
 	return clock_table[ARRAY_SIZE(clock_table) - 1][0];
 }
 
-int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
+static int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 round_tmp;
 	u32 iter;
@@ -148,7 +149,7 @@ int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
 	return 0;
 }
 
-struct clk_ops s5p64x0_clkarm_ops = {
+static struct clk_ops s5p64x0_clkarm_ops = {
 	.get_rate	= s5p64x0_armclk_get_rate,
 	.set_rate	= s5p64x0_armclk_set_rate,
 	.round_rate	= s5p64x0_armclk_round_rate,
@@ -173,7 +174,7 @@ struct clksrc_clk clk_dout_mpll = {
 	.reg_div	= { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 },
 };
 
-struct clk *clkset_hclk_low_list[] = {
+static struct clk *clkset_hclk_low_list[] = {
 	&clk_mout_apll.clk,
 	&clk_mout_mpll.clk,
 };
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 52b89a3..9143f8b 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -146,15 +146,12 @@ static void s5p64x0_idle(void)
 {
 	unsigned long val;
 
-	if (!need_resched()) {
-		val = __raw_readl(S5P64X0_PWR_CFG);
-		val &= ~(0x3 << 5);
-		val |= (0x1 << 5);
-		__raw_writel(val, S5P64X0_PWR_CFG);
+	val = __raw_readl(S5P64X0_PWR_CFG);
+	val &= ~(0x3 << 5);
+	val |= (0x1 << 5);
+	__raw_writel(val, S5P64X0_PWR_CFG);
 
-		cpu_do_idle();
-	}
-	local_irq_enable();
+	cpu_do_idle();
 }
 
 /*
@@ -286,7 +283,7 @@ int __init s5p64x0_init(void)
 	printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
 
 	/* set idle function */
-	pm_idle = s5p64x0_idle;
+	arm_pm_idle = s5p64x0_idle;
 
 	return device_register(&s5p64x0_dev);
 }
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index f820c07..2ee5dc0 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -38,7 +38,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 s5p6440_pdma_peri[] = {
+static u8 s5p6440_pdma_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
@@ -63,12 +63,12 @@ u8 s5p6440_pdma_peri[] = {
 	DMACH_SPI1_RX,
 };
 
-struct dma_pl330_platdata s5p6440_pdma_pdata = {
+static struct dma_pl330_platdata s5p6440_pdma_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
 	.peri_id = s5p6440_pdma_peri,
 };
 
-u8 s5p6450_pdma_peri[] = {
+static u8 s5p6450_pdma_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
@@ -103,39 +103,27 @@ u8 s5p6450_pdma_peri[] = {
 	DMACH_UART5_TX,
 };
 
-struct dma_pl330_platdata s5p6450_pdma_pdata = {
+static struct dma_pl330_platdata s5p6450_pdma_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
 	.peri_id = s5p6450_pdma_peri,
 };
 
-struct amba_device s5p64x0_device_pdma = {
-	.dev = {
-		.init_name = "dma-pl330",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.res = {
-		.start = S5P64X0_PA_PDMA,
-		.end = S5P64X0_PA_PDMA + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_DMA0, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(s5p64x0_pdma, "dma-pl330", 0x00041330,
+	S5P64X0_PA_PDMA, {IRQ_DMA0}, NULL);
 
 static int __init s5p64x0_dma_init(void)
 {
 	if (soc_is_s5p6450()) {
 		dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
 		dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
-		s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
+		s5p64x0_pdma_device.dev.platform_data = &s5p6450_pdma_pdata;
 	} else {
 		dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
 		dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
-		s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
+		s5p64x0_pdma_device.dev.platform_data = &s5p6440_pdma_pdata;
 	}
 
-	amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
+	amba_device_register(&s5p64x0_pdma_device, &iomem_resource);
 
 	return 0;
 }
diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
index ff85b4b..0ef47d1 100644
--- a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
@@ -22,16 +22,9 @@ extern struct clksrc_clk clk_mout_epll;
 extern int s5p64x0_epll_enable(struct clk *clk, int enable);
 extern unsigned long s5p64x0_epll_get_rate(struct clk *clk);
 
-extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk);
-extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate);
-extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate);
-
-extern struct clk_ops s5p64x0_clkarm_ops;
-
 extern struct clksrc_clk clk_armclk;
 extern struct clksrc_clk clk_dout_mpll;
 
-extern struct clk *clkset_hclk_low_list[];
 extern struct clksrc_sources clkset_hclk_low;
 
 extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable);
diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h
deleted file mode 100644
index cf26e09..0000000
--- a/arch/arm/mach-s5p64x0/include/mach/system.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* linux/arch/arm/mach-s5p64x0/include/mach/system.h
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * S5P64X0 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 247194d..16eca4e 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -170,7 +170,7 @@ static struct clk *clk_src_mout_am_list[] = {
 	[1] = &clk_div_apll2.clk,
 };
 
-struct clksrc_sources clk_src_mout_am = {
+static struct clksrc_sources clk_src_mout_am = {
 	.sources	= clk_src_mout_am_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_mout_am_list),
 };
@@ -212,7 +212,7 @@ static struct clk *clk_src_mout_onenand_list[] = {
 	[1] = &clk_div_d1_bus.clk,
 };
 
-struct clksrc_sources clk_src_mout_onenand = {
+static struct clksrc_sources clk_src_mout_onenand = {
 	.sources	= clk_src_mout_onenand_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_mout_onenand_list),
 };
@@ -756,7 +756,7 @@ static struct clk *clk_src_group1_list[] = {
 	[3] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group1 = {
+static struct clksrc_sources clk_src_group1 = {
 	.sources	= clk_src_group1_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group1_list),
 };
@@ -766,7 +766,7 @@ static struct clk *clk_src_group2_list[] = {
 	[1] = &clk_div_mpll.clk,
 };
 
-struct clksrc_sources clk_src_group2 = {
+static struct clksrc_sources clk_src_group2 = {
 	.sources	= clk_src_group2_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group2_list),
 };
@@ -780,7 +780,7 @@ static struct clk *clk_src_group3_list[] = {
 	[5] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group3 = {
+static struct clksrc_sources clk_src_group3 = {
 	.sources	= clk_src_group3_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group3_list),
 };
@@ -806,7 +806,7 @@ static struct clk *clk_src_group4_list[] = {
 	[5] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group4 = {
+static struct clksrc_sources clk_src_group4 = {
 	.sources	= clk_src_group4_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group4_list),
 };
@@ -831,7 +831,7 @@ static struct clk *clk_src_group5_list[] = {
 	[4] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_group5 = {
+static struct clksrc_sources clk_src_group5 = {
 	.sources	= clk_src_group5_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group5_list),
 };
@@ -854,7 +854,7 @@ static struct clk *clk_src_group6_list[] = {
 	[2] = &clk_div_hdmi.clk,
 };
 
-struct clksrc_sources clk_src_group6 = {
+static struct clksrc_sources clk_src_group6 = {
 	.sources	= clk_src_group6_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group6_list),
 };
@@ -866,7 +866,7 @@ static struct clk *clk_src_group7_list[] = {
 	[3] = &clk_vclk54m,
 };
 
-struct clksrc_sources clk_src_group7 = {
+static struct clksrc_sources clk_src_group7 = {
 	.sources	= clk_src_group7_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_group7_list),
 };
@@ -877,7 +877,7 @@ static struct clk *clk_src_mmc0_list[] = {
 	[2] = &clk_fin_epll,
 };
 
-struct clksrc_sources clk_src_mmc0 = {
+static struct clksrc_sources clk_src_mmc0 = {
 	.sources	= clk_src_mmc0_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_mmc0_list),
 };
@@ -889,7 +889,7 @@ static struct clk *clk_src_mmc12_list[] = {
 	[3] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_mmc12 = {
+static struct clksrc_sources clk_src_mmc12 = {
 	.sources	= clk_src_mmc12_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_mmc12_list),
 };
@@ -901,7 +901,7 @@ static struct clk *clk_src_irda_usb_list[] = {
 	[3] = &clk_mout_hpll.clk,
 };
 
-struct clksrc_sources clk_src_irda_usb = {
+static struct clksrc_sources clk_src_irda_usb = {
 	.sources	= clk_src_irda_usb_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_irda_usb_list),
 };
@@ -912,7 +912,7 @@ static struct clk *clk_src_pwi_list[] = {
 	[2] = &clk_div_mpll.clk,
 };
 
-struct clksrc_sources clk_src_pwi = {
+static struct clksrc_sources clk_src_pwi = {
 	.sources	= clk_src_pwi_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_pwi_list),
 };
@@ -923,7 +923,7 @@ static struct clk *clk_sclk_spdif_list[] = {
 	[2] = &clk_sclk_audio2.clk,
 };
 
-struct clksrc_sources clk_src_sclk_spdif = {
+static struct clksrc_sources clk_src_sclk_spdif = {
 	.sources	= clk_sclk_spdif_list,
 	.nr_sources	= ARRAY_SIZE(clk_sclk_spdif_list),
 };
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index c909573..ff71e2d 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -129,14 +129,6 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
 	}
 };
 
-static void s5pc100_idle(void)
-{
-	if (!need_resched())
-		cpu_do_idle();
-
-	local_irq_enable();
-}
-
 /*
  * s5pc100_map_io
  *
@@ -210,10 +202,6 @@ core_initcall(s5pc100_core_init);
 int __init s5pc100_init(void)
 {
 	printk(KERN_INFO "S5PC100: Initializing architecture\n");
-
-	/* set idle function */
-	pm_idle = s5pc100_idle;
-
 	return device_register(&s5pc100_dev);
 }
 
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index c841f4d3..afd8db2 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -35,7 +35,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 pdma0_peri[] = {
+static u8 pdma0_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
@@ -68,28 +68,15 @@ u8 pdma0_peri[] = {
 	DMACH_HSI_TX,
 };
 
-struct dma_pl330_platdata s5pc100_pdma0_pdata = {
+static struct dma_pl330_platdata s5pc100_pdma0_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
 	.peri_id = pdma0_peri,
 };
 
-struct amba_device s5pc100_device_pdma0 = {
-	.dev = {
-		.init_name = "dma-pl330.0",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &s5pc100_pdma0_pdata,
-	},
-	.res = {
-		.start = S5PC100_PA_PDMA0,
-		.end = S5PC100_PA_PDMA0 + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_PDMA0, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(s5pc100_pdma0,  "dma-pl330.0", 0x00041330,
+	S5PC100_PA_PDMA0, {IRQ_PDMA0}, &s5pc100_pdma0_pdata);
 
-u8 pdma1_peri[] = {
+static u8 pdma1_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
@@ -122,36 +109,23 @@ u8 pdma1_peri[] = {
 	DMACH_MSM_REQ3,
 };
 
-struct dma_pl330_platdata s5pc100_pdma1_pdata = {
+static struct dma_pl330_platdata s5pc100_pdma1_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
 	.peri_id = pdma1_peri,
 };
 
-struct amba_device s5pc100_device_pdma1 = {
-	.dev = {
-		.init_name = "dma-pl330.1",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &s5pc100_pdma1_pdata,
-	},
-	.res = {
-		.start = S5PC100_PA_PDMA1,
-		.end = S5PC100_PA_PDMA1 + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_PDMA1, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(s5pc100_pdma1, "dma-pl330.1", 0x00041330,
+	S5PC100_PA_PDMA1, {IRQ_PDMA1}, &s5pc100_pdma1_pdata);
 
 static int __init s5pc100_dma_init(void)
 {
 	dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask);
-	amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
+	amba_device_register(&s5pc100_pdma0_device, &iomem_resource);
 
 	dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask);
-	amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
+	amba_device_register(&s5pc100_pdma1_device, &iomem_resource);
 
 	return 0;
 }
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
deleted file mode 100644
index afc96c2..0000000
--- a/arch/arm/mach-s5pc100/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* linux/arch/arm/mach-s5pc100/include/mach/system.h
- *
- * Copyright 2009 Samsung Electronics Co.
- *      Byungho Min <bhmin@samsung.com>
- *
- * S5PC100 - system implementation
- *
- * Based on mach-s3c6400/include/mach/system.h
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 9c1bcdc..4c9e902 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -142,14 +142,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
 	}
 };
 
-static void s5pv210_idle(void)
-{
-	if (!need_resched())
-		cpu_do_idle();
-
-	local_irq_enable();
-}
-
 void s5pv210_restart(char mode, const char *cmd)
 {
 	__raw_writel(0x1, S5P_SWRESET);
@@ -247,10 +239,6 @@ core_initcall(s5pv210_core_init);
 int __init s5pv210_init(void)
 {
 	printk(KERN_INFO "S5PV210: Initializing architecture\n");
-
-	/* set idle function */
-	pm_idle = s5pv210_idle;
-
 	return device_register(&s5pv210_dev);
 }
 
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index a6113e0..86ce62f 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -35,7 +35,7 @@
 
 static u64 dma_dmamask = DMA_BIT_MASK(32);
 
-u8 pdma0_peri[] = {
+static u8 pdma0_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
@@ -66,28 +66,15 @@ u8 pdma0_peri[] = {
 	DMACH_SPDIF,
 };
 
-struct dma_pl330_platdata s5pv210_pdma0_pdata = {
+static struct dma_pl330_platdata s5pv210_pdma0_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma0_peri),
 	.peri_id = pdma0_peri,
 };
 
-struct amba_device s5pv210_device_pdma0 = {
-	.dev = {
-		.init_name = "dma-pl330.0",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &s5pv210_pdma0_pdata,
-	},
-	.res = {
-		.start = S5PV210_PA_PDMA0,
-		.end = S5PV210_PA_PDMA0 + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_PDMA0, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(s5pv210_pdma0, "dma-pl330.0", 0x00041330,
+	S5PV210_PA_PDMA0, {IRQ_PDMA0}, &s5pv210_pdma0_pdata);
 
-u8 pdma1_peri[] = {
+static u8 pdma1_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART1_RX,
@@ -122,36 +109,23 @@ u8 pdma1_peri[] = {
 	DMACH_PCM2_TX,
 };
 
-struct dma_pl330_platdata s5pv210_pdma1_pdata = {
+static struct dma_pl330_platdata s5pv210_pdma1_pdata = {
 	.nr_valid_peri = ARRAY_SIZE(pdma1_peri),
 	.peri_id = pdma1_peri,
 };
 
-struct amba_device s5pv210_device_pdma1 = {
-	.dev = {
-		.init_name = "dma-pl330.1",
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &s5pv210_pdma1_pdata,
-	},
-	.res = {
-		.start = S5PV210_PA_PDMA1,
-		.end = S5PV210_PA_PDMA1 + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_PDMA1, NO_IRQ},
-	.periphid = 0x00041330,
-};
+static AMBA_AHB_DEVICE(s5pv210_pdma1, "dma-pl330.1", 0x00041330,
+	S5PV210_PA_PDMA1, {IRQ_PDMA1}, &s5pv210_pdma1_pdata);
 
 static int __init s5pv210_dma_init(void)
 {
 	dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask);
-	amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
+	amba_device_register(&s5pv210_pdma0_device, &iomem_resource);
 
 	dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask);
-	amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
+	amba_device_register(&s5pv210_pdma1_device, &iomem_resource);
 
 	return 0;
 }
diff --git a/arch/arm/mach-s5pv210/include/mach/system.h b/arch/arm/mach-s5pv210/include/mach/system.h
deleted file mode 100644
index bf288ce..0000000
--- a/arch/arm/mach-s5pv210/include/mach/system.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/include/mach/system.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * S5PV210 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 5e734d0..a9ea64e 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -616,6 +616,7 @@ static struct platform_device *aquila_devices[] __initdata = {
 	&s5p_device_fimc0,
 	&s5p_device_fimc1,
 	&s5p_device_fimc2,
+	&s5p_device_fimc_md,
 	&s5pv210_device_iis0,
 	&wm8994_fixed_voltage0,
 	&wm8994_fixed_voltage1,
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index ff91526..2cf5ed7 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -844,7 +844,7 @@ static struct s5p_fimc_isp_info goni_camera_sensors[] = {
 	},
 };
 
-struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
+static struct s5p_platform_fimc goni_fimc_md_platdata __initdata = {
 	.isp_info	= goni_camera_sensors,
 	.num_clients	= ARRAY_SIZE(goni_camera_sensors),
 };
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index dff9ea7..0933c8e 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -140,7 +140,7 @@ static struct dm9000_plat_data smdkv210_dm9000_platdata = {
 	.dev_addr	= { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
 };
 
-struct platform_device smdkv210_dm9000 = {
+static struct platform_device smdkv210_dm9000 = {
 	.name		= "dm9000",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(smdkv210_dm9000_resources),
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index ed7408d..60b97ec 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := clock.o generic.o irq.o dma.o time.o #nmi-oopser.o
+obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o
 obj-m :=
 obj-n :=
 obj-  :=
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 0c4b76a..e708a93 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -15,11 +15,14 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
+#include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -40,13 +43,13 @@
 #include "generic.h"
 
 #define ASSABET_BCR_DB1110 \
-	(ASSABET_BCR_SPK_OFF    | ASSABET_BCR_QMUTE     | \
+	(ASSABET_BCR_SPK_OFF    | \
 	 ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
 	 ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
 	 ASSABET_BCR_IRDA_MD0)
 
 #define ASSABET_BCR_DB1111 \
-	(ASSABET_BCR_SPK_OFF    | ASSABET_BCR_QMUTE     | \
+	(ASSABET_BCR_SPK_OFF    | \
 	 ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
 	 ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
 	 ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
@@ -69,31 +72,10 @@ void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
 
 EXPORT_SYMBOL(ASSABET_BCR_frob);
 
-static void assabet_backlight_power(int on)
-{
-#ifndef ASSABET_PAL_VIDEO
-	if (on)
-		ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
-	else
-#endif
-		ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
-}
-
-/*
- * Turn on/off the backlight.  When turning the backlight on,
- * we wait 500us after turning it on so we don't cause the
- * supplies to droop when we enable the LCD controller (and
- * cause a hard reset.)
- */
-static void assabet_lcd_power(int on)
+static void assabet_ucb1x00_reset(enum ucb1x00_reset state)
 {
-#ifndef ASSABET_PAL_VIDEO
-	if (on) {
-		ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
-		udelay(500);
-	} else
-#endif
-		ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+	if (state == UCB_RST_PROBE)
+		ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
 }
 
 
@@ -152,15 +134,8 @@ static struct flash_platform_data assabet_flash_data = {
 };
 
 static struct resource assabet_flash_resources[] = {
-	{
-		.start	= SA1100_CS0_PHYS,
-		.end	= SA1100_CS0_PHYS + SZ_32M - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= SA1100_CS1_PHYS,
-		.end	= SA1100_CS1_PHYS + SZ_32M - 1,
-		.flags	= IORESOURCE_MEM,
-	}
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+	DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
 };
 
 
@@ -199,18 +174,126 @@ static struct irda_platform_data assabet_irda_data = {
 	.set_speed	= assabet_irda_set_speed,
 };
 
+static struct ucb1x00_plat_data assabet_ucb1x00_data = {
+	.reset		= assabet_ucb1x00_reset,
+	.gpio_base	= -1,
+};
+
 static struct mcp_plat_data assabet_mcp_data = {
 	.mccr0		= MCCR0_ADM,
 	.sclk_rate	= 11981000,
+	.codec_pdata	= &assabet_ucb1x00_data,
+};
+
+static void assabet_lcd_set_visual(u32 visual)
+{
+	u_int is_true_color = visual == FB_VISUAL_TRUECOLOR;
+
+	if (machine_is_assabet()) {
+#if 1		// phase 4 or newer Assabet's
+		if (is_true_color)
+			ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+		else
+			ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+#else
+		// older Assabet's
+		if (is_true_color)
+			ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+		else
+			ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+#endif
+	}
+}
+
+#ifndef ASSABET_PAL_VIDEO
+static void assabet_lcd_backlight_power(int on)
+{
+	if (on)
+		ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
+	else
+		ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+/*
+ * Turn on/off the backlight.  When turning the backlight on, we wait
+ * 500us after turning it on so we don't cause the supplies to droop
+ * when we enable the LCD controller (and cause a hard reset.)
+ */
+static void assabet_lcd_power(int on)
+{
+	if (on) {
+		ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
+		udelay(500);
+	} else
+		ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+/*
+ * The assabet uses a sharp LQ039Q2DS54 LCD module.  It is actually
+ * takes an RGB666 signal, but we provide it with an RGB565 signal
+ * instead (def_rgb_16).
+ */
+static struct sa1100fb_mach_info lq039q2ds54_info = {
+	.pixclock	= 171521,	.bpp		= 16,
+	.xres		= 320,		.yres		= 240,
+
+	.hsync_len	= 5,		.vsync_len	= 1,
+	.left_margin	= 61,		.upper_margin	= 3,
+	.right_margin	= 9,		.lower_margin	= 0,
+
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+	.backlight_power = assabet_lcd_backlight_power,
+	.lcd_power = assabet_lcd_power,
+	.set_visual = assabet_lcd_set_visual,
+};
+#else
+static void assabet_pal_backlight_power(int on)
+{
+	ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+static void assabet_pal_power(int on)
+{
+	ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+static struct sa1100fb_mach_info pal_info = {
+	.pixclock	= 67797,	.bpp		= 16,
+	.xres		= 640,		.yres		= 512,
+
+	.hsync_len	= 64,		.vsync_len	= 6,
+	.left_margin	= 125,		.upper_margin	= 70,
+	.right_margin	= 115,		.lower_margin	= 36,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+
+	.backlight_power = assabet_pal_backlight_power,
+	.lcd_power = assabet_pal_power,
+	.set_visual = assabet_lcd_set_visual,
 };
+#endif
+
+#ifdef CONFIG_ASSABET_NEPONSET
+static struct resource neponset_resources[] = {
+	DEFINE_RES_MEM(0x10000000, 0x08000000),
+	DEFINE_RES_MEM(0x18000000, 0x04000000),
+	DEFINE_RES_MEM(0x40000000, SZ_8K),
+	DEFINE_RES_IRQ(IRQ_GPIO25),
+};
+#endif
 
 static void __init assabet_init(void)
 {
 	/*
 	 * Ensure that the power supply is in "high power" mode.
 	 */
-	GPDR |= GPIO_GPIO16;
 	GPSR = GPIO_GPIO16;
+	GPDR |= GPIO_GPIO16;
 
 	/*
 	 * Ensure that these pins are set as outputs and are driving
@@ -218,8 +301,16 @@ static void __init assabet_init(void)
 	 * the WS latch in the CPLD, and we don't float causing
 	 * excessive power drain.  --rmk
 	 */
-	GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
 	GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+	GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+	/*
+	 * Also set GPIO27 as an output; this is used to clock UART3
+	 * via the FPGA and as otherwise has no pullups or pulldowns,
+	 * so stop it floating.
+	 */
+	GPCR = GPIO_GPIO27;
+	GPDR |= GPIO_GPIO27;
 
 	/*
 	 * Set up registers for sleep mode.
@@ -231,8 +322,7 @@ static void __init assabet_init(void)
 	PPDR |= PPC_TXD3 | PPC_TXD1;
 	PPSR |= PPC_TXD3 | PPC_TXD1;
 
-	sa1100fb_lcd_power = assabet_lcd_power;
-	sa1100fb_backlight_power = assabet_backlight_power;
+	sa11x0_ppc_configure_mcp();
 
 	if (machine_has_neponset()) {
 		/*
@@ -246,9 +336,17 @@ static void __init assabet_init(void)
 #ifndef CONFIG_ASSABET_NEPONSET
 		printk( "Warning: Neponset detected but full support "
 			"hasn't been configured in the kernel\n" );
+#else
+		platform_device_register_simple("neponset", 0,
+			neponset_resources, ARRAY_SIZE(neponset_resources));
 #endif
 	}
 
+#ifndef ASSABET_PAL_VIDEO
+	sa11x0_register_lcd(&lq039q2ds54_info);
+#else
+	sa11x0_register_lcd(&pal_video);
+#endif
 	sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
 			    ARRAY_SIZE(assabet_flash_resources));
 	sa11x0_register_irda(&assabet_irda_data);
@@ -412,21 +510,8 @@ static void __init assabet_map_io(void)
 	 */
 	Ser1SDCR0 |= SDCR0_SUS;
 
-	if (machine_has_neponset()) {
-#ifdef CONFIG_ASSABET_NEPONSET
-		extern void neponset_map_io(void);
-
-		/*
-		 * We map Neponset registers even if it isn't present since
-		 * many drivers will try to probe their stuff (and fail).
-		 * This is still more friendly than a kernel paging request
-		 * crash.
-		 */
-		neponset_map_io();
-#endif
-	} else {
+	if (!machine_has_neponset())
 		sa1100_register_uart_fns(&assabet_port_fns);
-	}
 
 	/*
 	 * When Neponset is attached, the first UART should be
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index b07a2c0..266ec0f 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -39,20 +39,27 @@
 #include "generic.h"
 
 static struct resource sa1111_resources[] = {
-	[0] = {
-		.start		= BADGE4_SA1111_BASE,
-		.end		= BADGE4_SA1111_BASE + 0x00001fff,
-		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= BADGE4_IRQ_GPIO_SA1111,
-		.end		= BADGE4_IRQ_GPIO_SA1111,
-		.flags		= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000),
+	[1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111),
 };
 
+static int badge4_sa1111_enable(void *data, unsigned devid)
+{
+	if (devid == SA1111_DEVID_USB)
+		badge4_set_5V(BADGE4_5V_USB, 1);
+	return 0;
+}
+
+static void badge4_sa1111_disable(void *data, unsigned devid)
+{
+	if (devid == SA1111_DEVID_USB)
+		badge4_set_5V(BADGE4_5V_USB, 0);
+}
+
 static struct sa1111_platform_data sa1111_info = {
-	.irq_base	= IRQ_BOARD_END,
+	.disable_devs	= SA1111_DEVID_PS2_MSE,
+	.enable		= badge4_sa1111_enable,
+	.disable	= badge4_sa1111_disable,
 };
 
 static u64 sa1111_dmamask = 0xffffffffUL;
@@ -121,11 +128,8 @@ static struct flash_platform_data badge4_flash_data = {
 	.nr_parts	= ARRAY_SIZE(badge4_partitions),
 };
 
-static struct resource badge4_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_64M - 1,
-	.flags		= IORESOURCE_MEM,
-};
+static struct resource badge4_flash_resource =
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M);
 
 static int five_v_on __initdata = 0;
 
@@ -269,11 +273,6 @@ static struct map_desc badge4_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(0x10000000),
 		.length		= 0x00100000,
 		.type		= MT_DEVICE
-	}, {	/* SA-1111      */
-		.virtual	= 0xf4000000,
-		.pfn		= __phys_to_pfn(0x48000000),
-		.length		= 0x00100000,
-		.type		= MT_DEVICE
 	}
 };
 
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 11bb6d0..8015604 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -33,11 +33,7 @@
 #include "generic.h"
 
 static struct resource cerfuart2_resources[] = {
-	[0] = {
-		.start	= 0x80030000,
-		.end	= 0x8003ffff,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM(0x80030000, SZ_64K),
 };
 
 static struct platform_device cerfuart2_device = {
@@ -87,11 +83,8 @@ static struct flash_platform_data cerf_flash_data = {
 	.nr_parts	= ARRAY_SIZE(cerf_partitions),
 };
 
-static struct resource cerf_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_32M - 1,
-	.flags		= IORESOURCE_MEM,
-};
+static struct resource cerf_flash_resource =
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 static void __init cerf_init_irq(void)
 {
@@ -128,6 +121,7 @@ static struct mcp_plat_data cerf_mcp_data = {
 
 static void __init cerf_init(void)
 {
+	sa11x0_ppc_configure_mcp();
 	platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
 	sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
 	sa11x0_register_mcp(&cerf_mcp_data);
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index fd56521..d4339d6 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -22,12 +22,15 @@
 #include <linux/tty.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
 #include <linux/gpio.h>
 #include <linux/pda_power.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
@@ -48,11 +51,7 @@
 #include "generic.h"
 
 static struct resource collie_scoop_resources[] = {
-	[0] = {
-		.start		= 0x40800000,
-		.end		= 0x40800fff,
-		.flags		= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
 };
 
 static struct scoop_config collie_scoop_setup = {
@@ -85,10 +84,14 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
 	.num_devs	= 1,
 };
 
+static struct ucb1x00_plat_data collie_ucb1x00_data = {
+	.gpio_base	= COLLIE_TC35143_GPIO_BASE,
+};
+
 static struct mcp_plat_data collie_mcp_data = {
 	.mccr0		= MCCR0_ADM | MCCR0_ExtClk,
 	.sclk_rate	= 9216000,
-	.gpio_base	= COLLIE_TC35143_GPIO_BASE,
+	.codec_pdata	= &collie_ucb1x00_data,
 };
 
 /*
@@ -221,16 +224,8 @@ device_initcall(collie_uart_init);
 
 
 static struct resource locomo_resources[] = {
-	[0] = {
-		.start		= 0x40000000,
-		.end		= 0x40001fff,
-		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= IRQ_GPIO25,
-		.end		= IRQ_GPIO25,
-		.flags		= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
+	[1] = DEFINE_RES_IRQ(IRQ_GPIO25),
 };
 
 static struct locomo_platform_data locomo_info = {
@@ -303,11 +298,21 @@ static struct flash_platform_data collie_flash_data = {
 };
 
 static struct resource collie_flash_resources[] = {
-	{
-		.start	= SA1100_CS0_PHYS,
-		.end	= SA1100_CS0_PHYS + SZ_32M - 1,
-		.flags	= IORESOURCE_MEM,
-	}
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+};
+
+static struct sa1100fb_mach_info collie_lcd_info = {
+	.pixclock	= 171521,	.bpp		= 16,
+	.xres		= 320,		.yres		= 240,
+
+	.hsync_len	= 5,		.vsync_len	= 1,
+	.left_margin	= 11,		.upper_margin	= 2,
+	.right_margin	= 30,		.lower_margin	= 0,
+
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
 };
 
 static void __init collie_init(void)
@@ -341,6 +346,10 @@ static void __init collie_init(void)
 
 	collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN);
 	collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN);
+
+	sa11x0_ppc_configure_mcp();
+
+
 	platform_scoop_config = &collie_pcmcia_config;
 
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
@@ -348,6 +357,7 @@ static void __init collie_init(void)
 		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
 	}
 
+	sa11x0_register_lcd(&collie_lcd_info);
 	sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
 			    ARRAY_SIZE(collie_flash_resources));
 	sa11x0_register_mcp(&collie_mcp_data);
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
deleted file mode 100644
index ad66035..0000000
--- a/arch/arm/mach-sa1100/dma.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * arch/arm/mach-sa1100/dma.c
- *
- * Support functions for the SA11x0 internal DMA channels.
- *
- * Copyright (C) 2000, 2001 by Nicolas Pitre
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-
-
-#undef DEBUG
-#ifdef DEBUG
-#define DPRINTK( s, arg... )  printk( "dma<%p>: " s, regs , ##arg )
-#else
-#define DPRINTK( x... )
-#endif
-
-
-typedef struct {
-	const char *device_id;		/* device name */
-	u_long device;			/* this channel device, 0  if unused*/
-	dma_callback_t callback;	/* to call when DMA completes */
-	void *data;			/* ... with private data ptr */
-} sa1100_dma_t;
-
-static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
-
-static DEFINE_SPINLOCK(dma_list_lock);
-
-
-static irqreturn_t dma_irq_handler(int irq, void *dev_id)
-{
-	dma_regs_t *dma_regs = dev_id;
-	sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
-	int status = dma_regs->RdDCSR;
-
-	if (status & (DCSR_ERROR)) {
-		printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id);
-		dma_regs->ClrDCSR = DCSR_ERROR;
-	}
-
-	dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
-	if (dma->callback) {
-		if (status & DCSR_DONEA)
-			dma->callback(dma->data);
-		if (status & DCSR_DONEB)
-			dma->callback(dma->data);
-	}
-	return IRQ_HANDLED;
-}
-
-
-/**
- *	sa1100_request_dma - allocate one of the SA11x0's DMA channels
- *	@device: The SA11x0 peripheral targeted by this request
- *	@device_id: An ascii name for the claiming device
- *	@callback: Function to be called when the DMA completes
- *	@data: A cookie passed back to the callback function
- *	@dma_regs: Pointer to the location of the allocated channel's identifier
- *
- * 	This function will search for a free DMA channel and returns the
- * 	address of the hardware registers for that channel as the channel
- * 	identifier. This identifier is written to the location pointed by
- * 	@dma_regs. The list of possible values for @device are listed into
- * 	arch/arm/mach-sa1100/include/mach/dma.h as a dma_device_t enum.
- *
- * 	Note that reading from a port and writing to the same port are
- * 	actually considered as two different streams requiring separate
- * 	DMA registrations.
- *
- * 	The @callback function is called from interrupt context when one
- * 	of the two possible DMA buffers in flight has terminated. That
- * 	function has to be small and efficient while posponing more complex
- * 	processing to a lower priority execution context.
- *
- * 	If no channels are available, or if the desired @device is already in
- * 	use by another DMA channel, then an error code is returned.  This
- * 	function must be called before any other DMA calls.
- **/
-
-int sa1100_request_dma (dma_device_t device, const char *device_id,
-			dma_callback_t callback, void *data,
-			dma_regs_t **dma_regs)
-{
-	sa1100_dma_t *dma = NULL;
-	dma_regs_t *regs;
-	int i, err;
-
-	*dma_regs = NULL;
-
-	err = 0;
-	spin_lock(&dma_list_lock);
-	for (i = 0; i < SA1100_DMA_CHANNELS; i++) {
-		if (dma_chan[i].device == device) {
-			err = -EBUSY;
-			break;
-		} else if (!dma_chan[i].device && !dma) {
-			dma = &dma_chan[i];
-		}
-	}
-	if (!err) {
-		if (dma)
-			dma->device = device;
-		else
-			err = -ENOSR;
-	}
-	spin_unlock(&dma_list_lock);
-	if (err)
-		return err;
-
-	i = dma - dma_chan;
-	regs = (dma_regs_t *)&DDAR(i);
-	err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED,
-			  device_id, regs);
-	if (err) {
-		printk(KERN_ERR
-		       "%s: unable to request IRQ %d for %s\n",
-		       __func__, IRQ_DMA0 + i, device_id);
-		dma->device = 0;
-		return err;
-	}
-
-	*dma_regs = regs;
-	dma->device_id = device_id;
-	dma->callback = callback;
-	dma->data = data;
-
-	regs->ClrDCSR =
-		(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
-		 DCSR_IE | DCSR_ERROR | DCSR_RUN);
-	regs->DDAR = device;
-
-	return 0;
-}
-
-
-/**
- * 	sa1100_free_dma - free a SA11x0 DMA channel
- * 	@regs: identifier for the channel to free
- *
- * 	This clears all activities on a given DMA channel and releases it
- * 	for future requests.  The @regs identifier is provided by a
- * 	successful call to sa1100_request_dma().
- **/
-
-void sa1100_free_dma(dma_regs_t *regs)
-{
-	int i;
-
-	for (i = 0; i < SA1100_DMA_CHANNELS; i++)
-		if (regs == (dma_regs_t *)&DDAR(i))
-			break;
-	if (i >= SA1100_DMA_CHANNELS) {
-		printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
-		return;
-	}
-
-	if (!dma_chan[i].device) {
-		printk(KERN_ERR "%s: Trying to free free DMA\n", __func__);
-		return;
-	}
-
-	regs->ClrDCSR =
-		(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
-		 DCSR_IE | DCSR_ERROR | DCSR_RUN);
-	free_irq(IRQ_DMA0 + i, regs);
-	dma_chan[i].device = 0;
-}
-
-
-/**
- * 	sa1100_start_dma - submit a data buffer for DMA
- * 	@regs: identifier for the channel to use
- * 	@dma_ptr: buffer physical (or bus) start address
- * 	@size: buffer size
- *
- * 	This function hands the given data buffer to the hardware for DMA
- * 	access. If another buffer is already in flight then this buffer
- * 	will be queued so the DMA engine will switch to it automatically
- * 	when the previous one is done.  The DMA engine is actually toggling
- * 	between two buffers so at most 2 successful calls can be made before
- * 	one of them terminates and the callback function is called.
- *
- * 	The @regs identifier is provided by a successful call to
- * 	sa1100_request_dma().
- *
- * 	The @size must not be larger than %MAX_DMA_SIZE.  If a given buffer
- * 	is larger than that then it's the caller's responsibility to split
- * 	it into smaller chunks and submit them separately. If this is the
- * 	case then a @size of %CUT_DMA_SIZE is recommended to avoid ending
- * 	up with too small chunks. The callback function can be used to chain
- * 	submissions of buffer chunks.
- *
- * 	Error return values:
- * 	%-EOVERFLOW:	Given buffer size is too big.
- * 	%-EBUSY:	Both DMA buffers are already in use.
- * 	%-EAGAIN:	Both buffers were busy but one of them just completed
- * 			but the interrupt handler has to execute first.
- *
- * 	This function returs 0 on success.
- **/
-
-int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size)
-{
-	unsigned long flags;
-	u_long status;
-	int ret;
-
-	if (dma_ptr & 3)
-		printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n",
-		       (unsigned long)dma_ptr);
-
-	if (size > MAX_DMA_SIZE)
-		return -EOVERFLOW;
-
-	local_irq_save(flags);
-	status = regs->RdDCSR;
-
-	/* If both DMA buffers are started, there's nothing else we can do. */
-	if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
-		DPRINTK("start: st %#x busy\n", status);
-		ret = -EBUSY;
-		goto out;
-	}
-
-	if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
-	    (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
-		if (status & DCSR_DONEA) {
-			/* give a chance for the interrupt to be processed */
-			ret = -EAGAIN;
-			goto out;
-		}
-		regs->DBSA = dma_ptr;
-		regs->DBTA = size;
-		regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
-		DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
-	} else {
-		if (status & DCSR_DONEB) {
-			/* give a chance for the interrupt to be processed */
-			ret = -EAGAIN;
-			goto out;
-		}
-		regs->DBSB = dma_ptr;
-		regs->DBTB = size;
-		regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
-		DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size);
-	}
-	ret = 0;
-
-out:
-	local_irq_restore(flags);
-	return ret;
-}
-
-
-/**
- * 	sa1100_get_dma_pos - return current DMA position
- * 	@regs: identifier for the channel to use
- *
- * 	This function returns the current physical (or bus) address for the
- * 	given DMA channel.  If the channel is running i.e. not in a stopped
- * 	state then the caller must disable interrupts prior calling this
- * 	function and process the returned value before re-enabling them to
- * 	prevent races with the completion interrupt handler and the callback
- * 	function. The validation of the returned value is the caller's
- * 	responsibility as well -- the hardware seems to return out of range
- * 	values when the DMA engine completes a buffer.
- *
- * 	The @regs identifier is provided by a successful call to
- * 	sa1100_request_dma().
- **/
-
-dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs)
-{
-	int status;
-
-	/*
-	 * We must determine whether buffer A or B is active.
-	 * Two possibilities: either we are in the middle of
-	 * a buffer, or the DMA controller just switched to the
-	 * next toggle but the interrupt hasn't been serviced yet.
-	 * The former case is straight forward.  In the later case,
-	 * we'll do like if DMA is just at the end of the previous
-	 * toggle since all registers haven't been reset yet.
-	 * This goes around the edge case and since we're always
-	 * a little behind anyways it shouldn't make a big difference.
-	 * If DMA has been stopped prior calling this then the
-	 * position is exact.
-	 */
-	status = regs->RdDCSR;
-	if ((!(status & DCSR_BIU) &&  (status & DCSR_STRTA)) ||
-	    ( (status & DCSR_BIU) && !(status & DCSR_STRTB)))
-		return regs->DBSA;
-	else
-		return regs->DBSB;
-}
-
-
-/**
- * 	sa1100_reset_dma - reset a DMA channel
- * 	@regs: identifier for the channel to use
- *
- * 	This function resets and reconfigure the given DMA channel. This is
- * 	particularly useful after a sleep/wakeup event.
- *
- * 	The @regs identifier is provided by a successful call to
- * 	sa1100_request_dma().
- **/
-
-void sa1100_reset_dma(dma_regs_t *regs)
-{
-	int i;
-
-	for (i = 0; i < SA1100_DMA_CHANNELS; i++)
-		if (regs == (dma_regs_t *)&DDAR(i))
-			break;
-	if (i >= SA1100_DMA_CHANNELS) {
-		printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
-		return;
-	}
-
-	regs->ClrDCSR =
-		(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
-		 DCSR_IE | DCSR_ERROR | DCSR_RUN);
-	regs->DDAR = dma_chan[i].device;
-}
-
-
-EXPORT_SYMBOL(sa1100_request_dma);
-EXPORT_SYMBOL(sa1100_free_dma);
-EXPORT_SYMBOL(sa1100_start_dma);
-EXPORT_SYMBOL(sa1100_get_dma_pos);
-EXPORT_SYMBOL(sa1100_reset_dma);
-
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index bb10ee2..97e9bdf 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -14,11 +14,14 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/pm.h>
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 
+#include <video/sa1100fb.h>
+
 #include <asm/div64.h>
 #include <mach/hardware.h>
 #include <asm/system.h>
@@ -149,16 +152,8 @@ static void sa11x0_register_device(struct platform_device *dev, void *data)
 
 
 static struct resource sa11x0udc_resources[] = {
-	[0] = {
-		.start	= __PREG(Ser0UDCCR),
-		.end	= __PREG(Ser0UDCCR) + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_Ser0UDC,
-		.end	= IRQ_Ser0UDC,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K),
+	[1] = DEFINE_RES_IRQ(IRQ_Ser0UDC),
 };
 
 static u64 sa11x0udc_dma_mask = 0xffffffffUL;
@@ -175,16 +170,8 @@ static struct platform_device sa11x0udc_device = {
 };
 
 static struct resource sa11x0uart1_resources[] = {
-	[0] = {
-		.start	= __PREG(Ser1UTCR0),
-		.end	= __PREG(Ser1UTCR0) + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_Ser1UART,
-		.end	= IRQ_Ser1UART,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K),
+	[1] = DEFINE_RES_IRQ(IRQ_Ser1UART),
 };
 
 static struct platform_device sa11x0uart1_device = {
@@ -195,16 +182,8 @@ static struct platform_device sa11x0uart1_device = {
 };
 
 static struct resource sa11x0uart3_resources[] = {
-	[0] = {
-		.start	= __PREG(Ser3UTCR0),
-		.end	= __PREG(Ser3UTCR0) + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_Ser3UART,
-		.end	= IRQ_Ser3UART,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K),
+	[1] = DEFINE_RES_IRQ(IRQ_Ser3UART),
 };
 
 static struct platform_device sa11x0uart3_device = {
@@ -215,16 +194,9 @@ static struct platform_device sa11x0uart3_device = {
 };
 
 static struct resource sa11x0mcp_resources[] = {
-	[0] = {
-		.start	= __PREG(Ser4MCCR0),
-		.end	= __PREG(Ser4MCCR0) + 0xffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_Ser4MCP,
-		.end	= IRQ_Ser4MCP,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
+	[1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
+	[2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
 };
 
 static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
@@ -240,22 +212,24 @@ static struct platform_device sa11x0mcp_device = {
 	.resource	= sa11x0mcp_resources,
 };
 
+void __init sa11x0_ppc_configure_mcp(void)
+{
+	/* Setup the PPC unit for the MCP */
+	PPDR &= ~PPC_RXD4;
+	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+	PSDR |= PPC_RXD4;
+	PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
 void sa11x0_register_mcp(struct mcp_plat_data *data)
 {
 	sa11x0_register_device(&sa11x0mcp_device, data);
 }
 
 static struct resource sa11x0ssp_resources[] = {
-	[0] = {
-		.start	= 0x80070000,
-		.end	= 0x8007ffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_Ser4SSP,
-		.end	= IRQ_Ser4SSP,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(0x80070000, SZ_64K),
+	[1] = DEFINE_RES_IRQ(IRQ_Ser4SSP),
 };
 
 static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
@@ -272,16 +246,8 @@ static struct platform_device sa11x0ssp_device = {
 };
 
 static struct resource sa11x0fb_resources[] = {
-	[0] = {
-		.start	= 0xb0100000,
-		.end	= 0xb010ffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_LCD,
-		.end	= IRQ_LCD,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(0xb0100000, SZ_64K),
+	[1] = DEFINE_RES_IRQ(IRQ_LCD),
 };
 
 static struct platform_device sa11x0fb_device = {
@@ -294,6 +260,11 @@ static struct platform_device sa11x0fb_device = {
 	.resource	= sa11x0fb_resources,
 };
 
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
+{
+	sa11x0_register_device(&sa11x0fb_device, inf);
+}
+
 static struct platform_device sa11x0pcmcia_device = {
 	.name		= "sa11x0-pcmcia",
 	.id		= -1,
@@ -314,23 +285,10 @@ void sa11x0_register_mtd(struct flash_platform_data *flash,
 }
 
 static struct resource sa11x0ir_resources[] = {
-	{
-		.start	= __PREG(Ser2UTCR0),
-		.end	= __PREG(Ser2UTCR0) + 0x24 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= __PREG(Ser2HSCR0),
-		.end	= __PREG(Ser2HSCR0) + 0x1c - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= __PREG(Ser2HSCR2),
-		.end	= __PREG(Ser2HSCR2) + 0x04 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_Ser2ICP,
-		.end	= IRQ_Ser2ICP,
-		.flags	= IORESOURCE_IRQ,
-	}
+	DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24),
+	DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c),
+	DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04),
+	DEFINE_RES_IRQ(IRQ_Ser2ICP),
 };
 
 static struct platform_device sa11x0ir_device = {
@@ -350,14 +308,37 @@ static struct platform_device sa11x0rtc_device = {
 	.id		= -1,
 };
 
+static struct resource sa11x0dma_resources[] = {
+	DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE),
+	DEFINE_RES_IRQ(IRQ_DMA0),
+	DEFINE_RES_IRQ(IRQ_DMA1),
+	DEFINE_RES_IRQ(IRQ_DMA2),
+	DEFINE_RES_IRQ(IRQ_DMA3),
+	DEFINE_RES_IRQ(IRQ_DMA4),
+	DEFINE_RES_IRQ(IRQ_DMA5),
+};
+
+static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device sa11x0dma_device = {
+	.name		= "sa11x0-dma",
+	.id		= -1,
+	.dev = {
+		.dma_mask = &sa11x0dma_dma_mask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(sa11x0dma_resources),
+	.resource	= sa11x0dma_resources,
+};
+
 static struct platform_device *sa11x0_devices[] __initdata = {
 	&sa11x0udc_device,
 	&sa11x0uart1_device,
 	&sa11x0uart3_device,
 	&sa11x0ssp_device,
 	&sa11x0pcmcia_device,
-	&sa11x0fb_device,
 	&sa11x0rtc_device,
+	&sa11x0dma_device,
 };
 
 static int __init sa1100_init(void)
@@ -368,12 +349,6 @@ static int __init sa1100_init(void)
 
 arch_initcall(sa1100_init);
 
-void (*sa1100fb_backlight_power)(int on);
-void (*sa1100fb_lcd_power)(int on);
-
-EXPORT_SYMBOL(sa1100fb_backlight_power);
-EXPORT_SYMBOL(sa1100fb_lcd_power);
-
 
 /*
  * Common I/O mapping:
@@ -428,7 +403,7 @@ void __init sa1100_map_io(void)
  * the MBGNT signal false to ensure the SA1111 doesn't own the
  * SDRAM bus.
  */
-void __init sa1110_mb_disable(void)
+void sa1110_mb_disable(void)
 {
 	unsigned long flags;
 
@@ -447,7 +422,7 @@ void __init sa1110_mb_disable(void)
  * If the system is going to use the SA-1111 DMA engines, set up
  * the memory bus request/grant pins.
  */
-void __devinit sa1110_mb_enable(void)
+void sa1110_mb_enable(void)
 {
 	unsigned long flags;
 
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 33268cf..9eb3b3c 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -16,9 +16,6 @@ extern void sa11x0_restart(char, const char *);
 	mi->bank[__nr].start = (__start), \
 	mi->bank[__nr].size = (__size)
 
-extern void (*sa1100fb_backlight_power)(int on);
-extern void (*sa1100fb_lcd_power)(int on);
-
 extern void sa1110_mb_enable(void);
 extern void sa1110_mb_disable(void);
 
@@ -39,4 +36,8 @@ struct irda_platform_data;
 void sa11x0_register_irda(struct irda_platform_data *irda);
 
 struct mcp_plat_data;
+void sa11x0_ppc_configure_mcp(void);
 void sa11x0_register_mcp(struct mcp_plat_data *data);
+
+struct sa1100fb_mach_info;
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index 1e6b3c1..f23e7d0 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -14,6 +14,8 @@
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 
+#include <video/sa1100fb.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irda.h>
@@ -36,13 +38,28 @@ static void h3100_lcd_power(int enable)
 	}
 }
 
+static struct sa1100fb_mach_info h3100_lcd_info = {
+	.pixclock	= 406977, 	.bpp		= 4,
+	.xres		= 320,		.yres		= 240,
+
+	.hsync_len	= 26,		.vsync_len	= 41,
+	.left_margin	= 4,		.upper_margin	= 0,
+	.right_margin	= 4,		.lower_margin	= 0,
+
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	.cmap_greyscale	= 1,
+	.cmap_inverse	= 1,
+
+	.lccr0		= LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+	.lcd_power = h3100_lcd_power,
+};
 
 static void __init h3100_map_io(void)
 {
 	h3xxx_map_io();
 
-	sa1100fb_lcd_power = h3100_lcd_power;
-
 	/* Older bootldrs put GPIO2-9 in alternate mode on the
 	   assumption that they are used for video */
 	GAFR &= ~0x000001fb;
@@ -80,6 +97,8 @@ static void __init h3100_mach_init(void)
 {
 	h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
 	h3xxx_mach_init();
+
+	sa11x0_register_lcd(&h3100_lcd_info);
 	sa11x0_register_irda(&h3100_irda_data);
 }
 
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 6b58e74..2feac56 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -14,6 +14,8 @@
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 
+#include <video/sa1100fb.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irda.h>
@@ -56,11 +58,35 @@ err2:	gpio_free(H3XXX_EGPIO_LCD_ON);
 err1:	return;
 }
 
+static const struct sa1100fb_rgb h3600_rgb_16 = {
+	.red	= { .offset = 12, .length = 4, },
+	.green	= { .offset = 7,  .length = 4, },
+	.blue	= { .offset = 1,  .length = 4, },
+	.transp	= { .offset = 0,  .length = 0, },
+};
+
+static struct sa1100fb_mach_info h3600_lcd_info = {
+	.pixclock	= 174757, 	.bpp		= 16,
+	.xres		= 320,		.yres		= 240,
+
+	.hsync_len	= 3,		.vsync_len	= 3,
+	.left_margin	= 12,		.upper_margin	= 10,
+	.right_margin	= 17,		.lower_margin	= 1,
+
+	.cmap_static	= 1,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+	.rgb[RGB_16] = &h3600_rgb_16,
+
+	.lcd_power = h3600_lcd_power,
+};
+
+
 static void __init h3600_map_io(void)
 {
 	h3xxx_map_io();
-
-	sa1100fb_lcd_power = h3600_lcd_power;
 }
 
 /*
@@ -121,6 +147,8 @@ static void __init h3600_mach_init(void)
 {
 	h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
 	h3xxx_mach_init();
+
+	sa11x0_register_lcd(&h3600_lcd_info);
 	sa11x0_register_irda(&h3600_irda_data);
 }
 
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
index b0784c9..63150e1 100644
--- a/arch/arm/mach-sa1100/h3xxx.c
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -109,11 +109,8 @@ static struct flash_platform_data h3xxx_flash_data = {
 	.nr_parts	= ARRAY_SIZE(h3xxx_partitions),
 };
 
-static struct resource h3xxx_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_32M - 1,
-	.flags		= IORESOURCE_MEM,
-};
+static struct resource h3xxx_flash_resource =
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 
 /*
@@ -186,11 +183,7 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = {
  */
 
 static struct resource egpio_resources[] = {
-	[0] = {
-		.start	= H3600_EGPIO_PHYS,
-		.end	= H3600_EGPIO_PHYS + 0x4 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4),
 };
 
 static struct htc_egpio_chip egpio_chips[] = {
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index c01bb36..37d381a 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -179,11 +179,8 @@ static struct flash_platform_data hackkit_flash_data = {
 	.nr_parts	= ARRAY_SIZE(hackkit_partitions),
 };
 
-static struct resource hackkit_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_32M,
-	.flags		= IORESOURCE_MEM,
-};
+static struct resource hackkit_flash_resource =
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 static void __init hackkit_init(void)
 {
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h
index bae8296..3f2d1b6 100644
--- a/arch/arm/mach-sa1100/include/mach/SA-1100.h
+++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h
@@ -1590,224 +1590,9 @@
 
 /*
  * Direct Memory Access (DMA) control registers
- *
- * Registers
- *    DDAR0     	Direct Memory Access (DMA) Device Address Register
- *              	channel 0 (read/write).
- *    DCSR0     	Direct Memory Access (DMA) Control and Status
- *              	Register channel 0 (read/write).
- *    DBSA0     	Direct Memory Access (DMA) Buffer Start address
- *              	register A channel 0 (read/write).
- *    DBTA0     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register A channel 0 (read/write).
- *    DBSB0     	Direct Memory Access (DMA) Buffer Start address
- *              	register B channel 0 (read/write).
- *    DBTB0     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register B channel 0 (read/write).
- *
- *    DDAR1     	Direct Memory Access (DMA) Device Address Register
- *              	channel 1 (read/write).
- *    DCSR1     	Direct Memory Access (DMA) Control and Status
- *              	Register channel 1 (read/write).
- *    DBSA1     	Direct Memory Access (DMA) Buffer Start address
- *              	register A channel 1 (read/write).
- *    DBTA1     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register A channel 1 (read/write).
- *    DBSB1     	Direct Memory Access (DMA) Buffer Start address
- *              	register B channel 1 (read/write).
- *    DBTB1     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register B channel 1 (read/write).
- *
- *    DDAR2     	Direct Memory Access (DMA) Device Address Register
- *              	channel 2 (read/write).
- *    DCSR2     	Direct Memory Access (DMA) Control and Status
- *              	Register channel 2 (read/write).
- *    DBSA2     	Direct Memory Access (DMA) Buffer Start address
- *              	register A channel 2 (read/write).
- *    DBTA2     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register A channel 2 (read/write).
- *    DBSB2     	Direct Memory Access (DMA) Buffer Start address
- *              	register B channel 2 (read/write).
- *    DBTB2     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register B channel 2 (read/write).
- *
- *    DDAR3     	Direct Memory Access (DMA) Device Address Register
- *              	channel 3 (read/write).
- *    DCSR3     	Direct Memory Access (DMA) Control and Status
- *              	Register channel 3 (read/write).
- *    DBSA3     	Direct Memory Access (DMA) Buffer Start address
- *              	register A channel 3 (read/write).
- *    DBTA3     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register A channel 3 (read/write).
- *    DBSB3     	Direct Memory Access (DMA) Buffer Start address
- *              	register B channel 3 (read/write).
- *    DBTB3     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register B channel 3 (read/write).
- *
- *    DDAR4     	Direct Memory Access (DMA) Device Address Register
- *              	channel 4 (read/write).
- *    DCSR4     	Direct Memory Access (DMA) Control and Status
- *              	Register channel 4 (read/write).
- *    DBSA4     	Direct Memory Access (DMA) Buffer Start address
- *              	register A channel 4 (read/write).
- *    DBTA4     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register A channel 4 (read/write).
- *    DBSB4     	Direct Memory Access (DMA) Buffer Start address
- *              	register B channel 4 (read/write).
- *    DBTB4     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register B channel 4 (read/write).
- *
- *    DDAR5     	Direct Memory Access (DMA) Device Address Register
- *              	channel 5 (read/write).
- *    DCSR5     	Direct Memory Access (DMA) Control and Status
- *              	Register channel 5 (read/write).
- *    DBSA5     	Direct Memory Access (DMA) Buffer Start address
- *              	register A channel 5 (read/write).
- *    DBTA5     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register A channel 5 (read/write).
- *    DBSB5     	Direct Memory Access (DMA) Buffer Start address
- *              	register B channel 5 (read/write).
- *    DBTB5     	Direct Memory Access (DMA) Buffer Transfer count
- *              	register B channel 5 (read/write).
  */
-
-#define DMASp   	0x00000020	/* DMA control reg. Space [byte]   */
-
-#define DDAR(Nb)	__REG(0xB0000000 + (Nb)*DMASp)  /* DMA Device Address Reg. channel [0..5] */
-#define SetDCSR(Nb)	__REG(0xB0000004 + (Nb)*DMASp)  /* Set DMA Control & Status Reg. channel [0..5] (write) */
-#define ClrDCSR(Nb)	__REG(0xB0000008 + (Nb)*DMASp)  /* Clear DMA Control & Status Reg. channel [0..5] (write) */
-#define RdDCSR(Nb)	__REG(0xB000000C + (Nb)*DMASp)  /* Read DMA Control & Status Reg. channel [0..5] (read) */
-#define DBSA(Nb)	__REG(0xB0000010 + (Nb)*DMASp)  /* DMA Buffer Start address reg. A channel [0..5] */
-#define DBTA(Nb)	__REG(0xB0000014 + (Nb)*DMASp)  /* DMA Buffer Transfer count reg. A channel [0..5] */
-#define DBSB(Nb)	__REG(0xB0000018 + (Nb)*DMASp)  /* DMA Buffer Start address reg. B channel [0..5] */
-#define DBTB(Nb)	__REG(0xB000001C + (Nb)*DMASp)  /* DMA Buffer Transfer count reg. B channel [0..5] */
-
-#define DDAR_RW 	0x00000001	/* device data Read/Write          */
-#define DDAR_DevWr	(DDAR_RW*0)	/*  Device data Write              */
-                	        	/*  (memory -> device)             */
-#define DDAR_DevRd	(DDAR_RW*1)	/*  Device data Read               */
-                	        	/*  (device -> memory)             */
-#define DDAR_E  	0x00000002	/* big/little Endian device        */
-#define DDAR_LtlEnd	(DDAR_E*0)	/*  Little Endian device           */
-#define DDAR_BigEnd	(DDAR_E*1)	/*  Big Endian device              */
-#define DDAR_BS 	0x00000004	/* device Burst Size               */
-#define DDAR_Brst4	(DDAR_BS*0)	/*  Burst-of-4 device              */
-#define DDAR_Brst8	(DDAR_BS*1)	/*  Burst-of-8 device              */
-#define DDAR_DW 	0x00000008	/* device Data Width               */
-#define DDAR_8BitDev	(DDAR_DW*0)	/*  8-Bit Device                   */
-#define DDAR_16BitDev	(DDAR_DW*1)	/*  16-Bit Device                  */
-#define DDAR_DS 	Fld (4, 4)	/* Device Select                   */
-#define DDAR_Ser0UDCTr	        	/*  Ser. port 0 UDC Transmit       */ \
-                	(0x0 << FShft (DDAR_DS))
-#define DDAR_Ser0UDCRc	        	/*  Ser. port 0 UDC Receive        */ \
-                	(0x1 << FShft (DDAR_DS))
-#define DDAR_Ser1SDLCTr	        	/*  Ser. port 1 SDLC Transmit      */ \
-                	(0x2 << FShft (DDAR_DS))
-#define DDAR_Ser1SDLCRc	        	/*  Ser. port 1 SDLC Receive       */ \
-                	(0x3 << FShft (DDAR_DS))
-#define DDAR_Ser1UARTTr	        	/*  Ser. port 1 UART Transmit      */ \
-                	(0x4 << FShft (DDAR_DS))
-#define DDAR_Ser1UARTRc	        	/*  Ser. port 1 UART Receive       */ \
-                	(0x5 << FShft (DDAR_DS))
-#define DDAR_Ser2ICPTr	        	/*  Ser. port 2 ICP Transmit       */ \
-                	(0x6 << FShft (DDAR_DS))
-#define DDAR_Ser2ICPRc	        	/*  Ser. port 2 ICP Receive        */ \
-                	(0x7 << FShft (DDAR_DS))
-#define DDAR_Ser3UARTTr	        	/*  Ser. port 3 UART Transmit      */ \
-                	(0x8 << FShft (DDAR_DS))
-#define DDAR_Ser3UARTRc	        	/*  Ser. port 3 UART Receive       */ \
-                	(0x9 << FShft (DDAR_DS))
-#define DDAR_Ser4MCP0Tr	        	/*  Ser. port 4 MCP 0 Transmit     */ \
-                	        	/*  (audio)                        */ \
-                	(0xA << FShft (DDAR_DS))
-#define DDAR_Ser4MCP0Rc	        	/*  Ser. port 4 MCP 0 Receive      */ \
-                	        	/*  (audio)                        */ \
-                	(0xB << FShft (DDAR_DS))
-#define DDAR_Ser4MCP1Tr	        	/*  Ser. port 4 MCP 1 Transmit     */ \
-                	        	/*  (telecom)                      */ \
-                	(0xC << FShft (DDAR_DS))
-#define DDAR_Ser4MCP1Rc	        	/*  Ser. port 4 MCP 1 Receive      */ \
-                	        	/*  (telecom)                      */ \
-                	(0xD << FShft (DDAR_DS))
-#define DDAR_Ser4SSPTr	        	/*  Ser. port 4 SSP Transmit       */ \
-                	(0xE << FShft (DDAR_DS))
-#define DDAR_Ser4SSPRc	        	/*  Ser. port 4 SSP Receive        */ \
-                	(0xF << FShft (DDAR_DS))
-#define DDAR_DA 	Fld (24, 8)	/* Device Address                  */
-#define DDAR_DevAdd(Add)        	/*  Device Address                 */ \
-                	(((Add) & 0xF0000000) | \
-                	 (((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2)))
-#define DDAR_Ser0UDCWr	        	/* Ser. port 0 UDC Write           */ \
-                	(DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
-                	 DDAR_Ser0UDCTr + DDAR_DevAdd (__PREG(Ser0UDCDR)))
-#define DDAR_Ser0UDCRd	        	/* Ser. port 0 UDC Read            */ \
-                	(DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
-                	 DDAR_Ser0UDCRc + DDAR_DevAdd (__PREG(Ser0UDCDR)))
-#define DDAR_Ser1UARTWr	        	/* Ser. port 1 UART Write          */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser1UARTTr + DDAR_DevAdd (__PREG(Ser1UTDR)))
-#define DDAR_Ser1UARTRd	        	/* Ser. port 1 UART Read           */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser1UARTRc + DDAR_DevAdd (__PREG(Ser1UTDR)))
-#define DDAR_Ser1SDLCWr	        	/* Ser. port 1 SDLC Write          */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser1SDLCTr + DDAR_DevAdd (__PREG(Ser1SDDR)))
-#define DDAR_Ser1SDLCRd	        	/* Ser. port 1 SDLC Read           */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser1SDLCRc + DDAR_DevAdd (__PREG(Ser1SDDR)))
-#define DDAR_Ser2UARTWr	        	/* Ser. port 2 UART Write          */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2UTDR)))
-#define DDAR_Ser2UARTRd	        	/* Ser. port 2 UART Read           */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2UTDR)))
-#define DDAR_Ser2HSSPWr	        	/* Ser. port 2 HSSP Write          */ \
-                	(DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
-                	 DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2HSDR)))
-#define DDAR_Ser2HSSPRd	        	/* Ser. port 2 HSSP Read           */ \
-                	(DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
-                	 DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2HSDR)))
-#define DDAR_Ser3UARTWr	        	/* Ser. port 3 UART Write          */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser3UARTTr + DDAR_DevAdd (__PREG(Ser3UTDR)))
-#define DDAR_Ser3UARTRd	        	/* Ser. port 3 UART Read           */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
-                	 DDAR_Ser3UARTRc + DDAR_DevAdd (__PREG(Ser3UTDR)))
-#define DDAR_Ser4MCP0Wr	        	/* Ser. port 4 MCP 0 Write (audio) */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
-                	 DDAR_Ser4MCP0Tr + DDAR_DevAdd (__PREG(Ser4MCDR0)))
-#define DDAR_Ser4MCP0Rd	        	/* Ser. port 4 MCP 0 Read (audio)  */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
-                	 DDAR_Ser4MCP0Rc + DDAR_DevAdd (__PREG(Ser4MCDR0)))
-#define DDAR_Ser4MCP1Wr	        	/* Ser. port 4 MCP 1 Write         */ \
-                	        	/* (telecom)                       */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
-                	 DDAR_Ser4MCP1Tr + DDAR_DevAdd (__PREG(Ser4MCDR1)))
-#define DDAR_Ser4MCP1Rd	        	/* Ser. port 4 MCP 1 Read          */ \
-                	        	/* (telecom)                       */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
-                	 DDAR_Ser4MCP1Rc + DDAR_DevAdd (__PREG(Ser4MCDR1)))
-#define DDAR_Ser4SSPWr	        	/* Ser. port 4 SSP Write (16 bits) */ \
-                	(DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
-                	 DDAR_Ser4SSPTr + DDAR_DevAdd (__PREG(Ser4SSDR)))
-#define DDAR_Ser4SSPRd	        	/* Ser. port 4 SSP Read (16 bits)  */ \
-                	(DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
-                	 DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR)))
-
-#define DCSR_RUN	0x00000001	/* DMA running                     */
-#define DCSR_IE 	0x00000002	/* DMA Interrupt Enable            */
-#define DCSR_ERROR	0x00000004	/* DMA ERROR                       */
-#define DCSR_DONEA	0x00000008	/* DONE DMA transfer buffer A      */
-#define DCSR_STRTA	0x00000010	/* STaRTed DMA transfer buffer A   */
-#define DCSR_DONEB	0x00000020	/* DONE DMA transfer buffer B      */
-#define DCSR_STRTB	0x00000040	/* STaRTed DMA transfer buffer B   */
-#define DCSR_BIU	0x00000080	/* DMA Buffer In Use               */
-#define DCSR_BufA	(DCSR_BIU*0)	/*  DMA Buffer A in use            */
-#define DCSR_BufB	(DCSR_BIU*1)	/*  DMA Buffer B in use            */
-
-#define DBT_TC  	Fld (13, 0)	/* Transfer Count                  */
-#define DBTA_TCA	DBT_TC  	/* Transfer Count buffer A         */
-#define DBTB_TCB	DBT_TC  	/* Transfer Count buffer B         */
+#define DMA_SIZE	(6 * 0x20)
+#define DMA_PHYS	0xb0000000
 
 
 /*
@@ -1903,16 +1688,6 @@
 #define LCD_Int100_0A	0xF     	/* LCD Intensity = 100.0% =  1     */
                 	        	/* (Alternative)                   */
 
-#define LCCR0		__REG(0xB0100000)  /* LCD Control Reg. 0 */
-#define LCSR		__REG(0xB0100004)  /* LCD Status Reg. */
-#define DBAR1		__REG(0xB0100010)  /* LCD DMA Base Address Reg. channel 1 */
-#define DCAR1		__REG(0xB0100014)  /* LCD DMA Current Address Reg. channel 1 */
-#define DBAR2		__REG(0xB0100018)  /* LCD DMA Base Address Reg.  channel 2 */
-#define DCAR2		__REG(0xB010001C)  /* LCD DMA Current Address Reg. channel 2 */
-#define LCCR1		__REG(0xB0100020)  /* LCD Control Reg. 1 */
-#define LCCR2		__REG(0xB0100024)  /* LCD Control Reg. 2 */
-#define LCCR3		__REG(0xB0100028)  /* LCD Control Reg. 3 */
-
 #define LCCR0_LEN	0x00000001	/* LCD ENable                      */
 #define LCCR0_CMS	0x00000002	/* Color/Monochrome display Select */
 #define LCCR0_Color	(LCCR0_CMS*0)	/*  Color display                  */
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
index 28c2cf5..3073914 100644
--- a/arch/arm/mach-sa1100/include/mach/assabet.h
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -85,21 +85,18 @@ extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
 #define ASSABET_BSR_RAD_RI	(1 << 31)
 
 
-/* GPIOs for which the generic definition doesn't say much */
+/* GPIOs (bitmasks) for which the generic definition doesn't say much */
 #define ASSABET_GPIO_RADIO_IRQ		GPIO_GPIO (14)	/* Radio interrupt request  */
 #define ASSABET_GPIO_PS_MODE_SYNC	GPIO_GPIO (16)	/* Power supply mode/sync   */
 #define ASSABET_GPIO_STEREO_64FS_CLK	GPIO_GPIO (19)	/* SSP UDA1341 clock input  */
-#define ASSABET_GPIO_CF_IRQ		GPIO_GPIO (21)	/* CF IRQ   */
-#define ASSABET_GPIO_CF_CD		GPIO_GPIO (22)	/* CF CD */
-#define ASSABET_GPIO_CF_BVD2		GPIO_GPIO (24)	/* CF BVD */
 #define ASSABET_GPIO_GFX_IRQ		GPIO_GPIO (24)	/* Graphics IRQ */
-#define ASSABET_GPIO_CF_BVD1		GPIO_GPIO (25)	/* CF BVD */
 #define ASSABET_GPIO_BATT_LOW		GPIO_GPIO (26)	/* Low battery */
 #define ASSABET_GPIO_RCLK		GPIO_GPIO (26)	/* CCLK/2  */
 
-#define ASSABET_IRQ_GPIO_CF_IRQ		IRQ_GPIO21
-#define ASSABET_IRQ_GPIO_CF_CD		IRQ_GPIO22
-#define ASSABET_IRQ_GPIO_CF_BVD2	IRQ_GPIO24
-#define ASSABET_IRQ_GPIO_CF_BVD1	IRQ_GPIO25
+/* These are gpiolib GPIO numbers, not bitmasks */
+#define ASSABET_GPIO_CF_IRQ		21	/* CF IRQ */
+#define ASSABET_GPIO_CF_CD		22	/* CF CD  */
+#define ASSABET_GPIO_CF_BVD2		24	/* CF BVD / IOSPKR */
+#define ASSABET_GPIO_CF_BVD1		25	/* CF BVD / IOSTSCHG */
 
 #endif
diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/include/mach/cerf.h
index c3ac3d0..88fd9c0 100644
--- a/arch/arm/mach-sa1100/include/mach/cerf.h
+++ b/arch/arm/mach-sa1100/include/mach/cerf.h
@@ -14,15 +14,10 @@
 #define CERF_ETH_IO			0xf0000000
 #define CERF_ETH_IRQ IRQ_GPIO26
 
-#define CERF_GPIO_CF_BVD2		GPIO_GPIO (19)
-#define CERF_GPIO_CF_BVD1		GPIO_GPIO (20)
-#define CERF_GPIO_CF_RESET		GPIO_GPIO (21)
-#define CERF_GPIO_CF_IRQ		GPIO_GPIO (22)
-#define CERF_GPIO_CF_CD			GPIO_GPIO (23)
-
-#define CERF_IRQ_GPIO_CF_BVD2		IRQ_GPIO19
-#define CERF_IRQ_GPIO_CF_BVD1		IRQ_GPIO20
-#define CERF_IRQ_GPIO_CF_IRQ		IRQ_GPIO22
-#define CERF_IRQ_GPIO_CF_CD		IRQ_GPIO23
+#define CERF_GPIO_CF_BVD2		19
+#define CERF_GPIO_CF_BVD1		20
+#define CERF_GPIO_CF_RESET		21
+#define CERF_GPIO_CF_IRQ		22
+#define CERF_GPIO_CF_CD			23
 
 #endif // _INCLUDE_CERF_H_
diff --git a/arch/arm/mach-sa1100/include/mach/dma.h b/arch/arm/mach-sa1100/include/mach/dma.h
deleted file mode 100644
index dda1b35..0000000
--- a/arch/arm/mach-sa1100/include/mach/dma.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/dma.h
- *
- * Generic SA1100 DMA support
- *
- * Copyright (C) 2000 Nicolas Pitre
- *
- */
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#include "hardware.h"
-
-
-/*
- * The SA1100 has six internal DMA channels.
- */
-#define SA1100_DMA_CHANNELS	6
-
-/*
- * Maximum physical DMA buffer size
- */
-#define MAX_DMA_SIZE		0x1fff
-#define CUT_DMA_SIZE		0x1000
-
-/*
- * All possible SA1100 devices a DMA channel can be attached to.
- */
-typedef enum {
-	DMA_Ser0UDCWr  = DDAR_Ser0UDCWr,   /* Ser. port 0 UDC Write */
-	DMA_Ser0UDCRd  = DDAR_Ser0UDCRd,   /* Ser. port 0 UDC Read */
-	DMA_Ser1UARTWr = DDAR_Ser1UARTWr,  /* Ser. port 1 UART Write */
-	DMA_Ser1UARTRd = DDAR_Ser1UARTRd,  /* Ser. port 1 UART Read */
-	DMA_Ser1SDLCWr = DDAR_Ser1SDLCWr,  /* Ser. port 1 SDLC Write */
-	DMA_Ser1SDLCRd = DDAR_Ser1SDLCRd,  /* Ser. port 1 SDLC Read */
-	DMA_Ser2UARTWr = DDAR_Ser2UARTWr,  /* Ser. port 2 UART Write */
-	DMA_Ser2UARTRd = DDAR_Ser2UARTRd,  /* Ser. port 2 UART Read */
-	DMA_Ser2HSSPWr = DDAR_Ser2HSSPWr,  /* Ser. port 2 HSSP Write */
-	DMA_Ser2HSSPRd = DDAR_Ser2HSSPRd,  /* Ser. port 2 HSSP Read */
-	DMA_Ser3UARTWr = DDAR_Ser3UARTWr,  /* Ser. port 3 UART Write */
-	DMA_Ser3UARTRd = DDAR_Ser3UARTRd,  /* Ser. port 3 UART Read */
-	DMA_Ser4MCP0Wr = DDAR_Ser4MCP0Wr,  /* Ser. port 4 MCP 0 Write (audio) */
-	DMA_Ser4MCP0Rd = DDAR_Ser4MCP0Rd,  /* Ser. port 4 MCP 0 Read (audio) */
-	DMA_Ser4MCP1Wr = DDAR_Ser4MCP1Wr,  /* Ser. port 4 MCP 1 Write */
-	DMA_Ser4MCP1Rd = DDAR_Ser4MCP1Rd,  /* Ser. port 4 MCP 1 Read */
-	DMA_Ser4SSPWr  = DDAR_Ser4SSPWr,   /* Ser. port 4 SSP Write (16 bits) */
-	DMA_Ser4SSPRd  = DDAR_Ser4SSPRd    /* Ser. port 4 SSP Read (16 bits) */
-} dma_device_t;
-
-typedef struct {
-	volatile u_long DDAR;
-	volatile u_long SetDCSR;
-	volatile u_long ClrDCSR;
-	volatile u_long RdDCSR;
-	volatile dma_addr_t DBSA;
-	volatile u_long DBTA;
-	volatile dma_addr_t DBSB;
-	volatile u_long DBTB;
-} dma_regs_t;
-
-typedef void (*dma_callback_t)(void *data);
-
-/*
- * DMA function prototypes
- */
-
-extern int sa1100_request_dma( dma_device_t device, const char *device_id,
-			       dma_callback_t callback, void *data,
-			       dma_regs_t **regs );
-extern void sa1100_free_dma( dma_regs_t *regs );
-extern int sa1100_start_dma( dma_regs_t *regs, dma_addr_t dma_ptr, u_int size );
-extern dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs);
-extern void sa1100_reset_dma(dma_regs_t *regs);
-
-/**
- * 	sa1100_stop_dma - stop DMA in progress
- * 	@regs: identifier for the channel to use
- *
- * 	This stops DMA without clearing buffer pointers. Unlike
- * 	sa1100_clear_dma() this allows subsequent use of sa1100_resume_dma()
- * 	or sa1100_get_dma_pos().
- *
- * 	The @regs identifier is provided by a successful call to
- * 	sa1100_request_dma().
- **/
-
-#define sa1100_stop_dma(regs)	((regs)->ClrDCSR = DCSR_IE|DCSR_RUN)
-
-/**
- * 	sa1100_resume_dma - resume DMA on a stopped channel
- * 	@regs: identifier for the channel to use
- *
- * 	This resumes DMA on a channel previously stopped with
- * 	sa1100_stop_dma().
- *
- * 	The @regs identifier is provided by a successful call to
- * 	sa1100_request_dma().
- **/
-
-#define sa1100_resume_dma(regs)	((regs)->SetDCSR = DCSR_IE|DCSR_RUN)
-
-/**
- * 	sa1100_clear_dma - clear DMA pointers
- * 	@regs: identifier for the channel to use
- *
- * 	This clear any DMA state so the DMA engine is ready to restart
- * 	with new buffers through sa1100_start_dma(). Any buffers in flight
- * 	are discarded.
- *
- * 	The @regs identifier is provided by a successful call to
- * 	sa1100_request_dma().
- **/
-
-#define sa1100_clear_dma(regs)	((regs)->ClrDCSR = DCSR_IE|DCSR_RUN|DCSR_STRTA|DCSR_STRTB)
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index d18f21a..db0699a 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -71,22 +71,16 @@
 /*
  * Figure out the MAX IRQ number.
  *
- * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
- * If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4
- * Otherwise, we have the standard IRQs only.
+ * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
+ * allocate their IRQs above NR_IRQS.
+ *
+ * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
+ * to be included in the NR_IRQS calculation.
  */
-#ifdef CONFIG_SA1111
-#define NR_IRQS			(IRQ_BOARD_END + 55)
-#elif defined(CONFIG_SHARP_LOCOMO)
-#define NR_IRQS			(IRQ_BOARD_START + 4)
+#ifdef CONFIG_SHARP_LOCOMO
+#define NR_IRQS_LOCOMO		4
 #else
-#define NR_IRQS			(IRQ_BOARD_START)
+#define NR_IRQS_LOCOMO		0
 #endif
 
-/*
- * Board specific IRQs.  Define them here.
- * Do not surround them with ifdefs.
- */
-#define IRQ_NEPONSET_SMC9196	(IRQ_BOARD_START + 0)
-#define IRQ_NEPONSET_USAR	(IRQ_BOARD_START + 1)
-#define IRQ_NEPONSET_SA1111	(IRQ_BOARD_START + 2)
+#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h
index ed1a331..4b2860ae 100644
--- a/arch/arm/mach-sa1100/include/mach/mcp.h
+++ b/arch/arm/mach-sa1100/include/mach/mcp.h
@@ -16,7 +16,7 @@ struct mcp_plat_data {
 	u32 mccr0;
 	u32 mccr1;
 	unsigned int sclk_rate;
-	int gpio_base;
+	void *codec_pdata;
 };
 
 #endif
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h
index 14f8382..5ebd469 100644
--- a/arch/arm/mach-sa1100/include/mach/nanoengine.h
+++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h
@@ -16,12 +16,12 @@
 
 #include <mach/irqs.h>
 
-#define GPIO_PC_READY0	GPIO_GPIO(11) /* ready for socket 0 (active high)*/
-#define GPIO_PC_READY1	GPIO_GPIO(12) /* ready for socket 1 (active high) */
-#define GPIO_PC_CD0	GPIO_GPIO(13) /* detect for socket 0 (active low) */
-#define GPIO_PC_CD1	GPIO_GPIO(14) /* detect for socket 1 (active low) */
-#define GPIO_PC_RESET0	GPIO_GPIO(15) /* reset socket 0 */
-#define GPIO_PC_RESET1	GPIO_GPIO(16) /* reset socket 1 */
+#define GPIO_PC_READY0	11 /* ready for socket 0 (active high)*/
+#define GPIO_PC_READY1	12 /* ready for socket 1 (active high) */
+#define GPIO_PC_CD0	13 /* detect for socket 0 (active low) */
+#define GPIO_PC_CD1	14 /* detect for socket 1 (active low) */
+#define GPIO_PC_RESET0	15 /* reset socket 0 */
+#define GPIO_PC_RESET1	16 /* reset socket 1 */
 
 #define NANOENGINE_IRQ_GPIO_PCI		IRQ_GPIO0
 #define NANOENGINE_IRQ_GPIO_PC_READY0	IRQ_GPIO11
diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h
index ffe2bc4..5516a52 100644
--- a/arch/arm/mach-sa1100/include/mach/neponset.h
+++ b/arch/arm/mach-sa1100/include/mach/neponset.h
@@ -15,54 +15,6 @@
 /*
  * Neponset definitions: 
  */
-
-#define NEPONSET_CPLD_BASE      (0x10000000)
-#define Nep_p2v( x )            ((x) - NEPONSET_CPLD_BASE + 0xf3000000)
-#define Nep_v2p( x )            ((x) - 0xf3000000 + NEPONSET_CPLD_BASE)
-
-#define _IRR                    0x10000024      /* Interrupt Reason Register */
-#define _AUD_CTL                0x100000c0      /* Audio controls (RW)       */
-#define _MDM_CTL_0              0x100000b0      /* Modem control 0 (RW)      */
-#define _MDM_CTL_1              0x100000b4      /* Modem control 1 (RW)      */
-#define _NCR_0	                0x100000a0      /* Control Register (RW)     */
-#define _KP_X_OUT               0x10000090      /* Keypad row write (RW)     */
-#define _KP_Y_IN                0x10000080      /* Keypad column read (RO)   */
-#define _SWPK                   0x10000020      /* Switch pack (RO)          */
-#define _WHOAMI                 0x10000000      /* System ID Register (RO)   */
-
-#define _LEDS                   0x10000010      /* LEDs [31:0] (WO)          */
-
-#define IRR                     (*((volatile u_char *) Nep_p2v(_IRR)))
-#define AUD_CTL                 (*((volatile u_char *) Nep_p2v(_AUD_CTL)))
-#define MDM_CTL_0               (*((volatile u_char *) Nep_p2v(_MDM_CTL_0)))
-#define MDM_CTL_1               (*((volatile u_char *) Nep_p2v(_MDM_CTL_1)))
-#define NCR_0			(*((volatile u_char *) Nep_p2v(_NCR_0)))
-#define KP_X_OUT                (*((volatile u_char *) Nep_p2v(_KP_X_OUT)))
-#define KP_Y_IN                 (*((volatile u_char *) Nep_p2v(_KP_Y_IN)))
-#define SWPK                    (*((volatile u_char *) Nep_p2v(_SWPK)))
-#define WHOAMI                  (*((volatile u_char *) Nep_p2v(_WHOAMI)))
-
-#define LEDS                    (*((volatile Word   *) Nep_p2v(_LEDS)))
-
-#define IRR_ETHERNET		(1<<0)
-#define IRR_USAR		(1<<1)
-#define IRR_SA1111		(1<<2)
-
-#define AUD_SEL_1341            (1<<0)
-#define AUD_MUTE_1341           (1<<1)
-
-#define MDM_CTL0_RTS1		(1 << 0)
-#define MDM_CTL0_DTR1		(1 << 1)
-#define MDM_CTL0_RTS2		(1 << 2)
-#define MDM_CTL0_DTR2		(1 << 3)
-
-#define MDM_CTL1_CTS1		(1 << 0)
-#define MDM_CTL1_DSR1		(1 << 1)
-#define MDM_CTL1_DCD1		(1 << 2)
-#define MDM_CTL1_CTS2		(1 << 3)
-#define MDM_CTL1_DSR2		(1 << 4)
-#define MDM_CTL1_DCD2		(1 << 5)
-
 #define NCR_GP01_OFF		(1<<0)
 #define NCR_TP_PWR_EN		(1<<1)
 #define NCR_MS_PWR_EN		(1<<2)
@@ -71,4 +23,8 @@
 #define NCR_A0VPP		(1<<5)
 #define NCR_A1VPP		(1<<6)
 
+void neponset_ncr_frob(unsigned int, unsigned int);
+#define neponset_ncr_set(v)	neponset_ncr_frob(0, v)
+#define neponset_ncr_clear(v)	neponset_ncr_frob(v, 0)
+
 #endif
diff --git a/arch/arm/mach-sa1100/include/mach/shannon.h b/arch/arm/mach-sa1100/include/mach/shannon.h
index ec27d6e..fff39e0 100644
--- a/arch/arm/mach-sa1100/include/mach/shannon.h
+++ b/arch/arm/mach-sa1100/include/mach/shannon.h
@@ -21,16 +21,12 @@
 #define SHANNON_GPIO_U3_RTS		GPIO_GPIO (19)	/* ?? */
 #define SHANNON_GPIO_U3_CTS		GPIO_GPIO (20)	/* ?? */
 #define SHANNON_GPIO_SENSE_12V		GPIO_GPIO (21)	/* Input, 12v flash unprotect detected */
-#define SHANNON_GPIO_DISP_EN		GPIO_GPIO (22)	/* out */
+#define SHANNON_GPIO_DISP_EN		22		/* out */
 /* XXX GPIO 23 unaccounted for */
-#define SHANNON_GPIO_EJECT_0		GPIO_GPIO (24)	/* in */
-#define SHANNON_IRQ_GPIO_EJECT_0	IRQ_GPIO24
-#define SHANNON_GPIO_EJECT_1		GPIO_GPIO (25)	/* in */
-#define SHANNON_IRQ_GPIO_EJECT_1	IRQ_GPIO25
-#define SHANNON_GPIO_RDY_0		GPIO_GPIO (26)	/* in */
-#define SHANNON_IRQ_GPIO_RDY_0		IRQ_GPIO26
-#define SHANNON_GPIO_RDY_1		GPIO_GPIO (27)	/* in */
-#define SHANNON_IRQ_GPIO_RDY_1		IRQ_GPIO27
+#define SHANNON_GPIO_EJECT_0		24		/* in */
+#define SHANNON_GPIO_EJECT_1		25		/* in */
+#define SHANNON_GPIO_RDY_0		26		/* in */
+#define SHANNON_GPIO_RDY_1		27		/* in */
 
 /* MCP UCB codec GPIO pins... */
 
diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h
index db28118..cdea671 100644
--- a/arch/arm/mach-sa1100/include/mach/simpad.h
+++ b/arch/arm/mach-sa1100/include/mach/simpad.h
@@ -39,10 +39,8 @@
 
 
 /*---  PCMCIA  ---*/
-#define GPIO_CF_CD              GPIO_GPIO24
-#define GPIO_CF_IRQ             GPIO_GPIO1
-#define IRQ_GPIO_CF_IRQ         IRQ_GPIO1
-#define IRQ_GPIO_CF_CD          IRQ_GPIO24
+#define GPIO_CF_CD              24
+#define GPIO_CF_IRQ             1
 
 /*--- SmartCard ---*/
 #define GPIO_SMART_CARD		GPIO_GPIO10
diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h
deleted file mode 100644
index e17b208..0000000
--- a/arch/arm/mach-sa1100/include/mach/system.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/system.h
- *
- * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index dfbf824..5d12a30 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -221,11 +221,8 @@ static struct irq_chip sa1100_normal_chip = {
 	.irq_set_wake	= sa1100_set_wake,
 };
 
-static struct resource irq_resource = {
-	.name	= "irqs",
-	.start	= 0x90050000,
-	.end	= 0x9005ffff,
-};
+static struct resource irq_resource =
+	DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
 
 static struct sa1100irq_state {
 	unsigned int	saved;
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index ee121d6..0c9a0bd 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -46,7 +46,7 @@
 
 /* memory space (line 52 of HP's doc) */
 #define SA1111REGSTART	0x40000000
-#define SA1111REGLEN	0x00001fff
+#define SA1111REGLEN	0x00002000
 #define EPSONREGSTART	0x48000000
 #define EPSONREGLEN	0x00100000
 #define EPSONFBSTART	0x48200000
@@ -174,16 +174,8 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
 };
 
 static struct resource s1d13xxxfb_resources[] = {
-	[0] = {
-		.start	= EPSONFBSTART,
-		.end	= EPSONFBSTART + EPSONFBLEN,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= EPSONREGSTART,
-		.end	= EPSONREGSTART + EPSONREGLEN,
-		.flags	= IORESOURCE_MEM,
-	}
+	[0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN),
+	[1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN),
 };
 
 static struct platform_device s1d13xxxfb_device = {
@@ -197,20 +189,12 @@ static struct platform_device s1d13xxxfb_device = {
 };
 
 static struct resource sa1111_resources[] = {
-	[0] = {
-		.start		= SA1111REGSTART,
-		.end		= SA1111REGSTART + SA1111REGLEN,
-		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= IRQ_GPIO1,
-		.end		= IRQ_GPIO1,
-		.flags		= IORESOURCE_IRQ,
-	},
+	[0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
+	[1] = DEFINE_RES_IRQ(IRQ_GPIO1),
 };
 
 static struct sa1111_platform_data sa1111_info = {
-	.irq_base	= IRQ_BOARD_END,
+	.disable_devs	= SA1111_DEVID_PS2_MSE,
 };
 
 static u64 sa1111_dmamask = 0xffffffffUL;
@@ -284,11 +268,6 @@ static struct map_desc jornada720_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(EPSONFBSTART),
 		.length		= EPSONFBLEN,
 		.type		= MT_DEVICE
-	}, {	/* SA-1111 */
-		.virtual	= 0xf4000000,
-		.pfn		= __phys_to_pfn(SA1111REGSTART),
-		.length		= SA1111REGLEN,
-		.type		= MT_DEVICE
 	}
 };
 
@@ -352,11 +331,8 @@ static struct flash_platform_data jornada720_flash_data = {
 	.nr_parts	= ARRAY_SIZE(jornada720_partitions),
 };
 
-static struct resource jornada720_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_32M - 1,
-	.flags		= IORESOURCE_MEM,
-};
+static struct resource jornada720_flash_resource =
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
 
 static void __init jornada720_mach_init(void)
 {
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index af4e276..570f75f 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -6,6 +6,8 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -26,8 +28,86 @@ static struct mcp_plat_data lart_mcp_data = {
 	.sclk_rate	= 11981000,
 };
 
+#ifdef LART_GREY_LCD
+static struct sa1100fb_mach_info lart_grey_info = {
+	.pixclock	= 150000,	.bpp		= 4,
+	.xres		= 320,		.yres		= 240,
+
+	.hsync_len	= 1,		.vsync_len	= 1,
+	.left_margin	= 4,		.upper_margin	= 0,
+	.right_margin	= 2,		.lower_margin	= 0,
+
+	.cmap_greyscale	= 1,
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+	.lccr0		= LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+#ifdef LART_COLOR_LCD
+static struct sa1100fb_mach_info lart_color_info = {
+	.pixclock	= 150000,	.bpp		= 16,
+	.xres		= 320,		.yres		= 240,
+
+	.hsync_len	= 2,		.vsync_len	= 3,
+	.left_margin	= 69,		.upper_margin	= 14,
+	.right_margin	= 8,		.lower_margin	= 4,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+#ifdef LART_VIDEO_OUT
+static struct sa1100fb_mach_info lart_video_info = {
+	.pixclock	= 39721,	.bpp		= 16,
+	.xres		= 640,		.yres		= 480,
+
+	.hsync_len	= 95,		.vsync_len	= 2,
+	.left_margin	= 40,		.upper_margin	= 32,
+	.right_margin	= 24,		.lower_margin	= 11,
+
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
+};
+#endif
+
+#ifdef LART_KIT01_LCD
+static struct sa1100fb_mach_info lart_kit01_info = {
+	.pixclock	= 63291,	.bpp		= 16,
+	.xres		= 640,		.yres		= 480,
+
+	.hsync_len	= 64,		.vsync_len	= 3,
+	.left_margin	= 122,		.upper_margin	= 45,
+	.right_margin	= 10,		.lower_margin	= 10,
+
+	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3		= LCCR3_OutEnH | LCCR3_PixFlEdg
+};
+#endif
+
 static void __init lart_init(void)
 {
+	struct sa1100fb_mach_info *inf = NULL;
+
+#ifdef LART_GREY_LCD
+	inf = &lart_grey_info;
+#endif
+#ifdef LART_COLOR_LCD
+	inf = &lart_color_info;
+#endif
+#ifdef LART_VIDEO_OUT
+	inf = &lart_video_info;
+#endif
+#ifdef LART_KIT01_LCD
+	inf = &lart_kit01_info;
+#endif
+
+	if (inf)
+		sa11x0_register_lcd(inf);
+
+	sa11x0_ppc_configure_mcp();
 	sa11x0_register_mcp(&lart_mcp_data);
 }
 
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index 85f6ee6..3923911 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -58,15 +58,8 @@ static struct flash_platform_data nanoengine_flash_data = {
 };
 
 static struct resource nanoengine_flash_resources[] = {
-	{
-		.start	= SA1100_CS0_PHYS,
-		.end	= SA1100_CS0_PHYS + SZ_32M - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= SA1100_CS1_PHYS,
-		.end	= SA1100_CS1_PHYS + SZ_32M - 1,
-		.flags	= IORESOURCE_MEM,
-	}
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+	DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
 };
 
 static struct map_desc nanoengine_io_desc[] __initdata = {
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index b4fa53a..3e43af4 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -1,89 +1,103 @@
 /*
  * linux/arch/arm/mach-sa1100/neponset.c
- *
  */
-#include <linux/kernel.h>
+#include <linux/err.h>
 #include <linux/init.h>
-#include <linux/tty.h>
 #include <linux/ioport.h>
-#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
 #include <asm/mach/map.h>
-#include <asm/mach/irq.h>
 #include <asm/mach/serial_sa1100.h>
-#include <mach/assabet.h>
-#include <mach/neponset.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/sizes.h>
 
-/*
- * Install handler for Neponset IRQ.  Note that we have to loop here
- * since the ETHERNET and USAR IRQs are level based, and we need to
- * ensure that the IRQ signal is deasserted before returning.  This
- * is rather unfortunate.
- */
-static void
-neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	unsigned int irr;
-
-	while (1) {
-		/*
-		 * Acknowledge the parent IRQ.
-		 */
-		desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-		/*
-		 * Read the interrupt reason register.  Let's have all
-		 * active IRQ bits high.  Note: there is a typo in the
-		 * Neponset user's guide for the SA1111 IRR level.
-		 */
-		irr = IRR ^ (IRR_ETHERNET | IRR_USAR);
-
-		if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
-			break;
-
-		/*
-		 * Since there is no individual mask, we have to
-		 * mask the parent IRQ.  This is safe, since we'll
-		 * recheck the register for any pending IRQs.
-		 */
-		if (irr & (IRR_ETHERNET | IRR_USAR)) {
-			desc->irq_data.chip->irq_mask(&desc->irq_data);
+#include <mach/hardware.h>
+#include <mach/assabet.h>
+#include <mach/neponset.h>
 
-			/*
-			 * Ack the interrupt now to prevent re-entering
-			 * this neponset handler.  Again, this is safe
-			 * since we'll check the IRR register prior to
-			 * leaving.
-			 */
-			desc->irq_data.chip->irq_ack(&desc->irq_data);
+#define NEP_IRQ_SMC91X	0
+#define NEP_IRQ_USAR	1
+#define NEP_IRQ_SA1111	2
+#define NEP_IRQ_NR	3
+
+#define WHOAMI		0x00
+#define LEDS		0x10
+#define SWPK		0x20
+#define IRR		0x24
+#define KP_Y_IN		0x80
+#define KP_X_OUT	0x90
+#define NCR_0		0xa0
+#define MDM_CTL_0	0xb0
+#define MDM_CTL_1	0xb4
+#define AUD_CTL		0xc0
+
+#define IRR_ETHERNET	(1 << 0)
+#define IRR_USAR	(1 << 1)
+#define IRR_SA1111	(1 << 2)
+
+#define MDM_CTL0_RTS1	(1 << 0)
+#define MDM_CTL0_DTR1	(1 << 1)
+#define MDM_CTL0_RTS2	(1 << 2)
+#define MDM_CTL0_DTR2	(1 << 3)
+
+#define MDM_CTL1_CTS1	(1 << 0)
+#define MDM_CTL1_DSR1	(1 << 1)
+#define MDM_CTL1_DCD1	(1 << 2)
+#define MDM_CTL1_CTS2	(1 << 3)
+#define MDM_CTL1_DSR2	(1 << 4)
+#define MDM_CTL1_DCD2	(1 << 5)
+
+#define AUD_SEL_1341	(1 << 0)
+#define AUD_MUTE_1341	(1 << 1)
 
-			if (irr & IRR_ETHERNET) {
-				generic_handle_irq(IRQ_NEPONSET_SMC9196);
-			}
+extern void sa1110_mb_disable(void);
 
-			if (irr & IRR_USAR) {
-				generic_handle_irq(IRQ_NEPONSET_USAR);
-			}
+struct neponset_drvdata {
+	void __iomem *base;
+	struct platform_device *sa1111;
+	struct platform_device *smc91x;
+	unsigned irq_base;
+#ifdef CONFIG_PM_SLEEP
+	u32 ncr0;
+	u32 mdm_ctl_0;
+#endif
+};
 
-			desc->irq_data.chip->irq_unmask(&desc->irq_data);
-		}
+static void __iomem *nep_base;
 
-		if (irr & IRR_SA1111) {
-			generic_handle_irq(IRQ_NEPONSET_SA1111);
-		}
+void neponset_ncr_frob(unsigned int mask, unsigned int val)
+{
+	void __iomem *base = nep_base;
+
+	if (base) {
+		unsigned long flags;
+		unsigned v;
+
+		local_irq_save(flags);
+		v = readb_relaxed(base + NCR_0);
+		writeb_relaxed((v & ~mask) | val, base + NCR_0);
+		local_irq_restore(flags);
+	} else {
+		WARN(1, "nep_base unset\n");
 	}
 }
 
 static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-	u_int mdm_ctl0 = MDM_CTL_0;
+	void __iomem *base = nep_base;
+	u_int mdm_ctl0;
+
+	if (!base)
+		return;
 
+	mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
 	if (port->mapbase == _Ser1UTCR0) {
 		if (mctrl & TIOCM_RTS)
 			mdm_ctl0 &= ~MDM_CTL0_RTS2;
@@ -106,14 +120,19 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
 			mdm_ctl0 |= MDM_CTL0_DTR1;
 	}
 
-	MDM_CTL_0 = mdm_ctl0;
+	writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
 }
 
 static u_int neponset_get_mctrl(struct uart_port *port)
 {
+	void __iomem *base = nep_base;
 	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
-	u_int mdm_ctl1 = MDM_CTL_1;
+	u_int mdm_ctl1;
 
+	if (!base)
+		return ret;
+
+	mdm_ctl1 = readb_relaxed(base + MDM_CTL_1);
 	if (port->mapbase == _Ser1UTCR0) {
 		if (mdm_ctl1 & MDM_CTL1_DCD2)
 			ret &= ~TIOCM_CD;
@@ -138,209 +157,278 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = {
 	.get_mctrl	= neponset_get_mctrl,
 };
 
-static int __devinit neponset_probe(struct platform_device *dev)
+/*
+ * Install handler for Neponset IRQ.  Note that we have to loop here
+ * since the ETHERNET and USAR IRQs are level based, and we need to
+ * ensure that the IRQ signal is deasserted before returning.  This
+ * is rather unfortunate.
+ */
+static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-	sa1100_register_uart_fns(&neponset_port_fns);
+	struct neponset_drvdata *d = irq_desc_get_handler_data(desc);
+	unsigned int irr;
 
-	/*
-	 * Install handler for GPIO25.
-	 */
-	irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING);
-	irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler);
+	while (1) {
+		/*
+		 * Acknowledge the parent IRQ.
+		 */
+		desc->irq_data.chip->irq_ack(&desc->irq_data);
 
-	/*
-	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but
-	 * unfortunately something on the Neponset activates
-	 * this IRQ on sleep (ethernet?)
-	 */
-#if 0
-	enable_irq_wake(IRQ_GPIO25);
-#endif
+		/*
+		 * Read the interrupt reason register.  Let's have all
+		 * active IRQ bits high.  Note: there is a typo in the
+		 * Neponset user's guide for the SA1111 IRR level.
+		 */
+		irr = readb_relaxed(d->base + IRR);
+		irr ^= IRR_ETHERNET | IRR_USAR;
 
-	/*
-	 * Setup other Neponset IRQs.  SA1111 will be done by the
-	 * generic SA1111 code.
-	 */
-	irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq);
-	set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
-	irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq);
-	set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
+		if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
+			break;
 
-	/*
-	 * Disable GPIO 0/1 drivers so the buttons work on the module.
-	 */
-	NCR_0 = NCR_GP01_OFF;
+		/*
+		 * Since there is no individual mask, we have to
+		 * mask the parent IRQ.  This is safe, since we'll
+		 * recheck the register for any pending IRQs.
+		 */
+		if (irr & (IRR_ETHERNET | IRR_USAR)) {
+			desc->irq_data.chip->irq_mask(&desc->irq_data);
 
-	return 0;
-}
+			/*
+			 * Ack the interrupt now to prevent re-entering
+			 * this neponset handler.  Again, this is safe
+			 * since we'll check the IRR register prior to
+			 * leaving.
+			 */
+			desc->irq_data.chip->irq_ack(&desc->irq_data);
 
-#ifdef CONFIG_PM
+			if (irr & IRR_ETHERNET)
+				generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X);
 
-/*
- * LDM power management.
- */
-static unsigned int neponset_saved_state;
+			if (irr & IRR_USAR)
+				generic_handle_irq(d->irq_base + NEP_IRQ_USAR);
 
-static int neponset_suspend(struct platform_device *dev, pm_message_t state)
-{
-	/*
-	 * Save state.
-	 */
-	neponset_saved_state = NCR_0;
+			desc->irq_data.chip->irq_unmask(&desc->irq_data);
+		}
 
-	return 0;
+		if (irr & IRR_SA1111)
+			generic_handle_irq(d->irq_base + NEP_IRQ_SA1111);
+	}
 }
 
-static int neponset_resume(struct platform_device *dev)
+/* Yes, we really do not have any kind of masking or unmasking */
+static void nochip_noop(struct irq_data *irq)
 {
-	NCR_0 = neponset_saved_state;
-
-	return 0;
 }
 
-#else
-#define neponset_suspend NULL
-#define neponset_resume  NULL
-#endif
-
-static struct platform_driver neponset_device_driver = {
-	.probe		= neponset_probe,
-	.suspend	= neponset_suspend,
-	.resume		= neponset_resume,
-	.driver		= {
-		.name	= "neponset",
-	},
-};
-
-static struct resource neponset_resources[] = {
-	[0] = {
-		.start	= 0x10000000,
-		.end	= 0x17ffffff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device neponset_device = {
-	.name		= "neponset",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(neponset_resources),
-	.resource	= neponset_resources,
-};
-
-static struct resource sa1111_resources[] = {
-	[0] = {
-		.start	= 0x40000000,
-		.end	= 0x40001fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_NEPONSET_SA1111,
-		.end	= IRQ_NEPONSET_SA1111,
-		.flags	= IORESOURCE_IRQ,
-	},
+static struct irq_chip nochip = {
+	.name = "neponset",
+	.irq_ack = nochip_noop,
+	.irq_mask = nochip_noop,
+	.irq_unmask = nochip_noop,
 };
 
 static struct sa1111_platform_data sa1111_info = {
-	.irq_base	= IRQ_BOARD_END,
+	.disable_devs	= SA1111_DEVID_PS2_MSE,
 };
 
-static u64 sa1111_dmamask = 0xffffffffUL;
+static int __devinit neponset_probe(struct platform_device *dev)
+{
+	struct neponset_drvdata *d;
+	struct resource *nep_res, *sa1111_res, *smc91x_res;
+	struct resource sa1111_resources[] = {
+		DEFINE_RES_MEM(0x40000000, SZ_8K),
+		{ .flags = IORESOURCE_IRQ },
+	};
+	struct platform_device_info sa1111_devinfo = {
+		.parent = &dev->dev,
+		.name = "sa1111",
+		.id = 0,
+		.res = sa1111_resources,
+		.num_res = ARRAY_SIZE(sa1111_resources),
+		.data = &sa1111_info,
+		.size_data = sizeof(sa1111_info),
+		.dma_mask = 0xffffffffUL,
+	};
+	struct resource smc91x_resources[] = {
+		DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
+			0x02000000, "smc91x-regs"),
+		DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
+			0x02000000, "smc91x-attrib"),
+		{ .flags = IORESOURCE_IRQ },
+	};
+	struct platform_device_info smc91x_devinfo = {
+		.parent = &dev->dev,
+		.name = "smc91x",
+		.id = 0,
+		.res = smc91x_resources,
+		.num_res = ARRAY_SIZE(smc91x_resources),
+	};
+	int ret, irq;
+
+	if (nep_base)
+		return -EBUSY;
+
+	irq = ret = platform_get_irq(dev, 0);
+	if (ret < 0)
+		goto err_alloc;
+
+	nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+	sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
+	if (!nep_res || !smc91x_res || !sa1111_res) {
+		ret = -ENXIO;
+		goto err_alloc;
+	}
 
-static struct platform_device sa1111_device = {
-	.name		= "sa1111",
-	.id		= 0,
-	.dev		= {
-		.dma_mask = &sa1111_dmamask,
-		.coherent_dma_mask = 0xffffffff,
-		.platform_data = &sa1111_info,
-	},
-	.num_resources	= ARRAY_SIZE(sa1111_resources),
-	.resource	= sa1111_resources,
-};
+	d = kzalloc(sizeof(*d), GFP_KERNEL);
+	if (!d) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
 
-static struct resource smc91x_resources[] = {
-	[0] = {
-		.name	= "smc91x-regs",
-		.start	= SA1100_CS3_PHYS,
-		.end	= SA1100_CS3_PHYS + 0x01ffffff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_NEPONSET_SMC9196,
-		.end	= IRQ_NEPONSET_SMC9196,
-		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
-		.name	= "smc91x-attrib",
-		.start	= SA1100_CS3_PHYS + 0x02000000,
-		.end	= SA1100_CS3_PHYS + 0x03ffffff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
+	d->base = ioremap(nep_res->start, SZ_4K);
+	if (!d->base) {
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
 
-static struct platform_device smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(smc91x_resources),
-	.resource	= smc91x_resources,
-};
+	if (readb_relaxed(d->base + WHOAMI) != 0x11) {
+		dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
+			 readb_relaxed(d->base + WHOAMI));
+		ret = -ENODEV;
+		goto err_id;
+	}
 
-static struct platform_device *devices[] __initdata = {
-	&neponset_device,
-	&sa1111_device,
-	&smc91x_device,
-};
+	ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
+	if (ret <= 0) {
+		dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
+			NEP_IRQ_NR, ret);
+		if (ret == 0)
+			ret = -ENOMEM;
+		goto err_irq_alloc;
+	}
 
-extern void sa1110_mb_disable(void);
+	d->irq_base = ret;
 
-static int __init neponset_init(void)
-{
-	platform_driver_register(&neponset_device_driver);
+	irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
+		handle_simple_irq);
+	set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE);
+	irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
+		handle_simple_irq);
+	set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE);
+	irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
 
-	/*
-	 * The Neponset is only present on the Assabet machine type.
-	 */
-	if (!machine_is_assabet())
-		return -ENODEV;
+	irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+	irq_set_handler_data(irq, d);
+	irq_set_chained_handler(irq, neponset_irq_handler);
 
 	/*
-	 * Ensure that the memory bus request/grant signals are setup,
-	 * and the grant is held in its inactive state, whether or not
-	 * we actually have a Neponset attached.
+	 * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
+	 * something on the Neponset activates this IRQ on sleep (eth?)
 	 */
+#if 0
+	enable_irq_wake(irq);
+#endif
+
+	dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
+		 d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
+	nep_base = d->base;
+
+	sa1100_register_uart_fns(&neponset_port_fns);
+
+	/* Ensure that the memory bus request/grant signals are setup */
 	sa1110_mb_disable();
 
-	if (!machine_has_neponset()) {
-		printk(KERN_DEBUG "Neponset expansion board not present\n");
-		return -ENODEV;
-	}
+	/* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
+	writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
 
-	if (WHOAMI != 0x11) {
-		printk(KERN_WARNING "Neponset board detected, but "
-			"wrong ID: %02x\n", WHOAMI);
-		return -ENODEV;
-	}
+	sa1111_resources[0].parent = sa1111_res;
+	sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
+	sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
+	d->sa1111 = platform_device_register_full(&sa1111_devinfo);
+
+	smc91x_resources[0].parent = smc91x_res;
+	smc91x_resources[1].parent = smc91x_res;
+	smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
+	smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
+	d->smc91x = platform_device_register_full(&smc91x_devinfo);
+
+	platform_set_drvdata(dev, d);
 
-	return platform_add_devices(devices, ARRAY_SIZE(devices));
+	return 0;
+
+ err_irq_alloc:
+ err_id:
+	iounmap(d->base);
+ err_ioremap:
+	kfree(d);
+ err_alloc:
+	return ret;
 }
 
-subsys_initcall(neponset_init);
+static int __devexit neponset_remove(struct platform_device *dev)
+{
+	struct neponset_drvdata *d = platform_get_drvdata(dev);
+	int irq = platform_get_irq(dev, 0);
+
+	if (!IS_ERR(d->sa1111))
+		platform_device_unregister(d->sa1111);
+	if (!IS_ERR(d->smc91x))
+		platform_device_unregister(d->smc91x);
+	irq_set_chained_handler(irq, NULL);
+	irq_free_descs(d->irq_base, NEP_IRQ_NR);
+	nep_base = NULL;
+	iounmap(d->base);
+	kfree(d);
 
-static struct map_desc neponset_io_desc[] __initdata = {
-	{	/* System Registers */
-		.virtual	=  0xf3000000,
-		.pfn		= __phys_to_pfn(0x10000000),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	}, {	/* SA-1111 */
-		.virtual	=  0xf4000000,
-		.pfn		= __phys_to_pfn(0x40000000),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	}
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int neponset_suspend(struct device *dev)
+{
+	struct neponset_drvdata *d = dev_get_drvdata(dev);
+
+	d->ncr0 = readb_relaxed(d->base + NCR_0);
+	d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
+
+	return 0;
+}
+
+static int neponset_resume(struct device *dev)
+{
+	struct neponset_drvdata *d = dev_get_drvdata(dev);
+
+	writeb_relaxed(d->ncr0, d->base + NCR_0);
+	writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
+
+	return 0;
+}
+
+static const struct dev_pm_ops neponset_pm_ops = {
+	.suspend_noirq = neponset_suspend,
+	.resume_noirq = neponset_resume,
+	.freeze_noirq = neponset_suspend,
+	.restore_noirq = neponset_resume,
+};
+#define PM_OPS &neponset_pm_ops
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver neponset_device_driver = {
+	.probe		= neponset_probe,
+	.remove		= __devexit_p(neponset_remove),
+	.driver		= {
+		.name	= "neponset",
+		.owner	= THIS_MODULE,
+		.pm	= PM_OPS,
+	},
 };
 
-void __init neponset_map_io(void)
+static int __init neponset_init(void)
 {
-	iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
+	return platform_driver_register(&neponset_device_driver);
 }
+
+subsys_initcall(neponset_init);
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
index 0d01ca7..41bb018 100644
--- a/arch/arm/mach-sa1100/pci-nanoengine.c
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -135,12 +135,8 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys
 				 &sys->resources);
 }
 
-static struct resource pci_io_ports = {
-	.name	= "PCI IO",
-	.start	= 0x400,
-	.end	= 0x7FF,
-	.flags	= IORESOURCE_IO,
-};
+static struct resource pci_io_ports =
+	DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO");
 
 static struct resource pci_non_prefetchable_memory = {
 	.name	= "PCI non-prefetchable",
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 9307df0..ca5d33b 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -37,17 +37,9 @@
 #define IRQ_GPIO_ETH0_IRQ	IRQ_GPIO21
 
 static struct resource smc91x_resources[] = {
-	[0] = {
-		.start	= PLEB_ETH0_P,
-		.end	= PLEB_ETH0_P | 0x03ffffff,
-		.flags	= IORESOURCE_MEM,
-	},
+	[0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000),
 #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
-	[1] = {
-		.start	= IRQ_GPIO_ETH0_IRQ,
-		.end	= IRQ_GPIO_ETH0_IRQ,
-		.flags	= IORESOURCE_IRQ,
-	},
+	[1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ),
 #endif
 };
 
@@ -70,16 +62,8 @@ static struct platform_device *devices[] __initdata = {
  * the two SA1100 lowest chip select outputs.
  */
 static struct resource pleb_flash_resources[] = {
-	[0] = {
-		.start = SA1100_CS0_PHYS,
-		.end   = SA1100_CS0_PHYS + SZ_8M - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = SA1100_CS1_PHYS,
-		.end   = SA1100_CS1_PHYS + SZ_8M - 1,
-		.flags = IORESOURCE_MEM,
-	}
+	[0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M),
+	[1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M),
 };
 
 
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 318b2b7..08bb122 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -9,6 +9,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/setup.h>
@@ -46,19 +48,32 @@ static struct flash_platform_data shannon_flash_data = {
 	.nr_parts	= ARRAY_SIZE(shannon_partitions),
 };
 
-static struct resource shannon_flash_resource = {
-	.start		= SA1100_CS0_PHYS,
-	.end		= SA1100_CS0_PHYS + SZ_4M - 1,
-	.flags		= IORESOURCE_MEM,
-};
+static struct resource shannon_flash_resource =
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M);
 
 static struct mcp_plat_data shannon_mcp_data = {
 	.mccr0		= MCCR0_ADM,
 	.sclk_rate	= 11981000,
 };
 
+static struct sa1100fb_mach_info shannon_lcd_info = {
+	.pixclock	= 152500,	.bpp		= 8,
+	.xres		= 640,		.yres		= 480,
+
+	.hsync_len	= 4,		.vsync_len	= 3,
+	.left_margin	= 2,		.upper_margin	= 0,
+	.right_margin	= 1,		.lower_margin	= 0,
+
+	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+	.lccr0		= LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
+	.lccr3		= LCCR3_ACBsDiv(512),
+};
+
 static void __init shannon_init(void)
 {
+	sa11x0_ppc_configure_mcp();
+	sa11x0_register_lcd(&shannon_lcd_info);
 	sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
 	sa11x0_register_mcp(&shannon_mcp_data);
 }
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index e17c04d..3da4c1f 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -10,6 +10,7 @@
 #include <linux/string.h> 
 #include <linux/pm.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
@@ -176,21 +177,18 @@ static struct flash_platform_data simpad_flash_data = {
 
 
 static struct resource simpad_flash_resources [] = {
-	{
-		.start     = SA1100_CS0_PHYS,
-		.end       = SA1100_CS0_PHYS + SZ_16M -1,
-		.flags     = IORESOURCE_MEM,
-	}, {
-		.start     = SA1100_CS1_PHYS,
-		.end       = SA1100_CS1_PHYS + SZ_16M -1,
-		.flags     = IORESOURCE_MEM,
-	}
+	DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M),
+	DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M),
+};
+
+static struct ucb1x00_plat_data simpad_ucb1x00_data = {
+	.gpio_base	= SIMPAD_UCB1X00_GPIO_BASE,
 };
 
 static struct mcp_plat_data simpad_mcp_data = {
 	.mccr0		= MCCR0_ADM,
 	.sclk_rate	= 11981000,
-	.gpio_base	= SIMPAD_UCB1X00_GPIO_BASE,
+	.codec_pdata	= &simpad_ucb1x00_data,
 };
 
 
@@ -376,6 +374,7 @@ static int __init simpad_init(void)
 
 	pm_power_off = simpad_power_off;
 
+	sa11x0_ppc_configure_mcp();
 	sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
 			      ARRAY_SIZE(simpad_flash_resources));
 	sa11x0_register_mcp(&simpad_mcp_data);
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
index e822331..30cc672 100644
--- a/arch/arm/mach-sa1100/sleep.S
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -26,27 +26,36 @@
  *
  * Causes sa11x0 to enter sleep state
  *
+ * Must be aligned to a cacheline.
  */
-
+	.balign	32
 ENTRY(sa1100_finish_suspend)
 	@ disable clock switching
 	mcr	p15, 0, r1, c15, c2, 2
 
-        @ Adjust memory timing before lowering CPU clock
-	@ Clock speed adjustment without changing memory timing makes
-	@ CPU hang in some cases
-        ldr     r0, =MDREFR
-        ldr     r1, [r0]
-        orr     r1, r1, #MDREFR_K1DB2
-        str     r1, [r0]
+	ldr	r6, =MDREFR
+	ldr	r4, [r6]
+	orr     r4, r4, #MDREFR_K1DB2
+	ldr	r5, =PPCR
+
+	@ Pre-load __udelay into the I-cache
+	mov	r0, #1
+	bl	__udelay
+	mov	r0, r0
+
+	@ The following must all exist in a single cache line to
+	@ avoid accessing memory until this sequence is complete,
+	@ otherwise we occasionally hang.
+
+	@ Adjust memory timing before lowering CPU clock
+	str     r4, [r6]
 
 	@ delay 90us and set CPU PLL to lowest speed
 	@ fixes resume problem on high speed SA1110
 	mov	r0, #90
 	bl	__udelay
-	ldr	r0, =PPCR
 	mov	r1, #0
-	str	r1, [r0]
+	str	r1, [r5]
 	mov	r0, #90
 	bl	__udelay
 
@@ -85,12 +94,10 @@ ENTRY(sa1100_finish_suspend)
 	bic	r5, r5, #FMsk(MSC_RT)
 	bic	r5, r5, #FMsk(MSC_RT)<<16
 
-	ldr	r6, =MDREFR
-
 	ldr	r7, [r6]
-bic	r7, r7, #0x0000FF00
-bic	r7, r7, #0x000000F0
-orr	r8, r7, #MDREFR_SLFRSH
+	bic	r7, r7, #0x0000FF00
+	bic	r7, r7, #0x000000F0
+	orr	r8, r7, #MDREFR_SLFRSH
 
 	ldr	r9, =MDCNFG
 	ldr	r10, [r9]
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index a851c25..6a2a7f2 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -149,10 +149,16 @@ static struct sys_timer shark_timer = {
 	.init		= shark_timer_init,
 };
 
+static void shark_init_early(void)
+{
+	disable_hlt();
+}
+
 MACHINE_START(SHARK, "Shark")
 	/* Maintainer: Alexander Schulz */
 	.atag_offset	= 0x3000,
 	.map_io		= shark_map_io,
+	.init_early	= shark_init_early,
 	.init_irq	= shark_init_irq,
 	.timer		= &shark_timer,
 	.dma_zone_size	= SZ_4M,
diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h
deleted file mode 100644
index 1b2f2c5..0000000
--- a/arch/arm/mach-shark/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/system.h
- *
- * by Alexander Schulz
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-}
-
-#endif
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 060e564..34560ca 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -100,6 +100,10 @@ config MACH_MARZEN
 
 comment "SH-Mobile System Configuration"
 
+config CPU_HAS_INTEVT
+        bool
+	default y
+
 menu "Memory configuration"
 
 config MEMORY_START
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index eff8a96..e922e92 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -42,6 +42,7 @@
 #include <video/sh_mipi_dsi.h>
 #include <sound/sh_fsi.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <mach/sh73a0.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index aab0a34..2ac08b2 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -745,26 +745,18 @@ fsi_set_rate_end:
 	return ret;
 }
 
-static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
-{
-	int ret;
-
-	if (is_porta)
-		ret = fsi_ak4642_set_rate(dev, rate, enable);
-	else
-		ret = fsi_hdmi_set_rate(dev, rate, enable);
-
-	return ret;
-}
-
 static struct sh_fsi_platform_info fsi_info = {
-	.porta_flags = SH_FSI_BRS_INV,
-
-	.portb_flags = SH_FSI_BRS_INV |
-		       SH_FSI_BRM_INV |
-		       SH_FSI_LRS_INV |
-		       SH_FSI_FMT_SPDIF,
-	.set_rate = fsi_set_rate,
+	.port_a = {
+		.flags		= SH_FSI_BRS_INV,
+		.set_rate	= fsi_ak4642_set_rate,
+	},
+	.port_b = {
+		.flags		= SH_FSI_BRS_INV |
+				  SH_FSI_BRM_INV |
+				  SH_FSI_LRS_INV |
+				  SH_FSI_FMT_SPDIF,
+		.set_rate	= fsi_hdmi_set_rate,
+	},
 };
 
 static struct resource fsi_resources[] = {
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index 4d22016..df9a653 100644
--- a/arch/arm/mach-shmobile/board-bonito.c
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -34,6 +34,7 @@
 #include <asm/mach/time.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <mach/r8a7740.h>
+#include <mach/irqs.h>
 #include <video/sh_mobile_lcdc.h>
 
 /*
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 72d5572..6dbdc42 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -33,6 +33,7 @@
 #include <linux/input.h>
 #include <linux/input/sh_keysc.h>
 #include <linux/dma-mapping.h>
+#include <mach/irqs.h>
 #include <mach/sh7367.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 2220b88..2936ccc 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -34,6 +34,7 @@
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <linux/gpio.h>
 #include <linux/dma-mapping.h>
+#include <mach/irqs.h>
 #include <mach/sh7377.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 857ceee..c71780b 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -39,6 +39,7 @@
 #include <linux/mfd/tmio.h>
 #include <linux/mmc/sh_mobile_sdhi.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <mach/sh73a0.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 9b42fbd..8004b4f 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -55,6 +55,7 @@
 #include <sound/sh_fsi.h>
 
 #include <mach/common.h>
+#include <mach/irqs.h>
 #include <mach/sh7372.h>
 
 #include <asm/mach/arch.h>
@@ -901,7 +902,7 @@ static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
 	return clk_enable(clk);
 }
 
-static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+static int fsi_b_set_rate(struct device *dev, int rate, int enable)
 {
 	struct clk *fsib_clk;
 	struct clk *fdiv_clk = &sh7372_fsidivb_clk;
@@ -910,10 +911,6 @@ static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
 	int ackmd_bpfmd;
 	int ret;
 
-	/* FSIA is slave mode. nothing to do here */
-	if (is_porta)
-		return 0;
-
 	/* clock start */
 	switch (rate) {
 	case 44100:
@@ -957,14 +954,16 @@ fsi_set_rate_end:
 }
 
 static struct sh_fsi_platform_info fsi_info = {
-	.porta_flags =	SH_FSI_BRS_INV,
-
-	.portb_flags =	SH_FSI_BRS_INV	|
+	.port_a = {
+		.flags = SH_FSI_BRS_INV,
+	},
+	.port_b = {
+		.flags = SH_FSI_BRS_INV	|
 			SH_FSI_BRM_INV	|
 			SH_FSI_LRS_INV	|
 			SH_FSI_FMT_SPDIF,
-
-	.set_rate = fsi_set_rate,
+		.set_rate = fsi_b_set_rate,
+	}
 };
 
 static struct resource fsi_resources[] = {
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index f0e02c0..3b2e88a 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -31,6 +31,7 @@
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
 #include <mach/common.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index dcb714f..4e686cc2 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -1,15 +1,11 @@
 #ifndef __ASM_MACH_IRQS_H
 #define __ASM_MACH_IRQS_H
 
-#define NR_IRQS         1024
+#include <linux/sh_intc.h>
 
 /* GIC */
 #define gic_spi(nr)		((nr) + 32)
 
-/* INTCA */
-#define evt2irq(evt)		(((evt) >> 5) - 16)
-#define irq2evt(irq)		(((irq) + 16) << 5)
-
 /* INTCS */
 #define INTCS_VECT_BASE		0x2200
 #define INTCS_VECT(n, vect)	INTC_VECT((n), INTCS_VECT_BASE + (vect))
diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h
index 956ac18..3bbcb3f 100644
--- a/arch/arm/mach-shmobile/include/mach/system.h
+++ b/arch/arm/mach-shmobile/include/mach/system.h
@@ -1,11 +1,6 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
 static inline void arch_reset(char mode, const char *cmd)
 {
 	soft_restart(0);
diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c
index 272c84c..09c42af 100644
--- a/arch/arm/mach-shmobile/intc-r8a7740.c
+++ b/arch/arm/mach-shmobile/intc-r8a7740.c
@@ -25,6 +25,7 @@
 #include <linux/io.h>
 #include <linux/sh_intc.h>
 #include <mach/intc.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
index cfde9bf..5bf7764 100644
--- a/arch/arm/mach-shmobile/intc-sh7367.c
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/sh_intc.h>
 #include <mach/intc.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index 89afcab..6447e0a 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/sh_intc.h>
 #include <mach/intc.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
index 2af4e6e..b84a460 100644
--- a/arch/arm/mach-shmobile/intc-sh7377.c
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/sh_intc.h>
 #include <mach/intc.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 1eda6b0..9a8207c 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/sh_intc.h>
 #include <mach/intc.h>
+#include <mach/irqs.h>
 #include <mach/sh73a0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 986dca6..fa15d81 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -25,6 +25,7 @@
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <mach/r8a7740.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 4725663..55df21a 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -29,6 +29,7 @@
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <mach/r8a7779.h>
 #include <mach/common.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index e546017..8e848198 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -29,6 +29,7 @@
 #include <linux/serial_sci.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index a83cf51..08d631a 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -32,6 +32,7 @@
 #include <linux/sh_timer.h>
 #include <linux/pm_domain.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <mach/sh7372.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index bb405b8..747ed8e 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -30,6 +30,7 @@
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 20e71e5..7bf740e 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -31,6 +31,7 @@
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <mach/sh73a0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h
deleted file mode 100644
index 92cee63..0000000
--- a/arch/arm/mach-spear3xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-spear3xx/include/mach/system.h
- *
- * SPEAr3xx Machine family specific architecture functions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-#include <plat/system.h>
-
-#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index a5e46b4..f7db668 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -430,18 +430,8 @@ static struct pl061_platform_data gpio1_plat_data = {
 	.irq_base	= SPEAR300_GPIO1_INT_BASE,
 };
 
-struct amba_device spear300_gpio1_device = {
-	.dev = {
-		.init_name = "gpio1",
-		.platform_data = &gpio1_plat_data,
-	},
-	.res = {
-		.start = SPEAR300_GPIO_BASE,
-		.end = SPEAR300_GPIO_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ},
-};
+AMBA_APB_DEVICE(spear300_gpio1, "gpio1", 0, SPEAR300_GPIO_BASE,
+	{SPEAR300_VIRQ_GPIO1}, &gpio1_plat_data);
 
 /* spear300 routines */
 void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
@@ -469,7 +459,7 @@ void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 	if (pmx_driver.base) {
 		ret = pmx_register(&pmx_driver);
 		if (ret)
-			printk(KERN_ERR "padmux: registeration failed. err no"
+			printk(KERN_ERR "padmux: registration failed. err no"
 					": %d\n", ret);
 		/* Free Mapping, device selection already done */
 		iounmap(pmx_driver.base);
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 9004cf9..febaa6f 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -303,6 +303,6 @@ void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 
 	ret = pmx_register(&pmx_driver);
 	if (ret)
-		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+		printk(KERN_ERR "padmux: registration failed. err no: %d\n",
 				ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index ee29bef..deaaf19 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -550,6 +550,6 @@ void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
 
 	ret = pmx_register(&pmx_driver);
 	if (ret)
-		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+		printk(KERN_ERR "padmux: registration failed. err no: %d\n",
 				ret);
 }
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 10af45d..b1733c3 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -28,31 +28,12 @@ static struct pl061_platform_data gpio_plat_data = {
 	.irq_base	= SPEAR3XX_GPIO_INT_BASE,
 };
 
-struct amba_device spear3xx_gpio_device = {
-	.dev = {
-		.init_name = "gpio",
-		.platform_data = &gpio_plat_data,
-	},
-	.res = {
-		.start = SPEAR3XX_ICM3_GPIO_BASE,
-		.end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ},
-};
+AMBA_APB_DEVICE(spear3xx_gpio, "gpio", 0, SPEAR3XX_ICM3_GPIO_BASE,
+	{SPEAR3XX_IRQ_BASIC_GPIO}, &gpio_plat_data);
 
 /* uart device registration */
-struct amba_device spear3xx_uart_device = {
-	.dev = {
-		.init_name = "uart",
-	},
-	.res = {
-		.start = SPEAR3XX_ICM1_UART_BASE,
-		.end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {SPEAR3XX_IRQ_UART, NO_IRQ},
-};
+AMBA_APB_DEVICE(spear3xx_uart, "uart", 0, SPEAR3XX_ICM1_UART_BASE,
+	{SPEAR3XX_IRQ_UART}, NULL);
 
 /* Do spear3xx familiy common initialization part here */
 void __init spear3xx_init(void)
diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h
deleted file mode 100644
index 0b1d2be..0000000
--- a/arch/arm/mach-spear6xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-spear6xx/include/mach/system.h
- *
- * SPEAr6xx Machine family specific architecture functions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Rajeev Kumar<rajeev-dlh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-#include <plat/system.h>
-
-#endif	/* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index e0f6628..b997b1b 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -34,7 +34,7 @@ struct amba_device uart_device[] = {
 			.end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {IRQ_UART_0, NO_IRQ},
+		.irq = {IRQ_UART_0},
 	}, {
 		.dev = {
 			.init_name = "uart1",
@@ -44,7 +44,7 @@ struct amba_device uart_device[] = {
 			.end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {IRQ_UART_1, NO_IRQ},
+		.irq = {IRQ_UART_1},
 	}
 };
 
@@ -73,7 +73,7 @@ struct amba_device gpio_device[] = {
 			.end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {IRQ_LOCAL_GPIO, NO_IRQ},
+		.irq = {IRQ_LOCAL_GPIO},
 	}, {
 		.dev = {
 			.init_name = "gpio1",
@@ -84,7 +84,7 @@ struct amba_device gpio_device[] = {
 			.end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {IRQ_BASIC_GPIO, NO_IRQ},
+		.irq = {IRQ_BASIC_GPIO},
 	}, {
 		.dev = {
 			.init_name = "gpio2",
@@ -95,7 +95,7 @@ struct amba_device gpio_device[] = {
 			.end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1,
 			.flags = IORESOURCE_MEM,
 		},
-		.irq = {IRQ_APPL_GPIO, NO_IRQ},
+		.irq = {IRQ_APPL_GPIO},
 	}
 };
 
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 373652d..32b420a 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -7,6 +7,8 @@ config ARCH_TEGRA_2x_SOC
 	select CPU_V7
 	select ARM_GIC
 	select ARCH_REQUIRE_GPIOLIB
+	select PINCTRL
+	select PINCTRL_TEGRA20
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
 	select USB_ULPI if USB_SUPPORT
 	select USB_ULPI_VIEWPORT if USB_SUPPORT
@@ -19,6 +21,8 @@ config ARCH_TEGRA_3x_SOC
 	select CPU_V7
 	select ARM_GIC
 	select ARCH_REQUIRE_GPIOLIB
+	select PINCTRL
+	select PINCTRL_TEGRA30
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
 	select USB_ULPI if USB_SUPPORT
 	select USB_ULPI_VIEWPORT if USB_SUPPORT
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index e120ff5..82994c0 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -7,15 +7,19 @@ obj-y                                   += clock.o
 obj-y                                   += timer.o
 obj-y                                   += pinmux.o
 obj-y					+= fuse.o
+obj-y					+= cpuidle.o
+obj-y					+= sleep.o
+obj-y					+= pmc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= powergate.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_clocks.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= tegra2_emc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pinmux-tegra20-tables.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= pinmux-tegra30-tables.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= board-dt-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= tegra30_clocks.o
 obj-$(CONFIG_SMP)                       += platsmp.o localtimer.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
-obj-$(CONFIG_TEGRA_SYSTEM_DMA)		+= dma.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA)		+= dma.o apbio.o
 obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
 obj-$(CONFIG_TEGRA_PCI)			+= pcie.o
 obj-$(CONFIG_USB_SUPPORT)		+= usb_phy.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
new file mode 100644
index 0000000..e75451e
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include <mach/dma.h>
+#include <mach/iomap.h>
+
+#include "apbio.h"
+
+static DEFINE_MUTEX(tegra_apb_dma_lock);
+
+static struct tegra_dma_channel *tegra_apb_dma;
+static u32 *tegra_apb_bb;
+static dma_addr_t tegra_apb_bb_phys;
+static DECLARE_COMPLETION(tegra_apb_wait);
+
+bool tegra_apb_init(void)
+{
+	struct tegra_dma_channel *ch;
+
+	mutex_lock(&tegra_apb_dma_lock);
+
+	/* Check to see if we raced to setup */
+	if (tegra_apb_dma)
+		goto out;
+
+	ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
+		TEGRA_DMA_SHARED);
+
+	if (!ch)
+		goto out_fail;
+
+	tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
+		&tegra_apb_bb_phys, GFP_KERNEL);
+	if (!tegra_apb_bb) {
+		pr_err("%s: can not allocate bounce buffer\n", __func__);
+		tegra_dma_free_channel(ch);
+		goto out_fail;
+	}
+
+	tegra_apb_dma = ch;
+out:
+	mutex_unlock(&tegra_apb_dma_lock);
+	return true;
+
+out_fail:
+	mutex_unlock(&tegra_apb_dma_lock);
+	return false;
+}
+
+static void apb_dma_complete(struct tegra_dma_req *req)
+{
+	complete(&tegra_apb_wait);
+}
+
+u32 tegra_apb_readl(unsigned long offset)
+{
+	struct tegra_dma_req req;
+	int ret;
+
+	if (!tegra_apb_dma && !tegra_apb_init())
+		return readl(IO_TO_VIRT(offset));
+
+	mutex_lock(&tegra_apb_dma_lock);
+	req.complete = apb_dma_complete;
+	req.to_memory = 1;
+	req.dest_addr = tegra_apb_bb_phys;
+	req.dest_bus_width = 32;
+	req.dest_wrap = 1;
+	req.source_addr = offset;
+	req.source_bus_width = 32;
+	req.source_wrap = 4;
+	req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+	req.size = 4;
+
+	INIT_COMPLETION(tegra_apb_wait);
+
+	tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+	ret = wait_for_completion_timeout(&tegra_apb_wait,
+		msecs_to_jiffies(50));
+
+	if (WARN(ret == 0, "apb read dma timed out")) {
+		tegra_dma_dequeue_req(tegra_apb_dma, &req);
+		*(u32 *)tegra_apb_bb = 0;
+	}
+
+	mutex_unlock(&tegra_apb_dma_lock);
+	return *((u32 *)tegra_apb_bb);
+}
+
+void tegra_apb_writel(u32 value, unsigned long offset)
+{
+	struct tegra_dma_req req;
+	int ret;
+
+	if (!tegra_apb_dma && !tegra_apb_init()) {
+		writel(value, IO_TO_VIRT(offset));
+		return;
+	}
+
+	mutex_lock(&tegra_apb_dma_lock);
+	*((u32 *)tegra_apb_bb) = value;
+	req.complete = apb_dma_complete;
+	req.to_memory = 0;
+	req.dest_addr = offset;
+	req.dest_wrap = 4;
+	req.dest_bus_width = 32;
+	req.source_addr = tegra_apb_bb_phys;
+	req.source_bus_width = 32;
+	req.source_wrap = 1;
+	req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+	req.size = 4;
+
+	INIT_COMPLETION(tegra_apb_wait);
+
+	tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+	ret = wait_for_completion_timeout(&tegra_apb_wait,
+		msecs_to_jiffies(50));
+
+	if (WARN(ret == 0, "apb write dma timed out"))
+		tegra_dma_dequeue_req(tegra_apb_dma, &req);
+
+	mutex_unlock(&tegra_apb_dma_lock);
+}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
new file mode 100644
index 0000000..8b49e8c
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_TEGRA_APBIO_H
+#define __MACH_TEGRA_APBIO_H
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+
+u32 tegra_apb_readl(unsigned long offset);
+void tegra_apb_writel(u32 value, unsigned long offset);
+
+#else
+#include <asm/io.h>
+#include <mach/io.h>
+
+static inline u32 tegra_apb_readl(unsigned long offset)
+{
+        return readl(IO_TO_VIRT(offset));
+}
+
+static inline void tegra_apb_writel(u32 value, unsigned long offset)
+{
+        writel(value, IO_TO_VIRT(offset));
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index 3c197e2..b4124b1 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -34,16 +34,38 @@
 #include <asm/hardware/gic.h>
 
 #include "board.h"
+#include "clock.h"
 
 static struct of_device_id tegra_dt_match_table[] __initdata = {
 	{ .compatible = "simple-bus", },
 	{}
 };
 
+struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
+	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000000, "sdhci-tegra.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000200, "sdhci-tegra.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000400, "sdhci-tegra.2", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-sdhci", 0x78000600, "sdhci-tegra.3", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C000, "tegra-i2c.0", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C400, "tegra-i2c.1", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C500, "tegra-i2c.2", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000C700, "tegra-i2c.3", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
+	{}
+};
+
+static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
+	/* name		parent		rate		enabled */
+	{ "uartd",	"pll_p",	408000000,	true },
+	{ NULL,		NULL,		0,		0},
+};
+
 static void __init tegra30_dt_init(void)
 {
+	tegra_clk_init_from_table(tegra_dt_clk_init_table);
+
 	of_platform_populate(NULL, tegra_dt_match_table,
-				NULL, NULL);
+				tegra30_auxdata_lookup, NULL);
 }
 
 static const char *tegra30_dt_board_compat[] = {
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
index 21d1285..976edfb0 100644
--- a/arch/arm/mach-tegra/board-harmony-power.c
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -18,18 +18,13 @@
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
-#include <linux/io.h>
 #include <linux/regulator/machine.h>
 #include <linux/mfd/tps6586x.h>
 
-#include <mach/iomap.h>
 #include <mach/irqs.h>
 
 #include "board-harmony.h"
 
-#define PMC_CTRL		0x0
-#define PMC_CTRL_INTR_LOW	(1 << 17)
-
 static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
 	REGULATOR_SUPPLY("pex_clk", NULL),
 };
@@ -114,16 +109,6 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
 
 int __init harmony_regulator_init(void)
 {
-	void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-	u32 pmc_ctrl;
-
-	/*
-	 * Configure the power management controller to trigger PMU
-	 * interrupts when low
-	 */
-	pmc_ctrl = readl(pmc + PMC_CTRL);
-	writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
-
 	i2c_register_board_info(3, harmony_regulators, 1);
 
 	return 0;
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 789bdc9..c00aadb 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -101,7 +101,6 @@ static struct wm8903_platform_data harmony_wm8903_pdata = {
 static struct i2c_board_info __initdata wm8903_board_info = {
 	I2C_BOARD_INFO("wm8903", 0x1a),
 	.platform_data = &harmony_wm8903_pdata,
-	.irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
 };
 
 static void __init harmony_i2c_init(void)
@@ -111,6 +110,7 @@ static void __init harmony_i2c_init(void)
 	platform_device_register(&tegra_i2c_device3);
 	platform_device_register(&tegra_i2c_device4);
 
+	wm8903_board_info.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ);
 	i2c_register_board_info(0, &wm8903_board_info, 1);
 }
 
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index ebac65f..d669847 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -159,7 +159,6 @@ static struct platform_device *seaboard_devices[] __initdata = {
 
 static struct i2c_board_info __initdata isl29018_device = {
 	I2C_BOARD_INFO("isl29018", 0x44),
-	.irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
 };
 
 static struct i2c_board_info __initdata adt7461_device = {
@@ -183,7 +182,6 @@ static struct wm8903_platform_data wm8903_pdata = {
 static struct i2c_board_info __initdata wm8903_device = {
 	I2C_BOARD_INFO("wm8903", 0x1a),
 	.platform_data = &wm8903_pdata,
-	.irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
 };
 
 static int seaboard_ehci_init(void)
@@ -214,7 +212,10 @@ static void __init seaboard_i2c_init(void)
 	gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
 	gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
 
+	isl29018_device.irq = gpio_to_irq(TEGRA_GPIO_ISL29018_IRQ);
 	i2c_register_board_info(0, &isl29018_device, 1);
+
+	wm8903_device.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ);
 	i2c_register_board_info(0, &wm8903_device, 1);
 
 	i2c_register_board_info(3, &adt7461_device, 1);
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 8337068..8dad8d1 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -399,6 +399,28 @@ void tegra_periph_reset_assert(struct clk *c)
 }
 EXPORT_SYMBOL(tegra_periph_reset_assert);
 
+/* Several extended clock configuration bits (e.g., clock routing, clock
+ * phase control) are included in PLL and peripheral clock source
+ * registers. */
+int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->spinlock, flags);
+
+	if (!c->ops || !c->ops->clk_cfg_ex) {
+		ret = -ENOSYS;
+		goto out;
+	}
+	ret = c->ops->clk_cfg_ex(c, p, setting);
+
+out:
+	spin_unlock_irqrestore(&c->spinlock, flags);
+
+	return ret;
+}
+
 #ifdef CONFIG_DEBUG_FS
 
 static int __clk_lock_all_spinlocks(void)
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 5c44106..bc30065 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -24,6 +24,8 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
+#include <mach/clk.h>
+
 #define DIV_BUS			(1 << 0)
 #define DIV_U71			(1 << 1)
 #define DIV_U71_FIXED		(1 << 2)
@@ -39,7 +41,16 @@
 #define PERIPH_MANUAL_RESET	(1 << 12)
 #define PLL_ALT_MISC_REG	(1 << 13)
 #define PLLU			(1 << 14)
+#define PLLX                    (1 << 15)
+#define MUX_PWM                 (1 << 16)
+#define MUX8                    (1 << 17)
+#define DIV_U71_UART            (1 << 18)
+#define MUX_CLK_OUT             (1 << 19)
+#define PLLM                    (1 << 20)
+#define DIV_U71_INT             (1 << 21)
+#define DIV_U71_IDLE            (1 << 22)
 #define ENABLE_ON_INIT		(1 << 28)
+#define PERIPH_ON_APB           (1 << 29)
 
 struct clk;
 
@@ -65,6 +76,8 @@ struct clk_ops {
 	int		(*set_rate)(struct clk *, unsigned long);
 	long		(*round_rate)(struct clk *, unsigned long);
 	void		(*reset)(struct clk *, bool);
+	int		(*clk_cfg_ex)(struct clk *,
+				enum tegra_clk_ex_param, u32);
 };
 
 enum clk_state {
@@ -114,6 +127,7 @@ struct clk {
 			unsigned long			vco_max;
 			const struct clk_pll_freq_table	*freq_table;
 			int				lock_delay;
+			unsigned long			fixed_rate;
 		} pll;
 		struct {
 			u32				sel;
@@ -146,6 +160,7 @@ struct tegra_clk_init_table {
 };
 
 void tegra2_init_clocks(void);
+void tegra30_init_clocks(void);
 void clk_init(struct clk *clk);
 struct clk *tegra_get_clock_by_name(const char *name);
 int clk_reparent(struct clk *c, struct clk *parent);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index a2eb901..e2a2c1f 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -27,11 +27,28 @@
 #include <asm/hardware/gic.h>
 
 #include <mach/iomap.h>
-#include <mach/system.h>
 
 #include "board.h"
 #include "clock.h"
 #include "fuse.h"
+#include "pmc.h"
+
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF)
+u32 tegra_uart_config[3] = {
+	/* Debug UART initialization required */
+	1,
+	/* Debug UART physical address */
+	(u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
+	/* Debug UART virtual address */
+	(u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
+};
 
 #ifdef CONFIG_OF
 static const struct of_device_id tegra_dt_irq_match[] __initconst = {
@@ -96,15 +113,20 @@ static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
 void __init tegra20_init_early(void)
 {
+	disable_hlt();  /* idle WFI usage needs to be confirmed */
+
 	tegra_init_fuse();
 	tegra2_init_clocks();
 	tegra_clk_init_from_table(tegra20_clk_init_table);
 	tegra_init_cache(0x331, 0x441);
+	tegra_pmc_init();
 }
 #endif
 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
 void __init tegra30_init_early(void)
 {
+	tegra30_init_clocks();
 	tegra_init_cache(0x441, 0x551);
+	tegra_pmc_init();
 }
 #endif
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
new file mode 100644
index 0000000..d83a8c0
--- /dev/null
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -0,0 +1,107 @@
+/*
+ * arch/arm/mach-tegra/cpuidle.c
+ *
+ * CPU idle driver for Tegra CPUs
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2011 Google, Inc.
+ * Author: Colin Cross <ccross@android.com>
+ *         Gary King <gking@nvidia.com>
+ *
+ * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/hrtimer.h>
+
+#include <mach/iomap.h>
+
+extern void tegra_cpu_wfi(void);
+
+static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
+				struct cpuidle_driver *drv, int index);
+
+struct cpuidle_driver tegra_idle_driver = {
+	.name = "tegra_idle",
+	.owner = THIS_MODULE,
+	.state_count = 1,
+	.states = {
+		[0] = {
+			.enter			= tegra_idle_enter_lp3,
+			.exit_latency		= 10,
+			.target_residency	= 10,
+			.power_usage		= 600,
+			.flags			= CPUIDLE_FLAG_TIME_VALID,
+			.name			= "LP3",
+			.desc			= "CPU flow-controlled",
+		},
+	},
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
+
+static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
+	struct cpuidle_driver *drv, int index)
+{
+	ktime_t enter, exit;
+	s64 us;
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	enter = ktime_get();
+
+	tegra_cpu_wfi();
+
+	exit = ktime_sub(ktime_get(), enter);
+	us = ktime_to_us(exit);
+
+	local_fiq_enable();
+	local_irq_enable();
+
+	dev->last_residency = us;
+
+	return index;
+}
+
+static int __init tegra_cpuidle_init(void)
+{
+	int ret;
+	unsigned int cpu;
+	struct cpuidle_device *dev;
+	struct cpuidle_driver *drv = &tegra_idle_driver;
+
+	ret = cpuidle_register_driver(&tegra_idle_driver);
+	if (ret) {
+		pr_err("CPUidle driver registration failed\n");
+		return ret;
+	}
+
+	for_each_possible_cpu(cpu) {
+		dev = &per_cpu(tegra_idle_device, cpu);
+		dev->cpu = cpu;
+
+		dev->state_count = drv->state_count;
+		ret = cpuidle_register_device(dev);
+		if (ret) {
+			pr_err("CPU%u: CPUidle device registration failed\n",
+				cpu);
+			return ret;
+		}
+	}
+	return 0;
+}
+device_initcall(tegra_cpuidle_init);
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index c0cf967..abea4f6 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -33,6 +33,8 @@
 #include <mach/iomap.h>
 #include <mach/suspend.h>
 
+#include "apbio.h"
+
 #define APB_DMA_GEN				0x000
 #define GEN_ENABLE				(1<<31)
 
@@ -50,8 +52,6 @@
 #define CSR_ONCE				(1<<27)
 #define CSR_FLOW				(1<<21)
 #define CSR_REQ_SEL_SHIFT			16
-#define CSR_REQ_SEL_MASK			(0x1F<<CSR_REQ_SEL_SHIFT)
-#define CSR_REQ_SEL_INVALID			(31<<CSR_REQ_SEL_SHIFT)
 #define CSR_WCOUNT_SHIFT			2
 #define CSR_WCOUNT_MASK				0xFFFC
 
@@ -133,6 +133,7 @@ struct tegra_dma_channel {
 
 static bool tegra_dma_initialized;
 static DEFINE_MUTEX(tegra_dma_lock);
+static DEFINE_SPINLOCK(enable_lock);
 
 static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
 static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
@@ -180,36 +181,94 @@ static void tegra_dma_stop(struct tegra_dma_channel *ch)
 
 static int tegra_dma_cancel(struct tegra_dma_channel *ch)
 {
-	u32 csr;
 	unsigned long irq_flags;
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
 	while (!list_empty(&ch->list))
 		list_del(ch->list.next);
 
-	csr = readl(ch->addr + APB_DMA_CHAN_CSR);
-	csr &= ~CSR_REQ_SEL_MASK;
-	csr |= CSR_REQ_SEL_INVALID;
-	writel(csr, ch->addr + APB_DMA_CHAN_CSR);
-
 	tegra_dma_stop(ch);
 
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
 	return 0;
 }
 
+static unsigned int get_channel_status(struct tegra_dma_channel *ch,
+			struct tegra_dma_req *req, bool is_stop_dma)
+{
+	void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+	unsigned int status;
+
+	if (is_stop_dma) {
+		/*
+		 * STOP the DMA and get the transfer count.
+		 * Getting the transfer count is tricky.
+		 *  - Globally disable DMA on all channels
+		 *  - Read the channel's status register to know the number
+		 *    of pending bytes to be transfered.
+		 *  - Stop the dma channel
+		 *  - Globally re-enable DMA to resume other transfers
+		 */
+		spin_lock(&enable_lock);
+		writel(0, addr + APB_DMA_GEN);
+		udelay(20);
+		status = readl(ch->addr + APB_DMA_CHAN_STA);
+		tegra_dma_stop(ch);
+		writel(GEN_ENABLE, addr + APB_DMA_GEN);
+		spin_unlock(&enable_lock);
+		if (status & STA_ISE_EOC) {
+			pr_err("Got Dma Int here clearing");
+			writel(status, ch->addr + APB_DMA_CHAN_STA);
+		}
+		req->status = TEGRA_DMA_REQ_ERROR_ABORTED;
+	} else {
+		status = readl(ch->addr + APB_DMA_CHAN_STA);
+	}
+	return status;
+}
+
+/* should be called with the channel lock held */
+static unsigned int dma_active_count(struct tegra_dma_channel *ch,
+	struct tegra_dma_req *req, unsigned int status)
+{
+	unsigned int to_transfer;
+	unsigned int req_transfer_count;
+	unsigned int bytes_transferred;
+
+	to_transfer = ((status & STA_COUNT_MASK) >> STA_COUNT_SHIFT) + 1;
+	req_transfer_count = ch->req_transfer_count + 1;
+	bytes_transferred = req_transfer_count;
+	if (status & STA_BUSY)
+		bytes_transferred -= to_transfer;
+	/*
+	 * In continuous transfer mode, DMA only tracks the count of the
+	 * half DMA buffer. So, if the DMA already finished half the DMA
+	 * then add the half buffer to the completed count.
+	 */
+	if (ch->mode & TEGRA_DMA_MODE_CONTINOUS) {
+		if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
+			bytes_transferred += req_transfer_count;
+		if (status & STA_ISE_EOC)
+			bytes_transferred += req_transfer_count;
+	}
+	bytes_transferred *= 4;
+	return bytes_transferred;
+}
+
 int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
 	struct tegra_dma_req *_req)
 {
-	unsigned int csr;
 	unsigned int status;
 	struct tegra_dma_req *req = NULL;
 	int found = 0;
 	unsigned long irq_flags;
-	int to_transfer;
-	int req_transfer_count;
+	int stop = 0;
 
 	spin_lock_irqsave(&ch->lock, irq_flags);
+
+	if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req)
+		stop = 1;
+
 	list_for_each_entry(req, &ch->list, node) {
 		if (req == _req) {
 			list_del(&req->node);
@@ -222,47 +281,12 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
 		return 0;
 	}
 
-	/* STOP the DMA and get the transfer count.
-	 * Getting the transfer count is tricky.
-	 *  - Change the source selector to invalid to stop the DMA from
-	 *    FIFO to memory.
-	 *  - Read the status register to know the number of pending
-	 *    bytes to be transferred.
-	 *  - Finally stop or program the DMA to the next buffer in the
-	 *    list.
-	 */
-	csr = readl(ch->addr + APB_DMA_CHAN_CSR);
-	csr &= ~CSR_REQ_SEL_MASK;
-	csr |= CSR_REQ_SEL_INVALID;
-	writel(csr, ch->addr + APB_DMA_CHAN_CSR);
-
-	/* Get the transfer count */
-	status = readl(ch->addr + APB_DMA_CHAN_STA);
-	to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT;
-	req_transfer_count = ch->req_transfer_count;
-	req_transfer_count += 1;
-	to_transfer += 1;
-
-	req->bytes_transferred = req_transfer_count;
-
-	if (status & STA_BUSY)
-		req->bytes_transferred -= to_transfer;
-
-	/* In continuous transfer mode, DMA only tracks the count of the
-	 * half DMA buffer. So, if the DMA already finished half the DMA
-	 * then add the half buffer to the completed count.
-	 *
-	 *	FIXME: There can be a race here. What if the req to
-	 *	dequue happens at the same time as the DMA just moved to
-	 *	the new buffer and SW didn't yet received the interrupt?
-	 */
-	if (ch->mode & TEGRA_DMA_MODE_CONTINOUS)
-		if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
-			req->bytes_transferred += req_transfer_count;
+	if (!stop)
+		goto skip_stop_dma;
 
-	req->bytes_transferred *= 4;
+	status = get_channel_status(ch, req, true);
+	req->bytes_transferred = dma_active_count(ch, req, status);
 
-	tegra_dma_stop(ch);
 	if (!list_empty(&ch->list)) {
 		/* if the list is not empty, queue the next request */
 		struct tegra_dma_req *next_req;
@@ -270,6 +294,8 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
 			typeof(*next_req), node);
 		tegra_dma_update_hw(ch, next_req);
 	}
+
+skip_stop_dma:
 	req->status = -TEGRA_DMA_REQ_ERROR_ABORTED;
 
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -357,7 +383,7 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
 	int channel;
 	struct tegra_dma_channel *ch = NULL;
 
-	if (WARN_ON(!tegra_dma_initialized))
+	if (!tegra_dma_initialized)
 		return NULL;
 
 	mutex_lock(&tegra_dma_lock);
diff --git a/arch/arm/mach-tegra/flowctrl.h b/arch/arm/mach-tegra/flowctrl.h
new file mode 100644
index 0000000..74c6efb
--- /dev/null
+++ b/arch/arm/mach-tegra/flowctrl.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-tegra/flowctrl.h
+ *
+ * functions and macros to control the flowcontroller
+ *
+ * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_FLOWCTRL_H
+#define __MACH_TEGRA_FLOWCTRL_H
+
+#define FLOW_CTRL_HALT_CPU0_EVENTS	0x0
+#define FLOW_CTRL_WAITEVENT		(2 << 29)
+#define FLOW_CTRL_WAIT_FOR_INTERRUPT	(4 << 29)
+#define FLOW_CTRL_JTAG_RESUME		(1 << 28)
+#define FLOW_CTRL_HALT_CPU_IRQ		(1 << 10)
+#define	FLOW_CTRL_HALT_CPU_FIQ		(1 << 8)
+#define FLOW_CTRL_CPU0_CSR		0x8
+#define	FLOW_CTRL_CSR_INTR_FLAG		(1 << 15)
+#define FLOW_CTRL_CSR_EVENT_FLAG	(1 << 14)
+#define FLOW_CTRL_CSR_ENABLE		(1 << 0)
+#define FLOW_CTRL_HALT_CPU1_EVENTS	0x14
+#define FLOW_CTRL_CPU1_CSR		0x18
+
+#endif
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 1fa26d9..adfa429 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -19,24 +19,75 @@
 
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <mach/iomap.h>
 
 #include "fuse.h"
+#include "apbio.h"
 
 #define FUSE_UID_LOW		0x108
 #define FUSE_UID_HIGH		0x10c
 #define FUSE_SKU_INFO		0x110
 #define FUSE_SPARE_BIT		0x200
 
-static inline u32 fuse_readl(unsigned long offset)
+int tegra_sku_id;
+int tegra_cpu_process_id;
+int tegra_core_process_id;
+enum tegra_revision tegra_revision;
+
+/* The BCT to use at boot is specified by board straps that can be read
+ * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
+ */
+int tegra_bct_strapping;
+
+#define STRAP_OPT 0x008
+#define GMI_AD0 (1 << 4)
+#define GMI_AD1 (1 << 5)
+#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
+#define RAM_CODE_SHIFT 4
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+	[TEGRA_REVISION_UNKNOWN] = "unknown",
+	[TEGRA_REVISION_A01]     = "A01",
+	[TEGRA_REVISION_A02]     = "A02",
+	[TEGRA_REVISION_A03]     = "A03",
+	[TEGRA_REVISION_A03p]    = "A03 prime",
+	[TEGRA_REVISION_A04]     = "A04",
+};
+
+static inline u32 tegra_fuse_readl(unsigned long offset)
+{
+	return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
+}
+
+static inline bool get_spare_fuse(int bit)
 {
-	return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+	return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
 }
 
-static inline void fuse_writel(u32 value, unsigned long offset)
+static enum tegra_revision tegra_get_revision(void)
 {
-	writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+	void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
+	u32 id = readl(chip_id);
+	u32 minor_rev = (id >> 16) & 0xf;
+	u32 chipid = (id >> 8) & 0xff;
+
+	switch (minor_rev) {
+	case 1:
+		return TEGRA_REVISION_A01;
+	case 2:
+		return TEGRA_REVISION_A02;
+	case 3:
+		if (chipid == 0x20 && (get_spare_fuse(18) || get_spare_fuse(19)))
+			return TEGRA_REVISION_A03p;
+		else
+			return TEGRA_REVISION_A03;
+	case 4:
+		return TEGRA_REVISION_A04;
+	default:
+		return TEGRA_REVISION_UNKNOWN;
+	}
 }
 
 void tegra_init_fuse(void)
@@ -45,40 +96,32 @@ void tegra_init_fuse(void)
 	reg |= 1 << 28;
 	writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
 
-	pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
-		tegra_sku_id(), tegra_cpu_process_id(),
-		tegra_core_process_id());
-}
+	reg = tegra_fuse_readl(FUSE_SKU_INFO);
+	tegra_sku_id = reg & 0xFF;
 
-unsigned long long tegra_chip_uid(void)
-{
-	unsigned long long lo, hi;
+	reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+	tegra_cpu_process_id = (reg >> 6) & 3;
 
-	lo = fuse_readl(FUSE_UID_LOW);
-	hi = fuse_readl(FUSE_UID_HIGH);
-	return (hi << 32ull) | lo;
-}
+	reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+	tegra_core_process_id = (reg >> 12) & 3;
 
-int tegra_sku_id(void)
-{
-	int sku_id;
-	u32 reg = fuse_readl(FUSE_SKU_INFO);
-	sku_id = reg & 0xFF;
-	return sku_id;
-}
+	reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
+	tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
 
-int tegra_cpu_process_id(void)
-{
-	int cpu_process_id;
-	u32 reg = fuse_readl(FUSE_SPARE_BIT);
-	cpu_process_id = (reg >> 6) & 3;
-	return cpu_process_id;
+	tegra_revision = tegra_get_revision();
+
+	pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+		tegra_revision_name[tegra_get_revision()],
+		tegra_sku_id, tegra_cpu_process_id,
+		tegra_core_process_id);
 }
 
-int tegra_core_process_id(void)
+unsigned long long tegra_chip_uid(void)
 {
-	int core_process_id;
-	u32 reg = fuse_readl(FUSE_SPARE_BIT);
-	core_process_id = (reg >> 12) & 3;
-	return core_process_id;
+	unsigned long long lo, hi;
+
+	lo = tegra_fuse_readl(FUSE_UID_LOW);
+	hi = tegra_fuse_readl(FUSE_UID_HIGH);
+	return (hi << 32ull) | lo;
 }
+EXPORT_SYMBOL(tegra_chip_uid);
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index 584b2e2..d65d2ab 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-tegra/fuse.c
- *
  * Copyright (C) 2010 Google, Inc.
  *
  * Author:
@@ -17,8 +15,34 @@
  *
  */
 
+#ifndef __MACH_TEGRA_FUSE_H
+#define __MACH_TEGRA_FUSE_H
+
+enum tegra_revision {
+	TEGRA_REVISION_UNKNOWN = 0,
+	TEGRA_REVISION_A01,
+	TEGRA_REVISION_A02,
+	TEGRA_REVISION_A03,
+	TEGRA_REVISION_A03p,
+	TEGRA_REVISION_A04,
+	TEGRA_REVISION_MAX,
+};
+
+#define SKU_ID_T20	8
+#define SKU_ID_T25SE	20
+#define SKU_ID_AP25	23
+#define SKU_ID_T25	24
+#define SKU_ID_AP25E	27
+#define SKU_ID_T25E	28
+
+extern int tegra_sku_id;
+extern int tegra_cpu_process_id;
+extern int tegra_core_process_id;
+extern enum tegra_revision tegra_revision;
+
+extern int tegra_bct_strapping;
+
 unsigned long long tegra_chip_uid(void);
-int tegra_sku_id(void);
-int tegra_cpu_process_id(void);
-int tegra_core_process_id(void);
 void tegra_init_fuse(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index f329404..d8dc9dd 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -13,6 +13,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 
 static inline void cpu_enter_lowpower(void)
 {
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
index fc3ecb6..d97e403 100644
--- a/arch/arm/mach-tegra/include/mach/clk.h
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -22,10 +22,20 @@
 
 struct clk;
 
+enum tegra_clk_ex_param {
+	TEGRA_CLK_VI_INP_SEL,
+	TEGRA_CLK_DTV_INVERT,
+	TEGRA_CLK_NAND_PAD_DIV2_ENB,
+	TEGRA_CLK_PLLD_CSI_OUT_ENB,
+	TEGRA_CLK_PLLD_DSI_OUT_ENB,
+	TEGRA_CLK_PLLD_MIPI_MUX_SEL,
+};
+
 void tegra_periph_reset_deassert(struct clk *c);
 void tegra_periph_reset_assert(struct clk *c);
 
 unsigned long clk_get_rate_all_locked(struct clk *c);
 void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
+int tegra_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting);
 
 #endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 619abc6..90069ab 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -1,11 +1,17 @@
 /*
  * arch/arm/mach-tegra/include/mach/debug-macro.S
  *
- * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010,2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
  *
  * Author:
  *	Colin Cross <ccross@google.com>
  *	Erik Gilling <konkers@google.com>
+ *	Doug Anderson <dianders@chromium.org>
+ *	Stephen Warren <swarren@nvidia.com>
+ *
+ * Portions based on mach-omap2's debug-macro.S
+ * Copyright (C) 1994-1999 Russell King
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -18,18 +24,78 @@
  *
  */
 
+#include <linux/serial_reg.h>
+
 #include <mach/io.h>
 #include <mach/iomap.h>
+#include <mach/irammap.h>
+
+		.macro  addruart, rp, rv, tmp
+		adr	\rp, 99f		@ actual addr of 99f
+		ldr	\rv, [\rp]		@ linked addr is stored there
+		sub	\rv, \rv, \rp		@ offset between the two
+		ldr	\rp, [\rp, #4]		@ linked tegra_uart_config
+		sub	\tmp, \rp, \rv		@ actual tegra_uart_config
+		ldr	\rp, [\tmp]		@ Load tegra_uart_config
+		cmp	\rp, #1			@ needs intitialization?
+		bne	100f			@ no; go load the addresses
+		mov	\rv, #0			@ yes; record init is done
+		str	\rv, [\tmp]
+		mov	\rp, #TEGRA_IRAM_BASE	@ See if cookie is in IRAM
+		ldr	\rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET]
+		movw	\rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff
+		movt	\rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16
+		cmp	\rv, \rp		@ Cookie present?
+		bne	100f			@ No, use default UART
+		mov	\rp, #TEGRA_IRAM_BASE	@ Load UART address from IRAM
+		ldr	\rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4]
+		str	\rv, [\tmp, #4]		@ Store in tegra_uart_phys
+		sub	\rv, \rv, #IO_APB_PHYS	@ Calculate virt address
+		add	\rv, \rv, #IO_APB_VIRT
+		str	\rv, [\tmp, #8]		@ Store in tegra_uart_virt
+		b	100f
+
+		.align
+99:		.word	.
+		.word	tegra_uart_config
+		.ltorg
+
+100:		ldr	\rp, [\tmp, #4]		@ Load tegra_uart_phys
+		ldr	\rv, [\tmp, #8]		@ Load tegra_uart_virt
+		.endm
+
+#define UART_SHIFT 2
+
+/*
+ * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
+ * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case.
+ * We use the fact that all 5 valid UART addresses all have something in the
+ * 2nd-to-lowest byte.
+ */
 
-	.macro  addruart, rp, rv, tmp
-        ldr     \rp, =IO_APB_PHYS       @ physical
-        ldr     \rv, =IO_APB_VIRT        @ virtual
-	orr	\rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
-	orr	\rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
-	orr	\rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
-	orr	\rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
-	.endm
+		.macro	senduart, rd, rx
+		tst	\rx, #0x0000ff00
+		strneb	\rd, [\rx, #UART_TX << UART_SHIFT]
+1001:
+		.endm
 
-#define UART_SHIFT	2
-#include <asm/hardware/debug-8250.S>
+		.macro	busyuart, rd, rx
+		tst	\rx, #0x0000ff00
+		beq	1002f
+1001:		ldrb	\rd, [\rx, #UART_LSR << UART_SHIFT]
+		and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+		teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
+		bne	1001b
+1002:
+		.endm
 
+		.macro	waituart, rd, rx
+#ifdef FLOW_CONTROL
+		tst	\rx, #0x0000ff00
+		beq	1002f
+1001:		ldrb	\rd, [\rx, #UART_MSR << UART_SHIFT]
+		tst	\rd, #UART_MSR_CTS
+		beq	1001b
+1002:
+#endif
+		.endm
diff --git a/arch/arm/mach-tegra/include/mach/gpio-tegra.h b/arch/arm/mach-tegra/include/mach/gpio-tegra.h
index 87d37fd..6140820 100644
--- a/arch/arm/mach-tegra/include/mach/gpio-tegra.h
+++ b/arch/arm/mach-tegra/include/mach/gpio-tegra.h
@@ -25,8 +25,6 @@
 
 #define TEGRA_NR_GPIOS		INT_GPIO_NR
 
-#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
-
 struct tegra_gpio_table {
 	int	gpio;	/* GPIO number */
 	bool	enable;	/* Enable for GPIO at init? */
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index 19dec3a..67644c9 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -74,6 +74,9 @@
 #define TEGRA_QUATERNARY_ICTLR_BASE	0x60004300
 #define TEGRA_QUATERNARY_ICTLR_SIZE	SZ_64
 
+#define TEGRA_QUINARY_ICTLR_BASE	0x60004400
+#define TEGRA_QUINARY_ICTLR_SIZE	SZ_64
+
 #define TEGRA_TMR1_BASE			0x60005000
 #define TEGRA_TMR1_SIZE			SZ_8
 
diff --git a/arch/arm/mach-tegra/include/mach/irammap.h b/arch/arm/mach-tegra/include/mach/irammap.h
new file mode 100644
index 0000000..0cbe632
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irammap.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_IRAMMAP_H
+#define __MACH_TEGRA_IRAMMAP_H
+
+#include <asm/sizes.h>
+
+/* The first 1K of IRAM is permanently reserved for the CPU reset handler */
+#define TEGRA_IRAM_RESET_HANDLER_OFFSET	0
+#define TEGRA_IRAM_RESET_HANDLER_SIZE	SZ_1K
+
+/*
+ * These locations are written to by uncompress.h, and read by debug-macro.S.
+ * The first word holds the cookie value if the data is valid. The second
+ * word holds the UART physical address.
+ */
+#define TEGRA_IRAM_DEBUG_UART_OFFSET	SZ_1K
+#define TEGRA_IRAM_DEBUG_UART_SIZE	8
+#define TEGRA_IRAM_DEBUG_UART_COOKIE	0x55415254
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index a2146cd..aad1a2c 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -165,11 +165,12 @@
 #define INT_QUAD_RES_30			(INT_QUAD_BASE + 30)
 #define INT_QUAD_RES_31			(INT_QUAD_BASE + 31)
 
-#define INT_MAIN_NR			(INT_QUAD_BASE + 32 - INT_PRI_BASE)
-
+/* Tegra30 has 5 banks of 32 IRQs */
+#define INT_MAIN_NR			(32 * 5)
 #define INT_GPIO_BASE			(INT_PRI_BASE + INT_MAIN_NR)
 
-#define INT_GPIO_NR			(28 * 8)
+/* Tegra30 has 8 banks of 32 GPIOs */
+#define INT_GPIO_NR			(32 * 8)
 
 #define TEGRA_NR_IRQS			(INT_GPIO_BASE + INT_GPIO_NR)
 
diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h
index 20bb054..a130256 100644
--- a/arch/arm/mach-tegra/include/mach/kbc.h
+++ b/arch/arm/mach-tegra/include/mach/kbc.h
@@ -24,20 +24,21 @@
 #include <linux/types.h>
 #include <linux/input/matrix_keypad.h>
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
 #define KBC_MAX_GPIO	24
 #define KBC_MAX_KPENT	8
-#else
-#define KBC_MAX_GPIO	20
-#define KBC_MAX_KPENT	7
-#endif
 
 #define KBC_MAX_ROW	16
 #define KBC_MAX_COL	8
 #define KBC_MAX_KEY	(KBC_MAX_ROW * KBC_MAX_COL)
 
+enum tegra_pin_type {
+	PIN_CFG_IGNORE,
+	PIN_CFG_COL,
+	PIN_CFG_ROW,
+};
+
 struct tegra_kbc_pin_cfg {
-	bool is_row;
+	enum tegra_pin_type type;
 	unsigned char num;
 };
 
diff --git a/arch/arm/mach-tegra/include/mach/pinconf-tegra.h b/arch/arm/mach-tegra/include/mach/pinconf-tegra.h
new file mode 100644
index 0000000..1f24d30
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinconf-tegra.h
@@ -0,0 +1,63 @@
+/*
+ * pinctrl configuration definitions for the NVIDIA Tegra pinmux
+ *
+ * Copyright (c) 2011, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#ifndef __PINCONF_TEGRA_H__
+#define __PINCONF_TEGRA_H__
+
+enum tegra_pinconf_param {
+	/* argument: tegra_pinconf_pull */
+	TEGRA_PINCONF_PARAM_PULL,
+	/* argument: tegra_pinconf_tristate */
+	TEGRA_PINCONF_PARAM_TRISTATE,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_ENABLE_INPUT,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_OPEN_DRAIN,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_LOCK,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_IORESET,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_SCHMITT,
+	/* argument: Boolean */
+	TEGRA_PINCONF_PARAM_LOW_POWER_MODE,
+	/* argument: Integer, range is HW-dependant */
+	TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH,
+	/* argument: Integer, range is HW-dependant */
+	TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH,
+	/* argument: Integer, range is HW-dependant */
+	TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING,
+	/* argument: Integer, range is HW-dependant */
+	TEGRA_PINCONF_PARAM_SLEW_RATE_RISING,
+};
+
+enum tegra_pinconf_pull {
+	TEGRA_PINCONFIG_PULL_NONE,
+	TEGRA_PINCONFIG_PULL_DOWN,
+	TEGRA_PINCONFIG_PULL_UP,
+};
+
+enum tegra_pinconf_tristate {
+	TEGRA_PINCONFIG_DRIVEN,
+	TEGRA_PINCONFIG_TRISTATE,
+};
+
+#define TEGRA_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_))
+#define TEGRA_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16)
+#define TEGRA_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff)
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h
new file mode 100644
index 0000000..dad403a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/smmu.h
@@ -0,0 +1,63 @@
+/*
+ * IOMMU API for SMMU in Tegra30
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef	MACH_SMMU_H
+#define	MACH_SMMU_H
+
+enum smmu_hwgrp {
+	HWGRP_AFI,
+	HWGRP_AVPC,
+	HWGRP_DC,
+	HWGRP_DCB,
+	HWGRP_EPP,
+	HWGRP_G2,
+	HWGRP_HC,
+	HWGRP_HDA,
+	HWGRP_ISP,
+	HWGRP_MPE,
+	HWGRP_NV,
+	HWGRP_NV2,
+	HWGRP_PPCS,
+	HWGRP_SATA,
+	HWGRP_VDE,
+	HWGRP_VI,
+
+	HWGRP_COUNT,
+
+	HWGRP_END = ~0,
+};
+
+#define HWG_AFI		(1 << HWGRP_AFI)
+#define HWG_AVPC	(1 << HWGRP_AVPC)
+#define HWG_DC		(1 << HWGRP_DC)
+#define HWG_DCB		(1 << HWGRP_DCB)
+#define HWG_EPP		(1 << HWGRP_EPP)
+#define HWG_G2		(1 << HWGRP_G2)
+#define HWG_HC		(1 << HWGRP_HC)
+#define HWG_HDA		(1 << HWGRP_HDA)
+#define HWG_ISP		(1 << HWGRP_ISP)
+#define HWG_MPE		(1 << HWGRP_MPE)
+#define HWG_NV		(1 << HWGRP_NV)
+#define HWG_NV2		(1 << HWGRP_NV2)
+#define HWG_PPCS	(1 << HWGRP_PPCS)
+#define HWG_SATA	(1 << HWGRP_SATA)
+#define HWG_VDE		(1 << HWGRP_VDE)
+#define HWG_VI		(1 << HWGRP_VI)
+
+#endif	/* MACH_SMMU_H */
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
deleted file mode 100644
index a312988..0000000
--- a/arch/arm/mach-tegra/include/mach/system.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/system.h
- *
- * Copyright (C) 2010 Google, Inc.
- *
- * Author:
- *	Colin Cross <ccross@google.com>
- *	Erik Gilling <konkers@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __MACH_TEGRA_SYSTEM_H
-#define __MACH_TEGRA_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-}
-
-#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 4e83237..b066ba0 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -2,10 +2,14 @@
  * arch/arm/mach-tegra/include/mach/uncompress.h
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
  *
  * Author:
  *	Colin Cross <ccross@google.com>
  *	Erik Gilling <konkers@google.com>
+ *	Doug Anderson <dianders@chromium.org>
+ *	Stephen Warren <swarren@nvidia.com>
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -21,40 +25,132 @@
 #ifndef __MACH_TEGRA_UNCOMPRESS_H
 #define __MACH_TEGRA_UNCOMPRESS_H
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/serial_reg.h>
 
 #include <mach/iomap.h>
+#include <mach/irammap.h>
+
+#define DEBUG_UART_SHIFT 2
+
+volatile u8 *uart;
 
 static void putc(int c)
 {
-	volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
-	int shift = 2;
-
 	if (uart == NULL)
 		return;
 
-	while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+	while (!(uart[UART_LSR << DEBUG_UART_SHIFT] & UART_LSR_THRE))
 		barrier();
-	uart[UART_TX << shift] = c;
+	uart[UART_TX << DEBUG_UART_SHIFT] = c;
 }
 
 static inline void flush(void)
 {
 }
 
+static inline void save_uart_address(void)
+{
+	u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET);
+
+	if (uart) {
+		buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE;
+		buf[1] = (u32)uart;
+	} else
+		buf[0] = 0;
+}
+
+/*
+ * Setup before decompression.  This is where we do UART selection for
+ * earlyprintk and init the uart_base register.
+ */
 static inline void arch_decomp_setup(void)
 {
-	volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
-	int shift = 2;
+	static const struct {
+		u32 base;
+		u32 reset_reg;
+		u32 clock_reg;
+		u32 bit;
+	} uarts[] = {
+		{
+			TEGRA_UARTA_BASE,
+			TEGRA_CLK_RESET_BASE + 0x04,
+			TEGRA_CLK_RESET_BASE + 0x10,
+			6,
+		},
+		{
+			TEGRA_UARTB_BASE,
+			TEGRA_CLK_RESET_BASE + 0x04,
+			TEGRA_CLK_RESET_BASE + 0x10,
+			7,
+		},
+		{
+			TEGRA_UARTC_BASE,
+			TEGRA_CLK_RESET_BASE + 0x08,
+			TEGRA_CLK_RESET_BASE + 0x14,
+			23,
+		},
+		{
+			TEGRA_UARTD_BASE,
+			TEGRA_CLK_RESET_BASE + 0x0c,
+			TEGRA_CLK_RESET_BASE + 0x18,
+			1,
+		},
+		{
+			TEGRA_UARTE_BASE,
+			TEGRA_CLK_RESET_BASE + 0x0c,
+			TEGRA_CLK_RESET_BASE + 0x18,
+			2,
+		},
+	};
+	int i;
+	volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
+	u32 chip, div;
+
+	/*
+	 * Look for the first UART that:
+	 * a) Is not in reset.
+	 * b) Is clocked.
+	 * c) Has a 'D' in the scratchpad register.
+	 *
+	 * Note that on Tegra30, the first two conditions are required, since
+	 * if not true, accesses to the UART scratch register will hang.
+	 * Tegra20 doesn't have this issue.
+	 *
+	 * The intent is that the bootloader will tell the kernel which UART
+	 * to use by setting up those conditions. If nothing found, we'll fall
+	 * back to what's specified in TEGRA_DEBUG_UART_BASE.
+	 */
+	for (i = 0; i < ARRAY_SIZE(uarts); i++) {
+		if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
+			continue;
 
+		if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
+			continue;
+
+		uart = (volatile u8 *)uarts[i].base;
+		if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
+			continue;
+
+		break;
+	}
+	if (i == ARRAY_SIZE(uarts))
+		uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+	save_uart_address();
 	if (uart == NULL)
 		return;
 
-	uart[UART_LCR << shift] |= UART_LCR_DLAB;
-	uart[UART_DLL << shift] = 0x75;
-	uart[UART_DLM << shift] = 0x0;
-	uart[UART_LCR << shift] = 3;
+	chip = (apb_misc[0x804 / 4] >> 8) & 0xff;
+	if (chip == 0x20)
+		div = 0x0075;
+	else
+		div = 0x00dd;
+
+	uart[UART_LCR << DEBUG_UART_SHIFT] |= UART_LCR_DLAB;
+	uart[UART_DLL << DEBUG_UART_SHIFT] = div & 0xff;
+	uart[UART_DLM << DEBUG_UART_SHIFT] = div >> 8;
+	uart[UART_LCR << DEBUG_UART_SHIFT] = 3;
 }
 
 static inline void arch_decomp_wdog(void)
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 4e1afcd..2f5bd2d 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -44,14 +44,16 @@
 #define ICTLR_COP_IER_CLR	0x38
 #define ICTLR_COP_IEP_CLASS	0x3c
 
-#define NUM_ICTLRS 4
 #define FIRST_LEGACY_IRQ 32
 
+static int num_ictlrs;
+
 static void __iomem *ictlr_reg_base[] = {
 	IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
 	IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
 	IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
 	IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
+	IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
 };
 
 static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
@@ -60,7 +62,7 @@ static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
 	u32 mask;
 
 	BUG_ON(irq < FIRST_LEGACY_IRQ ||
-		irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
+		irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32);
 
 	base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
 	mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
@@ -113,8 +115,18 @@ static int tegra_retrigger(struct irq_data *d)
 void __init tegra_init_irq(void)
 {
 	int i;
+	void __iomem *distbase;
+
+	distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE);
+	num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) & 0x1f;
+
+	if (num_ictlrs > ARRAY_SIZE(ictlr_reg_base)) {
+		WARN(1, "Too many (%d) interrupt controllers found. Maximum is %d.",
+			num_ictlrs, ARRAY_SIZE(ictlr_reg_base));
+		num_ictlrs = ARRAY_SIZE(ictlr_reg_base);
+	}
 
-	for (i = 0; i < NUM_ICTLRS; i++) {
+	for (i = 0; i < num_ictlrs; i++) {
 		void __iomem *ictlr = ictlr_reg_base[i];
 		writel(~0, ictlr + ICTLR_CPU_IER_CLR);
 		writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
@@ -131,6 +143,6 @@ void __init tegra_init_irq(void)
 	 * initialized elsewhere under DT.
 	 */
 	if (!of_have_populated_dt())
-		gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+		gic_init(0, 29, distbase,
 			IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
 }
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
new file mode 100644
index 0000000..7af6a54
--- /dev/null
+++ b/arch/arm/mach-tegra/pmc.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <mach/iomap.h>
+
+#define PMC_CTRL		0x0
+#define PMC_CTRL_INTR_LOW	(1 << 17)
+
+static inline u32 tegra_pmc_readl(u32 reg)
+{
+	return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+}
+
+static inline void tegra_pmc_writel(u32 val, u32 reg)
+{
+	writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id matches[] __initconst = {
+	{ .compatible = "nvidia,tegra20-pmc" },
+	{ }
+};
+#endif
+
+void __init tegra_pmc_init(void)
+{
+	/*
+	 * For now, Harmony is the only board that uses the PMC, and it wants
+	 * the signal inverted. Seaboard would too if it used the PMC.
+	 * Hopefully by the time other boards want to use the PMC, everything
+	 * will be device-tree, or they also want it inverted.
+	 */
+	bool invert_interrupt = true;
+	u32 val;
+
+#ifdef CONFIG_OF
+	if (of_have_populated_dt()) {
+		struct device_node *np;
+
+		invert_interrupt = false;
+
+		np = of_find_matching_node(NULL, matches);
+		if (np) {
+			if (of_find_property(np, "nvidia,invert-interrupt",
+						NULL))
+				invert_interrupt = true;
+		}
+	}
+#endif
+
+	val = tegra_pmc_readl(PMC_CTRL);
+	if (invert_interrupt)
+		val |= PMC_CTRL_INTR_LOW;
+	else
+		val &= ~PMC_CTRL_INTR_LOW;
+	tegra_pmc_writel(val, PMC_CTRL);
+}
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
new file mode 100644
index 0000000..8995ee4
--- /dev/null
+++ b/arch/arm/mach-tegra/pmc.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PMC_H
+#define __MACH_TEGRA_PMC_H
+
+void tegra_pmc_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S
new file mode 100644
index 0000000..8f9fde1
--- /dev/null
+++ b/arch/arm/mach-tegra/sleep.S
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mach-tegra/sleep.S
+ *
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
+ * Copyright (c) 2011, Google, Inc.
+ *
+ * Author: Colin Cross <ccross@android.com>
+ *         Gary King <gking@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/io.h>
+#include <mach/iomap.h>
+
+#include "flowctrl.h"
+
+#define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
+					+ IO_PPSB_VIRT)
+
+/* returns the offset of the flow controller halt register for a cpu */
+.macro cpu_to_halt_reg rd, rcpu
+	cmp	\rcpu, #0
+	subne	\rd, \rcpu, #1
+	movne	\rd, \rd, lsl #3
+	addne	\rd, \rd, #0x14
+	moveq	\rd, #0
+.endm
+
+/* returns the offset of the flow controller csr register for a cpu */
+.macro cpu_to_csr_reg rd, rcpu
+	cmp	\rcpu, #0
+	subne	\rd, \rcpu, #1
+	movne	\rd, \rd, lsl #3
+	addne	\rd, \rd, #0x18
+	moveq	\rd, #8
+.endm
+
+/* returns the ID of the current processor */
+.macro cpu_id, rd
+	mrc	p15, 0, \rd, c0, c0, 5
+	and	\rd, \rd, #0xF
+.endm
+
+/* loads a 32-bit value into a register without a data access */
+.macro mov32, reg, val
+	movw	\reg, #:lower16:\val
+	movt	\reg, #:upper16:\val
+.endm
+
+/*
+ * tegra_cpu_wfi
+ *
+ * puts current CPU in clock-gated wfi using the flow controller
+ *
+ * corrupts r0-r3
+ * must be called with MMU on
+ */
+
+ENTRY(tegra_cpu_wfi)
+	cpu_id	r0
+	cpu_to_halt_reg r1, r0
+	cpu_to_csr_reg r2, r0
+	mov32	r0, TEGRA_FLOW_CTRL_VIRT
+	mov	r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+	str	r3, [r0, r2]	@ clear event & interrupt status
+	mov	r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME
+	str	r3, [r0, r1]	@ put flow controller in wait irq mode
+	dsb
+	wfi
+	mov	r3, #0
+	str	r3, [r0, r1]	@ clear flow controller halt status
+	mov	r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
+	str	r3, [r0, r2]	@ clear event & interrupt status
+	dsb
+	mov	pc, lr
+ENDPROC(tegra_cpu_wfi)
+
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ff9e6b6..74d314f 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c)
 {
 	tegra2_pll_clk_init(c);
 
-	if (tegra_sku_id() == 7)
+	if (tegra_sku_id == 7)
 		c->max_rate = 750000000;
 }
 
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 0f7ae6e..5070d83 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -16,14 +16,19 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
 
 #include <mach/iomap.h>
 
 #include "tegra2_emc.h"
+#include "fuse.h"
 
 #ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
 static bool emc_enable = true;
@@ -32,18 +37,17 @@ static bool emc_enable;
 #endif
 module_param(emc_enable, bool, 0644);
 
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
 
 static inline void emc_writel(u32 val, unsigned long addr)
 {
-	writel(val, emc + addr);
+	writel(val, emc_regbase + addr);
 }
 
 static inline u32 emc_readl(unsigned long addr)
 {
-	return readl(emc + addr);
+	return readl(emc_regbase + addr);
 }
 
 static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +102,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
 /* Select the closest EMC rate that is higher than the requested rate */
 long tegra_emc_round_rate(unsigned long rate)
 {
+	struct tegra_emc_pdata *pdata;
 	int i;
 	int best = -1;
 	unsigned long distance = ULONG_MAX;
 
-	if (!tegra_emc_table)
+	if (!emc_pdev)
 		return -EINVAL;
 
-	if (!emc_enable)
-		return -EINVAL;
+	pdata = emc_pdev->dev.platform_data;
 
 	pr_debug("%s: %lu\n", __func__, rate);
 
@@ -116,10 +120,10 @@ long tegra_emc_round_rate(unsigned long rate)
 	 */
 	rate = rate / 2 / 1000;
 
-	for (i = 0; i < tegra_emc_table_size; i++) {
-		if (tegra_emc_table[i].rate >= rate &&
-		    (tegra_emc_table[i].rate - rate) < distance) {
-			distance = tegra_emc_table[i].rate - rate;
+	for (i = 0; i < pdata->num_tables; i++) {
+		if (pdata->tables[i].rate >= rate &&
+		    (pdata->tables[i].rate - rate) < distance) {
+			distance = pdata->tables[i].rate - rate;
 			best = i;
 		}
 	}
@@ -127,9 +131,9 @@ long tegra_emc_round_rate(unsigned long rate)
 	if (best < 0)
 		return -EINVAL;
 
-	pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+	pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
 
-	return tegra_emc_table[best].rate * 2 * 1000;
+	return pdata->tables[best].rate * 2 * 1000;
 }
 
 /*
@@ -142,37 +146,211 @@ long tegra_emc_round_rate(unsigned long rate)
  */
 int tegra_emc_set_rate(unsigned long rate)
 {
+	struct tegra_emc_pdata *pdata;
 	int i;
 	int j;
 
-	if (!tegra_emc_table)
+	if (!emc_pdev)
 		return -EINVAL;
 
+	pdata = emc_pdev->dev.platform_data;
+
 	/*
 	 * The EMC clock rate is twice the bus rate, and the bus rate is
 	 * measured in kHz
 	 */
 	rate = rate / 2 / 1000;
 
-	for (i = 0; i < tegra_emc_table_size; i++)
-		if (tegra_emc_table[i].rate == rate)
+	for (i = 0; i < pdata->num_tables; i++)
+		if (pdata->tables[i].rate == rate)
 			break;
 
-	if (i >= tegra_emc_table_size)
+	if (i >= pdata->num_tables)
 		return -EINVAL;
 
 	pr_debug("%s: setting to %lu\n", __func__, rate);
 
 	for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
-		emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+		emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
 
-	emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+	emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
 
 	return 0;
 }
 
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+#ifdef CONFIG_OF
+static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
+{
+	struct device_node *iter;
+	u32 reg;
+
+	for_each_child_of_node(np, iter) {
+		if (of_property_read_u32(np, "nvidia,ram-code", &reg))
+			continue;
+		if (reg == tegra_bct_strapping)
+			return of_node_get(iter);
+	}
+
+	return NULL;
+}
+
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+		struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *tnp, *iter;
+	struct tegra_emc_pdata *pdata;
+	int ret, i, num_tables;
+
+	if (!np)
+		return NULL;
+
+	if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
+		tnp = tegra_emc_ramcode_devnode(np);
+		if (!tnp)
+			dev_warn(&pdev->dev,
+				 "can't find emc table for ram-code 0x%02x\n",
+				 tegra_bct_strapping);
+	} else
+		tnp = of_node_get(np);
+
+	if (!tnp)
+		return NULL;
+
+	num_tables = 0;
+	for_each_child_of_node(tnp, iter)
+		if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
+			num_tables++;
+
+	if (!num_tables) {
+		pdata = NULL;
+		goto out;
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	pdata->tables = devm_kzalloc(&pdev->dev,
+				     sizeof(*pdata->tables) * num_tables,
+				     GFP_KERNEL);
+
+	i = 0;
+	for_each_child_of_node(tnp, iter) {
+		u32 prop;
+
+		ret = of_property_read_u32(iter, "clock-frequency", &prop);
+		if (ret) {
+			dev_err(&pdev->dev, "no clock-frequency in %s\n",
+				iter->full_name);
+			continue;
+		}
+		pdata->tables[i].rate = prop;
+
+		ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
+						 pdata->tables[i].regs,
+						 TEGRA_EMC_NUM_REGS);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"malformed emc-registers property in %s\n",
+				iter->full_name);
+			continue;
+		}
+
+		i++;
+	}
+	pdata->num_tables = i;
+
+out:
+	of_node_put(tnp);
+	return pdata;
+}
+#else
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+		struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
+static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
+{
+	struct clk *c = clk_get_sys(NULL, "emc");
+	struct tegra_emc_pdata *pdata;
+	unsigned long khz;
+	int i;
+
+	WARN_ON(pdev->dev.platform_data);
+	BUG_ON(IS_ERR_OR_NULL(c));
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables),
+				     GFP_KERNEL);
+
+	pdata->tables[0].rate = clk_get_rate(c) / 2 / 1000;
+
+	for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
+		pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
+
+	pdata->num_tables = 1;
+
+	khz = pdata->tables[0].rate;
+	dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, "
+		 "%ld kHz mem\n", khz * 2, khz);
+
+	return pdata;
+}
+
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+	struct tegra_emc_pdata *pdata;
+	struct resource *res;
+
+	if (!emc_enable) {
+		dev_err(&pdev->dev, "disabled per module parameter\n");
+		return -ENODEV;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "missing register base\n");
+		return -ENOMEM;
+	}
+
+	emc_regbase = devm_request_and_ioremap(&pdev->dev, res);
+	if (!emc_regbase) {
+		dev_err(&pdev->dev, "failed to remap registers\n");
+		return -ENOMEM;
+	}
+
+	pdata = pdev->dev.platform_data;
+
+	if (!pdata)
+		pdata = tegra_emc_dt_parse_pdata(pdev);
+
+	if (!pdata)
+		pdata = tegra_emc_fill_pdata(pdev);
+
+	pdev->dev.platform_data = pdata;
+
+	emc_pdev = pdev;
+
+	return 0;
+}
+
+static struct of_device_id tegra_emc_of_match[] __devinitdata = {
+	{ .compatible = "nvidia,tegra20-emc", },
+	{ },
+};
+
+static struct platform_driver tegra_emc_driver = {
+	.driver         = {
+		.name   = "tegra-emc",
+		.owner  = THIS_MODULE,
+		.of_match_table = tegra_emc_of_match,
+	},
+	.probe          = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
 {
-	tegra_emc_table = table;
-	tegra_emc_table_size = table_size;
+	return platform_driver_register(&tegra_emc_driver);
 }
+device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
index 19f08cb..f61409b 100644
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -15,13 +15,10 @@
  *
  */
 
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
-	unsigned long rate;
-	u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
 
 int tegra_emc_set_rate(unsigned long rate);
 long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
new file mode 100644
index 0000000..6d08b53
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra30_clocks.c
@@ -0,0 +1,3099 @@
+/*
+ * arch/arm/mach-tegra/tegra30_clocks.c
+ *
+ * Copyright (c) 2010-2011 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/iomap.h>
+
+#include "clock.h"
+#include "fuse.h"
+
+#define USE_PLL_LOCK_BITS 0
+
+#define RST_DEVICES_L			0x004
+#define RST_DEVICES_H			0x008
+#define RST_DEVICES_U			0x00C
+#define RST_DEVICES_V			0x358
+#define RST_DEVICES_W			0x35C
+#define RST_DEVICES_SET_L		0x300
+#define RST_DEVICES_CLR_L		0x304
+#define RST_DEVICES_SET_V		0x430
+#define RST_DEVICES_CLR_V		0x434
+#define RST_DEVICES_NUM			5
+
+#define CLK_OUT_ENB_L			0x010
+#define CLK_OUT_ENB_H			0x014
+#define CLK_OUT_ENB_U			0x018
+#define CLK_OUT_ENB_V			0x360
+#define CLK_OUT_ENB_W			0x364
+#define CLK_OUT_ENB_SET_L		0x320
+#define CLK_OUT_ENB_CLR_L		0x324
+#define CLK_OUT_ENB_SET_V		0x440
+#define CLK_OUT_ENB_CLR_V		0x444
+#define CLK_OUT_ENB_NUM			5
+
+#define RST_DEVICES_V_SWR_CPULP_RST_DIS	(0x1 << 1)
+#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN	(0x1 << 1)
+
+#define PERIPH_CLK_TO_BIT(c)		(1 << (c->u.periph.clk_num % 32))
+#define PERIPH_CLK_TO_RST_REG(c)	\
+	periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4)
+#define PERIPH_CLK_TO_RST_SET_REG(c)	\
+	periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8)
+#define PERIPH_CLK_TO_RST_CLR_REG(c)	\
+	periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8)
+
+#define PERIPH_CLK_TO_ENB_REG(c)	\
+	periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4)
+#define PERIPH_CLK_TO_ENB_SET_REG(c)	\
+	periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8)
+#define PERIPH_CLK_TO_ENB_CLR_REG(c)	\
+	periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8)
+
+#define CLK_MASK_ARM			0x44
+#define MISC_CLK_ENB			0x48
+
+#define OSC_CTRL			0x50
+#define OSC_CTRL_OSC_FREQ_MASK		(0xF<<28)
+#define OSC_CTRL_OSC_FREQ_13MHZ		(0x0<<28)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ	(0x4<<28)
+#define OSC_CTRL_OSC_FREQ_12MHZ		(0x8<<28)
+#define OSC_CTRL_OSC_FREQ_26MHZ		(0xC<<28)
+#define OSC_CTRL_OSC_FREQ_16_8MHZ	(0x1<<28)
+#define OSC_CTRL_OSC_FREQ_38_4MHZ	(0x5<<28)
+#define OSC_CTRL_OSC_FREQ_48MHZ		(0x9<<28)
+#define OSC_CTRL_MASK			(0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+
+#define OSC_CTRL_PLL_REF_DIV_MASK	(3<<26)
+#define OSC_CTRL_PLL_REF_DIV_1		(0<<26)
+#define OSC_CTRL_PLL_REF_DIV_2		(1<<26)
+#define OSC_CTRL_PLL_REF_DIV_4		(2<<26)
+
+#define OSC_FREQ_DET			0x58
+#define OSC_FREQ_DET_TRIG		(1<<31)
+
+#define OSC_FREQ_DET_STATUS		0x5C
+#define OSC_FREQ_DET_BUSY		(1<<31)
+#define OSC_FREQ_DET_CNT_MASK		0xFFFF
+
+#define PERIPH_CLK_SOURCE_I2S1		0x100
+#define PERIPH_CLK_SOURCE_EMC		0x19c
+#define PERIPH_CLK_SOURCE_OSC		0x1fc
+#define PERIPH_CLK_SOURCE_NUM1 \
+	((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
+
+#define PERIPH_CLK_SOURCE_G3D2		0x3b0
+#define PERIPH_CLK_SOURCE_SE		0x42c
+#define PERIPH_CLK_SOURCE_NUM2 \
+	((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1)
+
+#define AUDIO_DLY_CLK			0x49c
+#define AUDIO_SYNC_CLK_SPDIF		0x4b4
+#define PERIPH_CLK_SOURCE_NUM3 \
+	((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1)
+
+#define PERIPH_CLK_SOURCE_NUM		(PERIPH_CLK_SOURCE_NUM1 + \
+					 PERIPH_CLK_SOURCE_NUM2 + \
+					 PERIPH_CLK_SOURCE_NUM3)
+
+#define CPU_SOFTRST_CTRL		0x380
+
+#define PERIPH_CLK_SOURCE_DIVU71_MASK	0xFF
+#define PERIPH_CLK_SOURCE_DIVU16_MASK	0xFFFF
+#define PERIPH_CLK_SOURCE_DIV_SHIFT	0
+#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT	8
+#define PERIPH_CLK_SOURCE_DIVIDLE_VAL	50
+#define PERIPH_CLK_UART_DIV_ENB		(1<<24)
+#define PERIPH_CLK_VI_SEL_EX_SHIFT	24
+#define PERIPH_CLK_VI_SEL_EX_MASK	(0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT)
+#define PERIPH_CLK_NAND_DIV_EX_ENB	(1<<8)
+#define PERIPH_CLK_DTV_POLARITY_INV	(1<<25)
+
+#define AUDIO_SYNC_SOURCE_MASK		0x0F
+#define AUDIO_SYNC_DISABLE_BIT		0x10
+#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c)	((c->reg_shift - 24) * 4)
+
+#define PLL_BASE			0x0
+#define PLL_BASE_BYPASS			(1<<31)
+#define PLL_BASE_ENABLE			(1<<30)
+#define PLL_BASE_REF_ENABLE		(1<<29)
+#define PLL_BASE_OVERRIDE		(1<<28)
+#define PLL_BASE_LOCK			(1<<27)
+#define PLL_BASE_DIVP_MASK		(0x7<<20)
+#define PLL_BASE_DIVP_SHIFT		20
+#define PLL_BASE_DIVN_MASK		(0x3FF<<8)
+#define PLL_BASE_DIVN_SHIFT		8
+#define PLL_BASE_DIVM_MASK		(0x1F)
+#define PLL_BASE_DIVM_SHIFT		0
+
+#define PLL_OUT_RATIO_MASK		(0xFF<<8)
+#define PLL_OUT_RATIO_SHIFT		8
+#define PLL_OUT_OVERRIDE		(1<<2)
+#define PLL_OUT_CLKEN			(1<<1)
+#define PLL_OUT_RESET_DISABLE		(1<<0)
+
+#define PLL_MISC(c)			\
+	(((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+#define PLL_MISC_LOCK_ENABLE(c)	\
+	(((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18))
+
+#define PLL_MISC_DCCON_SHIFT		20
+#define PLL_MISC_CPCON_SHIFT		8
+#define PLL_MISC_CPCON_MASK		(0xF<<PLL_MISC_CPCON_SHIFT)
+#define PLL_MISC_LFCON_SHIFT		4
+#define PLL_MISC_LFCON_MASK		(0xF<<PLL_MISC_LFCON_SHIFT)
+#define PLL_MISC_VCOCON_SHIFT		0
+#define PLL_MISC_VCOCON_MASK		(0xF<<PLL_MISC_VCOCON_SHIFT)
+#define PLLD_MISC_CLKENABLE		(1<<30)
+
+#define PLLU_BASE_POST_DIV		(1<<20)
+
+#define PLLD_BASE_DSIB_MUX_SHIFT	25
+#define PLLD_BASE_DSIB_MUX_MASK		(1<<PLLD_BASE_DSIB_MUX_SHIFT)
+#define PLLD_BASE_CSI_CLKENABLE		(1<<26)
+#define PLLD_MISC_DSI_CLKENABLE		(1<<30)
+#define PLLD_MISC_DIV_RST		(1<<23)
+#define PLLD_MISC_DCCON_SHIFT		12
+
+#define PLLDU_LFCON_SET_DIVN		600
+
+/* FIXME: OUT_OF_TABLE_CPCON per pll */
+#define OUT_OF_TABLE_CPCON		0x8
+
+#define SUPER_CLK_MUX			0x00
+#define SUPER_STATE_SHIFT		28
+#define SUPER_STATE_MASK		(0xF << SUPER_STATE_SHIFT)
+#define SUPER_STATE_STANDBY		(0x0 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IDLE		(0x1 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_RUN			(0x2 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IRQ			(0x3 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_FIQ			(0x4 << SUPER_STATE_SHIFT)
+#define SUPER_LP_DIV2_BYPASS		(0x1 << 16)
+#define SUPER_SOURCE_MASK		0xF
+#define	SUPER_FIQ_SOURCE_SHIFT		12
+#define	SUPER_IRQ_SOURCE_SHIFT		8
+#define	SUPER_RUN_SOURCE_SHIFT		4
+#define	SUPER_IDLE_SOURCE_SHIFT		0
+
+#define SUPER_CLK_DIVIDER		0x04
+#define SUPER_CLOCK_DIV_U71_SHIFT	16
+#define SUPER_CLOCK_DIV_U71_MASK	(0xff << SUPER_CLOCK_DIV_U71_SHIFT)
+/* guarantees safe cpu backup */
+#define SUPER_CLOCK_DIV_U71_MIN		0x2
+
+#define BUS_CLK_DISABLE			(1<<3)
+#define BUS_CLK_DIV_MASK		0x3
+
+#define PMC_CTRL			0x0
+ #define PMC_CTRL_BLINK_ENB		(1 << 7)
+
+#define PMC_DPD_PADS_ORIDE		0x1c
+ #define PMC_DPD_PADS_ORIDE_BLINK_ENB	(1 << 20)
+
+#define PMC_BLINK_TIMER_DATA_ON_SHIFT	0
+#define PMC_BLINK_TIMER_DATA_ON_MASK	0x7fff
+#define PMC_BLINK_TIMER_ENB		(1 << 15)
+#define PMC_BLINK_TIMER_DATA_OFF_SHIFT	16
+#define PMC_BLINK_TIMER_DATA_OFF_MASK	0xffff
+
+#define PMC_PLLP_WB0_OVERRIDE				0xf8
+#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE		(1 << 12)
+
+#define UTMIP_PLL_CFG2					0x488
+#define UTMIP_PLL_CFG2_STABLE_COUNT(x)			(((x) & 0xfff) << 6)
+#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x)		(((x) & 0x3f) << 18)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN	(1 << 0)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN	(1 << 2)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN	(1 << 4)
+
+#define UTMIP_PLL_CFG1					0x484
+#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x)		(((x) & 0x1f) << 27)
+#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x)		(((x) & 0xfff) << 0)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN	(1 << 14)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN	(1 << 12)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN		(1 << 16)
+
+#define PLLE_BASE_CML_ENABLE		(1<<31)
+#define PLLE_BASE_ENABLE		(1<<30)
+#define PLLE_BASE_DIVCML_SHIFT		24
+#define PLLE_BASE_DIVCML_MASK		(0xf<<PLLE_BASE_DIVCML_SHIFT)
+#define PLLE_BASE_DIVP_SHIFT		16
+#define PLLE_BASE_DIVP_MASK		(0x3f<<PLLE_BASE_DIVP_SHIFT)
+#define PLLE_BASE_DIVN_SHIFT		8
+#define PLLE_BASE_DIVN_MASK		(0xFF<<PLLE_BASE_DIVN_SHIFT)
+#define PLLE_BASE_DIVM_SHIFT		0
+#define PLLE_BASE_DIVM_MASK		(0xFF<<PLLE_BASE_DIVM_SHIFT)
+#define PLLE_BASE_DIV_MASK		\
+	(PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \
+	 PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK)
+#define PLLE_BASE_DIV(m, n, p, cml)		\
+	 (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \
+	  ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT))
+
+#define PLLE_MISC_SETUP_BASE_SHIFT	16
+#define PLLE_MISC_SETUP_BASE_MASK	(0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT)
+#define PLLE_MISC_READY			(1<<15)
+#define PLLE_MISC_LOCK			(1<<11)
+#define PLLE_MISC_LOCK_ENABLE		(1<<9)
+#define PLLE_MISC_SETUP_EX_SHIFT	2
+#define PLLE_MISC_SETUP_EX_MASK		(0x3<<PLLE_MISC_SETUP_EX_SHIFT)
+#define PLLE_MISC_SETUP_MASK		\
+	  (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK)
+#define PLLE_MISC_SETUP_VALUE		\
+	  ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT))
+
+#define PLLE_SS_CTRL			0x68
+#define	PLLE_SS_INCINTRV_SHIFT		24
+#define	PLLE_SS_INCINTRV_MASK		(0x3f<<PLLE_SS_INCINTRV_SHIFT)
+#define	PLLE_SS_INC_SHIFT		16
+#define	PLLE_SS_INC_MASK		(0xff<<PLLE_SS_INC_SHIFT)
+#define	PLLE_SS_MAX_SHIFT		0
+#define	PLLE_SS_MAX_MASK		(0x1ff<<PLLE_SS_MAX_SHIFT)
+#define PLLE_SS_COEFFICIENTS_MASK	\
+	(PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
+#define PLLE_SS_COEFFICIENTS_12MHZ	\
+	((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
+	 (0x24<<PLLE_SS_MAX_SHIFT))
+#define PLLE_SS_DISABLE			((1<<12) | (1<<11) | (1<<10))
+
+#define PLLE_AUX			0x48c
+#define PLLE_AUX_PLLP_SEL		(1<<2)
+#define PLLE_AUX_CML_SATA_ENABLE	(1<<1)
+#define PLLE_AUX_CML_PCIE_ENABLE	(1<<0)
+
+#define	PMC_SATA_PWRGT			0x1ac
+#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE	(1<<5)
+#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL	(1<<4)
+
+#define ROUND_DIVIDER_UP	0
+#define ROUND_DIVIDER_DOWN	1
+
+/* FIXME: recommended safety delay after lock is detected */
+#define PLL_POST_LOCK_DELAY		100
+
+/**
+* Structure defining the fields for USB UTMI clocks Parameters.
+*/
+struct utmi_clk_param {
+	/* Oscillator Frequency in KHz */
+	u32 osc_frequency;
+	/* UTMIP PLL Enable Delay Count  */
+	u8 enable_delay_count;
+	/* UTMIP PLL Stable count */
+	u8 stable_count;
+	/*  UTMIP PLL Active delay count */
+	u8 active_delay_count;
+	/* UTMIP PLL Xtal frequency count */
+	u8 xtal_freq_count;
+};
+
+static const struct utmi_clk_param utmi_parameters[] = {
+	{
+		.osc_frequency = 13000000,
+		.enable_delay_count = 0x02,
+		.stable_count = 0x33,
+		.active_delay_count = 0x05,
+		.xtal_freq_count = 0x7F
+	},
+	{
+		.osc_frequency = 19200000,
+		.enable_delay_count = 0x03,
+		.stable_count = 0x4B,
+		.active_delay_count = 0x06,
+		.xtal_freq_count = 0xBB},
+	{
+		.osc_frequency = 12000000,
+		.enable_delay_count = 0x02,
+		.stable_count = 0x2F,
+		.active_delay_count = 0x04,
+		.xtal_freq_count = 0x76
+	},
+	{
+		.osc_frequency = 26000000,
+		.enable_delay_count = 0x04,
+		.stable_count = 0x66,
+		.active_delay_count = 0x09,
+		.xtal_freq_count = 0xFE
+	},
+	{
+		.osc_frequency = 16800000,
+		.enable_delay_count = 0x03,
+		.stable_count = 0x41,
+		.active_delay_count = 0x0A,
+		.xtal_freq_count = 0xA4
+	},
+};
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
+
+#define MISC_GP_HIDREV                  0x804
+
+/*
+ * Some peripheral clocks share an enable bit, so refcount the enable bits
+ * in registers CLK_ENABLE_L, ... CLK_ENABLE_W
+ */
+static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
+
+#define clk_writel(value, reg) \
+	__raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+	__raw_readl((u32)reg_clk_base + (reg))
+#define pmc_writel(value, reg) \
+	__raw_writel(value, (u32)reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+	__raw_readl((u32)reg_pmc_base + (reg))
+#define chipid_readl() \
+	__raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
+
+#define clk_writel_delay(value, reg)					\
+	do {								\
+		__raw_writel((value), (u32)reg_clk_base + (reg));	\
+		udelay(2);						\
+	} while (0)
+
+
+static inline int clk_set_div(struct clk *c, u32 n)
+{
+	return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
+}
+
+static inline u32 periph_clk_to_reg(
+	struct clk *c, u32 reg_L, u32 reg_V, int offs)
+{
+	u32 reg = c->u.periph.clk_num / 32;
+	BUG_ON(reg >= RST_DEVICES_NUM);
+	if (reg < 3)
+		reg = reg_L + (reg * offs);
+	else
+		reg = reg_V + ((reg - 3) * offs);
+	return reg;
+}
+
+static unsigned long clk_measure_input_freq(void)
+{
+	u32 clock_autodetect;
+	clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
+	do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+	clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
+	if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
+		return 12000000;
+	} else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
+		return 13000000;
+	} else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
+		return 19200000;
+	} else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
+		return 26000000;
+	} else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) {
+		return 16800000;
+	} else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) {
+		return 38400000;
+	} else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) {
+		return 48000000;
+	} else {
+		pr_err("%s: Unexpected clock autodetect value %d", __func__,
+			clock_autodetect);
+		BUG();
+		return 0;
+	}
+}
+
+static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate,
+				 u32 flags, u32 round_mode)
+{
+	s64 divider_u71 = parent_rate;
+	if (!rate)
+		return -EINVAL;
+
+	if (!(flags & DIV_U71_INT))
+		divider_u71 *= 2;
+	if (round_mode == ROUND_DIVIDER_UP)
+		divider_u71 += rate - 1;
+	do_div(divider_u71, rate);
+	if (flags & DIV_U71_INT)
+		divider_u71 *= 2;
+
+	if (divider_u71 - 2 < 0)
+		return 0;
+
+	if (divider_u71 - 2 > 255)
+		return -EINVAL;
+
+	return divider_u71 - 2;
+}
+
+static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+	s64 divider_u16;
+
+	divider_u16 = parent_rate;
+	if (!rate)
+		return -EINVAL;
+	divider_u16 += rate - 1;
+	do_div(divider_u16, rate);
+
+	if (divider_u16 - 1 < 0)
+		return 0;
+
+	if (divider_u16 - 1 > 0xFFFF)
+		return -EINVAL;
+
+	return divider_u16 - 1;
+}
+
+/* clk_m functions */
+static unsigned long tegra30_clk_m_autodetect_rate(struct clk *c)
+{
+	u32 osc_ctrl = clk_readl(OSC_CTRL);
+	u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
+	u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
+
+	c->rate = clk_measure_input_freq();
+	switch (c->rate) {
+	case 12000000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+		break;
+	case 13000000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+		break;
+	case 19200000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+		break;
+	case 26000000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+		break;
+	case 16800000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+		break;
+	case 38400000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
+		break;
+	case 48000000:
+		auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ;
+		BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
+		break;
+	default:
+		pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
+		BUG();
+	}
+	clk_writel(auto_clock_control, OSC_CTRL);
+	return c->rate;
+}
+
+static void tegra30_clk_m_init(struct clk *c)
+{
+	pr_debug("%s on clock %s\n", __func__, c->name);
+	tegra30_clk_m_autodetect_rate(c);
+}
+
+static int tegra30_clk_m_enable(struct clk *c)
+{
+	pr_debug("%s on clock %s\n", __func__, c->name);
+	return 0;
+}
+
+static void tegra30_clk_m_disable(struct clk *c)
+{
+	pr_debug("%s on clock %s\n", __func__, c->name);
+	WARN(1, "Attempting to disable main SoC clock\n");
+}
+
+static struct clk_ops tegra_clk_m_ops = {
+	.init		= tegra30_clk_m_init,
+	.enable		= tegra30_clk_m_enable,
+	.disable	= tegra30_clk_m_disable,
+};
+
+static struct clk_ops tegra_clk_m_div_ops = {
+	.enable		= tegra30_clk_m_enable,
+};
+
+/* PLL reference divider functions */
+static void tegra30_pll_ref_init(struct clk *c)
+{
+	u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	switch (pll_ref_div) {
+	case OSC_CTRL_PLL_REF_DIV_1:
+		c->div = 1;
+		break;
+	case OSC_CTRL_PLL_REF_DIV_2:
+		c->div = 2;
+		break;
+	case OSC_CTRL_PLL_REF_DIV_4:
+		c->div = 4;
+		break;
+	default:
+		pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div);
+		BUG();
+	}
+	c->mul = 1;
+	c->state = ON;
+}
+
+static struct clk_ops tegra_pll_ref_ops = {
+	.init		= tegra30_pll_ref_init,
+	.enable		= tegra30_clk_m_enable,
+	.disable	= tegra30_clk_m_disable,
+};
+
+/* super clock functions */
+/* "super clocks" on tegra30 have two-stage muxes, fractional 7.1 divider and
+ * clock skipping super divider.  We will ignore the clock skipping divider,
+ * since we can't lower the voltage when using the clock skip, but we can if
+ * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock
+ * only when its parent is a fixed rate PLL, since we can't change PLL rate
+ * in this case.
+ */
+static void tegra30_super_clk_init(struct clk *c)
+{
+	u32 val;
+	int source;
+	int shift;
+	const struct clk_mux_sel *sel;
+	val = clk_readl(c->reg + SUPER_CLK_MUX);
+	c->state = ON;
+	BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+		((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+	shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+		SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+	source = (val >> shift) & SUPER_SOURCE_MASK;
+	if (c->flags & DIV_2)
+		source |= val & SUPER_LP_DIV2_BYPASS;
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->value == source)
+			break;
+	}
+	BUG_ON(sel->input == NULL);
+	c->parent = sel->input;
+
+	if (c->flags & DIV_U71) {
+		/* Init safe 7.1 divider value (does not affect PLLX path) */
+		clk_writel(SUPER_CLOCK_DIV_U71_MIN << SUPER_CLOCK_DIV_U71_SHIFT,
+			   c->reg + SUPER_CLK_DIVIDER);
+		c->mul = 2;
+		c->div = 2;
+		if (!(c->parent->flags & PLLX))
+			c->div += SUPER_CLOCK_DIV_U71_MIN;
+	} else
+		clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
+}
+
+static int tegra30_super_clk_enable(struct clk *c)
+{
+	return 0;
+}
+
+static void tegra30_super_clk_disable(struct clk *c)
+{
+	/* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and
+	   geared up g-mode super clock - mode switch may request to disable
+	   either of them; accept request with no affect on h/w */
+}
+
+static int tegra30_super_clk_set_parent(struct clk *c, struct clk *p)
+{
+	u32 val;
+	const struct clk_mux_sel *sel;
+	int shift;
+
+	val = clk_readl(c->reg + SUPER_CLK_MUX);
+	BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+		((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+	shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+		SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->input == p) {
+			/* For LP mode super-clock switch between PLLX direct
+			   and divided-by-2 outputs is allowed only when other
+			   than PLLX clock source is current parent */
+			if ((c->flags & DIV_2) && (p->flags & PLLX) &&
+			    ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) {
+				if (c->parent->flags & PLLX)
+					return -EINVAL;
+				val ^= SUPER_LP_DIV2_BYPASS;
+				clk_writel_delay(val, c->reg);
+			}
+			val &= ~(SUPER_SOURCE_MASK << shift);
+			val |= (sel->value & SUPER_SOURCE_MASK) << shift;
+
+			/* 7.1 divider for CPU super-clock does not affect
+			   PLLX path */
+			if (c->flags & DIV_U71) {
+				u32 div = 0;
+				if (!(p->flags & PLLX)) {
+					div = clk_readl(c->reg +
+							SUPER_CLK_DIVIDER);
+					div &= SUPER_CLOCK_DIV_U71_MASK;
+					div >>= SUPER_CLOCK_DIV_U71_SHIFT;
+				}
+				c->div = div + 2;
+				c->mul = 2;
+			}
+
+			if (c->refcnt)
+				clk_enable(p);
+
+			clk_writel_delay(val, c->reg);
+
+			if (c->refcnt && c->parent)
+				clk_disable(c->parent);
+
+			clk_reparent(c, p);
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+/*
+ * Do not use super clocks "skippers", since dividing using a clock skipper
+ * does not allow the voltage to be scaled down. Instead adjust the rate of
+ * the parent clock. This requires that the parent of a super clock have no
+ * other children, otherwise the rate will change underneath the other
+ * children. Special case: if fixed rate PLL is CPU super clock parent the
+ * rate of this PLL can't be changed, and it has many other children. In
+ * this case use 7.1 fractional divider to adjust the super clock rate.
+ */
+static int tegra30_super_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) {
+		int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate,
+					rate, c->flags, ROUND_DIVIDER_DOWN);
+		div = max(div, SUPER_CLOCK_DIV_U71_MIN);
+
+		clk_writel(div << SUPER_CLOCK_DIV_U71_SHIFT,
+			   c->reg + SUPER_CLK_DIVIDER);
+		c->div = div + 2;
+		c->mul = 2;
+		return 0;
+	}
+	return clk_set_rate(c->parent, rate);
+}
+
+static struct clk_ops tegra_super_ops = {
+	.init			= tegra30_super_clk_init,
+	.enable			= tegra30_super_clk_enable,
+	.disable		= tegra30_super_clk_disable,
+	.set_parent		= tegra30_super_clk_set_parent,
+	.set_rate		= tegra30_super_clk_set_rate,
+};
+
+static int tegra30_twd_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	/* The input value 'rate' is the clock rate of the CPU complex. */
+	c->rate = (rate * c->mul) / c->div;
+	return 0;
+}
+
+static struct clk_ops tegra30_twd_ops = {
+	.set_rate	= tegra30_twd_clk_set_rate,
+};
+
+/* Blink output functions */
+
+static void tegra30_blink_clk_init(struct clk *c)
+{
+	u32 val;
+
+	val = pmc_readl(PMC_CTRL);
+	c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
+	c->mul = 1;
+	val = pmc_readl(c->reg);
+
+	if (val & PMC_BLINK_TIMER_ENB) {
+		unsigned int on_off;
+
+		on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
+			PMC_BLINK_TIMER_DATA_ON_MASK;
+		val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+		val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+		on_off += val;
+		/* each tick in the blink timer is 4 32KHz clocks */
+		c->div = on_off * 4;
+	} else {
+		c->div = 1;
+	}
+}
+
+static int tegra30_blink_clk_enable(struct clk *c)
+{
+	u32 val;
+
+	val = pmc_readl(PMC_DPD_PADS_ORIDE);
+	pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+
+	val = pmc_readl(PMC_CTRL);
+	pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+	return 0;
+}
+
+static void tegra30_blink_clk_disable(struct clk *c)
+{
+	u32 val;
+
+	val = pmc_readl(PMC_CTRL);
+	pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+	val = pmc_readl(PMC_DPD_PADS_ORIDE);
+	pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+}
+
+static int tegra30_blink_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(c->parent);
+	if (rate >= parent_rate) {
+		c->div = 1;
+		pmc_writel(0, c->reg);
+	} else {
+		unsigned int on_off;
+		u32 val;
+
+		on_off = DIV_ROUND_UP(parent_rate / 8, rate);
+		c->div = on_off * 8;
+
+		val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
+			PMC_BLINK_TIMER_DATA_ON_SHIFT;
+		on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+		on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+		val |= on_off;
+		val |= PMC_BLINK_TIMER_ENB;
+		pmc_writel(val, c->reg);
+	}
+
+	return 0;
+}
+
+static struct clk_ops tegra_blink_clk_ops = {
+	.init			= &tegra30_blink_clk_init,
+	.enable			= &tegra30_blink_clk_enable,
+	.disable		= &tegra30_blink_clk_disable,
+	.set_rate		= &tegra30_blink_clk_set_rate,
+};
+
+/* PLL Functions */
+static int tegra30_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg,
+					 u32 lock_bit)
+{
+#if USE_PLL_LOCK_BITS
+	int i;
+	for (i = 0; i < c->u.pll.lock_delay; i++) {
+		if (clk_readl(lock_reg) & lock_bit) {
+			udelay(PLL_POST_LOCK_DELAY);
+			return 0;
+		}
+		udelay(2);		/* timeout = 2 * lock time */
+	}
+	pr_err("Timed out waiting for lock bit on pll %s", c->name);
+	return -1;
+#endif
+	udelay(c->u.pll.lock_delay);
+
+	return 0;
+}
+
+
+static void tegra30_utmi_param_configure(struct clk *c)
+{
+	u32 reg;
+	int i;
+	unsigned long main_rate =
+		clk_get_rate(c->parent->parent);
+
+	for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
+		if (main_rate == utmi_parameters[i].osc_frequency)
+			break;
+	}
+
+	if (i >= ARRAY_SIZE(utmi_parameters)) {
+		pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate);
+		return;
+	}
+
+	reg = clk_readl(UTMIP_PLL_CFG2);
+
+	/* Program UTMIP PLL stable and active counts */
+	/* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
+	reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
+	reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
+			utmi_parameters[i].stable_count);
+
+	reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
+
+	reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
+			utmi_parameters[i].active_delay_count);
+
+	/* Remove power downs from UTMIP PLL control bits */
+	reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
+	reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
+	reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
+
+	clk_writel(reg, UTMIP_PLL_CFG2);
+
+	/* Program UTMIP PLL delay and oscillator frequency counts */
+	reg = clk_readl(UTMIP_PLL_CFG1);
+	reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
+
+	reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
+		utmi_parameters[i].enable_delay_count);
+
+	reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
+	reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
+		utmi_parameters[i].xtal_freq_count);
+
+	/* Remove power downs from UTMIP PLL control bits */
+	reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+	reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
+	reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
+
+	clk_writel(reg, UTMIP_PLL_CFG1);
+}
+
+static void tegra30_pll_clk_init(struct clk *c)
+{
+	u32 val = clk_readl(c->reg + PLL_BASE);
+
+	c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+
+	if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+		const struct clk_pll_freq_table *sel;
+		unsigned long input_rate = clk_get_rate(c->parent);
+		for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+			if (sel->input_rate == input_rate &&
+				sel->output_rate == c->u.pll.fixed_rate) {
+				c->mul = sel->n;
+				c->div = sel->m * sel->p;
+				return;
+			}
+		}
+		pr_err("Clock %s has unknown fixed frequency\n", c->name);
+		BUG();
+	} else if (val & PLL_BASE_BYPASS) {
+		c->mul = 1;
+		c->div = 1;
+	} else {
+		c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+		c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+		if (c->flags & PLLU)
+			c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+		else
+			c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
+					PLL_BASE_DIVP_SHIFT));
+		if (c->flags & PLL_FIXED) {
+			unsigned long rate = clk_get_rate_locked(c);
+			BUG_ON(rate != c->u.pll.fixed_rate);
+		}
+	}
+
+	if (c->flags & PLLU)
+		tegra30_utmi_param_configure(c);
+}
+
+static int tegra30_pll_clk_enable(struct clk *c)
+{
+	u32 val;
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+#if USE_PLL_LOCK_BITS
+	val = clk_readl(c->reg + PLL_MISC(c));
+	val |= PLL_MISC_LOCK_ENABLE(c);
+	clk_writel(val, c->reg + PLL_MISC(c));
+#endif
+	val = clk_readl(c->reg + PLL_BASE);
+	val &= ~PLL_BASE_BYPASS;
+	val |= PLL_BASE_ENABLE;
+	clk_writel(val, c->reg + PLL_BASE);
+
+	if (c->flags & PLLM) {
+		val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+		val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+		pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
+	}
+
+	tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK);
+
+	return 0;
+}
+
+static void tegra30_pll_clk_disable(struct clk *c)
+{
+	u32 val;
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	val = clk_readl(c->reg);
+	val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+	clk_writel(val, c->reg);
+
+	if (c->flags & PLLM) {
+		val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+		val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+		pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
+	}
+}
+
+static int tegra30_pll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	u32 val, p_div, old_base;
+	unsigned long input_rate;
+	const struct clk_pll_freq_table *sel;
+	struct clk_pll_freq_table cfg;
+
+	pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+	if (c->flags & PLL_FIXED) {
+		int ret = 0;
+		if (rate != c->u.pll.fixed_rate) {
+			pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
+			       __func__, c->name, c->u.pll.fixed_rate, rate);
+			ret = -EINVAL;
+		}
+		return ret;
+	}
+
+	if (c->flags & PLLM) {
+		if (rate != clk_get_rate_locked(c)) {
+			pr_err("%s: Can not change memory %s rate in flight\n",
+			       __func__, c->name);
+			return -EINVAL;
+		}
+		return 0;
+	}
+
+	p_div = 0;
+	input_rate = clk_get_rate(c->parent);
+
+	/* Check if the target rate is tabulated */
+	for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+		if (sel->input_rate == input_rate && sel->output_rate == rate) {
+			if (c->flags & PLLU) {
+				BUG_ON(sel->p < 1 || sel->p > 2);
+				if (sel->p == 1)
+					p_div = PLLU_BASE_POST_DIV;
+			} else {
+				BUG_ON(sel->p < 1);
+				for (val = sel->p; val > 1; val >>= 1)
+					p_div++;
+				p_div <<= PLL_BASE_DIVP_SHIFT;
+			}
+			break;
+		}
+	}
+
+	/* Configure out-of-table rate */
+	if (sel->input_rate == 0) {
+		unsigned long cfreq;
+		BUG_ON(c->flags & PLLU);
+		sel = &cfg;
+
+		switch (input_rate) {
+		case 12000000:
+		case 26000000:
+			cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
+			break;
+		case 13000000:
+			cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
+			break;
+		case 16800000:
+		case 19200000:
+			cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
+			break;
+		default:
+			pr_err("%s: Unexpected reference rate %lu\n",
+			       __func__, input_rate);
+			BUG();
+		}
+
+		/* Raise VCO to guarantee 0.5% accuracy */
+		for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
+		      cfg.output_rate <<= 1)
+			p_div++;
+
+		cfg.p = 0x1 << p_div;
+		cfg.m = input_rate / cfreq;
+		cfg.n = cfg.output_rate / cfreq;
+		cfg.cpcon = OUT_OF_TABLE_CPCON;
+
+		if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
+		    (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
+		    (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
+		    (cfg.output_rate > c->u.pll.vco_max)) {
+			pr_err("%s: Failed to set %s out-of-table rate %lu\n",
+			       __func__, c->name, rate);
+			return -EINVAL;
+		}
+		p_div <<= PLL_BASE_DIVP_SHIFT;
+	}
+
+	c->mul = sel->n;
+	c->div = sel->m * sel->p;
+
+	old_base = val = clk_readl(c->reg + PLL_BASE);
+	val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
+		 ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
+	val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
+		(sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
+	if (val == old_base)
+		return 0;
+
+	if (c->state == ON) {
+		tegra30_pll_clk_disable(c);
+		val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+	}
+	clk_writel(val, c->reg + PLL_BASE);
+
+	if (c->flags & PLL_HAS_CPCON) {
+		val = clk_readl(c->reg + PLL_MISC(c));
+		val &= ~PLL_MISC_CPCON_MASK;
+		val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
+		if (c->flags & (PLLU | PLLD)) {
+			val &= ~PLL_MISC_LFCON_MASK;
+			if (sel->n >= PLLDU_LFCON_SET_DIVN)
+				val |= 0x1 << PLL_MISC_LFCON_SHIFT;
+		} else if (c->flags & (PLLX | PLLM)) {
+			val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
+			if (rate >= (c->u.pll.vco_max >> 1))
+				val |= 0x1 << PLL_MISC_DCCON_SHIFT;
+		}
+		clk_writel(val, c->reg + PLL_MISC(c));
+	}
+
+	if (c->state == ON)
+		tegra30_pll_clk_enable(c);
+
+	return 0;
+}
+
+static struct clk_ops tegra_pll_ops = {
+	.init			= tegra30_pll_clk_init,
+	.enable			= tegra30_pll_clk_enable,
+	.disable		= tegra30_pll_clk_disable,
+	.set_rate		= tegra30_pll_clk_set_rate,
+};
+
+static int
+tegra30_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+	u32 val, mask, reg;
+
+	switch (p) {
+	case TEGRA_CLK_PLLD_CSI_OUT_ENB:
+		mask = PLLD_BASE_CSI_CLKENABLE;
+		reg = c->reg + PLL_BASE;
+		break;
+	case TEGRA_CLK_PLLD_DSI_OUT_ENB:
+		mask = PLLD_MISC_DSI_CLKENABLE;
+		reg = c->reg + PLL_MISC(c);
+		break;
+	case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
+		if (!(c->flags & PLL_ALT_MISC_REG)) {
+			mask = PLLD_BASE_DSIB_MUX_MASK;
+			reg = c->reg + PLL_BASE;
+			break;
+		}
+	/* fall through - error since PLLD2 does not have MUX_SEL control */
+	default:
+		return -EINVAL;
+	}
+
+	val = clk_readl(reg);
+	if (setting)
+		val |= mask;
+	else
+		val &= ~mask;
+	clk_writel(val, reg);
+	return 0;
+}
+
+static struct clk_ops tegra_plld_ops = {
+	.init			= tegra30_pll_clk_init,
+	.enable			= tegra30_pll_clk_enable,
+	.disable		= tegra30_pll_clk_disable,
+	.set_rate		= tegra30_pll_clk_set_rate,
+	.clk_cfg_ex		= tegra30_plld_clk_cfg_ex,
+};
+
+static void tegra30_plle_clk_init(struct clk *c)
+{
+	u32 val;
+
+	val = clk_readl(PLLE_AUX);
+	c->parent = (val & PLLE_AUX_PLLP_SEL) ?
+		tegra_get_clock_by_name("pll_p") :
+		tegra_get_clock_by_name("pll_ref");
+
+	val = clk_readl(c->reg + PLL_BASE);
+	c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
+	c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
+	c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
+	c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
+}
+
+static void tegra30_plle_clk_disable(struct clk *c)
+{
+	u32 val;
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	val = clk_readl(c->reg + PLL_BASE);
+	val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+	clk_writel(val, c->reg + PLL_BASE);
+}
+
+static void tegra30_plle_training(struct clk *c)
+{
+	u32 val;
+
+	/* PLLE is already disabled, and setup cleared;
+	 * create falling edge on PLLE IDDQ input */
+	val = pmc_readl(PMC_SATA_PWRGT);
+	val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+	pmc_writel(val, PMC_SATA_PWRGT);
+
+	val = pmc_readl(PMC_SATA_PWRGT);
+	val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+	pmc_writel(val, PMC_SATA_PWRGT);
+
+	val = pmc_readl(PMC_SATA_PWRGT);
+	val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+	pmc_writel(val, PMC_SATA_PWRGT);
+
+	do {
+		val = clk_readl(c->reg + PLL_MISC(c));
+	} while (!(val & PLLE_MISC_READY));
+}
+
+static int tegra30_plle_configure(struct clk *c, bool force_training)
+{
+	u32 val;
+	const struct clk_pll_freq_table *sel;
+	unsigned long rate = c->u.pll.fixed_rate;
+	unsigned long input_rate = clk_get_rate(c->parent);
+
+	for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+		if (sel->input_rate == input_rate && sel->output_rate == rate)
+			break;
+	}
+
+	if (sel->input_rate == 0)
+		return -ENOSYS;
+
+	/* disable PLLE, clear setup fiels */
+	tegra30_plle_clk_disable(c);
+
+	val = clk_readl(c->reg + PLL_MISC(c));
+	val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
+	clk_writel(val, c->reg + PLL_MISC(c));
+
+	/* training */
+	val = clk_readl(c->reg + PLL_MISC(c));
+	if (force_training || (!(val & PLLE_MISC_READY)))
+		tegra30_plle_training(c);
+
+	/* configure dividers, setup, disable SS */
+	val = clk_readl(c->reg + PLL_BASE);
+	val &= ~PLLE_BASE_DIV_MASK;
+	val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon);
+	clk_writel(val, c->reg + PLL_BASE);
+	c->mul = sel->n;
+	c->div = sel->m * sel->p;
+
+	val = clk_readl(c->reg + PLL_MISC(c));
+	val |= PLLE_MISC_SETUP_VALUE;
+	val |= PLLE_MISC_LOCK_ENABLE;
+	clk_writel(val, c->reg + PLL_MISC(c));
+
+	val = clk_readl(PLLE_SS_CTRL);
+	val |= PLLE_SS_DISABLE;
+	clk_writel(val, PLLE_SS_CTRL);
+
+	/* enable and lock PLLE*/
+	val = clk_readl(c->reg + PLL_BASE);
+	val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+	clk_writel(val, c->reg + PLL_BASE);
+
+	tegra30_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK);
+
+	return 0;
+}
+
+static int tegra30_plle_clk_enable(struct clk *c)
+{
+	pr_debug("%s on clock %s\n", __func__, c->name);
+	return tegra30_plle_configure(c, !c->set);
+}
+
+static struct clk_ops tegra_plle_ops = {
+	.init			= tegra30_plle_clk_init,
+	.enable			= tegra30_plle_clk_enable,
+	.disable		= tegra30_plle_clk_disable,
+};
+
+/* Clock divider ops */
+static void tegra30_pll_div_clk_init(struct clk *c)
+{
+	if (c->flags & DIV_U71) {
+		u32 divu71;
+		u32 val = clk_readl(c->reg);
+		val >>= c->reg_shift;
+		c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
+		if (!(val & PLL_OUT_RESET_DISABLE))
+			c->state = OFF;
+
+		divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+		c->div = (divu71 + 2);
+		c->mul = 2;
+	} else if (c->flags & DIV_2) {
+		c->state = ON;
+		if (c->flags & (PLLD | PLLX)) {
+			c->div = 2;
+			c->mul = 1;
+		} else
+			BUG();
+	} else {
+		c->state = ON;
+		c->div = 1;
+		c->mul = 1;
+	}
+}
+
+static int tegra30_pll_div_clk_enable(struct clk *c)
+{
+	u32 val;
+	u32 new_val;
+
+	pr_debug("%s: %s\n", __func__, c->name);
+	if (c->flags & DIV_U71) {
+		val = clk_readl(c->reg);
+		new_val = val >> c->reg_shift;
+		new_val &= 0xFFFF;
+
+		new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
+
+		val &= ~(0xFFFF << c->reg_shift);
+		val |= new_val << c->reg_shift;
+		clk_writel_delay(val, c->reg);
+		return 0;
+	} else if (c->flags & DIV_2) {
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static void tegra30_pll_div_clk_disable(struct clk *c)
+{
+	u32 val;
+	u32 new_val;
+
+	pr_debug("%s: %s\n", __func__, c->name);
+	if (c->flags & DIV_U71) {
+		val = clk_readl(c->reg);
+		new_val = val >> c->reg_shift;
+		new_val &= 0xFFFF;
+
+		new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
+
+		val &= ~(0xFFFF << c->reg_shift);
+		val |= new_val << c->reg_shift;
+		clk_writel_delay(val, c->reg);
+	}
+}
+
+static int tegra30_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	u32 val;
+	u32 new_val;
+	int divider_u71;
+	unsigned long parent_rate = clk_get_rate(c->parent);
+
+	pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+	if (c->flags & DIV_U71) {
+		divider_u71 = clk_div71_get_divider(
+			parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+		if (divider_u71 >= 0) {
+			val = clk_readl(c->reg);
+			new_val = val >> c->reg_shift;
+			new_val &= 0xFFFF;
+			if (c->flags & DIV_U71_FIXED)
+				new_val |= PLL_OUT_OVERRIDE;
+			new_val &= ~PLL_OUT_RATIO_MASK;
+			new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
+
+			val &= ~(0xFFFF << c->reg_shift);
+			val |= new_val << c->reg_shift;
+			clk_writel_delay(val, c->reg);
+			c->div = divider_u71 + 2;
+			c->mul = 2;
+			return 0;
+		}
+	} else if (c->flags & DIV_2)
+		return clk_set_rate(c->parent, rate * 2);
+
+	return -EINVAL;
+}
+
+static long tegra30_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
+{
+	int divider;
+	unsigned long parent_rate = clk_get_rate(c->parent);
+	pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+	if (c->flags & DIV_U71) {
+		divider = clk_div71_get_divider(
+			parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+		if (divider < 0)
+			return divider;
+		return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+	} else if (c->flags & DIV_2)
+		/* no rounding - fixed DIV_2 dividers pass rate to parent PLL */
+		return rate;
+
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_pll_div_ops = {
+	.init			= tegra30_pll_div_clk_init,
+	.enable			= tegra30_pll_div_clk_enable,
+	.disable		= tegra30_pll_div_clk_disable,
+	.set_rate		= tegra30_pll_div_clk_set_rate,
+	.round_rate		= tegra30_pll_div_clk_round_rate,
+};
+
+/* Periph clk ops */
+static inline u32 periph_clk_source_mask(struct clk *c)
+{
+	if (c->flags & MUX8)
+		return 7 << 29;
+	else if (c->flags & MUX_PWM)
+		return 3 << 28;
+	else if (c->flags & MUX_CLK_OUT)
+		return 3 << (c->u.periph.clk_num + 4);
+	else if (c->flags & PLLD)
+		return PLLD_BASE_DSIB_MUX_MASK;
+	else
+		return 3 << 30;
+}
+
+static inline u32 periph_clk_source_shift(struct clk *c)
+{
+	if (c->flags & MUX8)
+		return 29;
+	else if (c->flags & MUX_PWM)
+		return 28;
+	else if (c->flags & MUX_CLK_OUT)
+		return c->u.periph.clk_num + 4;
+	else if (c->flags & PLLD)
+		return PLLD_BASE_DSIB_MUX_SHIFT;
+	else
+		return 30;
+}
+
+static void tegra30_periph_clk_init(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	const struct clk_mux_sel *mux = 0;
+	const struct clk_mux_sel *sel;
+	if (c->flags & MUX) {
+		for (sel = c->inputs; sel->input != NULL; sel++) {
+			if (((val & periph_clk_source_mask(c)) >>
+			    periph_clk_source_shift(c)) == sel->value)
+				mux = sel;
+		}
+		BUG_ON(!mux);
+
+		c->parent = mux->input;
+	} else {
+		c->parent = c->inputs[0].input;
+	}
+
+	if (c->flags & DIV_U71) {
+		u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
+		if ((c->flags & DIV_U71_UART) &&
+		    (!(val & PERIPH_CLK_UART_DIV_ENB))) {
+			divu71 = 0;
+		}
+		if (c->flags & DIV_U71_IDLE) {
+			val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
+				PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+			val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
+				PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+			clk_writel(val, c->reg);
+		}
+		c->div = divu71 + 2;
+		c->mul = 2;
+	} else if (c->flags & DIV_U16) {
+		u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+		c->div = divu16 + 1;
+		c->mul = 1;
+	} else {
+		c->div = 1;
+		c->mul = 1;
+	}
+
+	c->state = ON;
+	if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
+		c->state = OFF;
+	if (!(c->flags & PERIPH_NO_RESET))
+		if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
+			c->state = OFF;
+}
+
+static int tegra30_periph_clk_enable(struct clk *c)
+{
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
+	if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
+		return 0;
+
+	clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c));
+	if (!(c->flags & PERIPH_NO_RESET) &&
+		 !(c->flags & PERIPH_MANUAL_RESET)) {
+		if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) &
+			 PERIPH_CLK_TO_BIT(c)) {
+			udelay(5);	/* reset propagation delay */
+			clk_writel(PERIPH_CLK_TO_BIT(c),
+				 PERIPH_CLK_TO_RST_CLR_REG(c));
+		}
+	}
+	return 0;
+}
+
+static void tegra30_periph_clk_disable(struct clk *c)
+{
+	unsigned long val;
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	if (c->refcnt)
+		tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+
+	if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
+		/* If peripheral is in the APB bus then read the APB bus to
+		 * flush the write operation in apb bus. This will avoid the
+		 * peripheral access after disabling clock*/
+		if (c->flags & PERIPH_ON_APB)
+			val = chipid_readl();
+
+		clk_writel_delay(
+			PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
+	}
+}
+
+static void tegra30_periph_clk_reset(struct clk *c, bool assert)
+{
+	unsigned long val;
+	pr_debug("%s %s on clock %s\n", __func__,
+		 assert ? "assert" : "deassert", c->name);
+
+	if (!(c->flags & PERIPH_NO_RESET)) {
+		if (assert) {
+			/* If peripheral is in the APB bus then read the APB
+			 * bus to flush the write operation in apb bus. This
+			 * will avoid the peripheral access after disabling
+			 * clock */
+			if (c->flags & PERIPH_ON_APB)
+				val = chipid_readl();
+
+			clk_writel(PERIPH_CLK_TO_BIT(c),
+				   PERIPH_CLK_TO_RST_SET_REG(c));
+		} else
+			clk_writel(PERIPH_CLK_TO_BIT(c),
+				   PERIPH_CLK_TO_RST_CLR_REG(c));
+	}
+}
+
+static int tegra30_periph_clk_set_parent(struct clk *c, struct clk *p)
+{
+	u32 val;
+	const struct clk_mux_sel *sel;
+	pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+	if (!(c->flags & MUX))
+		return (p == c->parent) ? 0 : (-EINVAL);
+
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->input == p) {
+			val = clk_readl(c->reg);
+			val &= ~periph_clk_source_mask(c);
+			val |= (sel->value << periph_clk_source_shift(c));
+
+			if (c->refcnt)
+				clk_enable(p);
+
+			clk_writel_delay(val, c->reg);
+
+			if (c->refcnt && c->parent)
+				clk_disable(c->parent);
+
+			clk_reparent(c, p);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int tegra30_periph_clk_set_rate(struct clk *c, unsigned long rate)
+{
+	u32 val;
+	int divider;
+	unsigned long parent_rate = clk_get_rate(c->parent);
+
+	if (c->flags & DIV_U71) {
+		divider = clk_div71_get_divider(
+			parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+		if (divider >= 0) {
+			val = clk_readl(c->reg);
+			val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
+			val |= divider;
+			if (c->flags & DIV_U71_UART) {
+				if (divider)
+					val |= PERIPH_CLK_UART_DIV_ENB;
+				else
+					val &= ~PERIPH_CLK_UART_DIV_ENB;
+			}
+			clk_writel_delay(val, c->reg);
+			c->div = divider + 2;
+			c->mul = 2;
+			return 0;
+		}
+	} else if (c->flags & DIV_U16) {
+		divider = clk_div16_get_divider(parent_rate, rate);
+		if (divider >= 0) {
+			val = clk_readl(c->reg);
+			val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+			val |= divider;
+			clk_writel_delay(val, c->reg);
+			c->div = divider + 1;
+			c->mul = 1;
+			return 0;
+		}
+	} else if (parent_rate <= rate) {
+		c->div = 1;
+		c->mul = 1;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static long tegra30_periph_clk_round_rate(struct clk *c,
+	unsigned long rate)
+{
+	int divider;
+	unsigned long parent_rate = clk_get_rate(c->parent);
+	pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+	if (c->flags & DIV_U71) {
+		divider = clk_div71_get_divider(
+			parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+		if (divider < 0)
+			return divider;
+
+		return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+	} else if (c->flags & DIV_U16) {
+		divider = clk_div16_get_divider(parent_rate, rate);
+		if (divider < 0)
+			return divider;
+		return DIV_ROUND_UP(parent_rate, divider + 1);
+	}
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_periph_clk_ops = {
+	.init			= &tegra30_periph_clk_init,
+	.enable			= &tegra30_periph_clk_enable,
+	.disable		= &tegra30_periph_clk_disable,
+	.set_parent		= &tegra30_periph_clk_set_parent,
+	.set_rate		= &tegra30_periph_clk_set_rate,
+	.round_rate		= &tegra30_periph_clk_round_rate,
+	.reset			= &tegra30_periph_clk_reset,
+};
+
+
+/* Periph extended clock configuration ops */
+static int
+tegra30_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+	if (p == TEGRA_CLK_VI_INP_SEL) {
+		u32 val = clk_readl(c->reg);
+		val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
+		val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) &
+			PERIPH_CLK_VI_SEL_EX_MASK;
+		clk_writel(val, c->reg);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_vi_clk_ops = {
+	.init			= &tegra30_periph_clk_init,
+	.enable			= &tegra30_periph_clk_enable,
+	.disable		= &tegra30_periph_clk_disable,
+	.set_parent		= &tegra30_periph_clk_set_parent,
+	.set_rate		= &tegra30_periph_clk_set_rate,
+	.round_rate		= &tegra30_periph_clk_round_rate,
+	.clk_cfg_ex		= &tegra30_vi_clk_cfg_ex,
+	.reset			= &tegra30_periph_clk_reset,
+};
+
+static int
+tegra30_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+	if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
+		u32 val = clk_readl(c->reg);
+		if (setting)
+			val |= PERIPH_CLK_NAND_DIV_EX_ENB;
+		else
+			val &= ~PERIPH_CLK_NAND_DIV_EX_ENB;
+		clk_writel(val, c->reg);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_nand_clk_ops = {
+	.init			= &tegra30_periph_clk_init,
+	.enable			= &tegra30_periph_clk_enable,
+	.disable		= &tegra30_periph_clk_disable,
+	.set_parent		= &tegra30_periph_clk_set_parent,
+	.set_rate		= &tegra30_periph_clk_set_rate,
+	.round_rate		= &tegra30_periph_clk_round_rate,
+	.clk_cfg_ex		= &tegra30_nand_clk_cfg_ex,
+	.reset			= &tegra30_periph_clk_reset,
+};
+
+
+static int
+tegra30_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+	if (p == TEGRA_CLK_DTV_INVERT) {
+		u32 val = clk_readl(c->reg);
+		if (setting)
+			val |= PERIPH_CLK_DTV_POLARITY_INV;
+		else
+			val &= ~PERIPH_CLK_DTV_POLARITY_INV;
+		clk_writel(val, c->reg);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_dtv_clk_ops = {
+	.init			= &tegra30_periph_clk_init,
+	.enable			= &tegra30_periph_clk_enable,
+	.disable		= &tegra30_periph_clk_disable,
+	.set_parent		= &tegra30_periph_clk_set_parent,
+	.set_rate		= &tegra30_periph_clk_set_rate,
+	.round_rate		= &tegra30_periph_clk_round_rate,
+	.clk_cfg_ex		= &tegra30_dtv_clk_cfg_ex,
+	.reset			= &tegra30_periph_clk_reset,
+};
+
+static int tegra30_dsib_clk_set_parent(struct clk *c, struct clk *p)
+{
+	const struct clk_mux_sel *sel;
+	struct clk *d = tegra_get_clock_by_name("pll_d");
+
+	pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->input == p) {
+			if (c->refcnt)
+				clk_enable(p);
+
+			/* The DSIB parent selection bit is in PLLD base
+			   register - can not do direct r-m-w, must be
+			   protected by PLLD lock */
+			tegra_clk_cfg_ex(
+				d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value);
+
+			if (c->refcnt && c->parent)
+				clk_disable(c->parent);
+
+			clk_reparent(c, p);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_dsib_clk_ops = {
+	.init			= &tegra30_periph_clk_init,
+	.enable			= &tegra30_periph_clk_enable,
+	.disable		= &tegra30_periph_clk_disable,
+	.set_parent		= &tegra30_dsib_clk_set_parent,
+	.set_rate		= &tegra30_periph_clk_set_rate,
+	.round_rate		= &tegra30_periph_clk_round_rate,
+	.reset			= &tegra30_periph_clk_reset,
+};
+
+/* pciex clock support only reset function */
+static struct clk_ops tegra_pciex_clk_ops = {
+	.reset    = tegra30_periph_clk_reset,
+};
+
+/* Output clock ops */
+
+static DEFINE_SPINLOCK(clk_out_lock);
+
+static void tegra30_clk_out_init(struct clk *c)
+{
+	const struct clk_mux_sel *mux = 0;
+	const struct clk_mux_sel *sel;
+	u32 val = pmc_readl(c->reg);
+
+	c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
+	c->mul = 1;
+	c->div = 1;
+
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (((val & periph_clk_source_mask(c)) >>
+		     periph_clk_source_shift(c)) == sel->value)
+			mux = sel;
+	}
+	BUG_ON(!mux);
+	c->parent = mux->input;
+}
+
+static int tegra30_clk_out_enable(struct clk *c)
+{
+	u32 val;
+	unsigned long flags;
+
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	spin_lock_irqsave(&clk_out_lock, flags);
+	val = pmc_readl(c->reg);
+	val |= (0x1 << c->u.periph.clk_num);
+	pmc_writel(val, c->reg);
+	spin_unlock_irqrestore(&clk_out_lock, flags);
+
+	return 0;
+}
+
+static void tegra30_clk_out_disable(struct clk *c)
+{
+	u32 val;
+	unsigned long flags;
+
+	pr_debug("%s on clock %s\n", __func__, c->name);
+
+	spin_lock_irqsave(&clk_out_lock, flags);
+	val = pmc_readl(c->reg);
+	val &= ~(0x1 << c->u.periph.clk_num);
+	pmc_writel(val, c->reg);
+	spin_unlock_irqrestore(&clk_out_lock, flags);
+}
+
+static int tegra30_clk_out_set_parent(struct clk *c, struct clk *p)
+{
+	u32 val;
+	unsigned long flags;
+	const struct clk_mux_sel *sel;
+
+	pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->input == p) {
+			if (c->refcnt)
+				clk_enable(p);
+
+			spin_lock_irqsave(&clk_out_lock, flags);
+			val = pmc_readl(c->reg);
+			val &= ~periph_clk_source_mask(c);
+			val |= (sel->value << periph_clk_source_shift(c));
+			pmc_writel(val, c->reg);
+			spin_unlock_irqrestore(&clk_out_lock, flags);
+
+			if (c->refcnt && c->parent)
+				clk_disable(c->parent);
+
+			clk_reparent(c, p);
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_clk_out_ops = {
+	.init			= &tegra30_clk_out_init,
+	.enable			= &tegra30_clk_out_enable,
+	.disable		= &tegra30_clk_out_disable,
+	.set_parent		= &tegra30_clk_out_set_parent,
+};
+
+
+/* Clock doubler ops */
+static void tegra30_clk_double_init(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
+	c->div = 1;
+	c->state = ON;
+	if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
+		c->state = OFF;
+};
+
+static int tegra30_clk_double_set_rate(struct clk *c, unsigned long rate)
+{
+	u32 val;
+	unsigned long parent_rate = clk_get_rate(c->parent);
+	if (rate == parent_rate) {
+		val = clk_readl(c->reg) | (0x1 << c->reg_shift);
+		clk_writel(val, c->reg);
+		c->mul = 1;
+		c->div = 1;
+		return 0;
+	} else if (rate == 2 * parent_rate) {
+		val = clk_readl(c->reg) & (~(0x1 << c->reg_shift));
+		clk_writel(val, c->reg);
+		c->mul = 2;
+		c->div = 1;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_clk_double_ops = {
+	.init			= &tegra30_clk_double_init,
+	.enable			= &tegra30_periph_clk_enable,
+	.disable		= &tegra30_periph_clk_disable,
+	.set_rate		= &tegra30_clk_double_set_rate,
+};
+
+/* Audio sync clock ops */
+static int tegra30_sync_source_set_rate(struct clk *c, unsigned long rate)
+{
+	c->rate = rate;
+	return 0;
+}
+
+static struct clk_ops tegra_sync_source_ops = {
+	.set_rate		= &tegra30_sync_source_set_rate,
+};
+
+static void tegra30_audio_sync_clk_init(struct clk *c)
+{
+	int source;
+	const struct clk_mux_sel *sel;
+	u32 val = clk_readl(c->reg);
+	c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
+	source = val & AUDIO_SYNC_SOURCE_MASK;
+	for (sel = c->inputs; sel->input != NULL; sel++)
+		if (sel->value == source)
+			break;
+	BUG_ON(sel->input == NULL);
+	c->parent = sel->input;
+}
+
+static int tegra30_audio_sync_clk_enable(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
+	return 0;
+}
+
+static void tegra30_audio_sync_clk_disable(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
+}
+
+static int tegra30_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
+{
+	u32 val;
+	const struct clk_mux_sel *sel;
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->input == p) {
+			val = clk_readl(c->reg);
+			val &= ~AUDIO_SYNC_SOURCE_MASK;
+			val |= sel->value;
+
+			if (c->refcnt)
+				clk_enable(p);
+
+			clk_writel(val, c->reg);
+
+			if (c->refcnt && c->parent)
+				clk_disable(c->parent);
+
+			clk_reparent(c, p);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_audio_sync_clk_ops = {
+	.init       = tegra30_audio_sync_clk_init,
+	.enable     = tegra30_audio_sync_clk_enable,
+	.disable    = tegra30_audio_sync_clk_disable,
+	.set_parent = tegra30_audio_sync_clk_set_parent,
+};
+
+/* cml0 (pcie), and cml1 (sata) clock ops */
+static void tegra30_cml_clk_init(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
+}
+
+static int tegra30_cml_clk_enable(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	val |= (0x1 << c->u.periph.clk_num);
+	clk_writel(val, c->reg);
+	return 0;
+}
+
+static void tegra30_cml_clk_disable(struct clk *c)
+{
+	u32 val = clk_readl(c->reg);
+	val &= ~(0x1 << c->u.periph.clk_num);
+	clk_writel(val, c->reg);
+}
+
+static struct clk_ops tegra_cml_clk_ops = {
+	.init			= &tegra30_cml_clk_init,
+	.enable			= &tegra30_cml_clk_enable,
+	.disable		= &tegra30_cml_clk_disable,
+};
+
+/* Clock definitions */
+static struct clk tegra_clk_32k = {
+	.name = "clk_32k",
+	.rate = 32768,
+	.ops  = NULL,
+	.max_rate = 32768,
+};
+
+static struct clk tegra_clk_m = {
+	.name      = "clk_m",
+	.flags     = ENABLE_ON_INIT,
+	.ops       = &tegra_clk_m_ops,
+	.reg       = 0x1fc,
+	.reg_shift = 28,
+	.max_rate  = 48000000,
+};
+
+static struct clk tegra_clk_m_div2 = {
+	.name      = "clk_m_div2",
+	.ops       = &tegra_clk_m_div_ops,
+	.parent    = &tegra_clk_m,
+	.mul       = 1,
+	.div       = 2,
+	.state     = ON,
+	.max_rate  = 24000000,
+};
+
+static struct clk tegra_clk_m_div4 = {
+	.name      = "clk_m_div4",
+	.ops       = &tegra_clk_m_div_ops,
+	.parent    = &tegra_clk_m,
+	.mul       = 1,
+	.div       = 4,
+	.state     = ON,
+	.max_rate  = 12000000,
+};
+
+static struct clk tegra_pll_ref = {
+	.name      = "pll_ref",
+	.flags     = ENABLE_ON_INIT,
+	.ops       = &tegra_pll_ref_ops,
+	.parent    = &tegra_clk_m,
+	.max_rate  = 26000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
+	{ 12000000, 1040000000, 520,  6, 1, 8},
+	{ 13000000, 1040000000, 480,  6, 1, 8},
+	{ 16800000, 1040000000, 495,  8, 1, 8},		/* actual: 1039.5 MHz */
+	{ 19200000, 1040000000, 325,  6, 1, 6},
+	{ 26000000, 1040000000, 520, 13, 1, 8},
+
+	{ 12000000, 832000000, 416,  6, 1, 8},
+	{ 13000000, 832000000, 832, 13, 1, 8},
+	{ 16800000, 832000000, 396,  8, 1, 8},		/* actual: 831.6 MHz */
+	{ 19200000, 832000000, 260,  6, 1, 8},
+	{ 26000000, 832000000, 416, 13, 1, 8},
+
+	{ 12000000, 624000000, 624, 12, 1, 8},
+	{ 13000000, 624000000, 624, 13, 1, 8},
+	{ 16800000, 600000000, 520, 14, 1, 8},
+	{ 19200000, 624000000, 520, 16, 1, 8},
+	{ 26000000, 624000000, 624, 26, 1, 8},
+
+	{ 12000000, 600000000, 600, 12, 1, 8},
+	{ 13000000, 600000000, 600, 13, 1, 8},
+	{ 16800000, 600000000, 500, 14, 1, 8},
+	{ 19200000, 600000000, 375, 12, 1, 6},
+	{ 26000000, 600000000, 600, 26, 1, 8},
+
+	{ 12000000, 520000000, 520, 12, 1, 8},
+	{ 13000000, 520000000, 520, 13, 1, 8},
+	{ 16800000, 520000000, 495, 16, 1, 8},		/* actual: 519.75 MHz */
+	{ 19200000, 520000000, 325, 12, 1, 6},
+	{ 26000000, 520000000, 520, 26, 1, 8},
+
+	{ 12000000, 416000000, 416, 12, 1, 8},
+	{ 13000000, 416000000, 416, 13, 1, 8},
+	{ 16800000, 416000000, 396, 16, 1, 8},		/* actual: 415.8 MHz */
+	{ 19200000, 416000000, 260, 12, 1, 6},
+	{ 26000000, 416000000, 416, 26, 1, 8},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_c = {
+	.name      = "pll_c",
+	.flags	   = PLL_HAS_CPCON,
+	.ops       = &tegra_pll_ops,
+	.reg       = 0x80,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 1400000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 31000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 20000000,
+		.vco_max   = 1400000000,
+		.freq_table = tegra_pll_c_freq_table,
+		.lock_delay = 300,
+	},
+};
+
+static struct clk tegra_pll_c_out1 = {
+	.name      = "pll_c_out1",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = DIV_U71,
+	.parent    = &tegra_pll_c,
+	.reg       = 0x84,
+	.reg_shift = 0,
+	.max_rate  = 700000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
+	{ 12000000, 666000000, 666, 12, 1, 8},
+	{ 13000000, 666000000, 666, 13, 1, 8},
+	{ 16800000, 666000000, 555, 14, 1, 8},
+	{ 19200000, 666000000, 555, 16, 1, 8},
+	{ 26000000, 666000000, 666, 26, 1, 8},
+	{ 12000000, 600000000, 600, 12, 1, 8},
+	{ 13000000, 600000000, 600, 13, 1, 8},
+	{ 16800000, 600000000, 500, 14, 1, 8},
+	{ 19200000, 600000000, 375, 12, 1, 6},
+	{ 26000000, 600000000, 600, 26, 1, 8},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_m = {
+	.name      = "pll_m",
+	.flags     = PLL_HAS_CPCON | PLLM,
+	.ops       = &tegra_pll_ops,
+	.reg       = 0x90,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 800000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 31000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 20000000,
+		.vco_max   = 1200000000,
+		.freq_table = tegra_pll_m_freq_table,
+		.lock_delay = 300,
+	},
+};
+
+static struct clk tegra_pll_m_out1 = {
+	.name      = "pll_m_out1",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = DIV_U71,
+	.parent    = &tegra_pll_m,
+	.reg       = 0x94,
+	.reg_shift = 0,
+	.max_rate  = 600000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
+	{ 12000000, 216000000, 432, 12, 2, 8},
+	{ 13000000, 216000000, 432, 13, 2, 8},
+	{ 16800000, 216000000, 360, 14, 2, 8},
+	{ 19200000, 216000000, 360, 16, 2, 8},
+	{ 26000000, 216000000, 432, 26, 2, 8},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_p = {
+	.name      = "pll_p",
+	.flags     = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
+	.ops       = &tegra_pll_ops,
+	.reg       = 0xa0,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 432000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 31000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 20000000,
+		.vco_max   = 1400000000,
+		.freq_table = tegra_pll_p_freq_table,
+		.lock_delay = 300,
+		.fixed_rate = 408000000,
+	},
+};
+
+static struct clk tegra_pll_p_out1 = {
+	.name      = "pll_p_out1",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+	.parent    = &tegra_pll_p,
+	.reg       = 0xa4,
+	.reg_shift = 0,
+	.max_rate  = 432000000,
+};
+
+static struct clk tegra_pll_p_out2 = {
+	.name      = "pll_p_out2",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+	.parent    = &tegra_pll_p,
+	.reg       = 0xa4,
+	.reg_shift = 16,
+	.max_rate  = 432000000,
+};
+
+static struct clk tegra_pll_p_out3 = {
+	.name      = "pll_p_out3",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+	.parent    = &tegra_pll_p,
+	.reg       = 0xa8,
+	.reg_shift = 0,
+	.max_rate  = 432000000,
+};
+
+static struct clk tegra_pll_p_out4 = {
+	.name      = "pll_p_out4",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+	.parent    = &tegra_pll_p,
+	.reg       = 0xa8,
+	.reg_shift = 16,
+	.max_rate  = 432000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
+	{ 9600000, 564480000, 294, 5, 1, 4},
+	{ 9600000, 552960000, 288, 5, 1, 4},
+	{ 9600000, 24000000,  5,   2, 1, 1},
+
+	{ 28800000, 56448000, 49, 25, 1, 1},
+	{ 28800000, 73728000, 64, 25, 1, 1},
+	{ 28800000, 24000000,  5,  6, 1, 1},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_a = {
+	.name      = "pll_a",
+	.flags     = PLL_HAS_CPCON,
+	.ops       = &tegra_pll_ops,
+	.reg       = 0xb0,
+	.parent    = &tegra_pll_p_out1,
+	.max_rate  = 700000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 31000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 20000000,
+		.vco_max   = 1400000000,
+		.freq_table = tegra_pll_a_freq_table,
+		.lock_delay = 300,
+	},
+};
+
+static struct clk tegra_pll_a_out0 = {
+	.name      = "pll_a_out0",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = DIV_U71,
+	.parent    = &tegra_pll_a,
+	.reg       = 0xb4,
+	.reg_shift = 0,
+	.max_rate  = 100000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
+	{ 12000000, 216000000, 216, 12, 1, 4},
+	{ 13000000, 216000000, 216, 13, 1, 4},
+	{ 16800000, 216000000, 180, 14, 1, 4},
+	{ 19200000, 216000000, 180, 16, 1, 4},
+	{ 26000000, 216000000, 216, 26, 1, 4},
+
+	{ 12000000, 594000000, 594, 12, 1, 8},
+	{ 13000000, 594000000, 594, 13, 1, 8},
+	{ 16800000, 594000000, 495, 14, 1, 8},
+	{ 19200000, 594000000, 495, 16, 1, 8},
+	{ 26000000, 594000000, 594, 26, 1, 8},
+
+	{ 12000000, 1000000000, 1000, 12, 1, 12},
+	{ 13000000, 1000000000, 1000, 13, 1, 12},
+	{ 19200000, 1000000000, 625,  12, 1, 8},
+	{ 26000000, 1000000000, 1000, 26, 1, 12},
+
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_d = {
+	.name      = "pll_d",
+	.flags     = PLL_HAS_CPCON | PLLD,
+	.ops       = &tegra_plld_ops,
+	.reg       = 0xd0,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 1000000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 40000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 40000000,
+		.vco_max   = 1000000000,
+		.freq_table = tegra_pll_d_freq_table,
+		.lock_delay = 1000,
+	},
+};
+
+static struct clk tegra_pll_d_out0 = {
+	.name      = "pll_d_out0",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = DIV_2 | PLLD,
+	.parent    = &tegra_pll_d,
+	.max_rate  = 500000000,
+};
+
+static struct clk tegra_pll_d2 = {
+	.name      = "pll_d2",
+	.flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLD,
+	.ops       = &tegra_plld_ops,
+	.reg       = 0x4b8,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 1000000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 40000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 40000000,
+		.vco_max   = 1000000000,
+		.freq_table = tegra_pll_d_freq_table,
+		.lock_delay = 1000,
+	},
+};
+
+static struct clk tegra_pll_d2_out0 = {
+	.name      = "pll_d2_out0",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = DIV_2 | PLLD,
+	.parent    = &tegra_pll_d2,
+	.max_rate  = 500000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
+	{ 12000000, 480000000, 960, 12, 2, 12},
+	{ 13000000, 480000000, 960, 13, 2, 12},
+	{ 16800000, 480000000, 400, 7,  2, 5},
+	{ 19200000, 480000000, 200, 4,  2, 3},
+	{ 26000000, 480000000, 960, 26, 2, 12},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_u = {
+	.name      = "pll_u",
+	.flags     = PLL_HAS_CPCON | PLLU,
+	.ops       = &tegra_pll_ops,
+	.reg       = 0xc0,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 480000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 40000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 480000000,
+		.vco_max   = 960000000,
+		.freq_table = tegra_pll_u_freq_table,
+		.lock_delay = 1000,
+	},
+};
+
+static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
+	/* 1.7 GHz */
+	{ 12000000, 1700000000, 850,  6,  1, 8},
+	{ 13000000, 1700000000, 915,  7,  1, 8},	/* actual: 1699.2 MHz */
+	{ 16800000, 1700000000, 708,  7,  1, 8},	/* actual: 1699.2 MHz */
+	{ 19200000, 1700000000, 885,  10, 1, 8},	/* actual: 1699.2 MHz */
+	{ 26000000, 1700000000, 850,  13, 1, 8},
+
+	/* 1.6 GHz */
+	{ 12000000, 1600000000, 800,  6,  1, 8},
+	{ 13000000, 1600000000, 738,  6,  1, 8},	/* actual: 1599.0 MHz */
+	{ 16800000, 1600000000, 857,  9,  1, 8},	/* actual: 1599.7 MHz */
+	{ 19200000, 1600000000, 500,  6,  1, 8},
+	{ 26000000, 1600000000, 800,  13, 1, 8},
+
+	/* 1.5 GHz */
+	{ 12000000, 1500000000, 750,  6,  1, 8},
+	{ 13000000, 1500000000, 923,  8,  1, 8},	/* actual: 1499.8 MHz */
+	{ 16800000, 1500000000, 625,  7,  1, 8},
+	{ 19200000, 1500000000, 625,  8,  1, 8},
+	{ 26000000, 1500000000, 750,  13, 1, 8},
+
+	/* 1.4 GHz */
+	{ 12000000, 1400000000, 700,  6,  1, 8},
+	{ 13000000, 1400000000, 969,  9,  1, 8},	/* actual: 1399.7 MHz */
+	{ 16800000, 1400000000, 1000, 12, 1, 8},
+	{ 19200000, 1400000000, 875,  12, 1, 8},
+	{ 26000000, 1400000000, 700,  13, 1, 8},
+
+	/* 1.3 GHz */
+	{ 12000000, 1300000000, 975,  9,  1, 8},
+	{ 13000000, 1300000000, 1000, 10, 1, 8},
+	{ 16800000, 1300000000, 928,  12, 1, 8},	/* actual: 1299.2 MHz */
+	{ 19200000, 1300000000, 812,  12, 1, 8},	/* actual: 1299.2 MHz */
+	{ 26000000, 1300000000, 650,  13, 1, 8},
+
+	/* 1.2 GHz */
+	{ 12000000, 1200000000, 1000, 10, 1, 8},
+	{ 13000000, 1200000000, 923,  10, 1, 8},	/* actual: 1199.9 MHz */
+	{ 16800000, 1200000000, 1000, 14, 1, 8},
+	{ 19200000, 1200000000, 1000, 16, 1, 8},
+	{ 26000000, 1200000000, 600,  13, 1, 8},
+
+	/* 1.1 GHz */
+	{ 12000000, 1100000000, 825,  9,  1, 8},
+	{ 13000000, 1100000000, 846,  10, 1, 8},	/* actual: 1099.8 MHz */
+	{ 16800000, 1100000000, 982,  15, 1, 8},	/* actual: 1099.8 MHz */
+	{ 19200000, 1100000000, 859,  15, 1, 8},	/* actual: 1099.5 MHz */
+	{ 26000000, 1100000000, 550,  13, 1, 8},
+
+	/* 1 GHz */
+	{ 12000000, 1000000000, 1000, 12, 1, 8},
+	{ 13000000, 1000000000, 1000, 13, 1, 8},
+	{ 16800000, 1000000000, 833,  14, 1, 8},	/* actual: 999.6 MHz */
+	{ 19200000, 1000000000, 625,  12, 1, 8},
+	{ 26000000, 1000000000, 1000, 26, 1, 8},
+
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_x = {
+	.name      = "pll_x",
+	.flags     = PLL_HAS_CPCON | PLL_ALT_MISC_REG | PLLX,
+	.ops       = &tegra_pll_ops,
+	.reg       = 0xe0,
+	.parent    = &tegra_pll_ref,
+	.max_rate  = 1700000000,
+	.u.pll = {
+		.input_min = 2000000,
+		.input_max = 31000000,
+		.cf_min    = 1000000,
+		.cf_max    = 6000000,
+		.vco_min   = 20000000,
+		.vco_max   = 1700000000,
+		.freq_table = tegra_pll_x_freq_table,
+		.lock_delay = 300,
+	},
+};
+
+static struct clk tegra_pll_x_out0 = {
+	.name      = "pll_x_out0",
+	.ops       = &tegra_pll_div_ops,
+	.flags     = DIV_2 | PLLX,
+	.parent    = &tegra_pll_x,
+	.max_rate  = 850000000,
+};
+
+
+static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
+	/* PLLE special case: use cpcon field to store cml divider value */
+	{ 12000000,  100000000, 150, 1,  18, 11},
+	{ 216000000, 100000000, 200, 18, 24, 13},
+	{ 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_e = {
+	.name      = "pll_e",
+	.flags     = PLL_ALT_MISC_REG,
+	.ops       = &tegra_plle_ops,
+	.reg       = 0xe8,
+	.max_rate  = 100000000,
+	.u.pll = {
+		.input_min = 12000000,
+		.input_max = 216000000,
+		.cf_min    = 12000000,
+		.cf_max    = 12000000,
+		.vco_min   = 1200000000,
+		.vco_max   = 2400000000U,
+		.freq_table = tegra_pll_e_freq_table,
+		.lock_delay = 300,
+		.fixed_rate = 100000000,
+	},
+};
+
+static struct clk tegra_cml0_clk = {
+	.name      = "cml0",
+	.parent    = &tegra_pll_e,
+	.ops       = &tegra_cml_clk_ops,
+	.reg       = PLLE_AUX,
+	.max_rate  = 100000000,
+	.u.periph  = {
+		.clk_num = 0,
+	},
+};
+
+static struct clk tegra_cml1_clk = {
+	.name      = "cml1",
+	.parent    = &tegra_pll_e,
+	.ops       = &tegra_cml_clk_ops,
+	.reg       = PLLE_AUX,
+	.max_rate  = 100000000,
+	.u.periph  = {
+		.clk_num   = 1,
+	},
+};
+
+static struct clk tegra_pciex_clk = {
+	.name      = "pciex",
+	.parent    = &tegra_pll_e,
+	.ops       = &tegra_pciex_clk_ops,
+	.max_rate  = 100000000,
+	.u.periph  = {
+		.clk_num   = 74,
+	},
+};
+
+/* Audio sync clocks */
+#define SYNC_SOURCE(_id)				\
+	{						\
+		.name      = #_id "_sync",		\
+		.rate      = 24000000,			\
+		.max_rate  = 24000000,			\
+		.ops       = &tegra_sync_source_ops	\
+	}
+static struct clk tegra_sync_source_list[] = {
+	SYNC_SOURCE(spdif_in),
+	SYNC_SOURCE(i2s0),
+	SYNC_SOURCE(i2s1),
+	SYNC_SOURCE(i2s2),
+	SYNC_SOURCE(i2s3),
+	SYNC_SOURCE(i2s4),
+	SYNC_SOURCE(vimclk),
+};
+
+static struct clk_mux_sel mux_audio_sync_clk[] = {
+	{ .input = &tegra_sync_source_list[0],	.value = 0},
+	{ .input = &tegra_sync_source_list[1],	.value = 1},
+	{ .input = &tegra_sync_source_list[2],	.value = 2},
+	{ .input = &tegra_sync_source_list[3],	.value = 3},
+	{ .input = &tegra_sync_source_list[4],	.value = 4},
+	{ .input = &tegra_sync_source_list[5],	.value = 5},
+	{ .input = &tegra_pll_a_out0,		.value = 6},
+	{ .input = &tegra_sync_source_list[6],	.value = 7},
+	{ 0, 0 }
+};
+
+#define AUDIO_SYNC_CLK(_id, _index)			\
+	{						\
+		.name      = #_id,			\
+		.inputs    = mux_audio_sync_clk,	\
+		.reg       = 0x4A0 + (_index) * 4,	\
+		.max_rate  = 24000000,			\
+		.ops       = &tegra_audio_sync_clk_ops	\
+	}
+static struct clk tegra_clk_audio_list[] = {
+	AUDIO_SYNC_CLK(audio0, 0),
+	AUDIO_SYNC_CLK(audio1, 1),
+	AUDIO_SYNC_CLK(audio2, 2),
+	AUDIO_SYNC_CLK(audio3, 3),
+	AUDIO_SYNC_CLK(audio4, 4),
+	AUDIO_SYNC_CLK(audio, 5),	/* SPDIF */
+};
+
+#define AUDIO_SYNC_2X_CLK(_id, _index)				\
+	{							\
+		.name      = #_id "_2x",			\
+		.flags     = PERIPH_NO_RESET,			\
+		.max_rate  = 48000000,				\
+		.ops       = &tegra_clk_double_ops,		\
+		.reg       = 0x49C,				\
+		.reg_shift = 24 + (_index),			\
+		.parent    = &tegra_clk_audio_list[(_index)],	\
+		.u.periph = {					\
+			.clk_num = 113 + (_index),		\
+		},						\
+	}
+static struct clk tegra_clk_audio_2x_list[] = {
+	AUDIO_SYNC_2X_CLK(audio0, 0),
+	AUDIO_SYNC_2X_CLK(audio1, 1),
+	AUDIO_SYNC_2X_CLK(audio2, 2),
+	AUDIO_SYNC_2X_CLK(audio3, 3),
+	AUDIO_SYNC_2X_CLK(audio4, 4),
+	AUDIO_SYNC_2X_CLK(audio, 5),	/* SPDIF */
+};
+
+#define MUX_I2S_SPDIF(_id, _index)					\
+static struct clk_mux_sel mux_pllaout0_##_id##_2x_pllp_clkm[] = {	\
+	{.input = &tegra_pll_a_out0, .value = 0},			\
+	{.input = &tegra_clk_audio_2x_list[(_index)], .value = 1},	\
+	{.input = &tegra_pll_p, .value = 2},				\
+	{.input = &tegra_clk_m, .value = 3},				\
+	{ 0, 0},							\
+}
+MUX_I2S_SPDIF(audio0, 0);
+MUX_I2S_SPDIF(audio1, 1);
+MUX_I2S_SPDIF(audio2, 2);
+MUX_I2S_SPDIF(audio3, 3);
+MUX_I2S_SPDIF(audio4, 4);
+MUX_I2S_SPDIF(audio, 5);		/* SPDIF */
+
+/* External clock outputs (through PMC) */
+#define MUX_EXTERN_OUT(_id)						\
+static struct clk_mux_sel mux_clkm_clkm2_clkm4_extern##_id[] = {	\
+	{.input = &tegra_clk_m,		.value = 0},			\
+	{.input = &tegra_clk_m_div2,	.value = 1},			\
+	{.input = &tegra_clk_m_div4,	.value = 2},			\
+	{.input = NULL,			.value = 3}, /* placeholder */	\
+	{ 0, 0},							\
+}
+MUX_EXTERN_OUT(1);
+MUX_EXTERN_OUT(2);
+MUX_EXTERN_OUT(3);
+
+static struct clk_mux_sel *mux_extern_out_list[] = {
+	mux_clkm_clkm2_clkm4_extern1,
+	mux_clkm_clkm2_clkm4_extern2,
+	mux_clkm_clkm2_clkm4_extern3,
+};
+
+#define CLK_OUT_CLK(_id)					\
+	{							\
+		.name      = "clk_out_" #_id,			\
+		.lookup    = {					\
+			.dev_id    = "clk_out_" #_id,		\
+			.con_id	   = "extern" #_id,		\
+		},						\
+		.ops       = &tegra_clk_out_ops,		\
+		.reg       = 0x1a8,				\
+		.inputs    = mux_clkm_clkm2_clkm4_extern##_id,	\
+		.flags     = MUX_CLK_OUT,			\
+		.max_rate  = 216000000,				\
+		.u.periph = {					\
+			.clk_num   = (_id - 1) * 8 + 2,		\
+		},						\
+	}
+static struct clk tegra_clk_out_list[] = {
+	CLK_OUT_CLK(1),
+	CLK_OUT_CLK(2),
+	CLK_OUT_CLK(3),
+};
+
+/* called after peripheral external clocks are initialized */
+static void init_clk_out_mux(void)
+{
+	int i;
+	struct clk *c;
+
+	/* output clock con_id is the name of peripheral
+	   external clock connected to input 3 of the output mux */
+	for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++) {
+		c = tegra_get_clock_by_name(
+			tegra_clk_out_list[i].lookup.con_id);
+		if (!c)
+			pr_err("%s: could not find clk %s\n", __func__,
+			       tegra_clk_out_list[i].lookup.con_id);
+		mux_extern_out_list[i][3].input = c;
+	}
+}
+
+/* Peripheral muxes */
+static struct clk_mux_sel mux_sclk[] = {
+	{ .input = &tegra_clk_m,	.value = 0},
+	{ .input = &tegra_pll_c_out1,	.value = 1},
+	{ .input = &tegra_pll_p_out4,	.value = 2},
+	{ .input = &tegra_pll_p_out3,	.value = 3},
+	{ .input = &tegra_pll_p_out2,	.value = 4},
+	/* { .input = &tegra_clk_d,	.value = 5}, - no use on tegra30 */
+	{ .input = &tegra_clk_32k,	.value = 6},
+	{ .input = &tegra_pll_m_out1,	.value = 7},
+	{ 0, 0},
+};
+
+static struct clk tegra_clk_sclk = {
+	.name	= "sclk",
+	.inputs	= mux_sclk,
+	.reg	= 0x28,
+	.ops	= &tegra_super_ops,
+	.max_rate = 334000000,
+	.min_rate = 40000000,
+};
+
+static struct clk tegra_clk_blink = {
+	.name		= "blink",
+	.parent		= &tegra_clk_32k,
+	.reg		= 0x40,
+	.ops		= &tegra_blink_clk_ops,
+	.max_rate	= 32768,
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
+	{ .input = &tegra_pll_m, .value = 0},
+	{ .input = &tegra_pll_c, .value = 1},
+	{ .input = &tegra_pll_p, .value = 2},
+	{ .input = &tegra_pll_a_out0, .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
+	{ .input = &tegra_pll_p, .value = 0},
+	{ .input = &tegra_pll_c, .value = 1},
+	{ .input = &tegra_pll_m, .value = 2},
+	{ .input = &tegra_clk_m, .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_clkm[] = {
+	{ .input = &tegra_pll_p, .value = 0},
+	{ .input = &tegra_clk_m, .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
+	{.input = &tegra_pll_p, .value = 0},
+	{.input = &tegra_pll_d_out0, .value = 1},
+	{.input = &tegra_pll_c, .value = 2},
+	{.input = &tegra_clk_m, .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
+	{.input = &tegra_pll_p, .value = 0},
+	{.input = &tegra_pll_m, .value = 1},
+	{.input = &tegra_pll_d_out0, .value = 2},
+	{.input = &tegra_pll_a_out0, .value = 3},
+	{.input = &tegra_pll_c, .value = 4},
+	{.input = &tegra_pll_d2_out0, .value = 5},
+	{.input = &tegra_clk_m, .value = 6},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_plla_pllc_pllp_clkm[] = {
+	{ .input = &tegra_pll_a_out0, .value = 0},
+	/* { .input = &tegra_pll_c, .value = 1}, no use on tegra30 */
+	{ .input = &tegra_pll_p, .value = 2},
+	{ .input = &tegra_clk_m, .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_clk32_clkm[] = {
+	{.input = &tegra_pll_p,     .value = 0},
+	{.input = &tegra_pll_c,     .value = 1},
+	{.input = &tegra_clk_32k,   .value = 2},
+	{.input = &tegra_clk_m,     .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_clkm_clk32[] = {
+	{.input = &tegra_pll_p,     .value = 0},
+	{.input = &tegra_pll_c,     .value = 1},
+	{.input = &tegra_clk_m,     .value = 2},
+	{.input = &tegra_clk_32k,   .value = 3},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
+	{.input = &tegra_pll_p,     .value = 0},
+	{.input = &tegra_pll_c,     .value = 1},
+	{.input = &tegra_pll_m,     .value = 2},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_m[] = {
+	{ .input = &tegra_clk_m, .value = 0},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_out3[] = {
+	{ .input = &tegra_pll_p_out3, .value = 0},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_plld_out0[] = {
+	{ .input = &tegra_pll_d_out0, .value = 0},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_plld_out0_plld2_out0[] = {
+	{ .input = &tegra_pll_d_out0,  .value = 0},
+	{ .input = &tegra_pll_d2_out0, .value = 1},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_32k[] = {
+	{ .input = &tegra_clk_32k, .value = 0},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_plla_clk32_pllp_clkm_plle[] = {
+	{ .input = &tegra_pll_a_out0, .value = 0},
+	{ .input = &tegra_clk_32k,    .value = 1},
+	{ .input = &tegra_pll_p,      .value = 2},
+	{ .input = &tegra_clk_m,      .value = 3},
+	{ .input = &tegra_pll_e,      .value = 4},
+	{ 0, 0},
+};
+
+static struct clk_mux_sel mux_cclk_g[] = {
+	{ .input = &tegra_clk_m,        .value = 0},
+	{ .input = &tegra_pll_c,        .value = 1},
+	{ .input = &tegra_clk_32k,      .value = 2},
+	{ .input = &tegra_pll_m,        .value = 3},
+	{ .input = &tegra_pll_p,        .value = 4},
+	{ .input = &tegra_pll_p_out4,   .value = 5},
+	{ .input = &tegra_pll_p_out3,   .value = 6},
+	{ .input = &tegra_pll_x,        .value = 8},
+	{ 0, 0},
+};
+
+static struct clk tegra_clk_cclk_g = {
+	.name	= "cclk_g",
+	.flags	= DIV_U71 | DIV_U71_INT,
+	.inputs = mux_cclk_g,
+	.reg	= 0x368,
+	.ops	= &tegra_super_ops,
+	.max_rate = 1700000000,
+};
+
+static struct clk tegra30_clk_twd = {
+	.parent	  = &tegra_clk_cclk_g,
+	.name     = "twd",
+	.ops      = &tegra30_twd_ops,
+	.max_rate = 1400000000,	/* Same as tegra_clk_cpu_cmplx.max_rate */
+	.mul      = 1,
+	.div      = 2,
+};
+
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
+	{						\
+		.name      = _name,			\
+		.lookup    = {				\
+			.dev_id    = _dev,		\
+			.con_id	   = _con,		\
+		},					\
+		.ops       = &tegra_periph_clk_ops,	\
+		.reg       = _reg,			\
+		.inputs    = _inputs,			\
+		.flags     = _flags,			\
+		.max_rate  = _max,			\
+		.u.periph = {				\
+			.clk_num   = _clk_num,		\
+		},					\
+	}
+
+#define PERIPH_CLK_EX(_name, _dev, _con, _clk_num, _reg, _max, _inputs,	\
+			_flags, _ops)					\
+	{						\
+		.name      = _name,			\
+		.lookup    = {				\
+			.dev_id    = _dev,		\
+			.con_id	   = _con,		\
+		},					\
+		.ops       = _ops,			\
+		.reg       = _reg,			\
+		.inputs    = _inputs,			\
+		.flags     = _flags,			\
+		.max_rate  = _max,			\
+		.u.periph = {				\
+			.clk_num   = _clk_num,		\
+		},					\
+	}
+
+#define SHARED_CLK(_name, _dev, _con, _parent, _id, _div, _mode)\
+	{						\
+		.name      = _name,			\
+		.lookup    = {				\
+			.dev_id    = _dev,		\
+			.con_id    = _con,		\
+		},					\
+		.ops       = &tegra_clk_shared_bus_ops,	\
+		.parent = _parent,			\
+		.u.shared_bus_user = {			\
+			.client_id = _id,		\
+			.client_div = _div,		\
+			.mode = _mode,			\
+		},					\
+	}
+struct clk tegra_list_clks[] = {
+	PERIPH_CLK("apbdma",	"tegra-dma",		NULL,	34,	0,	26000000,  mux_clk_m,			0),
+	PERIPH_CLK("rtc",	"rtc-tegra",		NULL,	4,	0,	32768,     mux_clk_32k,			PERIPH_NO_RESET | PERIPH_ON_APB),
+	PERIPH_CLK("kbc",	"tegra-kbc",		NULL,	36,	0,	32768,     mux_clk_32k,			PERIPH_NO_RESET | PERIPH_ON_APB),
+	PERIPH_CLK("timer",	"timer",		NULL,	5,	0,	26000000,  mux_clk_m,			0),
+	PERIPH_CLK("kfuse",	"kfuse-tegra",		NULL,	40,	0,	26000000,  mux_clk_m,			0),
+	PERIPH_CLK("fuse",	"fuse-tegra",		"fuse",	39,	0,	26000000,  mux_clk_m,			PERIPH_ON_APB),
+	PERIPH_CLK("fuse_burn",	"fuse-tegra",		"fuse_burn",	39,	0,	26000000,  mux_clk_m,		PERIPH_ON_APB),
+	PERIPH_CLK("apbif",	"tegra30-ahub",		"apbif", 107,	0,	26000000,  mux_clk_m,			0),
+	PERIPH_CLK("i2s0",	"tegra30-i2s.0",	NULL,	30,	0x1d8,	26000000,  mux_pllaout0_audio0_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("i2s1",	"tegra30-i2s.1",	NULL,	11,	0x100,	26000000,  mux_pllaout0_audio1_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("i2s2",	"tegra30-i2s.2",	NULL,	18,	0x104,	26000000,  mux_pllaout0_audio2_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("i2s3",	"tegra30-i2s.3",	NULL,	101,	0x3bc,	26000000,  mux_pllaout0_audio3_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("i2s4",	"tegra30-i2s.4",	NULL,	102,	0x3c0,	26000000,  mux_pllaout0_audio4_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("spdif_out",	"tegra30-spdif",	"spdif_out",	10,	0x108,	100000000, mux_pllaout0_audio_2x_pllp_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("spdif_in",	"tegra30-spdif",	"spdif_in",	10,	0x10c,	100000000, mux_pllp_pllc_pllm,		MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("pwm",	"pwm",			NULL,	17,	0x110,	432000000, mux_pllp_pllc_clk32_clkm,	MUX | MUX_PWM | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("d_audio",	"tegra30-ahub",		"d_audio", 106,	0x3d0,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("dam0",	"tegra30-dam.0",	NULL,   108,	0x3d8,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("dam1",	"tegra30-dam.1",	NULL,   109,	0x3dc,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("dam2",	"tegra30-dam.2",	NULL,   110,	0x3e0,	48000000,  mux_plla_pllc_pllp_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("hda",	"tegra30-hda",		"hda",   125,	0x428,	108000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("hda2codec_2x",	"tegra30-hda",	"hda2codec",   111,	0x3e4,	48000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("hda2hdmi",	"tegra30-hda",		"hda2hdmi",	128,	0,	48000000,  mux_clk_m,			0),
+	PERIPH_CLK("sbc1",	"spi_tegra.0",		NULL,	41,	0x134,	160000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sbc2",	"spi_tegra.1",		NULL,	44,	0x118,	160000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sbc3",	"spi_tegra.2",		NULL,	46,	0x11c,	160000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sbc4",	"spi_tegra.3",		NULL,	68,	0x1b4,	160000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sbc5",	"spi_tegra.4",		NULL,	104,	0x3c8,	160000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sbc6",	"spi_tegra.5",		NULL,	105,	0x3cc,	160000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sata_oob",	"tegra_sata_oob",	NULL,	123,	0x420,	216000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("sata",	"tegra_sata",		NULL,	124,	0x424,	216000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("sata_cold",	"tegra_sata_cold",	NULL,	129,	0,	48000000,  mux_clk_m,			0),
+	PERIPH_CLK_EX("ndflash", "tegra_nand",		NULL,	13,	0x160,	240000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71,	&tegra_nand_clk_ops),
+	PERIPH_CLK("ndspeed",	"tegra_nand_speed",	NULL,	80,	0x3f8,	240000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("vfir",	"vfir",			NULL,	7,	0x168,	72000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("sdmmc1",	"sdhci-tegra.0",	NULL,	14,	0x150,	208000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71), /* scales with voltage */
+	PERIPH_CLK("sdmmc2",	"sdhci-tegra.1",	NULL,	9,	0x154,	104000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71), /* scales with voltage */
+	PERIPH_CLK("sdmmc3",	"sdhci-tegra.2",	NULL,	69,	0x1bc,	208000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71), /* scales with voltage */
+	PERIPH_CLK("sdmmc4",	"sdhci-tegra.3",	NULL,	15,	0x164,	104000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71), /* scales with voltage */
+	PERIPH_CLK("vcp",	"tegra-avp",		"vcp",	29,	0,	250000000, mux_clk_m,			0),
+	PERIPH_CLK("bsea",	"tegra-avp",		"bsea",	62,	0,	250000000, mux_clk_m,			0),
+	PERIPH_CLK("bsev",	"tegra-aes",		"bsev",	63,	0,	250000000, mux_clk_m,			0),
+	PERIPH_CLK("vde",	"vde",			NULL,	61,	0x1c8,	520000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_INT),
+	PERIPH_CLK("csite",	"csite",		NULL,	73,	0x1d4,	144000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71), /* max rate ??? */
+	PERIPH_CLK("la",	"la",			NULL,	76,	0x1f8,	26000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("owr",	"tegra_w1",		NULL,	71,	0x1cc,	26000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("nor",	"nor",			NULL,	42,	0x1d0,	127000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71), /* requires min voltage */
+	PERIPH_CLK("mipi",	"mipi",			NULL,	50,	0x174,	60000000,  mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | PERIPH_ON_APB), /* scales with voltage */
+	PERIPH_CLK("i2c1",	"tegra-i2c.0",		NULL,	12,	0x124,	26000000,  mux_pllp_clkm,		MUX | DIV_U16 | PERIPH_ON_APB),
+	PERIPH_CLK("i2c2",	"tegra-i2c.1",		NULL,	54,	0x198,	26000000,  mux_pllp_clkm,		MUX | DIV_U16 | PERIPH_ON_APB),
+	PERIPH_CLK("i2c3",	"tegra-i2c.2",		NULL,	67,	0x1b8,	26000000,  mux_pllp_clkm,		MUX | DIV_U16 | PERIPH_ON_APB),
+	PERIPH_CLK("i2c4",	"tegra-i2c.3",		NULL,	103,	0x3c4,	26000000,  mux_pllp_clkm,		MUX | DIV_U16 | PERIPH_ON_APB),
+	PERIPH_CLK("i2c5",	"tegra-i2c.4",		NULL,	47,	0x128,	26000000,  mux_pllp_clkm,		MUX | DIV_U16 | PERIPH_ON_APB),
+	PERIPH_CLK("uarta",	"tegra_uart.0",		NULL,	6,	0x178,	800000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uartb",	"tegra_uart.1",		NULL,	7,	0x17c,	800000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uartc",	"tegra_uart.2",		NULL,	55,	0x1a0,	800000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uartd",	"tegra_uart.3",		NULL,	65,	0x1c0,	800000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uarte",	"tegra_uart.4",		NULL,	66,	0x1c4,	800000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uarta_dbg",	"serial8250.0",		"uarta", 6,	0x178,	800000000, mux_pllp_clkm,		MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uartb_dbg",	"serial8250.0",		"uartb", 7,	0x17c,	800000000, mux_pllp_clkm,		MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uartc_dbg",	"serial8250.0",		"uartc", 55,	0x1a0,	800000000, mux_pllp_clkm,		MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uartd_dbg",	"serial8250.0",		"uartd", 65,	0x1c0,	800000000, mux_pllp_clkm,		MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK("uarte_dbg",	"serial8250.0",		"uarte", 66,	0x1c4,	800000000, mux_pllp_clkm,		MUX | DIV_U71 | DIV_U71_UART | PERIPH_ON_APB),
+	PERIPH_CLK_EX("vi",	"tegra_camera",		"vi",	20,	0x148,	425000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT,	&tegra_vi_clk_ops),
+	PERIPH_CLK("3d",	"3d",			NULL,	24,	0x158,	520000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
+	PERIPH_CLK("3d2",       "3d2",			NULL,	98,	0x3b0,	520000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE | PERIPH_MANUAL_RESET),
+	PERIPH_CLK("2d",	"2d",			NULL,	21,	0x15c,	520000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT | DIV_U71_IDLE),
+	PERIPH_CLK("vi_sensor",	"tegra_camera",		"vi_sensor",	20,	0x1a8,	150000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | PERIPH_NO_RESET),
+	PERIPH_CLK("epp",	"epp",			NULL,	19,	0x16c,	520000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT),
+	PERIPH_CLK("mpe",	"mpe",			NULL,	60,	0x170,	520000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT),
+	PERIPH_CLK("host1x",	"host1x",		NULL,	28,	0x180,	260000000, mux_pllm_pllc_pllp_plla,	MUX | DIV_U71 | DIV_U71_INT),
+	PERIPH_CLK("cve",	"cve",			NULL,	49,	0x140,	250000000, mux_pllp_plld_pllc_clkm,	MUX | DIV_U71), /* requires min voltage */
+	PERIPH_CLK("tvo",	"tvo",			NULL,	49,	0x188,	250000000, mux_pllp_plld_pllc_clkm,	MUX | DIV_U71), /* requires min voltage */
+	PERIPH_CLK_EX("dtv",	"dtv",			NULL,	79,	0x1dc,	250000000, mux_clk_m,			0,		&tegra_dtv_clk_ops),
+	PERIPH_CLK("hdmi",	"hdmi",			NULL,	51,	0x18c,	148500000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,	MUX | MUX8 | DIV_U71),
+	PERIPH_CLK("tvdac",	"tvdac",		NULL,	53,	0x194,	220000000, mux_pllp_plld_pllc_clkm,	MUX | DIV_U71), /* requires min voltage */
+	PERIPH_CLK("disp1",	"tegradc.0",		NULL,	27,	0x138,	600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,	MUX | MUX8),
+	PERIPH_CLK("disp2",	"tegradc.1",		NULL,	26,	0x13c,	600000000, mux_pllp_pllm_plld_plla_pllc_plld2_clkm,	MUX | MUX8),
+	PERIPH_CLK("usbd",	"fsl-tegra-udc",	NULL,	22,	0,	480000000, mux_clk_m,			0), /* requires min voltage */
+	PERIPH_CLK("usb2",	"tegra-ehci.1",		NULL,	58,	0,	480000000, mux_clk_m,			0), /* requires min voltage */
+	PERIPH_CLK("usb3",	"tegra-ehci.2",		NULL,	59,	0,	480000000, mux_clk_m,			0), /* requires min voltage */
+	PERIPH_CLK("dsia",	"tegradc.0",		"dsia",	48,	0,	500000000, mux_plld_out0,		0),
+	PERIPH_CLK_EX("dsib",	"tegradc.1",		"dsib",	82,	0xd0,	500000000, mux_plld_out0_plld2_out0,	MUX | PLLD,	&tegra_dsib_clk_ops),
+	PERIPH_CLK("csi",	"tegra_camera",		"csi",	52,	0,	102000000, mux_pllp_out3,		0),
+	PERIPH_CLK("isp",	"tegra_camera",		"isp",	23,	0,	150000000, mux_clk_m,			0), /* same frequency as VI */
+	PERIPH_CLK("csus",	"tegra_camera",		"csus",	92,	0,	150000000, mux_clk_m,			PERIPH_NO_RESET),
+
+	PERIPH_CLK("tsensor",	"tegra-tsensor",	NULL,	100,	0x3b8,	216000000, mux_pllp_pllc_clkm_clk32,	MUX | DIV_U71),
+	PERIPH_CLK("actmon",	"actmon",		NULL,	119,	0x3e8,	216000000, mux_pllp_pllc_clk32_clkm,	MUX | DIV_U71),
+	PERIPH_CLK("extern1",	"extern1",		NULL,	120,	0x3ec,	216000000, mux_plla_clk32_pllp_clkm_plle,	MUX | MUX8 | DIV_U71),
+	PERIPH_CLK("extern2",	"extern2",		NULL,	121,	0x3f0,	216000000, mux_plla_clk32_pllp_clkm_plle,	MUX | MUX8 | DIV_U71),
+	PERIPH_CLK("extern3",	"extern3",		NULL,	122,	0x3f4,	216000000, mux_plla_clk32_pllp_clkm_plle,	MUX | MUX8 | DIV_U71),
+	PERIPH_CLK("i2cslow",	"i2cslow",		NULL,	81,	0x3fc,	26000000,  mux_pllp_pllc_clk32_clkm,	MUX | DIV_U71 | PERIPH_ON_APB),
+	PERIPH_CLK("pcie",	"tegra-pcie",		"pcie",	70,	0,	250000000, mux_clk_m,			0),
+	PERIPH_CLK("afi",	"tegra-pcie",		"afi",	72,	0,	250000000, mux_clk_m,			0),
+	PERIPH_CLK("se",	"se",			NULL,	127,	0x42c,	520000000, mux_pllp_pllc_pllm_clkm,	MUX | DIV_U71 | DIV_U71_INT),
+};
+
+#define CLK_DUPLICATE(_name, _dev, _con)		\
+	{						\
+		.name	= _name,			\
+		.lookup	= {				\
+			.dev_id	= _dev,			\
+			.con_id		= _con,		\
+		},					\
+	}
+
+/* Some clocks may be used by different drivers depending on the board
+ * configuration.  List those here to register them twice in the clock lookup
+ * table under two names.
+ */
+struct clk_duplicate tegra_clk_duplicates[] = {
+	CLK_DUPLICATE("usbd", "utmip-pad", NULL),
+	CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
+	CLK_DUPLICATE("usbd", "tegra-otg", NULL),
+	CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
+	CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
+	CLK_DUPLICATE("dsib", "tegradc.0", "dsib"),
+	CLK_DUPLICATE("dsia", "tegradc.1", "dsia"),
+	CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
+	CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
+	CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
+	CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
+	CLK_DUPLICATE("bsev", "tegra-avp", "bsev"),
+	CLK_DUPLICATE("bsev", "nvavp", "bsev"),
+	CLK_DUPLICATE("vde", "tegra-aes", "vde"),
+	CLK_DUPLICATE("bsea", "tegra-aes", "bsea"),
+	CLK_DUPLICATE("bsea", "nvavp", "bsea"),
+	CLK_DUPLICATE("cml1", "tegra_sata_cml", NULL),
+	CLK_DUPLICATE("cml0", "tegra_pcie", "cml"),
+	CLK_DUPLICATE("pciex", "tegra_pcie", "pciex"),
+	CLK_DUPLICATE("i2c1", "tegra-i2c-slave.0", NULL),
+	CLK_DUPLICATE("i2c2", "tegra-i2c-slave.1", NULL),
+	CLK_DUPLICATE("i2c3", "tegra-i2c-slave.2", NULL),
+	CLK_DUPLICATE("i2c4", "tegra-i2c-slave.3", NULL),
+	CLK_DUPLICATE("i2c5", "tegra-i2c-slave.4", NULL),
+	CLK_DUPLICATE("sbc1", "spi_slave_tegra.0", NULL),
+	CLK_DUPLICATE("sbc2", "spi_slave_tegra.1", NULL),
+	CLK_DUPLICATE("sbc3", "spi_slave_tegra.2", NULL),
+	CLK_DUPLICATE("sbc4", "spi_slave_tegra.3", NULL),
+	CLK_DUPLICATE("sbc5", "spi_slave_tegra.4", NULL),
+	CLK_DUPLICATE("sbc6", "spi_slave_tegra.5", NULL),
+	CLK_DUPLICATE("twd", "smp_twd", NULL),
+	CLK_DUPLICATE("vcp", "nvavp", "vcp"),
+};
+
+struct clk *tegra_ptr_clks[] = {
+	&tegra_clk_32k,
+	&tegra_clk_m,
+	&tegra_clk_m_div2,
+	&tegra_clk_m_div4,
+	&tegra_pll_ref,
+	&tegra_pll_m,
+	&tegra_pll_m_out1,
+	&tegra_pll_c,
+	&tegra_pll_c_out1,
+	&tegra_pll_p,
+	&tegra_pll_p_out1,
+	&tegra_pll_p_out2,
+	&tegra_pll_p_out3,
+	&tegra_pll_p_out4,
+	&tegra_pll_a,
+	&tegra_pll_a_out0,
+	&tegra_pll_d,
+	&tegra_pll_d_out0,
+	&tegra_pll_d2,
+	&tegra_pll_d2_out0,
+	&tegra_pll_u,
+	&tegra_pll_x,
+	&tegra_pll_x_out0,
+	&tegra_pll_e,
+	&tegra_clk_cclk_g,
+	&tegra_cml0_clk,
+	&tegra_cml1_clk,
+	&tegra_pciex_clk,
+	&tegra_clk_sclk,
+	&tegra_clk_blink,
+	&tegra30_clk_twd,
+};
+
+
+static void tegra30_init_one_clock(struct clk *c)
+{
+	clk_init(c);
+	INIT_LIST_HEAD(&c->shared_bus_list);
+	if (!c->lookup.dev_id && !c->lookup.con_id)
+		c->lookup.con_id = c->name;
+	c->lookup.clk = c;
+	clkdev_add(&c->lookup);
+}
+
+void __init tegra30_init_clocks(void)
+{
+	int i;
+	struct clk *c;
+
+	for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
+		tegra30_init_one_clock(tegra_ptr_clks[i]);
+
+	for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
+		tegra30_init_one_clock(&tegra_list_clks[i]);
+
+	for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
+		c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
+		if (!c) {
+			pr_err("%s: Unknown duplicate clock %s\n", __func__,
+				tegra_clk_duplicates[i].name);
+			continue;
+		}
+
+		tegra_clk_duplicates[i].lookup.clk = c;
+		clkdev_add(&tegra_clk_duplicates[i].lookup);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(tegra_sync_source_list); i++)
+		tegra30_init_one_clock(&tegra_sync_source_list[i]);
+	for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_list); i++)
+		tegra30_init_one_clock(&tegra_clk_audio_list[i]);
+	for (i = 0; i < ARRAY_SIZE(tegra_clk_audio_2x_list); i++)
+		tegra30_init_one_clock(&tegra_clk_audio_2x_list[i]);
+
+	init_clk_out_mux();
+	for (i = 0; i < ARRAY_SIZE(tegra_clk_out_list); i++)
+		tegra30_init_one_clock(&tegra_clk_out_list[i]);
+
+}
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index b4c6926..f0048a1 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -26,7 +26,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/fsmc.h>
 #include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/types.h>
@@ -94,19 +94,9 @@ static struct amba_pl011_data uart0_plat_data = {
 #endif
 };
 
-static struct amba_device uart0_device = {
-	.dev = {
-		.coherent_dma_mask = ~0,
-		.init_name = "uart0", /* Slow device at 0x3000 offset */
-		.platform_data = &uart0_plat_data,
-	},
-	.res = {
-		.start = U300_UART0_BASE,
-		.end   = U300_UART0_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = { IRQ_U300_UART0, NO_IRQ },
-};
+/* Slow device at 0x3000 offset */
+static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE,
+	{ IRQ_U300_UART0 }, &uart0_plat_data);
 
 /* The U335 have an additional UART1 on the APP CPU */
 #ifdef CONFIG_MACH_U300_BS335
@@ -118,71 +108,28 @@ static struct amba_pl011_data uart1_plat_data = {
 #endif
 };
 
-static struct amba_device uart1_device = {
-	.dev = {
-		.coherent_dma_mask = ~0,
-		.init_name = "uart1", /* Fast device at 0x7000 offset */
-		.platform_data = &uart1_plat_data,
-	},
-	.res = {
-		.start = U300_UART1_BASE,
-		.end   = U300_UART1_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = { IRQ_U300_UART1, NO_IRQ },
-};
+/* Fast device at 0x7000 offset */
+static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
+	{ IRQ_U300_UART1 }, &uart1_plat_data);
 #endif
 
-static struct amba_device pl172_device = {
-	.dev = {
-		.init_name = "pl172", /* AHB device at 0x4000 offset */
-		.platform_data = NULL,
-	},
-	.res = {
-		.start = U300_EMIF_CFG_BASE,
-		.end   = U300_EMIF_CFG_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
+/* AHB device at 0x4000 offset */
+static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
 
 
 /*
  * Everything within this next ifdef deals with external devices connected to
  * the APP SPI bus.
  */
-static struct amba_device pl022_device = {
-	.dev = {
-		.coherent_dma_mask = ~0,
-		.init_name = "pl022", /* Fast device at 0x6000 offset */
-	},
-	.res = {
-		.start = U300_SPI_BASE,
-		.end   = U300_SPI_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_U300_SPI, NO_IRQ },
-	/*
-	 * This device has a DMA channel but the Linux driver does not use
-	 * it currently.
-	 */
-};
+/* Fast device at 0x6000 offset */
+static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
+	{ IRQ_U300_SPI }, NULL);
 
-static struct amba_device mmcsd_device = {
-	.dev = {
-		.init_name = "mmci", /* Fast device at 0x1000 offset */
-		.platform_data = NULL, /* Added later */
-	},
-	.res = {
-		.start = U300_MMCSD_BASE,
-		.end   = U300_MMCSD_BASE + SZ_4K - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	.irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
-	/*
-	 * This device has a DMA channel but the Linux driver does not use
-	 * it currently.
-	 */
-};
+/* Fast device at 0x1000 offset */
+#define U300_MMCSD_IRQS	{ IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
+
+static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
+	U300_MMCSD_IRQS, NULL);
 
 /*
  * The order of device declaration may be important, since some devices
@@ -1477,7 +1424,7 @@ static struct coh901318_platform coh901318_platform = {
 	.max_channels = U300_DMA_CHANNELS,
 };
 
-static struct resource pinmux_resources[] = {
+static struct resource pinctrl_resources[] = {
 	{
 		.start = U300_SYSCON_BASE,
 		.end   = U300_SYSCON_BASE + SZ_4K - 1,
@@ -1506,6 +1453,13 @@ static struct platform_device i2c1_device = {
 	.resource = i2c1_resources,
 };
 
+static struct platform_device pinctrl_device = {
+	.name = "pinctrl-u300",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(pinctrl_resources),
+	.resource = pinctrl_resources,
+};
+
 /*
  * The different variants have a few different versions of the
  * GPIO block, with different number of ports.
@@ -1525,6 +1479,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
 #endif
 	.gpio_base = 0,
 	.gpio_irq_base = IRQ_U300_GPIO_BASE,
+	.pinctrl_device = &pinctrl_device,
 };
 
 static struct platform_device gpio_device = {
@@ -1597,29 +1552,22 @@ static struct platform_device dma_device = {
 	},
 };
 
-static struct platform_device pinmux_device = {
-	.name = "pinmux-u300",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(pinmux_resources),
-	.resource = pinmux_resources,
-};
-
 /* Pinmux settings */
-static struct pinmux_map __initdata u300_pinmux_map[] = {
+static struct pinctrl_map __initdata u300_pinmux_map[] = {
 	/* anonymous maps for chip power and EMIFs */
-	PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
-	PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
-	PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
+	PIN_MAP_SYS_HOG("POWER", "pinctrl-u300", "power"),
+	PIN_MAP_SYS_HOG("EMIF0", "pinctrl-u300", "emif0"),
+	PIN_MAP_SYS_HOG("EMIF1", "pinctrl-u300", "emif1"),
 	/* per-device maps for MMC/SD, SPI and UART */
-	PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
-	PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
-	PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
+	PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"),
+	PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"),
+	PIN_MAP("UART0", "pinctrl-u300", "uart0", "uart0"),
 };
 
 struct u300_mux_hog {
 	const char *name;
 	struct device *dev;
-	struct pinmux *pmx;
+	struct pinctrl *p;
 };
 
 static struct u300_mux_hog u300_mux_hogs[] = {
@@ -1637,31 +1585,31 @@ static struct u300_mux_hog u300_mux_hogs[] = {
 	},
 };
 
-static int __init u300_pinmux_fetch(void)
+static int __init u300_pinctrl_fetch(void)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
-		struct pinmux *pmx;
+		struct pinctrl *p;
 		int ret;
 
-		pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
-		if (IS_ERR(pmx)) {
+		p = pinctrl_get(u300_mux_hogs[i].dev, NULL);
+		if (IS_ERR(p)) {
 			pr_err("u300: could not get pinmux hog %s\n",
 			       u300_mux_hogs[i].name);
 			continue;
 		}
-		ret = pinmux_enable(pmx);
+		ret = pinctrl_enable(p);
 		if (ret) {
 			pr_err("u300: could enable pinmux hog %s\n",
 			       u300_mux_hogs[i].name);
 			continue;
 		}
-		u300_mux_hogs[i].pmx = pmx;
+		u300_mux_hogs[i].p = p;
 	}
 	return 0;
 }
-subsys_initcall(u300_pinmux_fetch);
+subsys_initcall(u300_pinctrl_fetch);
 
 /*
  * Notice that AMBA devices are initialized before platform devices.
@@ -1676,7 +1624,6 @@ static struct platform_device *platform_devs[] __initdata = {
 	&gpio_device,
 	&nand_device,
 	&wdog_device,
-	&pinmux_device,
 };
 
 /*
@@ -1861,8 +1808,8 @@ void __init u300_init_devices(void)
 	u300_assign_physmem();
 
 	/* Initialize pinmuxing */
-	pinmux_register_mappings(u300_pinmux_map,
-				 ARRAY_SIZE(u300_pinmux_map));
+	pinctrl_register_mappings(u300_pinmux_map,
+				  ARRAY_SIZE(u300_pinmux_map));
 
 	/* Register subdevices on the I2C buses */
 	u300_i2c_register_board_devices();
diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c
index 5140dee..a38f802 100644
--- a/arch/arm/mach-u300/i2c.c
+++ b/arch/arm/mach-u300/i2c.c
@@ -60,7 +60,6 @@ static struct regulator_consumer_supply supply_ldo_c[] = {
  */
 static struct regulator_consumer_supply supply_ldo_d[] = {
 	{
-		.dev = NULL,
 		.supply = "vana15", /* Powers the SoC (CPU etc) */
 	},
 };
@@ -92,7 +91,6 @@ static struct regulator_consumer_supply supply_ldo_k[] = {
  */
 static struct regulator_consumer_supply supply_ldo_ext[] = {
 	{
-		.dev = NULL,
 		.supply = "vext", /* External power */
 	},
 };
diff --git a/arch/arm/mach-u300/include/mach/gpio-u300.h b/arch/arm/mach-u300/include/mach/gpio-u300.h
index bf4c793..e81400c 100644
--- a/arch/arm/mach-u300/include/mach/gpio-u300.h
+++ b/arch/arm/mach-u300/include/mach/gpio-u300.h
@@ -24,12 +24,14 @@ enum u300_gpio_variant {
  * @ports: number of GPIO block ports
  * @gpio_base: first GPIO number for this block (use a free range)
  * @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
+ * @pinctrl_device: pin control device to spawn as child
  */
 struct u300_gpio_platform {
 	enum u300_gpio_variant variant;
 	u8 ports;
 	int gpio_base;
 	int gpio_irq_base;
+	struct platform_device *pinctrl_device;
 };
 
 #endif /* __MACH_U300_GPIO_U300_H */
diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h
deleted file mode 100644
index 574d46e..0000000
--- a/arch/arm/mach-u300/include/mach/system.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/include/mach/system.h
- *
- *
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * System shutdown and reset functions.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 52af004..5cfa539 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -28,6 +28,7 @@ config MACH_U8500
 	bool "U8500 Development platform"
 	depends on UX500_SOC_DB8500
 	select TPS6105X
+	select SOC_BUS
 	help
 	  Include support for the mop500 development platform.
 
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 5dde4d4..920251c 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -31,21 +31,13 @@
  * SDI 0 (MicroSD slot)
  */
 
-/* MMCIPOWER bits */
-#define MCI_DATA2DIREN		(1 << 2)
-#define MCI_CMDDIREN		(1 << 3)
-#define MCI_DATA0DIREN		(1 << 4)
-#define MCI_DATA31DIREN		(1 << 5)
-#define MCI_FBCLKEN		(1 << 7)
-
 /* GPIO pins used by the sdi0 level shifter */
 static int sdi0_en = -1;
 static int sdi0_vsel = -1;
 
-static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
-				   unsigned char power_mode)
+static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios)
 {
-	switch (power_mode) {
+	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 	case MMC_POWER_ON:
 		/*
@@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
 		break;
 	}
 
-	return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN |
-	       MCI_DATA2DIREN | MCI_DATA31DIREN;
+	return 0;
 }
 
 #ifdef CONFIG_STE_DMA40
@@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
 #endif
 
 static struct mmci_platform_data mop500_sdi0_data = {
-	.vdd_handler	= mop500_sdi0_vdd_handler,
+	.ios_handler	= mop500_sdi0_ios_handler,
 	.ocr_mask	= MMC_VDD_29_30,
 	.f_max		= 50000000,
 	.capabilities	= MMC_CAP_4_BIT_DATA |
 				MMC_CAP_SD_HIGHSPEED |
 				MMC_CAP_MMC_HIGHSPEED,
 	.gpio_wp	= -1,
+	.sigdir		= MCI_ST_FBCLKEN |
+				MCI_ST_CMDDIREN |
+				MCI_ST_DATA0DIREN |
+				MCI_ST_DATA2DIREN,
 #ifdef CONFIG_STE_DMA40
 	.dma_filter	= stedma40_filter,
 	.dma_rx_param	= &mop500_sdi0_dma_cfg_rx,
@@ -104,7 +99,7 @@ static struct mmci_platform_data mop500_sdi0_data = {
 #endif
 };
 
-static void sdi0_configure(void)
+static void sdi0_configure(struct device *parent)
 {
 	int ret;
 
@@ -123,15 +118,15 @@ static void sdi0_configure(void)
 	gpio_direction_output(sdi0_en, 1);
 
 	/* Add the device, force v2 to subrevision 1 */
-	db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID);
 }
 
-void mop500_sdi_tc35892_init(void)
+void mop500_sdi_tc35892_init(struct device *parent)
 {
 	mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
 	sdi0_en = GPIO_SDMMC_EN;
 	sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
-	sdi0_configure();
+	sdi0_configure(parent);
 }
 
 /*
@@ -246,12 +241,13 @@ static struct mmci_platform_data mop500_sdi4_data = {
 #endif
 };
 
-void __init mop500_sdi_init(void)
+void __init mop500_sdi_init(struct device *parent)
 {
 	/* PoP:ed eMMC */
-	db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
 	/* On-board eMMC */
-	db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+
 	/*
 	 * On boards with the TC35892 GPIO expander, sdi0 will finally
 	 * be added when the TC35892 initializes and calls
@@ -259,31 +255,31 @@ void __init mop500_sdi_init(void)
 	 */
 }
 
-void __init snowball_sdi_init(void)
+void __init snowball_sdi_init(struct device *parent)
 {
 	/* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */
 	mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
 	/* On-board eMMC */
-	db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
 	/* External Micro SD slot */
 	mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO;
 	mop500_sdi0_data.cd_invert = true;
 	sdi0_en = SNOWBALL_SDMMC_EN_GPIO;
 	sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO;
-	sdi0_configure();
+	sdi0_configure(parent);
 }
 
-void __init hrefv60_sdi_init(void)
+void __init hrefv60_sdi_init(struct device *parent)
 {
 	/* PoP:ed eMMC */
-	db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID);
 	/* On-board eMMC */
-	db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID);
 	/* External Micro SD slot */
 	mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
 	sdi0_en = HREFV60_SDMMC_EN_GPIO;
 	sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
-	sdi0_configure();
+	sdi0_configure(parent);
 	/* WLAN SDIO channel */
-	db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
+	db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID);
 }
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 5c00712..04afcdf 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -226,7 +226,12 @@ static struct tps6105x_platform_data mop500_tps61052_data = {
 
 static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
 {
-	mop500_sdi_tc35892_init();
+	struct device *parent = NULL;
+#if 0
+	/* FIXME: Is the sdi actually part of tc3589x? */
+	parent = tc3589x->dev;
+#endif
+	mop500_sdi_tc35892_init(parent);
 }
 
 static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
@@ -353,12 +358,12 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 U8500_I2C_CONTROLLER(2,	0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 U8500_I2C_CONTROLLER(3,	0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 
-static void __init mop500_i2c_init(void)
+static void __init mop500_i2c_init(struct device *parent)
 {
-	db8500_add_i2c0(&u8500_i2c0_data);
-	db8500_add_i2c1(&u8500_i2c1_data);
-	db8500_add_i2c2(&u8500_i2c2_data);
-	db8500_add_i2c3(&u8500_i2c3_data);
+	db8500_add_i2c0(parent, &u8500_i2c0_data);
+	db8500_add_i2c1(parent, &u8500_i2c1_data);
+	db8500_add_i2c2(parent, &u8500_i2c2_data);
+	db8500_add_i2c3(parent, &u8500_i2c3_data);
 }
 
 static struct gpio_keys_button mop500_gpio_keys[] = {
@@ -451,9 +456,9 @@ static struct pl022_ssp_controller ssp0_platform_data = {
 	.num_chipselect = 5,
 };
 
-static void __init mop500_spi_init(void)
+static void __init mop500_spi_init(struct device *parent)
 {
-	db8500_add_ssp0(&ssp0_platform_data);
+	db8500_add_ssp0(parent, &ssp0_platform_data);
 }
 
 #ifdef CONFIG_STE_DMA40
@@ -587,11 +592,11 @@ static struct amba_pl011_data uart2_plat = {
 #endif
 };
 
-static void __init mop500_uart_init(void)
+static void __init mop500_uart_init(struct device *parent)
 {
-	db8500_add_uart0(&uart0_plat);
-	db8500_add_uart1(&uart1_plat);
-	db8500_add_uart2(&uart2_plat);
+	db8500_add_uart0(parent, &uart0_plat);
+	db8500_add_uart1(parent, &uart1_plat);
+	db8500_add_uart2(parent, &uart2_plat);
 }
 
 static struct platform_device *snowball_platform_devs[] __initdata = {
@@ -603,21 +608,26 @@ static struct platform_device *snowball_platform_devs[] __initdata = {
 
 static void __init mop500_init_machine(void)
 {
+	struct device *parent = NULL;
 	int i2c0_devs;
+	int i;
 
 	mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
 
-	u8500_init_devices();
+	parent = u8500_init_devices();
 
 	mop500_pins_init();
 
+	for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
+		mop500_platform_devs[i]->dev.parent = parent;
+
 	platform_add_devices(mop500_platform_devs,
 			ARRAY_SIZE(mop500_platform_devs));
 
-	mop500_i2c_init();
-	mop500_sdi_init();
-	mop500_spi_init();
-	mop500_uart_init();
+	mop500_i2c_init(parent);
+	mop500_sdi_init(parent);
+	mop500_spi_init(parent);
+	mop500_uart_init(parent);
 
 	i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
 
@@ -631,19 +641,24 @@ static void __init mop500_init_machine(void)
 
 static void __init snowball_init_machine(void)
 {
+	struct device *parent = NULL;
 	int i2c0_devs;
+	int i;
 
-	u8500_init_devices();
+	parent = u8500_init_devices();
 
 	snowball_pins_init();
 
+	for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
+		snowball_platform_devs[i]->dev.parent = parent;
+
 	platform_add_devices(snowball_platform_devs,
 			ARRAY_SIZE(snowball_platform_devs));
 
-	mop500_i2c_init();
-	snowball_sdi_init();
-	mop500_spi_init();
-	mop500_uart_init();
+	mop500_i2c_init(parent);
+	snowball_sdi_init(parent);
+	mop500_spi_init(parent);
+	mop500_uart_init(parent);
 
 	i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
 	i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
@@ -656,7 +671,9 @@ static void __init snowball_init_machine(void)
 
 static void __init hrefv60_init_machine(void)
 {
+	struct device *parent = NULL;
 	int i2c0_devs;
+	int i;
 
 	/*
 	 * The HREFv60 board removed a GPIO expander and routed
@@ -665,17 +682,20 @@ static void __init hrefv60_init_machine(void)
 	 */
 	mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
 
-	u8500_init_devices();
+	parent = u8500_init_devices();
 
 	hrefv60_pins_init();
 
+	for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
+		mop500_platform_devs[i]->dev.parent = parent;
+
 	platform_add_devices(mop500_platform_devs,
 			ARRAY_SIZE(mop500_platform_devs));
 
-	mop500_i2c_init();
-	hrefv60_sdi_init();
-	mop500_spi_init();
-	mop500_uart_init();
+	mop500_i2c_init(parent);
+	hrefv60_sdi_init(parent);
+	mop500_spi_init(parent);
+	mop500_uart_init(parent);
 
 	i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
 
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index f926d3d..3d594c2 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -75,10 +75,10 @@
 
 struct i2c_board_info;
 
-extern void mop500_sdi_init(void);
-extern void snowball_sdi_init(void);
-extern void hrefv60_sdi_init(void);
-extern void mop500_sdi_tc35892_init(void);
+extern void mop500_sdi_init(struct device *parent);
+extern void snowball_sdi_init(struct device *parent);
+extern void hrefv60_sdi_init(struct device *parent);
+extern void mop500_sdi_tc35892_init(struct device *parent);
 void __init mop500_u8500uib_init(void);
 void __init mop500_stuib_init(void);
 void __init mop500_pins_init(void);
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c
index 63c3f80..836112e 100644
--- a/arch/arm/mach-ux500/board-u5500-sdi.c
+++ b/arch/arm/mach-ux500/board-u5500-sdi.c
@@ -66,9 +66,9 @@ static struct mmci_platform_data u5500_sdi0_data = {
 #endif
 };
 
-void __init u5500_sdi_init(void)
+void __init u5500_sdi_init(struct device *parent)
 {
 	nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins));
 
-	db5500_add_sdi0(&u5500_sdi0_data);
+	db5500_add_sdi0(parent, &u5500_sdi0_data);
 }
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
index 9de9e9c..0ff4be7 100644
--- a/arch/arm/mach-ux500/board-u5500.c
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -97,9 +97,9 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = {
 	},
 };
 
-static void __init u5500_i2c_init(void)
+static void __init u5500_i2c_init(struct device *parent)
 {
-	db5500_add_i2c2(&u5500_i2c2_data);
+	db5500_add_i2c2(parent, &u5500_i2c2_data);
 	i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices));
 }
 
@@ -126,20 +126,27 @@ static struct platform_device *u5500_platform_devices[] __initdata = {
 	&ab5500_device,
 };
 
-static void __init u5500_uart_init(void)
+static void __init u5500_uart_init(struct device *parent)
 {
-	db5500_add_uart0(NULL);
-	db5500_add_uart1(NULL);
-	db5500_add_uart2(NULL);
+	db5500_add_uart0(parent, NULL);
+	db5500_add_uart1(parent, NULL);
+	db5500_add_uart2(parent, NULL);
 }
 
 static void __init u5500_init_machine(void)
 {
-	u5500_init_devices();
+	struct device *parent = NULL;
+	int i;
+
+	parent = u5500_init_devices();
 	nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins));
-	u5500_i2c_init();
-	u5500_sdi_init();
-	u5500_uart_init();
+
+	u5500_i2c_init(parent);
+	u5500_sdi_init(parent);
+	u5500_uart_init(parent);
+
+	for (i = 0; i < ARRAY_SIZE(u5500_platform_devices); i++)
+		u5500_platform_devices[i]->dev.parent = parent;
 
 	platform_add_devices(u5500_platform_devices,
 		ARRAY_SIZE(u5500_platform_devices));
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
index 18aa5c0..bca47f3 100644
--- a/arch/arm/mach-ux500/cpu-db5500.c
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -147,13 +147,13 @@ static resource_size_t __initdata db5500_gpio_base[] = {
 	U5500_GPIOBANK7_BASE,
 };
 
-static void __init db5500_add_gpios(void)
+static void __init db5500_add_gpios(struct device *parent)
 {
 	struct nmk_gpio_platform_data pdata = {
 		/* No custom data yet */
 	};
 
-	dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base),
+	dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base),
 			 IRQ_DB5500_GPIO0, &pdata);
 }
 
@@ -212,14 +212,36 @@ static int usb_db5500_tx_dma_cfg[] = {
 	DB5500_DMA_DEV38_USB_OTG_OEP_8
 };
 
-void __init u5500_init_devices(void)
+static const char *db5500_read_soc_id(void)
 {
-	db5500_add_gpios();
+	return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n");
+}
+
+static struct device * __init db5500_soc_device_init(void)
+{
+	const char *soc_id = db5500_read_soc_id();
+
+	return ux500_soc_device_init(soc_id);
+}
+
+struct device * __init u5500_init_devices(void)
+{
+	struct device *parent;
+	int i;
+
+	parent = db5500_soc_device_init();
+
+	db5500_add_gpios(parent);
 	db5500_pmu_init();
-	db5500_dma_init();
-	db5500_add_rtc();
-	db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
+	db5500_dma_init(parent);
+	db5500_add_rtc(parent);
+	db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
+
+	for (i = 0; i < ARRAY_SIZE(db5500_platform_devs); i++)
+		db5500_platform_devs[i]->dev.parent = parent;
 
 	platform_add_devices(db5500_platform_devs,
 			     ARRAY_SIZE(db5500_platform_devs));
+
+	return parent;
 }
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 7176ee7..9bd8163 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -24,6 +24,7 @@
 #include <mach/setup.h>
 #include <mach/devices.h>
 #include <mach/usb.h>
+#include <mach/db8500-regs.h>
 
 #include "devices-db8500.h"
 #include "ste-dma40-db8500.h"
@@ -132,13 +133,13 @@ static resource_size_t __initdata db8500_gpio_base[] = {
 	U8500_GPIOBANK8_BASE,
 };
 
-static void __init db8500_add_gpios(void)
+static void __init db8500_add_gpios(struct device *parent)
 {
 	struct nmk_gpio_platform_data pdata = {
 		.supports_sleepmode = true,
 	};
 
-	dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
+	dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base),
 			 IRQ_DB8500_GPIO0, &pdata);
 }
 
@@ -164,17 +165,44 @@ static int usb_db8500_tx_dma_cfg[] = {
 	DB8500_DMA_DEV39_USB_OTG_OEP_8
 };
 
+static const char *db8500_read_soc_id(void)
+{
+	void __iomem *uid = __io_address(U8500_BB_UID_BASE);
+
+	return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
+			 readl((u32 *)uid+1),
+			 readl((u32 *)uid+1), readl((u32 *)uid+2),
+			 readl((u32 *)uid+3), readl((u32 *)uid+4));
+}
+
+static struct device * __init db8500_soc_device_init(void)
+{
+	const char *soc_id = db8500_read_soc_id();
+
+	return ux500_soc_device_init(soc_id);
+}
+
 /*
  * This function is called from the board init
  */
-void __init u8500_init_devices(void)
+struct device * __init u8500_init_devices(void)
 {
-	db8500_add_rtc();
-	db8500_add_gpios();
-	db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
+	struct device *parent;
+	int i;
+
+	parent = db8500_soc_device_init();
+
+	db8500_add_rtc(parent);
+	db8500_add_gpios(parent);
+	db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
+
+	platform_device_register_data(parent,
+		"cpufreq-u8500", -1, NULL, 0);
+
+	for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
+		platform_devs[i]->dev.parent = parent;
 
-	platform_device_register_simple("cpufreq-u8500", -1, NULL, 0);
 	platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
 
-	return ;
+	return parent;
 }
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index f418574..055fb6e 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -2,6 +2,7 @@
  * Copyright (C) ST-Ericsson SA 2010
  *
  * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson
  * License terms: GNU General Public License (GPL) version 2
  */
 
@@ -11,6 +12,10 @@
 #include <linux/mfd/db8500-prcmu.h>
 #include <linux/mfd/db5500-prcmu.h>
 #include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/sys_soc.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
 
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
@@ -50,3 +55,73 @@ void __init ux500_init_irq(void)
 		db8500_prcmu_early_init();
 	clk_init();
 }
+
+static const char * __init ux500_get_machine(void)
+{
+	return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber());
+}
+
+static const char * __init ux500_get_family(void)
+{
+	return kasprintf(GFP_KERNEL, "ux500");
+}
+
+static const char * __init ux500_get_revision(void)
+{
+	unsigned int rev = dbx500_revision();
+
+	if (rev == 0x01)
+		return kasprintf(GFP_KERNEL, "%s", "ED");
+	else if (rev >= 0xA0)
+		return kasprintf(GFP_KERNEL, "%d.%d",
+				 (rev >> 4) - 0xA + 1, rev & 0xf);
+
+	return kasprintf(GFP_KERNEL, "%s", "Unknown");
+}
+
+static ssize_t ux500_get_process(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	if (dbx500_id.process == 0x00)
+		return sprintf(buf, "Standard\n");
+
+	return sprintf(buf, "%02xnm\n", dbx500_id.process);
+}
+
+static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr,
+				     const char *soc_id)
+{
+	soc_dev_attr->soc_id   = soc_id;
+	soc_dev_attr->machine  = ux500_get_machine();
+	soc_dev_attr->family   = ux500_get_family();
+	soc_dev_attr->revision = ux500_get_revision();
+}
+
+struct device_attribute ux500_soc_attr =
+	__ATTR(process,  S_IRUGO, ux500_get_process,  NULL);
+
+struct device * __init ux500_soc_device_init(const char *soc_id)
+{
+	struct device *parent;
+	struct soc_device *soc_dev;
+	struct soc_device_attribute *soc_dev_attr;
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return ERR_PTR(-ENOMEM);
+
+	soc_info_populate(soc_dev_attr, soc_id);
+
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR_OR_NULL(soc_dev)) {
+	        kfree(soc_dev_attr);
+		return NULL;
+	}
+
+	parent = soc_device_to_device(soc_dev);
+	if (!IS_ERR_OR_NULL(parent))
+		device_create_file(parent, &ux500_soc_attr);
+
+	return parent;
+}
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
index c563e54..2be8fde 100644
--- a/arch/arm/mach-ux500/devices-common.c
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -20,35 +20,30 @@
 #include "devices-common.h"
 
 struct amba_device *
-dbx500_add_amba_device(const char *name, resource_size_t base,
-		       int irq, void *pdata, unsigned int periphid)
+dbx500_add_amba_device(struct device *parent, const char *name,
+		       resource_size_t base, int irq, void *pdata,
+		       unsigned int periphid)
 {
 	struct amba_device *dev;
 	int ret;
 
-	dev = kzalloc(sizeof *dev, GFP_KERNEL);
+	dev = amba_device_alloc(name, base, SZ_4K);
 	if (!dev)
 		return ERR_PTR(-ENOMEM);
 
-	dev->dev.init_name = name;
-
-	dev->res.start = base;
-	dev->res.end = base + SZ_4K - 1;
-	dev->res.flags = IORESOURCE_MEM;
-
 	dev->dma_mask = DMA_BIT_MASK(32);
 	dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
 	dev->irq[0] = irq;
-	dev->irq[1] = NO_IRQ;
 
 	dev->periphid = periphid;
 
 	dev->dev.platform_data = pdata;
+	dev->dev.parent = parent;
 
-	ret = amba_device_register(dev, &iomem_resource);
+	ret = amba_device_add(dev, &iomem_resource);
 	if (ret) {
-		kfree(dev);
+		amba_device_put(dev);
 		return ERR_PTR(ret);
 	}
 
@@ -56,60 +51,7 @@ dbx500_add_amba_device(const char *name, resource_size_t base,
 }
 
 static struct platform_device *
-dbx500_add_platform_device(const char *name, int id, void *pdata,
-			   struct resource *res, int resnum)
-{
-	struct platform_device *dev;
-	int ret;
-
-	dev = platform_device_alloc(name, id);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-	dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
-
-	ret = platform_device_add_resources(dev, res, resnum);
-	if (ret)
-		goto out_free;
-
-	dev->dev.platform_data = pdata;
-
-	ret = platform_device_add(dev);
-	if (ret)
-		goto out_free;
-
-	return dev;
-
-out_free:
-	platform_device_put(dev);
-	return ERR_PTR(ret);
-}
-
-struct platform_device *
-dbx500_add_platform_device_4k1irq(const char *name, int id,
-				  resource_size_t base,
-				  int irq, void *pdata)
-{
-	struct resource resources[] = {
-		[0] = {
-			.start	= base,
-			.end	= base + SZ_4K - 1,
-			.flags	= IORESOURCE_MEM,
-		},
-		[1] = {
-			.start	= irq,
-			.end	= irq,
-			.flags	= IORESOURCE_IRQ,
-		}
-	};
-
-	return dbx500_add_platform_device(name, id, pdata, resources,
-					  ARRAY_SIZE(resources));
-}
-
-static struct platform_device *
-dbx500_add_gpio(int id, resource_size_t addr, int irq,
+dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq,
 		struct nmk_gpio_platform_data *pdata)
 {
 	struct resource resources[] = {
@@ -125,13 +67,18 @@ dbx500_add_gpio(int id, resource_size_t addr, int irq,
 		}
 	};
 
-	return platform_device_register_resndata(NULL, "gpio", id,
-				resources, ARRAY_SIZE(resources),
-				pdata, sizeof(*pdata));
+	return platform_device_register_resndata(
+		parent,
+		"gpio",
+		id,
+		resources,
+		ARRAY_SIZE(resources),
+		pdata,
+		sizeof(*pdata));
 }
 
-void dbx500_add_gpios(resource_size_t *base, int num, int irq,
-		      struct nmk_gpio_platform_data *pdata)
+void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
+		      int irq, struct nmk_gpio_platform_data *pdata)
 {
 	int first = 0;
 	int i;
@@ -141,6 +88,6 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq,
 		pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
 		pdata->num_gpio = 32;
 
-		dbx500_add_gpio(i, base[i], irq, pdata);
+		dbx500_add_gpio(parent, i, base[i], irq, pdata);
 	}
 }
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
index 7825705..39c74ec 100644
--- a/arch/arm/mach-ux500/devices-common.h
+++ b/arch/arm/mach-ux500/devices-common.h
@@ -8,80 +8,89 @@
 #ifndef __DEVICES_COMMON_H
 #define __DEVICES_COMMON_H
 
-extern struct amba_device *
-dbx500_add_amba_device(const char *name, resource_size_t base,
-		       int irq, void *pdata, unsigned int periphid);
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/sys_soc.h>
+#include <plat/i2c.h>
 
-extern struct platform_device *
-dbx500_add_platform_device_4k1irq(const char *name, int id,
-				  resource_size_t base,
-				  int irq, void *pdata);
+extern struct amba_device *
+dbx500_add_amba_device(struct device *parent, const char *name,
+		       resource_size_t base, int irq, void *pdata,
+		       unsigned int periphid);
 
 struct spi_master_cntlr;
 
 static inline struct amba_device *
-dbx500_add_msp_spi(const char *name, resource_size_t base, int irq,
+dbx500_add_msp_spi(struct device *parent, const char *name,
+		   resource_size_t base, int irq,
 		   struct spi_master_cntlr *pdata)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, 0);
+	return dbx500_add_amba_device(parent, name, base, irq,
+				      pdata, 0);
 }
 
 static inline struct amba_device *
-dbx500_add_spi(const char *name, resource_size_t base, int irq,
-	       struct spi_master_cntlr *pdata,
+dbx500_add_spi(struct device *parent, const char *name, resource_size_t base,
+	       int irq, struct spi_master_cntlr *pdata,
 	       u32 periphid)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, periphid);
+	return dbx500_add_amba_device(parent, name, base, irq,
+				      pdata, periphid);
 }
 
 struct mmci_platform_data;
 
 static inline struct amba_device *
-dbx500_add_sdi(const char *name, resource_size_t base, int irq,
-	       struct mmci_platform_data *pdata,
-	       u32 periphid)
+dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base,
+	       int irq, struct mmci_platform_data *pdata, u32 periphid)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, periphid);
+	return dbx500_add_amba_device(parent, name, base, irq,
+				      pdata, periphid);
 }
 
 struct amba_pl011_data;
 
 static inline struct amba_device *
-dbx500_add_uart(const char *name, resource_size_t base, int irq,
-		struct amba_pl011_data *pdata)
+dbx500_add_uart(struct device *parent, const char *name, resource_size_t base,
+		int irq, struct amba_pl011_data *pdata)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, 0);
+	return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
 }
 
 struct nmk_i2c_controller;
 
 static inline struct platform_device *
-dbx500_add_i2c(int id, resource_size_t base, int irq,
-	       struct nmk_i2c_controller *pdata)
-{
-	return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq,
-						 pdata);
-}
-
-struct msp_i2s_platform_data;
-
-static inline struct platform_device *
-dbx500_add_msp_i2s(int id, resource_size_t base, int irq,
-		   struct msp_i2s_platform_data *pdata)
+dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq,
+	       struct nmk_i2c_controller *data)
 {
-	return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq,
-						 pdata);
+	struct resource res[] = {
+		DEFINE_RES_MEM(base, SZ_4K),
+		DEFINE_RES_IRQ(irq),
+	};
+
+	struct platform_device_info pdevinfo = {
+		.parent = parent,
+		.name = "nmk-i2c",
+		.id = id,
+		.res = res,
+		.num_res = ARRAY_SIZE(res),
+		.data = data,
+		.size_data = sizeof(*data),
+		.dma_mask = DMA_BIT_MASK(32),
+	};
+
+	return platform_device_register_full(&pdevinfo);
 }
 
 static inline struct amba_device *
-dbx500_add_rtc(resource_size_t base, int irq)
+dbx500_add_rtc(struct device *parent, resource_size_t base, int irq)
 {
-	return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0);
+	return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0);
 }
 
 struct nmk_gpio_platform_data;
 
-void dbx500_add_gpios(resource_size_t *base, int num, int irq,
-		      struct nmk_gpio_platform_data *pdata);
+void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num,
+		      int irq, struct nmk_gpio_platform_data *pdata);
 
 #endif
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h
index 0c4bccd..e709555 100644
--- a/arch/arm/mach-ux500/devices-db5500.h
+++ b/arch/arm/mach-ux500/devices-db5500.h
@@ -10,70 +10,90 @@
 
 #include "devices-common.h"
 
-#define db5500_add_i2c1(pdata) \
-	dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
-#define db5500_add_i2c2(pdata) \
-	dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
-#define db5500_add_i2c3(pdata) \
-	dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
+#define db5500_add_i2c1(parent, pdata) \
+	dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
+#define db5500_add_i2c2(parent, pdata) \
+	dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
+#define db5500_add_i2c3(parent, pdata) \
+	dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
 
-#define db5500_add_msp0_i2s(pdata) \
-	dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
-#define db5500_add_msp1_i2s(pdata) \
-	dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
-#define db5500_add_msp2_i2s(pdata) \
-	dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+#define db5500_add_msp0_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \
+			   IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \
+			   IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \
+			   IRQ_DB5500_MSP2, pdata)
 
-#define db5500_add_msp0_spi(pdata) \
-	dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
-#define db5500_add_msp1_spi(pdata) \
-	dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
-#define db5500_add_msp2_spi(pdata) \
-	dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+#define db5500_add_msp0_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \
+			  IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \
+			  IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \
+			  IRQ_DB5500_MSP2, pdata)
 
-#define db5500_add_rtc() \
-	dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC);
+#define db5500_add_rtc(parent) \
+	dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC);
 
-#define db5500_add_usb(rx_cfg, tx_cfg) \
-	ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
+#define db5500_add_usb(parent, rx_cfg, tx_cfg) \
+	ux500_add_usb(parent, U5500_USBOTG_BASE, \
+		      IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
 
-#define db5500_add_sdi0(pdata) \
-	dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \
+#define db5500_add_sdi0(parent, pdata) \
+	dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \
+		       IRQ_DB5500_SDMMC0, pdata,	\
 		       0x10480180)
-#define db5500_add_sdi1(pdata) \
-	dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \
+#define db5500_add_sdi1(parent, pdata) \
+	dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \
+		       IRQ_DB5500_SDMMC1, pdata,	\
 		       0x10480180)
-#define db5500_add_sdi2(pdata) \
-	dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \
+#define db5500_add_sdi2(parent, pdata) \
+	dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \
+		       IRQ_DB5500_SDMMC2, pdata		\
 		       0x10480180)
-#define db5500_add_sdi3(pdata) \
-	dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \
+#define db5500_add_sdi3(parent, pdata) \
+	dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \
+		       IRQ_DB5500_SDMMC3, pdata		\
 		       0x10480180)
-#define db5500_add_sdi4(pdata) \
-	dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \
+#define db5500_add_sdi4(parent, pdata) \
+	dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \
+		       IRQ_DB5500_SDMMC4, pdata		\
 		       0x10480180)
 
 /* This one has a bad peripheral ID in the U5500 silicon */
-#define db5500_add_spi0(pdata) \
-	dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \
+#define db5500_add_spi0(parent, pdata) \
+	dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \
+		       IRQ_DB5500_SPI0, pdata,		\
 		       0x10080023)
-#define db5500_add_spi1(pdata) \
-	dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \
+#define db5500_add_spi1(parent, pdata) \
+	dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \
+		       IRQ_DB5500_SPI1, pdata,		\
 		       0x10080023)
-#define db5500_add_spi2(pdata) \
-	dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \
+#define db5500_add_spi2(parent, pdata) \
+	dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \
+		       IRQ_DB5500_SPI2, pdata		\
 		       0x10080023)
-#define db5500_add_spi3(pdata) \
-	dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \
+#define db5500_add_spi3(parent, pdata) \
+	dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \
+		       IRQ_DB5500_SPI3, pdata		\
 		       0x10080023)
 
-#define db5500_add_uart0(plat) \
-	dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat)
-#define db5500_add_uart1(plat) \
-	dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat)
-#define db5500_add_uart2(plat) \
-	dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat)
-#define db5500_add_uart3(plat) \
-	dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat)
+#define db5500_add_uart0(parent, plat) \
+	dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \
+			IRQ_DB5500_UART0, plat)
+#define db5500_add_uart1(parent, plat) \
+	dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \
+			IRQ_DB5500_UART1, plat)
+#define db5500_add_uart2(parent, plat) \
+	dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \
+			IRQ_DB5500_UART2, plat)
+#define db5500_add_uart3(parent, plat) \
+	dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \
+			IRQ_DB5500_UART3, plat)
 
 #endif
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h
index cbd4a9a..9fd93e9 100644
--- a/arch/arm/mach-ux500/devices-db8500.h
+++ b/arch/arm/mach-ux500/devices-db8500.h
@@ -14,88 +14,114 @@ struct ske_keypad_platform_data;
 struct pl022_ssp_controller;
 
 static inline struct platform_device *
-db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata)
+db8500_add_ske_keypad(struct device *parent,
+		      struct ske_keypad_platform_data *pdata,
+		      size_t size)
 {
-	return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1,
-						 U8500_SKE_BASE,
-						 IRQ_DB8500_KB, pdata);
+	struct resource resources[] = {
+		DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K),
+		DEFINE_RES_IRQ(IRQ_DB8500_KB),
+	};
+
+	return platform_device_register_resndata(parent, "nmk-ske-keypad", -1,
+						 resources, 2, pdata, size);
 }
 
 static inline struct amba_device *
-db8500_add_ssp(const char *name, resource_size_t base, int irq,
-	       struct pl022_ssp_controller *pdata)
+db8500_add_ssp(struct device *parent, const char *name, resource_size_t base,
+	       int irq, struct pl022_ssp_controller *pdata)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, 0);
+	return dbx500_add_amba_device(parent, name, base, irq, pdata, 0);
 }
 
 
-#define db8500_add_i2c0(pdata) \
-	dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
-#define db8500_add_i2c1(pdata) \
-	dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
-#define db8500_add_i2c2(pdata) \
-	dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
-#define db8500_add_i2c3(pdata) \
-	dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
-#define db8500_add_i2c4(pdata) \
-	dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
-
-#define db8500_add_msp0_i2s(pdata) \
-	dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_i2s(pdata) \
-	dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_i2s(pdata) \
-	dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_i2s(pdata) \
-	dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
-
-#define db8500_add_msp0_spi(pdata) \
-	dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
-#define db8500_add_msp1_spi(pdata) \
-	dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
-#define db8500_add_msp2_spi(pdata) \
-	dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
-#define db8500_add_msp3_spi(pdata) \
-	dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
-
-#define db8500_add_rtc() \
-	dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC);
-
-#define db8500_add_usb(rx_cfg, tx_cfg) \
-	ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
-
-#define db8500_add_sdi0(pdata, pid) \
-	dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid)
-#define db8500_add_sdi1(pdata, pid) \
-	dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid)
-#define db8500_add_sdi2(pdata, pid) \
-	dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid)
-#define db8500_add_sdi3(pdata, pid) \
-	dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid)
-#define db8500_add_sdi4(pdata, pid) \
-	dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid)
-#define db8500_add_sdi5(pdata, pid) \
-	dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid)
-
-#define db8500_add_ssp0(pdata) \
-	db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata)
-#define db8500_add_ssp1(pdata) \
-	db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata)
-
-#define db8500_add_spi0(pdata) \
-	dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0)
-#define db8500_add_spi1(pdata) \
-	dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0)
-#define db8500_add_spi2(pdata) \
-	dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0)
-#define db8500_add_spi3(pdata) \
-	dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0)
-
-#define db8500_add_uart0(pdata) \
-	dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata)
-#define db8500_add_uart1(pdata) \
-	dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata)
-#define db8500_add_uart2(pdata) \
-	dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata)
+#define db8500_add_i2c0(parent, pdata) \
+	dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
+#define db8500_add_i2c1(parent, pdata) \
+	dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
+#define db8500_add_i2c2(parent, pdata) \
+	dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
+#define db8500_add_i2c3(parent, pdata) \
+	dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
+#define db8500_add_i2c4(parent, pdata) \
+	dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
+
+#define db8500_add_msp0_i2s(parent, pdata) \
+	dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_i2s(parent, pdata) \
+	dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_i2s(parent, pdata) \
+	dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_i2s(parent, pdata) \
+	dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_msp0_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \
+			   IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \
+			   IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \
+			   IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_spi(parent, pdata) \
+	dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \
+			   IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_rtc(parent) \
+	dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC);
+
+#define db8500_add_usb(parent, rx_cfg, tx_cfg) \
+	ux500_add_usb(parent, U8500_USBOTG_BASE, \
+		      IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
+
+#define db8500_add_sdi0(parent, pdata, pid) \
+	dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \
+		       IRQ_DB8500_SDMMC0, pdata, pid)
+#define db8500_add_sdi1(parent, pdata, pid) \
+	dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \
+		       IRQ_DB8500_SDMMC1, pdata, pid)
+#define db8500_add_sdi2(parent, pdata, pid) \
+	dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \
+		       IRQ_DB8500_SDMMC2, pdata, pid)
+#define db8500_add_sdi3(parent, pdata, pid) \
+	dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \
+		       IRQ_DB8500_SDMMC3, pdata, pid)
+#define db8500_add_sdi4(parent, pdata, pid) \
+	dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \
+		       IRQ_DB8500_SDMMC4, pdata, pid)
+#define db8500_add_sdi5(parent, pdata, pid) \
+	dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \
+		       IRQ_DB8500_SDMMC5, pdata, pid)
+
+#define db8500_add_ssp0(parent, pdata) \
+	db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \
+		       IRQ_DB8500_SSP0, pdata)
+#define db8500_add_ssp1(parent, pdata) \
+	db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \
+		       IRQ_DB8500_SSP1, pdata)
+
+#define db8500_add_spi0(parent, pdata) \
+	dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \
+		       IRQ_DB8500_SPI0, pdata, 0)
+#define db8500_add_spi1(parent, pdata) \
+	dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \
+		       IRQ_DB8500_SPI1, pdata, 0)
+#define db8500_add_spi2(parent, pdata) \
+	dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \
+		       IRQ_DB8500_SPI2, pdata, 0)
+#define db8500_add_spi3(parent, pdata) \
+	dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \
+		       IRQ_DB8500_SPI3, pdata, 0)
+
+#define db8500_add_uart0(parent, pdata) \
+	dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \
+			IRQ_DB8500_UART0, pdata)
+#define db8500_add_uart1(parent, pdata) \
+	dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \
+			IRQ_DB8500_UART1, pdata)
+#define db8500_add_uart2(parent, pdata) \
+	dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \
+			IRQ_DB8500_UART2, pdata)
 
 #endif
diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c
index 1cfab68..41e9470 100644
--- a/arch/arm/mach-ux500/dma-db5500.c
+++ b/arch/arm/mach-ux500/dma-db5500.c
@@ -125,10 +125,11 @@ static struct platform_device dma40_device = {
 	.resource	= dma40_resources
 };
 
-void __init db5500_dma_init(void)
+void __init db5500_dma_init(struct device *parent)
 {
 	int ret;
 
+	dma40_device.dev.parent = parent;
 	ret = platform_device_register(&dma40_device);
 	if (ret)
 		dev_err(&dma40_device.dev, "unable to register device: %d\n", ret);
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index 80e10f5..9ec20b9 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -161,4 +161,7 @@
 #define U8500_MODEM_BASE	0xe000000
 #define U8500_APE_BASE		0x6000000
 
+/* SoC identification number information */
+#define U8500_BB_UID_BASE      (U8500_BACKUPRAM1_BASE + 0xFC0)
+
 #endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
index d2d4131..7d34c52 100644
--- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -13,7 +13,7 @@
 
 #define MOP500_AB8500_IRQ_BASE		IRQ_BOARD_START
 #define MOP500_AB8500_IRQ_END		(MOP500_AB8500_IRQ_BASE \
-					 + AB8500_NR_IRQS)
+					 + AB8500_MAX_NR_IRQS)
 
 /* TC35892 */
 #define TC35892_NR_INTERNAL_IRQS	8
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index a7d363f..3dc00ff 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -18,17 +18,16 @@ void __init ux500_map_io(void);
 extern void __init u5500_map_io(void);
 extern void __init u8500_map_io(void);
 
-extern void __init u5500_init_devices(void);
-extern void __init u8500_init_devices(void);
+extern struct device * __init u5500_init_devices(void);
+extern struct device * __init u8500_init_devices(void);
 
 extern void __init ux500_init_irq(void);
 
-extern void __init u5500_sdi_init(void);
+extern void __init u5500_sdi_init(struct device *parent);
 
-extern void __init db5500_dma_init(void);
+extern void __init db5500_dma_init(struct device *parent);
 
-/* We re-use nomadik_timer for this platform */
-extern void nmdk_timer_init(void);
+extern struct device *ux500_soc_device_init(const char *soc_id);
 
 struct amba_device;
 extern void __init amba_add_devices(struct amba_device *devs[], int num);
diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h
deleted file mode 100644
index 258e5c9..0000000
--- a/arch/arm/mach-ux500/include/mach/system.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2009 ST-Ericsson.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-ux500/include/mach/usb.h b/arch/arm/mach-ux500/include/mach/usb.h
index d3739d4..4c1cc50 100644
--- a/arch/arm/mach-ux500/include/mach/usb.h
+++ b/arch/arm/mach-ux500/include/mach/usb.h
@@ -20,6 +20,6 @@ struct ux500_musb_board_data {
 	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
 };
 
-void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
-	int *dma_tx_cfg);
+void ux500_add_usb(struct device *parent, resource_size_t base,
+		   int irq, int *dma_rx_cfg, int *dma_tx_cfg);
 #endif
diff --git a/arch/arm/mach-ux500/mbox-db5500.c b/arch/arm/mach-ux500/mbox-db5500.c
index 2b2d51c..0127490 100644
--- a/arch/arm/mach-ux500/mbox-db5500.c
+++ b/arch/arm/mach-ux500/mbox-db5500.c
@@ -168,7 +168,7 @@ static ssize_t mbox_read_fifo(struct device *dev,
 	return sprintf(buf, "0x%X\n", mbox_value);
 }
 
-static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
+static DEVICE_ATTR(fifo, S_IWUSR | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
 
 static int mbox_show(struct seq_file *s, void *data)
 {
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index aea467d..fd00024 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -17,19 +17,20 @@
 
 static void __init ux500_timer_init(void)
 {
+	void __iomem *mtu_timer_base;
 	void __iomem *prcmu_timer_base;
 
 	if (cpu_is_u5500()) {
 #ifdef CONFIG_LOCAL_TIMERS
 		twd_base = __io_address(U5500_TWD_BASE);
 #endif
-		mtu_base = __io_address(U5500_MTU0_BASE);
+		mtu_timer_base = __io_address(U5500_MTU0_BASE);
 		prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
 	} else if (cpu_is_u8500()) {
 #ifdef CONFIG_LOCAL_TIMERS
 		twd_base = __io_address(U8500_TWD_BASE);
 #endif
-		mtu_base = __io_address(U8500_MTU0_BASE);
+		mtu_timer_base = __io_address(U8500_MTU0_BASE);
 		prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
 	} else {
 		ux500_unknown_soc();
@@ -52,7 +53,7 @@ static void __init ux500_timer_init(void)
 	 *
 	 */
 
-	nmdk_timer_init();
+	nmdk_timer_init(mtu_timer_base);
 	clksrc_dbx500_prcmu_init(prcmu_timer_base);
 }
 
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c
index 9f9e1c2..a74af38 100644
--- a/arch/arm/mach-ux500/usb.c
+++ b/arch/arm/mach-ux500/usb.c
@@ -7,6 +7,7 @@
 #include <linux/platform_device.h>
 #include <linux/usb/musb.h>
 #include <linux/dma-mapping.h>
+
 #include <plat/ste_dma40.h>
 #include <mach/hardware.h>
 #include <mach/usb.h>
@@ -140,8 +141,8 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
 		musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
 }
 
-void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
-	int *dma_tx_cfg)
+void ux500_add_usb(struct device *parent, resource_size_t base, int irq,
+		   int *dma_rx_cfg, int *dma_tx_cfg)
 {
 	ux500_musb_device.resource[0].start = base;
 	ux500_musb_device.resource[0].end = base + SZ_64K - 1;
@@ -151,5 +152,7 @@ void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
 	ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
 	ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);
 
+	ux500_musb_device.dev.parent = parent;
+
 	platform_device_register(&ux500_musb_device);
 }
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 02b7b93..0968772 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -98,8 +98,11 @@ static const struct of_device_id sic_of_match[] __initconst = {
 
 void __init versatile_init_irq(void)
 {
-	vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
-	irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START);
+	struct device_node *np;
+
+	np = of_find_matching_node_by_address(NULL, vic_of_match,
+					      VERSATILE_VIC_BASE);
+	__vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np);
 
 	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
@@ -582,58 +585,58 @@ static struct pl022_ssp_controller ssp0_plat_data = {
 	.num_chipselect = 1,
 };
 
-#define AACI_IRQ	{ IRQ_AACI, NO_IRQ }
+#define AACI_IRQ	{ IRQ_AACI }
 #define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B }
-#define KMI0_IRQ	{ IRQ_SIC_KMI0, NO_IRQ }
-#define KMI1_IRQ	{ IRQ_SIC_KMI1, NO_IRQ }
+#define KMI0_IRQ	{ IRQ_SIC_KMI0 }
+#define KMI1_IRQ	{ IRQ_SIC_KMI1 }
 
 /*
  * These devices are connected directly to the multi-layer AHB switch
  */
-#define SMC_IRQ		{ NO_IRQ, NO_IRQ }
-#define MPMC_IRQ	{ NO_IRQ, NO_IRQ }
-#define CLCD_IRQ	{ IRQ_CLCDINT, NO_IRQ }
-#define DMAC_IRQ	{ IRQ_DMAINT, NO_IRQ }
+#define SMC_IRQ		{ }
+#define MPMC_IRQ	{ }
+#define CLCD_IRQ	{ IRQ_CLCDINT }
+#define DMAC_IRQ	{ IRQ_DMAINT }
 
 /*
  * These devices are connected via the core APB bridge
  */
-#define SCTL_IRQ	{ NO_IRQ, NO_IRQ }
-#define WATCHDOG_IRQ	{ IRQ_WDOGINT, NO_IRQ }
-#define GPIO0_IRQ	{ IRQ_GPIOINT0, NO_IRQ }
-#define GPIO1_IRQ	{ IRQ_GPIOINT1, NO_IRQ }
-#define RTC_IRQ		{ IRQ_RTCINT, NO_IRQ }
+#define SCTL_IRQ	{ }
+#define WATCHDOG_IRQ	{ IRQ_WDOGINT }
+#define GPIO0_IRQ	{ IRQ_GPIOINT0 }
+#define GPIO1_IRQ	{ IRQ_GPIOINT1 }
+#define RTC_IRQ		{ IRQ_RTCINT }
 
 /*
  * These devices are connected via the DMA APB bridge
  */
-#define SCI_IRQ		{ IRQ_SCIINT, NO_IRQ }
-#define UART0_IRQ	{ IRQ_UARTINT0, NO_IRQ }
-#define UART1_IRQ	{ IRQ_UARTINT1, NO_IRQ }
-#define UART2_IRQ	{ IRQ_UARTINT2, NO_IRQ }
-#define SSP_IRQ		{ IRQ_SSPINT, NO_IRQ }
+#define SCI_IRQ		{ IRQ_SCIINT }
+#define UART0_IRQ	{ IRQ_UARTINT0 }
+#define UART1_IRQ	{ IRQ_UARTINT1 }
+#define UART2_IRQ	{ IRQ_UARTINT2 }
+#define SSP_IRQ		{ IRQ_SSPINT }
 
 /* FPGA Primecells */
-AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);
-AMBA_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data);
-AMBA_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);
-AMBA_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);
+APB_DEVICE(aaci,  "fpga:04", AACI,     NULL);
+APB_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data);
+APB_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);
+APB_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);
 
 /* DevChip Primecells */
-AMBA_DEVICE(smc,   "dev:00",  SMC,      NULL);
-AMBA_DEVICE(mpmc,  "dev:10",  MPMC,     NULL);
-AMBA_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);
-AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
-AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
-AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data);
-AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
-AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
-AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
-AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);
-AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);
-AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data);
+AHB_DEVICE(smc,   "dev:00",  SMC,      NULL);
+AHB_DEVICE(mpmc,  "dev:10",  MPMC,     NULL);
+AHB_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);
+AHB_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
+APB_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
+APB_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data);
+APB_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
+APB_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
+APB_DEVICE(uart0, "dev:f1",  UART0,    NULL);
+APB_DEVICE(uart1, "dev:f2",  UART1,    NULL);
+APB_DEVICE(uart2, "dev:f3",  UART2,    NULL);
+APB_DEVICE(ssp0,  "dev:f4",  SSP,      &ssp0_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&dmac_device,
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
index 2ef2f55..683e607 100644
--- a/arch/arm/mach-versatile/core.h
+++ b/arch/arm/mach-versatile/core.h
@@ -36,20 +36,10 @@ extern unsigned int mmc_status(struct device *dev);
 extern struct of_dev_auxdata versatile_auxdata_lookup[];
 #endif
 
-#define AMBA_DEVICE(name,busid,base,plat)			\
-static struct amba_device name##_device = {			\
-	.dev		= {					\
-		.coherent_dma_mask = ~0,			\
-		.init_name = busid,				\
-		.platform_data = plat,				\
-	},							\
-	.res		= {					\
-		.start	= VERSATILE_##base##_BASE,		\
-		.end	= (VERSATILE_##base##_BASE) + SZ_4K - 1,\
-		.flags	= IORESOURCE_MEM,			\
-	},							\
-	.dma_mask	= ~0,					\
-	.irq		= base##_IRQ,				\
-}
+#define APB_DEVICE(name, busid, base, plat)	\
+static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
+
+#define AHB_DEVICE(name, busid, base, plat)	\
+static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
 
 #endif
diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h
deleted file mode 100644
index f3fa347..0000000
--- a/arch/arm/mach-versatile/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  arch/arm/mach-versatile/include/mach/system.h
- *
- *  Copyright (C) 2003 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 9581c19..1973833 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -58,28 +58,28 @@ static struct pl061_platform_data gpio3_plat_data = {
 	.irq_base	= IRQ_GPIO3_START,
 };
 
-#define UART3_IRQ	{ IRQ_SIC_UART3, NO_IRQ }
-#define SCI1_IRQ	{ IRQ_SIC_SCI3, NO_IRQ }
+#define UART3_IRQ	{ IRQ_SIC_UART3 }
+#define SCI1_IRQ	{ IRQ_SIC_SCI3 }
 #define MMCI1_IRQ	{ IRQ_MMCI1A, IRQ_SIC_MMCI1B }
 
 /*
  * These devices are connected via the core APB bridge
  */
-#define GPIO2_IRQ	{ IRQ_GPIOINT2, NO_IRQ }
-#define GPIO3_IRQ	{ IRQ_GPIOINT3, NO_IRQ }
+#define GPIO2_IRQ	{ IRQ_GPIOINT2 }
+#define GPIO3_IRQ	{ IRQ_GPIOINT3 }
 
 /*
  * These devices are connected via the DMA APB bridge
  */
 
 /* FPGA Primecells */
-AMBA_DEVICE(uart3, "fpga:09", UART3,    NULL);
-AMBA_DEVICE(sci1,  "fpga:0a", SCI1,     NULL);
-AMBA_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data);
+APB_DEVICE(uart3, "fpga:09", UART3,    NULL);
+APB_DEVICE(sci1,  "fpga:0a", SCI1,     NULL);
+APB_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data);
 
 /* DevChip Primecells */
-AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data);
-AMBA_DEVICE(gpio3, "dev:e7",  GPIO3,    &gpio3_plat_data);
+APB_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data);
+APB_DEVICE(gpio3, "dev:e7",  GPIO3,    &gpio3_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&uart3_device,
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index f439715..9f0f282 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -1,19 +1,2 @@
 #define __MMIO_P2V(x)	(((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000)
 #define MMIO_P2V(x)	((void __iomem *)__MMIO_P2V(x))
-
-#define AMBA_DEVICE(name,busid,base,plat)	\
-struct amba_device name##_device = {		\
-	.dev		= {			\
-		.coherent_dma_mask = ~0UL,	\
-		.init_name = busid,		\
-		.platform_data = plat,		\
-	},					\
-	.res		= {			\
-		.start	= base,			\
-		.end	= base + SZ_4K - 1,	\
-		.flags	= IORESOURCE_MEM,	\
-	},					\
-	.dma_mask	= ~0UL,			\
-	.irq		= IRQ_##base,		\
-	/* .dma		= DMA_##base,*/		\
-}
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index b1e87c1..1b1d2e4 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -109,10 +109,10 @@ static struct clcd_board ct_ca9x4_clcd_data = {
 	.remove		= versatile_clcd_remove_dma,
 };
 
-static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
-static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
-static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
-static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
+static AMBA_AHB_DEVICE(clcd, "ct:clcd", 0, CT_CA9X4_CLCDC, IRQ_CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
+static AMBA_APB_DEVICE(dmc, "ct:dmc", 0, CT_CA9X4_DMC, IRQ_CT_CA9X4_DMC, NULL);
+static AMBA_APB_DEVICE(smc, "ct:smc", 0, CT_CA9X4_SMC, IRQ_CT_CA9X4_SMC, NULL);
+static AMBA_APB_DEVICE(gpio, "ct:gpio", 0, CT_CA9X4_GPIO, IRQ_CT_CA9X4_GPIO, NULL);
 
 static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
 	&clcd_device,
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
index 3034a4d..9ecc46b 100644
--- a/arch/arm/mach-vexpress/hotplug.c
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -13,8 +13,8 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <asm/smp_plat.h>
-#include <asm/system.h>
 
 extern volatile int pen_release;
 
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
index a34d3d4..a40468f 100644
--- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -35,7 +35,7 @@
  * Interrupts.  Those in {} are for AMBA devices
  */
 #define IRQ_CT_CA9X4_CLCDC	{ 76 }
-#define IRQ_CT_CA9X4_DMC	{ -1 }
+#define IRQ_CT_CA9X4_DMC	{ 0 }
 #define IRQ_CT_CA9X4_SMC	{ 77, 78 }
 #define IRQ_CT_CA9X4_TIMER0	80
 #define IRQ_CT_CA9X4_TIMER1	81
diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h
index 13522d8..0088cd3 100644
--- a/arch/arm/mach-vexpress/include/mach/io.h
+++ b/arch/arm/mach-vexpress/include/mach/io.h
@@ -20,7 +20,6 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define __io(a)		__typesafe_io(a)
 #define __mem_pci(a)	(a)
 
 #endif
diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h
deleted file mode 100644
index f653a8e..0000000
--- a/arch/arm/mach-vexpress/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  arch/arm/mach-vexpress/include/mach/system.h
- *
- *  Copyright (C) 2003 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index b4a28ca..ad64f97 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -266,16 +266,16 @@ static struct mmci_platform_data v2m_mmci_data = {
 	.status		= v2m_mmci_status,
 };
 
-static AMBA_DEVICE(aaci,  "mb:aaci",  V2M_AACI, NULL);
-static AMBA_DEVICE(mmci,  "mb:mmci",  V2M_MMCI, &v2m_mmci_data);
-static AMBA_DEVICE(kmi0,  "mb:kmi0",  V2M_KMI0, NULL);
-static AMBA_DEVICE(kmi1,  "mb:kmi1",  V2M_KMI1, NULL);
-static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
-static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
-static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
-static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
-static AMBA_DEVICE(wdt,   "mb:wdt",   V2M_WDT, NULL);
-static AMBA_DEVICE(rtc,   "mb:rtc",   V2M_RTC, NULL);
+static AMBA_APB_DEVICE(aaci,  "mb:aaci",  0, V2M_AACI, IRQ_V2M_AACI, NULL);
+static AMBA_APB_DEVICE(mmci,  "mb:mmci",  0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data);
+static AMBA_APB_DEVICE(kmi0,  "mb:kmi0",  0, V2M_KMI0, IRQ_V2M_KMI0, NULL);
+static AMBA_APB_DEVICE(kmi1,  "mb:kmi1",  0, V2M_KMI1, IRQ_V2M_KMI1, NULL);
+static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL);
+static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL);
+static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL);
+static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL);
+static AMBA_APB_DEVICE(wdt,   "mb:wdt",   0, V2M_WDT, IRQ_V2M_WDT, NULL);
+static AMBA_APB_DEVICE(rtc,   "mb:rtc",   0, V2M_RTC, IRQ_V2M_RTC, NULL);
 
 static struct amba_device *v2m_amba_devs[] __initdata = {
 	&aaci_device,
diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h
index d6c757e..58fa801 100644
--- a/arch/arm/mach-vt8500/include/mach/system.h
+++ b/arch/arm/mach-vt8500/include/mach/system.h
@@ -7,11 +7,6 @@
 /* PM Software Reset request register */
 #define VT8500_PMSR_VIRT	0xf8130060
 
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
 static inline void arch_reset(char mode, const char *cmd)
 {
 	writel(1, VT8500_PMSR_VIRT);
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
index 78110be..db82568 100644
--- a/arch/arm/mach-w90x900/dev.c
+++ b/arch/arm/mach-w90x900/dev.c
@@ -530,6 +530,7 @@ static struct platform_device *nuc900_public_dev[] __initdata = {
 
 void __init nuc900_board_init(struct platform_device **device, int size)
 {
+	disable_hlt();
 	platform_add_devices(device, size);
 	platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
 	spi_register_board_info(nuc900_spi_board_info,
diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h
deleted file mode 100644
index 2aaeb93..0000000
--- a/arch/arm/mach-w90x900/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/system.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/system.h
- *
- * 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.
- *
- */
-static void arch_idle(void)
-{
-}
diff --git a/arch/arm/mach-zynq/include/mach/system.h b/arch/arm/mach-zynq/include/mach/system.h
deleted file mode 100644
index 8e88e0b..0000000
--- a/arch/arm/mach-zynq/include/mach/system.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/system.h
- *
- *  Copyright (C) 2011 Xilinx
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- */
-
-#ifndef __MACH_SYSTEM_H__
-#define __MACH_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 1a3ca24..7edef91 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -631,7 +631,8 @@ comment "Processor Features"
 
 config ARM_LPAE
 	bool "Support for the Large Physical Address Extension"
-	depends on MMU && CPU_V7
+	depends on MMU && CPU_32v7 && !CPU_32v6 && !CPU_32v5 && \
+		!CPU_32v4 && !CPU_32v3
 	help
 	  Say Y if you have an ARMv7 processor supporting the LPAE page
 	  table format and you would like to access memory beyond the
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index caf14dc..78459b8 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -22,7 +22,7 @@
 #include <linux/sched.h>
 #include <linux/uaccess.h>
 
-#include <asm/system.h>
+#include <asm/cp15.h>
 #include <asm/unaligned.h>
 
 #include "fault.h"
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index e0b0e7a..dd3d591 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <plat/cache-feroceon-l2.h>
 
 /*
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index b1e192b..a53fd2a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -30,13 +30,13 @@
 
 static void __iomem *l2x0_base;
 static DEFINE_RAW_SPINLOCK(l2x0_lock);
-static uint32_t l2x0_way_mask;	/* Bitmask of active ways */
-static uint32_t l2x0_size;
+static u32 l2x0_way_mask;	/* Bitmask of active ways */
+static u32 l2x0_size;
 
 struct l2x0_regs l2x0_saved_regs;
 
 struct l2x0_of_data {
-	void (*setup)(const struct device_node *, __u32 *, __u32 *);
+	void (*setup)(const struct device_node *, u32 *, u32 *);
 	void (*save)(void);
 	void (*resume)(void);
 };
@@ -288,7 +288,7 @@ static void l2x0_disable(void)
 	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static void l2x0_unlock(__u32 cache_id)
+static void l2x0_unlock(u32 cache_id)
 {
 	int lockregs;
 	int i;
@@ -307,11 +307,11 @@ static void l2x0_unlock(__u32 cache_id)
 	}
 }
 
-void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 {
-	__u32 aux;
-	__u32 cache_id;
-	__u32 way_size = 0;
+	u32 aux;
+	u32 cache_id;
+	u32 way_size = 0;
 	int ways;
 	const char *type;
 
@@ -388,7 +388,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 
 #ifdef CONFIG_OF
 static void __init l2x0_of_setup(const struct device_node *np,
-				 __u32 *aux_val, __u32 *aux_mask)
+				 u32 *aux_val, u32 *aux_mask)
 {
 	u32 data[2] = { 0, 0 };
 	u32 tag = 0;
@@ -422,7 +422,7 @@ static void __init l2x0_of_setup(const struct device_node *np,
 }
 
 static void __init pl310_of_setup(const struct device_node *np,
-				  __u32 *aux_val, __u32 *aux_mask)
+				  u32 *aux_val, u32 *aux_mask)
 {
 	u32 data[3] = { 0, 0, 0 };
 	u32 tag[3] = { 0, 0, 0 };
@@ -548,7 +548,7 @@ static const struct of_device_id l2x0_ids[] __initconst = {
 	{}
 };
 
-int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask)
+int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
 {
 	struct device_node *np;
 	struct l2x0_of_data *data;
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c
index 5086865..1fbca05 100644
--- a/arch/arm/mm/cache-tauros2.c
+++ b/arch/arm/mm/cache-tauros2.c
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <asm/cacheflush.h>
+#include <asm/cp15.h>
 #include <asm/hardware/cache-tauros2.h>
 
 
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 7a24d39..a655d3d 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -55,7 +55,7 @@ loop1:
 	cmp	r1, #2				@ see what cache we have at this level
 	blt	skip				@ skip if no cache, or just i-cache
 #ifdef CONFIG_PREEMPT
-	save_and_disable_irqs r9		@ make cssr&csidr read atomic
+	save_and_disable_irqs_notrace r9	@ make cssr&csidr read atomic
 #endif
 	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
 	isb					@ isb to sych the new cssr&csidr
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
index 5a32020..6c3edeb 100644
--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -18,7 +18,7 @@
  */
 #include <linux/init.h>
 #include <linux/highmem.h>
-#include <asm/system.h>
+#include <asm/cp15.h>
 #include <asm/cputype.h>
 #include <asm/cacheflush.h>
 
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
index d2852e1..d130a5e 100644
--- a/arch/arm/mm/copypage-fa.c
+++ b/arch/arm/mm/copypage-fa.c
@@ -44,11 +44,11 @@ void fa_copy_user_highpage(struct page *to, struct page *from,
 {
 	void *kto, *kfrom;
 
-	kto = kmap_atomic(to, KM_USER0);
-	kfrom = kmap_atomic(from, KM_USER1);
+	kto = kmap_atomic(to);
+	kfrom = kmap_atomic(from);
 	fa_copy_user_page(kto, kfrom);
-	kunmap_atomic(kfrom, KM_USER1);
-	kunmap_atomic(kto, KM_USER0);
+	kunmap_atomic(kfrom);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -58,7 +58,7 @@ void fa_copy_user_highpage(struct page *to, struct page *from,
  */
 void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile("\
 	mov	r1, %2				@ 1\n\
 	mov	r2, #0				@ 1\n\
@@ -77,7 +77,7 @@ void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 32)
 	: "r1", "r2", "r3", "ip", "lr");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns fa_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c
index ac163de..49ee0c1 100644
--- a/arch/arm/mm/copypage-feroceon.c
+++ b/arch/arm/mm/copypage-feroceon.c
@@ -72,17 +72,17 @@ void feroceon_copy_user_highpage(struct page *to, struct page *from,
 {
 	void *kto, *kfrom;
 
-	kto = kmap_atomic(to, KM_USER0);
-	kfrom = kmap_atomic(from, KM_USER1);
+	kto = kmap_atomic(to);
+	kfrom = kmap_atomic(from);
 	flush_cache_page(vma, vaddr, page_to_pfn(from));
 	feroceon_copy_user_page(kto, kfrom);
-	kunmap_atomic(kfrom, KM_USER1);
-	kunmap_atomic(kto, KM_USER0);
+	kunmap_atomic(kfrom);
+	kunmap_atomic(kto);
 }
 
 void feroceon_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile ("\
 	mov	r1, %2				\n\
 	mov	r2, #0				\n\
@@ -102,7 +102,7 @@ void feroceon_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 32)
 	: "r1", "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns feroceon_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-v3.c b/arch/arm/mm/copypage-v3.c
index f72303e..3935bdd 100644
--- a/arch/arm/mm/copypage-v3.c
+++ b/arch/arm/mm/copypage-v3.c
@@ -42,11 +42,11 @@ void v3_copy_user_highpage(struct page *to, struct page *from,
 {
 	void *kto, *kfrom;
 
-	kto = kmap_atomic(to, KM_USER0);
-	kfrom = kmap_atomic(from, KM_USER1);
+	kto = kmap_atomic(to);
+	kfrom = kmap_atomic(from);
 	v3_copy_user_page(kto, kfrom);
-	kunmap_atomic(kfrom, KM_USER1);
-	kunmap_atomic(kto, KM_USER0);
+	kunmap_atomic(kfrom);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -56,7 +56,7 @@ void v3_copy_user_highpage(struct page *to, struct page *from,
  */
 void v3_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile("\n\
 	mov	r1, %2				@ 1\n\
 	mov	r2, #0				@ 1\n\
@@ -72,7 +72,7 @@ void v3_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 64)
 	: "r1", "r2", "r3", "ip", "lr");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns v3_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index 7d0a8c2..1267e64 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -23,10 +23,6 @@
 
 #include "mm.h"
 
-/*
- * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
- * specific hacks for copying pages efficiently.
- */
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
 				  L_PTE_MT_MINICACHE)
 
@@ -71,21 +67,20 @@ mc_copy_user_page(void *from, void *to)
 void v4_mc_copy_user_highpage(struct page *to, struct page *from,
 	unsigned long vaddr, struct vm_area_struct *vma)
 {
-	void *kto = kmap_atomic(to, KM_USER1);
+	void *kto = kmap_atomic(to);
 
 	if (!test_and_set_bit(PG_dcache_clean, &from->flags))
 		__flush_dcache_page(page_mapping(from), from);
 
 	raw_spin_lock(&minicache_lock);
 
-	set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0);
-	flush_tlb_kernel_page(0xffff8000);
+	set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
 
-	mc_copy_user_page((void *)0xffff8000, kto);
+	mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
 
 	raw_spin_unlock(&minicache_lock);
 
-	kunmap_atomic(kto, KM_USER1);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -93,7 +88,7 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from,
  */
 void v4_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile("\
 	mov	r1, %2				@ 1\n\
 	mov	r2, #0				@ 1\n\
@@ -111,7 +106,7 @@ void v4_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 64)
 	: "r1", "r2", "r3", "ip", "lr");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns v4_mc_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c
index cb589cb..067d0fd 100644
--- a/arch/arm/mm/copypage-v4wb.c
+++ b/arch/arm/mm/copypage-v4wb.c
@@ -52,12 +52,12 @@ void v4wb_copy_user_highpage(struct page *to, struct page *from,
 {
 	void *kto, *kfrom;
 
-	kto = kmap_atomic(to, KM_USER0);
-	kfrom = kmap_atomic(from, KM_USER1);
+	kto = kmap_atomic(to);
+	kfrom = kmap_atomic(from);
 	flush_cache_page(vma, vaddr, page_to_pfn(from));
 	v4wb_copy_user_page(kto, kfrom);
-	kunmap_atomic(kfrom, KM_USER1);
-	kunmap_atomic(kto, KM_USER0);
+	kunmap_atomic(kfrom);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -67,7 +67,7 @@ void v4wb_copy_user_highpage(struct page *to, struct page *from,
  */
 void v4wb_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile("\
 	mov	r1, %2				@ 1\n\
 	mov	r2, #0				@ 1\n\
@@ -86,7 +86,7 @@ void v4wb_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 64)
 	: "r1", "r2", "r3", "ip", "lr");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns v4wb_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c
index 30c7d04..b85c5da 100644
--- a/arch/arm/mm/copypage-v4wt.c
+++ b/arch/arm/mm/copypage-v4wt.c
@@ -48,11 +48,11 @@ void v4wt_copy_user_highpage(struct page *to, struct page *from,
 {
 	void *kto, *kfrom;
 
-	kto = kmap_atomic(to, KM_USER0);
-	kfrom = kmap_atomic(from, KM_USER1);
+	kto = kmap_atomic(to);
+	kfrom = kmap_atomic(from);
 	v4wt_copy_user_page(kto, kfrom);
-	kunmap_atomic(kfrom, KM_USER1);
-	kunmap_atomic(kto, KM_USER0);
+	kunmap_atomic(kfrom);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -62,7 +62,7 @@ void v4wt_copy_user_highpage(struct page *to, struct page *from,
  */
 void v4wt_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile("\
 	mov	r1, %2				@ 1\n\
 	mov	r2, #0				@ 1\n\
@@ -79,7 +79,7 @@ void v4wt_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 64)
 	: "r1", "r2", "r3", "ip", "lr");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns v4wt_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 3d9a155..b9bcc9d 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -24,9 +24,6 @@
 #error FIX ME
 #endif
 
-#define from_address	(0xffff8000)
-#define to_address	(0xffffc000)
-
 static DEFINE_RAW_SPINLOCK(v6_lock);
 
 /*
@@ -38,11 +35,11 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
 {
 	void *kto, *kfrom;
 
-	kfrom = kmap_atomic(from, KM_USER0);
-	kto = kmap_atomic(to, KM_USER1);
+	kfrom = kmap_atomic(from);
+	kto = kmap_atomic(to);
 	copy_page(kto, kfrom);
-	kunmap_atomic(kto, KM_USER1);
-	kunmap_atomic(kfrom, KM_USER0);
+	kunmap_atomic(kto);
+	kunmap_atomic(kfrom);
 }
 
 /*
@@ -51,9 +48,9 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
  */
 static void v6_clear_user_highpage_nonaliasing(struct page *page, unsigned long vaddr)
 {
-	void *kaddr = kmap_atomic(page, KM_USER0);
+	void *kaddr = kmap_atomic(page);
 	clear_page(kaddr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 /*
@@ -90,14 +87,11 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
 	 */
 	raw_spin_lock(&v6_lock);
 
-	set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0);
-	set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0);
-
-	kfrom = from_address + (offset << PAGE_SHIFT);
-	kto   = to_address + (offset << PAGE_SHIFT);
+	kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT);
+	kto   = COPYPAGE_V6_TO + (offset << PAGE_SHIFT);
 
-	flush_tlb_kernel_page(kfrom);
-	flush_tlb_kernel_page(kto);
+	set_top_pte(kfrom, mk_pte(from, PAGE_KERNEL));
+	set_top_pte(kto, mk_pte(to, PAGE_KERNEL));
 
 	copy_page((void *)kto, (void *)kfrom);
 
@@ -111,8 +105,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to,
  */
 static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr)
 {
-	unsigned int offset = CACHE_COLOUR(vaddr);
-	unsigned long to = to_address + (offset << PAGE_SHIFT);
+	unsigned long to = COPYPAGE_V6_TO + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
 
 	/* FIXME: not highmem safe */
 	discard_old_kernel_data(page_address(page));
@@ -123,8 +116,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad
 	 */
 	raw_spin_lock(&v6_lock);
 
-	set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0);
-	flush_tlb_kernel_page(to);
+	set_top_pte(to, mk_pte(page, PAGE_KERNEL));
 	clear_page((void *)to);
 
 	raw_spin_unlock(&v6_lock);
diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c
index f9cde07..03a2042 100644
--- a/arch/arm/mm/copypage-xsc3.c
+++ b/arch/arm/mm/copypage-xsc3.c
@@ -75,12 +75,12 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
 {
 	void *kto, *kfrom;
 
-	kto = kmap_atomic(to, KM_USER0);
-	kfrom = kmap_atomic(from, KM_USER1);
+	kto = kmap_atomic(to);
+	kfrom = kmap_atomic(from);
 	flush_cache_page(vma, vaddr, page_to_pfn(from));
 	xsc3_mc_copy_user_page(kto, kfrom);
-	kunmap_atomic(kfrom, KM_USER1);
-	kunmap_atomic(kto, KM_USER0);
+	kunmap_atomic(kfrom);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -90,7 +90,7 @@ void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
  */
 void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile ("\
 	mov	r1, %2				\n\
 	mov	r2, #0				\n\
@@ -105,7 +105,7 @@ void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 32)
 	: "r1", "r2", "r3");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns xsc3_mc_user_fns __initdata = {
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 610c24c..0fb8502 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -23,12 +23,6 @@
 
 #include "mm.h"
 
-/*
- * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
- * specific hacks for copying pages efficiently.
- */
-#define COPYPAGE_MINICACHE	0xffff8000
-
 #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
 				  L_PTE_MT_MINICACHE)
 
@@ -93,21 +87,20 @@ mc_copy_user_page(void *from, void *to)
 void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
 	unsigned long vaddr, struct vm_area_struct *vma)
 {
-	void *kto = kmap_atomic(to, KM_USER1);
+	void *kto = kmap_atomic(to);
 
 	if (!test_and_set_bit(PG_dcache_clean, &from->flags))
 		__flush_dcache_page(page_mapping(from), from);
 
 	raw_spin_lock(&minicache_lock);
 
-	set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0);
-	flush_tlb_kernel_page(COPYPAGE_MINICACHE);
+	set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot));
 
 	mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
 
 	raw_spin_unlock(&minicache_lock);
 
-	kunmap_atomic(kto, KM_USER1);
+	kunmap_atomic(kto);
 }
 
 /*
@@ -116,7 +109,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
 void
 xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+	void *ptr, *kaddr = kmap_atomic(page);
 	asm volatile(
 	"mov	r1, %2				\n\
 	mov	r2, #0				\n\
@@ -133,7 +126,7 @@ xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 	: "=r" (ptr)
 	: "0" (kaddr), "I" (PAGE_SIZE / 32)
 	: "r1", "r2", "r3", "ip");
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 struct cpu_user_fns xscale_mc_user_fns __initdata = {
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1aa664a..db23ae4 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -214,7 +214,8 @@ static int __init consistent_init(void)
 core_initcall(consistent_init);
 
 static void *
-__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
+	const void *caller)
 {
 	struct arm_vmregion *c;
 	size_t align;
@@ -241,7 +242,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
 	 * Allocate a virtual address in the consistent mapping region.
 	 */
 	c = arm_vmregion_alloc(&consistent_head, align, size,
-			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
+			    gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller);
 	if (c) {
 		pte_t *pte;
 		int idx = CONSISTENT_PTE_INDEX(c->vm_start);
@@ -320,14 +321,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size)
 
 #else	/* !CONFIG_MMU */
 
-#define __dma_alloc_remap(page, size, gfp, prot)	page_address(page)
+#define __dma_alloc_remap(page, size, gfp, prot, c)	page_address(page)
 #define __dma_free_remap(addr, size)			do { } while (0)
 
 #endif	/* CONFIG_MMU */
 
 static void *
 __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
-	    pgprot_t prot)
+	    pgprot_t prot, const void *caller)
 {
 	struct page *page;
 	void *addr;
@@ -349,7 +350,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
 		return NULL;
 
 	if (!arch_is_coherent())
-		addr = __dma_alloc_remap(page, size, gfp, prot);
+		addr = __dma_alloc_remap(page, size, gfp, prot, caller);
 	else
 		addr = page_address(page);
 
@@ -374,7 +375,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
 		return memory;
 
 	return __dma_alloc(dev, size, handle, gfp,
-			   pgprot_dmacoherent(pgprot_kernel));
+			   pgprot_dmacoherent(pgprot_kernel),
+			   __builtin_return_address(0));
 }
 EXPORT_SYMBOL(dma_alloc_coherent);
 
@@ -386,7 +388,8 @@ void *
 dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
 {
 	return __dma_alloc(dev, size, handle, gfp,
-			   pgprot_writecombine(pgprot_kernel));
+			   pgprot_writecombine(pgprot_kernel),
+			   __builtin_return_address(0));
 }
 EXPORT_SYMBOL(dma_alloc_writecombine);
 
@@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask);
 
 static int __init dma_debug_do_init(void)
 {
+#ifdef CONFIG_MMU
+	arm_vmregion_create_proc("dma-mappings", &consistent_head);
+#endif
 	dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
 	return 0;
 }
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index bb7eac3..40c43a9 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -164,7 +164,8 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
 	struct siginfo si;
 
 #ifdef CONFIG_DEBUG_USER
-	if (user_debug & UDBG_SEGV) {
+	if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
+	    ((user_debug & UDBG_BUS)  && (sig == SIGBUS))) {
 		printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
 		       tsk->comm, sig, addr, fsr);
 		show_pte(tsk->mm, addr);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 1a8d4aa..4d0b70f 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -23,15 +23,12 @@
 
 #ifdef CONFIG_CPU_CACHE_VIPT
 
-#define ALIAS_FLUSH_START	0xffff4000
-
 static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
 {
-	unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+	unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
 	const int zero = 0;
 
-	set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0);
-	flush_tlb_kernel_page(to);
+	set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL));
 
 	asm(	"mcrr	p15, 0, %1, %0, c14\n"
 	"	mcr	p15, 0, %2, c7, c10, 4"
@@ -42,13 +39,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
 
 static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len)
 {
-	unsigned long colour = CACHE_COLOUR(vaddr);
+	unsigned long va = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
 	unsigned long offset = vaddr & (PAGE_SIZE - 1);
 	unsigned long to;
 
-	set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0);
-	to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset;
-	flush_tlb_kernel_page(to);
+	set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL));
+	to = va + offset;
 	flush_icache_range(to, to + len);
 }
 
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 807c057..21b9e1b 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -36,7 +36,7 @@ void kunmap(struct page *page)
 }
 EXPORT_SYMBOL(kunmap);
 
-void *__kmap_atomic(struct page *page)
+void *kmap_atomic(struct page *page)
 {
 	unsigned int idx;
 	unsigned long vaddr;
@@ -69,19 +69,18 @@ void *__kmap_atomic(struct page *page)
 	 * With debugging enabled, kunmap_atomic forces that entry to 0.
 	 * Make sure it was indeed properly unmapped.
 	 */
-	BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+	BUG_ON(!pte_none(get_top_pte(vaddr)));
 #endif
-	set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0);
 	/*
 	 * When debugging is off, kunmap_atomic leaves the previous mapping
-	 * in place, so this TLB flush ensures the TLB is updated with the
-	 * new mapping.
+	 * in place, so the contained TLB flush ensures the TLB is updated
+	 * with the new mapping.
 	 */
-	local_flush_tlb_kernel_page(vaddr);
+	set_top_pte(vaddr, mk_pte(page, kmap_prot));
 
 	return (void *)vaddr;
 }
-EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic);
 
 void __kunmap_atomic(void *kvaddr)
 {
@@ -96,8 +95,7 @@ void __kunmap_atomic(void *kvaddr)
 			__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
 		BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
-		set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
-		local_flush_tlb_kernel_page(vaddr);
+		set_top_pte(vaddr, __pte(0));
 #else
 		(void) idx;  /* to kill a warning */
 #endif
@@ -121,10 +119,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
 	idx = type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
-	BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+	BUG_ON(!pte_none(get_top_pte(vaddr)));
 #endif
-	set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0);
-	local_flush_tlb_kernel_page(vaddr);
+	set_top_pte(vaddr, pfn_pte(pfn, kmap_prot));
 
 	return (void *)vaddr;
 }
@@ -132,11 +129,9 @@ void *kmap_atomic_pfn(unsigned long pfn)
 struct page *kmap_atomic_to_page(const void *ptr)
 {
 	unsigned long vaddr = (unsigned long)ptr;
-	pte_t *pte;
 
 	if (vaddr < FIXADDR_START)
 		return virt_to_page(ptr);
 
-	pte = TOP_PTE(vaddr);
-	return pte_page(*pte);
+	return pte_page(get_top_pte(vaddr));
 }
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 5dc7d12..595079f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -32,7 +32,6 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/memblock.h>
 
 #include "mm.h"
 
@@ -659,7 +658,9 @@ void __init mem_init(void)
 #ifdef CONFIG_HIGHMEM
 			"    pkmap   : 0x%08lx - 0x%08lx   (%4ld MB)\n"
 #endif
+#ifdef CONFIG_MODULES
 			"    modules : 0x%08lx - 0x%08lx   (%4ld MB)\n"
+#endif
 			"      .text : 0x%p" " - 0x%p" "   (%4d kB)\n"
 			"      .init : 0x%p" " - 0x%p" "   (%4d kB)\n"
 			"      .data : 0x%p" " - 0x%p" "   (%4d kB)\n"
@@ -678,7 +679,9 @@ void __init mem_init(void)
 			MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
 				(PAGE_SIZE)),
 #endif
+#ifdef CONFIG_MODULES
 			MLM(MODULES_VADDR, MODULES_END),
+#endif
 
 			MLK_ROUNDUP(_text, _etext),
 			MLK_ROUNDUP(__init_begin, __init_end),
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 80632e8..66daf17 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -26,6 +26,7 @@
 #include <linux/vmalloc.h>
 #include <linux/io.h>
 
+#include <asm/cp15.h>
 #include <asm/cputype.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 70f6d3ea..27f4a61 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -3,7 +3,31 @@
 /* the upper-most page table pointer */
 extern pmd_t *top_pmd;
 
-#define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently, while 0xffff4000
+ * is reserved for VIPT aliasing flushing by generic code.
+ *
+ * Note that we don't allow VIPT aliasing caches with SMP.
+ */
+#define COPYPAGE_MINICACHE	0xffff8000
+#define COPYPAGE_V6_FROM	0xffff8000
+#define COPYPAGE_V6_TO		0xffffc000
+/* PFN alias flushing, for VIPT caches */
+#define FLUSH_ALIAS_START	0xffff4000
+
+static inline void set_top_pte(unsigned long va, pte_t pte)
+{
+	pte_t *ptep = pte_offset_kernel(top_pmd, va);
+	set_pte_ext(ptep, pte, 0);
+	local_flush_tlb_kernel_page(va);
+}
+
+static inline pte_t get_top_pte(unsigned long va)
+{
+	pte_t *ptep = pte_offset_kernel(top_pmd, va);
+	return *ptep;
+}
 
 static inline pmd_t *pmd_off_k(unsigned long virt)
 {
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 94c5a0c..f77f1db 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -17,6 +17,7 @@
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
 
+#include <asm/cp15.h>
 #include <asm/cputype.h>
 #include <asm/sections.h>
 #include <asm/cachetype.h>
@@ -997,11 +998,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 {
 	struct map_desc map;
 	unsigned long addr;
+	void *vectors;
 
 	/*
 	 * Allocate the vector page early.
 	 */
-	vectors_page = early_alloc(PAGE_SIZE);
+	vectors = early_alloc(PAGE_SIZE);
+
+	early_trap_init(vectors);
 
 	for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1041,7 +1045,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
 	 * location (0xffff0000).  If we aren't using high-vectors, also
 	 * create a mapping at the low-vectors virtual address.
 	 */
-	map.pfn = __phys_to_pfn(virt_to_phys(vectors_page));
+	map.pfn = __phys_to_pfn(virt_to_phys(vectors));
 	map.virtual = 0xffff0000;
 	map.length = PAGE_SIZE;
 	map.type = MT_HIGH_VECTORS;
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index a3e78cc..0acb089 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -12,6 +12,7 @@
 #include <linux/highmem.h>
 #include <linux/slab.h>
 
+#include <asm/cp15.h>
 #include <asm/pgalloc.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 036fdbf..a631016 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -1,5 +1,8 @@
+#include <linux/fs.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 
 #include "vmregion.h"
@@ -36,7 +39,7 @@
 
 struct arm_vmregion *
 arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
-		   size_t size, gfp_t gfp)
+		   size_t size, gfp_t gfp, const void *caller)
 {
 	unsigned long start = head->vm_start, addr = head->vm_end;
 	unsigned long flags;
@@ -52,6 +55,8 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
 	if (!new)
 		goto out;
 
+	new->caller = caller;
+
 	spin_lock_irqsave(&head->vm_lock, flags);
 
 	addr = rounddown(addr - size, align);
@@ -129,3 +134,72 @@ void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
 
 	kfree(c);
 }
+
+#ifdef CONFIG_PROC_FS
+static int arm_vmregion_show(struct seq_file *m, void *p)
+{
+	struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list);
+
+	seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end,
+		c->vm_end - c->vm_start);
+	if (c->caller)
+		seq_printf(m, " %pS", (void *)c->caller);
+	seq_putc(m, '\n');
+	return 0;
+}
+
+static void *arm_vmregion_start(struct seq_file *m, loff_t *pos)
+{
+	struct arm_vmregion_head *h = m->private;
+	spin_lock_irq(&h->vm_lock);
+	return seq_list_start(&h->vm_list, *pos);
+}
+
+static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct arm_vmregion_head *h = m->private;
+	return seq_list_next(p, &h->vm_list, pos);
+}
+
+static void arm_vmregion_stop(struct seq_file *m, void *p)
+{
+	struct arm_vmregion_head *h = m->private;
+	spin_unlock_irq(&h->vm_lock);
+}
+
+static const struct seq_operations arm_vmregion_ops = {
+	.start	= arm_vmregion_start,
+	.stop	= arm_vmregion_stop,
+	.next	= arm_vmregion_next,
+	.show	= arm_vmregion_show,
+};
+
+static int arm_vmregion_open(struct inode *inode, struct file *file)
+{
+	struct arm_vmregion_head *h = PDE(inode)->data;
+	int ret = seq_open(file, &arm_vmregion_ops);
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+		m->private = h;
+	}
+	return ret;
+}
+
+static const struct file_operations arm_vmregion_fops = {
+	.open	= arm_vmregion_open,
+	.read	= seq_read,
+	.llseek	= seq_lseek,
+	.release = seq_release,
+};
+
+int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
+{
+	proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h);
+	return 0;
+}
+#else
+int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h)
+{
+	return 0;
+}
+#endif
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
index 15e9f04..162be66 100644
--- a/arch/arm/mm/vmregion.h
+++ b/arch/arm/mm/vmregion.h
@@ -19,11 +19,14 @@ struct arm_vmregion {
 	unsigned long		vm_end;
 	struct page		*vm_pages;
 	int			vm_active;
+	const void		*caller;
 };
 
-struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t);
+struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *);
 struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
 struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
 void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
 
+int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *);
+
 #endif
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 8cced35..0e51fc3 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -73,13 +73,13 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
 		return -ENOMEM;
 
 	if (audmux_clk)
-		clk_enable(audmux_clk);
+		clk_prepare_enable(audmux_clk);
 
 	ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
 	pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
 
 	if (audmux_clk)
-		clk_disable(audmux_clk);
+		clk_disable_unprepare(audmux_clk);
 
 	ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
 		       pdcr, ptcr);
@@ -172,13 +172,13 @@ int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
 		return -ENOSYS;
 
 	if (audmux_clk)
-		clk_enable(audmux_clk);
+		clk_prepare_enable(audmux_clk);
 
 	writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
 	writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
 
 	if (audmux_clk)
-		clk_disable(audmux_clk);
+		clk_disable_unprepare(audmux_clk);
 
 	return 0;
 }
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
index d8a56ae..ade4a1c 100644
--- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c
+++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
@@ -60,9 +60,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
 		dev_err(dev, "no sata clock.\n");
 		return PTR_ERR(sata_clk);
 	}
-	ret = clk_enable(sata_clk);
+	ret = clk_prepare_enable(sata_clk);
 	if (ret) {
-		dev_err(dev, "can't enable sata clock.\n");
+		dev_err(dev, "can't prepare/enable sata clock.\n");
 		goto put_sata_clk;
 	}
 
@@ -73,9 +73,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
 		ret = PTR_ERR(sata_ref_clk);
 		goto release_sata_clk;
 	}
-	ret = clk_enable(sata_ref_clk);
+	ret = clk_prepare_enable(sata_ref_clk);
 	if (ret) {
-		dev_err(dev, "can't enable sata ref clock.\n");
+		dev_err(dev, "can't prepare/enable sata ref clock.\n");
 		goto put_sata_ref_clk;
 	}
 
@@ -104,11 +104,11 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
 	return 0;
 
 release_sata_ref_clk:
-	clk_disable(sata_ref_clk);
+	clk_disable_unprepare(sata_ref_clk);
 put_sata_ref_clk:
 	clk_put(sata_ref_clk);
 release_sata_clk:
-	clk_disable(sata_clk);
+	clk_disable_unprepare(sata_clk);
 put_sata_clk:
 	clk_put(sata_clk);
 
@@ -117,10 +117,10 @@ put_sata_clk:
 
 static void imx_sata_exit(struct device *dev)
 {
-	clk_disable(sata_ref_clk);
+	clk_disable_unprepare(sata_ref_clk);
 	clk_put(sata_ref_clk);
 
-	clk_disable(sata_clk);
+	clk_disable_unprepare(sata_clk);
 	clk_put(sata_clk);
 
 }
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
index d3467f8..9129c9e 100644
--- a/arch/arm/plat-mxc/epit.c
+++ b/arch/arm/plat-mxc/epit.c
@@ -203,7 +203,7 @@ static int __init epit_clockevent_init(struct clk *timer_clk)
 
 void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
-	clk_enable(timer_clk);
+	clk_prepare_enable(timer_clk);
 
 	timer_base = base;
 
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
deleted file mode 100644
index 13ad0df..0000000
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; 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.
- */
-
-#ifndef __ASM_ARCH_MXC_SYSTEM_H__
-#define __ASM_ARCH_MXC_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index e032717..c0cab22 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -132,7 +132,7 @@ int pwm_enable(struct pwm_device *pwm)
 	int rc = 0;
 
 	if (!pwm->clk_enabled) {
-		rc = clk_enable(pwm->clk);
+		rc = clk_prepare_enable(pwm->clk);
 		if (!rc)
 			pwm->clk_enabled = 1;
 	}
@@ -145,7 +145,7 @@ void pwm_disable(struct pwm_device *pwm)
 	writel(0, pwm->mmio_base + MX3_PWMCR);
 
 	if (pwm->clk_enabled) {
-		clk_disable(pwm->clk);
+		clk_disable_unprepare(pwm->clk);
 		pwm->clk_enabled = 0;
 	}
 }
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 3599bf2..f30dcac 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -48,7 +48,7 @@ void mxc_restart(char mode, const char *cmd)
 
 		clk = clk_get_sys("imx2-wdt.0", NULL);
 		if (!IS_ERR(clk))
-			clk_enable(clk);
+			clk_prepare_enable(clk);
 		wcr_enable = (1 << 2);
 	}
 
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 1c96cdb..7daf7c9 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -283,7 +283,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
 	uint32_t tctl_val;
 
-	clk_enable(timer_clk);
+	clk_prepare_enable(timer_clk);
 
 	timer_base = base;
 
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
index bca4914..4c48c8b 100644
--- a/arch/arm/plat-nomadik/Kconfig
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -23,7 +23,6 @@ config HAS_MTU
 config NOMADIK_MTU_SCHED_CLOCK
 	bool
 	depends on HAS_MTU
-	select HAVE_SCHED_CLOCK
 	help
 	  Use the Multi Timer Unit as the sched_clock.
 
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
index 6508e76..582641f 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -1,9 +1,7 @@
 #ifndef __PLAT_MTU_H
 #define __PLAT_MTU_H
 
-/* should be set by the platform code */
-extern void __iomem *mtu_base;
-
+void nmdk_timer_init(void __iomem *base);
 void nmdk_clkevt_reset(void);
 void nmdk_clksrc_reset(void);
 
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index ad1b45b..9222e55 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -21,12 +21,6 @@
 #include <asm/sched_clock.h>
 
 /*
- * Guaranteed runtime conversion range in seconds for
- * the clocksource and clockevent.
- */
-#define MTU_MIN_RANGE 4
-
-/*
  * The MTU device hosts four different counters, with 4 set of
  * registers. These are register names.
  */
@@ -66,12 +60,11 @@
 #define MTU_PCELL2	0xff8
 #define MTU_PCELL3	0xffC
 
+static void __iomem *mtu_base;
 static bool clkevt_periodic;
 static u32 clk_prescale;
 static u32 nmdk_cycle;		/* write-once */
 
-void __iomem *mtu_base; /* Assigned by machine code */
-
 #ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
 /*
  * Override the global weak sched_clock symbol with this
@@ -103,7 +96,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
 void nmdk_clkevt_reset(void)
 {
 	if (clkevt_periodic) {
-
 		/* Timer: configure load and background-load, and fire it up */
 		writel(nmdk_cycle, mtu_base + MTU_LR(1));
 		writel(nmdk_cycle, mtu_base + MTU_BGLR(1));
@@ -121,7 +113,6 @@ void nmdk_clkevt_reset(void)
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
 			     struct clock_event_device *dev)
 {
-
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		clkevt_periodic = true;
@@ -183,15 +174,16 @@ void nmdk_clksrc_reset(void)
 	       mtu_base + MTU_CR(0));
 }
 
-void __init nmdk_timer_init(void)
+void __init nmdk_timer_init(void __iomem *base)
 {
 	unsigned long rate;
 	struct clk *clk0;
 
+	mtu_base = base;
 	clk0 = clk_get_sys("mtu0", NULL);
 	BUG_ON(IS_ERR(clk0));
-
-	clk_enable(clk0);
+	BUG_ON(clk_prepare(clk0) < 0);
+	BUG_ON(clk_enable(clk0) < 0);
 
 	/*
 	 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
@@ -224,17 +216,8 @@ void __init nmdk_timer_init(void)
 	setup_sched_clock(nomadik_read_sched_clock, 32, rate);
 #endif
 
-	/* Timer 1 is used for events */
-
-	clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
-
-	nmdk_clkevt.max_delta_ns =
-		clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
-	nmdk_clkevt.min_delta_ns =
-		clockevent_delta2ns(0x00000002, &nmdk_clkevt);
-	nmdk_clkevt.cpumask	= cpumask_of(0);
-
-	/* Register irq and clockevents */
+	/* Timer 1 is used for events, register irq and clockevents */
 	setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-	clockevents_register_device(&nmdk_clkevt);
+	nmdk_clkevt.cpumask = cpumask_of(0);
+	clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU);
 }
diff --git a/arch/arm/plat-omap/include/plat/remoteproc.h b/arch/arm/plat-omap/include/plat/remoteproc.h
new file mode 100644
index 0000000..b10eac8
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/remoteproc.h
@@ -0,0 +1,57 @@
+/*
+ * Remote Processor - omap-specific bits
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef _PLAT_REMOTEPROC_H
+#define _PLAT_REMOTEPROC_H
+
+struct rproc_ops;
+struct platform_device;
+
+/*
+ * struct omap_rproc_pdata - omap remoteproc's platform data
+ * @name: the remoteproc's name
+ * @oh_name: omap hwmod device
+ * @oh_name_opt: optional, secondary omap hwmod device
+ * @firmware: name of firmware file to load
+ * @mbox_name: name of omap mailbox device to use with this rproc
+ * @ops: start/stop rproc handlers
+ * @device_enable: omap-specific handler for enabling a device
+ * @device_shutdown: omap-specific handler for shutting down a device
+ */
+struct omap_rproc_pdata {
+	const char *name;
+	const char *oh_name;
+	const char *oh_name_opt;
+	const char *firmware;
+	const char *mbox_name;
+	const struct rproc_ops *ops;
+	int (*device_enable) (struct platform_device *pdev);
+	int (*device_shutdown) (struct platform_device *pdev);
+};
+
+#if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE)
+
+void __init omap_rproc_reserve_cma(void);
+
+#else
+
+void __init omap_rproc_reserve_cma(void)
+{
+}
+
+#endif
+
+#endif /* _PLAT_REMOTEPROC_H */
diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h
deleted file mode 100644
index 8e5ebd7..0000000
--- a/arch/arm/plat-omap/include/plat/system.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copied from arch/arm/mach-sa1100/include/mach/system.h
- * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <asm/proc-fns.h>
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 21f1fda..32a0993 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/regs-clock.h>
 #include <asm/irq.h>
 #include <asm/cacheflush.h>
 
@@ -190,8 +191,34 @@ static unsigned long s3c24xx_read_idcode_v4(void)
 	return __raw_readl(S3C2410_GSTATUS1);
 }
 
+static void s3c24xx_default_idle(void)
+{
+	unsigned long tmp;
+	int i;
+
+	/* idle the system by using the idle mode which will wait for an
+	 * interrupt to happen before restarting the system.
+	 */
+
+	/* Warning: going into idle state upsets jtag scanning */
+
+	__raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
+		     S3C2410_CLKCON);
+
+	/* the samsung port seems to do a loop and then unset idle.. */
+	for (i = 0; i < 50; i++)
+		tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
+
+	/* this bit is not cleared on re-start... */
+
+	__raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
+		     S3C2410_CLKCON);
+}
+
 void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
 {
+	arm_pm_idle = s3c24xx_default_idle;
+
 	/* initialise the io descriptors we need for initialisation */
 	iotable_init(mach_desc, size);
 	iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
index 68296b1..699f931 100644
--- a/arch/arm/plat-s3c24xx/pm-simtec.c
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -52,7 +52,7 @@ static __init int pm_simtec_init(void)
 	    !machine_is_aml_m5900())
 		return 0;
 
-	printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
+	printk(KERN_INFO "Simtec Board Power Management" COPYRIGHT "\n");
 
 	gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
 	gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 95e6819..037b448 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -53,7 +53,7 @@ int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
  * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
  * such directly equating the two source clocks is impossible.
  */
-struct clk clk_mpllref = {
+static struct clk clk_mpllref = {
 	.name		= "mpllref",
 	.parent		= &clk_xtal,
 };
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 8167ce6..e7fec78 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -80,6 +80,11 @@ config S5P_DEV_FIMC3
 	help
 	  Compile in platform device definitions for FIMC controller 3
 
+config S5P_DEV_G2D
+	bool
+	help
+	  Compile in platform device definitions for G2D device
+
 config S5P_DEV_FIMD0
 	bool
 	help
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index c496b35..139c050 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -200,7 +200,7 @@ static struct irq_chip s5p_irq_vic_eint = {
 #endif
 };
 
-int __init s5p_init_irq_eint(void)
+static int __init s5p_init_irq_eint(void)
 {
 	int irq;
 
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index 1fdfaa4..82c7311 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -41,7 +41,7 @@ struct s5p_gpioint_bank {
 	void			(*handler)(unsigned int, struct irq_desc *);
 };
 
-LIST_HEAD(banks);
+static LIST_HEAD(banks);
 
 static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
 {
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 10f7117..65c5eca 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -84,31 +84,35 @@ static int clk_null_enable(struct clk *clk, int enable)
 
 int clk_enable(struct clk *clk)
 {
+	unsigned long flags;
+
 	if (IS_ERR(clk) || clk == NULL)
 		return -EINVAL;
 
 	clk_enable(clk->parent);
 
-	spin_lock(&clocks_lock);
+	spin_lock_irqsave(&clocks_lock, flags);
 
 	if ((clk->usage++) == 0)
 		(clk->enable)(clk, 1);
 
-	spin_unlock(&clocks_lock);
+	spin_unlock_irqrestore(&clocks_lock, flags);
 	return 0;
 }
 
 void clk_disable(struct clk *clk)
 {
+	unsigned long flags;
+
 	if (IS_ERR(clk) || clk == NULL)
 		return;
 
-	spin_lock(&clocks_lock);
+	spin_lock_irqsave(&clocks_lock, flags);
 
 	if ((--clk->usage) == 0)
 		(clk->enable)(clk, 0);
 
-	spin_unlock(&clocks_lock);
+	spin_unlock_irqrestore(&clocks_lock, flags);
 	clk_disable(clk->parent);
 }
 
diff --git a/arch/arm/plat-samsung/dev-backlight.c b/arch/arm/plat-samsung/dev-backlight.c
index a976c02..2254920 100644
--- a/arch/arm/plat-samsung/dev-backlight.c
+++ b/arch/arm/plat-samsung/dev-backlight.c
@@ -115,6 +115,8 @@ void samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
 		samsung_bl_data->init = bl_data->init;
 	if (bl_data->notify)
 		samsung_bl_data->notify = bl_data->notify;
+	if (bl_data->notify_after)
+		samsung_bl_data->notify_after = bl_data->notify_after;
 	if (bl_data->exit)
 		samsung_bl_data->exit = bl_data->exit;
 	if (bl_data->check_fb)
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index f10768e..75ff3b0 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -267,6 +267,34 @@ struct platform_device s5p_device_fimc3 = {
 };
 #endif /* CONFIG_S5P_DEV_FIMC3 */
 
+/* G2D */
+
+#ifdef CONFIG_S5P_DEV_G2D
+static struct resource s5p_g2d_resource[] = {
+	[0] = {
+		.start	= S5P_PA_G2D,
+		.end	= S5P_PA_G2D + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_2D,
+		.end	= IRQ_2D,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device s5p_device_g2d = {
+	.name		= "s5p-g2d",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(s5p_g2d_resource),
+	.resource	= s5p_g2d_resource,
+	.dev		= {
+		.dma_mask		= &samsung_device_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+#endif /* CONFIG_S5P_DEV_G2D */
+
 /* FIMD0 */
 
 #ifdef CONFIG_S5P_DEV_FIMD0
@@ -323,7 +351,6 @@ struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
 	.max_width	= 4,
 	.host_caps	= (MMC_CAP_4_BIT_DATA |
 			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-	.clk_type	= S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc0 = {
@@ -354,7 +381,6 @@ struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
 	.max_width	= 4,
 	.host_caps	= (MMC_CAP_4_BIT_DATA |
 			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-	.clk_type	= S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc1 = {
@@ -387,7 +413,6 @@ struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
 	.max_width	= 4,
 	.host_caps	= (MMC_CAP_4_BIT_DATA |
 			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-	.clk_type	= S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc2 = {
@@ -418,7 +443,6 @@ struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
 	.max_width	= 4,
 	.host_caps	= (MMC_CAP_4_BIT_DATA |
 			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
-	.clk_type	= S3C_SDHCI_CLK_DIV_INTERNAL,
 };
 
 struct platform_device s3c_device_hsmmc3 = {
@@ -744,17 +768,6 @@ struct platform_device s3c_device_iis = {
 };
 #endif /* CONFIG_PLAT_S3C24XX */
 
-#ifdef CONFIG_CPU_S3C2440
-struct platform_device s3c2412_device_iis = {
-	.name		= "s3c2412-iis",
-	.id		= -1,
-	.dev		= {
-		.dma_mask		= &samsung_device_dma_mask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	}
-};
-#endif /* CONFIG_CPU_S3C2440 */
-
 /* IDE CFCON */
 
 #ifdef CONFIG_SAMSUNG_DEV_IDE
@@ -1078,7 +1091,7 @@ static struct resource s5p_pmu_resource[] = {
 	DEFINE_RES_IRQ(IRQ_PMU)
 };
 
-struct platform_device s5p_device_pmu = {
+static struct platform_device s5p_device_pmu = {
 	.name		= "arm-pmu",
 	.id		= ARM_PMU_DEVICE_CPU,
 	.num_resources	= ARRAY_SIZE(s5p_pmu_resource),
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 0747c77..301d9c3 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -116,7 +116,7 @@ static inline int samsung_dmadev_flush(unsigned ch)
 	return dmaengine_terminate_all((struct dma_chan *)ch);
 }
 
-struct samsung_dma_ops dmadev_ops = {
+static struct samsung_dma_ops dmadev_ops = {
 	.request	= samsung_dmadev_request,
 	.release	= samsung_dmadev_release,
 	.prepare	= samsung_dmadev_prepare,
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index 4214ea0..bb45848 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -79,6 +79,7 @@ extern struct platform_device s5p_device_fimc1;
 extern struct platform_device s5p_device_fimc2;
 extern struct platform_device s5p_device_fimc3;
 extern struct platform_device s5p_device_fimc_md;
+extern struct platform_device s5p_device_g2d;
 extern struct platform_device s5p_device_fimd0;
 extern struct platform_device s5p_device_hdmi;
 extern struct platform_device s5p_device_i2c_hdmiphy;
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
index 8f39aa5..bbb16e0 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -91,6 +91,9 @@
 #define VIDCON1_VSTATUS_BACKPORCH		(0x1 << 13)
 #define VIDCON1_VSTATUS_ACTIVE			(0x2 << 13)
 #define VIDCON1_VSTATUS_FRONTPORCH		(0x0 << 13)
+#define VIDCON1_VCLK_MASK			(0x3 << 9)
+#define VIDCON1_VCLK_HOLD			(0x0 << 9)
+#define VIDCON1_VCLK_RUN			(0x1 << 9)
 
 #define VIDCON1_INV_VCLK			(1 << 7)
 #define VIDCON1_INV_HSYNC			(1 << 6)
@@ -384,3 +387,9 @@
 #define WPALCON_W0PAL_16BPP_A555		(0x5 << 0)
 #define WPALCON_W0PAL_16BPP_565			(0x6 << 0)
 
+/* Blending equation control */
+#define BLENDCON				(0x260)
+#define BLENDCON_NEW_MASK			(1 << 0)
+#define BLENDCON_NEW_8BIT_ALPHA_VALUE		(1 << 0)
+#define BLENDCON_NEW_4BIT_ALPHA_VALUE		(0 << 0)
+
diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
index 30b7cc1..0f8263e 100644
--- a/arch/arm/plat-samsung/include/plat/regs-rtc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
@@ -18,51 +18,54 @@
 #define S3C2410_INTP_ALM	(1 << 1)
 #define S3C2410_INTP_TIC	(1 << 0)
 
-#define S3C2410_RTCCON	      S3C2410_RTCREG(0x40)
-#define S3C2410_RTCCON_RTCEN  (1<<0)
-#define S3C2410_RTCCON_CLKSEL (1<<1)
-#define S3C2410_RTCCON_CNTSEL (1<<2)
-#define S3C2410_RTCCON_CLKRST (1<<3)
-#define S3C64XX_RTCCON_TICEN  (1<<8)
+#define S3C2410_RTCCON		S3C2410_RTCREG(0x40)
+#define S3C2410_RTCCON_RTCEN	(1 << 0)
+#define S3C2410_RTCCON_CNTSEL	(1 << 2)
+#define S3C2410_RTCCON_CLKRST	(1 << 3)
+#define S3C2443_RTCCON_TICSEL	(1 << 4)
+#define S3C64XX_RTCCON_TICEN	(1 << 8)
 
-#define S3C64XX_RTCCON_TICMSK (0xF<<7)
-#define S3C64XX_RTCCON_TICSHT (7)
+#define S3C2410_TICNT		S3C2410_RTCREG(0x44)
+#define S3C2410_TICNT_ENABLE	(1 << 7)
 
-#define S3C2410_TICNT	      S3C2410_RTCREG(0x44)
-#define S3C2410_TICNT_ENABLE  (1<<7)
+/* S3C2443: tick count is 15 bit wide
+ * TICNT[6:0] contains upper 7 bits
+ * TICNT1[7:0] contains lower 8 bits
+ */
+#define S3C2443_TICNT_PART(x)	((x & 0x7f00) >> 8)
+#define S3C2443_TICNT1		S3C2410_RTCREG(0x4C)
+#define S3C2443_TICNT1_PART(x)	(x & 0xff)
 
-#define S3C2410_RTCALM	      S3C2410_RTCREG(0x50)
-#define S3C2410_RTCALM_ALMEN  (1<<6)
-#define S3C2410_RTCALM_YEAREN (1<<5)
-#define S3C2410_RTCALM_MONEN  (1<<4)
-#define S3C2410_RTCALM_DAYEN  (1<<3)
-#define S3C2410_RTCALM_HOUREN (1<<2)
-#define S3C2410_RTCALM_MINEN  (1<<1)
-#define S3C2410_RTCALM_SECEN  (1<<0)
+/* S3C2416: tick count is 32 bit wide
+ * TICNT[6:0] contains bits [14:8]
+ * TICNT1[7:0] contains lower 8 bits
+ * TICNT2[16:0] contains upper 17 bits
+ */
+#define S3C2416_TICNT2		S3C2410_RTCREG(0x48)
+#define S3C2416_TICNT2_PART(x)	((x & 0xffff8000) >> 15)
 
-#define S3C2410_RTCALM_ALL \
-  S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
-  S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
-  S3C2410_RTCALM_SECEN
+#define S3C2410_RTCALM		S3C2410_RTCREG(0x50)
+#define S3C2410_RTCALM_ALMEN	(1 << 6)
+#define S3C2410_RTCALM_YEAREN	(1 << 5)
+#define S3C2410_RTCALM_MONEN	(1 << 4)
+#define S3C2410_RTCALM_DAYEN	(1 << 3)
+#define S3C2410_RTCALM_HOUREN	(1 << 2)
+#define S3C2410_RTCALM_MINEN	(1 << 1)
+#define S3C2410_RTCALM_SECEN	(1 << 0)
 
+#define S3C2410_ALMSEC		S3C2410_RTCREG(0x54)
+#define S3C2410_ALMMIN		S3C2410_RTCREG(0x58)
+#define S3C2410_ALMHOUR		S3C2410_RTCREG(0x5c)
 
-#define S3C2410_ALMSEC	      S3C2410_RTCREG(0x54)
-#define S3C2410_ALMMIN	      S3C2410_RTCREG(0x58)
-#define S3C2410_ALMHOUR	      S3C2410_RTCREG(0x5c)
-
-#define S3C2410_ALMDATE	      S3C2410_RTCREG(0x60)
-#define S3C2410_ALMMON	      S3C2410_RTCREG(0x64)
-#define S3C2410_ALMYEAR	      S3C2410_RTCREG(0x68)
-
-#define S3C2410_RTCRST	      S3C2410_RTCREG(0x6c)
-
-#define S3C2410_RTCSEC	      S3C2410_RTCREG(0x70)
-#define S3C2410_RTCMIN	      S3C2410_RTCREG(0x74)
-#define S3C2410_RTCHOUR	      S3C2410_RTCREG(0x78)
-#define S3C2410_RTCDATE	      S3C2410_RTCREG(0x7c)
-#define S3C2410_RTCDAY	      S3C2410_RTCREG(0x80)
-#define S3C2410_RTCMON	      S3C2410_RTCREG(0x84)
-#define S3C2410_RTCYEAR	      S3C2410_RTCREG(0x88)
+#define S3C2410_ALMDATE		S3C2410_RTCREG(0x60)
+#define S3C2410_ALMMON		S3C2410_RTCREG(0x64)
+#define S3C2410_ALMYEAR		S3C2410_RTCREG(0x68)
 
+#define S3C2410_RTCSEC		S3C2410_RTCREG(0x70)
+#define S3C2410_RTCMIN		S3C2410_RTCREG(0x74)
+#define S3C2410_RTCHOUR		S3C2410_RTCREG(0x78)
+#define S3C2410_RTCDATE		S3C2410_RTCREG(0x7c)
+#define S3C2410_RTCMON		S3C2410_RTCREG(0x84)
+#define S3C2410_RTCYEAR		S3C2410_RTCREG(0x88)
 
 #endif /* __ASM_ARCH_REGS_RTC_H */
diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h
new file mode 100644
index 0000000..21d8594
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/rtc-core.h
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h
+ *
+ * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
+ *
+ * Samsung RTC Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_RTC_CORE_H
+#define __ASM_PLAT_RTC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+#if defined(CONFIG_SAMSUNG_DEV_RTC) || defined(CONFIG_PLAT_S3C24XX)
+	s3c_device_rtc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_RTC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index f82f888..151cc91 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -18,6 +18,8 @@
 #ifndef __PLAT_S3C_SDHCI_H
 #define __PLAT_S3C_SDHCI_H __FILE__
 
+#include <plat/devs.h>
+
 struct platform_device;
 struct mmc_host;
 struct mmc_card;
@@ -31,17 +33,12 @@ enum cd_types {
 	S3C_SDHCI_CD_PERMANENT,	/* no CD line, card permanently wired to host */
 };
 
-enum clk_types {
-	S3C_SDHCI_CLK_DIV_INTERNAL,	/* use mmc internal clock divider */
-	S3C_SDHCI_CLK_DIV_EXTERNAL,	/* use external clock divider */
-};
-
 /**
  * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
  * @max_width: The maximum number of data bits supported.
  * @host_caps: Standard MMC host capabilities bit field.
+ * @host_caps2: The second standard MMC host capabilities bit field.
  * @cd_type: Type of Card Detection method (see cd_types enum above)
- * @clk_type: Type of clock divider method (see clk_types enum above)
  * @ext_cd_init: Initialize external card detect subsystem. Called on
  *		 sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
  *		 notify_func argument is a callback to the sdhci-s3c driver
@@ -63,9 +60,9 @@ enum clk_types {
 struct s3c_sdhci_platdata {
 	unsigned int	max_width;
 	unsigned int	host_caps;
+	unsigned int	host_caps2;
 	unsigned int	pm_caps;
 	enum cd_types	cd_type;
-	enum clk_types	clk_type;
 
 	int		ext_cd_gpio;
 	bool		ext_cd_gpio_invert;
@@ -354,4 +351,30 @@ static inline void exynos4_default_sdhci3(void) { }
 
 #endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
 
+static inline void s3c_sdhci_setname(int id, char *name)
+{
+	switch (id) {
+#ifdef CONFIG_S3C_DEV_HSMMC
+	case 0:
+		s3c_device_hsmmc0.name = name;
+		break;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+	case 1:
+		s3c_device_hsmmc1.name = name;
+		break;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+	case 2:
+		s3c_device_hsmmc2.name = name;
+		break;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+	case 3:
+		s3c_device_hsmmc3.name = name;
+		break;
+#endif
+	}
+}
+
 #endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
index 0f70718..b430e99 100644
--- a/arch/arm/plat-samsung/platformdata.c
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -53,8 +53,8 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
 		set->cfg_gpio = pd->cfg_gpio;
 	if (pd->host_caps)
 		set->host_caps |= pd->host_caps;
+	if (pd->host_caps2)
+		set->host_caps2 |= pd->host_caps2;
 	if (pd->pm_caps)
 		set->pm_caps |= pd->pm_caps;
-	if (pd->clk_type)
-		set->clk_type = pd->clk_type;
 }
diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h
deleted file mode 100644
index 86c6f83..0000000
--- a/arch/arm/plat-spear/include/plat/system.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/plat-spear/include/plat/system.h
- *
- * SPEAr platform specific architecture functions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_SYSTEM_H
-#define __PLAT_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-	cpu_do_idle();
-}
-
-#endif /* __PLAT_SYSTEM_H */
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
index 52353be..043f7b0 100644
--- a/arch/arm/plat-versatile/Kconfig
+++ b/arch/arm/plat-versatile/Kconfig
@@ -11,7 +11,6 @@ config PLAT_VERSATILE_LEDS
 	depends on ARCH_REALVIEW || ARCH_VERSATILE
 
 config PLAT_VERSATILE_SCHED_CLOCK
-	def_bool y if !ARCH_INTEGRATOR_AP
-	select HAVE_SCHED_CLOCK
+	def_bool y
 
 endif
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 8f3ccdd..d89068f 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -18,6 +18,7 @@
 #include <linux/smp.h>
 #include <linux/init.h>
 
+#include <asm/cp15.h>
 #include <asm/cputype.h>
 #include <asm/thread_notify.h>
 #include <asm/vfp.h>
diff --git a/arch/avr32/include/asm/posix_types.h b/arch/avr32/include/asm/posix_types.h
index fe0c0c0..74667bf 100644
--- a/arch/avr32/include/asm/posix_types.h
+++ b/arch/avr32/include/asm/posix_types.h
@@ -14,112 +14,27 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long   __kernel_ino_t;
 typedef unsigned short  __kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short  __kernel_nlink_t;
-typedef long            __kernel_off_t;
-typedef int             __kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short  __kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned long	__kernel_size_t;
 typedef long		__kernel_ssize_t;
 typedef int             __kernel_ptrdiff_t;
-typedef long            __kernel_time_t;
-typedef long            __kernel_suseconds_t;
-typedef long            __kernel_clock_t;
-typedef int             __kernel_timer_t;
-typedef int             __kernel_clockid_t;
-typedef int             __kernel_daddr_t;
-typedef char *          __kernel_caddr_t;
-typedef unsigned short  __kernel_uid16_t;
-typedef unsigned short  __kernel_gid16_t;
-typedef unsigned int    __kernel_uid32_t;
-typedef unsigned int    __kernel_gid32_t;
+#define __kernel_size_t __kernel_size_t
 
 typedef unsigned short  __kernel_old_uid_t;
 typedef unsigned short  __kernel_old_gid_t;
-typedef unsigned short  __kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long       __kernel_loff_t;
-#endif
-
-typedef struct {
-    int     val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef  __FD_SET
-static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-    unsigned long __tmp = __fd / __NFDBITS;
-    unsigned long __rem = __fd % __NFDBITS;
-    __fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
-}
-
-#undef  __FD_CLR
-static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-    unsigned long __tmp = __fd / __NFDBITS;
-    unsigned long __rem = __fd % __NFDBITS;
-    __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
-}
+#define __kernel_old_uid_t __kernel_old_uid_t
 
+typedef unsigned short  __kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#undef  __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{
-    unsigned long __tmp = __fd / __NFDBITS;
-    unsigned long __rem = __fd % __NFDBITS;
-    return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef  __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
-{
-    unsigned long *__tmp = __p->fds_bits;
-    int __i;
-
-    if (__builtin_constant_p(__FDSET_LONGS)) {
-        switch (__FDSET_LONGS) {
-            case 16:
-                __tmp[ 0] = 0; __tmp[ 1] = 0;
-                __tmp[ 2] = 0; __tmp[ 3] = 0;
-                __tmp[ 4] = 0; __tmp[ 5] = 0;
-                __tmp[ 6] = 0; __tmp[ 7] = 0;
-                __tmp[ 8] = 0; __tmp[ 9] = 0;
-                __tmp[10] = 0; __tmp[11] = 0;
-                __tmp[12] = 0; __tmp[13] = 0;
-                __tmp[14] = 0; __tmp[15] = 0;
-                return;
-
-            case 8:
-                __tmp[ 0] = 0; __tmp[ 1] = 0;
-                __tmp[ 2] = 0; __tmp[ 3] = 0;
-                __tmp[ 4] = 0; __tmp[ 5] = 0;
-                __tmp[ 6] = 0; __tmp[ 7] = 0;
-                return;
-
-            case 4:
-                __tmp[ 0] = 0; __tmp[ 1] = 0;
-                __tmp[ 2] = 0; __tmp[ 3] = 0;
-                return;
-        }
-    }
-    __i = __FDSET_LONGS;
-    while (__i) {
-        __i--;
-        *__tmp = 0;
-        __tmp++;
-    }
-}
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif /* __ASM_AVR32_POSIX_TYPES_H */
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index 247b88c..30078f9 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -64,5 +64,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index 64f886f..feeb77b 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -87,10 +87,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -238,22 +235,15 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
 	 */
 	ret |= !valid_user_regs(regs);
 
-	/*
-	 * Block the signal if we were unsuccessful.
-	 */
-	if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka->sa.sa_mask);
-		sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
-
-	if (ret == 0)
+	if (ret != 0) {
+		force_sigsegv(sig, current);
 		return;
+	}
 
-	force_sigsegv(sig, current);
+	/*
+	 * Block the signal if we were successful.
+	 */
+	block_sigmask(ka, sig);
 }
 
 /*
diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h
index 8181293..16a24b1 100644
--- a/arch/avr32/mach-at32ap/include/mach/cpu.h
+++ b/arch/avr32/mach-at32ap/include/mach/cpu.h
@@ -30,9 +30,6 @@
 #define cpu_is_at91sam9261()	(0)
 #define cpu_is_at91sam9263()	(0)
 #define cpu_is_at91sam9rl()	(0)
-#define cpu_is_at91cap9()	(0)
-#define cpu_is_at91cap9_revB()	(0)
-#define cpu_is_at91cap9_revC()	(0)
 #define cpu_is_at91sam9g10()	(0)
 #define cpu_is_at91sam9g20()	(0)
 #define cpu_is_at91sam9g45()	(0)
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index abe5a9e..c1269a1 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -36,6 +36,7 @@ config BLACKFIN
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_PROBE
 	select IRQ_PER_CPU if SMP
+	select HAVE_NMI_WATCHDOG if NMI_WATCHDOG
 
 config GENERIC_CSUM
 	def_bool y
diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index 0b7039c..3830078 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -35,7 +33,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0x99B2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -51,7 +48,6 @@ CONFIG_IP_PNP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_JEDECPROBE=m
@@ -60,20 +56,28 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_NET_BFIN=y
 CONFIG_BFIN_MAC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_UART0=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -97,16 +101,13 @@ CONFIG_EXT2_FS=m
 CONFIG_VFAT_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
 CONFIG_NLS_CODEPAGE_437=m
 CONFIG_NLS_CODEPAGE_936=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 5553205..2f2c6ac 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -40,7 +38,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0x99B2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -56,7 +53,6 @@ CONFIG_IP_PNP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
@@ -74,10 +70,18 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=m
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_NET_BFIN=y
 CONFIG_BFIN_MAC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -85,12 +89,12 @@ CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_UART1=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=m
@@ -123,7 +127,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OTG_BLACKLIST_HUB=y
 CONFIG_USB_MON=y
-CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_STORAGE=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_BFIN=y
@@ -135,16 +138,13 @@ CONFIG_VFAT_FS=m
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
 CONFIG_NLS_CODEPAGE_437=m
 CONFIG_NLS_CODEPAGE_936=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
index 498f64a..9325d75 100644
--- a/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -39,7 +37,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0x99B2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -61,7 +58,6 @@ CONFIG_BFIN_SIR0=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_JEDECPROBE=m
@@ -77,10 +73,18 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=m
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_NET_BFIN=y
 CONFIG_BFIN_MAC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -93,12 +97,12 @@ CONFIG_TOUCHSCREEN_AD7879=y
 CONFIG_TOUCHSCREEN_AD7879_I2C=y
 CONFIG_INPUT_MISC=y
 # CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_UART1=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=m
@@ -147,7 +151,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OTG_BLACKLIST_HUB=y
 CONFIG_USB_MON=y
-CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_STORAGE=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
@@ -163,16 +166,13 @@ CONFIG_VFAT_FS=m
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
 CONFIG_NLS_CODEPAGE_437=m
 CONFIG_NLS_CODEPAGE_936=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index 72e0317..b953be0 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -38,7 +36,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0x99B2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -60,7 +57,6 @@ CONFIG_BFIN_SIR0=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_JEDECPROBE=m
@@ -76,10 +72,18 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=m
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_NET_BFIN=y
 CONFIG_BFIN_MAC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -87,12 +91,12 @@ CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_MISC=y
 # CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_UART1=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=m
@@ -141,8 +145,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OTG_BLACKLIST_HUB=y
 CONFIG_USB_MON=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_MUSB_PIO_ONLY=y
 CONFIG_USB_STORAGE=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_BFIN=y
@@ -155,16 +157,13 @@ CONFIG_VFAT_FS=m
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
 CONFIG_NLS_CODEPAGE_437=m
 CONFIG_NLS_CODEPAGE_936=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 2f075e0..127f20d 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -32,7 +30,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0xAAC2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -53,7 +50,6 @@ CONFIG_IRTTY_SIR=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_JEDECPROBE=m
@@ -62,10 +58,16 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
 CONFIG_SMC91X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -74,11 +76,11 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_BFIN5XX=y
@@ -94,12 +96,9 @@ CONFIG_RTC_DRV_BFIN=y
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index ab38a82..0df2f92 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -30,7 +28,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0xAAC2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -62,10 +59,16 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
 CONFIG_SMC91X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=m
@@ -74,11 +77,11 @@ CONFIG_INPUT_EVDEV=m
 CONFIG_INPUT_MISC=y
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=m
 CONFIG_I2C_CHARDEV=m
@@ -106,12 +109,9 @@ CONFIG_RTC_DRV_BFIN=y
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index 5c802d6..91d3eda 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -30,7 +28,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0x99B2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -45,7 +42,6 @@ CONFIG_IP_PNP=y
 CONFIG_CAN=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
-CONFIG_CAN_DEV=m
 CONFIG_CAN_BFIN=m
 CONFIG_IRDA=m
 CONFIG_IRLAN=m
@@ -58,7 +54,6 @@ CONFIG_BFIN_SIR1=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLOCK=y
@@ -69,11 +64,18 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_PHYSMAP=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
+CONFIG_NET_BFIN=y
 CONFIG_BFIN_MAC=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=m
@@ -82,12 +84,12 @@ CONFIG_INPUT_EVDEV=m
 CONFIG_INPUT_MISC=y
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
 CONFIG_SERIAL_BFIN_UART0=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=m
 CONFIG_I2C_CHARDEV=m
@@ -117,12 +119,9 @@ CONFIG_RTC_DRV_BFIN=y
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index 7a1e3bf..296de92 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -5,7 +5,6 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -85,10 +84,16 @@ CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_PATA_BF54X=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
 CONFIG_SMSC911X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -158,8 +163,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 CONFIG_USB_OTG_BLACKLIST_HUB=y
 CONFIG_USB_MON=y
-CONFIG_USB_MUSB_HDRC=y
-CONFIG_USB_MUSB_BLACKFIN=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK=m
@@ -187,7 +190,6 @@ CONFIG_NLS_CODEPAGE_437=m
 CONFIG_NLS_CODEPAGE_936=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
diff --git a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
index 78adbbf..680730e 100644
--- a/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT-SMP_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -23,17 +21,18 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_CFQ is not set
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_BF561=y
-CONFIG_SMP=y
 CONFIG_IRQ_TIMER0=10
 CONFIG_CLKIN_HZ=30000000
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=0
 CONFIG_BFIN_GPTIMERS=m
+CONFIG_BFIN_EXTMEM_WRITETHROUGH=y
+CONFIG_BFIN_L2_DCACHEABLE=y
+CONFIG_BFIN_L2_WRITETHROUGH=y
 CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0xAAC2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -54,21 +53,26 @@ CONFIG_IRTTY_SIR=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=m
+CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=m
-CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=m
-CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
 CONFIG_SMC91X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -77,11 +81,11 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_BFIN5XX=y
@@ -95,12 +99,9 @@ CONFIG_BFIN_WDT=y
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index d3cd0f5..680730e 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -4,9 +4,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_ELF_CORE is not set
 # CONFIG_FUTEX is not set
 # CONFIG_SIGNALFD is not set
@@ -35,7 +33,6 @@ CONFIG_C_CDPRIO=y
 CONFIG_BANK_3=0xAAC2
 CONFIG_BINFMT_FLAT=y
 CONFIG_BINFMT_ZFLAT=y
-CONFIG_PM=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -56,7 +53,6 @@ CONFIG_IRTTY_SIR=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -67,10 +63,16 @@ CONFIG_MTD_ROM=m
 CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
 CONFIG_SMC91X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
 # CONFIG_WLAN is not set
 CONFIG_INPUT=m
 # CONFIG_INPUT_MOUSEDEV is not set
@@ -79,11 +81,11 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_BFIN_JTAG_COMM=m
+# CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_BFIN=y
 CONFIG_SERIAL_BFIN_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_BFIN5XX=y
@@ -97,12 +99,9 @@ CONFIG_BFIN_WDT=y
 CONFIG_JFFS2_FS=m
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
-CONFIG_SMB_FS=m
-CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_SHIRQ=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_FTRACE is not set
 CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HWERR=y
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index 5392583..fb95c85 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -77,7 +77,6 @@ struct bfin5xx_spi_master {
 struct bfin5xx_spi_chip {
 	u16 ctl_reg;
 	u8 enable_dma;
-	u8 bits_per_word;
 	u16 cs_chg_udelay; /* Some devices require 16-bit delays */
 	/* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
 	u16 idle_tx_val;
diff --git a/arch/blackfin/include/asm/bfin_simple_timer.h b/arch/blackfin/include/asm/bfin_simple_timer.h
index 5248c13..aadfb1a 100644
--- a/arch/blackfin/include/asm/bfin_simple_timer.h
+++ b/arch/blackfin/include/asm/bfin_simple_timer.h
@@ -11,9 +11,11 @@
 
 #define BFIN_SIMPLE_TIMER_IOCTL_MAGIC 't'
 
-#define BFIN_SIMPLE_TIMER_SET_PERIOD _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  2)
-#define BFIN_SIMPLE_TIMER_START      _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  6)
-#define BFIN_SIMPLE_TIMER_STOP       _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  8)
-#define BFIN_SIMPLE_TIMER_READ       _IO (BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 10)
+#define BFIN_SIMPLE_TIMER_SET_PERIOD _IO(BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  2)
+#define BFIN_SIMPLE_TIMER_SET_WIDTH _IO(BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  3)
+#define BFIN_SIMPLE_TIMER_SET_MODE _IO(BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  4)
+#define BFIN_SIMPLE_TIMER_START      _IO(BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  6)
+#define BFIN_SIMPLE_TIMER_STOP       _IO(BFIN_SIMPLE_TIMER_IOCTL_MAGIC,  8)
+#define BFIN_SIMPLE_TIMER_READ       _IO(BFIN_SIMPLE_TIMER_IOCTL_MAGIC, 10)
 
 #endif
diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h
index f8568a3..0afcfbd 100644
--- a/arch/blackfin/include/asm/bfin_sport.h
+++ b/arch/blackfin/include/asm/bfin_sport.h
@@ -13,6 +13,7 @@
 #define NORM_MODE	0x0
 #define TDM_MODE	0x1
 #define I2S_MODE	0x2
+#define NDSO_MODE	0x3
 
 /* Data format, normal, a-law or u-law */
 #define NORM_FORMAT	0x0
@@ -56,6 +57,8 @@ struct sport_config {
 /* Userspace interface */
 #define SPORT_IOC_MAGIC		'P'
 #define SPORT_IOC_CONFIG	_IOWR('P', 0x01, struct sport_config)
+#define SPORT_IOC_GET_SYSTEMCLOCK         _IOR('P', 0x02, unsigned long)
+#define SPORT_IOC_SET_BAUDRATE            _IOW('P', 0x03, unsigned long)
 
 #ifdef __KERNEL__
 
diff --git a/arch/blackfin/include/asm/blackfin.h b/arch/blackfin/include/asm/blackfin.h
index 0928700..7be5368 100644
--- a/arch/blackfin/include/asm/blackfin.h
+++ b/arch/blackfin/include/asm/blackfin.h
@@ -17,22 +17,16 @@
 static inline void SSYNC(void)
 {
 	int _tmp;
-	if (ANOMALY_05000312)
+	if (ANOMALY_05000312 || ANOMALY_05000244)
 		__asm__ __volatile__(
 			"cli %0;"
 			"nop;"
 			"nop;"
+			"nop;"
 			"ssync;"
 			"sti %0;"
 			: "=d" (_tmp)
 		);
-	else if (ANOMALY_05000244)
-		__asm__ __volatile__(
-			"nop;"
-			"nop;"
-			"nop;"
-			"ssync;"
-		);
 	else
 		__asm__ __volatile__("ssync;");
 }
@@ -41,22 +35,16 @@ static inline void SSYNC(void)
 static inline void CSYNC(void)
 {
 	int _tmp;
-	if (ANOMALY_05000312)
+	if (ANOMALY_05000312 || ANOMALY_05000244)
 		__asm__ __volatile__(
 			"cli %0;"
 			"nop;"
 			"nop;"
+			"nop;"
 			"csync;"
 			"sti %0;"
 			: "=d" (_tmp)
 		);
-	else if (ANOMALY_05000244)
-		__asm__ __volatile__(
-			"nop;"
-			"nop;"
-			"nop;"
-			"csync;"
-		);
 	else
 		__asm__ __volatile__("csync;");
 }
@@ -73,18 +61,26 @@ static inline void CSYNC(void)
 #define ssync(x) SSYNC(x)
 #define csync(x) CSYNC(x)
 
-#if ANOMALY_05000312
-#define SSYNC(scratch) cli scratch; nop; nop; SSYNC; sti scratch;
-#define CSYNC(scratch) cli scratch; nop; nop; CSYNC; sti scratch;
-
-#elif ANOMALY_05000244
-#define SSYNC(scratch) nop; nop; nop; SSYNC;
-#define CSYNC(scratch) nop; nop; nop; CSYNC;
+#if ANOMALY_05000312 || ANOMALY_05000244
+#define SSYNC(scratch)	\
+do {			\
+	cli scratch;	\
+	nop; nop; nop;	\
+	SSYNC;		\
+	sti scratch;	\
+} while (0)
+
+#define CSYNC(scratch)	\
+do {			\
+	cli scratch;	\
+	nop; nop; nop;	\
+	CSYNC;		\
+	sti scratch;	\
+} while (0)
 
 #else
 #define SSYNC(scratch) SSYNC;
 #define CSYNC(scratch) CSYNC;
-
 #endif /* ANOMALY_05000312 & ANOMALY_05000244 handling */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h
index 12f4060..89de539 100644
--- a/arch/blackfin/include/asm/irq.h
+++ b/arch/blackfin/include/asm/irq.h
@@ -38,8 +38,4 @@
 
 #include <asm-generic/irq.h>
 
-#ifdef CONFIG_NMI_WATCHDOG
-# define ARCH_HAS_NMI_WATCHDOG
-#endif
-
 #endif				/* _BFIN_IRQ_H_ */
diff --git a/arch/blackfin/include/asm/kgdb.h b/arch/blackfin/include/asm/kgdb.h
index aaf8845..2703dde 100644
--- a/arch/blackfin/include/asm/kgdb.h
+++ b/arch/blackfin/include/asm/kgdb.h
@@ -109,6 +109,7 @@ static inline void arch_kgdb_breakpoint(void)
 # define CACHE_FLUSH_IS_SAFE	1
 #endif
 #define GDB_ADJUSTS_BREAK_OFFSET
+#define GDB_SKIP_HW_WATCH_TEST
 #define HW_INST_WATCHPOINT_NUM	6
 #define HW_WATCHPOINT_NUM	8
 #define TYPE_INST_WATCHPOINT	0
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index 3828c70..15b16d3 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -30,8 +30,11 @@ extern void *l1sram_alloc_max(void*);
 static inline void free_l1stack(void)
 {
 	nr_l1stack_tasks--;
-	if (nr_l1stack_tasks == 0)
+	if (nr_l1stack_tasks == 0) {
 		l1sram_free(l1_stack_base);
+		l1_stack_base = NULL;
+		l1_stack_len = 0;
+	}
 }
 
 static inline unsigned long
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 53ad100..02560fd 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -100,6 +100,7 @@ static inline struct thread_info *current_thread_info(void)
 					   TIF_NEED_RESCHED */
 #define TIF_MEMDIE		4	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
+#define TIF_FREEZE		6	/* is freezing for suspend */
 #define TIF_IRQ_SYNC		7	/* sync pipeline stage */
 #define TIF_NOTIFY_RESUME	8	/* callback before returning to user */
 #define TIF_SINGLESTEP		9
@@ -110,6 +111,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE		(1<<TIF_FREEZE)
 #define _TIF_IRQ_SYNC		(1<<TIF_IRQ_SYNC)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 0ccba60..75ec9df 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -399,8 +399,10 @@
 #define __NR_syncfs		378
 #define __NR_setns		379
 #define __NR_sendmmsg		380
+#define __NR_process_vm_readv	381
+#define __NR_process_vm_writev	382
 
-#define __NR_syscall		381
+#define __NR_syscall		383
 #define NR_syscalls		__NR_syscall
 
 /* Old optional stuff no one actually uses */
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 8de9229..b56bd85 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -120,6 +120,7 @@ MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
 		d_data = L2_DMEMORY;
 	} else if (addr >= physical_mem_end) {
 		if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
+#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)
 			mask = current_rwx_mask[cpu];
 			if (mask) {
 				int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
@@ -129,6 +130,7 @@ MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
 				if (mask[idx] & bit)
 					d_data |= CPLB_USER_RD;
 			}
+#endif
 		} else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
 		    && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
 			addr &= ~(1 * 1024 * 1024 - 1);
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index d536f35..05ece02 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -99,10 +99,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
 		goto badframe;
@@ -266,15 +263,9 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
 	/* set up the stack frame */
 	ret = setup_rt_frame(sig, ka, info, oldset, regs);
 
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
+
 	return ret;
 }
 
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index a2d96d3..a173957 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -821,7 +821,7 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	/* the MAC is stored in OTP memory page 0xDF */
 	u32 ret;
@@ -834,5 +834,6 @@ void bfin_get_ether_addr(char *addr)
 		for (ret = 0; ret < 6; ++ret)
 			addr[ret] = otp_mac_p[5 - ret];
 	}
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf518/boards/tcm-bf518.c b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
index f271310..6eebee4 100644
--- a/arch/blackfin/mach-bf518/boards/tcm-bf518.c
+++ b/arch/blackfin/mach-bf518/boards/tcm-bf518.c
@@ -730,9 +730,8 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+	return 1;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/ad7160eval.c b/arch/blackfin/mach-bf527/boards/ad7160eval.c
index c8d5d2b..fad7fea 100644
--- a/arch/blackfin/mach-bf527/boards/ad7160eval.c
+++ b/arch/blackfin/mach-bf527/boards/ad7160eval.c
@@ -846,7 +846,7 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	/* the MAC is stored in OTP memory page 0xDF */
 	u32 ret;
@@ -859,5 +859,6 @@ void bfin_get_ether_addr(char *addr)
 		for (ret = 0; ret < 6; ++ret)
 			addr[ret] = otp_mac_p[5 - ret];
 	}
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index 7330607..65b7fbd 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -983,9 +983,8 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+	return 1;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index db3ecfc..17c6a24 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -870,7 +870,7 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	/* the MAC is stored in OTP memory page 0xDF */
 	u32 ret;
@@ -883,5 +883,6 @@ void bfin_get_ether_addr(char *addr)
 		for (ret = 0; ret < 6; ++ret)
 			addr[ret] = otp_mac_p[5 - ret];
 	}
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index dfdd8e6..2f9a2bd 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -1311,7 +1311,7 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	/* the MAC is stored in OTP memory page 0xDF */
 	u32 ret;
@@ -1324,5 +1324,6 @@ void bfin_get_ether_addr(char *addr)
 		for (ret = 0; ret < 6; ++ret)
 			addr[ret] = otp_mac_p[5 - ret];
 	}
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/tll6527m.c b/arch/blackfin/mach-bf527/boards/tll6527m.c
index 360e97f..d192c0a 100644
--- a/arch/blackfin/mach-bf527/boards/tll6527m.c
+++ b/arch/blackfin/mach-bf527/boards/tll6527m.c
@@ -931,7 +931,7 @@ void native_machine_restart(char *cmd)
 		bfin_reset_boot_spi_cs(P_DEFAULT_BOOT_SPI_CS);
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	/* the MAC is stored in OTP memory page 0xDF */
 	u32 ret;
@@ -945,5 +945,6 @@ void bfin_get_ether_addr(char *addr)
 		for (ret = 0; ret < 6; ++ret)
 			addr[ret] = otp_mac_p[5 - ret];
 	}
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index 0d4a2f6..27fd2c3 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -813,9 +813,8 @@ void __init native_machine_early_platform_add_devices(void)
 		ARRAY_SIZE(cm_bf537e_early_devices));
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+	return 1;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index f553698..3f3abad 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -790,9 +790,8 @@ void __init native_machine_early_platform_add_devices(void)
 		ARRAY_SIZE(cm_bf537u_early_devices));
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+	return 1;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/dnp5370.c b/arch/blackfin/mach-bf537/boards/dnp5370.c
index 11dadeb..6f77bf7 100644
--- a/arch/blackfin/mach-bf537/boards/dnp5370.c
+++ b/arch/blackfin/mach-bf537/boards/dnp5370.c
@@ -399,9 +399,10 @@ arch_initcall(dnp5370_init);
 /*
  * Currently the MAC address is saved in Flash by U-Boot
  */
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	*(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC);
 	*(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4);
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 6fd8470..e9507fe 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -535,9 +535,8 @@ void __init native_machine_early_platform_add_devices(void)
 		ARRAY_SIZE(stamp_early_devices));
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+	return 1;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 2221173..f3562b0 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -975,7 +975,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 	},
 #endif
 
-#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
+#ifdef CONFIG_SND_SOC_AD193X_SPI
 	{
 		.modalias = "ad193x",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
@@ -2171,7 +2171,7 @@ static unsigned long adt7316_i2c_data[2] = {
 #endif
 
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
-#if defined(CONFIG_SND_BF5XX_SOC_AD193X) || defined(CONFIG_SND_BF5XX_SOC_AD193X_MODULE)
+#ifdef CONFIG_SND_SOC_AD193X_I2C
 	{
 		I2C_BOARD_INFO("ad1937", 0x04),
 	},
@@ -2593,6 +2593,21 @@ static struct platform_device bfin_ac97_pcm = {
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
+				defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
+static const unsigned ad73311_gpio[] = {
+	GPIO_PF4,
+};
+
+static struct platform_device bfin_ad73311_machine = {
+	.name = "bfin-snd-ad73311",
+	.id = 1,
+	.dev = {
+		.platform_data = (void *)ad73311_gpio,
+	},
+};
+#endif
+
 #if defined(CONFIG_SND_SOC_AD73311) || defined(CONFIG_SND_SOC_AD73311_MODULE)
 static struct platform_device bfin_ad73311_codec_device = {
 	.name = "ad73311",
@@ -2862,6 +2877,11 @@ static struct platform_device *stamp_devices[] __initdata = {
 	&bfin_ac97_pcm,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
+		defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
+	&bfin_ad73311_machine,
+#endif
+
 #if defined(CONFIG_SND_SOC_AD73311) || defined(CONFIG_SND_SOC_AD73311_MODULE)
 	&bfin_ad73311_codec_device,
 #endif
@@ -2993,9 +3013,10 @@ void native_machine_restart(char *cmd)
  * Currently the MAC address is saved in Flash by U-Boot
  */
 #define FLASH_MAC	0x203f0000
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
 	*(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC);
 	*(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4);
+	return 0;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 9885176..3fb4218 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -780,9 +780,8 @@ void __init native_machine_early_platform_add_devices(void)
 		ARRAY_SIZE(cm_bf537_early_devices));
 }
 
-void bfin_get_ether_addr(char *addr)
+int bfin_get_ether_addr(char *addr)
 {
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+	return 1;
 }
 EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 3ea45f8..4595a40 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -1237,6 +1237,8 @@ static struct bfin_capture_config bfin_capture_data = {
 	},
 	.ppi_info = &ppi_info,
 	.ppi_control = (POLC | PACKEN | DLEN_8 | XFR_TYPE | 0x20),
+	.int_mask = 0xFFFFFFFF, /* disable error interrupt on eppi */
+	.blank_clocks = 8, /* 8 clocks as SAV and EAV */
 };
 #endif
 
diff --git a/arch/blackfin/mach-bf561/atomic.S b/arch/blackfin/mach-bf561/atomic.S
index 52d6f73..2a08df8 100644
--- a/arch/blackfin/mach-bf561/atomic.S
+++ b/arch/blackfin/mach-bf561/atomic.S
@@ -72,6 +72,13 @@ ENTRY(_get_core_lock_noflush)
 	SSYNC(r2);
 	jump .Lretry_corelock_noflush
 .Ldone_corelock_noflush:
+	/*
+	 * SMP kgdb runs into dead loop without NOP here, when one core
+	 * single steps over get_core_lock_noflush and the other executes
+	 * get_core_lock as a slave node.
+	 */
+	nop;
+	CSYNC(r2);
 	rts;
 ENDPROC(_get_core_lock_noflush)
 
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h
index 71e805e..7d712ae 100644
--- a/arch/blackfin/mach-bf561/include/mach/defBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -479,61 +479,61 @@
 #define DMA1_11_PERIPHERAL_MAP 0xFFC01EEC	/* DMA1 Channel 11 Peripheral Map Register */
 
 /* Memory DMA1 Controller registers (0xFFC0 1E80-0xFFC0 1FFF) */
-#define MDMA_D2_CONFIG 0xFFC01F08	/*MemDMA1 Stream 0 Destination Configuration */
-#define MDMA_D2_NEXT_DESC_PTR 0xFFC01F00	/*MemDMA1 Stream 0 Destination Next Descriptor Ptr Reg */
-#define MDMA_D2_START_ADDR 0xFFC01F04	/*MemDMA1 Stream 0 Destination Start Address */
-#define MDMA_D2_X_COUNT 0xFFC01F10	/*MemDMA1 Stream 0 Destination Inner-Loop Count */
-#define MDMA_D2_Y_COUNT 0xFFC01F18	/*MemDMA1 Stream 0 Destination Outer-Loop Count */
-#define MDMA_D2_X_MODIFY 0xFFC01F14	/*MemDMA1 Stream 0 Dest Inner-Loop Address-Increment */
-#define MDMA_D2_Y_MODIFY 0xFFC01F1C	/*MemDMA1 Stream 0 Dest Outer-Loop Address-Increment */
-#define MDMA_D2_CURR_DESC_PTR 0xFFC01F20	/*MemDMA1 Stream 0 Dest Current Descriptor Ptr reg */
-#define MDMA_D2_CURR_ADDR 0xFFC01F24	/*MemDMA1 Stream 0 Destination Current Address */
-#define MDMA_D2_CURR_X_COUNT 0xFFC01F30	/*MemDMA1 Stream 0 Dest Current Inner-Loop Count */
-#define MDMA_D2_CURR_Y_COUNT 0xFFC01F38	/*MemDMA1 Stream 0 Dest Current Outer-Loop Count */
-#define MDMA_D2_IRQ_STATUS 0xFFC01F28	/*MemDMA1 Stream 0 Destination Interrupt/Status */
-#define MDMA_D2_PERIPHERAL_MAP 0xFFC01F2C	/*MemDMA1 Stream 0 Destination Peripheral Map */
-
-#define MDMA_S2_CONFIG 0xFFC01F48	/*MemDMA1 Stream 0 Source Configuration */
-#define MDMA_S2_NEXT_DESC_PTR 0xFFC01F40	/*MemDMA1 Stream 0 Source Next Descriptor Ptr Reg */
-#define MDMA_S2_START_ADDR 0xFFC01F44	/*MemDMA1 Stream 0 Source Start Address */
-#define MDMA_S2_X_COUNT 0xFFC01F50	/*MemDMA1 Stream 0 Source Inner-Loop Count */
-#define MDMA_S2_Y_COUNT 0xFFC01F58	/*MemDMA1 Stream 0 Source Outer-Loop Count */
-#define MDMA_S2_X_MODIFY 0xFFC01F54	/*MemDMA1 Stream 0 Source Inner-Loop Address-Increment */
-#define MDMA_S2_Y_MODIFY 0xFFC01F5C	/*MemDMA1 Stream 0 Source Outer-Loop Address-Increment */
-#define MDMA_S2_CURR_DESC_PTR 0xFFC01F60	/*MemDMA1 Stream 0 Source Current Descriptor Ptr reg */
-#define MDMA_S2_CURR_ADDR 0xFFC01F64	/*MemDMA1 Stream 0 Source Current Address */
-#define MDMA_S2_CURR_X_COUNT 0xFFC01F70	/*MemDMA1 Stream 0 Source Current Inner-Loop Count */
-#define MDMA_S2_CURR_Y_COUNT 0xFFC01F78	/*MemDMA1 Stream 0 Source Current Outer-Loop Count */
-#define MDMA_S2_IRQ_STATUS 0xFFC01F68	/*MemDMA1 Stream 0 Source Interrupt/Status */
-#define MDMA_S2_PERIPHERAL_MAP 0xFFC01F6C	/*MemDMA1 Stream 0 Source Peripheral Map */
-
-#define MDMA_D3_CONFIG 0xFFC01F88	/*MemDMA1 Stream 1 Destination Configuration */
-#define MDMA_D3_NEXT_DESC_PTR 0xFFC01F80	/*MemDMA1 Stream 1 Destination Next Descriptor Ptr Reg */
-#define MDMA_D3_START_ADDR 0xFFC01F84	/*MemDMA1 Stream 1 Destination Start Address */
-#define MDMA_D3_X_COUNT 0xFFC01F90	/*MemDMA1 Stream 1 Destination Inner-Loop Count */
-#define MDMA_D3_Y_COUNT 0xFFC01F98	/*MemDMA1 Stream 1 Destination Outer-Loop Count */
-#define MDMA_D3_X_MODIFY 0xFFC01F94	/*MemDMA1 Stream 1 Dest Inner-Loop Address-Increment */
-#define MDMA_D3_Y_MODIFY 0xFFC01F9C	/*MemDMA1 Stream 1 Dest Outer-Loop Address-Increment */
-#define MDMA_D3_CURR_DESC_PTR 0xFFC01FA0	/*MemDMA1 Stream 1 Dest Current Descriptor Ptr reg */
-#define MDMA_D3_CURR_ADDR 0xFFC01FA4	/*MemDMA1 Stream 1 Dest Current Address */
-#define MDMA_D3_CURR_X_COUNT 0xFFC01FB0	/*MemDMA1 Stream 1 Dest Current Inner-Loop Count */
-#define MDMA_D3_CURR_Y_COUNT 0xFFC01FB8	/*MemDMA1 Stream 1 Dest Current Outer-Loop Count */
-#define MDMA_D3_IRQ_STATUS 0xFFC01FA8	/*MemDMA1 Stream 1 Dest Interrupt/Status */
-#define MDMA_D3_PERIPHERAL_MAP 0xFFC01FAC	/*MemDMA1 Stream 1 Dest Peripheral Map */
-
-#define MDMA_S3_CONFIG 0xFFC01FC8	/*MemDMA1 Stream 1 Source Configuration */
-#define MDMA_S3_NEXT_DESC_PTR 0xFFC01FC0	/*MemDMA1 Stream 1 Source Next Descriptor Ptr Reg */
-#define MDMA_S3_START_ADDR 0xFFC01FC4	/*MemDMA1 Stream 1 Source Start Address */
-#define MDMA_S3_X_COUNT 0xFFC01FD0	/*MemDMA1 Stream 1 Source Inner-Loop Count */
-#define MDMA_S3_Y_COUNT 0xFFC01FD8	/*MemDMA1 Stream 1 Source Outer-Loop Count */
-#define MDMA_S3_X_MODIFY 0xFFC01FD4	/*MemDMA1 Stream 1 Source Inner-Loop Address-Increment */
-#define MDMA_S3_Y_MODIFY 0xFFC01FDC	/*MemDMA1 Stream 1 Source Outer-Loop Address-Increment */
-#define MDMA_S3_CURR_DESC_PTR 0xFFC01FE0	/*MemDMA1 Stream 1 Source Current Descriptor Ptr reg */
-#define MDMA_S3_CURR_ADDR 0xFFC01FE4	/*MemDMA1 Stream 1 Source Current Address */
-#define MDMA_S3_CURR_X_COUNT 0xFFC01FF0	/*MemDMA1 Stream 1 Source Current Inner-Loop Count */
-#define MDMA_S3_CURR_Y_COUNT 0xFFC01FF8	/*MemDMA1 Stream 1 Source Current Outer-Loop Count */
-#define MDMA_S3_IRQ_STATUS 0xFFC01FE8	/*MemDMA1 Stream 1 Source Interrupt/Status */
-#define MDMA_S3_PERIPHERAL_MAP 0xFFC01FEC	/*MemDMA1 Stream 1 Source Peripheral Map */
+#define MDMA_D0_CONFIG 0xFFC01F08	/*MemDMA1 Stream 0 Destination Configuration */
+#define MDMA_D0_NEXT_DESC_PTR 0xFFC01F00	/*MemDMA1 Stream 0 Destination Next Descriptor Ptr Reg */
+#define MDMA_D0_START_ADDR 0xFFC01F04	/*MemDMA1 Stream 0 Destination Start Address */
+#define MDMA_D0_X_COUNT 0xFFC01F10	/*MemDMA1 Stream 0 Destination Inner-Loop Count */
+#define MDMA_D0_Y_COUNT 0xFFC01F18	/*MemDMA1 Stream 0 Destination Outer-Loop Count */
+#define MDMA_D0_X_MODIFY 0xFFC01F14	/*MemDMA1 Stream 0 Dest Inner-Loop Address-Increment */
+#define MDMA_D0_Y_MODIFY 0xFFC01F1C	/*MemDMA1 Stream 0 Dest Outer-Loop Address-Increment */
+#define MDMA_D0_CURR_DESC_PTR 0xFFC01F20	/*MemDMA1 Stream 0 Dest Current Descriptor Ptr reg */
+#define MDMA_D0_CURR_ADDR 0xFFC01F24	/*MemDMA1 Stream 0 Destination Current Address */
+#define MDMA_D0_CURR_X_COUNT 0xFFC01F30	/*MemDMA1 Stream 0 Dest Current Inner-Loop Count */
+#define MDMA_D0_CURR_Y_COUNT 0xFFC01F38	/*MemDMA1 Stream 0 Dest Current Outer-Loop Count */
+#define MDMA_D0_IRQ_STATUS 0xFFC01F28	/*MemDMA1 Stream 0 Destination Interrupt/Status */
+#define MDMA_D0_PERIPHERAL_MAP 0xFFC01F2C	/*MemDMA1 Stream 0 Destination Peripheral Map */
+
+#define MDMA_S0_CONFIG 0xFFC01F48	/*MemDMA1 Stream 0 Source Configuration */
+#define MDMA_S0_NEXT_DESC_PTR 0xFFC01F40	/*MemDMA1 Stream 0 Source Next Descriptor Ptr Reg */
+#define MDMA_S0_START_ADDR 0xFFC01F44	/*MemDMA1 Stream 0 Source Start Address */
+#define MDMA_S0_X_COUNT 0xFFC01F50	/*MemDMA1 Stream 0 Source Inner-Loop Count */
+#define MDMA_S0_Y_COUNT 0xFFC01F58	/*MemDMA1 Stream 0 Source Outer-Loop Count */
+#define MDMA_S0_X_MODIFY 0xFFC01F54	/*MemDMA1 Stream 0 Source Inner-Loop Address-Increment */
+#define MDMA_S0_Y_MODIFY 0xFFC01F5C	/*MemDMA1 Stream 0 Source Outer-Loop Address-Increment */
+#define MDMA_S0_CURR_DESC_PTR 0xFFC01F60	/*MemDMA1 Stream 0 Source Current Descriptor Ptr reg */
+#define MDMA_S0_CURR_ADDR 0xFFC01F64	/*MemDMA1 Stream 0 Source Current Address */
+#define MDMA_S0_CURR_X_COUNT 0xFFC01F70	/*MemDMA1 Stream 0 Source Current Inner-Loop Count */
+#define MDMA_S0_CURR_Y_COUNT 0xFFC01F78	/*MemDMA1 Stream 0 Source Current Outer-Loop Count */
+#define MDMA_S0_IRQ_STATUS 0xFFC01F68	/*MemDMA1 Stream 0 Source Interrupt/Status */
+#define MDMA_S0_PERIPHERAL_MAP 0xFFC01F6C	/*MemDMA1 Stream 0 Source Peripheral Map */
+
+#define MDMA_D1_CONFIG 0xFFC01F88	/*MemDMA1 Stream 1 Destination Configuration */
+#define MDMA_D1_NEXT_DESC_PTR 0xFFC01F80	/*MemDMA1 Stream 1 Destination Next Descriptor Ptr Reg */
+#define MDMA_D1_START_ADDR 0xFFC01F84	/*MemDMA1 Stream 1 Destination Start Address */
+#define MDMA_D1_X_COUNT 0xFFC01F90	/*MemDMA1 Stream 1 Destination Inner-Loop Count */
+#define MDMA_D1_Y_COUNT 0xFFC01F98	/*MemDMA1 Stream 1 Destination Outer-Loop Count */
+#define MDMA_D1_X_MODIFY 0xFFC01F94	/*MemDMA1 Stream 1 Dest Inner-Loop Address-Increment */
+#define MDMA_D1_Y_MODIFY 0xFFC01F9C	/*MemDMA1 Stream 1 Dest Outer-Loop Address-Increment */
+#define MDMA_D1_CURR_DESC_PTR 0xFFC01FA0	/*MemDMA1 Stream 1 Dest Current Descriptor Ptr reg */
+#define MDMA_D1_CURR_ADDR 0xFFC01FA4	/*MemDMA1 Stream 1 Dest Current Address */
+#define MDMA_D1_CURR_X_COUNT 0xFFC01FB0	/*MemDMA1 Stream 1 Dest Current Inner-Loop Count */
+#define MDMA_D1_CURR_Y_COUNT 0xFFC01FB8	/*MemDMA1 Stream 1 Dest Current Outer-Loop Count */
+#define MDMA_D1_IRQ_STATUS 0xFFC01FA8	/*MemDMA1 Stream 1 Dest Interrupt/Status */
+#define MDMA_D1_PERIPHERAL_MAP 0xFFC01FAC	/*MemDMA1 Stream 1 Dest Peripheral Map */
+
+#define MDMA_S1_CONFIG 0xFFC01FC8	/*MemDMA1 Stream 1 Source Configuration */
+#define MDMA_S1_NEXT_DESC_PTR 0xFFC01FC0	/*MemDMA1 Stream 1 Source Next Descriptor Ptr Reg */
+#define MDMA_S1_START_ADDR 0xFFC01FC4	/*MemDMA1 Stream 1 Source Start Address */
+#define MDMA_S1_X_COUNT 0xFFC01FD0	/*MemDMA1 Stream 1 Source Inner-Loop Count */
+#define MDMA_S1_Y_COUNT 0xFFC01FD8	/*MemDMA1 Stream 1 Source Outer-Loop Count */
+#define MDMA_S1_X_MODIFY 0xFFC01FD4	/*MemDMA1 Stream 1 Source Inner-Loop Address-Increment */
+#define MDMA_S1_Y_MODIFY 0xFFC01FDC	/*MemDMA1 Stream 1 Source Outer-Loop Address-Increment */
+#define MDMA_S1_CURR_DESC_PTR 0xFFC01FE0	/*MemDMA1 Stream 1 Source Current Descriptor Ptr reg */
+#define MDMA_S1_CURR_ADDR 0xFFC01FE4	/*MemDMA1 Stream 1 Source Current Address */
+#define MDMA_S1_CURR_X_COUNT 0xFFC01FF0	/*MemDMA1 Stream 1 Source Current Inner-Loop Count */
+#define MDMA_S1_CURR_Y_COUNT 0xFFC01FF8	/*MemDMA1 Stream 1 Source Current Outer-Loop Count */
+#define MDMA_S1_IRQ_STATUS 0xFFC01FE8	/*MemDMA1 Stream 1 Source Interrupt/Status */
+#define MDMA_S1_PERIPHERAL_MAP 0xFFC01FEC	/*MemDMA1 Stream 1 Source Peripheral Map */
 
 /* DMA2 Controller registers (0xFFC0 0C00-0xFFC0 0DFF) */
 #define DMA2_0_CONFIG 0xFFC00C08	/* DMA2 Channel 0 Configuration register */
@@ -705,61 +705,61 @@
 #define DMA2_11_PERIPHERAL_MAP 0xFFC00EEC	/* DMA2 Channel 11 Peripheral Map Register */
 
 /* Memory DMA2 Controller registers (0xFFC0 0E80-0xFFC0 0FFF) */
-#define MDMA_D0_CONFIG 0xFFC00F08	/*MemDMA2 Stream 0 Destination Configuration register */
-#define MDMA_D0_NEXT_DESC_PTR 0xFFC00F00	/*MemDMA2 Stream 0 Destination Next Descriptor Ptr Reg */
-#define MDMA_D0_START_ADDR 0xFFC00F04	/*MemDMA2 Stream 0 Destination Start Address */
-#define MDMA_D0_X_COUNT 0xFFC00F10	/*MemDMA2 Stream 0 Dest Inner-Loop Count register */
-#define MDMA_D0_Y_COUNT 0xFFC00F18	/*MemDMA2 Stream 0 Dest Outer-Loop Count register */
-#define MDMA_D0_X_MODIFY 0xFFC00F14	/*MemDMA2 Stream 0 Dest Inner-Loop Address-Increment */
-#define MDMA_D0_Y_MODIFY 0xFFC00F1C	/*MemDMA2 Stream 0 Dest Outer-Loop Address-Increment */
-#define MDMA_D0_CURR_DESC_PTR 0xFFC00F20	/*MemDMA2 Stream 0 Dest Current Descriptor Ptr reg */
-#define MDMA_D0_CURR_ADDR 0xFFC00F24	/*MemDMA2 Stream 0 Destination Current Address */
-#define MDMA_D0_CURR_X_COUNT 0xFFC00F30	/*MemDMA2 Stream 0 Dest Current Inner-Loop Count reg */
-#define MDMA_D0_CURR_Y_COUNT 0xFFC00F38	/*MemDMA2 Stream 0 Dest Current Outer-Loop Count reg */
-#define MDMA_D0_IRQ_STATUS 0xFFC00F28	/*MemDMA2 Stream 0 Dest Interrupt/Status Register */
-#define MDMA_D0_PERIPHERAL_MAP 0xFFC00F2C	/*MemDMA2 Stream 0 Destination Peripheral Map register */
-
-#define MDMA_S0_CONFIG 0xFFC00F48	/*MemDMA2 Stream 0 Source Configuration register */
-#define MDMA_S0_NEXT_DESC_PTR 0xFFC00F40	/*MemDMA2 Stream 0 Source Next Descriptor Ptr Reg */
-#define MDMA_S0_START_ADDR 0xFFC00F44	/*MemDMA2 Stream 0 Source Start Address */
-#define MDMA_S0_X_COUNT 0xFFC00F50	/*MemDMA2 Stream 0 Source Inner-Loop Count register */
-#define MDMA_S0_Y_COUNT 0xFFC00F58	/*MemDMA2 Stream 0 Source Outer-Loop Count register */
-#define MDMA_S0_X_MODIFY 0xFFC00F54	/*MemDMA2 Stream 0 Src Inner-Loop Addr-Increment reg */
-#define MDMA_S0_Y_MODIFY 0xFFC00F5C	/*MemDMA2 Stream 0 Src Outer-Loop Addr-Increment reg */
-#define MDMA_S0_CURR_DESC_PTR 0xFFC00F60	/*MemDMA2 Stream 0 Source Current Descriptor Ptr reg */
-#define MDMA_S0_CURR_ADDR 0xFFC00F64	/*MemDMA2 Stream 0 Source Current Address */
-#define MDMA_S0_CURR_X_COUNT 0xFFC00F70	/*MemDMA2 Stream 0 Src Current Inner-Loop Count reg */
-#define MDMA_S0_CURR_Y_COUNT 0xFFC00F78	/*MemDMA2 Stream 0 Src Current Outer-Loop Count reg */
-#define MDMA_S0_IRQ_STATUS 0xFFC00F68	/*MemDMA2 Stream 0 Source Interrupt/Status Register */
-#define MDMA_S0_PERIPHERAL_MAP 0xFFC00F6C	/*MemDMA2 Stream 0 Source Peripheral Map register */
-
-#define MDMA_D1_CONFIG 0xFFC00F88	/*MemDMA2 Stream 1 Destination Configuration register */
-#define MDMA_D1_NEXT_DESC_PTR 0xFFC00F80	/*MemDMA2 Stream 1 Destination Next Descriptor Ptr Reg */
-#define MDMA_D1_START_ADDR 0xFFC00F84	/*MemDMA2 Stream 1 Destination Start Address */
-#define MDMA_D1_X_COUNT 0xFFC00F90	/*MemDMA2 Stream 1 Dest Inner-Loop Count register */
-#define MDMA_D1_Y_COUNT 0xFFC00F98	/*MemDMA2 Stream 1 Dest Outer-Loop Count register */
-#define MDMA_D1_X_MODIFY 0xFFC00F94	/*MemDMA2 Stream 1 Dest Inner-Loop Address-Increment */
-#define MDMA_D1_Y_MODIFY 0xFFC00F9C	/*MemDMA2 Stream 1 Dest Outer-Loop Address-Increment */
-#define MDMA_D1_CURR_DESC_PTR 0xFFC00FA0	/*MemDMA2 Stream 1 Destination Current Descriptor Ptr */
-#define MDMA_D1_CURR_ADDR 0xFFC00FA4	/*MemDMA2 Stream 1 Destination Current Address reg */
-#define MDMA_D1_CURR_X_COUNT 0xFFC00FB0	/*MemDMA2 Stream 1 Dest Current Inner-Loop Count reg */
-#define MDMA_D1_CURR_Y_COUNT 0xFFC00FB8	/*MemDMA2 Stream 1 Dest Current Outer-Loop Count reg */
-#define MDMA_D1_IRQ_STATUS 0xFFC00FA8	/*MemDMA2 Stream 1 Destination Interrupt/Status Reg */
-#define MDMA_D1_PERIPHERAL_MAP 0xFFC00FAC	/*MemDMA2 Stream 1 Destination Peripheral Map register */
-
-#define MDMA_S1_CONFIG 0xFFC00FC8	/*MemDMA2 Stream 1 Source Configuration register */
-#define MDMA_S1_NEXT_DESC_PTR 0xFFC00FC0	/*MemDMA2 Stream 1 Source Next Descriptor Ptr Reg */
-#define MDMA_S1_START_ADDR 0xFFC00FC4	/*MemDMA2 Stream 1 Source Start Address */
-#define MDMA_S1_X_COUNT 0xFFC00FD0	/*MemDMA2 Stream 1 Source Inner-Loop Count register */
-#define MDMA_S1_Y_COUNT 0xFFC00FD8	/*MemDMA2 Stream 1 Source Outer-Loop Count register */
-#define MDMA_S1_X_MODIFY 0xFFC00FD4	/*MemDMA2 Stream 1 Src Inner-Loop Address-Increment */
-#define MDMA_S1_Y_MODIFY 0xFFC00FDC	/*MemDMA2 Stream 1 Source Outer-Loop Address-Increment */
-#define MDMA_S1_CURR_DESC_PTR 0xFFC00FE0	/*MemDMA2 Stream 1 Source Current Descriptor Ptr reg */
-#define MDMA_S1_CURR_ADDR 0xFFC00FE4	/*MemDMA2 Stream 1 Source Current Address */
-#define MDMA_S1_CURR_X_COUNT 0xFFC00FF0	/*MemDMA2 Stream 1 Source Current Inner-Loop Count */
-#define MDMA_S1_CURR_Y_COUNT 0xFFC00FF8	/*MemDMA2 Stream 1 Source Current Outer-Loop Count */
-#define MDMA_S1_IRQ_STATUS 0xFFC00FE8	/*MemDMA2 Stream 1 Source Interrupt/Status Register */
-#define MDMA_S1_PERIPHERAL_MAP 0xFFC00FEC	/*MemDMA2 Stream 1 Source Peripheral Map register */
+#define MDMA_D2_CONFIG 0xFFC00F08	/*MemDMA2 Stream 0 Destination Configuration register */
+#define MDMA_D2_NEXT_DESC_PTR 0xFFC00F00	/*MemDMA2 Stream 0 Destination Next Descriptor Ptr Reg */
+#define MDMA_D2_START_ADDR 0xFFC00F04	/*MemDMA2 Stream 0 Destination Start Address */
+#define MDMA_D2_X_COUNT 0xFFC00F10	/*MemDMA2 Stream 0 Dest Inner-Loop Count register */
+#define MDMA_D2_Y_COUNT 0xFFC00F18	/*MemDMA2 Stream 0 Dest Outer-Loop Count register */
+#define MDMA_D2_X_MODIFY 0xFFC00F14	/*MemDMA2 Stream 0 Dest Inner-Loop Address-Increment */
+#define MDMA_D2_Y_MODIFY 0xFFC00F1C	/*MemDMA2 Stream 0 Dest Outer-Loop Address-Increment */
+#define MDMA_D2_CURR_DESC_PTR 0xFFC00F20	/*MemDMA2 Stream 0 Dest Current Descriptor Ptr reg */
+#define MDMA_D2_CURR_ADDR 0xFFC00F24	/*MemDMA2 Stream 0 Destination Current Address */
+#define MDMA_D2_CURR_X_COUNT 0xFFC00F30	/*MemDMA2 Stream 0 Dest Current Inner-Loop Count reg */
+#define MDMA_D2_CURR_Y_COUNT 0xFFC00F38	/*MemDMA2 Stream 0 Dest Current Outer-Loop Count reg */
+#define MDMA_D2_IRQ_STATUS 0xFFC00F28	/*MemDMA2 Stream 0 Dest Interrupt/Status Register */
+#define MDMA_D2_PERIPHERAL_MAP 0xFFC00F2C	/*MemDMA2 Stream 0 Destination Peripheral Map register */
+
+#define MDMA_S2_CONFIG 0xFFC00F48	/*MemDMA2 Stream 0 Source Configuration register */
+#define MDMA_S2_NEXT_DESC_PTR 0xFFC00F40	/*MemDMA2 Stream 0 Source Next Descriptor Ptr Reg */
+#define MDMA_S2_START_ADDR 0xFFC00F44	/*MemDMA2 Stream 0 Source Start Address */
+#define MDMA_S2_X_COUNT 0xFFC00F50	/*MemDMA2 Stream 0 Source Inner-Loop Count register */
+#define MDMA_S2_Y_COUNT 0xFFC00F58	/*MemDMA2 Stream 0 Source Outer-Loop Count register */
+#define MDMA_S2_X_MODIFY 0xFFC00F54	/*MemDMA2 Stream 0 Src Inner-Loop Addr-Increment reg */
+#define MDMA_S2_Y_MODIFY 0xFFC00F5C	/*MemDMA2 Stream 0 Src Outer-Loop Addr-Increment reg */
+#define MDMA_S2_CURR_DESC_PTR 0xFFC00F60	/*MemDMA2 Stream 0 Source Current Descriptor Ptr reg */
+#define MDMA_S2_CURR_ADDR 0xFFC00F64	/*MemDMA2 Stream 0 Source Current Address */
+#define MDMA_S2_CURR_X_COUNT 0xFFC00F70	/*MemDMA2 Stream 0 Src Current Inner-Loop Count reg */
+#define MDMA_S2_CURR_Y_COUNT 0xFFC00F78	/*MemDMA2 Stream 0 Src Current Outer-Loop Count reg */
+#define MDMA_S2_IRQ_STATUS 0xFFC00F68	/*MemDMA2 Stream 0 Source Interrupt/Status Register */
+#define MDMA_S2_PERIPHERAL_MAP 0xFFC00F6C	/*MemDMA2 Stream 0 Source Peripheral Map register */
+
+#define MDMA_D3_CONFIG 0xFFC00F88	/*MemDMA2 Stream 1 Destination Configuration register */
+#define MDMA_D3_NEXT_DESC_PTR 0xFFC00F80	/*MemDMA2 Stream 1 Destination Next Descriptor Ptr Reg */
+#define MDMA_D3_START_ADDR 0xFFC00F84	/*MemDMA2 Stream 1 Destination Start Address */
+#define MDMA_D3_X_COUNT 0xFFC00F90	/*MemDMA2 Stream 1 Dest Inner-Loop Count register */
+#define MDMA_D3_Y_COUNT 0xFFC00F98	/*MemDMA2 Stream 1 Dest Outer-Loop Count register */
+#define MDMA_D3_X_MODIFY 0xFFC00F94	/*MemDMA2 Stream 1 Dest Inner-Loop Address-Increment */
+#define MDMA_D3_Y_MODIFY 0xFFC00F9C	/*MemDMA2 Stream 1 Dest Outer-Loop Address-Increment */
+#define MDMA_D3_CURR_DESC_PTR 0xFFC00FA0	/*MemDMA2 Stream 1 Destination Current Descriptor Ptr */
+#define MDMA_D3_CURR_ADDR 0xFFC00FA4	/*MemDMA2 Stream 1 Destination Current Address reg */
+#define MDMA_D3_CURR_X_COUNT 0xFFC00FB0	/*MemDMA2 Stream 1 Dest Current Inner-Loop Count reg */
+#define MDMA_D3_CURR_Y_COUNT 0xFFC00FB8	/*MemDMA2 Stream 1 Dest Current Outer-Loop Count reg */
+#define MDMA_D3_IRQ_STATUS 0xFFC00FA8	/*MemDMA2 Stream 1 Destination Interrupt/Status Reg */
+#define MDMA_D3_PERIPHERAL_MAP 0xFFC00FAC	/*MemDMA2 Stream 1 Destination Peripheral Map register */
+
+#define MDMA_S3_CONFIG 0xFFC00FC8	/*MemDMA2 Stream 1 Source Configuration register */
+#define MDMA_S3_NEXT_DESC_PTR 0xFFC00FC0	/*MemDMA2 Stream 1 Source Next Descriptor Ptr Reg */
+#define MDMA_S3_START_ADDR 0xFFC00FC4	/*MemDMA2 Stream 1 Source Start Address */
+#define MDMA_S3_X_COUNT 0xFFC00FD0	/*MemDMA2 Stream 1 Source Inner-Loop Count register */
+#define MDMA_S3_Y_COUNT 0xFFC00FD8	/*MemDMA2 Stream 1 Source Outer-Loop Count register */
+#define MDMA_S3_X_MODIFY 0xFFC00FD4	/*MemDMA2 Stream 1 Src Inner-Loop Address-Increment */
+#define MDMA_S3_Y_MODIFY 0xFFC00FDC	/*MemDMA2 Stream 1 Source Outer-Loop Address-Increment */
+#define MDMA_S3_CURR_DESC_PTR 0xFFC00FE0	/*MemDMA2 Stream 1 Source Current Descriptor Ptr reg */
+#define MDMA_S3_CURR_ADDR 0xFFC00FE4	/*MemDMA2 Stream 1 Source Current Address */
+#define MDMA_S3_CURR_X_COUNT 0xFFC00FF0	/*MemDMA2 Stream 1 Source Current Inner-Loop Count */
+#define MDMA_S3_CURR_Y_COUNT 0xFFC00FF8	/*MemDMA2 Stream 1 Source Current Outer-Loop Count */
+#define MDMA_S3_IRQ_STATUS 0xFFC00FE8	/*MemDMA2 Stream 1 Source Interrupt/Status Register */
+#define MDMA_S3_PERIPHERAL_MAP 0xFFC00FEC	/*MemDMA2 Stream 1 Source Peripheral Map register */
 
 /* Internal Memory DMA Registers (0xFFC0_1800 - 0xFFC0_19FF) */
 #define IMDMA_D0_CONFIG 0xFFC01808	/*IMDMA Stream 0 Destination Configuration */
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index e413729..6d5102c 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1755,6 +1755,8 @@ ENTRY(_sys_call_table)
 	.long _sys_syncfs
 	.long _sys_setns
 	.long _sys_sendmmsg		/* 380 */
+	.long _sys_process_vm_readv
+	.long _sys_process_vm_writev
 
 	.rept NR_syscalls-(.-_sys_call_table)/4
 	.long _sys_ni_syscall
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 26e67f0..1c3ccd4 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -11,7 +11,8 @@ config TMS320C6X
 	select HAVE_DMA_API_DEBUG
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_MEMBLOCK
-	select HAVE_SPARSE_IRQ
+	select SPARSE_IRQ
+	select IRQ_DOMAIN
 	select OF
 	select OF_EARLY_FLATTREE
 
diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile
index ecca820..6891257 100644
--- a/arch/c6x/boot/Makefile
+++ b/arch/c6x/boot/Makefile
@@ -13,7 +13,7 @@ obj-y += linked_dtb.o
 endif
 
 $(obj)/%.dtb: $(src)/dts/%.dts FORCE
-	$(call cmd,dtc)
+	$(call if_changed_dep,dtc)
 
 quiet_cmd_cp = CP      $< $@$2
 	cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
index a6ae3c9..f13b78d 100644
--- a/arch/c6x/include/asm/irq.h
+++ b/arch/c6x/include/asm/irq.h
@@ -13,6 +13,7 @@
 #ifndef _ASM_C6X_IRQ_H
 #define _ASM_C6X_IRQ_H
 
+#include <linux/irqdomain.h>
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
@@ -41,253 +42,9 @@
 /* This number is used when no interrupt has been assigned */
 #define NO_IRQ		0
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-struct irq_host;
-struct radix_tree_root;
-struct device_node;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
-	/* Match an interrupt controller device node to a host, returns
-	 * 1 on a match
-	 */
-	int (*match)(struct irq_host *h, struct device_node *node);
-
-	/* Create or update a mapping between a virtual irq number and a hw
-	 * irq number. This is called only once for a given mapping.
-	 */
-	int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
-	/* Dispose of such a mapping */
-	void (*unmap)(struct irq_host *h, unsigned int virq);
-
-	/* Translate device-tree interrupt specifier from raw format coming
-	 * from the firmware to a irq_hw_number_t (interrupt line number) and
-	 * type (sense) that can be passed to set_irq_type(). In the absence
-	 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
-	 * will return the hw number in the first cell and IRQ_TYPE_NONE for
-	 * the type (which amount to keeping whatever default value the
-	 * interrupt controller has for that line)
-	 */
-	int (*xlate)(struct irq_host *h, struct device_node *ctrler,
-		     const u32 *intspec, unsigned int intsize,
-		     irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
-	struct list_head	link;
-
-	/* type of reverse mapping technique */
-	unsigned int		revmap_type;
-#define IRQ_HOST_MAP_PRIORITY   0 /* core priority irqs, get irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP	1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR	2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE	3 /* radix tree */
-	union {
-		struct {
-			unsigned int size;
-			unsigned int *revmap;
-		} linear;
-		struct radix_tree_root tree;
-	} revmap_data;
-	struct irq_host_ops	*ops;
-	void			*host_data;
-	irq_hw_number_t		inval_irq;
-
-	/* Optional device node pointer */
-	struct device_node	*of_node;
-};
-
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-
-/**
- * irq_alloc_host - Allocate a new irq_host data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
-				       unsigned int revmap_type,
-				       unsigned int revmap_arg,
-				       struct irq_host_ops *ops,
-				       irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_host *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_host *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
-				       irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_host *host,
-				     irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
-				    irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
-					    irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_host *host,
-				      irq_hw_number_t hwirq);
-
-
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
-				   unsigned int count,
-				   unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
 
 extern void __init init_pic_c64xplus(void);
 
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 0929e4b..d77bcfd 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -73,10 +73,10 @@ asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
 	set_irq_regs(old_regs);
 }
 
-static struct irq_host *core_host;
+static struct irq_domain *core_domain;
 
-static int core_host_map(struct irq_host *h, unsigned int virq,
-			 irq_hw_number_t hw)
+static int core_domain_map(struct irq_domain *h, unsigned int virq,
+			   irq_hw_number_t hw)
 {
 	if (hw < 4 || hw >= NR_PRIORITY_IRQS)
 		return -EINVAL;
@@ -86,8 +86,9 @@ static int core_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops core_host_ops = {
-	.map = core_host_map,
+static const struct irq_domain_ops core_domain_ops = {
+	.map = core_domain_map,
+	.xlate = irq_domain_xlate_onecell,
 };
 
 void __init init_IRQ(void)
@@ -100,10 +101,11 @@ void __init init_IRQ(void)
 	np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic");
 	if (np != NULL) {
 		/* create the core host */
-		core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0,
-					   &core_host_ops, 0);
-		if (core_host)
-			irq_set_default_host(core_host);
+		core_domain = irq_domain_add_legacy(np, NR_PRIORITY_IRQS,
+						    0, 0, &core_domain_ops,
+						    NULL);
+		if (core_domain)
+			irq_set_default_host(core_domain);
 		of_node_put(np);
 	}
 
@@ -128,601 +130,15 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	return 0;
 }
 
-/*
- * IRQ controller and virtual interrupts
- */
-
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
-	irq_hw_number_t	hwirq;
-	struct irq_host	*host;
-};
-
-static LIST_HEAD(irq_hosts);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
-
 irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
 {
-	return irq_map[d->irq].hwirq;
+	return d->hwirq;
 }
 EXPORT_SYMBOL_GPL(irqd_to_hwirq);
 
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
-	return irq_map[virq].hwirq;
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
-
-bool virq_is_host(unsigned int virq, struct irq_host *host)
-{
-	return irq_map[virq].host == host;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
-{
-	return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_host *irq_alloc_host(struct device_node *of_node,
-				unsigned int revmap_type,
-				unsigned int revmap_arg,
-				struct irq_host_ops *ops,
-				irq_hw_number_t inval_irq)
-{
-	struct irq_host *host;
-	unsigned int size = sizeof(struct irq_host);
-	unsigned int i;
-	unsigned int *rmap;
-	unsigned long flags;
-
-	/* Allocate structure and revmap table if using linear mapping */
-	if (revmap_type == IRQ_HOST_MAP_LINEAR)
-		size += revmap_arg * sizeof(unsigned int);
-	host = kzalloc(size, GFP_KERNEL);
-	if (host == NULL)
-		return NULL;
-
-	/* Fill structure */
-	host->revmap_type = revmap_type;
-	host->inval_irq = inval_irq;
-	host->ops = ops;
-	host->of_node = of_node_get(of_node);
-
-	if (host->ops->match == NULL)
-		host->ops->match = default_irq_host_match;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* Check for the priority controller. */
-	if (revmap_type == IRQ_HOST_MAP_PRIORITY) {
-		if (irq_map[0].host != NULL) {
-			raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-			of_node_put(host->of_node);
-			kfree(host);
-			return NULL;
-		}
-		irq_map[0].host = host;
-	}
-
-	list_add(&host->link, &irq_hosts);
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-
-	/* Additional setups per revmap type */
-	switch (revmap_type) {
-	case IRQ_HOST_MAP_PRIORITY:
-		/* 0 is always the invalid number for priority */
-		host->inval_irq = 0;
-		/* setup us as the host for all priority interrupts */
-		for (i = 1; i < NR_PRIORITY_IRQS; i++) {
-			irq_map[i].hwirq = i;
-			smp_wmb();
-			irq_map[i].host = host;
-			smp_wmb();
-
-			ops->map(host, i, i);
-		}
-		break;
-	case IRQ_HOST_MAP_LINEAR:
-		rmap = (unsigned int *)(host + 1);
-		for (i = 0; i < revmap_arg; i++)
-			rmap[i] = NO_IRQ;
-		host->revmap_data.linear.size = revmap_arg;
-		smp_wmb();
-		host->revmap_data.linear.revmap = rmap;
-		break;
-	case IRQ_HOST_MAP_TREE:
-		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
-		break;
-	default:
-		break;
-	}
-
-	pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
-	return host;
-}
-
-struct irq_host *irq_find_host(struct device_node *node)
-{
-	struct irq_host *h, *found = NULL;
-	unsigned long flags;
-
-	/* We might want to match the legacy controller last since
-	 * it might potentially be set to match all interrupts in
-	 * the absence of a device node. This isn't a problem so far
-	 * yet though...
-	 */
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	list_for_each_entry(h, &irq_hosts, link)
-		if (h->ops->match(h, node)) {
-			found = h;
-			break;
-		}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_host *host)
-{
-	pr_debug("irq: Default host set to @0x%p\n", host);
-
-	irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
-	pr_debug("irq: Trying to set virq count to %d\n", count);
-
-	BUG_ON(count < NR_PRIORITY_IRQS);
-	if (count < NR_IRQS)
-		irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
-			    irq_hw_number_t hwirq)
-{
-	int res;
-
-	res = irq_alloc_desc_at(virq, 0);
-	if (res != virq) {
-		pr_debug("irq: -> allocating desc failed\n");
-		goto error;
-	}
-
-	/* map it */
-	smp_wmb();
-	irq_map[virq].hwirq = hwirq;
-	smp_mb();
-
-	if (host->ops->map(host, virq, hwirq)) {
-		pr_debug("irq: -> mapping failed, freeing\n");
-		goto errdesc;
-	}
-
-	irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
-	return 0;
-
-errdesc:
-	irq_free_descs(virq, 1);
-error:
-	irq_free_virt(virq, 1);
-	return -1;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_host *host)
-{
-	unsigned int virq;
-
-	if (host == NULL)
-		host = irq_default_host;
-
-	BUG_ON(host == NULL);
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
-
-	virq = irq_alloc_virt(host, 1, 0);
-	if (virq == NO_IRQ) {
-		pr_debug("irq: create_direct virq allocation failed\n");
-		return NO_IRQ;
-	}
-
-	pr_debug("irq: create_direct obtained virq %d\n", virq);
-
-	if (irq_setup_virq(host, virq, virq))
-		return NO_IRQ;
-
-	return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_host *host,
-				irq_hw_number_t hwirq)
-{
-	unsigned int virq, hint;
-
-	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL) {
-		printk(KERN_WARNING "irq_create_mapping called for"
-		       " NULL host, hwirq=%lx\n", hwirq);
-		WARN_ON(1);
-		return NO_IRQ;
-	}
-	pr_debug("irq: -> using host @%p\n", host);
-
-	/* Check if mapping already exists */
-	virq = irq_find_mapping(host, hwirq);
-	if (virq != NO_IRQ) {
-		pr_debug("irq: -> existing mapping on virq %d\n", virq);
-		return virq;
-	}
-
-	/* Allocate a virtual interrupt number */
-	hint = hwirq % irq_virq_count;
-	virq = irq_alloc_virt(host, 1, hint);
-	if (virq == NO_IRQ) {
-		pr_debug("irq: -> virq allocation failed\n");
-		return NO_IRQ;
-	}
-
-	if (irq_setup_virq(host, virq, hwirq))
-		return NO_IRQ;
-
-	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
-		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	struct irq_host *host;
-	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	unsigned int virq;
-
-	if (controller == NULL)
-		host = irq_default_host;
-	else
-		host = irq_find_host(controller);
-	if (host == NULL) {
-		printk(KERN_WARNING "irq: no irq host found for %s !\n",
-		       controller->full_name);
-		return NO_IRQ;
-	}
-
-	/* If host has no translation, then we assume interrupt line */
-	if (host->ops->xlate == NULL)
-		hwirq = intspec[0];
-	else {
-		if (host->ops->xlate(host, controller, intspec, intsize,
-				     &hwirq, &type))
-			return NO_IRQ;
-	}
-
-	/* Create mapping */
-	virq = irq_create_mapping(host, hwirq);
-	if (virq == NO_IRQ)
-		return virq;
-
-	/* Set type if specified and different than the current one */
-	if (type != IRQ_TYPE_NONE &&
-	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
-		irq_set_irq_type(virq, type);
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-void irq_dispose_mapping(unsigned int virq)
-{
-	struct irq_host *host;
-	irq_hw_number_t hwirq;
-
-	if (virq == NO_IRQ)
-		return;
-
-	/* Never unmap priority interrupts */
-	if (virq < NR_PRIORITY_IRQS)
-		return;
-
-	host = irq_map[virq].host;
-	if (WARN_ON(host == NULL))
-		return;
-
-	irq_set_status_flags(virq, IRQ_NOREQUEST);
-
-	/* remove chip and handler */
-	irq_set_chip_and_handler(virq, NULL, NULL);
-
-	/* Make sure it's completed */
-	synchronize_irq(virq);
-
-	/* Tell the PIC about it */
-	if (host->ops->unmap)
-		host->ops->unmap(host, virq);
-	smp_mb();
-
-	/* Clear reverse map */
-	hwirq = irq_map[virq].hwirq;
-	switch (host->revmap_type) {
-	case IRQ_HOST_MAP_LINEAR:
-		if (hwirq < host->revmap_data.linear.size)
-			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
-		break;
-	case IRQ_HOST_MAP_TREE:
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_delete(&host->revmap_data.tree, hwirq);
-		mutex_unlock(&revmap_trees_mutex);
-		break;
-	}
-
-	/* Destroy map */
-	smp_mb();
-	irq_map[virq].hwirq = host->inval_irq;
-
-	irq_free_descs(virq, 1);
-	/* Free it */
-	irq_free_virt(virq, 1);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_host *host,
-			      irq_hw_number_t hwirq)
-{
-	unsigned int i;
-	unsigned int hint = hwirq % irq_virq_count;
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL)
-		return NO_IRQ;
-
-	/* Slow path does a linear search of the map */
-	i = hint;
-	do  {
-		if (irq_map[i].host == host &&
-		    irq_map[i].hwirq == hwirq)
-			return i;
-		i++;
-		if (i >= irq_virq_count)
-			i = 4;
-	} while (i != hint);
-	return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
-				     irq_hw_number_t hwirq)
-{
-	struct irq_map_entry *ptr;
-	unsigned int virq;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
-		return irq_find_mapping(host, hwirq);
-
-	/*
-	 * The ptr returned references the static global irq_map.
-	 * but freeing an irq can delete nodes along the path to
-	 * do the lookup via call_rcu.
-	 */
-	rcu_read_lock();
-	ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
-	rcu_read_unlock();
-
-	/*
-	 * If found in radix tree, then fine.
-	 * Else fallback to linear lookup - this should not happen in practice
-	 * as it means that we failed to insert the node in the radix tree.
-	 */
-	if (ptr)
-		virq = ptr - irq_map;
-	else
-		virq = irq_find_mapping(host, hwirq);
-
-	return virq;
-}
-
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
-			     irq_hw_number_t hwirq)
-{
-	if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
-		return;
-
-	if (virq != NO_IRQ) {
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&host->revmap_data.tree, hwirq,
-				  &irq_map[virq]);
-		mutex_unlock(&revmap_trees_mutex);
-	}
-}
-
-unsigned int irq_linear_revmap(struct irq_host *host,
-			       irq_hw_number_t hwirq)
-{
-	unsigned int *revmap;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check revmap bounds */
-	if (unlikely(hwirq >= host->revmap_data.linear.size))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check if revmap was allocated */
-	revmap = host->revmap_data.linear.revmap;
-	if (unlikely(revmap == NULL))
-		return irq_find_mapping(host, hwirq);
-
-	/* Fill up revmap with slow path if no mapping found */
-	if (unlikely(revmap[hwirq] == NO_IRQ))
-		revmap[hwirq] = irq_find_mapping(host, hwirq);
-
-	return revmap[hwirq];
-}
-
-unsigned int irq_alloc_virt(struct irq_host *host,
-			    unsigned int count,
-			    unsigned int hint)
-{
-	unsigned long flags;
-	unsigned int i, j, found = NO_IRQ;
-
-	if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS))
-		return NO_IRQ;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* Use hint for 1 interrupt if any */
-	if (count == 1 && hint >= NR_PRIORITY_IRQS &&
-	    hint < irq_virq_count && irq_map[hint].host == NULL) {
-		found = hint;
-		goto hint_found;
-	}
-
-	/* Look for count consecutive numbers in the allocatable
-	 * (non-legacy) space
-	 */
-	for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) {
-		if (irq_map[i].host != NULL)
-			j = 0;
-		else
-			j++;
-
-		if (j == count) {
-			found = i - count + 1;
-			break;
-		}
-	}
-	if (found == NO_IRQ) {
-		raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-		return NO_IRQ;
-	}
- hint_found:
-	for (i = found; i < (found + count); i++) {
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = host;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
-	unsigned long flags;
-	unsigned int i;
-
-	WARN_ON(virq < NR_PRIORITY_IRQS);
-	WARN_ON(count == 0 || (virq + count) > irq_virq_count);
-
-	if (virq < NR_PRIORITY_IRQS) {
-		if (virq + count < NR_PRIORITY_IRQS)
-			return;
-		count  -= NR_PRIORITY_IRQS - virq;
-		virq = NR_PRIORITY_IRQS;
-	}
-
-	if (count > irq_virq_count || virq > irq_virq_count - count) {
-		if (virq > irq_virq_count)
-			return;
-		count = irq_virq_count - virq;
-	}
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	for (i = virq; i < (virq + count); i++) {
-		struct irq_host *host;
-
-		host = irq_map[i].host;
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = NULL;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
-	unsigned long flags;
-	struct irq_desc *desc;
-	const char *p;
-	static const char none[] = "none";
-	void *data;
-	int i;
-
-	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-		      "chip name", "chip data", "host name");
-
-	for (i = 1; i < nr_irqs; i++) {
-		desc = irq_to_desc(i);
-		if (!desc)
-			continue;
-
-		raw_spin_lock_irqsave(&desc->lock, flags);
-
-		if (desc->action && desc->action->handler) {
-			struct irq_chip *chip;
-
-			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", irq_map[i].hwirq);
-
-			chip = irq_desc_get_chip(desc);
-			if (chip && chip->name)
-				p = chip->name;
-			else
-				p = none;
-			seq_printf(m, "%-15s  ", p);
-
-			data = irq_desc_get_chip_data(desc);
-			seq_printf(m, "0x%16p  ", data);
-
-			if (irq_map[i].host && irq_map[i].host->of_node)
-				p = irq_map[i].host->of_node->full_name;
-			else
-				p = none;
-			seq_printf(m, "%s\n", p);
-		}
-
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-	}
-
-	return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
-	.open = virq_debug_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
-	if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
-				 NULL, &virq_debug_fops) == NULL)
-		return -ENOMEM;
-
-	return 0;
-}
-device_initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
index 304f675..3b5a050 100644
--- a/arch/c6x/kernel/signal.c
+++ b/arch/c6x/kernel/signal.c
@@ -85,10 +85,7 @@ asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -279,15 +276,8 @@ static int handle_signal(int sig,
 
 	/* Set up the stack frame */
 	ret = setup_rt_frame(sig, ka, info, oldset, regs);
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 7c37a94..c1c4e2a 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -48,7 +48,7 @@ struct megamod_regs {
 };
 
 struct megamod_pic {
-	struct irq_host	*irqhost;
+	struct irq_domain *irqhost;
 	struct megamod_regs __iomem *regs;
 	raw_spinlock_t lock;
 
@@ -116,7 +116,7 @@ static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int megamod_map(struct irq_host *h, unsigned int virq,
+static int megamod_map(struct irq_domain *h, unsigned int virq,
 		       irq_hw_number_t hw)
 {
 	struct megamod_pic *pic = h->host_data;
@@ -136,21 +136,9 @@ static int megamod_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int megamod_xlate(struct irq_host *h, struct device_node *ct,
-			 const u32 *intspec, unsigned int intsize,
-			 irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
-	/* megamod intspecs must have 1 cell */
-	BUG_ON(intsize != 1);
-	*out_hwirq = intspec[0];
-	*out_type = IRQ_TYPE_NONE;
-	return 0;
-}
-
-static struct irq_host_ops megamod_host_ops = {
+static const struct irq_domain_ops megamod_domain_ops = {
 	.map	= megamod_map,
-	.xlate	= megamod_xlate,
+	.xlate	= irq_domain_xlate_onecell,
 };
 
 static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output)
@@ -223,9 +211,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np)
 		return NULL;
 	}
 
-	pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-				      NR_COMBINERS * 32, &megamod_host_ops,
-				      IRQ_UNMAPPED);
+	pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32,
+					     &megamod_domain_ops, pic);
 	if (!pic->irqhost) {
 		pr_err("%s: Could not alloc host.\n", np->full_name);
 		goto error_free;
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index e78fe49..a6e1ff0 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -50,12 +50,14 @@ void do_signal(int canrestart, struct pt_regs *regs);
 int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
 	long srp, struct pt_regs *regs)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
+
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
 	set_thread_flag(TIF_RESTORE_SIGMASK);
@@ -184,10 +186,7 @@ asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->sc))
 		goto badframe;
@@ -223,10 +222,7 @@ asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -468,15 +464,9 @@ static inline int handle_signal(int canrestart, unsigned long sig,
 	else
 		ret = setup_frame(sig, ka, oldset, regs);
 
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			&ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
+
 	return ret;
 }
 
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index 642c6fe..f8476d9 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -1394,11 +1394,10 @@ static int create_md5_pad(int alloc_flag, unsigned long long hashed_length, char
 
 	if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH;
 
-	p = kmalloc(padlen, alloc_flag);
+	p = kzalloc(padlen, alloc_flag);
 	if (!p) return -ENOMEM;
 
 	*p = 0x80;
-	memset(p+1, 0, padlen - 1);
 
 	DEBUG(printk("create_md5_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
 
@@ -1426,11 +1425,10 @@ static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, cha
 
 	if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH;
 
-	p = kmalloc(padlen, alloc_flag);
+	p = kzalloc(padlen, alloc_flag);
 	if (!p) return -ENOMEM;
 
 	*p = 0x80;
-	memset(p+1, 0, padlen - 1);
 
 	DEBUG(printk("create_sha1_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
 
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 511ece9..42ed6c7 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -115,8 +115,6 @@ void user_disable_single_step(struct task_struct *child)
 void
 ptrace_disable(struct task_struct *child)
 {
-	unsigned long tmp;
-
 	/* Deconfigure SPC and S-bit. */
 	user_disable_single_step(child);
 	put_reg(child, PT_SPC, 0);
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index ce4ab1a..e7ea1ea 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -62,12 +62,14 @@ int
 sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
 	       long srp, struct pt_regs *regs)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
+
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
 	set_thread_flag(TIF_RESTORE_SIGMASK);
@@ -176,12 +178,7 @@ sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-
-	current->blocked = set;
-
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->sc))
 		goto badframe;
@@ -222,12 +219,7 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-
-	current->blocked = set;
-
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -515,15 +507,8 @@ handle_signal(int canrestart, unsigned long sig,
 	if (ka->sa.sa_flags & SA_ONESHOT)
 		ka->sa.sa_handler = SIG_DFL;
 
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			&ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
index 1de779f..7caf25d 100644
--- a/arch/cris/include/arch-v32/arch/cache.h
+++ b/arch/cris/include/arch-v32/arch/cache.h
@@ -7,7 +7,7 @@
 #define L1_CACHE_BYTES 32
 #define L1_CACHE_SHIFT 5
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
 
 void flush_dma_list(dma_descr_data *descr);
 void flush_dma_descr(dma_descr_data *descr, int flush_buf);
diff --git a/arch/cris/include/asm/posix_types.h b/arch/cris/include/asm/posix_types.h
index ce3fb25..72b3cd6 100644
--- a/arch/cris/include/asm/posix_types.h
+++ b/arch/cris/include/asm/posix_types.h
@@ -12,55 +12,25 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short  __kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
+#define __kernel_uid_t __kernel_uid_t
+
 typedef __SIZE_TYPE__	__kernel_size_t;
 typedef long		__kernel_ssize_t;
 typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long            __kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short  __kernel_uid16_t;
-typedef unsigned short  __kernel_gid16_t;
-typedef unsigned int    __kernel_uid32_t;
-typedef unsigned int    __kernel_gid32_t;
+#define __kernel_size_t __kernel_size_t
 
-typedef unsigned short  __kernel_old_uid_t;
-typedef unsigned short  __kernel_old_gid_t;
 typedef unsigned short	__kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#ifdef __KERNEL__
-
-#undef	__FD_SET
-#define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd,fdsetp) clear_bit(fd, (void *)(fdsetp))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd,fdsetp) test_bit(fd, (void *)(fdsetp))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) memset((void *)(fdsetp), 0, __FDSET_LONGS << 2)
-
-#endif /* __KERNEL__ */
+#define __kernel_old_dev_t __kernel_old_dev_t
 
 #endif /* __ARCH_CRIS_POSIX_TYPES_H */
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index e269264..048aba6 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -66,6 +66,7 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
 
diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h
index a8d6565..716956a 100644
--- a/arch/frv/include/asm/highmem.h
+++ b/arch/frv/include/asm/highmem.h
@@ -157,7 +157,7 @@ static inline void kunmap_atomic_primary(void *kvaddr, enum km_type type)
 	pagefault_enable();
 }
 
-void *__kmap_atomic(struct page *page);
+void *kmap_atomic(struct page *page);
 void __kunmap_atomic(void *kvaddr);
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/frv/include/asm/perf_event.h b/arch/frv/include/asm/perf_event.h
index a69e015..c52ea55 100644
--- a/arch/frv/include/asm/perf_event.h
+++ b/arch/frv/include/asm/perf_event.h
@@ -12,6 +12,4 @@
 #ifndef _ASM_PERF_EVENT_H
 #define _ASM_PERF_EVENT_H
 
-#define PERF_EVENT_INDEX_OFFSET	0
-
 #endif /* _ASM_PERF_EVENT_H */
diff --git a/arch/frv/include/asm/posix_types.h b/arch/frv/include/asm/posix_types.h
index a9f1f5b..3f34cb4 100644
--- a/arch/frv/include/asm/posix_types.h
+++ b/arch/frv/include/asm/posix_types.h
@@ -7,56 +7,23 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short	__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
-typedef unsigned short	__kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
+#define __kernel_uid_t __kernel_uid_t
 
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-
-#undef	__FD_CLR
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-
-#undef	__FD_ISSET
-#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif
 
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h
index ce80fda..7a361810f3 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/asm/socket.h
@@ -64,6 +64,7 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
 
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index bab0129..dfa460e 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -40,12 +40,13 @@ struct fdpic_func_descriptor {
  */
 asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -158,10 +159,7 @@ asmlinkage int sys_sigreturn(void)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(&frame->sc, &gr8))
 		goto badframe;
@@ -184,10 +182,7 @@ asmlinkage int sys_rt_sigreturn(void)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
 		goto badframe;
@@ -474,15 +469,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 	else
 		ret = setup_frame(sig, ka, oldset);
 
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index fd7fcd4..31902c9 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -37,7 +37,7 @@ struct page *kmap_atomic_to_page(void *ptr)
 	return virt_to_page(ptr);
 }
 
-void *__kmap_atomic(struct page *page)
+void *kmap_atomic(struct page *page)
 {
 	unsigned long paddr;
 	int type;
@@ -64,7 +64,7 @@ void *__kmap_atomic(struct page *page)
 		return NULL;
 	}
 }
-EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic);
 
 void __kunmap_atomic(void *kvaddr)
 {
diff --git a/arch/h8300/include/asm/posix_types.h b/arch/h8300/include/asm/posix_types.h
index 6f833a1..bc4c34e 100644
--- a/arch/h8300/include/asm/posix_types.h
+++ b/arch/h8300/include/asm/posix_types.h
@@ -7,54 +7,23 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short	__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
+#define __kernel_uid_t __kernel_uid_t
 
 typedef unsigned short	__kernel_old_uid_t;
 typedef unsigned short	__kernel_old_gid_t;
+#define __kernel_old_uid_t __kernel_old_uid_t
 
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-
-#undef	__FD_CLR
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-
-#undef	__FD_ISSET
-#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index cf1daab..e7bbfce 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -64,5 +64,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index af842c3..cd63f5a 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -57,14 +57,13 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
 asmlinkage int do_sigsuspend(struct pt_regs *regs)
 {
 	old_sigset_t mask = regs->er3;
-	sigset_t saveset;
+	sigset_t saveset, blocked;
 
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	regs->er0 = -EINTR;
 	while (1) {
@@ -90,11 +89,8 @@ do_rt_sigsuspend(struct pt_regs *regs)
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	regs->er0 = -EINTR;
 	while (1) {
@@ -232,10 +228,7 @@ asmlinkage int do_sigreturn(unsigned long __unused,...)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 	
 	if (restore_sigcontext(regs, &frame->sc, &er0))
 		goto badframe;
@@ -260,10 +253,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_unlock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_lock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 	
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
 		goto badframe;
@@ -489,12 +479,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	else
 		setup_frame(sig, ka, oldset, regs);
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 }
 
 /*
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 9059e39..acdc187 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -13,21 +13,19 @@ config HEXAGON
 	# select ARCH_REQUIRE_GPIOLIB
 	# select HAVE_CLK
 	# select IRQ_PER_CPU
-	select HAVE_IRQ_WORK
 	# select GENERIC_PENDING_IRQ if SMP
+	select HAVE_IRQ_WORK
 	select GENERIC_ATOMIC64
 	select HAVE_PERF_EVENTS
 	select HAVE_GENERIC_HARDIRQS
-	select GENERIC_HARDIRQS_NO__DO_IRQ
-	select GENERIC_HARDIRQS_NO_DEPRECATED
 	# GENERIC_ALLOCATOR is used by dma_alloc_coherent()
 	select GENERIC_ALLOCATOR
 	select GENERIC_IRQ_SHOW
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_TRACEHOOK
 	select NO_IOPORT
+	select STACKTRACE_SUPPORT
 	select GENERIC_IOMAP
-	# mostly generic routines, with some accelerated ones
 	---help---
 	  Qualcomm Hexagon is a processor architecture designed for high
 	  performance and low power across a wide variety of applications.
@@ -74,15 +72,6 @@ config GENERIC_CSUM
 config GENERIC_IRQ_PROBE
 	def_bool y
 
-#config ZONE_DMA
-#	bool
-#	default y
-
-config HAS_DMA
-	bool
-	select HAVE_DMA_ATTRS
-	default y
-
 config NEED_SG_DMA_LENGTH
 	def_bool y
 
@@ -115,14 +104,11 @@ config GENERIC_BUG
 	def_bool y
 	depends on BUG
 
-config BUG
-	def_bool y
-
 menu "Machine selection"
 
 choice
 	prompt "System type"
-	default HEXAGON_ARCH_V2
+	default HEXAGON_COMET
 
 config HEXAGON_COMET
 	bool "Comet Board"
@@ -195,8 +181,7 @@ source "kernel/Kconfig.hz"
 source "kernel/time/Kconfig"
 
 config GENERIC_GPIO
-	bool "Generic GPIO support"
-	default n
+	def_bool n
 
 endmenu
 
diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile
index 0c4de87..9dfe1b9 100644
--- a/arch/hexagon/Makefile
+++ b/arch/hexagon/Makefile
@@ -52,7 +52,3 @@ core-y += arch/hexagon/kernel/ \
 	arch/hexagon/mm/ \
 	arch/hexagon/lib/
 
-#	arch/hexagon/platform/common/
-#
-#core-$(CONFIG_HEXAGON_COMET)		+= arch/hexagon/platform/comet/
-#machine-$(CONFIG_HEXAGON_COMET)		:= comet
diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h
index 448b224..233ed3d 100644
--- a/arch/hexagon/include/asm/dma-mapping.h
+++ b/arch/hexagon/include/asm/dma-mapping.h
@@ -71,29 +71,35 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 	return (dma_addr == bad_dma_address);
 }
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	void *ret;
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	BUG_ON(!dma_ops);
 
-	ret = ops->alloc_coherent(dev, size, dma_handle, flag);
+	ret = ops->alloc(dev, size, dma_handle, flag, attrs);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
 
 	return ret;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
 	BUG_ON(!dma_ops);
 
-	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	dma_ops->free(dev, size, cpu_addr, dma_handle, attrs);
 
 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
 }
diff --git a/arch/hexagon/include/asm/perf_event.h b/arch/hexagon/include/asm/perf_event.h
index 6c2910f..8b8526b 100644
--- a/arch/hexagon/include/asm/perf_event.h
+++ b/arch/hexagon/include/asm/perf_event.h
@@ -19,6 +19,4 @@
 #ifndef _ASM_PERF_EVENT_H
 #define _ASM_PERF_EVENT_H
 
-#define PERF_EVENT_INDEX_OFFSET	0
-
 #endif /* _ASM_PERF_EVENT_H */
diff --git a/arch/hexagon/include/asm/spinlock_types.h b/arch/hexagon/include/asm/spinlock_types.h
index 5e937af..99b5a75 100644
--- a/arch/hexagon/include/asm/spinlock_types.h
+++ b/arch/hexagon/include/asm/spinlock_types.h
@@ -21,8 +21,6 @@
 #ifndef _ASM_SPINLOCK_TYPES_H
 #define _ASM_SPINLOCK_TYPES_H
 
-#include <linux/version.h>
-
 #ifndef __LINUX_SPINLOCK_TYPES_H
 # error "please don't include this file directly"
 #endif
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index e711ace..0f2367c 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -22,6 +22,7 @@
 #include <linux/bootmem.h>
 #include <linux/genalloc.h>
 #include <asm/dma-mapping.h>
+#include <linux/module.h>
 
 struct dma_map_ops *dma_ops;
 EXPORT_SYMBOL(dma_ops);
@@ -54,7 +55,8 @@ static struct gen_pool *coherent_pool;
 /* Allocates from a pool of uncached memory that was reserved at boot time */
 
 void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
-				 dma_addr_t *dma_addr, gfp_t flag)
+				 dma_addr_t *dma_addr, gfp_t flag,
+				 struct dma_attrs *attrs)
 {
 	void *ret;
 
@@ -81,7 +83,7 @@ void *hexagon_dma_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr,
-				  dma_addr_t dma_addr)
+				  dma_addr_t dma_addr, struct dma_attrs *attrs)
 {
 	gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
 }
@@ -202,8 +204,8 @@ static void hexagon_sync_single_for_device(struct device *dev,
 }
 
 struct dma_map_ops hexagon_dma_ops = {
-	.alloc_coherent	= hexagon_dma_alloc_coherent,
-	.free_coherent	= hexagon_free_coherent,
+	.alloc		= hexagon_dma_alloc_coherent,
+	.free		= hexagon_free_coherent,
 	.map_sg		= hexagon_map_sg,
 	.map_page	= hexagon_map_page,
 	.sync_single_for_cpu = hexagon_sync_single_for_cpu,
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c
index bea3f08..8fe0349 100644
--- a/arch/hexagon/kernel/ptrace.c
+++ b/arch/hexagon/kernel/ptrace.c
@@ -28,6 +28,7 @@
 #include <linux/ptrace.h>
 #include <linux/regset.h>
 #include <linux/user.h>
+#include <linux/elf.h>
 
 #include <asm/system.h>
 #include <asm/user.h>
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index b45be31..ecbab34 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -192,12 +192,7 @@ static int handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
 	if (rc)
 		return rc;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 
 	return 0;
 }
@@ -305,10 +300,7 @@ asmlinkage int sys_rt_sigreturn(void)
 		goto badframe;
 
 	sigdelsetmask(&blocked, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = blocked;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&blocked);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c
index 6bee15c..36ba641 100644
--- a/arch/hexagon/kernel/time.c
+++ b/arch/hexagon/kernel/time.c
@@ -28,6 +28,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/module.h>
 
 #include <asm/timer-regs.h>
 #include <asm/hexagon_vm.h>
@@ -200,12 +201,10 @@ void __init time_init_deferred(void)
 		resource = rtos_timer_device.resource;
 
 	/*  ioremap here means this has to run later, after paging init  */
-	rtos_timer = ioremap(resource->start, resource->end
-		- resource->start + 1);
+	rtos_timer = ioremap(resource->start, resource_size(resource));
 
 	if (!rtos_timer) {
-		release_mem_region(resource->start, resource->end
-			- resource->start + 1);
+		release_mem_region(resource->start, resource_size(resource));
 	}
 	clocksource_register_khz(&hexagon_clocksource, pcycle_freq_mhz * 1000);
 
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c
index 16277c3..e4ceedb 100644
--- a/arch/hexagon/kernel/vdso.c
+++ b/arch/hexagon/kernel/vdso.c
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/binfmts.h>
 
 #include <asm/vdso.h>
 
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index f5f4ef1..e5eb9c4 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -1130,7 +1130,8 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
  * See Documentation/DMA-API-HOWTO.txt
  */
 static void *
-sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
+sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		   gfp_t flags, struct dma_attrs *attrs)
 {
 	struct ioc *ioc;
 	void *addr;
@@ -1192,8 +1193,8 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp
  *
  * See Documentation/DMA-API-HOWTO.txt
  */
-static void sba_free_coherent (struct device *dev, size_t size, void *vaddr,
-			       dma_addr_t dma_handle)
+static void sba_free_coherent(struct device *dev, size_t size, void *vaddr,
+			      dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL);
 	free_pages((unsigned long) vaddr, get_order(size));
@@ -2213,8 +2214,8 @@ sba_page_override(char *str)
 __setup("sbapagesize=",sba_page_override);
 
 struct dma_map_ops sba_dma_ops = {
-	.alloc_coherent		= sba_alloc_coherent,
-	.free_coherent		= sba_free_coherent,
+	.alloc			= sba_alloc_coherent,
+	.free			= sba_free_coherent,
 	.map_page		= sba_map_page,
 	.unmap_page		= sba_unmap_page,
 	.map_sg			= sba_map_sg_attrs,
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 4336d08..4f5e814 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -23,23 +23,29 @@ extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t,
 extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
 				enum dma_data_direction);
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *daddr, gfp_t gfp)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *daddr, gfp_t gfp,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = platform_dma_get_ops(dev);
 	void *caddr;
 
-	caddr = ops->alloc_coherent(dev, size, daddr, gfp);
+	caddr = ops->alloc(dev, size, daddr, gfp, attrs);
 	debug_dma_alloc_coherent(dev, size, *daddr, caddr);
 	return caddr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *caddr, dma_addr_t daddr)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *caddr, dma_addr_t daddr,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = platform_dma_get_ops(dev);
 	debug_dma_free_coherent(dev, size, caddr, daddr);
-	ops->free_coherent(dev, size, caddr, daddr);
+	ops->free(dev, size, caddr, daddr, attrs);
 }
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
diff --git a/arch/ia64/include/asm/posix_types.h b/arch/ia64/include/asm/posix_types.h
index 1788556..7323ab9 100644
--- a/arch/ia64/include/asm/posix_types.h
+++ b/arch/ia64/include/asm/posix_types.h
@@ -1,126 +1,11 @@
 #ifndef _ASM_IA64_POSIX_TYPES_H
 #define _ASM_IA64_POSIX_TYPES_H
 
-/*
- * This file is generally used by user-level software, so you need to
- * be a little careful about namespace pollution etc.  Also, we cannot
- * assume GCC is being used.
- *
- * Based on <asm-alpha/posix_types.h>.
- *
- * Modified 1998-2000, 2003
- *	David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
- */
-
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
 typedef unsigned int	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef long long	__kernel_loff_t;
-typedef int		__kernel_pid_t;
-typedef int		__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned long	__kernel_sigset_t;	/* at least 32 bits */
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-typedef __kernel_uid_t __kernel_old_uid_t;
-typedef __kernel_gid_t __kernel_old_gid_t;
-typedef __kernel_uid_t __kernel_uid32_t;
-typedef __kernel_gid_t __kernel_gid32_t;
-
-typedef unsigned int	__kernel_old_dev_t;
-
-# ifdef __KERNEL__
-
-#  ifndef __GNUC__
-
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define	__FD_ISSET(d, set)	(((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
-#define	__FD_ZERO(set)	\
-  ((void) memset ((void *) (set), 0, sizeof (__kernel_fd_set)))
+#define __kernel_nlink_t __kernel_nlink_t
 
-#  else /* !__GNUC__ */
-
-/* With GNU C, use inline functions instead so args are evaluated only once: */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, const __kernel_fd_set *p)
-{ 
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned long *tmp = p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		      case 16:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			return;
-
-		      case 8:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			return;
+typedef unsigned long	__kernel_sigset_t;	/* at least 32 bits */
 
-		      case 4:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
+#include <asm-generic/posix_types.h>
 
-#  endif /* !__GNUC__ */
-# endif /* __KERNEL__ */
 #endif /* _ASM_IA64_POSIX_TYPES_H */
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index 4b03664..ced62de 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -73,5 +73,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 5207035..2ad7328 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -844,7 +844,7 @@ early_param("additional_cpus", setup_additional_cpus);
  * are onlined, or offlined. The reason is per-cpu data-structures
  * are allocated by some modules at init time, and dont expect to
  * do this dynamically on cpu arrival/departure.
- * cpu_present_map on the other hand can change dynamically.
+ * cpu_present_mask on the other hand can change dynamically.
  * In case when cpu_hotplug is not compiled, then we resort to current
  * behaviour, which is cpu_possible == cpu_present.
  * - Ashok Raj
@@ -922,7 +922,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu)
 
 	acpi_map_cpu2node(handle, cpu, physid);
 
-	cpu_set(cpu, cpu_present_map);
+	set_cpu_present(cpu, true);
 	ia64_cpu_to_sapicid[cpu] = physid;
 
 	acpi_processor_set_pdc(handle);
@@ -941,7 +941,7 @@ EXPORT_SYMBOL(acpi_map_lsapic);
 int acpi_unmap_lsapic(int cpu)
 {
 	ia64_cpu_to_sapicid[cpu] = -1;
-	cpu_clear(cpu, cpu_present_map);
+	set_cpu_present(cpu, false);
 
 #ifdef CONFIG_ACPI_NUMA
 	/* NUMA specific cleanup's */
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 782c3a35..51da772 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -118,7 +118,7 @@ static inline int find_unassigned_vector(cpumask_t domain)
 	cpumask_t mask;
 	int pos, vector;
 
-	cpus_and(mask, domain, cpu_online_map);
+	cpumask_and(&mask, &domain, cpu_online_mask);
 	if (cpus_empty(mask))
 		return -EINVAL;
 
@@ -141,7 +141,7 @@ static int __bind_irq_vector(int irq, int vector, cpumask_t domain)
 	BUG_ON((unsigned)irq >= NR_IRQS);
 	BUG_ON((unsigned)vector >= IA64_NUM_VECTORS);
 
-	cpus_and(mask, domain, cpu_online_map);
+	cpumask_and(&mask, &domain, cpu_online_mask);
 	if (cpus_empty(mask))
 		return -EINVAL;
 	if ((cfg->vector == vector) && cpus_equal(cfg->domain, domain))
@@ -179,7 +179,7 @@ static void __clear_irq_vector(int irq)
 	BUG_ON(cfg->vector == IRQ_VECTOR_UNASSIGNED);
 	vector = cfg->vector;
 	domain = cfg->domain;
-	cpus_and(mask, cfg->domain, cpu_online_map);
+	cpumask_and(&mask, &cfg->domain, cpu_online_mask);
 	for_each_cpu_mask(cpu, mask)
 		per_cpu(vector_irq, cpu)[vector] = -1;
 	cfg->vector = IRQ_VECTOR_UNASSIGNED;
@@ -322,7 +322,7 @@ void irq_complete_move(unsigned irq)
 	if (unlikely(cpu_isset(smp_processor_id(), cfg->old_domain)))
 		return;
 
-	cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map);
+	cpumask_and(&cleanup_mask, &cfg->old_domain, cpu_online_mask);
 	cfg->move_cleanup_count = cpus_weight(cleanup_mask);
 	for_each_cpu_mask(i, cleanup_mask)
 		platform_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0);
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 84fb405..26dbbd3 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1447,6 +1447,8 @@ out:
 	/* Get the CMC error record and log it */
 	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
 
+	local_irq_disable();
+
 	return IRQ_HANDLED;
 }
 
@@ -1513,7 +1515,8 @@ static void
 ia64_mca_cmc_poll (unsigned long dummy)
 {
 	/* Trigger a CMC interrupt cascade  */
-	platform_send_ipi(first_cpu(cpu_online_map), IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
+	platform_send_ipi(cpumask_first(cpu_online_mask), IA64_CMCP_VECTOR,
+							IA64_IPI_DM_INT, 0);
 }
 
 /*
@@ -1589,7 +1592,8 @@ static void
 ia64_mca_cpe_poll (unsigned long dummy)
 {
 	/* Trigger a CPE interrupt cascade  */
-	platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
+	platform_send_ipi(cpumask_first(cpu_online_mask), IA64_CPEP_VECTOR,
+							IA64_IPI_DM_INT, 0);
 }
 
 #endif /* CONFIG_ACPI */
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 94e0db7..fb2f1e6 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -57,7 +57,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 		return irq;
 
 	irq_set_msi_desc(irq, desc);
-	cpus_and(mask, irq_to_domain(irq), cpu_online_map);
+	cpumask_and(&mask, &(irq_to_domain(irq)), cpu_online_mask);
 	dest_phys_id = cpu_physical_id(first_cpu(mask));
 	vector = irq_to_vector(irq);
 
@@ -179,7 +179,7 @@ msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
 	unsigned dest;
 	cpumask_t mask;
 
-	cpus_and(mask, irq_to_domain(irq), cpu_online_map);
+	cpumask_and(&mask, &(irq_to_domain(irq)), cpu_online_mask);
 	dest = cpu_physical_id(first_cpu(mask));
 
 	msg->address_hi = 0;
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index d9485d9..cc034c2 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -15,16 +15,17 @@ int swiotlb __read_mostly;
 EXPORT_SYMBOL(swiotlb);
 
 static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
-					 dma_addr_t *dma_handle, gfp_t gfp)
+					 dma_addr_t *dma_handle, gfp_t gfp,
+					 struct dma_attrs *attrs)
 {
 	if (dev->coherent_dma_mask != DMA_BIT_MASK(64))
 		gfp |= GFP_DMA;
-	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+	return swiotlb_alloc_coherent(dev, size, dma_handle, gfp, attrs);
 }
 
 struct dma_map_ops swiotlb_dma_ops = {
-	.alloc_coherent = ia64_swiotlb_alloc_coherent,
-	.free_coherent = swiotlb_free_coherent,
+	.alloc = ia64_swiotlb_alloc_coherent,
+	.free = swiotlb_free_coherent,
 	.map_page = swiotlb_map_page,
 	.unmap_page = swiotlb_unmap_page,
 	.map_sg = swiotlb_map_sg_attrs,
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index cd57d73..4d1a550 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -486,7 +486,7 @@ mark_bsp_online (void)
 {
 #ifdef CONFIG_SMP
 	/* If we register an early console, allow CPU 0 to printk */
-	cpu_set(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), true);
 #endif
 }
 
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 7bdafc8..7523501 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -201,13 +201,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
 		goto give_sigsegv;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	{
-		current->blocked = set;
-		recalc_sigpending();
-	}
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(sc, scr))
 		goto give_sigsegv;
@@ -427,12 +421,7 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
 	if (!setup_frame(sig, ka, info, oldset, scr))
 		return 0;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 
 	/*
 	 * Let tracing know that we've done the handler setup.
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index 0bd537b..8551979 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -77,7 +77,7 @@ stop_this_cpu(void)
 	/*
 	 * Remove this CPU:
 	 */
-	cpu_clear(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), false);
 	max_xtp();
 	local_irq_disable();
 	cpu_halt();
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 5590979..90916be 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -401,7 +401,7 @@ smp_callin (void)
 	/* Setup the per cpu irq handling data structures */
 	__setup_vector_irq(cpuid);
 	notify_cpu_starting(cpuid);
-	cpu_set(cpuid, cpu_online_map);
+	set_cpu_online(cpuid, true);
 	per_cpu(cpu_state, cpuid) = CPU_ONLINE;
 	spin_unlock(&vector_lock);
 	ipi_call_unlock_irq();
@@ -548,7 +548,7 @@ do_rest:
 	if (!cpu_isset(cpu, cpu_callin_map)) {
 		printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
 		ia64_cpu_to_sapicid[cpu] = -1;
-		cpu_clear(cpu, cpu_online_map);  /* was set in smp_callin() */
+		set_cpu_online(cpu, false);  /* was set in smp_callin() */
 		return -EINVAL;
 	}
 	return 0;
@@ -578,8 +578,7 @@ smp_build_cpu_map (void)
 	}
 
 	ia64_cpu_to_sapicid[0] = boot_cpu_id;
-	cpus_clear(cpu_present_map);
-	set_cpu_present(0, true);
+	init_cpu_present(cpumask_of(0));
 	set_cpu_possible(0, true);
 	for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
 		sapicid = smp_boot_data.cpu_phys_id[i];
@@ -606,10 +605,6 @@ smp_prepare_cpus (unsigned int max_cpus)
 
 	smp_setup_percpu_timer();
 
-	/*
-	 * We have the boot CPU online for sure.
-	 */
-	cpu_set(0, cpu_online_map);
 	cpu_set(0, cpu_callin_map);
 
 	local_cpu_data->loops_per_jiffy = loops_per_jiffy;
@@ -633,7 +628,7 @@ smp_prepare_cpus (unsigned int max_cpus)
 
 void __devinit smp_prepare_boot_cpu(void)
 {
-	cpu_set(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), true);
 	cpu_set(smp_processor_id(), cpu_callin_map);
 	set_numa_node(cpu_to_node_map[smp_processor_id()]);
 	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
@@ -690,7 +685,7 @@ int migrate_platform_irqs(unsigned int cpu)
 			/*
 			 * Now re-target the CPEI to a different processor
 			 */
-			new_cpei_cpu = any_online_cpu(cpu_online_map);
+			new_cpei_cpu = cpumask_any(cpu_online_mask);
 			mask = cpumask_of(new_cpei_cpu);
 			set_cpei_target_cpu(new_cpei_cpu);
 			data = irq_get_irq_data(ia64_cpe_irq);
@@ -732,10 +727,10 @@ int __cpu_disable(void)
 			return -EBUSY;
 	}
 
-	cpu_clear(cpu, cpu_online_map);
+	set_cpu_online(cpu, false);
 
 	if (migrate_platform_irqs(cpu)) {
-		cpu_set(cpu, cpu_online_map);
+		set_cpu_online(cpu, true);
 		return -EBUSY;
 	}
 
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 9deb21d..c64460b 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -220,7 +220,8 @@ static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf)
 	ssize_t	len;
 	cpumask_t shared_cpu_map;
 
-	cpus_and(shared_cpu_map, this_leaf->shared_cpu_map, cpu_online_map);
+	cpumask_and(&shared_cpu_map,
+				&this_leaf->shared_cpu_map, cpu_online_mask);
 	len = cpumask_scnprintf(buf, NR_CPUS+1, &shared_cpu_map);
 	len += sprintf(buf+len, "\n");
 	return len;
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index a9d310d..3290d6e 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -76,7 +76,8 @@ EXPORT_SYMBOL(sn_dma_set_mask);
  * more information.
  */
 static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
-				   dma_addr_t * dma_handle, gfp_t flags)
+				   dma_addr_t * dma_handle, gfp_t flags,
+				   struct dma_attrs *attrs)
 {
 	void *cpuaddr;
 	unsigned long phys_addr;
@@ -137,7 +138,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
  * any associated IOMMU mappings.
  */
 static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-				 dma_addr_t dma_handle)
+				 dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
@@ -466,8 +467,8 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
 }
 
 static struct dma_map_ops sn_dma_ops = {
-	.alloc_coherent		= sn_dma_alloc_coherent,
-	.free_coherent		= sn_dma_free_coherent,
+	.alloc			= sn_dma_alloc_coherent,
+	.free			= sn_dma_free_coherent,
 	.map_page		= sn_dma_map_page,
 	.unmap_page		= sn_dma_unmap_page,
 	.map_sg			= sn_dma_map_sg,
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c
index b279e14..3bb1223 100644
--- a/arch/ia64/xen/irq_xen.c
+++ b/arch/ia64/xen/irq_xen.c
@@ -58,7 +58,7 @@ xen_free_irq_vector(int vector)
 
 	irq_op.vector = vector;
 	if (HYPERVISOR_physdev_op(PHYSDEVOP_free_irq_vector, &irq_op))
-		printk(KERN_WARNING "%s: xen_free_irq_vecotr fail vector=%d\n",
+		printk(KERN_WARNING "%s: xen_free_irq_vector fail vector=%d\n",
 		       __func__, vector);
 }
 
diff --git a/arch/m32r/include/asm/posix_types.h b/arch/m32r/include/asm/posix_types.h
index b309c58..0195850 100644
--- a/arch/m32r/include/asm/posix_types.h
+++ b/arch/m32r/include/asm/posix_types.h
@@ -7,112 +7,22 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short	__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
+#define __kernel_uid_t __kernel_uid_t
 
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
 typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
-}
-
-#undef	__FD_CLR
-static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
-}
-
-
-#undef	__FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef	__FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
-{
-	unsigned long *__tmp = __p->fds_bits;
-	int __i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		case 16:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			__tmp[ 8] = 0; __tmp[ 9] = 0;
-			__tmp[10] = 0; __tmp[11] = 0;
-			__tmp[12] = 0; __tmp[13] = 0;
-			__tmp[14] = 0; __tmp[15] = 0;
-			return;
-
-		case 8:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			return;
-
-		case 4:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			return;
-		}
-	}
-	__i = __FDSET_LONGS;
-	while (__i) {
-		__i--;
-		*__tmp = 0;
-		__tmp++;
-	}
-}
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif  /* _ASM_M32R_POSIX_TYPES_H */
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h
index e8b8c5b..696cb4c 100644
--- a/arch/m32r/include/asm/socket.h
+++ b/arch/m32r/include/asm/socket.h
@@ -64,5 +64,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index a08697f..f54d969 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -112,10 +112,7 @@ sys_rt_sigreturn(unsigned long r0, unsigned long r1,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &result))
 		goto badframe;
@@ -300,12 +297,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
 	if (setup_rt_frame(sig, ka, info, oldset, regs))
 		return -EFAULT;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 	return 0;
 }
 
diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h
index 756bde4..3c79368 100644
--- a/arch/m68k/include/asm/mcf_pgtable.h
+++ b/arch/m68k/include/asm/mcf_pgtable.h
@@ -78,7 +78,8 @@
 				 | CF_PAGE_READABLE \
 				 | CF_PAGE_WRITABLE \
 				 | CF_PAGE_EXEC \
-				 | CF_PAGE_SYSTEM)
+				 | CF_PAGE_SYSTEM \
+				 | CF_PAGE_SHARED)
 
 #define PAGE_COPY	__pgprot(CF_PAGE_VALID \
 				 | CF_PAGE_ACCESSED \
diff --git a/arch/m68k/include/asm/posix_types.h b/arch/m68k/include/asm/posix_types.h
index 98d0970..6373093 100644
--- a/arch/m68k/include/asm/posix_types.h
+++ b/arch/m68k/include/asm/posix_types.h
@@ -7,55 +7,22 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short	__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
-typedef unsigned short	__kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
+#define __kernel_uid_t __kernel_uid_t
 
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-
-#undef	__FD_CLR
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-
-#undef	__FD_ISSET
-#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
+typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index d4708ce..e8b41a6 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -64,5 +64,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
index cb856f9..93208b8 100644
--- a/arch/m68k/kernel/signal_mm.c
+++ b/arch/m68k/kernel/signal_mm.c
@@ -105,12 +105,13 @@ int handle_kernel_fault(struct pt_regs *regs)
 asmlinkage int
 sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -528,8 +529,7 @@ asmlinkage int do_sigreturn(unsigned long __unused)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	current->blocked = set;
-	recalc_sigpending();
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->sc, frame + 1))
 		goto badframe;
@@ -554,8 +554,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	current->blocked = set;
-	recalc_sigpending();
+	set_current_blocked(&set);
 
 	if (rt_restore_ucontext(regs, sw, &frame->uc))
 		goto badframe;
@@ -1063,10 +1062,7 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	if (err)
 		return;
 
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
+	block_sigmask(ka, sig);
 
 	if (test_thread_flag(TIF_DELAYED_TRACE)) {
 		regs->sr &= ~0x8000;
diff --git a/arch/m68k/kernel/signal_no.c b/arch/m68k/kernel/signal_no.c
index 36a81bb..33e8bf5 100644
--- a/arch/m68k/kernel/signal_no.c
+++ b/arch/m68k/kernel/signal_no.c
@@ -60,12 +60,13 @@ void ret_from_user_rt_signal(void);
 asmlinkage int
 sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -343,10 +344,7 @@ asmlinkage int do_sigreturn(unsigned long __unused)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 	
 	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
 		goto badframe;
@@ -372,10 +370,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 	
 	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
 		goto badframe;
@@ -708,12 +703,7 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	if (err)
 		return;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 
 	clear_thread_flag(TIF_RESTORE_SIGMASK);
 }
diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds
index 8e66ccb..40e02d9 100644
--- a/arch/m68k/kernel/vmlinux-nommu.lds
+++ b/arch/m68k/kernel/vmlinux-nommu.lds
@@ -1,195 +1,93 @@
 /*
  *	vmlinux.lds.S -- master linker script for m68knommu arch
  *
- *	(C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>
+ *	(C) Copyright 2002-2012, Greg Ungerer <gerg@snapgear.com>
  *
  *	This linker script is equipped to build either ROM loaded or RAM
  *	run kernels.
  */
 
-#include <asm-generic/vmlinux.lds.h>
-#include <asm/page.h>
-#include <asm/thread_info.h>
-
 #if defined(CONFIG_RAMKERNEL)
-#define	RAM_START	CONFIG_KERNELBASE
-#define	RAM_LENGTH	(CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
-#define	TEXT		ram
-#define	DATA		ram
-#define	INIT		ram
-#define	BSSS		ram
-#endif
-#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
-#define	RAM_START	CONFIG_RAMBASE
-#define	RAM_LENGTH	CONFIG_RAMSIZE
-#define	ROMVEC_START	CONFIG_ROMVEC
-#define	ROMVEC_LENGTH	CONFIG_ROMVECSIZE
-#define	ROM_START	CONFIG_ROMSTART
-#define	ROM_LENGTH	CONFIG_ROMSIZE
-#define	TEXT		rom
-#define	DATA		ram
-#define	INIT		ram
-#define	BSSS		ram
+#define	KTEXT_ADDR	CONFIG_KERNELBASE
 #endif
-
-#ifndef DATA_ADDR
-#define	DATA_ADDR
+#if defined(CONFIG_ROMKERNEL)
+#define	KTEXT_ADDR	CONFIG_ROMSTART
+#define	KDATA_ADDR	CONFIG_KERNELBASE
+#define	LOAD_OFFSET	KDATA_ADDR + (ADDR(.text) + SIZEOF(.text))
 #endif
 
+#include <asm/page.h>
+#include <asm/thread_info.h>
+#include <asm-generic/vmlinux.lds.h>
 
 OUTPUT_ARCH(m68k)
 ENTRY(_start)
 
-MEMORY {
-	ram	: ORIGIN = RAM_START, LENGTH = RAM_LENGTH
-#ifdef ROM_START
-	romvec	: ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
-	rom	: ORIGIN = ROM_START, LENGTH = ROM_LENGTH
-#endif
-}
-
 jiffies = jiffies_64 + 4;
 
 SECTIONS {
 
-#ifdef ROMVEC_START
-	. = ROMVEC_START ;
+#ifdef CONFIG_ROMVEC
+	. = CONFIG_ROMVEC;
 	.romvec : {
-		__rom_start = . ;
+		__rom_start = .;
 		_romvec = .;
+		*(.romvec)
 		*(.data..initvect)
-	} > romvec
+	}
 #endif
 
+	. = KTEXT_ADDR;
+
+	_text = .;
+	_stext = .;
 	.text : {
-		_text = .;
-		_stext = . ;
 		HEAD_TEXT
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
-		*(.text..lock)
 		*(.fixup)
+		. = ALIGN(16);
+	}
+	_etext = .;
+
+#ifdef KDATA_ADDR
+	. = KDATA_ADDR;
+#endif
+
+	_sdata = .;
+	RO_DATA_SECTION(PAGE_SIZE)
+	RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
+	_edata = .;
 
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		*(.rodata) *(.rodata.*)
-		*(__vermagic)		/* Kernel version magic */
-		*(.rodata1)
-		*(.rodata.str1.1)
-
-		/* Kernel symbol table: Normal symbols */
-		. = ALIGN(4);
-		__start___ksymtab = .;
-		*(SORT(___ksymtab+*))
-		__stop___ksymtab = .;
-
-		/* Kernel symbol table: GPL-only symbols */
-		__start___ksymtab_gpl = .;
-		*(SORT(___ksymtab_gpl+*))
-		__stop___ksymtab_gpl = .;
-
-		/* Kernel symbol table: Normal unused symbols */
-		__start___ksymtab_unused = .;
-		*(SORT(___ksymtab_unused+*))
-		__stop___ksymtab_unused = .;
-
-		/* Kernel symbol table: GPL-only unused symbols */
-		__start___ksymtab_unused_gpl = .;
-		*(SORT(___ksymtab_unused_gpl+*))
-		__stop___ksymtab_unused_gpl = .;
-
-		/* Kernel symbol table: GPL-future symbols */
-		__start___ksymtab_gpl_future = .;
-		*(SORT(___ksymtab_gpl_future+*))
-		__stop___ksymtab_gpl_future = .;
-
-		/* Kernel symbol table: Normal symbols */
-		__start___kcrctab = .;
-		*(SORT(___kcrctab+*))
-		__stop___kcrctab = .;
-
-		/* Kernel symbol table: GPL-only symbols */
-		__start___kcrctab_gpl = .;
-		*(SORT(___kcrctab_gpl+*))
-		__stop___kcrctab_gpl = .;
-
-		/* Kernel symbol table: Normal unused symbols */
-		__start___kcrctab_unused = .;
-		*(SORT(___kcrctab_unused+*))
-		__stop___kcrctab_unused = .;
-
-		/* Kernel symbol table: GPL-only unused symbols */
-		__start___kcrctab_unused_gpl = .;
-		*(SORT(___kcrctab_unused_gpl+*))
-		__stop___kcrctab_unused_gpl = .;
-
-		/* Kernel symbol table: GPL-future symbols */
-		__start___kcrctab_gpl_future = .;
-		*(SORT(___kcrctab_gpl_future+*))
-		__stop___kcrctab_gpl_future = .;
-
-		/* Kernel symbol table: strings */
-		*(__ksymtab_strings)
-
-		/* Built-in module parameters */
-		. = ALIGN(4) ;
-		__start___param = .;
-		*(__param)
-		__stop___param = .;
-
-		/* Built-in module versions */
-		. = ALIGN(4) ;
-		__start___modver = .;
-		*(__modver)
-		__stop___modver = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > TEXT
-
-	.data DATA_ADDR : {
-		. = ALIGN(4);
-		_sdata = . ;
-		DATA_DATA
-		CACHELINE_ALIGNED_DATA(32)
-		PAGE_ALIGNED_DATA(PAGE_SIZE)
-		*(.data..shared_aligned)
-		INIT_TASK_DATA(THREAD_SIZE)
-		_edata = . ;
-	} > DATA
+	EXCEPTION_TABLE(16)
+	NOTES
 
+	. = ALIGN(PAGE_SIZE);
+	__init_begin = .;
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(16)
+	PERCPU_SECTION(16)
 	.m68k_fixup : {
 		__start_fixup = .;
 		*(.m68k_fixup)
 		__stop_fixup = .;
-	} > DATA
-	NOTES > DATA
-
-	.init.text : {
-		. = ALIGN(PAGE_SIZE);
-		__init_begin = .;
-	} > INIT
-	INIT_TEXT_SECTION(PAGE_SIZE) > INIT
-	INIT_DATA_SECTION(16) > INIT
+	}
 	.init.data : {
 		. = ALIGN(PAGE_SIZE);
 		__init_end = .;
-	} > INIT
-
-	.bss : {
-		. = ALIGN(4);
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-	 	_end = . ;
-	} > BSSS
+	}
+
+	_sbss = .;
+	BSS_SECTION(0, 0, 0)
+	_ebss = .;
+
+	_end = .;
+
+	STABS_DEBUG
+	.comment 0 : { *(.comment) }
 
+	/* Sections to be discarded */
 	DISCARDS
 }
 
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
index babd5a9..875b800 100644
--- a/arch/m68k/mm/mcfmmu.c
+++ b/arch/m68k/mm/mcfmmu.c
@@ -87,7 +87,7 @@ void __init paging_init(void)
 
 int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
 {
-	unsigned long flags, mmuar;
+	unsigned long flags, mmuar, mmutr;
 	struct mm_struct *mm;
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -137,9 +137,10 @@ int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
 	if (!pte_dirty(*pte) && !KMAPAREA(mmuar))
 		set_pte(pte, pte_wrprotect(*pte));
 
-	mmu_write(MMUTR, (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) |
-		(((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK)
-		>> CF_PAGE_MMUTR_SHIFT) | MMUTR_V);
+	mmutr = (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | MMUTR_V;
+	if ((mmuar < TASK_UNMAPPED_BASE) || (mmuar >= TASK_SIZE))
+		mmutr |= (pte->pte & CF_PAGE_MMUTR_MASK) >> CF_PAGE_MMUTR_SHIFT;
+	mmu_write(MMUTR, mmutr);
 
 	mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) |
 		((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X);
diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S
index 863889f..281e38c 100644
--- a/arch/m68k/platform/coldfire/entry.S
+++ b/arch/m68k/platform/coldfire/entry.S
@@ -136,7 +136,7 @@ Luser_return:
 	movel	%sp,%d1			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d1	/* at base of kernel stack */
 	movel	%d1,%a0
-	movel	%a0@(TINFO_FLAGS),%d1	/* get thread_info->flags */
+	moveb	%a0@(TINFO_FLAGS+3),%d1	/* thread_info->flags (low 8 bits) */
 	jne	Lwork_to_do		/* still work to do */
 
 Lreturn:
@@ -148,8 +148,6 @@ Lwork_to_do:
 	btst	#TIF_NEED_RESCHED,%d1
 	jne	reschedule
 
-	/* GERG: do we need something here for TRACEing?? */
-
 Lsignal_return:
 	subql	#4,%sp			/* dummy return address */
 	SAVE_SWITCH_STACK
diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
index 38f04a3..c3db70e 100644
--- a/arch/m68k/platform/coldfire/head.S
+++ b/arch/m68k/platform/coldfire/head.S
@@ -158,6 +158,10 @@ _start:
 #if defined(CONFIG_UBOOT)
 	movel	%sp,_init_sp			/* save initial stack pointer */
 #endif
+#ifdef CONFIG_MBAR
+	movel	#CONFIG_MBAR+1,%d0		/* configured MBAR address */
+	movec	%d0,%MBAR			/* set it */
+#endif
 
 	/*
 	 *	Do any platform or board specific setup now. Most boards
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index ad10fec..be93648 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -24,6 +24,7 @@
 #include <linux/rtc.h>
 #include <linux/vt_kern.h>
 #include <linux/bcd.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -329,3 +330,15 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll)
 	} else
 		return -EINVAL;
 }
+
+static __init int q40_add_kbd_device(void)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_simple("q40kbd", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+arch_initcall(q40_add_kbd_device);
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index c8d6efb..11060fa 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -14,6 +14,7 @@ config MICROBLAZE
 	select TRACING_SUPPORT
 	select OF
 	select OF_EARLY_FLATTREE
+	select IRQ_DOMAIN
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
index 3a3e5b8..0ee58d2 100644
--- a/arch/microblaze/include/asm/dma-mapping.h
+++ b/arch/microblaze/include/asm/dma-mapping.h
@@ -123,28 +123,34 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-					dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *memory;
 
 	BUG_ON(!ops);
 
-	memory = ops->alloc_coherent(dev, size, dma_handle, flag);
+	memory = ops->alloc(dev, size, dma_handle, flag, attrs);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
 	return memory;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	BUG_ON(!ops);
 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
-	ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	ops->free(dev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h
index cd1ac9a..fb3c05a 100644
--- a/arch/microblaze/include/asm/hardirq.h
+++ b/arch/microblaze/include/asm/hardirq.h
@@ -1,17 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * 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.
- */
-
-#ifndef _ASM_MICROBLAZE_HARDIRQ_H
-#define _ASM_MICROBLAZE_HARDIRQ_H
-
-/* should be defined in each interrupt controller driver */
-extern unsigned int get_irq(struct pt_regs *regs);
-
 #include <asm-generic/hardirq.h>
-
-#endif /* _ASM_MICROBLAZE_HARDIRQ_H */
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index a175132..bab3b13 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -9,49 +9,13 @@
 #ifndef _ASM_MICROBLAZE_IRQ_H
 #define _ASM_MICROBLAZE_IRQ_H
 
-
-/*
- * Linux IRQ# is currently offset by one to map to the hardware
- * irq number. So hardware IRQ0 maps to Linux irq 1.
- */
-#define NO_IRQ_OFFSET	1
-#define IRQ_OFFSET	NO_IRQ_OFFSET
-#define NR_IRQS		(32 + IRQ_OFFSET)
+#define NR_IRQS		(32 + 1)
 #include <asm-generic/irq.h>
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-extern unsigned int nr_irq;
-
 struct pt_regs;
 extern void do_IRQ(struct pt_regs *regs);
 
-/** FIXME - not implement
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-static inline void irq_dispose_mapping(unsigned int virq)
-{
-	return;
-}
-
-struct irq_host;
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
-					irq_hw_number_t hwirq);
+/* should be defined in each interrupt controller driver */
+extern unsigned int get_irq(void);
 
 #endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index 65a4af4..a2bfa2c 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -33,7 +33,8 @@ static unsigned long get_dma_direct_offset(struct device *dev)
 #define NOT_COHERENT_CACHE
 
 static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t flag)
+				       dma_addr_t *dma_handle, gfp_t flag,
+				       struct dma_attrs *attrs)
 {
 #ifdef NOT_COHERENT_CACHE
 	return consistent_alloc(flag, size, dma_handle);
@@ -57,7 +58,8 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void dma_direct_free_coherent(struct device *dev, size_t size,
-			      void *vaddr, dma_addr_t dma_handle)
+				     void *vaddr, dma_addr_t dma_handle,
+				     struct dma_attrs *attrs)
 {
 #ifdef NOT_COHERENT_CACHE
 	consistent_free(size, vaddr);
@@ -176,8 +178,8 @@ dma_direct_sync_sg_for_device(struct device *dev,
 }
 
 struct dma_map_ops dma_direct_ops = {
-	.alloc_coherent	= dma_direct_alloc_coherent,
-	.free_coherent	= dma_direct_free_coherent,
+	.alloc		= dma_direct_alloc_coherent,
+	.free		= dma_direct_free_coherent,
 	.map_sg		= dma_direct_map_sg,
 	.unmap_sg	= dma_direct_unmap_sg,
 	.dma_supported	= dma_direct_dma_supported,
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 44b177e..ad12067 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/irqdomain.h>
 #include <linux/irq.h>
 #include <asm/page.h>
 #include <linux/io.h>
@@ -25,8 +26,6 @@ static unsigned int intc_baseaddr;
 #define INTC_BASE	intc_baseaddr
 #endif
 
-unsigned int nr_irq;
-
 /* No one else should require these constants, so define them locally here. */
 #define ISR 0x00			/* Interrupt Status Register */
 #define IPR 0x04			/* Interrupt Pending Register */
@@ -84,24 +83,45 @@ static struct irq_chip intc_dev = {
 	.irq_mask_ack = intc_mask_ack,
 };
 
-unsigned int get_irq(struct pt_regs *regs)
+static struct irq_domain *root_domain;
+
+unsigned int get_irq(void)
 {
-	int irq;
+	unsigned int hwirq, irq = -1;
 
-	/*
-	 * NOTE: This function is the one that needs to be improved in
-	 * order to handle multiple interrupt controllers. It currently
-	 * is hardcoded to check for interrupts only on the first INTC.
-	 */
-	irq = in_be32(INTC_BASE + IVR) + NO_IRQ_OFFSET;
-	pr_debug("get_irq: %d\n", irq);
+	hwirq = in_be32(INTC_BASE + IVR);
+	if (hwirq != -1U)
+		irq = irq_find_mapping(root_domain, hwirq);
+
+	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
 
 	return irq;
 }
 
+int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+	u32 intr_mask = (u32)d->host_data;
+
+	if (intr_mask & (1 << hw)) {
+		irq_set_chip_and_handler_name(irq, &intc_dev,
+						handle_edge_irq, "edge");
+		irq_clear_status_flags(irq, IRQ_LEVEL);
+	} else {
+		irq_set_chip_and_handler_name(irq, &intc_dev,
+						handle_level_irq, "level");
+		irq_set_status_flags(irq, IRQ_LEVEL);
+	}
+	return 0;
+}
+
+static const struct irq_domain_ops xintc_irq_domain_ops = {
+	.xlate = irq_domain_xlate_onetwocell,
+	.map = xintc_map,
+};
+
 void __init init_IRQ(void)
 {
-	u32 i, intr_mask;
+	u32 nr_irq, intr_mask;
 	struct device_node *intc = NULL;
 #ifdef CONFIG_SELFMOD_INTC
 	unsigned int intc_baseaddr = 0;
@@ -146,16 +166,9 @@ void __init init_IRQ(void)
 	/* Turn on the Master Enable. */
 	out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
 
-	for (i = IRQ_OFFSET; i < (nr_irq + IRQ_OFFSET); ++i) {
-		if (intr_mask & (0x00000001 << (i - IRQ_OFFSET))) {
-			irq_set_chip_and_handler_name(i, &intc_dev,
-				handle_edge_irq, "edge");
-			irq_clear_status_flags(i, IRQ_LEVEL);
-		} else {
-			irq_set_chip_and_handler_name(i, &intc_dev,
-				handle_level_irq, "level");
-			irq_set_status_flags(i, IRQ_LEVEL);
-		}
-		irq_get_irq_data(i)->hwirq = i - IRQ_OFFSET;
-	}
+	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
+	 * lazy and Michal can clean it up to something nicer when he tests
+	 * and commits this patch.  ~~gcl */
+	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
+							(void *)intr_mask);
 }
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index bbebcae..ace700a 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -31,14 +31,13 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
 	trace_hardirqs_off();
 
 	irq_enter();
-	irq = get_irq(regs);
+	irq = get_irq();
 next_irq:
 	BUG_ON(!irq);
-	/* Substract 1 because of get_irq */
-	generic_handle_irq(irq + IRQ_OFFSET - NO_IRQ_OFFSET);
+	generic_handle_irq(irq);
 
-	irq = get_irq(regs);
-	if (irq) {
+	irq = get_irq();
+	if (irq != -1U) {
 		pr_debug("next irq: %d\n", irq);
 		++concurrent_irq;
 		goto next_irq;
@@ -48,18 +47,3 @@ next_irq:
 	set_irq_regs(old_regs);
 	trace_hardirqs_on();
 }
-
-/* MS: There is no any advance mapping mechanism. We are using simple 32bit
-  intc without any cascades or any connection that's why mapping is 1:1 */
-unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
-{
-	return hwirq + IRQ_OFFSET;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	return intspec[0] + IRQ_OFFSET;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index 604cd9d..70e6d0b 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -51,8 +51,6 @@ void __init setup_arch(char **cmdline_p)
 
 	unflatten_device_tree();
 
-	/* NOTE I think that this function is not necessary to call */
-	/* irq_early_init(); */
 	setup_cpuinfo();
 
 	microblaze_cache_init();
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 5996711..99b9708 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -105,10 +105,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
 		goto badframe;
@@ -169,7 +166,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 	return (void __user *)((sp - frame_size) & -8UL);
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			sigset_t *set, struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
@@ -267,12 +264,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 		current->comm, current->pid, frame, regs->pc);
 #endif
 
-	return;
+	return 0;
 
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
 /* Handle restarting system calls */
@@ -316,24 +312,20 @@ static int
 handle_signal(unsigned long sig, struct k_sigaction *ka,
 		siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
+	int ret;
+
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(sig, ka, info, oldset, regs);
 	else
-		setup_rt_frame(sig, ka, NULL, oldset, regs);
-
-	if (ka->sa.sa_flags & SA_ONESHOT)
-		ka->sa.sa_handler = SIG_DFL;
-
-	if (!(ka->sa.sa_flags & SA_NODEFER)) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked,
-				&current->blocked, &ka->sa.sa_mask);
-		sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
-	return 1;
+		ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
+
+	if (ret)
+		return ret;
+
+	block_sigmask(ka, sig);
+
+	return 0;
 }
 
 /*
@@ -374,7 +366,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
 		/* Whee! Actually deliver the signal. */
 		if (in_syscall)
 			handle_restart(regs, &ka, 1);
-		if (handle_signal(signr, &ka, &info, oldset, regs)) {
+		if (!handle_signal(signr, &ka, &info, oldset, regs)) {
 			/*
 			 * A signal was successfully delivered; the saved
 			 * sigmask will have been stored in the signal frame,
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5ab6e89..4bbbb40 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2456,6 +2456,7 @@ config MIPS32_COMPAT
 config COMPAT
 	bool
 	depends on MIPS32_COMPAT
+	select ARCH_WANT_OLD_COMPAT_IPC
 	default y
 
 config SYSVIPC_COMPAT
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
index 7da4d00..a7193ae 100644
--- a/arch/mips/alchemy/common/time.c
+++ b/arch/mips/alchemy/common/time.c
@@ -146,7 +146,7 @@ static int __init alchemy_time_init(unsigned int m2int)
 	cd->shift = 32;
 	cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
 	cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
-	cd->min_delta_ns = clockevent_delta2ns(8, cd);	/* ~0.25ms */
+	cd->min_delta_ns = clockevent_delta2ns(9, cd);	/* ~0.28ms */
 	clockevents_register_device(cd);
 	setup_irq(m2int, &au1x_rtcmatch2_irqaction);
 
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c
index 24f5469..e215070 100644
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -96,7 +96,7 @@ void __init ath79_register_wmac(u8 *cal_data)
 {
 	if (soc_is_ar913x())
 		ar913x_wmac_setup();
-	if (soc_is_ar933x())
+	else if (soc_is_ar933x())
 		ar933x_wmac_setup();
 	else
 		BUG();
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index d209f85..356b055 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -33,7 +33,7 @@ static void bcm6348_a1_reboot(void)
 	u32 reg;
 
 	/* soft reset all blocks */
-	printk(KERN_INFO "soft-reseting all blocks ...\n");
+	printk(KERN_INFO "soft-resetting all blocks ...\n");
 	reg = bcm_perf_readl(PERF_SOFTRESET_REG);
 	reg &= ~SOFTRESET_6348_ALL;
 	bcm_perf_writel(reg, PERF_SOFTRESET_REG);
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index b6bb92c..df70600 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -157,7 +157,7 @@ static void octeon_dma_sync_sg_for_device(struct device *dev,
 }
 
 static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t *dma_handle, gfp_t gfp)
+	dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
 	void *ret;
 
@@ -184,7 +184,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
 	/* Don't invoke OOM killer */
 	gfp |= __GFP_NORETRY;
 
-	ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+	ret = swiotlb_alloc_coherent(dev, size, dma_handle, gfp, attrs);
 
 	mb();
 
@@ -192,14 +192,14 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void octeon_dma_free_coherent(struct device *dev, size_t size,
-	void *vaddr, dma_addr_t dma_handle)
+	void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	int order = get_order(size);
 
 	if (dma_release_from_coherent(dev, order, vaddr))
 		return;
 
-	swiotlb_free_coherent(dev, size, vaddr, dma_handle);
+	swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs);
 }
 
 static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
@@ -240,8 +240,8 @@ EXPORT_SYMBOL(dma_to_phys);
 
 static struct octeon_dma_map_ops octeon_linear_dma_map_ops = {
 	.dma_map_ops = {
-		.alloc_coherent = octeon_dma_alloc_coherent,
-		.free_coherent = octeon_dma_free_coherent,
+		.alloc = octeon_dma_alloc_coherent,
+		.free = octeon_dma_free_coherent,
 		.map_page = octeon_dma_map_page,
 		.unmap_page = swiotlb_unmap_page,
 		.map_sg = octeon_dma_map_sg,
@@ -325,8 +325,8 @@ void __init plat_swiotlb_setup(void)
 #ifdef CONFIG_PCI
 static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = {
 	.dma_map_ops = {
-		.alloc_coherent = octeon_dma_alloc_coherent,
-		.free_coherent = octeon_dma_free_coherent,
+		.alloc = octeon_dma_alloc_coherent,
+		.free = octeon_dma_free_coherent,
 		.map_page = octeon_dma_map_page,
 		.unmap_page = swiotlb_unmap_page,
 		.map_sg = octeon_dma_map_sg,
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
index 4479fd6..28c6b27 100644
--- a/arch/mips/configs/nlm_xlp_defconfig
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -8,7 +8,7 @@ CONFIG_HIGH_RES_TIMERS=y
 # CONFIG_SECCOMP is not set
 CONFIG_USE_OF=y
 CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE="mips-linux-gnu-"
+CONFIG_CROSS_COMPILE=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -22,7 +22,7 @@ CONFIG_AUDIT=y
 CONFIG_CGROUPS=y
 CONFIG_NAMESPACES=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs.xlp"
+CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
 CONFIG_INITRAMFS_COMPRESSION_LZMA=y
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
index 7c68666..d0b857d 100644
--- a/arch/mips/configs/nlm_xlr_defconfig
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -8,7 +8,7 @@ CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT_VOLUNTARY=y
 CONFIG_KEXEC=y
 CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE="mips-linux-gnu-"
+CONFIG_CROSS_COMPILE=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -22,7 +22,7 @@ CONFIG_AUDIT=y
 CONFIG_NAMESPACES=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs.xlr"
+CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
 CONFIG_INITRAMFS_COMPRESSION_GZIP=y
diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig
index 3b0b6e8..7fda0ce 100644
--- a/arch/mips/configs/powertv_defconfig
+++ b/arch/mips/configs/powertv_defconfig
@@ -6,7 +6,7 @@ CONFIG_HZ_1000=y
 CONFIG_PREEMPT=y
 # CONFIG_SECCOMP is not set
 CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE="mips-linux-"
+CONFIG_CROSS_COMPILE=""
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=16
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
index 7aa37dd..be39a12 100644
--- a/arch/mips/include/asm/dma-mapping.h
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -57,25 +57,31 @@ dma_set_mask(struct device *dev, u64 mask)
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 	       enum dma_data_direction direction);
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t gfp)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t gfp,
+				    struct dma_attrs *attrs)
 {
 	void *ret;
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	ret = ops->alloc_coherent(dev, size, dma_handle, gfp);
+	ret = ops->alloc(dev, size, dma_handle, gfp, attrs);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, ret);
 
 	return ret;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
-	ops->free_coherent(dev, size, vaddr, dma_handle);
+	ops->free(dev, size, vaddr, dma_handle, attrs);
 
 	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
 }
diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h
index 77e6440..2d91888 100644
--- a/arch/mips/include/asm/highmem.h
+++ b/arch/mips/include/asm/highmem.h
@@ -47,7 +47,7 @@ extern void kunmap_high(struct page *page);
 
 extern void *kmap(struct page *page);
 extern void kunmap(struct page *page);
-extern void *__kmap_atomic(struct page *page);
+extern void *kmap_atomic(struct page *page);
 extern void __kunmap_atomic(void *kvaddr);
 extern void *kmap_atomic_pfn(unsigned long pfn);
 extern struct page *kmap_atomic_to_page(void *ptr);
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h
index 556e1be..fb9975c 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h
@@ -11,6 +11,9 @@
 #include <asm/io.h>
 #include <asm/mach-au1x00/au1000.h>
 
+struct gpio;
+struct gpio_chip;
+
 /* with the current GPIC design, up to 128 GPIOs are possible.
  * The only implementation so far is in the Au1300, which has 75 externally
  * available GPIOs.
@@ -203,7 +206,22 @@ static inline int gpio_request(unsigned int gpio, const char *label)
 	return 0;
 }
 
-static inline void gpio_free(unsigned int gpio)
+static inline int gpio_request_one(unsigned gpio,
+					unsigned long flags, const char *label)
+{
+	return 0;
+}
+
+static inline int gpio_request_array(struct gpio *array, size_t num)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
+static inline void gpio_free_array(struct gpio *array, size_t num)
 {
 }
 
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index d417909..da9bd7d 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -39,9 +39,6 @@
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
 #else /* !CONFIG_HUGETLB_PAGE */
-# ifndef BUILD_BUG
-#  define BUILD_BUG() do { extern void __build_bug(void); __build_bug(); } while (0)
-# endif
 #define HPAGE_SHIFT	({BUILD_BUG(); 0; })
 #define HPAGE_SIZE	({BUILD_BUG(); 0; })
 #define HPAGE_MASK	({BUILD_BUG(); 0; })
diff --git a/arch/mips/include/asm/posix_types.h b/arch/mips/include/asm/posix_types.h
index c200102..aa96dd1 100644
--- a/arch/mips/include/asm/posix_types.h
+++ b/arch/mips/include/asm/posix_types.h
@@ -17,128 +17,25 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-#if (_MIPS_SZLONG == 32)
-typedef unsigned long	__kernel_nlink_t;
-#endif
 #if (_MIPS_SZLONG == 64)
 typedef unsigned int	__kernel_nlink_t;
+#define __kernel_nlink_t __kernel_nlink_t
 #endif
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef int		__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-#if (_MIPS_SZLONG == 32)
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-#endif
-#if (_MIPS_SZLONG == 64)
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-#endif
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef long		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
 
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-typedef __kernel_uid_t	__kernel_old_uid_t;
-typedef __kernel_gid_t	__kernel_old_gid_t;
-typedef unsigned int	__kernel_old_dev_t;
+typedef long		__kernel_daddr_t;
+#define __kernel_daddr_t __kernel_daddr_t
 
 #ifdef __GNUC__
 typedef long long      __kernel_loff_t;
 #endif
 
-typedef struct {
 #if (_MIPS_SZLONG == 32)
+typedef struct {
 	long	val[2];
-#endif
-#if (_MIPS_SZLONG == 64)
-	int	val[2];
-#endif
 } __kernel_fsid_t;
+#define __kernel_fsid_t __kernel_fsid_t
+#endif
 
-#if defined(__KERNEL__)
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
-{
-	unsigned long *__tmp = __p->fds_bits;
-	int __i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		case 16:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			__tmp[ 8] = 0; __tmp[ 9] = 0;
-			__tmp[10] = 0; __tmp[11] = 0;
-			__tmp[12] = 0; __tmp[13] = 0;
-			__tmp[14] = 0; __tmp[15] = 0;
-			return;
-
-		case 8:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			return;
-
-		case 4:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			return;
-		}
-	}
-	__i = __FDSET_LONGS;
-	while (__i) {
-		__i--;
-		*__tmp = 0;
-		__tmp++;
-	}
-}
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif /* _ASM_POSIX_TYPES_H */
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index ad5c0a7..5210487 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -84,6 +84,7 @@ To add: #define SO_REUSEPORT 0x0200	/* Allow local address and port reuse.  */
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #ifdef __KERNEL__
 
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 639e3ce..9a91fe9 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -418,6 +418,11 @@ static struct platform_device qi_lb60_charger_device = {
 	},
 };
 
+/* audio */
+static struct platform_device qi_lb60_audio_device = {
+	.name = "qi-lb60-audio",
+	.id = -1,
+};
 
 static struct platform_device *jz_platform_devices[] __initdata = {
 	&jz4740_udc_device,
@@ -434,6 +439,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
 	&qi_lb60_gpio_keys,
 	&qi_lb60_pwm_beeper,
 	&qi_lb60_charger_device,
+	&qi_lb60_audio_device,
 };
 
 static void __init board_gpio_setup(void)
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index f852400..76084cc 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -256,11 +256,8 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sighand->siglock);
 	current->saved_sigmask = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -285,11 +282,8 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sighand->siglock);
 	current->saved_sigmask = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -361,10 +355,7 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
 		goto badframe;
 
 	sigdelsetmask(&blocked, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = blocked;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&blocked);
 
 	sig = restore_sigcontext(&regs, &frame->sf_sc);
 	if (sig < 0)
@@ -400,10 +391,7 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
 	if (sig < 0)
@@ -579,12 +567,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 	if (ret)
 		return ret;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index aae9866..902a889 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -290,11 +290,8 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sighand->siglock);
 	current->saved_sigmask = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -318,11 +315,8 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sighand->siglock);
 	current->saved_sigmask = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -488,10 +482,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 		goto badframe;
 
 	sigdelsetmask(&blocked, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = blocked;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&blocked);
 
 	sig = restore_sigcontext32(&regs, &frame->sf_sc);
 	if (sig < 0)
@@ -529,10 +520,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
 	if (sig < 0)
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c
index ee24d81..30fc7ff 100644
--- a/arch/mips/kernel/signal_n32.c
+++ b/arch/mips/kernel/signal_n32.c
@@ -94,11 +94,8 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 	sigset_from_compat(&newset, &uset);
 	sigdelsetmask(&newset, ~_BLOCKABLE);
 
-	spin_lock_irq(&current->sighand->siglock);
 	current->saved_sigmask = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -122,10 +119,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
 	if (sig < 0)
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 58fe71a..d5e950a 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -8,7 +8,6 @@
  * SMP support for BMIPS
  */
 
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cc4a3f1..d79ae54 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1135,7 +1135,7 @@ asmlinkage void do_mt(struct pt_regs *regs)
 		printk(KERN_DEBUG "YIELD Scheduler Exception\n");
 		break;
 	case 5:
-		printk(KERN_DEBUG "Gating Storage Schedulier Exception\n");
+		printk(KERN_DEBUG "Gating Storage Scheduler Exception\n");
 		break;
 	default:
 		printk(KERN_DEBUG "*** UNKNOWN THREAD EXCEPTION %d ***\n",
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index a81176f..924da5e 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -69,7 +69,6 @@ SECTIONS
 	RODATA
 
 	/* writeable */
-	_sdata = .;				/* Start of data section */
 	.data : {	/* Data */
 		. = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
 
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 4f9eb0b..c97087d 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -498,7 +498,7 @@ static inline void local_r4k_flush_cache_page(void *args)
 		if (map_coherent)
 			vaddr = kmap_coherent(page, addr);
 		else
-			vaddr = kmap_atomic(page, KM_USER0);
+			vaddr = kmap_atomic(page);
 		addr = (unsigned long)vaddr;
 	}
 
@@ -521,7 +521,7 @@ static inline void local_r4k_flush_cache_page(void *args)
 		if (map_coherent)
 			kunmap_coherent();
 		else
-			kunmap_atomic(vaddr, KM_USER0);
+			kunmap_atomic(vaddr);
 	}
 }
 
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4608491..3fab204 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -98,7 +98,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size,
 EXPORT_SYMBOL(dma_alloc_noncoherent);
 
 static void *mips_dma_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t * dma_handle, gfp_t gfp)
+	dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs)
 {
 	void *ret;
 
@@ -132,7 +132,7 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 EXPORT_SYMBOL(dma_free_noncoherent);
 
 static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-	dma_addr_t dma_handle)
+	dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	unsigned long addr = (unsigned long) vaddr;
 	int order = get_order(size);
@@ -323,8 +323,8 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 EXPORT_SYMBOL(dma_cache_sync);
 
 static struct dma_map_ops mips_default_dma_map_ops = {
-	.alloc_coherent = mips_dma_alloc_coherent,
-	.free_coherent = mips_dma_free_coherent,
+	.alloc = mips_dma_alloc_coherent,
+	.free = mips_dma_free_coherent,
 	.map_page = mips_dma_map_page,
 	.unmap_page = mips_dma_unmap_page,
 	.map_sg = mips_dma_map_sg,
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 937cf33..69ebd58 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -42,6 +42,8 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ
 	const int field = sizeof(unsigned long) * 2;
 	siginfo_t info;
 	int fault;
+	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+						 (write ? FAULT_FLAG_WRITE : 0);
 
 #if 0
 	printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
@@ -91,6 +93,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ
 	if (in_atomic() || !mm)
 		goto bad_area_nosemaphore;
 
+retry:
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, address);
 	if (!vma)
@@ -144,7 +147,11 @@ good_area:
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+	fault = handle_mm_fault(mm, vma, address, flags);
+
+	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+		return;
+
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
@@ -153,12 +160,27 @@ good_area:
 			goto do_sigbus;
 		BUG();
 	}
-	if (fault & VM_FAULT_MAJOR) {
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
-		tsk->maj_flt++;
-	} else {
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
-		tsk->min_flt++;
+	if (flags & FAULT_FLAG_ALLOW_RETRY) {
+		if (fault & VM_FAULT_MAJOR) {
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
+						  regs, address);
+			tsk->maj_flt++;
+		} else {
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
+						  regs, address);
+			tsk->min_flt++;
+		}
+		if (fault & VM_FAULT_RETRY) {
+			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+			/*
+			 * No need to up_read(&mm->mmap_sem) as we would
+			 * have already released it in __lock_page_or_retry
+			 * in mm/filemap.c.
+			 */
+
+			goto retry;
+		}
 	}
 
 	up_read(&mm->mmap_sem);
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 3634c7e..aff5705 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(kunmap);
  * kmaps are appropriate for short, tight code paths only.
  */
 
-void *__kmap_atomic(struct page *page)
+void *kmap_atomic(struct page *page)
 {
 	unsigned long vaddr;
 	int idx, type;
@@ -62,7 +62,7 @@ void *__kmap_atomic(struct page *page)
 
 	return (void*) vaddr;
 }
-EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic);
 
 void __kunmap_atomic(void *kvaddr)
 {
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 3b3ffd4..1a85ba9 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -207,21 +207,21 @@ void copy_user_highpage(struct page *to, struct page *from,
 {
 	void *vfrom, *vto;
 
-	vto = kmap_atomic(to, KM_USER1);
+	vto = kmap_atomic(to);
 	if (cpu_has_dc_aliases &&
 	    page_mapped(from) && !Page_dcache_dirty(from)) {
 		vfrom = kmap_coherent(from, vaddr);
 		copy_page(vto, vfrom);
 		kunmap_coherent();
 	} else {
-		vfrom = kmap_atomic(from, KM_USER0);
+		vfrom = kmap_atomic(from);
 		copy_page(vto, vfrom);
-		kunmap_atomic(vfrom, KM_USER0);
+		kunmap_atomic(vfrom);
 	}
 	if ((!cpu_has_ic_fills_f_dc) ||
 	    pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
 		flush_data_cache_page((unsigned long)vto);
-	kunmap_atomic(vto, KM_USER1);
+	kunmap_atomic(vto);
 	/* Make sure this page is cleared on other CPU's too before using it */
 	smp_wmb();
 }
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c
index 400535a..c682468 100644
--- a/arch/mips/pci/pci-bcm47xx.c
+++ b/arch/mips/pci/pci-bcm47xx.c
@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
 #include <bcm47xx.h>
 
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
@@ -32,15 +33,12 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 	return 0;
 }
 
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
 #ifdef CONFIG_BCM47XX_SSB
+static int bcm47xx_pcibios_plat_dev_init_ssb(struct pci_dev *dev)
+{
 	int res;
 	u8 slot, pin;
 
-	if (bcm47xx_bus_type !=  BCM47XX_BUS_TYPE_SSB)
-		return 0;
-
 	res = ssb_pcibios_plat_dev_init(dev);
 	if (res < 0) {
 		printk(KERN_ALERT "PCI: Failed to init device %s\n",
@@ -60,6 +58,47 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
 	}
 
 	dev->irq = res;
+	return 0;
+}
 #endif
+
+#ifdef CONFIG_BCM47XX_BCMA
+static int bcm47xx_pcibios_plat_dev_init_bcma(struct pci_dev *dev)
+{
+	int res;
+
+	res = bcma_core_pci_plat_dev_init(dev);
+	if (res < 0) {
+		printk(KERN_ALERT "PCI: Failed to init device %s\n",
+		       pci_name(dev));
+		return res;
+	}
+
+	res = bcma_core_pci_pcibios_map_irq(dev);
+
+	/* IRQ-0 and IRQ-1 are software interrupts. */
+	if (res < 2) {
+		printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
+		       pci_name(dev));
+		return res;
+	}
+
+	dev->irq = res;
 	return 0;
 }
+#endif
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+#ifdef CONFIG_BCM47XX_SSB
+	if (bcm47xx_bus_type ==  BCM47XX_BUS_TYPE_SSB)
+		return bcm47xx_pcibios_plat_dev_init_ssb(dev);
+	else
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	if  (bcm47xx_bus_type ==  BCM47XX_BUS_TYPE_BCMA)
+		return bcm47xx_pcibios_plat_dev_init_bcma(dev);
+	else
+#endif
+		return 0;
+}
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index aec2b11..1552150 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -279,7 +279,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
 	/* Propagate hose info into the subordinate devices.  */
 
-	struct list_head *ln;
 	struct pci_dev *dev = bus->self;
 
 	if (pci_probe_only && dev &&
@@ -288,9 +287,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 		pcibios_fixup_device_resources(dev, bus);
 	}
 
-	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-		dev = pci_dev_b(ln);
-
+	list_for_each_entry(dev, &bus->devices, bus_list) {
 		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 			pcibios_fixup_device_resources(dev, bus);
 	}
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
index 86b98e9..62ead66 100644
--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -35,16 +35,6 @@
  */
 void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct pci_bus *current_bus = bus;
-	struct pci_dev *devices;
-	struct list_head *devices_link;
-
-	list_for_each(devices_link, &(current_bus->devices)) {
-		devices = pci_dev_b(devices_link);
-		if (devices == NULL)
-			continue;
-	}
-
 	/*
 	 * PLX and SPKT related changes go here
 	 */
diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c
index 8e93b21..4642f56 100644
--- a/arch/mips/txx9/generic/7segled.c
+++ b/arch/mips/txx9/generic/7segled.c
@@ -102,7 +102,7 @@ static int __init tx_7segled_init_sysfs(void)
 			break;
 		}
 		dev->id = i;
-		dev->dev = &tx_7segled_subsys;
+		dev->bus = &tx_7segled_subsys;
 		error = device_register(dev);
 		if (!error) {
 			device_create_file(dev, &dev_attr_ascii);
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 8f1c40d..3aa3de0 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -5,6 +5,7 @@ config MN10300
 	select GENERIC_IRQ_SHOW
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_ARCH_KGDB
+	select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
 
 config AM33_2
 	def_bool n
diff --git a/arch/mn10300/include/asm/highmem.h b/arch/mn10300/include/asm/highmem.h
index bfe2d88..7c137cd 100644
--- a/arch/mn10300/include/asm/highmem.h
+++ b/arch/mn10300/include/asm/highmem.h
@@ -70,7 +70,7 @@ static inline void kunmap(struct page *page)
  * be used in IRQ contexts, so in some (very limited) cases we need
  * it.
  */
-static inline unsigned long __kmap_atomic(struct page *page)
+static inline unsigned long kmap_atomic(struct page *page)
 {
 	unsigned long vaddr;
 	int idx, type;
diff --git a/arch/mn10300/include/asm/posix_types.h b/arch/mn10300/include/asm/posix_types.h
index 56ffbc1..ab50618 100644
--- a/arch/mn10300/include/asm/posix_types.h
+++ b/arch/mn10300/include/asm/posix_types.h
@@ -17,14 +17,19 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short	__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
+#define __kernel_uid_t __kernel_uid_t
+
 #if __GNUC__ == 4
 typedef unsigned int	__kernel_size_t;
 typedef signed int	__kernel_ssize_t;
@@ -33,105 +38,11 @@ typedef unsigned long	__kernel_size_t;
 typedef signed long	__kernel_ssize_t;
 #endif
 typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
+#define __kernel_size_t __kernel_size_t
 
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
 typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
-	int	val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-	int	__val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
-
-#undef	__FD_SET
-static inline void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
-}
-
-#undef	__FD_CLR
-static inline void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
-}
-
-
-#undef	__FD_ISSET
-static inline int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef	__FD_ZERO
-static inline void __FD_ZERO(__kernel_fd_set *__p)
-{
-	unsigned long *__tmp = __p->fds_bits;
-	int __i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		case 16:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			__tmp[ 8] = 0; __tmp[ 9] = 0;
-			__tmp[10] = 0; __tmp[11] = 0;
-			__tmp[12] = 0; __tmp[13] = 0;
-			__tmp[14] = 0; __tmp[15] = 0;
-			return;
-
-		case 8:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			return;
-
-		case 4:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			return;
-		}
-	}
-	__i = __FDSET_LONGS;
-	while (__i) {
-		__i--;
-		*__tmp = 0;
-		__tmp++;
-	}
-}
-
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#include <asm-generic/posix_types.h>
 
 #endif /* _ASM_POSIX_TYPES_H */
diff --git a/arch/mn10300/include/asm/reset-regs.h b/arch/mn10300/include/asm/reset-regs.h
index 10c7502..8ca2a42 100644
--- a/arch/mn10300/include/asm/reset-regs.h
+++ b/arch/mn10300/include/asm/reset-regs.h
@@ -17,10 +17,6 @@
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_MN10300_WD_TIMER
-#define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
-#endif
-
 /*
  * watchdog timer registers
  */
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h
index 876356d..013fcc5 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/asm/socket.h
@@ -64,5 +64,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 690f4e9..bd77c6d 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -38,12 +38,13 @@
  */
 asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -172,10 +173,7 @@ asmlinkage long sys_sigreturn(void)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(current_frame(), &frame->sc, &d0))
 		goto badframe;
@@ -203,10 +201,7 @@ asmlinkage long sys_rt_sigreturn(void)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0))
 		goto badframe;
@@ -476,15 +471,8 @@ static int handle_signal(int sig,
 	else
 		ret = setup_frame(sig, ka, oldset, regs);
 
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
index 054537c..e612ce4 100644
--- a/arch/openrisc/include/asm/ptrace.h
+++ b/arch/openrisc/include/asm/ptrace.h
@@ -77,7 +77,6 @@ struct pt_regs {
 	long  syscallno;	/* Syscall number (used by strace) */
 	long dummy;		/* Cheap alignment fix */
 };
-#endif /* __ASSEMBLY__ */
 
 /* TODO: Rename this to REDZONE because that's what it is */
 #define STACK_FRAME_OVERHEAD  128  /* size of minimum stack frame */
@@ -87,6 +86,13 @@ struct pt_regs {
 #define user_stack_pointer(regs)	((unsigned long)(regs)->sp)
 #define profile_pc(regs)		instruction_pointer(regs)
 
+static inline long regs_return_value(struct pt_regs *regs)
+{
+	return regs->gpr[11];
+}
+
+#endif /* __ASSEMBLY__ */
+
 /*
  * Offsets used by 'ptrace' system call interface.
  */
diff --git a/arch/openrisc/include/asm/uaccess.h b/arch/openrisc/include/asm/uaccess.h
index c310e45..f5abaa0 100644
--- a/arch/openrisc/include/asm/uaccess.h
+++ b/arch/openrisc/include/asm/uaccess.h
@@ -26,7 +26,6 @@
 #include <linux/thread_info.h>
 #include <linux/prefetch.h>
 #include <linux/string.h>
-#include <linux/thread_info.h>
 #include <asm/page.h>
 
 #define VERIFY_READ	0
diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
index c75018d..1088b5f 100644
--- a/arch/openrisc/kernel/head.S
+++ b/arch/openrisc/kernel/head.S
@@ -26,6 +26,7 @@
 #include <asm/cache.h>
 #include <asm/spr_defs.h>
 #include <asm/asm-offsets.h>
+#include <linux/of_fdt.h>
 
 #define tophys(rd,rs)				\
 	l.movhi	rd,hi(-KERNELBASE)		;\
@@ -440,6 +441,9 @@ _dispatch_do_ipage_fault:
 	__HEAD
 	.global _start
 _start:
+	/* save kernel parameters */
+	l.or	r25,r0,r3	/* pointer to fdt */
+
 	/*
 	 * ensure a deterministic start
 	 */
@@ -471,7 +475,6 @@ _start:
 	CLEAR_GPR(r22)
 	CLEAR_GPR(r23)
 	CLEAR_GPR(r24)
-	CLEAR_GPR(r25)
 	CLEAR_GPR(r26)
 	CLEAR_GPR(r27)
 	CLEAR_GPR(r28)
@@ -565,6 +568,18 @@ enable_mmu:
 	// reset the simulation counters
 	l.nop 5
 
+	/* check fdt header magic word */
+	l.lwz	r3,0(r25)	/* load magic from fdt into r3 */
+	l.movhi	r4,hi(OF_DT_HEADER)
+	l.ori	r4,r4,lo(OF_DT_HEADER)
+	l.sfeq	r3,r4
+	l.bf	_fdt_found
+	 l.nop
+	/* magic number mismatch, set fdt pointer to null */
+	l.or	r25,r0,r0
+_fdt_found:
+	/* pass fdt pointer to or32_early_setup in r3 */
+	l.or	r3,r0,r25
 	LOAD_SYMBOL_2_GPR(r24, or32_early_setup)
 	l.jalr r24
 	 l.nop
diff --git a/arch/openrisc/kernel/init_task.c b/arch/openrisc/kernel/init_task.c
index 45744a38..ca53408 100644
--- a/arch/openrisc/kernel/init_task.c
+++ b/arch/openrisc/kernel/init_task.c
@@ -17,6 +17,7 @@
 
 #include <linux/init_task.h>
 #include <linux/mqueue.h>
+#include <linux/export.h>
 
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
 static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c
index 59b3023..4bfead2 100644
--- a/arch/openrisc/kernel/irq.c
+++ b/arch/openrisc/kernel/irq.c
@@ -23,6 +23,7 @@
 #include <linux/irq.h>
 #include <linux/seq_file.h>
 #include <linux/kernel_stat.h>
+#include <linux/export.h>
 
 #include <linux/irqflags.h>
 
diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c
index 656b94b..7259047 100644
--- a/arch/openrisc/kernel/ptrace.c
+++ b/arch/openrisc/kernel/ptrace.c
@@ -188,11 +188,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 		 */
 		ret = -1L;
 
-	/* Are these regs right??? */
-	if (unlikely(current->audit_context))
-		audit_syscall_entry(audit_arch(), regs->syscallno,
-				    regs->gpr[3], regs->gpr[4],
-				    regs->gpr[5], regs->gpr[6]);
+	audit_syscall_entry(audit_arch(), regs->syscallno,
+			    regs->gpr[3], regs->gpr[4],
+			    regs->gpr[5], regs->gpr[6]);
 
 	return ret ? : regs->syscallno;
 }
@@ -201,9 +199,7 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
 {
 	int step;
 
-	if (unlikely(current->audit_context))
-		audit_syscall_exit(AUDITSC_RESULT(regs->gpr[11]),
-				   regs->gpr[11]);
+	audit_syscall_exit(regs);
 
 	step = test_thread_flag(TIF_SINGLESTEP);
 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
diff --git a/arch/openrisc/kernel/setup.c b/arch/openrisc/kernel/setup.c
index 1422f74..bf5eba2 100644
--- a/arch/openrisc/kernel/setup.c
+++ b/arch/openrisc/kernel/setup.c
@@ -207,18 +207,18 @@ void __init setup_cpuinfo(void)
  * Handles the pointer to the device tree that this kernel is to use
  * for establishing the available platform devices.
  *
- * For now, this is limited to using the built-in device tree.  In the future,
- * it is intended that this function will take a pointer to the device tree
- * that is potentially built-in, but potentially also passed in by the
- * bootloader, or discovered by some equally clever means...
+ * Falls back on built-in device tree in case null pointer is passed.
  */
 
-void __init or32_early_setup(void)
+void __init or32_early_setup(unsigned int fdt)
 {
-
-	early_init_devtree(__dtb_start);
-
-	printk(KERN_INFO "Compiled-in FDT at 0x%p\n", __dtb_start);
+	if (fdt) {
+		early_init_devtree((void*) fdt);
+		printk(KERN_INFO "FDT at 0x%08x\n", fdt);
+	} else {
+		early_init_devtree(__dtb_start);
+		printk(KERN_INFO "Compiled-in FDT at %p\n", __dtb_start);
+	}
 }
 
 static int __init openrisc_device_probe(void)
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 95207ab..cf35ea0 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -102,10 +102,7 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -189,8 +186,8 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
  * trampoline which performs the syscall sigreturn, or a provided
  * user-mode trampoline.
  */
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			  sigset_t *set, struct pt_regs *regs)
 {
 	struct rt_sigframe *frame;
 	unsigned long return_ip;
@@ -247,31 +244,27 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	/* actually move the usp to reflect the stacked frame */
 	regs->sp = (unsigned long)frame;
 
-	return;
+	return 0;
 
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
-static inline void
+static inline int
 handle_signal(unsigned long sig,
 	      siginfo_t *info, struct k_sigaction *ka,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
-	setup_rt_frame(sig, ka, info, oldset, regs);
+	int ret;
 
-	if (ka->sa.sa_flags & SA_ONESHOT)
-		ka->sa.sa_handler = SIG_DFL;
+	ret = setup_rt_frame(sig, ka, info, oldset, regs);
+	if (ret)
+		return ret;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
+	block_sigmask(ka, sig);
 
-	spin_unlock_irq(&current->sighand->siglock);
+	return 0;
 }
 
 /*
@@ -360,13 +353,13 @@ void do_signal(struct pt_regs *regs)
 			oldset = &current->blocked;
 
 		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, &info, &ka, oldset, regs);
-		/* 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))
+		if (!handle_signal(signr, &info, &ka, oldset, regs)) {
+			/* a signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag */
 			clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
 
 		tracehook_signal_handler(signr, &info, &ka, regs,
 					 test_thread_flag(TIF_SINGLESTEP));
diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c
index bd946ef..7c52e94 100644
--- a/arch/openrisc/kernel/time.c
+++ b/arch/openrisc/kernel/time.c
@@ -125,16 +125,13 @@ irqreturn_t __irq_entry timer_interrupt(struct pt_regs *regs)
 
 static __init void openrisc_clockevent_init(void)
 {
-	clockevents_calc_mult_shift(&clockevent_openrisc_timer,
-				    cpuinfo.clock_frequency, 4);
+	clockevent_openrisc_timer.cpumask = cpumask_of(0);
 
 	/* We only have 28 bits */
-	clockevent_openrisc_timer.max_delta_ns =
-	    clockevent_delta2ns((u32) 0x0fffffff, &clockevent_openrisc_timer);
-	clockevent_openrisc_timer.min_delta_ns =
-	    clockevent_delta2ns(1, &clockevent_openrisc_timer);
-	clockevent_openrisc_timer.cpumask = cpumask_of(0);
-	clockevents_register_device(&clockevent_openrisc_timer);
+	clockevents_config_and_register(&clockevent_openrisc_timer,
+					cpuinfo.clock_frequency,
+					100, 0x0fffffff);
+
 }
 
 /**
diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c
index 359dcb2..736f6b2 100644
--- a/arch/openrisc/mm/init.c
+++ b/arch/openrisc/mm/init.c
@@ -222,8 +222,7 @@ void __init mem_init(void)
 {
 	int codesize, reservedpages, datasize, initsize;
 
-	if (!mem_map)
-		BUG();
+	BUG_ON(!mem_map);
 
 	set_max_mapnr_init();
 
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index da601dd..9f21ab0 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -140,7 +140,7 @@ static inline void *kmap(struct page *page)
 
 #define kunmap(page)			kunmap_parisc(page_address(page))
 
-static inline void *__kmap_atomic(struct page *page)
+static inline void *kmap_atomic(struct page *page)
 {
 	pagefault_disable();
 	return page_address(page);
diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h
index 2388bdb..49df148 100644
--- a/arch/parisc/include/asm/futex.h
+++ b/arch/parisc/include/asm/futex.h
@@ -8,6 +8,29 @@
 #include <asm/atomic.h>
 #include <asm/errno.h>
 
+/* The following has to match the LWS code in syscall.S.  We have
+   sixteen four-word locks. */
+
+static inline void
+_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags)
+{
+	extern u32 lws_lock_start[];
+	long index = ((long)uaddr & 0xf0) >> 2;
+	arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
+	local_irq_save(*flags);
+	arch_spin_lock(s);
+}
+
+static inline void
+_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
+{
+	extern u32 lws_lock_start[];
+	long index = ((long)uaddr & 0xf0) >> 2;
+	arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
+	arch_spin_unlock(s);
+	local_irq_restore(*flags);
+}
+
 static inline int
 futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
 {
@@ -26,7 +49,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
 
 	pagefault_disable();
 
-	_atomic_spin_lock_irqsave(uaddr, flags);
+	_futex_spin_lock_irqsave(uaddr, &flags);
 
 	switch (op) {
 	case FUTEX_OP_SET:
@@ -71,7 +94,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
 		ret = -ENOSYS;
 	}
 
-	_atomic_spin_unlock_irqrestore(uaddr, flags);
+	_futex_spin_unlock_irqrestore(uaddr, &flags);
 
 	pagefault_enable();
 
@@ -113,7 +136,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	 * address. This should scale to a couple of CPUs.
 	 */
 
-	_atomic_spin_lock_irqsave(uaddr, flags);
+	_futex_spin_lock_irqsave(uaddr, &flags);
 
 	ret = get_user(val, uaddr);
 
@@ -122,7 +145,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 
 	*uval = val;
 
-	_atomic_spin_unlock_irqrestore(uaddr, flags);
+	_futex_spin_unlock_irqrestore(uaddr, &flags);
 
 	return ret;
 }
diff --git a/arch/parisc/include/asm/posix_types.h b/arch/parisc/include/asm/posix_types.h
index 00da29a..5212b03 100644
--- a/arch/parisc/include/asm/posix_types.h
+++ b/arch/parisc/include/asm/posix_types.h
@@ -6,123 +6,22 @@
  * be a little careful about namespace pollution etc.  Also, we cannot
  * assume GCC is being used.
  */
-typedef unsigned long		__kernel_ino_t;
+
 typedef unsigned short		__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short		__kernel_nlink_t;
-typedef long			__kernel_off_t;
-typedef int			__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short		__kernel_ipc_pid_t;
-typedef unsigned int		__kernel_uid_t;
-typedef unsigned int		__kernel_gid_t;
-typedef int			__kernel_suseconds_t;
-typedef long			__kernel_clock_t;
-typedef int			__kernel_timer_t;
-typedef int			__kernel_clockid_t;
-typedef int			__kernel_daddr_t;
-/* Note these change from narrow to wide kernels */
-#ifdef CONFIG_64BIT
-typedef unsigned long		__kernel_size_t;
-typedef long			__kernel_ssize_t;
-typedef long			__kernel_ptrdiff_t;
-#else
-typedef unsigned int		__kernel_size_t;
-typedef int			__kernel_ssize_t;
-typedef int			__kernel_ptrdiff_t;
-#endif
-typedef long			__kernel_time_t;
-typedef char *			__kernel_caddr_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
 
-typedef unsigned short		__kernel_uid16_t;
-typedef unsigned short		__kernel_gid16_t;
-typedef unsigned int		__kernel_uid32_t;
-typedef unsigned int		__kernel_gid32_t;
+typedef int			__kernel_suseconds_t;
+#define __kernel_suseconds_t __kernel_suseconds_t
 
-#ifdef __GNUC__
-typedef long long		__kernel_loff_t;
 typedef long long		__kernel_off64_t;
 typedef unsigned long long	__kernel_ino64_t;
-#endif
-
-typedef unsigned int		__kernel_old_dev_t;
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-/* compatibility stuff */
-typedef __kernel_uid_t __kernel_old_uid_t;
-typedef __kernel_gid_t __kernel_old_gid_t;
-
-#if defined(__KERNEL__)
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
-{
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	__fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
-{ 
-	unsigned long __tmp = __fd / __NFDBITS;
-	unsigned long __rem = __fd % __NFDBITS;
-	return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
-{
-	unsigned long *__tmp = __p->fds_bits;
-	int __i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		case 16:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			__tmp[ 8] = 0; __tmp[ 9] = 0;
-			__tmp[10] = 0; __tmp[11] = 0;
-			__tmp[12] = 0; __tmp[13] = 0;
-			__tmp[14] = 0; __tmp[15] = 0;
-			return;
-
-		case 8:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			__tmp[ 4] = 0; __tmp[ 5] = 0;
-			__tmp[ 6] = 0; __tmp[ 7] = 0;
-			return;
-
-		case 4:
-			__tmp[ 0] = 0; __tmp[ 1] = 0;
-			__tmp[ 2] = 0; __tmp[ 3] = 0;
-			return;
-		}
-	}
-	__i = __FDSET_LONGS;
-	while (__i) {
-		__i--;
-		*__tmp = 0;
-		__tmp++;
-	}
-}
 
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index d28c51b..f717c9b 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -63,6 +63,7 @@
 
 #define SO_WIFI_STATUS		0x4022
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		0x4023
 
 /* O_NONBLOCK clashes with the bits used for socket types.  Therefore we
  * have to define SOCK_NONBLOCK to a different value here.
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 12c1ed3..bd36152 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -131,10 +131,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	}
 		
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	/* Good thing we saved the old gr[30], eh? */
 #ifdef CONFIG_64BIT
@@ -454,12 +451,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
 		return 0;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked,sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	block_sigmask(ka, sig);
 
 	tracehook_signal_handler(sig, info, ka, regs, 
 		test_thread_flag(TIF_SINGLESTEP) ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1919634..75f061e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -133,8 +133,9 @@ config PPC
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
 	select HAVE_GENERIC_HARDIRQS
-	select HAVE_SPARSE_IRQ
+	select MAY_HAVE_SPARSE_IRQ
 	select IRQ_PER_CPU
+	select IRQ_DOMAIN
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
 	select IRQ_FORCED_THREADING
@@ -152,6 +153,7 @@ config COMPAT
 	bool
 	default y if PPC64
 	select COMPAT_BINFMT_ELF
+	select ARCH_WANT_OLD_COMPAT_IPC
 
 config SYSVIPC_COMPAT
 	bool
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index dd70fac..62678e3 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -22,9 +22,11 @@
 
 /* Some dma direct funcs must be visible for use in other dma_ops */
 extern void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag);
+				       dma_addr_t *dma_handle, gfp_t flag,
+				       struct dma_attrs *attrs);
 extern void dma_direct_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle);
+				     void *vaddr, dma_addr_t dma_handle,
+				     struct dma_attrs *attrs);
 
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
@@ -130,23 +132,29 @@ static inline int dma_supported(struct device *dev, u64 mask)
 
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 	void *cpu_addr;
 
 	BUG_ON(!dma_ops);
 
-	cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+	cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs);
 
 	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
 
 	return cpu_addr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
@@ -154,7 +162,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 
 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
 
-	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	dma_ops->free(dev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/powerpc/include/asm/ehv_pic.h b/arch/powerpc/include/asm/ehv_pic.h
index a9e1f4f..dc7d48e 100644
--- a/arch/powerpc/include/asm/ehv_pic.h
+++ b/arch/powerpc/include/asm/ehv_pic.h
@@ -25,7 +25,7 @@
 
 struct ehv_pic {
 	/* The remapper for this EHV_PIC */
-	struct irq_host	*irqhost;
+	struct irq_domain	*irqhost;
 
 	/* The "linux" controller struct */
 	struct irq_chip	hc_irq;
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h
index dbc2640..caaf6e0 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -79,7 +79,7 @@ static inline void kunmap(struct page *page)
 	kunmap_high(page);
 }
 
-static inline void *__kmap_atomic(struct page *page)
+static inline void *kmap_atomic(struct page *page)
 {
 	return kmap_atomic_prot(page, kmap_prot);
 }
diff --git a/arch/powerpc/include/asm/i8259.h b/arch/powerpc/include/asm/i8259.h
index 105ade2..c3fdfbd 100644
--- a/arch/powerpc/include/asm/i8259.h
+++ b/arch/powerpc/include/asm/i8259.h
@@ -6,7 +6,7 @@
 
 extern void i8259_init(struct device_node *node, unsigned long intack_addr);
 extern unsigned int i8259_irq(void);
-extern struct irq_host *i8259_get_host(void);
+extern struct irq_domain *i8259_get_host(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_I8259_H */
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index c0e1bc3..fe0b09d 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/irqdomain.h>
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
@@ -35,258 +36,12 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Total number of virq in the platform */
 #define NR_IRQS		CONFIG_NR_IRQS
 
-/* Number of irqs reserved for the legacy controller */
-#define NUM_ISA_INTERRUPTS	16
-
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
 
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-struct irq_host;
-struct radix_tree_root;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
-	/* Match an interrupt controller device node to a host, returns
-	 * 1 on a match
-	 */
-	int (*match)(struct irq_host *h, struct device_node *node);
-
-	/* Create or update a mapping between a virtual irq number and a hw
-	 * irq number. This is called only once for a given mapping.
-	 */
-	int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
-	/* Dispose of such a mapping */
-	void (*unmap)(struct irq_host *h, unsigned int virq);
-
-	/* Translate device-tree interrupt specifier from raw format coming
-	 * from the firmware to a irq_hw_number_t (interrupt line number) and
-	 * type (sense) that can be passed to set_irq_type(). In the absence
-	 * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
-	 * will return the hw number in the first cell and IRQ_TYPE_NONE for
-	 * the type (which amount to keeping whatever default value the
-	 * interrupt controller has for that line)
-	 */
-	int (*xlate)(struct irq_host *h, struct device_node *ctrler,
-		     const u32 *intspec, unsigned int intsize,
-		     irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
-	struct list_head	link;
-
-	/* type of reverse mapping technique */
-	unsigned int		revmap_type;
-#define IRQ_HOST_MAP_LEGACY     0 /* legacy 8259, gets irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP	1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR	2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE	3 /* radix tree */
-	union {
-		struct {
-			unsigned int size;
-			unsigned int *revmap;
-		} linear;
-		struct radix_tree_root tree;
-	} revmap_data;
-	struct irq_host_ops	*ops;
-	void			*host_data;
-	irq_hw_number_t		inval_irq;
-
-	/* Optional device node pointer */
-	struct device_node	*of_node;
-};
-
 struct irq_data;
 extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-
-/**
- * irq_alloc_host - Allocate a new irq_host data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
-				       unsigned int revmap_type,
-				       unsigned int revmap_arg,
-				       struct irq_host_ops *ops,
-				       irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_host *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_host *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
-				       irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_host *host,
-				     irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
-				    irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
-					    irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_host *host,
-				      irq_hw_number_t hwirq);
-
-
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
-				   unsigned int count,
-				   unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
 
 /**
  * irq_early_init - Init irq remapping subsystem
diff --git a/arch/powerpc/include/asm/keylargo.h b/arch/powerpc/include/asm/keylargo.h
index fc195d0..2156315 100644
--- a/arch/powerpc/include/asm/keylargo.h
+++ b/arch/powerpc/include/asm/keylargo.h
@@ -21,7 +21,7 @@
 #define KEYLARGO_FCR4		0x48
 #define KEYLARGO_FCR5		0x4c	/* Pangea only */
 
-/* K2 aditional FCRs */
+/* K2 additional FCRs */
 #define K2_FCR6			0x34
 #define K2_FCR7			0x30
 #define K2_FCR8			0x2c
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 67b4d98..a5b7c56 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -255,7 +255,7 @@ struct mpic
 	struct device_node *node;
 
 	/* The remapper for this MPIC */
-	struct irq_host		*irqhost;
+	struct irq_domain	*irqhost;
 
 	/* The "linux" controller struct */
 	struct irq_chip		hc_irq;
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index 8f1df12..1a8093f 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -61,8 +61,6 @@ struct pt_regs;
 extern unsigned long perf_misc_flags(struct pt_regs *regs);
 extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
 
-#define PERF_EVENT_INDEX_OFFSET	1
-
 /*
  * Only override the default definitions in include/linux/perf_event.h
  * if we have hardware PMU support.
diff --git a/arch/powerpc/include/asm/posix_types.h b/arch/powerpc/include/asm/posix_types.h
index c4e396b..f139325 100644
--- a/arch/powerpc/include/asm/posix_types.h
+++ b/arch/powerpc/include/asm/posix_types.h
@@ -7,122 +7,22 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-typedef long		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef long		__kernel_suseconds_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-typedef unsigned int	__kernel_old_uid_t;
-typedef unsigned int	__kernel_old_gid_t;
-
 #ifdef __powerpc64__
-typedef unsigned long  	__kernel_nlink_t;
-typedef int             __kernel_ipc_pid_t;
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
 typedef unsigned long	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 #else
-typedef unsigned short	__kernel_nlink_t;
-typedef short		__kernel_ipc_pid_t;
 typedef unsigned int	__kernel_size_t;
 typedef int		__kernel_ssize_t;
-typedef unsigned int	__kernel_old_dev_t;
-#endif
-
-#ifdef __powerpc64__
-typedef long long	__kernel_loff_t;
-#else
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#ifndef __GNUC__
-
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define	__FD_ISSET(d, set)	(((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
-#define	__FD_ZERO(set)	\
-  ((void) memset ((void *) (set), 0, sizeof (__kernel_fd_set)))
-
-#else /* __GNUC__ */
-
-#if defined(__KERNEL__)
-/* With GNU C, use inline functions instead so args are evaluated only once: */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
-{ 
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned long *tmp = (unsigned long *)p->fds_bits;
-	int i;
+typedef long		__kernel_ptrdiff_t;
+#define __kernel_size_t __kernel_size_t
 
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		      case 16:
-			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+typedef unsigned short	__kernel_nlink_t;
+#define __kernel_nlink_t __kernel_nlink_t
 
-		      case 8:
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+typedef short		__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+#endif
 
-		      case 4:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
+#include <asm-generic/posix_types.h>
 
-#endif /* defined(__KERNEL__) */
-#endif /* __GNUC__ */
 #endif /* _ASM_POWERPC_POSIX_TYPES_H */
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index 2fc2af8..fe1c0b4 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -71,5 +71,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif	/* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index c48de98..4ae9a09 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -86,7 +86,7 @@ struct ics {
 extern unsigned int xics_default_server;
 extern unsigned int xics_default_distrib_server;
 extern unsigned int xics_interrupt_server_size;
-extern struct irq_host *xics_host;
+extern struct irq_domain *xics_host;
 
 struct xics_cppr {
 	unsigned char stack[MAX_NUM_PRIORITIES];
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 3f6464b..bcfdcd2 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -17,7 +17,8 @@
  * to the dma address (mapping) of the first page.
  */
 static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
-				      dma_addr_t *dma_handle, gfp_t flag)
+				      dma_addr_t *dma_handle, gfp_t flag,
+				      struct dma_attrs *attrs)
 {
 	return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
 				    dma_handle, dev->coherent_dma_mask, flag,
@@ -25,7 +26,8 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void dma_iommu_free_coherent(struct device *dev, size_t size,
-				    void *vaddr, dma_addr_t dma_handle)
+				    void *vaddr, dma_addr_t dma_handle,
+				    struct dma_attrs *attrs)
 {
 	iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle);
 }
@@ -105,8 +107,8 @@ static u64 dma_iommu_get_required_mask(struct device *dev)
 }
 
 struct dma_map_ops dma_iommu_ops = {
-	.alloc_coherent		= dma_iommu_alloc_coherent,
-	.free_coherent		= dma_iommu_free_coherent,
+	.alloc			= dma_iommu_alloc_coherent,
+	.free			= dma_iommu_free_coherent,
 	.map_sg			= dma_iommu_map_sg,
 	.unmap_sg		= dma_iommu_unmap_sg,
 	.dma_supported		= dma_iommu_dma_supported,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index 1ebc918..4ab88da 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -47,8 +47,8 @@ static u64 swiotlb_powerpc_get_required(struct device *dev)
  * for everything else.
  */
 struct dma_map_ops swiotlb_dma_ops = {
-	.alloc_coherent = dma_direct_alloc_coherent,
-	.free_coherent = dma_direct_free_coherent,
+	.alloc = dma_direct_alloc_coherent,
+	.free = dma_direct_free_coherent,
 	.map_sg = swiotlb_map_sg_attrs,
 	.unmap_sg = swiotlb_unmap_sg_attrs,
 	.dma_supported = swiotlb_dma_supported,
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 7d0233c..b1ec983 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -26,7 +26,8 @@
 
 
 void *dma_direct_alloc_coherent(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t flag)
+				dma_addr_t *dma_handle, gfp_t flag,
+				struct dma_attrs *attrs)
 {
 	void *ret;
 #ifdef CONFIG_NOT_COHERENT_CACHE
@@ -54,7 +55,8 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size,
 }
 
 void dma_direct_free_coherent(struct device *dev, size_t size,
-			      void *vaddr, dma_addr_t dma_handle)
+			      void *vaddr, dma_addr_t dma_handle,
+			      struct dma_attrs *attrs)
 {
 #ifdef CONFIG_NOT_COHERENT_CACHE
 	__dma_free_coherent(size, vaddr);
@@ -150,8 +152,8 @@ static inline void dma_direct_sync_single(struct device *dev,
 #endif
 
 struct dma_map_ops dma_direct_ops = {
-	.alloc_coherent			= dma_direct_alloc_coherent,
-	.free_coherent			= dma_direct_free_coherent,
+	.alloc				= dma_direct_alloc_coherent,
+	.free				= dma_direct_free_coherent,
 	.map_sg				= dma_direct_map_sg,
 	.unmap_sg			= dma_direct_unmap_sg,
 	.dma_supported			= dma_direct_dma_supported,
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index d39ae60..b01d14e 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -65,7 +65,8 @@ static struct of_device_id __initdata ibmebus_matches[] = {
 static void *ibmebus_alloc_coherent(struct device *dev,
 				    size_t size,
 				    dma_addr_t *dma_handle,
-				    gfp_t flag)
+				    gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	void *mem;
 
@@ -77,7 +78,8 @@ static void *ibmebus_alloc_coherent(struct device *dev,
 
 static void ibmebus_free_coherent(struct device *dev,
 				  size_t size, void *vaddr,
-				  dma_addr_t dma_handle)
+				  dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	kfree(vaddr);
 }
@@ -136,8 +138,8 @@ static u64 ibmebus_dma_get_required_mask(struct device *dev)
 }
 
 static struct dma_map_ops ibmebus_dma_ops = {
-	.alloc_coherent     = ibmebus_alloc_coherent,
-	.free_coherent      = ibmebus_free_coherent,
+	.alloc              = ibmebus_alloc_coherent,
+	.free               = ibmebus_free_coherent,
 	.map_sg             = ibmebus_map_sg,
 	.unmap_sg           = ibmebus_unmap_sg,
 	.dma_supported      = ibmebus_dma_supported,
@@ -713,7 +715,7 @@ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = {
 
 struct bus_type ibmebus_bus_type = {
 	.name      = "ibmebus",
-	.uevent    = of_device_uevent,
+	.uevent    = of_device_uevent_modalias,
 	.bus_attrs = ibmebus_bus_attrs,
 	.match     = ibmebus_bus_bus_match,
 	.probe     = ibmebus_bus_device_probe,
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 01e2877..bdfb3eee 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -490,409 +490,19 @@ void do_softirq(void)
 	local_irq_restore(flags);
 }
 
-
-/*
- * IRQ controller and virtual interrupts
- */
-
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
-	irq_hw_number_t	hwirq;
-	struct irq_host	*host;
-};
-
-static LIST_HEAD(irq_hosts);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
-
 irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
 {
-	return irq_map[d->irq].hwirq;
+	return d->hwirq;
 }
 EXPORT_SYMBOL_GPL(irqd_to_hwirq);
 
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
-	return irq_map[virq].hwirq;
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
-bool virq_is_host(unsigned int virq, struct irq_host *host)
-{
-	return irq_map[virq].host == host;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
-{
-	return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_host *irq_alloc_host(struct device_node *of_node,
-				unsigned int revmap_type,
-				unsigned int revmap_arg,
-				struct irq_host_ops *ops,
-				irq_hw_number_t inval_irq)
-{
-	struct irq_host *host;
-	unsigned int size = sizeof(struct irq_host);
-	unsigned int i;
-	unsigned int *rmap;
-	unsigned long flags;
-
-	/* Allocate structure and revmap table if using linear mapping */
-	if (revmap_type == IRQ_HOST_MAP_LINEAR)
-		size += revmap_arg * sizeof(unsigned int);
-	host = kzalloc(size, GFP_KERNEL);
-	if (host == NULL)
-		return NULL;
-
-	/* Fill structure */
-	host->revmap_type = revmap_type;
-	host->inval_irq = inval_irq;
-	host->ops = ops;
-	host->of_node = of_node_get(of_node);
-
-	if (host->ops->match == NULL)
-		host->ops->match = default_irq_host_match;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* If it's a legacy controller, check for duplicates and
-	 * mark it as allocated (we use irq 0 host pointer for that
-	 */
-	if (revmap_type == IRQ_HOST_MAP_LEGACY) {
-		if (irq_map[0].host != NULL) {
-			raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-			of_node_put(host->of_node);
-			kfree(host);
-			return NULL;
-		}
-		irq_map[0].host = host;
-	}
-
-	list_add(&host->link, &irq_hosts);
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-
-	/* Additional setups per revmap type */
-	switch(revmap_type) {
-	case IRQ_HOST_MAP_LEGACY:
-		/* 0 is always the invalid number for legacy */
-		host->inval_irq = 0;
-		/* setup us as the host for all legacy interrupts */
-		for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
-			irq_map[i].hwirq = i;
-			smp_wmb();
-			irq_map[i].host = host;
-			smp_wmb();
-
-			/* Legacy flags are left to default at this point,
-			 * one can then use irq_create_mapping() to
-			 * explicitly change them
-			 */
-			ops->map(host, i, i);
-
-			/* Clear norequest flags */
-			irq_clear_status_flags(i, IRQ_NOREQUEST);
-		}
-		break;
-	case IRQ_HOST_MAP_LINEAR:
-		rmap = (unsigned int *)(host + 1);
-		for (i = 0; i < revmap_arg; i++)
-			rmap[i] = NO_IRQ;
-		host->revmap_data.linear.size = revmap_arg;
-		smp_wmb();
-		host->revmap_data.linear.revmap = rmap;
-		break;
-	case IRQ_HOST_MAP_TREE:
-		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
-		break;
-	default:
-		break;
-	}
-
-	pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
-	return host;
-}
-
-struct irq_host *irq_find_host(struct device_node *node)
-{
-	struct irq_host *h, *found = NULL;
-	unsigned long flags;
-
-	/* We might want to match the legacy controller last since
-	 * it might potentially be set to match all interrupts in
-	 * the absence of a device node. This isn't a problem so far
-	 * yet though...
-	 */
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	list_for_each_entry(h, &irq_hosts, link)
-		if (h->ops->match(h, node)) {
-			found = h;
-			break;
-		}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_host *host)
-{
-	pr_debug("irq: Default host set to @0x%p\n", host);
-
-	irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
-	pr_debug("irq: Trying to set virq count to %d\n", count);
-
-	BUG_ON(count < NUM_ISA_INTERRUPTS);
-	if (count < NR_IRQS)
-		irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
-			    irq_hw_number_t hwirq)
-{
-	int res;
-
-	res = irq_alloc_desc_at(virq, 0);
-	if (res != virq) {
-		pr_debug("irq: -> allocating desc failed\n");
-		goto error;
-	}
-
-	/* map it */
-	smp_wmb();
-	irq_map[virq].hwirq = hwirq;
-	smp_mb();
-
-	if (host->ops->map(host, virq, hwirq)) {
-		pr_debug("irq: -> mapping failed, freeing\n");
-		goto errdesc;
-	}
-
-	irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
-	return 0;
-
-errdesc:
-	irq_free_descs(virq, 1);
-error:
-	irq_free_virt(virq, 1);
-	return -1;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_host *host)
-{
-	unsigned int virq;
-
-	if (host == NULL)
-		host = irq_default_host;
-
-	BUG_ON(host == NULL);
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
-
-	virq = irq_alloc_virt(host, 1, 0);
-	if (virq == NO_IRQ) {
-		pr_debug("irq: create_direct virq allocation failed\n");
-		return NO_IRQ;
-	}
-
-	pr_debug("irq: create_direct obtained virq %d\n", virq);
-
-	if (irq_setup_virq(host, virq, virq))
-		return NO_IRQ;
-
-	return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_host *host,
-				irq_hw_number_t hwirq)
-{
-	unsigned int virq, hint;
-
-	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL) {
-		printk(KERN_WARNING "irq_create_mapping called for"
-		       " NULL host, hwirq=%lx\n", hwirq);
-		WARN_ON(1);
-		return NO_IRQ;
-	}
-	pr_debug("irq: -> using host @%p\n", host);
-
-	/* Check if mapping already exists */
-	virq = irq_find_mapping(host, hwirq);
-	if (virq != NO_IRQ) {
-		pr_debug("irq: -> existing mapping on virq %d\n", virq);
-		return virq;
-	}
-
-	/* Get a virtual interrupt number */
-	if (host->revmap_type == IRQ_HOST_MAP_LEGACY) {
-		/* Handle legacy */
-		virq = (unsigned int)hwirq;
-		if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
-			return NO_IRQ;
-		return virq;
-	} else {
-		/* Allocate a virtual interrupt number */
-		hint = hwirq % irq_virq_count;
-		virq = irq_alloc_virt(host, 1, hint);
-		if (virq == NO_IRQ) {
-			pr_debug("irq: -> virq allocation failed\n");
-			return NO_IRQ;
-		}
-	}
-
-	if (irq_setup_virq(host, virq, hwirq))
-		return NO_IRQ;
-
-	pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
-		hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
-				   const u32 *intspec, unsigned int intsize)
-{
-	struct irq_host *host;
-	irq_hw_number_t hwirq;
-	unsigned int type = IRQ_TYPE_NONE;
-	unsigned int virq;
-
-	if (controller == NULL)
-		host = irq_default_host;
-	else
-		host = irq_find_host(controller);
-	if (host == NULL) {
-		printk(KERN_WARNING "irq: no irq host found for %s !\n",
-		       controller->full_name);
-		return NO_IRQ;
-	}
-
-	/* If host has no translation, then we assume interrupt line */
-	if (host->ops->xlate == NULL)
-		hwirq = intspec[0];
-	else {
-		if (host->ops->xlate(host, controller, intspec, intsize,
-				     &hwirq, &type))
-			return NO_IRQ;
-	}
-
-	/* Create mapping */
-	virq = irq_create_mapping(host, hwirq);
-	if (virq == NO_IRQ)
-		return virq;
-
-	/* Set type if specified and different than the current one */
-	if (type != IRQ_TYPE_NONE &&
-	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
-		irq_set_irq_type(virq, type);
-	return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
-void irq_dispose_mapping(unsigned int virq)
-{
-	struct irq_host *host;
-	irq_hw_number_t hwirq;
-
-	if (virq == NO_IRQ)
-		return;
-
-	host = irq_map[virq].host;
-	if (WARN_ON(host == NULL))
-		return;
-
-	/* Never unmap legacy interrupts */
-	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
-		return;
-
-	irq_set_status_flags(virq, IRQ_NOREQUEST);
-
-	/* remove chip and handler */
-	irq_set_chip_and_handler(virq, NULL, NULL);
-
-	/* Make sure it's completed */
-	synchronize_irq(virq);
-
-	/* Tell the PIC about it */
-	if (host->ops->unmap)
-		host->ops->unmap(host, virq);
-	smp_mb();
-
-	/* Clear reverse map */
-	hwirq = irq_map[virq].hwirq;
-	switch(host->revmap_type) {
-	case IRQ_HOST_MAP_LINEAR:
-		if (hwirq < host->revmap_data.linear.size)
-			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
-		break;
-	case IRQ_HOST_MAP_TREE:
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_delete(&host->revmap_data.tree, hwirq);
-		mutex_unlock(&revmap_trees_mutex);
-		break;
-	}
-
-	/* Destroy map */
-	smp_mb();
-	irq_map[virq].hwirq = host->inval_irq;
-
-	irq_free_descs(virq, 1);
-	/* Free it */
-	irq_free_virt(virq, 1);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_host *host,
-			      irq_hw_number_t hwirq)
-{
-	unsigned int i;
-	unsigned int hint = hwirq % irq_virq_count;
-
-	/* Look for default host if nececssary */
-	if (host == NULL)
-		host = irq_default_host;
-	if (host == NULL)
-		return NO_IRQ;
-
-	/* legacy -> bail early */
-	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
-		return hwirq;
-
-	/* Slow path does a linear search of the map */
-	if (hint < NUM_ISA_INTERRUPTS)
-		hint = NUM_ISA_INTERRUPTS;
-	i = hint;
-	do  {
-		if (irq_map[i].host == host &&
-		    irq_map[i].hwirq == hwirq)
-			return i;
-		i++;
-		if (i >= irq_virq_count)
-			i = NUM_ISA_INTERRUPTS;
-	} while(i != hint);
-	return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
 #ifdef CONFIG_SMP
 int irq_choose_cpu(const struct cpumask *mask)
 {
@@ -929,232 +539,11 @@ int irq_choose_cpu(const struct cpumask *mask)
 }
 #endif
 
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
-				     irq_hw_number_t hwirq)
-{
-	struct irq_map_entry *ptr;
-	unsigned int virq;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
-		return irq_find_mapping(host, hwirq);
-
-	/*
-	 * The ptr returned references the static global irq_map.
-	 * but freeing an irq can delete nodes along the path to
-	 * do the lookup via call_rcu.
-	 */
-	rcu_read_lock();
-	ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
-	rcu_read_unlock();
-
-	/*
-	 * If found in radix tree, then fine.
-	 * Else fallback to linear lookup - this should not happen in practice
-	 * as it means that we failed to insert the node in the radix tree.
-	 */
-	if (ptr)
-		virq = ptr - irq_map;
-	else
-		virq = irq_find_mapping(host, hwirq);
-
-	return virq;
-}
-
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
-			     irq_hw_number_t hwirq)
-{
-	if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
-		return;
-
-	if (virq != NO_IRQ) {
-		mutex_lock(&revmap_trees_mutex);
-		radix_tree_insert(&host->revmap_data.tree, hwirq,
-				  &irq_map[virq]);
-		mutex_unlock(&revmap_trees_mutex);
-	}
-}
-
-unsigned int irq_linear_revmap(struct irq_host *host,
-			       irq_hw_number_t hwirq)
-{
-	unsigned int *revmap;
-
-	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check revmap bounds */
-	if (unlikely(hwirq >= host->revmap_data.linear.size))
-		return irq_find_mapping(host, hwirq);
-
-	/* Check if revmap was allocated */
-	revmap = host->revmap_data.linear.revmap;
-	if (unlikely(revmap == NULL))
-		return irq_find_mapping(host, hwirq);
-
-	/* Fill up revmap with slow path if no mapping found */
-	if (unlikely(revmap[hwirq] == NO_IRQ))
-		revmap[hwirq] = irq_find_mapping(host, hwirq);
-
-	return revmap[hwirq];
-}
-
-unsigned int irq_alloc_virt(struct irq_host *host,
-			    unsigned int count,
-			    unsigned int hint)
-{
-	unsigned long flags;
-	unsigned int i, j, found = NO_IRQ;
-
-	if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
-		return NO_IRQ;
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-
-	/* Use hint for 1 interrupt if any */
-	if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
-	    hint < irq_virq_count && irq_map[hint].host == NULL) {
-		found = hint;
-		goto hint_found;
-	}
-
-	/* Look for count consecutive numbers in the allocatable
-	 * (non-legacy) space
-	 */
-	for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
-		if (irq_map[i].host != NULL)
-			j = 0;
-		else
-			j++;
-
-		if (j == count) {
-			found = i - count + 1;
-			break;
-		}
-	}
-	if (found == NO_IRQ) {
-		raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-		return NO_IRQ;
-	}
- hint_found:
-	for (i = found; i < (found + count); i++) {
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = host;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-	return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
-	unsigned long flags;
-	unsigned int i;
-
-	WARN_ON (virq < NUM_ISA_INTERRUPTS);
-	WARN_ON (count == 0 || (virq + count) > irq_virq_count);
-
-	if (virq < NUM_ISA_INTERRUPTS) {
-		if (virq + count < NUM_ISA_INTERRUPTS)
-			return;
-		count  =- NUM_ISA_INTERRUPTS - virq;
-		virq = NUM_ISA_INTERRUPTS;
-	}
-
-	if (count > irq_virq_count || virq > irq_virq_count - count) {
-		if (virq > irq_virq_count)
-			return;
-		count = irq_virq_count - virq;
-	}
-
-	raw_spin_lock_irqsave(&irq_big_lock, flags);
-	for (i = virq; i < (virq + count); i++) {
-		struct irq_host *host;
-
-		host = irq_map[i].host;
-		irq_map[i].hwirq = host->inval_irq;
-		smp_wmb();
-		irq_map[i].host = NULL;
-	}
-	raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
 int arch_early_irq_init(void)
 {
 	return 0;
 }
 
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
-	unsigned long flags;
-	struct irq_desc *desc;
-	const char *p;
-	static const char none[] = "none";
-	void *data;
-	int i;
-
-	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
-		      "chip name", "chip data", "host name");
-
-	for (i = 1; i < nr_irqs; i++) {
-		desc = irq_to_desc(i);
-		if (!desc)
-			continue;
-
-		raw_spin_lock_irqsave(&desc->lock, flags);
-
-		if (desc->action && desc->action->handler) {
-			struct irq_chip *chip;
-
-			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", irq_map[i].hwirq);
-
-			chip = irq_desc_get_chip(desc);
-			if (chip && chip->name)
-				p = chip->name;
-			else
-				p = none;
-			seq_printf(m, "%-15s  ", p);
-
-			data = irq_desc_get_chip_data(desc);
-			seq_printf(m, "0x%16p  ", data);
-
-			if (irq_map[i].host && irq_map[i].host->of_node)
-				p = irq_map[i].host->of_node->full_name;
-			else
-				p = none;
-			seq_printf(m, "%s\n", p);
-		}
-
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-	}
-
-	return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
-	.open = virq_debug_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
-	if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
-				 NULL, &virq_debug_fops) == NULL)
-		return -ENOMEM;
-
-	return 0;
-}
-__initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
-
 #ifdef CONFIG_PPC64
 static int __init setup_noirqdistrib(char *str)
 {
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index 64483fd..f04c230 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -1193,6 +1193,11 @@ static int power_pmu_event_init(struct perf_event *event)
 	return err;
 }
 
+static int power_pmu_event_idx(struct perf_event *event)
+{
+	return event->hw.idx;
+}
+
 struct pmu power_pmu = {
 	.pmu_enable	= power_pmu_enable,
 	.pmu_disable	= power_pmu_disable,
@@ -1205,6 +1210,7 @@ struct pmu power_pmu = {
 	.start_txn	= power_pmu_start_txn,
 	.cancel_txn	= power_pmu_cancel_txn,
 	.commit_txn	= power_pmu_commit_txn,
+	.event_idx	= power_pmu_event_idx,
 };
 
 /*
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 2300426..3867f7b 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -56,10 +56,7 @@ void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 void restore_sigmask(sigset_t *set)
 {
 	sigdelsetmask(set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = *set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(set);
 }
 
 static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
@@ -167,13 +164,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
 
 	regs->trap = 0;
 	if (ret) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka.sa.sa_mask);
-		if (!(ka.sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, signr);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
+		block_sigmask(&ka, signr);
 
 		/*
 		 * A signal was successfully delivered; the saved sigmask is in
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 836a5a1..e061ef5 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -242,12 +242,13 @@ static inline int restore_general_regs(struct pt_regs *regs,
  */
 long sys_sigsuspend(old_sigset_t mask)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
  	current->state = TASK_INTERRUPTIBLE;
  	schedule();
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 8b08629..2d49c32 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -487,7 +487,8 @@ static void vio_cmo_balance(struct work_struct *work)
 }
 
 static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size,
-                                          dma_addr_t *dma_handle, gfp_t flag)
+					  dma_addr_t *dma_handle, gfp_t flag,
+					  struct dma_attrs *attrs)
 {
 	struct vio_dev *viodev = to_vio_dev(dev);
 	void *ret;
@@ -497,7 +498,7 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size,
 		return NULL;
 	}
 
-	ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag);
+	ret = dma_iommu_ops.alloc(dev, size, dma_handle, flag, attrs);
 	if (unlikely(ret == NULL)) {
 		vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
 		atomic_inc(&viodev->cmo.allocs_failed);
@@ -507,11 +508,12 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void vio_dma_iommu_free_coherent(struct device *dev, size_t size,
-                                        void *vaddr, dma_addr_t dma_handle)
+					void *vaddr, dma_addr_t dma_handle,
+					struct dma_attrs *attrs)
 {
 	struct vio_dev *viodev = to_vio_dev(dev);
 
-	dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle);
+	dma_iommu_ops.free(dev, size, vaddr, dma_handle, attrs);
 
 	vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE));
 }
@@ -612,8 +614,8 @@ static u64 vio_dma_get_required_mask(struct device *dev)
 }
 
 struct dma_map_ops vio_dma_mapping_ops = {
-	.alloc_coherent    = vio_dma_iommu_alloc_coherent,
-	.free_coherent     = vio_dma_iommu_free_coherent,
+	.alloc             = vio_dma_iommu_alloc_coherent,
+	.free              = vio_dma_iommu_free_coherent,
 	.map_sg            = vio_dma_iommu_map_sg,
 	.unmap_sg          = vio_dma_iommu_unmap_sg,
 	.map_page          = vio_dma_iommu_map_page,
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index e2cfb9e..220fcdf 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -227,14 +227,14 @@ static void kvmppc_patch_dcbz(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
 	hpage_offset /= 4;
 
 	get_page(hpage);
-	page = kmap_atomic(hpage, KM_USER0);
+	page = kmap_atomic(hpage);
 
 	/* patch dcbz into reserved instruction, so we trap */
 	for (i=hpage_offset; i < hpage_offset + (HW_PAGE_SIZE / 4); i++)
 		if ((page[i] & 0xff0007ff) == INS_DCBZ)
 			page[i] &= 0xfffffff7;
 
-	kunmap_atomic(page, KM_USER0);
+	kunmap_atomic(page);
 	put_page(hpage);
 }
 
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c
index 329be36..6747eec 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -365,12 +365,11 @@ static inline void __dma_sync_page_highmem(struct page *page,
 	local_irq_save(flags);
 
 	do {
-		start = (unsigned long)kmap_atomic(page + seg_nr,
-				KM_PPC_SYNC_PAGE) + seg_offset;
+		start = (unsigned long)kmap_atomic(page + seg_nr) + seg_offset;
 
 		/* Sync this buffer segment */
 		__dma_sync((void *)start, seg_size, direction);
-		kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE);
+		kunmap_atomic((void *)start);
 		seg_nr++;
 
 		/* Calculate next buffer segment size */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index a8b3cc7..a3e6287 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -310,7 +310,8 @@ void __init reserve_hugetlb_gpages(void)
 	int i;
 
 	strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE);
-	parse_args("hugetlb gpages", cmdline, NULL, 0, &do_gpage_early_setup);
+	parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0,
+			&do_gpage_early_setup);
 
 	/*
 	 * Walk gpage list in reverse, allocating larger page sizes first.
@@ -910,9 +911,9 @@ void flush_dcache_icache_hugepage(struct page *page)
 		if (!PageHighMem(page)) {
 			__flush_dcache_icache(page_address(page+i));
 		} else {
-			start = kmap_atomic(page+i, KM_PPC_SYNC_ICACHE);
+			start = kmap_atomic(page+i);
 			__flush_dcache_icache(start);
-			kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+			kunmap_atomic(start);
 		}
 	}
 }
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index d974b79..baaafde 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -458,9 +458,9 @@ void flush_dcache_icache_page(struct page *page)
 #endif
 #ifdef CONFIG_BOOKE
 	{
-		void *start = kmap_atomic(page, KM_PPC_SYNC_ICACHE);
+		void *start = kmap_atomic(page);
 		__flush_dcache_icache(start);
-		kunmap_atomic(start, KM_PPC_SYNC_ICACHE);
+		kunmap_atomic(start);
 	}
 #elif defined(CONFIG_8xx) || defined(CONFIG_PPC64)
 	/* On 8xx there is no need to kmap since highmem is not supported */
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 9f09319..ca3a062 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -21,7 +21,7 @@
 #include <asm/prom.h>
 
 static struct device_node *cpld_pic_node;
-static struct irq_host *cpld_pic_host;
+static struct irq_domain *cpld_pic_host;
 
 /*
  * Bits to ignore in the misc_status register
@@ -123,13 +123,13 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
 }
 
 static int
-cpld_pic_host_match(struct irq_host *h, struct device_node *node)
+cpld_pic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	return cpld_pic_node == node;
 }
 
 static int
-cpld_pic_host_map(struct irq_host *h, unsigned int virq,
+cpld_pic_host_map(struct irq_domain *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
 	irq_set_status_flags(virq, IRQ_LEVEL);
@@ -137,8 +137,7 @@ cpld_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct
-irq_host_ops cpld_pic_host_ops = {
+static const struct irq_domain_ops cpld_pic_host_ops = {
 	.match = cpld_pic_host_match,
 	.map = cpld_pic_host_map,
 };
@@ -191,8 +190,7 @@ mpc5121_ads_cpld_pic_init(void)
 
 	cpld_pic_node = of_node_get(np);
 
-	cpld_pic_host =
-	    irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
+	cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL);
 	if (!cpld_pic_host) {
 		printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
 		goto end;
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 96f85e5..17d91b7 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -45,7 +45,7 @@ static struct of_device_id mpc5200_gpio_ids[] __initdata = {
 struct media5200_irq {
 	void __iomem *regs;
 	spinlock_t lock;
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 };
 struct media5200_irq media5200_irq;
 
@@ -112,7 +112,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
 	raw_spin_unlock(&desc->lock);
 }
 
-static int media5200_irq_map(struct irq_host *h, unsigned int virq,
+static int media5200_irq_map(struct irq_domain *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
 	pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
@@ -122,7 +122,7 @@ static int media5200_irq_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops media5200_irq_ops = {
+static const struct irq_domain_ops media5200_irq_ops = {
 	.map = media5200_irq_map,
 	.xlate = media5200_irq_xlate,
 };
@@ -173,15 +173,12 @@ static void __init media5200_init_irq(void)
 
 	spin_lock_init(&media5200_irq.lock);
 
-	media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR,
-					       MEDIA5200_NUM_IRQS,
-					       &media5200_irq_ops, -1);
+	media5200_irq.irqhost = irq_domain_add_linear(fpga_np,
+			MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq);
 	if (!media5200_irq.irqhost)
 		goto out;
 	pr_debug("%s: allocated irqhost\n", __func__);
 
-	media5200_irq.irqhost->host_data = &media5200_irq;
-
 	irq_set_handler_data(cascade_virq, &media5200_irq);
 	irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index f94f06e..028470b 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL");
  * @regs: virtual address of GPT registers
  * @lock: spinlock to coordinate between different functions.
  * @gc: gpio_chip instance structure; used when GPIO is enabled
- * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
+ * @irqhost: Pointer to irq_domain instance; used when IRQ mode is supported
  * @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
  *   if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
  *   if the timer is actively used as wdt which blocks gpt functions
@@ -91,7 +91,7 @@ struct mpc52xx_gpt_priv {
 	struct device *dev;
 	struct mpc52xx_gpt __iomem *regs;
 	spinlock_t lock;
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 	u32 ipb_freq;
 	u8 wdt_mode;
 
@@ -204,7 +204,7 @@ void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
 	}
 }
 
-static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq,
 			       irq_hw_number_t hw)
 {
 	struct mpc52xx_gpt_priv *gpt = h->host_data;
@@ -216,7 +216,7 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops mpc52xx_gpt_irq_ops = {
+static const struct irq_domain_ops mpc52xx_gpt_irq_ops = {
 	.map = mpc52xx_gpt_irq_map,
 	.xlate = mpc52xx_gpt_irq_xlate,
 };
@@ -252,14 +252,12 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
 	if (!cascade_virq)
 		return;
 
-	gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
-				      &mpc52xx_gpt_irq_ops, -1);
+	gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
 	if (!gpt->irqhost) {
-		dev_err(gpt->dev, "irq_alloc_host() failed\n");
+		dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
 		return;
 	}
 
-	gpt->irqhost->host_data = gpt;
 	irq_set_handler_data(cascade_virq, gpt);
 	irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 1a9a495..8520b58 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -132,7 +132,7 @@ static struct of_device_id mpc52xx_sdma_ids[] __initdata = {
 
 static struct mpc52xx_intr __iomem *intr;
 static struct mpc52xx_sdma __iomem *sdma;
-static struct irq_host *mpc52xx_irqhost = NULL;
+static struct irq_domain *mpc52xx_irqhost = NULL;
 
 static unsigned char mpc52xx_map_senses[4] = {
 	IRQ_TYPE_LEVEL_HIGH,
@@ -301,7 +301,7 @@ static int mpc52xx_is_extirq(int l1, int l2)
 /**
  * mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
  */
-static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc52xx_irqhost_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -335,7 +335,7 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
 /**
  * mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
  */
-static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
+static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
 			       irq_hw_number_t irq)
 {
 	int l1irq;
@@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops mpc52xx_irqhost_ops = {
+static const struct irq_domain_ops mpc52xx_irqhost_ops = {
 	.xlate = mpc52xx_irqhost_xlate,
 	.map = mpc52xx_irqhost_map,
 };
@@ -444,9 +444,9 @@ void __init mpc52xx_init_irq(void)
 	 * As last step, add an irq host to translate the real
 	 * hw irq information provided by the ofw to linux virq
 	 */
-	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
+	mpc52xx_irqhost = irq_domain_add_linear(picnode,
 	                                 MPC52xx_IRQ_HIGHTESTHWIRQ,
-	                                 &mpc52xx_irqhost_ops, -1);
+	                                 &mpc52xx_irqhost_ops, NULL);
 
 	if (!mpc52xx_irqhost)
 		panic(__FILE__ ": Cannot allocate the IRQ host\n");
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 8ccf9ed..328d221 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -29,7 +29,7 @@ static DEFINE_RAW_SPINLOCK(pci_pic_lock);
 
 struct pq2ads_pci_pic {
 	struct device_node *node;
-	struct irq_host *host;
+	struct irq_domain *host;
 
 	struct {
 		u32 stat;
@@ -103,7 +103,7 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
 	}
 }
 
-static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
+static int pci_pic_host_map(struct irq_domain *h, unsigned int virq,
 			    irq_hw_number_t hw)
 {
 	irq_set_status_flags(virq, IRQ_LEVEL);
@@ -112,14 +112,14 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops pci_pic_host_ops = {
+static const struct irq_domain_ops pci_pic_host_ops = {
 	.map = pci_pic_host_map,
 };
 
 int __init pq2ads_pci_init_irq(void)
 {
 	struct pq2ads_pci_pic *priv;
-	struct irq_host *host;
+	struct irq_domain *host;
 	struct device_node *np;
 	int ret = -ENODEV;
 	int irq;
@@ -156,17 +156,13 @@ int __init pq2ads_pci_init_irq(void)
 	out_be32(&priv->regs->mask, ~0);
 	mb();
 
-	host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS,
-	                      &pci_pic_host_ops, NUM_IRQS);
+	host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv);
 	if (!host) {
 		ret = -ENOMEM;
 		goto out_unmap_regs;
 	}
 
-	host->host_data = priv;
-
 	priv->host = host;
-	host->host_data = priv;
 	irq_set_handler_data(irq, priv);
 	irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
 
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 12cb9bb..3bbbf74 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -51,7 +51,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
 static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
 
 static void __iomem *socrates_fpga_pic_iobase;
-static struct irq_host *socrates_fpga_pic_irq_host;
+static struct irq_domain *socrates_fpga_pic_irq_host;
 static unsigned int socrates_fpga_irqs[3];
 
 static inline uint32_t socrates_fpga_pic_read(int reg)
@@ -227,7 +227,7 @@ static struct irq_chip socrates_fpga_pic_chip = {
 	.irq_set_type	= socrates_fpga_pic_set_type,
 };
 
-static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
+static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq,
 		irq_hw_number_t hwirq)
 {
 	/* All interrupts are LEVEL sensitive */
@@ -238,7 +238,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int socrates_fpga_pic_host_xlate(struct irq_host *h,
+static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
 		struct device_node *ct,	const u32 *intspec, unsigned int intsize,
 		irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_host *h,
 	return 0;
 }
 
-static struct irq_host_ops socrates_fpga_pic_host_ops = {
+static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
 	.map    = socrates_fpga_pic_host_map,
 	.xlate  = socrates_fpga_pic_host_xlate,
 };
@@ -279,10 +279,9 @@ void socrates_fpga_pic_init(struct device_node *pic)
 	unsigned long flags;
 	int i;
 
-	/* Setup an irq_host structure */
-	socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR,
-			SOCRATES_FPGA_NUM_IRQS,	&socrates_fpga_pic_host_ops,
-			SOCRATES_FPGA_NUM_IRQS);
+	/* Setup an irq_domain structure */
+	socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
+		    SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
 	if (socrates_fpga_pic_irq_host == NULL) {
 		pr_err("FPGA PIC: Unable to allocate host\n");
 		return;
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 94594e5..af3fd69 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -50,7 +50,7 @@
 static DEFINE_RAW_SPINLOCK(gef_pic_lock);
 
 static void __iomem *gef_pic_irq_reg_base;
-static struct irq_host *gef_pic_irq_host;
+static struct irq_domain *gef_pic_irq_host;
 static int gef_pic_cascade_irq;
 
 /*
@@ -153,7 +153,7 @@ static struct irq_chip gef_pic_chip = {
 /* When an interrupt is being configured, this call allows some flexibilty
  * in deciding which irq_chip structure is used
  */
-static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
+static int gef_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hwirq)
 {
 	/* All interrupts are LEVEL sensitive */
@@ -163,7 +163,7 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops gef_pic_host_ops = {
+static const struct irq_domain_ops gef_pic_host_ops = {
 	.map	= gef_pic_host_map,
 	.xlate	= gef_pic_host_xlate,
 };
@@ -211,10 +211,9 @@ void __init gef_pic_init(struct device_node *np)
 		return;
 	}
 
-	/* Setup an irq_host structure */
-	gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-					  GEF_PIC_NUM_IRQS,
-					  &gef_pic_host_ops, NO_IRQ);
+	/* Setup an irq_domain structure */
+	gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS,
+					  &gef_pic_host_ops, NULL);
 	if (gef_pic_irq_host == NULL)
 		return;
 
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index ee56a9e..1fb0b3c 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -26,6 +26,7 @@ config MPC86XADS
 config MPC885ADS
 	bool "MPC885ADS"
 	select CPM1
+	select OF_DYNAMIC
 	help
 	  Freescale Semiconductor MPC885 Application Development System (ADS).
 	  Also known as DUET.
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 40a6e34..db360fc 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -67,7 +67,7 @@
 
 
 struct axon_msic {
-	struct irq_host *irq_host;
+	struct irq_domain *irq_domain;
 	__le32 *fifo_virt;
 	dma_addr_t fifo_phys;
 	dcr_host_t dcr_host;
@@ -152,7 +152,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 
 static struct axon_msic *find_msi_translator(struct pci_dev *dev)
 {
-	struct irq_host *irq_host;
+	struct irq_domain *irq_domain;
 	struct device_node *dn, *tmp;
 	const phandle *ph;
 	struct axon_msic *msic = NULL;
@@ -184,14 +184,14 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
 		goto out_error;
 	}
 
-	irq_host = irq_find_host(dn);
-	if (!irq_host) {
-		dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n",
+	irq_domain = irq_find_host(dn);
+	if (!irq_domain) {
+		dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n",
 			dn->full_name);
 		goto out_error;
 	}
 
-	msic = irq_host->host_data;
+	msic = irq_domain->host_data;
 
 out_error:
 	of_node_put(dn);
@@ -280,7 +280,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 	BUILD_BUG_ON(NR_IRQS > 65536);
 
 	list_for_each_entry(entry, &dev->msi_list, list) {
-		virq = irq_create_direct_mapping(msic->irq_host);
+		virq = irq_create_direct_mapping(msic->irq_domain);
 		if (virq == NO_IRQ) {
 			dev_warn(&dev->dev,
 				 "axon_msi: virq allocation failed!\n");
@@ -318,7 +318,7 @@ static struct irq_chip msic_irq_chip = {
 	.name		= "AXON-MSI",
 };
 
-static int msic_host_map(struct irq_host *h, unsigned int virq,
+static int msic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -327,7 +327,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops msic_host_ops = {
+static const struct irq_domain_ops msic_host_ops = {
 	.map	= msic_host_map,
 };
 
@@ -337,7 +337,7 @@ static void axon_msi_shutdown(struct platform_device *device)
 	u32 tmp;
 
 	pr_devel("axon_msi: disabling %s\n",
-		  msic->irq_host->of_node->full_name);
+		  msic->irq_domain->of_node->full_name);
 	tmp  = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
 	tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
 	msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
@@ -392,16 +392,13 @@ static int axon_msi_probe(struct platform_device *device)
 	}
 	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-	msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
-					NR_IRQS, &msic_host_ops, 0);
-	if (!msic->irq_host) {
-		printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
+	msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
+	if (!msic->irq_domain) {
+		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
 		       dn->full_name);
 		goto out_free_fifo;
 	}
 
-	msic->irq_host->host_data = msic;
-
 	irq_set_handler_data(virq, msic);
 	irq_set_chained_handler(virq, axon_msi_cascade);
 	pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 55015e1..e5c3a2c 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -34,7 +34,7 @@ static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
 static uint64_t	beatic_irq_mask_enable[(MAX_IRQS+255)/64];
 static uint64_t	beatic_irq_mask_ack[(MAX_IRQS+255)/64];
 
-static struct irq_host *beatic_host;
+static struct irq_domain *beatic_host;
 
 /*
  * In this implementation, "virq" == "IRQ plug number",
@@ -122,7 +122,7 @@ static struct irq_chip beatic_pic = {
  *
  * Note that the number (virq) is already assigned at upper layer.
  */
-static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
+static void beatic_pic_host_unmap(struct irq_domain *h, unsigned int virq)
 {
 	beat_destruct_irq_plug(virq);
 }
@@ -133,7 +133,7 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
  *
  * Note that the number (virq) is already assigned at upper layer.
  */
-static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
+static int beatic_pic_host_map(struct irq_domain *h, unsigned int virq,
 			       irq_hw_number_t hw)
 {
 	int64_t	err;
@@ -154,7 +154,7 @@ static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
  * Called from irq_create_of_mapping() only.
  * Note: We have only 1 entry to translate.
  */
-static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int beatic_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 				 const u32 *intspec, unsigned int intsize,
 				 irq_hw_number_t *out_hwirq,
 				 unsigned int *out_flags)
@@ -166,13 +166,13 @@ static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static int beatic_pic_host_match(struct irq_host *h, struct device_node *np)
+static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np)
 {
 	/* Match all */
 	return 1;
 }
 
-static struct irq_host_ops beatic_pic_host_ops = {
+static const struct irq_domain_ops beatic_pic_host_ops = {
 	.map = beatic_pic_host_map,
 	.unmap = beatic_pic_host_unmap,
 	.xlate = beatic_pic_host_xlate,
@@ -239,9 +239,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 
 	/* Allocate an irq host */
-	beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
-				     &beatic_pic_host_ops,
-					 0);
+	beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
 	BUG_ON(beatic_host == NULL);
 	irq_set_default_host(beatic_host);
 }
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 96a433d..2d42f3b 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -56,7 +56,7 @@ struct iic {
 
 static DEFINE_PER_CPU(struct iic, cpu_iic);
 #define IIC_NODE_COUNT	2
-static struct irq_host *iic_host;
+static struct irq_domain *iic_host;
 
 /* Convert between "pending" bits and hw irq number */
 static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
@@ -186,7 +186,7 @@ void iic_message_pass(int cpu, int msg)
 	out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
 }
 
-struct irq_host *iic_get_irq_host(int node)
+struct irq_domain *iic_get_irq_host(int node)
 {
 	return iic_host;
 }
@@ -222,13 +222,13 @@ void iic_request_IPIs(void)
 #endif /* CONFIG_SMP */
 
 
-static int iic_host_match(struct irq_host *h, struct device_node *node)
+static int iic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	return of_device_is_compatible(node,
 				    "IBM,CBEA-Internal-Interrupt-Controller");
 }
 
-static int iic_host_map(struct irq_host *h, unsigned int virq,
+static int iic_host_map(struct irq_domain *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
 	switch (hw & IIC_IRQ_TYPE_MASK) {
@@ -245,7 +245,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops iic_host_ops = {
+static const struct irq_domain_ops iic_host_ops = {
 	.match = iic_host_match,
 	.map = iic_host_map,
 	.xlate = iic_host_xlate,
@@ -378,8 +378,8 @@ static int __init setup_iic(void)
 void __init iic_init_IRQ(void)
 {
 	/* Setup an irq host data structure */
-	iic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
-				  &iic_host_ops, IIC_IRQ_INVALID);
+	iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
+					 NULL);
 	BUG_ON(iic_host == NULL);
 	irq_set_default_host(iic_host);
 
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index ae9fc7b..b9f509a 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -564,7 +564,8 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
 /* A coherent allocation implies strong ordering */
 
 static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
-				      dma_addr_t *dma_handle, gfp_t flag)
+				      dma_addr_t *dma_handle, gfp_t flag,
+				      struct dma_attrs *attrs)
 {
 	if (iommu_fixed_is_weak)
 		return iommu_alloc_coherent(dev, cell_get_iommu_table(dev),
@@ -572,18 +573,19 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
 					    device_to_mask(dev), flag,
 					    dev_to_node(dev));
 	else
-		return dma_direct_ops.alloc_coherent(dev, size, dma_handle,
-						     flag);
+		return dma_direct_ops.alloc(dev, size, dma_handle, flag,
+					    attrs);
 }
 
 static void dma_fixed_free_coherent(struct device *dev, size_t size,
-				    void *vaddr, dma_addr_t dma_handle)
+				    void *vaddr, dma_addr_t dma_handle,
+				    struct dma_attrs *attrs)
 {
 	if (iommu_fixed_is_weak)
 		iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr,
 				    dma_handle);
 	else
-		dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle);
+		dma_direct_ops.free(dev, size, vaddr, dma_handle, attrs);
 }
 
 static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page,
@@ -642,8 +644,8 @@ static int dma_fixed_dma_supported(struct device *dev, u64 mask)
 static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
 
 struct dma_map_ops dma_iommu_fixed_ops = {
-	.alloc_coherent = dma_fixed_alloc_coherent,
-	.free_coherent  = dma_fixed_free_coherent,
+	.alloc          = dma_fixed_alloc_coherent,
+	.free           = dma_fixed_free_coherent,
 	.map_sg         = dma_fixed_map_sg,
 	.unmap_sg       = dma_fixed_unmap_sg,
 	.dma_supported  = dma_fixed_dma_supported,
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 442c28c..d8b7cc8 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -62,7 +62,7 @@ enum {
 #define SPIDER_IRQ_INVALID	63
 
 struct spider_pic {
-	struct irq_host		*host;
+	struct irq_domain		*host;
 	void __iomem		*regs;
 	unsigned int		node_id;
 };
@@ -168,7 +168,7 @@ static struct irq_chip spider_pic = {
 	.irq_set_type = spider_set_irq_type,
 };
 
-static int spider_host_map(struct irq_host *h, unsigned int virq,
+static int spider_host_map(struct irq_domain *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -180,7 +180,7 @@ static int spider_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
+static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops spider_host_ops = {
+static const struct irq_domain_ops spider_host_ops = {
 	.map = spider_host_map,
 	.xlate = spider_host_xlate,
 };
@@ -299,12 +299,10 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
 		panic("spider_pic: can't map registers !");
 
 	/* Allocate a host */
-	pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR,
-				   SPIDER_SRC_COUNT, &spider_host_ops,
-				   SPIDER_IRQ_INVALID);
+	pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
+					  &spider_host_ops, pic);
 	if (pic->host == NULL)
 		panic("spider_pic: can't allocate irq host !");
-	pic->host->host_data = pic;
 
 	/* Go through all sources and disable them */
 	for (i = 0; i < SPIDER_SRC_COUNT; i++) {
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index d4a094c..17b3211 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -757,9 +757,9 @@ spufs_create_root(struct super_block *sb, void *data)
 		goto out_iput;
 
 	ret = -ENOMEM;
-	sb->s_root = d_alloc_root(inode);
+	sb->s_root = d_make_root(inode);
 	if (!sb->s_root)
-		goto out_iput;
+		goto out;
 
 	return 0;
 out_iput:
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index f61a2dd..675335a 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -96,9 +96,9 @@ static struct irq_chip flipper_pic = {
  *
  */
 
-static struct irq_host *flipper_irq_host;
+static struct irq_domain *flipper_irq_host;
 
-static int flipper_pic_map(struct irq_host *h, unsigned int virq,
+static int flipper_pic_map(struct irq_domain *h, unsigned int virq,
 			   irq_hw_number_t hwirq)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -107,13 +107,13 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int flipper_pic_match(struct irq_host *h, struct device_node *np)
+static int flipper_pic_match(struct irq_domain *h, struct device_node *np)
 {
 	return 1;
 }
 
 
-static struct irq_host_ops flipper_irq_host_ops = {
+static const struct irq_domain_ops flipper_irq_domain_ops = {
 	.map = flipper_pic_map,
 	.match = flipper_pic_match,
 };
@@ -130,10 +130,10 @@ static void __flipper_quiesce(void __iomem *io_base)
 	out_be32(io_base + FLIPPER_ICR, 0xffffffff);
 }
 
-struct irq_host * __init flipper_pic_init(struct device_node *np)
+struct irq_domain * __init flipper_pic_init(struct device_node *np)
 {
 	struct device_node *pi;
-	struct irq_host *irq_host = NULL;
+	struct irq_domain *irq_domain = NULL;
 	struct resource res;
 	void __iomem *io_base;
 	int retval;
@@ -159,22 +159,20 @@ struct irq_host * __init flipper_pic_init(struct device_node *np)
 
 	__flipper_quiesce(io_base);
 
-	irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS,
-				  &flipper_irq_host_ops, -1);
-	if (!irq_host) {
-		pr_err("failed to allocate irq_host\n");
+	irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS,
+				  &flipper_irq_domain_ops, io_base);
+	if (!irq_domain) {
+		pr_err("failed to allocate irq_domain\n");
 		return NULL;
 	}
 
-	irq_host->host_data = io_base;
-
 out:
-	return irq_host;
+	return irq_domain;
 }
 
 unsigned int flipper_pic_get_irq(void)
 {
-	void __iomem *io_base = flipper_irq_host->host_data;
+	void __iomem *io_base = flipper_irq_domain->host_data;
 	int irq;
 	u32 irq_status;
 
@@ -184,7 +182,7 @@ unsigned int flipper_pic_get_irq(void)
 		return NO_IRQ;	/* no more IRQs pending */
 
 	irq = __ffs(irq_status);
-	return irq_linear_revmap(flipper_irq_host, irq);
+	return irq_linear_revmap(flipper_irq_domain, irq);
 }
 
 /*
@@ -199,7 +197,7 @@ void __init flipper_pic_probe(void)
 	np = of_find_compatible_node(NULL, NULL, "nintendo,flipper-pic");
 	BUG_ON(!np);
 
-	flipper_irq_host = flipper_pic_init(np);
+	flipper_irq_domain = flipper_pic_init(np);
 	BUG_ON(!flipper_irq_host);
 
 	irq_set_default_host(flipper_irq_host);
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index e491917..da6ca02 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -89,9 +89,9 @@ static struct irq_chip hlwd_pic = {
  *
  */
 
-static struct irq_host *hlwd_irq_host;
+static struct irq_domain *hlwd_irq_host;
 
-static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
+static int hlwd_pic_map(struct irq_domain *h, unsigned int virq,
 			   irq_hw_number_t hwirq)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -100,11 +100,11 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops hlwd_irq_host_ops = {
+static const struct irq_domain_ops hlwd_irq_domain_ops = {
 	.map = hlwd_pic_map,
 };
 
-static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
+static unsigned int __hlwd_pic_get_irq(struct irq_domain *h)
 {
 	void __iomem *io_base = h->host_data;
 	int irq;
@@ -123,14 +123,14 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
 				      struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct irq_host *irq_host = irq_get_handler_data(cascade_virq);
+	struct irq_domain *irq_domain = irq_get_handler_data(cascade_virq);
 	unsigned int virq;
 
 	raw_spin_lock(&desc->lock);
 	chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
 	raw_spin_unlock(&desc->lock);
 
-	virq = __hlwd_pic_get_irq(irq_host);
+	virq = __hlwd_pic_get_irq(irq_domain);
 	if (virq != NO_IRQ)
 		generic_handle_irq(virq);
 	else
@@ -155,9 +155,9 @@ static void __hlwd_quiesce(void __iomem *io_base)
 	out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff);
 }
 
-struct irq_host *hlwd_pic_init(struct device_node *np)
+struct irq_domain *hlwd_pic_init(struct device_node *np)
 {
-	struct irq_host *irq_host;
+	struct irq_domain *irq_domain;
 	struct resource res;
 	void __iomem *io_base;
 	int retval;
@@ -177,20 +177,19 @@ struct irq_host *hlwd_pic_init(struct device_node *np)
 
 	__hlwd_quiesce(io_base);
 
-	irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS,
-				  &hlwd_irq_host_ops, -1);
-	if (!irq_host) {
-		pr_err("failed to allocate irq_host\n");
+	irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS,
+					   &hlwd_irq_domain_ops, io_base);
+	if (!irq_domain) {
+		pr_err("failed to allocate irq_domain\n");
 		return NULL;
 	}
-	irq_host->host_data = io_base;
 
-	return irq_host;
+	return irq_domain;
 }
 
 unsigned int hlwd_pic_get_irq(void)
 {
-	return __hlwd_pic_get_irq(hlwd_irq_host);
+	return __hlwd_pic_get_irq(hlwd_irq_domain);
 }
 
 /*
@@ -200,7 +199,7 @@ unsigned int hlwd_pic_get_irq(void)
 
 void hlwd_pic_probe(void)
 {
-	struct irq_host *host;
+	struct irq_domain *host;
 	struct device_node *np;
 	const u32 *interrupts;
 	int cascade_virq;
@@ -214,7 +213,7 @@ void hlwd_pic_probe(void)
 			irq_set_handler_data(cascade_virq, host);
 			irq_set_chained_handler(cascade_virq,
 						hlwd_pic_irq_cascade);
-			hlwd_irq_host = host;
+			hlwd_irq_domain = host;
 			break;
 		}
 	}
@@ -228,7 +227,7 @@ void hlwd_pic_probe(void)
  */
 void hlwd_quiesce(void)
 {
-	void __iomem *io_base = hlwd_irq_host->host_data;
+	void __iomem *io_base = hlwd_irq_domain->host_data;
 
 	__hlwd_quiesce(io_base);
 }
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index b57cda3..63835e0 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -1,6 +1,7 @@
 config PPC_ISERIES
 	bool "IBM Legacy iSeries"
 	depends on PPC64 && PPC_BOOK3S
+	select OF_DYNAMIC
 	select PPC_SMP_MUXED_IPI
 	select PPC_INDIRECT_PIO
 	select PPC_INDIRECT_MMIO
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index b210345..05ce516 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -342,7 +342,7 @@ unsigned int iSeries_get_irq(void)
 
 #ifdef CONFIG_PCI
 
-static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
+static int iseries_irq_host_map(struct irq_domain *h, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
@@ -350,13 +350,13 @@ static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int iseries_irq_host_match(struct irq_host *h, struct device_node *np)
+static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np)
 {
 	/* Match all */
 	return 1;
 }
 
-static struct irq_host_ops iseries_irq_host_ops = {
+static const struct irq_domain_ops iseries_irq_domain_ops = {
 	.map = iseries_irq_host_map,
 	.match = iseries_irq_host_match,
 };
@@ -368,7 +368,7 @@ static struct irq_host_ops iseries_irq_host_ops = {
 void __init iSeries_init_IRQ(void)
 {
 	/* Register PCI event handler and open an event path */
-	struct irq_host *host;
+	struct irq_domain *host;
 	int ret;
 
 	/*
@@ -380,8 +380,7 @@ void __init iSeries_init_IRQ(void)
 	/* Create irq host. No need for a revmap since HV will give us
 	 * back our virtual irq number
 	 */
-	host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
-			      &iseries_irq_host_ops, 0);
+	host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL);
 	BUG_ON(host == NULL);
 	irq_set_default_host(host);
 
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 7761aab..92afc38 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -61,7 +61,7 @@ static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
 static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 static int pmac_irq_cascade = -1;
-static struct irq_host *pmac_pic_host;
+static struct irq_domain *pmac_pic_host;
 
 static void __pmac_retrigger(unsigned int irq_nr)
 {
@@ -268,13 +268,13 @@ static struct irqaction gatwick_cascade_action = {
 	.name		= "cascade",
 };
 
-static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
+static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* We match all, we don't always have a node anyway */
 	return 1;
 }
 
-static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
+static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
 			     irq_hw_number_t hw)
 {
 	if (hw >= max_irqs)
@@ -288,21 +288,10 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-			       const u32 *intspec, unsigned int intsize,
-			       irq_hw_number_t *out_hwirq,
-			       unsigned int *out_flags)
-
-{
-	*out_flags = IRQ_TYPE_NONE;
-	*out_hwirq = *intspec;
-	return 0;
-}
-
-static struct irq_host_ops pmac_pic_host_ops = {
+static const struct irq_domain_ops pmac_pic_host_ops = {
 	.match = pmac_pic_host_match,
 	.map = pmac_pic_host_map,
-	.xlate = pmac_pic_host_xlate,
+	.xlate = irq_domain_xlate_onecell,
 };
 
 static void __init pmac_pic_probe_oldstyle(void)
@@ -352,9 +341,8 @@ static void __init pmac_pic_probe_oldstyle(void)
 	/*
 	 * Allocate an irq host
 	 */
-	pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,
-				       &pmac_pic_host_ops,
-				       max_irqs);
+	pmac_pic_host = irq_domain_add_linear(master, max_irqs,
+					      &pmac_pic_host_ops, NULL);
 	BUG_ON(pmac_pic_host == NULL);
 	irq_set_default_host(pmac_pic_host);
 
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 44d7692..a81e5a8 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -125,7 +125,7 @@ static volatile u32 __iomem *psurge_start;
 static int psurge_type = PSURGE_NONE;
 
 /* irq for secondary cpus to report */
-static struct irq_host *psurge_host;
+static struct irq_domain *psurge_host;
 int psurge_secondary_virq;
 
 /*
@@ -176,7 +176,7 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
 	psurge_set_ipi(cpu);
 }
 
-static int psurge_host_map(struct irq_host *h, unsigned int virq,
+static int psurge_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
@@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-struct irq_host_ops psurge_host_ops = {
+static const struct irq_domain_ops psurge_host_ops = {
 	.map	= psurge_host_map,
 };
 
@@ -192,8 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
 	int rc = -ENOMEM;
 
-	psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
-		&psurge_host_ops, 0);
+	psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
 
 	if (psurge_host)
 		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 617efa1..2a4ff86 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -667,7 +667,7 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd,
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static int ps3_host_map(struct irq_host *h, unsigned int virq,
+static int ps3_host_map(struct irq_domain *h, unsigned int virq,
 	irq_hw_number_t hwirq)
 {
 	DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
@@ -678,13 +678,13 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int ps3_host_match(struct irq_host *h, struct device_node *np)
+static int ps3_host_match(struct irq_domain *h, struct device_node *np)
 {
 	/* Match all */
 	return 1;
 }
 
-static struct irq_host_ops ps3_host_ops = {
+static const struct irq_domain_ops ps3_host_ops = {
 	.map = ps3_host_map,
 	.match = ps3_host_match,
 };
@@ -751,10 +751,9 @@ void __init ps3_init_IRQ(void)
 {
 	int result;
 	unsigned cpu;
-	struct irq_host *host;
+	struct irq_domain *host;
 
-	host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
-		PS3_INVALID_OUTLET);
+	host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
 	irq_set_default_host(host);
 	irq_set_virq_count(PS3_PLUG_MAX + 1);
 
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 880eb9c..5606fe3 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -515,7 +515,8 @@ core_initcall(ps3_system_bus_init);
  * to the dma address (mapping) of the first page.
  */
 static void * ps3_alloc_coherent(struct device *_dev, size_t size,
-				      dma_addr_t *dma_handle, gfp_t flag)
+				 dma_addr_t *dma_handle, gfp_t flag,
+				 struct dma_attrs *attrs)
 {
 	int result;
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
@@ -552,7 +553,7 @@ clean_none:
 }
 
 static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
-	dma_addr_t dma_handle)
+			      dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 
@@ -701,8 +702,8 @@ static u64 ps3_dma_get_required_mask(struct device *_dev)
 }
 
 static struct dma_map_ops ps3_sb_dma_ops = {
-	.alloc_coherent = ps3_alloc_coherent,
-	.free_coherent = ps3_free_coherent,
+	.alloc = ps3_alloc_coherent,
+	.free = ps3_free_coherent,
 	.map_sg = ps3_sb_map_sg,
 	.unmap_sg = ps3_sb_unmap_sg,
 	.dma_supported = ps3_dma_supported,
@@ -712,8 +713,8 @@ static struct dma_map_ops ps3_sb_dma_ops = {
 };
 
 static struct dma_map_ops ps3_ioc0_dma_ops = {
-	.alloc_coherent = ps3_alloc_coherent,
-	.free_coherent = ps3_free_coherent,
+	.alloc = ps3_alloc_coherent,
+	.free = ps3_free_coherent,
 	.map_sg = ps3_ioc0_map_sg,
 	.unmap_sg = ps3_ioc0_unmap_sg,
 	.dma_supported = ps3_dma_supported,
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index 31f22c1..f255625 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -3,6 +3,7 @@ config PPC_PSERIES
 	bool "IBM pSeries & new (POWER5-based) iSeries"
 	select HAVE_PCSPKR_PLATFORM
 	select MPIC
+	select OF_DYNAMIC
 	select PCI_MSI
 	select PPC_XICS
 	select PPC_ICP_NATIVE
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
index 57d22a2..79d2225 100644
--- a/arch/powerpc/platforms/wsp/Kconfig
+++ b/arch/powerpc/platforms/wsp/Kconfig
@@ -25,6 +25,7 @@ config PPC_CHROMA
 	bool "PowerEN PCIe Chroma Card"
 	select EPAPR_BOOT
 	select PPC_WSP
+	select OF_DYNAMIC
 	default y
 
 endmenu
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 19f353d..cb565bf 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -30,7 +30,7 @@
 static int opb_index = 0;
 
 struct opb_pic {
-	struct irq_host *host;
+	struct irq_domain *host;
 	void *regs;
 	int index;
 	spinlock_t lock;
@@ -179,7 +179,7 @@ static struct irq_chip opb_irq_chip = {
 	.irq_set_type	= opb_set_irq_type
 };
 
-static int opb_host_map(struct irq_host *host, unsigned int virq,
+static int opb_host_map(struct irq_domain *host, unsigned int virq,
 		irq_hw_number_t hwirq)
 {
 	struct opb_pic *opb;
@@ -196,20 +196,9 @@ static int opb_host_map(struct irq_host *host, unsigned int virq,
 	return 0;
 }
 
-static int opb_host_xlate(struct irq_host *host, struct device_node *dn,
-		const u32 *intspec, unsigned int intsize,
-		irq_hw_number_t *out_hwirq, unsigned int *out_type)
-{
-	/* Interrupt size must == 2 */
-	BUG_ON(intsize != 2);
-	*out_hwirq = intspec[0];
-	*out_type = intspec[1];
-	return 0;
-}
-
-static struct irq_host_ops opb_host_ops = {
+static const struct irq_domain_ops opb_host_ops = {
 	.map = opb_host_map,
-	.xlate = opb_host_xlate,
+	.xlate = irq_domain_xlate_twocell,
 };
 
 irqreturn_t opb_irq_handler(int irq, void *private)
@@ -263,13 +252,11 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
 		goto free_opb;
 	}
 
-	/* Allocate an irq host so that Linux knows that despite only
+	/* Allocate an irq domain so that Linux knows that despite only
 	 * having one interrupt to issue, we're the controller for multiple
 	 * hardware IRQs, so later we can lookup their virtual IRQs. */
 
-	opb->host = irq_alloc_host(dn, IRQ_HOST_MAP_LINEAR,
-			OPB_NR_IRQS, &opb_host_ops, -1);
-
+	opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb);
 	if (!opb->host) {
 		printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
 		goto free_regs;
@@ -277,7 +264,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
 
 	opb->index = opb_index++;
 	spin_lock_init(&opb->lock);
-	opb->host->host_data = opb;
 
 	/* Disable all interrupts by default */
 	opb_out(opb, OPB_MLSASIER, 0);
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 5d7d59a..d4fa03f 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -54,7 +54,7 @@ cpm8xx_t __iomem *cpmp;  /* Pointer to comm processor space */
 immap_t __iomem *mpc8xx_immr;
 static cpic8xx_t __iomem *cpic_reg;
 
-static struct irq_host *cpm_pic_host;
+static struct irq_domain *cpm_pic_host;
 
 static void cpm_mask_irq(struct irq_data *d)
 {
@@ -98,7 +98,7 @@ int cpm_get_irq(void)
 	return irq_linear_revmap(cpm_pic_host, cpm_vec);
 }
 
-static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
+static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = {
 	.name = "error",
 };
 
-static struct irq_host_ops cpm_pic_host_ops = {
+static const struct irq_domain_ops cpm_pic_host_ops = {
 	.map = cpm_pic_host_map,
 };
 
@@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void)
 
 	out_be32(&cpic_reg->cpic_cimr, 0);
 
-	cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-				      64, &cpm_pic_host_ops, 64);
+	cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
 	if (cpm_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
 		sirq = NO_IRQ;
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index bcab50e..d3be961 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -50,7 +50,7 @@
 
 static intctl_cpm2_t __iomem *cpm2_intctl;
 
-static struct irq_host *cpm2_pic_host;
+static struct irq_domain *cpm2_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 
@@ -214,7 +214,7 @@ unsigned int cpm2_get_irq(void)
 	return irq_linear_revmap(cpm2_pic_host, irq);
 }
 
-static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
+static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -224,21 +224,9 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
-			    const u32 *intspec, unsigned int intsize,
-			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-{
-	*out_hwirq = intspec[0];
-	if (intsize > 1)
-		*out_flags = intspec[1];
-	else
-		*out_flags = IRQ_TYPE_NONE;
-	return 0;
-}
-
-static struct irq_host_ops cpm2_pic_host_ops = {
+static const struct irq_domain_ops cpm2_pic_host_ops = {
 	.map = cpm2_pic_host_map,
-	.xlate = cpm2_pic_host_xlate,
+	.xlate = irq_domain_xlate_onetwocell,
 };
 
 void cpm2_pic_init(struct device_node *node)
@@ -275,8 +263,7 @@ void cpm2_pic_init(struct device_node *node)
 	out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
 
 	/* create a legacy host */
-	cpm2_pic_host = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
-				       64, &cpm2_pic_host_ops, 64);
+	cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL);
 	if (cpm2_pic_host == NULL) {
 		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
 		return;
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index b6731e4..6e0e100 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -182,13 +182,13 @@ unsigned int ehv_pic_get_irq(void)
 	return irq_linear_revmap(global_ehv_pic->irqhost, irq);
 }
 
-static int ehv_pic_host_match(struct irq_host *h, struct device_node *node)
+static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless ehv_pic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
+static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct ehv_pic *ehv_pic = h->host_data;
@@ -217,7 +217,7 @@ static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops ehv_pic_host_ops = {
+static const struct irq_domain_ops ehv_pic_host_ops = {
 	.match = ehv_pic_host_match,
 	.map = ehv_pic_host_map,
 	.xlate = ehv_pic_host_xlate,
@@ -275,9 +275,8 @@ void __init ehv_pic_init(void)
 		return;
 	}
 
-	ehv_pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-		NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0);
-
+	ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS,
+						 &ehv_pic_host_ops, ehv_pic);
 	if (!ehv_pic->irqhost) {
 		of_node_put(np);
 		kfree(ehv_pic);
@@ -293,7 +292,6 @@ void __init ehv_pic_init(void)
 		of_node_put(np2);
 	}
 
-	ehv_pic->irqhost->host_data = ehv_pic;
 	ehv_pic->hc_irq = ehv_pic_irq_chip;
 	ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
 	ehv_pic->coreint_flag = coreint_flag;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ecb5c19..0c01deb 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -60,7 +60,7 @@ static struct irq_chip fsl_msi_chip = {
 	.name		= "FSL-MSI",
 };
 
-static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
+static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	struct fsl_msi *msi_data = h->host_data;
@@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops fsl_msi_host_ops = {
+static const struct irq_domain_ops fsl_msi_host_ops = {
 	.map = fsl_msi_host_map,
 };
 
@@ -387,8 +387,8 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 	}
 	platform_set_drvdata(dev, msi);
 
-	msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
-				      NR_MSI_IRQS, &fsl_msi_host_ops, 0);
+	msi->irqhost = irq_domain_add_linear(dev->dev.of_node,
+				      NR_MSI_IRQS, &fsl_msi_host_ops, msi);
 
 	if (msi->irqhost == NULL) {
 		dev_err(&dev->dev, "No memory for MSI irqhost\n");
@@ -420,8 +420,6 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
 
 	msi->feature = features->fsl_pic_ip;
 
-	msi->irqhost->host_data = msi;
-
 	/*
 	 * Remember the phandle, so that we can match with any PCI nodes
 	 * that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index f6c646a..8225f86 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -26,7 +26,7 @@
 #define FSL_PIC_IP_VMPIC  0x00000003
 
 struct fsl_msi {
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 
 	unsigned long cascade_irq;
 
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index d18bb27..997df6a 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -25,7 +25,7 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
 
 static DEFINE_RAW_SPINLOCK(i8259_lock);
 
-static struct irq_host *i8259_host;
+static struct irq_domain *i8259_host;
 
 /*
  * Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -163,12 +163,12 @@ static struct resource pic_edgectrl_iores = {
 	.flags = IORESOURCE_BUSY,
 };
 
-static int i8259_host_match(struct irq_host *h, struct device_node *node)
+static int i8259_host_match(struct irq_domain *h, struct device_node *node)
 {
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int i8259_host_map(struct irq_host *h, unsigned int virq,
+static int i8259_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw);
@@ -185,7 +185,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
+static int i8259_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -205,13 +205,13 @@ static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops i8259_host_ops = {
+static struct irq_domain_ops i8259_host_ops = {
 	.match = i8259_host_match,
 	.map = i8259_host_map,
 	.xlate = i8259_host_xlate,
 };
 
-struct irq_host *i8259_get_host(void)
+struct irq_domain *i8259_get_host(void)
 {
 	return i8259_host;
 }
@@ -263,8 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
-				    0, &i8259_host_ops, 0);
+	i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL);
 	if (i8259_host == NULL) {
 		printk(KERN_ERR "i8259: failed to allocate irq host !\n");
 		return;
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 95da897..b50f978 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -672,13 +672,13 @@ static struct irq_chip ipic_edge_irq_chip = {
 	.irq_set_type	= ipic_set_irq_type,
 };
 
-static int ipic_host_match(struct irq_host *h, struct device_node *node)
+static int ipic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless ipic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int ipic_host_map(struct irq_host *h, unsigned int virq,
+static int ipic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct ipic *ipic = h->host_data;
@@ -692,26 +692,10 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
-			   const u32 *intspec, unsigned int intsize,
-			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-
-{
-	/* interrupt sense values coming from the device tree equal either
-	 * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
-	 */
-	*out_hwirq = intspec[0];
-	if (intsize > 1)
-		*out_flags = intspec[1];
-	else
-		*out_flags = IRQ_TYPE_NONE;
-	return 0;
-}
-
-static struct irq_host_ops ipic_host_ops = {
+static struct irq_domain_ops ipic_host_ops = {
 	.match	= ipic_host_match,
 	.map	= ipic_host_map,
-	.xlate	= ipic_host_xlate,
+	.xlate	= irq_domain_xlate_onetwocell,
 };
 
 struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
@@ -728,9 +712,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 	if (ipic == NULL)
 		return NULL;
 
-	ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
-				       NR_IPIC_INTS,
-				       &ipic_host_ops, 0);
+	ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
+					      &ipic_host_ops, ipic);
 	if (ipic->irqhost == NULL) {
 		kfree(ipic);
 		return NULL;
@@ -738,8 +721,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 
 	ipic->regs = ioremap(res.start, resource_size(&res));
 
-	ipic->irqhost->host_data = ipic;
-
 	/* init hw */
 	ipic_write(ipic->regs, IPIC_SICNR, 0x0);
 
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index 9391c57..90031d1 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -43,7 +43,7 @@ struct ipic {
 	volatile u32 __iomem	*regs;
 
 	/* The remapper for this IPIC */
-	struct irq_host		*irqhost;
+	struct irq_domain		*irqhost;
 };
 
 struct ipic_info {
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2ca0a85..d5f5416 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -17,7 +17,7 @@
 
 extern int cpm_get_irq(struct pt_regs *regs);
 
-static struct irq_host *mpc8xx_pic_host;
+static struct irq_domain *mpc8xx_pic_host;
 #define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
 static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
 static sysconf8xx_t __iomem *siu_reg;
@@ -110,7 +110,7 @@ unsigned int mpc8xx_get_irq(void)
 
 }
 
-static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
+static int mpc8xx_pic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -121,7 +121,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
 }
 
 
-static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -142,7 +142,7 @@ static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
 }
 
 
-static struct irq_host_ops mpc8xx_pic_host_ops = {
+static struct irq_domain_ops mpc8xx_pic_host_ops = {
 	.map = mpc8xx_pic_host_map,
 	.xlate = mpc8xx_pic_host_xlate,
 };
@@ -171,8 +171,7 @@ int mpc8xx_pic_init(void)
 		goto out;
 	}
 
-	mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-					 64, &mpc8xx_pic_host_ops, 64);
+	mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
 	if (mpc8xx_pic_host == NULL) {
 		printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
 		ret = -ENOMEM;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e9ccb1..c83a512 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -965,13 +965,13 @@ static struct irq_chip mpic_irq_ht_chip = {
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
 
 
-static int mpic_host_match(struct irq_host *h, struct device_node *node)
+static int mpic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless mpic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int mpic_host_map(struct irq_host *h, unsigned int virq,
+static int mpic_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct mpic *mpic = h->host_data;
@@ -1041,7 +1041,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -1121,13 +1121,13 @@ static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
 	BUG_ON(!(mpic->flags & MPIC_SECONDARY));
 
 	virq = mpic_get_one_irq(mpic);
-	if (virq != NO_IRQ)
+	if (virq)
 		generic_handle_irq(virq);
 
 	chip->irq_eoi(&desc->irq_data);
 }
 
-static struct irq_host_ops mpic_host_ops = {
+static struct irq_domain_ops mpic_host_ops = {
 	.match = mpic_host_match,
 	.map = mpic_host_map,
 	.xlate = mpic_host_xlate,
@@ -1345,10 +1345,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
 	mpic->isu_mask = (1 << mpic->isu_shift) - 1;
 
-	mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR,
+	mpic->irqhost = irq_domain_add_linear(mpic->node,
 				       isu_size ? isu_size : mpic->num_sources,
-				       &mpic_host_ops,
-				       flags & MPIC_LARGE_VECTORS ? 2048 : 256);
+				       &mpic_host_ops, mpic);
 
 	/*
 	 * FIXME: The code leaks the MPIC object and mappings here; this
@@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
 	if (mpic->irqhost == NULL)
 		return NULL;
 
-	mpic->irqhost->host_data = mpic;
-
 	/* Display version */
 	switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
 	case 1:
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index 0f67cd7..0622aa9 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -32,7 +32,7 @@ void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
 static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
 {
 	irq_hw_number_t hwirq;
-	struct irq_host_ops *ops = mpic->irqhost->ops;
+	const struct irq_domain_ops *ops = mpic->irqhost->ops;
 	struct device_node *np;
 	int flags, index, i;
 	struct of_irq oirq;
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 14d1302..8848e99 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -70,7 +70,7 @@ static u32 mv64x60_cached_low_mask;
 static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
 static u32 mv64x60_cached_gpp_mask;
 
-static struct irq_host *mv64x60_irq_host;
+static struct irq_domain *mv64x60_irq_host;
 
 /*
  * mv64x60_chip_low functions
@@ -208,7 +208,7 @@ static struct irq_chip *mv64x60_chips[] = {
 	[MV64x60_LEVEL1_GPP]  = &mv64x60_chip_gpp,
 };
 
-static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
+static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hwirq)
 {
 	int level1;
@@ -223,7 +223,7 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops mv64x60_host_ops = {
+static struct irq_domain_ops mv64x60_host_ops = {
 	.map   = mv64x60_host_map,
 };
 
@@ -250,9 +250,8 @@ void __init mv64x60_init_irq(void)
 	paddr = of_translate_address(np, reg);
 	mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
 
-	mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
-					  MV64x60_NUM_IRQS,
-					  &mv64x60_host_ops, MV64x60_NUM_IRQS);
+	mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
+					  &mv64x60_host_ops, NULL);
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
 	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 73034bd..2fba6ef 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -245,13 +245,13 @@ static struct irq_chip qe_ic_irq_chip = {
 	.irq_mask_ack = qe_ic_mask_irq,
 };
 
-static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
+static int qe_ic_host_match(struct irq_domain *h, struct device_node *node)
 {
 	/* Exact match, unless qe_ic node is NULL */
 	return h->of_node == NULL || h->of_node == node;
 }
 
-static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
+static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	struct qe_ic *qe_ic = h->host_data;
@@ -272,23 +272,10 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
-			    const u32 * intspec, unsigned int intsize,
-			    irq_hw_number_t * out_hwirq,
-			    unsigned int *out_flags)
-{
-	*out_hwirq = intspec[0];
-	if (intsize > 1)
-		*out_flags = intspec[1];
-	else
-		*out_flags = IRQ_TYPE_NONE;
-	return 0;
-}
-
-static struct irq_host_ops qe_ic_host_ops = {
+static struct irq_domain_ops qe_ic_host_ops = {
 	.match = qe_ic_host_match,
 	.map = qe_ic_host_map,
-	.xlate = qe_ic_host_xlate,
+	.xlate = irq_domain_xlate_onetwocell,
 };
 
 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
@@ -339,8 +326,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 	if (qe_ic == NULL)
 		return;
 
-	qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
-					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
+	qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+					       &qe_ic_host_ops, qe_ic);
 	if (qe_ic->irqhost == NULL) {
 		kfree(qe_ic);
 		return;
@@ -348,7 +335,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 
 	qe_ic->regs = ioremap(res.start, resource_size(&res));
 
-	qe_ic->irqhost->host_data = qe_ic;
 	qe_ic->hc_irq = qe_ic_irq_chip;
 
 	qe_ic->virq_high = irq_of_parse_and_map(node, 0);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
index c1361d0..c327872 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -79,7 +79,7 @@ struct qe_ic {
 	volatile u32 __iomem *regs;
 
 	/* The remapper for this QEIC */
-	struct irq_host *irqhost;
+	struct irq_domain *irqhost;
 
 	/* The "linux" controller struct */
 	struct irq_chip hc_irq;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 4d18658..188012c 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -51,7 +51,7 @@
 u32 tsi108_pci_cfg_base;
 static u32 tsi108_pci_cfg_phys;
 u32 tsi108_csr_vir_base;
-static struct irq_host *pci_irq_host;
+static struct irq_domain *pci_irq_host;
 
 extern u32 get_vir_csrbase(void);
 extern u32 tsi108_read_reg(u32 reg_offset);
@@ -376,7 +376,7 @@ static struct irq_chip tsi108_pci_irq = {
 	.irq_unmask = tsi108_pci_irq_unmask,
 };
 
-static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
+static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 {
@@ -385,7 +385,7 @@ static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
+static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {	unsigned int irq;
 	DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
@@ -397,7 +397,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops pci_irq_host_ops = {
+static struct irq_domain_ops pci_irq_domain_ops = {
 	.map = pci_irq_host_map,
 	.xlate = pci_irq_host_xlate,
 };
@@ -419,10 +419,9 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
-				      0, &pci_irq_host_ops, 0);
+	pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL);
 	if (pci_irq_host == NULL) {
-		printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
+		printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
 		return;
 	}
 
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 063c901..9203393 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -49,7 +49,7 @@ struct uic {
 	raw_spinlock_t lock;
 
 	/* The remapper for this UIC */
-	struct irq_host	*irqhost;
+	struct irq_domain	*irqhost;
 };
 
 static void uic_unmask_irq(struct irq_data *d)
@@ -174,7 +174,7 @@ static struct irq_chip uic_irq_chip = {
 	.irq_set_type	= uic_set_irq_type,
 };
 
-static int uic_host_map(struct irq_host *h, unsigned int virq,
+static int uic_host_map(struct irq_domain *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
 	struct uic *uic = h->host_data;
@@ -190,21 +190,9 @@ static int uic_host_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
-			  const u32 *intspec, unsigned int intsize,
-			  irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
-	/* UIC intspecs must have 2 cells */
-	BUG_ON(intsize != 2);
-	*out_hwirq = intspec[0];
-	*out_type = intspec[1];
-	return 0;
-}
-
-static struct irq_host_ops uic_host_ops = {
+static struct irq_domain_ops uic_host_ops = {
 	.map	= uic_host_map,
-	.xlate	= uic_host_xlate,
+	.xlate	= irq_domain_xlate_twocell,
 };
 
 void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
@@ -270,13 +258,11 @@ static struct uic * __init uic_init_one(struct device_node *node)
 	}
 	uic->dcrbase = *dcrreg;
 
-	uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
-				      NR_UIC_INTS, &uic_host_ops, -1);
+	uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops,
+					     uic);
 	if (! uic->irqhost)
 		return NULL; /* FIXME: panic? */
 
-	uic->irqhost->host_data = uic;
-
 	/* Start with all interrupts disabled, level and non-critical */
 	mtdcr(uic->dcrbase + UIC_ER, 0);
 	mtdcr(uic->dcrbase + UIC_CR, 0);
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index d72eda6..ea5e204 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -40,7 +40,7 @@ unsigned int xics_interrupt_server_size		= 8;
 
 DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
 
-struct irq_host *xics_host;
+struct irq_domain *xics_host;
 
 static LIST_HEAD(ics_list);
 
@@ -212,16 +212,16 @@ void xics_migrate_irqs_away(void)
 		/* We can't set affinity on ISA interrupts */
 		if (virq < NUM_ISA_INTERRUPTS)
 			continue;
-		if (!virq_is_host(virq, xics_host))
-			continue;
-		irq = (unsigned int)virq_to_hw(virq);
-		/* We need to get IPIs still. */
-		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
-			continue;
 		desc = irq_to_desc(virq);
 		/* We only need to migrate enabled IRQS */
 		if (!desc || !desc->action)
 			continue;
+		if (desc->irq_data.domain != xics_host)
+			continue;
+		irq = desc->irq_data.hwirq;
+		/* We need to get IPIs still. */
+		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+			continue;
 		chip = irq_desc_get_chip(desc);
 		if (!chip || !chip->irq_set_affinity)
 			continue;
@@ -301,7 +301,7 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
 }
 #endif /* CONFIG_SMP */
 
-static int xics_host_match(struct irq_host *h, struct device_node *node)
+static int xics_host_match(struct irq_domain *h, struct device_node *node)
 {
 	struct ics *ics;
 
@@ -323,7 +323,7 @@ static struct irq_chip xics_ipi_chip = {
 	.irq_unmask = xics_ipi_unmask,
 };
 
-static int xics_host_map(struct irq_host *h, unsigned int virq,
+static int xics_host_map(struct irq_domain *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	struct ics *ics;
@@ -351,7 +351,7 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
 	return -EINVAL;
 }
 
-static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
+static int xics_host_xlate(struct irq_domain *h, struct device_node *ct,
 			   const u32 *intspec, unsigned int intsize,
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
@@ -366,7 +366,7 @@ static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
 	return 0;
 }
 
-static struct irq_host_ops xics_host_ops = {
+static struct irq_domain_ops xics_host_ops = {
 	.match = xics_host_match,
 	.map = xics_host_map,
 	.xlate = xics_host_xlate,
@@ -374,8 +374,7 @@ static struct irq_host_ops xics_host_ops = {
 
 static void __init xics_init_host(void)
 {
-	xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops,
-				   XICS_IRQ_SPURIOUS);
+	xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL);
 	BUG_ON(xics_host == NULL);
 	irq_set_default_host(xics_host);
 }
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 6183799..8d73c3c 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -40,7 +40,7 @@
 #define XINTC_IVR	24	/* Interrupt Vector */
 #define XINTC_MER	28	/* Master Enable */
 
-static struct irq_host *master_irqhost;
+static struct irq_domain *master_irqhost;
 
 #define XILINX_INTC_MAXIRQS	(32)
 
@@ -141,7 +141,7 @@ static struct irq_chip xilinx_intc_edge_irqchip = {
 /**
  * xilinx_intc_xlate - translate virq# from device tree interrupts property
  */
-static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
+static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct,
 				const u32 *intspec, unsigned int intsize,
 				irq_hw_number_t *out_hwirq,
 				unsigned int *out_flags)
@@ -161,7 +161,7 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
 
 	return 0;
 }
-static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
+static int xilinx_intc_map(struct irq_domain *h, unsigned int virq,
 				  irq_hw_number_t irq)
 {
 	irq_set_chip_data(virq, h->host_data);
@@ -177,15 +177,15 @@ static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static struct irq_host_ops xilinx_intc_ops = {
+static struct irq_domain_ops xilinx_intc_ops = {
 	.map = xilinx_intc_map,
 	.xlate = xilinx_intc_xlate,
 };
 
-struct irq_host * __init
+struct irq_domain * __init
 xilinx_intc_init(struct device_node *np)
 {
-	struct irq_host * irq;
+	struct irq_domain * irq;
 	void * regs;
 
 	/* Find and map the intc registers */
@@ -200,12 +200,11 @@ xilinx_intc_init(struct device_node *np)
 	out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */
 	out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
 
-	/* Allocate and initialize an irq_host structure. */
-	irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS,
-			     &xilinx_intc_ops, -1);
+	/* Allocate and initialize an irq_domain structure. */
+	irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
+				    regs);
 	if (!irq)
 		panic(__FILE__ ": Cannot allocate IRQ host\n");
-	irq->host_data = regs;
 
 	return irq;
 }
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index d172758..47bc8a6 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -218,6 +218,7 @@ config COMPAT
 	prompt "Kernel support for 31 bit emulation"
 	depends on 64BIT
 	select COMPAT_BINFMT_ELF
+	select ARCH_WANT_OLD_COMPAT_IPC
 	help
 	  Select this option if you want to enable your system kernel to
 	  handle system-calls from ELF binaries for 31 bit ESA.  This option
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 8a2a887..6a2cb56 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -293,11 +293,9 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
 		return -ENOMEM;
 	root_inode->i_op = &simple_dir_inode_operations;
 	root_inode->i_fop = &simple_dir_operations;
-	sb->s_root = root_dentry = d_alloc_root(root_inode);
-	if (!root_dentry) {
-		iput(root_inode);
+	sb->s_root = root_dentry = d_make_root(root_inode);
+	if (!root_dentry)
 		return -ENOMEM;
-	}
 	if (MACHINE_IS_VM)
 		rc = hypfs_vm_create_files(sb, root_dentry);
 	else
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h
index c23c390..24ef186 100644
--- a/arch/s390/include/asm/cputime.h
+++ b/arch/s390/include/asm/cputime.h
@@ -170,24 +170,17 @@ struct s390_idle_data {
 	unsigned int sequence;
 	unsigned long long idle_count;
 	unsigned long long idle_enter;
+	unsigned long long idle_exit;
 	unsigned long long idle_time;
 	int nohz_delay;
 };
 
 DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
 
-void vtime_start_cpu(__u64 int_clock, __u64 enter_timer);
 cputime64_t s390_get_idle_time(int cpu);
 
 #define arch_idle_time(cpu) s390_get_idle_time(cpu)
 
-static inline void s390_idle_check(struct pt_regs *regs, __u64 int_clock,
-				   __u64 enter_timer)
-{
-	if (regs->psw.mask & PSW_MASK_WAIT)
-		vtime_start_cpu(int_clock, enter_timer);
-}
-
 static inline int s390_nohz_delay(int cpu)
 {
 	return __get_cpu_var(s390_idle).nohz_delay != 0;
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h
index e4155d3..510ba9e 100644
--- a/arch/s390/include/asm/hardirq.h
+++ b/arch/s390/include/asm/hardirq.h
@@ -18,6 +18,7 @@
 
 #define __ARCH_IRQ_STAT
 #define __ARCH_HAS_DO_SOFTIRQ
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED
 
 #define HARDIRQ_BITS	8
 
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index ba6d85f..acee180 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -34,7 +34,12 @@ enum interruption_class {
 	NR_IRQS,
 };
 
-typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
+struct ext_code {
+	unsigned short subcode;
+	unsigned short code;
+};
+
+typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long);
 
 int register_external_interrupt(u16 code, ext_int_handler_t handler);
 int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 707f230..4e69563 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp. 1999,2010
+ *    Copyright IBM Corp. 1999,2012
  *    Author(s): Hartmut Penner <hp@de.ibm.com>,
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
  *		 Denis Joseph Barrow,
@@ -12,14 +12,6 @@
 #include <asm/ptrace.h>
 #include <asm/cpu.h>
 
-void restart_int_handler(void);
-void ext_int_handler(void);
-void system_call(void);
-void pgm_check_handler(void);
-void mcck_int_handler(void);
-void io_int_handler(void);
-void psw_restart_int_handler(void);
-
 #ifdef CONFIG_32BIT
 
 #define LC_ORDER 0
@@ -56,7 +48,7 @@ struct _lowcore {
 	psw_t	mcck_new_psw;			/* 0x0070 */
 	psw_t	io_new_psw;			/* 0x0078 */
 	__u32	ext_params;			/* 0x0080 */
-	__u16	cpu_addr;			/* 0x0084 */
+	__u16	ext_cpu_addr;			/* 0x0084 */
 	__u16	ext_int_code;			/* 0x0086 */
 	__u16	svc_ilc;			/* 0x0088 */
 	__u16	svc_code;			/* 0x008a */
@@ -117,32 +109,37 @@ struct _lowcore {
 	__u64	steal_timer;			/* 0x0288 */
 	__u64	last_update_timer;		/* 0x0290 */
 	__u64	last_update_clock;		/* 0x0298 */
+	__u64	int_clock;			/* 0x02a0 */
+	__u64	mcck_clock;			/* 0x02a8 */
+	__u64	clock_comparator;		/* 0x02b0 */
 
 	/* Current process. */
-	__u32	current_task;			/* 0x02a0 */
-	__u32	thread_info;			/* 0x02a4 */
-	__u32	kernel_stack;			/* 0x02a8 */
+	__u32	current_task;			/* 0x02b8 */
+	__u32	thread_info;			/* 0x02bc */
+	__u32	kernel_stack;			/* 0x02c0 */
+
+	/* Interrupt, panic and restart stack. */
+	__u32	async_stack;			/* 0x02c4 */
+	__u32	panic_stack;			/* 0x02c8 */
+	__u32	restart_stack;			/* 0x02cc */
 
-	/* Interrupt and panic stack. */
-	__u32	async_stack;			/* 0x02ac */
-	__u32	panic_stack;			/* 0x02b0 */
+	/* Restart function and parameter. */
+	__u32	restart_fn;			/* 0x02d0 */
+	__u32	restart_data;			/* 0x02d4 */
+	__u32	restart_source;			/* 0x02d8 */
 
 	/* Address space pointer. */
-	__u32	kernel_asce;			/* 0x02b4 */
-	__u32	user_asce;			/* 0x02b8 */
-	__u32	current_pid;			/* 0x02bc */
+	__u32	kernel_asce;			/* 0x02dc */
+	__u32	user_asce;			/* 0x02e0 */
+	__u32	current_pid;			/* 0x02e4 */
 
 	/* SMP info area */
-	__u32	cpu_nr;				/* 0x02c0 */
-	__u32	softirq_pending;		/* 0x02c4 */
-	__u32	percpu_offset;			/* 0x02c8 */
-	__u32	ext_call_fast;			/* 0x02cc */
-	__u64	int_clock;			/* 0x02d0 */
-	__u64	mcck_clock;			/* 0x02d8 */
-	__u64	clock_comparator;		/* 0x02e0 */
-	__u32	machine_flags;			/* 0x02e8 */
-	__u32	ftrace_func;			/* 0x02ec */
-	__u8	pad_0x02f8[0x0300-0x02f0];	/* 0x02f0 */
+	__u32	cpu_nr;				/* 0x02e8 */
+	__u32	softirq_pending;		/* 0x02ec */
+	__u32	percpu_offset;			/* 0x02f0 */
+	__u32	machine_flags;			/* 0x02f4 */
+	__u32	ftrace_func;			/* 0x02f8 */
+	__u8	pad_0x02fc[0x0300-0x02fc];	/* 0x02fc */
 
 	/* Interrupt response block */
 	__u8	irb[64];			/* 0x0300 */
@@ -189,7 +186,7 @@ struct _lowcore {
 	__u32	ipl_parmblock_ptr;		/* 0x0014 */
 	__u8	pad_0x0018[0x0080-0x0018];	/* 0x0018 */
 	__u32	ext_params;			/* 0x0080 */
-	__u16	cpu_addr;			/* 0x0084 */
+	__u16	ext_cpu_addr;			/* 0x0084 */
 	__u16	ext_int_code;			/* 0x0086 */
 	__u16	svc_ilc;			/* 0x0088 */
 	__u16	svc_code;			/* 0x008a */
@@ -254,34 +251,39 @@ struct _lowcore {
 	__u64	steal_timer;			/* 0x02e0 */
 	__u64	last_update_timer;		/* 0x02e8 */
 	__u64	last_update_clock;		/* 0x02f0 */
+	__u64	int_clock;			/* 0x02f8 */
+	__u64	mcck_clock;			/* 0x0300 */
+	__u64	clock_comparator;		/* 0x0308 */
 
 	/* Current process. */
-	__u64	current_task;			/* 0x02f8 */
-	__u64	thread_info;			/* 0x0300 */
-	__u64	kernel_stack;			/* 0x0308 */
+	__u64	current_task;			/* 0x0310 */
+	__u64	thread_info;			/* 0x0318 */
+	__u64	kernel_stack;			/* 0x0320 */
+
+	/* Interrupt, panic and restart stack. */
+	__u64	async_stack;			/* 0x0328 */
+	__u64	panic_stack;			/* 0x0330 */
+	__u64	restart_stack;			/* 0x0338 */
 
-	/* Interrupt and panic stack. */
-	__u64	async_stack;			/* 0x0310 */
-	__u64	panic_stack;			/* 0x0318 */
+	/* Restart function and parameter. */
+	__u64	restart_fn;			/* 0x0340 */
+	__u64	restart_data;			/* 0x0348 */
+	__u64	restart_source;			/* 0x0350 */
 
 	/* Address space pointer. */
-	__u64	kernel_asce;			/* 0x0320 */
-	__u64	user_asce;			/* 0x0328 */
-	__u64	current_pid;			/* 0x0330 */
+	__u64	kernel_asce;			/* 0x0358 */
+	__u64	user_asce;			/* 0x0360 */
+	__u64	current_pid;			/* 0x0368 */
 
 	/* SMP info area */
-	__u32	cpu_nr;				/* 0x0338 */
-	__u32	softirq_pending;		/* 0x033c */
-	__u64	percpu_offset;			/* 0x0340 */
-	__u64	ext_call_fast;			/* 0x0348 */
-	__u64	int_clock;			/* 0x0350 */
-	__u64	mcck_clock;			/* 0x0358 */
-	__u64	clock_comparator;		/* 0x0360 */
-	__u64	vdso_per_cpu_data;		/* 0x0368 */
-	__u64	machine_flags;			/* 0x0370 */
-	__u64	ftrace_func;			/* 0x0378 */
-	__u64	gmap;				/* 0x0380 */
-	__u8	pad_0x0388[0x0400-0x0388];	/* 0x0388 */
+	__u32	cpu_nr;				/* 0x0370 */
+	__u32	softirq_pending;		/* 0x0374 */
+	__u64	percpu_offset;			/* 0x0378 */
+	__u64	vdso_per_cpu_data;		/* 0x0380 */
+	__u64	machine_flags;			/* 0x0388 */
+	__u64	ftrace_func;			/* 0x0390 */
+	__u64	gmap;				/* 0x0398 */
+	__u8	pad_0x03a0[0x0400-0x03a0];	/* 0x03a0 */
 
 	/* Interrupt response block. */
 	__u8	irb[64];			/* 0x0400 */
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h
index a75f168..4eb444e 100644
--- a/arch/s390/include/asm/perf_event.h
+++ b/arch/s390/include/asm/perf_event.h
@@ -6,4 +6,3 @@
 
 /* Empty, just to avoid compiling error */
 
-#define PERF_EVENT_INDEX_OFFSET 0
diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/asm/posix_types.h
index 8cc113f..edf8527 100644
--- a/arch/s390/include/asm/posix_types.h
+++ b/arch/s390/include/asm/posix_types.h
@@ -3,7 +3,6 @@
  *
  *  S390 version
  *
- *  Derived from "include/asm-i386/posix_types.h"
  */
 
 #ifndef __ARCH_S390_POSIX_TYPES_H
@@ -15,22 +14,11 @@
  * assume GCC is being used.
  */
 
-typedef long            __kernel_off_t;
-typedef int             __kernel_pid_t;
 typedef unsigned long   __kernel_size_t;
-typedef long            __kernel_time_t;
-typedef long            __kernel_suseconds_t;
-typedef long            __kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int             __kernel_daddr_t;
-typedef char *          __kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
+#define __kernel_size_t __kernel_size_t
 
-#ifdef __GNUC__
-typedef long long       __kernel_loff_t;
-#endif
+typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
 #ifndef __s390x__
 
@@ -42,11 +30,6 @@ typedef unsigned short  __kernel_uid_t;
 typedef unsigned short  __kernel_gid_t;
 typedef int             __kernel_ssize_t;
 typedef int             __kernel_ptrdiff_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
-typedef unsigned short	__kernel_old_dev_t;
 
 #else /* __s390x__ */
 
@@ -59,49 +42,16 @@ typedef unsigned int    __kernel_gid_t;
 typedef long            __kernel_ssize_t;
 typedef long            __kernel_ptrdiff_t;
 typedef unsigned long   __kernel_sigset_t;      /* at least 32 bits */
-typedef __kernel_uid_t __kernel_old_uid_t;
-typedef __kernel_gid_t __kernel_old_gid_t;
-typedef __kernel_uid_t __kernel_uid32_t;
-typedef __kernel_gid_t __kernel_gid32_t;
-typedef unsigned short __kernel_old_dev_t;
 
 #endif /* __s390x__ */
 
-typedef struct {
-        int     val[2];
-} __kernel_fsid_t;
-
-
-#ifdef __KERNEL__
-
-#undef __FD_SET
-static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static inline int __FD_ISSET(unsigned long fd, const __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (fdsetp->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-#undef  __FD_ZERO
-#define __FD_ZERO(fdsetp) \
-	((void) memset ((void *) (fdsetp), 0, sizeof (__kernel_fd_set)))
+#define __kernel_ino_t  __kernel_ino_t
+#define __kernel_mode_t __kernel_mode_t
+#define __kernel_nlink_t __kernel_nlink_t
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+#define __kernel_uid_t __kernel_uid_t
+#define __kernel_gid_t __kernel_gid_t
 
-#endif     /* __KERNEL__ */
+#include <asm-generic/posix_types.h>
 
 #endif
diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/asm/qeth.h
index 90efda0..2c7c898 100644
--- a/arch/s390/include/asm/qeth.h
+++ b/arch/s390/include/asm/qeth.h
@@ -20,6 +20,7 @@
 #define SIOC_QETH_ARP_FLUSH_CACHE       (SIOCDEVPRIVATE + 4)
 #define SIOC_QETH_ADP_SET_SNMP_CONTROL  (SIOCDEVPRIVATE + 5)
 #define SIOC_QETH_GET_CARD_TYPE         (SIOCDEVPRIVATE + 6)
+#define SIOC_QETH_QUERY_OAT		(SIOCDEVPRIVATE + 7)
 
 struct qeth_arp_cache_entry {
 	__u8  macaddr[6];
@@ -107,4 +108,10 @@ struct qeth_arp_query_user_data {
 	char *entries;
 } __attribute__((packed));
 
+struct qeth_query_oat_data {
+	__u32 command;
+	__u32 buffer_len;
+	__u32 response_len;
+	__u64 ptr;
+};
 #endif /* __ASM_S390_QETH_IOCTL_H__ */
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
deleted file mode 100644
index 7040b85..0000000
--- a/arch/s390/include/asm/sigp.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *  Routines and structures for signalling other processors.
- *
- *    Copyright IBM Corp. 1999,2010
- *    Author(s): Denis Joseph Barrow,
- *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
- *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
- */
-
-#ifndef __ASM_SIGP_H
-#define __ASM_SIGP_H
-
-#include <asm/system.h>
-
-/* Get real cpu address from logical cpu number. */
-extern unsigned short __cpu_logical_map[];
-
-static inline int cpu_logical_map(int cpu)
-{
-#ifdef CONFIG_SMP
-	return __cpu_logical_map[cpu];
-#else
-	return stap();
-#endif
-}
-
-enum {
-	sigp_sense = 1,
-	sigp_external_call = 2,
-	sigp_emergency_signal = 3,
-	sigp_start = 4,
-	sigp_stop = 5,
-	sigp_restart = 6,
-	sigp_stop_and_store_status = 9,
-	sigp_initial_cpu_reset = 11,
-	sigp_cpu_reset = 12,
-	sigp_set_prefix = 13,
-	sigp_store_status_at_address = 14,
-	sigp_store_extended_status_at_address = 15,
-	sigp_set_architecture = 18,
-	sigp_conditional_emergency_signal = 19,
-	sigp_sense_running = 21,
-};
-
-enum {
-	sigp_order_code_accepted = 0,
-	sigp_status_stored = 1,
-	sigp_busy = 2,
-	sigp_not_operational = 3,
-};
-
-/*
- * Definitions for external call.
- */
-enum {
-	ec_schedule = 0,
-	ec_call_function,
-	ec_call_function_single,
-	ec_stop_cpu,
-};
-
-/*
- * Signal processor.
- */
-static inline int raw_sigp(u16 cpu, int order)
-{
-	register unsigned long reg1 asm ("1") = 0;
-	int ccode;
-
-	asm volatile(
-		"	sigp	%1,%2,0(%3)\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		:	"=d"	(ccode)
-		: "d" (reg1), "d" (cpu),
-		  "a" (order) : "cc" , "memory");
-	return ccode;
-}
-
-/*
- * Signal processor with parameter.
- */
-static inline int raw_sigp_p(u32 parameter, u16 cpu, int order)
-{
-	register unsigned int reg1 asm ("1") = parameter;
-	int ccode;
-
-	asm volatile(
-		"	sigp	%1,%2,0(%3)\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (ccode)
-		: "d" (reg1), "d" (cpu),
-		  "a" (order) : "cc" , "memory");
-	return ccode;
-}
-
-/*
- * Signal processor with parameter and return status.
- */
-static inline int raw_sigp_ps(u32 *status, u32 parm, u16 cpu, int order)
-{
-	register unsigned int reg1 asm ("1") = parm;
-	int ccode;
-
-	asm volatile(
-		"	sigp	%1,%2,0(%3)\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (ccode), "+d" (reg1)
-		: "d" (cpu), "a" (order)
-		: "cc" , "memory");
-	*status = reg1;
-	return ccode;
-}
-
-static inline int sigp(int cpu, int order)
-{
-	return raw_sigp(cpu_logical_map(cpu), order);
-}
-
-static inline int sigp_p(u32 parameter, int cpu, int order)
-{
-	return raw_sigp_p(parameter, cpu_logical_map(cpu), order);
-}
-
-static inline int sigp_ps(u32 *status, u32 parm, int cpu, int order)
-{
-	return raw_sigp_ps(status, parm, cpu_logical_map(cpu), order);
-}
-
-#endif /* __ASM_SIGP_H */
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index c32e912..797f787 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp. 1999,2009
+ *    Copyright IBM Corp. 1999,2012
  *    Author(s): Denis Joseph Barrow,
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
  *		 Heiko Carstens <heiko.carstens@de.ibm.com>,
@@ -10,71 +10,52 @@
 #ifdef CONFIG_SMP
 
 #include <asm/system.h>
-#include <asm/sigp.h>
-
-extern void machine_restart_smp(char *);
-extern void machine_halt_smp(void);
-extern void machine_power_off_smp(void);
 
 #define raw_smp_processor_id()	(S390_lowcore.cpu_nr)
 
-extern int __cpu_disable (void);
-extern void __cpu_die (unsigned int cpu);
-extern int __cpu_up (unsigned int cpu);
-
 extern struct mutex smp_cpu_state_mutex;
+extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
+
+extern int __cpu_up(unsigned int cpu);
 
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
-extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
-
-extern void smp_switch_to_ipl_cpu(void (*func)(void *), void *);
-extern void smp_switch_to_cpu(void (*)(void *), void *, unsigned long sp,
-			      int from, int to);
-extern void smp_restart_with_online_cpu(void);
-extern void smp_restart_cpu(void);
+extern void smp_call_online_cpu(void (*func)(void *), void *);
+extern void smp_call_ipl_cpu(void (*func)(void *), void *);
 
-/*
- * returns 1 if (virtual) cpu is scheduled
- * returns 0 otherwise
- */
-static inline int smp_vcpu_scheduled(int cpu)
-{
-	u32 status;
-
-	switch (sigp_ps(&status, 0, cpu, sigp_sense_running)) {
-	case sigp_status_stored:
-		/* Check for running status */
-		if (status & 0x400)
-			return 0;
-		break;
-	case sigp_not_operational:
-		return 0;
-	default:
-		break;
-	}
-	return 1;
-}
+extern int smp_find_processor_id(u16 address);
+extern int smp_store_status(int cpu);
+extern int smp_vcpu_scheduled(int cpu);
+extern void smp_yield_cpu(int cpu);
+extern void smp_yield(void);
+extern void smp_stop_cpu(void);
 
 #else /* CONFIG_SMP */
 
-static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
+static inline void smp_call_ipl_cpu(void (*func)(void *), void *data)
 {
 	func(data);
 }
 
-static inline void smp_restart_with_online_cpu(void)
+static inline void smp_call_online_cpu(void (*func)(void *), void *data)
 {
+	func(data);
 }
 
-#define smp_vcpu_scheduled	(1)
+static inline int smp_find_processor_id(int address) { return 0; }
+static inline int smp_vcpu_scheduled(int cpu) { return 1; }
+static inline void smp_yield_cpu(int cpu) { }
+static inline void smp_yield(void) { }
+static inline void smp_stop_cpu(void) { }
 
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_HOTPLUG_CPU
 extern int smp_rescan_cpus(void);
 extern void __noreturn cpu_die(void);
+extern void __cpu_die(unsigned int cpu);
+extern int __cpu_disable(void);
 #else
 static inline int smp_rescan_cpus(void) { return 0; }
 static inline void cpu_die(void) { }
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index 67b5c1b..581702f 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -72,5 +72,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/s390/include/asm/timer.h b/arch/s390/include/asm/timer.h
index 814243c..e63069b 100644
--- a/arch/s390/include/asm/timer.h
+++ b/arch/s390/include/asm/timer.h
@@ -33,8 +33,8 @@ struct vtimer_queue {
 	spinlock_t lock;
 	__u64 timer;		/* last programmed timer */
 	__u64 elapsed;		/* elapsed time of timer expire values */
-	__u64 idle;		/* temp var for idle */
-	int do_spt;		/* =1: reprogram cpu timer in idle */
+	__u64 idle_enter;	/* cpu timer on idle enter */
+	__u64 idle_exit;	/* cpu timer on idle exit */
 };
 
 extern void init_virt_timer(struct vtimer_list *timer);
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h
index 533f357..c4a11cf 100644
--- a/arch/s390/include/asm/vdso.h
+++ b/arch/s390/include/asm/vdso.h
@@ -40,8 +40,8 @@ struct vdso_per_cpu_data {
 extern struct vdso_data *vdso_data;
 
 #ifdef CONFIG_64BIT
-int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore);
-void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore);
+int vdso_alloc_per_cpu(struct _lowcore *lowcore);
+void vdso_free_per_cpu(struct _lowcore *lowcore);
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 7d9ec92..d0a4826 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -34,8 +34,6 @@ extra-y				+= $(if $(CONFIG_64BIT),head64.o,head31.o)
 obj-$(CONFIG_MODULES)		+= s390_ksyms.o module.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SCHED_BOOK)	+= topology.o
-obj-$(CONFIG_SMP)		+= $(if $(CONFIG_64BIT),switch_cpu64.o, \
-							switch_cpu.o)
 obj-$(CONFIG_HIBERNATION)	+= suspend.o swsusp_asm64.o
 obj-$(CONFIG_AUDIT)		+= audit.o
 compat-obj-$(CONFIG_AUDIT)	+= compat_audit.o
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 6e6a72e..ed8c913 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -8,9 +8,11 @@
 
 #include <linux/kbuild.h>
 #include <linux/sched.h>
+#include <asm/cputime.h>
+#include <asm/timer.h>
 #include <asm/vdso.h>
-#include <asm/sigp.h>
 #include <asm/pgtable.h>
+#include <asm/system.h>
 
 /*
  * Make sure that the compiler is new enough. We want a compiler that
@@ -70,15 +72,15 @@ int main(void)
 	DEFINE(__CLOCK_MONOTONIC, CLOCK_MONOTONIC);
 	DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
 	BLANK();
-	/* constants for SIGP */
-	DEFINE(__SIGP_STOP, sigp_stop);
-	DEFINE(__SIGP_RESTART, sigp_restart);
-	DEFINE(__SIGP_SENSE, sigp_sense);
-	DEFINE(__SIGP_INITIAL_CPU_RESET, sigp_initial_cpu_reset);
-	BLANK();
+	/* idle data offsets */
+	DEFINE(__IDLE_ENTER, offsetof(struct s390_idle_data, idle_enter));
+	DEFINE(__IDLE_EXIT, offsetof(struct s390_idle_data, idle_exit));
+	/* vtimer queue offsets */
+	DEFINE(__VQ_IDLE_ENTER, offsetof(struct vtimer_queue, idle_enter));
+	DEFINE(__VQ_IDLE_EXIT, offsetof(struct vtimer_queue, idle_exit));
 	/* lowcore offsets */
 	DEFINE(__LC_EXT_PARAMS, offsetof(struct _lowcore, ext_params));
-	DEFINE(__LC_CPU_ADDRESS, offsetof(struct _lowcore, cpu_addr));
+	DEFINE(__LC_EXT_CPU_ADDR, offsetof(struct _lowcore, ext_cpu_addr));
 	DEFINE(__LC_EXT_INT_CODE, offsetof(struct _lowcore, ext_int_code));
 	DEFINE(__LC_SVC_ILC, offsetof(struct _lowcore, svc_ilc));
 	DEFINE(__LC_SVC_INT_CODE, offsetof(struct _lowcore, svc_code));
@@ -95,20 +97,19 @@ int main(void)
 	DEFINE(__LC_IO_INT_WORD, offsetof(struct _lowcore, io_int_word));
 	DEFINE(__LC_STFL_FAC_LIST, offsetof(struct _lowcore, stfl_fac_list));
 	DEFINE(__LC_MCCK_CODE, offsetof(struct _lowcore, mcck_interruption_code));
-	DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
-	BLANK();
-	DEFINE(__LC_RST_NEW_PSW, offsetof(struct _lowcore, restart_psw));
 	DEFINE(__LC_RST_OLD_PSW, offsetof(struct _lowcore, restart_old_psw));
 	DEFINE(__LC_EXT_OLD_PSW, offsetof(struct _lowcore, external_old_psw));
 	DEFINE(__LC_SVC_OLD_PSW, offsetof(struct _lowcore, svc_old_psw));
 	DEFINE(__LC_PGM_OLD_PSW, offsetof(struct _lowcore, program_old_psw));
 	DEFINE(__LC_MCK_OLD_PSW, offsetof(struct _lowcore, mcck_old_psw));
 	DEFINE(__LC_IO_OLD_PSW, offsetof(struct _lowcore, io_old_psw));
+	DEFINE(__LC_RST_NEW_PSW, offsetof(struct _lowcore, restart_psw));
 	DEFINE(__LC_EXT_NEW_PSW, offsetof(struct _lowcore, external_new_psw));
 	DEFINE(__LC_SVC_NEW_PSW, offsetof(struct _lowcore, svc_new_psw));
 	DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
 	DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
 	DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
+	BLANK();
 	DEFINE(__LC_SAVE_AREA_SYNC, offsetof(struct _lowcore, save_area_sync));
 	DEFINE(__LC_SAVE_AREA_ASYNC, offsetof(struct _lowcore, save_area_async));
 	DEFINE(__LC_SAVE_AREA_RESTART, offsetof(struct _lowcore, save_area_restart));
@@ -129,12 +130,16 @@ int main(void)
 	DEFINE(__LC_KERNEL_STACK, offsetof(struct _lowcore, kernel_stack));
 	DEFINE(__LC_ASYNC_STACK, offsetof(struct _lowcore, async_stack));
 	DEFINE(__LC_PANIC_STACK, offsetof(struct _lowcore, panic_stack));
+	DEFINE(__LC_RESTART_STACK, offsetof(struct _lowcore, restart_stack));
+	DEFINE(__LC_RESTART_FN, offsetof(struct _lowcore, restart_fn));
 	DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
 	DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
 	DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
 	DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
 	DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
 	DEFINE(__LC_IRB, offsetof(struct _lowcore, irb));
+	DEFINE(__LC_DUMP_REIPL, offsetof(struct _lowcore, ipib));
+	BLANK();
 	DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
 	DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
 	DEFINE(__LC_PSW_SAVE_AREA, offsetof(struct _lowcore, psw_save_area));
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 6fe78c2..53a82c8 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -581,7 +581,6 @@ give_sigsegv:
 int handle_signal32(unsigned long sig, struct k_sigaction *ka,
 		    siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
-	sigset_t blocked;
 	int ret;
 
 	/* Set up the stack frame */
@@ -591,10 +590,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
 		ret = setup_frame32(sig, ka, oldset, regs);
 	if (ret)
 		return ret;
-	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&blocked, sig);
-	set_current_blocked(&blocked);
+	block_sigmask(ka, sig);
 	return 0;
 }
 
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 3705700..b533f44 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/entry.S
  *    S390 low-level entry points.
  *
- *    Copyright (C) IBM Corp. 1999,2006
+ *    Copyright (C) IBM Corp. 1999,2012
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *		 Hartmut Penner (hp@de.ibm.com),
  *		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
@@ -105,14 +105,14 @@ STACK_SIZE  = 1 << STACK_SHIFT
 
 	.macro	ADD64 high,low,timer
 	al	\high,\timer
-	al	\low,\timer+4
+	al	\low,4+\timer
 	brc	12,.+8
 	ahi	\high,1
 	.endm
 
 	.macro	SUB64 high,low,timer
 	sl	\high,\timer
-	sl	\low,\timer+4
+	sl	\low,4+\timer
 	brc	3,.+8
 	ahi	\high,-1
 	.endm
@@ -471,7 +471,6 @@ io_tif:
 	jnz	io_work			# there is work to do (signals etc.)
 io_restore:
 	mvc	__LC_RETURN_PSW(8),__PT_PSW(%r11)
-	ni	__LC_RETURN_PSW+1,0xfd	# clean wait state bit
 	stpt	__LC_EXIT_TIMER
 	lm	%r0,%r15,__PT_R0(%r11)
 	lpsw	__LC_RETURN_PSW
@@ -606,12 +605,32 @@ ext_skip:
 	stm	%r8,%r9,__PT_PSW(%r11)
 	TRACE_IRQS_OFF
 	lr	%r2,%r11		# pass pointer to pt_regs
-	l	%r3,__LC_CPU_ADDRESS	# get cpu address + interruption code
+	l	%r3,__LC_EXT_CPU_ADDR	# get cpu address + interruption code
 	l	%r4,__LC_EXT_PARAMS	# get external parameters
 	l	%r1,BASED(.Ldo_extint)
 	basr	%r14,%r1		# call do_extint
 	j	io_return
 
+/*
+ * Load idle PSW. The second "half" of this function is in cleanup_idle.
+ */
+ENTRY(psw_idle)
+	st	%r4,__SF_EMPTY(%r15)
+	basr	%r1,0
+	la	%r1,psw_idle_lpsw+4-.(%r1)
+	st	%r1,__SF_EMPTY+4(%r15)
+	oi	__SF_EMPTY+4(%r15),0x80
+	la	%r1,.Lvtimer_max-psw_idle_lpsw-4(%r1)
+	stck	__IDLE_ENTER(%r2)
+	ltr	%r5,%r5
+	stpt	__VQ_IDLE_ENTER(%r3)
+	jz	psw_idle_lpsw
+	spt	0(%r1)
+psw_idle_lpsw:
+	lpsw	__SF_EMPTY(%r15)
+	br	%r14
+psw_idle_end:
+
 __critical_end:
 
 /*
@@ -673,7 +692,6 @@ mcck_skip:
 	TRACE_IRQS_ON
 mcck_return:
 	mvc	__LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
-	ni	__LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
 	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
 	jno	0f
 	lm	%r0,%r15,__PT_R0(%r11)
@@ -691,77 +709,29 @@ mcck_panic:
 0:	ahi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
 	j	mcck_skip
 
-/*
- * Restart interruption handler, kick starter for additional CPUs
- */
-#ifdef CONFIG_SMP
-	__CPUINIT
-ENTRY(restart_int_handler)
-	basr	%r1,0
-restart_base:
-	spt	restart_vtime-restart_base(%r1)
-	stck	__LC_LAST_UPDATE_CLOCK
-	mvc	__LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
-	mvc	__LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
-	l	%r15,__LC_GPREGS_SAVE_AREA+60 # load ksp
-	lctl	%c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
-	lam	%a0,%a15,__LC_AREGS_SAVE_AREA
-	lm	%r6,%r15,__SF_GPRS(%r15)# load registers from clone
-	l	%r1,__LC_THREAD_INFO
-	mvc	__LC_USER_TIMER(8),__TI_user_timer(%r1)
-	mvc	__LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
-	xc	__LC_STEAL_TIMER(8),__LC_STEAL_TIMER
-	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
-	basr	%r14,0
-	l	%r14,restart_addr-.(%r14)
-	basr	%r14,%r14		# call start_secondary
-restart_addr:
-	.long	start_secondary
-	.align	8
-restart_vtime:
-	.long	0x7fffffff,0xffffffff
-	.previous
-#else
-/*
- * If we do not run with SMP enabled, let the new CPU crash ...
- */
-ENTRY(restart_int_handler)
-	basr	%r1,0
-restart_base:
-	lpsw	restart_crash-restart_base(%r1)
-	.align	8
-restart_crash:
-	.long	0x000a0000,0x00000000
-restart_go:
-#endif
-
 #
 # PSW restart interrupt handler
 #
-ENTRY(psw_restart_int_handler)
+ENTRY(restart_int_handler)
 	st	%r15,__LC_SAVE_AREA_RESTART
-	basr	%r15,0
-0:	l	%r15,.Lrestart_stack-0b(%r15)	# load restart stack
-	l	%r15,0(%r15)
+	l	%r15,__LC_RESTART_STACK
 	ahi	%r15,-__PT_SIZE			# create pt_regs on stack
+	xc	0(__PT_SIZE,%r15),0(%r15)
 	stm	%r0,%r14,__PT_R0(%r15)
 	mvc	__PT_R15(4,%r15),__LC_SAVE_AREA_RESTART
 	mvc	__PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw
-	ahi	%r15,-STACK_FRAME_OVERHEAD
-	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
-	basr	%r14,0
-1:	l	%r14,.Ldo_restart-1b(%r14)
-	basr	%r14,%r14
-	basr	%r14,0				# load disabled wait PSW if
-2:	lpsw	restart_psw_crash-2b(%r14)	# do_restart returns
-	.align 4
-.Ldo_restart:
-	.long	do_restart
-.Lrestart_stack:
-	.long	restart_stack
-	.align 8
-restart_psw_crash:
-	.long	0x000a0000,0x00000000 + restart_psw_crash
+	ahi	%r15,-STACK_FRAME_OVERHEAD	# create stack frame on stack
+	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
+	lm	%r1,%r3,__LC_RESTART_FN		# load fn, parm & source cpu
+	ltr	%r3,%r3				# test source cpu address
+	jm	1f				# negative -> skip source stop
+0:	sigp	%r4,%r3,1			# sigp sense to source cpu
+	brc	10,0b				# wait for status stored
+1:	basr	%r14,%r1			# call function
+	stap	__SF_EMPTY(%r15)		# store cpu address
+	lh	%r3,__SF_EMPTY(%r15)
+2:	sigp	%r4,%r3,5			# sigp stop to current cpu
+	brc	2,2b
 
 	.section .kprobes.text, "ax"
 
@@ -795,6 +765,8 @@ cleanup_table:
 	.long	io_tif + 0x80000000
 	.long	io_restore + 0x80000000
 	.long	io_done + 0x80000000
+	.long	psw_idle + 0x80000000
+	.long	psw_idle_end + 0x80000000
 
 cleanup_critical:
 	cl	%r9,BASED(cleanup_table)	# system_call
@@ -813,6 +785,10 @@ cleanup_critical:
 	jl	cleanup_io_tif
 	cl	%r9,BASED(cleanup_table+28)	# io_done
 	jl	cleanup_io_restore
+	cl	%r9,BASED(cleanup_table+32)	# psw_idle
+	jl	0f
+	cl	%r9,BASED(cleanup_table+36)	# psw_idle_end
+	jl	cleanup_idle
 0:	br	%r14
 
 cleanup_system_call:
@@ -896,7 +872,6 @@ cleanup_io_restore:
 	jhe	0f
 	l	%r9,12(%r11)		# get saved r11 pointer to pt_regs
 	mvc	__LC_RETURN_PSW(8),__PT_PSW(%r9)
-	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit
 	mvc	0(32,%r11),__PT_R8(%r9)
 	lm	%r0,%r7,__PT_R0(%r9)
 0:	lm	%r8,%r9,__LC_RETURN_PSW
@@ -904,11 +879,52 @@ cleanup_io_restore:
 cleanup_io_restore_insn:
 	.long	io_done - 4 + 0x80000000
 
+cleanup_idle:
+	# copy interrupt clock & cpu timer
+	mvc	__IDLE_EXIT(8,%r2),__LC_INT_CLOCK
+	mvc	__VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER
+	chi	%r11,__LC_SAVE_AREA_ASYNC
+	je	0f
+	mvc	__IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
+	mvc	__VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER
+0:	# check if stck has been executed
+	cl	%r9,BASED(cleanup_idle_insn)
+	jhe	1f
+	mvc	__IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2)
+	mvc	__VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3)
+	j	2f
+1:	# check if the cpu timer has been reprogrammed
+	ltr	%r5,%r5
+	jz	2f
+	spt	__VQ_IDLE_ENTER(%r3)
+2:	# account system time going idle
+	lm	%r9,%r10,__LC_STEAL_TIMER
+	ADD64	%r9,%r10,__IDLE_ENTER(%r2)
+	SUB64	%r9,%r10,__LC_LAST_UPDATE_CLOCK
+	stm	%r9,%r10,__LC_STEAL_TIMER
+	mvc	__LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2)
+	lm	%r9,%r10,__LC_SYSTEM_TIMER
+	ADD64	%r9,%r10,__LC_LAST_UPDATE_TIMER
+	SUB64	%r9,%r10,__VQ_IDLE_ENTER(%r3)
+	stm	%r9,%r10,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3)
+	# prepare return psw
+	n	%r8,BASED(cleanup_idle_wait)	# clear wait state bit
+	l	%r9,24(%r11)			# return from psw_idle
+	br	%r14
+cleanup_idle_insn:
+	.long	psw_idle_lpsw + 0x80000000
+cleanup_idle_wait:
+	.long	0xfffdffff
+
 /*
  * Integer constants
  */
 	.align	4
-.Lnr_syscalls:		.long	NR_syscalls
+.Lnr_syscalls:
+	.long	NR_syscalls
+.Lvtimer_max:
+	.quad	0x7fffffffffffffff
 
 /*
  * Symbol constants
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index bf538aa..6cdddac 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -4,11 +4,22 @@
 #include <linux/types.h>
 #include <linux/signal.h>
 #include <asm/ptrace.h>
-
+#include <asm/cputime.h>
+#include <asm/timer.h>
 
 extern void (*pgm_check_table[128])(struct pt_regs *);
 extern void *restart_stack;
 
+void system_call(void);
+void pgm_check_handler(void);
+void ext_int_handler(void);
+void io_int_handler(void);
+void mcck_int_handler(void);
+void restart_int_handler(void);
+void restart_call_handler(void);
+void psw_idle(struct s390_idle_data *, struct vtimer_queue *,
+	      unsigned long, int);
+
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
 asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
 
@@ -24,9 +35,9 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
 		    siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
 void do_notify_resume(struct pt_regs *regs);
 
-void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
+struct ext_code;
+void do_extint(struct pt_regs *regs, struct ext_code, unsigned int, unsigned long);
 void do_restart(void);
-int __cpuinit start_secondary(void *cpuvoid);
 void __init startup_init(void);
 void die(struct pt_regs *regs, const char *str);
 
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 412a7b8..e9da1a5 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/entry64.S
  *    S390 low-level entry points.
  *
- *    Copyright (C) IBM Corp. 1999,2010
+ *    Copyright (C) IBM Corp. 1999,2012
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *		 Hartmut Penner (hp@de.ibm.com),
  *		 Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
@@ -489,7 +489,6 @@ io_restore:
 	lg	%r14,__LC_VDSO_PER_CPU
 	lmg	%r0,%r10,__PT_R0(%r11)
 	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r11)
-	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit
 	stpt	__LC_EXIT_TIMER
 	mvc	__VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
 	lmg	%r11,%r15,__PT_R11(%r11)
@@ -625,12 +624,30 @@ ext_skip:
 	TRACE_IRQS_OFF
 	lghi	%r1,4096
 	lgr	%r2,%r11		# pass pointer to pt_regs
-	llgf	%r3,__LC_CPU_ADDRESS	# get cpu address + interruption code
+	llgf	%r3,__LC_EXT_CPU_ADDR	# get cpu address + interruption code
 	llgf	%r4,__LC_EXT_PARAMS	# get external parameter
 	lg	%r5,__LC_EXT_PARAMS2-4096(%r1)	# get 64 bit external parameter
 	brasl	%r14,do_extint
 	j	io_return
 
+/*
+ * Load idle PSW. The second "half" of this function is in cleanup_idle.
+ */
+ENTRY(psw_idle)
+	stg	%r4,__SF_EMPTY(%r15)
+	larl	%r1,psw_idle_lpsw+4
+	stg	%r1,__SF_EMPTY+8(%r15)
+	larl	%r1,.Lvtimer_max
+	stck	__IDLE_ENTER(%r2)
+	ltr	%r5,%r5
+	stpt	__VQ_IDLE_ENTER(%r3)
+	jz	psw_idle_lpsw
+	spt	0(%r1)
+psw_idle_lpsw:
+	lpswe	__SF_EMPTY(%r15)
+	br	%r14
+psw_idle_end:
+
 __critical_end:
 
 /*
@@ -696,7 +713,6 @@ mcck_return:
 	lg	%r14,__LC_VDSO_PER_CPU
 	lmg	%r0,%r10,__PT_R0(%r11)
 	mvc	__LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
-	ni	__LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
 	tm	__LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
 	jno	0f
 	stpt	__LC_EXIT_TIMER
@@ -713,68 +729,29 @@ mcck_panic:
 0:	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
 	j	mcck_skip
 
-/*
- * Restart interruption handler, kick starter for additional CPUs
- */
-#ifdef CONFIG_SMP
-	__CPUINIT
-ENTRY(restart_int_handler)
-	basr	%r1,0
-restart_base:
-	spt	restart_vtime-restart_base(%r1)
-	stck	__LC_LAST_UPDATE_CLOCK
-	mvc	__LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
-	mvc	__LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
-	lghi	%r10,__LC_GPREGS_SAVE_AREA
-	lg	%r15,120(%r10)		# load ksp
-	lghi	%r10,__LC_CREGS_SAVE_AREA
-	lctlg	%c0,%c15,0(%r10)	# get new ctl regs
-	lghi	%r10,__LC_AREGS_SAVE_AREA
-	lam	%a0,%a15,0(%r10)
-	lmg	%r6,%r15,__SF_GPRS(%r15)# load registers from clone
-	lg	%r1,__LC_THREAD_INFO
-	mvc	__LC_USER_TIMER(8),__TI_user_timer(%r1)
-	mvc	__LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
-	xc	__LC_STEAL_TIMER(8),__LC_STEAL_TIMER
-	ssm	__LC_PGM_NEW_PSW	# turn dat on, keep irqs off
-	brasl	%r14,start_secondary
-	.align	8
-restart_vtime:
-	.long	0x7fffffff,0xffffffff
-	.previous
-#else
-/*
- * If we do not run with SMP enabled, let the new CPU crash ...
- */
-ENTRY(restart_int_handler)
-	basr	%r1,0
-restart_base:
-	lpswe	restart_crash-restart_base(%r1)
-	.align 8
-restart_crash:
-	.long  0x000a0000,0x00000000,0x00000000,0x00000000
-restart_go:
-#endif
-
 #
 # PSW restart interrupt handler
 #
-ENTRY(psw_restart_int_handler)
+ENTRY(restart_int_handler)
 	stg	%r15,__LC_SAVE_AREA_RESTART
-	larl	%r15,restart_stack		# load restart stack
-	lg	%r15,0(%r15)
+	lg	%r15,__LC_RESTART_STACK
 	aghi	%r15,-__PT_SIZE			# create pt_regs on stack
+	xc	0(__PT_SIZE,%r15),0(%r15)
 	stmg	%r0,%r14,__PT_R0(%r15)
 	mvc	__PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
 	mvc	__PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
-	aghi	%r15,-STACK_FRAME_OVERHEAD
-	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
-	brasl	%r14,do_restart
-	larl	%r14,restart_psw_crash		# load disabled wait PSW if
-	lpswe	0(%r14)				# do_restart returns
-	.align 8
-restart_psw_crash:
-	.quad	0x0002000080000000,0x0000000000000000 + restart_psw_crash
+	aghi	%r15,-STACK_FRAME_OVERHEAD	# create stack frame on stack
+	xc	0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
+	lmg	%r1,%r3,__LC_RESTART_FN		# load fn, parm & source cpu
+	ltgr	%r3,%r3				# test source cpu address
+	jm	1f				# negative -> skip source stop
+0:	sigp	%r4,%r3,1			# sigp sense to source cpu
+	brc	10,0b				# wait for status stored
+1:	basr	%r14,%r1			# call function
+	stap	__SF_EMPTY(%r15)		# store cpu address
+	llgh	%r3,__SF_EMPTY(%r15)
+2:	sigp	%r4,%r3,5			# sigp stop to current cpu
+	brc	2,2b
 
 	.section .kprobes.text, "ax"
 
@@ -808,6 +785,8 @@ cleanup_table:
 	.quad	io_tif
 	.quad	io_restore
 	.quad	io_done
+	.quad	psw_idle
+	.quad	psw_idle_end
 
 cleanup_critical:
 	clg	%r9,BASED(cleanup_table)	# system_call
@@ -826,6 +805,10 @@ cleanup_critical:
 	jl	cleanup_io_tif
 	clg	%r9,BASED(cleanup_table+56)	# io_done
 	jl	cleanup_io_restore
+	clg	%r9,BASED(cleanup_table+64)	# psw_idle
+	jl	0f
+	clg	%r9,BASED(cleanup_table+72)	# psw_idle_end
+	jl	cleanup_idle
 0:	br	%r14
 
 
@@ -915,7 +898,6 @@ cleanup_io_restore:
 	je	0f
 	lg	%r9,24(%r11)		# get saved r11 pointer to pt_regs
 	mvc	__LC_RETURN_PSW(16),__PT_PSW(%r9)
-	ni	__LC_RETURN_PSW+1,0xfd	# clear wait state bit
 	mvc	0(64,%r11),__PT_R8(%r9)
 	lmg	%r0,%r7,__PT_R0(%r9)
 0:	lmg	%r8,%r9,__LC_RETURN_PSW
@@ -923,6 +905,42 @@ cleanup_io_restore:
 cleanup_io_restore_insn:
 	.quad	io_done - 4
 
+cleanup_idle:
+	# copy interrupt clock & cpu timer
+	mvc	__IDLE_EXIT(8,%r2),__LC_INT_CLOCK
+	mvc	__VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER
+	cghi	%r11,__LC_SAVE_AREA_ASYNC
+	je	0f
+	mvc	__IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
+	mvc	__VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER
+0:	# check if stck & stpt have been executed
+	clg	%r9,BASED(cleanup_idle_insn)
+	jhe	1f
+	mvc	__IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2)
+	mvc	__VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3)
+	j	2f
+1:	# check if the cpu timer has been reprogrammed
+	ltr	%r5,%r5
+	jz	2f
+	spt	__VQ_IDLE_ENTER(%r3)
+2:	# account system time going idle
+	lg	%r9,__LC_STEAL_TIMER
+	alg	%r9,__IDLE_ENTER(%r2)
+	slg	%r9,__LC_LAST_UPDATE_CLOCK
+	stg	%r9,__LC_STEAL_TIMER
+	mvc	__LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2)
+	lg	%r9,__LC_SYSTEM_TIMER
+	alg	%r9,__LC_LAST_UPDATE_TIMER
+	slg	%r9,__VQ_IDLE_ENTER(%r3)
+	stg	%r9,__LC_SYSTEM_TIMER
+	mvc	__LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3)
+	# prepare return psw
+	nihh	%r8,0xfffd		# clear wait state bit
+	lg	%r9,48(%r11)		# return from psw_idle
+	br	%r14
+cleanup_idle_insn:
+	.quad	psw_idle_lpsw
+
 /*
  * Integer constants
  */
@@ -931,6 +949,8 @@ cleanup_io_restore_insn:
 	.quad	__critical_start
 .Lcritical_length:
 	.quad	__critical_end - __critical_start
+.Lvtimer_max:
+	.quad	0x7fffffffffffffff
 
 
 #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index affa8e6..9e2f6f7 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/ipl.c
  *    ipl/reipl/dump support for Linux on s390.
  *
- *    Copyright IBM Corp. 2005,2007
+ *    Copyright IBM Corp. 2005,2012
  *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
  *		 Heiko Carstens <heiko.carstens@de.ibm.com>
  *		 Volker Sameske <sameske@de.ibm.com>
@@ -25,7 +25,6 @@
 #include <asm/ebcdic.h>
 #include <asm/reset.h>
 #include <asm/sclp.h>
-#include <asm/sigp.h>
 #include <asm/checksum.h>
 #include "entry.h"
 
@@ -571,7 +570,7 @@ static void __ipl_run(void *unused)
 
 static void ipl_run(struct shutdown_trigger *trigger)
 {
-	smp_switch_to_ipl_cpu(__ipl_run, NULL);
+	smp_call_ipl_cpu(__ipl_run, NULL);
 }
 
 static int __init ipl_init(void)
@@ -1101,7 +1100,7 @@ static void __reipl_run(void *unused)
 
 static void reipl_run(struct shutdown_trigger *trigger)
 {
-	smp_switch_to_ipl_cpu(__reipl_run, NULL);
+	smp_call_ipl_cpu(__reipl_run, NULL);
 }
 
 static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
@@ -1421,7 +1420,7 @@ static void dump_run(struct shutdown_trigger *trigger)
 	if (dump_method == DUMP_METHOD_NONE)
 		return;
 	smp_send_stop();
-	smp_switch_to_ipl_cpu(__dump_run, NULL);
+	smp_call_ipl_cpu(__dump_run, NULL);
 }
 
 static int __init dump_ccw_init(void)
@@ -1499,30 +1498,12 @@ static struct shutdown_action __refdata dump_action = {
 
 static void dump_reipl_run(struct shutdown_trigger *trigger)
 {
-	preempt_disable();
-	/*
-	 * Bypass dynamic address translation (DAT) when storing IPL parameter
-	 * information block address and checksum into the prefix area
-	 * (corresponding to absolute addresses 0-8191).
-	 * When enhanced DAT applies and the STE format control in one,
-	 * the absolute address is formed without prefixing. In this case a
-	 * normal store (stg/st) into the prefix area would no more match to
-	 * absolute addresses 0-8191.
-	 */
-#ifdef CONFIG_64BIT
-	asm volatile("sturg %0,%1"
-		:: "a" ((unsigned long) reipl_block_actual),
-		"a" (&lowcore_ptr[smp_processor_id()]->ipib));
-#else
-	asm volatile("stura %0,%1"
-		:: "a" ((unsigned long) reipl_block_actual),
-		"a" (&lowcore_ptr[smp_processor_id()]->ipib));
-#endif
-	asm volatile("stura %0,%1"
-		:: "a" (csum_partial(reipl_block_actual,
-				     reipl_block_actual->hdr.len, 0)),
-		"a" (&lowcore_ptr[smp_processor_id()]->ipib_checksum));
-	preempt_enable();
+	u32 csum;
+
+	csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
+	copy_to_absolute_zero(&S390_lowcore.ipib_checksum, &csum, sizeof(csum));
+	copy_to_absolute_zero(&S390_lowcore.ipib, &reipl_block_actual,
+			      sizeof(reipl_block_actual));
 	dump_run(trigger);
 }
 
@@ -1623,9 +1604,7 @@ static void stop_run(struct shutdown_trigger *trigger)
 	if (strcmp(trigger->name, ON_PANIC_STR) == 0 ||
 	    strcmp(trigger->name, ON_RESTART_STR) == 0)
 		disabled_wait((unsigned long) __builtin_return_address(0));
-	while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
-		cpu_relax();
-	for (;;);
+	smp_stop_cpu();
 }
 
 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
@@ -1738,9 +1717,8 @@ static ssize_t on_restart_store(struct kobject *kobj,
 static struct kobj_attribute on_restart_attr =
 	__ATTR(on_restart, 0644, on_restart_show, on_restart_store);
 
-void do_restart(void)
+static void __do_restart(void *ignore)
 {
-	smp_restart_with_online_cpu();
 	smp_send_stop();
 #ifdef CONFIG_CRASH_DUMP
 	crash_kexec(NULL);
@@ -1749,6 +1727,11 @@ void do_restart(void)
 	stop_run(&on_restart_trigger);
 }
 
+void do_restart(void)
+{
+	smp_call_online_cpu(__do_restart, NULL);
+}
+
 /* on halt */
 
 static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index b9a7fdd..2429ecd 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -165,13 +165,6 @@ static inline int ext_hash(u16 code)
 	return (code + (code >> 9)) & 0xff;
 }
 
-static void ext_int_hash_update(struct rcu_head *head)
-{
-	struct ext_int_info *p = container_of(head, struct ext_int_info, rcu);
-
-	kfree(p);
-}
-
 int register_external_interrupt(u16 code, ext_int_handler_t handler)
 {
 	struct ext_int_info *p;
@@ -202,38 +195,34 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
 	list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
 		if (p->code == code && p->handler == handler) {
 			list_del_rcu(&p->entry);
-			call_rcu(&p->rcu, ext_int_hash_update);
+			kfree_rcu(p, rcu);
 		}
 	spin_unlock_irqrestore(&ext_int_hash_lock, flags);
 	return 0;
 }
 EXPORT_SYMBOL(unregister_external_interrupt);
 
-void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
+void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code,
 			   unsigned int param32, unsigned long param64)
 {
 	struct pt_regs *old_regs;
-	unsigned short code;
 	struct ext_int_info *p;
 	int index;
 
-	code = (unsigned short) ext_int_code;
 	old_regs = set_irq_regs(regs);
-	s390_idle_check(regs, S390_lowcore.int_clock,
-			S390_lowcore.async_enter_timer);
 	irq_enter();
 	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
 		/* Serve timer interrupts first. */
 		clock_comparator_work();
 	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
-	if (code != 0x1004)
+	if (ext_code.code != 0x1004)
 		__get_cpu_var(s390_idle).nohz_delay = 1;
 
-	index = ext_hash(code);
+	index = ext_hash(ext_code.code);
 	rcu_read_lock();
 	list_for_each_entry_rcu(p, &ext_int_hash[index], entry)
-		if (likely(p->code == code))
-			p->handler(ext_int_code, param32, param64);
+		if (likely(p->code == ext_code.code))
+			p->handler(ext_code, param32, param64);
 	rcu_read_unlock();
 	irq_exit();
 	set_irq_regs(old_regs);
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 47b168f..bf6fbc0 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -49,50 +49,21 @@ static void add_elf_notes(int cpu)
 }
 
 /*
- * Store status of next available physical CPU
- */
-static int store_status_next(int start_cpu, int this_cpu)
-{
-	struct save_area *sa = (void *) 4608 + store_prefix();
-	int cpu, rc;
-
-	for (cpu = start_cpu; cpu < 65536; cpu++) {
-		if (cpu == this_cpu)
-			continue;
-		do {
-			rc = raw_sigp(cpu, sigp_stop_and_store_status);
-		} while (rc == sigp_busy);
-		if (rc != sigp_order_code_accepted)
-			continue;
-		if (sa->pref_reg)
-			return cpu;
-	}
-	return -1;
-}
-
-/*
  * Initialize CPU ELF notes
  */
 void setup_regs(void)
 {
 	unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE;
-	int cpu, this_cpu, phys_cpu = 0, first = 1;
+	int cpu, this_cpu;
 
-	this_cpu = stap();
-
-	if (!S390_lowcore.prefixreg_save_area)
-		first = 0;
+	this_cpu = smp_find_processor_id(stap());
+	add_elf_notes(this_cpu);
 	for_each_online_cpu(cpu) {
-		if (first) {
-			add_elf_notes(cpu);
-			first = 0;
+		if (cpu == this_cpu)
+			continue;
+		if (smp_store_status(cpu))
 			continue;
-		}
-		phys_cpu = store_status_next(phys_cpu, this_cpu);
-		if (phys_cpu == -1)
-			break;
 		add_elf_notes(cpu);
-		phys_cpu++;
 	}
 	/* Copy dump CPU store status info to absolute zero */
 	memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area));
@@ -255,5 +226,5 @@ void machine_kexec(struct kimage *image)
 		return;
 	tracer_disable();
 	smp_send_stop();
-	smp_switch_to_ipl_cpu(__machine_kexec, image);
+	smp_call_ipl_cpu(__machine_kexec, image);
 }
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index 0fd2e86..8c372ca 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -254,8 +254,6 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
 	int umode;
 
 	nmi_enter();
-	s390_idle_check(regs, S390_lowcore.mcck_clock,
-			S390_lowcore.mcck_enter_timer);
 	kstat_cpu(smp_processor_id()).irqs[NMI_NMI]++;
 	mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
 	mcck = &__get_cpu_var(cpu_mcck);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 3201ae4..acf994e 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -76,16 +76,10 @@ static void default_idle(void)
 	if (test_thread_flag(TIF_MCCK_PENDING)) {
 		local_mcck_enable();
 		local_irq_enable();
-		s390_handle_mcck();
 		return;
 	}
-	trace_hardirqs_on();
-	/* Don't trace preempt off for idle. */
-	stop_critical_timings();
-	/* Stop virtual timer and halt the cpu. */
+	/* Halt the cpu and keep track of cpu time accounting. */
 	vtime_stop_cpu();
-	/* Reenable preemption tracer. */
-	start_critical_timings();
 }
 
 void cpu_idle(void)
@@ -93,10 +87,12 @@ void cpu_idle(void)
 	for (;;) {
 		tick_nohz_idle_enter();
 		rcu_idle_enter();
-		while (!need_resched())
+		while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING))
 			default_idle();
 		rcu_idle_exit();
 		tick_nohz_idle_exit();
+		if (test_thread_flag(TIF_MCCK_PENDING))
+			s390_handle_mcck();
 		preempt_enable_no_resched();
 		schedule();
 		preempt_disable();
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 354de07..d354885 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/setup.c
  *
  *  S390 version
- *    Copyright (C) IBM Corp. 1999,2010
+ *    Copyright (C) IBM Corp. 1999,2012
  *    Author(s): Hartmut Penner (hp@de.ibm.com),
  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  *
@@ -62,6 +62,7 @@
 #include <asm/compat.h>
 #include <asm/kvm_virtio.h>
 #include <asm/diag.h>
+#include "entry.h"
 
 long psw_kernel_bits	= PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_ASC_PRIMARY |
 			  PSW_MASK_EA | PSW_MASK_BA;
@@ -351,8 +352,9 @@ static void setup_addressing_mode(void)
 	}
 }
 
-static void __init
-setup_lowcore(void)
+void *restart_stack __attribute__((__section__(".data")));
+
+static void __init setup_lowcore(void)
 {
 	struct _lowcore *lc;
 
@@ -363,7 +365,7 @@ setup_lowcore(void)
 	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
 	lc->restart_psw.mask = psw_kernel_bits;
 	lc->restart_psw.addr =
-		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
+		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
 	lc->external_new_psw.mask = psw_kernel_bits |
 		PSW_MASK_DAT | PSW_MASK_MCHECK;
 	lc->external_new_psw.addr =
@@ -412,6 +414,24 @@ setup_lowcore(void)
 	lc->last_update_timer = S390_lowcore.last_update_timer;
 	lc->last_update_clock = S390_lowcore.last_update_clock;
 	lc->ftrace_func = S390_lowcore.ftrace_func;
+
+	restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
+	restart_stack += ASYNC_SIZE;
+
+	/*
+	 * Set up PSW restart to call ipl.c:do_restart(). Copy the relevant
+	 * restart data to the absolute zero lowcore. This is necesary if
+	 * PSW restart is done on an offline CPU that has lowcore zero.
+	 */
+	lc->restart_stack = (unsigned long) restart_stack;
+	lc->restart_fn = (unsigned long) do_restart;
+	lc->restart_data = 0;
+	lc->restart_source = -1UL;
+	memcpy(&S390_lowcore.restart_stack, &lc->restart_stack,
+	       4*sizeof(unsigned long));
+	copy_to_absolute_zero(&S390_lowcore.restart_psw,
+			      &lc->restart_psw, sizeof(psw_t));
+
 	set_prefix((u32)(unsigned long) lc);
 	lowcore_ptr[0] = lc;
 }
@@ -572,27 +592,6 @@ static void __init setup_memory_end(void)
 	}
 }
 
-void *restart_stack __attribute__((__section__(".data")));
-
-/*
- * Setup new PSW and allocate stack for PSW restart interrupt
- */
-static void __init setup_restart_psw(void)
-{
-	psw_t psw;
-
-	restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
-	restart_stack += ASYNC_SIZE;
-
-	/*
-	 * Setup restart PSW for absolute zero lowcore. This is necesary
-	 * if PSW restart is done on an offline CPU that has lowcore zero
-	 */
-	psw.mask = PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
-	psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
-	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
-}
-
 static void __init setup_vmcoreinfo(void)
 {
 #ifdef CONFIG_KEXEC
@@ -747,7 +746,7 @@ static void __init reserve_crashkernel(void)
 {
 #ifdef CONFIG_CRASH_DUMP
 	unsigned long long crash_base, crash_size;
-	char *msg;
+	char *msg = NULL;
 	int rc;
 
 	rc = parse_crashkernel(boot_command_line, memory_end, &crash_size,
@@ -782,8 +781,7 @@ static void __init reserve_crashkernel(void)
 #endif
 }
 
-static void __init
-setup_memory(void)
+static void __init setup_memory(void)
 {
         unsigned long bootmap_size;
 	unsigned long start_pfn, end_pfn;
@@ -1014,8 +1012,7 @@ static void __init setup_hwcaps(void)
  * was printed.
  */
 
-void __init
-setup_arch(char **cmdline_p)
+void __init setup_arch(char **cmdline_p)
 {
         /*
          * print what head.S has found out about the machine
@@ -1068,7 +1065,6 @@ setup_arch(char **cmdline_p)
 	setup_memory();
 	setup_resources();
 	setup_vmcoreinfo();
-	setup_restart_psw();
 	setup_lowcore();
 
         cpu_init();
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index a8ba840..c4f5790 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -385,7 +385,6 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
 			 siginfo_t *info, sigset_t *oldset,
 			 struct pt_regs *regs)
 {
-	sigset_t blocked;
 	int ret;
 
 	/* Set up the stack frame */
@@ -395,10 +394,7 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
 		ret = setup_frame(sig, ka, oldset, regs);
 	if (ret)
 		return ret;
-	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&blocked, sig);
-	set_current_blocked(&blocked);
+	block_sigmask(ka, sig);
 	return 0;
 }
 
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 2398ce6..6d3919d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -1,7 +1,7 @@
 /*
  *  arch/s390/kernel/smp.c
  *
- *    Copyright IBM Corp. 1999, 2009
+ *    Copyright IBM Corp. 1999, 2012
  *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
  *		 Martin Schwidefsky (schwidefsky@de.ibm.com)
  *		 Heiko Carstens (heiko.carstens@de.ibm.com)
@@ -10,14 +10,9 @@
  *    (c) 1995 Alan Cox, CymruNET Ltd  <alan@cymru.net>
  *    (c) 1998 Ingo Molnar
  *
- * We work with logical cpu numbering everywhere we can. The only
- * functions using the real cpu address (got from STAP) are the sigp
- * functions. For all other functions we use the identity mapping.
- * That means that cpu_number_map[i] == i for every cpu. cpu_number_map is
- * used e.g. to find the idle task belonging to a logical cpu. Every array
- * in the kernel is sorted by the logical cpu number and not by the physical
- * one which is causing all the confusion with __cpu_logical_map and
- * cpu_number_map in other architectures.
+ * The code outside of smp.c uses logical cpu numbers, only smp.c does
+ * the translation of logical to physical cpu ids. All new code that
+ * operates on physical cpu numbers needs to go into smp.c.
  */
 
 #define KMSG_COMPONENT "cpu"
@@ -31,140 +26,384 @@
 #include <linux/spinlock.h>
 #include <linux/kernel_stat.h>
 #include <linux/delay.h>
-#include <linux/cache.h>
 #include <linux/interrupt.h>
 #include <linux/irqflags.h>
 #include <linux/cpu.h>
-#include <linux/timex.h>
-#include <linux/bootmem.h>
 #include <linux/slab.h>
 #include <linux/crash_dump.h>
 #include <asm/asm-offsets.h>
 #include <asm/ipl.h>
 #include <asm/setup.h>
-#include <asm/sigp.h>
-#include <asm/pgalloc.h>
 #include <asm/irq.h>
-#include <asm/cpcmd.h>
 #include <asm/tlbflush.h>
 #include <asm/timer.h>
 #include <asm/lowcore.h>
 #include <asm/sclp.h>
-#include <asm/cputime.h>
 #include <asm/vdso.h>
-#include <asm/cpu.h>
 #include "entry.h"
 
-/* logical cpu to cpu address */
-unsigned short __cpu_logical_map[NR_CPUS];
+enum {
+	sigp_sense = 1,
+	sigp_external_call = 2,
+	sigp_emergency_signal = 3,
+	sigp_start = 4,
+	sigp_stop = 5,
+	sigp_restart = 6,
+	sigp_stop_and_store_status = 9,
+	sigp_initial_cpu_reset = 11,
+	sigp_cpu_reset = 12,
+	sigp_set_prefix = 13,
+	sigp_store_status_at_address = 14,
+	sigp_store_extended_status_at_address = 15,
+	sigp_set_architecture = 18,
+	sigp_conditional_emergency_signal = 19,
+	sigp_sense_running = 21,
+};
 
-static struct task_struct *current_set[NR_CPUS];
+enum {
+	sigp_order_code_accepted = 0,
+	sigp_status_stored = 1,
+	sigp_busy = 2,
+	sigp_not_operational = 3,
+};
 
-static u8 smp_cpu_type;
-static int smp_use_sigp_detection;
+enum {
+	ec_schedule = 0,
+	ec_call_function,
+	ec_call_function_single,
+	ec_stop_cpu,
+};
 
-enum s390_cpu_state {
+enum {
 	CPU_STATE_STANDBY,
 	CPU_STATE_CONFIGURED,
 };
 
+struct pcpu {
+	struct cpu cpu;
+	struct task_struct *idle;	/* idle process for the cpu */
+	struct _lowcore *lowcore;	/* lowcore page(s) for the cpu */
+	unsigned long async_stack;	/* async stack for the cpu */
+	unsigned long panic_stack;	/* panic stack for the cpu */
+	unsigned long ec_mask;		/* bit mask for ec_xxx functions */
+	int state;			/* physical cpu state */
+	u32 status;			/* last status received via sigp */
+	u16 address;			/* physical cpu address */
+};
+
+static u8 boot_cpu_type;
+static u16 boot_cpu_address;
+static struct pcpu pcpu_devices[NR_CPUS];
+
 DEFINE_MUTEX(smp_cpu_state_mutex);
-static int smp_cpu_state[NR_CPUS];
 
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
+/*
+ * Signal processor helper functions.
+ */
+static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
+{
+	register unsigned int reg1 asm ("1") = parm;
+	int cc;
 
-static void smp_ext_bitcall(int, int);
+	asm volatile(
+		"	sigp	%1,%2,0(%3)\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+		: "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
+	if (status && cc == 1)
+		*status = reg1;
+	return cc;
+}
 
-static int raw_cpu_stopped(int cpu)
+static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
 {
-	u32 status;
+	int cc;
 
-	switch (raw_sigp_ps(&status, 0, cpu, sigp_sense)) {
-	case sigp_status_stored:
-		/* Check for stopped and check stop state */
-		if (status & 0x50)
-			return 1;
-		break;
-	default:
-		break;
+	while (1) {
+		cc = __pcpu_sigp(addr, order, parm, status);
+		if (cc != sigp_busy)
+			return cc;
+		cpu_relax();
 	}
-	return 0;
 }
 
-static inline int cpu_stopped(int cpu)
+static int pcpu_sigp_retry(struct pcpu *pcpu, u8 order, u32 parm)
+{
+	int cc, retry;
+
+	for (retry = 0; ; retry++) {
+		cc = __pcpu_sigp(pcpu->address, order, parm, &pcpu->status);
+		if (cc != sigp_busy)
+			break;
+		if (retry >= 3)
+			udelay(10);
+	}
+	return cc;
+}
+
+static inline int pcpu_stopped(struct pcpu *pcpu)
+{
+	if (__pcpu_sigp(pcpu->address, sigp_sense,
+			0, &pcpu->status) != sigp_status_stored)
+		return 0;
+	/* Check for stopped and check stop state */
+	return !!(pcpu->status & 0x50);
+}
+
+static inline int pcpu_running(struct pcpu *pcpu)
 {
-	return raw_cpu_stopped(cpu_logical_map(cpu));
+	if (__pcpu_sigp(pcpu->address, sigp_sense_running,
+			0, &pcpu->status) != sigp_status_stored)
+		return 1;
+	/* Check for running status */
+	return !(pcpu->status & 0x400);
 }
 
 /*
- * Ensure that PSW restart is done on an online CPU
+ * Find struct pcpu by cpu address.
  */
-void smp_restart_with_online_cpu(void)
+static struct pcpu *pcpu_find_address(const struct cpumask *mask, int address)
 {
 	int cpu;
 
-	for_each_online_cpu(cpu) {
-		if (stap() == __cpu_logical_map[cpu]) {
-			/* We are online: Enable DAT again and return */
-			__load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
-			return;
-		}
+	for_each_cpu(cpu, mask)
+		if (pcpu_devices[cpu].address == address)
+			return pcpu_devices + cpu;
+	return NULL;
+}
+
+static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit)
+{
+	int order;
+
+	set_bit(ec_bit, &pcpu->ec_mask);
+	order = pcpu_running(pcpu) ?
+		sigp_external_call : sigp_emergency_signal;
+	pcpu_sigp_retry(pcpu, order, 0);
+}
+
+static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu)
+{
+	struct _lowcore *lc;
+
+	if (pcpu != &pcpu_devices[0]) {
+		pcpu->lowcore =	(struct _lowcore *)
+			__get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
+		pcpu->async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
+		pcpu->panic_stack = __get_free_page(GFP_KERNEL);
+		if (!pcpu->lowcore || !pcpu->panic_stack || !pcpu->async_stack)
+			goto out;
 	}
-	/* We are not online: Do PSW restart on an online CPU */
-	while (sigp(cpu, sigp_restart) == sigp_busy)
-		cpu_relax();
-	/* And stop ourself */
-	while (raw_sigp(stap(), sigp_stop) == sigp_busy)
-		cpu_relax();
-	for (;;);
+
+	lc = pcpu->lowcore;
+	memcpy(lc, &S390_lowcore, 512);
+	memset((char *) lc + 512, 0, sizeof(*lc) - 512);
+	lc->async_stack = pcpu->async_stack + ASYNC_SIZE;
+	lc->panic_stack = pcpu->panic_stack + PAGE_SIZE;
+	lc->cpu_nr = cpu;
+
+#ifndef CONFIG_64BIT
+	if (MACHINE_HAS_IEEE) {
+		lc->extended_save_area_addr = get_zeroed_page(GFP_KERNEL);
+		if (!lc->extended_save_area_addr)
+			goto out;
+	}
+#else
+	if (vdso_alloc_per_cpu(lc))
+		goto out;
+#endif
+
+	lowcore_ptr[lc->cpu_nr] = lc;
+	pcpu_sigp_retry(pcpu, sigp_set_prefix, (u32)(unsigned long) lc);
+	return 0;
+out:
+	if (pcpu != &pcpu_devices[0]) {
+		free_page(pcpu->panic_stack);
+		free_pages(pcpu->async_stack, ASYNC_ORDER);
+		free_pages((unsigned long) pcpu->lowcore, LC_ORDER);
+	}
+	return -ENOMEM;
 }
 
-void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
+static void pcpu_free_lowcore(struct pcpu *pcpu)
 {
-	struct _lowcore *lc, *current_lc;
-	struct stack_frame *sf;
-	struct pt_regs *regs;
-	unsigned long sp;
-
-	if (smp_processor_id() == 0)
-		func(data);
-	__load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE |
-			PSW_MASK_EA | PSW_MASK_BA);
-	/* Disable lowcore protection */
-	__ctl_clear_bit(0, 28);
-	current_lc = lowcore_ptr[smp_processor_id()];
-	lc = lowcore_ptr[0];
-	if (!lc)
-		lc = current_lc;
-	lc->restart_psw.mask =
-		PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
-	lc->restart_psw.addr = PSW_ADDR_AMODE | (unsigned long) smp_restart_cpu;
-	if (!cpu_online(0))
-		smp_switch_to_cpu(func, data, 0, stap(), __cpu_logical_map[0]);
-	while (sigp(0, sigp_stop_and_store_status) == sigp_busy)
-		cpu_relax();
-	sp = lc->panic_stack;
-	sp -= sizeof(struct pt_regs);
-	regs = (struct pt_regs *) sp;
-	memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
-	regs->psw = current_lc->psw_save_area;
-	sp -= STACK_FRAME_OVERHEAD;
-	sf = (struct stack_frame *) sp;
-	sf->back_chain = 0;
-	smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
+	pcpu_sigp_retry(pcpu, sigp_set_prefix, 0);
+	lowcore_ptr[pcpu - pcpu_devices] = NULL;
+
+#ifndef CONFIG_64BIT
+	if (MACHINE_HAS_IEEE) {
+		struct _lowcore *lc = pcpu->lowcore;
+		free_page((unsigned long) lc->extended_save_area_addr);
+		lc->extended_save_area_addr = 0;
+	}
+#else
+	vdso_free_per_cpu(pcpu->lowcore);
+#endif
+	if (pcpu != &pcpu_devices[0]) {
+		free_page(pcpu->panic_stack);
+		free_pages(pcpu->async_stack, ASYNC_ORDER);
+		free_pages((unsigned long) pcpu->lowcore, LC_ORDER);
+	}
+}
+
+static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
+{
+	struct _lowcore *lc = pcpu->lowcore;
+
+	atomic_inc(&init_mm.context.attach_count);
+	lc->cpu_nr = cpu;
+	lc->percpu_offset = __per_cpu_offset[cpu];
+	lc->kernel_asce = S390_lowcore.kernel_asce;
+	lc->machine_flags = S390_lowcore.machine_flags;
+	lc->ftrace_func = S390_lowcore.ftrace_func;
+	lc->user_timer = lc->system_timer = lc->steal_timer = 0;
+	__ctl_store(lc->cregs_save_area, 0, 15);
+	save_access_regs((unsigned int *) lc->access_regs_save_area);
+	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
+	       MAX_FACILITY_BIT/8);
+}
+
+static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
+{
+	struct _lowcore *lc = pcpu->lowcore;
+	struct thread_info *ti = task_thread_info(tsk);
+
+	lc->kernel_stack = (unsigned long) task_stack_page(tsk) + THREAD_SIZE;
+	lc->thread_info = (unsigned long) task_thread_info(tsk);
+	lc->current_task = (unsigned long) tsk;
+	lc->user_timer = ti->user_timer;
+	lc->system_timer = ti->system_timer;
+	lc->steal_timer = 0;
+}
+
+static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data)
+{
+	struct _lowcore *lc = pcpu->lowcore;
+
+	lc->restart_stack = lc->kernel_stack;
+	lc->restart_fn = (unsigned long) func;
+	lc->restart_data = (unsigned long) data;
+	lc->restart_source = -1UL;
+	pcpu_sigp_retry(pcpu, sigp_restart, 0);
+}
+
+/*
+ * Call function via PSW restart on pcpu and stop the current cpu.
+ */
+static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *),
+			  void *data, unsigned long stack)
+{
+	struct _lowcore *lc = pcpu->lowcore;
+	unsigned short this_cpu;
+
+	__load_psw_mask(psw_kernel_bits);
+	this_cpu = stap();
+	if (pcpu->address == this_cpu)
+		func(data);	/* should not return */
+	/* Stop target cpu (if func returns this stops the current cpu). */
+	pcpu_sigp_retry(pcpu, sigp_stop, 0);
+	/* Restart func on the target cpu and stop the current cpu. */
+	lc->restart_stack = stack;
+	lc->restart_fn = (unsigned long) func;
+	lc->restart_data = (unsigned long) data;
+	lc->restart_source = (unsigned long) this_cpu;
+	asm volatile(
+		"0:	sigp	0,%0,6	# sigp restart to target cpu\n"
+		"	brc	2,0b	# busy, try again\n"
+		"1:	sigp	0,%1,5	# sigp stop to current cpu\n"
+		"	brc	2,1b	# busy, try again\n"
+		: : "d" (pcpu->address), "d" (this_cpu) : "0", "1", "cc");
+	for (;;) ;
+}
+
+/*
+ * Call function on an online CPU.
+ */
+void smp_call_online_cpu(void (*func)(void *), void *data)
+{
+	struct pcpu *pcpu;
+
+	/* Use the current cpu if it is online. */
+	pcpu = pcpu_find_address(cpu_online_mask, stap());
+	if (!pcpu)
+		/* Use the first online cpu. */
+		pcpu = pcpu_devices + cpumask_first(cpu_online_mask);
+	pcpu_delegate(pcpu, func, data, (unsigned long) restart_stack);
+}
+
+/*
+ * Call function on the ipl CPU.
+ */
+void smp_call_ipl_cpu(void (*func)(void *), void *data)
+{
+	pcpu_delegate(&pcpu_devices[0], func, data, pcpu_devices->panic_stack);
+}
+
+int smp_find_processor_id(u16 address)
+{
+	int cpu;
+
+	for_each_present_cpu(cpu)
+		if (pcpu_devices[cpu].address == address)
+			return cpu;
+	return -1;
+}
+
+int smp_vcpu_scheduled(int cpu)
+{
+	return pcpu_running(pcpu_devices + cpu);
+}
+
+void smp_yield(void)
+{
+	if (MACHINE_HAS_DIAG44)
+		asm volatile("diag 0,0,0x44");
+}
+
+void smp_yield_cpu(int cpu)
+{
+	if (MACHINE_HAS_DIAG9C)
+		asm volatile("diag %0,0,0x9c"
+			     : : "d" (pcpu_devices[cpu].address));
+	else if (MACHINE_HAS_DIAG44)
+		asm volatile("diag 0,0,0x44");
 }
 
-static void smp_stop_cpu(void)
+/*
+ * Send cpus emergency shutdown signal. This gives the cpus the
+ * opportunity to complete outstanding interrupts.
+ */
+void smp_emergency_stop(cpumask_t *cpumask)
 {
-	while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
+	u64 end;
+	int cpu;
+
+	end = get_clock() + (1000000UL << 12);
+	for_each_cpu(cpu, cpumask) {
+		struct pcpu *pcpu = pcpu_devices + cpu;
+		set_bit(ec_stop_cpu, &pcpu->ec_mask);
+		while (__pcpu_sigp(pcpu->address, sigp_emergency_signal,
+				   0, NULL) == sigp_busy &&
+		       get_clock() < end)
+			cpu_relax();
+	}
+	while (get_clock() < end) {
+		for_each_cpu(cpu, cpumask)
+			if (pcpu_stopped(pcpu_devices + cpu))
+				cpumask_clear_cpu(cpu, cpumask);
+		if (cpumask_empty(cpumask))
+			break;
 		cpu_relax();
+	}
 }
 
+/*
+ * Stop all cpus but the current one.
+ */
 void smp_send_stop(void)
 {
 	cpumask_t cpumask;
 	int cpu;
-	u64 end;
 
 	/* Disable all interrupts/machine checks */
 	__load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
@@ -173,56 +412,45 @@ void smp_send_stop(void)
 	cpumask_copy(&cpumask, cpu_online_mask);
 	cpumask_clear_cpu(smp_processor_id(), &cpumask);
 
-	if (oops_in_progress) {
-		/*
-		 * Give the other cpus the opportunity to complete
-		 * outstanding interrupts before stopping them.
-		 */
-		end = get_clock() + (1000000UL << 12);
-		for_each_cpu(cpu, &cpumask) {
-			set_bit(ec_stop_cpu, (unsigned long *)
-				&lowcore_ptr[cpu]->ext_call_fast);
-			while (sigp(cpu, sigp_emergency_signal) == sigp_busy &&
-			       get_clock() < end)
-				cpu_relax();
-		}
-		while (get_clock() < end) {
-			for_each_cpu(cpu, &cpumask)
-				if (cpu_stopped(cpu))
-					cpumask_clear_cpu(cpu, &cpumask);
-			if (cpumask_empty(&cpumask))
-				break;
-			cpu_relax();
-		}
-	}
+	if (oops_in_progress)
+		smp_emergency_stop(&cpumask);
 
 	/* stop all processors */
 	for_each_cpu(cpu, &cpumask) {
-		while (sigp(cpu, sigp_stop) == sigp_busy)
-			cpu_relax();
-		while (!cpu_stopped(cpu))
+		struct pcpu *pcpu = pcpu_devices + cpu;
+		pcpu_sigp_retry(pcpu, sigp_stop, 0);
+		while (!pcpu_stopped(pcpu))
 			cpu_relax();
 	}
 }
 
 /*
+ * Stop the current cpu.
+ */
+void smp_stop_cpu(void)
+{
+	pcpu_sigp_retry(pcpu_devices + smp_processor_id(), sigp_stop, 0);
+}
+
+/*
  * This is the main routine where commands issued by other
  * cpus are handled.
  */
-
-static void do_ext_call_interrupt(unsigned int ext_int_code,
+static void do_ext_call_interrupt(struct ext_code ext_code,
 				  unsigned int param32, unsigned long param64)
 {
 	unsigned long bits;
+	int cpu;
 
-	if ((ext_int_code & 0xffff) == 0x1202)
-		kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++;
+	cpu = smp_processor_id();
+	if (ext_code.code == 0x1202)
+		kstat_cpu(cpu).irqs[EXTINT_EXC]++;
 	else
-		kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++;
+		kstat_cpu(cpu).irqs[EXTINT_EMS]++;
 	/*
 	 * handle bit signal external calls
 	 */
-	bits = xchg(&S390_lowcore.ext_call_fast, 0);
+	bits = xchg(&pcpu_devices[cpu].ec_mask, 0);
 
 	if (test_bit(ec_stop_cpu, &bits))
 		smp_stop_cpu();
@@ -238,38 +466,17 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
 
 }
 
-/*
- * Send an external call sigp to another cpu and return without waiting
- * for its completion.
- */
-static void smp_ext_bitcall(int cpu, int sig)
-{
-	int order;
-
-	/*
-	 * Set signaling bit in lowcore of target cpu and kick it
-	 */
-	set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
-	while (1) {
-		order = smp_vcpu_scheduled(cpu) ?
-			sigp_external_call : sigp_emergency_signal;
-		if (sigp(cpu, order) != sigp_busy)
-			break;
-		udelay(10);
-	}
-}
-
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
 	int cpu;
 
 	for_each_cpu(cpu, mask)
-		smp_ext_bitcall(cpu, ec_call_function);
+		pcpu_ec_call(pcpu_devices + cpu, ec_call_function);
 }
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-	smp_ext_bitcall(cpu, ec_call_function_single);
+	pcpu_ec_call(pcpu_devices + cpu, ec_call_function_single);
 }
 
 #ifndef CONFIG_64BIT
@@ -295,15 +502,16 @@ EXPORT_SYMBOL(smp_ptlb_all);
  */
 void smp_send_reschedule(int cpu)
 {
-	smp_ext_bitcall(cpu, ec_schedule);
+	pcpu_ec_call(pcpu_devices + cpu, ec_schedule);
 }
 
 /*
  * parameter area for the set/clear control bit callbacks
  */
 struct ec_creg_mask_parms {
-	unsigned long orvals[16];
-	unsigned long andvals[16];
+	unsigned long orval;
+	unsigned long andval;
+	int cr;
 };
 
 /*
@@ -313,11 +521,9 @@ static void smp_ctl_bit_callback(void *info)
 {
 	struct ec_creg_mask_parms *pp = info;
 	unsigned long cregs[16];
-	int i;
 
 	__ctl_store(cregs, 0, 15);
-	for (i = 0; i <= 15; i++)
-		cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i];
+	cregs[pp->cr] = (cregs[pp->cr] & pp->andval) | pp->orval;
 	__ctl_load(cregs, 0, 15);
 }
 
@@ -326,11 +532,7 @@ static void smp_ctl_bit_callback(void *info)
  */
 void smp_ctl_set_bit(int cr, int bit)
 {
-	struct ec_creg_mask_parms parms;
-
-	memset(&parms.orvals, 0, sizeof(parms.orvals));
-	memset(&parms.andvals, 0xff, sizeof(parms.andvals));
-	parms.orvals[cr] = 1UL << bit;
+	struct ec_creg_mask_parms parms = { 1UL << bit, -1UL, cr };
 	on_each_cpu(smp_ctl_bit_callback, &parms, 1);
 }
 EXPORT_SYMBOL(smp_ctl_set_bit);
@@ -340,200 +542,168 @@ EXPORT_SYMBOL(smp_ctl_set_bit);
  */
 void smp_ctl_clear_bit(int cr, int bit)
 {
-	struct ec_creg_mask_parms parms;
-
-	memset(&parms.orvals, 0, sizeof(parms.orvals));
-	memset(&parms.andvals, 0xff, sizeof(parms.andvals));
-	parms.andvals[cr] = ~(1UL << bit);
+	struct ec_creg_mask_parms parms = { 0, ~(1UL << bit), cr };
 	on_each_cpu(smp_ctl_bit_callback, &parms, 1);
 }
 EXPORT_SYMBOL(smp_ctl_clear_bit);
 
 #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_CRASH_DUMP)
 
-static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
+struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
+EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
+
+static void __init smp_get_save_area(int cpu, u16 address)
 {
-	if (ipl_info.type != IPL_TYPE_FCP_DUMP && !OLDMEM_BASE)
-		return;
+	void *lc = pcpu_devices[0].lowcore;
+	struct save_area *save_area;
+
 	if (is_kdump_kernel())
 		return;
+	if (!OLDMEM_BASE && (address == boot_cpu_address ||
+			     ipl_info.type != IPL_TYPE_FCP_DUMP))
+		return;
 	if (cpu >= NR_CPUS) {
-		pr_warning("CPU %i exceeds the maximum %i and is excluded from "
-			   "the dump\n", cpu, NR_CPUS - 1);
+		pr_warning("CPU %i exceeds the maximum %i and is excluded "
+			   "from the dump\n", cpu, NR_CPUS - 1);
 		return;
 	}
-	zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL);
-	while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy)
-		cpu_relax();
-	memcpy_real(zfcpdump_save_areas[cpu],
-		    (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
-		    sizeof(struct save_area));
+	save_area = kmalloc(sizeof(struct save_area), GFP_KERNEL);
+	if (!save_area)
+		panic("could not allocate memory for save area\n");
+	zfcpdump_save_areas[cpu] = save_area;
+#ifdef CONFIG_CRASH_DUMP
+	if (address == boot_cpu_address) {
+		/* Copy the registers of the boot cpu. */
+		copy_oldmem_page(1, (void *) save_area, sizeof(*save_area),
+				 SAVE_AREA_BASE - PAGE_SIZE, 0);
+		return;
+	}
+#endif
+	/* Get the registers of a non-boot cpu. */
+	__pcpu_sigp_relax(address, sigp_stop_and_store_status, 0, NULL);
+	memcpy_real(save_area, lc + SAVE_AREA_BASE, sizeof(*save_area));
 }
 
-struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
-EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
+int smp_store_status(int cpu)
+{
+	struct pcpu *pcpu;
+
+	pcpu = pcpu_devices + cpu;
+	if (__pcpu_sigp_relax(pcpu->address, sigp_stop_and_store_status,
+			      0, NULL) != sigp_order_code_accepted)
+		return -EIO;
+	return 0;
+}
 
 #else
 
-static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
+static inline void smp_get_save_area(int cpu, u16 address) { }
 
 #endif /* CONFIG_ZFCPDUMP */
 
-static int cpu_known(int cpu_id)
+static struct sclp_cpu_info *smp_get_cpu_info(void)
 {
-	int cpu;
-
-	for_each_present_cpu(cpu) {
-		if (__cpu_logical_map[cpu] == cpu_id)
-			return 1;
+	static int use_sigp_detection;
+	struct sclp_cpu_info *info;
+	int address;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (info && (use_sigp_detection || sclp_get_cpu_info(info))) {
+		use_sigp_detection = 1;
+		for (address = 0; address <= MAX_CPU_ADDRESS; address++) {
+			if (__pcpu_sigp_relax(address, sigp_sense, 0, NULL) ==
+			    sigp_not_operational)
+				continue;
+			info->cpu[info->configured].address = address;
+			info->configured++;
+		}
+		info->combined = info->configured;
 	}
-	return 0;
+	return info;
 }
 
-static int smp_rescan_cpus_sigp(cpumask_t avail)
-{
-	int cpu_id, logical_cpu;
-
-	logical_cpu = cpumask_first(&avail);
-	if (logical_cpu >= nr_cpu_ids)
-		return 0;
-	for (cpu_id = 0; cpu_id <= MAX_CPU_ADDRESS; cpu_id++) {
-		if (cpu_known(cpu_id))
-			continue;
-		__cpu_logical_map[logical_cpu] = cpu_id;
-		cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
-		if (!cpu_stopped(logical_cpu))
-			continue;
-		set_cpu_present(logical_cpu, true);
-		smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-		logical_cpu = cpumask_next(logical_cpu, &avail);
-		if (logical_cpu >= nr_cpu_ids)
-			break;
-	}
-	return 0;
-}
+static int __devinit smp_add_present_cpu(int cpu);
 
-static int smp_rescan_cpus_sclp(cpumask_t avail)
+static int __devinit __smp_rescan_cpus(struct sclp_cpu_info *info,
+				       int sysfs_add)
 {
-	struct sclp_cpu_info *info;
-	int cpu_id, logical_cpu, cpu;
-	int rc;
+	struct pcpu *pcpu;
+	cpumask_t avail;
+	int cpu, nr, i;
 
-	logical_cpu = cpumask_first(&avail);
-	if (logical_cpu >= nr_cpu_ids)
-		return 0;
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (!info)
-		return -ENOMEM;
-	rc = sclp_get_cpu_info(info);
-	if (rc)
-		goto out;
-	for (cpu = 0; cpu < info->combined; cpu++) {
-		if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
+	nr = 0;
+	cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask);
+	cpu = cpumask_first(&avail);
+	for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) {
+		if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type)
 			continue;
-		cpu_id = info->cpu[cpu].address;
-		if (cpu_known(cpu_id))
+		if (pcpu_find_address(cpu_present_mask, info->cpu[i].address))
 			continue;
-		__cpu_logical_map[logical_cpu] = cpu_id;
-		cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
-		set_cpu_present(logical_cpu, true);
-		if (cpu >= info->configured)
-			smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
+		pcpu = pcpu_devices + cpu;
+		pcpu->address = info->cpu[i].address;
+		pcpu->state = (cpu >= info->configured) ?
+			CPU_STATE_STANDBY : CPU_STATE_CONFIGURED;
+		cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
+		set_cpu_present(cpu, true);
+		if (sysfs_add && smp_add_present_cpu(cpu) != 0)
+			set_cpu_present(cpu, false);
 		else
-			smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
-		logical_cpu = cpumask_next(logical_cpu, &avail);
-		if (logical_cpu >= nr_cpu_ids)
-			break;
+			nr++;
+		cpu = cpumask_next(cpu, &avail);
 	}
-out:
-	kfree(info);
-	return rc;
-}
-
-static int __smp_rescan_cpus(void)
-{
-	cpumask_t avail;
-
-	cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask);
-	if (smp_use_sigp_detection)
-		return smp_rescan_cpus_sigp(avail);
-	else
-		return smp_rescan_cpus_sclp(avail);
+	return nr;
 }
 
 static void __init smp_detect_cpus(void)
 {
 	unsigned int cpu, c_cpus, s_cpus;
 	struct sclp_cpu_info *info;
-	u16 boot_cpu_addr, cpu_addr;
 
-	c_cpus = 1;
-	s_cpus = 0;
-	boot_cpu_addr = __cpu_logical_map[0];
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	info = smp_get_cpu_info();
 	if (!info)
 		panic("smp_detect_cpus failed to allocate memory\n");
-#ifdef CONFIG_CRASH_DUMP
-	if (OLDMEM_BASE && !is_kdump_kernel()) {
-		struct save_area *save_area;
-
-		save_area = kmalloc(sizeof(*save_area), GFP_KERNEL);
-		if (!save_area)
-			panic("could not allocate memory for save area\n");
-		copy_oldmem_page(1, (void *) save_area, sizeof(*save_area),
-				 0x200, 0);
-		zfcpdump_save_areas[0] = save_area;
-	}
-#endif
-	/* Use sigp detection algorithm if sclp doesn't work. */
-	if (sclp_get_cpu_info(info)) {
-		smp_use_sigp_detection = 1;
-		for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) {
-			if (cpu == boot_cpu_addr)
-				continue;
-			if (!raw_cpu_stopped(cpu))
-				continue;
-			smp_get_save_area(c_cpus, cpu);
-			c_cpus++;
-		}
-		goto out;
-	}
 
 	if (info->has_cpu_type) {
 		for (cpu = 0; cpu < info->combined; cpu++) {
-			if (info->cpu[cpu].address == boot_cpu_addr) {
-				smp_cpu_type = info->cpu[cpu].type;
-				break;
-			}
+			if (info->cpu[cpu].address != boot_cpu_address)
+				continue;
+			/* The boot cpu dictates the cpu type. */
+			boot_cpu_type = info->cpu[cpu].type;
 		}
 	}
 
+	c_cpus = s_cpus = 0;
 	for (cpu = 0; cpu < info->combined; cpu++) {
-		if (info->has_cpu_type && info->cpu[cpu].type != smp_cpu_type)
-			continue;
-		cpu_addr = info->cpu[cpu].address;
-		if (cpu_addr == boot_cpu_addr)
+		if (info->has_cpu_type && info->cpu[cpu].type != boot_cpu_type)
 			continue;
-		if (!raw_cpu_stopped(cpu_addr)) {
+		if (cpu < info->configured) {
+			smp_get_save_area(c_cpus, info->cpu[cpu].address);
+			c_cpus++;
+		} else
 			s_cpus++;
-			continue;
-		}
-		smp_get_save_area(c_cpus, cpu_addr);
-		c_cpus++;
 	}
-out:
-	kfree(info);
 	pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus);
+
 	get_online_cpus();
-	__smp_rescan_cpus();
+	__smp_rescan_cpus(info, 0);
 	put_online_cpus();
+	kfree(info);
 }
 
 /*
  *	Activate a secondary processor.
  */
-int __cpuinit start_secondary(void *cpuvoid)
+static void __cpuinit smp_start_secondary(void *cpuvoid)
 {
+	S390_lowcore.last_update_clock = get_clock();
+	S390_lowcore.restart_stack = (unsigned long) restart_stack;
+	S390_lowcore.restart_fn = (unsigned long) do_restart;
+	S390_lowcore.restart_data = 0;
+	S390_lowcore.restart_source = -1UL;
+	restore_access_regs(S390_lowcore.access_regs_save_area);
+	__ctl_load(S390_lowcore.cregs_save_area, 0, 15);
+	__load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
+
 	cpu_init();
 	preempt_disable();
 	init_cpu_timer();
@@ -544,12 +714,7 @@ int __cpuinit start_secondary(void *cpuvoid)
 	ipi_call_lock();
 	set_cpu_online(smp_processor_id(), true);
 	ipi_call_unlock();
-	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
-	S390_lowcore.restart_psw.mask =
-		PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
-	S390_lowcore.restart_psw.addr =
-		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
-	__ctl_set_bit(0, 28); /* Enable lowcore protection */
+
 	/*
 	 * Wait until the cpu which brought this one up marked it
 	 * active before enabling interrupts.
@@ -559,7 +724,6 @@ int __cpuinit start_secondary(void *cpuvoid)
 	local_irq_enable();
 	/* cpu_idle will call schedule for us */
 	cpu_idle();
-	return 0;
 }
 
 struct create_idle {
@@ -578,82 +742,21 @@ static void __cpuinit smp_fork_idle(struct work_struct *work)
 	complete(&c_idle->done);
 }
 
-static int __cpuinit smp_alloc_lowcore(int cpu)
-{
-	unsigned long async_stack, panic_stack;
-	struct _lowcore *lowcore;
-
-	lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
-	if (!lowcore)
-		return -ENOMEM;
-	async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
-	panic_stack = __get_free_page(GFP_KERNEL);
-	if (!panic_stack || !async_stack)
-		goto out;
-	memcpy(lowcore, &S390_lowcore, 512);
-	memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
-	lowcore->async_stack = async_stack + ASYNC_SIZE;
-	lowcore->panic_stack = panic_stack + PAGE_SIZE;
-	lowcore->restart_psw.mask =
-		PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | PSW_MASK_BA;
-	lowcore->restart_psw.addr =
-		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
-	if (user_mode != HOME_SPACE_MODE)
-		lowcore->restart_psw.mask |= PSW_ASC_HOME;
-#ifndef CONFIG_64BIT
-	if (MACHINE_HAS_IEEE) {
-		unsigned long save_area;
-
-		save_area = get_zeroed_page(GFP_KERNEL);
-		if (!save_area)
-			goto out;
-		lowcore->extended_save_area_addr = (u32) save_area;
-	}
-#else
-	if (vdso_alloc_per_cpu(cpu, lowcore))
-		goto out;
-#endif
-	lowcore_ptr[cpu] = lowcore;
-	return 0;
-
-out:
-	free_page(panic_stack);
-	free_pages(async_stack, ASYNC_ORDER);
-	free_pages((unsigned long) lowcore, LC_ORDER);
-	return -ENOMEM;
-}
-
-static void smp_free_lowcore(int cpu)
-{
-	struct _lowcore *lowcore;
-
-	lowcore = lowcore_ptr[cpu];
-#ifndef CONFIG_64BIT
-	if (MACHINE_HAS_IEEE)
-		free_page((unsigned long) lowcore->extended_save_area_addr);
-#else
-	vdso_free_per_cpu(cpu, lowcore);
-#endif
-	free_page(lowcore->panic_stack - PAGE_SIZE);
-	free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER);
-	free_pages((unsigned long) lowcore, LC_ORDER);
-	lowcore_ptr[cpu] = NULL;
-}
-
 /* Upping and downing of CPUs */
 int __cpuinit __cpu_up(unsigned int cpu)
 {
-	struct _lowcore *cpu_lowcore;
 	struct create_idle c_idle;
-	struct task_struct *idle;
-	struct stack_frame *sf;
-	u32 lowcore;
-	int ccode;
+	struct pcpu *pcpu;
+	int rc;
 
-	if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
+	pcpu = pcpu_devices + cpu;
+	if (pcpu->state != CPU_STATE_CONFIGURED)
 		return -EIO;
-	idle = current_set[cpu];
-	if (!idle) {
+	if (pcpu_sigp_retry(pcpu, sigp_initial_cpu_reset, 0) !=
+	    sigp_order_code_accepted)
+		return -EIO;
+
+	if (!pcpu->idle) {
 		c_idle.done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done);
 		INIT_WORK_ONSTACK(&c_idle.work, smp_fork_idle);
 		c_idle.cpu = cpu;
@@ -661,68 +764,32 @@ int __cpuinit __cpu_up(unsigned int cpu)
 		wait_for_completion(&c_idle.done);
 		if (IS_ERR(c_idle.idle))
 			return PTR_ERR(c_idle.idle);
-		idle = c_idle.idle;
-		current_set[cpu] = c_idle.idle;
+		pcpu->idle = c_idle.idle;
 	}
-	init_idle(idle, cpu);
-	if (smp_alloc_lowcore(cpu))
-		return -ENOMEM;
-	do {
-		ccode = sigp(cpu, sigp_initial_cpu_reset);
-		if (ccode == sigp_busy)
-			udelay(10);
-		if (ccode == sigp_not_operational)
-			goto err_out;
-	} while (ccode == sigp_busy);
-
-	lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
-	while (sigp_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
-		udelay(10);
-
-	cpu_lowcore = lowcore_ptr[cpu];
-	cpu_lowcore->kernel_stack = (unsigned long)
-		task_stack_page(idle) + THREAD_SIZE;
-	cpu_lowcore->thread_info = (unsigned long) task_thread_info(idle);
-	sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
-				     - sizeof(struct pt_regs)
-				     - sizeof(struct stack_frame));
-	memset(sf, 0, sizeof(struct stack_frame));
-	sf->gprs[9] = (unsigned long) sf;
-	cpu_lowcore->gpregs_save_area[15] = (unsigned long) sf;
-	__ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
-	atomic_inc(&init_mm.context.attach_count);
-	asm volatile(
-		"	stam	0,15,0(%0)"
-		: : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
-	cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
-	cpu_lowcore->current_task = (unsigned long) idle;
-	cpu_lowcore->cpu_nr = cpu;
-	cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
-	cpu_lowcore->machine_flags = S390_lowcore.machine_flags;
-	cpu_lowcore->ftrace_func = S390_lowcore.ftrace_func;
-	memcpy(cpu_lowcore->stfle_fac_list, S390_lowcore.stfle_fac_list,
-	       MAX_FACILITY_BIT/8);
-	eieio();
+	init_idle(pcpu->idle, cpu);
 
-	while (sigp(cpu, sigp_restart) == sigp_busy)
-		udelay(10);
+	rc = pcpu_alloc_lowcore(pcpu, cpu);
+	if (rc)
+		return rc;
+
+	pcpu_prepare_secondary(pcpu, cpu);
+	pcpu_attach_task(pcpu, pcpu->idle);
+	pcpu_start_fn(pcpu, smp_start_secondary, NULL);
 
 	while (!cpu_online(cpu))
 		cpu_relax();
-	return 0;
 
-err_out:
-	smp_free_lowcore(cpu);
-	return -EIO;
+	return 0;
 }
 
 static int __init setup_possible_cpus(char *s)
 {
-	int pcpus, cpu;
+	int max, cpu;
 
-	pcpus = simple_strtoul(s, NULL, 0);
+	if (kstrtoint(s, 0, &max) < 0)
+		return 0;
 	init_cpu_possible(cpumask_of(0));
-	for (cpu = 1; cpu < pcpus && cpu < nr_cpu_ids; cpu++)
+	for (cpu = 1; cpu < max && cpu < nr_cpu_ids; cpu++)
 		set_cpu_possible(cpu, true);
 	return 0;
 }
@@ -732,52 +799,39 @@ early_param("possible_cpus", setup_possible_cpus);
 
 int __cpu_disable(void)
 {
-	struct ec_creg_mask_parms cr_parms;
-	int cpu = smp_processor_id();
+	unsigned long cregs[16];
 
-	set_cpu_online(cpu, false);
+	set_cpu_online(smp_processor_id(), false);
 
 	/* Disable pfault pseudo page faults on this cpu. */
 	pfault_fini();
 
-	memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals));
-	memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals));
-
-	/* disable all external interrupts */
-	cr_parms.orvals[0] = 0;
-	cr_parms.andvals[0] = ~(1 << 15 | 1 << 14 | 1 << 13 | 1 << 11 |
-				1 << 10 | 1 <<	9 | 1 <<  6 | 1 <<  5 |
-				1 <<  4);
-	/* disable all I/O interrupts */
-	cr_parms.orvals[6] = 0;
-	cr_parms.andvals[6] = ~(1 << 31 | 1 << 30 | 1 << 29 | 1 << 28 |
-				1 << 27 | 1 << 26 | 1 << 25 | 1 << 24);
-	/* disable most machine checks */
-	cr_parms.orvals[14] = 0;
-	cr_parms.andvals[14] = ~(1 << 28 | 1 << 27 | 1 << 26 |
-				 1 << 25 | 1 << 24);
-
-	smp_ctl_bit_callback(&cr_parms);
+	/* Disable interrupt sources via control register. */
+	__ctl_store(cregs, 0, 15);
+	cregs[0]  &= ~0x0000ee70UL;	/* disable all external interrupts */
+	cregs[6]  &= ~0xff000000UL;	/* disable all I/O interrupts */
+	cregs[14] &= ~0x1f000000UL;	/* disable most machine checks */
+	__ctl_load(cregs, 0, 15);
 
 	return 0;
 }
 
 void __cpu_die(unsigned int cpu)
 {
+	struct pcpu *pcpu;
+
 	/* Wait until target cpu is down */
-	while (!cpu_stopped(cpu))
+	pcpu = pcpu_devices + cpu;
+	while (!pcpu_stopped(pcpu))
 		cpu_relax();
-	while (sigp_p(0, cpu, sigp_set_prefix) == sigp_busy)
-		udelay(10);
-	smp_free_lowcore(cpu);
+	pcpu_free_lowcore(pcpu);
 	atomic_dec(&init_mm.context.attach_count);
 }
 
 void __noreturn cpu_die(void)
 {
 	idle_task_exit();
-	while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
-		cpu_relax();
+	pcpu_sigp_retry(pcpu_devices + smp_processor_id(), sigp_stop, 0);
 	for (;;);
 }
 
@@ -785,14 +839,6 @@ void __noreturn cpu_die(void)
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-#ifndef CONFIG_64BIT
-	unsigned long save_area = 0;
-#endif
-	unsigned long async_stack, panic_stack;
-	struct _lowcore *lowcore;
-
-	smp_detect_cpus();
-
 	/* request the 0x1201 emergency signal external interrupt */
 	if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
 		panic("Couldn't request external interrupt 0x1201");
@@ -800,45 +846,24 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0)
 		panic("Couldn't request external interrupt 0x1202");
 
-	/* Reallocate current lowcore, but keep its contents. */
-	lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
-	panic_stack = __get_free_page(GFP_KERNEL);
-	async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
-	BUG_ON(!lowcore || !panic_stack || !async_stack);
-#ifndef CONFIG_64BIT
-	if (MACHINE_HAS_IEEE)
-		save_area = get_zeroed_page(GFP_KERNEL);
-#endif
-	local_irq_disable();
-	local_mcck_disable();
-	lowcore_ptr[smp_processor_id()] = lowcore;
-	*lowcore = S390_lowcore;
-	lowcore->panic_stack = panic_stack + PAGE_SIZE;
-	lowcore->async_stack = async_stack + ASYNC_SIZE;
-#ifndef CONFIG_64BIT
-	if (MACHINE_HAS_IEEE)
-		lowcore->extended_save_area_addr = (u32) save_area;
-#endif
-	set_prefix((u32)(unsigned long) lowcore);
-	local_mcck_enable();
-	local_irq_enable();
-#ifdef CONFIG_64BIT
-	if (vdso_alloc_per_cpu(smp_processor_id(), &S390_lowcore))
-		BUG();
-#endif
+	smp_detect_cpus();
 }
 
 void __init smp_prepare_boot_cpu(void)
 {
-	BUG_ON(smp_processor_id() != 0);
-
-	current_thread_info()->cpu = 0;
-	set_cpu_present(0, true);
-	set_cpu_online(0, true);
+	struct pcpu *pcpu = pcpu_devices;
+
+	boot_cpu_address = stap();
+	pcpu->idle = current;
+	pcpu->state = CPU_STATE_CONFIGURED;
+	pcpu->address = boot_cpu_address;
+	pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix();
+	pcpu->async_stack = S390_lowcore.async_stack;
+	pcpu->panic_stack = S390_lowcore.panic_stack;
 	S390_lowcore.percpu_offset = __per_cpu_offset[0];
-	current_set[0] = current;
-	smp_cpu_state[0] = CPU_STATE_CONFIGURED;
 	cpu_set_polarization(0, POLARIZATION_UNKNOWN);
+	set_cpu_present(0, true);
+	set_cpu_online(0, true);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
@@ -848,7 +873,6 @@ void __init smp_cpus_done(unsigned int max_cpus)
 void __init smp_setup_processor_id(void)
 {
 	S390_lowcore.cpu_nr = 0;
-	__cpu_logical_map[0] = stap();
 }
 
 /*
@@ -864,22 +888,22 @@ int setup_profiling_timer(unsigned int multiplier)
 
 #ifdef CONFIG_HOTPLUG_CPU
 static ssize_t cpu_configure_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
+				  struct device_attribute *attr, char *buf)
 {
 	ssize_t count;
 
 	mutex_lock(&smp_cpu_state_mutex);
-	count = sprintf(buf, "%d\n", smp_cpu_state[dev->id]);
+	count = sprintf(buf, "%d\n", pcpu_devices[dev->id].state);
 	mutex_unlock(&smp_cpu_state_mutex);
 	return count;
 }
 
 static ssize_t cpu_configure_store(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf, size_t count)
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
 {
-	int cpu = dev->id;
-	int val, rc;
+	struct pcpu *pcpu;
+	int cpu, val, rc;
 	char delim;
 
 	if (sscanf(buf, "%d %c", &val, &delim) != 1)
@@ -891,29 +915,31 @@ static ssize_t cpu_configure_store(struct device *dev,
 	mutex_lock(&smp_cpu_state_mutex);
 	rc = -EBUSY;
 	/* disallow configuration changes of online cpus and cpu 0 */
+	cpu = dev->id;
 	if (cpu_online(cpu) || cpu == 0)
 		goto out;
+	pcpu = pcpu_devices + cpu;
 	rc = 0;
 	switch (val) {
 	case 0:
-		if (smp_cpu_state[cpu] == CPU_STATE_CONFIGURED) {
-			rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
-			if (!rc) {
-				smp_cpu_state[cpu] = CPU_STATE_STANDBY;
-				cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
-				topology_expect_change();
-			}
-		}
+		if (pcpu->state != CPU_STATE_CONFIGURED)
+			break;
+		rc = sclp_cpu_deconfigure(pcpu->address);
+		if (rc)
+			break;
+		pcpu->state = CPU_STATE_STANDBY;
+		cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
+		topology_expect_change();
 		break;
 	case 1:
-		if (smp_cpu_state[cpu] == CPU_STATE_STANDBY) {
-			rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
-			if (!rc) {
-				smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
-				cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
-				topology_expect_change();
-			}
-		}
+		if (pcpu->state != CPU_STATE_STANDBY)
+			break;
+		rc = sclp_cpu_configure(pcpu->address);
+		if (rc)
+			break;
+		pcpu->state = CPU_STATE_CONFIGURED;
+		cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
+		topology_expect_change();
 		break;
 	default:
 		break;
@@ -929,7 +955,7 @@ static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
 static ssize_t show_cpu_address(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
+	return sprintf(buf, "%d\n", pcpu_devices[dev->id].address);
 }
 static DEVICE_ATTR(address, 0444, show_cpu_address, NULL);
 
@@ -961,22 +987,16 @@ static DEVICE_ATTR(capability, 0444, show_capability, NULL);
 static ssize_t show_idle_count(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	struct s390_idle_data *idle;
+	struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
 	unsigned long long idle_count;
 	unsigned int sequence;
 
-	idle = &per_cpu(s390_idle, dev->id);
-repeat:
-	sequence = idle->sequence;
-	smp_rmb();
-	if (sequence & 1)
-		goto repeat;
-	idle_count = idle->idle_count;
-	if (idle->idle_enter)
-		idle_count++;
-	smp_rmb();
-	if (idle->sequence != sequence)
-		goto repeat;
+	do {
+		sequence = ACCESS_ONCE(idle->sequence);
+		idle_count = ACCESS_ONCE(idle->idle_count);
+		if (ACCESS_ONCE(idle->idle_enter))
+			idle_count++;
+	} while ((sequence & 1) || (idle->sequence != sequence));
 	return sprintf(buf, "%llu\n", idle_count);
 }
 static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
@@ -984,24 +1004,18 @@ static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
 static ssize_t show_idle_time(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	struct s390_idle_data *idle;
-	unsigned long long now, idle_time, idle_enter;
+	struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id);
+	unsigned long long now, idle_time, idle_enter, idle_exit;
 	unsigned int sequence;
 
-	idle = &per_cpu(s390_idle, dev->id);
-	now = get_clock();
-repeat:
-	sequence = idle->sequence;
-	smp_rmb();
-	if (sequence & 1)
-		goto repeat;
-	idle_time = idle->idle_time;
-	idle_enter = idle->idle_enter;
-	if (idle_enter != 0ULL && idle_enter < now)
-		idle_time += now - idle_enter;
-	smp_rmb();
-	if (idle->sequence != sequence)
-		goto repeat;
+	do {
+		now = get_clock();
+		sequence = ACCESS_ONCE(idle->sequence);
+		idle_time = ACCESS_ONCE(idle->idle_time);
+		idle_enter = ACCESS_ONCE(idle->idle_enter);
+		idle_exit = ACCESS_ONCE(idle->idle_exit);
+	} while ((sequence & 1) || (idle->sequence != sequence));
+	idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
 	return sprintf(buf, "%llu\n", idle_time >> 12);
 }
 static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
@@ -1021,7 +1035,7 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
 				    unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
-	struct cpu *c = &per_cpu(cpu_devices, cpu);
+	struct cpu *c = &pcpu_devices[cpu].cpu;
 	struct device *s = &c->dev;
 	struct s390_idle_data *idle;
 	int err = 0;
@@ -1047,7 +1061,7 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
 
 static int __devinit smp_add_present_cpu(int cpu)
 {
-	struct cpu *c = &per_cpu(cpu_devices, cpu);
+	struct cpu *c = &pcpu_devices[cpu].cpu;
 	struct device *s = &c->dev;
 	int rc;
 
@@ -1085,29 +1099,21 @@ out:
 
 int __ref smp_rescan_cpus(void)
 {
-	cpumask_t newcpus;
-	int cpu;
-	int rc;
+	struct sclp_cpu_info *info;
+	int nr;
 
+	info = smp_get_cpu_info();
+	if (!info)
+		return -ENOMEM;
 	get_online_cpus();
 	mutex_lock(&smp_cpu_state_mutex);
-	cpumask_copy(&newcpus, cpu_present_mask);
-	rc = __smp_rescan_cpus();
-	if (rc)
-		goto out;
-	cpumask_andnot(&newcpus, cpu_present_mask, &newcpus);
-	for_each_cpu(cpu, &newcpus) {
-		rc = smp_add_present_cpu(cpu);
-		if (rc)
-			set_cpu_present(cpu, false);
-	}
-	rc = 0;
-out:
+	nr = __smp_rescan_cpus(info, 1);
 	mutex_unlock(&smp_cpu_state_mutex);
 	put_online_cpus();
-	if (!cpumask_empty(&newcpus))
+	kfree(info);
+	if (nr)
 		topology_schedule_update();
-	return rc;
+	return 0;
 }
 
 static ssize_t __ref rescan_store(struct device *dev,
diff --git a/arch/s390/kernel/switch_cpu.S b/arch/s390/kernel/switch_cpu.S
deleted file mode 100644
index bfe070b..0000000
--- a/arch/s390/kernel/switch_cpu.S
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 31-bit switch cpu code
- *
- * Copyright IBM Corp. 2009
- *
- */
-
-#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
-#include <asm/ptrace.h>
-
-# smp_switch_to_cpu switches to destination cpu and executes the passed function
-# Parameter: %r2 - function to call
-#	     %r3 - function parameter
-#	     %r4 - stack poiner
-#	     %r5 - current cpu
-#	     %r6 - destination cpu
-
-	.section .text
-ENTRY(smp_switch_to_cpu)
-	stm	%r6,%r15,__SF_GPRS(%r15)
-	lr	%r1,%r15
-	ahi	%r15,-STACK_FRAME_OVERHEAD
-	st	%r1,__SF_BACKCHAIN(%r15)
-	basr	%r13,0
-0:	la	%r1,.gprregs_addr-0b(%r13)
-	l	%r1,0(%r1)
-	stm	%r0,%r15,0(%r1)
-1:	sigp	%r0,%r6,__SIGP_RESTART	/* start destination CPU */
-	brc	2,1b			/* busy, try again */
-2:	sigp	%r0,%r5,__SIGP_STOP	/* stop current CPU */
-	brc	2,2b			/* busy, try again */
-3:	j	3b
-
-ENTRY(smp_restart_cpu)
-	basr	%r13,0
-0:	la	%r1,.gprregs_addr-0b(%r13)
-	l	%r1,0(%r1)
-	lm	%r0,%r15,0(%r1)
-1:	sigp	%r0,%r5,__SIGP_SENSE	/* Wait for calling CPU */
-	brc	10,1b			/* busy, accepted (status 0), running */
-	tmll	%r0,0x40		/* Test if calling CPU is stopped */
-	jz	1b
-	ltr	%r4,%r4			/* New stack ? */
-	jz	1f
-	lr	%r15,%r4
-1:	lr	%r14,%r2		/* r14: Function to call */
-	lr	%r2,%r3			/* r2 : Parameter for function*/
-	basr	%r14,%r14		/* Call function */
-
-.gprregs_addr:
-	.long	.gprregs
-
-	.section .data,"aw",@progbits
-.gprregs:
-	.rept	16
-	.long	0
-	.endr
diff --git a/arch/s390/kernel/switch_cpu64.S b/arch/s390/kernel/switch_cpu64.S
deleted file mode 100644
index fcc42d7..0000000
--- a/arch/s390/kernel/switch_cpu64.S
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 64-bit switch cpu code
- *
- * Copyright IBM Corp. 2009
- *
- */
-
-#include <linux/linkage.h>
-#include <asm/asm-offsets.h>
-#include <asm/ptrace.h>
-
-# smp_switch_to_cpu switches to destination cpu and executes the passed function
-# Parameter: %r2 - function to call
-#	     %r3 - function parameter
-#	     %r4 - stack poiner
-#	     %r5 - current cpu
-#	     %r6 - destination cpu
-
-	.section .text
-ENTRY(smp_switch_to_cpu)
-	stmg	%r6,%r15,__SF_GPRS(%r15)
-	lgr	%r1,%r15
-	aghi	%r15,-STACK_FRAME_OVERHEAD
-	stg	%r1,__SF_BACKCHAIN(%r15)
-	larl	%r1,.gprregs
-	stmg	%r0,%r15,0(%r1)
-1:	sigp	%r0,%r6,__SIGP_RESTART	/* start destination CPU */
-	brc	2,1b			/* busy, try again */
-2:	sigp	%r0,%r5,__SIGP_STOP	/* stop current CPU */
-	brc	2,2b			/* busy, try again */
-3:	j	3b
-
-ENTRY(smp_restart_cpu)
-	larl	%r1,.gprregs
-	lmg	%r0,%r15,0(%r1)
-1:	sigp	%r0,%r5,__SIGP_SENSE	/* Wait for calling CPU */
-	brc	10,1b			/* busy, accepted (status 0), running */
-	tmll	%r0,0x40		/* Test if calling CPU is stopped */
-	jz	1b
-	ltgr	%r4,%r4			/* New stack ? */
-	jz	1f
-	lgr	%r15,%r4
-1:	lgr	%r14,%r2		/* r14: Function to call */
-	lgr	%r2,%r3			/* r2 : Parameter for function*/
-	basr	%r14,%r14		/* Call function */
-
-	.section .data,"aw",@progbits
-.gprregs:
-	.rept	16
-	.quad	0
-	.endr
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index acb78cd..ad3c79e 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -42,7 +42,7 @@ ENTRY(swsusp_arch_suspend)
 	lghi	%r1,0x1000
 
 	/* Save CPU address */
-	stap	__LC_CPU_ADDRESS(%r0)
+	stap	__LC_EXT_CPU_ADDR(%r0)
 
 	/* Store registers */
 	mvc	0x318(4,%r1),__SF_EMPTY(%r15)	/* move prefix to lowcore */
@@ -173,15 +173,15 @@ pgm_check_entry:
 	larl	%r1,.Lresume_cpu		/* Resume CPU address: r2 */
 	stap	0(%r1)
 	llgh	%r2,0(%r1)
-	llgh	%r1,__LC_CPU_ADDRESS(%r0)	/* Suspend CPU address: r1 */
+	llgh	%r1,__LC_EXT_CPU_ADDR(%r0)	/* Suspend CPU address: r1 */
 	cgr	%r1,%r2
 	je	restore_registers		/* r1 = r2 -> nothing to do */
 	larl	%r4,.Lrestart_suspend_psw	/* Set new restart PSW */
 	mvc	__LC_RST_NEW_PSW(16,%r0),0(%r4)
 3:
-	sigp	%r9,%r1,__SIGP_INITIAL_CPU_RESET
-	brc	8,4f	/* accepted */
-	brc	2,3b	/* busy, try again */
+	sigp	%r9,%r1,11			/* sigp initial cpu reset */
+	brc	8,4f				/* accepted */
+	brc	2,3b				/* busy, try again */
 
 	/* Suspend CPU not available -> panic */
 	larl	%r15,init_thread_union
@@ -196,10 +196,10 @@ pgm_check_entry:
 	lpsw	0(%r3)
 4:
 	/* Switch to suspend CPU */
-	sigp	%r9,%r1,__SIGP_RESTART	/* start suspend CPU */
+	sigp	%r9,%r1,6		/* sigp restart to suspend CPU */
 	brc	2,4b			/* busy, try again */
 5:
-	sigp	%r9,%r2,__SIGP_STOP	/* stop resume (current) CPU */
+	sigp	%r9,%r2,5		/* sigp stop to current resume CPU */
 	brc	2,5b			/* busy, try again */
 6:	j	6b
 
@@ -207,7 +207,7 @@ restart_suspend:
 	larl	%r1,.Lresume_cpu
 	llgh	%r2,0(%r1)
 7:
-	sigp	%r9,%r2,__SIGP_SENSE	/* Wait for resume CPU */
+	sigp	%r9,%r2,1		/* sigp sense, wait for resume CPU */
 	brc	8,7b			/* accepted, status 0, still running */
 	brc	2,7b			/* busy, try again */
 	tmll	%r9,0x40		/* Test if resume CPU is stopped */
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index fa02f44..d4e1cb1 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -113,11 +113,14 @@ static void fixup_clock_comparator(unsigned long long delta)
 static int s390_next_ktime(ktime_t expires,
 			   struct clock_event_device *evt)
 {
+	struct timespec ts;
 	u64 nsecs;
 
-	nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset()));
+	ts.tv_sec = ts.tv_nsec = 0;
+	monotonic_to_bootbased(&ts);
+	nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
 	do_div(nsecs, 125);
-	S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9);
+	S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
 	set_clock_comparator(S390_lowcore.clock_comparator);
 	return 0;
 }
@@ -162,7 +165,7 @@ void init_cpu_timer(void)
 	__ctl_set_bit(0, 4);
 }
 
-static void clock_comparator_interrupt(unsigned int ext_int_code,
+static void clock_comparator_interrupt(struct ext_code ext_code,
 				       unsigned int param32,
 				       unsigned long param64)
 {
@@ -174,7 +177,7 @@ static void clock_comparator_interrupt(unsigned int ext_int_code,
 static void etr_timing_alert(struct etr_irq_parm *);
 static void stp_timing_alert(struct stp_irq_parm *);
 
-static void timing_alert_interrupt(unsigned int ext_int_code,
+static void timing_alert_interrupt(struct ext_code ext_code,
 				   unsigned int param32, unsigned long param64)
 {
 	kstat_cpu(smp_processor_id()).irqs[EXTINT_TLA]++;
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 7370a41..4f8dc94 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -79,12 +79,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
 	     cpu < TOPOLOGY_CPU_BITS;
 	     cpu = find_next_bit(&tl_cpu->mask[0], TOPOLOGY_CPU_BITS, cpu + 1))
 	{
-		unsigned int rcpu, lcpu;
+		unsigned int rcpu;
+		int lcpu;
 
 		rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin;
-		for_each_present_cpu(lcpu) {
-			if (cpu_logical_map(lcpu) != rcpu)
-				continue;
+		lcpu = smp_find_processor_id(rcpu);
+		if (lcpu >= 0) {
 			cpumask_set_cpu(lcpu, &book->mask);
 			cpu_book_id[lcpu] = book->id;
 			cpumask_set_cpu(lcpu, &core->mask);
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index d73630b..dfcc586 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -89,18 +89,11 @@ static void vdso_init_data(struct vdso_data *vd)
 
 #ifdef CONFIG_64BIT
 /*
- * Setup per cpu vdso data page.
- */
-static void vdso_init_per_cpu_data(int cpu, struct vdso_per_cpu_data *vpcd)
-{
-}
-
-/*
  * Allocate/free per cpu vdso data.
  */
 #define SEGMENT_ORDER	2
 
-int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore)
+int vdso_alloc_per_cpu(struct _lowcore *lowcore)
 {
 	unsigned long segment_table, page_table, page_frame;
 	u32 *psal, *aste;
@@ -139,7 +132,6 @@ int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore)
 	aste[4] = (u32)(addr_t) psal;
 	lowcore->vdso_per_cpu_data = page_frame;
 
-	vdso_init_per_cpu_data(cpu, (struct vdso_per_cpu_data *) page_frame);
 	return 0;
 
 out:
@@ -149,7 +141,7 @@ out:
 	return -ENOMEM;
 }
 
-void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore)
+void vdso_free_per_cpu(struct _lowcore *lowcore)
 {
 	unsigned long segment_table, page_table, page_frame;
 	u32 *psal, *aste;
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index bb48977..39ebff5 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -26,6 +26,7 @@
 #include <asm/irq_regs.h>
 #include <asm/cputime.h>
 #include <asm/irq.h>
+#include "entry.h"
 
 static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
 
@@ -123,153 +124,53 @@ void account_system_vtime(struct task_struct *tsk)
 }
 EXPORT_SYMBOL_GPL(account_system_vtime);
 
-void __kprobes vtime_start_cpu(__u64 int_clock, __u64 enter_timer)
+void __kprobes vtime_stop_cpu(void)
 {
 	struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
 	struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer);
-	__u64 idle_time, expires;
+	unsigned long long idle_time;
+	unsigned long psw_mask;
 
-	if (idle->idle_enter == 0ULL)
-		return;
+	trace_hardirqs_on();
+	/* Don't trace preempt off for idle. */
+	stop_critical_timings();
 
-	/* Account time spent with enabled wait psw loaded as idle time. */
-	idle_time = int_clock - idle->idle_enter;
-	account_idle_time(idle_time);
-	S390_lowcore.steal_timer +=
-		idle->idle_enter - S390_lowcore.last_update_clock;
-	S390_lowcore.last_update_clock = int_clock;
-
-	/* Account system time spent going idle. */
-	S390_lowcore.system_timer += S390_lowcore.last_update_timer - vq->idle;
-	S390_lowcore.last_update_timer = enter_timer;
-
-	/* Restart vtime CPU timer */
-	if (vq->do_spt) {
-		/* Program old expire value but first save progress. */
-		expires = vq->idle - enter_timer;
-		expires += get_vtimer();
-		set_vtimer(expires);
-	} else {
-		/* Don't account the CPU timer delta while the cpu was idle. */
-		vq->elapsed -= vq->idle - enter_timer;
-	}
+	/* Wait for external, I/O or machine check interrupt. */
+	psw_mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_DAT |
+		PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
+	idle->nohz_delay = 0;
 
+	/* Call the assembler magic in entry.S */
+	psw_idle(idle, vq, psw_mask, !list_empty(&vq->list));
+
+	/* Reenable preemption tracer. */
+	start_critical_timings();
+
+	/* Account time spent with enabled wait psw loaded as idle time. */
 	idle->sequence++;
 	smp_wmb();
+	idle_time = idle->idle_exit - idle->idle_enter;
 	idle->idle_time += idle_time;
-	idle->idle_enter = 0ULL;
+	idle->idle_enter = idle->idle_exit = 0ULL;
 	idle->idle_count++;
+	account_idle_time(idle_time);
 	smp_wmb();
 	idle->sequence++;
 }
 
-void __kprobes vtime_stop_cpu(void)
-{
-	struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
-	struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer);
-	psw_t psw;
-
-	/* Wait for external, I/O or machine check interrupt. */
-	psw.mask = psw_kernel_bits | PSW_MASK_WAIT |
-		PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
-
-	idle->nohz_delay = 0;
-
-	/* Check if the CPU timer needs to be reprogrammed. */
-	if (vq->do_spt) {
-		__u64 vmax = VTIMER_MAX_SLICE;
-		/*
-		 * The inline assembly is equivalent to
-		 *	vq->idle = get_cpu_timer();
-		 *	set_cpu_timer(VTIMER_MAX_SLICE);
-		 *	idle->idle_enter = get_clock();
-		 *	__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
-		 *			   PSW_MASK_DAT | PSW_MASK_IO |
-		 *			   PSW_MASK_EXT | PSW_MASK_MCHECK);
-		 * The difference is that the inline assembly makes sure that
-		 * the last three instruction are stpt, stck and lpsw in that
-		 * order. This is done to increase the precision.
-		 */
-		asm volatile(
-#ifndef CONFIG_64BIT
-			"	basr	1,0\n"
-			"0:	ahi	1,1f-0b\n"
-			"	st	1,4(%2)\n"
-#else /* CONFIG_64BIT */
-			"	larl	1,1f\n"
-			"	stg	1,8(%2)\n"
-#endif /* CONFIG_64BIT */
-			"	stpt	0(%4)\n"
-			"	spt	0(%5)\n"
-			"	stck	0(%3)\n"
-#ifndef CONFIG_64BIT
-			"	lpsw	0(%2)\n"
-#else /* CONFIG_64BIT */
-			"	lpswe	0(%2)\n"
-#endif /* CONFIG_64BIT */
-			"1:"
-			: "=m" (idle->idle_enter), "=m" (vq->idle)
-			: "a" (&psw), "a" (&idle->idle_enter),
-			  "a" (&vq->idle), "a" (&vmax), "m" (vmax), "m" (psw)
-			: "memory", "cc", "1");
-	} else {
-		/*
-		 * The inline assembly is equivalent to
-		 *	vq->idle = get_cpu_timer();
-		 *	idle->idle_enter = get_clock();
-		 *	__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
-		 *			   PSW_MASK_DAT | PSW_MASK_IO |
-		 *			   PSW_MASK_EXT | PSW_MASK_MCHECK);
-		 * The difference is that the inline assembly makes sure that
-		 * the last three instruction are stpt, stck and lpsw in that
-		 * order. This is done to increase the precision.
-		 */
-		asm volatile(
-#ifndef CONFIG_64BIT
-			"	basr	1,0\n"
-			"0:	ahi	1,1f-0b\n"
-			"	st	1,4(%2)\n"
-#else /* CONFIG_64BIT */
-			"	larl	1,1f\n"
-			"	stg	1,8(%2)\n"
-#endif /* CONFIG_64BIT */
-			"	stpt	0(%4)\n"
-			"	stck	0(%3)\n"
-#ifndef CONFIG_64BIT
-			"	lpsw	0(%2)\n"
-#else /* CONFIG_64BIT */
-			"	lpswe	0(%2)\n"
-#endif /* CONFIG_64BIT */
-			"1:"
-			: "=m" (idle->idle_enter), "=m" (vq->idle)
-			: "a" (&psw), "a" (&idle->idle_enter),
-			  "a" (&vq->idle), "m" (psw)
-			: "memory", "cc", "1");
-	}
-}
-
 cputime64_t s390_get_idle_time(int cpu)
 {
-	struct s390_idle_data *idle;
-	unsigned long long now, idle_time, idle_enter;
+	struct s390_idle_data *idle = &per_cpu(s390_idle, cpu);
+	unsigned long long now, idle_enter, idle_exit;
 	unsigned int sequence;
 
-	idle = &per_cpu(s390_idle, cpu);
-
-	now = get_clock();
-repeat:
-	sequence = idle->sequence;
-	smp_rmb();
-	if (sequence & 1)
-		goto repeat;
-	idle_time = 0;
-	idle_enter = idle->idle_enter;
-	if (idle_enter != 0ULL && idle_enter < now)
-		idle_time = now - idle_enter;
-	smp_rmb();
-	if (idle->sequence != sequence)
-		goto repeat;
-	return idle_time;
+	do {
+		now = get_clock();
+		sequence = ACCESS_ONCE(idle->sequence);
+		idle_enter = ACCESS_ONCE(idle->idle_enter);
+		idle_exit = ACCESS_ONCE(idle->idle_exit);
+	} while ((sequence & 1) || (idle->sequence != sequence));
+	return idle_enter ? ((idle_exit ? : now) - idle_enter) : 0;
 }
 
 /*
@@ -319,7 +220,7 @@ static void do_callbacks(struct list_head *cb_list)
 /*
  * Handler for the virtual CPU timer.
  */
-static void do_cpu_timer_interrupt(unsigned int ext_int_code,
+static void do_cpu_timer_interrupt(struct ext_code ext_code,
 				   unsigned int param32, unsigned long param64)
 {
 	struct vtimer_queue *vq;
@@ -346,7 +247,6 @@ static void do_cpu_timer_interrupt(unsigned int ext_int_code,
 	}
 	spin_unlock(&vq->lock);
 
-	vq->do_spt = list_empty(&cb_list);
 	do_callbacks(&cb_list);
 
 	/* next event is first in list */
@@ -355,8 +255,7 @@ static void do_cpu_timer_interrupt(unsigned int ext_int_code,
 	if (!list_empty(&vq->list)) {
 		event = list_first_entry(&vq->list, struct vtimer_list, entry);
 		next = event->expires;
-	} else
-		vq->do_spt = 0;
+	}
 	spin_unlock(&vq->lock);
 	/*
 	 * To improve precision add the time spent by the
@@ -570,6 +469,9 @@ void init_cpu_vtimer(void)
 
 	/* enable cpu timer interrupts */
 	__ctl_set_bit(0,10);
+
+	/* set initial cpu timer */
+	set_vtimer(0x7fffffffffffffffULL);
 }
 
 static int __cpuinit s390_nohz_notify(struct notifier_block *self,
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 0243454..a5f6eff 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -133,13 +133,6 @@ static int handle_stop(struct kvm_vcpu *vcpu)
 
 	vcpu->stat.exit_stop_request++;
 	spin_lock_bh(&vcpu->arch.local_int.lock);
-	if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
-		vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
-		rc = kvm_s390_vcpu_store_status(vcpu,
-						  KVM_S390_STORE_STATUS_NOADDR);
-		if (rc >= 0)
-			rc = -EOPNOTSUPP;
-	}
 
 	if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) {
 		vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP;
@@ -155,7 +148,18 @@ static int handle_stop(struct kvm_vcpu *vcpu)
 		rc = -EOPNOTSUPP;
 	}
 
-	spin_unlock_bh(&vcpu->arch.local_int.lock);
+	if (vcpu->arch.local_int.action_bits & ACTION_STORE_ON_STOP) {
+		vcpu->arch.local_int.action_bits &= ~ACTION_STORE_ON_STOP;
+		/* store status must be called unlocked. Since local_int.lock
+		 * only protects local_int.* and not guest memory we can give
+		 * up the lock here */
+		spin_unlock_bh(&vcpu->arch.local_int.lock);
+		rc = kvm_s390_vcpu_store_status(vcpu,
+						KVM_S390_STORE_STATUS_NOADDR);
+		if (rc >= 0)
+			rc = -EOPNOTSUPP;
+	} else
+		spin_unlock_bh(&vcpu->arch.local_int.lock);
 	return rc;
 }
 
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 278ee00..f0647ce 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -134,7 +134,7 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
 		if (rc == -EFAULT)
 			exception = 1;
 
-		rc = put_guest_u16(vcpu, __LC_CPU_ADDRESS, inti->emerg.code);
+		rc = put_guest_u16(vcpu, __LC_EXT_CPU_ADDR, inti->emerg.code);
 		if (rc == -EFAULT)
 			exception = 1;
 
@@ -156,7 +156,7 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
 		if (rc == -EFAULT)
 			exception = 1;
 
-		rc = put_guest_u16(vcpu, __LC_CPU_ADDRESS, inti->extcall.code);
+		rc = put_guest_u16(vcpu, __LC_EXT_CPU_ADDR, inti->extcall.code);
 		if (rc == -EFAULT)
 			exception = 1;
 
@@ -202,7 +202,7 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
 		if (rc == -EFAULT)
 			exception = 1;
 
-		rc = put_guest_u16(vcpu, __LC_CPU_ADDRESS, 0x0d00);
+		rc = put_guest_u16(vcpu, __LC_EXT_CPU_ADDR, 0x0d00);
 		if (rc == -EFAULT)
 			exception = 1;
 
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index d1c44573..d3cb86c 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -418,7 +418,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
 {
 	memcpy(&vcpu->arch.guest_fpregs.fprs, &fpu->fprs, sizeof(fpu->fprs));
-	vcpu->arch.guest_fpregs.fpc = fpu->fpc;
+	vcpu->arch.guest_fpregs.fpc = fpu->fpc & FPC_VALID_MASK;
 	restore_fp_regs(&vcpu->arch.guest_fpregs);
 	return 0;
 }
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index db92f04..9f1f71e 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -13,6 +13,7 @@
 #include <linux/irqflags.h>
 #include <linux/interrupt.h>
 #include <asm/div64.h>
+#include <asm/timer.h>
 
 void __delay(unsigned long loops)
 {
@@ -28,36 +29,33 @@ void __delay(unsigned long loops)
 
 static void __udelay_disabled(unsigned long long usecs)
 {
-	unsigned long mask, cr0, cr0_saved;
-	u64 clock_saved;
-	u64 end;
+	unsigned long cr0, cr6, new;
+	u64 clock_saved, end;
 
-	mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_WAIT |
-		PSW_MASK_EXT | PSW_MASK_MCHECK;
 	end = get_clock() + (usecs << 12);
 	clock_saved = local_tick_disable();
-	__ctl_store(cr0_saved, 0, 0);
-	cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
-	__ctl_load(cr0 , 0, 0);
+	__ctl_store(cr0, 0, 0);
+	__ctl_store(cr6, 6, 6);
+	new = (cr0 &  0xffff00e0) | 0x00000800;
+	__ctl_load(new , 0, 0);
+	new = 0;
+	__ctl_load(new, 6, 6);
 	lockdep_off();
 	do {
 		set_clock_comparator(end);
-		trace_hardirqs_on();
-		__load_psw_mask(mask);
+		vtime_stop_cpu();
 		local_irq_disable();
 	} while (get_clock() < end);
 	lockdep_on();
-	__ctl_load(cr0_saved, 0, 0);
+	__ctl_load(cr0, 0, 0);
+	__ctl_load(cr6, 6, 6);
 	local_tick_enable(clock_saved);
 }
 
 static void __udelay_enabled(unsigned long long usecs)
 {
-	unsigned long mask;
-	u64 clock_saved;
-	u64 end;
+	u64 clock_saved, end;
 
-	mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO;
 	end = get_clock() + (usecs << 12);
 	do {
 		clock_saved = 0;
@@ -65,8 +63,7 @@ static void __udelay_enabled(unsigned long long usecs)
 			clock_saved = local_tick_disable();
 			set_clock_comparator(end);
 		}
-		trace_hardirqs_on();
-		__load_psw_mask(mask);
+		vtime_stop_cpu();
 		local_irq_disable();
 		if (clock_saved)
 			local_tick_enable(clock_saved);
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 91754ff..093eb69 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/smp.h>
 #include <asm/io.h>
 
 int spin_retry = 1000;
@@ -24,21 +25,6 @@ static int __init spin_retry_setup(char *str)
 }
 __setup("spin_retry=", spin_retry_setup);
 
-static inline void _raw_yield(void)
-{
-	if (MACHINE_HAS_DIAG44)
-		asm volatile("diag 0,0,0x44");
-}
-
-static inline void _raw_yield_cpu(int cpu)
-{
-	if (MACHINE_HAS_DIAG9C)
-		asm volatile("diag %0,0,0x9c"
-			     : : "d" (cpu_logical_map(cpu)));
-	else
-		_raw_yield();
-}
-
 void arch_spin_lock_wait(arch_spinlock_t *lp)
 {
 	int count = spin_retry;
@@ -60,7 +46,7 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
 		}
 		owner = lp->owner_cpu;
 		if (owner)
-			_raw_yield_cpu(~owner);
+			smp_yield_cpu(~owner);
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
 			return;
 	}
@@ -91,7 +77,7 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
 		}
 		owner = lp->owner_cpu;
 		if (owner)
-			_raw_yield_cpu(~owner);
+			smp_yield_cpu(~owner);
 		local_irq_disable();
 		if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0)
 			return;
@@ -121,7 +107,7 @@ void arch_spin_relax(arch_spinlock_t *lock)
 	if (cpu != 0) {
 		if (MACHINE_IS_VM || MACHINE_IS_KVM ||
 		    !smp_vcpu_scheduled(~cpu))
-			_raw_yield_cpu(~cpu);
+			smp_yield_cpu(~cpu);
 	}
 }
 EXPORT_SYMBOL(arch_spin_relax);
@@ -133,7 +119,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw)
 
 	while (1) {
 		if (count-- <= 0) {
-			_raw_yield();
+			smp_yield();
 			count = spin_retry;
 		}
 		if (!arch_read_can_lock(rw))
@@ -153,7 +139,7 @@ void _raw_read_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags)
 	local_irq_restore(flags);
 	while (1) {
 		if (count-- <= 0) {
-			_raw_yield();
+			smp_yield();
 			count = spin_retry;
 		}
 		if (!arch_read_can_lock(rw))
@@ -188,7 +174,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
 
 	while (1) {
 		if (count-- <= 0) {
-			_raw_yield();
+			smp_yield();
 			count = spin_retry;
 		}
 		if (!arch_write_can_lock(rw))
@@ -206,7 +192,7 @@ void _raw_write_lock_wait_flags(arch_rwlock_t *rw, unsigned long flags)
 	local_irq_restore(flags);
 	while (1) {
 		if (count-- <= 0) {
-			_raw_yield();
+			smp_yield();
 			count = spin_retry;
 		}
 		if (!arch_write_can_lock(rw))
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 354dd39..895389e 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -533,7 +533,7 @@ void pfault_fini(void)
 static DEFINE_SPINLOCK(pfault_lock);
 static LIST_HEAD(pfault_list);
 
-static void pfault_interrupt(unsigned int ext_int_code,
+static void pfault_interrupt(struct ext_code ext_code,
 			     unsigned int param32, unsigned long param64)
 {
 	struct task_struct *tsk;
@@ -546,7 +546,7 @@ static void pfault_interrupt(unsigned int ext_int_code,
 	 * in the 'cpu address' field associated with the
          * external interrupt. 
 	 */
-	subcode = ext_int_code >> 16;
+	subcode = ext_code.subcode;
 	if ((subcode & 0xff00) != __SUBCODE_MASK)
 		return;
 	kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 9a4d02f..51b0738 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -574,7 +574,7 @@ static inline void page_table_free_pgste(unsigned long *table)
 	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
 	mp = (struct gmap_pgtable *) page->index;
 	BUG_ON(!list_empty(&mp->mapper));
-	pgtable_page_ctor(page);
+	pgtable_page_dtor(page);
 	atomic_set(&page->_mapcount, -1);
 	kfree(mp);
 	__free_page(page);
diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c
index 9daee91..12bea05 100644
--- a/arch/s390/oprofile/hwsampler.c
+++ b/arch/s390/oprofile/hwsampler.c
@@ -233,8 +233,8 @@ static inline unsigned long *trailer_entry_ptr(unsigned long v)
 }
 
 /* prototypes for external interrupt handler and worker */
-static void hws_ext_handler(unsigned int ext_int_code,
-				unsigned int param32, unsigned long param64);
+static void hws_ext_handler(struct ext_code ext_code,
+			    unsigned int param32, unsigned long param64);
 
 static void worker(struct work_struct *work);
 
@@ -673,7 +673,7 @@ int hwsampler_activate(unsigned int cpu)
 	return rc;
 }
 
-static void hws_ext_handler(unsigned int ext_int_code,
+static void hws_ext_handler(struct ext_code ext_code,
 			    unsigned int param32, unsigned long param64)
 {
 	struct hws_cpu_buffer *cb;
diff --git a/arch/score/Kconfig.debug b/arch/score/Kconfig.debug
index a1f346d..d8a9b2d 100644
--- a/arch/score/Kconfig.debug
+++ b/arch/score/Kconfig.debug
@@ -22,7 +22,7 @@ config RUNTIME_DEBUG
 	help
 	  If you say Y here, some debugging macros will do run-time checking.
 	  If you say N here, those macros will mostly turn to no-ops.  See
-	  include/asm-score/debug.h for debuging macros.
+	  include/asm-score/debug.h for debugging macros.
 	  If unsure, say N.
 
 endmenu
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
index aa57440..5a5bd17 100644
--- a/arch/score/kernel/signal.c
+++ b/arch/score/kernel/signal.c
@@ -159,10 +159,7 @@ score_rt_sigreturn(struct pt_regs *regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
 	if (sig < 0)
@@ -272,12 +269,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 	 */
 	ret = setup_rt_frame(ka, regs, sig, oldset, info);
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 713fb58..b190eb1 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -22,7 +22,7 @@ config SUPERH
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_GENERIC_HARDIRQS
-	select HAVE_SPARSE_IRQ
+	select MAY_HAVE_SPARSE_IRQ
 	select IRQ_FORCED_THREADING
 	select RTC_LIB
 	select GENERIC_ATOMIC64
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 033ef2b..1e146fc 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -767,7 +767,9 @@ static struct platform_device camera_devices[] = {
 
 /* FSI */
 static struct sh_fsi_platform_info fsi_info = {
-	.portb_flags = SH_FSI_BRS_INV,
+	.port_b = {
+		.flags = SH_FSI_BRS_INV,
+	},
 };
 
 static struct resource fsi_resources[] = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 036fe1a..1fc5d47 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -277,7 +277,9 @@ static struct platform_device ceu1_device = {
 /* FSI */
 /* change J20, J21, J22 pin to 1-2 connection to use slave mode */
 static struct sh_fsi_platform_info fsi_info = {
-	.porta_flags = SH_FSI_BRS_INV,
+	.port_a = {
+		.flags = SH_FSI_BRS_INV,
+	},
 };
 
 static struct resource fsi_resources[] = {
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index fa7b978..fb8f1499 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -74,7 +74,7 @@ struct pci_errors {
 	{ SH4_PCIINT_MLCK,	"master lock error" },
 	{ SH4_PCIINT_TABT,	"target-target abort" },
 	{ SH4_PCIINT_TRET,	"target retry time out" },
-	{ SH4_PCIINT_MFDE,	"master function disable erorr" },
+	{ SH4_PCIINT_MFDE,	"master function disable error" },
 	{ SH4_PCIINT_PRTY,	"address parity error" },
 	{ SH4_PCIINT_SERR,	"SERR" },
 	{ SH4_PCIINT_TWDP,	"data parity error for target write" },
diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h
index 1a73c3e..8bd965e 100644
--- a/arch/sh/include/asm/dma-mapping.h
+++ b/arch/sh/include/asm/dma-mapping.h
@@ -52,25 +52,31 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 	return dma_addr == 0;
 }
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t gfp)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t gfp,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *memory;
 
 	if (dma_alloc_from_coherent(dev, size, dma_handle, &memory))
 		return memory;
-	if (!ops->alloc_coherent)
+	if (!ops->alloc)
 		return NULL;
 
-	memory = ops->alloc_coherent(dev, size, dma_handle, gfp);
+	memory = ops->alloc(dev, size, dma_handle, gfp, attrs);
 	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
 
 	return memory;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -78,14 +84,16 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 		return;
 
 	debug_dma_free_coherent(dev, size, vaddr, dma_handle);
-	if (ops->free_coherent)
-		ops->free_coherent(dev, size, vaddr, dma_handle);
+	if (ops->free)
+		ops->free(dev, size, vaddr, dma_handle, attrs);
 }
 
 /* arch/sh/mm/consistent.c */
 extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-					dma_addr_t *dma_addr, gfp_t flag);
+					dma_addr_t *dma_addr, gfp_t flag,
+					struct dma_attrs *attrs);
 extern void dma_generic_free_coherent(struct device *dev, size_t size,
-				      void *vaddr, dma_addr_t dma_handle);
+				      void *vaddr, dma_addr_t dma_handle,
+				      struct dma_attrs *attrs);
 
 #endif /* __ASM_SH_DMA_MAPPING_H */
diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h
index 45d08b6..2a62017 100644
--- a/arch/sh/include/asm/irq.h
+++ b/arch/sh/include/asm/irq.h
@@ -21,17 +21,6 @@
 #define NO_IRQ_IGNORE		((unsigned int)-1)
 
 /*
- * Convert back and forth between INTEVT and IRQ values.
- */
-#ifdef CONFIG_CPU_HAS_INTEVT
-#define evt2irq(evt)		(((evt) >> 5) - 16)
-#define irq2evt(irq)		(((irq) + 16) << 5)
-#else
-#define evt2irq(evt)		(evt)
-#define irq2evt(irq)		(irq)
-#endif
-
-/*
  * Simple Mask Register Support
  */
 extern void make_maskreg_irq(unsigned int irq);
diff --git a/arch/sh/include/asm/posix_types_32.h b/arch/sh/include/asm/posix_types_32.h
index 6a9ceaa..abda584 100644
--- a/arch/sh/include/asm/posix_types_32.h
+++ b/arch/sh/include/asm/posix_types_32.h
@@ -12,11 +12,6 @@ typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
 #define __kernel_gid_t __kernel_gid_t
 
-typedef unsigned int	__kernel_uid32_t;
-#define __kernel_uid32_t __kernel_uid32_t
-typedef unsigned int	__kernel_gid32_t;
-#define __kernel_gid32_t __kernel_gid32_t
-
 typedef unsigned short	__kernel_old_uid_t;
 #define __kernel_old_uid_t __kernel_old_uid_t
 typedef unsigned short	__kernel_old_gid_t;
diff --git a/arch/sh/include/asm/posix_types_64.h b/arch/sh/include/asm/posix_types_64.h
index 8cd1148..fcda07b 100644
--- a/arch/sh/include/asm/posix_types_64.h
+++ b/arch/sh/include/asm/posix_types_64.h
@@ -17,10 +17,6 @@ typedef int		__kernel_ssize_t;
 #define __kernel_ssize_t __kernel_ssize_t
 typedef int		__kernel_ptrdiff_t;
 #define __kernel_ptrdiff_t __kernel_ptrdiff_t
-typedef unsigned int	__kernel_uid32_t;
-#define __kernel_uid32_t __kernel_uid32_t
-typedef unsigned int	__kernel_gid32_t;
-#define __kernel_gid32_t __kernel_gid32_t
 
 typedef unsigned short	__kernel_old_uid_t;
 #define __kernel_old_uid_t __kernel_old_uid_t
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
index 3c55b87..5b0bfcd 100644
--- a/arch/sh/kernel/dma-nommu.c
+++ b/arch/sh/kernel/dma-nommu.c
@@ -63,8 +63,8 @@ static void nommu_sync_sg(struct device *dev, struct scatterlist *sg,
 #endif
 
 struct dma_map_ops nommu_dma_ops = {
-	.alloc_coherent		= dma_generic_alloc_coherent,
-	.free_coherent		= dma_generic_free_coherent,
+	.alloc			= dma_generic_alloc_coherent,
+	.free			= dma_generic_free_coherent,
 	.map_page		= nommu_map_page,
 	.map_sg			= nommu_map_sg,
 #ifdef CONFIG_DMA_NONCOHERENT
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index a7a55ed..883d711 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -58,12 +58,13 @@ sys_sigsuspend(old_sigset_t mask,
 	       unsigned long r5, unsigned long r6, unsigned long r7,
 	       struct pt_regs __regs)
 {
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
+	sigset_t blocked;
+
 	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
@@ -240,11 +241,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->sc, &r0))
 		goto badframe;
@@ -274,10 +271,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
 		goto badframe;
@@ -548,17 +542,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
 	else
 		ret = setup_frame(sig, ka, oldset, regs);
 
-	if (ka->sa.sa_flags & SA_ONESHOT)
-		ka->sa.sa_handler = SIG_DFL;
-
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked,sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 6b5603f..3c9a6f7 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -159,14 +159,13 @@ sys_sigsuspend(old_sigset_t mask,
 	       unsigned long r6, unsigned long r7,
 	       struct pt_regs * regs)
 {
-	sigset_t saveset;
+	sigset_t saveset, blocked;
 
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+
+	mask &= _BLOCKABLE;
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	REF_REG_RET = -EINTR;
 	while (1) {
@@ -198,11 +197,8 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
 	if (copy_from_user(&newset, unewset, sizeof(newset)))
 		return -EFAULT;
 	sigdelsetmask(&newset, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	REF_REG_RET = -EINTR;
 	while (1) {
@@ -408,11 +404,7 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->sc, &ret))
 		goto badframe;
@@ -445,10 +437,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
 		goto badframe;
@@ -734,17 +723,8 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	else
 		ret = setup_frame(sig, ka, oldset, regs);
 
-	if (ka->sa.sa_flags & SA_ONESHOT)
-		ka->sa.sa_handler = SIG_DFL;
-
-	if (ret == 0) {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked,sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	if (ret == 0)
+		block_sigmask(ka, sig);
 
 	return ret;
 }
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 92eb986..112fea1 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -244,7 +244,7 @@ static void sh4_flush_cache_page(void *args)
 		if (map_coherent)
 			vaddr = kmap_coherent(page, address);
 		else
-			vaddr = kmap_atomic(page, KM_USER0);
+			vaddr = kmap_atomic(page);
 
 		address = (unsigned long)vaddr;
 	}
@@ -259,7 +259,7 @@ static void sh4_flush_cache_page(void *args)
 		if (map_coherent)
 			kunmap_coherent(vaddr);
 		else
-			kunmap_atomic(vaddr, KM_USER0);
+			kunmap_atomic(vaddr);
 	}
 }
 
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 5a580ea..616966a 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -95,7 +95,7 @@ void copy_user_highpage(struct page *to, struct page *from,
 {
 	void *vfrom, *vto;
 
-	vto = kmap_atomic(to, KM_USER1);
+	vto = kmap_atomic(to);
 
 	if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
 	    test_bit(PG_dcache_clean, &from->flags)) {
@@ -103,16 +103,16 @@ void copy_user_highpage(struct page *to, struct page *from,
 		copy_page(vto, vfrom);
 		kunmap_coherent(vfrom);
 	} else {
-		vfrom = kmap_atomic(from, KM_USER0);
+		vfrom = kmap_atomic(from);
 		copy_page(vto, vfrom);
-		kunmap_atomic(vfrom, KM_USER0);
+		kunmap_atomic(vfrom);
 	}
 
 	if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK) ||
 	    (vma->vm_flags & VM_EXEC))
 		__flush_purge_region(vto, PAGE_SIZE);
 
-	kunmap_atomic(vto, KM_USER1);
+	kunmap_atomic(vto);
 	/* Make sure this page is cleared on other CPU's too before using it */
 	smp_wmb();
 }
@@ -120,14 +120,14 @@ EXPORT_SYMBOL(copy_user_highpage);
 
 void clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *kaddr = kmap_atomic(page, KM_USER0);
+	void *kaddr = kmap_atomic(page);
 
 	clear_page(kaddr);
 
 	if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK))
 		__flush_purge_region(kaddr, PAGE_SIZE);
 
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 EXPORT_SYMBOL(clear_user_highpage);
 
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index f251b5f..b81d9db 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -33,7 +33,8 @@ static int __init dma_init(void)
 fs_initcall(dma_init);
 
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-				 dma_addr_t *dma_handle, gfp_t gfp)
+				 dma_addr_t *dma_handle, gfp_t gfp,
+				 struct dma_attrs *attrs)
 {
 	void *ret, *ret_nocache;
 	int order = get_order(size);
@@ -64,7 +65,8 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,
 }
 
 void dma_generic_free_coherent(struct device *dev, size_t size,
-			       void *vaddr, dma_addr_t dma_handle)
+			       void *vaddr, dma_addr_t dma_handle,
+			       struct dma_attrs *attrs)
 {
 	int order = get_order(size);
 	unsigned long pfn = dma_handle >> PAGE_SHIFT;
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index ca5580e..6c0683d 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -29,6 +29,7 @@ config SPARC
 	select GENERIC_IRQ_SHOW
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select GENERIC_PCI_IOMAP
+	select HAVE_NMI_WATCHDOG if SPARC64
 
 config SPARC32
 	def_bool !64BIT
@@ -576,6 +577,7 @@ config COMPAT
 	depends on SPARC64
 	default y
 	select COMPAT_BINFMT_ELF
+	select ARCH_WANT_OLD_COMPAT_IPC
 
 config SYSVIPC_COMPAT
 	bool
diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h
index 8c0e4f7..48a7c65 100644
--- a/arch/sparc/include/asm/dma-mapping.h
+++ b/arch/sparc/include/asm/dma-mapping.h
@@ -26,24 +26,30 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 
 #include <asm-generic/dma-mapping-common.h>
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *cpu_addr;
 
-	cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag);
+	cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
 	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
 	return cpu_addr;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
 	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
-	ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	ops->free(dev, size, cpu_addr, dma_handle, attrs);
 }
 
 static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h
index 3d7afbb..3b6e00d 100644
--- a/arch/sparc/include/asm/highmem.h
+++ b/arch/sparc/include/asm/highmem.h
@@ -70,7 +70,7 @@ static inline void kunmap(struct page *page)
 	kunmap_high(page);
 }
 
-extern void *__kmap_atomic(struct page *page);
+extern void *kmap_atomic(struct page *page);
 extern void __kunmap_atomic(void *kvaddr);
 extern struct page *kmap_atomic_to_page(void *vaddr);
 
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h
index 16dcae6d..abf6afe 100644
--- a/arch/sparc/include/asm/irq_64.h
+++ b/arch/sparc/include/asm/irq_64.h
@@ -95,7 +95,6 @@ void arch_trigger_all_cpu_backtrace(void);
 extern void *hardirq_stack[NR_CPUS];
 extern void *softirq_stack[NR_CPUS];
 #define __ARCH_HAS_DO_SOFTIRQ
-#define ARCH_HAS_NMI_WATCHDOG
 
 #define NO_IRQ		0xffffffff
 
diff --git a/arch/sparc/include/asm/posix_types.h b/arch/sparc/include/asm/posix_types.h
index dbfc1a3..3070f25 100644
--- a/arch/sparc/include/asm/posix_types.h
+++ b/arch/sparc/include/asm/posix_types.h
@@ -9,35 +9,16 @@
 
 #if defined(__sparc__) && defined(__arch64__)
 /* sparc 64 bit */
-typedef unsigned long          __kernel_size_t;
-typedef long                   __kernel_ssize_t;
-typedef long                   __kernel_ptrdiff_t;
-typedef long                   __kernel_time_t;
-typedef long                   __kernel_clock_t;
-typedef int                    __kernel_pid_t;
-typedef int                    __kernel_ipc_pid_t;
-typedef unsigned int           __kernel_uid_t;
-typedef unsigned int           __kernel_gid_t;
-typedef unsigned long          __kernel_ino_t;
-typedef unsigned int           __kernel_mode_t;
 typedef unsigned int           __kernel_nlink_t;
-typedef int                    __kernel_daddr_t;
-typedef long                   __kernel_off_t;
-typedef char *                 __kernel_caddr_t;
-typedef unsigned short	       __kernel_uid16_t;
-typedef unsigned short	       __kernel_gid16_t;
-typedef int                    __kernel_clockid_t;
-typedef int                    __kernel_timer_t;
+#define __kernel_nlink_t __kernel_nlink_t
 
 typedef unsigned short 	       __kernel_old_uid_t;
 typedef unsigned short         __kernel_old_gid_t;
-typedef __kernel_uid_t	       __kernel_uid32_t;
-typedef __kernel_gid_t	       __kernel_gid32_t;
-
-typedef unsigned int	       __kernel_old_dev_t;
+#define __kernel_old_uid_t __kernel_old_uid_t
 
 /* Note this piece of asymmetry from the v9 ABI.  */
 typedef int		       __kernel_suseconds_t;
+#define __kernel_suseconds_t __kernel_suseconds_t
 
 #else
 /* sparc 32 bit */
@@ -45,109 +26,29 @@ typedef int		       __kernel_suseconds_t;
 typedef unsigned int           __kernel_size_t;
 typedef int                    __kernel_ssize_t;
 typedef long int               __kernel_ptrdiff_t;
-typedef long                   __kernel_time_t;
-typedef long		       __kernel_suseconds_t;
-typedef long                   __kernel_clock_t;
-typedef int                    __kernel_pid_t;
+#define __kernel_size_t __kernel_size_t
+
 typedef unsigned short         __kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short         __kernel_uid_t;
 typedef unsigned short         __kernel_gid_t;
-typedef unsigned long          __kernel_ino_t;
+#define __kernel_uid_t __kernel_uid_t
+
 typedef unsigned short         __kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef short                  __kernel_nlink_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef long                   __kernel_daddr_t;
-typedef long                   __kernel_off_t;
-typedef char *                 __kernel_caddr_t;
-typedef unsigned short	       __kernel_uid16_t;
-typedef unsigned short	       __kernel_gid16_t;
-typedef unsigned int	       __kernel_uid32_t;
-typedef unsigned int	       __kernel_gid32_t;
-typedef unsigned short	       __kernel_old_uid_t;
-typedef unsigned short	       __kernel_old_gid_t;
+#define __kernel_daddr_t __kernel_daddr_t
+
 typedef unsigned short	       __kernel_old_dev_t;
-typedef int                    __kernel_clockid_t;
-typedef int                    __kernel_timer_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
 #endif /* defined(__sparc__) && defined(__arch64__) */
 
-#ifdef __GNUC__
-typedef long long              __kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#ifdef __KERNEL__
-
-#undef __FD_SET
-static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant cases (8 or 32 longs,
- * for 256 and 1024-bit fd_sets respectively)
- */
-#undef __FD_ZERO
-static inline void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned long *tmp = p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-			case 32:
-			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			  tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-			  tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			  tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
-			  tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
-			  tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
-			  tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
-			  return;
-			case 16:
-			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			  tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-			  tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			  return;
-			case 8:
-			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			  tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			  return;
-			case 4:
-			  tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			  return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
+#include <asm-generic/posix_types.h>
 
-#endif /* __KERNEL__ */
 #endif /* __SPARC_POSIX_TYPES_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 8af1b64..68e2e27 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -60,6 +60,7 @@
 
 #define SO_WIFI_STATUS		0x0025
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		0x0026
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 4643d68..070ed14 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -280,7 +280,8 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx)
 }
 
 static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
-				   dma_addr_t *dma_addrp, gfp_t gfp)
+				   dma_addr_t *dma_addrp, gfp_t gfp,
+				   struct dma_attrs *attrs)
 {
 	unsigned long flags, order, first_page;
 	struct iommu *iommu;
@@ -330,7 +331,8 @@ static void *dma_4u_alloc_coherent(struct device *dev, size_t size,
 }
 
 static void dma_4u_free_coherent(struct device *dev, size_t size,
-				 void *cpu, dma_addr_t dvma)
+				 void *cpu, dma_addr_t dvma,
+				 struct dma_attrs *attrs)
 {
 	struct iommu *iommu;
 	unsigned long flags, order, npages;
@@ -825,8 +827,8 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
 }
 
 static struct dma_map_ops sun4u_dma_ops = {
-	.alloc_coherent		= dma_4u_alloc_coherent,
-	.free_coherent		= dma_4u_free_coherent,
+	.alloc			= dma_4u_alloc_coherent,
+	.free			= dma_4u_free_coherent,
 	.map_page		= dma_4u_map_page,
 	.unmap_page		= dma_4u_unmap_page,
 	.map_sg			= dma_4u_map_sg,
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index d0479e2..21bd739 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -261,7 +261,8 @@ EXPORT_SYMBOL(sbus_set_sbus64);
  * CPU may access them without any explicit flushing.
  */
 static void *sbus_alloc_coherent(struct device *dev, size_t len,
-				 dma_addr_t *dma_addrp, gfp_t gfp)
+				 dma_addr_t *dma_addrp, gfp_t gfp,
+				 struct dma_attrs *attrs)
 {
 	struct platform_device *op = to_platform_device(dev);
 	unsigned long len_total = PAGE_ALIGN(len);
@@ -315,7 +316,7 @@ err_nopages:
 }
 
 static void sbus_free_coherent(struct device *dev, size_t n, void *p,
-			       dma_addr_t ba)
+			       dma_addr_t ba, struct dma_attrs *attrs)
 {
 	struct resource *res;
 	struct page *pgv;
@@ -407,8 +408,8 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 }
 
 struct dma_map_ops sbus_dma_ops = {
-	.alloc_coherent		= sbus_alloc_coherent,
-	.free_coherent		= sbus_free_coherent,
+	.alloc			= sbus_alloc_coherent,
+	.free			= sbus_free_coherent,
 	.map_page		= sbus_map_page,
 	.unmap_page		= sbus_unmap_page,
 	.map_sg			= sbus_map_sg,
@@ -436,7 +437,8 @@ arch_initcall(sparc_register_ioport);
  * hwdev should be valid struct pci_dev pointer for PCI devices.
  */
 static void *pci32_alloc_coherent(struct device *dev, size_t len,
-				  dma_addr_t *pba, gfp_t gfp)
+				  dma_addr_t *pba, gfp_t gfp,
+				  struct dma_attrs *attrs)
 {
 	unsigned long len_total = PAGE_ALIGN(len);
 	void *va;
@@ -489,7 +491,7 @@ err_nopages:
  * past this call are illegal.
  */
 static void pci32_free_coherent(struct device *dev, size_t n, void *p,
-				dma_addr_t ba)
+				dma_addr_t ba, struct dma_attrs *attrs)
 {
 	struct resource *res;
 
@@ -645,8 +647,8 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist *
 }
 
 struct dma_map_ops pci32_dma_ops = {
-	.alloc_coherent		= pci32_alloc_coherent,
-	.free_coherent		= pci32_free_coherent,
+	.alloc			= pci32_alloc_coherent,
+	.free			= pci32_free_coherent,
 	.map_page		= pci32_map_page,
 	.unmap_page		= pci32_unmap_page,
 	.map_sg			= pci32_map_sg,
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index af5755d..7661e84 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -128,7 +128,8 @@ static inline long iommu_batch_end(void)
 }
 
 static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
-				   dma_addr_t *dma_addrp, gfp_t gfp)
+				   dma_addr_t *dma_addrp, gfp_t gfp,
+				   struct dma_attrs *attrs)
 {
 	unsigned long flags, order, first_page, npages, n;
 	struct iommu *iommu;
@@ -198,7 +199,7 @@ range_alloc_fail:
 }
 
 static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu,
-				 dma_addr_t dvma)
+				 dma_addr_t dvma, struct dma_attrs *attrs)
 {
 	struct pci_pbm_info *pbm;
 	struct iommu *iommu;
@@ -527,8 +528,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
 }
 
 static struct dma_map_ops sun4v_dma_ops = {
-	.alloc_coherent			= dma_4v_alloc_coherent,
-	.free_coherent			= dma_4v_free_coherent,
+	.alloc				= dma_4v_alloc_coherent,
+	.free				= dma_4v_free_coherent,
 	.map_page			= dma_4v_map_page,
 	.unmap_page			= dma_4v_unmap_page,
 	.map_sg				= dma_4v_map_sg,
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 023b886..c8f5b50 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -776,7 +776,6 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
 				  siginfo_t *info,
 				  sigset_t *oldset, struct pt_regs *regs)
 {
-	sigset_t blocked;
 	int err;
 
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -787,11 +786,7 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
 	if (err)
 		return err;
 
-	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NOMASK))
-		sigaddset(&blocked, signr);
-	set_current_blocked(&blocked);
-
+	block_sigmask(ka, signr);
 	tracehook_signal_handler(signr, info, ka, regs, 0);
 
 	return 0;
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index d54c6e5..7bb71b6 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -465,7 +465,6 @@ static inline int
 handle_signal(unsigned long signr, struct k_sigaction *ka,
 	      siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
 {
-	sigset_t blocked;
 	int err;
 
 	if (ka->sa.sa_flags & SA_SIGINFO)
@@ -476,11 +475,7 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
 	if (err)
 		return err;
 
-	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NOMASK))
-		sigaddset(&blocked, signr);
-	set_current_blocked(&blocked);
-
+	block_sigmask(ka, signr);
 	tracehook_signal_handler(signr, info, ka, regs, 0);
 
 	return 0;
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index f0836cd..d8a67e6 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -479,18 +479,14 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
 				siginfo_t *info,
 				sigset_t *oldset, struct pt_regs *regs)
 {
-	sigset_t blocked;
 	int err;
 
 	err = setup_rt_frame(ka, regs, signr, oldset,
 			     (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
 	if (err)
 		return err;
-	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NOMASK))
-		sigaddset(&blocked, signr);
-	set_current_blocked(&blocked);
 
+	block_sigmask(ka, signr);
 	tracehook_signal_handler(signr, info, ka, regs, 0);
 
 	return 0;
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index 76e4ac1..626e7b0 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -22,7 +22,6 @@
 #include <linux/bitops.h>
 #include <linux/perf_event.h>
 #include <linux/ratelimit.h>
-#include <linux/bitops.h>
 #include <asm/fpumacro.h>
 
 enum direction {
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 77140a0..055c66c 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -30,7 +30,7 @@
 #include <asm/tlbflush.h>
 #include <asm/fixmap.h>
 
-void *__kmap_atomic(struct page *page)
+void *kmap_atomic(struct page *page)
 {
 	unsigned long vaddr;
 	long idx, type;
@@ -64,7 +64,7 @@ void *__kmap_atomic(struct page *page)
 
 	return (void*) vaddr;
 }
-EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic);
 
 void __kunmap_atomic(void *kvaddr)
 {
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index bf95f55..4b4b289 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -242,17 +242,6 @@ long compat_sys_fallocate(int fd, int mode,
 long compat_sys_sched_rr_get_interval(compat_pid_t pid,
 				      struct compat_timespec __user *interval);
 
-/* Versions of compat functions that differ from generic Linux. */
-struct compat_msgbuf;
-long tile_compat_sys_msgsnd(int msqid,
-			    struct compat_msgbuf __user *msgp,
-			    size_t msgsz, int msgflg);
-long tile_compat_sys_msgrcv(int msqid,
-			    struct compat_msgbuf __user *msgp,
-			    size_t msgsz, long msgtyp, int msgflg);
-long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid,
-			    compat_long_t addr, compat_long_t data);
-
 /* Tilera Linux syscalls that don't have "compat" versions. */
 #define compat_sys_flush_cache sys_flush_cache
 
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h
index b2a6c5d..fc8429a 100644
--- a/arch/tile/include/asm/highmem.h
+++ b/arch/tile/include/asm/highmem.h
@@ -59,7 +59,7 @@ void *kmap_fix_kpte(struct page *page, int finished);
 /* This macro is used only in map_new_virtual() to map "page". */
 #define kmap_prot page_to_kpgprot(page)
 
-void *__kmap_atomic(struct page *page);
+void *kmap_atomic(struct page *page);
 void __kunmap_atomic(void *kvaddr);
 void *kmap_atomic_pfn(unsigned long pfn);
 void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
diff --git a/arch/tile/include/asm/smp.h b/arch/tile/include/asm/smp.h
index 532124a..1aa759a 100644
--- a/arch/tile/include/asm/smp.h
+++ b/arch/tile/include/asm/smp.h
@@ -43,10 +43,6 @@ void evaluate_message(int tag);
 /* Boot a secondary cpu */
 void online_secondary(void);
 
-/* Call a function on a specified set of CPUs (may include this one). */
-extern void on_each_cpu_mask(const struct cpumask *mask,
-			     void (*func)(void *), void *info, bool wait);
-
 /* Topology of the supervisor tile grid, and coordinates of boot processor */
 extern HV_Topology smp_topology;
 
@@ -91,9 +87,6 @@ void print_disabled_cpus(void);
 
 #else /* !CONFIG_SMP */
 
-#define on_each_cpu_mask(mask, func, info, wait)		\
-  do { if (cpumask_test_cpu(0, (mask))) func(info); } while (0)
-
 #define smp_master_cpu		0
 #define smp_height		1
 #define smp_width		1
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
index bf5e9d7..d67459b 100644
--- a/arch/tile/kernel/compat.c
+++ b/arch/tile/kernel/compat.c
@@ -16,7 +16,6 @@
 #define __SYSCALL_COMPAT
 
 #include <linux/compat.h>
-#include <linux/msg.h>
 #include <linux/syscalls.h>
 #include <linux/kdev_t.h>
 #include <linux/fs.h>
@@ -95,52 +94,10 @@ long compat_sys_sched_rr_get_interval(compat_pid_t pid,
 	return ret;
 }
 
-/*
- * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming
- * some different calling convention than our normal 32-bit tile code.
- */
-
-/* Already defined in ipc/compat.c, but we need it here. */
-struct compat_msgbuf {
-	compat_long_t mtype;
-	char mtext[1];
-};
-
-long tile_compat_sys_msgsnd(int msqid,
-			    struct compat_msgbuf __user *msgp,
-			    size_t msgsz, int msgflg)
-{
-	compat_long_t mtype;
-
-	if (get_user(mtype, &msgp->mtype))
-		return -EFAULT;
-	return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
-}
-
-long tile_compat_sys_msgrcv(int msqid,
-			    struct compat_msgbuf __user *msgp,
-			    size_t msgsz, long msgtyp, int msgflg)
-{
-	long err, mtype;
-
-	err =  do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
-	if (err < 0)
-		goto out;
-
-	if (put_user(mtype, &msgp->mtype))
-		err = -EFAULT;
- out:
-	return err;
-}
-
 /* Provide the compat syscall number to call mapping. */
 #undef __SYSCALL
 #define __SYSCALL(nr, call) [nr] = (call),
 
-/* The generic versions of these don't work for Tile. */
-#define compat_sys_msgrcv tile_compat_sys_msgrcv
-#define compat_sys_msgsnd tile_compat_sys_msgsnd
-
 /* See comments in sys.c */
 #define compat_sys_fadvise64_64 sys32_fadvise64_64
 #define compat_sys_readahead sys32_readahead
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index a7869ad..77763cc 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -303,10 +303,7 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index bedaf4e..f79d4b8 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -97,10 +97,7 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 		goto badframe;
@@ -286,13 +283,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
 		 * the work_pending path in the return-to-user code, and
 		 * either way we can re-enable interrupts unconditionally.
 		 */
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked,
-			  &current->blocked, &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, sig);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
+		block_sigmask(ka, sig);
 	}
 
 	return ret;
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
index c52224d..a44e103 100644
--- a/arch/tile/kernel/smp.c
+++ b/arch/tile/kernel/smp.c
@@ -87,25 +87,6 @@ void send_IPI_allbutself(int tag)
 	send_IPI_many(&mask, tag);
 }
 
-
-/*
- * Provide smp_call_function_mask, but also run function locally
- * if specified in the mask.
- */
-void on_each_cpu_mask(const struct cpumask *mask, void (*func)(void *),
-		      void *info, bool wait)
-{
-	int cpu = get_cpu();
-	smp_call_function_many(mask, func, info, wait);
-	if (cpumask_test_cpu(cpu, mask)) {
-		local_irq_disable();
-		func(info);
-		local_irq_enable();
-	}
-	put_cpu();
-}
-
-
 /*
  * Functions related to starting/stopping cpus.
  */
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
index 31dbbd9..ef8e5a6 100644
--- a/arch/tile/mm/highmem.c
+++ b/arch/tile/mm/highmem.c
@@ -224,12 +224,12 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 }
 EXPORT_SYMBOL(kmap_atomic_prot);
 
-void *__kmap_atomic(struct page *page)
+void *kmap_atomic(struct page *page)
 {
 	/* PAGE_NONE is a magic value that tells us to check immutability. */
 	return kmap_atomic_prot(page, PAGE_NONE);
 }
-EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic);
 
 void __kunmap_atomic(void *kvaddr)
 {
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index a492e59..d299618 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -293,7 +293,7 @@ static void uml_net_user_timer_expire(unsigned long _conn)
 #endif
 }
 
-static void setup_etheraddr(char *str, unsigned char *addr, char *name)
+static int setup_etheraddr(char *str, unsigned char *addr, char *name)
 {
 	char *end;
 	int i;
@@ -334,12 +334,13 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name)
 		       addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4],
 		       addr[5]);
 	}
-	return;
+	return 0;
 
 random:
 	printk(KERN_INFO
 	       "Choosing a random ethernet address for device %s\n", name);
 	random_ether_addr(addr);
+	return 1;
 }
 
 static DEFINE_SPINLOCK(devices_lock);
@@ -391,6 +392,7 @@ static void eth_configure(int n, void *init, char *mac,
 	struct net_device *dev;
 	struct uml_net_private *lp;
 	int err, size;
+	int random_mac;
 
 	size = transport->private_size + sizeof(struct uml_net_private);
 
@@ -417,7 +419,7 @@ static void eth_configure(int n, void *init, char *mac,
 	 */
 	snprintf(dev->name, sizeof(dev->name), "eth%d", n);
 
-	setup_etheraddr(mac, device->mac, dev->name);
+	random_mac = setup_etheraddr(mac, device->mac, dev->name);
 
 	printk(KERN_INFO "Netdevice %d (%pM) : ", n, device->mac);
 
@@ -474,6 +476,9 @@ static void eth_configure(int n, void *init, char *mac,
 
 	/* don't use eth_mac_addr, it will not work here */
 	memcpy(dev->dev_addr, device->mac, ETH_ALEN);
+	if (random_mac)
+		dev->addr_assign_type |= NET_ADDR_RANDOM;
+
 	dev->mtu = transport->user->mtu;
 	dev->netdev_ops = &uml_netdev_ops;
 	dev->ethtool_ops = &uml_net_ethtool_ops;
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index e8b889d..fb12f4c 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -65,21 +65,10 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
 #endif
 		err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
 
-	if (err) {
-		spin_lock_irq(&current->sighand->siglock);
-		current->blocked = *oldset;
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
+	if (err)
 		force_sigsegv(signr, current);
-	} else {
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked,
-			  &ka->sa.sa_mask);
-		if (!(ka->sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, signr);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
-	}
+	else
+		block_sigmask(ka, signr);
 
 	return err;
 }
@@ -162,12 +151,11 @@ int do_signal(void)
  */
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
+	sigset_t blocked;
+
 	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sighand->siglock);
-	current->saved_sigmask = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	siginitset(&blocked, mask);
+	set_current_blocked(&blocked);
 
 	current->state = TASK_INTERRUPTIBLE;
 	schedule();
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 9fefd92..cd7df79 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -69,7 +69,7 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
 		return -1;
 
 	page = pte_page(*pte);
-	addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) +
+	addr = (unsigned long) kmap_atomic(page) +
 		(addr & ~PAGE_MASK);
 
 	current->thread.fault_catcher = &buf;
@@ -82,7 +82,7 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
 
 	current->thread.fault_catcher = NULL;
 
-	kunmap_atomic((void *)addr, KM_UML_USERCOPY);
+	kunmap_atomic((void *)addr);
 
 	return n;
 }
diff --git a/arch/unicore32/include/asm/dma-mapping.h b/arch/unicore32/include/asm/dma-mapping.h
index 9258e59..366460a 100644
--- a/arch/unicore32/include/asm/dma-mapping.h
+++ b/arch/unicore32/include/asm/dma-mapping.h
@@ -82,20 +82,26 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
 	return 0;
 }
 
-static inline void *dma_alloc_coherent(struct device *dev, size_t size,
-				       dma_addr_t *dma_handle, gfp_t flag)
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
+static inline void *dma_alloc_attrs(struct device *dev, size_t size,
+				    dma_addr_t *dma_handle, gfp_t flag,
+				    struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
-	return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+	return dma_ops->alloc(dev, size, dma_handle, flag, attrs);
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *cpu_addr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
-	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	dma_ops->free(dev, size, cpu_addr, dma_handle, attrs);
 }
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index 911b549..72d9531 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -370,10 +370,7 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
 	/*
 	 * Block the signal if we were successful.
 	 */
-	sigorsets(&blocked, &tsk->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&blocked, sig);
-	set_current_blocked(&blocked);
+	block_sigmask(ka, sig);
 
 	return 0;
 }
diff --git a/arch/unicore32/mm/dma-swiotlb.c b/arch/unicore32/mm/dma-swiotlb.c
index bfa9fbb..ff70c2d 100644
--- a/arch/unicore32/mm/dma-swiotlb.c
+++ b/arch/unicore32/mm/dma-swiotlb.c
@@ -18,8 +18,8 @@
 #include <asm/dma.h>
 
 struct dma_map_ops swiotlb_dma_map_ops = {
-	.alloc_coherent = swiotlb_alloc_coherent,
-	.free_coherent = swiotlb_free_coherent,
+	.alloc = swiotlb_alloc_coherent,
+	.free = swiotlb_free_coherent,
 	.map_sg = swiotlb_map_sg_attrs,
 	.unmap_sg = swiotlb_unmap_sg_attrs,
 	.dma_supported = swiotlb_dma_supported,
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5bed94e..a61db6d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -69,7 +69,6 @@ config X86
 	select HAVE_ARCH_JUMP_LABEL
 	select HAVE_TEXT_POKE_SMP
 	select HAVE_GENERIC_HARDIRQS
-	select HAVE_SPARSE_IRQ
 	select SPARSE_IRQ
 	select GENERIC_FIND_FIRST_BIT
 	select GENERIC_IRQ_PROBE
@@ -84,7 +83,7 @@ config X86
 	select GENERIC_IOMAP
 
 config INSTRUCTION_DECODER
-	def_bool (KPROBES || PERF_EVENTS)
+	def_bool (KPROBES || PERF_EVENTS || UPROBES)
 
 config OUTPUT_FORMAT
 	string
@@ -179,6 +178,9 @@ config ARCH_HAS_DEFAULT_IDLE
 config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
 
+config ARCH_HAS_CPU_AUTOPROBE
+	def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
@@ -240,6 +242,9 @@ config ARCH_CPU_PROBE_RELEASE
 	def_bool y
 	depends on HOTPLUG_CPU
 
+config ARCH_SUPPORTS_UPROBES
+	def_bool y
+
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
@@ -417,27 +422,6 @@ if X86_WANT_INTEL_MID
 config X86_INTEL_MID
 	bool
 
-config X86_MRST
-       bool "Moorestown MID platform"
-	depends on PCI
-	depends on PCI_GOANY
-	depends on X86_IO_APIC
-	select X86_INTEL_MID
-	select SFI
-	select DW_APB_TIMER
-	select APB_TIMER
-	select I2C
-	select SPI
-	select INTEL_SCU_IPC
-	select X86_PLATFORM_DEVICES
-	---help---
-	  Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
-	  Internet Device(MID) platform. Moorestown consists of two chips:
-	  Lincroft (CPU core, graphics, and memory controller) and Langwell IOH.
-	  Unlike standard x86 PCs, Moorestown does not have many legacy devices
-	  nor standard legacy replacement devices/features. e.g. Moorestown does
-	  not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
-
 config X86_MDFLD
        bool "Medfield MID platform"
 	depends on PCI
@@ -451,6 +435,7 @@ config X86_MDFLD
 	select SPI
 	select INTEL_SCU_IPC
 	select X86_PLATFORM_DEVICES
+	select MFD_INTEL_MSIC
 	---help---
 	  Medfield is Intel's Low Power Intel Architecture (LPIA) based Moblin
 	  Internet Device(MID) platform. 
@@ -558,6 +543,37 @@ config SCHED_OMIT_FRAME_POINTER
 
 	  If in doubt, say "Y".
 
+config KVMTOOL_TEST_ENABLE
+	bool "Enable options to create a bootable tools/kvm/ kernel"
+	select NET
+	select NETDEVICES
+	select PCI
+	select BLOCK
+	select BLK_DEV
+	select NETWORK_FILESYSTEMS
+	select INET
+	select EXPERIMENTAL
+	select SERIAL_8250
+	select SERIAL_8250_CONSOLE
+	select IP_PNP
+	select IP_PNP_DHCP
+	select BINFMT_ELF
+	select PCI_MSI
+	select HAVE_ARCH_KGDB
+	select DEBUG_KERNEL
+	select KGDB
+	select KGDB_SERIAL_CONSOLE
+	select VIRTUALIZATION
+	select VIRTIO
+	select VIRTIO_RING
+	select VIRTIO_PCI
+	select VIRTIO_BLK
+	select VIRTIO_CONSOLE
+	select VIRTIO_NET
+	select 9P_FS
+	select NET_9P
+	select NET_9P_VIRTIO
+
 menuconfig PARAVIRT_GUEST
 	bool "Paravirtualized guest support"
 	---help---
@@ -2133,6 +2149,19 @@ config ALIX
 
 	  Note: You have to set alix.force=1 for boards with Award BIOS.
 
+config GEOS
+	bool "Traverse Technologies GEOS System Support (LEDS, GPIO, etc)"
+	select GPIOLIB
+	depends on DMI
+	---help---
+	  This option enables system support for the Traverse Technologies GEOS.
+
+config NET5501
+	bool "Soekris Engineering net5501 System Support (LEDS, GPIO, etc)"
+	select GPIOLIB
+	---help---
+	  This option enables system support for the Soekris Engineering net5501.
+
 endif # X86_32
 
 config AMD_NB
@@ -2178,6 +2207,7 @@ config IA32_AOUT
 config COMPAT
 	def_bool y
 	depends on IA32_EMULATION
+	select ARCH_WANT_OLD_COMPAT_IPC
 
 config COMPAT_FOR_U64_ALIGNMENT
 	def_bool COMPAT
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
index c7093bd..18997e5 100644
--- a/arch/x86/boot/boot.h
+++ b/arch/x86/boot/boot.h
@@ -67,7 +67,7 @@ static inline void outl(u32 v, u16 port)
 {
 	asm volatile("outl %0,%1" : : "a" (v), "dN" (port));
 }
-static inline u32 inl(u32 port)
+static inline u32 inl(u16 port)
 {
 	u32 v;
 	asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 545d0ce..c799352 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -28,6 +28,7 @@
 #include <crypto/aes.h>
 #include <crypto/cryptd.h>
 #include <crypto/ctr.h>
+#include <asm/cpu_device_id.h>
 #include <asm/i387.h>
 #include <asm/aes.h>
 #include <crypto/scatterwalk.h>
@@ -1107,12 +1108,12 @@ static int __driver_rfc4106_encrypt(struct aead_request *req)
 		one_entry_in_sg = 1;
 		scatterwalk_start(&src_sg_walk, req->src);
 		scatterwalk_start(&assoc_sg_walk, req->assoc);
-		src = scatterwalk_map(&src_sg_walk, 0);
-		assoc = scatterwalk_map(&assoc_sg_walk, 0);
+		src = scatterwalk_map(&src_sg_walk);
+		assoc = scatterwalk_map(&assoc_sg_walk);
 		dst = src;
 		if (unlikely(req->src != req->dst)) {
 			scatterwalk_start(&dst_sg_walk, req->dst);
-			dst = scatterwalk_map(&dst_sg_walk, 0);
+			dst = scatterwalk_map(&dst_sg_walk);
 		}
 
 	} else {
@@ -1136,11 +1137,11 @@ static int __driver_rfc4106_encrypt(struct aead_request *req)
 	 * back to the packet. */
 	if (one_entry_in_sg) {
 		if (unlikely(req->src != req->dst)) {
-			scatterwalk_unmap(dst, 0);
+			scatterwalk_unmap(dst);
 			scatterwalk_done(&dst_sg_walk, 0, 0);
 		}
-		scatterwalk_unmap(src, 0);
-		scatterwalk_unmap(assoc, 0);
+		scatterwalk_unmap(src);
+		scatterwalk_unmap(assoc);
 		scatterwalk_done(&src_sg_walk, 0, 0);
 		scatterwalk_done(&assoc_sg_walk, 0, 0);
 	} else {
@@ -1189,12 +1190,12 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
 		one_entry_in_sg = 1;
 		scatterwalk_start(&src_sg_walk, req->src);
 		scatterwalk_start(&assoc_sg_walk, req->assoc);
-		src = scatterwalk_map(&src_sg_walk, 0);
-		assoc = scatterwalk_map(&assoc_sg_walk, 0);
+		src = scatterwalk_map(&src_sg_walk);
+		assoc = scatterwalk_map(&assoc_sg_walk);
 		dst = src;
 		if (unlikely(req->src != req->dst)) {
 			scatterwalk_start(&dst_sg_walk, req->dst);
-			dst = scatterwalk_map(&dst_sg_walk, 0);
+			dst = scatterwalk_map(&dst_sg_walk);
 		}
 
 	} else {
@@ -1219,11 +1220,11 @@ static int __driver_rfc4106_decrypt(struct aead_request *req)
 
 	if (one_entry_in_sg) {
 		if (unlikely(req->src != req->dst)) {
-			scatterwalk_unmap(dst, 0);
+			scatterwalk_unmap(dst);
 			scatterwalk_done(&dst_sg_walk, 0, 0);
 		}
-		scatterwalk_unmap(src, 0);
-		scatterwalk_unmap(assoc, 0);
+		scatterwalk_unmap(src);
+		scatterwalk_unmap(assoc);
 		scatterwalk_done(&src_sg_walk, 0, 0);
 		scatterwalk_done(&assoc_sg_walk, 0, 0);
 	} else {
@@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = {
 };
 #endif
 
+
+static const struct x86_cpu_id aesni_cpu_id[] = {
+	X86_FEATURE_MATCH(X86_FEATURE_AES),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id);
+
 static int __init aesni_init(void)
 {
 	int err;
 
-	if (!cpu_has_aes) {
-		printk(KERN_INFO "Intel AES-NI instructions are not detected.\n");
+	if (!x86_match_cpu(aesni_cpu_id))
 		return -ENODEV;
-	}
 
 	if ((err = crypto_fpu_init()))
 		goto fpu_err;
diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c
index b05aa16..2970110 100644
--- a/arch/x86/crypto/blowfish_glue.c
+++ b/arch/x86/crypto/blowfish_glue.c
@@ -25,6 +25,7 @@
  *
  */
 
+#include <asm/processor.h>
 #include <crypto/blowfish.h>
 #include <linux/crypto.h>
 #include <linux/init.h>
@@ -446,10 +447,39 @@ static struct crypto_alg blk_ctr_alg = {
 	},
 };
 
+static bool is_blacklisted_cpu(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return false;
+
+	if (boot_cpu_data.x86 == 0x0f) {
+		/*
+		 * On Pentium 4, blowfish-x86_64 is slower than generic C
+		 * implementation because use of 64bit rotates (which are really
+		 * slow on P4). Therefore blacklist P4s.
+		 */
+		return true;
+	}
+
+	return false;
+}
+
+static int force;
+module_param(force, int, 0);
+MODULE_PARM_DESC(force, "Force module load, ignore CPU blacklist");
+
 static int __init init(void)
 {
 	int err;
 
+	if (!force && is_blacklisted_cpu()) {
+		printk(KERN_INFO
+			"blowfish-x86_64: performance on this CPU "
+			"would be suboptimal: disabling "
+			"blowfish-x86_64.\n");
+		return -ENODEV;
+	}
+
 	err = crypto_register_alg(&bf_alg);
 	if (err)
 		goto bf_err;
diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c
index b9d0026..493f959 100644
--- a/arch/x86/crypto/crc32c-intel.c
+++ b/arch/x86/crypto/crc32c-intel.c
@@ -31,6 +31,7 @@
 #include <crypto/internal/hash.h>
 
 #include <asm/cpufeature.h>
+#include <asm/cpu_device_id.h>
 
 #define CHKSUM_BLOCK_SIZE	1
 #define CHKSUM_DIGEST_SIZE	4
@@ -173,13 +174,17 @@ static struct shash_alg alg = {
 	}
 };
 
+static const struct x86_cpu_id crc32c_cpu_id[] = {
+	X86_FEATURE_MATCH(X86_FEATURE_XMM4_2),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id);
 
 static int __init crc32c_intel_mod_init(void)
 {
-	if (cpu_has_xmm4_2)
-		return crypto_register_shash(&alg);
-	else
+	if (!x86_match_cpu(crc32c_cpu_id))
 		return -ENODEV;
+	return crypto_register_shash(&alg);
 }
 
 static void __exit crc32c_intel_mod_fini(void)
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c
index 976aa64..b4bf0a6 100644
--- a/arch/x86/crypto/ghash-clmulni-intel_glue.c
+++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c
@@ -20,6 +20,7 @@
 #include <crypto/gf128mul.h>
 #include <crypto/internal/hash.h>
 #include <asm/i387.h>
+#include <asm/cpu_device_id.h>
 
 #define GHASH_BLOCK_SIZE	16
 #define GHASH_DIGEST_SIZE	16
@@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = {
 	},
 };
 
+static const struct x86_cpu_id pcmul_cpu_id[] = {
+	X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id);
+
 static int __init ghash_pclmulqdqni_mod_init(void)
 {
 	int err;
 
-	if (!cpu_has_pclmulqdq) {
-		printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not"
-		       " detected.\n");
+	if (!x86_match_cpu(pcmul_cpu_id))
 		return -ENODEV;
-	}
 
 	err = crypto_register_shash(&ghash_alg);
 	if (err)
diff --git a/arch/x86/crypto/serpent-sse2-i586-asm_32.S b/arch/x86/crypto/serpent-sse2-i586-asm_32.S
index 4e37677..c00053d 100644
--- a/arch/x86/crypto/serpent-sse2-i586-asm_32.S
+++ b/arch/x86/crypto/serpent-sse2-i586-asm_32.S
@@ -463,23 +463,20 @@
 	pand x0,		x4; \
 	pxor x2,		x4;
 
-#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
-	movdqa x2,		t3; \
-	movdqa x0,		t1; \
-	unpcklps x3,		t3; \
+#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
 	movdqa x0,		t2; \
-	unpcklps x1,		t1; \
-	unpckhps x1,		t2; \
-	movdqa t3,		x1; \
-	unpckhps x3,		x2; \
-	movdqa t1,		x0; \
-	movhlps t1,		x1; \
-	movdqa t2,		t1; \
-	movlhps t3,		x0; \
-	movlhps x2,		t1; \
-	movhlps t2,		x2; \
-	movdqa x2,		x3; \
-	movdqa t1,		x2;
+	punpckldq x1,		x0; \
+	punpckhdq x1,		t2; \
+	movdqa x2,		t1; \
+	punpckhdq x3,		x2; \
+	punpckldq x3,		t1; \
+	movdqa x0,		x1; \
+	punpcklqdq t1,		x0; \
+	punpckhqdq t1,		x1; \
+	movdqa t2,		x3; \
+	punpcklqdq x2,		t2; \
+	punpckhqdq x2,		x3; \
+	movdqa t2,		x2;
 
 #define read_blocks(in, x0, x1, x2, x3, t0, t1, t2) \
 	movdqu (0*4*4)(in),	x0; \
diff --git a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
index 7f24a15..3ee1ff0 100644
--- a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
+++ b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
@@ -585,23 +585,20 @@
 	get_key(i, 1, RK1); \
 	SBOX ## _2(x0 ## 2, x1 ## 2, x2 ## 2, x3 ## 2, x4 ## 2); \
 
-#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
-	movdqa x2,		t3; \
-	movdqa x0,		t1; \
-	unpcklps x3,		t3; \
+#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
 	movdqa x0,		t2; \
-	unpcklps x1,		t1; \
-	unpckhps x1,		t2; \
-	movdqa t3,		x1; \
-	unpckhps x3,		x2; \
-	movdqa t1,		x0; \
-	movhlps t1,		x1; \
-	movdqa t2,		t1; \
-	movlhps t3,		x0; \
-	movlhps x2,		t1; \
-	movhlps t2,		x2; \
-	movdqa x2,		x3; \
-	movdqa t1,		x2;
+	punpckldq x1,		x0; \
+	punpckhdq x1,		t2; \
+	movdqa x2,		t1; \
+	punpckhdq x3,		x2; \
+	punpckldq x3,		t1; \
+	movdqa x0,		x1; \
+	punpcklqdq t1,		x0; \
+	punpckhqdq t1,		x1; \
+	movdqa t2,		x3; \
+	punpcklqdq x2,		t2; \
+	punpckhqdq x2,		x3; \
+	movdqa t2,		x2;
 
 #define read_blocks(in, x0, x1, x2, x3, t0, t1, t2) \
 	movdqu (0*4*4)(in),	x0; \
diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c
index 7955a9b..de81cf4 100644
--- a/arch/x86/crypto/serpent_sse2_glue.c
+++ b/arch/x86/crypto/serpent_sse2_glue.c
@@ -1025,7 +1025,6 @@ static int __init serpent_sse2_init(void)
 		goto ablk_xts_err;
 	return err;
 
-	crypto_unregister_alg(&ablk_xts_alg);
 ablk_xts_err:
 	crypto_unregister_alg(&blk_xts_alg);
 blk_xts_err:
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
index 7fee8c1..2c7f14e 100644
--- a/arch/x86/crypto/twofish_glue_3way.c
+++ b/arch/x86/crypto/twofish_glue_3way.c
@@ -25,6 +25,7 @@
  *
  */
 
+#include <asm/processor.h>
 #include <linux/crypto.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -637,10 +638,56 @@ static struct crypto_alg blk_xts_alg = {
 	},
 };
 
+static bool is_blacklisted_cpu(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return false;
+
+	if (boot_cpu_data.x86 == 0x06 &&
+		(boot_cpu_data.x86_model == 0x1c ||
+		 boot_cpu_data.x86_model == 0x26 ||
+		 boot_cpu_data.x86_model == 0x36)) {
+		/*
+		 * On Atom, twofish-3way is slower than original assembler
+		 * implementation. Twofish-3way trades off some performance in
+		 * storing blocks in 64bit registers to allow three blocks to
+		 * be processed parallel. Parallel operation then allows gaining
+		 * more performance than was trade off, on out-of-order CPUs.
+		 * However Atom does not benefit from this parallellism and
+		 * should be blacklisted.
+		 */
+		return true;
+	}
+
+	if (boot_cpu_data.x86 == 0x0f) {
+		/*
+		 * On Pentium 4, twofish-3way is slower than original assembler
+		 * implementation because excessive uses of 64bit rotate and
+		 * left-shifts (which are really slow on P4) needed to store and
+		 * handle 128bit block in two 64bit registers.
+		 */
+		return true;
+	}
+
+	return false;
+}
+
+static int force;
+module_param(force, int, 0);
+MODULE_PARM_DESC(force, "Force module load, ignore CPU blacklist");
+
 int __init init(void)
 {
 	int err;
 
+	if (!force && is_blacklisted_cpu()) {
+		printk(KERN_INFO
+			"twofish-x86_64-3way: performance on this CPU "
+			"would be suboptimal: disabling "
+			"twofish-x86_64-3way.\n");
+		return -ENODEV;
+	}
+
 	err = crypto_register_alg(&blk_ecb_alg);
 	if (err)
 		goto ecb_err;
@@ -659,7 +706,6 @@ int __init init(void)
 
 	return 0;
 
-	crypto_unregister_alg(&blk_xts_alg);
 blk_xts_err:
 	crypto_unregister_alg(&blk_lrw_alg);
 blk_lrw_err:
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 37ad100..49331be 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -145,6 +145,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
  */
 #define ASM_OUTPUT2(a...) a
 
+/*
+ * use this macro if you need clobbers but no inputs in
+ * alternative_{input,io,call}()
+ */
+#define ASM_NO_INPUT_CLOBBER(clbr...) "i" (0) : clbr
+
 struct paravirt_patch_site;
 #ifdef CONFIG_PARAVIRT
 void apply_paravirt(struct paravirt_patch_site *start,
diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
index fa13f0e..1981199 100644
--- a/arch/x86/include/asm/atomic64_32.h
+++ b/arch/x86/include/asm/atomic64_32.h
@@ -14,13 +14,52 @@ typedef struct {
 
 #define ATOMIC64_INIT(val)	{ (val) }
 
+#define __ATOMIC64_DECL(sym) void atomic64_##sym(atomic64_t *, ...)
+#ifndef ATOMIC64_EXPORT
+#define ATOMIC64_DECL_ONE __ATOMIC64_DECL
+#else
+#define ATOMIC64_DECL_ONE(sym) __ATOMIC64_DECL(sym); \
+	ATOMIC64_EXPORT(atomic64_##sym)
+#endif
+
 #ifdef CONFIG_X86_CMPXCHG64
-#define ATOMIC64_ALTERNATIVE_(f, g) "call atomic64_" #g "_cx8"
+#define __alternative_atomic64(f, g, out, in...) \
+	asm volatile("call %P[func]" \
+		     : out : [func] "i" (atomic64_##g##_cx8), ## in)
+
+#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8)
 #else
-#define ATOMIC64_ALTERNATIVE_(f, g) ALTERNATIVE("call atomic64_" #f "_386", "call atomic64_" #g "_cx8", X86_FEATURE_CX8)
+#define __alternative_atomic64(f, g, out, in...) \
+	alternative_call(atomic64_##f##_386, atomic64_##g##_cx8, \
+			 X86_FEATURE_CX8, ASM_OUTPUT2(out), ## in)
+
+#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8); \
+	ATOMIC64_DECL_ONE(sym##_386)
+
+ATOMIC64_DECL_ONE(add_386);
+ATOMIC64_DECL_ONE(sub_386);
+ATOMIC64_DECL_ONE(inc_386);
+ATOMIC64_DECL_ONE(dec_386);
 #endif
 
-#define ATOMIC64_ALTERNATIVE(f) ATOMIC64_ALTERNATIVE_(f, f)
+#define alternative_atomic64(f, out, in...) \
+	__alternative_atomic64(f, f, ASM_OUTPUT2(out), ## in)
+
+ATOMIC64_DECL(read);
+ATOMIC64_DECL(set);
+ATOMIC64_DECL(xchg);
+ATOMIC64_DECL(add_return);
+ATOMIC64_DECL(sub_return);
+ATOMIC64_DECL(inc_return);
+ATOMIC64_DECL(dec_return);
+ATOMIC64_DECL(dec_if_positive);
+ATOMIC64_DECL(inc_not_zero);
+ATOMIC64_DECL(add_unless);
+
+#undef ATOMIC64_DECL
+#undef ATOMIC64_DECL_ONE
+#undef __ATOMIC64_DECL
+#undef ATOMIC64_EXPORT
 
 /**
  * atomic64_cmpxchg - cmpxchg atomic64 variable
@@ -50,11 +89,9 @@ static inline long long atomic64_xchg(atomic64_t *v, long long n)
 	long long o;
 	unsigned high = (unsigned)(n >> 32);
 	unsigned low = (unsigned)n;
-	asm volatile(ATOMIC64_ALTERNATIVE(xchg)
-		     : "=A" (o), "+b" (low), "+c" (high)
-		     : "S" (v)
-		     : "memory"
-		     );
+	alternative_atomic64(xchg, "=&A" (o),
+			     "S" (v), "b" (low), "c" (high)
+			     : "memory");
 	return o;
 }
 
@@ -69,11 +106,9 @@ static inline void atomic64_set(atomic64_t *v, long long i)
 {
 	unsigned high = (unsigned)(i >> 32);
 	unsigned low = (unsigned)i;
-	asm volatile(ATOMIC64_ALTERNATIVE(set)
-		     : "+b" (low), "+c" (high)
-		     : "S" (v)
-		     : "eax", "edx", "memory"
-		     );
+	alternative_atomic64(set, /* no output */,
+			     "S" (v), "b" (low), "c" (high)
+			     : "eax", "edx", "memory");
 }
 
 /**
@@ -85,10 +120,7 @@ static inline void atomic64_set(atomic64_t *v, long long i)
 static inline long long atomic64_read(const atomic64_t *v)
 {
 	long long r;
-	asm volatile(ATOMIC64_ALTERNATIVE(read)
-		     : "=A" (r), "+c" (v)
-		     : : "memory"
-		     );
+	alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
 	return r;
  }
 
@@ -101,10 +133,9 @@ static inline long long atomic64_read(const atomic64_t *v)
  */
 static inline long long atomic64_add_return(long long i, atomic64_t *v)
 {
-	asm volatile(ATOMIC64_ALTERNATIVE(add_return)
-		     : "+A" (i), "+c" (v)
-		     : : "memory"
-		     );
+	alternative_atomic64(add_return,
+			     ASM_OUTPUT2("+A" (i), "+c" (v)),
+			     ASM_NO_INPUT_CLOBBER("memory"));
 	return i;
 }
 
@@ -113,32 +144,25 @@ static inline long long atomic64_add_return(long long i, atomic64_t *v)
  */
 static inline long long atomic64_sub_return(long long i, atomic64_t *v)
 {
-	asm volatile(ATOMIC64_ALTERNATIVE(sub_return)
-		     : "+A" (i), "+c" (v)
-		     : : "memory"
-		     );
+	alternative_atomic64(sub_return,
+			     ASM_OUTPUT2("+A" (i), "+c" (v)),
+			     ASM_NO_INPUT_CLOBBER("memory"));
 	return i;
 }
 
 static inline long long atomic64_inc_return(atomic64_t *v)
 {
 	long long a;
-	asm volatile(ATOMIC64_ALTERNATIVE(inc_return)
-		     : "=A" (a)
-		     : "S" (v)
-		     : "memory", "ecx"
-		     );
+	alternative_atomic64(inc_return, "=&A" (a),
+			     "S" (v) : "memory", "ecx");
 	return a;
 }
 
 static inline long long atomic64_dec_return(atomic64_t *v)
 {
 	long long a;
-	asm volatile(ATOMIC64_ALTERNATIVE(dec_return)
-		     : "=A" (a)
-		     : "S" (v)
-		     : "memory", "ecx"
-		     );
+	alternative_atomic64(dec_return, "=&A" (a),
+			     "S" (v) : "memory", "ecx");
 	return a;
 }
 
@@ -151,10 +175,9 @@ static inline long long atomic64_dec_return(atomic64_t *v)
  */
 static inline long long atomic64_add(long long i, atomic64_t *v)
 {
-	asm volatile(ATOMIC64_ALTERNATIVE_(add, add_return)
-		     : "+A" (i), "+c" (v)
-		     : : "memory"
-		     );
+	__alternative_atomic64(add, add_return,
+			       ASM_OUTPUT2("+A" (i), "+c" (v)),
+			       ASM_NO_INPUT_CLOBBER("memory"));
 	return i;
 }
 
@@ -167,10 +190,9 @@ static inline long long atomic64_add(long long i, atomic64_t *v)
  */
 static inline long long atomic64_sub(long long i, atomic64_t *v)
 {
-	asm volatile(ATOMIC64_ALTERNATIVE_(sub, sub_return)
-		     : "+A" (i), "+c" (v)
-		     : : "memory"
-		     );
+	__alternative_atomic64(sub, sub_return,
+			       ASM_OUTPUT2("+A" (i), "+c" (v)),
+			       ASM_NO_INPUT_CLOBBER("memory"));
 	return i;
 }
 
@@ -196,10 +218,8 @@ static inline int atomic64_sub_and_test(long long i, atomic64_t *v)
  */
 static inline void atomic64_inc(atomic64_t *v)
 {
-	asm volatile(ATOMIC64_ALTERNATIVE_(inc, inc_return)
-		     : : "S" (v)
-		     : "memory", "eax", "ecx", "edx"
-		     );
+	__alternative_atomic64(inc, inc_return, /* no output */,
+			       "S" (v) : "memory", "eax", "ecx", "edx");
 }
 
 /**
@@ -210,10 +230,8 @@ static inline void atomic64_inc(atomic64_t *v)
  */
 static inline void atomic64_dec(atomic64_t *v)
 {
-	asm volatile(ATOMIC64_ALTERNATIVE_(dec, dec_return)
-		     : : "S" (v)
-		     : "memory", "eax", "ecx", "edx"
-		     );
+	__alternative_atomic64(dec, dec_return, /* no output */,
+			       "S" (v) : "memory", "eax", "ecx", "edx");
 }
 
 /**
@@ -263,15 +281,15 @@ static inline int atomic64_add_negative(long long i, atomic64_t *v)
  * @u: ...unless v is equal to u.
  *
  * Atomically adds @a to @v, so long as it was not @u.
- * Returns the old value of @v.
+ * Returns non-zero if the add was done, zero otherwise.
  */
 static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 {
 	unsigned low = (unsigned)u;
 	unsigned high = (unsigned)(u >> 32);
-	asm volatile(ATOMIC64_ALTERNATIVE(add_unless) "\n\t"
-		     : "+A" (a), "+c" (v), "+S" (low), "+D" (high)
-		     : : "memory");
+	alternative_atomic64(add_unless,
+			     ASM_OUTPUT2("+A" (a), "+c" (low), "+D" (high)),
+			     "S" (v) : "memory");
 	return (int)a;
 }
 
@@ -279,26 +297,20 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 static inline int atomic64_inc_not_zero(atomic64_t *v)
 {
 	int r;
-	asm volatile(ATOMIC64_ALTERNATIVE(inc_not_zero)
-		     : "=a" (r)
-		     : "S" (v)
-		     : "ecx", "edx", "memory"
-		     );
+	alternative_atomic64(inc_not_zero, "=&a" (r),
+			     "S" (v) : "ecx", "edx", "memory");
 	return r;
 }
 
 static inline long long atomic64_dec_if_positive(atomic64_t *v)
 {
 	long long r;
-	asm volatile(ATOMIC64_ALTERNATIVE(dec_if_positive)
-		     : "=A" (r)
-		     : "S" (v)
-		     : "ecx", "memory"
-		     );
+	alternative_atomic64(dec_if_positive, "=&A" (r),
+			     "S" (v) : "ecx", "memory");
 	return r;
 }
 
-#undef ATOMIC64_ALTERNATIVE
-#undef ATOMIC64_ALTERNATIVE_
+#undef alternative_atomic64
+#undef __alternative_atomic64
 
 #endif /* _ASM_X86_ATOMIC64_32_H */
diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h
new file mode 100644
index 0000000..ff501e5
--- /dev/null
+++ b/arch/x86/include/asm/cpu_device_id.h
@@ -0,0 +1,13 @@
+#ifndef _CPU_DEVICE_ID
+#define _CPU_DEVICE_ID 1
+
+/*
+ * Declare drivers belonging to specific x86 CPUs
+ * Similar in spirit to pci_device_id and related PCI functions
+ */
+
+#include <linux/mod_devicetable.h>
+
+extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
+
+#endif
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 8d67d42..dcb839e 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -177,6 +177,7 @@
 #define X86_FEATURE_PLN		(7*32+ 5) /* Intel Power Limit Notification */
 #define X86_FEATURE_PTS		(7*32+ 6) /* Intel Package Thermal Status */
 #define X86_FEATURE_DTS		(7*32+ 7) /* Digital Thermal Sensor */
+#define X86_FEATURE_HW_PSTATE	(7*32+ 8) /* AMD HW-PState */
 
 /* Virtualization flags: Linux defined, word 8 */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h
index 4d447b7..9476c04 100644
--- a/arch/x86/include/asm/current.h
+++ b/arch/x86/include/asm/current.h
@@ -11,7 +11,7 @@ DECLARE_PER_CPU(struct task_struct *, current_task);
 
 static __always_inline struct task_struct *get_current(void)
 {
-	return percpu_read_stable(current_task);
+	return this_cpu_read_stable(current_task);
 }
 
 #define current get_current()
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index e95822d..8bf1c06 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -6,6 +6,7 @@
 #include <asm/mmu.h>
 
 #include <linux/smp.h>
+#include <linux/percpu.h>
 
 static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info)
 {
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index ed3065f..4b4331d 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -59,7 +59,8 @@ extern int dma_supported(struct device *hwdev, u64 mask);
 extern int dma_set_mask(struct device *dev, u64 mask);
 
 extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-					dma_addr_t *dma_addr, gfp_t flag);
+					dma_addr_t *dma_addr, gfp_t flag,
+					struct dma_attrs *attrs);
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
@@ -111,9 +112,11 @@ static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp)
        return gfp;
 }
 
+#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL)
+
 static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		gfp_t gfp)
+dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		gfp_t gfp, struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 	void *memory;
@@ -129,18 +132,21 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
 	if (!is_device_dma_capable(dev))
 		return NULL;
 
-	if (!ops->alloc_coherent)
+	if (!ops->alloc)
 		return NULL;
 
-	memory = ops->alloc_coherent(dev, size, dma_handle,
-				     dma_alloc_coherent_gfp_flags(dev, gfp));
+	memory = ops->alloc(dev, size, dma_handle,
+			    dma_alloc_coherent_gfp_flags(dev, gfp), attrs);
 	debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
 
 	return memory;
 }
 
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *vaddr, dma_addr_t bus)
+#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL)
+
+static inline void dma_free_attrs(struct device *dev, size_t size,
+				  void *vaddr, dma_addr_t bus,
+				  struct dma_attrs *attrs)
 {
 	struct dma_map_ops *ops = get_dma_ops(dev);
 
@@ -150,8 +156,8 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
 		return;
 
 	debug_dma_free_coherent(dev, size, vaddr, bus);
-	if (ops->free_coherent)
-		ops->free_coherent(dev, size, vaddr, bus);
+	if (ops->free)
+		ops->free(dev, size, vaddr, bus, attrs);
 }
 
 #endif
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 3778256..5db3c45 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -53,6 +53,12 @@
  */
 #define E820_RESERVED_KERN        128
 
+/*
+ * Address ranges that need to be mapped by the kernel direct mapping
+ * because they require a runtime mapping. See setup_arch().
+ */
+#define E820_RESERVED_EFI         129
+
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 struct e820entry {
@@ -115,6 +121,7 @@ static inline void early_memtest(unsigned long start, unsigned long end)
 }
 #endif
 
+extern unsigned long e820_end_pfn(unsigned long limit_pfn, unsigned type);
 extern unsigned long e820_end_of_ram_pfn(void);
 extern unsigned long e820_end_of_low_ram_pfn(void);
 extern u64 early_reserve_e820(u64 sizet, u64 align);
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 844f735..26d8c18 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -35,8 +35,6 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
 #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6)	\
 	efi_call_virt(f, a1, a2, a3, a4, a5, a6)
 
-#define efi_ioremap(addr, size, type)		ioremap_cache(addr, size)
-
 #else /* !CONFIG_X86_32 */
 
 #define EFI_LOADER_SIGNATURE	"EL64"
@@ -88,9 +86,6 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
 	efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \
 		  (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
 
-extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
-				 u32 type);
-
 #endif /* CONFIG_X86_32 */
 
 extern int add_efi_memmap;
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index da0b3ca..b6e5c83 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -36,14 +36,15 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
 #define __ARCH_IRQ_STAT
 
-#define inc_irq_stat(member)	percpu_inc(irq_stat.member)
+#define inc_irq_stat(member)	__this_cpu_inc(irq_stat.member)
 
-#define local_softirq_pending()	percpu_read(irq_stat.__softirq_pending)
+#define local_softirq_pending()	__this_cpu_read(irq_stat.__softirq_pending)
 
 #define __ARCH_SET_SOFTIRQ_PENDING
 
-#define set_softirq_pending(x)	percpu_write(irq_stat.__softirq_pending, (x))
-#define or_softirq_pending(x)	percpu_or(irq_stat.__softirq_pending, (x))
+#define set_softirq_pending(x)	\
+		__this_cpu_write(irq_stat.__softirq_pending, (x))
+#define or_softirq_pending(x)	__this_cpu_or(irq_stat.__softirq_pending, (x))
 
 extern void ack_bad_irq(unsigned int irq);
 
diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h
index 3bd0402..302a323 100644
--- a/arch/x86/include/asm/highmem.h
+++ b/arch/x86/include/asm/highmem.h
@@ -61,7 +61,7 @@ void *kmap(struct page *page);
 void kunmap(struct page *page);
 
 void *kmap_atomic_prot(struct page *page, pgprot_t prot);
-void *__kmap_atomic(struct page *page);
+void *kmap_atomic(struct page *page);
 void __kunmap_atomic(void *kvaddr);
 void *kmap_atomic_pfn(unsigned long pfn);
 void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot);
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index a850b4d..df1cadd 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -29,10 +29,11 @@ extern unsigned int sig_xstate_size;
 extern void fpu_init(void);
 extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
-extern void __math_state_restore(struct task_struct *);
 extern void math_state_restore(void);
 extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
+DECLARE_PER_CPU(struct task_struct *, fpu_owner_task);
+
 extern user_regset_active_fn fpregs_active, xfpregs_active;
 extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
 				xstateregs_get;
@@ -269,6 +270,16 @@ static inline int fpu_restore_checking(struct fpu *fpu)
 
 static inline int restore_fpu_checking(struct task_struct *tsk)
 {
+	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+	   is pending.  Clear the x87 state here by setting it to fixed
+	   values. "m" is a random variable that should be in L1 */
+	alternative_input(
+		ASM_NOP8 ASM_NOP2,
+		"emms\n\t"	  	/* clear stack tags */
+		"fildl %P[addr]",	/* set F?P to defined value */
+		X86_FEATURE_FXSAVE_LEAK,
+		[addr] "m" (tsk->thread.fpu.has_fpu));
+
 	return fpu_restore_checking(&tsk->thread.fpu);
 }
 
@@ -279,19 +290,21 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
  */
 static inline int __thread_has_fpu(struct task_struct *tsk)
 {
-	return tsk->thread.has_fpu;
+	return tsk->thread.fpu.has_fpu;
 }
 
 /* Must be paired with an 'stts' after! */
 static inline void __thread_clear_has_fpu(struct task_struct *tsk)
 {
-	tsk->thread.has_fpu = 0;
+	tsk->thread.fpu.has_fpu = 0;
+	__this_cpu_write(fpu_owner_task, NULL);
 }
 
 /* Must be paired with a 'clts' before! */
 static inline void __thread_set_has_fpu(struct task_struct *tsk)
 {
-	tsk->thread.has_fpu = 1;
+	tsk->thread.fpu.has_fpu = 1;
+	__this_cpu_write(fpu_owner_task, tsk);
 }
 
 /*
@@ -336,30 +349,36 @@ typedef struct { int preload; } fpu_switch_t;
  * We don't do that yet, so "fpu_lazy_restore()" always returns
  * false, but some day..
  */
-#define fpu_lazy_restore(tsk) (0)
-#define fpu_lazy_state_intact(tsk) do { } while (0)
+static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu)
+{
+	return new == this_cpu_read_stable(fpu_owner_task) &&
+		cpu == new->thread.fpu.last_cpu;
+}
 
-static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new)
+static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new, int cpu)
 {
 	fpu_switch_t fpu;
 
 	fpu.preload = tsk_used_math(new) && new->fpu_counter > 5;
 	if (__thread_has_fpu(old)) {
-		if (__save_init_fpu(old))
-			fpu_lazy_state_intact(old);
-		__thread_clear_has_fpu(old);
-		old->fpu_counter++;
+		if (!__save_init_fpu(old))
+			cpu = ~0;
+		old->thread.fpu.last_cpu = cpu;
+		old->thread.fpu.has_fpu = 0;	/* But leave fpu_owner_task! */
 
 		/* Don't change CR0.TS if we just switch! */
 		if (fpu.preload) {
+			new->fpu_counter++;
 			__thread_set_has_fpu(new);
 			prefetch(new->thread.fpu.state);
 		} else
 			stts();
 	} else {
 		old->fpu_counter = 0;
+		old->thread.fpu.last_cpu = ~0;
 		if (fpu.preload) {
-			if (fpu_lazy_restore(new))
+			new->fpu_counter++;
+			if (fpu_lazy_restore(new, cpu))
 				fpu.preload = 0;
 			else
 				prefetch(new->thread.fpu.state);
@@ -377,8 +396,10 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta
  */
 static inline void switch_fpu_finish(struct task_struct *new, fpu_switch_t fpu)
 {
-	if (fpu.preload)
-		__math_state_restore(new);
+	if (fpu.preload) {
+		if (unlikely(restore_fpu_checking(new)))
+			__thread_fpu_end(new);
+	}
 }
 
 /*
@@ -451,8 +472,10 @@ static inline void kernel_fpu_begin(void)
 		__save_init_fpu(me);
 		__thread_clear_has_fpu(me);
 		/* We do 'stts()' in kernel_fpu_end() */
-	} else
+	} else {
+		__this_cpu_write(fpu_owner_task, NULL);
 		clts();
+	}
 }
 
 static inline void kernel_fpu_end(void)
diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
index 205b063..74a2e31 100644
--- a/arch/x86/include/asm/inat.h
+++ b/arch/x86/include/asm/inat.h
@@ -97,11 +97,12 @@
 
 /* Attribute search APIs */
 extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
+extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
 extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
-					     insn_byte_t last_pfx,
+					     int lpfx_id,
 					     insn_attr_t esc_attr);
 extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
-					    insn_byte_t last_pfx,
+					    int lpfx_id,
 					    insn_attr_t esc_attr);
 extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
 					  insn_byte_t vex_m,
diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h
index 74df3f1..48eb30a 100644
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -96,12 +96,6 @@ struct insn {
 #define X86_VEX_P(vex)	((vex) & 0x03)		/* VEX3 Byte2, VEX2 Byte1 */
 #define X86_VEX_M_MAX	0x1f			/* VEX3.M Maximum value */
 
-/* The last prefix is needed for two-byte and three-byte opcodes */
-static inline insn_byte_t insn_last_prefix(struct insn *insn)
-{
-	return insn->prefixes.bytes[3];
-}
-
 extern void insn_init(struct insn *insn, const void *kaddr, int x86_64);
 extern void insn_get_prefixes(struct insn *insn);
 extern void insn_get_opcode(struct insn *insn);
@@ -160,6 +154,18 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
 		return X86_VEX_P(insn->vex_prefix.bytes[2]);
 }
 
+/* Get the last prefix id from last prefix or VEX prefix */
+static inline int insn_last_prefix_id(struct insn *insn)
+{
+	if (insn_is_avx(insn))
+		return insn_vex_p_bits(insn);	/* VEX_p is a SIMD prefix id */
+
+	if (insn->prefixes.bytes[3])
+		return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
+
+	return 0;
+}
+
 /* Offset of each field from kaddr */
 static inline int insn_offset_rex_prefix(struct insn *insn)
 {
diff --git a/arch/x86/include/asm/irq_regs.h b/arch/x86/include/asm/irq_regs.h
index 7784322..15639ed 100644
--- a/arch/x86/include/asm/irq_regs.h
+++ b/arch/x86/include/asm/irq_regs.h
@@ -15,7 +15,7 @@ DECLARE_PER_CPU(struct pt_regs *, irq_regs);
 
 static inline struct pt_regs *get_irq_regs(void)
 {
-	return percpu_read(irq_regs);
+	return __this_cpu_read(irq_regs);
 }
 
 static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
@@ -23,7 +23,7 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
 	struct pt_regs *old_regs;
 
 	old_regs = get_irq_regs();
-	percpu_write(irq_regs, new_regs);
+	__this_cpu_write(irq_regs, new_regs);
 
 	return old_regs;
 }
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index 6902152..02ca533 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -25,8 +25,8 @@ void destroy_context(struct mm_struct *mm);
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
 #ifdef CONFIG_SMP
-	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
-		percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
+	if (__this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+		__this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
 #endif
 }
 
@@ -37,8 +37,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 
 	if (likely(prev != next)) {
 #ifdef CONFIG_SMP
-		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
-		percpu_write(cpu_tlbstate.active_mm, next);
+		__this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+		__this_cpu_write(cpu_tlbstate.active_mm, next);
 #endif
 		cpumask_set_cpu(cpu, mm_cpumask(next));
 
@@ -56,8 +56,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	}
 #ifdef CONFIG_SMP
 	else {
-		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
-		BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
+		__this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+		BUG_ON(__this_cpu_read(cpu_tlbstate.active_mm) != next);
 
 		if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next))) {
 			/* We were in lazy tlb mode and leave_mm disabled
diff --git a/arch/x86/include/asm/mrst.h b/arch/x86/include/asm/mrst.h
index 0a0a954..fc18bf3 100644
--- a/arch/x86/include/asm/mrst.h
+++ b/arch/x86/include/asm/mrst.h
@@ -26,8 +26,8 @@ extern struct sfi_rtc_table_entry sfi_mrtc_array[];
  * identified via MSRs.
  */
 enum mrst_cpu_type {
-	MRST_CPU_CHIP_LINCROFT = 1,
-	MRST_CPU_CHIP_PENWELL,
+	/* 1 was Moorestown */
+	MRST_CPU_CHIP_PENWELL = 2,
 };
 
 extern enum mrst_cpu_type __mrst_cpu_chip;
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index a6962d9..4e3cd38 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -127,6 +127,8 @@
 #define MSR_AMD64_IBSFETCHCTL		0xc0011030
 #define MSR_AMD64_IBSFETCHLINAD		0xc0011031
 #define MSR_AMD64_IBSFETCHPHYSAD	0xc0011032
+#define MSR_AMD64_IBSFETCH_REG_COUNT	3
+#define MSR_AMD64_IBSFETCH_REG_MASK	((1UL<<MSR_AMD64_IBSFETCH_REG_COUNT)-1)
 #define MSR_AMD64_IBSOPCTL		0xc0011033
 #define MSR_AMD64_IBSOPRIP		0xc0011034
 #define MSR_AMD64_IBSOPDATA		0xc0011035
@@ -134,8 +136,11 @@
 #define MSR_AMD64_IBSOPDATA3		0xc0011037
 #define MSR_AMD64_IBSDCLINAD		0xc0011038
 #define MSR_AMD64_IBSDCPHYSAD		0xc0011039
+#define MSR_AMD64_IBSOP_REG_COUNT	7
+#define MSR_AMD64_IBSOP_REG_MASK	((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1)
 #define MSR_AMD64_IBSCTL		0xc001103a
 #define MSR_AMD64_IBSBRTARGET		0xc001103b
+#define MSR_AMD64_IBS_REG_COUNT_MAX	8 /* includes MSR_AMD64_IBSBRTARGET */
 
 /* Fam 15h MSRs */
 #define MSR_F15H_PERF_CTL		0xc0010200
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 7a11910..ed3e18a 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -46,7 +46,7 @@
 
 #ifdef CONFIG_SMP
 #define __percpu_prefix		"%%"__stringify(__percpu_seg)":"
-#define __my_cpu_offset		percpu_read(this_cpu_off)
+#define __my_cpu_offset		__this_cpu_read(this_cpu_off)
 
 /*
  * Compared to the generic __my_cpu_offset version, the following
@@ -351,23 +351,15 @@ do {									\
 })
 
 /*
- * percpu_read() makes gcc load the percpu variable every time it is
- * accessed while percpu_read_stable() allows the value to be cached.
- * percpu_read_stable() is more efficient and can be used if its value
+ * this_cpu_read() makes gcc load the percpu variable every time it is
+ * accessed while this_cpu_read_stable() allows the value to be cached.
+ * this_cpu_read_stable() is more efficient and can be used if its value
  * is guaranteed to be valid across cpus.  The current users include
  * get_current() and get_thread_info() both of which are actually
  * per-thread variables implemented as per-cpu variables and thus
  * stable for the duration of the respective task.
  */
-#define percpu_read(var)		percpu_from_op("mov", var, "m" (var))
-#define percpu_read_stable(var)		percpu_from_op("mov", var, "p" (&(var)))
-#define percpu_write(var, val)		percpu_to_op("mov", var, val)
-#define percpu_add(var, val)		percpu_add_op(var, val)
-#define percpu_sub(var, val)		percpu_add_op(var, -(val))
-#define percpu_and(var, val)		percpu_to_op("and", var, val)
-#define percpu_or(var, val)		percpu_to_op("or", var, val)
-#define percpu_xor(var, val)		percpu_to_op("xor", var, val)
-#define percpu_inc(var)		percpu_unary_op("inc", var)
+#define this_cpu_read_stable(var)	percpu_from_op("mov", var, "p" (&(var)))
 
 #define __this_cpu_read_1(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
 #define __this_cpu_read_2(pcp)		percpu_from_op("mov", (pcp), "m"(pcp))
@@ -512,7 +504,11 @@ static __always_inline int x86_this_cpu_constant_test_bit(unsigned int nr,
 {
 	unsigned long __percpu *a = (unsigned long *)addr + nr / BITS_PER_LONG;
 
-	return ((1UL << (nr % BITS_PER_LONG)) & percpu_read(*a)) != 0;
+#ifdef CONFIG_X86_64
+	return ((1UL << (nr % BITS_PER_LONG)) & __this_cpu_read_8(*a)) != 0;
+#else
+	return ((1UL << (nr % BITS_PER_LONG)) & __this_cpu_read_4(*a)) != 0;
+#endif
 }
 
 static inline int x86_this_cpu_variable_test_bit(int nr,
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 096c975..0997c52 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -177,6 +177,8 @@ struct x86_pmu_capability {
 #define IBS_FETCH_MAX_CNT	0x0000FFFFULL
 
 /* IbsOpCtl bits */
+/* lower 4 bits of the current count are ignored: */
+#define IBS_OP_CUR_CNT		(0xFFFF0ULL<<32)
 #define IBS_OP_CNT_CTL		(1ULL<<19)
 #define IBS_OP_VAL		(1ULL<<18)
 #define IBS_OP_ENABLE		(1ULL<<17)
@@ -188,8 +190,6 @@ extern u32 get_ibs_caps(void);
 #ifdef CONFIG_PERF_EVENTS
 extern void perf_events_lapic_init(void);
 
-#define PERF_EVENT_INDEX_OFFSET			0
-
 /*
  * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups.
  * This flag is otherwise unused and ABI specified to be 0, so nobody should
diff --git a/arch/x86/include/asm/posix_types_32.h b/arch/x86/include/asm/posix_types_32.h
index f7d9adf..99f262e 100644
--- a/arch/x86/include/asm/posix_types_32.h
+++ b/arch/x86/include/asm/posix_types_32.h
@@ -7,79 +7,22 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
 typedef unsigned short	__kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
 typedef unsigned short	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
+#define __kernel_nlink_t __kernel_nlink_t
+
 typedef unsigned short	__kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned short	__kernel_uid_t;
 typedef unsigned short	__kernel_gid_t;
-typedef unsigned int	__kernel_size_t;
-typedef int		__kernel_ssize_t;
-typedef int		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
+#define __kernel_uid_t __kernel_uid_t
 
-typedef unsigned short	__kernel_old_uid_t;
-typedef unsigned short	__kernel_old_gid_t;
 typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#if defined(__KERNEL__)
-
-#undef	__FD_SET
-#define __FD_SET(fd,fdsetp)					\
-	asm volatile("btsl %1,%0":				\
-		     "+m" (*(__kernel_fd_set *)(fdsetp))	\
-		     : "r" ((int)(fd)))
-
-#undef	__FD_CLR
-#define __FD_CLR(fd,fdsetp)					\
-	asm volatile("btrl %1,%0":				\
-		     "+m" (*(__kernel_fd_set *)(fdsetp))	\
-		     : "r" ((int) (fd)))
-
-#undef	__FD_ISSET
-#define __FD_ISSET(fd,fdsetp)					\
-	(__extension__						\
-	 ({							\
-	 unsigned char __result;				\
-	 asm volatile("btl %1,%2 ; setb %0"			\
-		      : "=q" (__result)				\
-		      : "r" ((int)(fd)),			\
-			"m" (*(__kernel_fd_set *)(fdsetp)));	\
-	 __result;						\
-}))
-
-#undef	__FD_ZERO
-#define __FD_ZERO(fdsetp)					\
-do {								\
-	int __d0, __d1;						\
-	asm volatile("cld ; rep ; stosl"			\
-		     : "=m" (*(__kernel_fd_set *)(fdsetp)),	\
-		       "=&c" (__d0), "=&D" (__d1)		\
-		     : "a" (0), "1" (__FDSET_LONGS),		\
-		       "2" ((__kernel_fd_set *)(fdsetp))	\
-		     : "memory");				\
-} while (0)
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif /* _ASM_X86_POSIX_TYPES_32_H */
diff --git a/arch/x86/include/asm/posix_types_64.h b/arch/x86/include/asm/posix_types_64.h
index eb8d2d9..cba0c1e 100644
--- a/arch/x86/include/asm/posix_types_64.h
+++ b/arch/x86/include/asm/posix_types_64.h
@@ -7,113 +7,13 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-typedef unsigned long	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
-typedef int		__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
-typedef unsigned long	__kernel_size_t;
-typedef long		__kernel_ssize_t;
-typedef long		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
 typedef unsigned short __kernel_old_uid_t;
 typedef unsigned short __kernel_old_gid_t;
-typedef __kernel_uid_t __kernel_uid32_t;
-typedef __kernel_gid_t __kernel_gid32_t;
+#define __kernel_old_uid_t __kernel_old_uid_t
 
 typedef unsigned long	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-#ifdef __KERNEL__
-
-#undef __FD_SET
-static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant cases (8 or 32 longs,
- * for 256 and 1024-bit fd_sets respectively)
- */
-#undef __FD_ZERO
-static inline void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned long *tmp = p->fds_bits;
-	int i;
-
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-		case 32:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
-			tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
-			tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
-			tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
-			return;
-		case 16:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
-			tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
-			return;
-		case 8:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
-			return;
-		case 4:
-			tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
-			return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
-
-#endif /* defined(__KERNEL__) */
+#include <asm-generic/posix_types.h>
 
 #endif /* _ASM_X86_POSIX_TYPES_64_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index f7c89e2..58545c9 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -374,6 +374,8 @@ union thread_xstate {
 };
 
 struct fpu {
+	unsigned int last_cpu;
+	unsigned int has_fpu;
 	union thread_xstate *state;
 };
 
@@ -454,7 +456,6 @@ struct thread_struct {
 	unsigned long		trap_no;
 	unsigned long		error_code;
 	/* floating point and extended processor state */
-	unsigned long		has_fpu;
 	struct fpu		fpu;
 #ifdef CONFIG_X86_32
 	/* Virtual 86 mode info */
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 0434c40..e276f6b 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -188,11 +188,11 @@ extern unsigned disabled_cpus __cpuinitdata;
  * from the initial startup. We map APIC_BASE very early in page_setup(),
  * so this is correct in the x86 case.
  */
-#define raw_smp_processor_id() (percpu_read(cpu_number))
+#define raw_smp_processor_id() (this_cpu_read(cpu_number))
 extern int safe_smp_processor_id(void);
 
 #elif defined(CONFIG_X86_64_SMP)
-#define raw_smp_processor_id() (percpu_read(cpu_number))
+#define raw_smp_processor_id() (this_cpu_read(cpu_number))
 
 #define stack_smp_processor_id()					\
 ({								\
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index a82c2bf..76bfa2c 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -88,14 +88,14 @@ static inline int __ticket_spin_is_locked(arch_spinlock_t *lock)
 {
 	struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets);
 
-	return !!(tmp.tail ^ tmp.head);
+	return tmp.tail != tmp.head;
 }
 
 static inline int __ticket_spin_is_contended(arch_spinlock_t *lock)
 {
 	struct __raw_tickets tmp = ACCESS_ONCE(lock->tickets);
 
-	return ((tmp.tail - tmp.head) & TICKET_MASK) > 1;
+	return (__ticket_t)(tmp.tail - tmp.head) > 1;
 }
 
 #ifndef CONFIG_PARAVIRT_SPINLOCKS
diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h
index 8ebd5df..ad0ad07 100644
--- a/arch/x86/include/asm/spinlock_types.h
+++ b/arch/x86/include/asm/spinlock_types.h
@@ -16,7 +16,6 @@ typedef u32 __ticketpair_t;
 #endif
 
 #define TICKET_SHIFT	(sizeof(__ticket_t) * 8)
-#define TICKET_MASK	((__ticket_t)((1 << TICKET_SHIFT) - 1))
 
 typedef struct arch_spinlock {
 	union {
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index 1575177..e8a60c9 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -76,9 +76,9 @@ static __always_inline void boot_init_stack_canary(void)
 
 	current->stack_canary = canary;
 #ifdef CONFIG_X86_64
-	percpu_write(irq_stack_union.stack_canary, canary);
+	__this_cpu_write(irq_stack_union.stack_canary, canary);
 #else
-	percpu_write(stack_canary.canary, canary);
+	__this_cpu_write(stack_canary.canary, canary);
 #endif
 }
 
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index cfd8144..5cd37a1 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -85,6 +85,7 @@ struct thread_info {
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_MCE_NOTIFY		10	/* notify userspace of an MCE */
 #define TIF_USER_RETURN_NOTIFY	11	/* notify kernel of userspace return */
+#define TIF_UPROBE		12	/* breakpointed or singlestepping */
 #define TIF_NOTSC		16	/* TSC is not accessible in userland */
 #define TIF_IA32		17	/* 32bit process */
 #define TIF_FORK		18	/* ret_from_fork */
@@ -107,6 +108,7 @@ struct thread_info {
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_MCE_NOTIFY		(1 << TIF_MCE_NOTIFY)
 #define _TIF_USER_RETURN_NOTIFY	(1 << TIF_USER_RETURN_NOTIFY)
+#define _TIF_UPROBE		(1 << TIF_UPROBE)
 #define _TIF_NOTSC		(1 << TIF_NOTSC)
 #define _TIF_IA32		(1 << TIF_IA32)
 #define _TIF_FORK		(1 << TIF_FORK)
@@ -218,7 +220,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack);
 static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
-	ti = (void *)(percpu_read_stable(kernel_stack) +
+	ti = (void *)(this_cpu_read_stable(kernel_stack) +
 		      KERNEL_STACK_OFFSET - THREAD_SIZE);
 	return ti;
 }
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 169be89..e90eec0 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -156,8 +156,8 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
 
 static inline void reset_lazy_tlbstate(void)
 {
-	percpu_write(cpu_tlbstate.state, 0);
-	percpu_write(cpu_tlbstate.active_mm, &init_mm);
+	__this_cpu_write(cpu_tlbstate.state, 0);
+	__this_cpu_write(cpu_tlbstate.active_mm, &init_mm);
 }
 
 #endif	/* SMP */
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
new file mode 100644
index 0000000..88df7ec
--- /dev/null
+++ b/arch/x86/include/asm/uprobes.h
@@ -0,0 +1,58 @@
+#ifndef _ASM_UPROBES_H
+#define _ASM_UPROBES_H
+/*
+ * Userspace Probes (UProbes) for x86
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2008-2011
+ * Authors:
+ *	Srikar Dronamraju
+ *	Jim Keniston
+ */
+
+#include <linux/notifier.h>
+
+typedef u8 uprobe_opcode_t;
+#define MAX_UINSN_BYTES 16
+#define UPROBES_XOL_SLOT_BYTES	128	/* to keep it cache aligned */
+
+#define UPROBES_BKPT_INSN 0xcc
+#define UPROBES_BKPT_INSN_SIZE 1
+
+struct uprobe_arch_info {
+	u16			fixups;
+#ifdef CONFIG_X86_64
+	unsigned long rip_rela_target_address;
+#endif
+};
+
+struct uprobe_task_arch_info {
+	unsigned long saved_trap_no;
+#ifdef CONFIG_X86_64
+	unsigned long saved_scratch_register;
+#endif
+};
+
+struct uprobe;
+
+extern int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe);
+extern int pre_xol(struct uprobe *uprobe, struct pt_regs *regs);
+extern int post_xol(struct uprobe *uprobe, struct pt_regs *regs);
+extern bool xol_was_trapped(struct task_struct *tsk);
+extern int uprobe_exception_notify(struct notifier_block *self,
+				       unsigned long val, void *data);
+extern void abort_xol(struct pt_regs *regs, struct uprobe *uprobe);
+#endif	/* _ASM_UPROBES_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 5369059..8c8c365 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
 
 obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
 obj-$(CONFIG_OF)			+= devicetree.o
+obj-$(CONFIG_UPROBES)			+= uprobes.o
 
 ###
 # 64 bit specific files
diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c
index b1e7c7f..e663112 100644
--- a/arch/x86/kernel/amd_gart_64.c
+++ b/arch/x86/kernel/amd_gart_64.c
@@ -477,7 +477,7 @@ error:
 /* allocate and map a coherent mapping */
 static void *
 gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
-		    gfp_t flag)
+		    gfp_t flag, struct dma_attrs *attrs)
 {
 	dma_addr_t paddr;
 	unsigned long align_mask;
@@ -500,7 +500,8 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 		}
 		__free_pages(page, get_order(size));
 	} else
-		return dma_generic_alloc_coherent(dev, size, dma_addr, flag);
+		return dma_generic_alloc_coherent(dev, size, dma_addr, flag,
+						  attrs);
 
 	return NULL;
 }
@@ -508,7 +509,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
 /* free a coherent mapping */
 static void
 gart_free_coherent(struct device *dev, size_t size, void *vaddr,
-		   dma_addr_t dma_addr)
+		   dma_addr_t dma_addr, struct dma_attrs *attrs)
 {
 	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
 	free_pages((unsigned long)vaddr, get_order(size));
@@ -700,8 +701,8 @@ static struct dma_map_ops gart_dma_ops = {
 	.unmap_sg			= gart_unmap_sg,
 	.map_page			= gart_map_page,
 	.unmap_page			= gart_unmap_page,
-	.alloc_coherent			= gart_alloc_coherent,
-	.free_coherent			= gart_free_coherent,
+	.alloc				= gart_alloc_coherent,
+	.free				= gart_free_coherent,
 	.mapping_error			= gart_mapping_error,
 };
 
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index f76623c..5d56931 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -1234,8 +1234,7 @@ static int suspend(int vetoable)
 	struct apm_user	*as;
 
 	dpm_suspend_start(PMSG_SUSPEND);
-
-	dpm_suspend_noirq(PMSG_SUSPEND);
+	dpm_suspend_end(PMSG_SUSPEND);
 
 	local_irq_disable();
 	syscore_suspend();
@@ -1259,9 +1258,9 @@ static int suspend(int vetoable)
 	syscore_resume();
 	local_irq_enable();
 
-	dpm_resume_noirq(PMSG_RESUME);
-
+	dpm_resume_start(PMSG_RESUME);
 	dpm_resume_end(PMSG_RESUME);
+
 	queue_event(APM_NORMAL_RESUME, NULL);
 	spin_lock(&user_list_lock);
 	for (as = user_list; as != NULL; as = as->next) {
@@ -1277,7 +1276,7 @@ static void standby(void)
 {
 	int err;
 
-	dpm_suspend_noirq(PMSG_SUSPEND);
+	dpm_suspend_end(PMSG_SUSPEND);
 
 	local_irq_disable();
 	syscore_suspend();
@@ -1291,7 +1290,7 @@ static void standby(void)
 	syscore_resume();
 	local_irq_enable();
 
-	dpm_resume_noirq(PMSG_RESUME);
+	dpm_resume_start(PMSG_RESUME);
 }
 
 static apm_event_t get_event(void)
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 25f24dc..6ab6aa2 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -16,6 +16,7 @@ obj-y			:= intel_cacheinfo.o scattered.o topology.o
 obj-y			+= proc.o capflags.o powerflags.o common.o
 obj-y			+= vmware.o hypervisor.o sched.o mshyperv.o
 obj-y			+= rdrand.o
+obj-y			+= match.o
 
 obj-$(CONFIG_X86_32)	+= bugs.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index f4773f4..0a44b90 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -5,6 +5,7 @@
 #include <linux/mm.h>
 
 #include <linux/io.h>
+#include <linux/sched.h>
 #include <asm/processor.h>
 #include <asm/apic.h>
 #include <asm/cpu.h>
@@ -456,6 +457,8 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
 	if (c->x86_power & (1 << 8)) {
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
+		if (!check_tsc_unstable())
+			sched_clock_stable = 1;
 	}
 
 #ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d43cad7..72e43f6 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1044,6 +1044,9 @@ DEFINE_PER_CPU(char *, irq_stack_ptr) =
 
 DEFINE_PER_CPU(unsigned int, irq_count) = -1;
 
+DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
+EXPORT_PER_CPU_SYMBOL(fpu_owner_task);
+
 /*
  * Special IST stacks which the CPU switches to when it calls
  * an IST-marked descriptor entry. Up to 7 stacks (hardware
@@ -1111,6 +1114,8 @@ void debug_stack_reset(void)
 
 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
 EXPORT_PER_CPU_SYMBOL(current_task);
+DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
+EXPORT_PER_CPU_SYMBOL(fpu_owner_task);
 
 #ifdef CONFIG_CC_STACKPROTECTOR
 DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
@@ -1189,7 +1194,7 @@ void __cpuinit cpu_init(void)
 	oist = &per_cpu(orig_ist, cpu);
 
 #ifdef CONFIG_NUMA
-	if (cpu != 0 && percpu_read(numa_node) == 0 &&
+	if (cpu != 0 && __this_cpu_read(numa_node) == 0 &&
 	    early_cpu_to_node(cpu) != NUMA_NO_NODE)
 		set_numa_node(early_cpu_to_node(cpu));
 #endif
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 6b45e5e..73d08ed 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -326,8 +326,7 @@ static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb)
 	l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
 }
 
-static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf,
-					int index)
+static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
 {
 	int node;
 
@@ -725,14 +724,16 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
 #define CPUID4_INFO_IDX(x, y)	(&((per_cpu(ici_cpuid4_info, x))[y]))
 
 #ifdef CONFIG_SMP
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+
+static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
 {
-	struct _cpuid4_info	*this_leaf, *sibling_leaf;
-	unsigned long num_threads_sharing;
-	int index_msb, i, sibling;
+	struct _cpuid4_info *this_leaf;
+	int ret, i, sibling;
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
-	if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
+	ret = 0;
+	if (index == 3) {
+		ret = 1;
 		for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
 			if (!per_cpu(ici_cpuid4_info, i))
 				continue;
@@ -743,8 +744,35 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 				set_bit(sibling, this_leaf->shared_cpu_map);
 			}
 		}
-		return;
+	} else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) {
+		ret = 1;
+		for_each_cpu(i, cpu_sibling_mask(cpu)) {
+			if (!per_cpu(ici_cpuid4_info, i))
+				continue;
+			this_leaf = CPUID4_INFO_IDX(i, index);
+			for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
+				if (!cpu_online(sibling))
+					continue;
+				set_bit(sibling, this_leaf->shared_cpu_map);
+			}
+		}
 	}
+
+	return ret;
+}
+
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+{
+	struct _cpuid4_info *this_leaf, *sibling_leaf;
+	unsigned long num_threads_sharing;
+	int index_msb, i;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+	if (c->x86_vendor == X86_VENDOR_AMD) {
+		if (cache_shared_amd_cpu_map_setup(cpu, index))
+			return;
+	}
+
 	this_leaf = CPUID4_INFO_IDX(cpu, index);
 	num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing;
 
diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c
new file mode 100644
index 0000000..5502b28
--- /dev/null
+++ b/arch/x86/kernel/cpu/match.c
@@ -0,0 +1,91 @@
+#include <asm/cpu_device_id.h>
+#include <asm/processor.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/**
+ * x86_match_cpu - match current CPU again an array of x86_cpu_ids
+ * @match: Pointer to array of x86_cpu_ids. Last entry terminated with
+ *         {}.
+ *
+ * Return the entry if the current CPU matches the entries in the
+ * passed x86_cpu_id match table. Otherwise NULL.  The match table
+ * contains vendor (X86_VENDOR_*), family, model and feature bits or
+ * respective wildcard entries.
+ *
+ * A typical table entry would be to match a specific CPU
+ * { X86_VENDOR_INTEL, 6, 0x12 }
+ * or to match a specific CPU feature
+ * { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) }
+ *
+ * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY,
+ * %X86_MODEL_ANY, %X86_FEATURE_ANY or 0 (except for vendor)
+ *
+ * Arrays used to match for this should also be declared using
+ * MODULE_DEVICE_TABLE(x86_cpu, ...)
+ *
+ * This always matches against the boot cpu, assuming models and features are
+ * consistent over all CPUs.
+ */
+const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match)
+{
+	const struct x86_cpu_id *m;
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	for (m = match; m->vendor | m->family | m->model | m->feature; m++) {
+		if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
+			continue;
+		if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
+			continue;
+		if (m->model != X86_MODEL_ANY && c->x86_model != m->model)
+			continue;
+		if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature))
+			continue;
+		return m;
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(x86_match_cpu);
+
+ssize_t arch_print_cpu_modalias(struct device *dev,
+				struct device_attribute *attr,
+				char *bufptr)
+{
+	int size = PAGE_SIZE;
+	int i, n;
+	char *buf = bufptr;
+
+	n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:"
+		     "model:%04X:feature:",
+		boot_cpu_data.x86_vendor,
+		boot_cpu_data.x86,
+		boot_cpu_data.x86_model);
+	size -= n;
+	buf += n;
+	size -= 1;
+	for (i = 0; i < NCAPINTS*32; i++) {
+		if (boot_cpu_has(i)) {
+			n = snprintf(buf, size, ",%04X", i);
+			if (n >= size) {
+				WARN(1, "x86 features overflow page\n");
+				break;
+			}
+			size -= n;
+			buf += n;
+		}
+	}
+	*buf++ = '\n';
+	return buf - bufptr;
+}
+
+int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (buf) {
+		arch_print_cpu_modalias(NULL, NULL, buf);
+		add_uevent_var(env, "MODALIAS=%s", buf);
+		kfree(buf);
+	}
+	return 0;
+}
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 7395d5f..f6c92f9 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -54,6 +54,7 @@ static struct severity {
 #define  MASK(x, y)	.mask = x, .result = y
 #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S)
 #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR)
+#define	MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV)
 #define MCACOD 0xffff
 
 	MCESEV(
@@ -102,11 +103,24 @@ static struct severity {
 		SER, BITCLR(MCI_STATUS_S)
 		),
 
-	/* AR add known MCACODs here */
 	MCESEV(
 		PANIC, "Action required with lost events",
 		SER, BITSET(MCI_STATUS_OVER|MCI_UC_SAR)
 		),
+
+	/* known AR MCACODs: */
+#ifdef	CONFIG_MEMORY_FAILURE
+	MCESEV(
+		KEEP, "HT thread notices Action required: data load error",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|0x0134),
+		MCGMASK(MCG_STATUS_EIPV, 0)
+		),
+	MCESEV(
+		AR, "Action required: data load error",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|0x0134),
+		USER
+		),
+#endif
 	MCESEV(
 		PANIC, "Action required: unknown MCACOD",
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR, MCI_UC_SAR)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 5a11ae2..fee9b4d 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -540,6 +540,27 @@ static void mce_report_event(struct pt_regs *regs)
 	irq_work_queue(&__get_cpu_var(mce_irq_work));
 }
 
+/*
+ * Read ADDR and MISC registers.
+ */
+static void mce_read_aux(struct mce *m, int i)
+{
+	if (m->status & MCI_STATUS_MISCV)
+		m->misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
+	if (m->status & MCI_STATUS_ADDRV) {
+		m->addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+
+		/*
+		 * Mask the reported address by the reported granularity.
+		 */
+		if (mce_ser && (m->status & MCI_STATUS_MISCV)) {
+			u8 shift = MCI_MISC_ADDR_LSB(m->misc);
+			m->addr >>= shift;
+			m->addr <<= shift;
+		}
+	}
+}
+
 DEFINE_PER_CPU(unsigned, mce_poll_count);
 
 /*
@@ -562,7 +583,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 	struct mce m;
 	int i;
 
-	percpu_inc(mce_poll_count);
+	__this_cpu_inc(mce_poll_count);
 
 	mce_gather_info(&m, NULL);
 
@@ -590,10 +611,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		    (m.status & (mce_ser ? MCI_STATUS_S : MCI_STATUS_UC)))
 			continue;
 
-		if (m.status & MCI_STATUS_MISCV)
-			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
-		if (m.status & MCI_STATUS_ADDRV)
-			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+		mce_read_aux(&m, i);
 
 		if (!(flags & MCP_TIMESTAMP))
 			m.tsc = 0;
@@ -917,6 +935,49 @@ static void mce_clear_state(unsigned long *toclear)
 }
 
 /*
+ * Need to save faulting physical address associated with a process
+ * in the machine check handler some place where we can grab it back
+ * later in mce_notify_process()
+ */
+#define	MCE_INFO_MAX	16
+
+struct mce_info {
+	atomic_t		inuse;
+	struct task_struct	*t;
+	__u64			paddr;
+} mce_info[MCE_INFO_MAX];
+
+static void mce_save_info(__u64 addr)
+{
+	struct mce_info *mi;
+
+	for (mi = mce_info; mi < &mce_info[MCE_INFO_MAX]; mi++) {
+		if (atomic_cmpxchg(&mi->inuse, 0, 1) == 0) {
+			mi->t = current;
+			mi->paddr = addr;
+			return;
+		}
+	}
+
+	mce_panic("Too many concurrent recoverable errors", NULL, NULL);
+}
+
+static struct mce_info *mce_find_info(void)
+{
+	struct mce_info *mi;
+
+	for (mi = mce_info; mi < &mce_info[MCE_INFO_MAX]; mi++)
+		if (atomic_read(&mi->inuse) && mi->t == current)
+			return mi;
+	return NULL;
+}
+
+static void mce_clear_info(struct mce_info *mi)
+{
+	atomic_set(&mi->inuse, 0);
+}
+
+/*
  * The actual machine check handler. This only handles real
  * exceptions when something got corrupted coming in through int 18.
  *
@@ -954,7 +1015,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 
 	atomic_inc(&mce_entry);
 
-	percpu_inc(mce_exception_count);
+	__this_cpu_inc(mce_exception_count);
 
 	if (!banks)
 		goto out;
@@ -969,7 +1030,9 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 	barrier();
 
 	/*
-	 * When no restart IP must always kill or panic.
+	 * When no restart IP might need to kill or panic.
+	 * Assume the worst for now, but if we find the
+	 * severity is MCE_AR_SEVERITY we have other options.
 	 */
 	if (!(m.mcgstatus & MCG_STATUS_RIPV))
 		kill_it = 1;
@@ -1023,16 +1086,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			continue;
 		}
 
-		/*
-		 * Kill on action required.
-		 */
-		if (severity == MCE_AR_SEVERITY)
-			kill_it = 1;
-
-		if (m.status & MCI_STATUS_MISCV)
-			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
-		if (m.status & MCI_STATUS_ADDRV)
-			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+		mce_read_aux(&m, i);
 
 		/*
 		 * Action optional error. Queue address for later processing.
@@ -1052,6 +1106,9 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		}
 	}
 
+	/* mce_clear_state will clear *final, save locally for use later */
+	m = *final;
+
 	if (!no_way_out)
 		mce_clear_state(toclear);
 
@@ -1063,27 +1120,22 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		no_way_out = worst >= MCE_PANIC_SEVERITY;
 
 	/*
-	 * If we have decided that we just CAN'T continue, and the user
-	 * has not set tolerant to an insane level, give up and die.
-	 *
-	 * This is mainly used in the case when the system doesn't
-	 * support MCE broadcasting or it has been disabled.
-	 */
-	if (no_way_out && tolerant < 3)
-		mce_panic("Fatal machine check on current CPU", final, msg);
-
-	/*
-	 * If the error seems to be unrecoverable, something should be
-	 * done.  Try to kill as little as possible.  If we can kill just
-	 * one task, do that.  If the user has set the tolerance very
-	 * high, don't try to do anything at all.
+	 * At insane "tolerant" levels we take no action. Otherwise
+	 * we only die if we have no other choice. For less serious
+	 * issues we try to recover, or limit damage to the current
+	 * process.
 	 */
-
-	if (kill_it && tolerant < 3)
-		force_sig(SIGBUS, current);
-
-	/* notify userspace ASAP */
-	set_thread_flag(TIF_MCE_NOTIFY);
+	if (tolerant < 3) {
+		if (no_way_out)
+			mce_panic("Fatal machine check on current CPU", &m, msg);
+		if (worst == MCE_AR_SEVERITY) {
+			/* schedule action before return to userland */
+			mce_save_info(m.addr);
+			set_thread_flag(TIF_MCE_NOTIFY);
+		} else if (kill_it) {
+			force_sig(SIGBUS, current);
+		}
+	}
 
 	if (worst > 0)
 		mce_report_event(regs);
@@ -1094,34 +1146,57 @@ out:
 }
 EXPORT_SYMBOL_GPL(do_machine_check);
 
-/* dummy to break dependency. actual code is in mm/memory-failure.c */
-void __attribute__((weak)) memory_failure(unsigned long pfn, int vector)
+#ifndef CONFIG_MEMORY_FAILURE
+int memory_failure(unsigned long pfn, int vector, int flags)
 {
-	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);
+	/* mce_severity() should not hand us an ACTION_REQUIRED error */
+	BUG_ON(flags & MF_ACTION_REQUIRED);
+	printk(KERN_ERR "Uncorrected memory error in page 0x%lx ignored\n"
+		"Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", pfn);
+
+	return 0;
 }
+#endif
 
 /*
- * Called after mce notification in process context. This code
- * is allowed to sleep. Call the high level VM handler to process
- * any corrupted pages.
- * Assume that the work queue code only calls this one at a time
- * per CPU.
- * Note we don't disable preemption, so this code might run on the wrong
- * CPU. In this case the event is picked up by the scheduled work queue.
- * This is merely a fast path to expedite processing in some common
- * cases.
+ * Called in process context that interrupted by MCE and marked with
+ * TIF_MCE_NOTIFY, just before returning to erroneous userland.
+ * This code is allowed to sleep.
+ * Attempt possible recovery such as calling the high level VM handler to
+ * process any corrupted pages, and kill/signal current process if required.
+ * Action required errors are handled here.
  */
 void mce_notify_process(void)
 {
 	unsigned long pfn;
-	mce_notify_irq();
-	while (mce_ring_get(&pfn))
-		memory_failure(pfn, MCE_VECTOR);
+	struct mce_info *mi = mce_find_info();
+
+	if (!mi)
+		mce_panic("Lost physical address for unconsumed uncorrectable error", NULL, NULL);
+	pfn = mi->paddr >> PAGE_SHIFT;
+
+	clear_thread_flag(TIF_MCE_NOTIFY);
+
+	pr_err("Uncorrected hardware memory error in user-access at %llx",
+		 mi->paddr);
+	if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) {
+		pr_err("Memory error not recovered");
+		force_sig(SIGBUS, current);
+	}
+	mce_clear_info(mi);
 }
 
+/*
+ * Action optional processing happens here (picking up
+ * from the list of faulting pages that do_machine_check()
+ * placed into the "ring").
+ */
 static void mce_process_work(struct work_struct *dummy)
 {
-	mce_notify_process();
+	unsigned long pfn;
+
+	while (mce_ring_get(&pfn))
+		memory_failure(pfn, MCE_VECTOR, 0);
 }
 
 #ifdef CONFIG_X86_MCE_INTEL
@@ -1211,8 +1286,6 @@ int mce_notify_irq(void)
 	/* Not more than two messages every minute */
 	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
 
-	clear_thread_flag(TIF_MCE_NOTIFY);
-
 	if (test_and_clear_bit(0, &mce_need_notify)) {
 		/* wake processes polling /dev/mcelog */
 		wake_up_interruptible(&mce_chrdev_wait);
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 5adce10..00fa032 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/bitops.h>
+#include <linux/device.h>
 
 #include <asm/apic.h>
 #include <asm/stacktrace.h>
@@ -31,6 +32,7 @@
 #include <asm/compat.h>
 #include <asm/smp.h>
 #include <asm/alternative.h>
+#include <asm/timer.h>
 
 #include "perf_event.h"
 
@@ -577,14 +579,14 @@ static bool __perf_sched_find_counter(struct perf_sched *sched)
 	/* Prefer fixed purpose counters */
 	if (x86_pmu.num_counters_fixed) {
 		idx = X86_PMC_IDX_FIXED;
-		for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_MAX) {
+		for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) {
 			if (!__test_and_set_bit(idx, sched->state.used))
 				goto done;
 		}
 	}
 	/* Grab the first unused counter starting with idx */
 	idx = sched->state.counter;
-	for_each_set_bit_cont(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
+	for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_FIXED) {
 		if (!__test_and_set_bit(idx, sched->state.used))
 			goto done;
 	}
@@ -1210,6 +1212,8 @@ x86_pmu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
 		break;
 
 	case CPU_STARTING:
+		if (x86_pmu.attr_rdpmc)
+			set_in_cr4(X86_CR4_PCE);
 		if (x86_pmu.cpu_starting)
 			x86_pmu.cpu_starting(cpu);
 		break;
@@ -1319,6 +1323,8 @@ static int __init init_hw_perf_events(void)
 		}
 	}
 
+	x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */
+
 	pr_info("... version:                %d\n",     x86_pmu.version);
 	pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
 	pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
@@ -1542,10 +1548,71 @@ static int x86_pmu_event_init(struct perf_event *event)
 	return err;
 }
 
+static int x86_pmu_event_idx(struct perf_event *event)
+{
+	int idx = event->hw.idx;
+
+	if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) {
+		idx -= X86_PMC_IDX_FIXED;
+		idx |= 1 << 30;
+	}
+
+	return idx + 1;
+}
+
+static ssize_t get_attr_rdpmc(struct device *cdev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	return snprintf(buf, 40, "%d\n", x86_pmu.attr_rdpmc);
+}
+
+static void change_rdpmc(void *info)
+{
+	bool enable = !!(unsigned long)info;
+
+	if (enable)
+		set_in_cr4(X86_CR4_PCE);
+	else
+		clear_in_cr4(X86_CR4_PCE);
+}
+
+static ssize_t set_attr_rdpmc(struct device *cdev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	unsigned long val = simple_strtoul(buf, NULL, 0);
+
+	if (!!val != !!x86_pmu.attr_rdpmc) {
+		x86_pmu.attr_rdpmc = !!val;
+		smp_call_function(change_rdpmc, (void *)val, 1);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(rdpmc, S_IRUSR | S_IWUSR, get_attr_rdpmc, set_attr_rdpmc);
+
+static struct attribute *x86_pmu_attrs[] = {
+	&dev_attr_rdpmc.attr,
+	NULL,
+};
+
+static struct attribute_group x86_pmu_attr_group = {
+	.attrs = x86_pmu_attrs,
+};
+
+static const struct attribute_group *x86_pmu_attr_groups[] = {
+	&x86_pmu_attr_group,
+	NULL,
+};
+
 static struct pmu pmu = {
 	.pmu_enable	= x86_pmu_enable,
 	.pmu_disable	= x86_pmu_disable,
 
+	.attr_groups	= x86_pmu_attr_groups,
+
 	.event_init	= x86_pmu_event_init,
 
 	.add		= x86_pmu_add,
@@ -1557,8 +1624,23 @@ static struct pmu pmu = {
 	.start_txn	= x86_pmu_start_txn,
 	.cancel_txn	= x86_pmu_cancel_txn,
 	.commit_txn	= x86_pmu_commit_txn,
+
+	.event_idx	= x86_pmu_event_idx,
 };
 
+void perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now)
+{
+	if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
+		return;
+
+	if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
+		return;
+
+	userpg->time_mult = this_cpu_read(cyc2ns);
+	userpg->time_shift = CYC2NS_SCALE_FACTOR;
+	userpg->time_offset = this_cpu_read(cyc2ns_offset) - now;
+}
+
 /*
  * callchain support
  */
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 8944062..513d617 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -307,6 +307,14 @@ struct x86_pmu {
 	struct x86_pmu_quirk *quirks;
 	int		perfctr_second_write;
 
+	/*
+	 * sysfs attrs
+	 */
+	int		attr_rdpmc;
+
+	/*
+	 * CPU Hotplug hooks
+	 */
 	int		(*cpu_prepare)(int cpu);
 	void		(*cpu_starting)(int cpu);
 	void		(*cpu_dying)(int cpu);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index 3b8a2d3..573d248 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -16,36 +16,460 @@ static u32 ibs_caps;
 
 #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
 
-static struct pmu perf_ibs;
+#include <linux/kprobes.h>
+#include <linux/hardirq.h>
+
+#include <asm/nmi.h>
+
+#define IBS_FETCH_CONFIG_MASK	(IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
+#define IBS_OP_CONFIG_MASK	IBS_OP_MAX_CNT
+
+enum ibs_states {
+	IBS_ENABLED	= 0,
+	IBS_STARTED	= 1,
+	IBS_STOPPING	= 2,
+
+	IBS_MAX_STATES,
+};
+
+struct cpu_perf_ibs {
+	struct perf_event	*event;
+	unsigned long		state[BITS_TO_LONGS(IBS_MAX_STATES)];
+};
+
+struct perf_ibs {
+	struct pmu	pmu;
+	unsigned int	msr;
+	u64		config_mask;
+	u64		cnt_mask;
+	u64		enable_mask;
+	u64		valid_mask;
+	u64		max_period;
+	unsigned long	offset_mask[1];
+	int		offset_max;
+	struct cpu_perf_ibs __percpu *pcpu;
+	u64		(*get_count)(u64 config);
+};
+
+struct perf_ibs_data {
+	u32		size;
+	union {
+		u32	data[0];	/* data buffer starts here */
+		u32	caps;
+	};
+	u64		regs[MSR_AMD64_IBS_REG_COUNT_MAX];
+};
+
+static int
+perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *count)
+{
+	s64 left = local64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int overflow = 0;
+
+	/*
+	 * If we are way outside a reasonable range then just skip forward:
+	 */
+	if (unlikely(left <= -period)) {
+		left = period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		overflow = 1;
+	}
+
+	if (unlikely(left <= 0)) {
+		left += period;
+		local64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		overflow = 1;
+	}
+
+	if (unlikely(left < min))
+		left = min;
+
+	if (left > max)
+		left = max;
+
+	*count = (u64)left;
+
+	return overflow;
+}
+
+static  int
+perf_event_try_update(struct perf_event *event, u64 new_raw_count, int width)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int shift = 64 - width;
+	u64 prev_raw_count;
+	u64 delta;
+
+	/*
+	 * Careful: an NMI might modify the previous event value.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic event atomically:
+	 */
+	prev_raw_count = local64_read(&hwc->prev_count);
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+					new_raw_count) != prev_raw_count)
+		return 0;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (event-)time and add that to the generic event.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	local64_add(delta, &event->count);
+	local64_sub(delta, &hwc->period_left);
+
+	return 1;
+}
+
+static struct perf_ibs perf_ibs_fetch;
+static struct perf_ibs perf_ibs_op;
+
+static struct perf_ibs *get_ibs_pmu(int type)
+{
+	if (perf_ibs_fetch.pmu.type == type)
+		return &perf_ibs_fetch;
+	if (perf_ibs_op.pmu.type == type)
+		return &perf_ibs_op;
+	return NULL;
+}
 
 static int perf_ibs_init(struct perf_event *event)
 {
-	if (perf_ibs.type != event->attr.type)
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_ibs *perf_ibs;
+	u64 max_cnt, config;
+
+	perf_ibs = get_ibs_pmu(event->attr.type);
+	if (!perf_ibs)
 		return -ENOENT;
+
+	config = event->attr.config;
+	if (config & ~perf_ibs->config_mask)
+		return -EINVAL;
+
+	if (hwc->sample_period) {
+		if (config & perf_ibs->cnt_mask)
+			/* raw max_cnt may not be set */
+			return -EINVAL;
+		if (hwc->sample_period & 0x0f)
+			/* lower 4 bits can not be set in ibs max cnt */
+			return -EINVAL;
+	} else {
+		max_cnt = config & perf_ibs->cnt_mask;
+		config &= ~perf_ibs->cnt_mask;
+		event->attr.sample_period = max_cnt << 4;
+		hwc->sample_period = event->attr.sample_period;
+	}
+
+	if (!hwc->sample_period)
+		return -EINVAL;
+
+	hwc->config_base = perf_ibs->msr;
+	hwc->config = config;
+
 	return 0;
 }
 
+static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
+			       struct hw_perf_event *hwc, u64 *period)
+{
+	int ret;
+
+	/* ignore lower 4 bits in min count: */
+	ret = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
+	local64_set(&hwc->prev_count, 0);
+
+	return ret;
+}
+
+static u64 get_ibs_fetch_count(u64 config)
+{
+	return (config & IBS_FETCH_CNT) >> 12;
+}
+
+static u64 get_ibs_op_count(u64 config)
+{
+	return (config & IBS_OP_CUR_CNT) >> 32;
+}
+
+static void
+perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
+		      u64 config)
+{
+	u64 count = perf_ibs->get_count(config);
+
+	while (!perf_event_try_update(event, count, 20)) {
+		rdmsrl(event->hw.config_base, config);
+		count = perf_ibs->get_count(config);
+	}
+}
+
+/* Note: The enable mask must be encoded in the config argument. */
+static inline void perf_ibs_enable_event(struct hw_perf_event *hwc, u64 config)
+{
+	wrmsrl(hwc->config_base, hwc->config | config);
+}
+
+/*
+ * We cannot restore the ibs pmu state, so we always needs to update
+ * the event while stopping it and then reset the state when starting
+ * again. Thus, ignoring PERF_EF_RELOAD and PERF_EF_UPDATE flags in
+ * perf_ibs_start()/perf_ibs_stop() and instead always do it.
+ */
+static void perf_ibs_start(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+	u64 config;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+	hwc->state = 0;
+
+	perf_ibs_set_period(perf_ibs, hwc, &config);
+	config = (config >> 4) | perf_ibs->enable_mask;
+	set_bit(IBS_STARTED, pcpu->state);
+	perf_ibs_enable_event(hwc, config);
+
+	perf_event_update_userpage(event);
+}
+
+static void perf_ibs_stop(struct perf_event *event, int flags)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+	u64 val;
+	int stopping;
+
+	stopping = test_and_clear_bit(IBS_STARTED, pcpu->state);
+
+	if (!stopping && (hwc->state & PERF_HES_UPTODATE))
+		return;
+
+	rdmsrl(hwc->config_base, val);
+
+	if (stopping) {
+		set_bit(IBS_STOPPING, pcpu->state);
+		val &= ~perf_ibs->enable_mask;
+		wrmsrl(hwc->config_base, val);
+		WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+		hwc->state |= PERF_HES_STOPPED;
+	}
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	perf_ibs_event_update(perf_ibs, event, val);
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
 static int perf_ibs_add(struct perf_event *event, int flags)
 {
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+
+	if (test_and_set_bit(IBS_ENABLED, pcpu->state))
+		return -ENOSPC;
+
+	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+
+	pcpu->event = event;
+
+	if (flags & PERF_EF_START)
+		perf_ibs_start(event, PERF_EF_RELOAD);
+
 	return 0;
 }
 
 static void perf_ibs_del(struct perf_event *event, int flags)
 {
+	struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+
+	if (!test_and_clear_bit(IBS_ENABLED, pcpu->state))
+		return;
+
+	perf_ibs_stop(event, PERF_EF_UPDATE);
+
+	pcpu->event = NULL;
+
+	perf_event_update_userpage(event);
 }
 
-static struct pmu perf_ibs = {
-	.event_init= perf_ibs_init,
-	.add= perf_ibs_add,
-	.del= perf_ibs_del,
+static void perf_ibs_read(struct perf_event *event) { }
+
+static struct perf_ibs perf_ibs_fetch = {
+	.pmu = {
+		.task_ctx_nr	= perf_invalid_context,
+
+		.event_init	= perf_ibs_init,
+		.add		= perf_ibs_add,
+		.del		= perf_ibs_del,
+		.start		= perf_ibs_start,
+		.stop		= perf_ibs_stop,
+		.read		= perf_ibs_read,
+	},
+	.msr			= MSR_AMD64_IBSFETCHCTL,
+	.config_mask		= IBS_FETCH_CONFIG_MASK,
+	.cnt_mask		= IBS_FETCH_MAX_CNT,
+	.enable_mask		= IBS_FETCH_ENABLE,
+	.valid_mask		= IBS_FETCH_VAL,
+	.max_period		= IBS_FETCH_MAX_CNT << 4,
+	.offset_mask		= { MSR_AMD64_IBSFETCH_REG_MASK },
+	.offset_max		= MSR_AMD64_IBSFETCH_REG_COUNT,
+
+	.get_count		= get_ibs_fetch_count,
 };
 
+static struct perf_ibs perf_ibs_op = {
+	.pmu = {
+		.task_ctx_nr	= perf_invalid_context,
+
+		.event_init	= perf_ibs_init,
+		.add		= perf_ibs_add,
+		.del		= perf_ibs_del,
+		.start		= perf_ibs_start,
+		.stop		= perf_ibs_stop,
+		.read		= perf_ibs_read,
+	},
+	.msr			= MSR_AMD64_IBSOPCTL,
+	.config_mask		= IBS_OP_CONFIG_MASK,
+	.cnt_mask		= IBS_OP_MAX_CNT,
+	.enable_mask		= IBS_OP_ENABLE,
+	.valid_mask		= IBS_OP_VAL,
+	.max_period		= IBS_OP_MAX_CNT << 4,
+	.offset_mask		= { MSR_AMD64_IBSOP_REG_MASK },
+	.offset_max		= MSR_AMD64_IBSOP_REG_COUNT,
+
+	.get_count		= get_ibs_op_count,
+};
+
+static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
+{
+	struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
+	struct perf_event *event = pcpu->event;
+	struct hw_perf_event *hwc = &event->hw;
+	struct perf_sample_data data;
+	struct perf_raw_record raw;
+	struct pt_regs regs;
+	struct perf_ibs_data ibs_data;
+	int offset, size, overflow, reenable;
+	unsigned int msr;
+	u64 *buf, config;
+
+	if (!test_bit(IBS_STARTED, pcpu->state)) {
+		/* Catch spurious interrupts after stopping IBS: */
+		if (!test_and_clear_bit(IBS_STOPPING, pcpu->state))
+			return 0;
+		rdmsrl(perf_ibs->msr, *ibs_data.regs);
+		return (*ibs_data.regs & perf_ibs->valid_mask) ? 1 : 0;
+	}
+
+	msr = hwc->config_base;
+	buf = ibs_data.regs;
+	rdmsrl(msr, *buf);
+	if (!(*buf++ & perf_ibs->valid_mask))
+		return 0;
+
+	perf_sample_data_init(&data, 0);
+	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
+		ibs_data.caps = ibs_caps;
+		size = 1;
+		offset = 1;
+		do {
+		    rdmsrl(msr + offset, *buf++);
+		    size++;
+		    offset = find_next_bit(perf_ibs->offset_mask,
+					   perf_ibs->offset_max,
+					   offset + 1);
+		} while (offset < perf_ibs->offset_max);
+		raw.size = sizeof(u32) + sizeof(u64) * size;
+		raw.data = ibs_data.data;
+		data.raw = &raw;
+	}
+
+	regs = *iregs; /* XXX: update ip from ibs sample */
+
+	/*
+	 * Emulate IbsOpCurCnt in MSRC001_1033 (IbsOpCtl), not
+	 * supported in all cpus. As this triggered an interrupt, we
+	 * set the current count to the max count.
+	 */
+	config = ibs_data.regs[0];
+	if (perf_ibs == &perf_ibs_op && !(ibs_caps & IBS_CAPS_RDWROPCNT)) {
+		config &= ~IBS_OP_CUR_CNT;
+		config |= (config & IBS_OP_MAX_CNT) << 36;
+	}
+
+	perf_ibs_event_update(perf_ibs, event, config);
+
+	overflow = perf_ibs_set_period(perf_ibs, hwc, &config);
+	reenable = !(overflow && perf_event_overflow(event, &data, &regs));
+	config = (config >> 4) | (reenable ? perf_ibs->enable_mask : 0);
+	perf_ibs_enable_event(hwc, config);
+
+	perf_event_update_userpage(event);
+
+	return 1;
+}
+
+static int __kprobes
+perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
+{
+	int handled = 0;
+
+	handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
+	handled += perf_ibs_handle_irq(&perf_ibs_op, regs);
+
+	if (handled)
+		inc_irq_stat(apic_perf_irqs);
+
+	return handled;
+}
+
+static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
+{
+	struct cpu_perf_ibs __percpu *pcpu;
+	int ret;
+
+	pcpu = alloc_percpu(struct cpu_perf_ibs);
+	if (!pcpu)
+		return -ENOMEM;
+
+	perf_ibs->pcpu = pcpu;
+
+	ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
+	if (ret) {
+		perf_ibs->pcpu = NULL;
+		free_percpu(pcpu);
+	}
+
+	return ret;
+}
+
 static __init int perf_event_ibs_init(void)
 {
 	if (!ibs_caps)
 		return -ENODEV;	/* ibs not supported by the cpu */
 
-	perf_pmu_register(&perf_ibs, "ibs", -1);
+	perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
+	perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
+	register_nmi_handler(NMI_LOCAL, &perf_ibs_nmi_handler, 0, "perf_ibs");
 	printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
 
 	return 0;
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index c7f64e6..addf9e8 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -40,6 +40,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
 		{ X86_FEATURE_EPB,		CR_ECX, 3, 0x00000006, 0 },
 		{ X86_FEATURE_XSAVEOPT,		CR_EAX,	0, 0x0000000d, 1 },
 		{ X86_FEATURE_CPB,		CR_EDX, 9, 0x80000007, 0 },
+		{ X86_FEATURE_HW_PSTATE,	CR_EDX, 7, 0x80000007, 0 },
 		{ X86_FEATURE_NPT,		CR_EDX, 0, 0x8000000a, 0 },
 		{ X86_FEATURE_LBRV,		CR_EDX, 1, 0x8000000a, 0 },
 		{ X86_FEATURE_SVML,		CR_EDX, 2, 0x8000000a, 0 },
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 13ad899..571f253 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -54,16 +54,12 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
 	 */
 	cpu_emergency_vmxoff();
 	cpu_emergency_svm_disable();
-
-	disable_local_APIC();
 }
 
 static void kdump_nmi_shootdown_cpus(void)
 {
 	in_crash_kexec = 1;
 	nmi_shootdown_cpus(kdump_nmi_callback);
-
-	disable_local_APIC();
 }
 
 #else
@@ -95,10 +91,6 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 	cpu_emergency_vmxoff();
 	cpu_emergency_svm_disable();
 
-	lapic_shutdown();
-#if defined(CONFIG_X86_IO_APIC)
-	disable_IO_APIC();
-#endif
 #ifdef CONFIG_HPET_TIMER
 	hpet_disable();
 #endif
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index 642f75a..11891ca 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -62,16 +62,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 
 	if (!userbuf) {
 		memcpy(buf, (vaddr + offset), csize);
-		kunmap_atomic(vaddr, KM_PTE0);
+		kunmap_atomic(vaddr);
 	} else {
 		if (!kdump_buf_page) {
 			printk(KERN_WARNING "Kdump: Kdump buffer page not"
 				" allocated\n");
-			kunmap_atomic(vaddr, KM_PTE0);
+			kunmap_atomic(vaddr);
 			return -EFAULT;
 		}
 		copy_page(kdump_buf_page, vaddr);
-		kunmap_atomic(vaddr, KM_PTE0);
+		kunmap_atomic(vaddr);
 		if (copy_to_user(buf, (kdump_buf_page + offset), csize))
 			return -EFAULT;
 	}
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 62d61e9..dd27ca0 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -136,6 +136,7 @@ static void __init e820_print_type(u32 type)
 		printk(KERN_CONT "(usable)");
 		break;
 	case E820_RESERVED:
+	case E820_RESERVED_EFI:
 		printk(KERN_CONT "(reserved)");
 		break;
 	case E820_ACPI:
@@ -754,7 +755,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
 /*
  * Find the highest page frame number we have available
  */
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
 {
 	int i;
 	unsigned long last_pfn = 0;
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 313fb5c..43e2b1c 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -306,10 +306,10 @@ void __init native_init_IRQ(void)
 	 * us. (some of these will be overridden and become
 	 * 'special' SMP interrupts)
 	 */
-	for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
+	i = FIRST_EXTERNAL_VECTOR;
+	for_each_clear_bit_from(i, used_vectors, NR_VECTORS) {
 		/* IA32_SYSCALL_VECTOR could be used in trap_init already. */
-		if (!test_bit(i, used_vectors))
-			set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
+		set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
 	}
 
 	if (!acpi_ioapic && !of_ioapic)
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index ac0417b..73465aa 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -360,7 +360,6 @@ out:
 static enum ucode_state
 request_microcode_user(int cpu, const void __user *buf, size_t size)
 {
-	pr_info("AMD microcode update via /dev/cpu/microcode not supported\n");
 	return UCODE_ERROR;
 }
 
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index fda91c3..87a0f86 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -86,6 +86,7 @@
 
 #include <asm/microcode.h>
 #include <asm/processor.h>
+#include <asm/cpu_device_id.h>
 
 MODULE_DESCRIPTION("Microcode Update Driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
@@ -504,6 +505,20 @@ static struct notifier_block __refdata mc_cpu_notifier = {
 	.notifier_call	= mc_cpu_callback,
 };
 
+#ifdef MODULE
+/* Autoload on Intel and AMD systems */
+static const struct x86_cpu_id microcode_id[] = {
+#ifdef CONFIG_MICROCODE_INTEL
+	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, },
+#endif
+#ifdef CONFIG_MICROCODE_AMD
+	{ X86_VENDOR_AMD, X86_FAMILY_ANY, X86_MODEL_ANY, },
+#endif
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, microcode_id);
+#endif
+
 static int __init microcode_init(void)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c
index 0d01a8e..8aca005 100644
--- a/arch/x86/kernel/nmi_selftest.c
+++ b/arch/x86/kernel/nmi_selftest.c
@@ -12,6 +12,7 @@
 #include <linux/smp.h>
 #include <linux/cpumask.h>
 #include <linux/delay.h>
+#include <linux/percpu.h>
 
 #include <asm/apic.h>
 #include <asm/nmi.h>
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index d90272e..2f0c1d1 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -239,16 +239,16 @@ static DEFINE_PER_CPU(enum paravirt_lazy_mode, paravirt_lazy_mode) = PARAVIRT_LA
 
 static inline void enter_lazy(enum paravirt_lazy_mode mode)
 {
-	BUG_ON(percpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
+	BUG_ON(__this_cpu_read(paravirt_lazy_mode) != PARAVIRT_LAZY_NONE);
 
-	percpu_write(paravirt_lazy_mode, mode);
+	__this_cpu_write(paravirt_lazy_mode, mode);
 }
 
 static void leave_lazy(enum paravirt_lazy_mode mode)
 {
-	BUG_ON(percpu_read(paravirt_lazy_mode) != mode);
+	BUG_ON(__this_cpu_read(paravirt_lazy_mode) != mode);
 
-	percpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
+	__this_cpu_write(paravirt_lazy_mode, PARAVIRT_LAZY_NONE);
 }
 
 void paravirt_enter_lazy_mmu(void)
@@ -265,7 +265,7 @@ void paravirt_start_context_switch(struct task_struct *prev)
 {
 	BUG_ON(preemptible());
 
-	if (percpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) {
+	if (__this_cpu_read(paravirt_lazy_mode) == PARAVIRT_LAZY_MMU) {
 		arch_leave_lazy_mmu_mode();
 		set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
 	}
@@ -287,7 +287,7 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
 	if (in_interrupt())
 		return PARAVIRT_LAZY_NONE;
 
-	return percpu_read(paravirt_lazy_mode);
+	return __this_cpu_read(paravirt_lazy_mode);
 }
 
 void arch_flush_lazy_mmu_mode(void)
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 726494b..07b587c 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -431,7 +431,7 @@ static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr,
 }
 
 static void* calgary_alloc_coherent(struct device *dev, size_t size,
-	dma_addr_t *dma_handle, gfp_t flag)
+	dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs)
 {
 	void *ret = NULL;
 	dma_addr_t mapping;
@@ -464,7 +464,8 @@ error:
 }
 
 static void calgary_free_coherent(struct device *dev, size_t size,
-				  void *vaddr, dma_addr_t dma_handle)
+				  void *vaddr, dma_addr_t dma_handle,
+				  struct dma_attrs *attrs)
 {
 	unsigned int npages;
 	struct iommu_table *tbl = find_iommu_table(dev);
@@ -477,8 +478,8 @@ static void calgary_free_coherent(struct device *dev, size_t size,
 }
 
 static struct dma_map_ops calgary_dma_ops = {
-	.alloc_coherent = calgary_alloc_coherent,
-	.free_coherent = calgary_free_coherent,
+	.alloc = calgary_alloc_coherent,
+	.free = calgary_free_coherent,
 	.map_sg = calgary_map_sg,
 	.unmap_sg = calgary_unmap_sg,
 	.map_page = calgary_map_page,
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 1c4d769..75e1cc1 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -96,7 +96,8 @@ void __init pci_iommu_alloc(void)
 	}
 }
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
-				 dma_addr_t *dma_addr, gfp_t flag)
+				 dma_addr_t *dma_addr, gfp_t flag,
+				 struct dma_attrs *attrs)
 {
 	unsigned long dma_mask;
 	struct page *page;
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index 3af4af8..f960506 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -75,7 +75,7 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 }
 
 static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
-				dma_addr_t dma_addr)
+				dma_addr_t dma_addr, struct dma_attrs *attrs)
 {
 	free_pages((unsigned long)vaddr, get_order(size));
 }
@@ -96,8 +96,8 @@ static void nommu_sync_sg_for_device(struct device *dev,
 }
 
 struct dma_map_ops nommu_dma_ops = {
-	.alloc_coherent		= dma_generic_alloc_coherent,
-	.free_coherent		= nommu_free_coherent,
+	.alloc			= dma_generic_alloc_coherent,
+	.free			= nommu_free_coherent,
 	.map_sg			= nommu_map_sg,
 	.map_page		= nommu_map_page,
 	.sync_single_for_device = nommu_sync_single_for_device,
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index 8f972cb..fa462a3 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -15,21 +15,23 @@
 int swiotlb __read_mostly;
 
 static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-					dma_addr_t *dma_handle, gfp_t flags)
+					dma_addr_t *dma_handle, gfp_t flags,
+					struct dma_attrs *attrs)
 {
 	void *vaddr;
 
-	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags);
+	vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags,
+					   attrs);
 	if (vaddr)
 		return vaddr;
 
-	return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
+	return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags, attrs);
 }
 
 static struct dma_map_ops swiotlb_dma_ops = {
 	.mapping_error = swiotlb_dma_mapping_error,
-	.alloc_coherent = x86_swiotlb_alloc_coherent,
-	.free_coherent = swiotlb_free_coherent,
+	.alloc = x86_swiotlb_alloc_coherent,
+	.free = swiotlb_free_coherent,
 	.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
 	.sync_single_for_device = swiotlb_sync_single_for_device,
 	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 80bfe1a..0c1ec73 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -214,6 +214,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
 	task_user_gs(p) = get_user_gs(regs);
 
+	p->fpu_counter = 0;
 	p->thread.io_bitmap_ptr = NULL;
 	tsk = current;
 	err = -ENOMEM;
@@ -303,7 +304,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
-	fpu = switch_fpu_prepare(prev_p, next_p);
+	fpu = switch_fpu_prepare(prev_p, next_p, cpu);
 
 	/*
 	 * Reload esp0.
@@ -360,7 +361,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	switch_fpu_finish(next_p, fpu);
 
-	percpu_write(current_task, next_p);
+	__this_cpu_write(current_task, next_p);
 
 	return prev_p;
 }
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 1fd94bc..cb5d11b 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister);
 
 void enter_idle(void)
 {
-	percpu_write(is_idle, 1);
+	__this_cpu_write(is_idle, 1);
 	atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
 }
 
@@ -286,6 +286,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
 	set_tsk_thread_flag(p, TIF_FORK);
 
+	p->fpu_counter = 0;
 	p->thread.io_bitmap_ptr = NULL;
 
 	savesegment(gs, p->thread.gsindex);
@@ -343,7 +344,7 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip,
 	load_gs_index(0);
 	regs->ip		= new_ip;
 	regs->sp		= new_sp;
-	percpu_write(old_rsp, new_sp);
+	this_cpu_write(old_rsp, new_sp);
 	regs->cs		= _cs;
 	regs->ss		= _ss;
 	regs->flags		= X86_EFLAGS_IF;
@@ -388,7 +389,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	unsigned fsindex, gsindex;
 	fpu_switch_t fpu;
 
-	fpu = switch_fpu_prepare(prev_p, next_p);
+	fpu = switch_fpu_prepare(prev_p, next_p, cpu);
 
 	/*
 	 * Reload esp0, LDT and the page table pointer:
@@ -463,11 +464,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	/*
 	 * Switch the PDA and FPU contexts.
 	 */
-	prev->usersp = percpu_read(old_rsp);
-	percpu_write(old_rsp, next->usersp);
-	percpu_write(current_task, next_p);
+	prev->usersp = __this_cpu_read(old_rsp);
+	__this_cpu_write(old_rsp, next->usersp);
+	__this_cpu_write(current_task, next_p);
 
-	percpu_write(kernel_stack,
+	__this_cpu_write(kernel_stack,
 		  (unsigned long)task_stack_page(next_p) +
 		  THREAD_SIZE - KERNEL_STACK_OFFSET);
 
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index d840e69..77215c2 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -39,7 +39,8 @@ static int reboot_mode;
 enum reboot_type reboot_type = BOOT_ACPI;
 int reboot_force;
 
-/* This variable is used privately to keep track of whether or not
+/*
+ * This variable is used privately to keep track of whether or not
  * reboot_type is still set to its default value (i.e., reboot= hasn't
  * been set on the command line).  This is needed so that we can
  * suppress DMI scanning for reboot quirks.  Without it, it's
@@ -51,7 +52,8 @@ static int reboot_default = 1;
 static int reboot_cpu = -1;
 #endif
 
-/* This is set if we need to go through the 'emergency' path.
+/*
+ * This is set if we need to go through the 'emergency' path.
  * When machine_emergency_restart() is called, we may be on
  * an inconsistent state and won't be able to do a clean cleanup
  */
@@ -60,22 +62,24 @@ static int reboot_emergency;
 /* This is set by the PCI code if either type 1 or type 2 PCI is detected */
 bool port_cf9_safe = false;
 
-/* reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
-   warm   Don't set the cold reboot flag
-   cold   Set the cold reboot flag
-   bios   Reboot by jumping through the BIOS (only for X86_32)
-   smp    Reboot by executing reset on BSP or other CPU (only for X86_32)
-   triple Force a triple fault (init)
-   kbd    Use the keyboard controller. cold reset (default)
-   acpi   Use the RESET_REG in the FADT
-   efi    Use efi reset_system runtime service
-   pci    Use the so-called "PCI reset register", CF9
-   force  Avoid anything that could hang.
+/*
+ * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
+ * warm   Don't set the cold reboot flag
+ * cold   Set the cold reboot flag
+ * bios   Reboot by jumping through the BIOS (only for X86_32)
+ * smp    Reboot by executing reset on BSP or other CPU (only for X86_32)
+ * triple Force a triple fault (init)
+ * kbd    Use the keyboard controller. cold reset (default)
+ * acpi   Use the RESET_REG in the FADT
+ * efi    Use efi reset_system runtime service
+ * pci    Use the so-called "PCI reset register", CF9
+ * force  Avoid anything that could hang.
  */
 static int __init reboot_setup(char *str)
 {
 	for (;;) {
-		/* Having anything passed on the command line via
+		/*
+		 * Having anything passed on the command line via
 		 * reboot= will cause us to disable DMI checking
 		 * below.
 		 */
@@ -98,9 +102,11 @@ static int __init reboot_setup(char *str)
 				if (isdigit(*(str+2)))
 					reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
 			}
-				/* we will leave sorting out the final value
-				   when we are ready to reboot, since we might not
-				   have detected BSP APIC ID or smp_num_cpu */
+			/*
+			 * We will leave sorting out the final value
+			 * when we are ready to reboot, since we might not
+			 * have detected BSP APIC ID or smp_num_cpu
+			 */
 			break;
 #endif /* CONFIG_SMP */
 
@@ -150,6 +156,82 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
 	return 0;
 }
 
+extern const unsigned char machine_real_restart_asm[];
+extern const u64 machine_real_restart_gdt[3];
+
+void machine_real_restart(unsigned int type)
+{
+	void *restart_va;
+	unsigned long restart_pa;
+	void (*restart_lowmem)(unsigned int);
+	u64 *lowmem_gdt;
+
+	local_irq_disable();
+
+	/*
+	 * Write zero to CMOS register number 0x0f, which the BIOS POST
+	 * routine will recognize as telling it to do a proper reboot.  (Well
+	 * that's what this book in front of me says -- it may only apply to
+	 * the Phoenix BIOS though, it's not clear).  At the same time,
+	 * disable NMIs by setting the top bit in the CMOS address register,
+	 * as we're about to do peculiar things to the CPU.  I'm not sure if
+	 * `outb_p' is needed instead of just `outb'.  Use it to be on the
+	 * safe side.  (Yes, CMOS_WRITE does outb_p's. -  Paul G.)
+	 */
+	spin_lock(&rtc_lock);
+	CMOS_WRITE(0x00, 0x8f);
+	spin_unlock(&rtc_lock);
+
+	/*
+	 * Switch back to the initial page table.
+	 */
+	load_cr3(initial_page_table);
+
+	/*
+	 * Write 0x1234 to absolute memory location 0x472.  The BIOS reads
+	 * this on booting to tell it to "Bypass memory test (also warm
+	 * boot)".  This seems like a fairly standard thing that gets set by
+	 * REBOOT.COM programs, and the previous reset routine did this
+	 * too. */
+	*((unsigned short *)0x472) = reboot_mode;
+
+	/* Patch the GDT in the low memory trampoline */
+	lowmem_gdt = TRAMPOLINE_SYM(machine_real_restart_gdt);
+
+	restart_va = TRAMPOLINE_SYM(machine_real_restart_asm);
+	restart_pa = virt_to_phys(restart_va);
+	restart_lowmem = (void (*)(unsigned int))restart_pa;
+
+	/* GDT[0]: GDT self-pointer */
+	lowmem_gdt[0] =
+		(u64)(sizeof(machine_real_restart_gdt) - 1) +
+		((u64)virt_to_phys(lowmem_gdt) << 16);
+	/* GDT[1]: 64K real mode code segment */
+	lowmem_gdt[1] =
+		GDT_ENTRY(0x009b, restart_pa, 0xffff);
+
+	/* Jump to the identity-mapped low memory code */
+	restart_lowmem(type);
+}
+#ifdef CONFIG_APM_MODULE
+EXPORT_SYMBOL(machine_real_restart);
+#endif
+
+#endif /* CONFIG_X86_32 */
+
+/*
+ * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
+ */
+static int __init set_pci_reboot(const struct dmi_system_id *d)
+{
+	if (reboot_type != BOOT_CF9) {
+		reboot_type = BOOT_CF9;
+		printk(KERN_INFO "%s series board detected. "
+		       "Selecting PCI-method for reboots.\n", d->ident);
+	}
+	return 0;
+}
+
 static int __init set_kbd_reboot(const struct dmi_system_id *d)
 {
 	if (reboot_type != BOOT_KBD) {
@@ -159,7 +241,12 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d)
 	return 0;
 }
 
+/*
+ * This is a single dmi_table handling all reboot quirks.  Note that
+ * REBOOT_BIOS is only available for 32bit
+ */
 static struct dmi_system_id __initdata reboot_dmi_table[] = {
+#ifdef CONFIG_X86_32
 	{	/* Handle problems with rebooting on Dell E520's */
 		.callback = set_bios_reboot,
 		.ident = "Dell E520",
@@ -184,7 +271,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
 		},
 	},
-	{       /* Handle problems with rebooting on Dell Optiplex 745's SFF*/
+	{	/* Handle problems with rebooting on Dell Optiplex 745's SFF */
 		.callback = set_bios_reboot,
 		.ident = "Dell OptiPlex 745",
 		.matches = {
@@ -192,7 +279,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
 		},
 	},
-	{       /* Handle problems with rebooting on Dell Optiplex 745's DFF*/
+	{	/* Handle problems with rebooting on Dell Optiplex 745's DFF */
 		.callback = set_bios_reboot,
 		.ident = "Dell OptiPlex 745",
 		.matches = {
@@ -201,7 +288,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_BOARD_NAME, "0MM599"),
 		},
 	},
-	{       /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
+	{	/* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
 		.callback = set_bios_reboot,
 		.ident = "Dell OptiPlex 745",
 		.matches = {
@@ -210,7 +297,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_BOARD_NAME, "0KW626"),
 		},
 	},
-	{   /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
+	{	/* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
 		.callback = set_bios_reboot,
 		.ident = "Dell OptiPlex 330",
 		.matches = {
@@ -219,7 +306,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_BOARD_NAME, "0KP561"),
 		},
 	},
-	{   /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
+	{	/* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
 		.callback = set_bios_reboot,
 		.ident = "Dell OptiPlex 360",
 		.matches = {
@@ -228,7 +315,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
 		},
 	},
-	{	/* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G*/
+	{	/* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */
 		.callback = set_bios_reboot,
 		.ident = "Dell OptiPlex 760",
 		.matches = {
@@ -301,7 +388,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
 		},
 	},
-	{       /* Handle problems with rebooting on ASUS P4S800 */
+	{	/* Handle problems with rebooting on ASUS P4S800 */
 		.callback = set_bios_reboot,
 		.ident = "ASUS P4S800",
 		.matches = {
@@ -309,7 +396,9 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
 		},
 	},
-	{ /* Handle reboot issue on Acer Aspire one */
+#endif /* CONFIG_X86_32 */
+
+	{	/* Handle reboot issue on Acer Aspire one */
 		.callback = set_kbd_reboot,
 		.ident = "Acer Aspire One A110",
 		.matches = {
@@ -317,96 +406,6 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
 			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
 		},
 	},
-	{ }
-};
-
-static int __init reboot_init(void)
-{
-	/* Only do the DMI check if reboot_type hasn't been overridden
-	 * on the command line
-	 */
-	if (reboot_default) {
-		dmi_check_system(reboot_dmi_table);
-	}
-	return 0;
-}
-core_initcall(reboot_init);
-
-extern const unsigned char machine_real_restart_asm[];
-extern const u64 machine_real_restart_gdt[3];
-
-void machine_real_restart(unsigned int type)
-{
-	void *restart_va;
-	unsigned long restart_pa;
-	void (*restart_lowmem)(unsigned int);
-	u64 *lowmem_gdt;
-
-	local_irq_disable();
-
-	/* Write zero to CMOS register number 0x0f, which the BIOS POST
-	   routine will recognize as telling it to do a proper reboot.  (Well
-	   that's what this book in front of me says -- it may only apply to
-	   the Phoenix BIOS though, it's not clear).  At the same time,
-	   disable NMIs by setting the top bit in the CMOS address register,
-	   as we're about to do peculiar things to the CPU.  I'm not sure if
-	   `outb_p' is needed instead of just `outb'.  Use it to be on the
-	   safe side.  (Yes, CMOS_WRITE does outb_p's. -  Paul G.)
-	 */
-	spin_lock(&rtc_lock);
-	CMOS_WRITE(0x00, 0x8f);
-	spin_unlock(&rtc_lock);
-
-	/*
-	 * Switch back to the initial page table.
-	 */
-	load_cr3(initial_page_table);
-
-	/* Write 0x1234 to absolute memory location 0x472.  The BIOS reads
-	   this on booting to tell it to "Bypass memory test (also warm
-	   boot)".  This seems like a fairly standard thing that gets set by
-	   REBOOT.COM programs, and the previous reset routine did this
-	   too. */
-	*((unsigned short *)0x472) = reboot_mode;
-
-	/* Patch the GDT in the low memory trampoline */
-	lowmem_gdt = TRAMPOLINE_SYM(machine_real_restart_gdt);
-
-	restart_va = TRAMPOLINE_SYM(machine_real_restart_asm);
-	restart_pa = virt_to_phys(restart_va);
-	restart_lowmem = (void (*)(unsigned int))restart_pa;
-
-	/* GDT[0]: GDT self-pointer */
-	lowmem_gdt[0] =
-		(u64)(sizeof(machine_real_restart_gdt) - 1) +
-		((u64)virt_to_phys(lowmem_gdt) << 16);
-	/* GDT[1]: 64K real mode code segment */
-	lowmem_gdt[1] =
-		GDT_ENTRY(0x009b, restart_pa, 0xffff);
-
-	/* Jump to the identity-mapped low memory code */
-	restart_lowmem(type);
-}
-#ifdef CONFIG_APM_MODULE
-EXPORT_SYMBOL(machine_real_restart);
-#endif
-
-#endif /* CONFIG_X86_32 */
-
-/*
- * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
- */
-static int __init set_pci_reboot(const struct dmi_system_id *d)
-{
-	if (reboot_type != BOOT_CF9) {
-		reboot_type = BOOT_CF9;
-		printk(KERN_INFO "%s series board detected. "
-		       "Selecting PCI-method for reboots.\n", d->ident);
-	}
-	return 0;
-}
-
-static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
 	{	/* Handle problems with rebooting on Apple MacBook5 */
 		.callback = set_pci_reboot,
 		.ident = "Apple MacBook5",
@@ -474,17 +473,17 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
 	{ }
 };
 
-static int __init pci_reboot_init(void)
+static int __init reboot_init(void)
 {
-	/* Only do the DMI check if reboot_type hasn't been overridden
+	/*
+	 * Only do the DMI check if reboot_type hasn't been overridden
 	 * on the command line
 	 */
-	if (reboot_default) {
-		dmi_check_system(pci_reboot_dmi_table);
-	}
+	if (reboot_default)
+		dmi_check_system(reboot_dmi_table);
 	return 0;
 }
-core_initcall(pci_reboot_init);
+core_initcall(reboot_init);
 
 static inline void kb_wait(void)
 {
@@ -502,14 +501,14 @@ static void vmxoff_nmi(int cpu, struct pt_regs *regs)
 	cpu_emergency_vmxoff();
 }
 
-/* Use NMIs as IPIs to tell all CPUs to disable virtualization
- */
+/* Use NMIs as IPIs to tell all CPUs to disable virtualization */
 static void emergency_vmx_disable_all(void)
 {
 	/* Just make sure we won't change CPUs while doing this */
 	local_irq_disable();
 
-	/* We need to disable VMX on all CPUs before rebooting, otherwise
+	/*
+	 * We need to disable VMX on all CPUs before rebooting, otherwise
 	 * we risk hanging up the machine, because the CPU ignore INIT
 	 * signals when VMX is enabled.
 	 *
@@ -528,8 +527,7 @@ static void emergency_vmx_disable_all(void)
 	 * is still enabling VMX.
 	 */
 	if (cpu_has_vmx() && cpu_vmx_enabled()) {
-		/* Disable VMX on this CPU.
-		 */
+		/* Disable VMX on this CPU. */
 		cpu_vmxoff();
 
 		/* Halt and disable VMX on the other CPUs */
@@ -574,12 +572,12 @@ static void native_machine_emergency_restart(void)
 		/* Could also try the reset bit in the Hammer NB */
 		switch (reboot_type) {
 		case BOOT_KBD:
-			mach_reboot_fixups(); /* for board specific fixups */
+			mach_reboot_fixups(); /* For board specific fixups */
 
 			for (i = 0; i < 10; i++) {
 				kb_wait();
 				udelay(50);
-				outb(0xfe, 0x64); /* pulse reset low */
+				outb(0xfe, 0x64); /* Pulse reset low */
 				udelay(50);
 			}
 			if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
@@ -621,7 +619,7 @@ static void native_machine_emergency_restart(void)
 
 		case BOOT_CF9:
 			port_cf9_safe = true;
-			/* fall through */
+			/* Fall through */
 
 		case BOOT_CF9_COND:
 			if (port_cf9_safe) {
@@ -659,7 +657,8 @@ void native_machine_shutdown(void)
 	/* Make certain I only run on the appropriate processor */
 	set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id));
 
-	/* O.K Now that I'm on the appropriate processor,
+	/*
+	 * O.K Now that I'm on the appropriate processor,
 	 * stop all of the others.
 	 */
 	stop_other_cpus();
@@ -697,12 +696,11 @@ static void native_machine_restart(char *__unused)
 
 static void native_machine_halt(void)
 {
-	/* stop other cpus and apics */
+	/* Stop other cpus and apics */
 	machine_shutdown();
 
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 
-	/* stop this cpu */
 	stop_this_cpu(NULL);
 }
 
@@ -713,7 +711,7 @@ static void native_machine_power_off(void)
 			machine_shutdown();
 		pm_power_off();
 	}
-	/* a fallback in case there is no PM info available */
+	/* A fallback in case there is no PM info available */
 	tboot_shutdown(TB_SHUTDOWN_HALT);
 }
 
@@ -775,7 +773,8 @@ static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
 
 	cpu = raw_smp_processor_id();
 
-	/* Don't do anything if this handler is invoked on crashing cpu.
+	/*
+	 * Don't do anything if this handler is invoked on crashing cpu.
 	 * Otherwise, system will completely hang. Crashing cpu can get
 	 * an NMI if system was initially booted with nmi_watchdog parameter.
 	 */
@@ -799,7 +798,8 @@ static void smp_send_nmi_allbutself(void)
 	apic->send_IPI_allbutself(NMI_VECTOR);
 }
 
-/* Halt all other CPUs, calling the specified function on each of them
+/*
+ * Halt all other CPUs, calling the specified function on each of them
  *
  * This function can be used to halt all other CPUs on crash
  * or emergency reboot time. The function passed as parameter
@@ -810,7 +810,7 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
 	unsigned long msecs;
 	local_irq_disable();
 
-	/* Make a note of crashing cpu. Will be used in NMI callback.*/
+	/* Make a note of crashing cpu. Will be used in NMI callback. */
 	crashing_cpu = safe_smp_processor_id();
 
 	shootdown_callback = callback;
@@ -819,8 +819,9 @@ void nmi_shootdown_cpus(nmi_shootdown_cb callback)
 	/* Would it be better to replace the trap vector here? */
 	if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
 				 NMI_FLAG_FIRST, "crash"))
-		return;		/* return what? */
-	/* Ensure the new callback function is set before sending
+		return;		/* Return what? */
+	/*
+	 * Ensure the new callback function is set before sending
 	 * out the NMI
 	 */
 	wmb();
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d7d5099..e22bb08 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -690,6 +690,8 @@ early_param("reservelow", parse_reservelow);
 
 void __init setup_arch(char **cmdline_p)
 {
+	unsigned long end_pfn;
+
 #ifdef CONFIG_X86_32
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	visws_early_detect();
@@ -926,7 +928,24 @@ void __init setup_arch(char **cmdline_p)
 	init_gbpages();
 
 	/* max_pfn_mapped is updated here */
-	max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
+	end_pfn = max_low_pfn;
+
+#ifdef CONFIG_X86_64
+	/*
+	 * There may be regions after the last E820_RAM region that we
+	 * want to include in the kernel direct mapping because their
+	 * contents are needed at runtime.
+	 */
+	if (efi_enabled) {
+		unsigned long efi_end;
+
+		efi_end = e820_end_pfn(MAXMEM>>PAGE_SHIFT, E820_RESERVED_EFI);
+		if (efi_end > end_pfn)
+			end_pfn = efi_end;
+	}
+#endif
+
+	max_low_pfn_mapped = init_memory_mapping(0, end_pfn << PAGE_SHIFT);
 	max_pfn_mapped = max_low_pfn_mapped;
 
 #ifdef CONFIG_X86_64
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 46a01bd..f190103 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -20,6 +20,7 @@
 #include <linux/personality.h>
 #include <linux/uaccess.h>
 #include <linux/user-return-notifier.h>
+#include <linux/uprobes.h>
 
 #include <asm/processor.h>
 #include <asm/ucontext.h>
@@ -816,6 +817,11 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
 		mce_notify_process();
 #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
 
+	if (thread_info_flags & _TIF_UPROBE) {
+		clear_thread_flag(TIF_UPROBE);
+		uprobe_notify_resume(regs);
+	}
+
 	/* deal with pending signal delivery */
 	if (thread_info_flags & _TIF_SIGPENDING)
 		do_signal(regs);
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
index 0514890..ef59642 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -195,7 +195,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 {
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
-	unsigned long addr = addr0;
+	unsigned long addr = addr0, start_addr;
 
 	/* requested length too big for entire address space */
 	if (len > TASK_SIZE)
@@ -223,25 +223,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 		mm->free_area_cache = mm->mmap_base;
 	}
 
+try_again:
 	/* either no address requested or can't fit in requested address hole */
-	addr = mm->free_area_cache;
-
-	/* make sure it can fit in the remaining address space */
-	if (addr > len) {
-		unsigned long tmp_addr = align_addr(addr - len, filp,
-						    ALIGN_TOPDOWN);
-
-		vma = find_vma(mm, tmp_addr);
-		if (!vma || tmp_addr + len <= vma->vm_start)
-			/* remember the address as a hint for next time */
-			return mm->free_area_cache = tmp_addr;
-	}
-
-	if (mm->mmap_base < len)
-		goto bottomup;
+	start_addr = addr = mm->free_area_cache;
 
-	addr = mm->mmap_base-len;
+	if (addr < len)
+		goto fail;
 
+	addr -= len;
 	do {
 		addr = align_addr(addr, filp, ALIGN_TOPDOWN);
 
@@ -263,6 +252,17 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 		addr = vma->vm_start-len;
 	} while (len < vma->vm_start);
 
+fail:
+	/*
+	 * if hint left us with no space for the requested
+	 * mapping then try again:
+	 */
+	if (start_addr != mm->mmap_base) {
+		mm->free_area_cache = mm->mmap_base;
+		mm->cached_hole_size = 0;
+		goto try_again;
+	}
+
 bottomup:
 	/*
 	 * A failed mmap() very likely causes application failure,
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 77da5b4..4bbe04d 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -571,37 +571,6 @@ asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
 }
 
 /*
- * This gets called with the process already owning the
- * FPU state, and with CR0.TS cleared. It just needs to
- * restore the FPU register state.
- */
-void __math_state_restore(struct task_struct *tsk)
-{
-	/* We need a safe address that is cheap to find and that is already
-	   in L1. We've just brought in "tsk->thread.has_fpu", so use that */
-#define safe_address (tsk->thread.has_fpu)
-
-	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
-	   is pending.  Clear the x87 state here by setting it to fixed
-	   values. safe_address is a random variable that should be in L1 */
-	alternative_input(
-		ASM_NOP8 ASM_NOP2,
-		"emms\n\t"	  	/* clear stack tags */
-		"fildl %P[addr]",	/* set F?P to defined value */
-		X86_FEATURE_FXSAVE_LEAK,
-		[addr] "m" (safe_address));
-
-	/*
-	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
-	 */
-	if (unlikely(restore_fpu_checking(tsk))) {
-		__thread_fpu_end(tsk);
-		force_sig(SIGSEGV, tsk);
-		return;
-	}
-}
-
-/*
  * 'math_state_restore()' saves the current math information in the
  * old math state array, and gets the new ones from the current task
  *
@@ -631,7 +600,14 @@ void math_state_restore(void)
 	}
 
 	__thread_fpu_begin(tsk);
-	__math_state_restore(tsk);
+	/*
+	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
+	 */
+	if (unlikely(restore_fpu_checking(tsk))) {
+		__thread_fpu_end(tsk);
+		force_sig(SIGSEGV, tsk);
+		return;
+	}
 
 	tsk->fpu_counter++;
 }
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
new file mode 100644
index 0000000..1e26700
--- /dev/null
+++ b/arch/x86/kernel/uprobes.c
@@ -0,0 +1,674 @@
+/*
+ * Userspace Probes (UProbes) for x86
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2008-2011
+ * Authors:
+ *	Srikar Dronamraju
+ *	Jim Keniston
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/uprobes.h>
+#include <linux/uaccess.h>
+
+#include <linux/kdebug.h>
+#include <asm/insn.h>
+
+#ifdef CONFIG_X86_32
+#define is_32bit_app(tsk) 1
+#else
+#define is_32bit_app(tsk) (test_tsk_thread_flag(tsk, TIF_IA32))
+#endif
+
+/* Post-execution fixups. */
+
+/* No fixup needed */
+#define UPROBES_FIX_NONE	0x0
+/* Adjust IP back to vicinity of actual insn */
+#define UPROBES_FIX_IP		0x1
+/* Adjust the return address of a call insn */
+#define UPROBES_FIX_CALL	0x2
+
+#define UPROBES_FIX_RIP_AX	0x8000
+#define UPROBES_FIX_RIP_CX	0x4000
+
+/* Adaptations for mhiramat x86 decoder v14. */
+#define OPCODE1(insn) ((insn)->opcode.bytes[0])
+#define OPCODE2(insn) ((insn)->opcode.bytes[1])
+#define OPCODE3(insn) ((insn)->opcode.bytes[2])
+#define MODRM_REG(insn) X86_MODRM_REG(insn->modrm.value)
+
+#define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
+	(((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) |   \
+	  (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) |   \
+	  (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) |   \
+	  (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf))    \
+	 << (row % 32))
+
+#ifdef CONFIG_X86_64
+static volatile u32 good_insns_64[256 / 32] = {
+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
+	/*      ----------------------------------------------         */
+	W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */
+	W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */
+	W(0x20, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 20 */
+	W(0x30, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 30 */
+	W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
+	W(0x60, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
+	W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
+	W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
+	W(0xc0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
+	W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
+	W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
+	W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1)   /* f0 */
+	/*      ----------------------------------------------         */
+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
+};
+#endif
+
+/* Good-instruction tables for 32-bit apps */
+
+static volatile u32 good_insns_32[256 / 32] = {
+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
+	/*      ----------------------------------------------         */
+	W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 00 */
+	W(0x10, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 10 */
+	W(0x20, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) | /* 20 */
+	W(0x30, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) , /* 30 */
+	W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
+	W(0x60, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
+	W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
+	W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
+	W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
+	W(0xd0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
+	W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
+	W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1)   /* f0 */
+	/*      ----------------------------------------------         */
+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
+};
+
+/* Using this for both 64-bit and 32-bit apps */
+static volatile u32 good_2byte_insns[256 / 32] = {
+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
+	/*      ----------------------------------------------         */
+	W(0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) | /* 00 */
+	W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1) , /* 10 */
+	W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 20 */
+	W(0x30, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */
+	W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
+	W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 60 */
+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) , /* 70 */
+	W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
+	W(0xa0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1) | /* a0 */
+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
+	W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */
+	W(0xd0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
+	W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* e0 */
+	W(0xf0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)   /* f0 */
+	/*      ----------------------------------------------         */
+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
+};
+
+#undef W
+
+/*
+ * opcodes we'll probably never support:
+ * 6c-6d, e4-e5, ec-ed - in
+ * 6e-6f, e6-e7, ee-ef - out
+ * cc, cd - int3, int
+ * cf - iret
+ * d6 - illegal instruction
+ * f1 - int1/icebp
+ * f4 - hlt
+ * fa, fb - cli, sti
+ * 0f - lar, lsl, syscall, clts, sysret, sysenter, sysexit, invd, wbinvd, ud2
+ *
+ * invalid opcodes in 64-bit mode:
+ * 06, 0e, 16, 1e, 27, 2f, 37, 3f, 60-62, 82, c4-c5, d4-d5
+ *
+ * 63 - we support this opcode in x86_64 but not in i386.
+ *
+ * opcodes we may need to refine support for:
+ * 0f - 2-byte instructions: For many of these instructions, the validity
+ * depends on the prefix and/or the reg field.  On such instructions, we
+ * just consider the opcode combination valid if it corresponds to any
+ * valid instruction.
+ * 8f - Group 1 - only reg = 0 is OK
+ * c6-c7 - Group 11 - only reg = 0 is OK
+ * d9-df - fpu insns with some illegal encodings
+ * f2, f3 - repnz, repz prefixes.  These are also the first byte for
+ * certain floating-point instructions, such as addsd.
+ * fe - Group 4 - only reg = 0 or 1 is OK
+ * ff - Group 5 - only reg = 0-6 is OK
+ *
+ * others -- Do we need to support these?
+ * 0f - (floating-point?) prefetch instructions
+ * 07, 17, 1f - pop es, pop ss, pop ds
+ * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes --
+ *	but 64 and 65 (fs: and gs:) seem to be used, so we support them
+ * 67 - addr16 prefix
+ * ce - into
+ * f0 - lock prefix
+ */
+
+/*
+ * TODO:
+ * - Where necessary, examine the modrm byte and allow only valid instructions
+ * in the different Groups and fpu instructions.
+ */
+
+static bool is_prefix_bad(struct insn *insn)
+{
+	int i;
+
+	for (i = 0; i < insn->prefixes.nbytes; i++) {
+		switch (insn->prefixes.bytes[i]) {
+		case 0x26:	/*INAT_PFX_ES   */
+		case 0x2E:	/*INAT_PFX_CS   */
+		case 0x36:	/*INAT_PFX_DS   */
+		case 0x3E:	/*INAT_PFX_SS   */
+		case 0xF0:	/*INAT_PFX_LOCK */
+			return true;
+		}
+	}
+	return false;
+}
+
+static int validate_insn_32bits(struct uprobe *uprobe, struct insn *insn)
+{
+	insn_init(insn, uprobe->insn, false);
+
+	/* Skip good instruction prefixes; reject "bad" ones. */
+	insn_get_opcode(insn);
+	if (is_prefix_bad(insn))
+		return -ENOTSUPP;
+	if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_32))
+		return 0;
+	if (insn->opcode.nbytes == 2) {
+		if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
+			return 0;
+	}
+	return -ENOTSUPP;
+}
+
+/*
+ * Figure out which fixups post_xol() will need to perform, and annotate
+ * uprobe->arch_info.fixups accordingly.  To start with,
+ * uprobe->arch_info.fixups is either zero or it reflects rip-related
+ * fixups.
+ */
+static void prepare_fixups(struct uprobe *uprobe, struct insn *insn)
+{
+	bool fix_ip = true, fix_call = false;	/* defaults */
+	int reg;
+
+	insn_get_opcode(insn);	/* should be a nop */
+
+	switch (OPCODE1(insn)) {
+	case 0xc3:		/* ret/lret */
+	case 0xcb:
+	case 0xc2:
+	case 0xca:
+		/* ip is correct */
+		fix_ip = false;
+		break;
+	case 0xe8:		/* call relative - Fix return addr */
+		fix_call = true;
+		break;
+	case 0x9a:		/* call absolute - Fix return addr, not ip */
+		fix_call = true;
+		fix_ip = false;
+		break;
+	case 0xff:
+		insn_get_modrm(insn);
+		reg = MODRM_REG(insn);
+		if (reg == 2 || reg == 3) {
+			/* call or lcall, indirect */
+			/* Fix return addr; ip is correct. */
+			fix_call = true;
+			fix_ip = false;
+		} else if (reg == 4 || reg == 5) {
+			/* jmp or ljmp, indirect */
+			/* ip is correct. */
+			fix_ip = false;
+		}
+		break;
+	case 0xea:		/* jmp absolute -- ip is correct */
+		fix_ip = false;
+		break;
+	default:
+		break;
+	}
+	if (fix_ip)
+		uprobe->arch_info.fixups |= UPROBES_FIX_IP;
+	if (fix_call)
+		uprobe->arch_info.fixups |= UPROBES_FIX_CALL;
+}
+
+#ifdef CONFIG_X86_64
+/*
+ * If uprobe->insn doesn't use rip-relative addressing, return
+ * immediately.  Otherwise, rewrite the instruction so that it accesses
+ * its memory operand indirectly through a scratch register.  Set
+ * uprobe->arch_info.fixups and uprobe->arch_info.rip_rela_target_address
+ * accordingly.  (The contents of the scratch register will be saved
+ * before we single-step the modified instruction, and restored
+ * afterward.)
+ *
+ * We do this because a rip-relative instruction can access only a
+ * relatively small area (+/- 2 GB from the instruction), and the XOL
+ * area typically lies beyond that area.  At least for instructions
+ * that store to memory, we can't execute the original instruction
+ * and "fix things up" later, because the misdirected store could be
+ * disastrous.
+ *
+ * Some useful facts about rip-relative instructions:
+ * - There's always a modrm byte.
+ * - There's never a SIB byte.
+ * - The displacement is always 4 bytes.
+ */
+static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
+							struct insn *insn)
+{
+	u8 *cursor;
+	u8 reg;
+
+	if (mm->context.ia32_compat)
+		return;
+
+	uprobe->arch_info.rip_rela_target_address = 0x0;
+	if (!insn_rip_relative(insn))
+		return;
+
+	/*
+	 * insn_rip_relative() would have decoded rex_prefix, modrm.
+	 * Clear REX.b bit (extension of MODRM.rm field):
+	 * we want to encode rax/rcx, not r8/r9.
+	 */
+	if (insn->rex_prefix.nbytes) {
+		cursor = uprobe->insn + insn_offset_rex_prefix(insn);
+		*cursor &= 0xfe;	/* Clearing REX.B bit */
+	}
+
+	/*
+	 * Point cursor at the modrm byte.  The next 4 bytes are the
+	 * displacement.  Beyond the displacement, for some instructions,
+	 * is the immediate operand.
+	 */
+	cursor = uprobe->insn + insn_offset_modrm(insn);
+	insn_get_length(insn);
+
+	/*
+	 * Convert from rip-relative addressing to indirect addressing
+	 * via a scratch register.  Change the r/m field from 0x5 (%rip)
+	 * to 0x0 (%rax) or 0x1 (%rcx), and squeeze out the offset field.
+	 */
+	reg = MODRM_REG(insn);
+	if (reg == 0) {
+		/*
+		 * The register operand (if any) is either the A register
+		 * (%rax, %eax, etc.) or (if the 0x4 bit is set in the
+		 * REX prefix) %r8.  In any case, we know the C register
+		 * is NOT the register operand, so we use %rcx (register
+		 * #1) for the scratch register.
+		 */
+		uprobe->arch_info.fixups = UPROBES_FIX_RIP_CX;
+		/* Change modrm from 00 000 101 to 00 000 001. */
+		*cursor = 0x1;
+	} else {
+		/* Use %rax (register #0) for the scratch register. */
+		uprobe->arch_info.fixups = UPROBES_FIX_RIP_AX;
+		/* Change modrm from 00 xxx 101 to 00 xxx 000 */
+		*cursor = (reg << 3);
+	}
+
+	/* Target address = address of next instruction + (signed) offset */
+	uprobe->arch_info.rip_rela_target_address = (long)insn->length
+					+ insn->displacement.value;
+	/* Displacement field is gone; slide immediate field (if any) over. */
+	if (insn->immediate.nbytes) {
+		cursor++;
+		memmove(cursor, cursor + insn->displacement.nbytes,
+						insn->immediate.nbytes);
+	}
+	return;
+}
+
+static int validate_insn_64bits(struct uprobe *uprobe, struct insn *insn)
+{
+	insn_init(insn, uprobe->insn, true);
+
+	/* Skip good instruction prefixes; reject "bad" ones. */
+	insn_get_opcode(insn);
+	if (is_prefix_bad(insn))
+		return -ENOTSUPP;
+	if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_64))
+		return 0;
+	if (insn->opcode.nbytes == 2) {
+		if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
+			return 0;
+	}
+	return -ENOTSUPP;
+}
+
+static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe,
+				struct insn *insn)
+{
+	if (mm->context.ia32_compat)
+		return validate_insn_32bits(uprobe, insn);
+	return validate_insn_64bits(uprobe, insn);
+}
+#else
+static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
+							struct insn *insn)
+{
+	return;
+}
+
+static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe,
+				struct insn *insn)
+{
+	return validate_insn_32bits(uprobe, insn);
+}
+#endif /* CONFIG_X86_64 */
+
+/**
+ * analyze_insn - instruction analysis including validity and fixups.
+ * @mm: the probed address space.
+ * @uprobe: the probepoint information.
+ * Return 0 on success or a -ve number on error.
+ */
+int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe)
+{
+	int ret;
+	struct insn insn;
+
+	uprobe->arch_info.fixups = 0;
+	ret = validate_insn_bits(mm, uprobe, &insn);
+	if (ret != 0)
+		return ret;
+	handle_riprel_insn(mm, uprobe, &insn);
+	prepare_fixups(uprobe, &insn);
+	return 0;
+}
+
+#define	UPROBE_TRAP_NO		UINT_MAX
+
+/*
+ * pre_xol - prepare to execute out of line.
+ * @uprobe: the probepoint information.
+ * @regs: reflects the saved user state of @tsk.
+ *
+ * If we're emulating a rip-relative instruction, save the contents
+ * of the scratch register and store the target address in that register.
+ *
+ * Returns true if @uprobe->opcode is @bkpt_insn.
+ */
+#ifdef CONFIG_X86_64
+int pre_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	struct uprobe_task_arch_info *tskinfo = &current->utask->tskinfo;
+
+	tskinfo->saved_trap_no = current->thread.trap_no;
+	current->thread.trap_no = UPROBE_TRAP_NO;
+
+	regs->ip = current->utask->xol_vaddr;
+	if (uprobe->arch_info.fixups & UPROBES_FIX_RIP_AX) {
+		tskinfo->saved_scratch_register = regs->ax;
+		regs->ax = current->utask->vaddr;
+		regs->ax += uprobe->arch_info.rip_rela_target_address;
+	} else if (uprobe->arch_info.fixups & UPROBES_FIX_RIP_CX) {
+		tskinfo->saved_scratch_register = regs->cx;
+		regs->cx = current->utask->vaddr;
+		regs->cx += uprobe->arch_info.rip_rela_target_address;
+	}
+	return 0;
+}
+#else
+int pre_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	struct uprobe_task_arch_info *tskinfo = &current->utask->tskinfo;
+
+	tskinfo->saved_trap_no = current->thread.trap_no;
+	current->thread.trap_no = UPROBE_TRAP_NO;
+
+	regs->ip = current->utask->xol_vaddr;
+	return 0;
+}
+#endif
+
+/*
+ * Called by post_xol() to adjust the return address pushed by a call
+ * instruction executed out of line.
+ */
+static int adjust_ret_addr(unsigned long sp, long correction)
+{
+	int rasize, ncopied;
+	long ra = 0;
+
+	if (is_32bit_app(current))
+		rasize = 4;
+	else
+		rasize = 8;
+
+	ncopied = copy_from_user(&ra, (void __user *)sp, rasize);
+	if (unlikely(ncopied))
+		return -EFAULT;
+
+	ra += correction;
+	ncopied = copy_to_user((void __user *)sp, &ra, rasize);
+	if (unlikely(ncopied))
+		return -EFAULT;
+
+	return 0;
+}
+
+#ifdef CONFIG_X86_64
+static bool is_riprel_insn(struct uprobe *uprobe)
+{
+	return ((uprobe->arch_info.fixups &
+			(UPROBES_FIX_RIP_AX | UPROBES_FIX_RIP_CX)) != 0);
+}
+
+static void handle_riprel_post_xol(struct uprobe *uprobe,
+			struct pt_regs *regs, long *correction)
+{
+	if (is_riprel_insn(uprobe)) {
+		struct uprobe_task_arch_info *tskinfo;
+		tskinfo = &current->utask->tskinfo;
+
+		if (uprobe->arch_info.fixups & UPROBES_FIX_RIP_AX)
+			regs->ax = tskinfo->saved_scratch_register;
+		else
+			regs->cx = tskinfo->saved_scratch_register;
+		/*
+		 * The original instruction includes a displacement, and so
+		 * is 4 bytes longer than what we've just single-stepped.
+		 * Fall through to handle stuff like "jmpq *...(%rip)" and
+		 * "callq *...(%rip)".
+		 */
+		if (correction)
+			*correction += 4;
+	}
+}
+#else
+static void handle_riprel_post_xol(struct uprobe *uprobe,
+			struct pt_regs *regs, long *correction)
+{
+}
+#endif
+
+/*
+ * If xol insn itself traps and generates a signal(Say,
+ * SIGILL/SIGSEGV/etc), then detect the case where a singlestepped
+ * instruction jumps back to its own address. It is assumed that anything
+ * like do_page_fault/do_trap/etc sets thread.trap_no != -1.
+ *
+ * pre_xol/post_xol save/restore thread.trap_no, xol_was_trapped() simply
+ * checks that ->trap_no is not equal to UPROBE_TRAP_NO == -1 set by
+ * pre_xol().
+ */
+bool xol_was_trapped(struct task_struct *tsk)
+{
+	if (tsk->thread.trap_no != UPROBE_TRAP_NO)
+		return true;
+
+	return false;
+}
+
+/*
+ * Called after single-stepping. To avoid the SMP problems that can
+ * occur when we temporarily put back the original opcode to
+ * single-step, we single-stepped a copy of the instruction.
+ *
+ * This function prepares to resume execution after the single-step.
+ * We have to fix things up as follows:
+ *
+ * Typically, the new ip is relative to the copied instruction.  We need
+ * to make it relative to the original instruction (FIX_IP).  Exceptions
+ * are return instructions and absolute or indirect jump or call instructions.
+ *
+ * If the single-stepped instruction was a call, the return address that
+ * is atop the stack is the address following the copied instruction.  We
+ * need to make it the address following the original instruction (FIX_CALL).
+ *
+ * If the original instruction was a rip-relative instruction such as
+ * "movl %edx,0xnnnn(%rip)", we have instead executed an equivalent
+ * instruction using a scratch register -- e.g., "movl %edx,(%rax)".
+ * We need to restore the contents of the scratch register and adjust
+ * the ip, keeping in mind that the instruction we executed is 4 bytes
+ * shorter than the original instruction (since we squeezed out the offset
+ * field).  (FIX_RIP_AX or FIX_RIP_CX)
+ */
+int post_xol(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	struct uprobe_task *utask = current->utask;
+	int result = 0;
+	long correction;
+
+	WARN_ON_ONCE(current->thread.trap_no != UPROBE_TRAP_NO);
+
+	current->thread.trap_no = utask->tskinfo.saved_trap_no;
+	correction = (long)(utask->vaddr - utask->xol_vaddr);
+	handle_riprel_post_xol(uprobe, regs, &correction);
+	if (uprobe->arch_info.fixups & UPROBES_FIX_IP)
+		regs->ip += correction;
+	if (uprobe->arch_info.fixups & UPROBES_FIX_CALL)
+		result = adjust_ret_addr(regs->sp, correction);
+	return result;
+}
+
+/*
+ * Wrapper routine for handling exceptions.
+ */
+int uprobe_exception_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
+{
+	struct die_args *args = data;
+	struct pt_regs *regs = args->regs;
+	int ret = NOTIFY_DONE;
+
+	/* We are only interested in userspace traps */
+	if (regs && !user_mode_vm(regs))
+		return NOTIFY_DONE;
+
+	switch (val) {
+	case DIE_INT3:
+		/* Run your handler here */
+		if (uprobe_bkpt_notifier(regs))
+			ret = NOTIFY_STOP;
+		break;
+	case DIE_DEBUG:
+		if (uprobe_post_notifier(regs))
+			ret = NOTIFY_STOP;
+	default:
+		break;
+	}
+	return ret;
+}
+
+/*
+ * xol insn either trapped or thread has a fatal signal, so reset the
+ * instruction pointer to its probed address.
+ */
+void abort_xol(struct pt_regs *regs, struct uprobe *uprobe)
+{
+	struct uprobe_task *utask = current->utask;
+
+	current->thread.trap_no = utask->tskinfo.saved_trap_no;
+	handle_riprel_post_xol(uprobe, regs, NULL);
+	instruction_pointer_set(regs, utask->vaddr);
+}
+
+/*
+ * Skip these instructions:
+ *
+ * 0f 19 90 90 90 90 90		nopl   -0x6f6f6f70(%rax)
+ * 0f 1f 00			nopl (%rax)
+ * 0f 1f 40 00			nopl 0x0(%rax)
+ * 0f 1f 44 00 00		nopl 0x0(%rax,%rax,1)
+ * 0f 1f 80 00 00 00 00		nopl 0x0(%rax)
+ * 0f 1f 84 00 00 00 00		nopl 0x0(%rax,%rax,1)
+ * 66 0f 1f 44 00 00 00		nopw 0x0(%rax,%rax,1)
+ * 66 0f 1f 84 00 00 00		nopw 0x0(%rax,%rax,1)
+ * 66 87 c0			xchg %eax,%eax
+ * 66 90			nop
+ * 87 c0			xchg %eax,%eax
+ * 90 				nop
+ */
+
+bool uprobe_skip_sstep(struct pt_regs *regs, struct uprobe *u)
+{
+	int i;
+
+	for (i = 0; i < MAX_UINSN_BYTES; i++) {
+		if ((u->insn[i] == 0x66))
+			continue;
+
+		if (u->insn[i] == 0x90)
+			return true;
+
+		if (i == (MAX_UINSN_BYTES - 1))
+			break;
+
+		if ((u->insn[i] == 0x0f) && (u->insn[i+1] == 0x1f))
+			return true;
+
+		if ((u->insn[i] == 0x0f) && (u->insn[i+1] == 0x19))
+			return true;
+
+		if ((u->insn[i] == 0x87) && (u->insn[i+1] == 0xc0))
+			return true;
+
+		break;
+	}
+
+	u->flags &= ~UPROBES_SKIP_SSTEP;
+	return false;
+}
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index cfdc6e0..31bfc69 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1283,9 +1283,9 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
 	if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr)
 		return;
 
-	vapic = kmap_atomic(vcpu->arch.apic->vapic_page, KM_USER0);
+	vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
 	data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
-	kunmap_atomic(vapic, KM_USER0);
+	kunmap_atomic(vapic);
 
 	apic_set_tpr(vcpu->arch.apic, data & 0xff);
 }
@@ -1310,9 +1310,9 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
 		max_isr = 0;
 	data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24);
 
-	vapic = kmap_atomic(vcpu->arch.apic->vapic_page, KM_USER0);
+	vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
 	*(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data;
-	kunmap_atomic(vapic, KM_USER0);
+	kunmap_atomic(vapic);
 }
 
 void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 1561028..df5a703 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -92,9 +92,9 @@ static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
 	if (unlikely(npages != 1))
 		return -EFAULT;
 
-	table = kmap_atomic(page, KM_USER0);
+	table = kmap_atomic(page);
 	ret = CMPXCHG(&table[index], orig_pte, new_pte);
-	kunmap_atomic(table, KM_USER0);
+	kunmap_atomic(table);
 
 	kvm_release_page_dirty(page);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 9cbfc06..c03283b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1162,12 +1162,12 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
 	 */
 	vcpu->hv_clock.version += 2;
 
-	shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0);
+	shared_kaddr = kmap_atomic(vcpu->time_page);
 
 	memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
 	       sizeof(vcpu->hv_clock));
 
-	kunmap_atomic(shared_kaddr, KM_USER0);
+	kunmap_atomic(shared_kaddr);
 
 	mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
 	return 0;
@@ -2997,6 +2997,8 @@ static void write_protect_slot(struct kvm *kvm,
 			       unsigned long *dirty_bitmap,
 			       unsigned long nr_dirty_pages)
 {
+	spin_lock(&kvm->mmu_lock);
+
 	/* Not many dirty pages compared to # of shadow pages. */
 	if (nr_dirty_pages < kvm->arch.n_used_mmu_pages) {
 		unsigned long gfn_offset;
@@ -3004,16 +3006,13 @@ static void write_protect_slot(struct kvm *kvm,
 		for_each_set_bit(gfn_offset, dirty_bitmap, memslot->npages) {
 			unsigned long gfn = memslot->base_gfn + gfn_offset;
 
-			spin_lock(&kvm->mmu_lock);
 			kvm_mmu_rmap_write_protect(kvm, gfn, memslot);
-			spin_unlock(&kvm->mmu_lock);
 		}
 		kvm_flush_remote_tlbs(kvm);
-	} else {
-		spin_lock(&kvm->mmu_lock);
+	} else
 		kvm_mmu_slot_remove_write_access(kvm, memslot->id);
-		spin_unlock(&kvm->mmu_lock);
-	}
+
+	spin_unlock(&kvm->mmu_lock);
 }
 
 /*
@@ -3848,7 +3847,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
 		goto emul_write;
 	}
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	kaddr += offset_in_page(gpa);
 	switch (bytes) {
 	case 1:
@@ -3866,7 +3865,7 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
 	default:
 		BUG();
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	kvm_release_page_dirty(page);
 
 	if (!exchanged)
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c
index 042f682..a0b4a35 100644
--- a/arch/x86/lib/atomic64_32.c
+++ b/arch/x86/lib/atomic64_32.c
@@ -1,59 +1,4 @@
-#include <linux/compiler.h>
-#include <linux/module.h>
-#include <linux/types.h>
+#define ATOMIC64_EXPORT EXPORT_SYMBOL
 
-#include <asm/processor.h>
-#include <asm/cmpxchg.h>
+#include <linux/export.h>
 #include <linux/atomic.h>
-
-long long atomic64_read_cx8(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_read_cx8);
-long long atomic64_set_cx8(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_set_cx8);
-long long atomic64_xchg_cx8(long long, unsigned high);
-EXPORT_SYMBOL(atomic64_xchg_cx8);
-long long atomic64_add_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_add_return_cx8);
-long long atomic64_sub_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_sub_return_cx8);
-long long atomic64_inc_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_return_cx8);
-long long atomic64_dec_return_cx8(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_return_cx8);
-long long atomic64_dec_if_positive_cx8(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_if_positive_cx8);
-int atomic64_inc_not_zero_cx8(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_not_zero_cx8);
-int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u);
-EXPORT_SYMBOL(atomic64_add_unless_cx8);
-
-#ifndef CONFIG_X86_CMPXCHG64
-long long atomic64_read_386(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_read_386);
-long long atomic64_set_386(long long, const atomic64_t *v);
-EXPORT_SYMBOL(atomic64_set_386);
-long long atomic64_xchg_386(long long, unsigned high);
-EXPORT_SYMBOL(atomic64_xchg_386);
-long long atomic64_add_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_add_return_386);
-long long atomic64_sub_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_sub_return_386);
-long long atomic64_inc_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_return_386);
-long long atomic64_dec_return_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_return_386);
-long long atomic64_add_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_add_386);
-long long atomic64_sub_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_sub_386);
-long long atomic64_inc_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_386);
-long long atomic64_dec_386(long long a, atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_386);
-long long atomic64_dec_if_positive_386(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_dec_if_positive_386);
-int atomic64_inc_not_zero_386(atomic64_t *v);
-EXPORT_SYMBOL(atomic64_inc_not_zero_386);
-int atomic64_add_unless_386(atomic64_t *v, long long a, long long u);
-EXPORT_SYMBOL(atomic64_add_unless_386);
-#endif
diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S
index e8e7e0d..00933d5 100644
--- a/arch/x86/lib/atomic64_386_32.S
+++ b/arch/x86/lib/atomic64_386_32.S
@@ -137,13 +137,13 @@ BEGIN(dec_return)
 RET_ENDP
 #undef v
 
-#define v %ecx
+#define v %esi
 BEGIN(add_unless)
-	addl %eax, %esi
+	addl %eax, %ecx
 	adcl %edx, %edi
 	addl  (v), %eax
 	adcl 4(v), %edx
-	cmpl %eax, %esi
+	cmpl %eax, %ecx
 	je 3f
 1:
 	movl %eax,  (v)
diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S
index 391a083..f5cc9eb 100644
--- a/arch/x86/lib/atomic64_cx8_32.S
+++ b/arch/x86/lib/atomic64_cx8_32.S
@@ -55,8 +55,6 @@ ENDPROC(atomic64_set_cx8)
 ENTRY(atomic64_xchg_cx8)
 	CFI_STARTPROC
 
-	movl %ebx, %eax
-	movl %ecx, %edx
 1:
 	LOCK_PREFIX
 	cmpxchg8b (%esi)
@@ -78,7 +76,7 @@ ENTRY(atomic64_\func\()_return_cx8)
 	movl %edx, %edi
 	movl %ecx, %ebp
 
-	read64 %ebp
+	read64 %ecx
 1:
 	movl %eax, %ebx
 	movl %edx, %ecx
@@ -159,23 +157,22 @@ ENTRY(atomic64_add_unless_cx8)
 	SAVE ebx
 /* these just push these two parameters on the stack */
 	SAVE edi
-	SAVE esi
+	SAVE ecx
 
-	movl %ecx, %ebp
-	movl %eax, %esi
+	movl %eax, %ebp
 	movl %edx, %edi
 
-	read64 %ebp
+	read64 %esi
 1:
 	cmpl %eax, 0(%esp)
 	je 4f
 2:
 	movl %eax, %ebx
 	movl %edx, %ecx
-	addl %esi, %ebx
+	addl %ebp, %ebx
 	adcl %edi, %ecx
 	LOCK_PREFIX
-	cmpxchg8b (%ebp)
+	cmpxchg8b (%esi)
 	jne 1b
 
 	movl $1, %eax
@@ -199,13 +196,13 @@ ENTRY(atomic64_inc_not_zero_cx8)
 
 	read64 %esi
 1:
-	testl %eax, %eax
-	je 4f
-2:
+	movl %eax, %ecx
+	orl %edx, %ecx
+	jz 3f
 	movl %eax, %ebx
-	movl %edx, %ecx
+	xorl %ecx, %ecx
 	addl $1, %ebx
-	adcl $0, %ecx
+	adcl %edx, %ecx
 	LOCK_PREFIX
 	cmpxchg8b (%esi)
 	jne 1b
@@ -214,9 +211,5 @@ ENTRY(atomic64_inc_not_zero_cx8)
 3:
 	RESTORE ebx
 	ret
-4:
-	testl %edx, %edx
-	jne 2b
-	jmp 3b
 	CFI_ENDPROC
 ENDPROC(atomic64_inc_not_zero_cx8)
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
index 01c805b..6b34d04 100644
--- a/arch/x86/lib/copy_page_64.S
+++ b/arch/x86/lib/copy_page_64.S
@@ -20,14 +20,12 @@ ENDPROC(copy_page_c)
 
 ENTRY(copy_page)
 	CFI_STARTPROC
-	subq	$3*8,%rsp
-	CFI_ADJUST_CFA_OFFSET 3*8
+	subq	$2*8,%rsp
+	CFI_ADJUST_CFA_OFFSET 2*8
 	movq	%rbx,(%rsp)
 	CFI_REL_OFFSET rbx, 0
 	movq	%r12,1*8(%rsp)
 	CFI_REL_OFFSET r12, 1*8
-	movq	%r13,2*8(%rsp)
-	CFI_REL_OFFSET r13, 2*8
 
 	movl	$(4096/64)-5,%ecx
 	.p2align 4
@@ -91,10 +89,8 @@ ENTRY(copy_page)
 	CFI_RESTORE rbx
 	movq	1*8(%rsp),%r12
 	CFI_RESTORE r12
-	movq	2*8(%rsp),%r13
-	CFI_RESTORE r13
-	addq	$3*8,%rsp
-	CFI_ADJUST_CFA_OFFSET -3*8
+	addq	$2*8,%rsp
+	CFI_ADJUST_CFA_OFFSET -2*8
 	ret
 .Lcopy_page_end:
 	CFI_ENDPROC
diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c
index 88ad5fb..c1f01a8 100644
--- a/arch/x86/lib/inat.c
+++ b/arch/x86/lib/inat.c
@@ -29,46 +29,46 @@ insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
 	return inat_primary_table[opcode];
 }
 
-insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx,
+int inat_get_last_prefix_id(insn_byte_t last_pfx)
+{
+	insn_attr_t lpfx_attr;
+
+	lpfx_attr = inat_get_opcode_attribute(last_pfx);
+	return inat_last_prefix_id(lpfx_attr);
+}
+
+insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id,
 				      insn_attr_t esc_attr)
 {
 	const insn_attr_t *table;
-	insn_attr_t lpfx_attr;
-	int n, m = 0;
+	int n;
 
 	n = inat_escape_id(esc_attr);
-	if (last_pfx) {
-		lpfx_attr = inat_get_opcode_attribute(last_pfx);
-		m = inat_last_prefix_id(lpfx_attr);
-	}
+
 	table = inat_escape_tables[n][0];
 	if (!table)
 		return 0;
-	if (inat_has_variant(table[opcode]) && m) {
-		table = inat_escape_tables[n][m];
+	if (inat_has_variant(table[opcode]) && lpfx_id) {
+		table = inat_escape_tables[n][lpfx_id];
 		if (!table)
 			return 0;
 	}
 	return table[opcode];
 }
 
-insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx,
+insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id,
 				     insn_attr_t grp_attr)
 {
 	const insn_attr_t *table;
-	insn_attr_t lpfx_attr;
-	int n, m = 0;
+	int n;
 
 	n = inat_group_id(grp_attr);
-	if (last_pfx) {
-		lpfx_attr = inat_get_opcode_attribute(last_pfx);
-		m = inat_last_prefix_id(lpfx_attr);
-	}
+
 	table = inat_group_tables[n][0];
 	if (!table)
 		return inat_group_common_attribute(grp_attr);
-	if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) {
-		table = inat_group_tables[n][m];
+	if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) {
+		table = inat_group_tables[n][lpfx_id];
 		if (!table)
 			return inat_group_common_attribute(grp_attr);
 	}
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
index 5a1f9f3..25feb1a 100644
--- a/arch/x86/lib/insn.c
+++ b/arch/x86/lib/insn.c
@@ -185,7 +185,8 @@ err_out:
 void insn_get_opcode(struct insn *insn)
 {
 	struct insn_field *opcode = &insn->opcode;
-	insn_byte_t op, pfx;
+	insn_byte_t op;
+	int pfx_id;
 	if (opcode->got)
 		return;
 	if (!insn->prefixes.got)
@@ -212,8 +213,8 @@ void insn_get_opcode(struct insn *insn)
 		/* Get escaped opcode */
 		op = get_next(insn_byte_t, insn);
 		opcode->bytes[opcode->nbytes++] = op;
-		pfx = insn_last_prefix(insn);
-		insn->attr = inat_get_escape_attribute(op, pfx, insn->attr);
+		pfx_id = insn_last_prefix_id(insn);
+		insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr);
 	}
 	if (inat_must_vex(insn->attr))
 		insn->attr = 0;	/* This instruction is bad */
@@ -235,7 +236,7 @@ err_out:
 void insn_get_modrm(struct insn *insn)
 {
 	struct insn_field *modrm = &insn->modrm;
-	insn_byte_t pfx, mod;
+	insn_byte_t pfx_id, mod;
 	if (modrm->got)
 		return;
 	if (!insn->opcode.got)
@@ -246,8 +247,8 @@ void insn_get_modrm(struct insn *insn)
 		modrm->value = mod;
 		modrm->nbytes = 1;
 		if (inat_is_group(insn->attr)) {
-			pfx = insn_last_prefix(insn);
-			insn->attr = inat_get_group_attribute(mod, pfx,
+			pfx_id = insn_last_prefix_id(insn);
+			insn->attr = inat_get_group_attribute(mod, pfx_id,
 							      insn->attr);
 			if (insn_is_avx(insn) && !inat_accept_vex(insn->attr))
 				insn->attr = 0;	/* This is bad */
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
index efbf2a0..1c273be 100644
--- a/arch/x86/lib/memcpy_64.S
+++ b/arch/x86/lib/memcpy_64.S
@@ -27,9 +27,8 @@
 	.section .altinstr_replacement, "ax", @progbits
 .Lmemcpy_c:
 	movq %rdi, %rax
-
-	movl %edx, %ecx
-	shrl $3, %ecx
+	movq %rdx, %rcx
+	shrq $3, %rcx
 	andl $7, %edx
 	rep movsq
 	movl %edx, %ecx
@@ -48,8 +47,7 @@
 	.section .altinstr_replacement, "ax", @progbits
 .Lmemcpy_c_e:
 	movq %rdi, %rax
-
-	movl %edx, %ecx
+	movq %rdx, %rcx
 	rep movsb
 	ret
 .Lmemcpy_e_e:
@@ -60,10 +58,7 @@ ENTRY(memcpy)
 	CFI_STARTPROC
 	movq %rdi, %rax
 
-	/*
-	 * Use 32bit CMP here to avoid long NOP padding.
-	 */
-	cmp  $0x20, %edx
+	cmpq $0x20, %rdx
 	jb .Lhandle_tail
 
 	/*
@@ -72,7 +67,7 @@ ENTRY(memcpy)
 	 */
 	cmp  %dil, %sil
 	jl .Lcopy_backward
-	subl $0x20, %edx
+	subq $0x20, %rdx
 .Lcopy_forward_loop:
 	subq $0x20,	%rdx
 
@@ -91,7 +86,7 @@ ENTRY(memcpy)
 	movq %r11,	3*8(%rdi)
 	leaq 4*8(%rdi),	%rdi
 	jae  .Lcopy_forward_loop
-	addq $0x20,	%rdx
+	addl $0x20,	%edx
 	jmp  .Lhandle_tail
 
 .Lcopy_backward:
@@ -123,11 +118,11 @@ ENTRY(memcpy)
 	/*
 	 * Calculate copy position to head.
 	 */
-	addq $0x20,	%rdx
+	addl $0x20,	%edx
 	subq %rdx,	%rsi
 	subq %rdx,	%rdi
 .Lhandle_tail:
-	cmpq $16,	%rdx
+	cmpl $16,	%edx
 	jb   .Lless_16bytes
 
 	/*
@@ -144,7 +139,7 @@ ENTRY(memcpy)
 	retq
 	.p2align 4
 .Lless_16bytes:
-	cmpq $8,	%rdx
+	cmpl $8,	%edx
 	jb   .Lless_8bytes
 	/*
 	 * Move data from 8 bytes to 15 bytes.
@@ -156,7 +151,7 @@ ENTRY(memcpy)
 	retq
 	.p2align 4
 .Lless_8bytes:
-	cmpq $4,	%rdx
+	cmpl $4,	%edx
 	jb   .Lless_3bytes
 
 	/*
@@ -169,18 +164,19 @@ ENTRY(memcpy)
 	retq
 	.p2align 4
 .Lless_3bytes:
-	cmpl $0, %edx
-	je .Lend
+	subl $1, %edx
+	jb .Lend
 	/*
 	 * Move data from 1 bytes to 3 bytes.
 	 */
-.Lloop_1:
-	movb (%rsi), %r8b
-	movb %r8b, (%rdi)
-	incq %rdi
-	incq %rsi
-	decl %edx
-	jnz .Lloop_1
+	movzbl (%rsi), %ecx
+	jz .Lstore_1byte
+	movzbq 1(%rsi), %r8
+	movzbq (%rsi, %rdx), %r9
+	movb %r8b, 1(%rdi)
+	movb %r9b, (%rdi, %rdx)
+.Lstore_1byte:
+	movb %cl, (%rdi)
 
 .Lend:
 	retq
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
index 79bd454..2dcb380 100644
--- a/arch/x86/lib/memset_64.S
+++ b/arch/x86/lib/memset_64.S
@@ -19,16 +19,15 @@
 	.section .altinstr_replacement, "ax", @progbits
 .Lmemset_c:
 	movq %rdi,%r9
-	movl %edx,%r8d
-	andl $7,%r8d
-	movl %edx,%ecx
-	shrl $3,%ecx
+	movq %rdx,%rcx
+	andl $7,%edx
+	shrq $3,%rcx
 	/* expand byte value  */
 	movzbl %sil,%esi
 	movabs $0x0101010101010101,%rax
-	mulq %rsi		/* with rax, clobbers rdx */
+	imulq %rsi,%rax
 	rep stosq
-	movl %r8d,%ecx
+	movl %edx,%ecx
 	rep stosb
 	movq %r9,%rax
 	ret
@@ -50,7 +49,7 @@
 .Lmemset_c_e:
 	movq %rdi,%r9
 	movb %sil,%al
-	movl %edx,%ecx
+	movq %rdx,%rcx
 	rep stosb
 	movq %r9,%rax
 	ret
@@ -61,12 +60,11 @@ ENTRY(memset)
 ENTRY(__memset)
 	CFI_STARTPROC
 	movq %rdi,%r10
-	movq %rdx,%r11
 
 	/* expand byte value  */
 	movzbl %sil,%ecx
 	movabs $0x0101010101010101,%rax
-	mul    %rcx		/* with rax, clobbers rdx */
+	imulq  %rcx,%rax
 
 	/* align dst */
 	movl  %edi,%r9d
@@ -75,13 +73,13 @@ ENTRY(__memset)
 	CFI_REMEMBER_STATE
 .Lafter_bad_alignment:
 
-	movl %r11d,%ecx
-	shrl $6,%ecx
+	movq  %rdx,%rcx
+	shrq  $6,%rcx
 	jz	 .Lhandle_tail
 
 	.p2align 4
 .Lloop_64:
-	decl   %ecx
+	decq  %rcx
 	movq  %rax,(%rdi)
 	movq  %rax,8(%rdi)
 	movq  %rax,16(%rdi)
@@ -97,7 +95,7 @@ ENTRY(__memset)
 	   to predict jump tables. */
 	.p2align 4
 .Lhandle_tail:
-	movl	%r11d,%ecx
+	movl	%edx,%ecx
 	andl    $63&(~7),%ecx
 	jz 		.Lhandle_7
 	shrl	$3,%ecx
@@ -109,12 +107,11 @@ ENTRY(__memset)
 	jnz    .Lloop_8
 
 .Lhandle_7:
-	movl	%r11d,%ecx
-	andl	$7,%ecx
+	andl	$7,%edx
 	jz      .Lende
 	.p2align 4
 .Lloop_1:
-	decl    %ecx
+	decl    %edx
 	movb 	%al,(%rdi)
 	leaq	1(%rdi),%rdi
 	jnz     .Lloop_1
@@ -125,13 +122,13 @@ ENTRY(__memset)
 
 	CFI_RESTORE_STATE
 .Lbad_alignment:
-	cmpq $7,%r11
+	cmpq $7,%rdx
 	jbe	.Lhandle_7
 	movq %rax,(%rdi)	/* unaligned store */
 	movq $8,%r8
 	subq %r9,%r8
 	addq %r8,%rdi
-	subq %r8,%r11
+	subq %r8,%rdx
 	jmp .Lafter_bad_alignment
 .Lfinal:
 	CFI_ENDPROC
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index e218d5d..d9b094c 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -760,9 +760,9 @@ survive:
 				break;
 			}
 
-			maddr = kmap_atomic(pg, KM_USER0);
+			maddr = kmap_atomic(pg);
 			memcpy(maddr + offset, from, len);
-			kunmap_atomic(maddr, KM_USER0);
+			kunmap_atomic(maddr);
 			set_page_dirty_lock(pg);
 			put_page(pg);
 			up_read(&current->mm->mmap_sem);
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index f4f29b1..6f31ee5 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -51,11 +51,11 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
 }
 EXPORT_SYMBOL(kmap_atomic_prot);
 
-void *__kmap_atomic(struct page *page)
+void *kmap_atomic(struct page *page)
 {
 	return kmap_atomic_prot(page, kmap_prot);
 }
-EXPORT_SYMBOL(__kmap_atomic);
+EXPORT_SYMBOL(kmap_atomic);
 
 /*
  * This is the same as kmap_atomic() but can map memory that doesn't
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index f581a18..09a35ee 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -308,10 +308,11 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
 {
 	struct hstate *h = hstate_file(file);
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma, *prev_vma;
-	unsigned long base = mm->mmap_base, addr = addr0;
+	struct vm_area_struct *vma;
+	unsigned long base = mm->mmap_base;
+	unsigned long addr = addr0;
+	unsigned long start_addr;
 	unsigned long largest_hole = mm->cached_hole_size;
-	int first_time = 1;
 
 	/* don't allow allocations above current base */
 	if (mm->free_area_cache > base)
@@ -322,6 +323,8 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
 		mm->free_area_cache  = base;
 	}
 try_again:
+	start_addr = mm->free_area_cache;
+
 	/* make sure it can fit in the remaining address space */
 	if (mm->free_area_cache < len)
 		goto fail;
@@ -333,24 +336,15 @@ try_again:
 		 * Lookup failure means no vma is above this address,
 		 * i.e. return with success:
 		 */
-		if (!(vma = find_vma_prev(mm, addr, &prev_vma)))
-			return addr;
-
-		/*
-		 * new region fits between prev_vma->vm_end and
-		 * vma->vm_start, use it:
-		 */
-		if (addr + len <= vma->vm_start &&
-		            (!prev_vma || (addr >= prev_vma->vm_end))) {
+		vma = find_vma(mm, addr);
+		if (!vma || addr + len <= vma->vm_start) {
 			/* remember the address as a hint for next time */
 		        mm->cached_hole_size = largest_hole;
 		        return (mm->free_area_cache = addr);
-		} else {
+		} else if (mm->free_area_cache == vma->vm_end) {
 			/* pull free_area_cache down to the first hole */
-		        if (mm->free_area_cache == vma->vm_end) {
-				mm->free_area_cache = vma->vm_start;
-				mm->cached_hole_size = largest_hole;
-			}
+			mm->free_area_cache = vma->vm_start;
+			mm->cached_hole_size = largest_hole;
 		}
 
 		/* remember the largest hole we saw so far */
@@ -366,10 +360,9 @@ fail:
 	 * if hint left us with no space for the requested
 	 * mapping then try again:
 	 */
-	if (first_time) {
+	if (start_addr != base) {
 		mm->free_area_cache = base;
 		largest_hole = 0;
-		first_time = 0;
 		goto try_again;
 	}
 	/*
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 6cabf65..2e92fdc 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -30,8 +30,14 @@ int direct_gbpages
 #endif
 ;
 
-static void __init find_early_table_space(unsigned long end, int use_pse,
-					  int use_gbpages)
+struct map_range {
+	unsigned long start;
+	unsigned long end;
+	unsigned page_size_mask;
+};
+
+static void __init find_early_table_space(struct map_range *mr, unsigned long end,
+					  int use_pse, int use_gbpages)
 {
 	unsigned long puds, pmds, ptes, tables, start = 0, good_end = end;
 	phys_addr_t base;
@@ -56,6 +62,9 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
 #ifdef CONFIG_X86_32
 		extra += PMD_SIZE;
 #endif
+		/* The first 2/4M doesn't use large pages. */
+		extra += mr->end - mr->start;
+
 		ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	} else
 		ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -85,12 +94,6 @@ void __init native_pagetable_reserve(u64 start, u64 end)
 	memblock_reserve(start, end - start);
 }
 
-struct map_range {
-	unsigned long start;
-	unsigned long end;
-	unsigned page_size_mask;
-};
-
 #ifdef CONFIG_X86_32
 #define NR_RANGE_MR 3
 #else /* CONFIG_X86_64 */
@@ -262,7 +265,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
 	 * nodes are discovered.
 	 */
 	if (!after_bootmem)
-		find_early_table_space(end, use_pse, use_gbpages);
+		find_early_table_space(&mr[0], end, use_pse, use_gbpages);
 
 	for (i = 0; i < nr_range; i++)
 		ret = kernel_physical_mapping_init(mr[i].start, mr[i].end,
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index d6c0418..e931db0 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -61,10 +61,10 @@ static DEFINE_PER_CPU_READ_MOSTLY(int, tlb_vector_offset);
  */
 void leave_mm(int cpu)
 {
-	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+	if (__this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
 		BUG();
 	cpumask_clear_cpu(cpu,
-			  mm_cpumask(percpu_read(cpu_tlbstate.active_mm)));
+			  mm_cpumask(__this_cpu_read(cpu_tlbstate.active_mm)));
 	load_cr3(swapper_pg_dir);
 }
 EXPORT_SYMBOL_GPL(leave_mm);
@@ -152,8 +152,8 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
 		 * BUG();
 		 */
 
-	if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) {
-		if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
+	if (f->flush_mm == __this_cpu_read(cpu_tlbstate.active_mm)) {
+		if (__this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
 			if (f->flush_va == TLB_FLUSH_ALL)
 				local_flush_tlb();
 			else
@@ -322,7 +322,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
 static void do_flush_tlb_all(void *info)
 {
 	__flush_tlb_all();
-	if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY)
+	if (__this_cpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY)
 		leave_mm(smp_processor_id());
 }
 
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index a312e76..daa4249 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -404,7 +404,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
 		kfree(sd);
 	} else {
 		get_current_resources(device, busnum, domain, &resources);
-		if (list_empty(&resources))
+
+		/*
+		 * _CRS with no apertures is normal, so only fall back to
+		 * defaults or native bridge info if we're ignoring _CRS.
+		 */
+		if (!pci_use_crs)
 			x86_pci_root_bus_resources(busnum, &resources);
 		bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
 					  &resources);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 91821a1..33e6a0b 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -39,6 +39,85 @@
 #include <asm/io_apic.h>
 
 
+/*
+ * This list of dynamic mappings is for temporarily maintaining
+ * original BIOS BAR addresses for possible reinstatement.
+ */
+struct pcibios_fwaddrmap {
+	struct list_head list;
+	struct pci_dev *dev;
+	resource_size_t fw_addr[DEVICE_COUNT_RESOURCE];
+};
+
+static LIST_HEAD(pcibios_fwaddrmappings);
+static DEFINE_SPINLOCK(pcibios_fwaddrmap_lock);
+
+/* Must be called with 'pcibios_fwaddrmap_lock' lock held. */
+static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev)
+{
+	struct pcibios_fwaddrmap *map;
+
+	list_for_each_entry(map, &pcibios_fwaddrmappings, list)
+		if (map->dev == dev)
+			return map;
+
+	return NULL;
+}
+
+static void
+pcibios_save_fw_addr(struct pci_dev *dev, int idx, resource_size_t fw_addr)
+{
+	unsigned long flags;
+	struct pcibios_fwaddrmap *map;
+
+	spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
+	map = pcibios_fwaddrmap_lookup(dev);
+	if (!map) {
+		spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
+		map = kzalloc(sizeof(*map), GFP_KERNEL);
+		if (!map)
+			return;
+
+		map->dev = pci_dev_get(dev);
+		map->fw_addr[idx] = fw_addr;
+		INIT_LIST_HEAD(&map->list);
+
+		spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
+		list_add_tail(&map->list, &pcibios_fwaddrmappings);
+	} else
+		map->fw_addr[idx] = fw_addr;
+	spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
+}
+
+resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
+{
+	unsigned long flags;
+	struct pcibios_fwaddrmap *map;
+	resource_size_t fw_addr = 0;
+
+	spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
+	map = pcibios_fwaddrmap_lookup(dev);
+	if (map)
+		fw_addr = map->fw_addr[idx];
+	spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
+
+	return fw_addr;
+}
+
+static void pcibios_fw_addr_list_del(void)
+{
+	unsigned long flags;
+	struct pcibios_fwaddrmap *entry, *next;
+
+	spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags);
+	list_for_each_entry_safe(entry, next, &pcibios_fwaddrmappings, list) {
+		list_del(&entry->list);
+		pci_dev_put(entry->dev);
+		kfree(entry);
+	}
+	spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags);
+}
+
 static int
 skip_isa_ioresource_align(struct pci_dev *dev) {
 
@@ -182,7 +261,8 @@ static void __init pcibios_allocate_resources(int pass)
 					idx, r, disabled, pass);
 				if (pci_claim_resource(dev, idx) < 0) {
 					/* We'll assign a new address later */
-					dev->fw_addr[idx] = r->start;
+					pcibios_save_fw_addr(dev,
+							idx, r->start);
 					r->end -= r->start;
 					r->start = 0;
 				}
@@ -228,6 +308,7 @@ static int __init pcibios_assign_resources(void)
 	}
 
 	pci_assign_unassigned_resources();
+	pcibios_fw_addr_list_del();
 
 	return 0;
 }
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index d99346e..7415aa9 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -324,6 +324,32 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 out:
 	return ret;
 }
+
+static void xen_initdom_restore_msi_irqs(struct pci_dev *dev, int irq)
+{
+	int ret = 0;
+
+	if (pci_seg_supported) {
+		struct physdev_pci_device restore_ext;
+
+		restore_ext.seg = pci_domain_nr(dev->bus);
+		restore_ext.bus = dev->bus->number;
+		restore_ext.devfn = dev->devfn;
+		ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi_ext,
+					&restore_ext);
+		if (ret == -ENOSYS)
+			pci_seg_supported = false;
+		WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret);
+	}
+	if (!pci_seg_supported) {
+		struct physdev_restore_msi restore;
+
+		restore.bus = dev->bus->number;
+		restore.devfn = dev->devfn;
+		ret = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi, &restore);
+		WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret);
+	}
+}
 #endif
 
 static void xen_teardown_msi_irqs(struct pci_dev *dev)
@@ -446,6 +472,7 @@ int __init pci_xen_initial_domain(void)
 #ifdef CONFIG_PCI_MSI
 	x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
 	x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+	x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
 #endif
 	xen_setup_acpi_sci();
 	__acpi_register_gsi = acpi_register_gsi_xen;
diff --git a/arch/x86/platform/ce4100/falconfalls.dts b/arch/x86/platform/ce4100/falconfalls.dts
index e70be38..ce874f8 100644
--- a/arch/x86/platform/ce4100/falconfalls.dts
+++ b/arch/x86/platform/ce4100/falconfalls.dts
@@ -208,16 +208,19 @@
 					interrupts = <14 1>;
 				};
 
-				gpio@b,1 {
+				pcigpio: gpio@b,1 {
+					#gpio-cells = <2>;
+					#interrupt-cells = <2>;
 					compatible = "pci8086,2e67.2",
 						   "pci8086,2e67",
 						   "pciclassff0000",
 						   "pciclassff00";
 
-					#gpio-cells = <2>;
 					reg = <0x15900 0x0 0x0 0x0 0x0>;
 					interrupts = <15 1>;
+					interrupt-controller;
 					gpio-controller;
+					intel,muxctl = <0>;
 				};
 
 				i2c-controller@b,2 {
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 4cf9bd0..264cc6e 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -324,13 +324,20 @@ static void __init do_add_efi_memmap(void)
 		case EFI_UNUSABLE_MEMORY:
 			e820_type = E820_UNUSABLE;
 			break;
+		case EFI_MEMORY_MAPPED_IO:
+		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+			e820_type = E820_RESERVED;
+			break;
 		default:
 			/*
 			 * EFI_RESERVED_TYPE EFI_RUNTIME_SERVICES_CODE
-			 * EFI_RUNTIME_SERVICES_DATA EFI_MEMORY_MAPPED_IO
-			 * EFI_MEMORY_MAPPED_IO_PORT_SPACE EFI_PAL_CODE
+			 * EFI_RUNTIME_SERVICES_DATA
+			 * EFI_PAL_CODE
 			 */
-			e820_type = E820_RESERVED;
+			if (md->attribute & EFI_MEMORY_RUNTIME)
+				e820_type = E820_RESERVED_EFI;
+			else
+				e820_type = E820_RESERVED;
 			break;
 		}
 		e820_add_region(start, size, e820_type);
@@ -669,10 +676,21 @@ void __init efi_enter_virtual_mode(void)
 		end_pfn = PFN_UP(end);
 		if (end_pfn <= max_low_pfn_mapped
 		    || (end_pfn > (1UL << (32 - PAGE_SHIFT))
-			&& end_pfn <= max_pfn_mapped))
+			&& end_pfn <= max_pfn_mapped)) {
 			va = __va(md->phys_addr);
-		else
-			va = efi_ioremap(md->phys_addr, size, md->type);
+
+			if (!(md->attribute & EFI_MEMORY_WB)) {
+				addr = (u64) (unsigned long)va;
+				npages = md->num_pages;
+				memrange_efi_to_native(&addr, &npages);
+				set_memory_uc(addr, npages);
+			}
+		} else {
+			if (!(md->attribute & EFI_MEMORY_WB))
+				va = ioremap_nocache(md->phys_addr, size);
+			else
+				va = ioremap_cache(md->phys_addr, size);
+		}
 
 		md->virt_addr = (u64) (unsigned long) va;
 
@@ -682,13 +700,6 @@ void __init efi_enter_virtual_mode(void)
 			continue;
 		}
 
-		if (!(md->attribute & EFI_MEMORY_WB)) {
-			addr = md->virt_addr;
-			npages = md->num_pages;
-			memrange_efi_to_native(&addr, &npages);
-			set_memory_uc(addr, npages);
-		}
-
 		systab = (u64) (unsigned long) efi_phys.systab;
 		if (md->phys_addr <= systab && systab < end) {
 			systab += md->virt_addr - md->phys_addr;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index ac3aa54..312250c 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -80,20 +80,3 @@ void __init efi_call_phys_epilog(void)
 	local_irq_restore(efi_flags);
 	early_code_mapping_set_exec(0);
 }
-
-void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
-				 u32 type)
-{
-	unsigned long last_map_pfn;
-
-	if (type == EFI_MEMORY_MAPPED_IO)
-		return ioremap(phys_addr, size);
-
-	last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size);
-	if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) {
-		unsigned long top = last_map_pfn << PAGE_SHIFT;
-		efi_ioremap(top, size - (top - phys_addr), type);
-	}
-
-	return (void __iomem *)__va(phys_addr);
-}
diff --git a/arch/x86/platform/geode/Makefile b/arch/x86/platform/geode/Makefile
index 07c9cd0..5b51194 100644
--- a/arch/x86/platform/geode/Makefile
+++ b/arch/x86/platform/geode/Makefile
@@ -1 +1,3 @@
 obj-$(CONFIG_ALIX)		+= alix.o
+obj-$(CONFIG_NET5501)		+= net5501.o
+obj-$(CONFIG_GEOS)		+= geos.o
diff --git a/arch/x86/platform/geode/alix.c b/arch/x86/platform/geode/alix.c
index dc5f1d3..b506b79 100644
--- a/arch/x86/platform/geode/alix.c
+++ b/arch/x86/platform/geode/alix.c
@@ -6,6 +6,7 @@
  *
  * Copyright (C) 2008 Constantin Baranov <const@mimas.ru>
  * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com>
+ *                and Philip Prindeville <philipp@redfish-solutions.com>
  *
  * TODO: There are large similarities with leds-net5501.c
  * by Alessandro Zummo <a.zummo@towertech.it>
@@ -24,14 +25,47 @@
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/dmi.h>
 
 #include <asm/geode.h>
 
+#define BIOS_SIGNATURE_TINYBIOS		0xf0000
+#define BIOS_SIGNATURE_COREBOOT		0x500
+#define BIOS_REGION_SIZE		0x10000
+
 static bool force = 0;
 module_param(force, bool, 0444);
 /* FIXME: Award bios is not automatically detected as Alix platform */
 MODULE_PARM_DESC(force, "Force detection as ALIX.2/ALIX.3 platform");
 
+static struct gpio_keys_button alix_gpio_buttons[] = {
+	{
+		.code = KEY_RESTART,
+		.gpio = 24,
+		.active_low = 1,
+		.desc = "Reset button",
+		.type = EV_KEY,
+		.wakeup = 0,
+		.debounce_interval = 100,
+		.can_disable = 0,
+	}
+};
+static struct gpio_keys_platform_data alix_buttons_data = {
+	.buttons = alix_gpio_buttons,
+	.nbuttons = ARRAY_SIZE(alix_gpio_buttons),
+	.poll_interval = 20,
+};
+
+static struct platform_device alix_buttons_dev = {
+	.name = "gpio-keys-polled",
+	.id = 1,
+	.dev = {
+		.platform_data = &alix_buttons_data,
+	}
+};
+
 static struct gpio_led alix_leds[] = {
 	{
 		.name = "alix:1",
@@ -64,17 +98,22 @@ static struct platform_device alix_leds_dev = {
 	.dev.platform_data = &alix_leds_data,
 };
 
+static struct __initdata platform_device *alix_devs[] = {
+	&alix_buttons_dev,
+	&alix_leds_dev,
+};
+
 static void __init register_alix(void)
 {
 	/* Setup LED control through leds-gpio driver */
-	platform_device_register(&alix_leds_dev);
+	platform_add_devices(alix_devs, ARRAY_SIZE(alix_devs));
 }
 
-static int __init alix_present(unsigned long bios_phys,
+static bool __init alix_present(unsigned long bios_phys,
 				const char *alix_sig,
 				size_t alix_sig_len)
 {
-	const size_t bios_len = 0x00010000;
+	const size_t bios_len = BIOS_REGION_SIZE;
 	const char *bios_virt;
 	const char *scan_end;
 	const char *p;
@@ -84,7 +123,7 @@ static int __init alix_present(unsigned long bios_phys,
 		printk(KERN_NOTICE "%s: forced to skip BIOS test, "
 		       "assume system is ALIX.2/ALIX.3\n",
 		       KBUILD_MODNAME);
-		return 1;
+		return true;
 	}
 
 	bios_virt = phys_to_virt(bios_phys);
@@ -109,15 +148,33 @@ static int __init alix_present(unsigned long bios_phys,
 			*a = '\0';
 
 		tail = p + alix_sig_len;
-		if ((tail[0] == '2' || tail[0] == '3')) {
+		if ((tail[0] == '2' || tail[0] == '3' || tail[0] == '6')) {
 			printk(KERN_INFO
 			       "%s: system is recognized as \"%s\"\n",
 			       KBUILD_MODNAME, name);
-			return 1;
+			return true;
 		}
 	}
 
-	return 0;
+	return false;
+}
+
+static bool __init alix_present_dmi(void)
+{
+	const char *vendor, *product;
+
+	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+	if (!vendor || strcmp(vendor, "PC Engines"))
+		return false;
+
+	product = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!product || (strcmp(product, "ALIX.2D") && strcmp(product, "ALIX.6")))
+		return false;
+
+	printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n",
+	       KBUILD_MODNAME, vendor, product);
+
+	return true;
 }
 
 static int __init alix_init(void)
@@ -128,8 +185,9 @@ static int __init alix_init(void)
 	if (!is_geode())
 		return 0;
 
-	if (alix_present(0xf0000, tinybios_sig, sizeof(tinybios_sig) - 1) ||
-	    alix_present(0x500, coreboot_sig, sizeof(coreboot_sig) - 1))
+	if (alix_present(BIOS_SIGNATURE_TINYBIOS, tinybios_sig, sizeof(tinybios_sig) - 1) ||
+	    alix_present(BIOS_SIGNATURE_COREBOOT, coreboot_sig, sizeof(coreboot_sig) - 1) ||
+	    alix_present_dmi())
 		register_alix();
 
 	return 0;
diff --git a/arch/x86/platform/geode/geos.c b/arch/x86/platform/geode/geos.c
new file mode 100644
index 0000000..c2e6d53
--- /dev/null
+++ b/arch/x86/platform/geode/geos.c
@@ -0,0 +1,128 @@
+/*
+ * System Specific setup for Traverse Technologies GEOS.
+ * At the moment this means setup of GPIO control of LEDs.
+ *
+ * Copyright (C) 2008 Constantin Baranov <const@mimas.ru>
+ * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com>
+ *                and Philip Prindeville <philipp@redfish-solutions.com>
+ *
+ * TODO: There are large similarities with leds-net5501.c
+ * by Alessandro Zummo <a.zummo@towertech.it>
+ * In the future leds-net5501.c should be migrated over to platform
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/dmi.h>
+
+#include <asm/geode.h>
+
+static struct gpio_keys_button geos_gpio_buttons[] = {
+	{
+		.code = KEY_RESTART,
+		.gpio = 3,
+		.active_low = 1,
+		.desc = "Reset button",
+		.type = EV_KEY,
+		.wakeup = 0,
+		.debounce_interval = 100,
+		.can_disable = 0,
+	}
+};
+static struct gpio_keys_platform_data geos_buttons_data = {
+	.buttons = geos_gpio_buttons,
+	.nbuttons = ARRAY_SIZE(geos_gpio_buttons),
+	.poll_interval = 20,
+};
+
+static struct platform_device geos_buttons_dev = {
+	.name = "gpio-keys-polled",
+	.id = 1,
+	.dev = {
+		.platform_data = &geos_buttons_data,
+	}
+};
+
+static struct gpio_led geos_leds[] = {
+	{
+		.name = "geos:1",
+		.gpio = 6,
+		.default_trigger = "default-on",
+		.active_low = 1,
+	},
+	{
+		.name = "geos:2",
+		.gpio = 25,
+		.default_trigger = "default-off",
+		.active_low = 1,
+	},
+	{
+		.name = "geos:3",
+		.gpio = 27,
+		.default_trigger = "default-off",
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data geos_leds_data = {
+	.num_leds = ARRAY_SIZE(geos_leds),
+	.leds = geos_leds,
+};
+
+static struct platform_device geos_leds_dev = {
+	.name = "leds-gpio",
+	.id = -1,
+	.dev.platform_data = &geos_leds_data,
+};
+
+static struct __initdata platform_device *geos_devs[] = {
+	&geos_buttons_dev,
+	&geos_leds_dev,
+};
+
+static void __init register_geos(void)
+{
+	/* Setup LED control through leds-gpio driver */
+	platform_add_devices(geos_devs, ARRAY_SIZE(geos_devs));
+}
+
+static int __init geos_init(void)
+{
+	const char *vendor, *product;
+
+	if (!is_geode())
+		return 0;
+
+	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+	if (!vendor || strcmp(vendor, "Traverse Technologies"))
+		return 0;
+
+	product = dmi_get_system_info(DMI_PRODUCT_NAME);
+	if (!product || strcmp(product, "Geos"))
+		return 0;
+
+	printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n",
+	       KBUILD_MODNAME, vendor, product);
+
+	register_geos();
+
+	return 0;
+}
+
+module_init(geos_init);
+
+MODULE_AUTHOR("Philip Prindeville <philipp@redfish-solutions.com>");
+MODULE_DESCRIPTION("Traverse Technologies Geos System Setup");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/platform/geode/net5501.c b/arch/x86/platform/geode/net5501.c
new file mode 100644
index 0000000..66d377e
--- /dev/null
+++ b/arch/x86/platform/geode/net5501.c
@@ -0,0 +1,154 @@
+/*
+ * System Specific setup for Soekris net5501
+ * At the moment this means setup of GPIO control of LEDs and buttons
+ * on net5501 boards.
+ *
+ *
+ * Copyright (C) 2008-2009 Tower Technologies
+ * Written by Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * Copyright (C) 2008 Constantin Baranov <const@mimas.ru>
+ * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com>
+ *                and Philip Prindeville <philipp@redfish-solutions.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/geode.h>
+
+#define BIOS_REGION_BASE		0xffff0000
+#define BIOS_REGION_SIZE		0x00010000
+
+static struct gpio_keys_button net5501_gpio_buttons[] = {
+	{
+		.code = KEY_RESTART,
+		.gpio = 24,
+		.active_low = 1,
+		.desc = "Reset button",
+		.type = EV_KEY,
+		.wakeup = 0,
+		.debounce_interval = 100,
+		.can_disable = 0,
+	}
+};
+static struct gpio_keys_platform_data net5501_buttons_data = {
+	.buttons = net5501_gpio_buttons,
+	.nbuttons = ARRAY_SIZE(net5501_gpio_buttons),
+	.poll_interval = 20,
+};
+
+static struct platform_device net5501_buttons_dev = {
+	.name = "gpio-keys-polled",
+	.id = 1,
+	.dev = {
+		.platform_data = &net5501_buttons_data,
+	}
+};
+
+static struct gpio_led net5501_leds[] = {
+	{
+		.name = "net5501:1",
+		.gpio = 6,
+		.default_trigger = "default-on",
+		.active_low = 1,
+	},
+};
+
+static struct gpio_led_platform_data net5501_leds_data = {
+	.num_leds = ARRAY_SIZE(net5501_leds),
+	.leds = net5501_leds,
+};
+
+static struct platform_device net5501_leds_dev = {
+	.name = "leds-gpio",
+	.id = -1,
+	.dev.platform_data = &net5501_leds_data,
+};
+
+static struct __initdata platform_device *net5501_devs[] = {
+	&net5501_buttons_dev,
+	&net5501_leds_dev,
+};
+
+static void __init register_net5501(void)
+{
+	/* Setup LED control through leds-gpio driver */
+	platform_add_devices(net5501_devs, ARRAY_SIZE(net5501_devs));
+}
+
+struct net5501_board {
+	u16	offset;
+	u16	len;
+	char	*sig;
+};
+
+static struct net5501_board __initdata boards[] = {
+	{ 0xb7b, 7, "net5501" },	/* net5501 v1.33/1.33c */
+	{ 0xb1f, 7, "net5501" },	/* net5501 v1.32i */
+};
+
+static bool __init net5501_present(void)
+{
+	int i;
+	unsigned char *rombase, *bios;
+	bool found = false;
+
+	rombase = ioremap(BIOS_REGION_BASE, BIOS_REGION_SIZE - 1);
+	if (!rombase) {
+		printk(KERN_ERR "%s: failed to get rombase\n", KBUILD_MODNAME);
+		return found;
+	}
+
+	bios = rombase + 0x20;	/* null terminated */
+
+	if (memcmp(bios, "comBIOS", 7))
+		goto unmap;
+
+	for (i = 0; i < ARRAY_SIZE(boards); i++) {
+		unsigned char *model = rombase + boards[i].offset;
+
+		if (!memcmp(model, boards[i].sig, boards[i].len)) {
+			printk(KERN_INFO "%s: system is recognized as \"%s\"\n",
+			       KBUILD_MODNAME, model);
+
+			found = true;
+			break;
+		}
+	}
+
+unmap:
+	iounmap(rombase);
+	return found;
+}
+
+static int __init net5501_init(void)
+{
+	if (!is_geode())
+		return 0;
+
+	if (!net5501_present())
+		return 0;
+
+	register_net5501();
+
+	return 0;
+}
+
+module_init(net5501_init);
+
+MODULE_AUTHOR("Philip Prindeville <philipp@redfish-solutions.com>");
+MODULE_DESCRIPTION("Soekris net5501 System Setup");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/platform/iris/iris.c b/arch/x86/platform/iris/iris.c
index 5917eb5..e6cb80f 100644
--- a/arch/x86/platform/iris/iris.c
+++ b/arch/x86/platform/iris/iris.c
@@ -23,6 +23,7 @@
 
 #include <linux/moduleparam.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
@@ -62,29 +63,75 @@ static void iris_power_off(void)
  * by reading its input port and seeing whether the read value is
  * meaningful.
  */
-static int iris_init(void)
+static int iris_probe(struct platform_device *pdev)
 {
-	unsigned char status;
-	if (force != 1) {
-		printk(KERN_ERR "The force parameter has not been set to 1 so the Iris poweroff handler will not be installed.\n");
-		return -ENODEV;
-	}
-	status = inb(IRIS_GIO_INPUT);
+	unsigned char status = inb(IRIS_GIO_INPUT);
 	if (status == IRIS_GIO_NODEV) {
-		printk(KERN_ERR "This machine does not seem to be an Iris. Power_off handler not installed.\n");
+		printk(KERN_ERR "This machine does not seem to be an Iris. "
+			"Power off handler not installed.\n");
 		return -ENODEV;
 	}
 	old_pm_power_off = pm_power_off;
 	pm_power_off = &iris_power_off;
 	printk(KERN_INFO "Iris power_off handler installed.\n");
-
 	return 0;
 }
 
-static void iris_exit(void)
+static int iris_remove(struct platform_device *pdev)
 {
 	pm_power_off = old_pm_power_off;
 	printk(KERN_INFO "Iris power_off handler uninstalled.\n");
+	return 0;
+}
+
+static struct platform_driver iris_driver = {
+	.driver		= {
+		.name   = "iris",
+		.owner  = THIS_MODULE,
+	},
+	.probe          = iris_probe,
+	.remove         = iris_remove,
+};
+
+static struct resource iris_resources[] = {
+	{
+		.start  = IRIS_GIO_BASE,
+		.end    = IRIS_GIO_OUTPUT,
+		.flags  = IORESOURCE_IO,
+		.name   = "address"
+	}
+};
+
+static struct platform_device *iris_device;
+
+static int iris_init(void)
+{
+	int ret;
+	if (force != 1) {
+		printk(KERN_ERR "The force parameter has not been set to 1."
+			" The Iris poweroff handler will not be installed.\n");
+		return -ENODEV;
+	}
+	ret = platform_driver_register(&iris_driver);
+	if (ret < 0) {
+		printk(KERN_ERR "Failed to register iris platform driver: %d\n",
+			ret);
+		return ret;
+	}
+	iris_device = platform_device_register_simple("iris", (-1),
+				iris_resources, ARRAY_SIZE(iris_resources));
+	if (IS_ERR(iris_device)) {
+		printk(KERN_ERR "Failed to register iris platform device\n");
+		platform_driver_unregister(&iris_driver);
+		return PTR_ERR(iris_device);
+	}
+	return 0;
+}
+
+static void iris_exit(void)
+{
+	platform_device_unregister(iris_device);
+	platform_driver_unregister(&iris_driver);
 }
 
 module_init(iris_init);
diff --git a/arch/x86/platform/mrst/Makefile b/arch/x86/platform/mrst/Makefile
index 7baed51..af1da7e 100644
--- a/arch/x86/platform/mrst/Makefile
+++ b/arch/x86/platform/mrst/Makefile
@@ -1,4 +1,3 @@
 obj-$(CONFIG_X86_INTEL_MID)	+= mrst.o
 obj-$(CONFIG_X86_INTEL_MID)	+= vrtc.o
 obj-$(CONFIG_EARLY_PRINTK_INTEL_MID)	+= early_printk_mrst.o
-obj-$(CONFIG_X86_MRST)		+= pmu.o
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
index 475e2cd..721e652 100644
--- a/arch/x86/platform/mrst/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
@@ -78,16 +78,11 @@ int sfi_mrtc_num;
 
 static void mrst_power_off(void)
 {
-	if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT)
-		intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 1);
 }
 
 static void mrst_reboot(void)
 {
-	if (__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT)
-		intel_scu_ipc_simple_command(IPCMSG_COLD_RESET, 0);
-	else
-		intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
+	intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
 }
 
 /* parse all the mtimer info to a static mtimer array */
@@ -200,34 +195,28 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table)
 
 static unsigned long __init mrst_calibrate_tsc(void)
 {
-	unsigned long flags, fast_calibrate;
-	if (__mrst_cpu_chip == MRST_CPU_CHIP_PENWELL) {
-		u32 lo, hi, ratio, fsb;
-
-		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-		pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi);
-		ratio = (hi >> 8) & 0x1f;
-		pr_debug("ratio is %d\n", ratio);
-		if (!ratio) {
-			pr_err("read a zero ratio, should be incorrect!\n");
-			pr_err("force tsc ratio to 16 ...\n");
-			ratio = 16;
-		}
-		rdmsr(MSR_FSB_FREQ, lo, hi);
-		if ((lo & 0x7) == 0x7)
-			fsb = PENWELL_FSB_FREQ_83SKU;
-		else
-			fsb = PENWELL_FSB_FREQ_100SKU;
-		fast_calibrate = ratio * fsb;
-		pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
-		lapic_timer_frequency = fsb * 1000 / HZ;
-		/* mark tsc clocksource as reliable */
-		set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
-	} else {
-		local_irq_save(flags);
-		fast_calibrate = apbt_quick_calibrate();
-		local_irq_restore(flags);
+	unsigned long fast_calibrate;
+	u32 lo, hi, ratio, fsb;
+
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi);
+	ratio = (hi >> 8) & 0x1f;
+	pr_debug("ratio is %d\n", ratio);
+	if (!ratio) {
+		pr_err("read a zero ratio, should be incorrect!\n");
+		pr_err("force tsc ratio to 16 ...\n");
+		ratio = 16;
 	}
+	rdmsr(MSR_FSB_FREQ, lo, hi);
+	if ((lo & 0x7) == 0x7)
+		fsb = PENWELL_FSB_FREQ_83SKU;
+	else
+		fsb = PENWELL_FSB_FREQ_100SKU;
+	fast_calibrate = ratio * fsb;
+	pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
+	lapic_timer_frequency = fsb * 1000 / HZ;
+	/* mark tsc clocksource as reliable */
+	set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE);
 	
 	if (fast_calibrate)
 		return fast_calibrate;
@@ -261,16 +250,11 @@ static void __cpuinit mrst_arch_setup(void)
 {
 	if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27)
 		__mrst_cpu_chip = MRST_CPU_CHIP_PENWELL;
-	else if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x26)
-		__mrst_cpu_chip = MRST_CPU_CHIP_LINCROFT;
 	else {
-		pr_err("Unknown Moorestown CPU (%d:%d), default to Lincroft\n",
+		pr_err("Unknown Intel MID CPU (%d:%d), default to Penwell\n",
 			boot_cpu_data.x86, boot_cpu_data.x86_model);
-		__mrst_cpu_chip = MRST_CPU_CHIP_LINCROFT;
+		__mrst_cpu_chip = MRST_CPU_CHIP_PENWELL;
 	}
-	pr_debug("Moorestown CPU %s identified\n",
-		(__mrst_cpu_chip == MRST_CPU_CHIP_LINCROFT) ?
-		"Lincroft" : "Penwell");
 }
 
 /* MID systems don't have i8042 controller */
@@ -686,6 +670,11 @@ static void *msic_ocd_platform_data(void *info)
 	return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD);
 }
 
+static void *msic_thermal_platform_data(void *info)
+{
+	return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_THERMAL);
+}
+
 static const struct devs_id __initconst device_ids[] = {
 	{"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data},
 	{"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data},
@@ -705,6 +694,7 @@ static const struct devs_id __initconst device_ids[] = {
 	{"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data},
 	{"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data},
 	{"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data},
+	{"msic_thermal", SFI_DEV_TYPE_IPC, 1, &msic_thermal_platform_data},
 
 	{},
 };
diff --git a/arch/x86/platform/mrst/pmu.c b/arch/x86/platform/mrst/pmu.c
deleted file mode 100644
index c0ac06d..0000000
--- a/arch/x86/platform/mrst/pmu.c
+++ /dev/null
@@ -1,817 +0,0 @@
-/*
- * mrst/pmu.c - driver for MRST Power Management Unit
- *
- * Copyright (c) 2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/cpuidle.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/seq_file.h>
-#include <linux/sfi.h>
-#include <asm/intel_scu_ipc.h>
-#include "pmu.h"
-
-#define IPCMSG_FW_REVISION	0xF4
-
-struct mrst_device {
-	u16 pci_dev_num;	/* DEBUG only */
-	u16 lss;
-	u16 latest_request;
-	unsigned int pci_state_counts[PCI_D3cold + 1]; /* DEBUG only */
-};
-
-/*
- * comlete list of MRST PCI devices
- */
-static struct mrst_device mrst_devs[] = {
-/*  0 */ { 0x0800, LSS_SPI0 },		/* Moorestown SPI Ctrl 0 */
-/*  1 */ { 0x0801, LSS_SPI1 },		/* Moorestown SPI Ctrl 1 */
-/*  2 */ { 0x0802, LSS_I2C0 },		/* Moorestown I2C 0 */
-/*  3 */ { 0x0803, LSS_I2C1 },		/* Moorestown I2C 1 */
-/*  4 */ { 0x0804, LSS_I2C2 },		/* Moorestown I2C 2 */
-/*  5 */ { 0x0805, LSS_KBD },		/* Moorestown Keyboard Ctrl */
-/*  6 */ { 0x0806, LSS_USB_HC },	/* Moorestown USB Ctrl */
-/*  7 */ { 0x0807, LSS_SD_HC0 },	/* Moorestown SD Host Ctrl 0 */
-/*  8 */ { 0x0808, LSS_SD_HC1 },	/* Moorestown SD Host Ctrl 1 */
-/*  9 */ { 0x0809, LSS_NAND },		/* Moorestown NAND Ctrl */
-/* 10 */ { 0x080a, LSS_AUDIO },		/* Moorestown Audio Ctrl */
-/* 11 */ { 0x080b, LSS_IMAGING },	/* Moorestown ISP */
-/* 12 */ { 0x080c, LSS_SECURITY },	/* Moorestown Security Controller */
-/* 13 */ { 0x080d, LSS_DISPLAY },	/* Moorestown External Displays */
-/* 14 */ { 0x080e, 0 },			/* Moorestown SCU IPC */
-/* 15 */ { 0x080f, LSS_GPIO },		/* Moorestown GPIO Controller */
-/* 16 */ { 0x0810, 0 },			/* Moorestown Power Management Unit */
-/* 17 */ { 0x0811, LSS_USB_OTG },	/* Moorestown OTG Ctrl */
-/* 18 */ { 0x0812, LSS_SPI2 },		/* Moorestown SPI Ctrl 2 */
-/* 19 */ { 0x0813, 0 },			/* Moorestown SC DMA */
-/* 20 */ { 0x0814, LSS_AUDIO_LPE },	/* Moorestown LPE DMA */
-/* 21 */ { 0x0815, LSS_AUDIO_SSP },	/* Moorestown SSP0 */
-
-/* 22 */ { 0x084F, LSS_SD_HC2 },	/* Moorestown SD Host Ctrl 2 */
-
-/* 23 */ { 0x4102, 0 },			/* Lincroft */
-/* 24 */ { 0x4110, 0 },			/* Lincroft */
-};
-
-/* n.b. We ignore PCI-id 0x815 in LSS9 b/c Linux has no driver for it */
-static u16 mrst_lss9_pci_ids[] = {0x080a, 0x0814, 0};
-static u16 mrst_lss10_pci_ids[] = {0x0800, 0x0801, 0x0802, 0x0803,
-					0x0804, 0x0805, 0x080f, 0};
-
-/* handle concurrent SMP invokations of pmu_pci_set_power_state() */
-static spinlock_t mrst_pmu_power_state_lock;
-
-static unsigned int wake_counters[MRST_NUM_LSS];	/* DEBUG only */
-static unsigned int pmu_irq_stats[INT_INVALID + 1];	/* DEBUG only */
-
-static int graphics_is_off;
-static int lss_s0i3_enabled;
-static bool mrst_pmu_s0i3_enable;
-
-/*  debug counters */
-static u32 pmu_wait_ready_calls;
-static u32 pmu_wait_ready_udelays;
-static u32 pmu_wait_ready_udelays_max;
-static u32 pmu_wait_done_calls;
-static u32 pmu_wait_done_udelays;
-static u32 pmu_wait_done_udelays_max;
-static u32 pmu_set_power_state_entry;
-static u32 pmu_set_power_state_send_cmd;
-
-static struct mrst_device *pci_id_2_mrst_dev(u16 pci_dev_num)
-{
-	int index = 0;
-
-	if ((pci_dev_num >= 0x0800) && (pci_dev_num <= 0x815))
-		index = pci_dev_num - 0x800;
-	else if (pci_dev_num == 0x084F)
-		index = 22;
-	else if (pci_dev_num == 0x4102)
-		index = 23;
-	else if (pci_dev_num == 0x4110)
-		index = 24;
-
-	if (pci_dev_num != mrst_devs[index].pci_dev_num) {
-		WARN_ONCE(1, FW_BUG "Unknown PCI device 0x%04X\n", pci_dev_num);
-		return 0;
-	}
-
-	return &mrst_devs[index];
-}
-
-/**
- * mrst_pmu_validate_cstates
- * @dev: cpuidle_device
- *
- * Certain states are not appropriate for governor to pick in some cases.
- * This function will be called as cpuidle_device's prepare callback and
- * thus tells governor to ignore such states when selecting the next state
- * to enter.
- */
-
-#define IDLE_STATE4_IS_C6	4
-#define IDLE_STATE5_IS_S0I3	5
-
-int mrst_pmu_invalid_cstates(void)
-{
-	int cpu = smp_processor_id();
-
-	/*
-	 * Demote to C4 if the PMU is busy.
-	 * Since LSS changes leave the busy bit clear...
-	 * busy means either the PMU is waiting for an ACK-C6 that
-	 * isn't coming due to an MWAIT that returned immediately;
-	 * or we returned from S0i3 successfully, and the PMU
-	 * is not done sending us interrupts.
-	 */
-	if (pmu_read_busy_status())
-		return 1 << IDLE_STATE4_IS_C6 | 1 << IDLE_STATE5_IS_S0I3;
-
-	/*
-	 * Disallow S0i3 if: PMU is not initialized, or CPU1 is active,
-	 * or if device LSS is insufficient, or the GPU is active,
-	 * or if it has been explicitly disabled.
-	 */
-	if (!pmu_reg || !cpumask_equal(cpu_online_mask, cpumask_of(cpu)) ||
-	    !lss_s0i3_enabled || !graphics_is_off || !mrst_pmu_s0i3_enable)
-		return 1 << IDLE_STATE5_IS_S0I3;
-	else
-		return 0;
-}
-
-/*
- * pmu_update_wake_counters(): read PM_WKS, update wake_counters[]
- * DEBUG only.
- */
-static void pmu_update_wake_counters(void)
-{
-	int lss;
-	u32 wake_status;
-
-	wake_status = pmu_read_wks();
-
-	for (lss = 0; lss < MRST_NUM_LSS; ++lss) {
-		if (wake_status & (1 << lss))
-			wake_counters[lss]++;
-	}
-}
-
-int mrst_pmu_s0i3_entry(void)
-{
-	int status;
-
-	/* Clear any possible error conditions */
-	pmu_write_ics(0x300);
-
-	/* set wake control to current D-states */
-	pmu_write_wssc(S0I3_SSS_TARGET);
-
-	status = mrst_s0i3_entry(PM_S0I3_COMMAND, &pmu_reg->pm_cmd);
-	pmu_update_wake_counters();
-	return status;
-}
-
-/* poll for maximum of 5ms for busy bit to clear */
-static int pmu_wait_ready(void)
-{
-	int udelays;
-
-	pmu_wait_ready_calls++;
-
-	for (udelays = 0; udelays < 500; ++udelays) {
-		if (udelays > pmu_wait_ready_udelays_max)
-			pmu_wait_ready_udelays_max = udelays;
-
-		if (pmu_read_busy_status() == 0)
-			return 0;
-
-		udelay(10);
-		pmu_wait_ready_udelays++;
-	}
-
-	/*
-	 * if this fires, observe
-	 * /sys/kernel/debug/mrst_pmu_wait_ready_calls
-	 * /sys/kernel/debug/mrst_pmu_wait_ready_udelays
-	 */
-	WARN_ONCE(1, "SCU not ready for 5ms");
-	return -EBUSY;
-}
-/* poll for maximum of 50ms us for busy bit to clear */
-static int pmu_wait_done(void)
-{
-	int udelays;
-
-	pmu_wait_done_calls++;
-
-	for (udelays = 0; udelays < 500; ++udelays) {
-		if (udelays > pmu_wait_done_udelays_max)
-			pmu_wait_done_udelays_max = udelays;
-
-		if (pmu_read_busy_status() == 0)
-			return 0;
-
-		udelay(100);
-		pmu_wait_done_udelays++;
-	}
-
-	/*
-	 * if this fires, observe
-	 * /sys/kernel/debug/mrst_pmu_wait_done_calls
-	 * /sys/kernel/debug/mrst_pmu_wait_done_udelays
-	 */
-	WARN_ONCE(1, "SCU not done for 50ms");
-	return -EBUSY;
-}
-
-u32 mrst_pmu_msi_is_disabled(void)
-{
-	return pmu_msi_is_disabled();
-}
-
-void mrst_pmu_enable_msi(void)
-{
-	pmu_msi_enable();
-}
-
-/**
- * pmu_irq - pmu driver interrupt handler
- * Context: interrupt context
- */
-static irqreturn_t pmu_irq(int irq, void *dummy)
-{
-	union pmu_pm_ics pmu_ics;
-
-	pmu_ics.value = pmu_read_ics();
-
-	if (!pmu_ics.bits.pending)
-		return IRQ_NONE;
-
-	switch (pmu_ics.bits.cause) {
-	case INT_SPURIOUS:
-	case INT_CMD_DONE:
-	case INT_CMD_ERR:
-	case INT_WAKE_RX:
-	case INT_SS_ERROR:
-	case INT_S0IX_MISS:
-	case INT_NO_ACKC6:
-		pmu_irq_stats[pmu_ics.bits.cause]++;
-		break;
-	default:
-		pmu_irq_stats[INT_INVALID]++;
-	}
-
-	pmu_write_ics(pmu_ics.value); /* Clear pending interrupt */
-
-	return IRQ_HANDLED;
-}
-
-/*
- * Translate PCI power management to MRST LSS D-states
- */
-static int pci_2_mrst_state(int lss, pci_power_t pci_state)
-{
-	switch (pci_state) {
-	case PCI_D0:
-		if (SSMSK(D0i1, lss) & D0I1_ACG_SSS_TARGET)
-			return D0i1;
-		else
-			return D0;
-	case PCI_D1:
-		return D0i1;
-	case PCI_D2:
-		return D0i2;
-	case PCI_D3hot:
-	case PCI_D3cold:
-		return D0i3;
-	default:
-		WARN(1, "pci_state %d\n", pci_state);
-		return 0;
-	}
-}
-
-static int pmu_issue_command(u32 pm_ssc)
-{
-	union pmu_pm_set_cfg_cmd_t command;
-
-	if (pmu_read_busy_status()) {
-		pr_debug("pmu is busy, Operation not permitted\n");
-		return -1;
-	}
-
-	/*
-	 * enable interrupts in PMU so that interrupts are
-	 * propagated when ioc bit for a particular set
-	 * command is set
-	 */
-
-	pmu_irq_enable();
-
-	/* Configure the sub systems for pmu2 */
-
-	pmu_write_ssc(pm_ssc);
-
-	/*
-	 * Send the set config command for pmu its configured
-	 * for mode CM_IMMEDIATE & hence with No Trigger
-	 */
-
-	command.pmu2_params.d_param.cfg_mode = CM_IMMEDIATE;
-	command.pmu2_params.d_param.cfg_delay = 0;
-	command.pmu2_params.d_param.rsvd = 0;
-
-	/* construct the command to send SET_CFG to particular PMU */
-	command.pmu2_params.d_param.cmd = SET_CFG_CMD;
-	command.pmu2_params.d_param.ioc = 0;
-	command.pmu2_params.d_param.mode_id = 0;
-	command.pmu2_params.d_param.sys_state = SYS_STATE_S0I0;
-
-	/* write the value of PM_CMD into particular PMU */
-	pr_debug("pmu command being written %x\n",
-			command.pmu_pm_set_cfg_cmd_value);
-
-	pmu_write_cmd(command.pmu_pm_set_cfg_cmd_value);
-
-	return 0;
-}
-
-static u16 pmu_min_lss_pci_req(u16 *ids, u16 pci_state)
-{
-	u16 existing_request;
-	int i;
-
-	for (i = 0; ids[i]; ++i) {
-		struct mrst_device *mrst_dev;
-
-		mrst_dev = pci_id_2_mrst_dev(ids[i]);
-		if (unlikely(!mrst_dev))
-			continue;
-
-		existing_request = mrst_dev->latest_request;
-		if (existing_request < pci_state)
-			pci_state = existing_request;
-	}
-	return pci_state;
-}
-
-/**
- * pmu_pci_set_power_state - Callback function is used by all the PCI devices
- *			for a platform  specific device power on/shutdown.
- */
-
-int pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t pci_state)
-{
-	u32 old_sss, new_sss;
-	int status = 0;
-	struct mrst_device *mrst_dev;
-
-	pmu_set_power_state_entry++;
-
-	BUG_ON(pdev->vendor != PCI_VENDOR_ID_INTEL);
-	BUG_ON(pci_state < PCI_D0 || pci_state > PCI_D3cold);
-
-	mrst_dev = pci_id_2_mrst_dev(pdev->device);
-	if (unlikely(!mrst_dev))
-		return -ENODEV;
-
-	mrst_dev->pci_state_counts[pci_state]++;	/* count invocations */
-
-	/* PMU driver calls self as part of PCI initialization, ignore */
-	if (pdev->device == PCI_DEV_ID_MRST_PMU)
-		return 0;
-
-	BUG_ON(!pmu_reg); /* SW bug if called before initialized */
-
-	spin_lock(&mrst_pmu_power_state_lock);
-
-	if (pdev->d3_delay) {
-		dev_dbg(&pdev->dev, "d3_delay %d, should be 0\n",
-			pdev->d3_delay);
-		pdev->d3_delay = 0;
-	}
-	/*
-	 * If Lincroft graphics, simply remember state
-	 */
-	if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY
-		&& !((pdev->class & PCI_SUB_CLASS_MASK) >> 8)) {
-		if (pci_state == PCI_D0)
-			graphics_is_off = 0;
-		else
-			graphics_is_off = 1;
-		goto ret;
-	}
-
-	if (!mrst_dev->lss)
-		goto ret;	/* device with no LSS */
-
-	if (mrst_dev->latest_request == pci_state)
-		goto ret;	/* no change */
-
-	mrst_dev->latest_request = pci_state;	/* record latest request */
-
-	/*
-	 * LSS9 and LSS10 contain multiple PCI devices.
-	 * Use the lowest numbered (highest power) state in the LSS
-	 */
-	if (mrst_dev->lss == 9)
-		pci_state = pmu_min_lss_pci_req(mrst_lss9_pci_ids, pci_state);
-	else if (mrst_dev->lss == 10)
-		pci_state = pmu_min_lss_pci_req(mrst_lss10_pci_ids, pci_state);
-
-	status = pmu_wait_ready();
-	if (status)
-		goto ret;
-
-	old_sss = pmu_read_sss();
-	new_sss = old_sss & ~SSMSK(3, mrst_dev->lss);
-	new_sss |= SSMSK(pci_2_mrst_state(mrst_dev->lss, pci_state),
-			mrst_dev->lss);
-
-	if (new_sss == old_sss)
-		goto ret;	/* nothing to do */
-
-	pmu_set_power_state_send_cmd++;
-
-	status = pmu_issue_command(new_sss);
-
-	if (unlikely(status != 0)) {
-		dev_err(&pdev->dev, "Failed to Issue a PM command\n");
-		goto ret;
-	}
-
-	if (pmu_wait_done())
-		goto ret;
-
-	lss_s0i3_enabled =
-	((pmu_read_sss() & S0I3_SSS_TARGET) == S0I3_SSS_TARGET);
-ret:
-	spin_unlock(&mrst_pmu_power_state_lock);
-	return status;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static char *d0ix_names[] = {"D0", "D0i1", "D0i2", "D0i3"};
-
-static inline const char *d0ix_name(int state)
-{
-	return d0ix_names[(int) state];
-}
-
-static int debug_mrst_pmu_show(struct seq_file *s, void *unused)
-{
-	struct pci_dev *pdev = NULL;
-	u32 cur_pmsss;
-	int lss;
-
-	seq_printf(s, "0x%08X D0I1_ACG_SSS_TARGET\n", D0I1_ACG_SSS_TARGET);
-
-	cur_pmsss = pmu_read_sss();
-
-	seq_printf(s, "0x%08X S0I3_SSS_TARGET\n", S0I3_SSS_TARGET);
-
-	seq_printf(s, "0x%08X Current SSS ", cur_pmsss);
-	seq_printf(s, lss_s0i3_enabled ? "\n" : "[BLOCKS s0i3]\n");
-
-	if (cpumask_equal(cpu_online_mask, cpumask_of(0)))
-		seq_printf(s, "cpu0 is only cpu online\n");
-	else
-		seq_printf(s, "cpu0 is NOT only cpu online [BLOCKS S0i3]\n");
-
-	seq_printf(s, "GFX: %s\n", graphics_is_off ? "" : "[BLOCKS s0i3]");
-
-
-	for_each_pci_dev(pdev) {
-		int pos;
-		u16 pmcsr;
-		struct mrst_device *mrst_dev;
-		int i;
-
-		mrst_dev = pci_id_2_mrst_dev(pdev->device);
-
-		seq_printf(s, "%s %04x/%04X %-16.16s ",
-			dev_name(&pdev->dev),
-			pdev->vendor, pdev->device,
-			dev_driver_string(&pdev->dev));
-
-		if (unlikely (!mrst_dev)) {
-			seq_printf(s, " UNKNOWN\n");
-			continue;
-		}
-
-		if (mrst_dev->lss)
-			seq_printf(s, "LSS %2d %-4s ", mrst_dev->lss,
-				d0ix_name(((cur_pmsss >>
-					(mrst_dev->lss * 2)) & 0x3)));
-		else
-			seq_printf(s, "            ");
-
-		/* PCI PM config space setting */
-		pos = pci_find_capability(pdev, PCI_CAP_ID_PM);
-		if (pos != 0) {
-			pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr);
-		seq_printf(s, "PCI-%-4s",
-			pci_power_name(pmcsr & PCI_PM_CTRL_STATE_MASK));
-		} else {
-			seq_printf(s, "        ");
-		}
-
-		seq_printf(s, " %s ", pci_power_name(mrst_dev->latest_request));
-		for (i = 0; i <= PCI_D3cold; ++i)
-			seq_printf(s, "%d ", mrst_dev->pci_state_counts[i]);
-
-		if (mrst_dev->lss) {
-			unsigned int lssmask;
-
-			lssmask = SSMSK(D0i3, mrst_dev->lss);
-
-			if ((lssmask & S0I3_SSS_TARGET) &&
-				((lssmask & cur_pmsss) !=
-					(lssmask & S0I3_SSS_TARGET)))
-						seq_printf(s , "[BLOCKS s0i3]");
-		}
-
-		seq_printf(s, "\n");
-	}
-	seq_printf(s, "Wake Counters:\n");
-	for (lss = 0; lss < MRST_NUM_LSS; ++lss)
-		seq_printf(s, "LSS%d %d\n", lss, wake_counters[lss]);
-
-	seq_printf(s, "Interrupt Counters:\n");
-	seq_printf(s,
-		"INT_SPURIOUS \t%8u\n" "INT_CMD_DONE \t%8u\n"
-		"INT_CMD_ERR  \t%8u\n" "INT_WAKE_RX  \t%8u\n"
-		"INT_SS_ERROR \t%8u\n" "INT_S0IX_MISS\t%8u\n"
-		"INT_NO_ACKC6 \t%8u\n" "INT_INVALID  \t%8u\n",
-		pmu_irq_stats[INT_SPURIOUS], pmu_irq_stats[INT_CMD_DONE],
-		pmu_irq_stats[INT_CMD_ERR], pmu_irq_stats[INT_WAKE_RX],
-		pmu_irq_stats[INT_SS_ERROR], pmu_irq_stats[INT_S0IX_MISS],
-		pmu_irq_stats[INT_NO_ACKC6], pmu_irq_stats[INT_INVALID]);
-
-	seq_printf(s, "mrst_pmu_wait_ready_calls          %8d\n",
-			pmu_wait_ready_calls);
-	seq_printf(s, "mrst_pmu_wait_ready_udelays        %8d\n",
-			pmu_wait_ready_udelays);
-	seq_printf(s, "mrst_pmu_wait_ready_udelays_max    %8d\n",
-			pmu_wait_ready_udelays_max);
-	seq_printf(s, "mrst_pmu_wait_done_calls           %8d\n",
-			pmu_wait_done_calls);
-	seq_printf(s, "mrst_pmu_wait_done_udelays         %8d\n",
-			pmu_wait_done_udelays);
-	seq_printf(s, "mrst_pmu_wait_done_udelays_max     %8d\n",
-			pmu_wait_done_udelays_max);
-	seq_printf(s, "mrst_pmu_set_power_state_entry     %8d\n",
-			pmu_set_power_state_entry);
-	seq_printf(s, "mrst_pmu_set_power_state_send_cmd  %8d\n",
-			pmu_set_power_state_send_cmd);
-	seq_printf(s, "SCU busy: %d\n", pmu_read_busy_status());
-
-	return 0;
-}
-
-static int debug_mrst_pmu_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, debug_mrst_pmu_show, NULL);
-}
-
-static const struct file_operations devices_state_operations = {
-	.open		= debug_mrst_pmu_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-#endif	/* DEBUG_FS */
-
-/*
- * Validate SCU PCI shim PCI vendor capability byte
- * against LSS hard-coded in mrst_devs[] above.
- * DEBUG only.
- */
-static void pmu_scu_firmware_debug(void)
-{
-	struct pci_dev *pdev = NULL;
-
-	for_each_pci_dev(pdev) {
-		struct mrst_device *mrst_dev;
-		u8 pci_config_lss;
-		int pos;
-
-		mrst_dev = pci_id_2_mrst_dev(pdev->device);
-		if (unlikely(!mrst_dev)) {
-			printk(KERN_ERR FW_BUG "pmu: Unknown "
-				"PCI device 0x%04X\n", pdev->device);
-			continue;
-		}
-
-		if (mrst_dev->lss == 0)
-			continue;	 /* no LSS in our table */
-
-		pos = pci_find_capability(pdev, PCI_CAP_ID_VNDR);
-		if (!pos != 0) {
-			printk(KERN_ERR FW_BUG "pmu: 0x%04X "
-				"missing PCI Vendor Capability\n",
-				pdev->device);
-			continue;
-		}
-		pci_read_config_byte(pdev, pos + 4, &pci_config_lss);
-		if (!(pci_config_lss & PCI_VENDOR_CAP_LOG_SS_MASK)) {
-			printk(KERN_ERR FW_BUG "pmu: 0x%04X "
-				"invalid PCI Vendor Capability 0x%x "
-				" expected LSS 0x%X\n",
-				pdev->device, pci_config_lss, mrst_dev->lss);
-			continue;
-		}
-		pci_config_lss &= PCI_VENDOR_CAP_LOG_ID_MASK;
-
-		if (mrst_dev->lss == pci_config_lss)
-			continue;
-
-		printk(KERN_ERR FW_BUG "pmu: 0x%04X LSS = %d, expected %d\n",
-			pdev->device, pci_config_lss, mrst_dev->lss);
-	}
-}
-
-/**
- * pmu_probe
- */
-static int __devinit pmu_probe(struct pci_dev *pdev,
-				   const struct pci_device_id *pci_id)
-{
-	int ret;
-	struct mrst_pmu_reg *pmu;
-
-	/* Init the device */
-	ret = pci_enable_device(pdev);
-	if (ret) {
-		dev_err(&pdev->dev, "Unable to Enable PCI device\n");
-		return ret;
-	}
-
-	ret = pci_request_regions(pdev, MRST_PMU_DRV_NAME);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n");
-		goto out_err1;
-	}
-
-	/* Map the memory of PMU reg base */
-	pmu = pci_iomap(pdev, 0, 0);
-	if (!pmu) {
-		dev_err(&pdev->dev, "Unable to map the PMU address space\n");
-		ret = -ENOMEM;
-		goto out_err2;
-	}
-
-#ifdef CONFIG_DEBUG_FS
-	/* /sys/kernel/debug/mrst_pmu */
-	(void) debugfs_create_file("mrst_pmu", S_IFREG | S_IRUGO,
-				NULL, NULL, &devices_state_operations);
-#endif
-	pmu_reg = pmu;	/* success */
-
-	if (request_irq(pdev->irq, pmu_irq, 0, MRST_PMU_DRV_NAME, NULL)) {
-		dev_err(&pdev->dev, "Registering isr has failed\n");
-		ret = -1;
-		goto out_err3;
-	}
-
-	pmu_scu_firmware_debug();
-
-	pmu_write_wkc(S0I3_WAKE_SOURCES);	/* Enable S0i3 wakeup sources */
-
-	pmu_wait_ready();
-
-	pmu_write_ssc(D0I1_ACG_SSS_TARGET);	/* Enable Auto-Clock_Gating */
-	pmu_write_cmd(0x201);
-
-	spin_lock_init(&mrst_pmu_power_state_lock);
-
-	/* Enable the hardware interrupt */
-	pmu_irq_enable();
-	return 0;
-
-out_err3:
-	free_irq(pdev->irq, NULL);
-	pci_iounmap(pdev, pmu_reg);
-	pmu_reg = NULL;
-out_err2:
-	pci_release_region(pdev, 0);
-out_err1:
-	pci_disable_device(pdev);
-	return ret;
-}
-
-static void __devexit pmu_remove(struct pci_dev *pdev)
-{
-	dev_err(&pdev->dev, "Mid PM pmu_remove called\n");
-
-	/* Freeing up the irq */
-	free_irq(pdev->irq, NULL);
-
-	pci_iounmap(pdev, pmu_reg);
-	pmu_reg = NULL;
-
-	/* disable the current PCI device */
-	pci_release_region(pdev, 0);
-	pci_disable_device(pdev);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(pmu_pci_ids) = {
-	{ PCI_VDEVICE(INTEL, PCI_DEV_ID_MRST_PMU), 0 },
-	{ }
-};
-
-MODULE_DEVICE_TABLE(pci, pmu_pci_ids);
-
-static struct pci_driver driver = {
-	.name = MRST_PMU_DRV_NAME,
-	.id_table = pmu_pci_ids,
-	.probe = pmu_probe,
-	.remove = __devexit_p(pmu_remove),
-};
-
-/**
- * pmu_pci_register - register the PMU driver as PCI device
- */
-static int __init pmu_pci_register(void)
-{
-	return pci_register_driver(&driver);
-}
-
-/* Register and probe via fs_initcall() to preceed device_initcall() */
-fs_initcall(pmu_pci_register);
-
-static void __exit mid_pci_cleanup(void)
-{
-	pci_unregister_driver(&driver);
-}
-
-static int ia_major;
-static int ia_minor;
-
-static int pmu_sfi_parse_oem(struct sfi_table_header *table)
-{
-	struct sfi_table_simple *sb;
-
-	sb = (struct sfi_table_simple *)table;
-	ia_major = (sb->pentry[1] >> 0) & 0xFFFF;
-	ia_minor = (sb->pentry[1] >> 16) & 0xFFFF;
-	printk(KERN_INFO "mrst_pmu: IA FW version v%x.%x\n",
-		ia_major, ia_minor);
-
-	return 0;
-}
-
-static int __init scu_fw_check(void)
-{
-	int ret;
-	u32 fw_version;
-
-	if (!pmu_reg)
-		return 0;	/* this driver didn't probe-out */
-
-	sfi_table_parse("OEMB", NULL, NULL, pmu_sfi_parse_oem);
-
-	if (ia_major < 0x6005 || ia_minor < 0x1525) {
-		WARN(1, "mrst_pmu: IA FW version too old\n");
-		return -1;
-	}
-
-	ret = intel_scu_ipc_command(IPCMSG_FW_REVISION, 0, NULL, 0,
-					&fw_version, 1);
-
-	if (ret) {
-		WARN(1, "mrst_pmu: IPC FW version? %d\n", ret);
-	} else {
-		int scu_major = (fw_version >> 8) & 0xFF;
-		int scu_minor = (fw_version >> 0) & 0xFF;
-
-		printk(KERN_INFO "mrst_pmu: firmware v%x\n", fw_version);
-
-		if ((scu_major >= 0xC0) && (scu_minor >= 0x49)) {
-			printk(KERN_INFO "mrst_pmu: enabling S0i3\n");
-			mrst_pmu_s0i3_enable = true;
-		} else {
-			WARN(1, "mrst_pmu: S0i3 disabled, old firmware %X.%X",
-					scu_major, scu_minor);
-		}
-	}
-	return 0;
-}
-late_initcall(scu_fw_check);
-module_exit(mid_pci_cleanup);
diff --git a/arch/x86/platform/mrst/pmu.h b/arch/x86/platform/mrst/pmu.h
deleted file mode 100644
index bfbfe64..0000000
--- a/arch/x86/platform/mrst/pmu.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c
- *
- * Copyright (c) 2011, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _MRST_PMU_H_
-#define _MRST_PMU_H_
-
-#define PCI_DEV_ID_MRST_PMU		0x0810
-#define MRST_PMU_DRV_NAME		"mrst_pmu"
-#define	PCI_SUB_CLASS_MASK		0xFF00
-
-#define	PCI_VENDOR_CAP_LOG_ID_MASK	0x7F
-#define PCI_VENDOR_CAP_LOG_SS_MASK	0x80
-
-#define SUB_SYS_ALL_D0I1	0x01155555
-#define S0I3_WAKE_SOURCES	0x00001FFF
-
-#define PM_S0I3_COMMAND					\
-	((0 << 31) |	/* Reserved */			\
-	(0 << 30) |	/* Core must be idle */		\
-	(0xc2 << 22) |	/* ACK C6 trigger */		\
-	(3 << 19) |	/* Trigger on DMI message */	\
-	(3 << 16) |	/* Enter S0i3 */		\
-	(0 << 13) |	/* Numeric mode ID (sw) */	\
-	(3 << 9) |	/* Trigger mode */		\
-	(0 << 8) |	/* Do not interrupt */		\
-	(1 << 0))	/* Set configuration */
-
-#define	LSS_DMI		0
-#define	LSS_SD_HC0	1
-#define	LSS_SD_HC1	2
-#define	LSS_NAND	3
-#define	LSS_IMAGING	4
-#define	LSS_SECURITY	5
-#define	LSS_DISPLAY	6
-#define	LSS_USB_HC	7
-#define	LSS_USB_OTG	8
-#define	LSS_AUDIO	9
-#define	LSS_AUDIO_LPE	9
-#define	LSS_AUDIO_SSP	9
-#define	LSS_I2C0	10
-#define	LSS_I2C1	10
-#define	LSS_I2C2	10
-#define	LSS_KBD		10
-#define	LSS_SPI0	10
-#define	LSS_SPI1	10
-#define	LSS_SPI2	10
-#define	LSS_GPIO	10
-#define	LSS_SRAM	11	/* used by SCU, do not touch */
-#define	LSS_SD_HC2	12
-/* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */
-#define MRST_NUM_LSS	13
-
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
-#define	SSMSK(mask, lss) ((mask) << ((lss) * 2))
-#define	D0	0
-#define	D0i1	1
-#define	D0i2	2
-#define	D0i3	3
-
-#define S0I3_SSS_TARGET	(		\
-	SSMSK(D0i1, LSS_DMI) |		\
-	SSMSK(D0i3, LSS_SD_HC0) |	\
-	SSMSK(D0i3, LSS_SD_HC1) |	\
-	SSMSK(D0i3, LSS_NAND) |		\
-	SSMSK(D0i3, LSS_SD_HC2) |	\
-	SSMSK(D0i3, LSS_IMAGING) |	\
-	SSMSK(D0i3, LSS_SECURITY) |	\
-	SSMSK(D0i3, LSS_DISPLAY) |	\
-	SSMSK(D0i3, LSS_USB_HC) |	\
-	SSMSK(D0i3, LSS_USB_OTG) |	\
-	SSMSK(D0i3, LSS_AUDIO) |	\
-	SSMSK(D0i1, LSS_I2C0))
-
-/*
- * D0i1 on Langwell is Autonomous Clock Gating (ACG).
- * Enable ACG on every LSS except camera and audio
- */
-#define D0I1_ACG_SSS_TARGET	 \
-	(SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO))
-
-enum cm_mode {
-	CM_NOP,			/* ignore the config mode value */
-	CM_IMMEDIATE,
-	CM_DELAY,
-	CM_TRIGGER,
-	CM_INVALID
-};
-
-enum sys_state {
-	SYS_STATE_S0I0,
-	SYS_STATE_S0I1,
-	SYS_STATE_S0I2,
-	SYS_STATE_S0I3,
-	SYS_STATE_S3,
-	SYS_STATE_S5
-};
-
-#define SET_CFG_CMD	1
-
-enum int_status {
-	INT_SPURIOUS = 0,
-	INT_CMD_DONE = 1,
-	INT_CMD_ERR = 2,
-	INT_WAKE_RX = 3,
-	INT_SS_ERROR = 4,
-	INT_S0IX_MISS = 5,
-	INT_NO_ACKC6 = 6,
-	INT_INVALID = 7,
-};
-
-/* PMU register interface */
-static struct mrst_pmu_reg {
-	u32 pm_sts;		/* 0x00 */
-	u32 pm_cmd;		/* 0x04 */
-	u32 pm_ics;		/* 0x08 */
-	u32 _resv1;		/* 0x0C */
-	u32 pm_wkc[2];		/* 0x10 */
-	u32 pm_wks[2];		/* 0x18 */
-	u32 pm_ssc[4];		/* 0x20 */
-	u32 pm_sss[4];		/* 0x30 */
-	u32 pm_wssc[4];		/* 0x40 */
-	u32 pm_c3c4;		/* 0x50 */
-	u32 pm_c5c6;		/* 0x54 */
-	u32 pm_msi_disable;	/* 0x58 */
-} *pmu_reg;
-
-static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); }
-static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); }
-static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); }
-static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); }
-
-static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); }
-static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); }
-static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); }
-static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); }
-static inline void pmu_write_wssc(u32 arg)
-					{ writel(arg, &pmu_reg->pm_wssc[0]); }
-
-static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); }
-static inline u32 pmu_msi_is_disabled(void)
-				{ return readl(&pmu_reg->pm_msi_disable); }
-
-union pmu_pm_ics {
-	struct {
-		u32 cause:8;
-		u32 enable:1;
-		u32 pending:1;
-		u32 reserved:22;
-	} bits;
-	u32 value;
-};
-
-static inline void pmu_irq_enable(void)
-{
-	union pmu_pm_ics pmu_ics;
-
-	pmu_ics.value = pmu_read_ics();
-	pmu_ics.bits.enable = 1;
-	pmu_write_ics(pmu_ics.value);
-}
-
-union pmu_pm_status {
-	struct {
-		u32 pmu_rev:8;
-		u32 pmu_busy:1;
-		u32 mode_id:4;
-		u32 Reserved:19;
-	} pmu_status_parts;
-	u32 pmu_status_value;
-};
-
-static inline int pmu_read_busy_status(void)
-{
-	union pmu_pm_status result;
-
-	result.pmu_status_value = pmu_read_sts();
-
-	return result.pmu_status_parts.pmu_busy;
-}
-
-/* pmu set config parameters */
-struct cfg_delay_param_t {
-	u32 cmd:8;
-	u32 ioc:1;
-	u32 cfg_mode:4;
-	u32 mode_id:3;
-	u32 sys_state:3;
-	u32 cfg_delay:8;
-	u32 rsvd:5;
-};
-
-struct cfg_trig_param_t {
-	u32 cmd:8;
-	u32 ioc:1;
-	u32 cfg_mode:4;
-	u32 mode_id:3;
-	u32 sys_state:3;
-	u32 cfg_trig_type:3;
-	u32 cfg_trig_val:8;
-	u32 cmbi:1;
-	u32 rsvd1:1;
-};
-
-union pmu_pm_set_cfg_cmd_t {
-	union {
-		struct cfg_delay_param_t d_param;
-		struct cfg_trig_param_t t_param;
-	} pmu2_params;
-	u32 pmu_pm_set_cfg_cmd_value;
-};
-
-#ifdef FUTURE_PATCH
-extern int mrst_s0i3_entry(u32 regval, u32 *regaddr);
-#else
-static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; }
-#endif
-#endif
diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c
index 2b235b7..e1869b4 100644
--- a/arch/x86/platform/olpc/olpc-xo15-sci.c
+++ b/arch/x86/platform/olpc/olpc-xo15-sci.c
@@ -24,6 +24,62 @@
 #define XO15_SCI_DEVICE_NAME		"OLPC XO-1.5 SCI"
 
 static unsigned long xo15_sci_gpe;
+static bool lid_wake_on_close;
+
+/*
+ * The normal ACPI LID wakeup behavior is wake-on-open, but not
+ * wake-on-close. This is implemented as standard by the XO-1.5 DSDT.
+ *
+ * We provide here a sysfs attribute that will additionally enable
+ * wake-on-close behavior. This is useful (e.g.) when we oportunistically
+ * suspend with the display running; if the lid is then closed, we want to
+ * wake up to turn the display off.
+ *
+ * This is controlled through a custom method in the XO-1.5 DSDT.
+ */
+static int set_lid_wake_behavior(bool wake_on_close)
+{
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+	acpi_status status;
+
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = wake_on_close;
+	status = acpi_evaluate_object(NULL, "\\_SB.PCI0.LID.LIDW", &arg_list,
+				      NULL);
+	if (ACPI_FAILURE(status)) {
+		pr_warning(PFX "failed to set lid behavior\n");
+		return 1;
+	}
+
+	lid_wake_on_close = wake_on_close;
+	return 0;
+}
+
+static ssize_t lid_wake_on_close_show(struct kobject *s,
+				      struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%u\n", lid_wake_on_close);
+}
+
+static ssize_t lid_wake_on_close_store(struct kobject *s,
+				       struct kobj_attribute *attr,
+				       const char *buf, size_t n)
+{
+	unsigned int val;
+
+	if (sscanf(buf, "%u", &val) != 1)
+		return -EINVAL;
+
+	set_lid_wake_behavior(!!val);
+	return n;
+}
+
+static struct kobj_attribute lid_wake_on_close_attr =
+	__ATTR(lid_wake_on_close, 0644,
+	       lid_wake_on_close_show, lid_wake_on_close_store);
 
 static void battery_status_changed(void)
 {
@@ -91,6 +147,7 @@ static int xo15_sci_add(struct acpi_device *device)
 {
 	unsigned long long tmp;
 	acpi_status status;
+	int r;
 
 	if (!device)
 		return -EINVAL;
@@ -112,6 +169,10 @@ static int xo15_sci_add(struct acpi_device *device)
 
 	dev_info(&device->dev, "Initialized, GPE = 0x%lx\n", xo15_sci_gpe);
 
+	r = sysfs_create_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
+	if (r)
+		goto err_sysfs;
+
 	/* Flush queue, and enable all SCI events */
 	process_sci_queue();
 	olpc_ec_mask_write(EC_SCI_SRC_ALL);
@@ -123,6 +184,11 @@ static int xo15_sci_add(struct acpi_device *device)
 		device_init_wakeup(&device->dev, true);
 
 	return 0;
+
+err_sysfs:
+	acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
+	cancel_work_sync(&sci_work);
+	return r;
 }
 
 static int xo15_sci_remove(struct acpi_device *device, int type)
@@ -130,6 +196,7 @@ static int xo15_sci_remove(struct acpi_device *device, int type)
 	acpi_disable_gpe(NULL, xo15_sci_gpe);
 	acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler);
 	cancel_work_sync(&sci_work);
+	sysfs_remove_file(&device->dev.kobj, &lid_wake_on_close_attr.attr);
 	return 0;
 }
 
diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c
index 7cce722..8260747 100644
--- a/arch/x86/platform/olpc/olpc.c
+++ b/arch/x86/platform/olpc/olpc.c
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/syscore_ops.h>
+#include <linux/debugfs.h>
 
 #include <asm/geode.h>
 #include <asm/setup.h>
@@ -31,6 +32,13 @@ EXPORT_SYMBOL_GPL(olpc_platform_info);
 
 static DEFINE_SPINLOCK(ec_lock);
 
+/* debugfs interface to EC commands */
+#define EC_MAX_CMD_ARGS (5 + 1)	/* cmd byte + 5 args */
+#define EC_MAX_CMD_REPLY (8)
+static struct dentry *ec_debugfs_dir;
+static unsigned char ec_debugfs_resp[EC_MAX_CMD_REPLY];
+static unsigned int ec_debugfs_resp_bytes;
+
 /* EC event mask to be applied during suspend (defining wakeup sources). */
 static u16 ec_wakeup_mask;
 
@@ -269,6 +277,83 @@ int olpc_ec_sci_query(u16 *sci_value)
 }
 EXPORT_SYMBOL_GPL(olpc_ec_sci_query);
 
+static ssize_t ec_gen_write(struct file *file, const char __user *buf,
+			    size_t size, loff_t *ppos)
+{
+	int i, m;
+	unsigned char ec_cmd[EC_MAX_CMD_ARGS];
+	unsigned int ec_cmd_int[EC_MAX_CMD_ARGS];
+	char cmdbuf[64];
+	int ec_cmd_bytes;
+
+	size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size);
+
+	m = sscanf(cmdbuf, "%x:%u %x %x %x %x %x", &ec_cmd_int[0],
+		   &ec_debugfs_resp_bytes,
+		   &ec_cmd_int[1], &ec_cmd_int[2], &ec_cmd_int[3],
+		   &ec_cmd_int[4], &ec_cmd_int[5]);
+	if (m < 2 || ec_debugfs_resp_bytes > EC_MAX_CMD_REPLY) {
+		printk(KERN_DEBUG "olpc-ec: bad ec cmd:  "
+		       "cmd:response-count [arg1 [arg2 ...]]\n");
+		return -EINVAL;
+	}
+
+	/* convert scanf'd ints to char */
+	ec_cmd_bytes = m - 2;
+	for (i = 0; i <= ec_cmd_bytes; i++)
+		ec_cmd[i] = ec_cmd_int[i];
+
+	printk(KERN_DEBUG "olpc-ec: debugfs cmd 0x%02x with %d args "
+	       "%02x %02x %02x %02x %02x, want %d returns\n",
+	       ec_cmd[0], ec_cmd_bytes, ec_cmd[1], ec_cmd[2], ec_cmd[3],
+	       ec_cmd[4], ec_cmd[5], ec_debugfs_resp_bytes);
+
+	olpc_ec_cmd((unsigned char) ec_cmd[0],
+		(ec_cmd_bytes == 0) ? NULL : &ec_cmd[1],
+		ec_cmd_bytes, ec_debugfs_resp, ec_debugfs_resp_bytes);
+
+	printk(KERN_DEBUG "olpc-ec: response "
+	       "%02x %02x %02x %02x %02x %02x %02x %02x (%d bytes expected)\n",
+	       ec_debugfs_resp[0], ec_debugfs_resp[1], ec_debugfs_resp[2],
+	       ec_debugfs_resp[3], ec_debugfs_resp[4], ec_debugfs_resp[5],
+	       ec_debugfs_resp[6], ec_debugfs_resp[7], ec_debugfs_resp_bytes);
+
+	return size;
+}
+
+static ssize_t ec_gen_read(struct file *file, char __user *buf,
+			   size_t size, loff_t *ppos)
+{
+	unsigned int i, r;
+	char *rp;
+	char respbuf[64];
+
+	rp = respbuf;
+	rp += sprintf(rp, "%02x", ec_debugfs_resp[0]);
+	for (i = 1; i < ec_debugfs_resp_bytes; i++)
+		rp += sprintf(rp, ", %02x", ec_debugfs_resp[i]);
+	rp += sprintf(rp, "\n");
+
+	r = rp - respbuf;
+
+	return simple_read_from_buffer(buf, size, ppos, respbuf, r);
+}
+
+static const struct file_operations ec_debugfs_genops = {
+	.write	 = ec_gen_write,
+	.read	 = ec_gen_read,
+};
+
+static void setup_debugfs(void)
+{
+	ec_debugfs_dir = debugfs_create_dir("olpc-ec", 0);
+	if (ec_debugfs_dir == ERR_PTR(-ENODEV))
+		return;
+
+	debugfs_create_file("generic", 0600, ec_debugfs_dir, NULL,
+			    &ec_debugfs_genops);
+}
+
 static int olpc_ec_suspend(void)
 {
 	return olpc_ec_mask_write(ec_wakeup_mask);
@@ -372,6 +457,7 @@ static int __init olpc_init(void)
 	}
 
 	register_syscore_ops(&olpc_syscore_ops);
+	setup_debugfs();
 
 	return 0;
 }
diff --git a/arch/x86/platform/scx200/scx200_32.c b/arch/x86/platform/scx200/scx200_32.c
index 7e004ac..7a9ad30 100644
--- a/arch/x86/platform/scx200/scx200_32.c
+++ b/arch/x86/platform/scx200/scx200_32.c
@@ -17,8 +17,6 @@
 /* Verify that the configuration block really is there */
 #define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
 
-#define NAME "scx200"
-
 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
 MODULE_DESCRIPTION("NatSemi SCx200 Driver");
 MODULE_LICENSE("GPL");
@@ -29,10 +27,10 @@ unsigned long scx200_gpio_shadow[2];
 unsigned scx200_cb_base = 0;
 
 static struct pci_device_id scx200_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_XBUS)   },
-	{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_XBUS)   },
+	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_XBUS)   },
+	{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SC1100_XBUS)   },
 	{ },
 };
 MODULE_DEVICE_TABLE(pci,scx200_tbl);
@@ -63,10 +61,11 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_
 	if (pdev->device == PCI_DEVICE_ID_NS_SCx200_BRIDGE ||
 	    pdev->device == PCI_DEVICE_ID_NS_SC1100_BRIDGE) {
 		base = pci_resource_start(pdev, 0);
-		printk(KERN_INFO NAME ": GPIO base 0x%x\n", base);
+		pr_info("GPIO base 0x%x\n", base);
 
-		if (!request_region(base, SCx200_GPIO_SIZE, "NatSemi SCx200 GPIO")) {
-			printk(KERN_ERR NAME ": can't allocate I/O for GPIOs\n");
+		if (!request_region(base, SCx200_GPIO_SIZE,
+				    "NatSemi SCx200 GPIO")) {
+			pr_err("can't allocate I/O for GPIOs\n");
 			return -EBUSY;
 		}
 
@@ -82,11 +81,11 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_
 			if (scx200_cb_probe(base)) {
 				scx200_cb_base = base;
 			} else {
-				printk(KERN_WARNING NAME ": Configuration Block not found\n");
+				pr_warn("Configuration Block not found\n");
 				return -ENODEV;
 			}
 		}
-		printk(KERN_INFO NAME ": Configuration Block base 0x%x\n", scx200_cb_base);
+		pr_info("Configuration Block base 0x%x\n", scx200_cb_base);
 	}
 
 	return 0;
@@ -111,8 +110,7 @@ u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits)
 
 static int __init scx200_init(void)
 {
-	printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n");
-
+	pr_info("NatSemi SCx200 Driver\n");
 	return pci_register_driver(&scx200_pci_driver);
 }
 
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index ce98e28..ca2df9b 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -355,3 +355,4 @@
 346	i386	setns			sys_setns
 347	i386	process_vm_readv	sys_process_vm_readv		compat_sys_process_vm_readv
 348	i386	process_vm_writev	sys_process_vm_writev		compat_sys_process_vm_writev
+349	i386	kcmp			sys_kcmp
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index b440a8f..ac3066f 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -318,3 +318,4 @@
 309	64	getcpu			sys_getcpu
 310	64	process_vm_readv	sys_process_vm_readv
 311	64	process_vm_writev	sys_process_vm_writev
+312	64	kcmp			sys_kcmp
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 12eb07b..312c9e3 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -777,11 +777,11 @@ static DEFINE_PER_CPU(unsigned long, xen_cr0_value);
 
 static unsigned long xen_read_cr0(void)
 {
-	unsigned long cr0 = percpu_read(xen_cr0_value);
+	unsigned long cr0 = this_cpu_read(xen_cr0_value);
 
 	if (unlikely(cr0 == 0)) {
 		cr0 = native_read_cr0();
-		percpu_write(xen_cr0_value, cr0);
+		this_cpu_write(xen_cr0_value, cr0);
 	}
 
 	return cr0;
@@ -791,7 +791,7 @@ static void xen_write_cr0(unsigned long cr0)
 {
 	struct multicall_space mcs;
 
-	percpu_write(xen_cr0_value, cr0);
+	this_cpu_write(xen_cr0_value, cr0);
 
 	/* Only pay attention to cr0.TS; everything else is
 	   ignored. */
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 8bbb465..1573376 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -26,7 +26,7 @@ static unsigned long xen_save_fl(void)
 	struct vcpu_info *vcpu;
 	unsigned long flags;
 
-	vcpu = percpu_read(xen_vcpu);
+	vcpu = this_cpu_read(xen_vcpu);
 
 	/* flag has opposite sense of mask */
 	flags = !vcpu->evtchn_upcall_mask;
@@ -50,7 +50,7 @@ static void xen_restore_fl(unsigned long flags)
 	   make sure we're don't switch CPUs between getting the vcpu
 	   pointer and updating the mask. */
 	preempt_disable();
-	vcpu = percpu_read(xen_vcpu);
+	vcpu = this_cpu_read(xen_vcpu);
 	vcpu->evtchn_upcall_mask = flags;
 	preempt_enable_no_resched();
 
@@ -72,7 +72,7 @@ static void xen_irq_disable(void)
 	   make sure we're don't switch CPUs between getting the vcpu
 	   pointer and updating the mask. */
 	preempt_disable();
-	percpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
+	this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
 	preempt_enable_no_resched();
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
@@ -86,7 +86,7 @@ static void xen_irq_enable(void)
 	   the caller is confused and is trying to re-enable interrupts
 	   on an indeterminate processor. */
 
-	vcpu = percpu_read(xen_vcpu);
+	vcpu = this_cpu_read(xen_vcpu);
 	vcpu->evtchn_upcall_mask = 0;
 
 	/* Doesn't matter if we get preempted here, because any
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 58a0e46..1a309ee 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1071,14 +1071,14 @@ static void drop_other_mm_ref(void *info)
 	struct mm_struct *mm = info;
 	struct mm_struct *active_mm;
 
-	active_mm = percpu_read(cpu_tlbstate.active_mm);
+	active_mm = this_cpu_read(cpu_tlbstate.active_mm);
 
-	if (active_mm == mm && percpu_read(cpu_tlbstate.state) != TLBSTATE_OK)
+	if (active_mm == mm && this_cpu_read(cpu_tlbstate.state) != TLBSTATE_OK)
 		leave_mm(smp_processor_id());
 
 	/* If this cpu still has a stale cr3 reference, then make sure
 	   it has been flushed. */
-	if (percpu_read(xen_current_cr3) == __pa(mm->pgd))
+	if (this_cpu_read(xen_current_cr3) == __pa(mm->pgd))
 		load_cr3(swapper_pg_dir);
 }
 
@@ -1185,17 +1185,17 @@ static void __init xen_pagetable_setup_done(pgd_t *base)
 
 static void xen_write_cr2(unsigned long cr2)
 {
-	percpu_read(xen_vcpu)->arch.cr2 = cr2;
+	this_cpu_read(xen_vcpu)->arch.cr2 = cr2;
 }
 
 static unsigned long xen_read_cr2(void)
 {
-	return percpu_read(xen_vcpu)->arch.cr2;
+	return this_cpu_read(xen_vcpu)->arch.cr2;
 }
 
 unsigned long xen_read_cr2_direct(void)
 {
-	return percpu_read(xen_vcpu_info.arch.cr2);
+	return this_cpu_read(xen_vcpu_info.arch.cr2);
 }
 
 static void xen_flush_tlb(void)
@@ -1278,12 +1278,12 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
 
 static unsigned long xen_read_cr3(void)
 {
-	return percpu_read(xen_cr3);
+	return this_cpu_read(xen_cr3);
 }
 
 static void set_current_cr3(void *v)
 {
-	percpu_write(xen_current_cr3, (unsigned long)v);
+	this_cpu_write(xen_current_cr3, (unsigned long)v);
 }
 
 static void __xen_write_cr3(bool kernel, unsigned long cr3)
@@ -1306,7 +1306,7 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3)
 	xen_extend_mmuext_op(&op);
 
 	if (kernel) {
-		percpu_write(xen_cr3, cr3);
+		this_cpu_write(xen_cr3, cr3);
 
 		/* Update xen_current_cr3 once the batch has actually
 		   been submitted. */
@@ -1322,7 +1322,7 @@ static void xen_write_cr3(unsigned long cr3)
 
 	/* Update while interrupts are disabled, so its atomic with
 	   respect to ipis */
-	percpu_write(xen_cr3, cr3);
+	this_cpu_write(xen_cr3, cr3);
 
 	__xen_write_cr3(true, cr3);
 
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h
index dee79b7..9c2e74f 100644
--- a/arch/x86/xen/multicalls.h
+++ b/arch/x86/xen/multicalls.h
@@ -47,7 +47,7 @@ static inline void xen_mc_issue(unsigned mode)
 		xen_mc_flush();
 
 	/* restore flags saved in xen_mc_batch */
-	local_irq_restore(percpu_read(xen_mc_irq_flags));
+	local_irq_restore(this_cpu_read(xen_mc_irq_flags));
 }
 
 /* Set up a callback to be called when the current batch is flushed */
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index b480d42..967633a 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -12,8 +12,8 @@ int xen_swiotlb __read_mostly;
 
 static struct dma_map_ops xen_swiotlb_dma_ops = {
 	.mapping_error = xen_swiotlb_dma_mapping_error,
-	.alloc_coherent = xen_swiotlb_alloc_coherent,
-	.free_coherent = xen_swiotlb_free_coherent,
+	.alloc = xen_swiotlb_alloc_coherent,
+	.free = xen_swiotlb_free_coherent,
 	.sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu,
 	.sync_single_for_device = xen_swiotlb_sync_single_for_device,
 	.sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu,
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 501d4e0..315d8fa 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -76,7 +76,7 @@ static void __cpuinit cpu_bringup(void)
 	xen_setup_cpu_clockevents();
 
 	set_cpu_online(cpu, true);
-	percpu_write(cpu_state, CPU_ONLINE);
+	this_cpu_write(cpu_state, CPU_ONLINE);
 	wmb();
 
 	/* We can take interrupts now: we're officially "up". */
diff --git a/arch/xtensa/include/asm/posix_types.h b/arch/xtensa/include/asm/posix_types.h
index 6b2190c..6e96be0 100644
--- a/arch/xtensa/include/asm/posix_types.h
+++ b/arch/xtensa/include/asm/posix_types.h
@@ -19,104 +19,21 @@
  * assume GCC is being used.
  */
 
-typedef unsigned long	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
-typedef unsigned long	__kernel_nlink_t;
-typedef long		__kernel_off_t;
-typedef int		__kernel_pid_t;
 typedef unsigned short	__kernel_ipc_pid_t;
-typedef unsigned int	__kernel_uid_t;
-typedef unsigned int	__kernel_gid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
 typedef unsigned int	__kernel_size_t;
 typedef int		__kernel_ssize_t;
 typedef long		__kernel_ptrdiff_t;
-typedef long		__kernel_time_t;
-typedef long		__kernel_suseconds_t;
-typedef long		__kernel_clock_t;
-typedef int		__kernel_timer_t;
-typedef int		__kernel_clockid_t;
-typedef int		__kernel_daddr_t;
-typedef char *		__kernel_caddr_t;
-typedef unsigned short	__kernel_uid16_t;
-typedef unsigned short	__kernel_gid16_t;
-typedef unsigned int	__kernel_uid32_t;
-typedef unsigned int	__kernel_gid32_t;
+#define __kernel_size_t __kernel_size_t
 
 typedef unsigned short	__kernel_old_uid_t;
 typedef unsigned short	__kernel_old_gid_t;
-typedef unsigned short	__kernel_old_dev_t;
-
-#ifdef __GNUC__
-typedef long long	__kernel_loff_t;
-#endif
-
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
-#ifndef __GNUC__
-
-#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
-#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define	__FD_ISSET(d, set)	(!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
-#define	__FD_ZERO(set)	\
-  ((void) memset ((void *) (set), 0, sizeof (__kernel_fd_set)))
-
-#else /* __GNUC__ */
+#define __kernel_old_uid_t __kernel_old_uid_t
 
-#if defined(__KERNEL__)
-/* With GNU C, use inline functions instead so args are evaluated only once: */
-
-#undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
-}
-
-#undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
-}
-
-#undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
-{
-	unsigned long _tmp = fd / __NFDBITS;
-	unsigned long _rem = fd % __NFDBITS;
-	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
-}
-
-/*
- * This will unroll the loop for the normal constant case (8 ints,
- * for a 256-bit fd_set)
- */
-#undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
-{
-	unsigned int *tmp = (unsigned int *)p->fds_bits;
-	int i;
+typedef unsigned short	__kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
 
-	if (__builtin_constant_p(__FDSET_LONGS)) {
-		switch (__FDSET_LONGS) {
-			case 8:
-				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
-				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
-				return;
-		}
-	}
-	i = __FDSET_LONGS;
-	while (i) {
-		i--;
-		*tmp = 0;
-		tmp++;
-	}
-}
+#include <asm-generic/posix_types.h>
 
-#endif /* defined(__KERNEL__) */
-#endif /* __GNUC__ */
 #endif /* _XTENSA_POSIX_TYPES_H */
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index bb06968..74818b1 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -75,5 +75,6 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS		SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 
 #endif	/* _XTENSA_SOCKET_H */
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index f2220b5..b69b000 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -260,10 +260,7 @@ asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3,
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, frame))
 		goto badframe;
@@ -336,8 +333,8 @@ gen_return_code(unsigned char *codemem)
 }
 
 
-static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			sigset_t *set, struct pt_regs *regs)
+static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+		       sigset_t *set, struct pt_regs *regs)
 {
 	struct rt_sigframe *frame;
 	int err = 0;
@@ -422,12 +419,11 @@ static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 		current->comm, current->pid, signal, frame, regs->pc);
 #endif
 
-	return;
+	return 0;
 
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-	force_sig(SIGSEGV, current);
+	force_sigsegv(sig, current);
+	return -EFAULT;
 }
 
 /*
@@ -449,11 +445,8 @@ asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset,
 		return -EFAULT;
 
 	sigdelsetmask(&newset, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
 	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&newset);
 
 	regs->areg[2] = -EINTR;
 	while (1) {
@@ -536,17 +529,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
 
 		/* Whee!  Actually deliver the signal.  */
 		/* Set up the stack frame */
-		setup_frame(signr, &ka, &info, oldset, regs);
-
-		if (ka.sa.sa_flags & SA_ONESHOT)
-			ka.sa.sa_handler = SIG_DFL;
+		ret = setup_frame(signr, &ka, &info, oldset, regs);
+		if (ret)
+			return ret;
 
-		spin_lock_irq(&current->sighand->siglock);
-		sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
-		if (!(ka.sa.sa_flags & SA_NODEFER))
-			sigaddset(&current->blocked, signr);
-		recalc_sigpending();
-		spin_unlock_irq(&current->sighand->siglock);
+		block_sigmask(&ka, signr);
 		if (current->ptrace & PT_SINGLESTEP)
 			task_pt_regs(current)->icountlevel = 1;
 
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 75642a3..ea84a23 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -28,13 +28,10 @@ static LIST_HEAD(blkio_list);
 struct blkio_cgroup blkio_root_cgroup = { .weight = 2*BLKIO_WEIGHT_DEFAULT };
 EXPORT_SYMBOL_GPL(blkio_root_cgroup);
 
-static struct cgroup_subsys_state *blkiocg_create(struct cgroup_subsys *,
-						  struct cgroup *);
-static int blkiocg_can_attach(struct cgroup_subsys *, struct cgroup *,
-			      struct cgroup_taskset *);
-static void blkiocg_attach(struct cgroup_subsys *, struct cgroup *,
-			   struct cgroup_taskset *);
-static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *);
+static struct cgroup_subsys_state *blkiocg_create(struct cgroup *);
+static int blkiocg_can_attach(struct cgroup *, struct cgroup_taskset *);
+static void blkiocg_attach(struct cgroup *, struct cgroup_taskset *);
+static void blkiocg_destroy(struct cgroup *);
 static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);
 
 /* for encoding cft->private value on file */
@@ -1548,7 +1545,7 @@ static int blkiocg_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup)
 				ARRAY_SIZE(blkio_files));
 }
 
-static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
+static void blkiocg_destroy(struct cgroup *cgroup)
 {
 	struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup);
 	unsigned long flags;
@@ -1598,8 +1595,7 @@ static void blkiocg_destroy(struct cgroup_subsys *subsys, struct cgroup *cgroup)
 		kfree(blkcg);
 }
 
-static struct cgroup_subsys_state *
-blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
+static struct cgroup_subsys_state *blkiocg_create(struct cgroup *cgroup)
 {
 	struct blkio_cgroup *blkcg;
 	struct cgroup *parent = cgroup->parent;
@@ -1628,8 +1624,7 @@ done:
  * of the main cic data structures.  For now we allow a task to change
  * its cgroup only if it's the only owner of its ioc.
  */
-static int blkiocg_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			      struct cgroup_taskset *tset)
+static int blkiocg_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 {
 	struct task_struct *task;
 	struct io_context *ioc;
@@ -1648,8 +1643,7 @@ static int blkiocg_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 	return ret;
 }
 
-static void blkiocg_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			   struct cgroup_taskset *tset)
+static void blkiocg_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 {
 	struct task_struct *task;
 	struct io_context *ioc;
diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index 1366a89..467c8de 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/cpu.h>
+#include <linux/sched.h>
 
 #include "blk.h"
 
@@ -103,9 +104,10 @@ static struct notifier_block __cpuinitdata blk_cpu_notifier = {
 
 void __blk_complete_request(struct request *req)
 {
-	int ccpu, cpu, group_cpu = NR_CPUS;
+	int ccpu, cpu;
 	struct request_queue *q = req->q;
 	unsigned long flags;
+	bool shared = false;
 
 	BUG_ON(!q->softirq_done_fn);
 
@@ -117,22 +119,20 @@ void __blk_complete_request(struct request *req)
 	 */
 	if (req->cpu != -1) {
 		ccpu = req->cpu;
-		if (!test_bit(QUEUE_FLAG_SAME_FORCE, &q->queue_flags)) {
-			ccpu = blk_cpu_to_group(ccpu);
-			group_cpu = blk_cpu_to_group(cpu);
-		}
+		if (!test_bit(QUEUE_FLAG_SAME_FORCE, &q->queue_flags))
+			shared = cpus_share_cache(cpu, ccpu);
 	} else
 		ccpu = cpu;
 
 	/*
-	 * If current CPU and requested CPU are in the same group, running
-	 * softirq in current CPU. One might concern this is just like
+	 * If current CPU and requested CPU share a cache, run the softirq on
+	 * the current CPU. One might concern this is just like
 	 * QUEUE_FLAG_SAME_FORCE, but actually not. blk_complete_request() is
 	 * running in interrupt handler, and currently I/O controller doesn't
 	 * support multiple interrupts, so current CPU is unique actually. This
 	 * avoids IPI sending from current CPU to the first CPU of a group.
 	 */
-	if (ccpu == cpu || ccpu == group_cpu) {
+	if (ccpu == cpu || shared) {
 		struct list_head *list;
 do_local:
 		list = &__get_cpu_var(blk_cpu_done);
diff --git a/block/blk.h b/block/blk.h
index 9c12f80..d45be87 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -166,22 +166,6 @@ static inline int queue_congestion_off_threshold(struct request_queue *q)
 	return q->nr_congestion_off;
 }
 
-static inline int blk_cpu_to_group(int cpu)
-{
-	int group = NR_CPUS;
-#ifdef CONFIG_SCHED_MC
-	const struct cpumask *mask = cpu_coregroup_mask(cpu);
-	group = cpumask_first(mask);
-#elif defined(CONFIG_SCHED_SMT)
-	group = cpumask_first(topology_thread_cpumask(cpu));
-#else
-	return cpu;
-#endif
-	if (likely(group < NR_CPUS))
-		return group;
-	return cpu;
-}
-
 /*
  * Contribute to IO statistics IFF:
  *
diff --git a/crypto/Kconfig b/crypto/Kconfig
index e6cfe1a..29f4d73 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -308,6 +308,7 @@ comment "Digest"
 config CRYPTO_CRC32C
 	tristate "CRC32c CRC algorithm"
 	select CRYPTO_HASH
+	select CRC32
 	help
 	  Castagnoli, et al Cyclic Redundancy-Check Algorithm.  Used
 	  by iSCSI for header and data digests and by others.
diff --git a/crypto/ahash.c b/crypto/ahash.c
index ac93c99..33bc9b6 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -46,7 +46,7 @@ static int hash_walk_next(struct crypto_hash_walk *walk)
 	unsigned int nbytes = min(walk->entrylen,
 				  ((unsigned int)(PAGE_SIZE)) - offset);
 
-	walk->data = crypto_kmap(walk->pg, 0);
+	walk->data = kmap_atomic(walk->pg);
 	walk->data += offset;
 
 	if (offset & alignmask) {
@@ -93,7 +93,7 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
 		return nbytes;
 	}
 
-	crypto_kunmap(walk->data, 0);
+	kunmap_atomic(walk->data);
 	crypto_yield(walk->flags);
 
 	if (err)
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 9d4a9fe..056571b 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -405,6 +405,41 @@ int crypto_unregister_alg(struct crypto_alg *alg)
 }
 EXPORT_SYMBOL_GPL(crypto_unregister_alg);
 
+int crypto_register_algs(struct crypto_alg *algs, int count)
+{
+	int i, ret;
+
+	for (i = 0; i < count; i++) {
+		ret = crypto_register_alg(&algs[i]);
+		if (ret)
+			goto err;
+	}
+
+	return 0;
+
+err:
+	for (--i; i >= 0; --i)
+		crypto_unregister_alg(&algs[i]);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(crypto_register_algs);
+
+int crypto_unregister_algs(struct crypto_alg *algs, int count)
+{
+	int i, ret;
+
+	for (i = 0; i < count; i++) {
+		ret = crypto_unregister_alg(&algs[i]);
+		if (ret)
+			pr_err("Failed to unregister %s %s: %d\n",
+			       algs[i].cra_driver_name, algs[i].cra_name, ret);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_algs);
+
 int crypto_register_template(struct crypto_template *tmpl)
 {
 	struct crypto_template *q;
diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c
index 0d5a90c..361b5e8 100644
--- a/crypto/async_tx/async_memcpy.c
+++ b/crypto/async_tx/async_memcpy.c
@@ -79,13 +79,13 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
 		/* wait for any prerequisite operations */
 		async_tx_quiesce(&submit->depend_tx);
 
-		dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset;
-		src_buf = kmap_atomic(src, KM_USER1) + src_offset;
+		dest_buf = kmap_atomic(dest) + dest_offset;
+		src_buf = kmap_atomic(src) + src_offset;
 
 		memcpy(dest_buf, src_buf, len);
 
-		kunmap_atomic(src_buf, KM_USER1);
-		kunmap_atomic(dest_buf, KM_USER0);
+		kunmap_atomic(src_buf);
+		kunmap_atomic(dest_buf);
 
 		async_tx_sync_epilog(submit);
 	}
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 1e61d1a..4dd80c7 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -43,22 +43,22 @@ static int blkcipher_walk_first(struct blkcipher_desc *desc,
 
 static inline void blkcipher_map_src(struct blkcipher_walk *walk)
 {
-	walk->src.virt.addr = scatterwalk_map(&walk->in, 0);
+	walk->src.virt.addr = scatterwalk_map(&walk->in);
 }
 
 static inline void blkcipher_map_dst(struct blkcipher_walk *walk)
 {
-	walk->dst.virt.addr = scatterwalk_map(&walk->out, 1);
+	walk->dst.virt.addr = scatterwalk_map(&walk->out);
 }
 
 static inline void blkcipher_unmap_src(struct blkcipher_walk *walk)
 {
-	scatterwalk_unmap(walk->src.virt.addr, 0);
+	scatterwalk_unmap(walk->src.virt.addr);
 }
 
 static inline void blkcipher_unmap_dst(struct blkcipher_walk *walk)
 {
-	scatterwalk_unmap(walk->dst.virt.addr, 1);
+	scatterwalk_unmap(walk->dst.virt.addr);
 }
 
 /* Get a spot of the specified length that does not straddle a page.
diff --git a/crypto/ccm.c b/crypto/ccm.c
index c36d654..32fe1bb 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -216,12 +216,12 @@ static void get_data_to_compute(struct crypto_cipher *tfm,
 			scatterwalk_start(&walk, sg_next(walk.sg));
 			n = scatterwalk_clamp(&walk, len);
 		}
-		data_src = scatterwalk_map(&walk, 0);
+		data_src = scatterwalk_map(&walk);
 
 		compute_mac(tfm, data_src, n, pctx);
 		len -= n;
 
-		scatterwalk_unmap(data_src, 0);
+		scatterwalk_unmap(data_src);
 		scatterwalk_advance(&walk, n);
 		scatterwalk_done(&walk, 0, len);
 		if (len)
diff --git a/crypto/crc32c.c b/crypto/crc32c.c
index 3f9ad28..06f7018 100644
--- a/crypto/crc32c.c
+++ b/crypto/crc32c.c
@@ -40,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/crc32.h>
 
 #define CHKSUM_BLOCK_SIZE	1
 #define CHKSUM_DIGEST_SIZE	4
@@ -53,95 +54,6 @@ struct chksum_desc_ctx {
 };
 
 /*
- * This is the CRC-32C table
- * Generated with:
- * width = 32 bits
- * poly = 0x1EDC6F41
- * reflect input bytes = true
- * reflect output bytes = true
- */
-
-static const u32 crc32c_table[256] = {
-	0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
-	0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
-	0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
-	0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
-	0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
-	0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
-	0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
-	0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
-	0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
-	0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
-	0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
-	0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
-	0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
-	0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
-	0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
-	0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
-	0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
-	0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
-	0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
-	0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
-	0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
-	0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
-	0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
-	0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
-	0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
-	0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
-	0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
-	0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
-	0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
-	0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
-	0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
-	0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
-	0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
-	0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
-	0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
-	0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
-	0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
-	0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
-	0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
-	0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
-	0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
-	0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
-	0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
-	0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
-	0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
-	0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
-	0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
-	0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
-	0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
-	0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
-	0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
-	0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
-	0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
-	0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
-	0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
-	0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
-	0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
-	0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
-	0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
-	0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
-	0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
-	0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
-	0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
-	0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
-};
-
-/*
- * Steps through buffer one byte at at time, calculates reflected
- * crc using table.
- */
-
-static u32 crc32c(u32 crc, const u8 *data, unsigned int length)
-{
-	while (length--)
-		crc = crc32c_table[(crc ^ *data++) & 0xFFL] ^ (crc >> 8);
-
-	return crc;
-}
-
-/*
  * Steps through buffer one byte at at time, calculates reflected
  * crc using table.
  */
@@ -179,7 +91,7 @@ static int chksum_update(struct shash_desc *desc, const u8 *data,
 {
 	struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
 
-	ctx->crc = crc32c(ctx->crc, data, length);
+	ctx->crc = __crc32c_le(ctx->crc, data, length);
 	return 0;
 }
 
@@ -193,7 +105,7 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
 
 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out)
 {
-	*(__le32 *)out = ~cpu_to_le32(crc32c(*crcp, data, len));
+	*(__le32 *)out = ~cpu_to_le32(__crc32c_le(*crcp, data, len));
 	return 0;
 }
 
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 16f8693..36a2af7 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -304,7 +304,7 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
 static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
 			  struct nlattr **attrs)
 {
-	int exact;
+	int exact = 0;
 	const char *name;
 	struct crypto_alg *alg;
 	struct crypto_user_alg *p = nlmsg_data(nlh);
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 41e529a..7281b8a 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -40,9 +40,9 @@ void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
 }
 EXPORT_SYMBOL_GPL(scatterwalk_start);
 
-void *scatterwalk_map(struct scatter_walk *walk, int out)
+void *scatterwalk_map(struct scatter_walk *walk)
 {
-	return crypto_kmap(scatterwalk_page(walk), out) +
+	return kmap_atomic(scatterwalk_page(walk)) +
 	       offset_in_page(walk->offset);
 }
 EXPORT_SYMBOL_GPL(scatterwalk_map);
@@ -83,9 +83,9 @@ void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
 		if (len_this_page > nbytes)
 			len_this_page = nbytes;
 
-		vaddr = scatterwalk_map(walk, out);
+		vaddr = scatterwalk_map(walk);
 		memcpy_dir(buf, vaddr, len_this_page, out);
-		scatterwalk_unmap(vaddr, out);
+		scatterwalk_unmap(vaddr);
 
 		scatterwalk_advance(walk, len_this_page);
 
diff --git a/crypto/shash.c b/crypto/shash.c
index 9100912..21fc12e 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -281,10 +281,10 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
 	if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
 		void *data;
 
-		data = crypto_kmap(sg_page(sg), 0);
+		data = kmap_atomic(sg_page(sg));
 		err = crypto_shash_digest(desc, data + offset, nbytes,
 					  req->result);
-		crypto_kunmap(data, 0);
+		kunmap_atomic(data);
 		crypto_yield(desc->flags);
 	} else
 		err = crypto_shash_init(desc) ?:
@@ -420,9 +420,9 @@ static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg,
 
 		desc->flags = hdesc->flags;
 
-		data = crypto_kmap(sg_page(sg), 0);
+		data = kmap_atomic(sg_page(sg));
 		err = crypto_shash_digest(desc, data + offset, nbytes, out);
-		crypto_kunmap(data, 0);
+		kunmap_atomic(data);
 		crypto_yield(desc->flags);
 		goto out;
 	}
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 5afe5d1..b3ae9e5 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -40,8 +40,6 @@ source "drivers/net/Kconfig"
 
 source "drivers/isdn/Kconfig"
 
-source "drivers/telephony/Kconfig"
-
 # input before char - char/joystick depends on it. As does USB.
 
 source "drivers/input/Kconfig"
@@ -52,6 +50,8 @@ source "drivers/i2c/Kconfig"
 
 source "drivers/spi/Kconfig"
 
+source "drivers/hsi/Kconfig"
+
 source "drivers/pps/Kconfig"
 
 source "drivers/ptp/Kconfig"
@@ -132,8 +132,14 @@ source "drivers/clocksource/Kconfig"
 
 source "drivers/iommu/Kconfig"
 
+source "drivers/remoteproc/Kconfig"
+
+source "drivers/rpmsg/Kconfig"
+
 source "drivers/virt/Kconfig"
 
 source "drivers/devfreq/Kconfig"
 
+source "drivers/modem_shm/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index c07be02..4855a1a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_ATA)		+= ata/
 obj-$(CONFIG_TARGET_CORE)	+= target/
 obj-$(CONFIG_MTD)		+= mtd/
 obj-$(CONFIG_SPI)		+= spi/
+obj-y				+= hsi/
 obj-y				+= net/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_FUSION)		+= message/
@@ -86,7 +87,6 @@ obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
 obj-$(CONFIG_THERMAL)		+= thermal/
 obj-$(CONFIG_WATCHDOG)		+= watchdog/
-obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_ACCESSIBILITY)	+= accessibility/
@@ -120,12 +120,15 @@ obj-$(CONFIG_VLYNQ)		+= vlynq/
 obj-$(CONFIG_STAGING)		+= staging/
 obj-y				+= platform/
 obj-y				+= ieee802154/
+obj-$(CONFIG_MODEM_SHM)	+= modem_shm/
 #common clk code
 obj-y				+= clk/
 
 obj-$(CONFIG_HWSPINLOCK)	+= hwspinlock/
 obj-$(CONFIG_NFC)		+= nfc/
 obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
+obj-$(CONFIG_REMOTEPROC)	+= remoteproc/
+obj-$(CONFIG_RPMSG)		+= rpmsg/
 
 # Virtualization drivers
 obj-$(CONFIG_VIRT_DRIVERS)	+= virt/
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 88eb143..b5e4142 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -276,6 +276,84 @@ int is_dock_device(acpi_handle handle)
 EXPORT_SYMBOL_GPL(is_dock_device);
 
 /**
+ * dock_link_device - link a device from the dock
+ * @handle: acpi handle of the potentially dependent device
+ */
+struct device **dock_link_device(acpi_handle handle)
+{
+	struct device *dev = acpi_get_physical_device(handle);
+	struct dock_station *dock_station;
+	int ret, dock = 0;
+	struct device **devices;
+
+	devices = kmalloc(dock_station_count * sizeof(struct device *),
+			  GFP_KERNEL);
+
+	if (!dev)
+		return NULL;
+
+	if (is_dock(handle)) {
+		put_device(dev);
+		return NULL;
+	}
+
+	list_for_each_entry(dock_station, &dock_stations, sibling) {
+		if (find_dock_dependent_device(dock_station, handle)) {
+			ret = sysfs_create_link(&dock_station->dock_device->dev.kobj,
+						&dev->kobj, dev_name(dev));
+			WARN_ON(ret);
+			devices[dock] = &dock_station->dock_device->dev;
+			dock++;
+		}
+	}
+	if (!dock)
+		put_device(dev);
+
+	devices[dock] = NULL;
+	return devices;
+}
+EXPORT_SYMBOL_GPL(dock_link_device);
+
+/**
+ * dock_unlink_device - unlink a device from the dock
+ * @handle: acpi handle of the potentially dependent device
+ */
+struct device **dock_unlink_device(acpi_handle handle)
+{
+	struct device *dev = acpi_get_physical_device(handle);
+	struct dock_station *dock_station;
+	int dock = 0;
+	struct device **devices =
+		kmalloc(dock_station_count * sizeof(struct device *),
+			GFP_KERNEL);
+
+	if (!dev)
+		return NULL;
+
+	if (is_dock(handle)) {
+		put_device(dev);
+		return NULL;
+	}
+
+	list_for_each_entry(dock_station, &dock_stations, sibling) {
+		if (find_dock_dependent_device(dock_station, handle)) {
+			sysfs_remove_link(&dock_station->dock_device->dev.kobj,
+					  dev_name(dev));
+			devices[dock] = &dock_station->dock_device->dev;
+			dock++;
+		}
+	}
+	/* An extra reference has been held while the link existed */
+	if (dock)
+		put_device(dev);
+
+	put_device(dev);
+	devices[dock] = NULL;
+	return devices;
+}
+EXPORT_SYMBOL_GPL(dock_unlink_device);
+
+/**
  * dock_present - see if the dock station is present.
  * @ds: the dock station
  *
@@ -642,6 +720,26 @@ void unregister_hotplug_dock_device(acpi_handle handle)
 }
 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
 
+int is_registered_hotplug_dock_device(const struct acpi_dock_ops *ops)
+{
+	struct dock_dependent_device *dd;
+	struct dock_station *ds;
+
+	list_for_each_entry(ds, &dock_stations, sibling) {
+		mutex_lock(&ds->hp_lock);
+		list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
+			if (ops == dd->ops) {
+				mutex_unlock(&ds->hp_lock);
+				return 1;
+			}
+		}
+		mutex_unlock(&ds->hp_lock);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(is_registered_hotplug_dock_device);
+
 /**
  * handle_eject_request - handle an undock request checking for error conditions
  *
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 29a4a5c..18d6812 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -39,6 +39,7 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
 	}
 	return -ENODEV;
 }
+EXPORT_SYMBOL(register_acpi_bus_type);
 
 int unregister_acpi_bus_type(struct acpi_bus_type *type)
 {
@@ -54,6 +55,7 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
 	}
 	return -ENODEV;
 }
+EXPORT_SYMBOL(unregister_acpi_bus_type);
 
 static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
 {
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 8ae05ce..2801b41 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -474,6 +474,7 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
 
 #ifdef CONFIG_CPU_FREQ
 	acpi_processor_ppc_has_changed(pr, 0);
+	acpi_processor_load_module(pr);
 #endif
 	acpi_processor_get_throttling_info(pr);
 	acpi_processor_get_limit_info(pr);
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 85b3237..0af48a8 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void)
 	acpi_processor_ppc_status &= ~PPC_REGISTERED;
 }
 
+/*
+ * Do a quick check if the systems looks like it should use ACPI
+ * cpufreq. We look at a _PCT method being available, but don't
+ * do a whole lot of sanity checks.
+ */
+void acpi_processor_load_module(struct acpi_processor *pr)
+{
+	static int requested;
+	acpi_status status = 0;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	if (!arch_has_acpi_pdc() || requested)
+		return;
+	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+	if (!ACPI_FAILURE(status)) {
+		printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n");
+		request_module_nowait("acpi_cpufreq");
+		requested = 1;
+	}
+	kfree(buffer.pointer);
+}
+
 static int acpi_processor_get_performance_control(struct acpi_processor *pr)
 {
 	int result = 0;
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 54eaf96..01c2cf4 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -497,37 +497,22 @@ static void amba_device_release(struct device *dev)
 }
 
 /**
- *	amba_device_register - register an AMBA device
- *	@dev: AMBA device to register
- *	@parent: parent memory resource
+ *	amba_device_add - add a previously allocated AMBA device structure
+ *	@dev: AMBA device allocated by amba_device_alloc
+ *	@parent: resource parent for this devices resources
  *
- *	Setup the AMBA device, reading the cell ID if present.
- *	Claim the resource, and register the AMBA device with
- *	the Linux device manager.
+ *	Claim the resource, and read the device cell ID if not already
+ *	initialized.  Register the AMBA device with the Linux device
+ *	manager.
  */
-int amba_device_register(struct amba_device *dev, struct resource *parent)
+int amba_device_add(struct amba_device *dev, struct resource *parent)
 {
 	u32 size;
 	void __iomem *tmp;
 	int i, ret;
 
-	device_initialize(&dev->dev);
-
-	/*
-	 * Copy from device_add
-	 */
-	if (dev->dev.init_name) {
-		dev_set_name(&dev->dev, "%s", dev->dev.init_name);
-		dev->dev.init_name = NULL;
-	}
-
-	dev->dev.release = amba_device_release;
-	dev->dev.bus = &amba_bustype;
-	dev->dev.dma_mask = &dev->dma_mask;
-	dev->res.name = dev_name(&dev->dev);
-
-	if (!dev->dev.coherent_dma_mask && dev->dma_mask)
-		dev_warn(&dev->dev, "coherent dma mask is unset\n");
+	WARN_ON(dev->irq[0] == (unsigned int)-1);
+	WARN_ON(dev->irq[1] == (unsigned int)-1);
 
 	ret = request_resource(parent, &dev->res);
 	if (ret)
@@ -582,9 +567,9 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
 	if (ret)
 		goto err_release;
 
-	if (dev->irq[0] != NO_IRQ)
+	if (dev->irq[0] && dev->irq[0] != NO_IRQ)
 		ret = device_create_file(&dev->dev, &dev_attr_irq0);
-	if (ret == 0 && dev->irq[1] != NO_IRQ)
+	if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ)
 		ret = device_create_file(&dev->dev, &dev_attr_irq1);
 	if (ret == 0)
 		return ret;
@@ -596,6 +581,74 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
  err_out:
 	return ret;
 }
+EXPORT_SYMBOL_GPL(amba_device_add);
+
+static void amba_device_initialize(struct amba_device *dev, const char *name)
+{
+	device_initialize(&dev->dev);
+	if (name)
+		dev_set_name(&dev->dev, "%s", name);
+	dev->dev.release = amba_device_release;
+	dev->dev.bus = &amba_bustype;
+	dev->dev.dma_mask = &dev->dma_mask;
+	dev->res.name = dev_name(&dev->dev);
+}
+
+/**
+ *	amba_device_alloc - allocate an AMBA device
+ *	@name: sysfs name of the AMBA device
+ *	@base: base of AMBA device
+ *	@size: size of AMBA device
+ *
+ *	Allocate and initialize an AMBA device structure.  Returns %NULL
+ *	on failure.
+ */
+struct amba_device *amba_device_alloc(const char *name, resource_size_t base,
+	size_t size)
+{
+	struct amba_device *dev;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev) {
+		amba_device_initialize(dev, name);
+		dev->res.start = base;
+		dev->res.end = base + size - 1;
+		dev->res.flags = IORESOURCE_MEM;
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL_GPL(amba_device_alloc);
+
+/**
+ *	amba_device_register - register an AMBA device
+ *	@dev: AMBA device to register
+ *	@parent: parent memory resource
+ *
+ *	Setup the AMBA device, reading the cell ID if present.
+ *	Claim the resource, and register the AMBA device with
+ *	the Linux device manager.
+ */
+int amba_device_register(struct amba_device *dev, struct resource *parent)
+{
+	amba_device_initialize(dev, dev->dev.init_name);
+	dev->dev.init_name = NULL;
+
+	if (!dev->dev.coherent_dma_mask && dev->dma_mask)
+		dev_warn(&dev->dev, "coherent dma mask is unset\n");
+
+	return amba_device_add(dev, parent);
+}
+
+/**
+ *	amba_device_put - put an AMBA device
+ *	@dev: AMBA device to put
+ */
+void amba_device_put(struct amba_device *dev)
+{
+	put_device(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(amba_device_put);
 
 /**
  *	amba_device_unregister - unregister an AMBA device
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index d07bf03..fb659c8 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -261,6 +261,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
 	{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
 	{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
+	{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
+	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index fdf27b9..68013f9 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -321,6 +321,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
 	{ 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
 	/* SATA Controller IDE (Panther Point) */
 	{ 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (Lynx Point) */
+	{ 0x8086, 0x8c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
+	/* SATA Controller IDE (Lynx Point) */
+	{ 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
+	/* SATA Controller IDE (Lynx Point) */
+	{ 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (Lynx Point) */
+	{ 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
 	{ }	/* terminate list */
 };
 
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index bb7c5f1..b03e468 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -48,62 +48,42 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
 }
 
 /**
- * ata_acpi_associate_sata_port - associate SATA port with ACPI objects
- * @ap: target SATA port
+ * ata_ap_acpi_handle - provide the acpi_handle for an ata_port
+ * @ap: the acpi_handle returned will correspond to this port
  *
- * Look up ACPI objects associated with @ap and initialize acpi_handle
- * fields of @ap, the port and devices accordingly.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
+ * Returns the acpi_handle for the ACPI namespace object corresponding to
+ * the ata_port passed into the function, or NULL if no such object exists
  */
-void ata_acpi_associate_sata_port(struct ata_port *ap)
+acpi_handle ata_ap_acpi_handle(struct ata_port *ap)
 {
-	WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
-
-	if (!sata_pmp_attached(ap)) {
-		u64 adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
-
-		ap->link.device->acpi_handle =
-			acpi_get_child(ap->host->acpi_handle, adr);
-	} else {
-		struct ata_link *link;
-
-		ap->link.device->acpi_handle = NULL;
-
-		ata_for_each_link(link, ap, EDGE) {
-			u64 adr = SATA_ADR(ap->port_no, link->pmp);
-
-			link->device->acpi_handle =
-				acpi_get_child(ap->host->acpi_handle, adr);
-		}
-	}
+	if (ap->flags & ATA_FLAG_ACPI_SATA)
+		return NULL;
+	return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev);
 }
+EXPORT_SYMBOL(ata_ap_acpi_handle);
 
-static void ata_acpi_associate_ide_port(struct ata_port *ap)
+/**
+ * ata_dev_acpi_handle - provide the acpi_handle for an ata_device
+ * @dev: the acpi_device returned will correspond to this port
+ *
+ * Returns the acpi_handle for the ACPI namespace object corresponding to
+ * the ata_device passed into the function, or NULL if no such object exists
+ */
+acpi_handle ata_dev_acpi_handle(struct ata_device *dev)
 {
-	int max_devices, i;
-
-	ap->acpi_handle = acpi_get_child(ap->host->acpi_handle, ap->port_no);
-	if (!ap->acpi_handle)
-		return;
-
-	max_devices = 1;
-	if (ap->flags & ATA_FLAG_SLAVE_POSS)
-		max_devices++;
-
-	for (i = 0; i < max_devices; i++) {
-		struct ata_device *dev = &ap->link.device[i];
-
-		dev->acpi_handle = acpi_get_child(ap->acpi_handle, i);
-	}
+	acpi_integer adr;
+	struct ata_port *ap = dev->link->ap;
 
-	if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
-		ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
+	if (ap->flags & ATA_FLAG_ACPI_SATA) {
+		if (!sata_pmp_attached(ap))
+			adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
+		else
+			adr = SATA_ADR(ap->port_no, dev->link->pmp);
+		return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), adr);
+	} else
+		return acpi_get_child(ata_ap_acpi_handle(ap), dev->devno);
 }
+EXPORT_SYMBOL(ata_dev_acpi_handle);
 
 /* @ap and @dev are the same as ata_acpi_handle_hotplug() */
 static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev)
@@ -229,56 +209,6 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
 };
 
 /**
- * ata_acpi_associate - associate ATA host with ACPI objects
- * @host: target ATA host
- *
- * Look up ACPI objects associated with @host and initialize
- * acpi_handle fields of @host, its ports and devices accordingly.
- *
- * LOCKING:
- * EH context.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-void ata_acpi_associate(struct ata_host *host)
-{
-	int i, j;
-
-	if (!is_pci_dev(host->dev) || libata_noacpi)
-		return;
-
-	host->acpi_handle = DEVICE_ACPI_HANDLE(host->dev);
-	if (!host->acpi_handle)
-		return;
-
-	for (i = 0; i < host->n_ports; i++) {
-		struct ata_port *ap = host->ports[i];
-
-		if (host->ports[0]->flags & ATA_FLAG_ACPI_SATA)
-			ata_acpi_associate_sata_port(ap);
-		else
-			ata_acpi_associate_ide_port(ap);
-
-		if (ap->acpi_handle) {
-			/* we might be on a docking station */
-			register_hotplug_dock_device(ap->acpi_handle,
-					     &ata_acpi_ap_dock_ops, ap);
-		}
-
-		for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
-			struct ata_device *dev = &ap->link.device[j];
-
-			if (dev->acpi_handle) {
-				/* we might be on a docking station */
-				register_hotplug_dock_device(dev->acpi_handle,
-					     &ata_acpi_dev_dock_ops, dev);
-			}
-		}
-	}
-}
-
-/**
  * ata_acpi_dissociate - dissociate ATA host from ACPI objects
  * @host: target ATA host
  *
@@ -299,7 +229,7 @@ void ata_acpi_dissociate(struct ata_host *host)
 		struct ata_port *ap = host->ports[i];
 		const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
 
-		if (ap->acpi_handle && gtm)
+		if (ata_ap_acpi_handle(ap) && gtm)
 			ata_acpi_stm(ap, gtm);
 	}
 }
@@ -324,7 +254,8 @@ int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *gtm)
 	acpi_status status;
 	int rc = 0;
 
-	status = acpi_evaluate_object(ap->acpi_handle, "_GTM", NULL, &output);
+	status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_GTM", NULL,
+				      &output);
 
 	rc = -ENOENT;
 	if (status == AE_NOT_FOUND)
@@ -394,7 +325,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm)
 	input.count = 3;
 	input.pointer = in_params;
 
-	status = acpi_evaluate_object(ap->acpi_handle, "_STM", &input, NULL);
+	status = acpi_evaluate_object(ata_ap_acpi_handle(ap), "_STM", &input,
+				      NULL);
 
 	if (status == AE_NOT_FOUND)
 		return -ENOENT;
@@ -451,7 +383,8 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf)
 			    __func__, ap->port_no);
 
 	/* _GTF has no input parameters */
-	status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output);
+	status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_GTF", NULL,
+				      &output);
 	out_obj = dev->gtf_cache = output.pointer;
 
 	if (ACPI_FAILURE(status)) {
@@ -817,7 +750,8 @@ static int ata_acpi_push_id(struct ata_device *dev)
 
 	/* It's OK for _SDD to be missing too. */
 	swap_buf_le16(dev->id, ATA_ID_WORDS);
-	status = acpi_evaluate_object(dev->acpi_handle, "_SDD", &input, NULL);
+	status = acpi_evaluate_object(ata_dev_acpi_handle(dev), "_SDD", &input,
+				      NULL);
 	swap_buf_le16(dev->id, ATA_ID_WORDS);
 
 	if (status == AE_NOT_FOUND)
@@ -867,7 +801,7 @@ void ata_acpi_on_resume(struct ata_port *ap)
 	const struct ata_acpi_gtm *gtm = ata_acpi_init_gtm(ap);
 	struct ata_device *dev;
 
-	if (ap->acpi_handle && gtm) {
+	if (ata_ap_acpi_handle(ap) && gtm) {
 		/* _GTM valid */
 
 		/* restore timing parameters */
@@ -908,22 +842,22 @@ void ata_acpi_set_state(struct ata_port *ap, pm_message_t state)
 {
 	struct ata_device *dev;
 
-	if (!ap->acpi_handle || (ap->flags & ATA_FLAG_ACPI_SATA))
+	if (!ata_ap_acpi_handle(ap) || (ap->flags & ATA_FLAG_ACPI_SATA))
 		return;
 
 	/* channel first and then drives for power on and vica versa
 	   for power off */
 	if (state.event == PM_EVENT_ON)
-		acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D0);
+		acpi_bus_set_power(ata_ap_acpi_handle(ap), ACPI_STATE_D0);
 
 	ata_for_each_dev(dev, &ap->link, ENABLED) {
-		if (dev->acpi_handle)
-			acpi_bus_set_power(dev->acpi_handle,
+		if (ata_dev_acpi_handle(dev))
+			acpi_bus_set_power(ata_dev_acpi_handle(dev),
 				state.event == PM_EVENT_ON ?
 					ACPI_STATE_D0 : ACPI_STATE_D3);
 	}
 	if (state.event != PM_EVENT_ON)
-		acpi_bus_set_power(ap->acpi_handle, ACPI_STATE_D3);
+		acpi_bus_set_power(ata_ap_acpi_handle(ap), ACPI_STATE_D3);
 }
 
 /**
@@ -948,7 +882,7 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
 	int nr_executed = 0;
 	int rc;
 
-	if (!dev->acpi_handle)
+	if (!ata_dev_acpi_handle(dev))
 		return 0;
 
 	/* do we need to do _GTF? */
@@ -994,7 +928,6 @@ int ata_acpi_on_devcfg(struct ata_device *dev)
 	}
 
 	ata_dev_warn(dev, "ACPI: failed the second time, disabled\n");
-	dev->acpi_handle = NULL;
 
 	/* We can safely continue if no _GTF command has been executed
 	 * and port is not frozen.
@@ -1018,3 +951,121 @@ void ata_acpi_on_disable(struct ata_device *dev)
 {
 	ata_acpi_clear_gtf(dev);
 }
+
+void ata_acpi_bind_dock(struct ata_device *dev)
+{
+	struct device **docks;
+
+	if (!ata_dev_acpi_handle(dev))
+		return;
+	docks = dock_link_device(ata_dev_acpi_handle(dev));
+	kfree(docks);
+}
+
+void ata_acpi_unbind_dock(struct ata_device *dev)
+{
+	struct device **docks;
+
+	if (!ata_dev_acpi_handle(dev))
+		return;
+	docks = dock_unlink_device(ata_dev_acpi_handle(dev));
+	kfree(docks);
+}
+
+static int is_pci_ata(struct device *dev)
+{
+	struct pci_dev *pdev;
+
+	if (!is_pci_dev(dev))
+		return 0;
+
+	pdev = to_pci_dev(dev);
+
+	if ((pdev->class >> 8) != PCI_CLASS_STORAGE_SATA &&
+	    (pdev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return 0;
+
+	return 1;
+}
+
+static int ata_acpi_bind_host(struct device *dev, int host, acpi_handle *handle)
+{
+	struct Scsi_Host *shost = dev_to_shost(dev);
+	struct ata_port *ap = ata_shost_to_port(shost);
+
+	if (ap->flags & ATA_FLAG_ACPI_SATA)
+		return -ENODEV;
+
+	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent->parent), ap->port_no);
+
+	if (!*handle)
+		return -ENODEV;
+
+	if (!is_registered_hotplug_dock_device(&ata_acpi_ap_dock_ops))
+		register_hotplug_dock_device(*handle, &ata_acpi_ap_dock_ops, ap);
+
+	return 0;
+}
+
+static int ata_acpi_bind_device(struct device *dev, int channel, int id,
+				acpi_handle *handle)
+{
+	struct device *host = dev->parent->parent;
+	struct Scsi_Host *shost = dev_to_shost(host);
+	struct ata_port *ap = ata_shost_to_port(shost);
+	struct ata_device *ata_dev;
+
+	if (ap->flags & ATA_FLAG_ACPI_SATA)
+		ata_dev = &ap->link.device[channel];
+	else
+		ata_dev = &ap->link.device[id];
+
+	*handle = ata_dev_acpi_handle(ata_dev);
+
+	if (!*handle)
+		return -ENODEV;
+
+	if (!is_registered_hotplug_dock_device(&ata_acpi_dev_dock_ops))
+		register_hotplug_dock_device(*handle, &ata_acpi_dev_dock_ops, ata_dev);
+
+	return 0;
+}
+
+static int ata_acpi_find_device(struct device *dev, acpi_handle *handle)
+{
+	unsigned int host, channel, id, lun;
+
+	if (sscanf(dev_name(dev), "host%u", &host) == 1) {
+		if (!is_pci_ata(dev->parent->parent))
+			return -ENODEV;
+
+		return ata_acpi_bind_host(dev, host, handle);
+	} else if (sscanf(dev_name(dev), "%d:%d:%d:%d",
+			&host, &channel, &id, &lun) == 4) {
+		if (!is_pci_ata(dev->parent->parent->parent->parent))
+			return -ENODEV;
+
+		return ata_acpi_bind_device(dev, channel, id, handle);
+	} else
+		return -ENODEV;
+}
+
+static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle)
+{
+	return -ENODEV;
+}
+
+static struct acpi_bus_type ata_acpi_bus = {
+	.find_bridge = ata_acpi_find_dummy,
+	.find_device = ata_acpi_find_device,
+};
+
+int ata_acpi_register(void)
+{
+	return scsi_register_acpi_bus_type(&ata_acpi_bus);
+}
+
+void ata_acpi_unregister(void)
+{
+	scsi_unregister_acpi_bus_type(&ata_acpi_bus);
+}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index c06e0ec..3f74ad3 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5936,29 +5936,31 @@ void ata_host_init(struct ata_host *host, struct device *dev,
 	host->ops = ops;
 }
 
-int ata_port_probe(struct ata_port *ap)
+void __ata_port_probe(struct ata_port *ap)
 {
-	int rc = 0;
+	struct ata_eh_info *ehi = &ap->link.eh_info;
+	unsigned long flags;
 
-	/* probe */
-	if (ap->ops->error_handler) {
-		struct ata_eh_info *ehi = &ap->link.eh_info;
-		unsigned long flags;
+	/* kick EH for boot probing */
+	spin_lock_irqsave(ap->lock, flags);
 
-		/* kick EH for boot probing */
-		spin_lock_irqsave(ap->lock, flags);
+	ehi->probe_mask |= ATA_ALL_DEVICES;
+	ehi->action |= ATA_EH_RESET;
+	ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
 
-		ehi->probe_mask |= ATA_ALL_DEVICES;
-		ehi->action |= ATA_EH_RESET;
-		ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
+	ap->pflags &= ~ATA_PFLAG_INITIALIZING;
+	ap->pflags |= ATA_PFLAG_LOADING;
+	ata_port_schedule_eh(ap);
 
-		ap->pflags &= ~ATA_PFLAG_INITIALIZING;
-		ap->pflags |= ATA_PFLAG_LOADING;
-		ata_port_schedule_eh(ap);
+	spin_unlock_irqrestore(ap->lock, flags);
+}
 
-		spin_unlock_irqrestore(ap->lock, flags);
+int ata_port_probe(struct ata_port *ap)
+{
+	int rc = 0;
 
-		/* wait for EH to finish */
+	if (ap->ops->error_handler) {
+		__ata_port_probe(ap);
 		ata_port_wait_eh(ap);
 	} else {
 		DPRINTK("ata%u: bus probe begin\n", ap->print_id);
@@ -6042,9 +6044,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 	if (rc)
 		goto err_tadd;
 
-	/* associate with ACPI nodes */
-	ata_acpi_associate(host);
-
 	/* set cable, sata_spd_limit and report */
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
@@ -6504,6 +6503,8 @@ static int __init ata_init(void)
 
 	ata_parse_force_param();
 
+	ata_acpi_register();
+
 	rc = ata_sff_init();
 	if (rc) {
 		kfree(ata_force_tbl);
@@ -6530,6 +6531,7 @@ static void __exit ata_exit(void)
 	ata_release_transport(ata_scsi_transport_template);
 	libata_transport_exit();
 	ata_sff_exit();
+	ata_acpi_unregister();
 	kfree(ata_force_tbl);
 }
 
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index a9b2820..c61316e 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -863,6 +863,7 @@ void ata_port_wait_eh(struct ata_port *ap)
 		goto retry;
 	}
 }
+EXPORT_SYMBOL_GPL(ata_port_wait_eh);
 
 static int ata_eh_nr_in_flight(struct ata_port *ap)
 {
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 21b80c5..61c59ee 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -529,8 +529,6 @@ int sata_pmp_attach(struct ata_device *dev)
 	ata_for_each_link(tlink, ap, EDGE)
 		sata_link_init_spd(tlink);
 
-	ata_acpi_associate_sata_port(ap);
-
 	return 0;
 
  fail:
@@ -570,8 +568,6 @@ static void sata_pmp_detach(struct ata_device *dev)
 	ap->nr_pmp_links = 0;
 	link->pmp = 0;
 	spin_unlock_irqrestore(ap->lock, flags);
-
-	ata_acpi_associate_sata_port(ap);
 }
 
 /**
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 508a60b..db15eb5 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3444,6 +3444,7 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
 			if (!IS_ERR(sdev)) {
 				dev->sdev = sdev;
 				scsi_device_put(sdev);
+				ata_acpi_bind_dock(dev);
 			} else {
 				dev->sdev = NULL;
 			}
@@ -3544,6 +3545,8 @@ static void ata_scsi_remove_dev(struct ata_device *dev)
 	sdev = dev->sdev;
 	dev->sdev = NULL;
 
+	ata_acpi_unbind_dock(dev);
+
 	if (sdev) {
 		/* If user initiated unplug races with us, sdev can go
 		 * away underneath us after the host lock and
@@ -3838,6 +3841,19 @@ void ata_sas_port_stop(struct ata_port *ap)
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_stop);
 
+int ata_sas_async_port_init(struct ata_port *ap)
+{
+	int rc = ap->ops->port_start(ap);
+
+	if (!rc) {
+		ap->print_id = ata_print_id++;
+		__ata_port_probe(ap);
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(ata_sas_async_port_init);
+
 /**
  *	ata_sas_port_init - Initialize a SATA device
  *	@ap: SATA port to initialize
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 9691dd0..d8af325 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -720,13 +720,13 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 
 		/* FIXME: use a bounce buffer */
 		local_irq_save(flags);
-		buf = kmap_atomic(page, KM_IRQ0);
+		buf = kmap_atomic(page);
 
 		/* do the actual data transfer */
 		ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
 				       do_write);
 
-		kunmap_atomic(buf, KM_IRQ0);
+		kunmap_atomic(buf);
 		local_irq_restore(flags);
 	} else {
 		buf = page_address(page);
@@ -865,13 +865,13 @@ next_sg:
 
 		/* FIXME: use bounce buffer */
 		local_irq_save(flags);
-		buf = kmap_atomic(page, KM_IRQ0);
+		buf = kmap_atomic(page);
 
 		/* do the actual data transfer */
 		consumed = ap->ops->sff_data_xfer(dev,  buf + offset,
 								count, rw);
 
-		kunmap_atomic(buf, KM_IRQ0);
+		kunmap_atomic(buf);
 		local_irq_restore(flags);
 	} else {
 		buf = page_address(page);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 814486d..71d8a89 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -105,22 +105,22 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
 extern struct ata_port *ata_port_alloc(struct ata_host *host);
 extern const char *sata_spd_string(unsigned int spd);
 extern int ata_port_probe(struct ata_port *ap);
+extern void __ata_port_probe(struct ata_port *ap);
 
 /* libata-acpi.c */
 #ifdef CONFIG_ATA_ACPI
 extern unsigned int ata_acpi_gtf_filter;
-
-extern void ata_acpi_associate_sata_port(struct ata_port *ap);
-extern void ata_acpi_associate(struct ata_host *host);
 extern void ata_acpi_dissociate(struct ata_host *host);
 extern int ata_acpi_on_suspend(struct ata_port *ap);
 extern void ata_acpi_on_resume(struct ata_port *ap);
 extern int ata_acpi_on_devcfg(struct ata_device *dev);
 extern void ata_acpi_on_disable(struct ata_device *dev);
 extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state);
+extern int ata_acpi_register(void);
+extern void ata_acpi_unregister(void);
+extern void ata_acpi_bind_dock(struct ata_device *dev);
+extern void ata_acpi_unbind_dock(struct ata_device *dev);
 #else
-static inline void ata_acpi_associate_sata_port(struct ata_port *ap) { }
-static inline void ata_acpi_associate(struct ata_host *host) { }
 static inline void ata_acpi_dissociate(struct ata_host *host) { }
 static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
 static inline void ata_acpi_on_resume(struct ata_port *ap) { }
@@ -128,6 +128,10 @@ static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; }
 static inline void ata_acpi_on_disable(struct ata_device *dev) { }
 static inline void ata_acpi_set_state(struct ata_port *ap,
 				      pm_message_t state) { }
+static inline int ata_acpi_register(void) { return 0; }
+static void ata_acpi_unregister(void) { }
+static void ata_acpi_bind_dock(struct ata_device *dev) { }
+static void ata_acpi_unbind_dock(struct ata_device *dev) { }
 #endif
 
 /* libata-scsi.c */
@@ -151,7 +155,6 @@ extern void ata_eh_acquire(struct ata_port *ap);
 extern void ata_eh_release(struct ata_port *ap);
 extern enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
 extern void ata_scsi_error(struct Scsi_Host *host);
-extern void ata_port_wait_eh(struct ata_port *ap);
 extern void ata_eh_fastdrain_timerfn(unsigned long arg);
 extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
 extern void ata_dev_disable(struct ata_device *dev);
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 54145ed..b63ca3b 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -39,7 +39,7 @@ static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
 {
 	struct ata_port *ap = link->ap;
 	struct pata_acpi *acpi = ap->private_data;
-	if (ap->acpi_handle == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
+	if (ata_ap_acpi_handle(ap) == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
 		return -ENODEV;
 
 	return ata_sff_prereset(link, deadline);
@@ -195,7 +195,7 @@ static int pacpi_port_start(struct ata_port *ap)
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	struct pata_acpi *acpi;
 
-	if (ap->acpi_handle == NULL)
+	if (ata_ap_acpi_handle(ap) == NULL)
 		return -ENODEV;
 
 	acpi = ap->private_data = devm_kzalloc(&pdev->dev, sizeof(struct pata_acpi), GFP_KERNEL);
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 35aca7d..4fe9d21 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -401,8 +401,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
 	ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
 
 	active = clamp_val(t.active, 2, 15);
-	recover = clamp_val(t.recover, 2, 16);
-	recover &= 0x15;
+	recover = clamp_val(t.recover, 2, 16) & 0x0F;
 
 	inb(0x3E6);
 	inb(0x3E6);
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index f556969..68c7588 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -1572,7 +1572,7 @@ static inline void host_vcc_unbind(struct lanai_dev *lanai,
 
 static void lanai_reset(struct lanai_dev *lanai)
 {
-	printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* reseting - not "
+	printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* resetting - not "
 	    "implemented\n", lanai->number);
 	/* TODO */
 	/* The following is just a hack until we write the real
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 5d1d076..e8cd652 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1206,9 +1206,9 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	
  out_unmap_both:
 	pci_set_drvdata(dev, NULL);
-	pci_iounmap(dev, card->config_regs);
- out_unmap_config:
 	pci_iounmap(dev, card->buffers);
+ out_unmap_config:
+	pci_iounmap(dev, card->config_regs);
  out_release_regions:
 	pci_release_regions(dev);
  out:
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 7be9f79..9aa618a 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -176,6 +176,9 @@ config GENERIC_CPU_DEVICES
 	bool
 	default n
 
+config SOC_BUS
+	bool
+
 source "drivers/base/regmap/Kconfig"
 
 config DMA_SHARED_BUFFER
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 610f999..b6d1b9c 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MODULES)	+= module.o
 endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
 obj-$(CONFIG_REGMAP)	+= regmap/
+obj-$(CONFIG_SOC_BUS) += soc.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 40fb122..26a06b8 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -1194,13 +1194,15 @@ EXPORT_SYMBOL_GPL(subsys_interface_register);
 
 void subsys_interface_unregister(struct subsys_interface *sif)
 {
-	struct bus_type *subsys = sif->subsys;
+	struct bus_type *subsys;
 	struct subsys_dev_iter iter;
 	struct device *dev;
 
-	if (!sif)
+	if (!sif || !sif->subsys)
 		return;
 
+	subsys = sif->subsys;
+
 	mutex_lock(&subsys->p->mutex);
 	list_del_init(&sif->node);
 	if (sif->remove_dev) {
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 74dda4f..0841a36 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -18,6 +18,8 @@
 #include <linux/string.h>
 #include <linux/kdev_t.h>
 #include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/genhd.h>
 #include <linux/kallsyms.h>
 #include <linux/mutex.h>
@@ -267,6 +269,9 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
 	if (dev->driver)
 		add_uevent_var(env, "DRIVER=%s", dev->driver->name);
 
+	/* Add common DT information about the device */
+	of_device_uevent(dev, env);
+
 	/* have the bus specific function add its stuff */
 	if (dev->bus && dev->bus->uevent) {
 		retval = dev->bus->uevent(dev, env);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4dabf50..adf937b 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -11,6 +11,7 @@
 #include <linux/device.h>
 #include <linux/node.h>
 #include <linux/gfp.h>
+#include <linux/slab.h>
 #include <linux/percpu.h>
 
 #include "base.h"
@@ -244,6 +245,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
 	cpu->dev.id = num;
 	cpu->dev.bus = &cpu_subsys;
 	cpu->dev.release = cpu_device_release;
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
+	cpu->dev.bus->uevent = arch_cpu_uevent;
+#endif
 	error = device_register(&cpu->dev);
 	if (!error && cpu->hotpluggable)
 		register_cpu_control(cpu);
@@ -268,6 +272,10 @@ struct device *get_cpu_device(unsigned cpu)
 }
 EXPORT_SYMBOL_GPL(get_cpu_device);
 
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
+static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
+#endif
+
 static struct attribute *cpu_root_attrs[] = {
 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 	&dev_attr_probe.attr,
@@ -278,6 +286,9 @@ static struct attribute *cpu_root_attrs[] = {
 	&cpu_attrs[2].attr.attr,
 	&dev_attr_kernel_max.attr,
 	&dev_attr_offline.attr,
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
+	&dev_attr_modalias.attr,
+#endif
 	NULL
 };
 
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index b631f7c..60e4f77 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -153,34 +153,6 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj,
 }
 EXPORT_SYMBOL_GPL(driver_add_kobj);
 
-/**
- * get_driver - increment driver reference count.
- * @drv: driver.
- */
-struct device_driver *get_driver(struct device_driver *drv)
-{
-	if (drv) {
-		struct driver_private *priv;
-		struct kobject *kobj;
-
-		kobj = kobject_get(&drv->p->kobj);
-		priv = to_driver(kobj);
-		return priv->driver;
-	}
-	return NULL;
-}
-EXPORT_SYMBOL_GPL(get_driver);
-
-/**
- * put_driver - decrement driver's refcount.
- * @drv: driver.
- */
-void put_driver(struct device_driver *drv)
-{
-	kobject_put(&drv->p->kobj);
-}
-EXPORT_SYMBOL_GPL(put_driver);
-
 static int driver_add_groups(struct device_driver *drv,
 			     const struct attribute_group **groups)
 {
@@ -234,7 +206,6 @@ int driver_register(struct device_driver *drv)
 
 	other = driver_find(drv->name, drv->bus);
 	if (other) {
-		put_driver(other);
 		printk(KERN_ERR "Error: Driver '%s' is already registered, "
 			"aborting...\n", drv->name);
 		return -EBUSY;
@@ -275,7 +246,9 @@ EXPORT_SYMBOL_GPL(driver_unregister);
  * Call kset_find_obj() to iterate over list of drivers on
  * a bus to find driver by name. Return driver if found.
  *
- * Note that kset_find_obj increments driver's reference count.
+ * This routine provides no locking to prevent the driver it returns
+ * from being unregistered or unloaded while the caller is using it.
+ * The caller is responsible for preventing this.
  */
 struct device_driver *driver_find(const char *name, struct bus_type *bus)
 {
@@ -283,6 +256,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus)
 	struct driver_private *priv;
 
 	if (k) {
+		/* Drop reference added by kset_find_obj() */
+		kobject_put(k);
 		priv = to_driver(k);
 		return priv->driver;
 	}
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 9e60dbe..7dda4f7 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -466,7 +466,7 @@ store_hard_offline_page(struct device *dev,
 	if (strict_strtoull(buf, 0, &pfn) < 0)
 		return -EINVAL;
 	pfn >>= PAGE_SHIFT;
-	ret = __memory_failure(pfn, 0, 0);
+	ret = memory_failure(pfn, 0, 0);
 	return ret ? ret : count;
 }
 
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f0c605e..a1a7225 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -621,7 +621,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
 	int rc;
 
 	/* Some devices have extra OF data and an OF-style MODALIAS */
-	rc = of_device_uevent(dev,env);
+	rc = of_device_uevent_modalias(dev,env);
 	if (rc != -ENODEV)
 		return rc;
 
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 978bbf7..d2c0323 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -820,17 +820,16 @@ static int pm_genpd_suspend(struct device *dev)
 }
 
 /**
- * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain.
+ * pm_genpd_suspend_late - Late suspend of a device from an I/O PM domain.
  * @dev: Device to suspend.
  *
  * Carry out a late suspend of a device under the assumption that its
  * pm_domain field points to the domain member of an object of type
  * struct generic_pm_domain representing a PM domain consisting of I/O devices.
  */
-static int pm_genpd_suspend_noirq(struct device *dev)
+static int pm_genpd_suspend_late(struct device *dev)
 {
 	struct generic_pm_domain *genpd;
-	int ret;
 
 	dev_dbg(dev, "%s()\n", __func__);
 
@@ -838,14 +837,28 @@ static int pm_genpd_suspend_noirq(struct device *dev)
 	if (IS_ERR(genpd))
 		return -EINVAL;
 
-	if (genpd->suspend_power_off)
-		return 0;
+	return genpd->suspend_power_off ? 0 : genpd_suspend_late(genpd, dev);
+}
 
-	ret = genpd_suspend_late(genpd, dev);
-	if (ret)
-		return ret;
+/**
+ * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
+ * @dev: Device to suspend.
+ *
+ * Stop the device and remove power from the domain if all devices in it have
+ * been stopped.
+ */
+static int pm_genpd_suspend_noirq(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
 
-	if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))
+	dev_dbg(dev, "%s()\n", __func__);
+
+	genpd = dev_to_genpd(dev);
+	if (IS_ERR(genpd))
+		return -EINVAL;
+
+	if (genpd->suspend_power_off
+	    || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)))
 		return 0;
 
 	genpd_stop_dev(genpd, dev);
@@ -862,13 +875,10 @@ static int pm_genpd_suspend_noirq(struct device *dev)
 }
 
 /**
- * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain.
+ * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain.
  * @dev: Device to resume.
  *
- * Carry out an early resume of a device under the assumption that its
- * pm_domain field points to the domain member of an object of type
- * struct generic_pm_domain representing a power domain consisting of I/O
- * devices.
+ * Restore power to the device's PM domain, if necessary, and start the device.
  */
 static int pm_genpd_resume_noirq(struct device *dev)
 {
@@ -890,13 +900,34 @@ static int pm_genpd_resume_noirq(struct device *dev)
 	 */
 	pm_genpd_poweron(genpd);
 	genpd->suspended_count--;
-	genpd_start_dev(genpd, dev);
 
-	return genpd_resume_early(genpd, dev);
+	return genpd_start_dev(genpd, dev);
 }
 
 /**
- * pm_genpd_resume - Resume a device belonging to an I/O power domain.
+ * pm_genpd_resume_early - Early resume of a device in an I/O PM domain.
+ * @dev: Device to resume.
+ *
+ * Carry out an early resume of a device under the assumption that its
+ * pm_domain field points to the domain member of an object of type
+ * struct generic_pm_domain representing a power domain consisting of I/O
+ * devices.
+ */
+static int pm_genpd_resume_early(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	genpd = dev_to_genpd(dev);
+	if (IS_ERR(genpd))
+		return -EINVAL;
+
+	return genpd->suspend_power_off ? 0 : genpd_resume_early(genpd, dev);
+}
+
+/**
+ * pm_genpd_resume - Resume of device in an I/O PM domain.
  * @dev: Device to resume.
  *
  * Resume a device under the assumption that its pm_domain field points to the
@@ -917,7 +948,7 @@ static int pm_genpd_resume(struct device *dev)
 }
 
 /**
- * pm_genpd_freeze - Freeze a device belonging to an I/O power domain.
+ * pm_genpd_freeze - Freezing a device in an I/O PM domain.
  * @dev: Device to freeze.
  *
  * Freeze a device under the assumption that its pm_domain field points to the
@@ -938,7 +969,29 @@ static int pm_genpd_freeze(struct device *dev)
 }
 
 /**
- * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain.
+ * pm_genpd_freeze_late - Late freeze of a device in an I/O PM domain.
+ * @dev: Device to freeze.
+ *
+ * Carry out a late freeze of a device under the assumption that its
+ * pm_domain field points to the domain member of an object of type
+ * struct generic_pm_domain representing a power domain consisting of I/O
+ * devices.
+ */
+static int pm_genpd_freeze_late(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	genpd = dev_to_genpd(dev);
+	if (IS_ERR(genpd))
+		return -EINVAL;
+
+	return genpd->suspend_power_off ? 0 : genpd_freeze_late(genpd, dev);
+}
+
+/**
+ * pm_genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
  * @dev: Device to freeze.
  *
  * Carry out a late freeze of a device under the assumption that its
@@ -949,7 +1002,6 @@ static int pm_genpd_freeze(struct device *dev)
 static int pm_genpd_freeze_noirq(struct device *dev)
 {
 	struct generic_pm_domain *genpd;
-	int ret;
 
 	dev_dbg(dev, "%s()\n", __func__);
 
@@ -957,20 +1009,31 @@ static int pm_genpd_freeze_noirq(struct device *dev)
 	if (IS_ERR(genpd))
 		return -EINVAL;
 
-	if (genpd->suspend_power_off)
-		return 0;
+	return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev);
+}
 
-	ret = genpd_freeze_late(genpd, dev);
-	if (ret)
-		return ret;
+/**
+ * pm_genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
+ * @dev: Device to thaw.
+ *
+ * Start the device, unless power has been removed from the domain already
+ * before the system transition.
+ */
+static int pm_genpd_thaw_noirq(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
 
-	genpd_stop_dev(genpd, dev);
+	dev_dbg(dev, "%s()\n", __func__);
 
-	return 0;
+	genpd = dev_to_genpd(dev);
+	if (IS_ERR(genpd))
+		return -EINVAL;
+
+	return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev);
 }
 
 /**
- * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain.
+ * pm_genpd_thaw_early - Early thaw of device in an I/O PM domain.
  * @dev: Device to thaw.
  *
  * Carry out an early thaw of a device under the assumption that its
@@ -978,7 +1041,7 @@ static int pm_genpd_freeze_noirq(struct device *dev)
  * struct generic_pm_domain representing a power domain consisting of I/O
  * devices.
  */
-static int pm_genpd_thaw_noirq(struct device *dev)
+static int pm_genpd_thaw_early(struct device *dev)
 {
 	struct generic_pm_domain *genpd;
 
@@ -988,12 +1051,7 @@ static int pm_genpd_thaw_noirq(struct device *dev)
 	if (IS_ERR(genpd))
 		return -EINVAL;
 
-	if (genpd->suspend_power_off)
-		return 0;
-
-	genpd_start_dev(genpd, dev);
-
-	return genpd_thaw_early(genpd, dev);
+	return genpd->suspend_power_off ? 0 : genpd_thaw_early(genpd, dev);
 }
 
 /**
@@ -1018,13 +1076,11 @@ static int pm_genpd_thaw(struct device *dev)
 }
 
 /**
- * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain.
+ * pm_genpd_restore_noirq - Start of restore of device in an I/O PM domain.
  * @dev: Device to resume.
  *
- * Carry out an early restore of a device under the assumption that its
- * pm_domain field points to the domain member of an object of type
- * struct generic_pm_domain representing a power domain consisting of I/O
- * devices.
+ * Make sure the domain will be in the same power state as before the
+ * hibernation the system is resuming from and start the device if necessary.
  */
 static int pm_genpd_restore_noirq(struct device *dev)
 {
@@ -1054,9 +1110,8 @@ static int pm_genpd_restore_noirq(struct device *dev)
 
 	pm_genpd_poweron(genpd);
 	genpd->suspended_count--;
-	genpd_start_dev(genpd, dev);
 
-	return genpd_resume_early(genpd, dev);
+	return genpd_start_dev(genpd, dev);
 }
 
 /**
@@ -1099,11 +1154,15 @@ static void pm_genpd_complete(struct device *dev)
 
 #define pm_genpd_prepare		NULL
 #define pm_genpd_suspend		NULL
+#define pm_genpd_suspend_late		NULL
 #define pm_genpd_suspend_noirq		NULL
+#define pm_genpd_resume_early		NULL
 #define pm_genpd_resume_noirq		NULL
 #define pm_genpd_resume			NULL
 #define pm_genpd_freeze			NULL
+#define pm_genpd_freeze_late		NULL
 #define pm_genpd_freeze_noirq		NULL
+#define pm_genpd_thaw_early		NULL
 #define pm_genpd_thaw_noirq		NULL
 #define pm_genpd_thaw			NULL
 #define pm_genpd_restore_noirq		NULL
@@ -1171,6 +1230,38 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 }
 
 /**
+ * __pm_genpd_of_add_device - Add a device to an I/O PM domain.
+ * @genpd_node: Device tree node pointer representing a PM domain to which the
+ *   the device is added to.
+ * @dev: Device to be added.
+ * @td: Set of PM QoS timing parameters to attach to the device.
+ */
+int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev,
+			     struct gpd_timing_data *td)
+{
+	struct generic_pm_domain *genpd = NULL, *gpd;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	if (IS_ERR_OR_NULL(genpd_node) || IS_ERR_OR_NULL(dev))
+		return -EINVAL;
+
+	mutex_lock(&gpd_list_lock);
+	list_for_each_entry(gpd, &gpd_list, gpd_list_node) {
+		if (gpd->of_node == genpd_node) {
+			genpd = gpd;
+			break;
+		}
+	}
+	mutex_unlock(&gpd_list_lock);
+
+	if (!genpd)
+		return -EINVAL;
+
+	return __pm_genpd_add_device(genpd, dev, td);
+}
+
+/**
  * pm_genpd_remove_device - Remove a device from an I/O PM domain.
  * @genpd: PM domain to remove the device from.
  * @dev: Device to be removed.
@@ -1450,7 +1541,7 @@ static int pm_genpd_default_suspend_late(struct device *dev)
 {
 	int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.suspend_late;
 
-	return cb ? cb(dev) : pm_generic_suspend_noirq(dev);
+	return cb ? cb(dev) : pm_generic_suspend_late(dev);
 }
 
 /**
@@ -1461,7 +1552,7 @@ static int pm_genpd_default_resume_early(struct device *dev)
 {
 	int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.resume_early;
 
-	return cb ? cb(dev) : pm_generic_resume_noirq(dev);
+	return cb ? cb(dev) : pm_generic_resume_early(dev);
 }
 
 /**
@@ -1494,7 +1585,7 @@ static int pm_genpd_default_freeze_late(struct device *dev)
 {
 	int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.freeze_late;
 
-	return cb ? cb(dev) : pm_generic_freeze_noirq(dev);
+	return cb ? cb(dev) : pm_generic_freeze_late(dev);
 }
 
 /**
@@ -1505,7 +1596,7 @@ static int pm_genpd_default_thaw_early(struct device *dev)
 {
 	int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.thaw_early;
 
-	return cb ? cb(dev) : pm_generic_thaw_noirq(dev);
+	return cb ? cb(dev) : pm_generic_thaw_early(dev);
 }
 
 /**
@@ -1564,16 +1655,22 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 	genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
 	genpd->domain.ops.prepare = pm_genpd_prepare;
 	genpd->domain.ops.suspend = pm_genpd_suspend;
+	genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
 	genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq;
 	genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq;
+	genpd->domain.ops.resume_early = pm_genpd_resume_early;
 	genpd->domain.ops.resume = pm_genpd_resume;
 	genpd->domain.ops.freeze = pm_genpd_freeze;
+	genpd->domain.ops.freeze_late = pm_genpd_freeze_late;
 	genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq;
 	genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq;
+	genpd->domain.ops.thaw_early = pm_genpd_thaw_early;
 	genpd->domain.ops.thaw = pm_genpd_thaw;
 	genpd->domain.ops.poweroff = pm_genpd_suspend;
+	genpd->domain.ops.poweroff_late = pm_genpd_suspend_late;
 	genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq;
 	genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq;
+	genpd->domain.ops.restore_early = pm_genpd_resume_early;
 	genpd->domain.ops.restore = pm_genpd_resume;
 	genpd->domain.ops.complete = pm_genpd_complete;
 	genpd->dev_ops.save_state = pm_genpd_default_save_state;
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 10bdd79..d03d290 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -92,59 +92,28 @@ int pm_generic_prepare(struct device *dev)
 }
 
 /**
- * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback.
- * @dev: Device to handle.
- * @event: PM transition of the system under way.
- * @bool: Whether or not this is the "noirq" stage.
- *
- * Execute the PM callback corresponding to @event provided by the driver of
- * @dev, if defined, and return its error code.    Return 0 if the callback is
- * not present.
+ * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems.
+ * @dev: Device to suspend.
  */
-static int __pm_generic_call(struct device *dev, int event, bool noirq)
+int pm_generic_suspend_noirq(struct device *dev)
 {
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*callback)(struct device *);
-
-	if (!pm)
-		return 0;
-
-	switch (event) {
-	case PM_EVENT_SUSPEND:
-		callback = noirq ? pm->suspend_noirq : pm->suspend;
-		break;
-	case PM_EVENT_FREEZE:
-		callback = noirq ? pm->freeze_noirq : pm->freeze;
-		break;
-	case PM_EVENT_HIBERNATE:
-		callback = noirq ? pm->poweroff_noirq : pm->poweroff;
-		break;
-	case PM_EVENT_RESUME:
-		callback = noirq ? pm->resume_noirq : pm->resume;
-		break;
-	case PM_EVENT_THAW:
-		callback = noirq ? pm->thaw_noirq : pm->thaw;
-		break;
-	case PM_EVENT_RESTORE:
-		callback = noirq ? pm->restore_noirq : pm->restore;
-		break;
-	default:
-		callback = NULL;
-		break;
-	}
 
-	return callback ? callback(dev) : 0;
+	return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0;
 }
+EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
 
 /**
- * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems.
+ * pm_generic_suspend_late - Generic suspend_late callback for subsystems.
  * @dev: Device to suspend.
  */
-int pm_generic_suspend_noirq(struct device *dev)
+int pm_generic_suspend_late(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_SUSPEND, true);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->suspend_late ? pm->suspend_late(dev) : 0;
 }
-EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
+EXPORT_SYMBOL_GPL(pm_generic_suspend_late);
 
 /**
  * pm_generic_suspend - Generic suspend callback for subsystems.
@@ -152,7 +121,9 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq);
  */
 int pm_generic_suspend(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_SUSPEND, false);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->suspend ? pm->suspend(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_suspend);
 
@@ -162,17 +133,33 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend);
  */
 int pm_generic_freeze_noirq(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_FREEZE, true);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq);
 
 /**
+ * pm_generic_freeze_late - Generic freeze_late callback for subsystems.
+ * @dev: Device to freeze.
+ */
+int pm_generic_freeze_late(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->freeze_late ? pm->freeze_late(dev) : 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_freeze_late);
+
+/**
  * pm_generic_freeze - Generic freeze callback for subsystems.
  * @dev: Device to freeze.
  */
 int pm_generic_freeze(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_FREEZE, false);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->freeze ? pm->freeze(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_freeze);
 
@@ -182,17 +169,33 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze);
  */
 int pm_generic_poweroff_noirq(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_HIBERNATE, true);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq);
 
 /**
+ * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems.
+ * @dev: Device to handle.
+ */
+int pm_generic_poweroff_late(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_poweroff_late);
+
+/**
  * pm_generic_poweroff - Generic poweroff callback for subsystems.
  * @dev: Device to handle.
  */
 int pm_generic_poweroff(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_HIBERNATE, false);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->poweroff ? pm->poweroff(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_poweroff);
 
@@ -202,17 +205,33 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff);
  */
 int pm_generic_thaw_noirq(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_THAW, true);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq);
 
 /**
+ * pm_generic_thaw_early - Generic thaw_early callback for subsystems.
+ * @dev: Device to thaw.
+ */
+int pm_generic_thaw_early(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->thaw_early ? pm->thaw_early(dev) : 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_thaw_early);
+
+/**
  * pm_generic_thaw - Generic thaw callback for subsystems.
  * @dev: Device to thaw.
  */
 int pm_generic_thaw(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_THAW, false);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->thaw ? pm->thaw(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_thaw);
 
@@ -222,17 +241,33 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw);
  */
 int pm_generic_resume_noirq(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_RESUME, true);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_resume_noirq);
 
 /**
+ * pm_generic_resume_early - Generic resume_early callback for subsystems.
+ * @dev: Device to resume.
+ */
+int pm_generic_resume_early(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->resume_early ? pm->resume_early(dev) : 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_resume_early);
+
+/**
  * pm_generic_resume - Generic resume callback for subsystems.
  * @dev: Device to resume.
  */
 int pm_generic_resume(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_RESUME, false);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->resume ? pm->resume(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_resume);
 
@@ -242,17 +277,33 @@ EXPORT_SYMBOL_GPL(pm_generic_resume);
  */
 int pm_generic_restore_noirq(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_RESTORE, true);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_restore_noirq);
 
 /**
+ * pm_generic_restore_early - Generic restore_early callback for subsystems.
+ * @dev: Device to resume.
+ */
+int pm_generic_restore_early(struct device *dev)
+{
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->restore_early ? pm->restore_early(dev) : 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_restore_early);
+
+/**
  * pm_generic_restore - Generic restore callback for subsystems.
  * @dev: Device to restore.
  */
 int pm_generic_restore(struct device *dev)
 {
-	return __pm_generic_call(dev, PM_EVENT_RESTORE, false);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+	return pm && pm->restore ? pm->restore(dev) : 0;
 }
 EXPORT_SYMBOL_GPL(pm_generic_restore);
 
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index e2cc3d2..b462c0e 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -47,6 +47,7 @@ typedef int (*pm_callback_t)(struct device *);
 LIST_HEAD(dpm_list);
 LIST_HEAD(dpm_prepared_list);
 LIST_HEAD(dpm_suspended_list);
+LIST_HEAD(dpm_late_early_list);
 LIST_HEAD(dpm_noirq_list);
 
 struct suspend_stats suspend_stats;
@@ -246,6 +247,40 @@ static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state)
 }
 
 /**
+ * pm_late_early_op - Return the PM operation appropriate for given PM event.
+ * @ops: PM operations to choose from.
+ * @state: PM transition of the system being carried out.
+ *
+ * Runtime PM is disabled for @dev while this function is being executed.
+ */
+static pm_callback_t pm_late_early_op(const struct dev_pm_ops *ops,
+				      pm_message_t state)
+{
+	switch (state.event) {
+#ifdef CONFIG_SUSPEND
+	case PM_EVENT_SUSPEND:
+		return ops->suspend_late;
+	case PM_EVENT_RESUME:
+		return ops->resume_early;
+#endif /* CONFIG_SUSPEND */
+#ifdef CONFIG_HIBERNATE_CALLBACKS
+	case PM_EVENT_FREEZE:
+	case PM_EVENT_QUIESCE:
+		return ops->freeze_late;
+	case PM_EVENT_HIBERNATE:
+		return ops->poweroff_late;
+	case PM_EVENT_THAW:
+	case PM_EVENT_RECOVER:
+		return ops->thaw_early;
+	case PM_EVENT_RESTORE:
+		return ops->restore_early;
+#endif /* CONFIG_HIBERNATE_CALLBACKS */
+	}
+
+	return NULL;
+}
+
+/**
  * pm_noirq_op - Return the PM operation appropriate for given PM event.
  * @ops: PM operations to choose from.
  * @state: PM transition of the system being carried out.
@@ -374,21 +409,21 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
 	TRACE_RESUME(0);
 
 	if (dev->pm_domain) {
-		info = "EARLY power domain ";
+		info = "noirq power domain ";
 		callback = pm_noirq_op(&dev->pm_domain->ops, state);
 	} else if (dev->type && dev->type->pm) {
-		info = "EARLY type ";
+		info = "noirq type ";
 		callback = pm_noirq_op(dev->type->pm, state);
 	} else if (dev->class && dev->class->pm) {
-		info = "EARLY class ";
+		info = "noirq class ";
 		callback = pm_noirq_op(dev->class->pm, state);
 	} else if (dev->bus && dev->bus->pm) {
-		info = "EARLY bus ";
+		info = "noirq bus ";
 		callback = pm_noirq_op(dev->bus->pm, state);
 	}
 
 	if (!callback && dev->driver && dev->driver->pm) {
-		info = "EARLY driver ";
+		info = "noirq driver ";
 		callback = pm_noirq_op(dev->driver->pm, state);
 	}
 
@@ -399,13 +434,13 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
 }
 
 /**
- * dpm_resume_noirq - Execute "early resume" callbacks for non-sysdev devices.
+ * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices.
  * @state: PM transition of the system being carried out.
  *
- * Call the "noirq" resume handlers for all devices marked as DPM_OFF_IRQ and
+ * Call the "noirq" resume handlers for all devices in dpm_noirq_list and
  * enable device drivers to receive interrupts.
  */
-void dpm_resume_noirq(pm_message_t state)
+static void dpm_resume_noirq(pm_message_t state)
 {
 	ktime_t starttime = ktime_get();
 
@@ -415,7 +450,7 @@ void dpm_resume_noirq(pm_message_t state)
 		int error;
 
 		get_device(dev);
-		list_move_tail(&dev->power.entry, &dpm_suspended_list);
+		list_move_tail(&dev->power.entry, &dpm_late_early_list);
 		mutex_unlock(&dpm_list_mtx);
 
 		error = device_resume_noirq(dev, state);
@@ -423,6 +458,80 @@ void dpm_resume_noirq(pm_message_t state)
 			suspend_stats.failed_resume_noirq++;
 			dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
 			dpm_save_failed_dev(dev_name(dev));
+			pm_dev_err(dev, state, " noirq", error);
+		}
+
+		mutex_lock(&dpm_list_mtx);
+		put_device(dev);
+	}
+	mutex_unlock(&dpm_list_mtx);
+	dpm_show_time(starttime, state, "noirq");
+	resume_device_irqs();
+}
+
+/**
+ * device_resume_early - Execute an "early resume" callback for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
+ *
+ * Runtime PM is disabled for @dev while this function is being executed.
+ */
+static int device_resume_early(struct device *dev, pm_message_t state)
+{
+	pm_callback_t callback = NULL;
+	char *info = NULL;
+	int error = 0;
+
+	TRACE_DEVICE(dev);
+	TRACE_RESUME(0);
+
+	if (dev->pm_domain) {
+		info = "early power domain ";
+		callback = pm_late_early_op(&dev->pm_domain->ops, state);
+	} else if (dev->type && dev->type->pm) {
+		info = "early type ";
+		callback = pm_late_early_op(dev->type->pm, state);
+	} else if (dev->class && dev->class->pm) {
+		info = "early class ";
+		callback = pm_late_early_op(dev->class->pm, state);
+	} else if (dev->bus && dev->bus->pm) {
+		info = "early bus ";
+		callback = pm_late_early_op(dev->bus->pm, state);
+	}
+
+	if (!callback && dev->driver && dev->driver->pm) {
+		info = "early driver ";
+		callback = pm_late_early_op(dev->driver->pm, state);
+	}
+
+	error = dpm_run_callback(callback, dev, state, info);
+
+	TRACE_RESUME(error);
+	return error;
+}
+
+/**
+ * dpm_resume_early - Execute "early resume" callbacks for all devices.
+ * @state: PM transition of the system being carried out.
+ */
+static void dpm_resume_early(pm_message_t state)
+{
+	ktime_t starttime = ktime_get();
+
+	mutex_lock(&dpm_list_mtx);
+	while (!list_empty(&dpm_late_early_list)) {
+		struct device *dev = to_device(dpm_late_early_list.next);
+		int error;
+
+		get_device(dev);
+		list_move_tail(&dev->power.entry, &dpm_suspended_list);
+		mutex_unlock(&dpm_list_mtx);
+
+		error = device_resume_early(dev, state);
+		if (error) {
+			suspend_stats.failed_resume_early++;
+			dpm_save_failed_step(SUSPEND_RESUME_EARLY);
+			dpm_save_failed_dev(dev_name(dev));
 			pm_dev_err(dev, state, " early", error);
 		}
 
@@ -431,9 +540,18 @@ void dpm_resume_noirq(pm_message_t state)
 	}
 	mutex_unlock(&dpm_list_mtx);
 	dpm_show_time(starttime, state, "early");
-	resume_device_irqs();
 }
-EXPORT_SYMBOL_GPL(dpm_resume_noirq);
+
+/**
+ * dpm_resume_start - Execute "noirq" and "early" device callbacks.
+ * @state: PM transition of the system being carried out.
+ */
+void dpm_resume_start(pm_message_t state)
+{
+	dpm_resume_noirq(state);
+	dpm_resume_early(state);
+}
+EXPORT_SYMBOL_GPL(dpm_resume_start);
 
 /**
  * device_resume - Execute "resume" callbacks for given device.
@@ -716,21 +834,21 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
 	char *info = NULL;
 
 	if (dev->pm_domain) {
-		info = "LATE power domain ";
+		info = "noirq power domain ";
 		callback = pm_noirq_op(&dev->pm_domain->ops, state);
 	} else if (dev->type && dev->type->pm) {
-		info = "LATE type ";
+		info = "noirq type ";
 		callback = pm_noirq_op(dev->type->pm, state);
 	} else if (dev->class && dev->class->pm) {
-		info = "LATE class ";
+		info = "noirq class ";
 		callback = pm_noirq_op(dev->class->pm, state);
 	} else if (dev->bus && dev->bus->pm) {
-		info = "LATE bus ";
+		info = "noirq bus ";
 		callback = pm_noirq_op(dev->bus->pm, state);
 	}
 
 	if (!callback && dev->driver && dev->driver->pm) {
-		info = "LATE driver ";
+		info = "noirq driver ";
 		callback = pm_noirq_op(dev->driver->pm, state);
 	}
 
@@ -738,21 +856,21 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
 }
 
 /**
- * dpm_suspend_noirq - Execute "late suspend" callbacks for non-sysdev devices.
+ * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices.
  * @state: PM transition of the system being carried out.
  *
  * Prevent device drivers from receiving interrupts and call the "noirq" suspend
  * handlers for all non-sysdev devices.
  */
-int dpm_suspend_noirq(pm_message_t state)
+static int dpm_suspend_noirq(pm_message_t state)
 {
 	ktime_t starttime = ktime_get();
 	int error = 0;
 
 	suspend_device_irqs();
 	mutex_lock(&dpm_list_mtx);
-	while (!list_empty(&dpm_suspended_list)) {
-		struct device *dev = to_device(dpm_suspended_list.prev);
+	while (!list_empty(&dpm_late_early_list)) {
+		struct device *dev = to_device(dpm_late_early_list.prev);
 
 		get_device(dev);
 		mutex_unlock(&dpm_list_mtx);
@@ -761,7 +879,7 @@ int dpm_suspend_noirq(pm_message_t state)
 
 		mutex_lock(&dpm_list_mtx);
 		if (error) {
-			pm_dev_err(dev, state, " late", error);
+			pm_dev_err(dev, state, " noirq", error);
 			suspend_stats.failed_suspend_noirq++;
 			dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ);
 			dpm_save_failed_dev(dev_name(dev));
@@ -776,10 +894,95 @@ int dpm_suspend_noirq(pm_message_t state)
 	if (error)
 		dpm_resume_noirq(resume_event(state));
 	else
+		dpm_show_time(starttime, state, "noirq");
+	return error;
+}
+
+/**
+ * device_suspend_late - Execute a "late suspend" callback for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
+ *
+ * Runtime PM is disabled for @dev while this function is being executed.
+ */
+static int device_suspend_late(struct device *dev, pm_message_t state)
+{
+	pm_callback_t callback = NULL;
+	char *info = NULL;
+
+	if (dev->pm_domain) {
+		info = "late power domain ";
+		callback = pm_late_early_op(&dev->pm_domain->ops, state);
+	} else if (dev->type && dev->type->pm) {
+		info = "late type ";
+		callback = pm_late_early_op(dev->type->pm, state);
+	} else if (dev->class && dev->class->pm) {
+		info = "late class ";
+		callback = pm_late_early_op(dev->class->pm, state);
+	} else if (dev->bus && dev->bus->pm) {
+		info = "late bus ";
+		callback = pm_late_early_op(dev->bus->pm, state);
+	}
+
+	if (!callback && dev->driver && dev->driver->pm) {
+		info = "late driver ";
+		callback = pm_late_early_op(dev->driver->pm, state);
+	}
+
+	return dpm_run_callback(callback, dev, state, info);
+}
+
+/**
+ * dpm_suspend_late - Execute "late suspend" callbacks for all devices.
+ * @state: PM transition of the system being carried out.
+ */
+static int dpm_suspend_late(pm_message_t state)
+{
+	ktime_t starttime = ktime_get();
+	int error = 0;
+
+	mutex_lock(&dpm_list_mtx);
+	while (!list_empty(&dpm_suspended_list)) {
+		struct device *dev = to_device(dpm_suspended_list.prev);
+
+		get_device(dev);
+		mutex_unlock(&dpm_list_mtx);
+
+		error = device_suspend_late(dev, state);
+
+		mutex_lock(&dpm_list_mtx);
+		if (error) {
+			pm_dev_err(dev, state, " late", error);
+			suspend_stats.failed_suspend_late++;
+			dpm_save_failed_step(SUSPEND_SUSPEND_LATE);
+			dpm_save_failed_dev(dev_name(dev));
+			put_device(dev);
+			break;
+		}
+		if (!list_empty(&dev->power.entry))
+			list_move(&dev->power.entry, &dpm_late_early_list);
+		put_device(dev);
+	}
+	mutex_unlock(&dpm_list_mtx);
+	if (error)
+		dpm_resume_early(resume_event(state));
+	else
 		dpm_show_time(starttime, state, "late");
+
 	return error;
 }
-EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
+
+/**
+ * dpm_suspend_end - Execute "late" and "noirq" device suspend callbacks.
+ * @state: PM transition of the system being carried out.
+ */
+int dpm_suspend_end(pm_message_t state)
+{
+	int error = dpm_suspend_late(state);
+
+	return error ? : dpm_suspend_noirq(state);
+}
+EXPORT_SYMBOL_GPL(dpm_suspend_end);
 
 /**
  * legacy_suspend - Execute a legacy (bus or class) suspend callback for device.
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
index caf995f..7c5ab70 100644
--- a/drivers/base/power/wakeup.c
+++ b/drivers/base/power/wakeup.c
@@ -64,7 +64,6 @@ struct wakeup_source *wakeup_source_create(const char *name)
 	if (!ws)
 		return NULL;
 
-	spin_lock_init(&ws->lock);
 	if (name)
 		ws->name = kstrdup(name, GFP_KERNEL);
 
@@ -75,22 +74,17 @@ EXPORT_SYMBOL_GPL(wakeup_source_create);
 /**
  * wakeup_source_destroy - Destroy a struct wakeup_source object.
  * @ws: Wakeup source to destroy.
+ *
+ * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never
+ * be run in parallel with this function for the same wakeup source object.
  */
 void wakeup_source_destroy(struct wakeup_source *ws)
 {
 	if (!ws)
 		return;
 
-	spin_lock_irq(&ws->lock);
-	while (ws->active) {
-		spin_unlock_irq(&ws->lock);
-
-		schedule_timeout_interruptible(msecs_to_jiffies(TIMEOUT));
-
-		spin_lock_irq(&ws->lock);
-	}
-	spin_unlock_irq(&ws->lock);
-
+	del_timer_sync(&ws->timer);
+	__pm_relax(ws);
 	kfree(ws->name);
 	kfree(ws);
 }
@@ -105,6 +99,7 @@ void wakeup_source_add(struct wakeup_source *ws)
 	if (WARN_ON(!ws))
 		return;
 
+	spin_lock_init(&ws->lock);
 	setup_timer(&ws->timer, pm_wakeup_timer_fn, (unsigned long)ws);
 	ws->active = false;
 
@@ -349,7 +344,6 @@ static void wakeup_source_activate(struct wakeup_source *ws)
 {
 	ws->active = true;
 	ws->active_count++;
-	ws->timer_expires = jiffies;
 	ws->last_time = ktime_get();
 
 	/* Increment the counter of events in progress. */
@@ -370,9 +364,14 @@ void __pm_stay_awake(struct wakeup_source *ws)
 		return;
 
 	spin_lock_irqsave(&ws->lock, flags);
+
 	ws->event_count++;
 	if (!ws->active)
 		wakeup_source_activate(ws);
+
+	del_timer(&ws->timer);
+	ws->timer_expires = 0;
+
 	spin_unlock_irqrestore(&ws->lock, flags);
 }
 EXPORT_SYMBOL_GPL(__pm_stay_awake);
@@ -438,6 +437,7 @@ static void wakeup_source_deactivate(struct wakeup_source *ws)
 		ws->max_time = duration;
 
 	del_timer(&ws->timer);
+	ws->timer_expires = 0;
 
 	/*
 	 * Increment the counter of registered wakeup events and decrement the
@@ -492,11 +492,22 @@ EXPORT_SYMBOL_GPL(pm_relax);
  * pm_wakeup_timer_fn - Delayed finalization of a wakeup event.
  * @data: Address of the wakeup source object associated with the event source.
  *
- * Call __pm_relax() for the wakeup source whose address is stored in @data.
+ * Call wakeup_source_deactivate() for the wakeup source whose address is stored
+ * in @data if it is currently active and its timer has not been canceled and
+ * the expiration time of the timer is not in future.
  */
 static void pm_wakeup_timer_fn(unsigned long data)
 {
-	__pm_relax((struct wakeup_source *)data);
+	struct wakeup_source *ws = (struct wakeup_source *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ws->lock, flags);
+
+	if (ws->active && ws->timer_expires
+	    && time_after_eq(jiffies, ws->timer_expires))
+		wakeup_source_deactivate(ws);
+
+	spin_unlock_irqrestore(&ws->lock, flags);
 }
 
 /**
@@ -534,7 +545,7 @@ void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec)
 	if (!expires)
 		expires = 1;
 
-	if (time_after(expires, ws->timer_expires)) {
+	if (!ws->timer_expires || time_after(expires, ws->timer_expires)) {
 		mod_timer(&ws->timer, expires);
 		ws->timer_expires = expires;
 	}
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 1a02b75..abd7667 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -22,6 +22,7 @@ struct regcache_ops;
 struct regmap_format {
 	size_t buf_size;
 	size_t reg_bytes;
+	size_t pad_bytes;
 	size_t val_bytes;
 	void (*format_write)(struct regmap *map,
 			     unsigned int reg, unsigned int val);
@@ -65,16 +66,19 @@ struct regmap {
 	unsigned int num_reg_defaults_raw;
 
 	/* if set, only the cache is modified not the HW */
-	unsigned int cache_only:1;
+	u32 cache_only;
 	/* if set, only the HW is modified not the cache */
-	unsigned int cache_bypass:1;
+	u32 cache_bypass;
 	/* if set, remember to free reg_defaults_raw */
-	unsigned int cache_free:1;
+	bool cache_free;
 
 	struct reg_default *reg_defaults;
 	const void *reg_defaults_raw;
 	void *cache;
-	bool cache_dirty;
+	u32 cache_dirty;
+
+	struct reg_default *patch;
+	int patch_regs;
 };
 
 struct regcache_ops {
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index d1daa5e..fe8c9bb 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -35,12 +35,17 @@ static int regcache_hw_init(struct regmap *map)
 		return -EINVAL;
 
 	if (!map->reg_defaults_raw) {
+		u32 cache_bypass = map->cache_bypass;
 		dev_warn(map->dev, "No cache defaults, reading back from HW\n");
+
+		/* Bypass the cache access till data read from HW*/
+		map->cache_bypass = 1;
 		tmp_buf = kmalloc(map->cache_size_raw, GFP_KERNEL);
 		if (!tmp_buf)
 			return -EINVAL;
 		ret = regmap_bulk_read(map, 0, tmp_buf,
 				       map->num_reg_defaults_raw);
+		map->cache_bypass = cache_bypass;
 		if (ret < 0) {
 			kfree(tmp_buf);
 			return ret;
@@ -211,7 +216,6 @@ int regcache_read(struct regmap *map,
 
 	return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(regcache_read);
 
 /**
  * regcache_write: Set the value of a given register in the cache.
@@ -238,7 +242,6 @@ int regcache_write(struct regmap *map,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(regcache_write);
 
 /**
  * regcache_sync: Sync the register cache with the hardware.
@@ -268,8 +271,22 @@ int regcache_sync(struct regmap *map)
 		map->cache_ops->name);
 	name = map->cache_ops->name;
 	trace_regcache_sync(map->dev, name, "start");
+
 	if (!map->cache_dirty)
 		goto out;
+
+	/* Apply any patch first */
+	map->cache_bypass = 1;
+	for (i = 0; i < map->patch_regs; i++) {
+		ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def);
+		if (ret != 0) {
+			dev_err(map->dev, "Failed to write %x = %x: %d\n",
+				map->patch[i].reg, map->patch[i].def, ret);
+			goto out;
+		}
+	}
+	map->cache_bypass = 0;
+
 	if (map->cache_ops->sync) {
 		ret = map->cache_ops->sync(map);
 	} else {
@@ -374,10 +391,16 @@ bool regcache_set_val(void *base, unsigned int idx,
 		cache[idx] = val;
 		break;
 	}
+	case 4: {
+		u32 *cache = base;
+		if (cache[idx] == val)
+			return true;
+		cache[idx] = val;
+		break;
+	}
 	default:
 		BUG();
 	}
-	/* unreachable */
 	return false;
 }
 
@@ -396,6 +419,10 @@ unsigned int regcache_get_val(const void *base, unsigned int idx,
 		const u16 *cache = base;
 		return cache[idx];
 	}
+	case 4: {
+		const u32 *cache = base;
+		return cache[idx];
+	}
 	default:
 		BUG();
 	}
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c
index 6f39747..b3b4b8f 100644
--- a/drivers/base/regmap/regmap-debugfs.c
+++ b/drivers/base/regmap/regmap-debugfs.c
@@ -192,6 +192,15 @@ void regmap_debugfs_init(struct regmap *map)
 		debugfs_create_file("access", 0400, map->debugfs,
 				    map, &regmap_access_fops);
 	}
+
+	if (map->cache_type) {
+		debugfs_create_bool("cache_only", 0400, map->debugfs,
+				    &map->cache_only);
+		debugfs_create_bool("cache_dirty", 0400, map->debugfs,
+				    &map->cache_dirty);
+		debugfs_create_bool("cache_bypass", 0400, map->debugfs,
+				    &map->cache_bypass);
+	}
 }
 
 void regmap_debugfs_exit(struct regmap *map)
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 38621ec..9a3a8c5 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -111,4 +111,21 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c,
 }
 EXPORT_SYMBOL_GPL(regmap_init_i2c);
 
+/**
+ * devm_regmap_init_i2c(): Initialise managed register map
+ *
+ * @i2c: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
+				    const struct regmap_config *config)
+{
+	return devm_regmap_init(&i2c->dev, &regmap_i2c, config);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c
index 2560658..7c0c35a 100644
--- a/drivers/base/regmap/regmap-spi.c
+++ b/drivers/base/regmap/regmap-spi.c
@@ -70,4 +70,21 @@ struct regmap *regmap_init_spi(struct spi_device *spi,
 }
 EXPORT_SYMBOL_GPL(regmap_init_spi);
 
+/**
+ * devm_regmap_init_spi(): Initialise register map
+ *
+ * @spi: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The map will be automatically freed by the
+ * device management code.
+ */
+struct regmap *devm_regmap_init_spi(struct spi_device *spi,
+				    const struct regmap_config *config)
+{
+	return devm_regmap_init(&spi->dev, &regmap_spi, config);
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init_spi);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6555803..e146b02 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -36,6 +36,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
 	if (map->max_register && reg > map->max_register)
 		return false;
 
+	if (map->format.format_write)
+		return false;
+
 	if (map->readable_reg)
 		return map->readable_reg(map->dev, reg);
 
@@ -44,7 +47,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
 
 bool regmap_volatile(struct regmap *map, unsigned int reg)
 {
-	if (map->max_register && reg > map->max_register)
+	if (!regmap_readable(map, reg))
 		return false;
 
 	if (map->volatile_reg)
@@ -55,7 +58,7 @@ bool regmap_volatile(struct regmap *map, unsigned int reg)
 
 bool regmap_precious(struct regmap *map, unsigned int reg)
 {
-	if (map->max_register && reg > map->max_register)
+	if (!regmap_readable(map, reg))
 		return false;
 
 	if (map->precious_reg)
@@ -76,6 +79,14 @@ static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
 	return true;
 }
 
+static void regmap_format_2_6_write(struct regmap *map,
+				     unsigned int reg, unsigned int val)
+{
+	u8 *out = map->work_buf;
+
+	*out = (reg << 6) | val;
+}
+
 static void regmap_format_4_12_write(struct regmap *map,
 				     unsigned int reg, unsigned int val)
 {
@@ -114,6 +125,13 @@ static void regmap_format_16(void *buf, unsigned int val)
 	b[0] = cpu_to_be16(val);
 }
 
+static void regmap_format_32(void *buf, unsigned int val)
+{
+	__be32 *b = buf;
+
+	b[0] = cpu_to_be32(val);
+}
+
 static unsigned int regmap_parse_8(void *buf)
 {
 	u8 *b = buf;
@@ -130,6 +148,15 @@ static unsigned int regmap_parse_16(void *buf)
 	return b[0];
 }
 
+static unsigned int regmap_parse_32(void *buf)
+{
+	__be32 *b = buf;
+
+	b[0] = be32_to_cpu(b[0]);
+
+	return b[0];
+}
+
 /**
  * regmap_init(): Initialise register map
  *
@@ -159,8 +186,10 @@ struct regmap *regmap_init(struct device *dev,
 
 	mutex_init(&map->lock);
 	map->format.buf_size = (config->reg_bits + config->val_bits) / 8;
-	map->format.reg_bytes = config->reg_bits / 8;
-	map->format.val_bytes = config->val_bits / 8;
+	map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8);
+	map->format.pad_bytes = config->pad_bits / 8;
+	map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8);
+	map->format.buf_size += map->format.pad_bytes;
 	map->dev = dev;
 	map->bus = bus;
 	map->max_register = config->max_register;
@@ -178,6 +207,16 @@ struct regmap *regmap_init(struct device *dev,
 	}
 
 	switch (config->reg_bits) {
+	case 2:
+		switch (config->val_bits) {
+		case 6:
+			map->format.format_write = regmap_format_2_6_write;
+			break;
+		default:
+			goto err_map;
+		}
+		break;
+
 	case 4:
 		switch (config->val_bits) {
 		case 12:
@@ -216,6 +255,10 @@ struct regmap *regmap_init(struct device *dev,
 		map->format.format_reg = regmap_format_16;
 		break;
 
+	case 32:
+		map->format.format_reg = regmap_format_32;
+		break;
+
 	default:
 		goto err_map;
 	}
@@ -229,13 +272,17 @@ struct regmap *regmap_init(struct device *dev,
 		map->format.format_val = regmap_format_16;
 		map->format.parse_val = regmap_parse_16;
 		break;
+	case 32:
+		map->format.format_val = regmap_format_32;
+		map->format.parse_val = regmap_parse_32;
+		break;
 	}
 
 	if (!map->format.format_write &&
 	    !(map->format.format_reg && map->format.format_val))
 		goto err_map;
 
-	map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL);
+	map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL);
 	if (map->work_buf == NULL) {
 		ret = -ENOMEM;
 		goto err_map;
@@ -258,6 +305,45 @@ err:
 }
 EXPORT_SYMBOL_GPL(regmap_init);
 
+static void devm_regmap_release(struct device *dev, void *res)
+{
+	regmap_exit(*(struct regmap **)res);
+}
+
+/**
+ * devm_regmap_init(): Initialise managed register map
+ *
+ * @dev: Device that will be interacted with
+ * @bus: Bus-specific callbacks to use with device
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  This function should generally not be called
+ * directly, it should be called by bus-specific init functions.  The
+ * map will be automatically freed by the device management code.
+ */
+struct regmap *devm_regmap_init(struct device *dev,
+				const struct regmap_bus *bus,
+				const struct regmap_config *config)
+{
+	struct regmap **ptr, *regmap;
+
+	ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	regmap = regmap_init(dev, bus, config);
+	if (!IS_ERR(regmap)) {
+		*ptr = regmap;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(devm_regmap_init);
+
 /**
  * regmap_reinit_cache(): Reinitialise the current register cache
  *
@@ -276,6 +362,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
 	mutex_lock(&map->lock);
 
 	regcache_exit(map);
+	regmap_debugfs_exit(map);
 
 	map->max_register = config->max_register;
 	map->writeable_reg = config->writeable_reg;
@@ -284,6 +371,8 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config)
 	map->precious_reg = config->precious_reg;
 	map->cache_type = config->cache_type;
 
+	regmap_debugfs_init(map);
+
 	map->cache_bypass = false;
 	map->cache_only = false;
 
@@ -321,6 +410,26 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
 			if (!map->writeable_reg(map->dev, reg + i))
 				return -EINVAL;
 
+	if (!map->cache_bypass && map->format.parse_val) {
+		unsigned int ival;
+		int val_bytes = map->format.val_bytes;
+		for (i = 0; i < val_len / val_bytes; i++) {
+			memcpy(map->work_buf, val + (i * val_bytes), val_bytes);
+			ival = map->format.parse_val(map->work_buf);
+			ret = regcache_write(map, reg + i, ival);
+			if (ret) {
+				dev_err(map->dev,
+				   "Error in caching of register: %u ret: %d\n",
+					reg + i, ret);
+				return ret;
+			}
+		}
+		if (map->cache_only) {
+			map->cache_dirty = true;
+			return 0;
+		}
+	}
+
 	map->format.format_reg(map->work_buf, reg);
 
 	u8[0] |= map->write_flag_mask;
@@ -332,23 +441,28 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
 	 * send the work_buf directly, otherwise try to do a gather
 	 * write.
 	 */
-	if (val == map->work_buf + map->format.reg_bytes)
+	if (val == (map->work_buf + map->format.pad_bytes +
+		    map->format.reg_bytes))
 		ret = map->bus->write(map->dev, map->work_buf,
-				      map->format.reg_bytes + val_len);
+				      map->format.reg_bytes +
+				      map->format.pad_bytes +
+				      val_len);
 	else if (map->bus->gather_write)
 		ret = map->bus->gather_write(map->dev, map->work_buf,
-					     map->format.reg_bytes,
+					     map->format.reg_bytes +
+					     map->format.pad_bytes,
 					     val, val_len);
 
 	/* If that didn't work fall back on linearising by hand. */
 	if (ret == -ENOTSUPP) {
-		len = map->format.reg_bytes + val_len;
-		buf = kmalloc(len, GFP_KERNEL);
+		len = map->format.reg_bytes + map->format.pad_bytes + val_len;
+		buf = kzalloc(len, GFP_KERNEL);
 		if (!buf)
 			return -ENOMEM;
 
 		memcpy(buf, map->work_buf, map->format.reg_bytes);
-		memcpy(buf + map->format.reg_bytes, val, val_len);
+		memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
+		       val, val_len);
 		ret = map->bus->write(map->dev, buf, len);
 
 		kfree(buf);
@@ -366,7 +480,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
 	int ret;
 	BUG_ON(!map->format.format_write && !map->format.format_val);
 
-	if (!map->cache_bypass) {
+	if (!map->cache_bypass && map->format.format_write) {
 		ret = regcache_write(map, reg, val);
 		if (ret != 0)
 			return ret;
@@ -390,10 +504,12 @@ int _regmap_write(struct regmap *map, unsigned int reg,
 
 		return ret;
 	} else {
-		map->format.format_val(map->work_buf + map->format.reg_bytes,
-				       val);
+		map->format.format_val(map->work_buf + map->format.reg_bytes
+				       + map->format.pad_bytes, val);
 		return _regmap_raw_write(map, reg,
-					 map->work_buf + map->format.reg_bytes,
+					 map->work_buf +
+					 map->format.reg_bytes +
+					 map->format.pad_bytes,
 					 map->format.val_bytes);
 	}
 }
@@ -441,12 +557,8 @@ EXPORT_SYMBOL_GPL(regmap_write);
 int regmap_raw_write(struct regmap *map, unsigned int reg,
 		     const void *val, size_t val_len)
 {
-	size_t val_count = val_len / map->format.val_bytes;
 	int ret;
 
-	WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
-		map->cache_type != REGCACHE_NONE);
-
 	mutex_lock(&map->lock);
 
 	ret = _regmap_raw_write(map, reg, val, val_len);
@@ -457,6 +569,56 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(regmap_raw_write);
 
+/*
+ * regmap_bulk_write(): Write multiple registers to the device
+ *
+ * @map: Register map to write to
+ * @reg: First register to be write from
+ * @val: Block of data to be written, in native register size for device
+ * @val_count: Number of registers to write
+ *
+ * This function is intended to be used for writing a large block of
+ * data to be device either in single transfer or multiple transfer.
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
+		     size_t val_count)
+{
+	int ret = 0, i;
+	size_t val_bytes = map->format.val_bytes;
+	void *wval;
+
+	if (!map->format.parse_val)
+		return -EINVAL;
+
+	mutex_lock(&map->lock);
+
+	/* No formatting is require if val_byte is 1 */
+	if (val_bytes == 1) {
+		wval = (void *)val;
+	} else {
+		wval = kmemdup(val, val_count * val_bytes, GFP_KERNEL);
+		if (!wval) {
+			ret = -ENOMEM;
+			dev_err(map->dev, "Error in memory allocation\n");
+			goto out;
+		}
+		for (i = 0; i < val_count * val_bytes; i += val_bytes)
+			map->format.parse_val(wval + i);
+	}
+	ret = _regmap_raw_write(map, reg, wval, val_bytes * val_count);
+
+	if (val_bytes != 1)
+		kfree(wval);
+
+out:
+	mutex_unlock(&map->lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_bulk_write);
+
 static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 			    unsigned int val_len)
 {
@@ -476,7 +638,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 	trace_regmap_hw_read_start(map->dev, reg,
 				   val_len / map->format.val_bytes);
 
-	ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes,
+	ret = map->bus->read(map->dev, map->work_buf,
+			     map->format.reg_bytes + map->format.pad_bytes,
 			     val, val_len);
 
 	trace_regmap_hw_read_done(map->dev, reg,
@@ -549,16 +712,32 @@ EXPORT_SYMBOL_GPL(regmap_read);
 int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 		    size_t val_len)
 {
-	size_t val_count = val_len / map->format.val_bytes;
-	int ret;
-
-	WARN_ON(!regmap_volatile_range(map, reg, val_count) &&
-		map->cache_type != REGCACHE_NONE);
+	size_t val_bytes = map->format.val_bytes;
+	size_t val_count = val_len / val_bytes;
+	unsigned int v;
+	int ret, i;
 
 	mutex_lock(&map->lock);
 
-	ret = _regmap_raw_read(map, reg, val, val_len);
+	if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
+	    map->cache_type == REGCACHE_NONE) {
+		/* Physical block read if there's no cache involved */
+		ret = _regmap_raw_read(map, reg, val, val_len);
 
+	} else {
+		/* Otherwise go word by word for the cache; should be low
+		 * cost as we expect to hit the cache.
+		 */
+		for (i = 0; i < val_count; i++) {
+			ret = _regmap_read(map, reg + i, &v);
+			if (ret != 0)
+				goto out;
+
+			map->format.format_val(val + (i * val_bytes), v);
+		}
+	}
+
+ out:
 	mutex_unlock(&map->lock);
 
 	return ret;
@@ -672,6 +851,79 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(regmap_update_bits_check);
 
+/**
+ * regmap_register_patch: Register and apply register updates to be applied
+ *                        on device initialistion
+ *
+ * @map: Register map to apply updates to.
+ * @regs: Values to update.
+ * @num_regs: Number of entries in regs.
+ *
+ * Register a set of register updates to be applied to the device
+ * whenever the device registers are synchronised with the cache and
+ * apply them immediately.  Typically this is used to apply
+ * corrections to be applied to the device defaults on startup, such
+ * as the updates some vendors provide to undocumented registers.
+ */
+int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
+			  int num_regs)
+{
+	int i, ret;
+	bool bypass;
+
+	/* If needed the implementation can be extended to support this */
+	if (map->patch)
+		return -EBUSY;
+
+	mutex_lock(&map->lock);
+
+	bypass = map->cache_bypass;
+
+	map->cache_bypass = true;
+
+	/* Write out first; it's useful to apply even if we fail later. */
+	for (i = 0; i < num_regs; i++) {
+		ret = _regmap_write(map, regs[i].reg, regs[i].def);
+		if (ret != 0) {
+			dev_err(map->dev, "Failed to write %x = %x: %d\n",
+				regs[i].reg, regs[i].def, ret);
+			goto out;
+		}
+	}
+
+	map->patch = kcalloc(num_regs, sizeof(struct reg_default), GFP_KERNEL);
+	if (map->patch != NULL) {
+		memcpy(map->patch, regs,
+		       num_regs * sizeof(struct reg_default));
+		map->patch_regs = num_regs;
+	} else {
+		ret = -ENOMEM;
+	}
+
+out:
+	map->cache_bypass = bypass;
+
+	mutex_unlock(&map->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_register_patch);
+
+/*
+ * regmap_get_val_bytes(): Report the size of a register value
+ *
+ * Report the size of a register value, mainly intended to for use by
+ * generic infrastructure built on top of regmap.
+ */
+int regmap_get_val_bytes(struct regmap *map)
+{
+	if (map->format.format_write)
+		return -EINVAL;
+
+	return map->format.val_bytes;
+}
+EXPORT_SYMBOL_GPL(regmap_get_val_bytes);
+
 static int __init regmap_initcall(void)
 {
 	regmap_debugfs_initcall();
diff --git a/drivers/base/soc.c b/drivers/base/soc.c
new file mode 100644
index 0000000..05f1503
--- /dev/null
+++ b/drivers/base/soc.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/spinlock.h>
+#include <linux/sys_soc.h>
+#include <linux/err.h>
+
+static DEFINE_IDR(soc_ida);
+static DEFINE_SPINLOCK(soc_lock);
+
+static ssize_t soc_info_get(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf);
+
+struct soc_device {
+	struct device dev;
+	struct soc_device_attribute *attr;
+	int soc_dev_num;
+};
+
+static struct bus_type soc_bus_type = {
+	.name  = "soc",
+};
+
+static DEVICE_ATTR(machine,  S_IRUGO, soc_info_get,  NULL);
+static DEVICE_ATTR(family,   S_IRUGO, soc_info_get,  NULL);
+static DEVICE_ATTR(soc_id,   S_IRUGO, soc_info_get,  NULL);
+static DEVICE_ATTR(revision, S_IRUGO, soc_info_get,  NULL);
+
+struct device *soc_device_to_device(struct soc_device *soc_dev)
+{
+	return &soc_dev->dev;
+}
+
+static mode_t soc_attribute_mode(struct kobject *kobj,
+                                 struct attribute *attr,
+                                 int index)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
+
+	if ((attr == &dev_attr_machine.attr)
+	    && (soc_dev->attr->machine != NULL))
+		return attr->mode;
+	if ((attr == &dev_attr_family.attr)
+	    && (soc_dev->attr->family != NULL))
+		return attr->mode;
+	if ((attr == &dev_attr_revision.attr)
+	    && (soc_dev->attr->revision != NULL))
+		return attr->mode;
+	if ((attr == &dev_attr_soc_id.attr)
+	    && (soc_dev->attr->soc_id != NULL))
+	        return attr->mode;
+
+	/* Unknown or unfilled attribute. */
+	return 0;
+}
+
+static ssize_t soc_info_get(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
+
+	if (attr == &dev_attr_machine)
+		return sprintf(buf, "%s\n", soc_dev->attr->machine);
+	if (attr == &dev_attr_family)
+		return sprintf(buf, "%s\n", soc_dev->attr->family);
+	if (attr == &dev_attr_revision)
+		return sprintf(buf, "%s\n", soc_dev->attr->revision);
+	if (attr == &dev_attr_soc_id)
+		return sprintf(buf, "%s\n", soc_dev->attr->soc_id);
+
+	return -EINVAL;
+
+}
+
+static struct attribute *soc_attr[] = {
+	&dev_attr_machine.attr,
+	&dev_attr_family.attr,
+	&dev_attr_soc_id.attr,
+	&dev_attr_revision.attr,
+	NULL,
+};
+
+static const struct attribute_group soc_attr_group = {
+	.attrs = soc_attr,
+	.is_visible = soc_attribute_mode,
+};
+
+static const struct attribute_group *soc_attr_groups[] = {
+	&soc_attr_group,
+	NULL,
+};
+
+static void soc_release(struct device *dev)
+{
+	struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
+
+	kfree(soc_dev);
+}
+
+struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr)
+{
+	struct soc_device *soc_dev;
+	int ret;
+
+	soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL);
+	if (!soc_dev) {
+	        ret = -ENOMEM;
+		goto out1;
+	}
+
+	/* Fetch a unique (reclaimable) SOC ID. */
+	do {
+		if (!ida_pre_get(&soc_ida, GFP_KERNEL)) {
+			ret = -ENOMEM;
+			goto out2;
+		}
+
+		spin_lock(&soc_lock);
+		ret = ida_get_new(&soc_ida, &soc_dev->soc_dev_num);
+		spin_unlock(&soc_lock);
+
+	} while (ret == -EAGAIN);
+
+	if (ret)
+	         goto out2;
+
+	soc_dev->attr = soc_dev_attr;
+	soc_dev->dev.bus = &soc_bus_type;
+	soc_dev->dev.groups = soc_attr_groups;
+	soc_dev->dev.release = soc_release;
+
+	dev_set_name(&soc_dev->dev, "soc%d", soc_dev->soc_dev_num);
+
+	ret = device_register(&soc_dev->dev);
+	if (ret)
+		goto out3;
+
+	return soc_dev;
+
+out3:
+	ida_remove(&soc_ida, soc_dev->soc_dev_num);
+out2:
+	kfree(soc_dev);
+out1:
+	return ERR_PTR(ret);
+}
+
+/* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */
+void soc_device_unregister(struct soc_device *soc_dev)
+{
+	ida_remove(&soc_ida, soc_dev->soc_dev_num);
+
+	device_unregister(&soc_dev->dev);
+}
+
+static int __init soc_bus_register(void)
+{
+	spin_lock_init(&soc_lock);
+
+	return bus_register(&soc_bus_type);
+}
+core_initcall(soc_bus_register);
+
+static void __exit soc_bus_unregister(void)
+{
+	ida_destroy(&soc_ida);
+
+	bus_unregister(&soc_bus_type);
+}
+module_exit(soc_bus_unregister);
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 0def898..b81755b 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -13,7 +13,7 @@
 struct bcma_bus;
 
 /* main.c */
-int bcma_bus_register(struct bcma_bus *bus);
+int __devinit bcma_bus_register(struct bcma_bus *bus);
 void bcma_bus_unregister(struct bcma_bus *bus);
 int __init bcma_bus_early_register(struct bcma_bus *bus,
 				   struct bcma_device *core_cc,
@@ -48,8 +48,12 @@ extern int __init bcma_host_pci_init(void);
 extern void __exit bcma_host_pci_exit(void);
 #endif /* CONFIG_BCMA_HOST_PCI */
 
+/* driver_pci.c */
+u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
+
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
-void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
+bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
+void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
 
 #endif
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 4fde625..4d38ae1 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -2,8 +2,9 @@
  * Broadcom specific AMBA
  * PCI Core
  *
- * Copyright 2005, Broadcom Corporation
+ * Copyright 2005, 2011, Broadcom Corporation
  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
@@ -16,40 +17,41 @@
  * R/W ops.
  **************************************************/
 
-static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
+u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
 {
-	pcicore_write32(pc, 0x130, address);
-	pcicore_read32(pc, 0x130);
-	return pcicore_read32(pc, 0x134);
+	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
+	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
+	return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
 }
 
 #if 0
 static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
 {
-	pcicore_write32(pc, 0x130, address);
-	pcicore_read32(pc, 0x130);
-	pcicore_write32(pc, 0x134, data);
+	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
+	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
+	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
 }
 #endif
 
 static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 {
-	const u16 mdio_control = 0x128;
-	const u16 mdio_data = 0x12C;
 	u32 v;
 	int i;
 
-	v = (1 << 30); /* Start of Transaction */
-	v |= (1 << 28); /* Write Transaction */
-	v |= (1 << 17); /* Turnaround */
-	v |= (0x1F << 18);
+	v = BCMA_CORE_PCI_MDIODATA_START;
+	v |= BCMA_CORE_PCI_MDIODATA_WRITE;
+	v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
+	      BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
+	v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
+	      BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
+	v |= BCMA_CORE_PCI_MDIODATA_TA;
 	v |= (phy << 4);
-	pcicore_write32(pc, mdio_data, v);
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
 
 	udelay(10);
 	for (i = 0; i < 200; i++) {
-		v = pcicore_read32(pc, mdio_control);
-		if (v & 0x100 /* Trans complete */)
+		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
+		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
 			break;
 		msleep(1);
 	}
@@ -57,79 +59,84 @@ static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
 
 static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
 {
-	const u16 mdio_control = 0x128;
-	const u16 mdio_data = 0x12C;
 	int max_retries = 10;
 	u16 ret = 0;
 	u32 v;
 	int i;
 
-	v = 0x80; /* Enable Preamble Sequence */
-	v |= 0x2; /* MDIO Clock Divisor */
-	pcicore_write32(pc, mdio_control, v);
+	/* enable mdio access to SERDES */
+	v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
+	v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
 
 	if (pc->core->id.rev >= 10) {
 		max_retries = 200;
 		bcma_pcie_mdio_set_phy(pc, device);
+		v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
+		     BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
+	} else {
+		v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
 	}
 
-	v = (1 << 30); /* Start of Transaction */
-	v |= (1 << 29); /* Read Transaction */
-	v |= (1 << 17); /* Turnaround */
-	if (pc->core->id.rev < 10)
-		v |= (u32)device << 22;
-	v |= (u32)address << 18;
-	pcicore_write32(pc, mdio_data, v);
+	v = BCMA_CORE_PCI_MDIODATA_START;
+	v |= BCMA_CORE_PCI_MDIODATA_READ;
+	v |= BCMA_CORE_PCI_MDIODATA_TA;
+
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
 	/* Wait for the device to complete the transaction */
 	udelay(10);
 	for (i = 0; i < max_retries; i++) {
-		v = pcicore_read32(pc, mdio_control);
-		if (v & 0x100 /* Trans complete */) {
+		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
+		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
 			udelay(10);
-			ret = pcicore_read32(pc, mdio_data);
+			ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
 			break;
 		}
 		msleep(1);
 	}
-	pcicore_write32(pc, mdio_control, 0);
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
 	return ret;
 }
 
 static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
 				u8 address, u16 data)
 {
-	const u16 mdio_control = 0x128;
-	const u16 mdio_data = 0x12C;
 	int max_retries = 10;
 	u32 v;
 	int i;
 
-	v = 0x80; /* Enable Preamble Sequence */
-	v |= 0x2; /* MDIO Clock Divisor */
-	pcicore_write32(pc, mdio_control, v);
+	/* enable mdio access to SERDES */
+	v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
+	v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
 
 	if (pc->core->id.rev >= 10) {
 		max_retries = 200;
 		bcma_pcie_mdio_set_phy(pc, device);
+		v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
+		     BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
+	} else {
+		v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
 	}
 
-	v = (1 << 30); /* Start of Transaction */
-	v |= (1 << 28); /* Write Transaction */
-	v |= (1 << 17); /* Turnaround */
-	if (pc->core->id.rev < 10)
-		v |= (u32)device << 22;
-	v |= (u32)address << 18;
+	v = BCMA_CORE_PCI_MDIODATA_START;
+	v |= BCMA_CORE_PCI_MDIODATA_WRITE;
+	v |= BCMA_CORE_PCI_MDIODATA_TA;
 	v |= data;
-	pcicore_write32(pc, mdio_data, v);
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
 	/* Wait for the device to complete the transaction */
 	udelay(10);
 	for (i = 0; i < max_retries; i++) {
-		v = pcicore_read32(pc, mdio_control);
-		if (v & 0x100 /* Trans complete */)
+		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
+		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
 			break;
 		msleep(1);
 	}
-	pcicore_write32(pc, mdio_control, 0);
+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
 }
 
 /**************************************************
@@ -138,72 +145,53 @@ static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
 
 static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
 {
-	return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
+	u32 tmp;
+
+	tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
+	if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
+		return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
+		       BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
+	else
+		return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
 }
 
 static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
 {
-	const u8 serdes_pll_device = 0x1D;
-	const u8 serdes_rx_device = 0x1F;
 	u16 tmp;
 
-	bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
-			      bcma_pcicore_polarity_workaround(pc));
-	tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
-	if (tmp & 0x4000)
-		bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
+	bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
+	                     BCMA_CORE_PCI_SERDES_RX_CTRL,
+			     bcma_pcicore_polarity_workaround(pc));
+	tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
+	                          BCMA_CORE_PCI_SERDES_PLL_CTRL);
+	if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
+		bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
+		                     BCMA_CORE_PCI_SERDES_PLL_CTRL,
+		                     tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
 }
 
 /**************************************************
  * Init.
  **************************************************/
 
-static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
+static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
 {
 	bcma_pcicore_serdes_workaround(pc);
 }
 
-static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
-{
-	struct bcma_bus *bus = pc->core->bus;
-	u16 chipid_top;
-
-	chipid_top = (bus->chipinfo.id & 0xFF00);
-	if (chipid_top != 0x4700 &&
-	    chipid_top != 0x5300)
-		return false;
-
-#ifdef CONFIG_SSB_DRIVER_PCICORE
-	if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
-		return false;
-#endif /* CONFIG_SSB_DRIVER_PCICORE */
-
-#if 0
-	/* TODO: on BCMA we use address from EROM instead of magic formula */
-	u32 tmp;
-	return !mips_busprobe32(tmp, (bus->mmio +
-		(pc->core->core_index * BCMA_CORE_SIZE)));
-#endif
-
-	return true;
-}
-
-void bcma_core_pci_init(struct bcma_drv_pci *pc)
+void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
 {
 	if (pc->setup_done)
 		return;
 
-	if (bcma_core_pci_is_in_hostmode(pc)) {
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+	pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
+	if (pc->hostmode)
 		bcma_core_pci_hostmode_init(pc);
-#else
-		pr_err("Driver compiled without support for hostmode PCI\n");
 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
-	} else {
-		bcma_core_pci_clientmode_init(pc);
-	}
 
-	pc->setup_done = true;
+	if (!pc->hostmode)
+		bcma_core_pci_clientmode_init(pc);
 }
 
 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index eb332b7..4e20bcf 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -2,13 +2,587 @@
  * Broadcom specific AMBA
  * PCI Core in hostmode
  *
+ * Copyright 2005 - 2011, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
+ *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
 
 #include "bcma_private.h"
+#include <linux/export.h>
 #include <linux/bcma/bcma.h>
+#include <asm/paccess.h>
+
+/* Probe a 32bit value on the bus and catch bus exceptions.
+ * Returns nonzero on a bus exception.
+ * This is MIPS specific */
+#define mips_busprobe32(val, addr)	get_dbe((val), ((u32 *)(addr)))
+
+/* Assume one-hot slot wiring */
+#define BCMA_PCI_SLOT_MAX	16
+#define	PCI_CONFIG_SPACE_SIZE	256
+
+bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
+{
+	struct bcma_bus *bus = pc->core->bus;
+	u16 chipid_top;
+	u32 tmp;
+
+	chipid_top = (bus->chipinfo.id & 0xFF00);
+	if (chipid_top != 0x4700 &&
+	    chipid_top != 0x5300)
+		return false;
+
+	if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
+		pr_info("This PCI core is disabled and not working\n");
+		return false;
+	}
+
+	bcma_core_enable(pc->core, 0);
+
+	return !mips_busprobe32(tmp, pc->core->io_addr);
+}
+
+static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
+{
+	pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
+	pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
+	return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
+}
+
+static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
+				   u32 data)
+{
+	pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
+	pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
+	pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
+}
+
+static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
+			     unsigned int func, unsigned int off)
+{
+	u32 addr = 0;
+
+	/* Issue config commands only when the data link is up (atleast
+	 * one external pcie device is present).
+	 */
+	if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
+			  & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
+		goto out;
+
+	/* Type 0 transaction */
+	/* Slide the PCI window to the appropriate slot */
+	pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
+	/* Calculate the address */
+	addr = pc->host_controller->host_cfg_addr;
+	addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
+	addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
+	addr |= (off & ~3);
+
+out:
+	return addr;
+}
 
-void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
+static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
+				  unsigned int func, unsigned int off,
+				  void *buf, int len)
 {
-	pr_err("No support for PCI core in hostmode yet\n");
+	int err = -EINVAL;
+	u32 addr, val;
+	void __iomem *mmio = 0;
+
+	WARN_ON(!pc->hostmode);
+	if (unlikely(len != 1 && len != 2 && len != 4))
+		goto out;
+	if (dev == 0) {
+		/* we support only two functions on device 0 */
+		if (func > 1)
+			return -EINVAL;
+
+		/* accesses to config registers with offsets >= 256
+		 * requires indirect access.
+		 */
+		if (off >= PCI_CONFIG_SPACE_SIZE) {
+			addr = (func << 12);
+			addr |= (off & 0x0FFF);
+			val = bcma_pcie_read_config(pc, addr);
+		} else {
+			addr = BCMA_CORE_PCI_PCICFG0;
+			addr |= (func << 8);
+			addr |= (off & 0xfc);
+			val = pcicore_read32(pc, addr);
+		}
+	} else {
+		addr = bcma_get_cfgspace_addr(pc, dev, func, off);
+		if (unlikely(!addr))
+			goto out;
+		err = -ENOMEM;
+		mmio = ioremap_nocache(addr, len);
+		if (!mmio)
+			goto out;
+
+		if (mips_busprobe32(val, mmio)) {
+			val = 0xffffffff;
+			goto unmap;
+		}
+
+		val = readl(mmio);
+	}
+	val >>= (8 * (off & 3));
+
+	switch (len) {
+	case 1:
+		*((u8 *)buf) = (u8)val;
+		break;
+	case 2:
+		*((u16 *)buf) = (u16)val;
+		break;
+	case 4:
+		*((u32 *)buf) = (u32)val;
+		break;
+	}
+	err = 0;
+unmap:
+	if (mmio)
+		iounmap(mmio);
+out:
+	return err;
+}
+
+static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
+				   unsigned int func, unsigned int off,
+				   const void *buf, int len)
+{
+	int err = -EINVAL;
+	u32 addr = 0, val = 0;
+	void __iomem *mmio = 0;
+	u16 chipid = pc->core->bus->chipinfo.id;
+
+	WARN_ON(!pc->hostmode);
+	if (unlikely(len != 1 && len != 2 && len != 4))
+		goto out;
+	if (dev == 0) {
+		/* accesses to config registers with offsets >= 256
+		 * requires indirect access.
+		 */
+		if (off < PCI_CONFIG_SPACE_SIZE) {
+			addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
+			addr |= (func << 8);
+			addr |= (off & 0xfc);
+			mmio = ioremap_nocache(addr, len);
+			if (!mmio)
+				goto out;
+		}
+	} else {
+		addr = bcma_get_cfgspace_addr(pc, dev, func, off);
+		if (unlikely(!addr))
+			goto out;
+		err = -ENOMEM;
+		mmio = ioremap_nocache(addr, len);
+		if (!mmio)
+			goto out;
+
+		if (mips_busprobe32(val, mmio)) {
+			val = 0xffffffff;
+			goto unmap;
+		}
+	}
+
+	switch (len) {
+	case 1:
+		val = readl(mmio);
+		val &= ~(0xFF << (8 * (off & 3)));
+		val |= *((const u8 *)buf) << (8 * (off & 3));
+		break;
+	case 2:
+		val = readl(mmio);
+		val &= ~(0xFFFF << (8 * (off & 3)));
+		val |= *((const u16 *)buf) << (8 * (off & 3));
+		break;
+	case 4:
+		val = *((const u32 *)buf);
+		break;
+	}
+	if (dev == 0 && !addr) {
+		/* accesses to config registers with offsets >= 256
+		 * requires indirect access.
+		 */
+		addr = (func << 12);
+		addr |= (off & 0x0FFF);
+		bcma_pcie_write_config(pc, addr, val);
+	} else {
+		writel(val, mmio);
+
+		if (chipid == 0x4716 || chipid == 0x4748)
+			readl(mmio);
+	}
+
+	err = 0;
+unmap:
+	if (mmio)
+		iounmap(mmio);
+out:
+	return err;
+}
+
+static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
+					      unsigned int devfn,
+					      int reg, int size, u32 *val)
+{
+	unsigned long flags;
+	int err;
+	struct bcma_drv_pci *pc;
+	struct bcma_drv_pci_host *pc_host;
+
+	pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
+	pc = pc_host->pdev;
+
+	spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
+	err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
+				     PCI_FUNC(devfn), reg, val, size);
+	spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
+
+	return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
+					       unsigned int devfn,
+					       int reg, int size, u32 val)
+{
+	unsigned long flags;
+	int err;
+	struct bcma_drv_pci *pc;
+	struct bcma_drv_pci_host *pc_host;
+
+	pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
+	pc = pc_host->pdev;
+
+	spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
+	err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
+				      PCI_FUNC(devfn), reg, &val, size);
+	spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
+
+	return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+}
+
+/* return cap_offset if requested capability exists in the PCI config space */
+static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
+					     unsigned int dev,
+					     unsigned int func, u8 req_cap_id,
+					     unsigned char *buf, u32 *buflen)
+{
+	u8 cap_id;
+	u8 cap_ptr = 0;
+	u32 bufsize;
+	u8 byte_val;
+
+	/* check for Header type 0 */
+	bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
+				sizeof(u8));
+	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
+		return cap_ptr;
+
+	/* check if the capability pointer field exists */
+	bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
+				sizeof(u8));
+	if (!(byte_val & PCI_STATUS_CAP_LIST))
+		return cap_ptr;
+
+	/* check if the capability pointer is 0x00 */
+	bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
+				sizeof(u8));
+	if (cap_ptr == 0x00)
+		return cap_ptr;
+
+	/* loop thr'u the capability list and see if the requested capabilty
+	 * exists */
+	bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
+	while (cap_id != req_cap_id) {
+		bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
+					sizeof(u8));
+		if (cap_ptr == 0x00)
+			return cap_ptr;
+		bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
+					sizeof(u8));
+	}
+
+	/* found the caller requested capability */
+	if ((buf != NULL) && (buflen != NULL)) {
+		u8 cap_data;
+
+		bufsize = *buflen;
+		if (!bufsize)
+			return cap_ptr;
+
+		*buflen = 0;
+
+		/* copy the cpability data excluding cap ID and next ptr */
+		cap_data = cap_ptr + 2;
+		if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
+			bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
+		*buflen = bufsize;
+		while (bufsize--) {
+			bcma_extpci_read_config(pc, dev, func, cap_data, buf,
+						sizeof(u8));
+			cap_data++;
+			buf++;
+		}
+	}
+
+	return cap_ptr;
+}
+
+/* If the root port is capable of returning Config Request
+ * Retry Status (CRS) Completion Status to software then
+ * enable the feature.
+ */
+static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
+{
+	u8 cap_ptr, root_ctrl, root_cap, dev;
+	u16 val16;
+	int i;
+
+	cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
+					   NULL);
+	root_cap = cap_ptr + PCI_EXP_RTCAP;
+	bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
+	if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
+		/* Enable CRS software visibility */
+		root_ctrl = cap_ptr + PCI_EXP_RTCTL;
+		val16 = PCI_EXP_RTCTL_CRSSVE;
+		bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
+					sizeof(u16));
+
+		/* Initiate a configuration request to read the vendor id
+		 * field of the device function's config space header after
+		 * 100 ms wait time from the end of Reset. If the device is
+		 * not done with its internal initialization, it must at
+		 * least return a completion TLP, with a completion status
+		 * of "Configuration Request Retry Status (CRS)". The root
+		 * complex must complete the request to the host by returning
+		 * a read-data value of 0001h for the Vendor ID field and
+		 * all 1s for any additional bytes included in the request.
+		 * Poll using the config reads for max wait time of 1 sec or
+		 * until we receive the successful completion status. Repeat
+		 * the procedure for all the devices.
+		 */
+		for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
+			for (i = 0; i < 100000; i++) {
+				bcma_extpci_read_config(pc, dev, 0,
+							PCI_VENDOR_ID, &val16,
+							sizeof(val16));
+				if (val16 != 0x1)
+					break;
+				udelay(10);
+			}
+			if (val16 == 0x1)
+				pr_err("PCI: Broken device in slot %d\n", dev);
+		}
+	}
+}
+
+void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
+{
+	struct bcma_bus *bus = pc->core->bus;
+	struct bcma_drv_pci_host *pc_host;
+	u32 tmp;
+	u32 pci_membase_1G;
+	unsigned long io_map_base;
+
+	pr_info("PCIEcore in host mode found\n");
+
+	pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
+	if (!pc_host)  {
+		pr_err("can not allocate memory");
+		return;
+	}
+
+	pc->host_controller = pc_host;
+	pc_host->pci_controller.io_resource = &pc_host->io_resource;
+	pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
+	pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
+	pc_host->pdev = pc;
+
+	pci_membase_1G = BCMA_SOC_PCI_DMA;
+	pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
+
+	pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
+	pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
+
+	pc_host->mem_resource.name = "BCMA PCIcore external memory",
+	pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
+	pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
+	pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
+
+	pc_host->io_resource.name = "BCMA PCIcore external I/O",
+	pc_host->io_resource.start = 0x100;
+	pc_host->io_resource.end = 0x7FF;
+	pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
+
+	/* Reset RC */
+	udelay(3000);
+	pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
+	udelay(1000);
+	pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
+			BCMA_CORE_PCI_CTL_RST_OE);
+
+	/* 64 MB I/O access window. On 4716, use
+	 * sbtopcie0 to access the device registers. We
+	 * can't use address match 2 (1 GB window) region
+	 * as mips can't generate 64-bit address on the
+	 * backplane.
+	 */
+	if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
+		pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
+		pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
+					    BCMA_SOC_PCI_MEM_SZ - 1;
+		pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+				BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
+	} else if (bus->chipinfo.id == 0x5300) {
+		tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
+		tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
+		tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
+		if (pc->core->core_unit == 0) {
+			pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
+			pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
+						    BCMA_SOC_PCI_MEM_SZ - 1;
+			pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
+			pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+					tmp | BCMA_SOC_PCI_MEM);
+		} else if (pc->core->core_unit == 1) {
+			pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
+			pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
+						    BCMA_SOC_PCI_MEM_SZ - 1;
+			pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
+			pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
+			pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+					tmp | BCMA_SOC_PCI1_MEM);
+		}
+	} else
+		pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
+				BCMA_CORE_PCI_SBTOPCI_IO);
+
+	/* 64 MB configuration access window */
+	pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
+
+	/* 1 GB memory access window */
+	pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
+			BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
+
+
+	/* As per PCI Express Base Spec 1.1 we need to wait for
+	 * at least 100 ms from the end of a reset (cold/warm/hot)
+	 * before issuing configuration requests to PCI Express
+	 * devices.
+	 */
+	udelay(100000);
+
+	bcma_core_pci_enable_crs(pc);
+
+	/* Enable PCI bridge BAR0 memory & master access */
+	tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
+
+	/* Enable PCI interrupts */
+	pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
+
+	/* Ok, ready to run, register it to the system.
+	 * The following needs change, if we want to port hostmode
+	 * to non-MIPS platform. */
+	io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
+						     0x04000000);
+	pc_host->pci_controller.io_map_base = io_map_base;
+	set_io_port_base(pc_host->pci_controller.io_map_base);
+	/* Give some time to the PCI controller to configure itself with the new
+	 * values. Not waiting at this point causes crashes of the machine. */
+	mdelay(10);
+	register_pci_controller(&pc_host->pci_controller);
+	return;
+}
+
+/* Early PCI fixup for a device on the PCI-core bridge. */
+static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
+{
+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+		/* This is not a device on the PCI-core bridge. */
+		return;
+	}
+	if (PCI_SLOT(dev->devfn) != 0)
+		return;
+
+	pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
+
+	/* Enable PCI bridge bus mastering and memory space */
+	pci_set_master(dev);
+	if (pcibios_enable_device(dev, ~0) < 0) {
+		pr_err("PCI: BCMA bridge enable failed\n");
+		return;
+	}
+
+	/* Enable PCI bridge BAR1 prefetch and burst */
+	pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
+
+/* Early PCI fixup for all PCI-cores to set the correct memory address. */
+static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
+{
+	struct resource *res;
+	int pos;
+
+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+		/* This is not a device on the PCI-core bridge. */
+		return;
+	}
+	if (PCI_SLOT(dev->devfn) == 0)
+		return;
+
+	pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
+
+	for (pos = 0; pos < 6; pos++) {
+		res = &dev->resource[pos];
+		if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
+			pci_assign_resource(dev, pos);
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
+
+/* This function is called when doing a pci_enable_device().
+ * We must first check if the device is a device on the PCI-core bridge. */
+int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
+{
+	struct bcma_drv_pci_host *pc_host;
+
+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+		/* This is not a device on the PCI-core bridge. */
+		return -ENODEV;
+	}
+	pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
+			       pci_ops);
+
+	pr_info("PCI: Fixing up device %s\n", pci_name(dev));
+
+	/* Fix up interrupt lines */
+	dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
+	return 0;
+}
+EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
+
+/* PCI device IRQ mapping. */
+int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
+{
+	struct bcma_drv_pci_host *pc_host;
+
+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+		/* This is not a device on the PCI-core bridge. */
+		return -ENODEV;
+	}
+
+	pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
+			       pci_ops);
+	return bcma_core_mips_irq(pc_host->pdev->core) + 2;
 }
+EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index f59244e..e3928d6 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -154,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci_ops = {
 	.awrite32	= bcma_host_pci_awrite32,
 };
 
-static int bcma_host_pci_probe(struct pci_dev *dev,
-			     const struct pci_device_id *id)
+static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
+					 const struct pci_device_id *id)
 {
 	struct bcma_bus *bus;
 	int err = -ENOMEM;
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index ec31f7d..b8379b9 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -13,6 +13,12 @@
 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
 MODULE_LICENSE("GPL");
 
+/* contains the number the next bus should get. */
+static unsigned int bcma_bus_next_num = 0;
+
+/* bcma_buses_mutex locks the bcma_bus_next_num */
+static DEFINE_MUTEX(bcma_buses_mutex);
+
 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
 static int bcma_device_probe(struct device *dev);
 static int bcma_device_remove(struct device *dev);
@@ -93,7 +99,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
 
 		core->dev.release = bcma_release_core_dev;
 		core->dev.bus = &bcma_bus_type;
-		dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
+		dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
 
 		switch (bus->hosttype) {
 		case BCMA_HOSTTYPE_PCI:
@@ -132,11 +138,15 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
 	}
 }
 
-int bcma_bus_register(struct bcma_bus *bus)
+int __devinit bcma_bus_register(struct bcma_bus *bus)
 {
 	int err;
 	struct bcma_device *core;
 
+	mutex_lock(&bcma_buses_mutex);
+	bus->num = bcma_bus_next_num++;
+	mutex_unlock(&bcma_buses_mutex);
+
 	/* Scan for devices (cores) */
 	err = bcma_bus_scan(bus);
 	if (err) {
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 3a2f672..f94cccc 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -212,6 +212,17 @@ static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
 	return NULL;
 }
 
+static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
+{
+	struct bcma_device *core;
+
+	list_for_each_entry_reverse(core, &bus->cores, list) {
+		if (core->id.id == coreid)
+			return core;
+	}
+	return NULL;
+}
+
 static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 			      struct bcma_device_id *match, int core_num,
 			      struct bcma_device *core)
@@ -353,6 +364,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 void bcma_init_bus(struct bcma_bus *bus)
 {
 	s32 tmp;
+	struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
 
 	if (bus->init_done)
 		return;
@@ -363,9 +375,12 @@ void bcma_init_bus(struct bcma_bus *bus)
 	bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
 
 	tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
-	bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
-	bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
-	bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+	chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
+	chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
+	chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+	pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
+		chipinfo->id, chipinfo->rev, chipinfo->pkg);
+
 	bus->init_done = true;
 }
 
@@ -392,6 +407,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
 	bcma_scan_switch_core(bus, erombase);
 
 	while (eromptr < eromend) {
+		struct bcma_device *other_core;
 		struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
 		if (!core)
 			return -ENOMEM;
@@ -414,6 +430,8 @@ int bcma_bus_scan(struct bcma_bus *bus)
 
 		core->core_index = core_num++;
 		bus->nr_cores++;
+		other_core = bcma_find_core_reverse(bus, core->id.id);
+		core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
 
 		pr_info("Core %d found: %s "
 			"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 6f230fb..ca77525 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -14,8 +14,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 
-#define SPOFF(offset)	((offset) / sizeof(u16))
-
 /**************************************************
  * R/W ops.
  **************************************************/
@@ -124,10 +122,21 @@ static int bcma_sprom_valid(const u16 *sprom)
  * SPROM extraction.
  **************************************************/
 
+#define SPOFF(offset)	((offset) / sizeof(u16))
+
+#define SPEX(_field, _offset, _mask, _shift)	\
+	bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
+
 static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 {
-	u16 v;
+	u16 v, o;
 	int i;
+	u16 pwr_info_offset[] = {
+		SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
+		SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
+	};
+	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
+			ARRAY_SIZE(bus->sprom.core_pwr_info));
 
 	bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
 		SSB_SPROM_REVISION_REV;
@@ -137,78 +146,111 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 		*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
 	}
 
-	bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
-
-	bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
-	     SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
-	bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
-	     SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
-	bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
-	     SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
-	bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
-	     SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
-
-	bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
-	     SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
-	bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
-	     SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
-	bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
-	     SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
-	bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
-	     SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
-
-	bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
-	     SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
-	bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
-	     SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
-	bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
-	     SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
-	bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
-	     SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
-
-	bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
-	     SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
-	bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
-	     SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
-	bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
-	     SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
-	bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
-	     SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
-
-	bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
-	bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
-	bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
-	bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
-
-	bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
-
-	bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-		SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
-	bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-		SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
-	bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-		SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
-	bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-		SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
-	bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
-		SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
-
-	bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-		SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
-	bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-		SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
-	bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-		SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
-	bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-		SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
-	bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
-		SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
+	SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
+
+	SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
+	     SSB_SPROM4_TXPID2G0_SHIFT);
+	SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
+	     SSB_SPROM4_TXPID2G1_SHIFT);
+	SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
+	     SSB_SPROM4_TXPID2G2_SHIFT);
+	SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
+	     SSB_SPROM4_TXPID2G3_SHIFT);
+
+	SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
+	     SSB_SPROM4_TXPID5GL0_SHIFT);
+	SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
+	     SSB_SPROM4_TXPID5GL1_SHIFT);
+	SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
+	     SSB_SPROM4_TXPID5GL2_SHIFT);
+	SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
+	     SSB_SPROM4_TXPID5GL3_SHIFT);
+
+	SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
+	     SSB_SPROM4_TXPID5G0_SHIFT);
+	SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
+	     SSB_SPROM4_TXPID5G1_SHIFT);
+	SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
+	     SSB_SPROM4_TXPID5G2_SHIFT);
+	SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
+	     SSB_SPROM4_TXPID5G3_SHIFT);
+
+	SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
+	     SSB_SPROM4_TXPID5GH0_SHIFT);
+	SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
+	     SSB_SPROM4_TXPID5GH1_SHIFT);
+	SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
+	     SSB_SPROM4_TXPID5GH2_SHIFT);
+	SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
+	     SSB_SPROM4_TXPID5GH3_SHIFT);
+
+	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
+	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
+	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
+	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
+
+	SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
+
+	/* Extract cores power info info */
+	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
+		o = pwr_info_offset[i];
+		SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+			SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
+		SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+			SSB_SPROM8_2G_MAXP, 0);
+
+		SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
+
+		SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+			SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
+		SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+			SSB_SPROM8_5G_MAXP, 0);
+		SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
+			SSB_SPROM8_5GH_MAXP, 0);
+		SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
+			SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
+
+		SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
+	}
+
+	SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
+	     SSB_SROM8_FEM_TSSIPOS_SHIFT);
+	SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
+	     SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
+	SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
+	     SSB_SROM8_FEM_PDET_RANGE_SHIFT);
+	SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
+	     SSB_SROM8_FEM_TR_ISO_SHIFT);
+	SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
+	     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
+
+	SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
+	     SSB_SROM8_FEM_TSSIPOS_SHIFT);
+	SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
+	     SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
+	SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
+	     SSB_SROM8_FEM_PDET_RANGE_SHIFT);
+	SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
+	     SSB_SROM8_FEM_TR_ISO_SHIFT);
+	SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
+	     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
 }
 
 int bcma_sprom_get(struct bcma_bus *bus)
 {
 	u16 offset;
 	u16 *sprom;
+	u32 sromctrl;
 	int err = 0;
 
 	if (!bus->drv_cc.core)
@@ -217,6 +259,12 @@ int bcma_sprom_get(struct bcma_bus *bus)
 	if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
 		return -ENOENT;
 
+	if (bus->drv_cc.core->id.rev >= 32) {
+		sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
+		if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT))
+			return -ENOENT;
+	}
+
 	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
 			GFP_KERNEL);
 	if (!sprom)
@@ -230,6 +278,7 @@ int bcma_sprom_get(struct bcma_bus *bus)
 	 * TODO: understand this condition and use it */
 	offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
 		BCMA_CC_SPROM_PCIE6;
+	pr_debug("SPROM offset 0x%x\n", offset);
 	bcma_sprom_read(bus, offset, sprom);
 
 	if (bus->chipinfo.id == 0x4331)
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index ec24643..531ceb3 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -242,9 +242,9 @@ static void copy_to_brd(struct brd_device *brd, const void *src,
 	page = brd_lookup_page(brd, sector);
 	BUG_ON(!page);
 
-	dst = kmap_atomic(page, KM_USER1);
+	dst = kmap_atomic(page);
 	memcpy(dst + offset, src, copy);
-	kunmap_atomic(dst, KM_USER1);
+	kunmap_atomic(dst);
 
 	if (copy < n) {
 		src += copy;
@@ -253,9 +253,9 @@ static void copy_to_brd(struct brd_device *brd, const void *src,
 		page = brd_lookup_page(brd, sector);
 		BUG_ON(!page);
 
-		dst = kmap_atomic(page, KM_USER1);
+		dst = kmap_atomic(page);
 		memcpy(dst, src, copy);
-		kunmap_atomic(dst, KM_USER1);
+		kunmap_atomic(dst);
 	}
 }
 
@@ -273,9 +273,9 @@ static void copy_from_brd(void *dst, struct brd_device *brd,
 	copy = min_t(size_t, n, PAGE_SIZE - offset);
 	page = brd_lookup_page(brd, sector);
 	if (page) {
-		src = kmap_atomic(page, KM_USER1);
+		src = kmap_atomic(page);
 		memcpy(dst, src + offset, copy);
-		kunmap_atomic(src, KM_USER1);
+		kunmap_atomic(src);
 	} else
 		memset(dst, 0, copy);
 
@@ -285,9 +285,9 @@ static void copy_from_brd(void *dst, struct brd_device *brd,
 		copy = n - copy;
 		page = brd_lookup_page(brd, sector);
 		if (page) {
-			src = kmap_atomic(page, KM_USER1);
+			src = kmap_atomic(page);
 			memcpy(dst, src, copy);
-			kunmap_atomic(src, KM_USER1);
+			kunmap_atomic(src);
 		} else
 			memset(dst, 0, copy);
 	}
@@ -309,7 +309,7 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page,
 			goto out;
 	}
 
-	mem = kmap_atomic(page, KM_USER0);
+	mem = kmap_atomic(page);
 	if (rw == READ) {
 		copy_from_brd(mem + off, brd, sector, len);
 		flush_dcache_page(page);
@@ -317,7 +317,7 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page,
 		flush_dcache_page(page);
 		copy_to_brd(brd, mem + off, sector, len);
 	}
-	kunmap_atomic(mem, KM_USER0);
+	kunmap_atomic(mem);
 
 out:
 	return err;
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index 912f585..3030201 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -289,25 +289,25 @@ static unsigned int bm_bit_to_page_idx(struct drbd_bitmap *b, u64 bitnr)
 	return page_nr;
 }
 
-static unsigned long *__bm_map_pidx(struct drbd_bitmap *b, unsigned int idx, const enum km_type km)
+static unsigned long *__bm_map_pidx(struct drbd_bitmap *b, unsigned int idx)
 {
 	struct page *page = b->bm_pages[idx];
-	return (unsigned long *) kmap_atomic(page, km);
+	return (unsigned long *) kmap_atomic(page);
 }
 
 static unsigned long *bm_map_pidx(struct drbd_bitmap *b, unsigned int idx)
 {
-	return __bm_map_pidx(b, idx, KM_IRQ1);
+	return __bm_map_pidx(b, idx);
 }
 
-static void __bm_unmap(unsigned long *p_addr, const enum km_type km)
+static void __bm_unmap(unsigned long *p_addr)
 {
-	kunmap_atomic(p_addr, km);
+	kunmap_atomic(p_addr);
 };
 
 static void bm_unmap(unsigned long *p_addr)
 {
-	return __bm_unmap(p_addr, KM_IRQ1);
+	return __bm_unmap(p_addr);
 }
 
 /* long word offset of _bitmap_ sector */
@@ -543,15 +543,15 @@ static unsigned long bm_count_bits(struct drbd_bitmap *b)
 
 	/* all but last page */
 	for (idx = 0; idx < b->bm_number_of_pages - 1; idx++) {
-		p_addr = __bm_map_pidx(b, idx, KM_USER0);
+		p_addr = __bm_map_pidx(b, idx);
 		for (i = 0; i < LWPP; i++)
 			bits += hweight_long(p_addr[i]);
-		__bm_unmap(p_addr, KM_USER0);
+		__bm_unmap(p_addr);
 		cond_resched();
 	}
 	/* last (or only) page */
 	last_word = ((b->bm_bits - 1) & BITS_PER_PAGE_MASK) >> LN2_BPL;
-	p_addr = __bm_map_pidx(b, idx, KM_USER0);
+	p_addr = __bm_map_pidx(b, idx);
 	for (i = 0; i < last_word; i++)
 		bits += hweight_long(p_addr[i]);
 	p_addr[last_word] &= cpu_to_lel(mask);
@@ -559,7 +559,7 @@ static unsigned long bm_count_bits(struct drbd_bitmap *b)
 	/* 32bit arch, may have an unused padding long */
 	if (BITS_PER_LONG == 32 && (last_word & 1) == 0)
 		p_addr[last_word+1] = 0;
-	__bm_unmap(p_addr, KM_USER0);
+	__bm_unmap(p_addr);
 	return bits;
 }
 
@@ -970,11 +970,11 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
 		 * to use pre-allocated page pool */
 		void *src, *dest;
 		page = alloc_page(__GFP_HIGHMEM|__GFP_WAIT);
-		dest = kmap_atomic(page, KM_USER0);
-		src = kmap_atomic(b->bm_pages[page_nr], KM_USER1);
+		dest = kmap_atomic(page);
+		src = kmap_atomic(b->bm_pages[page_nr]);
 		memcpy(dest, src, PAGE_SIZE);
-		kunmap_atomic(src, KM_USER1);
-		kunmap_atomic(dest, KM_USER0);
+		kunmap_atomic(src);
+		kunmap_atomic(dest);
 		bm_store_page_idx(page, page_nr);
 	} else
 		page = b->bm_pages[page_nr];
@@ -1163,7 +1163,7 @@ int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(loc
  * this returns a bit number, NOT a sector!
  */
 static unsigned long __bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo,
-	const int find_zero_bit, const enum km_type km)
+	const int find_zero_bit)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long *p_addr;
@@ -1178,7 +1178,7 @@ static unsigned long __bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo,
 		while (bm_fo < b->bm_bits) {
 			/* bit offset of the first bit in the page */
 			bit_offset = bm_fo & ~BITS_PER_PAGE_MASK;
-			p_addr = __bm_map_pidx(b, bm_bit_to_page_idx(b, bm_fo), km);
+			p_addr = __bm_map_pidx(b, bm_bit_to_page_idx(b, bm_fo));
 
 			if (find_zero_bit)
 				i = find_next_zero_bit_le(p_addr,
@@ -1187,7 +1187,7 @@ static unsigned long __bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo,
 				i = find_next_bit_le(p_addr,
 						PAGE_SIZE*8, bm_fo & BITS_PER_PAGE_MASK);
 
-			__bm_unmap(p_addr, km);
+			__bm_unmap(p_addr);
 			if (i < PAGE_SIZE*8) {
 				bm_fo = bit_offset + i;
 				if (bm_fo >= b->bm_bits)
@@ -1215,7 +1215,7 @@ static unsigned long bm_find_next(struct drbd_conf *mdev,
 	if (BM_DONT_TEST & b->bm_flags)
 		bm_print_lock_info(mdev);
 
-	i = __bm_find_next(mdev, bm_fo, find_zero_bit, KM_IRQ1);
+	i = __bm_find_next(mdev, bm_fo, find_zero_bit);
 
 	spin_unlock_irq(&b->bm_lock);
 	return i;
@@ -1239,13 +1239,13 @@ unsigned long drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo
 unsigned long _drbd_bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo)
 {
 	/* WARN_ON(!(BM_DONT_SET & mdev->b->bm_flags)); */
-	return __bm_find_next(mdev, bm_fo, 0, KM_USER1);
+	return __bm_find_next(mdev, bm_fo, 0);
 }
 
 unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_fo)
 {
 	/* WARN_ON(!(BM_DONT_SET & mdev->b->bm_flags)); */
-	return __bm_find_next(mdev, bm_fo, 1, KM_USER1);
+	return __bm_find_next(mdev, bm_fo, 1);
 }
 
 /* returns number of bits actually changed.
@@ -1273,14 +1273,14 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
 		unsigned int page_nr = bm_bit_to_page_idx(b, bitnr);
 		if (page_nr != last_page_nr) {
 			if (p_addr)
-				__bm_unmap(p_addr, KM_IRQ1);
+				__bm_unmap(p_addr);
 			if (c < 0)
 				bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
 			else if (c > 0)
 				bm_set_page_need_writeout(b->bm_pages[last_page_nr]);
 			changed_total += c;
 			c = 0;
-			p_addr = __bm_map_pidx(b, page_nr, KM_IRQ1);
+			p_addr = __bm_map_pidx(b, page_nr);
 			last_page_nr = page_nr;
 		}
 		if (val)
@@ -1289,7 +1289,7 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
 			c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr));
 	}
 	if (p_addr)
-		__bm_unmap(p_addr, KM_IRQ1);
+		__bm_unmap(p_addr);
 	if (c < 0)
 		bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
 	else if (c > 0)
@@ -1342,13 +1342,13 @@ static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b,
 {
 	int i;
 	int bits;
-	unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_IRQ1);
+	unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr]);
 	for (i = first_word; i < last_word; i++) {
 		bits = hweight_long(paddr[i]);
 		paddr[i] = ~0UL;
 		b->bm_set += BITS_PER_LONG - bits;
 	}
-	kunmap_atomic(paddr, KM_IRQ1);
+	kunmap_atomic(paddr);
 }
 
 /* Same thing as drbd_bm_set_bits,
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index af2a250..abfaaca 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -179,7 +179,7 @@ int drbd_khelper(struct drbd_conf *mdev, char *cmd)
 	dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
 
 	drbd_bcast_ev_helper(mdev, cmd);
-	ret = call_usermodehelper(usermode_helper, argv, envp, 1);
+	ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
 	if (ret)
 		dev_warn(DEV, "helper command: %s %s %s exit code %u (0x%x)\n",
 				usermode_helper, cmd, mb,
@@ -2526,10 +2526,10 @@ void drbd_bcast_ee(struct drbd_conf *mdev,
 
 	page = e->pages;
 	page_chain_for_each(page) {
-		void *d = kmap_atomic(page, KM_USER0);
+		void *d = kmap_atomic(page);
 		unsigned l = min_t(unsigned, len, PAGE_SIZE);
 		memcpy(tl, d, l);
-		kunmap_atomic(d, KM_USER0);
+		kunmap_atomic(d);
 		tl = (unsigned short*)((char*)tl + l);
 		len -= l;
 		if (len == 0)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index cd50435..bbca966 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -93,16 +93,16 @@ static int transfer_none(struct loop_device *lo, int cmd,
 			 struct page *loop_page, unsigned loop_off,
 			 int size, sector_t real_block)
 {
-	char *raw_buf = kmap_atomic(raw_page, KM_USER0) + raw_off;
-	char *loop_buf = kmap_atomic(loop_page, KM_USER1) + loop_off;
+	char *raw_buf = kmap_atomic(raw_page) + raw_off;
+	char *loop_buf = kmap_atomic(loop_page) + loop_off;
 
 	if (cmd == READ)
 		memcpy(loop_buf, raw_buf, size);
 	else
 		memcpy(raw_buf, loop_buf, size);
 
-	kunmap_atomic(loop_buf, KM_USER1);
-	kunmap_atomic(raw_buf, KM_USER0);
+	kunmap_atomic(loop_buf);
+	kunmap_atomic(raw_buf);
 	cond_resched();
 	return 0;
 }
@@ -112,8 +112,8 @@ static int transfer_xor(struct loop_device *lo, int cmd,
 			struct page *loop_page, unsigned loop_off,
 			int size, sector_t real_block)
 {
-	char *raw_buf = kmap_atomic(raw_page, KM_USER0) + raw_off;
-	char *loop_buf = kmap_atomic(loop_page, KM_USER1) + loop_off;
+	char *raw_buf = kmap_atomic(raw_page) + raw_off;
+	char *loop_buf = kmap_atomic(loop_page) + loop_off;
 	char *in, *out, *key;
 	int i, keysize;
 
@@ -130,8 +130,8 @@ static int transfer_xor(struct loop_device *lo, int cmd,
 	for (i = 0; i < size; i++)
 		*out++ = *in++ ^ key[(i & 511) % keysize];
 
-	kunmap_atomic(loop_buf, KM_USER1);
-	kunmap_atomic(raw_buf, KM_USER0);
+	kunmap_atomic(loop_buf);
+	kunmap_atomic(raw_buf);
 	cond_resched();
 	return 0;
 }
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index c1dc4d8..09776da 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -39,7 +39,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/types.h>
-#include <linux/version.h>
 
 #define NVME_Q_DEPTH 1024
 #define SQ_SIZE(depth)		(depth * sizeof(struct nvme_command))
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index d59edea..ba66e44 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -987,14 +987,14 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag
 
 	while (copy_size > 0) {
 		struct bio_vec *src_bvl = bio_iovec_idx(src_bio, seg);
-		void *vfrom = kmap_atomic(src_bvl->bv_page, KM_USER0) +
+		void *vfrom = kmap_atomic(src_bvl->bv_page) +
 			src_bvl->bv_offset + offs;
 		void *vto = page_address(dst_page) + dst_offs;
 		int len = min_t(int, copy_size, src_bvl->bv_len - offs);
 
 		BUG_ON(len < 0);
 		memcpy(vto, vfrom, len);
-		kunmap_atomic(vfrom, KM_USER0);
+		kunmap_atomic(vfrom);
 
 		seg++;
 		offs = 0;
@@ -1019,10 +1019,10 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
 	offs = 0;
 	for (f = 0; f < pkt->frames; f++) {
 		if (bvec[f].bv_page != pkt->pages[p]) {
-			void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset;
+			void *vfrom = kmap_atomic(bvec[f].bv_page) + bvec[f].bv_offset;
 			void *vto = page_address(pkt->pages[p]) + offs;
 			memcpy(vto, vfrom, CD_FRAMESIZE);
-			kunmap_atomic(vfrom, KM_USER0);
+			kunmap_atomic(vfrom);
 			bvec[f].bv_page = pkt->pages[p];
 			bvec[f].bv_offset = offs;
 		} else {
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f00f596..fa945db 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -102,6 +102,8 @@ static struct usb_device_id btusb_table[] = {
 
 	/* Broadcom BCM20702A0 */
 	{ USB_DEVICE(0x0a5c, 0x21e3) },
+	{ USB_DEVICE(0x0a5c, 0x21e6) },
+	{ USB_DEVICE(0x0a5c, 0x21f3) },
 	{ USB_DEVICE(0x413c, 0x8197) },
 
 	{ }	/* Terminating entry */
@@ -726,9 +728,6 @@ static int btusb_send_frame(struct sk_buff *skb)
 		usb_fill_bulk_urb(urb, data->udev, pipe,
 				skb->data, skb->len, btusb_tx_complete, skb);
 
-		if (skb->priority >= HCI_PRIO_MAX - 1)
-			urb->transfer_flags  = URB_ISO_ASAP;
-
 		hdev->stat.acl_tx++;
 		break;
 
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 4364303..f166499 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -603,6 +603,7 @@ source "drivers/s390/char/Kconfig"
 config RAMOOPS
 	tristate "Log panic/oops to a RAM buffer"
 	depends on HAS_IOMEM
+	depends on PSTORE
 	default n
 	help
 	  This enables panic and oops messages to be logged to a circular
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index b427711..962e75d 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -850,6 +850,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
 	.subvendor	= PCI_ANY_ID,			\
 	.subdevice	= PCI_ANY_ID,			\
 	}
+	ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */
 	ID(PCI_DEVICE_ID_INTEL_82443LX_0),
 	ID(PCI_DEVICE_ID_INTEL_82443BX_0),
 	ID(PCI_DEVICE_ID_INTEL_82443GX_0),
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 0833896..c9aeb7f 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -263,16 +263,40 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
 
 static int hpet_open(struct inode *inode, struct file *file)
 {
-	struct hpet_dev *devp;
 	struct hpets *hpetp;
-	int i;
 
 	if (file->f_mode & FMODE_WRITE)
 		return -EINVAL;
 
+	hpetp = hpets;
+	/* starting with timer-neutral instance */
+	file->private_data = &hpetp->hp_dev[hpetp->hp_ntimer];
+
+	return 0;
+}
+
+static int hpet_alloc_timer(struct file *file)
+{
+	struct hpet_dev *devp;
+	struct hpets *hpetp;
+	int i;
+
+	/* once acquired, will remain */
+	devp = file->private_data;
+	if (devp->hd_timer)
+		return 0;
+
 	mutex_lock(&hpet_mutex);
 	spin_lock_irq(&hpet_lock);
 
+	/* check for race acquiring */
+	devp = file->private_data;
+	if (devp->hd_timer) {
+		spin_unlock_irq(&hpet_lock);
+		mutex_unlock(&hpet_mutex);
+		return 0;
+	}
+
 	for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
 		for (i = 0; i < hpetp->hp_ntimer; i++)
 			if (hpetp->hp_dev[i].hd_flags & HPET_OPEN)
@@ -402,6 +426,11 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
 static int hpet_fasync(int fd, struct file *file, int on)
 {
 	struct hpet_dev *devp;
+	int r;
+
+	r = hpet_alloc_timer(file);
+	if (r < 0)
+		return r;
 
 	devp = file->private_data;
 
@@ -420,6 +449,9 @@ static int hpet_release(struct inode *inode, struct file *file)
 	devp = file->private_data;
 	timer = devp->hd_timer;
 
+	if (!timer)
+		goto out;
+
 	spin_lock_irq(&hpet_lock);
 
 	writeq((readq(&timer->hpet_config) & ~Tn_INT_ENB_CNF_MASK),
@@ -444,7 +476,7 @@ static int hpet_release(struct inode *inode, struct file *file)
 
 	if (irq)
 		free_irq(irq, devp);
-
+out:
 	file->private_data = NULL;
 	return 0;
 }
@@ -593,6 +625,9 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg,
 		break;
 	case HPET_IE_ON:
 		return hpet_ioctl_ieon(devp);
+	case HPET_ALLOC_TIMER:
+		/* nothing to do */
+		return 0;
 	default:
 		return -EINVAL;
 	}
@@ -859,7 +894,11 @@ int hpet_alloc(struct hpet_data *hdp)
 		return 0;
 	}
 
-	siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
+	/*
+	 * last hpet_dev will have null timer pointer, gives timer-neutral
+	 * representation of block
+	 */
+	siz = sizeof(struct hpets) + ((hdp->hd_nirqs) *
 				      sizeof(struct hpet_dev));
 
 	hpetp = kzalloc(siz, GFP_KERNEL);
@@ -925,13 +964,16 @@ int hpet_alloc(struct hpet_data *hdp)
 		writeq(mcfg, &hpet->hpet_config);
 	}
 
-	for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer; i++, devp++) {
+	for (i = 0, devp = hpetp->hp_dev; i < hpetp->hp_ntimer + 1;
+	     i++, devp++) {
 		struct hpet_timer __iomem *timer;
 
-		timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
-
 		devp->hd_hpets = hpetp;
 		devp->hd_hpet = hpet;
+		if (i == hpetp->hp_ntimer)
+			continue;
+
+		timer = &hpet->hpet_timers[devp - hpetp->hp_dev];
 		devp->hd_timer = timer;
 
 		/*
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
index 0bc0cb7..de473ef 100644
--- a/drivers/char/hw_random/tx4939-rng.c
+++ b/drivers/char/hw_random/tx4939-rng.c
@@ -115,10 +115,7 @@ static int __init tx4939_rng_probe(struct platform_device *dev)
 	rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
 	if (!rngdev)
 		return -ENOMEM;
-	if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r),
-				     dev_name(&dev->dev)))
-		return -EBUSY;
-	rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
+	rngdev->base = devm_request_and_ioremap(&dev->dev, r);
 	if (!rngdev->base)
 		return -EBUSY;
 
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index cf82fed..e53fc24 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -118,8 +118,8 @@ enum kcs_states {
 #define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH
 
 /* Timeouts in microseconds. */
-#define IBF_RETRY_TIMEOUT 1000000
-#define OBF_RETRY_TIMEOUT 1000000
+#define IBF_RETRY_TIMEOUT 5000000
+#define OBF_RETRY_TIMEOUT 5000000
 #define MAX_ERROR_RETRIES 10
 #define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
 
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 58c0e63..5c1820c 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -46,6 +46,7 @@
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/rcupdate.h>
+#include <linux/interrupt.h>
 
 #define PFX "IPMI message handler: "
 
@@ -53,6 +54,8 @@
 
 static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
 static int ipmi_init_msghandler(void);
+static void smi_recv_tasklet(unsigned long);
+static void handle_new_recv_msgs(ipmi_smi_t intf);
 
 static int initialized;
 
@@ -355,12 +358,15 @@ struct ipmi_smi {
 	int curr_seq;
 
 	/*
-	 * Messages that were delayed for some reason (out of memory,
-	 * for instance), will go in here to be processed later in a
-	 * periodic timer interrupt.
+	 * Messages queued for delivery.  If delivery fails (out of memory
+	 * for instance), They will stay in here to be processed later in a
+	 * periodic timer interrupt.  The tasklet is for handling received
+	 * messages directly from the handler.
 	 */
 	spinlock_t       waiting_msgs_lock;
 	struct list_head waiting_msgs;
+	atomic_t	 watchdog_pretimeouts_to_deliver;
+	struct tasklet_struct recv_tasklet;
 
 	/*
 	 * The list of command receivers that are registered for commands
@@ -493,6 +499,8 @@ static void clean_up_interface_data(ipmi_smi_t intf)
 	struct cmd_rcvr  *rcvr, *rcvr2;
 	struct list_head list;
 
+	tasklet_kill(&intf->recv_tasklet);
+
 	free_smi_msg_list(&intf->waiting_msgs);
 	free_recv_msg_list(&intf->waiting_events);
 
@@ -2786,12 +2794,17 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
 	return;
 }
 
-void ipmi_poll_interface(ipmi_user_t user)
+static void ipmi_poll(ipmi_smi_t intf)
 {
-	ipmi_smi_t intf = user->intf;
-
 	if (intf->handlers->poll)
 		intf->handlers->poll(intf->send_info);
+	/* In case something came in */
+	handle_new_recv_msgs(intf);
+}
+
+void ipmi_poll_interface(ipmi_user_t user)
+{
+	ipmi_poll(user->intf);
 }
 EXPORT_SYMBOL(ipmi_poll_interface);
 
@@ -2860,6 +2873,10 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
 #endif
 	spin_lock_init(&intf->waiting_msgs_lock);
 	INIT_LIST_HEAD(&intf->waiting_msgs);
+	tasklet_init(&intf->recv_tasklet,
+		     smi_recv_tasklet,
+		     (unsigned long) intf);
+	atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
 	spin_lock_init(&intf->events_lock);
 	INIT_LIST_HEAD(&intf->waiting_events);
 	intf->waiting_events_count = 0;
@@ -3622,11 +3639,11 @@ static int handle_bmc_rsp(ipmi_smi_t          intf,
 }
 
 /*
- * Handle a new message.  Return 1 if the message should be requeued,
+ * Handle a received message.  Return 1 if the message should be requeued,
  * 0 if the message should be freed, or -1 if the message should not
  * be freed or requeued.
  */
-static int handle_new_recv_msg(ipmi_smi_t          intf,
+static int handle_one_recv_msg(ipmi_smi_t          intf,
 			       struct ipmi_smi_msg *msg)
 {
 	int requeue;
@@ -3784,12 +3801,72 @@ static int handle_new_recv_msg(ipmi_smi_t          intf,
 	return requeue;
 }
 
+/*
+ * If there are messages in the queue or pretimeouts, handle them.
+ */
+static void handle_new_recv_msgs(ipmi_smi_t intf)
+{
+	struct ipmi_smi_msg  *smi_msg;
+	unsigned long        flags = 0;
+	int                  rv;
+	int                  run_to_completion = intf->run_to_completion;
+
+	/* See if any waiting messages need to be processed. */
+	if (!run_to_completion)
+		spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+	while (!list_empty(&intf->waiting_msgs)) {
+		smi_msg = list_entry(intf->waiting_msgs.next,
+				     struct ipmi_smi_msg, link);
+		list_del(&smi_msg->link);
+		if (!run_to_completion)
+			spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
+		rv = handle_one_recv_msg(intf, smi_msg);
+		if (!run_to_completion)
+			spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+		if (rv == 0) {
+			/* Message handled */
+			ipmi_free_smi_msg(smi_msg);
+		} else if (rv < 0) {
+			/* Fatal error on the message, del but don't free. */
+		} else {
+			/*
+			 * To preserve message order, quit if we
+			 * can't handle a message.
+			 */
+			list_add(&smi_msg->link, &intf->waiting_msgs);
+			break;
+		}
+	}
+	if (!run_to_completion)
+		spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
+
+	/*
+	 * If the pretimout count is non-zero, decrement one from it and
+	 * deliver pretimeouts to all the users.
+	 */
+	if (atomic_add_unless(&intf->watchdog_pretimeouts_to_deliver, -1, 0)) {
+		ipmi_user_t user;
+
+		rcu_read_lock();
+		list_for_each_entry_rcu(user, &intf->users, link) {
+			if (user->handler->ipmi_watchdog_pretimeout)
+				user->handler->ipmi_watchdog_pretimeout(
+					user->handler_data);
+		}
+		rcu_read_unlock();
+	}
+}
+
+static void smi_recv_tasklet(unsigned long val)
+{
+	handle_new_recv_msgs((ipmi_smi_t) val);
+}
+
 /* Handle a new message from the lower layer. */
 void ipmi_smi_msg_received(ipmi_smi_t          intf,
 			   struct ipmi_smi_msg *msg)
 {
 	unsigned long flags = 0; /* keep us warning-free. */
-	int           rv;
 	int           run_to_completion;
 
 
@@ -3843,31 +3920,11 @@ void ipmi_smi_msg_received(ipmi_smi_t          intf,
 	run_to_completion = intf->run_to_completion;
 	if (!run_to_completion)
 		spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
-	if (!list_empty(&intf->waiting_msgs)) {
-		list_add_tail(&msg->link, &intf->waiting_msgs);
-		if (!run_to_completion)
-			spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
-		goto out;
-	}
+	list_add_tail(&msg->link, &intf->waiting_msgs);
 	if (!run_to_completion)
 		spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
 
-	rv = handle_new_recv_msg(intf, msg);
-	if (rv > 0) {
-		/*
-		 * Could not handle the message now, just add it to a
-		 * list to handle later.
-		 */
-		run_to_completion = intf->run_to_completion;
-		if (!run_to_completion)
-			spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
-		list_add_tail(&msg->link, &intf->waiting_msgs);
-		if (!run_to_completion)
-			spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
-	} else if (rv == 0) {
-		ipmi_free_smi_msg(msg);
-	}
-
+	tasklet_schedule(&intf->recv_tasklet);
  out:
 	return;
 }
@@ -3875,16 +3932,8 @@ EXPORT_SYMBOL(ipmi_smi_msg_received);
 
 void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
 {
-	ipmi_user_t user;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(user, &intf->users, link) {
-		if (!user->handler->ipmi_watchdog_pretimeout)
-			continue;
-
-		user->handler->ipmi_watchdog_pretimeout(user->handler_data);
-	}
-	rcu_read_unlock();
+	atomic_set(&intf->watchdog_pretimeouts_to_deliver, 1);
+	tasklet_schedule(&intf->recv_tasklet);
 }
 EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout);
 
@@ -3998,28 +4047,12 @@ static void ipmi_timeout_handler(long timeout_period)
 	ipmi_smi_t           intf;
 	struct list_head     timeouts;
 	struct ipmi_recv_msg *msg, *msg2;
-	struct ipmi_smi_msg  *smi_msg, *smi_msg2;
 	unsigned long        flags;
 	int                  i;
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
-		/* See if any waiting messages need to be processed. */
-		spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
-		list_for_each_entry_safe(smi_msg, smi_msg2,
-					 &intf->waiting_msgs, link) {
-			if (!handle_new_recv_msg(intf, smi_msg)) {
-				list_del(&smi_msg->link);
-				ipmi_free_smi_msg(smi_msg);
-			} else {
-				/*
-				 * To preserve message order, quit if we
-				 * can't handle a message.
-				 */
-				break;
-			}
-		}
-		spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
+		tasklet_schedule(&intf->recv_tasklet);
 
 		/*
 		 * Go through the seq table and find any messages that
@@ -4173,12 +4206,48 @@ EXPORT_SYMBOL(ipmi_free_recv_msg);
 
 #ifdef CONFIG_IPMI_PANIC_EVENT
 
+static atomic_t panic_done_count = ATOMIC_INIT(0);
+
 static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
 {
+	atomic_dec(&panic_done_count);
 }
 
 static void dummy_recv_done_handler(struct ipmi_recv_msg *msg)
 {
+	atomic_dec(&panic_done_count);
+}
+
+/*
+ * Inside a panic, send a message and wait for a response.
+ */
+static void ipmi_panic_request_and_wait(ipmi_smi_t           intf,
+					struct ipmi_addr     *addr,
+					struct kernel_ipmi_msg *msg)
+{
+	struct ipmi_smi_msg  smi_msg;
+	struct ipmi_recv_msg recv_msg;
+	int rv;
+
+	smi_msg.done = dummy_smi_done_handler;
+	recv_msg.done = dummy_recv_done_handler;
+	atomic_add(2, &panic_done_count);
+	rv = i_ipmi_request(NULL,
+			    intf,
+			    addr,
+			    0,
+			    msg,
+			    intf,
+			    &smi_msg,
+			    &recv_msg,
+			    0,
+			    intf->channels[0].address,
+			    intf->channels[0].lun,
+			    0, 1); /* Don't retry, and don't wait. */
+	if (rv)
+		atomic_sub(2, &panic_done_count);
+	while (atomic_read(&panic_done_count) != 0)
+		ipmi_poll(intf);
 }
 
 #ifdef CONFIG_IPMI_PANIC_STRING
@@ -4217,8 +4286,6 @@ static void send_panic_events(char *str)
 	unsigned char                     data[16];
 	struct ipmi_system_interface_addr *si;
 	struct ipmi_addr                  addr;
-	struct ipmi_smi_msg               smi_msg;
-	struct ipmi_recv_msg              recv_msg;
 
 	si = (struct ipmi_system_interface_addr *) &addr;
 	si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
@@ -4246,9 +4313,6 @@ static void send_panic_events(char *str)
 		data[7] = str[2];
 	}
 
-	smi_msg.done = dummy_smi_done_handler;
-	recv_msg.done = dummy_recv_done_handler;
-
 	/* For every registered interface, send the event. */
 	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
 		if (!intf->handlers)
@@ -4258,18 +4322,7 @@ static void send_panic_events(char *str)
 		intf->run_to_completion = 1;
 		/* Send the event announcing the panic. */
 		intf->handlers->set_run_to_completion(intf->send_info, 1);
-		i_ipmi_request(NULL,
-			       intf,
-			       &addr,
-			       0,
-			       &msg,
-			       intf,
-			       &smi_msg,
-			       &recv_msg,
-			       0,
-			       intf->channels[0].address,
-			       intf->channels[0].lun,
-			       0, 1); /* Don't retry, and don't wait. */
+		ipmi_panic_request_and_wait(intf, &addr, &msg);
 	}
 
 #ifdef CONFIG_IPMI_PANIC_STRING
@@ -4317,18 +4370,7 @@ static void send_panic_events(char *str)
 		msg.data = NULL;
 		msg.data_len = 0;
 		intf->null_user_handler = device_id_fetcher;
-		i_ipmi_request(NULL,
-			       intf,
-			       &addr,
-			       0,
-			       &msg,
-			       intf,
-			       &smi_msg,
-			       &recv_msg,
-			       0,
-			       intf->channels[0].address,
-			       intf->channels[0].lun,
-			       0, 1); /* Don't retry, and don't wait. */
+		ipmi_panic_request_and_wait(intf, &addr, &msg);
 
 		if (intf->local_event_generator) {
 			/* Request the event receiver from the local MC. */
@@ -4337,18 +4379,7 @@ static void send_panic_events(char *str)
 			msg.data = NULL;
 			msg.data_len = 0;
 			intf->null_user_handler = event_receiver_fetcher;
-			i_ipmi_request(NULL,
-				       intf,
-				       &addr,
-				       0,
-				       &msg,
-				       intf,
-				       &smi_msg,
-				       &recv_msg,
-				       0,
-				       intf->channels[0].address,
-				       intf->channels[0].lun,
-				       0, 1); /* no retry, and no wait. */
+			ipmi_panic_request_and_wait(intf, &addr, &msg);
 		}
 		intf->null_user_handler = NULL;
 
@@ -4405,18 +4436,7 @@ static void send_panic_events(char *str)
 			strncpy(data+5, p, 11);
 			p += size;
 
-			i_ipmi_request(NULL,
-				       intf,
-				       &addr,
-				       0,
-				       &msg,
-				       intf,
-				       &smi_msg,
-				       &recv_msg,
-				       0,
-				       intf->channels[0].address,
-				       intf->channels[0].lun,
-				       0, 1); /* no retry, and no wait. */
+			ipmi_panic_request_and_wait(intf, &addr, &msg);
 		}
 	}
 #endif /* CONFIG_IPMI_PANIC_STRING */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 50fcf9c..3c7e693 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -171,7 +171,6 @@ struct smi_info {
 	struct si_sm_handlers  *handlers;
 	enum si_type           si_type;
 	spinlock_t             si_lock;
-	spinlock_t             msg_lock;
 	struct list_head       xmit_msgs;
 	struct list_head       hp_xmit_msgs;
 	struct ipmi_smi_msg    *curr_msg;
@@ -320,16 +319,8 @@ static int register_xaction_notifier(struct notifier_block *nb)
 static void deliver_recv_msg(struct smi_info *smi_info,
 			     struct ipmi_smi_msg *msg)
 {
-	/* Deliver the message to the upper layer with the lock
-	   released. */
-
-	if (smi_info->run_to_completion) {
-		ipmi_smi_msg_received(smi_info->intf, msg);
-	} else {
-		spin_unlock(&(smi_info->si_lock));
-		ipmi_smi_msg_received(smi_info->intf, msg);
-		spin_lock(&(smi_info->si_lock));
-	}
+	/* Deliver the message to the upper layer. */
+	ipmi_smi_msg_received(smi_info->intf, msg);
 }
 
 static void return_hosed_msg(struct smi_info *smi_info, int cCode)
@@ -358,13 +349,6 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
 	struct timeval t;
 #endif
 
-	/*
-	 * No need to save flags, we aleady have interrupts off and we
-	 * already hold the SMI lock.
-	 */
-	if (!smi_info->run_to_completion)
-		spin_lock(&(smi_info->msg_lock));
-
 	/* Pick the high priority queue first. */
 	if (!list_empty(&(smi_info->hp_xmit_msgs))) {
 		entry = smi_info->hp_xmit_msgs.next;
@@ -402,9 +386,6 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
 		rv = SI_SM_CALL_WITHOUT_DELAY;
 	}
  out:
-	if (!smi_info->run_to_completion)
-		spin_unlock(&(smi_info->msg_lock));
-
 	return rv;
 }
 
@@ -481,9 +462,7 @@ static void handle_flags(struct smi_info *smi_info)
 
 		start_clear_flags(smi_info);
 		smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
-		spin_unlock(&(smi_info->si_lock));
 		ipmi_smi_watchdog_pretimeout(smi_info->intf);
-		spin_lock(&(smi_info->si_lock));
 	} else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) {
 		/* Messages available. */
 		smi_info->curr_msg = ipmi_alloc_smi_msg();
@@ -889,19 +868,6 @@ static void sender(void                *send_info,
 	printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec);
 #endif
 
-	/*
-	 * last_timeout_jiffies is updated here to avoid
-	 * smi_timeout() handler passing very large time_diff
-	 * value to smi_event_handler() that causes
-	 * the send command to abort.
-	 */
-	smi_info->last_timeout_jiffies = jiffies;
-
-	mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
-
-	if (smi_info->thread)
-		wake_up_process(smi_info->thread);
-
 	if (smi_info->run_to_completion) {
 		/*
 		 * If we are running to completion, then throw it in
@@ -924,16 +890,29 @@ static void sender(void                *send_info,
 		return;
 	}
 
-	spin_lock_irqsave(&smi_info->msg_lock, flags);
+	spin_lock_irqsave(&smi_info->si_lock, flags);
 	if (priority > 0)
 		list_add_tail(&msg->link, &smi_info->hp_xmit_msgs);
 	else
 		list_add_tail(&msg->link, &smi_info->xmit_msgs);
-	spin_unlock_irqrestore(&smi_info->msg_lock, flags);
 
-	spin_lock_irqsave(&smi_info->si_lock, flags);
-	if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL)
+	if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
+		/*
+		 * last_timeout_jiffies is updated here to avoid
+		 * smi_timeout() handler passing very large time_diff
+		 * value to smi_event_handler() that causes
+		 * the send command to abort.
+		 */
+		smi_info->last_timeout_jiffies = jiffies;
+
+		mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
+
+		if (smi_info->thread)
+			wake_up_process(smi_info->thread);
+
 		start_next_msg(smi_info);
+		smi_event_handler(smi_info, 0);
+	}
 	spin_unlock_irqrestore(&smi_info->si_lock, flags);
 }
 
@@ -1034,16 +1013,19 @@ static int ipmi_thread(void *data)
 static void poll(void *send_info)
 {
 	struct smi_info *smi_info = send_info;
-	unsigned long flags;
+	unsigned long flags = 0;
+	int run_to_completion = smi_info->run_to_completion;
 
 	/*
 	 * Make sure there is some delay in the poll loop so we can
 	 * drive time forward and timeout things.
 	 */
 	udelay(10);
-	spin_lock_irqsave(&smi_info->si_lock, flags);
+	if (!run_to_completion)
+		spin_lock_irqsave(&smi_info->si_lock, flags);
 	smi_event_handler(smi_info, 10);
-	spin_unlock_irqrestore(&smi_info->si_lock, flags);
+	if (!run_to_completion)
+		spin_unlock_irqrestore(&smi_info->si_lock, flags);
 }
 
 static void request_events(void *send_info)
@@ -1680,10 +1662,8 @@ static struct smi_info *smi_info_alloc(void)
 {
 	struct smi_info *info = kzalloc(sizeof(*info), GFP_KERNEL);
 
-	if (info) {
+	if (info)
 		spin_lock_init(&info->si_lock);
-		spin_lock_init(&info->msg_lock);
-	}
 	return info;
 }
 
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 34767a6..99dc1da 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -520,6 +520,7 @@ static void panic_halt_ipmi_heartbeat(void)
 	msg.cmd = IPMI_WDOG_RESET_TIMER;
 	msg.data = NULL;
 	msg.data_len = 0;
+	atomic_add(2, &panic_done_count);
 	rv = ipmi_request_supply_msgs(watchdog_user,
 				      (struct ipmi_addr *) &addr,
 				      0,
@@ -528,8 +529,8 @@ static void panic_halt_ipmi_heartbeat(void)
 				      &panic_halt_heartbeat_smi_msg,
 				      &panic_halt_heartbeat_recv_msg,
 				      1);
-	if (!rv)
-		atomic_add(2, &panic_done_count);
+	if (rv)
+		atomic_sub(2, &panic_done_count);
 }
 
 static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -553,16 +554,18 @@ static void panic_halt_ipmi_set_timeout(void)
 	/* Wait for the messages to be free. */
 	while (atomic_read(&panic_done_count) != 0)
 		ipmi_poll_interface(watchdog_user);
+	atomic_add(2, &panic_done_count);
 	rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
 				&panic_halt_recv_msg,
 				&send_heartbeat_now);
-	if (!rv) {
-		atomic_add(2, &panic_done_count);
-		if (send_heartbeat_now)
-			panic_halt_ipmi_heartbeat();
-	} else
+	if (rv) {
+		atomic_sub(2, &panic_done_count);
 		printk(KERN_WARNING PFX
 		       "Unable to extend the watchdog timeout.");
+	} else {
+		if (send_heartbeat_now)
+			panic_halt_ipmi_heartbeat();
+	}
 	while (atomic_read(&panic_done_count) != 0)
 		ipmi_poll_interface(watchdog_user);
 }
@@ -1164,7 +1167,7 @@ static int wdog_reboot_handler(struct notifier_block *this,
 		if (code == SYS_POWER_OFF || code == SYS_HALT) {
 			/* Disable the WDT if we are shutting down. */
 			ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
-			panic_halt_ipmi_set_timeout();
+			ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 		} else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
 			/* Set a long timer to let the reboot happens, but
 			   reboot if it hangs, but only if the watchdog
@@ -1172,7 +1175,7 @@ static int wdog_reboot_handler(struct notifier_block *this,
 			timeout = 120;
 			pretimeout = 0;
 			ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
-			panic_halt_ipmi_set_timeout();
+			ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
 		}
 	}
 	return NOTIFY_OK;
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index da3cfee..eaade8a 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -94,7 +94,7 @@
 /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
  * rtc_lock held. Due to the index-port/data-port design of the RTC, we
  * don't want two different things trying to get to it at once. (e.g. the
- * periodic 11 min sync from time.c vs. this driver.)
+ * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
  */
 
 #include <linux/types.h>
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c
index 9fec323..7da2473 100644
--- a/drivers/char/ramoops.c
+++ b/drivers/char/ramoops.c
@@ -2,6 +2,7 @@
  * RAM Oops/Panic logger
  *
  * Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
+ * Copyright (C) 2011 Kees Cook <keescook@chromium.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -24,7 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/module.h>
-#include <linux/kmsg_dump.h>
+#include <linux/pstore.h>
 #include <linux/time.h>
 #include <linux/err.h>
 #include <linux/io.h>
@@ -56,73 +57,156 @@ module_param(dump_oops, int, 0600);
 MODULE_PARM_DESC(dump_oops,
 		"set to 1 to dump oopses, 0 to only dump panics (default 1)");
 
-static struct ramoops_context {
-	struct kmsg_dumper dump;
+struct ramoops_context {
 	void *virt_addr;
 	phys_addr_t phys_addr;
 	unsigned long size;
-	unsigned long record_size;
+	size_t record_size;
 	int dump_oops;
-	int count;
-	int max_count;
-} oops_cxt;
+	unsigned int count;
+	unsigned int max_count;
+	unsigned int read_count;
+	struct pstore_info pstore;
+};
 
 static struct platform_device *dummy;
 static struct ramoops_platform_data *dummy_data;
 
-static void ramoops_do_dump(struct kmsg_dumper *dumper,
-		enum kmsg_dump_reason reason, const char *s1, unsigned long l1,
-		const char *s2, unsigned long l2)
+static int ramoops_pstore_open(struct pstore_info *psi)
+{
+	struct ramoops_context *cxt = psi->data;
+
+	cxt->read_count = 0;
+	return 0;
+}
+
+static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
+				   struct timespec *time,
+				   char **buf,
+				   struct pstore_info *psi)
 {
-	struct ramoops_context *cxt = container_of(dumper,
-			struct ramoops_context, dump);
-	unsigned long s1_start, s2_start;
-	unsigned long l1_cpy, l2_cpy;
-	int res, hdr_size;
-	char *buf, *buf_orig;
+	ssize_t size;
+	char *rambuf;
+	struct ramoops_context *cxt = psi->data;
+
+	if (cxt->read_count >= cxt->max_count)
+		return -EINVAL;
+	*id = cxt->read_count++;
+	/* Only supports dmesg output so far. */
+	*type = PSTORE_TYPE_DMESG;
+	/* TODO(kees): Bogus time for the moment. */
+	time->tv_sec = 0;
+	time->tv_nsec = 0;
+
+	rambuf = cxt->virt_addr + (*id * cxt->record_size);
+	size = strnlen(rambuf, cxt->record_size);
+	*buf = kmalloc(size, GFP_KERNEL);
+	if (*buf == NULL)
+		return -ENOMEM;
+	memcpy(*buf, rambuf, size);
+
+	return size;
+}
+
+static int ramoops_pstore_write(enum pstore_type_id type,
+				enum kmsg_dump_reason reason,
+				u64 *id,
+				unsigned int part,
+				size_t size, struct pstore_info *psi)
+{
+	char *buf;
+	size_t res;
 	struct timeval timestamp;
+	struct ramoops_context *cxt = psi->data;
+	size_t available = cxt->record_size;
+
+	/* Currently ramoops is designed to only store dmesg dumps. */
+	if (type != PSTORE_TYPE_DMESG)
+		return -EINVAL;
 
+	/* Out of the various dmesg dump types, ramoops is currently designed
+	 * to only store crash logs, rather than storing general kernel logs.
+	 */
 	if (reason != KMSG_DUMP_OOPS &&
 	    reason != KMSG_DUMP_PANIC)
-		return;
+		return -EINVAL;
 
-	/* Only dump oopses if dump_oops is set */
+	/* Skip Oopes when configured to do so. */
 	if (reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
-		return;
+		return -EINVAL;
+
+	/* Explicitly only take the first part of any new crash.
+	 * If our buffer is larger than kmsg_bytes, this can never happen,
+	 * and if our buffer is smaller than kmsg_bytes, we don't want the
+	 * report split across multiple records.
+	 */
+	if (part != 1)
+		return -ENOSPC;
 
 	buf = cxt->virt_addr + (cxt->count * cxt->record_size);
-	buf_orig = buf;
 
-	memset(buf, '\0', cxt->record_size);
 	res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR);
 	buf += res;
+	available -= res;
+
 	do_gettimeofday(&timestamp);
 	res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec);
 	buf += res;
+	available -= res;
 
-	hdr_size = buf - buf_orig;
-	l2_cpy = min(l2, cxt->record_size - hdr_size);
-	l1_cpy = min(l1, cxt->record_size - hdr_size - l2_cpy);
+	if (size > available)
+		size = available;
 
-	s2_start = l2 - l2_cpy;
-	s1_start = l1 - l1_cpy;
-
-	memcpy(buf, s1 + s1_start, l1_cpy);
-	memcpy(buf + l1_cpy, s2 + s2_start, l2_cpy);
+	memcpy(buf, cxt->pstore.buf, size);
+	memset(buf + size, '\0', available - size);
 
 	cxt->count = (cxt->count + 1) % cxt->max_count;
+
+	return 0;
+}
+
+static int ramoops_pstore_erase(enum pstore_type_id type, u64 id,
+				struct pstore_info *psi)
+{
+	char *buf;
+	struct ramoops_context *cxt = psi->data;
+
+	if (id >= cxt->max_count)
+		return -EINVAL;
+
+	buf = cxt->virt_addr + (id * cxt->record_size);
+	memset(buf, '\0', cxt->record_size);
+
+	return 0;
 }
 
+static struct ramoops_context oops_cxt = {
+	.pstore = {
+		.owner	= THIS_MODULE,
+		.name	= "ramoops",
+		.open	= ramoops_pstore_open,
+		.read	= ramoops_pstore_read,
+		.write	= ramoops_pstore_write,
+		.erase	= ramoops_pstore_erase,
+	},
+};
+
 static int __init ramoops_probe(struct platform_device *pdev)
 {
 	struct ramoops_platform_data *pdata = pdev->dev.platform_data;
 	struct ramoops_context *cxt = &oops_cxt;
 	int err = -EINVAL;
 
+	/* Only a single ramoops area allowed at a time, so fail extra
+	 * probes.
+	 */
+	if (cxt->max_count)
+		goto fail_out;
+
 	if (!pdata->mem_size || !pdata->record_size) {
 		pr_err("The memory size and the record size must be "
 			"non-zero\n");
-		goto fail3;
+		goto fail_out;
 	}
 
 	pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
@@ -131,14 +215,15 @@ static int __init ramoops_probe(struct platform_device *pdev)
 	/* Check for the minimum memory size */
 	if (pdata->mem_size < MIN_MEM_SIZE &&
 			pdata->record_size < MIN_MEM_SIZE) {
-		pr_err("memory size too small, minium is %lu\n", MIN_MEM_SIZE);
-		goto fail3;
+		pr_err("memory size too small, minimum is %lu\n",
+			MIN_MEM_SIZE);
+		goto fail_out;
 	}
 
 	if (pdata->mem_size < pdata->record_size) {
 		pr_err("The memory size must be larger than the "
 			"records size\n");
-		goto fail3;
+		goto fail_out;
 	}
 
 	cxt->max_count = pdata->mem_size / pdata->record_size;
@@ -148,23 +233,32 @@ static int __init ramoops_probe(struct platform_device *pdev)
 	cxt->record_size = pdata->record_size;
 	cxt->dump_oops = pdata->dump_oops;
 
+	cxt->pstore.data = cxt;
+	cxt->pstore.bufsize = cxt->record_size;
+	cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
+	spin_lock_init(&cxt->pstore.buf_lock);
+	if (!cxt->pstore.buf) {
+		pr_err("cannot allocate pstore buffer\n");
+		goto fail_clear;
+	}
+
 	if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) {
-		pr_err("request mem region failed\n");
+		pr_err("request mem region (0x%lx@0x%llx) failed\n",
+			cxt->size, (unsigned long long)cxt->phys_addr);
 		err = -EINVAL;
-		goto fail3;
+		goto fail_buf;
 	}
 
 	cxt->virt_addr = ioremap(cxt->phys_addr,  cxt->size);
 	if (!cxt->virt_addr) {
 		pr_err("ioremap failed\n");
-		goto fail2;
+		goto fail_mem_region;
 	}
 
-	cxt->dump.dump = ramoops_do_dump;
-	err = kmsg_dump_register(&cxt->dump);
+	err = pstore_register(&cxt->pstore);
 	if (err) {
-		pr_err("registering kmsg dumper failed\n");
-		goto fail1;
+		pr_err("registering with pstore failed\n");
+		goto fail_iounmap;
 	}
 
 	/*
@@ -176,26 +270,44 @@ static int __init ramoops_probe(struct platform_device *pdev)
 	record_size = pdata->record_size;
 	dump_oops = pdata->dump_oops;
 
+	pr_info("attached 0x%lx@0x%llx (%ux0x%zx)\n",
+		cxt->size, (unsigned long long)cxt->phys_addr,
+		cxt->max_count, cxt->record_size);
+
 	return 0;
 
-fail1:
+fail_iounmap:
 	iounmap(cxt->virt_addr);
-fail2:
+fail_mem_region:
 	release_mem_region(cxt->phys_addr, cxt->size);
-fail3:
+fail_buf:
+	kfree(cxt->pstore.buf);
+fail_clear:
+	cxt->pstore.bufsize = 0;
+	cxt->max_count = 0;
+fail_out:
 	return err;
 }
 
 static int __exit ramoops_remove(struct platform_device *pdev)
 {
+#if 0
+	/* TODO(kees): We cannot unload ramoops since pstore doesn't support
+	 * unregistering yet.
+	 */
 	struct ramoops_context *cxt = &oops_cxt;
 
-	if (kmsg_dump_unregister(&cxt->dump) < 0)
-		pr_warn("could not unregister kmsg_dumper\n");
-
 	iounmap(cxt->virt_addr);
 	release_mem_region(cxt->phys_addr, cxt->size);
+	cxt->max_count = 0;
+
+	/* TODO(kees): When pstore supports unregistering, call it here. */
+	kfree(cxt->pstore.buf);
+	cxt->pstore.bufsize = 0;
+
 	return 0;
+#endif
+	return -EBUSY;
 }
 
 static struct platform_driver ramoops_driver = {
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index ccd124a..872e09a 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -57,8 +57,8 @@
  *	Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
  *	interrupts disabled. Due to the index-port/data-port (0x70/0x71)
  *	design of the RTC, we don't want two different things trying to
- *	get to it at once. (e.g. the periodic 11 min sync from time.c vs.
- *	this driver.)
+ *	get to it at once. (e.g. the periodic 11 min sync from
+ *      kernel/time/ntp.c vs. this driver.)
  */
 
 #include <linux/interrupt.h>
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 0c964cd..ce29e7c 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -797,7 +797,7 @@ static int __init tlclk_init(void)
 	telclk_interrupt = (inb(TLCLK_REG7) & 0x0f);
 
 	if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */
-		printk(KERN_ERR "telclk_interrup = 0x%x non-mcpbl0010 hw.\n",
+		printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n",
 			telclk_interrupt);
 		ret = -ENXIO;
 		goto out3;
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 7fc75e4..a048199 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -5,7 +5,6 @@
 menuconfig TCG_TPM
 	tristate "TPM Hardware Support"
 	depends on HAS_IOMEM
-	depends on EXPERIMENTAL
 	select SECURITYFS
 	---help---
 	  If you have a TPM security chip in your system, which
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 32362cf..ad7c732 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1221,12 +1221,13 @@ ssize_t tpm_read(struct file *file, char __user *buf,
 	ret_size = atomic_read(&chip->data_pending);
 	atomic_set(&chip->data_pending, 0);
 	if (ret_size > 0) {	/* relay data */
+		ssize_t orig_ret_size = ret_size;
 		if (size < ret_size)
 			ret_size = size;
 
 		mutex_lock(&chip->buffer_mutex);
 		rc = copy_to_user(buf, chip->data_buffer, ret_size);
-		memset(chip->data_buffer, 0, ret_size);
+		memset(chip->data_buffer, 0, orig_ret_size);
 		if (rc)
 			ret_size = -EFAULT;
 
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 0105471..b1c5280 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -99,6 +99,8 @@ struct tpm_vendor_specific {
 	wait_queue_head_t int_queue;
 };
 
+#define TPM_VID_INTEL    0x8086
+
 struct tpm_chip {
 	struct device *dev;	/* Device stuff */
 
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index a174862..1250e33 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -367,7 +367,12 @@ static int probe_itpm(struct tpm_chip *chip)
 		0x00, 0x00, 0x00, 0xf1
 	};
 	size_t len = sizeof(cmd_getticks);
-	int rem_itpm = itpm;
+	bool rem_itpm = itpm;
+	u16 vendor = ioread16(chip->vendor.iobase + TPM_DID_VID(0));
+
+	/* probe only iTPMS */
+	if (vendor != TPM_VID_INTEL)
+		return 0;
 
 	itpm = 0;
 
@@ -390,9 +395,6 @@ static int probe_itpm(struct tpm_chip *chip)
 out:
 	itpm = rem_itpm;
 	tpm_tis_ready(chip);
-	/* some TPMs need a break here otherwise they will not work
-	 * correctly on the immediately subsequent command */
-	msleep(chip->vendor.timeout_b);
 	release_locality(chip, chip->vendor.locality, 0);
 
 	return rc;
@@ -508,7 +510,7 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
 			resource_size_t len, unsigned int irq)
 {
 	u32 vendor, intfcaps, intmask;
-	int rc, i, irq_s, irq_e;
+	int rc, i, irq_s, irq_e, probe;
 	struct tpm_chip *chip;
 
 	if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
@@ -538,11 +540,12 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
 		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
 	if (!itpm) {
-		itpm = probe_itpm(chip);
-		if (itpm < 0) {
+		probe = probe_itpm(chip);
+		if (probe < 0) {
 			rc = -ENODEV;
 			goto out_err;
 		}
+		itpm = (probe == 0) ? 0 : 1;
 	}
 
 	if (itpm)
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index ad6e64a..8b34c65 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -976,7 +976,7 @@ int __init viotap_init(void)
 
 	tape_class = class_create(THIS_MODULE, "tape");
 	if (IS_ERR(tape_class)) {
-		printk(VIOTAPE_KERN_WARN "Unable to allocat class\n");
+		printk(VIOTAPE_KERN_WARN "Unable to allocate class\n");
 		ret = PTR_ERR(tape_class);
 		goto unreg_chrdev;
 	}
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c
index b7dab32..540795c 100644
--- a/drivers/clocksource/cs5535-clockevt.c
+++ b/drivers/clocksource/cs5535-clockevt.c
@@ -100,7 +100,6 @@ static struct clock_event_device cs5535_clockevent = {
 	.set_mode = mfgpt_set_mode,
 	.set_next_event = mfgpt_next_event,
 	.rating = 250,
-	.cpumask = cpu_all_mask,
 	.shift = 32
 };
 
@@ -133,7 +132,7 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
 
 static struct irqaction mfgptirq  = {
 	.handler = mfgpt_tick,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER | IRQF_SHARED,
 	.name = DRV_NAME,
 };
 
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c
index 7bac808..13d311e 100644
--- a/drivers/cpufreq/cpufreq-nforce2.c
+++ b/drivers/cpufreq/cpufreq-nforce2.c
@@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = {
 	.owner = THIS_MODULE,
 };
 
+#ifdef MODULE
+static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 },
+	{}
+};
+MODULE_DEVICE_TABLE(pci, nforce2_ids);
+#endif
+
 /**
  * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
  *
diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c
index f500201..a22ffa5 100644
--- a/drivers/cpufreq/db8500-cpufreq.c
+++ b/drivers/cpufreq/db8500-cpufreq.c
@@ -22,11 +22,11 @@ static struct cpufreq_frequency_table freq_table[] = {
 	},
 	[1] = {
 		.index = 1,
-		.frequency = 300000,
+		.frequency = 400000,
 	},
 	[2] = {
 		.index = 2,
-		.frequency = 600000,
+		.frequency = 800000,
 	},
 	[3] = {
 		/* Used for MAX_OPP, if available */
@@ -113,12 +113,9 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
 
 	BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
 
-	if (!prcmu_is_u8400()) {
-		freq_table[1].frequency = 400000;
-		freq_table[2].frequency = 800000;
-		if (prcmu_has_arm_maxopp())
-			freq_table[3].frequency = 1000000;
-	}
+	if (prcmu_has_arm_maxopp())
+		freq_table[3].frequency = 1000000;
+
 	pr_info("db8500-cpufreq : Available frequencies:\n");
 	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
 		pr_info("  %d Mhz\n", freq_table[i].frequency/1000);
diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c
index 4bd6815..3fffbe6 100644
--- a/drivers/cpufreq/e_powersaver.c
+++ b/drivers/cpufreq/e_powersaver.c
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 
+#include <asm/cpu_device_id.h>
 #include <asm/msr.h>
 #include <asm/tsc.h>
 
@@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = {
 	.attr		= eps_attr,
 };
 
+
+/* This driver will work only on Centaur C7 processors with
+ * Enhanced SpeedStep/PowerSaver registers */
+static const struct x86_cpu_id eps_cpu_id[] = {
+	{ X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
+
 static int __init eps_init(void)
 {
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	/* This driver will work only on Centaur C7 processors with
-	 * Enhanced SpeedStep/PowerSaver registers */
-	if (c->x86_vendor != X86_VENDOR_CENTAUR
-	    || c->x86 != 6 || c->x86_model < 10)
-		return -ENODEV;
-	if (!cpu_has(c, X86_FEATURE_EST))
+	if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
 		return -ENODEV;
-
 	if (cpufreq_register_driver(&eps_driver))
 		return -EINVAL;
 	return 0;
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
index c587db4..960671f 100644
--- a/drivers/cpufreq/elanfreq.c
+++ b/drivers/cpufreq/elanfreq.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/cpufreq.h>
 
+#include <asm/cpu_device_id.h>
 #include <asm/msr.h>
 #include <linux/timex.h>
 #include <linux/io.h>
@@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = {
 	.attr		= elanfreq_attr,
 };
 
+static const struct x86_cpu_id elan_id[] = {
+	{ X86_VENDOR_AMD, 4, 10, },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, elan_id);
 
 static int __init elanfreq_init(void)
 {
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	/* Test if we have the right hardware */
-	if ((c->x86_vendor != X86_VENDOR_AMD) ||
-		(c->x86 != 4) || (c->x86_model != 10)) {
-		printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
+	if (!x86_match_cpu(elan_id))
 		return -ENODEV;
-	}
 	return cpufreq_register_driver(&elanfreq_driver);
 }
 
diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c
index ffe1f2c..456bee0 100644
--- a/drivers/cpufreq/gx-suspmod.c
+++ b/drivers/cpufreq/gx-suspmod.c
@@ -82,6 +82,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
+#include <asm/cpu_device_id.h>
 #include <asm/processor-cyrix.h>
 
 /* PCI config registers, all at F0 */
@@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = {
 	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
 	{ 0, },
 };
+MODULE_DEVICE_TABLE(pci, gx_chipset_tbl);
 
 static void gx_write_byte(int reg, int value)
 {
@@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void)
 {
 	struct pci_dev *gx_pci = NULL;
 
-	/* check if CPU is a MediaGX or a Geode. */
-	if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
-	    (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
-		pr_debug("error: no MediaGX/Geode processor found!\n");
-		return NULL;
-	}
-
 	/* detect which companion chip is used */
 	for_each_pci_dev(gx_pci) {
 		if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index f47d26e..53ddbc7 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -35,6 +35,7 @@
 #include <linux/acpi.h>
 
 #include <asm/msr.h>
+#include <asm/cpu_device_id.h>
 #include <acpi/processor.h>
 
 #include "longhaul.h"
@@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = {
 	.attr	= longhaul_attr,
 };
 
+static const struct x86_cpu_id longhaul_id[] = {
+	{ X86_VENDOR_CENTAUR, 6 },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, longhaul_id);
 
 static int __init longhaul_init(void)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
 
-	if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
+	if (!x86_match_cpu(longhaul_id))
 		return -ENODEV;
 
 #ifdef CONFIG_SMP
diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c
index 34ea359..8bc9f5f 100644
--- a/drivers/cpufreq/longrun.c
+++ b/drivers/cpufreq/longrun.c
@@ -14,6 +14,7 @@
 
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/cpu_device_id.h>
 
 static struct cpufreq_driver	longrun_driver;
 
@@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = {
 	.owner		= THIS_MODULE,
 };
 
+static const struct x86_cpu_id longrun_ids[] = {
+	{ X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY,
+	  X86_FEATURE_LONGRUN },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, longrun_ids);
 
 /**
  * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
@@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = {
  */
 static int __init longrun_init(void)
 {
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
-	    !cpu_has(c, X86_FEATURE_LONGRUN))
+	if (!x86_match_cpu(longrun_ids))
 		return -ENODEV;
-
 	return cpufreq_register_driver(&longrun_driver);
 }
 
diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c
index 6be3e07..827629c9 100644
--- a/drivers/cpufreq/p4-clockmod.c
+++ b/drivers/cpufreq/p4-clockmod.c
@@ -31,6 +31,7 @@
 #include <asm/processor.h>
 #include <asm/msr.h>
 #include <asm/timer.h>
+#include <asm/cpu_device_id.h>
 
 #include "speedstep-lib.h"
 
@@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = {
 	.attr		= p4clockmod_attr,
 };
 
+static const struct x86_cpu_id cpufreq_p4_id[] = {
+	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC },
+	{}
+};
+
+/*
+ * Intentionally no MODULE_DEVICE_TABLE here: this driver should not
+ * be auto loaded.  Please don't add one.
+ */
 
 static int __init cpufreq_p4_init(void)
 {
-	struct cpuinfo_x86 *c = &cpu_data(0);
 	int ret;
 
 	/*
 	 * THERM_CONTROL is architectural for IA32 now, so
 	 * we can rely on the capability checks
 	 */
-	if (c->x86_vendor != X86_VENDOR_INTEL)
-		return -ENODEV;
-
-	if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
-				!test_cpu_cap(c, X86_FEATURE_ACC))
+	if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI))
 		return -ENODEV;
 
 	ret = cpufreq_register_driver(&p4clockmod_driver);
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index b3379d6..af23e0b 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -16,6 +16,7 @@
 #include <linux/timex.h>
 #include <linux/io.h>
 
+#include <asm/cpu_device_id.h>
 #include <asm/msr.h>
 
 #define POWERNOW_IOPORT 0xfff0          /* it doesn't matter where, as long
@@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = {
 	.attr		= powernow_k6_attr,
 };
 
+static const struct x86_cpu_id powernow_k6_ids[] = {
+	{ X86_VENDOR_AMD, 5, 12 },
+	{ X86_VENDOR_AMD, 5, 13 },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, powernow_k6_ids);
 
 /**
  * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
@@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = {
  */
 static int __init powernow_k6_init(void)
 {
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
-		((c->x86_model != 12) && (c->x86_model != 13)))
+	if (!x86_match_cpu(powernow_k6_ids))
 		return -ENODEV;
 
 	if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
index d71d9f3..cf7e1ee 100644
--- a/drivers/cpufreq/powernow-k7.c
+++ b/drivers/cpufreq/powernow-k7.c
@@ -28,6 +28,7 @@
 #include <asm/timer.h>		/* Needed for recalibrate_cpu_khz() */
 #include <asm/msr.h>
 #include <asm/system.h>
+#include <asm/cpu_device_id.h>
 
 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
 #include <linux/acpi.h>
@@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed)
 	return delta < 5;
 }
 
+static const struct x86_cpu_id powernow_k7_cpuids[] = {
+	{ X86_VENDOR_AMD, 6, },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
+
 static int check_powernow(void)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
 	unsigned int maxei, eax, ebx, ecx, edx;
 
-	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
-#ifdef MODULE
-		printk(KERN_INFO PFX "This module only works with "
-				"AMD K7 CPUs\n");
-#endif
+	if (!x86_match_cpu(powernow_k7_cpuids))
 		return 0;
-	}
 
 	/* Get maximum capabilities */
 	maxei = cpuid_eax(0x80000000);
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 8f9b2ce..c0e8164 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -40,6 +40,7 @@
 #include <linux/delay.h>
 
 #include <asm/msr.h>
+#include <asm/cpu_device_id.h>
 
 #include <linux/acpi.h>
 #include <linux/mutex.h>
@@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
 	return 0;
 }
 
+static const struct x86_cpu_id powernow_k8_ids[] = {
+	/* IO based frequency switching */
+	{ X86_VENDOR_AMD, 0xf },
+	/* MSR based frequency switching supported */
+	X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
+
 static void check_supported_cpu(void *_rc)
 {
 	u32 eax, ebx, ecx, edx;
@@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc)
 
 	*rc = -ENODEV;
 
-	if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
-		return;
-
 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
-	if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
-	    ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
-		return;
 
 	if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
 		if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
@@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void)
 	unsigned int i, supported_cpus = 0, cpu;
 	int rv;
 
+	if (!x86_match_cpu(powernow_k8_ids))
+		return -ENODEV;
+
 	for_each_online_cpu(i) {
 		int rc;
 		smp_call_function_single(i, check_supported_cpu, &rc, 1);
diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c
index 1e205e6..e42e073 100644
--- a/drivers/cpufreq/sc520_freq.c
+++ b/drivers/cpufreq/sc520_freq.c
@@ -22,6 +22,7 @@
 #include <linux/timex.h>
 #include <linux/io.h>
 
+#include <asm/cpu_device_id.h>
 #include <asm/msr.h>
 
 #define MMCR_BASE	0xfffef000	/* The default base address */
@@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = {
 	.attr	= sc520_freq_attr,
 };
 
+static const struct x86_cpu_id sc520_ids[] = {
+	{ X86_VENDOR_AMD, 4, 9 },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, sc520_ids);
 
 static int __init sc520_freq_init(void)
 {
-	struct cpuinfo_x86 *c = &cpu_data(0);
 	int err;
 
-	/* Test if we have the right hardware */
-	if (c->x86_vendor != X86_VENDOR_AMD ||
-	    c->x86 != 4 || c->x86_model != 9) {
-		pr_debug("no Elan SC520 processor found!\n");
+	if (!x86_match_cpu(sc520_ids))
 		return -ENODEV;
-	}
+
 	cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
 	if (!cpuctl) {
 		printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c
index 6ea3455..3a953d5 100644
--- a/drivers/cpufreq/speedstep-centrino.c
+++ b/drivers/cpufreq/speedstep-centrino.c
@@ -25,6 +25,7 @@
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
+#include <asm/cpu_device_id.h>
 
 #define PFX		"speedstep-centrino: "
 #define MAINTAINER	"cpufreq@vger.kernel.org"
@@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = {
 	.owner		= THIS_MODULE,
 };
 
+/*
+ * This doesn't replace the detailed checks above because
+ * the generic CPU IDs don't have a way to match for steppings
+ * or ASCII model IDs.
+ */
+static const struct x86_cpu_id centrino_ids[] = {
+	{ X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST },
+	{ X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
+	{ X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
+	{ X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST },
+	{ X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST },
+	{ X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST },
+	{}
+};
+#if 0
+/* Autoload or not? Do not for now. */
+MODULE_DEVICE_TABLE(x86cpu, centrino_ids);
+#endif
 
 /**
  * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
@@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = {
  */
 static int __init centrino_init(void)
 {
-	struct cpuinfo_x86 *cpu = &cpu_data(0);
-
-	if (!cpu_has(cpu, X86_FEATURE_EST))
+	if (!x86_match_cpu(centrino_ids))
 		return -ENODEV;
-
 	return cpufreq_register_driver(&centrino_driver);
 }
 
diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c
index a748ce7..7432b3a 100644
--- a/drivers/cpufreq/speedstep-ich.c
+++ b/drivers/cpufreq/speedstep-ich.c
@@ -25,6 +25,8 @@
 #include <linux/pci.h>
 #include <linux/sched.h>
 
+#include <asm/cpu_device_id.h>
+
 #include "speedstep-lib.h"
 
 
@@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = {
 	.attr	= speedstep_attr,
 };
 
+static const struct x86_cpu_id ss_smi_ids[] = {
+	{ X86_VENDOR_INTEL, 6, 0xb, },
+	{ X86_VENDOR_INTEL, 6, 0x8, },
+	{ X86_VENDOR_INTEL, 15, 2 },
+	{}
+};
+#if 0
+/* Autoload or not? Do not for now. */
+MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
+#endif
 
 /**
  * speedstep_init - initializes the SpeedStep CPUFreq driver
@@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = {
  */
 static int __init speedstep_init(void)
 {
+	if (!x86_match_cpu(ss_smi_ids))
+		return -ENODEV;
+
 	/* detect processor */
 	speedstep_processor = speedstep_detect_processor();
 	if (!speedstep_processor) {
diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c
index 8af2d2f..7047821 100644
--- a/drivers/cpufreq/speedstep-lib.c
+++ b/drivers/cpufreq/speedstep-lib.c
@@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
  *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
  *********************************************************************/
 
+/* Keep in sync with the x86_cpu_id tables in the different modules */
 unsigned int speedstep_detect_processor(void)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c
index c76ead3..6a457fc 100644
--- a/drivers/cpufreq/speedstep-smi.c
+++ b/drivers/cpufreq/speedstep-smi.c
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <asm/ist.h>
+#include <asm/cpu_device_id.h>
 
 #include "speedstep-lib.h"
 
@@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = {
 	.attr		= speedstep_attr,
 };
 
+static const struct x86_cpu_id ss_smi_ids[] = {
+	{ X86_VENDOR_INTEL, 6, 0xb, },
+	{ X86_VENDOR_INTEL, 6, 0x8, },
+	{ X86_VENDOR_INTEL, 15, 2 },
+	{}
+};
+#if 0
+/* Not auto loaded currently */
+MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids);
+#endif
+
 /**
  * speedstep_init - initializes the SpeedStep CPUFreq driver
  *
@@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = {
  */
 static int __init speedstep_init(void)
 {
+	if (!x86_match_cpu(ss_smi_ids))
+		return -ENODEV;
+
 	speedstep_processor = speedstep_detect_processor();
 
 	switch (speedstep_processor) {
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 6d16b4b..e707979 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -293,4 +293,15 @@ config CRYPTO_DEV_S5P
 	  Select this to offload Samsung S5PV210 or S5PC110 from AES
 	  algorithms execution.
 
+config CRYPTO_DEV_TEGRA_AES
+	tristate "Support for TEGRA AES hw engine"
+	depends on ARCH_TEGRA
+	select CRYPTO_AES
+	help
+	  TEGRA processors have AES module accelerator. Select this if you
+	  want to use the TEGRA module for AES algorithms.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called tegra-aes.
+
 endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 53ea501..f3e64ea 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
 obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
 obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
+obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index e73cf2e..534a364 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1844,6 +1844,25 @@ static struct caam_alg_template driver_algs[] = {
 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
 	},
 	{
+		.name = "authenc(hmac(sha224),cbc(aes))",
+		.driver_name = "authenc-hmac-sha224-cbc-aes-caam",
+		.blocksize = AES_BLOCK_SIZE,
+		.template_aead = {
+			.setkey = aead_setkey,
+			.setauthsize = aead_setauthsize,
+			.encrypt = aead_encrypt,
+			.decrypt = aead_decrypt,
+			.givencrypt = aead_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = AES_BLOCK_SIZE,
+			.maxauthsize = SHA224_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
+	},
+	{
 		.name = "authenc(hmac(sha256),cbc(aes))",
 		.driver_name = "authenc-hmac-sha256-cbc-aes-caam",
 		.blocksize = AES_BLOCK_SIZE,
@@ -1864,6 +1883,26 @@ static struct caam_alg_template driver_algs[] = {
 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
 	},
 	{
+		.name = "authenc(hmac(sha384),cbc(aes))",
+		.driver_name = "authenc-hmac-sha384-cbc-aes-caam",
+		.blocksize = AES_BLOCK_SIZE,
+		.template_aead = {
+			.setkey = aead_setkey,
+			.setauthsize = aead_setauthsize,
+			.encrypt = aead_encrypt,
+			.decrypt = aead_decrypt,
+			.givencrypt = aead_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = AES_BLOCK_SIZE,
+			.maxauthsize = SHA384_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
+	},
+
+	{
 		.name = "authenc(hmac(sha512),cbc(aes))",
 		.driver_name = "authenc-hmac-sha512-cbc-aes-caam",
 		.blocksize = AES_BLOCK_SIZE,
@@ -1922,6 +1961,25 @@ static struct caam_alg_template driver_algs[] = {
 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
 	},
 	{
+		.name = "authenc(hmac(sha224),cbc(des3_ede))",
+		.driver_name = "authenc-hmac-sha224-cbc-des3_ede-caam",
+		.blocksize = DES3_EDE_BLOCK_SIZE,
+		.template_aead = {
+			.setkey = aead_setkey,
+			.setauthsize = aead_setauthsize,
+			.encrypt = aead_encrypt,
+			.decrypt = aead_decrypt,
+			.givencrypt = aead_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES3_EDE_BLOCK_SIZE,
+			.maxauthsize = SHA224_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
+	},
+	{
 		.name = "authenc(hmac(sha256),cbc(des3_ede))",
 		.driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam",
 		.blocksize = DES3_EDE_BLOCK_SIZE,
@@ -1942,6 +2000,25 @@ static struct caam_alg_template driver_algs[] = {
 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
 	},
 	{
+		.name = "authenc(hmac(sha384),cbc(des3_ede))",
+		.driver_name = "authenc-hmac-sha384-cbc-des3_ede-caam",
+		.blocksize = DES3_EDE_BLOCK_SIZE,
+		.template_aead = {
+			.setkey = aead_setkey,
+			.setauthsize = aead_setauthsize,
+			.encrypt = aead_encrypt,
+			.decrypt = aead_decrypt,
+			.givencrypt = aead_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES3_EDE_BLOCK_SIZE,
+			.maxauthsize = SHA384_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
+	},
+	{
 		.name = "authenc(hmac(sha512),cbc(des3_ede))",
 		.driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam",
 		.blocksize = DES3_EDE_BLOCK_SIZE,
@@ -2000,6 +2077,25 @@ static struct caam_alg_template driver_algs[] = {
 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
 	},
 	{
+		.name = "authenc(hmac(sha224),cbc(des))",
+		.driver_name = "authenc-hmac-sha224-cbc-des-caam",
+		.blocksize = DES_BLOCK_SIZE,
+		.template_aead = {
+			.setkey = aead_setkey,
+			.setauthsize = aead_setauthsize,
+			.encrypt = aead_encrypt,
+			.decrypt = aead_decrypt,
+			.givencrypt = aead_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES_BLOCK_SIZE,
+			.maxauthsize = SHA224_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
+	},
+	{
 		.name = "authenc(hmac(sha256),cbc(des))",
 		.driver_name = "authenc-hmac-sha256-cbc-des-caam",
 		.blocksize = DES_BLOCK_SIZE,
@@ -2020,6 +2116,25 @@ static struct caam_alg_template driver_algs[] = {
 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
 	},
 	{
+		.name = "authenc(hmac(sha384),cbc(des))",
+		.driver_name = "authenc-hmac-sha384-cbc-des-caam",
+		.blocksize = DES_BLOCK_SIZE,
+		.template_aead = {
+			.setkey = aead_setkey,
+			.setauthsize = aead_setauthsize,
+			.encrypt = aead_encrypt,
+			.decrypt = aead_decrypt,
+			.givencrypt = aead_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES_BLOCK_SIZE,
+			.maxauthsize = SHA384_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
+	},
+	{
 		.name = "authenc(hmac(sha512),cbc(des))",
 		.driver_name = "authenc-hmac-sha512-cbc-des-caam",
 		.blocksize = DES_BLOCK_SIZE,
@@ -2205,7 +2320,8 @@ static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev,
 	alg->cra_blocksize = template->blocksize;
 	alg->cra_alignmask = 0;
 	alg->cra_ctxsize = sizeof(struct caam_ctx);
-	alg->cra_flags = CRYPTO_ALG_ASYNC | template->type;
+	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
+			 template->type;
 	switch (template->type) {
 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
 		alg->cra_type = &crypto_ablkcipher_type;
@@ -2285,12 +2401,12 @@ static int __init caam_algapi_init(void)
 			dev_warn(ctrldev, "%s alg registration failed\n",
 				t_alg->crypto_alg.cra_driver_name);
 			kfree(t_alg);
-		} else {
+		} else
 			list_add_tail(&t_alg->entry, &priv->alg_list);
-			dev_info(ctrldev, "%s\n",
-				 t_alg->crypto_alg.cra_driver_name);
-		}
 	}
+	if (!list_empty(&priv->alg_list))
+		dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n",
+			 (char *)of_get_property(dev_node, "compatible", NULL));
 
 	return err;
 }
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 8ae3ba2..c5f61c5 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -46,7 +46,7 @@ static int caam_remove(struct platform_device *pdev)
 /* Probe routine for CAAM top (controller) level */
 static int caam_probe(struct platform_device *pdev)
 {
-	int d, ring, rspec;
+	int ring, rspec;
 	struct device *dev;
 	struct device_node *nprop, *np;
 	struct caam_ctrl __iomem *ctrl;
diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c
index 219d09c..f3e36c8 100644
--- a/drivers/crypto/geode-aes.c
+++ b/drivers/crypto/geode-aes.c
@@ -393,7 +393,8 @@ static struct crypto_alg geode_cbc_alg = {
 	.cra_driver_name	=	"cbc-aes-geode",
 	.cra_priority		=	400,
 	.cra_flags			=	CRYPTO_ALG_TYPE_BLKCIPHER |
-							CRYPTO_ALG_NEED_FALLBACK,
+						CRYPTO_ALG_KERN_DRIVER_ONLY |
+						CRYPTO_ALG_NEED_FALLBACK,
 	.cra_init			=	fallback_init_blk,
 	.cra_exit			=	fallback_exit_blk,
 	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
@@ -479,7 +480,8 @@ static struct crypto_alg geode_ecb_alg = {
 	.cra_driver_name	=	"ecb-aes-geode",
 	.cra_priority		=	400,
 	.cra_flags			=	CRYPTO_ALG_TYPE_BLKCIPHER |
-							CRYPTO_ALG_NEED_FALLBACK,
+						CRYPTO_ALG_KERN_DRIVER_ONLY |
+						CRYPTO_ALG_NEED_FALLBACK,
 	.cra_init			=	fallback_init_blk,
 	.cra_exit			=	fallback_exit_blk,
 	.cra_blocksize		=	AES_MIN_BLOCK_SIZE,
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index fe765f4..c9c4bef 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1731,9 +1731,9 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
 	while (size) {
 		copy = min3(srest, dst->length, size);
 
-		daddr = kmap_atomic(sg_page(dst), KM_IRQ0);
+		daddr = kmap_atomic(sg_page(dst));
 		memcpy(daddr + dst->offset + offset, saddr, copy);
-		kunmap_atomic(daddr, KM_IRQ0);
+		kunmap_atomic(daddr);
 
 		nbytes -= copy;
 		size -= copy;
@@ -1793,17 +1793,17 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
 				continue;
 			}
 
-			saddr = kmap_atomic(sg_page(t), KM_SOFTIRQ0);
+			saddr = kmap_atomic(sg_page(t));
 
 			err = ablkcipher_get(saddr, &t->length, t->offset,
 					dst, nbytes, &nbytes);
 			if (err < 0) {
-				kunmap_atomic(saddr, KM_SOFTIRQ0);
+				kunmap_atomic(saddr);
 				break;
 			}
 
 			idx += err;
-			kunmap_atomic(saddr, KM_SOFTIRQ0);
+			kunmap_atomic(saddr);
 		}
 
 		hifn_cipher_walk_exit(&rctx->walk);
@@ -2494,7 +2494,8 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t)
 		 t->drv_name, dev->name);
 
 	alg->alg.cra_priority = 300;
-	alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
+	alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+				CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC;
 	alg->alg.cra_blocksize = t->bsize;
 	alg->alg.cra_ctxsize = sizeof(struct hifn_context);
 	alg->alg.cra_alignmask = 0;
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 4c20c5b..0053d7e 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -265,7 +265,7 @@ static int setup_crypt_desc(void)
 	BUILD_BUG_ON(sizeof(struct crypt_ctl) != 64);
 	crypt_virt = dma_alloc_coherent(dev,
 			NPE_QLEN * sizeof(struct crypt_ctl),
-			&crypt_phys, GFP_KERNEL);
+			&crypt_phys, GFP_ATOMIC);
 	if (!crypt_virt)
 		return -ENOMEM;
 	memset(crypt_virt, 0, NPE_QLEN * sizeof(struct crypt_ctl));
@@ -1449,6 +1449,7 @@ static int __init ixp_module_init(void)
 			/* block ciphers */
 			cra->cra_type = &crypto_ablkcipher_type;
 			cra->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+					 CRYPTO_ALG_KERN_DRIVER_ONLY |
 					 CRYPTO_ALG_ASYNC;
 			if (!cra->cra_ablkcipher.setkey)
 				cra->cra_ablkcipher.setkey = ablk_setkey;
@@ -1461,6 +1462,7 @@ static int __init ixp_module_init(void)
 			/* authenc */
 			cra->cra_type = &crypto_aead_type;
 			cra->cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					 CRYPTO_ALG_KERN_DRIVER_ONLY |
 					 CRYPTO_ALG_ASYNC;
 			cra->cra_aead.setkey = aead_setkey;
 			cra->cra_aead.setauthsize = aead_setauthsize;
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 597235a..8ad2883 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -898,7 +898,8 @@ struct crypto_alg mv_aes_alg_ecb = {
 	.cra_name		= "ecb(aes)",
 	.cra_driver_name	= "mv-ecb-aes",
 	.cra_priority	= 300,
-	.cra_flags	= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_flags	= CRYPTO_ALG_TYPE_ABLKCIPHER |
+			  CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC,
 	.cra_blocksize	= 16,
 	.cra_ctxsize	= sizeof(struct mv_ctx),
 	.cra_alignmask	= 0,
@@ -920,7 +921,8 @@ struct crypto_alg mv_aes_alg_cbc = {
 	.cra_name		= "cbc(aes)",
 	.cra_driver_name	= "mv-cbc-aes",
 	.cra_priority	= 300,
-	.cra_flags	= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_flags	= CRYPTO_ALG_TYPE_ABLKCIPHER |
+			  CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC,
 	.cra_blocksize	= AES_BLOCK_SIZE,
 	.cra_ctxsize	= sizeof(struct mv_ctx),
 	.cra_alignmask	= 0,
@@ -952,7 +954,8 @@ struct ahash_alg mv_sha1_alg = {
 			  .cra_driver_name = "mv-sha1",
 			  .cra_priority = 300,
 			  .cra_flags =
-			  CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+			  CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
+			  CRYPTO_ALG_NEED_FALLBACK,
 			  .cra_blocksize = SHA1_BLOCK_SIZE,
 			  .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx),
 			  .cra_init = mv_cra_hash_sha1_init,
@@ -976,7 +979,8 @@ struct ahash_alg mv_hmac_sha1_alg = {
 			  .cra_driver_name = "mv-hmac-sha1",
 			  .cra_priority = 300,
 			  .cra_flags =
-			  CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+			  CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
+			  CRYPTO_ALG_NEED_FALLBACK,
 			  .cra_blocksize = SHA1_BLOCK_SIZE,
 			  .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx),
 			  .cra_init = mv_cra_hash_hmac_sha1_init,
diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c
index 8944dab..67b97c5 100644
--- a/drivers/crypto/n2_core.c
+++ b/drivers/crypto/n2_core.c
@@ -1402,7 +1402,8 @@ static int __devinit __n2_register_one_cipher(const struct n2_cipher_tmpl *tmpl)
 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->drv_name);
 	alg->cra_priority = N2_CRA_PRIORITY;
-	alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC;
+	alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+			 CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC;
 	alg->cra_blocksize = tmpl->block_size;
 	p->enc_type = tmpl->enc_type;
 	alg->cra_ctxsize = sizeof(struct n2_cipher_context);
@@ -1493,7 +1494,9 @@ static int __devinit __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl)
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
 	snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->name);
 	base->cra_priority = N2_CRA_PRIORITY;
-	base->cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK;
+	base->cra_flags = CRYPTO_ALG_TYPE_AHASH |
+			  CRYPTO_ALG_KERN_DRIVER_ONLY |
+			  CRYPTO_ALG_NEED_FALLBACK;
 	base->cra_blocksize = tmpl->block_size;
 	base->cra_ctxsize = sizeof(struct n2_hash_ctx);
 	base->cra_module = THIS_MODULE;
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 5b970d9..63e57b5 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -756,7 +756,9 @@ static struct crypto_alg algs[] = {
 	.cra_name		= "ecb(aes)",
 	.cra_driver_name	= "ecb-aes-omap",
 	.cra_priority		= 100,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
+				  CRYPTO_ALG_KERN_DRIVER_ONLY |
+				  CRYPTO_ALG_ASYNC,
 	.cra_blocksize		= AES_BLOCK_SIZE,
 	.cra_ctxsize		= sizeof(struct omap_aes_ctx),
 	.cra_alignmask		= 0,
@@ -776,7 +778,9 @@ static struct crypto_alg algs[] = {
 	.cra_name		= "cbc(aes)",
 	.cra_driver_name	= "cbc-aes-omap",
 	.cra_priority		= 100,
-	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
+				  CRYPTO_ALG_KERN_DRIVER_ONLY |
+				  CRYPTO_ALG_ASYNC,
 	.cra_blocksize		= AES_BLOCK_SIZE,
 	.cra_ctxsize		= sizeof(struct omap_aes_ctx),
 	.cra_alignmask		= 0,
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 6399a8f..a3fd6fc 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -953,6 +953,7 @@ static struct ahash_alg algs[] = {
 		.cra_driver_name	= "omap-sha1",
 		.cra_priority		= 100,
 		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_KERN_DRIVER_ONLY |
 						CRYPTO_ALG_ASYNC |
 						CRYPTO_ALG_NEED_FALLBACK,
 		.cra_blocksize		= SHA1_BLOCK_SIZE,
@@ -975,6 +976,7 @@ static struct ahash_alg algs[] = {
 		.cra_driver_name	= "omap-md5",
 		.cra_priority		= 100,
 		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_KERN_DRIVER_ONLY |
 						CRYPTO_ALG_ASYNC |
 						CRYPTO_ALG_NEED_FALLBACK,
 		.cra_blocksize		= SHA1_BLOCK_SIZE,
@@ -998,6 +1000,7 @@ static struct ahash_alg algs[] = {
 		.cra_driver_name	= "omap-hmac-sha1",
 		.cra_priority		= 100,
 		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_KERN_DRIVER_ONLY |
 						CRYPTO_ALG_ASYNC |
 						CRYPTO_ALG_NEED_FALLBACK,
 		.cra_blocksize		= SHA1_BLOCK_SIZE,
@@ -1022,6 +1025,7 @@ static struct ahash_alg algs[] = {
 		.cra_driver_name	= "omap-hmac-md5",
 		.cra_priority		= 100,
 		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_KERN_DRIVER_ONLY |
 						CRYPTO_ALG_ASYNC |
 						CRYPTO_ALG_NEED_FALLBACK,
 		.cra_blocksize		= SHA1_BLOCK_SIZE,
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index 29b9469..37b2e94 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -19,6 +19,7 @@
 #include <linux/percpu.h>
 #include <linux/smp.h>
 #include <linux/slab.h>
+#include <asm/cpu_device_id.h>
 #include <asm/byteorder.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
@@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = {
 	}
 };
 
+static struct x86_cpu_id padlock_cpu_id[] = {
+	X86_FEATURE_MATCH(X86_FEATURE_XCRYPT),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, padlock_cpu_id);
+
 static int __init padlock_init(void)
 {
 	int ret;
 	struct cpuinfo_x86 *c = &cpu_data(0);
 
-	if (!cpu_has_xcrypt)
+	if (!x86_match_cpu(padlock_cpu_id))
 		return -ENODEV;
 
 	if (!cpu_has_xcrypt_enabled) {
diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c
index 06bdb4b..9266c0e 100644
--- a/drivers/crypto/padlock-sha.c
+++ b/drivers/crypto/padlock-sha.c
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/scatterlist.h>
+#include <asm/cpu_device_id.h>
 #include <asm/i387.h>
 
 struct padlock_sha_desc {
@@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = {
 	}
 };
 
+static struct x86_cpu_id padlock_sha_ids[] = {
+	X86_FEATURE_MATCH(X86_FEATURE_PHE),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, padlock_sha_ids);
+
 static int __init padlock_init(void)
 {
 	int rc = -ENODEV;
@@ -533,15 +540,8 @@ static int __init padlock_init(void)
 	struct shash_alg *sha1;
 	struct shash_alg *sha256;
 
-	if (!cpu_has_phe) {
-		printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n");
-		return -ENODEV;
-	}
-
-	if (!cpu_has_phe_enabled) {
-		printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n");
+	if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled)
 		return -ENODEV;
-	}
 
 	/* Register the newly added algorithm module if on *
 	* VIA Nano processor, or else just do as before */
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c
index 58480d0..410a03c 100644
--- a/drivers/crypto/picoxcell_crypto.c
+++ b/drivers/crypto/picoxcell_crypto.c
@@ -1322,6 +1322,7 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_driver_name = "cbc-aes-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
 			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+				     CRYPTO_ALG_KERN_DRIVER_ONLY |
 				     CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_NEED_FALLBACK,
 			.cra_blocksize = AES_BLOCK_SIZE,
@@ -1349,6 +1350,7 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_driver_name = "ecb-aes-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
 			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+				CRYPTO_ALG_KERN_DRIVER_ONLY |
 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
 			.cra_blocksize = AES_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_ablk_ctx),
@@ -1373,7 +1375,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "cbc(des)",
 			.cra_driver_name = "cbc-des-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_ablk_ctx),
 			.cra_type = &crypto_ablkcipher_type,
@@ -1398,7 +1402,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "ecb(des)",
 			.cra_driver_name = "ecb-des-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_ablk_ctx),
 			.cra_type = &crypto_ablkcipher_type,
@@ -1422,7 +1428,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "cbc(des3_ede)",
 			.cra_driver_name = "cbc-des3-ede-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_ablk_ctx),
 			.cra_type = &crypto_ablkcipher_type,
@@ -1447,7 +1455,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "ecb(des3_ede)",
 			.cra_driver_name = "ecb-des3-ede-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_ablk_ctx),
 			.cra_type = &crypto_ablkcipher_type,
@@ -1472,7 +1482,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "authenc(hmac(sha1),cbc(aes))",
 			.cra_driver_name = "authenc-hmac-sha1-cbc-aes-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = AES_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_aead_ctx),
 			.cra_type = &crypto_aead_type,
@@ -1500,7 +1512,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "authenc(hmac(sha256),cbc(aes))",
 			.cra_driver_name = "authenc-hmac-sha256-cbc-aes-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = AES_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_aead_ctx),
 			.cra_type = &crypto_aead_type,
@@ -1527,7 +1541,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "authenc(hmac(md5),cbc(aes))",
 			.cra_driver_name = "authenc-hmac-md5-cbc-aes-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = AES_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_aead_ctx),
 			.cra_type = &crypto_aead_type,
@@ -1554,7 +1570,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
 			.cra_driver_name = "authenc-hmac-sha1-cbc-3des-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_aead_ctx),
 			.cra_type = &crypto_aead_type,
@@ -1582,7 +1600,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
 			.cra_driver_name = "authenc-hmac-sha256-cbc-3des-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_aead_ctx),
 			.cra_type = &crypto_aead_type,
@@ -1609,7 +1629,9 @@ static struct spacc_alg ipsec_engine_algs[] = {
 			.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
 			.cra_driver_name = "authenc-hmac-md5-cbc-3des-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_AEAD |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_ctxsize = sizeof(struct spacc_aead_ctx),
 			.cra_type = &crypto_aead_type,
@@ -1639,7 +1661,9 @@ static struct spacc_alg l2_engine_algs[] = {
 			.cra_name = "f8(kasumi)",
 			.cra_driver_name = "f8-kasumi-picoxcell",
 			.cra_priority = SPACC_CRYPTO_ALG_PRIORITY,
-			.cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_ASYNC,
+			.cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER |
+					CRYPTO_ALG_ASYNC |
+					CRYPTO_ALG_KERN_DRIVER_ONLY,
 			.cra_blocksize = 8,
 			.cra_ctxsize = sizeof(struct spacc_ablk_ctx),
 			.cra_type = &crypto_ablkcipher_type,
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c
index 3376bca..bc986f8 100644
--- a/drivers/crypto/s5p-sss.c
+++ b/drivers/crypto/s5p-sss.c
@@ -518,7 +518,8 @@ static struct crypto_alg algs[] = {
 		.cra_driver_name	= "ecb-aes-s5p",
 		.cra_priority		= 100,
 		.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
-					  CRYPTO_ALG_ASYNC,
+					  CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_KERN_DRIVER_ONLY,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct s5p_aes_ctx),
 		.cra_alignmask		= 0x0f,
@@ -538,7 +539,8 @@ static struct crypto_alg algs[] = {
 		.cra_driver_name	= "cbc-aes-s5p",
 		.cra_priority		= 100,
 		.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
-					  CRYPTO_ALG_ASYNC,
+					  CRYPTO_ALG_ASYNC |
+					  CRYPTO_ALG_KERN_DRIVER_ONLY,
 		.cra_blocksize		= AES_BLOCK_SIZE,
 		.cra_ctxsize		= sizeof(struct s5p_aes_ctx),
 		.cra_alignmask		= 0x0f,
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 2d8c789..dc641c7 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2648,6 +2648,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
 	alg->cra_priority = TALITOS_CRA_PRIORITY;
 	alg->cra_alignmask = 0;
 	alg->cra_ctxsize = sizeof(struct talitos_ctx);
+	alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
 
 	t_alg->dev = dev;
 
diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c
new file mode 100644
index 0000000..422a976
--- /dev/null
+++ b/drivers/crypto/tegra-aes.c
@@ -0,0 +1,1096 @@
+/*
+ * drivers/crypto/tegra-aes.c
+ *
+ * Driver for NVIDIA Tegra AES hardware engine residing inside the
+ * Bit Stream Engine for Video (BSEV) hardware block.
+ *
+ * The programming sequence for this engine is with the help
+ * of commands which travel via a command queue residing between the
+ * CPU and the BSEV block. The BSEV engine has an internal RAM (VRAM)
+ * where the final input plaintext, keys and the IV have to be copied
+ * before starting the encrypt/decrypt operation.
+ *
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+
+#include <mach/clk.h>
+
+#include <crypto/scatterwalk.h>
+#include <crypto/aes.h>
+#include <crypto/internal/rng.h>
+
+#include "tegra-aes.h"
+
+#define FLAGS_MODE_MASK			0x00FF
+#define FLAGS_ENCRYPT			BIT(0)
+#define FLAGS_CBC			BIT(1)
+#define FLAGS_GIV			BIT(2)
+#define FLAGS_RNG			BIT(3)
+#define FLAGS_OFB			BIT(4)
+#define FLAGS_NEW_KEY			BIT(5)
+#define FLAGS_NEW_IV			BIT(6)
+#define FLAGS_INIT			BIT(7)
+#define FLAGS_FAST			BIT(8)
+#define FLAGS_BUSY			9
+
+/*
+ * Defines AES engine Max process bytes size in one go, which takes 1 msec.
+ * AES engine spends about 176 cycles/16-bytes or 11 cycles/byte
+ * The duration CPU can use the BSE to 1 msec, then the number of available
+ * cycles of AVP/BSE is 216K. In this duration, AES can process 216/11 ~= 19KB
+ * Based on this AES_HW_DMA_BUFFER_SIZE_BYTES is configured to 16KB.
+ */
+#define AES_HW_DMA_BUFFER_SIZE_BYTES 0x4000
+
+/*
+ * The key table length is 64 bytes
+ * (This includes first upto 32 bytes key + 16 bytes original initial vector
+ * and 16 bytes updated initial vector)
+ */
+#define AES_HW_KEY_TABLE_LENGTH_BYTES 64
+
+/*
+ * The memory being used is divides as follows:
+ * 1. Key - 32 bytes
+ * 2. Original IV - 16 bytes
+ * 3. Updated IV - 16 bytes
+ * 4. Key schedule - 256 bytes
+ *
+ * 1+2+3 constitute the hw key table.
+ */
+#define AES_HW_IV_SIZE 16
+#define AES_HW_KEYSCHEDULE_LEN 256
+#define AES_IVKEY_SIZE (AES_HW_KEY_TABLE_LENGTH_BYTES + AES_HW_KEYSCHEDULE_LEN)
+
+/* Define commands required for AES operation */
+enum {
+	CMD_BLKSTARTENGINE = 0x0E,
+	CMD_DMASETUP = 0x10,
+	CMD_DMACOMPLETE = 0x11,
+	CMD_SETTABLE = 0x15,
+	CMD_MEMDMAVD = 0x22,
+};
+
+/* Define sub-commands */
+enum {
+	SUBCMD_VRAM_SEL = 0x1,
+	SUBCMD_CRYPTO_TABLE_SEL = 0x3,
+	SUBCMD_KEY_TABLE_SEL = 0x8,
+};
+
+/* memdma_vd command */
+#define MEMDMA_DIR_DTOVRAM		0 /* sdram -> vram */
+#define MEMDMA_DIR_VTODRAM		1 /* vram -> sdram */
+#define MEMDMA_DIR_SHIFT		25
+#define MEMDMA_NUM_WORDS_SHIFT		12
+
+/* command queue bit shifts */
+enum {
+	CMDQ_KEYTABLEADDR_SHIFT = 0,
+	CMDQ_KEYTABLEID_SHIFT = 17,
+	CMDQ_VRAMSEL_SHIFT = 23,
+	CMDQ_TABLESEL_SHIFT = 24,
+	CMDQ_OPCODE_SHIFT = 26,
+};
+
+/*
+ * The secure key slot contains a unique secure key generated
+ * and loaded by the bootloader. This slot is marked as non-accessible
+ * to the kernel.
+ */
+#define SSK_SLOT_NUM		4
+
+#define AES_NR_KEYSLOTS		8
+#define TEGRA_AES_QUEUE_LENGTH	50
+#define DEFAULT_RNG_BLK_SZ	16
+
+/* The command queue depth */
+#define AES_HW_MAX_ICQ_LENGTH	5
+
+struct tegra_aes_slot {
+	struct list_head node;
+	int slot_num;
+};
+
+static struct tegra_aes_slot ssk = {
+	.slot_num = SSK_SLOT_NUM,
+};
+
+struct tegra_aes_reqctx {
+	unsigned long mode;
+};
+
+struct tegra_aes_dev {
+	struct device *dev;
+	void __iomem *io_base;
+	dma_addr_t ivkey_phys_base;
+	void __iomem *ivkey_base;
+	struct clk *aes_clk;
+	struct tegra_aes_ctx *ctx;
+	int irq;
+	unsigned long flags;
+	struct completion op_complete;
+	u32 *buf_in;
+	dma_addr_t dma_buf_in;
+	u32 *buf_out;
+	dma_addr_t dma_buf_out;
+	u8 *iv;
+	u8 dt[DEFAULT_RNG_BLK_SZ];
+	int ivlen;
+	u64 ctr;
+	spinlock_t lock;
+	struct crypto_queue queue;
+	struct tegra_aes_slot *slots;
+	struct ablkcipher_request *req;
+	size_t total;
+	struct scatterlist *in_sg;
+	size_t in_offset;
+	struct scatterlist *out_sg;
+	size_t out_offset;
+};
+
+static struct tegra_aes_dev *aes_dev;
+
+struct tegra_aes_ctx {
+	struct tegra_aes_dev *dd;
+	unsigned long flags;
+	struct tegra_aes_slot *slot;
+	u8 key[AES_MAX_KEY_SIZE];
+	size_t keylen;
+};
+
+static struct tegra_aes_ctx rng_ctx = {
+	.flags = FLAGS_NEW_KEY,
+	.keylen = AES_KEYSIZE_128,
+};
+
+/* keep registered devices data here */
+static struct list_head dev_list;
+static DEFINE_SPINLOCK(list_lock);
+static DEFINE_MUTEX(aes_lock);
+
+static void aes_workqueue_handler(struct work_struct *work);
+static DECLARE_WORK(aes_work, aes_workqueue_handler);
+static struct workqueue_struct *aes_wq;
+
+extern unsigned long long tegra_chip_uid(void);
+
+static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset)
+{
+	return readl(dd->io_base + offset);
+}
+
+static inline void aes_writel(struct tegra_aes_dev *dd, u32 val, u32 offset)
+{
+	writel(val, dd->io_base + offset);
+}
+
+static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr,
+	int nblocks, int mode, bool upd_iv)
+{
+	u32 cmdq[AES_HW_MAX_ICQ_LENGTH];
+	int i, eng_busy, icq_empty, ret;
+	u32 value;
+
+	/* reset all the interrupt bits */
+	aes_writel(dd, 0xFFFFFFFF, TEGRA_AES_INTR_STATUS);
+
+	/* enable error, dma xfer complete interrupts */
+	aes_writel(dd, 0x33, TEGRA_AES_INT_ENB);
+
+	cmdq[0] = CMD_DMASETUP << CMDQ_OPCODE_SHIFT;
+	cmdq[1] = in_addr;
+	cmdq[2] = CMD_BLKSTARTENGINE << CMDQ_OPCODE_SHIFT | (nblocks-1);
+	cmdq[3] = CMD_DMACOMPLETE << CMDQ_OPCODE_SHIFT;
+
+	value = aes_readl(dd, TEGRA_AES_CMDQUE_CONTROL);
+	/* access SDRAM through AHB */
+	value &= ~TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD;
+	value &= ~TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD;
+	value |= TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD |
+		 TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD |
+		 TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD;
+	aes_writel(dd, value, TEGRA_AES_CMDQUE_CONTROL);
+	dev_dbg(dd->dev, "cmd_q_ctrl=0x%x", value);
+
+	value = (0x1 << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT) |
+		((dd->ctx->keylen * 8) <<
+			TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT) |
+		((u32)upd_iv << TEGRA_AES_SECURE_IV_SELECT_SHIFT);
+
+	if (mode & FLAGS_CBC) {
+		value |= ((((mode & FLAGS_ENCRYPT) ? 2 : 3)
+				<< TEGRA_AES_SECURE_XOR_POS_SHIFT) |
+			(((mode & FLAGS_ENCRYPT) ? 2 : 3)
+				<< TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT) |
+			((mode & FLAGS_ENCRYPT) ? 1 : 0)
+				<< TEGRA_AES_SECURE_CORE_SEL_SHIFT);
+	} else if (mode & FLAGS_OFB) {
+		value |= ((TEGRA_AES_SECURE_XOR_POS_FIELD) |
+			(2 << TEGRA_AES_SECURE_INPUT_SEL_SHIFT) |
+			(TEGRA_AES_SECURE_CORE_SEL_FIELD));
+	} else if (mode & FLAGS_RNG) {
+		value |= (((mode & FLAGS_ENCRYPT) ? 1 : 0)
+				<< TEGRA_AES_SECURE_CORE_SEL_SHIFT |
+			  TEGRA_AES_SECURE_RNG_ENB_FIELD);
+	} else {
+		value |= (((mode & FLAGS_ENCRYPT) ? 1 : 0)
+				<< TEGRA_AES_SECURE_CORE_SEL_SHIFT);
+	}
+
+	dev_dbg(dd->dev, "secure_in_sel=0x%x", value);
+	aes_writel(dd, value, TEGRA_AES_SECURE_INPUT_SELECT);
+
+	aes_writel(dd, out_addr, TEGRA_AES_SECURE_DEST_ADDR);
+	INIT_COMPLETION(dd->op_complete);
+
+	for (i = 0; i < AES_HW_MAX_ICQ_LENGTH - 1; i++) {
+		do {
+			value = aes_readl(dd, TEGRA_AES_INTR_STATUS);
+			eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD;
+			icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD;
+		} while (eng_busy & (!icq_empty));
+		aes_writel(dd, cmdq[i], TEGRA_AES_ICMDQUE_WR);
+	}
+
+	ret = wait_for_completion_timeout(&dd->op_complete,
+					  msecs_to_jiffies(150));
+	if (ret == 0) {
+		dev_err(dd->dev, "timed out (0x%x)\n",
+			aes_readl(dd, TEGRA_AES_INTR_STATUS));
+		return -ETIMEDOUT;
+	}
+
+	aes_writel(dd, cmdq[AES_HW_MAX_ICQ_LENGTH - 1], TEGRA_AES_ICMDQUE_WR);
+	return 0;
+}
+
+static void aes_release_key_slot(struct tegra_aes_slot *slot)
+{
+	if (slot->slot_num == SSK_SLOT_NUM)
+		return;
+
+	spin_lock(&list_lock);
+	list_add_tail(&slot->node, &dev_list);
+	slot = NULL;
+	spin_unlock(&list_lock);
+}
+
+static struct tegra_aes_slot *aes_find_key_slot(void)
+{
+	struct tegra_aes_slot *slot = NULL;
+	struct list_head *new_head;
+	int empty;
+
+	spin_lock(&list_lock);
+	empty = list_empty(&dev_list);
+	if (!empty) {
+		slot = list_entry(&dev_list, struct tegra_aes_slot, node);
+		new_head = dev_list.next;
+		list_del(&dev_list);
+		dev_list.next = new_head->next;
+		dev_list.prev = NULL;
+	}
+	spin_unlock(&list_lock);
+
+	return slot;
+}
+
+static int aes_set_key(struct tegra_aes_dev *dd)
+{
+	u32 value, cmdq[2];
+	struct tegra_aes_ctx *ctx = dd->ctx;
+	int eng_busy, icq_empty, dma_busy;
+	bool use_ssk = false;
+
+	/* use ssk? */
+	if (!dd->ctx->slot) {
+		dev_dbg(dd->dev, "using ssk");
+		dd->ctx->slot = &ssk;
+		use_ssk = true;
+	}
+
+	/* enable key schedule generation in hardware */
+	value = aes_readl(dd, TEGRA_AES_SECURE_CONFIG_EXT);
+	value &= ~TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD;
+	aes_writel(dd, value, TEGRA_AES_SECURE_CONFIG_EXT);
+
+	/* select the key slot */
+	value = aes_readl(dd, TEGRA_AES_SECURE_CONFIG);
+	value &= ~TEGRA_AES_SECURE_KEY_INDEX_FIELD;
+	value |= (ctx->slot->slot_num << TEGRA_AES_SECURE_KEY_INDEX_SHIFT);
+	aes_writel(dd, value, TEGRA_AES_SECURE_CONFIG);
+
+	if (use_ssk)
+		return 0;
+
+	/* copy the key table from sdram to vram */
+	cmdq[0] = CMD_MEMDMAVD << CMDQ_OPCODE_SHIFT |
+		MEMDMA_DIR_DTOVRAM << MEMDMA_DIR_SHIFT |
+		AES_HW_KEY_TABLE_LENGTH_BYTES / sizeof(u32) <<
+			MEMDMA_NUM_WORDS_SHIFT;
+	cmdq[1] = (u32)dd->ivkey_phys_base;
+
+	aes_writel(dd, cmdq[0], TEGRA_AES_ICMDQUE_WR);
+	aes_writel(dd, cmdq[1], TEGRA_AES_ICMDQUE_WR);
+
+	do {
+		value = aes_readl(dd, TEGRA_AES_INTR_STATUS);
+		eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD;
+		icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD;
+		dma_busy = value & TEGRA_AES_DMA_BUSY_FIELD;
+	} while (eng_busy & (!icq_empty) & dma_busy);
+
+	/* settable command to get key into internal registers */
+	value = CMD_SETTABLE << CMDQ_OPCODE_SHIFT |
+		SUBCMD_CRYPTO_TABLE_SEL << CMDQ_TABLESEL_SHIFT |
+		SUBCMD_VRAM_SEL << CMDQ_VRAMSEL_SHIFT |
+		(SUBCMD_KEY_TABLE_SEL | ctx->slot->slot_num) <<
+			CMDQ_KEYTABLEID_SHIFT;
+	aes_writel(dd, value, TEGRA_AES_ICMDQUE_WR);
+
+	do {
+		value = aes_readl(dd, TEGRA_AES_INTR_STATUS);
+		eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD;
+		icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD;
+	} while (eng_busy & (!icq_empty));
+
+	return 0;
+}
+
+static int tegra_aes_handle_req(struct tegra_aes_dev *dd)
+{
+	struct crypto_async_request *async_req, *backlog;
+	struct crypto_ablkcipher *tfm;
+	struct tegra_aes_ctx *ctx;
+	struct tegra_aes_reqctx *rctx;
+	struct ablkcipher_request *req;
+	unsigned long flags;
+	int dma_max = AES_HW_DMA_BUFFER_SIZE_BYTES;
+	int ret = 0, nblocks, total;
+	int count = 0;
+	dma_addr_t addr_in, addr_out;
+	struct scatterlist *in_sg, *out_sg;
+
+	if (!dd)
+		return -EINVAL;
+
+	spin_lock_irqsave(&dd->lock, flags);
+	backlog = crypto_get_backlog(&dd->queue);
+	async_req = crypto_dequeue_request(&dd->queue);
+	if (!async_req)
+		clear_bit(FLAGS_BUSY, &dd->flags);
+	spin_unlock_irqrestore(&dd->lock, flags);
+
+	if (!async_req)
+		return -ENODATA;
+
+	if (backlog)
+		backlog->complete(backlog, -EINPROGRESS);
+
+	req = ablkcipher_request_cast(async_req);
+
+	dev_dbg(dd->dev, "%s: get new req\n", __func__);
+
+	if (!req->src || !req->dst)
+		return -EINVAL;
+
+	/* take mutex to access the aes hw */
+	mutex_lock(&aes_lock);
+
+	/* assign new request to device */
+	dd->req = req;
+	dd->total = req->nbytes;
+	dd->in_offset = 0;
+	dd->in_sg = req->src;
+	dd->out_offset = 0;
+	dd->out_sg = req->dst;
+
+	in_sg = dd->in_sg;
+	out_sg = dd->out_sg;
+
+	total = dd->total;
+
+	tfm = crypto_ablkcipher_reqtfm(req);
+	rctx = ablkcipher_request_ctx(req);
+	ctx = crypto_ablkcipher_ctx(tfm);
+	rctx->mode &= FLAGS_MODE_MASK;
+	dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode;
+
+	dd->iv = (u8 *)req->info;
+	dd->ivlen = crypto_ablkcipher_ivsize(tfm);
+
+	/* assign new context to device */
+	ctx->dd = dd;
+	dd->ctx = ctx;
+
+	if (ctx->flags & FLAGS_NEW_KEY) {
+		/* copy the key */
+		memcpy(dd->ivkey_base, ctx->key, ctx->keylen);
+		memset(dd->ivkey_base + ctx->keylen, 0, AES_HW_KEY_TABLE_LENGTH_BYTES - ctx->keylen);
+		aes_set_key(dd);
+		ctx->flags &= ~FLAGS_NEW_KEY;
+	}
+
+	if (((dd->flags & FLAGS_CBC) || (dd->flags & FLAGS_OFB)) && dd->iv) {
+		/* set iv to the aes hw slot
+		 * Hw generates updated iv only after iv is set in slot.
+		 * So key and iv is passed asynchronously.
+		 */
+		memcpy(dd->buf_in, dd->iv, dd->ivlen);
+
+		ret = aes_start_crypt(dd, (u32)dd->dma_buf_in,
+				      dd->dma_buf_out, 1, FLAGS_CBC, false);
+		if (ret < 0) {
+			dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret);
+			goto out;
+		}
+	}
+
+	while (total) {
+		dev_dbg(dd->dev, "remain: %d\n", total);
+		ret = dma_map_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE);
+		if (!ret) {
+			dev_err(dd->dev, "dma_map_sg() error\n");
+			goto out;
+		}
+
+		ret = dma_map_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE);
+		if (!ret) {
+			dev_err(dd->dev, "dma_map_sg() error\n");
+			dma_unmap_sg(dd->dev, dd->in_sg,
+				1, DMA_TO_DEVICE);
+			goto out;
+		}
+
+		addr_in = sg_dma_address(in_sg);
+		addr_out = sg_dma_address(out_sg);
+		dd->flags |= FLAGS_FAST;
+		count = min_t(int, sg_dma_len(in_sg), dma_max);
+		WARN_ON(sg_dma_len(in_sg) != sg_dma_len(out_sg));
+		nblocks = DIV_ROUND_UP(count, AES_BLOCK_SIZE);
+
+		ret = aes_start_crypt(dd, addr_in, addr_out, nblocks,
+			dd->flags, true);
+
+		dma_unmap_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE);
+		dma_unmap_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE);
+
+		if (ret < 0) {
+			dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret);
+			goto out;
+		}
+		dd->flags &= ~FLAGS_FAST;
+
+		dev_dbg(dd->dev, "out: copied %d\n", count);
+		total -= count;
+		in_sg = sg_next(in_sg);
+		out_sg = sg_next(out_sg);
+		WARN_ON(((total != 0) && (!in_sg || !out_sg)));
+	}
+
+out:
+	mutex_unlock(&aes_lock);
+
+	dd->total = total;
+
+	if (dd->req->base.complete)
+		dd->req->base.complete(&dd->req->base, ret);
+
+	dev_dbg(dd->dev, "%s: exit\n", __func__);
+	return ret;
+}
+
+static int tegra_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+			    unsigned int keylen)
+{
+	struct tegra_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+	struct tegra_aes_dev *dd = aes_dev;
+	struct tegra_aes_slot *key_slot;
+
+	if ((keylen != AES_KEYSIZE_128) && (keylen != AES_KEYSIZE_192) &&
+		(keylen != AES_KEYSIZE_256)) {
+		dev_err(dd->dev, "unsupported key size\n");
+		crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+		return -EINVAL;
+	}
+
+	dev_dbg(dd->dev, "keylen: %d\n", keylen);
+
+	ctx->dd = dd;
+
+	if (key) {
+		if (!ctx->slot) {
+			key_slot = aes_find_key_slot();
+			if (!key_slot) {
+				dev_err(dd->dev, "no empty slot\n");
+				return -ENOMEM;
+			}
+
+			ctx->slot = key_slot;
+		}
+
+		memcpy(ctx->key, key, keylen);
+		ctx->keylen = keylen;
+	}
+
+	ctx->flags |= FLAGS_NEW_KEY;
+	dev_dbg(dd->dev, "done\n");
+	return 0;
+}
+
+static void aes_workqueue_handler(struct work_struct *work)
+{
+	struct tegra_aes_dev *dd = aes_dev;
+	int ret;
+
+	ret = clk_enable(dd->aes_clk);
+	if (ret)
+		BUG_ON("clock enable failed");
+
+	/* empty the crypto queue and then return */
+	do {
+		ret = tegra_aes_handle_req(dd);
+	} while (!ret);
+
+	clk_disable(dd->aes_clk);
+}
+
+static irqreturn_t aes_irq(int irq, void *dev_id)
+{
+	struct tegra_aes_dev *dd = (struct tegra_aes_dev *)dev_id;
+	u32 value = aes_readl(dd, TEGRA_AES_INTR_STATUS);
+	int busy = test_bit(FLAGS_BUSY, &dd->flags);
+
+	if (!busy) {
+		dev_dbg(dd->dev, "spurious interrupt\n");
+		return IRQ_NONE;
+	}
+
+	dev_dbg(dd->dev, "irq_stat: 0x%x\n", value);
+	if (value & TEGRA_AES_INT_ERROR_MASK)
+		aes_writel(dd, TEGRA_AES_INT_ERROR_MASK, TEGRA_AES_INTR_STATUS);
+
+	if (!(value & TEGRA_AES_ENGINE_BUSY_FIELD))
+		complete(&dd->op_complete);
+	else
+		return IRQ_NONE;
+
+	return IRQ_HANDLED;
+}
+
+static int tegra_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
+{
+	struct tegra_aes_reqctx *rctx = ablkcipher_request_ctx(req);
+	struct tegra_aes_dev *dd = aes_dev;
+	unsigned long flags;
+	int err = 0;
+	int busy;
+
+	dev_dbg(dd->dev, "nbytes: %d, enc: %d, cbc: %d, ofb: %d\n",
+		req->nbytes, !!(mode & FLAGS_ENCRYPT),
+		!!(mode & FLAGS_CBC), !!(mode & FLAGS_OFB));
+
+	rctx->mode = mode;
+
+	spin_lock_irqsave(&dd->lock, flags);
+	err = ablkcipher_enqueue_request(&dd->queue, req);
+	busy = test_and_set_bit(FLAGS_BUSY, &dd->flags);
+	spin_unlock_irqrestore(&dd->lock, flags);
+
+	if (!busy)
+		queue_work(aes_wq, &aes_work);
+
+	return err;
+}
+
+static int tegra_aes_ecb_encrypt(struct ablkcipher_request *req)
+{
+	return tegra_aes_crypt(req, FLAGS_ENCRYPT);
+}
+
+static int tegra_aes_ecb_decrypt(struct ablkcipher_request *req)
+{
+	return tegra_aes_crypt(req, 0);
+}
+
+static int tegra_aes_cbc_encrypt(struct ablkcipher_request *req)
+{
+	return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
+}
+
+static int tegra_aes_cbc_decrypt(struct ablkcipher_request *req)
+{
+	return tegra_aes_crypt(req, FLAGS_CBC);
+}
+
+static int tegra_aes_ofb_encrypt(struct ablkcipher_request *req)
+{
+	return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_OFB);
+}
+
+static int tegra_aes_ofb_decrypt(struct ablkcipher_request *req)
+{
+	return tegra_aes_crypt(req, FLAGS_OFB);
+}
+
+static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata,
+				unsigned int dlen)
+{
+	struct tegra_aes_dev *dd = aes_dev;
+	struct tegra_aes_ctx *ctx = &rng_ctx;
+	int ret, i;
+	u8 *dest = rdata, *dt = dd->dt;
+
+	/* take mutex to access the aes hw */
+	mutex_lock(&aes_lock);
+
+	ret = clk_enable(dd->aes_clk);
+	if (ret)
+		return ret;
+
+	ctx->dd = dd;
+	dd->ctx = ctx;
+	dd->flags = FLAGS_ENCRYPT | FLAGS_RNG;
+
+	memcpy(dd->buf_in, dt, DEFAULT_RNG_BLK_SZ);
+
+	ret = aes_start_crypt(dd, (u32)dd->dma_buf_in,
+			      (u32)dd->dma_buf_out, 1, dd->flags, true);
+	if (ret < 0) {
+		dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret);
+		dlen = ret;
+		goto out;
+	}
+	memcpy(dest, dd->buf_out, dlen);
+
+	/* update the DT */
+	for (i = DEFAULT_RNG_BLK_SZ - 1; i >= 0; i--) {
+		dt[i] += 1;
+		if (dt[i] != 0)
+			break;
+	}
+
+out:
+	clk_disable(dd->aes_clk);
+	mutex_unlock(&aes_lock);
+
+	dev_dbg(dd->dev, "%s: done\n", __func__);
+	return dlen;
+}
+
+static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed,
+			       unsigned int slen)
+{
+	struct tegra_aes_dev *dd = aes_dev;
+	struct tegra_aes_ctx *ctx = &rng_ctx;
+	struct tegra_aes_slot *key_slot;
+	struct timespec ts;
+	int ret = 0;
+	u64 nsec, tmp[2];
+	u8 *dt;
+
+	if (!ctx || !dd) {
+		dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n",
+			(unsigned int)ctx, (unsigned int)dd);
+		return -EINVAL;
+	}
+
+	if (slen < (DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) {
+		dev_err(dd->dev, "seed size invalid");
+		return -ENOMEM;
+	}
+
+	/* take mutex to access the aes hw */
+	mutex_lock(&aes_lock);
+
+	if (!ctx->slot) {
+		key_slot = aes_find_key_slot();
+		if (!key_slot) {
+			dev_err(dd->dev, "no empty slot\n");
+			mutex_unlock(&aes_lock);
+			return -ENOMEM;
+		}
+		ctx->slot = key_slot;
+	}
+
+	ctx->dd = dd;
+	dd->ctx = ctx;
+	dd->ctr = 0;
+
+	ctx->keylen = AES_KEYSIZE_128;
+	ctx->flags |= FLAGS_NEW_KEY;
+
+	/* copy the key to the key slot */
+	memcpy(dd->ivkey_base, seed + DEFAULT_RNG_BLK_SZ, AES_KEYSIZE_128);
+	memset(dd->ivkey_base + AES_KEYSIZE_128, 0, AES_HW_KEY_TABLE_LENGTH_BYTES - AES_KEYSIZE_128);
+
+	dd->iv = seed;
+	dd->ivlen = slen;
+
+	dd->flags = FLAGS_ENCRYPT | FLAGS_RNG;
+
+	ret = clk_enable(dd->aes_clk);
+	if (ret)
+		return ret;
+
+	aes_set_key(dd);
+
+	/* set seed to the aes hw slot */
+	memcpy(dd->buf_in, dd->iv, DEFAULT_RNG_BLK_SZ);
+	ret = aes_start_crypt(dd, (u32)dd->dma_buf_in,
+			      dd->dma_buf_out, 1, FLAGS_CBC, false);
+	if (ret < 0) {
+		dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret);
+		goto out;
+	}
+
+	if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) {
+		dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128;
+	} else {
+		getnstimeofday(&ts);
+		nsec = timespec_to_ns(&ts);
+		do_div(nsec, 1000);
+		nsec ^= dd->ctr << 56;
+		dd->ctr++;
+		tmp[0] = nsec;
+		tmp[1] = tegra_chip_uid();
+		dt = (u8 *)tmp;
+	}
+	memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ);
+
+out:
+	clk_disable(dd->aes_clk);
+	mutex_unlock(&aes_lock);
+
+	dev_dbg(dd->dev, "%s: done\n", __func__);
+	return ret;
+}
+
+static int tegra_aes_cra_init(struct crypto_tfm *tfm)
+{
+	tfm->crt_ablkcipher.reqsize = sizeof(struct tegra_aes_reqctx);
+
+	return 0;
+}
+
+void tegra_aes_cra_exit(struct crypto_tfm *tfm)
+{
+	struct tegra_aes_ctx *ctx =
+		crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm);
+
+	if (ctx && ctx->slot)
+		aes_release_key_slot(ctx->slot);
+}
+
+static struct crypto_alg algs[] = {
+	{
+		.cra_name = "ecb(aes)",
+		.cra_driver_name = "ecb-aes-tegra",
+		.cra_priority = 300,
+		.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+		.cra_blocksize = AES_BLOCK_SIZE,
+		.cra_alignmask = 3,
+		.cra_type = &crypto_ablkcipher_type,
+		.cra_u.ablkcipher = {
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.setkey = tegra_aes_setkey,
+			.encrypt = tegra_aes_ecb_encrypt,
+			.decrypt = tegra_aes_ecb_decrypt,
+		},
+	}, {
+		.cra_name = "cbc(aes)",
+		.cra_driver_name = "cbc-aes-tegra",
+		.cra_priority = 300,
+		.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+		.cra_blocksize = AES_BLOCK_SIZE,
+		.cra_alignmask = 3,
+		.cra_type = &crypto_ablkcipher_type,
+		.cra_u.ablkcipher = {
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.ivsize = AES_MIN_KEY_SIZE,
+			.setkey = tegra_aes_setkey,
+			.encrypt = tegra_aes_cbc_encrypt,
+			.decrypt = tegra_aes_cbc_decrypt,
+		}
+	}, {
+		.cra_name = "ofb(aes)",
+		.cra_driver_name = "ofb-aes-tegra",
+		.cra_priority = 300,
+		.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+		.cra_blocksize = AES_BLOCK_SIZE,
+		.cra_alignmask = 3,
+		.cra_type = &crypto_ablkcipher_type,
+		.cra_u.ablkcipher = {
+			.min_keysize = AES_MIN_KEY_SIZE,
+			.max_keysize = AES_MAX_KEY_SIZE,
+			.ivsize = AES_MIN_KEY_SIZE,
+			.setkey = tegra_aes_setkey,
+			.encrypt = tegra_aes_ofb_encrypt,
+			.decrypt = tegra_aes_ofb_decrypt,
+		}
+	}, {
+		.cra_name = "ansi_cprng",
+		.cra_driver_name = "rng-aes-tegra",
+		.cra_flags = CRYPTO_ALG_TYPE_RNG,
+		.cra_ctxsize = sizeof(struct tegra_aes_ctx),
+		.cra_type = &crypto_rng_type,
+		.cra_u.rng = {
+			.rng_make_random = tegra_aes_get_random,
+			.rng_reset = tegra_aes_rng_reset,
+			.seedsize = AES_KEYSIZE_128 + (2 * DEFAULT_RNG_BLK_SZ),
+		}
+	}
+};
+
+static int tegra_aes_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra_aes_dev *dd;
+	struct resource *res;
+	int err = -ENOMEM, i = 0, j;
+
+	dd = devm_kzalloc(dev, sizeof(struct tegra_aes_dev), GFP_KERNEL);
+	if (dd == NULL) {
+		dev_err(dev, "unable to alloc data struct.\n");
+		return err;
+	}
+
+	dd->dev = dev;
+	platform_set_drvdata(pdev, dd);
+
+	dd->slots = devm_kzalloc(dev, sizeof(struct tegra_aes_slot) *
+				 AES_NR_KEYSLOTS, GFP_KERNEL);
+	if (dd->slots == NULL) {
+		dev_err(dev, "unable to alloc slot struct.\n");
+		goto out;
+	}
+
+	spin_lock_init(&dd->lock);
+	crypto_init_queue(&dd->queue, TEGRA_AES_QUEUE_LENGTH);
+
+	/* Get the module base address */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "invalid resource type: base\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+				     resource_size(res),
+				     dev_name(&pdev->dev))) {
+		dev_err(&pdev->dev, "Couldn't request MEM resource\n");
+		return -ENODEV;
+	}
+
+	dd->io_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!dd->io_base) {
+		dev_err(dev, "can't ioremap register space\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	/* Initialize the vde clock */
+	dd->aes_clk = clk_get(dev, "vde");
+	if (IS_ERR(dd->aes_clk)) {
+		dev_err(dev, "iclock intialization failed.\n");
+		err = -ENODEV;
+		goto out;
+	}
+
+	err = clk_set_rate(dd->aes_clk, ULONG_MAX);
+	if (err) {
+		dev_err(dd->dev, "iclk set_rate fail(%d)\n", err);
+		goto out;
+	}
+
+	/*
+	 * the foll contiguous memory is allocated as follows -
+	 * - hardware key table
+	 * - key schedule
+	 */
+	dd->ivkey_base = dma_alloc_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES,
+					    &dd->ivkey_phys_base,
+		GFP_KERNEL);
+	if (!dd->ivkey_base) {
+		dev_err(dev, "can not allocate iv/key buffer\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	dd->buf_in = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
+					&dd->dma_buf_in, GFP_KERNEL);
+	if (!dd->buf_in) {
+		dev_err(dev, "can not allocate dma-in buffer\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	dd->buf_out = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
+					 &dd->dma_buf_out, GFP_KERNEL);
+	if (!dd->buf_out) {
+		dev_err(dev, "can not allocate dma-out buffer\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	init_completion(&dd->op_complete);
+	aes_wq = alloc_workqueue("tegra_aes_wq", WQ_HIGHPRI | WQ_UNBOUND, 1);
+	if (!aes_wq) {
+		dev_err(dev, "alloc_workqueue failed\n");
+		goto out;
+	}
+
+	/* get the irq */
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_err(dev, "invalid resource type: base\n");
+		err = -ENODEV;
+		goto out;
+	}
+	dd->irq = res->start;
+
+	err = devm_request_irq(dev, dd->irq, aes_irq, IRQF_TRIGGER_HIGH |
+				IRQF_SHARED, "tegra-aes", dd);
+	if (err) {
+		dev_err(dev, "request_irq failed\n");
+		goto out;
+	}
+
+	mutex_init(&aes_lock);
+	INIT_LIST_HEAD(&dev_list);
+
+	spin_lock_init(&list_lock);
+	spin_lock(&list_lock);
+	for (i = 0; i < AES_NR_KEYSLOTS; i++) {
+		if (i == SSK_SLOT_NUM)
+			continue;
+		dd->slots[i].slot_num = i;
+		INIT_LIST_HEAD(&dd->slots[i].node);
+		list_add_tail(&dd->slots[i].node, &dev_list);
+	}
+	spin_unlock(&list_lock);
+
+	aes_dev = dd;
+	for (i = 0; i < ARRAY_SIZE(algs); i++) {
+		INIT_LIST_HEAD(&algs[i].cra_list);
+
+		algs[i].cra_priority = 300;
+		algs[i].cra_ctxsize = sizeof(struct tegra_aes_ctx);
+		algs[i].cra_module = THIS_MODULE;
+		algs[i].cra_init = tegra_aes_cra_init;
+		algs[i].cra_exit = tegra_aes_cra_exit;
+
+		err = crypto_register_alg(&algs[i]);
+		if (err)
+			goto out;
+	}
+
+	dev_info(dev, "registered");
+	return 0;
+
+out:
+	for (j = 0; j < i; j++)
+		crypto_unregister_alg(&algs[j]);
+	if (dd->ivkey_base)
+		dma_free_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES,
+			dd->ivkey_base, dd->ivkey_phys_base);
+	if (dd->buf_in)
+		dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
+			dd->buf_in, dd->dma_buf_in);
+	if (dd->buf_out)
+		dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
+			dd->buf_out, dd->dma_buf_out);
+	if (IS_ERR(dd->aes_clk))
+		clk_put(dd->aes_clk);
+	if (aes_wq)
+		destroy_workqueue(aes_wq);
+	spin_lock(&list_lock);
+	list_del(&dev_list);
+	spin_unlock(&list_lock);
+
+	aes_dev = NULL;
+
+	dev_err(dev, "%s: initialization failed.\n", __func__);
+	return err;
+}
+
+static int __devexit tegra_aes_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct tegra_aes_dev *dd = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++)
+		crypto_unregister_alg(&algs[i]);
+
+	cancel_work_sync(&aes_work);
+	destroy_workqueue(aes_wq);
+	spin_lock(&list_lock);
+	list_del(&dev_list);
+	spin_unlock(&list_lock);
+
+	dma_free_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES,
+			  dd->ivkey_base, dd->ivkey_phys_base);
+	dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
+			  dd->buf_in, dd->dma_buf_in);
+	dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES,
+			  dd->buf_out, dd->dma_buf_out);
+	clk_put(dd->aes_clk);
+	aes_dev = NULL;
+
+	return 0;
+}
+
+static struct of_device_id tegra_aes_of_match[] __devinitdata = {
+	{ .compatible = "nvidia,tegra20-aes", },
+	{ .compatible = "nvidia,tegra30-aes", },
+	{ },
+};
+
+static struct platform_driver tegra_aes_driver = {
+	.probe  = tegra_aes_probe,
+	.remove = __devexit_p(tegra_aes_remove),
+	.driver = {
+		.name   = "tegra-aes",
+		.owner  = THIS_MODULE,
+		.of_match_table = tegra_aes_of_match,
+	},
+};
+
+module_platform_driver(tegra_aes_driver);
+
+MODULE_DESCRIPTION("Tegra AES/OFB/CPRNG hw acceleration support.");
+MODULE_AUTHOR("NVIDIA Corporation");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/crypto/tegra-aes.h b/drivers/crypto/tegra-aes.h
new file mode 100644
index 0000000..6006333
--- /dev/null
+++ b/drivers/crypto/tegra-aes.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2010, NVIDIA Corporation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __CRYPTODEV_TEGRA_AES_H
+#define __CRYPTODEV_TEGRA_AES_H
+
+#define TEGRA_AES_ICMDQUE_WR			0x1000
+#define TEGRA_AES_CMDQUE_CONTROL		0x1008
+#define TEGRA_AES_INTR_STATUS			0x1018
+#define TEGRA_AES_INT_ENB			0x1040
+#define TEGRA_AES_CONFIG			0x1044
+#define TEGRA_AES_IRAM_ACCESS_CFG		0x10A0
+#define TEGRA_AES_SECURE_DEST_ADDR		0x1100
+#define TEGRA_AES_SECURE_INPUT_SELECT		0x1104
+#define TEGRA_AES_SECURE_CONFIG			0x1108
+#define TEGRA_AES_SECURE_CONFIG_EXT		0x110C
+#define TEGRA_AES_SECURE_SECURITY		0x1110
+#define TEGRA_AES_SECURE_HASH_RESULT0		0x1120
+#define TEGRA_AES_SECURE_HASH_RESULT1		0x1124
+#define TEGRA_AES_SECURE_HASH_RESULT2		0x1128
+#define TEGRA_AES_SECURE_HASH_RESULT3		0x112C
+#define TEGRA_AES_SECURE_SEC_SEL0		0x1140
+#define TEGRA_AES_SECURE_SEC_SEL1		0x1144
+#define TEGRA_AES_SECURE_SEC_SEL2		0x1148
+#define TEGRA_AES_SECURE_SEC_SEL3		0x114C
+#define TEGRA_AES_SECURE_SEC_SEL4		0x1150
+#define TEGRA_AES_SECURE_SEC_SEL5		0x1154
+#define TEGRA_AES_SECURE_SEC_SEL6		0x1158
+#define TEGRA_AES_SECURE_SEC_SEL7		0x115C
+
+/* interrupt status reg masks and shifts */
+#define TEGRA_AES_ENGINE_BUSY_FIELD		BIT(0)
+#define TEGRA_AES_ICQ_EMPTY_FIELD		BIT(3)
+#define TEGRA_AES_DMA_BUSY_FIELD		BIT(23)
+
+/* secure select reg masks and shifts */
+#define TEGRA_AES_SECURE_SEL0_KEYREAD_ENB0_FIELD	BIT(0)
+
+/* secure config ext masks and shifts */
+#define TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD	BIT(15)
+
+/* secure config masks and shifts */
+#define TEGRA_AES_SECURE_KEY_INDEX_SHIFT	20
+#define TEGRA_AES_SECURE_KEY_INDEX_FIELD	(0x1F << TEGRA_AES_SECURE_KEY_INDEX_SHIFT)
+#define TEGRA_AES_SECURE_BLOCK_CNT_SHIFT	0
+#define TEGRA_AES_SECURE_BLOCK_CNT_FIELD	(0xFFFFF << TEGRA_AES_SECURE_BLOCK_CNT_SHIFT)
+
+/* stream interface select masks and shifts */
+#define TEGRA_AES_CMDQ_CTRL_UCMDQEN_FIELD	BIT(0)
+#define TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD	BIT(1)
+#define TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD	BIT(4)
+#define TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD	BIT(5)
+
+/* config register masks and shifts */
+#define TEGRA_AES_CONFIG_ENDIAN_ENB_FIELD	BIT(10)
+#define TEGRA_AES_CONFIG_MODE_SEL_SHIFT		0
+#define TEGRA_AES_CONFIG_MODE_SEL_FIELD		(0x1F << TEGRA_AES_CONFIG_MODE_SEL_SHIFT)
+
+/* extended config */
+#define TEGRA_AES_SECURE_OFFSET_CNT_SHIFT	24
+#define TEGRA_AES_SECURE_OFFSET_CNT_FIELD	(0xFF << TEGRA_AES_SECURE_OFFSET_CNT_SHIFT)
+#define TEGRA_AES_SECURE_KEYSCHED_GEN_FIELD	BIT(15)
+
+/* init vector select */
+#define TEGRA_AES_SECURE_IV_SELECT_SHIFT	10
+#define TEGRA_AES_SECURE_IV_SELECT_FIELD	BIT(10)
+
+/* secure engine input */
+#define TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT	28
+#define TEGRA_AES_SECURE_INPUT_ALG_SEL_FIELD	(0xF << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT)
+#define TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT	16
+#define TEGRA_AES_SECURE_INPUT_KEY_LEN_FIELD	(0xFFF << TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT)
+#define TEGRA_AES_SECURE_RNG_ENB_FIELD		BIT(11)
+#define TEGRA_AES_SECURE_CORE_SEL_SHIFT		9
+#define TEGRA_AES_SECURE_CORE_SEL_FIELD		BIT(9)
+#define TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT	7
+#define TEGRA_AES_SECURE_VCTRAM_SEL_FIELD	(0x3 << TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT)
+#define TEGRA_AES_SECURE_INPUT_SEL_SHIFT	5
+#define TEGRA_AES_SECURE_INPUT_SEL_FIELD	(0x3 << TEGRA_AES_SECURE_INPUT_SEL_SHIFT)
+#define TEGRA_AES_SECURE_XOR_POS_SHIFT		3
+#define TEGRA_AES_SECURE_XOR_POS_FIELD		(0x3 << TEGRA_AES_SECURE_XOR_POS_SHIFT)
+#define TEGRA_AES_SECURE_HASH_ENB_FIELD		BIT(2)
+#define TEGRA_AES_SECURE_ON_THE_FLY_FIELD	BIT(0)
+
+/* interrupt error mask */
+#define TEGRA_AES_INT_ERROR_MASK		0xFFF000
+
+#endif
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index c189b82..a129a7b 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -501,12 +501,82 @@ static ssize_t show_central_polling(struct device *dev,
 		       !to_devfreq(dev)->governor->no_central_polling);
 }
 
+static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct devfreq *df = to_devfreq(dev);
+	unsigned long value;
+	int ret;
+	unsigned long max;
+
+	ret = sscanf(buf, "%lu", &value);
+	if (ret != 1)
+		goto out;
+
+	mutex_lock(&df->lock);
+	max = df->max_freq;
+	if (value && max && value > max) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	df->min_freq = value;
+	update_devfreq(df);
+	ret = count;
+unlock:
+	mutex_unlock(&df->lock);
+out:
+	return ret;
+}
+
+static ssize_t show_min_freq(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq);
+}
+
+static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct devfreq *df = to_devfreq(dev);
+	unsigned long value;
+	int ret;
+	unsigned long min;
+
+	ret = sscanf(buf, "%lu", &value);
+	if (ret != 1)
+		goto out;
+
+	mutex_lock(&df->lock);
+	min = df->min_freq;
+	if (value && min && value < min) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	df->max_freq = value;
+	update_devfreq(df);
+	ret = count;
+unlock:
+	mutex_unlock(&df->lock);
+out:
+	return ret;
+}
+
+static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq);
+}
+
 static struct device_attribute devfreq_attrs[] = {
 	__ATTR(governor, S_IRUGO, show_governor, NULL),
 	__ATTR(cur_freq, S_IRUGO, show_freq, NULL),
 	__ATTR(central_polling, S_IRUGO, show_central_polling, NULL),
 	__ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval,
 	       store_polling_interval),
+	__ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq),
+	__ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq),
 	{ },
 };
 
diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
index 6460577..590d686 100644
--- a/drivers/devfreq/exynos4_bus.c
+++ b/drivers/devfreq/exynos4_bus.c
@@ -622,9 +622,7 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp,
 static int exynos4_bus_target(struct device *dev, unsigned long *_freq)
 {
 	int err = 0;
-	struct platform_device *pdev = container_of(dev, struct platform_device,
-						    dev);
-	struct busfreq_data *data = platform_get_drvdata(pdev);
+	struct busfreq_data *data = dev_get_drvdata(dev);
 	struct opp *opp = devfreq_recommended_opp(dev, _freq);
 	unsigned long old_freq = opp_get_freq(data->curr_opp);
 	unsigned long freq = opp_get_freq(opp);
@@ -689,9 +687,7 @@ static int exynos4_get_busier_dmc(struct busfreq_data *data)
 static int exynos4_bus_get_dev_status(struct device *dev,
 				      struct devfreq_dev_status *stat)
 {
-	struct platform_device *pdev = container_of(dev, struct platform_device,
-						    dev);
-	struct busfreq_data *data = platform_get_drvdata(pdev);
+	struct busfreq_data *data = dev_get_drvdata(dev);
 	int busier_dmc;
 	int cycles_x2 = 2; /* 2 x cycles */
 	void __iomem *addr;
@@ -739,9 +735,7 @@ static int exynos4_bus_get_dev_status(struct device *dev,
 
 static void exynos4_bus_exit(struct device *dev)
 {
-	struct platform_device *pdev = container_of(dev, struct platform_device,
-						    dev);
-	struct busfreq_data *data = platform_get_drvdata(pdev);
+	struct busfreq_data *data = dev_get_drvdata(dev);
 
 	devfreq_unregister_opp_notifier(dev, data->devfreq);
 }
@@ -1087,9 +1081,7 @@ static __devexit int exynos4_busfreq_remove(struct platform_device *pdev)
 
 static int exynos4_busfreq_resume(struct device *dev)
 {
-	struct platform_device *pdev = container_of(dev, struct platform_device,
-						    dev);
-	struct busfreq_data *data = platform_get_drvdata(pdev);
+	struct busfreq_data *data = dev_get_drvdata(dev);
 
 	busfreq_mon_reset(data);
 	return 0;
@@ -1132,4 +1124,3 @@ module_exit(exynos4_busfreq_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
-MODULE_ALIAS("exynos4-busfreq");
diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c
index c0596b2..574a06b 100644
--- a/drivers/devfreq/governor_performance.c
+++ b/drivers/devfreq/governor_performance.c
@@ -18,7 +18,10 @@ static int devfreq_performance_func(struct devfreq *df,
 	 * target callback should be able to get floor value as
 	 * said in devfreq.h
 	 */
-	*freq = UINT_MAX;
+	if (!df->max_freq)
+		*freq = UINT_MAX;
+	else
+		*freq = df->max_freq;
 	return 0;
 }
 
diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c
index 2483a85..d742d4a 100644
--- a/drivers/devfreq/governor_powersave.c
+++ b/drivers/devfreq/governor_powersave.c
@@ -18,7 +18,7 @@ static int devfreq_powersave_func(struct devfreq *df,
 	 * target callback should be able to get ceiling value as
 	 * said in devfreq.h
 	 */
-	*freq = 0;
+	*freq = df->min_freq;
 	return 0;
 }
 
diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c
index efad8dc..a2e3eae 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -25,6 +25,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 	unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD;
 	unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL;
 	struct devfreq_simple_ondemand_data *data = df->data;
+	unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX;
 
 	if (err)
 		return err;
@@ -41,7 +42,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 
 	/* Assume MAX if it is going to be divided by zero */
 	if (stat.total_time == 0) {
-		*freq = UINT_MAX;
+		*freq = max;
 		return 0;
 	}
 
@@ -54,13 +55,13 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 	/* Set MAX if it's busy enough */
 	if (stat.busy_time * 100 >
 	    stat.total_time * dfso_upthreshold) {
-		*freq = UINT_MAX;
+		*freq = max;
 		return 0;
 	}
 
 	/* Set MAX if we do not know the initial frequency */
 	if (stat.current_frequency == 0) {
-		*freq = UINT_MAX;
+		*freq = max;
 		return 0;
 	}
 
@@ -79,6 +80,11 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
 	b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2));
 	*freq = (unsigned long) b;
 
+	if (df->min_freq && *freq < df->min_freq)
+		*freq = df->min_freq;
+	if (df->max_freq && *freq > df->max_freq)
+		*freq = df->max_freq;
+
 	return 0;
 }
 
diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
index 4f8b563..0681246 100644
--- a/drivers/devfreq/governor_userspace.c
+++ b/drivers/devfreq/governor_userspace.c
@@ -25,10 +25,19 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
 {
 	struct userspace_data *data = df->data;
 
-	if (!data->valid)
+	if (data->valid) {
+		unsigned long adjusted_freq = data->user_frequency;
+
+		if (df->max_freq && adjusted_freq > df->max_freq)
+			adjusted_freq = df->max_freq;
+
+		if (df->min_freq && adjusted_freq < df->min_freq)
+			adjusted_freq = df->min_freq;
+
+		*freq = adjusted_freq;
+	} else {
 		*freq = df->previous_freq; /* No user freq specified yet */
-	else
-		*freq = data->user_frequency;
+	}
 	return 0;
 }
 
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index f1a2749..4a6c46d 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -252,6 +252,15 @@ config EP93XX_DMA
 	help
 	  Enable support for the Cirrus Logic EP93xx M2P/M2M DMA controller.
 
+config DMA_SA11X0
+	tristate "SA-11x0 DMA support"
+	depends on ARCH_SA1100
+	select DMA_ENGINE
+	help
+	  Support the DMA engine found on Intel StrongARM SA-1100 and
+	  SA-1110 SoCs.  This DMA engine can only be used with on-chip
+	  devices.
+
 config DMA_ENGINE
 	bool
 
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 009a222..86b795b 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -27,3 +27,4 @@ obj-$(CONFIG_PL330_DMA) += pl330.o
 obj-$(CONFIG_PCH_DMA) += pch_dma.o
 obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
 obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
+obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 8a28158..840c6c0 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -649,7 +649,7 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x,
 			}
 
 			if ((bd.srcbus.addr % bd.srcbus.buswidth) ||
-					(bd.srcbus.addr % bd.srcbus.buswidth)) {
+					(bd.dstbus.addr % bd.dstbus.buswidth)) {
 				dev_err(&pl08x->adev->dev,
 					"%s src & dst address must be aligned to src"
 					" & dst width if peripheral is flow controller",
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index e4383ee..3296a73 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -186,8 +186,6 @@ static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx)
 
 	cookie = imxdma_assign_cookie(imxdmac);
 
-	imx_dma_enable(imxdmac->imxdma_channel);
-
 	spin_unlock_irq(&imxdmac->lock);
 
 	return cookie;
@@ -332,9 +330,10 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
 
 static void imxdma_issue_pending(struct dma_chan *chan)
 {
-	/*
-	 * Nothing to do. We only have a single descriptor
-	 */
+	struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
+
+	if (imxdmac->status == DMA_IN_PROGRESS)
+		imx_dma_enable(imxdmac->imxdma_channel);
 }
 
 static int __init imxdma_probe(struct platform_device *pdev)
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 8bc5acf..bf736ad 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/bitops.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
@@ -260,8 +261,8 @@ struct sdma_channel {
 	unsigned int			pc_from_device, pc_to_device;
 	unsigned long			flags;
 	dma_addr_t			per_address;
-	u32				event_mask0, event_mask1;
-	u32				watermark_level;
+	unsigned long			event_mask[2];
+	unsigned long			watermark_level;
 	u32				shp_addr, per_addr;
 	struct dma_chan			chan;
 	spinlock_t			lock;
@@ -272,7 +273,7 @@ struct sdma_channel {
 	unsigned int			chn_real_count;
 };
 
-#define IMX_DMA_SG_LOOP		(1 << 0)
+#define IMX_DMA_SG_LOOP		BIT(0)
 
 #define MAX_DMA_CHANNELS 32
 #define MXC_SDMA_DEFAULT_PRIORITY 1
@@ -346,9 +347,9 @@ static const struct of_device_id sdma_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, sdma_dt_ids);
 
-#define SDMA_H_CONFIG_DSPDMA	(1 << 12) /* indicates if the DSPDMA is used */
-#define SDMA_H_CONFIG_RTD_PINS	(1 << 11) /* indicates if Real-Time Debug pins are enabled */
-#define SDMA_H_CONFIG_ACR	(1 << 4)  /* indicates if AHB freq /core freq = 2 or 1 */
+#define SDMA_H_CONFIG_DSPDMA	BIT(12) /* indicates if the DSPDMA is used */
+#define SDMA_H_CONFIG_RTD_PINS	BIT(11) /* indicates if Real-Time Debug pins are enabled */
+#define SDMA_H_CONFIG_ACR	BIT(4)  /* indicates if AHB freq /core freq = 2 or 1 */
 #define SDMA_H_CONFIG_CSM	(3)       /* indicates which context switch mode is selected*/
 
 static inline u32 chnenbl_ofs(struct sdma_engine *sdma, unsigned int event)
@@ -363,37 +364,42 @@ static int sdma_config_ownership(struct sdma_channel *sdmac,
 {
 	struct sdma_engine *sdma = sdmac->sdma;
 	int channel = sdmac->channel;
-	u32 evt, mcu, dsp;
+	unsigned long evt, mcu, dsp;
 
 	if (event_override && mcu_override && dsp_override)
 		return -EINVAL;
 
-	evt = __raw_readl(sdma->regs + SDMA_H_EVTOVR);
-	mcu = __raw_readl(sdma->regs + SDMA_H_HOSTOVR);
-	dsp = __raw_readl(sdma->regs + SDMA_H_DSPOVR);
+	evt = readl_relaxed(sdma->regs + SDMA_H_EVTOVR);
+	mcu = readl_relaxed(sdma->regs + SDMA_H_HOSTOVR);
+	dsp = readl_relaxed(sdma->regs + SDMA_H_DSPOVR);
 
 	if (dsp_override)
-		dsp &= ~(1 << channel);
+		__clear_bit(channel, &dsp);
 	else
-		dsp |= (1 << channel);
+		__set_bit(channel, &dsp);
 
 	if (event_override)
-		evt &= ~(1 << channel);
+		__clear_bit(channel, &evt);
 	else
-		evt |= (1 << channel);
+		__set_bit(channel, &evt);
 
 	if (mcu_override)
-		mcu &= ~(1 << channel);
+		__clear_bit(channel, &mcu);
 	else
-		mcu |= (1 << channel);
+		__set_bit(channel, &mcu);
 
-	__raw_writel(evt, sdma->regs + SDMA_H_EVTOVR);
-	__raw_writel(mcu, sdma->regs + SDMA_H_HOSTOVR);
-	__raw_writel(dsp, sdma->regs + SDMA_H_DSPOVR);
+	writel_relaxed(evt, sdma->regs + SDMA_H_EVTOVR);
+	writel_relaxed(mcu, sdma->regs + SDMA_H_HOSTOVR);
+	writel_relaxed(dsp, sdma->regs + SDMA_H_DSPOVR);
 
 	return 0;
 }
 
+static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
+{
+	writel(BIT(channel), sdma->regs + SDMA_H_START);
+}
+
 /*
  * sdma_run_channel - run a channel and wait till it's done
  */
@@ -405,7 +411,7 @@ static int sdma_run_channel(struct sdma_channel *sdmac)
 
 	init_completion(&sdmac->done);
 
-	__raw_writel(1 << channel, sdma->regs + SDMA_H_START);
+	sdma_enable_channel(sdma, channel);
 
 	ret = wait_for_completion_timeout(&sdmac->done, HZ);
 
@@ -452,12 +458,12 @@ static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event)
 {
 	struct sdma_engine *sdma = sdmac->sdma;
 	int channel = sdmac->channel;
-	u32 val;
+	unsigned long val;
 	u32 chnenbl = chnenbl_ofs(sdma, event);
 
-	val = __raw_readl(sdma->regs + chnenbl);
-	val |= (1 << channel);
-	__raw_writel(val, sdma->regs + chnenbl);
+	val = readl_relaxed(sdma->regs + chnenbl);
+	__set_bit(channel, &val);
+	writel_relaxed(val, sdma->regs + chnenbl);
 }
 
 static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
@@ -465,11 +471,11 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
 	struct sdma_engine *sdma = sdmac->sdma;
 	int channel = sdmac->channel;
 	u32 chnenbl = chnenbl_ofs(sdma, event);
-	u32 val;
+	unsigned long val;
 
-	val = __raw_readl(sdma->regs + chnenbl);
-	val &= ~(1 << channel);
-	__raw_writel(val, sdma->regs + chnenbl);
+	val = readl_relaxed(sdma->regs + chnenbl);
+	__clear_bit(channel, &val);
+	writel_relaxed(val, sdma->regs + chnenbl);
 }
 
 static void sdma_handle_channel_loop(struct sdma_channel *sdmac)
@@ -545,10 +551,10 @@ static void mxc_sdma_handle_channel(struct sdma_channel *sdmac)
 static irqreturn_t sdma_int_handler(int irq, void *dev_id)
 {
 	struct sdma_engine *sdma = dev_id;
-	u32 stat;
+	unsigned long stat;
 
-	stat = __raw_readl(sdma->regs + SDMA_H_INTR);
-	__raw_writel(stat, sdma->regs + SDMA_H_INTR);
+	stat = readl_relaxed(sdma->regs + SDMA_H_INTR);
+	writel_relaxed(stat, sdma->regs + SDMA_H_INTR);
 
 	while (stat) {
 		int channel = fls(stat) - 1;
@@ -556,7 +562,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
 
 		mxc_sdma_handle_channel(sdmac);
 
-		stat &= ~(1 << channel);
+		__clear_bit(channel, &stat);
 	}
 
 	return IRQ_HANDLED;
@@ -664,11 +670,11 @@ static int sdma_load_context(struct sdma_channel *sdmac)
 		return load_address;
 
 	dev_dbg(sdma->dev, "load_address = %d\n", load_address);
-	dev_dbg(sdma->dev, "wml = 0x%08x\n", sdmac->watermark_level);
+	dev_dbg(sdma->dev, "wml = 0x%08x\n", (u32)sdmac->watermark_level);
 	dev_dbg(sdma->dev, "shp_addr = 0x%08x\n", sdmac->shp_addr);
 	dev_dbg(sdma->dev, "per_addr = 0x%08x\n", sdmac->per_addr);
-	dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0);
-	dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1);
+	dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", (u32)sdmac->event_mask[0]);
+	dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", (u32)sdmac->event_mask[1]);
 
 	mutex_lock(&sdma->channel_0_lock);
 
@@ -678,8 +684,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
 	/* Send by context the event mask,base address for peripheral
 	 * and watermark level
 	 */
-	context->gReg[0] = sdmac->event_mask1;
-	context->gReg[1] = sdmac->event_mask0;
+	context->gReg[0] = sdmac->event_mask[1];
+	context->gReg[1] = sdmac->event_mask[0];
 	context->gReg[2] = sdmac->per_addr;
 	context->gReg[6] = sdmac->shp_addr;
 	context->gReg[7] = sdmac->watermark_level;
@@ -702,7 +708,7 @@ static void sdma_disable_channel(struct sdma_channel *sdmac)
 	struct sdma_engine *sdma = sdmac->sdma;
 	int channel = sdmac->channel;
 
-	__raw_writel(1 << channel, sdma->regs + SDMA_H_STATSTOP);
+	writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
 	sdmac->status = DMA_ERROR;
 }
 
@@ -712,13 +718,13 @@ static int sdma_config_channel(struct sdma_channel *sdmac)
 
 	sdma_disable_channel(sdmac);
 
-	sdmac->event_mask0 = 0;
-	sdmac->event_mask1 = 0;
+	sdmac->event_mask[0] = 0;
+	sdmac->event_mask[1] = 0;
 	sdmac->shp_addr = 0;
 	sdmac->per_addr = 0;
 
 	if (sdmac->event_id0) {
-		if (sdmac->event_id0 > 32)
+		if (sdmac->event_id0 >= sdmac->sdma->num_events)
 			return -EINVAL;
 		sdma_event_enable(sdmac, sdmac->event_id0);
 	}
@@ -741,15 +747,14 @@ static int sdma_config_channel(struct sdma_channel *sdmac)
 			(sdmac->peripheral_type != IMX_DMATYPE_DSP)) {
 		/* Handle multiple event channels differently */
 		if (sdmac->event_id1) {
-			sdmac->event_mask1 = 1 << (sdmac->event_id1 % 32);
+			sdmac->event_mask[1] = BIT(sdmac->event_id1 % 32);
 			if (sdmac->event_id1 > 31)
-				sdmac->watermark_level |= 1 << 31;
-			sdmac->event_mask0 = 1 << (sdmac->event_id0 % 32);
+				__set_bit(31, &sdmac->watermark_level);
+			sdmac->event_mask[0] = BIT(sdmac->event_id0 % 32);
 			if (sdmac->event_id0 > 31)
-				sdmac->watermark_level |= 1 << 30;
+				__set_bit(30, &sdmac->watermark_level);
 		} else {
-			sdmac->event_mask0 = 1 << sdmac->event_id0;
-			sdmac->event_mask1 = 1 << (sdmac->event_id0 - 32);
+			__set_bit(sdmac->event_id0, sdmac->event_mask);
 		}
 		/* Watermark Level */
 		sdmac->watermark_level |= sdmac->watermark_level;
@@ -775,7 +780,7 @@ static int sdma_set_channel_priority(struct sdma_channel *sdmac,
 		return -EINVAL;
 	}
 
-	__raw_writel(priority, sdma->regs + SDMA_CHNPRI_0 + 4 * channel);
+	writel_relaxed(priority, sdma->regs + SDMA_CHNPRI_0 + 4 * channel);
 
 	return 0;
 }
@@ -797,8 +802,6 @@ static int sdma_request_channel(struct sdma_channel *sdmac)
 	sdma->channel_control[channel].base_bd_ptr = sdmac->bd_phys;
 	sdma->channel_control[channel].current_bd_ptr = sdmac->bd_phys;
 
-	clk_enable(sdma->clk);
-
 	sdma_set_channel_priority(sdmac, MXC_SDMA_DEFAULT_PRIORITY);
 
 	init_completion(&sdmac->done);
@@ -811,11 +814,6 @@ out:
 	return ret;
 }
 
-static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
-{
-	__raw_writel(1 << channel, sdma->regs + SDMA_H_START);
-}
-
 static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac)
 {
 	dma_cookie_t cookie = sdmac->chan.cookie;
@@ -838,15 +836,12 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx)
 {
 	unsigned long flags;
 	struct sdma_channel *sdmac = to_sdma_chan(tx->chan);
-	struct sdma_engine *sdma = sdmac->sdma;
 	dma_cookie_t cookie;
 
 	spin_lock_irqsave(&sdmac->lock, flags);
 
 	cookie = sdma_assign_cookie(sdmac);
 
-	sdma_enable_channel(sdma, sdmac->channel);
-
 	spin_unlock_irqrestore(&sdmac->lock, flags);
 
 	return cookie;
@@ -876,11 +871,14 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan)
 
 	sdmac->peripheral_type = data->peripheral_type;
 	sdmac->event_id0 = data->dma_request;
-	ret = sdma_set_channel_priority(sdmac, prio);
+
+	clk_enable(sdmac->sdma->clk);
+
+	ret = sdma_request_channel(sdmac);
 	if (ret)
 		return ret;
 
-	ret = sdma_request_channel(sdmac);
+	ret = sdma_set_channel_priority(sdmac, prio);
 	if (ret)
 		return ret;
 
@@ -1137,9 +1135,11 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
 
 static void sdma_issue_pending(struct dma_chan *chan)
 {
-	/*
-	 * Nothing to do. We only have a single descriptor
-	 */
+	struct sdma_channel *sdmac = to_sdma_chan(chan);
+	struct sdma_engine *sdma = sdmac->sdma;
+
+	if (sdmac->status == DMA_IN_PROGRESS)
+		sdma_enable_channel(sdma, sdmac->channel);
 }
 
 #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1	34
@@ -1231,7 +1231,7 @@ static int __init sdma_init(struct sdma_engine *sdma)
 	clk_enable(sdma->clk);
 
 	/* Be sure SDMA has not started yet */
-	__raw_writel(0, sdma->regs + SDMA_H_C0PTR);
+	writel_relaxed(0, sdma->regs + SDMA_H_C0PTR);
 
 	sdma->channel_control = dma_alloc_coherent(NULL,
 			MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) +
@@ -1254,11 +1254,11 @@ static int __init sdma_init(struct sdma_engine *sdma)
 
 	/* disable all channels */
 	for (i = 0; i < sdma->num_events; i++)
-		__raw_writel(0, sdma->regs + chnenbl_ofs(sdma, i));
+		writel_relaxed(0, sdma->regs + chnenbl_ofs(sdma, i));
 
 	/* All channels have priority 0 */
 	for (i = 0; i < MAX_DMA_CHANNELS; i++)
-		__raw_writel(0, sdma->regs + SDMA_CHNPRI_0 + i * 4);
+		writel_relaxed(0, sdma->regs + SDMA_CHNPRI_0 + i * 4);
 
 	ret = sdma_request_channel(&sdma->channel[0]);
 	if (ret)
@@ -1267,16 +1267,16 @@ static int __init sdma_init(struct sdma_engine *sdma)
 	sdma_config_ownership(&sdma->channel[0], false, true, false);
 
 	/* Set Command Channel (Channel Zero) */
-	__raw_writel(0x4050, sdma->regs + SDMA_CHN0ADDR);
+	writel_relaxed(0x4050, sdma->regs + SDMA_CHN0ADDR);
 
 	/* Set bits of CONFIG register but with static context switching */
 	/* FIXME: Check whether to set ACR bit depending on clock ratios */
-	__raw_writel(0, sdma->regs + SDMA_H_CONFIG);
+	writel_relaxed(0, sdma->regs + SDMA_H_CONFIG);
 
-	__raw_writel(ccb_phys, sdma->regs + SDMA_H_C0PTR);
+	writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
 
 	/* Set bits of CONFIG register with given context switching mode */
-	__raw_writel(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
+	writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
 
 	/* Initializes channel's priorities */
 	sdma_set_channel_priority(&sdma->channel[0], 7);
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 04be90b..faf88b7 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -1482,7 +1482,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev)
 		goto err_free_adev;
 	}
 
-	dev_dbg(&pdev->dev, "%s: allocted descriptor pool virt %p phys %p\n",
+	dev_dbg(&pdev->dev, "%s: allocated descriptor pool virt %p phys %p\n",
 		__func__, adev->dma_desc_pool_virt,
 		(void *) adev->dma_desc_pool);
 
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index b8ec03e..84ebea9 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -829,7 +829,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	if (IS_ERR(pdmac->clk)) {
 		dev_err(&adev->dev, "Cannot get operation clock.\n");
 		ret = -EINVAL;
-		goto probe_err1;
+		goto probe_err2;
 	}
 
 	amba_set_drvdata(adev, pdmac);
@@ -843,11 +843,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	ret = request_irq(irq, pl330_irq_handler, 0,
 			dev_name(&adev->dev), pi);
 	if (ret)
-		goto probe_err2;
+		goto probe_err3;
 
 	ret = pl330_add(pi);
 	if (ret)
-		goto probe_err3;
+		goto probe_err4;
 
 	INIT_LIST_HEAD(&pdmac->desc_pool);
 	spin_lock_init(&pdmac->pool_lock);
@@ -904,7 +904,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	ret = dma_async_device_register(pd);
 	if (ret) {
 		dev_err(&adev->dev, "unable to register DMAC\n");
-		goto probe_err4;
+		goto probe_err5;
 	}
 
 	dev_info(&adev->dev,
@@ -917,10 +917,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	return 0;
 
-probe_err4:
+probe_err5:
 	pl330_del(pi);
-probe_err3:
+probe_err4:
 	free_irq(irq, pi);
+probe_err3:
+#ifndef CONFIG_PM_RUNTIME
+	clk_disable(pdmac->clk);
+#endif
+	clk_put(pdmac->clk);
 probe_err2:
 	iounmap(pi->base);
 probe_err1:
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
new file mode 100644
index 0000000..594d97e
--- /dev/null
+++ b/drivers/dma/sa11x0-dma.c
@@ -0,0 +1,1117 @@
+/*
+ * SA11x0 DMAengine support
+ *
+ * Copyright (C) 2012 Russell King
+ *   Derived in part from arch/arm/mach-sa1100/dma.c,
+ *   Copyright (C) 2000, 2001 by Nicolas Pitre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sa11x0-dma.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#define NR_PHY_CHAN	6
+#define DMA_ALIGN	3
+#define DMA_MAX_SIZE	0x1fff
+#define DMA_CHUNK_SIZE	0x1000
+
+#define DMA_DDAR	0x00
+#define DMA_DCSR_S	0x04
+#define DMA_DCSR_C	0x08
+#define DMA_DCSR_R	0x0c
+#define DMA_DBSA	0x10
+#define DMA_DBTA	0x14
+#define DMA_DBSB	0x18
+#define DMA_DBTB	0x1c
+#define DMA_SIZE	0x20
+
+#define DCSR_RUN	(1 << 0)
+#define DCSR_IE		(1 << 1)
+#define DCSR_ERROR	(1 << 2)
+#define DCSR_DONEA	(1 << 3)
+#define DCSR_STRTA	(1 << 4)
+#define DCSR_DONEB	(1 << 5)
+#define DCSR_STRTB	(1 << 6)
+#define DCSR_BIU	(1 << 7)
+
+#define DDAR_RW		(1 << 0)	/* 0 = W, 1 = R */
+#define DDAR_E		(1 << 1)	/* 0 = LE, 1 = BE */
+#define DDAR_BS		(1 << 2)	/* 0 = BS4, 1 = BS8 */
+#define DDAR_DW		(1 << 3)	/* 0 = 8b, 1 = 16b */
+#define DDAR_Ser0UDCTr	(0x0 << 4)
+#define DDAR_Ser0UDCRc	(0x1 << 4)
+#define DDAR_Ser1SDLCTr	(0x2 << 4)
+#define DDAR_Ser1SDLCRc	(0x3 << 4)
+#define DDAR_Ser1UARTTr	(0x4 << 4)
+#define DDAR_Ser1UARTRc	(0x5 << 4)
+#define DDAR_Ser2ICPTr	(0x6 << 4)
+#define DDAR_Ser2ICPRc	(0x7 << 4)
+#define DDAR_Ser3UARTTr	(0x8 << 4)
+#define DDAR_Ser3UARTRc	(0x9 << 4)
+#define DDAR_Ser4MCP0Tr	(0xa << 4)
+#define DDAR_Ser4MCP0Rc	(0xb << 4)
+#define DDAR_Ser4MCP1Tr	(0xc << 4)
+#define DDAR_Ser4MCP1Rc	(0xd << 4)
+#define DDAR_Ser4SSPTr	(0xe << 4)
+#define DDAR_Ser4SSPRc	(0xf << 4)
+
+struct sa11x0_dma_sg {
+	u32			addr;
+	u32			len;
+};
+
+struct sa11x0_dma_desc {
+	struct dma_async_tx_descriptor tx;
+	u32			ddar;
+	size_t			size;
+
+	/* maybe protected by c->lock */
+	struct list_head	node;
+	unsigned		sglen;
+	struct sa11x0_dma_sg	sg[0];
+};
+
+struct sa11x0_dma_phy;
+
+struct sa11x0_dma_chan {
+	struct dma_chan		chan;
+	spinlock_t		lock;
+	dma_cookie_t		lc;
+
+	/* protected by c->lock */
+	struct sa11x0_dma_phy	*phy;
+	enum dma_status		status;
+	struct list_head	desc_alloc;
+	struct list_head	desc_submitted;
+	struct list_head	desc_issued;
+
+	/* protected by d->lock */
+	struct list_head	node;
+
+	u32			ddar;
+	const char		*name;
+};
+
+struct sa11x0_dma_phy {
+	void __iomem		*base;
+	struct sa11x0_dma_dev	*dev;
+	unsigned		num;
+
+	struct sa11x0_dma_chan	*vchan;
+
+	/* Protected by c->lock */
+	unsigned		sg_load;
+	struct sa11x0_dma_desc	*txd_load;
+	unsigned		sg_done;
+	struct sa11x0_dma_desc	*txd_done;
+#ifdef CONFIG_PM_SLEEP
+	u32			dbs[2];
+	u32			dbt[2];
+	u32			dcsr;
+#endif
+};
+
+struct sa11x0_dma_dev {
+	struct dma_device	slave;
+	void __iomem		*base;
+	spinlock_t		lock;
+	struct tasklet_struct	task;
+	struct list_head	chan_pending;
+	struct list_head	desc_complete;
+	struct sa11x0_dma_phy	phy[NR_PHY_CHAN];
+};
+
+static struct sa11x0_dma_chan *to_sa11x0_dma_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct sa11x0_dma_chan, chan);
+}
+
+static struct sa11x0_dma_dev *to_sa11x0_dma(struct dma_device *dmadev)
+{
+	return container_of(dmadev, struct sa11x0_dma_dev, slave);
+}
+
+static struct sa11x0_dma_desc *to_sa11x0_dma_tx(struct dma_async_tx_descriptor *tx)
+{
+	return container_of(tx, struct sa11x0_dma_desc, tx);
+}
+
+static struct sa11x0_dma_desc *sa11x0_dma_next_desc(struct sa11x0_dma_chan *c)
+{
+	if (list_empty(&c->desc_issued))
+		return NULL;
+
+	return list_first_entry(&c->desc_issued, struct sa11x0_dma_desc, node);
+}
+
+static void sa11x0_dma_start_desc(struct sa11x0_dma_phy *p, struct sa11x0_dma_desc *txd)
+{
+	list_del(&txd->node);
+	p->txd_load = txd;
+	p->sg_load = 0;
+
+	dev_vdbg(p->dev->slave.dev, "pchan %u: txd %p[%x]: starting: DDAR:%x\n",
+		p->num, txd, txd->tx.cookie, txd->ddar);
+}
+
+static void noinline sa11x0_dma_start_sg(struct sa11x0_dma_phy *p,
+	struct sa11x0_dma_chan *c)
+{
+	struct sa11x0_dma_desc *txd = p->txd_load;
+	struct sa11x0_dma_sg *sg;
+	void __iomem *base = p->base;
+	unsigned dbsx, dbtx;
+	u32 dcsr;
+
+	if (!txd)
+		return;
+
+	dcsr = readl_relaxed(base + DMA_DCSR_R);
+
+	/* Don't try to load the next transfer if both buffers are started */
+	if ((dcsr & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB))
+		return;
+
+	if (p->sg_load == txd->sglen) {
+		struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c);
+
+		/*
+		 * We have reached the end of the current descriptor.
+		 * Peek at the next descriptor, and if compatible with
+		 * the current, start processing it.
+		 */
+		if (txn && txn->ddar == txd->ddar) {
+			txd = txn;
+			sa11x0_dma_start_desc(p, txn);
+		} else {
+			p->txd_load = NULL;
+			return;
+		}
+	}
+
+	sg = &txd->sg[p->sg_load++];
+
+	/* Select buffer to load according to channel status */
+	if (((dcsr & (DCSR_BIU | DCSR_STRTB)) == (DCSR_BIU | DCSR_STRTB)) ||
+	    ((dcsr & (DCSR_BIU | DCSR_STRTA)) == 0)) {
+		dbsx = DMA_DBSA;
+		dbtx = DMA_DBTA;
+		dcsr = DCSR_STRTA | DCSR_IE | DCSR_RUN;
+	} else {
+		dbsx = DMA_DBSB;
+		dbtx = DMA_DBTB;
+		dcsr = DCSR_STRTB | DCSR_IE | DCSR_RUN;
+	}
+
+	writel_relaxed(sg->addr, base + dbsx);
+	writel_relaxed(sg->len, base + dbtx);
+	writel(dcsr, base + DMA_DCSR_S);
+
+	dev_dbg(p->dev->slave.dev, "pchan %u: load: DCSR:%02x DBS%c:%08x DBT%c:%08x\n",
+		p->num, dcsr,
+		'A' + (dbsx == DMA_DBSB), sg->addr,
+		'A' + (dbtx == DMA_DBTB), sg->len);
+}
+
+static void noinline sa11x0_dma_complete(struct sa11x0_dma_phy *p,
+	struct sa11x0_dma_chan *c)
+{
+	struct sa11x0_dma_desc *txd = p->txd_done;
+
+	if (++p->sg_done == txd->sglen) {
+		struct sa11x0_dma_dev *d = p->dev;
+
+		dev_vdbg(d->slave.dev, "pchan %u: txd %p[%x]: completed\n",
+			p->num, p->txd_done, p->txd_done->tx.cookie);
+
+		c->lc = txd->tx.cookie;
+
+		spin_lock(&d->lock);
+		list_add_tail(&txd->node, &d->desc_complete);
+		spin_unlock(&d->lock);
+
+		p->sg_done = 0;
+		p->txd_done = p->txd_load;
+
+		tasklet_schedule(&d->task);
+	}
+
+	sa11x0_dma_start_sg(p, c);
+}
+
+static irqreturn_t sa11x0_dma_irq(int irq, void *dev_id)
+{
+	struct sa11x0_dma_phy *p = dev_id;
+	struct sa11x0_dma_dev *d = p->dev;
+	struct sa11x0_dma_chan *c;
+	u32 dcsr;
+
+	dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+	if (!(dcsr & (DCSR_ERROR | DCSR_DONEA | DCSR_DONEB)))
+		return IRQ_NONE;
+
+	/* Clear reported status bits */
+	writel_relaxed(dcsr & (DCSR_ERROR | DCSR_DONEA | DCSR_DONEB),
+		p->base + DMA_DCSR_C);
+
+	dev_dbg(d->slave.dev, "pchan %u: irq: DCSR:%02x\n", p->num, dcsr);
+
+	if (dcsr & DCSR_ERROR) {
+		dev_err(d->slave.dev, "pchan %u: error. DCSR:%02x DDAR:%08x DBSA:%08x DBTA:%08x DBSB:%08x DBTB:%08x\n",
+			p->num, dcsr,
+			readl_relaxed(p->base + DMA_DDAR),
+			readl_relaxed(p->base + DMA_DBSA),
+			readl_relaxed(p->base + DMA_DBTA),
+			readl_relaxed(p->base + DMA_DBSB),
+			readl_relaxed(p->base + DMA_DBTB));
+	}
+
+	c = p->vchan;
+	if (c) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&c->lock, flags);
+		/*
+		 * Now that we're holding the lock, check that the vchan
+		 * really is associated with this pchan before touching the
+		 * hardware.  This should always succeed, because we won't
+		 * change p->vchan or c->phy while the channel is actively
+		 * transferring.
+		 */
+		if (c->phy == p) {
+			if (dcsr & DCSR_DONEA)
+				sa11x0_dma_complete(p, c);
+			if (dcsr & DCSR_DONEB)
+				sa11x0_dma_complete(p, c);
+		}
+		spin_unlock_irqrestore(&c->lock, flags);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void sa11x0_dma_start_txd(struct sa11x0_dma_chan *c)
+{
+	struct sa11x0_dma_desc *txd = sa11x0_dma_next_desc(c);
+
+	/* If the issued list is empty, we have no further txds to process */
+	if (txd) {
+		struct sa11x0_dma_phy *p = c->phy;
+
+		sa11x0_dma_start_desc(p, txd);
+		p->txd_done = txd;
+		p->sg_done = 0;
+
+		/* The channel should not have any transfers started */
+		WARN_ON(readl_relaxed(p->base + DMA_DCSR_R) &
+				      (DCSR_STRTA | DCSR_STRTB));
+
+		/* Clear the run and start bits before changing DDAR */
+		writel_relaxed(DCSR_RUN | DCSR_STRTA | DCSR_STRTB,
+			       p->base + DMA_DCSR_C);
+		writel_relaxed(txd->ddar, p->base + DMA_DDAR);
+
+		/* Try to start both buffers */
+		sa11x0_dma_start_sg(p, c);
+		sa11x0_dma_start_sg(p, c);
+	}
+}
+
+static void sa11x0_dma_tasklet(unsigned long arg)
+{
+	struct sa11x0_dma_dev *d = (struct sa11x0_dma_dev *)arg;
+	struct sa11x0_dma_phy *p;
+	struct sa11x0_dma_chan *c;
+	struct sa11x0_dma_desc *txd, *txn;
+	LIST_HEAD(head);
+	unsigned pch, pch_alloc = 0;
+
+	dev_dbg(d->slave.dev, "tasklet enter\n");
+
+	/* Get the completed tx descriptors */
+	spin_lock_irq(&d->lock);
+	list_splice_init(&d->desc_complete, &head);
+	spin_unlock_irq(&d->lock);
+
+	list_for_each_entry(txd, &head, node) {
+		c = to_sa11x0_dma_chan(txd->tx.chan);
+
+		dev_dbg(d->slave.dev, "vchan %p: txd %p[%x] completed\n",
+			c, txd, txd->tx.cookie);
+
+		spin_lock_irq(&c->lock);
+		p = c->phy;
+		if (p) {
+			if (!p->txd_done)
+				sa11x0_dma_start_txd(c);
+			if (!p->txd_done) {
+				/* No current txd associated with this channel */
+				dev_dbg(d->slave.dev, "pchan %u: free\n", p->num);
+
+				/* Mark this channel free */
+				c->phy = NULL;
+				p->vchan = NULL;
+			}
+		}
+		spin_unlock_irq(&c->lock);
+	}
+
+	spin_lock_irq(&d->lock);
+	for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+		p = &d->phy[pch];
+
+		if (p->vchan == NULL && !list_empty(&d->chan_pending)) {
+			c = list_first_entry(&d->chan_pending,
+				struct sa11x0_dma_chan, node);
+			list_del_init(&c->node);
+
+			pch_alloc |= 1 << pch;
+
+			/* Mark this channel allocated */
+			p->vchan = c;
+
+			dev_dbg(d->slave.dev, "pchan %u: alloc vchan %p\n", pch, c);
+		}
+	}
+	spin_unlock_irq(&d->lock);
+
+	for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+		if (pch_alloc & (1 << pch)) {
+			p = &d->phy[pch];
+			c = p->vchan;
+
+			spin_lock_irq(&c->lock);
+			c->phy = p;
+
+			sa11x0_dma_start_txd(c);
+			spin_unlock_irq(&c->lock);
+		}
+	}
+
+	/* Now free the completed tx descriptor, and call their callbacks */
+	list_for_each_entry_safe(txd, txn, &head, node) {
+		dma_async_tx_callback callback = txd->tx.callback;
+		void *callback_param = txd->tx.callback_param;
+
+		dev_dbg(d->slave.dev, "txd %p[%x]: callback and free\n",
+			txd, txd->tx.cookie);
+
+		kfree(txd);
+
+		if (callback)
+			callback(callback_param);
+	}
+
+	dev_dbg(d->slave.dev, "tasklet exit\n");
+}
+
+
+static void sa11x0_dma_desc_free(struct sa11x0_dma_dev *d, struct list_head *head)
+{
+	struct sa11x0_dma_desc *txd, *txn;
+
+	list_for_each_entry_safe(txd, txn, head, node) {
+		dev_dbg(d->slave.dev, "txd %p: freeing\n", txd);
+		kfree(txd);
+	}
+}
+
+static int sa11x0_dma_alloc_chan_resources(struct dma_chan *chan)
+{
+	return 0;
+}
+
+static void sa11x0_dma_free_chan_resources(struct dma_chan *chan)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+	unsigned long flags;
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&c->lock, flags);
+	spin_lock(&d->lock);
+	list_del_init(&c->node);
+	spin_unlock(&d->lock);
+
+	list_splice_tail_init(&c->desc_alloc, &head);
+	list_splice_tail_init(&c->desc_submitted, &head);
+	list_splice_tail_init(&c->desc_issued, &head);
+	spin_unlock_irqrestore(&c->lock, flags);
+
+	sa11x0_dma_desc_free(d, &head);
+}
+
+static dma_addr_t sa11x0_dma_pos(struct sa11x0_dma_phy *p)
+{
+	unsigned reg;
+	u32 dcsr;
+
+	dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+
+	if ((dcsr & (DCSR_BIU | DCSR_STRTA)) == DCSR_STRTA ||
+	    (dcsr & (DCSR_BIU | DCSR_STRTB)) == DCSR_BIU)
+		reg = DMA_DBSA;
+	else
+		reg = DMA_DBSB;
+
+	return readl_relaxed(p->base + reg);
+}
+
+static enum dma_status sa11x0_dma_tx_status(struct dma_chan *chan,
+	dma_cookie_t cookie, struct dma_tx_state *state)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+	struct sa11x0_dma_phy *p;
+	struct sa11x0_dma_desc *txd;
+	dma_cookie_t last_used, last_complete;
+	unsigned long flags;
+	enum dma_status ret;
+	size_t bytes = 0;
+
+	last_used = c->chan.cookie;
+	last_complete = c->lc;
+
+	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	if (ret == DMA_SUCCESS) {
+		dma_set_tx_state(state, last_complete, last_used, 0);
+		return ret;
+	}
+
+	spin_lock_irqsave(&c->lock, flags);
+	p = c->phy;
+	ret = c->status;
+	if (p) {
+		dma_addr_t addr = sa11x0_dma_pos(p);
+
+		dev_vdbg(d->slave.dev, "tx_status: addr:%x\n", addr);
+
+		txd = p->txd_done;
+		if (txd) {
+			unsigned i;
+
+			for (i = 0; i < txd->sglen; i++) {
+				dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x\n",
+					i, txd->sg[i].addr, txd->sg[i].len);
+				if (addr >= txd->sg[i].addr &&
+				    addr < txd->sg[i].addr + txd->sg[i].len) {
+					unsigned len;
+
+					len = txd->sg[i].len -
+						(addr - txd->sg[i].addr);
+					dev_vdbg(d->slave.dev, "tx_status: [%u] +%x\n",
+						i, len);
+					bytes += len;
+					i++;
+					break;
+				}
+			}
+			for (; i < txd->sglen; i++) {
+				dev_vdbg(d->slave.dev, "tx_status: [%u] %x+%x ++\n",
+					i, txd->sg[i].addr, txd->sg[i].len);
+				bytes += txd->sg[i].len;
+			}
+		}
+		if (txd != p->txd_load && p->txd_load)
+			bytes += p->txd_load->size;
+	}
+	list_for_each_entry(txd, &c->desc_issued, node) {
+		bytes += txd->size;
+	}
+	spin_unlock_irqrestore(&c->lock, flags);
+
+	dma_set_tx_state(state, last_complete, last_used, bytes);
+
+	dev_vdbg(d->slave.dev, "tx_status: bytes 0x%zx\n", bytes);
+
+	return ret;
+}
+
+/*
+ * Move pending txds to the issued list, and re-init pending list.
+ * If not already pending, add this channel to the list of pending
+ * channels and trigger the tasklet to run.
+ */
+static void sa11x0_dma_issue_pending(struct dma_chan *chan)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->lock, flags);
+	list_splice_tail_init(&c->desc_submitted, &c->desc_issued);
+	if (!list_empty(&c->desc_issued)) {
+		spin_lock(&d->lock);
+		if (!c->phy && list_empty(&c->node)) {
+			list_add_tail(&c->node, &d->chan_pending);
+			tasklet_schedule(&d->task);
+			dev_dbg(d->slave.dev, "vchan %p: issued\n", c);
+		}
+		spin_unlock(&d->lock);
+	} else
+		dev_dbg(d->slave.dev, "vchan %p: nothing to issue\n", c);
+	spin_unlock_irqrestore(&c->lock, flags);
+}
+
+static dma_cookie_t sa11x0_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(tx->chan);
+	struct sa11x0_dma_desc *txd = to_sa11x0_dma_tx(tx);
+	unsigned long flags;
+
+	spin_lock_irqsave(&c->lock, flags);
+	c->chan.cookie += 1;
+	if (c->chan.cookie < 0)
+		c->chan.cookie = 1;
+	txd->tx.cookie = c->chan.cookie;
+
+	list_move_tail(&txd->node, &c->desc_submitted);
+	spin_unlock_irqrestore(&c->lock, flags);
+
+	dev_dbg(tx->chan->device->dev, "vchan %p: txd %p[%x]: submitted\n",
+		c, txd, txd->tx.cookie);
+
+	return txd->tx.cookie;
+}
+
+static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg(
+	struct dma_chan *chan, struct scatterlist *sg, unsigned int sglen,
+	enum dma_transfer_direction dir, unsigned long flags)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	struct sa11x0_dma_desc *txd;
+	struct scatterlist *sgent;
+	unsigned i, j = sglen;
+	size_t size = 0;
+
+	/* SA11x0 channels can only operate in their native direction */
+	if (dir != (c->ddar & DDAR_RW ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV)) {
+		dev_err(chan->device->dev, "vchan %p: bad DMA direction: DDAR:%08x dir:%u\n",
+			c, c->ddar, dir);
+		return NULL;
+	}
+
+	/* Do not allow zero-sized txds */
+	if (sglen == 0)
+		return NULL;
+
+	for_each_sg(sg, sgent, sglen, i) {
+		dma_addr_t addr = sg_dma_address(sgent);
+		unsigned int len = sg_dma_len(sgent);
+
+		if (len > DMA_MAX_SIZE)
+			j += DIV_ROUND_UP(len, DMA_MAX_SIZE & ~DMA_ALIGN) - 1;
+		if (addr & DMA_ALIGN) {
+			dev_dbg(chan->device->dev, "vchan %p: bad buffer alignment: %08x\n",
+				c, addr);
+			return NULL;
+		}
+	}
+
+	txd = kzalloc(sizeof(*txd) + j * sizeof(txd->sg[0]), GFP_ATOMIC);
+	if (!txd) {
+		dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", c);
+		return NULL;
+	}
+
+	j = 0;
+	for_each_sg(sg, sgent, sglen, i) {
+		dma_addr_t addr = sg_dma_address(sgent);
+		unsigned len = sg_dma_len(sgent);
+
+		size += len;
+
+		do {
+			unsigned tlen = len;
+
+			/*
+			 * Check whether the transfer will fit.  If not, try
+			 * to split the transfer up such that we end up with
+			 * equal chunks - but make sure that we preserve the
+			 * alignment.  This avoids small segments.
+			 */
+			if (tlen > DMA_MAX_SIZE) {
+				unsigned mult = DIV_ROUND_UP(tlen,
+					DMA_MAX_SIZE & ~DMA_ALIGN);
+
+				tlen = (tlen / mult) & ~DMA_ALIGN;
+			}
+
+			txd->sg[j].addr = addr;
+			txd->sg[j].len = tlen;
+
+			addr += tlen;
+			len -= tlen;
+			j++;
+		} while (len);
+	}
+
+	dma_async_tx_descriptor_init(&txd->tx, &c->chan);
+	txd->tx.flags = flags;
+	txd->tx.tx_submit = sa11x0_dma_tx_submit;
+	txd->ddar = c->ddar;
+	txd->size = size;
+	txd->sglen = j;
+
+	spin_lock_irqsave(&c->lock, flags);
+	list_add_tail(&txd->node, &c->desc_alloc);
+	spin_unlock_irqrestore(&c->lock, flags);
+
+	dev_dbg(chan->device->dev, "vchan %p: txd %p: size %u nr %u\n",
+		c, txd, txd->size, txd->sglen);
+
+	return &txd->tx;
+}
+
+static int sa11x0_dma_slave_config(struct sa11x0_dma_chan *c, struct dma_slave_config *cfg)
+{
+	u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW);
+	dma_addr_t addr;
+	enum dma_slave_buswidth width;
+	u32 maxburst;
+
+	if (ddar & DDAR_RW) {
+		addr = cfg->src_addr;
+		width = cfg->src_addr_width;
+		maxburst = cfg->src_maxburst;
+	} else {
+		addr = cfg->dst_addr;
+		width = cfg->dst_addr_width;
+		maxburst = cfg->dst_maxburst;
+	}
+
+	if ((width != DMA_SLAVE_BUSWIDTH_1_BYTE &&
+	     width != DMA_SLAVE_BUSWIDTH_2_BYTES) ||
+	    (maxburst != 4 && maxburst != 8))
+		return -EINVAL;
+
+	if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
+		ddar |= DDAR_DW;
+	if (maxburst == 8)
+		ddar |= DDAR_BS;
+
+	dev_dbg(c->chan.device->dev, "vchan %p: dma_slave_config addr %x width %u burst %u\n",
+		c, addr, width, maxburst);
+
+	c->ddar = ddar | (addr & 0xf0000000) | (addr & 0x003ffffc) << 6;
+
+	return 0;
+}
+
+static int sa11x0_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+	unsigned long arg)
+{
+	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+	struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device);
+	struct sa11x0_dma_phy *p;
+	LIST_HEAD(head);
+	unsigned long flags;
+	int ret;
+
+	switch (cmd) {
+	case DMA_SLAVE_CONFIG:
+		return sa11x0_dma_slave_config(c, (struct dma_slave_config *)arg);
+
+	case DMA_TERMINATE_ALL:
+		dev_dbg(d->slave.dev, "vchan %p: terminate all\n", c);
+		/* Clear the tx descriptor lists */
+		spin_lock_irqsave(&c->lock, flags);
+		list_splice_tail_init(&c->desc_alloc, &head);
+		list_splice_tail_init(&c->desc_submitted, &head);
+		list_splice_tail_init(&c->desc_issued, &head);
+
+		p = c->phy;
+		if (p) {
+			struct sa11x0_dma_desc *txd, *txn;
+
+			dev_dbg(d->slave.dev, "pchan %u: terminating\n", p->num);
+			/* vchan is assigned to a pchan - stop the channel */
+			writel(DCSR_RUN | DCSR_IE |
+				DCSR_STRTA | DCSR_DONEA |
+				DCSR_STRTB | DCSR_DONEB,
+				p->base + DMA_DCSR_C);
+
+			list_for_each_entry_safe(txd, txn, &d->desc_complete, node)
+				if (txd->tx.chan == &c->chan)
+					list_move(&txd->node, &head);
+
+			if (p->txd_load) {
+				if (p->txd_load != p->txd_done)
+					list_add_tail(&p->txd_load->node, &head);
+				p->txd_load = NULL;
+			}
+			if (p->txd_done) {
+				list_add_tail(&p->txd_done->node, &head);
+				p->txd_done = NULL;
+			}
+			c->phy = NULL;
+			spin_lock(&d->lock);
+			p->vchan = NULL;
+			spin_unlock(&d->lock);
+			tasklet_schedule(&d->task);
+		}
+		spin_unlock_irqrestore(&c->lock, flags);
+		sa11x0_dma_desc_free(d, &head);
+		ret = 0;
+		break;
+
+	case DMA_PAUSE:
+		dev_dbg(d->slave.dev, "vchan %p: pause\n", c);
+		spin_lock_irqsave(&c->lock, flags);
+		if (c->status == DMA_IN_PROGRESS) {
+			c->status = DMA_PAUSED;
+
+			p = c->phy;
+			if (p) {
+				writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
+			} else {
+				spin_lock(&d->lock);
+				list_del_init(&c->node);
+				spin_unlock(&d->lock);
+			}
+		}
+		spin_unlock_irqrestore(&c->lock, flags);
+		ret = 0;
+		break;
+
+	case DMA_RESUME:
+		dev_dbg(d->slave.dev, "vchan %p: resume\n", c);
+		spin_lock_irqsave(&c->lock, flags);
+		if (c->status == DMA_PAUSED) {
+			c->status = DMA_IN_PROGRESS;
+
+			p = c->phy;
+			if (p) {
+				writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_S);
+			} else if (!list_empty(&c->desc_issued)) {
+				spin_lock(&d->lock);
+				list_add_tail(&c->node, &d->chan_pending);
+				spin_unlock(&d->lock);
+			}
+		}
+		spin_unlock_irqrestore(&c->lock, flags);
+		ret = 0;
+		break;
+
+	default:
+		ret = -ENXIO;
+		break;
+	}
+
+	return ret;
+}
+
+struct sa11x0_dma_channel_desc {
+	u32 ddar;
+	const char *name;
+};
+
+#define CD(d1, d2) { .ddar = DDAR_##d1 | d2, .name = #d1 }
+static const struct sa11x0_dma_channel_desc chan_desc[] = {
+	CD(Ser0UDCTr, 0),
+	CD(Ser0UDCRc, DDAR_RW),
+	CD(Ser1SDLCTr, 0),
+	CD(Ser1SDLCRc, DDAR_RW),
+	CD(Ser1UARTTr, 0),
+	CD(Ser1UARTRc, DDAR_RW),
+	CD(Ser2ICPTr, 0),
+	CD(Ser2ICPRc, DDAR_RW),
+	CD(Ser3UARTTr, 0),
+	CD(Ser3UARTRc, DDAR_RW),
+	CD(Ser4MCP0Tr, 0),
+	CD(Ser4MCP0Rc, DDAR_RW),
+	CD(Ser4MCP1Tr, 0),
+	CD(Ser4MCP1Rc, DDAR_RW),
+	CD(Ser4SSPTr, 0),
+	CD(Ser4SSPRc, DDAR_RW),
+};
+
+static int __devinit sa11x0_dma_init_dmadev(struct dma_device *dmadev,
+	struct device *dev)
+{
+	unsigned i;
+
+	dmadev->chancnt = ARRAY_SIZE(chan_desc);
+	INIT_LIST_HEAD(&dmadev->channels);
+	dmadev->dev = dev;
+	dmadev->device_alloc_chan_resources = sa11x0_dma_alloc_chan_resources;
+	dmadev->device_free_chan_resources = sa11x0_dma_free_chan_resources;
+	dmadev->device_control = sa11x0_dma_control;
+	dmadev->device_tx_status = sa11x0_dma_tx_status;
+	dmadev->device_issue_pending = sa11x0_dma_issue_pending;
+
+	for (i = 0; i < dmadev->chancnt; i++) {
+		struct sa11x0_dma_chan *c;
+
+		c = kzalloc(sizeof(*c), GFP_KERNEL);
+		if (!c) {
+			dev_err(dev, "no memory for channel %u\n", i);
+			return -ENOMEM;
+		}
+
+		c->chan.device = dmadev;
+		c->status = DMA_IN_PROGRESS;
+		c->ddar = chan_desc[i].ddar;
+		c->name = chan_desc[i].name;
+		spin_lock_init(&c->lock);
+		INIT_LIST_HEAD(&c->desc_alloc);
+		INIT_LIST_HEAD(&c->desc_submitted);
+		INIT_LIST_HEAD(&c->desc_issued);
+		INIT_LIST_HEAD(&c->node);
+		list_add_tail(&c->chan.device_node, &dmadev->channels);
+	}
+
+	return dma_async_device_register(dmadev);
+}
+
+static int sa11x0_dma_request_irq(struct platform_device *pdev, int nr,
+	void *data)
+{
+	int irq = platform_get_irq(pdev, nr);
+
+	if (irq <= 0)
+		return -ENXIO;
+
+	return request_irq(irq, sa11x0_dma_irq, 0, dev_name(&pdev->dev), data);
+}
+
+static void sa11x0_dma_free_irq(struct platform_device *pdev, int nr,
+	void *data)
+{
+	int irq = platform_get_irq(pdev, nr);
+	if (irq > 0)
+		free_irq(irq, data);
+}
+
+static void sa11x0_dma_free_channels(struct dma_device *dmadev)
+{
+	struct sa11x0_dma_chan *c, *cn;
+
+	list_for_each_entry_safe(c, cn, &dmadev->channels, chan.device_node) {
+		list_del(&c->chan.device_node);
+		kfree(c);
+	}
+}
+
+static int __devinit sa11x0_dma_probe(struct platform_device *pdev)
+{
+	struct sa11x0_dma_dev *d;
+	struct resource *res;
+	unsigned i;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	d = kzalloc(sizeof(*d), GFP_KERNEL);
+	if (!d) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	spin_lock_init(&d->lock);
+	INIT_LIST_HEAD(&d->chan_pending);
+	INIT_LIST_HEAD(&d->desc_complete);
+
+	d->base = ioremap(res->start, resource_size(res));
+	if (!d->base) {
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	tasklet_init(&d->task, sa11x0_dma_tasklet, (unsigned long)d);
+
+	for (i = 0; i < NR_PHY_CHAN; i++) {
+		struct sa11x0_dma_phy *p = &d->phy[i];
+
+		p->dev = d;
+		p->num = i;
+		p->base = d->base + i * DMA_SIZE;
+		writel_relaxed(DCSR_RUN | DCSR_IE | DCSR_ERROR |
+			DCSR_DONEA | DCSR_STRTA | DCSR_DONEB | DCSR_STRTB,
+			p->base + DMA_DCSR_C);
+		writel_relaxed(0, p->base + DMA_DDAR);
+
+		ret = sa11x0_dma_request_irq(pdev, i, p);
+		if (ret) {
+			while (i) {
+				i--;
+				sa11x0_dma_free_irq(pdev, i, &d->phy[i]);
+			}
+			goto err_irq;
+		}
+	}
+
+	dma_cap_set(DMA_SLAVE, d->slave.cap_mask);
+	d->slave.device_prep_slave_sg = sa11x0_dma_prep_slave_sg;
+	ret = sa11x0_dma_init_dmadev(&d->slave, &pdev->dev);
+	if (ret) {
+		dev_warn(d->slave.dev, "failed to register slave async device: %d\n",
+			ret);
+		goto err_slave_reg;
+	}
+
+	platform_set_drvdata(pdev, d);
+	return 0;
+
+ err_slave_reg:
+	sa11x0_dma_free_channels(&d->slave);
+	for (i = 0; i < NR_PHY_CHAN; i++)
+		sa11x0_dma_free_irq(pdev, i, &d->phy[i]);
+ err_irq:
+	tasklet_kill(&d->task);
+	iounmap(d->base);
+ err_ioremap:
+	kfree(d);
+ err_alloc:
+	return ret;
+}
+
+static int __devexit sa11x0_dma_remove(struct platform_device *pdev)
+{
+	struct sa11x0_dma_dev *d = platform_get_drvdata(pdev);
+	unsigned pch;
+
+	dma_async_device_unregister(&d->slave);
+
+	sa11x0_dma_free_channels(&d->slave);
+	for (pch = 0; pch < NR_PHY_CHAN; pch++)
+		sa11x0_dma_free_irq(pdev, pch, &d->phy[pch]);
+	tasklet_kill(&d->task);
+	iounmap(d->base);
+	kfree(d);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sa11x0_dma_suspend(struct device *dev)
+{
+	struct sa11x0_dma_dev *d = dev_get_drvdata(dev);
+	unsigned pch;
+
+	for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+		struct sa11x0_dma_phy *p = &d->phy[pch];
+		u32 dcsr, saved_dcsr;
+
+		dcsr = saved_dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+		if (dcsr & DCSR_RUN) {
+			writel(DCSR_RUN | DCSR_IE, p->base + DMA_DCSR_C);
+			dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+		}
+
+		saved_dcsr &= DCSR_RUN | DCSR_IE;
+		if (dcsr & DCSR_BIU) {
+			p->dbs[0] = readl_relaxed(p->base + DMA_DBSB);
+			p->dbt[0] = readl_relaxed(p->base + DMA_DBTB);
+			p->dbs[1] = readl_relaxed(p->base + DMA_DBSA);
+			p->dbt[1] = readl_relaxed(p->base + DMA_DBTA);
+			saved_dcsr |= (dcsr & DCSR_STRTA ? DCSR_STRTB : 0) |
+				      (dcsr & DCSR_STRTB ? DCSR_STRTA : 0);
+		} else {
+			p->dbs[0] = readl_relaxed(p->base + DMA_DBSA);
+			p->dbt[0] = readl_relaxed(p->base + DMA_DBTA);
+			p->dbs[1] = readl_relaxed(p->base + DMA_DBSB);
+			p->dbt[1] = readl_relaxed(p->base + DMA_DBTB);
+			saved_dcsr |= dcsr & (DCSR_STRTA | DCSR_STRTB);
+		}
+		p->dcsr = saved_dcsr;
+
+		writel(DCSR_STRTA | DCSR_STRTB, p->base + DMA_DCSR_C);
+	}
+
+	return 0;
+}
+
+static int sa11x0_dma_resume(struct device *dev)
+{
+	struct sa11x0_dma_dev *d = dev_get_drvdata(dev);
+	unsigned pch;
+
+	for (pch = 0; pch < NR_PHY_CHAN; pch++) {
+		struct sa11x0_dma_phy *p = &d->phy[pch];
+		struct sa11x0_dma_desc *txd = NULL;
+		u32 dcsr = readl_relaxed(p->base + DMA_DCSR_R);
+
+		WARN_ON(dcsr & (DCSR_BIU | DCSR_STRTA | DCSR_STRTB | DCSR_RUN));
+
+		if (p->txd_done)
+			txd = p->txd_done;
+		else if (p->txd_load)
+			txd = p->txd_load;
+
+		if (!txd)
+			continue;
+
+		writel_relaxed(txd->ddar, p->base + DMA_DDAR);
+
+		writel_relaxed(p->dbs[0], p->base + DMA_DBSA);
+		writel_relaxed(p->dbt[0], p->base + DMA_DBTA);
+		writel_relaxed(p->dbs[1], p->base + DMA_DBSB);
+		writel_relaxed(p->dbt[1], p->base + DMA_DBTB);
+		writel_relaxed(p->dcsr, p->base + DMA_DCSR_S);
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops sa11x0_dma_pm_ops = {
+	.suspend_noirq = sa11x0_dma_suspend,
+	.resume_noirq = sa11x0_dma_resume,
+	.freeze_noirq = sa11x0_dma_suspend,
+	.thaw_noirq = sa11x0_dma_resume,
+	.poweroff_noirq = sa11x0_dma_suspend,
+	.restore_noirq = sa11x0_dma_resume,
+};
+
+static struct platform_driver sa11x0_dma_driver = {
+	.driver = {
+		.name	= "sa11x0-dma",
+		.owner	= THIS_MODULE,
+		.pm	= &sa11x0_dma_pm_ops,
+	},
+	.probe		= sa11x0_dma_probe,
+	.remove		= __devexit_p(sa11x0_dma_remove),
+};
+
+bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)
+{
+	if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {
+		struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+		const char *p = param;
+
+		return !strcmp(c->name, p);
+	}
+	return false;
+}
+EXPORT_SYMBOL(sa11x0_dma_filter_fn);
+
+static int __init sa11x0_dma_init(void)
+{
+	return platform_driver_register(&sa11x0_dma_driver);
+}
+subsys_initcall(sa11x0_dma_init);
+
+static void __exit sa11x0_dma_exit(void)
+{
+	platform_driver_unregister(&sa11x0_dma_driver);
+}
+module_exit(sa11x0_dma_exit);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SA-11x0 DMA driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sa11x0-dma");
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index c9eee6d..6a83d49 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1132,12 +1132,36 @@ static int k8_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
 		return ddr2_cs_size(cs_mode, dclr & WIDTH_128);
 	}
 	else if (pvt->ext_model >= K8_REV_D) {
+		unsigned diff;
 		WARN_ON(cs_mode > 10);
 
-		if (cs_mode == 3 || cs_mode == 8)
-			return 32 << (cs_mode - 1);
-		else
-			return 32 << cs_mode;
+		/*
+		 * the below calculation, besides trying to win an obfuscated C
+		 * contest, maps cs_mode values to DIMM chip select sizes. The
+		 * mappings are:
+		 *
+		 * cs_mode	CS size (mb)
+		 * =======	============
+		 * 0		32
+		 * 1		64
+		 * 2		128
+		 * 3		128
+		 * 4		256
+		 * 5		512
+		 * 6		256
+		 * 7		512
+		 * 8		1024
+		 * 9		1024
+		 * 10		2048
+		 *
+		 * Basically, it calculates a value with which to shift the
+		 * smallest CS size of 32MB.
+		 *
+		 * ddr[23]_cs_size have a similar purpose.
+		 */
+		diff = cs_mode/3 + (unsigned)(cs_mode > 5);
+
+		return 32 << (cs_mode - diff);
 	}
 	else {
 		WARN_ON(cs_mode > 6);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index ca6c04d..da09cd7 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -620,13 +620,13 @@ static void edac_mc_scrub_block(unsigned long page, unsigned long offset,
 	if (PageHighMem(pg))
 		local_irq_save(flags);
 
-	virt_addr = kmap_atomic(pg, KM_BOUNCE_READ);
+	virt_addr = kmap_atomic(pg);
 
 	/* Perform architecture specific atomic scrub operation */
 	atomic_scrub(virt_addr + offset, size);
 
 	/* Unmap and complete */
-	kunmap_atomic(virt_addr, KM_BOUNCE_READ);
+	kunmap_atomic(virt_addr);
 
 	if (PageHighMem(pg))
 		local_irq_restore(flags);
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index d56e634..e9a28f5 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -452,7 +452,7 @@ static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci,
 	int new_bw = 0;
 
 	if (!mci->set_sdram_scrub_rate)
-		return -EINVAL;
+		return -ENODEV;
 
 	if (strict_strtoul(data, 10, &bandwidth) < 0)
 		return -EINVAL;
@@ -475,7 +475,7 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data)
 	int bandwidth = 0;
 
 	if (!mci->get_sdram_scrub_rate)
-		return -EINVAL;
+		return -ENODEV;
 
 	bandwidth = mci->get_sdram_scrub_rate(mci);
 	if (bandwidth < 0) {
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index bd926ea..36e1486 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -39,42 +39,31 @@ EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
  */
 
 /* transaction type */
-const char *tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
+const char * const tt_msgs[] = { "INSN", "DATA", "GEN", "RESV" };
 EXPORT_SYMBOL_GPL(tt_msgs);
 
 /* cache level */
-const char *ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
+const char * const ll_msgs[] = { "RESV", "L1", "L2", "L3/GEN" };
 EXPORT_SYMBOL_GPL(ll_msgs);
 
 /* memory transaction type */
-const char *rrrr_msgs[] = {
+const char * const rrrr_msgs[] = {
        "GEN", "RD", "WR", "DRD", "DWR", "IRD", "PRF", "EV", "SNP"
 };
 EXPORT_SYMBOL_GPL(rrrr_msgs);
 
 /* participating processor */
-const char *pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
+const char * const pp_msgs[] = { "SRC", "RES", "OBS", "GEN" };
 EXPORT_SYMBOL_GPL(pp_msgs);
 
 /* request timeout */
-const char *to_msgs[] = { "no timeout",	"timed out" };
+const char * const to_msgs[] = { "no timeout", "timed out" };
 EXPORT_SYMBOL_GPL(to_msgs);
 
 /* memory or i/o */
-const char *ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
+const char * const ii_msgs[] = { "MEM", "RESV", "IO", "GEN" };
 EXPORT_SYMBOL_GPL(ii_msgs);
 
-static const char *f10h_nb_mce_desc[] = {
-	"HT link data error",
-	"Protocol error (link, L3, probe filter, etc.)",
-	"Parity error in NB-internal arrays",
-	"Link Retry due to IO link transmission error",
-	"L3 ECC data cache error",
-	"ECC error in L3 cache tag",
-	"L3 LRU parity bits error",
-	"ECC Error in the Probe Filter directory"
-};
-
 static const char * const f15h_ic_mce_desc[] = {
 	"UC during a demand linefill from L2",
 	"Parity error during data load from IC",
@@ -88,7 +77,7 @@ static const char * const f15h_ic_mce_desc[] = {
 	"Parity error for IC probe tag valid bit",
 	"PFB non-cacheable bit parity error",
 	"PFB valid bit parity error",			/* xec = 0xd */
-	"patch RAM",					/* xec = 010 */
+	"Microcode Patch Buffer",			/* xec = 010 */
 	"uop queue",
 	"insn buffer",
 	"predecode buffer",
@@ -104,7 +93,7 @@ static const char * const f15h_cu_mce_desc[] = {
 	"WCC Tag ECC error",
 	"WCC Data ECC error",
 	"WCB Data parity error",
-	"VB Data/ECC error",
+	"VB Data ECC or parity error",
 	"L2 Tag ECC error",				/* xec = 0x10 */
 	"Hard L2 Tag ECC error",
 	"Multiple hits on L2 tag",
@@ -112,6 +101,28 @@ static const char * const f15h_cu_mce_desc[] = {
 	"PRB address parity error"
 };
 
+static const char * const nb_mce_desc[] = {
+	"DRAM ECC error detected on the NB",
+	"CRC error detected on HT link",
+	"Link-defined sync error packets detected on HT link",
+	"HT Master abort",
+	"HT Target abort",
+	"Invalid GART PTE entry during GART table walk",
+	"Unsupported atomic RMW received from an IO link",
+	"Watchdog timeout due to lack of progress",
+	"DRAM ECC error detected on the NB",
+	"SVM DMA Exclusion Vector error",
+	"HT data error detected on link",
+	"Protocol error (link, L3, probe filter)",
+	"NB internal arrays parity error",
+	"DRAM addr/ctl signals parity error",
+	"IO link transmission error",
+	"L3 data cache ECC error",			/* xec = 0x1c */
+	"L3 cache tag error",
+	"L3 LRU parity bits error",
+	"ECC Error in the Probe Filter directory"
+};
+
 static const char * const fr_ex_mce_desc[] = {
 	"CPU Watchdog timer expire",
 	"Wakeup array dest tag",
@@ -125,7 +136,7 @@ static const char * const fr_ex_mce_desc[] = {
 	"Physical register file AG0 port",
 	"Physical register file AG1 port",
 	"Flag register file",
-	"DE correctable error could not be corrected"
+	"DE error occurred"
 };
 
 static bool f12h_dc_mce(u16 ec, u8 xec)
@@ -255,10 +266,9 @@ static bool f15h_dc_mce(u16 ec, u8 xec)
 	} else if (BUS_ERROR(ec)) {
 
 		if (!xec)
-			pr_cont("during system linefill.\n");
+			pr_cont("System Read Data Error.\n");
 		else
-			pr_cont(" Internal %s condition.\n",
-				((xec == 1) ? "livelock" : "deadlock"));
+			pr_cont(" Internal error condition type %d.\n", xec);
 	} else
 		ret = false;
 
@@ -355,7 +365,11 @@ static bool f15h_ic_mce(u16 ec, u8 xec)
 		pr_cont("%s.\n", f15h_ic_mce_desc[xec-2]);
 		break;
 
-	case 0x10 ... 0x14:
+	case 0x10:
+		pr_cont("%s.\n", f15h_ic_mce_desc[xec-4]);
+		break;
+
+	case 0x11 ... 0x14:
 		pr_cont("Decoder %s parity error.\n", f15h_ic_mce_desc[xec-4]);
 		break;
 
@@ -496,58 +510,31 @@ wrong_ls_mce:
 	pr_emerg(HW_ERR "Corrupted LS MCE info?\n");
 }
 
-static bool k8_nb_mce(u16 ec, u8 xec)
+void amd_decode_nb_mce(struct mce *m)
 {
-	bool ret = true;
-
-	switch (xec) {
-	case 0x1:
-		pr_cont("CRC error detected on HT link.\n");
-		break;
-
-	case 0x5:
-		pr_cont("Invalid GART PTE entry during GART table walk.\n");
-		break;
-
-	case 0x6:
-		pr_cont("Unsupported atomic RMW received from an IO link.\n");
-		break;
-
-	case 0x0:
-	case 0x8:
-		if (boot_cpu_data.x86 == 0x11)
-			return false;
-
-		pr_cont("DRAM ECC error detected on the NB.\n");
-		break;
-
-	case 0xd:
-		pr_cont("Parity error on the DRAM addr/ctl signals.\n");
-		break;
-
-	default:
-		ret = false;
-		break;
-	}
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+	int node_id = amd_get_nb_id(m->extcpu);
+	u16 ec = EC(m->status);
+	u8 xec = XEC(m->status, 0x1f);
+	u8 offset = 0;
 
-	return ret;
-}
+	pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
 
-static bool f10h_nb_mce(u16 ec, u8 xec)
-{
-	bool ret = true;
-	u8 offset = 0;
+	switch (xec) {
+	case 0x0 ... 0xe:
 
-	if (k8_nb_mce(ec, xec))
-		return true;
+		/* special handling for DRAM ECCs */
+		if (xec == 0x0 || xec == 0x8) {
+			/* no ECCs on F11h */
+			if (c->x86 == 0x11)
+				goto wrong_nb_mce;
 
-	switch(xec) {
-	case 0xa ... 0xc:
-		offset = 10;
-		break;
+			pr_cont("%s.\n", nb_mce_desc[xec]);
 
-	case 0xe:
-		offset = 11;
+			if (nb_bus_decoder)
+				nb_bus_decoder(node_id, m);
+			return;
+		}
 		break;
 
 	case 0xf:
@@ -556,83 +543,25 @@ static bool f10h_nb_mce(u16 ec, u8 xec)
 		else if (BUS_ERROR(ec))
 			pr_cont("DMA Exclusion Vector Table Walk error.\n");
 		else
-			ret = false;
-
-		goto out;
-		break;
+			goto wrong_nb_mce;
+		return;
 
 	case 0x19:
 		if (boot_cpu_data.x86 == 0x15)
 			pr_cont("Compute Unit Data Error.\n");
 		else
-			ret = false;
-
-		goto out;
-		break;
+			goto wrong_nb_mce;
+		return;
 
 	case 0x1c ... 0x1f:
-		offset = 24;
+		offset = 13;
 		break;
 
 	default:
-		ret = false;
-
-		goto out;
-		break;
-	}
-
-	pr_cont("%s.\n", f10h_nb_mce_desc[xec - offset]);
-
-out:
-	return ret;
-}
-
-static bool nb_noop_mce(u16 ec, u8 xec)
-{
-	return false;
-}
-
-void amd_decode_nb_mce(struct mce *m)
-{
-	struct cpuinfo_x86 *c = &boot_cpu_data;
-	int node_id = amd_get_nb_id(m->extcpu);
-	u16 ec = EC(m->status);
-	u8 xec = XEC(m->status, 0x1f);
-
-	pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
-
-	switch (xec) {
-	case 0x2:
-		pr_cont("Sync error (sync packets on HT link detected).\n");
-		return;
-
-	case 0x3:
-		pr_cont("HT Master abort.\n");
-		return;
-
-	case 0x4:
-		pr_cont("HT Target abort.\n");
-		return;
-
-	case 0x7:
-		pr_cont("NB Watchdog timeout.\n");
-		return;
-
-	case 0x9:
-		pr_cont("SVM DMA Exclusion Vector error.\n");
-		return;
-
-	default:
-		break;
-	}
-
-	if (!fam_ops->nb_mce(ec, xec))
 		goto wrong_nb_mce;
+	}
 
-	if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15)
-		if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
-			nb_bus_decoder(node_id, m);
-
+	pr_cont("%s.\n", nb_mce_desc[xec - offset]);
 	return;
 
 wrong_nb_mce:
@@ -648,9 +577,6 @@ static void amd_decode_fr_mce(struct mce *m)
 	if (c->x86 == 0xf || c->x86 == 0x11)
 		goto wrong_fr_mce;
 
-	if (c->x86 != 0x15 && xec != 0x0)
-		goto wrong_fr_mce;
-
 	pr_emerg(HW_ERR "%s Error: ",
 		 (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
 
@@ -841,39 +767,33 @@ static int __init mce_amd_init(void)
 	case 0xf:
 		fam_ops->dc_mce = k8_dc_mce;
 		fam_ops->ic_mce = k8_ic_mce;
-		fam_ops->nb_mce = k8_nb_mce;
 		break;
 
 	case 0x10:
 		fam_ops->dc_mce = f10h_dc_mce;
 		fam_ops->ic_mce = k8_ic_mce;
-		fam_ops->nb_mce = f10h_nb_mce;
 		break;
 
 	case 0x11:
 		fam_ops->dc_mce = k8_dc_mce;
 		fam_ops->ic_mce = k8_ic_mce;
-		fam_ops->nb_mce = f10h_nb_mce;
 		break;
 
 	case 0x12:
 		fam_ops->dc_mce = f12h_dc_mce;
 		fam_ops->ic_mce = k8_ic_mce;
-		fam_ops->nb_mce = nb_noop_mce;
 		break;
 
 	case 0x14:
 		nb_err_cpumask  = 0x3;
 		fam_ops->dc_mce = f14h_dc_mce;
 		fam_ops->ic_mce = f14h_ic_mce;
-		fam_ops->nb_mce = nb_noop_mce;
 		break;
 
 	case 0x15:
 		xec_mask = 0x1f;
 		fam_ops->dc_mce = f15h_dc_mce;
 		fam_ops->ic_mce = f15h_ic_mce;
-		fam_ops->nb_mce = f10h_nb_mce;
 		break;
 
 	default:
diff --git a/drivers/edac/mce_amd.h b/drivers/edac/mce_amd.h
index 0106747..c6074c5 100644
--- a/drivers/edac/mce_amd.h
+++ b/drivers/edac/mce_amd.h
@@ -69,12 +69,12 @@ enum rrrr_ids {
 	R4_SNOOP,
 };
 
-extern const char *tt_msgs[];
-extern const char *ll_msgs[];
-extern const char *rrrr_msgs[];
-extern const char *pp_msgs[];
-extern const char *to_msgs[];
-extern const char *ii_msgs[];
+extern const char * const tt_msgs[];
+extern const char * const ll_msgs[];
+extern const char * const rrrr_msgs[];
+extern const char * const pp_msgs[];
+extern const char * const to_msgs[];
+extern const char * const ii_msgs[];
 
 /*
  * per-family decoder ops
@@ -82,7 +82,6 @@ extern const char *ii_msgs[];
 struct amd_decoder_ops {
 	bool (*dc_mce)(u16, u8);
 	bool (*ic_mce)(u16, u8);
-	bool (*nb_mce)(u16, u8);
 };
 
 void amd_report_gart_errors(bool);
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index f3b890d..4c6c7d8 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -641,6 +641,7 @@ static void fw_unit_release(struct device *dev)
 {
 	struct fw_unit *unit = fw_unit(dev);
 
+	fw_device_put(fw_parent_device(unit));
 	kfree(unit);
 }
 
@@ -692,6 +693,7 @@ static void create_units(struct fw_device *device)
 		if (device_register(&unit->device) < 0)
 			goto skip_unit;
 
+		fw_device_get(device);
 		continue;
 
 	skip_unit:
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h
index b45be57..b5b3495 100644
--- a/drivers/firewire/core.h
+++ b/drivers/firewire/core.h
@@ -1,6 +1,7 @@
 #ifndef _FIREWIRE_CORE_H
 #define _FIREWIRE_CORE_H
 
+#include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <linux/idr.h>
@@ -141,6 +142,18 @@ extern struct rw_semaphore fw_device_rwsem;
 extern struct idr fw_device_idr;
 extern int fw_cdev_major;
 
+static inline struct fw_device *fw_device_get(struct fw_device *device)
+{
+	get_device(&device->device);
+
+	return device;
+}
+
+static inline void fw_device_put(struct fw_device *device)
+{
+	put_device(&device->device);
+}
+
 struct fw_device *fw_device_get_by_devt(dev_t devt);
 int fw_device_set_broadcast_channel(struct device *dev, void *gen);
 void fw_node_event(struct fw_card *card, struct fw_node *node, int event);
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 7f5f0da..f752498 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -349,7 +349,7 @@ MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
 	", busReset events = "	__stringify(OHCI_PARAM_DEBUG_BUSRESETS)
 	", or a combination, or all = -1)");
 
-static void log_irqs(u32 evt)
+static void log_irqs(struct fw_ohci *ohci, u32 evt)
 {
 	if (likely(!(param_debug &
 			(OHCI_PARAM_DEBUG_IRQS | OHCI_PARAM_DEBUG_BUSRESETS))))
@@ -359,7 +359,8 @@ static void log_irqs(u32 evt)
 	    !(evt & OHCI1394_busReset))
 		return;
 
-	fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+	dev_notice(ohci->card.device,
+	    "IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
 	    evt & OHCI1394_selfIDComplete	? " selfID"		: "",
 	    evt & OHCI1394_RQPkt		? " AR_req"		: "",
 	    evt & OHCI1394_RSPkt		? " AR_resp"		: "",
@@ -398,24 +399,29 @@ static char _p(u32 *s, int shift)
 	return port[*s >> shift & 3];
 }
 
-static void log_selfids(int node_id, int generation, int self_id_count, u32 *s)
+static void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count)
 {
+	u32 *s;
+
 	if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS)))
 		return;
 
-	fw_notify("%d selfIDs, generation %d, local node ID %04x\n",
-		  self_id_count, generation, node_id);
+	dev_notice(ohci->card.device,
+		   "%d selfIDs, generation %d, local node ID %04x\n",
+		   self_id_count, generation, ohci->node_id);
 
-	for (; self_id_count--; ++s)
+	for (s = ohci->self_id_buffer; self_id_count--; ++s)
 		if ((*s & 1 << 23) == 0)
-			fw_notify("selfID 0: %08x, phy %d [%c%c%c] "
+			dev_notice(ohci->card.device,
+			    "selfID 0: %08x, phy %d [%c%c%c] "
 			    "%s gc=%d %s %s%s%s\n",
 			    *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2),
 			    speed[*s >> 14 & 3], *s >> 16 & 63,
 			    power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "",
 			    *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : "");
 		else
-			fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n",
+			dev_notice(ohci->card.device,
+			    "selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n",
 			    *s, *s >> 24 & 63,
 			    _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10),
 			    _p(s,  8), _p(s,  6), _p(s,  4), _p(s,  2));
@@ -451,7 +457,8 @@ static const char *tcodes[] = {
 	[0xe] = "link internal",	[0xf] = "-reserved-",
 };
 
-static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
+static void log_ar_at_event(struct fw_ohci *ohci,
+			    char dir, int speed, u32 *header, int evt)
 {
 	int tcode = header[0] >> 4 & 0xf;
 	char specific[12];
@@ -463,8 +470,9 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
 			evt = 0x1f;
 
 	if (evt == OHCI1394_evt_bus_reset) {
-		fw_notify("A%c evt_bus_reset, generation %d\n",
-		    dir, (header[2] >> 16) & 0xff);
+		dev_notice(ohci->card.device,
+			   "A%c evt_bus_reset, generation %d\n",
+			   dir, (header[2] >> 16) & 0xff);
 		return;
 	}
 
@@ -483,36 +491,41 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
 
 	switch (tcode) {
 	case 0xa:
-		fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]);
+		dev_notice(ohci->card.device,
+			   "A%c %s, %s\n",
+			   dir, evts[evt], tcodes[tcode]);
 		break;
 	case 0xe:
-		fw_notify("A%c %s, PHY %08x %08x\n",
-			  dir, evts[evt], header[1], header[2]);
+		dev_notice(ohci->card.device,
+			   "A%c %s, PHY %08x %08x\n",
+			   dir, evts[evt], header[1], header[2]);
 		break;
 	case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
-		fw_notify("A%c spd %x tl %02x, "
-		    "%04x -> %04x, %s, "
-		    "%s, %04x%08x%s\n",
-		    dir, speed, header[0] >> 10 & 0x3f,
-		    header[1] >> 16, header[0] >> 16, evts[evt],
-		    tcodes[tcode], header[1] & 0xffff, header[2], specific);
+		dev_notice(ohci->card.device,
+			   "A%c spd %x tl %02x, "
+			   "%04x -> %04x, %s, "
+			   "%s, %04x%08x%s\n",
+			   dir, speed, header[0] >> 10 & 0x3f,
+			   header[1] >> 16, header[0] >> 16, evts[evt],
+			   tcodes[tcode], header[1] & 0xffff, header[2], specific);
 		break;
 	default:
-		fw_notify("A%c spd %x tl %02x, "
-		    "%04x -> %04x, %s, "
-		    "%s%s\n",
-		    dir, speed, header[0] >> 10 & 0x3f,
-		    header[1] >> 16, header[0] >> 16, evts[evt],
-		    tcodes[tcode], specific);
+		dev_notice(ohci->card.device,
+			   "A%c spd %x tl %02x, "
+			   "%04x -> %04x, %s, "
+			   "%s%s\n",
+			   dir, speed, header[0] >> 10 & 0x3f,
+			   header[1] >> 16, header[0] >> 16, evts[evt],
+			   tcodes[tcode], specific);
 	}
 }
 
 #else
 
 #define param_debug 0
-static inline void log_irqs(u32 evt) {}
-static inline void log_selfids(int node_id, int generation, int self_id_count, u32 *s) {}
-static inline void log_ar_at_event(char dir, int speed, u32 *header, int evt) {}
+static inline void log_irqs(struct fw_ohci *ohci, u32 evt) {}
+static inline void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count) {}
+static inline void log_ar_at_event(struct fw_ohci *ohci, char dir, int speed, u32 *header, int evt) {}
 
 #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */
 
@@ -559,7 +572,7 @@ static int read_phy_reg(struct fw_ohci *ohci, int addr)
 		if (i >= 3)
 			msleep(1);
 	}
-	fw_error("failed to read phy reg\n");
+	dev_err(ohci->card.device, "failed to read phy reg\n");
 
 	return -EBUSY;
 }
@@ -581,7 +594,7 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val)
 		if (i >= 3)
 			msleep(1);
 	}
-	fw_error("failed to write phy reg\n");
+	dev_err(ohci->card.device, "failed to write phy reg\n");
 
 	return -EBUSY;
 }
@@ -680,11 +693,14 @@ static void ar_context_release(struct ar_context *ctx)
 
 static void ar_context_abort(struct ar_context *ctx, const char *error_msg)
 {
-	if (reg_read(ctx->ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) {
-		reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
-		flush_writes(ctx->ohci);
+	struct fw_ohci *ohci = ctx->ohci;
 
-		fw_error("AR error: %s; DMA stopped\n", error_msg);
+	if (reg_read(ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) {
+		reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
+		flush_writes(ohci);
+
+		dev_err(ohci->card.device, "AR error: %s; DMA stopped\n",
+			error_msg);
 	}
 	/* FIXME: restart? */
 }
@@ -854,7 +870,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
 	p.timestamp  = status & 0xffff;
 	p.generation = ohci->request_generation;
 
-	log_ar_at_event('R', p.speed, p.header, evt);
+	log_ar_at_event(ohci, 'R', p.speed, p.header, evt);
 
 	/*
 	 * Several controllers, notably from NEC and VIA, forget to
@@ -1226,21 +1242,22 @@ static void context_append(struct context *ctx,
 
 static void context_stop(struct context *ctx)
 {
+	struct fw_ohci *ohci = ctx->ohci;
 	u32 reg;
 	int i;
 
-	reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
+	reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN);
 	ctx->running = false;
 
 	for (i = 0; i < 1000; i++) {
-		reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs));
+		reg = reg_read(ohci, CONTROL_SET(ctx->regs));
 		if ((reg & CONTEXT_ACTIVE) == 0)
 			return;
 
 		if (i)
 			udelay(10);
 	}
-	fw_error("Error: DMA context still active (0x%08x)\n", reg);
+	dev_err(ohci->card.device, "DMA context still active (0x%08x)\n", reg);
 }
 
 struct driver_data {
@@ -1420,7 +1437,7 @@ static int handle_at_packet(struct context *context,
 	evt = le16_to_cpu(last->transfer_status) & 0x1f;
 	packet->timestamp = le16_to_cpu(last->res_count);
 
-	log_ar_at_event('T', packet->speed, packet->header, evt);
+	log_ar_at_event(ohci, 'T', packet->speed, packet->header, evt);
 
 	switch (evt) {
 	case OHCI1394_evt_timeout:
@@ -1549,7 +1566,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
 			goto out;
 		}
 
-	fw_error("swap not done (CSR lock timeout)\n");
+	dev_err(ohci->card.device, "swap not done (CSR lock timeout)\n");
 	fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
  out:
@@ -1625,11 +1642,13 @@ static void detect_dead_context(struct fw_ohci *ohci,
 	ctl = reg_read(ohci, CONTROL_SET(regs));
 	if (ctl & CONTEXT_DEAD) {
 #ifdef CONFIG_FIREWIRE_OHCI_DEBUG
-		fw_error("DMA context %s has stopped, error code: %s\n",
-			 name, evts[ctl & 0x1f]);
+		dev_err(ohci->card.device,
+			"DMA context %s has stopped, error code: %s\n",
+			name, evts[ctl & 0x1f]);
 #else
-		fw_error("DMA context %s has stopped, error code: %#x\n",
-			 name, ctl & 0x1f);
+		dev_err(ohci->card.device,
+			"DMA context %s has stopped, error code: %#x\n",
+			name, ctl & 0x1f);
 #endif
 	}
 }
@@ -1781,7 +1800,8 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count)
 
 	reg = reg_read(ohci, OHCI1394_NodeID);
 	if (!(reg & OHCI1394_NodeID_idValid)) {
-		fw_notify("node ID not valid, new bus reset in progress\n");
+		dev_notice(ohci->card.device,
+			   "node ID not valid, new bus reset in progress\n");
 		return -EBUSY;
 	}
 	self_id |= ((reg & 0x3f) << 24); /* phy ID */
@@ -1827,11 +1847,12 @@ static void bus_reset_work(struct work_struct *work)
 
 	reg = reg_read(ohci, OHCI1394_NodeID);
 	if (!(reg & OHCI1394_NodeID_idValid)) {
-		fw_notify("node ID not valid, new bus reset in progress\n");
+		dev_notice(ohci->card.device,
+			   "node ID not valid, new bus reset in progress\n");
 		return;
 	}
 	if ((reg & OHCI1394_NodeID_nodeNumber) == 63) {
-		fw_notify("malconfigured bus\n");
+		dev_notice(ohci->card.device, "malconfigured bus\n");
 		return;
 	}
 	ohci->node_id = reg & (OHCI1394_NodeID_busNumber |
@@ -1845,7 +1866,7 @@ static void bus_reset_work(struct work_struct *work)
 
 	reg = reg_read(ohci, OHCI1394_SelfIDCount);
 	if (reg & OHCI1394_SelfIDCount_selfIDError) {
-		fw_notify("inconsistent self IDs\n");
+		dev_notice(ohci->card.device, "inconsistent self IDs\n");
 		return;
 	}
 	/*
@@ -1857,7 +1878,7 @@ static void bus_reset_work(struct work_struct *work)
 	self_id_count = (reg >> 3) & 0xff;
 
 	if (self_id_count > 252) {
-		fw_notify("inconsistent self IDs\n");
+		dev_notice(ohci->card.device, "inconsistent self IDs\n");
 		return;
 	}
 
@@ -1875,11 +1896,13 @@ static void bus_reset_work(struct work_struct *work)
 			 */
 			if (cond_le32_to_cpu(ohci->self_id_cpu[i])
 							== 0xffff008f) {
-				fw_notify("ignoring spurious self IDs\n");
+				dev_notice(ohci->card.device,
+					   "ignoring spurious self IDs\n");
 				self_id_count = j;
 				break;
 			} else {
-				fw_notify("inconsistent self IDs\n");
+				dev_notice(ohci->card.device,
+					   "inconsistent self IDs\n");
 				return;
 			}
 		}
@@ -1890,13 +1913,14 @@ static void bus_reset_work(struct work_struct *work)
 	if (ohci->quirks & QUIRK_TI_SLLZ059) {
 		self_id_count = find_and_insert_self_id(ohci, self_id_count);
 		if (self_id_count < 0) {
-			fw_notify("could not construct local self ID\n");
+			dev_notice(ohci->card.device,
+				   "could not construct local self ID\n");
 			return;
 		}
 	}
 
 	if (self_id_count == 0) {
-		fw_notify("inconsistent self IDs\n");
+		dev_notice(ohci->card.device, "inconsistent self IDs\n");
 		return;
 	}
 	rmb();
@@ -1917,8 +1941,8 @@ static void bus_reset_work(struct work_struct *work)
 
 	new_generation = (reg_read(ohci, OHCI1394_SelfIDCount) >> 16) & 0xff;
 	if (new_generation != generation) {
-		fw_notify("recursive bus reset detected, "
-			  "discarding self ids\n");
+		dev_notice(ohci->card.device,
+			   "new bus reset, discarding self ids\n");
 		return;
 	}
 
@@ -1989,8 +2013,7 @@ static void bus_reset_work(struct work_struct *work)
 		dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
 				  free_rom, free_rom_bus);
 
-	log_selfids(ohci->node_id, generation,
-		    self_id_count, ohci->self_id_buffer);
+	log_selfids(ohci, generation, self_id_count);
 
 	fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation,
 				 self_id_count, ohci->self_id_buffer,
@@ -2015,7 +2038,7 @@ static irqreturn_t irq_handler(int irq, void *data)
 	 */
 	reg_write(ohci, OHCI1394_IntEventClear,
 		  event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
-	log_irqs(event);
+	log_irqs(ohci, event);
 
 	if (event & OHCI1394_selfIDComplete)
 		queue_work(fw_workqueue, &ohci->bus_reset_work);
@@ -2057,8 +2080,8 @@ static irqreturn_t irq_handler(int irq, void *data)
 	}
 
 	if (unlikely(event & OHCI1394_regAccessFail))
-		fw_error("Register access failure - "
-			 "please notify linux1394-devel@lists.sf.net\n");
+		dev_err(ohci->card.device,
+			"register access failure - please notify linux1394-devel@lists.sf.net\n");
 
 	if (unlikely(event & OHCI1394_postedWriteErr)) {
 		reg_read(ohci, OHCI1394_PostedWriteAddressHi);
@@ -2066,12 +2089,13 @@ static irqreturn_t irq_handler(int irq, void *data)
 		reg_write(ohci, OHCI1394_IntEventClear,
 			  OHCI1394_postedWriteErr);
 		if (printk_ratelimit())
-			fw_error("PCI posted write error\n");
+			dev_err(ohci->card.device, "PCI posted write error\n");
 	}
 
 	if (unlikely(event & OHCI1394_cycleTooLong)) {
 		if (printk_ratelimit())
-			fw_notify("isochronous cycle too long\n");
+			dev_notice(ohci->card.device,
+				   "isochronous cycle too long\n");
 		reg_write(ohci, OHCI1394_LinkControlSet,
 			  OHCI1394_LinkControl_cycleMaster);
 	}
@@ -2084,7 +2108,8 @@ static irqreturn_t irq_handler(int irq, void *data)
 		 * them at least two cycles later.  (FIXME?)
 		 */
 		if (printk_ratelimit())
-			fw_notify("isochronous cycle inconsistent\n");
+			dev_notice(ohci->card.device,
+				   "isochronous cycle inconsistent\n");
 	}
 
 	if (unlikely(event & OHCI1394_unrecoverableError))
@@ -2211,7 +2236,7 @@ static int ohci_enable(struct fw_card *card,
 	int i, ret;
 
 	if (software_reset(ohci)) {
-		fw_error("Failed to reset ohci card.\n");
+		dev_err(card->device, "failed to reset ohci card\n");
 		return -EBUSY;
 	}
 
@@ -2235,7 +2260,7 @@ static int ohci_enable(struct fw_card *card,
 	}
 
 	if (!lps) {
-		fw_error("Failed to set Link Power Status\n");
+		dev_err(card->device, "failed to set Link Power Status\n");
 		return -EIO;
 	}
 
@@ -2244,7 +2269,7 @@ static int ohci_enable(struct fw_card *card,
 		if (ret < 0)
 			return ret;
 		if (ret)
-			fw_notify("local TSB41BA3D phy\n");
+			dev_notice(card->device, "local TSB41BA3D phy\n");
 		else
 			ohci->quirks &= ~QUIRK_TI_SLLZ059;
 	}
@@ -2344,7 +2369,8 @@ static int ohci_enable(struct fw_card *card,
 	if (request_irq(dev->irq, irq_handler,
 			pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED,
 			ohci_driver_name, ohci)) {
-		fw_error("Failed to allocate interrupt %d.\n", dev->irq);
+		dev_err(card->device, "failed to allocate interrupt %d\n",
+			dev->irq);
 		pci_disable_msi(dev);
 
 		if (config_rom) {
@@ -2509,7 +2535,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
 		dma_unmap_single(ohci->card.device, packet->payload_bus,
 				 packet->payload_length, DMA_TO_DEVICE);
 
-	log_ar_at_event('T', packet->speed, packet->header, 0x20);
+	log_ar_at_event(ohci, 'T', packet->speed, packet->header, 0x20);
 	driver_data->packet = NULL;
 	packet->ack = RCODE_CANCELLED;
 	packet->callback(packet, &ohci->card, packet->ack);
@@ -3463,7 +3489,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
 
 	err = pci_enable_device(dev);
 	if (err) {
-		fw_error("Failed to enable OHCI hardware\n");
+		dev_err(&dev->dev, "failed to enable OHCI hardware\n");
 		goto fail_free;
 	}
 
@@ -3478,13 +3504,13 @@ static int __devinit pci_probe(struct pci_dev *dev,
 
 	err = pci_request_region(dev, 0, ohci_driver_name);
 	if (err) {
-		fw_error("MMIO resource unavailable\n");
+		dev_err(&dev->dev, "MMIO resource unavailable\n");
 		goto fail_disable;
 	}
 
 	ohci->registers = pci_iomap(dev, 0, OHCI1394_REGISTER_SIZE);
 	if (ohci->registers == NULL) {
-		fw_error("Failed to remap registers\n");
+		dev_err(&dev->dev, "failed to remap registers\n");
 		err = -ENXIO;
 		goto fail_iomem;
 	}
@@ -3573,9 +3599,10 @@ static int __devinit pci_probe(struct pci_dev *dev,
 		goto fail_contexts;
 
 	version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
-	fw_notify("Added fw-ohci device %s, OHCI v%x.%x, "
+	dev_notice(&dev->dev,
+		  "added OHCI v%x.%x device as card %d, "
 		  "%d IR + %d IT contexts, quirks 0x%x\n",
-		  dev_name(&dev->dev), version >> 16, version & 0xff,
+		  version >> 16, version & 0xff, ohci->card.index,
 		  ohci->n_ir, ohci->n_it, ohci->quirks);
 
 	return 0;
@@ -3604,7 +3631,7 @@ static int __devinit pci_probe(struct pci_dev *dev,
 	pmac_ohci_off(dev);
  fail:
 	if (err == -ENOMEM)
-		fw_error("Out of memory\n");
+		dev_err(&dev->dev, "out of memory\n");
 
 	return err;
 }
@@ -3648,7 +3675,7 @@ static void pci_remove(struct pci_dev *dev)
 	kfree(ohci);
 	pmac_ohci_off(dev);
 
-	fw_notify("Removed fw-ohci device.\n");
+	dev_notice(&dev->dev, "removed fw-ohci device\n");
 }
 
 #ifdef CONFIG_PM
@@ -3662,12 +3689,12 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state)
 	pci_disable_msi(dev);
 	err = pci_save_state(dev);
 	if (err) {
-		fw_error("pci_save_state failed\n");
+		dev_err(&dev->dev, "pci_save_state failed\n");
 		return err;
 	}
 	err = pci_set_power_state(dev, pci_choose_state(dev, state));
 	if (err)
-		fw_error("pci_set_power_state failed with %d\n", err);
+		dev_err(&dev->dev, "pci_set_power_state failed with %d\n", err);
 	pmac_ohci_off(dev);
 
 	return 0;
@@ -3683,7 +3710,7 @@ static int pci_resume(struct pci_dev *dev)
 	pci_restore_state(dev);
 	err = pci_enable_device(dev);
 	if (err) {
-		fw_error("pci_enable_device failed\n");
+		dev_err(&dev->dev, "pci_enable_device failed\n");
 		return err;
 	}
 
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 80e95aa..52559f9 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -165,7 +165,6 @@ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
  */
 struct sbp2_target {
 	struct fw_unit *unit;
-	const char *bus_id;
 	struct list_head lu_list;
 
 	u64 management_agent_address;
@@ -181,11 +180,21 @@ struct sbp2_target {
 	int blocked;	/* ditto */
 };
 
-static struct fw_device *target_device(struct sbp2_target *tgt)
+static struct fw_device *target_parent_device(struct sbp2_target *tgt)
 {
 	return fw_parent_device(tgt->unit);
 }
 
+static const struct device *tgt_dev(const struct sbp2_target *tgt)
+{
+	return &tgt->unit->device;
+}
+
+static const struct device *lu_dev(const struct sbp2_logical_unit *lu)
+{
+	return &lu->tgt->unit->device;
+}
+
 /* Impossible login_id, to detect logout attempt before successful login */
 #define INVALID_LOGIN_ID 0x10000
 
@@ -430,7 +439,8 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
 		memcpy(status.data, payload + 8, length - 8);
 
 	if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) {
-		fw_notify("non-orb related status write, not handled\n");
+		dev_notice(lu_dev(lu),
+			   "non-ORB related status write, not handled\n");
 		fw_send_response(card, request, RCODE_COMPLETE);
 		return;
 	}
@@ -451,7 +461,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
 		orb->callback(orb, &status);
 		kref_put(&orb->kref, free_orb); /* orb callback reference */
 	} else {
-		fw_error("status write for unknown orb\n");
+		dev_err(lu_dev(lu), "status write for unknown ORB\n");
 	}
 
 	fw_send_response(card, request, RCODE_COMPLETE);
@@ -492,7 +502,7 @@ static void complete_transaction(struct fw_card *card, int rcode,
 static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
 			  int node_id, int generation, u64 offset)
 {
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	struct sbp2_pointer orb_pointer;
 	unsigned long flags;
 
@@ -513,7 +523,7 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
 
 static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
 {
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	struct sbp2_orb *orb, *next;
 	struct list_head list;
 	unsigned long flags;
@@ -552,7 +562,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
 				    int generation, int function,
 				    int lun_or_login_id, void *response)
 {
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	struct sbp2_management_orb *orb;
 	unsigned int timeout;
 	int retval = -ENOMEM;
@@ -612,20 +622,20 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
 
 	retval = -EIO;
 	if (sbp2_cancel_orbs(lu) == 0) {
-		fw_error("%s: orb reply timed out, rcode=0x%02x\n",
-			 lu->tgt->bus_id, orb->base.rcode);
+		dev_err(lu_dev(lu), "ORB reply timed out, rcode 0x%02x\n",
+			orb->base.rcode);
 		goto out;
 	}
 
 	if (orb->base.rcode != RCODE_COMPLETE) {
-		fw_error("%s: management write failed, rcode 0x%02x\n",
-			 lu->tgt->bus_id, orb->base.rcode);
+		dev_err(lu_dev(lu), "management write failed, rcode 0x%02x\n",
+			orb->base.rcode);
 		goto out;
 	}
 
 	if (STATUS_GET_RESPONSE(orb->status) != 0 ||
 	    STATUS_GET_SBP_STATUS(orb->status) != 0) {
-		fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id,
+		dev_err(lu_dev(lu), "error status: %d:%d\n",
 			 STATUS_GET_RESPONSE(orb->status),
 			 STATUS_GET_SBP_STATUS(orb->status));
 		goto out;
@@ -648,7 +658,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
 
 static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
 {
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	__be32 d = 0;
 
 	fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
@@ -665,7 +675,7 @@ static void complete_agent_reset_write_no_wait(struct fw_card *card,
 
 static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
 {
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	struct fw_transaction *t;
 	static __be32 d;
 
@@ -704,7 +714,7 @@ static inline void sbp2_allow_block(struct sbp2_logical_unit *lu)
 static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
 {
 	struct sbp2_target *tgt = lu->tgt;
-	struct fw_card *card = target_device(tgt)->card;
+	struct fw_card *card = target_parent_device(tgt)->card;
 	struct Scsi_Host *shost =
 		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
 	unsigned long flags;
@@ -728,7 +738,7 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu)
 static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
 {
 	struct sbp2_target *tgt = lu->tgt;
-	struct fw_card *card = target_device(tgt)->card;
+	struct fw_card *card = target_parent_device(tgt)->card;
 	struct Scsi_Host *shost =
 		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
 	unsigned long flags;
@@ -753,7 +763,7 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu)
  */
 static void sbp2_unblock(struct sbp2_target *tgt)
 {
-	struct fw_card *card = target_device(tgt)->card;
+	struct fw_card *card = target_parent_device(tgt)->card;
 	struct Scsi_Host *shost =
 		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
 	unsigned long flags;
@@ -794,7 +804,7 @@ static int sbp2_lun2int(u16 lun)
  */
 static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
 {
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	__be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
 
 	fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
@@ -809,7 +819,7 @@ static void sbp2_login(struct work_struct *work)
 	struct sbp2_logical_unit *lu =
 		container_of(work, struct sbp2_logical_unit, work.work);
 	struct sbp2_target *tgt = lu->tgt;
-	struct fw_device *device = target_device(tgt);
+	struct fw_device *device = target_parent_device(tgt);
 	struct Scsi_Host *shost;
 	struct scsi_device *sdev;
 	struct sbp2_login_response response;
@@ -833,8 +843,8 @@ static void sbp2_login(struct work_struct *work)
 		if (lu->retries++ < 5) {
 			sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5));
 		} else {
-			fw_error("%s: failed to login to LUN %04x\n",
-				 tgt->bus_id, lu->lun);
+			dev_err(tgt_dev(tgt), "failed to login to LUN %04x\n",
+				lu->lun);
 			/* Let any waiting I/O fail from now on. */
 			sbp2_unblock(lu->tgt);
 		}
@@ -851,8 +861,8 @@ static void sbp2_login(struct work_struct *work)
 		      << 32) | be32_to_cpu(response.command_block_agent.low);
 	lu->login_id = be32_to_cpu(response.misc) & 0xffff;
 
-	fw_notify("%s: logged in to LUN %04x (%d retries)\n",
-		  tgt->bus_id, lu->lun, lu->retries);
+	dev_notice(tgt_dev(tgt), "logged in to LUN %04x (%d retries)\n",
+		   lu->lun, lu->retries);
 
 	/* set appropriate retry limit(s) in BUSY_TIMEOUT register */
 	sbp2_set_busy_timeout(lu);
@@ -919,7 +929,7 @@ static void sbp2_reconnect(struct work_struct *work)
 	struct sbp2_logical_unit *lu =
 		container_of(work, struct sbp2_logical_unit, work.work);
 	struct sbp2_target *tgt = lu->tgt;
-	struct fw_device *device = target_device(tgt);
+	struct fw_device *device = target_parent_device(tgt);
 	int generation, node_id, local_node_id;
 
 	if (fw_device_is_shutdown(device))
@@ -943,7 +953,7 @@ static void sbp2_reconnect(struct work_struct *work)
 		smp_rmb(); /* get current card generation */
 		if (generation == device->card->generation ||
 		    lu->retries++ >= 5) {
-			fw_error("%s: failed to reconnect\n", tgt->bus_id);
+			dev_err(tgt_dev(tgt), "failed to reconnect\n");
 			lu->retries = 0;
 			PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
 		}
@@ -957,8 +967,8 @@ static void sbp2_reconnect(struct work_struct *work)
 	smp_wmb();	  /* node IDs must not be older than generation */
 	lu->generation	  = generation;
 
-	fw_notify("%s: reconnected to LUN %04x (%d retries)\n",
-		  tgt->bus_id, lu->lun, lu->retries);
+	dev_notice(tgt_dev(tgt), "reconnected to LUN %04x (%d retries)\n",
+		   lu->lun, lu->retries);
 
 	sbp2_agent_reset(lu);
 	sbp2_cancel_orbs(lu);
@@ -1068,8 +1078,8 @@ static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt)
 	unsigned int timeout = tgt->mgt_orb_timeout;
 
 	if (timeout > 40000)
-		fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n",
-			  tgt->bus_id, timeout / 1000);
+		dev_notice(tgt_dev(tgt), "%ds mgt_ORB_timeout limited to 40s\n",
+			   timeout / 1000);
 
 	tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000);
 }
@@ -1081,9 +1091,9 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
 	unsigned int w = sbp2_param_workarounds;
 
 	if (w)
-		fw_notify("Please notify linux1394-devel@lists.sourceforge.net "
-			  "if you need the workarounds parameter for %s\n",
-			  tgt->bus_id);
+		dev_notice(tgt_dev(tgt),
+			   "Please notify linux1394-devel@lists.sf.net "
+			   "if you need the workarounds parameter\n");
 
 	if (w & SBP2_WORKAROUND_OVERRIDE)
 		goto out;
@@ -1103,9 +1113,9 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
 	}
  out:
 	if (w)
-		fw_notify("Workarounds for %s: 0x%x "
-			  "(firmware_revision 0x%06x, model_id 0x%06x)\n",
-			  tgt->bus_id, w, firmware_revision, model);
+		dev_notice(tgt_dev(tgt), "workarounds 0x%x "
+			   "(firmware_revision 0x%06x, model_id 0x%06x)\n",
+			   w, firmware_revision, model);
 	tgt->workarounds = w;
 }
 
@@ -1133,7 +1143,6 @@ static int sbp2_probe(struct device *dev)
 	dev_set_drvdata(&unit->device, tgt);
 	tgt->unit = unit;
 	INIT_LIST_HEAD(&tgt->lu_list);
-	tgt->bus_id = dev_name(&unit->device);
 	tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
 
 	if (fw_device_enable_phys_dma(device) < 0)
@@ -1239,7 +1248,7 @@ static int sbp2_remove(struct device *dev)
 		kfree(lu);
 	}
 	scsi_remove_host(shost);
-	fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no);
+	dev_notice(dev, "released target %d:0:0\n", shost->host_no);
 
 	scsi_host_put(shost);
 	return 0;
@@ -1325,7 +1334,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb,
 {
 	struct sbp2_command_orb *orb =
 		container_of(base_orb, struct sbp2_command_orb, base);
-	struct fw_device *device = target_device(orb->lu->tgt);
+	struct fw_device *device = target_parent_device(orb->lu->tgt);
 	int result;
 
 	if (status != NULL) {
@@ -1433,7 +1442,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost,
 				  struct scsi_cmnd *cmd)
 {
 	struct sbp2_logical_unit *lu = cmd->device->hostdata;
-	struct fw_device *device = target_device(lu->tgt);
+	struct fw_device *device = target_parent_device(lu->tgt);
 	struct sbp2_command_orb *orb;
 	int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
 
@@ -1442,7 +1451,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost,
 	 * transfer direction not handled.
 	 */
 	if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
-		fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
+		dev_err(lu_dev(lu), "cannot handle bidirectional command\n");
 		cmd->result = DID_ERROR << 16;
 		cmd->scsi_done(cmd);
 		return 0;
@@ -1450,7 +1459,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost,
 
 	orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
 	if (orb == NULL) {
-		fw_notify("failed to alloc orb\n");
+		dev_notice(lu_dev(lu), "failed to alloc ORB\n");
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -1550,7 +1559,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
 {
 	struct sbp2_logical_unit *lu = cmd->device->hostdata;
 
-	fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id);
+	dev_notice(lu_dev(lu), "sbp2_scsi_abort\n");
 	sbp2_agent_reset(lu);
 	sbp2_cancel_orbs(lu);
 
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d0c4118..dbb1909 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -225,6 +225,12 @@ config GPIO_MAX732X_IRQ
 	  Say yes here to enable the max732x to be used as an interrupt
 	  controller. It requires the driver to be built in the kernel.
 
+config GPIO_MC9S08DZ60
+	bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions"
+	depends on I2C && MACH_MX35_3DS
+	help
+	  Select this to enable the MC9S08DZ60 GPIO driver
+
 config GPIO_PCA953X
 	tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports"
 	depends on I2C
@@ -411,6 +417,14 @@ config GPIO_ML_IOH
 	  Hub) which is for IVI(In-Vehicle Infotainment) use.
 	  This driver can access the IOH's GPIO device.
 
+config GPIO_SODAVILLE
+	bool "Intel Sodaville GPIO support"
+	depends on X86 && PCI && OF
+	select GPIO_GENERIC
+	select GENERIC_IRQ_CHIP
+	help
+	  Say Y here to support Intel Sodaville GPIO.
+
 config GPIO_TIMBERDALE
 	bool "Support for timberdale GPIO IP"
 	depends on MFD_TIMBERDALE && HAS_IOMEM
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index fa10df6..593bdcd 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_MAX7300)	+= gpio-max7300.o
 obj-$(CONFIG_GPIO_MAX7301)	+= gpio-max7301.o
 obj-$(CONFIG_GPIO_MAX732X)	+= gpio-max732x.o
 obj-$(CONFIG_GPIO_MC33880)	+= gpio-mc33880.o
+obj-$(CONFIG_GPIO_MC9S08DZ60)	+= gpio-mc9s08dz60.o
 obj-$(CONFIG_GPIO_MCP23S08)	+= gpio-mcp23s08.o
 obj-$(CONFIG_GPIO_ML_IOH)	+= gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MPC5200)	+= gpio-mpc5200.o
@@ -45,6 +46,7 @@ obj-$(CONFIG_GPIO_RDC321X)	+= gpio-rdc321x.o
 obj-$(CONFIG_PLAT_SAMSUNG)	+= gpio-samsung.o
 obj-$(CONFIG_ARCH_SA1100)	+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SCH)		+= gpio-sch.o
+obj-$(CONFIG_GPIO_SODAVILLE)	+= gpio-sodaville.o
 obj-$(CONFIG_GPIO_STMPE)	+= gpio-stmpe.o
 obj-$(CONFIG_GPIO_SX150X)	+= gpio-sx150x.o
 obj-$(CONFIG_GPIO_TC3589X)	+= gpio-tc3589x.o
diff --git a/drivers/gpio/gpio-mc9s08dz60.c b/drivers/gpio/gpio-mc9s08dz60.c
new file mode 100644
index 0000000..2738cc4
--- /dev/null
+++ b/drivers/gpio/gpio-mc9s08dz60.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Wu Guoxing <b39297@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+
+#define GPIO_GROUP_NUM 2
+#define GPIO_NUM_PER_GROUP 8
+#define GPIO_NUM (GPIO_GROUP_NUM*GPIO_NUM_PER_GROUP)
+
+struct mc9s08dz60 {
+	struct i2c_client *client;
+	struct gpio_chip chip;
+};
+
+static inline struct mc9s08dz60 *to_mc9s08dz60(struct gpio_chip *gc)
+{
+	return container_of(gc, struct mc9s08dz60, chip);
+}
+
+
+static void mc9s_gpio_to_reg_and_bit(int offset, u8 *reg, u8 *bit)
+{
+	*reg = 0x20 + offset / GPIO_NUM_PER_GROUP;
+	*bit = offset % GPIO_NUM_PER_GROUP;
+}
+
+static int mc9s08dz60_get_value(struct gpio_chip *gc, unsigned offset)
+{
+	u8 reg, bit;
+	s32 value;
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	mc9s_gpio_to_reg_and_bit(offset, &reg, &bit);
+	value = i2c_smbus_read_byte_data(mc9s->client, reg);
+
+	return (value >= 0) ? (value >> bit) & 0x1 : 0;
+}
+
+static int mc9s08dz60_set(struct mc9s08dz60 *mc9s, unsigned offset, int val)
+{
+	u8 reg, bit;
+	s32 value;
+
+	mc9s_gpio_to_reg_and_bit(offset, &reg, &bit);
+	value = i2c_smbus_read_byte_data(mc9s->client, reg);
+	if (value >= 0) {
+		if (val)
+			value |= 1 << bit;
+		else
+			value &= ~(1 << bit);
+
+		return i2c_smbus_write_byte_data(mc9s->client, reg, value);
+	} else
+		return value;
+
+}
+
+
+static void mc9s08dz60_set_value(struct gpio_chip *gc, unsigned offset, int val)
+{
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	mc9s08dz60_set(mc9s, offset, val);
+}
+
+static int mc9s08dz60_direction_output(struct gpio_chip *gc,
+				       unsigned offset, int val)
+{
+	struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc);
+
+	return mc9s08dz60_set(mc9s, offset, val);
+}
+
+static int mc9s08dz60_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	int ret = 0;
+	struct mc9s08dz60 *mc9s;
+
+	mc9s = kzalloc(sizeof(*mc9s), GFP_KERNEL);
+	if (!mc9s)
+		return -ENOMEM;
+
+	mc9s->chip.label = client->name;
+	mc9s->chip.base = -1;
+	mc9s->chip.dev = &client->dev;
+	mc9s->chip.owner = THIS_MODULE;
+	mc9s->chip.ngpio = GPIO_NUM;
+	mc9s->chip.can_sleep = 1;
+	mc9s->chip.get = mc9s08dz60_get_value;
+	mc9s->chip.set = mc9s08dz60_set_value;
+	mc9s->chip.direction_output = mc9s08dz60_direction_output;
+	mc9s->client = client;
+	i2c_set_clientdata(client, mc9s);
+
+	ret = gpiochip_add(&mc9s->chip);
+	if (ret)
+		goto error;
+
+	return 0;
+
+ error:
+	kfree(mc9s);
+	return ret;
+}
+
+static int mc9s08dz60_remove(struct i2c_client *client)
+{
+	struct mc9s08dz60 *mc9s;
+	int ret;
+
+	mc9s = i2c_get_clientdata(client);
+
+	ret = gpiochip_remove(&mc9s->chip);
+	if (!ret)
+		kfree(mc9s);
+
+	return ret;
+
+}
+
+static const struct i2c_device_id mc9s08dz60_id[] = {
+	{"mc9s08dz60", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, mc9s08dz60_id);
+
+static struct i2c_driver mc9s08dz60_i2c_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "mc9s08dz60",
+	},
+	.probe = mc9s08dz60_probe,
+	.remove = mc9s08dz60_remove,
+	.id_table = mc9s08dz60_id,
+};
+
+module_i2c_driver(mc9s08dz60_i2c_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc. "
+		"Wu Guoxing <b39297@freescale.com>");
+MODULE_DESCRIPTION("mc9s08dz60 gpio function on mx35 3ds board");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 5cd04b6..e6568c1 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -37,7 +37,7 @@ struct mpc8xxx_gpio_chip {
 	 * open drain mode safely
 	 */
 	u32 data;
-	struct irq_host *irq;
+	struct irq_domain *irq;
 	void *of_dev_id_data;
 };
 
@@ -281,7 +281,7 @@ static struct irq_chip mpc8xxx_irq_chip = {
 	.irq_set_type	= mpc8xxx_irq_set_type,
 };
 
-static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
@@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
 	return 0;
 }
 
-static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
-				  const u32 *intspec, unsigned int intsize,
-				  irq_hw_number_t *out_hwirq,
-				  unsigned int *out_flags)
-
-{
-	/* interrupt sense values coming from the device tree equal either
-	 * EDGE_FALLING or EDGE_BOTH
-	 */
-	*out_hwirq = intspec[0];
-	*out_flags = intspec[1];
-
-	return 0;
-}
-
-static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
 	.map	= mpc8xxx_gpio_irq_map,
-	.xlate	= mpc8xxx_gpio_irq_xlate,
+	.xlate	= irq_domain_xlate_twocell,
 };
 
 static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
@@ -364,9 +349,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 	if (hwirq == NO_IRQ)
 		goto skip_irq;
 
-	mpc8xxx_gc->irq =
-		irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
-			       &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+	mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
+					&mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
 	if (!mpc8xxx_gc->irq)
 		goto skip_irq;
 
@@ -374,8 +358,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
 	if (id)
 		mpc8xxx_gc->of_dev_id_data = id->data;
 
-	mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
 	/* ack and mask all irqs */
 	out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
 	out_be32(mm_gc->regs + GPIO_IMR, 0);
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index b2d3ee1..5689ce6 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -22,6 +22,8 @@
 #include <linux/syscore_ops.h>
 #include <linux/slab.h>
 
+#include <mach/irqs.h>
+
 /*
  * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with
  * one set of registers. The register offsets are organized below:
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c
new file mode 100644
index 0000000..9ba15d3
--- /dev/null
+++ b/drivers/gpio/gpio-sodaville.c
@@ -0,0 +1,302 @@
+/*
+ *  GPIO interface for Intel Sodaville SoCs.
+ *
+ *  Copyright (c) 2010, 2011 Intel Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/of_irq.h>
+#include <linux/basic_mmio_gpio.h>
+
+#define DRV_NAME		"sdv_gpio"
+#define SDV_NUM_PUB_GPIOS	12
+#define PCI_DEVICE_ID_SDV_GPIO	0x2e67
+#define GPIO_BAR		0
+
+#define GPOUTR		0x00
+#define GPOER		0x04
+#define GPINR		0x08
+
+#define GPSTR		0x0c
+#define GPIT1R0		0x10
+#define GPIO_INT	0x14
+#define GPIT1R1		0x18
+
+#define GPMUXCTL	0x1c
+
+struct sdv_gpio_chip_data {
+	int irq_base;
+	void __iomem *gpio_pub_base;
+	struct irq_domain id;
+	struct irq_chip_generic *gc;
+	struct bgpio_chip bgpio;
+};
+
+static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct sdv_gpio_chip_data *sd = gc->private;
+	void __iomem *type_reg;
+	u32 irq_offs = d->irq - sd->irq_base;
+	u32 reg;
+
+	if (irq_offs < 8)
+		type_reg = sd->gpio_pub_base + GPIT1R0;
+	else
+		type_reg = sd->gpio_pub_base + GPIT1R1;
+
+	reg = readl(type_reg);
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_HIGH:
+		reg &= ~BIT(4 * (irq_offs % 8));
+		break;
+
+	case IRQ_TYPE_LEVEL_LOW:
+		reg |= BIT(4 * (irq_offs % 8));
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	writel(reg, type_reg);
+	return 0;
+}
+
+static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data)
+{
+	struct sdv_gpio_chip_data *sd = data;
+	u32 irq_stat = readl(sd->gpio_pub_base + GPSTR);
+
+	irq_stat &= readl(sd->gpio_pub_base + GPIO_INT);
+	if (!irq_stat)
+		return IRQ_NONE;
+
+	while (irq_stat) {
+		u32 irq_bit = __fls(irq_stat);
+
+		irq_stat &= ~BIT(irq_bit);
+		generic_handle_irq(sd->irq_base + irq_bit);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int sdv_xlate(struct irq_domain *h, struct device_node *node,
+		const u32 *intspec, u32 intsize, irq_hw_number_t *out_hwirq,
+		u32 *out_type)
+{
+	u32 line, type;
+
+	if (node != h->of_node)
+		return -EINVAL;
+
+	if (intsize < 2)
+		return -EINVAL;
+
+	line = *intspec;
+	*out_hwirq = line;
+
+	intspec++;
+	type = *intspec;
+
+	switch (type) {
+	case IRQ_TYPE_LEVEL_LOW:
+	case IRQ_TYPE_LEVEL_HIGH:
+		*out_type = type;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct irq_domain_ops irq_domain_sdv_ops = {
+	.dt_translate	= sdv_xlate,
+};
+
+static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd,
+		struct pci_dev *pdev)
+{
+	struct irq_chip_type *ct;
+	int ret;
+
+	sd->irq_base = irq_alloc_descs(-1, 0, SDV_NUM_PUB_GPIOS, -1);
+	if (sd->irq_base < 0)
+		return sd->irq_base;
+
+	/* mask + ACK all interrupt sources */
+	writel(0, sd->gpio_pub_base + GPIO_INT);
+	writel((1 << 11) - 1, sd->gpio_pub_base + GPSTR);
+
+	ret = request_irq(pdev->irq, sdv_gpio_pub_irq_handler, IRQF_SHARED,
+			"sdv_gpio", sd);
+	if (ret)
+		goto out_free_desc;
+
+	sd->id.irq_base = sd->irq_base;
+	sd->id.of_node = of_node_get(pdev->dev.of_node);
+	sd->id.ops = &irq_domain_sdv_ops;
+
+	/*
+	 * This gpio irq controller latches level irqs. Testing shows that if
+	 * we unmask & ACK the IRQ before the source of the interrupt is gone
+	 * then the interrupt is active again.
+	 */
+	sd->gc = irq_alloc_generic_chip("sdv-gpio", 1, sd->irq_base,
+			sd->gpio_pub_base, handle_fasteoi_irq);
+	if (!sd->gc) {
+		ret = -ENOMEM;
+		goto out_free_irq;
+	}
+
+	sd->gc->private = sd;
+	ct = sd->gc->chip_types;
+	ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
+	ct->regs.eoi = GPSTR;
+	ct->regs.mask = GPIO_INT;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->chip.irq_eoi = irq_gc_eoi;
+	ct->chip.irq_set_type = sdv_gpio_pub_set_type;
+
+	irq_setup_generic_chip(sd->gc, IRQ_MSK(SDV_NUM_PUB_GPIOS),
+			IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST,
+			IRQ_LEVEL | IRQ_NOPROBE);
+
+	irq_domain_add(&sd->id);
+	return 0;
+out_free_irq:
+	free_irq(pdev->irq, sd);
+out_free_desc:
+	irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
+	return ret;
+}
+
+static int __devinit sdv_gpio_probe(struct pci_dev *pdev,
+					const struct pci_device_id *pci_id)
+{
+	struct sdv_gpio_chip_data *sd;
+	unsigned long addr;
+	const void *prop;
+	int len;
+	int ret;
+	u32 mux_val;
+
+	sd = kzalloc(sizeof(struct sdv_gpio_chip_data), GFP_KERNEL);
+	if (!sd)
+		return -ENOMEM;
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "can't enable device.\n");
+		goto done;
+	}
+
+	ret = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
+	if (ret) {
+		dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
+		goto disable_pci;
+	}
+
+	addr = pci_resource_start(pdev, GPIO_BAR);
+	if (!addr)
+		goto release_reg;
+	sd->gpio_pub_base = ioremap(addr, pci_resource_len(pdev, GPIO_BAR));
+
+	prop = of_get_property(pdev->dev.of_node, "intel,muxctl", &len);
+	if (prop && len == 4) {
+		mux_val = of_read_number(prop, 1);
+		writel(mux_val, sd->gpio_pub_base + GPMUXCTL);
+	}
+
+	ret = bgpio_init(&sd->bgpio, &pdev->dev, 4,
+			sd->gpio_pub_base + GPINR, sd->gpio_pub_base + GPOUTR,
+			NULL, sd->gpio_pub_base + GPOER, NULL, false);
+	if (ret)
+		goto unmap;
+	sd->bgpio.gc.ngpio = SDV_NUM_PUB_GPIOS;
+
+	ret = gpiochip_add(&sd->bgpio.gc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "gpiochip_add() failed.\n");
+		goto unmap;
+	}
+
+	ret = sdv_register_irqsupport(sd, pdev);
+	if (ret)
+		goto unmap;
+
+	pci_set_drvdata(pdev, sd);
+	dev_info(&pdev->dev, "Sodaville GPIO driver registered.\n");
+	return 0;
+
+unmap:
+	iounmap(sd->gpio_pub_base);
+release_reg:
+	pci_release_region(pdev, GPIO_BAR);
+disable_pci:
+	pci_disable_device(pdev);
+done:
+	kfree(sd);
+	return ret;
+}
+
+static void sdv_gpio_remove(struct pci_dev *pdev)
+{
+	struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev);
+
+	irq_domain_del(&sd->id);
+	free_irq(pdev->irq, sd);
+	irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
+
+	if (gpiochip_remove(&sd->bgpio.gc))
+		dev_err(&pdev->dev, "gpiochip_remove() failed.\n");
+
+	pci_release_region(pdev, GPIO_BAR);
+	iounmap(sd->gpio_pub_base);
+	pci_disable_device(pdev);
+	kfree(sd);
+}
+
+static struct pci_device_id sdv_gpio_pci_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_SDV_GPIO) },
+	{ 0, },
+};
+
+static struct pci_driver sdv_gpio_driver = {
+	.name = DRV_NAME,
+	.id_table = sdv_gpio_pci_ids,
+	.probe = sdv_gpio_probe,
+	.remove = sdv_gpio_remove,
+};
+
+static int __init sdv_gpio_init(void)
+{
+	return pci_register_driver(&sdv_gpio_driver);
+}
+module_init(sdv_gpio_init);
+
+static void __exit sdv_gpio_exit(void)
+{
+	pci_unregister_driver(&sdv_gpio_driver);
+}
+module_exit(sdv_gpio_exit);
+
+MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>");
+MODULE_DESCRIPTION("GPIO interface for Intel Sodaville SoCs");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 87a68a8..094c5c4 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -307,13 +307,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
 	struct stmpe_gpio_platform_data *pdata;
 	struct stmpe_gpio *stmpe_gpio;
 	int ret;
-	int irq;
+	int irq = 0;
 
 	pdata = stmpe->pdata->gpio;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
 
 	stmpe_gpio = kzalloc(sizeof(struct stmpe_gpio), GFP_KERNEL);
 	if (!stmpe_gpio)
@@ -330,21 +328,28 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
 	stmpe_gpio->chip.dev = &pdev->dev;
 	stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1;
 
-	stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
+	if (irq >= 0)
+		stmpe_gpio->irq_base = stmpe->irq_base + STMPE_INT_GPIO(0);
+	else
+		dev_info(&pdev->dev,
+			"device configured in no-irq mode; "
+			"irqs are not available\n");
 
 	ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
 	if (ret)
 		goto out_free;
 
-	ret = stmpe_gpio_irq_init(stmpe_gpio);
-	if (ret)
-		goto out_disable;
+	if (irq >= 0) {
+		ret = stmpe_gpio_irq_init(stmpe_gpio);
+		if (ret)
+			goto out_disable;
 
-	ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT,
-				   "stmpe-gpio", stmpe_gpio);
-	if (ret) {
-		dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
-		goto out_removeirq;
+		ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq,
+				IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
+		if (ret) {
+			dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
+			goto out_removeirq;
+		}
 	}
 
 	ret = gpiochip_add(&stmpe_gpio->chip);
@@ -361,9 +366,11 @@ static int __devinit stmpe_gpio_probe(struct platform_device *pdev)
 	return 0;
 
 out_freeirq:
-	free_irq(irq, stmpe_gpio);
+	if (irq >= 0)
+		free_irq(irq, stmpe_gpio);
 out_removeirq:
-	stmpe_gpio_irq_remove(stmpe_gpio);
+	if (irq >= 0)
+		stmpe_gpio_irq_remove(stmpe_gpio);
 out_disable:
 	stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
 out_free:
@@ -391,8 +398,10 @@ static int __devexit stmpe_gpio_remove(struct platform_device *pdev)
 
 	stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
 
-	free_irq(irq, stmpe_gpio);
-	stmpe_gpio_irq_remove(stmpe_gpio);
+	if (irq >= 0) {
+		free_irq(irq, stmpe_gpio);
+		stmpe_gpio_irq_remove(stmpe_gpio);
+	}
 	platform_set_drvdata(pdev, NULL);
 	kfree(stmpe_gpio);
 
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index bdc2937..98f3980 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/irqdomain.h>
 
 #include <asm/mach/irq.h>
 
@@ -74,9 +75,10 @@ struct tegra_gpio_bank {
 #endif
 };
 
-
+static struct irq_domain irq_domain;
 static void __iomem *regs;
-static struct tegra_gpio_bank tegra_gpio_banks[7];
+static u32 tegra_gpio_bank_count;
+static struct tegra_gpio_bank *tegra_gpio_banks;
 
 static inline void tegra_gpio_writel(u32 val, u32 reg)
 {
@@ -139,7 +141,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 
 static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
 {
-	return TEGRA_GPIO_TO_IRQ(offset);
+	return irq_domain_to_irq(&irq_domain, offset);
 }
 
 static struct gpio_chip tegra_gpio_chip = {
@@ -155,28 +157,28 @@ static struct gpio_chip tegra_gpio_chip = {
 
 static void tegra_gpio_irq_ack(struct irq_data *d)
 {
-	int gpio = d->irq - INT_GPIO_BASE;
+	int gpio = d->hwirq;
 
 	tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
 }
 
 static void tegra_gpio_irq_mask(struct irq_data *d)
 {
-	int gpio = d->irq - INT_GPIO_BASE;
+	int gpio = d->hwirq;
 
 	tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
 }
 
 static void tegra_gpio_irq_unmask(struct irq_data *d)
 {
-	int gpio = d->irq - INT_GPIO_BASE;
+	int gpio = d->hwirq;
 
 	tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
 }
 
 static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 {
-	int gpio = d->irq - INT_GPIO_BASE;
+	int gpio = d->hwirq;
 	struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
 	int port = GPIO_PORT(gpio);
 	int lvl_type;
@@ -273,7 +275,7 @@ void tegra_gpio_resume(void)
 
 	local_irq_save(flags);
 
-	for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+	for (b = 0; b < tegra_gpio_bank_count; b++) {
 		struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
 
 		for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -296,7 +298,7 @@ void tegra_gpio_suspend(void)
 	int p;
 
 	local_irq_save(flags);
-	for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+	for (b = 0; b < tegra_gpio_bank_count; b++) {
 		struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
 
 		for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -337,13 +339,46 @@ static struct lock_class_key gpio_lock_class;
 
 static int __devinit tegra_gpio_probe(struct platform_device *pdev)
 {
+	int irq_base;
 	struct resource *res;
 	struct tegra_gpio_bank *bank;
 	int gpio;
 	int i;
 	int j;
 
-	for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+	for (;;) {
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count);
+		if (!res)
+			break;
+		tegra_gpio_bank_count++;
+	}
+	if (!tegra_gpio_bank_count) {
+		dev_err(&pdev->dev, "Missing IRQ resource\n");
+		return -ENODEV;
+	}
+
+	tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32;
+
+	tegra_gpio_banks = devm_kzalloc(&pdev->dev,
+			tegra_gpio_bank_count * sizeof(*tegra_gpio_banks),
+			GFP_KERNEL);
+	if (!tegra_gpio_banks) {
+		dev_err(&pdev->dev, "Couldn't allocate bank structure\n");
+		return -ENODEV;
+	}
+
+	irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
+	if (irq_base < 0) {
+		dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
+		return -ENODEV;
+	}
+	irq_domain.irq_base = irq_base;
+	irq_domain.nr_irq = tegra_gpio_chip.ngpio;
+	irq_domain.ops = &irq_domain_simple_ops;
+	irq_domain.of_node = pdev->dev.of_node;
+	irq_domain_add(&irq_domain);
+
+	for (i = 0; i < tegra_gpio_bank_count; i++) {
 		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
 		if (!res) {
 			dev_err(&pdev->dev, "Missing IRQ resource\n");
@@ -380,8 +415,8 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
 
 	gpiochip_add(&tegra_gpio_chip);
 
-	for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
-		int irq = TEGRA_GPIO_TO_IRQ(gpio);
+	for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
+		int irq = irq_domain_to_irq(&irq_domain, gpio);
 		/* No validity check; all Tegra GPIOs are valid IRQs */
 
 		bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -393,7 +428,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
 		set_irq_flags(irq, IRQF_VALID);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+	for (i = 0; i < tegra_gpio_bank_count; i++) {
 		bank = &tegra_gpio_banks[i];
 
 		irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c
index 91f45b9..7eef648 100644
--- a/drivers/gpio/gpio-tps65910.c
+++ b/drivers/gpio/gpio-tps65910.c
@@ -69,6 +69,7 @@ static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
 void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
 {
 	int ret;
+	struct tps65910_board *board_data;
 
 	if (!gpio_base)
 		return;
@@ -80,10 +81,10 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
 
 	switch(tps65910_chip_id(tps65910)) {
 	case TPS65910:
-		tps65910->gpio.ngpio	= 6;
+		tps65910->gpio.ngpio	= TPS65910_NUM_GPIO;
 		break;
 	case TPS65911:
-		tps65910->gpio.ngpio	= 9;
+		tps65910->gpio.ngpio	= TPS65911_NUM_GPIO;
 		break;
 	default:
 		return;
@@ -95,6 +96,21 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
 	tps65910->gpio.set		= tps65910_gpio_set;
 	tps65910->gpio.get		= tps65910_gpio_get;
 
+	/* Configure sleep control for gpios */
+	board_data = dev_get_platdata(tps65910->dev);
+	if (board_data) {
+		int i;
+		for (i = 0; i < tps65910->gpio.ngpio; ++i) {
+			if (board_data->en_gpio_sleep[i]) {
+				ret = tps65910_set_bits(tps65910,
+					TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
+				if (ret < 0)
+					dev_warn(tps65910->dev,
+						"GPIO Sleep setting failed\n");
+			}
+		}
+	}
+
 	ret = gpiochip_add(&tps65910->gpio);
 
 	if (ret)
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 5928653..4b8653b 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -41,10 +41,10 @@ drm_clflush_page(struct page *page)
 	if (unlikely(page == NULL))
 		return;
 
-	page_virtual = kmap_atomic(page, KM_USER0);
+	page_virtual = kmap_atomic(page);
 	for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
 		clflush(page_virtual + i);
-	kunmap_atomic(page_virtual, KM_USER0);
+	kunmap_atomic(page_virtual);
 }
 
 static void drm_cache_flush_clflush(struct page *pages[],
@@ -87,10 +87,10 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
 		if (unlikely(page == NULL))
 			continue;
 
-		page_virtual = kmap_atomic(page, KM_USER0);
+		page_virtual = kmap_atomic(page);
 		flush_dcache_range((unsigned long)page_virtual,
 				   (unsigned long)page_virtual + PAGE_SIZE);
-		kunmap_atomic(page_virtual, KM_USER0);
+		kunmap_atomic(page_virtual);
 	}
 #else
 	printk(KERN_ERR "Architecture has no drm_cache.c support\n");
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 5e818a8..6fdaf6f 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -38,11 +38,6 @@
 #include "drm_edid.h"
 #include "drm_fourcc.h"
 
-struct drm_prop_enum_list {
-	int type;
-	char *name;
-};
-
 /* Avoid boilerplate.  I'm tired of typing. */
 #define DRM_ENUM_NAME_FN(fnname, list)				\
 	char *fnname(int val)					\
@@ -442,7 +437,7 @@ void drm_mode_remove(struct drm_connector *connector,
 		     struct drm_display_mode *mode)
 {
 	list_del(&mode->head);
-	kfree(mode);
+	drm_mode_destroy(connector->dev, mode);
 }
 EXPORT_SYMBOL(drm_mode_remove);
 
@@ -454,7 +449,7 @@ EXPORT_SYMBOL(drm_mode_remove);
  * @name: user visible name of the connector
  *
  * LOCKING:
- * Caller must hold @dev's mode_config lock.
+ * Takes mode config lock.
  *
  * Initialises a preallocated connector. Connectors should be
  * subclassed as part of driver connector objects.
@@ -497,7 +492,7 @@ EXPORT_SYMBOL(drm_connector_init);
  * @connector: connector to cleanup
  *
  * LOCKING:
- * Caller must hold @dev's mode_config lock.
+ * Takes mode config lock.
  *
  * Cleans up the connector but doesn't free the object.
  */
@@ -658,7 +653,6 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
 {
 	struct drm_property *edid;
 	struct drm_property *dpms;
-	int i;
 
 	/*
 	 * Standard properties (apply to all connectors)
@@ -668,11 +662,9 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
 				   "EDID", 0);
 	dev->mode_config.edid_property = edid;
 
-	dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
-				   "DPMS", ARRAY_SIZE(drm_dpms_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
-		drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
-				      drm_dpms_enum_list[i].name);
+	dpms = drm_property_create_enum(dev, 0,
+				   "DPMS", drm_dpms_enum_list,
+				   ARRAY_SIZE(drm_dpms_enum_list));
 	dev->mode_config.dpms_property = dpms;
 
 	return 0;
@@ -688,30 +680,21 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev)
 {
 	struct drm_property *dvi_i_selector;
 	struct drm_property *dvi_i_subconnector;
-	int i;
 
 	if (dev->mode_config.dvi_i_select_subconnector_property)
 		return 0;
 
 	dvi_i_selector =
-		drm_property_create(dev, DRM_MODE_PROP_ENUM,
+		drm_property_create_enum(dev, 0,
 				    "select subconnector",
+				    drm_dvi_i_select_enum_list,
 				    ARRAY_SIZE(drm_dvi_i_select_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
-		drm_property_add_enum(dvi_i_selector, i,
-				      drm_dvi_i_select_enum_list[i].type,
-				      drm_dvi_i_select_enum_list[i].name);
 	dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
 
-	dvi_i_subconnector =
-		drm_property_create(dev, DRM_MODE_PROP_ENUM |
-				    DRM_MODE_PROP_IMMUTABLE,
+	dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
 				    "subconnector",
+				    drm_dvi_i_subconnector_enum_list,
 				    ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
-		drm_property_add_enum(dvi_i_subconnector, i,
-				      drm_dvi_i_subconnector_enum_list[i].type,
-				      drm_dvi_i_subconnector_enum_list[i].name);
 	dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
 
 	return 0;
@@ -742,51 +725,33 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
 	/*
 	 * Basic connector properties
 	 */
-	tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+	tv_selector = drm_property_create_enum(dev, 0,
 					  "select subconnector",
+					  drm_tv_select_enum_list,
 					  ARRAY_SIZE(drm_tv_select_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
-		drm_property_add_enum(tv_selector, i,
-				      drm_tv_select_enum_list[i].type,
-				      drm_tv_select_enum_list[i].name);
 	dev->mode_config.tv_select_subconnector_property = tv_selector;
 
 	tv_subconnector =
-		drm_property_create(dev, DRM_MODE_PROP_ENUM |
-				    DRM_MODE_PROP_IMMUTABLE, "subconnector",
+		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
+				    "subconnector",
+				    drm_tv_subconnector_enum_list,
 				    ARRAY_SIZE(drm_tv_subconnector_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
-		drm_property_add_enum(tv_subconnector, i,
-				      drm_tv_subconnector_enum_list[i].type,
-				      drm_tv_subconnector_enum_list[i].name);
 	dev->mode_config.tv_subconnector_property = tv_subconnector;
 
 	/*
 	 * Other, TV specific properties: margins & TV modes.
 	 */
 	dev->mode_config.tv_left_margin_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "left margin", 2);
-	dev->mode_config.tv_left_margin_property->values[0] = 0;
-	dev->mode_config.tv_left_margin_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "left margin", 0, 100);
 
 	dev->mode_config.tv_right_margin_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "right margin", 2);
-	dev->mode_config.tv_right_margin_property->values[0] = 0;
-	dev->mode_config.tv_right_margin_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "right margin", 0, 100);
 
 	dev->mode_config.tv_top_margin_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "top margin", 2);
-	dev->mode_config.tv_top_margin_property->values[0] = 0;
-	dev->mode_config.tv_top_margin_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "top margin", 0, 100);
 
 	dev->mode_config.tv_bottom_margin_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "bottom margin", 2);
-	dev->mode_config.tv_bottom_margin_property->values[0] = 0;
-	dev->mode_config.tv_bottom_margin_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "bottom margin", 0, 100);
 
 	dev->mode_config.tv_mode_property =
 		drm_property_create(dev, DRM_MODE_PROP_ENUM,
@@ -796,40 +761,22 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
 				      i, modes[i]);
 
 	dev->mode_config.tv_brightness_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "brightness", 2);
-	dev->mode_config.tv_brightness_property->values[0] = 0;
-	dev->mode_config.tv_brightness_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "brightness", 0, 100);
 
 	dev->mode_config.tv_contrast_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "contrast", 2);
-	dev->mode_config.tv_contrast_property->values[0] = 0;
-	dev->mode_config.tv_contrast_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "contrast", 0, 100);
 
 	dev->mode_config.tv_flicker_reduction_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "flicker reduction", 2);
-	dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
-	dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
 
 	dev->mode_config.tv_overscan_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "overscan", 2);
-	dev->mode_config.tv_overscan_property->values[0] = 0;
-	dev->mode_config.tv_overscan_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "overscan", 0, 100);
 
 	dev->mode_config.tv_saturation_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "saturation", 2);
-	dev->mode_config.tv_saturation_property->values[0] = 0;
-	dev->mode_config.tv_saturation_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "saturation", 0, 100);
 
 	dev->mode_config.tv_hue_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "hue", 2);
-	dev->mode_config.tv_hue_property->values[0] = 0;
-	dev->mode_config.tv_hue_property->values[1] = 100;
+		drm_property_create_range(dev, 0, "hue", 0, 100);
 
 	return 0;
 }
@@ -845,18 +792,14 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
 int drm_mode_create_scaling_mode_property(struct drm_device *dev)
 {
 	struct drm_property *scaling_mode;
-	int i;
 
 	if (dev->mode_config.scaling_mode_property)
 		return 0;
 
 	scaling_mode =
-		drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
+		drm_property_create_enum(dev, 0, "scaling mode",
+				drm_scaling_mode_enum_list,
 				    ARRAY_SIZE(drm_scaling_mode_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
-		drm_property_add_enum(scaling_mode, i,
-				      drm_scaling_mode_enum_list[i].type,
-				      drm_scaling_mode_enum_list[i].name);
 
 	dev->mode_config.scaling_mode_property = scaling_mode;
 
@@ -874,18 +817,14 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
 int drm_mode_create_dithering_property(struct drm_device *dev)
 {
 	struct drm_property *dithering_mode;
-	int i;
 
 	if (dev->mode_config.dithering_mode_property)
 		return 0;
 
 	dithering_mode =
-		drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
+		drm_property_create_enum(dev, 0, "dithering",
+				drm_dithering_mode_enum_list,
 				    ARRAY_SIZE(drm_dithering_mode_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
-		drm_property_add_enum(dithering_mode, i,
-				      drm_dithering_mode_enum_list[i].type,
-				      drm_dithering_mode_enum_list[i].name);
 	dev->mode_config.dithering_mode_property = dithering_mode;
 
 	return 0;
@@ -902,20 +841,15 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
 int drm_mode_create_dirty_info_property(struct drm_device *dev)
 {
 	struct drm_property *dirty_info;
-	int i;
 
 	if (dev->mode_config.dirty_info_property)
 		return 0;
 
 	dirty_info =
-		drm_property_create(dev, DRM_MODE_PROP_ENUM |
-				    DRM_MODE_PROP_IMMUTABLE,
+		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
 				    "dirty",
+				    drm_dirty_info_enum_list,
 				    ARRAY_SIZE(drm_dirty_info_enum_list));
-	for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
-		drm_property_add_enum(dirty_info, i,
-				      drm_dirty_info_enum_list[i].type,
-				      drm_dirty_info_enum_list[i].name);
 	dev->mode_config.dirty_info_property = dirty_info;
 
 	return 0;
@@ -1048,6 +982,9 @@ void drm_mode_config_cleanup(struct drm_device *dev)
 				 head) {
 		plane->funcs->destroy(plane);
 	}
+
+	idr_remove_all(&dev->mode_config.crtc_idr);
+	idr_destroy(&dev->mode_config.crtc_idr);
 }
 EXPORT_SYMBOL(drm_mode_config_cleanup);
 
@@ -1311,7 +1248,7 @@ out:
  * @arg: arg from ioctl
  *
  * LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
  *
  * Construct a CRTC configuration structure to return to the user.
  *
@@ -1371,7 +1308,7 @@ out:
  * @arg: arg from ioctl
  *
  * LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
  *
  * Construct a connector configuration structure to return to the user.
  *
@@ -1553,6 +1490,9 @@ out:
  * @data: ioctl data
  * @file_priv: DRM file info
  *
+ * LOCKING:
+ * Takes mode config lock.
+ *
  * Return an plane count and set of IDs.
  */
 int drm_mode_getplane_res(struct drm_device *dev, void *data,
@@ -1599,6 +1539,9 @@ out:
  * @data: ioctl data
  * @file_priv: DRM file info
  *
+ * LOCKING:
+ * Takes mode config lock.
+ *
  * Return plane info, including formats supported, gamma size, any
  * current fb, etc.
  */
@@ -1664,6 +1607,9 @@ out:
  * @data: ioctl data*
  * @file_prive: DRM file info
  *
+ * LOCKING:
+ * Takes mode config lock.
+ *
  * Set plane info, including placement, fb, scaling, and other factors.
  * Or pass a NULL fb to disable.
  */
@@ -1794,7 +1740,7 @@ out:
  * @arg: arg from ioctl
  *
  * LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
  *
  * Build a new CRTC configuration based on user request.
  *
@@ -2275,7 +2221,7 @@ out:
  * @arg: arg from ioctl
  *
  * LOCKING:
- * Caller? (FIXME)
+ * Takes mode config lock.
  *
  * Lookup the FB given its ID and return info about it.
  *
@@ -2617,6 +2563,53 @@ fail:
 }
 EXPORT_SYMBOL(drm_property_create);
 
+struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
+					 const char *name,
+					 const struct drm_prop_enum_list *props,
+					 int num_values)
+{
+	struct drm_property *property;
+	int i, ret;
+
+	flags |= DRM_MODE_PROP_ENUM;
+
+	property = drm_property_create(dev, flags, name, num_values);
+	if (!property)
+		return NULL;
+
+	for (i = 0; i < num_values; i++) {
+		ret = drm_property_add_enum(property, i,
+				      props[i].type,
+				      props[i].name);
+		if (ret) {
+			drm_property_destroy(dev, property);
+			return NULL;
+		}
+	}
+
+	return property;
+}
+EXPORT_SYMBOL(drm_property_create_enum);
+
+struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
+					 const char *name,
+					 uint64_t min, uint64_t max)
+{
+	struct drm_property *property;
+
+	flags |= DRM_MODE_PROP_RANGE;
+
+	property = drm_property_create(dev, flags, name, 2);
+	if (!property)
+		return NULL;
+
+	property->values[0] = min;
+	property->values[1] = max;
+
+	return property;
+}
+EXPORT_SYMBOL(drm_property_create_range);
+
 int drm_property_add_enum(struct drm_property *property, int index,
 			  uint64_t value, const char *name)
 {
@@ -3021,7 +3014,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
 
-bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
+int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
 				  int gamma_size)
 {
 	crtc->gamma_size = gamma_size;
@@ -3029,10 +3022,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
 	crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
 	if (!crtc->gamma_store) {
 		crtc->gamma_size = 0;
-		return false;
+		return -ENOMEM;
 	}
 
-	return true;
+	return 0;
 }
 EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);
 
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 84a4a80..d761d12 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -44,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600);
 static void drm_mode_validate_flag(struct drm_connector *connector,
 				   int flags)
 {
-	struct drm_display_mode *mode, *t;
+	struct drm_display_mode *mode;
 
 	if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
 		return;
 
-	list_for_each_entry_safe(mode, t, &connector->modes, head) {
+	list_for_each_entry(mode, &connector->modes, head) {
 		if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
 				!(flags & DRM_MODE_FLAG_INTERLACE))
 			mode->status = MODE_NO_INTERLACE;
@@ -87,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 					    uint32_t maxX, uint32_t maxY)
 {
 	struct drm_device *dev = connector->dev;
-	struct drm_display_mode *mode, *t;
+	struct drm_display_mode *mode;
 	struct drm_connector_helper_funcs *connector_funcs =
 		connector->helper_private;
 	int count = 0;
@@ -96,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
 			drm_get_connector_name(connector));
 	/* set all modes to the unverified state */
-	list_for_each_entry_safe(mode, t, &connector->modes, head)
+	list_for_each_entry(mode, &connector->modes, head)
 		mode->status = MODE_UNVERIFIED;
 
 	if (connector->force) {
@@ -136,7 +136,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 		mode_flags |= DRM_MODE_FLAG_DBLSCAN;
 	drm_mode_validate_flag(connector, mode_flags);
 
-	list_for_each_entry_safe(mode, t, &connector->modes, head) {
+	list_for_each_entry(mode, &connector->modes, head) {
 		if (mode->status == MODE_OK)
 			mode->status = connector_funcs->mode_valid(connector,
 								   mode);
@@ -152,7 +152,7 @@ prune:
 
 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
 			drm_get_connector_name(connector));
-	list_for_each_entry_safe(mode, t, &connector->modes, head) {
+	list_for_each_entry(mode, &connector->modes, head) {
 		mode->vrefresh = drm_mode_vrefresh(mode);
 
 		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index ebf7d3f..d166bd0 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -135,23 +135,23 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
 
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
-	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ece03fc..7ee7be1 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -266,6 +266,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
 			}
 		};
 		ret = i2c_transfer(adapter, msgs, 2);
+		if (ret == -ENXIO) {
+			DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
+					adapter->name);
+			break;
+		}
 	} while (ret != 2 && --retries);
 
 	return ret == 2 ? 0 : -1;
@@ -745,7 +750,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
 		 */
 		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
 		if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
-			kfree(mode);
+			drm_mode_destroy(dev, mode);
 			mode = drm_gtf_mode_complex(dev, hsize, vsize,
 						    vrefresh_rate, 0, 0,
 						    drm_gtf2_m(edid),
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index aada26f..7740dd2 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
 #endif
 
-static void drm_fb_helper_on(struct fb_info *info)
+static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
 {
 	struct drm_fb_helper *fb_helper = info->par;
 	struct drm_device *dev = fb_helper->dev;
 	struct drm_crtc *crtc;
-	struct drm_crtc_helper_funcs *crtc_funcs;
-	struct drm_connector *connector;
-	struct drm_encoder *encoder;
-	int i, j;
-
-	/*
-	 * For each CRTC in this fb, turn the crtc on then,
-	 * find all associated encoders and turn them on.
-	 */
-	mutex_lock(&dev->mode_config.mutex);
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		crtc = fb_helper->crtc_info[i].mode_set.crtc;
-		crtc_funcs = crtc->helper_private;
-
-		if (!crtc->enabled)
-			continue;
-
-		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-
-		/* Walk the connectors & encoders on this fb turning them on */
-		for (j = 0; j < fb_helper->connector_count; j++) {
-			connector = fb_helper->connector_info[j]->connector;
-			connector->dpms = DRM_MODE_DPMS_ON;
-			drm_connector_property_set_value(connector,
-							 dev->mode_config.dpms_property,
-							 DRM_MODE_DPMS_ON);
-		}
-		/* Found a CRTC on this fb, now find encoders */
-		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-			if (encoder->crtc == crtc) {
-				struct drm_encoder_helper_funcs *encoder_funcs;
-
-				encoder_funcs = encoder->helper_private;
-				encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-			}
-		}
-	}
-	mutex_unlock(&dev->mode_config.mutex);
-}
-
-static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
-{
-	struct drm_fb_helper *fb_helper = info->par;
-	struct drm_device *dev = fb_helper->dev;
-	struct drm_crtc *crtc;
-	struct drm_crtc_helper_funcs *crtc_funcs;
 	struct drm_connector *connector;
-	struct drm_encoder *encoder;
 	int i, j;
 
 	/*
-	 * For each CRTC in this fb, find all associated encoders
-	 * and turn them off, then turn off the CRTC.
+	 * For each CRTC in this fb, turn the connectors on/off.
 	 */
 	mutex_lock(&dev->mode_config.mutex);
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		crtc = fb_helper->crtc_info[i].mode_set.crtc;
-		crtc_funcs = crtc->helper_private;
 
 		if (!crtc->enabled)
 			continue;
 
-		/* Walk the connectors on this fb and mark them off */
+		/* Walk the connectors & encoders on this fb turning them on/off */
 		for (j = 0; j < fb_helper->connector_count; j++) {
 			connector = fb_helper->connector_info[j]->connector;
-			connector->dpms = dpms_mode;
+			drm_helper_connector_dpms(connector, dpms_mode);
 			drm_connector_property_set_value(connector,
-							 dev->mode_config.dpms_property,
-							 dpms_mode);
-		}
-		/* Found a CRTC on this fb, now find encoders */
-		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-			if (encoder->crtc == crtc) {
-				struct drm_encoder_helper_funcs *encoder_funcs;
-
-				encoder_funcs = encoder->helper_private;
-				encoder_funcs->dpms(encoder, dpms_mode);
-			}
+				dev->mode_config.dpms_property, dpms_mode);
 		}
-		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 	}
 	mutex_unlock(&dev->mode_config.mutex);
 }
@@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
 	switch (blank) {
 	/* Display: On; HSync: On, VSync: On */
 	case FB_BLANK_UNBLANK:
-		drm_fb_helper_on(info);
+		drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
 		break;
 	/* Display: Off; HSync: On, VSync: On */
 	case FB_BLANK_NORMAL:
-		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+		drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
 		break;
 	/* Display: Off; HSync: Off, VSync: On */
 	case FB_BLANK_HSYNC_SUSPEND:
-		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+		drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
 		break;
 	/* Display: Off; HSync: On, VSync: Off */
 	case FB_BLANK_VSYNC_SUSPEND:
-		drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
+		drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND);
 		break;
 	/* Display: Off; HSync: Off, VSync: Off */
 	case FB_BLANK_POWERDOWN:
-		drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
+		drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF);
 		break;
 	}
 	return 0;
@@ -430,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
 	for (i = 0; i < helper->connector_count; i++)
 		kfree(helper->connector_info[i]);
 	kfree(helper->connector_info);
-	for (i = 0; i < helper->crtc_count; i++)
+	for (i = 0; i < helper->crtc_count; i++) {
 		kfree(helper->crtc_info[i].mode_set.connectors);
+		if (helper->crtc_info[i].mode_set.mode)
+			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
+	}
 	kfree(helper->crtc_info);
 }
 
@@ -474,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev,
 
 	i = 0;
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		fb_helper->crtc_info[i].crtc_id = crtc->base.id;
 		fb_helper->crtc_info[i].mode_set.crtc = crtc;
 		i++;
 	}
-	fb_helper->conn_limit = max_conn_count;
+
 	return 0;
 out_free:
 	drm_fb_helper_crtc_free(fb_helper);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 956fd38..cf85155 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -37,6 +37,7 @@
 #include "drm_core.h"
 
 #include "linux/pci.h"
+#include "linux/export.h"
 
 /**
  * Get the bus id.
@@ -276,6 +277,12 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
 	case DRM_CAP_VBLANK_HIGH_CRTC:
 		req->value = 1;
 		break;
+	case DRM_CAP_DUMB_PREFERRED_DEPTH:
+		req->value = dev->mode_config.preferred_depth;
+		break;
+	case DRM_CAP_DUMB_PREFER_SHADOW:
+		req->value = dev->mode_config.prefer_shadow;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -346,3 +353,4 @@ int drm_noop(struct drm_device *dev, void *data,
 	DRM_DEBUG("\n");
 	return 0;
 }
+EXPORT_SYMBOL(drm_noop);
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index fb8e46b..7ff13bc 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -686,8 +686,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
 			p->crtc_vsync_end /= 2;
 			p->crtc_vtotal /= 2;
 		}
-
-		p->crtc_vtotal |= 1;
 	}
 
 	if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
index d4d10b7..13f3d93 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -324,8 +324,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 	if (ret)
 		goto err_g1;
 
-	pci_set_master(pdev);
-
 	dev->pdev = pdev;
 	dev->dev = &pdev->dev;
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index d7ae29d..5737bc5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -46,39 +46,13 @@ struct exynos_drm_fbdev {
 	struct exynos_drm_gem_obj	*exynos_gem_obj;
 };
 
-static int exynos_drm_fbdev_set_par(struct fb_info *info)
-{
-	struct fb_var_screeninfo *var = &info->var;
-
-	switch (var->bits_per_pixel) {
-	case 32:
-	case 24:
-	case 18:
-	case 16:
-	case 12:
-		info->fix.visual = FB_VISUAL_TRUECOLOR;
-		break;
-	case 1:
-		info->fix.visual = FB_VISUAL_MONO01;
-		break;
-	default:
-		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-		break;
-	}
-
-	info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
-
-	return drm_fb_helper_set_par(info);
-}
-
-
 static struct fb_ops exynos_drm_fb_ops = {
 	.owner		= THIS_MODULE,
 	.fb_fillrect	= cfb_fillrect,
 	.fb_copyarea	= cfb_copyarea,
 	.fb_imageblit	= cfb_imageblit,
 	.fb_check_var	= drm_fb_helper_check_var,
-	.fb_set_par	= exynos_drm_fbdev_set_par,
+	.fb_set_par	= drm_fb_helper_set_par,
 	.fb_blank	= drm_fb_helper_blank,
 	.fb_pan_display	= drm_fb_helper_pan_display,
 	.fb_setcmap	= drm_fb_helper_setcmap,
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 830dfdd6b..c1c4dc1 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -507,11 +507,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
 	info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
 
-	info->pixmap.size = 64 * 1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
+	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
 	dev_info(dev->dev, "allocated %dx%d fb\n",
 					psbfb->base.width, psbfb->base.height);
@@ -725,10 +721,7 @@ static int psb_create_backlight_property(struct drm_device *dev)
 	if (dev_priv->backlight_property)
 		return 0;
 
-	backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
-							"backlight", 2);
-	backlight->values[0] = 0;
-	backlight->values[1] = 100;
+	backlight = drm_property_create_range(dev, 0, "backlight", 0, 100);
 
 	dev_priv->backlight_property = backlight;
 
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c
index 147584a..9db9052 100644
--- a/drivers/gpu/drm/gma500/intel_gmbus.c
+++ b/drivers/gpu/drm/gma500/intel_gmbus.c
@@ -395,7 +395,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev)
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	int ret, i;
 
-	dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS,
+	dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus),
 				  GFP_KERNEL);
 	if (dev_priv->gmbus == NULL)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c
index c904d73..e80ee82 100644
--- a/drivers/gpu/drm/gma500/mmu.c
+++ b/drivers/gpu/drm/gma500/mmu.c
@@ -125,14 +125,14 @@ static void psb_page_clflush(struct psb_mmu_driver *driver, struct page* page)
 	int i;
 	uint8_t *clf;
 
-	clf = kmap_atomic(page, KM_USER0);
+	clf = kmap_atomic(page);
 	mb();
 	for (i = 0; i < clflush_count; ++i) {
 		psb_clflush(clf);
 		clf += clflush_add;
 	}
 	mb();
-	kunmap_atomic(clf, KM_USER0);
+	kunmap_atomic(clf);
 }
 
 static void psb_pages_clflush(struct psb_mmu_driver *driver,
@@ -325,7 +325,7 @@ static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
 
 	spin_lock(lock);
 
-	v = kmap_atomic(pt->p, KM_USER0);
+	v = kmap_atomic(pt->p);
 	clf = (uint8_t *) v;
 	ptes = (uint32_t *) v;
 	for (i = 0; i < (PAGE_SIZE / sizeof(uint32_t)); ++i)
@@ -341,7 +341,7 @@ static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd)
 		mb();
 	}
 
-	kunmap_atomic(v, KM_USER0);
+	kunmap_atomic(v);
 	spin_unlock(lock);
 
 	pt->count = 0;
@@ -376,18 +376,18 @@ struct psb_mmu_pt *psb_mmu_pt_alloc_map_lock(struct psb_mmu_pd *pd,
 			continue;
 		}
 
-		v = kmap_atomic(pd->p, KM_USER0);
+		v = kmap_atomic(pd->p);
 		pd->tables[index] = pt;
 		v[index] = (page_to_pfn(pt->p) << 12) | pd->pd_mask;
 		pt->index = index;
-		kunmap_atomic((void *) v, KM_USER0);
+		kunmap_atomic((void *) v);
 
 		if (pd->hw_context != -1) {
 			psb_mmu_clflush(pd->driver, (void *) &v[index]);
 			atomic_set(&pd->driver->needs_tlbflush, 1);
 		}
 	}
-	pt->v = kmap_atomic(pt->p, KM_USER0);
+	pt->v = kmap_atomic(pt->p);
 	return pt;
 }
 
@@ -404,7 +404,7 @@ static struct psb_mmu_pt *psb_mmu_pt_map_lock(struct psb_mmu_pd *pd,
 		spin_unlock(lock);
 		return NULL;
 	}
-	pt->v = kmap_atomic(pt->p, KM_USER0);
+	pt->v = kmap_atomic(pt->p);
 	return pt;
 }
 
@@ -413,9 +413,9 @@ static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
 	struct psb_mmu_pd *pd = pt->pd;
 	uint32_t *v;
 
-	kunmap_atomic(pt->v, KM_USER0);
+	kunmap_atomic(pt->v);
 	if (pt->count == 0) {
-		v = kmap_atomic(pd->p, KM_USER0);
+		v = kmap_atomic(pd->p);
 		v[pt->index] = pd->invalid_pde;
 		pd->tables[pt->index] = NULL;
 
@@ -424,7 +424,7 @@ static void psb_mmu_pt_unmap_unlock(struct psb_mmu_pt *pt)
 					(void *) &v[pt->index]);
 			atomic_set(&pd->driver->needs_tlbflush, 1);
 		}
-		kunmap_atomic(pt->v, KM_USER0);
+		kunmap_atomic(pt->v);
 		spin_unlock(&pd->driver->lock);
 		psb_mmu_free_pt(pt);
 		return;
@@ -457,7 +457,7 @@ void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
 	down_read(&driver->sem);
 	spin_lock(&driver->lock);
 
-	v = kmap_atomic(pd->p, KM_USER0);
+	v = kmap_atomic(pd->p);
 	v += start;
 
 	while (gtt_pages--) {
@@ -467,7 +467,7 @@ void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
 
 	/*ttm_tt_cache_flush(&pd->p, num_pages);*/
 	psb_pages_clflush(pd->driver, &pd->p, num_pages);
-	kunmap_atomic(v, KM_USER0);
+	kunmap_atomic(v);
 	spin_unlock(&driver->lock);
 
 	if (pd->hw_context != -1)
@@ -830,9 +830,9 @@ int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
 		uint32_t *v;
 
 		spin_lock(lock);
-		v = kmap_atomic(pd->p, KM_USER0);
+		v = kmap_atomic(pd->p);
 		tmp = v[psb_mmu_pd_index(virtual)];
-		kunmap_atomic(v, KM_USER0);
+		kunmap_atomic(v);
 		spin_unlock(lock);
 
 		if (tmp != pd->invalid_pde || !(tmp & PSB_PTE_VALID) ||
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index f14768f..1f57aac 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -283,6 +283,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
 	dev_priv->dev = dev;
 	dev->dev_private = (void *) dev_priv;
 
+	pci_set_master(dev->pdev);
+
 	if (!IS_PSB(dev)) {
 		if (pci_enable_msi(dev->pdev))
 			dev_warn(dev->dev, "Enabling MSI failed!\n");
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index a25e4ca..0a43758 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -713,7 +713,6 @@ void psb_intel_lvds_init(struct drm_device *dev,
 
 	psb_intel_encoder =
 			kzalloc(sizeof(struct psb_intel_encoder), GFP_KERNEL);
-
 	if (!psb_intel_encoder) {
 		dev_err(dev->dev, "psb_intel_encoder allocation error\n");
 		return;
@@ -721,10 +720,9 @@ void psb_intel_lvds_init(struct drm_device *dev,
 
 	psb_intel_connector =
 		kzalloc(sizeof(struct psb_intel_connector), GFP_KERNEL);
-
 	if (!psb_intel_connector) {
-		kfree(psb_intel_encoder);
 		dev_err(dev->dev, "psb_intel_connector allocation error\n");
+		goto failed_encoder;
 	}
 
 	lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
@@ -862,7 +860,8 @@ failed_blc_i2c:
 	drm_encoder_cleanup(encoder);
 	drm_connector_cleanup(connector);
 failed_connector:
-	if (psb_intel_connector)
-		kfree(psb_intel_connector);
+	kfree(psb_intel_connector);
+failed_encoder:
+	kfree(psb_intel_encoder);
 }
 
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index 88b4297..41b55d7 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -2312,10 +2312,8 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s
 		psb_intel_sdvo_connector->max_##name = data_value[0]; \
 		psb_intel_sdvo_connector->cur_##name = response; \
 		psb_intel_sdvo_connector->name = \
-			drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \
+			drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
 		if (!psb_intel_sdvo_connector->name) return false; \
-		psb_intel_sdvo_connector->name->values[0] = 0; \
-		psb_intel_sdvo_connector->name->values[1] = data_value[0]; \
 		drm_connector_attach_property(connector, \
 					      psb_intel_sdvo_connector->name, \
 					      psb_intel_sdvo_connector->cur_##name); \
@@ -2349,25 +2347,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
 		psb_intel_sdvo_connector->left_margin = data_value[0] - response;
 		psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin;
 		psb_intel_sdvo_connector->left =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "left_margin", 2);
+			drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]);
 		if (!psb_intel_sdvo_connector->left)
 			return false;
 
-		psb_intel_sdvo_connector->left->values[0] = 0;
-		psb_intel_sdvo_connector->left->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      psb_intel_sdvo_connector->left,
 					      psb_intel_sdvo_connector->left_margin);
 
 		psb_intel_sdvo_connector->right =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "right_margin", 2);
+			drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]);
 		if (!psb_intel_sdvo_connector->right)
 			return false;
 
-		psb_intel_sdvo_connector->right->values[0] = 0;
-		psb_intel_sdvo_connector->right->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      psb_intel_sdvo_connector->right,
 					      psb_intel_sdvo_connector->right_margin);
@@ -2391,25 +2383,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
 		psb_intel_sdvo_connector->top_margin = data_value[0] - response;
 		psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin;
 		psb_intel_sdvo_connector->top =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "top_margin", 2);
+			drm_property_create_range(dev, 0, "top_margin", 0, data_value[0]);
 		if (!psb_intel_sdvo_connector->top)
 			return false;
 
-		psb_intel_sdvo_connector->top->values[0] = 0;
-		psb_intel_sdvo_connector->top->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      psb_intel_sdvo_connector->top,
 					      psb_intel_sdvo_connector->top_margin);
 
 		psb_intel_sdvo_connector->bottom =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "bottom_margin", 2);
+			drm_property_create_range(dev, 0, "bottom_margin", 0, data_value[0]);
 		if (!psb_intel_sdvo_connector->bottom)
 			return false;
 
-		psb_intel_sdvo_connector->bottom->values[0] = 0;
-		psb_intel_sdvo_connector->bottom->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      psb_intel_sdvo_connector->bottom,
 					      psb_intel_sdvo_connector->bottom_margin);
@@ -2438,12 +2424,10 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
 		psb_intel_sdvo_connector->max_dot_crawl = 1;
 		psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1;
 		psb_intel_sdvo_connector->dot_crawl =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2);
+			drm_property_create_range(dev, 0, "dot_crawl", 0, 1);
 		if (!psb_intel_sdvo_connector->dot_crawl)
 			return false;
 
-		psb_intel_sdvo_connector->dot_crawl->values[0] = 0;
-		psb_intel_sdvo_connector->dot_crawl->values[1] = 1;
 		drm_connector_attach_property(connector,
 					      psb_intel_sdvo_connector->dot_crawl,
 					      psb_intel_sdvo_connector->cur_dot_crawl);
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
index 07d55df..d3f2e87 100644
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
@@ -252,10 +252,7 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder,
 
 	drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
 
-	priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE,
-						   "scale", 2);
-	priv->scale_property->values[0] = 0;
-	priv->scale_property->values[1] = 2;
+	priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2);
 
 	drm_connector_attach_property(connector, conf->tv_select_subconnector_property,
 				      priv->select_subconnector);
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index 7f4b4e1..64a989e 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -1208,6 +1208,8 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags)
 	dev->types[8] = _DRM_STAT_SECONDARY;
 	dev->types[9] = _DRM_STAT_DMA;
 
+	pci_set_master(dev->pdev);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 808b255..ce7fc77 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -3,7 +3,7 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 ccflags-y := -Iinclude/drm
-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
+i915-y := i915_drv.o i915_dma.o i915_irq.o \
 	  i915_debugfs.o \
           i915_suspend.o \
 	  i915_gem.o \
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index deaa657..11ae06a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -83,6 +83,7 @@ static int i915_capabilities(struct seq_file *m, void *data)
 	B(supports_tv);
 	B(has_bsd_ring);
 	B(has_blt_ring);
+	B(has_llc);
 #undef B
 
 	return 0;
@@ -563,45 +564,6 @@ static int i915_hws_info(struct seq_file *m, void *data)
 	return 0;
 }
 
-static void i915_dump_object(struct seq_file *m,
-			     struct io_mapping *mapping,
-			     struct drm_i915_gem_object *obj)
-{
-	int page, page_count, i;
-
-	page_count = obj->base.size / PAGE_SIZE;
-	for (page = 0; page < page_count; page++) {
-		u32 *mem = io_mapping_map_wc(mapping,
-					     obj->gtt_offset + page * PAGE_SIZE);
-		for (i = 0; i < PAGE_SIZE; i += 4)
-			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
-		io_mapping_unmap(mem);
-	}
-}
-
-static int i915_batchbuffer_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj;
-	int ret;
-
-	ret = mutex_lock_interruptible(&dev->struct_mutex);
-	if (ret)
-		return ret;
-
-	list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) {
-		if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) {
-		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset);
-		    i915_dump_object(m, dev_priv->mm.gtt_mapping, obj);
-		}
-	}
-
-	mutex_unlock(&dev->struct_mutex);
-	return 0;
-}
-
 static int i915_ringbuffer_data(struct seq_file *m, void *data)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -668,9 +630,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data)
 static const char *ring_str(int ring)
 {
 	switch (ring) {
-	case RING_RENDER: return " render";
-	case RING_BSD: return " bsd";
-	case RING_BLT: return " blt";
+	case RCS: return "render";
+	case VCS: return "bsd";
+	case BCS: return "blt";
 	default: return "";
 	}
 }
@@ -713,7 +675,7 @@ static void print_error_buffers(struct seq_file *m,
 	seq_printf(m, "%s [%d]:\n", name, count);
 
 	while (count--) {
-		seq_printf(m, "  %08x %8u %04x %04x %08x%s%s%s%s%s%s",
+		seq_printf(m, "  %08x %8u %04x %04x %08x%s%s%s%s%s%s%s",
 			   err->gtt_offset,
 			   err->size,
 			   err->read_domains,
@@ -723,6 +685,7 @@ static void print_error_buffers(struct seq_file *m,
 			   tiling_flag(err->tiling),
 			   dirty_flag(err->dirty),
 			   purgeable_flag(err->purgeable),
+			   err->ring != -1 ? " " : "",
 			   ring_str(err->ring),
 			   cache_level_str(err->cache_level));
 
@@ -736,6 +699,32 @@ static void print_error_buffers(struct seq_file *m,
 	}
 }
 
+static void i915_ring_error_state(struct seq_file *m,
+				  struct drm_device *dev,
+				  struct drm_i915_error_state *error,
+				  unsigned ring)
+{
+	seq_printf(m, "%s command stream:\n", ring_str(ring));
+	seq_printf(m, "  HEAD: 0x%08x\n", error->head[ring]);
+	seq_printf(m, "  TAIL: 0x%08x\n", error->tail[ring]);
+	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd[ring]);
+	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir[ring]);
+	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr[ring]);
+	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone[ring]);
+	if (ring == RCS && INTEL_INFO(dev)->gen >= 4) {
+		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
+		seq_printf(m, "  BBADDR: 0x%08llx\n", error->bbaddr);
+	}
+	if (INTEL_INFO(dev)->gen >= 4)
+		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps[ring]);
+	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm[ring]);
+	if (INTEL_INFO(dev)->gen >= 6) {
+		seq_printf(m, "  FADDR: 0x%08x\n", error->faddr[ring]);
+		seq_printf(m, "  FAULT_REG: 0x%08x\n", error->fault_reg[ring]);
+	}
+	seq_printf(m, "  seqno: 0x%08x\n", error->seqno[ring]);
+}
+
 static int i915_error_state(struct seq_file *m, void *unused)
 {
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
@@ -758,35 +747,20 @@ static int i915_error_state(struct seq_file *m, void *unused)
 	seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device);
 	seq_printf(m, "EIR: 0x%08x\n", error->eir);
 	seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+
+	for (i = 0; i < dev_priv->num_fence_regs; i++)
+		seq_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
+
 	if (INTEL_INFO(dev)->gen >= 6) {
 		seq_printf(m, "ERROR: 0x%08x\n", error->error);
-		seq_printf(m, "Blitter command stream:\n");
-		seq_printf(m, "  ACTHD:    0x%08x\n", error->bcs_acthd);
-		seq_printf(m, "  IPEIR:    0x%08x\n", error->bcs_ipeir);
-		seq_printf(m, "  IPEHR:    0x%08x\n", error->bcs_ipehr);
-		seq_printf(m, "  INSTDONE: 0x%08x\n", error->bcs_instdone);
-		seq_printf(m, "  seqno:    0x%08x\n", error->bcs_seqno);
-		seq_printf(m, "Video (BSD) command stream:\n");
-		seq_printf(m, "  ACTHD:    0x%08x\n", error->vcs_acthd);
-		seq_printf(m, "  IPEIR:    0x%08x\n", error->vcs_ipeir);
-		seq_printf(m, "  IPEHR:    0x%08x\n", error->vcs_ipehr);
-		seq_printf(m, "  INSTDONE: 0x%08x\n", error->vcs_instdone);
-		seq_printf(m, "  seqno:    0x%08x\n", error->vcs_seqno);
+		seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg);
 	}
-	seq_printf(m, "Render command stream:\n");
-	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd);
-	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir);
-	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr);
-	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone);
-	if (INTEL_INFO(dev)->gen >= 4) {
-		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
-		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
-	}
-	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
-	seq_printf(m, "  seqno: 0x%08x\n", error->seqno);
 
-	for (i = 0; i < dev_priv->num_fence_regs; i++)
-		seq_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
+	i915_ring_error_state(m, dev, error, RCS);
+	if (HAS_BLT(dev))
+		i915_ring_error_state(m, dev, error, BCS);
+	if (HAS_BSD(dev))
+		i915_ring_error_state(m, dev, error, VCS);
 
 	if (error->active_bo)
 		print_error_buffers(m, "Active",
@@ -1414,9 +1388,58 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
 	return 0;
 }
 
+static const char *swizzle_string(unsigned swizzle)
+{
+	switch(swizzle) {
+	case I915_BIT_6_SWIZZLE_NONE:
+		return "none";
+	case I915_BIT_6_SWIZZLE_9:
+		return "bit9";
+	case I915_BIT_6_SWIZZLE_9_10:
+		return "bit9/bit10";
+	case I915_BIT_6_SWIZZLE_9_11:
+		return "bit9/bit11";
+	case I915_BIT_6_SWIZZLE_9_10_11:
+		return "bit9/bit10/bit11";
+	case I915_BIT_6_SWIZZLE_9_17:
+		return "bit9/bit17";
+	case I915_BIT_6_SWIZZLE_9_10_17:
+		return "bit9/bit10/bit17";
+	case I915_BIT_6_SWIZZLE_UNKNOWN:
+		return "unkown";
+	}
+
+	return "bug";
+}
+
+static int i915_swizzle_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	mutex_lock(&dev->struct_mutex);
+	seq_printf(m, "bit6 swizzle for X-tiling = %s\n",
+		   swizzle_string(dev_priv->mm.bit_6_swizzle_x));
+	seq_printf(m, "bit6 swizzle for Y-tiling = %s\n",
+		   swizzle_string(dev_priv->mm.bit_6_swizzle_y));
+
+	if (IS_GEN3(dev) || IS_GEN4(dev)) {
+		seq_printf(m, "DDC = 0x%08x\n",
+			   I915_READ(DCC));
+		seq_printf(m, "C0DRB3 = 0x%04x\n",
+			   I915_READ16(C0DRB3));
+		seq_printf(m, "C1DRB3 = 0x%04x\n",
+			   I915_READ16(C1DRB3));
+	}
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
 static int
-i915_wedged_open(struct inode *inode,
-		 struct file *filp)
+i915_debugfs_common_open(struct inode *inode,
+			 struct file *filp)
 {
 	filp->private_data = inode->i_private;
 	return 0;
@@ -1472,20 +1495,12 @@ i915_wedged_write(struct file *filp,
 
 static const struct file_operations i915_wedged_fops = {
 	.owner = THIS_MODULE,
-	.open = i915_wedged_open,
+	.open = i915_debugfs_common_open,
 	.read = i915_wedged_read,
 	.write = i915_wedged_write,
 	.llseek = default_llseek,
 };
 
-static int
-i915_max_freq_open(struct inode *inode,
-		   struct file *filp)
-{
-	filp->private_data = inode->i_private;
-	return 0;
-}
-
 static ssize_t
 i915_max_freq_read(struct file *filp,
 		   char __user *ubuf,
@@ -1542,20 +1557,12 @@ i915_max_freq_write(struct file *filp,
 
 static const struct file_operations i915_max_freq_fops = {
 	.owner = THIS_MODULE,
-	.open = i915_max_freq_open,
+	.open = i915_debugfs_common_open,
 	.read = i915_max_freq_read,
 	.write = i915_max_freq_write,
 	.llseek = default_llseek,
 };
 
-static int
-i915_cache_sharing_open(struct inode *inode,
-		   struct file *filp)
-{
-	filp->private_data = inode->i_private;
-	return 0;
-}
-
 static ssize_t
 i915_cache_sharing_read(struct file *filp,
 		   char __user *ubuf,
@@ -1621,7 +1628,7 @@ i915_cache_sharing_write(struct file *filp,
 
 static const struct file_operations i915_cache_sharing_fops = {
 	.owner = THIS_MODULE,
-	.open = i915_cache_sharing_open,
+	.open = i915_debugfs_common_open,
 	.read = i915_cache_sharing_read,
 	.write = i915_cache_sharing_write,
 	.llseek = default_llseek,
@@ -1653,21 +1660,6 @@ drm_add_fake_info_node(struct drm_minor *minor,
 	return 0;
 }
 
-static int i915_wedged_create(struct dentry *root, struct drm_minor *minor)
-{
-	struct drm_device *dev = minor->dev;
-	struct dentry *ent;
-
-	ent = debugfs_create_file("i915_wedged",
-				  S_IRUGO | S_IWUSR,
-				  root, dev,
-				  &i915_wedged_fops);
-	if (IS_ERR(ent))
-		return PTR_ERR(ent);
-
-	return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
-}
-
 static int i915_forcewake_open(struct inode *inode, struct file *file)
 {
 	struct drm_device *dev = inode->i_private;
@@ -1729,34 +1721,22 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
 	return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops);
 }
 
-static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor)
-{
-	struct drm_device *dev = minor->dev;
-	struct dentry *ent;
-
-	ent = debugfs_create_file("i915_max_freq",
-				  S_IRUGO | S_IWUSR,
-				  root, dev,
-				  &i915_max_freq_fops);
-	if (IS_ERR(ent))
-		return PTR_ERR(ent);
-
-	return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops);
-}
-
-static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor)
+static int i915_debugfs_create(struct dentry *root,
+			       struct drm_minor *minor,
+			       const char *name,
+			       const struct file_operations *fops)
 {
 	struct drm_device *dev = minor->dev;
 	struct dentry *ent;
 
-	ent = debugfs_create_file("i915_cache_sharing",
+	ent = debugfs_create_file(name,
 				  S_IRUGO | S_IWUSR,
 				  root, dev,
-				  &i915_cache_sharing_fops);
+				  fops);
 	if (IS_ERR(ent))
 		return PTR_ERR(ent);
 
-	return drm_add_fake_info_node(minor, ent, &i915_cache_sharing_fops);
+	return drm_add_fake_info_node(minor, ent, fops);
 }
 
 static struct drm_info_list i915_debugfs_list[] = {
@@ -1782,7 +1762,6 @@ static struct drm_info_list i915_debugfs_list[] = {
 	{"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS},
 	{"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS},
 	{"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS},
-	{"i915_batchbuffers", i915_batchbuffer_info, 0},
 	{"i915_error_state", i915_error_state, 0},
 	{"i915_rstdby_delays", i915_rstdby_delays, 0},
 	{"i915_cur_delayinfo", i915_cur_delayinfo, 0},
@@ -1798,6 +1777,7 @@ static struct drm_info_list i915_debugfs_list[] = {
 	{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
 	{"i915_context_status", i915_context_status, 0},
 	{"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
+	{"i915_swizzle_info", i915_swizzle_info, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
@@ -1805,17 +1785,25 @@ int i915_debugfs_init(struct drm_minor *minor)
 {
 	int ret;
 
-	ret = i915_wedged_create(minor->debugfs_root, minor);
+	ret = i915_debugfs_create(minor->debugfs_root, minor,
+				  "i915_wedged",
+				  &i915_wedged_fops);
 	if (ret)
 		return ret;
 
 	ret = i915_forcewake_create(minor->debugfs_root, minor);
 	if (ret)
 		return ret;
-	ret = i915_max_freq_create(minor->debugfs_root, minor);
+
+	ret = i915_debugfs_create(minor->debugfs_root, minor,
+				  "i915_max_freq",
+				  &i915_max_freq_fops);
 	if (ret)
 		return ret;
-	ret = i915_cache_sharing_create(minor->debugfs_root, minor);
+
+	ret = i915_debugfs_create(minor->debugfs_root, minor,
+				  "i915_cache_sharing",
+				  &i915_cache_sharing_fops);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index ddfe3d9..a8081f2 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -784,6 +784,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
 	case I915_PARAM_HAS_GEN7_SOL_RESET:
 		value = 1;
 		break;
+	case I915_PARAM_HAS_LLC:
+		value = HAS_LLC(dev);
+		break;
 	default:
 		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
 				 param->param);
@@ -1930,6 +1933,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 		goto free_priv;
 	}
 
+	pci_set_master(dev->pdev);
+
 	/* overlay on gen2 is broken and can't address above 1G */
 	if (IS_GEN2(dev))
 		dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
@@ -2129,7 +2134,7 @@ int i915_driver_unload(struct drm_device *dev)
 		unregister_shrinker(&dev_priv->mm.inactive_shrinker);
 
 	mutex_lock(&dev->struct_mutex);
-	ret = i915_gpu_idle(dev);
+	ret = i915_gpu_idle(dev, true);
 	if (ret)
 		DRM_ERROR("failed to idle hardware: %d\n", ret);
 	mutex_unlock(&dev->struct_mutex);
@@ -2247,18 +2252,12 @@ void i915_driver_lastclose(struct drm_device * dev)
 
 	i915_gem_lastclose(dev);
 
-	if (dev_priv->agp_heap)
-		i915_mem_takedown(&(dev_priv->agp_heap));
-
 	i915_dma_cleanup(dev);
 }
 
 void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
 {
-	drm_i915_private_t *dev_priv = dev->dev_private;
 	i915_gem_release(dev, file_priv);
-	if (!drm_core_check_feature(dev, DRIVER_MODESET))
-		i915_mem_release(dev, file_priv, dev_priv->agp_heap);
 }
 
 void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
@@ -2277,11 +2276,11 @@ struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
 	DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH),
 	DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH),
-	DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH),
-	DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
-	DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP,  i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP,  drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE,  i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE,  i915_vblank_pipe_get, DRM_AUTH),
 	DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 308f819..3d92d82 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -198,7 +198,7 @@ static const struct intel_device_info intel_pineview_info = {
 
 static const struct intel_device_info intel_ironlake_d_info = {
 	.gen = 5,
-	.need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
+	.need_gfx_hws = 1, .has_hotplug = 1,
 	.has_bsd_ring = 1,
 };
 
@@ -214,6 +214,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
 	.need_gfx_hws = 1, .has_hotplug = 1,
 	.has_bsd_ring = 1,
 	.has_blt_ring = 1,
+	.has_llc = 1,
 };
 
 static const struct intel_device_info intel_sandybridge_m_info = {
@@ -222,6 +223,7 @@ static const struct intel_device_info intel_sandybridge_m_info = {
 	.has_fbc = 1,
 	.has_bsd_ring = 1,
 	.has_blt_ring = 1,
+	.has_llc = 1,
 };
 
 static const struct intel_device_info intel_ivybridge_d_info = {
@@ -229,6 +231,7 @@ static const struct intel_device_info intel_ivybridge_d_info = {
 	.need_gfx_hws = 1, .has_hotplug = 1,
 	.has_bsd_ring = 1,
 	.has_blt_ring = 1,
+	.has_llc = 1,
 };
 
 static const struct intel_device_info intel_ivybridge_m_info = {
@@ -237,6 +240,7 @@ static const struct intel_device_info intel_ivybridge_m_info = {
 	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
 	.has_bsd_ring = 1,
 	.has_blt_ring = 1,
+	.has_llc = 1,
 };
 
 static const struct pci_device_id pciidlist[] = {		/* aka */
@@ -633,7 +637,7 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags)
 }
 
 /**
- * i965_reset - reset chip after a hang
+ * i915_reset - reset chip after a hang
  * @dev: drm device to reset
  * @flags: reset domains
  *
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9689ca3..68a5338 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -135,6 +135,7 @@ struct drm_i915_fence_reg {
 	struct list_head lru_list;
 	struct drm_i915_gem_object *obj;
 	uint32_t setup_seqno;
+	int pin_count;
 };
 
 struct sdvo_device_mapping {
@@ -152,26 +153,21 @@ struct drm_i915_error_state {
 	u32 eir;
 	u32 pgtbl_er;
 	u32 pipestat[I915_MAX_PIPES];
-	u32 ipeir;
-	u32 ipehr;
-	u32 instdone;
-	u32 acthd;
+	u32 tail[I915_NUM_RINGS];
+	u32 head[I915_NUM_RINGS];
+	u32 ipeir[I915_NUM_RINGS];
+	u32 ipehr[I915_NUM_RINGS];
+	u32 instdone[I915_NUM_RINGS];
+	u32 acthd[I915_NUM_RINGS];
 	u32 error; /* gen6+ */
-	u32 bcs_acthd; /* gen6+ blt engine */
-	u32 bcs_ipehr;
-	u32 bcs_ipeir;
-	u32 bcs_instdone;
-	u32 bcs_seqno;
-	u32 vcs_acthd; /* gen6+ bsd engine */
-	u32 vcs_ipehr;
-	u32 vcs_ipeir;
-	u32 vcs_instdone;
-	u32 vcs_seqno;
-	u32 instpm;
-	u32 instps;
+	u32 instpm[I915_NUM_RINGS];
+	u32 instps[I915_NUM_RINGS];
 	u32 instdone1;
-	u32 seqno;
+	u32 seqno[I915_NUM_RINGS];
 	u64 bbaddr;
+	u32 fault_reg[I915_NUM_RINGS];
+	u32 done_reg;
+	u32 faddr[I915_NUM_RINGS];
 	u64 fence[I915_MAX_NUM_FENCES];
 	struct timeval time;
 	struct drm_i915_error_object {
@@ -255,6 +251,7 @@ struct intel_device_info {
 	u8 supports_tv:1;
 	u8 has_bsd_ring:1;
 	u8 has_blt_ring:1;
+	u8 has_llc:1;
 };
 
 enum no_fbc_reason {
@@ -335,7 +332,6 @@ typedef struct drm_i915_private {
 
 	int tex_lru_log_granularity;
 	int allow_batchbuffer;
-	struct mem_block *agp_heap;
 	unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
 	int vblank_pipe;
 	int num_pipe;
@@ -974,6 +970,7 @@ struct drm_i915_file_private {
 
 #define HAS_BSD(dev)            (INTEL_INFO(dev)->has_bsd_ring)
 #define HAS_BLT(dev)            (INTEL_INFO(dev)->has_blt_ring)
+#define HAS_LLC(dev)            (INTEL_INFO(dev)->has_llc)
 #define I915_NEED_GFX_HWS(dev)	(INTEL_INFO(dev)->need_gfx_hws)
 
 #define HAS_OVERLAY(dev)		(INTEL_INFO(dev)->has_overlay)
@@ -1079,18 +1076,6 @@ extern void i915_destroy_error_state(struct drm_device *dev);
 #endif
 
 
-/* i915_mem.c */
-extern int i915_mem_alloc(struct drm_device *dev, void *data,
-			  struct drm_file *file_priv);
-extern int i915_mem_free(struct drm_device *dev, void *data,
-			 struct drm_file *file_priv);
-extern int i915_mem_init_heap(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
-extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
-				 struct drm_file *file_priv);
-extern void i915_mem_takedown(struct mem_block **heap);
-extern void i915_mem_release(struct drm_device * dev,
-			     struct drm_file *file_priv, struct mem_block *heap);
 /* i915_gem.c */
 int i915_gem_init_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
@@ -1181,6 +1166,24 @@ int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
 					   struct intel_ring_buffer *pipelined);
 int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj);
 
+static inline void
+i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
+{
+	if (obj->fence_reg != I915_FENCE_REG_NONE) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+		dev_priv->fence_regs[obj->fence_reg].pin_count++;
+	}
+}
+
+static inline void
+i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
+{
+	if (obj->fence_reg != I915_FENCE_REG_NONE) {
+		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+		dev_priv->fence_regs[obj->fence_reg].pin_count--;
+	}
+}
+
 void i915_gem_retire_requests(struct drm_device *dev);
 void i915_gem_reset(struct drm_device *dev);
 void i915_gem_clflush_object(struct drm_i915_gem_object *obj);
@@ -1194,13 +1197,14 @@ void i915_gem_do_init(struct drm_device *dev,
 		      unsigned long start,
 		      unsigned long mappable_end,
 		      unsigned long end);
-int __must_check i915_gpu_idle(struct drm_device *dev);
+int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire);
 int __must_check i915_gem_idle(struct drm_device *dev);
 int __must_check i915_add_request(struct intel_ring_buffer *ring,
 				  struct drm_file *file,
 				  struct drm_i915_gem_request *request);
 int __must_check i915_wait_request(struct intel_ring_buffer *ring,
-				   uint32_t seqno);
+				   uint32_t seqno,
+				   bool do_retire);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int __must_check
 i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e55badb..51a2b0c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -58,6 +58,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj);
 
 static int i915_gem_inactive_shrink(struct shrinker *shrinker,
 				    struct shrink_control *sc);
+static void i915_gem_object_truncate(struct drm_i915_gem_object *obj);
 
 /* some bookkeeping */
 static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv,
@@ -258,73 +259,6 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
 		obj->tiling_mode != I915_TILING_NONE;
 }
 
-static inline void
-slow_shmem_copy(struct page *dst_page,
-		int dst_offset,
-		struct page *src_page,
-		int src_offset,
-		int length)
-{
-	char *dst_vaddr, *src_vaddr;
-
-	dst_vaddr = kmap(dst_page);
-	src_vaddr = kmap(src_page);
-
-	memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length);
-
-	kunmap(src_page);
-	kunmap(dst_page);
-}
-
-static inline void
-slow_shmem_bit17_copy(struct page *gpu_page,
-		      int gpu_offset,
-		      struct page *cpu_page,
-		      int cpu_offset,
-		      int length,
-		      int is_read)
-{
-	char *gpu_vaddr, *cpu_vaddr;
-
-	/* Use the unswizzled path if this page isn't affected. */
-	if ((page_to_phys(gpu_page) & (1 << 17)) == 0) {
-		if (is_read)
-			return slow_shmem_copy(cpu_page, cpu_offset,
-					       gpu_page, gpu_offset, length);
-		else
-			return slow_shmem_copy(gpu_page, gpu_offset,
-					       cpu_page, cpu_offset, length);
-	}
-
-	gpu_vaddr = kmap(gpu_page);
-	cpu_vaddr = kmap(cpu_page);
-
-	/* Copy the data, XORing A6 with A17 (1). The user already knows he's
-	 * XORing with the other bits (A9 for Y, A9 and A10 for X)
-	 */
-	while (length > 0) {
-		int cacheline_end = ALIGN(gpu_offset + 1, 64);
-		int this_length = min(cacheline_end - gpu_offset, length);
-		int swizzled_gpu_offset = gpu_offset ^ 64;
-
-		if (is_read) {
-			memcpy(cpu_vaddr + cpu_offset,
-			       gpu_vaddr + swizzled_gpu_offset,
-			       this_length);
-		} else {
-			memcpy(gpu_vaddr + swizzled_gpu_offset,
-			       cpu_vaddr + cpu_offset,
-			       this_length);
-		}
-		cpu_offset += this_length;
-		gpu_offset += this_length;
-		length -= this_length;
-	}
-
-	kunmap(cpu_page);
-	kunmap(gpu_page);
-}
-
 /**
  * This is the fast shmem pread path, which attempts to copy_from_user directly
  * from the backing pages of the object to the user's address space.  On a
@@ -385,6 +319,58 @@ i915_gem_shmem_pread_fast(struct drm_device *dev,
 	return 0;
 }
 
+static inline int
+__copy_to_user_swizzled(char __user *cpu_vaddr,
+			const char *gpu_vaddr, int gpu_offset,
+			int length)
+{
+	int ret, cpu_offset = 0;
+
+	while (length > 0) {
+		int cacheline_end = ALIGN(gpu_offset + 1, 64);
+		int this_length = min(cacheline_end - gpu_offset, length);
+		int swizzled_gpu_offset = gpu_offset ^ 64;
+
+		ret = __copy_to_user(cpu_vaddr + cpu_offset,
+				     gpu_vaddr + swizzled_gpu_offset,
+				     this_length);
+		if (ret)
+			return ret + length;
+
+		cpu_offset += this_length;
+		gpu_offset += this_length;
+		length -= this_length;
+	}
+
+	return 0;
+}
+
+static inline int
+__copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset,
+			  const char *cpu_vaddr,
+			  int length)
+{
+	int ret, cpu_offset = 0;
+
+	while (length > 0) {
+		int cacheline_end = ALIGN(gpu_offset + 1, 64);
+		int this_length = min(cacheline_end - gpu_offset, length);
+		int swizzled_gpu_offset = gpu_offset ^ 64;
+
+		ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset,
+				       cpu_vaddr + cpu_offset,
+				       this_length);
+		if (ret)
+			return ret + length;
+
+		cpu_offset += this_length;
+		gpu_offset += this_length;
+		length -= this_length;
+	}
+
+	return 0;
+}
+
 /**
  * This is the fallback shmem pread path, which allocates temporary storage
  * in kernel space to copy_to_user into outside of the struct_mutex, so we
@@ -398,72 +384,34 @@ i915_gem_shmem_pread_slow(struct drm_device *dev,
 			  struct drm_file *file)
 {
 	struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
-	struct mm_struct *mm = current->mm;
-	struct page **user_pages;
+	char __user *user_data;
 	ssize_t remain;
-	loff_t offset, pinned_pages, i;
-	loff_t first_data_page, last_data_page, num_pages;
-	int shmem_page_offset;
-	int data_page_index, data_page_offset;
-	int page_length;
-	int ret;
-	uint64_t data_ptr = args->data_ptr;
-	int do_bit17_swizzling;
+	loff_t offset;
+	int shmem_page_offset, page_length, ret;
+	int obj_do_bit17_swizzling, page_do_bit17_swizzling;
 
+	user_data = (char __user *) (uintptr_t) args->data_ptr;
 	remain = args->size;
 
-	/* Pin the user pages containing the data.  We can't fault while
-	 * holding the struct mutex, yet we want to hold it while
-	 * dereferencing the user data.
-	 */
-	first_data_page = data_ptr / PAGE_SIZE;
-	last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
-	num_pages = last_data_page - first_data_page + 1;
+	obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
 
-	user_pages = drm_malloc_ab(num_pages, sizeof(struct page *));
-	if (user_pages == NULL)
-		return -ENOMEM;
+	offset = args->offset;
 
 	mutex_unlock(&dev->struct_mutex);
-	down_read(&mm->mmap_sem);
-	pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
-				      num_pages, 1, 0, user_pages, NULL);
-	up_read(&mm->mmap_sem);
-	mutex_lock(&dev->struct_mutex);
-	if (pinned_pages < num_pages) {
-		ret = -EFAULT;
-		goto out;
-	}
-
-	ret = i915_gem_object_set_cpu_read_domain_range(obj,
-							args->offset,
-							args->size);
-	if (ret)
-		goto out;
-
-	do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
-
-	offset = args->offset;
 
 	while (remain > 0) {
 		struct page *page;
+		char *vaddr;
 
 		/* Operation in this page
 		 *
 		 * shmem_page_offset = offset within page in shmem file
-		 * data_page_index = page number in get_user_pages return
-		 * data_page_offset = offset with data_page_index page.
 		 * page_length = bytes to copy for this page
 		 */
 		shmem_page_offset = offset_in_page(offset);
-		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-		data_page_offset = offset_in_page(data_ptr);
-
 		page_length = remain;
 		if ((shmem_page_offset + page_length) > PAGE_SIZE)
 			page_length = PAGE_SIZE - shmem_page_offset;
-		if ((data_page_offset + page_length) > PAGE_SIZE)
-			page_length = PAGE_SIZE - data_page_offset;
 
 		page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
 		if (IS_ERR(page)) {
@@ -471,36 +419,38 @@ i915_gem_shmem_pread_slow(struct drm_device *dev,
 			goto out;
 		}
 
-		if (do_bit17_swizzling) {
-			slow_shmem_bit17_copy(page,
-					      shmem_page_offset,
-					      user_pages[data_page_index],
-					      data_page_offset,
-					      page_length,
-					      1);
-		} else {
-			slow_shmem_copy(user_pages[data_page_index],
-					data_page_offset,
-					page,
-					shmem_page_offset,
-					page_length);
-		}
+		page_do_bit17_swizzling = obj_do_bit17_swizzling &&
+			(page_to_phys(page) & (1 << 17)) != 0;
+
+		vaddr = kmap(page);
+		if (page_do_bit17_swizzling)
+			ret = __copy_to_user_swizzled(user_data,
+						      vaddr, shmem_page_offset,
+						      page_length);
+		else
+			ret = __copy_to_user(user_data,
+					     vaddr + shmem_page_offset,
+					     page_length);
+		kunmap(page);
 
 		mark_page_accessed(page);
 		page_cache_release(page);
 
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
 		remain -= page_length;
-		data_ptr += page_length;
+		user_data += page_length;
 		offset += page_length;
 	}
 
 out:
-	for (i = 0; i < pinned_pages; i++) {
-		SetPageDirty(user_pages[i]);
-		mark_page_accessed(user_pages[i]);
-		page_cache_release(user_pages[i]);
-	}
-	drm_free_large(user_pages);
+	mutex_lock(&dev->struct_mutex);
+	/* Fixup: Kill any reinstated backing storage pages */
+	if (obj->madv == __I915_MADV_PURGED)
+		i915_gem_object_truncate(obj);
 
 	return ret;
 }
@@ -841,71 +791,36 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev,
 			   struct drm_file *file)
 {
 	struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
-	struct mm_struct *mm = current->mm;
-	struct page **user_pages;
 	ssize_t remain;
-	loff_t offset, pinned_pages, i;
-	loff_t first_data_page, last_data_page, num_pages;
-	int shmem_page_offset;
-	int data_page_index,  data_page_offset;
-	int page_length;
-	int ret;
-	uint64_t data_ptr = args->data_ptr;
-	int do_bit17_swizzling;
+	loff_t offset;
+	char __user *user_data;
+	int shmem_page_offset, page_length, ret;
+	int obj_do_bit17_swizzling, page_do_bit17_swizzling;
 
+	user_data = (char __user *) (uintptr_t) args->data_ptr;
 	remain = args->size;
 
-	/* Pin the user pages containing the data.  We can't fault while
-	 * holding the struct mutex, and all of the pwrite implementations
-	 * want to hold it while dereferencing the user data.
-	 */
-	first_data_page = data_ptr / PAGE_SIZE;
-	last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
-	num_pages = last_data_page - first_data_page + 1;
-
-	user_pages = drm_malloc_ab(num_pages, sizeof(struct page *));
-	if (user_pages == NULL)
-		return -ENOMEM;
-
-	mutex_unlock(&dev->struct_mutex);
-	down_read(&mm->mmap_sem);
-	pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
-				      num_pages, 0, 0, user_pages, NULL);
-	up_read(&mm->mmap_sem);
-	mutex_lock(&dev->struct_mutex);
-	if (pinned_pages < num_pages) {
-		ret = -EFAULT;
-		goto out;
-	}
-
-	ret = i915_gem_object_set_to_cpu_domain(obj, 1);
-	if (ret)
-		goto out;
-
-	do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
+	obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj);
 
 	offset = args->offset;
 	obj->dirty = 1;
 
+	mutex_unlock(&dev->struct_mutex);
+
 	while (remain > 0) {
 		struct page *page;
+		char *vaddr;
 
 		/* Operation in this page
 		 *
 		 * shmem_page_offset = offset within page in shmem file
-		 * data_page_index = page number in get_user_pages return
-		 * data_page_offset = offset with data_page_index page.
 		 * page_length = bytes to copy for this page
 		 */
 		shmem_page_offset = offset_in_page(offset);
-		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-		data_page_offset = offset_in_page(data_ptr);
 
 		page_length = remain;
 		if ((shmem_page_offset + page_length) > PAGE_SIZE)
 			page_length = PAGE_SIZE - shmem_page_offset;
-		if ((data_page_offset + page_length) > PAGE_SIZE)
-			page_length = PAGE_SIZE - data_page_offset;
 
 		page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
 		if (IS_ERR(page)) {
@@ -913,34 +828,45 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev,
 			goto out;
 		}
 
-		if (do_bit17_swizzling) {
-			slow_shmem_bit17_copy(page,
-					      shmem_page_offset,
-					      user_pages[data_page_index],
-					      data_page_offset,
-					      page_length,
-					      0);
-		} else {
-			slow_shmem_copy(page,
-					shmem_page_offset,
-					user_pages[data_page_index],
-					data_page_offset,
-					page_length);
-		}
+		page_do_bit17_swizzling = obj_do_bit17_swizzling &&
+			(page_to_phys(page) & (1 << 17)) != 0;
+
+		vaddr = kmap(page);
+		if (page_do_bit17_swizzling)
+			ret = __copy_from_user_swizzled(vaddr, shmem_page_offset,
+							user_data,
+							page_length);
+		else
+			ret = __copy_from_user(vaddr + shmem_page_offset,
+					       user_data,
+					       page_length);
+		kunmap(page);
 
 		set_page_dirty(page);
 		mark_page_accessed(page);
 		page_cache_release(page);
 
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
 		remain -= page_length;
-		data_ptr += page_length;
+		user_data += page_length;
 		offset += page_length;
 	}
 
 out:
-	for (i = 0; i < pinned_pages; i++)
-		page_cache_release(user_pages[i]);
-	drm_free_large(user_pages);
+	mutex_lock(&dev->struct_mutex);
+	/* Fixup: Kill any reinstated backing storage pages */
+	if (obj->madv == __I915_MADV_PURGED)
+		i915_gem_object_truncate(obj);
+	/* and flush dirty cachelines in case the object isn't in the cpu write
+	 * domain anymore. */
+	if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
+		i915_gem_clflush_object(obj);
+		intel_gtt_chipset_flush();
+	}
 
 	return ret;
 }
@@ -996,10 +922,13 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 	 * pread/pwrite currently are reading and writing from the CPU
 	 * perspective, requiring manual detiling by the client.
 	 */
-	if (obj->phys_obj)
+	if (obj->phys_obj) {
 		ret = i915_gem_phys_pwrite(dev, obj, args, file);
-	else if (obj->gtt_space &&
-		 obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
+		goto out;
+	}
+
+	if (obj->gtt_space &&
+	    obj->base.write_domain != I915_GEM_DOMAIN_CPU) {
 		ret = i915_gem_object_pin(obj, 0, true);
 		if (ret)
 			goto out;
@@ -1018,18 +947,24 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 out_unpin:
 		i915_gem_object_unpin(obj);
-	} else {
-		ret = i915_gem_object_set_to_cpu_domain(obj, 1);
-		if (ret)
-			goto out;
 
-		ret = -EFAULT;
-		if (!i915_gem_object_needs_bit17_swizzle(obj))
-			ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file);
-		if (ret == -EFAULT)
-			ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file);
+		if (ret != -EFAULT)
+			goto out;
+		/* Fall through to the shmfs paths because the gtt paths might
+		 * fail with non-page-backed user pointers (e.g. gtt mappings
+		 * when moving data between textures). */
 	}
 
+	ret = i915_gem_object_set_to_cpu_domain(obj, 1);
+	if (ret)
+		goto out;
+
+	ret = -EFAULT;
+	if (!i915_gem_object_needs_bit17_swizzle(obj))
+		ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file);
+	if (ret == -EFAULT)
+		ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file);
+
 out:
 	drm_gem_object_unreference(&obj->base);
 unlock:
@@ -1141,7 +1076,6 @@ int
 i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
 		    struct drm_file *file)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_gem_mmap *args = data;
 	struct drm_gem_object *obj;
 	unsigned long addr;
@@ -1153,11 +1087,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
 	if (obj == NULL)
 		return -ENOENT;
 
-	if (obj->size > dev_priv->mm.gtt_mappable_end) {
-		drm_gem_object_unreference_unlocked(obj);
-		return -E2BIG;
-	}
-
 	down_write(&current->mm->mmap_sem);
 	addr = do_mmap(obj->filp, 0, args->size,
 		       PROT_READ | PROT_WRITE, MAP_SHARED,
@@ -1943,7 +1872,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
  */
 int
 i915_wait_request(struct intel_ring_buffer *ring,
-		  uint32_t seqno)
+		  uint32_t seqno,
+		  bool do_retire)
 {
 	drm_i915_private_t *dev_priv = ring->dev->dev_private;
 	u32 ier;
@@ -2027,7 +1957,7 @@ i915_wait_request(struct intel_ring_buffer *ring,
 	 * buffer to have made it to the inactive list, and we would need
 	 * a separate wait queue to handle that.
 	 */
-	if (ret == 0)
+	if (ret == 0 && do_retire)
 		i915_gem_retire_requests_ring(ring);
 
 	return ret;
@@ -2051,7 +1981,8 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj)
 	 * it.
 	 */
 	if (obj->active) {
-		ret = i915_wait_request(obj->ring, obj->last_rendering_seqno);
+		ret = i915_wait_request(obj->ring, obj->last_rendering_seqno,
+					true);
 		if (ret)
 			return ret;
 	}
@@ -2172,7 +2103,7 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring,
 	return 0;
 }
 
-static int i915_ring_idle(struct intel_ring_buffer *ring)
+static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire)
 {
 	int ret;
 
@@ -2186,18 +2117,18 @@ static int i915_ring_idle(struct intel_ring_buffer *ring)
 			return ret;
 	}
 
-	return i915_wait_request(ring, i915_gem_next_request_seqno(ring));
+	return i915_wait_request(ring, i915_gem_next_request_seqno(ring),
+				 do_retire);
 }
 
-int
-i915_gpu_idle(struct drm_device *dev)
+int i915_gpu_idle(struct drm_device *dev, bool do_retire)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	int ret, i;
 
 	/* Flush everything onto the inactive list. */
 	for (i = 0; i < I915_NUM_RINGS; i++) {
-		ret = i915_ring_idle(&dev_priv->ring[i]);
+		ret = i915_ring_idle(&dev_priv->ring[i], do_retire);
 		if (ret)
 			return ret;
 	}
@@ -2400,7 +2331,8 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj,
 		if (!ring_passed_seqno(obj->last_fenced_ring,
 				       obj->last_fenced_seqno)) {
 			ret = i915_wait_request(obj->last_fenced_ring,
-						obj->last_fenced_seqno);
+						obj->last_fenced_seqno,
+						true);
 			if (ret)
 				return ret;
 		}
@@ -2432,6 +2364,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
 
 	if (obj->fence_reg != I915_FENCE_REG_NONE) {
 		struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
+
+		WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count);
 		i915_gem_clear_fence_reg(obj->base.dev,
 					 &dev_priv->fence_regs[obj->fence_reg]);
 
@@ -2456,7 +2390,7 @@ i915_find_fence_reg(struct drm_device *dev,
 		if (!reg->obj)
 			return reg;
 
-		if (!reg->obj->pin_count)
+		if (!reg->pin_count)
 			avail = reg;
 	}
 
@@ -2466,7 +2400,7 @@ i915_find_fence_reg(struct drm_device *dev,
 	/* None available, try to steal one or wait for a user to finish */
 	avail = first = NULL;
 	list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) {
-		if (reg->obj->pin_count)
+		if (reg->pin_count)
 			continue;
 
 		if (first == NULL)
@@ -2541,7 +2475,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
 				if (!ring_passed_seqno(obj->last_fenced_ring,
 						       reg->setup_seqno)) {
 					ret = i915_wait_request(obj->last_fenced_ring,
-								reg->setup_seqno);
+								reg->setup_seqno,
+								true);
 					if (ret)
 						return ret;
 				}
@@ -2560,7 +2495,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj,
 
 	reg = i915_find_fence_reg(dev, pipelined);
 	if (reg == NULL)
-		return -ENOSPC;
+		return -EDEADLK;
 
 	ret = i915_gem_object_flush_fence(obj, pipelined);
 	if (ret)
@@ -2660,6 +2595,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev,
 	list_del_init(&reg->lru_list);
 	reg->obj = NULL;
 	reg->setup_seqno = 0;
+	reg->pin_count = 0;
 }
 
 /**
@@ -3619,8 +3555,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
 	obj->base.write_domain = I915_GEM_DOMAIN_CPU;
 	obj->base.read_domains = I915_GEM_DOMAIN_CPU;
 
-	if (IS_GEN6(dev) || IS_GEN7(dev)) {
-		/* On Gen6, we can have the GPU use the LLC (the CPU
+	if (HAS_LLC(dev)) {
+		/* On some devices, we can have the GPU use the LLC (the CPU
 		 * cache) for about a 10% performance improvement
 		 * compared to uncached.  Graphics requests other than
 		 * display scanout are coherent with the CPU in
@@ -3710,7 +3646,7 @@ i915_gem_idle(struct drm_device *dev)
 		return 0;
 	}
 
-	ret = i915_gpu_idle(dev);
+	ret = i915_gpu_idle(dev, true);
 	if (ret) {
 		mutex_unlock(&dev->struct_mutex);
 		return ret;
@@ -4201,7 +4137,7 @@ rescan:
 		 * This has a dramatic impact to reduce the number of
 		 * OOM-killer events whilst running the GPU aggressively.
 		 */
-		if (i915_gpu_idle(dev) == 0)
+		if (i915_gpu_idle(dev, true) == 0)
 			goto rescan;
 	}
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
index ead5d00..097119c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -195,7 +195,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only)
 	trace_i915_gem_evict_everything(dev, purgeable_only);
 
 	/* Flush everything (on to the inactive lists) and evict */
-	ret = i915_gpu_idle(dev);
+	ret = i915_gpu_idle(dev, true);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 65e1f00..c719df1 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -203,9 +203,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj,
 	cd->invalidate_domains |= invalidate_domains;
 	cd->flush_domains |= flush_domains;
 	if (flush_domains & I915_GEM_GPU_DOMAINS)
-		cd->flush_rings |= obj->ring->id;
+		cd->flush_rings |= intel_ring_flag(obj->ring);
 	if (invalidate_domains & I915_GEM_GPU_DOMAINS)
-		cd->flush_rings |= ring->id;
+		cd->flush_rings |= intel_ring_flag(ring);
 }
 
 struct eb_objects {
@@ -303,8 +303,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
 			  reloc->write_domain);
 		return ret;
 	}
-	if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) {
-		DRM_ERROR("reloc with read/write CPU domains: "
+	if (unlikely((reloc->write_domain | reloc->read_domains)
+		     & ~I915_GEM_GPU_DOMAINS)) {
+		DRM_ERROR("reloc with read/write non-GPU domains: "
 			  "obj %p target %d offset %d "
 			  "read %08x write %08x",
 			  obj, reloc->target_handle,
@@ -461,6 +462,54 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
 	return ret;
 }
 
+#define  __EXEC_OBJECT_HAS_FENCE (1<<31)
+
+static int
+pin_and_fence_object(struct drm_i915_gem_object *obj,
+		     struct intel_ring_buffer *ring)
+{
+	struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
+	bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4;
+	bool need_fence, need_mappable;
+	int ret;
+
+	need_fence =
+		has_fenced_gpu_access &&
+		entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
+		obj->tiling_mode != I915_TILING_NONE;
+	need_mappable =
+		entry->relocation_count ? true : need_fence;
+
+	ret = i915_gem_object_pin(obj, entry->alignment, need_mappable);
+	if (ret)
+		return ret;
+
+	if (has_fenced_gpu_access) {
+		if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) {
+			if (obj->tiling_mode) {
+				ret = i915_gem_object_get_fence(obj, ring);
+				if (ret)
+					goto err_unpin;
+
+				entry->flags |= __EXEC_OBJECT_HAS_FENCE;
+				i915_gem_object_pin_fence(obj);
+			} else {
+				ret = i915_gem_object_put_fence(obj);
+				if (ret)
+					goto err_unpin;
+			}
+		}
+		obj->pending_fenced_gpu_access = need_fence;
+	}
+
+	entry->offset = obj->gtt_offset;
+	return 0;
+
+err_unpin:
+	i915_gem_object_unpin(obj);
+	return ret;
+}
+
 static int
 i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
 			    struct drm_file *file,
@@ -518,6 +567,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
 		list_for_each_entry(obj, objects, exec_list) {
 			struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
 			bool need_fence, need_mappable;
+
 			if (!obj->gtt_space)
 				continue;
 
@@ -532,58 +582,47 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
 			    (need_mappable && !obj->map_and_fenceable))
 				ret = i915_gem_object_unbind(obj);
 			else
-				ret = i915_gem_object_pin(obj,
-							  entry->alignment,
-							  need_mappable);
+				ret = pin_and_fence_object(obj, ring);
 			if (ret)
 				goto err;
-
-			entry++;
 		}
 
 		/* Bind fresh objects */
 		list_for_each_entry(obj, objects, exec_list) {
-			struct drm_i915_gem_exec_object2 *entry = obj->exec_entry;
-			bool need_fence;
-
-			need_fence =
-				has_fenced_gpu_access &&
-				entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
-				obj->tiling_mode != I915_TILING_NONE;
-
-			if (!obj->gtt_space) {
-				bool need_mappable =
-					entry->relocation_count ? true : need_fence;
-
-				ret = i915_gem_object_pin(obj,
-							  entry->alignment,
-							  need_mappable);
-				if (ret)
-					break;
-			}
+			if (obj->gtt_space)
+				continue;
 
-			if (has_fenced_gpu_access) {
-				if (need_fence) {
-					ret = i915_gem_object_get_fence(obj, ring);
-					if (ret)
-						break;
-				} else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
-					   obj->tiling_mode == I915_TILING_NONE) {
-					/* XXX pipelined! */
-					ret = i915_gem_object_put_fence(obj);
-					if (ret)
-						break;
-				}
-				obj->pending_fenced_gpu_access = need_fence;
+			ret = pin_and_fence_object(obj, ring);
+			if (ret) {
+				int ret_ignore;
+
+				/* This can potentially raise a harmless
+				 * -EINVAL if we failed to bind in the above
+				 * call. It cannot raise -EINTR since we know
+				 * that the bo is freshly bound and so will
+				 * not need to be flushed or waited upon.
+				 */
+				ret_ignore = i915_gem_object_unbind(obj);
+				(void)ret_ignore;
+				WARN_ON(obj->gtt_space);
+				break;
 			}
-
-			entry->offset = obj->gtt_offset;
 		}
 
 		/* Decrement pin count for bound objects */
 		list_for_each_entry(obj, objects, exec_list) {
-			if (obj->gtt_space)
-				i915_gem_object_unpin(obj);
+			struct drm_i915_gem_exec_object2 *entry;
+
+			if (!obj->gtt_space)
+				continue;
+
+			entry = obj->exec_entry;
+			if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
+				i915_gem_object_unpin_fence(obj);
+				entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
+			}
+
+			i915_gem_object_unpin(obj);
 		}
 
 		if (ret != -ENOSPC || retry > 1)
@@ -600,16 +639,19 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring,
 	} while (1);
 
 err:
-	obj = list_entry(obj->exec_list.prev,
-			 struct drm_i915_gem_object,
-			 exec_list);
-	while (objects != &obj->exec_list) {
-		if (obj->gtt_space)
-			i915_gem_object_unpin(obj);
+	list_for_each_entry_continue_reverse(obj, objects, exec_list) {
+		struct drm_i915_gem_exec_object2 *entry;
+
+		if (!obj->gtt_space)
+			continue;
+
+		entry = obj->exec_entry;
+		if (entry->flags & __EXEC_OBJECT_HAS_FENCE) {
+			i915_gem_object_unpin_fence(obj);
+			entry->flags &= ~__EXEC_OBJECT_HAS_FENCE;
+		}
 
-		obj = list_entry(obj->exec_list.prev,
-				 struct drm_i915_gem_object,
-				 exec_list);
+		i915_gem_object_unpin(obj);
 	}
 
 	return ret;
@@ -1186,7 +1228,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 			 * so every billion or so execbuffers, we need to stall
 			 * the GPU in order to reset the counters.
 			 */
-			ret = i915_gpu_idle(dev);
+			ret = i915_gpu_idle(dev, true);
 			if (ret)
 				goto err;
 
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6042c5e..11bddd5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -55,7 +55,7 @@ static bool do_idling(struct drm_i915_private *dev_priv)
 
 	if (unlikely(dev_priv->mm.gtt->do_idle_maps)) {
 		dev_priv->mm.interruptible = false;
-		if (i915_gpu_idle(dev_priv->dev)) {
+		if (i915_gpu_idle(dev_priv->dev, false)) {
 			DRM_ERROR("Couldn't idle GPU\n");
 			/* Wait a bit, in hopes it avoids the hang */
 			udelay(10);
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 31d334d..861223b 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -107,10 +107,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
 		 */
 		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
 		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
-	} else if (IS_MOBILE(dev)) {
+	} else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) {
 		uint32_t dcc;
 
-		/* On mobile 9xx chipsets, channel interleave by the CPU is
+		/* On 9xx chipsets, channel interleave by the CPU is
 		 * determined by DCC.  For single-channel, neither the CPU
 		 * nor the GPU do swizzling.  For dual channel interleaved,
 		 * the GPU's interleave is bit 9 and 10 for X tiled, and bit
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5bd4361..6442ff2 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -720,7 +720,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
 	reloc_offset = src->gtt_offset;
 	for (page = 0; page < page_count; page++) {
 		unsigned long flags;
-		void __iomem *s;
 		void *d;
 
 		d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
@@ -728,10 +727,29 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
 			goto unwind;
 
 		local_irq_save(flags);
-		s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
-					     reloc_offset);
-		memcpy_fromio(d, s, PAGE_SIZE);
-		io_mapping_unmap_atomic(s);
+		if (reloc_offset < dev_priv->mm.gtt_mappable_end) {
+			void __iomem *s;
+
+			/* Simply ignore tiling or any overlapping fence.
+			 * It's part of the error state, and this hopefully
+			 * captures what the GPU read.
+			 */
+
+			s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
+						     reloc_offset);
+			memcpy_fromio(d, s, PAGE_SIZE);
+			io_mapping_unmap_atomic(s);
+		} else {
+			void *s;
+
+			drm_clflush_pages(&src->pages[page], 1);
+
+			s = kmap_atomic(src->pages[page]);
+			memcpy(d, s, PAGE_SIZE);
+			kunmap_atomic(s);
+
+			drm_clflush_pages(&src->pages[page], 1);
+		}
 		local_irq_restore(flags);
 
 		dst->pages[page] = d;
@@ -804,7 +822,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err,
 		err->tiling = obj->tiling_mode;
 		err->dirty = obj->dirty;
 		err->purgeable = obj->madv != I915_MADV_WILLNEED;
-		err->ring = obj->ring ? obj->ring->id : 0;
+		err->ring = obj->ring ? obj->ring->id : -1;
 		err->cache_level = obj->cache_level;
 
 		if (++i == count)
@@ -876,6 +894,39 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
 	return NULL;
 }
 
+static void i915_record_ring_state(struct drm_device *dev,
+				   struct drm_i915_error_state *error,
+				   struct intel_ring_buffer *ring)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (INTEL_INFO(dev)->gen >= 6) {
+		error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base));
+		error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring));
+	}
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base));
+		error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base));
+		error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base));
+		error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base));
+		if (ring->id == RCS) {
+			error->instdone1 = I915_READ(INSTDONE1);
+			error->bbaddr = I915_READ64(BB_ADDR);
+		}
+	} else {
+		error->ipeir[ring->id] = I915_READ(IPEIR);
+		error->ipehr[ring->id] = I915_READ(IPEHR);
+		error->instdone[ring->id] = I915_READ(INSTDONE);
+	}
+
+	error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base));
+	error->seqno[ring->id] = ring->get_seqno(ring);
+	error->acthd[ring->id] = intel_ring_get_active_head(ring);
+	error->head[ring->id] = I915_READ_HEAD(ring);
+	error->tail[ring->id] = I915_READ_TAIL(ring);
+}
+
 /**
  * i915_capture_error_state - capture an error record for later analysis
  * @dev: drm device
@@ -900,7 +951,7 @@ static void i915_capture_error_state(struct drm_device *dev)
 		return;
 
 	/* Account for pipe specific data like PIPE*STAT */
-	error = kmalloc(sizeof(*error), GFP_ATOMIC);
+	error = kzalloc(sizeof(*error), GFP_ATOMIC);
 	if (!error) {
 		DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
 		return;
@@ -909,47 +960,22 @@ static void i915_capture_error_state(struct drm_device *dev)
 	DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n",
 		 dev->primary->index);
 
-	error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]);
 	error->eir = I915_READ(EIR);
 	error->pgtbl_er = I915_READ(PGTBL_ER);
 	for_each_pipe(pipe)
 		error->pipestat[pipe] = I915_READ(PIPESTAT(pipe));
-	error->instpm = I915_READ(INSTPM);
-	error->error = 0;
+
 	if (INTEL_INFO(dev)->gen >= 6) {
 		error->error = I915_READ(ERROR_GEN6);
-
-		error->bcs_acthd = I915_READ(BCS_ACTHD);
-		error->bcs_ipehr = I915_READ(BCS_IPEHR);
-		error->bcs_ipeir = I915_READ(BCS_IPEIR);
-		error->bcs_instdone = I915_READ(BCS_INSTDONE);
-		error->bcs_seqno = 0;
-		if (dev_priv->ring[BCS].get_seqno)
-			error->bcs_seqno = dev_priv->ring[BCS].get_seqno(&dev_priv->ring[BCS]);
-
-		error->vcs_acthd = I915_READ(VCS_ACTHD);
-		error->vcs_ipehr = I915_READ(VCS_IPEHR);
-		error->vcs_ipeir = I915_READ(VCS_IPEIR);
-		error->vcs_instdone = I915_READ(VCS_INSTDONE);
-		error->vcs_seqno = 0;
-		if (dev_priv->ring[VCS].get_seqno)
-			error->vcs_seqno = dev_priv->ring[VCS].get_seqno(&dev_priv->ring[VCS]);
-	}
-	if (INTEL_INFO(dev)->gen >= 4) {
-		error->ipeir = I915_READ(IPEIR_I965);
-		error->ipehr = I915_READ(IPEHR_I965);
-		error->instdone = I915_READ(INSTDONE_I965);
-		error->instps = I915_READ(INSTPS);
-		error->instdone1 = I915_READ(INSTDONE1);
-		error->acthd = I915_READ(ACTHD_I965);
-		error->bbaddr = I915_READ64(BB_ADDR);
-	} else {
-		error->ipeir = I915_READ(IPEIR);
-		error->ipehr = I915_READ(IPEHR);
-		error->instdone = I915_READ(INSTDONE);
-		error->acthd = I915_READ(ACTHD);
-		error->bbaddr = 0;
+		error->done_reg = I915_READ(DONE_REG);
 	}
+
+	i915_record_ring_state(dev, error, &dev_priv->ring[RCS]);
+	if (HAS_BLT(dev))
+		i915_record_ring_state(dev, error, &dev_priv->ring[BCS]);
+	if (HAS_BSD(dev))
+		i915_record_ring_state(dev, error, &dev_priv->ring[VCS]);
+
 	i915_gem_record_fences(dev, error);
 
 	/* Record the active batch and ring buffers */
@@ -1017,11 +1043,12 @@ void i915_destroy_error_state(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_error_state *error;
+	unsigned long flags;
 
-	spin_lock(&dev_priv->error_lock);
+	spin_lock_irqsave(&dev_priv->error_lock, flags);
 	error = dev_priv->first_error;
 	dev_priv->first_error = NULL;
-	spin_unlock(&dev_priv->error_lock);
+	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
 
 	if (error)
 		i915_error_state_free(dev, error);
@@ -1698,6 +1725,7 @@ void i915_hangcheck_elapsed(unsigned long data)
 	    dev_priv->last_instdone1 == instdone1) {
 		if (dev_priv->hangcheck_count++ > 1) {
 			DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
+			i915_handle_error(dev, true);
 
 			if (!IS_GEN2(dev)) {
 				/* Is the chip hanging on a WAIT_FOR_EVENT?
@@ -1705,7 +1733,6 @@ void i915_hangcheck_elapsed(unsigned long data)
 				 * and break the hang. This should work on
 				 * all but the second generation chipsets.
 				 */
-
 				if (kick_ring(&dev_priv->ring[RCS]))
 					goto repeat;
 
@@ -1718,7 +1745,6 @@ void i915_hangcheck_elapsed(unsigned long data)
 					goto repeat;
 			}
 
-			i915_handle_error(dev, true);
 			return;
 		}
 	} else {
diff --git a/drivers/gpu/drm/i915/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c
deleted file mode 100644
index cc8f6d4..0000000
--- a/drivers/gpu/drm/i915/i915_mem.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
- */
-/*
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-/* This memory manager is integrated into the global/local lru
- * mechanisms used by the clients.  Specifically, it operates by
- * setting the 'in_use' fields of the global LRU to indicate whether
- * this region is privately allocated to a client.
- *
- * This does require the client to actually respect that field.
- *
- * Currently no effort is made to allocate 'private' memory in any
- * clever way - the LRU information isn't used to determine which
- * block to allocate, and the ring is drained prior to allocations --
- * in other words allocation is expensive.
- */
-static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
-	drm_i915_sarea_t *sarea_priv = master_priv->sarea_priv;
-	struct drm_tex_region *list;
-	unsigned shift, nr;
-	unsigned start;
-	unsigned end;
-	unsigned i;
-	int age;
-
-	shift = dev_priv->tex_lru_log_granularity;
-	nr = I915_NR_TEX_REGIONS;
-
-	start = p->start >> shift;
-	end = (p->start + p->size - 1) >> shift;
-
-	age = ++sarea_priv->texAge;
-	list = sarea_priv->texList;
-
-	/* Mark the regions with the new flag and update their age.  Move
-	 * them to head of list to preserve LRU semantics.
-	 */
-	for (i = start; i <= end; i++) {
-		list[i].in_use = in_use;
-		list[i].age = age;
-
-		/* remove_from_list(i)
-		 */
-		list[(unsigned)list[i].next].prev = list[i].prev;
-		list[(unsigned)list[i].prev].next = list[i].next;
-
-		/* insert_at_head(list, i)
-		 */
-		list[i].prev = nr;
-		list[i].next = list[nr].next;
-		list[(unsigned)list[nr].next].prev = i;
-		list[nr].next = i;
-	}
-}
-
-/* Very simple allocator for agp memory, working on a static range
- * already mapped into each client's address space.
- */
-
-static struct mem_block *split_block(struct mem_block *p, int start, int size,
-				     struct drm_file *file_priv)
-{
-	/* Maybe cut off the start of an existing block */
-	if (start > p->start) {
-		struct mem_block *newblock = kmalloc(sizeof(*newblock),
-						     GFP_KERNEL);
-		if (!newblock)
-			goto out;
-		newblock->start = start;
-		newblock->size = p->size - (start - p->start);
-		newblock->file_priv = NULL;
-		newblock->next = p->next;
-		newblock->prev = p;
-		p->next->prev = newblock;
-		p->next = newblock;
-		p->size -= newblock->size;
-		p = newblock;
-	}
-
-	/* Maybe cut off the end of an existing block */
-	if (size < p->size) {
-		struct mem_block *newblock = kmalloc(sizeof(*newblock),
-						     GFP_KERNEL);
-		if (!newblock)
-			goto out;
-		newblock->start = start + size;
-		newblock->size = p->size - size;
-		newblock->file_priv = NULL;
-		newblock->next = p->next;
-		newblock->prev = p;
-		p->next->prev = newblock;
-		p->next = newblock;
-		p->size = size;
-	}
-
-      out:
-	/* Our block is in the middle */
-	p->file_priv = file_priv;
-	return p;
-}
-
-static struct mem_block *alloc_block(struct mem_block *heap, int size,
-				     int align2, struct drm_file *file_priv)
-{
-	struct mem_block *p;
-	int mask = (1 << align2) - 1;
-
-	for (p = heap->next; p != heap; p = p->next) {
-		int start = (p->start + mask) & ~mask;
-		if (p->file_priv == NULL && start + size <= p->start + p->size)
-			return split_block(p, start, size, file_priv);
-	}
-
-	return NULL;
-}
-
-static struct mem_block *find_block(struct mem_block *heap, int start)
-{
-	struct mem_block *p;
-
-	for (p = heap->next; p != heap; p = p->next)
-		if (p->start == start)
-			return p;
-
-	return NULL;
-}
-
-static void free_block(struct mem_block *p)
-{
-	p->file_priv = NULL;
-
-	/* Assumes a single contiguous range.  Needs a special file_priv in
-	 * 'heap' to stop it being subsumed.
-	 */
-	if (p->next->file_priv == NULL) {
-		struct mem_block *q = p->next;
-		p->size += q->size;
-		p->next = q->next;
-		p->next->prev = p;
-		kfree(q);
-	}
-
-	if (p->prev->file_priv == NULL) {
-		struct mem_block *q = p->prev;
-		q->size += p->size;
-		q->next = p->next;
-		q->next->prev = q;
-		kfree(p);
-	}
-}
-
-/* Initialize.  How to check for an uninitialized heap?
- */
-static int init_heap(struct mem_block **heap, int start, int size)
-{
-	struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL);
-
-	if (!blocks)
-		return -ENOMEM;
-
-	*heap = kmalloc(sizeof(**heap), GFP_KERNEL);
-	if (!*heap) {
-		kfree(blocks);
-		return -ENOMEM;
-	}
-
-	blocks->start = start;
-	blocks->size = size;
-	blocks->file_priv = NULL;
-	blocks->next = blocks->prev = *heap;
-
-	memset(*heap, 0, sizeof(**heap));
-	(*heap)->file_priv = (struct drm_file *) -1;
-	(*heap)->next = (*heap)->prev = blocks;
-	return 0;
-}
-
-/* Free all blocks associated with the releasing file.
- */
-void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv,
-		      struct mem_block *heap)
-{
-	struct mem_block *p;
-
-	if (!heap || !heap->next)
-		return;
-
-	for (p = heap->next; p != heap; p = p->next) {
-		if (p->file_priv == file_priv) {
-			p->file_priv = NULL;
-			mark_block(dev, p, 0);
-		}
-	}
-
-	/* Assumes a single contiguous range.  Needs a special file_priv in
-	 * 'heap' to stop it being subsumed.
-	 */
-	for (p = heap->next; p != heap; p = p->next) {
-		while (p->file_priv == NULL && p->next->file_priv == NULL) {
-			struct mem_block *q = p->next;
-			p->size += q->size;
-			p->next = q->next;
-			p->next->prev = p;
-			kfree(q);
-		}
-	}
-}
-
-/* Shutdown.
- */
-void i915_mem_takedown(struct mem_block **heap)
-{
-	struct mem_block *p;
-
-	if (!*heap)
-		return;
-
-	for (p = (*heap)->next; p != *heap;) {
-		struct mem_block *q = p;
-		p = p->next;
-		kfree(q);
-	}
-
-	kfree(*heap);
-	*heap = NULL;
-}
-
-static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)
-{
-	switch (region) {
-	case I915_MEM_REGION_AGP:
-		return &dev_priv->agp_heap;
-	default:
-		return NULL;
-	}
-}
-
-/* IOCTL HANDLERS */
-
-int i915_mem_alloc(struct drm_device *dev, void *data,
-		   struct drm_file *file_priv)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	drm_i915_mem_alloc_t *alloc = data;
-	struct mem_block *block, **heap;
-
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
-
-	heap = get_heap(dev_priv, alloc->region);
-	if (!heap || !*heap)
-		return -EFAULT;
-
-	/* Make things easier on ourselves: all allocations at least
-	 * 4k aligned.
-	 */
-	if (alloc->alignment < 12)
-		alloc->alignment = 12;
-
-	block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);
-
-	if (!block)
-		return -ENOMEM;
-
-	mark_block(dev, block, 1);
-
-	if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
-			     sizeof(int))) {
-		DRM_ERROR("copy_to_user\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-int i915_mem_free(struct drm_device *dev, void *data,
-		  struct drm_file *file_priv)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	drm_i915_mem_free_t *memfree = data;
-	struct mem_block *block, **heap;
-
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
-
-	heap = get_heap(dev_priv, memfree->region);
-	if (!heap || !*heap)
-		return -EFAULT;
-
-	block = find_block(*heap, memfree->region_offset);
-	if (!block)
-		return -EFAULT;
-
-	if (block->file_priv != file_priv)
-		return -EPERM;
-
-	mark_block(dev, block, 0);
-	free_block(block);
-	return 0;
-}
-
-int i915_mem_init_heap(struct drm_device *dev, void *data,
-		       struct drm_file *file_priv)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	drm_i915_mem_init_heap_t *initheap = data;
-	struct mem_block **heap;
-
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
-
-	heap = get_heap(dev_priv, initheap->region);
-	if (!heap)
-		return -EFAULT;
-
-	if (*heap) {
-		DRM_ERROR("heap already initialized?");
-		return -EFAULT;
-	}
-
-	return init_heap(heap, initheap->start, initheap->size);
-}
-
-int i915_mem_destroy_heap(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	drm_i915_mem_destroy_heap_t *destroyheap = data;
-	struct mem_block **heap;
-
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
-
-	heap = get_heap(dev_priv, destroyheap->region);
-	if (!heap) {
-		DRM_ERROR("get_heap failed");
-		return -EFAULT;
-	}
-
-	if (!*heap) {
-		DRM_ERROR("heap not initialized?");
-		return -EFAULT;
-	}
-
-	i915_mem_takedown(heap);
-	return 0;
-}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c3afb78..f960738 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -319,6 +319,8 @@
 #define RING_HWS_PGA(base)	((base)+0x80)
 #define RING_HWS_PGA_GEN6(base)	((base)+0x2080)
 #define RENDER_HWS_PGA_GEN7	(0x04080)
+#define RING_FAULT_REG(ring)	(0x4094 + 0x100*(ring)->id)
+#define DONE_REG		0x40b0
 #define BSD_HWS_PGA_GEN7	(0x04180)
 #define BLT_HWS_PGA_GEN7	(0x04280)
 #define RING_ACTHD(base)	((base)+0x74)
@@ -352,6 +354,12 @@
 #define IPEIR_I965	0x02064
 #define IPEHR_I965	0x02068
 #define INSTDONE_I965	0x0206c
+#define RING_IPEIR(base)	((base)+0x64)
+#define RING_IPEHR(base)	((base)+0x68)
+#define RING_INSTDONE(base)	((base)+0x6c)
+#define RING_INSTPS(base)	((base)+0x70)
+#define RING_DMA_FADD(base)	((base)+0x78)
+#define RING_INSTPM(base)	((base)+0xc0)
 #define INSTPS		0x02070 /* 965+ only */
 #define INSTDONE1	0x0207c /* 965+ only */
 #define ACTHD_I965	0x02074
@@ -365,14 +373,6 @@
 #define INSTDONE	0x02090
 #define NOPID		0x02094
 #define HWSTAM		0x02098
-#define VCS_INSTDONE	0x1206C
-#define VCS_IPEIR	0x12064
-#define VCS_IPEHR	0x12068
-#define VCS_ACTHD	0x12074
-#define BCS_INSTDONE	0x2206C
-#define BCS_IPEIR	0x22064
-#define BCS_IPEHR	0x22068
-#define BCS_ACTHD	0x22074
 
 #define ERROR_GEN6	0x040a0
 
@@ -391,7 +391,7 @@
 
 #define MI_MODE		0x0209c
 # define VS_TIMER_DISPATCH				(1 << 6)
-# define MI_FLUSH_ENABLE				(1 << 11)
+# define MI_FLUSH_ENABLE				(1 << 12)
 
 #define GFX_MODE	0x02520
 #define GFX_MODE_GEN7	0x0229c
@@ -3742,4 +3742,16 @@
  */
 #define GEN7_SO_WRITE_OFFSET(n)		(0x5280 + (n) * 4)
 
+#define IBX_AUD_CONFIG_A			0xe2000
+#define CPT_AUD_CONFIG_A			0xe5000
+#define   AUD_CONFIG_N_VALUE_INDEX		(1 << 29)
+#define   AUD_CONFIG_N_PROG_ENABLE		(1 << 28)
+#define   AUD_CONFIG_UPPER_N_SHIFT		20
+#define   AUD_CONFIG_UPPER_N_VALUE		(0xff << 20)
+#define   AUD_CONFIG_LOWER_N_SHIFT		4
+#define   AUD_CONFIG_LOWER_N_VALUE		(0xfff << 4)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT	16
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI		(0xf << 16)
+#define   AUD_CONFIG_DISABLE_NCTS		(1 << 3)
+
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c
index cb91210..bae3edf 100644
--- a/drivers/gpu/drm/i915/intel_acpi.c
+++ b/drivers/gpu/drm/i915/intel_acpi.c
@@ -208,7 +208,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev)
 
 	ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0);
 	if (ret < 0) {
-		DRM_ERROR("failed to get supported _DSM functions\n");
+		DRM_DEBUG_KMS("failed to get supported _DSM functions\n");
 		return false;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 63880e2..5065633 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -572,7 +572,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv,
 		DRM_DEBUG_KMS("no child dev is parsed from VBT\n");
 		return;
 	}
-	dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL);
+	dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);
 	if (!dev_priv->child_dev) {
 		DRM_DEBUG_KMS("No memory space for child device\n");
 		return;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 00fbff5..dd5665b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -75,7 +75,7 @@ struct intel_limit {
 	intel_range_t   dot, vco, n, m, m1, m2, p, p1;
 	intel_p2_t	    p2;
 	bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
-			int, int, intel_clock_t *);
+			int, int, intel_clock_t *, intel_clock_t *);
 };
 
 /* FDI */
@@ -83,17 +83,21 @@ struct intel_limit {
 
 static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-		    int target, int refclk, intel_clock_t *best_clock);
+		    int target, int refclk, intel_clock_t *match_clock,
+		    intel_clock_t *best_clock);
 static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *best_clock);
+			int target, int refclk, intel_clock_t *match_clock,
+			intel_clock_t *best_clock);
 
 static bool
 intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *best_clock);
+		      int target, int refclk, intel_clock_t *match_clock,
+		      intel_clock_t *best_clock);
 static bool
 intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
-			   int target, int refclk, intel_clock_t *best_clock);
+			   int target, int refclk, intel_clock_t *match_clock,
+			   intel_clock_t *best_clock);
 
 static inline u32 /* units of 100MHz */
 intel_fdi_link_freq(struct drm_device *dev)
@@ -515,7 +519,8 @@ static bool intel_PLL_is_valid(struct drm_device *dev,
 
 static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-		    int target, int refclk, intel_clock_t *best_clock)
+		    int target, int refclk, intel_clock_t *match_clock,
+		    intel_clock_t *best_clock)
 
 {
 	struct drm_device *dev = crtc->dev;
@@ -562,6 +567,9 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 					if (!intel_PLL_is_valid(dev, limit,
 								&clock))
 						continue;
+					if (match_clock &&
+					    clock.p != match_clock->p)
+						continue;
 
 					this_err = abs(clock.dot - target);
 					if (this_err < err) {
@@ -578,7 +586,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 
 static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
-			int target, int refclk, intel_clock_t *best_clock)
+			int target, int refclk, intel_clock_t *match_clock,
+			intel_clock_t *best_clock)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -625,6 +634,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 					if (!intel_PLL_is_valid(dev, limit,
 								&clock))
 						continue;
+					if (match_clock &&
+					    clock.p != match_clock->p)
+						continue;
 
 					this_err = abs(clock.dot - target);
 					if (this_err < err_most) {
@@ -642,7 +654,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 
 static bool
 intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
-			   int target, int refclk, intel_clock_t *best_clock)
+			   int target, int refclk, intel_clock_t *match_clock,
+			   intel_clock_t *best_clock)
 {
 	struct drm_device *dev = crtc->dev;
 	intel_clock_t clock;
@@ -668,7 +681,8 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
 /* DisplayPort has only two frequencies, 162MHz and 270MHz */
 static bool
 intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc,
-		      int target, int refclk, intel_clock_t *best_clock)
+		      int target, int refclk, intel_clock_t *match_clock,
+		      intel_clock_t *best_clock)
 {
 	intel_clock_t clock;
 	if (target < 200000) {
@@ -922,6 +936,10 @@ void assert_pipe(struct drm_i915_private *dev_priv,
 	u32 val;
 	bool cur_state;
 
+	/* if we need the pipe A quirk it must be always on */
+	if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
+		state = true;
+
 	reg = PIPECONF(pipe);
 	val = I915_READ(reg);
 	cur_state = !!(val & PIPECONF_ENABLE);
@@ -930,19 +948,24 @@ void assert_pipe(struct drm_i915_private *dev_priv,
 	     pipe_name(pipe), state_string(state), state_string(cur_state));
 }
 
-static void assert_plane_enabled(struct drm_i915_private *dev_priv,
-				 enum plane plane)
+static void assert_plane(struct drm_i915_private *dev_priv,
+			 enum plane plane, bool state)
 {
 	int reg;
 	u32 val;
+	bool cur_state;
 
 	reg = DSPCNTR(plane);
 	val = I915_READ(reg);
-	WARN(!(val & DISPLAY_PLANE_ENABLE),
-	     "plane %c assertion failure, should be active but is disabled\n",
-	     plane_name(plane));
+	cur_state = !!(val & DISPLAY_PLANE_ENABLE);
+	WARN(cur_state != state,
+	     "plane %c assertion failure (expected %s, current %s)\n",
+	     plane_name(plane), state_string(state), state_string(cur_state));
 }
 
+#define assert_plane_enabled(d, p) assert_plane(d, p, true)
+#define assert_plane_disabled(d, p) assert_plane(d, p, false)
+
 static void assert_planes_disabled(struct drm_i915_private *dev_priv,
 				   enum pipe pipe)
 {
@@ -951,8 +974,14 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
 	int cur_pipe;
 
 	/* Planes are fixed to pipes on ILK+ */
-	if (HAS_PCH_SPLIT(dev_priv->dev))
+	if (HAS_PCH_SPLIT(dev_priv->dev)) {
+		reg = DSPCNTR(pipe);
+		val = I915_READ(reg);
+		WARN((val & DISPLAY_PLANE_ENABLE),
+		     "plane %c assertion failure, should be disabled but not\n",
+		     plane_name(pipe));
 		return;
+	}
 
 	/* Need to check both planes against the pipe */
 	for (i = 0; i < 2; i++) {
@@ -1071,7 +1100,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
 {
 	u32 val = I915_READ(reg);
 	WARN(hdmi_pipe_enabled(dev_priv, val, pipe),
-	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
+	     "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
 	     reg, pipe_name(pipe));
 }
 
@@ -2012,6 +2041,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
 		ret = i915_gem_object_get_fence(obj, pipelined);
 		if (ret)
 			goto err_unpin;
+
+		i915_gem_object_pin_fence(obj);
 	}
 
 	dev_priv->mm.interruptible = true;
@@ -2024,6 +2055,12 @@ err_interruptible:
 	return ret;
 }
 
+void intel_unpin_fb_obj(struct drm_i915_gem_object *obj)
+{
+	i915_gem_object_unpin_fence(obj);
+	i915_gem_object_unpin(obj);
+}
+
 static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 			     int x, int y)
 {
@@ -2255,7 +2292,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
 					 LEAVE_ATOMIC_MODE_SET);
 	if (ret) {
-		i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj);
+		intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
 		mutex_unlock(&dev->struct_mutex);
 		DRM_ERROR("failed to update base address\n");
 		return ret;
@@ -2263,7 +2300,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
 	if (old_fb) {
 		intel_wait_for_vblank(dev, intel_crtc->pipe);
-		i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj);
+		intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj);
 	}
 
 	mutex_unlock(&dev->struct_mutex);
@@ -3321,10 +3358,12 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
 	struct drm_device *dev = crtc->dev;
 
 	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+	assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
+	assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
 
 	if (crtc->fb) {
 		mutex_lock(&dev->struct_mutex);
-		i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj);
+		intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
 		mutex_unlock(&dev->struct_mutex);
 	}
 }
@@ -4521,6 +4560,7 @@ void sandybridge_update_wm(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int latency = SNB_READ_WM0_LATENCY() * 100;	/* In unit 0.1us */
+	u32 val;
 	int fbc_wm, plane_wm, cursor_wm;
 	unsigned int enabled;
 
@@ -4529,8 +4569,10 @@ void sandybridge_update_wm(struct drm_device *dev)
 			    &sandybridge_display_wm_info, latency,
 			    &sandybridge_cursor_wm_info, latency,
 			    &plane_wm, &cursor_wm)) {
-		I915_WRITE(WM0_PIPEA_ILK,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+		val = I915_READ(WM0_PIPEA_ILK);
+		val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
+		I915_WRITE(WM0_PIPEA_ILK, val |
+			   ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm));
 		DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
 			      " plane %d, " "cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4541,8 +4583,10 @@ void sandybridge_update_wm(struct drm_device *dev)
 			    &sandybridge_display_wm_info, latency,
 			    &sandybridge_cursor_wm_info, latency,
 			    &plane_wm, &cursor_wm)) {
-		I915_WRITE(WM0_PIPEB_ILK,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+		val = I915_READ(WM0_PIPEB_ILK);
+		val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
+		I915_WRITE(WM0_PIPEB_ILK, val |
+			   ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm));
 		DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
 			      " plane %d, cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4555,8 +4599,10 @@ void sandybridge_update_wm(struct drm_device *dev)
 			    &sandybridge_display_wm_info, latency,
 			    &sandybridge_cursor_wm_info, latency,
 			    &plane_wm, &cursor_wm)) {
-		I915_WRITE(WM0_PIPEC_IVB,
-			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
+		val = I915_READ(WM0_PIPEC_IVB);
+		val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK);
+		I915_WRITE(WM0_PIPEC_IVB, val |
+			   ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm));
 		DRM_DEBUG_KMS("FIFO watermarks For pipe C -"
 			      " plane %d, cursor: %d\n",
 			      plane_wm, cursor_wm);
@@ -4700,6 +4746,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe,
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int latency = SNB_READ_WM0_LATENCY() * 100;	/* In unit 0.1us */
+	u32 val;
 	int sprite_wm, reg;
 	int ret;
 
@@ -4726,7 +4773,9 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe,
 		return;
 	}
 
-	I915_WRITE(reg, I915_READ(reg) | (sprite_wm << WM0_PIPE_SPRITE_SHIFT));
+	val = I915_READ(reg);
+	val &= ~WM0_PIPE_SPRITE_MASK;
+	I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT));
 	DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm);
 
 
@@ -4968,6 +5017,82 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
 	return display_bpc != bpc;
 }
 
+static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int refclk;
+
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+	    intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
+		refclk = dev_priv->lvds_ssc_freq * 1000;
+		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
+			      refclk / 1000);
+	} else if (!IS_GEN2(dev)) {
+		refclk = 96000;
+	} else {
+		refclk = 48000;
+	}
+
+	return refclk;
+}
+
+static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode,
+				      intel_clock_t *clock)
+{
+	/* SDVO TV has fixed PLL values depend on its clock range,
+	   this mirrors vbios setting. */
+	if (adjusted_mode->clock >= 100000
+	    && adjusted_mode->clock < 140500) {
+		clock->p1 = 2;
+		clock->p2 = 10;
+		clock->n = 3;
+		clock->m1 = 16;
+		clock->m2 = 8;
+	} else if (adjusted_mode->clock >= 140500
+		   && adjusted_mode->clock <= 200000) {
+		clock->p1 = 1;
+		clock->p2 = 10;
+		clock->n = 6;
+		clock->m1 = 12;
+		clock->m2 = 8;
+	}
+}
+
+static void i9xx_update_pll_dividers(struct drm_crtc *crtc,
+				     intel_clock_t *clock,
+				     intel_clock_t *reduced_clock)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	u32 fp, fp2 = 0;
+
+	if (IS_PINEVIEW(dev)) {
+		fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2;
+		if (reduced_clock)
+			fp2 = (1 << reduced_clock->n) << 16 |
+				reduced_clock->m1 << 8 | reduced_clock->m2;
+	} else {
+		fp = clock->n << 16 | clock->m1 << 8 | clock->m2;
+		if (reduced_clock)
+			fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 |
+				reduced_clock->m2;
+	}
+
+	I915_WRITE(FP0(pipe), fp);
+
+	intel_crtc->lowfreq_avail = false;
+	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+	    reduced_clock && i915_powersave) {
+		I915_WRITE(FP1(pipe), fp2);
+		intel_crtc->lowfreq_avail = true;
+	} else {
+		I915_WRITE(FP1(pipe), fp);
+	}
+}
+
 static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 			      struct drm_display_mode *mode,
 			      struct drm_display_mode *adjusted_mode,
@@ -4981,7 +5106,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	int plane = intel_crtc->plane;
 	int refclk, num_connectors = 0;
 	intel_clock_t clock, reduced_clock;
-	u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf;
+	u32 dpll, dspcntr, pipeconf;
 	bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
 	bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
 	struct drm_mode_config *mode_config = &dev->mode_config;
@@ -5022,15 +5147,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 		num_connectors++;
 	}
 
-	if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
-		refclk = dev_priv->lvds_ssc_freq * 1000;
-		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
-			      refclk / 1000);
-	} else if (!IS_GEN2(dev)) {
-		refclk = 96000;
-	} else {
-		refclk = 48000;
-	}
+	refclk = i9xx_get_refclk(crtc, num_connectors);
 
 	/*
 	 * Returns a set of divisors for the desired target clock with the given
@@ -5038,7 +5155,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
 	limit = intel_limit(crtc, refclk);
-	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
+	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
+			     &clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
 		return -EINVAL;
@@ -5048,53 +5166,24 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	intel_crtc_update_cursor(crtc, true);
 
 	if (is_lvds && dev_priv->lvds_downclock_avail) {
+		/*
+		 * Ensure we match the reduced clock's P to the target clock.
+		 * If the clocks don't match, we can't switch the display clock
+		 * by using the FP0/FP1. In such case we will disable the LVDS
+		 * downclock feature.
+		*/
 		has_reduced_clock = limit->find_pll(limit, crtc,
 						    dev_priv->lvds_downclock,
 						    refclk,
+						    &clock,
 						    &reduced_clock);
-		if (has_reduced_clock && (clock.p != reduced_clock.p)) {
-			/*
-			 * If the different P is found, it means that we can't
-			 * switch the display clock by using the FP0/FP1.
-			 * In such case we will disable the LVDS downclock
-			 * feature.
-			 */
-			DRM_DEBUG_KMS("Different P is found for "
-				      "LVDS clock/downclock\n");
-			has_reduced_clock = 0;
-		}
-	}
-	/* SDVO TV has fixed PLL values depend on its clock range,
-	   this mirrors vbios setting. */
-	if (is_sdvo && is_tv) {
-		if (adjusted_mode->clock >= 100000
-		    && adjusted_mode->clock < 140500) {
-			clock.p1 = 2;
-			clock.p2 = 10;
-			clock.n = 3;
-			clock.m1 = 16;
-			clock.m2 = 8;
-		} else if (adjusted_mode->clock >= 140500
-			   && adjusted_mode->clock <= 200000) {
-			clock.p1 = 1;
-			clock.p2 = 10;
-			clock.n = 6;
-			clock.m1 = 12;
-			clock.m2 = 8;
-		}
 	}
 
-	if (IS_PINEVIEW(dev)) {
-		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
-		if (has_reduced_clock)
-			fp2 = (1 << reduced_clock.n) << 16 |
-				reduced_clock.m1 << 8 | reduced_clock.m2;
-	} else {
-		fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
-		if (has_reduced_clock)
-			fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
-				reduced_clock.m2;
-	}
+	if (is_sdvo && is_tv)
+		i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock);
+
+	i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ?
+				 &reduced_clock : NULL);
 
 	dpll = DPLL_VGA_MODE_DIS;
 
@@ -5168,8 +5257,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	/* Set up the display plane register */
 	dspcntr = DISPPLANE_GAMMA_ENABLE;
 
-	/* Ironlake's plane is forced to pipe, bit 24 is to
-	   enable color space conversion */
 	if (pipe == 0)
 		dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
 	else
@@ -5204,7 +5291,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 	drm_mode_debug_printmodeline(mode);
 
-	I915_WRITE(FP0(pipe), fp);
 	I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
 
 	POSTING_READ(DPLL(pipe));
@@ -5291,17 +5377,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
 		I915_WRITE(DPLL(pipe), dpll);
 	}
 
-	intel_crtc->lowfreq_avail = false;
-	if (is_lvds && has_reduced_clock && i915_powersave) {
-		I915_WRITE(FP1(pipe), fp2);
-		intel_crtc->lowfreq_avail = true;
-		if (HAS_PIPE_CXSR(dev)) {
+	if (HAS_PIPE_CXSR(dev)) {
+		if (intel_crtc->lowfreq_avail) {
 			DRM_DEBUG_KMS("enabling CxSR downclocking\n");
 			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
-		}
-	} else {
-		I915_WRITE(FP1(pipe), fp);
-		if (HAS_PIPE_CXSR(dev)) {
+		} else {
 			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
 			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
 		}
@@ -5584,7 +5664,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 	 */
 	limit = intel_limit(crtc, refclk);
-	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
+	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL,
+			     &clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
 		return -EINVAL;
@@ -5594,21 +5675,17 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 	intel_crtc_update_cursor(crtc, true);
 
 	if (is_lvds && dev_priv->lvds_downclock_avail) {
+		/*
+		 * Ensure we match the reduced clock's P to the target clock.
+		 * If the clocks don't match, we can't switch the display clock
+		 * by using the FP0/FP1. In such case we will disable the LVDS
+		 * downclock feature.
+		*/
 		has_reduced_clock = limit->find_pll(limit, crtc,
 						    dev_priv->lvds_downclock,
 						    refclk,
+						    &clock,
 						    &reduced_clock);
-		if (has_reduced_clock && (clock.p != reduced_clock.p)) {
-			/*
-			 * If the different P is found, it means that we can't
-			 * switch the display clock by using the FP0/FP1.
-			 * In such case we will disable the LVDS downclock
-			 * feature.
-			 */
-			DRM_DEBUG_KMS("Different P is found for "
-				      "LVDS clock/downclock\n");
-			has_reduced_clock = 0;
-		}
 	}
 	/* SDVO TV has fixed PLL values depend on its clock range,
 	   this mirrors vbios setting. */
@@ -6077,15 +6154,18 @@ static void ironlake_write_eld(struct drm_connector *connector,
 	uint32_t i;
 	int len;
 	int hdmiw_hdmiedid;
+	int aud_config;
 	int aud_cntl_st;
 	int aud_cntrl_st2;
 
 	if (HAS_PCH_IBX(connector->dev)) {
 		hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A;
+		aud_config = IBX_AUD_CONFIG_A;
 		aud_cntl_st = IBX_AUD_CNTL_ST_A;
 		aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
 	} else {
 		hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A;
+		aud_config = CPT_AUD_CONFIG_A;
 		aud_cntl_st = CPT_AUD_CNTL_ST_A;
 		aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
 	}
@@ -6093,6 +6173,7 @@ static void ironlake_write_eld(struct drm_connector *connector,
 	i = to_intel_crtc(crtc)->pipe;
 	hdmiw_hdmiedid += i * 0x100;
 	aud_cntl_st += i * 0x100;
+	aud_config += i * 0x100;
 
 	DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i));
 
@@ -6112,7 +6193,9 @@ static void ironlake_write_eld(struct drm_connector *connector,
 	if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) {
 		DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n");
 		eld[5] |= (1 << 2);	/* Conn_Type, 0x1 = DisplayPort */
-	}
+		I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */
+	} else
+		I915_WRITE(aud_config, 0);
 
 	if (intel_eld_uptodate(connector,
 			       aud_cntrl_st2, eldv,
@@ -7088,7 +7171,7 @@ static void intel_unpin_work_fn(struct work_struct *__work)
 		container_of(__work, struct intel_unpin_work, work);
 
 	mutex_lock(&work->dev->struct_mutex);
-	i915_gem_object_unpin(work->old_fb_obj);
+	intel_unpin_fb_obj(work->old_fb_obj);
 	drm_gem_object_unreference(&work->pending_flip_obj->base);
 	drm_gem_object_unreference(&work->old_fb_obj->base);
 
@@ -7238,7 +7321,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
 		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
 	OUT_RING(fb->pitches[0]);
 	OUT_RING(obj->gtt_offset + offset);
-	OUT_RING(MI_NOOP);
+	OUT_RING(0); /* aux display base address, unused */
 	ADVANCE_LP_RING();
 out:
 	return ret;
@@ -7830,7 +7913,8 @@ int intel_framebuffer_init(struct drm_device *dev,
 	case DRM_FORMAT_VYUY:
 		break;
 	default:
-		DRM_ERROR("unsupported pixel format\n");
+		DRM_DEBUG_KMS("unsupported pixel format %u\n",
+				mode_cmd->pixel_format);
 		return -EINVAL;
 	}
 
@@ -9007,6 +9091,9 @@ void intel_modeset_init(struct drm_device *dev)
 	dev->mode_config.min_width = 0;
 	dev->mode_config.min_height = 0;
 
+	dev->mode_config.preferred_depth = 24;
+	dev->mode_config.prefer_shadow = 1;
+
 	dev->mode_config.funcs = (void *)&intel_mode_funcs;
 
 	intel_init_quirks(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 94f860c..39eccf9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -352,7 +352,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 	int recv_bytes;
 	uint32_t status;
 	uint32_t aux_clock_divider;
-	int try, precharge;
+	int try, precharge = 5;
 
 	intel_dp_check_edp(intel_dp);
 	/* The clock divider is based off the hrawclk,
@@ -368,15 +368,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 		else
 			aux_clock_divider = 225; /* eDP input clock at 450Mhz */
 	} else if (HAS_PCH_SPLIT(dev))
-		aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
+		aux_clock_divider = 63; /* IRL input clock fixed at 125Mhz */
 	else
 		aux_clock_divider = intel_hrawclk(dev) / 2;
 
-	if (IS_GEN6(dev))
-		precharge = 3;
-	else
-		precharge = 5;
-
 	/* Try to wait for any previous AUX channel activity */
 	for (try = 0; try < 3; try++) {
 		status = I915_READ(ch_ctl);
@@ -421,6 +416,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 			   DP_AUX_CH_CTL_DONE |
 			   DP_AUX_CH_CTL_TIME_OUT_ERROR |
 			   DP_AUX_CH_CTL_RECEIVE_ERROR);
+
+		if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR |
+			      DP_AUX_CH_CTL_RECEIVE_ERROR))
+			continue;
 		if (status & DP_AUX_CH_CTL_DONE)
 			break;
 	}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1348705..9cec6c3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -374,6 +374,7 @@ extern void intel_init_emon(struct drm_device *dev);
 extern int intel_pin_and_fence_fb_obj(struct drm_device *dev,
 				      struct drm_i915_gem_object *obj,
 				      struct intel_ring_buffer *pipelined);
+extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj);
 
 extern int intel_framebuffer_init(struct drm_device *dev,
 				  struct intel_framebuffer *ifb,
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 571375a..2d87669 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -152,11 +152,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
 	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
 	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
 
-	info->pixmap.size = 64*1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
+	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
 	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
 		      fb->width, fb->height,
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index d30cccc..03573e0 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -37,7 +37,7 @@
 
 /* Intel GPIO access functions */
 
-#define I2C_RISEFALL_TIME 20
+#define I2C_RISEFALL_TIME 10
 
 static inline struct intel_gmbus *
 to_intel_gmbus(struct i2c_adapter *i2c)
@@ -375,7 +375,7 @@ int intel_setup_gmbus(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int ret, i;
 
-	dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS,
+	dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus),
 				  GFP_KERNEL);
 	if (dev_priv->gmbus == NULL)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index be2c6fe..961f75d 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -83,10 +83,10 @@ int intel_ddc_get_modes(struct drm_connector *connector,
 	return ret;
 }
 
-static const char *force_audio_names[] = {
-	"off",
-	"auto",
-	"on",
+static const struct drm_prop_enum_list force_audio_names[] = {
+	{ -1, "off" },
+	{  0, "auto" },
+	{  1, "on" },
 };
 
 void
@@ -95,27 +95,24 @@ intel_attach_force_audio_property(struct drm_connector *connector)
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_property *prop;
-	int i;
 
 	prop = dev_priv->force_audio_property;
 	if (prop == NULL) {
-		prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+		prop = drm_property_create_enum(dev, 0,
 					   "audio",
+					   force_audio_names,
 					   ARRAY_SIZE(force_audio_names));
 		if (prop == NULL)
 			return;
 
-		for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
-			drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
-
 		dev_priv->force_audio_property = prop;
 	}
 	drm_connector_attach_property(connector, prop, 0);
 }
 
-static const char *broadcast_rgb_names[] = {
-	"Full",
-	"Limited 16:235",
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+	{ 0, "Full" },
+	{ 1, "Limited 16:235" },
 };
 
 void
@@ -124,19 +121,16 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector)
 	struct drm_device *dev = connector->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_property *prop;
-	int i;
 
 	prop = dev_priv->broadcast_rgb_property;
 	if (prop == NULL) {
-		prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
 					   "Broadcast RGB",
+					   broadcast_rgb_names,
 					   ARRAY_SIZE(broadcast_rgb_names));
 		if (prop == NULL)
 			return;
 
-		for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
-			drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
-
 		dev_priv->broadcast_rgb_property = prop;
 	}
 
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index cdf17d4..23a543c 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -227,7 +227,8 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
 	}
 	overlay->last_flip_req = request->seqno;
 	overlay->flip_tail = tail;
-	ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req);
+	ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req,
+				true);
 	if (ret)
 		return ret;
 
@@ -448,7 +449,8 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
 	if (overlay->last_flip_req == 0)
 		return 0;
 
-	ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req);
+	ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req,
+				true);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 04d79fd..c935cda 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -141,8 +141,8 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv)
 			dev_priv->saveBLC_PWM_CTL2 = val;
 		} else if (val == 0) {
 			I915_WRITE(BLC_PWM_PCH_CTL2,
-				   dev_priv->saveBLC_PWM_CTL);
-			val = dev_priv->saveBLC_PWM_CTL;
+				   dev_priv->saveBLC_PWM_CTL2);
+			val = dev_priv->saveBLC_PWM_CTL2;
 		}
 	} else {
 		val = I915_READ(BLC_PWM_CTL);
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1ab842c..4956f1b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -399,8 +399,6 @@ static int init_render_ring(struct intel_ring_buffer *ring)
 
 	if (INTEL_INFO(dev)->gen > 3) {
 		int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
-		if (IS_GEN6(dev) || IS_GEN7(dev))
-			mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
 		I915_WRITE(MI_MODE, mode);
 		if (IS_GEN7(dev))
 			I915_WRITE(GFX_MODE_GEN7,
@@ -744,13 +742,13 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
 	 */
 	if (IS_GEN7(dev)) {
 		switch (ring->id) {
-		case RING_RENDER:
+		case RCS:
 			mmio = RENDER_HWS_PGA_GEN7;
 			break;
-		case RING_BLT:
+		case BCS:
 			mmio = BLT_HWS_PGA_GEN7;
 			break;
-		case RING_BSD:
+		case VCS:
 			mmio = BSD_HWS_PGA_GEN7;
 			break;
 		}
@@ -1212,7 +1210,7 @@ void intel_ring_advance(struct intel_ring_buffer *ring)
 
 static const struct intel_ring_buffer render_ring = {
 	.name			= "render ring",
-	.id			= RING_RENDER,
+	.id			= RCS,
 	.mmio_base		= RENDER_RING_BASE,
 	.size			= 32 * PAGE_SIZE,
 	.init			= init_render_ring,
@@ -1235,7 +1233,7 @@ static const struct intel_ring_buffer render_ring = {
 
 static const struct intel_ring_buffer bsd_ring = {
 	.name                   = "bsd ring",
-	.id			= RING_BSD,
+	.id			= VCS,
 	.mmio_base		= BSD_RING_BASE,
 	.size			= 32 * PAGE_SIZE,
 	.init			= init_ring_common,
@@ -1345,7 +1343,7 @@ gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring)
 /* ring buffer for Video Codec for Gen6+ */
 static const struct intel_ring_buffer gen6_bsd_ring = {
 	.name			= "gen6 bsd ring",
-	.id			= RING_BSD,
+	.id			= VCS,
 	.mmio_base		= GEN6_BSD_RING_BASE,
 	.size			= 32 * PAGE_SIZE,
 	.init			= init_ring_common,
@@ -1381,79 +1379,13 @@ blt_ring_put_irq(struct intel_ring_buffer *ring)
 			  GEN6_BLITTER_USER_INTERRUPT);
 }
 
-
-/* Workaround for some stepping of SNB,
- * each time when BLT engine ring tail moved,
- * the first command in the ring to be parsed
- * should be MI_BATCH_BUFFER_START
- */
-#define NEED_BLT_WORKAROUND(dev) \
-	(IS_GEN6(dev) && (dev->pdev->revision < 8))
-
-static inline struct drm_i915_gem_object *
-to_blt_workaround(struct intel_ring_buffer *ring)
-{
-	return ring->private;
-}
-
-static int blt_ring_init(struct intel_ring_buffer *ring)
-{
-	if (NEED_BLT_WORKAROUND(ring->dev)) {
-		struct drm_i915_gem_object *obj;
-		u32 *ptr;
-		int ret;
-
-		obj = i915_gem_alloc_object(ring->dev, 4096);
-		if (obj == NULL)
-			return -ENOMEM;
-
-		ret = i915_gem_object_pin(obj, 4096, true);
-		if (ret) {
-			drm_gem_object_unreference(&obj->base);
-			return ret;
-		}
-
-		ptr = kmap(obj->pages[0]);
-		*ptr++ = MI_BATCH_BUFFER_END;
-		*ptr++ = MI_NOOP;
-		kunmap(obj->pages[0]);
-
-		ret = i915_gem_object_set_to_gtt_domain(obj, false);
-		if (ret) {
-			i915_gem_object_unpin(obj);
-			drm_gem_object_unreference(&obj->base);
-			return ret;
-		}
-
-		ring->private = obj;
-	}
-
-	return init_ring_common(ring);
-}
-
-static int blt_ring_begin(struct intel_ring_buffer *ring,
-			  int num_dwords)
-{
-	if (ring->private) {
-		int ret = intel_ring_begin(ring, num_dwords+2);
-		if (ret)
-			return ret;
-
-		intel_ring_emit(ring, MI_BATCH_BUFFER_START);
-		intel_ring_emit(ring, to_blt_workaround(ring)->gtt_offset);
-
-		return 0;
-	} else
-		return intel_ring_begin(ring, 4);
-}
-
 static int blt_ring_flush(struct intel_ring_buffer *ring,
 			  u32 invalidate, u32 flush)
 {
 	uint32_t cmd;
 	int ret;
 
-	ret = blt_ring_begin(ring, 4);
+	ret = intel_ring_begin(ring, 4);
 	if (ret)
 		return ret;
 
@@ -1468,22 +1400,12 @@ static int blt_ring_flush(struct intel_ring_buffer *ring,
 	return 0;
 }
 
-static void blt_ring_cleanup(struct intel_ring_buffer *ring)
-{
-	if (!ring->private)
-		return;
-
-	i915_gem_object_unpin(ring->private);
-	drm_gem_object_unreference(ring->private);
-	ring->private = NULL;
-}
-
 static const struct intel_ring_buffer gen6_blt_ring = {
 	.name			= "blt ring",
-	.id			= RING_BLT,
+	.id			= BCS,
 	.mmio_base		= BLT_RING_BASE,
 	.size			= 32 * PAGE_SIZE,
-	.init			= blt_ring_init,
+	.init			= init_ring_common,
 	.write_tail		= ring_write_tail,
 	.flush			= blt_ring_flush,
 	.add_request		= gen6_add_request,
@@ -1491,7 +1413,6 @@ static const struct intel_ring_buffer gen6_blt_ring = {
 	.irq_get		= blt_ring_get_irq,
 	.irq_put		= blt_ring_put_irq,
 	.dispatch_execbuffer	= gen6_ring_dispatch_execbuffer,
-	.cleanup		= blt_ring_cleanup,
 	.sync_to		= gen6_blt_ring_sync_to,
 	.semaphore_register	= {MI_SEMAPHORE_SYNC_BR,
 				   MI_SEMAPHORE_SYNC_BV,
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 68281c9..c8b9cc0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -1,13 +1,6 @@
 #ifndef _INTEL_RINGBUFFER_H_
 #define _INTEL_RINGBUFFER_H_
 
-enum {
-	RCS = 0x0,
-	VCS,
-	BCS,
-	I915_NUM_RINGS,
-};
-
 struct  intel_hw_status_page {
 	u32	__iomem	*page_addr;
 	unsigned int	gfx_addr;
@@ -36,10 +29,11 @@ struct  intel_hw_status_page {
 struct  intel_ring_buffer {
 	const char	*name;
 	enum intel_ring_id {
-		RING_RENDER = 0x1,
-		RING_BSD = 0x2,
-		RING_BLT = 0x4,
+		RCS = 0x0,
+		VCS,
+		BCS,
 	} id;
+#define I915_NUM_RINGS 3
 	u32		mmio_base;
 	void		__iomem *virtual_start;
 	struct		drm_device *dev;
@@ -119,6 +113,12 @@ struct  intel_ring_buffer {
 	void *private;
 };
 
+static inline unsigned
+intel_ring_flag(struct intel_ring_buffer *ring)
+{
+	return 1 << ring->id;
+}
+
 static inline u32
 intel_ring_sync_index(struct intel_ring_buffer *ring,
 		      struct intel_ring_buffer *other)
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index e334ec3..80acc3f 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2277,10 +2277,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
 		intel_sdvo_connector->max_##name = data_value[0]; \
 		intel_sdvo_connector->cur_##name = response; \
 		intel_sdvo_connector->name = \
-			drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \
+			drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
 		if (!intel_sdvo_connector->name) return false; \
-		intel_sdvo_connector->name->values[0] = 0; \
-		intel_sdvo_connector->name->values[1] = data_value[0]; \
 		drm_connector_attach_property(connector, \
 					      intel_sdvo_connector->name, \
 					      intel_sdvo_connector->cur_##name); \
@@ -2314,25 +2312,19 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
 		intel_sdvo_connector->left_margin = data_value[0] - response;
 		intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin;
 		intel_sdvo_connector->left =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "left_margin", 2);
+			drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]);
 		if (!intel_sdvo_connector->left)
 			return false;
 
-		intel_sdvo_connector->left->values[0] = 0;
-		intel_sdvo_connector->left->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      intel_sdvo_connector->left,
 					      intel_sdvo_connector->left_margin);
 
 		intel_sdvo_connector->right =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "right_margin", 2);
+			drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]);
 		if (!intel_sdvo_connector->right)
 			return false;
 
-		intel_sdvo_connector->right->values[0] = 0;
-		intel_sdvo_connector->right->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      intel_sdvo_connector->right,
 					      intel_sdvo_connector->right_margin);
@@ -2356,25 +2348,21 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
 		intel_sdvo_connector->top_margin = data_value[0] - response;
 		intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin;
 		intel_sdvo_connector->top =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "top_margin", 2);
+			drm_property_create_range(dev, 0,
+					    "top_margin", 0, data_value[0]);
 		if (!intel_sdvo_connector->top)
 			return false;
 
-		intel_sdvo_connector->top->values[0] = 0;
-		intel_sdvo_connector->top->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      intel_sdvo_connector->top,
 					      intel_sdvo_connector->top_margin);
 
 		intel_sdvo_connector->bottom =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE,
-					    "bottom_margin", 2);
+			drm_property_create_range(dev, 0,
+					    "bottom_margin", 0, data_value[0]);
 		if (!intel_sdvo_connector->bottom)
 			return false;
 
-		intel_sdvo_connector->bottom->values[0] = 0;
-		intel_sdvo_connector->bottom->values[1] = data_value[0];
 		drm_connector_attach_property(connector,
 					      intel_sdvo_connector->bottom,
 					      intel_sdvo_connector->bottom_margin);
@@ -2403,12 +2391,10 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
 		intel_sdvo_connector->max_dot_crawl = 1;
 		intel_sdvo_connector->cur_dot_crawl = response & 0x1;
 		intel_sdvo_connector->dot_crawl =
-			drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2);
+			drm_property_create_range(dev, 0, "dot_crawl", 0, 1);
 		if (!intel_sdvo_connector->dot_crawl)
 			return false;
 
-		intel_sdvo_connector->dot_crawl->values[0] = 0;
-		intel_sdvo_connector->dot_crawl->values[1] = 1;
 		drm_connector_attach_property(connector,
 					      intel_sdvo_connector->dot_crawl,
 					      intel_sdvo_connector->cur_dot_crawl);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 2288abf..98444ab 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -501,7 +501,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 			intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe);
 			mutex_lock(&dev->struct_mutex);
 		}
-		i915_gem_object_unpin(old_obj);
+		intel_unpin_fb_obj(old_obj);
 	}
 
 out_unlock:
@@ -528,7 +528,7 @@ intel_disable_plane(struct drm_plane *plane)
 		goto out;
 
 	mutex_lock(&dev->struct_mutex);
-	i915_gem_object_unpin(intel_plane->obj);
+	intel_unpin_fb_obj(intel_plane->obj);
 	intel_plane->obj = NULL;
 	mutex_unlock(&dev->struct_mutex);
 out:
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index 5ccb65de..507aa3d 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -403,6 +403,8 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags)
 	dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
 	dev_priv->chipset = flags;
 
+	pci_set_master(dev->pdev);
+
 	dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
 	dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 795a9e3..5565e50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -155,20 +155,20 @@ static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
 };
 
 
-struct drm_prop_enum_list {
+struct nouveau_drm_prop_enum_list {
 	u8 gen_mask;
 	int type;
 	char *name;
 };
 
-static struct drm_prop_enum_list underscan[] = {
+static struct nouveau_drm_prop_enum_list underscan[] = {
 	{ 6, UNDERSCAN_AUTO, "auto" },
 	{ 6, UNDERSCAN_OFF, "off" },
 	{ 6, UNDERSCAN_ON, "on" },
 	{}
 };
 
-static struct drm_prop_enum_list dither_mode[] = {
+static struct nouveau_drm_prop_enum_list dither_mode[] = {
 	{ 7, DITHERING_MODE_AUTO, "auto" },
 	{ 7, DITHERING_MODE_OFF, "off" },
 	{ 1, DITHERING_MODE_ON, "on" },
@@ -178,7 +178,7 @@ static struct drm_prop_enum_list dither_mode[] = {
 	{}
 };
 
-static struct drm_prop_enum_list dither_depth[] = {
+static struct nouveau_drm_prop_enum_list dither_depth[] = {
 	{ 6, DITHERING_DEPTH_AUTO, "auto" },
 	{ 6, DITHERING_DEPTH_6BPC, "6 bpc" },
 	{ 6, DITHERING_DEPTH_8BPC, "8 bpc" },
@@ -186,7 +186,7 @@ static struct drm_prop_enum_list dither_depth[] = {
 };
 
 #define PROP_ENUM(p,gen,n,list) do {                                           \
-	struct drm_prop_enum_list *l = (list);                                 \
+	struct nouveau_drm_prop_enum_list *l = (list);                         \
 	int c = 0;                                                             \
 	while (l->gen_mask) {                                                  \
 		if (l->gen_mask & (1 << (gen)))                                \
@@ -281,16 +281,10 @@ nouveau_display_create(struct drm_device *dev)
 	PROP_ENUM(disp->underscan_property, gen, "underscan", underscan);
 
 	disp->underscan_hborder_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "underscan hborder", 2);
-	disp->underscan_hborder_property->values[0] = 0;
-	disp->underscan_hborder_property->values[1] = 128;
+		drm_property_create_range(dev, 0, "underscan hborder", 0, 128);
 
 	disp->underscan_vborder_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE,
-				    "underscan vborder", 2);
-	disp->underscan_vborder_property->values[0] = 0;
-	disp->underscan_vborder_property->values[1] = 128;
+		drm_property_create_range(dev, 0, "underscan vborder", 0, 128);
 
 	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
 	dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1);
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 9892218..8113e92 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -381,11 +381,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
 		goto out_unref;
 	}
 
-	info->pixmap.size = 64*1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
+	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
 	mutex_unlock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index f80c5e0..912839c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -1002,6 +1002,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
 	dev->dev_private = dev_priv;
 	dev_priv->dev = dev;
 
+	pci_set_master(dev->pdev);
+
 	dev_priv->flags = flags & NOUVEAU_FLAGS;
 
 	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index 6a5f439..88718fa 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -85,6 +85,7 @@ static struct drm_driver driver = {
 
 int r128_driver_load(struct drm_device *dev, unsigned long flags)
 {
+	pci_set_master(dev->pdev);
 	return drm_vblank_init(dev, 1);
 }
 
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 2139fe8..8410415 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
 	r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
 	evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
 	radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \
-	radeon_semaphore.o radeon_sa.o
+	radeon_semaphore.o radeon_sa.o atombios_i2c.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 742f17f..72672ea 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1031,6 +1031,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 	struct radeon_bo *rbo;
 	uint64_t fb_location;
 	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
+	unsigned bankw, bankh, mtaspect, tile_split;
 	u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
 	u32 tmp, viewport_w, viewport_h;
 	int r;
@@ -1121,20 +1122,13 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
 			break;
 		}
 
-		switch ((tmp & 0xf000) >> 12) {
-		case 0: /* 1KB rows */
-		default:
-			fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
-			break;
-		case 1: /* 2KB rows */
-			fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
-			break;
-		case 2: /* 4KB rows */
-			fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
-			break;
-		}
-
 		fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
+
+		evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
+		fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
+		fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
+		fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
+		fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
 	} else if (tiling_flags & RADEON_TILING_MICRO)
 		fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
 
diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c
new file mode 100644
index 0000000..44d87b6
--- /dev/null
+++ b/drivers/gpu/drm/radeon/atombios_i2c.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ *
+ */
+#include "drmP.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+#include "atom.h"
+
+#define TARGET_HW_I2C_CLOCK 50
+
+/* these are a limitation of ProcessI2cChannelTransaction not the hw */
+#define ATOM_MAX_HW_I2C_WRITE 2
+#define ATOM_MAX_HW_I2C_READ  255
+
+static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
+				 u8 slave_addr, u8 flags,
+				 u8 *buf, u8 num)
+{
+	struct drm_device *dev = chan->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args;
+	int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction);
+	unsigned char *base;
+	u16 out;
+
+	memset(&args, 0, sizeof(args));
+
+	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
+
+	if (flags & HW_I2C_WRITE) {
+		if (num > ATOM_MAX_HW_I2C_WRITE) {
+			DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num);
+			return -EINVAL;
+		}
+		memcpy(&out, buf, num);
+		args.lpI2CDataOut = cpu_to_le16(out);
+	} else {
+		if (num > ATOM_MAX_HW_I2C_READ) {
+			DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num);
+			return -EINVAL;
+		}
+	}
+
+	args.ucI2CSpeed = TARGET_HW_I2C_CLOCK;
+	args.ucRegIndex = 0;
+	args.ucTransBytes = num;
+	args.ucSlaveAddr = slave_addr << 1;
+	args.ucLineNumber = chan->rec.i2c_id;
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+	/* error */
+	if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
+		DRM_DEBUG_KMS("hw_i2c error\n");
+		return -EIO;
+	}
+
+	if (!(flags & HW_I2C_WRITE))
+		memcpy(buf, base, num);
+
+	return 0;
+}
+
+int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
+			    struct i2c_msg *msgs, int num)
+{
+	struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
+	struct i2c_msg *p;
+	int i, remaining, current_count, buffer_offset, max_bytes, ret;
+	u8 buf = 0, flags;
+
+	/* check for bus probe */
+	p = &msgs[0];
+	if ((num == 1) && (p->len == 0)) {
+		ret = radeon_process_i2c_ch(i2c,
+					    p->addr, HW_I2C_WRITE,
+					    &buf, 1);
+		if (ret)
+			return ret;
+		else
+			return num;
+	}
+
+	for (i = 0; i < num; i++) {
+		p = &msgs[i];
+		remaining = p->len;
+		buffer_offset = 0;
+		/* max_bytes are a limitation of ProcessI2cChannelTransaction not the hw */
+		if (p->flags & I2C_M_RD) {
+			max_bytes = ATOM_MAX_HW_I2C_READ;
+			flags = HW_I2C_READ;
+		} else {
+			max_bytes = ATOM_MAX_HW_I2C_WRITE;
+			flags = HW_I2C_WRITE;
+		}
+		while (remaining) {
+			if (remaining > max_bytes)
+				current_count = max_bytes;
+			else
+				current_count = remaining;
+			ret = radeon_process_i2c_ch(i2c,
+						    p->addr, flags,
+						    &p->buf[buffer_offset], current_count);
+			if (ret)
+				return ret;
+			remaining -= current_count;
+			buffer_offset += current_count;
+		}
+	}
+
+	return num;
+}
+
+u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 9be353b..1a816ea 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -43,6 +43,37 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
 extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
 				     int ring, u32 cp_int_cntl);
 
+void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
+			     unsigned *bankh, unsigned *mtaspect,
+			     unsigned *tile_split)
+{
+	*bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
+	*bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
+	*mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
+	*tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
+	switch (*bankw) {
+	default:
+	case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break;
+	case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break;
+	case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break;
+	case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break;
+	}
+	switch (*bankh) {
+	default:
+	case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break;
+	case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break;
+	case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break;
+	case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break;
+	}
+	switch (*mtaspect) {
+	default:
+	case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break;
+	case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break;
+	case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break;
+	case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break;
+	}
+}
+
 void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
 {
 	u16 ctl, v;
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index 2379849..4e83fdc 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -32,17 +32,7 @@
 #include "evergreend.h"
 #include "evergreen_blit_shaders.h"
 #include "cayman_blit_shaders.h"
-
-#define DI_PT_RECTLIST        0x11
-#define DI_INDEX_SIZE_16_BIT  0x0
-#define DI_SRC_SEL_AUTO_INDEX 0x2
-
-#define FMT_8                 0x1
-#define FMT_5_6_5             0x8
-#define FMT_8_8_8_8           0x1a
-#define COLOR_8               0x1
-#define COLOR_5_6_5           0x8
-#define COLOR_8_8_8_8         0x1a
+#include "radeon_blit_common.h"
 
 /* emits 17 */
 static void
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 8e8cd85..49203b6 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -31,6 +31,9 @@
 #include "evergreen_reg_safe.h"
 #include "cayman_reg_safe.h"
 
+#define MAX(a,b)                   (((a)>(b))?(a):(b))
+#define MIN(a,b)                   (((a)<(b))?(a):(b))
+
 static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
 					  struct radeon_cs_reloc **cs_reloc);
 
@@ -54,14 +57,20 @@ struct evergreen_cs_track {
 	u32			cb_color_dim[12];
 	u32			cb_color_pitch[12];
 	u32			cb_color_slice[12];
+	u32			cb_color_attrib[12];
 	u32			cb_color_cmask_slice[8];
 	u32			cb_color_fmask_slice[8];
 	u32			cb_target_mask;
 	u32			cb_shader_mask;
 	u32			vgt_strmout_config;
 	u32			vgt_strmout_buffer_config;
+	struct radeon_bo	*vgt_strmout_bo[4];
+	u64			vgt_strmout_bo_mc[4];
+	u32			vgt_strmout_bo_offset[4];
+	u32			vgt_strmout_size[4];
 	u32			db_depth_control;
 	u32			db_depth_view;
+	u32			db_depth_slice;
 	u32			db_depth_size;
 	u32			db_depth_size_idx;
 	u32			db_z_info;
@@ -103,19 +112,6 @@ static u32 evergreen_cs_get_num_banks(u32 nbanks)
 	}
 }
 
-static u32 evergreen_cs_get_tile_split(u32 row_size)
-{
-	switch (row_size) {
-	case 1:
-	default:
-		return ADDR_SURF_TILE_SPLIT_1KB;
-	case 2:
-		return ADDR_SURF_TILE_SPLIT_2KB;
-	case 4:
-		return ADDR_SURF_TILE_SPLIT_4KB;
-	}
-}
-
 static void evergreen_cs_track_init(struct evergreen_cs_track *track)
 {
 	int i;
@@ -132,7 +128,7 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
 		track->cb_color_bo[i] = NULL;
 		track->cb_color_bo_offset[i] = 0xFFFFFFFF;
 		track->cb_color_info[i] = 0;
-		track->cb_color_view[i] = 0;
+		track->cb_color_view[i] = 0xFFFFFFFF;
 		track->cb_color_pitch_idx[i] = 0;
 		track->cb_color_slice_idx[i] = 0;
 		track->cb_color_dim[i] = 0;
@@ -159,19 +155,704 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track)
 	track->db_s_write_offset = 0xFFFFFFFF;
 	track->db_s_read_bo = NULL;
 	track->db_s_write_bo = NULL;
+
+	for (i = 0; i < 4; i++) {
+		track->vgt_strmout_size[i] = 0;
+		track->vgt_strmout_bo[i] = NULL;
+		track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF;
+		track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF;
+	}
 }
 
-static int evergreen_cs_track_check(struct radeon_cs_parser *p)
+struct eg_surface {
+	/* value gathered from cs */
+	unsigned	nbx;
+	unsigned	nby;
+	unsigned	format;
+	unsigned	mode;
+	unsigned	nbanks;
+	unsigned	bankw;
+	unsigned	bankh;
+	unsigned	tsplit;
+	unsigned	mtilea;
+	unsigned	nsamples;
+	/* output value */
+	unsigned	bpe;
+	unsigned	layer_size;
+	unsigned	palign;
+	unsigned	halign;
+	unsigned long	base_align;
+};
+
+static int evergreen_surface_check_linear(struct radeon_cs_parser *p,
+					  struct eg_surface *surf,
+					  const char *prefix)
+{
+	surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples;
+	surf->base_align = surf->bpe;
+	surf->palign = 1;
+	surf->halign = 1;
+	return 0;
+}
+
+static int evergreen_surface_check_linear_aligned(struct radeon_cs_parser *p,
+						  struct eg_surface *surf,
+						  const char *prefix)
+{
+	struct evergreen_cs_track *track = p->track;
+	unsigned palign;
+
+	palign = MAX(64, track->group_size / surf->bpe);
+	surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples;
+	surf->base_align = track->group_size;
+	surf->palign = palign;
+	surf->halign = 1;
+	if (surf->nbx & (palign - 1)) {
+		if (prefix) {
+			dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n",
+				 __func__, __LINE__, prefix, surf->nbx, palign);
+		}
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int evergreen_surface_check_1d(struct radeon_cs_parser *p,
+				      struct eg_surface *surf,
+				      const char *prefix)
+{
+	struct evergreen_cs_track *track = p->track;
+	unsigned palign;
+
+	palign = track->group_size / (8 * surf->bpe * surf->nsamples);
+	palign = MAX(8, palign);
+	surf->layer_size = surf->nbx * surf->nby * surf->bpe;
+	surf->base_align = track->group_size;
+	surf->palign = palign;
+	surf->halign = 8;
+	if ((surf->nbx & (palign - 1))) {
+		if (prefix) {
+			dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d (%d %d %d)\n",
+				 __func__, __LINE__, prefix, surf->nbx, palign,
+				 track->group_size, surf->bpe, surf->nsamples);
+		}
+		return -EINVAL;
+	}
+	if ((surf->nby & (8 - 1))) {
+		if (prefix) {
+			dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with 8\n",
+				 __func__, __LINE__, prefix, surf->nby);
+		}
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
+				      struct eg_surface *surf,
+				      const char *prefix)
+{
+	struct evergreen_cs_track *track = p->track;
+	unsigned palign, halign, tileb, slice_pt;
+
+	tileb = 64 * surf->bpe * surf->nsamples;
+	palign = track->group_size / (8 * surf->bpe * surf->nsamples);
+	palign = MAX(8, palign);
+	slice_pt = 1;
+	if (tileb > surf->tsplit) {
+		slice_pt = tileb / surf->tsplit;
+	}
+	tileb = tileb / slice_pt;
+	/* macro tile width & height */
+	palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
+	halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
+	surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt;
+	surf->base_align = (palign / 8) * (halign / 8) * tileb;
+	surf->palign = palign;
+	surf->halign = halign;
+
+	if ((surf->nbx & (palign - 1))) {
+		if (prefix) {
+			dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n",
+				 __func__, __LINE__, prefix, surf->nbx, palign);
+		}
+		return -EINVAL;
+	}
+	if ((surf->nby & (halign - 1))) {
+		if (prefix) {
+			dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with %d\n",
+				 __func__, __LINE__, prefix, surf->nby, halign);
+		}
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int evergreen_surface_check(struct radeon_cs_parser *p,
+				   struct eg_surface *surf,
+				   const char *prefix)
+{
+	/* some common value computed here */
+	surf->bpe = r600_fmt_get_blocksize(surf->format);
+
+	switch (surf->mode) {
+	case ARRAY_LINEAR_GENERAL:
+		return evergreen_surface_check_linear(p, surf, prefix);
+	case ARRAY_LINEAR_ALIGNED:
+		return evergreen_surface_check_linear_aligned(p, surf, prefix);
+	case ARRAY_1D_TILED_THIN1:
+		return evergreen_surface_check_1d(p, surf, prefix);
+	case ARRAY_2D_TILED_THIN1:
+		return evergreen_surface_check_2d(p, surf, prefix);
+	default:
+		dev_warn(p->dev, "%s:%d invalid array mode %d\n",
+				__func__, __LINE__, surf->mode);
+		return -EINVAL;
+	}
+	return -EINVAL;
+}
+
+static int evergreen_surface_value_conv_check(struct radeon_cs_parser *p,
+					      struct eg_surface *surf,
+					      const char *prefix)
+{
+	switch (surf->mode) {
+	case ARRAY_2D_TILED_THIN1:
+		break;
+	case ARRAY_LINEAR_GENERAL:
+	case ARRAY_LINEAR_ALIGNED:
+	case ARRAY_1D_TILED_THIN1:
+		return 0;
+	default:
+		dev_warn(p->dev, "%s:%d invalid array mode %d\n",
+				__func__, __LINE__, surf->mode);
+		return -EINVAL;
+	}
+
+	switch (surf->nbanks) {
+	case 0: surf->nbanks = 2; break;
+	case 1: surf->nbanks = 4; break;
+	case 2: surf->nbanks = 8; break;
+	case 3: surf->nbanks = 16; break;
+	default:
+		dev_warn(p->dev, "%s:%d %s invalid number of banks %d\n",
+			 __func__, __LINE__, prefix, surf->nbanks);
+		return -EINVAL;
+	}
+	switch (surf->bankw) {
+	case 0: surf->bankw = 1; break;
+	case 1: surf->bankw = 2; break;
+	case 2: surf->bankw = 4; break;
+	case 3: surf->bankw = 8; break;
+	default:
+		dev_warn(p->dev, "%s:%d %s invalid bankw %d\n",
+			 __func__, __LINE__, prefix, surf->bankw);
+		return -EINVAL;
+	}
+	switch (surf->bankh) {
+	case 0: surf->bankh = 1; break;
+	case 1: surf->bankh = 2; break;
+	case 2: surf->bankh = 4; break;
+	case 3: surf->bankh = 8; break;
+	default:
+		dev_warn(p->dev, "%s:%d %s invalid bankh %d\n",
+			 __func__, __LINE__, prefix, surf->bankh);
+		return -EINVAL;
+	}
+	switch (surf->mtilea) {
+	case 0: surf->mtilea = 1; break;
+	case 1: surf->mtilea = 2; break;
+	case 2: surf->mtilea = 4; break;
+	case 3: surf->mtilea = 8; break;
+	default:
+		dev_warn(p->dev, "%s:%d %s invalid macro tile aspect %d\n",
+			 __func__, __LINE__, prefix, surf->mtilea);
+		return -EINVAL;
+	}
+	switch (surf->tsplit) {
+	case 0: surf->tsplit = 64; break;
+	case 1: surf->tsplit = 128; break;
+	case 2: surf->tsplit = 256; break;
+	case 3: surf->tsplit = 512; break;
+	case 4: surf->tsplit = 1024; break;
+	case 5: surf->tsplit = 2048; break;
+	case 6: surf->tsplit = 4096; break;
+	default:
+		dev_warn(p->dev, "%s:%d %s invalid tile split %d\n",
+			 __func__, __LINE__, prefix, surf->tsplit);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned id)
+{
+	struct evergreen_cs_track *track = p->track;
+	struct eg_surface surf;
+	unsigned pitch, slice, mslice;
+	unsigned long offset;
+	int r;
+
+	mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
+	pitch = track->cb_color_pitch[id];
+	slice = track->cb_color_slice[id];
+	surf.nbx = (pitch + 1) * 8;
+	surf.nby = ((slice + 1) * 64) / surf.nbx;
+	surf.mode = G_028C70_ARRAY_MODE(track->cb_color_info[id]);
+	surf.format = G_028C70_FORMAT(track->cb_color_info[id]);
+	surf.tsplit = G_028C74_TILE_SPLIT(track->cb_color_attrib[id]);
+	surf.nbanks = G_028C74_NUM_BANKS(track->cb_color_attrib[id]);
+	surf.bankw = G_028C74_BANK_WIDTH(track->cb_color_attrib[id]);
+	surf.bankh = G_028C74_BANK_HEIGHT(track->cb_color_attrib[id]);
+	surf.mtilea = G_028C74_MACRO_TILE_ASPECT(track->cb_color_attrib[id]);
+	surf.nsamples = 1;
+
+	if (!r600_fmt_is_valid_color(surf.format)) {
+		dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08x)\n",
+			 __func__, __LINE__, surf.format,
+			id, track->cb_color_info[id]);
+		return -EINVAL;
+	}
+
+	r = evergreen_surface_value_conv_check(p, &surf, "cb");
+	if (r) {
+		return r;
+	}
+
+	r = evergreen_surface_check(p, &surf, "cb");
+	if (r) {
+		dev_warn(p->dev, "%s:%d cb[%d] invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
+			 __func__, __LINE__, id, track->cb_color_pitch[id],
+			 track->cb_color_slice[id], track->cb_color_attrib[id],
+			 track->cb_color_info[id]);
+		return r;
+	}
+
+	offset = track->cb_color_bo_offset[id] << 8;
+	if (offset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, id, offset, surf.base_align);
+		return -EINVAL;
+	}
+
+	offset += surf.layer_size * mslice;
+	if (offset > radeon_bo_size(track->cb_color_bo[id])) {
+		dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
+			 "offset %d, max layer %d, bo size %ld, slice %d)\n",
+			 __func__, __LINE__, id, surf.layer_size,
+			track->cb_color_bo_offset[id] << 8, mslice,
+			radeon_bo_size(track->cb_color_bo[id]), slice);
+		dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
+			 __func__, __LINE__, surf.nbx, surf.nby,
+			surf.mode, surf.bpe, surf.nsamples,
+			surf.bankw, surf.bankh,
+			surf.tsplit, surf.mtilea);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
 {
 	struct evergreen_cs_track *track = p->track;
+	struct eg_surface surf;
+	unsigned pitch, slice, mslice;
+	unsigned long offset;
+	int r;
+
+	mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
+	pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size);
+	slice = track->db_depth_slice;
+	surf.nbx = (pitch + 1) * 8;
+	surf.nby = ((slice + 1) * 64) / surf.nbx;
+	surf.mode = G_028040_ARRAY_MODE(track->db_z_info);
+	surf.format = G_028044_FORMAT(track->db_s_info);
+	surf.tsplit = G_028044_TILE_SPLIT(track->db_s_info);
+	surf.nbanks = G_028040_NUM_BANKS(track->db_z_info);
+	surf.bankw = G_028040_BANK_WIDTH(track->db_z_info);
+	surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info);
+	surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info);
+	surf.nsamples = 1;
+
+	if (surf.format != 1) {
+		dev_warn(p->dev, "%s:%d stencil invalid format %d\n",
+			 __func__, __LINE__, surf.format);
+		return -EINVAL;
+	}
+	/* replace by color format so we can use same code */
+	surf.format = V_028C70_COLOR_8;
+
+	r = evergreen_surface_value_conv_check(p, &surf, "stencil");
+	if (r) {
+		return r;
+	}
+
+	r = evergreen_surface_check(p, &surf, NULL);
+	if (r) {
+		/* old userspace doesn't compute proper depth/stencil alignment
+		 * check that alignment against a bigger byte per elements and
+		 * only report if that alignment is wrong too.
+		 */
+		surf.format = V_028C70_COLOR_8_8_8_8;
+		r = evergreen_surface_check(p, &surf, "stencil");
+		if (r) {
+			dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
+				 __func__, __LINE__, track->db_depth_size,
+				 track->db_depth_slice, track->db_s_info, track->db_z_info);
+		}
+		return r;
+	}
+
+	offset = track->db_s_read_offset << 8;
+	if (offset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, offset, surf.base_align);
+		return -EINVAL;
+	}
+	offset += surf.layer_size * mslice;
+	if (offset > radeon_bo_size(track->db_s_read_bo)) {
+		dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
+			 "offset %ld, max layer %d, bo size %ld)\n",
+			 __func__, __LINE__, surf.layer_size,
+			(unsigned long)track->db_s_read_offset << 8, mslice,
+			radeon_bo_size(track->db_s_read_bo));
+		dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
+			 __func__, __LINE__, track->db_depth_size,
+			 track->db_depth_slice, track->db_s_info, track->db_z_info);
+		return -EINVAL;
+	}
+
+	offset = track->db_s_write_offset << 8;
+	if (offset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, offset, surf.base_align);
+		return -EINVAL;
+	}
+	offset += surf.layer_size * mslice;
+	if (offset > radeon_bo_size(track->db_s_write_bo)) {
+		dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
+			 "offset %ld, max layer %d, bo size %ld)\n",
+			 __func__, __LINE__, surf.layer_size,
+			(unsigned long)track->db_s_write_offset << 8, mslice,
+			radeon_bo_size(track->db_s_write_bo));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
+{
+	struct evergreen_cs_track *track = p->track;
+	struct eg_surface surf;
+	unsigned pitch, slice, mslice;
+	unsigned long offset;
+	int r;
+
+	mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
+	pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size);
+	slice = track->db_depth_slice;
+	surf.nbx = (pitch + 1) * 8;
+	surf.nby = ((slice + 1) * 64) / surf.nbx;
+	surf.mode = G_028040_ARRAY_MODE(track->db_z_info);
+	surf.format = G_028040_FORMAT(track->db_z_info);
+	surf.tsplit = G_028040_TILE_SPLIT(track->db_z_info);
+	surf.nbanks = G_028040_NUM_BANKS(track->db_z_info);
+	surf.bankw = G_028040_BANK_WIDTH(track->db_z_info);
+	surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info);
+	surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info);
+	surf.nsamples = 1;
+
+	switch (surf.format) {
+	case V_028040_Z_16:
+		surf.format = V_028C70_COLOR_16;
+		break;
+	case V_028040_Z_24:
+	case V_028040_Z_32_FLOAT:
+		surf.format = V_028C70_COLOR_8_8_8_8;
+		break;
+	default:
+		dev_warn(p->dev, "%s:%d depth invalid format %d\n",
+			 __func__, __LINE__, surf.format);
+		return -EINVAL;
+	}
+
+	r = evergreen_surface_value_conv_check(p, &surf, "depth");
+	if (r) {
+		dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
+			 __func__, __LINE__, track->db_depth_size,
+			 track->db_depth_slice, track->db_z_info);
+		return r;
+	}
+
+	r = evergreen_surface_check(p, &surf, "depth");
+	if (r) {
+		dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
+			 __func__, __LINE__, track->db_depth_size,
+			 track->db_depth_slice, track->db_z_info);
+		return r;
+	}
+
+	offset = track->db_z_read_offset << 8;
+	if (offset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, offset, surf.base_align);
+		return -EINVAL;
+	}
+	offset += surf.layer_size * mslice;
+	if (offset > radeon_bo_size(track->db_z_read_bo)) {
+		dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
+			 "offset %ld, max layer %d, bo size %ld)\n",
+			 __func__, __LINE__, surf.layer_size,
+			(unsigned long)track->db_z_read_offset << 8, mslice,
+			radeon_bo_size(track->db_z_read_bo));
+		return -EINVAL;
+	}
+
+	offset = track->db_z_write_offset << 8;
+	if (offset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, offset, surf.base_align);
+		return -EINVAL;
+	}
+	offset += surf.layer_size * mslice;
+	if (offset > radeon_bo_size(track->db_z_write_bo)) {
+		dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
+			 "offset %ld, max layer %d, bo size %ld)\n",
+			 __func__, __LINE__, surf.layer_size,
+			(unsigned long)track->db_z_write_offset << 8, mslice,
+			radeon_bo_size(track->db_z_write_bo));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
+					       struct radeon_bo *texture,
+					       struct radeon_bo *mipmap,
+					       unsigned idx)
+{
+	struct eg_surface surf;
+	unsigned long toffset, moffset;
+	unsigned dim, llevel, mslice, width, height, depth, i;
+	u32 texdw[8];
+	int r;
+
+	texdw[0] = radeon_get_ib_value(p, idx + 0);
+	texdw[1] = radeon_get_ib_value(p, idx + 1);
+	texdw[2] = radeon_get_ib_value(p, idx + 2);
+	texdw[3] = radeon_get_ib_value(p, idx + 3);
+	texdw[4] = radeon_get_ib_value(p, idx + 4);
+	texdw[5] = radeon_get_ib_value(p, idx + 5);
+	texdw[6] = radeon_get_ib_value(p, idx + 6);
+	texdw[7] = radeon_get_ib_value(p, idx + 7);
+	dim = G_030000_DIM(texdw[0]);
+	llevel = G_030014_LAST_LEVEL(texdw[5]);
+	mslice = G_030014_LAST_ARRAY(texdw[5]) + 1;
+	width = G_030000_TEX_WIDTH(texdw[0]) + 1;
+	height =  G_030004_TEX_HEIGHT(texdw[1]) + 1;
+	depth = G_030004_TEX_DEPTH(texdw[1]) + 1;
+	surf.format = G_03001C_DATA_FORMAT(texdw[7]);
+	surf.nbx = (G_030000_PITCH(texdw[0]) + 1) * 8;
+	surf.nbx = r600_fmt_get_nblocksx(surf.format, surf.nbx);
+	surf.nby = r600_fmt_get_nblocksy(surf.format, height);
+	surf.mode = G_030004_ARRAY_MODE(texdw[1]);
+	surf.tsplit = G_030018_TILE_SPLIT(texdw[6]);
+	surf.nbanks = G_03001C_NUM_BANKS(texdw[7]);
+	surf.bankw = G_03001C_BANK_WIDTH(texdw[7]);
+	surf.bankh = G_03001C_BANK_HEIGHT(texdw[7]);
+	surf.mtilea = G_03001C_MACRO_TILE_ASPECT(texdw[7]);
+	surf.nsamples = 1;
+	toffset = texdw[2] << 8;
+	moffset = texdw[3] << 8;
 
-	/* we don't support stream out buffer yet */
-	if (track->vgt_strmout_config || track->vgt_strmout_buffer_config) {
-		dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
+	if (!r600_fmt_is_valid_texture(surf.format, p->family)) {
+		dev_warn(p->dev, "%s:%d texture invalid format %d\n",
+			 __func__, __LINE__, surf.format);
 		return -EINVAL;
 	}
+	switch (dim) {
+	case V_030000_SQ_TEX_DIM_1D:
+	case V_030000_SQ_TEX_DIM_2D:
+	case V_030000_SQ_TEX_DIM_CUBEMAP:
+	case V_030000_SQ_TEX_DIM_1D_ARRAY:
+	case V_030000_SQ_TEX_DIM_2D_ARRAY:
+		depth = 1;
+	case V_030000_SQ_TEX_DIM_3D:
+		break;
+	default:
+		dev_warn(p->dev, "%s:%d texture invalid dimension %d\n",
+			 __func__, __LINE__, dim);
+		return -EINVAL;
+	}
+
+	r = evergreen_surface_value_conv_check(p, &surf, "texture");
+	if (r) {
+		return r;
+	}
+
+	/* align height */
+	evergreen_surface_check(p, &surf, NULL);
+	surf.nby = ALIGN(surf.nby, surf.halign);
+
+	r = evergreen_surface_check(p, &surf, "texture");
+	if (r) {
+		dev_warn(p->dev, "%s:%d texture invalid 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			 __func__, __LINE__, texdw[0], texdw[1], texdw[4],
+			 texdw[5], texdw[6], texdw[7]);
+		return r;
+	}
+
+	/* check texture size */
+	if (toffset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d texture bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, toffset, surf.base_align);
+		return -EINVAL;
+	}
+	if (moffset & (surf.base_align - 1)) {
+		dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n",
+			 __func__, __LINE__, moffset, surf.base_align);
+		return -EINVAL;
+	}
+	if (dim == SQ_TEX_DIM_3D) {
+		toffset += surf.layer_size * depth;
+	} else {
+		toffset += surf.layer_size * mslice;
+	}
+	if (toffset > radeon_bo_size(texture)) {
+		dev_warn(p->dev, "%s:%d texture bo too small (layer size %d, "
+			 "offset %ld, max layer %d, depth %d, bo size %ld) (%d %d)\n",
+			 __func__, __LINE__, surf.layer_size,
+			(unsigned long)texdw[2] << 8, mslice,
+			depth, radeon_bo_size(texture),
+			surf.nbx, surf.nby);
+		return -EINVAL;
+	}
+
+	/* check mipmap size */
+	for (i = 1; i <= llevel; i++) {
+		unsigned w, h, d;
+
+		w = r600_mip_minify(width, i);
+		h = r600_mip_minify(height, i);
+		d = r600_mip_minify(depth, i);
+		surf.nbx = r600_fmt_get_nblocksx(surf.format, w);
+		surf.nby = r600_fmt_get_nblocksy(surf.format, h);
+
+		switch (surf.mode) {
+		case ARRAY_2D_TILED_THIN1:
+			if (surf.nbx < surf.palign || surf.nby < surf.halign) {
+				surf.mode = ARRAY_1D_TILED_THIN1;
+			}
+			/* recompute alignment */
+			evergreen_surface_check(p, &surf, NULL);
+			break;
+		case ARRAY_LINEAR_GENERAL:
+		case ARRAY_LINEAR_ALIGNED:
+		case ARRAY_1D_TILED_THIN1:
+			break;
+		default:
+			dev_warn(p->dev, "%s:%d invalid array mode %d\n",
+				 __func__, __LINE__, surf.mode);
+			return -EINVAL;
+		}
+		surf.nbx = ALIGN(surf.nbx, surf.palign);
+		surf.nby = ALIGN(surf.nby, surf.halign);
+
+		r = evergreen_surface_check(p, &surf, "mipmap");
+		if (r) {
+			return r;
+		}
+
+		if (dim == SQ_TEX_DIM_3D) {
+			moffset += surf.layer_size * d;
+		} else {
+			moffset += surf.layer_size * mslice;
+		}
+		if (moffset > radeon_bo_size(mipmap)) {
+			dev_warn(p->dev, "%s:%d mipmap [%d] bo too small (layer size %d, "
+					"offset %ld, coffset %ld, max layer %d, depth %d, "
+					"bo size %ld) level0 (%d %d %d)\n",
+					__func__, __LINE__, i, surf.layer_size,
+					(unsigned long)texdw[3] << 8, moffset, mslice,
+					d, radeon_bo_size(mipmap),
+					width, height, depth);
+			dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
+				 __func__, __LINE__, surf.nbx, surf.nby,
+				surf.mode, surf.bpe, surf.nsamples,
+				surf.bankw, surf.bankh,
+				surf.tsplit, surf.mtilea);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int evergreen_cs_track_check(struct radeon_cs_parser *p)
+{
+	struct evergreen_cs_track *track = p->track;
+	unsigned tmp, i, j;
+	int r;
+
+	/* check streamout */
+	for (i = 0; i < 4; i++) {
+		if (track->vgt_strmout_config & (1 << i)) {
+			for (j = 0; j < 4; j++) {
+				if ((track->vgt_strmout_buffer_config >> (i * 4)) & (1 << j)) {
+					if (track->vgt_strmout_bo[j]) {
+						u64 offset = (u64)track->vgt_strmout_bo_offset[j] +
+							(u64)track->vgt_strmout_size[j];
+						if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
+							DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n",
+								  j, offset,
+								  radeon_bo_size(track->vgt_strmout_bo[j]));
+							return -EINVAL;
+						}
+					} else {
+						dev_warn(p->dev, "No buffer for streamout %d\n", j);
+						return -EINVAL;
+					}
+				}
+			}
+		}
+	}
+
+	/* check that we have a cb for each enabled target
+	 */
+	tmp = track->cb_target_mask;
+	for (i = 0; i < 8; i++) {
+		if ((tmp >> (i * 4)) & 0xF) {
+			/* at least one component is enabled */
+			if (track->cb_color_bo[i] == NULL) {
+				dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
+					__func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
+				return -EINVAL;
+			}
+			/* check cb */
+			r = evergreen_cs_track_validate_cb(p, i);
+			if (r) {
+				return r;
+			}
+		}
+	}
+
+	/* Check stencil buffer */
+	if (G_028800_STENCIL_ENABLE(track->db_depth_control)) {
+		r = evergreen_cs_track_validate_stencil(p);
+		if (r)
+			return r;
+	}
+	/* Check depth buffer */
+	if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) {
+		r = evergreen_cs_track_validate_depth(p);
+		if (r)
+			return r;
+	}
 
-	/* XXX fill in */
 	return 0;
 }
 
@@ -532,8 +1213,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 			ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
 			track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
 			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+				unsigned bankw, bankh, mtaspect, tile_split;
+
+				evergreen_tiling_fields(reloc->lobj.tiling_flags,
+							&bankw, &bankh, &mtaspect,
+							&tile_split);
 				ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
-				ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+				ib[idx] |= DB_TILE_SPLIT(tile_split) |
+						DB_BANK_WIDTH(bankw) |
+						DB_BANK_HEIGHT(bankh) |
+						DB_MACRO_TILE_ASPECT(mtaspect);
 			}
 		}
 		break;
@@ -547,6 +1236,9 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 		track->db_depth_size = radeon_get_ib_value(p, idx);
 		track->db_depth_size_idx = idx;
 		break;
+	case R_02805C_DB_DEPTH_SLICE:
+		track->db_depth_slice = radeon_get_ib_value(p, idx);
+		break;
 	case DB_Z_READ_BASE:
 		r = evergreen_cs_packet_next_reloc(p, &reloc);
 		if (r) {
@@ -597,6 +1289,38 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 	case VGT_STRMOUT_BUFFER_CONFIG:
 		track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx);
 		break;
+	case VGT_STRMOUT_BUFFER_BASE_0:
+	case VGT_STRMOUT_BUFFER_BASE_1:
+	case VGT_STRMOUT_BUFFER_BASE_2:
+	case VGT_STRMOUT_BUFFER_BASE_3:
+		r = evergreen_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16;
+		track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		track->vgt_strmout_bo[tmp] = reloc->robj;
+		track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset;
+		break;
+	case VGT_STRMOUT_BUFFER_SIZE_0:
+	case VGT_STRMOUT_BUFFER_SIZE_1:
+	case VGT_STRMOUT_BUFFER_SIZE_2:
+	case VGT_STRMOUT_BUFFER_SIZE_3:
+		tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16;
+		/* size in register is DWs, convert to bytes */
+		track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4;
+		break;
+	case CP_COHER_BASE:
+		r = evergreen_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "missing reloc for CP_COHER_BASE "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
 	case CB_TARGET_MASK:
 		track->cb_target_mask = radeon_get_ib_value(p, idx);
 		break;
@@ -725,6 +1449,29 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 	case CB_COLOR5_ATTRIB:
 	case CB_COLOR6_ATTRIB:
 	case CB_COLOR7_ATTRIB:
+		r = evergreen_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+				unsigned bankw, bankh, mtaspect, tile_split;
+
+				evergreen_tiling_fields(reloc->lobj.tiling_flags,
+							&bankw, &bankh, &mtaspect,
+							&tile_split);
+				ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+				ib[idx] |= CB_TILE_SPLIT(tile_split) |
+					   CB_BANK_WIDTH(bankw) |
+					   CB_BANK_HEIGHT(bankh) |
+					   CB_MACRO_TILE_ASPECT(mtaspect);
+			}
+		}
+		tmp = ((reg - CB_COLOR0_ATTRIB) / 0x3c);
+		track->cb_color_attrib[tmp] = ib[idx];
+		break;
 	case CB_COLOR8_ATTRIB:
 	case CB_COLOR9_ATTRIB:
 	case CB_COLOR10_ATTRIB:
@@ -735,10 +1482,22 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 					"0x%04X\n", reg);
 			return -EINVAL;
 		}
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-			ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
-			ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+				unsigned bankw, bankh, mtaspect, tile_split;
+
+				evergreen_tiling_fields(reloc->lobj.tiling_flags,
+							&bankw, &bankh, &mtaspect,
+							&tile_split);
+				ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+				ib[idx] |= CB_TILE_SPLIT(tile_split) |
+					   CB_BANK_WIDTH(bankw) |
+					   CB_BANK_HEIGHT(bankh) |
+					   CB_MACRO_TILE_ASPECT(mtaspect);
+			}
 		}
+		tmp = ((reg - CB_COLOR8_ATTRIB) / 0x1c) + 8;
+		track->cb_color_attrib[tmp] = ib[idx];
 		break;
 	case CB_COLOR0_DIM:
 	case CB_COLOR1_DIM:
@@ -996,22 +1755,30 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 	return 0;
 }
 
-/**
- * evergreen_check_texture_resource() - check if register is authorized or not
- * @p: parser structure holding parsing context
- * @idx: index into the cs buffer
- * @texture: texture's bo structure
- * @mipmap: mipmap's bo structure
- *
- * This function will check that the resource has valid field and that
- * the texture and mipmap bo object are big enough to cover this resource.
- */
-static int evergreen_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
-						   struct radeon_bo *texture,
-						   struct radeon_bo *mipmap)
+static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 {
-	/* XXX fill in */
-	return 0;
+	u32 last_reg, m, i;
+
+	if (p->rdev->family >= CHIP_CAYMAN)
+		last_reg = ARRAY_SIZE(cayman_reg_safe_bm);
+	else
+		last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
+
+	i = (reg >> 7);
+	if (i >= last_reg) {
+		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+		return false;
+	}
+	m = 1 << ((reg >> 2) & 31);
+	if (p->rdev->family >= CHIP_CAYMAN) {
+		if (!(cayman_reg_safe_bm[i] & m))
+			return true;
+	} else {
+		if (!(evergreen_reg_safe_bm[i] & m))
+			return true;
+	}
+	dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+	return false;
 }
 
 static int evergreen_packet3_check(struct radeon_cs_parser *p,
@@ -1344,6 +2111,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
 		}
 		for (i = 0; i < (pkt->count / 8); i++) {
 			struct radeon_bo *texture, *mipmap;
+			u32 toffset, moffset;
 			u32 size, offset;
 
 			switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
@@ -1354,30 +2122,38 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
 					DRM_ERROR("bad SET_RESOURCE (tex)\n");
 					return -EINVAL;
 				}
-				ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
 				if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
 					ib[idx+1+(i*8)+1] |=
 						TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
 					if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-						ib[idx+1+(i*8)+6] |=
-							TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+						unsigned bankw, bankh, mtaspect, tile_split;
+
+						evergreen_tiling_fields(reloc->lobj.tiling_flags,
+									&bankw, &bankh, &mtaspect,
+									&tile_split);
+						ib[idx+1+(i*8)+6] |= TEX_TILE_SPLIT(tile_split);
 						ib[idx+1+(i*8)+7] |=
+							TEX_BANK_WIDTH(bankw) |
+							TEX_BANK_HEIGHT(bankh) |
+							MACRO_TILE_ASPECT(mtaspect) |
 							TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
 					}
 				}
 				texture = reloc->robj;
+				toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
 				/* tex mip base */
 				r = evergreen_cs_packet_next_reloc(p, &reloc);
 				if (r) {
 					DRM_ERROR("bad SET_RESOURCE (tex)\n");
 					return -EINVAL;
 				}
-				ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
 				mipmap = reloc->robj;
-				r = evergreen_check_texture_resource(p,  idx+1+(i*8),
-						texture, mipmap);
+				r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8));
 				if (r)
 					return r;
+				ib[idx+1+(i*8)+2] += toffset;
+				ib[idx+1+(i*8)+3] += moffset;
 				break;
 			case SQ_TEX_VTX_VALID_BUFFER:
 				/* vtx base */
@@ -1451,6 +2227,100 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
 			return -EINVAL;
 		}
 		break;
+	case PACKET3_STRMOUT_BUFFER_UPDATE:
+		if (pkt->count != 4) {
+			DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n");
+			return -EINVAL;
+		}
+		/* Updating memory at DST_ADDRESS. */
+		if (idx_value & 0x1) {
+			u64 offset;
+			r = evergreen_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+1);
+			offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		}
+		/* Reading data from SRC_ADDRESS. */
+		if (((idx_value >> 1) & 0x3) == 2) {
+			u64 offset;
+			r = evergreen_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+3);
+			offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		}
+		break;
+	case PACKET3_COPY_DW:
+		if (pkt->count != 4) {
+			DRM_ERROR("bad COPY_DW (invalid count)\n");
+			return -EINVAL;
+		}
+		if (idx_value & 0x1) {
+			u64 offset;
+			/* SRC is memory. */
+			r = evergreen_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad COPY_DW (missing src reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+1);
+			offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		} else {
+			/* SRC is a reg. */
+			reg = radeon_get_ib_value(p, idx+1) << 2;
+			if (!evergreen_is_safe_reg(p, reg, idx+1))
+				return -EINVAL;
+		}
+		if (idx_value & 0x2) {
+			u64 offset;
+			/* DST is memory. */
+			r = evergreen_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad COPY_DW (missing dst reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+3);
+			offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		} else {
+			/* DST is a reg. */
+			reg = radeon_get_ib_value(p, idx+3) << 2;
+			if (!evergreen_is_safe_reg(p, reg, idx+3))
+				return -EINVAL;
+		}
+		break;
 	case PACKET3_NOP:
 		break;
 	default:
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 74713d4..eb5708c 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -77,6 +77,7 @@
 
 #define	CONFIG_MEMSIZE					0x5428
 
+#define	CP_COHER_BASE					0x85F8
 #define CP_ME_CNTL					0x86D8
 #define		CP_ME_HALT					(1 << 28)
 #define		CP_PFP_HALT					(1 << 26)
@@ -925,7 +926,70 @@
 #define DB_DEBUG4					0x983C
 #define DB_WATERMARKS					0x9854
 #define DB_DEPTH_CONTROL				0x28800
+#define R_028800_DB_DEPTH_CONTROL                    0x028800
+#define   S_028800_STENCIL_ENABLE(x)                   (((x) & 0x1) << 0)
+#define   G_028800_STENCIL_ENABLE(x)                   (((x) >> 0) & 0x1)
+#define   C_028800_STENCIL_ENABLE                      0xFFFFFFFE
+#define   S_028800_Z_ENABLE(x)                         (((x) & 0x1) << 1)
+#define   G_028800_Z_ENABLE(x)                         (((x) >> 1) & 0x1)
+#define   C_028800_Z_ENABLE                            0xFFFFFFFD
+#define   S_028800_Z_WRITE_ENABLE(x)                   (((x) & 0x1) << 2)
+#define   G_028800_Z_WRITE_ENABLE(x)                   (((x) >> 2) & 0x1)
+#define   C_028800_Z_WRITE_ENABLE                      0xFFFFFFFB
+#define   S_028800_ZFUNC(x)                            (((x) & 0x7) << 4)
+#define   G_028800_ZFUNC(x)                            (((x) >> 4) & 0x7)
+#define   C_028800_ZFUNC                               0xFFFFFF8F
+#define   S_028800_BACKFACE_ENABLE(x)                  (((x) & 0x1) << 7)
+#define   G_028800_BACKFACE_ENABLE(x)                  (((x) >> 7) & 0x1)
+#define   C_028800_BACKFACE_ENABLE                     0xFFFFFF7F
+#define   S_028800_STENCILFUNC(x)                      (((x) & 0x7) << 8)
+#define   G_028800_STENCILFUNC(x)                      (((x) >> 8) & 0x7)
+#define   C_028800_STENCILFUNC                         0xFFFFF8FF
+#define     V_028800_STENCILFUNC_NEVER                 0x00000000
+#define     V_028800_STENCILFUNC_LESS                  0x00000001
+#define     V_028800_STENCILFUNC_EQUAL                 0x00000002
+#define     V_028800_STENCILFUNC_LEQUAL                0x00000003
+#define     V_028800_STENCILFUNC_GREATER               0x00000004
+#define     V_028800_STENCILFUNC_NOTEQUAL              0x00000005
+#define     V_028800_STENCILFUNC_GEQUAL                0x00000006
+#define     V_028800_STENCILFUNC_ALWAYS                0x00000007
+#define   S_028800_STENCILFAIL(x)                      (((x) & 0x7) << 11)
+#define   G_028800_STENCILFAIL(x)                      (((x) >> 11) & 0x7)
+#define   C_028800_STENCILFAIL                         0xFFFFC7FF
+#define     V_028800_STENCIL_KEEP                      0x00000000
+#define     V_028800_STENCIL_ZERO                      0x00000001
+#define     V_028800_STENCIL_REPLACE                   0x00000002
+#define     V_028800_STENCIL_INCR                      0x00000003
+#define     V_028800_STENCIL_DECR                      0x00000004
+#define     V_028800_STENCIL_INVERT                    0x00000005
+#define     V_028800_STENCIL_INCR_WRAP                 0x00000006
+#define     V_028800_STENCIL_DECR_WRAP                 0x00000007
+#define   S_028800_STENCILZPASS(x)                     (((x) & 0x7) << 14)
+#define   G_028800_STENCILZPASS(x)                     (((x) >> 14) & 0x7)
+#define   C_028800_STENCILZPASS                        0xFFFE3FFF
+#define   S_028800_STENCILZFAIL(x)                     (((x) & 0x7) << 17)
+#define   G_028800_STENCILZFAIL(x)                     (((x) >> 17) & 0x7)
+#define   C_028800_STENCILZFAIL                        0xFFF1FFFF
+#define   S_028800_STENCILFUNC_BF(x)                   (((x) & 0x7) << 20)
+#define   G_028800_STENCILFUNC_BF(x)                   (((x) >> 20) & 0x7)
+#define   C_028800_STENCILFUNC_BF                      0xFF8FFFFF
+#define   S_028800_STENCILFAIL_BF(x)                   (((x) & 0x7) << 23)
+#define   G_028800_STENCILFAIL_BF(x)                   (((x) >> 23) & 0x7)
+#define   C_028800_STENCILFAIL_BF                      0xFC7FFFFF
+#define   S_028800_STENCILZPASS_BF(x)                  (((x) & 0x7) << 26)
+#define   G_028800_STENCILZPASS_BF(x)                  (((x) >> 26) & 0x7)
+#define   C_028800_STENCILZPASS_BF                     0xE3FFFFFF
+#define   S_028800_STENCILZFAIL_BF(x)                  (((x) & 0x7) << 29)
+#define   G_028800_STENCILZFAIL_BF(x)                  (((x) >> 29) & 0x7)
+#define   C_028800_STENCILZFAIL_BF                     0x1FFFFFFF
 #define DB_DEPTH_VIEW					0x28008
+#define R_028008_DB_DEPTH_VIEW                       0x00028008
+#define   S_028008_SLICE_START(x)                      (((x) & 0x7FF) << 0)
+#define   G_028008_SLICE_START(x)                      (((x) >> 0) & 0x7FF)
+#define   C_028008_SLICE_START                         0xFFFFF800
+#define   S_028008_SLICE_MAX(x)                        (((x) & 0x7FF) << 13)
+#define   G_028008_SLICE_MAX(x)                        (((x) >> 13) & 0x7FF)
+#define   C_028008_SLICE_MAX                           0xFF001FFF
 #define DB_HTILE_DATA_BASE				0x28014
 #define DB_Z_INFO					0x28040
 #       define Z_ARRAY_MODE(x)                          ((x) << 4)
@@ -933,12 +997,59 @@
 #       define DB_NUM_BANKS(x)                          (((x) & 0x3) << 12)
 #       define DB_BANK_WIDTH(x)                         (((x) & 0x3) << 16)
 #       define DB_BANK_HEIGHT(x)                        (((x) & 0x3) << 20)
+#       define DB_MACRO_TILE_ASPECT(x)                  (((x) & 0x3) << 24)
+#define R_028040_DB_Z_INFO                       0x028040
+#define   S_028040_FORMAT(x)                           (((x) & 0x3) << 0)
+#define   G_028040_FORMAT(x)                           (((x) >> 0) & 0x3)
+#define   C_028040_FORMAT                              0xFFFFFFFC
+#define     V_028040_Z_INVALID                     0x00000000
+#define     V_028040_Z_16                          0x00000001
+#define     V_028040_Z_24                          0x00000002
+#define     V_028040_Z_32_FLOAT                    0x00000003
+#define   S_028040_ARRAY_MODE(x)                       (((x) & 0xF) << 4)
+#define   G_028040_ARRAY_MODE(x)                       (((x) >> 4) & 0xF)
+#define   C_028040_ARRAY_MODE                          0xFFFFFF0F
+#define   S_028040_READ_SIZE(x)                        (((x) & 0x1) << 28)
+#define   G_028040_READ_SIZE(x)                        (((x) >> 28) & 0x1)
+#define   C_028040_READ_SIZE                           0xEFFFFFFF
+#define   S_028040_TILE_SURFACE_ENABLE(x)              (((x) & 0x1) << 29)
+#define   G_028040_TILE_SURFACE_ENABLE(x)              (((x) >> 29) & 0x1)
+#define   C_028040_TILE_SURFACE_ENABLE                 0xDFFFFFFF
+#define   S_028040_ZRANGE_PRECISION(x)                 (((x) & 0x1) << 31)
+#define   G_028040_ZRANGE_PRECISION(x)                 (((x) >> 31) & 0x1)
+#define   C_028040_ZRANGE_PRECISION                    0x7FFFFFFF
+#define   S_028040_TILE_SPLIT(x)                       (((x) & 0x7) << 8)
+#define   G_028040_TILE_SPLIT(x)                       (((x) >> 8) & 0x7)
+#define   S_028040_NUM_BANKS(x)                        (((x) & 0x3) << 12)
+#define   G_028040_NUM_BANKS(x)                        (((x) >> 12) & 0x3)
+#define   S_028040_BANK_WIDTH(x)                       (((x) & 0x3) << 16)
+#define   G_028040_BANK_WIDTH(x)                       (((x) >> 16) & 0x3)
+#define   S_028040_BANK_HEIGHT(x)                      (((x) & 0x3) << 20)
+#define   G_028040_BANK_HEIGHT(x)                      (((x) >> 20) & 0x3)
+#define   S_028040_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 24)
+#define   G_028040_MACRO_TILE_ASPECT(x)                (((x) >> 24) & 0x3)
 #define DB_STENCIL_INFO					0x28044
+#define R_028044_DB_STENCIL_INFO                     0x028044
+#define   S_028044_FORMAT(x)                           (((x) & 0x1) << 0)
+#define   G_028044_FORMAT(x)                           (((x) >> 0) & 0x1)
+#define   C_028044_FORMAT                              0xFFFFFFFE
+#define   G_028044_TILE_SPLIT(x)                       (((x) >> 8) & 0x7)
 #define DB_Z_READ_BASE					0x28048
 #define DB_STENCIL_READ_BASE				0x2804c
 #define DB_Z_WRITE_BASE					0x28050
 #define DB_STENCIL_WRITE_BASE				0x28054
 #define DB_DEPTH_SIZE					0x28058
+#define R_028058_DB_DEPTH_SIZE                       0x028058
+#define   S_028058_PITCH_TILE_MAX(x)                   (((x) & 0x7FF) << 0)
+#define   G_028058_PITCH_TILE_MAX(x)                   (((x) >> 0) & 0x7FF)
+#define   C_028058_PITCH_TILE_MAX                      0xFFFFF800
+#define   S_028058_HEIGHT_TILE_MAX(x)                   (((x) & 0x7FF) << 11)
+#define   G_028058_HEIGHT_TILE_MAX(x)                   (((x) >> 11) & 0x7FF)
+#define   C_028058_HEIGHT_TILE_MAX                      0xFFC007FF
+#define R_02805C_DB_DEPTH_SLICE                      0x02805C
+#define   S_02805C_SLICE_TILE_MAX(x)                   (((x) & 0x3FFFFF) << 0)
+#define   G_02805C_SLICE_TILE_MAX(x)                   (((x) >> 0) & 0x3FFFFF)
+#define   C_02805C_SLICE_TILE_MAX                      0xFFC00000
 
 #define SQ_PGM_START_PS					0x28840
 #define SQ_PGM_START_VS					0x2885c
@@ -948,6 +1059,14 @@
 #define SQ_PGM_START_HS					0x288b8
 #define SQ_PGM_START_LS					0x288d0
 
+#define	VGT_STRMOUT_BUFFER_BASE_0			0x28AD8
+#define	VGT_STRMOUT_BUFFER_BASE_1			0x28AE8
+#define	VGT_STRMOUT_BUFFER_BASE_2			0x28AF8
+#define	VGT_STRMOUT_BUFFER_BASE_3			0x28B08
+#define VGT_STRMOUT_BUFFER_SIZE_0			0x28AD0
+#define VGT_STRMOUT_BUFFER_SIZE_1			0x28AE0
+#define VGT_STRMOUT_BUFFER_SIZE_2			0x28AF0
+#define VGT_STRMOUT_BUFFER_SIZE_3			0x28B00
 #define VGT_STRMOUT_CONFIG				0x28b94
 #define VGT_STRMOUT_BUFFER_CONFIG			0x28b98
 
@@ -974,6 +1093,114 @@
 #define	CB_COLOR0_PITCH					0x28c64
 #define	CB_COLOR0_SLICE					0x28c68
 #define	CB_COLOR0_VIEW					0x28c6c
+#define R_028C6C_CB_COLOR0_VIEW                      0x00028C6C
+#define   S_028C6C_SLICE_START(x)                      (((x) & 0x7FF) << 0)
+#define   G_028C6C_SLICE_START(x)                      (((x) >> 0) & 0x7FF)
+#define   C_028C6C_SLICE_START                         0xFFFFF800
+#define   S_028C6C_SLICE_MAX(x)                        (((x) & 0x7FF) << 13)
+#define   G_028C6C_SLICE_MAX(x)                        (((x) >> 13) & 0x7FF)
+#define   C_028C6C_SLICE_MAX                           0xFF001FFF
+#define R_028C70_CB_COLOR0_INFO                      0x028C70
+#define   S_028C70_ENDIAN(x)                           (((x) & 0x3) << 0)
+#define   G_028C70_ENDIAN(x)                           (((x) >> 0) & 0x3)
+#define   C_028C70_ENDIAN                              0xFFFFFFFC
+#define   S_028C70_FORMAT(x)                           (((x) & 0x3F) << 2)
+#define   G_028C70_FORMAT(x)                           (((x) >> 2) & 0x3F)
+#define   C_028C70_FORMAT                              0xFFFFFF03
+#define     V_028C70_COLOR_INVALID                     0x00000000
+#define     V_028C70_COLOR_8                           0x00000001
+#define     V_028C70_COLOR_4_4                         0x00000002
+#define     V_028C70_COLOR_3_3_2                       0x00000003
+#define     V_028C70_COLOR_16                          0x00000005
+#define     V_028C70_COLOR_16_FLOAT                    0x00000006
+#define     V_028C70_COLOR_8_8                         0x00000007
+#define     V_028C70_COLOR_5_6_5                       0x00000008
+#define     V_028C70_COLOR_6_5_5                       0x00000009
+#define     V_028C70_COLOR_1_5_5_5                     0x0000000A
+#define     V_028C70_COLOR_4_4_4_4                     0x0000000B
+#define     V_028C70_COLOR_5_5_5_1                     0x0000000C
+#define     V_028C70_COLOR_32                          0x0000000D
+#define     V_028C70_COLOR_32_FLOAT                    0x0000000E
+#define     V_028C70_COLOR_16_16                       0x0000000F
+#define     V_028C70_COLOR_16_16_FLOAT                 0x00000010
+#define     V_028C70_COLOR_8_24                        0x00000011
+#define     V_028C70_COLOR_8_24_FLOAT                  0x00000012
+#define     V_028C70_COLOR_24_8                        0x00000013
+#define     V_028C70_COLOR_24_8_FLOAT                  0x00000014
+#define     V_028C70_COLOR_10_11_11                    0x00000015
+#define     V_028C70_COLOR_10_11_11_FLOAT              0x00000016
+#define     V_028C70_COLOR_11_11_10                    0x00000017
+#define     V_028C70_COLOR_11_11_10_FLOAT              0x00000018
+#define     V_028C70_COLOR_2_10_10_10                  0x00000019
+#define     V_028C70_COLOR_8_8_8_8                     0x0000001A
+#define     V_028C70_COLOR_10_10_10_2                  0x0000001B
+#define     V_028C70_COLOR_X24_8_32_FLOAT              0x0000001C
+#define     V_028C70_COLOR_32_32                       0x0000001D
+#define     V_028C70_COLOR_32_32_FLOAT                 0x0000001E
+#define     V_028C70_COLOR_16_16_16_16                 0x0000001F
+#define     V_028C70_COLOR_16_16_16_16_FLOAT           0x00000020
+#define     V_028C70_COLOR_32_32_32_32                 0x00000022
+#define     V_028C70_COLOR_32_32_32_32_FLOAT           0x00000023
+#define     V_028C70_COLOR_32_32_32_FLOAT              0x00000030
+#define   S_028C70_ARRAY_MODE(x)                       (((x) & 0xF) << 8)
+#define   G_028C70_ARRAY_MODE(x)                       (((x) >> 8) & 0xF)
+#define   C_028C70_ARRAY_MODE                          0xFFFFF0FF
+#define     V_028C70_ARRAY_LINEAR_GENERAL              0x00000000
+#define     V_028C70_ARRAY_LINEAR_ALIGNED              0x00000001
+#define     V_028C70_ARRAY_1D_TILED_THIN1              0x00000002
+#define     V_028C70_ARRAY_2D_TILED_THIN1              0x00000004
+#define   S_028C70_NUMBER_TYPE(x)                      (((x) & 0x7) << 12)
+#define   G_028C70_NUMBER_TYPE(x)                      (((x) >> 12) & 0x7)
+#define   C_028C70_NUMBER_TYPE                         0xFFFF8FFF
+#define     V_028C70_NUMBER_UNORM                      0x00000000
+#define     V_028C70_NUMBER_SNORM                      0x00000001
+#define     V_028C70_NUMBER_USCALED                    0x00000002
+#define     V_028C70_NUMBER_SSCALED                    0x00000003
+#define     V_028C70_NUMBER_UINT                       0x00000004
+#define     V_028C70_NUMBER_SINT                       0x00000005
+#define     V_028C70_NUMBER_SRGB                       0x00000006
+#define     V_028C70_NUMBER_FLOAT                      0x00000007
+#define   S_028C70_COMP_SWAP(x)                        (((x) & 0x3) << 15)
+#define   G_028C70_COMP_SWAP(x)                        (((x) >> 15) & 0x3)
+#define   C_028C70_COMP_SWAP                           0xFFFE7FFF
+#define     V_028C70_SWAP_STD                          0x00000000
+#define     V_028C70_SWAP_ALT                          0x00000001
+#define     V_028C70_SWAP_STD_REV                      0x00000002
+#define     V_028C70_SWAP_ALT_REV                      0x00000003
+#define   S_028C70_FAST_CLEAR(x)                       (((x) & 0x1) << 17)
+#define   G_028C70_FAST_CLEAR(x)                       (((x) >> 17) & 0x1)
+#define   C_028C70_FAST_CLEAR                          0xFFFDFFFF
+#define   S_028C70_COMPRESSION(x)                      (((x) & 0x3) << 18)
+#define   G_028C70_COMPRESSION(x)                      (((x) >> 18) & 0x3)
+#define   C_028C70_COMPRESSION                         0xFFF3FFFF
+#define   S_028C70_BLEND_CLAMP(x)                      (((x) & 0x1) << 19)
+#define   G_028C70_BLEND_CLAMP(x)                      (((x) >> 19) & 0x1)
+#define   C_028C70_BLEND_CLAMP                         0xFFF7FFFF
+#define   S_028C70_BLEND_BYPASS(x)                     (((x) & 0x1) << 20)
+#define   G_028C70_BLEND_BYPASS(x)                     (((x) >> 20) & 0x1)
+#define   C_028C70_BLEND_BYPASS                        0xFFEFFFFF
+#define   S_028C70_SIMPLE_FLOAT(x)                     (((x) & 0x1) << 21)
+#define   G_028C70_SIMPLE_FLOAT(x)                     (((x) >> 21) & 0x1)
+#define   C_028C70_SIMPLE_FLOAT                        0xFFDFFFFF
+#define   S_028C70_ROUND_MODE(x)                       (((x) & 0x1) << 22)
+#define   G_028C70_ROUND_MODE(x)                       (((x) >> 22) & 0x1)
+#define   C_028C70_ROUND_MODE                          0xFFBFFFFF
+#define   S_028C70_TILE_COMPACT(x)                     (((x) & 0x1) << 23)
+#define   G_028C70_TILE_COMPACT(x)                     (((x) >> 23) & 0x1)
+#define   C_028C70_TILE_COMPACT                        0xFF7FFFFF
+#define   S_028C70_SOURCE_FORMAT(x)                    (((x) & 0x3) << 24)
+#define   G_028C70_SOURCE_FORMAT(x)                    (((x) >> 24) & 0x3)
+#define   C_028C70_SOURCE_FORMAT                       0xFCFFFFFF
+#define     V_028C70_EXPORT_4C_32BPC                   0x0
+#define     V_028C70_EXPORT_4C_16BPC                   0x1
+#define     V_028C70_EXPORT_2C_32BPC                   0x2 /* Do not use */
+#define   S_028C70_RAT(x)                              (((x) & 0x1) << 26)
+#define   G_028C70_RAT(x)                              (((x) >> 26) & 0x1)
+#define   C_028C70_RAT                                 0xFBFFFFFF
+#define   S_028C70_RESOURCE_TYPE(x)                    (((x) & 0x7) << 27)
+#define   G_028C70_RESOURCE_TYPE(x)                    (((x) >> 27) & 0x7)
+#define   C_028C70_RESOURCE_TYPE                       0xC7FFFFFF
+
 #define	CB_COLOR0_INFO					0x28c70
 #	define CB_FORMAT(x)				((x) << 2)
 #       define CB_ARRAY_MODE(x)                         ((x) << 8)
@@ -984,6 +1211,20 @@
 #	define CB_SOURCE_FORMAT(x)			((x) << 24)
 #	define CB_SF_EXPORT_FULL			0
 #	define CB_SF_EXPORT_NORM			1
+#define R_028C74_CB_COLOR0_ATTRIB                      0x028C74
+#define   S_028C74_NON_DISP_TILING_ORDER(x)            (((x) & 0x1) << 4)
+#define   G_028C74_NON_DISP_TILING_ORDER(x)            (((x) >> 4) & 0x1)
+#define   C_028C74_NON_DISP_TILING_ORDER               0xFFFFFFEF
+#define   S_028C74_TILE_SPLIT(x)                       (((x) & 0xf) << 5)
+#define   G_028C74_TILE_SPLIT(x)                       (((x) >> 5) & 0xf)
+#define   S_028C74_NUM_BANKS(x)                        (((x) & 0x3) << 10)
+#define   G_028C74_NUM_BANKS(x)                        (((x) >> 10) & 0x3)
+#define   S_028C74_BANK_WIDTH(x)                       (((x) & 0x3) << 13)
+#define   G_028C74_BANK_WIDTH(x)                       (((x) >> 13) & 0x3)
+#define   S_028C74_BANK_HEIGHT(x)                      (((x) & 0x3) << 16)
+#define   G_028C74_BANK_HEIGHT(x)                      (((x) >> 16) & 0x3)
+#define   S_028C74_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 19)
+#define   G_028C74_MACRO_TILE_ASPECT(x)                (((x) >> 19) & 0x3)
 #define	CB_COLOR0_ATTRIB				0x28c74
 #       define CB_TILE_SPLIT(x)                         (((x) & 0x7) << 5)
 #       define ADDR_SURF_TILE_SPLIT_64B                 0
@@ -1008,6 +1249,7 @@
 #       define ADDR_SURF_BANK_HEIGHT_2                  1
 #       define ADDR_SURF_BANK_HEIGHT_4                  2
 #       define ADDR_SURF_BANK_HEIGHT_8                  3
+#       define CB_MACRO_TILE_ASPECT(x)                  (((x) & 0x3) << 19)
 #define	CB_COLOR0_DIM					0x28c78
 /* only CB0-7 blocks have these regs */
 #define	CB_COLOR0_CMASK					0x28c7c
@@ -1196,9 +1438,144 @@
 #define SQ_TEX_RESOURCE_WORD6_0                         0x30018
 #       define TEX_TILE_SPLIT(x)                        (((x) & 0x7) << 29)
 #define SQ_TEX_RESOURCE_WORD7_0                         0x3001c
+#       define MACRO_TILE_ASPECT(x)                     (((x) & 0x3) << 6)
 #       define TEX_BANK_WIDTH(x)                        (((x) & 0x3) << 8)
 #       define TEX_BANK_HEIGHT(x)                       (((x) & 0x3) << 10)
 #       define TEX_NUM_BANKS(x)                         (((x) & 0x3) << 16)
+#define R_030000_SQ_TEX_RESOURCE_WORD0_0             0x030000
+#define   S_030000_DIM(x)                              (((x) & 0x7) << 0)
+#define   G_030000_DIM(x)                              (((x) >> 0) & 0x7)
+#define   C_030000_DIM                                 0xFFFFFFF8
+#define     V_030000_SQ_TEX_DIM_1D                     0x00000000
+#define     V_030000_SQ_TEX_DIM_2D                     0x00000001
+#define     V_030000_SQ_TEX_DIM_3D                     0x00000002
+#define     V_030000_SQ_TEX_DIM_CUBEMAP                0x00000003
+#define     V_030000_SQ_TEX_DIM_1D_ARRAY               0x00000004
+#define     V_030000_SQ_TEX_DIM_2D_ARRAY               0x00000005
+#define     V_030000_SQ_TEX_DIM_2D_MSAA                0x00000006
+#define     V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA          0x00000007
+#define   S_030000_NON_DISP_TILING_ORDER(x)            (((x) & 0x1) << 5)
+#define   G_030000_NON_DISP_TILING_ORDER(x)            (((x) >> 5) & 0x1)
+#define   C_030000_NON_DISP_TILING_ORDER               0xFFFFFFDF
+#define   S_030000_PITCH(x)                            (((x) & 0xFFF) << 6)
+#define   G_030000_PITCH(x)                            (((x) >> 6) & 0xFFF)
+#define   C_030000_PITCH                               0xFFFC003F
+#define   S_030000_TEX_WIDTH(x)                        (((x) & 0x3FFF) << 18)
+#define   G_030000_TEX_WIDTH(x)                        (((x) >> 18) & 0x3FFF)
+#define   C_030000_TEX_WIDTH                           0x0003FFFF
+#define R_030004_SQ_TEX_RESOURCE_WORD1_0             0x030004
+#define   S_030004_TEX_HEIGHT(x)                       (((x) & 0x3FFF) << 0)
+#define   G_030004_TEX_HEIGHT(x)                       (((x) >> 0) & 0x3FFF)
+#define   C_030004_TEX_HEIGHT                          0xFFFFC000
+#define   S_030004_TEX_DEPTH(x)                        (((x) & 0x1FFF) << 14)
+#define   G_030004_TEX_DEPTH(x)                        (((x) >> 14) & 0x1FFF)
+#define   C_030004_TEX_DEPTH                           0xF8003FFF
+#define   S_030004_ARRAY_MODE(x)                       (((x) & 0xF) << 28)
+#define   G_030004_ARRAY_MODE(x)                       (((x) >> 28) & 0xF)
+#define   C_030004_ARRAY_MODE                          0x0FFFFFFF
+#define R_030008_SQ_TEX_RESOURCE_WORD2_0             0x030008
+#define   S_030008_BASE_ADDRESS(x)                     (((x) & 0xFFFFFFFF) << 0)
+#define   G_030008_BASE_ADDRESS(x)                     (((x) >> 0) & 0xFFFFFFFF)
+#define   C_030008_BASE_ADDRESS                        0x00000000
+#define R_03000C_SQ_TEX_RESOURCE_WORD3_0             0x03000C
+#define   S_03000C_MIP_ADDRESS(x)                      (((x) & 0xFFFFFFFF) << 0)
+#define   G_03000C_MIP_ADDRESS(x)                      (((x) >> 0) & 0xFFFFFFFF)
+#define   C_03000C_MIP_ADDRESS                         0x00000000
+#define R_030010_SQ_TEX_RESOURCE_WORD4_0             0x030010
+#define   S_030010_FORMAT_COMP_X(x)                    (((x) & 0x3) << 0)
+#define   G_030010_FORMAT_COMP_X(x)                    (((x) >> 0) & 0x3)
+#define   C_030010_FORMAT_COMP_X                       0xFFFFFFFC
+#define     V_030010_SQ_FORMAT_COMP_UNSIGNED           0x00000000
+#define     V_030010_SQ_FORMAT_COMP_SIGNED             0x00000001
+#define     V_030010_SQ_FORMAT_COMP_UNSIGNED_BIASED    0x00000002
+#define   S_030010_FORMAT_COMP_Y(x)                    (((x) & 0x3) << 2)
+#define   G_030010_FORMAT_COMP_Y(x)                    (((x) >> 2) & 0x3)
+#define   C_030010_FORMAT_COMP_Y                       0xFFFFFFF3
+#define   S_030010_FORMAT_COMP_Z(x)                    (((x) & 0x3) << 4)
+#define   G_030010_FORMAT_COMP_Z(x)                    (((x) >> 4) & 0x3)
+#define   C_030010_FORMAT_COMP_Z                       0xFFFFFFCF
+#define   S_030010_FORMAT_COMP_W(x)                    (((x) & 0x3) << 6)
+#define   G_030010_FORMAT_COMP_W(x)                    (((x) >> 6) & 0x3)
+#define   C_030010_FORMAT_COMP_W                       0xFFFFFF3F
+#define   S_030010_NUM_FORMAT_ALL(x)                   (((x) & 0x3) << 8)
+#define   G_030010_NUM_FORMAT_ALL(x)                   (((x) >> 8) & 0x3)
+#define   C_030010_NUM_FORMAT_ALL                      0xFFFFFCFF
+#define     V_030010_SQ_NUM_FORMAT_NORM                0x00000000
+#define     V_030010_SQ_NUM_FORMAT_INT                 0x00000001
+#define     V_030010_SQ_NUM_FORMAT_SCALED              0x00000002
+#define   S_030010_SRF_MODE_ALL(x)                     (((x) & 0x1) << 10)
+#define   G_030010_SRF_MODE_ALL(x)                     (((x) >> 10) & 0x1)
+#define   C_030010_SRF_MODE_ALL                        0xFFFFFBFF
+#define     V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE     0x00000000
+#define     V_030010_SRF_MODE_NO_ZERO                  0x00000001
+#define   S_030010_FORCE_DEGAMMA(x)                    (((x) & 0x1) << 11)
+#define   G_030010_FORCE_DEGAMMA(x)                    (((x) >> 11) & 0x1)
+#define   C_030010_FORCE_DEGAMMA                       0xFFFFF7FF
+#define   S_030010_ENDIAN_SWAP(x)                      (((x) & 0x3) << 12)
+#define   G_030010_ENDIAN_SWAP(x)                      (((x) >> 12) & 0x3)
+#define   C_030010_ENDIAN_SWAP                         0xFFFFCFFF
+#define   S_030010_DST_SEL_X(x)                        (((x) & 0x7) << 16)
+#define   G_030010_DST_SEL_X(x)                        (((x) >> 16) & 0x7)
+#define   C_030010_DST_SEL_X                           0xFFF8FFFF
+#define     V_030010_SQ_SEL_X                          0x00000000
+#define     V_030010_SQ_SEL_Y                          0x00000001
+#define     V_030010_SQ_SEL_Z                          0x00000002
+#define     V_030010_SQ_SEL_W                          0x00000003
+#define     V_030010_SQ_SEL_0                          0x00000004
+#define     V_030010_SQ_SEL_1                          0x00000005
+#define   S_030010_DST_SEL_Y(x)                        (((x) & 0x7) << 19)
+#define   G_030010_DST_SEL_Y(x)                        (((x) >> 19) & 0x7)
+#define   C_030010_DST_SEL_Y                           0xFFC7FFFF
+#define   S_030010_DST_SEL_Z(x)                        (((x) & 0x7) << 22)
+#define   G_030010_DST_SEL_Z(x)                        (((x) >> 22) & 0x7)
+#define   C_030010_DST_SEL_Z                           0xFE3FFFFF
+#define   S_030010_DST_SEL_W(x)                        (((x) & 0x7) << 25)
+#define   G_030010_DST_SEL_W(x)                        (((x) >> 25) & 0x7)
+#define   C_030010_DST_SEL_W                           0xF1FFFFFF
+#define   S_030010_BASE_LEVEL(x)                       (((x) & 0xF) << 28)
+#define   G_030010_BASE_LEVEL(x)                       (((x) >> 28) & 0xF)
+#define   C_030010_BASE_LEVEL                          0x0FFFFFFF
+#define R_030014_SQ_TEX_RESOURCE_WORD5_0             0x030014
+#define   S_030014_LAST_LEVEL(x)                       (((x) & 0xF) << 0)
+#define   G_030014_LAST_LEVEL(x)                       (((x) >> 0) & 0xF)
+#define   C_030014_LAST_LEVEL                          0xFFFFFFF0
+#define   S_030014_BASE_ARRAY(x)                       (((x) & 0x1FFF) << 4)
+#define   G_030014_BASE_ARRAY(x)                       (((x) >> 4) & 0x1FFF)
+#define   C_030014_BASE_ARRAY                          0xFFFE000F
+#define   S_030014_LAST_ARRAY(x)                       (((x) & 0x1FFF) << 17)
+#define   G_030014_LAST_ARRAY(x)                       (((x) >> 17) & 0x1FFF)
+#define   C_030014_LAST_ARRAY                          0xC001FFFF
+#define R_030018_SQ_TEX_RESOURCE_WORD6_0             0x030018
+#define   S_030018_MAX_ANISO(x)                        (((x) & 0x7) << 0)
+#define   G_030018_MAX_ANISO(x)                        (((x) >> 0) & 0x7)
+#define   C_030018_MAX_ANISO                           0xFFFFFFF8
+#define   S_030018_PERF_MODULATION(x)                  (((x) & 0x7) << 3)
+#define   G_030018_PERF_MODULATION(x)                  (((x) >> 3) & 0x7)
+#define   C_030018_PERF_MODULATION                     0xFFFFFFC7
+#define   S_030018_INTERLACED(x)                       (((x) & 0x1) << 6)
+#define   G_030018_INTERLACED(x)                       (((x) >> 6) & 0x1)
+#define   C_030018_INTERLACED                          0xFFFFFFBF
+#define   S_030018_TILE_SPLIT(x)                       (((x) & 0x7) << 29)
+#define   G_030018_TILE_SPLIT(x)                       (((x) >> 29) & 0x7)
+#define R_03001C_SQ_TEX_RESOURCE_WORD7_0             0x03001C
+#define   S_03001C_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 6)
+#define   G_03001C_MACRO_TILE_ASPECT(x)                (((x) >> 6) & 0x3)
+#define   S_03001C_BANK_WIDTH(x)                       (((x) & 0x3) << 8)
+#define   G_03001C_BANK_WIDTH(x)                       (((x) >> 8) & 0x3)
+#define   S_03001C_BANK_HEIGHT(x)                      (((x) & 0x3) << 10)
+#define   G_03001C_BANK_HEIGHT(x)                      (((x) >> 10) & 0x3)
+#define   S_03001C_NUM_BANKS(x)                        (((x) & 0x3) << 16)
+#define   G_03001C_NUM_BANKS(x)                        (((x) >> 16) & 0x3)
+#define   S_03001C_TYPE(x)                             (((x) & 0x3) << 30)
+#define   G_03001C_TYPE(x)                             (((x) >> 30) & 0x3)
+#define   C_03001C_TYPE                                0x3FFFFFFF
+#define     V_03001C_SQ_TEX_VTX_INVALID_TEXTURE        0x00000000
+#define     V_03001C_SQ_TEX_VTX_INVALID_BUFFER         0x00000001
+#define     V_03001C_SQ_TEX_VTX_VALID_TEXTURE          0x00000002
+#define     V_03001C_SQ_TEX_VTX_VALID_BUFFER           0x00000003
+#define   S_03001C_DATA_FORMAT(x)                      (((x) & 0x3F) << 0)
+#define   G_03001C_DATA_FORMAT(x)                      (((x) >> 0) & 0x3F)
+#define   C_03001C_DATA_FORMAT                         0xFFFFFFC0
 
 #define SQ_VTX_CONSTANT_WORD0_0				0x30000
 #define SQ_VTX_CONSTANT_WORD1_0				0x30004
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 18cd84f..2d96e93 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -87,23 +87,27 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
 		r100_cs_dump_packet(p, pkt);
 		return r;
 	}
+
 	value = radeon_get_ib_value(p, idx);
 	tmp = value & 0x003fffff;
 	tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
 
-	if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-		tile_flags |= RADEON_DST_TILE_MACRO;
-	if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-		if (reg == RADEON_SRC_PITCH_OFFSET) {
-			DRM_ERROR("Cannot src blit from microtiled surface\n");
-			r100_cs_dump_packet(p, pkt);
-			return -EINVAL;
+	if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+			tile_flags |= RADEON_DST_TILE_MACRO;
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+			if (reg == RADEON_SRC_PITCH_OFFSET) {
+				DRM_ERROR("Cannot src blit from microtiled surface\n");
+				r100_cs_dump_packet(p, pkt);
+				return -EINVAL;
+			}
+			tile_flags |= RADEON_DST_TILE_MICRO;
 		}
-		tile_flags |= RADEON_DST_TILE_MICRO;
-	}
 
-	tmp |= tile_flags;
-	p->ib->ptr[idx] = (value & 0x3fc00000) | tmp;
+		tmp |= tile_flags;
+		p->ib->ptr[idx] = (value & 0x3fc00000) | tmp;
+	} else
+		p->ib->ptr[idx] = (value & 0xffc00000) | tmp;
 	return 0;
 }
 
@@ -1552,7 +1556,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
 			r100_cs_dump_packet(p, pkt);
 			return r;
 		}
-		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
+		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+				tile_flags |= RADEON_TXO_MACRO_TILE;
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+				tile_flags |= RADEON_TXO_MICRO_TILE_X2;
+
+			tmp = idx_value & ~(0x7 << 2);
+			tmp |= tile_flags;
+			ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset);
+		} else
+			ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
 		track->textures[i].robj = reloc->robj;
 		track->tex_dirty = true;
 		break;
@@ -1623,15 +1637,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
 			r100_cs_dump_packet(p, pkt);
 			return r;
 		}
-
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-			tile_flags |= RADEON_COLOR_TILE_ENABLE;
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-			tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
-
-		tmp = idx_value & ~(0x7 << 16);
-		tmp |= tile_flags;
-		ib[idx] = tmp;
+		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+				tile_flags |= RADEON_COLOR_TILE_ENABLE;
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+				tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
+
+			tmp = idx_value & ~(0x7 << 16);
+			tmp |= tile_flags;
+			ib[idx] = tmp;
+		} else
+			ib[idx] = idx_value;
 
 		track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
 		track->cb_dirty = true;
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index eba4cbf..a59cc47 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -215,7 +215,17 @@ int r200_packet0_check(struct radeon_cs_parser *p,
 			r100_cs_dump_packet(p, pkt);
 			return r;
 		}
-		ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
+		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+				tile_flags |= R200_TXO_MACRO_TILE;
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+				tile_flags |= R200_TXO_MICRO_TILE;
+
+			tmp = idx_value & ~(0x7 << 2);
+			tmp |= tile_flags;
+			ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset);
+		} else
+			ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
 		track->textures[i].robj = reloc->robj;
 		track->tex_dirty = true;
 		break;
@@ -277,14 +287,17 @@ int r200_packet0_check(struct radeon_cs_parser *p,
 			return r;
 		}
 
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-			tile_flags |= RADEON_COLOR_TILE_ENABLE;
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-			tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
+		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+				tile_flags |= RADEON_COLOR_TILE_ENABLE;
+			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+				tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
 
-		tmp = idx_value & ~(0x7 << 16);
-		tmp |= tile_flags;
-		ib[idx] = tmp;
+			tmp = idx_value & ~(0x7 << 16);
+			tmp |= tile_flags;
+			ib[idx] = tmp;
+		} else
+			ib[idx] = idx_value;
 
 		track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
 		track->cb_dirty = true;
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index accc032..db38f58 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -30,20 +30,7 @@
 
 #include "r600d.h"
 #include "r600_blit_shaders.h"
-
-#define DI_PT_RECTLIST        0x11
-#define DI_INDEX_SIZE_16_BIT  0x0
-#define DI_SRC_SEL_AUTO_INDEX 0x2
-
-#define FMT_8                 0x1
-#define FMT_5_6_5             0x8
-#define FMT_8_8_8_8           0x1a
-#define COLOR_8               0x1
-#define COLOR_5_6_5           0x8
-#define COLOR_8_8_8_8         0x1a
-
-#define RECT_UNIT_H           32
-#define RECT_UNIT_W           (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
+#include "radeon_blit_common.h"
 
 /* emits 21 on rv770+, 23 on r600 */
 static void
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 38ce5d0..5cbe948 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -55,12 +55,17 @@ struct r600_cs_track {
 	struct radeon_bo	*cb_color_frag_bo[8];
 	struct radeon_bo	*cb_color_tile_bo[8];
 	u32			cb_color_info[8];
+	u32			cb_color_view[8];
 	u32			cb_color_size_idx[8];
 	u32			cb_target_mask;
 	u32			cb_shader_mask;
 	u32			cb_color_size[8];
 	u32			vgt_strmout_en;
 	u32			vgt_strmout_buffer_en;
+	struct radeon_bo	*vgt_strmout_bo[4];
+	u64			vgt_strmout_bo_mc[4];
+	u32			vgt_strmout_bo_offset[4];
+	u32			vgt_strmout_size[4];
 	u32			db_depth_control;
 	u32			db_depth_info;
 	u32			db_depth_size_idx;
@@ -73,9 +78,9 @@ struct r600_cs_track {
 
 #define FMT_8_BIT(fmt, vc)   [fmt] = { 1, 1, 1, vc, CHIP_R600 }
 #define FMT_16_BIT(fmt, vc)  [fmt] = { 1, 1, 2, vc, CHIP_R600 }
-#define FMT_24_BIT(fmt)      [fmt] = { 1, 1, 3,  0, CHIP_R600 }
+#define FMT_24_BIT(fmt)      [fmt] = { 1, 1, 4,  0, CHIP_R600 }
 #define FMT_32_BIT(fmt, vc)  [fmt] = { 1, 1, 4, vc, CHIP_R600 }
-#define FMT_48_BIT(fmt)      [fmt] = { 1, 1, 6,  0, CHIP_R600 }
+#define FMT_48_BIT(fmt)      [fmt] = { 1, 1, 8,  0, CHIP_R600 }
 #define FMT_64_BIT(fmt, vc)  [fmt] = { 1, 1, 8, vc, CHIP_R600 }
 #define FMT_96_BIT(fmt)      [fmt] = { 1, 1, 12, 0, CHIP_R600 }
 #define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 }
@@ -107,7 +112,7 @@ static const struct gpu_formats color_formats_table[] = {
 
 	/* 24-bit */
 	FMT_24_BIT(V_038004_FMT_8_8_8),
-					       
+
 	/* 32-bit */
 	FMT_32_BIT(V_038004_COLOR_32, 1),
 	FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1),
@@ -162,22 +167,22 @@ static const struct gpu_formats color_formats_table[] = {
 	[V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR},
 };
 
-static bool fmt_is_valid_color(u32 format)
+bool r600_fmt_is_valid_color(u32 format)
 {
 	if (format >= ARRAY_SIZE(color_formats_table))
 		return false;
-	
+
 	if (color_formats_table[format].valid_color)
 		return true;
 
 	return false;
 }
 
-static bool fmt_is_valid_texture(u32 format, enum radeon_family family)
+bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family)
 {
 	if (format >= ARRAY_SIZE(color_formats_table))
 		return false;
-	
+
 	if (family < color_formats_table[format].min_family)
 		return false;
 
@@ -187,7 +192,7 @@ static bool fmt_is_valid_texture(u32 format, enum radeon_family family)
 	return false;
 }
 
-static int fmt_get_blocksize(u32 format)
+int r600_fmt_get_blocksize(u32 format)
 {
 	if (format >= ARRAY_SIZE(color_formats_table))
 		return 0;
@@ -195,7 +200,7 @@ static int fmt_get_blocksize(u32 format)
 	return color_formats_table[format].blocksize;
 }
 
-static int fmt_get_nblocksx(u32 format, u32 w)
+int r600_fmt_get_nblocksx(u32 format, u32 w)
 {
 	unsigned bw;
 
@@ -209,7 +214,7 @@ static int fmt_get_nblocksx(u32 format, u32 w)
 	return (w + bw - 1) / bw;
 }
 
-static int fmt_get_nblocksy(u32 format, u32 h)
+int r600_fmt_get_nblocksy(u32 format, u32 h)
 {
 	unsigned bh;
 
@@ -256,7 +261,7 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values,
 		break;
 	case ARRAY_LINEAR_ALIGNED:
 		*pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize));
-		*height_align = tile_height;
+		*height_align = 1;
 		*depth_align = 1;
 		*base_align = values->group_size;
 		break;
@@ -269,10 +274,9 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values,
 		*base_align = values->group_size;
 		break;
 	case ARRAY_2D_TILED_THIN1:
-		*pitch_align = max((u32)macro_tile_width,
-				  (u32)(((values->group_size / tile_height) /
-					 (values->blocksize * values->nsamples)) *
-					values->nbanks)) * tile_width;
+		*pitch_align = max((u32)macro_tile_width * tile_width,
+				(u32)((values->group_size * values->nbanks) /
+				(values->blocksize * values->nsamples * tile_width)));
 		*height_align = macro_tile_height * tile_height;
 		*depth_align = 1;
 		*base_align = max(macro_tile_bytes,
@@ -296,6 +300,7 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 		track->cb_color_size[i] = 0;
 		track->cb_color_size_idx[i] = 0;
 		track->cb_color_info[i] = 0;
+		track->cb_color_view[i] = 0xFFFFFFFF;
 		track->cb_color_bo[i] = NULL;
 		track->cb_color_bo_offset[i] = 0xFFFFFFFF;
 		track->cb_color_bo_mc[i] = 0xFFFFFFFF;
@@ -310,6 +315,13 @@ static void r600_cs_track_init(struct r600_cs_track *track)
 	track->db_depth_size = 0xFFFFFFFF;
 	track->db_depth_size_idx = 0;
 	track->db_depth_control = 0xFFFFFFFF;
+
+	for (i = 0; i < 4; i++) {
+		track->vgt_strmout_size[i] = 0;
+		track->vgt_strmout_bo[i] = NULL;
+		track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF;
+		track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF;
+	}
 }
 
 static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
@@ -322,13 +334,14 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	volatile u32 *ib = p->ib->ptr;
 	unsigned array_mode;
 	u32 format;
+
 	if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
 		dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
 		return -EINVAL;
 	}
 	size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
 	format = G_0280A0_FORMAT(track->cb_color_info[i]);
-	if (!fmt_is_valid_color(format)) {
+	if (!r600_fmt_is_valid_color(format)) {
 		dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
 			 __func__, __LINE__, format,
 			i, track->cb_color_info[i]);
@@ -349,7 +362,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	array_check.nbanks = track->nbanks;
 	array_check.npipes = track->npipes;
 	array_check.nsamples = track->nsamples;
-	array_check.blocksize = fmt_get_blocksize(format);
+	array_check.blocksize = r600_fmt_get_blocksize(format);
 	if (r600_get_array_mode_alignment(&array_check,
 					  &pitch_align, &height_align, &depth_align, &base_align)) {
 		dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@@ -393,7 +406,18 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	}
 
 	/* check offset */
-	tmp = fmt_get_nblocksy(format, height) * fmt_get_nblocksx(format, pitch) * fmt_get_blocksize(format);
+	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format);
+	switch (array_mode) {
+	default:
+	case V_0280A0_ARRAY_LINEAR_GENERAL:
+	case V_0280A0_ARRAY_LINEAR_ALIGNED:
+		tmp += track->cb_color_view[i] & 0xFF;
+		break;
+	case V_0280A0_ARRAY_1D_TILED_THIN1:
+	case V_0280A0_ARRAY_2D_TILED_THIN1:
+		tmp += G_028080_SLICE_MAX(track->cb_color_view[i]) * tmp;
+		break;
+	}
 	if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
 		if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
 			/* the initial DDX does bad things with the CB size occasionally */
@@ -403,10 +427,13 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 			 * broken userspace.
 			 */
 		} else {
-			dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i,
-				 array_mode,
+			dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
+				 __func__, i, array_mode,
 				 track->cb_color_bo_offset[i], tmp,
-				 radeon_bo_size(track->cb_color_bo[i]));
+				 radeon_bo_size(track->cb_color_bo[i]),
+				 pitch, height, r600_fmt_get_nblocksx(format, pitch),
+				 r600_fmt_get_nblocksy(format, height),
+				 r600_fmt_get_blocksize(format));
 			return -EINVAL;
 		}
 	}
@@ -430,11 +457,28 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
 	/* on legacy kernel we don't perform advanced check */
 	if (p->rdev == NULL)
 		return 0;
-	/* we don't support out buffer yet */
-	if (track->vgt_strmout_en || track->vgt_strmout_buffer_en) {
-		dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
-		return -EINVAL;
+
+	/* check streamout */
+	if (track->vgt_strmout_en) {
+		for (i = 0; i < 4; i++) {
+			if (track->vgt_strmout_buffer_en & (1 << i)) {
+				if (track->vgt_strmout_bo[i]) {
+					u64 offset = (u64)track->vgt_strmout_bo_offset[i] +
+						(u64)track->vgt_strmout_size[i];
+					if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
+						DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n",
+							  i, offset,
+							  radeon_bo_size(track->vgt_strmout_bo[i]));
+						return -EINVAL;
+					}
+				} else {
+					dev_warn(p->dev, "No buffer for streamout %d\n", i);
+					return -EINVAL;
+				}
+			}
+		}
 	}
+
 	/* check that we have a cb for each enabled target, we don't check
 	 * shader_mask because it seems mesa isn't always setting it :(
 	 */
@@ -975,6 +1019,39 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 	case R_028B20_VGT_STRMOUT_BUFFER_EN:
 		track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx);
 		break;
+	case VGT_STRMOUT_BUFFER_BASE_0:
+	case VGT_STRMOUT_BUFFER_BASE_1:
+	case VGT_STRMOUT_BUFFER_BASE_2:
+	case VGT_STRMOUT_BUFFER_BASE_3:
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "bad SET_CONTEXT_REG "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16;
+		track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		track->vgt_strmout_bo[tmp] = reloc->robj;
+		track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset;
+		break;
+	case VGT_STRMOUT_BUFFER_SIZE_0:
+	case VGT_STRMOUT_BUFFER_SIZE_1:
+	case VGT_STRMOUT_BUFFER_SIZE_2:
+	case VGT_STRMOUT_BUFFER_SIZE_3:
+		tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16;
+		/* size in register is DWs, convert to bytes */
+		track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4;
+		break;
+	case CP_COHER_BASE:
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			dev_warn(p->dev, "missing reloc for CP_COHER_BASE "
+					"0x%04X\n", reg);
+			return -EINVAL;
+		}
+		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		break;
 	case R_028238_CB_TARGET_MASK:
 		track->cb_target_mask = radeon_get_ib_value(p, idx);
 		break;
@@ -1014,6 +1091,17 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 			track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
 		}
 		break;
+	case R_028080_CB_COLOR0_VIEW:
+	case R_028084_CB_COLOR1_VIEW:
+	case R_028088_CB_COLOR2_VIEW:
+	case R_02808C_CB_COLOR3_VIEW:
+	case R_028090_CB_COLOR4_VIEW:
+	case R_028094_CB_COLOR5_VIEW:
+	case R_028098_CB_COLOR6_VIEW:
+	case R_02809C_CB_COLOR7_VIEW:
+		tmp = (reg - R_028080_CB_COLOR0_VIEW) / 4;
+		track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
+		break;
 	case R_028060_CB_COLOR0_SIZE:
 	case R_028064_CB_COLOR1_SIZE:
 	case R_028068_CB_COLOR2_SIZE:
@@ -1198,7 +1286,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 	return 0;
 }
 
-static unsigned mip_minify(unsigned size, unsigned level)
+unsigned r600_mip_minify(unsigned size, unsigned level)
 {
 	unsigned val;
 
@@ -1220,22 +1308,22 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
 	unsigned nlevels = llevel - blevel + 1;
 
 	*l0_size = -1;
-	blocksize = fmt_get_blocksize(format);
+	blocksize = r600_fmt_get_blocksize(format);
 
-	w0 = mip_minify(w0, 0);
-	h0 = mip_minify(h0, 0);
-	d0 = mip_minify(d0, 0);
+	w0 = r600_mip_minify(w0, 0);
+	h0 = r600_mip_minify(h0, 0);
+	d0 = r600_mip_minify(d0, 0);
 	for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) {
-		width = mip_minify(w0, i);
-		nbx = fmt_get_nblocksx(format, width);
+		width = r600_mip_minify(w0, i);
+		nbx = r600_fmt_get_nblocksx(format, width);
 
 		nbx = round_up(nbx, block_align);
 
-		height = mip_minify(h0, i);
-		nby = fmt_get_nblocksy(format, height);
+		height = r600_mip_minify(h0, i);
+		nby = r600_fmt_get_nblocksy(format, height);
 		nby = round_up(nby, height_align);
 
-		depth = mip_minify(d0, i);
+		depth = r600_mip_minify(d0, i);
 
 		size = nbx * nby * blocksize;
 		if (nfaces)
@@ -1326,7 +1414,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
 		return -EINVAL;
 	}
 	format = G_038004_DATA_FORMAT(word1);
-	if (!fmt_is_valid_texture(format, p->family)) {
+	if (!r600_fmt_is_valid_texture(format, p->family)) {
 		dev_warn(p->dev, "%s:%d texture invalid format %d\n",
 			 __func__, __LINE__, format);
 		return -EINVAL;
@@ -1339,7 +1427,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
 	array_check.nbanks = track->nbanks;
 	array_check.npipes = track->npipes;
 	array_check.nsamples = 1;
-	array_check.blocksize = fmt_get_blocksize(format);
+	array_check.blocksize = r600_fmt_get_blocksize(format);
 	if (r600_get_array_mode_alignment(&array_check,
 					  &pitch_align, &height_align, &depth_align, &base_align)) {
 		dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
@@ -1372,6 +1460,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
 	word1 = radeon_get_ib_value(p, idx + 5);
 	blevel = G_038010_BASE_LEVEL(word0);
 	llevel = G_038014_LAST_LEVEL(word1);
+	if (blevel > llevel) {
+		dev_warn(p->dev, "texture blevel %d > llevel %d\n",
+			 blevel, llevel);
+	}
 	if (array == 1) {
 		barray = G_038014_BASE_ARRAY(word1);
 		larray = G_038014_LAST_ARRAY(word1);
@@ -1383,8 +1475,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
 			  &l0_size, &mipmap_size);
 	/* using get ib will give us the offset into the texture bo */
 	if ((l0_size + word2) > radeon_bo_size(texture)) {
-		dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n",
-			w0, h0, format, word2, l0_size, radeon_bo_size(texture));
+		dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n",
+			 w0, h0, pitch_align, height_align,
+			 array_check.array_mode, format, word2,
+			 l0_size, radeon_bo_size(texture));
 		dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align);
 		return -EINVAL;
 	}
@@ -1397,6 +1491,22 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
 	return 0;
 }
 
+static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
+{
+	u32 m, i;
+
+	i = (reg >> 7);
+	if (i >= ARRAY_SIZE(r600_reg_safe_bm)) {
+		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+		return false;
+	}
+	m = 1 << ((reg >> 2) & 31);
+	if (!(r600_reg_safe_bm[i] & m))
+		return true;
+	dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
+	return false;
+}
+
 static int r600_packet3_check(struct radeon_cs_parser *p,
 				struct radeon_cs_packet *pkt)
 {
@@ -1742,6 +1852,100 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
 			return -EINVAL;
 		}
 		break;
+	case PACKET3_STRMOUT_BUFFER_UPDATE:
+		if (pkt->count != 4) {
+			DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n");
+			return -EINVAL;
+		}
+		/* Updating memory at DST_ADDRESS. */
+		if (idx_value & 0x1) {
+			u64 offset;
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+1);
+			offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		}
+		/* Reading data from SRC_ADDRESS. */
+		if (((idx_value >> 1) & 0x3) == 2) {
+			u64 offset;
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+3);
+			offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		}
+		break;
+	case PACKET3_COPY_DW:
+		if (pkt->count != 4) {
+			DRM_ERROR("bad COPY_DW (invalid count)\n");
+			return -EINVAL;
+		}
+		if (idx_value & 0x1) {
+			u64 offset;
+			/* SRC is memory. */
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad COPY_DW (missing src reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+1);
+			offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		} else {
+			/* SRC is a reg. */
+			reg = radeon_get_ib_value(p, idx+1) << 2;
+			if (!r600_is_safe_reg(p, reg, idx+1))
+				return -EINVAL;
+		}
+		if (idx_value & 0x2) {
+			u64 offset;
+			/* DST is memory. */
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad COPY_DW (missing dst reloc)\n");
+				return -EINVAL;
+			}
+			offset = radeon_get_ib_value(p, idx+3);
+			offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
+			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
+				DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n",
+					  offset + 4, radeon_bo_size(reloc->robj));
+				return -EINVAL;
+			}
+			ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		} else {
+			/* DST is a reg. */
+			reg = radeon_get_ib_value(p, idx+3) << 2;
+			if (!r600_is_safe_reg(p, reg, idx+3))
+				return -EINVAL;
+		}
+		break;
 	case PACKET3_NOP:
 		break;
 	default:
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 3ee1fd7..2ba460b 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -78,6 +78,20 @@
 
 #define CB_COLOR0_SIZE                                  0x28060
 #define CB_COLOR0_VIEW                                  0x28080
+#define R_028080_CB_COLOR0_VIEW                      0x028080
+#define   S_028080_SLICE_START(x)                      (((x) & 0x7FF) << 0)
+#define   G_028080_SLICE_START(x)                      (((x) >> 0) & 0x7FF)
+#define   C_028080_SLICE_START                         0xFFFFF800
+#define   S_028080_SLICE_MAX(x)                        (((x) & 0x7FF) << 13)
+#define   G_028080_SLICE_MAX(x)                        (((x) >> 13) & 0x7FF)
+#define   C_028080_SLICE_MAX                           0xFF001FFF
+#define R_028084_CB_COLOR1_VIEW                      0x028084
+#define R_028088_CB_COLOR2_VIEW                      0x028088
+#define R_02808C_CB_COLOR3_VIEW                      0x02808C
+#define R_028090_CB_COLOR4_VIEW                      0x028090
+#define R_028094_CB_COLOR5_VIEW                      0x028094
+#define R_028098_CB_COLOR6_VIEW                      0x028098
+#define R_02809C_CB_COLOR7_VIEW                      0x02809C
 #define CB_COLOR0_INFO                                  0x280a0
 #	define CB_FORMAT(x)				((x) << 2)
 #       define CB_ARRAY_MODE(x)                         ((x) << 8)
@@ -493,6 +507,11 @@
 #define	VGT_STRMOUT_BUFFER_OFFSET_1			0x28AEC
 #define	VGT_STRMOUT_BUFFER_OFFSET_2			0x28AFC
 #define	VGT_STRMOUT_BUFFER_OFFSET_3			0x28B0C
+#define VGT_STRMOUT_BUFFER_SIZE_0			0x28AD0
+#define VGT_STRMOUT_BUFFER_SIZE_1			0x28AE0
+#define VGT_STRMOUT_BUFFER_SIZE_2			0x28AF0
+#define VGT_STRMOUT_BUFFER_SIZE_3			0x28B00
+
 #define	VGT_STRMOUT_EN					0x28AB0
 #define	VGT_VERTEX_REUSE_BLOCK_CNTL			0x28C58
 #define		VTX_REUSE_DEPTH_MASK				0x000000FF
@@ -834,6 +853,7 @@
 #              define PACKET3_SEM_SEL_SIGNAL	    (0x6 << 29)
 #              define PACKET3_SEM_SEL_WAIT	    (0x7 << 29)
 #define	PACKET3_MPEG_INDEX				0x3A
+#define	PACKET3_COPY_DW					0x3B
 #define	PACKET3_WAIT_REG_MEM				0x3C
 #define	PACKET3_MEM_WRITE				0x3D
 #define	PACKET3_INDIRECT_BUFFER				0x32
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 1668ec1..884e0d4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -242,6 +242,9 @@ extern int rv6xx_get_temp(struct radeon_device *rdev);
 extern int rv770_get_temp(struct radeon_device *rdev);
 extern int evergreen_get_temp(struct radeon_device *rdev);
 extern int sumo_get_temp(struct radeon_device *rdev);
+extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
+				    unsigned *bankh, unsigned *mtaspect,
+				    unsigned *tile_split);
 
 /*
  * Fences.
@@ -1750,6 +1753,16 @@ int r600_vram_scratch_init(struct radeon_device *rdev);
 void r600_vram_scratch_fini(struct radeon_device *rdev);
 
 /*
+ * r600 cs checking helper
+ */
+unsigned r600_mip_minify(unsigned size, unsigned level);
+bool r600_fmt_is_valid_color(u32 format);
+bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family);
+int r600_fmt_get_blocksize(u32 format);
+int r600_fmt_get_nblocksx(u32 format, u32 w);
+int r600_fmt_get_nblocksy(u32 format, u32 h);
+
+/*
  * r600 functions used by radeon_encoder.c
  */
 extern void r600_hdmi_enable(struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c
index 815f234..58cee89 100644
--- a/drivers/gpu/drm/radeon/radeon_benchmark.c
+++ b/drivers/gpu/drm/radeon/radeon_benchmark.c
@@ -208,22 +208,22 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number)
 		break;
 	case 3:
 		/* GTT to VRAM, buffer size sweep, powers of 2 */
-		for (i = 1; i <= 65536; i <<= 1)
-			radeon_benchmark_move(rdev, i*1024,
+		for (i = 1; i <= 16384; i <<= 1)
+			radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
 					      RADEON_GEM_DOMAIN_GTT,
 					      RADEON_GEM_DOMAIN_VRAM);
 		break;
 	case 4:
 		/* VRAM to GTT, buffer size sweep, powers of 2 */
-		for (i = 1; i <= 65536; i <<= 1)
-			radeon_benchmark_move(rdev, i*1024,
+		for (i = 1; i <= 16384; i <<= 1)
+			radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
 					      RADEON_GEM_DOMAIN_VRAM,
 					      RADEON_GEM_DOMAIN_GTT);
 		break;
 	case 5:
 		/* VRAM to VRAM, buffer size sweep, powers of 2 */
-		for (i = 1; i <= 65536; i <<= 1)
-			radeon_benchmark_move(rdev, i*1024,
+		for (i = 1; i <= 16384; i <<= 1)
+			radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
 					      RADEON_GEM_DOMAIN_VRAM,
 					      RADEON_GEM_DOMAIN_VRAM);
 		break;
diff --git a/drivers/gpu/drm/radeon/radeon_blit_common.h b/drivers/gpu/drm/radeon/radeon_blit_common.h
new file mode 100644
index 0000000..4ecbe72
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_blit_common.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ * Copyright 2012 Alcatel-Lucent, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __RADEON_BLIT_COMMON_H__
+
+#define DI_PT_RECTLIST        0x11
+#define DI_INDEX_SIZE_16_BIT  0x0
+#define DI_SRC_SEL_AUTO_INDEX 0x2
+
+#define FMT_8                 0x1
+#define FMT_5_6_5             0x8
+#define FMT_8_8_8_8           0x1a
+#define COLOR_8               0x1
+#define COLOR_5_6_5           0x8
+#define COLOR_8_8_8_8         0x1a
+
+#define RECT_UNIT_H           32
+#define RECT_UNIT_W           (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
+
+#define __RADEON_BLIT_COMMON_H__
+#endif
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 72ae826..0ebb7d4 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -2115,6 +2115,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
 		break;
 	}
 
+	pci_set_master(dev->pdev);
+
 	if (drm_pci_device_is_agp(dev))
 		dev_priv->flags |= RADEON_IS_AGP;
 	else if (pci_is_pcie(dev->pdev))
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 8c49fef..7cb062d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1124,11 +1124,6 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
 	.output_poll_changed = radeon_output_poll_changed
 };
 
-struct drm_prop_enum_list {
-	int type;
-	char *name;
-};
-
 static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
 {	{ 0, "driver" },
 	{ 1, "bios" },
@@ -1153,86 +1148,53 @@ static struct drm_prop_enum_list radeon_underscan_enum_list[] =
 
 static int radeon_modeset_create_props(struct radeon_device *rdev)
 {
-	int i, sz;
+	int sz;
 
 	if (rdev->is_atom_bios) {
 		rdev->mode_info.coherent_mode_property =
-			drm_property_create(rdev->ddev,
-					    DRM_MODE_PROP_RANGE,
-					    "coherent", 2);
+			drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
 		if (!rdev->mode_info.coherent_mode_property)
 			return -ENOMEM;
-
-		rdev->mode_info.coherent_mode_property->values[0] = 0;
-		rdev->mode_info.coherent_mode_property->values[1] = 1;
 	}
 
 	if (!ASIC_IS_AVIVO(rdev)) {
 		sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
 		rdev->mode_info.tmds_pll_property =
-			drm_property_create(rdev->ddev,
-					    DRM_MODE_PROP_ENUM,
-					    "tmds_pll", sz);
-		for (i = 0; i < sz; i++) {
-			drm_property_add_enum(rdev->mode_info.tmds_pll_property,
-					      i,
-					      radeon_tmds_pll_enum_list[i].type,
-					      radeon_tmds_pll_enum_list[i].name);
-		}
+			drm_property_create_enum(rdev->ddev, 0,
+					    "tmds_pll",
+					    radeon_tmds_pll_enum_list, sz);
 	}
 
 	rdev->mode_info.load_detect_property =
-		drm_property_create(rdev->ddev,
-				    DRM_MODE_PROP_RANGE,
-				    "load detection", 2);
+		drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
 	if (!rdev->mode_info.load_detect_property)
 		return -ENOMEM;
-	rdev->mode_info.load_detect_property->values[0] = 0;
-	rdev->mode_info.load_detect_property->values[1] = 1;
 
 	drm_mode_create_scaling_mode_property(rdev->ddev);
 
 	sz = ARRAY_SIZE(radeon_tv_std_enum_list);
 	rdev->mode_info.tv_std_property =
-		drm_property_create(rdev->ddev,
-				    DRM_MODE_PROP_ENUM,
-				    "tv standard", sz);
-	for (i = 0; i < sz; i++) {
-		drm_property_add_enum(rdev->mode_info.tv_std_property,
-				      i,
-				      radeon_tv_std_enum_list[i].type,
-				      radeon_tv_std_enum_list[i].name);
-	}
+		drm_property_create_enum(rdev->ddev, 0,
+				    "tv standard",
+				    radeon_tv_std_enum_list, sz);
 
 	sz = ARRAY_SIZE(radeon_underscan_enum_list);
 	rdev->mode_info.underscan_property =
-		drm_property_create(rdev->ddev,
-				    DRM_MODE_PROP_ENUM,
-				    "underscan", sz);
-	for (i = 0; i < sz; i++) {
-		drm_property_add_enum(rdev->mode_info.underscan_property,
-				      i,
-				      radeon_underscan_enum_list[i].type,
-				      radeon_underscan_enum_list[i].name);
-	}
+		drm_property_create_enum(rdev->ddev, 0,
+				    "underscan",
+				    radeon_underscan_enum_list, sz);
 
 	rdev->mode_info.underscan_hborder_property =
-		drm_property_create(rdev->ddev,
-					DRM_MODE_PROP_RANGE,
-					"underscan hborder", 2);
+		drm_property_create_range(rdev->ddev, 0,
+					"underscan hborder", 0, 128);
 	if (!rdev->mode_info.underscan_hborder_property)
 		return -ENOMEM;
-	rdev->mode_info.underscan_hborder_property->values[0] = 0;
-	rdev->mode_info.underscan_hborder_property->values[1] = 128;
 
 	rdev->mode_info.underscan_vborder_property =
-		drm_property_create(rdev->ddev,
-					DRM_MODE_PROP_RANGE,
-					"underscan vborder", 2);
+		drm_property_create_range(rdev->ddev, 0,
+					"underscan vborder", 0, 128);
 	if (!rdev->mode_info.underscan_vborder_property)
 		return -ENOMEM;
-	rdev->mode_info.underscan_vborder_property->values[0] = 0;
-	rdev->mode_info.underscan_vborder_property->values[1] = 128;
 
 	return 0;
 }
@@ -1278,6 +1240,9 @@ int radeon_modeset_init(struct radeon_device *rdev)
 		rdev->ddev->mode_config.max_height = 4096;
 	}
 
+	rdev->ddev->mode_config.preferred_depth = 24;
+	rdev->ddev->mode_config.prefer_shadow = 1;
+
 	rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
 
 	ret = radeon_modeset_create_props(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 8032f1f..498d21d 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -54,10 +54,11 @@
  *   2.10.0 - fusion 2D tiling
  *   2.11.0 - backend map, initial compute support for the CS checker
  *   2.12.0 - RADEON_CS_KEEP_TILING_FLAGS
- *   2.13.0 - virtual memory support
+ *   2.13.0 - virtual memory support, streamout
+ *   2.14.0 - add evergreen tiling informations
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	13
+#define KMS_DRIVER_MINOR	14
 #define KMS_DRIVER_PATCHLEVEL	0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index cf2bf35..a5692d5 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -254,11 +254,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
 	info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
 	info->apertures->ranges[0].size = rdev->mc.aper_size;
 
-	info->pixmap.size = 64*1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
+	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
 	if (info->screen_base == NULL) {
 		ret = -ENOSPC;
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 98a8ad6..3265a7a 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -30,6 +30,10 @@
 #include "radeon.h"
 #include "atom.h"
 
+extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
+				   struct i2c_msg *msgs, int num);
+extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap);
+
 /**
  * radeon_ddc_probe
  *
@@ -882,6 +886,11 @@ static const struct i2c_algorithm radeon_i2c_algo = {
 	.functionality = radeon_hw_i2c_func,
 };
 
+static const struct i2c_algorithm radeon_atom_i2c_algo = {
+	.master_xfer = radeon_atom_hw_i2c_xfer,
+	.functionality = radeon_atom_hw_i2c_func,
+};
+
 struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
 					  struct radeon_i2c_bus_rec *rec,
 					  const char *name)
@@ -914,6 +923,18 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
 			DRM_ERROR("Failed to register hw i2c %s\n", name);
 			goto out_free;
 		}
+	} else if (rec->hw_capable &&
+		   radeon_hw_i2c &&
+		   ASIC_IS_DCE3(rdev)) {
+		/* hw i2c using atom */
+		snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
+			 "Radeon i2c hw bus %s", name);
+		i2c->adapter.algo = &radeon_atom_i2c_algo;
+		ret = i2c_add_adapter(&i2c->adapter);
+		if (ret) {
+			DRM_ERROR("Failed to register hw i2c %s\n", name);
+			goto out_free;
+		}
 	} else {
 		/* set the radeon bit adapter */
 		snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
@@ -925,10 +946,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
 		i2c->algo.bit.setscl = set_clock;
 		i2c->algo.bit.getsda = get_data;
 		i2c->algo.bit.getscl = get_clock;
-		i2c->algo.bit.udelay = 20;
-		/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
-		 * make this, 2 jiffies is a lot more reliable */
-		i2c->algo.bit.timeout = 2;
+		i2c->algo.bit.udelay = 10;
+		i2c->algo.bit.timeout = usecs_to_jiffies(2200);	/* from VESA */
 		i2c->algo.bit.data = i2c;
 		ret = i2c_bit_add_bus(&i2c->adapter);
 		if (ret) {
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index d335288..1986eba 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -57,6 +57,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 	}
 	dev->dev_private = (void *)rdev;
 
+	pci_set_master(dev->pdev);
+
 	/* update BUS flag */
 	if (drm_pci_device_is_agp(dev)) {
 		flags |= RADEON_IS_AGP;
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index d45df17..342deac 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -445,8 +445,54 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo)
 int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
 				uint32_t tiling_flags, uint32_t pitch)
 {
+	struct radeon_device *rdev = bo->rdev;
 	int r;
 
+	if (rdev->family >= CHIP_CEDAR) {
+		unsigned bankw, bankh, mtaspect, tilesplit, stilesplit;
+
+		bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
+		bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
+		mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
+		tilesplit = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
+		stilesplit = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
+		switch (bankw) {
+		case 0:
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			break;
+		default:
+			return -EINVAL;
+		}
+		switch (bankh) {
+		case 0:
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			break;
+		default:
+			return -EINVAL;
+		}
+		switch (mtaspect) {
+		case 0:
+		case 1:
+		case 2:
+		case 4:
+		case 8:
+			break;
+		default:
+			return -EINVAL;
+		}
+		if (tilesplit > 6) {
+			return -EINVAL;
+		}
+		if (stilesplit > 6) {
+			return -EINVAL;
+		}
+	}
 	r = radeon_bo_reserve(bo, false);
 	if (unlikely(r != 0))
 		return r;
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman
index 2316977..7b526d3 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/cayman
+++ b/drivers/gpu/drm/radeon/reg_srcs/cayman
@@ -1,5 +1,8 @@
 cayman 0x9400
 0x0000802C GRBM_GFX_INDEX
+0x000084FC CP_STRMOUT_CNTL
+0x000085F0 CP_COHER_CNTL
+0x000085F4 CP_COHER_SIZE
 0x000088B0 VGT_VTX_VECT_EJECT_REG
 0x000088C4 VGT_CACHE_INVALIDATION
 0x000088D4 VGT_GS_VERTEX_REUSE
@@ -77,7 +80,6 @@ cayman 0x9400
 0x0002802C DB_DEPTH_CLEAR
 0x00028030 PA_SC_SCREEN_SCISSOR_TL
 0x00028034 PA_SC_SCREEN_SCISSOR_BR
-0x0002805C DB_DEPTH_SLICE
 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
 0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
@@ -512,6 +514,13 @@ cayman 0x9400
 0x00028AC0 DB_SRESULTS_COMPARE_STATE0
 0x00028AC4 DB_SRESULTS_COMPARE_STATE1
 0x00028AC8 DB_PRELOAD_CONTROL
+0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
+0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
+0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
+0x00028B04 VGT_STRMOUT_VTX_STRIDE_3
+0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
+0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
+0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
 0x00028B38 VGT_GS_MAX_VERT_OUT
 0x00028B54 VGT_SHADER_STAGES_EN
 0x00028B58 VGT_LS_HS_CONFIG
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen
index 161737a..7f43394 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/evergreen
+++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen
@@ -4,6 +4,9 @@ evergreen 0x9400
 0x00008044 WAIT_UNTIL_POLL_CNTL
 0x00008048 WAIT_UNTIL_POLL_MASK
 0x0000804c WAIT_UNTIL_POLL_REFDATA
+0x000084FC CP_STRMOUT_CNTL
+0x000085F0 CP_COHER_CNTL
+0x000085F4 CP_COHER_SIZE
 0x000088B0 VGT_VTX_VECT_EJECT_REG
 0x000088C4 VGT_CACHE_INVALIDATION
 0x000088D4 VGT_GS_VERTEX_REUSE
@@ -93,7 +96,6 @@ evergreen 0x9400
 0x0002802C DB_DEPTH_CLEAR
 0x00028030 PA_SC_SCREEN_SCISSOR_TL
 0x00028034 PA_SC_SCREEN_SCISSOR_BR
-0x0002805C DB_DEPTH_SLICE
 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
 0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
@@ -522,6 +524,13 @@ evergreen 0x9400
 0x00028AC0 DB_SRESULTS_COMPARE_STATE0
 0x00028AC4 DB_SRESULTS_COMPARE_STATE1
 0x00028AC8 DB_PRELOAD_CONTROL
+0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
+0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
+0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
+0x00028B04 VGT_STRMOUT_VTX_STRIDE_3
+0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
+0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
+0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
 0x00028B38 VGT_GS_MAX_VERT_OUT
 0x00028B54 VGT_SHADER_STAGES_EN
 0x00028B58 VGT_LS_HS_CONFIG
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
index 0380c5c..79d2455 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r600
+++ b/drivers/gpu/drm/radeon/reg_srcs/r600
@@ -3,6 +3,9 @@ r600 0x9400
 0x00028230 R7xx_PA_SC_EDGERULE
 0x000286C8 R7xx_SPI_THREAD_GROUPING
 0x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
+0x00008490 CP_STRMOUT_CNTL
+0x000085F0 CP_COHER_CNTL
+0x000085F4 CP_COHER_SIZE
 0x000088C4 VGT_CACHE_INVALIDATION
 0x00028A50 VGT_ENHANCE
 0x000088CC VGT_ES_PER_GS
@@ -38,6 +41,13 @@ r600 0x9400
 0x00028AB4 VGT_REUSE_OFF
 0x00028AB8 VGT_VTX_CNT_EN
 0x000088B0 VGT_VTX_VECT_EJECT_REG
+0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
+0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
+0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
+0x00028B04 VGT_STRMOUT_VTX_STRIDE_3
+0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
+0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
+0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
 0x00028810 PA_CL_CLIP_CNTL
 0x00008A14 PA_CL_ENHANCE
 0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ
@@ -429,6 +439,7 @@ r600 0x9400
 0x00028438 SX_ALPHA_REF
 0x00028410 SX_ALPHA_TEST_CONTROL
 0x00028350 SX_MISC
+0x00028354 SX_SURFACE_SYNC
 0x00009014 SX_MEMORY_EXPORT_SIZE
 0x00009604 TC_INVALIDATE
 0x00009400 TD_FILTER4
@@ -743,14 +754,6 @@ r600 0x9400
 0x00028114 CB_COLOR5_MASK
 0x00028118 CB_COLOR6_MASK
 0x0002811C CB_COLOR7_MASK
-0x00028080 CB_COLOR0_VIEW
-0x00028084 CB_COLOR1_VIEW
-0x00028088 CB_COLOR2_VIEW
-0x0002808C CB_COLOR3_VIEW
-0x00028090 CB_COLOR4_VIEW
-0x00028094 CB_COLOR5_VIEW
-0x00028098 CB_COLOR6_VIEW
-0x0002809C CB_COLOR7_VIEW
 0x00028808 CB_COLOR_CONTROL
 0x0002842C CB_FOG_BLUE
 0x00028428 CB_FOG_GREEN
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 880637f..8787b18 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -150,7 +150,7 @@ void rv515_gpu_init(struct radeon_device *rdev)
 
 	if (r100_gui_wait_for_idle(rdev)) {
 		printk(KERN_WARNING "Failed to wait GUI idle while "
-		       "reseting GPU. Bad things might happen.\n");
+		       "resetting GPU. Bad things might happen.\n");
 	}
 	rv515_vga_render_disable(rdev);
 	r420_pipes_init(rdev);
@@ -162,7 +162,7 @@ void rv515_gpu_init(struct radeon_device *rdev)
 	WREG32_PLL(0x000D, tmp);
 	if (r100_gui_wait_for_idle(rdev)) {
 		printk(KERN_WARNING "Failed to wait GUI idle while "
-		       "reseting GPU. Bad things might happen.\n");
+		       "resetting GPU. Bad things might happen.\n");
 	}
 	if (rv515_mc_wait_for_idle(rdev)) {
 		printk(KERN_WARNING "Failed to wait MC idle while "
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 573220c..30d98d1 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -41,6 +41,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
 {
 	drm_sis_private_t *dev_priv;
 
+	pci_set_master(dev->pdev);
+
 	dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL);
 	if (dev_priv == NULL)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 2f75d20..c10cf5e 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -309,11 +309,11 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
 			goto out_err;
 
 		preempt_disable();
-		from_virtual = kmap_atomic(from_page, KM_USER0);
-		to_virtual = kmap_atomic(to_page, KM_USER1);
+		from_virtual = kmap_atomic(from_page);
+		to_virtual = kmap_atomic(to_page);
 		memcpy(to_virtual, from_virtual, PAGE_SIZE);
-		kunmap_atomic(to_virtual, KM_USER1);
-		kunmap_atomic(from_virtual, KM_USER0);
+		kunmap_atomic(to_virtual);
+		kunmap_atomic(from_virtual);
 		preempt_enable();
 		page_cache_release(from_page);
 	}
@@ -365,11 +365,11 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
 			goto out_err;
 		}
 		preempt_disable();
-		from_virtual = kmap_atomic(from_page, KM_USER0);
-		to_virtual = kmap_atomic(to_page, KM_USER1);
+		from_virtual = kmap_atomic(from_page);
+		to_virtual = kmap_atomic(to_page);
 		memcpy(to_virtual, from_virtual, PAGE_SIZE);
-		kunmap_atomic(to_virtual, KM_USER1);
-		kunmap_atomic(from_virtual, KM_USER0);
+		kunmap_atomic(to_virtual);
+		kunmap_atomic(from_virtual);
 		preempt_enable();
 		set_page_dirty(to_page);
 		mark_page_accessed(to_page);
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index a2ab343..1f18225 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -106,6 +106,8 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
 
 	idr_init(&dev->object_name_idr);
 
+	pci_set_master(dev->pdev);
+
 	ret = drm_vblank_init(dev, 1);
 	if (ret) {
 		kfree(dev_priv);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index f390f5f..ee24d21 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -38,6 +38,10 @@
 #define VMWGFX_CHIP_SVGAII 0
 #define VMW_FB_RESERVATION 0
 
+#define VMW_MIN_INITIAL_WIDTH 800
+#define VMW_MIN_INITIAL_HEIGHT 600
+
+
 /**
  * Fully encoded drm commands. Might move to vmw_drm.h
  */
@@ -387,6 +391,41 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv,
 	BUG_ON(n3d < 0);
 }
 
+/**
+ * Sets the initial_[width|height] fields on the given vmw_private.
+ *
+ * It does so by reading SVGA_REG_[WIDTH|HEIGHT] regs and then
+ * clamping the value to fb_max_[width|height] fields and the
+ * VMW_MIN_INITIAL_[WIDTH|HEIGHT].
+ * If the values appear to be invalid, set them to
+ * VMW_MIN_INITIAL_[WIDTH|HEIGHT].
+ */
+static void vmw_get_initial_size(struct vmw_private *dev_priv)
+{
+	uint32_t width;
+	uint32_t height;
+
+	width = vmw_read(dev_priv, SVGA_REG_WIDTH);
+	height = vmw_read(dev_priv, SVGA_REG_HEIGHT);
+
+	width = max_t(uint32_t, width, VMW_MIN_INITIAL_WIDTH);
+	height = max_t(uint32_t, height, VMW_MIN_INITIAL_HEIGHT);
+
+	if (width > dev_priv->fb_max_width ||
+	    height > dev_priv->fb_max_height) {
+
+		/*
+		 * This is a host error and shouldn't occur.
+		 */
+
+		width = VMW_MIN_INITIAL_WIDTH;
+		height = VMW_MIN_INITIAL_HEIGHT;
+	}
+
+	dev_priv->initial_width = width;
+	dev_priv->initial_height = height;
+}
+
 static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 {
 	struct vmw_private *dev_priv;
@@ -400,6 +439,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 	}
 	memset(dev_priv, 0, sizeof(*dev_priv));
 
+	pci_set_master(dev->pdev);
+
 	dev_priv->dev = dev;
 	dev_priv->vmw_chipset = chipset;
 	dev_priv->last_read_seqno = (uint32_t) -100;
@@ -430,7 +471,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 	svga_id = vmw_read(dev_priv, SVGA_REG_ID);
 	if (svga_id != SVGA_ID_2) {
 		ret = -ENOSYS;
-		DRM_ERROR("Unsuported SVGA ID 0x%x\n", svga_id);
+		DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id);
 		mutex_unlock(&dev_priv->hw_mutex);
 		goto out_err0;
 	}
@@ -441,6 +482,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
 	dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE);
 	dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH);
 	dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT);
+
+	vmw_get_initial_size(dev_priv);
+
 	if (dev_priv->capabilities & SVGA_CAP_GMR) {
 		dev_priv->max_gmr_descriptors =
 			vmw_read(dev_priv,
@@ -688,6 +732,15 @@ static int vmw_driver_unload(struct drm_device *dev)
 	return 0;
 }
 
+static void vmw_preclose(struct drm_device *dev,
+			 struct drm_file *file_priv)
+{
+	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+	struct vmw_private *dev_priv = vmw_priv(dev);
+
+	vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events);
+}
+
 static void vmw_postclose(struct drm_device *dev,
 			 struct drm_file *file_priv)
 {
@@ -710,6 +763,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
 	if (unlikely(vmw_fp == NULL))
 		return ret;
 
+	INIT_LIST_HEAD(&vmw_fp->fence_events);
 	vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
 	if (unlikely(vmw_fp->tfile == NULL))
 		goto out_no_tfile;
@@ -1102,6 +1156,7 @@ static struct drm_driver driver = {
 	.master_set = vmw_master_set,
 	.master_drop = vmw_master_drop,
 	.open = vmw_driver_open,
+	.preclose = vmw_preclose,
 	.postclose = vmw_postclose,
 	.fops = &vmwgfx_driver_fops,
 	.name = VMWGFX_DRIVER_NAME,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index dc27970..d0f2c07 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -40,9 +40,9 @@
 #include "ttm/ttm_module.h"
 #include "vmwgfx_fence.h"
 
-#define VMWGFX_DRIVER_DATE "20111025"
+#define VMWGFX_DRIVER_DATE "20120209"
 #define VMWGFX_DRIVER_MAJOR 2
-#define VMWGFX_DRIVER_MINOR 3
+#define VMWGFX_DRIVER_MINOR 4
 #define VMWGFX_DRIVER_PATCHLEVEL 0
 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000
 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
@@ -62,6 +62,7 @@
 struct vmw_fpriv {
 	struct drm_master *locked_master;
 	struct ttm_object_file *tfile;
+	struct list_head fence_events;
 };
 
 struct vmw_dma_buffer {
@@ -202,6 +203,8 @@ struct vmw_private {
 	uint32_t mmio_size;
 	uint32_t fb_max_width;
 	uint32_t fb_max_height;
+	uint32_t initial_width;
+	uint32_t initial_height;
 	__le32 __iomem *mmio_virt;
 	int mmio_mtrr;
 	uint32_t capabilities;
@@ -533,7 +536,8 @@ extern int vmw_execbuf_process(struct drm_file *file_priv,
 			       uint32_t command_size,
 			       uint64_t throttle_us,
 			       struct drm_vmw_fence_rep __user
-			       *user_fence_rep);
+			       *user_fence_rep,
+			       struct vmw_fence_obj **out_fence);
 
 extern void
 vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 40932fb..4acced4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -1109,10 +1109,11 @@ int vmw_execbuf_process(struct drm_file *file_priv,
 			void *kernel_commands,
 			uint32_t command_size,
 			uint64_t throttle_us,
-			struct drm_vmw_fence_rep __user *user_fence_rep)
+			struct drm_vmw_fence_rep __user *user_fence_rep,
+			struct vmw_fence_obj **out_fence)
 {
 	struct vmw_sw_context *sw_context = &dev_priv->ctx;
-	struct vmw_fence_obj *fence;
+	struct vmw_fence_obj *fence = NULL;
 	uint32_t handle;
 	void *cmd;
 	int ret;
@@ -1208,8 +1209,13 @@ int vmw_execbuf_process(struct drm_file *file_priv,
 	vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
 				    user_fence_rep, fence, handle);
 
-	if (likely(fence != NULL))
+	/* Don't unreference when handing fence out */
+	if (unlikely(out_fence != NULL)) {
+		*out_fence = fence;
+		fence = NULL;
+	} else if (likely(fence != NULL)) {
 		vmw_fence_obj_unreference(&fence);
+	}
 
 	mutex_unlock(&dev_priv->cmdbuf_mutex);
 	return 0;
@@ -1362,7 +1368,8 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
 	ret = vmw_execbuf_process(file_priv, dev_priv,
 				  (void __user *)(unsigned long)arg->commands,
 				  NULL, arg->command_size, arg->throttle_us,
-				  (void __user *)(unsigned long)arg->fence_rep);
+				  (void __user *)(unsigned long)arg->fence_rep,
+				  NULL);
 
 	if (unlikely(ret != 0))
 		goto out_unlock;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 34e51a1..3c447bf 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -414,10 +414,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
 	unsigned fb_bpp, fb_depth, fb_offset, fb_pitch, fb_size;
 	int ret;
 
-	/* XXX These shouldn't be hardcoded. */
-	initial_width = 800;
-	initial_height = 600;
-
 	fb_bpp = 32;
 	fb_depth = 24;
 
@@ -425,8 +421,8 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
 	fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
 	fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
 
-	initial_width = min(fb_width, initial_width);
-	initial_height = min(fb_height, initial_height);
+	initial_width = min(vmw_priv->initial_width, fb_width);
+	initial_height = min(vmw_priv->initial_height, fb_height);
 
 	fb_pitch = fb_width * fb_bpp / 8;
 	fb_size = fb_pitch * fb_height;
@@ -515,19 +511,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
 	info->var.xres = initial_width;
 	info->var.yres = initial_height;
 
-#if 0
-	info->pixmap.size = 64*1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
-#else
-	info->pixmap.size = 0;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
-#endif
+	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
 	info->apertures = alloc_apertures(1);
 	if (!info->apertures) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 15fb260..f2fb8f1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -69,12 +69,13 @@ struct vmw_user_fence {
  * be assigned the current time tv_usec val when the fence signals.
  */
 struct vmw_event_fence_action {
-	struct drm_pending_event e;
 	struct vmw_fence_action action;
+	struct list_head fpriv_head;
+
+	struct drm_pending_event *event;
 	struct vmw_fence_obj *fence;
 	struct drm_device *dev;
-	struct kref kref;
-	uint32_t size;
+
 	uint32_t *tv_sec;
 	uint32_t *tv_usec;
 };
@@ -784,46 +785,40 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
 }
 
 /**
- * vmw_event_fence_action_destroy
- *
- * @kref: The struct kref embedded in a struct vmw_event_fence_action.
- *
- * The vmw_event_fence_action destructor that may be called either after
- * the fence action cleanup, or when the event is delivered.
- * It frees both the vmw_event_fence_action struct and the actual
- * event structure copied to user-space.
- */
-static void vmw_event_fence_action_destroy(struct kref *kref)
-{
-	struct vmw_event_fence_action *eaction =
-		container_of(kref, struct vmw_event_fence_action, kref);
-	struct ttm_mem_global *mem_glob =
-		vmw_mem_glob(vmw_priv(eaction->dev));
-	uint32_t size = eaction->size;
-
-	kfree(eaction->e.event);
-	kfree(eaction);
-	ttm_mem_global_free(mem_glob, size);
-}
-
-
-/**
- * vmw_event_fence_action_delivered
+ * vmw_event_fence_fpriv_gone - Remove references to struct drm_file objects
  *
- * @e: The struct drm_pending_event embedded in a struct
- * vmw_event_fence_action.
+ * @fman: Pointer to a struct vmw_fence_manager
+ * @event_list: Pointer to linked list of struct vmw_event_fence_action objects
+ * with pointers to a struct drm_file object about to be closed.
  *
- * The struct drm_pending_event destructor that is called by drm
- * once the event is delivered. Since we don't know whether this function
- * will be called before or after the fence action destructor, we
- * free a refcount and destroy if it becomes zero.
+ * This function removes all pending fence events with references to a
+ * specific struct drm_file object about to be closed. The caller is required
+ * to pass a list of all struct vmw_event_fence_action objects with such
+ * events attached. This function is typically called before the
+ * struct drm_file object's event management is taken down.
  */
-static void vmw_event_fence_action_delivered(struct drm_pending_event *e)
+void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
+				struct list_head *event_list)
 {
-	struct vmw_event_fence_action *eaction =
-		container_of(e, struct vmw_event_fence_action, e);
+	struct vmw_event_fence_action *eaction;
+	struct drm_pending_event *event;
+	unsigned long irq_flags;
 
-	kref_put(&eaction->kref, vmw_event_fence_action_destroy);
+	while (1) {
+		spin_lock_irqsave(&fman->lock, irq_flags);
+		if (list_empty(event_list))
+			goto out_unlock;
+		eaction = list_first_entry(event_list,
+					   struct vmw_event_fence_action,
+					   fpriv_head);
+		list_del_init(&eaction->fpriv_head);
+		event = eaction->event;
+		eaction->event = NULL;
+		spin_unlock_irqrestore(&fman->lock, irq_flags);
+		event->destroy(event);
+	}
+out_unlock:
+	spin_unlock_irqrestore(&fman->lock, irq_flags);
 }
 
 
@@ -836,18 +831,21 @@ static void vmw_event_fence_action_delivered(struct drm_pending_event *e)
  * This function is called when the seqno of the fence where @action is
  * attached has passed. It queues the event on the submitter's event list.
  * This function is always called from atomic context, and may be called
- * from irq context. It ups a refcount reflecting that we now have two
- * destructors.
+ * from irq context.
  */
 static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
 {
 	struct vmw_event_fence_action *eaction =
 		container_of(action, struct vmw_event_fence_action, action);
 	struct drm_device *dev = eaction->dev;
-	struct drm_file *file_priv = eaction->e.file_priv;
+	struct drm_pending_event *event = eaction->event;
+	struct drm_file *file_priv;
 	unsigned long irq_flags;
 
-	kref_get(&eaction->kref);
+	if (unlikely(event == NULL))
+		return;
+
+	file_priv = event->file_priv;
 	spin_lock_irqsave(&dev->event_lock, irq_flags);
 
 	if (likely(eaction->tv_sec != NULL)) {
@@ -858,7 +856,9 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
 		*eaction->tv_usec = tv.tv_usec;
 	}
 
-	list_add_tail(&eaction->e.link, &file_priv->event_list);
+	list_del_init(&eaction->fpriv_head);
+	list_add_tail(&eaction->event->link, &file_priv->event_list);
+	eaction->event = NULL;
 	wake_up_all(&file_priv->event_wait);
 	spin_unlock_irqrestore(&dev->event_lock, irq_flags);
 }
@@ -876,9 +876,15 @@ static void vmw_event_fence_action_cleanup(struct vmw_fence_action *action)
 {
 	struct vmw_event_fence_action *eaction =
 		container_of(action, struct vmw_event_fence_action, action);
+	struct vmw_fence_manager *fman = eaction->fence->fman;
+	unsigned long irq_flags;
+
+	spin_lock_irqsave(&fman->lock, irq_flags);
+	list_del(&eaction->fpriv_head);
+	spin_unlock_irqrestore(&fman->lock, irq_flags);
 
 	vmw_fence_obj_unreference(&eaction->fence);
-	kref_put(&eaction->kref, vmw_event_fence_action_destroy);
+	kfree(eaction);
 }
 
 
@@ -946,39 +952,23 @@ void vmw_fence_obj_add_action(struct vmw_fence_obj *fence,
  * an error code, the caller needs to free that object.
  */
 
-int vmw_event_fence_action_create(struct drm_file *file_priv,
-				  struct vmw_fence_obj *fence,
-				  struct drm_event *event,
-				  uint32_t *tv_sec,
-				  uint32_t *tv_usec,
-				  bool interruptible)
+int vmw_event_fence_action_queue(struct drm_file *file_priv,
+				 struct vmw_fence_obj *fence,
+				 struct drm_pending_event *event,
+				 uint32_t *tv_sec,
+				 uint32_t *tv_usec,
+				 bool interruptible)
 {
 	struct vmw_event_fence_action *eaction;
-	struct ttm_mem_global *mem_glob =
-		vmw_mem_glob(fence->fman->dev_priv);
 	struct vmw_fence_manager *fman = fence->fman;
-	uint32_t size = fman->event_fence_action_size +
-		ttm_round_pot(event->length);
-	int ret;
-
-	/*
-	 * Account for internal structure size as well as the
-	 * event size itself.
-	 */
-
-	ret = ttm_mem_global_alloc(mem_glob, size, false, interruptible);
-	if (unlikely(ret != 0))
-		return ret;
+	struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
+	unsigned long irq_flags;
 
 	eaction = kzalloc(sizeof(*eaction), GFP_KERNEL);
-	if (unlikely(eaction == NULL)) {
-		ttm_mem_global_free(mem_glob, size);
+	if (unlikely(eaction == NULL))
 		return -ENOMEM;
-	}
 
-	eaction->e.event = event;
-	eaction->e.file_priv = file_priv;
-	eaction->e.destroy = vmw_event_fence_action_delivered;
+	eaction->event = event;
 
 	eaction->action.seq_passed = vmw_event_fence_action_seq_passed;
 	eaction->action.cleanup = vmw_event_fence_action_cleanup;
@@ -986,16 +976,89 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
 
 	eaction->fence = vmw_fence_obj_reference(fence);
 	eaction->dev = fman->dev_priv->dev;
-	eaction->size = size;
 	eaction->tv_sec = tv_sec;
 	eaction->tv_usec = tv_usec;
 
-	kref_init(&eaction->kref);
+	spin_lock_irqsave(&fman->lock, irq_flags);
+	list_add_tail(&eaction->fpriv_head, &vmw_fp->fence_events);
+	spin_unlock_irqrestore(&fman->lock, irq_flags);
+
 	vmw_fence_obj_add_action(fence, &eaction->action);
 
 	return 0;
 }
 
+struct vmw_event_fence_pending {
+	struct drm_pending_event base;
+	struct drm_vmw_event_fence event;
+};
+
+int vmw_event_fence_action_create(struct drm_file *file_priv,
+				  struct vmw_fence_obj *fence,
+				  uint32_t flags,
+				  uint64_t user_data,
+				  bool interruptible)
+{
+	struct vmw_event_fence_pending *event;
+	struct drm_device *dev = fence->fman->dev_priv->dev;
+	unsigned long irq_flags;
+	int ret;
+
+	spin_lock_irqsave(&dev->event_lock, irq_flags);
+
+	ret = (file_priv->event_space < sizeof(event->event)) ? -EBUSY : 0;
+	if (likely(ret == 0))
+		file_priv->event_space -= sizeof(event->event);
+
+	spin_unlock_irqrestore(&dev->event_lock, irq_flags);
+
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("Failed to allocate event space for this file.\n");
+		goto out_no_space;
+	}
+
+
+	event = kzalloc(sizeof(event->event), GFP_KERNEL);
+	if (unlikely(event == NULL)) {
+		DRM_ERROR("Failed to allocate an event.\n");
+		ret = -ENOMEM;
+		goto out_no_event;
+	}
+
+	event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
+	event->event.base.length = sizeof(*event);
+	event->event.user_data = user_data;
+
+	event->base.event = &event->event.base;
+	event->base.file_priv = file_priv;
+	event->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
+
+
+	if (flags & DRM_VMW_FE_FLAG_REQ_TIME)
+		ret = vmw_event_fence_action_queue(file_priv, fence,
+						   &event->base,
+						   &event->event.tv_sec,
+						   &event->event.tv_usec,
+						   interruptible);
+	else
+		ret = vmw_event_fence_action_queue(file_priv, fence,
+						   &event->base,
+						   NULL,
+						   NULL,
+						   interruptible);
+	if (ret != 0)
+		goto out_no_queue;
+
+out_no_queue:
+	event->base.destroy(&event->base);
+out_no_event:
+	spin_lock_irqsave(&dev->event_lock, irq_flags);
+	file_priv->event_space += sizeof(*event);
+	spin_unlock_irqrestore(&dev->event_lock, irq_flags);
+out_no_space:
+	return ret;
+}
+
 int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
 			  struct drm_file *file_priv)
 {
@@ -1008,8 +1071,6 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
 		(struct drm_vmw_fence_rep __user *)(unsigned long)
 		arg->fence_rep;
 	uint32_t handle;
-	unsigned long irq_flags;
-	struct drm_vmw_event_fence *event;
 	int ret;
 
 	/*
@@ -1062,59 +1123,28 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
 
 	BUG_ON(fence == NULL);
 
-	spin_lock_irqsave(&dev->event_lock, irq_flags);
-
-	ret = (file_priv->event_space < sizeof(*event)) ? -EBUSY : 0;
-	if (likely(ret == 0))
-		file_priv->event_space -= sizeof(*event);
-
-	spin_unlock_irqrestore(&dev->event_lock, irq_flags);
-
-	if (unlikely(ret != 0)) {
-		DRM_ERROR("Failed to allocate event space for this file.\n");
-		goto out_no_event_space;
-	}
-
-	event = kzalloc(sizeof(*event), GFP_KERNEL);
-	if (unlikely(event == NULL)) {
-		DRM_ERROR("Failed to allocate an event.\n");
-		goto out_no_event;
-	}
-
-	event->base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
-	event->base.length = sizeof(*event);
-	event->user_data = arg->user_data;
-
 	if (arg->flags & DRM_VMW_FE_FLAG_REQ_TIME)
 		ret = vmw_event_fence_action_create(file_priv, fence,
-						    &event->base,
-						    &event->tv_sec,
-						    &event->tv_usec,
+						    arg->flags,
+						    arg->user_data,
 						    true);
 	else
 		ret = vmw_event_fence_action_create(file_priv, fence,
-						    &event->base,
-						    NULL,
-						    NULL,
+						    arg->flags,
+						    arg->user_data,
 						    true);
 
 	if (unlikely(ret != 0)) {
 		if (ret != -ERESTARTSYS)
 			DRM_ERROR("Failed to attach event to fence.\n");
-		goto out_no_attach;
+		goto out_no_create;
 	}
 
 	vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
 				    handle);
 	vmw_fence_obj_unreference(&fence);
 	return 0;
-out_no_attach:
-	kfree(event);
-out_no_event:
-	spin_lock_irqsave(&dev->event_lock, irq_flags);
-	file_priv->event_space += sizeof(*event);
-	spin_unlock_irqrestore(&dev->event_lock, irq_flags);
-out_no_event_space:
+out_no_create:
 	if (user_fence_rep != NULL)
 		ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
 					  handle, TTM_REF_USAGE);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
index 0854a20..faf2e78 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h
@@ -109,5 +109,12 @@ extern int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
 				     struct drm_file *file_priv);
 extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
 				 struct drm_file *file_priv);
-
+extern void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
+				       struct list_head *event_list);
+extern int vmw_event_fence_action_queue(struct drm_file *filee_priv,
+					struct vmw_fence_obj *fence,
+					struct drm_pending_event *event,
+					uint32_t *tv_sec,
+					uint32_t *tv_usec,
+					bool interruptible);
 #endif /* _VMWGFX_FENCE_H_ */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
index f4e7763..51c9ba5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
@@ -136,10 +136,10 @@ static int vmw_gmr_build_descriptors(struct list_head *desc_pages,
 
 		if (likely(page_virtual != NULL)) {
 			desc_virtual->ppn = page_to_pfn(page);
-			kunmap_atomic(page_virtual, KM_USER0);
+			kunmap_atomic(page_virtual);
 		}
 
-		page_virtual = kmap_atomic(page, KM_USER0);
+		page_virtual = kmap_atomic(page);
 		desc_virtual = page_virtual - 1;
 		prev_pfn = ~(0UL);
 
@@ -169,7 +169,7 @@ static int vmw_gmr_build_descriptors(struct list_head *desc_pages,
 	}
 
 	if (likely(page_virtual != NULL))
-		kunmap_atomic(page_virtual, KM_USER0);
+		kunmap_atomic(page_virtual);
 
 	return 0;
 out_err:
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index b66ef0e..2286d47 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -422,7 +422,8 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
 				struct vmw_framebuffer *framebuffer,
 				unsigned flags, unsigned color,
 				struct drm_clip_rect *clips,
-				unsigned num_clips, int inc)
+				unsigned num_clips, int inc,
+				struct vmw_fence_obj **out_fence)
 {
 	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
 	struct drm_clip_rect *clips_ptr;
@@ -542,12 +543,15 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
 		if (num == 0)
 			continue;
 
+		/* only return the last fence */
+		if (out_fence && *out_fence)
+			vmw_fence_obj_unreference(out_fence);
 
 		/* recalculate package length */
 		fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
 		cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
 		ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-					  fifo_size, 0, NULL);
+					  fifo_size, 0, NULL, out_fence);
 
 		if (unlikely(ret != 0))
 			break;
@@ -598,7 +602,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
 
 	ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base,
 				   flags, color,
-				   clips, num_clips, inc);
+				   clips, num_clips, inc, NULL);
 
 	ttm_read_unlock(&vmaster->lock);
 	return 0;
@@ -809,7 +813,7 @@ static int do_dmabuf_define_gmrfb(struct drm_file *file_priv,
 	cmd->body.ptr.offset = 0;
 
 	ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-				  fifo_size, 0, NULL);
+				  fifo_size, 0, NULL, NULL);
 
 	kfree(cmd);
 
@@ -821,7 +825,8 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
 			       struct vmw_framebuffer *framebuffer,
 			       unsigned flags, unsigned color,
 			       struct drm_clip_rect *clips,
-			       unsigned num_clips, int increment)
+			       unsigned num_clips, int increment,
+			       struct vmw_fence_obj **out_fence)
 {
 	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
 	struct drm_clip_rect *clips_ptr;
@@ -894,9 +899,13 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
 		if (hit_num == 0)
 			continue;
 
+		/* only return the last fence */
+		if (out_fence && *out_fence)
+			vmw_fence_obj_unreference(out_fence);
+
 		fifo_size = sizeof(*blits) * hit_num;
 		ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits,
-					  fifo_size, 0, NULL);
+					  fifo_size, 0, NULL, out_fence);
 
 		if (unlikely(ret != 0))
 			break;
@@ -942,7 +951,7 @@ int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
 	} else {
 		ret = do_dmabuf_dirty_sou(file_priv, dev_priv, &vfbd->base,
 					  flags, color,
-					  clips, num_clips, increment);
+					  clips, num_clips, increment, NULL);
 	}
 
 	ttm_read_unlock(&vmaster->lock);
@@ -1296,7 +1305,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
 		fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
 		cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
 		ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-					  fifo_size, 0, NULL);
+					  fifo_size, 0, NULL, NULL);
 
 		if (unlikely(ret != 0))
 			break;
@@ -1409,7 +1418,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
 	fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos;
 
 	ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
-				  0, user_fence_rep);
+				  0, user_fence_rep, NULL);
 
 	kfree(cmd);
 
@@ -1672,6 +1681,70 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
 	return 0;
 }
 
+int vmw_du_page_flip(struct drm_crtc *crtc,
+		     struct drm_framebuffer *fb,
+		     struct drm_pending_vblank_event *event)
+{
+	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
+	struct drm_framebuffer *old_fb = crtc->fb;
+	struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
+	struct drm_file *file_priv = event->base.file_priv;
+	struct vmw_fence_obj *fence = NULL;
+	struct drm_clip_rect clips;
+	int ret;
+
+	/* require ScreenObject support for page flipping */
+	if (!dev_priv->sou_priv)
+		return -ENOSYS;
+
+	if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
+		return -EINVAL;
+
+	crtc->fb = fb;
+
+	/* do a full screen dirty update */
+	clips.x1 = clips.y1 = 0;
+	clips.x2 = fb->width;
+	clips.y2 = fb->height;
+
+	if (vfb->dmabuf)
+		ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb,
+					  0, 0, &clips, 1, 1, &fence);
+	else
+		ret = do_surface_dirty_sou(dev_priv, file_priv, vfb,
+					   0, 0, &clips, 1, 1, &fence);
+
+
+	if (ret != 0)
+		goto out_no_fence;
+	if (!fence) {
+		ret = -EINVAL;
+		goto out_no_fence;
+	}
+
+	ret = vmw_event_fence_action_queue(file_priv, fence,
+					   &event->base,
+					   &event->event.tv_sec,
+					   &event->event.tv_usec,
+					   true);
+
+	/*
+	 * No need to hold on to this now. The only cleanup
+	 * we need to do if we fail is unref the fence.
+	 */
+	vmw_fence_obj_unreference(&fence);
+
+	if (vmw_crtc_to_du(crtc)->is_implicit)
+		vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc);
+
+	return ret;
+
+out_no_fence:
+	crtc->fb = old_fb;
+	return ret;
+}
+
+
 void vmw_du_crtc_save(struct drm_crtc *crtc)
 {
 }
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index a4f7f03..8184bc5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -121,6 +121,9 @@ struct vmw_display_unit {
  * Shared display unit functions - vmwgfx_kms.c
  */
 void vmw_display_unit_cleanup(struct vmw_display_unit *du);
+int vmw_du_page_flip(struct drm_crtc *crtc,
+		     struct drm_framebuffer *fb,
+		     struct drm_pending_vblank_event *event);
 void vmw_du_crtc_save(struct drm_crtc *crtc);
 void vmw_du_crtc_restore(struct drm_crtc *crtc);
 void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
@@ -154,5 +157,10 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv);
 int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv);
 int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num,
 			      struct drm_vmw_rect *rects);
+bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
+				     struct drm_crtc *crtc);
+void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
+					      struct drm_crtc *crtc);
+
 
 #endif
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index f77b184..070fb23 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -354,8 +354,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
 	INIT_LIST_HEAD(&ldu->active);
 
 	ldu->base.pref_active = (unit == 0);
-	ldu->base.pref_width = 800;
-	ldu->base.pref_height = 600;
+	ldu->base.pref_width = dev_priv->initial_width;
+	ldu->base.pref_height = dev_priv->initial_height;
 	ldu->base.pref_mode = NULL;
 	ldu->base.is_implicit = true;
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 4defdcf..6deaf2f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -394,6 +394,7 @@ static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
 	.gamma_set = vmw_du_crtc_gamma_set,
 	.destroy = vmw_sou_crtc_destroy,
 	.set_config = vmw_sou_crtc_set_config,
+	.page_flip = vmw_du_page_flip,
 };
 
 /*
@@ -448,8 +449,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
 	sou->active_implicit = false;
 
 	sou->base.pref_active = (unit == 0);
-	sou->base.pref_width = 800;
-	sou->base.pref_height = 600;
+	sou->base.pref_width = dev_priv->initial_width;
+	sou->base.pref_height = dev_priv->initial_height;
 	sou->base.pref_mode = NULL;
 	sou->base.is_implicit = true;
 
@@ -535,3 +536,36 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
 
 	return 0;
 }
+
+/**
+ * Returns if this unit can be page flipped.
+ * Must be called with the mode_config mutex held.
+ */
+bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
+				     struct drm_crtc *crtc)
+{
+	struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
+
+	if (!sou->base.is_implicit)
+		return true;
+
+	if (dev_priv->sou_priv->num_implicit != 1)
+		return false;
+
+	return true;
+}
+
+/**
+ * Update the implicit fb to the current fb of this crtc.
+ * Must be called with the mode_config mutex held.
+ */
+void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
+					      struct drm_crtc *crtc)
+{
+	struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
+
+	BUG_ON(!sou->base.is_implicit);
+
+	dev_priv->sou_priv->implicit_fb =
+		vmw_framebuffer_to_vfb(sou->base.crtc.fb);
+}
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index a421abd..069577a 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -257,7 +257,9 @@ config HID_LOGITECH_DJ
 	---help---
 	Say Y if you want support for Logitech Unifying receivers and devices.
 	Unifying receivers are capable of pairing up to 6 Logitech compliant
-	devices to the same receiver.
+	devices to the same receiver. Without this driver it will be handled by
+	generic USB_HID driver and all incomming events will be multiplexed
+	into a single mouse and a single keyboard device.
 
 config LOGITECH_FF
 	bool "Logitech force feedback support"
@@ -354,7 +356,9 @@ config HID_MULTITOUCH
 	  - LG Display panels (Dell ST2220Tc)
 	  - Lumio CrystalTouch panels
 	  - MosArt dual-touch panels
+	  - Panasonic multitouch panels
 	  - PenMount dual touch panels
+	  - Perixx Peripad 701 touchpad
 	  - PixArt optical touch screen
 	  - Pixcir dual touch panels
 	  - Quanta panels
@@ -476,59 +480,12 @@ config HID_PRIMAX
 	HID standard.
 
 config HID_ROCCAT
-	tristate "Roccat special event support"
+	tristate "Roccat device support"
 	depends on USB_HID
-	select HID_ROCCAT_COMMON
 	---help---
-	Support for Roccat special events.
-	Say Y here if you have a Roccat mouse or keyboard and want OSD or
-	macro execution support.
-
-config HID_ROCCAT_COMMON
-	tristate
-	depends on HID_ROCCAT
-
-config HID_ROCCAT_ARVO
-	tristate "Roccat Arvo keyboard support"
-	depends on USB_HID
-	depends on HID_ROCCAT
-	---help---
-	Support for Roccat Arvo keyboard.
-
-config HID_ROCCAT_ISKU
-	tristate "Roccat Isku keyboard support"
-	depends on USB_HID
-	depends on HID_ROCCAT
-	---help---
-	Support for Roccat Isku keyboard.
-
-config HID_ROCCAT_KONE
-	tristate "Roccat Kone Mouse support"
-	depends on USB_HID
-	depends on HID_ROCCAT
-	---help---
-	Support for Roccat Kone mouse.
-
-config HID_ROCCAT_KONEPLUS
-	tristate "Roccat Kone[+] mouse support"
-	depends on USB_HID
-	depends on HID_ROCCAT
-	---help---
-	Support for Roccat Kone[+] mouse.
-
-config HID_ROCCAT_KOVAPLUS
-	tristate "Roccat Kova[+] mouse support"
-	depends on USB_HID
-	depends on HID_ROCCAT
-	---help---
-	Support for Roccat Kova[+] mouse.
-
-config HID_ROCCAT_PYRA
-	tristate "Roccat Pyra mouse support"
-	depends on USB_HID
-	depends on HID_ROCCAT
-	---help---
-	Support for Roccat Pyra mouse.
+	Support for Roccat devices.
+	Say Y here if you have a Roccat mouse or keyboard and want
+	support for its special functionalities.
 
 config HID_SAMSUNG
 	tristate "Samsung InfraRed remote control or keyboards"
@@ -594,6 +551,12 @@ config SMARTJOYPLUS_FF
 	Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to
 	enable force feedback support for it.
 
+config HID_TIVO
+	tristate "TiVo Slide Bluetooth remote control support"
+	depends on USB_HID
+	---help---
+	Say Y if you have a TiVo Slide Bluetooth remote control.
+
 config HID_TOPSEED
 	tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
 	depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 8aefdc9..164ef6e 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -64,14 +64,9 @@ obj-$(CONFIG_HID_PANTHERLORD)	+= hid-pl.o
 obj-$(CONFIG_HID_PETALYNX)	+= hid-petalynx.o
 obj-$(CONFIG_HID_PICOLCD)	+= hid-picolcd.o
 obj-$(CONFIG_HID_PRIMAX)	+= hid-primax.o
-obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o
-obj-$(CONFIG_HID_ROCCAT_COMMON)	+= hid-roccat-common.o
-obj-$(CONFIG_HID_ROCCAT_ARVO)	+= hid-roccat-arvo.o
-obj-$(CONFIG_HID_ROCCAT_ISKU)	+= hid-roccat-isku.o
-obj-$(CONFIG_HID_ROCCAT_KONE)	+= hid-roccat-kone.o
-obj-$(CONFIG_HID_ROCCAT_KONEPLUS)	+= hid-roccat-koneplus.o
-obj-$(CONFIG_HID_ROCCAT_KOVAPLUS)	+= hid-roccat-kovaplus.o
-obj-$(CONFIG_HID_ROCCAT_PYRA)	+= hid-roccat-pyra.o
+obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o hid-roccat-common.o \
+	hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
+	hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
 obj-$(CONFIG_HID_SMARTJOYPLUS)	+= hid-sjoy.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
@@ -79,6 +74,7 @@ obj-$(CONFIG_HID_SPEEDLINK)	+= hid-speedlink.o
 obj-$(CONFIG_HID_SUNPLUS)	+= hid-sunplus.o
 obj-$(CONFIG_HID_GREENASIA)	+= hid-gaff.o
 obj-$(CONFIG_HID_THRUSTMASTER)	+= hid-tmff.o
+obj-$(CONFIG_HID_TIVO)		+= hid-tivo.o
 obj-$(CONFIG_HID_TOPSEED)	+= hid-topseed.o
 obj-$(CONFIG_HID_TWINHAN)	+= hid-twinhan.o
 obj-$(CONFIG_HID_UCLOGIC)	+= hid-uclogic.o
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index 8965ad9..b99af34 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -45,6 +45,12 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	case 0xff09: ch_map_key_clear(BTN_9);	break;
 	case 0xff0a: ch_map_key_clear(BTN_A);	break;
 	case 0xff0b: ch_map_key_clear(BTN_B);	break;
+	case 0x00f1: ch_map_key_clear(KEY_WLAN);	break;
+	case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN);	break;
+	case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP);	break;
+	case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF);	break;
+	case 0x00f7: ch_map_key_clear(KEY_CAMERA);	break;
+	case 0x00f8: ch_map_key_clear(KEY_PROG1);	break;
 	default:
 		return 0;
 	}
@@ -53,6 +59,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 
 static const struct hid_device_id ch_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, ch_devices);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index af08ce7..ae91e21 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1396,6 +1396,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
@@ -1462,8 +1463,10 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
+#if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) },
+#endif
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
@@ -1501,6 +1504,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT780) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
@@ -1535,6 +1540,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
@@ -1548,6 +1554,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
@@ -1556,6 +1563,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_Q_PAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
@@ -1619,11 +1627,7 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf,
 	list_add_tail(&dynid->list, &hdrv->dyn_list);
 	spin_unlock(&hdrv->dyn_lock);
 
-	ret = 0;
-	if (get_driver(&hdrv->driver)) {
-		ret = driver_attach(&hdrv->driver);
-		put_driver(&hdrv->driver);
-	}
+	ret = driver_attach(&hdrv->driver);
 
 	return ret ? : count;
 }
@@ -1912,6 +1916,16 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
+#if defined(CONFIG_MOUSE_SYNAPTICS_USB) || defined(CONFIG_MOUSE_SYNAPTICS_USB_MODULE)
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_CPAD) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_STICK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WP) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_COMP_TP) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WTP) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) },
+#endif
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
@@ -1993,6 +2007,16 @@ static bool hid_ignore(struct hid_device *hdev)
 		if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST &&
 				hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
 			return true;
+		/*
+		 * The Keene FM transmitter USB device has the same USB ID as
+		 * the Logitech AudioHub Speaker, but it should ignore the hid.
+		 * Check if the name is that of the Keene device.
+		 * For reference: the name of the AudioHub is
+		 * "HOLTEK  AudioHub Speaker".
+		 */
+		if (hdev->product == USB_DEVICE_ID_LOGITECH_AUDIOHUB &&
+			!strcmp(hdev->name, "HOLTEK  B-LINK USB Audio  "))
+				return true;
 		break;
 	case USB_VENDOR_ID_SOUNDGRAPH:
 		if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index b8574cd..00e32f3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -41,7 +41,7 @@
 #define USB_VENDOR_ID_ACTIONSTAR	0x2101
 #define USB_DEVICE_ID_ACTIONSTAR_1011	0x1011
 
-#define USB_VENDOR_ID_ADS_TECH 		0x06e1
+#define USB_VENDOR_ID_ADS_TECH		0x06e1
 #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X	0xa155
 
 #define USB_VENDOR_ID_AFATECH		0x15a4
@@ -173,6 +173,7 @@
 #define USB_VENDOR_ID_CH		0x068e
 #define USB_DEVICE_ID_CH_PRO_THROTTLE	0x00f1
 #define USB_DEVICE_ID_CH_PRO_PEDALS	0x00f2
+#define USB_DEVICE_ID_CH_FIGHTERSTICK	0x00f3
 #define USB_DEVICE_ID_CH_COMBATSTICK	0x00f4
 #define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE       0x0051
 #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE	0x00ff
@@ -190,6 +191,7 @@
 #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD	0x0418
 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH	0xb19d
 #define USB_DEVICE_ID_CHICONY_WIRELESS	0x0618
+#define USB_DEVICE_ID_CHICONY_WIRELESS2	0x1123
 
 #define USB_VENDOR_ID_CHUNGHWAT		0x2247
 #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH	0x0001
@@ -451,6 +453,7 @@
 #define USB_DEVICE_ID_LG_MULTITOUCH	0x0064
 
 #define USB_VENDOR_ID_LOGITECH		0x046d
+#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
 #define USB_DEVICE_ID_LOGITECH_RECEIVER	0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
@@ -565,6 +568,10 @@
 #define USB_DEVICE_ID_ORTEK_PKB1700	0x1700
 #define USB_DEVICE_ID_ORTEK_WKB2000	0x2000
 
+#define USB_VENDOR_ID_PANASONIC		0x04da
+#define USB_DEVICE_ID_PANABOARD_UBT780	0x1044
+#define USB_DEVICE_ID_PANABOARD_UBT880	0x104d
+
 #define USB_VENDOR_ID_PANJIT		0x134c
 
 #define USB_VENDOR_ID_PANTHERLORD	0x0810
@@ -652,13 +659,28 @@
 #define USB_DEVICE_ID_SYMBOL_SCANNER_1	0x0800
 #define USB_DEVICE_ID_SYMBOL_SCANNER_2	0x1300
 
+#define USB_VENDOR_ID_SYNAPTICS		0x06cb
+#define USB_DEVICE_ID_SYNAPTICS_TP	0x0001
+#define USB_DEVICE_ID_SYNAPTICS_INT_TP	0x0002
+#define USB_DEVICE_ID_SYNAPTICS_CPAD	0x0003
+#define USB_DEVICE_ID_SYNAPTICS_TS	0x0006
+#define USB_DEVICE_ID_SYNAPTICS_STICK	0x0007
+#define USB_DEVICE_ID_SYNAPTICS_WP	0x0008
+#define USB_DEVICE_ID_SYNAPTICS_COMP_TP	0x0009
+#define USB_DEVICE_ID_SYNAPTICS_WTP	0x0010
+#define USB_DEVICE_ID_SYNAPTICS_DPAD	0x0013
+
 #define USB_VENDOR_ID_THRUSTMASTER	0x044f
 
+#define USB_VENDOR_ID_TIVO		0x150a
+#define USB_DEVICE_ID_TIVO_SLIDE	0x1201
+
 #define USB_VENDOR_ID_TOPSEED		0x0766
 #define USB_DEVICE_ID_TOPSEED_CYBERLINK	0x0204
 
 #define USB_VENDOR_ID_TOPSEED2		0x1784
 #define USB_DEVICE_ID_TOPSEED2_RF_COMBO	0x0004
+#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701	0x0016
 
 #define USB_VENDOR_ID_TOPMAX		0x0663
 #define USB_DEVICE_ID_TOPMAX_COBRAPAD	0x0103
@@ -703,6 +725,7 @@
 #define USB_VENDOR_ID_WALTOP				0x172f
 #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH	0x0032
 #define USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH	0x0034
+#define USB_DEVICE_ID_WALTOP_Q_PAD			0x0037
 #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH	0x0501
 #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH	0x0500
 
@@ -711,6 +734,7 @@
 #define USB_DEVICE_ID_1_PHIDGETSERVO_20	0x8101
 #define USB_DEVICE_ID_4_PHIDGETSERVO_20	0x8104
 #define USB_DEVICE_ID_8_8_4_IF_KIT	0x8201
+#define USB_DEVICE_ID_SUPER_JOY_BOX_3	0x8888
 #define USB_DEVICE_ID_QUAD_USB_JOYPAD	0x8800
 #define USB_DEVICE_ID_DUAL_USB_JOYPAD	0x8866
 
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 9333d69..af0200f 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -279,7 +279,8 @@ static enum power_supply_property hidinput_battery_props[] = {
 	POWER_SUPPLY_PROP_ONLINE,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_MODEL_NAME,
-	POWER_SUPPLY_PROP_STATUS
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_SCOPE,
 };
 
 #define HID_BATTERY_QUIRK_PERCENT	(1 << 0) /* always reports percent */
@@ -344,6 +345,10 @@ static int hidinput_get_battery_property(struct power_supply *psy,
 		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
 		break;
 
+	case POWER_SUPPLY_PROP_SCOPE:
+		val->intval = POWER_SUPPLY_SCOPE_DEVICE;
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
@@ -403,6 +408,8 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
 		battery->name = NULL;
 	}
 
+	power_supply_powers(battery, &dev->dev);
+
 out:
 	return true;
 }
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 38b12e4..2b56efc 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -445,7 +445,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
 	dj_report.report_id = REPORT_ID_DJ_SHORT;
 	dj_report.device_index = 0xFF;
 	dj_report.report_type = REPORT_TYPE_CMD_SWITCH;
-	dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x1F;
+	dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F;
 	dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout;
 	return logi_dj_recv_send_report(djrcv_dev, &dj_report);
 }
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 2ab7175..7cf3ffe 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -418,6 +418,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
 		__set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
 		__set_bit(BTN_TOOL_QUADTAP, input->keybit);
 		__set_bit(BTN_TOUCH, input->keybit);
+		__set_bit(INPUT_PROP_POINTER, input->propbit);
+		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 	}
 
 	if (report_touches) {
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 24fc442..09e42ef 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1,9 +1,9 @@
 /*
  *  HID driver for multitouch panels
  *
- *  Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr>
- *  Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
- *  Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
+ *  Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
+ *  Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
+ *  Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
  *
  *  This code is partly based on hid-egalax.c:
  *
@@ -67,6 +67,7 @@ struct mt_class {
 	__s32 sn_height;	/* Signal/noise ratio for height events */
 	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
 	__u8 maxcontacts;
+	bool is_indirect;	/* true for touchpads */
 };
 
 struct mt_device {
@@ -76,6 +77,8 @@ struct mt_device {
 	unsigned last_slot_field;	/* the last field of a slot */
 	int last_mt_collection;	/* last known mt-related collection */
 	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */
+	__s8 maxcontact_report_id;	/* Maximum Contact Number HID feature,
+				   -1 if non-existent */
 	__u8 num_received;	/* how many contacts we received */
 	__u8 num_expected;	/* expected last contact index */
 	__u8 maxcontacts;
@@ -100,6 +103,8 @@ struct mt_device {
 #define MT_CLS_CYPRESS				0x0102
 #define MT_CLS_EGALAX				0x0103
 #define MT_CLS_EGALAX_SERIAL			0x0104
+#define MT_CLS_TOPSEED				0x0105
+#define MT_CLS_PANASONIC			0x0106
 
 #define MT_DEFAULT_MAXCONTACT	10
 
@@ -189,6 +194,14 @@ static struct mt_class mt_classes[] = {
 		.sn_move = 4096,
 		.sn_pressure = 32,
 	},
+	{ .name = MT_CLS_TOPSEED,
+		.quirks = MT_QUIRK_ALWAYS_VALID,
+		.is_indirect = true,
+		.maxcontacts = 2,
+	},
+	{ .name = MT_CLS_PANASONIC,
+		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
+		.maxcontacts = 4 },
 
 	{ }
 };
@@ -241,6 +254,7 @@ static void mt_feature_mapping(struct hid_device *hdev,
 		td->inputmode = field->report->id;
 		break;
 	case HID_DG_CONTACTMAX:
+		td->maxcontact_report_id = field->report->id;
 		td->maxcontacts = field->value[0];
 		if (td->mtclass.maxcontacts)
 			/* check if the maxcontacts is given by the class */
@@ -265,17 +279,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
 	struct mt_class *cls = &td->mtclass;
+	int code;
 
 	/* Only map fields from TouchScreen or TouchPad collections.
-         * We need to ignore fields that belong to other collections
-         * such as Mouse that might have the same GenericDesktop usages. */
+	* We need to ignore fields that belong to other collections
+	* such as Mouse that might have the same GenericDesktop usages. */
 	if (field->application == HID_DG_TOUCHSCREEN)
 		set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
-	else if (field->application == HID_DG_TOUCHPAD)
-		set_bit(INPUT_PROP_POINTER, hi->input->propbit);
-	else
+	else if (field->application != HID_DG_TOUCHPAD)
 		return 0;
 
+	/* In case of an indirect device (touchpad), we need to add
+	 * specific BTN_TOOL_* to be handled by the synaptics xorg
+	 * driver.
+	 * We also consider that touchscreens providing buttons are touchpads.
+	 */
+	if (field->application == HID_DG_TOUCHPAD ||
+	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON ||
+	    cls->is_indirect) {
+		set_bit(INPUT_PROP_POINTER, hi->input->propbit);
+		set_bit(BTN_TOOL_FINGER, hi->input->keybit);
+		set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
+		set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
+		set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
+	}
+
 	/* eGalax devices provide a Digitizer.Stylus input which overrides
 	 * the correct Digitizers.Finger X/Y ranges.
 	 * Let's just ignore this input. */
@@ -389,9 +417,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 				td->last_field_index = field->index;
 			return -1;
 		}
+		case HID_DG_TOUCH:
+			/* Legacy devices use TIPSWITCH and not TOUCH.
+			 * Let's just ignore this field. */
+			return -1;
 		/* let hid-input decide for the others */
 		return 0;
 
+	case HID_UP_BUTTON:
+		code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
+		hid_map_usage(hi, usage, bit, max, EV_KEY, code);
+		input_set_capability(hi->input, EV_KEY, code);
+		return 1;
+
 	case 0xff000000:
 		/* we do not want to map these: no input-oriented meaning */
 		return -1;
@@ -538,15 +576,17 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
 			if (value)
 				td->num_expected = value;
 			break;
+		case HID_DG_TOUCH:
+			/* do nothing */
+			break;
 
 		default:
 			/* fallback to the generic hidinput handling */
 			return 0;
 		}
 
-		if (usage->hid == td->last_slot_field) {
+		if (usage->hid == td->last_slot_field)
 			mt_complete_slot(td);
-		}
 
 		if (field->index == td->last_field_index
 			&& td->num_received >= td->num_expected)
@@ -578,6 +618,32 @@ static void mt_set_input_mode(struct hid_device *hdev)
 	}
 }
 
+static void mt_set_maxcontacts(struct hid_device *hdev)
+{
+	struct mt_device *td = hid_get_drvdata(hdev);
+	struct hid_report *r;
+	struct hid_report_enum *re;
+	int fieldmax, max;
+
+	if (td->maxcontact_report_id < 0)
+		return;
+
+	if (!td->mtclass.maxcontacts)
+		return;
+
+	re = &hdev->report_enum[HID_FEATURE_REPORT];
+	r = re->report_id_hash[td->maxcontact_report_id];
+	if (r) {
+		max = td->mtclass.maxcontacts;
+		fieldmax = r->field[0]->logical_maximum;
+		max = min(fieldmax, max);
+		if (r->field[0]->value[0] != max) {
+			r->field[0]->value[0] = max;
+			usbhid_submit_report(hdev, r, USB_DIR_OUT);
+		}
+	}
+}
+
 static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
 	int ret, i;
@@ -603,6 +669,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	}
 	td->mtclass = *mtclass;
 	td->inputmode = -1;
+	td->maxcontact_report_id = -1;
 	td->last_mt_collection = -1;
 	hid_set_drvdata(hdev, td);
 
@@ -625,6 +692,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
 
+	mt_set_maxcontacts(hdev);
 	mt_set_input_mode(hdev);
 
 	return 0;
@@ -637,6 +705,7 @@ fail:
 #ifdef CONFIG_PM
 static int mt_reset_resume(struct hid_device *hdev)
 {
+	mt_set_maxcontacts(hdev);
 	mt_set_input_mode(hdev);
 	return 0;
 }
@@ -791,6 +860,14 @@ static const struct hid_device_id mt_devices[] = {
 		HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
 			USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
 
+	/* Panasonic panels */
+	{ .driver_data = MT_CLS_PANASONIC,
+		HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
+			USB_DEVICE_ID_PANABOARD_UBT780) },
+	{ .driver_data = MT_CLS_PANASONIC,
+		HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
+			USB_DEVICE_ID_PANABOARD_UBT880) },
+
 	/* PenMount panels */
 	{ .driver_data = MT_CLS_CONFIDENCE,
 		HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
@@ -837,6 +914,11 @@ static const struct hid_device_id mt_devices[] = {
 		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,
 			USB_DEVICE_ID_MTP_SITRONIX)},
 
+	/* TopSeed panels */
+	{ .driver_data = MT_CLS_TOPSEED,
+		HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2,
+			USB_DEVICE_ID_TOPSEED2_PERIPAD_701) },
+
 	/* Touch International panels */
 	{ .driver_data = MT_CLS_DEFAULT,
 		HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index 4b14486..42257ac 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -155,7 +155,8 @@ err:
 }
 
 static const struct hid_device_id sjoy_devices[] = {
-	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO),
+		.driver_data = HID_QUIRK_NOGET },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO),
 		.driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
 			       HID_QUIRK_SKIP_OUTPUT_REPORTS },
@@ -163,8 +164,9 @@ static const struct hid_device_id sjoy_devices[] = {
 		.driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
 			       HID_QUIRK_SKIP_OUTPUT_REPORTS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SUPER_JOY_BOX_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD),
-		.driver_data = HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET |
+		.driver_data = HID_QUIRK_MULTI_INPUT |
 			       HID_QUIRK_SKIP_OUTPUT_REPORTS },
 	{ }
 };
diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c
new file mode 100644
index 0000000..3d43c06
--- /dev/null
+++ b/drivers/hid/hid-tivo.c
@@ -0,0 +1,89 @@
+/*
+ *  HID driver for TiVo Slide Bluetooth remote
+ *
+ *  Copyright (c) 2011 Jarod Wilson <jarod@redhat.com>
+ *  based on the hid-topseed driver, which is in turn, based on hid-cherry...
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define HID_UP_TIVOVENDOR	0xffff0000
+#define tivo_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
+					EV_KEY, (c))
+
+static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	switch (usage->hid & HID_USAGE_PAGE) {
+	case HID_UP_TIVOVENDOR:
+		switch (usage->hid & HID_USAGE) {
+		/* TiVo button */
+		case 0x3d: tivo_map_key_clear(KEY_MEDIA);	break;
+		/* Live TV */
+		case 0x3e: tivo_map_key_clear(KEY_TV);		break;
+		/* Red thumbs down */
+		case 0x41: tivo_map_key_clear(KEY_KPMINUS);	break;
+		/* Green thumbs up */
+		case 0x42: tivo_map_key_clear(KEY_KPPLUS);	break;
+		default:
+			return 0;
+		}
+		break;
+	case HID_UP_CONSUMER:
+		switch (usage->hid & HID_USAGE) {
+		/* Enter/Last (default mapping: KEY_LAST) */
+		case 0x083: tivo_map_key_clear(KEY_ENTER);	break;
+		/* Info (default mapping: KEY_PROPS) */
+		case 0x209: tivo_map_key_clear(KEY_INFO);	break;
+		default:
+			return 0;
+		}
+		break;
+	default:
+		return 0;
+	}
+
+	/* This means we found a matching mapping here, else, look in the
+	 * standard hid mappings in hid-input.c */
+	return 1;
+}
+
+static const struct hid_device_id tivo_devices[] = {
+	/* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, tivo_devices);
+
+static struct hid_driver tivo_driver = {
+	.name = "tivo_slide",
+	.id_table = tivo_devices,
+	.input_mapping = tivo_input_mapping,
+};
+
+static int __init tivo_init(void)
+{
+	return hid_register_driver(&tivo_driver);
+}
+
+static void __exit tivo_exit(void)
+{
+	hid_unregister_driver(&tivo_driver);
+}
+
+module_init(tivo_init);
+module_exit(tivo_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index acab74c..0621047 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -518,6 +518,7 @@ static int wacom_probe(struct hid_device *hdev,
 		wacom_poke(hdev, 1);
 		break;
 	case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
+		sprintf(hdev->name, "%s", "Wacom Intuos4 WL");
 		wdata->features = 0;
 		wacom_set_features(hdev);
 		break;
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c
index b3a4163..0ec1696 100644
--- a/drivers/hid/hid-waltop.c
+++ b/drivers/hid/hid-waltop.c
@@ -424,6 +424,190 @@ static __u8 slim_tablet_12_1_inch_rdesc_fixed[] = {
 };
 
 /*
+ * Original Q Pad report descriptor.
+ *
+ * The descriptor is similar to the Slim Tablet 5.8 inch descriptor with the
+ * addition of consumer AC Pan field to the report ID 1, which seems to be
+ * unused in the default mode. However, this tablet has resolution of 2048 LPI.
+ *
+ *  Usage Page (Desktop),           ; Generic desktop controls (01h)
+ *  Usage (Mouse),                  ; Mouse (02h, application collection)
+ *  Collection (Application),
+ *    Report ID (1),
+ *    Usage (Pointer),              ; Pointer (01h, physical collection)
+ *    Collection (Physical),
+ *      Usage Page (Button),        ; Button (09h)
+ *      Usage Minimum (01h),
+ *      Usage Maximum (05h),
+ *      Logical Minimum (0),
+ *      Logical Maximum (1),
+ *      Report Size (1),
+ *      Report Count (5),
+ *      Input (Variable),
+ *      Report Size (3),
+ *      Report Count (1),
+ *      Input (Constant, Variable),
+ *      Usage Page (Desktop),       ; Generic desktop controls (01h)
+ *      Usage (X),                  ; X (30h, dynamic value)
+ *      Usage (Y),                  ; Y (31h, dynamic value)
+ *      Usage (Wheel),              ; Wheel (38h, dynamic value)
+ *      Logical Minimum (-127),
+ *      Logical Maximum (127),
+ *      Report Size (8),
+ *      Report Count (3),
+ *      Input (Variable, Relative),
+ *      Usage Page (Consumer),      ; Consumer (0Ch)
+ *      Logical Minimum (-127),
+ *      Logical Maximum (127),
+ *      Report Size (8),
+ *      Report Count (1),
+ *      Usage (AC Pan),             ; AC pan (0238h, linear control)
+ *      Input (Variable, Relative),
+ *    End Collection,
+ *  End Collection,
+ *  Usage Page (Digitizer),         ; Digitizer (0Dh)
+ *  Usage (Pen),                    ; Pen (02h, application collection)
+ *  Collection (Application),
+ *    Report ID (2),
+ *    Usage (Stylus),               ; Stylus (20h, logical collection)
+ *    Collection (Physical),
+ *      Usage (00h),
+ *      Logical Minimum (0),
+ *      Logical Maximum (255),
+ *      Report Size (8),
+ *      Report Count (7),
+ *      Input (Variable),
+ *      Usage (Azimuth),            ; Azimuth (3Fh, dynamic value)
+ *      Usage (Altitude),           ; Altitude (40h, dynamic value)
+ *      Logical Minimum (0),
+ *      Logical Maximum (255),
+ *      Report Size (8),
+ *      Report Count (2),
+ *      Feature (Variable),
+ *    End Collection,
+ *    Report ID (5),
+ *    Usage Page (Digitizer),       ; Digitizer (0Dh)
+ *    Usage (Stylus),               ; Stylus (20h, logical collection)
+ *    Collection (Physical),
+ *      Usage (00h),
+ *      Logical Minimum (0),
+ *      Logical Maximum (255),
+ *      Report Size (8),
+ *      Report Count (7),
+ *      Input (Variable),
+ *    End Collection,
+ *    Report ID (10),
+ *    Usage Page (Digitizer),       ; Digitizer (0Dh)
+ *    Usage (Stylus),               ; Stylus (20h, logical collection)
+ *    Collection (Physical),
+ *      Usage (00h),
+ *      Logical Minimum (0),
+ *      Logical Maximum (255),
+ *      Report Size (8),
+ *      Report Count (7),
+ *      Input (Variable),
+ *    End Collection,
+ *    Report ID (16),
+ *    Usage (Stylus),               ; Stylus (20h, logical collection)
+ *    Collection (Physical),
+ *      Usage (Tip Switch),         ; Tip switch (42h, momentary control)
+ *      Usage (Barrel Switch),      ; Barrel switch (44h, momentary control)
+ *      Usage (Invert),             ; Invert (3Ch, momentary control)
+ *      Usage (Eraser),             ; Eraser (45h, momentary control)
+ *      Usage (In Range),           ; In range (32h, momentary control)
+ *      Logical Minimum (0),
+ *      Logical Maximum (1),
+ *      Report Size (1),
+ *      Report Count (5),
+ *      Input (Variable),
+ *      Report Count (3),
+ *      Input (Constant, Variable),
+ *      Usage Page (Desktop),       ; Generic desktop controls (01h)
+ *      Usage (X),                  ; X (30h, dynamic value)
+ *      Report Size (16),
+ *      Report Count (1),
+ *      Push,
+ *      Unit Exponent (13),
+ *      Unit (Inch^3),
+ *      Logical Minimum (0),
+ *      Logical Maximum (12288),
+ *      Physical Minimum (0),
+ *      Physical Maximum (12288),
+ *      Input (Variable),
+ *      Usage (Y),                  ; Y (31h, dynamic value)
+ *      Logical Minimum (0),
+ *      Logical Maximum (9216),
+ *      Physical Minimum (0),
+ *      Physical Maximum (9216),
+ *      Input (Variable),
+ *      Usage Page (Digitizer),     ; Digitizer (0Dh)
+ *      Usage (Tip Pressure),       ; Tip pressure (30h, dynamic value)
+ *      Logical Minimum (0),
+ *      Logical Maximum (1023),
+ *      Physical Minimum (0),
+ *      Physical Maximum (1023),
+ *      Input (Variable),
+ *    End Collection,
+ *  End Collection
+ */
+
+/* Size of the original report descriptor of Q Pad */
+#define Q_PAD_RDESC_ORIG_SIZE	241
+
+/*
+ * Fixed Q Pad descriptor.
+ *
+ * All the reports except the stylus report (ID 16) were removed as unused.
+ * The stylus buttons description was fixed.
+ */
+static __u8 q_pad_rdesc_fixed[] = {
+	0x05, 0x0D,         /*  Usage Page (Digitizer),             */
+	0x09, 0x02,         /*  Usage (Pen),                        */
+	0xA1, 0x01,         /*  Collection (Application),           */
+	0x85, 0x10,         /*      Report ID (16),                 */
+	0x09, 0x20,         /*      Usage (Stylus),                 */
+	0xA0,               /*      Collection (Physical),          */
+	0x09, 0x42,         /*          Usage (Tip Switch),         */
+	0x09, 0x44,         /*          Usage (Barrel Switch),      */
+	0x09, 0x46,         /*          Usage (Tablet Pick),        */
+	0x15, 0x01,         /*          Logical Minimum (1),        */
+	0x25, 0x03,         /*          Logical Maximum (3),        */
+	0x75, 0x04,         /*          Report Size (4),            */
+	0x95, 0x01,         /*          Report Count (1),           */
+	0x80,               /*          Input,                      */
+	0x09, 0x32,         /*          Usage (In Range),           */
+	0x14,               /*          Logical Minimum (0),        */
+	0x25, 0x01,         /*          Logical Maximum (1),        */
+	0x75, 0x01,         /*          Report Size (1),            */
+	0x95, 0x01,         /*          Report Count (1),           */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0x95, 0x03,         /*          Report Count (3),           */
+	0x81, 0x03,         /*          Input (Constant, Variable), */
+	0x75, 0x10,         /*          Report Size (16),           */
+	0x95, 0x01,         /*          Report Count (1),           */
+	0x14,               /*          Logical Minimum (0),        */
+	0xA4,               /*          Push,                       */
+	0x05, 0x01,         /*          Usage Page (Desktop),       */
+	0x65, 0x13,         /*          Unit (Inch),                */
+	0x55, 0xFD,         /*          Unit Exponent (-3),         */
+	0x34,               /*          Physical Minimum (0),       */
+	0x09, 0x30,         /*          Usage (X),                  */
+	0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */
+	0x26, 0x00, 0x30,   /*          Logical Maximum (12288),    */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0x09, 0x31,         /*          Usage (Y),                  */
+	0x46, 0x94, 0x11,   /*          Physical Maximum (4500),    */
+	0x26, 0x00, 0x24,   /*          Logical Maximum (9216),     */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0xB4,               /*          Pop,                        */
+	0x09, 0x30,         /*          Usage (Tip Pressure),       */
+	0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
+	0x81, 0x02,         /*          Input (Variable),           */
+	0xC0,               /*      End Collection,                 */
+	0xC0                /*  End Collection                      */
+};
+
+/*
  * Original Media Tablet 10.6 inch report descriptor.
  *
  * There are at least two versions of this model in the wild. They are
@@ -1049,6 +1233,12 @@ static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 			*rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed);
 		}
 		break;
+	case USB_DEVICE_ID_WALTOP_Q_PAD:
+		if (*rsize == Q_PAD_RDESC_ORIG_SIZE) {
+			rdesc = q_pad_rdesc_fixed;
+			*rsize = sizeof(q_pad_rdesc_fixed);
+		}
+		break;
 	case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
 		if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
 			rdesc = media_tablet_10_6_inch_rdesc_fixed;
@@ -1071,6 +1261,8 @@ static const struct hid_device_id waltop_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
 				USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
+				USB_DEVICE_ID_WALTOP_Q_PAD) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
 				USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
 				USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index c831af9..ae7d283 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -59,6 +59,7 @@ static const struct hid_blacklist {
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
diff --git a/drivers/hsi/Kconfig b/drivers/hsi/Kconfig
new file mode 100644
index 0000000..d94e38d
--- /dev/null
+++ b/drivers/hsi/Kconfig
@@ -0,0 +1,19 @@
+#
+# HSI driver configuration
+#
+menuconfig HSI
+	tristate "HSI support"
+	---help---
+	  The "High speed synchronous Serial Interface" is
+	  synchronous serial interface used mainly to connect
+	  application engines and cellular modems.
+
+if HSI
+
+config HSI_BOARDINFO
+	bool
+	default y
+
+source "drivers/hsi/clients/Kconfig"
+
+endif # HSI
diff --git a/drivers/hsi/Makefile b/drivers/hsi/Makefile
new file mode 100644
index 0000000..9d5d33f
--- /dev/null
+++ b/drivers/hsi/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for HSI
+#
+obj-$(CONFIG_HSI_BOARDINFO)	+= hsi_boardinfo.o
+obj-$(CONFIG_HSI)		+= hsi.o
+obj-y				+= clients/
diff --git a/drivers/hsi/clients/Kconfig b/drivers/hsi/clients/Kconfig
new file mode 100644
index 0000000..3bacd27
--- /dev/null
+++ b/drivers/hsi/clients/Kconfig
@@ -0,0 +1,13 @@
+#
+# HSI clients configuration
+#
+
+comment "HSI clients"
+
+config HSI_CHAR
+	tristate "HSI/SSI character driver"
+	depends on HSI
+	---help---
+	  If you say Y here, you will enable the HSI/SSI character driver.
+	  This driver provides a simple character device interface for
+	  serial communication with the cellular modem over HSI/SSI bus.
diff --git a/drivers/hsi/clients/Makefile b/drivers/hsi/clients/Makefile
new file mode 100644
index 0000000..327c0e2
--- /dev/null
+++ b/drivers/hsi/clients/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for HSI clients
+#
+
+obj-$(CONFIG_HSI_CHAR)	+= hsi_char.o
diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c
new file mode 100644
index 0000000..88a050d
--- /dev/null
+++ b/drivers/hsi/clients/hsi_char.c
@@ -0,0 +1,802 @@
+/*
+ * HSI character device driver, implements the character device
+ * interface.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Andras Domokos <andras.domokos@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/kmemleak.h>
+#include <linux/ioctl.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/scatterlist.h>
+#include <linux/stat.h>
+#include <linux/hsi/hsi.h>
+#include <linux/hsi/hsi_char.h>
+
+#define HSC_DEVS		16 /* Num of channels */
+#define HSC_MSGS		4
+
+#define HSC_RXBREAK		0
+
+#define HSC_ID_BITS		6
+#define HSC_PORT_ID_BITS	4
+#define HSC_ID_MASK		3
+#define HSC_PORT_ID_MASK	3
+#define HSC_CH_MASK		0xf
+
+/*
+ * We support up to 4 controllers that can have up to 4
+ * ports, which should currently be more than enough.
+ */
+#define HSC_BASEMINOR(id, port_id) \
+		((((id) & HSC_ID_MASK) << HSC_ID_BITS) | \
+		(((port_id) & HSC_PORT_ID_MASK) << HSC_PORT_ID_BITS))
+
+enum {
+	HSC_CH_OPEN,
+	HSC_CH_READ,
+	HSC_CH_WRITE,
+	HSC_CH_WLINE,
+};
+
+enum {
+	HSC_RX,
+	HSC_TX,
+};
+
+struct hsc_client_data;
+/**
+ * struct hsc_channel - hsi_char internal channel data
+ * @ch: channel number
+ * @flags: Keeps state of the channel (open/close, reading, writing)
+ * @free_msgs_list: List of free HSI messages/requests
+ * @rx_msgs_queue: List of pending RX requests
+ * @tx_msgs_queue: List of pending TX requests
+ * @lock: Serialize access to the lists
+ * @cl: reference to the associated hsi_client
+ * @cl_data: reference to the client data that this channels belongs to
+ * @rx_wait: RX requests wait queue
+ * @tx_wait: TX requests wait queue
+ */
+struct hsc_channel {
+	unsigned int		ch;
+	unsigned long		flags;
+	struct list_head	free_msgs_list;
+	struct list_head	rx_msgs_queue;
+	struct list_head	tx_msgs_queue;
+	spinlock_t		lock;
+	struct hsi_client	*cl;
+	struct hsc_client_data *cl_data;
+	wait_queue_head_t	rx_wait;
+	wait_queue_head_t	tx_wait;
+};
+
+/**
+ * struct hsc_client_data - hsi_char internal client data
+ * @cdev: Characther device associated to the hsi_client
+ * @lock: Lock to serialize open/close access
+ * @flags: Keeps track of port state (rx hwbreak armed)
+ * @usecnt: Use count for claiming the HSI port (mutex protected)
+ * @cl: Referece to the HSI client
+ * @channels: Array of channels accessible by the client
+ */
+struct hsc_client_data {
+	struct cdev		cdev;
+	struct mutex		lock;
+	unsigned long		flags;
+	unsigned int		usecnt;
+	struct hsi_client	*cl;
+	struct hsc_channel	channels[HSC_DEVS];
+};
+
+/* Stores the major number dynamically allocated for hsi_char */
+static unsigned int hsc_major;
+/* Maximum buffer size that hsi_char will accept from userspace */
+static unsigned int max_data_size = 0x1000;
+module_param(max_data_size, uint, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)");
+
+static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg,
+							struct list_head *queue)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&channel->lock, flags);
+	list_add_tail(&msg->link, queue);
+	spin_unlock_irqrestore(&channel->lock, flags);
+}
+
+static struct hsi_msg *hsc_get_first_msg(struct hsc_channel *channel,
+							struct list_head *queue)
+{
+	struct hsi_msg *msg = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&channel->lock, flags);
+
+	if (list_empty(queue))
+		goto out;
+
+	msg = list_first_entry(queue, struct hsi_msg, link);
+	list_del(&msg->link);
+out:
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	return msg;
+}
+
+static inline void hsc_msg_free(struct hsi_msg *msg)
+{
+	kfree(sg_virt(msg->sgt.sgl));
+	hsi_free_msg(msg);
+}
+
+static void hsc_free_list(struct list_head *list)
+{
+	struct hsi_msg *msg, *tmp;
+
+	list_for_each_entry_safe(msg, tmp, list, link) {
+		list_del(&msg->link);
+		hsc_msg_free(msg);
+	}
+}
+
+static void hsc_reset_list(struct hsc_channel *channel, struct list_head *l)
+{
+	unsigned long flags;
+	LIST_HEAD(list);
+
+	spin_lock_irqsave(&channel->lock, flags);
+	list_splice_init(l, &list);
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	hsc_free_list(&list);
+}
+
+static inline struct hsi_msg *hsc_msg_alloc(unsigned int alloc_size)
+{
+	struct hsi_msg *msg;
+	void *buf;
+
+	msg = hsi_alloc_msg(1, GFP_KERNEL);
+	if (!msg)
+		goto out;
+	buf = kmalloc(alloc_size, GFP_KERNEL);
+	if (!buf) {
+		hsi_free_msg(msg);
+		goto out;
+	}
+	sg_init_one(msg->sgt.sgl, buf, alloc_size);
+	/* Ignore false positive, due to sg pointer handling */
+	kmemleak_ignore(buf);
+
+	return msg;
+out:
+	return NULL;
+}
+
+static inline int hsc_msgs_alloc(struct hsc_channel *channel)
+{
+	struct hsi_msg *msg;
+	int i;
+
+	for (i = 0; i < HSC_MSGS; i++) {
+		msg = hsc_msg_alloc(max_data_size);
+		if (!msg)
+			goto out;
+		msg->channel = channel->ch;
+		list_add_tail(&msg->link, &channel->free_msgs_list);
+	}
+
+	return 0;
+out:
+	hsc_free_list(&channel->free_msgs_list);
+
+	return -ENOMEM;
+}
+
+static inline unsigned int hsc_msg_len_get(struct hsi_msg *msg)
+{
+	return msg->sgt.sgl->length;
+}
+
+static inline void hsc_msg_len_set(struct hsi_msg *msg, unsigned int len)
+{
+	msg->sgt.sgl->length = len;
+}
+
+static void hsc_rx_completed(struct hsi_msg *msg)
+{
+	struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+	struct hsc_channel *channel = cl_data->channels + msg->channel;
+
+	if (test_bit(HSC_CH_READ, &channel->flags)) {
+		hsc_add_tail(channel, msg, &channel->rx_msgs_queue);
+		wake_up(&channel->rx_wait);
+	} else {
+		hsc_add_tail(channel, msg, &channel->free_msgs_list);
+	}
+}
+
+static void hsc_rx_msg_destructor(struct hsi_msg *msg)
+{
+	msg->status = HSI_STATUS_ERROR;
+	hsc_msg_len_set(msg, 0);
+	hsc_rx_completed(msg);
+}
+
+static void hsc_tx_completed(struct hsi_msg *msg)
+{
+	struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+	struct hsc_channel *channel = cl_data->channels + msg->channel;
+
+	if (test_bit(HSC_CH_WRITE, &channel->flags)) {
+		hsc_add_tail(channel, msg, &channel->tx_msgs_queue);
+		wake_up(&channel->tx_wait);
+	} else {
+		hsc_add_tail(channel, msg, &channel->free_msgs_list);
+	}
+}
+
+static void hsc_tx_msg_destructor(struct hsi_msg *msg)
+{
+	msg->status = HSI_STATUS_ERROR;
+	hsc_msg_len_set(msg, 0);
+	hsc_tx_completed(msg);
+}
+
+static void hsc_break_req_destructor(struct hsi_msg *msg)
+{
+	struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+
+	hsi_free_msg(msg);
+	clear_bit(HSC_RXBREAK, &cl_data->flags);
+}
+
+static void hsc_break_received(struct hsi_msg *msg)
+{
+	struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl);
+	struct hsc_channel *channel = cl_data->channels;
+	int i, ret;
+
+	/* Broadcast HWBREAK on all channels */
+	for (i = 0; i < HSC_DEVS; i++, channel++) {
+		struct hsi_msg *msg2;
+
+		if (!test_bit(HSC_CH_READ, &channel->flags))
+			continue;
+		msg2 = hsc_get_first_msg(channel, &channel->free_msgs_list);
+		if (!msg2)
+			continue;
+		clear_bit(HSC_CH_READ, &channel->flags);
+		hsc_msg_len_set(msg2, 0);
+		msg2->status = HSI_STATUS_COMPLETED;
+		hsc_add_tail(channel, msg2, &channel->rx_msgs_queue);
+		wake_up(&channel->rx_wait);
+	}
+	hsi_flush(msg->cl);
+	ret = hsi_async_read(msg->cl, msg);
+	if (ret < 0)
+		hsc_break_req_destructor(msg);
+}
+
+static int hsc_break_request(struct hsi_client *cl)
+{
+	struct hsc_client_data *cl_data = hsi_client_drvdata(cl);
+	struct hsi_msg *msg;
+	int ret;
+
+	if (test_and_set_bit(HSC_RXBREAK, &cl_data->flags))
+		return -EBUSY;
+
+	msg = hsi_alloc_msg(0, GFP_KERNEL);
+	if (!msg) {
+		clear_bit(HSC_RXBREAK, &cl_data->flags);
+		return -ENOMEM;
+	}
+	msg->break_frame = 1;
+	msg->complete = hsc_break_received;
+	msg->destructor = hsc_break_req_destructor;
+	ret = hsi_async_read(cl, msg);
+	if (ret < 0)
+		hsc_break_req_destructor(msg);
+
+	return ret;
+}
+
+static int hsc_break_send(struct hsi_client *cl)
+{
+	struct hsi_msg *msg;
+	int ret;
+
+	msg = hsi_alloc_msg(0, GFP_ATOMIC);
+	if (!msg)
+		return -ENOMEM;
+	msg->break_frame = 1;
+	msg->complete = hsi_free_msg;
+	msg->destructor = hsi_free_msg;
+	ret = hsi_async_write(cl, msg);
+	if (ret < 0)
+		hsi_free_msg(msg);
+
+	return ret;
+}
+
+static int hsc_rx_set(struct hsi_client *cl, struct hsc_rx_config *rxc)
+{
+	struct hsi_config tmp;
+	int ret;
+
+	if ((rxc->mode != HSI_MODE_STREAM) && (rxc->mode != HSI_MODE_FRAME))
+		return -EINVAL;
+	if ((rxc->channels == 0) || (rxc->channels > HSC_DEVS))
+		return -EINVAL;
+	if (rxc->channels & (rxc->channels - 1))
+		return -EINVAL;
+	if ((rxc->flow != HSI_FLOW_SYNC) && (rxc->flow != HSI_FLOW_PIPE))
+		return -EINVAL;
+	tmp = cl->rx_cfg;
+	cl->rx_cfg.mode = rxc->mode;
+	cl->rx_cfg.channels = rxc->channels;
+	cl->rx_cfg.flow = rxc->flow;
+	ret = hsi_setup(cl);
+	if (ret < 0) {
+		cl->rx_cfg = tmp;
+		return ret;
+	}
+	if (rxc->mode == HSI_MODE_FRAME)
+		hsc_break_request(cl);
+
+	return ret;
+}
+
+static inline void hsc_rx_get(struct hsi_client *cl, struct hsc_rx_config *rxc)
+{
+	rxc->mode = cl->rx_cfg.mode;
+	rxc->channels = cl->rx_cfg.channels;
+	rxc->flow = cl->rx_cfg.flow;
+}
+
+static int hsc_tx_set(struct hsi_client *cl, struct hsc_tx_config *txc)
+{
+	struct hsi_config tmp;
+	int ret;
+
+	if ((txc->mode != HSI_MODE_STREAM) && (txc->mode != HSI_MODE_FRAME))
+		return -EINVAL;
+	if ((txc->channels == 0) || (txc->channels > HSC_DEVS))
+		return -EINVAL;
+	if (txc->channels & (txc->channels - 1))
+		return -EINVAL;
+	if ((txc->arb_mode != HSI_ARB_RR) && (txc->arb_mode != HSI_ARB_PRIO))
+		return -EINVAL;
+	tmp = cl->tx_cfg;
+	cl->tx_cfg.mode = txc->mode;
+	cl->tx_cfg.channels = txc->channels;
+	cl->tx_cfg.speed = txc->speed;
+	cl->tx_cfg.arb_mode = txc->arb_mode;
+	ret = hsi_setup(cl);
+	if (ret < 0) {
+		cl->tx_cfg = tmp;
+		return ret;
+	}
+
+	return ret;
+}
+
+static inline void hsc_tx_get(struct hsi_client *cl, struct hsc_tx_config *txc)
+{
+	txc->mode = cl->tx_cfg.mode;
+	txc->channels = cl->tx_cfg.channels;
+	txc->speed = cl->tx_cfg.speed;
+	txc->arb_mode = cl->tx_cfg.arb_mode;
+}
+
+static ssize_t hsc_read(struct file *file, char __user *buf, size_t len,
+						loff_t *ppos __maybe_unused)
+{
+	struct hsc_channel *channel = file->private_data;
+	struct hsi_msg *msg;
+	ssize_t ret;
+
+	if (len == 0)
+		return 0;
+	if (!IS_ALIGNED(len, sizeof(u32)))
+		return -EINVAL;
+	if (len > max_data_size)
+		len = max_data_size;
+	if (channel->ch >= channel->cl->rx_cfg.channels)
+		return -ECHRNG;
+	if (test_and_set_bit(HSC_CH_READ, &channel->flags))
+		return -EBUSY;
+	msg = hsc_get_first_msg(channel, &channel->free_msgs_list);
+	if (!msg) {
+		ret = -ENOSPC;
+		goto out;
+	}
+	hsc_msg_len_set(msg, len);
+	msg->complete = hsc_rx_completed;
+	msg->destructor = hsc_rx_msg_destructor;
+	ret = hsi_async_read(channel->cl, msg);
+	if (ret < 0) {
+		hsc_add_tail(channel, msg, &channel->free_msgs_list);
+		goto out;
+	}
+
+	ret = wait_event_interruptible(channel->rx_wait,
+					!list_empty(&channel->rx_msgs_queue));
+	if (ret < 0) {
+		clear_bit(HSC_CH_READ, &channel->flags);
+		hsi_flush(channel->cl);
+		return -EINTR;
+	}
+
+	msg = hsc_get_first_msg(channel, &channel->rx_msgs_queue);
+	if (msg) {
+		if (msg->status != HSI_STATUS_ERROR) {
+			ret = copy_to_user((void __user *)buf,
+			sg_virt(msg->sgt.sgl), hsc_msg_len_get(msg));
+			if (ret)
+				ret = -EFAULT;
+			else
+				ret = hsc_msg_len_get(msg);
+		} else {
+			ret = -EIO;
+		}
+		hsc_add_tail(channel, msg, &channel->free_msgs_list);
+	}
+out:
+	clear_bit(HSC_CH_READ, &channel->flags);
+
+	return ret;
+}
+
+static ssize_t hsc_write(struct file *file, const char __user *buf, size_t len,
+						loff_t *ppos __maybe_unused)
+{
+	struct hsc_channel *channel = file->private_data;
+	struct hsi_msg *msg;
+	ssize_t ret;
+
+	if ((len == 0) || !IS_ALIGNED(len, sizeof(u32)))
+		return -EINVAL;
+	if (len > max_data_size)
+		len = max_data_size;
+	if (channel->ch >= channel->cl->tx_cfg.channels)
+		return -ECHRNG;
+	if (test_and_set_bit(HSC_CH_WRITE, &channel->flags))
+		return -EBUSY;
+	msg = hsc_get_first_msg(channel, &channel->free_msgs_list);
+	if (!msg) {
+		clear_bit(HSC_CH_WRITE, &channel->flags);
+		return -ENOSPC;
+	}
+	if (copy_from_user(sg_virt(msg->sgt.sgl), (void __user *)buf, len)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	hsc_msg_len_set(msg, len);
+	msg->complete = hsc_tx_completed;
+	msg->destructor = hsc_tx_msg_destructor;
+	ret = hsi_async_write(channel->cl, msg);
+	if (ret < 0)
+		goto out;
+
+	ret = wait_event_interruptible(channel->tx_wait,
+					!list_empty(&channel->tx_msgs_queue));
+	if (ret < 0) {
+		clear_bit(HSC_CH_WRITE, &channel->flags);
+		hsi_flush(channel->cl);
+		return -EINTR;
+	}
+
+	msg = hsc_get_first_msg(channel, &channel->tx_msgs_queue);
+	if (msg) {
+		if (msg->status == HSI_STATUS_ERROR)
+			ret = -EIO;
+		else
+			ret = hsc_msg_len_get(msg);
+
+		hsc_add_tail(channel, msg, &channel->free_msgs_list);
+	}
+out:
+	clear_bit(HSC_CH_WRITE, &channel->flags);
+
+	return ret;
+}
+
+static long hsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct hsc_channel *channel = file->private_data;
+	unsigned int state;
+	struct hsc_rx_config rxc;
+	struct hsc_tx_config txc;
+	long ret = 0;
+
+	switch (cmd) {
+	case HSC_RESET:
+		hsi_flush(channel->cl);
+		break;
+	case HSC_SET_PM:
+		if (copy_from_user(&state, (void __user *)arg, sizeof(state)))
+			return -EFAULT;
+		if (state == HSC_PM_DISABLE) {
+			if (test_and_set_bit(HSC_CH_WLINE, &channel->flags))
+				return -EINVAL;
+			ret = hsi_start_tx(channel->cl);
+		} else if (state == HSC_PM_ENABLE) {
+			if (!test_and_clear_bit(HSC_CH_WLINE, &channel->flags))
+				return -EINVAL;
+			ret = hsi_stop_tx(channel->cl);
+		} else {
+			ret = -EINVAL;
+		}
+		break;
+	case HSC_SEND_BREAK:
+		return hsc_break_send(channel->cl);
+	case HSC_SET_RX:
+		if (copy_from_user(&rxc, (void __user *)arg, sizeof(rxc)))
+			return -EFAULT;
+		return hsc_rx_set(channel->cl, &rxc);
+	case HSC_GET_RX:
+		hsc_rx_get(channel->cl, &rxc);
+		if (copy_to_user((void __user *)arg, &rxc, sizeof(rxc)))
+			return -EFAULT;
+		break;
+	case HSC_SET_TX:
+		if (copy_from_user(&txc, (void __user *)arg, sizeof(txc)))
+			return -EFAULT;
+		return hsc_tx_set(channel->cl, &txc);
+	case HSC_GET_TX:
+		hsc_tx_get(channel->cl, &txc);
+		if (copy_to_user((void __user *)arg, &txc, sizeof(txc)))
+			return -EFAULT;
+		break;
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return ret;
+}
+
+static inline void __hsc_port_release(struct hsc_client_data *cl_data)
+{
+	BUG_ON(cl_data->usecnt == 0);
+
+	if (--cl_data->usecnt == 0) {
+		hsi_flush(cl_data->cl);
+		hsi_release_port(cl_data->cl);
+	}
+}
+
+static int hsc_open(struct inode *inode, struct file *file)
+{
+	struct hsc_client_data *cl_data;
+	struct hsc_channel *channel;
+	int ret = 0;
+
+	pr_debug("open, minor = %d\n", iminor(inode));
+
+	cl_data = container_of(inode->i_cdev, struct hsc_client_data, cdev);
+	mutex_lock(&cl_data->lock);
+	channel = cl_data->channels + (iminor(inode) & HSC_CH_MASK);
+
+	if (test_and_set_bit(HSC_CH_OPEN, &channel->flags)) {
+		ret = -EBUSY;
+		goto out;
+	}
+	/*
+	 * Check if we have already claimed the port associated to the HSI
+	 * client. If not then try to claim it, else increase its refcount
+	 */
+	if (cl_data->usecnt == 0) {
+		ret = hsi_claim_port(cl_data->cl, 0);
+		if (ret < 0)
+			goto out;
+		hsi_setup(cl_data->cl);
+	}
+	cl_data->usecnt++;
+
+	ret = hsc_msgs_alloc(channel);
+	if (ret < 0) {
+		__hsc_port_release(cl_data);
+		goto out;
+	}
+
+	file->private_data = channel;
+	mutex_unlock(&cl_data->lock);
+
+	return ret;
+out:
+	mutex_unlock(&cl_data->lock);
+
+	return ret;
+}
+
+static int hsc_release(struct inode *inode __maybe_unused, struct file *file)
+{
+	struct hsc_channel *channel = file->private_data;
+	struct hsc_client_data *cl_data = channel->cl_data;
+
+	mutex_lock(&cl_data->lock);
+	file->private_data = NULL;
+	if (test_and_clear_bit(HSC_CH_WLINE, &channel->flags))
+		hsi_stop_tx(channel->cl);
+	__hsc_port_release(cl_data);
+	hsc_reset_list(channel, &channel->rx_msgs_queue);
+	hsc_reset_list(channel, &channel->tx_msgs_queue);
+	hsc_reset_list(channel, &channel->free_msgs_list);
+	clear_bit(HSC_CH_READ, &channel->flags);
+	clear_bit(HSC_CH_WRITE, &channel->flags);
+	clear_bit(HSC_CH_OPEN, &channel->flags);
+	wake_up(&channel->rx_wait);
+	wake_up(&channel->tx_wait);
+	mutex_unlock(&cl_data->lock);
+
+	return 0;
+}
+
+static const struct file_operations hsc_fops = {
+	.owner		= THIS_MODULE,
+	.read		= hsc_read,
+	.write		= hsc_write,
+	.unlocked_ioctl	= hsc_ioctl,
+	.open		= hsc_open,
+	.release	= hsc_release,
+};
+
+static void __devinit hsc_channel_init(struct hsc_channel *channel)
+{
+	init_waitqueue_head(&channel->rx_wait);
+	init_waitqueue_head(&channel->tx_wait);
+	spin_lock_init(&channel->lock);
+	INIT_LIST_HEAD(&channel->free_msgs_list);
+	INIT_LIST_HEAD(&channel->rx_msgs_queue);
+	INIT_LIST_HEAD(&channel->tx_msgs_queue);
+}
+
+static int __devinit hsc_probe(struct device *dev)
+{
+	const char devname[] = "hsi_char";
+	struct hsc_client_data *cl_data;
+	struct hsc_channel *channel;
+	struct hsi_client *cl = to_hsi_client(dev);
+	unsigned int hsc_baseminor;
+	dev_t hsc_dev;
+	int ret;
+	int i;
+
+	cl_data = kzalloc(sizeof(*cl_data), GFP_KERNEL);
+	if (!cl_data) {
+		dev_err(dev, "Could not allocate hsc_client_data\n");
+		return -ENOMEM;
+	}
+	hsc_baseminor = HSC_BASEMINOR(hsi_id(cl), hsi_port_id(cl));
+	if (!hsc_major) {
+		ret = alloc_chrdev_region(&hsc_dev, hsc_baseminor,
+						HSC_DEVS, devname);
+		if (ret > 0)
+			hsc_major = MAJOR(hsc_dev);
+	} else {
+		hsc_dev = MKDEV(hsc_major, hsc_baseminor);
+		ret = register_chrdev_region(hsc_dev, HSC_DEVS, devname);
+	}
+	if (ret < 0) {
+		dev_err(dev, "Device %s allocation failed %d\n",
+					hsc_major ? "minor" : "major", ret);
+		goto out1;
+	}
+	mutex_init(&cl_data->lock);
+	hsi_client_set_drvdata(cl, cl_data);
+	cdev_init(&cl_data->cdev, &hsc_fops);
+	cl_data->cdev.owner = THIS_MODULE;
+	cl_data->cl = cl;
+	for (i = 0, channel = cl_data->channels; i < HSC_DEVS; i++, channel++) {
+		hsc_channel_init(channel);
+		channel->ch = i;
+		channel->cl = cl;
+		channel->cl_data = cl_data;
+	}
+
+	/* 1 hsi client -> N char devices (one for each channel) */
+	ret = cdev_add(&cl_data->cdev, hsc_dev, HSC_DEVS);
+	if (ret) {
+		dev_err(dev, "Could not add char device %d\n", ret);
+		goto out2;
+	}
+
+	return 0;
+out2:
+	unregister_chrdev_region(hsc_dev, HSC_DEVS);
+out1:
+	kfree(cl_data);
+
+	return ret;
+}
+
+static int __devexit hsc_remove(struct device *dev)
+{
+	struct hsi_client *cl = to_hsi_client(dev);
+	struct hsc_client_data *cl_data = hsi_client_drvdata(cl);
+	dev_t hsc_dev = cl_data->cdev.dev;
+
+	cdev_del(&cl_data->cdev);
+	unregister_chrdev_region(hsc_dev, HSC_DEVS);
+	hsi_client_set_drvdata(cl, NULL);
+	kfree(cl_data);
+
+	return 0;
+}
+
+static struct hsi_client_driver hsc_driver = {
+	.driver = {
+		.name	= "hsi_char",
+		.owner	= THIS_MODULE,
+		.probe	= hsc_probe,
+		.remove	= __devexit_p(hsc_remove),
+	},
+};
+
+static int __init hsc_init(void)
+{
+	int ret;
+
+	if ((max_data_size < 4) || (max_data_size > 0x10000) ||
+		(max_data_size & (max_data_size - 1))) {
+		pr_err("Invalid max read/write data size");
+		return -EINVAL;
+	}
+
+	ret = hsi_register_client_driver(&hsc_driver);
+	if (ret) {
+		pr_err("Error while registering HSI/SSI driver %d", ret);
+		return ret;
+	}
+
+	pr_info("HSI/SSI char device loaded\n");
+
+	return 0;
+}
+module_init(hsc_init);
+
+static void __exit hsc_exit(void)
+{
+	hsi_unregister_client_driver(&hsc_driver);
+	pr_info("HSI char device removed\n");
+}
+module_exit(hsc_exit);
+
+MODULE_AUTHOR("Andras Domokos <andras.domokos@nokia.com>");
+MODULE_ALIAS("hsi:hsi_char");
+MODULE_DESCRIPTION("HSI character device");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hsi/hsi.c b/drivers/hsi/hsi.c
new file mode 100644
index 0000000..4e2d79b
--- /dev/null
+++ b/drivers/hsi/hsi.c
@@ -0,0 +1,494 @@
+/*
+ * HSI core.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/hsi/hsi.h>
+#include <linux/compiler.h>
+#include <linux/rwsem.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include "hsi_core.h"
+
+static struct device_type hsi_ctrl = {
+	.name	= "hsi_controller",
+};
+
+static struct device_type hsi_cl = {
+	.name	= "hsi_client",
+};
+
+static struct device_type hsi_port = {
+	.name	= "hsi_port",
+};
+
+static ssize_t modalias_show(struct device *dev,
+			struct device_attribute *a __maybe_unused, char *buf)
+{
+	return sprintf(buf, "hsi:%s\n", dev_name(dev));
+}
+
+static struct device_attribute hsi_bus_dev_attrs[] = {
+	__ATTR_RO(modalias),
+	__ATTR_NULL,
+};
+
+static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	if (dev->type == &hsi_cl)
+		add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev));
+
+	return 0;
+}
+
+static int hsi_bus_match(struct device *dev, struct device_driver *driver)
+{
+	return strcmp(dev_name(dev), driver->name) == 0;
+}
+
+static struct bus_type hsi_bus_type = {
+	.name		= "hsi",
+	.dev_attrs	= hsi_bus_dev_attrs,
+	.match		= hsi_bus_match,
+	.uevent		= hsi_bus_uevent,
+};
+
+static void hsi_client_release(struct device *dev)
+{
+	kfree(to_hsi_client(dev));
+}
+
+static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info)
+{
+	struct hsi_client *cl;
+	unsigned long flags;
+
+	cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+	if (!cl)
+		return;
+	cl->device.type = &hsi_cl;
+	cl->tx_cfg = info->tx_cfg;
+	cl->rx_cfg = info->rx_cfg;
+	cl->device.bus = &hsi_bus_type;
+	cl->device.parent = &port->device;
+	cl->device.release = hsi_client_release;
+	dev_set_name(&cl->device, info->name);
+	cl->device.platform_data = info->platform_data;
+	spin_lock_irqsave(&port->clock, flags);
+	list_add_tail(&cl->link, &port->clients);
+	spin_unlock_irqrestore(&port->clock, flags);
+	if (info->archdata)
+		cl->device.archdata = *info->archdata;
+	if (device_register(&cl->device) < 0) {
+		pr_err("hsi: failed to register client: %s\n", info->name);
+		kfree(cl);
+	}
+}
+
+static void hsi_scan_board_info(struct hsi_controller *hsi)
+{
+	struct hsi_cl_info *cl_info;
+	struct hsi_port	*p;
+
+	list_for_each_entry(cl_info, &hsi_board_list, list)
+		if (cl_info->info.hsi_id == hsi->id) {
+			p = hsi_find_port_num(hsi, cl_info->info.port);
+			if (!p)
+				continue;
+			hsi_new_client(p, &cl_info->info);
+		}
+}
+
+static int hsi_remove_client(struct device *dev, void *data __maybe_unused)
+{
+	struct hsi_client *cl = to_hsi_client(dev);
+	struct hsi_port *port = to_hsi_port(dev->parent);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->clock, flags);
+	list_del(&cl->link);
+	spin_unlock_irqrestore(&port->clock, flags);
+	device_unregister(dev);
+
+	return 0;
+}
+
+static int hsi_remove_port(struct device *dev, void *data __maybe_unused)
+{
+	device_for_each_child(dev, NULL, hsi_remove_client);
+	device_unregister(dev);
+
+	return 0;
+}
+
+static void hsi_controller_release(struct device *dev __maybe_unused)
+{
+}
+
+static void hsi_port_release(struct device *dev __maybe_unused)
+{
+}
+
+/**
+ * hsi_unregister_controller - Unregister an HSI controller
+ * @hsi: The HSI controller to register
+ */
+void hsi_unregister_controller(struct hsi_controller *hsi)
+{
+	device_for_each_child(&hsi->device, NULL, hsi_remove_port);
+	device_unregister(&hsi->device);
+}
+EXPORT_SYMBOL_GPL(hsi_unregister_controller);
+
+/**
+ * hsi_register_controller - Register an HSI controller and its ports
+ * @hsi: The HSI controller to register
+ *
+ * Returns -errno on failure, 0 on success.
+ */
+int hsi_register_controller(struct hsi_controller *hsi)
+{
+	unsigned int i;
+	int err;
+
+	hsi->device.type = &hsi_ctrl;
+	hsi->device.bus = &hsi_bus_type;
+	hsi->device.release = hsi_controller_release;
+	err = device_register(&hsi->device);
+	if (err < 0)
+		return err;
+	for (i = 0; i < hsi->num_ports; i++) {
+		hsi->port[i].device.parent = &hsi->device;
+		hsi->port[i].device.bus = &hsi_bus_type;
+		hsi->port[i].device.release = hsi_port_release;
+		hsi->port[i].device.type = &hsi_port;
+		INIT_LIST_HEAD(&hsi->port[i].clients);
+		spin_lock_init(&hsi->port[i].clock);
+		err = device_register(&hsi->port[i].device);
+		if (err < 0)
+			goto out;
+	}
+	/* Populate HSI bus with HSI clients */
+	hsi_scan_board_info(hsi);
+
+	return 0;
+out:
+	hsi_unregister_controller(hsi);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(hsi_register_controller);
+
+/**
+ * hsi_register_client_driver - Register an HSI client to the HSI bus
+ * @drv: HSI client driver to register
+ *
+ * Returns -errno on failure, 0 on success.
+ */
+int hsi_register_client_driver(struct hsi_client_driver *drv)
+{
+	drv->driver.bus = &hsi_bus_type;
+
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(hsi_register_client_driver);
+
+static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused)
+{
+	return 0;
+}
+
+static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused)
+{
+	return 0;
+}
+
+/**
+ * hsi_alloc_controller - Allocate an HSI controller and its ports
+ * @n_ports: Number of ports on the HSI controller
+ * @flags: Kernel allocation flags
+ *
+ * Return NULL on failure or a pointer to an hsi_controller on success.
+ */
+struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags)
+{
+	struct hsi_controller	*hsi;
+	struct hsi_port		*port;
+	unsigned int		i;
+
+	if (!n_ports)
+		return NULL;
+
+	port = kzalloc(sizeof(*port)*n_ports, flags);
+	if (!port)
+		return NULL;
+	hsi = kzalloc(sizeof(*hsi), flags);
+	if (!hsi)
+		goto out;
+	for (i = 0; i < n_ports; i++) {
+		dev_set_name(&port[i].device, "port%d", i);
+		port[i].num = i;
+		port[i].async = hsi_dummy_msg;
+		port[i].setup = hsi_dummy_cl;
+		port[i].flush = hsi_dummy_cl;
+		port[i].start_tx = hsi_dummy_cl;
+		port[i].stop_tx = hsi_dummy_cl;
+		port[i].release = hsi_dummy_cl;
+		mutex_init(&port[i].lock);
+	}
+	hsi->num_ports = n_ports;
+	hsi->port = port;
+
+	return hsi;
+out:
+	kfree(port);
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(hsi_alloc_controller);
+
+/**
+ * hsi_free_controller - Free an HSI controller
+ * @hsi: Pointer to HSI controller
+ */
+void hsi_free_controller(struct hsi_controller *hsi)
+{
+	if (!hsi)
+		return;
+
+	kfree(hsi->port);
+	kfree(hsi);
+}
+EXPORT_SYMBOL_GPL(hsi_free_controller);
+
+/**
+ * hsi_free_msg - Free an HSI message
+ * @msg: Pointer to the HSI message
+ *
+ * Client is responsible to free the buffers pointed by the scatterlists.
+ */
+void hsi_free_msg(struct hsi_msg *msg)
+{
+	if (!msg)
+		return;
+	sg_free_table(&msg->sgt);
+	kfree(msg);
+}
+EXPORT_SYMBOL_GPL(hsi_free_msg);
+
+/**
+ * hsi_alloc_msg - Allocate an HSI message
+ * @nents: Number of memory entries
+ * @flags: Kernel allocation flags
+ *
+ * nents can be 0. This mainly makes sense for read transfer.
+ * In that case, HSI drivers will call the complete callback when
+ * there is data to be read without consuming it.
+ *
+ * Return NULL on failure or a pointer to an hsi_msg on success.
+ */
+struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags)
+{
+	struct hsi_msg *msg;
+	int err;
+
+	msg = kzalloc(sizeof(*msg), flags);
+	if (!msg)
+		return NULL;
+
+	if (!nents)
+		return msg;
+
+	err = sg_alloc_table(&msg->sgt, nents, flags);
+	if (unlikely(err)) {
+		kfree(msg);
+		msg = NULL;
+	}
+
+	return msg;
+}
+EXPORT_SYMBOL_GPL(hsi_alloc_msg);
+
+/**
+ * hsi_async - Submit an HSI transfer to the controller
+ * @cl: HSI client sending the transfer
+ * @msg: The HSI transfer passed to controller
+ *
+ * The HSI message must have the channel, ttype, complete and destructor
+ * fields set beforehand. If nents > 0 then the client has to initialize
+ * also the scatterlists to point to the buffers to write to or read from.
+ *
+ * HSI controllers relay on pre-allocated buffers from their clients and they
+ * do not allocate buffers on their own.
+ *
+ * Once the HSI message transfer finishes, the HSI controller calls the
+ * complete callback with the status and actual_len fields of the HSI message
+ * updated. The complete callback can be called before returning from
+ * hsi_async.
+ *
+ * Returns -errno on failure or 0 on success
+ */
+int hsi_async(struct hsi_client *cl, struct hsi_msg *msg)
+{
+	struct hsi_port *port = hsi_get_port(cl);
+
+	if (!hsi_port_claimed(cl))
+		return -EACCES;
+
+	WARN_ON_ONCE(!msg->destructor || !msg->complete);
+	msg->cl = cl;
+
+	return port->async(msg);
+}
+EXPORT_SYMBOL_GPL(hsi_async);
+
+/**
+ * hsi_claim_port - Claim the HSI client's port
+ * @cl: HSI client that wants to claim its port
+ * @share: Flag to indicate if the client wants to share the port or not.
+ *
+ * Returns -errno on failure, 0 on success.
+ */
+int hsi_claim_port(struct hsi_client *cl, unsigned int share)
+{
+	struct hsi_port *port = hsi_get_port(cl);
+	int err = 0;
+
+	mutex_lock(&port->lock);
+	if ((port->claimed) && (!port->shared || !share)) {
+		err = -EBUSY;
+		goto out;
+	}
+	if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) {
+		err = -ENODEV;
+		goto out;
+	}
+	port->claimed++;
+	port->shared = !!share;
+	cl->pclaimed = 1;
+out:
+	mutex_unlock(&port->lock);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(hsi_claim_port);
+
+/**
+ * hsi_release_port - Release the HSI client's port
+ * @cl: HSI client which previously claimed its port
+ */
+void hsi_release_port(struct hsi_client *cl)
+{
+	struct hsi_port *port = hsi_get_port(cl);
+
+	mutex_lock(&port->lock);
+	/* Allow HW driver to do some cleanup */
+	port->release(cl);
+	if (cl->pclaimed)
+		port->claimed--;
+	BUG_ON(port->claimed < 0);
+	cl->pclaimed = 0;
+	if (!port->claimed)
+		port->shared = 0;
+	module_put(to_hsi_controller(port->device.parent)->owner);
+	mutex_unlock(&port->lock);
+}
+EXPORT_SYMBOL_GPL(hsi_release_port);
+
+static int hsi_start_rx(struct hsi_client *cl, void *data __maybe_unused)
+{
+	if (cl->hsi_start_rx)
+		(*cl->hsi_start_rx)(cl);
+
+	return 0;
+}
+
+static int hsi_stop_rx(struct hsi_client *cl, void *data __maybe_unused)
+{
+	if (cl->hsi_stop_rx)
+		(*cl->hsi_stop_rx)(cl);
+
+	return 0;
+}
+
+static int hsi_port_for_each_client(struct hsi_port *port, void *data,
+				int (*fn)(struct hsi_client *cl, void *data))
+{
+	struct hsi_client *cl;
+
+	spin_lock(&port->clock);
+	list_for_each_entry(cl, &port->clients, link) {
+		spin_unlock(&port->clock);
+		(*fn)(cl, data);
+		spin_lock(&port->clock);
+	}
+	spin_unlock(&port->clock);
+
+	return 0;
+}
+
+/**
+ * hsi_event -Notifies clients about port events
+ * @port: Port where the event occurred
+ * @event: The event type
+ *
+ * Clients should not be concerned about wake line behavior. However, due
+ * to a race condition in HSI HW protocol, clients need to be notified
+ * about wake line changes, so they can implement a workaround for it.
+ *
+ * Events:
+ * HSI_EVENT_START_RX - Incoming wake line high
+ * HSI_EVENT_STOP_RX - Incoming wake line down
+ */
+void hsi_event(struct hsi_port *port, unsigned int event)
+{
+	int (*fn)(struct hsi_client *cl, void *data);
+
+	switch (event) {
+	case HSI_EVENT_START_RX:
+		fn = hsi_start_rx;
+		break;
+	case HSI_EVENT_STOP_RX:
+		fn = hsi_stop_rx;
+		break;
+	default:
+		return;
+	}
+	hsi_port_for_each_client(port, NULL, fn);
+}
+EXPORT_SYMBOL_GPL(hsi_event);
+
+static int __init hsi_init(void)
+{
+	return bus_register(&hsi_bus_type);
+}
+postcore_initcall(hsi_init);
+
+static void __exit hsi_exit(void)
+{
+	bus_unregister(&hsi_bus_type);
+}
+module_exit(hsi_exit);
+
+MODULE_AUTHOR("Carlos Chinea <carlos.chinea@nokia.com>");
+MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hsi/hsi_boardinfo.c b/drivers/hsi/hsi_boardinfo.c
new file mode 100644
index 0000000..e56bc6d
--- /dev/null
+++ b/drivers/hsi/hsi_boardinfo.c
@@ -0,0 +1,62 @@
+/*
+ * HSI clients registration interface
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <linux/hsi/hsi.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include "hsi_core.h"
+
+/*
+ * hsi_board_list is only used internally by the HSI framework.
+ * No one else is allowed to make use of it.
+ */
+LIST_HEAD(hsi_board_list);
+EXPORT_SYMBOL_GPL(hsi_board_list);
+
+/**
+ * hsi_register_board_info - Register HSI clients information
+ * @info: Array of HSI clients on the board
+ * @len: Length of the array
+ *
+ * HSI clients are statically declared and registered on board files.
+ *
+ * HSI clients will be automatically registered to the HSI bus once the
+ * controller and the port where the clients wishes to attach are registered
+ * to it.
+ *
+ * Return -errno on failure, 0 on success.
+ */
+int __init hsi_register_board_info(struct hsi_board_info const *info,
+							unsigned int len)
+{
+	struct hsi_cl_info *cl_info;
+
+	cl_info = kzalloc(sizeof(*cl_info) * len, GFP_KERNEL);
+	if (!cl_info)
+		return -ENOMEM;
+
+	for (; len; len--, info++, cl_info++) {
+		cl_info->info = *info;
+		list_add_tail(&cl_info->list, &hsi_board_list);
+	}
+
+	return 0;
+}
diff --git a/drivers/hsi/hsi_core.h b/drivers/hsi/hsi_core.h
new file mode 100644
index 0000000..ab5c2fb
--- /dev/null
+++ b/drivers/hsi/hsi_core.h
@@ -0,0 +1,35 @@
+/*
+ * HSI framework internal interfaces,
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __LINUX_HSI_CORE_H__
+#define __LINUX_HSI_CORE_H__
+
+#include <linux/hsi/hsi.h>
+
+struct hsi_cl_info {
+	struct list_head	list;
+	struct hsi_board_info	info;
+};
+
+extern struct list_head hsi_board_list;
+
+#endif /* __LINUX_HSI_CORE_H__ */
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 36484db..9ffbfc5 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -37,81 +37,6 @@ struct vmbus_channel_message_table_entry {
 	void (*message_handler)(struct vmbus_channel_message_header *msg);
 };
 
-#define MAX_MSG_TYPES                    4
-#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
-
-static const uuid_le
-	supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
-	/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
-	/* Storage - SCSI */
-	{
-		.b  = {
-			0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
-			0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
-		}
-	},
-
-	/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
-	/* Network */
-	{
-		.b = {
-			0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
-			0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
-		}
-	},
-
-	/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
-	/* Input */
-	{
-		.b = {
-			0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
-			0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
-		}
-	},
-
-	/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
-	/* IDE */
-	{
-		.b = {
-			0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-			0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
-		}
-	},
-	/* 0E0B6031-5213-4934-818B-38D90CED39DB */
-	/* Shutdown */
-	{
-		.b = {
-			0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
-			0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
-		}
-	},
-	/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
-	/* TimeSync */
-	{
-		.b = {
-			0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
-			0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
-		}
-	},
-	/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
-	/* Heartbeat */
-	{
-		.b = {
-			0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
-			0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
-		}
-	},
-	/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
-	/* KVP */
-	{
-		.b = {
-			0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
-			0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6
-	}
-	},
-
-};
-
 
 /**
  * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
@@ -321,20 +246,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
 	struct vmbus_channel *newchannel;
 	uuid_le *guidtype;
 	uuid_le *guidinstance;
-	int i;
-	int fsupported = 0;
 
 	offer = (struct vmbus_channel_offer_channel *)hdr;
-	for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
-		if (!uuid_le_cmp(offer->offer.if_type,
-				supported_device_classes[i])) {
-			fsupported = 1;
-			break;
-		}
-	}
-
-	if (!fsupported)
-		return;
 
 	guidtype = &offer->offer.if_type;
 	guidinstance = &offer->offer.if_instance;
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 12aa97f..15956bd 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -155,9 +155,9 @@ int hv_init(void)
 	union hv_x64_msr_hypercall_contents hypercall_msr;
 	void *virtaddr = NULL;
 
-	memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS);
+	memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS);
 	memset(hv_context.synic_message_page, 0,
-	       sizeof(void *) * MAX_NUM_CPUS);
+	       sizeof(void *) * NR_CPUS);
 
 	if (!query_hypervisor_presence())
 		goto cleanup;
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 0e8343f..0ef4c1f 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -28,8 +28,6 @@
 #include <linux/workqueue.h>
 #include <linux/hyperv.h>
 
-#include "hv_kvp.h"
-
 
 
 /*
@@ -73,15 +71,20 @@ kvp_register(void)
 {
 
 	struct cn_msg *msg;
+	struct hv_kvp_msg *kvp_msg;
+	char *version;
 
-	msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC);
+	msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg), GFP_ATOMIC);
 
 	if (msg) {
+		kvp_msg = (struct hv_kvp_msg *)msg->data;
+		version = kvp_msg->body.kvp_version;
 		msg->id.idx =  CN_KVP_IDX;
 		msg->id.val = CN_KVP_VAL;
-		msg->seq = KVP_REGISTER;
-		strcpy(msg->data, HV_DRV_VERSION);
-		msg->len = strlen(HV_DRV_VERSION) + 1;
+
+		kvp_msg->kvp_hdr.operation = KVP_OP_REGISTER;
+		strcpy(version, HV_DRV_VERSION);
+		msg->len = sizeof(struct hv_kvp_msg);
 		cn_netlink_send(msg, 0, GFP_ATOMIC);
 		kfree(msg);
 	}
@@ -103,23 +106,24 @@ kvp_work_func(struct work_struct *dummy)
 static void
 kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
-	struct hv_ku_msg *message;
+	struct hv_kvp_msg *message;
+	struct hv_kvp_msg_enumerate *data;
 
-	message = (struct hv_ku_msg *)msg->data;
-	if (msg->seq == KVP_REGISTER) {
+	message = (struct hv_kvp_msg *)msg->data;
+	if (message->kvp_hdr.operation == KVP_OP_REGISTER) {
 		pr_info("KVP: user-mode registering done.\n");
 		kvp_register();
 	}
 
-	if (msg->seq == KVP_USER_SET) {
+	if (message->kvp_hdr.operation == KVP_OP_ENUMERATE) {
+		data = &message->body.kvp_enum_data;
 		/*
 		 * Complete the transaction by forwarding the key value
 		 * to the host. But first, cancel the timeout.
 		 */
 		if (cancel_delayed_work_sync(&kvp_work))
-			kvp_respond_to_host(message->kvp_key,
-						message->kvp_value,
-						!strlen(message->kvp_key));
+			kvp_respond_to_host(data->data.key, data->data.value,
+					!strlen(data->data.key));
 	}
 }
 
@@ -127,6 +131,7 @@ static void
 kvp_send_key(struct work_struct *dummy)
 {
 	struct cn_msg *msg;
+	struct hv_kvp_msg *message;
 	int index = kvp_transaction.index;
 
 	msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
@@ -134,9 +139,11 @@ kvp_send_key(struct work_struct *dummy)
 	if (msg) {
 		msg->id.idx =  CN_KVP_IDX;
 		msg->id.val = CN_KVP_VAL;
-		msg->seq = KVP_KERNEL_GET;
-		((struct hv_ku_msg *)msg->data)->kvp_index = index;
-		msg->len = sizeof(struct hv_ku_msg);
+
+		message = (struct hv_kvp_msg *)msg->data;
+		message->kvp_hdr.operation = KVP_OP_ENUMERATE;
+		message->body.kvp_enum_data.index = index;
+		msg->len = sizeof(struct hv_kvp_msg);
 		cn_netlink_send(msg, 0, GFP_ATOMIC);
 		kfree(msg);
 	}
@@ -193,7 +200,7 @@ kvp_respond_to_host(char *key, char *value, int error)
 	kvp_msg = (struct hv_kvp_msg *)
 			&recv_buffer[sizeof(struct vmbuspipe_hdr) +
 			sizeof(struct icmsg_hdr)];
-	kvp_data = &kvp_msg->kvp_data;
+	kvp_data = &kvp_msg->body.kvp_enum_data;
 	key_name = key;
 
 	/*
@@ -268,7 +275,7 @@ void hv_kvp_onchannelcallback(void *context)
 				sizeof(struct vmbuspipe_hdr) +
 				sizeof(struct icmsg_hdr)];
 
-			kvp_data = &kvp_msg->kvp_data;
+			kvp_data = &kvp_msg->body.kvp_enum_data;
 
 			/*
 			 * We only support the "get" operation on
diff --git a/drivers/hv/hv_kvp.h b/drivers/hv/hv_kvp.h
deleted file mode 100644
index 9b765d7..0000000
--- a/drivers/hv/hv_kvp.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * An implementation of HyperV key value pair (KVP) functionality for Linux.
- *
- *
- * Copyright (C) 2010, Novell, Inc.
- * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#ifndef	_KVP_H
-#define	_KVP_H_
-
-/*
- * Maximum value size - used for both key names and value data, and includes
- * any applicable NULL terminators.
- *
- * Note:  This limit is somewhat arbitrary, but falls easily within what is
- * supported for all native guests (back to Win 2000) and what is reasonable
- * for the IC KVP exchange functionality.  Note that Windows Me/98/95 are
- * limited to 255 character key names.
- *
- * MSDN recommends not storing data values larger than 2048 bytes in the
- * registry.
- *
- * Note:  This value is used in defining the KVP exchange message - this value
- * cannot be modified without affecting the message size and compatibility.
- */
-
-/*
- * bytes, including any null terminators
- */
-#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE          (2048)
-
-
-/*
- * Maximum key size - the registry limit for the length of an entry name
- * is 256 characters, including the null terminator
- */
-
-#define HV_KVP_EXCHANGE_MAX_KEY_SIZE            (512)
-
-/*
- * In Linux, we implement the KVP functionality in two components:
- * 1) The kernel component which is packaged as part of the hv_utils driver
- * is responsible for communicating with the host and responsible for
- * implementing the host/guest protocol. 2) A user level daemon that is
- * responsible for data gathering.
- *
- * Host/Guest Protocol: The host iterates over an index and expects the guest
- * to assign a key name to the index and also return the value corresponding to
- * the key. The host will have atmost one KVP transaction outstanding at any
- * given point in time. The host side iteration stops when the guest returns
- * an error. Microsoft has specified the following mapping of key names to
- * host specified index:
- *
- *	Index		Key Name
- *	0		FullyQualifiedDomainName
- *	1		IntegrationServicesVersion
- *	2		NetworkAddressIPv4
- *	3		NetworkAddressIPv6
- *	4		OSBuildNumber
- *	5		OSName
- *	6		OSMajorVersion
- *	7		OSMinorVersion
- *	8		OSVersion
- *	9		ProcessorArchitecture
- *
- * The Windows host expects the Key Name and Key Value to be encoded in utf16.
- *
- * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the
- * data gathering functionality in a user mode daemon. The user level daemon
- * is also responsible for binding the key name to the index as well. The
- * kernel and user-level daemon communicate using a connector channel.
- *
- * The user mode component first registers with the
- * the kernel component. Subsequently, the kernel component requests, data
- * for the specified keys. In response to this message the user mode component
- * fills in the value corresponding to the specified key. We overload the
- * sequence field in the cn_msg header to define our KVP message types.
- *
- *
- * The kernel component simply acts as a conduit for communication between the
- * Windows host and the user-level daemon. The kernel component passes up the
- * index received from the Host to the user-level daemon. If the index is
- * valid (supported), the corresponding key as well as its
- * value (both are strings) is returned. If the index is invalid
- * (not supported), a NULL key string is returned.
- */
-
-/*
- *
- * The following definitions are shared with the user-mode component; do not
- * change any of this without making the corresponding changes in
- * the KVP user-mode component.
- */
-
-#define CN_KVP_VAL             0x1 /* This supports queries from the kernel */
-#define CN_KVP_USER_VAL       0x2 /* This supports queries from the user */
-
-enum hv_ku_op {
-	KVP_REGISTER = 0, /* Register the user mode component */
-	KVP_KERNEL_GET, /* Kernel is requesting the value */
-	KVP_KERNEL_SET, /* Kernel is providing the value */
-	KVP_USER_GET,  /* User is requesting the value */
-	KVP_USER_SET  /* User is providing the value */
-};
-
-struct hv_ku_msg {
-	__u32 kvp_index; /* Key index */
-	__u8  kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
-	__u8  kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key  value */
-};
-
-
-
-
-#ifdef __KERNEL__
-
-/*
- * Registry value types.
- */
-
-#define REG_SZ 1
-
-enum hv_kvp_exchg_op {
-	KVP_OP_GET = 0,
-	KVP_OP_SET,
-	KVP_OP_DELETE,
-	KVP_OP_ENUMERATE,
-	KVP_OP_COUNT /* Number of operations, must be last. */
-};
-
-enum hv_kvp_exchg_pool {
-	KVP_POOL_EXTERNAL = 0,
-	KVP_POOL_GUEST,
-	KVP_POOL_AUTO,
-	KVP_POOL_AUTO_EXTERNAL,
-	KVP_POOL_AUTO_INTERNAL,
-	KVP_POOL_COUNT /* Number of pools, must be last. */
-};
-
-struct hv_kvp_hdr {
-	u8 operation;
-	u8 pool;
-};
-
-struct hv_kvp_exchg_msg_value {
-	u32 value_type;
-	u32 key_size;
-	u32 value_size;
-	u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
-	u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
-};
-
-struct hv_kvp_msg_enumerate {
-	u32 index;
-	struct hv_kvp_exchg_msg_value data;
-};
-
-struct hv_kvp_msg {
-	struct hv_kvp_hdr	kvp_hdr;
-	struct hv_kvp_msg_enumerate	kvp_data;
-};
-
-int hv_kvp_init(struct hv_util_service *);
-void hv_kvp_deinit(void);
-void hv_kvp_onchannelcallback(void *);
-
-#endif /* __KERNEL__ */
-#endif	/* _KVP_H */
-
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 55d58f2..dbb8b8e 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -28,9 +28,6 @@
 #include <linux/reboot.h>
 #include <linux/hyperv.h>
 
-#include "hv_kvp.h"
-
-
 static void shutdown_onchannelcallback(void *context);
 static struct hv_util_service util_shutdown = {
 	.util_cb = shutdown_onchannelcallback,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 6d7d286..699f0d8 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -457,7 +457,6 @@ static const uuid_le VMBUS_SERVICE_ID = {
 	},
 };
 
-#define MAX_NUM_CPUS	32
 
 
 struct hv_input_signal_event_buffer {
@@ -483,8 +482,8 @@ struct hv_context {
 	/* 8-bytes aligned of the buffer above */
 	struct hv_input_signal_event *signal_event_param;
 
-	void *synic_message_page[MAX_NUM_CPUS];
-	void *synic_event_page[MAX_NUM_CPUS];
+	void *synic_message_page[NR_CPUS];
+	void *synic_event_page[NR_CPUS];
 };
 
 extern struct hv_context hv_context;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 0226040..24d584a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -597,11 +597,11 @@ config SENSORS_LM78
 	  will be called lm78.
 
 config SENSORS_LM80
-	tristate "National Semiconductor LM80"
+	tristate "National Semiconductor LM80 and LM96080"
 	depends on I2C
 	help
 	  If you say yes here you get support for National Semiconductor
-	  LM80 sensor chips.
+	  LM80 and LM96080 sensor chips.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm80.
@@ -647,7 +647,8 @@ config SENSORS_LM90
 	  LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A,
 	  Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659,
 	  MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008,
-	  Winbond/Nuvoton W83L771W/G/AWG/ASG and Philips SA56004 sensor chips.
+	  Winbond/Nuvoton W83L771W/G/AWG/ASG, Philips SA56004, and GMT G781
+	  sensor chips.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm90.
@@ -1226,18 +1227,19 @@ config SENSORS_W83795
 	depends on I2C && EXPERIMENTAL
 	help
 	  If you say yes here you get support for the Winbond W83795G and
-	  W83795ADG hardware monitoring chip.
+	  W83795ADG hardware monitoring chip, including manual fan speed
+	  control.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called w83795.
 
 config SENSORS_W83795_FANCTRL
-	boolean "Include fan control support (DANGEROUS)"
+	boolean "Include automatic fan control support (DANGEROUS)"
 	depends on SENSORS_W83795 && EXPERIMENTAL
 	default n
 	help
-	  If you say yes here, support for the both manual and automatic
-	  fan control features will be included in the driver.
+	  If you say yes here, support for automatic fan speed control
+	  will be included in the driver.
 
 	  This part of the code wasn't carefully reviewed and tested yet,
 	  so enabling this option is strongly discouraged on production
@@ -1355,10 +1357,10 @@ config SENSORS_APPLESMC
 	  the awesome power of applesmc.
 
 config SENSORS_MC13783_ADC
-        tristate "Freescale MC13783 ADC"
-        depends on MFD_MC13783
+        tristate "Freescale MC13783/MC13892 ADC"
+        depends on MFD_MC13XXX
         help
-          Support for the A/D converter on MC13783 PMIC.
+          Support for the A/D converter on MC13783 and MC13892 PMIC.
 
 if ACPI
 
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 3b728e8..a72bf25 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -1,25 +1,25 @@
 /*
-    abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.
-*/
+ * abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 supports the sensor part of the first and second revision of
-    the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because
-    of lack of specs the CPU/RAM voltage & frequency control is not supported!
-*/
+ * This driver supports the sensor part of the first and second revision of
+ * the custom Abit uGuru chip found on Abit uGuru motherboards. Note: because
+ * of lack of specs the CPU/RAM voltage & frequency control is not supported!
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -44,8 +44,10 @@
 #define ABIT_UGURU_SENSOR_BANK2			0x26 /* fans */
 /* max nr of sensors in bank1, a bank1 sensor can be in, temp or nc */
 #define ABIT_UGURU_MAX_BANK1_SENSORS		16
-/* Warning if you increase one of the 2 MAX defines below to 10 or higher you
-   should adjust the belonging _NAMES_LENGTH macro for the 2 digit number! */
+/*
+ * Warning if you increase one of the 2 MAX defines below to 10 or higher you
+ * should adjust the belonging _NAMES_LENGTH macro for the 2 digit number!
+ */
 /* max nr of sensors in bank2, currently mb's with max 6 fans are known */
 #define ABIT_UGURU_MAX_BANK2_SENSORS		6
 /* max nr of pwm outputs, currently mb's with max 5 pwm outputs are known */
@@ -70,16 +72,22 @@
 #define ABIT_UGURU_IN_SENSOR			0
 #define ABIT_UGURU_TEMP_SENSOR			1
 #define ABIT_UGURU_NC				2
-/* In many cases we need to wait for the uGuru to reach a certain status, most
-   of the time it will reach this status within 30 - 90 ISA reads, and thus we
-   can best busy wait. This define gives the total amount of reads to try. */
+/*
+ * In many cases we need to wait for the uGuru to reach a certain status, most
+ * of the time it will reach this status within 30 - 90 ISA reads, and thus we
+ * can best busy wait. This define gives the total amount of reads to try.
+ */
 #define ABIT_UGURU_WAIT_TIMEOUT			125
-/* However sometimes older versions of the uGuru seem to be distracted and they
-   do not respond for a long time. To handle this we sleep before each of the
-   last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. */
+/*
+ * However sometimes older versions of the uGuru seem to be distracted and they
+ * do not respond for a long time. To handle this we sleep before each of the
+ * last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries.
+ */
 #define ABIT_UGURU_WAIT_TIMEOUT_SLEEP		5
-/* Normally all expected status in abituguru_ready, are reported after the
-   first read, but sometimes not and we need to poll. */
+/*
+ * Normally all expected status in abituguru_ready, are reported after the
+ * first read, but sometimes not and we need to poll.
+ */
 #define ABIT_UGURU_READY_TIMEOUT		5
 /* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */
 #define ABIT_UGURU_MAX_RETRIES			3
@@ -92,17 +100,25 @@
 	if (level <= verbose)						\
 		printk(KERN_DEBUG ABIT_UGURU_NAME ": "	format , ## arg)
 /* Macros to help calculate the sysfs_names array length */
-/* sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
-   in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0 */
+/*
+ * sum of strlen of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
+ * in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0
+ */
 #define ABITUGURU_IN_NAMES_LENGTH	(11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14)
-/* sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0,
-   temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0 */
+/*
+ * sum of strlen of: temp??_input\0, temp??_max\0, temp??_crit\0,
+ * temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0
+ */
 #define ABITUGURU_TEMP_NAMES_LENGTH	(13 + 11 + 12 + 13 + 20 + 12 + 16)
-/* sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0,
-   fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0 */
+/*
+ * sum of strlen of: fan?_input\0, fan?_min\0, fan?_alarm\0,
+ * fan?_alarm_enable\0, fan?_beep\0, fan?_shutdown\0
+ */
 #define ABITUGURU_FAN_NAMES_LENGTH	(11 + 9 + 11 + 18 + 10 + 14)
-/* sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0,
-   pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0 */
+/*
+ * sum of strlen of: pwm?_enable\0, pwm?_auto_channels_temp\0,
+ * pwm?_auto_point{1,2}_pwm\0, pwm?_auto_point{1,2}_temp\0
+ */
 #define ABITUGURU_PWM_NAMES_LENGTH	(12 + 24 + 2 * 21 + 2 * 22)
 /* IN_NAMES_LENGTH > TEMP_NAMES_LENGTH so assume all bank1 sensors are in */
 #define ABITUGURU_SYSFS_NAMES_LENGTH	( \
@@ -110,10 +126,12 @@
 	ABIT_UGURU_MAX_BANK2_SENSORS * ABITUGURU_FAN_NAMES_LENGTH + \
 	ABIT_UGURU_MAX_PWMS * ABITUGURU_PWM_NAMES_LENGTH)
 
-/* All the macros below are named identical to the oguru and oguru2 programs
-   reverse engineered by Olle Sandberg, hence the names might not be 100%
-   logical. I could come up with better names, but I prefer keeping the names
-   identical so that this driver can be compared with his work more easily. */
+/*
+ * All the macros below are named identical to the oguru and oguru2 programs
+ * reverse engineered by Olle Sandberg, hence the names might not be 100%
+ * logical. I could come up with better names, but I prefer keeping the names
+ * identical so that this driver can be compared with his work more easily.
+ */
 /* Two i/o-ports are used by uGuru */
 #define ABIT_UGURU_BASE				0x00E0
 /* Used to tell uGuru what to read and to read the actual data */
@@ -130,16 +148,22 @@
 /* Constants */
 /* in (Volt) sensors go up to 3494 mV, temp to 255000 millidegrees Celsius */
 static const int abituguru_bank1_max_value[2] = { 3494, 255000 };
-/* Min / Max allowed values for sensor2 (fan) alarm threshold, these values
-   correspond to 300-3000 RPM */
+/*
+ * Min / Max allowed values for sensor2 (fan) alarm threshold, these values
+ * correspond to 300-3000 RPM
+ */
 static const u8 abituguru_bank2_min_threshold = 5;
 static const u8 abituguru_bank2_max_threshold = 50;
-/* Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4
-   are temperature trip points. */
+/*
+ * Register 0 is a bitfield, 1 and 2 are pwm settings (255 = 100%), 3 and 4
+ * are temperature trip points.
+ */
 static const int abituguru_pwm_settings_multiplier[5] = { 0, 1, 1, 1000, 1000 };
-/* Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a
-   special case the minium allowed pwm% setting for this is 30% (77) on
-   some MB's this special case is handled in the code! */
+/*
+ * Min / Max allowed values for pwm_settings. Note: pwm1 (CPU fan) is a
+ * special case the minium allowed pwm% setting for this is 30% (77) on
+ * some MB's this special case is handled in the code!
+ */
 static const u8 abituguru_pwm_min[5] = { 0, 170, 170, 25, 25 };
 static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 };
 
@@ -175,23 +199,29 @@ MODULE_PARM_DESC(verbose, "How verbose should the driver be? (0-3):\n"
 	"   3 + retryable error reporting");
 
 
-/* For the Abit uGuru, we need to keep some data in memory.
-   The structure is dynamically allocated, at the same time when a new
-   abituguru device is allocated. */
+/*
+ * For the Abit uGuru, we need to keep some data in memory.
+ * The structure is dynamically allocated, at the same time when a new
+ * abituguru device is allocated.
+ */
 struct abituguru_data {
 	struct device *hwmon_dev;	/* hwmon registered device */
 	struct mutex update_lock;	/* protect access to data and uGuru */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned short addr;		/* uguru base address */
 	char uguru_ready;		/* is the uguru in ready state? */
-	unsigned char update_timeouts;	/* number of update timeouts since last
-					   successful update */
-
-	/* The sysfs attr and their names are generated automatically, for bank1
-	   we cannot use a predefined array because we don't know beforehand
-	   of a sensor is a volt or a temp sensor, for bank2 and the pwms its
-	   easier todo things the same way.  For in sensors we have 9 (temp 7)
-	   sysfs entries per sensor, for bank2 and pwms 6. */
+	unsigned char update_timeouts;	/*
+					 * number of update timeouts since last
+					 * successful update
+					 */
+
+	/*
+	 * The sysfs attr and their names are generated automatically, for bank1
+	 * we cannot use a predefined array because we don't know beforehand
+	 * of a sensor is a volt or a temp sensor, for bank2 and the pwms its
+	 * easier todo things the same way.  For in sensors we have 9 (temp 7)
+	 * sysfs entries per sensor, for bank2 and pwms 6.
+	 */
 	struct sensor_device_attribute_2 sysfs_attr[
 		ABIT_UGURU_MAX_BANK1_SENSORS * 9 +
 		ABIT_UGURU_MAX_BANK2_SENSORS * 6 + ABIT_UGURU_MAX_PWMS * 6];
@@ -203,11 +233,15 @@ struct abituguru_data {
 	u8 bank1_sensors[2];
 	u8 bank1_address[2][ABIT_UGURU_MAX_BANK1_SENSORS];
 	u8 bank1_value[ABIT_UGURU_MAX_BANK1_SENSORS];
-	/* This array holds 3 entries per sensor for the bank 1 sensor settings
-	   (flags, min, max for voltage / flags, warn, shutdown for temp). */
+	/*
+	 * This array holds 3 entries per sensor for the bank 1 sensor settings
+	 * (flags, min, max for voltage / flags, warn, shutdown for temp).
+	 */
 	u8 bank1_settings[ABIT_UGURU_MAX_BANK1_SENSORS][3];
-	/* Maximum value for each sensor used for scaling in mV/millidegrees
-	   Celsius. */
+	/*
+	 * Maximum value for each sensor used for scaling in mV/millidegrees
+	 * Celsius.
+	 */
 	int bank1_max_value[ABIT_UGURU_MAX_BANK1_SENSORS];
 
 	/* Bank 2 data, ABIT_UGURU_MAX_BANK2_SENSORS entries for bank2 */
@@ -236,8 +270,10 @@ static int abituguru_wait(struct abituguru_data *data, u8 state)
 		timeout--;
 		if (timeout == 0)
 			return -EBUSY;
-		/* sleep a bit before our last few tries, see the comment on
-		   this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. */
+		/*
+		 * sleep a bit before our last few tries, see the comment on
+		 * this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined.
+		 */
 		if (timeout <= ABIT_UGURU_WAIT_TIMEOUT_SLEEP)
 			msleep(0);
 	}
@@ -273,8 +309,10 @@ static int abituguru_ready(struct abituguru_data *data)
 		msleep(0);
 	}
 
-	/* After this the ABIT_UGURU_DATA port should contain
-	   ABIT_UGURU_STATUS_INPUT */
+	/*
+	 * After this the ABIT_UGURU_DATA port should contain
+	 * ABIT_UGURU_STATUS_INPUT
+	 */
 	timeout = ABIT_UGURU_READY_TIMEOUT;
 	while (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT) {
 		timeout--;
@@ -290,27 +328,35 @@ static int abituguru_ready(struct abituguru_data *data)
 	return 0;
 }
 
-/* Send the bank and then sensor address to the uGuru for the next read/write
-   cycle. This function gets called as the first part of a read/write by
-   abituguru_read and abituguru_write. This function should never be
-   called by any other function. */
+/*
+ * Send the bank and then sensor address to the uGuru for the next read/write
+ * cycle. This function gets called as the first part of a read/write by
+ * abituguru_read and abituguru_write. This function should never be
+ * called by any other function.
+ */
 static int abituguru_send_address(struct abituguru_data *data,
 	u8 bank_addr, u8 sensor_addr, int retries)
 {
-	/* assume the caller does error handling itself if it has not requested
-	   any retries, and thus be quiet. */
+	/*
+	 * assume the caller does error handling itself if it has not requested
+	 * any retries, and thus be quiet.
+	 */
 	int report_errors = retries;
 
 	for (;;) {
-		/* Make sure the uguru is ready and then send the bank address,
-		   after this the uguru is no longer "ready". */
+		/*
+		 * Make sure the uguru is ready and then send the bank address,
+		 * after this the uguru is no longer "ready".
+		 */
 		if (abituguru_ready(data) != 0)
 			return -EIO;
 		outb(bank_addr, data->addr + ABIT_UGURU_DATA);
 		data->uguru_ready = 0;
 
-		/* Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again
-		   and send the sensor addr */
+		/*
+		 * Wait till the uguru is ABIT_UGURU_STATUS_INPUT state again
+		 * and send the sensor addr
+		 */
 		if (abituguru_wait(data, ABIT_UGURU_STATUS_INPUT)) {
 			if (retries) {
 				ABIT_UGURU_DEBUG(3, "timeout exceeded "
@@ -332,8 +378,10 @@ static int abituguru_send_address(struct abituguru_data *data,
 	}
 }
 
-/* Read count bytes from sensor sensor_addr in bank bank_addr and store the
-   result in buf, retry the send address part of the read retries times. */
+/*
+ * Read count bytes from sensor sensor_addr in bank bank_addr and store the
+ * result in buf, retry the send address part of the read retries times.
+ */
 static int abituguru_read(struct abituguru_data *data,
 	u8 bank_addr, u8 sensor_addr, u8 *buf, int count, int retries)
 {
@@ -362,13 +410,17 @@ static int abituguru_read(struct abituguru_data *data,
 	return i;
 }
 
-/* Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send
-   address part of the write is always retried ABIT_UGURU_MAX_RETRIES times. */
+/*
+ * Write count bytes from buf to sensor sensor_addr in bank bank_addr, the send
+ * address part of the write is always retried ABIT_UGURU_MAX_RETRIES times.
+ */
 static int abituguru_write(struct abituguru_data *data,
 	u8 bank_addr, u8 sensor_addr, u8 *buf, int count)
 {
-	/* We use the ready timeout as we have to wait for 0xAC just like the
-	   ready function */
+	/*
+	 * We use the ready timeout as we have to wait for 0xAC just like the
+	 * ready function
+	 */
 	int i, timeout = ABIT_UGURU_READY_TIMEOUT;
 
 	/* Send the address */
@@ -388,9 +440,11 @@ static int abituguru_write(struct abituguru_data *data,
 		outb(buf[i], data->addr + ABIT_UGURU_CMD);
 	}
 
-	/* Now we need to wait till the chip is ready to be read again,
-	   so that we can read 0xAC as confirmation that our write has
-	   succeeded. */
+	/*
+	 * Now we need to wait till the chip is ready to be read again,
+	 * so that we can read 0xAC as confirmation that our write has
+	 * succeeded.
+	 */
 	if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
 		ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state "
 			"after write (bank: %d, sensor: %d)\n", (int)bank_addr,
@@ -416,12 +470,14 @@ static int abituguru_write(struct abituguru_data *data,
 	return i;
 }
 
-/* Detect sensor type. Temp and Volt sensors are enabled with
-   different masks and will ignore enable masks not meant for them.
-   This enables us to test what kind of sensor we're dealing with.
-   By setting the alarm thresholds so that we will always get an
-   alarm for sensor type X and then enabling the sensor as sensor type
-   X, if we then get an alarm it is a sensor of type X. */
+/*
+ * Detect sensor type. Temp and Volt sensors are enabled with
+ * different masks and will ignore enable masks not meant for them.
+ * This enables us to test what kind of sensor we're dealing with.
+ * By setting the alarm thresholds so that we will always get an
+ * alarm for sensor type X and then enabling the sensor as sensor type
+ * X, if we then get an alarm it is a sensor of type X.
+ */
 static int __devinit
 abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
 				   u8 sensor_addr)
@@ -448,16 +504,20 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
 		pr_warn("bank1-sensor: %d reading (%d) too close to limits, "
 			"unable to determine sensor type, skipping sensor\n",
 			(int)sensor_addr, (int)val);
-		/* assume no sensor is there for sensors for which we can't
-		   determine the sensor type because their reading is too close
-		   to their limits, this usually means no sensor is there. */
+		/*
+		 * assume no sensor is there for sensors for which we can't
+		 * determine the sensor type because their reading is too close
+		 * to their limits, this usually means no sensor is there.
+		 */
 		return ABIT_UGURU_NC;
 	}
 
 	ABIT_UGURU_DEBUG(2, "testing bank1 sensor %d\n", (int)sensor_addr);
-	/* Volt sensor test, enable volt low alarm, set min value ridicously
-	   high, or vica versa if the reading is very high. If its a volt
-	   sensor this should always give us an alarm. */
+	/*
+	 * Volt sensor test, enable volt low alarm, set min value ridicously
+	 * high, or vica versa if the reading is very high. If its a volt
+	 * sensor this should always give us an alarm.
+	 */
 	if (val <= 240u) {
 		buf[0] = ABIT_UGURU_VOLT_LOW_ALARM_ENABLE;
 		buf[1] = 245;
@@ -473,8 +533,10 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
 	if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
 			buf, 3) != 3)
 		goto abituguru_detect_bank1_sensor_type_exit;
-	/* Now we need 20 ms to give the uguru time to read the sensors
-	   and raise a voltage alarm */
+	/*
+	 * Now we need 20 ms to give the uguru time to read the sensors
+	 * and raise a voltage alarm
+	 */
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(HZ/50);
 	/* Check for alarm and check the alarm is a volt low alarm. */
@@ -497,17 +559,21 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
 		ABIT_UGURU_DEBUG(2, "  alarm not raised during volt sensor "
 			"test\n");
 
-	/* Temp sensor test, enable sensor as a temp sensor, set beep value
-	   ridicously low (but not too low, otherwise uguru ignores it).
-	   If its a temp sensor this should always give us an alarm. */
+	/*
+	 * Temp sensor test, enable sensor as a temp sensor, set beep value
+	 * ridicously low (but not too low, otherwise uguru ignores it).
+	 * If its a temp sensor this should always give us an alarm.
+	 */
 	buf[0] = ABIT_UGURU_TEMP_HIGH_ALARM_ENABLE;
 	buf[1] = 5;
 	buf[2] = 10;
 	if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
 			buf, 3) != 3)
 		goto abituguru_detect_bank1_sensor_type_exit;
-	/* Now we need 50 ms to give the uguru time to read the sensors
-	   and raise a temp alarm */
+	/*
+	 * Now we need 50 ms to give the uguru time to read the sensors
+	 * and raise a temp alarm
+	 */
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(HZ/20);
 	/* Check for alarm and check the alarm is a temp high alarm. */
@@ -532,9 +598,11 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
 
 	ret = ABIT_UGURU_NC;
 abituguru_detect_bank1_sensor_type_exit:
-	/* Restore original settings, failing here is really BAD, it has been
-	   reported that some BIOS-es hang when entering the uGuru menu with
-	   invalid settings present in the uGuru, so we try this 3 times. */
+	/*
+	 * Restore original settings, failing here is really BAD, it has been
+	 * reported that some BIOS-es hang when entering the uGuru menu with
+	 * invalid settings present in the uGuru, so we try this 3 times.
+	 */
 	for (i = 0; i < 3; i++)
 		if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2,
 				sensor_addr, data->bank1_settings[sensor_addr],
@@ -548,23 +616,25 @@ abituguru_detect_bank1_sensor_type_exit:
 	return ret;
 }
 
-/* These functions try to find out how many sensors there are in bank2 and how
-   many pwms there are. The purpose of this is to make sure that we don't give
-   the user the possibility to change settings for non-existent sensors / pwm.
-   The uGuru will happily read / write whatever memory happens to be after the
-   memory storing the PWM settings when reading/writing to a PWM which is not
-   there. Notice even if we detect a PWM which doesn't exist we normally won't
-   write to it, unless the user tries to change the settings.
-
-   Although the uGuru allows reading (settings) from non existing bank2
-   sensors, my version of the uGuru does seem to stop writing to them, the
-   write function above aborts in this case with:
-   "CMD reg does not hold 0xAC after write"
-
-   Notice these 2 tests are non destructive iow read-only tests, otherwise
-   they would defeat their purpose. Although for the bank2_sensors detection a
-   read/write test would be feasible because of the reaction above, I've
-   however opted to stay on the safe side. */
+/*
+ * These functions try to find out how many sensors there are in bank2 and how
+ * many pwms there are. The purpose of this is to make sure that we don't give
+ * the user the possibility to change settings for non-existent sensors / pwm.
+ * The uGuru will happily read / write whatever memory happens to be after the
+ * memory storing the PWM settings when reading/writing to a PWM which is not
+ * there. Notice even if we detect a PWM which doesn't exist we normally won't
+ * write to it, unless the user tries to change the settings.
+ *
+ * Although the uGuru allows reading (settings) from non existing bank2
+ * sensors, my version of the uGuru does seem to stop writing to them, the
+ * write function above aborts in this case with:
+ * "CMD reg does not hold 0xAC after write"
+ *
+ * Notice these 2 tests are non destructive iow read-only tests, otherwise
+ * they would defeat their purpose. Although for the bank2_sensors detection a
+ * read/write test would be feasible because of the reaction above, I've
+ * however opted to stay on the safe side.
+ */
 static void __devinit
 abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
 {
@@ -580,12 +650,14 @@ abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
 
 	ABIT_UGURU_DEBUG(2, "detecting number of fan sensors\n");
 	for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) {
-		/* 0x89 are the known used bits:
-		   -0x80 enable shutdown
-		   -0x08 enable beep
-		   -0x01 enable alarm
-		   All other bits should be 0, but on some motherboards
-		   0x40 (bit 6) is also high for some of the fans?? */
+		/*
+		 * 0x89 are the known used bits:
+		 * -0x80 enable shutdown
+		 * -0x08 enable beep
+		 * -0x01 enable alarm
+		 * All other bits should be 0, but on some motherboards
+		 * 0x40 (bit 6) is also high for some of the fans??
+		 */
 		if (data->bank2_settings[i][0] & ~0xC9) {
 			ABIT_UGURU_DEBUG(2, "  bank2 sensor %d does not seem "
 				"to be a fan sensor: settings[0] = %02X\n",
@@ -633,9 +705,11 @@ abituguru_detect_no_pwms(struct abituguru_data *data)
 
 	ABIT_UGURU_DEBUG(2, "detecting number of PWM outputs\n");
 	for (i = 0; i < ABIT_UGURU_MAX_PWMS; i++) {
-		/* 0x80 is the enable bit and the low
-		   nibble is which temp sensor to use,
-		   the other bits should be 0 */
+		/*
+		 * 0x80 is the enable bit and the low
+		 * nibble is which temp sensor to use,
+		 * the other bits should be 0
+		 */
 		if (data->pwm_settings[i][0] & ~0x8F) {
 			ABIT_UGURU_DEBUG(2, "  pwm channel %d does not seem "
 				"to be a pwm channel: settings[0] = %02X\n",
@@ -643,8 +717,10 @@ abituguru_detect_no_pwms(struct abituguru_data *data)
 			break;
 		}
 
-		/* the low nibble must correspond to one of the temp sensors
-		   we've found */
+		/*
+		 * the low nibble must correspond to one of the temp sensors
+		 * we've found
+		 */
 		for (j = 0; j < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR];
 				j++) {
 			if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][j] ==
@@ -711,9 +787,11 @@ abituguru_detect_no_pwms_exit:
 	ABIT_UGURU_DEBUG(2, " found: %d PWM outputs\n", (int)data->pwms);
 }
 
-/* Following are the sysfs callback functions. These functions expect:
-   sensor_device_attribute_2->index:   sensor address/offset in the bank
-   sensor_device_attribute_2->nr:      register offset, bitmask or NA. */
+/*
+ * Following are the sysfs callback functions. These functions expect:
+ * sensor_device_attribute_2->index:   sensor address/offset in the bank
+ * sensor_device_attribute_2->nr:      register offset, bitmask or NA.
+ */
 static struct abituguru_data *abituguru_update_device(struct device *dev);
 
 static ssize_t show_bank1_value(struct device *dev,
@@ -763,10 +841,18 @@ static ssize_t store_bank1_setting(struct device *dev, struct device_attribute
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	u8 val = (simple_strtoul(buf, NULL, 10) * 255 +
-		data->bank1_max_value[attr->index]/2) /
+	unsigned long val;
+	ssize_t ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	ret = count;
+	val = (val * 255 + data->bank1_max_value[attr->index] / 2) /
 		data->bank1_max_value[attr->index];
-	ssize_t ret = count;
+	if (val > 255)
+		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
 	if (data->bank1_settings[attr->index][attr->nr] != val) {
@@ -788,13 +874,19 @@ static ssize_t store_bank2_setting(struct device *dev, struct device_attribute
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	u8 val = (simple_strtoul(buf, NULL, 10)*255 + ABIT_UGURU_FAN_MAX/2) /
-		ABIT_UGURU_FAN_MAX;
-	ssize_t ret = count;
+	unsigned long val;
+	ssize_t ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	ret = count;
+	val = (val * 255 + ABIT_UGURU_FAN_MAX / 2) / ABIT_UGURU_FAN_MAX;
 
 	/* this check can be done before taking the lock */
-	if ((val < abituguru_bank2_min_threshold) ||
-			(val > abituguru_bank2_max_threshold))
+	if (val < abituguru_bank2_min_threshold ||
+			val > abituguru_bank2_max_threshold)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -819,11 +911,13 @@ static ssize_t show_bank1_alarm(struct device *dev,
 	struct abituguru_data *data = abituguru_update_device(dev);
 	if (!data)
 		return -EIO;
-	/* See if the alarm bit for this sensor is set, and if the
-	   alarm matches the type of alarm we're looking for (for volt
-	   it can be either low or high). The type is stored in a few
-	   readonly bits in the settings part of the relevant sensor.
-	   The bitmask of the type is passed to us in attr->nr. */
+	/*
+	 * See if the alarm bit for this sensor is set, and if the
+	 * alarm matches the type of alarm we're looking for (for volt
+	 * it can be either low or high). The type is stored in a few
+	 * readonly bits in the settings part of the relevant sensor.
+	 * The bitmask of the type is passed to us in attr->nr.
+	 */
 	if ((data->alarms[attr->index / 8] & (0x01 << (attr->index % 8))) &&
 			(data->bank1_settings[attr->index][0] & attr->nr))
 		return sprintf(buf, "1\n");
@@ -871,10 +965,15 @@ static ssize_t store_bank1_mask(struct device *dev,
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	int mask = simple_strtoul(buf, NULL, 10);
-	ssize_t ret = count;
+	ssize_t ret;
 	u8 orig_val;
+	unsigned long mask;
+
+	ret = kstrtoul(buf, 10, &mask);
+	if (ret)
+		return ret;
 
+	ret = count;
 	mutex_lock(&data->update_lock);
 	orig_val = data->bank1_settings[attr->index][0];
 
@@ -899,10 +998,15 @@ static ssize_t store_bank2_mask(struct device *dev,
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	int mask = simple_strtoul(buf, NULL, 10);
-	ssize_t ret = count;
+	ssize_t ret;
 	u8 orig_val;
+	unsigned long mask;
 
+	ret = kstrtoul(buf, 10, &mask);
+	if (ret)
+		return ret;
+
+	ret = count;
 	mutex_lock(&data->update_lock);
 	orig_val = data->bank2_settings[attr->index][0];
 
@@ -937,10 +1041,17 @@ static ssize_t store_pwm_setting(struct device *dev, struct device_attribute
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	u8 min, val = (simple_strtoul(buf, NULL, 10) +
-		abituguru_pwm_settings_multiplier[attr->nr]/2) /
-		abituguru_pwm_settings_multiplier[attr->nr];
-	ssize_t ret = count;
+	u8 min;
+	unsigned long val;
+	ssize_t ret;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	ret = count;
+	val = (val + abituguru_pwm_settings_multiplier[attr->nr] / 2) /
+				abituguru_pwm_settings_multiplier[attr->nr];
 
 	/* special case pwm1 min pwm% */
 	if ((attr->index == 0) && ((attr->nr == 1) || (attr->nr == 2)))
@@ -949,7 +1060,7 @@ static ssize_t store_pwm_setting(struct device *dev, struct device_attribute
 		min = abituguru_pwm_min[attr->nr];
 
 	/* this check can be done before taking the lock */
-	if ((val < min) || (val > abituguru_pwm_max[attr->nr]))
+	if (val < min || val > abituguru_pwm_max[attr->nr])
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -981,8 +1092,10 @@ static ssize_t show_pwm_sensor(struct device *dev,
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
 	int i;
-	/* We need to walk to the temp sensor addresses to find what
-	   the userspace id of the configured temp sensor is. */
+	/*
+	 * We need to walk to the temp sensor addresses to find what
+	 * the userspace id of the configured temp sensor is.
+	 */
 	for (i = 0; i < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]; i++)
 		if (data->bank1_address[ABIT_UGURU_TEMP_SENSOR][i] ==
 				(data->pwm_settings[attr->index][0] & 0x0F))
@@ -996,27 +1109,32 @@ static ssize_t store_pwm_sensor(struct device *dev, struct device_attribute
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10) - 1;
-	ssize_t ret = count;
+	ssize_t ret;
+	unsigned long val;
+	u8 orig_val;
+	u8 address;
+
+	ret = kstrtoul(buf, 10, &val);
+	if (ret)
+		return ret;
 
+	if (val == 0 || val > data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR])
+		return -EINVAL;
+
+	val -= 1;
+	ret = count;
 	mutex_lock(&data->update_lock);
-	if (val < data->bank1_sensors[ABIT_UGURU_TEMP_SENSOR]) {
-		u8 orig_val = data->pwm_settings[attr->index][0];
-		u8 address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val];
-		data->pwm_settings[attr->index][0] &= 0xF0;
-		data->pwm_settings[attr->index][0] |= address;
-		if (data->pwm_settings[attr->index][0] != orig_val) {
-			if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1,
-					attr->index,
-					data->pwm_settings[attr->index],
-					5) < 1) {
-				data->pwm_settings[attr->index][0] = orig_val;
-				ret = -EIO;
-			}
+	orig_val = data->pwm_settings[attr->index][0];
+	address = data->bank1_address[ABIT_UGURU_TEMP_SENSOR][val];
+	data->pwm_settings[attr->index][0] &= 0xF0;
+	data->pwm_settings[attr->index][0] |= address;
+	if (data->pwm_settings[attr->index][0] != orig_val) {
+		if (abituguru_write(data, ABIT_UGURU_FAN_PWM + 1, attr->index,
+				    data->pwm_settings[attr->index], 5) < 1) {
+			data->pwm_settings[attr->index][0] = orig_val;
+			ret = -EIO;
 		}
 	}
-	else
-		ret = -EINVAL;
 	mutex_unlock(&data->update_lock);
 	return ret;
 }
@@ -1037,22 +1155,27 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
 {
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct abituguru_data *data = dev_get_drvdata(dev);
-	u8 orig_val, user_val = simple_strtoul(buf, NULL, 10);
-	ssize_t ret = count;
+	u8 orig_val;
+	ssize_t ret;
+	unsigned long user_val;
+
+	ret = kstrtoul(buf, 10, &user_val);
+	if (ret)
+		return ret;
 
+	ret = count;
 	mutex_lock(&data->update_lock);
 	orig_val = data->pwm_settings[attr->index][0];
 	switch (user_val) {
-		case 0:
-			data->pwm_settings[attr->index][0] &=
-				~ABIT_UGURU_FAN_PWM_ENABLE;
-			break;
-		case 2:
-			data->pwm_settings[attr->index][0] |=
-				ABIT_UGURU_FAN_PWM_ENABLE;
-			break;
-		default:
-			ret = -EINVAL;
+	case 0:
+		data->pwm_settings[attr->index][0] &=
+			~ABIT_UGURU_FAN_PWM_ENABLE;
+		break;
+	case 2:
+		data->pwm_settings[attr->index][0] |= ABIT_UGURU_FAN_PWM_ENABLE;
+		break;
+	default:
+		ret = -EINVAL;
 	}
 	if ((data->pwm_settings[attr->index][0] != orig_val) &&
 			(abituguru_write(data, ABIT_UGURU_FAN_PWM + 1,
@@ -1147,13 +1270,16 @@ static int __devinit abituguru_probe(struct platform_device *pdev)
 	int i, j, used, sysfs_names_free, sysfs_attr_i, res = -ENODEV;
 	char *sysfs_filename;
 
-	/* El weirdo probe order, to keep the sysfs order identical to the
-	   BIOS and window-appliction listing order. */
+	/*
+	 * El weirdo probe order, to keep the sysfs order identical to the
+	 * BIOS and window-appliction listing order.
+	 */
 	const u8 probe_order[ABIT_UGURU_MAX_BANK1_SENSORS] = {
 		0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02,
 		0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C };
 
-	if (!(data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL)))
+	data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL);
+	if (!data)
 		return -ENOMEM;
 
 	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
@@ -1164,9 +1290,11 @@ static int __devinit abituguru_probe(struct platform_device *pdev)
 	if (inb_p(data->addr + ABIT_UGURU_DATA) == ABIT_UGURU_STATUS_INPUT)
 		data->uguru_ready = 1;
 
-	/* Completely read the uGuru this has 2 purposes:
-	   - testread / see if one really is there.
-	   - make an in memory copy of all the uguru settings for future use. */
+	/*
+	 * Completely read the uGuru this has 2 purposes:
+	 * - testread / see if one really is there.
+	 * - make an in memory copy of all the uguru settings for future use.
+	 */
 	if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
 			data->alarms, 3, ABIT_UGURU_MAX_RETRIES) != 3)
 		goto abituguru_probe_error;
@@ -1181,11 +1309,13 @@ static int __devinit abituguru_probe(struct platform_device *pdev)
 				ABIT_UGURU_MAX_RETRIES) != 3)
 			goto abituguru_probe_error;
 	}
-	/* Note: We don't know how many bank2 sensors / pwms there really are,
-	   but in order to "detect" this we need to read the maximum amount
-	   anyways. If we read sensors/pwms not there we'll just read crap
-	   this can't hurt. We need the detection because we don't want
-	   unwanted writes, which will hurt! */
+	/*
+	 * Note: We don't know how many bank2 sensors / pwms there really are,
+	 * but in order to "detect" this we need to read the maximum amount
+	 * anyways. If we read sensors/pwms not there we'll just read crap
+	 * this can't hurt. We need the detection because we don't want
+	 * unwanted writes, which will hurt!
+	 */
 	for (i = 0; i < ABIT_UGURU_MAX_BANK2_SENSORS; i++) {
 		if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i,
 				&data->bank2_value[i], 1,
@@ -1332,24 +1462,26 @@ static struct abituguru_data *abituguru_update_device(struct device *dev)
 	mutex_lock(&data->update_lock);
 	if (time_after(jiffies, data->last_updated + HZ)) {
 		success = 0;
-		if ((err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
-				data->alarms, 3, 0)) != 3)
+		err = abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0,
+				     data->alarms, 3, 0);
+		if (err != 3)
 			goto LEAVE_UPDATE;
 		for (i = 0; i < ABIT_UGURU_MAX_BANK1_SENSORS; i++) {
-			if ((err = abituguru_read(data,
-					ABIT_UGURU_SENSOR_BANK1, i,
-					&data->bank1_value[i], 1, 0)) != 1)
+			err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1,
+					     i, &data->bank1_value[i], 1, 0);
+			if (err != 1)
 				goto LEAVE_UPDATE;
-			if ((err = abituguru_read(data,
-					ABIT_UGURU_SENSOR_BANK1 + 1, i,
-					data->bank1_settings[i], 3, 0)) != 3)
+			err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1,
+					     i, data->bank1_settings[i], 3, 0);
+			if (err != 3)
 				goto LEAVE_UPDATE;
 		}
-		for (i = 0; i < data->bank2_sensors; i++)
-			if ((err = abituguru_read(data,
-					ABIT_UGURU_SENSOR_BANK2, i,
-					&data->bank2_value[i], 1, 0)) != 1)
+		for (i = 0; i < data->bank2_sensors; i++) {
+			err = abituguru_read(data, ABIT_UGURU_SENSOR_BANK2, i,
+					     &data->bank2_value[i], 1, 0);
+			if (err != 1)
 				goto LEAVE_UPDATE;
+		}
 		/* success! */
 		success = 1;
 		data->update_timeouts = 0;
@@ -1385,8 +1517,10 @@ LEAVE_UPDATE:
 static int abituguru_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct abituguru_data *data = platform_get_drvdata(pdev);
-	/* make sure all communications with the uguru are done and no new
-	   ones are started */
+	/*
+	 * make sure all communications with the uguru are done and no new
+	 * ones are started
+	 */
 	mutex_lock(&data->update_lock);
 	return 0;
 }
@@ -1418,12 +1552,14 @@ static struct platform_driver abituguru_driver = {
 
 static int __init abituguru_detect(void)
 {
-	/* See if there is an uguru there. After a reboot uGuru will hold 0x00
-	   at DATA and 0xAC, when this driver has already been loaded once
-	   DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either
-	   scenario but some will hold 0x00.
-	   Some uGuru's initially hold 0x09 at DATA and will only hold 0x08
-	   after reading CMD first, so CMD must be read first! */
+	/*
+	 * See if there is an uguru there. After a reboot uGuru will hold 0x00
+	 * at DATA and 0xAC, when this driver has already been loaded once
+	 * DATA will hold 0x08. For most uGuru's CMD will hold 0xAC in either
+	 * scenario but some will hold 0x00.
+	 * Some uGuru's initially hold 0x09 at DATA and will only hold 0x08
+	 * after reading CMD first, so CMD must be read first!
+	 */
 	u8 cmd_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_CMD);
 	u8 data_val = inb_p(ABIT_UGURU_BASE + ABIT_UGURU_DATA);
 	if (((data_val == 0x00) || (data_val == 0x08)) &&
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index 34a14a7..a5bc428 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -1,28 +1,28 @@
 /*
-    abituguru3.c
-
-    Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com>
-    Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
-
-    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.
-*/
+ * abituguru3.c
+ *
+ * Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
+ *
+ * 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 supports the sensor part of revision 3 of the custom Abit uGuru
-    chip found on newer Abit uGuru motherboards. Note: because of lack of specs
-    only reading the sensors and their settings is supported.
-*/
+ * This driver supports the sensor part of revision 3 of the custom Abit uGuru
+ * chip found on newer Abit uGuru motherboards. Note: because of lack of specs
+ * only reading the sensors and their settings is supported.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -62,13 +62,17 @@
 #define ABIT_UGURU3_TEMP_SENSOR			1
 #define ABIT_UGURU3_FAN_SENSOR			2
 
-/* Timeouts / Retries, if these turn out to need a lot of fiddling we could
-   convert them to params. Determined by trial and error. I assume this is
-   cpu-speed independent, since the ISA-bus and not the CPU should be the
-   bottleneck. */
+/*
+ * Timeouts / Retries, if these turn out to need a lot of fiddling we could
+ * convert them to params. Determined by trial and error. I assume this is
+ * cpu-speed independent, since the ISA-bus and not the CPU should be the
+ * bottleneck.
+ */
 #define ABIT_UGURU3_WAIT_TIMEOUT		250
-/* Normally the 0xAC at the end of synchronize() is reported after the
-   first read, but sometimes not and we need to poll */
+/*
+ * Normally the 0xAC at the end of synchronize() is reported after the
+ * first read, but sometimes not and we need to poll
+ */
 #define ABIT_UGURU3_SYNCHRONIZE_TIMEOUT		5
 /* utility macros */
 #define ABIT_UGURU3_NAME			"abituguru3"
@@ -78,32 +82,45 @@
 
 /* Macros to help calculate the sysfs_names array length */
 #define ABIT_UGURU3_MAX_NO_SENSORS 26
-/* sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
-   in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0 */
-#define ABIT_UGURU3_IN_NAMES_LENGTH (11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11)
-/* sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0,
-   temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0,
-   temp??_label\0 */
+/*
+ * sum of strlen +1 of: in??_input\0, in??_{min,max}\0, in??_{min,max}_alarm\0,
+ * in??_{min,max}_alarm_enable\0, in??_beep\0, in??_shutdown\0, in??_label\0
+ */
+#define ABIT_UGURU3_IN_NAMES_LENGTH \
+				(11 + 2 * 9 + 2 * 15 + 2 * 22 + 10 + 14 + 11)
+/*
+ * sum of strlen +1 of: temp??_input\0, temp??_max\0, temp??_crit\0,
+ * temp??_alarm\0, temp??_alarm_enable\0, temp??_beep\0, temp??_shutdown\0,
+ * temp??_label\0
+ */
 #define ABIT_UGURU3_TEMP_NAMES_LENGTH (13 + 11 + 12 + 13 + 20 + 12 + 16 + 13)
-/* sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0,
-   fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0 */
+/*
+ * sum of strlen +1 of: fan??_input\0, fan??_min\0, fan??_alarm\0,
+ * fan??_alarm_enable\0, fan??_beep\0, fan??_shutdown\0, fan??_label\0
+ */
 #define ABIT_UGURU3_FAN_NAMES_LENGTH (12 + 10 + 12 + 19 + 11 + 15 + 12)
-/* Worst case scenario 16 in sensors (longest names_length) and the rest
-   temp sensors (second longest names_length). */
+/*
+ * Worst case scenario 16 in sensors (longest names_length) and the rest
+ * temp sensors (second longest names_length).
+ */
 #define ABIT_UGURU3_SYSFS_NAMES_LENGTH (16 * ABIT_UGURU3_IN_NAMES_LENGTH + \
 	(ABIT_UGURU3_MAX_NO_SENSORS - 16) * ABIT_UGURU3_TEMP_NAMES_LENGTH)
 
-/* All the macros below are named identical to the openguru2 program
-   reverse engineered by Louis Kruger, hence the names might not be 100%
-   logical. I could come up with better names, but I prefer keeping the names
-   identical so that this driver can be compared with his work more easily. */
+/*
+ * All the macros below are named identical to the openguru2 program
+ * reverse engineered by Louis Kruger, hence the names might not be 100%
+ * logical. I could come up with better names, but I prefer keeping the names
+ * identical so that this driver can be compared with his work more easily.
+ */
 /* Two i/o-ports are used by uGuru */
 #define ABIT_UGURU3_BASE			0x00E0
 #define ABIT_UGURU3_CMD				0x00
 #define ABIT_UGURU3_DATA			0x04
 #define ABIT_UGURU3_REGION_LENGTH		5
-/* The wait_xxx functions return this on success and the last contents
-   of the DATA register (0-255) on failure. */
+/*
+ * The wait_xxx functions return this on success and the last contents
+ * of the DATA register (0-255) on failure.
+ */
 #define ABIT_UGURU3_SUCCESS			-1
 /* uGuru status flags */
 #define ABIT_UGURU3_STATUS_READY_FOR_READ	0x01
@@ -112,7 +129,7 @@
 
 /* Structures */
 struct abituguru3_sensor_info {
-	const char* name;
+	const char *name;
 	int port;
 	int type;
 	int multiplier;
@@ -130,9 +147,11 @@ struct abituguru3_motherboard_info {
 	struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
 };
 
-/* For the Abit uGuru, we need to keep some data in memory.
-   The structure is dynamically allocated, at the same time when a new
-   abituguru3 device is allocated. */
+/*
+ * For the Abit uGuru, we need to keep some data in memory.
+ * The structure is dynamically allocated, at the same time when a new
+ * abituguru3 device is allocated.
+ */
 struct abituguru3_data {
 	struct device *hwmon_dev;	/* hwmon registered device */
 	struct mutex update_lock;	/* protect access to data and uGuru */
@@ -140,8 +159,10 @@ struct abituguru3_data {
 	char valid;			/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 
-	/* For convenience the sysfs attr and their names are generated
-	   automatically. We have max 10 entries per sensor (for in sensors) */
+	/*
+	 * For convenience the sysfs attr and their names are generated
+	 * automatically. We have max 10 entries per sensor (for in sensors)
+	 */
 	struct sensor_device_attribute_2 sysfs_attr[ABIT_UGURU3_MAX_NO_SENSORS
 		* 10];
 
@@ -151,9 +172,11 @@ struct abituguru3_data {
 	/* Pointer to the sensors info for the detected motherboard */
 	const struct abituguru3_sensor_info *sensors;
 
-	/* The abituguru3 supports up to 48 sensors, and thus has registers
-	   sets for 48 sensors, for convienence reasons / simplicity of the
-	   code we always read and store all registers for all 48 sensors */
+	/*
+	 * The abituguru3 supports up to 48 sensors, and thus has registers
+	 * sets for 48 sensors, for convienence reasons / simplicity of the
+	 * code we always read and store all registers for all 48 sensors
+	 */
 
 	/* Alarms for all 48 sensors (1 bit per sensor) */
 	u8 alarms[48/8];
@@ -161,9 +184,11 @@ struct abituguru3_data {
 	/* Value of all 48 sensors */
 	u8 value[48];
 
-	/* Settings of all 48 sensors, note in and temp sensors (the first 32
-	   sensors) have 3 bytes of settings, while fans only have 2 bytes,
-	   for convenience we use 3 bytes for all sensors */
+	/*
+	 * Settings of all 48 sensors, note in and temp sensors (the first 32
+	 * sensors) have 3 bytes of settings, while fans only have 2 bytes,
+	 * for convenience we use 3 bytes for all sensors
+	 */
 	u8 settings[48][3];
 };
 
@@ -626,8 +651,10 @@ static int abituguru3_wait_while_busy(struct abituguru3_data *data)
 		timeout--;
 		if (timeout == 0)
 			return x;
-		/* sleep a bit before our last try, to give the uGuru3 one
-		   last chance to respond. */
+		/*
+		 * sleep a bit before our last try, to give the uGuru3 one
+		 * last chance to respond.
+		 */
 		if (timeout == 1)
 			msleep(1);
 	}
@@ -645,48 +672,57 @@ static int abituguru3_wait_for_read(struct abituguru3_data *data)
 		timeout--;
 		if (timeout == 0)
 			return x;
-		/* sleep a bit before our last try, to give the uGuru3 one
-		   last chance to respond. */
+		/*
+		 * sleep a bit before our last try, to give the uGuru3 one
+		 * last chance to respond.
+		 */
 		if (timeout == 1)
 			msleep(1);
 	}
 	return ABIT_UGURU3_SUCCESS;
 }
 
-/* This synchronizes us with the uGuru3's protocol state machine, this
-   must be done before each command. */
+/*
+ * This synchronizes us with the uGuru3's protocol state machine, this
+ * must be done before each command.
+ */
 static int abituguru3_synchronize(struct abituguru3_data *data)
 {
 	int x, timeout = ABIT_UGURU3_SYNCHRONIZE_TIMEOUT;
 
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("synchronize timeout during initial busy "
 			"wait, status: 0x%02x\n", x);
 		return -EIO;
 	}
 
 	outb(0x20, data->addr + ABIT_UGURU3_DATA);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x20, "
 			"status: 0x%02x\n", x);
 		return -EIO;
 	}
 
 	outb(0x10, data->addr + ABIT_UGURU3_CMD);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x10, "
 			"status: 0x%02x\n", x);
 		return -EIO;
 	}
 
 	outb(0x00, data->addr + ABIT_UGURU3_CMD);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("synchronize timeout after sending 0x00, "
 			"status: 0x%02x\n", x);
 		return -EIO;
 	}
 
-	if ((x = abituguru3_wait_for_read(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_for_read(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("synchronize timeout waiting for read, "
 			"status: 0x%02x\n", x);
 		return -EIO;
@@ -705,18 +741,22 @@ static int abituguru3_synchronize(struct abituguru3_data *data)
 	return 0;
 }
 
-/* Read count bytes from sensor sensor_addr in bank bank_addr and store the
-   result in buf */
+/*
+ * Read count bytes from sensor sensor_addr in bank bank_addr and store the
+ * result in buf
+ */
 static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 	u8 count, u8 *buf)
 {
 	int i, x;
 
-	if ((x = abituguru3_synchronize(data)))
+	x = abituguru3_synchronize(data);
+	if (x)
 		return x;
 
 	outb(0x1A, data->addr + ABIT_UGURU3_DATA);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 			"sending 0x1A, status: 0x%02x\n", (unsigned int)bank,
 			(unsigned int)offset, x);
@@ -724,7 +764,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 	}
 
 	outb(bank, data->addr + ABIT_UGURU3_CMD);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 			"sending the bank, status: 0x%02x\n",
 			(unsigned int)bank, (unsigned int)offset, x);
@@ -732,7 +773,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 	}
 
 	outb(offset, data->addr + ABIT_UGURU3_CMD);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 			"sending the offset, status: 0x%02x\n",
 			(unsigned int)bank, (unsigned int)offset, x);
@@ -740,7 +782,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 	}
 
 	outb(count, data->addr + ABIT_UGURU3_CMD);
-	if ((x = abituguru3_wait_while_busy(data)) != ABIT_UGURU3_SUCCESS) {
+	x = abituguru3_wait_while_busy(data);
+	if (x != ABIT_UGURU3_SUCCESS) {
 		ABIT_UGURU3_DEBUG("read from 0x%02x:0x%02x timed out after "
 			"sending the count, status: 0x%02x\n",
 			(unsigned int)bank, (unsigned int)offset, x);
@@ -748,8 +791,8 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 	}
 
 	for (i = 0; i < count; i++) {
-		if ((x = abituguru3_wait_for_read(data)) !=
-				ABIT_UGURU3_SUCCESS) {
+		x = abituguru3_wait_for_read(data);
+		if (x != ABIT_UGURU3_SUCCESS) {
 			ABIT_UGURU3_DEBUG("timeout reading byte %d from "
 				"0x%02x:0x%02x, status: 0x%02x\n", i,
 				(unsigned int)bank, (unsigned int)offset, x);
@@ -760,28 +803,34 @@ static int abituguru3_read(struct abituguru3_data *data, u8 bank, u8 offset,
 	return i;
 }
 
-/* Sensor settings are stored 1 byte per offset with the bytes
-   placed add consecutive offsets. */
+/*
+ * Sensor settings are stored 1 byte per offset with the bytes
+ * placed add consecutive offsets.
+ */
 static int abituguru3_read_increment_offset(struct abituguru3_data *data,
 					    u8 bank, u8 offset, u8 count,
 					    u8 *buf, int offset_count)
 {
 	int i, x;
 
-	for (i = 0; i < offset_count; i++)
-		if ((x = abituguru3_read(data, bank, offset + i, count,
-				buf + i * count)) != count) {
+	for (i = 0; i < offset_count; i++) {
+		x = abituguru3_read(data, bank, offset + i, count,
+				    buf + i * count);
+		if (x != count) {
 			if (x < 0)
 				return x;
 			return i * count + x;
 		}
+	}
 
 	return i * count;
 }
 
-/* Following are the sysfs callback functions. These functions expect:
-   sensor_device_attribute_2->index:   index into the data->sensors array
-   sensor_device_attribute_2->nr:      register offset, bitmask or NA. */
+/*
+ * Following are the sysfs callback functions. These functions expect:
+ * sensor_device_attribute_2->index:   index into the data->sensors array
+ * sensor_device_attribute_2->nr:      register offset, bitmask or NA.
+ */
 static struct abituguru3_data *abituguru3_update_device(struct device *dev);
 
 static ssize_t show_value(struct device *dev,
@@ -807,8 +856,10 @@ static ssize_t show_value(struct device *dev,
 	value = (value * sensor->multiplier) / sensor->divisor +
 		sensor->offset;
 
-	/* alternatively we could update the sensors settings struct for this,
-	   but then its contents would differ from the windows sw ini files */
+	/*
+	 * alternatively we could update the sensors settings struct for this,
+	 * but then its contents would differ from the windows sw ini files
+	 */
 	if (sensor->type == ABIT_UGURU3_TEMP_SENSOR)
 		value *= 1000;
 
@@ -827,10 +878,12 @@ static ssize_t show_alarm(struct device *dev,
 
 	port = data->sensors[attr->index].port;
 
-	/* See if the alarm bit for this sensor is set and if a bitmask is
-	   given in attr->nr also check if the alarm matches the type of alarm
-	   we're looking for (for volt it can be either low or high). The type
-	   is stored in a few readonly bits in the settings of the sensor. */
+	/*
+	 * See if the alarm bit for this sensor is set and if a bitmask is
+	 * given in attr->nr also check if the alarm matches the type of alarm
+	 * we're looking for (for volt it can be either low or high). The type
+	 * is stored in a few readonly bits in the settings of the sensor.
+	 */
 	if ((data->alarms[port / 8] & (0x01 << (port % 8))) &&
 			(!attr->nr || (data->settings[port][0] & attr->nr)))
 		return sprintf(buf, "1\n");
@@ -923,7 +976,8 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
 	u8 buf[2];
 	u16 id;
 
-	if (!(data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL)))
+	data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL);
+	if (!data)
 		return -ENOMEM;
 
 	data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
@@ -931,10 +985,10 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, data);
 
 	/* Read the motherboard ID */
-	if ((i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK,
-			ABIT_UGURU3_BOARD_ID, 2, buf)) != 2) {
+	i = abituguru3_read(data, ABIT_UGURU3_MISC_BANK, ABIT_UGURU3_BOARD_ID,
+			    2, buf);
+	if (i != 2)
 		goto abituguru3_probe_error;
-	}
 
 	/* Completely read the uGuru to see if one really is there */
 	if (!abituguru3_update_device(&pdev->dev))
@@ -1091,8 +1145,10 @@ LEAVE_UPDATE:
 static int abituguru3_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct abituguru3_data *data = platform_get_drvdata(pdev);
-	/* make sure all communications with the uguru3 are done and no new
-	   ones are started */
+	/*
+	 * make sure all communications with the uguru3 are done and no new
+	 * ones are started
+	 */
 	mutex_lock(&data->update_lock);
 	return 0;
 }
@@ -1134,7 +1190,8 @@ static int __init abituguru3_dmi_detect(void)
 	if (!board_name)
 		return err;
 
-	/* At the moment, we don't care about the part of the vendor
+	/*
+	 * At the moment, we don't care about the part of the vendor
 	 * DMI string contained in brackets. Truncate the string at
 	 * the first occurrence of a bracket. Trim any trailing space
 	 * from the substring.
@@ -1157,15 +1214,18 @@ static int __init abituguru3_dmi_detect(void)
 	return 1;
 }
 
-/* FIXME: Manual detection should die eventually; we need to collect stable
+/*
+ * FIXME: Manual detection should die eventually; we need to collect stable
  *        DMI model names first before we can rely entirely on CONFIG_DMI.
  */
 
 static int __init abituguru3_detect(void)
 {
-	/* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
-	   0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
-	   or 0x55 at CMD instead, why is unknown. */
+	/*
+	 * See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
+	 * 0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
+	 * or 0x55 at CMD instead, why is unknown.
+	 */
 	u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
 	u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
 	if (((data_val == 0x00) || (data_val == 0x08)) &&
@@ -1197,7 +1257,8 @@ static int __init abituguru3_init(void)
 	if (err < 0)
 		return err;
 
-	/* Fall back to manual detection if there was no exact
+	/*
+	 * Fall back to manual detection if there was no exact
 	 * board name match, or force was specified.
 	 */
 	if (err > 0) {
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c
index 5d760f3..0e0cfcc 100644
--- a/drivers/hwmon/ad7314.c
+++ b/drivers/hwmon/ad7314.c
@@ -167,17 +167,7 @@ static struct spi_driver ad7314_driver = {
 	.id_table = ad7314_id,
 };
 
-static __init int ad7314_init(void)
-{
-	return spi_register_driver(&ad7314_driver);
-}
-module_init(ad7314_init);
-
-static __exit void ad7314_exit(void)
-{
-	spi_unregister_driver(&ad7314_driver);
-}
-module_exit(ad7314_exit);
+module_spi_driver(ad7314_driver);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital"
diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c
index df29a7f..06d2d60 100644
--- a/drivers/hwmon/ad7414.c
+++ b/drivers/hwmon/ad7414.c
@@ -50,7 +50,8 @@ struct ad7414_data {
 /* REG: (0.25C/bit, two's complement) << 6 */
 static inline int ad7414_temp_from_reg(s16 reg)
 {
-	/* use integer division instead of equivalent right shift to
+	/*
+	 * use integer division instead of equivalent right shift to
 	 * guarantee arithmetic shift and preserve the sign
 	 */
 	return ((int)reg / 64) * 250;
@@ -130,7 +131,11 @@ static ssize_t set_max_min(struct device *dev,
 	struct ad7414_data *data = i2c_get_clientdata(client);
 	int index = to_sensor_dev_attr(attr)->index;
 	u8 reg = AD7414_REG_LIMIT[index];
-	long temp = simple_strtol(buf, NULL, 10);
+	long temp;
+	int ret = kstrtol(buf, 10, &temp);
+
+	if (ret < 0)
+		return ret;
 
 	temp = SENSORS_LIMIT(temp, -40000, 85000);
 	temp = (temp + (temp < 0 ? -500 : 500)) / 1000;
@@ -252,17 +257,7 @@ static struct i2c_driver ad7414_driver = {
 	.id_table = ad7414_id,
 };
 
-static int __init ad7414_init(void)
-{
-	return i2c_add_driver(&ad7414_driver);
-}
-module_init(ad7414_init);
-
-static void __exit ad7414_exit(void)
-{
-	i2c_del_driver(&ad7414_driver);
-}
-module_exit(ad7414_exit);
+module_i2c_driver(ad7414_driver);
 
 MODULE_AUTHOR("Stefan Roese <sr at denx.de>, "
 	      "Frank Edelhaeuser <frank.edelhaeuser at spansion.com>");
diff --git a/drivers/hwmon/ad7418.c b/drivers/hwmon/ad7418.c
index 8cb718c..a50a6be 100644
--- a/drivers/hwmon/ad7418.c
+++ b/drivers/hwmon/ad7418.c
@@ -167,7 +167,11 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct ad7418_data *data = i2c_get_clientdata(client);
-	long temp = simple_strtol(buf, NULL, 10);
+	long temp;
+	int ret = kstrtol(buf, 10, &temp);
+
+	if (ret < 0)
+		return ret;
 
 	mutex_lock(&data->lock);
 	data->temp[attr->index] = LM75_TEMP_TO_REG(temp);
@@ -228,7 +232,8 @@ static int ad7418_probe(struct i2c_client *client,
 		goto exit;
 	}
 
-	if (!(data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto exit;
 	}
@@ -261,7 +266,8 @@ static int ad7418_probe(struct i2c_client *client,
 	ad7418_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
+	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -289,20 +295,9 @@ static int ad7418_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int __init ad7418_init(void)
-{
-	return i2c_add_driver(&ad7418_driver);
-}
-
-static void __exit ad7418_exit(void)
-{
-	i2c_del_driver(&ad7418_driver);
-}
+module_i2c_driver(ad7418_driver);
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("AD7416/17/18 driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(ad7418_init);
-module_exit(ad7418_exit);
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c
index ceb24a3..a3d3183 100644
--- a/drivers/hwmon/adcxx.c
+++ b/drivers/hwmon/adcxx.c
@@ -248,18 +248,7 @@ static struct spi_driver adcxx_driver = {
 	.remove	= __devexit_p(adcxx_remove),
 };
 
-static int __init init_adcxx(void)
-{
-	return spi_register_driver(&adcxx_driver);
-}
-
-static void __exit exit_adcxx(void)
-{
-	spi_unregister_driver(&adcxx_driver);
-}
-
-module_init(init_adcxx);
-module_exit(exit_adcxx);
+module_spi_driver(adcxx_driver);
 
 MODULE_AUTHOR("Marc Pignat");
 MODULE_DESCRIPTION("National Semiconductor adcxx8sxxx Linux driver");
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index 0158cc3..4394e7e 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -1,23 +1,23 @@
 /*
-    adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
-		monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
-    Philip Edelbrock <phil@netroedge.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
+ *			     Philip Edelbrock <phil@netroedge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -70,10 +70,12 @@ enum chips {
 
 /* Initial values */
 
-/* Note: Even though I left the low and high limits named os and hyst,
-they don't quite work like a thermostat the way the LM75 does.  I.e.,
-a lower temp than THYST actually triggers an alarm instead of
-clearing it.  Weird, ey?   --Phil  */
+/*
+ * Note: Even though I left the low and high limits named os and hyst,
+ * they don't quite work like a thermostat the way the LM75 does.  I.e.,
+ * a lower temp than THYST actually triggers an alarm instead of
+ * clearing it.  Weird, ey?   --Phil
+ */
 
 /* Each client has this additional data */
 struct adm1021_data {
@@ -182,7 +184,13 @@ static ssize_t set_temp_max(struct device *dev,
 	int index = to_sensor_dev_attr(devattr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1021_data *data = i2c_get_clientdata(client);
-	long temp = simple_strtol(buf, NULL, 10) / 1000;
+	long temp;
+	int err;
+
+	err = kstrtol(buf, 10, &temp);
+	if (err)
+		return err;
+	temp /= 1000;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127);
@@ -201,7 +209,13 @@ static ssize_t set_temp_min(struct device *dev,
 	int index = to_sensor_dev_attr(devattr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1021_data *data = i2c_get_clientdata(client);
-	long temp = simple_strtol(buf, NULL, 10) / 1000;
+	long temp;
+	int err;
+
+	err = kstrtol(buf, 10, &temp);
+	if (err)
+		return err;
+	temp /= 1000;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127);
@@ -226,7 +240,14 @@ static ssize_t set_low_power(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1021_data *data = i2c_get_clientdata(client);
-	int low_power = simple_strtol(buf, NULL, 10) != 0;
+	char low_power;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	low_power = val != 0;
 
 	mutex_lock(&data->update_lock);
 	if (low_power != data->low_power) {
@@ -361,7 +382,8 @@ static int adm1021_probe(struct i2c_client *client,
 		adm1021_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group)))
+	err = sysfs_create_group(&client->dev.kobj, &adm1021_group);
+	if (err)
 		goto error1;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -427,8 +449,10 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
 		data->alarms = i2c_smbus_read_byte_data(client,
 						ADM1021_REG_STATUS) & 0x7c;
 		if (data->type == adm1023) {
-			/* The ADM1023 provides 3 extra bits of precision for
-			 * the remote sensor in extra registers. */
+			/*
+			 * The ADM1023 provides 3 extra bits of precision for
+			 * the remote sensor in extra registers.
+			 */
 			data->temp[1] += 125 * (i2c_smbus_read_byte_data(
 				client, ADM1023_REG_REM_TEMP_PREC) >> 5);
 			data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
@@ -451,23 +475,12 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_adm1021_init(void)
-{
-	return i2c_add_driver(&adm1021_driver);
-}
-
-static void __exit sensors_adm1021_exit(void)
-{
-	i2c_del_driver(&adm1021_driver);
-}
+module_i2c_driver(adm1021_driver);
 
-MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl> and "
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
 		"Philip Edelbrock <phil@netroedge.com>");
 MODULE_DESCRIPTION("adm1021 driver");
 MODULE_LICENSE("GPL");
 
 module_param(read_only, bool, 0);
 MODULE_PARM_DESC(read_only, "Don't set any values, read only mode");
-
-module_init(sensors_adm1021_init)
-module_exit(sensors_adm1021_exit)
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index 60befc0..b8557f9 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -12,7 +12,7 @@
  * resolution of about 0.5% of the nominal value). Temperature values are
  * reported with a 1 deg resolution and a 3 deg accuracy. Complete
  * datasheet can be obtained from Analog's website at:
- *   http://www.onsemi.com/PowerSolutions/product.do?id=ADM1025 
+ *   http://www.onsemi.com/PowerSolutions/product.do?id=ADM1025
  *
  * This driver also supports the ADM1025A, which differs from the ADM1025
  * only in that it has "open-drain VID inputs while the ADM1025 has
@@ -91,15 +91,16 @@ enum chips { adm1025, ne1619 };
 
 static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
 
-#define IN_FROM_REG(reg,scale)	(((reg) * (scale) + 96) / 192)
-#define IN_TO_REG(val,scale)	((val) <= 0 ? 0 : \
+#define IN_FROM_REG(reg, scale)	(((reg) * (scale) + 96) / 192)
+#define IN_TO_REG(val, scale)	((val) <= 0 ? 0 : \
 				 (val) * 192 >= (scale) * 255 ? 255 : \
-				 ((val) * 192 + (scale)/2) / (scale))
+				 ((val) * 192 + (scale) / 2) / (scale))
 
 #define TEMP_FROM_REG(reg)	((reg) * 1000)
 #define TEMP_TO_REG(val)	((val) <= -127500 ? -128 : \
 				 (val) >= 126500 ? 127 : \
-				 (((val) < 0 ? (val)-500 : (val)+500) / 1000))
+				 (((val) < 0 ? (val) - 500 : \
+				   (val) + 500) / 1000))
 
 /*
  * Functions declaration
@@ -218,7 +219,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 	int index = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1025_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[index] = IN_TO_REG(val, in_scale[index]);
@@ -234,7 +240,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 	int index = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1025_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[index] = IN_TO_REG(val, in_scale[index]);
@@ -264,7 +275,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	int index = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1025_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[index] = TEMP_TO_REG(val);
@@ -280,7 +296,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	int index = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1025_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[index] = TEMP_TO_REG(val);
@@ -343,7 +364,14 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
 		       const char *buf, size_t count)
 {
 	struct adm1025_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	data->vrm = val;
 	return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
@@ -462,14 +490,15 @@ static int adm1025_probe(struct i2c_client *client,
 	adm1025_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &adm1025_group)))
+	err = sysfs_create_group(&client->dev.kobj, &adm1025_group);
+	if (err)
 		goto exit_free;
 
 	/* Pin 11 is either in4 (+12V) or VID4 */
 	config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
 	if (!(config & 0x20)) {
-		if ((err = sysfs_create_group(&client->dev.kobj,
-					      &adm1025_group_in4)))
+		err = sysfs_create_group(&client->dev.kobj, &adm1025_group_in4);
+		if (err)
 			goto exit_remove;
 	}
 
@@ -506,7 +535,7 @@ static void adm1025_init_client(struct i2c_client *client)
 	 * setting yet, we better set the high limits to the max so that
 	 * no alarm triggers.
 	 */
-	for (i=0; i<6; i++) {
+	for (i = 0; i < 6; i++) {
 		reg = i2c_smbus_read_byte_data(client,
 					       ADM1025_REG_IN_MAX(i));
 		if (reg == 0)
@@ -514,7 +543,7 @@ static void adm1025_init_client(struct i2c_client *client)
 						  ADM1025_REG_IN_MAX(i),
 						  0xFF);
 	}
-	for (i=0; i<2; i++) {
+	for (i = 0; i < 2; i++) {
 		reg = i2c_smbus_read_byte_data(client,
 					       ADM1025_REG_TEMP_HIGH(i));
 		if (reg == 0)
@@ -555,7 +584,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
 		int i;
 
 		dev_dbg(&client->dev, "Updating data.\n");
-		for (i=0; i<6; i++) {
+		for (i = 0; i < 6; i++) {
 			data->in[i] = i2c_smbus_read_byte_data(client,
 				      ADM1025_REG_IN(i));
 			data->in_min[i] = i2c_smbus_read_byte_data(client,
@@ -563,7 +592,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
 			data->in_max[i] = i2c_smbus_read_byte_data(client,
 					  ADM1025_REG_IN_MAX(i));
 		}
-		for (i=0; i<2; i++) {
+		for (i = 0; i < 2; i++) {
 			data->temp[i] = i2c_smbus_read_byte_data(client,
 					ADM1025_REG_TEMP(i));
 			data->temp_min[i] = i2c_smbus_read_byte_data(client,
@@ -589,19 +618,8 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_adm1025_init(void)
-{
-	return i2c_add_driver(&adm1025_driver);
-}
-
-static void __exit sensors_adm1025_exit(void)
-{
-	i2c_del_driver(&adm1025_driver);
-}
+module_i2c_driver(adm1025_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("ADM1025 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_adm1025_init);
-module_exit(sensors_adm1025_exit);
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 0531867..1003219 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -1,27 +1,27 @@
 /*
-    adm1026.c - Part of lm_sensors, Linux kernel modules for hardware
-	     monitoring
-    Copyright (C) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
-    Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com>
-
-    Chip details at:
-
-    <http://www.onsemi.com/PowerSolutions/product.do?id=ADM1026>
-
-    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.
-*/
+ * adm1026.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Copyright (C) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
+ * Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com>
+ *
+ * Chip details at:
+ *
+ * <http://www.onsemi.com/PowerSolutions/product.do?id=ADM1026>
+ *
+ * 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>
@@ -90,7 +90,8 @@ MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs");
 #define E2CFG_ROM		0x08
 #define E2CFG_CLK_EXT		0x80
 
-/* There are 10 general analog inputs and 7 dedicated inputs
+/*
+ * There are 10 general analog inputs and 7 dedicated inputs
  * They are:
  *    0 - 9  =  AIN0 - AIN9
  *       10  =  Vbat
@@ -117,7 +118,8 @@ static u16 ADM1026_REG_IN_MAX[] = {
 		0x43, 0x44, 0x45, 0x46, 0x47
 	};
 
-/* Temperatures are:
+/*
+ * Temperatures are:
  *    0 - Internal
  *    1 - External 1
  *    2 - External 2
@@ -170,12 +172,14 @@ static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f };
 #define ADM1026_FAN_CONTROL_TEMP_RANGE	20
 #define ADM1026_PWM_MAX			255
 
-/* Conversions. Rounding and limit checking is only done on the TO_REG
+/*
+ * Conversions. Rounding and limit checking is only done on the TO_REG
  * variants. Note that you should be a bit careful with which arguments
  * these macros are called: arguments may be evaluated more than once.
  */
 
-/* IN are scaled according to built-in resistors.  These are the
+/*
+ * IN are scaled according to built-in resistors.  These are the
  *   voltages corresponding to 3/4 of full scale (192 or 0xc0)
  *   NOTE: The -12V input needs an additional factor to account
  *      for the Vref pullup resistor.
@@ -197,23 +201,25 @@ static int adm1026_scaling[] = { /* .001 Volts */
 	0, 255))
 #define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n]))
 
-/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses
+/*
+ * FAN speed is measured using 22.5kHz clock and counts for 2 pulses
  *   and we assume a 2 pulse-per-rev fan tach signal
  *      22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000
  */
 #define FAN_TO_REG(val, div)  ((val) <= 0 ? 0xff : \
-				SENSORS_LIMIT(1350000/((val)*(div)), 1, 254))
-#define FAN_FROM_REG(val, div) ((val) == 0 ? -1:(val) == 0xff ? 0 : \
-				1350000/((val)*(div)))
-#define DIV_FROM_REG(val) (1<<(val))
+				SENSORS_LIMIT(1350000 / ((val) * (div)), \
+					      1, 254))
+#define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 0xff ? 0 : \
+				1350000 / ((val) * (div)))
+#define DIV_FROM_REG(val) (1 << (val))
 #define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0)
 
 /* Temperature is reported in 1 degC increments */
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
-	-127, 127))
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \
+					/ 1000, -127, 127))
 #define TEMP_FROM_REG(val) ((val) * 1000)
-#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
-	-127, 127))
+#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \
+					  / 1000, -127, 127))
 #define OFFSET_FROM_REG(val) ((val) * 1000)
 
 #define PWM_TO_REG(val) (SENSORS_LIMIT(val, 0, 255))
@@ -222,14 +228,16 @@ static int adm1026_scaling[] = { /* .001 Volts */
 #define PWM_MIN_TO_REG(val) ((val) & 0xf0)
 #define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4))
 
-/* Analog output is a voltage, and scaled to millivolts.  The datasheet
+/*
+ * Analog output is a voltage, and scaled to millivolts.  The datasheet
  *   indicates that the DAC could be used to drive the fans, but in our
  *   example board (Arima HDAMA) it isn't connected to the fans at all.
  */
-#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500), 0, 255))
-#define DAC_FROM_REG(val) (((val)*2500)/255)
+#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val) * 255) + 500) / 2500), 0, 255))
+#define DAC_FROM_REG(val) (((val) * 2500) / 255)
 
-/* Chip sampling rates
+/*
+ * Chip sampling rates
  *
  * Some sensors are not updated more frequently than once per second
  *    so it doesn't make sense to read them more often than that.
@@ -243,11 +251,13 @@ static int adm1026_scaling[] = { /* .001 Volts */
 #define ADM1026_DATA_INTERVAL		(1 * HZ)
 #define ADM1026_CONFIG_INTERVAL		(5 * 60 * HZ)
 
-/* We allow for multiple chips in a single system.
+/*
+ * We allow for multiple chips in a single system.
  *
  * For each registered ADM1026, we need to keep state information
  * at client->data. The adm1026_data structure is dynamically
- * allocated, when a new client structure is allocated. */
+ * allocated, when a new client structure is allocated.
+ */
 
 struct pwm_data {
 	u8 pwm;
@@ -388,17 +398,16 @@ static void adm1026_init_client(struct i2c_client *client)
 		dev_dbg(&client->dev, "THERM pin enabled.  "
 			"GPIO16 disabled.\n");
 	}
-	if (data->config3 & CFG3_VREF_250) {
+	if (data->config3 & CFG3_VREF_250)
 		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
-	} else {
+	else
 		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
-	}
 	/* Read and pick apart the existing GPIO configuration */
 	value = 0;
-	for (i = 0;i <= 15;++i) {
+	for (i = 0; i <= 15; ++i) {
 		if ((i & 0x03) == 0) {
 			value = adm1026_read_value(client,
-					ADM1026_REG_GPIO_CFG_0_3 + i/4);
+					ADM1026_REG_GPIO_CFG_0_3 + i / 4);
 		}
 		data->gpio_config[i] = value & 0x03;
 		value >>= 2;
@@ -408,7 +417,8 @@ static void adm1026_init_client(struct i2c_client *client)
 	/* ... and then print it */
 	adm1026_print_gpio(client);
 
-	/* If the user asks us to reprogram the GPIO config, then
+	/*
+	 * If the user asks us to reprogram the GPIO config, then
 	 * do it now.
 	 */
 	if (gpio_input[0] != -1 || gpio_output[0] != -1
@@ -417,7 +427,8 @@ static void adm1026_init_client(struct i2c_client *client)
 		adm1026_fixup_gpio(client);
 	}
 
-	/* WE INTENTIONALLY make no changes to the limits,
+	/*
+	 * WE INTENTIONALLY make no changes to the limits,
 	 *   offsets, pwms, fans and zones.  If they were
 	 *   configured, we don't want to mess with them.
 	 *   If they weren't, the default is 100% PWM, no
@@ -428,7 +439,7 @@ static void adm1026_init_client(struct i2c_client *client)
 	 *   without first setting a value for pwm1.auto_pwm_min
 	 *   will not result in potentially dangerous fan speed decrease.
 	 */
-	data->pwm1.auto_pwm_min=255;
+	data->pwm1.auto_pwm_min = 255;
 	/* Start monitoring */
 	value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
 	/* Set MONITOR, clear interrupt acknowledge and s/w reset */
@@ -440,7 +451,7 @@ static void adm1026_init_client(struct i2c_client *client)
 	/* initialize fan_div[] to hardware defaults */
 	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
 		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
-	for (i = 0;i <= 7;++i) {
+	for (i = 0; i <= 7; ++i) {
 		data->fan_div[i] = DIV_FROM_REG(value & 0x03);
 		value >>= 2;
 	}
@@ -452,7 +463,7 @@ static void adm1026_print_gpio(struct i2c_client *client)
 	int i;
 
 	dev_dbg(&client->dev, "GPIO config is:\n");
-	for (i = 0;i <= 7;++i) {
+	for (i = 0; i <= 7; ++i) {
 		if (data->config2 & (1 << i)) {
 			dev_dbg(&client->dev, "\t%sGP%s%d\n",
 				data->gpio_config[i] & 0x02 ? "" : "!",
@@ -462,7 +473,7 @@ static void adm1026_print_gpio(struct i2c_client *client)
 			dev_dbg(&client->dev, "\tFAN%d\n", i);
 		}
 	}
-	for (i = 8;i <= 15;++i) {
+	for (i = 8; i <= 15; ++i) {
 		dev_dbg(&client->dev, "\t%sGP%s%d\n",
 			data->gpio_config[i] & 0x02 ? "" : "!",
 			data->gpio_config[i] & 0x01 ? "OUT" : "IN",
@@ -485,52 +496,46 @@ static void adm1026_fixup_gpio(struct i2c_client *client)
 	int value;
 
 	/* Make the changes requested. */
-	/* We may need to unlock/stop monitoring or soft-reset the
+	/*
+	 * We may need to unlock/stop monitoring or soft-reset the
 	 *    chip before we can make changes.  This hasn't been
 	 *    tested much.  FIXME
 	 */
 
 	/* Make outputs */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_output[i] >= 0 && gpio_output[i] <= 16) {
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
 			data->gpio_config[gpio_output[i]] |= 0x01;
-		}
 		/* if GPIO0-7 is output, it isn't a FAN tach */
-		if (gpio_output[i] >= 0 && gpio_output[i] <= 7) {
+		if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
 			data->config2 |= 1 << gpio_output[i];
-		}
 	}
 
 	/* Input overrides output */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_input[i] >= 0 && gpio_input[i] <= 16) {
-			data->gpio_config[gpio_input[i]] &= ~ 0x01;
-		}
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
+			data->gpio_config[gpio_input[i]] &= ~0x01;
 		/* if GPIO0-7 is input, it isn't a FAN tach */
-		if (gpio_input[i] >= 0 && gpio_input[i] <= 7) {
+		if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
 			data->config2 |= 1 << gpio_input[i];
-		}
 	}
 
 	/* Inverted */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) {
-			data->gpio_config[gpio_inverted[i]] &= ~ 0x02;
-		}
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
+			data->gpio_config[gpio_inverted[i]] &= ~0x02;
 	}
 
 	/* Normal overrides inverted */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) {
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
 			data->gpio_config[gpio_normal[i]] |= 0x02;
-		}
 	}
 
 	/* Fan overrides input and output */
-	for (i = 0;i <= 7;++i) {
-		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) {
+	for (i = 0; i <= 7; ++i) {
+		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
 			data->config2 &= ~(1 << gpio_fan[i]);
-		}
 	}
 
 	/* Write new configs to registers */
@@ -538,7 +543,7 @@ static void adm1026_fixup_gpio(struct i2c_client *client)
 	data->config3 = (data->config3 & 0x3f)
 			| ((data->gpio_config[16] & 0x03) << 6);
 	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
-	for (i = 15, value = 0;i >= 0;--i) {
+	for (i = 15, value = 0; i >= 0; --i) {
 		value <<= 2;
 		value |= data->gpio_config[i] & 0x03;
 		if ((i & 0x03) == 0) {
@@ -563,22 +568,25 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
 
 	mutex_lock(&data->update_lock);
 	if (!data->valid
-	    || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) {
+	    || time_after(jiffies,
+			  data->last_reading + ADM1026_DATA_INTERVAL)) {
 		/* Things that change quickly */
 		dev_dbg(&client->dev, "Reading sensor values\n");
-		for (i = 0;i <= 16;++i) {
+		for (i = 0; i <= 16; ++i) {
 			data->in[i] =
 			    adm1026_read_value(client, ADM1026_REG_IN[i]);
 		}
 
-		for (i = 0;i <= 7;++i) {
+		for (i = 0; i <= 7; ++i) {
 			data->fan[i] =
 			    adm1026_read_value(client, ADM1026_REG_FAN(i));
 		}
 
-		for (i = 0;i <= 2;++i) {
-			/* NOTE: temp[] is s8 and we assume 2's complement
-			 *   "conversion" in the assignment */
+		for (i = 0; i <= 2; ++i) {
+			/*
+			 * NOTE: temp[] is s8 and we assume 2's complement
+			 *   "conversion" in the assignment
+			 */
 			data->temp[i] =
 			    adm1026_read_value(client, ADM1026_REG_TEMP[i]);
 		}
@@ -614,7 +622,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
 	    time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) {
 		/* Things that don't change often */
 		dev_dbg(&client->dev, "Reading config values\n");
-		for (i = 0;i <= 16;++i) {
+		for (i = 0; i <= 16; ++i) {
 			data->in_min[i] = adm1026_read_value(client,
 				ADM1026_REG_IN_MIN[i]);
 			data->in_max[i] = adm1026_read_value(client,
@@ -624,7 +632,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
 		value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3)
 			| (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7)
 			<< 8);
-		for (i = 0;i <= 7;++i) {
+		for (i = 0; i <= 7; ++i) {
 			data->fan_min[i] = adm1026_read_value(client,
 				ADM1026_REG_FAN_MIN(i));
 			data->fan_div[i] = DIV_FROM_REG(value & 0x03);
@@ -632,7 +640,8 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
 		}
 
 		for (i = 0; i <= 2; ++i) {
-			/* NOTE: temp_xxx[] are s8 and we assume 2's
+			/*
+			 * NOTE: temp_xxx[] are s8 and we assume 2's
 			 *    complement "conversion" in the assignment
 			 */
 			data->temp_min[i] = adm1026_read_value(client,
@@ -681,7 +690,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
 		data->gpio_config[16] = (data->config3 >> 6) & 0x03;
 
 		value = 0;
-		for (i = 0;i <= 15;++i) {
+		for (i = 0; i <= 15; ++i) {
 			if ((i & 0x03) == 0) {
 				value = adm1026_read_value(client,
 					    ADM1026_REG_GPIO_CFG_0_3 + i/4);
@@ -721,7 +730,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = INS_TO_REG(nr, val);
@@ -744,7 +758,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = INS_TO_REG(nr, val);
@@ -779,23 +798,31 @@ in_reg(13);
 in_reg(14);
 in_reg(15);
 
-static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_in16(struct device *dev, struct device_attribute *attr,
+			 char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in[16]) -
 		NEG12_OFFSET);
 }
-static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr,
+			     char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_min[16])
 		- NEG12_OFFSET);
 }
-static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET);
@@ -803,17 +830,24 @@ static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, c
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr,
+			     char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_max[16])
 			- NEG12_OFFSET);
 }
-static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET);
@@ -823,10 +857,10 @@ static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, c
 }
 
 static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16);
-static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min, 16);
-static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max, 16);
-
-
+static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min,
+			  set_in16_min, 16);
+static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max,
+			  set_in16_max, 16);
 
 
 /* Now add fan read/write functions */
@@ -856,7 +890,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]);
@@ -890,9 +929,8 @@ static void fixup_fan_min(struct device *dev, int fan, int old_div)
 	int new_div = data->fan_div[fan];
 
 	/* 0 and 0xff are special.  Don't adjust them */
-	if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) {
+	if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff)
 		return;
-	}
 
 	new_min = data->fan_min[fan] * old_div / new_div;
 	new_min = SENSORS_LIMIT(new_min, 1, 254);
@@ -916,9 +954,14 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val, orig_div, new_div;
+	long val;
+	int orig_div, new_div;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtol(buf, NULL, 10);
 	new_div = DIV_TO_REG(val);
 
 	mutex_lock(&data->update_lock);
@@ -939,9 +982,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 				    (DIV_TO_REG(data->fan_div[7]) << 6));
 	}
 
-	if (data->fan_div[nr] != orig_div) {
+	if (data->fan_div[nr] != orig_div)
 		fixup_fan_min(dev, nr, orig_div);
-	}
+
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -983,7 +1026,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[nr] = TEMP_TO_REG(val);
@@ -1007,7 +1055,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[nr] = TEMP_TO_REG(val);
@@ -1046,7 +1099,12 @@ static ssize_t set_temp_offset(struct device *dev,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_offset[nr] = TEMP_TO_REG(val);
@@ -1056,8 +1114,8 @@ static ssize_t set_temp_offset(struct device *dev,
 	return count;
 }
 
-#define temp_offset_reg(offset)							\
-static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR,		\
+#define temp_offset_reg(offset)						\
+static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR,	\
 		show_temp_offset, set_temp_offset, offset - 1);
 
 temp_offset_reg(1);
@@ -1097,7 +1155,12 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_tmin[nr] = TEMP_TO_REG(val);
@@ -1131,15 +1194,21 @@ static ssize_t set_temp_crit_enable(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	if (val > 1)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
+	adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1);
+	mutex_unlock(&data->update_lock);
 
-	if ((val == 1) || (val==0)) {
-		mutex_lock(&data->update_lock);
-		data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
-		adm1026_write_value(client, ADM1026_REG_CONFIG1,
-			data->config1);
-		mutex_unlock(&data->update_lock);
-	}
 	return count;
 }
 
@@ -1166,7 +1235,12 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_crit[nr] = TEMP_TO_REG(val);
@@ -1184,17 +1258,24 @@ temp_crit_reg(1);
 temp_crit_reg(2);
 temp_crit_reg(3);
 
-static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_analog_out_reg(struct device *dev,
+				   struct device_attribute *attr, char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", DAC_FROM_REG(data->analog_out));
 }
-static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+static ssize_t set_analog_out_reg(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->analog_out = DAC_TO_REG(val);
@@ -1206,7 +1287,8 @@ static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *a
 static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg,
 	set_analog_out_reg);
 
-static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
+			    char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	int vid = (data->gpio >> 11) & 0x1f;
@@ -1214,25 +1296,35 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, c
 	dev_dbg(dev, "Setting VID from GPIO11-15.\n");
 	return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm));
 }
+
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
 
-static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr,
+			    char *buf)
 {
 	struct adm1026_data *data = dev_get_drvdata(dev);
 	return sprintf(buf, "%d\n", data->vrm);
 }
-static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 	struct adm1026_data *data = dev_get_drvdata(dev);
+	unsigned long val;
+	int err;
 
-	data->vrm = simple_strtol(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	data->vrm = val;
 	return count;
 }
 
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
 
-static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms_reg(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%ld\n", data->alarms);
@@ -1277,18 +1369,24 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 24);
 static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 25);
 static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 26);
 
-static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarm_mask(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%ld\n", data->alarm_mask);
 }
-static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
 	unsigned long mask;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->alarm_mask = val & 0x7fffffff;
@@ -1313,18 +1411,24 @@ static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask,
 	set_alarm_mask);
 
 
-static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_gpio(struct device *dev, struct device_attribute *attr,
+			 char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%ld\n", data->gpio);
 }
-static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+static ssize_t set_gpio(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
 	long gpio;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->gpio = val & 0x1ffff;
@@ -1340,19 +1444,24 @@ static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const
 
 static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio);
 
-
-static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr,
+			      char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%ld\n", data->gpio_mask);
 }
-static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
 	long mask;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->gpio_mask = val & 0x1ffff;
@@ -1368,19 +1477,26 @@ static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask);
 
-static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr,
+			    char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm1.pwm));
 }
-static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+
+static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
 
 	if (data->pwm1.enable == 1) {
-		int val = simple_strtol(buf, NULL, 10);
+		long val;
+		int err;
+
+		err = kstrtol(buf, 10, &val);
+		if (err)
+			return err;
 
 		mutex_lock(&data->update_lock);
 		data->pwm1.pwm = PWM_TO_REG(val);
@@ -1389,17 +1505,26 @@ static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, co
 	}
 	return count;
 }
-static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf)
+
+static ssize_t show_auto_pwm_min(struct device *dev,
+				 struct device_attribute *attr, char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", data->pwm1.auto_pwm_min);
 }
-static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+
+static ssize_t set_auto_pwm_min(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm1.auto_pwm_min = SENSORS_LIMIT(val, 0, 255);
@@ -1411,44 +1536,53 @@ static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *att
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf)
+
+static ssize_t show_auto_pwm_max(struct device *dev,
+				 struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%d\n", ADM1026_PWM_MAX);
 }
-static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
+
+static ssize_t show_pwm_enable(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf, "%d\n", data->pwm1.enable);
 }
-static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf,
-		size_t count)
+
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
 	int old_enable;
+	unsigned long val;
+	int err;
 
-	if ((val >= 0) && (val < 3)) {
-		mutex_lock(&data->update_lock);
-		old_enable = data->pwm1.enable;
-		data->pwm1.enable = val;
-		data->config1 = (data->config1 & ~CFG1_PWM_AFC)
-				| ((val == 2) ? CFG1_PWM_AFC : 0);
-		adm1026_write_value(client, ADM1026_REG_CONFIG1,
-			data->config1);
-		if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */
-			data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
-				PWM_MIN_TO_REG(data->pwm1.auto_pwm_min));
-			adm1026_write_value(client, ADM1026_REG_PWM,
-				data->pwm1.pwm);
-		} else if (!((old_enable == 1) && (val == 1))) {
-			/* set pwm to safe value */
-			data->pwm1.pwm = 255;
-			adm1026_write_value(client, ADM1026_REG_PWM,
-				data->pwm1.pwm);
-		}
-		mutex_unlock(&data->update_lock);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	if (val >= 3)
+		return -EINVAL;
+
+	mutex_lock(&data->update_lock);
+	old_enable = data->pwm1.enable;
+	data->pwm1.enable = val;
+	data->config1 = (data->config1 & ~CFG1_PWM_AFC)
+			| ((val == 2) ? CFG1_PWM_AFC : 0);
+	adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1);
+	if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */
+		data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
+			PWM_MIN_TO_REG(data->pwm1.auto_pwm_min));
+		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
+	} else if (!((old_enable == 1) && (val == 1))) {
+		/* set pwm to safe value */
+		data->pwm1.pwm = 255;
+		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
 	}
+	mutex_unlock(&data->update_lock);
+
 	return count;
 }
 
@@ -1716,7 +1850,8 @@ static int adm1026_probe(struct i2c_client *client,
 	adm1026_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group)))
+	err = sysfs_create_group(&client->dev.kobj, &adm1026_group);
+	if (err)
 		goto exitfree;
 	if (data->config1 & CFG1_AIN8_9)
 		err = sysfs_create_group(&client->dev.kobj,
@@ -1761,20 +1896,9 @@ static int adm1026_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int __init sm_adm1026_init(void)
-{
-	return i2c_add_driver(&adm1026_driver);
-}
-
-static void __exit sm_adm1026_exit(void)
-{
-	i2c_del_driver(&adm1026_driver);
-}
+module_i2c_driver(adm1026_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
 	      "Justin Thiessen <jthiessen@penguincomputing.com>");
 MODULE_DESCRIPTION("ADM1026 driver");
-
-module_init(sm_adm1026_init);
-module_exit(sm_adm1026_exit);
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index 0b8a3b1..80cc465 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -78,7 +78,7 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
 
 #define TEMP_FROM_REG(val)	((val) * 1000)
 
-#define DIV_FROM_REG(val)	( 1 << (((val) >> 6) - 1))
+#define DIV_FROM_REG(val)	(1 << (((val) >> 6) - 1))
 
 /* Registers to be checked by adm1029_update_device() */
 static const u8 ADM1029_REG_TEMP[] = {
@@ -200,8 +200,11 @@ static ssize_t set_fan_div(struct device *dev,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm1029_data *data = i2c_get_clientdata(client);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	long val = simple_strtol(buf, NULL, 10);
 	u8 reg;
+	long val;
+	int ret = kstrtol(buf, 10, &val);
+	if (ret < 0)
+		return ret;
 
 	mutex_lock(&data->update_lock);
 
@@ -237,9 +240,9 @@ static ssize_t set_fan_div(struct device *dev,
 }
 
 /*
-Access rights on sysfs, S_IRUGO stand for Is Readable by User, Group and Others
-			S_IWUSR stand for Is Writable by User
-*/
+ * Access rights on sysfs. S_IRUGO: Is Readable by User, Group and Others
+ *			   S_IWUSR: Is Writable by User.
+ */
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
@@ -300,7 +303,8 @@ static int adm1029_detect(struct i2c_client *client,
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* ADM1029 doesn't have CHIP ID, check just MAN ID
+	/*
+	 * ADM1029 doesn't have CHIP ID, check just MAN ID
 	 * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED,
 	 * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values
 	 * documented
@@ -318,8 +322,10 @@ static int adm1029_detect(struct i2c_client *client,
 		return -ENODEV;
 
 	if ((chip_id & 0xF0) != 0x00) {
-		/* There are no "official" CHIP ID, so actually
-		 * we use Major/Minor revision for that */
+		/*
+		 * There are no "official" CHIP ID, so actually
+		 * we use Major/Minor revision for that
+		 */
 		pr_info("adm1029: Unknown major revision %x, "
 			"please let us know\n", chip_id);
 		return -ENODEV;
@@ -355,7 +361,8 @@ static int adm1029_probe(struct i2c_client *client,
 	}
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &adm1029_group)))
+	err = sysfs_create_group(&client->dev.kobj, &adm1029_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -403,8 +410,8 @@ static int adm1029_remove(struct i2c_client *client)
 }
 
 /*
-function that update the status of the chips (temperature for example)
-*/
+ * function that update the status of the chips (temperature for example)
+ */
 static struct adm1029_data *adm1029_update_device(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -446,24 +453,8 @@ static struct adm1029_data *adm1029_update_device(struct device *dev)
 	return data;
 }
 
-/*
-	Common module stuff
-*/
-static int __init sensors_adm1029_init(void)
-{
-
-	return i2c_add_driver(&adm1029_driver);
-}
-
-static void __exit sensors_adm1029_exit(void)
-{
-
-	i2c_del_driver(&adm1029_driver);
-}
+module_i2c_driver(adm1029_driver);
 
 MODULE_AUTHOR("Corentin LABBE <corentin.labbe@geomatys.fr>");
 MODULE_DESCRIPTION("adm1029 driver");
 MODULE_LICENSE("GPL v2");
-
-module_init(sensors_adm1029_init);
-module_exit(sensors_adm1029_exit);
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 97e2cfb..ff37363 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -1,25 +1,25 @@
 /*
-  adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
-  monitoring
-  Based on lm75.c and lm85.c
-  Supports adm1030 / adm1031
-  Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org>
-  Reworked by Jean Delvare <khali@linux-fr.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.
-*/
+ * adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Based on lm75.c and lm85.c
+ * Supports adm1030 / adm1031
+ * Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org>
+ * Reworked by Jean Delvare <khali@linux-fr.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/module.h>
 #include <linux/init.h>
@@ -80,7 +80,8 @@ struct adm1031_data {
 	char valid;		/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned int update_interval;	/* In milliseconds */
-	/* The chan_select_table contains the possible configurations for
+	/*
+	 * The chan_select_table contains the possible configurations for
 	 * auto fan control.
 	 */
 	const auto_chan_table_t *chan_select_table;
@@ -205,7 +206,8 @@ static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
 #define GET_FAN_AUTO_BITFIELD(data, idx)	\
 	(*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx % 2]
 
-/* The tables below contains the possible values for the auto fan
+/*
+ * The tables below contains the possible values for the auto fan
  * control bitfields. the index in the table is the register value.
  * MSb is the auto fan control enable bit, so the four first entries
  * in the table disables auto fan control when both bitfields are zero.
@@ -226,7 +228,8 @@ static const auto_chan_table_t auto_channel_select_table_adm1030 = {
 	{ 3 /* 0b11 */		, 0 },
 };
 
-/* That function checks if a bitfield is valid and returns the other bitfield
+/*
+ * That function checks if a bitfield is valid and returns the other bitfield
  * nearest match if no exact match where found.
  */
 static int
@@ -252,7 +255,8 @@ get_fan_auto_nearest(struct adm1031_data *data,
 			break;
 		} else if (val == (*data->chan_select_table)[i][chan] &&
 			   first_match == -1) {
-			/* Save the first match in case of an exact match has
+			/*
+			 * Save the first match in case of an exact match has
 			 * not been found
 			 */
 			first_match = i;
@@ -306,9 +310,11 @@ set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
 	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^
 	    (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
 		if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
-			/* Switch to Auto Fan Mode
+			/*
+			 * Switch to Auto Fan Mode
 			 * Save PWM registers
-			 * Set PWM registers to 33% Both */
+			 * Set PWM registers to 33% Both
+			 */
 			data->old_pwm[0] = data->pwm[0];
 			data->old_pwm[1] = data->pwm[1];
 			adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
@@ -1131,19 +1137,8 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_adm1031_init(void)
-{
-	return i2c_add_driver(&adm1031_driver);
-}
-
-static void __exit sensors_adm1031_exit(void)
-{
-	i2c_del_driver(&adm1031_driver);
-}
+module_i2c_driver(adm1031_driver);
 
 MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>");
 MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_adm1031_init);
-module_exit(sensors_adm1031_exit);
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 3f63f5f..c3c2865 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -1,12 +1,12 @@
 /*
  * adm9240.c	Part of lm_sensors, Linux kernel modules for hardware
- * 		monitoring
+ *		monitoring
  *
  * Copyright (C) 1999	Frodo Looijaard <frodol@dds.nl>
  *			Philip Edelbrock <phil@netroedge.com>
  * Copyright (C) 2003	Michiel Rook <michiel@grendelproject.nl>
  * Copyright (C) 2005	Grant Coady <gcoady.lk@gmail.com> with valuable
- * 				guidance from Jean Delvare
+ *				guidance from Jean Delvare
  *
  * Driver supports	Analog Devices		ADM9240
  *			Dallas Semiconductor	DS1780
@@ -204,7 +204,12 @@ static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm9240_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[attr->index] = TEMP_TO_REG(val);
@@ -255,7 +260,12 @@ static ssize_t set_in_min(struct device *dev,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm9240_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[attr->index] = IN_TO_REG(val, attr->index);
@@ -272,7 +282,12 @@ static ssize_t set_in_max(struct device *dev,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm9240_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[attr->index] = IN_TO_REG(val, attr->index);
@@ -283,7 +298,7 @@ static ssize_t set_in_max(struct device *dev,
 }
 
 #define vin(nr)							\
-static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO, 		\
+static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO,		\
 		show_in, NULL, nr);				\
 static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR,	\
 		show_in_min, set_in_min, nr);			\
@@ -357,9 +372,14 @@ static ssize_t set_fan_min(struct device *dev,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm9240_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int nr = attr->index;
 	u8 new_div;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -465,7 +485,12 @@ static ssize_t set_aout(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct adm9240_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->aout = AOUT_TO_REG(val);
@@ -481,7 +506,12 @@ static ssize_t chassis_clear_legacy(struct device *dev,
 		const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
-	unsigned long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	dev_warn(dev, "Attribute chassis_clear is deprecated, "
 		 "use intrusion0_alarm instead\n");
@@ -632,7 +662,8 @@ static int adm9240_probe(struct i2c_client *new_client,
 	adm9240_init_client(new_client);
 
 	/* populate sysfs filesystem */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group)))
+	err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -681,8 +712,7 @@ static void adm9240_init_client(struct i2c_client *client)
 	} else { /* cold start: open limits before starting chip */
 		int i;
 
-		for (i = 0; i < 6; i++)
-		{
+		for (i = 0; i < 6; i++) {
 			i2c_smbus_write_byte_data(client,
 					ADM9240_REG_IN_MIN(i), 0);
 			i2c_smbus_write_byte_data(client,
@@ -717,8 +747,7 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
 	if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
 			|| !data->valid) {
 
-		for (i = 0; i < 6; i++) /* read voltages */
-		{
+		for (i = 0; i < 6; i++) { /* read voltages */
 			data->in[i] = i2c_smbus_read_byte_data(client,
 					ADM9240_REG_IN(i));
 		}
@@ -727,16 +756,17 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
 					i2c_smbus_read_byte_data(client,
 					ADM9240_REG_INT(1)) << 8;
 
-		/* read temperature: assume temperature changes less than
+		/*
+		 * read temperature: assume temperature changes less than
 		 * 0.5'C per two measurement cycles thus ignore possible
-		 * but unlikely aliasing error on lsb reading. --Grant */
+		 * but unlikely aliasing error on lsb reading. --Grant
+		 */
 		data->temp = ((i2c_smbus_read_byte_data(client,
 					ADM9240_REG_TEMP) << 8) |
 					i2c_smbus_read_byte_data(client,
 					ADM9240_REG_TEMP_CONF)) / 128;
 
-		for (i = 0; i < 2; i++) /* read fans */
-		{
+		for (i = 0; i < 2; i++) { /* read fans */
 			data->fan[i] = i2c_smbus_read_byte_data(client,
 					ADM9240_REG_FAN(i));
 
@@ -760,15 +790,13 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
 	if (time_after(jiffies, data->last_updated_config + (HZ * 300))
 			|| !data->valid) {
 
-		for (i = 0; i < 6; i++)
-		{
+		for (i = 0; i < 6; i++) {
 			data->in_min[i] = i2c_smbus_read_byte_data(client,
 					ADM9240_REG_IN_MIN(i));
 			data->in_max[i] = i2c_smbus_read_byte_data(client,
 					ADM9240_REG_IN_MAX(i));
 		}
-		for (i = 0; i < 2; i++)
-		{
+		for (i = 0; i < 2; i++) {
 			data->fan_min[i] = i2c_smbus_read_byte_data(client,
 					ADM9240_REG_FAN_MIN(i));
 		}
@@ -795,21 +823,9 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_adm9240_init(void)
-{
-	return i2c_add_driver(&adm9240_driver);
-}
-
-static void __exit sensors_adm9240_exit(void)
-{
-	i2c_del_driver(&adm9240_driver);
-}
+module_i2c_driver(adm9240_driver);
 
 MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
 		"Grant Coady <gcoady.lk@gmail.com> and others");
 MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_adm9240_init);
-module_exit(sensors_adm9240_exit);
-
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index eedca3c..60be358 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -306,19 +306,8 @@ static struct i2c_driver ads1015_driver = {
 	.id_table = ads1015_id,
 };
 
-static int __init sensors_ads1015_init(void)
-{
-	return i2c_add_driver(&ads1015_driver);
-}
-
-static void __exit sensors_ads1015_exit(void)
-{
-	i2c_del_driver(&ads1015_driver);
-}
+module_i2c_driver(ads1015_driver);
 
 MODULE_AUTHOR("Dirk Eibach <eibach@gdsys.de>");
 MODULE_DESCRIPTION("ADS1015 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_ads1015_init);
-module_exit(sensors_ads1015_exit);
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index ed60242..bf3fdf4 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -1,27 +1,27 @@
 /*
-	ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC
-	(C) 2007 EADS Astrium
-
-	This driver is based on the lm75 and other lm_sensors/hwmon drivers
-
-	Written by Steve Hardy <shardy@redhat.com>
-
-	Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf
-
-	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.
-*/
+ * ads7828.c - lm_sensors driver for ads7828 12-bit 8-channel ADC
+ * (C) 2007 EADS Astrium
+ *
+ * This driver is based on the lm75 and other lm_sensors/hwmon drivers
+ *
+ * Written by Steve Hardy <shardy@redhat.com>
+ *
+ * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads7828.pdf
+ *
+ * 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>
@@ -188,12 +188,13 @@ static int ads7828_detect(struct i2c_client *client,
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
 		return -ENODEV;
 
-	/* Now, we do the remaining detection. There is no identification
-	dedicated register so attempt to sanity check using knowledge of
-	the chip
-	- Read from the 8 channel addresses
-	- Check the top 4 bits of each result are not set (12 data bits)
-	*/
+	/*
+	 * Now, we do the remaining detection. There is no identification
+	 * dedicated register so attempt to sanity check using knowledge of
+	 * the chip
+	 * - Read from the 8 channel addresses
+	 * - Check the top 4 bits of each result are not set (12 data bits)
+	 */
 	for (ch = 0; ch < ADS7828_NCH; ch++) {
 		u16 in_data;
 		u8 cmd = channel_cmd_byte(ch);
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c
index 04450f8..e65c6e4 100644
--- a/drivers/hwmon/ads7871.c
+++ b/drivers/hwmon/ads7871.c
@@ -34,9 +34,11 @@
 #define REG_SER_CONTROL 24 /*Serial Interface Control Register*/
 #define REG_ID		31 /*ID Register*/
 
-/*From figure 17 in the datasheet
-* These bits get ORed with the address to form
-* the instruction byte */
+/*
+ * From figure 17 in the datasheet
+ * These bits get ORed with the address to form
+ * the instruction byte
+ */
 /*Instruction Bit masks*/
 #define INST_MODE_bm	(1<<7)
 #define INST_READ_bm	(1<<6)
@@ -105,8 +107,10 @@ static ssize_t show_voltage(struct device *dev,
 	uint8_t channel, mux_cnv;
 
 	channel = attr->index;
-	/*TODO: add support for conversions
-	 *other than single ended with a gain of 1*/
+	/*
+	 * TODO: add support for conversions
+	 * other than single ended with a gain of 1
+	 */
 	/*MUX_M3_bm forces single ended*/
 	/*This is also where the gain of the PGA would be set*/
 	ads7871_write_reg8(spi, REG_GAIN_MUX,
@@ -114,8 +118,10 @@ static ssize_t show_voltage(struct device *dev,
 
 	ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
 	mux_cnv = ((ret & MUX_CNV_bm)>>MUX_CNV_bv);
-	/*on 400MHz arm9 platform the conversion
-	 *is already done when we do this test*/
+	/*
+	 * on 400MHz arm9 platform the conversion
+	 * is already done when we do this test
+	 */
 	while ((i < 2) && mux_cnv) {
 		i++;
 		ret = ads7871_read_reg8(spi, REG_GAIN_MUX);
@@ -179,8 +185,10 @@ static int __devinit ads7871_probe(struct spi_device *spi)
 	ret = ads7871_read_reg8(spi, REG_OSC_CONTROL);
 
 	dev_dbg(&spi->dev, "REG_OSC_CONTROL write:%x, read:%x\n", val, ret);
-	/*because there is no other error checking on an SPI bus
-	we need to make sure we really have a chip*/
+	/*
+	 * because there is no other error checking on an SPI bus
+	 * we need to make sure we really have a chip
+	 */
 	if (val != ret) {
 		err = -ENODEV;
 		goto exit;
@@ -234,18 +242,7 @@ static struct spi_driver ads7871_driver = {
 	.remove = __devexit_p(ads7871_remove),
 };
 
-static int __init ads7871_init(void)
-{
-	return spi_register_driver(&ads7871_driver);
-}
-
-static void __exit ads7871_exit(void)
-{
-	spi_unregister_driver(&ads7871_driver);
-}
-
-module_init(ads7871_init);
-module_exit(ads7871_exit);
+module_spi_driver(ads7871_driver);
 
 MODULE_AUTHOR("Paul Thomas <pthomas8589@gmail.com>");
 MODULE_DESCRIPTION("TI ADS7871 A/D driver");
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index 5b02f7a..71bacc5 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -8,7 +8,7 @@
  *  published by the Free Software Foundation.
  *
  *  TODO: SPI, support for external temperature sensor
- * 	  use power-down mode for suspend?, interrupt handling?
+ *	  use power-down mode for suspend?, interrupt handling?
  */
 
 #include <linux/kernel.h>
@@ -348,17 +348,7 @@ static struct i2c_driver adt7411_driver = {
 	.class = I2C_CLASS_HWMON,
 };
 
-static int __init sensors_adt7411_init(void)
-{
-	return i2c_add_driver(&adt7411_driver);
-}
-module_init(sensors_adt7411_init)
-
-static void __exit sensors_adt7411_exit(void)
-{
-	i2c_del_driver(&adt7411_driver);
-}
-module_exit(sensors_adt7411_exit)
+module_i2c_driver(adt7411_driver);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and "
 	"Wolfram Sang <w.sang@pengutronix.de>");
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index 7a14948..339269f 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -65,8 +65,8 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
 #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR	0x5F
 #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR	0x60
 #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR	0x63
-#define 	ADT7462_PWM_HYST_MASK		0x0F
-#define 	ADT7462_PWM_RANGE_MASK		0xF0
+#define	ADT7462_PWM_HYST_MASK			0x0F
+#define	ADT7462_PWM_RANGE_MASK			0xF0
 #define		ADT7462_PWM_RANGE_SHIFT		4
 #define ADT7462_REG_PWM_CFG_BASE_ADDR		0x21
 #define ADT7462_REG_PWM_CFG_MAX_ADDR		0x24
@@ -85,7 +85,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
 #define		ADT7462_PIN15_INPUT		0x20
 #define		ADT7462_PIN13_INPUT		0x40
 #define		ADT7462_PIN8_INPUT		0x80
-#define 	ADT7462_PIN23_MASK		0x03
+#define		ADT7462_PIN23_MASK		0x03
 #define		ADT7462_PIN23_SHIFT		0
 #define		ADT7462_PIN26_MASK		0x0C	/* cfg2 */
 #define		ADT7462_PIN26_SHIFT		2
@@ -99,7 +99,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
 #define		ADT7462_PIN28_VOLT		0x5
 
 #define ADT7462_REG_ALARM1			0xB8
-#define 	ADT7462_LT_ALARM		0x02
+#define	ADT7462_LT_ALARM			0x02
 #define		ADT7462_R1T_ALARM		0x04
 #define		ADT7462_R2T_ALARM		0x08
 #define		ADT7462_R3T_ALARM		0x10
@@ -135,9 +135,9 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
 #define ADT7462_ALARM_FLAG_MASK			0x0F
 
 #define ADT7462_TEMP_COUNT		4
-#define ADT7462_TEMP_REG(x)		(ADT7462_REG_TEMP_BASE_ADDR + (x * 2))
-#define ADT7462_TEMP_MIN_REG(x) 	(ADT7462_REG_MIN_TEMP_BASE_ADDR + (x))
-#define ADT7462_TEMP_MAX_REG(x) 	(ADT7462_REG_MAX_TEMP_BASE_ADDR + (x))
+#define ADT7462_TEMP_REG(x)		(ADT7462_REG_TEMP_BASE_ADDR + ((x) * 2))
+#define ADT7462_TEMP_MIN_REG(x)		(ADT7462_REG_MIN_TEMP_BASE_ADDR + (x))
+#define ADT7462_TEMP_MAX_REG(x)		(ADT7462_REG_MAX_TEMP_BASE_ADDR + (x))
 #define TEMP_FRAC_OFFSET		6
 
 #define ADT7462_FAN_COUNT		8
@@ -1727,8 +1727,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
 
-static struct attribute *adt7462_attr[] =
-{
+static struct attribute *adt7462_attr[] = {
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp3_max.dev_attr.attr,
@@ -1975,19 +1974,8 @@ static int adt7462_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int __init adt7462_init(void)
-{
-	return i2c_add_driver(&adt7462_driver);
-}
-
-static void __exit adt7462_exit(void)
-{
-	i2c_del_driver(&adt7462_driver);
-}
+module_i2c_driver(adt7462_driver);
 
 MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
 MODULE_DESCRIPTION("ADT7462 driver");
 MODULE_LICENSE("GPL");
-
-module_init(adt7462_init);
-module_exit(adt7462_exit);
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c
index 5e10c79..54ec890 100644
--- a/drivers/hwmon/adt7470.c
+++ b/drivers/hwmon/adt7470.c
@@ -1131,8 +1131,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
 
-static struct attribute *adt7470_attr[] =
-{
+static struct attribute *adt7470_attr[] = {
 	&dev_attr_alarm_mask.attr,
 	&dev_attr_num_temp_sensors.attr,
 	&dev_attr_auto_update_interval.attr,
@@ -1276,7 +1275,8 @@ static int adt7470_probe(struct i2c_client *client,
 
 	/* Register sysfs hooks */
 	data->attrs.attrs = adt7470_attr;
-	if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
+	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -1317,19 +1317,8 @@ static int adt7470_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int __init adt7470_init(void)
-{
-	return i2c_add_driver(&adt7470_driver);
-}
-
-static void __exit adt7470_exit(void)
-{
-	i2c_del_driver(&adt7470_driver);
-}
+module_i2c_driver(adt7470_driver);
 
 MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
 MODULE_DESCRIPTION("ADT7470 driver");
 MODULE_LICENSE("GPL");
-
-module_init(adt7470_init);
-module_exit(adt7470_exit);
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 7dab354..df29d13 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -32,9 +32,10 @@
 #define THERM		5
 #define HYSTERSIS	6
 
-/* These are unique identifiers for the sysfs functions - unlike the
-   numbers above, these are not also indexes into an array
-*/
+/*
+ * These are unique identifiers for the sysfs functions - unlike the
+ * numbers above, these are not also indexes into an array
+ */
 
 #define ALARM		9
 #define FAULT		10
@@ -288,8 +289,10 @@ static void adt7475_write_word(struct i2c_client *client, int reg, u16 val)
 	i2c_smbus_write_byte_data(client, reg, val & 0xFF);
 }
 
-/* Find the nearest value in a table - used for pwm frequency and
-   auto temp range */
+/*
+ * Find the nearest value in a table - used for pwm frequency and
+ * auto temp range
+ */
 static int find_nearest(long val, const int *array, int size)
 {
 	int i;
@@ -385,16 +388,20 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
 			out = (out >> 4) & 0xF;
 		else
 			out = (out & 0xF);
-		/* Show the value as an absolute number tied to
-		 * THERM */
+		/*
+		 * Show the value as an absolute number tied to
+		 * THERM
+		 */
 		out = reg2temp(data, data->temp[THERM][sattr->index]) -
 			out * 1000;
 		mutex_unlock(&data->lock);
 		break;
 
 	case OFFSET:
-		/* Offset is always 2's complement, regardless of the
-		 * setting in CONFIG5 */
+		/*
+		 * Offset is always 2's complement, regardless of the
+		 * setting in CONFIG5
+		 */
 		mutex_lock(&data->lock);
 		out = (s8)data->temp[sattr->nr][sattr->index];
 		if (data->config5 & CONFIG5_TEMPOFFSET)
@@ -452,8 +459,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
 		break;
 
 	case HYSTERSIS:
-		/* The value will be given as an absolute value, turn it
-		   into an offset based on THERM */
+		/*
+		 * The value will be given as an absolute value, turn it
+		 * into an offset based on THERM
+		 */
 
 		/* Read fresh THERM and HYSTERSIS values from the chip */
 		data->temp[THERM][sattr->index] =
@@ -478,8 +487,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
 	default:
 		data->temp[sattr->nr][sattr->index] = temp2reg(data, val);
 
-		/* We maintain an extra 2 digits of precision for simplicity
-		 * - shift those back off before writing the value */
+		/*
+		 * We maintain an extra 2 digits of precision for simplicity
+		 * - shift those back off before writing the value
+		 */
 		out = (u8) (data->temp[sattr->nr][sattr->index] >> 2);
 	}
 
@@ -514,8 +525,10 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-/* Table of autorange values - the user will write the value in millidegrees,
-   and we'll convert it */
+/*
+ * Table of autorange values - the user will write the value in millidegrees,
+ * and we'll convert it
+ */
 static const int autorange_table[] = {
 	2000, 2500, 3330, 4000, 5000, 6670, 8000,
 	10000, 13330, 16000, 20000, 26670, 32000, 40000,
@@ -558,8 +571,10 @@ static ssize_t set_point2(struct device *dev, struct device_attribute *attr,
 	data->range[sattr->index] =
 		adt7475_read(TEMP_TRANGE_REG(sattr->index));
 
-	/* The user will write an absolute value, so subtract the start point
-	   to figure the range */
+	/*
+	 * The user will write an absolute value, so subtract the start point
+	 * to figure the range
+	 */
 	temp = reg2temp(data, data->temp[AUTOMIN][sattr->index]);
 	val = SENSORS_LIMIT(val, temp + autorange_table[0],
 		temp + autorange_table[ARRAY_SIZE(autorange_table) - 1]);
@@ -664,8 +679,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		data->pwm[CONTROL][sattr->index] =
 			adt7475_read(PWM_CONFIG_REG(sattr->index));
 
-		/* If we are not in manual mode, then we shouldn't allow
-		 * the user to set the pwm speed */
+		/*
+		 * If we are not in manual mode, then we shouldn't allow
+		 * the user to set the pwm speed
+		 */
 		if (((data->pwm[CONTROL][sattr->index] >> 5) & 7) != 7) {
 			mutex_unlock(&data->lock);
 			return count;
@@ -1232,7 +1249,7 @@ static void adt7475_remove_files(struct i2c_client *client,
 static int adt7475_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
-	static const char *names[] = {
+	static const char * const names[] = {
 		[adt7473] = "ADT7473",
 		[adt7475] = "ADT7475",
 		[adt7476] = "ADT7476",
@@ -1280,9 +1297,11 @@ static int adt7475_probe(struct i2c_client *client,
 	if ((data->config4 & CONFIG4_PINFUNC) == 0x0)
 		data->has_fan4 = 1;
 
-	/* THERM configuration is more complex on the ADT7476 and ADT7490,
-	   because 2 different pins (TACH4 and +2.5 Vin) can be used for
-	   this function */
+	/*
+	 * THERM configuration is more complex on the ADT7476 and ADT7490,
+	 * because 2 different pins (TACH4 and +2.5 Vin) can be used for
+	 * this function
+	 */
 	if (id->driver_data == adt7490) {
 		if ((data->config4 & CONFIG4_PINFUNC) == 0x1 &&
 		    !(config3 & CONFIG3_THERM))
@@ -1294,8 +1313,10 @@ static int adt7475_probe(struct i2c_client *client,
 			data->has_voltage |= (1 << 0);		/* in0 */
 	}
 
-	/* On the ADT7476, the +12V input pin may instead be used as VID5,
-	   and VID pins may alternatively be used as GPIO */
+	/*
+	 * On the ADT7476, the +12V input pin may instead be used as VID5,
+	 * and VID pins may alternatively be used as GPIO
+	 */
 	if (id->driver_data == adt7476) {
 		u8 vid = adt7475_read(REG_VID);
 		if (!(vid & VID_VIDSEL))
@@ -1314,8 +1335,10 @@ static int adt7475_probe(struct i2c_client *client,
 	}
 	data->bypass_attn &= data->has_voltage;
 
-	/* Call adt7475_read_pwm for all pwm's as this will reprogram any
-	   pwm's which are disabled to manual mode with 0% duty cycle */
+	/*
+	 * Call adt7475_read_pwm for all pwm's as this will reprogram any
+	 * pwm's which are disabled to manual mode with 0% duty cycle
+	 */
 	for (i = 0; i < ADT7475_PWM_COUNT; i++)
 		adt7475_read_pwm(client, i);
 
@@ -1431,8 +1454,10 @@ static void adt7475_read_pwm(struct i2c_client *client, int index)
 
 	data->pwm[CONTROL][index] = adt7475_read(PWM_CONFIG_REG(index));
 
-	/* Figure out the internal value for pwmctrl and pwmchan
-	   based on the current settings */
+	/*
+	 * Figure out the internal value for pwmctrl and pwmchan
+	 * based on the current settings
+	 */
 	v = (data->pwm[CONTROL][index] >> 5) & 7;
 
 	if (v == 3)
@@ -1440,10 +1465,11 @@ static void adt7475_read_pwm(struct i2c_client *client, int index)
 	else if (v == 7)
 		data->pwmctl[index] = 1;
 	else if (v == 4) {
-		/* The fan is disabled - we don't want to
-		   support that, so change to manual mode and
-		   set the duty cycle to 0 instead
-		*/
+		/*
+		 * The fan is disabled - we don't want to
+		 * support that, so change to manual mode and
+		 * set the duty cycle to 0 instead
+		 */
 		data->pwm[INPUT][index] = 0;
 		data->pwm[CONTROL][index] &= ~0xE0;
 		data->pwm[CONTROL][index] |= (7 << 5);
@@ -1600,19 +1626,8 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_adt7475_init(void)
-{
-	return i2c_add_driver(&adt7475_driver);
-}
-
-static void __exit sensors_adt7475_exit(void)
-{
-	i2c_del_driver(&adt7475_driver);
-}
+module_i2c_driver(adt7475_driver);
 
 MODULE_AUTHOR("Advanced Micro Devices, Inc");
 MODULE_DESCRIPTION("adt7475 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_adt7475_init);
-module_exit(sensors_adt7475_exit);
diff --git a/drivers/hwmon/amc6821.c b/drivers/hwmon/amc6821.c
index 89a6b9d..f600fa1 100644
--- a/drivers/hwmon/amc6821.c
+++ b/drivers/hwmon/amc6821.c
@@ -1,25 +1,25 @@
 /*
-	amc6821.c - Part of lm_sensors, Linux kernel modules for hardware
-	monitoring
-	Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si>
-
-	Based on max6650.c:
-	Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.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.
-*/
+ * amc6821.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si>
+ *
+ * Based on max6650.c:
+ * Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.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.
+ */
 
 
 #include <linux/kernel.h>	/* Needed for KERN_INFO */
@@ -47,7 +47,7 @@ static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
  * Insmod parameters
  */
 
-static int pwminv = 0;	/*Inverted PWM output. */
+static int pwminv;	/*Inverted PWM output. */
 module_param(pwminv, int, S_IRUGO);
 
 static int init = 1; /*Power-on initialization.*/
@@ -188,7 +188,7 @@ static struct i2c_driver amc6821_driver = {
 
 /*
  * Client data (each client gets its own)
-  */
+ */
 
 struct amc6821_data {
 	struct device *hwmon_dev;
@@ -836,8 +836,10 @@ static int amc6821_detect(
 		return -ENODEV;
 	}
 
-	/* Bit 7 of the address register is ignored, so we can check the
-	   ID registers again */
+	/*
+	 * Bit 7 of the address register is ignored, so we can check the
+	 * ID registers again
+	 */
 	dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID);
 	comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID);
 	if (dev_id != 0x21 || comp_id != 0x49) {
@@ -1080,9 +1082,10 @@ static struct amc6821_data *amc6821_update_device(struct device *dev)
 			data->pwm1_auto_channels_temp = 3;
 			data->pwm1_enable = 3;
 			break;
-		case 1: /*semi-open loop: software sets rpm, chip controls pwm1,
-			  *currently not implemented
-			  */
+		case 1: /*
+			 * semi-open loop: software sets rpm, chip controls
+			 * pwm1, currently not implemented
+			 */
 			data->pwm1_auto_channels_temp = 0;
 			data->pwm1_enable = 0;
 			break;
@@ -1095,20 +1098,7 @@ static struct amc6821_data *amc6821_update_device(struct device *dev)
 	return data;
 }
 
-
-static int __init amc6821_init(void)
-{
-	return i2c_add_driver(&amc6821_driver);
-}
-
-static void __exit amc6821_exit(void)
-{
-	i2c_del_driver(&amc6821_driver);
-}
-
-module_init(amc6821_init);
-module_exit(amc6821_exit);
-
+module_i2c_driver(amc6821_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("T. Mertelj <tomaz.mertelj@guest.arnes.si>");
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index b989553..f082e48 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -344,8 +344,10 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key)
 	while (begin != end) {
 		int middle = begin + (end - begin) / 2;
 		entry = applesmc_get_entry_by_index(middle);
-		if (IS_ERR(entry))
+		if (IS_ERR(entry)) {
+			*lo = 0;
 			return PTR_ERR(entry);
+		}
 		if (strcmp(entry->key, key) < 0)
 			begin = middle + 1;
 		else
@@ -364,8 +366,10 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key)
 	while (begin != end) {
 		int middle = begin + (end - begin) / 2;
 		entry = applesmc_get_entry_by_index(middle);
-		if (IS_ERR(entry))
+		if (IS_ERR(entry)) {
+			*hi = smcreg.key_count;
 			return PTR_ERR(entry);
+		}
 		if (strcmp(key, entry->key) < 0)
 			end = middle;
 		else
@@ -1189,8 +1193,10 @@ static int applesmc_dmi_match(const struct dmi_system_id *id)
 	return 1;
 }
 
-/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
- * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
+/*
+ * Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
+ * So we need to put "Apple MacBook Pro" before "Apple MacBook".
+ */
 static __initdata struct dmi_system_id applesmc_whitelist[] = {
 	{ applesmc_dmi_match, "Apple MacBook Air", {
 	  DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index d7bd1f3..4b8814d 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -1,40 +1,40 @@
 /*
-    asb100.c - Part of lm_sensors, Linux kernel modules for hardware
-	        monitoring
-
-    Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
-
-	(derived from w83781d.c)
-
-    Copyright (C) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>, and
-    Mark Studebaker <mdsxyz123@yahoo.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * asb100.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	      monitoring
+ *
+ * Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
+ *
+ * (derived from w83781d.c)
+ *
+ * Copyright (C) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
+ *			      Philip Edelbrock <phil@netroedge.com>, and
+ *			      Mark Studebaker <mdsxyz123@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 /*
-    This driver supports the hardware sensor chips: Asus ASB100 and
-    ASB100-A "BACH".
-
-    ASB100-A supports pwm1, while plain ASB100 does not.  There is no known
-    way for the driver to tell which one is there.
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    asb100	7	3	1	4	0x31	0x0694	yes	no
-*/
+ * This driver supports the hardware sensor chips: Asus ASB100 and
+ * ASB100-A "BACH".
+ *
+ * ASB100-A supports pwm1, while plain ASB100 does not.  There is no known
+ * way for the driver to tell which one is there.
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * asb100	7	3	1	4	0x31	0x0694	yes	no
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -99,15 +99,19 @@ static const u16 asb100_reg_temp_hyst[]	= {0, 0x3a, 0x153, 0x253, 0x19};
 /* bit 7 -> enable, bits 0-3 -> duty cycle */
 #define ASB100_REG_PWM1		0x59
 
-/* CONVERSIONS
-   Rounding and limit checking is only done on the TO_REG variants. */
+/*
+ * CONVERSIONS
+ * Rounding and limit checking is only done on the TO_REG variants.
+ */
 
 /* These constants are a guess, consistent w/ w83781d */
-#define ASB100_IN_MIN (   0)
-#define ASB100_IN_MAX (4080)
+#define ASB100_IN_MIN		0
+#define ASB100_IN_MAX		4080
 
-/* IN: 1/1000 V (0V to 4.08V)
-   REG: 16mV/bit */
+/*
+ * IN: 1/1000 V (0V to 4.08V)
+ * REG: 16mV/bit
+ */
 static u8 IN_TO_REG(unsigned val)
 {
 	unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX);
@@ -131,19 +135,21 @@ static u8 FAN_TO_REG(long rpm, int div)
 
 static int FAN_FROM_REG(u8 val, int div)
 {
-	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+	return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div);
 }
 
 /* These constants are a guess, consistent w/ w83781d */
-#define ASB100_TEMP_MIN (-128000)
-#define ASB100_TEMP_MAX ( 127000)
+#define ASB100_TEMP_MIN		-128000
+#define ASB100_TEMP_MAX		127000
 
-/* TEMP: 0.001C/bit (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: 0.001C/bit (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static u8 TEMP_TO_REG(long temp)
 {
 	int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX);
-	ntemp += (ntemp<0 ? -500 : 500);
+	ntemp += (ntemp < 0 ? -500 : 500);
 	return (u8)(ntemp / 1000);
 }
 
@@ -152,8 +158,10 @@ static int TEMP_FROM_REG(u8 reg)
 	return (s8)reg * 1000;
 }
 
-/* PWM: 0 - 255 per sensors documentation
-   REG: (6.25% duty cycle per bit) */
+/*
+ * PWM: 0 - 255 per sensors documentation
+ * REG: (6.25% duty cycle per bit)
+ */
 static u8 ASB100_PWM_TO_REG(int pwm)
 {
 	pwm = SENSORS_LIMIT(pwm, 0, 255);
@@ -167,16 +175,20 @@ static int ASB100_PWM_FROM_REG(u8 reg)
 
 #define DIV_FROM_REG(val) (1 << (val))
 
-/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
-   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
+/*
+ * FAN DIV: 1, 2, 4, or 8 (defaults to 2)
+ * REG: 0, 1, 2, or 3 (respectively) (defaults to 1)
+ */
 static u8 DIV_TO_REG(long val)
 {
-	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
+	return val == 8 ? 3 : val == 4 ? 2 : val == 1 ? 0 : 1;
 }
 
-/* For each registered client, we need to keep some data in memory. That
-   data is pointed to by client->data. The structure itself is
-   dynamically allocated, at the same time the client itself is allocated. */
+/*
+ * For each registered client, we need to keep some data in memory. That
+ * data is pointed to by client->data. The structure itself is
+ * dynamically allocated, at the same time the client itself is allocated.
+ */
 struct asb100_data {
 	struct device *hwmon_dev;
 	struct mutex lock;
@@ -253,8 +265,10 @@ static ssize_t set_in_##reg(struct device *dev, struct device_attribute *attr, \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct asb100_data *data = i2c_get_clientdata(client); \
-	unsigned long val = simple_strtoul(buf, NULL, 10); \
- \
+	unsigned long val; \
+	int err = kstrtoul(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
 	data->in_##reg[nr] = IN_TO_REG(val); \
 	asb100_write_value(client, ASB100_REG_IN_##REG(nr), \
@@ -315,7 +329,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct asb100_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -324,10 +343,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
@@ -335,8 +356,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct asb100_data *data = i2c_get_clientdata(client);
 	unsigned long min;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -421,8 +447,10 @@ static ssize_t set_##reg(struct device *dev, struct device_attribute *attr, \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct asb100_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
+	long val; \
+	int err = kstrtol(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
 	switch (nr) { \
 	case 1: case 2: \
@@ -476,7 +504,13 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct asb100_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	data->vrm = val;
 	return count;
 }
 
@@ -524,7 +558,12 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct asb100_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm &= 0x80; /* keep the enable bit */
@@ -546,7 +585,12 @@ static ssize_t set_pwm_enable1(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct asb100_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm &= 0x0f; /* keep the duty cycle bits */
@@ -768,7 +812,8 @@ static int asb100_probe(struct i2c_client *client,
 	data->fan_min[2] = asb100_read_value(client, ASB100_REG_FAN_MIN(2));
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &asb100_group)))
+	err = sysfs_create_group(&client->dev.kobj, &asb100_group);
+	if (err)
 		goto ERROR3;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -805,8 +850,10 @@ static int asb100_remove(struct i2c_client *client)
 	return 0;
 }
 
-/* The SMBus locks itself, usually, but nothing may access the chip between
-   bank switches. */
+/*
+ * The SMBus locks itself, usually, but nothing may access the chip between
+ * bank switches.
+ */
 static int asb100_read_value(struct i2c_client *client, u16 reg)
 {
 	struct asb100_data *data = i2c_get_clientdata(client);
@@ -971,19 +1018,8 @@ static struct asb100_data *asb100_update_device(struct device *dev)
 	return data;
 }
 
-static int __init asb100_init(void)
-{
-	return i2c_add_driver(&asb100_driver);
-}
-
-static void __exit asb100_exit(void)
-{
-	i2c_del_driver(&asb100_driver);
-}
+module_i2c_driver(asb100_driver);
 
 MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
 MODULE_DESCRIPTION("ASB100 Bach driver");
 MODULE_LICENSE("GPL");
-
-module_init(asb100_init);
-module_exit(asb100_exit);
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
index 3efd324..7caa242 100644
--- a/drivers/hwmon/asc7621.c
+++ b/drivers/hwmon/asc7621.c
@@ -268,9 +268,11 @@ static ssize_t store_fan16(struct device *dev,
 	if (kstrtol(buf, 10, &reqval))
 		return -EINVAL;
 
-	/* If a minimum RPM of zero is requested, then we set the register to
-	   0xffff. This value allows the fan to be stopped completely without
-	   generating an alarm. */
+	/*
+	 * If a minimum RPM of zero is requested, then we set the register to
+	 * 0xffff. This value allows the fan to be stopped completely without
+	 * generating an alarm.
+	 */
 	reqval =
 	    (reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe));
 
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index 00e9851..351d1f4 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -38,7 +38,8 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = {
 	{ }
 };
 
-/* Minimum time between readings, enforced in order to avoid
+/*
+ * Minimum time between readings, enforced in order to avoid
  * hogging the CPU.
  */
 #define CACHE_TIME		HZ
@@ -161,7 +162,8 @@ struct atk_sensor_data {
 	char const *acpi_name;
 };
 
-/* Return buffer format:
+/*
+ * Return buffer format:
  * [0-3] "value" is valid flag
  * [4-7] value
  * [8- ] unknown stuff on newer mobos
@@ -310,7 +312,8 @@ static union acpi_object *atk_get_pack_member(struct atk_data *data,
 }
 
 
-/* New package format is:
+/*
+ * New package format is:
  * - flag (int)
  *	class - used for de-muxing the request to the correct GITn
  *	type (volt, temp, fan)
@@ -613,7 +616,8 @@ static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
 
 	buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
 	if (buf->flags == 0) {
-		/* The reading is not valid, possible causes:
+		/*
+		 * The reading is not valid, possible causes:
 		 * - sensor failure
 		 * - enumeration was FUBAR (and we didn't notice)
 		 */
@@ -1311,14 +1315,16 @@ static int atk_probe_if(struct atk_data *data)
 		dev_dbg(dev, "method " METHOD_WRITE " not found: %s\n",
 				 acpi_format_exception(status));
 
-	/* Check for hwmon methods: first check "old" style methods; note that
+	/*
+	 * Check for hwmon methods: first check "old" style methods; note that
 	 * both may be present: in this case we stick to the old interface;
 	 * analysis of multiple DSDTs indicates that when both interfaces
 	 * are present the new one (GGRP/GITM) is not functional.
 	 */
 	if (new_if)
 		dev_info(dev, "Overriding interface detection\n");
-	if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle && !new_if)
+	if (data->rtmp_handle &&
+			data->rvlt_handle && data->rfan_handle && !new_if)
 		data->old_interface = true;
 	else if (data->enumerate_handle && data->read_handle &&
 			data->write_handle)
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index 33cc143..58af6aa 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -1,22 +1,22 @@
 /*
-    atxp1.c - kernel module for setting CPU VID and general purpose
-                     I/Os using the Attansic ATXP1 chip.
-
-    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.
-
-*/
+ * atxp1.c - kernel module for setting CPU VID and general purpose
+ *	     I/Os using the Attansic ATXP1 chip.
+ *
+ * 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/kernel.h>
 #include <linux/init.h>
@@ -48,7 +48,7 @@ static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
 static int atxp1_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id);
 static int atxp1_remove(struct i2c_client *client);
-static struct atxp1_data * atxp1_update_device(struct device *dev);
+static struct atxp1_data *atxp1_update_device(struct device *dev);
 static int atxp1_detect(struct i2c_client *client, struct i2c_board_info *info);
 
 static const struct i2c_device_id atxp1_id[] = {
@@ -83,7 +83,7 @@ struct atxp1_data {
 	u8 vrm;			/* Detected CPU VRM */
 };
 
-static struct atxp1_data * atxp1_update_device(struct device *dev)
+static struct atxp1_data *atxp1_update_device(struct device *dev)
 {
 	struct i2c_client *client;
 	struct atxp1_data *data;
@@ -97,7 +97,8 @@ static struct atxp1_data * atxp1_update_device(struct device *dev)
 
 		/* Update local register data */
 		data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID);
-		data->reg.cpu_vid = i2c_smbus_read_byte_data(client, ATXP1_CVID);
+		data->reg.cpu_vid = i2c_smbus_read_byte_data(client,
+							     ATXP1_CVID);
 		data->reg.gpio1 = i2c_smbus_read_byte_data(client, ATXP1_GPIO1);
 		data->reg.gpio2 = i2c_smbus_read_byte_data(client, ATXP1_GPIO2);
 
@@ -106,33 +107,41 @@ static struct atxp1_data * atxp1_update_device(struct device *dev)
 
 	mutex_unlock(&data->update_lock);
 
-	return(data);
+	return data;
 }
 
 /* sys file functions for cpu0_vid */
-static ssize_t atxp1_showvcore(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t atxp1_showvcore(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	int size;
 	struct atxp1_data *data;
 
 	data = atxp1_update_device(dev);
 
-	size = sprintf(buf, "%d\n", vid_from_reg(data->reg.vid & ATXP1_VIDMASK, data->vrm));
+	size = sprintf(buf, "%d\n", vid_from_reg(data->reg.vid & ATXP1_VIDMASK,
+						 data->vrm));
 
 	return size;
 }
 
-static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t atxp1_storevcore(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
 	struct atxp1_data *data;
 	struct i2c_client *client;
 	int vid, cvid;
-	unsigned int vcore;
+	unsigned long vcore;
+	int err;
 
 	client = to_i2c_client(dev);
 	data = atxp1_update_device(dev);
 
-	vcore = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &vcore);
+	if (err)
+		return err;
+
 	vcore /= 25;
 	vcore *= 25;
 
@@ -144,7 +153,10 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att
 		return -1;
 	}
 
-	/* If output enabled, use control register value. Otherwise original CPU VID */
+	/*
+	 * If output enabled, use control register value.
+	 * Otherwise original CPU VID
+	 */
 	if (data->reg.vid & ATXP1_VIDENA)
 		cvid = data->reg.vid & ATXP1_VIDMASK;
 	else
@@ -154,18 +166,17 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att
 	if (vid == cvid)
 		return count;
 
-	dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid);
+	dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", (int)vcore, vid);
 
 	/* Write every 25 mV step to increase stability */
 	if (cvid > vid) {
-		for (; cvid >= vid; cvid--) {
-        		i2c_smbus_write_byte_data(client, ATXP1_VID, cvid | ATXP1_VIDENA);
-		}
-	}
-	else {
-		for (; cvid <= vid; cvid++) {
-        		i2c_smbus_write_byte_data(client, ATXP1_VID, cvid | ATXP1_VIDENA);
-		}
+		for (; cvid >= vid; cvid--)
+			i2c_smbus_write_byte_data(client,
+						ATXP1_VID, cvid | ATXP1_VIDENA);
+	} else {
+		for (; cvid <= vid; cvid++)
+			i2c_smbus_write_byte_data(client,
+						ATXP1_VID, cvid | ATXP1_VIDENA);
 	}
 
 	data->valid = 0;
@@ -173,13 +184,16 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att
 	return count;
 }
 
-/* CPU core reference voltage
-    unit: millivolt
-*/
-static DEVICE_ATTR(cpu0_vid, S_IRUGO | S_IWUSR, atxp1_showvcore, atxp1_storevcore);
+/*
+ * CPU core reference voltage
+ * unit: millivolt
+ */
+static DEVICE_ATTR(cpu0_vid, S_IRUGO | S_IWUSR, atxp1_showvcore,
+		   atxp1_storevcore);
 
 /* sys file functions for GPIO1 */
-static ssize_t atxp1_showgpio1(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t atxp1_showgpio1(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	int size;
 	struct atxp1_data *data;
@@ -191,21 +205,26 @@ static ssize_t atxp1_showgpio1(struct device *dev, struct device_attribute *attr
 	return size;
 }
 
-static ssize_t atxp1_storegpio1(struct device *dev, struct device_attribute *attr, const char*buf, size_t count)
+static ssize_t atxp1_storegpio1(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
 {
 	struct atxp1_data *data;
 	struct i2c_client *client;
-	unsigned int value;
+	unsigned long value;
+	int err;
 
 	client = to_i2c_client(dev);
 	data = atxp1_update_device(dev);
 
-	value = simple_strtoul(buf, NULL, 16);
+	err = kstrtoul(buf, 16, &value);
+	if (err)
+		return err;
 
 	value &= ATXP1_GPIO1MASK;
 
 	if (value != (data->reg.gpio1 & ATXP1_GPIO1MASK)) {
-		dev_info(dev, "Writing 0x%x to GPIO1.\n", value);
+		dev_info(dev, "Writing 0x%x to GPIO1.\n", (unsigned int)value);
 
 		i2c_smbus_write_byte_data(client, ATXP1_GPIO1, value);
 
@@ -215,13 +234,15 @@ static ssize_t atxp1_storegpio1(struct device *dev, struct device_attribute *att
 	return count;
 }
 
-/* GPIO1 data register
-    unit: Four bit as hex (e.g. 0x0f)
-*/
+/*
+ * GPIO1 data register
+ * unit: Four bit as hex (e.g. 0x0f)
+ */
 static DEVICE_ATTR(gpio1, S_IRUGO | S_IWUSR, atxp1_showgpio1, atxp1_storegpio1);
 
 /* sys file functions for GPIO2 */
-static ssize_t atxp1_showgpio2(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t atxp1_showgpio2(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	int size;
 	struct atxp1_data *data;
@@ -233,19 +254,22 @@ static ssize_t atxp1_showgpio2(struct device *dev, struct device_attribute *attr
 	return size;
 }
 
-static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t atxp1_storegpio2(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
-	struct atxp1_data *data;
-	struct i2c_client *client;
-	unsigned int value;
-
-	client = to_i2c_client(dev);
-	data = atxp1_update_device(dev);
+	struct atxp1_data *data = atxp1_update_device(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long value;
+	int err;
 
-	value = simple_strtoul(buf, NULL, 16) & 0xff;
+	err = kstrtoul(buf, 16, &value);
+	if (err)
+		return err;
+	value &= 0xff;
 
 	if (value != data->reg.gpio2) {
-		dev_info(dev, "Writing 0x%x to GPIO1.\n", value);
+		dev_info(dev, "Writing 0x%x to GPIO1.\n", (unsigned int)value);
 
 		i2c_smbus_write_byte_data(client, ATXP1_GPIO2, value);
 
@@ -255,9 +279,10 @@ static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *att
 	return count;
 }
 
-/* GPIO2 data register
-    unit: Eight bit as hex (e.g. 0xff)
-*/
+/*
+ * GPIO2 data register
+ * unit: Eight bit as hex (e.g. 0xff)
+ */
 static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
 
 static struct attribute *atxp1_attributes[] = {
@@ -290,8 +315,10 @@ static int atxp1_detect(struct i2c_client *new_client,
 	     (i2c_smbus_read_byte_data(new_client, 0xff) == 0)))
 		return -ENODEV;
 
-	/* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
-	 * showing the same as register 0x00 */
+	/*
+	 * No vendor ID, now checking if registers 0x10,0x11 (non-existent)
+	 * showing the same as register 0x00
+	 */
 	temp = i2c_smbus_read_byte_data(new_client, 0x00);
 
 	if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
@@ -333,7 +360,8 @@ static int atxp1_probe(struct i2c_client *new_client,
 	mutex_init(&data->update_lock);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group)))
+	err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -357,7 +385,7 @@ exit:
 
 static int atxp1_remove(struct i2c_client *client)
 {
-	struct atxp1_data * data = i2c_get_clientdata(client);
+	struct atxp1_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&client->dev.kobj, &atxp1_group);
@@ -367,15 +395,4 @@ static int atxp1_remove(struct i2c_client *client)
 	return 0;
 };
 
-static int __init atxp1_init(void)
-{
-	return i2c_add_driver(&atxp1_driver);
-};
-
-static void __exit atxp1_exit(void)
-{
-	i2c_del_driver(&atxp1_driver);
-};
-
-module_init(atxp1_init);
-module_exit(atxp1_exit);
+module_i2c_driver(atxp1_driver);
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index a6c6ec3..0d3141f 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -39,6 +39,7 @@
 #include <linux/moduleparam.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/cpu_device_id.h>
 
 #define DRVNAME	"coretemp"
 
@@ -57,8 +58,8 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
 #define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1)
 #define MAX_CORE_DATA		(NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
 
-#define TO_PHYS_ID(cpu)		cpu_data(cpu).phys_proc_id
-#define TO_CORE_ID(cpu)		cpu_data(cpu).cpu_core_id
+#define TO_PHYS_ID(cpu)		(cpu_data(cpu).phys_proc_id)
+#define TO_CORE_ID(cpu)		(cpu_data(cpu).cpu_core_id)
 #define TO_ATTR_NO(cpu)		(TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
 
 #ifdef CONFIG_SMP
@@ -759,13 +760,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = {
 	.notifier_call = coretemp_cpu_callback,
 };
 
+static const struct x86_cpu_id coretemp_ids[] = {
+	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, coretemp_ids);
+
 static int __init coretemp_init(void)
 {
 	int i, err = -ENODEV;
 
-	/* quick check if we run Intel */
-	if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
-		goto exit;
+	/*
+	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
+	 * sensors. We check this bit only, all the early CPUs
+	 * without thermal sensors will be filtered out.
+	 */
+	if (!x86_match_cpu(coretemp_ids))
+		return -ENODEV;
 
 	err = platform_driver_register(&coretemp_driver);
 	if (err)
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index ffb229a..e7c6a19 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -82,12 +82,12 @@ enum chips { dme1737, sch5027, sch311x, sch5127 };
  * --------------------------------------------------------------------- */
 
 /* Voltages (in) numbered 0-7 (ix) */
-#define	DME1737_REG_IN(ix)		((ix) < 5 ? 0x20 + (ix) : \
+#define DME1737_REG_IN(ix)		((ix) < 5 ? 0x20 + (ix) : \
 					 (ix) < 7 ? 0x94 + (ix) : \
 						    0x1f)
-#define	DME1737_REG_IN_MIN(ix)		((ix) < 5 ? 0x44 + (ix) * 2 \
+#define DME1737_REG_IN_MIN(ix)		((ix) < 5 ? 0x44 + (ix) * 2 \
 						  : 0x91 + (ix) * 2)
-#define	DME1737_REG_IN_MAX(ix)		((ix) < 5 ? 0x45 + (ix) * 2 \
+#define DME1737_REG_IN_MAX(ix)		((ix) < 5 ? 0x45 + (ix) * 2 \
 						  : 0x92 + (ix) * 2)
 
 /* Temperatures (temp) numbered 0-2 (ix) */
@@ -97,14 +97,16 @@ enum chips { dme1737, sch5027, sch311x, sch5127 };
 #define DME1737_REG_TEMP_OFFSET(ix)	((ix) == 0 ? 0x1f \
 						   : 0x1c + (ix))
 
-/* Voltage and temperature LSBs
+/*
+ * Voltage and temperature LSBs
  * The LSBs (4 bits each) are stored in 5 registers with the following layouts:
  *    IN_TEMP_LSB(0) = [in5, in6]
  *    IN_TEMP_LSB(1) = [temp3, temp1]
  *    IN_TEMP_LSB(2) = [in4, temp2]
  *    IN_TEMP_LSB(3) = [in3, in0]
  *    IN_TEMP_LSB(4) = [in2, in1]
- *    IN_TEMP_LSB(5) = [res, in7] */
+ *    IN_TEMP_LSB(5) = [res, in7]
+ */
 #define DME1737_REG_IN_TEMP_LSB(ix)	(0x84 + (ix))
 static const u8 DME1737_REG_IN_LSB[] = {3, 4, 4, 3, 2, 0, 0, 5};
 static const u8 DME1737_REG_IN_LSB_SHL[] = {4, 4, 0, 0, 0, 0, 4, 4};
@@ -127,24 +129,30 @@ static const u8 DME1737_REG_TEMP_LSB_SHL[] = {4, 4, 0};
 #define DME1737_REG_PWM_MIN(ix)		(0x64 + (ix)) /* only for pwm[0-2] */
 #define DME1737_REG_PWM_FREQ(ix)	((ix) < 3 ? 0x5f + (ix) \
 						  : 0xa3 + (ix))
-/* The layout of the ramp rate registers is different from the other pwm
+/*
+ * The layout of the ramp rate registers is different from the other pwm
  * registers. The bits for the 3 PWMs are stored in 2 registers:
  *    PWM_RR(0) = [OFF3, OFF2,  OFF1,  RES,   RR1E, RR1-2, RR1-1, RR1-0]
- *    PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0] */
+ *    PWM_RR(1) = [RR2E, RR2-2, RR2-1, RR2-0, RR3E, RR3-2, RR3-1, RR3-0]
+ */
 #define DME1737_REG_PWM_RR(ix)		(0x62 + (ix)) /* only for pwm[0-2] */
 
 /* Thermal zones 0-2 */
 #define DME1737_REG_ZONE_LOW(ix)	(0x67 + (ix))
 #define DME1737_REG_ZONE_ABS(ix)	(0x6a + (ix))
-/* The layout of the hysteresis registers is different from the other zone
+/*
+ * The layout of the hysteresis registers is different from the other zone
  * registers. The bits for the 3 zones are stored in 2 registers:
  *    ZONE_HYST(0) = [H1-3,  H1-2,  H1-1, H1-0, H2-3, H2-2, H2-1, H2-0]
- *    ZONE_HYST(1) = [H3-3,  H3-2,  H3-1, H3-0, RES,  RES,  RES,  RES] */
+ *    ZONE_HYST(1) = [H3-3,  H3-2,  H3-1, H3-0, RES,  RES,  RES,  RES]
+ */
 #define DME1737_REG_ZONE_HYST(ix)	(0x6d + (ix))
 
-/* Alarm registers and bit mapping
+/*
+ * Alarm registers and bit mapping
  * The 3 8-bit alarm registers will be concatenated to a single 32-bit
- * alarm value [0, ALARM3, ALARM2, ALARM1]. */
+ * alarm value [0, ALARM3, ALARM2, ALARM1].
+ */
 #define DME1737_REG_ALARM1		0x41
 #define DME1737_REG_ALARM2		0x42
 #define DME1737_REG_ALARM3		0x83
@@ -257,9 +265,11 @@ static const int IN_NOMINAL_SCH5127[] = {2500, 2250, 3300, 1125, 1125, 3300,
 				 (type) == sch5127 ? IN_NOMINAL_SCH5127 : \
 				 IN_NOMINAL_DME1737)
 
-/* Voltage input
+/*
+ * Voltage input
  * Voltage inputs have 16 bits resolution, limit values have 8 bits
- * resolution. */
+ * resolution.
+ */
 static inline int IN_FROM_REG(int reg, int nominal, int res)
 {
 	return (reg * nominal + (3 << (res - 3))) / (3 << (res - 2));
@@ -270,10 +280,12 @@ static inline int IN_TO_REG(int val, int nominal)
 	return SENSORS_LIMIT((val * 192 + nominal / 2) / nominal, 0, 255);
 }
 
-/* Temperature input
+/*
+ * Temperature input
  * The register values represent temperatures in 2's complement notation from
  * -127 degrees C to +127 degrees C. Temp inputs have 16 bits resolution, limit
- * values have 8 bits resolution. */
+ * values have 8 bits resolution.
+ */
 static inline int TEMP_FROM_REG(int reg, int res)
 {
 	return (reg * 1000) >> (res - 8);
@@ -300,18 +312,19 @@ static int TEMP_RANGE_TO_REG(int val, int reg)
 	int i;
 
 	for (i = 15; i > 0; i--) {
-		if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2) {
+		if (val > (TEMP_RANGE[i] + TEMP_RANGE[i - 1] + 1) / 2)
 			break;
-		}
 	}
 
 	return (reg & 0x0f) | (i << 4);
 }
 
-/* Temperature hysteresis
+/*
+ * Temperature hysteresis
  * Register layout:
  *    reg[0] = [H1-3, H1-2, H1-1, H1-0, H2-3, H2-2, H2-1, H2-0]
- *    reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx] */
+ *    reg[1] = [H3-3, H3-2, H3-1, H3-0, xxxx, xxxx, xxxx, xxxx]
+ */
 static inline int TEMP_HYST_FROM_REG(int reg, int ix)
 {
 	return (((ix == 1) ? reg : reg >> 4) & 0x0f) * 1000;
@@ -327,11 +340,10 @@ static inline int TEMP_HYST_TO_REG(int val, int ix, int reg)
 /* Fan input RPM */
 static inline int FAN_FROM_REG(int reg, int tpc)
 {
-	if (tpc) {
+	if (tpc)
 		return tpc * reg;
-	} else {
+	else
 		return (reg == 0 || reg == 0xffff) ? 0 : 90000 * 60 / reg;
-	}
 }
 
 static inline int FAN_TO_REG(int val, int tpc)
@@ -344,17 +356,21 @@ static inline int FAN_TO_REG(int val, int tpc)
 	}
 }
 
-/* Fan TPC (tach pulse count)
+/*
+ * Fan TPC (tach pulse count)
  * Converts a register value to a TPC multiplier or returns 0 if the tachometer
- * is configured in legacy (non-tpc) mode */
+ * is configured in legacy (non-tpc) mode
+ */
 static inline int FAN_TPC_FROM_REG(int reg)
 {
 	return (reg & 0x20) ? 0 : 60 >> (reg & 0x03);
 }
 
-/* Fan type
+/*
+ * Fan type
  * The type of a fan is expressed in number of pulses-per-revolution that it
- * emits */
+ * emits
+ */
 static inline int FAN_TYPE_FROM_REG(int reg)
 {
 	int edge = (reg >> 1) & 0x03;
@@ -378,9 +394,8 @@ static int FAN_MAX_FROM_REG(int reg)
 	int i;
 
 	for (i = 10; i > 0; i--) {
-		if (reg == FAN_MAX[i]) {
+		if (reg == FAN_MAX[i])
 			break;
-		}
 	}
 
 	return 1000 + i * 500;
@@ -391,15 +406,15 @@ static int FAN_MAX_TO_REG(int val)
 	int i;
 
 	for (i = 10; i > 0; i--) {
-		if (val > (1000 + (i - 1) * 500)) {
+		if (val > (1000 + (i - 1) * 500))
 			break;
-		}
 	}
 
 	return FAN_MAX[i];
 }
 
-/* PWM enable
+/*
+ * PWM enable
  * Register to enable mapping:
  * 000:  2  fan on zone 1 auto
  * 001:  2  fan on zone 2 auto
@@ -408,7 +423,8 @@ static int FAN_MAX_TO_REG(int val)
  * 100: -1  fan disabled
  * 101:  2  fan on hottest of zones 2,3 auto
  * 110:  2  fan on hottest of zones 1,2,3 auto
- * 111:  1  fan in manual mode */
+ * 111:  1  fan in manual mode
+ */
 static inline int PWM_EN_FROM_REG(int reg)
 {
 	static const int en[] = {2, 2, 2, 0, -1, 2, 2, 1};
@@ -423,7 +439,8 @@ static inline int PWM_EN_TO_REG(int val, int reg)
 	return (reg & 0x1f) | ((en & 0x07) << 5);
 }
 
-/* PWM auto channels zone
+/*
+ * PWM auto channels zone
  * Register to auto channels zone mapping (ACZ is a bitfield with bit x
  * corresponding to zone x+1):
  * 000: 001  fan on zone 1 auto
@@ -433,7 +450,8 @@ static inline int PWM_EN_TO_REG(int val, int reg)
  * 100: 000  fan disabled
  * 101: 110  fan on hottest of zones 2,3 auto
  * 110: 111  fan on hottest of zones 1,2,3 auto
- * 111: 000  fan in manual mode */
+ * 111: 000  fan in manual mode
+ */
 static inline int PWM_ACZ_FROM_REG(int reg)
 {
 	static const int acz[] = {1, 2, 4, 0, 0, 6, 7, 0};
@@ -468,19 +486,20 @@ static int PWM_FREQ_TO_REG(int val, int reg)
 		i = 11;
 	} else {
 		for (i = 9; i > 0; i--) {
-			if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2) {
+			if (val > (PWM_FREQ[i] + PWM_FREQ[i - 1] + 1) / 2)
 				break;
-			}
 		}
 	}
 
 	return (reg & 0xf0) | i;
 }
 
-/* PWM ramp rate
+/*
+ * PWM ramp rate
  * Register layout:
  *    reg[0] = [OFF3,  OFF2,  OFF1,  RES,   RR1-E, RR1-2, RR1-1, RR1-0]
- *    reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0] */
+ *    reg[1] = [RR2-E, RR2-2, RR2-1, RR2-0, RR3-E, RR3-2, RR3-1, RR3-0]
+ */
 static const u8 PWM_RR[] = {206, 104, 69, 41, 26, 18, 10, 5};
 
 static inline int PWM_RR_FROM_REG(int reg, int ix)
@@ -495,9 +514,8 @@ static int PWM_RR_TO_REG(int val, int ix, int reg)
 	int i;
 
 	for (i = 0; i < 7; i++) {
-		if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2) {
+		if (val > (PWM_RR[i] + PWM_RR[i + 1] + 1) / 2)
 			break;
-		}
 	}
 
 	return (ix == 1) ? (reg & 0x8f) | (i << 4) : (reg & 0xf8) | i;
@@ -516,9 +534,11 @@ static inline int PWM_RR_EN_TO_REG(int val, int ix, int reg)
 	return val ? reg | en : reg & ~en;
 }
 
-/* PWM min/off
+/*
+ * PWM min/off
  * The PWM min/off bits are part of the PMW ramp rate register 0 (see above for
- * the register layout). */
+ * the register layout).
+ */
 static inline int PWM_OFF_FROM_REG(int reg, int ix)
 {
 	return (reg >> (ix + 5)) & 0x01;
@@ -604,12 +624,13 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 
 		/* In (voltage) registers */
 		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
-			/* Voltage inputs are stored as 16 bit values even
+			/*
+			 * Voltage inputs are stored as 16 bit values even
 			 * though they have only 12 bits resolution. This is
-			 * to make it consistent with the temp inputs. */
-			if (ix == 7 && !(data->has_features & HAS_IN7)) {
+			 * to make it consistent with the temp inputs.
+			 */
+			if (ix == 7 && !(data->has_features & HAS_IN7))
 				continue;
-			}
 			data->in[ix] = dme1737_read(data,
 					DME1737_REG_IN(ix)) << 8;
 			data->in_min[ix] = dme1737_read(data,
@@ -620,11 +641,13 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 
 		/* Temp registers */
 		for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
-			/* Temp inputs are stored as 16 bit values even
+			/*
+			 * Temp inputs are stored as 16 bit values even
 			 * though they have only 12 bits resolution. This is
 			 * to take advantage of implicit conversions between
 			 * register values (2's complement) and temp values
-			 * (signed decimal). */
+			 * (signed decimal).
+			 */
 			data->temp[ix] = dme1737_read(data,
 					DME1737_REG_TEMP(ix)) << 8;
 			data->temp_min[ix] = dme1737_read(data,
@@ -637,21 +660,21 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 			}
 		}
 
-		/* In and temp LSB registers
+		/*
+		 * In and temp LSB registers
 		 * The LSBs are latched when the MSBs are read, so the order in
 		 * which the registers are read (MSB first, then LSB) is
-		 * important! */
+		 * important!
+		 */
 		for (ix = 0; ix < ARRAY_SIZE(lsb); ix++) {
-			if (ix == 5 && !(data->has_features & HAS_IN7)) {
+			if (ix == 5 && !(data->has_features & HAS_IN7))
 				continue;
-			}
 			lsb[ix] = dme1737_read(data,
 					DME1737_REG_IN_TEMP_LSB(ix));
 		}
 		for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
-			if (ix == 7 && !(data->has_features & HAS_IN7)) {
+			if (ix == 7 && !(data->has_features & HAS_IN7))
 				continue;
-			}
 			data->in[ix] |= (lsb[DME1737_REG_IN_LSB[ix]] <<
 					DME1737_REG_IN_LSB_SHL[ix]) & 0xf0;
 		}
@@ -662,11 +685,12 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 
 		/* Fan registers */
 		for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) {
-			/* Skip reading registers if optional fans are not
-			 * present */
-			if (!(data->has_features & HAS_FAN(ix))) {
+			/*
+			 * Skip reading registers if optional fans are not
+			 * present
+			 */
+			if (!(data->has_features & HAS_FAN(ix)))
 				continue;
-			}
 			data->fan[ix] = dme1737_read(data,
 					DME1737_REG_FAN(ix));
 			data->fan[ix] |= dme1737_read(data,
@@ -686,11 +710,12 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 
 		/* PWM registers */
 		for (ix = 0; ix < ARRAY_SIZE(data->pwm); ix++) {
-			/* Skip reading registers if optional PWMs are not
-			 * present */
-			if (!(data->has_features & HAS_PWM(ix))) {
+			/*
+			 * Skip reading registers if optional PWMs are not
+			 * present
+			 */
+			if (!(data->has_features & HAS_PWM(ix)))
 				continue;
-			}
 			data->pwm[ix] = dme1737_read(data,
 					DME1737_REG_PWM(ix));
 			data->pwm_freq[ix] = dme1737_read(data,
@@ -711,9 +736,8 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 		/* Thermal zone registers */
 		for (ix = 0; ix < ARRAY_SIZE(data->zone_low); ix++) {
 			/* Skip reading registers if zone3 is not present */
-			if ((ix == 2) && !(data->has_features & HAS_ZONE3)) {
+			if ((ix == 2) && !(data->has_features & HAS_ZONE3))
 				continue;
-			}
 			/* sch5127 zone2 registers are special */
 			if ((ix == 1) && (data->type == sch5127)) {
 				data->zone_low[1] = dme1737_read(data,
@@ -737,8 +761,10 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 		/* Alarm registers */
 		data->alarms = dme1737_read(data,
 						DME1737_REG_ALARM1);
-		/* Bit 7 tells us if the other alarm registers are non-zero and
-		 * therefore also need to be read */
+		/*
+		 * Bit 7 tells us if the other alarm registers are non-zero and
+		 * therefore also need to be read
+		 */
 		if (data->alarms & 0x80) {
 			data->alarms |= dme1737_read(data,
 						DME1737_REG_ALARM2) << 8;
@@ -746,22 +772,18 @@ static struct dme1737_data *dme1737_update_device(struct device *dev)
 						DME1737_REG_ALARM3) << 16;
 		}
 
-		/* The ISA chips require explicit clearing of alarm bits.
+		/*
+		 * The ISA chips require explicit clearing of alarm bits.
 		 * Don't worry, an alarm will come back if the condition
-		 * that causes it still exists */
+		 * that causes it still exists
+		 */
 		if (!data->client) {
-			if (data->alarms & 0xff0000) {
-				dme1737_write(data, DME1737_REG_ALARM3,
-					      0xff);
-			}
-			if (data->alarms & 0xff00) {
-				dme1737_write(data, DME1737_REG_ALARM2,
-					      0xff);
-			}
-			if (data->alarms & 0xff) {
-				dme1737_write(data, DME1737_REG_ALARM1,
-					      0xff);
-			}
+			if (data->alarms & 0xff0000)
+				dme1737_write(data, DME1737_REG_ALARM3, 0xff);
+			if (data->alarms & 0xff00)
+				dme1737_write(data, DME1737_REG_ALARM2, 0xff);
+			if (data->alarms & 0xff)
+				dme1737_write(data, DME1737_REG_ALARM1, 0xff);
 		}
 
 		data->last_update = jiffies;
@@ -822,7 +844,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
 		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -901,7 +928,12 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
 		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -952,11 +984,10 @@ static ssize_t show_zone(struct device *dev, struct device_attribute *attr,
 	switch (fn) {
 	case SYS_ZONE_AUTO_CHANNELS_TEMP:
 		/* check config2 for non-standard temp-to-zone mapping */
-		if ((ix == 1) && (data->config2 & 0x02)) {
+		if ((ix == 1) && (data->config2 & 0x02))
 			res = 4;
-		} else {
+		else
 			res = 1 << ix;
-		}
 		break;
 	case SYS_ZONE_AUTO_POINT1_TEMP_HYST:
 		res = TEMP_FROM_REG(data->zone_low[ix], 8) -
@@ -989,7 +1020,12 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr,
 		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -1014,8 +1050,10 @@ static ssize_t set_zone(struct device *dev, struct device_attribute *attr,
 		/* Refresh the cache */
 		data->zone_low[ix] = dme1737_read(data,
 						  DME1737_REG_ZONE_LOW(ix));
-		/* Modify the temp range value (which is stored in the upper
-		 * nibble of the pwm_freq register) */
+		/*
+		 * Modify the temp range value (which is stored in the upper
+		 * nibble of the pwm_freq register)
+		 */
 		data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val -
 					TEMP_FROM_REG(data->zone_low[ix], 8),
 					dme1737_read(data,
@@ -1095,7 +1133,12 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
 		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -1170,21 +1213,19 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
 
 	switch (fn) {
 	case SYS_PWM:
-		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0) {
+		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0)
 			res = 255;
-		} else {
+		else
 			res = data->pwm[ix];
-		}
 		break;
 	case SYS_PWM_FREQ:
 		res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]);
 		break;
 	case SYS_PWM_ENABLE:
-		if (ix >= 3) {
+		if (ix >= 3)
 			res = 1; /* pwm[5-6] hard-wired to manual mode */
-		} else {
+		else
 			res = PWM_EN_FROM_REG(data->pwm_config[ix]);
-		}
 		break;
 	case SYS_PWM_RAMP_RATE:
 		/* Only valid for pwm[1-3] */
@@ -1192,19 +1233,17 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
 		break;
 	case SYS_PWM_AUTO_CHANNELS_ZONE:
 		/* Only valid for pwm[1-3] */
-		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
+		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2)
 			res = PWM_ACZ_FROM_REG(data->pwm_config[ix]);
-		} else {
+		else
 			res = data->pwm_acz[ix];
-		}
 		break;
 	case SYS_PWM_AUTO_PWM_MIN:
 		/* Only valid for pwm[1-3] */
-		if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix)) {
+		if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix))
 			res = data->pwm_min[ix];
-		} else {
+		else
 			res = 0;
-		}
 		break;
 	case SYS_PWM_AUTO_POINT1_PWM:
 		/* Only valid for pwm[1-3] */
@@ -1233,7 +1272,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		*sensor_attr_2 = to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -1307,8 +1351,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 			/* Change permissions of pwm[ix] to read-only */
 			dme1737_chmod_file(dev, dme1737_pwm_chmod_attr[ix],
 					   S_IRUGO);
-			/* Turn on auto mode using the saved zone channel
-			 * assignment */
+			/*
+			 * Turn on auto mode using the saved zone channel
+			 * assignment
+			 */
 			data->pwm_config[ix] = PWM_ACZ_TO_REG(
 							data->pwm_acz[ix],
 							data->pwm_config[ix]);
@@ -1338,8 +1384,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 			data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix,
 							data->pwm_rr[ix > 0]);
 		}
-		/* Enable/disable the feature only if the associated PWM
-		 * output is in automatic mode. */
+		/*
+		 * Enable/disable the feature only if the associated PWM
+		 * output is in automatic mode.
+		 */
 		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
 			data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix,
 							data->pwm_rr[ix > 0]);
@@ -1361,15 +1409,19 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		data->pwm_config[ix] = dme1737_read(data,
 						DME1737_REG_PWM_CONFIG(ix));
 		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {
-			/* PWM is already in auto mode so update the temp
-			 * channel assignment */
+			/*
+			 * PWM is already in auto mode so update the temp
+			 * channel assignment
+			 */
 			data->pwm_config[ix] = PWM_ACZ_TO_REG(val,
 						data->pwm_config[ix]);
 			dme1737_write(data, DME1737_REG_PWM_CONFIG(ix),
 				      data->pwm_config[ix]);
 		} else {
-			/* PWM is not in auto mode so we save the temp
-			 * channel assignment for later use */
+			/*
+			 * PWM is not in auto mode so we save the temp
+			 * channel assignment for later use
+			 */
 			data->pwm_acz[ix] = val;
 		}
 		break;
@@ -1378,10 +1430,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		/* Refresh the cache */
 		data->pwm_min[ix] = dme1737_read(data,
 						DME1737_REG_PWM_MIN(ix));
-		/* There are only 2 values supported for the auto_pwm_min
+		/*
+		 * There are only 2 values supported for the auto_pwm_min
 		 * value: 0 or auto_point1_pwm. So if the temperature drops
 		 * below the auto_point1_temp_hyst value, the fan either turns
-		 * off or runs at auto_point1_pwm duty-cycle. */
+		 * off or runs at auto_point1_pwm duty-cycle.
+		 */
 		if (val > ((data->pwm_min[ix] + 1) / 2)) {
 			data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix,
 						dme1737_read(data,
@@ -1426,7 +1480,12 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
 		       const char *buf, size_t count)
 {
 	struct dme1737_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	data->vrm = val;
 	return count;
@@ -1586,10 +1645,12 @@ static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);   /* for ISA devices */
 
-/* This struct holds all the attributes that are always present and need to be
+/*
+ * This struct holds all the attributes that are always present and need to be
  * created unconditionally. The attributes that need modification of their
  * permissions are created read-only and write permissions are added or removed
- * on the fly when required */
+ * on the fly when required
+ */
 static struct attribute *dme1737_attr[] = {
 	/* Voltages */
 	&sensor_dev_attr_in0_input.dev_attr.attr,
@@ -1652,9 +1713,11 @@ static const struct attribute_group dme1737_group = {
 	.attrs = dme1737_attr,
 };
 
-/* The following struct holds temp offset attributes, which are not available
+/*
+ * The following struct holds temp offset attributes, which are not available
  * in all chips. The following chips support them:
- * DME1737, SCH311x */
+ * DME1737, SCH311x
+ */
 static struct attribute *dme1737_temp_offset_attr[] = {
 	&sensor_dev_attr_temp1_offset.dev_attr.attr,
 	&sensor_dev_attr_temp2_offset.dev_attr.attr,
@@ -1666,9 +1729,11 @@ static const struct attribute_group dme1737_temp_offset_group = {
 	.attrs = dme1737_temp_offset_attr,
 };
 
-/* The following struct holds VID related attributes, which are not available
+/*
+ * The following struct holds VID related attributes, which are not available
  * in all chips. The following chips support them:
- * DME1737 */
+ * DME1737
+ */
 static struct attribute *dme1737_vid_attr[] = {
 	&dev_attr_vrm.attr,
 	&dev_attr_cpu0_vid.attr,
@@ -1679,9 +1744,11 @@ static const struct attribute_group dme1737_vid_group = {
 	.attrs = dme1737_vid_attr,
 };
 
-/* The following struct holds temp zone 3 related attributes, which are not
+/*
+ * The following struct holds temp zone 3 related attributes, which are not
  * available in all chips. The following chips support them:
- * DME1737, SCH311x, SCH5027 */
+ * DME1737, SCH311x, SCH5027
+ */
 static struct attribute *dme1737_zone3_attr[] = {
 	&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
 	&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
@@ -1695,9 +1762,11 @@ static const struct attribute_group dme1737_zone3_group = {
 };
 
 
-/* The following struct holds temp zone hysteresis related attributes, which
+/*
+ * The following struct holds temp zone hysteresis related attributes, which
  * are not available in all chips. The following chips support them:
- * DME1737, SCH311x */
+ * DME1737, SCH311x
+ */
 static struct attribute *dme1737_zone_hyst_attr[] = {
 	&sensor_dev_attr_zone1_auto_point1_temp_hyst.dev_attr.attr,
 	&sensor_dev_attr_zone2_auto_point1_temp_hyst.dev_attr.attr,
@@ -1709,9 +1778,11 @@ static const struct attribute_group dme1737_zone_hyst_group = {
 	.attrs = dme1737_zone_hyst_attr,
 };
 
-/* The following struct holds voltage in7 related attributes, which
+/*
+ * The following struct holds voltage in7 related attributes, which
  * are not available in all chips. The following chips support them:
- * SCH5127 */
+ * SCH5127
+ */
 static struct attribute *dme1737_in7_attr[] = {
 	&sensor_dev_attr_in7_input.dev_attr.attr,
 	&sensor_dev_attr_in7_min.dev_attr.attr,
@@ -1724,9 +1795,11 @@ static const struct attribute_group dme1737_in7_group = {
 	.attrs = dme1737_in7_attr,
 };
 
-/* The following structs hold the PWM attributes, some of which are optional.
+/*
+ * The following structs hold the PWM attributes, some of which are optional.
  * Their creation depends on the chip configuration which is determined during
- * module load. */
+ * module load.
+ */
 static struct attribute *dme1737_pwm1_attr[] = {
 	&sensor_dev_attr_pwm1.dev_attr.attr,
 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
@@ -1779,18 +1852,22 @@ static const struct attribute_group dme1737_pwm_group[] = {
 	{ .attrs = dme1737_pwm6_attr },
 };
 
-/* The following struct holds auto PWM min attributes, which are not available
+/*
+ * The following struct holds auto PWM min attributes, which are not available
  * in all chips. Their creation depends on the chip type which is determined
- * during module load. */
+ * during module load.
+ */
 static struct attribute *dme1737_auto_pwm_min_attr[] = {
 	&sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr,
 	&sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr,
 	&sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr,
 };
 
-/* The following structs hold the fan attributes, some of which are optional.
+/*
+ * The following structs hold the fan attributes, some of which are optional.
  * Their creation depends on the chip configuration which is determined during
- * module load. */
+ * module load.
+ */
 static struct attribute *dme1737_fan1_attr[] = {
 	&sensor_dev_attr_fan1_input.dev_attr.attr,
 	&sensor_dev_attr_fan1_min.dev_attr.attr,
@@ -1843,8 +1920,10 @@ static const struct attribute_group dme1737_fan_group[] = {
 	{ .attrs = dme1737_fan6_attr },
 };
 
-/* The permissions of the following zone attributes are changed to read-
- * writeable if the chip is *not* locked. Otherwise they stay read-only. */
+/*
+ * The permissions of the following zone attributes are changed to read-
+ * writeable if the chip is *not* locked. Otherwise they stay read-only.
+ */
 static struct attribute *dme1737_zone_chmod_attr[] = {
 	&sensor_dev_attr_zone1_auto_point1_temp.dev_attr.attr,
 	&sensor_dev_attr_zone1_auto_point2_temp.dev_attr.attr,
@@ -1860,8 +1939,10 @@ static const struct attribute_group dme1737_zone_chmod_group = {
 };
 
 
-/* The permissions of the following zone 3 attributes are changed to read-
- * writeable if the chip is *not* locked. Otherwise they stay read-only. */
+/*
+ * The permissions of the following zone 3 attributes are changed to read-
+ * writeable if the chip is *not* locked. Otherwise they stay read-only.
+ */
 static struct attribute *dme1737_zone3_chmod_attr[] = {
 	&sensor_dev_attr_zone3_auto_point1_temp.dev_attr.attr,
 	&sensor_dev_attr_zone3_auto_point2_temp.dev_attr.attr,
@@ -1873,9 +1954,11 @@ static const struct attribute_group dme1737_zone3_chmod_group = {
 	.attrs = dme1737_zone3_chmod_attr,
 };
 
-/* The permissions of the following PWM attributes are changed to read-
+/*
+ * The permissions of the following PWM attributes are changed to read-
  * writeable if the chip is *not* locked and the respective PWM is available.
- * Otherwise they stay read-only. */
+ * Otherwise they stay read-only.
+ */
 static struct attribute *dme1737_pwm1_chmod_attr[] = {
 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
@@ -1920,8 +2003,10 @@ static const struct attribute_group dme1737_pwm_chmod_group[] = {
 	{ .attrs = dme1737_pwm6_chmod_attr },
 };
 
-/* Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the
- * chip is not locked. Otherwise they are read-only. */
+/*
+ * Pwm[1-3] are read-writeable if the associated pwm is in manual mode and the
+ * chip is not locked. Otherwise they are read-only.
+ */
 static struct attribute *dme1737_pwm_chmod_attr[] = {
 	&sensor_dev_attr_pwm1.dev_attr.attr,
 	&sensor_dev_attr_pwm2.dev_attr.attr,
@@ -1975,9 +2060,8 @@ static void dme1737_chmod_group(struct device *dev,
 {
 	struct attribute **attr;
 
-	for (attr = group->attrs; *attr; attr++) {
+	for (attr = group->attrs; *attr; attr++)
 		dme1737_chmod_file(dev, *attr, mode);
-	}
 }
 
 static void dme1737_remove_files(struct device *dev)
@@ -2003,26 +2087,20 @@ static void dme1737_remove_files(struct device *dev)
 		}
 	}
 
-	if (data->has_features & HAS_TEMP_OFFSET) {
+	if (data->has_features & HAS_TEMP_OFFSET)
 		sysfs_remove_group(&dev->kobj, &dme1737_temp_offset_group);
-	}
-	if (data->has_features & HAS_VID) {
+	if (data->has_features & HAS_VID)
 		sysfs_remove_group(&dev->kobj, &dme1737_vid_group);
-	}
-	if (data->has_features & HAS_ZONE3) {
+	if (data->has_features & HAS_ZONE3)
 		sysfs_remove_group(&dev->kobj, &dme1737_zone3_group);
-	}
-	if (data->has_features & HAS_ZONE_HYST) {
+	if (data->has_features & HAS_ZONE_HYST)
 		sysfs_remove_group(&dev->kobj, &dme1737_zone_hyst_group);
-	}
-	if (data->has_features & HAS_IN7) {
+	if (data->has_features & HAS_IN7)
 		sysfs_remove_group(&dev->kobj, &dme1737_in7_group);
-	}
 	sysfs_remove_group(&dev->kobj, &dme1737_group);
 
-	if (!data->client) {
+	if (!data->client)
 		sysfs_remove_file(&dev->kobj, &dev_attr_name.attr);
-	}
 }
 
 static int dme1737_create_files(struct device *dev)
@@ -2033,48 +2111,41 @@ static int dme1737_create_files(struct device *dev)
 	/* Create a name attribute for ISA devices */
 	if (!data->client) {
 		err = sysfs_create_file(&dev->kobj, &dev_attr_name.attr);
-		if (err) {
+		if (err)
 			goto exit;
-		}
 	}
 
 	/* Create standard sysfs attributes */
 	err = sysfs_create_group(&dev->kobj, &dme1737_group);
-	if (err) {
+	if (err)
 		goto exit_remove;
-	}
 
 	/* Create chip-dependent sysfs attributes */
 	if (data->has_features & HAS_TEMP_OFFSET) {
 		err = sysfs_create_group(&dev->kobj,
 					 &dme1737_temp_offset_group);
-		if (err) {
+		if (err)
 			goto exit_remove;
-		}
 	}
 	if (data->has_features & HAS_VID) {
 		err = sysfs_create_group(&dev->kobj, &dme1737_vid_group);
-		if (err) {
+		if (err)
 			goto exit_remove;
-		}
 	}
 	if (data->has_features & HAS_ZONE3) {
 		err = sysfs_create_group(&dev->kobj, &dme1737_zone3_group);
-		if (err) {
+		if (err)
 			goto exit_remove;
-		}
 	}
 	if (data->has_features & HAS_ZONE_HYST) {
 		err = sysfs_create_group(&dev->kobj, &dme1737_zone_hyst_group);
-		if (err) {
+		if (err)
 			goto exit_remove;
-		}
 	}
 	if (data->has_features & HAS_IN7) {
 		err = sysfs_create_group(&dev->kobj, &dme1737_in7_group);
-		if (err) {
+		if (err)
 			goto exit_remove;
-		}
 	}
 
 	/* Create fan sysfs attributes */
@@ -2082,9 +2153,8 @@ static int dme1737_create_files(struct device *dev)
 		if (data->has_features & HAS_FAN(ix)) {
 			err = sysfs_create_group(&dev->kobj,
 						 &dme1737_fan_group[ix]);
-			if (err) {
+			if (err)
 				goto exit_remove;
-			}
 		}
 	}
 
@@ -2093,21 +2163,21 @@ static int dme1737_create_files(struct device *dev)
 		if (data->has_features & HAS_PWM(ix)) {
 			err = sysfs_create_group(&dev->kobj,
 						 &dme1737_pwm_group[ix]);
-			if (err) {
+			if (err)
 				goto exit_remove;
-			}
 			if ((data->has_features & HAS_PWM_MIN) && (ix < 3)) {
 				err = sysfs_create_file(&dev->kobj,
 						dme1737_auto_pwm_min_attr[ix]);
-				if (err) {
+				if (err)
 					goto exit_remove;
-				}
 			}
 		}
 	}
 
-	/* Inform if the device is locked. Otherwise change the permissions of
-	 * selected attributes from read-only to read-writeable. */
+	/*
+	 * Inform if the device is locked. Otherwise change the permissions of
+	 * selected attributes from read-only to read-writeable.
+	 */
 	if (data->config & 0x02) {
 		dev_info(dev, "Device is locked. Some attributes "
 			 "will be read-only.\n");
@@ -2194,26 +2264,30 @@ static int dme1737_init_device(struct device *dev)
 		return -EFAULT;
 	}
 
-	/* Determine which optional fan and pwm features are enabled (only
-	 * valid for I2C devices) */
+	/*
+	 * Determine which optional fan and pwm features are enabled (only
+	 * valid for I2C devices)
+	 */
 	if (client) {   /* I2C chip */
 		data->config2 = dme1737_read(data, DME1737_REG_CONFIG2);
 		/* Check if optional fan3 input is enabled */
-		if (data->config2 & 0x04) {
+		if (data->config2 & 0x04)
 			data->has_features |= HAS_FAN(2);
-		}
 
-		/* Fan4 and pwm3 are only available if the client's I2C address
+		/*
+		 * Fan4 and pwm3 are only available if the client's I2C address
 		 * is the default 0x2e. Otherwise the I/Os associated with
-		 * these functions are used for addr enable/select. */
-		if (client->addr == 0x2e) {
+		 * these functions are used for addr enable/select.
+		 */
+		if (client->addr == 0x2e)
 			data->has_features |= HAS_FAN(3) | HAS_PWM(2);
-		}
 
-		/* Determine which of the optional fan[5-6] and pwm[5-6]
+		/*
+		 * Determine which of the optional fan[5-6] and pwm[5-6]
 		 * features are enabled. For this, we need to query the runtime
 		 * registers through the Super-IO LPC interface. Try both
-		 * config ports 0x2e and 0x4e. */
+		 * config ports 0x2e and 0x4e.
+		 */
 		if (dme1737_i2c_get_features(0x2e, data) &&
 		    dme1737_i2c_get_features(0x4e, data)) {
 			dev_warn(dev, "Failed to query Super-IO for optional "
@@ -2271,9 +2345,11 @@ static int dme1737_init_device(struct device *dev)
 			 ((reg >> 4) & 0x03) + 1);
 	}
 
-	/* Switch pwm[1-3] to manual mode if they are currently disabled and
+	/*
+	 * Switch pwm[1-3] to manual mode if they are currently disabled and
 	 * set the duty-cycles to 0% (which is identical to the PWMs being
-	 * disabled). */
+	 * disabled).
+	 */
 	if (!(data->config & 0x02)) {
 		for (ix = 0; ix < 3; ix++) {
 			data->pwm_config[ix] = dme1737_read(data,
@@ -2298,9 +2374,8 @@ static int dme1737_init_device(struct device *dev)
 	data->pwm_acz[2] = 4;	/* pwm3 -> zone3 */
 
 	/* Set VRM */
-	if (data->has_features & HAS_VID) {
+	if (data->has_features & HAS_VID)
 		data->vrm = vid_which_vrm();
-	}
 
 	return 0;
 }
@@ -2318,8 +2393,10 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data)
 
 	dme1737_sio_enter(sio_cip);
 
-	/* Check device ID
-	 * We currently know about two kinds of DME1737 and SCH5027. */
+	/*
+	 * Check device ID
+	 * We currently know about two kinds of DME1737 and SCH5027.
+	 */
 	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
 	if (!(reg == DME1737_ID_1 || reg == DME1737_ID_2 ||
 	      reg == SCH5027_ID)) {
@@ -2338,21 +2415,19 @@ static int dme1737_i2c_get_features(int sio_cip, struct dme1737_data *data)
 		goto exit;
 	}
 
-	/* Read the runtime registers to determine which optional features
+	/*
+	 * Read the runtime registers to determine which optional features
 	 * are enabled and available. Bits [3:2] of registers 0x43-0x46 are set
-	 * to '10' if the respective feature is enabled. */
-	if ((inb(addr + 0x43) & 0x0c) == 0x08) { /* fan6 */
+	 * to '10' if the respective feature is enabled.
+	 */
+	if ((inb(addr + 0x43) & 0x0c) == 0x08) /* fan6 */
 		data->has_features |= HAS_FAN(5);
-	}
-	if ((inb(addr + 0x44) & 0x0c) == 0x08) { /* pwm6 */
+	if ((inb(addr + 0x44) & 0x0c) == 0x08) /* pwm6 */
 		data->has_features |= HAS_PWM(5);
-	}
-	if ((inb(addr + 0x45) & 0x0c) == 0x08) { /* fan5 */
+	if ((inb(addr + 0x45) & 0x0c) == 0x08) /* fan5 */
 		data->has_features |= HAS_FAN(4);
-	}
-	if ((inb(addr + 0x46) & 0x0c) == 0x08) { /* pwm5 */
+	if ((inb(addr + 0x46) & 0x0c) == 0x08) /* pwm5 */
 		data->has_features |= HAS_PWM(4);
-	}
 
 exit:
 	dme1737_sio_exit(sio_cip);
@@ -2369,9 +2444,8 @@ static int dme1737_i2c_detect(struct i2c_client *client,
 	u8 company, verstep = 0;
 	const char *name;
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
-	}
 
 	company = i2c_smbus_read_byte_data(client, DME1737_REG_COMPANY);
 	verstep = i2c_smbus_read_byte_data(client, DME1737_REG_VERSTEP);
@@ -2486,8 +2560,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
 
 	dme1737_sio_enter(sio_cip);
 
-	/* Check device ID
-	 * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127 */
+	/*
+	 * Check device ID
+	 * We currently know about SCH3112, SCH3114, SCH3116, and SCH5127
+	 */
 	reg = force_id ? force_id : dme1737_sio_inb(sio_cip, 0x20);
 	if (!(reg == SCH3112_ID || reg == SCH3114_ID || reg == SCH3116_ID ||
 	      reg == SCH5127_ID)) {
@@ -2507,8 +2583,10 @@ static int __init dme1737_isa_detect(int sio_cip, unsigned short *addr)
 		goto exit;
 	}
 
-	/* Access to the hwmon registers is through an index/data register
-	 * pair located at offset 0x70/0x71. */
+	/*
+	 * Access to the hwmon registers is through an index/data register
+	 * pair located at offset 0x70/0x71.
+	 */
 	*addr = base_addr + 0x70;
 
 exit:
@@ -2610,11 +2688,10 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (data->type == sch5127) {
+	if (data->type == sch5127)
 		data->name = "sch5127";
-	} else {
+	else
 		data->name = "sch311x";
-	}
 
 	/* Initialize the mutex */
 	mutex_init(&data->update_lock);
@@ -2689,9 +2766,8 @@ static int __init dme1737_init(void)
 	unsigned short addr;
 
 	err = i2c_add_driver(&dme1737_i2c_driver);
-	if (err) {
+	if (err)
 		goto exit;
-	}
 
 	if (dme1737_isa_detect(0x2e, &addr) &&
 	    dme1737_isa_detect(0x4e, &addr) &&
@@ -2703,15 +2779,13 @@ static int __init dme1737_init(void)
 	}
 
 	err = platform_driver_register(&dme1737_isa_driver);
-	if (err) {
+	if (err)
 		goto exit_del_i2c_driver;
-	}
 
 	/* Sets global pdev as a side effect */
 	err = dme1737_isa_device_add(addr);
-	if (err) {
+	if (err)
 		goto exit_del_isa_driver;
-	}
 
 	return 0;
 
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index ef1ac996..f647a33 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -1,25 +1,25 @@
 /*
-    ds1621.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Christian W. Zuckschwerdt  <zany@triq.net>  2000-11-23
-    based on lm75.c by Frodo Looijaard <frodol@dds.nl>
-    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with 
-    the help of Jean Delvare <khali@linux-fr.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.
-*/
+ * ds1621.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	      monitoring
+ * Christian W. Zuckschwerdt  <zany@triq.net>  2000-11-23
+ * based on lm75.c by Frodo Looijaard <frodol@dds.nl>
+ * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+ * the help of Jean Delvare <khali@linux-fr.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/module.h>
 #include <linux/init.h>
@@ -67,7 +67,7 @@ static const u8 DS1621_REG_TEMP[3] = {
 
 /* Conversions */
 #define ALARMS_FROM_REG(val) ((val) & \
-                              (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW))
+			(DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW))
 
 /* Each client has this additional data */
 struct ds1621_data {
@@ -93,10 +93,10 @@ static void ds1621_init_client(struct i2c_client *client)
 		new_conf &= ~DS1621_REG_CONFIG_POLARITY;
 	else if (polarity == 1)
 		new_conf |= DS1621_REG_CONFIG_POLARITY;
-	
+
 	if (conf != new_conf)
 		i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
-	
+
 	/* start conversion */
 	i2c_smbus_write_byte(client, DS1621_COM_START);
 }
@@ -155,10 +155,15 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct ds1621_data *data = i2c_get_clientdata(client);
-	u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10));
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	data->temp[attr->index] = val;
+	data->temp[attr->index] = LM75_TEMP_TO_REG(val);
 	i2c_smbus_write_word_swapped(client, DS1621_REG_TEMP[attr->index],
 				     data->temp[attr->index]);
 	mutex_unlock(&data->update_lock);
@@ -212,14 +217,17 @@ static int ds1621_detect(struct i2c_client *client,
 	int conf, temp;
 	int i;
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA 
-				     | I2C_FUNC_SMBUS_WORD_DATA 
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+				     | I2C_FUNC_SMBUS_WORD_DATA
 				     | I2C_FUNC_SMBUS_WRITE_BYTE))
 		return -ENODEV;
 
-	/* Now, we do the remaining detection. It is lousy. */
-	/* The NVB bit should be low if no EEPROM write has been  requested
-	   during the latest 10ms, which is highly improbable in our case. */
+	/*
+	 * Now, we do the remaining detection. It is lousy.
+	 *
+	 * The NVB bit should be low if no EEPROM write has been requested
+	 * during the latest 10ms, which is highly improbable in our case.
+	 */
 	conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
 	if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
 		return -ENODEV;
@@ -254,7 +262,8 @@ static int ds1621_probe(struct i2c_client *client,
 	ds1621_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &ds1621_group)))
+	err = sysfs_create_group(&client->dev.kobj, &ds1621_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -265,11 +274,11 @@ static int ds1621_probe(struct i2c_client *client,
 
 	return 0;
 
-      exit_remove_files:
+ exit_remove_files:
 	sysfs_remove_group(&client->dev.kobj, &ds1621_group);
-      exit_free:
+ exit_free:
 	kfree(data);
-      exit:
+ exit:
 	return err;
 }
 
@@ -305,20 +314,8 @@ static struct i2c_driver ds1621_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init ds1621_init(void)
-{
-	return i2c_add_driver(&ds1621_driver);
-}
-
-static void __exit ds1621_exit(void)
-{
-	i2c_del_driver(&ds1621_driver);
-}
-
+module_i2c_driver(ds1621_driver);
 
 MODULE_AUTHOR("Christian W. Zuckschwerdt <zany@triq.net>");
 MODULE_DESCRIPTION("DS1621 driver");
 MODULE_LICENSE("GPL");
-
-module_init(ds1621_init);
-module_exit(ds1621_exit);
diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c
index 300c3d4..50663ef 100644
--- a/drivers/hwmon/ds620.c
+++ b/drivers/hwmon/ds620.c
@@ -297,19 +297,8 @@ static struct i2c_driver ds620_driver = {
 	.id_table = ds620_id,
 };
 
-static int __init ds620_init(void)
-{
-	return i2c_add_driver(&ds620_driver);
-}
-
-static void __exit ds620_exit(void)
-{
-	i2c_del_driver(&ds620_driver);
-}
+module_i2c_driver(ds620_driver);
 
 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
 MODULE_DESCRIPTION("DS620 driver");
 MODULE_LICENSE("GPL");
-
-module_init(ds620_init);
-module_exit(ds620_exit);
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 270ffab..149dcb0 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -41,8 +41,10 @@
 struct thermal_data {
 	struct device *hwmon_dev;
 	struct mutex mutex;
-	/* Cache the hyst value so we don't keep re-reading it. In theory
-	   we could cache it forever as nobody else should be writing it. */
+	/*
+	 * Cache the hyst value so we don't keep re-reading it. In theory
+	 * we could cache it forever as nobody else should be writing it.
+	 */
 	u8 cached_hyst;
 	unsigned long hyst_valid;
 };
@@ -283,8 +285,10 @@ static int emc1403_detect(struct i2c_client *client,
 	case 0x23:
 		strlcpy(info->type, "emc1423", I2C_NAME_SIZE);
 		break;
-	/* Note: 0x25 is the 1404 which is very similar and this
-	   driver could be extended */
+	/*
+	 * Note: 0x25 is the 1404 which is very similar and this
+	 * driver could be extended
+	 */
 	default:
 		return -ENODEV;
 	}
@@ -366,18 +370,7 @@ static struct i2c_driver sensor_emc1403 = {
 	.address_list = emc1403_address_list,
 };
 
-static int __init sensor_emc1403_init(void)
-{
-	return i2c_add_driver(&sensor_emc1403);
-}
-
-static void  __exit sensor_emc1403_exit(void)
-{
-	i2c_del_driver(&sensor_emc1403);
-}
-
-module_init(sensor_emc1403_init);
-module_exit(sensor_emc1403_exit);
+module_i2c_driver(sensor_emc1403);
 
 MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
 MODULE_DESCRIPTION("emc1403 Thermal Driver");
diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c
index 8650639..9691f66 100644
--- a/drivers/hwmon/emc2103.c
+++ b/drivers/hwmon/emc2103.c
@@ -1,21 +1,21 @@
 /*
-    emc2103.c - Support for SMSC EMC2103
-    Copyright (c) 2010 SMSC
-
-    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.
-*/
+ * emc2103.c - Support for SMSC EMC2103
+ * Copyright (c) 2010 SMSC
+ *
+ * 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>
@@ -48,12 +48,14 @@ static const u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 };
 /* equation 4 from datasheet: rpm = (3932160 * multipler) / count */
 #define FAN_RPM_FACTOR		3932160
 
-/* 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes
+/*
+ * 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes
  * in anti-parallel mode, and in this configuration both can be read
  * independently (so we have 4 temperature inputs).  The device can't
  * detect if it's connected in this mode, so we have to manually enable
  * it.  Default is to leave the device in the state it's already in (-1).
- * This parameter allows APD mode to be optionally forced on or off */
+ * This parameter allows APD mode to be optionally forced on or off
+ */
 static int apd = -1;
 module_param(apd, bint, 0);
 MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode");
@@ -302,10 +304,12 @@ show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
 	return sprintf(buf, "%d\n", fan_div);
 }
 
-/* Note: we also update the fan target here, because its value is
-   determined in part by the fan clock divider.  This follows the principle
-   of least surprise; the user doesn't expect the fan target to change just
-   because the divider changed. */
+/*
+ * Note: we also update the fan target here, because its value is
+ * determined in part by the fan clock divider.  This follows the principle
+ * of least surprise; the user doesn't expect the fan target to change just
+ * because the divider changed.
+ */
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 			   const char *buf, size_t count)
 {
@@ -722,19 +726,8 @@ static struct i2c_driver emc2103_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_emc2103_init(void)
-{
-	return i2c_add_driver(&emc2103_driver);
-}
-
-static void __exit sensors_emc2103_exit(void)
-{
-	i2c_del_driver(&emc2103_driver);
-}
+module_i2c_driver(emc2103_driver);
 
 MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
 MODULE_DESCRIPTION("SMSC EMC2103 hwmon driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_emc2103_init);
-module_exit(sensors_emc2103_exit);
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index 6ebb9b7..840f511 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -552,17 +552,7 @@ static struct i2c_driver emc6w201_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_emc6w201_init(void)
-{
-	return i2c_add_driver(&emc6w201_driver);
-}
-module_init(sensors_emc6w201_init);
-
-static void __exit sensors_emc6w201_exit(void)
-{
-	i2c_del_driver(&emc6w201_driver);
-}
-module_exit(sensors_emc6w201_exit);
+module_i2c_driver(emc6w201_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver");
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 6dbfd3e..3e4da62 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -202,7 +202,7 @@ struct f71805f_sio_data {
 
 static inline long in_from_reg(u8 reg)
 {
-	return (reg * 8);
+	return reg * 8;
 }
 
 /* The 2 least significant bits are not used */
@@ -212,13 +212,13 @@ static inline u8 in_to_reg(long val)
 		return 0;
 	if (val >= 2016)
 		return 0xfc;
-	return (((val + 16) / 32) << 2);
+	return ((val + 16) / 32) << 2;
 }
 
 /* in0 is downscaled by a factor 2 internally */
 static inline long in0_from_reg(u8 reg)
 {
-	return (reg * 16);
+	return reg * 16;
 }
 
 static inline u8 in0_to_reg(long val)
@@ -227,7 +227,7 @@ static inline u8 in0_to_reg(long val)
 		return 0;
 	if (val >= 4032)
 		return 0xfc;
-	return (((val + 32) / 64) << 2);
+	return ((val + 32) / 64) << 2;
 }
 
 /* The 4 most significant bits are not used */
@@ -236,17 +236,19 @@ static inline long fan_from_reg(u16 reg)
 	reg &= 0xfff;
 	if (!reg || reg == 0xfff)
 		return 0;
-	return (1500000 / reg);
+	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 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);
+	return 1500000 / rpm;
 }
 
 static inline unsigned long pwm_freq_from_reg(u8 reg)
@@ -278,7 +280,7 @@ static inline int pwm_mode_from_reg(u8 reg)
 
 static inline long temp_from_reg(u8 reg)
 {
-	return (reg * 1000);
+	return reg * 1000;
 }
 
 static inline u8 temp_to_reg(long val)
@@ -308,9 +310,11 @@ static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
 	outb(val, data->addr + DATA_REG_OFFSET);
 }
 
-/* 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.
-   Must be called with data->update_lock held, except during initialization */
+/*
+ * 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.
+ * Must be called with data->update_lock held, except during initialization
+ */
 static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
 {
 	u16 val;
@@ -455,7 +459,12 @@ static ssize_t set_in0_max(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_high[nr] = in0_to_reg(val);
@@ -471,7 +480,12 @@ static ssize_t set_in0_min(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_low[nr] = in0_to_reg(val);
@@ -517,7 +531,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_high[nr] = in_to_reg(val);
@@ -533,7 +552,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_low[nr] = in_to_reg(val);
@@ -579,7 +603,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_low[nr] = fan_to_reg(val);
@@ -595,7 +624,12 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_target[nr] = fan_to_reg(val);
@@ -664,7 +698,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	if (val > 255)
 		return -EINVAL;
@@ -685,8 +724,13 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	u8 reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	if (val < 1 || val > 3)
 		return -EINVAL;
@@ -730,7 +774,12 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm_freq[nr] = pwm_freq_to_reg(val);
@@ -742,7 +791,7 @@ static ssize_t set_pwm_freq(struct device *dev, struct device_attribute
 
 static ssize_t show_pwm_auto_point_temp(struct device *dev,
 					struct device_attribute *devattr,
-					char* buf)
+					char *buf)
 {
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
@@ -755,13 +804,18 @@ static ssize_t show_pwm_auto_point_temp(struct device *dev,
 
 static ssize_t set_pwm_auto_point_temp(struct device *dev,
 				       struct device_attribute *devattr,
-				       const char* buf, size_t count)
+				       const char *buf, size_t count)
 {
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	int pwmnr = attr->nr;
 	int apnr = attr->index;
-	unsigned long val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->auto_points[pwmnr].temp[apnr] = temp_to_reg(val);
@@ -774,7 +828,7 @@ static ssize_t set_pwm_auto_point_temp(struct device *dev,
 
 static ssize_t show_pwm_auto_point_fan(struct device *dev,
 				       struct device_attribute *devattr,
-				       char* buf)
+				       char *buf)
 {
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
@@ -787,18 +841,23 @@ static ssize_t show_pwm_auto_point_fan(struct device *dev,
 
 static ssize_t set_pwm_auto_point_fan(struct device *dev,
 				      struct device_attribute *devattr,
-				      const char* buf, size_t count)
+				      const char *buf, size_t count)
 {
 	struct f71805f_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	int pwmnr = attr->nr;
 	int apnr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->auto_points[pwmnr].fan[apnr] = fan_to_reg(val);
 	f71805f_write16(data, F71805F_REG_PWM_AUTO_POINT_FAN(pwmnr, apnr),
-		        data->auto_points[pwmnr].fan[apnr]);
+			data->auto_points[pwmnr].fan[apnr]);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -851,7 +910,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_high[nr] = temp_to_reg(val);
@@ -867,7 +931,12 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
 	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);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_hyst[nr] = temp_to_reg(val);
@@ -920,9 +989,9 @@ static ssize_t show_name(struct device *dev, struct device_attribute
 }
 
 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL, 0);
-static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR,
+static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
 			  show_in0_max, set_in0_max, 0);
-static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR,
+static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
 			  show_in0_min, set_in0_min, 0);
 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
 static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR,
@@ -1010,8 +1079,10 @@ static SENSOR_DEVICE_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
 		    show_temp_hyst, set_temp_hyst, 2);
 static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
 
-/* pwm (value) files are created read-only, write permission is
-   then added or removed dynamically as needed */
+/*
+ * pwm (value) files are created read-only, write permission is
+ * then added or removed dynamically as needed
+ */
 static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, show_pwm, set_pwm, 0);
 static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
 			  show_pwm_enable, set_pwm_enable, 0);
@@ -1246,8 +1317,10 @@ static const struct attribute_group f71805f_group_optin[4] = {
 	{ .attrs = f71805f_attributes_optin[3] },
 };
 
-/* We don't include pwm_freq files in the arrays above, because they must be
-   created conditionally (only if pwm_mode is 1 == PWM) */
+/*
+ * We don't include pwm_freq files in the arrays above, because they must be
+ * created conditionally (only if pwm_mode is 1 == PWM)
+ */
 static struct attribute *f71805f_attributes_pwm_freq[] = {
 	&sensor_dev_attr_pwm1_freq.dev_attr.attr,
 	&sensor_dev_attr_pwm2_freq.dev_attr.attr,
@@ -1282,13 +1355,17 @@ static void __devinit f71805f_init_device(struct f71805f_data *data)
 		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. */
+	/*
+	 * 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++) {
 		data->fan_ctrl[i] = f71805f_read8(data,
 						  F71805F_REG_FAN_CTRL(i));
-		/* Clear latch full bit, else "speed mode" fan speed control
-		   doesn't work */
+		/*
+		 * Clear latch full bit, else "speed mode" fan speed control
+		 * doesn't work
+		 */
 		if (data->fan_ctrl[i] & FAN_CTRL_LATCH_FULL) {
 			data->fan_ctrl[i] &= ~FAN_CTRL_LATCH_FULL;
 			f71805f_write8(data, F71805F_REG_FAN_CTRL(i),
@@ -1304,12 +1381,13 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
 	struct resource *res;
 	int i, err;
 
-	static const char *names[] = {
+	static const char * const names[] = {
 		"f71805f",
 		"f71872f",
 	};
 
-	if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		pr_err("Out of memory\n");
 		goto exit;
@@ -1347,40 +1425,47 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
 	f71805f_init_device(data);
 
 	/* Register sysfs interface files */
-	if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group)))
+	err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group);
+	if (err)
 		goto exit_release_region;
 	if (data->has_in & (1 << 4)) { /* in4 */
-		if ((err = sysfs_create_group(&pdev->dev.kobj,
-					      &f71805f_group_optin[0])))
+		err = sysfs_create_group(&pdev->dev.kobj,
+					 &f71805f_group_optin[0]);
+		if (err)
 			goto exit_remove_files;
 	}
 	if (data->has_in & (1 << 8)) { /* in8 */
-		if ((err = sysfs_create_group(&pdev->dev.kobj,
-					      &f71805f_group_optin[1])))
+		err = sysfs_create_group(&pdev->dev.kobj,
+					 &f71805f_group_optin[1]);
+		if (err)
 			goto exit_remove_files;
 	}
 	if (data->has_in & (1 << 9)) { /* in9 (F71872F/FG only) */
-		if ((err = sysfs_create_group(&pdev->dev.kobj,
-					      &f71805f_group_optin[2])))
+		err = sysfs_create_group(&pdev->dev.kobj,
+					 &f71805f_group_optin[2]);
+		if (err)
 			goto exit_remove_files;
 	}
 	if (data->has_in & (1 << 10)) { /* in9 (F71872F/FG only) */
-		if ((err = sysfs_create_group(&pdev->dev.kobj,
-					      &f71805f_group_optin[3])))
+		err = sysfs_create_group(&pdev->dev.kobj,
+					 &f71805f_group_optin[3]);
+		if (err)
 			goto exit_remove_files;
 	}
 	for (i = 0; i < 3; i++) {
 		/* If control mode is PWM, create pwm_freq file */
 		if (!(data->fan_ctrl[i] & FAN_CTRL_DC_MODE)) {
-			if ((err = sysfs_create_file(&pdev->dev.kobj,
-					f71805f_attributes_pwm_freq[i])))
+			err = sysfs_create_file(&pdev->dev.kobj,
+						f71805f_attributes_pwm_freq[i]);
+			if (err)
 				goto exit_remove_files;
 		}
 		/* If PWM is in manual mode, add write permission */
 		if (data->fan_ctrl[i] & FAN_CTRL_MODE_MANUAL) {
-			if ((err = sysfs_chmod_file(&pdev->dev.kobj,
-						    f71805f_attr_pwm[i],
-						    S_IRUGO | S_IWUSR))) {
+			err = sysfs_chmod_file(&pdev->dev.kobj,
+					       f71805f_attr_pwm[i],
+					       S_IRUGO | S_IWUSR);
+			if (err) {
 				dev_err(&pdev->dev, "chmod +w pwm%d failed\n",
 					i + 1);
 				goto exit_remove_files;
@@ -1495,7 +1580,7 @@ static int __init f71805f_find(int sioaddr, unsigned short *address,
 	int err = -ENODEV;
 	u16 devid;
 
-	static const char *names[] = {
+	static const char * const names[] = {
 		"F71805F/FG",
 		"F71872F/FG or F71806F/FG",
 	};
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index e503058..6d12263 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -112,7 +112,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
 enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
 	     f71889fg, f71889ed, f71889a, f8000, f81865f };
 
-static const char *f71882fg_names[] = {
+static const char *const f71882fg_names[] = {
 	"f71808e",
 	"f71808a",
 	"f71858fg",
@@ -252,9 +252,11 @@ struct f71882fg_data {
 	u16	fan_full_speed[4];
 	u8	fan_status;
 	u8	fan_beep;
-	/* Note: all models have max 3 temperature channels, but on some
-	   they are addressed as 0-2 and on others as 1-3, so for coding
-	   convenience we reserve space for 4 channels */
+	/*
+	 * Note: all models have max 3 temperature channels, but on some
+	 * they are addressed as 0-2 and on others as 1-3, so for coding
+	 * convenience we reserve space for 4 channels
+	 */
 	u16	temp[4];
 	u8	temp_ovt[4];
 	u8	temp_high[4];
@@ -362,7 +364,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev,
 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
 	char *buf);
 
-static int __devinit f71882fg_probe(struct platform_device * pdev);
+static int __devinit f71882fg_probe(struct platform_device *pdev);
 static int f71882fg_remove(struct platform_device *pdev);
 
 static struct platform_driver f71882fg_driver = {
@@ -376,8 +378,10 @@ static struct platform_driver f71882fg_driver = {
 
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-/* Temp attr for the f71858fg, the f71858fg is special as it has its
-   temperature indexes start at 0 (the others start at 1) */
+/*
+ * Temp attr for the f71858fg, the f71858fg is special as it has its
+ * temperature indexes start at 0 (the others start at 1)
+ */
 static struct sensor_device_attribute_2 f71858fg_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
 	SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
@@ -424,9 +428,11 @@ static struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { {
 		store_temp_max, 0, 1),
 	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
 		store_temp_max_hyst, 0, 1),
-	/* Should really be temp1_max_alarm, but older versions did not handle
-	   the max and crit alarms separately and lm_sensors v2 depends on the
-	   presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
+	/*
+	 * Should really be temp1_max_alarm, but older versions did not handle
+	 * the max and crit alarms separately and lm_sensors v2 depends on the
+	 * presence of temp#_alarm files. The same goes for temp2/3 _alarm.
+	 */
 	SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
 	SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
 		store_temp_crit, 0, 1),
@@ -485,10 +491,11 @@ static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
 		store_temp_beep, 0, 7),
 } };
 
-/* Temp attr for the f8000
-   Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
-   is used as hysteresis value to clear alarms
-   Also like the f71858fg its temperature indexes start at 0
+/*
+ * Temp attr for the f8000
+ * Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
+ * is used as hysteresis value to clear alarms
+ * Also like the f71858fg its temperature indexes start at 0
  */
 static struct sensor_device_attribute_2 f8000_temp_attr[] = {
 	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
@@ -603,8 +610,10 @@ static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
 		store_fan_beep, 0, 3),
 };
 
-/* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
-   standard models */
+/*
+ * PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
+ * standard models
+ */
 static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { {
 	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_channel,
@@ -673,9 +682,11 @@ static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { {
 		      show_pwm_auto_point_temp_hyst, NULL, 3, 2),
 } };
 
-/* PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the
-   pwm setting when the temperature is above the pwmX_auto_point1_temp can be
-   programmed instead of being hardcoded to 0xff */
+/*
+ * PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the
+ * pwm setting when the temperature is above the pwmX_auto_point1_temp can be
+ * programmed instead of being hardcoded to 0xff
+ */
 static struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { {
 	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_channel,
@@ -925,9 +936,11 @@ static struct sensor_device_attribute_2 f8000_fan_attr[] = {
 	SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
 };
 
-/* PWM attr for the f8000, zones mapped to temp instead of to pwm!
-   Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
-   F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
+/*
+ * PWM attr for the f8000, zones mapped to temp instead of to pwm!
+ * Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
+ * F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0
+ */
 static struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { {
 	SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
 		      show_pwm_auto_point_channel,
@@ -2295,8 +2308,10 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 			data->temp_config =
 				f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
 			if (data->temp_config & 0x10)
-				/* The f71858fg temperature alarms behave as
-				   the f8000 alarms in this mode */
+				/*
+				 * The f71858fg temperature alarms behave as
+				 * the f8000 alarms in this mode
+				 */
 				err = f71882fg_create_sysfs_files(pdev,
 					f8000_temp_attr,
 					ARRAY_SIZE(f8000_temp_attr));
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index f609b57..faf66c8 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -857,19 +857,8 @@ static int f75375_detect(struct i2c_client *client,
 	return 0;
 }
 
-static int __init sensors_f75375_init(void)
-{
-	return i2c_add_driver(&f75375_driver);
-}
-
-static void __exit sensors_f75375_exit(void)
-{
-	i2c_del_driver(&f75375_driver);
-}
+module_i2c_driver(f75375_driver);
 
 MODULE_AUTHOR("Riku Voipio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("F75373/F75375/F75387 hardware monitoring driver");
-
-module_init(sensors_f75375_init);
-module_exit(sensors_f75375_exit);
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c
index 523f8fb..b7494af 100644
--- a/drivers/hwmon/fam15h_power.c
+++ b/drivers/hwmon/fam15h_power.c
@@ -60,15 +60,15 @@ static ssize_t show_power(struct device *dev,
 	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
 				  REG_TDP_RUNNING_AVERAGE, &val);
 	running_avg_capture = (val >> 4) & 0x3fffff;
-	running_avg_capture = sign_extend32(running_avg_capture, 22);
-	running_avg_range = val & 0xf;
+	running_avg_capture = sign_extend32(running_avg_capture, 21);
+	running_avg_range = (val & 0xf) + 1;
 
 	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
 				  REG_TDP_LIMIT3, &val);
 
 	tdp_limit = val >> 16;
-	curr_pwr_watts = tdp_limit + data->base_tdp -
-		(s32)(running_avg_capture >> (running_avg_range + 1));
+	curr_pwr_watts = (tdp_limit + data->base_tdp) << running_avg_range;
+	curr_pwr_watts -= running_avg_capture;
 	curr_pwr_watts *= data->tdp_to_watts;
 
 	/*
@@ -78,7 +78,7 @@ static ssize_t show_power(struct device *dev,
 	 * scaling factor 1/(2^16).  For conversion we use
 	 * (10^6)/(2^16) = 15625/(2^10)
 	 */
-	curr_pwr_watts = (curr_pwr_watts * 15625) >> 10;
+	curr_pwr_watts = (curr_pwr_watts * 15625) >> (10 + running_avg_range);
 	return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts);
 }
 static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL);
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index aa6d8b6..8305d29 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -1,4 +1,5 @@
-/* fschmd.c
+/*
+ * fschmd.c
  *
  * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com>
  *
@@ -76,12 +77,12 @@ enum chips { fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl };
 #define FSCHMD_CONTROL_ALERT_LED	0x01
 
 /* watchdog */
-static const u8 FSCHMD_REG_WDOG_CONTROL[7] =
-	{ 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
-static const u8 FSCHMD_REG_WDOG_STATE[7] =
-	{ 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
-static const u8 FSCHMD_REG_WDOG_PRESET[7] =
-	{ 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
+static const u8 FSCHMD_REG_WDOG_CONTROL[7] = {
+	0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
+static const u8 FSCHMD_REG_WDOG_STATE[7] = {
+	0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
+static const u8 FSCHMD_REG_WDOG_PRESET[7] = {
+	0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
 
 #define FSCHMD_WDOG_CONTROL_TRIGGER	0x10
 #define FSCHMD_WDOG_CONTROL_STARTED	0x10 /* the same as trigger */
@@ -103,10 +104,12 @@ static const u8 FSCHMD_REG_VOLT[7][6] = {
 
 static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 };
 
-/* minimum pwm at which the fan is driven (pwm can by increased depending on
-   the temp. Notice that for the scy some fans share there minimum speed.
-   Also notice that with the scy the sensor order is different than with the
-   other chips, this order was in the 2.4 driver and kept for consistency. */
+/*
+ * minimum pwm at which the fan is driven (pwm can by increased depending on
+ * the temp. Notice that for the scy some fans share there minimum speed.
+ * Also notice that with the scy the sensor order is different than with the
+ * other chips, this order was in the 2.4 driver and kept for consistency.
+ */
 static const u8 FSCHMD_REG_FAN_MIN[7][7] = {
 	{ 0x55, 0x65 },					/* pos */
 	{ 0x55, 0x65, 0xb5 },				/* her */
@@ -182,11 +185,13 @@ static const u8 FSCHMD_REG_TEMP_STATE[7][11] = {
 	  0xb9, 0xc9, 0xd9, 0xe9, 0xf9 },
 };
 
-/* temperature high limit registers, FSC does not document these. Proven to be
-   there with field testing on the fscher and fschrc, already supported / used
-   in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
-   at these addresses, but doesn't want to confirm they are the same as with
-   the fscher?? */
+/*
+ * temperature high limit registers, FSC does not document these. Proven to be
+ * there with field testing on the fscher and fschrc, already supported / used
+ * in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
+ * at these addresses, but doesn't want to confirm they are the same as with
+ * the fscher??
+ */
 static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
 	{ 0, 0, 0 },					/* pos */
 	{ 0x76, 0x86, 0x96 },				/* her */
@@ -198,13 +203,15 @@ static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
 	  0xba, 0xca, 0xda, 0xea, 0xfa },
 };
 
-/* These were found through experimenting with an fscher, currently they are
-   not used, but we keep them around for future reference.
-   On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc),
-   AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence
-   the fan speed.
-static const u8 FSCHER_REG_TEMP_AUTOP1[] =	{ 0x73, 0x83, 0x93 };
-static const u8 FSCHER_REG_TEMP_AUTOP2[] =	{ 0x75, 0x85, 0x95 }; */
+/*
+ * These were found through experimenting with an fscher, currently they are
+ * not used, but we keep them around for future reference.
+ * On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc),
+ * AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence
+ * the fan speed.
+ * static const u8 FSCHER_REG_TEMP_AUTOP1[] =	{ 0x73, 0x83, 0x93 };
+ * static const u8 FSCHER_REG_TEMP_AUTOP2[] =	{ 0x75, 0x85, 0x95 };
+ */
 
 static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 };
 
@@ -290,24 +297,30 @@ struct fschmd_data {
 	u8 fan_ripple[7];	/* divider for rps */
 };
 
-/* Global variables to hold information read from special DMI tables, which are
-   available on FSC machines with an fscher or later chip. There is no need to
-   protect these with a lock as they are only modified from our attach function
-   which always gets called with the i2c-core lock held and never accessed
-   before the attach function is done with them. */
+/*
+ * Global variables to hold information read from special DMI tables, which are
+ * available on FSC machines with an fscher or later chip. There is no need to
+ * protect these with a lock as they are only modified from our attach function
+ * which always gets called with the i2c-core lock held and never accessed
+ * before the attach function is done with them.
+ */
 static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 };
 static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 };
 static int dmi_vref = -1;
 
-/* Somewhat ugly :( global data pointer list with all fschmd devices, so that
-   we can find our device data as when using misc_register there is no other
-   method to get to ones device data from the open fop. */
+/*
+ * Somewhat ugly :( global data pointer list with all fschmd devices, so that
+ * we can find our device data as when using misc_register there is no other
+ * method to get to ones device data from the open fop.
+ */
 static LIST_HEAD(watchdog_data_list);
 /* Note this lock not only protect list access, but also data.kref access */
 static DEFINE_MUTEX(watchdog_data_mutex);
 
-/* Release our data struct when we're detached from the i2c client *and* all
-   references to our watchdog device are released */
+/*
+ * Release our data struct when we're detached from the i2c client *and* all
+ * references to our watchdog device are released
+ */
 static void fschmd_release_resources(struct kref *ref)
 {
 	struct fschmd_data *data = container_of(ref, struct fschmd_data, kref);
@@ -359,9 +372,14 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute
 {
 	int index = to_sensor_dev_attr(devattr)->index;
 	struct fschmd_data *data = dev_get_drvdata(dev);
-	long v = simple_strtol(buf, NULL, 10) / 1000;
+	long v;
+	int err;
 
-	v = SENSORS_LIMIT(v, -128, 127) + 128;
+	err = kstrtol(buf, 10, &v);
+	if (err)
+		return err;
+
+	v = SENSORS_LIMIT(v / 1000, -128, 127) + 128;
 
 	mutex_lock(&data->update_lock);
 	i2c_smbus_write_byte_data(to_i2c_client(dev),
@@ -427,12 +445,23 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute
 	int index = to_sensor_dev_attr(devattr)->index;
 	struct fschmd_data *data = dev_get_drvdata(dev);
 	/* supported values: 2, 4, 8 */
-	unsigned long v = simple_strtoul(buf, NULL, 10);
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
 
 	switch (v) {
-	case 2: v = 1; break;
-	case 4: v = 2; break;
-	case 8: v = 3; break;
+	case 2:
+		v = 1;
+		break;
+	case 4:
+		v = 2;
+		break;
+	case 8:
+		v = 3;
+		break;
 	default:
 		dev_err(dev, "fan_div value %lu not supported. "
 			"Choose one of 2, 4 or 8!\n", v);
@@ -502,7 +531,12 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
 {
 	int index = to_sensor_dev_attr(devattr)->index;
 	struct fschmd_data *data = dev_get_drvdata(dev);
-	unsigned long v = simple_strtoul(buf, NULL, 10);
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
 
 	/* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
 	if (v || data->kind == fscsyl) {
@@ -522,8 +556,10 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
 }
 
 
-/* The FSC hwmon family has the ability to force an attached alert led to flash
-   from software, we export this as an alert_led sysfs attr */
+/*
+ * The FSC hwmon family has the ability to force an attached alert led to flash
+ * from software, we export this as an alert_led sysfs attr
+ */
 static ssize_t show_alert_led(struct device *dev,
 	struct device_attribute *devattr, char *buf)
 {
@@ -540,7 +576,12 @@ static ssize_t store_alert_led(struct device *dev,
 {
 	u8 reg;
 	struct fschmd_data *data = dev_get_drvdata(dev);
-	unsigned long v = simple_strtoul(buf, NULL, 10);
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -754,8 +795,10 @@ static int watchdog_stop(struct fschmd_data *data)
 	}
 
 	data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
-	/* Don't store the stop flag in our watchdog control register copy, as
-	   its a write only bit (read always returns 0) */
+	/*
+	 * Don't store the stop flag in our watchdog control register copy, as
+	 * its a write only bit (read always returns 0)
+	 */
 	i2c_smbus_write_byte_data(data->client,
 		FSCHMD_REG_WDOG_CONTROL[data->kind],
 		data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
@@ -769,10 +812,12 @@ static int watchdog_open(struct inode *inode, struct file *filp)
 	struct fschmd_data *pos, *data = NULL;
 	int watchdog_is_open;
 
-	/* We get called from drivers/char/misc.c with misc_mtx hold, and we
-	   call misc_register() from fschmd_probe() with watchdog_data_mutex
-	   hold, as misc_register() takes the misc_mtx lock, this is a possible
-	   deadlock, so we use mutex_trylock here. */
+	/*
+	 * We get called from drivers/char/misc.c with misc_mtx hold, and we
+	 * call misc_register() from fschmd_probe() with watchdog_data_mutex
+	 * hold, as misc_register() takes the misc_mtx lock, this is a possible
+	 * deadlock, so we use mutex_trylock here.
+	 */
 	if (!mutex_trylock(&watchdog_data_mutex))
 		return -ERESTARTSYS;
 	list_for_each_entry(pos, &watchdog_data_list, list) {
@@ -847,7 +892,8 @@ static ssize_t watchdog_write(struct file *filp, const char __user *buf,
 	return count;
 }
 
-static long watchdog_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+static long watchdog_ioctl(struct file *filp, unsigned int cmd,
+			   unsigned long arg)
 {
 	struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
@@ -930,30 +976,38 @@ static const struct file_operations watchdog_fops = {
  * Detect, register, unregister and update device functions
  */
 
-/* DMI decode routine to read voltage scaling factors from special DMI tables,
-   which are available on FSC machines with an fscher or later chip. */
+/*
+ * DMI decode routine to read voltage scaling factors from special DMI tables,
+ * which are available on FSC machines with an fscher or later chip.
+ */
 static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy)
 {
 	int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
 
-	/* dmi code ugliness, we get passed the address of the contents of
-	   a complete DMI record, but in the form of a dmi_header pointer, in
-	   reality this address holds header->length bytes of which the header
-	   are the first 4 bytes */
+	/*
+	 * dmi code ugliness, we get passed the address of the contents of
+	 * a complete DMI record, but in the form of a dmi_header pointer, in
+	 * reality this address holds header->length bytes of which the header
+	 * are the first 4 bytes
+	 */
 	u8 *dmi_data = (u8 *)header;
 
 	/* We are looking for OEM-specific type 185 */
 	if (header->type != 185)
 		return;
 
-	/* we are looking for what Siemens calls "subtype" 19, the subtype
-	   is stored in byte 5 of the dmi block */
+	/*
+	 * we are looking for what Siemens calls "subtype" 19, the subtype
+	 * is stored in byte 5 of the dmi block
+	 */
 	if (header->length < 5 || dmi_data[4] != 19)
 		return;
 
-	/* After the subtype comes 1 unknown byte and then blocks of 5 bytes,
-	   consisting of what Siemens calls an "Entity" number, followed by
-	   2 16-bit words in LSB first order */
+	/*
+	 * After the subtype comes 1 unknown byte and then blocks of 5 bytes,
+	 * consisting of what Siemens calls an "Entity" number, followed by
+	 * 2 16-bit words in LSB first order
+	 */
 	for (i = 6; (i + 4) < header->length; i += 5) {
 		/* entity 1 - 3: voltage multiplier and offset */
 		if (dmi_data[i] >= 1 && dmi_data[i] <= 3) {
@@ -988,9 +1042,11 @@ static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy)
 			dmi_mult[i] = mult[i] * 10;
 			dmi_offset[i] = offset[i] * 10;
 		}
-		/* According to the docs there should be separate dmi entries
-		   for the mult's and offsets of in3-5 of the syl, but on
-		   my test machine these are not present */
+		/*
+		 * According to the docs there should be separate dmi entries
+		 * for the mult's and offsets of in3-5 of the syl, but on
+		 * my test machine these are not present
+		 */
 		dmi_mult[3] = dmi_mult[2];
 		dmi_mult[4] = dmi_mult[1];
 		dmi_mult[5] = dmi_mult[2];
@@ -1058,15 +1114,19 @@ static int fschmd_probe(struct i2c_client *client,
 	mutex_init(&data->watchdog_lock);
 	INIT_LIST_HEAD(&data->list);
 	kref_init(&data->kref);
-	/* Store client pointer in our data struct for watchdog usage
-	   (where the client is found through a data ptr instead of the
-	   otherway around) */
+	/*
+	 * Store client pointer in our data struct for watchdog usage
+	 * (where the client is found through a data ptr instead of the
+	 * otherway around)
+	 */
 	data->client = client;
 	data->kind = kind;
 
 	if (kind == fscpos) {
-		/* The Poseidon has hardwired temp limits, fill these
-		   in for the alarm resetting code */
+		/*
+		 * The Poseidon has hardwired temp limits, fill these
+		 * in for the alarm resetting code
+		 */
 		data->temp_max[0] = 70 + 128;
 		data->temp_max[1] = 50 + 128;
 		data->temp_max[2] = 50 + 128;
@@ -1157,9 +1217,11 @@ static int fschmd_probe(struct i2c_client *client,
 		goto exit_detach;
 	}
 
-	/* We take the data_mutex lock early so that watchdog_open() cannot
-	   run when misc_register() has completed, but we've not yet added
-	   our data to the watchdog_data_list (and set the default timeout) */
+	/*
+	 * We take the data_mutex lock early so that watchdog_open() cannot
+	 * run when misc_register() has completed, but we've not yet added
+	 * our data to the watchdog_data_list (and set the default timeout)
+	 */
 	mutex_lock(&watchdog_data_mutex);
 	for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
 		/* Register our watchdog part */
@@ -1225,8 +1287,10 @@ static int fschmd_remove(struct i2c_client *client)
 		mutex_unlock(&data->watchdog_lock);
 	}
 
-	/* Check if registered in case we're called from fschmd_detect
-	   to cleanup after an error */
+	/*
+	 * Check if registered in case we're called from fschmd_detect
+	 * to cleanup after an error
+	 */
 	if (data->hwmon_dev)
 		hwmon_device_unregister(data->hwmon_dev);
 
@@ -1269,8 +1333,10 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
 					client,
 					FSCHMD_REG_TEMP_LIMIT[data->kind][i]);
 
-			/* reset alarm if the alarm condition is gone,
-			   the chip doesn't do this itself */
+			/*
+			 * reset alarm if the alarm condition is gone,
+			 * the chip doesn't do this itself
+			 */
 			if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) ==
 					FSCHMD_TEMP_ALARM_MASK &&
 					data->temp_act[i] < data->temp_max[i])
@@ -1314,20 +1380,9 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
 	return data;
 }
 
-static int __init fschmd_init(void)
-{
-	return i2c_add_driver(&fschmd_driver);
-}
-
-static void __exit fschmd_exit(void)
-{
-	i2c_del_driver(&fschmd_driver);
-}
+module_i2c_driver(fschmd_driver);
 
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades "
 			"and Syleus driver");
 MODULE_LICENSE("GPL");
-
-module_init(fschmd_init);
-module_exit(fschmd_exit);
diff --git a/drivers/hwmon/g760a.c b/drivers/hwmon/g760a.c
index 781277d..ebcd269 100644
--- a/drivers/hwmon/g760a.c
+++ b/drivers/hwmon/g760a.c
@@ -1,17 +1,17 @@
 /*
-    g760a - Driver for the Global Mixed-mode Technology Inc. G760A
-            fan speed PWM controller chip
-
-    Copyright (C) 2007  Herbert Valerio Riedel <hvr@gnu.org>
-
-    Complete datasheet is available at GMT's website:
-      http://www.gmt.com.tw/product/datasheet/EDS-760A.pdf 
-
-    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.
-*/
+ * g760a - Driver for the Global Mixed-mode Technology Inc. G760A
+ *	   fan speed PWM controller chip
+ *
+ * Copyright (C) 2007  Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * Complete datasheet is available at GMT's website:
+ * http://www.gmt.com.tw/product/datasheet/EDS-760A.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -59,7 +59,8 @@ struct g760a_data {
 	u8 act_cnt; /*   formula: cnt = (CLK * 30)/(rpm * P) */
 	u8 fan_sta; /* bit 0: set when actual fan speed more than 20%
 		     *   outside requested fan speed
-		     * bit 1: set when fan speed below 1920 rpm */
+		     * bit 1: set when fan speed below 1920 rpm
+		     */
 };
 
 #define G760A_DEFAULT_CLK 32768
@@ -99,7 +100,7 @@ static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg,
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-/****************************************************************************
+/*
  * sysfs attributes
  */
 
@@ -192,7 +193,7 @@ static const struct attribute_group g760a_group = {
 	.attrs = g760a_attributes,
 };
 
-/****************************************************************************
+/*
  * new-style driver model code
  */
 
@@ -250,21 +251,8 @@ static int g760a_remove(struct i2c_client *client)
 	return 0;
 }
 
-/* module management */
-
-static int __init g760a_init(void)
-{
-	return i2c_add_driver(&g760a_driver);
-}
-
-static void __exit g760a_exit(void)
-{
-	i2c_del_driver(&g760a_driver);
-}
+module_i2c_driver(g760a_driver);
 
 MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
 MODULE_DESCRIPTION("GMT G760A driver");
 MODULE_LICENSE("GPL");
-
-module_init(g760a_init);
-module_exit(g760a_exit);
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index a13e2da..764a083 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -83,11 +83,12 @@ enum chips { gl518sm_r00, gl518sm_r80 };
 
 #define RAW_FROM_REG(val)	val
 
-#define BOOL_FROM_REG(val)	((val)?0:1)
-#define BOOL_TO_REG(val)	((val)?0:1)
+#define BOOL_FROM_REG(val)	((val) ? 0 : 1)
+#define BOOL_TO_REG(val)	((val) ? 0 : 1)
 
-#define TEMP_TO_REG(val)	(SENSORS_LIMIT(((((val)<0? \
-				(val)-500:(val)+500)/1000)+119),0,255))
+#define TEMP_TO_REG(val)	SENSORS_LIMIT(((((val) < 0 ? \
+				(val) - 500 : \
+				(val) + 500) / 1000) + 119), 0, 255)
 #define TEMP_FROM_REG(val)	(((val) - 119) * 1000)
 
 static inline u8 FAN_TO_REG(long rpm, int div)
@@ -98,13 +99,13 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 	rpmdiv = SENSORS_LIMIT(rpm, 1, 960000) * div;
 	return SENSORS_LIMIT((480000 + rpmdiv / 2) / rpmdiv, 1, 255);
 }
-#define FAN_FROM_REG(val,div)	((val)==0 ? 0 : (480000/((val)*(div))))
+#define FAN_FROM_REG(val, div)	((val) == 0 ? 0 : (480000 / ((val) * (div))))
 
-#define IN_TO_REG(val)		(SENSORS_LIMIT((((val)+9)/19),0,255))
-#define IN_FROM_REG(val)	((val)*19)
+#define IN_TO_REG(val)		SENSORS_LIMIT((((val) + 9) / 19), 0, 255)
+#define IN_FROM_REG(val)	((val) * 19)
 
-#define VDD_TO_REG(val)		(SENSORS_LIMIT((((val)*4+47)/95),0,255))
-#define VDD_FROM_REG(val)	(((val)*95+2)/4)
+#define VDD_TO_REG(val)		SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255)
+#define VDD_FROM_REG(val)	(((val) * 95 + 2) / 4)
 
 #define DIV_FROM_REG(val)	(1 << (val))
 
@@ -169,7 +170,8 @@ static struct i2c_driver gl518_driver = {
  */
 
 #define show(type, suffix, value)					\
-static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf)		\
+static ssize_t show_##suffix(struct device *dev,			\
+			     struct device_attribute *attr, char *buf)	\
 {									\
 	struct gl518_data *data = gl518_update_device(dev);		\
 	return sprintf(buf, "%d\n", type##_FROM_REG(data->value));	\
@@ -222,12 +224,16 @@ static ssize_t show_fan_div(struct device *dev,
 }
 
 #define set(type, suffix, value, reg)					\
-static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf,	\
-	size_t count)							\
+static ssize_t set_##suffix(struct device *dev,				\
+			    struct device_attribute *attr,		\
+			    const char *buf, size_t count)		\
 {									\
 	struct i2c_client *client = to_i2c_client(dev);			\
 	struct gl518_data *data = i2c_get_clientdata(client);		\
-	long val = simple_strtol(buf, NULL, 10);			\
+	long val;							\
+	int err = kstrtol(buf, 10, &val);				\
+	if (err)							\
+		return err;						\
 									\
 	mutex_lock(&data->update_lock);					\
 	data->value = type##_TO_REG(val);				\
@@ -237,13 +243,17 @@ static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, c
 }
 
 #define set_bits(type, suffix, value, reg, mask, shift)			\
-static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf,	\
-	size_t count)							\
+static ssize_t set_##suffix(struct device *dev,				\
+			    struct device_attribute *attr,		\
+			    const char *buf, size_t count)		\
 {									\
 	struct i2c_client *client = to_i2c_client(dev);			\
 	struct gl518_data *data = i2c_get_clientdata(client);		\
 	int regvalue;							\
-	unsigned long val = simple_strtoul(buf, NULL, 10);		\
+	unsigned long val;						\
+	int err = kstrtoul(buf, 10, &val);				\
+	if (err)							\
+		return err;						\
 									\
 	mutex_lock(&data->update_lock);					\
 	regvalue = gl518_read_value(client, reg);			\
@@ -280,7 +290,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	struct gl518_data *data = i2c_get_clientdata(client);
 	int nr = to_sensor_dev_attr(attr)->index;
 	int regvalue;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
@@ -308,13 +323,26 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 	struct gl518_data *data = i2c_get_clientdata(client);
 	int nr = to_sensor_dev_attr(attr)->index;
 	int regvalue;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	switch (val) {
-	case 1: val = 0; break;
-	case 2: val = 1; break;
-	case 4: val = 2; break;
-	case 8: val = 3; break;
+	case 1:
+		val = 0;
+		break;
+	case 2:
+		val = 1;
+		break;
+	case 4:
+		val = 2;
+		break;
+	case 8:
+		val = 3;
+		break;
 	default:
 		dev_err(dev, "Invalid fan clock divider %lu, choose one "
 			"of 1, 2, 4 or 8\n", val);
@@ -395,8 +423,12 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 	struct gl518_data *data = i2c_get_clientdata(client);
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	unsigned long bit;
+	int err;
+
+	err = kstrtoul(buf, 10, &bit);
+	if (err)
+		return err;
 
-	bit = simple_strtoul(buf, NULL, 10);
 	if (bit & ~1)
 		return -EINVAL;
 
@@ -528,12 +560,14 @@ static int gl518_probe(struct i2c_client *client,
 	gl518_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &gl518_group)))
+	err = sysfs_create_group(&client->dev.kobj, &gl518_group);
+	if (err)
 		goto exit_free;
-	if (data->type == gl518sm_r80)
-		if ((err = sysfs_create_group(&client->dev.kobj,
-					      &gl518_group_r80)))
+	if (data->type == gl518sm_r80) {
+		err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80);
+		if (err)
 			goto exit_remove_files;
+	}
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
@@ -554,8 +588,10 @@ exit:
 }
 
 
-/* Called when we have found a new GL518SM.
-   Note that we preserve D4:NoFan2 and D2:beep_enable. */
+/*
+ * Called when we have found a new GL518SM.
+ * Note that we preserve D4:NoFan2 and D2:beep_enable.
+ */
 static void gl518_init_client(struct i2c_client *client)
 {
 	/* Make sure we leave D7:Reset untouched */
@@ -585,9 +621,11 @@ static int gl518_remove(struct i2c_client *client)
 	return 0;
 }
 
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized
-   GL518 uses a high-byte first convention, which is exactly opposite to
-   the SMBus standard. */
+/*
+ * Registers 0x07 to 0x0c are word-sized, others are byte-sized
+ * GL518 uses a high-byte first convention, which is exactly opposite to
+ * the SMBus standard.
+ */
 static int gl518_read_value(struct i2c_client *client, u8 reg)
 {
 	if ((reg >= 0x07) && (reg <= 0x0c))
@@ -676,21 +714,10 @@ static struct gl518_data *gl518_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_gl518sm_init(void)
-{
-	return i2c_add_driver(&gl518_driver);
-}
-
-static void __exit sensors_gl518sm_exit(void)
-{
-	i2c_del_driver(&gl518_driver);
-}
+module_i2c_driver(gl518_driver);
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
 	"Kyosti Malkki <kmalkki@cc.hut.fi> and "
 	"Hong-Gunn Chew <hglinux@gunnet.org>");
 MODULE_DESCRIPTION("GL518SM driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_gl518sm_init);
-module_exit(sensors_gl518sm_exit);
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index cd6085b..5ff452b 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -1,25 +1,25 @@
 /*
-    gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
-                              Kyösti Mälkki <kmalkki@cc.hut.fi>
-    Copyright (c) 2005        Maarten Deprez <maartendeprez@users.sourceforge.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.
-
-*/
+ * gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
+ *			     Kyösti Mälkki <kmalkki@cc.hut.fi>
+ * Copyright (c) 2005	Maarten Deprez <maartendeprez@users.sourceforge.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.
+ *
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -41,10 +41,11 @@ MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=tempe
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
 
-/* Many GL520 constants specified below
-One of the inputs can be configured as either temp or voltage.
-That's why _TEMP2 and _IN4 access the same register
-*/
+/*
+ * Many GL520 constants specified below
+ * One of the inputs can be configured as either temp or voltage.
+ * That's why _TEMP2 and _IN4 access the same register
+ */
 
 /* The GL520 registers */
 #define GL520_REG_CHIP_ID		0x00
@@ -142,11 +143,11 @@ static ssize_t get_cpu_vid(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, get_cpu_vid, NULL);
 
-#define VDD_FROM_REG(val) (((val)*95+2)/4)
-#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255))
+#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4)
+#define VDD_TO_REG(val) SENSORS_LIMIT((((val) * 4 + 47) / 95), 0, 255)
 
-#define IN_FROM_REG(val) ((val)*19)
-#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255))
+#define IN_FROM_REG(val) ((val) * 19)
+#define IN_TO_REG(val) SENSORS_LIMIT((((val) + 9) / 19), 0, 255)
 
 static ssize_t get_in_input(struct device *dev, struct device_attribute *attr,
 			    char *buf)
@@ -193,8 +194,13 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
 	int n = to_sensor_dev_attr(attr)->index;
-	long v = simple_strtol(buf, NULL, 10);
 	u8 r;
+	long v;
+	int err;
+
+	err = kstrtol(buf, 10, &v);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -222,8 +228,13 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
 	int n = to_sensor_dev_attr(attr)->index;
-	long v = simple_strtol(buf, NULL, 10);
 	u8 r;
+	long v;
+	int err;
+
+	err = kstrtol(buf, 10, &v);
+	if (err)
+		return err;
 
 	if (n == 0)
 		r = VDD_TO_REG(v);
@@ -272,8 +283,10 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR,
 		get_in_max, set_in_max, 4);
 
 #define DIV_FROM_REG(val) (1 << (val))
-#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div))))
-#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255))
+#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) << (div))))
+#define FAN_TO_REG(val, div) ((val) <= 0 ? 0 : \
+	SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, \
+		      255))
 
 static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr,
 			     char *buf)
@@ -317,8 +330,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
 	int n = to_sensor_dev_attr(attr)->index;
-	unsigned long v = simple_strtoul(buf, NULL, 10);
 	u8 r;
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	r = FAN_TO_REG(v, data->fan_div[n]);
@@ -351,16 +369,30 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
 	int n = to_sensor_dev_attr(attr)->index;
-	unsigned long v = simple_strtoul(buf, NULL, 10);
 	u8 r;
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
 
 	switch (v) {
-	case 1: r = 0; break;
-	case 2: r = 1; break;
-	case 4: r = 2; break;
-	case 8: r = 3; break;
+	case 1:
+		r = 0;
+		break;
+	case 2:
+		r = 1;
+		break;
+	case 4:
+		r = 2;
+		break;
+	case 8:
+		r = 3;
+		break;
 	default:
-		dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
+		dev_err(&client->dev,
+	"fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
 		return -EINVAL;
 	}
 
@@ -385,7 +417,15 @@ static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
-	u8 r = simple_strtoul(buf, NULL, 10)?1:0;
+	u8 r;
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
+
+	r = (v ? 1 : 0);
 
 	mutex_lock(&data->update_lock);
 	data->fan_off = r;
@@ -410,7 +450,8 @@ static DEVICE_ATTR(fan1_off, S_IRUGO | S_IWUSR,
 		get_fan_off, set_fan_off);
 
 #define TEMP_FROM_REG(val) (((val) - 130) * 1000)
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255))
+#define TEMP_TO_REG(val) SENSORS_LIMIT(((((val) < 0 ? \
+			(val) - 500 : (val) + 500) / 1000) + 130), 0, 255)
 
 static ssize_t get_temp_input(struct device *dev, struct device_attribute *attr,
 			      char *buf)
@@ -430,8 +471,8 @@ static ssize_t get_temp_max(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n]));
 }
 
-static ssize_t get_temp_max_hyst(struct device *dev, struct device_attribute
-				 *attr, char *buf)
+static ssize_t get_temp_max_hyst(struct device *dev,
+				 struct device_attribute *attr, char *buf)
 {
 	int n = to_sensor_dev_attr(attr)->index;
 	struct gl520_data *data = gl520_update_device(dev);
@@ -445,7 +486,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
 	int n = to_sensor_dev_attr(attr)->index;
-	long v = simple_strtol(buf, NULL, 10);
+	long v;
+	int err;
+
+	err = kstrtol(buf, 10, &v);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[n] = TEMP_TO_REG(v);
@@ -460,7 +506,12 @@ static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
 	int n = to_sensor_dev_attr(attr)->index;
-	long v = simple_strtol(buf, NULL, 10);
+	long v;
+	int err;
+
+	err = kstrtol(buf, 10, &v);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max_hyst[n] = TEMP_TO_REG(v);
@@ -507,7 +558,15 @@ static ssize_t set_beep_enable(struct device *dev, struct device_attribute
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
-	u8 r = simple_strtoul(buf, NULL, 10)?0:1;
+	u8 r;
+	unsigned long v;
+	int err;
+
+	err = kstrtoul(buf, 10, &v);
+	if (err)
+		return err;
+
+	r = (v ? 0 : 1);
 
 	mutex_lock(&data->update_lock);
 	data->beep_enable = !r;
@@ -523,7 +582,12 @@ static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct gl520_data *data = i2c_get_clientdata(client);
-	u8 r = simple_strtoul(buf, NULL, 10);
+	unsigned long r;
+	int err;
+
+	err = kstrtoul(buf, 10, &r);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	r &= data->alarm_mask;
@@ -575,7 +639,11 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	unsigned long bit;
 
-	bit = simple_strtoul(buf, NULL, 10);
+	int err;
+
+	err = kstrtoul(buf, 10, &bit);
+	if (err)
+		return err;
 	if (bit & ~1)
 		return -EINVAL;
 
@@ -652,13 +720,16 @@ static const struct attribute_group gl520_group = {
 	.attrs = gl520_attributes,
 };
 
-static struct attribute *gl520_attributes_opt[] = {
+static struct attribute *gl520_attributes_in4[] = {
 	&sensor_dev_attr_in4_input.dev_attr.attr,
 	&sensor_dev_attr_in4_min.dev_attr.attr,
 	&sensor_dev_attr_in4_max.dev_attr.attr,
 	&sensor_dev_attr_in4_alarm.dev_attr.attr,
 	&sensor_dev_attr_in4_beep.dev_attr.attr,
+	NULL
+};
 
+static struct attribute *gl520_attributes_temp2[] = {
 	&sensor_dev_attr_temp2_input.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_max_hyst.dev_attr.attr,
@@ -667,8 +738,12 @@ static struct attribute *gl520_attributes_opt[] = {
 	NULL
 };
 
-static const struct attribute_group gl520_group_opt = {
-	.attrs = gl520_attributes_opt,
+static const struct attribute_group gl520_group_in4 = {
+	.attrs = gl520_attributes_in4,
+};
+
+static const struct attribute_group gl520_group_temp2 = {
+	.attrs = gl520_attributes_temp2,
 };
 
 
@@ -717,35 +792,17 @@ static int gl520_probe(struct i2c_client *client,
 	gl520_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group)))
+	err = sysfs_create_group(&client->dev.kobj, &gl520_group);
+	if (err)
 		goto exit_free;
 
-	if (data->two_temps) {
-		if ((err = device_create_file(&client->dev,
-				&sensor_dev_attr_temp2_input.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_temp2_max.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_temp2_max_hyst.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_temp2_alarm.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_temp2_beep.dev_attr)))
-			goto exit_remove_files;
-	} else {
-		if ((err = device_create_file(&client->dev,
-				&sensor_dev_attr_in4_input.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_in4_min.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_in4_max.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_in4_alarm.dev_attr))
-		 || (err = device_create_file(&client->dev,
-				&sensor_dev_attr_in4_beep.dev_attr)))
-			goto exit_remove_files;
-	}
+	if (data->two_temps)
+		err = sysfs_create_group(&client->dev.kobj, &gl520_group_temp2);
+	else
+		err = sysfs_create_group(&client->dev.kobj, &gl520_group_in4);
 
+	if (err)
+		goto exit_remove_files;
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
@@ -757,7 +814,8 @@ static int gl520_probe(struct i2c_client *client,
 
 exit_remove_files:
 	sysfs_remove_group(&client->dev.kobj, &gl520_group);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
+	sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
+	sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
 exit_free:
 	kfree(data);
 exit:
@@ -809,15 +867,18 @@ static int gl520_remove(struct i2c_client *client)
 
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&client->dev.kobj, &gl520_group);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group_opt);
+	sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
+	sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
 
 	kfree(data);
 	return 0;
 }
 
 
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized
-   GL520 uses a high-byte first convention */
+/*
+ * Registers 0x07 to 0x0c are word-sized, others are byte-sized
+ * GL520 uses a high-byte first convention
+ */
 static int gl520_read_value(struct i2c_client *client, u8 reg)
 {
 	if ((reg >= 0x07) && (reg <= 0x0c))
@@ -849,7 +910,8 @@ static struct gl520_data *gl520_update_device(struct device *dev)
 
 		data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
 		data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
-		data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f;
+		data->vid = gl520_read_value(client,
+					     GL520_REG_VID_INPUT) & 0x1f;
 
 		for (i = 0; i < 4; i++) {
 			data->in_input[i] = gl520_read_value(client,
@@ -910,23 +972,10 @@ static struct gl520_data *gl520_update_device(struct device *dev)
 	return data;
 }
 
-
-static int __init sensors_gl520sm_init(void)
-{
-	return i2c_add_driver(&gl520_driver);
-}
-
-static void __exit sensors_gl520sm_exit(void)
-{
-	i2c_del_driver(&gl520_driver);
-}
-
+module_i2c_driver(gl520_driver);
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
 	"Kyösti Mälkki <kmalkki@cc.hut.fi>, "
 	"Maarten Deprez <maartendeprez@users.sourceforge.net>");
 MODULE_DESCRIPTION("GL520SM driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_gl520sm_init);
-module_exit(sensors_gl520sm_exit);
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 932da8a..9f26400 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -40,7 +40,7 @@
  * available at http://developer.intel.com/.
  *
  * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094,
- * http://support.amd.com/us/Processor_TechDocs/26094.PDF 
+ * http://support.amd.com/us/Processor_TechDocs/26094.PDF
  * Table 74. VID Code Voltages
  * This corresponds to an arbitrary VRM code of 24 in the functions below.
  * These CPU models (K8 revision <= E) have 5 VID pins. See also:
@@ -83,27 +83,27 @@ int vid_from_reg(int val, u8 vrm)
 {
 	int vid;
 
-	switch(vrm) {
+	switch (vrm) {
 
-	case 100:               /* VRD 10.0 */
+	case 100:		/* VRD 10.0 */
 		/* compute in uV, round to mV */
 		val &= 0x3f;
-		if((val & 0x1f) == 0x1f)
+		if ((val & 0x1f) == 0x1f)
 			return 0;
-		if((val & 0x1f) <= 0x09 || val == 0x0a)
+		if ((val & 0x1f) <= 0x09 || val == 0x0a)
 			vid = 1087500 - (val & 0x1f) * 25000;
 		else
 			vid = 1862500 - (val & 0x1f) * 25000;
-		if(val & 0x20)
+		if (val & 0x20)
 			vid -= 12500;
-		return((vid + 500) / 1000);
+		return (vid + 500) / 1000;
 
 	case 110:		/* Intel Conroe */
 				/* compute in uV, round to mV */
 		val &= 0xff;
 		if (val < 0x02 || val > 0xb2)
 			return 0;
-		return((1600000 - (val - 2) * 6250 + 500) / 1000);
+		return (1600000 - (val - 2) * 6250 + 500) / 1000;
 
 	case 24:		/* Athlon64 & Opteron */
 		val &= 0x1f;
@@ -118,38 +118,38 @@ int vid_from_reg(int val, u8 vrm)
 	case 91:		/* VRM 9.1 */
 	case 90:		/* VRM 9.0 */
 		val &= 0x1f;
-		return(val == 0x1f ? 0 :
-		                       1850 - val * 25);
+		return val == 0x1f ? 0 :
+				     1850 - val * 25;
 
 	case 85:		/* VRM 8.5 */
 		val &= 0x1f;
-		return((val & 0x10  ? 25 : 0) +
+		return (val & 0x10  ? 25 : 0) +
 		       ((val & 0x0f) > 0x04 ? 2050 : 1250) -
-		       ((val & 0x0f) * 50));
+		       ((val & 0x0f) * 50);
 
 	case 84:		/* VRM 8.4 */
 		val &= 0x0f;
 				/* fall through */
 	case 82:		/* VRM 8.2 */
 		val &= 0x1f;
-		return(val == 0x1f ? 0 :
+		return val == 0x1f ? 0 :
 		       val & 0x10  ? 5100 - (val) * 100 :
-		                     2050 - (val) * 50);
+				     2050 - (val) * 50;
 	case 17:		/* Intel IMVP-II */
 		val &= 0x1f;
-		return(val & 0x10 ? 975 - (val & 0xF) * 25 :
-				    1750 - val * 50);
+		return val & 0x10 ? 975 - (val & 0xF) * 25 :
+				    1750 - val * 50;
 	case 13:
 	case 131:
 		val &= 0x3f;
 		/* Exception for Eden ULV 500 MHz */
 		if (vrm == 131 && val == 0x3f)
 			val++;
-		return(1708 - val * 16);
+		return 1708 - val * 16;
 	case 14:		/* Intel Core */
 				/* compute in uV, round to mV */
 		val &= 0x7f;
-		return(val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000);
+		return val > 0x77 ? 0 : (1500000 - (val * 12500) + 500) / 1000;
 	default:		/* report 0 for unknown */
 		if (vrm)
 			pr_warn("Requested unsupported VRM version (%u)\n",
@@ -157,7 +157,7 @@ int vid_from_reg(int val, u8 vrm)
 		return 0;
 	}
 }
-
+EXPORT_SYMBOL(vid_from_reg);
 
 /*
  * After this point is the code to automatically determine which
@@ -166,9 +166,10 @@ int vid_from_reg(int val, u8 vrm)
 
 struct vrm_model {
 	u8 vendor;
-	u8 eff_family;
-	u8 eff_model;
-	u8 eff_stepping;
+	u8 family;
+	u8 model_from;
+	u8 model_to;
+	u8 stepping_to;
 	u8 vrm_type;
 };
 
@@ -177,42 +178,52 @@ struct vrm_model {
 #ifdef CONFIG_X86
 
 /*
- * The stepping parameter is highest acceptable stepping for current line.
+ * The stepping_to parameter is highest acceptable stepping for current line.
  * The model match must be exact for 4-bit values. For model values 0x10
  * and above (extended model), all models below the parameter will match.
  */
 
 static struct vrm_model vrm_models[] = {
-	{X86_VENDOR_AMD, 0x6, ANY, ANY, 90},		/* Athlon Duron etc */
-	{X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24},		/* Athlon 64, Opteron */
-	/* In theory, all NPT family 0Fh processors have 6 VID pins and should
-	   thus use vrm 25, however in practice not all mainboards route the
-	   6th VID pin because it is never needed. So we use the 5 VID pin
-	   variant (vrm 24) for the models which exist today. */
-	{X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24},		/* NPT family 0Fh */
-	{X86_VENDOR_AMD, 0xF, ANY, ANY, 25},		/* future fam. 0Fh */
-	{X86_VENDOR_AMD, 0x10, ANY, ANY, 25},		/* NPT family 10h */
-
-	{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13},		/* Pentium M (130 nm) */
-	{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85},		/* Tualatin */
-	{X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13},		/* Pentium M (90 nm) */
-	{X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14},		/* Intel Core (65 nm) */
-	{X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110},		/* Intel Conroe */
-	{X86_VENDOR_INTEL, 0x6, ANY, ANY, 82},		/* any P6 */
-	{X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90},		/* P4 */
-	{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90},		/* P4 Willamette */
-	{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90},		/* P4 Northwood */
-	{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100},		/* Prescott and above assume VRD 10 */
-
-	{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},	/* Eden ESP/Ezra */
-	{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},	/* Ezra T */
-	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},	/* Nehemiah */
-	{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},	/* C3-M, Eden-N */
-	{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0},		/* No information */
-	{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13},	/* C7-M, C7, Eden (Esther) */
-	{X86_VENDOR_CENTAUR, 0x6, 0xD, ANY, 134},	/* C7-D, C7-M, C7, Eden (Esther) */
-
-	{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0}		/* stop here */
+	{X86_VENDOR_AMD, 0x6, 0x0, ANY, ANY, 90},	/* Athlon Duron etc */
+	{X86_VENDOR_AMD, 0xF, 0x0, 0x3F, ANY, 24},	/* Athlon 64, Opteron */
+	/*
+	 * In theory, all NPT family 0Fh processors have 6 VID pins and should
+	 * thus use vrm 25, however in practice not all mainboards route the
+	 * 6th VID pin because it is never needed. So we use the 5 VID pin
+	 * variant (vrm 24) for the models which exist today.
+	 */
+	{X86_VENDOR_AMD, 0xF, 0x40, 0x7F, ANY, 24},	/* NPT family 0Fh */
+	{X86_VENDOR_AMD, 0xF, 0x80, ANY, ANY, 25},	/* future fam. 0Fh */
+	{X86_VENDOR_AMD, 0x10, 0x0, ANY, ANY, 25},	/* NPT family 10h */
+
+	{X86_VENDOR_INTEL, 0x6, 0x0, 0x6, ANY, 82},	/* Pentium Pro,
+							 * Pentium II, Xeon,
+							 * Mobile Pentium,
+							 * Celeron */
+	{X86_VENDOR_INTEL, 0x6, 0x7, 0x7, ANY, 84},	/* Pentium III, Xeon */
+	{X86_VENDOR_INTEL, 0x6, 0x8, 0x8, ANY, 82},	/* Pentium III, Xeon */
+	{X86_VENDOR_INTEL, 0x6, 0x9, 0x9, ANY, 13},	/* Pentium M (130 nm) */
+	{X86_VENDOR_INTEL, 0x6, 0xA, 0xA, ANY, 82},	/* Pentium III Xeon */
+	{X86_VENDOR_INTEL, 0x6, 0xB, 0xB, ANY, 85},	/* Tualatin */
+	{X86_VENDOR_INTEL, 0x6, 0xD, 0xD, ANY, 13},	/* Pentium M (90 nm) */
+	{X86_VENDOR_INTEL, 0x6, 0xE, 0xE, ANY, 14},	/* Intel Core (65 nm) */
+	{X86_VENDOR_INTEL, 0x6, 0xF, ANY, ANY, 110},	/* Intel Conroe and
+							 * later */
+	{X86_VENDOR_INTEL, 0xF, 0x0, 0x0, ANY, 90},	/* P4 */
+	{X86_VENDOR_INTEL, 0xF, 0x1, 0x1, ANY, 90},	/* P4 Willamette */
+	{X86_VENDOR_INTEL, 0xF, 0x2, 0x2, ANY, 90},	/* P4 Northwood */
+	{X86_VENDOR_INTEL, 0xF, 0x3, ANY, ANY, 100},	/* Prescott and above
+							 * assume VRD 10 */
+
+	{X86_VENDOR_CENTAUR, 0x6, 0x7, 0x7, ANY, 85},	/* Eden ESP/Ezra */
+	{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x8, 0x7, 85},	/* Ezra T */
+	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, 0x7, 85},	/* Nehemiah */
+	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x9, ANY, 17},	/* C3-M, Eden-N */
+	{X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, 0x7, 0},	/* No information */
+	{X86_VENDOR_CENTAUR, 0x6, 0xA, 0xA, ANY, 13},	/* C7-M, C7,
+							 * Eden (Esther) */
+	{X86_VENDOR_CENTAUR, 0x6, 0xD, 0xD, ANY, 134},	/* C7-D, C7-M, C7,
+							 * Eden (Esther) */
 };
 
 /*
@@ -248,20 +259,17 @@ static u8 get_via_model_d_vrm(void)
 	}
 }
 
-static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
+static u8 find_vrm(u8 family, u8 model, u8 stepping, u8 vendor)
 {
-	int i = 0;
-
-	while (vrm_models[i].vendor!=X86_VENDOR_UNKNOWN) {
-		if (vrm_models[i].vendor==vendor)
-			if ((vrm_models[i].eff_family==eff_family)
-			 && ((vrm_models[i].eff_model==eff_model) ||
-			     (vrm_models[i].eff_model >= 0x10 &&
-			      eff_model <= vrm_models[i].eff_model) ||
-			     (vrm_models[i].eff_model==ANY)) &&
-			     (eff_stepping <= vrm_models[i].eff_stepping))
-				return vrm_models[i].vrm_type;
-		i++;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vrm_models); i++) {
+		if (vendor == vrm_models[i].vendor &&
+		    family == vrm_models[i].family &&
+		    model >= vrm_models[i].model_from &&
+		    model <= vrm_models[i].model_to &&
+		    stepping <= vrm_models[i].stepping_to)
+			return vrm_models[i].vrm_type;
 	}
 
 	return 0;
@@ -270,21 +278,12 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
 u8 vid_which_vrm(void)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
-	u32 eax;
-	u8 eff_family, eff_model, eff_stepping, vrm_ret;
+	u8 vrm_ret;
 
 	if (c->x86 < 6)		/* Any CPU with family lower than 6 */
-		return 0;	/* doesn't have VID and/or CPUID */
-
-	eax = cpuid_eax(1);
-	eff_family = ((eax & 0x00000F00)>>8);
-	eff_model  = ((eax & 0x000000F0)>>4);
-	eff_stepping = eax & 0xF;
-	if (eff_family == 0xF) {	/* use extended model & family */
-		eff_family += ((eax & 0x00F00000)>>20);
-		eff_model += ((eax & 0x000F0000)>>16)<<4;
-	}
-	vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor);
+		return 0;	/* doesn't have VID */
+
+	vrm_ret = find_vrm(c->x86, c->x86_model, c->x86_mask, c->x86_vendor);
 	if (vrm_ret == 134)
 		vrm_ret = get_via_model_d_vrm();
 	if (vrm_ret == 0)
@@ -300,8 +299,6 @@ u8 vid_which_vrm(void)
 	return 0;
 }
 #endif
-
-EXPORT_SYMBOL(vid_from_reg);
 EXPORT_SYMBOL(vid_which_vrm);
 
 MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 6460487..c3c471c 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -1,14 +1,14 @@
 /*
-    hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring
-
-    This file defines the sysfs class "hwmon", for use by sensors drivers.
-
-    Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; version 2 of the License.
-*/
+ * hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring
+ *
+ * This file defines the sysfs class "hwmon", for use by sensors drivers.
+ *
+ * Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -55,6 +55,7 @@ struct device *hwmon_device_register(struct device *dev)
 
 	return hwdev;
 }
+EXPORT_SYMBOL_GPL(hwmon_device_register);
 
 /**
  * hwmon_device_unregister - removes the previously registered class device
@@ -72,6 +73,7 @@ void hwmon_device_unregister(struct device *dev)
 		dev_dbg(dev->parent,
 			"hwmon_device_unregister() failed: bad class ID!\n");
 }
+EXPORT_SYMBOL_GPL(hwmon_device_unregister);
 
 static void __init hwmon_pci_quirks(void)
 {
@@ -119,9 +121,6 @@ static void __exit hwmon_exit(void)
 subsys_initcall(hwmon_init);
 module_exit(hwmon_exit);
 
-EXPORT_SYMBOL_GPL(hwmon_device_register);
-EXPORT_SYMBOL_GPL(hwmon_device_unregister);
-
 MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
 MODULE_DESCRIPTION("hardware monitoring sysfs/class support");
 MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index d22f241..a18882c 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -159,8 +159,12 @@ static ssize_t store_amb_min(struct device *dev,
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i5k_amb_data *data = dev_get_drvdata(dev);
-	unsigned long temp = simple_strtoul(buf, NULL, 10) / 500;
+	unsigned long temp;
+	int ret = kstrtoul(buf, 10, &temp);
+	if (ret < 0)
+		return ret;
 
+	temp = temp / 500;
 	if (temp > 255)
 		temp = 255;
 
@@ -175,8 +179,12 @@ static ssize_t store_amb_mid(struct device *dev,
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i5k_amb_data *data = dev_get_drvdata(dev);
-	unsigned long temp = simple_strtoul(buf, NULL, 10) / 500;
+	unsigned long temp;
+	int ret = kstrtoul(buf, 10, &temp);
+	if (ret < 0)
+		return ret;
 
+	temp = temp / 500;
 	if (temp > 255)
 		temp = 255;
 
@@ -191,8 +199,12 @@ static ssize_t store_amb_max(struct device *dev,
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i5k_amb_data *data = dev_get_drvdata(dev);
-	unsigned long temp = simple_strtoul(buf, NULL, 10) / 500;
+	unsigned long temp;
+	int ret = kstrtoul(buf, 10, &temp);
+	if (ret < 0)
+		return ret;
 
+	temp = temp / 500;
 	if (temp > 255)
 		temp = 255;
 
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index cc2981f..37f17e0 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -1045,7 +1045,7 @@ static struct aem_ro_sensor_template aem2_ro_sensors[] = {
 {"power6_average",	  aem2_show_pcap_value,	POWER_CAP_MIN_WARNING},
 {"power7_average",	  aem2_show_pcap_value,	POWER_CAP_MIN},
 
-{"power3_average", 	  aem2_show_pcap_value,	POWER_AUX},
+{"power3_average",	  aem2_show_pcap_value,	POWER_AUX},
 {"power_cap",		  aem2_show_pcap_value,	POWER_CAP},
 {NULL,                    NULL,                 0},
 };
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 0054d6f..0b204e4 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -176,12 +176,16 @@ static bool fix_pwm_polarity;
 #define IT87_REG_ALARM2        0x02
 #define IT87_REG_ALARM3        0x03
 
-/* The IT8718F and IT8720F have the VID value in a different register, in
-   Super-I/O configuration space. */
+/*
+ * The IT8718F and IT8720F have the VID value in a different register, in
+ * Super-I/O configuration space.
+ */
 #define IT87_REG_VID           0x0a
-/* The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
-   for fan divisors. Later IT8712F revisions must use 16-bit tachometer
-   mode. */
+/*
+ * The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
+ * for fan divisors. Later IT8712F revisions must use 16-bit tachometer
+ * mode.
+ */
 #define IT87_REG_FAN_DIV       0x0b
 #define IT87_REG_FAN_16BIT     0x0c
 
@@ -227,8 +231,10 @@ struct it87_sio_data {
 	u8 skip_pwm;
 };
 
-/* For each registered chip, we need to keep some data in memory.
-   The structure is dynamically allocated. */
+/*
+ * For each registered chip, we need to keep some data in memory.
+ * The structure is dynamically allocated.
+ */
 struct it87_data {
 	struct device *hwmon_dev;
 	enum chips type;
@@ -259,14 +265,16 @@ struct it87_data {
 	u8 fan_main_ctrl;	/* Register value */
 	u8 fan_ctl;		/* Register value */
 
-	/* The following 3 arrays correspond to the same registers up to
+	/*
+	 * The following 3 arrays correspond to the same registers up to
 	 * the IT8720F. The meaning of bits 6-0 depends on the value of bit
 	 * 7, and we want to preserve settings on mode changes, so we have
 	 * to track all values separately.
 	 * Starting with the IT8721F, the manual PWM duty cycles are stored
 	 * in separate registers (8-bit values), so the separate tracking
 	 * is no longer needed, but it is still done to keep the driver
-	 * simple. */
+	 * simple.
+	 */
 	u8 pwm_ctrl[3];		/* Register value */
 	u8 pwm_duty[3];		/* Manual PWM value set by user */
 	u8 pwm_temp_map[3];	/* PWM to temp. chan. mapping (bits 1-0) */
@@ -388,9 +396,11 @@ static const unsigned int pwm_freq[8] = {
 
 static inline int has_16bit_fans(const struct it87_data *data)
 {
-	/* IT8705F Datasheet 0.4.1, 3h == Version G.
-	   IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
-	   These are the first revisions with 16bit tachometer support. */
+	/*
+	 * IT8705F Datasheet 0.4.1, 3h == Version G.
+	 * IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
+	 * These are the first revisions with 16-bit tachometer support.
+	 */
 	return (data->type == it87 && data->revision >= 0x03)
 	    || (data->type == it8712 && data->revision >= 0x08)
 	    || data->type == it8716
@@ -402,9 +412,11 @@ static inline int has_16bit_fans(const struct it87_data *data)
 
 static inline int has_old_autopwm(const struct it87_data *data)
 {
-	/* The old automatic fan speed control interface is implemented
-	   by IT8705F chips up to revision F and IT8712F chips up to
-	   revision G. */
+	/*
+	 * The old automatic fan speed control interface is implemented
+	 * by IT8705F chips up to revision F and IT8712F chips up to
+	 * revision G.
+	 */
 	return (data->type == it87 && data->revision < 0x03)
 	    || (data->type == it8712 && data->revision < 0x08);
 }
@@ -606,10 +618,8 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
-
 	struct it87_data *data = it87_update_device(dev);
-	u8 reg = data->sensor;		/* In case the value is updated while
-					   we use it */
+	u8 reg = data->sensor;	    /* In case value is updated while used */
 
 	if (reg & (1 << nr))
 		return sprintf(buf, "3\n");  /* thermal diode */
@@ -894,8 +904,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 
 	mutex_lock(&data->update_lock);
 	if (has_newer_autopwm(data)) {
-		/* If we are in automatic mode, the PWM duty cycle register
-		 * is read-only so we can't write the value */
+		/*
+		 * If we are in automatic mode, the PWM duty cycle register
+		 * is read-only so we can't write the value.
+		 */
 		if (data->pwm_ctrl[nr] & 0x80) {
 			mutex_unlock(&data->update_lock);
 			return -EBUSY;
@@ -905,8 +917,10 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 				 data->pwm_duty[nr]);
 	} else {
 		data->pwm_duty[nr] = pwm_to_reg(data, val);
-		/* If we are in manual mode, write the duty cycle immediately;
-		 * otherwise, just store it for later use. */
+		/*
+		 * If we are in manual mode, write the duty cycle immediately;
+		 * otherwise, just store it for later use.
+		 */
 		if (!(data->pwm_ctrl[nr] & 0x80)) {
 			data->pwm_ctrl[nr] = data->pwm_duty[nr];
 			it87_write_value(data, IT87_REG_PWM(nr),
@@ -965,8 +979,10 @@ static ssize_t set_pwm_temp_map(struct device *dev,
 	long val;
 	u8 reg;
 
-	/* This check can go away if we ever support automatic fan speed
-	   control on newer chips. */
+	/*
+	 * This check can go away if we ever support automatic fan speed
+	 * control on newer chips.
+	 */
 	if (!has_old_autopwm(data)) {
 		dev_notice(dev, "Mapping change disabled for safety reasons\n");
 		return -EINVAL;
@@ -991,8 +1007,10 @@ static ssize_t set_pwm_temp_map(struct device *dev,
 
 	mutex_lock(&data->update_lock);
 	data->pwm_temp_map[nr] = reg;
-	/* If we are in automatic mode, write the temp mapping immediately;
-	 * otherwise, just store it for later use. */
+	/*
+	 * If we are in automatic mode, write the temp mapping immediately;
+	 * otherwise, just store it for later use.
+	 */
 	if (data->pwm_ctrl[nr] & 0x80) {
 		data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
 		it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
@@ -1162,9 +1180,11 @@ static ssize_t set_fan16_min(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-/* We want to use the same sysfs file names as 8-bit fans, but we need
-   different variable names, so we have to use SENSOR_ATTR instead of
-   SENSOR_DEVICE_ATTR. */
+/*
+ * We want to use the same sysfs file names as 8-bit fans, but we need
+ * different variable names, so we have to use SENSOR_ATTR instead of
+ * SENSOR_DEVICE_ATTR.
+ */
 #define show_fan16_offset(offset) \
 static struct sensor_device_attribute sensor_dev_attr_fan##offset##_input16 \
 	= SENSOR_ATTR(fan##offset##_input, S_IRUGO,		\
@@ -1321,12 +1341,12 @@ static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
 static ssize_t show_label(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
-	static const char *labels[] = {
+	static const char * const labels[] = {
 		"+5V",
 		"5VSB",
 		"Vbat",
 	};
-	static const char *labels_it8721[] = {
+	static const char * const labels_it8721[] = {
 		"+3.3V",
 		"3VSB",
 		"Vbat",
@@ -1736,12 +1756,14 @@ static int __init it87_find(unsigned short *address,
 	if (board_vendor && board_name) {
 		if (strcmp(board_vendor, "nVIDIA") == 0
 		 && strcmp(board_name, "FN68PT") == 0) {
-			/* On the Shuttle SN68PT, FAN_CTL2 is apparently not
-			   connected to a fan, but to something else. One user
-			   has reported instant system power-off when changing
-			   the PWM2 duty cycle, so we disable it.
-			   I use the board name string as the trigger in case
-			   the same board is ever used in other systems. */
+			/*
+			 * On the Shuttle SN68PT, FAN_CTL2 is apparently not
+			 * connected to a fan, but to something else. One user
+			 * has reported instant system power-off when changing
+			 * the PWM2 duty cycle, so we disable it.
+			 * I use the board name string as the trigger in case
+			 * the same board is ever used in other systems.
+			 */
 			pr_info("Disabling pwm2 due to hardware constraints\n");
 			sio_data->skip_pwm = (1 << 1);
 		}
@@ -1793,7 +1815,7 @@ static int __devinit it87_probe(struct platform_device *pdev)
 	int err = 0, i;
 	int enable_pwm_interface;
 	int fan_beep_need_rw;
-	static const char *names[] = {
+	static const char * const names[] = {
 		"it87",
 		"it8712",
 		"it8716",
@@ -1879,9 +1901,11 @@ static int __devinit it87_probe(struct platform_device *pdev)
 			if (!fan_beep_need_rw)
 				continue;
 
-			/* As we have a single beep enable bit for all fans,
+			/*
+			 * As we have a single beep enable bit for all fans,
 			 * only the first enabled fan has a writable attribute
-			 * for it. */
+			 * for it.
+			 */
 			if (sysfs_chmod_file(&dev->kobj,
 					     it87_attributes_fan_beep[i],
 					     S_IRUGO | S_IWUSR))
@@ -1961,18 +1985,22 @@ static int __devexit it87_remove(struct platform_device *pdev)
 	return 0;
 }
 
-/* Must be called with data->update_lock held, except during initialization.
-   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the IT87 access and should not be necessary. */
+/*
+ * Must be called with data->update_lock held, except during initialization.
+ * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
+ * would slow down the IT87 access and should not be necessary.
+ */
 static int it87_read_value(struct it87_data *data, u8 reg)
 {
 	outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
 	return inb_p(data->addr + IT87_DATA_REG_OFFSET);
 }
 
-/* Must be called with data->update_lock held, except during initialization.
-   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the IT87 access and should not be necessary. */
+/*
+ * Must be called with data->update_lock held, except during initialization.
+ * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
+ * would slow down the IT87 access and should not be necessary.
+ */
 static void it87_write_value(struct it87_data *data, u8 reg, u8 value)
 {
 	outb_p(reg, data->addr + IT87_ADDR_REG_OFFSET);
@@ -1983,15 +2011,19 @@ static void it87_write_value(struct it87_data *data, u8 reg, u8 value)
 static int __devinit it87_check_pwm(struct device *dev)
 {
 	struct it87_data *data = dev_get_drvdata(dev);
-	/* Some BIOSes fail to correctly configure the IT87 fans. All fans off
+	/*
+	 * Some BIOSes fail to correctly configure the IT87 fans. All fans off
 	 * and polarity set to active low is sign that this is the case so we
-	 * disable pwm control to protect the user. */
+	 * disable pwm control to protect the user.
+	 */
 	int tmp = it87_read_value(data, IT87_REG_FAN_CTL);
 	if ((tmp & 0x87) == 0) {
 		if (fix_pwm_polarity) {
-			/* The user asks us to attempt a chip reconfiguration.
+			/*
+			 * The user asks us to attempt a chip reconfiguration.
 			 * This means switching to active high polarity and
-			 * inverting all fan speed values. */
+			 * inverting all fan speed values.
+			 */
 			int i;
 			u8 pwm[3];
 
@@ -1999,10 +2031,12 @@ static int __devinit it87_check_pwm(struct device *dev)
 				pwm[i] = it87_read_value(data,
 							 IT87_REG_PWM(i));
 
-			/* If any fan is in automatic pwm mode, the polarity
+			/*
+			 * If any fan is in automatic pwm mode, the polarity
 			 * might be correct, as suspicious as it seems, so we
 			 * better don't change anything (but still disable the
-			 * PWM interface). */
+			 * PWM interface).
+			 */
 			if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) {
 				dev_info(dev, "Reconfiguring PWM to "
 					 "active high polarity\n");
@@ -2038,7 +2072,8 @@ static void __devinit it87_init_device(struct platform_device *pdev)
 	int tmp, i;
 	u8 mask;
 
-	/* For each PWM channel:
+	/*
+	 * For each PWM channel:
 	 * - If it is in automatic mode, setting to manual mode should set
 	 *   the fan to full speed by default.
 	 * - If it is in manual mode, we need a mapping to temperature
@@ -2048,18 +2083,21 @@ static void __devinit it87_init_device(struct platform_device *pdev)
 	 * prior to switching to a different mode.
 	 * Note that this is no longer needed for the IT8721F and later, as
 	 * these have separate registers for the temperature mapping and the
-	 * manual duty cycle. */
+	 * manual duty cycle.
+	 */
 	for (i = 0; i < 3; i++) {
 		data->pwm_temp_map[i] = i;
 		data->pwm_duty[i] = 0x7f;	/* Full speed */
 		data->auto_pwm[i][3] = 0x7f;	/* Full speed, hard-coded */
 	}
 
-	/* Some chips seem to have default value 0xff for all limit
+	/*
+	 * Some chips seem to have default value 0xff for all limit
 	 * registers. For low voltage limits it makes no sense and triggers
 	 * alarms, so change to 0 instead. For high temperature limits, it
 	 * means -1 degree C, which surprisingly doesn't trigger an alarm,
-	 * but is still confusing, so change to 127 degrees C. */
+	 * but is still confusing, so change to 127 degrees C.
+	 */
 	for (i = 0; i < 8; i++) {
 		tmp = it87_read_value(data, IT87_REG_VIN_MIN(i));
 		if (tmp == 0xff)
@@ -2071,10 +2109,12 @@ static void __devinit it87_init_device(struct platform_device *pdev)
 			it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
 	}
 
-	/* Temperature channels are not forcibly enabled, as they can be
+	/*
+	 * Temperature channels are not forcibly enabled, as they can be
 	 * set to two different sensor types and we can't guess which one
 	 * is correct for a given system. These channels can be enabled at
-	 * run-time through the temp{1-3}_type sysfs accessors if needed. */
+	 * run-time through the temp{1-3}_type sysfs accessors if needed.
+	 */
 
 	/* Check if voltage monitors are reset manually or by some reason */
 	tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
@@ -2157,8 +2197,10 @@ static struct it87_data *it87_update_device(struct device *dev)
 	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
 	    || !data->valid) {
 		if (update_vbat) {
-			/* Cleared after each update, so reenable.  Value
-			   returned by this read will be previous value */
+			/*
+			 * Cleared after each update, so reenable.  Value
+			 * returned by this read will be previous value
+			 */
 			it87_write_value(data, IT87_REG_CONFIG,
 				it87_read_value(data, IT87_REG_CONFIG) | 0x40);
 		}
@@ -2220,13 +2262,17 @@ static struct it87_data *it87_update_device(struct device *dev)
 			it87_update_pwm_ctrl(data, i);
 
 		data->sensor = it87_read_value(data, IT87_REG_TEMP_ENABLE);
-		/* The 8705 does not have VID capability.
-		   The 8718 and later don't use IT87_REG_VID for the
-		   same purpose. */
+		/*
+		 * The IT8705F does not have VID capability.
+		 * The IT8718F and later don't use IT87_REG_VID for the
+		 * same purpose.
+		 */
 		if (data->type == it8712 || data->type == it8716) {
 			data->vid = it87_read_value(data, IT87_REG_VID);
-			/* The older IT8712F revisions had only 5 VID pins,
-			   but we assume it is always safe to read 6 bits. */
+			/*
+			 * The older IT8712F revisions had only 5 VID pins,
+			 * but we assume it is always safe to read 6 bits.
+			 */
 			data->vid &= 0x3f;
 		}
 		data->last_updated = jiffies;
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
index 28c09ee..7c2a52e 100644
--- a/drivers/hwmon/jc42.c
+++ b/drivers/hwmon/jc42.c
@@ -324,8 +324,10 @@ set(temp_min, JC42_REG_TEMP_LOWER);
 set(temp_max, JC42_REG_TEMP_UPPER);
 set(temp_crit, JC42_REG_TEMP_CRITICAL);
 
-/* JC42.4 compliant chips only support four hysteresis values.
- * Pick best choice and go from there. */
+/*
+ * JC42.4 compliant chips only support four hysteresis values.
+ * Pick best choice and go from there.
+ */
 static ssize_t set_temp_crit_hyst(struct device *dev,
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
@@ -588,19 +590,8 @@ abort:
 	return ret;
 }
 
-static int __init sensors_jc42_init(void)
-{
-	return i2c_add_driver(&jc42_driver);
-}
-
-static void __exit sensors_jc42_exit(void)
-{
-	i2c_del_driver(&jc42_driver);
-}
+module_i2c_driver(jc42_driver);
 
 MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
 MODULE_DESCRIPTION("JC42 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_jc42_init);
-module_exit(sensors_jc42_exit);
diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c
index 41aa6a3..aba29d6 100644
--- a/drivers/hwmon/k10temp.c
+++ b/drivers/hwmon/k10temp.c
@@ -205,7 +205,7 @@ static void __devexit k10temp_remove(struct pci_dev *pdev)
 	pci_set_drvdata(pdev, NULL);
 }
 
-static const struct pci_device_id k10temp_id_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(k10temp_id_table) = {
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index b923bc2..5751019 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -46,7 +46,7 @@ struct k8temp_data {
 	unsigned long last_updated;	/* in jiffies */
 
 	/* registers values */
-	u8 sensorsp;		/* sensor presence bits - SEL_CORE & SEL_PLACE */
+	u8 sensorsp;		/* sensor presence bits - SEL_CORE, SEL_PLACE */
 	u32 temp[2][2];		/* core, place */
 	u8 swap_core_select;    /* meaning of SEL_CORE is inverted */
 	u32 temp_offset;
@@ -63,7 +63,7 @@ static struct k8temp_data *k8temp_update_device(struct device *dev)
 	if (!data->valid
 	    || time_after(jiffies, data->last_updated + HZ)) {
 		pci_read_config_byte(pdev, REG_TEMP, &tmp);
-		tmp &= ~(SEL_PLACE | SEL_CORE);		/* Select sensor 0, core0 */
+		tmp &= ~(SEL_PLACE | SEL_CORE);	/* Select sensor 0, core0 */
 		pci_write_config_byte(pdev, REG_TEMP, tmp);
 		pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]);
 
@@ -82,7 +82,7 @@ static struct k8temp_data *k8temp_update_device(struct device *dev)
 					      &data->temp[1][0]);
 
 			if (data->sensorsp & SEL_PLACE) {
-				tmp |= SEL_PLACE;	/* Select sensor 1, core1 */
+				tmp |= SEL_PLACE; /* Select sensor 1, core1 */
 				pci_write_config_byte(pdev, REG_TEMP, tmp);
 				pci_read_config_dword(pdev, REG_TEMP,
 						      &data->temp[1][1]);
@@ -136,7 +136,7 @@ static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0);
 static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-static const struct pci_device_id k8temp_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(k8temp_ids) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 	{ 0 },
 };
@@ -183,7 +183,8 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
 	u8 model, stepping;
 	struct k8temp_data *data;
 
-	if (!(data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct k8temp_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto exit;
 	}
@@ -217,7 +218,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
 		data->temp_offset = 21000;
 
 	pci_read_config_byte(pdev, REG_TEMP, &scfg);
-	scfg &= ~(SEL_PLACE | SEL_CORE);		/* Select sensor 0, core0 */
+	scfg &= ~(SEL_PLACE | SEL_CORE);	/* Select sensor 0, core0 */
 	pci_write_config_byte(pdev, REG_TEMP, scfg);
 	pci_read_config_byte(pdev, REG_TEMP, &scfg);
 
@@ -238,7 +239,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
 		pci_write_config_byte(pdev, REG_TEMP, scfg);
 		pci_read_config_dword(pdev, REG_TEMP, &temp);
 		scfg |= SEL_CORE;	/* prepare for next selection */
-		if (!((temp >> 16) & 0xff))	/* if temp is 0 -49C is not likely */
+		if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */
 			data->sensorsp &= ~SEL_PLACE;
 	}
 
@@ -246,7 +247,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev,
 		scfg &= ~SEL_PLACE;	/* Select sensor 0, core1 */
 		pci_write_config_byte(pdev, REG_TEMP, scfg);
 		pci_read_config_dword(pdev, REG_TEMP, &temp);
-		if (!((temp >> 16) & 0xff))	/* if temp is 0 -49C is not likely */
+		if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */
 			data->sensorsp &= ~SEL_CORE;
 	}
 
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index 58eded2..5b8c9ae 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -568,19 +568,8 @@ static struct i2c_driver pem_driver = {
 	.id_table = pem_id,
 };
 
-static int __init pem_init(void)
-{
-	return i2c_add_driver(&pem_driver);
-}
-
-static void __exit pem_exit(void)
-{
-	i2c_del_driver(&pem_driver);
-}
+module_i2c_driver(pem_driver);
 
 MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
 MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver");
 MODULE_LICENSE("GPL");
-
-module_init(pem_init);
-module_exit(pem_exit);
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 5e6457a..602a0f0 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -148,46 +148,9 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
 #define UPDATE_INTERVAL(max, rate) \
 			((1000 << (LM63_MAX_CONVRATE - (rate))) / (max))
 
-/*
- * Functions declaration
- */
-
-static int lm63_probe(struct i2c_client *client,
-		      const struct i2c_device_id *id);
-static int lm63_remove(struct i2c_client *client);
-
-static struct lm63_data *lm63_update_device(struct device *dev);
-
-static int lm63_detect(struct i2c_client *client, struct i2c_board_info *info);
-static void lm63_init_client(struct i2c_client *client);
-
 enum chips { lm63, lm64, lm96163 };
 
 /*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id lm63_id[] = {
-	{ "lm63", lm63 },
-	{ "lm64", lm64 },
-	{ "lm96163", lm96163 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, lm63_id);
-
-static struct i2c_driver lm63_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "lm63",
-	},
-	.probe		= lm63_probe,
-	.remove		= lm63_remove,
-	.id_table	= lm63_id,
-	.detect		= lm63_detect,
-	.address_list	= normal_i2c,
-};
-
-/*
  * Client data (each client gets its own)
  */
 
@@ -242,6 +205,145 @@ static inline int lut_temp_from_reg(struct lm63_data *data, int nr)
 	return data->temp8[nr] * (data->lut_temp_highres ? 500 : 1000);
 }
 
+static inline int lut_temp_to_reg(struct lm63_data *data, long val)
+{
+	val -= data->temp2_offset;
+	if (data->lut_temp_highres)
+		return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127500), 500);
+	else
+		return DIV_ROUND_CLOSEST(SENSORS_LIMIT(val, 0, 127000), 1000);
+}
+
+/*
+ * Update the lookup table register cache.
+ * client->update_lock must be held when calling this function.
+ */
+static void lm63_update_lut(struct i2c_client *client)
+{
+	struct lm63_data *data = i2c_get_clientdata(client);
+	int i;
+
+	if (time_after(jiffies, data->lut_last_updated + 5 * HZ) ||
+	    !data->lut_valid) {
+		for (i = 0; i < data->lut_size; i++) {
+			data->pwm1[1 + i] = i2c_smbus_read_byte_data(client,
+					    LM63_REG_LUT_PWM(i));
+			data->temp8[3 + i] = i2c_smbus_read_byte_data(client,
+					     LM63_REG_LUT_TEMP(i));
+		}
+		data->lut_temp_hyst = i2c_smbus_read_byte_data(client,
+				      LM63_REG_LUT_TEMP_HYST);
+
+		data->lut_last_updated = jiffies;
+		data->lut_valid = 1;
+	}
+}
+
+static struct lm63_data *lm63_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	unsigned long next_update;
+
+	mutex_lock(&data->update_lock);
+
+	next_update = data->last_updated
+	  + msecs_to_jiffies(data->update_interval) + 1;
+
+	if (time_after(jiffies, next_update) || !data->valid) {
+		if (data->config & 0x04) { /* tachometer enabled  */
+			/* order matters for fan1_input */
+			data->fan[0] = i2c_smbus_read_byte_data(client,
+				       LM63_REG_TACH_COUNT_LSB) & 0xFC;
+			data->fan[0] |= i2c_smbus_read_byte_data(client,
+					LM63_REG_TACH_COUNT_MSB) << 8;
+			data->fan[1] = (i2c_smbus_read_byte_data(client,
+					LM63_REG_TACH_LIMIT_LSB) & 0xFC)
+				     | (i2c_smbus_read_byte_data(client,
+					LM63_REG_TACH_LIMIT_MSB) << 8);
+		}
+
+		data->pwm1_freq = i2c_smbus_read_byte_data(client,
+				  LM63_REG_PWM_FREQ);
+		if (data->pwm1_freq == 0)
+			data->pwm1_freq = 1;
+		data->pwm1[0] = i2c_smbus_read_byte_data(client,
+				LM63_REG_PWM_VALUE);
+
+		data->temp8[0] = i2c_smbus_read_byte_data(client,
+				 LM63_REG_LOCAL_TEMP);
+		data->temp8[1] = i2c_smbus_read_byte_data(client,
+				 LM63_REG_LOCAL_HIGH);
+
+		/* order matters for temp2_input */
+		data->temp11[0] = i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_TEMP_MSB) << 8;
+		data->temp11[0] |= i2c_smbus_read_byte_data(client,
+				   LM63_REG_REMOTE_TEMP_LSB);
+		data->temp11[1] = (i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_LOW_MSB) << 8)
+				| i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_LOW_LSB);
+		data->temp11[2] = (i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_HIGH_MSB) << 8)
+				| i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_HIGH_LSB);
+		data->temp11[3] = (i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_OFFSET_MSB) << 8)
+				| i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_OFFSET_LSB);
+
+		if (data->kind == lm96163)
+			data->temp11u = (i2c_smbus_read_byte_data(client,
+					LM96163_REG_REMOTE_TEMP_U_MSB) << 8)
+				      | i2c_smbus_read_byte_data(client,
+					LM96163_REG_REMOTE_TEMP_U_LSB);
+
+		data->temp8[2] = i2c_smbus_read_byte_data(client,
+				 LM63_REG_REMOTE_TCRIT);
+		data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
+					LM63_REG_REMOTE_TCRIT_HYST);
+
+		data->alarms = i2c_smbus_read_byte_data(client,
+			       LM63_REG_ALERT_STATUS) & 0x7F;
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	lm63_update_lut(client);
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/*
+ * Trip points in the lookup table should be in ascending order for both
+ * temperatures and PWM output values.
+ */
+static int lm63_lut_looks_bad(struct i2c_client *client)
+{
+	struct lm63_data *data = i2c_get_clientdata(client);
+	int i;
+
+	mutex_lock(&data->update_lock);
+	lm63_update_lut(client);
+
+	for (i = 1; i < data->lut_size; i++) {
+		if (data->pwm1[1 + i - 1] > data->pwm1[1 + i]
+		 || data->temp8[3 + i - 1] > data->temp8[3 + i]) {
+			dev_warn(&client->dev,
+				 "Lookup table doesn't look sane (check entries %d and %d)\n",
+				 i, i + 1);
+			break;
+		}
+	}
+	mutex_unlock(&data->update_lock);
+
+	return i == data->lut_size ? 0 : 1;
+}
+
 /*
  * Sysfs callback functions and files
  */
@@ -294,13 +396,16 @@ static ssize_t show_pwm1(struct device *dev, struct device_attribute *devattr,
 	return sprintf(buf, "%d\n", pwm);
 }
 
-static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
+static ssize_t set_pwm1(struct device *dev, struct device_attribute *devattr,
 			const char *buf, size_t count)
 {
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm63_data *data = i2c_get_clientdata(client);
+	int nr = attr->index;
 	unsigned long val;
 	int err;
+	u8 reg;
 
 	if (!(data->config_fan & 0x20)) /* register is read-only */
 		return -EPERM;
@@ -309,11 +414,13 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
 	if (err)
 		return err;
 
+	reg = nr ? LM63_REG_LUT_PWM(nr - 1) : LM63_REG_PWM_VALUE;
 	val = SENSORS_LIMIT(val, 0, 255);
+
 	mutex_lock(&data->update_lock);
-	data->pwm1[0] = data->pwm_highres ? val :
+	data->pwm1[nr] = data->pwm_highres ? val :
 			(val * data->pwm1_freq * 2 + 127) / 255;
-	i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1[0]);
+	i2c_smbus_write_byte_data(client, reg, data->pwm1[nr]);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -325,6 +432,41 @@ static ssize_t show_pwm1_enable(struct device *dev,
 	return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
 }
 
+static ssize_t set_pwm1_enable(struct device *dev,
+			       struct device_attribute *dummy,
+			       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val < 1 || val > 2)
+		return -EINVAL;
+
+	/*
+	 * Only let the user switch to automatic mode if the lookup table
+	 * looks sane.
+	 */
+	if (val == 2 && lm63_lut_looks_bad(client))
+		return -EPERM;
+
+	mutex_lock(&data->update_lock);
+	data->config_fan = i2c_smbus_read_byte_data(client,
+						    LM63_REG_CONFIG_FAN);
+	if (val == 1)
+		data->config_fan |= 0x20;
+	else
+		data->config_fan &= ~0x20;
+	i2c_smbus_write_byte_data(client, LM63_REG_CONFIG_FAN,
+	data->config_fan);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
 /*
  * There are 8bit registers for both local(temp1) and remote(temp2) sensor.
  * For remote sensor registers temp2_offset has to be considered,
@@ -367,23 +509,31 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm63_data *data = i2c_get_clientdata(client);
 	int nr = attr->index;
-	int reg = nr == 2 ? LM63_REG_REMOTE_TCRIT : LM63_REG_LOCAL_HIGH;
 	long val;
 	int err;
 	int temp;
+	u8 reg;
 
 	err = kstrtol(buf, 10, &val);
 	if (err)
 		return err;
 
 	mutex_lock(&data->update_lock);
-	if (nr == 2) {
+	switch (nr) {
+	case 2:
+		reg = LM63_REG_REMOTE_TCRIT;
 		if (data->remote_unsigned)
 			temp = TEMP8U_TO_REG(val - data->temp2_offset);
 		else
 			temp = TEMP8_TO_REG(val - data->temp2_offset);
-	} else {
+		break;
+	case 1:
+		reg = LM63_REG_LOCAL_HIGH;
 		temp = TEMP8_TO_REG(val);
+		break;
+	default:	/* lookup table */
+		reg = LM63_REG_LUT_TEMP(nr - 3);
+		temp = lut_temp_to_reg(data, val);
 	}
 	data->temp8[nr] = temp;
 	i2c_smbus_write_byte_data(client, reg, temp);
@@ -613,65 +763,78 @@ static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
 	set_fan, 1);
 
 static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1, 0);
-static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IRUGO, show_pwm1, NULL, 1);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IRUGO,
-	show_lut_temp, NULL, 3);
+static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+	show_pwm1_enable, set_pwm1_enable);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 1);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 3);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point1_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 3);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IRUGO, show_pwm1, NULL, 2);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IRUGO,
-	show_lut_temp, NULL, 4);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 2);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 4);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point2_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 4);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IRUGO, show_pwm1, NULL, 3);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IRUGO,
-	show_lut_temp, NULL, 5);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point3_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 3);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 5);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point3_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 5);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IRUGO, show_pwm1, NULL, 4);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IRUGO,
-	show_lut_temp, NULL, 6);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point4_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 4);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 6);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point4_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 6);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IRUGO, show_pwm1, NULL, 5);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IRUGO,
-	show_lut_temp, NULL, 7);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point5_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 5);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 7);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point5_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 7);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IRUGO, show_pwm1, NULL, 6);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IRUGO,
-	show_lut_temp, NULL, 8);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point6_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 6);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 8);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point6_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 8);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IRUGO, show_pwm1, NULL, 7);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IRUGO,
-	show_lut_temp, NULL, 9);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point7_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 7);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 9);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point7_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 9);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IRUGO, show_pwm1, NULL, 8);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IRUGO,
-	show_lut_temp, NULL, 10);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point8_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 8);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 10);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point8_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 10);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IRUGO, show_pwm1, NULL, 9);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IRUGO,
-	show_lut_temp, NULL, 11);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point9_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 9);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 11);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point9_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 11);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IRUGO, show_pwm1, NULL, 10);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IRUGO,
-	show_lut_temp, NULL, 12);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point10_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 10);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 12);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point10_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 12);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IRUGO, show_pwm1, NULL, 11);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IRUGO,
-	show_lut_temp, NULL, 13);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point11_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 11);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 13);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point11_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 13);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IRUGO, show_pwm1, NULL, 12);
-static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IRUGO,
-	show_lut_temp, NULL, 14);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point12_pwm, S_IWUSR | S_IRUGO,
+	show_pwm1, set_pwm1, 12);
+static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp, S_IWUSR | S_IRUGO,
+	show_lut_temp, set_temp8, 14);
 static SENSOR_DEVICE_ATTR(pwm1_auto_point12_temp_hyst, S_IRUGO,
 	show_lut_temp_hyst, NULL, 14);
 
@@ -817,28 +980,25 @@ static const struct attribute_group lm63_group_fan1 = {
  */
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm63_detect(struct i2c_client *new_client,
+static int lm63_detect(struct i2c_client *client,
 		       struct i2c_board_info *info)
 {
-	struct i2c_adapter *adapter = new_client->adapter;
+	struct i2c_adapter *adapter = client->adapter;
 	u8 man_id, chip_id, reg_config1, reg_config2;
 	u8 reg_alert_status, reg_alert_mask;
-	int address = new_client->addr;
+	int address = client->addr;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	man_id = i2c_smbus_read_byte_data(new_client, LM63_REG_MAN_ID);
-	chip_id = i2c_smbus_read_byte_data(new_client, LM63_REG_CHIP_ID);
+	man_id = i2c_smbus_read_byte_data(client, LM63_REG_MAN_ID);
+	chip_id = i2c_smbus_read_byte_data(client, LM63_REG_CHIP_ID);
 
-	reg_config1 = i2c_smbus_read_byte_data(new_client,
-		      LM63_REG_CONFIG1);
-	reg_config2 = i2c_smbus_read_byte_data(new_client,
-		      LM63_REG_CONFIG2);
-	reg_alert_status = i2c_smbus_read_byte_data(new_client,
+	reg_config1 = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
+	reg_config2 = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG2);
+	reg_alert_status = i2c_smbus_read_byte_data(client,
 			   LM63_REG_ALERT_STATUS);
-	reg_alert_mask = i2c_smbus_read_byte_data(new_client,
-			 LM63_REG_ALERT_MASK);
+	reg_alert_mask = i2c_smbus_read_byte_data(client, LM63_REG_ALERT_MASK);
 
 	if (man_id != 0x01 /* National Semiconductor */
 	 || (reg_config1 & 0x18) != 0x00
@@ -863,74 +1023,6 @@ static int lm63_detect(struct i2c_client *new_client,
 	return 0;
 }
 
-static int lm63_probe(struct i2c_client *new_client,
-		      const struct i2c_device_id *id)
-{
-	struct lm63_data *data;
-	int err;
-
-	data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL);
-	if (!data) {
-		err = -ENOMEM;
-		goto exit;
-	}
-
-	i2c_set_clientdata(new_client, data);
-	data->valid = 0;
-	mutex_init(&data->update_lock);
-
-	/* Set the device type */
-	data->kind = id->driver_data;
-	if (data->kind == lm64)
-		data->temp2_offset = 16000;
-
-	/* Initialize chip */
-	lm63_init_client(new_client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&new_client->dev.kobj, &lm63_group);
-	if (err)
-		goto exit_free;
-	if (data->config & 0x04) { /* tachometer enabled */
-		err = sysfs_create_group(&new_client->dev.kobj,
-					 &lm63_group_fan1);
-		if (err)
-			goto exit_remove_files;
-	}
-	if (data->kind == lm96163) {
-		err = device_create_file(&new_client->dev,
-					 &dev_attr_temp2_type);
-		if (err)
-			goto exit_remove_files;
-
-		err = sysfs_create_group(&new_client->dev.kobj,
-					 &lm63_group_extra_lut);
-		if (err)
-			goto exit_remove_files;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&new_client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	return 0;
-
-exit_remove_files:
-	sysfs_remove_group(&new_client->dev.kobj, &lm63_group);
-	sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1);
-	if (data->kind == lm96163) {
-		device_remove_file(&new_client->dev, &dev_attr_temp2_type);
-		sysfs_remove_group(&new_client->dev.kobj,
-				   &lm63_group_extra_lut);
-	}
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
 /*
  * Ideally we shouldn't have to initialize anything, since the BIOS
  * should have taken care of everything
@@ -1010,128 +1102,113 @@ static void lm63_init_client(struct i2c_client *client)
 		(data->config_fan & 0x20) ? "manual" : "auto");
 }
 
-static int lm63_remove(struct i2c_client *client)
+static int lm63_probe(struct i2c_client *client,
+		      const struct i2c_device_id *id)
 {
-	struct lm63_data *data = i2c_get_clientdata(client);
+	struct lm63_data *data;
+	int err;
 
-	hwmon_device_unregister(data->hwmon_dev);
+	data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	i2c_set_clientdata(client, data);
+	data->valid = 0;
+	mutex_init(&data->update_lock);
+
+	/* Set the device type */
+	data->kind = id->driver_data;
+	if (data->kind == lm64)
+		data->temp2_offset = 16000;
+
+	/* Initialize chip */
+	lm63_init_client(client);
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&client->dev.kobj, &lm63_group);
+	if (err)
+		goto exit_free;
+	if (data->config & 0x04) { /* tachometer enabled */
+		err = sysfs_create_group(&client->dev.kobj, &lm63_group_fan1);
+		if (err)
+			goto exit_remove_files;
+	}
+	if (data->kind == lm96163) {
+		err = device_create_file(&client->dev, &dev_attr_temp2_type);
+		if (err)
+			goto exit_remove_files;
+
+		err = sysfs_create_group(&client->dev.kobj,
+					 &lm63_group_extra_lut);
+		if (err)
+			goto exit_remove_files;
+	}
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto exit_remove_files;
+	}
+
+	return 0;
+
+exit_remove_files:
 	sysfs_remove_group(&client->dev.kobj, &lm63_group);
 	sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
 	if (data->kind == lm96163) {
 		device_remove_file(&client->dev, &dev_attr_temp2_type);
 		sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut);
 	}
-
+exit_free:
 	kfree(data);
-	return 0;
+exit:
+	return err;
 }
 
-static struct lm63_data *lm63_update_device(struct device *dev)
+static int lm63_remove(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct lm63_data *data = i2c_get_clientdata(client);
-	unsigned long next_update;
-	int i;
 
-	mutex_lock(&data->update_lock);
-
-	next_update = data->last_updated
-	  + msecs_to_jiffies(data->update_interval) + 1;
-
-	if (time_after(jiffies, next_update) || !data->valid) {
-		if (data->config & 0x04) { /* tachometer enabled  */
-			/* order matters for fan1_input */
-			data->fan[0] = i2c_smbus_read_byte_data(client,
-				       LM63_REG_TACH_COUNT_LSB) & 0xFC;
-			data->fan[0] |= i2c_smbus_read_byte_data(client,
-					LM63_REG_TACH_COUNT_MSB) << 8;
-			data->fan[1] = (i2c_smbus_read_byte_data(client,
-					LM63_REG_TACH_LIMIT_LSB) & 0xFC)
-				     | (i2c_smbus_read_byte_data(client,
-					LM63_REG_TACH_LIMIT_MSB) << 8);
-		}
-
-		data->pwm1_freq = i2c_smbus_read_byte_data(client,
-				  LM63_REG_PWM_FREQ);
-		if (data->pwm1_freq == 0)
-			data->pwm1_freq = 1;
-		data->pwm1[0] = i2c_smbus_read_byte_data(client,
-				LM63_REG_PWM_VALUE);
-
-		data->temp8[0] = i2c_smbus_read_byte_data(client,
-				 LM63_REG_LOCAL_TEMP);
-		data->temp8[1] = i2c_smbus_read_byte_data(client,
-				 LM63_REG_LOCAL_HIGH);
-
-		/* order matters for temp2_input */
-		data->temp11[0] = i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_TEMP_MSB) << 8;
-		data->temp11[0] |= i2c_smbus_read_byte_data(client,
-				   LM63_REG_REMOTE_TEMP_LSB);
-		data->temp11[1] = (i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_LOW_MSB) << 8)
-				| i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_LOW_LSB);
-		data->temp11[2] = (i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_HIGH_MSB) << 8)
-				| i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_HIGH_LSB);
-		data->temp11[3] = (i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_OFFSET_MSB) << 8)
-				| i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_OFFSET_LSB);
-
-		if (data->kind == lm96163)
-			data->temp11u = (i2c_smbus_read_byte_data(client,
-					LM96163_REG_REMOTE_TEMP_U_MSB) << 8)
-				      | i2c_smbus_read_byte_data(client,
-					LM96163_REG_REMOTE_TEMP_U_LSB);
-
-		data->temp8[2] = i2c_smbus_read_byte_data(client,
-				 LM63_REG_REMOTE_TCRIT);
-		data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
-					LM63_REG_REMOTE_TCRIT_HYST);
-
-		data->alarms = i2c_smbus_read_byte_data(client,
-			       LM63_REG_ALERT_STATUS) & 0x7F;
-
-		data->last_updated = jiffies;
-		data->valid = 1;
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &lm63_group);
+	sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
+	if (data->kind == lm96163) {
+		device_remove_file(&client->dev, &dev_attr_temp2_type);
+		sysfs_remove_group(&client->dev.kobj, &lm63_group_extra_lut);
 	}
 
-	if (time_after(jiffies, data->lut_last_updated + 5 * HZ) ||
-	    !data->lut_valid) {
-		for (i = 0; i < data->lut_size; i++) {
-			data->pwm1[1 + i] = i2c_smbus_read_byte_data(client,
-					    LM63_REG_LUT_PWM(i));
-			data->temp8[3 + i] = i2c_smbus_read_byte_data(client,
-					     LM63_REG_LUT_TEMP(i));
-		}
-		data->lut_temp_hyst = i2c_smbus_read_byte_data(client,
-				      LM63_REG_LUT_TEMP_HYST);
-
-		data->lut_last_updated = jiffies;
-		data->lut_valid = 1;
-	}
+	kfree(data);
+	return 0;
+}
 
-	mutex_unlock(&data->update_lock);
+/*
+ * Driver data (common to all clients)
+ */
 
-	return data;
-}
+static const struct i2c_device_id lm63_id[] = {
+	{ "lm63", lm63 },
+	{ "lm64", lm64 },
+	{ "lm96163", lm96163 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lm63_id);
 
-static int __init sensors_lm63_init(void)
-{
-	return i2c_add_driver(&lm63_driver);
-}
+static struct i2c_driver lm63_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "lm63",
+	},
+	.probe		= lm63_probe,
+	.remove		= lm63_remove,
+	.id_table	= lm63_id,
+	.detect		= lm63_detect,
+	.address_list	= normal_i2c,
+};
 
-static void __exit sensors_lm63_exit(void)
-{
-	i2c_del_driver(&lm63_driver);
-}
+module_i2c_driver(lm63_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("LM63 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm63_init);
-module_exit(sensors_lm63_exit);
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index c274ea2..472f795 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -57,7 +57,7 @@ static ssize_t lm70_sense_temp(struct device *dev,
 	struct spi_device *spi = to_spi_device(dev);
 	int status, val = 0;
 	u8 rxbuf[2];
-	s16 raw=0;
+	s16 raw = 0;
 	struct lm70 *p_lm70 = spi_get_drvdata(spi);
 
 	if (mutex_lock_interruptible(&p_lm70->lock))
@@ -156,6 +156,15 @@ static int __devinit lm70_probe(struct spi_device *spi)
 	mutex_init(&p_lm70->lock);
 	p_lm70->chip = chip;
 
+	spi_set_drvdata(spi, p_lm70);
+
+	status = device_create_file(&spi->dev, &dev_attr_temp1_input);
+	if (status)
+		goto out_dev_create_temp_file_failed;
+	status = device_create_file(&spi->dev, &dev_attr_name);
+	if (status)
+		goto out_dev_create_file_failed;
+
 	/* sysfs hook */
 	p_lm70->hwmon_dev = hwmon_device_register(&spi->dev);
 	if (IS_ERR(p_lm70->hwmon_dev)) {
@@ -163,20 +172,14 @@ static int __devinit lm70_probe(struct spi_device *spi)
 		status = PTR_ERR(p_lm70->hwmon_dev);
 		goto out_dev_reg_failed;
 	}
-	spi_set_drvdata(spi, p_lm70);
-
-	if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))
-	 || (status = device_create_file(&spi->dev, &dev_attr_name))) {
-		dev_dbg(&spi->dev, "device_create_file failure.\n");
-		goto out_dev_create_file_failed;
-	}
 
 	return 0;
 
+out_dev_reg_failed:
+	device_remove_file(&spi->dev, &dev_attr_name);
 out_dev_create_file_failed:
 	device_remove_file(&spi->dev, &dev_attr_temp1_input);
-	hwmon_device_unregister(p_lm70->hwmon_dev);
-out_dev_reg_failed:
+out_dev_create_temp_file_failed:
 	spi_set_drvdata(spi, NULL);
 	kfree(p_lm70);
 	return status;
@@ -186,9 +189,9 @@ static int __devexit lm70_remove(struct spi_device *spi)
 {
 	struct lm70 *p_lm70 = spi_get_drvdata(spi);
 
+	hwmon_device_unregister(p_lm70->hwmon_dev);
 	device_remove_file(&spi->dev, &dev_attr_temp1_input);
 	device_remove_file(&spi->dev, &dev_attr_name);
-	hwmon_device_unregister(p_lm70->hwmon_dev);
 	spi_set_drvdata(spi, NULL);
 	kfree(p_lm70);
 
@@ -213,18 +216,7 @@ static struct spi_driver lm70_driver = {
 	.remove	= __devexit_p(lm70_remove),
 };
 
-static int __init init_lm70(void)
-{
-	return spi_register_driver(&lm70_driver);
-}
-
-static void __exit cleanup_lm70(void)
-{
-	spi_unregister_driver(&lm70_driver);
-}
-
-module_init(init_lm70);
-module_exit(cleanup_lm70);
+module_spi_driver(lm70_driver);
 
 MODULE_AUTHOR("Kaiwan N Billimoria");
 MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
index 9c8093c..8fa2632 100644
--- a/drivers/hwmon/lm73.c
+++ b/drivers/hwmon/lm73.c
@@ -194,21 +194,8 @@ static struct i2c_driver lm73_driver = {
 	.address_list	= normal_i2c,
 };
 
-/* module glue */
-
-static int __init sensors_lm73_init(void)
-{
-	return i2c_add_driver(&lm73_driver);
-}
-
-static void __exit sensors_lm73_exit(void)
-{
-	i2c_del_driver(&lm73_driver);
-}
+module_i2c_driver(lm73_driver);
 
 MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@gmail.com>");
 MODULE_DESCRIPTION("LM73 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm73_init);
-module_exit(sensors_lm73_exit);
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index b3311b1..a83f206 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -438,23 +438,8 @@ abort:
 	return ret;
 }
 
-/*-----------------------------------------------------------------------*/
-
-/* module glue */
-
-static int __init sensors_lm75_init(void)
-{
-	return i2c_add_driver(&lm75_driver);
-}
-
-static void __exit sensors_lm75_exit(void)
-{
-	i2c_del_driver(&lm75_driver);
-}
+module_i2c_driver(lm75_driver);
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
 MODULE_DESCRIPTION("LM75 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm75_init);
-module_exit(sensors_lm75_exit);
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 8dfc678..0fca861 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -1,29 +1,29 @@
 /*
-    lm77.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-
-    Copyright (c) 2004  Andras BALI <drewie@freemail.hu>
-
-    Heavily based on lm75.c by Frodo Looijaard <frodol@dds.nl>.  The LM77
-    is a temperature sensor and thermal window comparator with 0.5 deg
-    resolution made by National Semiconductor.  Complete datasheet can be
-    obtained at their site:
-       http://www.national.com/pf/LM/LM77.html
-
-    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.
-*/
+ * lm77.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	    monitoring
+ *
+ * Copyright (c) 2004  Andras BALI <drewie@freemail.hu>
+ *
+ * Heavily based on lm75.c by Frodo Looijaard <frodol@dds.nl>.  The LM77
+ * is a temperature sensor and thermal window comparator with 0.5 deg
+ * resolution made by National Semiconductor.  Complete datasheet can be
+ * obtained at their site:
+ *	http://www.national.com/pf/LM/LM77.html
+ *
+ * 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>
@@ -49,7 +49,7 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
 
 /* Each client has this additional data */
 struct lm77_data {
-	struct device 		*hwmon_dev;
+	struct device		*hwmon_dev;
 	struct mutex		update_lock;
 	char			valid;
 	unsigned long		last_updated;	/* In jiffies */
@@ -95,8 +95,10 @@ static struct i2c_driver lm77_driver = {
 #define LM77_TEMP_MIN (-55000)
 #define LM77_TEMP_MAX 125000
 
-/* In the temperature registers, the low 3 bits are not part of the
-   temperature values; they are the status bits. */
+/*
+ * In the temperature registers, the low 3 bits are not part of the
+ * temperature values; they are the status bits.
+ */
 static inline s16 LM77_TEMP_TO_REG(int temp)
 {
 	int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
@@ -112,7 +114,9 @@ static inline int LM77_TEMP_FROM_REG(s16 reg)
 
 /* read routines for temperature limits */
 #define show(value)	\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)	\
+static ssize_t show_##value(struct device *dev,			\
+			    struct device_attribute *attr,	\
+			    char *buf)				\
 {								\
 	struct lm77_data *data = lm77_update_device(dev);	\
 	return sprintf(buf, "%d\n", data->value);		\
@@ -124,17 +128,20 @@ show(temp_min);
 show(temp_max);
 
 /* read routines for hysteresis values */
-static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_crit_hyst(struct device *dev,
+				   struct device_attribute *attr, char *buf)
 {
 	struct lm77_data *data = lm77_update_device(dev);
 	return sprintf(buf, "%d\n", data->temp_crit - data->temp_hyst);
 }
-static ssize_t show_temp_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_min_hyst(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
 	struct lm77_data *data = lm77_update_device(dev);
 	return sprintf(buf, "%d\n", data->temp_min + data->temp_hyst);
 }
-static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_max_hyst(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
 	struct lm77_data *data = lm77_update_device(dev);
 	return sprintf(buf, "%d\n", data->temp_max - data->temp_hyst);
@@ -142,29 +149,42 @@ static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute *a
 
 /* write routines */
 #define set(value, reg)	\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{										\
-	struct i2c_client *client = to_i2c_client(dev);				\
-	struct lm77_data *data = i2c_get_clientdata(client);			\
-	long val = simple_strtol(buf, NULL, 10);				\
-										\
-	mutex_lock(&data->update_lock);						\
-	data->value = val;				\
-	lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value));		\
-	mutex_unlock(&data->update_lock);					\
-	return count;								\
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \
+			   const char *buf, size_t count)		\
+{									\
+	struct i2c_client *client = to_i2c_client(dev);			\
+	struct lm77_data *data = i2c_get_clientdata(client);		\
+	long val;							\
+	int err = kstrtol(buf, 10, &val);				\
+	if (err)							\
+		return err;						\
+									\
+	mutex_lock(&data->update_lock);					\
+	data->value = val;						\
+	lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value));	\
+	mutex_unlock(&data->update_lock);				\
+	return count;							\
 }
 
 set(temp_min, LM77_REG_TEMP_MIN);
 set(temp_max, LM77_REG_TEMP_MAX);
 
-/* hysteresis is stored as a relative value on the chip, so it has to be
-   converted first */
-static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+/*
+ * hysteresis is stored as a relative value on the chip, so it has to be
+ * converted first
+ */
+static ssize_t set_temp_crit_hyst(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm77_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_hyst = data->temp_crit - val;
@@ -175,13 +195,19 @@ static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *a
 }
 
 /* preserve hysteresis when setting T_crit */
-static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm77_data *data = i2c_get_clientdata(client);
-	long val = simple_strtoul(buf, NULL, 10);
 	int oldcrithyst;
-	
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
 	mutex_lock(&data->update_lock);
 	oldcrithyst = data->temp_crit - data->temp_hyst;
 	data->temp_crit = val;
@@ -251,17 +277,19 @@ static int lm77_detect(struct i2c_client *new_client,
 				     I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 
-	/* Here comes the remaining detection.  Since the LM77 has no
-	   register dedicated to identification, we have to rely on the
-	   following tricks:
-
-	   1. the high 4 bits represent the sign and thus they should
-	      always be the same
-	   2. the high 3 bits are unused in the configuration register
-	   3. addresses 0x06 and 0x07 return the last read value
-	   4. registers cycling over 8-address boundaries
-
-	   Word-sized registers are high-byte first. */
+	/*
+	 * Here comes the remaining detection.  Since the LM77 has no
+	 * register dedicated to identification, we have to rely on the
+	 * following tricks:
+	 *
+	 * 1. the high 4 bits represent the sign and thus they should
+	 *    always be the same
+	 * 2. the high 3 bits are unused in the configuration register
+	 * 3. addresses 0x06 and 0x07 return the last read value
+	 * 4. registers cycling over 8-address boundaries
+	 *
+	 * Word-sized registers are high-byte first.
+	 */
 
 	/* addresses cycling */
 	cur = i2c_smbus_read_word_data(new_client, 0);
@@ -330,7 +358,8 @@ static int lm77_probe(struct i2c_client *new_client,
 	lm77_init_client(new_client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &lm77_group)))
+	err = sysfs_create_group(&new_client->dev.kobj, &lm77_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -358,8 +387,10 @@ static int lm77_remove(struct i2c_client *client)
 	return 0;
 }
 
-/* All registers are word-sized, except for the configuration register.
-   The LM77 uses the high-byte first convention. */
+/*
+ * All registers are word-sized, except for the configuration register.
+ * The LM77 uses the high-byte first convention.
+ */
 static u16 lm77_read_value(struct i2c_client *client, u8 reg)
 {
 	if (reg == LM77_REG_CONF)
@@ -420,19 +451,8 @@ static struct lm77_data *lm77_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_lm77_init(void)
-{
-	return i2c_add_driver(&lm77_driver);
-}
-
-static void __exit sensors_lm77_exit(void)
-{
-	i2c_del_driver(&lm77_driver);
-}
+module_i2c_driver(lm77_driver);
 
 MODULE_AUTHOR("Andras BALI <drewie@freemail.hu>");
 MODULE_DESCRIPTION("LM77 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm77_init);
-module_exit(sensors_lm77_exit);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 6df0b46..f6bc414 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -1,23 +1,23 @@
 /*
-    lm78.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
-    Copyright (c) 2007, 2011  Jean Delvare <khali@linux-fr.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.
-*/
+ * lm78.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	    monitoring
+ * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+ * Copyright (c) 2007, 2011  Jean Delvare <khali@linux-fr.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.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -74,11 +74,15 @@ enum chips { lm78, lm79 };
 #define LM78_REG_I2C_ADDR 0x48
 
 
-/* Conversions. Rounding and limit checking is only done on the TO_REG 
-   variants. */
+/*
+ * Conversions. Rounding and limit checking is only done on the TO_REG
+ * variants.
+ */
 
-/* IN: mV, (0V to 4.08V)
-   REG: 16mV/bit */
+/*
+ * IN: mV (0V to 4.08V)
+ * REG: 16mV/bit
+ */
 static inline u8 IN_TO_REG(unsigned long val)
 {
 	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
@@ -95,15 +99,17 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 
 static inline int FAN_FROM_REG(u8 val, int div)
 {
-	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+	return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div);
 }
 
-/* TEMP: mC (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: mC (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static inline s8 TEMP_TO_REG(int val)
 {
 	int nval = SENSORS_LIMIT(val, -128000, 127000) ;
-	return nval<0 ? (nval-500)/1000 : (nval+500)/1000;
+	return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000;
 }
 
 static inline int TEMP_FROM_REG(s8 val)
@@ -177,8 +183,13 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct lm78_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int nr = attr->index;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val);
@@ -192,8 +203,13 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct lm78_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int nr = attr->index;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val);
@@ -201,7 +217,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-	
+
 #define show_in_offset(offset)					\
 static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
 		show_in, NULL, offset);				\
@@ -237,7 +253,12 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
 			     const char *buf, size_t count)
 {
 	struct lm78_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_over = TEMP_TO_REG(val);
@@ -257,7 +278,12 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
 			     const char *buf, size_t count)
 {
 	struct lm78_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_hyst = TEMP_TO_REG(val);
@@ -280,7 +306,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da,
 	struct lm78_data *data = lm78_update_device(dev);
 	int nr = attr->index;
 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
+		DIV_FROM_REG(data->fan_div[nr])));
 }
 
 static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
@@ -289,8 +315,8 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct lm78_data *data = lm78_update_device(dev);
 	int nr = attr->index;
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])));
 }
 
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
@@ -299,7 +325,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct lm78_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -316,29 +347,44 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
 	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 			   const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct lm78_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	unsigned long min;
 	u8 reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	min = FAN_FROM_REG(data->fan_min[nr],
 			   DIV_FROM_REG(data->fan_div[nr]));
 
 	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
+	case 1:
+		data->fan_div[nr] = 0;
+		break;
+	case 2:
+		data->fan_div[nr] = 1;
+		break;
+	case 4:
+		data->fan_div[nr] = 2;
+		break;
+	case 8:
+		data->fan_div[nr] = 3;
+		break;
 	default:
 		dev_err(dev, "fan_div value %ld not "
 			"supported. Choose one of 1, 2, 4 or 8!\n", val);
@@ -484,8 +530,10 @@ static struct platform_device *pdev;
 
 static unsigned short isa_address = 0x290;
 
-/* I2C devices get this name attribute automatically, but for ISA devices
-   we must create it by ourselves. */
+/*
+ * I2C devices get this name attribute automatically, but for ISA devices
+ * we must create it by ourselves.
+ */
 static ssize_t show_name(struct device *dev, struct device_attribute
 			 *devattr, char *buf)
 {
@@ -515,8 +563,10 @@ static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
 	if ((lm78_read_value(isa, LM78_REG_CHIPID) & 0xfe) != (chipid & 0xfe))
 		return 0;	/* Chip type doesn't match */
 
-	/* We compare all the limit registers, the config register and the
-	 * interrupt mask registers */
+	/*
+	 * We compare all the limit registers, the config register and the
+	 * interrupt mask registers
+	 */
 	for (i = 0x2b; i <= 0x3d; i++) {
 		if (lm78_read_value(isa, i) !=
 		    i2c_smbus_read_byte_data(client, i))
@@ -558,9 +608,11 @@ static int lm78_i2c_detect(struct i2c_client *client,
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* We block updates of the ISA device to minimize the risk of
-	   concurrent access to the same LM78 chip through different
-	   interfaces. */
+	/*
+	 * We block updates of the ISA device to minimize the risk of
+	 * concurrent access to the same LM78 chip through different
+	 * interfaces.
+	 */
 	if (isa)
 		mutex_lock(&isa->update_lock);
 
@@ -669,11 +721,13 @@ static struct i2c_driver lm78_driver = {
 	.address_list	= normal_i2c,
 };
 
-/* The SMBus locks itself, but ISA access must be locked explicitly! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
-   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the LM78 access and should not be necessary.  */
+/*
+ * The SMBus locks itself, but ISA access must be locked explicitly!
+ * We don't want to lock the whole ISA bus, so we lock each client
+ * separately.
+ * We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
+ * would slow down the LM78 access and should not be necessary.
+ */
 static int lm78_read_value(struct lm78_data *data, u8 reg)
 {
 	struct i2c_client *client = data->client;
@@ -691,13 +745,6 @@ static int lm78_read_value(struct lm78_data *data, u8 reg)
 		return i2c_smbus_read_byte_data(client, reg);
 }
 
-/* The SMBus locks itself, but ISA access muse be locked explicitly! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
-   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the LM78 access and should not be necessary. 
-   There are some ugly typecasts here, but the good new is - they should
-   nowhere else be necessary! */
 static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
 {
 	struct i2c_client *client = data->client;
@@ -823,8 +870,11 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
 	lm78_init_device(data);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
-	 || (err = device_create_file(&pdev->dev, &dev_attr_name)))
+	err = sysfs_create_group(&pdev->dev.kobj, &lm78_group);
+	if (err)
+		goto exit_remove_files;
+	err = device_create_file(&pdev->dev, &dev_attr_name);
+	if (err)
 		goto exit_remove_files;
 
 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
@@ -876,9 +926,11 @@ static int __init lm78_isa_found(unsigned short address)
 	int val, save, found = 0;
 	int port;
 
-	/* Some boards declare base+0 to base+7 as a PNP device, some base+4
+	/*
+	 * Some boards declare base+0 to base+7 as a PNP device, some base+4
 	 * to base+7 and some base+5 to base+6. So we better request each port
-	 * individually for the probing phase. */
+	 * individually for the probing phase.
+	 */
 	for (port = address; port < address + LM78_EXTENT; port++) {
 		if (!request_region(port, 1, "lm78")) {
 			pr_debug("Failed to request port 0x%x\n", port);
@@ -887,8 +939,10 @@ static int __init lm78_isa_found(unsigned short address)
 	}
 
 #define REALLY_SLOW_IO
-	/* We need the timeouts for at least some LM78-like
-	   chips. But only if we read 'undefined' registers. */
+	/*
+	 * We need the timeouts for at least some LM78-like
+	 * chips. But only if we read 'undefined' registers.
+	 */
 	val = inb_p(address + 1);
 	if (inb_p(address + 2) != val
 	 || inb_p(address + 3) != val
@@ -896,8 +950,10 @@ static int __init lm78_isa_found(unsigned short address)
 		goto release;
 #undef REALLY_SLOW_IO
 
-	/* We should be able to change the 7 LSB of the address port. The
-	   MSB (busy flag) should be clear initially, set after the write. */
+	/*
+	 * We should be able to change the 7 LSB of the address port. The
+	 * MSB (busy flag) should be clear initially, set after the write.
+	 */
 	save = inb_p(address + LM78_ADDR_REG_OFFSET);
 	if (save & 0x80)
 		goto release;
@@ -1036,8 +1092,10 @@ static int __init sm_lm78_init(void)
 {
 	int res;
 
-	/* We register the ISA device first, so that we can skip the
-	 * registration of an I2C interface to the same device. */
+	/*
+	 * We register the ISA device first, so that we can skip the
+	 * registration of an I2C interface to the same device.
+	 */
 	res = lm78_isa_register();
 	if (res)
 		goto exit;
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index 0891b38..e2c43e1 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -1,8 +1,8 @@
 /*
  * lm80.c - From lm_sensors, Linux kernel modules for hardware
- * monitoring
+ *	    monitoring
  * Copyright (C) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
- * and Philip Edelbrock <phil@netroedge.com>
+ *			     and Philip Edelbrock <phil@netroedge.com>
  *
  * Ported to Linux 2.6 by Tiago Sousa <mirage@kaotik.org>
  *
@@ -60,11 +60,17 @@ static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
 #define LM80_REG_FANDIV			0x05
 #define LM80_REG_RES			0x06
 
+#define LM96080_REG_CONV_RATE		0x07
+#define LM96080_REG_MAN_ID		0x3e
+#define LM96080_REG_DEV_ID		0x3f
 
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
+
+/*
+ * Conversions. Rounding and limit checking is only done on the TO_REG
+ * variants. Note that you should be a bit careful with which arguments
+ * these macros are called: arguments may be evaluated more than once.
+ * Fixing this is just not worth it.
+ */
 
 #define IN_TO_REG(val)		(SENSORS_LIMIT(((val) + 5) / 10, 0, 255))
 #define IN_FROM_REG(val)	((val) * 10)
@@ -108,6 +114,7 @@ static inline long TEMP_FROM_REG(u16 temp)
 struct lm80_data {
 	struct device *hwmon_dev;
 	struct mutex update_lock;
+	char error;		/* !=0 if error occurred during last update */
 	char valid;		/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 
@@ -144,6 +151,7 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
 
 static const struct i2c_device_id lm80_id[] = {
 	{ "lm80", 0 },
+	{ "lm96080", 1 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, lm80_id);
@@ -170,6 +178,8 @@ static ssize_t show_in_##suffix(struct device *dev, \
 { \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct lm80_data *data = lm80_update_device(dev); \
+	if (IS_ERR(data)) \
+		return PTR_ERR(data); \
 	return sprintf(buf, "%d\n", IN_FROM_REG(data->value[nr])); \
 }
 show_in(min, in_min)
@@ -183,7 +193,10 @@ static ssize_t set_in_##suffix(struct device *dev, \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct lm80_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
+	long val; \
+	int err = kstrtol(buf, 10, &val); \
+	if (err < 0) \
+		return err; \
 \
 	mutex_lock(&data->update_lock);\
 	data->value[nr] = IN_TO_REG(val); \
@@ -200,6 +213,8 @@ static ssize_t show_fan_##suffix(struct device *dev, \
 { \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct lm80_data *data = lm80_update_device(dev); \
+	if (IS_ERR(data)) \
+		return PTR_ERR(data); \
 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[nr], \
 		       DIV_FROM_REG(data->fan_div[nr]))); \
 }
@@ -211,6 +226,8 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct lm80_data *data = lm80_update_device(dev);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
 	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
 }
 
@@ -220,7 +237,10 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm80_data *data = i2c_get_clientdata(client);
-	long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err = kstrtoul(buf, 10, &val);
+	if (err < 0)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -229,18 +249,23 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count)
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm80_data *data = i2c_get_clientdata(client);
-	unsigned long min, val = simple_strtoul(buf, NULL, 10);
+	unsigned long min, val;
 	u8 reg;
+	int err = kstrtoul(buf, 10, &val);
+	if (err < 0)
+		return err;
 
 	/* Save fan_min */
 	mutex_lock(&data->update_lock);
@@ -283,6 +308,8 @@ static ssize_t show_temp_input1(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
 	struct lm80_data *data = lm80_update_device(dev);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
 	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp));
 }
 
@@ -291,6 +318,8 @@ static ssize_t show_temp_##suffix(struct device *dev, \
 	struct device_attribute *attr, char *buf) \
 { \
 	struct lm80_data *data = lm80_update_device(dev); \
+	if (IS_ERR(data)) \
+		return PTR_ERR(data); \
 	return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \
 }
 show_temp(hot_max, temp_hot_max);
@@ -304,7 +333,10 @@ static ssize_t set_temp_##suffix(struct device *dev, \
 { \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct lm80_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtoul(buf, NULL, 10); \
+	long val; \
+	int err = kstrtol(buf, 10, &val); \
+	if (err < 0) \
+		return err; \
 \
 	mutex_lock(&data->update_lock); \
 	data->value = TEMP_LIMIT_TO_REG(val); \
@@ -321,6 +353,8 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
 			   char *buf)
 {
 	struct lm80_data *data = lm80_update_device(dev);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
 	return sprintf(buf, "%u\n", data->alarms);
 }
 
@@ -329,6 +363,8 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
 {
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	struct lm80_data *data = lm80_update_device(dev);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
 	return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
 }
 
@@ -459,23 +495,44 @@ static const struct attribute_group lm80_group = {
 static int lm80_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
 	struct i2c_adapter *adapter = client->adapter;
-	int i, cur;
+	int i, cur, man_id, dev_id;
+	const char *name = NULL;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* Now, we do the remaining detection. It is lousy. */
-	if (lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
+	/* First check for unused bits, common to both chip types */
+	if ((lm80_read_value(client, LM80_REG_ALARM2) & 0xc0)
+	 || (lm80_read_value(client, LM80_REG_CONFIG) & 0x80))
 		return -ENODEV;
-	for (i = 0x2a; i <= 0x3d; i++) {
-		cur = i2c_smbus_read_byte_data(client, i);
-		if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur)
-		 || (i2c_smbus_read_byte_data(client, i + 0x80) != cur)
-		 || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur))
+
+	/*
+	 * The LM96080 has manufacturer and stepping/die rev registers so we
+	 * can just check that. The LM80 does not have such registers so we
+	 * have to use a more expensive trick.
+	 */
+	man_id = lm80_read_value(client, LM96080_REG_MAN_ID);
+	dev_id = lm80_read_value(client, LM96080_REG_DEV_ID);
+	if (man_id == 0x01 && dev_id == 0x08) {
+		/* Check more unused bits for confirmation */
+		if (lm80_read_value(client, LM96080_REG_CONV_RATE) & 0xfe)
 			return -ENODEV;
+
+		name = "lm96080";
+	} else {
+		/* Check 6-bit addressing */
+		for (i = 0x2a; i <= 0x3d; i++) {
+			cur = i2c_smbus_read_byte_data(client, i);
+			if ((i2c_smbus_read_byte_data(client, i + 0x40) != cur)
+			 || (i2c_smbus_read_byte_data(client, i + 0x80) != cur)
+			 || (i2c_smbus_read_byte_data(client, i + 0xc0) != cur))
+				return -ENODEV;
+		}
+
+		name = "lm80";
 	}
 
-	strlcpy(info->type, "lm80", I2C_NAME_SIZE);
+	strlcpy(info->type, name, I2C_NAME_SIZE);
 
 	return 0;
 }
@@ -547,9 +604,11 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value)
 /* Called when we have found a new LM80. */
 static void lm80_init_client(struct i2c_client *client)
 {
-	/* Reset all except Watchdog values and last conversion values
-	   This sets fan-divs to 2, among others. This makes most other
-	   initializations unnecessary */
+	/*
+	 * Reset all except Watchdog values and last conversion values
+	 * This sets fan-divs to 2, among others. This makes most other
+	 * initializations unnecessary
+	 */
 	lm80_write_value(client, LM80_REG_CONFIG, 0x80);
 	/* Set 11-bit temperature resolution */
 	lm80_write_value(client, LM80_REG_RES, 0x08);
@@ -563,66 +622,116 @@ static struct lm80_data *lm80_update_device(struct device *dev)
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm80_data *data = i2c_get_clientdata(client);
 	int i;
+	int rv;
+	int prev_rv;
+	struct lm80_data *ret = data;
 
 	mutex_lock(&data->update_lock);
 
+	if (data->error)
+		lm80_init_client(client);
+
 	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
 		dev_dbg(&client->dev, "Starting lm80 update\n");
 		for (i = 0; i <= 6; i++) {
-			data->in[i] =
-			    lm80_read_value(client, LM80_REG_IN(i));
-			data->in_min[i] =
-			    lm80_read_value(client, LM80_REG_IN_MIN(i));
-			data->in_max[i] =
-			    lm80_read_value(client, LM80_REG_IN_MAX(i));
+			rv = lm80_read_value(client, LM80_REG_IN(i));
+			if (rv < 0)
+				goto abort;
+			data->in[i] = rv;
+
+			rv = lm80_read_value(client, LM80_REG_IN_MIN(i));
+			if (rv < 0)
+				goto abort;
+			data->in_min[i] = rv;
+
+			rv = lm80_read_value(client, LM80_REG_IN_MAX(i));
+			if (rv < 0)
+				goto abort;
+			data->in_max[i] = rv;
 		}
-		data->fan[0] = lm80_read_value(client, LM80_REG_FAN1);
-		data->fan_min[0] =
-		    lm80_read_value(client, LM80_REG_FAN_MIN(1));
-		data->fan[1] = lm80_read_value(client, LM80_REG_FAN2);
-		data->fan_min[1] =
-		    lm80_read_value(client, LM80_REG_FAN_MIN(2));
-
-		data->temp =
-		    (lm80_read_value(client, LM80_REG_TEMP) << 8) |
-		    (lm80_read_value(client, LM80_REG_RES) & 0xf0);
-		data->temp_os_max =
-		    lm80_read_value(client, LM80_REG_TEMP_OS_MAX);
-		data->temp_os_hyst =
-		    lm80_read_value(client, LM80_REG_TEMP_OS_HYST);
-		data->temp_hot_max =
-		    lm80_read_value(client, LM80_REG_TEMP_HOT_MAX);
-		data->temp_hot_hyst =
-		    lm80_read_value(client, LM80_REG_TEMP_HOT_HYST);
-
-		i = lm80_read_value(client, LM80_REG_FANDIV);
-		data->fan_div[0] = (i >> 2) & 0x03;
-		data->fan_div[1] = (i >> 4) & 0x03;
-		data->alarms = lm80_read_value(client, LM80_REG_ALARM1) +
-		    (lm80_read_value(client, LM80_REG_ALARM2) << 8);
+
+		rv = lm80_read_value(client, LM80_REG_FAN1);
+		if (rv < 0)
+			goto abort;
+		data->fan[0] = rv;
+
+		rv = lm80_read_value(client, LM80_REG_FAN_MIN(1));
+		if (rv < 0)
+			goto abort;
+		data->fan_min[0] = rv;
+
+		rv = lm80_read_value(client, LM80_REG_FAN2);
+		if (rv < 0)
+			goto abort;
+		data->fan[1] = rv;
+
+		rv = lm80_read_value(client, LM80_REG_FAN_MIN(2));
+		if (rv < 0)
+			goto abort;
+		data->fan_min[1] = rv;
+
+		prev_rv = rv = lm80_read_value(client, LM80_REG_TEMP);
+		if (rv < 0)
+			goto abort;
+		rv = lm80_read_value(client, LM80_REG_RES);
+		if (rv < 0)
+			goto abort;
+		data->temp = (prev_rv << 8) | (rv & 0xf0);
+
+		rv = lm80_read_value(client, LM80_REG_TEMP_OS_MAX);
+		if (rv < 0)
+			goto abort;
+		data->temp_os_max = rv;
+
+		rv = lm80_read_value(client, LM80_REG_TEMP_OS_HYST);
+		if (rv < 0)
+			goto abort;
+		data->temp_os_hyst = rv;
+
+		rv = lm80_read_value(client, LM80_REG_TEMP_HOT_MAX);
+		if (rv < 0)
+			goto abort;
+		data->temp_hot_max = rv;
+
+		rv = lm80_read_value(client, LM80_REG_TEMP_HOT_HYST);
+		if (rv < 0)
+			goto abort;
+		data->temp_hot_hyst = rv;
+
+		rv = lm80_read_value(client, LM80_REG_FANDIV);
+		if (rv < 0)
+			goto abort;
+		data->fan_div[0] = (rv >> 2) & 0x03;
+		data->fan_div[1] = (rv >> 4) & 0x03;
+
+		prev_rv = rv = lm80_read_value(client, LM80_REG_ALARM1);
+		if (rv < 0)
+			goto abort;
+		rv = lm80_read_value(client, LM80_REG_ALARM2);
+		if (rv < 0)
+			goto abort;
+		data->alarms = prev_rv + (rv << 8);
+
 		data->last_updated = jiffies;
 		data->valid = 1;
+		data->error = 0;
 	}
+	goto done;
+
+abort:
+	ret = ERR_PTR(rv);
+	data->valid = 0;
+	data->error = 1;
 
+done:
 	mutex_unlock(&data->update_lock);
 
-	return data;
+	return ret;
 }
 
-static int __init sensors_lm80_init(void)
-{
-	return i2c_add_driver(&lm80_driver);
-}
-
-static void __exit sensors_lm80_exit(void)
-{
-	i2c_del_driver(&lm80_driver);
-}
+module_i2c_driver(lm80_driver);
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
 	"Philip Edelbrock <phil@netroedge.com>");
 MODULE_DESCRIPTION("LM80 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm80_init);
-module_exit(sensors_lm80_exit);
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
index 8290476..cd45b9d 100644
--- a/drivers/hwmon/lm83.c
+++ b/drivers/hwmon/lm83.c
@@ -124,7 +124,7 @@ static struct lm83_data *lm83_update_device(struct device *dev);
 /*
  * Driver data (common to all clients)
  */
- 
+
 static const struct i2c_device_id lm83_id[] = {
 	{ "lm83", lm83 },
 	{ "lm82", lm82 },
@@ -179,8 +179,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm83_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
 	int nr = attr->index;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err < 0)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp[nr] = TEMP_TO_REG(val);
@@ -355,12 +360,14 @@ static int lm83_probe(struct i2c_client *new_client,
 	 * declare 1 and 3 common, and then 2 and 4 only for the LM83.
 	 */
 
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &lm83_group)))
+	err = sysfs_create_group(&new_client->dev.kobj, &lm83_group);
+	if (err)
 		goto exit_free;
 
 	if (id->driver_data == lm83) {
-		if ((err = sysfs_create_group(&new_client->dev.kobj,
-					      &lm83_group_opt)))
+		err = sysfs_create_group(&new_client->dev.kobj,
+					 &lm83_group_opt);
+		if (err)
 			goto exit_remove_files;
 	}
 
@@ -423,19 +430,8 @@ static struct lm83_data *lm83_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_lm83_init(void)
-{
-	return i2c_add_driver(&lm83_driver);
-}
-
-static void __exit sensors_lm83_exit(void)
-{
-	i2c_del_driver(&lm83_driver);
-}
+module_i2c_driver(lm83_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("LM83 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm83_init);
-module_exit(sensors_lm83_exit);
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index da72dc1..864c7d9 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -1,28 +1,28 @@
 /*
-    lm85.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
-    Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
-    Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
-    Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
-    Copyright (C) 2007--2009  Jean Delvare <khali@linux-fr.org>
-
-    Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
-
-    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.
-*/
+ * lm85.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	    monitoring
+ * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+ * Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
+ * Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
+ * Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
+ * Copyright (C) 2007--2009  Jean Delvare <khali@linux-fr.org>
+ *
+ * Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
+ *
+ * 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>
@@ -46,88 +46,89 @@ enum chips {
 
 /* The LM85 registers */
 
-#define	LM85_REG_IN(nr)			(0x20 + (nr))
-#define	LM85_REG_IN_MIN(nr)		(0x44 + (nr) * 2)
-#define	LM85_REG_IN_MAX(nr)		(0x45 + (nr) * 2)
+#define LM85_REG_IN(nr)			(0x20 + (nr))
+#define LM85_REG_IN_MIN(nr)		(0x44 + (nr) * 2)
+#define LM85_REG_IN_MAX(nr)		(0x45 + (nr) * 2)
 
-#define	LM85_REG_TEMP(nr)		(0x25 + (nr))
-#define	LM85_REG_TEMP_MIN(nr)		(0x4e + (nr) * 2)
-#define	LM85_REG_TEMP_MAX(nr)		(0x4f + (nr) * 2)
+#define LM85_REG_TEMP(nr)		(0x25 + (nr))
+#define LM85_REG_TEMP_MIN(nr)		(0x4e + (nr) * 2)
+#define LM85_REG_TEMP_MAX(nr)		(0x4f + (nr) * 2)
 
 /* Fan speeds are LSB, MSB (2 bytes) */
-#define	LM85_REG_FAN(nr)		(0x28 + (nr) * 2)
-#define	LM85_REG_FAN_MIN(nr)		(0x54 + (nr) * 2)
+#define LM85_REG_FAN(nr)		(0x28 + (nr) * 2)
+#define LM85_REG_FAN_MIN(nr)		(0x54 + (nr) * 2)
 
-#define	LM85_REG_PWM(nr)		(0x30 + (nr))
+#define LM85_REG_PWM(nr)		(0x30 + (nr))
 
-#define	LM85_REG_COMPANY		0x3e
-#define	LM85_REG_VERSTEP		0x3f
+#define LM85_REG_COMPANY		0x3e
+#define LM85_REG_VERSTEP		0x3f
 
-#define	ADT7468_REG_CFG5		0x7c
-#define		ADT7468_OFF64		(1 << 0)
-#define		ADT7468_HFPWM		(1 << 1)
-#define	IS_ADT7468_OFF64(data)		\
+#define ADT7468_REG_CFG5		0x7c
+#define ADT7468_OFF64			(1 << 0)
+#define ADT7468_HFPWM			(1 << 1)
+#define IS_ADT7468_OFF64(data)		\
 	((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64))
-#define	IS_ADT7468_HFPWM(data)		\
+#define IS_ADT7468_HFPWM(data)		\
 	((data)->type == adt7468 && !((data)->cfg5 & ADT7468_HFPWM))
 
 /* These are the recognized values for the above regs */
-#define	LM85_COMPANY_NATIONAL		0x01
-#define	LM85_COMPANY_ANALOG_DEV		0x41
-#define	LM85_COMPANY_SMSC		0x5c
-#define	LM85_VERSTEP_VMASK              0xf0
-#define	LM85_VERSTEP_GENERIC		0x60
-#define	LM85_VERSTEP_GENERIC2		0x70
-#define	LM85_VERSTEP_LM85C		0x60
-#define	LM85_VERSTEP_LM85B		0x62
-#define	LM85_VERSTEP_LM96000_1		0x68
-#define	LM85_VERSTEP_LM96000_2		0x69
-#define	LM85_VERSTEP_ADM1027		0x60
-#define	LM85_VERSTEP_ADT7463		0x62
-#define	LM85_VERSTEP_ADT7463C		0x6A
-#define	LM85_VERSTEP_ADT7468_1		0x71
-#define	LM85_VERSTEP_ADT7468_2		0x72
-#define	LM85_VERSTEP_EMC6D100_A0        0x60
-#define	LM85_VERSTEP_EMC6D100_A1        0x61
-#define	LM85_VERSTEP_EMC6D102		0x65
-#define	LM85_VERSTEP_EMC6D103_A0	0x68
-#define	LM85_VERSTEP_EMC6D103_A1	0x69
-#define	LM85_VERSTEP_EMC6D103S		0x6A	/* Also known as EMC6D103:A2 */
-
-#define	LM85_REG_CONFIG			0x40
-
-#define	LM85_REG_ALARM1			0x41
-#define	LM85_REG_ALARM2			0x42
-
-#define	LM85_REG_VID			0x43
+#define LM85_COMPANY_NATIONAL		0x01
+#define LM85_COMPANY_ANALOG_DEV		0x41
+#define LM85_COMPANY_SMSC		0x5c
+#define LM85_VERSTEP_VMASK              0xf0
+#define LM85_VERSTEP_GENERIC		0x60
+#define LM85_VERSTEP_GENERIC2		0x70
+#define LM85_VERSTEP_LM85C		0x60
+#define LM85_VERSTEP_LM85B		0x62
+#define LM85_VERSTEP_LM96000_1		0x68
+#define LM85_VERSTEP_LM96000_2		0x69
+#define LM85_VERSTEP_ADM1027		0x60
+#define LM85_VERSTEP_ADT7463		0x62
+#define LM85_VERSTEP_ADT7463C		0x6A
+#define LM85_VERSTEP_ADT7468_1		0x71
+#define LM85_VERSTEP_ADT7468_2		0x72
+#define LM85_VERSTEP_EMC6D100_A0        0x60
+#define LM85_VERSTEP_EMC6D100_A1        0x61
+#define LM85_VERSTEP_EMC6D102		0x65
+#define LM85_VERSTEP_EMC6D103_A0	0x68
+#define LM85_VERSTEP_EMC6D103_A1	0x69
+#define LM85_VERSTEP_EMC6D103S		0x6A	/* Also known as EMC6D103:A2 */
+
+#define LM85_REG_CONFIG			0x40
+
+#define LM85_REG_ALARM1			0x41
+#define LM85_REG_ALARM2			0x42
+
+#define LM85_REG_VID			0x43
 
 /* Automated FAN control */
-#define	LM85_REG_AFAN_CONFIG(nr)	(0x5c + (nr))
-#define	LM85_REG_AFAN_RANGE(nr)		(0x5f + (nr))
-#define	LM85_REG_AFAN_SPIKE1		0x62
-#define	LM85_REG_AFAN_MINPWM(nr)	(0x64 + (nr))
-#define	LM85_REG_AFAN_LIMIT(nr)		(0x67 + (nr))
-#define	LM85_REG_AFAN_CRITICAL(nr)	(0x6a + (nr))
-#define	LM85_REG_AFAN_HYST1		0x6d
-#define	LM85_REG_AFAN_HYST2		0x6e
-
-#define	ADM1027_REG_EXTEND_ADC1		0x76
-#define	ADM1027_REG_EXTEND_ADC2		0x77
+#define LM85_REG_AFAN_CONFIG(nr)	(0x5c + (nr))
+#define LM85_REG_AFAN_RANGE(nr)		(0x5f + (nr))
+#define LM85_REG_AFAN_SPIKE1		0x62
+#define LM85_REG_AFAN_MINPWM(nr)	(0x64 + (nr))
+#define LM85_REG_AFAN_LIMIT(nr)		(0x67 + (nr))
+#define LM85_REG_AFAN_CRITICAL(nr)	(0x6a + (nr))
+#define LM85_REG_AFAN_HYST1		0x6d
+#define LM85_REG_AFAN_HYST2		0x6e
+
+#define ADM1027_REG_EXTEND_ADC1		0x76
+#define ADM1027_REG_EXTEND_ADC2		0x77
 
 #define EMC6D100_REG_ALARM3             0x7d
 /* IN5, IN6 and IN7 */
-#define	EMC6D100_REG_IN(nr)             (0x70 + ((nr) - 5))
-#define	EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr) - 5) * 2)
-#define	EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr) - 5) * 2)
-#define	EMC6D102_REG_EXTEND_ADC1	0x85
-#define	EMC6D102_REG_EXTEND_ADC2	0x86
-#define	EMC6D102_REG_EXTEND_ADC3	0x87
-#define	EMC6D102_REG_EXTEND_ADC4	0x88
-
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
+#define EMC6D100_REG_IN(nr)             (0x70 + ((nr) - 5))
+#define EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr) - 5) * 2)
+#define EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr) - 5) * 2)
+#define EMC6D102_REG_EXTEND_ADC1	0x85
+#define EMC6D102_REG_EXTEND_ADC2	0x86
+#define EMC6D102_REG_EXTEND_ADC3	0x87
+#define EMC6D102_REG_EXTEND_ADC4	0x88
+
+
+/*
+ * Conversions. Rounding and limit checking is only done on the TO_REG
+ * variants. Note that you should be a bit careful with which arguments
+ * these macros are called: arguments may be evaluated more than once.
  */
 
 /* IN are scaled according to built-in resistors */
@@ -166,7 +167,8 @@ static inline u16 FAN_TO_REG(unsigned long val)
 #define PWM_FROM_REG(val)		(val)
 
 
-/* ZONEs have the following parameters:
+/*
+ * ZONEs have the following parameters:
  *    Limit (low) temp,           1. degC
  *    Hysteresis (below limit),   1. degC (0-15)
  *    Range of speed control,     .1 degC (2-80)
@@ -228,7 +230,8 @@ static int FREQ_FROM_REG(const int *map, u8 reg)
 	return map[reg & 0x07];
 }
 
-/* Since we can't use strings, I'm abusing these numbers
+/*
+ * Since we can't use strings, I'm abusing these numbers
  *   to stand in for the following meanings:
  *      1 -- PWM responds to Zone 1
  *      2 -- PWM responds to Zone 2
@@ -258,7 +261,8 @@ static int ZONE_TO_REG(int zone)
 #define HYST_TO_REG(val)	SENSORS_LIMIT(((val) + 500) / 1000, 0, 15)
 #define HYST_FROM_REG(val)	((val) * 1000)
 
-/* Chip sampling rates
+/*
+ * Chip sampling rates
  *
  * Some sensors are not updated more frequently than once per second
  *    so it doesn't make sense to read them more often than that.
@@ -274,7 +278,8 @@ static int ZONE_TO_REG(int zone)
 #define LM85_DATA_INTERVAL  (HZ + HZ / 2)
 #define LM85_CONFIG_INTERVAL  (1 * 60 * HZ)
 
-/* LM85 can automatically adjust fan speeds based on temperature
+/*
+ * LM85 can automatically adjust fan speeds based on temperature
  * This structure encapsulates an entire Zone config.  There are
  * three zones (one for each temperature input) on the lm85
  */
@@ -283,7 +288,8 @@ struct lm85_zone {
 	u8 hyst;	/* Low limit hysteresis. (0-15) */
 	u8 range;	/* Temp range, encoded */
 	s8 critical;	/* "All fans ON" temp limit */
-	u8 max_desired; /* Actual "max" temperature specified.  Preserved
+	u8 max_desired; /*
+			 * Actual "max" temperature specified.  Preserved
 			 * to prevent "drift" as other autofan control
 			 * values change.
 			 */
@@ -295,8 +301,10 @@ struct lm85_autofan {
 	u8 min_off;	/* Min PWM or OFF below "limit", flag */
 };
 
-/* For each registered chip, we need to keep some data in memory.
-   The structure is dynamically allocated. */
+/*
+ * For each registered chip, we need to keep some data in memory.
+ * The structure is dynamically allocated.
+ */
 struct lm85_data {
 	struct device *hwmon_dev;
 	const int *freq_map;
@@ -391,7 +399,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val);
@@ -443,7 +456,14 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct lm85_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	data->vrm = val;
 	return count;
 }
 
@@ -500,7 +520,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm[nr] = PWM_TO_REG(val);
@@ -537,8 +562,13 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
 	u8 config;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	switch (val) {
 	case 0:
@@ -548,8 +578,10 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
 		config = 7;
 		break;
 	case 2:
-		/* Here we have to choose arbitrarily one of the 5 possible
-		   configurations; I go for the safest */
+		/*
+		 * Here we have to choose arbitrarily one of the 5 possible
+		 * configurations; I go for the safest
+		 */
 		config = 6;
 		break;
 	default:
@@ -588,12 +620,19 @@ static ssize_t set_pwm_freq(struct device *dev,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	/* The ADT7468 has a special high-frequency PWM output mode,
+	/*
+	 * The ADT7468 has a special high-frequency PWM output mode,
 	 * where all PWM outputs are driven by a 22.5 kHz clock.
-	 * This might confuse the user, but there's not much we can do. */
+	 * This might confuse the user, but there's not much we can do.
+	 */
 	if (data->type == adt7468 && val >= 11300) {	/* High freq. mode */
 		data->cfg5 &= ~ADT7468_HFPWM;
 		lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5);
@@ -648,7 +687,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = INS_TO_REG(nr, val);
@@ -671,7 +715,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = INS_TO_REG(nr, val);
@@ -722,7 +771,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	if (IS_ADT7468_OFF64(data))
 		val += 64;
@@ -748,7 +802,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	if (IS_ADT7468_OFF64(data))
 		val += 64;
@@ -789,7 +848,12 @@ static ssize_t set_pwm_auto_channels(struct device *dev,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
@@ -814,7 +878,12 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->autofan[nr].min_pwm = PWM_TO_REG(val);
@@ -838,8 +907,13 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
 	u8 tmp;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->autofan[nr].min_off = val;
@@ -885,7 +959,12 @@ static ssize_t set_temp_auto_temp_off(struct device *dev,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
 	int min;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	min = TEMP_FROM_REG(data->zone[nr].limit);
@@ -916,7 +995,12 @@ static ssize_t set_temp_auto_temp_min(struct device *dev,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->zone[nr].limit = TEMP_TO_REG(val);
@@ -951,7 +1035,12 @@ static ssize_t set_temp_auto_temp_max(struct device *dev,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
 	int min;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	min = TEMP_FROM_REG(data->zone[nr].limit);
@@ -979,7 +1068,12 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->zone[nr].critical = TEMP_TO_REG(val);
@@ -1338,24 +1432,28 @@ static int lm85_probe(struct i2c_client *client,
 			goto err_remove_files;
 	}
 
-	/* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used
-	   as a sixth digital VID input rather than an analog input. */
+	/*
+	 * The ADT7463/68 have an optional VRM 10 mode where pin 21 is used
+	 * as a sixth digital VID input rather than an analog input.
+	 */
 	if (data->type == adt7463 || data->type == adt7468) {
 		u8 vid = lm85_read_value(client, LM85_REG_VID);
 		if (vid & 0x80)
 			data->has_vid5 = true;
 	}
 
-	if (!data->has_vid5)
-		if ((err = sysfs_create_group(&client->dev.kobj,
-					&lm85_group_in4)))
+	if (!data->has_vid5) {
+		err = sysfs_create_group(&client->dev.kobj, &lm85_group_in4);
+		if (err)
 			goto err_remove_files;
+	}
 
 	/* The EMC6D100 has 3 additional voltage inputs */
-	if (data->type == emc6d100)
-		if ((err = sysfs_create_group(&client->dev.kobj,
-					&lm85_group_in567)))
+	if (data->type == emc6d100) {
+		err = sysfs_create_group(&client->dev.kobj, &lm85_group_in567);
+		if (err)
 			goto err_remove_files;
+	}
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
@@ -1443,7 +1541,8 @@ static struct lm85_data *lm85_update_device(struct device *dev)
 		/* Things that change quickly */
 		dev_dbg(&client->dev, "Reading sensor values\n");
 
-		/* Have to read extended bits first to "freeze" the
+		/*
+		 * Have to read extended bits first to "freeze" the
 		 * more significant bits that are read later.
 		 * There are 2 additional resolution bits per channel and we
 		 * have room for 4, so we shift them to the left.
@@ -1503,9 +1602,10 @@ static struct lm85_data *lm85_update_device(struct device *dev)
 						EMC6D100_REG_ALARM3) << 16;
 		} else if (data->type == emc6d102 || data->type == emc6d103 ||
 			   data->type == emc6d103s) {
-			/* Have to read LSB bits after the MSB ones because
-			   the reading of the MSB bits has frozen the
-			   LSBs (backward from the ADM1027).
+			/*
+			 * Have to read LSB bits after the MSB ones because
+			 * the reading of the MSB bits has frozen the
+			 * LSBs (backward from the ADM1027).
 			 */
 			int ext1 = lm85_read_value(client,
 						   EMC6D102_REG_EXTEND_ADC1);
@@ -1611,22 +1711,10 @@ static struct lm85_data *lm85_update_device(struct device *dev)
 	return data;
 }
 
-
-static int __init sm_lm85_init(void)
-{
-	return i2c_add_driver(&lm85_driver);
-}
-
-static void __exit sm_lm85_exit(void)
-{
-	i2c_del_driver(&lm85_driver);
-}
+module_i2c_driver(lm85_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
 	"Margit Schubert-While <margitsw@t-online.de>, "
 	"Justin Thiessen <jthiessen@penguincomputing.com>");
 MODULE_DESCRIPTION("LM85-B, LM85-C driver");
-
-module_init(sm_lm85_init);
-module_exit(sm_lm85_exit);
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index f1e6e75..314d147 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -119,20 +119,21 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C };
  * The LM87 uses signed 8-bit values for temperatures.
  */
 
-#define IN_FROM_REG(reg,scale)	(((reg) * (scale) + 96) / 192)
-#define IN_TO_REG(val,scale)	((val) <= 0 ? 0 : \
+#define IN_FROM_REG(reg, scale)	(((reg) * (scale) + 96) / 192)
+#define IN_TO_REG(val, scale)	((val) <= 0 ? 0 : \
 				 (val) * 192 >= (scale) * 255 ? 255 : \
-				 ((val) * 192 + (scale)/2) / (scale))
+				 ((val) * 192 + (scale) / 2) / (scale))
 
 #define TEMP_FROM_REG(reg)	((reg) * 1000)
 #define TEMP_TO_REG(val)	((val) <= -127500 ? -128 : \
 				 (val) >= 126500 ? 127 : \
-				 (((val) < 0 ? (val)-500 : (val)+500) / 1000))
+				 (((val) < 0 ? (val) - 500 : \
+				   (val) + 500) / 1000))
 
-#define FAN_FROM_REG(reg,div)	((reg) == 255 || (reg) == 0 ? 0 : \
-				 (1350000 + (reg)*(div) / 2) / ((reg)*(div)))
-#define FAN_TO_REG(val,div)	((val)*(div) * 255 <= 1350000 ? 255 : \
-				 (1350000 + (val)*(div) / 2) / ((val)*(div)))
+#define FAN_FROM_REG(reg, div)	((reg) == 255 || (reg) == 0 ? 0 : \
+				 (1350000 + (reg)*(div) / 2) / ((reg) * (div)))
+#define FAN_TO_REG(val, div)	((val) * (div) * 255 <= 1350000 ? 255 : \
+				 (1350000 + (val)*(div) / 2) / ((val) * (div)))
 
 #define FAN_DIV_FROM_REG(reg)	(1 << (reg))
 
@@ -149,41 +150,6 @@ static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C };
 #define CHAN_NO_VID		(1 << 7)
 
 /*
- * Functions declaration
- */
-
-static int lm87_probe(struct i2c_client *client,
-		      const struct i2c_device_id *id);
-static int lm87_detect(struct i2c_client *new_client,
-		       struct i2c_board_info *info);
-static void lm87_init_client(struct i2c_client *client);
-static int lm87_remove(struct i2c_client *client);
-static struct lm87_data *lm87_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id lm87_id[] = {
-	{ "lm87", lm87 },
-	{ "adm1024", adm1024 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, lm87_id);
-
-static struct i2c_driver lm87_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "lm87",
-	},
-	.probe		= lm87_probe,
-	.remove		= lm87_remove,
-	.id_table	= lm87_id,
-	.detect		= lm87_detect,
-	.address_list	= normal_i2c,
-};
-
-/*
  * Client data (each client gets its own)
  */
 
@@ -217,10 +183,6 @@ struct lm87_data {
 	u8 vrm;
 };
 
-/*
- * Sysfs stuff
- */
-
 static inline int lm87_read_value(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
@@ -231,79 +193,168 @@ static inline int lm87_write_value(struct i2c_client *client, u8 reg, u8 value)
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-#define show_in(offset) \
-static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
-		       data->in_scale[offset])); \
-} \
-static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
-		       data->in_scale[offset])); \
-} \
-static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
-		       data->in_scale[offset])); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
-		show_in##offset##_input, NULL);
-show_in(0);
-show_in(1);
-show_in(2);
-show_in(3);
-show_in(4);
-show_in(5);
-show_in(6);
-show_in(7);
-
-static void set_in_min(struct device *dev, const char *buf, int nr)
+static struct lm87_data *lm87_update_device(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		int i, j;
+
+		dev_dbg(&client->dev, "Updating data.\n");
+
+		i = (data->channel & CHAN_TEMP3) ? 1 : 0;
+		j = (data->channel & CHAN_TEMP3) ? 5 : 6;
+		for (; i < j; i++) {
+			data->in[i] = lm87_read_value(client,
+				      LM87_REG_IN(i));
+			data->in_min[i] = lm87_read_value(client,
+					  LM87_REG_IN_MIN(i));
+			data->in_max[i] = lm87_read_value(client,
+					  LM87_REG_IN_MAX(i));
+		}
+
+		for (i = 0; i < 2; i++) {
+			if (data->channel & CHAN_NO_FAN(i)) {
+				data->in[6+i] = lm87_read_value(client,
+						LM87_REG_AIN(i));
+				data->in_max[6+i] = lm87_read_value(client,
+						    LM87_REG_AIN_MAX(i));
+				data->in_min[6+i] = lm87_read_value(client,
+						    LM87_REG_AIN_MIN(i));
+
+			} else {
+				data->fan[i] = lm87_read_value(client,
+					       LM87_REG_FAN(i));
+				data->fan_min[i] = lm87_read_value(client,
+						   LM87_REG_FAN_MIN(i));
+			}
+		}
+
+		j = (data->channel & CHAN_TEMP3) ? 3 : 2;
+		for (i = 0 ; i < j; i++) {
+			data->temp[i] = lm87_read_value(client,
+					LM87_REG_TEMP[i]);
+			data->temp_high[i] = lm87_read_value(client,
+					     LM87_REG_TEMP_HIGH[i]);
+			data->temp_low[i] = lm87_read_value(client,
+					    LM87_REG_TEMP_LOW[i]);
+		}
+
+		i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK);
+		j = lm87_read_value(client, LM87_REG_TEMP_HW_INT);
+		data->temp_crit_int = min(i, j);
+
+		i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK);
+		j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT);
+		data->temp_crit_ext = min(i, j);
+
+		i = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = (i >> 6) & 0x03;
+		data->vid = (i & 0x0F)
+			  | (lm87_read_value(client, LM87_REG_VID4) & 0x01)
+			     << 4;
+
+		data->alarms = lm87_read_value(client, LM87_REG_ALARMS1)
+			     | (lm87_read_value(client, LM87_REG_ALARMS2)
+				<< 8);
+		data->aout = lm87_read_value(client, LM87_REG_AOUT);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[nr],
+		       data->in_scale[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[nr],
+		       data->in_scale[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[nr],
+		       data->in_scale[nr]));
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	int nr = to_sensor_dev_attr(attr)->index;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]);
-	lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) :
-			 LM87_REG_AIN_MIN(nr-6), data->in_min[nr]);
+	lm87_write_value(client, nr < 6 ? LM87_REG_IN_MIN(nr) :
+			 LM87_REG_AIN_MIN(nr - 6), data->in_min[nr]);
 	mutex_unlock(&data->update_lock);
+	return count;
 }
 
-static void set_in_max(struct device *dev, const char *buf, int nr)
+static ssize_t set_in_max(struct device *dev,  struct device_attribute *attr,
+			  const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	int nr = to_sensor_dev_attr(attr)->index;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]);
-	lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) :
-			 LM87_REG_AIN_MAX(nr-6), data->in_max[nr]);
+	lm87_write_value(client, nr < 6 ? LM87_REG_IN_MAX(nr) :
+			 LM87_REG_AIN_MAX(nr - 6), data->in_max[nr]);
 	mutex_unlock(&data->update_lock);
+	return count;
 }
 
 #define set_in(offset) \
-static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, \
-		const char *buf, size_t count) \
-{ \
-	set_in_min(dev, buf, offset); \
-	return count; \
-} \
-static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, \
-		const char *buf, size_t count) \
-{ \
-	set_in_max(dev, buf, offset); \
-	return count; \
-} \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
-		show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
-		show_in##offset##_max, set_in##offset##_max);
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+		show_in_input, NULL, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+		show_in_min, set_in_min, offset); \
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+		show_in_max, set_in_max, offset)
 set_in(0);
 set_in(1);
 set_in(2);
@@ -313,80 +364,95 @@ set_in(5);
 set_in(6);
 set_in(7);
 
-#define show_temp(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
-} \
-static ssize_t show_temp##offset##_low(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[offset-1])); \
-} \
-static ssize_t show_temp##offset##_high(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[offset-1])); \
-}\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
-		show_temp##offset##_input, NULL);
-show_temp(1);
-show_temp(2);
-show_temp(3);
-
-static void set_temp_low(struct device *dev, const char *buf, int nr)
+static ssize_t show_temp_input(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
+}
+
+static ssize_t show_temp_low(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%d\n",
+		       TEMP_FROM_REG(data->temp_low[nr]));
+}
+
+static ssize_t show_temp_high(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%d\n",
+		       TEMP_FROM_REG(data->temp_high[nr]));
+}
+
+static ssize_t set_temp_low(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	int nr = to_sensor_dev_attr(attr)->index;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_low[nr] = TEMP_TO_REG(val);
 	lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
 	mutex_unlock(&data->update_lock);
+	return count;
 }
 
-static void set_temp_high(struct device *dev, const char *buf, int nr)
+static ssize_t set_temp_high(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	int nr = to_sensor_dev_attr(attr)->index;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_high[nr] = TEMP_TO_REG(val);
 	lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
 	mutex_unlock(&data->update_lock);
+	return count;
 }
 
 #define set_temp(offset) \
-static ssize_t set_temp##offset##_low(struct device *dev, struct device_attribute *attr, \
-		const char *buf, size_t count) \
-{ \
-	set_temp_low(dev, buf, offset-1); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_high(struct device *dev, struct device_attribute *attr, \
-		const char *buf, size_t count) \
-{ \
-	set_temp_high(dev, buf, offset-1); \
-	return count; \
-} \
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
-		show_temp##offset##_high, set_temp##offset##_high); \
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
-		show_temp##offset##_low, set_temp##offset##_low);
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+		show_temp_input, NULL, offset - 1); \
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
+		show_temp_high, set_temp_high, offset - 1); \
+static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
+		show_temp_low, set_temp_low, offset - 1)
 set_temp(1);
 set_temp(2);
 set_temp(3);
 
-static ssize_t show_temp_crit_int(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_crit_int(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
 	struct lm87_data *data = lm87_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int));
 }
 
-static ssize_t show_temp_crit_ext(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_crit_ext(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
 	struct lm87_data *data = lm87_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext));
@@ -396,64 +462,95 @@ static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit_int, NULL);
 static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit_ext, NULL);
 static DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit_ext, NULL);
 
-#define show_fan(offset) \
-static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[offset-1], \
-		       FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
-} \
-static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[offset-1], \
-		       FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
-} \
-static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[offset-1])); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
-		show_fan##offset##_input, NULL);
-show_fan(1);
-show_fan(2);
-
-static void set_fan_min(struct device *dev, const char *buf, int nr)
+static ssize_t show_fan_input(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+		       FAN_DIV_FROM_REG(data->fan_div[nr])));
+}
+
+static ssize_t show_fan_min(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+		       FAN_DIV_FROM_REG(data->fan_div[nr])));
+}
+
+static ssize_t show_fan_div(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	int nr = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%d\n",
+		       FAN_DIV_FROM_REG(data->fan_div[nr]));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	int nr = to_sensor_dev_attr(attr)->index;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val,
 			    FAN_DIV_FROM_REG(data->fan_div[nr]));
 	lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
 	mutex_unlock(&data->update_lock);
+	return count;
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan clock divider.  This follows the principle
-   of least surprise; the user doesn't expect the fan minimum to change just
-   because the divider changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-		size_t count, int nr)
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan clock divider.  This follows the principle
+ * of least surprise; the user doesn't expect the fan minimum to change just
+ * because the divider changed.
+ */
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	int nr = to_sensor_dev_attr(attr)->index;
+	long val;
+	int err;
 	unsigned long min;
 	u8 reg;
 
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
+
 	mutex_lock(&data->update_lock);
 	min = FAN_FROM_REG(data->fan_min[nr],
 			   FAN_DIV_FROM_REG(data->fan_div[nr]));
 
 	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
+	case 1:
+		data->fan_div[nr] = 0;
+		break;
+	case 2:
+		data->fan_div[nr] = 1;
+		break;
+	case 4:
+		data->fan_div[nr] = 2;
+		break;
+	case 8:
+		data->fan_div[nr] = 3;
+		break;
 	default:
 		mutex_unlock(&data->update_lock);
 		return -EINVAL;
@@ -479,61 +576,69 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
 }
 
 #define set_fan(offset) \
-static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
-		size_t count) \
-{ \
-	set_fan_min(dev, buf, offset-1); \
-	return count; \
-} \
-static ssize_t set_fan##offset##_div(struct device *dev, struct device_attribute *attr, const char *buf, \
-		size_t count) \
-{ \
-	return set_fan_div(dev, buf, count, offset-1); \
-} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
-		show_fan##offset##_min, set_fan##offset##_min); \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
-		show_fan##offset##_div, set_fan##offset##_div);
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+		show_fan_input, NULL, offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+		show_fan_min, set_fan_min, offset - 1); \
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+		show_fan_div, set_fan_div, offset - 1)
 set_fan(1);
 set_fan(2);
 
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+			   char *buf)
 {
 	struct lm87_data *data = lm87_update_device(dev);
 	return sprintf(buf, "%d\n", data->alarms);
 }
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
-static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
+			char *buf)
 {
 	struct lm87_data *data = lm87_update_device(dev);
 	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
 
-static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr,
+			char *buf)
 {
 	struct lm87_data *data = dev_get_drvdata(dev);
 	return sprintf(buf, "%d\n", data->vrm);
 }
-static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
 {
 	struct lm87_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	data->vrm = val;
 	return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
 
-static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_aout(struct device *dev, struct device_attribute *attr,
+			 char *buf)
 {
 	struct lm87_data *data = lm87_update_device(dev);
 	return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
 }
-static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_aout(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->aout = AOUT_TO_REG(val);
@@ -571,31 +676,31 @@ static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15);
  */
 
 static struct attribute *lm87_attributes[] = {
-	&dev_attr_in1_input.attr,
-	&dev_attr_in1_min.attr,
-	&dev_attr_in1_max.attr,
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in1_min.dev_attr.attr,
+	&sensor_dev_attr_in1_max.dev_attr.attr,
 	&sensor_dev_attr_in1_alarm.dev_attr.attr,
-	&dev_attr_in2_input.attr,
-	&dev_attr_in2_min.attr,
-	&dev_attr_in2_max.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in2_min.dev_attr.attr,
+	&sensor_dev_attr_in2_max.dev_attr.attr,
 	&sensor_dev_attr_in2_alarm.dev_attr.attr,
-	&dev_attr_in3_input.attr,
-	&dev_attr_in3_min.attr,
-	&dev_attr_in3_max.attr,
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in3_min.dev_attr.attr,
+	&sensor_dev_attr_in3_max.dev_attr.attr,
 	&sensor_dev_attr_in3_alarm.dev_attr.attr,
-	&dev_attr_in4_input.attr,
-	&dev_attr_in4_min.attr,
-	&dev_attr_in4_max.attr,
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in4_min.dev_attr.attr,
+	&sensor_dev_attr_in4_max.dev_attr.attr,
 	&sensor_dev_attr_in4_alarm.dev_attr.attr,
 
-	&dev_attr_temp1_input.attr,
-	&dev_attr_temp1_max.attr,
-	&dev_attr_temp1_min.attr,
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&dev_attr_temp1_crit.attr,
 	&sensor_dev_attr_temp1_alarm.dev_attr.attr,
-	&dev_attr_temp2_input.attr,
-	&dev_attr_temp2_max.attr,
-	&dev_attr_temp2_min.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_max.dev_attr.attr,
+	&sensor_dev_attr_temp2_min.dev_attr.attr,
 	&dev_attr_temp2_crit.attr,
 	&sensor_dev_attr_temp2_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp2_fault.dev_attr.attr,
@@ -610,70 +715,110 @@ static const struct attribute_group lm87_group = {
 	.attrs = lm87_attributes,
 };
 
-static struct attribute *lm87_attributes_opt[] = {
-	&dev_attr_in6_input.attr,
-	&dev_attr_in6_min.attr,
-	&dev_attr_in6_max.attr,
+static struct attribute *lm87_attributes_in6[] = {
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in6_min.dev_attr.attr,
+	&sensor_dev_attr_in6_max.dev_attr.attr,
 	&sensor_dev_attr_in6_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group lm87_group_in6 = {
+	.attrs = lm87_attributes_in6,
+};
 
-	&dev_attr_fan1_input.attr,
-	&dev_attr_fan1_min.attr,
-	&dev_attr_fan1_div.attr,
+static struct attribute *lm87_attributes_fan1[] = {
+	&sensor_dev_attr_fan1_input.dev_attr.attr,
+	&sensor_dev_attr_fan1_min.dev_attr.attr,
+	&sensor_dev_attr_fan1_div.dev_attr.attr,
 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group lm87_group_fan1 = {
+	.attrs = lm87_attributes_fan1,
+};
 
-	&dev_attr_in7_input.attr,
-	&dev_attr_in7_min.attr,
-	&dev_attr_in7_max.attr,
+static struct attribute *lm87_attributes_in7[] = {
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in7_min.dev_attr.attr,
+	&sensor_dev_attr_in7_max.dev_attr.attr,
 	&sensor_dev_attr_in7_alarm.dev_attr.attr,
+	NULL
+};
 
-	&dev_attr_fan2_input.attr,
-	&dev_attr_fan2_min.attr,
-	&dev_attr_fan2_div.attr,
+static const struct attribute_group lm87_group_in7 = {
+	.attrs = lm87_attributes_in7,
+};
+
+static struct attribute *lm87_attributes_fan2[] = {
+	&sensor_dev_attr_fan2_input.dev_attr.attr,
+	&sensor_dev_attr_fan2_min.dev_attr.attr,
+	&sensor_dev_attr_fan2_div.dev_attr.attr,
 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group lm87_group_fan2 = {
+	.attrs = lm87_attributes_fan2,
+};
 
-	&dev_attr_temp3_input.attr,
-	&dev_attr_temp3_max.attr,
-	&dev_attr_temp3_min.attr,
+static struct attribute *lm87_attributes_temp3[] = {
+	&sensor_dev_attr_temp3_input.dev_attr.attr,
+	&sensor_dev_attr_temp3_max.dev_attr.attr,
+	&sensor_dev_attr_temp3_min.dev_attr.attr,
 	&dev_attr_temp3_crit.attr,
 	&sensor_dev_attr_temp3_alarm.dev_attr.attr,
 	&sensor_dev_attr_temp3_fault.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group lm87_group_temp3 = {
+	.attrs = lm87_attributes_temp3,
+};
 
-	&dev_attr_in0_input.attr,
-	&dev_attr_in0_min.attr,
-	&dev_attr_in0_max.attr,
+static struct attribute *lm87_attributes_in0_5[] = {
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in0_min.dev_attr.attr,
+	&sensor_dev_attr_in0_max.dev_attr.attr,
 	&sensor_dev_attr_in0_alarm.dev_attr.attr,
-	&dev_attr_in5_input.attr,
-	&dev_attr_in5_min.attr,
-	&dev_attr_in5_max.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in5_min.dev_attr.attr,
+	&sensor_dev_attr_in5_max.dev_attr.attr,
 	&sensor_dev_attr_in5_alarm.dev_attr.attr,
+	NULL
+};
 
+static const struct attribute_group lm87_group_in0_5 = {
+	.attrs = lm87_attributes_in0_5,
+};
+
+static struct attribute *lm87_attributes_vid[] = {
 	&dev_attr_cpu0_vid.attr,
 	&dev_attr_vrm.attr,
-
 	NULL
 };
 
-static const struct attribute_group lm87_group_opt = {
-	.attrs = lm87_attributes_opt,
+static const struct attribute_group lm87_group_vid = {
+	.attrs = lm87_attributes_vid,
 };
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm87_detect(struct i2c_client *new_client,
-		       struct i2c_board_info *info)
+static int lm87_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
-	struct i2c_adapter *adapter = new_client->adapter;
+	struct i2c_adapter *adapter = client->adapter;
 	const char *name;
 	u8 cid, rev;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	if (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)
+	if (lm87_read_value(client, LM87_REG_CONFIG) & 0x80)
 		return -ENODEV;
 
 	/* Now, we do the remaining detection. */
-	cid = lm87_read_value(new_client, LM87_REG_COMPANY_ID);
-	rev = lm87_read_value(new_client, LM87_REG_REVISION);
+	cid = lm87_read_value(client, LM87_REG_COMPANY_ID);
+	rev = lm87_read_value(client, LM87_REG_REVISION);
 
 	if (cid == 0x02			/* National Semiconductor */
 	 && (rev >= 0x01 && rev <= 0x08))
@@ -683,7 +828,7 @@ static int lm87_detect(struct i2c_client *new_client,
 		name = "adm1024";
 	else {
 		dev_dbg(&adapter->dev, "LM87 detection failed at 0x%02x\n",
-			new_client->addr);
+			client->addr);
 		return -ENODEV;
 	}
 
@@ -692,8 +837,63 @@ static int lm87_detect(struct i2c_client *new_client,
 	return 0;
 }
 
-static int lm87_probe(struct i2c_client *new_client,
-		      const struct i2c_device_id *id)
+static void lm87_remove_files(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+
+	sysfs_remove_group(&dev->kobj, &lm87_group);
+	sysfs_remove_group(&dev->kobj, &lm87_group_in6);
+	sysfs_remove_group(&dev->kobj, &lm87_group_fan1);
+	sysfs_remove_group(&dev->kobj, &lm87_group_in7);
+	sysfs_remove_group(&dev->kobj, &lm87_group_fan2);
+	sysfs_remove_group(&dev->kobj, &lm87_group_temp3);
+	sysfs_remove_group(&dev->kobj, &lm87_group_in0_5);
+	sysfs_remove_group(&dev->kobj, &lm87_group_vid);
+}
+
+static void lm87_init_client(struct i2c_client *client)
+{
+	struct lm87_data *data = i2c_get_clientdata(client);
+
+	if (client->dev.platform_data) {
+		data->channel = *(u8 *)client->dev.platform_data;
+		lm87_write_value(client,
+				 LM87_REG_CHANNEL_MODE, data->channel);
+	} else {
+		data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
+	}
+	data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F;
+
+	if (!(data->config & 0x01)) {
+		int i;
+
+		/* Limits are left uninitialized after power-up */
+		for (i = 1; i < 6; i++) {
+			lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00);
+			lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF);
+		}
+		for (i = 0; i < 2; i++) {
+			lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F);
+			lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00);
+			lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00);
+			lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF);
+		}
+		if (data->channel & CHAN_TEMP3) {
+			lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F);
+			lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00);
+		} else {
+			lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00);
+			lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF);
+		}
+	}
+
+	/* Make sure Start is set and INT#_Clear is clear */
+	if ((data->config & 0x09) != 0x01)
+		lm87_write_value(client, LM87_REG_CONFIG,
+				 (data->config & 0x77) | 0x01);
+}
+
+static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct lm87_data *data;
 	int err;
@@ -704,12 +904,12 @@ static int lm87_probe(struct i2c_client *new_client,
 		goto exit;
 	}
 
-	i2c_set_clientdata(new_client, data);
+	i2c_set_clientdata(client, data);
 	data->valid = 0;
 	mutex_init(&data->update_lock);
 
 	/* Initialize the LM87 chip */
-	lm87_init_client(new_client);
+	lm87_init_client(client);
 
 	data->in_scale[0] = 2500;
 	data->in_scale[1] = 2700;
@@ -721,97 +921,48 @@ static int lm87_probe(struct i2c_client *new_client,
 	data->in_scale[7] = 1875;
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group)))
+	err = sysfs_create_group(&client->dev.kobj, &lm87_group);
+	if (err)
 		goto exit_free;
 
 	if (data->channel & CHAN_NO_FAN(0)) {
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_in6_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in6_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in6_max))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_in6_alarm.dev_attr)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_in6);
+		if (err)
 			goto exit_remove;
 	} else {
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_fan1_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_fan1_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_fan1_div))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_fan1_alarm.dev_attr)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_fan1);
+		if (err)
 			goto exit_remove;
 	}
 
 	if (data->channel & CHAN_NO_FAN(1)) {
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_in7_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in7_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in7_max))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_in7_alarm.dev_attr)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_in7);
+		if (err)
 			goto exit_remove;
 	} else {
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_fan2_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_fan2_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_fan2_div))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_fan2_alarm.dev_attr)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_fan2);
+		if (err)
 			goto exit_remove;
 	}
 
 	if (data->channel & CHAN_TEMP3) {
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_temp3_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_temp3_max))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_temp3_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_temp3_crit))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_temp3_alarm.dev_attr))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_temp3_fault.dev_attr)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_temp3);
+		if (err)
 			goto exit_remove;
 	} else {
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_in0_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in0_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in0_max))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_in0_alarm.dev_attr))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in5_input))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in5_min))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_in5_max))
-		 || (err = device_create_file(&new_client->dev,
-					&sensor_dev_attr_in5_alarm.dev_attr)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_in0_5);
+		if (err)
 			goto exit_remove;
 	}
 
 	if (!(data->channel & CHAN_NO_VID)) {
 		data->vrm = vid_which_vrm();
-		if ((err = device_create_file(&new_client->dev,
-					&dev_attr_cpu0_vid))
-		 || (err = device_create_file(&new_client->dev,
-					&dev_attr_vrm)))
+		err = sysfs_create_group(&client->dev.kobj, &lm87_group_vid);
+		if (err)
 			goto exit_remove;
 	}
 
-	data->hwmon_dev = hwmon_device_register(&new_client->dev);
+	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (IS_ERR(data->hwmon_dev)) {
 		err = PTR_ERR(data->hwmon_dev);
 		goto exit_remove;
@@ -820,162 +971,51 @@ static int lm87_probe(struct i2c_client *new_client,
 	return 0;
 
 exit_remove:
-	sysfs_remove_group(&new_client->dev.kobj, &lm87_group);
-	sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt);
+	lm87_remove_files(client);
 exit_free:
-	lm87_write_value(new_client, LM87_REG_CONFIG, data->config);
+	lm87_write_value(client, LM87_REG_CONFIG, data->config);
 	kfree(data);
 exit:
 	return err;
 }
 
-static void lm87_init_client(struct i2c_client *client)
-{
-	struct lm87_data *data = i2c_get_clientdata(client);
-
-	if (client->dev.platform_data) {
-		data->channel = *(u8 *)client->dev.platform_data;
-		lm87_write_value(client,
-				 LM87_REG_CHANNEL_MODE, data->channel);
-	} else {
-		data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
-	}
-	data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F;
-
-	if (!(data->config & 0x01)) {
-		int i;
-
-		/* Limits are left uninitialized after power-up */
-		for (i = 1; i < 6; i++) {
-			lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00);
-			lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF);
-		}
-		for (i = 0; i < 2; i++) {
-			lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F);
-			lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00);
-			lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00);
-			lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF);
-		}
-		if (data->channel & CHAN_TEMP3) {
-			lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F);
-			lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00);
-		} else {
-			lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00);
-			lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF);
-		}
-	}
-
-	/* Make sure Start is set and INT#_Clear is clear */
-	if ((data->config & 0x09) != 0x01)
-		lm87_write_value(client, LM87_REG_CONFIG,
-				 (data->config & 0x77) | 0x01);
-}
-
 static int lm87_remove(struct i2c_client *client)
 {
 	struct lm87_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &lm87_group);
-	sysfs_remove_group(&client->dev.kobj, &lm87_group_opt);
+	lm87_remove_files(client);
 
 	lm87_write_value(client, LM87_REG_CONFIG, data->config);
 	kfree(data);
 	return 0;
 }
 
-static struct lm87_data *lm87_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-		int i, j;
-
-		dev_dbg(&client->dev, "Updating data.\n");
-
-		i = (data->channel & CHAN_TEMP3) ? 1 : 0;
-		j = (data->channel & CHAN_TEMP3) ? 5 : 6;
-		for (; i < j; i++) {
-			data->in[i] = lm87_read_value(client,
-				      LM87_REG_IN(i));
-			data->in_min[i] = lm87_read_value(client,
-					  LM87_REG_IN_MIN(i));
-			data->in_max[i] = lm87_read_value(client,
-					  LM87_REG_IN_MAX(i));
-		}
-
-		for (i = 0; i < 2; i++) {
-			if (data->channel & CHAN_NO_FAN(i)) {
-				data->in[6+i] = lm87_read_value(client,
-						LM87_REG_AIN(i));
-				data->in_max[6+i] = lm87_read_value(client,
-						    LM87_REG_AIN_MAX(i));
-				data->in_min[6+i] = lm87_read_value(client,
-						    LM87_REG_AIN_MIN(i));
-
-			} else {
-				data->fan[i] = lm87_read_value(client,
-					       LM87_REG_FAN(i));
-				data->fan_min[i] = lm87_read_value(client,
-						   LM87_REG_FAN_MIN(i));
-			}
-		}
-
-		j = (data->channel & CHAN_TEMP3) ? 3 : 2;
-		for (i = 0 ; i < j; i++) {
-			data->temp[i] = lm87_read_value(client,
-					LM87_REG_TEMP[i]);
-			data->temp_high[i] = lm87_read_value(client,
-					     LM87_REG_TEMP_HIGH[i]);
-			data->temp_low[i] = lm87_read_value(client,
-					    LM87_REG_TEMP_LOW[i]);
-		}
-
-		i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK);
-		j = lm87_read_value(client, LM87_REG_TEMP_HW_INT);
-		data->temp_crit_int = min(i, j);
-
-		i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK);
-		j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT);
-		data->temp_crit_ext = min(i, j);
-
-		i = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = (i >> 6) & 0x03;
-		data->vid = (i & 0x0F)
-			  | (lm87_read_value(client, LM87_REG_VID4) & 0x01)
-			     << 4;
-
-		data->alarms = lm87_read_value(client, LM87_REG_ALARMS1)
-			     | (lm87_read_value(client, LM87_REG_ALARMS2)
-				<< 8);
-		data->aout = lm87_read_value(client, LM87_REG_AOUT);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	mutex_unlock(&data->update_lock);
+/*
+ * Driver data (common to all clients)
+ */
 
-	return data;
-}
+static const struct i2c_device_id lm87_id[] = {
+	{ "lm87", lm87 },
+	{ "adm1024", adm1024 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lm87_id);
 
-static int __init sensors_lm87_init(void)
-{
-	return i2c_add_driver(&lm87_driver);
-}
+static struct i2c_driver lm87_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "lm87",
+	},
+	.probe		= lm87_probe,
+	.remove		= lm87_remove,
+	.id_table	= lm87_id,
+	.detect		= lm87_detect,
+	.address_list	= normal_i2c,
+};
 
-static void __exit sensors_lm87_exit(void)
-{
-	i2c_del_driver(&lm87_driver);
-}
+module_i2c_driver(lm87_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org> and others");
 MODULE_DESCRIPTION("LM87 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm87_init);
-module_exit(sensors_lm87_exit);
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index d2dd5f9..3309a51 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -57,6 +57,9 @@
  * This driver also supports the SA56004 from Philips. This device is
  * pin-compatible with the LM86, the ED/EDP parts are also address-compatible.
  *
+ * This driver also supports the G781 from GMT. This device is compatible
+ * with the ADM1032.
+ *
  * Since the LM90 was the first chipset supported by this driver, most
  * comments will refer to this chipset, but are actually general and
  * concern all supported chipsets, unless mentioned otherwise.
@@ -107,7 +110,7 @@ static const unsigned short normal_i2c[] = {
 	0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
 
 enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
-	max6646, w83l771, max6696, sa56004 };
+	max6646, w83l771, max6696, sa56004, g781 };
 
 /*
  * The LM90 registers
@@ -184,6 +187,7 @@ static const struct i2c_device_id lm90_id[] = {
 	{ "adm1032", adm1032 },
 	{ "adt7461", adt7461 },
 	{ "adt7461a", adt7461 },
+	{ "g781", g781 },
 	{ "lm90", lm90 },
 	{ "lm86", lm86 },
 	{ "lm89", lm86 },
@@ -229,6 +233,12 @@ static const struct lm90_params lm90_params[] = {
 		.alert_alarms = 0x7c,
 		.max_convrate = 10,
 	},
+	[g781] = {
+		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT
+		  | LM90_HAVE_BROKEN_ALERT,
+		.alert_alarms = 0x7c,
+		.max_convrate = 8,
+	},
 	[lm86] = {
 		.flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT,
 		.alert_alarms = 0x7b,
@@ -308,22 +318,24 @@ struct lm90_data {
 
 	/* registers values */
 	s8 temp8[8];	/* 0: local low limit
-			   1: local high limit
-			   2: local critical limit
-			   3: remote critical limit
-			   4: local emergency limit (max6659 and max6695/96)
-			   5: remote emergency limit (max6659 and max6695/96)
-			   6: remote 2 critical limit (max6695/96 only)
-			   7: remote 2 emergency limit (max6695/96 only) */
+			 * 1: local high limit
+			 * 2: local critical limit
+			 * 3: remote critical limit
+			 * 4: local emergency limit (max6659 and max6695/96)
+			 * 5: remote emergency limit (max6659 and max6695/96)
+			 * 6: remote 2 critical limit (max6695/96 only)
+			 * 7: remote 2 emergency limit (max6695/96 only)
+			 */
 	s16 temp11[8];	/* 0: remote input
-			   1: remote low limit
-			   2: remote high limit
-			   3: remote offset (except max6646, max6657/58/59,
-					     and max6695/96)
-			   4: local input
-			   5: remote 2 input (max6695/96 only)
-			   6: remote 2 low limit (max6695/96 only)
-			   7: remote 2 high limit (ma6695/96 only) */
+			 * 1: remote low limit
+			 * 2: remote high limit
+			 * 3: remote offset (except max6646, max6657/58/59,
+			 *		     and max6695/96)
+			 * 4: local input
+			 * 5: remote 2 input (max6695/96 only)
+			 * 6: remote 2 low limit (max6695/96 only)
+			 * 7: remote 2 high limit (max6695/96 only)
+			 */
 	u8 temp_hyst;
 	u16 alarms; /* bitvector (upper 8 bits for max6695/96) */
 };
@@ -533,8 +545,10 @@ static struct lm90_data *lm90_update_device(struct device *dev)
 				data->alarms |= alarms << 8;
 		}
 
-		/* Re-enable ALERT# output if it was originally enabled and
-		 * relevant alarms are all clear */
+		/*
+		 * Re-enable ALERT# output if it was originally enabled and
+		 * relevant alarms are all clear
+		 */
 		if ((data->config_orig & 0x80) == 0
 		 && (data->alarms & data->alert_alarms) == 0) {
 			u8 config;
@@ -1162,8 +1176,10 @@ static int lm90_detect(struct i2c_client *client,
 		 && (config1 & 0x3F) == 0x00
 		 && convrate <= 0x0A) {
 			name = "adm1032";
-			/* The ADM1032 supports PEC, but only if combined
-			   transactions are not used. */
+			/*
+			 * The ADM1032 supports PEC, but only if combined
+			 * transactions are not used.
+			 */
 			if (i2c_check_functionality(adapter,
 						    I2C_FUNC_SMBUS_BYTE))
 				info->flags |= I2C_CLIENT_PEC;
@@ -1283,6 +1299,13 @@ static int lm90_detect(struct i2c_client *client,
 		 && convrate <= 0x09) {
 			name = "sa56004";
 		}
+	} else
+	if ((address == 0x4C || address == 0x4D)
+	 && man_id == 0x47) { /* GMT */
+		if (chip_id == 0x01 /* G781 */
+		 && (config1 & 0x3F) == 0x00
+		 && convrate <= 0x08)
+			name = "g781";
 	}
 
 	if (!name) { /* identification failed */
@@ -1382,8 +1405,10 @@ static int lm90_probe(struct i2c_client *client,
 			client->flags &= ~I2C_CLIENT_PEC;
 	}
 
-	/* Different devices have different alarm bits triggering the
-	 * ALERT# output */
+	/*
+	 * Different devices have different alarm bits triggering the
+	 * ALERT# output
+	 */
 	data->alert_alarms = lm90_params[data->kind].alert_alarms;
 
 	/* Set chip capabilities */
@@ -1488,9 +1513,11 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag)
 			dev_warn(&client->dev,
 				 "temp%d out of range, please check!\n", 3);
 
-		/* Disable ALERT# output, because these chips don't implement
-		  SMBus alert correctly; they should only hold the alert line
-		  low briefly. */
+		/*
+		 * Disable ALERT# output, because these chips don't implement
+		 * SMBus alert correctly; they should only hold the alert line
+		 * low briefly.
+		 */
 		if ((data->flags & LM90_HAVE_BROKEN_ALERT)
 		 && (alarms & data->alert_alarms)) {
 			dev_dbg(&client->dev, "Disabling ALERT#\n");
@@ -1514,19 +1541,8 @@ static struct i2c_driver lm90_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_lm90_init(void)
-{
-	return i2c_add_driver(&lm90_driver);
-}
-
-static void __exit sensors_lm90_exit(void)
-{
-	i2c_del_driver(&lm90_driver);
-}
+module_i2c_driver(lm90_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("LM90/ADM1032 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm90_init);
-module_exit(sensors_lm90_exit);
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index 8fcbd4d4..fdc691a 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -49,8 +49,10 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 
-/* The LM92 and MAX6635 have 2 two-state pins for address selection,
-   resulting in 4 possible addresses. */
+/*
+ * The LM92 and MAX6635 have 2 two-state pins for address selection,
+ * resulting in 4 possible addresses.
+ */
 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
 						I2C_CLIENT_END };
 
@@ -63,11 +65,13 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
 #define LM92_REG_TEMP_HIGH		0x05 /* 16-bit, RW */
 #define LM92_REG_MAN_ID			0x07 /* 16-bit, RO, LM92 only */
 
-/* The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
-   left-justified in 16-bit registers. No rounding is done, with such
-   a resolution it's just not worth it. Note that the MAX6635 doesn't
-   make use of the 4 lower bits for limits (i.e. effective resolution
-   for limits is 1 degree Celsius). */
+/*
+ * The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
+ * left-justified in 16-bit registers. No rounding is done, with such
+ * a resolution it's just not worth it. Note that the MAX6635 doesn't
+ * make use of the 4 lower bits for limits (i.e. effective resolution
+ * for limits is 1 degree Celsius).
+ */
 static inline int TEMP_FROM_REG(s16 reg)
 {
 	return reg / 8 * 625 / 10;
@@ -138,7 +142,8 @@ static struct lm92_data *lm92_update_device(struct device *dev)
 }
 
 #define show_temp(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, \
+			    char *buf) \
 { \
 	struct lm92_data *data = lm92_update_device(dev); \
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
@@ -149,13 +154,17 @@ show_temp(temp1_min);
 show_temp(temp1_max);
 
 #define set_temp(value, reg) \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \
+			   const char *buf, \
 	size_t count) \
 { \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct lm92_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
+	long val; \
+	int err = kstrtol(buf, 10, &val); \
+	if (err) \
+		return err; \
+\
 	mutex_lock(&data->update_lock); \
 	data->value = TEMP_TO_REG(val); \
 	i2c_smbus_write_word_swapped(client, reg, data->value); \
@@ -166,31 +175,40 @@ set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
 set_temp(temp1_min, LM92_REG_TEMP_LOW);
 set_temp(temp1_max, LM92_REG_TEMP_HIGH);
 
-static ssize_t show_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp1_crit_hyst(struct device *dev,
+				    struct device_attribute *attr, char *buf)
 {
 	struct lm92_data *data = lm92_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit)
 		       - TEMP_FROM_REG(data->temp1_hyst));
 }
-static ssize_t show_temp1_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp1_max_hyst(struct device *dev,
+				   struct device_attribute *attr, char *buf)
 {
 	struct lm92_data *data = lm92_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max)
 		       - TEMP_FROM_REG(data->temp1_hyst));
 }
-static ssize_t show_temp1_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp1_min_hyst(struct device *dev,
+				   struct device_attribute *attr, char *buf)
 {
 	struct lm92_data *data = lm92_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min)
 		       + TEMP_FROM_REG(data->temp1_hyst));
 }
 
-static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf,
-	size_t count)
+static ssize_t set_temp1_crit_hyst(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm92_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
@@ -200,7 +218,8 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *
 	return count;
 }
 
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+			   char *buf)
 {
 	struct lm92_data *data = lm92_update_device(dev);
 	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
@@ -246,26 +265,30 @@ static void lm92_init_client(struct i2c_client *client)
 					  config & 0xFE);
 }
 
-/* The MAX6635 has no identification register, so we have to use tricks
-   to identify it reliably. This is somewhat slow.
-   Note that we do NOT rely on the 2 MSB of the configuration register
-   always reading 0, as suggested by the datasheet, because it was once
-   reported not to be true. */
+/*
+ * The MAX6635 has no identification register, so we have to use tricks
+ * to identify it reliably. This is somewhat slow.
+ * Note that we do NOT rely on the 2 MSB of the configuration register
+ * always reading 0, as suggested by the datasheet, because it was once
+ * reported not to be true.
+ */
 static int max6635_check(struct i2c_client *client)
 {
 	u16 temp_low, temp_high, temp_hyst, temp_crit;
 	u8 conf;
 	int i;
 
-	/* No manufacturer ID register, so a read from this address will
-	   always return the last read value. */
+	/*
+	 * No manufacturer ID register, so a read from this address will
+	 * always return the last read value.
+	 */
 	temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW);
 	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low)
 		return 0;
 	temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH);
 	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high)
 		return 0;
-	
+
 	/* Limits are stored as integer values (signed, 9-bit). */
 	if ((temp_low & 0x7f00) || (temp_high & 0x7f00))
 		return 0;
@@ -274,22 +297,24 @@ static int max6635_check(struct i2c_client *client)
 	if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00))
 		return 0;
 
-	/* Registers addresses were found to cycle over 16-byte boundaries.
-	   We don't test all registers with all offsets so as to save some
-	   reads and time, but this should still be sufficient to dismiss
-	   non-MAX6635 chips. */
+	/*
+	 * Registers addresses were found to cycle over 16-byte boundaries.
+	 * We don't test all registers with all offsets so as to save some
+	 * reads and time, but this should still be sufficient to dismiss
+	 * non-MAX6635 chips.
+	 */
 	conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
-	for (i=16; i<96; i*=2) {
+	for (i = 16; i < 96; i *= 2) {
 		if (temp_hyst != i2c_smbus_read_word_data(client,
-		 		 LM92_REG_TEMP_HYST + i - 16)
+				 LM92_REG_TEMP_HYST + i - 16)
 		 || temp_crit != i2c_smbus_read_word_data(client,
-		 		 LM92_REG_TEMP_CRIT + i)
+				 LM92_REG_TEMP_CRIT + i)
 		 || temp_low != i2c_smbus_read_word_data(client,
 				LM92_REG_TEMP_LOW + i + 16)
 		 || temp_high != i2c_smbus_read_word_data(client,
-		 		 LM92_REG_TEMP_HIGH + i + 32)
+				 LM92_REG_TEMP_HIGH + i + 32)
 		 || conf != i2c_smbus_read_byte_data(client,
-		 	    LM92_REG_CONFIG + i))
+			    LM92_REG_CONFIG + i))
 			return 0;
 	}
 
@@ -362,7 +387,8 @@ static int lm92_probe(struct i2c_client *new_client,
 	lm92_init_client(new_client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &lm92_group)))
+	err = sysfs_create_group(&new_client->dev.kobj, &lm92_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -416,19 +442,8 @@ static struct i2c_driver lm92_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_lm92_init(void)
-{
-	return i2c_add_driver(&lm92_driver);
-}
-
-static void __exit sensors_lm92_exit(void)
-{
-	i2c_del_driver(&lm92_driver);
-}
+module_i2c_driver(lm92_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("LM92/MAX6635 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm92_init);
-module_exit(sensors_lm92_exit);
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index 8bd6c5c..67e8fe2 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -1,42 +1,42 @@
 /*
-    lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
-
-    Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
-	Copyright (c) 2004 Utilitek Systems, Inc.
-
-    derived in part from lm78.c:
-	Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
-
-    derived in part from lm85.c:
-	Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com>
-	Copyright (c) 2003       Margit Schubert-While <margitsw@t-online.de>
-
-    derived in part from w83l785ts.c:
-	Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org>
-
-    Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com>
-	Copyright (c) 2005 Aspen Systems, Inc.
-
-    Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org>
-        Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab
-
-    Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de>
-        Copyright (c) 2007 Hans J. Koch, Linutronix GmbH
-
-    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.
-*/
+ * lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
+ *
+ * Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
+ *	Copyright (c) 2004 Utilitek Systems, Inc.
+ *
+ * derived in part from lm78.c:
+ *	Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+ *
+ * derived in part from lm85.c:
+ *	Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com>
+ *	Copyright (c) 2003       Margit Schubert-While <margitsw@t-online.de>
+ *
+ * derived in part from w83l785ts.c:
+ *	Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org>
+ *
+ * Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com>
+ *	Copyright (c) 2005 Aspen Systems, Inc.
+ *
+ * Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org>
+ *	Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab
+ *
+ * Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de>
+ *	Copyright (c) 2007 Hans J. Koch, Linutronix GmbH
+ *
+ * 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>
@@ -83,7 +83,7 @@
 #define LM93_REG_FAN_MIN(nr)		(0xb4 + (nr) * 2)
 
 /* pwm outputs: pwm1-pwm2 (nr => 0-1, reg => 0-3) */
-#define LM93_REG_PWM_CTL(nr,reg)	(0xc8 + (reg) + (nr) * 4)
+#define LM93_REG_PWM_CTL(nr, reg)	(0xc8 + (reg) + (nr) * 4)
 #define LM93_PWM_CTL1	0x0
 #define LM93_PWM_CTL2	0x1
 #define LM93_PWM_CTL3	0x2
@@ -160,7 +160,7 @@ static bool init;
 module_param(init, bool, 0);
 MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization.");
 
-static int vccp_limit_type[2] = {0,0};
+static int vccp_limit_type[2] = {0, 0};
 module_param_array(vccp_limit_type, int, NULL, 0);
 MODULE_PARM_DESC(vccp_limit_type, "Configures in7 and in8 limit modes.");
 
@@ -187,8 +187,10 @@ static const struct { u8 cmd; u8 len; } lm93_block_read_cmds[12] = {
 	{ 0xfd,  9 },
 };
 
-/* ALARMS: SYSCTL format described further below
-   REG: 64 bits in 8 registers, as immediately below */
+/*
+ * ALARMS: SYSCTL format described further below
+ * REG: 64 bits in 8 registers, as immediately below
+ */
 struct block1_t {
 	u8 host_status_1;
 	u8 host_status_2;
@@ -217,8 +219,10 @@ struct lm93_data {
 	/* register values, arranged by block read groups */
 	struct block1_t block1;
 
-	/* temp1 - temp4: unfiltered readings
-	   temp1 - temp2: filtered readings */
+	/*
+	 * temp1 - temp4: unfiltered readings
+	 * temp1 - temp2: filtered readings
+	 */
 	u8 block2[6];
 
 	/* vin1 - vin16: readings */
@@ -295,14 +299,18 @@ struct lm93_data {
 	u8 sfc2;
 	u8 sf_tach_to_pwm;
 
-	/* The two PWM CTL2  registers can read something other than what was
-	   last written for the OVR_DC field (duty cycle override).  So, we
-	   save the user-commanded value here. */
+	/*
+	 * The two PWM CTL2  registers can read something other than what was
+	 * last written for the OVR_DC field (duty cycle override).  So, we
+	 * save the user-commanded value here.
+	 */
 	u8 pwm_override[2];
 };
 
-/* VID:	mV
-   REG: 6-bits, right justified, *always* using Intel VRM/VRD 10 */
+/*
+ * VID:	mV
+ * REG: 6-bits, right justified, *always* using Intel VRM/VRD 10
+ */
 static int LM93_VID_FROM_REG(u8 reg)
 {
 	return vid_from_reg((reg & 0x3f), 100);
@@ -317,12 +325,13 @@ static const u8 lm93_vin_reg_max[16] = {
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 	0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1,
 };
-/* Values from the datasheet. They're here for documentation only.
-static const u8 lm93_vin_reg_nom[16] = {
-	0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-	0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0,
-};
-*/
+/*
+ * Values from the datasheet. They're here for documentation only.
+ * static const u8 lm93_vin_reg_nom[16] = {
+ * 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
+ * 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0,
+ * };
+ */
 
 /* min, max, and nominal voltage readings, per channel (mV)*/
 static const unsigned long lm93_vin_val_min[16] = {
@@ -334,12 +343,13 @@ static const unsigned long lm93_vin_val_max[16] = {
 	1236, 1236, 1236, 1600, 2000, 2000, 1600, 1600,
 	4400, 6500, 3333, 2625, 1312, 1312, 1236, 3600,
 };
-/* Values from the datasheet. They're here for documentation only.
-static const unsigned long lm93_vin_val_nom[16] = {
-	 927,  927,  927, 1200, 1500, 1500, 1200, 1200,
-	3300, 5000, 2500, 1969,  984,  984,  309, 3300,
-};
-*/
+/*
+ * Values from the datasheet. They're here for documentation only.
+ * static const unsigned long lm93_vin_val_nom[16] = {
+ * 927,  927,  927, 1200, 1500, 1500, 1200, 1200,
+ * 3300, 5000, 2500, 1969,  984,  984,  309, 3300,
+ * };
+ */
 
 static unsigned LM93_IN_FROM_REG(int nr, u8 reg)
 {
@@ -353,8 +363,10 @@ static unsigned LM93_IN_FROM_REG(int nr, u8 reg)
 	return (slope * reg + intercept + 500) / 1000;
 }
 
-/* IN: mV, limits determined by channel nr
-   REG: scaling determined by channel nr */
+/*
+ * IN: mV, limits determined by channel nr
+ * REG: scaling determined by channel nr
+ */
 static u8 LM93_IN_TO_REG(int nr, unsigned val)
 {
 	/* range limit */
@@ -386,12 +398,14 @@ static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid)
 	return (uV_vid + uV_offset + 5000) / 10000;
 }
 
-#define LM93_IN_MIN_FROM_REG(reg,vid)	LM93_IN_REL_FROM_REG(reg,0,vid)
-#define LM93_IN_MAX_FROM_REG(reg,vid)	LM93_IN_REL_FROM_REG(reg,1,vid)
+#define LM93_IN_MIN_FROM_REG(reg, vid)	LM93_IN_REL_FROM_REG((reg), 0, (vid))
+#define LM93_IN_MAX_FROM_REG(reg, vid)	LM93_IN_REL_FROM_REG((reg), 1, (vid))
 
-/* vid in mV , upper == 0 indicates low limit, otherwise upper limit
-   upper also determines which nibble of the register is returned
-   (the other nibble will be 0x0) */
+/*
+ * vid in mV , upper == 0 indicates low limit, otherwise upper limit
+ * upper also determines which nibble of the register is returned
+ * (the other nibble will be 0x0)
+ */
 static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid)
 {
 	long uV_offset = vid * 1000 - val * 10000;
@@ -404,22 +418,26 @@ static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid)
 	}
 }
 
-/* TEMP: 1/1000 degrees C (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: 1/1000 degrees C (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static int LM93_TEMP_FROM_REG(u8 reg)
 {
 	return (s8)reg * 1000;
 }
 
 #define LM93_TEMP_MIN (-128000)
-#define LM93_TEMP_MAX ( 127000)
+#define LM93_TEMP_MAX (127000)
 
-/* TEMP: 1/1000 degrees C (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: 1/1000 degrees C (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static u8 LM93_TEMP_TO_REG(long temp)
 {
 	int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX);
-	ntemp += (ntemp<0 ? -500 : 500);
+	ntemp += (ntemp < 0 ? -500 : 500);
 	return (u8)(ntemp / 1000);
 }
 
@@ -430,21 +448,25 @@ static int LM93_TEMP_OFFSET_MODE_FROM_REG(u8 sfc2, int nr)
 	return sfc2 & (nr < 2 ? 0x10 : 0x20);
 }
 
-/* This function is common to all 4-bit temperature offsets
-   reg is 4 bits right justified
-   mode 0 => 1C/bit, mode !0 => 0.5C/bit */
+/*
+ * This function is common to all 4-bit temperature offsets
+ * reg is 4 bits right justified
+ * mode 0 => 1C/bit, mode !0 => 0.5C/bit
+ */
 static int LM93_TEMP_OFFSET_FROM_REG(u8 reg, int mode)
 {
 	return (reg & 0x0f) * (mode ? 5 : 10);
 }
 
-#define LM93_TEMP_OFFSET_MIN  (  0)
+#define LM93_TEMP_OFFSET_MIN  (0)
 #define LM93_TEMP_OFFSET_MAX0 (150)
-#define LM93_TEMP_OFFSET_MAX1 ( 75)
+#define LM93_TEMP_OFFSET_MAX1 (75)
 
-/* This function is common to all 4-bit temperature offsets
-   returns 4 bits right justified
-   mode 0 => 1C/bit, mode !0 => 0.5C/bit */
+/*
+ * This function is common to all 4-bit temperature offsets
+ * returns 4 bits right justified
+ * mode 0 => 1C/bit, mode !0 => 0.5C/bit
+ */
 static u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode)
 {
 	int factor = mode ? 5 : 10;
@@ -466,9 +488,11 @@ static int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode)
 		return LM93_TEMP_OFFSET_FROM_REG(reg >> 4 & 0x0f, mode);
 }
 
-/* TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero))
-   REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero)
-   0 <= nr <= 3 */
+/*
+ * TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero))
+ * REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero)
+ * 0 <= nr <= 3
+ */
 static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode)
 {
 	u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode);
@@ -532,9 +556,12 @@ static u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, long hyst,
 	return reg;
 }
 
-/* PWM: 0-255 per sensors documentation
-   REG: 0-13 as mapped below... right justified */
-typedef enum { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ } pwm_freq_t;
+/*
+ * PWM: 0-255 per sensors documentation
+ * REG: 0-13 as mapped below... right justified
+ */
+enum pwm_freq { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ };
+
 static int lm93_pwm_map[2][16] = {
 	{
 		0x00, /*   0.00% */ 0x40, /*  25.00% */
@@ -558,13 +585,13 @@ static int lm93_pwm_map[2][16] = {
 	},
 };
 
-static int LM93_PWM_FROM_REG(u8 reg, pwm_freq_t freq)
+static int LM93_PWM_FROM_REG(u8 reg, enum pwm_freq freq)
 {
 	return lm93_pwm_map[freq][reg & 0x0f];
 }
 
 /* round up to nearest match */
-static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq)
+static u8 LM93_PWM_TO_REG(int pwm, enum pwm_freq freq)
 {
 	int i;
 	for (i = 0; i < 13; i++)
@@ -578,7 +605,7 @@ static u8 LM93_PWM_TO_REG(int pwm, pwm_freq_t freq)
 static int LM93_FAN_FROM_REG(u16 regs)
 {
 	const u16 count = le16_to_cpu(regs) >> 2;
-	return count==0 ? -1 : count==0x3fff ? 0: 1350000 / count;
+	return count == 0 ? -1 : count == 0x3fff ? 0 : 1350000 / count;
 }
 
 /*
@@ -600,8 +627,10 @@ static u16 LM93_FAN_TO_REG(long rpm)
 	return cpu_to_le16(regs);
 }
 
-/* PWM FREQ: HZ
-   REG: 0-7 as mapped below */
+/*
+ * PWM FREQ: HZ
+ * REG: 0-7 as mapped below
+ */
 static int lm93_pwm_freq_map[8] = {
 	22500, 96, 84, 72, 60, 48, 36, 12
 };
@@ -623,8 +652,10 @@ static u8 LM93_PWM_FREQ_TO_REG(int freq)
 	return (u8)i;
 }
 
-/* TIME: 1/100 seconds
- * REG: 0-7 as mapped below */
+/*
+ * TIME: 1/100 seconds
+ * REG: 0-7 as mapped below
+ */
 static int lm93_spinup_time_map[8] = {
 	0, 10, 25, 40, 70, 100, 200, 400,
 };
@@ -654,24 +685,30 @@ static int LM93_RAMP_FROM_REG(u8 reg)
 	return (reg & 0x0f) * 5;
 }
 
-/* RAMP: 1/100 seconds
-   REG: 50mS/bit 4-bits right justified */
+/*
+ * RAMP: 1/100 seconds
+ * REG: 50mS/bit 4-bits right justified
+ */
 static u8 LM93_RAMP_TO_REG(int ramp)
 {
 	ramp = SENSORS_LIMIT(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX);
 	return (u8)((ramp + 2) / 5);
 }
 
-/* PROCHOT: 0-255, 0 => 0%, 255 => > 96.6%
- * REG: (same) */
+/*
+ * PROCHOT: 0-255, 0 => 0%, 255 => > 96.6%
+ * REG: (same)
+ */
 static u8 LM93_PROCHOT_TO_REG(long prochot)
 {
 	prochot = SENSORS_LIMIT(prochot, 0, 255);
 	return (u8)prochot;
 }
 
-/* PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds)
- * REG: 0-9 as mapped below */
+/*
+ * PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds)
+ * REG: 0-9 as mapped below
+ */
 static int lm93_interval_map[10] = {
 	73, 146, 290, 580, 1170, 2330, 4660, 9320, 18600, 37200,
 };
@@ -693,22 +730,25 @@ static u8 LM93_INTERVAL_TO_REG(long interval)
 	return (u8)i;
 }
 
-/* GPIO: 0-255, GPIO0 is LSB
- * REG: inverted */
+/*
+ * GPIO: 0-255, GPIO0 is LSB
+ * REG: inverted
+ */
 static unsigned LM93_GPI_FROM_REG(u8 reg)
 {
 	return ~reg & 0xff;
 }
 
-/* alarm bitmask definitions
-   The LM93 has nearly 64 bits of error status... I've pared that down to
-   what I think is a useful subset in order to fit it into 32 bits.
-
-   Especially note that the #VRD_HOT alarms are missing because we provide
-   that information as values in another sysfs file.
-
-   If libsensors is extended to support 64 bit values, this could be revisited.
-*/
+/*
+ * alarm bitmask definitions
+ * The LM93 has nearly 64 bits of error status... I've pared that down to
+ * what I think is a useful subset in order to fit it into 32 bits.
+ *
+ * Especially note that the #VRD_HOT alarms are missing because we provide
+ * that information as values in another sysfs file.
+ *
+ * If libsensors is extended to support 64 bit values, this could be revisited.
+ */
 #define LM93_ALARM_IN1		0x00000001
 #define LM93_ALARM_IN2		0x00000002
 #define LM93_ALARM_IN3		0x00000004
@@ -772,11 +812,12 @@ static u8 lm93_read_byte(struct i2c_client *client, u8 reg)
 	int value, i;
 
 	/* retry in case of read errors */
-	for (i=1; i<=MAX_RETRIES; i++) {
-		if ((value = i2c_smbus_read_byte_data(client, reg)) >= 0) {
+	for (i = 1; i <= MAX_RETRIES; i++) {
+		value = i2c_smbus_read_byte_data(client, reg);
+		if (value >= 0) {
 			return value;
 		} else {
-			dev_warn(&client->dev,"lm93: read byte data failed, "
+			dev_warn(&client->dev, "lm93: read byte data failed, "
 				"address 0x%02x.\n", reg);
 			mdelay(i + 3);
 		}
@@ -784,7 +825,7 @@ static u8 lm93_read_byte(struct i2c_client *client, u8 reg)
 	}
 
 	/* <TODO> what to return in case of error? */
-	dev_err(&client->dev,"lm93: All read byte retries failed!!\n");
+	dev_err(&client->dev, "lm93: All read byte retries failed!!\n");
 	return 0;
 }
 
@@ -796,7 +837,7 @@ static int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value)
 	result = i2c_smbus_write_byte_data(client, reg, value);
 
 	if (result < 0)
-		dev_warn(&client->dev,"lm93: write byte data failed, "
+		dev_warn(&client->dev, "lm93: write byte data failed, "
 			 "0x%02x at address 0x%02x.\n", value, reg);
 
 	return result;
@@ -807,11 +848,12 @@ static u16 lm93_read_word(struct i2c_client *client, u8 reg)
 	int value, i;
 
 	/* retry in case of read errors */
-	for (i=1; i<=MAX_RETRIES; i++) {
-		if ((value = i2c_smbus_read_word_data(client, reg)) >= 0) {
+	for (i = 1; i <= MAX_RETRIES; i++) {
+		value = i2c_smbus_read_word_data(client, reg);
+		if (value >= 0) {
 			return value;
 		} else {
-			dev_warn(&client->dev,"lm93: read word data failed, "
+			dev_warn(&client->dev, "lm93: read word data failed, "
 				 "address 0x%02x.\n", reg);
 			mdelay(i + 3);
 		}
@@ -819,7 +861,7 @@ static u16 lm93_read_word(struct i2c_client *client, u8 reg)
 	}
 
 	/* <TODO> what to return in case of error? */
-	dev_err(&client->dev,"lm93: All read word retries failed!!\n");
+	dev_err(&client->dev, "lm93: All read word retries failed!!\n");
 	return 0;
 }
 
@@ -831,7 +873,7 @@ static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value)
 	result = i2c_smbus_write_word_data(client, reg, value);
 
 	if (result < 0)
-		dev_warn(&client->dev,"lm93: write word data failed, "
+		dev_warn(&client->dev, "lm93: write word data failed, "
 			 "0x%04x at address 0x%02x.\n", value, reg);
 
 	return result;
@@ -840,13 +882,13 @@ static int lm93_write_word(struct i2c_client *client, u8 reg, u16 value)
 static u8 lm93_block_buffer[I2C_SMBUS_BLOCK_MAX];
 
 /*
-	read block data into values, retry if not expected length
-	fbn => index to lm93_block_read_cmds table
-		(Fixed Block Number - section 14.5.2 of LM93 datasheet)
-*/
+ * read block data into values, retry if not expected length
+ * fbn => index to lm93_block_read_cmds table
+ * (Fixed Block Number - section 14.5.2 of LM93 datasheet)
+ */
 static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values)
 {
-	int i, result=0;
+	int i, result = 0;
 
 	for (i = 1; i <= MAX_RETRIES; i++) {
 		result = i2c_smbus_read_block_data(client,
@@ -855,7 +897,7 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values)
 		if (result == lm93_block_read_cmds[fbn].len) {
 			break;
 		} else {
-			dev_warn(&client->dev,"lm93: block read data failed, "
+			dev_warn(&client->dev, "lm93: block read data failed, "
 				 "command 0x%02x.\n",
 				 lm93_block_read_cmds[fbn].cmd);
 			mdelay(i + 3);
@@ -863,7 +905,8 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values)
 	}
 
 	if (result == lm93_block_read_cmds[fbn].len) {
-		memcpy(values,lm93_block_buffer,lm93_block_read_cmds[fbn].len);
+		memcpy(values, lm93_block_buffer,
+		       lm93_block_read_cmds[fbn].len);
 	} else {
 		/* <TODO> what to do in case of error? */
 	}
@@ -964,7 +1007,7 @@ static void lm93_update_client_common(struct lm93_data *data,
 static void lm93_update_client_full(struct lm93_data *data,
 				    struct i2c_client *client)
 {
-	dev_dbg(&client->dev,"starting device update (block data enabled)\n");
+	dev_dbg(&client->dev, "starting device update (block data enabled)\n");
 
 	/* in1 - in16: values & limits */
 	lm93_read_block(client, 3, (u8 *)(data->block3));
@@ -996,10 +1039,10 @@ static void lm93_update_client_full(struct lm93_data *data,
 static void lm93_update_client_min(struct lm93_data *data,
 				   struct i2c_client *client)
 {
-	int i,j;
+	int i, j;
 	u8 *ptr;
 
-	dev_dbg(&client->dev,"starting device update (block data disabled)\n");
+	dev_dbg(&client->dev, "starting device update (block data disabled)\n");
 
 	/* in1 - in16: values & limits */
 	for (i = 0; i < 16; i++) {
@@ -1037,7 +1080,7 @@ static void lm93_update_client_min(struct lm93_data *data,
 	for (i = 0; i < 2; i++) {
 		for (j = 0; j < 4; j++) {
 			data->block9[i][j] =
-				lm93_read_byte(client, LM93_REG_PWM_CTL(i,j));
+				lm93_read_byte(client, LM93_REG_PWM_CTL(i, j));
 		}
 	}
 
@@ -1097,14 +1140,13 @@ static ssize_t show_in_min(struct device *dev,
 	int vccp = nr - 6;
 	long rc, vid;
 
-	if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) {
+	if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) {
 		vid = LM93_VID_FROM_REG(data->vid[vccp]);
 		rc = LM93_IN_MIN_FROM_REG(data->vccp_limits[vccp], vid);
+	} else {
+		rc = LM93_IN_FROM_REG(nr, data->block7[nr].min);
 	}
-	else {
-		rc = LM93_IN_FROM_REG(nr, data->block7[nr].min); \
-	}
-	return sprintf(buf, "%ld\n", rc); \
+	return sprintf(buf, "%ld\n", rc);
 }
 
 static ssize_t store_in_min(struct device *dev, struct device_attribute *attr,
@@ -1113,20 +1155,24 @@ static ssize_t store_in_min(struct device *dev, struct device_attribute *attr,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	int vccp = nr - 6;
 	long vid;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) {
+	if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) {
 		vid = LM93_VID_FROM_REG(data->vid[vccp]);
 		data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0xf0) |
 				LM93_IN_REL_TO_REG(val, 0, vid);
 		lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp),
 				data->vccp_limits[vccp]);
-	}
-	else {
-		data->block7[nr].min = LM93_IN_TO_REG(nr,val);
+	} else {
+		data->block7[nr].min = LM93_IN_TO_REG(nr, val);
 		lm93_write_byte(client, LM93_REG_IN_MIN(nr),
 				data->block7[nr].min);
 	}
@@ -1175,14 +1221,13 @@ static ssize_t show_in_max(struct device *dev,
 	int vccp = nr - 6;
 	long rc, vid;
 
-	if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) {
+	if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) {
 		vid = LM93_VID_FROM_REG(data->vid[vccp]);
-		rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp],vid);
-	}
-	else {
-		rc = LM93_IN_FROM_REG(nr,data->block7[nr].max); \
+		rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp], vid);
+	} else {
+		rc = LM93_IN_FROM_REG(nr, data->block7[nr].max);
 	}
-	return sprintf(buf,"%ld\n",rc); \
+	return sprintf(buf, "%ld\n", rc);
 }
 
 static ssize_t store_in_max(struct device *dev, struct device_attribute *attr,
@@ -1191,20 +1236,24 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute *attr,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	int vccp = nr - 6;
 	long vid;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	if ((nr==6 || nr==7) && (vccp_limit_type[vccp])) {
+	if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) {
 		vid = LM93_VID_FROM_REG(data->vid[vccp]);
 		data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0x0f) |
 				LM93_IN_REL_TO_REG(val, 1, vid);
 		lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp),
 				data->vccp_limits[vccp]);
-	}
-	else {
-		data->block7[nr].max = LM93_IN_TO_REG(nr,val);
+	} else {
+		data->block7[nr].max = LM93_IN_TO_REG(nr, val);
 		lm93_write_byte(client, LM93_REG_IN_MAX(nr),
 				data->block7[nr].max);
 	}
@@ -1250,7 +1299,7 @@ static ssize_t show_temp(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block2[nr]));
+	return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->block2[nr]));
 }
 
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
@@ -1262,7 +1311,7 @@ static ssize_t show_temp_min(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].min));
+	return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->temp_lim[nr].min));
 }
 
 static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr,
@@ -1271,7 +1320,12 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_lim[nr].min = LM93_TEMP_TO_REG(val);
@@ -1292,7 +1346,7 @@ static ssize_t show_temp_max(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->temp_lim[nr].max));
+	return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->temp_lim[nr].max));
 }
 
 static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr,
@@ -1301,7 +1355,12 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_lim[nr].max = LM93_TEMP_TO_REG(val);
@@ -1322,7 +1381,7 @@ static ssize_t show_temp_auto_base(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->block10.base[nr]));
+	return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->block10.base[nr]));
 }
 
 static ssize_t store_temp_auto_base(struct device *dev,
@@ -1332,7 +1391,12 @@ static ssize_t store_temp_auto_base(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->block10.base[nr] = LM93_TEMP_TO_REG(val);
@@ -1349,11 +1413,11 @@ static SENSOR_DEVICE_ATTR(temp3_auto_base, S_IWUSR | S_IRUGO,
 			  show_temp_auto_base, store_temp_auto_base, 2);
 
 static ssize_t show_temp_auto_boost(struct device *dev,
-				    struct device_attribute *attr,char *buf)
+				    struct device_attribute *attr, char *buf)
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_TEMP_FROM_REG(data->boost[nr]));
+	return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->boost[nr]));
 }
 
 static ssize_t store_temp_auto_boost(struct device *dev,
@@ -1363,7 +1427,12 @@ static ssize_t store_temp_auto_boost(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->boost[nr] = LM93_TEMP_TO_REG(val);
@@ -1386,7 +1455,7 @@ static ssize_t show_temp_auto_boost_hyst(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
 	int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr);
-	return sprintf(buf,"%d\n",
+	return sprintf(buf, "%d\n",
 		       LM93_AUTO_BOOST_HYST_FROM_REGS(data, nr, mode));
 }
 
@@ -1397,7 +1466,12 @@ static ssize_t store_temp_auto_boost_hyst(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	/* force 0.5C/bit mode */
@@ -1429,9 +1503,9 @@ static ssize_t show_temp_auto_offset(struct device *dev,
 	int ofs = s_attr->nr;
 	struct lm93_data *data = lm93_update_device(dev);
 	int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr);
-	return sprintf(buf,"%d\n",
+	return sprintf(buf, "%d\n",
 	       LM93_TEMP_AUTO_OFFSET_FROM_REG(data->block10.offset[ofs],
-					      nr,mode));
+					      nr, mode));
 }
 
 static ssize_t store_temp_auto_offset(struct device *dev,
@@ -1443,7 +1517,12 @@ static ssize_t store_temp_auto_offset(struct device *dev,
 	int ofs = s_attr->nr;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	/* force 0.5C/bit mode */
@@ -1539,7 +1618,7 @@ static ssize_t show_temp_auto_pwm_min(struct device *dev,
 	struct lm93_data *data = lm93_update_device(dev);
 	reg = data->auto_pwm_min_hyst[nr/2] >> 4 & 0x0f;
 	ctl4 = data->block9[nr][LM93_PWM_CTL4];
-	return sprintf(buf,"%d\n",LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ?
+	return sprintf(buf, "%d\n", LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ?
 				LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ));
 }
 
@@ -1550,12 +1629,17 @@ static ssize_t store_temp_auto_pwm_min(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 reg, ctl4;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	reg = lm93_read_byte(client, LM93_REG_PWM_MIN_HYST(nr));
-	ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4));
+	ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4));
 	reg = (reg & 0x0f) |
 		LM93_PWM_TO_REG(val, (ctl4 & 0x07) ?
 				LM93_PWM_MAP_LO_FREQ :
@@ -1582,8 +1666,8 @@ static ssize_t show_temp_auto_offset_hyst(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
 	int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr);
-	return sprintf(buf,"%d\n",LM93_TEMP_OFFSET_FROM_REG(
-					data->auto_pwm_min_hyst[nr/2], mode));
+	return sprintf(buf, "%d\n", LM93_TEMP_OFFSET_FROM_REG(
+					data->auto_pwm_min_hyst[nr / 2], mode));
 }
 
 static ssize_t store_temp_auto_offset_hyst(struct device *dev,
@@ -1593,8 +1677,13 @@ static ssize_t store_temp_auto_offset_hyst(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	/* force 0.5C/bit mode */
@@ -1626,7 +1715,7 @@ static ssize_t show_fan_input(struct device *dev,
 	int nr = s_attr->index;
 	struct lm93_data *data = lm93_update_device(dev);
 
-	return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block5[nr]));
+	return sprintf(buf, "%d\n", LM93_FAN_FROM_REG(data->block5[nr]));
 }
 
 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
@@ -1640,7 +1729,7 @@ static ssize_t show_fan_min(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
 
-	return sprintf(buf,"%d\n",LM93_FAN_FROM_REG(data->block8[nr]));
+	return sprintf(buf, "%d\n", LM93_FAN_FROM_REG(data->block8[nr]));
 }
 
 static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
@@ -1649,11 +1738,16 @@ static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->block8[nr] = LM93_FAN_TO_REG(val);
-	lm93_write_word(client,LM93_REG_FAN_MIN(nr),data->block8[nr]);
+	lm93_write_word(client, LM93_REG_FAN_MIN(nr), data->block8[nr]);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1667,18 +1761,19 @@ static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO,
 			  show_fan_min, store_fan_min, 3);
 
-/* some tedious bit-twiddling here to deal with the register format:
-
-	data->sf_tach_to_pwm: (tach to pwm mapping bits)
-
-		bit |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0
-		     T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1
-
-	data->sfc2: (enable bits)
-
-		bit |  3  |  2  |  1  |  0
-		       T4    T3    T2    T1
-*/
+/*
+ * some tedious bit-twiddling here to deal with the register format:
+ *
+ *	data->sf_tach_to_pwm: (tach to pwm mapping bits)
+ *
+ *		bit |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0
+ *		     T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1
+ *
+ *	data->sfc2: (enable bits)
+ *
+ *		bit |  3  |  2  |  1  |  0
+ *		       T4    T3    T2    T1
+ */
 
 static ssize_t show_fan_smart_tach(struct device *dev,
 				struct device_attribute *attr, char *buf)
@@ -1694,11 +1789,13 @@ static ssize_t show_fan_smart_tach(struct device *dev,
 	/* if there's a mapping and it's enabled */
 	if (mapping && ((data->sfc2 >> nr) & 0x01))
 		rc = mapping;
-	return sprintf(buf,"%ld\n",rc);
+	return sprintf(buf, "%ld\n", rc);
 }
 
-/* helper function - must grab data->update_lock before calling
-   fan is 0-3, indicating fan1-fan4 */
+/*
+ * helper function - must grab data->update_lock before calling
+ * fan is 0-3, indicating fan1-fan4
+ */
 static void lm93_write_fan_smart_tach(struct i2c_client *client,
 	struct lm93_data *data, int fan, long value)
 {
@@ -1724,7 +1821,12 @@ static ssize_t store_fan_smart_tach(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	/* sanity test, ignore the write otherwise */
@@ -1732,7 +1834,7 @@ static ssize_t store_fan_smart_tach(struct device *dev,
 		/* can't enable if pwm freq is 22.5KHz */
 		if (val) {
 			u8 ctl4 = lm93_read_byte(client,
-				LM93_REG_PWM_CTL(val-1,LM93_PWM_CTL4));
+				LM93_REG_PWM_CTL(val - 1, LM93_PWM_CTL4));
 			if ((ctl4 & 0x07) == 0)
 				val = 0;
 		}
@@ -1766,7 +1868,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
 	else /* show present h/w value if manual pwm disabled */
 		rc = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ?
 			LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ);
-	return sprintf(buf,"%ld\n",rc);
+	return sprintf(buf, "%ld\n", rc);
 }
 
 static ssize_t store_pwm(struct device *dev, struct device_attribute *attr,
@@ -1775,19 +1877,24 @@ static ssize_t store_pwm(struct device *dev, struct device_attribute *attr,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ctl2, ctl4;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2));
-	ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4));
-	ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val,(ctl4 & 0x07) ?
+	ctl2 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2));
+	ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4));
+	ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ?
 			LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ) << 4;
 	/* save user commanded value */
 	data->pwm_override[nr] = LM93_PWM_FROM_REG(ctl2 >> 4,
 			(ctl4 & 0x07) ?  LM93_PWM_MAP_LO_FREQ :
 			LM93_PWM_MAP_HI_FREQ);
-	lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2);
+	lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2), ctl2);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1808,7 +1915,7 @@ static ssize_t show_pwm_enable(struct device *dev,
 		rc = ((ctl2 & 0xF0) == 0xF0) ? 0 : 1;
 	else
 		rc = 2;
-	return sprintf(buf,"%ld\n",rc);
+	return sprintf(buf, "%ld\n", rc);
 }
 
 static ssize_t store_pwm_enable(struct device *dev,
@@ -1818,26 +1925,33 @@ static ssize_t store_pwm_enable(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ctl2;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2));
+	ctl2 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2));
 
 	switch (val) {
 	case 0:
 		ctl2 |= 0xF1; /* enable manual override, set PWM to max */
 		break;
-	case 1: ctl2 |= 0x01; /* enable manual override */
+	case 1:
+		ctl2 |= 0x01; /* enable manual override */
 		break;
-	case 2: ctl2 &= ~0x01; /* disable manual override */
+	case 2:
+		ctl2 &= ~0x01; /* disable manual override */
 		break;
 	default:
 		mutex_unlock(&data->update_lock);
 		return -EINVAL;
 	}
 
-	lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2);
+	lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2), ctl2);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1855,12 +1969,14 @@ static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
 	u8 ctl4;
 
 	ctl4 = data->block9[nr][LM93_PWM_CTL4];
-	return sprintf(buf,"%d\n",LM93_PWM_FREQ_FROM_REG(ctl4));
+	return sprintf(buf, "%d\n", LM93_PWM_FREQ_FROM_REG(ctl4));
 }
 
-/* helper function - must grab data->update_lock before calling
-   pwm is 0-1, indicating pwm1-pwm2
-   this disables smart tach for all tach channels bound to the given pwm */
+/*
+ * helper function - must grab data->update_lock before calling
+ * pwm is 0-1, indicating pwm1-pwm2
+ * this disables smart tach for all tach channels bound to the given pwm
+ */
 static void lm93_disable_fan_smart_tach(struct i2c_client *client,
 	struct lm93_data *data, int pwm)
 {
@@ -1887,17 +2003,22 @@ static ssize_t store_pwm_freq(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ctl4;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4));
+	ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4));
 	ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(val);
 	data->block9[nr][LM93_PWM_CTL4] = ctl4;
 	/* ctl4 == 0 -> 22.5KHz -> disable smart tach */
 	if (!ctl4)
 		lm93_disable_fan_smart_tach(client, data, nr);
-	lm93_write_byte(client,	LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4), ctl4);
+	lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4), ctl4);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1912,7 +2033,7 @@ static ssize_t show_pwm_auto_channels(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",data->block9[nr][LM93_PWM_CTL1]);
+	return sprintf(buf, "%d\n", data->block9[nr][LM93_PWM_CTL1]);
 }
 
 static ssize_t store_pwm_auto_channels(struct device *dev,
@@ -1922,11 +2043,16 @@ static ssize_t store_pwm_auto_channels(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255);
-	lm93_write_byte(client,	LM93_REG_PWM_CTL(nr,LM93_PWM_CTL1),
+	lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL1),
 				data->block9[nr][LM93_PWM_CTL1]);
 	mutex_unlock(&data->update_lock);
 	return count;
@@ -1938,7 +2064,7 @@ static SENSOR_DEVICE_ATTR(pwm2_auto_channels, S_IWUSR | S_IRUGO,
 			  show_pwm_auto_channels, store_pwm_auto_channels, 1);
 
 static ssize_t show_pwm_auto_spinup_min(struct device *dev,
-				struct device_attribute *attr,char *buf)
+				struct device_attribute *attr, char *buf)
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
@@ -1946,7 +2072,7 @@ static ssize_t show_pwm_auto_spinup_min(struct device *dev,
 
 	ctl3 = data->block9[nr][LM93_PWM_CTL3];
 	ctl4 = data->block9[nr][LM93_PWM_CTL4];
-	return sprintf(buf,"%d\n",
+	return sprintf(buf, "%d\n",
 		       LM93_PWM_FROM_REG(ctl3 & 0x0f, (ctl4 & 0x07) ?
 			LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ));
 }
@@ -1958,17 +2084,22 @@ static ssize_t store_pwm_auto_spinup_min(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ctl3, ctl4;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3));
-	ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4));
-	ctl3 = (ctl3 & 0xf0) | 	LM93_PWM_TO_REG(val, (ctl4 & 0x07) ?
+	ctl3 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3));
+	ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4));
+	ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ?
 			LM93_PWM_MAP_LO_FREQ :
 			LM93_PWM_MAP_HI_FREQ);
 	data->block9[nr][LM93_PWM_CTL3] = ctl3;
-	lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3);
+	lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -1985,7 +2116,7 @@ static ssize_t show_pwm_auto_spinup_time(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_SPINUP_TIME_FROM_REG(
+	return sprintf(buf, "%d\n", LM93_SPINUP_TIME_FROM_REG(
 				data->block9[nr][LM93_PWM_CTL3]));
 }
 
@@ -1996,14 +2127,19 @@ static ssize_t store_pwm_auto_spinup_time(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ctl3;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3));
+	ctl3 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3));
 	ctl3 = (ctl3 & 0x1f) | (LM93_SPINUP_TIME_TO_REG(val) << 5 & 0xe0);
 	data->block9[nr][LM93_PWM_CTL3] = ctl3;
-	lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3);
+	lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3);
 	mutex_unlock(&data->update_lock);
 	return count;
 }
@@ -2019,7 +2155,7 @@ static ssize_t show_pwm_auto_prochot_ramp(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",
+	return sprintf(buf, "%d\n",
 		       LM93_RAMP_FROM_REG(data->pwm_ramp_ctl >> 4 & 0x0f));
 }
 
@@ -2029,8 +2165,13 @@ static ssize_t store_pwm_auto_prochot_ramp(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ramp;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL);
@@ -2048,7 +2189,7 @@ static ssize_t show_pwm_auto_vrdhot_ramp(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",
+	return sprintf(buf, "%d\n",
 		       LM93_RAMP_FROM_REG(data->pwm_ramp_ctl & 0x0f));
 }
 
@@ -2058,8 +2199,13 @@ static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 ramp;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL);
@@ -2078,7 +2224,7 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_VID_FROM_REG(data->vid[nr]));
+	return sprintf(buf, "%d\n", LM93_VID_FROM_REG(data->vid[nr]));
 }
 
 static SENSOR_DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL, 0);
@@ -2089,7 +2235,7 @@ static ssize_t show_prochot(struct device *dev, struct device_attribute *attr,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",data->block4[nr].cur);
+	return sprintf(buf, "%d\n", data->block4[nr].cur);
 }
 
 static SENSOR_DEVICE_ATTR(prochot1, S_IRUGO, show_prochot, NULL, 0);
@@ -2100,7 +2246,7 @@ static ssize_t show_prochot_avg(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",data->block4[nr].avg);
+	return sprintf(buf, "%d\n", data->block4[nr].avg);
 }
 
 static SENSOR_DEVICE_ATTR(prochot1_avg, S_IRUGO, show_prochot_avg, NULL, 0);
@@ -2111,7 +2257,7 @@ static ssize_t show_prochot_max(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",data->prochot_max[nr]);
+	return sprintf(buf, "%d\n", data->prochot_max[nr]);
 }
 
 static ssize_t store_prochot_max(struct device *dev,
@@ -2121,7 +2267,12 @@ static ssize_t store_prochot_max(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->prochot_max[nr] = LM93_PROCHOT_TO_REG(val);
@@ -2143,7 +2294,7 @@ static ssize_t show_prochot_override(struct device *dev,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",
+	return sprintf(buf, "%d\n",
 		(data->prochot_override & prochot_override_mask[nr]) ? 1 : 0);
 }
 
@@ -2154,7 +2305,12 @@ static ssize_t store_prochot_override(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	if (val)
@@ -2178,11 +2334,11 @@ static ssize_t show_prochot_interval(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
 	u8 tmp;
-	if (nr==1)
+	if (nr == 1)
 		tmp = (data->prochot_interval & 0xf0) >> 4;
 	else
 		tmp = data->prochot_interval & 0x0f;
-	return sprintf(buf,"%d\n",LM93_INTERVAL_FROM_REG(tmp));
+	return sprintf(buf, "%d\n", LM93_INTERVAL_FROM_REG(tmp));
 }
 
 static ssize_t store_prochot_interval(struct device *dev,
@@ -2192,12 +2348,17 @@ static ssize_t store_prochot_interval(struct device *dev,
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 tmp;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	tmp = lm93_read_byte(client, LM93_REG_PROCHOT_INTERVAL);
-	if (nr==1)
+	if (nr == 1)
 		tmp = (tmp & 0x0f) | (LM93_INTERVAL_TO_REG(val) << 4);
 	else
 		tmp = (tmp & 0xf0) | LM93_INTERVAL_TO_REG(val);
@@ -2217,7 +2378,7 @@ static ssize_t show_prochot_override_duty_cycle(struct device *dev,
 						char *buf)
 {
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",data->prochot_override & 0x0f);
+	return sprintf(buf, "%d\n", data->prochot_override & 0x0f);
 }
 
 static ssize_t store_prochot_override_duty_cycle(struct device *dev,
@@ -2226,7 +2387,12 @@ static ssize_t store_prochot_override_duty_cycle(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->prochot_override = (data->prochot_override & 0xf0) |
@@ -2245,7 +2411,7 @@ static ssize_t show_prochot_short(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",(data->config & 0x10) ? 1 : 0);
+	return sprintf(buf, "%d\n", (data->config & 0x10) ? 1 : 0);
 }
 
 static ssize_t store_prochot_short(struct device *dev,
@@ -2254,7 +2420,12 @@ static ssize_t store_prochot_short(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm93_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	if (val)
@@ -2274,8 +2445,8 @@ static ssize_t show_vrdhot(struct device *dev, struct device_attribute *attr,
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",
-		       data->block1.host_status_1 & (1 << (nr+4)) ? 1 : 0);
+	return sprintf(buf, "%d\n",
+		       data->block1.host_status_1 & (1 << (nr + 4)) ? 1 : 0);
 }
 
 static SENSOR_DEVICE_ATTR(vrdhot1, S_IRUGO, show_vrdhot, NULL, 0);
@@ -2285,7 +2456,7 @@ static ssize_t show_gpio(struct device *dev, struct device_attribute *attr,
 				char *buf)
 {
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_GPI_FROM_REG(data->gpi));
+	return sprintf(buf, "%d\n", LM93_GPI_FROM_REG(data->gpi));
 }
 
 static DEVICE_ATTR(gpio, S_IRUGO, show_gpio, NULL);
@@ -2294,7 +2465,7 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
 				char *buf)
 {
 	struct lm93_data *data = lm93_update_device(dev);
-	return sprintf(buf,"%d\n",LM93_ALARMS_FROM_REG(data->block1));
+	return sprintf(buf, "%d\n", LM93_ALARMS_FROM_REG(data->block1));
 }
 
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
@@ -2494,13 +2665,13 @@ static void lm93_init_client(struct i2c_client *client)
 	lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x01);
 
 	/* spin until ready */
-	for (i=0; i<20; i++) {
+	for (i = 0; i < 20; i++) {
 		msleep(10);
 		if ((lm93_read_byte(client, LM93_REG_CONFIG) & 0x80) == 0x80)
 			return;
 	}
 
-	dev_warn(&client->dev,"timed out waiting for sensor "
+	dev_warn(&client->dev, "timed out waiting for sensor "
 		 "chip to signal ready!\n");
 }
 
@@ -2540,7 +2711,7 @@ static int lm93_detect(struct i2c_client *client, struct i2c_board_info *info)
 	}
 
 	strlcpy(info->type, name, I2C_NAME_SIZE);
-	dev_dbg(&adapter->dev,"loading %s at %d,0x%02x\n",
+	dev_dbg(&adapter->dev, "loading %s at %d, 0x%02x\n",
 		client->name, i2c_adapter_id(client->adapter),
 		client->addr);
 
@@ -2593,7 +2764,7 @@ static int lm93_probe(struct i2c_client *client,
 
 	/* Register hwmon driver class */
 	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if ( !IS_ERR(data->hwmon_dev))
+	if (!IS_ERR(data->hwmon_dev))
 		return 0;
 
 	err = PTR_ERR(data->hwmon_dev);
@@ -2635,20 +2806,9 @@ static struct i2c_driver lm93_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init lm93_init(void)
-{
-	return i2c_add_driver(&lm93_driver);
-}
-
-static void __exit lm93_exit(void)
-{
-	i2c_del_driver(&lm93_driver);
-}
+module_i2c_driver(lm93_driver);
 
 MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, "
 		"Hans J. Koch <hjk@hansjkoch.de>");
 MODULE_DESCRIPTION("LM93 driver");
 MODULE_LICENSE("GPL");
-
-module_init(lm93_init);
-module_exit(lm93_exit);
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 70bca67..bd8cdb7 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -455,19 +455,8 @@ static struct i2c_driver lm95241_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_lm95241_init(void)
-{
-	return i2c_add_driver(&lm95241_driver);
-}
-
-static void __exit sensors_lm95241_exit(void)
-{
-	i2c_del_driver(&lm95241_driver);
-}
+module_i2c_driver(lm95241_driver);
 
 MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>");
 MODULE_DESCRIPTION("LM95241 sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm95241_init);
-module_exit(sensors_lm95241_exit);
diff --git a/drivers/hwmon/lm95245.c b/drivers/hwmon/lm95245.c
index 5e5fc1b..9a46c10 100644
--- a/drivers/hwmon/lm95245.c
+++ b/drivers/hwmon/lm95245.c
@@ -525,19 +525,8 @@ static struct i2c_driver lm95245_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_lm95245_init(void)
-{
-	return i2c_add_driver(&lm95245_driver);
-}
-
-static void __exit sensors_lm95245_exit(void)
-{
-	i2c_del_driver(&lm95245_driver);
-}
+module_i2c_driver(lm95245_driver);
 
 MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>");
 MODULE_DESCRIPTION("LM95245 sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_lm95245_init);
-module_exit(sensors_lm95245_exit);
diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c
index 4ac06b7..4d005b2 100644
--- a/drivers/hwmon/ltc4151.c
+++ b/drivers/hwmon/ltc4151.c
@@ -154,7 +154,8 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, \
 static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, \
 	ltc4151_show_value, NULL, LTC4151_SENSE_H);
 
-/* Finally, construct an array of pointers to members of the above objects,
+/*
+ * Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
  */
 static struct attribute *ltc4151_attributes[] = {
@@ -238,19 +239,8 @@ static struct i2c_driver ltc4151_driver = {
 	.id_table	= ltc4151_id,
 };
 
-static int __init ltc4151_init(void)
-{
-	return i2c_add_driver(&ltc4151_driver);
-}
-
-static void __exit ltc4151_exit(void)
-{
-	i2c_del_driver(&ltc4151_driver);
-}
+module_i2c_driver(ltc4151_driver);
 
 MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>");
 MODULE_DESCRIPTION("LTC4151 driver");
 MODULE_LICENSE("GPL");
-
-module_init(ltc4151_init);
-module_exit(ltc4151_exit);
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index c7e6d8e..429c5b2 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -91,8 +91,10 @@ static int ltc4215_get_voltage(struct device *dev, u8 reg)
 		voltage = regval * 605 / 10;
 		break;
 	case LTC4215_ADIN:
-		/* The ADIN input is divided by 12.5, and has 4.82 mV
-		 * per increment, so we have the additional multiply */
+		/*
+		 * The ADIN input is divided by 12.5, and has 4.82 mV
+		 * per increment, so we have the additional multiply
+		 */
 		voltage = regval * 482 * 125 / 1000;
 		break;
 	default:
@@ -109,7 +111,8 @@ static unsigned int ltc4215_get_current(struct device *dev)
 {
 	struct ltc4215_data *data = ltc4215_update_device(dev);
 
-	/* The strange looking conversions that follow are fixed-point
+	/*
+	 * The strange looking conversions that follow are fixed-point
 	 * math, since we cannot do floating point in the kernel.
 	 *
 	 * Step 1: convert sense register to microVolts
@@ -176,7 +179,8 @@ static ssize_t ltc4215_show_alarm(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
 }
 
-/* These macros are used below in constructing device attribute objects
+/*
+ * These macros are used below in constructing device attribute objects
  * for use with sysfs_create_group() to make a sysfs device file
  * for each register.
  */
@@ -215,7 +219,8 @@ LTC4215_ALARM(in1_min_alarm,	(1 << 1),	LTC4215_STATUS);
 LTC4215_VOLTAGE(in2_input,			LTC4215_SOURCE);
 LTC4215_ALARM(in2_min_alarm,	(1 << 3),	LTC4215_STATUS);
 
-/* Finally, construct an array of pointers to members of the above objects,
+/*
+ * Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
  */
 static struct attribute *ltc4215_attributes[] = {
@@ -309,19 +314,8 @@ static struct i2c_driver ltc4215_driver = {
 	.id_table	= ltc4215_id,
 };
 
-static int __init ltc4215_init(void)
-{
-	return i2c_add_driver(&ltc4215_driver);
-}
-
-static void __exit ltc4215_exit(void)
-{
-	i2c_del_driver(&ltc4215_driver);
-}
+module_i2c_driver(ltc4215_driver);
 
 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
 MODULE_DESCRIPTION("LTC4215 driver");
 MODULE_LICENSE("GPL");
-
-module_init(ltc4215_init);
-module_exit(ltc4215_exit);
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index 6593083..b99b45b 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -214,7 +214,8 @@ static unsigned int ltc4245_get_current(struct device *dev, u8 reg)
 	unsigned int voltage;
 	unsigned int curr;
 
-	/* The strange looking conversions that follow are fixed-point
+	/*
+	 * The strange looking conversions that follow are fixed-point
 	 * math, since we cannot do floating point in the kernel.
 	 *
 	 * Step 1: convert sense register to microVolts
@@ -317,7 +318,8 @@ static ssize_t ltc4245_show_gpio(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%u\n", val * 10);
 }
 
-/* These macros are used below in constructing device attribute objects
+/*
+ * These macros are used below in constructing device attribute objects
  * for use with sysfs_create_group() to make a sysfs device file
  * for each register.
  */
@@ -391,7 +393,8 @@ LTC4245_POWER(power2_input,			LTC4245_5VSENSE);
 LTC4245_POWER(power3_input,			LTC4245_3VSENSE);
 LTC4245_POWER(power4_input,			LTC4245_VEESENSE);
 
-/* Finally, construct an array of pointers to members of the above objects,
+/*
+ * Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
  */
 static struct attribute *ltc4245_std_attributes[] = {
@@ -578,19 +581,8 @@ static struct i2c_driver ltc4245_driver = {
 	.id_table	= ltc4245_id,
 };
 
-static int __init ltc4245_init(void)
-{
-	return i2c_add_driver(&ltc4245_driver);
-}
-
-static void __exit ltc4245_exit(void)
-{
-	i2c_del_driver(&ltc4245_driver);
-}
+module_i2c_driver(ltc4245_driver);
 
 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
 MODULE_DESCRIPTION("LTC4245 driver");
 MODULE_LICENSE("GPL");
-
-module_init(ltc4245_init);
-module_exit(ltc4245_exit);
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c
index ce52355..ab1bfbf 100644
--- a/drivers/hwmon/ltc4261.c
+++ b/drivers/hwmon/ltc4261.c
@@ -297,19 +297,8 @@ static struct i2c_driver ltc4261_driver = {
 	.id_table = ltc4261_id,
 };
 
-static int __init ltc4261_init(void)
-{
-	return i2c_add_driver(&ltc4261_driver);
-}
-
-static void __exit ltc4261_exit(void)
-{
-	i2c_del_driver(&ltc4261_driver);
-}
+module_i2c_driver(ltc4261_driver);
 
 MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
 MODULE_DESCRIPTION("LTC4261 driver");
 MODULE_LICENSE("GPL");
-
-module_init(ltc4261_init);
-module_exit(ltc4261_exit);
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index 482ca90..362a40e 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -106,7 +106,8 @@ static ssize_t show_adc(struct device *dev,
 	if (ret < 0)
 		return ret;
 
-	/* assume the reference voltage to be 2.048V, with an 8-bit sample,
+	/*
+	 * assume the reference voltage to be 2.048V, with an 8-bit sample,
 	 * the LSB weight is 8mV
 	 */
 	return sprintf(buf, "%d\n", ret * 8);
@@ -227,17 +228,7 @@ static struct spi_driver max1111_driver = {
 	.remove		= __devexit_p(max1111_remove),
 };
 
-static int __init max1111_init(void)
-{
-	return spi_register_driver(&max1111_driver);
-}
-module_init(max1111_init);
-
-static void __exit max1111_exit(void)
-{
-	spi_unregister_driver(&max1111_driver);
-}
-module_exit(max1111_exit);
+module_spi_driver(max1111_driver);
 
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
 MODULE_DESCRIPTION("MAX1111 ADC Driver");
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index f8e323a..51edae9 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -699,19 +699,8 @@ static struct i2c_driver max16065_driver = {
 	.id_table = max16065_id,
 };
 
-static int __init max16065_init(void)
-{
-	return i2c_add_driver(&max16065_driver);
-}
-
-static void __exit max16065_exit(void)
-{
-	i2c_del_driver(&max16065_driver);
-}
+module_i2c_driver(max16065_driver);
 
 MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
 MODULE_DESCRIPTION("MAX16065 driver");
 MODULE_LICENSE("GPL");
-
-module_init(max16065_init);
-module_exit(max16065_exit);
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 022ded0..ecac04a 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -125,7 +125,7 @@ struct max1619_data {
 	u8 temp_input2, temp_low2, temp_high2; /* remote */
 	u8 temp_crit2;
 	u8 temp_hyst2;
-	u8 alarms; 
+	u8 alarms;
 };
 
 /*
@@ -133,7 +133,8 @@ struct max1619_data {
  */
 
 #define show_temp(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, \
+			    char *buf) \
 { \
 	struct max1619_data *data = max1619_update_device(dev); \
 	return sprintf(buf, "%d\n", temp_from_reg(data->value)); \
@@ -146,13 +147,17 @@ show_temp(temp_crit2);
 show_temp(temp_hyst2);
 
 #define set_temp2(value, reg) \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, \
+			   const char *buf, \
 	size_t count) \
 { \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct max1619_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
+	long val; \
+	int err = kstrtol(buf, 10, &val); \
+	if (err) \
+		return err; \
+\
 	mutex_lock(&data->update_lock); \
 	data->value = temp_to_reg(val); \
 	i2c_smbus_write_byte_data(client, reg, data->value); \
@@ -165,7 +170,8 @@ set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH);
 set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT);
 set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST);
 
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+			   char *buf)
 {
 	struct max1619_data *data = max1619_update_device(dev);
 	return sprintf(buf, "%d\n", data->alarms);
@@ -275,7 +281,8 @@ static int max1619_probe(struct i2c_client *new_client,
 	max1619_init_client(new_client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&new_client->dev.kobj, &max1619_group)))
+	err = sysfs_create_group(&new_client->dev.kobj, &max1619_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
@@ -353,20 +360,9 @@ static struct max1619_data *max1619_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_max1619_init(void)
-{
-	return i2c_add_driver(&max1619_driver);
-}
-
-static void __exit sensors_max1619_exit(void)
-{
-	i2c_del_driver(&max1619_driver);
-}
+module_i2c_driver(max1619_driver);
 
 MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and "
 	"Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("MAX1619 sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_max1619_init);
-module_exit(sensors_max1619_exit);
diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c
index 88953f9..335b183 100644
--- a/drivers/hwmon/max1668.c
+++ b/drivers/hwmon/max1668.c
@@ -1,23 +1,23 @@
 /*
-    Copyright (c) 2011 David George <david.george@ska.ac.za>
-
-    based on adm1021.c
-    some credit to Christoph Scheurer, but largely a rewrite
-
-    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.
-*/
+ * Copyright (c) 2011 David George <david.george@ska.ac.za>
+ *
+ * based on adm1021.c
+ * some credit to Christoph Scheurer, but largely a rewrite
+ *
+ * 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>
@@ -484,19 +484,8 @@ static struct i2c_driver max1668_driver = {
 	.address_list = max1668_addr_list,
 };
 
-static int __init sensors_max1668_init(void)
-{
-	return i2c_add_driver(&max1668_driver);
-}
-
-static void __exit sensors_max1668_exit(void)
-{
-	i2c_del_driver(&max1668_driver);
-}
+module_i2c_driver(max1668_driver);
 
 MODULE_AUTHOR("David George <david.george@ska.ac.za>");
 MODULE_DESCRIPTION("MAX1668 remote temperature sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_max1668_init)
-module_exit(sensors_max1668_exit)
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c
index e10a092..d203eb1 100644
--- a/drivers/hwmon/max6639.c
+++ b/drivers/hwmon/max6639.c
@@ -635,19 +635,8 @@ static struct i2c_driver max6639_driver = {
 	.address_list = normal_i2c,
 };
 
-static int __init max6639_init(void)
-{
-	return i2c_add_driver(&max6639_driver);
-}
-
-static void __exit max6639_exit(void)
-{
-	i2c_del_driver(&max6639_driver);
-}
+module_i2c_driver(max6639_driver);
 
 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
 MODULE_DESCRIPTION("max6639 driver");
 MODULE_LICENSE("GPL");
-
-module_init(max6639_init);
-module_exit(max6639_exit);
diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c
index 209e8a5..4298909 100644
--- a/drivers/hwmon/max6642.c
+++ b/drivers/hwmon/max6642.c
@@ -352,19 +352,8 @@ static struct i2c_driver max6642_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init max6642_init(void)
-{
-	return i2c_add_driver(&max6642_driver);
-}
-
-static void __exit max6642_exit(void)
-{
-	i2c_del_driver(&max6642_driver);
-}
+module_i2c_driver(max6642_driver);
 
 MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>");
 MODULE_DESCRIPTION("MAX6642 sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(max6642_init);
-module_exit(max6642_exit);
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index 2fc034a..33a8a7f 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -135,8 +135,7 @@ static struct i2c_driver max6650_driver = {
  * Client data (each client gets its own)
  */
 
-struct max6650_data
-{
+struct max6650_data {
 	struct device *hwmon_dev;
 	struct mutex update_lock;
 	int nr_fans;
@@ -160,13 +159,13 @@ static ssize_t get_fan(struct device *dev, struct device_attribute *devattr,
 	int rpm;
 
 	/*
-	* Calculation details:
-	*
-	* Each tachometer counts over an interval given by the "count"
-	* register (0.25, 0.5, 1 or 2 seconds). This module assumes
-	* that the fans produce two pulses per revolution (this seems
-	* to be the most common).
-	*/
+	 * Calculation details:
+	 *
+	 * Each tachometer counts over an interval given by the "count"
+	 * register (0.25, 0.5, 1 or 2 seconds). This module assumes
+	 * that the fans produce two pulses per revolution (this seems
+	 * to be the most common).
+	 */
 
 	rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count));
 	return sprintf(buf, "%d\n", rpm);
@@ -220,12 +219,12 @@ static ssize_t get_target(struct device *dev, struct device_attribute *devattr,
 	int kscale, ktach, rpm;
 
 	/*
-	* Use the datasheet equation:
-	*
-	*    FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)]
-	*
-	* then multiply by 60 to give rpm.
-	*/
+	 * Use the datasheet equation:
+	 *
+	 *    FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)]
+	 *
+	 * then multiply by 60 to give rpm.
+	 */
 
 	kscale = DIV_FROM_REG(data->config);
 	ktach = data->speed;
@@ -238,17 +237,22 @@ static ssize_t set_target(struct device *dev, struct device_attribute *devattr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct max6650_data *data = i2c_get_clientdata(client);
-	int rpm = simple_strtoul(buf, NULL, 10);
 	int kscale, ktach;
+	unsigned long rpm;
+	int err;
+
+	err = kstrtoul(buf, 10, &rpm);
+	if (err)
+		return err;
 
 	rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX);
 
 	/*
-	* Divide the required speed by 60 to get from rpm to rps, then
-	* use the datasheet equation:
-	*
-	*     KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1
-	*/
+	 * Divide the required speed by 60 to get from rpm to rps, then
+	 * use the datasheet equation:
+	 *
+	 *     KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1
+	 */
 
 	mutex_lock(&data->update_lock);
 
@@ -282,8 +286,10 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr,
 	int pwm;
 	struct max6650_data *data = max6650_update_device(dev);
 
-	/* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans.
-	   Lower DAC values mean higher speeds. */
+	/*
+	 * Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans.
+	 * Lower DAC values mean higher speeds.
+	 */
 	if (data->config & MAX6650_CFG_V12)
 		pwm = 255 - (255 * (int)data->dac)/180;
 	else
@@ -300,7 +306,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct max6650_data *data = i2c_get_clientdata(client);
-	int pwm = simple_strtoul(buf, NULL, 10);
+	unsigned long pwm;
+	int err;
+
+	err = kstrtoul(buf, 10, &pwm);
+	if (err)
+		return err;
 
 	pwm = SENSORS_LIMIT(pwm, 0, 255);
 
@@ -341,14 +352,16 @@ static ssize_t set_enable(struct device *dev, struct device_attribute *devattr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct max6650_data *data = i2c_get_clientdata(client);
-	int mode = simple_strtoul(buf, NULL, 10);
 	int max6650_modes[3] = {0, 3, 2};
+	unsigned long mode;
+	int err;
 
-	if ((mode < 0)||(mode > 2)) {
-		dev_err(&client->dev,
-			"illegal value for pwm1_enable (%d)\n", mode);
+	err = kstrtoul(buf, 10, &mode);
+	if (err)
+		return err;
+
+	if (mode > 2)
 		return -EINVAL;
-	}
 
 	mutex_lock(&data->update_lock);
 
@@ -389,7 +402,12 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct max6650_data *data = i2c_get_clientdata(client);
-	int div = simple_strtoul(buf, NULL, 10);
+	unsigned long div;
+	int err;
+
+	err = kstrtoul(buf, 10, &div);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (div) {
@@ -407,8 +425,6 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
 		break;
 	default:
 		mutex_unlock(&data->update_lock);
-		dev_err(&client->dev,
-			"illegal value for fan divider (%d)\n", div);
 		return -EINVAL;
 	}
 
@@ -529,7 +545,8 @@ static int max6650_probe(struct i2c_client *client,
 	struct max6650_data *data;
 	int err;
 
-	if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL);
+	if (!data) {
 		dev_err(&client->dev, "out of memory.\n");
 		return -ENOMEM;
 	}
@@ -596,55 +613,54 @@ static int max6650_init_client(struct i2c_client *client)
 	}
 
 	switch (fan_voltage) {
-		case 0:
-			break;
-		case 5:
-			config &= ~MAX6650_CFG_V12;
-			break;
-		case 12:
-			config |= MAX6650_CFG_V12;
-			break;
-		default:
-			dev_err(&client->dev,
-				"illegal value for fan_voltage (%d)\n",
-				fan_voltage);
+	case 0:
+		break;
+	case 5:
+		config &= ~MAX6650_CFG_V12;
+		break;
+	case 12:
+		config |= MAX6650_CFG_V12;
+		break;
+	default:
+		dev_err(&client->dev, "illegal value for fan_voltage (%d)\n",
+			fan_voltage);
 	}
 
 	dev_info(&client->dev, "Fan voltage is set to %dV.\n",
 		 (config & MAX6650_CFG_V12) ? 12 : 5);
 
 	switch (prescaler) {
-		case 0:
-			break;
-		case 1:
-			config &= ~MAX6650_CFG_PRESCALER_MASK;
-			break;
-		case 2:
-			config = (config & ~MAX6650_CFG_PRESCALER_MASK)
-				 | MAX6650_CFG_PRESCALER_2;
-			break;
-		case  4:
-			config = (config & ~MAX6650_CFG_PRESCALER_MASK)
-				 | MAX6650_CFG_PRESCALER_4;
-			break;
-		case  8:
-			config = (config & ~MAX6650_CFG_PRESCALER_MASK)
-				 | MAX6650_CFG_PRESCALER_8;
-			break;
-		case 16:
-			config = (config & ~MAX6650_CFG_PRESCALER_MASK)
-				 | MAX6650_CFG_PRESCALER_16;
-			break;
-		default:
-			dev_err(&client->dev,
-				"illegal value for prescaler (%d)\n",
-				prescaler);
+	case 0:
+		break;
+	case 1:
+		config &= ~MAX6650_CFG_PRESCALER_MASK;
+		break;
+	case 2:
+		config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+			 | MAX6650_CFG_PRESCALER_2;
+		break;
+	case  4:
+		config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+			 | MAX6650_CFG_PRESCALER_4;
+		break;
+	case  8:
+		config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+			 | MAX6650_CFG_PRESCALER_8;
+		break;
+	case 16:
+		config = (config & ~MAX6650_CFG_PRESCALER_MASK)
+			 | MAX6650_CFG_PRESCALER_16;
+		break;
+	default:
+		dev_err(&client->dev, "illegal value for prescaler (%d)\n",
+			prescaler);
 	}
 
 	dev_info(&client->dev, "Prescaler is set to %d.\n",
 		 1 << (config & MAX6650_CFG_PRESCALER_MASK));
 
-	/* If mode is set to "full off", we change it to "open loop" and
+	/*
+	 * If mode is set to "full off", we change it to "open loop" and
 	 * set DAC to 255, which has the same effect. We do this because
 	 * there's no "full off" mode defined in hwmon specifcations.
 	 */
@@ -698,9 +714,11 @@ static struct max6650_data *max6650_update_device(struct device *dev)
 							MAX6650_REG_COUNT);
 		data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
 
-		/* Alarms are cleared on read in case the condition that
+		/*
+		 * Alarms are cleared on read in case the condition that
 		 * caused the alarm is removed. Keep the value latched here
-		 * for providing the register through different alarm files. */
+		 * for providing the register through different alarm files.
+		 */
 		data->alarm |= i2c_smbus_read_byte_data(client,
 							MAX6650_REG_ALARM);
 
@@ -713,19 +731,8 @@ static struct max6650_data *max6650_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_max6650_init(void)
-{
-	return i2c_add_driver(&max6650_driver);
-}
-
-static void __exit sensors_max6650_exit(void)
-{
-	i2c_del_driver(&max6650_driver);
-}
+module_i2c_driver(max6650_driver);
 
 MODULE_AUTHOR("Hans J. Koch");
 MODULE_DESCRIPTION("MAX6650 sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_max6650_init);
-module_exit(sensors_max6650_exit);
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
index ef65ab5..ce86c5e 100644
--- a/drivers/hwmon/mc13783-adc.c
+++ b/drivers/hwmon/mc13783-adc.c
@@ -1,5 +1,5 @@
 /*
- * Driver for the Freescale Semiconductor MC13783 adc.
+ * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs.
  *
  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright (C) 2009 Sascha Hauer, Pengutronix
@@ -18,7 +18,7 @@
  * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <linux/mfd/mc13783.h>
+#include <linux/mfd/mc13xxx.h>
 #include <linux/platform_device.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/kernel.h>
@@ -28,24 +28,30 @@
 #include <linux/init.h>
 #include <linux/err.h>
 
-#define MC13783_ADC_NAME	"mc13783-adc"
+#define DRIVER_NAME	"mc13783-adc"
+
+/* platform device id driver data */
+#define MC13783_ADC_16CHANS	1
+#define MC13783_ADC_BPDIV2	2
 
 struct mc13783_adc_priv {
 	struct mc13xxx *mc13xxx;
 	struct device *hwmon_dev;
+	char name[10];
 };
 
 static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
 			      *devattr, char *buf)
 {
-	return sprintf(buf, "mc13783_adc\n");
+	struct mc13783_adc_priv *priv = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", priv->name);
 }
 
 static int mc13783_adc_read(struct device *dev,
 		struct device_attribute *devattr, unsigned int *val)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct mc13783_adc_priv *priv = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	unsigned int channel = attr->index;
 	unsigned int sample[4];
@@ -53,7 +59,7 @@ static int mc13783_adc_read(struct device *dev,
 
 	ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
 			MC13XXX_ADC_MODE_MULT_CHAN,
-			channel, sample);
+			channel, 0, 0, sample);
 	if (ret)
 		return ret;
 
@@ -68,16 +74,21 @@ static ssize_t mc13783_adc_read_bp(struct device *dev,
 		struct device_attribute *devattr, char *buf)
 {
 	unsigned val;
+	struct platform_device *pdev = to_platform_device(dev);
+	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
 	int ret = mc13783_adc_read(dev, devattr, &val);
 
 	if (ret)
 		return ret;
 
-	/*
-	 * BP (channel 2) reports with offset 2.4V to the actual value to fit
-	 * the input range of the ADC.  unit = 2.25mV = 9/4 mV.
-	 */
-	val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400;
+	if (driver_data & MC13783_ADC_BPDIV2)
+		val = DIV_ROUND_CLOSEST(val * 9, 2);
+	else
+		/*
+		 * BP (channel 2) reports with offset 2.4V to the actual value
+		 * to fit the input range of the ADC.  unit = 2.25mV = 9/4 mV.
+		 */
+		val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400;
 
 	return sprintf(buf, "%u\n", val);
 }
@@ -114,12 +125,21 @@ static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, mc13783_adc_read_gp, NULL, 13);
 static SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, mc13783_adc_read_gp, NULL, 14);
 static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, mc13783_adc_read_gp, NULL, 15);
 
-static struct attribute *mc13783_attr[] = {
+static struct attribute *mc13783_attr_base[] = {
 	&dev_attr_name.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
 	&sensor_dev_attr_in5_input.dev_attr.attr,
 	&sensor_dev_attr_in6_input.dev_attr.attr,
 	&sensor_dev_attr_in7_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group mc13783_group_base = {
+	.attrs = mc13783_attr_base,
+};
+
+/* these are only used if MC13783_ADC_16CHANS is provided in driver data */
+static struct attribute *mc13783_attr_16chans[] = {
 	&sensor_dev_attr_in8_input.dev_attr.attr,
 	&sensor_dev_attr_in9_input.dev_attr.attr,
 	&sensor_dev_attr_in10_input.dev_attr.attr,
@@ -127,8 +147,8 @@ static struct attribute *mc13783_attr[] = {
 	NULL
 };
 
-static const struct attribute_group mc13783_group = {
-	.attrs = mc13783_attr,
+static const struct attribute_group mc13783_group_16chans = {
+	.attrs = mc13783_attr_16chans,
 };
 
 /* last four channels may be occupied by the touchscreen */
@@ -156,24 +176,37 @@ static int __init mc13783_adc_probe(struct platform_device *pdev)
 {
 	struct mc13783_adc_priv *priv;
 	int ret;
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	char *dash;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
+	snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name);
+	dash = strchr(priv->name, '-');
+	if (dash)
+		*dash = '\0';
 
 	platform_set_drvdata(pdev, priv);
 
 	/* Register sysfs hooks */
-	ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group);
+	ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base);
 	if (ret)
-		goto out_err_create1;
+		goto out_err_create_base;
+
+	if (id->driver_data & MC13783_ADC_16CHANS) {
+		ret = sysfs_create_group(&pdev->dev.kobj,
+				&mc13783_group_16chans);
+		if (ret)
+			goto out_err_create_16chans;
+	}
 
 	if (!mc13783_adc_use_touchscreen(pdev)) {
 		ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts);
 		if (ret)
-			goto out_err_create2;
+			goto out_err_create_ts;
 	}
 
 	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
@@ -184,17 +217,20 @@ static int __init mc13783_adc_probe(struct platform_device *pdev)
 		goto out_err_register;
 	}
 
-
 	return 0;
 
 out_err_register:
 
 	if (!mc13783_adc_use_touchscreen(pdev))
 		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
-out_err_create2:
+out_err_create_ts:
 
-	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group);
-out_err_create1:
+	if (id->driver_data & MC13783_ADC_16CHANS)
+		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans);
+out_err_create_16chans:
+
+	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base);
+out_err_create_base:
 
 	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
@@ -205,13 +241,17 @@ out_err_create1:
 static int __devexit mc13783_adc_remove(struct platform_device *pdev)
 {
 	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data;
 
 	hwmon_device_unregister(priv->hwmon_dev);
 
 	if (!mc13783_adc_use_touchscreen(pdev))
 		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts);
 
-	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group);
+	if (driver_data & MC13783_ADC_16CHANS)
+		sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans);
+
+	sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base);
 
 	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
@@ -219,12 +259,26 @@ static int __devexit mc13783_adc_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct platform_device_id mc13783_adc_idtable[] = {
+	{
+		.name = "mc13783-adc",
+		.driver_data = MC13783_ADC_16CHANS,
+	}, {
+		.name = "mc13892-adc",
+		.driver_data = MC13783_ADC_BPDIV2,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(platform, mc13783_adc_idtable);
+
 static struct platform_driver mc13783_adc_driver = {
-	.remove 	= __devexit_p(mc13783_adc_remove),
+	.remove		= __devexit_p(mc13783_adc_remove),
 	.driver		= {
 		.owner	= THIS_MODULE,
-		.name	= MC13783_ADC_NAME,
+		.name	= DRIVER_NAME,
 	},
+	.id_table	= mc13783_adc_idtable,
 };
 
 static int __init mc13783_adc_init(void)
@@ -243,4 +297,3 @@ module_exit(mc13783_adc_exit);
 MODULE_DESCRIPTION("MC13783 ADC driver");
 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" MC13783_ADC_NAME);
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 3d99b88..79ba48c 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -56,11 +56,11 @@ static u8 confreg[4];
 static int init = 1;
 module_param(init, int, 0);
 MODULE_PARM_DESC(init,
- "Chip initialization level:\n"
- " 0: None\n"
- "*1: Forcibly enable internal voltage and temperature channels, except in9\n"
- " 2: Forcibly enable all voltage and temperature channels, except in9\n"
- " 3: Forcibly enable all voltage and temperature channels, including in9");
+"Chip initialization level:\n"
+" 0: None\n"
+"*1: Forcibly enable internal voltage and temperature channels, except in9\n"
+" 2: Forcibly enable all voltage and temperature channels, except in9\n"
+" 3: Forcibly enable all voltage and temperature channels, including in9");
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
@@ -88,19 +88,19 @@ static const u8 logdev[LDNI_MAX] = { FSCM, VLM, TMS };
 static inline void superio_outb(int sioaddr, int reg, int val)
 {
 	outb(reg, sioaddr);
-	outb(val, sioaddr+1);
+	outb(val, sioaddr + 1);
 }
 
 static inline int superio_inb(int sioaddr, int reg)
 {
 	outb(reg, sioaddr);
-	return inb(sioaddr+1);
+	return inb(sioaddr + 1);
 }
 
 static inline void superio_exit(int sioaddr)
 {
 	outb(0x02, sioaddr);
-	outb(0x02, sioaddr+1);
+	outb(0x02, sioaddr + 1);
 }
 
 /*
@@ -122,18 +122,18 @@ static inline void superio_exit(int sioaddr)
 #define PC87360_REG_FAN(nr)		(0x07 + 3 * (nr))
 #define PC87360_REG_FAN_STATUS(nr)	(0x08 + 3 * (nr))
 
-#define FAN_FROM_REG(val,div)		((val) == 0 ? 0: \
-					 480000 / ((val)*(div)))
-#define FAN_TO_REG(val,div)		((val) <= 100 ? 0 : \
-					 480000 / ((val)*(div)))
-#define FAN_DIV_FROM_REG(val)		(1 << ((val >> 5) & 0x03))
+#define FAN_FROM_REG(val, div)		((val) == 0 ? 0 : \
+					 480000 / ((val) * (div)))
+#define FAN_TO_REG(val, div)		((val) <= 100 ? 0 : \
+					 480000 / ((val) * (div)))
+#define FAN_DIV_FROM_REG(val)		(1 << (((val) >> 5) & 0x03))
 #define FAN_STATUS_FROM_REG(val)	((val) & 0x07)
 
-#define FAN_CONFIG_MONITOR(val,nr)	(((val) >> (2 + nr * 3)) & 1)
-#define FAN_CONFIG_CONTROL(val,nr)	(((val) >> (3 + nr * 3)) & 1)
-#define FAN_CONFIG_INVERT(val,nr)	(((val) >> (4 + nr * 3)) & 1)
+#define FAN_CONFIG_MONITOR(val, nr)	(((val) >> (2 + (nr) * 3)) & 1)
+#define FAN_CONFIG_CONTROL(val, nr)	(((val) >> (3 + (nr) * 3)) & 1)
+#define FAN_CONFIG_INVERT(val, nr)	(((val) >> (4 + (nr) * 3)) & 1)
 
-#define PWM_FROM_REG(val,inv)		((inv) ? 255 - (val) : (val))
+#define PWM_FROM_REG(val, inv)		((inv) ? 255 - (val) : (val))
 static inline u8 PWM_TO_REG(int val, int inv)
 {
 	if (inv)
@@ -159,10 +159,10 @@ static inline u8 PWM_TO_REG(int val, int inv)
 #define PC87365_REG_IN_ALARMS2		0x01
 #define PC87365_REG_VID			0x06
 
-#define IN_FROM_REG(val,ref)		(((val) * (ref) + 128) / 256)
-#define IN_TO_REG(val,ref)		((val) < 0 ? 0 : \
-					 (val)*256 >= (ref)*255 ? 255: \
-					 ((val) * 256 + (ref)/2) / (ref))
+#define IN_FROM_REG(val, ref)		(((val) * (ref) + 128) / 256)
+#define IN_TO_REG(val, ref)		((val) < 0 ? 0 : \
+					 (val) * 256 >= (ref) * 255 ? 255 : \
+					 ((val) * 256 + (ref) / 2) / (ref))
 
 /*
  * Temperature registers and conversions
@@ -255,43 +255,54 @@ static struct platform_driver pc87360_driver = {
  * Sysfs stuff
  */
 
-static ssize_t show_fan_input(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_fan_input(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[attr->index],
 		       FAN_DIV_FROM_REG(data->fan_status[attr->index])));
 }
-static ssize_t show_fan_min(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_fan_min(struct device *dev,
+			    struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[attr->index],
 		       FAN_DIV_FROM_REG(data->fan_status[attr->index])));
 }
-static ssize_t show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_fan_div(struct device *dev,
+			    struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n",
 		       FAN_DIV_FROM_REG(data->fan_status[attr->index]));
 }
-static ssize_t show_fan_status(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_fan_status(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n",
 		       FAN_STATUS_FROM_REG(data->fan_status[attr->index]));
 }
-static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr, const char *buf,
+static ssize_t set_fan_min(struct device *dev,
+			   struct device_attribute *devattr, const char *buf,
 	size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long fan_min = simple_strtol(buf, NULL, 10);
+	long fan_min;
+	int err;
+
+	err = kstrtol(buf, 10, &fan_min);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index]));
+	fan_min = FAN_TO_REG(fan_min,
+			     FAN_DIV_FROM_REG(data->fan_status[attr->index]));
 
 	/* If it wouldn't fit, change clock divisor */
 	while (fan_min > 255
@@ -301,11 +312,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr,
 		data->fan_status[attr->index] += 0x20;
 	}
 	data->fan_min[attr->index] = fan_min > 255 ? 255 : fan_min;
-	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(attr->index),
+	pc87360_write_value(data, LD_FAN, NO_BANK,
+			    PC87360_REG_FAN_MIN(attr->index),
 			    data->fan_min[attr->index]);
 
 	/* Write new divider, preserve alarm bits */
-	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index),
+	pc87360_write_value(data, LD_FAN, NO_BANK,
+			    PC87360_REG_FAN_STATUS(attr->index),
 			    data->fan_status[attr->index] & 0xF9);
 	mutex_unlock(&data->update_lock);
 
@@ -333,13 +346,16 @@ static struct sensor_device_attribute fan_min[] = {
 	SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2),
 };
 
-#define FAN_UNIT_ATTRS(X)	\
-	&fan_input[X].dev_attr.attr,	\
+#define FAN_UNIT_ATTRS(X)		\
+{	&fan_input[X].dev_attr.attr,	\
 	&fan_status[X].dev_attr.attr,	\
 	&fan_div[X].dev_attr.attr,	\
-	&fan_min[X].dev_attr.attr
+	&fan_min[X].dev_attr.attr,	\
+	NULL				\
+}
 
-static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
+			char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
@@ -348,12 +364,17 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, ch
 				    FAN_CONFIG_INVERT(data->fan_conf,
 						      attr->index)));
 }
-static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
+		       const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm[attr->index] = PWM_TO_REG(val,
@@ -370,52 +391,60 @@ static struct sensor_device_attribute pwm[] = {
 	SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2),
 };
 
-static struct attribute * pc8736x_fan_attr_array[] = {
+static struct attribute *pc8736x_fan_attr[][5] = {
 	FAN_UNIT_ATTRS(0),
 	FAN_UNIT_ATTRS(1),
-	FAN_UNIT_ATTRS(2),
-	&pwm[0].dev_attr.attr,
-	&pwm[1].dev_attr.attr,
-	&pwm[2].dev_attr.attr,
-	NULL
+	FAN_UNIT_ATTRS(2)
 };
-static const struct attribute_group pc8736x_fan_group = {
-	.attrs = pc8736x_fan_attr_array,
+
+static const struct attribute_group pc8736x_fan_attr_group[] = {
+	{ .attrs = pc8736x_fan_attr[0], },
+	{ .attrs = pc8736x_fan_attr[1], },
+	{ .attrs = pc8736x_fan_attr[2], },
 };
 
-static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_in_input(struct device *dev,
+			     struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index],
 		       data->in_vref));
 }
-static ssize_t show_in_min(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_in_min(struct device *dev,
+			   struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index],
 		       data->in_vref));
 }
-static ssize_t show_in_max(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_in_max(struct device *dev,
+			   struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index],
 		       data->in_vref));
 }
-static ssize_t show_in_status(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_in_status(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", data->in_status[attr->index]);
 }
-static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr,
+			  const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[attr->index] = IN_TO_REG(val, data->in_vref);
@@ -424,12 +453,17 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr,
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr,
+			  const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[attr->index] = IN_TO_REG(val,
@@ -498,9 +532,11 @@ static struct sensor_device_attribute in_max[] = {
 #define CHAN_ALM_MAX	0x04	/* max limit exceeded */
 #define TEMP_ALM_CRIT	0x08	/* temp crit exceeded (temp only) */
 
-/* show_in_min/max_alarm() reads data from the per-channel status
-   register (sec 11.5.12), not the vin event status registers (sec
-   11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) */
+/*
+ * show_in_min/max_alarm() reads data from the per-channel status
+ * register (sec 11.5.12), not the vin event status registers (sec
+ * 11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms)
+ */
 
 static ssize_t show_in_min_alarm(struct device *dev,
 			struct device_attribute *devattr, char *buf)
@@ -554,27 +590,38 @@ static struct sensor_device_attribute in_max_alarm[] = {
 	&in_min_alarm[X].dev_attr.attr,	\
 	&in_max_alarm[X].dev_attr.attr
 
-static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
+			char *buf)
 {
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
 }
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
 
-static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr,
+			char *buf)
 {
 	struct pc87360_data *data = dev_get_drvdata(dev);
 	return sprintf(buf, "%u\n", data->vrm);
 }
-static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
 {
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	data->vrm = val;
 	return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
 
-static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_in_alarms(struct device *dev,
+			      struct device_attribute *attr, char *buf)
 {
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", data->in_alarms);
@@ -602,46 +649,58 @@ static const struct attribute_group pc8736x_vin_group = {
 	.attrs = pc8736x_vin_attr_array,
 };
 
-static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_therm_input(struct device *dev,
+				struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[attr->index],
 		       data->in_vref));
 }
-static ssize_t show_therm_min(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_therm_min(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[attr->index],
 		       data->in_vref));
 }
-static ssize_t show_therm_max(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_therm_max(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[attr->index],
 		       data->in_vref));
 }
-static ssize_t show_therm_crit(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_therm_crit(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[attr->index-11],
 		       data->in_vref));
 }
-static ssize_t show_therm_status(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_therm_status(struct device *dev,
+				 struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", data->in_status[attr->index]);
 }
-static ssize_t set_therm_min(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+
+static ssize_t set_therm_min(struct device *dev,
+			     struct device_attribute *devattr,
+			     const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[attr->index] = IN_TO_REG(val, data->in_vref);
@@ -650,12 +709,19 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+
+static ssize_t set_therm_max(struct device *dev,
+			     struct device_attribute *devattr,
+			     const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[attr->index] = IN_TO_REG(val, data->in_vref);
@@ -664,12 +730,18 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+static ssize_t set_therm_crit(struct device *dev,
+			      struct device_attribute *devattr,
+			      const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref);
@@ -679,46 +751,49 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat
 	return count;
 }
 
-/* the +11 term below reflects the fact that VLM units 11,12,13 are
-   used in the chip to measure voltage across the thermistors
-*/
+/*
+ * the +11 term below reflects the fact that VLM units 11,12,13 are
+ * used in the chip to measure voltage across the thermistors
+ */
 static struct sensor_device_attribute therm_input[] = {
-	SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0+11),
-	SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1+11),
-	SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2+11),
+	SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0 + 11),
+	SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1 + 11),
+	SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2 + 11),
 };
 static struct sensor_device_attribute therm_status[] = {
-	SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0+11),
-	SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1+11),
-	SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2+11),
+	SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0 + 11),
+	SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1 + 11),
+	SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2 + 11),
 };
 static struct sensor_device_attribute therm_min[] = {
 	SENSOR_ATTR(temp4_min, S_IRUGO | S_IWUSR,
-		    show_therm_min, set_therm_min, 0+11),
+		    show_therm_min, set_therm_min, 0 + 11),
 	SENSOR_ATTR(temp5_min, S_IRUGO | S_IWUSR,
-		    show_therm_min, set_therm_min, 1+11),
+		    show_therm_min, set_therm_min, 1 + 11),
 	SENSOR_ATTR(temp6_min, S_IRUGO | S_IWUSR,
-		    show_therm_min, set_therm_min, 2+11),
+		    show_therm_min, set_therm_min, 2 + 11),
 };
 static struct sensor_device_attribute therm_max[] = {
 	SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR,
-		    show_therm_max, set_therm_max, 0+11),
+		    show_therm_max, set_therm_max, 0 + 11),
 	SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR,
-		    show_therm_max, set_therm_max, 1+11),
+		    show_therm_max, set_therm_max, 1 + 11),
 	SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR,
-		    show_therm_max, set_therm_max, 2+11),
+		    show_therm_max, set_therm_max, 2 + 11),
 };
 static struct sensor_device_attribute therm_crit[] = {
 	SENSOR_ATTR(temp4_crit, S_IRUGO | S_IWUSR,
-		    show_therm_crit, set_therm_crit, 0+11),
+		    show_therm_crit, set_therm_crit, 0 + 11),
 	SENSOR_ATTR(temp5_crit, S_IRUGO | S_IWUSR,
-		    show_therm_crit, set_therm_crit, 1+11),
+		    show_therm_crit, set_therm_crit, 1 + 11),
 	SENSOR_ATTR(temp6_crit, S_IRUGO | S_IWUSR,
-		    show_therm_crit, set_therm_crit, 2+11),
+		    show_therm_crit, set_therm_crit, 2 + 11),
 };
 
-/* show_therm_min/max_alarm() reads data from the per-channel voltage
-   status register (sec 11.5.12) */
+/*
+ * show_therm_min/max_alarm() reads data from the per-channel voltage
+ * status register (sec 11.5.12)
+ */
 
 static ssize_t show_therm_min_alarm(struct device *dev,
 				struct device_attribute *devattr, char *buf)
@@ -747,27 +822,27 @@ static ssize_t show_therm_crit_alarm(struct device *dev,
 
 static struct sensor_device_attribute therm_min_alarm[] = {
 	SENSOR_ATTR(temp4_min_alarm, S_IRUGO,
-		    show_therm_min_alarm, NULL, 0+11),
+		    show_therm_min_alarm, NULL, 0 + 11),
 	SENSOR_ATTR(temp5_min_alarm, S_IRUGO,
-		    show_therm_min_alarm, NULL, 1+11),
+		    show_therm_min_alarm, NULL, 1 + 11),
 	SENSOR_ATTR(temp6_min_alarm, S_IRUGO,
-		    show_therm_min_alarm, NULL, 2+11),
+		    show_therm_min_alarm, NULL, 2 + 11),
 };
 static struct sensor_device_attribute therm_max_alarm[] = {
 	SENSOR_ATTR(temp4_max_alarm, S_IRUGO,
-		    show_therm_max_alarm, NULL, 0+11),
+		    show_therm_max_alarm, NULL, 0 + 11),
 	SENSOR_ATTR(temp5_max_alarm, S_IRUGO,
-		    show_therm_max_alarm, NULL, 1+11),
+		    show_therm_max_alarm, NULL, 1 + 11),
 	SENSOR_ATTR(temp6_max_alarm, S_IRUGO,
-		    show_therm_max_alarm, NULL, 2+11),
+		    show_therm_max_alarm, NULL, 2 + 11),
 };
 static struct sensor_device_attribute therm_crit_alarm[] = {
 	SENSOR_ATTR(temp4_crit_alarm, S_IRUGO,
-		    show_therm_crit_alarm, NULL, 0+11),
+		    show_therm_crit_alarm, NULL, 0 + 11),
 	SENSOR_ATTR(temp5_crit_alarm, S_IRUGO,
-		    show_therm_crit_alarm, NULL, 1+11),
+		    show_therm_crit_alarm, NULL, 1 + 11),
 	SENSOR_ATTR(temp6_crit_alarm, S_IRUGO,
-		    show_therm_crit_alarm, NULL, 2+11),
+		    show_therm_crit_alarm, NULL, 2 + 11),
 };
 
 #define THERM_UNIT_ATTRS(X) \
@@ -780,7 +855,7 @@ static struct sensor_device_attribute therm_crit_alarm[] = {
 	&therm_max_alarm[X].dev_attr.attr, \
 	&therm_crit_alarm[X].dev_attr.attr
 
-static struct attribute * pc8736x_therm_attr_array[] = {
+static struct attribute *pc8736x_therm_attr_array[] = {
 	THERM_UNIT_ATTRS(0),
 	THERM_UNIT_ATTRS(1),
 	THERM_UNIT_ATTRS(2),
@@ -790,42 +865,59 @@ static const struct attribute_group pc8736x_therm_group = {
 	.attrs = pc8736x_therm_attr_array,
 };
 
-static ssize_t show_temp_input(struct device *dev, struct device_attribute *devattr, char *buf)
+static ssize_t show_temp_input(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
 }
-static ssize_t show_temp_min(struct device *dev, struct device_attribute *devattr, char *buf)
+
+static ssize_t show_temp_min(struct device *dev,
+			     struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[attr->index]));
 }
-static ssize_t show_temp_max(struct device *dev, struct device_attribute *devattr, char *buf)
+
+static ssize_t show_temp_max(struct device *dev,
+			     struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[attr->index]));
 }
-static ssize_t show_temp_crit(struct device *dev, struct device_attribute *devattr, char *buf)
+
+static ssize_t show_temp_crit(struct device *dev,
+			      struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[attr->index]));
+	return sprintf(buf, "%d\n",
+		       TEMP_FROM_REG(data->temp_crit[attr->index]));
 }
-static ssize_t show_temp_status(struct device *dev, struct device_attribute *devattr, char *buf)
+
+static ssize_t show_temp_status(struct device *dev,
+				struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%d\n", data->temp_status[attr->index]);
 }
-static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+
+static ssize_t set_temp_min(struct device *dev,
+			    struct device_attribute *devattr,
+			    const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[attr->index] = TEMP_TO_REG(val);
@@ -834,12 +926,19 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+
+static ssize_t set_temp_max(struct device *dev,
+			    struct device_attribute *devattr,
+			    const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[attr->index] = TEMP_TO_REG(val);
@@ -848,12 +947,19 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr
 	mutex_unlock(&data->update_lock);
 	return count;
 }
-static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf,
-	size_t count)
+
+static ssize_t set_temp_crit(struct device *dev,
+			     struct device_attribute *devattr, const char *buf,
+			     size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct pc87360_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_crit[attr->index] = TEMP_TO_REG(val);
@@ -898,16 +1004,20 @@ static struct sensor_device_attribute temp_crit[] = {
 		    show_temp_crit, set_temp_crit, 2),
 };
 
-static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_alarms(struct device *dev,
+				struct device_attribute *attr, char *buf)
 {
 	struct pc87360_data *data = pc87360_update_device(dev);
 	return sprintf(buf, "%u\n", data->temp_alarms);
 }
+
 static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
 
-/* show_temp_min/max_alarm() reads data from the per-channel status
-   register (sec 12.3.7), not the temp event status registers (sec
-   12.3.2) that show_temp_alarm() reads (via data->temp_alarms) */
+/*
+ * show_temp_min/max_alarm() reads data from the per-channel status
+ * register (sec 12.3.7), not the temp event status registers (sec
+ * 12.3.2) that show_temp_alarm() reads (via data->temp_alarms)
+ */
 
 static ssize_t show_temp_min_alarm(struct device *dev,
 			struct device_attribute *devattr, char *buf)
@@ -917,6 +1027,7 @@ static ssize_t show_temp_min_alarm(struct device *dev,
 
 	return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MIN));
 }
+
 static ssize_t show_temp_max_alarm(struct device *dev,
 			struct device_attribute *devattr, char *buf)
 {
@@ -925,6 +1036,7 @@ static ssize_t show_temp_max_alarm(struct device *dev,
 
 	return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MAX));
 }
+
 static ssize_t show_temp_crit_alarm(struct device *dev,
 			struct device_attribute *devattr, char *buf)
 {
@@ -939,11 +1051,13 @@ static struct sensor_device_attribute temp_min_alarm[] = {
 	SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 1),
 	SENSOR_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 2),
 };
+
 static struct sensor_device_attribute temp_max_alarm[] = {
 	SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 0),
 	SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 1),
 	SENSOR_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 2),
 };
+
 static struct sensor_device_attribute temp_crit_alarm[] = {
 	SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 0),
 	SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 1),
@@ -965,27 +1079,29 @@ static struct sensor_device_attribute temp_fault[] = {
 	SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2),
 };
 
-#define TEMP_UNIT_ATTRS(X) \
-	&temp_input[X].dev_attr.attr,	\
-	&temp_status[X].dev_attr.attr,	\
-	&temp_min[X].dev_attr.attr,	\
-	&temp_max[X].dev_attr.attr,	\
-	&temp_crit[X].dev_attr.attr,	\
-	&temp_min_alarm[X].dev_attr.attr, \
-	&temp_max_alarm[X].dev_attr.attr, \
-	&temp_crit_alarm[X].dev_attr.attr, \
-	&temp_fault[X].dev_attr.attr
-
-static struct attribute * pc8736x_temp_attr_array[] = {
+#define TEMP_UNIT_ATTRS(X)			\
+{	&temp_input[X].dev_attr.attr,		\
+	&temp_status[X].dev_attr.attr,		\
+	&temp_min[X].dev_attr.attr,		\
+	&temp_max[X].dev_attr.attr,		\
+	&temp_crit[X].dev_attr.attr,		\
+	&temp_min_alarm[X].dev_attr.attr,	\
+	&temp_max_alarm[X].dev_attr.attr,	\
+	&temp_crit_alarm[X].dev_attr.attr,	\
+	&temp_fault[X].dev_attr.attr,		\
+	NULL					\
+}
+
+static struct attribute *pc8736x_temp_attr[][10] = {
 	TEMP_UNIT_ATTRS(0),
 	TEMP_UNIT_ATTRS(1),
-	TEMP_UNIT_ATTRS(2),
-	/* include the few miscellaneous atts here */
-	&dev_attr_alarms_temp.attr,
-	NULL
+	TEMP_UNIT_ATTRS(2)
 };
-static const struct attribute_group pc8736x_temp_group = {
-	.attrs = pc8736x_temp_attr_array,
+
+static const struct attribute_group pc8736x_temp_attr_group[] = {
+	{ .attrs = pc8736x_temp_attr[0] },
+	{ .attrs = pc8736x_temp_attr[1] },
+	{ .attrs = pc8736x_temp_attr[2] }
 };
 
 static ssize_t show_name(struct device *dev,
@@ -994,13 +1110,15 @@ static ssize_t show_name(struct device *dev,
 	struct pc87360_data *data = dev_get_drvdata(dev);
 	return sprintf(buf, "%s\n", data->name);
 }
+
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
 /*
  * Device detection, registration and update
  */
 
-static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses)
+static int __init pc87360_find(int sioaddr, u8 *devid,
+			       unsigned short *addresses)
 {
 	u16 val;
 	int i;
@@ -1047,7 +1165,7 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
 
 		addresses[i] = val;
 
-		if (i==0) { /* Fans */
+		if (i == 0) { /* Fans */
 			confreg[0] = superio_inb(sioaddr, 0xF0);
 			confreg[1] = superio_inb(sioaddr, 0xF1);
 
@@ -1060,12 +1178,14 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
 			pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 3,
 				 confreg[1] & 1, (confreg[1] >> 1) & 1,
 				 (confreg[1] >> 2) & 1);
-		} else if (i==1) { /* Voltages */
+		} else if (i == 1) { /* Voltages */
 			/* Are we using thermistors? */
 			if (*devid == 0xE9) { /* PC87366 */
-				/* These registers are not logical-device
-				   specific, just that we won't need them if
-				   we don't use the VLM device */
+				/*
+				 * These registers are not logical-device
+				 * specific, just that we won't need them if
+				 * we don't use the VLM device
+				 */
 				confreg[2] = superio_inb(sioaddr, 0x2B);
 				confreg[3] = superio_inb(sioaddr, 0x25);
 
@@ -1085,6 +1205,22 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
 	return 0;
 }
 
+static void pc87360_remove_files(struct device *dev)
+{
+	int i;
+
+	device_remove_file(dev, &dev_attr_name);
+	device_remove_file(dev, &dev_attr_alarms_temp);
+	for (i = 0; i < ARRAY_SIZE(pc8736x_temp_attr_group); i++)
+		sysfs_remove_group(&dev->kobj, &pc8736x_temp_attr_group[i]);
+	for (i = 0; i < ARRAY_SIZE(pc8736x_fan_attr_group); i++) {
+		sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_attr_group[i]);
+		device_remove_file(dev, &pwm[i].dev_attr);
+	}
+	sysfs_remove_group(&dev->kobj, &pc8736x_therm_group);
+	sysfs_remove_group(&dev->kobj, &pc8736x_vin_group);
+}
+
 static int __devinit pc87360_probe(struct platform_device *pdev)
 {
 	int i;
@@ -1094,7 +1230,8 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
 	int use_thermistors = 0;
 	struct device *dev = &pdev->dev;
 
-	if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
+	data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL);
+	if (!data)
 		return -ENOMEM;
 
 	data->fannr = 2;
@@ -1130,9 +1267,10 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, data);
 
 	for (i = 0; i < LDNI_MAX; i++) {
-		if (((data->address[i] = extra_isa[i]))
+		data->address[i] = extra_isa[i];
+		if (data->address[i]
 		 && !request_region(extra_isa[i], PC87360_EXTENT,
-		 		    pc87360_driver.driver.name)) {
+				    pc87360_driver.driver.name)) {
 			dev_err(dev, "Region 0x%x-0x%x already "
 				"in use!\n", extra_isa[i],
 				extra_isa[i]+PC87360_EXTENT-1);
@@ -1147,9 +1285,11 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
 	if (data->fannr)
 		data->fan_conf = confreg[0] | (confreg[1] << 8);
 
-	/* Use the correct reference voltage
-	   Unless both the VLM and the TMS logical devices agree to
-	   use an external Vref, the internal one is used. */
+	/*
+	 * Use the correct reference voltage
+	 * Unless both the VLM and the TMS logical devices agree to
+	 * use an external Vref, the internal one is used.
+	 */
 	if (data->innr) {
 		i = pc87360_read_value(data, LD_IN, NO_BANK,
 				       PC87365_REG_IN_CONFIG);
@@ -1182,62 +1322,48 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
 
 	/* Register all-or-nothing sysfs groups */
 
-	if (data->innr &&
-	    (err = sysfs_create_group(&dev->kobj,
-				      &pc8736x_vin_group)))
-		goto ERROR3;
+	if (data->innr) {
+		err = sysfs_create_group(&dev->kobj, &pc8736x_vin_group);
+		if (err)
+			goto ERROR3;
+	}
 
-	if (data->innr == 14 &&
-	    (err = sysfs_create_group(&dev->kobj,
-				      &pc8736x_therm_group)))
-		goto ERROR3;
+	if (data->innr == 14) {
+		err = sysfs_create_group(&dev->kobj, &pc8736x_therm_group);
+		if (err)
+			goto ERROR3;
+	}
 
 	/* create device attr-files for varying sysfs groups */
 
 	if (data->tempnr) {
 		for (i = 0; i < data->tempnr; i++) {
-			if ((err = device_create_file(dev,
-					&temp_input[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_min[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_max[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_crit[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_status[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_min_alarm[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_max_alarm[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_crit_alarm[i].dev_attr))
-			    || (err = device_create_file(dev,
-					&temp_fault[i].dev_attr)))
+			err = sysfs_create_group(&dev->kobj,
+						 &pc8736x_temp_attr_group[i]);
+			if (err)
 				goto ERROR3;
 		}
-		if ((err = device_create_file(dev, &dev_attr_alarms_temp)))
+		err = device_create_file(dev, &dev_attr_alarms_temp);
+		if (err)
 			goto ERROR3;
 	}
 
 	for (i = 0; i < data->fannr; i++) {
-		if (FAN_CONFIG_MONITOR(data->fan_conf, i)
-		    && ((err = device_create_file(dev,
-					&fan_input[i].dev_attr))
-			|| (err = device_create_file(dev,
-					&fan_min[i].dev_attr))
-			|| (err = device_create_file(dev,
-					&fan_div[i].dev_attr))
-			|| (err = device_create_file(dev,
-					&fan_status[i].dev_attr))))
-			goto ERROR3;
-
-		if (FAN_CONFIG_CONTROL(data->fan_conf, i)
-		    && (err = device_create_file(dev, &pwm[i].dev_attr)))
-			goto ERROR3;
+		if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
+			err = sysfs_create_group(&dev->kobj,
+						 &pc8736x_fan_attr_group[i]);
+			if (err)
+				goto ERROR3;
+		}
+		if (FAN_CONFIG_CONTROL(data->fan_conf, i)) {
+			err = device_create_file(dev, &pwm[i].dev_attr);
+			if (err)
+				goto ERROR3;
+		}
 	}
 
-	if ((err = device_create_file(dev, &dev_attr_name)))
+	err = device_create_file(dev, &dev_attr_name);
+	if (err)
 		goto ERROR3;
 
 	data->hwmon_dev = hwmon_device_register(dev);
@@ -1248,16 +1374,10 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
 	return 0;
 
 ERROR3:
-	device_remove_file(dev, &dev_attr_name);
-	/* can still remove groups whose members were added individually */
-	sysfs_remove_group(&dev->kobj, &pc8736x_temp_group);
-	sysfs_remove_group(&dev->kobj, &pc8736x_fan_group);
-	sysfs_remove_group(&dev->kobj, &pc8736x_therm_group);
-	sysfs_remove_group(&dev->kobj, &pc8736x_vin_group);
+	pc87360_remove_files(dev);
 	for (i = 0; i < 3; i++) {
-		if (data->address[i]) {
+		if (data->address[i])
 			release_region(data->address[i], PC87360_EXTENT);
-		}
 	}
 ERROR1:
 	kfree(data);
@@ -1270,25 +1390,20 @@ static int __devexit pc87360_remove(struct platform_device *pdev)
 	int i;
 
 	hwmon_device_unregister(data->hwmon_dev);
-
-	device_remove_file(&pdev->dev, &dev_attr_name);
-	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group);
-	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_group);
-	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_therm_group);
-	sysfs_remove_group(&pdev->dev.kobj, &pc8736x_vin_group);
-
+	pc87360_remove_files(&pdev->dev);
 	for (i = 0; i < 3; i++) {
-		if (data->address[i]) {
+		if (data->address[i])
 			release_region(data->address[i], PC87360_EXTENT);
-		}
 	}
 	kfree(data);
 
 	return 0;
 }
 
-/* ldi is the logical device index
-   bank is for voltages and temperatures only */
+/*
+ * ldi is the logical device index
+ * bank is for voltages and temperatures only
+ */
 static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
 			      u8 reg)
 {
@@ -1359,8 +1474,10 @@ static void pc87360_init_device(struct platform_device *pdev,
 		}
 	}
 
-	/* We can't blindly trust the Super-I/O space configuration bit,
-	   most BIOS won't set it properly */
+	/*
+	 * We can't blindly trust the Super-I/O space configuration bit,
+	 * most BIOS won't set it properly
+	 */
 	dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors);
 	for (i = 11; i < data->innr; i++) {
 		reg = pc87360_read_value(data, LD_IN, i,
@@ -1375,12 +1492,12 @@ static void pc87360_init_device(struct platform_device *pdev,
 	for (; i < data->tempnr; i++) {
 		reg = pc87360_read_value(data, LD_TEMP, i,
 					 PC87365_REG_TEMP_STATUS);
-		dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg);
+		dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i + 1, reg);
 		if (init >= init_temp[i]) {
 			/* Forcibly enable temperature channel */
 			if (!(reg & CHAN_ENA)) {
-				dev_dbg(&pdev->dev, "Forcibly "
-					"enabling temp%d\n", i+1);
+				dev_dbg(&pdev->dev,
+					"Forcibly enabling temp%d\n", i + 1);
 				pc87360_write_value(data, LD_TEMP, i,
 						    PC87365_REG_TEMP_STATUS,
 						    0xCF);
@@ -1391,14 +1508,16 @@ static void pc87360_init_device(struct platform_device *pdev,
 	if (use_thermistors) {
 		for (i = 11; i < data->innr; i++) {
 			if (init >= init_in[i]) {
-				/* The pin may already be used by thermal
-				   diodes */
+				/*
+				 * The pin may already be used by thermal
+				 * diodes
+				 */
 				reg = pc87360_read_value(data, LD_TEMP,
-				      (i-11)/2, PC87365_REG_TEMP_STATUS);
+				      (i - 11) / 2, PC87365_REG_TEMP_STATUS);
 				if (reg & CHAN_ENA) {
-					dev_dbg(&pdev->dev, "Skipping "
-						"temp%d, pin already in use "
-						"by temp%d\n", i-7, (i-11)/2);
+					dev_dbg(&pdev->dev,
+			"Skipping temp%d, pin already in use by temp%d\n",
+						i - 7, (i - 11) / 2);
 					continue;
 				}
 
@@ -1406,8 +1525,9 @@ static void pc87360_init_device(struct platform_device *pdev,
 				reg = pc87360_read_value(data, LD_IN, i,
 							 PC87365_REG_IN_STATUS);
 				if (!(reg & CHAN_ENA)) {
-					dev_dbg(&pdev->dev, "Forcibly "
-						"enabling temp%d\n", i-7);
+					dev_dbg(&pdev->dev,
+						"Forcibly enabling temp%d\n",
+						i - 7);
 					pc87360_write_value(data, LD_IN, i,
 						PC87365_REG_TEMP_STATUS,
 						(reg & 0x60) | 0x8F);
@@ -1421,8 +1541,8 @@ static void pc87360_init_device(struct platform_device *pdev,
 					 PC87365_REG_IN_CONFIG);
 		dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg);
 		if (reg & CHAN_ENA) {
-			dev_dbg(&pdev->dev, "Forcibly "
-				"enabling monitoring (VLM)\n");
+			dev_dbg(&pdev->dev,
+				"Forcibly enabling monitoring (VLM)\n");
 			pc87360_write_value(data, LD_IN, NO_BANK,
 					    PC87365_REG_IN_CONFIG,
 					    reg & 0xFE);
@@ -1434,8 +1554,8 @@ static void pc87360_init_device(struct platform_device *pdev,
 					 PC87365_REG_TEMP_CONFIG);
 		dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg);
 		if (reg & CHAN_ENA) {
-			dev_dbg(&pdev->dev, "Forcibly enabling "
-				"monitoring (TMS)\n");
+			dev_dbg(&pdev->dev,
+				"Forcibly enabling monitoring (TMS)\n");
 			pc87360_write_value(data, LD_TEMP, NO_BANK,
 					    PC87365_REG_TEMP_CONFIG,
 					    reg & 0xFE);
@@ -1444,10 +1564,12 @@ static void pc87360_init_device(struct platform_device *pdev,
 		if (init >= 2) {
 			/* Chip config as documented by National Semi. */
 			pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08);
-			/* We voluntarily omit the bank here, in case the
-			   sequence itself matters. It shouldn't be a problem,
-			   since nobody else is supposed to access the
-			   device at that point. */
+			/*
+			 * We voluntarily omit the bank here, in case the
+			 * sequence itself matters. It shouldn't be a problem,
+			 * since nobody else is supposed to access the
+			 * device at that point.
+			 */
 			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04);
 			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35);
 			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05);
@@ -1470,7 +1592,7 @@ static void pc87360_autodiv(struct device *dev, int nr)
 			data->fan[nr] >>= 1;
 			dev_dbg(dev, "Increasing "
 				"clock divider to %d for fan %d\n",
-				FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1);
+				FAN_DIV_FROM_REG(data->fan_status[nr]), nr + 1);
 		}
 	} else {
 		/* Decrease clock divider if possible */
@@ -1483,7 +1605,7 @@ static void pc87360_autodiv(struct device *dev, int nr)
 			dev_dbg(dev, "Decreasing "
 				"clock divider to %d for fan %d\n",
 				FAN_DIV_FROM_REG(data->fan_status[nr]),
-				nr+1);
+				nr + 1);
 		}
 	}
 
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index cb35461..37059a3 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -46,9 +46,11 @@ static struct platform_device *pdev;
 
 #define DRVNAME "pc87427"
 
-/* The lock mutex protects both the I/O accesses (needed because the
-   device is using banked registers) and the register cache (needed to keep
-   the data in the registers and the cache in sync at any time). */
+/*
+ * The lock mutex protects both the I/O accesses (needed because the
+ * device is using banked registers) and the register cache (needed to keep
+ * the data in the registers and the cache in sync at any time).
+ */
 struct pc87427_data {
 	struct device *hwmon_dev;
 	struct mutex lock;
@@ -173,10 +175,12 @@ static inline void pc87427_write8_bank(struct pc87427_data *data, u8 ldi,
 #define FAN_STATUS_LOSPD		(1 << 1)
 #define FAN_STATUS_MONEN		(1 << 0)
 
-/* Dedicated function to read all registers related to a given fan input.
-   This saves us quite a few locks and bank selections.
-   Must be called with data->lock held.
-   nr is from 0 to 7 */
+/*
+ * Dedicated function to read all registers related to a given fan input.
+ * This saves us quite a few locks and bank selections.
+ * Must be called with data->lock held.
+ * nr is from 0 to 7
+ */
 static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
 {
 	int iobase = data->address[LD_FAN];
@@ -189,8 +193,10 @@ static void pc87427_readall_fan(struct pc87427_data *data, u8 nr)
 	outb(data->fan_status[nr], iobase + PC87427_REG_FAN_STATUS);
 }
 
-/* The 2 LSB of fan speed registers are used for something different.
-   The actual 2 LSB of the measurements are not available. */
+/*
+ * The 2 LSB of fan speed registers are used for something different.
+ * The actual 2 LSB of the measurements are not available.
+ */
 static inline unsigned long fan_from_reg(u16 reg)
 {
 	reg &= 0xfffc;
@@ -224,10 +230,12 @@ static inline u16 fan_to_reg(unsigned long val)
 #define PWM_MODE_OFF			(2 << 4)
 #define PWM_MODE_ON			(7 << 4)
 
-/* Dedicated function to read all registers related to a given PWM output.
-   This saves us quite a few locks and bank selections.
-   Must be called with data->lock held.
-   nr is from 0 to 3 */
+/*
+ * Dedicated function to read all registers related to a given PWM output.
+ * This saves us quite a few locks and bank selections.
+ * Must be called with data->lock held.
+ * nr is from 0 to 3
+ */
 static void pc87427_readall_pwm(struct pc87427_data *data, u8 nr)
 {
 	int iobase = data->address[LD_FAN];
@@ -286,10 +294,12 @@ static inline u8 pwm_enable_to_reg(unsigned long val, u8 pwmval)
 #define TEMP_TYPE_REMOTE_DIODE		(2 << 5)
 #define TEMP_TYPE_LOCAL_DIODE		(3 << 5)
 
-/* Dedicated function to read all registers related to a given temperature
-   input. This saves us quite a few locks and bank selections.
-   Must be called with data->lock held.
-   nr is from 0 to 5 */
+/*
+ * Dedicated function to read all registers related to a given temperature
+ * input. This saves us quite a few locks and bank selections.
+ * Must be called with data->lock held.
+ * nr is from 0 to 5
+ */
 static void pc87427_readall_temp(struct pc87427_data *data, u8 nr)
 {
 	int iobase = data->address[LD_TEMP];
@@ -318,8 +328,10 @@ static inline unsigned int temp_type_from_reg(u8 reg)
 	}
 }
 
-/* We assume 8-bit thermal sensors; 9-bit thermal sensors are possible
-   too, but I have no idea how to figure out when they are used. */
+/*
+ * We assume 8-bit thermal sensors; 9-bit thermal sensors are possible
+ * too, but I have no idea how to figure out when they are used.
+ */
 static inline long temp_from_reg(s16 reg)
 {
 	return reg * 1000 / 256;
@@ -423,9 +435,11 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
 
 	mutex_lock(&data->lock);
 	outb(BANK_FM(nr), iobase + PC87427_REG_BANK);
-	/* The low speed limit registers are read-only while monitoring
-	   is enabled, so we have to disable monitoring, then change the
-	   limit, and finally enable monitoring again. */
+	/*
+	 * The low speed limit registers are read-only while monitoring
+	 * is enabled, so we have to disable monitoring, then change the
+	 * limit, and finally enable monitoring again.
+	 */
 	outb(0, iobase + PC87427_REG_FAN_STATUS);
 	data->fan_min[nr] = fan_to_reg(val);
 	outw(data->fan_min[nr], iobase + PC87427_REG_FAN_MIN);
@@ -542,8 +556,10 @@ static const struct attribute_group pc87427_group_fan[8] = {
 	{ .attrs = pc87427_attributes_fan[7] },
 };
 
-/* Must be called with data->lock held and pc87427_readall_pwm() freshly
-   called */
+/*
+ * Must be called with data->lock held and pc87427_readall_pwm() freshly
+ * called
+ */
 static void update_pwm_enable(struct pc87427_data *data, int nr, u8 mode)
 {
 	int iobase = data->address[LD_FAN];
@@ -1023,9 +1039,11 @@ static void __devinit pc87427_init_device(struct device *dev)
 		if (reg & PWM_ENABLE_CTLEN)
 			data->pwm_enabled |= (1 << i);
 
-		/* We don't expose an interface to reconfigure the automatic
-		   fan control mode, so only allow to return to this mode if
-		   it was originally set. */
+		/*
+		 * We don't expose an interface to reconfigure the automatic
+		 * fan control mode, so only allow to return to this mode if
+		 * it was originally set.
+		 */
 		if ((reg & PWM_ENABLE_MODE_MASK) == PWM_MODE_AUTO) {
 			dev_dbg(dev, "PWM%d is in automatic control mode\n",
 				i + 1);
diff --git a/drivers/hwmon/pcf8591.c b/drivers/hwmon/pcf8591.c
index 731b09a..4174c74 100644
--- a/drivers/hwmon/pcf8591.c
+++ b/drivers/hwmon/pcf8591.c
@@ -1,22 +1,22 @@
 /*
-    Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
-    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
-    the help of Jean Delvare <khali@linux-fr.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.
-*/
+ * Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
+ * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+ * the help of Jean Delvare <khali@linux-fr.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.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -39,28 +39,34 @@ MODULE_PARM_DESC(input_mode,
 	" 2 = single ended and differential mixed\n"
 	" 3 = two differential inputs\n");
 
-/* The PCF8591 control byte
-      7    6    5    4    3    2    1    0
-   |  0 |AOEF|   AIP   |  0 |AINC|  AICH   | */
+/*
+ * The PCF8591 control byte
+ *      7    6    5    4    3    2    1    0
+ *   |  0 |AOEF|   AIP   |  0 |AINC|  AICH   |
+ */
 
 /* Analog Output Enable Flag (analog output active if 1) */
 #define PCF8591_CONTROL_AOEF		0x40
 
-/* Analog Input Programming
-   0x00 = four single ended inputs
-   0x10 = three differential inputs
-   0x20 = single ended and differential mixed
-   0x30 = two differential inputs */
+/*
+ * Analog Input Programming
+ * 0x00 = four single ended inputs
+ * 0x10 = three differential inputs
+ * 0x20 = single ended and differential mixed
+ * 0x30 = two differential inputs
+ */
 #define PCF8591_CONTROL_AIP_MASK	0x30
 
 /* Autoincrement Flag (switch on if 1) */
 #define PCF8591_CONTROL_AINC		0x04
 
-/* Channel selection
-   0x00 = channel 0
-   0x01 = channel 1
-   0x02 = channel 2
-   0x03 = channel 3 */
+/*
+ * Channel selection
+ * 0x00 = channel 0
+ * 0x01 = channel 1
+ * 0x02 = channel 2
+ * 0x03 = channel 3
+ */
 #define PCF8591_CONTROL_AICH_MASK	0x03
 
 /* Initial values */
@@ -68,7 +74,7 @@ MODULE_PARM_DESC(input_mode,
 #define PCF8591_INIT_AOUT	0	/* DAC out = 0 */
 
 /* Conversions */
-#define REG_TO_SIGNED(reg)	(((reg) & 0x80)?((reg) - 256):(reg))
+#define REG_TO_SIGNED(reg)	(((reg) & 0x80) ? ((reg) - 256) : (reg))
 
 struct pcf8591_data {
 	struct device *hwmon_dev;
@@ -83,7 +89,9 @@ static int pcf8591_read_channel(struct device *dev, int channel);
 
 /* following are the sysfs callback functions */
 #define show_in_channel(channel)					\
-static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf)	\
+static ssize_t show_in##channel##_input(struct device *dev,		\
+					struct device_attribute *attr,	\
+					char *buf)			\
 {									\
 	return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
 }									\
@@ -95,39 +103,57 @@ show_in_channel(1);
 show_in_channel(2);
 show_in_channel(3);
 
-static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_out0_ouput(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
 	return sprintf(buf, "%d\n", data->aout * 10);
 }
 
-static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_out0_output(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
 {
-	unsigned int value;
+	unsigned long val;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct pcf8591_data *data = i2c_get_clientdata(client);
-	if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) {
-		data->aout = value;
-		i2c_smbus_write_byte_data(client, data->control, data->aout);
-		return count;
-	}
-	return -EINVAL;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	val /= 10;
+	if (val > 255)
+		return -EINVAL;
+
+	data->aout = val;
+	i2c_smbus_write_byte_data(client, data->control, data->aout);
+	return count;
 }
 
 static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
 		   show_out0_ouput, set_out0_output);
 
-static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_out0_enable(struct device *dev,
+				struct device_attribute *attr, char *buf)
 {
 	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
 	return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
 }
 
-static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_out0_enable(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct pcf8591_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	if (val)
@@ -174,7 +200,8 @@ static int pcf8591_probe(struct i2c_client *client,
 	struct pcf8591_data *data;
 	int err;
 
-	if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto exit;
 	}
@@ -192,15 +219,15 @@ static int pcf8591_probe(struct i2c_client *client,
 
 	/* Register input2 if not in "two differential inputs" mode */
 	if (input_mode != 3) {
-		if ((err = device_create_file(&client->dev,
-					      &dev_attr_in2_input)))
+		err = device_create_file(&client->dev, &dev_attr_in2_input);
+		if (err)
 			goto exit_sysfs_remove;
 	}
 
 	/* Register input3 only in "four single ended inputs" mode */
 	if (input_mode == 0) {
-		if ((err = device_create_file(&client->dev,
-					      &dev_attr_in3_input)))
+		err = device_create_file(&client->dev, &dev_attr_in3_input);
+		if (err)
 			goto exit_sysfs_remove;
 	}
 
@@ -241,8 +268,10 @@ static void pcf8591_init_client(struct i2c_client *client)
 
 	i2c_smbus_write_byte_data(client, data->control, data->aout);
 
-	/* The first byte transmitted contains the conversion code of the
-	   previous read cycle. FLUSH IT! */
+	/*
+	 * The first byte transmitted contains the conversion code of the
+	 * previous read cycle. FLUSH IT!
+	 */
 	i2c_smbus_read_byte(client);
 }
 
@@ -259,8 +288,10 @@ static int pcf8591_read_channel(struct device *dev, int channel)
 			      | channel;
 		i2c_smbus_write_byte(client, data->control);
 
-		/* The first byte transmitted contains the conversion code of
-		   the previous read cycle. FLUSH IT! */
+		/*
+		 * The first byte transmitted contains the conversion code of
+		 * the previous read cycle. FLUSH IT!
+		 */
 		i2c_smbus_read_byte(client);
 	}
 	value = i2c_smbus_read_byte(client);
@@ -269,9 +300,9 @@ static int pcf8591_read_channel(struct device *dev, int channel)
 
 	if ((channel == 2 && input_mode == 2) ||
 	    (channel != 3 && (input_mode == 1 || input_mode == 3)))
-		return (10 * REG_TO_SIGNED(value));
+		return 10 * REG_TO_SIGNED(value);
 	else
-		return (10 * value);
+		return 10 * value;
 }
 
 static const struct i2c_device_id pcf8591_id[] = {
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c
index 81c7c2e..fe52c3c 100644
--- a/drivers/hwmon/pmbus/adm1275.c
+++ b/drivers/hwmon/pmbus/adm1275.c
@@ -326,18 +326,8 @@ static struct i2c_driver adm1275_driver = {
 	.id_table = adm1275_id,
 };
 
-static int __init adm1275_init(void)
-{
-	return i2c_add_driver(&adm1275_driver);
-}
-
-static void __exit adm1275_exit(void)
-{
-	i2c_del_driver(&adm1275_driver);
-}
+module_i2c_driver(adm1275_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles");
 MODULE_LICENSE("GPL");
-module_init(adm1275_init);
-module_exit(adm1275_exit);
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c
index 84a37f0..86ac15a 100644
--- a/drivers/hwmon/pmbus/lm25066.c
+++ b/drivers/hwmon/pmbus/lm25066.c
@@ -334,18 +334,8 @@ static struct i2c_driver lm25066_driver = {
 	.id_table = lm25066_id,
 };
 
-static int __init lm25066_init(void)
-{
-	return i2c_add_driver(&lm25066_driver);
-}
-
-static void __exit lm25066_exit(void)
-{
-	i2c_del_driver(&lm25066_driver);
-}
+module_i2c_driver(lm25066_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for LM25066/LM5064/LM5066");
 MODULE_LICENSE("GPL");
-module_init(lm25066_init);
-module_exit(lm25066_exit);
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c
index 820fff4..c9e4dd2 100644
--- a/drivers/hwmon/pmbus/ltc2978.c
+++ b/drivers/hwmon/pmbus/ltc2978.c
@@ -391,18 +391,8 @@ static struct i2c_driver ltc2978_driver = {
 	.id_table = ltc2978_id,
 };
 
-static int __init ltc2978_init(void)
-{
-	return i2c_add_driver(&ltc2978_driver);
-}
-
-static void __exit ltc2978_exit(void)
-{
-	i2c_del_driver(&ltc2978_driver);
-}
+module_i2c_driver(ltc2978_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for LTC2978 and LTC3880");
 MODULE_LICENSE("GPL");
-module_init(ltc2978_init);
-module_exit(ltc2978_exit);
diff --git a/drivers/hwmon/pmbus/max16064.c b/drivers/hwmon/pmbus/max16064.c
index 1d77cf4..5cfe20f 100644
--- a/drivers/hwmon/pmbus/max16064.c
+++ b/drivers/hwmon/pmbus/max16064.c
@@ -126,18 +126,8 @@ static struct i2c_driver max16064_driver = {
 	.id_table = max16064_id,
 };
 
-static int __init max16064_init(void)
-{
-	return i2c_add_driver(&max16064_driver);
-}
-
-static void __exit max16064_exit(void)
-{
-	i2c_del_driver(&max16064_driver);
-}
+module_i2c_driver(max16064_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064");
 MODULE_LICENSE("GPL");
-module_init(max16064_init);
-module_exit(max16064_exit);
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
index beaf5a8..89ae303 100644
--- a/drivers/hwmon/pmbus/max34440.c
+++ b/drivers/hwmon/pmbus/max34440.c
@@ -248,18 +248,8 @@ static struct i2c_driver max34440_driver = {
 	.id_table = max34440_id,
 };
 
-static int __init max34440_init(void)
-{
-	return i2c_add_driver(&max34440_driver);
-}
-
-static void __exit max34440_exit(void)
-{
-	i2c_del_driver(&max34440_driver);
-}
+module_i2c_driver(max34440_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
 MODULE_LICENSE("GPL");
-module_init(max34440_init);
-module_exit(max34440_exit);
diff --git a/drivers/hwmon/pmbus/max8688.c b/drivers/hwmon/pmbus/max8688.c
index e2b74bb..82c598d 100644
--- a/drivers/hwmon/pmbus/max8688.c
+++ b/drivers/hwmon/pmbus/max8688.c
@@ -203,18 +203,8 @@ static struct i2c_driver max8688_driver = {
 	.id_table = max8688_id,
 };
 
-static int __init max8688_init(void)
-{
-	return i2c_add_driver(&max8688_driver);
-}
-
-static void __exit max8688_exit(void)
-{
-	i2c_del_driver(&max8688_driver);
-}
+module_i2c_driver(max8688_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688");
 MODULE_LICENSE("GPL");
-module_init(max8688_init);
-module_exit(max8688_exit);
diff --git a/drivers/hwmon/pmbus/pmbus.c b/drivers/hwmon/pmbus/pmbus.c
index 18a385e..da5fe36 100644
--- a/drivers/hwmon/pmbus/pmbus.c
+++ b/drivers/hwmon/pmbus/pmbus.c
@@ -224,18 +224,8 @@ static struct i2c_driver pmbus_driver = {
 	.id_table = pmbus_id,
 };
 
-static int __init pmbus_init(void)
-{
-	return i2c_add_driver(&pmbus_driver);
-}
-
-static void __exit pmbus_exit(void)
-{
-	i2c_del_driver(&pmbus_driver);
-}
+module_i2c_driver(pmbus_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("Generic PMBus driver");
 MODULE_LICENSE("GPL");
-module_init(pmbus_init);
-module_exit(pmbus_exit);
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 00460d8..b31f461 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -781,7 +781,7 @@ static ssize_t pmbus_set_sensor(struct device *dev,
 	int ret;
 	u16 regval;
 
-	if (strict_strtol(buf, 10, &val) < 0)
+	if (kstrtol(buf, 10, &val) < 0)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
diff --git a/drivers/hwmon/pmbus/ucd9000.c b/drivers/hwmon/pmbus/ucd9000.c
index 4ff6cf2..759a563 100644
--- a/drivers/hwmon/pmbus/ucd9000.c
+++ b/drivers/hwmon/pmbus/ucd9000.c
@@ -258,18 +258,8 @@ static struct i2c_driver ucd9000_driver = {
 	.id_table = ucd9000_id,
 };
 
-static int __init ucd9000_init(void)
-{
-	return i2c_add_driver(&ucd9000_driver);
-}
-
-static void __exit ucd9000_exit(void)
-{
-	i2c_del_driver(&ucd9000_driver);
-}
+module_i2c_driver(ucd9000_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx");
 MODULE_LICENSE("GPL");
-module_init(ucd9000_init);
-module_exit(ucd9000_exit);
diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c
index 6e1c1a8..629d0c9 100644
--- a/drivers/hwmon/pmbus/ucd9200.c
+++ b/drivers/hwmon/pmbus/ucd9200.c
@@ -190,18 +190,8 @@ static struct i2c_driver ucd9200_driver = {
 	.id_table = ucd9200_id,
 };
 
-static int __init ucd9200_init(void)
-{
-	return i2c_add_driver(&ucd9200_driver);
-}
-
-static void __exit ucd9200_exit(void)
-{
-	i2c_del_driver(&ucd9200_driver);
-}
+module_i2c_driver(ucd9200_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x");
 MODULE_LICENSE("GPL");
-module_init(ucd9200_init);
-module_exit(ucd9200_exit);
diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c
index 48c7b4a..0bb7bba 100644
--- a/drivers/hwmon/pmbus/zl6100.c
+++ b/drivers/hwmon/pmbus/zl6100.c
@@ -268,18 +268,8 @@ static struct i2c_driver zl6100_driver = {
 	.id_table = zl6100_id,
 };
 
-static int __init zl6100_init(void)
-{
-	return i2c_add_driver(&zl6100_driver);
-}
-
-static void __exit zl6100_exit(void)
-{
-	i2c_del_driver(&zl6100_driver);
-}
+module_i2c_driver(zl6100_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("PMBus driver for ZL6100 and compatibles");
 MODULE_LICENSE("GPL");
-module_init(zl6100_init);
-module_exit(zl6100_exit);
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 91fdd1f..8b011d0 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -806,7 +806,7 @@ static void sht15_bh_read_data(struct work_struct *work_s)
 		 */
 		atomic_set(&data->interrupt_handled, 0);
 		enable_irq(gpio_to_irq(data->pdata->gpio_data));
-		/* If still not occurred or another handler has been scheduled */
+		/* If still not occurred or another handler was scheduled */
 		if (gpio_get_value(data->pdata->gpio_data)
 		    || atomic_read(&data->interrupt_handled))
 			return;
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index 1539878..6c2dede 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -261,28 +261,7 @@ static struct i2c_driver sht21_driver = {
 	.id_table    = sht21_id,
 };
 
-/**
- * sht21_init() - initialize driver
- *
- * Called when kernel is booted or module is inserted.
- * Returns 0 on success.
- */
-static int __init sht21_init(void)
-{
-	return i2c_add_driver(&sht21_driver);
-}
-module_init(sht21_init);
-
-/**
- * sht21_init() - clean up driver
- *
- * Called when module is removed.
- */
-static void __exit sht21_exit(void)
-{
-	i2c_del_driver(&sht21_driver);
-}
-module_exit(sht21_exit);
+module_i2c_driver(sht21_driver);
 
 MODULE_AUTHOR("Urs Fleisch <urs.fleisch@sensirion.com>");
 MODULE_DESCRIPTION("Sensirion SHT21 humidity and temperature sensor driver");
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 47d7ce9..6c4d8eb 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -1,54 +1,54 @@
 /*
-    sis5595.c - Part of lm_sensors, Linux kernel modules
-		for hardware monitoring
-
-    Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
-			Kyösti Mälkki <kmalkki@cc.hut.fi>, and
-			Mark D. Studebaker <mdsxyz123@yahoo.com>
-    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
-    the help of Jean Delvare <khali@linux-fr.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.
-*/
+ * sis5595.c - Part of lm_sensors, Linux kernel modules
+ *	       for hardware monitoring
+ *
+ * Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
+ *			     Kyösti Mälkki <kmalkki@cc.hut.fi>, and
+ *			     Mark D. Studebaker <mdsxyz123@yahoo.com>
+ * Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+ * the help of Jean Delvare <khali@linux-fr.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.
+ */
 
 /*
-   SiS southbridge has a LM78-like chip integrated on the same IC.
-   This driver is a customized copy of lm78.c
-   
-   Supports following revisions:
-	Version		PCI ID		PCI Revision
-	1		1039/0008	AF or less
-	2		1039/0008	B0 or greater
-
-   Note: these chips contain a 0008 device which is incompatible with the
-	 5595. We recognize these by the presence of the listed
-	 "blacklist" PCI ID and refuse to load.
-
-   NOT SUPPORTED	PCI ID		BLACKLIST PCI ID	
-	 540		0008		0540
-	 550		0008		0550
-	5513		0008		5511
-	5581		0008		5597
-	5582		0008		5597
-	5597		0008		5597
-	5598		0008		5597/5598
-	 630		0008		0630
-	 645		0008		0645
-	 730		0008		0730
-	 735		0008		0735
-*/
+ * SiS southbridge has a LM78-like chip integrated on the same IC.
+ * This driver is a customized copy of lm78.c
+ *
+ * Supports following revisions:
+ *	Version		PCI ID		PCI Revision
+ *	1		1039/0008	AF or less
+ *	2		1039/0008	B0 or greater
+ *
+ *  Note: these chips contain a 0008 device which is incompatible with the
+ *	 5595. We recognize these by the presence of the listed
+ *	 "blacklist" PCI ID and refuse to load.
+ *
+ * NOT SUPPORTED	PCI ID		BLACKLIST PCI ID
+ *	 540		0008		0540
+ *	 550		0008		0550
+ *	5513		0008		5511
+ *	5581		0008		5597
+ *	5582		0008		5597
+ *	5597		0008		5597
+ *	5598		0008		5597/5598
+ *	 630		0008		0630
+ *	 645		0008		0645
+ *	 730		0008		0730
+ *	 735		0008		0735
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -68,8 +68,10 @@
 #include <linux/io.h>
 
 
-/* If force_addr is set to anything different from 0, we forcibly enable
-   the device at the given address. */
+/*
+ * If force_addr is set to anything different from 0, we forcibly enable
+ * the device at the given address.
+ */
 static u16 force_addr;
 module_param(force_addr, ushort, 0);
 MODULE_PARM_DESC(force_addr,
@@ -98,30 +100,36 @@ static struct platform_device *pdev;
 #define SIS5595_REG_FAN_MIN(nr) (0x3b + (nr))
 #define SIS5595_REG_FAN(nr) (0x28 + (nr))
 
-/* On the first version of the chip, the temp registers are separate.
-   On the second version,
-   TEMP pin is shared with IN4, configured in PCI register 0x7A.
-   The registers are the same as well.
-   OVER and HYST are really MAX and MIN. */
+/*
+ * On the first version of the chip, the temp registers are separate.
+ * On the second version,
+ * TEMP pin is shared with IN4, configured in PCI register 0x7A.
+ * The registers are the same as well.
+ * OVER and HYST are really MAX and MIN.
+ */
 
 #define REV2MIN	0xb0
-#define SIS5595_REG_TEMP 	(( data->revision) >= REV2MIN) ? \
-					SIS5595_REG_IN(4) : 0x27
-#define SIS5595_REG_TEMP_OVER	(( data->revision) >= REV2MIN) ? \
-					SIS5595_REG_IN_MAX(4) : 0x39
-#define SIS5595_REG_TEMP_HYST	(( data->revision) >= REV2MIN) ? \
-					SIS5595_REG_IN_MIN(4) : 0x3a
+#define SIS5595_REG_TEMP	(((data->revision) >= REV2MIN) ? \
+					SIS5595_REG_IN(4) : 0x27)
+#define SIS5595_REG_TEMP_OVER	(((data->revision) >= REV2MIN) ? \
+					SIS5595_REG_IN_MAX(4) : 0x39)
+#define SIS5595_REG_TEMP_HYST	(((data->revision) >= REV2MIN) ? \
+					SIS5595_REG_IN_MIN(4) : 0x3a)
 
 #define SIS5595_REG_CONFIG 0x40
 #define SIS5595_REG_ALARM1 0x41
 #define SIS5595_REG_ALARM2 0x42
 #define SIS5595_REG_FANDIV 0x47
 
-/* Conversions. Limit checking is only done on the TO_REG
-   variants. */
+/*
+ * Conversions. Limit checking is only done on the TO_REG
+ * variants.
+ */
 
-/* IN: mV, (0V to 4.08V)
-   REG: 16mV/bit */
+/*
+ * IN: mV, (0V to 4.08V)
+ * REG: 16mV/bit
+ */
 static inline u8 IN_TO_REG(unsigned long val)
 {
 	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
@@ -138,11 +146,13 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 
 static inline int FAN_FROM_REG(u8 val, int div)
 {
-	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+	return val == 0 ? -1 : val == 255 ? 0 : 1350000 / (val * div);
 }
 
-/* TEMP: mC (-54.12C to +157.53C)
-   REG: 0.83C/bit + 52.12, two's complement  */
+/*
+ * TEMP: mC (-54.12C to +157.53C)
+ * REG: 0.83C/bit + 52.12, two's complement
+ */
 static inline int TEMP_FROM_REG(s8 val)
 {
 	return val * 830 + 52120;
@@ -150,19 +160,23 @@ static inline int TEMP_FROM_REG(s8 val)
 static inline s8 TEMP_TO_REG(int val)
 {
 	int nval = SENSORS_LIMIT(val, -54120, 157530) ;
-	return nval<0 ? (nval-5212-415)/830 : (nval-5212+415)/830;
+	return nval < 0 ? (nval - 5212 - 415) / 830 : (nval - 5212 + 415) / 830;
 }
 
-/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
-   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
+/*
+ * FAN DIV: 1, 2, 4, or 8 (defaults to 2)
+ * REG: 0, 1, 2, or 3 (respectively) (defaults to 1)
+ */
 static inline u8 DIV_TO_REG(int val)
 {
-	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
+	return val == 8 ? 3 : val == 4 ? 2 : val == 1 ? 0 : 1;
 }
 #define DIV_FROM_REG(val) (1 << (val))
 
-/* For each registered chip, we need to keep some data in memory.
-   The structure is dynamically allocated. */
+/*
+ * For each registered chip, we need to keep some data in memory.
+ * The structure is dynamically allocated.
+ */
 struct sis5595_data {
 	unsigned short addr;
 	const char *name;
@@ -240,7 +254,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
 	struct sis5595_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val);
@@ -255,7 +274,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
 	struct sis5595_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val);
@@ -279,22 +303,30 @@ show_in_offset(3);
 show_in_offset(4);
 
 /* Temperature */
-static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+			 char *buf)
 {
 	struct sis5595_data *data = sis5595_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
 }
 
-static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr,
+			      char *buf)
 {
 	struct sis5595_data *data = sis5595_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
 }
 
-static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 	struct sis5595_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_over = TEMP_TO_REG(val);
@@ -303,16 +335,23 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr,
+			      char *buf)
 {
 	struct sis5595_data *data = sis5595_update_device(dev);
 	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
 }
 
-static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
 {
 	struct sis5595_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_hyst = TEMP_TO_REG(val);
@@ -335,7 +374,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
+		DIV_FROM_REG(data->fan_div[nr])));
 }
 
 static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
@@ -344,8 +383,8 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
 	struct sis5595_data *data = sis5595_update_device(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])));
 }
 
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
@@ -354,7 +393,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
 	struct sis5595_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -369,13 +413,15 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
 	struct sis5595_data *data = sis5595_update_device(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 			   const char *buf, size_t count)
 {
@@ -383,8 +429,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
 	unsigned long min;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	min = FAN_FROM_REG(data->fan_min[nr],
@@ -392,17 +443,25 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 	reg = sis5595_read_value(data, SIS5595_REG_FANDIV);
 
 	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
+	case 1:
+		data->fan_div[nr] = 0;
+		break;
+	case 2:
+		data->fan_div[nr] = 1;
+		break;
+	case 4:
+		data->fan_div[nr] = 2;
+		break;
+	case 8:
+		data->fan_div[nr] = 3;
+		break;
 	default:
 		dev_err(dev, "fan_div value %ld not "
 			"supported. Choose one of 1, 2, 4 or 8!\n", val);
 		mutex_unlock(&data->update_lock);
 		return -EINVAL;
 	}
-	
+
 	switch (nr) {
 	case 0:
 		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
@@ -431,7 +490,8 @@ show_fan_offset(1);
 show_fan_offset(2);
 
 /* Alarms */
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+			   char *buf)
 {
 	struct sis5595_data *data = sis5595_update_device(dev);
 	return sprintf(buf, "%d\n", data->alarms);
@@ -521,7 +581,7 @@ static struct attribute *sis5595_attributes_temp1[] = {
 static const struct attribute_group sis5595_group_temp1 = {
 	.attrs = sis5595_attributes_temp1,
 };
- 
+
 /* This is called when the module is loaded */
 static int __devinit sis5595_probe(struct platform_device *pdev)
 {
@@ -539,7 +599,8 @@ static int __devinit sis5595_probe(struct platform_device *pdev)
 		goto exit;
 	}
 
-	if (!(data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct sis5595_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto exit_release;
 	}
@@ -550,7 +611,9 @@ static int __devinit sis5595_probe(struct platform_device *pdev)
 	data->name = "sis5595";
 	platform_set_drvdata(pdev, data);
 
-	/* Check revision and pin registers to determine whether 4 or 5 voltages */
+	/*
+	 * Check revision and pin registers to determine whether 4 or 5 voltages
+	 */
 	data->revision = s_bridge->revision;
 	/* 4 voltages, 1 temp */
 	data->maxins = 3;
@@ -560,7 +623,7 @@ static int __devinit sis5595_probe(struct platform_device *pdev)
 			/* 5 voltages, no temps */
 			data->maxins = 4;
 	}
-	
+
 	/* Initialize the SIS5595 chip */
 	sis5595_init_device(data);
 
@@ -571,15 +634,16 @@ static int __devinit sis5595_probe(struct platform_device *pdev)
 	}
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group)))
+	err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group);
+	if (err)
 		goto exit_free;
 	if (data->maxins == 4) {
-		if ((err = sysfs_create_group(&pdev->dev.kobj,
-					      &sis5595_group_in4)))
+		err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group_in4);
+		if (err)
 			goto exit_remove_files;
 	} else {
-		if ((err = sysfs_create_group(&pdev->dev.kobj,
-					      &sis5595_group_temp1)))
+		err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group_temp1);
+		if (err)
 			goto exit_remove_files;
 	}
 
@@ -699,7 +763,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev)
 	return data;
 }
 
-static const struct pci_device_id sis5595_pci_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(sis5595_pci_ids) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
 	{ 0, }
 };
@@ -713,9 +777,11 @@ static int blacklist[] __devinitdata = {
 	PCI_DEVICE_ID_SI_645,
 	PCI_DEVICE_ID_SI_730,
 	PCI_DEVICE_ID_SI_735,
-	PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but
-				  that ID shows up in other chips so we
-				  use the 5511 ID for recognition */
+	PCI_DEVICE_ID_SI_5511, /*
+				* 5513 chip has the 0008 device but
+				* that ID shows up in other chips so we
+				* use the 5511 ID for recognition
+				*/
 	PCI_DEVICE_ID_SI_5597,
 	PCI_DEVICE_ID_SI_5598,
 	0 };
@@ -770,13 +836,16 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev,
 
 	for (i = blacklist; *i != 0; i++) {
 		struct pci_dev *d;
-		if ((d = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL))) {
-			dev_err(&d->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
+		d = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
+		if (d) {
+			dev_err(&d->dev,
+				"Looked for SIS5595 but found unsupported device %.4x\n",
+				*i);
 			pci_dev_put(d);
 			return -ENODEV;
 		}
 	}
-	
+
 	force_addr &= ~(SIS5595_EXTENT - 1);
 	if (force_addr) {
 		dev_warn(&dev->dev, "Forcing ISA address 0x%x\n", force_addr);
@@ -788,10 +857,11 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev,
 		dev_err(&dev->dev, "Failed to read ISA address\n");
 		return -ENODEV;
 	}
-	
+
 	address &= ~(SIS5595_EXTENT - 1);
 	if (!address) {
-		dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n");
+		dev_err(&dev->dev,
+			"Base address not set - upgrade BIOS or use force_addr=0xaddr\n");
 		return -ENODEV;
 	}
 	if (force_addr && address != force_addr) {
@@ -828,7 +898,8 @@ static int __devinit sis5595_pci_probe(struct pci_dev *dev,
 	if (sis5595_device_add(address))
 		goto exit_unregister;
 
-	/* Always return failure here.  This is to allow other drivers to bind
+	/*
+	 * Always return failure here.  This is to allow other drivers to bind
 	 * to this pci device.  We don't really want to have control over the
 	 * pci device, we only wanted to read as few register values from it.
 	 */
diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c
index 4116381..5877078 100644
--- a/drivers/hwmon/smm665.c
+++ b/drivers/hwmon/smm665.c
@@ -124,9 +124,9 @@ enum chips { smm465, smm665, smm665c, smm764, smm766 };
 #define SMM665_AIN_ADC_TO_VOLTS(adc)   ((adc) * vref / 512)
 
 /* Temp Sensor */
-#define SMM665_TEMP_ADC_TO_CELSIUS(adc) ((adc) <= 511) ?		   \
+#define SMM665_TEMP_ADC_TO_CELSIUS(adc) (((adc) <= 511) ?		   \
 					 ((int)(adc) * 1000 / 4) :	   \
-					 (((int)(adc) - 0x400) * 1000 / 4)
+					 (((int)(adc) - 0x400) * 1000 / 4))
 
 #define SMM665_NUM_ADC		11
 
@@ -376,7 +376,7 @@ static ssize_t smm665_show_input(struct device *dev,
 }
 
 #define SMM665_SHOW(what) \
-  static ssize_t smm665_show_##what(struct device *dev, \
+static ssize_t smm665_show_##what(struct device *dev, \
 				    struct device_attribute *da, char *buf) \
 { \
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
@@ -389,7 +389,8 @@ SMM665_SHOW(max);
 SMM665_SHOW(lcrit);
 SMM665_SHOW(crit);
 
-/* These macros are used below in constructing device attribute objects
+/*
+ * These macros are used below in constructing device attribute objects
  * for use with sysfs_create_group() to make a sysfs device file
  * for each register.
  */
@@ -718,19 +719,8 @@ static struct i2c_driver smm665_driver = {
 	.id_table = smm665_id,
 };
 
-static int __init smm665_init(void)
-{
-	return i2c_add_driver(&smm665_driver);
-}
-
-static void __exit smm665_exit(void)
-{
-	i2c_del_driver(&smm665_driver);
-}
+module_i2c_driver(smm665_driver);
 
 MODULE_AUTHOR("Guenter Roeck");
 MODULE_DESCRIPTION("SMM665 driver");
 MODULE_LICENSE("GPL");
-
-module_init(smm665_init);
-module_exit(smm665_exit);
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 65c88ff..d3b778d 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -1,30 +1,30 @@
 /*
-    smsc47b397.c - Part of lm_sensors, Linux kernel modules
-			for hardware monitoring
-
-    Supports the SMSC LPC47B397-NC Super-I/O chip.
-
-    Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
-	Copyright (C) 2004 Utilitek Systems, Inc.
-
-    derived in part from smsc47m1.c:
-	Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
-	Copyright (C) 2004 Jean Delvare <khali@linux-fr.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.
-*/
+ * smsc47b397.c - Part of lm_sensors, Linux kernel modules
+ * for hardware monitoring
+ *
+ * Supports the SMSC LPC47B397-NC Super-I/O chip.
+ *
+ * Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
+ * Copyright (C) 2004 Utilitek Systems, Inc.
+ *
+ * derived in part from smsc47m1.c:
+ * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+ * Copyright (C) 2004 Jean Delvare <khali@linux-fr.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.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -157,8 +157,10 @@ static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
 	return data;
 }
 
-/* TEMP: 0.001C/bit (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: 0.001C/bit (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static int temp_from_reg(u8 reg)
 {
 	return (s8)reg * 1000;
@@ -177,8 +179,10 @@ static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
 
-/* FAN: 1 RPM/bit
-   REG: count of 90kHz pulses / revolution */
+/*
+ * FAN: 1 RPM/bit
+ * REG: count of 90kHz pulses / revolution
+ */
 static int fan_from_reg(u16 reg)
 {
 	if (reg == 0 || reg == 0xffff)
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index f44a89a..c590c14 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -1,30 +1,30 @@
 /*
-    smsc47m1.c - Part of lm_sensors, Linux kernel modules
-                 for hardware monitoring
-
-    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
-    LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997
-    Super-I/O chips.
-
-    Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
-    Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
-    Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
-                        and Jean Delvare
-
-    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.
-*/
+ * smsc47m1.c - Part of lm_sensors, Linux kernel modules
+ *		for hardware monitoring
+ *
+ * Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
+ * LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997
+ * Super-I/O chips.
+ *
+ * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+ * Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
+ * Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
+ *			and Jean Delvare
+ *
+ * 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.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -53,8 +53,8 @@ enum chips { smsc47m1, smsc47m2 };
 
 /* Super-I/0 registers and commands */
 
-#define	REG	0x2e	/* The register to read/write */
-#define	VAL	0x2f	/* The value to read/write */
+#define REG	0x2e	/* The register to read/write */
+#define VAL	0x2f	/* The value to read/write */
 
 static inline void
 superio_outb(int reg, int val)
@@ -111,10 +111,11 @@ static const u8 SMSC47M1_REG_PWM[3]		= { 0x56, 0x57, 0x69 };
 #define SMSC47M2_REG_PPIN3		0x2c
 #define SMSC47M2_REG_FANDIV3		0x6a
 
-#define MIN_FROM_REG(reg,div)		((reg)>=192 ? 0 : \
-					 983040/((192-(reg))*(div)))
-#define FAN_FROM_REG(reg,div,preload)	((reg)<=(preload) || (reg)==255 ? 0 : \
-					 983040/(((reg)-(preload))*(div)))
+#define MIN_FROM_REG(reg, div)		((reg) >= 192 ? 0 : \
+					 983040 / ((192 - (reg)) * (div)))
+#define FAN_FROM_REG(reg, div, preload)	((reg) <= (preload) || (reg) == 255 ? \
+					 0 : \
+					 983040 / (((reg) - (preload)) * (div)))
 #define DIV_FROM_REG(reg)		(1 << (reg))
 #define PWM_FROM_REG(reg)		(((reg) & 0x7E) << 1)
 #define PWM_EN_FROM_REG(reg)		((~(reg)) & 0x01)
@@ -171,10 +172,12 @@ static ssize_t get_fan(struct device *dev, struct device_attribute
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
 	int nr = attr->index;
-	/* This chip (stupidly) stops monitoring fan speed if PWM is
-	   enabled and duty cycle is 0%. This is fine if the monitoring
-	   and control concern the same fan, but troublesome if they are
-	   not (which could as well happen). */
+	/*
+	 * This chip (stupidly) stops monitoring fan speed if PWM is
+	 * enabled and duty cycle is 0%. This is fine if the monitoring
+	 * and control concern the same fan, but troublesome if they are
+	 * not (which could as well happen).
+	 */
 	int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
 		  FAN_FROM_REG(data->fan[nr],
 			       DIV_FROM_REG(data->fan_div[nr]),
@@ -238,7 +241,13 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct smsc47m1_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	long rpmdiv, val = simple_strtol(buf, NULL, 10);
+	long rpmdiv;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
@@ -256,28 +265,44 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
 	return count;
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan clock divider.  This follows the principle
-   of least surprise; the user doesn't expect the fan minimum to change just
-   because the divider changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan clock divider.  This follows the principle
+ * of least surprise; the user doesn't expect the fan minimum to change just
+ * because the divider changed.
+ */
 static ssize_t set_fan_div(struct device *dev, struct device_attribute
 			   *devattr, const char *buf, size_t count)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct smsc47m1_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	long new_div = simple_strtol(buf, NULL, 10), tmp;
+	long new_div;
+	int err;
+	long tmp;
 	u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
 
+	err = kstrtol(buf, 10, &new_div);
+	if (err)
+		return err;
+
 	if (new_div == old_div) /* No change */
 		return count;
 
 	mutex_lock(&data->update_lock);
 	switch (new_div) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
+	case 1:
+		data->fan_div[nr] = 0;
+		break;
+	case 2:
+		data->fan_div[nr] = 1;
+		break;
+	case 4:
+		data->fan_div[nr] = 2;
+		break;
+	case 8:
+		data->fan_div[nr] = 3;
+		break;
 	default:
 		mutex_unlock(&data->update_lock);
 		return -EINVAL;
@@ -315,7 +340,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct smsc47m1_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	if (val < 0 || val > 255)
 		return -EINVAL;
@@ -336,9 +366,14 @@ static ssize_t set_pwm_en(struct device *dev, struct device_attribute
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct smsc47m1_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	long val = simple_strtol(buf, NULL, 10);
-	
-	if (val != 0 && val != 1)
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	if (val > 1)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -380,30 +415,73 @@ static ssize_t show_name(struct device *dev, struct device_attribute
 }
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 
-/* Almost all sysfs files may or may not be created depending on the chip
-   setup so we create them individually. It is still convenient to define a
-   group to remove them all at once. */
-static struct attribute *smsc47m1_attributes[] = {
+static struct attribute *smsc47m1_attributes_fan1[] = {
 	&sensor_dev_attr_fan1_input.dev_attr.attr,
 	&sensor_dev_attr_fan1_min.dev_attr.attr,
 	&sensor_dev_attr_fan1_div.dev_attr.attr,
 	&sensor_dev_attr_fan1_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group smsc47m1_group_fan1 = {
+	.attrs = smsc47m1_attributes_fan1,
+};
+
+static struct attribute *smsc47m1_attributes_fan2[] = {
 	&sensor_dev_attr_fan2_input.dev_attr.attr,
 	&sensor_dev_attr_fan2_min.dev_attr.attr,
 	&sensor_dev_attr_fan2_div.dev_attr.attr,
 	&sensor_dev_attr_fan2_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group smsc47m1_group_fan2 = {
+	.attrs = smsc47m1_attributes_fan2,
+};
+
+static struct attribute *smsc47m1_attributes_fan3[] = {
 	&sensor_dev_attr_fan3_input.dev_attr.attr,
 	&sensor_dev_attr_fan3_min.dev_attr.attr,
 	&sensor_dev_attr_fan3_div.dev_attr.attr,
 	&sensor_dev_attr_fan3_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group smsc47m1_group_fan3 = {
+	.attrs = smsc47m1_attributes_fan3,
+};
 
+static struct attribute *smsc47m1_attributes_pwm1[] = {
 	&sensor_dev_attr_pwm1.dev_attr.attr,
 	&sensor_dev_attr_pwm1_enable.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group smsc47m1_group_pwm1 = {
+	.attrs = smsc47m1_attributes_pwm1,
+};
+
+static struct attribute *smsc47m1_attributes_pwm2[] = {
 	&sensor_dev_attr_pwm2.dev_attr.attr,
 	&sensor_dev_attr_pwm2_enable.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group smsc47m1_group_pwm2 = {
+	.attrs = smsc47m1_attributes_pwm2,
+};
+
+static struct attribute *smsc47m1_attributes_pwm3[] = {
 	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&sensor_dev_attr_pwm3_enable.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group smsc47m1_group_pwm3 = {
+	.attrs = smsc47m1_attributes_pwm3,
+};
 
+static struct attribute *smsc47m1_attributes[] = {
 	&dev_attr_alarms.attr,
 	&dev_attr_name.attr,
 	NULL
@@ -476,8 +554,10 @@ static int __init smsc47m1_find(unsigned short *addr,
 		return -ENODEV;
 	}
 
-	/* Enable only if address is set (needed at least on the
-	 * Compaq Presario S4000NX) */
+	/*
+	 * Enable only if address is set (needed at least on the
+	 * Compaq Presario S4000NX)
+	 */
 	sio_data->activate = superio_inb(SUPERIO_REG_ACT);
 	if ((sio_data->activate & 0x01) == 0) {
 		pr_info("Enabling device\n");
@@ -583,6 +663,17 @@ static int smsc47m1_handle_resources(unsigned short address, enum chips type,
 	return 0;
 }
 
+static void smsc47m1_remove_files(struct device *dev)
+{
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group);
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group_fan1);
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group_fan2);
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group_fan3);
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group_pwm1);
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group_pwm2);
+	sysfs_remove_group(&dev->kobj, &smsc47m1_group_pwm3);
+}
+
 static int __init smsc47m1_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -592,7 +683,7 @@ static int __init smsc47m1_probe(struct platform_device *pdev)
 	int err;
 	int fan1, fan2, fan3, pwm1, pwm2, pwm3;
 
-	static const char *names[] = {
+	static const char * const names[] = {
 		"smsc47m1",
 		"smsc47m2",
 	};
@@ -603,7 +694,8 @@ static int __init smsc47m1_probe(struct platform_device *pdev)
 	if (err < 0)
 		return err;
 
-	if (!(data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct smsc47m1_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto error_release;
 	}
@@ -614,8 +706,10 @@ static int __init smsc47m1_probe(struct platform_device *pdev)
 	mutex_init(&data->update_lock);
 	platform_set_drvdata(pdev, data);
 
-	/* If no function is properly configured, there's no point in
-	   actually registering the chip. */
+	/*
+	 * If no function is properly configured, there's no point in
+	 * actually registering the chip.
+	 */
 	pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05)
 	       == 0x04;
 	pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05)
@@ -643,84 +737,67 @@ static int __init smsc47m1_probe(struct platform_device *pdev)
 		goto error_free;
 	}
 
-	/* Some values (fan min, clock dividers, pwm registers) may be
-	   needed before any update is triggered, so we better read them
-	   at least once here. We don't usually do it that way, but in
-	   this particular case, manually reading 5 registers out of 8
-	   doesn't make much sense and we're better using the existing
-	   function. */
+	/*
+	 * Some values (fan min, clock dividers, pwm registers) may be
+	 * needed before any update is triggered, so we better read them
+	 * at least once here. We don't usually do it that way, but in
+	 * this particular case, manually reading 5 registers out of 8
+	 * doesn't make much sense and we're better using the existing
+	 * function.
+	 */
 	smsc47m1_update_device(dev, 1);
 
 	/* Register sysfs hooks */
 	if (fan1) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_fan1_input.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan1_min.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan1_div.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan1_alarm.dev_attr)))
+		err = sysfs_create_group(&dev->kobj,
+					 &smsc47m1_group_fan1);
+		if (err)
 			goto error_remove_files;
 	} else
 		dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
 
 	if (fan2) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_fan2_input.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan2_min.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan2_div.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan2_alarm.dev_attr)))
+		err = sysfs_create_group(&dev->kobj,
+					 &smsc47m1_group_fan2);
+		if (err)
 			goto error_remove_files;
 	} else
 		dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
 
 	if (fan3) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_fan3_input.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan3_min.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan3_div.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_fan3_alarm.dev_attr)))
+		err = sysfs_create_group(&dev->kobj,
+					 &smsc47m1_group_fan3);
+		if (err)
 			goto error_remove_files;
 	} else if (data->type == smsc47m2)
 		dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
 
 	if (pwm1) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm1.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_pwm1_enable.dev_attr)))
+		err = sysfs_create_group(&dev->kobj,
+					 &smsc47m1_group_pwm1);
+		if (err)
 			goto error_remove_files;
 	} else
 		dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
 
 	if (pwm2) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm2.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_pwm2_enable.dev_attr)))
+		err = sysfs_create_group(&dev->kobj,
+					 &smsc47m1_group_pwm2);
+		if (err)
 			goto error_remove_files;
 	} else
 		dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
 
 	if (pwm3) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm3.dev_attr))
-		 || (err = device_create_file(dev,
-				&sensor_dev_attr_pwm3_enable.dev_attr)))
+		err = sysfs_create_group(&dev->kobj,
+					 &smsc47m1_group_pwm3);
+		if (err)
 			goto error_remove_files;
 	} else if (data->type == smsc47m2)
 		dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");
 
-	if ((err = device_create_file(dev, &dev_attr_alarms)))
-		goto error_remove_files;
-	if ((err = device_create_file(dev, &dev_attr_name)))
+	err = sysfs_create_group(&dev->kobj, &smsc47m1_group);
+	if (err)
 		goto error_remove_files;
 
 	data->hwmon_dev = hwmon_device_register(dev);
@@ -732,7 +809,7 @@ static int __init smsc47m1_probe(struct platform_device *pdev)
 	return 0;
 
 error_remove_files:
-	sysfs_remove_group(&dev->kobj, &smsc47m1_group);
+	smsc47m1_remove_files(dev);
 error_free:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
@@ -747,7 +824,7 @@ static int __exit smsc47m1_remove(struct platform_device *pdev)
 	struct resource *res;
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
+	smsc47m1_remove_files(&pdev->dev);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	smsc47m1_handle_resources(res->start, data->type, RELEASE, &pdev->dev);
diff --git a/drivers/hwmon/smsc47m192.c b/drivers/hwmon/smsc47m192.c
index 40b2667..4705a8b 100644
--- a/drivers/hwmon/smsc47m192.c
+++ b/drivers/hwmon/smsc47m192.c
@@ -1,25 +1,25 @@
 /*
-    smsc47m192.c - Support for hardware monitoring block of
-                   SMSC LPC47M192 and compatible Super I/O chips
-
-    Copyright (C) 2006  Hartmut Rick <linux@rick.claranet.de>
-
-    Derived from lm78.c and other chip drivers.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.
-*/
+ * smsc47m192.c - Support for hardware monitoring block of
+ *		  SMSC LPC47M192 and compatible Super I/O chips
+ *
+ * Copyright (C) 2006  Hartmut Rick <linux@rick.claranet.de>
+ *
+ * Derived from lm78.c and other chip drivers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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>
@@ -37,16 +37,16 @@
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
 
 /* SMSC47M192 registers */
-#define SMSC47M192_REG_IN(nr)		((nr)<6 ? (0x20 + (nr)) : \
+#define SMSC47M192_REG_IN(nr)		((nr) < 6 ? (0x20 + (nr)) : \
 					(0x50 + (nr) - 6))
-#define SMSC47M192_REG_IN_MAX(nr)	((nr)<6 ? (0x2b + (nr) * 2) : \
+#define SMSC47M192_REG_IN_MAX(nr)	((nr) < 6 ? (0x2b + (nr) * 2) : \
 					(0x54 + (((nr) - 6) * 2)))
-#define SMSC47M192_REG_IN_MIN(nr)	((nr)<6 ? (0x2c + (nr) * 2) : \
+#define SMSC47M192_REG_IN_MIN(nr)	((nr) < 6 ? (0x2c + (nr) * 2) : \
 					(0x55 + (((nr) - 6) * 2)))
 static u8 SMSC47M192_REG_TEMP[3] =	{ 0x27, 0x26, 0x52 };
 static u8 SMSC47M192_REG_TEMP_MAX[3] =	{ 0x39, 0x37, 0x58 };
 static u8 SMSC47M192_REG_TEMP_MIN[3] =	{ 0x3A, 0x38, 0x59 };
-#define SMSC47M192_REG_TEMP_OFFSET(nr)	((nr)==2 ? 0x1e : 0x1f)
+#define SMSC47M192_REG_TEMP_OFFSET(nr)	((nr) == 2 ? 0x1e : 0x1f)
 #define SMSC47M192_REG_ALARM1		0x41
 #define SMSC47M192_REG_ALARM2		0x42
 #define SMSC47M192_REG_VID		0x47
@@ -80,8 +80,10 @@ static inline u8 IN_TO_REG(unsigned long val, int n)
 	return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255);
 }
 
-/* TEMP: 0.001 degC units (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: 0.001 degC units (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static inline s8 TEMP_TO_REG(int val)
 {
 	return SENSORS_LIMIT(SCALE(val, 1, 1000), -128000, 127000);
@@ -170,7 +172,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct smsc47m192_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val, nr);
@@ -187,7 +194,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct smsc47m192_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val, nr);
@@ -249,7 +261,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct smsc47m192_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[nr] = TEMP_TO_REG(val);
@@ -266,7 +283,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct smsc47m192_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[nr] = TEMP_TO_REG(val);
@@ -293,22 +315,29 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute
 	struct i2c_client *client = to_i2c_client(dev);
 	struct smsc47m192_data *data = i2c_get_clientdata(client);
 	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_offset[nr] = TEMP_TO_REG(val);
-	if (nr>1)
+	if (nr > 1)
 		i2c_smbus_write_byte_data(client,
 			SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
 	else if (data->temp_offset[nr] != 0) {
-		/* offset[0] and offset[1] share the same register,
-			SFR bit 4 activates offset[0] */
+		/*
+		 * offset[0] and offset[1] share the same register,
+		 * SFR bit 4 activates offset[0]
+		 */
 		i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
-					(sfr & 0xef) | (nr==0 ? 0x10 : 0));
+					(sfr & 0xef) | (nr == 0 ? 0x10 : 0));
 		data->temp_offset[1-nr] = 0;
 		i2c_smbus_write_byte_data(client,
 			SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
-	} else if ((sfr & 0x10) == (nr==0 ? 0x10 : 0))
+	} else if ((sfr & 0x10) == (nr == 0 ? 0x10 : 0))
 		i2c_smbus_write_byte_data(client,
 					SMSC47M192_REG_TEMP_OFFSET(nr), 0);
 	mutex_unlock(&data->update_lock);
@@ -349,7 +378,14 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct smsc47m192_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	data->vrm = val;
 	return count;
 }
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
@@ -458,13 +494,13 @@ static void smsc47m192_init_client(struct i2c_client *client)
 						(sfr & 0xfd) | 0x02);
 	if (!(config & 0x01)) {
 		/* initialize alarm limits */
-		for (i=0; i<8; i++) {
+		for (i = 0; i < 8; i++) {
 			i2c_smbus_write_byte_data(client,
 				SMSC47M192_REG_IN_MIN(i), 0);
 			i2c_smbus_write_byte_data(client,
 				SMSC47M192_REG_IN_MAX(i), 0xff);
 		}
-		for (i=0; i<3; i++) {
+		for (i = 0; i < 3; i++) {
 			i2c_smbus_write_byte_data(client,
 				SMSC47M192_REG_TEMP_MIN[i], 0x80);
 			i2c_smbus_write_byte_data(client,
@@ -532,14 +568,16 @@ static int smsc47m192_probe(struct i2c_client *client,
 	smsc47m192_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group)))
+	err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group);
+	if (err)
 		goto exit_free;
 
 	/* Pin 110 is either in4 (+12V) or VID4 */
 	config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
 	if (!(config & 0x20)) {
-		if ((err = sysfs_create_group(&client->dev.kobj,
-					      &smsc47m192_group_in4)))
+		err = sysfs_create_group(&client->dev.kobj,
+					 &smsc47m192_group_in4);
+		if (err)
 			goto exit_remove_files;
 	}
 
@@ -606,8 +644,10 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
 		for (i = 1; i < 3; i++)
 			data->temp_offset[i] = i2c_smbus_read_byte_data(client,
 						SMSC47M192_REG_TEMP_OFFSET(i));
-		/* first offset is temp_offset[0] if SFR bit 4 is set,
-					temp_offset[1] otherwise */
+		/*
+		 * first offset is temp_offset[0] if SFR bit 4 is set,
+		 * temp_offset[1] otherwise
+		 */
 		if (sfr & 0x10) {
 			data->temp_offset[0] = data->temp_offset[1];
 			data->temp_offset[1] = 0;
@@ -624,7 +664,7 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
 		data->alarms = i2c_smbus_read_byte_data(client,
 						SMSC47M192_REG_ALARM1) |
 			       (i2c_smbus_read_byte_data(client,
-		       				SMSC47M192_REG_ALARM2) << 8);
+						SMSC47M192_REG_ALARM2) << 8);
 
 		data->last_updated = jiffies;
 		data->valid = 1;
@@ -635,19 +675,8 @@ static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
 	return data;
 }
 
-static int __init smsc47m192_init(void)
-{
-	return i2c_add_driver(&smsc47m192_driver);
-}
-
-static void __exit smsc47m192_exit(void)
-{
-	i2c_del_driver(&smsc47m192_driver);
-}
+module_i2c_driver(smsc47m192_driver);
 
 MODULE_AUTHOR("Hartmut Rick <linux@rick.claranet.de>");
 MODULE_DESCRIPTION("SMSC47M192 driver");
 MODULE_LICENSE("GPL");
-
-module_init(smsc47m192_init);
-module_exit(smsc47m192_exit);
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 7dfb4de..add9f01 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -1,24 +1,24 @@
 /*
-    thmc50.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
-    Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and
-    Philip Edelbrock <phil@netroedge.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * thmc50.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	      monitoring
+ * Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
+ * Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and
+ * Philip Edelbrock <phil@netroedge.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -124,8 +124,13 @@ static ssize_t set_analog_out(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct thmc50_data *data = i2c_get_clientdata(client);
-	int tmp = simple_strtoul(buf, NULL, 10);
 	int config;
+	unsigned long tmp;
+	int err;
+
+	err = kstrtoul(buf, 10, &tmp);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->analog_out = SENSORS_LIMIT(tmp, 0, 255);
@@ -173,7 +178,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct thmc50_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[nr] = SENSORS_LIMIT(val / 1000, -128, 127);
@@ -197,7 +207,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct thmc50_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[nr] = SENSORS_LIMIT(val / 1000, -128, 127);
@@ -360,14 +375,16 @@ static int thmc50_probe(struct i2c_client *client,
 	thmc50_init_client(client);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &thmc50_group)))
+	err = sysfs_create_group(&client->dev.kobj, &thmc50_group);
+	if (err)
 		goto exit_free;
 
 	/* Register ADM1022 sysfs hooks */
-	if (data->has_temp3)
-		if ((err = sysfs_create_group(&client->dev.kobj,
-					      &temp3_group)))
+	if (data->has_temp3) {
+		err = sysfs_create_group(&client->dev.kobj, &temp3_group);
+		if (err)
 			goto exit_remove_sysfs_thmc50;
+	}
 
 	/* Register a new directory entry with module sensors */
 	data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -465,18 +482,7 @@ static struct thmc50_data *thmc50_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sm_thmc50_init(void)
-{
-	return i2c_add_driver(&thmc50_driver);
-}
-
-static void __exit sm_thmc50_exit(void)
-{
-	i2c_del_driver(&thmc50_driver);
-}
+module_i2c_driver(thmc50_driver);
 
 MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
 MODULE_DESCRIPTION("THMC50 driver");
-
-module_init(sm_thmc50_init);
-module_exit(sm_thmc50_exit);
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index c08eee2..0d466b9 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -292,17 +292,7 @@ static struct i2c_driver tmp102_driver = {
 	.id_table	= tmp102_id,
 };
 
-static int __init tmp102_init(void)
-{
-	return i2c_add_driver(&tmp102_driver);
-}
-module_init(tmp102_init);
-
-static void __exit tmp102_exit(void)
-{
-	i2c_del_driver(&tmp102_driver);
-}
-module_exit(tmp102_exit);
+module_i2c_driver(tmp102_driver);
 
 MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
 MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver");
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
index 8b9a774..ea54c33 100644
--- a/drivers/hwmon/tmp401.c
+++ b/drivers/hwmon/tmp401.c
@@ -624,7 +624,7 @@ static int tmp401_probe(struct i2c_client *client,
 			goto exit_remove;
 	}
 
-	/* Register aditional tmp411 sysfs hooks */
+	/* Register additional tmp411 sysfs hooks */
 	if (data->kind == tmp411) {
 		for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) {
 			err = device_create_file(&client->dev,
@@ -662,19 +662,8 @@ static struct i2c_driver tmp401_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init tmp401_init(void)
-{
-	return i2c_add_driver(&tmp401_driver);
-}
-
-static void __exit tmp401_exit(void)
-{
-	i2c_del_driver(&tmp401_driver);
-}
+module_i2c_driver(tmp401_driver);
 
 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver");
 MODULE_LICENSE("GPL");
-
-module_init(tmp401_init);
-module_exit(tmp401_exit);
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
index c48381f..8fac87a 100644
--- a/drivers/hwmon/tmp421.c
+++ b/drivers/hwmon/tmp421.c
@@ -324,20 +324,9 @@ static struct i2c_driver tmp421_driver = {
 	.address_list = normal_i2c,
 };
 
-static int __init tmp421_init(void)
-{
-	return i2c_add_driver(&tmp421_driver);
-}
-
-static void __exit tmp421_exit(void)
-{
-	i2c_del_driver(&tmp421_driver);
-}
+module_i2c_driver(tmp421_driver);
 
 MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
 MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor"
 		   " driver");
 MODULE_LICENSE("GPL");
-
-module_init(tmp421_init);
-module_exit(tmp421_exit);
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c
index b9a87e8..c315c59 100644
--- a/drivers/hwmon/ultra45_env.c
+++ b/drivers/hwmon/ultra45_env.c
@@ -1,4 +1,5 @@
-/* ultra45_env.c: Driver for Ultra45 PIC16F747 environmental monitor.
+/*
+ * ultra45_env.c: Driver for Ultra45 PIC16F747 environmental monitor.
  *
  * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
  */
@@ -82,7 +83,8 @@ static void env_write(struct env *p, u8 ireg, u8 val)
 	spin_unlock(&p->lock);
 }
 
-/* There seems to be a adr7462 providing these values, thus a lot
+/*
+ * There seems to be a adr7462 providing these values, thus a lot
  * of these calculations are borrowed from the adt7470 driver.
  */
 #define FAN_PERIOD_TO_RPM(x)	((90000 * 60) / (x))
@@ -90,7 +92,8 @@ static void env_write(struct env *p, u8 ireg, u8 val)
 #define FAN_PERIOD_INVALID	(0xff << 8)
 #define FAN_DATA_VALID(x)	((x) && (x) != FAN_PERIOD_INVALID)
 
-static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr,
+			      char *buf)
 {
 	int fan_nr = to_sensor_dev_attr(attr)->index;
 	struct env *p = dev_get_drvdata(dev);
@@ -111,10 +114,15 @@ static ssize_t set_fan_speed(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 {
 	int fan_nr = to_sensor_dev_attr(attr)->index;
-	int rpm = simple_strtol(buf, NULL, 10);
+	unsigned long rpm;
 	struct env *p = dev_get_drvdata(dev);
 	int period;
 	u8 val;
+	int err;
+
+	err = kstrtoul(buf, 10, &rpm);
+	if (err)
+		return err;
 
 	if (!rpm)
 		return -EINVAL;
@@ -126,7 +134,8 @@ static ssize_t set_fan_speed(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-static ssize_t show_fan_fault(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_fan_fault(struct device *dev, struct device_attribute *attr,
+			      char *buf)
 {
 	int fan_nr = to_sensor_dev_attr(attr)->index;
 	struct env *p = dev_get_drvdata(dev);
@@ -148,7 +157,8 @@ fan(4);
 
 static SENSOR_DEVICE_ATTR(psu_fan_fault, S_IRUGO, show_fan_fault, NULL, 6);
 
-static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+			 char *buf)
 {
 	int temp_nr = to_sensor_dev_attr(attr)->index;
 	struct env *p = dev_get_drvdata(dev);
@@ -168,7 +178,8 @@ static SENSOR_DEVICE_ATTR(lsi1064_local_temp, S_IRUGO, show_temp, NULL, 6);
 static SENSOR_DEVICE_ATTR(front_panel_temp, S_IRUGO, show_temp, NULL, 7);
 static SENSOR_DEVICE_ATTR(psu_temp, S_IRUGO, show_temp, NULL, 13);
 
-static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr,
+			     char *buf)
 {
 	int index = to_sensor_dev_attr(attr)->index;
 	struct env *p = dev_get_drvdata(dev);
@@ -181,9 +192,11 @@ static ssize_t show_stat_bit(struct device *dev, struct device_attribute *attr,
 static SENSOR_DEVICE_ATTR(fan_failure, S_IRUGO, show_stat_bit, NULL, 0);
 static SENSOR_DEVICE_ATTR(env_bus_busy, S_IRUGO, show_stat_bit, NULL, 1);
 static SENSOR_DEVICE_ATTR(env_data_stale, S_IRUGO, show_stat_bit, NULL, 2);
-static SENSOR_DEVICE_ATTR(tpm_self_test_passed, S_IRUGO, show_stat_bit, NULL, 3);
+static SENSOR_DEVICE_ATTR(tpm_self_test_passed, S_IRUGO, show_stat_bit, NULL,
+			  3);
 
-static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_fwver(struct device *dev, struct device_attribute *attr,
+			  char *buf)
 {
 	struct env *p = dev_get_drvdata(dev);
 	u8 val;
@@ -194,7 +207,8 @@ static ssize_t show_fwver(struct device *dev, struct device_attribute *attr, cha
 
 static SENSOR_DEVICE_ATTR(firmware_version, S_IRUGO, show_fwver, NULL, 0);
 
-static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr,
+			 char *buf)
 {
 	return sprintf(buf, "ultra45\n");
 }
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 8eac67d..8689664 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -37,6 +37,7 @@
 #include <linux/cpu.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
+#include <asm/cpu_device_id.h>
 
 #define DRVNAME	"via_cputemp"
 
@@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = {
 	.notifier_call = via_cputemp_cpu_callback,
 };
 
+static const struct x86_cpu_id cputemp_ids[] = {
+	{ X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */
+	{ X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */
+	{ X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, cputemp_ids);
+
 static int __init via_cputemp_init(void)
 {
 	int i, err;
 
-	if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) {
-		printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n");
-		err = -ENODEV;
-		goto exit;
-	}
+	if (!x86_match_cpu(cputemp_ids))
+		return -ENODEV;
 
 	err = platform_driver_register(&via_cputemp_driver);
 	if (err)
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 25e9166..288135d 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -1,34 +1,35 @@
 /*
-    via686a.c - Part of lm_sensors, Linux kernel modules
-		for hardware monitoring
-
-    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
-			Kyösti Mälkki <kmalkki@cc.hut.fi>,
-			Mark Studebaker <mdsxyz123@yahoo.com>,
-			and Bob Dougherty <bobd@stanford.edu>
-    (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
-    <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
-
-    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.
-*/
+ * via686a.c - Part of lm_sensors, Linux kernel modules
+ *	       for hardware monitoring
+ *
+ * Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
+ *			      Kyösti Mälkki <kmalkki@cc.hut.fi>,
+ *			      Mark Studebaker <mdsxyz123@yahoo.com>,
+ *			      and Bob Dougherty <bobd@stanford.edu>
+ *
+ * (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
+ * <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
+ *
+ * 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.
+ */
 
 /*
-    Supports the Via VT82C686A, VT82C686B south bridges.
-    Reports all as a 686A.
-    Warning - only supports a single device.
-*/
+ * Supports the Via VT82C686A, VT82C686B south bridges.
+ * Reports all as a 686A.
+ * Warning - only supports a single device.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -47,8 +48,10 @@
 #include <linux/io.h>
 
 
-/* If force_addr is set to anything different from 0, we forcibly enable
-   the device at the given address. */
+/*
+ * If force_addr is set to anything different from 0, we forcibly enable
+ * the device at the given address.
+ */
 static unsigned short force_addr;
 module_param(force_addr, ushort, 0);
 MODULE_PARM_DESC(force_addr,
@@ -57,9 +60,9 @@ MODULE_PARM_DESC(force_addr,
 static struct platform_device *pdev;
 
 /*
-   The Via 686a southbridge has a LM78-like chip integrated on the same IC.
-   This driver is a customized copy of lm78.c
-*/
+ * The Via 686a southbridge has a LM78-like chip integrated on the same IC.
+ * This driver is a customized copy of lm78.c
+ */
 
 /* Many VIA686A constants specified below */
 
@@ -91,40 +94,46 @@ static const u8 VIA686A_REG_TEMP_HYST[]	= { 0x3a, 0x3e, 0x1e };
 #define VIA686A_REG_ALARM2	0x42
 #define VIA686A_REG_FANDIV	0x47
 #define VIA686A_REG_CONFIG	0x40
-/* The following register sets temp interrupt mode (bits 1-0 for temp1,
- 3-2 for temp2, 5-4 for temp3).  Modes are:
-    00 interrupt stays as long as value is out-of-range
-    01 interrupt is cleared once register is read (default)
-    10 comparator mode- like 00, but ignores hysteresis
-    11 same as 00 */
+/*
+ * The following register sets temp interrupt mode (bits 1-0 for temp1,
+ * 3-2 for temp2, 5-4 for temp3).  Modes are:
+ * 00 interrupt stays as long as value is out-of-range
+ * 01 interrupt is cleared once register is read (default)
+ * 10 comparator mode- like 00, but ignores hysteresis
+ * 11 same as 00
+ */
 #define VIA686A_REG_TEMP_MODE		0x4b
 /* We'll just assume that you want to set all 3 simultaneously: */
 #define VIA686A_TEMP_MODE_MASK		0x3F
 #define VIA686A_TEMP_MODE_CONTINUOUS	0x00
 
-/* Conversions. Limit checking is only done on the TO_REG
-   variants.
-
-********* VOLTAGE CONVERSIONS (Bob Dougherty) ********
- From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
- voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
- voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
- voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
- voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
- voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
- in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
- That is:
- volts = (25*regVal+133)*factor
- regVal = (volts/factor-133)/25
- (These conversions were contributed by Jonathan Teh Soon Yew
- <j.teh@iname.com>) */
+/*
+ * Conversions. Limit checking is only done on the TO_REG
+ * variants.
+ *
+ ******** VOLTAGE CONVERSIONS (Bob Dougherty) ********
+ * From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
+ * voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
+ * voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
+ * voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
+ * voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
+ * voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
+ * in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
+ * That is:
+ * volts = (25*regVal+133)*factor
+ * regVal = (volts/factor-133)/25
+ * (These conversions were contributed by Jonathan Teh Soon Yew
+ * <j.teh@iname.com>)
+ */
 static inline u8 IN_TO_REG(long val, int inNum)
 {
-	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
-	   Rounding is done (120500 is actually 133000 - 12500).
-	   Remember that val is expressed in 0.001V/bit, which is why we divide
-	   by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
-	   for the constants. */
+	/*
+	 * To avoid floating point, we multiply constants by 10 (100 for +12V).
+	 * Rounding is done (120500 is actually 133000 - 12500).
+	 * Remember that val is expressed in 0.001V/bit, which is why we divide
+	 * by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
+	 * for the constants.
+	 */
 	if (inNum <= 1)
 		return (u8)
 		    SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
@@ -141,9 +150,11 @@ static inline u8 IN_TO_REG(long val, int inNum)
 
 static inline long IN_FROM_REG(u8 val, int inNum)
 {
-	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
-	   We also multiply them by 1000 because we want 0.001V/bit for the
-	   output value. Rounding is done. */
+	/*
+	 * To avoid floating point, we multiply constants by 10 (100 for +12V).
+	 * We also multiply them by 1000 because we want 0.001V/bit for the
+	 * output value. Rounding is done.
+	 */
 	if (inNum <= 1)
 		return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
 	else if (inNum == 2)
@@ -155,9 +166,11 @@ static inline long IN_FROM_REG(u8 val, int inNum)
 }
 
 /********* FAN RPM CONVERSIONS ********/
-/* Higher register values = slower fans (the fan's strobe gates a counter).
- But this chip saturates back at 0, not at 255 like all the other chips.
- So, 0 means 0 RPM */
+/*
+ * Higher register values = slower fans (the fan's strobe gates a counter).
+ * But this chip saturates back at 0, not at 255 like all the other chips.
+ * So, 0 means 0 RPM
+ */
 static inline u8 FAN_TO_REG(long rpm, int div)
 {
 	if (rpm == 0)
@@ -166,42 +179,45 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
 }
 
-#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
+#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (val) == 255 ? 0 : 1350000 / \
+				((val) * (div)))
 
 /******** TEMP CONVERSIONS (Bob Dougherty) *********/
-/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
-      if(temp<169)
-	      return double(temp)*0.427-32.08;
-      else if(temp>=169 && temp<=202)
-	      return double(temp)*0.582-58.16;
-      else
-	      return double(temp)*0.924-127.33;
-
- A fifth-order polynomial fits the unofficial data (provided by Alex van
- Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
- numbers on my machine (ie. they agree with what my BIOS tells me).
- Here's the fifth-order fit to the 8-bit data:
- temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
-	2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
-
- (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
- finding my typos in this formula!)
-
- Alas, none of the elegant function-fit solutions will work because we
- aren't allowed to use floating point in the kernel and doing it with
- integers doesn't provide enough precision.  So we'll do boring old
- look-up table stuff.  The unofficial data (see below) have effectively
- 7-bit resolution (they are rounded to the nearest degree).  I'm assuming
- that the transfer function of the device is monotonic and smooth, so a
- smooth function fit to the data will allow us to get better precision.
- I used the 5th-order poly fit described above and solved for
- VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
- precision.  (I could have done all 1024 values for our 10-bit readings,
- but the function is very linear in the useful range (0-80 deg C), so
- we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
- is the temp at via register values 0-255: */
-static const s16 tempLUT[] =
-{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
+/*
+ * linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
+ *	if(temp<169)
+ *		return double(temp)*0.427-32.08;
+ *	else if(temp>=169 && temp<=202)
+ *		return double(temp)*0.582-58.16;
+ *	else
+ *		return double(temp)*0.924-127.33;
+ *
+ * A fifth-order polynomial fits the unofficial data (provided by Alex van
+ * Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
+ * numbers on my machine (ie. they agree with what my BIOS tells me).
+ * Here's the fifth-order fit to the 8-bit data:
+ * temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
+ *	2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
+ *
+ * (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
+ * finding my typos in this formula!)
+ *
+ * Alas, none of the elegant function-fit solutions will work because we
+ * aren't allowed to use floating point in the kernel and doing it with
+ * integers doesn't provide enough precision.  So we'll do boring old
+ * look-up table stuff.  The unofficial data (see below) have effectively
+ * 7-bit resolution (they are rounded to the nearest degree).  I'm assuming
+ * that the transfer function of the device is monotonic and smooth, so a
+ * smooth function fit to the data will allow us to get better precision.
+ * I used the 5th-order poly fit described above and solved for
+ * VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
+ * precision.  (I could have done all 1024 values for our 10-bit readings,
+ * but the function is very linear in the useful range (0-80 deg C), so
+ * we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
+ * is the temp at via register values 0-255:
+ */
+static const s16 tempLUT[] = {
+	-709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
 	-503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
 	-362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
 	-255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
@@ -225,29 +241,31 @@ static const s16 tempLUT[] =
 	1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
 };
 
-/* the original LUT values from Alex van Kaam <darkside@chello.nl>
-   (for via register values 12-240):
-{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
--30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
--15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
--3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
-12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
-22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
-33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
-45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
-61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
-85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
-
-
- Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
- an extra term for a good fit to these inverse data!) and then
- solving for each temp value from -50 to 110 (the useable range for
- this chip).  Here's the fit:
- viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
- - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
- Note that n=161: */
-static const u8 viaLUT[] =
-{ 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
+/*
+ * the original LUT values from Alex van Kaam <darkside@chello.nl>
+ * (for via register values 12-240):
+ * {-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
+ * -30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
+ * -15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
+ * -3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
+ * 12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
+ * 22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
+ * 33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
+ * 45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
+ * 61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
+ * 85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
+ *
+ *
+ * Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
+ * an extra term for a good fit to these inverse data!) and then
+ * solving for each temp value from -50 to 110 (the useable range for
+ * this chip).  Here's the fit:
+ * viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
+ * - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
+ * Note that n=161:
+ */
+static const u8 viaLUT[] = {
+	12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
 	23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
 	41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
 	69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
@@ -262,9 +280,11 @@ static const u8 viaLUT[] =
 	239, 240
 };
 
-/* Converting temps to (8-bit) hyst and over registers
-   No interpolation here.
-   The +50 is because the temps start at -50 */
+/*
+ * Converting temps to (8-bit) hyst and over registers
+ * No interpolation here.
+ * The +50 is because the temps start at -50
+ */
 static inline u8 TEMP_TO_REG(long val)
 {
 	return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 :
@@ -290,10 +310,12 @@ static inline long TEMP_FROM_REG10(u16 val)
 }
 
 #define DIV_FROM_REG(val) (1 << (val))
-#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
+#define DIV_TO_REG(val) ((val) == 8 ? 3 : (val) == 4 ? 2 : (val) == 1 ? 0 : 1)
 
-/* For each registered chip, we need to keep some data in memory.
-   The structure is dynamically allocated. */
+/*
+ * For each registered chip, we need to keep some data in memory.
+ * The structure is dynamically allocated.
+ */
 struct via686a_data {
 	unsigned short addr;
 	const char *name;
@@ -365,7 +387,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
 	struct via686a_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val, nr);
@@ -379,7 +406,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
 	struct via686a_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val, nr);
@@ -429,7 +461,12 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
 	struct via686a_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_over[nr] = TEMP_TO_REG(val);
@@ -443,7 +480,12 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
 	struct via686a_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_hyst[nr] = TEMP_TO_REG(val);
@@ -471,7 +513,7 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
 	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-				DIV_FROM_REG(data->fan_div[nr])) );
+				DIV_FROM_REG(data->fan_div[nr])));
 }
 static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
 		char *buf) {
@@ -479,21 +521,27 @@ static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
 	return sprintf(buf, "%d\n",
-		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
+		FAN_FROM_REG(data->fan_min[nr],
+			     DIV_FROM_REG(data->fan_div[nr])));
 }
 static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
 		char *buf) {
 	struct via686a_data *data = via686a_update_device(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
 }
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
 		const char *buf, size_t count) {
 	struct via686a_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	int val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -506,8 +554,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 	struct via686a_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	int nr = attr->index;
-	int val = simple_strtol(buf, NULL, 10);
 	int old;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	old = via686a_read_value(data, VIA686A_REG_FANDIV);
@@ -530,10 +583,13 @@ show_fan_offset(1);
 show_fan_offset(2);
 
 /* Alarms */
-static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
 	struct via686a_data *data = via686a_update_device(dev);
 	return sprintf(buf, "%u\n", data->alarms);
 }
+
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
 static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
@@ -641,7 +697,8 @@ static int __devinit via686a_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	if (!(data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct via686a_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto exit_release;
 	}
@@ -655,7 +712,8 @@ static int __devinit via686a_probe(struct platform_device *pdev)
 	via686a_init_device(data);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&pdev->dev.kobj, &via686a_group)))
+	err = sysfs_create_group(&pdev->dev.kobj, &via686a_group);
+	if (err)
 		goto exit_free;
 
 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
@@ -748,10 +806,11 @@ static struct via686a_data *via686a_update_device(struct device *dev)
 			    via686a_read_value(data,
 					       VIA686A_REG_TEMP_HYST[i]);
 		}
-		/* add in lower 2 bits
-		   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
-		   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
-		   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
+		/*
+		 * add in lower 2 bits
+		 * temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
+		 * temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
+		 * temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
 		 */
 		data->temp[0] |= (via686a_read_value(data,
 						     VIA686A_REG_TEMP_LOW1)
@@ -777,11 +836,10 @@ static struct via686a_data *via686a_update_device(struct device *dev)
 	return data;
 }
 
-static const struct pci_device_id via686a_pci_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(via686a_pci_ids) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
-	{ 0, }
+	{ }
 };
-
 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
 
 static int __devinit via686a_device_add(unsigned short address)
@@ -872,7 +930,8 @@ static int __devinit via686a_pci_probe(struct pci_dev *dev,
 	if (via686a_device_add(address))
 		goto exit_unregister;
 
-	/* Always return failure here.  This is to allow other drivers to bind
+	/*
+	 * Always return failure here.  This is to allow other drivers to bind
 	 * to this pci device.  We don't really want to have control over the
 	 * pci device, we only wanted to read as few register values from it.
 	 */
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 49163d4..c2c5c72 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -151,8 +151,10 @@ struct vt1211_data {
 #define ISTEMP(ix, uch_config)	((ix) < 2 ? 1 : \
 				 ((uch_config) >> (ix)) & 1)
 
-/* in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the
-   driver according to the VT1211 BIOS porting guide */
+/*
+ * in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the
+ * driver according to the VT1211 BIOS porting guide
+ */
 #define IN_FROM_REG(ix, reg)	((reg) < 3 ? 0 : (ix) == 5 ? \
 				 (((reg) - 3) * 15882 + 479) / 958 : \
 				 (((reg) - 3) * 10000 + 479) / 958)
@@ -160,11 +162,13 @@ struct vt1211_data {
 				 ((val) * 958 + 7941) / 15882 + 3 : \
 				 ((val) * 958 + 5000) / 10000 + 3, 0, 255))
 
-/* temp1 (ix = 0) is an intel thermal diode which is scaled in user space.
-   temp2 (ix = 1) is the internal temp diode so it's scaled in the driver
-   according to some measurements that I took on an EPIA M10000.
-   temp3-7 are thermistor based so the driver returns the voltage measured at
-   the pin (range 0V - 2.2V). */
+/*
+ * temp1 (ix = 0) is an intel thermal diode which is scaled in user space.
+ * temp2 (ix = 1) is the internal temp diode so it's scaled in the driver
+ * according to some measurements that I took on an EPIA M10000.
+ * temp3-7 are thermistor based so the driver returns the voltage measured at
+ * the pin (range 0V - 2.2V).
+ */
 #define TEMP_FROM_REG(ix, reg)	((ix) == 0 ? (reg) * 1000 : \
 				 (ix) == 1 ? (reg) < 51 ? 0 : \
 				 ((reg) - 51) * 1000 : \
@@ -186,8 +190,10 @@ struct vt1211_data {
  * Super-I/O constants and functions
  * --------------------------------------------------------------------- */
 
-/* Configuration index port registers
- * The vt1211 can live at 2 different addresses so we need to probe both */
+/*
+ * Configuration index port registers
+ * The vt1211 can live at 2 different addresses so we need to probe both
+ */
 #define SIO_REG_CIP1		0x2e
 #define SIO_REG_CIP2		0x4e
 
@@ -377,7 +383,12 @@ static ssize_t set_in(struct device *dev, struct device_attribute *attr,
 						to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -446,7 +457,12 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
 						to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (fn) {
@@ -517,8 +533,13 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
 						to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
 	int reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -536,16 +557,23 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
 		break;
 	case SHOW_SET_FAN_DIV:
 		switch (val) {
-			case 1: data->fan_div[ix] = 0; break;
-			case 2: data->fan_div[ix] = 1; break;
-			case 4: data->fan_div[ix] = 2; break;
-			case 8: data->fan_div[ix] = 3; break;
-			default:
-				count = -EINVAL;
-				dev_warn(dev, "fan div value %ld not "
-					 "supported. Choose one of 1, 2, "
-					 "4, or 8.\n", val);
-				goto EXIT;
+		case 1:
+			data->fan_div[ix] = 0;
+			break;
+		case 2:
+			data->fan_div[ix] = 1;
+			break;
+		case 4:
+			data->fan_div[ix] = 2;
+			break;
+		case 8:
+			data->fan_div[ix] = 3;
+			break;
+		default:
+			count = -EINVAL;
+			dev_warn(dev, "fan div value %ld not supported. "
+				 "Choose one of 1, 2, 4, or 8.\n", val);
+			goto EXIT;
 		}
 		vt1211_write8(data, VT1211_REG_FAN_DIV,
 			      ((data->fan_div[1] << 6) |
@@ -610,8 +638,13 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 						to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int fn = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
 	int tmp, reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -628,11 +661,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		switch (val) {
 		case 0:
 			data->pwm_ctl[ix] &= 7;
-			/* disable SmartGuardian if both PWM outputs are
-			 * disabled */
-			if ((data->pwm_ctl[ix ^ 1] & 1) == 0) {
+			/*
+			 * disable SmartGuardian if both PWM outputs are
+			 * disabled
+			 */
+			if ((data->pwm_ctl[ix ^ 1] & 1) == 0)
 				data->fan_ctl &= 0xe;
-			}
 			break;
 		case 2:
 			data->pwm_ctl[ix] |= 8;
@@ -656,16 +690,15 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		val = 135000 / SENSORS_LIMIT(val, 135000 >> 7, 135000);
 		/* calculate tmp = log2(val) */
 		tmp = 0;
-		for (val >>= 1; val > 0; val >>= 1) {
+		for (val >>= 1; val > 0; val >>= 1)
 			tmp++;
-		}
 		/* sync the data cache */
 		reg = vt1211_read8(data, VT1211_REG_PWM_CLK);
 		data->pwm_clk = (reg & 0xf8) | tmp;
 		vt1211_write8(data, VT1211_REG_PWM_CLK, data->pwm_clk);
 		break;
 	case SHOW_SET_PWM_AUTO_CHANNELS_TEMP:
-		if ((val < 1) || (val > 7)) {
+		if (val < 1 || val > 7) {
 			count = -EINVAL;
 			dev_warn(dev, "temp channel %ld not supported. "
 				 "Choose a value between 1 and 7.\n", val);
@@ -741,8 +774,14 @@ static ssize_t set_pwm_auto_point_temp(struct device *dev,
 						to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int ap = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
 	int reg;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
+
 
 	mutex_lock(&data->update_lock);
 
@@ -774,7 +813,7 @@ static ssize_t set_pwm_auto_point_temp(struct device *dev,
  * 1  1  : pwm2 low speed duty cycle  (pwm_auto_pwm[1][1])
  * 1  2  : pwm2 high speed duty cycle (pwm_auto_pwm[1][2])
  * 1  3  : pwm2 full speed            (pwm_auto_pwm[1][3], hard-wired to 255)
-*/
+ */
 
 static ssize_t show_pwm_auto_point_pwm(struct device *dev,
 				       struct device_attribute *attr,
@@ -798,16 +837,15 @@ static ssize_t set_pwm_auto_point_pwm(struct device *dev,
 						to_sensor_dev_attr_2(attr);
 	int ix = sensor_attr_2->index;
 	int ap = sensor_attr_2->nr;
-	long val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
 
-	if ((val < 0) || (val > 255)) {
-		dev_err(dev, "pwm value %ld is out of range. "
-			"Choose a value between 0 and 255.\n" , val);
-		return -EINVAL;
-	}
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	data->pwm_auto_pwm[ix][ap] = val;
+	data->pwm_auto_pwm[ix][ap] = SENSORS_LIMIT(val, 0, 255);
 	vt1211_write8(data, VT1211_REG_PWM_AUTO_PWM(ix, ap),
 		      data->pwm_auto_pwm[ix][ap]);
 	mutex_unlock(&data->update_lock);
@@ -831,7 +869,12 @@ static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
 		       const char *buf, size_t count)
 {
 	struct vt1211_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	data->vrm = val;
 
@@ -866,112 +909,99 @@ static ssize_t show_alarms(struct device *dev,
  * Device attribute structs
  * --------------------------------------------------------------------- */
 
-#define SENSOR_ATTR_IN_INPUT(ix) \
-	SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \
-		show_in, NULL, SHOW_IN_INPUT, ix)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_in_input[] = {
-	SENSOR_ATTR_IN_INPUT(0),
-	SENSOR_ATTR_IN_INPUT(1),
-	SENSOR_ATTR_IN_INPUT(2),
-	SENSOR_ATTR_IN_INPUT(3),
-	SENSOR_ATTR_IN_INPUT(4),
-	SENSOR_ATTR_IN_INPUT(5),
-};
-
-#define SENSOR_ATTR_IN_MIN(ix) \
+#define SENSOR_ATTR_IN(ix) \
+{	SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \
+		show_in, NULL, SHOW_IN_INPUT, ix), \
 	SENSOR_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \
-		show_in, set_in, SHOW_SET_IN_MIN, ix)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_in_min[] = {
-	SENSOR_ATTR_IN_MIN(0),
-	SENSOR_ATTR_IN_MIN(1),
-	SENSOR_ATTR_IN_MIN(2),
-	SENSOR_ATTR_IN_MIN(3),
-	SENSOR_ATTR_IN_MIN(4),
-	SENSOR_ATTR_IN_MIN(5),
-};
-
-#define SENSOR_ATTR_IN_MAX(ix) \
+		show_in, set_in, SHOW_SET_IN_MIN, ix), \
 	SENSOR_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \
-		show_in, set_in, SHOW_SET_IN_MAX, ix)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_in_max[] = {
-	SENSOR_ATTR_IN_MAX(0),
-	SENSOR_ATTR_IN_MAX(1),
-	SENSOR_ATTR_IN_MAX(2),
-	SENSOR_ATTR_IN_MAX(3),
-	SENSOR_ATTR_IN_MAX(4),
-	SENSOR_ATTR_IN_MAX(5),
+		show_in, set_in, SHOW_SET_IN_MAX, ix), \
+	SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \
+		show_in, NULL, SHOW_IN_ALARM, ix) \
+}
+
+static struct sensor_device_attribute_2 vt1211_sysfs_in[][4] = {
+	SENSOR_ATTR_IN(0),
+	SENSOR_ATTR_IN(1),
+	SENSOR_ATTR_IN(2),
+	SENSOR_ATTR_IN(3),
+	SENSOR_ATTR_IN(4),
+	SENSOR_ATTR_IN(5)
 };
 
-#define SENSOR_ATTR_IN_ALARM(ix) \
-	SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \
-		show_in, NULL, SHOW_IN_ALARM, ix)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_in_alarm[] = {
-	SENSOR_ATTR_IN_ALARM(0),
-	SENSOR_ATTR_IN_ALARM(1),
-	SENSOR_ATTR_IN_ALARM(2),
-	SENSOR_ATTR_IN_ALARM(3),
-	SENSOR_ATTR_IN_ALARM(4),
-	SENSOR_ATTR_IN_ALARM(5),
+#define IN_UNIT_ATTRS(X)			\
+{	&vt1211_sysfs_in[X][0].dev_attr.attr,	\
+	&vt1211_sysfs_in[X][1].dev_attr.attr,	\
+	&vt1211_sysfs_in[X][2].dev_attr.attr,	\
+	&vt1211_sysfs_in[X][3].dev_attr.attr,	\
+	NULL					\
+}
+
+static struct attribute *vt1211_in_attr[][5] = {
+	IN_UNIT_ATTRS(0),
+	IN_UNIT_ATTRS(1),
+	IN_UNIT_ATTRS(2),
+	IN_UNIT_ATTRS(3),
+	IN_UNIT_ATTRS(4),
+	IN_UNIT_ATTRS(5)
 };
 
-#define SENSOR_ATTR_TEMP_INPUT(ix) \
-	SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \
-		show_temp, NULL, SHOW_TEMP_INPUT, ix-1)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_temp_input[] = {
-	SENSOR_ATTR_TEMP_INPUT(1),
-	SENSOR_ATTR_TEMP_INPUT(2),
-	SENSOR_ATTR_TEMP_INPUT(3),
-	SENSOR_ATTR_TEMP_INPUT(4),
-	SENSOR_ATTR_TEMP_INPUT(5),
-	SENSOR_ATTR_TEMP_INPUT(6),
-	SENSOR_ATTR_TEMP_INPUT(7),
+static const struct attribute_group vt1211_in_attr_group[] = {
+	{ .attrs = vt1211_in_attr[0] },
+	{ .attrs = vt1211_in_attr[1] },
+	{ .attrs = vt1211_in_attr[2] },
+	{ .attrs = vt1211_in_attr[3] },
+	{ .attrs = vt1211_in_attr[4] },
+	{ .attrs = vt1211_in_attr[5] }
 };
 
-#define SENSOR_ATTR_TEMP_MAX(ix) \
+#define SENSOR_ATTR_TEMP(ix) \
+{	SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \
+		show_temp, NULL, SHOW_TEMP_INPUT, ix-1), \
 	SENSOR_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \
-		show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_temp_max[] = {
-	SENSOR_ATTR_TEMP_MAX(1),
-	SENSOR_ATTR_TEMP_MAX(2),
-	SENSOR_ATTR_TEMP_MAX(3),
-	SENSOR_ATTR_TEMP_MAX(4),
-	SENSOR_ATTR_TEMP_MAX(5),
-	SENSOR_ATTR_TEMP_MAX(6),
-	SENSOR_ATTR_TEMP_MAX(7),
+		show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1), \
+	SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \
+		show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1), \
+	SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \
+		show_temp, NULL, SHOW_TEMP_ALARM, ix-1) \
+}
+
+static struct sensor_device_attribute_2 vt1211_sysfs_temp[][4] = {
+	SENSOR_ATTR_TEMP(1),
+	SENSOR_ATTR_TEMP(2),
+	SENSOR_ATTR_TEMP(3),
+	SENSOR_ATTR_TEMP(4),
+	SENSOR_ATTR_TEMP(5),
+	SENSOR_ATTR_TEMP(6),
+	SENSOR_ATTR_TEMP(7),
 };
 
-#define SENSOR_ATTR_TEMP_MAX_HYST(ix) \
-	SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \
-		show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_temp_max_hyst[] = {
-	SENSOR_ATTR_TEMP_MAX_HYST(1),
-	SENSOR_ATTR_TEMP_MAX_HYST(2),
-	SENSOR_ATTR_TEMP_MAX_HYST(3),
-	SENSOR_ATTR_TEMP_MAX_HYST(4),
-	SENSOR_ATTR_TEMP_MAX_HYST(5),
-	SENSOR_ATTR_TEMP_MAX_HYST(6),
-	SENSOR_ATTR_TEMP_MAX_HYST(7),
+#define TEMP_UNIT_ATTRS(X)			\
+{	&vt1211_sysfs_temp[X][0].dev_attr.attr,	\
+	&vt1211_sysfs_temp[X][1].dev_attr.attr,	\
+	&vt1211_sysfs_temp[X][2].dev_attr.attr,	\
+	&vt1211_sysfs_temp[X][3].dev_attr.attr,	\
+	NULL					\
+}
+
+static struct attribute *vt1211_temp_attr[][5] = {
+	TEMP_UNIT_ATTRS(0),
+	TEMP_UNIT_ATTRS(1),
+	TEMP_UNIT_ATTRS(2),
+	TEMP_UNIT_ATTRS(3),
+	TEMP_UNIT_ATTRS(4),
+	TEMP_UNIT_ATTRS(5),
+	TEMP_UNIT_ATTRS(6)
 };
 
-#define SENSOR_ATTR_TEMP_ALARM(ix) \
-	SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \
-		show_temp, NULL, SHOW_TEMP_ALARM, ix-1)
-
-static struct sensor_device_attribute_2 vt1211_sysfs_temp_alarm[] = {
-	SENSOR_ATTR_TEMP_ALARM(1),
-	SENSOR_ATTR_TEMP_ALARM(2),
-	SENSOR_ATTR_TEMP_ALARM(3),
-	SENSOR_ATTR_TEMP_ALARM(4),
-	SENSOR_ATTR_TEMP_ALARM(5),
-	SENSOR_ATTR_TEMP_ALARM(6),
-	SENSOR_ATTR_TEMP_ALARM(7),
+static const struct attribute_group vt1211_temp_attr_group[] = {
+	{ .attrs = vt1211_temp_attr[0] },
+	{ .attrs = vt1211_temp_attr[1] },
+	{ .attrs = vt1211_temp_attr[2] },
+	{ .attrs = vt1211_temp_attr[3] },
+	{ .attrs = vt1211_temp_attr[4] },
+	{ .attrs = vt1211_temp_attr[5] },
+	{ .attrs = vt1211_temp_attr[6] }
 };
 
 #define SENSOR_ATTR_FAN(ix) \
@@ -1069,7 +1099,8 @@ static void __devinit vt1211_init_device(struct vt1211_data *data)
 		vt1211_write8(data, VT1211_REG_UCH_CONFIG, data->uch_config);
 	}
 
-	/* Initialize the interrupt mode (if request at module load time).
+	/*
+	 * Initialize the interrupt mode (if request at module load time).
 	 * The VT1211 implements 3 different modes for clearing interrupts:
 	 * 0: Clear INT when status register is read. Regenerate INT as long
 	 *    as temp stays above hysteresis limit.
@@ -1079,7 +1110,8 @@ static void __devinit vt1211_init_device(struct vt1211_data *data)
 	 * 2: Clear INT when temp falls below max limit.
 	 *
 	 * The driver only allows to force mode 0 since that's the only one
-	 * that makes sense for 'sensors' */
+	 * that makes sense for 'sensors'
+	 */
 	if (int_mode == 0) {
 		vt1211_write8(data, VT1211_REG_TEMP1_CONFIG, 0);
 		vt1211_write8(data, VT1211_REG_TEMP2_CONFIG, 0);
@@ -1095,33 +1127,18 @@ static void vt1211_remove_sysfs(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) {
-		device_remove_file(dev,
-			&vt1211_sysfs_in_input[i].dev_attr);
-		device_remove_file(dev,
-			&vt1211_sysfs_in_min[i].dev_attr);
-		device_remove_file(dev,
-			&vt1211_sysfs_in_max[i].dev_attr);
-		device_remove_file(dev,
-			&vt1211_sysfs_in_alarm[i].dev_attr);
-	}
-	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) {
-		device_remove_file(dev,
-			&vt1211_sysfs_temp_input[i].dev_attr);
-		device_remove_file(dev,
-			&vt1211_sysfs_temp_max[i].dev_attr);
-		device_remove_file(dev,
-			&vt1211_sysfs_temp_max_hyst[i].dev_attr);
-		device_remove_file(dev,
-			&vt1211_sysfs_temp_alarm[i].dev_attr);
-	}
+	for (i = 0; i < ARRAY_SIZE(vt1211_in_attr_group); i++)
+		sysfs_remove_group(&dev->kobj, &vt1211_in_attr_group[i]);
+
+	for (i = 0; i < ARRAY_SIZE(vt1211_temp_attr_group); i++)
+		sysfs_remove_group(&dev->kobj, &vt1211_temp_attr_group[i]);
+
 	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) {
 		device_remove_file(dev,
 			&vt1211_sysfs_fan_pwm[i].dev_attr);
 	}
-	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) {
+	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++)
 		device_remove_file(dev, &vt1211_sysfs_misc[i]);
-	}
 }
 
 static int __devinit vt1211_probe(struct platform_device *pdev)
@@ -1131,7 +1148,8 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
 	struct resource *res;
 	int i, err;
 
-	if (!(data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct vt1211_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		dev_err(dev, "Out of memory\n");
 		goto EXIT;
@@ -1154,47 +1172,33 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
 	vt1211_init_device(data);
 
 	/* Create sysfs interface files */
-	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_in_input); i++) {
+	for (i = 0; i < ARRAY_SIZE(vt1211_in_attr_group); i++) {
 		if (ISVOLT(i, data->uch_config)) {
-			if ((err = device_create_file(dev,
-				&vt1211_sysfs_in_input[i].dev_attr)) ||
-			    (err = device_create_file(dev,
-				&vt1211_sysfs_in_min[i].dev_attr)) ||
-			    (err = device_create_file(dev,
-				&vt1211_sysfs_in_max[i].dev_attr)) ||
-			    (err = device_create_file(dev,
-				&vt1211_sysfs_in_alarm[i].dev_attr))) {
+			err = sysfs_create_group(&dev->kobj,
+						 &vt1211_in_attr_group[i]);
+			if (err)
 				goto EXIT_DEV_REMOVE;
-			}
 		}
 	}
-	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_temp_input); i++) {
+	for (i = 0; i < ARRAY_SIZE(vt1211_temp_attr_group); i++) {
 		if (ISTEMP(i, data->uch_config)) {
-			if ((err = device_create_file(dev,
-				&vt1211_sysfs_temp_input[i].dev_attr)) ||
-			    (err = device_create_file(dev,
-				&vt1211_sysfs_temp_max[i].dev_attr)) ||
-			    (err = device_create_file(dev,
-				&vt1211_sysfs_temp_max_hyst[i].dev_attr)) ||
-			    (err = device_create_file(dev,
-				&vt1211_sysfs_temp_alarm[i].dev_attr))) {
+			err = sysfs_create_group(&dev->kobj,
+						 &vt1211_temp_attr_group[i]);
+			if (err)
 				goto EXIT_DEV_REMOVE;
-			}
 		}
 	}
 	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) {
 		err = device_create_file(dev,
 			&vt1211_sysfs_fan_pwm[i].dev_attr);
-		if (err) {
+		if (err)
 			goto EXIT_DEV_REMOVE;
-		}
 	}
 	for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) {
 		err = device_create_file(dev,
 		       &vt1211_sysfs_misc[i]);
-		if (err) {
+		if (err)
 			goto EXIT_DEV_REMOVE;
-		}
 	}
 
 	/* Register device */
@@ -1293,9 +1297,8 @@ static int __init vt1211_find(int sio_cip, unsigned short *address)
 	superio_enter(sio_cip);
 
 	devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID);
-	if (devid != SIO_VT1211_ID) {
+	if (devid != SIO_VT1211_ID)
 		goto EXIT;
-	}
 
 	superio_select(sio_cip, SIO_VT1211_LDN_HWMON);
 
@@ -1325,35 +1328,35 @@ static int __init vt1211_init(void)
 	int err;
 	unsigned short address = 0;
 
-	if ((err = vt1211_find(SIO_REG_CIP1, &address)) &&
-	    (err = vt1211_find(SIO_REG_CIP2, &address))) {
-		goto EXIT;
+	err = vt1211_find(SIO_REG_CIP1, &address);
+	if (err) {
+		err = vt1211_find(SIO_REG_CIP2, &address);
+		if (err)
+			goto EXIT;
 	}
 
 	if ((uch_config < -1) || (uch_config > 31)) {
 		err = -EINVAL;
 		pr_warn("Invalid UCH configuration %d. "
 			"Choose a value between 0 and 31.\n", uch_config);
-	  goto EXIT;
+		goto EXIT;
 	}
 
 	if ((int_mode < -1) || (int_mode > 0)) {
 		err = -EINVAL;
 		pr_warn("Invalid interrupt mode %d. "
 			"Only mode 0 is supported.\n", int_mode);
-	  goto EXIT;
+		goto EXIT;
 	}
 
 	err = platform_driver_register(&vt1211_driver);
-	if (err) {
+	if (err)
 		goto EXIT;
-	}
 
 	/* Sets global pdev as a side effect */
 	err = vt1211_device_add(address);
-	if (err) {
+	if (err)
 		goto EXIT_DRV_UNREGISTER;
-	}
 
 	return 0;
 
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index db3b2e8..386a845 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -1,28 +1,29 @@
 /*
-	vt8231.c - Part of lm_sensors, Linux kernel modules
-				for hardware monitoring
+ * vt8231.c - Part of lm_sensors, Linux kernel modules
+ *	      for hardware monitoring
+ *
+ * Copyright (c) 2005 Roger Lucas <vt8231@hiddenengine.co.uk>
+ * Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+ *		      Aaron M. Marsh <amarsh@sdf.lonestar.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.
+ */
 
-	Copyright (c) 2005 Roger Lucas <vt8231@hiddenengine.co.uk>
-	Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
-			   Aaron M. Marsh <amarsh@sdf.lonestar.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.
-*/
-
-/* Supports VIA VT8231 South Bridge embedded sensors
-*/
+/*
+ * Supports VIA VT8231 South Bridge embedded sensors
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -50,26 +51,27 @@ static struct platform_device *pdev;
 #define VT8231_BASE_REG 0x70
 #define VT8231_ENABLE_REG 0x74
 
-/* The VT8231 registers
-
-   The reset value for the input channel configuration is used (Reg 0x4A=0x07)
-   which sets the selected inputs marked with '*' below if multiple options are
-   possible:
-
-	            Voltage Mode	  Temperature Mode
-	Sensor	      Linux Id	      Linux Id        VIA Id
-	--------      --------	      --------        ------
-	CPU Diode	N/A		temp1		0
-	UIC1		in0		temp2 *		1
-	UIC2		in1 *		temp3   	2
-	UIC3		in2 *		temp4		3
-	UIC4		in3 *		temp5		4
-	UIC5		in4 *		temp6		5
-	3.3V		in5		N/A
-
-   Note that the BIOS may set the configuration register to a different value
-   to match the motherboard configuration.
-*/
+/*
+ * The VT8231 registers
+ *
+ * The reset value for the input channel configuration is used (Reg 0x4A=0x07)
+ * which sets the selected inputs marked with '*' below if multiple options are
+ * possible:
+ *
+ *		    Voltage Mode	  Temperature Mode
+ *	Sensor	      Linux Id	      Linux Id	      VIA Id
+ *	--------      --------	      --------	      ------
+ *	CPU Diode	N/A		temp1		0
+ *	UIC1		in0		temp2 *		1
+ *	UIC2		in1 *		temp3		2
+ *	UIC3		in2 *		temp4		3
+ *	UIC4		in3 *		temp5		4
+ *	UIC5		in4 *		temp6		5
+ *	3.3V		in5		N/A
+ *
+ * Note that the BIOS may set the configuration register to a different value
+ * to match the motherboard configuration.
+ */
 
 /* fans numbered 0-1 */
 #define VT8231_REG_FAN_MIN(nr)	(0x3b + (nr))
@@ -81,13 +83,14 @@ static const u8 regvolt[]    = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 };
 static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 };
 static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 };
 
-/* Temperatures are numbered 1-6 according to the Linux kernel specification.
-**
-** In the VIA datasheet, however, the temperatures are numbered from zero.
-** Since it is important that this driver can easily be compared to the VIA
-** datasheet, we will use the VIA numbering within this driver and map the
-** kernel sysfs device name to the VIA number in the sysfs callback.
-*/
+/*
+ * Temperatures are numbered 1-6 according to the Linux kernel specification.
+ *
+ * In the VIA datasheet, however, the temperatures are numbered from zero.
+ * Since it is important that this driver can easily be compared to the VIA
+ * datasheet, we will use the VIA numbering within this driver and map the
+ * kernel sysfs device name to the VIA number in the sysfs callback.
+ */
 
 #define VT8231_REG_TEMP_LOW01	0x49
 #define VT8231_REG_TEMP_LOW25	0x4d
@@ -108,9 +111,10 @@ static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 };
 #define VT8231_REG_TEMP1_CONFIG 0x4b
 #define VT8231_REG_TEMP2_CONFIG 0x4c
 
-/* temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux
-** numbering
-*/
+/*
+ * temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux
+ * numbering
+ */
 #define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \
 			      ((ch_config) >> ((i)+1)) & 0x01)
 /* voltages 0-5 */
@@ -119,24 +123,26 @@ static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 };
 
 #define DIV_FROM_REG(val) (1 << (val))
 
-/* NB  The values returned here are NOT temperatures.  The calibration curves
-**     for the thermistor curves are board-specific and must go in the
-**     sensors.conf file.  Temperature sensors are actually ten bits, but the
-**     VIA datasheet only considers the 8 MSBs obtained from the regtemp[]
-**     register.  The temperature value returned should have a magnitude of 3,
-**     so we use the VIA scaling as the "true" scaling and use the remaining 2
-**     LSBs as fractional precision.
-**
-**     All the on-chip hardware temperature comparisons for the alarms are only
-**     8-bits wide, and compare against the 8 MSBs of the temperature.  The bits
-**     in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are
-**     ignored.
-*/
-
-/******** FAN RPM CONVERSIONS ********
-** This chip saturates back at 0, not at 255 like many the other chips.
-** So, 0 means 0 RPM
-*/
+/*
+ * NB  The values returned here are NOT temperatures.  The calibration curves
+ *     for the thermistor curves are board-specific and must go in the
+ *     sensors.conf file.  Temperature sensors are actually ten bits, but the
+ *     VIA datasheet only considers the 8 MSBs obtained from the regtemp[]
+ *     register.  The temperature value returned should have a magnitude of 3,
+ *     so we use the VIA scaling as the "true" scaling and use the remaining 2
+ *     LSBs as fractional precision.
+ *
+ *     All the on-chip hardware temperature comparisons for the alarms are only
+ *     8-bits wide, and compare against the 8 MSBs of the temperature.  The bits
+ *     in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are
+ *     ignored.
+ */
+
+/*
+ ****** FAN RPM CONVERSIONS ********
+ * This chip saturates back at 0, not at 255 like many the other chips.
+ * So, 0 means 0 RPM
+ */
 static inline u8 FAN_TO_REG(long rpm, int div)
 {
 	if (rpm == 0)
@@ -222,7 +228,12 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
@@ -237,7 +248,12 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
@@ -278,7 +294,12 @@ static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
@@ -292,7 +313,12 @@ static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
@@ -346,7 +372,12 @@ static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
@@ -358,7 +389,12 @@ static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
@@ -400,7 +436,12 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
@@ -414,7 +455,12 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	int val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
@@ -423,9 +469,10 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-/* Note that these map the Linux temperature sensor numbering (1-6) to the VIA
-** temperature sensor numbering (0-5)
-*/
+/*
+ * Note that these map the Linux temperature sensor numbering (1-6) to the VIA
+ * temperature sensor numbering (0-5)
+ */
 #define define_temperature_sysfs(offset)				\
 static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
 		show_temp, NULL, offset - 1);				\
@@ -436,7 +483,8 @@ static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,	\
 
 static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL);
 static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max);
-static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp0_min,
+		   set_temp0_min);
 
 define_temperature_sysfs(2);
 define_temperature_sysfs(3);
@@ -480,7 +528,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct vt8231_data *data = dev_get_drvdata(dev);
-	int val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -494,21 +547,34 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 {
 	struct vt8231_data *data = dev_get_drvdata(dev);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
 	int nr = sensor_attr->index;
 	int old = vt8231_read_value(data, VT8231_REG_FANDIV);
 	long min = FAN_FROM_REG(data->fan_min[nr],
 				 DIV_FROM_REG(data->fan_div[nr]));
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
+	case 1:
+		data->fan_div[nr] = 0;
+		break;
+	case 2:
+		data->fan_div[nr] = 1;
+		break;
+	case 4:
+		data->fan_div[nr] = 2;
+		break;
+	case 8:
+		data->fan_div[nr] = 3;
+		break;
 	default:
 		dev_err(dev, "fan_div value %ld not supported. "
-		        "Choose one of 1, 2, 4 or 8!\n", val);
+			"Choose one of 1, 2, 4 or 8!\n", val);
 		mutex_unlock(&data->update_lock);
 		return -EINVAL;
 	}
@@ -699,7 +765,7 @@ static struct platform_driver vt8231_driver = {
 	.remove	= __devexit_p(vt8231_remove),
 };
 
-static const struct pci_device_id vt8231_pci_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(vt8231_pci_ids) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
 	{ 0, }
 };
@@ -707,7 +773,7 @@ static const struct pci_device_id vt8231_pci_ids[] = {
 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
 
 static int __devinit vt8231_pci_probe(struct pci_dev *dev,
-			 	      const struct pci_device_id *id);
+				      const struct pci_device_id *id);
 
 static struct pci_driver vt8231_pci_driver = {
 	.name		= "vt8231",
@@ -730,7 +796,8 @@ static int vt8231_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	if (!(data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto exit_release;
 	}
@@ -743,7 +810,8 @@ static int vt8231_probe(struct platform_device *pdev)
 	vt8231_init_device(data);
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group)))
+	err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group);
+	if (err)
 		goto exit_free;
 
 	/* Must update device information to find out the config field */
@@ -751,16 +819,18 @@ static int vt8231_probe(struct platform_device *pdev)
 
 	for (i = 0; i < ARRAY_SIZE(vt8231_group_temps); i++) {
 		if (ISTEMP(i, data->uch_config)) {
-			if ((err = sysfs_create_group(&pdev->dev.kobj,
-					&vt8231_group_temps[i])))
+			err = sysfs_create_group(&pdev->dev.kobj,
+						 &vt8231_group_temps[i]);
+			if (err)
 				goto exit_remove_files;
 		}
 	}
 
 	for (i = 0; i < ARRAY_SIZE(vt8231_group_volts); i++) {
 		if (ISVOLT(i, data->uch_config)) {
-			if ((err = sysfs_create_group(&pdev->dev.kobj,
-					&vt8231_group_volts[i])))
+			err = sysfs_create_group(&pdev->dev.kobj,
+						 &vt8231_group_volts[i]);
+			if (err)
 				goto exit_remove_files;
 		}
 	}
@@ -866,17 +936,15 @@ static struct vt8231_data *vt8231_update_device(struct device *dev)
 			(vt8231_read_value(data, VT8231_REG_ALARM2) << 8);
 
 		/* Set alarm flags correctly */
-		if (!data->fan[0] && data->fan_min[0]) {
+		if (!data->fan[0] && data->fan_min[0])
 			data->alarms |= 0x40;
-		} else if (data->fan[0] && !data->fan_min[0]) {
+		else if (data->fan[0] && !data->fan_min[0])
 			data->alarms &= ~0x40;
-		}
 
-		if (!data->fan[1] && data->fan_min[1]) {
+		if (!data->fan[1] && data->fan_min[1])
 			data->alarms |= 0x80;
-		} else if (data->fan[1] && !data->fan_min[1]) {
+		else if (data->fan[1] && !data->fan_min[1])
 			data->alarms &= ~0x80;
-		}
 
 		data->last_updated = jiffies;
 		data->valid = 1;
@@ -971,13 +1039,16 @@ static int __devinit vt8231_pci_probe(struct pci_dev *dev,
 	if (vt8231_device_add(address))
 		goto exit_unregister;
 
-	/* Always return failure here.  This is to allow other drivers to bind
+	/*
+	 * Always return failure here.  This is to allow other drivers to bind
 	 * to this pci device.  We don't really want to have control over the
 	 * pci device, we only wanted to read as few register values from it.
 	 */
 
-	/* We do, however, mark ourselves as using the PCI device to stop it
-	   getting unloaded. */
+	/*
+	 * We do, however, mark ourselves as using the PCI device to stop it
+	 * getting unloaded.
+	 */
 	s_bridge = pci_dev_get(dev);
 	return -ENODEV;
 
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 5276d19..57a31a0 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -1,50 +1,50 @@
 /*
-    w83627ehf - Driver for the hardware monitoring functionality of
-		the Winbond W83627EHF Super-I/O chip
-    Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
-    Copyright (C) 2006  Yuan Mu (Winbond),
-			Rudolf Marek <r.marek@assembler.cz>
-			David Hubbard <david.c.hubbard@gmail.com>
-			Daniel J Blueman <daniel.blueman@gmail.com>
-    Copyright (C) 2010  Sheng-Yuan Huang (Nuvoton) (PS00)
-
-    Shamelessly ripped from the w83627hf driver
-    Copyright (C) 2003  Mark Studebaker
-
-    Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help
-    in testing and debugging this driver.
-
-    This driver also supports the W83627EHG, which is the lead-free
-    version of the W83627EHF.
-
-    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.
-
-
-    Supports the following chips:
-
-    Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
-    w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
-					       0x8860 0xa1
-    w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
-    w83627dhg-p  9      5       4       3      0xb070 0xc1    0x5ca3
-    w83627uhg    8      2       2       2      0xa230 0xc1    0x5ca3
-    w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
-    w83667hg-b   9      5       3       4      0xb350 0xc1    0x5ca3
-    nct6775f     9      4       3       9      0xb470 0xc1    0x5ca3
-    nct6776f     9      5       3       9      0xC330 0xc1    0x5ca3
-*/
+ * w83627ehf - Driver for the hardware monitoring functionality of
+ *	       the Winbond W83627EHF Super-I/O chip
+ * Copyright (C) 2005-2011  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2006  Yuan Mu (Winbond),
+ *		       Rudolf Marek <r.marek@assembler.cz>
+ *		       David Hubbard <david.c.hubbard@gmail.com>
+ *		       Daniel J Blueman <daniel.blueman@gmail.com>
+ * Copyright (C) 2010  Sheng-Yuan Huang (Nuvoton) (PS00)
+ *
+ * Shamelessly ripped from the w83627hf driver
+ * Copyright (C) 2003  Mark Studebaker
+ *
+ * Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help
+ * in testing and debugging this driver.
+ *
+ * This driver also supports the W83627EHG, which is the lead-free
+ * version of the W83627EHF.
+ *
+ * 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.
+ *
+ *
+ * Supports the following chips:
+ *
+ * Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
+ * w83627ehf   10      5       4       3      0x8850 0x88    0x5ca3
+ *					      0x8860 0xa1
+ * w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
+ * w83627dhg-p  9      5       4       3      0xb070 0xc1    0x5ca3
+ * w83627uhg    8      2       2       2      0xa230 0xc1    0x5ca3
+ * w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
+ * w83667hg-b   9      5       3       4      0xb350 0xc1    0x5ca3
+ * nct6775f     9      4       3       9      0xb470 0xc1    0x5ca3
+ * nct6776f     9      5       3       9      0xC330 0xc1    0x5ca3
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -164,11 +164,13 @@ superio_exit(int ioreg)
 #define W83627EHF_REG_BANK		0x4E
 #define W83627EHF_REG_CONFIG		0x40
 
-/* Not currently used:
+/*
+ * Not currently used:
  * REG_MAN_ID has the value 0x5ca3 for all supported chips.
  * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
  * REG_MAN_ID is at port 0x4f
- * REG_CHIP_ID is at port 0x58 */
+ * REG_CHIP_ID is at port 0x58
+ */
 
 static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
 static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
@@ -393,8 +395,10 @@ div_from_reg(u8 reg)
 	return 1 << reg;
 }
 
-/* Some of the voltage inputs have internal scaling, the tables below
- * contain 8 (the ADC LSB in mV) * scaling factor * 100 */
+/*
+ * Some of the voltage inputs have internal scaling, the tables below
+ * contain 8 (the ADC LSB in mV) * scaling factor * 100
+ */
 static const u16 scale_in_common[10] = {
 	800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800
 };
@@ -470,12 +474,13 @@ struct w83627ehf_data {
 
 	u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
 	u8 pwm_enable[4]; /* 1->manual
-			     2->thermal cruise mode (also called SmartFan I)
-			     3->fan speed cruise mode
-			     4->variable thermal cruise (also called
-				SmartFan III)
-			     5->enhanced variable thermal cruise (also called
-				SmartFan IV) */
+			   * 2->thermal cruise mode (also called SmartFan I)
+			   * 3->fan speed cruise mode
+			   * 4->variable thermal cruise (also called
+			   * SmartFan III)
+			   * 5->enhanced variable thermal cruise (also called
+			   * SmartFan IV)
+			   */
 	u8 pwm_enable_orig[4];	/* original value of pwm_enable */
 	u8 pwm_num;		/* number of pwm */
 	u8 pwm[4];
@@ -816,9 +821,11 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
 				data->fan_min[i] = w83627ehf_read_value(data,
 					   data->REG_FAN_MIN[i]);
 
-			/* If we failed to measure the fan speed and clock
-			   divider can be increased, let's try that for next
-			   time */
+			/*
+			 * If we failed to measure the fan speed and clock
+			 * divider can be increased, let's try that for next
+			 * time
+			 */
 			if (data->has_fan_div
 			    && (reg >= 0xff || (sio_data->kind == nct6775
 						&& reg == 0x00))
@@ -1081,25 +1088,31 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 		new_div = data->fan_div[nr]; /* No change */
 		dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
 	} else if ((reg = 1350000U / val) >= 128 * 255) {
-		/* Speed below this value cannot possibly be represented,
-		   even with the highest divider (128) */
+		/*
+		 * Speed below this value cannot possibly be represented,
+		 * even with the highest divider (128)
+		 */
 		data->fan_min[nr] = 254;
 		new_div = 7; /* 128 == (1 << 7) */
 		dev_warn(dev, "fan%u low limit %lu below minimum %u, set to "
 			 "minimum\n", nr + 1, val,
 			 data->fan_from_reg_min(254, 7));
 	} else if (!reg) {
-		/* Speed above this value cannot possibly be represented,
-		   even with the lowest divider (1) */
+		/*
+		 * Speed above this value cannot possibly be represented,
+		 * even with the lowest divider (1)
+		 */
 		data->fan_min[nr] = 1;
 		new_div = 0; /* 1 == (1 << 0) */
 		dev_warn(dev, "fan%u low limit %lu above maximum %u, set to "
 			 "maximum\n", nr + 1, val,
 			 data->fan_from_reg_min(1, 0));
 	} else {
-		/* Automatically pick the best divider, i.e. the one such
-		   that the min limit will correspond to a register value
-		   in the 96..192 range */
+		/*
+		 * Automatically pick the best divider, i.e. the one such
+		 * that the min limit will correspond to a register value
+		 * in the 96..192 range
+		 */
 		new_div = 0;
 		while (reg > 192 && new_div < 7) {
 			reg >>= 1;
@@ -1108,8 +1121,10 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 		data->fan_min[nr] = reg;
 	}
 
-	/* Write both the fan clock divider (if it changed) and the new
-	   fan min (unconditionally) */
+	/*
+	 * Write both the fan clock divider (if it changed) and the new
+	 * fan min (unconditionally)
+	 */
 	if (new_div != data->fan_div[nr]) {
 		dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
 			nr + 1, div_from_reg(data->fan_div[nr]),
@@ -1736,8 +1751,10 @@ static struct sensor_device_attribute_2 sda_caseopen[] = {
 
 static void w83627ehf_device_remove_files(struct device *dev)
 {
-	/* some entries in the following arrays may not have been used in
-	 * device_create_file(), but device_remove_file() will ignore them */
+	/*
+	 * some entries in the following arrays may not have been used in
+	 * device_create_file(), but device_remove_file() will ignore them
+	 */
 	int i;
 	struct w83627ehf_data *data = dev_get_drvdata(dev);
 
@@ -2278,9 +2295,11 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
 	/* Read VID value */
 	if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b ||
 	    sio_data->kind == nct6775 || sio_data->kind == nct6776) {
-		/* W83667HG has different pins for VID input and output, so
-		we can get the VID input values directly at logical device D
-		0xe3. */
+		/*
+		 * W83667HG has different pins for VID input and output, so
+		 * we can get the VID input values directly at logical device D
+		 * 0xe3.
+		 */
 		superio_select(sio_data->sioreg, W83667HG_LD_VID);
 		data->vid = superio_inb(sio_data->sioreg, 0xe3);
 		err = device_create_file(dev, &dev_attr_cpu0_vid);
@@ -2289,11 +2308,13 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
 	} else if (sio_data->kind != w83627uhg) {
 		superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
 		if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
-			/* Set VID input sensibility if needed. In theory the
-			   BIOS should have set it, but in practice it's not
-			   always the case. We only do it for the W83627EHF/EHG
-			   because the W83627DHG is more complex in this
-			   respect. */
+			/*
+			 * Set VID input sensibility if needed. In theory the
+			 * BIOS should have set it, but in practice it's not
+			 * always the case. We only do it for the W83627EHF/EHG
+			 * because the W83627DHG is more complex in this
+			 * respect.
+			 */
 			if (sio_data->kind == w83627ehf) {
 				en_vrm10 = superio_inb(sio_data->sioreg,
 						       SIO_REG_EN_VRM10);
@@ -2617,10 +2638,12 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
 	return 0;
 }
 
-/* when Super-I/O functions move to a separate file, the Super-I/O
+/*
+ * when Super-I/O functions move to a separate file, the Super-I/O
  * bus will manage the lifetime of the device and this module will only keep
  * track of the w83627ehf driver. But since we platform_device_alloc(), we
- * must keep track of the device */
+ * must keep track of the device
+ */
 static struct platform_device *pdev;
 
 static int __init sensors_w83627ehf_init(void)
@@ -2630,11 +2653,13 @@ static int __init sensors_w83627ehf_init(void)
 	struct resource res;
 	struct w83627ehf_sio_data sio_data;
 
-	/* initialize sio_data->kind and sio_data->sioreg.
+	/*
+	 * initialize sio_data->kind and sio_data->sioreg.
 	 *
 	 * when Super-I/O functions move to a separate file, the Super-I/O
 	 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
-	 * w83627ehf hardware monitor, and call probe() */
+	 * w83627ehf hardware monitor, and call probe()
+	 */
 	if (w83627ehf_find(0x2e, &address, &sio_data) &&
 	    w83627ehf_find(0x4e, &address, &sio_data))
 		return -ENODEV;
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 374118f..5ce54a2 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -1,43 +1,43 @@
 /*
-    w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>,
-    and Mark Studebaker <mdsxyz123@yahoo.com>
-    Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org>
-    Copyright (c) 2007  Jean Delvare <khali@linux-fr.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.
-*/
+ * w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware
+ *		monitoring
+ * Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
+ *			      Philip Edelbrock <phil@netroedge.com>,
+ *			      and Mark Studebaker <mdsxyz123@yahoo.com>
+ * Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org>
+ * Copyright (c) 2007  Jean Delvare <khali@linux-fr.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.
+ */
 
 /*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    w83627hf	9	3	2	3	0x20	0x5ca3	no	yes(LPC)
-    w83627thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
-    w83637hf	7	3	3	3	0x80	0x5ca3	no	yes(LPC)
-    w83687thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
-    w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
-
-    For other winbond chips, and for i2c support in the above chips,
-    use w83781d.c.
-
-    Note: automatic ("cruise") fan control for 697, 637 & 627thf not
-    supported yet.
-*/
+ * Supports following chips:
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * w83627hf	9	3	2	3	0x20	0x5ca3	no	yes(LPC)
+ * w83627thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
+ * w83637hf	7	3	3	3	0x80	0x5ca3	no	yes(LPC)
+ * w83687thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
+ * w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
+ *
+ * For other winbond chips, and for i2c support in the above chips,
+ * use w83781d.c.
+ *
+ * Note: automatic ("cruise") fan control for 697, 637 & 627thf not
+ * supported yet.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -80,7 +80,7 @@ module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
 /* modified from kernel/include/traps.c */
-#define	DEV	0x07	/* Register: Logical device select */
+#define DEV			0x07 /* Register: Logical device select */
 
 /* logical device numbers for superio_select (below) */
 #define W83627HF_LD_FDC		0x00
@@ -99,7 +99,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
 #define W83627HF_LD_ACPI	0x0a
 #define W83627HF_LD_HWM		0x0b
 
-#define	DEVID	0x20	/* Register: Device ID */
+#define DEVID			0x20 /* Register: Device ID */
 
 #define W83627THF_GPIO5_EN	0x30 /* w83627thf only */
 #define W83627THF_GPIO5_IOSR	0xf3 /* w83627thf only */
@@ -248,10 +248,12 @@ static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
 static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
 #define W83781D_DEFAULT_BETA 3435
 
-/* Conversions. Limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
+/*
+ * Conversions. Limit checking is only done on the TO_REG
+ * variants. Note that you should be a bit careful with which arguments
+ * these macros are called: arguments may be evaluated more than once.
+ * Fixing this is just not worth it.
+ */
 #define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
 #define IN_FROM_REG(val) ((val) * 16)
 
@@ -267,8 +269,10 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 #define TEMP_MIN (-128000)
 #define TEMP_MAX ( 127000)
 
-/* TEMP: 0.001C/bit (-128C to +127C)
-   REG: 1C/bit, two's complement */
+/*
+ * TEMP: 0.001C/bit (-128C to +127C)
+ * REG: 1C/bit, two's complement
+ */
 static u8 TEMP_TO_REG(long temp)
 {
         int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX);
@@ -294,8 +298,10 @@ static inline unsigned long pwm_freq_from_reg_627hf(u8 reg)
 static inline u8 pwm_freq_to_reg_627hf(unsigned long val)
 {
 	u8 i;
-	/* Only 5 dividers (1 2 4 8 16)
-	   Search for the nearest available frequency */
+	/*
+	 * Only 5 dividers (1 2 4 8 16)
+	 * Search for the nearest available frequency
+	 */
 	for (i = 0; i < 4; i++) {
 		if (val > (((W83627HF_BASE_PWM_FREQ >> i) +
 			    (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2))
@@ -313,7 +319,7 @@ static inline unsigned long pwm_freq_from_reg(u8 reg)
 	/* This should not happen but anyway... */
 	if (reg == 0)
 		reg++;
-	return (clock / (reg << 8));
+	return clock / (reg << 8);
 }
 static inline u8 pwm_freq_to_reg(unsigned long val)
 {
@@ -321,11 +327,11 @@ static inline u8 pwm_freq_to_reg(unsigned long val)
 	if (val >= 93750)	/* The highest we can do */
 		return 0x01;
 	if (val >= 720)	/* Use 24 MHz clock */
-		return (24000000UL / (val << 8));
+		return 24000000UL / (val << 8);
 	if (val < 6)		/* The lowest we can do */
 		return 0xFF;
 	else			/* Use 180 kHz clock */
-		return (0x80 | (180000UL / (val << 8)));
+		return 0x80 | (180000UL / (val << 8));
 }
 
 #define BEEP_MASK_FROM_REG(val)		((val) & 0xff7fff)
@@ -342,11 +348,13 @@ static inline u8 DIV_TO_REG(long val)
 			break;
 		val >>= 1;
 	}
-	return ((u8) i);
+	return (u8)i;
 }
 
-/* For each registered chip, we need to keep some data in memory.
-   The structure is dynamically allocated. */
+/*
+ * For each registered chip, we need to keep some data in memory.
+ * The structure is dynamically allocated.
+ */
 struct w83627hf_data {
 	unsigned short addr;
 	const char *name;
@@ -372,11 +380,13 @@ struct w83627hf_data {
 	u32 beep_mask;		/* Register encoding, combined */
 	u8 pwm[3];		/* Register value */
 	u8 pwm_enable[3];	/* 1 = manual
-				   2 = thermal cruise (also called SmartFan I)
-				   3 = fan speed cruise */
+				 * 2 = thermal cruise (also called SmartFan I)
+				 * 3 = fan speed cruise
+				 */
 	u8 pwm_freq[3];		/* Register value */
 	u16 sens[3];		/* 1 = pentium diode; 2 = 3904 diode;
-				   4 = thermistor */
+				 * 4 = thermistor
+				 */
 	u8 vrm;
 	u8 vrm_ovt;		/* Register value, 627THF/637HF/687THF only */
 };
@@ -427,7 +437,12 @@ store_in_min(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_min[nr] = IN_TO_REG(val);
@@ -441,7 +456,12 @@ store_in_max(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->in_max[nr] = IN_TO_REG(val);
@@ -506,9 +526,12 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a
 	const char *buf, size_t count)
 {
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	
@@ -533,9 +556,12 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a
 	const char *buf, size_t count)
 {
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -584,7 +610,12 @@ store_fan_min(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -645,9 +676,15 @@ store_temp_max(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
-	u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
+	u16 tmp;
+	long val;
+	int err;
 
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
+
+	tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
 	mutex_lock(&data->update_lock);
 	data->temp_max[nr] = tmp;
 	w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp);
@@ -661,9 +698,15 @@ store_temp_max_hyst(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	long val = simple_strtol(buf, NULL, 10);
-	u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
+	u16 tmp;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
+	tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val);
 	mutex_lock(&data->update_lock);
 	data->temp_max_hyst[nr] = tmp;
 	w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp);
@@ -701,9 +744,12 @@ static ssize_t
 store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 	data->vrm = val;
 
 	return count;
@@ -755,8 +801,11 @@ store_beep_mask(struct device *dev, struct device_attribute *attr,
 {
 	struct w83627hf_data *data = dev_get_drvdata(dev);
 	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -791,10 +840,14 @@ store_beep(struct device *dev, struct device_attribute *attr,
 {
 	struct w83627hf_data *data = dev_get_drvdata(dev);
 	int bitnr = to_sensor_dev_attr(attr)->index;
-	unsigned long bit;
 	u8 reg;
+	unsigned long bit;
+	int err;
+
+	err = kstrtoul(buf, 10, &bit);
+	if (err)
+		return err;
 
-	bit = simple_strtoul(buf, NULL, 10);
 	if (bit & ~1)
 		return -EINVAL;
 
@@ -872,10 +925,12 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
 	return sprintf(buf, "%ld\n",
 		       (long) DIV_FROM_REG(data->fan_div[nr]));
 }
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t
 store_fan_div(struct device *dev, struct device_attribute *devattr,
 	      const char *buf, size_t count)
@@ -884,7 +939,12 @@ store_fan_div(struct device *dev, struct device_attribute *devattr,
 	struct w83627hf_data *data = dev_get_drvdata(dev);
 	unsigned long min;
 	u8 reg;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -933,7 +993,12 @@ store_pwm(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	u32 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -974,10 +1039,15 @@ store_pwm_enable(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	u8 reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	if (!val || (val > 3))	/* modes 1, 2 and 3 are supported */
+	if (!val || val > 3)	/* modes 1, 2 and 3 are supported */
 		return -EINVAL;
 	mutex_lock(&data->update_lock);
 	data->pwm_enable[nr] = val;
@@ -1016,9 +1086,12 @@ store_pwm_freq(struct device *dev, struct device_attribute *devattr,
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
 	static const u8 mask[]={0xF8, 0x8F};
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -1060,9 +1133,13 @@ store_temp_type(struct device *dev, struct device_attribute *devattr,
 {
 	int nr = to_sensor_dev_attr(devattr)->index;
 	struct w83627hf_data *data = dev_get_drvdata(dev);
-	u32 val, tmp;
+	unsigned long val;
+	u32 tmp;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -1290,7 +1367,8 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
 		goto ERROR0;
 	}
 
-	if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
+	data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL);
+	if (!data) {
 		err = -ENOMEM;
 		goto ERROR1;
 	}
@@ -1311,7 +1389,8 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
 	w83627hf_update_fan_div(data);
 
 	/* Register common device attributes */
-	if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group)))
+	err = sysfs_create_group(&dev->kobj, &w83627hf_group);
+	if (err)
 		goto ERROR3;
 
 	/* Register chip-specific device attributes */
@@ -1387,10 +1466,11 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
 	}
 
 	if (data->type == w83627thf || data->type == w83637hf
-	 || data->type == w83687thf)
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm3.dev_attr)))
+	    || data->type == w83687thf) {
+		err = device_create_file(dev, &sensor_dev_attr_pwm3.dev_attr);
+		if (err)
 			goto ERROR4;
+	}
 
 	if (data->type == w83637hf || data->type == w83687thf)
 		if ((err = device_create_file(dev,
@@ -1409,10 +1489,12 @@ static int __devinit w83627hf_probe(struct platform_device *pdev)
 			goto ERROR4;
 
 	if (data->type == w83627thf || data->type == w83637hf
-	 || data->type == w83687thf)
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm3_enable.dev_attr)))
+	    || data->type == w83687thf) {
+		err = device_create_file(dev,
+					 &sensor_dev_attr_pwm3_enable.dev_attr);
+		if (err)
 			goto ERROR4;
+	}
 
 	data->hwmon_dev = hwmon_device_register(dev);
 	if (IS_ERR(data->hwmon_dev)) {
@@ -1510,8 +1592,10 @@ static int __devinit w83627thf_read_gpio5(struct platform_device *pdev)
 		goto exit;
 	}
 
-	/* Make sure the pins are configured for input
-	   There must be at least five (VRM 9), and possibly 6 (VRM 10) */
+	/*
+	 * Make sure the pins are configured for input
+	 * There must be at least five (VRM 9), and possibly 6 (VRM 10)
+	 */
 	sel = superio_inb(sio_data, W83627THF_GPIO5_IOSR) & 0x3f;
 	if ((sel & 0x1f) != 0x1f) {
 		dev_dbg(&pdev->dev, "GPIO5 not configured for VID "
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 17a8fa2..b03d54a 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -1,37 +1,37 @@
 /*
-    w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (c) 1998 - 2001  Frodo Looijaard <frodol@dds.nl>,
-                               Philip Edelbrock <phil@netroedge.com>,
-                               and Mark Studebaker <mdsxyz123@yahoo.com>
-    Copyright (c) 2007 - 2008  Jean Delvare <khali@linux-fr.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.
-*/
+ * w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Copyright (c) 1998 - 2001  Frodo Looijaard <frodol@dds.nl>,
+ *			      Philip Edelbrock <phil@netroedge.com>,
+ *			      and Mark Studebaker <mdsxyz123@yahoo.com>
+ * Copyright (c) 2007 - 2008  Jean Delvare <khali@linux-fr.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.
+ */
 
 /*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    as99127f	7	3	0	3	0x31	0x12c3	yes	no
-    as99127f rev.2 (type_name = as99127f)	0x31	0x5ca3	yes	no
-    w83781d	7	3	0	3	0x10-1	0x5ca3	yes	yes
-    w83782d	9	3	2-4	3	0x30	0x5ca3	yes	yes
-    w83783s	5-6	3	2	1-2	0x40	0x5ca3	yes	no
-
-*/
+ * Supports following chips:
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * as99127f	7	3	0	3	0x31	0x12c3	yes	no
+ * as99127f rev.2 (type_name = as99127f)	0x31	0x5ca3	yes	no
+ * w83781d	7	3	0	3	0x10-1	0x5ca3	yes	yes
+ * w83782d	9	3	2-4	3	0x30	0x5ca3	yes	yes
+ * w83783s	5-6	3	2	1-2	0x40	0x5ca3	yes	no
+ *
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -145,8 +145,10 @@ static const u8 W83781D_REG_PWM[] = { 0x5B, 0x5A, 0x5E, 0x5F };
 #define W83781D_REG_I2C_ADDR		0x48
 #define W83781D_REG_I2C_SUBADDR		0x4A
 
-/* The following are undocumented in the data sheets however we
-   received the information in an email from Winbond tech support */
+/*
+ * The following are undocumented in the data sheets however we
+ * received the information in an email from Winbond tech support
+ */
 /* Sensor selection - not on 781d */
 #define W83781D_REG_SCFG1		0x5D
 static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
@@ -182,9 +184,9 @@ FAN_FROM_REG(u8 val, int div)
 #define TEMP_TO_REG(val)		SENSORS_LIMIT((val) / 1000, -127, 128)
 #define TEMP_FROM_REG(val)		((val) * 1000)
 
-#define BEEP_MASK_FROM_REG(val,type)	((type) == as99127f ? \
+#define BEEP_MASK_FROM_REG(val, type)	((type) == as99127f ? \
 					 (~(val)) & 0x7fff : (val) & 0xff7fff)
-#define BEEP_MASK_TO_REG(val,type)	((type) == as99127f ? \
+#define BEEP_MASK_TO_REG(val, type)	((type) == as99127f ? \
 					 (~(val)) & 0x7fff : (val) & 0xff7fff)
 
 #define DIV_FROM_REG(val)		(1 << (val))
@@ -238,9 +240,11 @@ struct w83781d_data {
 	u32 beep_mask;		/* Register encoding, combined */
 	u8 pwm[4];		/* Register value */
 	u8 pwm2_enable;		/* Boolean */
-	u16 sens[3];		/* 782D/783S only.
-				   1 = pentium diode; 2 = 3904 diode;
-				   4 = thermistor */
+	u16 sens[3];		/*
+				 * 782D/783S only.
+				 * 1 = pentium diode; 2 = 3904 diode;
+				 * 4 = thermistor
+				 */
 	u8 vrm;
 };
 
@@ -254,7 +258,7 @@ static void w83781d_init_device(struct device *dev);
 
 /* following are the sysfs callback functions */
 #define show_in_reg(reg) \
-static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \
 		char *buf) \
 { \
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
@@ -267,20 +271,21 @@ show_in_reg(in_min);
 show_in_reg(in_max);
 
 #define store_in_reg(REG, reg) \
-static ssize_t store_in_##reg (struct device *dev, struct device_attribute \
+static ssize_t store_in_##reg(struct device *dev, struct device_attribute \
 		*da, const char *buf, size_t count) \
 { \
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
 	struct w83781d_data *data = dev_get_drvdata(dev); \
 	int nr = attr->index; \
-	u32 val; \
-	 \
-	val = simple_strtoul(buf, NULL, 10); \
-	 \
+	unsigned long val; \
+	int err = kstrtoul(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
 	data->in_##reg[nr] = IN_TO_REG(val); \
-	w83781d_write_value(data, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
-	 \
+	w83781d_write_value(data, W83781D_REG_IN_##REG(nr), \
+			    data->in_##reg[nr]); \
+	\
 	mutex_unlock(&data->update_lock); \
 	return count; \
 }
@@ -306,12 +311,12 @@ sysfs_in_offsets(7);
 sysfs_in_offsets(8);
 
 #define show_fan_reg(reg) \
-static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \
 		char *buf) \
 { \
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
 	struct w83781d_data *data = w83781d_update_device(dev); \
-	return sprintf(buf,"%ld\n", \
+	return sprintf(buf, "%ld\n", \
 		FAN_FROM_REG(data->reg[attr->index], \
 			DIV_FROM_REG(data->fan_div[attr->index]))); \
 }
@@ -325,9 +330,12 @@ store_fan_min(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct w83781d_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] =
@@ -350,17 +358,17 @@ static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
 		show_fan_min, store_fan_min, 2);
 
 #define show_temp_reg(reg) \
-static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \
 		char *buf) \
 { \
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
 	struct w83781d_data *data = w83781d_update_device(dev); \
 	int nr = attr->index; \
 	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		return sprintf(buf,"%d\n", \
+		return sprintf(buf, "%d\n", \
 			LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
 	} else {	/* TEMP1 */ \
-		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
+		return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->reg)); \
 	} \
 }
 show_temp_reg(temp);
@@ -368,16 +376,16 @@ show_temp_reg(temp_max);
 show_temp_reg(temp_max_hyst);
 
 #define store_temp_reg(REG, reg) \
-static ssize_t store_temp_##reg (struct device *dev, \
+static ssize_t store_temp_##reg(struct device *dev, \
 		struct device_attribute *da, const char *buf, size_t count) \
 { \
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
 	struct w83781d_data *data = dev_get_drvdata(dev); \
 	int nr = attr->index; \
 	long val; \
-	 \
-	val = simple_strtol(buf, NULL, 10); \
-	 \
+	int err = kstrtol(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
 	 \
 	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
@@ -425,13 +433,17 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
 }
 
 static ssize_t
-store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+store_vrm_reg(struct device *dev, struct device_attribute *attr,
+	      const char *buf, size_t count)
 {
 	struct w83781d_data *data = dev_get_drvdata(dev);
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
-	data->vrm = val;
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	data->vrm = SENSORS_LIMIT(val, 0, 255);
 
 	return count;
 }
@@ -480,7 +492,8 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
 static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5);
 static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp3_alarm, NULL, 0);
 
-static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_beep_mask(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
 	struct w83781d_data *data = w83781d_update_device(dev);
 	return sprintf(buf, "%ld\n",
@@ -492,9 +505,12 @@ store_beep_mask(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
 	struct w83781d_data *data = dev_get_drvdata(dev);
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->beep_mask &= 0x8000; /* preserve beep enable */
@@ -529,10 +545,14 @@ store_beep(struct device *dev, struct device_attribute *attr,
 {
 	struct w83781d_data *data = dev_get_drvdata(dev);
 	int bitnr = to_sensor_dev_attr(attr)->index;
-	unsigned long bit;
 	u8 reg;
+	unsigned long bit;
+	int err;
+
+	err = kstrtoul(buf, 10, &bit);
+	if (err)
+		return err;
 
-	bit = simple_strtoul(buf, NULL, 10);
 	if (bit & ~1)
 		return -EINVAL;
 
@@ -620,10 +640,12 @@ show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
 		       (long) DIV_FROM_REG(data->fan_div[attr->index]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t
 store_fan_div(struct device *dev, struct device_attribute *da,
 		const char *buf, size_t count)
@@ -633,7 +655,12 @@ store_fan_div(struct device *dev, struct device_attribute *da,
 	unsigned long min;
 	int nr = attr->index;
 	u8 reg;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -643,10 +670,12 @@ store_fan_div(struct device *dev, struct device_attribute *da,
 
 	data->fan_div[nr] = DIV_TO_REG(val, data->type);
 
-	reg = (w83781d_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
-	       & (nr==0 ? 0xcf : 0x3f))
-	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
-	w83781d_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
+	reg = (w83781d_read_value(data, nr == 2 ?
+				  W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
+		& (nr == 0 ? 0xcf : 0x3f))
+	      | ((data->fan_div[nr] & 0x03) << (nr == 0 ? 4 : 6));
+	w83781d_write_value(data, nr == 2 ?
+			    W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
 
 	/* w83781d and as99127f don't have extended divisor bits */
 	if (data->type != w83781d && data->type != as99127f) {
@@ -693,9 +722,12 @@ store_pwm(struct device *dev, struct device_attribute *da, const char *buf,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct w83781d_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
@@ -709,9 +741,13 @@ store_pwm2_enable(struct device *dev, struct device_attribute *da,
 		const char *buf, size_t count)
 {
 	struct w83781d_data *data = dev_get_drvdata(dev);
-	u32 val, reg;
+	unsigned long val;
+	u32 reg;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -761,9 +797,13 @@ store_sensor(struct device *dev, struct device_attribute *da,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct w83781d_data *data = dev_get_drvdata(dev);
 	int nr = attr->index;
-	u32 val, tmp;
+	unsigned long val;
+	u32 tmp;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -813,7 +853,8 @@ static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR,
 static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR,
 	show_sensor, store_sensor, 2);
 
-/* Assumes that adapter is of I2C, not ISA variety.
+/*
+ * Assumes that adapter is of I2C, not ISA variety.
  * OTHERWISE DON'T CALL THIS
  */
 static int
@@ -911,7 +952,7 @@ ERROR_SC_1:
 	&sensor_dev_attr_temp##X##_alarm.dev_attr.attr,		\
 	&sensor_dev_attr_temp##X##_beep.dev_attr.attr
 
-static struct attribute* w83781d_attributes[] = {
+static struct attribute *w83781d_attributes[] = {
 	IN_UNIT_ATTRS(0),
 	IN_UNIT_ATTRS(2),
 	IN_UNIT_ATTRS(3),
@@ -934,23 +975,58 @@ static const struct attribute_group w83781d_group = {
 	.attrs = w83781d_attributes,
 };
 
-static struct attribute *w83781d_attributes_opt[] = {
+static struct attribute *w83781d_attributes_in1[] = {
 	IN_UNIT_ATTRS(1),
+	NULL
+};
+static const struct attribute_group w83781d_group_in1 = {
+	.attrs = w83781d_attributes_in1,
+};
+
+static struct attribute *w83781d_attributes_in78[] = {
 	IN_UNIT_ATTRS(7),
 	IN_UNIT_ATTRS(8),
+	NULL
+};
+static const struct attribute_group w83781d_group_in78 = {
+	.attrs = w83781d_attributes_in78,
+};
+
+static struct attribute *w83781d_attributes_temp3[] = {
 	TEMP_UNIT_ATTRS(3),
+	NULL
+};
+static const struct attribute_group w83781d_group_temp3 = {
+	.attrs = w83781d_attributes_temp3,
+};
+
+static struct attribute *w83781d_attributes_pwm12[] = {
 	&sensor_dev_attr_pwm1.dev_attr.attr,
 	&sensor_dev_attr_pwm2.dev_attr.attr,
+	&dev_attr_pwm2_enable.attr,
+	NULL
+};
+static const struct attribute_group w83781d_group_pwm12 = {
+	.attrs = w83781d_attributes_pwm12,
+};
+
+static struct attribute *w83781d_attributes_pwm34[] = {
 	&sensor_dev_attr_pwm3.dev_attr.attr,
 	&sensor_dev_attr_pwm4.dev_attr.attr,
-	&dev_attr_pwm2_enable.attr,
+	NULL
+};
+static const struct attribute_group w83781d_group_pwm34 = {
+	.attrs = w83781d_attributes_pwm34,
+};
+
+static struct attribute *w83781d_attributes_other[] = {
 	&sensor_dev_attr_temp1_type.dev_attr.attr,
 	&sensor_dev_attr_temp2_type.dev_attr.attr,
 	&sensor_dev_attr_temp3_type.dev_attr.attr,
 	NULL
 };
-static const struct attribute_group w83781d_group_opt = {
-	.attrs = w83781d_attributes_opt,
+static const struct attribute_group w83781d_group_other = {
+	.attrs = w83781d_attributes_other,
 };
 
 /* No clean up is done on error, it's up to the caller */
@@ -959,56 +1035,23 @@ w83781d_create_files(struct device *dev, int kind, int is_isa)
 {
 	int err;
 
-	if ((err = sysfs_create_group(&dev->kobj, &w83781d_group)))
+	err = sysfs_create_group(&dev->kobj, &w83781d_group);
+	if (err)
 		return err;
 
 	if (kind != w83783s) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_in1_input.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in1_min.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in1_max.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in1_alarm.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in1_beep.dev_attr)))
+		err = sysfs_create_group(&dev->kobj, &w83781d_group_in1);
+		if (err)
 			return err;
 	}
 	if (kind != as99127f && kind != w83781d && kind != w83783s) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_in7_input.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in7_min.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in7_max.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in7_alarm.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in7_beep.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in8_input.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in8_min.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in8_max.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in8_alarm.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_in8_beep.dev_attr)))
+		err = sysfs_create_group(&dev->kobj, &w83781d_group_in78);
+		if (err)
 			return err;
 	}
 	if (kind != w83783s) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_temp3_input.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_temp3_max.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_temp3_max_hyst.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_temp3_alarm.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_temp3_beep.dev_attr)))
+		err = sysfs_create_group(&dev->kobj, &w83781d_group_temp3);
+		if (err)
 			return err;
 
 		if (kind != w83781d) {
@@ -1021,30 +1064,29 @@ w83781d_create_files(struct device *dev, int kind, int is_isa)
 	}
 
 	if (kind != w83781d && kind != as99127f) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm1.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_pwm2.dev_attr))
-		    || (err = device_create_file(dev, &dev_attr_pwm2_enable)))
+		err = sysfs_create_group(&dev->kobj, &w83781d_group_pwm12);
+		if (err)
 			return err;
 	}
 	if (kind == w83782d && !is_isa) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_pwm3.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_pwm4.dev_attr)))
+		err = sysfs_create_group(&dev->kobj, &w83781d_group_pwm34);
+		if (err)
 			return err;
 	}
 
 	if (kind != as99127f && kind != w83781d) {
-		if ((err = device_create_file(dev,
-				&sensor_dev_attr_temp1_type.dev_attr))
-		    || (err = device_create_file(dev,
-				&sensor_dev_attr_temp2_type.dev_attr)))
+		err = device_create_file(dev,
+					 &sensor_dev_attr_temp1_type.dev_attr);
+		if (err)
+			return err;
+		err = device_create_file(dev,
+					 &sensor_dev_attr_temp2_type.dev_attr);
+		if (err)
 			return err;
 		if (kind != w83783s) {
-			if ((err = device_create_file(dev,
-					&sensor_dev_attr_temp3_type.dev_attr)))
+			err = device_create_file(dev,
+					&sensor_dev_attr_temp3_type.dev_attr);
+			if (err)
 				return err;
 		}
 	}
@@ -1066,9 +1108,11 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info)
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 
-	/* We block updates of the ISA device to minimize the risk of
-	   concurrent access to the same W83781D chip through different
-	   interfaces. */
+	/*
+	 * We block updates of the ISA device to minimize the risk of
+	 * concurrent access to the same W83781D chip through different
+	 * interfaces.
+	 */
 	if (isa)
 		mutex_lock(&isa->update_lock);
 
@@ -1083,15 +1127,17 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info)
 	/* Check for Winbond or Asus ID if in bank 0 */
 	if (!(val1 & 0x07) &&
 	    ((!(val1 & 0x80) && val2 != 0xa3 && val2 != 0xc3) ||
-	     ( (val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) {
+	     ((val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) {
 		dev_dbg(&adapter->dev,
 			"Detection of w83781d chip failed at step 4\n");
 		goto err_nodev;
 	}
-	/* If Winbond SMBus, check address at 0x48.
-	   Asus doesn't support, except for as99127f rev.2 */
+	/*
+	 * If Winbond SMBus, check address at 0x48.
+	 * Asus doesn't support, except for as99127f rev.2
+	 */
 	if ((!(val1 & 0x80) && val2 == 0xa3) ||
-	    ( (val1 & 0x80) && val2 == 0x5c)) {
+	    ((val1 & 0x80) && val2 == 0x5c)) {
 		if (i2c_smbus_read_byte_data(client, W83781D_REG_I2C_ADDR)
 		    != address) {
 			dev_dbg(&adapter->dev,
@@ -1149,6 +1195,17 @@ w83781d_detect(struct i2c_client *client, struct i2c_board_info *info)
 	return -ENODEV;
 }
 
+static void w83781d_remove_files(struct device *dev)
+{
+	sysfs_remove_group(&dev->kobj, &w83781d_group);
+	sysfs_remove_group(&dev->kobj, &w83781d_group_in1);
+	sysfs_remove_group(&dev->kobj, &w83781d_group_in78);
+	sysfs_remove_group(&dev->kobj, &w83781d_group_temp3);
+	sysfs_remove_group(&dev->kobj, &w83781d_group_pwm12);
+	sysfs_remove_group(&dev->kobj, &w83781d_group_pwm34);
+	sysfs_remove_group(&dev->kobj, &w83781d_group_other);
+}
+
 static int
 w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
@@ -1191,9 +1248,7 @@ w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	return 0;
 
 ERROR4:
-	sysfs_remove_group(&dev->kobj, &w83781d_group);
-	sysfs_remove_group(&dev->kobj, &w83781d_group_opt);
-
+	w83781d_remove_files(dev);
 	if (data->lm75[0])
 		i2c_unregister_device(data->lm75[0]);
 	if (data->lm75[1])
@@ -1211,9 +1266,7 @@ w83781d_remove(struct i2c_client *client)
 	struct device *dev = &client->dev;
 
 	hwmon_device_unregister(data->hwmon_dev);
-
-	sysfs_remove_group(&dev->kobj, &w83781d_group);
-	sysfs_remove_group(&dev->kobj, &w83781d_group_opt);
+	w83781d_remove_files(dev);
 
 	if (data->lm75[0])
 		i2c_unregister_device(data->lm75[0]);
@@ -1310,35 +1363,47 @@ w83781d_init_device(struct device *dev)
 	int type = data->type;
 	u8 tmp;
 
-	if (reset && type != as99127f) { /* this resets registers we don't have
-					   documentation for on the as99127f */
-		/* Resetting the chip has been the default for a long time,
-		   but it causes the BIOS initializations (fan clock dividers,
-		   thermal sensor types...) to be lost, so it is now optional.
-		   It might even go away if nobody reports it as being useful,
-		   as I see very little reason why this would be needed at
-		   all. */
+	if (reset && type != as99127f) { /*
+					  * this resets registers we don't have
+					  * documentation for on the as99127f
+					  */
+		/*
+		 * Resetting the chip has been the default for a long time,
+		 * but it causes the BIOS initializations (fan clock dividers,
+		 * thermal sensor types...) to be lost, so it is now optional.
+		 * It might even go away if nobody reports it as being useful,
+		 * as I see very little reason why this would be needed at
+		 * all.
+		 */
 		dev_info(dev, "If reset=1 solved a problem you were "
 			 "having, please report!\n");
 
 		/* save these registers */
 		i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
 		p = w83781d_read_value(data, W83781D_REG_PWMCLK12);
-		/* Reset all except Watchdog values and last conversion values
-		   This sets fan-divs to 2, among others */
+		/*
+		 * Reset all except Watchdog values and last conversion values
+		 * This sets fan-divs to 2, among others
+		 */
 		w83781d_write_value(data, W83781D_REG_CONFIG, 0x80);
-		/* Restore the registers and disable power-on abnormal beep.
-		   This saves FAN 1/2/3 input/output values set by BIOS. */
+		/*
+		 * Restore the registers and disable power-on abnormal beep.
+		 * This saves FAN 1/2/3 input/output values set by BIOS.
+		 */
 		w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
 		w83781d_write_value(data, W83781D_REG_PWMCLK12, p);
-		/* Disable master beep-enable (reset turns it on).
-		   Individual beep_mask should be reset to off but for some reason
-		   disabling this bit helps some people not get beeped */
+		/*
+		 * Disable master beep-enable (reset turns it on).
+		 * Individual beep_mask should be reset to off but for some
+		 * reason disabling this bit helps some people not get beeped
+		 */
 		w83781d_write_value(data, W83781D_REG_BEEP_INTS2, 0);
 	}
 
-	/* Disable power-on abnormal beep, as advised by the datasheet.
-	   Already done if reset=1. */
+	/*
+	 * Disable power-on abnormal beep, as advised by the datasheet.
+	 * Already done if reset=1.
+	 */
 	if (init && !reset && type != as99127f) {
 		i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
 		w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
@@ -1444,7 +1509,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
 			}
 			/* Only PWM2 can be disabled */
 			data->pwm2_enable = (w83781d_read_value(data,
-					      W83781D_REG_PWMCLK12) & 0x08) >> 3;
+					     W83781D_REG_PWMCLK12) & 0x08) >> 3;
 		}
 
 		data->temp = w83781d_read_value(data, W83781D_REG_TEMP(1));
@@ -1495,8 +1560,10 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
 				     | (w83781d_read_value(data,
 						W83782D_REG_ALARM2) << 8);
 		} else {
-			/* No real-time status registers, fall back to
-			   interrupt status registers */
+			/*
+			 * No real-time status registers, fall back to
+			 * interrupt status registers
+			 */
 			data->alarms = w83781d_read_value(data,
 						W83781D_REG_ALARM1)
 				     | (w83781d_read_value(data,
@@ -1550,8 +1617,10 @@ static struct platform_device *pdev;
 
 static unsigned short isa_address = 0x290;
 
-/* I2C devices get this name attribute automatically, but for ISA devices
-   we must create it by ourselves. */
+/*
+ * I2C devices get this name attribute automatically, but for ISA devices
+ * we must create it by ourselves.
+ */
 static ssize_t
 show_name(struct device *dev, struct device_attribute *devattr, char *buf)
 {
@@ -1581,8 +1650,10 @@ static int w83781d_alias_detect(struct i2c_client *client, u8 chipid)
 	if (w83781d_read_value(isa, W83781D_REG_WCHIPID) != chipid)
 		return 0;	/* Chip type doesn't match */
 
-	/* We compare all the limit registers, the config register and the
-	 * interrupt mask registers */
+	/*
+	 * We compare all the limit registers, the config register and the
+	 * interrupt mask registers
+	 */
 	for (i = 0x2b; i <= 0x3d; i++) {
 		if (w83781d_read_value(isa, i) !=
 		    i2c_smbus_read_byte_data(client, i))
@@ -1663,12 +1734,14 @@ w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value)
 	}
 }
 
-/* The SMBus locks itself, usually, but nothing may access the Winbond between
-   bank switches. ISA access must always be locked explicitly!
-   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the W83781D access and should not be necessary.
-   There are some ugly typecasts here, but the good news is - they should
-   nowhere else be necessary! */
+/*
+ * The SMBus locks itself, usually, but nothing may access the Winbond between
+ * bank switches. ISA access must always be locked explicitly!
+ * We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
+ * would slow down the W83781D access and should not be necessary.
+ * There are some ugly typecasts here, but the good news is - they should
+ * nowhere else be necessary!
+ */
 static int
 w83781d_read_value(struct w83781d_data *data, u16 reg)
 {
@@ -1754,8 +1827,7 @@ w83781d_isa_probe(struct platform_device *pdev)
 	return 0;
 
  exit_remove_files:
-	sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
-	sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
+	w83781d_remove_files(&pdev->dev);
 	device_remove_file(&pdev->dev, &dev_attr_name);
 	kfree(data);
  exit_release_region:
@@ -1770,8 +1842,7 @@ w83781d_isa_remove(struct platform_device *pdev)
 	struct w83781d_data *data = platform_get_drvdata(pdev);
 
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
-	sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
+	w83781d_remove_files(&pdev->dev);
 	device_remove_file(&pdev->dev, &dev_attr_name);
 	release_region(data->isa_addr + W83781D_ADDR_REG_OFFSET, 2);
 	kfree(data);
@@ -1795,9 +1866,11 @@ w83781d_isa_found(unsigned short address)
 	int val, save, found = 0;
 	int port;
 
-	/* Some boards declare base+0 to base+7 as a PNP device, some base+4
+	/*
+	 * Some boards declare base+0 to base+7 as a PNP device, some base+4
 	 * to base+7 and some base+5 to base+6. So we better request each port
-	 * individually for the probing phase. */
+	 * individually for the probing phase.
+	 */
 	for (port = address; port < address + W83781D_EXTENT; port++) {
 		if (!request_region(port, 1, "w83781d")) {
 			pr_debug("Failed to request port 0x%x\n", port);
@@ -1806,8 +1879,10 @@ w83781d_isa_found(unsigned short address)
 	}
 
 #define REALLY_SLOW_IO
-	/* We need the timeouts for at least some W83781D-like
-	   chips. But only if we read 'undefined' registers. */
+	/*
+	 * We need the timeouts for at least some W83781D-like
+	 * chips. But only if we read 'undefined' registers.
+	 */
 	val = inb_p(address + 1);
 	if (inb_p(address + 2) != val
 	 || inb_p(address + 3) != val
@@ -1817,8 +1892,10 @@ w83781d_isa_found(unsigned short address)
 	}
 #undef REALLY_SLOW_IO
 
-	/* We should be able to change the 7 LSB of the address port. The
-	   MSB (busy flag) should be clear initially, set after the write. */
+	/*
+	 * We should be able to change the 7 LSB of the address port. The
+	 * MSB (busy flag) should be clear initially, set after the write.
+	 */
 	save = inb_p(address + W83781D_ADDR_REG_OFFSET);
 	if (save & 0x80) {
 		pr_debug("Detection failed at step %d\n", 2);
@@ -2004,8 +2081,10 @@ sensors_w83781d_init(void)
 {
 	int res;
 
-	/* We register the ISA device first, so that we can skip the
-	 * registration of an I2C interface to the same device. */
+	/*
+	 * We register the ISA device first, so that we can skip the
+	 * registration of an I2C interface to the same device.
+	 */
 	res = w83781d_isa_register();
 	if (res)
 		goto exit;
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 35aa514..2f446f9 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -1,36 +1,36 @@
 /*
-    w83791d.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-
-    Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * w83791d.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ *
+ * Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 /*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    w83791d	10	5	5	3	0x71	0x5ca3	yes	no
-
-    The w83791d chip appears to be part way between the 83781d and the
-    83792d. Thus, this file is derived from both the w83792d.c and
-    w83781d.c files.
-
-    The w83791g chip is the same as the w83791d but lead-free.
-*/
+ * Supports following chips:
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * w83791d	10	5	5	3	0x71	0x5ca3	yes	no
+ *
+ * The w83791d chip appears to be part way between the 83781d and the
+ * 83792d. Thus, this file is derived from both the w83792d.c and
+ * w83781d.c files.
+ *
+ * The w83791g chip is the same as the w83791d but lead-free.
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -198,10 +198,12 @@ static const u8 W83791D_REG_BEEP_CTRL[3] = {
 #define W83791D_REG_VBAT		0x5D
 #define W83791D_REG_I2C_ADDR		0x48
 
-/* The SMBus locks itself. The Winbond W83791D has a bank select register
-   (index 0x4e), but the driver only accesses registers in bank 0. Since
-   we don't switch banks, we don't need any special code to handle
-   locking access between bank switches */
+/*
+ * The SMBus locks itself. The Winbond W83791D has a bank select register
+ * (index 0x4e), but the driver only accesses registers in bank 0. Since
+ * we don't switch banks, we don't need any special code to handle
+ * locking access between bank switches
+ */
 static inline int w83791d_read(struct i2c_client *client, u8 reg)
 {
 	return i2c_smbus_read_byte_data(client, reg);
@@ -212,9 +214,11 @@ static inline int w83791d_write(struct i2c_client *client, u8 reg, u8 value)
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-/* The analog voltage inputs have 16mV LSB. Since the sysfs output is
-   in mV as would be measured on the chip input pin, need to just
-   multiply/divide by 16 to translate from/to register values. */
+/*
+ * The analog voltage inputs have 16mV LSB. Since the sysfs output is
+ * in mV as would be measured on the chip input pin, need to just
+ * multiply/divide by 16 to translate from/to register values.
+ */
 #define IN_TO_REG(val)		(SENSORS_LIMIT((((val) + 8) / 16), 0, 255))
 #define IN_FROM_REG(val)	((val) * 16)
 
@@ -226,7 +230,7 @@ static u8 fan_to_reg(long rpm, int div)
 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
-#define FAN_FROM_REG(val,div)	((val) == 0   ? -1 : \
+#define FAN_FROM_REG(val, div)	((val) == 0 ? -1 : \
 				((val) == 255 ? 0 : \
 					1350000 / ((val) * (div))))
 
@@ -237,10 +241,12 @@ static u8 fan_to_reg(long rpm, int div)
 				 (val) < 0 ? ((val) - 500) / 1000 : \
 				 ((val) + 500) / 1000)
 
-/* for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius
-   Assumes the top 8 bits are the integral amount and the bottom 8 bits
-   are the fractional amount. Since we only have 0.5 degree resolution,
-   the bottom 7 bits will always be zero */
+/*
+ * for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius
+ * Assumes the top 8 bits are the integral amount and the bottom 8 bits
+ * are the fractional amount. Since we only have 0.5 degree resolution,
+ * the bottom 7 bits will always be zero
+ */
 #define TEMP23_FROM_REG(val)	((val) / 128 * 500)
 #define TEMP23_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
 				 (val) >= 127500 ? 0x7F80 : \
@@ -300,17 +306,19 @@ struct w83791d_data {
 
 	s8 temp1[3];		/* current, over, thyst */
 	s16 temp_add[2][3];	/* fixed point value. Top 8 bits are the
-				   integral part, bottom 8 bits are the
-				   fractional part. We only use the top
-				   9 bits as the resolution is only
-				   to the 0.5 degree C...
-				   two sensors with three values
-				   (cur, over, hyst)  */
+				 * integral part, bottom 8 bits are the
+				 * fractional part. We only use the top
+				 * 9 bits as the resolution is only
+				 * to the 0.5 degree C...
+				 * two sensors with three values
+				 * (cur, over, hyst)
+				 */
 
 	/* PWMs */
 	u8 pwm[5];		/* pwm duty cycle */
 	u8 pwm_enable[3];	/* pwm enable status for fan 1-3
-					(fan 4-5 only support manual mode) */
+				 * (fan 4-5 only support manual mode)
+				 */
 
 	u8 temp_target[3];	/* pwm 1-3 target temperature */
 	u8 temp_tolerance[3];	/* pwm 1-3 temperature tolerance */
@@ -366,7 +374,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
 						to_sensor_dev_attr(attr); \
 	struct w83791d_data *data = w83791d_update_device(dev); \
 	int nr = sensor_attr->index; \
-	return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
 }
 
 show_in_reg(in);
@@ -382,9 +390,11 @@ static ssize_t store_in_##reg(struct device *dev, \
 						to_sensor_dev_attr(attr); \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct w83791d_data *data = i2c_get_clientdata(client); \
-	unsigned long val = simple_strtoul(buf, NULL, 10); \
 	int nr = sensor_attr->index; \
-	 \
+	unsigned long val; \
+	int err = kstrtoul(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
 	data->in_##reg[nr] = IN_TO_REG(val); \
 	w83791d_write(client, W83791D_REG_IN_##REG[nr], data->in_##reg[nr]); \
@@ -455,7 +465,14 @@ static ssize_t store_beep(struct device *dev, struct device_attribute *attr,
 	struct w83791d_data *data = i2c_get_clientdata(client);
 	int bitnr = sensor_attr->index;
 	int bytenr = bitnr / 8;
-	long val = simple_strtol(buf, NULL, 10) ? 1 : 0;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	val = val ? 1 : 0;
 
 	mutex_lock(&data->update_lock);
 
@@ -485,8 +502,10 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
 }
 
-/* Note: The bitmask for the beep enable/disable is different than
-   the bitmask for the alarm. */
+/*
+ * Note: The bitmask for the beep enable/disable is different than
+ * the bitmask for the alarm.
+ */
 static struct sensor_device_attribute sda_in_beep[] = {
 	SENSOR_ATTR(in0_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 0),
 	SENSOR_ATTR(in1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 13),
@@ -521,7 +540,7 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
 						to_sensor_dev_attr(attr); \
 	struct w83791d_data *data = w83791d_update_device(dev); \
 	int nr = sensor_attr->index; \
-	return sprintf(buf,"%d\n", \
+	return sprintf(buf, "%d\n", \
 		FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
 }
 
@@ -534,8 +553,13 @@ static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83791d_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
 	int nr = sensor_attr->index;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr]));
@@ -554,10 +578,12 @@ static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
 				const char *buf, size_t count)
 {
@@ -572,12 +598,18 @@ static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
 	int indx = 0;
 	u8 keep_mask = 0;
 	u8 new_shift = 0;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	/* Save fan_min */
 	min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
 
 	mutex_lock(&data->update_lock);
-	data->fan_div[nr] = div_to_reg(nr, simple_strtoul(buf, NULL, 10));
+	data->fan_div[nr] = div_to_reg(nr, val);
 
 	switch (nr) {
 	case 0:
@@ -918,8 +950,13 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *devattr,
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83791d_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
 	int nr = attr->index;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp1[nr] = TEMP1_TO_REG(val);
@@ -946,10 +983,15 @@ static ssize_t store_temp23(struct device *dev,
 	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83791d_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
 	int nr = attr->nr;
 	int index = attr->index;
 
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
+
 	mutex_lock(&data->update_lock);
 	data->temp_add[nr][index] = TEMP23_TO_REG(val);
 	w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2],
@@ -985,8 +1027,10 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
 			show_temp23, store_temp23, 1, 2),
 };
 
-/* Note: The bitmask for the beep enable/disable is different than
-   the bitmask for the alarm. */
+/*
+ * Note: The bitmask for the beep enable/disable is different than
+ * the bitmask for the alarm.
+ */
 static struct sensor_device_attribute sda_temp_beep[] = {
 	SENSOR_ATTR(temp1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 4),
 	SENSOR_ATTR(temp2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 5),
@@ -1035,13 +1079,20 @@ static ssize_t store_beep_mask(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83791d_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
 	int i;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
-	/* The beep_enable state overrides any enabling request from
-	   the masks */
+	/*
+	 * The beep_enable state overrides any enabling request from
+	 * the masks
+	 */
 	data->beep_mask = BEEP_MASK_TO_REG(val) & ~GLOBAL_BEEP_ENABLE_MASK;
 	data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);
 
@@ -1063,7 +1114,12 @@ static ssize_t store_beep_enable(struct device *dev,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83791d_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 
@@ -1073,8 +1129,10 @@ static ssize_t store_beep_enable(struct device *dev,
 	data->beep_mask &= ~GLOBAL_BEEP_ENABLE_MASK;
 	data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);
 
-	/* The global control is in the second beep control register
-	   so only need to update that register */
+	/*
+	 * The global control is in the second beep control register
+	 * so only need to update that register
+	 */
 	val = (data->beep_mask >> 8) & 0xff;
 
 	w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val);
@@ -1113,36 +1171,44 @@ static ssize_t store_vrm_reg(struct device *dev,
 				const char *buf, size_t count)
 {
 	struct w83791d_data *data = dev_get_drvdata(dev);
+	unsigned long val;
+	int err;
+
+	/*
+	 * No lock needed as vrm is internal to the driver
+	 * (not read from a chip register) and so is not
+	 * updated in w83791d_update_device()
+	 */
 
-	/* No lock needed as vrm is internal to the driver
-	   (not read from a chip register) and so is not
-	   updated in w83791d_update_device() */
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
+	data->vrm = val;
 	return count;
 }
 
 static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
 
 #define IN_UNIT_ATTRS(X) \
-	&sda_in_input[X].dev_attr.attr, \
-	&sda_in_min[X].dev_attr.attr,   \
-	&sda_in_max[X].dev_attr.attr,   \
-	&sda_in_beep[X].dev_attr.attr,  \
+	&sda_in_input[X].dev_attr.attr,	\
+	&sda_in_min[X].dev_attr.attr,	\
+	&sda_in_max[X].dev_attr.attr,	\
+	&sda_in_beep[X].dev_attr.attr,	\
 	&sda_in_alarm[X].dev_attr.attr
 
 #define FAN_UNIT_ATTRS(X) \
-	&sda_fan_input[X].dev_attr.attr,        \
-	&sda_fan_min[X].dev_attr.attr,          \
-	&sda_fan_div[X].dev_attr.attr,          \
-	&sda_fan_beep[X].dev_attr.attr,         \
+	&sda_fan_input[X].dev_attr.attr,	\
+	&sda_fan_min[X].dev_attr.attr,		\
+	&sda_fan_div[X].dev_attr.attr,		\
+	&sda_fan_beep[X].dev_attr.attr,		\
 	&sda_fan_alarm[X].dev_attr.attr
 
 #define TEMP_UNIT_ATTRS(X) \
-	&sda_temp_input[X].dev_attr.attr,       \
-	&sda_temp_max[X].dev_attr.attr,         \
-	&sda_temp_max_hyst[X].dev_attr.attr,    \
-	&sda_temp_beep[X].dev_attr.attr,        \
+	&sda_temp_input[X].dev_attr.attr,	\
+	&sda_temp_max[X].dev_attr.attr,		\
+	&sda_temp_max_hyst[X].dev_attr.attr,	\
+	&sda_temp_beep[X].dev_attr.attr,	\
 	&sda_temp_alarm[X].dev_attr.attr
 
 static struct attribute *w83791d_attributes[] = {
@@ -1186,9 +1252,11 @@ static const struct attribute_group w83791d_group = {
 	.attrs = w83791d_attributes,
 };
 
-/* Separate group of attributes for fan/pwm 4-5. Their pins can also be
-   in use for GPIO in which case their sysfs-interface should not be made
-   available */
+/*
+ * Separate group of attributes for fan/pwm 4-5. Their pins can also be
+ * in use for GPIO in which case their sysfs-interface should not be made
+ * available
+ */
 static struct attribute *w83791d_attributes_fanpwm45[] = {
 	FAN_UNIT_ATTRS(3),
 	FAN_UNIT_ATTRS(4),
@@ -1228,9 +1296,8 @@ static int w83791d_detect_subclients(struct i2c_client *client)
 	}
 
 	val = w83791d_read(client, W83791D_REG_I2C_SUBADDR);
-	if (!(val & 0x08)) {
+	if (!(val & 0x08))
 		data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7));
-	}
 	if (!(val & 0x80)) {
 		if ((data->lm75[0] != NULL) &&
 				((val & 0x7) == ((val >> 4) & 0x7))) {
@@ -1265,9 +1332,8 @@ static int w83791d_detect(struct i2c_client *client,
 	int val1, val2;
 	unsigned short address = client->addr;
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
-	}
 
 	if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80)
 		return -ENODEV;
@@ -1277,12 +1343,14 @@ static int w83791d_detect(struct i2c_client *client,
 	/* Check for Winbond ID if in bank 0 */
 	if (!(val1 & 0x07)) {
 		if ((!(val1 & 0x80) && val2 != 0xa3) ||
-		    ( (val1 & 0x80) && val2 != 0x5c)) {
+		    ((val1 & 0x80) && val2 != 0x5c)) {
 			return -ENODEV;
 		}
 	}
-	/* If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
-	   should match */
+	/*
+	 * If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
+	 * should match
+	 */
 	if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address)
 		return -ENODEV;
 
@@ -1332,14 +1400,16 @@ static int w83791d_probe(struct i2c_client *client,
 	/* Initialize the chip */
 	w83791d_init_client(client);
 
-	/* If the fan_div is changed, make sure there is a rational
-	   fan_min in place */
-	for (i = 0; i < NUMBER_OF_FANIN; i++) {
+	/*
+	 * If the fan_div is changed, make sure there is a rational
+	 * fan_min in place
+	 */
+	for (i = 0; i < NUMBER_OF_FANIN; i++)
 		data->fan_min[i] = w83791d_read(client, W83791D_REG_FAN_MIN[i]);
-	}
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group)))
+	err = sysfs_create_group(&client->dev.kobj, &w83791d_group);
+	if (err)
 		goto error3;
 
 	/* Check if pins of fan/pwm 4-5 are in use as GPIO */
@@ -1398,19 +1468,20 @@ static void w83791d_init_client(struct i2c_client *client)
 	u8 tmp;
 	u8 old_beep;
 
-	/* The difference between reset and init is that reset
-	   does a hard reset of the chip via index 0x40, bit 7,
-	   but init simply forces certain registers to have "sane"
-	   values. The hope is that the BIOS has done the right
-	   thing (which is why the default is reset=0, init=0),
-	   but if not, reset is the hard hammer and init
-	   is the soft mallet both of which are trying to whack
-	   things into place...
-	   NOTE: The data sheet makes a distinction between
-	   "power on defaults" and "reset by MR". As far as I can tell,
-	   the hard reset puts everything into a power-on state so I'm
-	   not sure what "reset by MR" means or how it can happen.
-	   */
+	/*
+	 * The difference between reset and init is that reset
+	 * does a hard reset of the chip via index 0x40, bit 7,
+	 * but init simply forces certain registers to have "sane"
+	 * values. The hope is that the BIOS has done the right
+	 * thing (which is why the default is reset=0, init=0),
+	 * but if not, reset is the hard hammer and init
+	 * is the soft mallet both of which are trying to whack
+	 * things into place...
+	 * NOTE: The data sheet makes a distinction between
+	 * "power on defaults" and "reset by MR". As far as I can tell,
+	 * the hard reset puts everything into a power-on state so I'm
+	 * not sure what "reset by MR" means or how it can happen.
+	 */
 	if (reset || init) {
 		/* keep some BIOS settings when we... */
 		old_beep = w83791d_read(client, W83791D_REG_BEEP_CONFIG);
@@ -1494,8 +1565,10 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
 		data->fan_div[3] = reg_array_tmp[2] & 0x07;
 		data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07;
 
-		/* The fan divisor for fans 0-2 get bit 2 from
-		   bits 5-7 respectively of vbat register */
+		/*
+		 * The fan divisor for fans 0-2 get bit 2 from
+		 * bits 5-7 respectively of vbat register
+		 */
 		vbat_reg = w83791d_read(client, W83791D_REG_VBAT);
 		for (i = 0; i < 3; i++)
 			data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04;
@@ -1601,12 +1674,13 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev)
 		dev_dbg(dev, "fan_div[%d] is: 0x%02x\n", i, data->fan_div[i]);
 	}
 
-	/* temperature math is signed, but only print out the
-	   bits that matter */
+	/*
+	 * temperature math is signed, but only print out the
+	 * bits that matter
+	 */
 	dev_dbg(dev, "%d set of Temperatures: ===>\n", NUMBER_OF_TEMPIN);
-	for (i = 0; i < 3; i++) {
+	for (i = 0; i < 3; i++)
 		dev_dbg(dev, "temp1[%d] is: 0x%02x\n", i, (u8) data->temp1[i]);
-	}
 	for (i = 0; i < 2; i++) {
 		for (j = 0; j < 3; j++) {
 			dev_dbg(dev, "temp_add[%d][%d] is: 0x%04x\n", i, j,
@@ -1625,19 +1699,8 @@ static void w83791d_print_debug(struct w83791d_data *data, struct device *dev)
 }
 #endif
 
-static int __init sensors_w83791d_init(void)
-{
-	return i2c_add_driver(&w83791d_driver);
-}
-
-static void __exit sensors_w83791d_exit(void)
-{
-	i2c_del_driver(&w83791d_driver);
-}
+module_i2c_driver(w83791d_driver);
 
 MODULE_AUTHOR("Charles Spirakis <bezaur@gmail.com>");
 MODULE_DESCRIPTION("W83791D driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83791d_init);
-module_exit(sensors_w83791d_exit);
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index d3100ea..ffb5fdf 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -1,39 +1,39 @@
 /*
-    w83792d.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (C) 2004, 2005 Winbond Electronics Corp.
-                        Chunhao Huang <DZShen@Winbond.com.tw>,
-                        Rudolf Marek <r.marek@assembler.cz>
-
-    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.
-
-    Note:
-    1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver.
-    2. This driver is only for Winbond W83792D C version device, there
-       are also some motherboards with B version W83792D device. The
-       calculation method to in6-in7(measured value, limits) is a little
-       different between C and B version. C or B version can be identified
-       by CR[0x49h].
-*/
+ * w83792d.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	       monitoring
+ * Copyright (C) 2004, 2005 Winbond Electronics Corp.
+ *			    Chunhao Huang <DZShen@Winbond.com.tw>,
+ *			    Rudolf Marek <r.marek@assembler.cz>
+ *
+ * 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.
+ *
+ * Note:
+ * 1. This driver is only for 2.6 kernel, 2.4 kernel need a different driver.
+ * 2. This driver is only for Winbond W83792D C version device, there
+ *     are also some motherboards with B version W83792D device. The
+ *     calculation method to in6-in7(measured value, limits) is a little
+ *     different between C and B version. C or B version can be identified
+ *     by CR[0x49h].
+ */
 
 /*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    w83792d	9	7	7	3	0x7a	0x5ca3	yes	no
-*/
+ * Supports following chips:
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * w83792d	9	7	7	3	0x7a	0x5ca3	yes	no
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -218,14 +218,16 @@ static const u8 W83792D_REG_LEVELS[3][4] = {
 #define W83792D_REG_VBAT		0x5D
 #define W83792D_REG_I2C_ADDR		0x48
 
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
-#define IN_FROM_REG(nr,val) (((nr)<=1)?(val*2): \
-				((((nr)==6)||((nr)==7))?(val*6):(val*4)))
-#define IN_TO_REG(nr,val) (((nr)<=1)?(val/2): \
-				((((nr)==6)||((nr)==7))?(val/6):(val/4)))
+/*
+ * Conversions. Rounding and limit checking is only done on the TO_REG
+ * variants. Note that you should be a bit careful with which arguments
+ * these macros are called: arguments may be evaluated more than once.
+ * Fixing this is just not worth it.
+ */
+#define IN_FROM_REG(nr, val) (((nr) <= 1) ? ((val) * 2) : \
+		((((nr) == 6) || ((nr) == 7)) ? ((val) * 6) : ((val) * 4)))
+#define IN_TO_REG(nr, val) (((nr) <= 1) ? ((val) / 2) : \
+		((((nr) == 6) || ((nr) == 7)) ? ((val) / 6) : ((val) / 4)))
 
 static inline u8
 FAN_TO_REG(long rpm, int div)
@@ -236,7 +238,7 @@ FAN_TO_REG(long rpm, int div)
 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
-#define FAN_FROM_REG(val,div)	((val) == 0   ? -1 : \
+#define FAN_FROM_REG(val, div)	((val) == 0   ? -1 : \
 				((val) == 255 ? 0 : \
 						1350000 / ((val) * (div))))
 
@@ -265,7 +267,7 @@ DIV_TO_REG(long val)
 			break;
 		val >>= 1;
 	}
-	return ((u8) i);
+	return (u8)i;
 }
 
 struct w83792d_data {
@@ -287,8 +289,10 @@ struct w83792d_data {
 	u8 temp1[3];		/* current, over, thyst */
 	u8 temp_add[2][6];	/* Register value */
 	u8 fan_div[7];		/* Register encoding, shifted right */
-	u8 pwm[7];		/* We only consider the first 3 set of pwm,
-				   although 792 chip has 7 set of pwm. */
+	u8 pwm[7];		/*
+				 * We only consider the first 3 set of pwm,
+				 * although 792 chip has 7 set of pwm.
+				 */
 	u8 pwmenable[3];
 	u32 alarms;		/* realtime status register encoding,combined */
 	u8 chassis;		/* Chassis status */
@@ -333,12 +337,14 @@ static struct i2c_driver w83792d_driver = {
 static inline long in_count_from_reg(int nr, struct w83792d_data *data)
 {
 	/* in7 and in8 do not have low bits, but the formula still works */
-	return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03));
+	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. */
+/*
+ * 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);
@@ -357,37 +363,43 @@ static ssize_t show_in(struct device *dev, struct device_attribute *attr,
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	struct w83792d_data *data = w83792d_update_device(dev);
-	return sprintf(buf,"%ld\n", IN_FROM_REG(nr,(in_count_from_reg(nr, data))));
+	return sprintf(buf, "%ld\n",
+		       IN_FROM_REG(nr, in_count_from_reg(nr, data)));
 }
 
 #define show_in_reg(reg) \
 static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
 			char *buf) \
 { \
-	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+	struct sensor_device_attribute *sensor_attr \
+		= to_sensor_dev_attr(attr); \
 	int nr = sensor_attr->index; \
 	struct w83792d_data *data = w83792d_update_device(dev); \
-	return sprintf(buf,"%ld\n", (long)(IN_FROM_REG(nr, (data->reg[nr])*4))); \
+	return sprintf(buf, "%ld\n", \
+		       (long)(IN_FROM_REG(nr, data->reg[nr]) * 4)); \
 }
 
 show_in_reg(in_min);
 show_in_reg(in_max);
 
 #define store_in_reg(REG, reg) \
-static ssize_t store_in_##reg (struct device *dev, \
+static ssize_t store_in_##reg(struct device *dev, \
 				struct device_attribute *attr, \
 				const char *buf, size_t count) \
 { \
-	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+	struct sensor_device_attribute *sensor_attr \
+			= to_sensor_dev_attr(attr); \
 	int nr = sensor_attr->index; \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct w83792d_data *data = i2c_get_clientdata(client); \
-	u32 val; \
-	 \
-	val = simple_strtoul(buf, NULL, 10); \
+	unsigned long val; \
+	int err = kstrtoul(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
-	data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val)/4, 0, 255); \
-	w83792d_write_value(client, W83792D_REG_IN_##REG[nr], data->in_##reg[nr]); \
+	data->in_##reg[nr] = SENSORS_LIMIT(IN_TO_REG(nr, val) / 4, 0, 255); \
+	w83792d_write_value(client, W83792D_REG_IN_##REG[nr], \
+			    data->in_##reg[nr]); \
 	mutex_unlock(&data->update_lock); \
 	 \
 	return count; \
@@ -396,13 +408,14 @@ store_in_reg(MIN, min);
 store_in_reg(MAX, max);
 
 #define show_fan_reg(reg) \
-static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
 			char *buf) \
 { \
-	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
+	struct sensor_device_attribute *sensor_attr \
+			= to_sensor_dev_attr(attr); \
 	int nr = sensor_attr->index - 1; \
 	struct w83792d_data *data = w83792d_update_device(dev); \
-	return sprintf(buf,"%d\n", \
+	return sprintf(buf, "%d\n", \
 		FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
 }
 
@@ -417,9 +430,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index - 1;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
 	w83792d_write_value(client, W83792D_REG_FAN_MIN[nr],
@@ -439,10 +456,12 @@ show_fan_div(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr - 1]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t
 store_fan_div(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
@@ -455,13 +474,19 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
 	/*u8 reg;*/
 	u8 fan_div_reg = 0;
 	u8 tmp_fan_div;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	/* Save fan_min */
 	mutex_lock(&data->update_lock);
 	min = FAN_FROM_REG(data->fan_min[nr],
 			   DIV_FROM_REG(data->fan_div[nr]));
 
-	data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
+	data->fan_div[nr] = DIV_TO_REG(val);
 
 	fan_div_reg = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]);
 	fan_div_reg &= (nr & 0x01) ? 0x8f : 0xf8;
@@ -496,9 +521,13 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	s32 val;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtol(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->temp1[nr] = TEMP1_TO_REG(val);
 	w83792d_write_value(client, W83792D_REG_TEMP1[nr],
@@ -513,11 +542,12 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
 static ssize_t show_temp23(struct device *dev, struct device_attribute *attr,
 				char *buf)
 {
-	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	struct sensor_device_attribute_2 *sensor_attr
+	  = to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
 	struct w83792d_data *data = w83792d_update_device(dev);
-	return sprintf(buf,"%ld\n",
+	return sprintf(buf, "%ld\n",
 		(long)TEMP_ADD_FROM_REG(data->temp_add[nr][index],
 			data->temp_add[nr][index+1]));
 }
@@ -525,14 +555,19 @@ static ssize_t show_temp23(struct device *dev, struct device_attribute *attr,
 static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
 				const char *buf, size_t count)
 {
-	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	struct sensor_device_attribute_2 *sensor_attr
+	  = to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	s32 val;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtol(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->temp_add[nr][index] = TEMP_ADD_TO_REG_HIGH(val);
 	data->temp_add[nr][index+1] = TEMP_ADD_TO_REG_LOW(val);
@@ -604,7 +639,13 @@ store_pwm(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255) >> 4;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	val = SENSORS_LIMIT(val, 0, 255) >> 4;
 
 	mutex_lock(&data->update_lock);
 	val |= w83792d_read_value(client, W83792D_REG_PWM[nr]) & 0xf0;
@@ -623,10 +664,14 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index - 1;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
 	u8 fan_cfg_tmp, cfg1_tmp, cfg2_tmp, cfg3_tmp, cfg4_tmp;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	if (val < 1 || val > 3)
 		return -EINVAL;
 
@@ -645,7 +690,7 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
 	cfg1_tmp = data->pwmenable[0];
 	cfg2_tmp = (data->pwmenable[1]) << 2;
 	cfg3_tmp = (data->pwmenable[2]) << 4;
-	cfg4_tmp = w83792d_read_value(client,W83792D_REG_FAN_CFG) & 0xc0;
+	cfg4_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG) & 0xc0;
 	fan_cfg_tmp = ((cfg4_tmp | cfg3_tmp) | cfg2_tmp) | cfg1_tmp;
 	w83792d_write_value(client, W83792D_REG_FAN_CFG, fan_cfg_tmp);
 	mutex_unlock(&data->update_lock);
@@ -671,10 +716,13 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
-	if (val != 0 && val != 1)
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val > 1)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -721,16 +769,20 @@ store_chassis_clear_legacy(struct device *dev, struct device_attribute *attr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
+	unsigned long val;
+	int err;
 	u8 temp1 = 0, temp2 = 0;
 
 	dev_warn(dev,
 		 "Attribute %s is deprecated, use intrusion0_alarm instead\n",
 		 "chassis_clear");
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
 	mutex_lock(&data->update_lock);
-	data->chassis_clear = SENSORS_LIMIT(val, 0 ,1);
+	data->chassis_clear = SENSORS_LIMIT(val, 0, 1);
 	temp1 = ((data->chassis_clear) << 7) & 0x80;
 	temp2 = w83792d_read_value(client,
 		W83792D_REG_CHASSIS_CLR) & 0x7f;
@@ -780,14 +832,19 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index - 1;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
-	u8 target_tmp=0, target_mask=0;
+	u8 target_tmp = 0, target_mask = 0;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	target_tmp = val;
 	target_tmp = target_tmp & 0x7f;
 	mutex_lock(&data->update_lock);
-	target_mask = w83792d_read_value(client, W83792D_REG_THERMAL[nr]) & 0x80;
+	target_mask = w83792d_read_value(client,
+					 W83792D_REG_THERMAL[nr]) & 0x80;
 	data->thermal_cruise[nr] = SENSORS_LIMIT(target_tmp, 0, 255);
 	w83792d_write_value(client, W83792D_REG_THERMAL[nr],
 		(data->thermal_cruise[nr]) | target_mask);
@@ -815,19 +872,22 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->index - 1;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
 	u8 tol_tmp, tol_mask;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	tol_mask = w83792d_read_value(client,
 		W83792D_REG_TOLERANCE[nr]) & ((nr == 1) ? 0x0f : 0xf0);
 	tol_tmp = SENSORS_LIMIT(val, 0, 15);
 	tol_tmp &= 0x0f;
 	data->tolerance[nr] = tol_tmp;
-	if (nr == 1) {
+	if (nr == 1)
 		tol_tmp <<= 4;
-	}
 	w83792d_write_value(client, W83792D_REG_TOLERANCE[nr],
 		tol_mask | tol_tmp);
 	mutex_unlock(&data->update_lock);
@@ -840,7 +900,8 @@ static ssize_t
 show_sf2_point(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
-	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	struct sensor_device_attribute_2 *sensor_attr
+	  = to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
 	struct w83792d_data *data = w83792d_update_device(dev);
@@ -851,15 +912,20 @@ static ssize_t
 store_sf2_point(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	struct sensor_device_attribute_2 *sensor_attr
+	  = to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr - 1;
 	int index = sensor_attr->index - 1;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
 	u8 mask_tmp = 0;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->sf2_points[index][nr] = SENSORS_LIMIT(val, 0, 127);
 	mask_tmp = w83792d_read_value(client,
@@ -875,7 +941,8 @@ static ssize_t
 show_sf2_level(struct device *dev, struct device_attribute *attr,
 		char *buf)
 {
-	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	struct sensor_device_attribute_2 *sensor_attr
+	  = to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
 	struct w83792d_data *data = w83792d_update_device(dev);
@@ -887,25 +954,30 @@ static ssize_t
 store_sf2_level(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 {
-	struct sensor_device_attribute_2 *sensor_attr = to_sensor_dev_attr_2(attr);
+	struct sensor_device_attribute_2 *sensor_attr
+	  = to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index - 1;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83792d_data *data = i2c_get_clientdata(client);
-	u32 val;
-	u8 mask_tmp=0, level_tmp=0;
+	u8 mask_tmp = 0, level_tmp = 0;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->sf2_levels[index][nr] = SENSORS_LIMIT((val * 15) / 100, 0, 15);
 	mask_tmp = w83792d_read_value(client, W83792D_REG_LEVELS[index][nr])
-		& ((nr==3) ? 0xf0 : 0x0f);
-	if (nr==3) {
+		& ((nr == 3) ? 0xf0 : 0x0f);
+	if (nr == 3)
 		level_tmp = data->sf2_levels[index][nr];
-	} else {
+	else
 		level_tmp = data->sf2_levels[index][nr] << 4;
-	}
-	w83792d_write_value(client, W83792D_REG_LEVELS[index][nr], level_tmp | mask_tmp);
+	w83792d_write_value(client, W83792D_REG_LEVELS[index][nr],
+			    level_tmp | mask_tmp);
 	mutex_unlock(&data->update_lock);
 
 	return count;
@@ -939,9 +1011,8 @@ w83792d_detect_subclients(struct i2c_client *new_client)
 	}
 
 	val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR);
-	if (!(val & 0x08)) {
+	if (!(val & 0x08))
 		data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7));
-	}
 	if (!(val & 0x80)) {
 		if ((data->lm75[0] != NULL) &&
 			((val & 0x7) == ((val >> 4) & 0x7))) {
@@ -1306,9 +1377,8 @@ w83792d_detect(struct i2c_client *client, struct i2c_board_info *info)
 	int val1, val2;
 	unsigned short address = client->addr;
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
-	}
 
 	if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80)
 		return -ENODEV;
@@ -1318,11 +1388,13 @@ w83792d_detect(struct i2c_client *client, struct i2c_board_info *info)
 	/* Check for Winbond ID if in bank 0 */
 	if (!(val1 & 0x07)) {  /* is Bank0 */
 		if ((!(val1 & 0x80) && val2 != 0xa3) ||
-		    ( (val1 & 0x80) && val2 != 0x5c))
+		    ((val1 & 0x80) && val2 != 0x5c))
 			return -ENODEV;
 	}
-	/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
-	   should match */
+	/*
+	 * If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
+	 * should match
+	 */
 	if (w83792d_read_value(client, W83792D_REG_I2C_ADDR) != address)
 		return -ENODEV;
 
@@ -1374,33 +1446,40 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	}
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&dev->kobj, &w83792d_group)))
+	err = sysfs_create_group(&dev->kobj, &w83792d_group);
+	if (err)
 		goto ERROR3;
 
-	/* Read GPIO enable register to check if pins for fan 4,5 are used as
-	   GPIO */
+	/*
+	 * Read GPIO enable register to check if pins for fan 4,5 are used as
+	 * GPIO
+	 */
 	val1 = w83792d_read_value(client, W83792D_REG_GPIO_EN);
 
-	if (!(val1 & 0x40))
-		if ((err = sysfs_create_group(&dev->kobj,
-					      &w83792d_group_fan[0])))
+	if (!(val1 & 0x40)) {
+		err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[0]);
+		if (err)
 			goto exit_remove_files;
+	}
 
-	if (!(val1 & 0x20))
-		if ((err = sysfs_create_group(&dev->kobj,
-					      &w83792d_group_fan[1])))
+	if (!(val1 & 0x20)) {
+		err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[1]);
+		if (err)
 			goto exit_remove_files;
+	}
 
 	val1 = w83792d_read_value(client, W83792D_REG_PIN);
-	if (val1 & 0x40)
-		if ((err = sysfs_create_group(&dev->kobj,
-					      &w83792d_group_fan[2])))
+	if (val1 & 0x40) {
+		err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[2]);
+		if (err)
 			goto exit_remove_files;
+	}
 
-	if (val1 & 0x04)
-		if ((err = sysfs_create_group(&dev->kobj,
-					      &w83792d_group_fan[3])))
+	if (val1 & 0x04) {
+		err = sysfs_create_group(&dev->kobj, &w83792d_group_fan[3]);
+		if (err)
 			goto exit_remove_files;
+	}
 
 	data->hwmon_dev = hwmon_device_register(dev);
 	if (IS_ERR(data->hwmon_dev)) {
@@ -1451,14 +1530,16 @@ w83792d_init_client(struct i2c_client *client)
 {
 	u8 temp2_cfg, temp3_cfg, vid_in_b;
 
-	if (init) {
+	if (init)
 		w83792d_write_value(client, W83792D_REG_CONFIG, 0x80);
-	}
-	/* Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0):
-	   W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of
-	     vin0/vin1 can be modified by user;
-	   W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of
-	     vin0/vin1 auto-updated, can NOT be modified by user. */
+
+	/*
+	 * Clear the bit6 of W83792D_REG_VID_IN_B(set it into 0):
+	 * W83792D_REG_VID_IN_B bit6 = 0: the high/low limit of
+	 * vin0/vin1 can be modified by user;
+	 * W83792D_REG_VID_IN_B bit6 = 1: the high/low limit of
+	 * vin0/vin1 auto-updated, can NOT be modified by user.
+	 */
 	vid_in_b = w83792d_read_value(client, W83792D_REG_VID_IN_B);
 	w83792d_write_value(client, W83792D_REG_VID_IN_B,
 			    vid_in_b & 0xbf);
@@ -1527,7 +1608,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
 		for (i = 0; i < 2; i++) {
 			for (j = 0; j < 6; j++) {
 				data->temp_add[i][j] = w83792d_read_value(
-					client,W83792D_REG_TEMP_ADD[i][j]);
+					client, W83792D_REG_TEMP_ADD[i][j]);
 			}
 		}
 
@@ -1572,8 +1653,9 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
 		/* Update Smart Fan II temperature points */
 		for (i = 0; i < 3; i++) {
 			for (j = 0; j < 4; j++) {
-				data->sf2_points[i][j] = w83792d_read_value(
-					client,W83792D_REG_POINTS[i][j]) & 0x7f;
+				data->sf2_points[i][j]
+				  = w83792d_read_value(client,
+					W83792D_REG_POINTS[i][j]) & 0x7f;
 			}
 		}
 
@@ -1605,10 +1687,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
 #ifdef DEBUG
 static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
 {
-	int i=0, j=0;
+	int i = 0, j = 0;
 	dev_dbg(dev, "==========The following is the debug message...========\n");
 	dev_dbg(dev, "9 set of Voltages: =====>\n");
-	for (i=0; i<9; i++) {
+	for (i = 0; i < 9; i++) {
 		dev_dbg(dev, "vin[%d] is: 0x%x\n", i, data->in[i]);
 		dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]);
 		dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]);
@@ -1616,47 +1698,32 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev)
 	dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff);
 	dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8);
 	dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n");
-	for (i=0; i<7; i++) {
+	for (i = 0; i < 7; i++) {
 		dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
 		dev_dbg(dev, "fan[%d] min is: 0x%x\n", i, data->fan_min[i]);
 		dev_dbg(dev, "pwm[%d]     is: 0x%x\n", i, data->pwm[i]);
 	}
 	dev_dbg(dev, "3 set of Temperatures: =====>\n");
-	for (i=0; i<3; i++) {
+	for (i = 0; i < 3; i++)
 		dev_dbg(dev, "temp1[%d] is: 0x%x\n", i, data->temp1[i]);
-	}
 
-	for (i=0; i<2; i++) {
-		for (j=0; j<6; j++) {
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < 6; j++) {
 			dev_dbg(dev, "temp_add[%d][%d] is: 0x%x\n", i, j,
 							data->temp_add[i][j]);
 		}
 	}
 
-	for (i=0; i<7; i++) {
+	for (i = 0; i < 7; i++)
 		dev_dbg(dev, "fan_div[%d] is: 0x%x\n", i, data->fan_div[i]);
-	}
-	dev_dbg(dev, "==========End of the debug message...==================\n");
+
+	dev_dbg(dev, "==========End of the debug message...================\n");
 	dev_dbg(dev, "\n");
 }
 #endif
 
-static int __init
-sensors_w83792d_init(void)
-{
-	return i2c_add_driver(&w83792d_driver);
-}
-
-static void __exit
-sensors_w83792d_exit(void)
-{
-	i2c_del_driver(&w83792d_driver);
-}
+module_i2c_driver(w83792d_driver);
 
 MODULE_AUTHOR("Chunhao Huang @ Winbond <DZShen@Winbond.com.tw>");
 MODULE_DESCRIPTION("W83792AD/D driver for linux-2.6");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83792d_init);
-module_exit(sensors_w83792d_exit);
-
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 45ec7e7..834e49d 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -1,34 +1,34 @@
 /*
-    w83793.c - Linux kernel driver for hardware monitoring
-    Copyright (C) 2006 Winbond Electronics Corp.
-                  Yuan Mu
-                  Rudolf Marek <r.marek@assembler.cz>
-    Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG.
-		  Watchdog driver part
-		  (Based partially on fschmd driver,
-		   Copyright 2007-2008 by Hans de Goede)
-
-    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 - version 2.
-
-    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., 51 Franklin Street, Fifth Floor, Boston, MA
-    02110-1301 USA.
-*/
+ * w83793.c - Linux kernel driver for hardware monitoring
+ * Copyright (C) 2006 Winbond Electronics Corp.
+ *	      Yuan Mu
+ *	      Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009-2010 Sven Anders <anders@anduras.de>, ANDURAS AG.
+ *		Watchdog driver part
+ *		(Based partially on fschmd driver,
+ *		 Copyright 2007-2008 by Hans de Goede)
+ *
+ * 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 - version 2.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
 
 /*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    w83793	10	12	8	6	0x7b	0x5ca3	yes	no
-*/
+ * Supports following chips:
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * w83793	10	12	8	6	0x7b	0x5ca3	yes	no
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -78,9 +78,9 @@ MODULE_PARM_DESC(nowayout,
 				__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
-   Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
-   as ID, Bank Select registers
-*/
+ * Address 0x00, 0x0d, 0x0e, 0x0f in all three banks are reserved
+ * as ID, Bank Select registers
+ */
 #define W83793_REG_BANKSEL		0x00
 #define W83793_REG_VENDORID		0x0d
 #define W83793_REG_CHIPID		0x0e
@@ -110,8 +110,10 @@ static u16 W83793_REG_TEMP_MODE[2] = { 0x5e, 0x5f };
 #define TEMP_CRIT_HYST	2
 #define TEMP_WARN	3
 #define TEMP_WARN_HYST	4
-/* only crit and crit_hyst affect real-time alarm status
-   current crit crit_hyst warn warn_hyst */
+/*
+ * only crit and crit_hyst affect real-time alarm status
+ * current crit crit_hyst warn warn_hyst
+ */
 static u16 W83793_REG_TEMP[][5] = {
 	{0x1c, 0x78, 0x79, 0x7a, 0x7b},
 	{0x1d, 0x7c, 0x7d, 0x7e, 0x7f},
@@ -181,7 +183,7 @@ static inline unsigned long FAN_FROM_REG(u16 val)
 {
 	if ((val >= 0xfff) || (val == 0))
 		return	0;
-	return (1350000UL / val);
+	return 1350000UL / val;
 }
 
 static inline u16 FAN_TO_REG(long rpm)
@@ -193,7 +195,7 @@ static inline u16 FAN_TO_REG(long rpm)
 
 static inline unsigned long TIME_FROM_REG(u8 reg)
 {
-	return (reg * 100);
+	return reg * 100;
 }
 
 static inline u8 TIME_TO_REG(unsigned long val)
@@ -203,7 +205,7 @@ static inline u8 TIME_TO_REG(unsigned long val)
 
 static inline long TEMP_FROM_REG(s8 reg)
 {
-	return (reg * 1000);
+	return reg * 1000;
 }
 
 static inline s8 TEMP_TO_REG(long val, s8 min, s8 max)
@@ -218,7 +220,8 @@ struct w83793_data {
 	char valid;			/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned long last_nonvolatile;	/* In jiffies, last time we update the
-					   nonvolatile registers */
+					 * nonvolatile registers
+					 */
 
 	u8 bank;
 	u8 vrm;
@@ -233,7 +236,8 @@ struct w83793_data {
 	s8 temp[6][5];		/* current, crit, crit_hyst,warn, warn_hyst */
 	u8 temp_low_bits;	/* Additional resolution TD1-TD4 */
 	u8 temp_mode[2];	/* byte 0: Temp D1-D4 mode each has 2 bits
-				   byte 1: Temp R1,R2 mode, each has 1 bit */
+				 * byte 1: Temp R1,R2 mode, each has 1 bit
+				 */
 	u8 temp_critical;	/* If reached all fan will be at full speed */
 	u8 temp_fan_map[6];	/* Temp controls which pwm fan, bit field */
 
@@ -268,17 +272,21 @@ struct w83793_data {
 	int watchdog_timeout; /* watchdog timeout in minutes */
 };
 
-/* Somewhat ugly :( global data pointer list with all devices, so that
-   we can find our device data as when using misc_register. There is no
-   other method to get to one's device data from the open file-op and
-   for usage in the reboot notifier callback. */
+/*
+ * Somewhat ugly :( global data pointer list with all devices, so that
+ * we can find our device data as when using misc_register. There is no
+ * other method to get to one's device data from the open file-op and
+ * for usage in the reboot notifier callback.
+ */
 static LIST_HEAD(watchdog_data_list);
 
 /* Note this lock not only protect list access, but also data.kref access */
 static DEFINE_MUTEX(watchdog_data_mutex);
 
-/* Release our data struct when we're detached from the i2c client *and* all
-   references to our watchdog device are released */
+/*
+ * Release our data struct when we're detached from the i2c client *and* all
+ * references to our watchdog device are released
+ */
 static void w83793_release_resources(struct kref *ref)
 {
 	struct w83793_data *data = container_of(ref, struct w83793_data, kref);
@@ -337,7 +345,14 @@ store_vrm(struct device *dev, struct device_attribute *attr,
 	  const char *buf, size_t count)
 {
 	struct w83793_data *data = dev_get_drvdata(dev);
-	data->vrm = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	data->vrm = val;
 	return count;
 }
 
@@ -354,7 +369,7 @@ show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf)
 	int bit = sensor_attr->index & 0x07;
 	u8 val;
 
-	if (ALARM_STATUS == nr) {
+	if (nr == ALARM_STATUS) {
 		val = (data->alarms[index] >> (bit)) & 1;
 	} else {		/* BEEP_ENABLE */
 		val = (data->beeps[index] >> (bit)) & 1;
@@ -374,10 +389,14 @@ store_beep(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index >> 3;
 	int shift = sensor_attr->index & 0x07;
 	u8 beep_bit = 1 << shift;
-	u8 val;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
-	if (val != 0 && val != 1)
+	if (val > 1)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -403,9 +422,14 @@ store_beep_enable(struct device *dev, struct device_attribute *attr,
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83793_data *data = i2c_get_clientdata(client);
-	u8 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	if (val != 0 && val != 1)
+	if (val > 1)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -449,8 +473,12 @@ store_chassis_clear(struct device *dev,
 	struct w83793_data *data = i2c_get_clientdata(client);
 	unsigned long val;
 	u8 reg;
+	int err;
 
-	if (kstrtoul(buf, 10, &val) || val != 0)
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val)
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -473,11 +501,10 @@ show_fan(struct device *dev, struct device_attribute *attr, char *buf)
 	struct w83793_data *data = w83793_update_device(dev);
 	u16 val;
 
-	if (FAN_INPUT == nr) {
+	if (nr == FAN_INPUT)
 		val = data->fan[index] & 0x0fff;
-	} else {
+	else
 		val = data->fan_min[index] & 0x0fff;
-	}
 
 	return sprintf(buf, "%lu\n", FAN_FROM_REG(val));
 }
@@ -491,7 +518,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83793_data *data = i2c_get_clientdata(client);
-	u16 val = FAN_TO_REG(simple_strtoul(buf, NULL, 10));
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	val = FAN_TO_REG(val);
 
 	mutex_lock(&data->update_lock);
 	data->fan_min[index] = val;
@@ -513,7 +546,7 @@ show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
 
-	if (PWM_STOP_TIME == nr)
+	if (nr == PWM_STOP_TIME)
 		val = TIME_FROM_REG(data->pwm_stop_time[index]);
 	else
 		val = (data->pwm[index][nr] & 0x3f) << 2;
@@ -531,17 +564,21 @@ store_pwm(struct device *dev, struct device_attribute *attr,
 	    to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
-	u8 val;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	if (PWM_STOP_TIME == nr) {
-		val = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+	if (nr == PWM_STOP_TIME) {
+		val = TIME_TO_REG(val);
 		data->pwm_stop_time[index] = val;
 		w83793_write_value(client, W83793_REG_PWM_STOP_TIME(index),
 				   val);
 	} else {
-		val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff)
-		      >> 2;
+		val = SENSORS_LIMIT(val, 0, 0xff) >> 2;
 		data->pwm[index][nr] =
 		    w83793_read_value(client, W83793_REG_PWM(index, nr)) & 0xc0;
 		data->pwm[index][nr] |= val;
@@ -563,7 +600,7 @@ show_temp(struct device *dev, struct device_attribute *attr, char *buf)
 	struct w83793_data *data = w83793_update_device(dev);
 	long temp = TEMP_FROM_REG(data->temp[index][nr]);
 
-	if (TEMP_READ == nr && index < 4) {	/* Only TD1-TD4 have low bits */
+	if (nr == TEMP_READ && index < 4) {	/* Only TD1-TD4 have low bits */
 		int low = ((data->temp_low_bits >> (index * 2)) & 0x03) * 250;
 		temp += temp > 0 ? low : -low;
 	}
@@ -580,7 +617,12 @@ store_temp(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83793_data *data = i2c_get_clientdata(client);
-	long tmp = simple_strtol(buf, NULL, 10);
+	long tmp;
+	int err;
+
+	err = kstrtol(buf, 10, &tmp);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	data->temp[index][nr] = TEMP_TO_REG(tmp, -128, 127);
@@ -591,18 +633,18 @@ store_temp(struct device *dev, struct device_attribute *attr,
 }
 
 /*
-	TD1-TD4
-	each has 4 mode:(2 bits)
-	0:	Stop monitor
-	1:	Use internal temp sensor(default)
-	2:	Reserved
-	3:	Use sensor in Intel CPU and get result by PECI
-
-	TR1-TR2
-	each has 2 mode:(1 bit)
-	0:	Disable temp sensor monitor
-	1:	To enable temp sensors monitor
-*/
+ * TD1-TD4
+ * each has 4 mode:(2 bits)
+ * 0:	Stop monitor
+ * 1:	Use internal temp sensor(default)
+ * 2:	Reserved
+ * 3:	Use sensor in Intel CPU and get result by PECI
+ *
+ * TR1-TR2
+ * each has 2 mode:(1 bit)
+ * 0:	Disable temp sensor monitor
+ * 1:	To enable temp sensors monitor
+ */
 
 /* 0 disable, 6 PECI */
 static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 };
@@ -622,11 +664,10 @@ show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf)
 	tmp = (data->temp_mode[index] >> shift) & mask;
 
 	/* for the internal sensor, found out if diode or thermistor */
-	if (tmp == 1) {
+	if (tmp == 1)
 		tmp = index == 0 ? 3 : 4;
-	} else {
+	else
 		tmp = TO_TEMP_MODE[tmp];
-	}
 
 	return sprintf(buf, "%d\n", tmp);
 }
@@ -642,7 +683,12 @@ store_temp_mode(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index;
 	u8 mask = (index < 4) ? 0x03 : 0x01;
 	u8 shift = (index < 4) ? (2 * index) : (index - 4);
-	u8 val = simple_strtoul(buf, NULL, 10);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	/* transform the sysfs interface values into table above */
 	if ((val == 6) && (index < 4)) {
@@ -681,15 +727,14 @@ show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf)
 	struct w83793_data *data = w83793_update_device(dev);
 	u32 val = 0;
 
-	if (SETUP_PWM_DEFAULT == nr) {
+	if (nr == SETUP_PWM_DEFAULT)
 		val = (data->pwm_default & 0x3f) << 2;
-	} else if (SETUP_PWM_UPTIME == nr) {
+	else if (nr == SETUP_PWM_UPTIME)
 		val = TIME_FROM_REG(data->pwm_uptime);
-	} else if (SETUP_PWM_DOWNTIME == nr) {
+	else if (nr == SETUP_PWM_DOWNTIME)
 		val = TIME_FROM_REG(data->pwm_downtime);
-	} else if (SETUP_TEMP_CRITICAL == nr) {
+	else if (nr == SETUP_TEMP_CRITICAL)
 		val = TEMP_FROM_REG(data->temp_critical & 0x7f);
-	}
 
 	return sprintf(buf, "%d\n", val);
 }
@@ -703,31 +748,34 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 	int nr = sensor_attr->nr;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83793_data *data = i2c_get_clientdata(client);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	if (SETUP_PWM_DEFAULT == nr) {
+	if (nr == SETUP_PWM_DEFAULT) {
 		data->pwm_default =
 		    w83793_read_value(client, W83793_REG_PWM_DEFAULT) & 0xc0;
-		data->pwm_default |= SENSORS_LIMIT(simple_strtoul(buf, NULL,
-								  10),
-						   0, 0xff) >> 2;
+		data->pwm_default |= SENSORS_LIMIT(val, 0, 0xff) >> 2;
 		w83793_write_value(client, W83793_REG_PWM_DEFAULT,
 							data->pwm_default);
-	} else if (SETUP_PWM_UPTIME == nr) {
-		data->pwm_uptime = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+	} else if (nr == SETUP_PWM_UPTIME) {
+		data->pwm_uptime = TIME_TO_REG(val);
 		data->pwm_uptime += data->pwm_uptime == 0 ? 1 : 0;
 		w83793_write_value(client, W83793_REG_PWM_UPTIME,
 							data->pwm_uptime);
-	} else if (SETUP_PWM_DOWNTIME == nr) {
-		data->pwm_downtime = TIME_TO_REG(simple_strtoul(buf, NULL, 10));
+	} else if (nr == SETUP_PWM_DOWNTIME) {
+		data->pwm_downtime = TIME_TO_REG(val);
 		data->pwm_downtime += data->pwm_downtime == 0 ? 1 : 0;
 		w83793_write_value(client, W83793_REG_PWM_DOWNTIME,
 							data->pwm_downtime);
 	} else {		/* SETUP_TEMP_CRITICAL */
 		data->temp_critical =
 		    w83793_read_value(client, W83793_REG_TEMP_CRITICAL) & 0x80;
-		data->temp_critical |= TEMP_TO_REG(simple_strtol(buf, NULL, 10),
-						   0, 0x7f);
+		data->temp_critical |= TEMP_TO_REG(val, 0, 0x7f);
 		w83793_write_value(client, W83793_REG_TEMP_CRITICAL,
 							data->temp_critical);
 	}
@@ -737,31 +785,31 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 }
 
 /*
-	Temp SmartFan control
-	TEMP_FAN_MAP
-	Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1...
-	It's possible two or more temp channels control the same fan, w83793
-	always prefers to pick the most critical request and applies it to
-	the related Fan.
-	It's possible one fan is not in any mapping of 6 temp channels, this
-	means the fan is manual mode
-
-	TEMP_PWM_ENABLE
-	Each temp channel has its own SmartFan mode, and temp channel
-	control	fans that are set by TEMP_FAN_MAP
-	0:	SmartFanII mode
-	1:	Thermal Cruise Mode
-
-	TEMP_CRUISE
-	Target temperature in thermal cruise mode, w83793 will try to turn
-	fan speed to keep the temperature of target device around this
-	temperature.
-
-	TEMP_TOLERANCE
-	If Temp higher or lower than target with this tolerance, w83793
-	will take actions to speed up or slow down the fan to keep the
-	temperature within the tolerance range.
-*/
+ * Temp SmartFan control
+ * TEMP_FAN_MAP
+ * Temp channel control which pwm fan, bitfield, bit 0 indicate pwm1...
+ * It's possible two or more temp channels control the same fan, w83793
+ * always prefers to pick the most critical request and applies it to
+ * the related Fan.
+ * It's possible one fan is not in any mapping of 6 temp channels, this
+ * means the fan is manual mode
+ *
+ * TEMP_PWM_ENABLE
+ * Each temp channel has its own SmartFan mode, and temp channel
+ * control fans that are set by TEMP_FAN_MAP
+ * 0:	SmartFanII mode
+ * 1:	Thermal Cruise Mode
+ *
+ * TEMP_CRUISE
+ * Target temperature in thermal cruise mode, w83793 will try to turn
+ * fan speed to keep the temperature of target device around this
+ * temperature.
+ *
+ * TEMP_TOLERANCE
+ * If Temp higher or lower than target with this tolerance, w83793
+ * will take actions to speed up or slow down the fan to keep the
+ * temperature within the tolerance range.
+ */
 
 #define TEMP_FAN_MAP			0
 #define TEMP_PWM_ENABLE			1
@@ -777,12 +825,12 @@ show_sf_ctrl(struct device *dev, struct device_attribute *attr, char *buf)
 	struct w83793_data *data = w83793_update_device(dev);
 	u32 val;
 
-	if (TEMP_FAN_MAP == nr) {
+	if (nr == TEMP_FAN_MAP) {
 		val = data->temp_fan_map[index];
-	} else if (TEMP_PWM_ENABLE == nr) {
+	} else if (nr == TEMP_PWM_ENABLE) {
 		/* +2 to transfrom into 2 and 3 to conform with sysfs intf */
 		val = ((data->pwm_enable >> index) & 0x01) + 2;
-	} else if (TEMP_CRUISE == nr) {
+	} else if (nr == TEMP_CRUISE) {
 		val = TEMP_FROM_REG(data->temp_cruise[index] & 0x7f);
 	} else {		/* TEMP_TOLERANCE */
 		val = data->tolerance[index >> 1] >> ((index & 0x01) ? 4 : 0);
@@ -801,16 +849,20 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83793_data *data = i2c_get_clientdata(client);
-	u32 val;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
-	if (TEMP_FAN_MAP == nr) {
-		val = simple_strtoul(buf, NULL, 10) & 0xff;
+	if (nr == TEMP_FAN_MAP) {
+		val = SENSORS_LIMIT(val, 0, 255);
 		w83793_write_value(client, W83793_REG_TEMP_FAN_MAP(index), val);
 		data->temp_fan_map[index] = val;
-	} else if (TEMP_PWM_ENABLE == nr) {
-		val = simple_strtoul(buf, NULL, 10);
-		if (2 == val || 3 == val) {
+	} else if (nr == TEMP_PWM_ENABLE) {
+		if (val == 2 || val == 3) {
 			data->pwm_enable =
 			    w83793_read_value(client, W83793_REG_PWM_ENABLE);
 			if (val - 2)
@@ -823,12 +875,11 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr,
 			mutex_unlock(&data->update_lock);
 			return -EINVAL;
 		}
-	} else if (TEMP_CRUISE == nr) {
+	} else if (nr == TEMP_CRUISE) {
 		data->temp_cruise[index] =
 		    w83793_read_value(client, W83793_REG_TEMP_CRUISE(index));
-		val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f);
 		data->temp_cruise[index] &= 0x80;
-		data->temp_cruise[index] |= val;
+		data->temp_cruise[index] |= TEMP_TO_REG(val, 0, 0x7f);
 
 		w83793_write_value(client, W83793_REG_TEMP_CRUISE(index),
 						data->temp_cruise[index]);
@@ -838,9 +889,8 @@ store_sf_ctrl(struct device *dev, struct device_attribute *attr,
 		data->tolerance[i] =
 		    w83793_read_value(client, W83793_REG_TEMP_TOL(i));
 
-		val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x0f);
 		data->tolerance[i] &= ~(0x0f << shift);
-		data->tolerance[i] |= val << shift;
+		data->tolerance[i] |= TEMP_TO_REG(val, 0, 0x0f) << shift;
 		w83793_write_value(client, W83793_REG_TEMP_TOL(i),
 							data->tolerance[i]);
 	}
@@ -871,7 +921,13 @@ store_sf2_pwm(struct device *dev, struct device_attribute *attr,
 	    to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
-	u8 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 0xff) >> 2;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	val = SENSORS_LIMIT(val, 0, 0xff) >> 2;
 
 	mutex_lock(&data->update_lock);
 	data->sf2_pwm[index][nr] =
@@ -906,7 +962,13 @@ store_sf2_temp(struct device *dev, struct device_attribute *attr,
 	    to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
-	u8 val = TEMP_TO_REG(simple_strtol(buf, NULL, 10), 0, 0x7f);
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
+	val = TEMP_TO_REG(val, 0, 0x7f);
 
 	mutex_lock(&data->update_lock);
 	data->sf2_temp[index][nr] =
@@ -948,17 +1010,19 @@ store_in(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83793_data *data = i2c_get_clientdata(client);
-	u32 val;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	val = (val + scale_in[index] / 2) / scale_in[index];
 
-	val =
-	    (simple_strtoul(buf, NULL, 10) +
-	     scale_in[index] / 2) / scale_in[index];
 	mutex_lock(&data->update_lock);
 	if (index > 2) {
 		/* fix the limit values of 5VDD and 5VSB to ALARM mechanism */
-		if (1 == nr || 2 == nr) {
+		if (nr == 1 || nr == 2)
 			val -= scale_in_add[index] / scale_in[index];
-		}
 		val = SENSORS_LIMIT(val, 0, 255);
 	} else {
 		val = SENSORS_LIMIT(val, 0, 0x3FF);
@@ -1143,9 +1207,8 @@ static struct sensor_device_attribute_2 sda_single_files[] = {
 
 static void w83793_init_client(struct i2c_client *client)
 {
-	if (reset) {
+	if (reset)
 		w83793_write_value(client, W83793_REG_CONFIG, 0x80);
-	}
 
 	/* Start monitoring */
 	w83793_write_value(client, W83793_REG_CONFIG,
@@ -1259,10 +1322,12 @@ static int watchdog_open(struct inode *inode, struct file *filp)
 	struct w83793_data *pos, *data = NULL;
 	int watchdog_is_open;
 
-	/* We get called from drivers/char/misc.c with misc_mtx hold, and we
-	   call misc_register() from  w83793_probe() with watchdog_data_mutex
-	   hold, as misc_register() takes the misc_mtx lock, this is a possible
-	   deadlock, so we use mutex_trylock here. */
+	/*
+	 * We get called from drivers/char/misc.c with misc_mtx hold, and we
+	 * call misc_register() from  w83793_probe() with watchdog_data_mutex
+	 * hold, as misc_register() takes the misc_mtx lock, this is a possible
+	 * deadlock, so we use mutex_trylock here.
+	 */
 	if (!mutex_trylock(&watchdog_data_mutex))
 		return -ERESTARTSYS;
 	list_for_each_entry(pos, &watchdog_data_list, list) {
@@ -1275,8 +1340,10 @@ static int watchdog_open(struct inode *inode, struct file *filp)
 	/* Check, if device is already open */
 	watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
 
-	/* Increase data reference counter (if not already done).
-	   Note we can never not have found data, so we don't check for this */
+	/*
+	 * Increase data reference counter (if not already done).
+	 * Note we can never not have found data, so we don't check for this
+	 */
 	if (!watchdog_is_open)
 		kref_get(&data->kref);
 
@@ -1556,9 +1623,8 @@ w83793_detect_subclients(struct i2c_client *client)
 	}
 
 	tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR);
-	if (!(tmp & 0x08)) {
+	if (!(tmp & 0x08))
 		data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7));
-	}
 	if (!(tmp & 0x80)) {
 		if ((data->lm75[0] != NULL)
 		    && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) {
@@ -1591,9 +1657,8 @@ static int w83793_detect(struct i2c_client *client,
 	struct i2c_adapter *adapter = client->adapter;
 	unsigned short address = client->addr;
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
-	}
 
 	bank = i2c_smbus_read_byte_data(client, W83793_REG_BANKSEL);
 
@@ -1604,8 +1669,10 @@ static int w83793_detect(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	/* If Winbond chip, address of chip and W83793_REG_I2C_ADDR
-	   should match */
+	/*
+	 * If Winbond chip, address of chip and W83793_REG_I2C_ADDR
+	 * should match
+	 */
 	if ((bank & 0x07) == 0
 	 && i2c_smbus_read_byte_data(client, W83793_REG_I2C_ADDR) !=
 	    (address << 1)) {
@@ -1647,9 +1714,11 @@ static int w83793_probe(struct i2c_client *client,
 	INIT_LIST_HEAD(&data->list);
 	kref_init(&data->kref);
 
-	/* Store client pointer in our data struct for watchdog usage
-	   (where the client is found through a data ptr instead of the
-	   otherway around) */
+	/*
+	 * Store client pointer in our data struct for watchdog usage
+	 * (where the client is found through a data ptr instead of the
+	 * otherway around)
+	 */
 	data->client = client;
 
 	err = w83793_detect_subclients(client);
@@ -1660,8 +1729,8 @@ static int w83793_probe(struct i2c_client *client,
 	w83793_init_client(client);
 
 	/*
-	   Only fan 1-5 has their own input pins,
-	   Pwm 1-3 has their own pins
+	 * Only fan 1-5 has their own input pins,
+	 * Pwm 1-3 has their own pins
 	 */
 	data->has_fan = 0x1f;
 	data->has_pwm = 0x07;
@@ -1723,7 +1792,7 @@ static int w83793_probe(struct i2c_client *client,
 	}
 
 	/* check the temp1-6 mode, ignore former AMDSI selected inputs */
-	tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]);
+	tmp = w83793_read_value(client, W83793_REG_TEMP_MODE[0]);
 	if (tmp & 0x01)
 		data->has_temp |= 0x01;
 	if (tmp & 0x04)
@@ -1733,7 +1802,7 @@ static int w83793_probe(struct i2c_client *client,
 	if (tmp & 0x40)
 		data->has_temp |= 0x08;
 
-	tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]);
+	tmp = w83793_read_value(client, W83793_REG_TEMP_MODE[1]);
 	if (tmp & 0x01)
 		data->has_temp |= 0x10;
 	if (tmp & 0x02)
@@ -1823,9 +1892,11 @@ static int w83793_probe(struct i2c_client *client,
 		goto exit_devunreg;
 	}
 
-	/* Enable Watchdog registers.
-	   Set Configuration Register to Enable Watch Dog Registers
-	   (Bit 2) = XXXX, X1XX. */
+	/*
+	 * Enable Watchdog registers.
+	 * Set Configuration Register to Enable Watch Dog Registers
+	 * (Bit 2) = XXXX, X1XX.
+	 */
 	tmp = w83793_read_value(client, W83793_REG_CONFIG);
 	w83793_write_value(client, W83793_REG_CONFIG, tmp | 0x04);
 
@@ -1839,9 +1910,11 @@ static int w83793_probe(struct i2c_client *client,
 	/* Disable Soft Watchdog during initialiation */
 	watchdog_disable(data);
 
-	/* We take the data_mutex lock early so that watchdog_open() cannot
-	   run when misc_register() has completed, but we've not yet added
-	   our data to the watchdog_data_list (and set the default timeout) */
+	/*
+	 * We take the data_mutex lock early so that watchdog_open() cannot
+	 * run when misc_register() has completed, but we've not yet added
+	 * our data to the watchdog_data_list (and set the default timeout)
+	 */
 	mutex_lock(&watchdog_data_mutex);
 	for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
 		/* Register our watchdog part */
@@ -1921,9 +1994,9 @@ static void w83793_update_nonvolatile(struct device *dev)
 	struct w83793_data *data = i2c_get_clientdata(client);
 	int i, j;
 	/*
-	   They are somewhat "stable" registers, and to update them every time
-	   takes so much time, it's just not worthy. Update them in a long
-	   interval to avoid exception.
+	 * They are somewhat "stable" registers, and to update them every time
+	 * takes so much time, it's just not worthy. Update them in a long
+	 * interval to avoid exception.
 	 */
 	if (!(time_after(jiffies, data->last_nonvolatile + HZ * 300)
 	      || !data->valid))
@@ -1940,9 +2013,8 @@ static void w83793_update_nonvolatile(struct device *dev)
 
 	for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
 		/* Update the Fan measured value and limits */
-		if (!(data->has_fan & (1 << i))) {
+		if (!(data->has_fan & (1 << i)))
 			continue;
-		}
 		data->fan_min[i] =
 		    w83793_read_value(client, W83793_REG_FAN_MIN(i)) << 8;
 		data->fan_min[i] |=
@@ -1997,9 +2069,8 @@ static void w83793_update_nonvolatile(struct device *dev)
 	    w83793_read_value(client, W83793_REG_TEMP_CRITICAL);
 	data->beep_enable = w83793_read_value(client, W83793_REG_OVT_BEEP);
 
-	for (i = 0; i < ARRAY_SIZE(data->beeps); i++) {
+	for (i = 0; i < ARRAY_SIZE(data->beeps); i++)
 		data->beeps[i] = w83793_read_value(client, W83793_REG_BEEP(i));
-	}
 
 	data->last_nonvolatile = jiffies;
 }
@@ -2025,9 +2096,8 @@ static struct w83793_data *w83793_update_device(struct device *dev)
 	    w83793_read_value(client, W83793_REG_IN_LOW_BITS[IN_READ]);
 
 	for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
-		if (!(data->has_fan & (1 << i))) {
+		if (!(data->has_fan & (1 << i)))
 			continue;
-		}
 		data->fan[i] =
 		    w83793_read_value(client, W83793_REG_FAN(i)) << 8;
 		data->fan[i] |=
@@ -2067,8 +2137,10 @@ END:
 	return data;
 }
 
-/* Ignore the possibility that somebody change bank outside the driver
-   Must be called with data->update_lock held, except during initialization */
+/*
+ * Ignore the possibility that somebody change bank outside the driver
+ * Must be called with data->update_lock held, except during initialization
+ */
 static u8 w83793_read_value(struct i2c_client *client, u16 reg)
 {
 	struct w83793_data *data = i2c_get_clientdata(client);
@@ -2103,16 +2175,16 @@ static int w83793_write_value(struct i2c_client *client, u16 reg, u8 value)
 
 	new_bank |= data->bank & 0xfc;
 	if (data->bank != new_bank) {
-		if ((res = i2c_smbus_write_byte_data
-		    (client, W83793_REG_BANKSEL, new_bank)) >= 0)
-			data->bank = new_bank;
-		else {
+		res = i2c_smbus_write_byte_data(client, W83793_REG_BANKSEL,
+						new_bank);
+		if (res < 0) {
 			dev_err(&client->dev,
 				"set bank to %d failed, fall back "
 				"to bank %d, write reg 0x%x error\n",
 				new_bank, data->bank, reg);
 			goto END;
 		}
+		data->bank = new_bank;
 	}
 
 	res = i2c_smbus_write_byte_data(client, reg & 0xff, value);
@@ -2120,19 +2192,8 @@ END:
 	return res;
 }
 
-static int __init sensors_w83793_init(void)
-{
-	return i2c_add_driver(&w83793_driver);
-}
-
-static void __exit sensors_w83793_exit(void)
-{
-	i2c_del_driver(&w83793_driver);
-}
+module_i2c_driver(w83793_driver);
 
 MODULE_AUTHOR("Yuan Mu, Sven Anders");
 MODULE_DESCRIPTION("w83793 driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83793_init);
-module_exit(sensors_w83793_exit);
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index aa58b25..d887cb3 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -72,8 +72,10 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
 #define TEMP_CRIT_HYST			2
 #define TEMP_WARN			3
 #define TEMP_WARN_HYST			4
-/* only crit and crit_hyst affect real-time alarm status
- * current crit crit_hyst warn warn_hyst */
+/*
+ * only crit and crit_hyst affect real-time alarm status
+ * current crit crit_hyst warn warn_hyst
+ */
 static const u16 W83795_REG_TEMP[][5] = {
 	{0x21, 0x96, 0x97, 0x98, 0x99},	/* TD1/TR1 */
 	{0x22, 0x9a, 0x9b, 0x9c, 0x9d},	/* TD2/TR2 */
@@ -354,26 +356,34 @@ struct w83795_data {
 	u8 temp_mode;		/* Bit vector, 0 = TR, 1 = TD */
 	u8 temp_src[3];		/* Register value */
 
-	u8 enable_dts;		/* Enable PECI and SB-TSI,
+	u8 enable_dts;		/*
+				 * Enable PECI and SB-TSI,
 				 * bit 0: =1 enable, =0 disable,
-				 * bit 1: =1 AMD SB-TSI, =0 Intel PECI */
+				 * bit 1: =1 AMD SB-TSI, =0 Intel PECI
+				 */
 	u8 has_dts;		/* Enable monitor DTS temp */
 	s8 dts[8];		/* Register value */
 	u8 dts_read_vrlsb[8];	/* Register value */
 	s8 dts_ext[4];		/* Register value */
 
-	u8 has_pwm;		/* 795g supports 8 pwm, 795adg only supports 2,
+	u8 has_pwm;		/*
+				 * 795g supports 8 pwm, 795adg only supports 2,
 				 * no config register, only affected by chip
-				 * type */
-	u8 pwm[8][5];		/* Register value, output, freq, start,
-				 *  non stop, stop time */
+				 * type
+				 */
+	u8 pwm[8][5];		/*
+				 * Register value, output, freq, start,
+				 *  non stop, stop time
+				 */
 	u16 clkin;		/* CLKIN frequency in kHz */
 	u8 pwm_fcms[2];		/* Register value */
 	u8 pwm_tfmr[6];		/* Register value */
 	u8 pwm_fomc;		/* Register value */
 
-	u16 target_speed[8];	/* Register value, target speed for speed
-				 * cruise */
+	u16 target_speed[8];	/*
+				 * Register value, target speed for speed
+				 * cruise
+				 */
 	u8 tol_speed;		/* tolerance of target speed */
 	u8 pwm_temp[6][4];	/* TTTI, CTFS, HCT, HOT */
 	u8 sf4_reg[6][2][7];	/* 6 temp, temp/dcpwm, 7 registers */
@@ -482,8 +492,10 @@ static void w83795_update_limits(struct i2c_client *client)
 	/* Read the fan limits */
 	lsb = 0; /* Silent false gcc warning */
 	for (i = 0; i < ARRAY_SIZE(data->fan); i++) {
-		/* Each register contains LSB for 2 fans, but we want to
-		 * read it only once to save time */
+		/*
+		 * Each register contains LSB for 2 fans, but we want to
+		 * read it only once to save time
+		 */
 		if ((i & 1) == 0 && (data->has_fan & (3 << i)))
 			lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i));
 
@@ -665,9 +677,11 @@ static struct w83795_data *w83795_update_device(struct device *dev)
 		    w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT));
 	}
 
-	/* Update intrusion and alarms
+	/*
+	 * Update intrusion and alarms
 	 * It is important to read intrusion first, because reading from
-	 * register SMI STS6 clears the interrupt status temporarily. */
+	 * register SMI STS6 clears the interrupt status temporarily.
+	 */
 	tmp = w83795_read(client, W83795_REG_ALARM_CTRL);
 	/* Switch to interrupt status for intrusion if needed */
 	if (tmp & ALARM_CTRL_RTSACS)
@@ -929,6 +943,14 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
 	if (val < 1 || val > 2)
 		return -EINVAL;
 
+#ifndef CONFIG_SENSORS_W83795_FANCTRL
+	if (val > 1) {
+		dev_warn(dev, "Automatic fan speed control support disabled\n");
+		dev_warn(dev, "Build with CONFIG_SENSORS_W83795_FANCTRL=y if you want it\n");
+		return -EOPNOTSUPP;
+	}
+#endif
+
 	mutex_lock(&data->update_lock);
 	switch (val) {
 	case 1:
@@ -1595,8 +1617,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 
 #define NOT_USED			-1
 
-/* Don't change the attribute order, _max, _min and _beep are accessed by index
- * somewhere else in the code */
+/*
+ * Don't change the attribute order, _max, _min and _beep are accessed by index
+ * somewhere else in the code
+ */
 #define SENSOR_ATTR_IN(index) {						\
 	SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL,	\
 		IN_READ, index), \
@@ -1610,8 +1634,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 		show_alarm_beep, store_beep, BEEP_ENABLE,		\
 		index + ((index > 14) ? 1 : 0)) }
 
-/* Don't change the attribute order, _beep is accessed by index
- * somewhere else in the code */
+/*
+ * Don't change the attribute order, _beep is accessed by index
+ * somewhere else in the code
+ */
 #define SENSOR_ATTR_FAN(index) {					\
 	SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan,		\
 		NULL, FAN_INPUT, index - 1), \
@@ -1625,23 +1651,25 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 #define SENSOR_ATTR_PWM(index) {					\
 	SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm,		\
 		store_pwm, PWM_OUTPUT, index - 1),			\
+	SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO,		\
+		show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \
+	SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO,			\
+		show_pwm_mode, NULL, NOT_USED, index - 1),		\
+	SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO,		\
+		show_pwm, store_pwm, PWM_FREQ, index - 1),		\
 	SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO,		\
 		show_pwm, store_pwm, PWM_NONSTOP, index - 1),		\
 	SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO,		\
 		show_pwm, store_pwm, PWM_START, index - 1),		\
 	SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO,	\
 		show_pwm, store_pwm, PWM_STOP_TIME, index - 1),	 \
-	SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO,	\
-		show_pwm, store_pwm, PWM_FREQ, index - 1),	 \
-	SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO,		\
-		show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \
-	SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO,			\
-		show_pwm_mode, NULL, NOT_USED, index - 1),		\
 	SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \
 		show_fanin, store_fanin, FANIN_TARGET, index - 1) }
 
-/* Don't change the attribute order, _beep is accessed by index
- * somewhere else in the code */
+/*
+ * Don't change the attribute order, _beep is accessed by index
+ * somewhere else in the code
+ */
 #define SENSOR_ATTR_DTS(index) {					\
 	SENSOR_ATTR_2(temp##index##_type, S_IRUGO ,		\
 		show_dts_mode, NULL, NOT_USED, index - 7),	\
@@ -1660,8 +1688,10 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
 	SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO,		\
 		show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) }
 
-/* Don't change the attribute order, _beep is accessed by index
- * somewhere else in the code */
+/*
+ * Don't change the attribute order, _beep is accessed by index
+ * somewhere else in the code
+ */
 #define SENSOR_ATTR_TEMP(index) {					\
 	SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
 		show_temp_mode, store_temp_mode, NOT_USED, index - 1),	\
@@ -1867,8 +1897,10 @@ static int w83795_get_device_id(struct i2c_client *client)
 
 	device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID);
 
-	/* Special case for rev. A chips; can't be checked first because later
-	   revisions emulate this for compatibility */
+	/*
+	 * Special case for rev. A chips; can't be checked first because later
+	 * revisions emulate this for compatibility
+	 */
 	if (device_id < 0 || (device_id & 0xf0) != 0x50) {
 		int alt_id;
 
@@ -1920,8 +1952,10 @@ static int w83795_detect(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	/* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR
-	   should match */
+	/*
+	 * If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR
+	 * should match
+	 */
 	if ((bank & 0x07) == 0) {
 		i2c_addr = i2c_smbus_read_byte_data(client,
 						    W83795_REG_I2C_ADDR);
@@ -1933,10 +1967,12 @@ static int w83795_detect(struct i2c_client *client,
 		}
 	}
 
-	/* Check 795 chip type: 795G or 795ADG
-	   Usually we don't write to chips during detection, but here we don't
-	   quite have the choice; hopefully it's OK, we are about to return
-	   success anyway */
+	/*
+	 * Check 795 chip type: 795G or 795ADG
+	 * Usually we don't write to chips during detection, but here we don't
+	 * quite have the choice; hopefully it's OK, we are about to return
+	 * success anyway
+	 */
 	if ((bank & 0x07) != 0)
 		i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL,
 					  bank & ~0x07);
@@ -1953,6 +1989,14 @@ static int w83795_detect(struct i2c_client *client,
 	return 0;
 }
 
+#ifdef CONFIG_SENSORS_W83795_FANCTRL
+#define NUM_PWM_ATTRIBUTES	ARRAY_SIZE(w83795_pwm[0])
+#define NUM_TEMP_ATTRIBUTES	ARRAY_SIZE(w83795_temp[0])
+#else
+#define NUM_PWM_ATTRIBUTES	4
+#define NUM_TEMP_ATTRIBUTES	8
+#endif
+
 static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
 			       const struct device_attribute *))
 {
@@ -2006,24 +2050,18 @@ static int w83795_handle_files(struct device *dev, int (*fn)(struct device *,
 		}
 	}
 
-#ifdef CONFIG_SENSORS_W83795_FANCTRL
 	for (i = 0; i < data->has_pwm; i++) {
-		for (j = 0; j < ARRAY_SIZE(w83795_pwm[0]); j++) {
+		for (j = 0; j < NUM_PWM_ATTRIBUTES; j++) {
 			err = fn(dev, &w83795_pwm[i][j].dev_attr);
 			if (err)
 				return err;
 		}
 	}
-#endif
 
 	for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) {
 		if (!(data->has_temp & (1 << i)))
 			continue;
-#ifdef CONFIG_SENSORS_W83795_FANCTRL
-		for (j = 0; j < ARRAY_SIZE(w83795_temp[0]); j++) {
-#else
-		for (j = 0; j < 8; j++) {
-#endif
+		for (j = 0; j < NUM_TEMP_ATTRIBUTES; j++) {
 			if (j == 7 && !data->enable_beep)
 				continue;
 			err = fn(dev, &w83795_temp[i][j].dev_attr);
@@ -2183,8 +2221,10 @@ static int w83795_probe(struct i2c_client *client,
 		/* The W83795G has a dedicated BEEP pin */
 		data->enable_beep = 1;
 	} else {
-		/* The W83795ADG has a shared pin for OVT# and BEEP, so you
-		 * can't have both */
+		/*
+		 * The W83795ADG has a shared pin for OVT# and BEEP, so you
+		 * can't have both
+		 */
 		tmp = w83795_read(client, W83795_REG_OVT_CFG);
 		if ((tmp & OVT_CFG_SEL) == 0)
 			data->enable_beep = 1;
@@ -2244,19 +2284,8 @@ static struct i2c_driver w83795_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init sensors_w83795_init(void)
-{
-	return i2c_add_driver(&w83795_driver);
-}
-
-static void __exit sensors_w83795_exit(void)
-{
-	i2c_del_driver(&w83795_driver);
-}
+module_i2c_driver(w83795_driver);
 
 MODULE_AUTHOR("Wei Song, Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("W83795G/ADG hardware monitoring driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83795_init);
-module_exit(sensors_w83795_exit);
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index 20781de..5f14e38 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -86,7 +86,7 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev);
 /*
  * Driver data (common to all clients)
  */
- 
+
 static const struct i2c_device_id w83l785ts_id[] = {
 	{ "w83l785ts", 0 },
 	{ }
@@ -116,8 +116,7 @@ struct w83l785ts_data {
 	unsigned long last_updated; /* in jiffies */
 
 	/* registers values */
-	s8 temp[2]; /* 0: input
-		       1: critical limit */
+	s8 temp[2]; /* 0: input, 1: critical limit */
 };
 
 /*
@@ -250,8 +249,10 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
 	struct device *dev;
 	const char *prefix;
 
-	/* We might be called during detection, at which point the client
-	   isn't yet fully initialized, so we can't use dev_dbg on it */
+	/*
+	 * We might be called during detection, at which point the client
+	 * isn't yet fully initialized, so we can't use dev_dbg on it
+	 */
 	if (i2c_get_clientdata(client)) {
 		dev = &client->dev;
 		prefix = "";
@@ -260,9 +261,11 @@ static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
 		prefix = "w83l785ts: ";
 	}
 
-	/* Frequent read errors have been reported on Asus boards, so we
+	/*
+	 * Frequent read errors have been reported on Asus boards, so we
 	 * retry on read errors. If it still fails (unlikely), return the
-	 * default value requested by the caller. */
+	 * default value requested by the caller.
+	 */
 	for (i = 1; i <= MAX_RETRIES; i++) {
 		value = i2c_smbus_read_byte_data(client, reg);
 		if (value >= 0) {
@@ -302,19 +305,8 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
 	return data;
 }
 
-static int __init sensors_w83l785ts_init(void)
-{
-	return i2c_add_driver(&w83l785ts_driver);
-}
-
-static void __exit sensors_w83l785ts_exit(void)
-{
-	i2c_del_driver(&w83l785ts_driver);
-}
+module_i2c_driver(w83l785ts_driver);
 
 MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("W83L785TS-S driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83l785ts_init);
-module_exit(sensors_w83l785ts_exit);
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index 063bd95..5850b77 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -1,28 +1,28 @@
 /*
-    w83l786ng.c - Linux kernel driver for hardware monitoring
-    Copyright (c) 2007 Kevin Lo <kevlo@kevlo.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 - version 2.
-
-    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., 51 Franklin Street, Fifth Floor, Boston, MA
-    02110-1301 USA.
-*/
+ * w83l786ng.c - Linux kernel driver for hardware monitoring
+ * Copyright (c) 2007 Kevin Lo <kevlo@kevlo.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 - version 2.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
 
 /*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    w83l786ng	3	2	2	2	0x7b	0x5ca3	yes	no
-*/
+ * Supports following chips:
+ *
+ * Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+ * w83l786ng	3	2	2	2	0x7b	0x5ca3	yes	no
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
 
 #define W83L786NG_REG_CONFIG		0x40
 #define W83L786NG_REG_ALARM1		0x41
-#define W83L786NG_REG_ALARM2 		0x42
+#define W83L786NG_REG_ALARM2		0x42
 #define W83L786NG_REG_GPIO_EN		0x47
 #define W83L786NG_REG_MAN_ID2		0x4C
 #define W83L786NG_REG_MAN_ID1		0x4D
@@ -89,19 +89,23 @@ FAN_TO_REG(long rpm, int div)
 	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
-#define FAN_FROM_REG(val,div)	((val) == 0   ? -1 : \
+#define FAN_FROM_REG(val, div)	((val) == 0   ? -1 : \
 				((val) == 255 ? 0 : \
 				1350000 / ((val) * (div))))
 
 /* for temp */
-#define TEMP_TO_REG(val)	(SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
-				    : (val)) / 1000, 0, 0xff))
-#define TEMP_FROM_REG(val)	(((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
-
-/* The analog voltage inputs have 8mV LSB. Since the sysfs output is
-   in mV as would be measured on the chip input pin, need to just
-   multiply/divide by 8 to translate from/to register values. */
-#define IN_TO_REG(val)          (SENSORS_LIMIT((((val) + 4) / 8), 0, 255))
+#define TEMP_TO_REG(val)	(SENSORS_LIMIT(((val) < 0 ? \
+						(val) + 0x100 * 1000 \
+						: (val)) / 1000, 0, 0xff))
+#define TEMP_FROM_REG(val)	(((val) & 0x80 ? \
+				  (val) - 0x100 : (val)) * 1000)
+
+/*
+ * The analog voltage inputs have 8mV LSB. Since the sysfs output is
+ * in mV as would be measured on the chip input pin, need to just
+ * multiply/divide by 8 to translate from/to register values.
+ */
+#define IN_TO_REG(val)		(SENSORS_LIMIT((((val) + 4) / 8), 0, 255))
 #define IN_FROM_REG(val)	((val) * 8)
 
 #define DIV_FROM_REG(val)	(1 << (val))
@@ -116,7 +120,7 @@ DIV_TO_REG(long val)
 			break;
 		val >>= 1;
 	}
-	return ((u8) i);
+	return (u8)i;
 }
 
 struct w83l786ng_data {
@@ -125,7 +129,7 @@ struct w83l786ng_data {
 	char valid;			/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned long last_nonvolatile;	/* In jiffies, last time we update the
-					   nonvolatile registers */
+					 * nonvolatile registers */
 
 	u8 in[3];
 	u8 in_max[3];
@@ -137,10 +141,10 @@ struct w83l786ng_data {
 	u8 temp[2][3];
 	u8 pwm[2];
 	u8 pwm_mode[2];	/* 0->DC variable voltage
-			   1->PWM variable duty cycle */
+			 * 1->PWM variable duty cycle */
 
 	u8 pwm_enable[2]; /* 1->manual
-			     2->thermal cruise (also called SmartFan I) */
+			   * 2->thermal cruise (also called SmartFan I) */
 	u8 tolerance[2];
 };
 
@@ -186,11 +190,11 @@ w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value)
 #define show_in_reg(reg) \
 static ssize_t \
 show_##reg(struct device *dev, struct device_attribute *attr, \
-           char *buf) \
+	   char *buf) \
 { \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct w83l786ng_data *data = w83l786ng_update_device(dev); \
-	return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
 }
 
 show_in_reg(in)
@@ -199,13 +203,16 @@ show_in_reg(in_max)
 
 #define store_in_reg(REG, reg) \
 static ssize_t \
-store_in_##reg (struct device *dev, struct device_attribute *attr, \
-		const char *buf, size_t count) \
+store_in_##reg(struct device *dev, struct device_attribute *attr, \
+	       const char *buf, size_t count) \
 { \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct i2c_client *client = to_i2c_client(dev); \
 	struct w83l786ng_data *data = i2c_get_clientdata(client); \
-	unsigned long val = simple_strtoul(buf, NULL, 10); \
+	unsigned long val; \
+	int err = kstrtoul(buf, 10, &val); \
+	if (err) \
+		return err; \
 	mutex_lock(&data->update_lock); \
 	data->in_##reg[nr] = IN_TO_REG(val); \
 	w83l786ng_write_value(client, W83L786NG_REG_IN_##REG(nr), \
@@ -241,8 +248,8 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
 { \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	struct w83l786ng_data *data = w83l786ng_update_device(dev); \
-        return sprintf(buf,"%d\n", \
-                FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \
+	return sprintf(buf, "%d\n", \
+		FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \
 }
 
 show_fan_reg(fan);
@@ -255,9 +262,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	u32 val;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtoul(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
 	w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr),
@@ -276,10 +287,12 @@ show_fan_div(struct device *dev, struct device_attribute *attr,
 	return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t
 store_fan_div(struct device *dev, struct device_attribute *attr,
 	      const char *buf, size_t count)
@@ -294,11 +307,18 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
 	u8 keep_mask = 0;
 	u8 new_shift = 0;
 
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
 	/* Save fan_min */
 	mutex_lock(&data->update_lock);
 	min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
 
-	data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
+	data->fan_div[nr] = DIV_TO_REG(val);
 
 	switch (nr) {
 	case 0:
@@ -371,16 +391,20 @@ store_temp(struct device *dev, struct device_attribute *attr,
 	int index = sensor_attr->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	s32 val;
+	long val;
+	int err;
+
+	err = kstrtol(buf, 10, &val);
+	if (err)
+		return err;
 
-	val = simple_strtol(buf, NULL, 10);
 	mutex_lock(&data->update_lock);
 	data->temp[nr][index] = TEMP_TO_REG(val);
 	w83l786ng_write_value(client, W83L786NG_REG_TEMP[nr][index],
 			      data->temp[nr][index]);
 	mutex_unlock(&data->update_lock);
 
-        return count;
+	return count;
 }
 
 static struct sensor_device_attribute_2 sda_temp_input[] = {
@@ -403,8 +427,8 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
 };
 
 #define show_pwm_reg(reg) \
-static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
-			   char *buf) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+			  char *buf) \
 { \
 	struct w83l786ng_data *data = w83l786ng_update_device(dev); \
 	int nr = to_sensor_dev_attr(attr)->index; \
@@ -422,8 +446,13 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
 	u8 reg;
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	if (val > 1)
 		return -EINVAL;
@@ -445,7 +474,13 @@ store_pwm(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255);
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	val = SENSORS_LIMIT(val, 0, 255);
 
 	mutex_lock(&data->update_lock);
 	data->pwm[nr] = val;
@@ -461,11 +496,15 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
-
 	u8 reg;
+	unsigned long val;
+	int err;
 
-	if (!val || (val > 2))  /* only modes 1 and 2 are supported */
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+
+	if (!val || val > 2)  /* only modes 1 and 2 are supported */
 		return -EINVAL;
 
 	mutex_lock(&data->update_lock);
@@ -513,10 +552,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
 	int nr = to_sensor_dev_attr(attr)->index;
 	struct i2c_client *client = to_i2c_client(dev);
 	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	u32 val;
 	u8 tol_tmp, tol_mask;
+	unsigned long val;
+	int err;
 
-	val = simple_strtoul(buf, NULL, 10);
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
 
 	mutex_lock(&data->update_lock);
 	tol_mask = w83l786ng_read_value(client,
@@ -524,9 +566,8 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
 	tol_tmp = SENSORS_LIMIT(val, 0, 15);
 	tol_tmp &= 0x0f;
 	data->tolerance[nr] = tol_tmp;
-	if (nr == 1) {
+	if (nr == 1)
 		tol_tmp <<= 4;
-	}
 
 	w83l786ng_write_value(client, W83L786NG_REG_TOLERANCE,
 			      tol_mask | tol_tmp);
@@ -591,9 +632,8 @@ w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
 	u16 man_id;
 	u8 chip_id;
 
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
-	}
 
 	/* Detection */
 	if ((w83l786ng_read_value(client, W83L786NG_REG_CONFIG) & 0x80)) {
@@ -652,7 +692,8 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	data->fan_div[1] = (reg_tmp >> 4) & 0x07;
 
 	/* Register sysfs hooks */
-	if ((err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group)))
+	err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group);
+	if (err)
 		goto exit_remove;
 
 	data->hwmon_dev = hwmon_device_register(dev);
@@ -769,21 +810,8 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
 	return data;
 }
 
-static int __init
-sensors_w83l786ng_init(void)
-{
-	return i2c_add_driver(&w83l786ng_driver);
-}
-
-static void __exit
-sensors_w83l786ng_exit(void)
-{
-	i2c_del_driver(&w83l786ng_driver);
-}
+module_i2c_driver(w83l786ng_driver);
 
 MODULE_AUTHOR("Kevin Lo");
 MODULE_DESCRIPTION("w83l786ng driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83l786ng_init);
-module_exit(sensors_w83l786ng_exit);
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c
index 9b598ed..07cb25a 100644
--- a/drivers/hwmon/wm831x-hwmon.c
+++ b/drivers/hwmon/wm831x-hwmon.c
@@ -40,7 +40,7 @@ static ssize_t show_name(struct device *dev,
 	return sprintf(buf, "wm831x\n");
 }
 
-static const char *input_names[] = {
+static const char * const input_names[] = {
 	[WM831X_AUX_SYSVDD]    = "SYSVDD",
 	[WM831X_AUX_USB]       = "USB",
 	[WM831X_AUX_BKUP_BATT] = "Backup battery",
@@ -117,8 +117,10 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_chip_temp, NULL,
 			  WM831X_AUX_CHIP_TEMP);
 static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL,
 			  WM831X_AUX_CHIP_TEMP);
-/* Report as a voltage since conversion depends on external components
- * and that's what the ABI wants. */
+/*
+ * Report as a voltage since conversion depends on external components
+ * and that's what the ABI wants.
+ */
 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_voltage, NULL,
 			  WM831X_AUX_BATT_TEMP);
 static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
index 3ff67ed..b955756 100644
--- a/drivers/hwmon/wm8350-hwmon.c
+++ b/drivers/hwmon/wm8350-hwmon.c
@@ -34,7 +34,7 @@ static ssize_t show_name(struct device *dev,
 	return sprintf(buf, "wm8350\n");
 }
 
-static const char *input_names[] = {
+static const char * const input_names[] = {
 	[WM8350_AUXADC_USB]  = "USB",
 	[WM8350_AUXADC_LINE] = "Line",
 	[WM8350_AUXADC_BATT] = "Battery",
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 3101dd5..f4e8ba9 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -103,6 +103,7 @@ config I2C_I801
 	    Patsburg (PCH)
 	    DH89xxCC (PCH)
 	    Panther Point (PCH)
+	    Lynx Point (PCH)
 
 	  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-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index a651779..69fbfae 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -14,8 +14,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 
 /* Toggle SDA by changing the direction of the pin */
 static void i2c_gpio_setsda_dir(void *data, int state)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 5d2e281..ae2945a 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -2,7 +2,7 @@
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
     Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
     <mdsxyz123@yahoo.com>
-    Copyright (C) 2007, 2008   Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2007 - 2012  Jean Delvare <khali@linux-fr.org>
     Copyright (C) 2010         Intel Corporation,
                                David Woodhouse <dwmw2@infradead.org>
 
@@ -51,6 +51,7 @@
   Patsburg (PCH) IDF    0x1d72     32     hard     yes     yes     yes
   DH89xxCC (PCH)        0x2330     32     hard     yes     yes     yes
   Panther Point (PCH)   0x1e22     32     hard     yes     yes     yes
+  Lynx Point (PCH)      0x8c22     32     hard     yes     yes     yes
 
   Features supported by this driver:
   Software PEC                     no
@@ -105,7 +106,7 @@
 #define SMBHSTCNT_KILL		2
 
 /* Other settings */
-#define MAX_TIMEOUT		100
+#define MAX_RETRIES		400
 #define ENABLE_INT9		0	/* set to 0x01 to enable - untested */
 
 /* I801 command constants */
@@ -145,6 +146,7 @@
 #define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS	0x1e22
 #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS	0x2330
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS	0x3b30
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS	0x8c22
 
 struct i801_priv {
 	struct i2c_adapter adapter;
@@ -215,7 +217,7 @@ static int i801_check_post(struct i801_priv *priv, int status, int timeout)
 		dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
 		outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
 		       SMBHSTCNT(priv));
-		msleep(1);
+		usleep_range(1000, 2000);
 		outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
 		       SMBHSTCNT(priv));
 
@@ -272,11 +274,11 @@ static int i801_transaction(struct i801_priv *priv, int xact)
 
 	/* We will always wait for a fraction of a second! */
 	do {
-		msleep(1);
+		usleep_range(250, 500);
 		status = inb_p(SMBHSTSTS(priv));
-	} while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
+	} while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_RETRIES));
 
-	result = i801_check_post(priv, status, timeout > MAX_TIMEOUT);
+	result = i801_check_post(priv, status, timeout > MAX_RETRIES);
 	if (result < 0)
 		return result;
 
@@ -291,12 +293,12 @@ static void i801_wait_hwpec(struct i801_priv *priv)
 	int status;
 
 	do {
-		msleep(1);
+		usleep_range(250, 500);
 		status = inb_p(SMBHSTSTS(priv));
 	} while ((!(status & SMBHSTSTS_INTR))
-		 && (timeout++ < MAX_TIMEOUT));
+		 && (timeout++ < MAX_RETRIES));
 
-	if (timeout > MAX_TIMEOUT)
+	if (timeout > MAX_RETRIES)
 		dev_dbg(&priv->pci_dev->dev, "PEC Timeout!\n");
 
 	outb_p(status, SMBHSTSTS(priv));
@@ -380,12 +382,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
 		/* We will always wait for a fraction of a second! */
 		timeout = 0;
 		do {
-			msleep(1);
+			usleep_range(250, 500);
 			status = inb_p(SMBHSTSTS(priv));
 		} while ((!(status & SMBHSTSTS_BYTE_DONE))
-			 && (timeout++ < MAX_TIMEOUT));
+			 && (timeout++ < MAX_RETRIES));
 
-		result = i801_check_post(priv, status, timeout > MAX_TIMEOUT);
+		result = i801_check_post(priv, status, timeout > MAX_RETRIES);
 		if (result < 0)
 			return result;
 
@@ -633,6 +635,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) },
 	{ 0, }
 };
 
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 58832e5..8d1ab6f 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -196,7 +196,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
 
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
-	clk_enable(i2c_imx->clk);
+	clk_prepare_enable(i2c_imx->clk);
 	writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
 	/* Enable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2SR);
@@ -245,7 +245,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 
 	/* Disable I2C controller */
 	writeb(0, i2c_imx->base + IMX_I2C_I2CR);
-	clk_disable(i2c_imx->clk);
+	clk_disable_unprepare(i2c_imx->clk);
 }
 
 static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 6561d27..f90a605 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -47,7 +47,7 @@
 #define SMBBLKDAT	(0x20 + sch_smba)
 
 /* Other settings */
-#define MAX_TIMEOUT	500
+#define MAX_RETRIES	5000
 
 /* I2C constants */
 #define SCH_QUICK		0x00
@@ -68,7 +68,7 @@ static int sch_transaction(void)
 {
 	int temp;
 	int result = 0;
-	int timeout = 0;
+	int retries = 0;
 
 	dev_dbg(&sch_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
 		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb(SMBHSTCNT),
@@ -100,12 +100,12 @@ static int sch_transaction(void)
 	outb(inb(SMBHSTCNT) | 0x10, SMBHSTCNT);
 
 	do {
-		msleep(1);
+		usleep_range(100, 200);
 		temp = inb(SMBHSTSTS) & 0x0f;
-	} while ((temp & 0x08) && (timeout++ < MAX_TIMEOUT));
+	} while ((temp & 0x08) && (retries++ < MAX_RETRIES));
 
 	/* If the SMBus is still busy, we give up */
-	if (timeout > MAX_TIMEOUT) {
+	if (retries > MAX_RETRIES) {
 		dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
 		result = -ETIMEDOUT;
 	}
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 1e56061..e9c1893 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1386,8 +1386,10 @@ int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
 
 	ret = i2c_transfer(adap, &msg, 1);
 
-	/* If everything went ok (i.e. 1 msg transmitted), return #bytes
-	   transmitted, else error code. */
+	/*
+	 * If everything went ok (i.e. 1 msg transmitted), return #bytes
+	 * transmitted, else error code.
+	 */
 	return (ret == 1) ? count : ret;
 }
 EXPORT_SYMBOL(i2c_master_send);
@@ -1414,8 +1416,10 @@ int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
 
 	ret = i2c_transfer(adap, &msg, 1);
 
-	/* If everything went ok (i.e. 1 msg transmitted), return #bytes
-	   transmitted, else error code. */
+	/*
+	 * If everything went ok (i.e. 1 msg received), return #bytes received,
+	 * else error code.
+	 */
 	return (ret == 1) ? count : ret;
 }
 EXPORT_SYMBOL(i2c_master_recv);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 5bc2839..729428e 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -253,7 +253,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 		if (page_is_high)
 			local_irq_save(flags);
 
-		buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+		buf = kmap_atomic(page) + offset;
 
 		cmd->nleft -= nr_bytes;
 		cmd->cursg_ofs += nr_bytes;
@@ -269,7 +269,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 		else
 			hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
 
-		kunmap_atomic(buf, KM_BIO_SRC_IRQ);
+		kunmap_atomic(buf);
 
 		if (page_is_high)
 			local_irq_restore(flags);
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 54ab97b..1c15e9b 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -62,6 +62,7 @@
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
+#include <asm/cpu_device_id.h>
 #include <asm/mwait.h>
 #include <asm/msr.h>
 
@@ -81,6 +82,17 @@ static unsigned int mwait_substates;
 /* Reliable LAPIC Timer States, bit 1 for C1 etc.  */
 static unsigned int lapic_timer_reliable_states = (1 << 1);	 /* Default to only C1 */
 
+struct idle_cpu {
+	struct cpuidle_state *state_table;
+
+	/*
+	 * Hardware C-state auto-demotion may not always be optimal.
+	 * Indicate which enable bits to clear here.
+	 */
+	unsigned long auto_demotion_disable_flags;
+};
+
+static const struct idle_cpu *icpu;
 static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
 static int intel_idle(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv, int index);
@@ -88,12 +100,6 @@ static int intel_idle(struct cpuidle_device *dev,
 static struct cpuidle_state *cpuidle_state_table;
 
 /*
- * Hardware C-state auto-demotion may not always be optimal.
- * Indicate which enable bits to clear here.
- */
-static unsigned long long auto_demotion_disable_flags;
-
-/*
  * Set this flag for states where the HW flushes the TLB for us
  * and so we don't need cross-calls to keep it consistent.
  * If this flag is set, SW flushes the TLB, so even if the
@@ -319,27 +325,68 @@ static void auto_demotion_disable(void *dummy)
 	unsigned long long msr_bits;
 
 	rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
-	msr_bits &= ~auto_demotion_disable_flags;
+	msr_bits &= ~(icpu->auto_demotion_disable_flags);
 	wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
 }
 
+static const struct idle_cpu idle_cpu_nehalem = {
+	.state_table = nehalem_cstates,
+	.auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE,
+};
+
+static const struct idle_cpu idle_cpu_atom = {
+	.state_table = atom_cstates,
+};
+
+static const struct idle_cpu idle_cpu_lincroft = {
+	.state_table = atom_cstates,
+	.auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE,
+};
+
+static const struct idle_cpu idle_cpu_snb = {
+	.state_table = snb_cstates,
+};
+
+#define ICPU(model, cpu) \
+	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu }
+
+static const struct x86_cpu_id intel_idle_ids[] = {
+	ICPU(0x1a, idle_cpu_nehalem),
+	ICPU(0x1e, idle_cpu_nehalem),
+	ICPU(0x1f, idle_cpu_nehalem),
+	ICPU(0x25, idle_cpu_nehalem),
+	ICPU(0x2c, idle_cpu_nehalem),
+	ICPU(0x2e, idle_cpu_nehalem),
+	ICPU(0x1c, idle_cpu_atom),
+	ICPU(0x26, idle_cpu_lincroft),
+	ICPU(0x2f, idle_cpu_nehalem),
+	ICPU(0x2a, idle_cpu_snb),
+	ICPU(0x2d, idle_cpu_snb),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
+
 /*
  * intel_idle_probe()
  */
 static int intel_idle_probe(void)
 {
 	unsigned int eax, ebx, ecx;
+	const struct x86_cpu_id *id;
 
 	if (max_cstate == 0) {
 		pr_debug(PREFIX "disabled\n");
 		return -EPERM;
 	}
 
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
-		return -ENODEV;
-
-	if (!boot_cpu_has(X86_FEATURE_MWAIT))
+	id = x86_match_cpu(intel_idle_ids);
+	if (!id) {
+		if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+		    boot_cpu_data.x86 == 6)
+			pr_debug(PREFIX "does not run on family %d model %d\n",
+				boot_cpu_data.x86, boot_cpu_data.x86_model);
 		return -ENODEV;
+	}
 
 	if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
 		return -ENODEV;
@@ -353,43 +400,8 @@ static int intel_idle_probe(void)
 
 	pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
 
-
-	if (boot_cpu_data.x86 != 6)	/* family 6 */
-		return -ENODEV;
-
-	switch (boot_cpu_data.x86_model) {
-
-	case 0x1A:	/* Core i7, Xeon 5500 series */
-	case 0x1E:	/* Core i7 and i5 Processor - Lynnfield Jasper Forest */
-	case 0x1F:	/* Core i7 and i5 Processor - Nehalem */
-	case 0x2E:	/* Nehalem-EX Xeon */
-	case 0x2F:	/* Westmere-EX Xeon */
-	case 0x25:	/* Westmere */
-	case 0x2C:	/* Westmere */
-		cpuidle_state_table = nehalem_cstates;
-		auto_demotion_disable_flags =
-			(NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
-		break;
-
-	case 0x1C:	/* 28 - Atom Processor */
-		cpuidle_state_table = atom_cstates;
-		break;
-
-	case 0x26:	/* 38 - Lincroft Atom Processor */
-		cpuidle_state_table = atom_cstates;
-		auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
-		break;
-
-	case 0x2A:	/* SNB */
-	case 0x2D:	/* SNB Xeon */
-		cpuidle_state_table = snb_cstates;
-		break;
-
-	default:
-		pr_debug(PREFIX "does not run on family %d model %d\n",
-			boot_cpu_data.x86, boot_cpu_data.x86_model);
-		return -ENODEV;
-	}
+	icpu = (const struct idle_cpu *)id->driver_data;
+	cpuidle_state_table = icpu->state_table;
 
 	if (boot_cpu_has(X86_FEATURE_ARAT))	/* Always Reliable APIC Timer */
 		lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
@@ -470,7 +482,7 @@ static int intel_idle_cpuidle_driver_init(void)
 		drv->state_count += 1;
 	}
 
-	if (auto_demotion_disable_flags)
+	if (icpu->auto_demotion_disable_flags)
 		on_each_cpu(auto_demotion_disable, NULL, 1);
 
 	return 0;
@@ -522,7 +534,7 @@ int intel_idle_cpu_init(int cpu)
 		return -EIO;
 	}
 
-	if (auto_demotion_disable_flags)
+	if (icpu->auto_demotion_disable_flags)
 		smp_call_function_single(cpu, auto_demotion_disable, NULL, 1);
 
 	return 0;
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 1612cfd..6ef660c 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -178,22 +178,26 @@ static void queue_req(struct addr_req *req)
 	mutex_unlock(&lock);
 }
 
-static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr)
+static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, void *daddr)
 {
 	struct neighbour *n;
 	int ret;
 
+	n = dst_neigh_lookup(dst, daddr);
+
 	rcu_read_lock();
-	n = dst_get_neighbour_noref(dst);
 	if (!n || !(n->nud_state & NUD_VALID)) {
 		if (n)
 			neigh_event_send(n, NULL);
 		ret = -ENODATA;
 	} else {
-		ret = rdma_copy_addr(addr, dst->dev, n->ha);
+		ret = rdma_copy_addr(dev_addr, dst->dev, n->ha);
 	}
 	rcu_read_unlock();
 
+	if (n)
+		neigh_release(n);
+
 	return ret;
 }
 
@@ -232,7 +236,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		goto put;
 	}
 
-	ret = dst_fetch_ha(&rt->dst, addr);
+	ret = dst_fetch_ha(&rt->dst, addr, &fl4.daddr);
 put:
 	ip_rt_put(rt);
 out:
@@ -280,7 +284,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		goto put;
 	}
 
-	ret = dst_fetch_ha(dst, addr);
+	ret = dst_fetch_ha(dst, addr, &fl6.daddr);
 put:
 	dst_release(dst);
 	return ret;
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 0668bb3..0cf6155 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -1562,11 +1562,11 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst,
 	struct neighbour *n;
 	int err, step;
 
-	rcu_read_lock();
-	n = dst_get_neighbour_noref(dst);
-	err = -ENODEV;
+	n = dst_neigh_lookup(dst, &peer_ip);
 	if (!n)
-		goto out;
+		return -ENODEV;
+
+	rcu_read_lock();
 	err = -ENOMEM;
 	if (n->dev->flags & IFF_LOOPBACK) {
 		struct net_device *pdev;
@@ -1614,6 +1614,8 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst,
 out:
 	rcu_read_unlock();
 
+	neigh_release(n);
+
 	return err;
 }
 
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index a4972ab..c5e4cb2 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1351,8 +1351,9 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
 	else
 		netdev = nesvnic->netdev;
 
+	neigh = dst_neigh_lookup(&rt->dst, &dst_ip);
+
 	rcu_read_lock();
-	neigh = dst_get_neighbour_noref(&rt->dst);
 	if (neigh) {
 		if (neigh->nud_state & NUD_VALID) {
 			nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
@@ -1379,9 +1380,12 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
 			neigh_event_send(neigh, NULL);
 		}
 	}
-
 out:
 	rcu_read_unlock();
+
+	if (neigh)
+		neigh_release(neigh);
+
 	ip_rt_put(rt);
 	return rc;
 }
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index fb88d68..2033a92 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -73,11 +73,11 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
 
 		p = mem;
 		for_each_sg(sgl, sg, data->size, i) {
-			from = kmap_atomic(sg_page(sg), KM_USER0);
+			from = kmap_atomic(sg_page(sg));
 			memcpy(p,
 			       from + sg->offset,
 			       sg->length);
-			kunmap_atomic(from, KM_USER0);
+			kunmap_atomic(from);
 			p += sg->length;
 		}
 	}
@@ -133,11 +133,11 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
 
 		p = mem;
 		for_each_sg(sgl, sg, sg_size, i) {
-			to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
+			to = kmap_atomic(sg_page(sg));
 			memcpy(to + sg->offset,
 			       p,
 			       sg->length);
-			kunmap_atomic(to, KM_SOFTIRQ0);
+			kunmap_atomic(to);
 			p += sg->length;
 		}
 	}
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 2b73d43..b8367f1 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1378,7 +1378,9 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
 		break;
 	case SRPT_STATE_NEED_DATA:
 		/* DMA_TO_DEVICE (write) - RDMA read error. */
-		atomic_set(&ioctx->cmd.transport_lun_stop, 1);
+		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
+		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
+		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
 		transport_generic_handle_data(&ioctx->cmd);
 		break;
 	case SRPT_STATE_CMD_RSP_SENT:
@@ -1387,7 +1389,9 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
 		 * not been received in time.
 		 */
 		srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
-		atomic_set(&ioctx->cmd.transport_lun_stop, 1);
+		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
+		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
+		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
 		kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
 		break;
 	case SRPT_STATE_MGMT_RSP_SENT:
@@ -1494,6 +1498,7 @@ static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch,
 {
 	struct se_cmd *cmd;
 	enum srpt_command_state state;
+	unsigned long flags;
 
 	cmd = &ioctx->cmd;
 	state = srpt_get_cmd_state(ioctx);
@@ -1513,7 +1518,9 @@ static void srpt_handle_rdma_err_comp(struct srpt_rdma_ch *ch,
 			       __func__, __LINE__, state);
 		break;
 	case SRPT_RDMA_WRITE_LAST:
-		atomic_set(&ioctx->cmd.transport_lun_stop, 1);
+		spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
+		ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
+		spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
 		break;
 	default:
 		printk(KERN_ERR "%s[%d]: opcode = %u\n", __func__,
@@ -3450,7 +3457,7 @@ static struct se_node_acl *srpt_alloc_fabric_acl(struct se_portal_group *se_tpg)
 
 	nacl = kzalloc(sizeof(struct srpt_node_acl), GFP_KERNEL);
 	if (!nacl) {
-		printk(KERN_ERR "Unable to alocate struct srpt_node_acl\n");
+		printk(KERN_ERR "Unable to allocate struct srpt_node_acl\n");
 		return NULL;
 	}
 
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index afc166f..cfe7859 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -20,7 +20,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/major.h>
 #include <linux/device.h>
 #include "input-compat.h"
@@ -46,6 +46,7 @@ struct evdev_client {
 	struct fasync_struct *fasync;
 	struct evdev *evdev;
 	struct list_head node;
+	int clkid;
 	unsigned int bufsize;
 	struct input_event buffer[];
 };
@@ -54,8 +55,12 @@ static struct evdev *evdev_table[EVDEV_MINORS];
 static DEFINE_MUTEX(evdev_table_mutex);
 
 static void evdev_pass_event(struct evdev_client *client,
-			     struct input_event *event)
+			     struct input_event *event,
+			     ktime_t mono, ktime_t real)
 {
+	event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
+					mono : real);
+
 	/* Interrupts are disabled, just acquire the lock. */
 	spin_lock(&client->buffer_lock);
 
@@ -94,8 +99,11 @@ static void evdev_event(struct input_handle *handle,
 	struct evdev *evdev = handle->private;
 	struct evdev_client *client;
 	struct input_event event;
+	ktime_t time_mono, time_real;
+
+	time_mono = ktime_get();
+	time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());
 
-	do_gettimeofday(&event.time);
 	event.type = type;
 	event.code = code;
 	event.value = value;
@@ -103,11 +111,12 @@ static void evdev_event(struct input_handle *handle,
 	rcu_read_lock();
 
 	client = rcu_dereference(evdev->grab);
+
 	if (client)
-		evdev_pass_event(client, &event);
+		evdev_pass_event(client, &event, time_mono, time_real);
 	else
 		list_for_each_entry_rcu(client, &evdev->client_list, node)
-			evdev_pass_event(client, &event);
+			evdev_pass_event(client, &event, time_mono, time_real);
 
 	rcu_read_unlock();
 
@@ -623,6 +632,28 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
 	return input_set_keycode(dev, &ke);
 }
 
+static int evdev_handle_mt_request(struct input_dev *dev,
+				   unsigned int size,
+				   int __user *ip)
+{
+	const struct input_mt_slot *mt = dev->mt;
+	unsigned int code;
+	int max_slots;
+	int i;
+
+	if (get_user(code, &ip[0]))
+		return -EFAULT;
+	if (!input_is_mt_value(code))
+		return -EINVAL;
+
+	max_slots = (size - sizeof(__u32)) / sizeof(__s32);
+	for (i = 0; i < dev->mtsize && i < max_slots; i++)
+		if (put_user(input_mt_get_value(&mt[i], code), &ip[1 + i]))
+			return -EFAULT;
+
+	return 0;
+}
+
 static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 			   void __user *p, int compat_mode)
 {
@@ -685,6 +716,14 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 		else
 			return evdev_ungrab(evdev, client);
 
+	case EVIOCSCLOCKID:
+		if (copy_from_user(&i, p, sizeof(unsigned int)))
+			return -EFAULT;
+		if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
+			return -EINVAL;
+		client->clkid = i;
+		return 0;
+
 	case EVIOCGKEYCODE:
 		return evdev_handle_get_keycode(dev, p);
 
@@ -708,6 +747,9 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 		return bits_to_user(dev->propbit, INPUT_PROP_MAX,
 				    size, p, compat_mode);
 
+	case EVIOCGMTSLOTS(0):
+		return evdev_handle_mt_request(dev, size, ip);
+
 	case EVIOCGKEY(0):
 		return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
 
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index c351aa4..da739d9 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -449,7 +449,6 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut
 	} else if ((drv = driver_find(buf, &gameport_bus)) != NULL) {
 		gameport_disconnect_port(gameport);
 		error = gameport_bind_driver(gameport, to_gameport_driver(drv));
-		put_driver(drv);
 	} else {
 		error = -EINVAL;
 	}
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 1f78c95..8921c61 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -180,7 +180,7 @@ static int input_handle_abs_event(struct input_dev *dev,
 		return INPUT_IGNORE_EVENT;
 	}
 
-	is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;
+	is_mt_event = input_is_mt_value(code);
 
 	if (!is_mt_event) {
 		pold = &dev->absinfo[code].value;
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c
index e35566a..101e245 100644
--- a/drivers/input/keyboard/nomadik-ske-keypad.c
+++ b/drivers/input/keyboard/nomadik-ske-keypad.c
@@ -88,7 +88,7 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr,
  *
  * Enable Multi key press detection, auto scan mode
  */
-static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad)
+static int __init ske_keypad_chip_init(struct ske_keypad *keypad)
 {
 	u32 value;
 	int timeout = 50;
@@ -198,7 +198,7 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int __devinit ske_keypad_probe(struct platform_device *pdev)
+static int __init ske_keypad_probe(struct platform_device *pdev)
 {
 	const struct ske_keypad_platform_data *plat = pdev->dev.platform_data;
 	struct ske_keypad *keypad;
@@ -344,7 +344,7 @@ static int __devexit ske_keypad_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ske_keypad_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -372,22 +372,17 @@ static int ske_keypad_resume(struct device *dev)
 
 	return 0;
 }
-
-static const struct dev_pm_ops ske_keypad_dev_pm_ops = {
-	.suspend = ske_keypad_suspend,
-	.resume = ske_keypad_resume,
-};
 #endif
 
+static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops,
+			 ske_keypad_suspend, ske_keypad_resume);
+
 static struct platform_driver ske_keypad_driver = {
 	.driver = {
 		.name = "nmk-ske-keypad",
 		.owner  = THIS_MODULE,
-#ifdef CONFIG_PM
 		.pm = &ske_keypad_dev_pm_ops,
-#endif
 	},
-	.probe = ske_keypad_probe,
 	.remove = __devexit_p(ske_keypad_remove),
 };
 
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index 17ba7f9..2391ae8 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -175,7 +175,7 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id)
 
 	} while (key_down && !keypad->stopped);
 
-	pm_runtime_put_sync(&keypad->pdev->dev);
+	pm_runtime_put(&keypad->pdev->dev);
 
 	return IRQ_HANDLED;
 }
@@ -199,7 +199,7 @@ static void samsung_keypad_start(struct samsung_keypad *keypad)
 	/* KEYIFCOL reg clear. */
 	writel(0, keypad->base + SAMSUNG_KEYIFCOL);
 
-	pm_runtime_put_sync(&keypad->pdev->dev);
+	pm_runtime_put(&keypad->pdev->dev);
 }
 
 static void samsung_keypad_stop(struct samsung_keypad *keypad)
@@ -229,7 +229,7 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad)
 	 */
 	enable_irq(keypad->irq);
 
-	pm_runtime_put_sync(&keypad->pdev->dev);
+	pm_runtime_put(&keypad->pdev->dev);
 }
 
 static int samsung_keypad_open(struct input_dev *input_dev)
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
index a136e2e..dc19432 100644
--- a/drivers/input/keyboard/tegra-kbc.c
+++ b/drivers/input/keyboard/tegra-kbc.c
@@ -48,6 +48,7 @@
 #define KBC_FIFO_TH_CNT_SHIFT(cnt)	(cnt << 14)
 #define KBC_DEBOUNCE_CNT_SHIFT(cnt)	(cnt << 4)
 #define KBC_CONTROL_FIFO_CNT_INT_EN	(1 << 3)
+#define KBC_CONTROL_KEYPRESS_INT_EN	(1 << 1)
 #define KBC_CONTROL_KBC_EN		(1 << 0)
 
 /* KBC Interrupt Register */
@@ -356,6 +357,18 @@ static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable)
 	writel(val, kbc->mmio + KBC_CONTROL_0);
 }
 
+static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable)
+{
+	u32 val;
+
+	val = readl(kbc->mmio + KBC_CONTROL_0);
+	if (enable)
+		val |= KBC_CONTROL_KEYPRESS_INT_EN;
+	else
+		val &= ~KBC_CONTROL_KEYPRESS_INT_EN;
+	writel(val, kbc->mmio + KBC_CONTROL_0);
+}
+
 static void tegra_kbc_keypress_timer(unsigned long data)
 {
 	struct tegra_kbc *kbc = (struct tegra_kbc *)data;
@@ -455,10 +468,18 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc)
 		row_cfg &= ~r_mask;
 		col_cfg &= ~c_mask;
 
-		if (pdata->pin_cfg[i].is_row)
+		switch (pdata->pin_cfg[i].type) {
+		case PIN_CFG_ROW:
 			row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft;
-		else
+			break;
+
+		case PIN_CFG_COL:
 			col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft;
+			break;
+
+		case PIN_CFG_IGNORE:
+			break;
+		}
 
 		writel(row_cfg, kbc->mmio + r_offs);
 		writel(col_cfg, kbc->mmio + c_offs);
@@ -563,7 +584,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata,
 	for (i = 0; i < KBC_MAX_GPIO; i++) {
 		const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i];
 
-		if (pin_cfg->is_row) {
+		switch (pin_cfg->type) {
+		case PIN_CFG_ROW:
 			if (pin_cfg->num >= KBC_MAX_ROW) {
 				dev_err(dev,
 					"pin_cfg[%d]: invalid row number %d\n",
@@ -571,13 +593,25 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata,
 				return false;
 			}
 			(*num_rows)++;
-		} else {
+			break;
+
+		case PIN_CFG_COL:
 			if (pin_cfg->num >= KBC_MAX_COL) {
 				dev_err(dev,
 					"pin_cfg[%d]: invalid column number %d\n",
 					i, pin_cfg->num);
 				return false;
 			}
+			break;
+
+		case PIN_CFG_IGNORE:
+			break;
+
+		default:
+			dev_err(dev,
+				"pin_cfg[%d]: invalid entry type %d\n",
+				pin_cfg->type, pin_cfg->num);
+			return false;
 		}
 	}
 
@@ -594,7 +628,6 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
 	if (!np)
 		return NULL;
 
-	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
 		return NULL;
 
@@ -616,12 +649,12 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
 	 */
 	for (i = 0; i < KBC_MAX_ROW; i++) {
 		pdata->pin_cfg[i].num = i;
-		pdata->pin_cfg[i].is_row = true;
+		pdata->pin_cfg[i].type = PIN_CFG_ROW;
 	}
 
 	for (i = 0; i < KBC_MAX_COL; i++) {
 		pdata->pin_cfg[KBC_MAX_ROW + i].num = i;
-		pdata->pin_cfg[KBC_MAX_ROW + i].is_row = false;
+		pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL;
 	}
 
 	return pdata;
@@ -831,6 +864,8 @@ static int tegra_kbc_suspend(struct device *dev)
 		msleep(30);
 
 		kbc->keypress_caused_wake = false;
+		/* Enable keypress interrupt before going into suspend. */
+		tegra_kbc_set_keypress_interrupt(kbc, true);
 		enable_irq(kbc->irq);
 		enable_irq_wake(kbc->irq);
 	} else {
@@ -852,6 +887,8 @@ static int tegra_kbc_resume(struct device *dev)
 	if (device_may_wakeup(&pdev->dev)) {
 		disable_irq_wake(kbc->irq);
 		tegra_kbc_setup_wakekeys(kbc, false);
+		/* We will use fifo interrupts for key detection. */
+		tegra_kbc_set_keypress_interrupt(kbc, false);
 
 		/* Restore the resident time of continuous polling mode. */
 		writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7b46781..532754f 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -368,8 +368,7 @@ config INPUT_TWL4030_VIBRA
 
 config INPUT_TWL6040_VIBRA
 	tristate "Support for TWL6040 Vibrator"
-	depends on TWL4030_CORE
-	select TWL6040_CORE
+	depends on TWL6040_CORE
 	select INPUT_FF_MEMLESS
 	help
 	  This option enables support for TWL6040 Vibrator Driver.
@@ -415,7 +414,7 @@ config INPUT_PCF8574
 	tristate "PCF8574 Keypad input device"
 	depends on I2C && EXPERIMENTAL
 	help
-	  Say Y here if you want to support a keypad connetced via I2C
+	  Say Y here if you want to support a keypad connected via I2C
 	  with a PCF8574.
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
index 45874fe..14e94f5 100644
--- a/drivers/input/misc/twl6040-vibra.c
+++ b/drivers/input/misc/twl6040-vibra.c
@@ -28,7 +28,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/workqueue.h>
-#include <linux/i2c/twl.h>
+#include <linux/input.h>
 #include <linux/mfd/twl6040.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL);
 
 static int __devinit twl6040_vibra_probe(struct platform_device *pdev)
 {
-	struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+	struct twl6040_vibra_data *pdata = pdev->dev.platform_data;
 	struct vibra_info *info;
 	int ret;
 
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 9c1e6ee..9b8db82 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -322,4 +322,21 @@ config MOUSE_SYNAPTICS_I2C
 	  To compile this driver as a module, choose M here: the
 	  module will be called synaptics_i2c.
 
+config MOUSE_SYNAPTICS_USB
+	tristate "Synaptics USB device support"
+	depends on USB_ARCH_HAS_HCD
+	select USB
+	help
+	  Say Y here if you want to use a Synaptics USB touchpad or pointing
+	  stick.
+
+	  While these devices emulate an USB mouse by default and can be used
+	  with standard usbhid driver, this driver, together with its X.Org
+	  counterpart, allows you to fully utilize capabilities of the device.
+	  More information can be found at:
+	  <http://jan-steinhoff.de/linux/synaptics-usb.html>
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called synaptics_usb.
+
 endif
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 570c84a4..4718eff 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_MOUSE_PXA930_TRKBALL)	+= pxa930_trkball.o
 obj-$(CONFIG_MOUSE_RISCPC)		+= rpcmouse.o
 obj-$(CONFIG_MOUSE_SERIAL)		+= sermouse.o
 obj-$(CONFIG_MOUSE_SYNAPTICS_I2C)	+= synaptics_i2c.o
+obj-$(CONFIG_MOUSE_SYNAPTICS_USB)	+= synaptics_usb.o
 obj-$(CONFIG_MOUSE_VSXXXAA)		+= vsxxxaa.o
 
 psmouse-objs := psmouse-base.o synaptics.o
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 927e479..f9e2758 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -433,6 +433,7 @@ static void setup_events_to_report(struct input_dev *input_dev,
 	__set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
 	__set_bit(BTN_LEFT, input_dev->keybit);
 
+	__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
 	if (cfg->caps & HAS_INTEGRATED_BUTTON)
 		__set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
 
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c
new file mode 100644
index 0000000..e559a94
--- /dev/null
+++ b/drivers/input/mouse/synaptics_usb.c
@@ -0,0 +1,568 @@
+/*
+ * USB Synaptics device driver
+ *
+ *  Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk)
+ *  Copyright (c) 2003 Ron Lee (ron@debian.org)
+ *	cPad driver for kernel 2.4
+ *
+ *  Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de)
+ *  Copyright (c) 2004 Ron Lee (ron@debian.org)
+ *	rewritten for kernel 2.6
+ *
+ *  cPad display character device part is not included. It can be found at
+ *  http://jan-steinhoff.de/linux/synaptics-usb.html
+ *
+ * Bases on:	usb_skeleton.c v2.2 by Greg Kroah-Hartman
+ *		drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik
+ *		drivers/input/mouse/synaptics.c by Peter Osterlund
+ *
+ * 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.
+ *
+ * Trademarks are the property of their respective owners.
+ */
+
+/*
+ * There are three different types of Synaptics USB devices: Touchpads,
+ * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported
+ * by this driver, touchstick support has not been tested much yet, and
+ * touchscreens have not been tested at all.
+ *
+ * Up to three alternate settings are possible:
+ *	setting 0: one int endpoint for relative movement (used by usbhid.ko)
+ *	setting 1: one int endpoint for absolute finger position
+ *	setting 2 (cPad only): one int endpoint for absolute finger position and
+ *		   two bulk endpoints for the display (in/out)
+ * This driver uses setting 1.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <linux/usb/input.h>
+
+#define USB_VENDOR_ID_SYNAPTICS	0x06cb
+#define USB_DEVICE_ID_SYNAPTICS_TP	0x0001	/* Synaptics USB TouchPad */
+#define USB_DEVICE_ID_SYNAPTICS_INT_TP	0x0002	/* Integrated USB TouchPad */
+#define USB_DEVICE_ID_SYNAPTICS_CPAD	0x0003	/* Synaptics cPad */
+#define USB_DEVICE_ID_SYNAPTICS_TS	0x0006	/* Synaptics TouchScreen */
+#define USB_DEVICE_ID_SYNAPTICS_STICK	0x0007	/* Synaptics USB Styk */
+#define USB_DEVICE_ID_SYNAPTICS_WP	0x0008	/* Synaptics USB WheelPad */
+#define USB_DEVICE_ID_SYNAPTICS_COMP_TP	0x0009	/* Composite USB TouchPad */
+#define USB_DEVICE_ID_SYNAPTICS_WTP	0x0010	/* Wireless TouchPad */
+#define USB_DEVICE_ID_SYNAPTICS_DPAD	0x0013	/* DisplayPad */
+
+#define SYNUSB_TOUCHPAD			(1 << 0)
+#define SYNUSB_STICK			(1 << 1)
+#define SYNUSB_TOUCHSCREEN		(1 << 2)
+#define SYNUSB_AUXDISPLAY		(1 << 3) /* For cPad */
+#define SYNUSB_COMBO			(1 << 4) /* Composite device (TP + stick) */
+#define SYNUSB_IO_ALWAYS		(1 << 5)
+
+#define USB_DEVICE_SYNAPTICS(prod, kind)		\
+	USB_DEVICE(USB_VENDOR_ID_SYNAPTICS,		\
+		   USB_DEVICE_ID_SYNAPTICS_##prod),	\
+	.driver_info = (kind),
+
+#define SYNUSB_RECV_SIZE	8
+
+#define XMIN_NOMINAL		1472
+#define XMAX_NOMINAL		5472
+#define YMIN_NOMINAL		1408
+#define YMAX_NOMINAL		4448
+
+struct synusb {
+	struct usb_device *udev;
+	struct usb_interface *intf;
+	struct urb *urb;
+	unsigned char *data;
+
+	/* input device related data structures */
+	struct input_dev *input;
+	char name[128];
+	char phys[64];
+
+	/* characteristics of the device */
+	unsigned long flags;
+};
+
+static void synusb_report_buttons(struct synusb *synusb)
+{
+	struct input_dev *input_dev = synusb->input;
+
+	input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04);
+	input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01);
+	input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02);
+}
+
+static void synusb_report_stick(struct synusb *synusb)
+{
+	struct input_dev *input_dev = synusb->input;
+	int x, y;
+	unsigned int pressure;
+
+	pressure = synusb->data[6];
+	x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7;
+	y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7;
+
+	if (pressure > 0) {
+		input_report_rel(input_dev, REL_X, x);
+		input_report_rel(input_dev, REL_Y, -y);
+	}
+
+	input_report_abs(input_dev, ABS_PRESSURE, pressure);
+
+	synusb_report_buttons(synusb);
+
+	input_sync(input_dev);
+}
+
+static void synusb_report_touchpad(struct synusb *synusb)
+{
+	struct input_dev *input_dev = synusb->input;
+	unsigned int num_fingers, tool_width;
+	unsigned int x, y;
+	unsigned int pressure, w;
+
+	pressure = synusb->data[6];
+	x = be16_to_cpup((__be16 *)&synusb->data[2]);
+	y = be16_to_cpup((__be16 *)&synusb->data[4]);
+	w = synusb->data[0] & 0x0f;
+
+	if (pressure > 0) {
+		num_fingers = 1;
+		tool_width = 5;
+		switch (w) {
+		case 0 ... 1:
+			num_fingers = 2 + w;
+			break;
+
+		case 2:	                /* pen, pretend its a finger */
+			break;
+
+		case 4 ... 15:
+			tool_width = w;
+			break;
+		}
+	} else {
+		num_fingers = 0;
+		tool_width = 0;
+	}
+
+	/*
+	 * Post events
+	 * BTN_TOUCH has to be first as mousedev relies on it when doing
+	 * absolute -> relative conversion
+	 */
+
+	if (pressure > 30)
+		input_report_key(input_dev, BTN_TOUCH, 1);
+	if (pressure < 25)
+		input_report_key(input_dev, BTN_TOUCH, 0);
+
+	if (num_fingers > 0) {
+		input_report_abs(input_dev, ABS_X, x);
+		input_report_abs(input_dev, ABS_Y,
+				 YMAX_NOMINAL + YMIN_NOMINAL - y);
+	}
+
+	input_report_abs(input_dev, ABS_PRESSURE, pressure);
+	input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width);
+
+	input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1);
+	input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
+	input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
+
+	synusb_report_buttons(synusb);
+	if (synusb->flags & SYNUSB_AUXDISPLAY)
+		input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08);
+
+	input_sync(input_dev);
+}
+
+static void synusb_irq(struct urb *urb)
+{
+	struct synusb *synusb = urb->context;
+	int error;
+
+	/* Check our status in case we need to bail out early. */
+	switch (urb->status) {
+	case 0:
+		usb_mark_last_busy(synusb->udev);
+		break;
+
+	/* Device went away so don't keep trying to read from it. */
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+
+	default:
+		goto resubmit;
+		break;
+	}
+
+	if (synusb->flags & SYNUSB_STICK)
+		synusb_report_stick(synusb);
+	else
+		synusb_report_touchpad(synusb);
+
+resubmit:
+	error = usb_submit_urb(urb, GFP_ATOMIC);
+	if (error && error != -EPERM)
+		dev_err(&synusb->intf->dev,
+			"%s - usb_submit_urb failed with result: %d",
+			__func__, error);
+}
+
+static struct usb_endpoint_descriptor *
+synusb_get_in_endpoint(struct usb_host_interface *iface)
+{
+
+	struct usb_endpoint_descriptor *endpoint;
+	int i;
+
+	for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
+		endpoint = &iface->endpoint[i].desc;
+
+		if (usb_endpoint_is_int_in(endpoint)) {
+			/* we found our interrupt in endpoint */
+			return endpoint;
+		}
+	}
+
+	return NULL;
+}
+
+static int synusb_open(struct input_dev *dev)
+{
+	struct synusb *synusb = input_get_drvdata(dev);
+	int retval;
+
+	retval = usb_autopm_get_interface(synusb->intf);
+	if (retval) {
+		dev_err(&synusb->intf->dev,
+			"%s - usb_autopm_get_interface failed, error: %d\n",
+			__func__, retval);
+		return retval;
+	}
+
+	retval = usb_submit_urb(synusb->urb, GFP_KERNEL);
+	if (retval) {
+		dev_err(&synusb->intf->dev,
+			"%s - usb_submit_urb failed, error: %d\n",
+			__func__, retval);
+		retval = -EIO;
+		goto out;
+	}
+
+	synusb->intf->needs_remote_wakeup = 1;
+
+out:
+	usb_autopm_put_interface(synusb->intf);
+	return retval;
+}
+
+static void synusb_close(struct input_dev *dev)
+{
+	struct synusb *synusb = input_get_drvdata(dev);
+	int autopm_error;
+
+	autopm_error = usb_autopm_get_interface(synusb->intf);
+
+	usb_kill_urb(synusb->urb);
+	synusb->intf->needs_remote_wakeup = 0;
+
+	if (!autopm_error)
+		usb_autopm_put_interface(synusb->intf);
+}
+
+static int synusb_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_endpoint_descriptor *ep;
+	struct synusb *synusb;
+	struct input_dev *input_dev;
+	unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber;
+	unsigned int altsetting = min(intf->num_altsetting, 1U);
+	int error;
+
+	error = usb_set_interface(udev, intf_num, altsetting);
+	if (error) {
+		dev_err(&udev->dev,
+			"Can not set alternate setting to %i, error: %i",
+			altsetting, error);
+		return error;
+	}
+
+	ep = synusb_get_in_endpoint(intf->cur_altsetting);
+	if (!ep)
+		return -ENODEV;
+
+	synusb = kzalloc(sizeof(*synusb), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!synusb || !input_dev) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	synusb->udev = udev;
+	synusb->intf = intf;
+	synusb->input = input_dev;
+
+	synusb->flags = id->driver_info;
+	if (synusb->flags & SYNUSB_COMBO) {
+		/*
+		 * This is a combo device, we need to set proper
+		 * capability, depending on the interface.
+		 */
+		synusb->flags |= intf_num == 1 ?
+					SYNUSB_STICK : SYNUSB_TOUCHPAD;
+	}
+
+	synusb->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!synusb->urb) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL,
+					  &synusb->urb->transfer_dma);
+	if (!synusb->data) {
+		error = -ENOMEM;
+		goto err_free_urb;
+	}
+
+	usb_fill_int_urb(synusb->urb, udev,
+			 usb_rcvintpipe(udev, ep->bEndpointAddress),
+			 synusb->data, SYNUSB_RECV_SIZE,
+			 synusb_irq, synusb,
+			 ep->bInterval);
+	synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	if (udev->manufacturer)
+		strlcpy(synusb->name, udev->manufacturer,
+			sizeof(synusb->name));
+
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(synusb->name, " ", sizeof(synusb->name));
+		strlcat(synusb->name, udev->product, sizeof(synusb->name));
+	}
+
+	if (!strlen(synusb->name))
+		snprintf(synusb->name, sizeof(synusb->name),
+			 "USB Synaptics Device %04x:%04x",
+			 le16_to_cpu(udev->descriptor.idVendor),
+			 le16_to_cpu(udev->descriptor.idProduct));
+
+	if (synusb->flags & SYNUSB_STICK)
+		strlcat(synusb->name, " (Stick) ", sizeof(synusb->name));
+
+	usb_make_path(udev, synusb->phys, sizeof(synusb->phys));
+	strlcat(synusb->phys, "/input0", sizeof(synusb->phys));
+
+	input_dev->name = synusb->name;
+	input_dev->phys = synusb->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->dev.parent = &synusb->intf->dev;
+
+	if (!(synusb->flags & SYNUSB_IO_ALWAYS)) {
+		input_dev->open = synusb_open;
+		input_dev->close = synusb_close;
+	}
+
+	input_set_drvdata(input_dev, synusb);
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(EV_KEY, input_dev->evbit);
+
+	if (synusb->flags & SYNUSB_STICK) {
+		__set_bit(EV_REL, input_dev->evbit);
+		__set_bit(REL_X, input_dev->relbit);
+		__set_bit(REL_Y, input_dev->relbit);
+		input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0);
+	} else {
+		input_set_abs_params(input_dev, ABS_X,
+				     XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
+		input_set_abs_params(input_dev, ABS_Y,
+				     YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
+		input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
+		input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
+		__set_bit(BTN_TOUCH, input_dev->keybit);
+		__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+		__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+		__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+	}
+
+	__set_bit(BTN_LEFT, input_dev->keybit);
+	__set_bit(BTN_RIGHT, input_dev->keybit);
+	__set_bit(BTN_MIDDLE, input_dev->keybit);
+
+	usb_set_intfdata(intf, synusb);
+
+	if (synusb->flags & SYNUSB_IO_ALWAYS) {
+		error = synusb_open(input_dev);
+		if (error)
+			goto err_free_dma;
+	}
+
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(&udev->dev,
+			"Failed to register input device, error %d\n",
+			error);
+		goto err_stop_io;
+	}
+
+	return 0;
+
+err_stop_io:
+	if (synusb->flags & SYNUSB_IO_ALWAYS)
+		synusb_close(synusb->input);
+err_free_dma:
+	usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data,
+			  synusb->urb->transfer_dma);
+err_free_urb:
+	usb_free_urb(synusb->urb);
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(synusb);
+	usb_set_intfdata(intf, NULL);
+
+	return error;
+}
+
+static void synusb_disconnect(struct usb_interface *intf)
+{
+	struct synusb *synusb = usb_get_intfdata(intf);
+	struct usb_device *udev = interface_to_usbdev(intf);
+
+	if (synusb->flags & SYNUSB_IO_ALWAYS)
+		synusb_close(synusb->input);
+
+	input_unregister_device(synusb->input);
+
+	usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data,
+			  synusb->urb->transfer_dma);
+	usb_free_urb(synusb->urb);
+	kfree(synusb);
+
+	usb_set_intfdata(intf, NULL);
+}
+
+static int synusb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct synusb *synusb = usb_get_intfdata(intf);
+	struct input_dev *input_dev = synusb->input;
+
+	mutex_lock(&input_dev->mutex);
+	usb_kill_urb(synusb->urb);
+	mutex_unlock(&input_dev->mutex);
+
+	return 0;
+}
+
+static int synusb_resume(struct usb_interface *intf)
+{
+	struct synusb *synusb = usb_get_intfdata(intf);
+	struct input_dev *input_dev = synusb->input;
+	int retval = 0;
+
+	mutex_lock(&input_dev->mutex);
+
+	if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
+	    usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
+		retval = -EIO;
+	}
+
+	mutex_unlock(&input_dev->mutex);
+
+	return retval;
+}
+
+static int synusb_pre_reset(struct usb_interface *intf)
+{
+	struct synusb *synusb = usb_get_intfdata(intf);
+	struct input_dev *input_dev = synusb->input;
+
+	mutex_lock(&input_dev->mutex);
+	usb_kill_urb(synusb->urb);
+
+	return 0;
+}
+
+static int synusb_post_reset(struct usb_interface *intf)
+{
+	struct synusb *synusb = usb_get_intfdata(intf);
+	struct input_dev *input_dev = synusb->input;
+	int retval = 0;
+
+	if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) &&
+	    usb_submit_urb(synusb->urb, GFP_NOIO) < 0) {
+		retval = -EIO;
+	}
+
+	mutex_unlock(&input_dev->mutex);
+
+	return retval;
+}
+
+static int synusb_reset_resume(struct usb_interface *intf)
+{
+	return synusb_resume(intf);
+}
+
+static struct usb_device_id synusb_idtable[] = {
+	{ USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) },
+	{ USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) },
+	{ USB_DEVICE_SYNAPTICS(CPAD,
+		SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) },
+	{ USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) },
+	{ USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) },
+	{ USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) },
+	{ USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) },
+	{ USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) },
+	{ USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) },
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, synusb_idtable);
+
+static struct usb_driver synusb_driver = {
+	.name		= "synaptics_usb",
+	.probe		= synusb_probe,
+	.disconnect	= synusb_disconnect,
+	.id_table	= synusb_idtable,
+	.suspend	= synusb_suspend,
+	.resume		= synusb_resume,
+	.pre_reset	= synusb_pre_reset,
+	.post_reset	= synusb_post_reset,
+	.reset_resume	= synusb_reset_resume,
+	.supports_autosuspend = 1,
+};
+
+static int __init synusb_init(void)
+{
+	return usb_register(&synusb_driver);
+}
+
+static void __exit synusb_exit(void)
+{
+	usb_deregister(&synusb_driver);
+}
+
+module_init(synusb_init);
+module_exit(synusb_exit);
+
+MODULE_AUTHOR("Rob Miller <rob@inpharmatica.co.uk>, "
+              "Ron Lee <ron@debian.org>, "
+              "Jan Steinhoff <cpad@jan-steinhoff.de>");
+MODULE_DESCRIPTION("Synaptics USB device driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c
index 95280f9..36e799c 100644
--- a/drivers/input/serio/at32psif.c
+++ b/drivers/input/serio/at32psif.c
@@ -98,9 +98,9 @@ struct psif {
 	struct serio		*io;
 	void __iomem		*regs;
 	unsigned int		irq;
-	unsigned int		open;
 	/* Prevent concurrent writes to PSIF THR. */
 	spinlock_t		lock;
+	bool			open;
 };
 
 static irqreturn_t psif_interrupt(int irq, void *_ptr)
@@ -164,7 +164,7 @@ static int psif_open(struct serio *io)
 	psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN));
 	psif_writel(psif, IER, PSIF_BIT(RXRDY));
 
-	psif->open = 1;
+	psif->open = true;
 out:
 	return retval;
 }
@@ -173,7 +173,7 @@ static void psif_close(struct serio *io)
 {
 	struct psif *psif = io->port_data;
 
-	psif->open = 0;
+	psif->open = false;
 
 	psif_writel(psif, IDR, ~0UL);
 	psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS));
@@ -319,9 +319,10 @@ static int __exit psif_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int psif_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int psif_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct psif *psif = platform_get_drvdata(pdev);
 
 	if (psif->open) {
@@ -332,8 +333,9 @@ static int psif_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int psif_resume(struct platform_device *pdev)
+static int psif_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct psif *psif = platform_get_drvdata(pdev);
 
 	if (psif->open) {
@@ -344,19 +346,17 @@ static int psif_resume(struct platform_device *pdev)
 
 	return 0;
 }
-#else
-#define psif_suspend	NULL
-#define psif_resume	NULL
 #endif
 
+static SIMPLE_DEV_PM_OPS(psif_pm_ops, psif_suspend, psif_resume);
+
 static struct platform_driver psif_driver = {
 	.remove		= __exit_p(psif_remove),
 	.driver		= {
 		.name	= "atmel_psif",
 		.owner	= THIS_MODULE,
+		.pm	= &psif_pm_ops,
 	},
-	.suspend	= psif_suspend,
-	.resume		= psif_resume,
 };
 
 static int __init psif_init(void)
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index 5eb84b3..0c0df7f 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -44,26 +44,31 @@
 #include <asm/irq.h>
 #include <asm/q40ints.h>
 
+#define DRV_NAME	"q40kbd"
+
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
 
-static DEFINE_SPINLOCK(q40kbd_lock);
-static struct serio *q40kbd_port;
-static struct platform_device *q40kbd_device;
+struct q40kbd {
+	struct serio *port;
+	spinlock_t lock;
+};
 
 static irqreturn_t q40kbd_interrupt(int irq, void *dev_id)
 {
+	struct q40kbd *q40kbd = dev_id;
 	unsigned long flags;
 
-	spin_lock_irqsave(&q40kbd_lock, flags);
+	spin_lock_irqsave(&q40kbd->lock, flags);
 
 	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
-		serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0);
+		serio_interrupt(q40kbd->port, master_inb(KEYCODE_REG), 0);
 
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
 
-	spin_unlock_irqrestore(&q40kbd_lock, flags);
+	spin_unlock_irqrestore(&q40kbd->lock, flags);
 
 	return IRQ_HANDLED;
 }
@@ -72,17 +77,23 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id)
  * q40kbd_flush() flushes all data that may be in the keyboard buffers
  */
 
-static void q40kbd_flush(void)
+static void q40kbd_flush(struct q40kbd *q40kbd)
 {
 	int maxread = 100;
 	unsigned long flags;
 
-	spin_lock_irqsave(&q40kbd_lock, flags);
+	spin_lock_irqsave(&q40kbd->lock, flags);
 
 	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
 		master_inb(KEYCODE_REG);
 
-	spin_unlock_irqrestore(&q40kbd_lock, flags);
+	spin_unlock_irqrestore(&q40kbd->lock, flags);
+}
+
+static void q40kbd_stop(void)
+{
+	master_outb(0, KEY_IRQ_ENABLE_REG);
+	master_outb(-1, KEYBOARD_UNLOCK_REG);
 }
 
 /*
@@ -92,12 +103,9 @@ static void q40kbd_flush(void)
 
 static int q40kbd_open(struct serio *port)
 {
-	q40kbd_flush();
+	struct q40kbd *q40kbd = port->port_data;
 
-	if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
-		printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
-		return -EBUSY;
-	}
+	q40kbd_flush(q40kbd);
 
 	/* off we go */
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
@@ -108,36 +116,72 @@ static int q40kbd_open(struct serio *port)
 
 static void q40kbd_close(struct serio *port)
 {
-	master_outb(0, KEY_IRQ_ENABLE_REG);
-	master_outb(-1, KEYBOARD_UNLOCK_REG);
-	free_irq(Q40_IRQ_KEYBOARD, NULL);
+	struct q40kbd *q40kbd = port->port_data;
 
-	q40kbd_flush();
+	q40kbd_stop();
+	q40kbd_flush(q40kbd);
 }
 
-static int __devinit q40kbd_probe(struct platform_device *dev)
+static int __devinit q40kbd_probe(struct platform_device *pdev)
 {
-	q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
-	if (!q40kbd_port)
-		return -ENOMEM;
-
-	q40kbd_port->id.type	= SERIO_8042;
-	q40kbd_port->open	= q40kbd_open;
-	q40kbd_port->close	= q40kbd_close;
-	q40kbd_port->dev.parent	= &dev->dev;
-	strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name));
-	strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys));
-
-	serio_register_port(q40kbd_port);
+	struct q40kbd *q40kbd;
+	struct serio *port;
+	int error;
+
+	q40kbd = kzalloc(sizeof(struct q40kbd), GFP_KERNEL);
+	port = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!q40kbd || !port) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	q40kbd->port = port;
+	spin_lock_init(&q40kbd->lock);
+
+	port->id.type = SERIO_8042;
+	port->open = q40kbd_open;
+	port->close = q40kbd_close;
+	port->port_data = q40kbd;
+	port->dev.parent = &pdev->dev;
+	strlcpy(port->name, "Q40 Kbd Port", sizeof(port->name));
+	strlcpy(port->phys, "Q40", sizeof(port->phys));
+
+	q40kbd_stop();
+
+	error = request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0,
+			    DRV_NAME, q40kbd);
+	if (error) {
+		dev_err(&pdev->dev, "Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
+		goto err_free_mem;
+	}
+
+	serio_register_port(q40kbd->port);
+
+	platform_set_drvdata(pdev, q40kbd);
 	printk(KERN_INFO "serio: Q40 kbd registered\n");
 
 	return 0;
+
+err_free_mem:
+	kfree(port);
+	kfree(q40kbd);
+	return error;
 }
 
-static int __devexit q40kbd_remove(struct platform_device *dev)
+static int __devexit q40kbd_remove(struct platform_device *pdev)
 {
-	serio_unregister_port(q40kbd_port);
-
+	struct q40kbd *q40kbd = platform_get_drvdata(pdev);
+
+	/*
+	 * q40kbd_close() will be called as part of unregistering
+	 * and will ensure that IRQ is turned off, so it is safe
+	 * to unregister port first and free IRQ later.
+	 */
+	serio_unregister_port(q40kbd->port);
+	free_irq(Q40_IRQ_KEYBOARD, q40kbd);
+	kfree(q40kbd);
+
+	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
@@ -146,41 +190,16 @@ static struct platform_driver q40kbd_driver = {
 		.name	= "q40kbd",
 		.owner	= THIS_MODULE,
 	},
-	.probe		= q40kbd_probe,
 	.remove		= __devexit_p(q40kbd_remove),
 };
 
 static int __init q40kbd_init(void)
 {
-	int error;
-
-	if (!MACH_IS_Q40)
-		return -ENODEV;
-
-	error = platform_driver_register(&q40kbd_driver);
-	if (error)
-		return error;
-
-	q40kbd_device = platform_device_alloc("q40kbd", -1);
-	if (!q40kbd_device)
-		goto err_unregister_driver;
-
-	error = platform_device_add(q40kbd_device);
-	if (error)
-		goto err_free_device;
-
-	return 0;
-
- err_free_device:
-	platform_device_put(q40kbd_device);
- err_unregister_driver:
-	platform_driver_unregister(&q40kbd_driver);
-	return error;
+	return platform_driver_probe(&q40kbd_driver, q40kbd_probe);
 }
 
 static void __exit q40kbd_exit(void)
 {
-	platform_device_unregister(q40kbd_device);
 	platform_driver_unregister(&q40kbd_driver);
 }
 
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index 44fc8b4..5ebabe3 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -24,6 +24,26 @@
 
 #include <asm/hardware/sa1111.h>
 
+#define PS2CR		0x0000
+#define PS2STAT		0x0004
+#define PS2DATA		0x0008
+#define PS2CLKDIV	0x000c
+#define PS2PRECNT	0x0010
+
+#define PS2CR_ENA	0x08
+#define PS2CR_FKD	0x02
+#define PS2CR_FKC	0x01
+
+#define PS2STAT_STP	0x0100
+#define PS2STAT_TXE	0x0080
+#define PS2STAT_TXB	0x0040
+#define PS2STAT_RXF	0x0020
+#define PS2STAT_RXB	0x0010
+#define PS2STAT_ENA	0x0008
+#define PS2STAT_RXP	0x0004
+#define PS2STAT_KBD	0x0002
+#define PS2STAT_KBC	0x0001
+
 struct ps2if {
 	struct serio		*io;
 	struct sa1111_dev	*dev;
@@ -45,22 +65,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id)
 	struct ps2if *ps2if = dev_id;
 	unsigned int scancode, flag, status;
 
-	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+	status = sa1111_readl(ps2if->base + PS2STAT);
 	while (status & PS2STAT_RXF) {
 		if (status & PS2STAT_STP)
-			sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT);
+			sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT);
 
 		flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) |
 		       (status & PS2STAT_RXP ? 0 : SERIO_PARITY);
 
-		scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff;
+		scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff;
 
 		if (hweight8(scancode) & 1)
 			flag ^= SERIO_PARITY;
 
 		serio_interrupt(ps2if->io, scancode, flag);
 
-		status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+		status = sa1111_readl(ps2if->base + PS2STAT);
         }
 
         return IRQ_HANDLED;
@@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id)
 	unsigned int status;
 
 	spin_lock(&ps2if->lock);
-	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+	status = sa1111_readl(ps2if->base + PS2STAT);
 	if (ps2if->head == ps2if->tail) {
 		disable_irq_nosync(irq);
 		/* done */
 	} else if (status & PS2STAT_TXE) {
-		sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA);
+		sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA);
 		ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1);
 	}
 	spin_unlock(&ps2if->lock);
@@ -103,8 +123,8 @@ static int ps2_write(struct serio *io, unsigned char val)
 	/*
 	 * If the TX register is empty, we can go straight out.
 	 */
-	if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) {
-		sa1111_writel(val, ps2if->base + SA1111_PS2DATA);
+	if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) {
+		sa1111_writel(val, ps2if->base + PS2DATA);
 	} else {
 		if (ps2if->head == ps2if->tail)
 			enable_irq(ps2if->dev->irq[1]);
@@ -124,13 +144,16 @@ static int ps2_open(struct serio *io)
 	struct ps2if *ps2if = io->port_data;
 	int ret;
 
-	sa1111_enable_device(ps2if->dev);
+	ret = sa1111_enable_device(ps2if->dev);
+	if (ret)
+		return ret;
 
 	ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
 			  SA1111_DRIVER_NAME(ps2if->dev), ps2if);
 	if (ret) {
 		printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
 			ps2if->dev->irq[0], ret);
+		sa1111_disable_device(ps2if->dev);
 		return ret;
 	}
 
@@ -140,6 +163,7 @@ static int ps2_open(struct serio *io)
 		printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
 			ps2if->dev->irq[1], ret);
 		free_irq(ps2if->dev->irq[0], ps2if);
+		sa1111_disable_device(ps2if->dev);
 		return ret;
 	}
 
@@ -147,7 +171,7 @@ static int ps2_open(struct serio *io)
 
 	enable_irq_wake(ps2if->dev->irq[0]);
 
-	sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR);
+	sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR);
 	return 0;
 }
 
@@ -155,7 +179,7 @@ static void ps2_close(struct serio *io)
 {
 	struct ps2if *ps2if = io->port_data;
 
-	sa1111_writel(0, ps2if->base + SA1111_PS2CR);
+	sa1111_writel(0, ps2if->base + PS2CR);
 
 	disable_irq_wake(ps2if->dev->irq[0]);
 
@@ -175,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if)
 	int maxread = 100;
 
 	while (maxread--) {
-		if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff)
+		if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff)
 			break;
 	}
 }
@@ -185,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if,
 {
 	unsigned int val;
 
-	sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR);
+	sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR);
 
 	udelay(2);
 
-	val = sa1111_readl(ps2if->base + SA1111_PS2STAT);
+	val = sa1111_readl(ps2if->base + PS2STAT);
 	return val & (PS2STAT_KBC | PS2STAT_KBD);
 }
 
@@ -220,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if)
 		ret = -ENODEV;
 	}
 
-	sa1111_writel(0, ps2if->base + SA1111_PS2CR);
+	sa1111_writel(0, ps2if->base + PS2CR);
 
 	return ret;
 }
@@ -274,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev)
 	sa1111_enable_device(ps2if->dev);
 
 	/* Incoming clock is 8MHz */
-	sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV);
-	sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT);
+	sa1111_writel(0, ps2if->base + PS2CLKDIV);
+	sa1111_writel(127, ps2if->base + PS2PRECNT);
 
 	/*
 	 * Flush any pending input.
@@ -330,6 +354,7 @@ static int __devexit ps2_remove(struct sa1111_dev *dev)
 static struct sa1111_driver ps2_driver = {
 	.drv = {
 		.name	= "sa1111-ps2",
+		.owner	= THIS_MODULE,
 	},
 	.devid		= SA1111_DEVID_PS2,
 	.probe		= ps2_probe,
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index ba70058..d0f7533 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -441,7 +441,6 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *
 	} else if ((drv = driver_find(buf, &serio_bus)) != NULL) {
 		serio_disconnect_port(serio);
 		error = serio_bind_driver(serio, to_serio_driver(drv));
-		put_driver(drv);
 		serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT);
 	} else {
 		error = -EINVAL;
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 2a97b7e..39205ed 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -176,7 +176,7 @@ static int wacom_parse_logical_collection(unsigned char *report,
 
 		/* Logical collection is only used by 3rd gen Bamboo Touch */
 		features->pktlen = WACOM_PKGLEN_BBTOUCH3;
-		features->device_type = BTN_TOOL_DOUBLETAP;
+		features->device_type = BTN_TOOL_FINGER;
 
 		/*
 		 * Stylus and Touch have same active area
@@ -286,12 +286,10 @@ static int wacom_parse_hid(struct usb_interface *intf,
 						if (features->type == TABLETPC2FG) {
 							/* need to reset back */
 							features->pktlen = WACOM_PKGLEN_TPC2FG;
-							features->device_type = BTN_TOOL_DOUBLETAP;
 						}
 						if (features->type == BAMBOO_PT) {
 							/* need to reset back */
 							features->pktlen = WACOM_PKGLEN_BBTOUCH;
-							features->device_type = BTN_TOOL_DOUBLETAP;
 							features->x_phy =
 								get_unaligned_le16(&report[i + 5]);
 							features->x_max =
@@ -325,7 +323,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
 						if (features->type == TABLETPC2FG) {
 							/* need to reset back */
 							features->pktlen = WACOM_PKGLEN_TPC2FG;
-							features->device_type = BTN_TOOL_DOUBLETAP;
 							features->y_max =
 								get_unaligned_le16(&report[i + 3]);
 							features->y_phy =
@@ -334,7 +331,6 @@ static int wacom_parse_hid(struct usb_interface *intf,
 						} else if (features->type == BAMBOO_PT) {
 							/* need to reset back */
 							features->pktlen = WACOM_PKGLEN_BBTOUCH;
-							features->device_type = BTN_TOOL_DOUBLETAP;
 							features->y_phy =
 								get_unaligned_le16(&report[i + 3]);
 							features->y_max =
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 88672ec..07a1f21 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -832,12 +832,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
 
 	dbg("wacom_tpc_irq: received report #%d", data[0]);
 
-	if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG)
-		return wacom_tpc_single_touch(wacom, len);
-	else if (data[0] == WACOM_REPORT_TPC2FG)
-		return wacom_tpc_mt_touch(wacom);
-	else if (data[0] == WACOM_REPORT_PENABLED)
-		return wacom_tpc_pen(wacom);
+	switch (len) {
+	case WACOM_PKGLEN_TPC1FG:
+		 return wacom_tpc_single_touch(wacom, len);
+
+	case WACOM_PKGLEN_TPC2FG:
+ 		return wacom_tpc_mt_touch(wacom);
+
+	default:
+		switch (data[0]) {
+		case WACOM_REPORT_TPC1FG:
+		case WACOM_REPORT_TPCHID:
+		case WACOM_REPORT_TPCST:
+			return wacom_tpc_single_touch(wacom, len);
+
+		case WACOM_REPORT_PENABLED:
+			return wacom_tpc_pen(wacom);
+		}
+	}
 
 	return 0;
 }
@@ -1317,7 +1329,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
 		break;
 
 	case TABLETPC2FG:
-		if (features->device_type == BTN_TOOL_DOUBLETAP) {
+		if (features->device_type == BTN_TOOL_FINGER) {
 
 			input_mt_init_slots(input_dev, 2);
 			input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
@@ -1366,7 +1378,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
 
 		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
 
-		if (features->device_type == BTN_TOOL_DOUBLETAP) {
+		if (features->device_type == BTN_TOOL_FINGER) {
 			__set_bit(BTN_LEFT, input_dev->keybit);
 			__set_bit(BTN_FORWARD, input_dev->keybit);
 			__set_bit(BTN_BACK, input_dev->keybit);
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
index 050acae..4f0ba21 100644
--- a/drivers/input/tablet/wacom_wac.h
+++ b/drivers/input/tablet/wacom_wac.h
@@ -39,6 +39,8 @@
 #define WACOM_REPORT_INTUOSPAD		12
 #define WACOM_REPORT_TPC1FG		6
 #define WACOM_REPORT_TPC2FG		13
+#define WACOM_REPORT_TPCHID		15
+#define WACOM_REPORT_TPCST		16
 
 /* device quirks */
 #define WACOM_QUIRK_MULTI_INPUT		0x0001
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 4af2a18..2b21a70 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -139,7 +139,6 @@ config TOUCHSCREEN_CY8CTMG110
 	tristate "cy8ctmg110 touchscreen"
 	depends on I2C
 	depends on GPIOLIB
-
 	help
 	  Say Y here if you have a cy8ctmg110 capacitive touchscreen on
 	  an AAVA device.
@@ -149,6 +148,37 @@ config TOUCHSCREEN_CY8CTMG110
 	  To compile this driver as a module, choose M here: the
 	  module will be called cy8ctmg110_ts.
 
+config TOUCHSCREEN_CYTTSP_CORE
+	tristate "Cypress TTSP touchscreen"
+	help
+	  Say Y here if you have a touchscreen using controller from
+	  the Cypress TrueTouch(tm) Standard Product family connected
+	  to your system. You will also need to select appropriate
+	  bus connection below.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cyttsp_core.
+
+config TOUCHSCREEN_CYTTSP_I2C
+	tristate "support I2C bus connection"
+	depends on TOUCHSCREEN_CYTTSP_CORE && I2C
+	help
+	  Say Y here if the touchscreen is connected via I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cyttsp_i2c.
+
+config TOUCHSCREEN_CYTTSP_SPI
+	tristate "support SPI bus connection"
+	depends on TOUCHSCREEN_CYTTSP_CORE && SPI_MASTER
+	help
+	  Say Y here if the touchscreen is connected via SPI bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cyttsp_spi.
+
 config TOUCHSCREEN_DA9034
 	tristate "Touchscreen support for Dialog Semiconductor DA9034"
 	depends on PMIC_DA903X
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 496091e..d9acbdc 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -16,8 +16,11 @@ obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT)	+= atmel_mxt_ts.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)	+= atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)	+= auo-pixcir-ts.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)		+= h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_BU21013)       += bu21013_ts.o
+obj-$(CONFIG_TOUCHSCREEN_BU21013)	+= bu21013_ts.o
 obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110)	+= cy8ctmg110_ts.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE)	+= cyttsp_core.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C)	+= cyttsp_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI)	+= cyttsp_spi.o
 obj-$(CONFIG_TOUCHSCREEN_DA9034)	+= da9034-ts.o
 obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)	+= dynapro.o
 obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE)	+= hampshire.o
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c
new file mode 100644
index 0000000..8be2247
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp_core.c
@@ -0,0 +1,625 @@
+/*
+ * Core Source for:
+ * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers.
+ * For use with Cypress Txx3xx parts.
+ * Supported parts include:
+ * CY8CTST341
+ * CY8CTMA340
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#include "cyttsp_core.h"
+
+/* Bootloader number of command keys */
+#define CY_NUM_BL_KEYS		8
+
+/* helpers */
+#define GET_NUM_TOUCHES(x)		((x) & 0x0F)
+#define IS_LARGE_AREA(x)		(((x) & 0x10) >> 4)
+#define IS_BAD_PKT(x)			((x) & 0x20)
+#define IS_VALID_APP(x)			((x) & 0x01)
+#define IS_OPERATIONAL_ERR(x)		((x) & 0x3F)
+#define GET_HSTMODE(reg)		(((reg) & 0x70) >> 4)
+#define GET_BOOTLOADERMODE(reg)		(((reg) & 0x10) >> 4)
+
+#define CY_REG_BASE			0x00
+#define CY_REG_ACT_DIST			0x1E
+#define CY_REG_ACT_INTRVL		0x1D
+#define CY_REG_TCH_TMOUT		(CY_REG_ACT_INTRVL + 1)
+#define CY_REG_LP_INTRVL		(CY_REG_TCH_TMOUT + 1)
+#define CY_MAXZ				255
+#define CY_DELAY_DFLT			20 /* ms */
+#define CY_DELAY_MAX			500
+#define CY_ACT_DIST_DFLT		0xF8
+#define CY_HNDSHK_BIT			0x80
+/* device mode bits */
+#define CY_OPERATE_MODE			0x00
+#define CY_SYSINFO_MODE			0x10
+/* power mode select bits */
+#define CY_SOFT_RESET_MODE		0x01 /* return to Bootloader mode */
+#define CY_DEEP_SLEEP_MODE		0x02
+#define CY_LOW_POWER_MODE		0x04
+
+/* Slots management */
+#define CY_MAX_FINGER			4
+#define CY_MAX_ID			16
+
+static const u8 bl_command[] = {
+	0x00,			/* file offset */
+	0xFF,			/* command */
+	0xA5,			/* exit bootloader command */
+	0, 1, 2, 3, 4, 5, 6, 7	/* default keys */
+};
+
+static int ttsp_read_block_data(struct cyttsp *ts, u8 command,
+				u8 length, void *buf)
+{
+	int error;
+	int tries;
+
+	for (tries = 0; tries < CY_NUM_RETRY; tries++) {
+		error = ts->bus_ops->read(ts, command, length, buf);
+		if (!error)
+			return 0;
+
+		msleep(CY_DELAY_DFLT);
+	}
+
+	return -EIO;
+}
+
+static int ttsp_write_block_data(struct cyttsp *ts, u8 command,
+				 u8 length, void *buf)
+{
+	int error;
+	int tries;
+
+	for (tries = 0; tries < CY_NUM_RETRY; tries++) {
+		error = ts->bus_ops->write(ts, command, length, buf);
+		if (!error)
+			return 0;
+
+		msleep(CY_DELAY_DFLT);
+	}
+
+	return -EIO;
+}
+
+static int ttsp_send_command(struct cyttsp *ts, u8 cmd)
+{
+	return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd);
+}
+
+static int cyttsp_load_bl_regs(struct cyttsp *ts)
+{
+	memset(&ts->bl_data, 0, sizeof(ts->bl_data));
+	ts->bl_data.bl_status = 0x10;
+
+	return ttsp_read_block_data(ts, CY_REG_BASE,
+				    sizeof(ts->bl_data), &ts->bl_data);
+}
+
+static int cyttsp_exit_bl_mode(struct cyttsp *ts)
+{
+	int error;
+	u8 bl_cmd[sizeof(bl_command)];
+
+	memcpy(bl_cmd, bl_command, sizeof(bl_command));
+	if (ts->pdata->bl_keys)
+		memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS],
+			ts->pdata->bl_keys, sizeof(bl_command));
+
+	error = ttsp_write_block_data(ts, CY_REG_BASE,
+				      sizeof(bl_cmd), bl_cmd);
+	if (error)
+		return error;
+
+	/* wait for TTSP Device to complete the operation */
+	msleep(CY_DELAY_DFLT);
+
+	error = cyttsp_load_bl_regs(ts);
+	if (error)
+		return error;
+
+	if (GET_BOOTLOADERMODE(ts->bl_data.bl_status))
+		return -EIO;
+
+	return 0;
+}
+
+static int cyttsp_set_operational_mode(struct cyttsp *ts)
+{
+	int error;
+
+	error = ttsp_send_command(ts, CY_OPERATE_MODE);
+	if (error)
+		return error;
+
+	/* wait for TTSP Device to complete switch to Operational mode */
+	error = ttsp_read_block_data(ts, CY_REG_BASE,
+				     sizeof(ts->xy_data), &ts->xy_data);
+	if (error)
+		return error;
+
+	return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0;
+}
+
+static int cyttsp_set_sysinfo_mode(struct cyttsp *ts)
+{
+	int error;
+
+	memset(&ts->sysinfo_data, 0, sizeof(ts->sysinfo_data));
+
+	/* switch to sysinfo mode */
+	error = ttsp_send_command(ts, CY_SYSINFO_MODE);
+	if (error)
+		return error;
+
+	/* read sysinfo registers */
+	msleep(CY_DELAY_DFLT);
+	error = ttsp_read_block_data(ts, CY_REG_BASE, sizeof(ts->sysinfo_data),
+				      &ts->sysinfo_data);
+	if (error)
+		return error;
+
+	if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl)
+		return -EIO;
+
+	return 0;
+}
+
+static int cyttsp_set_sysinfo_regs(struct cyttsp *ts)
+{
+	int retval = 0;
+
+	if (ts->pdata->act_intrvl != CY_ACT_INTRVL_DFLT ||
+	    ts->pdata->tch_tmout != CY_TCH_TMOUT_DFLT ||
+	    ts->pdata->lp_intrvl != CY_LP_INTRVL_DFLT) {
+
+		u8 intrvl_ray[] = {
+			ts->pdata->act_intrvl,
+			ts->pdata->tch_tmout,
+			ts->pdata->lp_intrvl
+		};
+
+		/* set intrvl registers */
+		retval = ttsp_write_block_data(ts, CY_REG_ACT_INTRVL,
+					sizeof(intrvl_ray), intrvl_ray);
+		msleep(CY_DELAY_DFLT);
+	}
+
+	return retval;
+}
+
+static int cyttsp_soft_reset(struct cyttsp *ts)
+{
+	unsigned long timeout;
+	int retval;
+
+	/* wait for interrupt to set ready completion */
+	INIT_COMPLETION(ts->bl_ready);
+	ts->state = CY_BL_STATE;
+
+	enable_irq(ts->irq);
+
+	retval = ttsp_send_command(ts, CY_SOFT_RESET_MODE);
+	if (retval)
+		goto out;
+
+	timeout = wait_for_completion_timeout(&ts->bl_ready,
+			msecs_to_jiffies(CY_DELAY_DFLT * CY_DELAY_MAX));
+	retval = timeout ? 0 : -EIO;
+
+out:
+	ts->state = CY_IDLE_STATE;
+	disable_irq(ts->irq);
+	return retval;
+}
+
+static int cyttsp_act_dist_setup(struct cyttsp *ts)
+{
+	u8 act_dist_setup = ts->pdata->act_dist;
+
+	/* Init gesture; active distance setup */
+	return ttsp_write_block_data(ts, CY_REG_ACT_DIST,
+				sizeof(act_dist_setup), &act_dist_setup);
+}
+
+static void cyttsp_extract_track_ids(struct cyttsp_xydata *xy_data, int *ids)
+{
+	ids[0] = xy_data->touch12_id >> 4;
+	ids[1] = xy_data->touch12_id & 0xF;
+	ids[2] = xy_data->touch34_id >> 4;
+	ids[3] = xy_data->touch34_id & 0xF;
+}
+
+static const struct cyttsp_tch *cyttsp_get_tch(struct cyttsp_xydata *xy_data,
+					       int idx)
+{
+	switch (idx) {
+	case 0:
+		return &xy_data->tch1;
+	case 1:
+		return &xy_data->tch2;
+	case 2:
+		return &xy_data->tch3;
+	case 3:
+		return &xy_data->tch4;
+	default:
+		return NULL;
+	}
+}
+
+static void cyttsp_report_tchdata(struct cyttsp *ts)
+{
+	struct cyttsp_xydata *xy_data = &ts->xy_data;
+	struct input_dev *input = ts->input;
+	int num_tch = GET_NUM_TOUCHES(xy_data->tt_stat);
+	const struct cyttsp_tch *tch;
+	int ids[CY_MAX_ID];
+	int i;
+	DECLARE_BITMAP(used, CY_MAX_ID);
+
+	if (IS_LARGE_AREA(xy_data->tt_stat) == 1) {
+		/* terminate all active tracks */
+		num_tch = 0;
+		dev_dbg(ts->dev, "%s: Large area detected\n", __func__);
+	} else if (num_tch > CY_MAX_FINGER) {
+		/* terminate all active tracks */
+		num_tch = 0;
+		dev_dbg(ts->dev, "%s: Num touch error detected\n", __func__);
+	} else if (IS_BAD_PKT(xy_data->tt_mode)) {
+		/* terminate all active tracks */
+		num_tch = 0;
+		dev_dbg(ts->dev, "%s: Invalid buffer detected\n", __func__);
+	}
+
+	cyttsp_extract_track_ids(xy_data, ids);
+
+	bitmap_zero(used, CY_MAX_ID);
+
+	for (i = 0; i < num_tch; i++) {
+		tch = cyttsp_get_tch(xy_data, i);
+
+		input_mt_slot(input, ids[i]);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+		input_report_abs(input, ABS_MT_POSITION_X, be16_to_cpu(tch->x));
+		input_report_abs(input, ABS_MT_POSITION_Y, be16_to_cpu(tch->y));
+		input_report_abs(input, ABS_MT_TOUCH_MAJOR, tch->z);
+
+		__set_bit(ids[i], used);
+	}
+
+	for (i = 0; i < CY_MAX_ID; i++) {
+		if (test_bit(i, used))
+			continue;
+
+		input_mt_slot(input, i);
+		input_mt_report_slot_state(input, MT_TOOL_FINGER, false);
+	}
+
+	input_sync(input);
+}
+
+static irqreturn_t cyttsp_irq(int irq, void *handle)
+{
+	struct cyttsp *ts = handle;
+	int error;
+
+	if (unlikely(ts->state == CY_BL_STATE)) {
+		complete(&ts->bl_ready);
+		goto out;
+	}
+
+	/* Get touch data from CYTTSP device */
+	error = ttsp_read_block_data(ts, CY_REG_BASE,
+				 sizeof(struct cyttsp_xydata), &ts->xy_data);
+	if (error)
+		goto out;
+
+	/* provide flow control handshake */
+	if (ts->pdata->use_hndshk) {
+		error = ttsp_send_command(ts,
+				ts->xy_data.hst_mode ^ CY_HNDSHK_BIT);
+		if (error)
+			goto out;
+	}
+
+	if (unlikely(ts->state == CY_IDLE_STATE))
+		goto out;
+
+	if (GET_BOOTLOADERMODE(ts->xy_data.tt_mode)) {
+		/*
+		 * TTSP device has reset back to bootloader mode.
+		 * Restore to operational mode.
+		 */
+		error = cyttsp_exit_bl_mode(ts);
+		if (error) {
+			dev_err(ts->dev,
+				"Could not return to operational mode, err: %d\n",
+				error);
+			ts->state = CY_IDLE_STATE;
+		}
+	} else {
+		cyttsp_report_tchdata(ts);
+	}
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int cyttsp_power_on(struct cyttsp *ts)
+{
+	int error;
+
+	error = cyttsp_soft_reset(ts);
+	if (error)
+		return error;
+
+	error = cyttsp_load_bl_regs(ts);
+	if (error)
+		return error;
+
+	if (GET_BOOTLOADERMODE(ts->bl_data.bl_status) &&
+	    IS_VALID_APP(ts->bl_data.bl_status)) {
+		error = cyttsp_exit_bl_mode(ts);
+		if (error)
+			return error;
+	}
+
+	if (GET_HSTMODE(ts->bl_data.bl_file) != CY_OPERATE_MODE ||
+	    IS_OPERATIONAL_ERR(ts->bl_data.bl_status)) {
+		return -ENODEV;
+	}
+
+	error = cyttsp_set_sysinfo_mode(ts);
+	if (error)
+		return error;
+
+	error = cyttsp_set_sysinfo_regs(ts);
+	if (error)
+		return error;
+
+	error = cyttsp_set_operational_mode(ts);
+	if (error)
+		return error;
+
+	/* init active distance */
+	error = cyttsp_act_dist_setup(ts);
+	if (error)
+		return error;
+
+	ts->state = CY_ACTIVE_STATE;
+
+	return 0;
+}
+
+static int cyttsp_enable(struct cyttsp *ts)
+{
+	int error;
+
+	/*
+	 * The device firmware can wake on an I2C or SPI memory slave
+	 * address match. So just reading a register is sufficient to
+	 * wake up the device. The first read attempt will fail but it
+	 * will wake it up making the second read attempt successful.
+	 */
+	error = ttsp_read_block_data(ts, CY_REG_BASE,
+				     sizeof(ts->xy_data), &ts->xy_data);
+	if (error)
+		return error;
+
+	if (GET_HSTMODE(ts->xy_data.hst_mode))
+		return -EIO;
+
+	enable_irq(ts->irq);
+
+	return 0;
+}
+
+static int cyttsp_disable(struct cyttsp *ts)
+{
+	int error;
+
+	error = ttsp_send_command(ts, CY_LOW_POWER_MODE);
+	if (error)
+		return error;
+
+	disable_irq(ts->irq);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int cyttsp_suspend(struct device *dev)
+{
+	struct cyttsp *ts = dev_get_drvdata(dev);
+	int retval = 0;
+
+	mutex_lock(&ts->input->mutex);
+
+	if (ts->input->users) {
+		retval = cyttsp_disable(ts);
+		if (retval == 0)
+			ts->suspended = true;
+	}
+
+	mutex_unlock(&ts->input->mutex);
+
+	return retval;
+}
+
+static int cyttsp_resume(struct device *dev)
+{
+	struct cyttsp *ts = dev_get_drvdata(dev);
+
+	mutex_lock(&ts->input->mutex);
+
+	if (ts->input->users)
+		cyttsp_enable(ts);
+
+	ts->suspended = false;
+
+	mutex_unlock(&ts->input->mutex);
+
+	return 0;
+}
+
+#endif
+
+SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume);
+EXPORT_SYMBOL_GPL(cyttsp_pm_ops);
+
+static int cyttsp_open(struct input_dev *dev)
+{
+	struct cyttsp *ts = input_get_drvdata(dev);
+	int retval = 0;
+
+	if (!ts->suspended)
+		retval = cyttsp_enable(ts);
+
+	return retval;
+}
+
+static void cyttsp_close(struct input_dev *dev)
+{
+	struct cyttsp *ts = input_get_drvdata(dev);
+
+	if (!ts->suspended)
+		cyttsp_disable(ts);
+}
+
+struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
+			    struct device *dev, int irq, size_t xfer_buf_size)
+{
+	const struct cyttsp_platform_data *pdata = dev->platform_data;
+	struct cyttsp *ts;
+	struct input_dev *input_dev;
+	int error;
+
+	if (!dev || !bus_ops || !pdata || !pdata->name || irq <= 0) {
+		error = -EINVAL;
+		goto err_out;
+	}
+
+	ts = kzalloc(sizeof(*ts) + xfer_buf_size, GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ts || !input_dev) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	ts->dev = dev;
+	ts->input = input_dev;
+	ts->pdata = dev->platform_data;
+	ts->bus_ops = bus_ops;
+	ts->irq = irq;
+
+	init_completion(&ts->bl_ready);
+	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
+
+	if (pdata->init) {
+		error = pdata->init();
+		if (error) {
+			dev_err(ts->dev, "platform init failed, err: %d\n",
+				error);
+			goto err_free_mem;
+		}
+	}
+
+	input_dev->name = pdata->name;
+	input_dev->phys = ts->phys;
+	input_dev->id.bustype = bus_ops->bustype;
+	input_dev->dev.parent = ts->dev;
+
+	input_dev->open = cyttsp_open;
+	input_dev->close = cyttsp_close;
+
+	input_set_drvdata(input_dev, ts);
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	input_set_abs_params(input_dev, ABS_MT_POSITION_X,
+			     0, pdata->maxx, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
+			     0, pdata->maxy, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
+			     0, CY_MAXZ, 0, 0);
+
+	input_mt_init_slots(input_dev, CY_MAX_ID);
+
+	error = request_threaded_irq(ts->irq, NULL, cyttsp_irq,
+				     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				     pdata->name, ts);
+	if (error) {
+		dev_err(ts->dev, "failed to request IRQ %d, err: %d\n",
+			ts->irq, error);
+		goto err_platform_exit;
+	}
+
+	disable_irq(ts->irq);
+
+	error = cyttsp_power_on(ts);
+	if (error)
+		goto err_free_irq;
+
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(ts->dev, "failed to register input device: %d\n",
+			error);
+		goto err_free_irq;
+	}
+
+	return ts;
+
+err_free_irq:
+	free_irq(ts->irq, ts);
+err_platform_exit:
+	if (pdata->exit)
+		pdata->exit();
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(ts);
+err_out:
+	return ERR_PTR(error);
+}
+EXPORT_SYMBOL_GPL(cyttsp_probe);
+
+void cyttsp_remove(struct cyttsp *ts)
+{
+	free_irq(ts->irq, ts);
+	input_unregister_device(ts->input);
+	if (ts->pdata->exit)
+		ts->pdata->exit();
+	kfree(ts);
+}
+EXPORT_SYMBOL_GPL(cyttsp_remove);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard touchscreen driver core");
+MODULE_AUTHOR("Cypress");
diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h
new file mode 100644
index 0000000..1aa3c69
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp_core.h
@@ -0,0 +1,149 @@
+/*
+ * Header file for:
+ * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers.
+ * For use with Cypress Txx3xx parts.
+ * Supported parts include:
+ * CY8CTST341
+ * CY8CTMA340
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
+ *
+ */
+
+
+#ifndef __CYTTSP_CORE_H__
+#define __CYTTSP_CORE_H__
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/input/cyttsp.h>
+
+#define CY_NUM_RETRY		16 /* max number of retries for read ops */
+
+struct cyttsp_tch {
+	__be16 x, y;
+	u8 z;
+} __packed;
+
+/* TrueTouch Standard Product Gen3 interface definition */
+struct cyttsp_xydata {
+	u8 hst_mode;
+	u8 tt_mode;
+	u8 tt_stat;
+	struct cyttsp_tch tch1;
+	u8 touch12_id;
+	struct cyttsp_tch tch2;
+	u8 gest_cnt;
+	u8 gest_id;
+	struct cyttsp_tch tch3;
+	u8 touch34_id;
+	struct cyttsp_tch tch4;
+	u8 tt_undef[3];
+	u8 act_dist;
+	u8 tt_reserved;
+} __packed;
+
+
+/* TTSP System Information interface definition */
+struct cyttsp_sysinfo_data {
+	u8 hst_mode;
+	u8 mfg_cmd;
+	u8 mfg_stat;
+	u8 cid[3];
+	u8 tt_undef1;
+	u8 uid[8];
+	u8 bl_verh;
+	u8 bl_verl;
+	u8 tts_verh;
+	u8 tts_verl;
+	u8 app_idh;
+	u8 app_idl;
+	u8 app_verh;
+	u8 app_verl;
+	u8 tt_undef[5];
+	u8 scn_typ;
+	u8 act_intrvl;
+	u8 tch_tmout;
+	u8 lp_intrvl;
+};
+
+/* TTSP Bootloader Register Map interface definition */
+#define CY_BL_CHKSUM_OK 0x01
+struct cyttsp_bootloader_data {
+	u8 bl_file;
+	u8 bl_status;
+	u8 bl_error;
+	u8 blver_hi;
+	u8 blver_lo;
+	u8 bld_blver_hi;
+	u8 bld_blver_lo;
+	u8 ttspver_hi;
+	u8 ttspver_lo;
+	u8 appid_hi;
+	u8 appid_lo;
+	u8 appver_hi;
+	u8 appver_lo;
+	u8 cid_0;
+	u8 cid_1;
+	u8 cid_2;
+};
+
+struct cyttsp;
+
+struct cyttsp_bus_ops {
+	u16 bustype;
+	int (*write)(struct cyttsp *ts,
+		     u8 addr, u8 length, const void *values);
+	int (*read)(struct cyttsp *ts, u8 addr, u8 length, void *values);
+};
+
+enum cyttsp_state {
+	CY_IDLE_STATE,
+	CY_ACTIVE_STATE,
+	CY_BL_STATE,
+};
+
+struct cyttsp {
+	struct device *dev;
+	int irq;
+	struct input_dev *input;
+	char phys[32];
+	const struct cyttsp_platform_data *pdata;
+	const struct cyttsp_bus_ops *bus_ops;
+	struct cyttsp_bootloader_data bl_data;
+	struct cyttsp_sysinfo_data sysinfo_data;
+	struct cyttsp_xydata xy_data;
+	struct completion bl_ready;
+	enum cyttsp_state state;
+	bool suspended;
+
+	u8 xfer_buf[] ____cacheline_aligned;
+};
+
+struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops,
+			    struct device *dev, int irq, size_t xfer_buf_size);
+void cyttsp_remove(struct cyttsp *ts);
+
+extern const struct dev_pm_ops cyttsp_pm_ops;
+
+#endif /* __CYTTSP_CORE_H__ */
diff --git a/drivers/input/touchscreen/cyttsp_i2c.c b/drivers/input/touchscreen/cyttsp_i2c.c
new file mode 100644
index 0000000..c7110cc
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp_i2c.c
@@ -0,0 +1,146 @@
+/*
+ * Source for:
+ * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver.
+ * For use with Cypress Txx3xx parts.
+ * Supported parts include:
+ * CY8CTST341
+ * CY8CTMA340
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
+ *
+ */
+
+#include "cyttsp_core.h"
+
+#include <linux/i2c.h>
+#include <linux/input.h>
+
+#define CY_I2C_DATA_SIZE	128
+
+static int cyttsp_i2c_read_block_data(struct cyttsp *ts,
+				      u8 addr, u8 length, void *values)
+{
+	struct i2c_client *client = to_i2c_client(ts->dev);
+	struct i2c_msg msgs[] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &addr,
+		},
+		{
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = length,
+			.buf = values,
+		},
+	};
+	int retval;
+
+	retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (retval < 0)
+		return retval;
+
+	return retval != ARRAY_SIZE(msgs) ? -EIO : 0;
+}
+
+static int cyttsp_i2c_write_block_data(struct cyttsp *ts,
+				       u8 addr, u8 length, const void *values)
+{
+	struct i2c_client *client = to_i2c_client(ts->dev);
+	int retval;
+
+	ts->xfer_buf[0] = addr;
+	memcpy(&ts->xfer_buf[1], values, length);
+
+	retval = i2c_master_send(client, ts->xfer_buf, length + 1);
+
+	return retval < 0 ? retval : 0;
+}
+
+static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = {
+	.bustype	= BUS_I2C,
+	.write		= cyttsp_i2c_write_block_data,
+	.read           = cyttsp_i2c_read_block_data,
+};
+
+static int __devinit cyttsp_i2c_probe(struct i2c_client *client,
+				      const struct i2c_device_id *id)
+{
+	struct cyttsp *ts;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "I2C functionality not Supported\n");
+		return -EIO;
+	}
+
+	ts = cyttsp_probe(&cyttsp_i2c_bus_ops, &client->dev, client->irq,
+			  CY_I2C_DATA_SIZE);
+
+	if (IS_ERR(ts))
+		return PTR_ERR(ts);
+
+	i2c_set_clientdata(client, ts);
+
+	return 0;
+}
+
+static int __devexit cyttsp_i2c_remove(struct i2c_client *client)
+{
+	struct cyttsp *ts = i2c_get_clientdata(client);
+
+	cyttsp_remove(ts);
+
+	return 0;
+}
+
+static const struct i2c_device_id cyttsp_i2c_id[] = {
+	{ CY_I2C_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id);
+
+static struct i2c_driver cyttsp_i2c_driver = {
+	.driver = {
+		.name	= CY_I2C_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &cyttsp_pm_ops,
+	},
+	.probe		= cyttsp_i2c_probe,
+	.remove		= __devexit_p(cyttsp_i2c_remove),
+	.id_table	= cyttsp_i2c_id,
+};
+
+static int __init cyttsp_i2c_init(void)
+{
+	return i2c_add_driver(&cyttsp_i2c_driver);
+}
+module_init(cyttsp_i2c_init);
+
+static void __exit cyttsp_i2c_exit(void)
+{
+	return i2c_del_driver(&cyttsp_i2c_driver);
+}
+module_exit(cyttsp_i2c_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver");
+MODULE_AUTHOR("Cypress");
+MODULE_ALIAS("i2c:cyttsp");
diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c
new file mode 100644
index 0000000..9db5f87
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp_spi.c
@@ -0,0 +1,210 @@
+/*
+ * Source for:
+ * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver.
+ * For use with Cypress Txx3xx parts.
+ * Supported parts include:
+ * CY8CTST341
+ * CY8CTMA340
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com <kev@cypress.com>
+ *
+ */
+
+#include "cyttsp_core.h"
+
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+
+#define CY_SPI_WR_OP		0x00 /* r/~w */
+#define CY_SPI_RD_OP		0x01
+#define CY_SPI_CMD_BYTES	4
+#define CY_SPI_SYNC_BYTE	2
+#define CY_SPI_SYNC_ACK1	0x62 /* from protocol v.2 */
+#define CY_SPI_SYNC_ACK2	0x9D /* from protocol v.2 */
+#define CY_SPI_DATA_SIZE	128
+#define CY_SPI_DATA_BUF_SIZE	(CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE)
+#define CY_SPI_BITS_PER_WORD	8
+
+static int cyttsp_spi_xfer(struct cyttsp *ts,
+			   u8 op, u8 reg, u8 *buf, int length)
+{
+	struct spi_device *spi = to_spi_device(ts->dev);
+	struct spi_message msg;
+	struct spi_transfer xfer[2];
+	u8 *wr_buf = &ts->xfer_buf[0];
+	u8 *rd_buf = &ts->xfer_buf[CY_SPI_DATA_BUF_SIZE];
+	int retval;
+	int i;
+
+	if (length > CY_SPI_DATA_SIZE) {
+		dev_err(ts->dev, "%s: length %d is too big.\n",
+			__func__, length);
+		return -EINVAL;
+	}
+
+	memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE);
+	memset(rd_buf, 0, CY_SPI_DATA_BUF_SIZE);
+
+	wr_buf[0] = 0x00; /* header byte 0 */
+	wr_buf[1] = 0xFF; /* header byte 1 */
+	wr_buf[2] = reg;  /* reg index */
+	wr_buf[3] = op;   /* r/~w */
+	if (op == CY_SPI_WR_OP)
+		memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length);
+
+	memset(xfer, 0, sizeof(xfer));
+	spi_message_init(&msg);
+
+	/*
+	  We set both TX and RX buffers because Cypress TTSP
+	  requires full duplex operation.
+	*/
+	xfer[0].tx_buf = wr_buf;
+	xfer[0].rx_buf = rd_buf;
+	switch (op) {
+	case CY_SPI_WR_OP:
+		xfer[0].len = length + CY_SPI_CMD_BYTES;
+		spi_message_add_tail(&xfer[0], &msg);
+		break;
+
+	case CY_SPI_RD_OP:
+		xfer[0].len = CY_SPI_CMD_BYTES;
+		spi_message_add_tail(&xfer[0], &msg);
+
+		xfer[1].rx_buf = buf;
+		xfer[1].len = length;
+		spi_message_add_tail(&xfer[1], &msg);
+		break;
+
+	default:
+		dev_err(ts->dev, "%s: bad operation code=%d\n", __func__, op);
+		return -EINVAL;
+	}
+
+	retval = spi_sync(spi, &msg);
+	if (retval < 0) {
+		dev_dbg(ts->dev, "%s: spi_sync() error %d, len=%d, op=%d\n",
+			__func__, retval, xfer[1].len, op);
+
+		/*
+		 * do not return here since was a bad ACK sequence
+		 * let the following ACK check handle any errors and
+		 * allow silent retries
+		 */
+	}
+
+	if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK1 ||
+	    rd_buf[CY_SPI_SYNC_BYTE + 1] != CY_SPI_SYNC_ACK2) {
+
+		dev_dbg(ts->dev, "%s: operation %d failed\n", __func__, op);
+
+		for (i = 0; i < CY_SPI_CMD_BYTES; i++)
+			dev_dbg(ts->dev, "%s: test rd_buf[%d]:0x%02x\n",
+				__func__, i, rd_buf[i]);
+		for (i = 0; i < length; i++)
+			dev_dbg(ts->dev, "%s: test buf[%d]:0x%02x\n",
+				__func__, i, buf[i]);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int cyttsp_spi_read_block_data(struct cyttsp *ts,
+				      u8 addr, u8 length, void *data)
+{
+	return cyttsp_spi_xfer(ts, CY_SPI_RD_OP, addr, data, length);
+}
+
+static int cyttsp_spi_write_block_data(struct cyttsp *ts,
+				       u8 addr, u8 length, const void *data)
+{
+	return cyttsp_spi_xfer(ts, CY_SPI_WR_OP, addr, (void *)data, length);
+}
+
+static const struct cyttsp_bus_ops cyttsp_spi_bus_ops = {
+	.bustype	= BUS_SPI,
+	.write		= cyttsp_spi_write_block_data,
+	.read		= cyttsp_spi_read_block_data,
+};
+
+static int __devinit cyttsp_spi_probe(struct spi_device *spi)
+{
+	struct cyttsp *ts;
+	int error;
+
+	/* Set up SPI*/
+	spi->bits_per_word = CY_SPI_BITS_PER_WORD;
+	spi->mode = SPI_MODE_0;
+	error = spi_setup(spi);
+	if (error < 0) {
+		dev_err(&spi->dev, "%s: SPI setup error %d\n",
+			__func__, error);
+		return error;
+	}
+
+	ts = cyttsp_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq,
+			  CY_SPI_DATA_BUF_SIZE * 2);
+	if (IS_ERR(ts))
+		return PTR_ERR(ts);
+
+	spi_set_drvdata(spi, ts);
+
+	return 0;
+}
+
+static int __devexit cyttsp_spi_remove(struct spi_device *spi)
+{
+	struct cyttsp *ts = spi_get_drvdata(spi);
+
+	cyttsp_remove(ts);
+
+	return 0;
+}
+
+static struct spi_driver cyttsp_spi_driver = {
+	.driver = {
+		.name	= CY_SPI_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &cyttsp_pm_ops,
+	},
+	.probe  = cyttsp_spi_probe,
+	.remove = __devexit_p(cyttsp_spi_remove),
+};
+
+static int __init cyttsp_spi_init(void)
+{
+	return spi_register_driver(&cyttsp_spi_driver);
+}
+module_init(cyttsp_spi_init);
+
+static void __exit cyttsp_spi_exit(void)
+{
+	spi_unregister_driver(&cyttsp_spi_driver);
+}
+module_exit(cyttsp_spi_exit);
+
+MODULE_ALIAS("spi:cyttsp");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver");
+MODULE_AUTHOR("Cypress");
+MODULE_ALIAS("spi:cyttsp");
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index ede0274..48dc5b0 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -39,6 +39,7 @@ struct mc13783_ts_priv {
 	struct delayed_work work;
 	struct workqueue_struct *workq;
 	unsigned int sample[4];
+	struct mc13xxx_ts_platform_data *touch;
 };
 
 static irqreturn_t mc13783_ts_handler(int irq, void *data)
@@ -125,7 +126,9 @@ static void mc13783_ts_work(struct work_struct *work)
 	unsigned int channel = 12;
 
 	if (mc13xxx_adc_do_conversion(priv->mc13xxx,
-				mode, channel, priv->sample) == 0)
+				mode, channel,
+				priv->touch->ato, priv->touch->atox,
+				priv->sample) == 0)
 		mc13783_ts_report_sample(priv);
 }
 
@@ -179,6 +182,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
 	INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
 	priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
 	priv->idev = idev;
+	priv->touch = dev_get_platdata(&pdev->dev);
+	if (!priv->touch) {
+		dev_err(&pdev->dev, "missing platform data\n");
+		ret = -ENODEV;
+		goto err_free_mem;
+	}
 
 	/*
 	 * We need separate workqueue because mc13783_adc_do_conversion
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 6bea696..3bd9fff 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -142,4 +142,24 @@ config OMAP_IOMMU_DEBUG
 
          Say N unless you know you need this.
 
+config TEGRA_IOMMU_GART
+	bool "Tegra GART IOMMU Support"
+	depends on ARCH_TEGRA_2x_SOC
+	select IOMMU_API
+	help
+	  Enables support for remapping discontiguous physical memory
+	  shared with the operating system into contiguous I/O virtual
+	  space through the GART (Graphics Address Relocation Table)
+	  hardware included on Tegra SoCs.
+
+config TEGRA_IOMMU_SMMU
+	bool "Tegra SMMU IOMMU Support"
+	depends on ARCH_TEGRA_3x_SOC
+	select IOMMU_API
+	help
+	  Enables support for remapping discontiguous physical memory
+	  shared with the operating system into contiguous I/O virtual
+	  space through the SMMU (System Memory Management Unit)
+	  hardware included on Tegra SoCs.
+
 endif # IOMMU_SUPPORT
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 0e36b49..7ad7a3b 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -8,3 +8,5 @@ obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o
 obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
 obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o
+obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
+obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index f75e060..daa333f 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2707,7 +2707,8 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
  * The exported alloc_coherent function for dma_ops.
  */
 static void *alloc_coherent(struct device *dev, size_t size,
-			    dma_addr_t *dma_addr, gfp_t flag)
+			    dma_addr_t *dma_addr, gfp_t flag,
+			    struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	void *virt_addr;
@@ -2765,7 +2766,8 @@ out_free:
  * The exported free_coherent function for dma_ops.
  */
 static void free_coherent(struct device *dev, size_t size,
-			  void *virt_addr, dma_addr_t dma_addr)
+			  void *virt_addr, dma_addr_t dma_addr,
+			  struct dma_attrs *attrs)
 {
 	unsigned long flags;
 	struct protection_domain *domain;
@@ -2846,8 +2848,8 @@ static void prealloc_protection_domains(void)
 }
 
 static struct dma_map_ops amd_iommu_dma_ops = {
-	.alloc_coherent = alloc_coherent,
-	.free_coherent = free_coherent,
+	.alloc = alloc_coherent,
+	.free = free_coherent,
 	.map_page = map_page,
 	.unmap_page = unmap_page,
 	.map_sg = map_sg,
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c9c6053..78befe4 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1241,7 +1241,7 @@ static int iommu_init_domains(struct intel_iommu *iommu)
 	unsigned long nlongs;
 
 	ndomains = cap_ndoms(iommu->cap);
-	pr_debug("IOMMU %d: Number of Domains supportd <%ld>\n", iommu->seq_id,
+	pr_debug("IOMMU %d: Number of Domains supported <%ld>\n", iommu->seq_id,
 			ndomains);
 	nlongs = BITS_TO_LONGS(ndomains);
 
@@ -2938,7 +2938,8 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
 }
 
 static void *intel_alloc_coherent(struct device *hwdev, size_t size,
-				  dma_addr_t *dma_handle, gfp_t flags)
+				  dma_addr_t *dma_handle, gfp_t flags,
+				  struct dma_attrs *attrs)
 {
 	void *vaddr;
 	int order;
@@ -2970,7 +2971,7 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
 }
 
 static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-				dma_addr_t dma_handle)
+				dma_addr_t dma_handle, struct dma_attrs *attrs)
 {
 	int order;
 
@@ -3115,8 +3116,8 @@ static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
 }
 
 struct dma_map_ops intel_dma_ops = {
-	.alloc_coherent = intel_alloc_coherent,
-	.free_coherent = intel_free_coherent,
+	.alloc = intel_alloc_coherent,
+	.free = intel_free_coherent,
 	.map_sg = intel_map_sg,
 	.unmap_sg = intel_unmap_sg,
 	.map_page = intel_map_page,
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
new file mode 100644
index 0000000..b21598f
--- /dev/null
+++ b/drivers/iommu/tegra-gart.c
@@ -0,0 +1,451 @@
+/*
+ * IOMMU API for GART in Tegra20
+ *
+ * Copyright (c) 2010-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define pr_fmt(fmt)	"%s(): " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/iommu.h>
+
+#include <asm/cacheflush.h>
+
+/* bitmap of the page sizes currently supported */
+#define GART_IOMMU_PGSIZES	(SZ_4K)
+
+#define GART_CONFIG		0x24
+#define GART_ENTRY_ADDR		0x28
+#define GART_ENTRY_DATA		0x2c
+#define GART_ENTRY_PHYS_ADDR_VALID	(1 << 31)
+
+#define GART_PAGE_SHIFT		12
+#define GART_PAGE_SIZE		(1 << GART_PAGE_SHIFT)
+#define GART_PAGE_MASK						\
+	(~(GART_PAGE_SIZE - 1) & ~GART_ENTRY_PHYS_ADDR_VALID)
+
+struct gart_client {
+	struct device		*dev;
+	struct list_head	list;
+};
+
+struct gart_device {
+	void __iomem		*regs;
+	u32			*savedata;
+	u32			page_count;	/* total remappable size */
+	dma_addr_t		iovmm_base;	/* offset to vmm_area */
+	spinlock_t		pte_lock;	/* for pagetable */
+	struct list_head	client;
+	spinlock_t		client_lock;	/* for client list */
+	struct device		*dev;
+};
+
+static struct gart_device *gart_handle; /* unique for a system */
+
+#define GART_PTE(_pfn)						\
+	(GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT))
+
+/*
+ * Any interaction between any block on PPSB and a block on APB or AHB
+ * must have these read-back to ensure the APB/AHB bus transaction is
+ * complete before initiating activity on the PPSB block.
+ */
+#define FLUSH_GART_REGS(gart)	((void)readl((gart)->regs + GART_CONFIG))
+
+#define for_each_gart_pte(gart, iova)					\
+	for (iova = gart->iovmm_base;					\
+	     iova < gart->iovmm_base + GART_PAGE_SIZE * gart->page_count; \
+	     iova += GART_PAGE_SIZE)
+
+static inline void gart_set_pte(struct gart_device *gart,
+				unsigned long offs, u32 pte)
+{
+	writel(offs, gart->regs + GART_ENTRY_ADDR);
+	writel(pte, gart->regs + GART_ENTRY_DATA);
+
+	dev_dbg(gart->dev, "%s %08lx:%08x\n",
+		 pte ? "map" : "unmap", offs, pte & GART_PAGE_MASK);
+}
+
+static inline unsigned long gart_read_pte(struct gart_device *gart,
+					  unsigned long offs)
+{
+	unsigned long pte;
+
+	writel(offs, gart->regs + GART_ENTRY_ADDR);
+	pte = readl(gart->regs + GART_ENTRY_DATA);
+
+	return pte;
+}
+
+static void do_gart_setup(struct gart_device *gart, const u32 *data)
+{
+	unsigned long iova;
+
+	for_each_gart_pte(gart, iova)
+		gart_set_pte(gart, iova, data ? *(data++) : 0);
+
+	writel(1, gart->regs + GART_CONFIG);
+	FLUSH_GART_REGS(gart);
+}
+
+#ifdef DEBUG
+static void gart_dump_table(struct gart_device *gart)
+{
+	unsigned long iova;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gart->pte_lock, flags);
+	for_each_gart_pte(gart, iova) {
+		unsigned long pte;
+
+		pte = gart_read_pte(gart, iova);
+
+		dev_dbg(gart->dev, "%s %08lx:%08lx\n",
+			(GART_ENTRY_PHYS_ADDR_VALID & pte) ? "v" : " ",
+			iova, pte & GART_PAGE_MASK);
+	}
+	spin_unlock_irqrestore(&gart->pte_lock, flags);
+}
+#else
+static inline void gart_dump_table(struct gart_device *gart)
+{
+}
+#endif
+
+static inline bool gart_iova_range_valid(struct gart_device *gart,
+					 unsigned long iova, size_t bytes)
+{
+	unsigned long iova_start, iova_end, gart_start, gart_end;
+
+	iova_start = iova;
+	iova_end = iova_start + bytes - 1;
+	gart_start = gart->iovmm_base;
+	gart_end = gart_start + gart->page_count * GART_PAGE_SIZE - 1;
+
+	if (iova_start < gart_start)
+		return false;
+	if (iova_end > gart_end)
+		return false;
+	return true;
+}
+
+static int gart_iommu_attach_dev(struct iommu_domain *domain,
+				 struct device *dev)
+{
+	struct gart_device *gart;
+	struct gart_client *client, *c;
+	int err = 0;
+
+	gart = dev_get_drvdata(dev->parent);
+	if (!gart)
+		return -EINVAL;
+	domain->priv = gart;
+
+	client = devm_kzalloc(gart->dev, sizeof(*c), GFP_KERNEL);
+	if (!client)
+		return -ENOMEM;
+	client->dev = dev;
+
+	spin_lock(&gart->client_lock);
+	list_for_each_entry(c, &gart->client, list) {
+		if (c->dev == dev) {
+			dev_err(gart->dev,
+				"%s is already attached\n", dev_name(dev));
+			err = -EINVAL;
+			goto fail;
+		}
+	}
+	list_add(&client->list, &gart->client);
+	spin_unlock(&gart->client_lock);
+	dev_dbg(gart->dev, "Attached %s\n", dev_name(dev));
+	return 0;
+
+fail:
+	devm_kfree(gart->dev, client);
+	spin_unlock(&gart->client_lock);
+	return err;
+}
+
+static void gart_iommu_detach_dev(struct iommu_domain *domain,
+				  struct device *dev)
+{
+	struct gart_device *gart = domain->priv;
+	struct gart_client *c;
+
+	spin_lock(&gart->client_lock);
+
+	list_for_each_entry(c, &gart->client, list) {
+		if (c->dev == dev) {
+			list_del(&c->list);
+			devm_kfree(gart->dev, c);
+			dev_dbg(gart->dev, "Detached %s\n", dev_name(dev));
+			goto out;
+		}
+	}
+	dev_err(gart->dev, "Couldn't find\n");
+out:
+	spin_unlock(&gart->client_lock);
+}
+
+static int gart_iommu_domain_init(struct iommu_domain *domain)
+{
+	return 0;
+}
+
+static void gart_iommu_domain_destroy(struct iommu_domain *domain)
+{
+	struct gart_device *gart = domain->priv;
+
+	if (!gart)
+		return;
+
+	spin_lock(&gart->client_lock);
+	if (!list_empty(&gart->client)) {
+		struct gart_client *c;
+
+		list_for_each_entry(c, &gart->client, list)
+			gart_iommu_detach_dev(domain, c->dev);
+	}
+	spin_unlock(&gart->client_lock);
+	domain->priv = NULL;
+}
+
+static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova,
+			  phys_addr_t pa, size_t bytes, int prot)
+{
+	struct gart_device *gart = domain->priv;
+	unsigned long flags;
+	unsigned long pfn;
+
+	if (!gart_iova_range_valid(gart, iova, bytes))
+		return -EINVAL;
+
+	spin_lock_irqsave(&gart->pte_lock, flags);
+	pfn = __phys_to_pfn(pa);
+	if (!pfn_valid(pfn)) {
+		dev_err(gart->dev, "Invalid page: %08x\n", pa);
+		spin_lock_irqsave(&gart->pte_lock, flags);
+		return -EINVAL;
+	}
+	gart_set_pte(gart, iova, GART_PTE(pfn));
+	FLUSH_GART_REGS(gart);
+	spin_unlock_irqrestore(&gart->pte_lock, flags);
+	return 0;
+}
+
+static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+			       size_t bytes)
+{
+	struct gart_device *gart = domain->priv;
+	unsigned long flags;
+
+	if (!gart_iova_range_valid(gart, iova, bytes))
+		return 0;
+
+	spin_lock_irqsave(&gart->pte_lock, flags);
+	gart_set_pte(gart, iova, 0);
+	FLUSH_GART_REGS(gart);
+	spin_unlock_irqrestore(&gart->pte_lock, flags);
+	return 0;
+}
+
+static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain,
+					   unsigned long iova)
+{
+	struct gart_device *gart = domain->priv;
+	unsigned long pte;
+	phys_addr_t pa;
+	unsigned long flags;
+
+	if (!gart_iova_range_valid(gart, iova, 0))
+		return -EINVAL;
+
+	spin_lock_irqsave(&gart->pte_lock, flags);
+	pte = gart_read_pte(gart, iova);
+	spin_unlock_irqrestore(&gart->pte_lock, flags);
+
+	pa = (pte & GART_PAGE_MASK);
+	if (!pfn_valid(__phys_to_pfn(pa))) {
+		dev_err(gart->dev, "No entry for %08lx:%08x\n", iova, pa);
+		gart_dump_table(gart);
+		return -EINVAL;
+	}
+	return pa;
+}
+
+static int gart_iommu_domain_has_cap(struct iommu_domain *domain,
+				     unsigned long cap)
+{
+	return 0;
+}
+
+static struct iommu_ops gart_iommu_ops = {
+	.domain_init	= gart_iommu_domain_init,
+	.domain_destroy	= gart_iommu_domain_destroy,
+	.attach_dev	= gart_iommu_attach_dev,
+	.detach_dev	= gart_iommu_detach_dev,
+	.map		= gart_iommu_map,
+	.unmap		= gart_iommu_unmap,
+	.iova_to_phys	= gart_iommu_iova_to_phys,
+	.domain_has_cap	= gart_iommu_domain_has_cap,
+	.pgsize_bitmap	= GART_IOMMU_PGSIZES,
+};
+
+static int tegra_gart_suspend(struct device *dev)
+{
+	struct gart_device *gart = dev_get_drvdata(dev);
+	unsigned long iova;
+	u32 *data = gart->savedata;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gart->pte_lock, flags);
+	for_each_gart_pte(gart, iova)
+		*(data++) = gart_read_pte(gart, iova);
+	spin_unlock_irqrestore(&gart->pte_lock, flags);
+	return 0;
+}
+
+static int tegra_gart_resume(struct device *dev)
+{
+	struct gart_device *gart = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gart->pte_lock, flags);
+	do_gart_setup(gart, gart->savedata);
+	spin_unlock_irqrestore(&gart->pte_lock, flags);
+	return 0;
+}
+
+static int tegra_gart_probe(struct platform_device *pdev)
+{
+	struct gart_device *gart;
+	struct resource *res, *res_remap;
+	void __iomem *gart_regs;
+	int err;
+	struct device *dev = &pdev->dev;
+
+	if (gart_handle)
+		return -EIO;
+
+	BUILD_BUG_ON(PAGE_SHIFT != GART_PAGE_SHIFT);
+
+	/* the GART memory aperture is required */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res || !res_remap) {
+		dev_err(dev, "GART memory aperture expected\n");
+		return -ENXIO;
+	}
+
+	gart = devm_kzalloc(dev, sizeof(*gart), GFP_KERNEL);
+	if (!gart) {
+		dev_err(dev, "failed to allocate gart_device\n");
+		return -ENOMEM;
+	}
+
+	gart_regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (!gart_regs) {
+		dev_err(dev, "failed to remap GART registers\n");
+		err = -ENXIO;
+		goto fail;
+	}
+
+	gart->dev = &pdev->dev;
+	spin_lock_init(&gart->pte_lock);
+	spin_lock_init(&gart->client_lock);
+	INIT_LIST_HEAD(&gart->client);
+	gart->regs = gart_regs;
+	gart->iovmm_base = (dma_addr_t)res_remap->start;
+	gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT);
+
+	gart->savedata = vmalloc(sizeof(u32) * gart->page_count);
+	if (!gart->savedata) {
+		dev_err(dev, "failed to allocate context save area\n");
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	platform_set_drvdata(pdev, gart);
+	do_gart_setup(gart, NULL);
+
+	gart_handle = gart;
+	return 0;
+
+fail:
+	if (gart_regs)
+		devm_iounmap(dev, gart_regs);
+	if (gart && gart->savedata)
+		vfree(gart->savedata);
+	devm_kfree(dev, gart);
+	return err;
+}
+
+static int tegra_gart_remove(struct platform_device *pdev)
+{
+	struct gart_device *gart = platform_get_drvdata(pdev);
+	struct device *dev = gart->dev;
+
+	writel(0, gart->regs + GART_CONFIG);
+	if (gart->savedata)
+		vfree(gart->savedata);
+	if (gart->regs)
+		devm_iounmap(dev, gart->regs);
+	devm_kfree(dev, gart);
+	gart_handle = NULL;
+	return 0;
+}
+
+const struct dev_pm_ops tegra_gart_pm_ops = {
+	.suspend	= tegra_gart_suspend,
+	.resume		= tegra_gart_resume,
+};
+
+static struct platform_driver tegra_gart_driver = {
+	.probe		= tegra_gart_probe,
+	.remove		= tegra_gart_remove,
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "tegra-gart",
+		.pm	= &tegra_gart_pm_ops,
+	},
+};
+
+static int __devinit tegra_gart_init(void)
+{
+	bus_set_iommu(&platform_bus_type, &gart_iommu_ops);
+	return platform_driver_register(&tegra_gart_driver);
+}
+
+static void __exit tegra_gart_exit(void)
+{
+	platform_driver_unregister(&tegra_gart_driver);
+}
+
+subsys_initcall(tegra_gart_init);
+module_exit(tegra_gart_exit);
+
+MODULE_DESCRIPTION("IOMMU API for GART in Tegra20");
+MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
new file mode 100644
index 0000000..eb93c82
--- /dev/null
+++ b/drivers/iommu/tegra-smmu.c
@@ -0,0 +1,1034 @@
+/*
+ * IOMMU API for SMMU in Tegra30
+ *
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define pr_fmt(fmt)	"%s(): " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+#include <linux/iommu.h>
+#include <linux/io.h>
+
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+
+#include <mach/iomap.h>
+#include <mach/smmu.h>
+
+/* bitmap of the page sizes currently supported */
+#define SMMU_IOMMU_PGSIZES	(SZ_4K)
+
+#define SMMU_CONFIG				0x10
+#define SMMU_CONFIG_DISABLE			0
+#define SMMU_CONFIG_ENABLE			1
+
+#define SMMU_TLB_CONFIG				0x14
+#define SMMU_TLB_CONFIG_STATS__MASK		(1 << 31)
+#define SMMU_TLB_CONFIG_STATS__ENABLE		(1 << 31)
+#define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE	(1 << 29)
+#define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE	0x10
+#define SMMU_TLB_CONFIG_RESET_VAL		0x20000010
+
+#define SMMU_PTC_CONFIG				0x18
+#define SMMU_PTC_CONFIG_STATS__MASK		(1 << 31)
+#define SMMU_PTC_CONFIG_STATS__ENABLE		(1 << 31)
+#define SMMU_PTC_CONFIG_CACHE__ENABLE		(1 << 29)
+#define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN	0x3f
+#define SMMU_PTC_CONFIG_RESET_VAL		0x2000003f
+
+#define SMMU_PTB_ASID				0x1c
+#define SMMU_PTB_ASID_CURRENT_SHIFT		0
+
+#define SMMU_PTB_DATA				0x20
+#define SMMU_PTB_DATA_RESET_VAL			0
+#define SMMU_PTB_DATA_ASID_NONSECURE_SHIFT	29
+#define SMMU_PTB_DATA_ASID_WRITABLE_SHIFT	30
+#define SMMU_PTB_DATA_ASID_READABLE_SHIFT	31
+
+#define SMMU_TLB_FLUSH				0x30
+#define SMMU_TLB_FLUSH_VA_MATCH_ALL		0
+#define SMMU_TLB_FLUSH_VA_MATCH_SECTION		2
+#define SMMU_TLB_FLUSH_VA_MATCH_GROUP		3
+#define SMMU_TLB_FLUSH_ASID_SHIFT		29
+#define SMMU_TLB_FLUSH_ASID_MATCH_DISABLE	0
+#define SMMU_TLB_FLUSH_ASID_MATCH_ENABLE	1
+#define SMMU_TLB_FLUSH_ASID_MATCH_SHIFT		31
+
+#define SMMU_PTC_FLUSH				0x34
+#define SMMU_PTC_FLUSH_TYPE_ALL			0
+#define SMMU_PTC_FLUSH_TYPE_ADR			1
+#define SMMU_PTC_FLUSH_ADR_SHIFT		4
+
+#define SMMU_ASID_SECURITY			0x38
+
+#define SMMU_STATS_TLB_HIT_COUNT		0x1f0
+#define SMMU_STATS_TLB_MISS_COUNT		0x1f4
+#define SMMU_STATS_PTC_HIT_COUNT		0x1f8
+#define SMMU_STATS_PTC_MISS_COUNT		0x1fc
+
+#define SMMU_TRANSLATION_ENABLE_0		0x228
+#define SMMU_TRANSLATION_ENABLE_1		0x22c
+#define SMMU_TRANSLATION_ENABLE_2		0x230
+
+#define SMMU_AFI_ASID	0x238   /* PCIE */
+#define SMMU_AVPC_ASID	0x23c   /* AVP */
+#define SMMU_DC_ASID	0x240   /* Display controller */
+#define SMMU_DCB_ASID	0x244   /* Display controller B */
+#define SMMU_EPP_ASID	0x248   /* Encoder pre-processor */
+#define SMMU_G2_ASID	0x24c   /* 2D engine */
+#define SMMU_HC_ASID	0x250   /* Host1x */
+#define SMMU_HDA_ASID	0x254   /* High-def audio */
+#define SMMU_ISP_ASID	0x258   /* Image signal processor */
+#define SMMU_MPE_ASID	0x264   /* MPEG encoder */
+#define SMMU_NV_ASID	0x268   /* (3D) */
+#define SMMU_NV2_ASID	0x26c   /* (3D) */
+#define SMMU_PPCS_ASID	0x270   /* AHB */
+#define SMMU_SATA_ASID	0x278   /* SATA */
+#define SMMU_VDE_ASID	0x27c   /* Video decoder */
+#define SMMU_VI_ASID	0x280   /* Video input */
+
+#define SMMU_PDE_NEXT_SHIFT		28
+
+/* AHB Arbiter Registers */
+#define AHB_XBAR_CTRL				0xe0
+#define AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE	1
+#define AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT	17
+
+#define SMMU_NUM_ASIDS				4
+#define SMMU_TLB_FLUSH_VA_SECTION__MASK		0xffc00000
+#define SMMU_TLB_FLUSH_VA_SECTION__SHIFT	12 /* right shift */
+#define SMMU_TLB_FLUSH_VA_GROUP__MASK		0xffffc000
+#define SMMU_TLB_FLUSH_VA_GROUP__SHIFT		12 /* right shift */
+#define SMMU_TLB_FLUSH_VA(iova, which)	\
+	((((iova) & SMMU_TLB_FLUSH_VA_##which##__MASK) >> \
+		SMMU_TLB_FLUSH_VA_##which##__SHIFT) |	\
+	SMMU_TLB_FLUSH_VA_MATCH_##which)
+#define SMMU_PTB_ASID_CUR(n)	\
+		((n) << SMMU_PTB_ASID_CURRENT_SHIFT)
+#define SMMU_TLB_FLUSH_ASID_MATCH_disable		\
+		(SMMU_TLB_FLUSH_ASID_MATCH_DISABLE <<	\
+			SMMU_TLB_FLUSH_ASID_MATCH_SHIFT)
+#define SMMU_TLB_FLUSH_ASID_MATCH__ENABLE		\
+		(SMMU_TLB_FLUSH_ASID_MATCH_ENABLE <<	\
+			SMMU_TLB_FLUSH_ASID_MATCH_SHIFT)
+
+#define SMMU_PAGE_SHIFT 12
+#define SMMU_PAGE_SIZE	(1 << SMMU_PAGE_SHIFT)
+
+#define SMMU_PDIR_COUNT	1024
+#define SMMU_PDIR_SIZE	(sizeof(unsigned long) * SMMU_PDIR_COUNT)
+#define SMMU_PTBL_COUNT	1024
+#define SMMU_PTBL_SIZE	(sizeof(unsigned long) * SMMU_PTBL_COUNT)
+#define SMMU_PDIR_SHIFT	12
+#define SMMU_PDE_SHIFT	12
+#define SMMU_PTE_SHIFT	12
+#define SMMU_PFN_MASK	0x000fffff
+
+#define SMMU_ADDR_TO_PFN(addr)	((addr) >> 12)
+#define SMMU_ADDR_TO_PDN(addr)	((addr) >> 22)
+#define SMMU_PDN_TO_ADDR(addr)	((pdn) << 22)
+
+#define _READABLE	(1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT)
+#define _WRITABLE	(1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT)
+#define _NONSECURE	(1 << SMMU_PTB_DATA_ASID_NONSECURE_SHIFT)
+#define _PDE_NEXT	(1 << SMMU_PDE_NEXT_SHIFT)
+#define _MASK_ATTR	(_READABLE | _WRITABLE | _NONSECURE)
+
+#define _PDIR_ATTR	(_READABLE | _WRITABLE | _NONSECURE)
+
+#define _PDE_ATTR	(_READABLE | _WRITABLE | _NONSECURE)
+#define _PDE_ATTR_N	(_PDE_ATTR | _PDE_NEXT)
+#define _PDE_VACANT(pdn)	(((pdn) << 10) | _PDE_ATTR)
+
+#define _PTE_ATTR	(_READABLE | _WRITABLE | _NONSECURE)
+#define _PTE_VACANT(addr)	(((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR)
+
+#define SMMU_MK_PDIR(page, attr)	\
+		((page_to_phys(page) >> SMMU_PDIR_SHIFT) | (attr))
+#define SMMU_MK_PDE(page, attr)		\
+		(unsigned long)((page_to_phys(page) >> SMMU_PDE_SHIFT) | (attr))
+#define SMMU_EX_PTBL_PAGE(pde)		\
+		pfn_to_page((unsigned long)(pde) & SMMU_PFN_MASK)
+#define SMMU_PFN_TO_PTE(pfn, attr)	(unsigned long)((pfn) | (attr))
+
+#define SMMU_ASID_ENABLE(asid)	((asid) | (1 << 31))
+#define SMMU_ASID_DISABLE	0
+#define SMMU_ASID_ASID(n)	((n) & ~SMMU_ASID_ENABLE(0))
+
+#define smmu_client_enable_hwgrp(c, m)	smmu_client_set_hwgrp(c, m, 1)
+#define smmu_client_disable_hwgrp(c)	smmu_client_set_hwgrp(c, 0, 0)
+#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1)
+#define __smmu_client_disable_hwgrp(c)	__smmu_client_set_hwgrp(c, 0, 0)
+
+#define HWGRP_INIT(client) [HWGRP_##client] = SMMU_##client##_ASID
+
+static const u32 smmu_hwgrp_asid_reg[] = {
+	HWGRP_INIT(AFI),
+	HWGRP_INIT(AVPC),
+	HWGRP_INIT(DC),
+	HWGRP_INIT(DCB),
+	HWGRP_INIT(EPP),
+	HWGRP_INIT(G2),
+	HWGRP_INIT(HC),
+	HWGRP_INIT(HDA),
+	HWGRP_INIT(ISP),
+	HWGRP_INIT(MPE),
+	HWGRP_INIT(NV),
+	HWGRP_INIT(NV2),
+	HWGRP_INIT(PPCS),
+	HWGRP_INIT(SATA),
+	HWGRP_INIT(VDE),
+	HWGRP_INIT(VI),
+};
+#define HWGRP_ASID_REG(x) (smmu_hwgrp_asid_reg[x])
+
+/*
+ * Per client for address space
+ */
+struct smmu_client {
+	struct device		*dev;
+	struct list_head	list;
+	struct smmu_as		*as;
+	u32			hwgrp;
+};
+
+/*
+ * Per address space
+ */
+struct smmu_as {
+	struct smmu_device	*smmu;	/* back pointer to container */
+	unsigned int		asid;
+	spinlock_t		lock;	/* for pagetable */
+	struct page		*pdir_page;
+	unsigned long		pdir_attr;
+	unsigned long		pde_attr;
+	unsigned long		pte_attr;
+	unsigned int		*pte_count;
+
+	struct list_head	client;
+	spinlock_t		client_lock; /* for client list */
+};
+
+/*
+ * Per SMMU device - IOMMU device
+ */
+struct smmu_device {
+	void __iomem	*regs, *regs_ahbarb;
+	unsigned long	iovmm_base;	/* remappable base address */
+	unsigned long	page_count;	/* total remappable size */
+	spinlock_t	lock;
+	char		*name;
+	struct device	*dev;
+	int		num_as;
+	struct smmu_as	*as;		/* Run-time allocated array */
+	struct page *avp_vector_page;	/* dummy page shared by all AS's */
+
+	/*
+	 * Register image savers for suspend/resume
+	 */
+	unsigned long translation_enable_0;
+	unsigned long translation_enable_1;
+	unsigned long translation_enable_2;
+	unsigned long asid_security;
+};
+
+static struct smmu_device *smmu_handle; /* unique for a system */
+
+/*
+ *	SMMU/AHB register accessors
+ */
+static inline u32 smmu_read(struct smmu_device *smmu, size_t offs)
+{
+	return readl(smmu->regs + offs);
+}
+static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)
+{
+	writel(val, smmu->regs + offs);
+}
+
+static inline u32 ahb_read(struct smmu_device *smmu, size_t offs)
+{
+	return readl(smmu->regs_ahbarb + offs);
+}
+static inline void ahb_write(struct smmu_device *smmu, u32 val, size_t offs)
+{
+	writel(val, smmu->regs_ahbarb + offs);
+}
+
+#define VA_PAGE_TO_PA(va, page)	\
+	(page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK))
+
+#define FLUSH_CPU_DCACHE(va, page, size)	\
+	do {	\
+		unsigned long _pa_ = VA_PAGE_TO_PA(va, page);		\
+		__cpuc_flush_dcache_area((void *)(va), (size_t)(size));	\
+		outer_flush_range(_pa_, _pa_+(size_t)(size));		\
+	} while (0)
+
+/*
+ * Any interaction between any block on PPSB and a block on APB or AHB
+ * must have these read-back barriers to ensure the APB/AHB bus
+ * transaction is complete before initiating activity on the PPSB
+ * block.
+ */
+#define FLUSH_SMMU_REGS(smmu)	smmu_read(smmu, SMMU_CONFIG)
+
+#define smmu_client_hwgrp(c) (u32)((c)->dev->platform_data)
+
+static int __smmu_client_set_hwgrp(struct smmu_client *c,
+				   unsigned long map, int on)
+{
+	int i;
+	struct smmu_as *as = c->as;
+	u32 val, offs, mask = SMMU_ASID_ENABLE(as->asid);
+	struct smmu_device *smmu = as->smmu;
+
+	WARN_ON(!on && map);
+	if (on && !map)
+		return -EINVAL;
+	if (!on)
+		map = smmu_client_hwgrp(c);
+
+	for_each_set_bit(i, &map, HWGRP_COUNT) {
+		offs = HWGRP_ASID_REG(i);
+		val = smmu_read(smmu, offs);
+		if (on) {
+			if (WARN_ON(val & mask))
+				goto err_hw_busy;
+			val |= mask;
+		} else {
+			WARN_ON((val & mask) == mask);
+			val &= ~mask;
+		}
+		smmu_write(smmu, val, offs);
+	}
+	FLUSH_SMMU_REGS(smmu);
+	c->hwgrp = map;
+	return 0;
+
+err_hw_busy:
+	for_each_set_bit(i, &map, HWGRP_COUNT) {
+		offs = HWGRP_ASID_REG(i);
+		val = smmu_read(smmu, offs);
+		val &= ~mask;
+		smmu_write(smmu, val, offs);
+	}
+	return -EBUSY;
+}
+
+static int smmu_client_set_hwgrp(struct smmu_client *c, u32 map, int on)
+{
+	u32 val;
+	unsigned long flags;
+	struct smmu_as *as = c->as;
+	struct smmu_device *smmu = as->smmu;
+
+	spin_lock_irqsave(&smmu->lock, flags);
+	val = __smmu_client_set_hwgrp(c, map, on);
+	spin_unlock_irqrestore(&smmu->lock, flags);
+	return val;
+}
+
+/*
+ * Flush all TLB entries and all PTC entries
+ * Caller must lock smmu
+ */
+static void smmu_flush_regs(struct smmu_device *smmu, int enable)
+{
+	u32 val;
+
+	smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH);
+	FLUSH_SMMU_REGS(smmu);
+	val = SMMU_TLB_FLUSH_VA_MATCH_ALL |
+		SMMU_TLB_FLUSH_ASID_MATCH_disable;
+	smmu_write(smmu, val, SMMU_TLB_FLUSH);
+
+	if (enable)
+		smmu_write(smmu, SMMU_CONFIG_ENABLE, SMMU_CONFIG);
+	FLUSH_SMMU_REGS(smmu);
+}
+
+static void smmu_setup_regs(struct smmu_device *smmu)
+{
+	int i;
+	u32 val;
+
+	for (i = 0; i < smmu->num_as; i++) {
+		struct smmu_as *as = &smmu->as[i];
+		struct smmu_client *c;
+
+		smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID);
+		val = as->pdir_page ?
+			SMMU_MK_PDIR(as->pdir_page, as->pdir_attr) :
+			SMMU_PTB_DATA_RESET_VAL;
+		smmu_write(smmu, val, SMMU_PTB_DATA);
+
+		list_for_each_entry(c, &as->client, list)
+			__smmu_client_set_hwgrp(c, c->hwgrp, 1);
+	}
+
+	smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0);
+	smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1);
+	smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2);
+	smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY);
+	smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_TLB_CONFIG);
+	smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_PTC_CONFIG);
+
+	smmu_flush_regs(smmu, 1);
+
+	val = ahb_read(smmu, AHB_XBAR_CTRL);
+	val |= AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE <<
+		AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT;
+	ahb_write(smmu, val, AHB_XBAR_CTRL);
+}
+
+static void flush_ptc_and_tlb(struct smmu_device *smmu,
+		      struct smmu_as *as, dma_addr_t iova,
+		      unsigned long *pte, struct page *page, int is_pde)
+{
+	u32 val;
+	unsigned long tlb_flush_va = is_pde
+		?  SMMU_TLB_FLUSH_VA(iova, SECTION)
+		:  SMMU_TLB_FLUSH_VA(iova, GROUP);
+
+	val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page);
+	smmu_write(smmu, val, SMMU_PTC_FLUSH);
+	FLUSH_SMMU_REGS(smmu);
+	val = tlb_flush_va |
+		SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
+		(as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
+	smmu_write(smmu, val, SMMU_TLB_FLUSH);
+	FLUSH_SMMU_REGS(smmu);
+}
+
+static void free_ptbl(struct smmu_as *as, dma_addr_t iova)
+{
+	unsigned long pdn = SMMU_ADDR_TO_PDN(iova);
+	unsigned long *pdir = (unsigned long *)page_address(as->pdir_page);
+
+	if (pdir[pdn] != _PDE_VACANT(pdn)) {
+		dev_dbg(as->smmu->dev, "pdn: %lx\n", pdn);
+
+		ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn]));
+		__free_page(SMMU_EX_PTBL_PAGE(pdir[pdn]));
+		pdir[pdn] = _PDE_VACANT(pdn);
+		FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]);
+		flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn],
+				  as->pdir_page, 1);
+	}
+}
+
+static void free_pdir(struct smmu_as *as)
+{
+	unsigned addr;
+	int count;
+	struct device *dev = as->smmu->dev;
+
+	if (!as->pdir_page)
+		return;
+
+	addr = as->smmu->iovmm_base;
+	count = as->smmu->page_count;
+	while (count-- > 0) {
+		free_ptbl(as, addr);
+		addr += SMMU_PAGE_SIZE * SMMU_PTBL_COUNT;
+	}
+	ClearPageReserved(as->pdir_page);
+	__free_page(as->pdir_page);
+	as->pdir_page = NULL;
+	devm_kfree(dev, as->pte_count);
+	as->pte_count = NULL;
+}
+
+/*
+ * Maps PTBL for given iova and returns the PTE address
+ * Caller must unmap the mapped PTBL returned in *ptbl_page_p
+ */
+static unsigned long *locate_pte(struct smmu_as *as,
+				 dma_addr_t iova, bool allocate,
+				 struct page **ptbl_page_p,
+				 unsigned int **count)
+{
+	unsigned long ptn = SMMU_ADDR_TO_PFN(iova);
+	unsigned long pdn = SMMU_ADDR_TO_PDN(iova);
+	unsigned long *pdir = page_address(as->pdir_page);
+	unsigned long *ptbl;
+
+	if (pdir[pdn] != _PDE_VACANT(pdn)) {
+		/* Mapped entry table already exists */
+		*ptbl_page_p = SMMU_EX_PTBL_PAGE(pdir[pdn]);
+		ptbl = page_address(*ptbl_page_p);
+	} else if (!allocate) {
+		return NULL;
+	} else {
+		int pn;
+		unsigned long addr = SMMU_PDN_TO_ADDR(pdn);
+
+		/* Vacant - allocate a new page table */
+		dev_dbg(as->smmu->dev, "New PTBL pdn: %lx\n", pdn);
+
+		*ptbl_page_p = alloc_page(GFP_ATOMIC);
+		if (!*ptbl_page_p) {
+			dev_err(as->smmu->dev,
+				"failed to allocate smmu_device page table\n");
+			return NULL;
+		}
+		SetPageReserved(*ptbl_page_p);
+		ptbl = (unsigned long *)page_address(*ptbl_page_p);
+		for (pn = 0; pn < SMMU_PTBL_COUNT;
+		     pn++, addr += SMMU_PAGE_SIZE) {
+			ptbl[pn] = _PTE_VACANT(addr);
+		}
+		FLUSH_CPU_DCACHE(ptbl, *ptbl_page_p, SMMU_PTBL_SIZE);
+		pdir[pdn] = SMMU_MK_PDE(*ptbl_page_p,
+					as->pde_attr | _PDE_NEXT);
+		FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]);
+		flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn],
+				  as->pdir_page, 1);
+	}
+	*count = &as->pte_count[pdn];
+
+	return &ptbl[ptn % SMMU_PTBL_COUNT];
+}
+
+#ifdef CONFIG_SMMU_SIG_DEBUG
+static void put_signature(struct smmu_as *as,
+			  dma_addr_t iova, unsigned long pfn)
+{
+	struct page *page;
+	unsigned long *vaddr;
+
+	page = pfn_to_page(pfn);
+	vaddr = page_address(page);
+	if (!vaddr)
+		return;
+
+	vaddr[0] = iova;
+	vaddr[1] = pfn << PAGE_SHIFT;
+	FLUSH_CPU_DCACHE(vaddr, page, sizeof(vaddr[0]) * 2);
+}
+#else
+static inline void put_signature(struct smmu_as *as,
+				 unsigned long addr, unsigned long pfn)
+{
+}
+#endif
+
+/*
+ * Caller must lock/unlock as
+ */
+static int alloc_pdir(struct smmu_as *as)
+{
+	unsigned long *pdir;
+	int pdn;
+	u32 val;
+	struct smmu_device *smmu = as->smmu;
+
+	if (as->pdir_page)
+		return 0;
+
+	as->pte_count = devm_kzalloc(smmu->dev,
+		     sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL);
+	if (!as->pte_count) {
+		dev_err(smmu->dev,
+			"failed to allocate smmu_device PTE cunters\n");
+		return -ENOMEM;
+	}
+	as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA);
+	if (!as->pdir_page) {
+		dev_err(smmu->dev,
+			"failed to allocate smmu_device page directory\n");
+		devm_kfree(smmu->dev, as->pte_count);
+		as->pte_count = NULL;
+		return -ENOMEM;
+	}
+	SetPageReserved(as->pdir_page);
+	pdir = page_address(as->pdir_page);
+
+	for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++)
+		pdir[pdn] = _PDE_VACANT(pdn);
+	FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE);
+	val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pdir, as->pdir_page);
+	smmu_write(smmu, val, SMMU_PTC_FLUSH);
+	FLUSH_SMMU_REGS(as->smmu);
+	val = SMMU_TLB_FLUSH_VA_MATCH_ALL |
+		SMMU_TLB_FLUSH_ASID_MATCH__ENABLE |
+		(as->asid << SMMU_TLB_FLUSH_ASID_SHIFT);
+	smmu_write(smmu, val, SMMU_TLB_FLUSH);
+	FLUSH_SMMU_REGS(as->smmu);
+
+	return 0;
+}
+
+static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova)
+{
+	unsigned long *pte;
+	struct page *page;
+	unsigned int *count;
+
+	pte = locate_pte(as, iova, false, &page, &count);
+	if (WARN_ON(!pte))
+		return;
+
+	if (WARN_ON(*pte == _PTE_VACANT(iova)))
+		return;
+
+	*pte = _PTE_VACANT(iova);
+	FLUSH_CPU_DCACHE(pte, page, sizeof(*pte));
+	flush_ptc_and_tlb(as->smmu, as, iova, pte, page, 0);
+	if (!--(*count)) {
+		free_ptbl(as, iova);
+		smmu_flush_regs(as->smmu, 0);
+	}
+}
+
+static void __smmu_iommu_map_pfn(struct smmu_as *as, dma_addr_t iova,
+				 unsigned long pfn)
+{
+	struct smmu_device *smmu = as->smmu;
+	unsigned long *pte;
+	unsigned int *count;
+	struct page *page;
+
+	pte = locate_pte(as, iova, true, &page, &count);
+	if (WARN_ON(!pte))
+		return;
+
+	if (*pte == _PTE_VACANT(iova))
+		(*count)++;
+	*pte = SMMU_PFN_TO_PTE(pfn, as->pte_attr);
+	if (unlikely((*pte == _PTE_VACANT(iova))))
+		(*count)--;
+	FLUSH_CPU_DCACHE(pte, page, sizeof(*pte));
+	flush_ptc_and_tlb(smmu, as, iova, pte, page, 0);
+	put_signature(as, iova, pfn);
+}
+
+static int smmu_iommu_map(struct iommu_domain *domain, unsigned long iova,
+			  phys_addr_t pa, size_t bytes, int prot)
+{
+	struct smmu_as *as = domain->priv;
+	unsigned long pfn = __phys_to_pfn(pa);
+	unsigned long flags;
+
+	dev_dbg(as->smmu->dev, "[%d] %08lx:%08x\n", as->asid, iova, pa);
+
+	if (!pfn_valid(pfn))
+		return -ENOMEM;
+
+	spin_lock_irqsave(&as->lock, flags);
+	__smmu_iommu_map_pfn(as, iova, pfn);
+	spin_unlock_irqrestore(&as->lock, flags);
+	return 0;
+}
+
+static size_t smmu_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+			       size_t bytes)
+{
+	struct smmu_as *as = domain->priv;
+	unsigned long flags;
+
+	dev_dbg(as->smmu->dev, "[%d] %08lx\n", as->asid, iova);
+
+	spin_lock_irqsave(&as->lock, flags);
+	__smmu_iommu_unmap(as, iova);
+	spin_unlock_irqrestore(&as->lock, flags);
+	return SMMU_PAGE_SIZE;
+}
+
+static phys_addr_t smmu_iommu_iova_to_phys(struct iommu_domain *domain,
+					   unsigned long iova)
+{
+	struct smmu_as *as = domain->priv;
+	unsigned long *pte;
+	unsigned int *count;
+	struct page *page;
+	unsigned long pfn;
+	unsigned long flags;
+
+	spin_lock_irqsave(&as->lock, flags);
+
+	pte = locate_pte(as, iova, true, &page, &count);
+	pfn = *pte & SMMU_PFN_MASK;
+	WARN_ON(!pfn_valid(pfn));
+	dev_dbg(as->smmu->dev,
+		"iova:%08lx pfn:%08lx asid:%d\n", iova, pfn, as->asid);
+
+	spin_unlock_irqrestore(&as->lock, flags);
+	return PFN_PHYS(pfn);
+}
+
+static int smmu_iommu_domain_has_cap(struct iommu_domain *domain,
+				     unsigned long cap)
+{
+	return 0;
+}
+
+static int smmu_iommu_attach_dev(struct iommu_domain *domain,
+				 struct device *dev)
+{
+	struct smmu_as *as = domain->priv;
+	struct smmu_device *smmu = as->smmu;
+	struct smmu_client *client, *c;
+	u32 map;
+	int err;
+
+	client = devm_kzalloc(smmu->dev, sizeof(*c), GFP_KERNEL);
+	if (!client)
+		return -ENOMEM;
+	client->dev = dev;
+	client->as = as;
+	map = (unsigned long)dev->platform_data;
+	if (!map)
+		return -EINVAL;
+
+	err = smmu_client_enable_hwgrp(client, map);
+	if (err)
+		goto err_hwgrp;
+
+	spin_lock(&as->client_lock);
+	list_for_each_entry(c, &as->client, list) {
+		if (c->dev == dev) {
+			dev_err(smmu->dev,
+				"%s is already attached\n", dev_name(c->dev));
+			err = -EINVAL;
+			goto err_client;
+		}
+	}
+	list_add(&client->list, &as->client);
+	spin_unlock(&as->client_lock);
+
+	/*
+	 * Reserve "page zero" for AVP vectors using a common dummy
+	 * page.
+	 */
+	if (map & HWG_AVPC) {
+		struct page *page;
+
+		page = as->smmu->avp_vector_page;
+		__smmu_iommu_map_pfn(as, 0, page_to_pfn(page));
+
+		pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n");
+	}
+
+	dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev));
+	return 0;
+
+err_client:
+	smmu_client_disable_hwgrp(client);
+	spin_unlock(&as->client_lock);
+err_hwgrp:
+	devm_kfree(smmu->dev, client);
+	return err;
+}
+
+static void smmu_iommu_detach_dev(struct iommu_domain *domain,
+				  struct device *dev)
+{
+	struct smmu_as *as = domain->priv;
+	struct smmu_device *smmu = as->smmu;
+	struct smmu_client *c;
+
+	spin_lock(&as->client_lock);
+
+	list_for_each_entry(c, &as->client, list) {
+		if (c->dev == dev) {
+			smmu_client_disable_hwgrp(c);
+			list_del(&c->list);
+			devm_kfree(smmu->dev, c);
+			c->as = NULL;
+			dev_dbg(smmu->dev,
+				"%s is detached\n", dev_name(c->dev));
+			goto out;
+		}
+	}
+	dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev));
+out:
+	spin_unlock(&as->client_lock);
+}
+
+static int smmu_iommu_domain_init(struct iommu_domain *domain)
+{
+	int i;
+	unsigned long flags;
+	struct smmu_as *as;
+	struct smmu_device *smmu = smmu_handle;
+
+	/* Look for a free AS with lock held */
+	for  (i = 0; i < smmu->num_as; i++) {
+		struct smmu_as *tmp = &smmu->as[i];
+
+		spin_lock_irqsave(&tmp->lock, flags);
+		if (!tmp->pdir_page) {
+			as = tmp;
+			goto found;
+		}
+		spin_unlock_irqrestore(&tmp->lock, flags);
+	}
+	dev_err(smmu->dev, "no free AS\n");
+	return -ENODEV;
+
+found:
+	if (alloc_pdir(as) < 0)
+		goto err_alloc_pdir;
+
+	spin_lock(&smmu->lock);
+
+	/* Update PDIR register */
+	smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID);
+	smmu_write(smmu,
+		   SMMU_MK_PDIR(as->pdir_page, as->pdir_attr), SMMU_PTB_DATA);
+	FLUSH_SMMU_REGS(smmu);
+
+	spin_unlock(&smmu->lock);
+
+	spin_unlock_irqrestore(&as->lock, flags);
+	domain->priv = as;
+
+	dev_dbg(smmu->dev, "smmu_as@%p\n", as);
+	return 0;
+
+err_alloc_pdir:
+	spin_unlock_irqrestore(&as->lock, flags);
+	return -ENODEV;
+}
+
+static void smmu_iommu_domain_destroy(struct iommu_domain *domain)
+{
+	struct smmu_as *as = domain->priv;
+	struct smmu_device *smmu = as->smmu;
+	unsigned long flags;
+
+	spin_lock_irqsave(&as->lock, flags);
+
+	if (as->pdir_page) {
+		spin_lock(&smmu->lock);
+		smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID);
+		smmu_write(smmu, SMMU_PTB_DATA_RESET_VAL, SMMU_PTB_DATA);
+		FLUSH_SMMU_REGS(smmu);
+		spin_unlock(&smmu->lock);
+
+		free_pdir(as);
+	}
+
+	if (!list_empty(&as->client)) {
+		struct smmu_client *c;
+
+		list_for_each_entry(c, &as->client, list)
+			smmu_iommu_detach_dev(domain, c->dev);
+	}
+
+	spin_unlock_irqrestore(&as->lock, flags);
+
+	domain->priv = NULL;
+	dev_dbg(smmu->dev, "smmu_as@%p\n", as);
+}
+
+static struct iommu_ops smmu_iommu_ops = {
+	.domain_init	= smmu_iommu_domain_init,
+	.domain_destroy	= smmu_iommu_domain_destroy,
+	.attach_dev	= smmu_iommu_attach_dev,
+	.detach_dev	= smmu_iommu_detach_dev,
+	.map		= smmu_iommu_map,
+	.unmap		= smmu_iommu_unmap,
+	.iova_to_phys	= smmu_iommu_iova_to_phys,
+	.domain_has_cap	= smmu_iommu_domain_has_cap,
+	.pgsize_bitmap	= SMMU_IOMMU_PGSIZES,
+};
+
+static int tegra_smmu_suspend(struct device *dev)
+{
+	struct smmu_device *smmu = dev_get_drvdata(dev);
+
+	smmu->translation_enable_0 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_0);
+	smmu->translation_enable_1 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_1);
+	smmu->translation_enable_2 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_2);
+	smmu->asid_security = smmu_read(smmu, SMMU_ASID_SECURITY);
+	return 0;
+}
+
+static int tegra_smmu_resume(struct device *dev)
+{
+	struct smmu_device *smmu = dev_get_drvdata(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&smmu->lock, flags);
+	smmu_setup_regs(smmu);
+	spin_unlock_irqrestore(&smmu->lock, flags);
+	return 0;
+}
+
+static int tegra_smmu_probe(struct platform_device *pdev)
+{
+	struct smmu_device *smmu;
+	struct resource *regs, *regs2, *window;
+	struct device *dev = &pdev->dev;
+	int i, err = 0;
+
+	if (smmu_handle)
+		return -EIO;
+
+	BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT);
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	window = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	if (!regs || !regs2 || !window) {
+		dev_err(dev, "No SMMU resources\n");
+		return -ENODEV;
+	}
+
+	smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
+	if (!smmu) {
+		dev_err(dev, "failed to allocate smmu_device\n");
+		return -ENOMEM;
+	}
+
+	smmu->dev = dev;
+	smmu->num_as = SMMU_NUM_ASIDS;
+	smmu->iovmm_base = (unsigned long)window->start;
+	smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT;
+	smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs));
+	smmu->regs_ahbarb = devm_ioremap(dev, regs2->start,
+					 resource_size(regs2));
+	if (!smmu->regs || !smmu->regs_ahbarb) {
+		dev_err(dev, "failed to remap SMMU registers\n");
+		err = -ENXIO;
+		goto fail;
+	}
+
+	smmu->translation_enable_0 = ~0;
+	smmu->translation_enable_1 = ~0;
+	smmu->translation_enable_2 = ~0;
+	smmu->asid_security = 0;
+
+	smmu->as = devm_kzalloc(dev,
+			sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL);
+	if (!smmu->as) {
+		dev_err(dev, "failed to allocate smmu_as\n");
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	for (i = 0; i < smmu->num_as; i++) {
+		struct smmu_as *as = &smmu->as[i];
+
+		as->smmu = smmu;
+		as->asid = i;
+		as->pdir_attr = _PDIR_ATTR;
+		as->pde_attr = _PDE_ATTR;
+		as->pte_attr = _PTE_ATTR;
+
+		spin_lock_init(&as->lock);
+		INIT_LIST_HEAD(&as->client);
+	}
+	spin_lock_init(&smmu->lock);
+	smmu_setup_regs(smmu);
+	platform_set_drvdata(pdev, smmu);
+
+	smmu->avp_vector_page = alloc_page(GFP_KERNEL);
+	if (!smmu->avp_vector_page)
+		goto fail;
+
+	smmu_handle = smmu;
+	return 0;
+
+fail:
+	if (smmu->avp_vector_page)
+		__free_page(smmu->avp_vector_page);
+	if (smmu->regs)
+		devm_iounmap(dev, smmu->regs);
+	if (smmu->regs_ahbarb)
+		devm_iounmap(dev, smmu->regs_ahbarb);
+	if (smmu && smmu->as) {
+		for (i = 0; i < smmu->num_as; i++) {
+			if (smmu->as[i].pdir_page) {
+				ClearPageReserved(smmu->as[i].pdir_page);
+				__free_page(smmu->as[i].pdir_page);
+			}
+		}
+		devm_kfree(dev, smmu->as);
+	}
+	devm_kfree(dev, smmu);
+	return err;
+}
+
+static int tegra_smmu_remove(struct platform_device *pdev)
+{
+	struct smmu_device *smmu = platform_get_drvdata(pdev);
+	struct device *dev = smmu->dev;
+
+	smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG);
+	platform_set_drvdata(pdev, NULL);
+	if (smmu->as) {
+		int i;
+
+		for (i = 0; i < smmu->num_as; i++)
+			free_pdir(&smmu->as[i]);
+		devm_kfree(dev, smmu->as);
+	}
+	if (smmu->avp_vector_page)
+		__free_page(smmu->avp_vector_page);
+	if (smmu->regs)
+		devm_iounmap(dev, smmu->regs);
+	if (smmu->regs_ahbarb)
+		devm_iounmap(dev, smmu->regs_ahbarb);
+	devm_kfree(dev, smmu);
+	smmu_handle = NULL;
+	return 0;
+}
+
+const struct dev_pm_ops tegra_smmu_pm_ops = {
+	.suspend	= tegra_smmu_suspend,
+	.resume		= tegra_smmu_resume,
+};
+
+static struct platform_driver tegra_smmu_driver = {
+	.probe		= tegra_smmu_probe,
+	.remove		= tegra_smmu_remove,
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= "tegra-smmu",
+		.pm	= &tegra_smmu_pm_ops,
+	},
+};
+
+static int __devinit tegra_smmu_init(void)
+{
+	bus_set_iommu(&platform_bus_type, &smmu_iommu_ops);
+	return platform_driver_register(&tegra_smmu_driver);
+}
+
+static void __exit tegra_smmu_exit(void)
+{
+	platform_driver_unregister(&tegra_smmu_driver);
+}
+
+subsys_initcall(tegra_smmu_init);
+module_exit(tegra_smmu_exit);
+
+MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30");
+MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h
index 88c9423..321d437 100644
--- a/drivers/isdn/act2000/act2000.h
+++ b/drivers/isdn/act2000/act2000.h
@@ -4,7 +4,7 @@
  *
  * Author       Fritz Elfert
  * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -40,21 +40,21 @@
 /* Struct for adding new cards */
 typedef struct act2000_cdef {
 	int bus;
-        int port;
-        int irq;
-        char id[10];
+	int port;
+	int irq;
+	char id[10];
 } act2000_cdef;
 
 /* Struct for downloading firmware */
 typedef struct act2000_ddef {
-        int length;             /* Length of code */
-        char __user *buffer;    /* Ptr. to code   */
+	int length;             /* Length of code */
+	char __user *buffer;    /* Ptr. to code   */
 } act2000_ddef;
 
 typedef struct act2000_fwid {
-        char isdn[4];
-        char revlen[2];
-        char revision[504];
+	char isdn[4];
+	char revlen[2];
+	char revision[504];
 } act2000_fwid;
 
 #if defined(__KERNEL__) || defined(__DEBUGVAR__)
@@ -128,8 +128,8 @@ typedef struct act2000_chan {
 
 typedef struct msn_entry {
 	char eaz;
-        char msn[16];
-        struct msn_entry * next;
+	char msn[16];
+	struct msn_entry *next;
 } msn_entry;
 
 typedef struct irq_data_isa {
@@ -183,17 +183,17 @@ typedef struct act2000_card {
 
 static inline void act2000_schedule_tx(act2000_card *card)
 {
-        schedule_work(&card->snd_tq);
+	schedule_work(&card->snd_tq);
 }
 
 static inline void act2000_schedule_rx(act2000_card *card)
 {
-        schedule_work(&card->rcv_tq);
+	schedule_work(&card->rcv_tq);
 }
 
 static inline void act2000_schedule_poll(act2000_card *card)
 {
-        schedule_work(&card->poll_tq);
+	schedule_work(&card->poll_tq);
 }
 
 extern char *act2000_find_eaz(act2000_card *, char);
diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c
index fea5b78..b5fad29 100644
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -4,7 +4,7 @@
  *
  * Author       Fritz Elfert
  * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -25,99 +25,99 @@
 static int
 act2000_isa_reset(unsigned short portbase)
 {
-        unsigned char reg;
-        int i;
-        int found;
-        int serial = 0;
-
-        found = 0;
-        if ((reg = inb(portbase + ISA_COR)) != 0xff) {
-                outb(reg | ISA_COR_RESET, portbase + ISA_COR);
-                mdelay(10);
-                outb(reg, portbase + ISA_COR);
-                mdelay(10);
-
-                for (i = 0; i < 16; i++) {
-                        if (inb(portbase + ISA_ISR) & ISA_ISR_SERIAL)
-                                serial |= 0x10000;
-                        serial >>= 1;
-                }
-                if (serial == ISA_SER_ID)
-                        found++;
-        }
-        return found;
+	unsigned char reg;
+	int i;
+	int found;
+	int serial = 0;
+
+	found = 0;
+	if ((reg = inb(portbase + ISA_COR)) != 0xff) {
+		outb(reg | ISA_COR_RESET, portbase + ISA_COR);
+		mdelay(10);
+		outb(reg, portbase + ISA_COR);
+		mdelay(10);
+
+		for (i = 0; i < 16; i++) {
+			if (inb(portbase + ISA_ISR) & ISA_ISR_SERIAL)
+				serial |= 0x10000;
+			serial >>= 1;
+		}
+		if (serial == ISA_SER_ID)
+			found++;
+	}
+	return found;
 }
 
 int
 act2000_isa_detect(unsigned short portbase)
 {
-        int ret = 0;
+	int ret = 0;
 
 	if (request_region(portbase, ACT2000_PORTLEN, "act2000isa")) {
-                ret = act2000_isa_reset(portbase);
+		ret = act2000_isa_reset(portbase);
 		release_region(portbase, ISA_REGION);
 	}
-        return ret;
+	return ret;
 }
 
 static irqreturn_t
 act2000_isa_interrupt(int dummy, void *dev_id)
 {
-        act2000_card *card = dev_id;
-        u_char istatus;
+	act2000_card *card = dev_id;
+	u_char istatus;
 
-        istatus = (inb(ISA_PORT_ISR) & 0x07);
-        if (istatus & ISA_ISR_OUT) {
-                /* RX fifo has data */
+	istatus = (inb(ISA_PORT_ISR) & 0x07);
+	if (istatus & ISA_ISR_OUT) {
+		/* RX fifo has data */
 		istatus &= ISA_ISR_OUT_MASK;
 		outb(0, ISA_PORT_SIS);
 		act2000_isa_receive(card);
 		outb(ISA_SIS_INT, ISA_PORT_SIS);
-        }
-        if (istatus & ISA_ISR_ERR) {
-                /* Error Interrupt */
+	}
+	if (istatus & ISA_ISR_ERR) {
+		/* Error Interrupt */
 		istatus &= ISA_ISR_ERR_MASK;
-                printk(KERN_WARNING "act2000: errIRQ\n");
-        }
+		printk(KERN_WARNING "act2000: errIRQ\n");
+	}
 	if (istatus)
 		printk(KERN_DEBUG "act2000: ?IRQ %d %02x\n", card->irq, istatus);
 	return IRQ_HANDLED;
 }
 
 static void
-act2000_isa_select_irq(act2000_card * card)
+act2000_isa_select_irq(act2000_card *card)
 {
 	unsigned char reg;
 
 	reg = (inb(ISA_PORT_COR) & ~ISA_COR_IRQOFF) | ISA_COR_PERR;
 	switch (card->irq) {
-		case 3:
-			reg = ISA_COR_IRQ03;
-			break;
-		case 5:
-			reg = ISA_COR_IRQ05;
-			break;
-		case 7:
-			reg = ISA_COR_IRQ07;
-			break;
-		case 10:
-			reg = ISA_COR_IRQ10;
-			break;
-		case 11:
-			reg = ISA_COR_IRQ11;
-			break;
-		case 12:
-			reg = ISA_COR_IRQ12;
-			break;
-		case 15:
-			reg = ISA_COR_IRQ15;
-			break;
+	case 3:
+		reg = ISA_COR_IRQ03;
+		break;
+	case 5:
+		reg = ISA_COR_IRQ05;
+		break;
+	case 7:
+		reg = ISA_COR_IRQ07;
+		break;
+	case 10:
+		reg = ISA_COR_IRQ10;
+		break;
+	case 11:
+		reg = ISA_COR_IRQ11;
+		break;
+	case 12:
+		reg = ISA_COR_IRQ12;
+		break;
+	case 15:
+		reg = ISA_COR_IRQ15;
+		break;
 	}
 	outb(reg, ISA_PORT_COR);
 }
 
 static void
-act2000_isa_enable_irq(act2000_card * card)
+act2000_isa_enable_irq(act2000_card *card)
 {
 	act2000_isa_select_irq(card);
 	/* Enable READ irq */
@@ -129,102 +129,102 @@ act2000_isa_enable_irq(act2000_card * card)
  * If irq is -1, choose next free irq, else irq is given explicitly.
  */
 int
-act2000_isa_config_irq(act2000_card * card, short irq)
+act2000_isa_config_irq(act2000_card *card, short irq)
 {
 	int old_irq;
 
-        if (card->flags & ACT2000_FLAGS_IVALID) {
-                free_irq(card->irq, card);
-        }
-        card->flags &= ~ACT2000_FLAGS_IVALID;
-        outb(ISA_COR_IRQOFF, ISA_PORT_COR);
-        if (!irq)
-                return 0;
+	if (card->flags & ACT2000_FLAGS_IVALID) {
+		free_irq(card->irq, card);
+	}
+	card->flags &= ~ACT2000_FLAGS_IVALID;
+	outb(ISA_COR_IRQOFF, ISA_PORT_COR);
+	if (!irq)
+		return 0;
 
 	old_irq = card->irq;
 	card->irq = irq;
 	if (request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) {
 		card->irq = old_irq;
 		card->flags |= ACT2000_FLAGS_IVALID;
-                printk(KERN_WARNING
-                       "act2000: Could not request irq %d\n",irq);
-                return -EBUSY;
-        } else {
+		printk(KERN_WARNING
+		       "act2000: Could not request irq %d\n", irq);
+		return -EBUSY;
+	} else {
 		act2000_isa_select_irq(card);
-                /* Disable READ and WRITE irq */
-                outb(0, ISA_PORT_SIS);
-                outb(0, ISA_PORT_SOS);
-        }
-        return 0;
+		/* Disable READ and WRITE irq */
+		outb(0, ISA_PORT_SIS);
+		outb(0, ISA_PORT_SOS);
+	}
+	return 0;
 }
 
 int
-act2000_isa_config_port(act2000_card * card, unsigned short portbase)
+act2000_isa_config_port(act2000_card *card, unsigned short portbase)
 {
-        if (card->flags & ACT2000_FLAGS_PVALID) {
-                release_region(card->port, ISA_REGION);
-                card->flags &= ~ACT2000_FLAGS_PVALID;
-        }
+	if (card->flags & ACT2000_FLAGS_PVALID) {
+		release_region(card->port, ISA_REGION);
+		card->flags &= ~ACT2000_FLAGS_PVALID;
+	}
 	if (request_region(portbase, ACT2000_PORTLEN, card->regname) == NULL)
 		return -EBUSY;
 	else {
-                card->port = portbase;
-                card->flags |= ACT2000_FLAGS_PVALID;
-                return 0;
-        }
+		card->port = portbase;
+		card->flags |= ACT2000_FLAGS_PVALID;
+		return 0;
+	}
 }
 
 /*
  * Release ressources, used by an adaptor.
  */
 void
-act2000_isa_release(act2000_card * card)
+act2000_isa_release(act2000_card *card)
 {
-        unsigned long flags;
+	unsigned long flags;
 
-        spin_lock_irqsave(&card->lock, flags);
-        if (card->flags & ACT2000_FLAGS_IVALID)
-                free_irq(card->irq, card);
+	spin_lock_irqsave(&card->lock, flags);
+	if (card->flags & ACT2000_FLAGS_IVALID)
+		free_irq(card->irq, card);
 
-        card->flags &= ~ACT2000_FLAGS_IVALID;
-        if (card->flags & ACT2000_FLAGS_PVALID)
-                release_region(card->port, ISA_REGION);
-        card->flags &= ~ACT2000_FLAGS_PVALID;
-        spin_unlock_irqrestore(&card->lock, flags);
+	card->flags &= ~ACT2000_FLAGS_IVALID;
+	if (card->flags & ACT2000_FLAGS_PVALID)
+		release_region(card->port, ISA_REGION);
+	card->flags &= ~ACT2000_FLAGS_PVALID;
+	spin_unlock_irqrestore(&card->lock, flags);
 }
 
 static int
-act2000_isa_writeb(act2000_card * card, u_char data)
+act2000_isa_writeb(act2000_card *card, u_char data)
 {
-        u_char timeout = 40;
-
-        while (timeout) {
-                if (inb(ISA_PORT_SOS) & ISA_SOS_READY) {
-                        outb(data, ISA_PORT_SDO);
-                        return 0;
-                } else {
-                        timeout--;
-                        udelay(10);
-                }
-        }
-        return 1;
+	u_char timeout = 40;
+
+	while (timeout) {
+		if (inb(ISA_PORT_SOS) & ISA_SOS_READY) {
+			outb(data, ISA_PORT_SDO);
+			return 0;
+		} else {
+			timeout--;
+			udelay(10);
+		}
+	}
+	return 1;
 }
 
 static int
-act2000_isa_readb(act2000_card * card, u_char * data)
+act2000_isa_readb(act2000_card *card, u_char *data)
 {
-        u_char timeout = 40;
-
-        while (timeout) {
-                if (inb(ISA_PORT_SIS) & ISA_SIS_READY) {
-                        *data = inb(ISA_PORT_SDI);
-                        return 0;
-                } else {
-                        timeout--;
-                        udelay(10);
-                }
-        }
-        return 1;
+	u_char timeout = 40;
+
+	while (timeout) {
+		if (inb(ISA_PORT_SIS) & ISA_SIS_READY) {
+			*data = inb(ISA_PORT_SDI);
+			return 0;
+		} else {
+			timeout--;
+			udelay(10);
+		}
+	}
+	return 1;
 }
 
 void
@@ -232,11 +232,11 @@ act2000_isa_receive(act2000_card *card)
 {
 	u_char c;
 
-        if (test_and_set_bit(ACT2000_LOCK_RX, (void *) &card->ilock) != 0)
+	if (test_and_set_bit(ACT2000_LOCK_RX, (void *) &card->ilock) != 0)
 		return;
 	while (!act2000_isa_readb(card, &c)) {
 		if (card->idat.isa.rcvidx < 8) {
-                        card->idat.isa.rcvhdr[card->idat.isa.rcvidx++] = c;
+			card->idat.isa.rcvhdr[card->idat.isa.rcvidx++] = c;
 			if (card->idat.isa.rcvidx == 8) {
 				int valid = actcapi_chkhdr(card, (actcapi_msghdr *)&card->idat.isa.rcvhdr);
 
@@ -291,14 +291,14 @@ act2000_isa_receive(act2000_card *card)
 }
 
 void
-act2000_isa_send(act2000_card * card)
+act2000_isa_send(act2000_card *card)
 {
 	unsigned long flags;
 	struct sk_buff *skb;
 	actcapi_msg *msg;
 	int l;
 
-        if (test_and_set_bit(ACT2000_LOCK_TX, (void *) &card->ilock) != 0)
+	if (test_and_set_bit(ACT2000_LOCK_TX, (void *) &card->ilock) != 0)
 		return;
 	while (1) {
 		spin_lock_irqsave(&card->lock, flags);
@@ -307,7 +307,7 @@ act2000_isa_send(act2000_card * card)
 				card->ack_msg = card->sbuf->data;
 				msg = (actcapi_msg *)card->sbuf->data;
 				if ((msg->hdr.cmd.cmd == 0x86) &&
-				    (msg->hdr.cmd.subcmd == 0)   ) {
+				    (msg->hdr.cmd.subcmd == 0)) {
 					/* Save flags in message */
 					card->need_b3ack = msg->msg.data_b3_req.flags;
 					msg->msg.data_b3_req.flags = 0;
@@ -335,7 +335,7 @@ act2000_isa_send(act2000_card * card)
 		}
 		msg = (actcapi_msg *)card->ack_msg;
 		if ((msg->hdr.cmd.cmd == 0x86) &&
-		    (msg->hdr.cmd.subcmd == 0)   ) {
+		    (msg->hdr.cmd.subcmd == 0)) {
 			/*
 			 * If it's user data, reset data-ptr
 			 * and put skb into ackq.
@@ -354,90 +354,90 @@ act2000_isa_send(act2000_card * card)
  * Get firmware ID, check for 'ISDN' signature.
  */
 static int
-act2000_isa_getid(act2000_card * card)
+act2000_isa_getid(act2000_card *card)
 {
 
-        act2000_fwid fid;
-        u_char *p = (u_char *) & fid;
-        int count = 0;
-
-        while (1) {
-                if (count > 510)
-                        return -EPROTO;
-                if (act2000_isa_readb(card, p++))
-                        break;
-                count++;
-        }
-        if (count <= 20) {
-                printk(KERN_WARNING "act2000: No Firmware-ID!\n");
-                return -ETIME;
-        }
-        *p = '\0';
-        fid.revlen[0] = '\0';
-        if (strcmp(fid.isdn, "ISDN")) {
-                printk(KERN_WARNING "act2000: Wrong Firmware-ID!\n");
-                return -EPROTO;
-        }
+	act2000_fwid fid;
+	u_char *p = (u_char *)&fid;
+	int count = 0;
+
+	while (1) {
+		if (count > 510)
+			return -EPROTO;
+		if (act2000_isa_readb(card, p++))
+			break;
+		count++;
+	}
+	if (count <= 20) {
+		printk(KERN_WARNING "act2000: No Firmware-ID!\n");
+		return -ETIME;
+	}
+	*p = '\0';
+	fid.revlen[0] = '\0';
+	if (strcmp(fid.isdn, "ISDN")) {
+		printk(KERN_WARNING "act2000: Wrong Firmware-ID!\n");
+		return -EPROTO;
+	}
 	if ((p = strchr(fid.revision, '\n')))
 		*p = '\0';
-        printk(KERN_INFO "act2000: Firmware-ID: %s\n", fid.revision);
+	printk(KERN_INFO "act2000: Firmware-ID: %s\n", fid.revision);
 	if (card->flags & ACT2000_FLAGS_IVALID) {
 		printk(KERN_DEBUG "Enabling Interrupts ...\n");
 		act2000_isa_enable_irq(card);
 	}
-        return 0;
+	return 0;
 }
 
 /*
  * Download microcode into card, check Firmware signature.
  */
 int
-act2000_isa_download(act2000_card * card, act2000_ddef __user * cb)
+act2000_isa_download(act2000_card *card, act2000_ddef __user *cb)
 {
-        unsigned int length;
-        int l;
-        int c;
-        long timeout;
-        u_char *b;
-        u_char __user *p;
-        u_char *buf;
-        act2000_ddef cblock;
-
-        if (!act2000_isa_reset(card->port))
-                return -ENXIO;
-        msleep_interruptible(500);
-        if (copy_from_user(&cblock, cb, sizeof(cblock)))
-        	return -EFAULT;
-        length = cblock.length;
-        p = cblock.buffer;
-        if (!access_ok(VERIFY_READ, p, length))
-                return -EFAULT;
-        buf = kmalloc(1024, GFP_KERNEL);
-        if (!buf)
-                return -ENOMEM;
-        timeout = 0;
-        while (length) {
-                l = (length > 1024) ? 1024 : length;
-                c = 0;
-                b = buf;
-                if (copy_from_user(buf, p, l)) {
-                        kfree(buf);
-                        return -EFAULT;
-                }
-                while (c < l) {
-                        if (act2000_isa_writeb(card, *b++)) {
-                                printk(KERN_WARNING
-                                       "act2000: loader timed out"
-                                       " len=%d c=%d\n", length, c);
-                                kfree(buf);
-                                return -ETIME;
-                        }
-                        c++;
-                }
-                length -= l;
-                p += l;
-        }
-        kfree(buf);
-        msleep_interruptible(500);
-        return (act2000_isa_getid(card));
+	unsigned int length;
+	int l;
+	int c;
+	long timeout;
+	u_char *b;
+	u_char __user *p;
+	u_char *buf;
+	act2000_ddef cblock;
+
+	if (!act2000_isa_reset(card->port))
+		return -ENXIO;
+	msleep_interruptible(500);
+	if (copy_from_user(&cblock, cb, sizeof(cblock)))
+		return -EFAULT;
+	length = cblock.length;
+	p = cblock.buffer;
+	if (!access_ok(VERIFY_READ, p, length))
+		return -EFAULT;
+	buf = kmalloc(1024, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	timeout = 0;
+	while (length) {
+		l = (length > 1024) ? 1024 : length;
+		c = 0;
+		b = buf;
+		if (copy_from_user(buf, p, l)) {
+			kfree(buf);
+			return -EFAULT;
+		}
+		while (c < l) {
+			if (act2000_isa_writeb(card, *b++)) {
+				printk(KERN_WARNING
+				       "act2000: loader timed out"
+				       " len=%d c=%d\n", length, c);
+				kfree(buf);
+				return -ETIME;
+			}
+			c++;
+		}
+		length -= l;
+		p += l;
+	}
+	kfree(buf);
+	msleep_interruptible(500);
+	return (act2000_isa_getid(card));
 }
diff --git a/drivers/isdn/act2000/act2000_isa.h b/drivers/isdn/act2000/act2000_isa.h
index ad86c5e..1a72898 100644
--- a/drivers/isdn/act2000/act2000_isa.h
+++ b/drivers/isdn/act2000/act2000_isa.h
@@ -4,7 +4,7 @@
  *
  * Author       Fritz Elfert
  * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -18,9 +18,9 @@
 #define ISA_POLL_LOOP 40        /* Try to read-write before give up */
 
 typedef enum {
-        INT_NO_CHANGE = 0,      /* Do not change the Mask */
-        INT_ON = 1,             /* Set to Enable */
-        INT_OFF = 2,            /* Set to Disable */
+	INT_NO_CHANGE = 0,      /* Do not change the Mask */
+	INT_ON = 1,             /* Set to Enable */
+	INT_OFF = 2,            /* Set to Disable */
 } ISA_INT_T;
 
 /**************************************************************************/
@@ -114,22 +114,22 @@ typedef enum {
 
 
 /* Macros for accessing ports */
-#define ISA_PORT_COR (card->port+ISA_COR)
-#define ISA_PORT_ISR (card->port+ISA_ISR)
-#define ISA_PORT_EPR (card->port+ISA_EPR)
-#define ISA_PORT_EER (card->port+ISA_EER)
-#define ISA_PORT_SDI (card->port+ISA_SDI)
-#define ISA_PORT_SDO (card->port+ISA_SDO)
-#define ISA_PORT_SIS (card->port+ISA_SIS)
-#define ISA_PORT_SOS (card->port+ISA_SOS)
+#define ISA_PORT_COR (card->port + ISA_COR)
+#define ISA_PORT_ISR (card->port + ISA_ISR)
+#define ISA_PORT_EPR (card->port + ISA_EPR)
+#define ISA_PORT_EER (card->port + ISA_EER)
+#define ISA_PORT_SDI (card->port + ISA_SDI)
+#define ISA_PORT_SDO (card->port + ISA_SDO)
+#define ISA_PORT_SIS (card->port + ISA_SIS)
+#define ISA_PORT_SOS (card->port + ISA_SOS)
 
 /* Prototypes */
 
 extern int act2000_isa_detect(unsigned short portbase);
-extern int act2000_isa_config_irq(act2000_card * card, short irq);
-extern int act2000_isa_config_port(act2000_card * card, unsigned short portbase);
-extern int act2000_isa_download(act2000_card * card, act2000_ddef __user * cb);
-extern void act2000_isa_release(act2000_card * card);
+extern int act2000_isa_config_irq(act2000_card *card, short irq);
+extern int act2000_isa_config_port(act2000_card *card, unsigned short portbase);
+extern int act2000_isa_download(act2000_card *card, act2000_ddef __user *cb);
+extern void act2000_isa_release(act2000_card *card);
 extern void act2000_isa_receive(act2000_card *card);
 extern void act2000_isa_send(act2000_card *card);
 
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
index 1f0a949..3f66ca2 100644
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -5,7 +5,7 @@
  *
  * Author       Fritz Elfert
  * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -64,14 +64,14 @@ static actcapi_msgdsc valid_msg[] = {
 	{{ 0x86, 0x00}, "DATA_B3_REQ"},
 	{{ 0xff, 0x00}, "MANUFACTURER_REQ"},
 	/* Responses */
-	{{ 0x01, 0x03}, "RESET_B3_RESP"},	
-	{{ 0x02, 0x03}, "CONNECT_RESP"},	
-	{{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},	
-	{{ 0x04, 0x03}, "DISCONNECT_RESP"},	
-	{{ 0x07, 0x03}, "INFO_RESP"},	
-	{{ 0x08, 0x03}, "DATA_RESP"},	
-	{{ 0x82, 0x03}, "CONNECT_B3_RESP"},	
-	{{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},	
+	{{ 0x01, 0x03}, "RESET_B3_RESP"},
+	{{ 0x02, 0x03}, "CONNECT_RESP"},
+	{{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
+	{{ 0x04, 0x03}, "DISCONNECT_RESP"},
+	{{ 0x07, 0x03}, "INFO_RESP"},
+	{{ 0x08, 0x03}, "DATA_RESP"},
+	{{ 0x82, 0x03}, "CONNECT_B3_RESP"},
+	{{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
 	{{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
 	{{ 0x86, 0x03}, "DATA_B3_RESP"},
 	{{ 0xff, 0x03}, "MANUFACTURER_RESP"},
@@ -88,7 +88,7 @@ static actcapi_msgdsc valid_msg[] = {
  *   2 = Valid message, B-Channel-data
  */
 int
-actcapi_chkhdr(act2000_card * card, actcapi_msghdr *hdr)
+actcapi_chkhdr(act2000_card *card, actcapi_msghdr *hdr)
 {
 	int i;
 
@@ -99,33 +99,33 @@ actcapi_chkhdr(act2000_card * card, actcapi_msghdr *hdr)
 	for (i = 0; i < num_valid_imsg; i++)
 		if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) &&
 		    (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) {
-			return (i?1:2);
+			return (i ? 1 : 2);
 		}
 	return 0;
 }
 
-#define ACTCAPI_MKHDR(l, c, s) { \
-	skb = alloc_skb(l + 8, GFP_ATOMIC); \
-	if (skb) { \
-	        m = (actcapi_msg *)skb_put(skb, l + 8); \
-		m->hdr.len = l + 8; \
-		m->hdr.applicationID = 1; \
-	        m->hdr.cmd.cmd = c; \
-	        m->hdr.cmd.subcmd = s; \
-	        m->hdr.msgnum = actcapi_nextsmsg(card); \
-	} else m = NULL;\
-}
+#define ACTCAPI_MKHDR(l, c, s) {				\
+		skb = alloc_skb(l + 8, GFP_ATOMIC);		\
+		if (skb) {					\
+			m = (actcapi_msg *)skb_put(skb, l + 8); \
+			m->hdr.len = l + 8;			\
+			m->hdr.applicationID = 1;		\
+			m->hdr.cmd.cmd = c;			\
+			m->hdr.cmd.subcmd = s;			\
+			m->hdr.msgnum = actcapi_nextsmsg(card); \
+		} else m = NULL;				\
+	}
 
-#define ACTCAPI_CHKSKB if (!skb) { \
-	printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
-	return; \
-}
+#define ACTCAPI_CHKSKB if (!skb) {					\
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");	\
+		return;							\
+	}
 
-#define ACTCAPI_QUEUE_TX { \
-	actcapi_debug_msg(skb, 1); \
-	skb_queue_tail(&card->sndq, skb); \
-	act2000_schedule_tx(card); \
-}
+#define ACTCAPI_QUEUE_TX {				\
+		actcapi_debug_msg(skb, 1);		\
+		skb_queue_tail(&card->sndq, skb);	\
+		act2000_schedule_tx(card);		\
+	}
 
 int
 actcapi_listen_req(act2000_card *card)
@@ -138,16 +138,16 @@ actcapi_listen_req(act2000_card *card)
 	for (i = 0; i < ACT2000_BCH; i++)
 		eazmask |= card->bch[i].eazmask;
 	ACTCAPI_MKHDR(9, 0x05, 0x00);
-        if (!skb) {
-                printk(KERN_WARNING "actcapi: alloc_skb failed\n");
-                return -ENOMEM;
-        }
+	if (!skb) {
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");
+		return -ENOMEM;
+	}
 	m->msg.listen_req.controller = 0;
 	m->msg.listen_req.infomask = 0x3f; /* All information */
 	m->msg.listen_req.eazmask = eazmask;
-	m->msg.listen_req.simask = (eazmask)?0x86:0; /* All SI's  */
+	m->msg.listen_req.simask = (eazmask) ? 0x86 : 0; /* All SI's  */
 	ACTCAPI_QUEUE_TX;
-        return 0;
+	return 0;
 }
 
 int
@@ -159,7 +159,7 @@ actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone,
 
 	ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00);
 	if (!skb) {
-                printk(KERN_WARNING "actcapi: alloc_skb failed\n");
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");
 		chan->fsm_state = ACT2000_STATE_NULL;
 		return -ENOMEM;
 	}
@@ -168,7 +168,7 @@ actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone,
 	m->msg.connect_req.infomask = 0x3f;
 	m->msg.connect_req.si1 = si1;
 	m->msg.connect_req.si2 = si2;
-	m->msg.connect_req.eaz = eaz?eaz:'0';
+	m->msg.connect_req.eaz = eaz ? eaz : '0';
 	m->msg.connect_req.addr.len = strlen(phone) + 1;
 	m->msg.connect_req.addr.tnp = 0x81;
 	memcpy(m->msg.connect_req.addr.num, phone, strlen(phone));
@@ -203,21 +203,21 @@ actcapi_manufacturer_req_net(act2000_card *card)
 	struct sk_buff *skb;
 
 	ACTCAPI_MKHDR(5, 0xff, 0x00);
-        if (!skb) {
-                printk(KERN_WARNING "actcapi: alloc_skb failed\n");
-                return -ENOMEM;
-        }
+	if (!skb) {
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");
+		return -ENOMEM;
+	}
 	m->msg.manufacturer_req_net.manuf_msg = 0x11;
 	m->msg.manufacturer_req_net.controller = 1;
-	m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO)?1:0;
+	m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO) ? 1 : 0;
 	ACTCAPI_QUEUE_TX;
 	printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n",
-	       card->interface.id, (card->ptype == ISDN_PTYPE_EURO)?"euro":"1tr6");
+	       card->interface.id, (card->ptype == ISDN_PTYPE_EURO) ? "euro" : "1tr6");
 	card->interface.features &=
 		~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6);
 	card->interface.features |=
-		((card->ptype == ISDN_PTYPE_EURO)?ISDN_FEATURE_P_EURO:ISDN_FEATURE_P_1TR6);
-        return 0;
+		((card->ptype == ISDN_PTYPE_EURO) ? ISDN_FEATURE_P_EURO : ISDN_FEATURE_P_1TR6);
+	return 0;
 }
 
 /*
@@ -231,16 +231,16 @@ actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
 	struct sk_buff *skb;
 
 	ACTCAPI_MKHDR(8, 0xff, 0x00);
-        if (!skb) {
+	if (!skb) {
 
-                printk(KERN_WARNING "actcapi: alloc_skb failed\n");
-                return -ENOMEM;
-        }
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");
+		return -ENOMEM;
+	}
 	m->msg.manufacturer_req_v42.manuf_msg = 0x10;
 	m->msg.manufacturer_req_v42.controller = 0;
-	m->msg.manufacturer_req_v42.v42control = (arg?1:0);
+	m->msg.manufacturer_req_v42.v42control = (arg ? 1 : 0);
 	ACTCAPI_QUEUE_TX;
-        return 0;
+	return 0;
 }
 #endif  /*  0  */
 
@@ -254,15 +254,15 @@ actcapi_manufacturer_req_errh(act2000_card *card)
 	struct sk_buff *skb;
 
 	ACTCAPI_MKHDR(4, 0xff, 0x00);
-        if (!skb) {
+	if (!skb) {
 
-                printk(KERN_WARNING "actcapi: alloc_skb failed\n");
-                return -ENOMEM;
-        }
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");
+		return -ENOMEM;
+	}
 	m->msg.manufacturer_req_err.manuf_msg = 0x03;
 	m->msg.manufacturer_req_err.controller = 0;
 	ACTCAPI_QUEUE_TX;
-        return 0;
+	return 0;
 }
 
 /*
@@ -295,7 +295,7 @@ actcapi_manufacturer_req_msn(act2000_card *card)
 		}
 		p = p->next;
 	}
-        return 0;
+	return 0;
 }
 
 void
@@ -311,24 +311,24 @@ actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan)
 	       sizeof(m->msg.select_b2_protocol_req.dlpd));
 	m->msg.select_b2_protocol_req.dlpd.len = 6;
 	switch (chan->l2prot) {
-		case ISDN_PROTO_L2_TRANS:
-			m->msg.select_b2_protocol_req.protocol = 0x03;
-			m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
-			break;
-		case ISDN_PROTO_L2_HDLC:
-			m->msg.select_b2_protocol_req.protocol = 0x02;
-			m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
-			break;
-		case ISDN_PROTO_L2_X75I:
-		case ISDN_PROTO_L2_X75UI:
-		case ISDN_PROTO_L2_X75BUI:
-			m->msg.select_b2_protocol_req.protocol = 0x01;
-			m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
-			m->msg.select_b2_protocol_req.dlpd.laa = 3;
-			m->msg.select_b2_protocol_req.dlpd.lab = 1;
-			m->msg.select_b2_protocol_req.dlpd.win = 7;
-			m->msg.select_b2_protocol_req.dlpd.modulo = 8;
-			break;
+	case ISDN_PROTO_L2_TRANS:
+		m->msg.select_b2_protocol_req.protocol = 0x03;
+		m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
+		break;
+	case ISDN_PROTO_L2_HDLC:
+		m->msg.select_b2_protocol_req.protocol = 0x02;
+		m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
+		break;
+	case ISDN_PROTO_L2_X75I:
+	case ISDN_PROTO_L2_X75UI:
+	case ISDN_PROTO_L2_X75BUI:
+		m->msg.select_b2_protocol_req.protocol = 0x01;
+		m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
+		m->msg.select_b2_protocol_req.dlpd.laa = 3;
+		m->msg.select_b2_protocol_req.dlpd.lab = 1;
+		m->msg.select_b2_protocol_req.dlpd.win = 7;
+		m->msg.select_b2_protocol_req.dlpd.modulo = 8;
+		break;
 	}
 	ACTCAPI_QUEUE_TX;
 }
@@ -345,11 +345,11 @@ actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan)
 	memset(&m->msg.select_b3_protocol_req.ncpd, 0,
 	       sizeof(m->msg.select_b3_protocol_req.ncpd));
 	switch (chan->l3prot) {
-		case ISDN_PROTO_L3_TRANS:
-			m->msg.select_b3_protocol_req.protocol = 0x04;
-			m->msg.select_b3_protocol_req.ncpd.len = 13;
-			m->msg.select_b3_protocol_req.ncpd.modulo = 8;
-			break;
+	case ISDN_PROTO_L3_TRANS:
+		m->msg.select_b3_protocol_req.protocol = 0x04;
+		m->msg.select_b3_protocol_req.ncpd.len = 13;
+		m->msg.select_b3_protocol_req.ncpd.modulo = 8;
+		break;
 	}
 	ACTCAPI_QUEUE_TX;
 }
@@ -434,7 +434,7 @@ actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause
 	actcapi_msg *m;
 	struct sk_buff *skb;
 
-	ACTCAPI_MKHDR((rejectcause?3:17), 0x82, 0x03);
+	ACTCAPI_MKHDR((rejectcause ? 3 : 17), 0x82, 0x03);
 	ACTCAPI_CHKSKB;
 	m->msg.connect_b3_resp.ncci = chan->ncci;
 	m->msg.connect_b3_resp.rejectcause = rejectcause;
@@ -563,10 +563,10 @@ actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) {
 	blocknr = msg->msg.data_b3_ind.blocknr;
 	skb_pull(skb, 19);
 	card->interface.rcvcallb_skb(card->myid, chan, skb);
-        if (!(skb = alloc_skb(11, GFP_ATOMIC))) {
-                printk(KERN_WARNING "actcapi: alloc_skb failed\n");
-                return 1;
-        }
+	if (!(skb = alloc_skb(11, GFP_ATOMIC))) {
+		printk(KERN_WARNING "actcapi: alloc_skb failed\n");
+		return 1;
+	}
 	msg = (actcapi_msg *)skb_put(skb, 11);
 	msg->hdr.len = 11;
 	msg->hdr.applicationID = 1;
@@ -595,34 +595,34 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
 	spin_lock_irqsave(&card->lock, flags);
 	skb = skb_peek(&card->ackq);
 	spin_unlock_irqrestore(&card->lock, flags);
-        if (!skb) {
+	if (!skb) {
 		printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
 		return 0;
 	}
-        tmp = skb;
-        while (1) {
-                m = (actcapi_msg *)tmp->data;
-                if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
+	tmp = skb;
+	while (1) {
+		m = (actcapi_msg *)tmp->data;
+		if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
 		    (m->msg.data_b3_req.blocknr == blocknr)) {
 			/* found corresponding DATA_B3_REQ */
-                        skb_unlink(tmp, &card->ackq);
+			skb_unlink(tmp, &card->ackq);
 			chan->queued -= m->msg.data_b3_req.datalen;
 			if (m->msg.data_b3_req.flags)
 				ret = m->msg.data_b3_req.datalen;
 			dev_kfree_skb(tmp);
 			if (chan->queued < 0)
 				chan->queued = 0;
-                        return ret;
-                }
-                spin_lock_irqsave(&card->lock, flags);
-                tmp = skb_peek((struct sk_buff_head *)tmp);
-                spin_unlock_irqrestore(&card->lock, flags);
-                if ((tmp == skb) || (tmp == NULL)) {
+			return ret;
+		}
+		spin_lock_irqsave(&card->lock, flags);
+		tmp = skb_peek((struct sk_buff_head *)tmp);
+		spin_unlock_irqrestore(&card->lock, flags);
+		if ((tmp == skb) || (tmp == NULL)) {
 			/* reached end of queue */
 			printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
-                        return 0;
+			return 0;
 		}
-        }
+	}
 }
 
 void
@@ -644,294 +644,294 @@ actcapi_dispatch(struct work_struct *work)
 		msg = (actcapi_msg *)skb->data;
 		ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd);
 		switch (ccmd) {
-			case 0x8602:
-				/* DATA_B3_IND */
-				if (actcapi_data_b3_ind(card, skb))
-					return;
-				break;
-			case 0x8601:
-				/* DATA_B3_CONF */
-				chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
-				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
-					if (msg->msg.data_b3_conf.info != 0)
-						printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
-						       msg->msg.data_b3_conf.info);
-					len = handle_ack(card, &card->bch[chan],
-							 msg->msg.data_b3_conf.blocknr);
-					if (len) {
+		case 0x8602:
+			/* DATA_B3_IND */
+			if (actcapi_data_b3_ind(card, skb))
+				return;
+			break;
+		case 0x8601:
+			/* DATA_B3_CONF */
+			chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
+			if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
+				if (msg->msg.data_b3_conf.info != 0)
+					printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
+					       msg->msg.data_b3_conf.info);
+				len = handle_ack(card, &card->bch[chan],
+						 msg->msg.data_b3_conf.blocknr);
+				if (len) {
+					cmd.driver = card->myid;
+					cmd.command = ISDN_STAT_BSENT;
+					cmd.arg = chan;
+					cmd.parm.length = len;
+					card->interface.statcallb(&cmd);
+				}
+			}
+			break;
+		case 0x0201:
+			/* CONNECT_CONF */
+			chan = find_dialing(card, msg->hdr.msgnum);
+			if (chan >= 0) {
+				if (msg->msg.connect_conf.info) {
+					card->bch[chan].fsm_state = ACT2000_STATE_NULL;
+					cmd.driver = card->myid;
+					cmd.command = ISDN_STAT_DHUP;
+					cmd.arg = chan;
+					card->interface.statcallb(&cmd);
+				} else {
+					card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
+					card->bch[chan].plci = msg->msg.connect_conf.plci;
+				}
+			}
+			break;
+		case 0x0202:
+			/* CONNECT_IND */
+			chan = new_plci(card, msg->msg.connect_ind.plci);
+			if (chan < 0) {
+				ctmp = (act2000_chan *)tmp;
+				ctmp->plci = msg->msg.connect_ind.plci;
+				actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
+			} else {
+				card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
+				cmd.driver = card->myid;
+				cmd.command = ISDN_STAT_ICALL;
+				cmd.arg = chan;
+				cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
+				cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
+				if (card->ptype == ISDN_PTYPE_EURO)
+					strcpy(cmd.parm.setup.eazmsn,
+					       act2000_find_eaz(card, msg->msg.connect_ind.eaz));
+				else {
+					cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
+					cmd.parm.setup.eazmsn[1] = 0;
+				}
+				memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
+				memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
+				       msg->msg.connect_ind.addr.len - 1);
+				cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
+				cmd.parm.setup.screen = 0;
+				if (card->interface.statcallb(&cmd) == 2)
+					actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
+			}
+			break;
+		case 0x0302:
+			/* CONNECT_ACTIVE_IND */
+			chan = find_plci(card, msg->msg.connect_active_ind.plci);
+			if (chan >= 0)
+				switch (card->bch[chan].fsm_state) {
+				case ACT2000_STATE_IWAIT:
+					actcapi_connect_active_resp(card, &card->bch[chan]);
+					break;
+				case ACT2000_STATE_OWAIT:
+					actcapi_connect_active_resp(card, &card->bch[chan]);
+					actcapi_select_b2_protocol_req(card, &card->bch[chan]);
+					break;
+				}
+			break;
+		case 0x8202:
+			/* CONNECT_B3_IND */
+			chan = find_plci(card, msg->msg.connect_b3_ind.plci);
+			if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
+				card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
+				actcapi_connect_b3_resp(card, &card->bch[chan], 0);
+			} else {
+				ctmp = (act2000_chan *)tmp;
+				ctmp->ncci = msg->msg.connect_b3_ind.ncci;
+				actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
+			}
+			break;
+		case 0x8302:
+			/* CONNECT_B3_ACTIVE_IND */
+			chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
+			if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
+				actcapi_connect_b3_active_resp(card, &card->bch[chan]);
+				cmd.driver = card->myid;
+				cmd.command = ISDN_STAT_BCONN;
+				cmd.arg = chan;
+				card->interface.statcallb(&cmd);
+			}
+			break;
+		case 0x8402:
+			/* DISCONNECT_B3_IND */
+			chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
+			if (chan >= 0) {
+				ctmp = &card->bch[chan];
+				actcapi_disconnect_b3_resp(card, ctmp);
+				switch (ctmp->fsm_state) {
+				case ACT2000_STATE_ACTIVE:
+					ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
+					cmd.driver = card->myid;
+					cmd.command = ISDN_STAT_BHUP;
+					cmd.arg = chan;
+					card->interface.statcallb(&cmd);
+					break;
+				case ACT2000_STATE_BHWAIT2:
+					actcapi_disconnect_req(card, ctmp);
+					ctmp->fsm_state = ACT2000_STATE_DHWAIT;
+					cmd.driver = card->myid;
+					cmd.command = ISDN_STAT_BHUP;
+					cmd.arg = chan;
+					card->interface.statcallb(&cmd);
+					break;
+				}
+			}
+			break;
+		case 0x0402:
+			/* DISCONNECT_IND */
+			chan = find_plci(card, msg->msg.disconnect_ind.plci);
+			if (chan >= 0) {
+				ctmp = &card->bch[chan];
+				actcapi_disconnect_resp(card, ctmp);
+				ctmp->fsm_state = ACT2000_STATE_NULL;
+				cmd.driver = card->myid;
+				cmd.command = ISDN_STAT_DHUP;
+				cmd.arg = chan;
+				card->interface.statcallb(&cmd);
+			} else {
+				ctmp = (act2000_chan *)tmp;
+				ctmp->plci = msg->msg.disconnect_ind.plci;
+				actcapi_disconnect_resp(card, ctmp);
+			}
+			break;
+		case 0x4001:
+			/* SELECT_B2_PROTOCOL_CONF */
+			chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
+			if (chan >= 0)
+				switch (card->bch[chan].fsm_state) {
+				case ACT2000_STATE_ICALL:
+				case ACT2000_STATE_OWAIT:
+					ctmp = &card->bch[chan];
+					if (msg->msg.select_b2_protocol_conf.info == 0)
+						actcapi_select_b3_protocol_req(card, ctmp);
+					else {
+						ctmp->fsm_state = ACT2000_STATE_NULL;
 						cmd.driver = card->myid;
-						cmd.command = ISDN_STAT_BSENT;
+						cmd.command = ISDN_STAT_DHUP;
 						cmd.arg = chan;
-						cmd.parm.length = len;
 						card->interface.statcallb(&cmd);
 					}
+					break;
 				}
-				break;
-			case 0x0201:
-				/* CONNECT_CONF */
-				chan = find_dialing(card, msg->hdr.msgnum);
-				if (chan >= 0) {
-					if (msg->msg.connect_conf.info) {
-						card->bch[chan].fsm_state = ACT2000_STATE_NULL;
+			break;
+		case 0x8001:
+			/* SELECT_B3_PROTOCOL_CONF */
+			chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
+			if (chan >= 0)
+				switch (card->bch[chan].fsm_state) {
+				case ACT2000_STATE_ICALL:
+				case ACT2000_STATE_OWAIT:
+					ctmp = &card->bch[chan];
+					if (msg->msg.select_b3_protocol_conf.info == 0)
+						actcapi_listen_b3_req(card, ctmp);
+					else {
+						ctmp->fsm_state = ACT2000_STATE_NULL;
 						cmd.driver = card->myid;
 						cmd.command = ISDN_STAT_DHUP;
 						cmd.arg = chan;
 						card->interface.statcallb(&cmd);
-					} else {
-						card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
-						card->bch[chan].plci = msg->msg.connect_conf.plci;
 					}
 				}
-				break;
-			case 0x0202:
-				/* CONNECT_IND */
-				chan = new_plci(card, msg->msg.connect_ind.plci);
-				if (chan < 0) {
-					ctmp = (act2000_chan *)tmp;
-					ctmp->plci = msg->msg.connect_ind.plci;
-					actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
-				} else {
-					card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
-					cmd.driver = card->myid;
-					cmd.command = ISDN_STAT_ICALL;
-					cmd.arg = chan;
-					cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
-					cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
-					if (card->ptype == ISDN_PTYPE_EURO)
-						strcpy(cmd.parm.setup.eazmsn,
-						       act2000_find_eaz(card, msg->msg.connect_ind.eaz));
+			break;
+		case 0x8101:
+			/* LISTEN_B3_CONF */
+			chan = find_plci(card, msg->msg.listen_b3_conf.plci);
+			if (chan >= 0)
+				switch (card->bch[chan].fsm_state) {
+				case ACT2000_STATE_ICALL:
+					ctmp = &card->bch[chan];
+					if (msg->msg.listen_b3_conf.info == 0)
+						actcapi_connect_resp(card, ctmp, 0);
 					else {
-						cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
-						cmd.parm.setup.eazmsn[1] = 0;
-					}
-					memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
-					memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
-					       msg->msg.connect_ind.addr.len - 1);
-					cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
-					cmd.parm.setup.screen = 0;
-					if (card->interface.statcallb(&cmd) == 2)
-						actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
-				}
-				break;
-			case 0x0302:
-				/* CONNECT_ACTIVE_IND */
-				chan = find_plci(card, msg->msg.connect_active_ind.plci);
-				if (chan >= 0)
-					switch (card->bch[chan].fsm_state) {
-						case ACT2000_STATE_IWAIT:
-							actcapi_connect_active_resp(card, &card->bch[chan]);
-							break;
-						case ACT2000_STATE_OWAIT:
-							actcapi_connect_active_resp(card, &card->bch[chan]);
-							actcapi_select_b2_protocol_req(card, &card->bch[chan]);
-							break;
+						ctmp->fsm_state = ACT2000_STATE_NULL;
+						cmd.driver = card->myid;
+						cmd.command = ISDN_STAT_DHUP;
+						cmd.arg = chan;
+						card->interface.statcallb(&cmd);
 					}
-				break;
-			case 0x8202:
-				/* CONNECT_B3_IND */
-				chan = find_plci(card, msg->msg.connect_b3_ind.plci);
-				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
-					card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
-					actcapi_connect_b3_resp(card, &card->bch[chan], 0);
-				} else {
-					ctmp = (act2000_chan *)tmp;
-					ctmp->ncci = msg->msg.connect_b3_ind.ncci;
-					actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
-				}
-				break;
-			case 0x8302:
-				/* CONNECT_B3_ACTIVE_IND */
-				chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
-				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
-					actcapi_connect_b3_active_resp(card, &card->bch[chan]);
-					cmd.driver = card->myid;
-					cmd.command = ISDN_STAT_BCONN;
-					cmd.arg = chan;
-					card->interface.statcallb(&cmd);
-				}
-				break;
-			case 0x8402:
-				/* DISCONNECT_B3_IND */
-				chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
-				if (chan >= 0) {
+					break;
+				case ACT2000_STATE_OWAIT:
 					ctmp = &card->bch[chan];
-					actcapi_disconnect_b3_resp(card, ctmp);
-					switch (ctmp->fsm_state) {
-						case ACT2000_STATE_ACTIVE:
-							ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
-							cmd.driver = card->myid;
-							cmd.command = ISDN_STAT_BHUP;
-							cmd.arg = chan;
-							card->interface.statcallb(&cmd);
-							break;
-						case ACT2000_STATE_BHWAIT2:
-							actcapi_disconnect_req(card, ctmp);
-							ctmp->fsm_state = ACT2000_STATE_DHWAIT;
-							cmd.driver = card->myid;
-							cmd.command = ISDN_STAT_BHUP;
-							cmd.arg = chan;
-							card->interface.statcallb(&cmd);
-							break;
+					if (msg->msg.listen_b3_conf.info == 0) {
+						actcapi_connect_b3_req(card, ctmp);
+						ctmp->fsm_state = ACT2000_STATE_OBWAIT;
+						cmd.driver = card->myid;
+						cmd.command = ISDN_STAT_DCONN;
+						cmd.arg = chan;
+						card->interface.statcallb(&cmd);
+					} else {
+						ctmp->fsm_state = ACT2000_STATE_NULL;
+						cmd.driver = card->myid;
+						cmd.command = ISDN_STAT_DHUP;
+						cmd.arg = chan;
+						card->interface.statcallb(&cmd);
 					}
+					break;
 				}
-				break;
-			case 0x0402:
-				/* DISCONNECT_IND */
-				chan = find_plci(card, msg->msg.disconnect_ind.plci);
-				if (chan >= 0) {
-					ctmp = &card->bch[chan];
-					actcapi_disconnect_resp(card, ctmp);
+			break;
+		case 0x8201:
+			/* CONNECT_B3_CONF */
+			chan = find_plci(card, msg->msg.connect_b3_conf.plci);
+			if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
+				ctmp = &card->bch[chan];
+				if (msg->msg.connect_b3_conf.info) {
 					ctmp->fsm_state = ACT2000_STATE_NULL;
 					cmd.driver = card->myid;
 					cmd.command = ISDN_STAT_DHUP;
 					cmd.arg = chan;
 					card->interface.statcallb(&cmd);
 				} else {
-					ctmp = (act2000_chan *)tmp;
-					ctmp->plci = msg->msg.disconnect_ind.plci;
-					actcapi_disconnect_resp(card, ctmp);
+					ctmp->ncci = msg->msg.connect_b3_conf.ncci;
+					ctmp->fsm_state = ACT2000_STATE_BWAIT;
 				}
-				break;
-			case 0x4001:
-				/* SELECT_B2_PROTOCOL_CONF */
-				chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
-				if (chan >= 0)
-					switch (card->bch[chan].fsm_state) {
-						case ACT2000_STATE_ICALL:
-						case ACT2000_STATE_OWAIT:
-							ctmp = &card->bch[chan];
-							if (msg->msg.select_b2_protocol_conf.info == 0)
-								actcapi_select_b3_protocol_req(card, ctmp);
-							else {
-								ctmp->fsm_state = ACT2000_STATE_NULL;
-								cmd.driver = card->myid;
-								cmd.command = ISDN_STAT_DHUP;
-								cmd.arg = chan;
-								card->interface.statcallb(&cmd);
-							}
-							break;
-					}
-				break;
-			case 0x8001:
-				/* SELECT_B3_PROTOCOL_CONF */
-				chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
-				if (chan >= 0)
-					switch (card->bch[chan].fsm_state) {
-						case ACT2000_STATE_ICALL:
-						case ACT2000_STATE_OWAIT:
-							ctmp = &card->bch[chan];
-							if (msg->msg.select_b3_protocol_conf.info == 0)
-								actcapi_listen_b3_req(card, ctmp);
-							else {
-								ctmp->fsm_state = ACT2000_STATE_NULL;
-								cmd.driver = card->myid;
-								cmd.command = ISDN_STAT_DHUP;
-								cmd.arg = chan;
-								card->interface.statcallb(&cmd);
-							}
-					}
-				break;
-			case 0x8101:
-				/* LISTEN_B3_CONF */
-				chan = find_plci(card, msg->msg.listen_b3_conf.plci);
-				if (chan >= 0)
-					switch (card->bch[chan].fsm_state) {
-						case ACT2000_STATE_ICALL:
-							ctmp = &card->bch[chan];
-							if (msg->msg.listen_b3_conf.info == 0)
-								actcapi_connect_resp(card, ctmp, 0);
-							else {
-								ctmp->fsm_state = ACT2000_STATE_NULL;
-								cmd.driver = card->myid;
-								cmd.command = ISDN_STAT_DHUP;
-								cmd.arg = chan;
-								card->interface.statcallb(&cmd);
-							}
-							break;
-						case ACT2000_STATE_OWAIT:
-							ctmp = &card->bch[chan];
-							if (msg->msg.listen_b3_conf.info == 0) {
-								actcapi_connect_b3_req(card, ctmp);
-								ctmp->fsm_state = ACT2000_STATE_OBWAIT;
-								cmd.driver = card->myid;
-								cmd.command = ISDN_STAT_DCONN;
-								cmd.arg = chan;
-								card->interface.statcallb(&cmd);
-							} else {
-								ctmp->fsm_state = ACT2000_STATE_NULL;
-								cmd.driver = card->myid;
-								cmd.command = ISDN_STAT_DHUP;
-								cmd.arg = chan;
-								card->interface.statcallb(&cmd);
-							}
-							break;
-					}
-				break;
-			case 0x8201:
-				/* CONNECT_B3_CONF */
-				chan = find_plci(card, msg->msg.connect_b3_conf.plci);
-				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
-					ctmp = &card->bch[chan];
-					if (msg->msg.connect_b3_conf.info) {
-						ctmp->fsm_state = ACT2000_STATE_NULL;
+			}
+			break;
+		case 0x8401:
+			/* DISCONNECT_B3_CONF */
+			chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
+			if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
+				card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
+			break;
+		case 0x0702:
+			/* INFO_IND */
+			chan = find_plci(card, msg->msg.info_ind.plci);
+			if (chan >= 0)
+				/* TODO: Eval Charging info / cause */
+				actcapi_info_resp(card, &card->bch[chan]);
+			break;
+		case 0x0401:
+			/* LISTEN_CONF */
+		case 0x0501:
+			/* LISTEN_CONF */
+		case 0xff01:
+			/* MANUFACTURER_CONF */
+			break;
+		case 0xff02:
+			/* MANUFACTURER_IND */
+			if (msg->msg.manuf_msg == 3) {
+				memset(tmp, 0, sizeof(tmp));
+				strncpy(tmp,
+					&msg->msg.manufacturer_ind_err.errstring,
+					msg->hdr.len - 16);
+				if (msg->msg.manufacturer_ind_err.errcode)
+					printk(KERN_WARNING "act2000: %s\n", tmp);
+				else {
+					printk(KERN_DEBUG "act2000: %s\n", tmp);
+					if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
+					    (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
+						card->flags |= ACT2000_FLAGS_RUNNING;
+						cmd.command = ISDN_STAT_RUN;
 						cmd.driver = card->myid;
-						cmd.command = ISDN_STAT_DHUP;
-						cmd.arg = chan;
+						cmd.arg = 0;
+						actcapi_manufacturer_req_net(card);
+						actcapi_manufacturer_req_msn(card);
+						actcapi_listen_req(card);
 						card->interface.statcallb(&cmd);
-					} else {
-						ctmp->ncci = msg->msg.connect_b3_conf.ncci;
-						ctmp->fsm_state = ACT2000_STATE_BWAIT;
 					}
 				}
-				break;
-			case 0x8401:
-				/* DISCONNECT_B3_CONF */
-				chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
-				if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
-					card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
-				break;
-			case 0x0702:
-				/* INFO_IND */
-				chan = find_plci(card, msg->msg.info_ind.plci);
-				if (chan >= 0)
-					/* TODO: Eval Charging info / cause */
-					actcapi_info_resp(card, &card->bch[chan]);
-				break;
-			case 0x0401:
-				/* LISTEN_CONF */
-			case 0x0501:
-				/* LISTEN_CONF */
-			case 0xff01:
-				/* MANUFACTURER_CONF */
-				break;
-			case 0xff02:
-				/* MANUFACTURER_IND */
-				if (msg->msg.manuf_msg == 3) {
-					memset(tmp, 0, sizeof(tmp));
-					strncpy(tmp,
-						&msg->msg.manufacturer_ind_err.errstring,
-						msg->hdr.len - 16);
-					if (msg->msg.manufacturer_ind_err.errcode)
-						printk(KERN_WARNING "act2000: %s\n", tmp);
-					else {
-						printk(KERN_DEBUG "act2000: %s\n", tmp);
-						if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
-						    (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
-							card->flags |= ACT2000_FLAGS_RUNNING;
-							cmd.command = ISDN_STAT_RUN;
-							cmd.driver = card->myid;
-							cmd.arg = 0;
-							actcapi_manufacturer_req_net(card);
-							actcapi_manufacturer_req_msn(card);
-							actcapi_listen_req(card);
-							card->interface.statcallb(&cmd);
-						}
-					}
-				}
-				break;
-			default:
-				printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
-				break;
+			}
+			break;
+		default:
+			printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
+			break;
 		}
 		dev_kfree_skb(skb);
 	}
@@ -1015,7 +1015,7 @@ actcapi_debug_msg(struct sk_buff *skb, int direction)
 	char *descr;
 	int i;
 	char tmp[170];
-	
+
 #ifndef DEBUG_DATA_MSG
 	if (msg->hdr.cmd.cmd == 0x86)
 		return;
@@ -1030,151 +1030,151 @@ actcapi_debug_msg(struct sk_buff *skb, int direction)
 			descr = valid_msg[i].description;
 			break;
 		}
-	printk(KERN_DEBUG "%s %s msg\n", direction?"Outgoing":"Incoming", descr);
+	printk(KERN_DEBUG "%s %s msg\n", direction ? "Outgoing" : "Incoming", descr);
 	printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID);
 	printk(KERN_DEBUG " Len    = %d\n", msg->hdr.len);
 	printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum);
 	printk(KERN_DEBUG " Cmd    = 0x%02x\n", msg->hdr.cmd.cmd);
 	printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd);
 	switch (i) {
-		case 0:
-			/* DATA B3 IND */
-			printk(KERN_DEBUG " BLOCK = 0x%02x\n",
-			       msg->msg.data_b3_ind.blocknr);
-			break;
-		case 2:
-			/* CONNECT CONF */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.connect_conf.plci);
-			printk(KERN_DEBUG " Info = 0x%04x\n",
-			       msg->msg.connect_conf.info);
-			break;
+	case 0:
+		/* DATA B3 IND */
+		printk(KERN_DEBUG " BLOCK = 0x%02x\n",
+		       msg->msg.data_b3_ind.blocknr);
+		break;
+	case 2:
+		/* CONNECT CONF */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.connect_conf.plci);
+		printk(KERN_DEBUG " Info = 0x%04x\n",
+		       msg->msg.connect_conf.info);
+		break;
+	case 3:
+		/* CONNECT IND */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.connect_ind.plci);
+		printk(KERN_DEBUG " Contr = %d\n",
+		       msg->msg.connect_ind.controller);
+		printk(KERN_DEBUG " SI1   = %d\n",
+		       msg->msg.connect_ind.si1);
+		printk(KERN_DEBUG " SI2   = %d\n",
+		       msg->msg.connect_ind.si2);
+		printk(KERN_DEBUG " EAZ   = '%c'\n",
+		       msg->msg.connect_ind.eaz);
+		actcapi_debug_caddr(&msg->msg.connect_ind.addr);
+		break;
+	case 5:
+		/* CONNECT ACTIVE IND */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.connect_active_ind.plci);
+		actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
+		break;
+	case 8:
+		/* LISTEN CONF */
+		printk(KERN_DEBUG " Contr = %d\n",
+		       msg->msg.listen_conf.controller);
+		printk(KERN_DEBUG " Info = 0x%04x\n",
+		       msg->msg.listen_conf.info);
+		break;
+	case 11:
+		/* INFO IND */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.info_ind.plci);
+		printk(KERN_DEBUG " Imsk = 0x%04x\n",
+		       msg->msg.info_ind.nr.mask);
+		if (msg->hdr.len > 12) {
+			int l = msg->hdr.len - 12;
+			int j;
+			char *p = tmp;
+			for (j = 0; j < l; j++)
+				p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
+			printk(KERN_DEBUG " D = '%s'\n", tmp);
+		}
+		break;
+	case 14:
+		/* SELECT B2 PROTOCOL CONF */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.select_b2_protocol_conf.plci);
+		printk(KERN_DEBUG " Info = 0x%04x\n",
+		       msg->msg.select_b2_protocol_conf.info);
+		break;
+	case 15:
+		/* SELECT B3 PROTOCOL CONF */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.select_b3_protocol_conf.plci);
+		printk(KERN_DEBUG " Info = 0x%04x\n",
+		       msg->msg.select_b3_protocol_conf.info);
+		break;
+	case 16:
+		/* LISTEN B3 CONF */
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.listen_b3_conf.plci);
+		printk(KERN_DEBUG " Info = 0x%04x\n",
+		       msg->msg.listen_b3_conf.info);
+		break;
+	case 18:
+		/* CONNECT B3 IND */
+		printk(KERN_DEBUG " NCCI = 0x%04x\n",
+		       msg->msg.connect_b3_ind.ncci);
+		printk(KERN_DEBUG " PLCI = 0x%04x\n",
+		       msg->msg.connect_b3_ind.plci);
+		actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
+		break;
+	case 19:
+		/* CONNECT B3 ACTIVE IND */
+		printk(KERN_DEBUG " NCCI = 0x%04x\n",
+		       msg->msg.connect_b3_active_ind.ncci);
+		actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
+		break;
+	case 26:
+		/* MANUFACTURER IND */
+		printk(KERN_DEBUG " Mmsg = 0x%02x\n",
+		       msg->msg.manufacturer_ind_err.manuf_msg);
+		switch (msg->msg.manufacturer_ind_err.manuf_msg) {
 		case 3:
-			/* CONNECT IND */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.connect_ind.plci);
 			printk(KERN_DEBUG " Contr = %d\n",
-			       msg->msg.connect_ind.controller);
-			printk(KERN_DEBUG " SI1   = %d\n",
-			       msg->msg.connect_ind.si1);
-			printk(KERN_DEBUG " SI2   = %d\n",
-			       msg->msg.connect_ind.si2);
-			printk(KERN_DEBUG " EAZ   = '%c'\n",
-			       msg->msg.connect_ind.eaz);
-			actcapi_debug_caddr(&msg->msg.connect_ind.addr);
-			break;
-		case 5:
-			/* CONNECT ACTIVE IND */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.connect_active_ind.plci);
-			actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
-			break;
-		case 8:
-			/* LISTEN CONF */
-			printk(KERN_DEBUG " Contr = %d\n",
-			       msg->msg.listen_conf.controller);
-			printk(KERN_DEBUG " Info = 0x%04x\n",
-			       msg->msg.listen_conf.info);
-			break;
-		case 11:
-			/* INFO IND */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.info_ind.plci);
-			printk(KERN_DEBUG " Imsk = 0x%04x\n",
-			       msg->msg.info_ind.nr.mask);
-			if (msg->hdr.len > 12) {
-				int l = msg->hdr.len - 12;
-				int j;
-				char *p = tmp;
-				for (j = 0; j < l ; j++)
-					p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
-				printk(KERN_DEBUG " D = '%s'\n", tmp);
-			}
-			break;
-		case 14:
-			/* SELECT B2 PROTOCOL CONF */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.select_b2_protocol_conf.plci);
-			printk(KERN_DEBUG " Info = 0x%04x\n",
-			       msg->msg.select_b2_protocol_conf.info);
-			break;
-		case 15:
-			/* SELECT B3 PROTOCOL CONF */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.select_b3_protocol_conf.plci);
-			printk(KERN_DEBUG " Info = 0x%04x\n",
-			       msg->msg.select_b3_protocol_conf.info);
-			break;
-		case 16:
-			/* LISTEN B3 CONF */
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.listen_b3_conf.plci);
-			printk(KERN_DEBUG " Info = 0x%04x\n",
-			       msg->msg.listen_b3_conf.info);
-			break;
-		case 18:
-			/* CONNECT B3 IND */
-			printk(KERN_DEBUG " NCCI = 0x%04x\n",
-			       msg->msg.connect_b3_ind.ncci);
-			printk(KERN_DEBUG " PLCI = 0x%04x\n",
-			       msg->msg.connect_b3_ind.plci);
-			actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
-			break;
-		case 19:
-			/* CONNECT B3 ACTIVE IND */
-			printk(KERN_DEBUG " NCCI = 0x%04x\n",
-			       msg->msg.connect_b3_active_ind.ncci);
-			actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
-			break;
-		case 26:
-			/* MANUFACTURER IND */
-			printk(KERN_DEBUG " Mmsg = 0x%02x\n",
-			       msg->msg.manufacturer_ind_err.manuf_msg);
-			switch (msg->msg.manufacturer_ind_err.manuf_msg) {
-				case 3:
-					printk(KERN_DEBUG " Contr = %d\n",
-					       msg->msg.manufacturer_ind_err.controller);
-					printk(KERN_DEBUG " Code = 0x%08x\n",
-					       msg->msg.manufacturer_ind_err.errcode);
-					memset(tmp, 0, sizeof(tmp));
-					strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
-						msg->hdr.len - 16);
-					printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
-					break;
-			}
-			break;
-		case 30:
-			/* LISTEN REQ */
-			printk(KERN_DEBUG " Imsk = 0x%08x\n",
-			       msg->msg.listen_req.infomask);
-			printk(KERN_DEBUG " Emsk = 0x%04x\n",
-			       msg->msg.listen_req.eazmask);
-			printk(KERN_DEBUG " Smsk = 0x%04x\n",
-			       msg->msg.listen_req.simask);
-			break;
-		case 35:
-			/* SELECT_B2_PROTOCOL_REQ */
-			printk(KERN_DEBUG " PLCI  = 0x%04x\n",
-			       msg->msg.select_b2_protocol_req.plci);
-			printk(KERN_DEBUG " prot  = 0x%02x\n",
-			       msg->msg.select_b2_protocol_req.protocol);
-			if (msg->hdr.len >= 11)
-				printk(KERN_DEBUG "No dlpd\n");
-			else
-				actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
-			break;
-		case 44:
-			/* CONNECT RESP */
-			printk(KERN_DEBUG " PLCI  = 0x%04x\n",
-			       msg->msg.connect_resp.plci);
-			printk(KERN_DEBUG " CAUSE = 0x%02x\n",
-			       msg->msg.connect_resp.rejectcause);
-			break;
-		case 45:
-			/* CONNECT ACTIVE RESP */
-			printk(KERN_DEBUG " PLCI  = 0x%04x\n",
-			       msg->msg.connect_active_resp.plci);
+			       msg->msg.manufacturer_ind_err.controller);
+			printk(KERN_DEBUG " Code = 0x%08x\n",
+			       msg->msg.manufacturer_ind_err.errcode);
+			memset(tmp, 0, sizeof(tmp));
+			strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
+				msg->hdr.len - 16);
+			printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
 			break;
+		}
+		break;
+	case 30:
+		/* LISTEN REQ */
+		printk(KERN_DEBUG " Imsk = 0x%08x\n",
+		       msg->msg.listen_req.infomask);
+		printk(KERN_DEBUG " Emsk = 0x%04x\n",
+		       msg->msg.listen_req.eazmask);
+		printk(KERN_DEBUG " Smsk = 0x%04x\n",
+		       msg->msg.listen_req.simask);
+		break;
+	case 35:
+		/* SELECT_B2_PROTOCOL_REQ */
+		printk(KERN_DEBUG " PLCI  = 0x%04x\n",
+		       msg->msg.select_b2_protocol_req.plci);
+		printk(KERN_DEBUG " prot  = 0x%02x\n",
+		       msg->msg.select_b2_protocol_req.protocol);
+		if (msg->hdr.len >= 11)
+			printk(KERN_DEBUG "No dlpd\n");
+		else
+			actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
+		break;
+	case 44:
+		/* CONNECT RESP */
+		printk(KERN_DEBUG " PLCI  = 0x%04x\n",
+		       msg->msg.connect_resp.plci);
+		printk(KERN_DEBUG " CAUSE = 0x%02x\n",
+		       msg->msg.connect_resp.rejectcause);
+		break;
+	case 45:
+		/* CONNECT ACTIVE RESP */
+		printk(KERN_DEBUG " PLCI  = 0x%04x\n",
+		       msg->msg.connect_active_resp.plci);
+		break;
 	}
 }
 #endif
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
index e55f6a9..01ccdec 100644
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -4,7 +4,7 @@
  *
  * Author       Fritz Elfert
  * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -46,10 +46,10 @@ typedef struct actcapi_addr {
 typedef  union actcapi_infonr {              /* info number                  */
 	__u16 mask;                          /* info-mask field              */
 	struct bmask {                       /* bit definitions              */
-		unsigned  codes : 3;         /* code set                     */
-		unsigned  rsvd  : 5;         /* reserved                     */
-		unsigned  svind : 1;         /* single, variable length ind. */
-		unsigned  wtype : 7;         /* W-element type               */
+		unsigned  codes:3;           /* code set                     */
+		unsigned  rsvd:5;            /* reserved                     */
+		unsigned  svind:1;           /* single, variable length ind. */
+		unsigned  wtype:7;           /* W-element type               */
 	} bmask;
 } actcapi_infonr;
 
@@ -59,13 +59,13 @@ typedef union  actcapi_infoel {              /* info element                 */
 	__u8 display[40];                    /* display contents             */
 	__u8 uuinfo[40];                     /* User-user info field         */
 	struct cause {                       /* Cause information            */
-		unsigned ext2  : 1;          /* extension                    */
-		unsigned cod   : 2;          /* coding standard              */
-		unsigned spare : 1;          /* spare                        */
-		unsigned loc   : 4;          /* location                     */
-		unsigned ext1  : 1;          /* extension                    */
-		unsigned cval  : 7;          /* Cause value                  */
-	} cause;                     
+		unsigned ext2:1;             /* extension                    */
+		unsigned cod:2;              /* coding standard              */
+		unsigned spare:1;            /* spare                        */
+		unsigned loc:4;              /* location                     */
+		unsigned ext1:1;             /* extension                    */
+		unsigned cval:7;             /* Cause value                  */
+	} cause;
 	struct charge {                      /* Charging information         */
 		__u8 toc;                    /* type of charging info        */
 		__u8 unit[10];               /* charging units               */
@@ -111,14 +111,14 @@ typedef struct actcapi_ncpd {
  * Bit 5-7  = Controller
  * Bit 8-15 = NCCI
  */
-#define MAKE_NCCI(plci,contr,ncci) \
-        ((plci & 0x1f) | ((contr & 0x7) << 5) | ((ncci & 0xff) << 8))
+#define MAKE_NCCI(plci, contr, ncci)					\
+	((plci & 0x1f) | ((contr & 0x7) << 5) | ((ncci & 0xff) << 8))
 
-#define EVAL_NCCI(fakencci,plci,contr,ncci) { \
-	plci  = fakencci & 0x1f; \
-	contr = (fakencci >> 5) & 0x7; \
-	ncci  = (fakencci >> 8) & 0xff; \
-}
+#define EVAL_NCCI(fakencci, plci, contr, ncci) {	\
+		plci  = fakencci & 0x1f;		\
+		contr = (fakencci >> 5) & 0x7;		\
+		ncci  = (fakencci >> 8) & 0xff;		\
+	}
 
 /*
  * Layout of PLCI field in a B3 DATA CAPI message is different from
@@ -128,13 +128,13 @@ typedef struct actcapi_ncpd {
  * Bit 5-7  = Controller
  * Bit 8-15 = reserved (must be 0)
  */
-#define MAKE_PLCI(plci,contr) \
-        ((plci & 0x1f) | ((contr & 0x7) << 5))
+#define MAKE_PLCI(plci, contr)			\
+	((plci & 0x1f) | ((contr & 0x7) << 5))
 
-#define EVAL_PLCI(fakeplci,plci,contr) { \
-	plci  = fakeplci & 0x1f; \
-	contr = (fakeplci >> 5) & 0x7; \
-}
+#define EVAL_PLCI(fakeplci, plci, contr) {	\
+		plci  = fakeplci & 0x1f;	\
+		contr = (fakeplci >> 5) & 0x7;	\
+	}
 
 typedef struct actcapi_msg {
 	actcapi_msghdr hdr;
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index 05ed72c..b4147c0 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -4,7 +4,7 @@
  *
  * Author       Fritz Elfert
  * Copyright    by Fritz Elfert      <fritz@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -21,8 +21,8 @@
 
 static unsigned short act2000_isa_ports[] =
 {
-        0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
-        0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
+	0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
+	0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
 };
 
 static act2000_card *cards = (act2000_card *) NULL;
@@ -33,14 +33,14 @@ static int   act_port = -1;  /* -1 = Autoprobe  */
 static int   act_irq  = -1;
 static char *act_id   = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 
-MODULE_DESCRIPTION(       "ISDN4Linux: Driver for IBM Active 2000 ISDN card");
-MODULE_AUTHOR(            "Fritz Elfert");
-MODULE_LICENSE(           "GPL");
+MODULE_DESCRIPTION("ISDN4Linux: Driver for IBM Active 2000 ISDN card");
+MODULE_AUTHOR("Fritz Elfert");
+MODULE_LICENSE("GPL");
 MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA");
 MODULE_PARM_DESC(membase, "Base port address of first card");
 MODULE_PARM_DESC(act_irq, "IRQ of first card");
-MODULE_PARM_DESC(act_id,  "ID-String of first card");
-module_param(act_bus,  int, 0);
+MODULE_PARM_DESC(act_id, "ID-String of first card");
+module_param(act_bus, int, 0);
 module_param(act_port, int, 0);
 module_param(act_irq, int, 0);
 module_param(act_id, charp, 0);
@@ -51,7 +51,7 @@ static act2000_chan *
 find_channel(act2000_card *card, int channel)
 {
 	if ((channel >= 0) && (channel < ACT2000_BCH))
-        	return &(card->bch[channel]);
+		return &(card->bch[channel]);
 	printk(KERN_WARNING "act2000: Invalid channel %d\n", channel);
 	return NULL;
 }
@@ -84,7 +84,7 @@ act2000_clear_msn(act2000_card *card)
 static __u16
 act2000_find_msn(act2000_card *card, char *msn, int ia5)
 {
-        struct msn_entry *p = card->msn_list;
+	struct msn_entry *p = card->msn_list;
 	__u8 eaz = '0';
 
 	while (p) {
@@ -107,14 +107,14 @@ act2000_find_msn(act2000_card *card, char *msn, int ia5)
 char *
 act2000_find_eaz(act2000_card *card, char eaz)
 {
-        struct msn_entry *p = card->msn_list;
+	struct msn_entry *p = card->msn_list;
 
 	while (p) {
 		if (p->eaz == eaz)
-			return(p->msn);
+			return (p->msn);
 		p = p->next;
 	}
-	return("\0");
+	return ("\0");
 }
 
 /*
@@ -126,11 +126,11 @@ act2000_find_eaz(act2000_card *card, char eaz)
 static int
 act2000_set_msn(act2000_card *card, char *eazmsn)
 {
-        struct msn_entry *p = card->msn_list;
-        struct msn_entry *q = NULL;
+	struct msn_entry *p = card->msn_list;
+	struct msn_entry *q = NULL;
 	unsigned long flags;
 	int i;
-	
+
 	if (!strlen(eazmsn))
 		return 0;
 	if (strlen(eazmsn) > 16)
@@ -138,7 +138,7 @@ act2000_set_msn(act2000_card *card, char *eazmsn)
 	for (i = 0; i < strlen(eazmsn); i++)
 		if (!isdigit(eazmsn[i]))
 			return -EINVAL;
-        if (strlen(eazmsn) == 1) {
+	if (strlen(eazmsn) == 1) {
 		/* Delete a single MSN */
 		while (p) {
 			if (p->eaz == eazmsn[0]) {
@@ -158,7 +158,7 @@ act2000_set_msn(act2000_card *card, char *eazmsn)
 			p = p->next;
 		}
 		return 0;
-        }
+	}
 	/* Add a single MSN */
 	while (p) {
 		/* Found in list, replace MSN */
@@ -198,14 +198,14 @@ act2000_transmit(struct work_struct *work)
 		container_of(work, struct act2000_card, snd_tq);
 
 	switch (card->bus) {
-		case ACT2000_BUS_ISA:
-			act2000_isa_send(card);
-			break;
-		case ACT2000_BUS_PCMCIA:
-		case ACT2000_BUS_MCA:
-		default:
-			printk(KERN_WARNING
-			       "act2000_transmit: Illegal bustype %d\n", card->bus);
+	case ACT2000_BUS_ISA:
+		act2000_isa_send(card);
+		break;
+	case ACT2000_BUS_PCMCIA:
+	case ACT2000_BUS_MCA:
+	default:
+		printk(KERN_WARNING
+		       "act2000_transmit: Illegal bustype %d\n", card->bus);
 	}
 }
 
@@ -216,221 +216,221 @@ act2000_receive(struct work_struct *work)
 		container_of(work, struct act2000_card, poll_tq);
 
 	switch (card->bus) {
-		case ACT2000_BUS_ISA:
-			act2000_isa_receive(card);
-			break;
-		case ACT2000_BUS_PCMCIA:
-		case ACT2000_BUS_MCA:
-		default:
-			printk(KERN_WARNING
-			       "act2000_receive: Illegal bustype %d\n", card->bus);
+	case ACT2000_BUS_ISA:
+		act2000_isa_receive(card);
+		break;
+	case ACT2000_BUS_PCMCIA:
+	case ACT2000_BUS_MCA:
+	default:
+		printk(KERN_WARNING
+		       "act2000_receive: Illegal bustype %d\n", card->bus);
 	}
 }
 
 static void
 act2000_poll(unsigned long data)
 {
-	act2000_card * card = (act2000_card *)data;
+	act2000_card *card = (act2000_card *)data;
 	unsigned long flags;
 
 	act2000_receive(&card->poll_tq);
 	spin_lock_irqsave(&card->lock, flags);
-	mod_timer(&card->ptimer, jiffies+3);
+	mod_timer(&card->ptimer, jiffies + 3);
 	spin_unlock_irqrestore(&card->lock, flags);
 }
 
 static int
-act2000_command(act2000_card * card, isdn_ctrl * c)
+act2000_command(act2000_card *card, isdn_ctrl *c)
 {
-        ulong a;
-        act2000_chan *chan;
+	ulong a;
+	act2000_chan *chan;
 	act2000_cdef cdef;
 	isdn_ctrl cmd;
 	char tmp[17];
 	int ret;
 	unsigned long flags;
 	void __user *arg;
- 
-        switch (c->command) {
-		case ISDN_CMD_IOCTL:
-			memcpy(&a, c->parm.num, sizeof(ulong));
-			arg = (void __user *)a;
-			switch (c->arg) {
-				case ACT2000_IOCTL_LOADBOOT:
-					switch (card->bus) {
-						case ACT2000_BUS_ISA:
-							ret = act2000_isa_download(card,
-									   arg);
-							if (!ret) {
-								card->flags |= ACT2000_FLAGS_LOADED;
-								if (!(card->flags & ACT2000_FLAGS_IVALID)) {
-									card->ptimer.expires = jiffies + 3;
-									card->ptimer.function = act2000_poll;
-									card->ptimer.data = (unsigned long)card;
-									add_timer(&card->ptimer);
-								}
-								actcapi_manufacturer_req_errh(card);
-							}
-							break;
-						default:
-							printk(KERN_WARNING
-							       "act2000: Illegal BUS type %d\n",
-							       card->bus);
-							ret = -EIO;
+
+	switch (c->command) {
+	case ISDN_CMD_IOCTL:
+		memcpy(&a, c->parm.num, sizeof(ulong));
+		arg = (void __user *)a;
+		switch (c->arg) {
+		case ACT2000_IOCTL_LOADBOOT:
+			switch (card->bus) {
+			case ACT2000_BUS_ISA:
+				ret = act2000_isa_download(card,
+							   arg);
+				if (!ret) {
+					card->flags |= ACT2000_FLAGS_LOADED;
+					if (!(card->flags & ACT2000_FLAGS_IVALID)) {
+						card->ptimer.expires = jiffies + 3;
+						card->ptimer.function = act2000_poll;
+						card->ptimer.data = (unsigned long)card;
+						add_timer(&card->ptimer);
 					}
-					return ret;
-				case ACT2000_IOCTL_SETPROTO:
-					card->ptype = a?ISDN_PTYPE_EURO:ISDN_PTYPE_1TR6;
-					if (!(card->flags & ACT2000_FLAGS_RUNNING))
-						return 0;
-					actcapi_manufacturer_req_net(card);
-					return 0;
-				case ACT2000_IOCTL_SETMSN:
-					if (copy_from_user(tmp, arg,
-							   sizeof(tmp)))
-						return -EFAULT;
-					if ((ret = act2000_set_msn(card, tmp)))
-						return ret;
-					if (card->flags & ACT2000_FLAGS_RUNNING)
-						return(actcapi_manufacturer_req_msn(card));
-					return 0;
-				case ACT2000_IOCTL_ADDCARD:
-					if (copy_from_user(&cdef, arg,
-							   sizeof(cdef)))
-						return -EFAULT;
-					if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id))
-						return -EIO;
-					return 0;
-				case ACT2000_IOCTL_TEST:
-					if (!(card->flags & ACT2000_FLAGS_RUNNING))
-						return -ENODEV;
-					return 0;
-				default:
-					return -EINVAL;
-			}
-			break;
-		case ISDN_CMD_DIAL:
-			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
+					actcapi_manufacturer_req_errh(card);
+				}
 				break;
-			spin_lock_irqsave(&card->lock, flags);
-			if (chan->fsm_state != ACT2000_STATE_NULL) {
-				spin_unlock_irqrestore(&card->lock, flags);
-				printk(KERN_WARNING "Dial on channel with state %d\n",
-					chan->fsm_state);
-				return -EBUSY;
-			}
-			if (card->ptype == ISDN_PTYPE_EURO)
-				tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1);
-			else
-				tmp[0] = c->parm.setup.eazmsn[0];
-			chan->fsm_state = ACT2000_STATE_OCALL;
-			chan->callref = 0xffff;
-			spin_unlock_irqrestore(&card->lock, flags);
-			ret = actcapi_connect_req(card, chan, c->parm.setup.phone,
-						  tmp[0], c->parm.setup.si1,
-						  c->parm.setup.si2);
-			if (ret) {
-				cmd.driver = card->myid;
-				cmd.command = ISDN_STAT_DHUP;
-				cmd.arg &= 0x0f;
-				card->interface.statcallb(&cmd);
+			default:
+				printk(KERN_WARNING
+				       "act2000: Illegal BUS type %d\n",
+				       card->bus);
+				ret = -EIO;
 			}
 			return ret;
-		case ISDN_CMD_ACCEPTD:
-			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
-				break;
-			if (chan->fsm_state == ACT2000_STATE_ICALL)
-				actcapi_select_b2_protocol_req(card, chan);
-			return 0;
-		case ISDN_CMD_ACCEPTB:
-			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			return 0;
-		case ISDN_CMD_HANGUP:
+		case ACT2000_IOCTL_SETPROTO:
+			card->ptype = a ? ISDN_PTYPE_EURO : ISDN_PTYPE_1TR6;
 			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
-				break;
-			switch (chan->fsm_state) {
-				case ACT2000_STATE_ICALL:
-				case ACT2000_STATE_BSETUP:
-					actcapi_connect_resp(card, chan, 0x15);
-					break;
-				case ACT2000_STATE_ACTIVE:
-					actcapi_disconnect_b3_req(card, chan);
-					break;
-			}
+				return 0;
+			actcapi_manufacturer_req_net(card);
 			return 0;
-		case ISDN_CMD_SETEAZ:
-			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
-				break;
-			if (strlen(c->parm.num)) {
-				if (card->ptype == ISDN_PTYPE_EURO) {
-					chan->eazmask = act2000_find_msn(card, c->parm.num, 0);
-				}
-				if (card->ptype == ISDN_PTYPE_1TR6) {
-					int i;
-					chan->eazmask = 0;
-					for (i = 0; i < strlen(c->parm.num); i++)
-						if (isdigit(c->parm.num[i]))
-							chan->eazmask |= (1 << (c->parm.num[i] - '0'));
-				}
-			} else
-				chan->eazmask = 0x3ff;
-			actcapi_listen_req(card);
+		case ACT2000_IOCTL_SETMSN:
+			if (copy_from_user(tmp, arg,
+					   sizeof(tmp)))
+				return -EFAULT;
+			if ((ret = act2000_set_msn(card, tmp)))
+				return ret;
+			if (card->flags & ACT2000_FLAGS_RUNNING)
+				return (actcapi_manufacturer_req_msn(card));
 			return 0;
-		case ISDN_CMD_CLREAZ:
-			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
-				break;
-			chan->eazmask = 0;
-			actcapi_listen_req(card);
+		case ACT2000_IOCTL_ADDCARD:
+			if (copy_from_user(&cdef, arg,
+					   sizeof(cdef)))
+				return -EFAULT;
+			if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id))
+				return -EIO;
 			return 0;
-		case ISDN_CMD_SETL2:
+		case ACT2000_IOCTL_TEST:
 			if (!(card->flags & ACT2000_FLAGS_RUNNING))
 				return -ENODEV;
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
-				break;
-			chan->l2prot = (c->arg >> 8);
 			return 0;
-		case ISDN_CMD_SETL3:
-			if (!(card->flags & ACT2000_FLAGS_RUNNING))
-				return -ENODEV;
-			if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) {
-				printk(KERN_WARNING "L3 protocol unknown\n");
-				return -1;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case ISDN_CMD_DIAL:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		spin_lock_irqsave(&card->lock, flags);
+		if (chan->fsm_state != ACT2000_STATE_NULL) {
+			spin_unlock_irqrestore(&card->lock, flags);
+			printk(KERN_WARNING "Dial on channel with state %d\n",
+			       chan->fsm_state);
+			return -EBUSY;
+		}
+		if (card->ptype == ISDN_PTYPE_EURO)
+			tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1);
+		else
+			tmp[0] = c->parm.setup.eazmsn[0];
+		chan->fsm_state = ACT2000_STATE_OCALL;
+		chan->callref = 0xffff;
+		spin_unlock_irqrestore(&card->lock, flags);
+		ret = actcapi_connect_req(card, chan, c->parm.setup.phone,
+					  tmp[0], c->parm.setup.si1,
+					  c->parm.setup.si2);
+		if (ret) {
+			cmd.driver = card->myid;
+			cmd.command = ISDN_STAT_DHUP;
+			cmd.arg &= 0x0f;
+			card->interface.statcallb(&cmd);
+		}
+		return ret;
+	case ISDN_CMD_ACCEPTD:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		if (chan->fsm_state == ACT2000_STATE_ICALL)
+			actcapi_select_b2_protocol_req(card, chan);
+		return 0;
+	case ISDN_CMD_ACCEPTB:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		return 0;
+	case ISDN_CMD_HANGUP:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		switch (chan->fsm_state) {
+		case ACT2000_STATE_ICALL:
+		case ACT2000_STATE_BSETUP:
+			actcapi_connect_resp(card, chan, 0x15);
+			break;
+		case ACT2000_STATE_ACTIVE:
+			actcapi_disconnect_b3_req(card, chan);
+			break;
+		}
+		return 0;
+	case ISDN_CMD_SETEAZ:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		if (strlen(c->parm.num)) {
+			if (card->ptype == ISDN_PTYPE_EURO) {
+				chan->eazmask = act2000_find_msn(card, c->parm.num, 0);
 			}
-			if (!(chan = find_channel(card, c->arg & 0x0f)))
-				break;
-			chan->l3prot = (c->arg >> 8);
-			return 0;
-        }
-	
-        return -EINVAL;
+			if (card->ptype == ISDN_PTYPE_1TR6) {
+				int i;
+				chan->eazmask = 0;
+				for (i = 0; i < strlen(c->parm.num); i++)
+					if (isdigit(c->parm.num[i]))
+						chan->eazmask |= (1 << (c->parm.num[i] - '0'));
+			}
+		} else
+			chan->eazmask = 0x3ff;
+		actcapi_listen_req(card);
+		return 0;
+	case ISDN_CMD_CLREAZ:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		chan->eazmask = 0;
+		actcapi_listen_req(card);
+		return 0;
+	case ISDN_CMD_SETL2:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		chan->l2prot = (c->arg >> 8);
+		return 0;
+	case ISDN_CMD_SETL3:
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) {
+			printk(KERN_WARNING "L3 protocol unknown\n");
+			return -1;
+		}
+		if (!(chan = find_channel(card, c->arg & 0x0f)))
+			break;
+		chan->l3prot = (c->arg >> 8);
+		return 0;
+	}
+
+	return -EINVAL;
 }
 
 static int
 act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb)
 {
-        struct sk_buff *xmit_skb;
-        int len;
-        act2000_chan *chan;
+	struct sk_buff *xmit_skb;
+	int len;
+	act2000_chan *chan;
 	actcapi_msg *msg;
 
-        if (!(chan = find_channel(card, channel)))
+	if (!(chan = find_channel(card, channel)))
+		return -1;
+	if (chan->fsm_state != ACT2000_STATE_ACTIVE)
 		return -1;
-        if (chan->fsm_state != ACT2000_STATE_ACTIVE)
-                return -1;
-        len = skb->len;
-        if ((chan->queued + len) >= ACT2000_MAX_QUEUED)
-                return 0;
+	len = skb->len;
+	if ((chan->queued + len) >= ACT2000_MAX_QUEUED)
+		return 0;
 	if (!len)
 		return 0;
 	if (skb_headroom(skb) < 19) {
@@ -462,28 +462,28 @@ act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb)
 	msg->msg.data_b3_req.fakencci = MAKE_NCCI(chan->plci, 0, chan->ncci);
 	msg->msg.data_b3_req.flags = ack; /* Will be set to 0 on actual sending */
 	actcapi_debug_msg(xmit_skb, 1);
-        chan->queued += len;
+	chan->queued += len;
 	skb_queue_tail(&card->sndq, xmit_skb);
 	act2000_schedule_tx(card);
-        return len;
+	return len;
 }
 
 
 /* Read the Status-replies from the Interface */
 static int
-act2000_readstatus(u_char __user * buf, int len, act2000_card * card)
+act2000_readstatus(u_char __user *buf, int len, act2000_card *card)
 {
-        int count;
-        u_char __user *p;
+	int count;
+	u_char __user *p;
 
-        for (p = buf, count = 0; count < len; p++, count++) {
-                if (card->status_buf_read == card->status_buf_write)
-                        return count;
+	for (p = buf, count = 0; count < len; p++, count++) {
+		if (card->status_buf_read == card->status_buf_write)
+			return count;
 		put_user(*card->status_buf_read++, p);
-                if (card->status_buf_read > card->status_buf_end)
-                        card->status_buf_read = card->status_buf;
-        }
-        return count;
+		if (card->status_buf_read > card->status_buf_end)
+			card->status_buf_read = card->status_buf;
+	}
+	return count;
 }
 
 /*
@@ -492,75 +492,75 @@ act2000_readstatus(u_char __user * buf, int len, act2000_card * card)
 static inline act2000_card *
 act2000_findcard(int driverid)
 {
-        act2000_card *p = cards;
-
-        while (p) {
-                if (p->myid == driverid)
-                        return p;
-                p = p->next;
-        }
-        return (act2000_card *) 0;
+	act2000_card *p = cards;
+
+	while (p) {
+		if (p->myid == driverid)
+			return p;
+		p = p->next;
+	}
+	return (act2000_card *) 0;
 }
 
 /*
  * Wrapper functions for interface to linklevel
  */
 static int
-if_command(isdn_ctrl * c)
+if_command(isdn_ctrl *c)
 {
-        act2000_card *card = act2000_findcard(c->driver);
-
-        if (card)
-                return (act2000_command(card, c));
-        printk(KERN_ERR
-             "act2000: if_command %d called with invalid driverId %d!\n",
-               c->command, c->driver);
-        return -ENODEV;
+	act2000_card *card = act2000_findcard(c->driver);
+
+	if (card)
+		return (act2000_command(card, c));
+	printk(KERN_ERR
+	       "act2000: if_command %d called with invalid driverId %d!\n",
+	       c->command, c->driver);
+	return -ENODEV;
 }
 
 static int
 if_writecmd(const u_char __user *buf, int len, int id, int channel)
 {
-        act2000_card *card = act2000_findcard(id);
-
-        if (card) {
-                if (!(card->flags & ACT2000_FLAGS_RUNNING))
-                        return -ENODEV;
-                return (len);
-        }
-        printk(KERN_ERR
-               "act2000: if_writecmd called with invalid driverId!\n");
-        return -ENODEV;
+	act2000_card *card = act2000_findcard(id);
+
+	if (card) {
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		return (len);
+	}
+	printk(KERN_ERR
+	       "act2000: if_writecmd called with invalid driverId!\n");
+	return -ENODEV;
 }
 
 static int
-if_readstatus(u_char __user * buf, int len, int id, int channel)
+if_readstatus(u_char __user *buf, int len, int id, int channel)
 {
-        act2000_card *card = act2000_findcard(id);
-	
-        if (card) {
-                if (!(card->flags & ACT2000_FLAGS_RUNNING))
-                        return -ENODEV;
-                return (act2000_readstatus(buf, len, card));
-        }
-        printk(KERN_ERR
-               "act2000: if_readstatus called with invalid driverId!\n");
-        return -ENODEV;
+	act2000_card *card = act2000_findcard(id);
+
+	if (card) {
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
+		return (act2000_readstatus(buf, len, card));
+	}
+	printk(KERN_ERR
+	       "act2000: if_readstatus called with invalid driverId!\n");
+	return -ENODEV;
 }
 
 static int
 if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
 {
-        act2000_card *card = act2000_findcard(id);
-	
-        if (card) {
-                if (!(card->flags & ACT2000_FLAGS_RUNNING))
-                        return -ENODEV;
+	act2000_card *card = act2000_findcard(id);
+
+	if (card) {
+		if (!(card->flags & ACT2000_FLAGS_RUNNING))
+			return -ENODEV;
 		return (act2000_sendbuf(card, channel, ack, skb));
-        }
-        printk(KERN_ERR
-               "act2000: if_sendbuf called with invalid driverId!\n");
-        return -ENODEV;
+	}
+	printk(KERN_ERR
+	       "act2000: if_sendbuf called with invalid driverId!\n");
+	return -ENODEV;
 }
 
 
@@ -572,14 +572,14 @@ static void
 act2000_alloccard(int bus, int port, int irq, char *id)
 {
 	int i;
-        act2000_card *card;
-        if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) {
-                printk(KERN_WARNING
+	act2000_card *card;
+	if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) {
+		printk(KERN_WARNING
 		       "act2000: (%s) Could not allocate card-struct.\n", id);
-                return;
-        }
-        spin_lock_init(&card->lock);
-        spin_lock_init(&card->mnlock);
+		return;
+	}
+	spin_lock_init(&card->lock);
+	spin_lock_init(&card->mnlock);
 	skb_queue_head_init(&card->sndq);
 	skb_queue_head_init(&card->rcvq);
 	skb_queue_head_init(&card->ackq);
@@ -588,82 +588,82 @@ act2000_alloccard(int bus, int port, int irq, char *id)
 	INIT_WORK(&card->poll_tq, act2000_receive);
 	init_timer(&card->ptimer);
 	card->interface.owner = THIS_MODULE;
-        card->interface.channels = ACT2000_BCH;
-        card->interface.maxbufsize = 4000;
-        card->interface.command = if_command;
-        card->interface.writebuf_skb = if_sendbuf;
-        card->interface.writecmd = if_writecmd;
-        card->interface.readstat = if_readstatus;
-        card->interface.features =
+	card->interface.channels = ACT2000_BCH;
+	card->interface.maxbufsize = 4000;
+	card->interface.command = if_command;
+	card->interface.writebuf_skb = if_sendbuf;
+	card->interface.writecmd = if_writecmd;
+	card->interface.readstat = if_readstatus;
+	card->interface.features =
 		ISDN_FEATURE_L2_X75I |
 		ISDN_FEATURE_L2_HDLC |
 		ISDN_FEATURE_L3_TRANS |
 		ISDN_FEATURE_P_UNKNOWN;
-        card->interface.hl_hdrlen = 20;
-        card->ptype = ISDN_PTYPE_EURO;
-        strlcpy(card->interface.id, id, sizeof(card->interface.id));
-        for (i=0; i<ACT2000_BCH; i++) {
-                card->bch[i].plci = 0x8000;
-                card->bch[i].ncci = 0x8000;
-                card->bch[i].l2prot = ISDN_PROTO_L2_X75I;
-                card->bch[i].l3prot = ISDN_PROTO_L3_TRANS;
-        }
-        card->myid = -1;
-        card->bus = bus;
-        card->port = port;
-        card->irq = irq;
-        card->next = cards;
-        cards = card;
+	card->interface.hl_hdrlen = 20;
+	card->ptype = ISDN_PTYPE_EURO;
+	strlcpy(card->interface.id, id, sizeof(card->interface.id));
+	for (i = 0; i < ACT2000_BCH; i++) {
+		card->bch[i].plci = 0x8000;
+		card->bch[i].ncci = 0x8000;
+		card->bch[i].l2prot = ISDN_PROTO_L2_X75I;
+		card->bch[i].l3prot = ISDN_PROTO_L3_TRANS;
+	}
+	card->myid = -1;
+	card->bus = bus;
+	card->port = port;
+	card->irq = irq;
+	card->next = cards;
+	cards = card;
 }
 
 /*
  * register card at linklevel
  */
 static int
-act2000_registercard(act2000_card * card)
+act2000_registercard(act2000_card *card)
 {
-        switch (card->bus) {
-		case ACT2000_BUS_ISA:
-			break;
-		case ACT2000_BUS_MCA:
-		case ACT2000_BUS_PCMCIA:
-		default:
-			printk(KERN_WARNING
-			       "act2000: Illegal BUS type %d\n",
-			       card->bus);
-			return -1;
-        }
-        if (!register_isdn(&card->interface)) {
-                printk(KERN_WARNING
-                       "act2000: Unable to register %s\n",
-                       card->interface.id);
-                return -1;
-        }
-        card->myid = card->interface.channels;
-        sprintf(card->regname, "act2000-isdn (%s)", card->interface.id);
-        return 0;
+	switch (card->bus) {
+	case ACT2000_BUS_ISA:
+		break;
+	case ACT2000_BUS_MCA:
+	case ACT2000_BUS_PCMCIA:
+	default:
+		printk(KERN_WARNING
+		       "act2000: Illegal BUS type %d\n",
+		       card->bus);
+		return -1;
+	}
+	if (!register_isdn(&card->interface)) {
+		printk(KERN_WARNING
+		       "act2000: Unable to register %s\n",
+		       card->interface.id);
+		return -1;
+	}
+	card->myid = card->interface.channels;
+	sprintf(card->regname, "act2000-isdn (%s)", card->interface.id);
+	return 0;
 }
 
 static void
-unregister_card(act2000_card * card)
+unregister_card(act2000_card *card)
 {
-        isdn_ctrl cmd;
+	isdn_ctrl cmd;
 
-        cmd.command = ISDN_STAT_UNLOAD;
-        cmd.driver = card->myid;
-        card->interface.statcallb(&cmd);
-        switch (card->bus) {
-		case ACT2000_BUS_ISA:
-			act2000_isa_release(card);
-			break;
-		case ACT2000_BUS_MCA:
-		case ACT2000_BUS_PCMCIA:
-		default:
-			printk(KERN_WARNING
-			       "act2000: Invalid BUS type %d\n",
-			       card->bus);
-			break;
-        }
+	cmd.command = ISDN_STAT_UNLOAD;
+	cmd.driver = card->myid;
+	card->interface.statcallb(&cmd);
+	switch (card->bus) {
+	case ACT2000_BUS_ISA:
+		act2000_isa_release(card);
+		break;
+	case ACT2000_BUS_MCA:
+	case ACT2000_BUS_PCMCIA:
+	default:
+		printk(KERN_WARNING
+		       "act2000: Invalid BUS type %d\n",
+		       card->bus);
+		break;
+	}
 }
 
 static int
@@ -690,23 +690,23 @@ act2000_addcard(int bus, int port, int irq, char *id)
 			for (i = 0; i < ARRAY_SIZE(act2000_isa_ports); i++)
 				if (act2000_isa_detect(act2000_isa_ports[i])) {
 					printk(KERN_INFO "act2000: Detected "
-						"ISA card at port 0x%x\n",
-						act2000_isa_ports[i]);
+					       "ISA card at port 0x%x\n",
+					       act2000_isa_ports[i]);
 					act2000_alloccard(bus,
-						act2000_isa_ports[i], irq, id);
+							  act2000_isa_ports[i], irq, id);
 				}
 			break;
 		case ACT2000_BUS_MCA:
 		case ACT2000_BUS_PCMCIA:
 		default:
 			printk(KERN_WARNING
-				"act2000: addcard: Invalid BUS type %d\n", bus);
+			       "act2000: addcard: Invalid BUS type %d\n", bus);
 		}
 	}
 	if (!cards)
 		return 1;
-        p = cards;
-        while (p) {
+	p = cards;
+	while (p) {
 		initialized = 0;
 		if (!p->interface.statcallb) {
 			/* Not yet registered.
@@ -714,99 +714,99 @@ act2000_addcard(int bus, int port, int irq, char *id)
 			 */
 			added++;
 			switch (p->bus) {
-				case ACT2000_BUS_ISA:
-					if (act2000_isa_detect(p->port)) {
-						if (act2000_registercard(p))
-							break;
-						if (act2000_isa_config_port(p, p->port)) {
-							printk(KERN_WARNING
-							       "act2000: Could not request port 0x%04x\n",
-							       p->port);
-							unregister_card(p);
-							p->interface.statcallb = NULL;
-							break;
-						}
-						if (act2000_isa_config_irq(p, p->irq)) {
-							printk(KERN_INFO
-							       "act2000: No IRQ available, fallback to polling\n");
-							/* Fall back to polled operation */
-							p->irq = 0;
-						}
-						printk(KERN_INFO
-						       "act2000: ISA"
-						       "-type card at port "
-						       "0x%04x ",
+			case ACT2000_BUS_ISA:
+				if (act2000_isa_detect(p->port)) {
+					if (act2000_registercard(p))
+						break;
+					if (act2000_isa_config_port(p, p->port)) {
+						printk(KERN_WARNING
+						       "act2000: Could not request port 0x%04x\n",
 						       p->port);
-						if (p->irq)
-							printk("irq %d\n", p->irq);
-						else
-							printk("polled\n");
-						initialized = 1;
+						unregister_card(p);
+						p->interface.statcallb = NULL;
+						break;
+					}
+					if (act2000_isa_config_irq(p, p->irq)) {
+						printk(KERN_INFO
+						       "act2000: No IRQ available, fallback to polling\n");
+						/* Fall back to polled operation */
+						p->irq = 0;
 					}
-					break;
-				case ACT2000_BUS_MCA:
-				case ACT2000_BUS_PCMCIA:
-				default:
-					printk(KERN_WARNING
-					       "act2000: addcard: Invalid BUS type %d\n",
-					       p->bus);
+					printk(KERN_INFO
+					       "act2000: ISA"
+					       "-type card at port "
+					       "0x%04x ",
+					       p->port);
+					if (p->irq)
+						printk("irq %d\n", p->irq);
+					else
+						printk("polled\n");
+					initialized = 1;
+				}
+				break;
+			case ACT2000_BUS_MCA:
+			case ACT2000_BUS_PCMCIA:
+			default:
+				printk(KERN_WARNING
+				       "act2000: addcard: Invalid BUS type %d\n",
+				       p->bus);
 			}
 		} else
 			/* Card already initialized */
 			initialized = 1;
-                if (initialized) {
+		if (initialized) {
 			/* Init OK, next card ... */
-                        q = p;
-                        p = p->next;
-                } else {
-                        /* Init failed, remove card from list, free memory */
-                        printk(KERN_WARNING
-                               "act2000: Initialization of %s failed\n",
-                               p->interface.id);
-                        if (q) {
-                                q->next = p->next;
-                                kfree(p);
-                                p = q->next;
-                        } else {
-                                cards = p->next;
-                                kfree(p);
-                                p = cards;
-                        }
+			q = p;
+			p = p->next;
+		} else {
+			/* Init failed, remove card from list, free memory */
+			printk(KERN_WARNING
+			       "act2000: Initialization of %s failed\n",
+			       p->interface.id);
+			if (q) {
+				q->next = p->next;
+				kfree(p);
+				p = q->next;
+			} else {
+				cards = p->next;
+				kfree(p);
+				p = cards;
+			}
 			failed++;
-                }
+		}
 	}
-        return (added - failed);
+	return (added - failed);
 }
 
 #define DRIVERNAME "IBM Active 2000 ISDN driver"
 
 static int __init act2000_init(void)
 {
-        printk(KERN_INFO "%s\n", DRIVERNAME);
-        if (!cards)
+	printk(KERN_INFO "%s\n", DRIVERNAME);
+	if (!cards)
 		act2000_addcard(act_bus, act_port, act_irq, act_id);
-        if (!cards)
-                printk(KERN_INFO "act2000: No cards defined yet\n");
-        return 0;
+	if (!cards)
+		printk(KERN_INFO "act2000: No cards defined yet\n");
+	return 0;
 }
 
 static void __exit act2000_exit(void)
 {
-        act2000_card *card = cards;
-        act2000_card *last;
-        while (card) {
-                unregister_card(card);
+	act2000_card *card = cards;
+	act2000_card *last;
+	while (card) {
+		unregister_card(card);
 		del_timer(&card->ptimer);
-                card = card->next;
-        }
-        card = cards;
-        while (card) {
-                last = card;
-                card = card->next;
+		card = card->next;
+	}
+	card = cards;
+	while (card) {
+		last = card;
+		card = card->next;
 		act2000_clear_msn(last);
-                kfree(last);
-        }
-        printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
+		kfree(last);
+	}
+	printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
 }
 
 module_init(act2000_init);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index e44933d..0d47ebc 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -164,7 +164,7 @@ static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
 
 	spin_lock_bh(&mp->ackqlock);
 	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
- 		if (p->datahandle == datahandle) {
+		if (p->datahandle == datahandle) {
 			list_del(&p->list);
 			mp->nack--;
 			spin_unlock_bh(&mp->ackqlock);
@@ -199,8 +199,8 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
 	unsigned int minor;
 
 	mp = kzalloc(sizeof(*mp), GFP_KERNEL);
-  	if (!mp) {
-  		printk(KERN_ERR "capi: can't alloc capiminor\n");
+	if (!mp) {
+		printk(KERN_ERR "capi: can't alloc capiminor\n");
 		return NULL;
 	}
 
@@ -391,7 +391,7 @@ gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
 	struct sk_buff *nskb;
 	nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_KERNEL);
 	if (nskb) {
-		u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
+		u16 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 4 + 2);
 		unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
 		capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
 		capimsg_setu16(s, 2, mp->ap->applid);
@@ -418,7 +418,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
 		pr_debug("capi: currently no receiver\n");
 		return -1;
 	}
-	
+
 	ld = tty_ldisc_ref(tty);
 	if (!ld) {
 		/* fatal error, do not requeue */
@@ -459,7 +459,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
 		ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
 	} else {
 		printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
-				errcode);
+		       errcode);
 		kfree_skb(nskb);
 
 		if (errcode == CAPI_SENDQUEUEFULL)
@@ -618,7 +618,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 		goto unlock_out;
 	}
 	if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
-		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
+		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 4 + 2);
 		pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
 			 datahandle, skb->len-CAPIMSG_LEN(skb->data));
 		skb_queue_tail(&mp->inqueue, skb);
@@ -627,10 +627,10 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 
 	} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
 
-		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
+		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
 		pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
 			 datahandle,
-			 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
+			 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4 + 2));
 		kfree_skb(skb);
 		capiminor_del_ack(mp, datahandle);
 		tty = tty_port_tty_get(&mp->port);
@@ -669,7 +669,7 @@ capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
 		err = wait_event_interruptible(cdev->recvwait,
-				(skb = skb_dequeue(&cdev->recvqueue)));
+					       (skb = skb_dequeue(&cdev->recvqueue)));
 		if (err)
 			return err;
 	}
@@ -736,7 +736,7 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
 }
 
 static unsigned int
-capi_poll(struct file *file, poll_table * wait)
+capi_poll(struct file *file, poll_table *wait)
 {
 	struct capidev *cdev = file->private_data;
 	unsigned int mask = 0;
@@ -786,75 +786,75 @@ register_out:
 		return retval;
 
 	case CAPI_GET_VERSION:
-		{
-			if (copy_from_user(&data.contr, argp,
-						sizeof(data.contr)))
-				return -EFAULT;
-		        cdev->errcode = capi20_get_version(data.contr, &data.version);
-			if (cdev->errcode)
-				return -EIO;
-			if (copy_to_user(argp, &data.version,
-					 sizeof(data.version)))
-				return -EFAULT;
-		}
-		return 0;
+	{
+		if (copy_from_user(&data.contr, argp,
+				   sizeof(data.contr)))
+			return -EFAULT;
+		cdev->errcode = capi20_get_version(data.contr, &data.version);
+		if (cdev->errcode)
+			return -EIO;
+		if (copy_to_user(argp, &data.version,
+				 sizeof(data.version)))
+			return -EFAULT;
+	}
+	return 0;
 
 	case CAPI_GET_SERIAL:
-		{
-			if (copy_from_user(&data.contr, argp,
-					   sizeof(data.contr)))
-				return -EFAULT;
-			cdev->errcode = capi20_get_serial (data.contr, data.serial);
-			if (cdev->errcode)
-				return -EIO;
-			if (copy_to_user(argp, data.serial,
-					 sizeof(data.serial)))
-				return -EFAULT;
-		}
-		return 0;
+	{
+		if (copy_from_user(&data.contr, argp,
+				   sizeof(data.contr)))
+			return -EFAULT;
+		cdev->errcode = capi20_get_serial(data.contr, data.serial);
+		if (cdev->errcode)
+			return -EIO;
+		if (copy_to_user(argp, data.serial,
+				 sizeof(data.serial)))
+			return -EFAULT;
+	}
+	return 0;
 	case CAPI_GET_PROFILE:
-		{
-			if (copy_from_user(&data.contr, argp,
-					   sizeof(data.contr)))
-				return -EFAULT;
+	{
+		if (copy_from_user(&data.contr, argp,
+				   sizeof(data.contr)))
+			return -EFAULT;
 
-			if (data.contr == 0) {
-				cdev->errcode = capi20_get_profile(data.contr, &data.profile);
-				if (cdev->errcode)
-					return -EIO;
+		if (data.contr == 0) {
+			cdev->errcode = capi20_get_profile(data.contr, &data.profile);
+			if (cdev->errcode)
+				return -EIO;
 
-				retval = copy_to_user(argp,
-				      &data.profile.ncontroller,
-				       sizeof(data.profile.ncontroller));
+			retval = copy_to_user(argp,
+					      &data.profile.ncontroller,
+					      sizeof(data.profile.ncontroller));
 
-			} else {
-				cdev->errcode = capi20_get_profile(data.contr, &data.profile);
-				if (cdev->errcode)
-					return -EIO;
+		} else {
+			cdev->errcode = capi20_get_profile(data.contr, &data.profile);
+			if (cdev->errcode)
+				return -EIO;
 
-				retval = copy_to_user(argp, &data.profile,
-						   sizeof(data.profile));
-			}
-			if (retval)
-				return -EFAULT;
+			retval = copy_to_user(argp, &data.profile,
+					      sizeof(data.profile));
 		}
-		return 0;
+		if (retval)
+			return -EFAULT;
+	}
+	return 0;
 
 	case CAPI_GET_MANUFACTURER:
-		{
-			if (copy_from_user(&data.contr, argp,
-					   sizeof(data.contr)))
-				return -EFAULT;
-			cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer);
-			if (cdev->errcode)
-				return -EIO;
+	{
+		if (copy_from_user(&data.contr, argp,
+				   sizeof(data.contr)))
+			return -EFAULT;
+		cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer);
+		if (cdev->errcode)
+			return -EIO;
 
-			if (copy_to_user(argp, data.manufacturer,
-					 sizeof(data.manufacturer)))
-				return -EFAULT;
+		if (copy_to_user(argp, data.manufacturer,
+				 sizeof(data.manufacturer)))
+			return -EFAULT;
 
-		}
-		return 0;
+	}
+	return 0;
 	case CAPI_GET_ERRCODE:
 		data.errcode = cdev->errcode;
 		cdev->errcode = CAPI_NOERROR;
@@ -871,15 +871,15 @@ register_out:
 		return -ENXIO;
 
 	case CAPI_MANUFACTURER_CMD:
-		{
-			struct capi_manufacturer_cmd mcmd;
-			if (!capable(CAP_SYS_ADMIN))
-				return -EPERM;
-			if (copy_from_user(&mcmd, argp, sizeof(mcmd)))
-				return -EFAULT;
-			return capi20_manufacturer(mcmd.cmd, mcmd.data);
-		}
-		return 0;
+	{
+		struct capi_manufacturer_cmd mcmd;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		if (copy_from_user(&mcmd, argp, sizeof(mcmd)))
+			return -EFAULT;
+		return capi20_manufacturer(mcmd.cmd, mcmd.data);
+	}
+	return 0;
 
 	case CAPI_SET_FLAGS:
 	case CAPI_CLR_FLAGS: {
@@ -1015,14 +1015,11 @@ capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
 	int idx = tty->index;
 	struct capiminor *mp = capiminor_get(idx);
-	int ret = tty_init_termios(tty);
+	int ret = tty_standard_install(driver, tty);
 
-	if (ret == 0) {
-		tty_driver_kref_get(driver);
-		tty->count++;
+	if (ret == 0)
 		tty->driver_data = mp;
-		driver->ttys[idx] = tty;
-	} else
+	else
 		capiminor_put(mp);
 	return ret;
 }
@@ -1070,7 +1067,7 @@ static int capinc_tty_write(struct tty_struct *tty,
 		mp->outbytes += skb->len;
 	}
 
-	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);
+	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + count, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
 		spin_unlock_bh(&mp->outlock);
@@ -1111,7 +1108,7 @@ static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
 		invoke_send = true;
 	}
 
-	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC);
+	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + CAPI_MAX_BLKSIZE, GFP_ATOMIC);
 	if (skb) {
 		skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
 		*(skb_put(skb, 1)) = ch;
@@ -1175,12 +1172,12 @@ static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
 }
 
 static int capinc_tty_ioctl(struct tty_struct *tty,
-		    unsigned int cmd, unsigned long arg)
+			    unsigned int cmd, unsigned long arg)
 {
 	return -ENOIOCTLCMD;
 }
 
-static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
+static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
 	pr_debug("capinc_tty_set_termios\n");
 }
@@ -1344,18 +1341,18 @@ static inline void capinc_tty_exit(void) { }
  */
 static int capi20_proc_show(struct seq_file *m, void *v)
 {
-        struct capidev *cdev;
+	struct capidev *cdev;
 	struct list_head *l;
 
 	mutex_lock(&capidev_list_lock);
 	list_for_each(l, &capidev_list) {
 		cdev = list_entry(l, struct capidev, list);
 		seq_printf(m, "0 %d %lu %lu %lu %lu\n",
-			cdev->ap.applid,
-			cdev->ap.nrecvctlpkt,
-			cdev->ap.nrecvdatapkt,
-			cdev->ap.nsentctlpkt,
-			cdev->ap.nsentdatapkt);
+			   cdev->ap.applid,
+			   cdev->ap.nrecvctlpkt,
+			   cdev->ap.nrecvdatapkt,
+			   cdev->ap.nsentctlpkt,
+			   cdev->ap.nsentdatapkt);
 	}
 	mutex_unlock(&capidev_list_lock);
 	return 0;
@@ -1450,9 +1447,9 @@ static int __init capi_init(void)
 	proc_init();
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
-        compileinfo = " (middleware)";
+	compileinfo = " (middleware)";
 #else
-        compileinfo = " (no middleware)";
+	compileinfo = " (no middleware)";
 #endif
 	printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
 	       capi_major, compileinfo);
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 92607ed..6f5016b 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -40,7 +40,7 @@ static int debugmode = 0;
 MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
-module_param(debugmode, uint, S_IRUGO|S_IWUSR);
+module_param(debugmode, uint, S_IRUGO | S_IWUSR);
 
 /* -------- type definitions ----------------------------------------- */
 
@@ -64,7 +64,7 @@ struct capidrv_contr {
 	int state;
 	u32 cipmask;
 	u32 cipmask2;
-        struct timer_list listentimer;
+	struct timer_list listentimer;
 
 	/*
 	 * ID of capi message sent
@@ -105,9 +105,9 @@ struct capidrv_contr {
 				/* */
 				u16 datahandle;
 				struct ncci_datahandle_queue {
-				    struct ncci_datahandle_queue *next;
-				    u16                         datahandle;
-				    int                           len;
+					struct ncci_datahandle_queue *next;
+					u16                         datahandle;
+					int                           len;
 				} *ackqueue;
 			} *ncci_list;
 		} *plcip;
@@ -142,7 +142,7 @@ static capidrv_data global;
 static DEFINE_SPINLOCK(global_lock);
 
 static void handle_dtrace_data(capidrv_contr *card,
-	int send, int level2, u8 *data, u16 len);
+			       int send, int level2, u8 *data, u16 len);
 
 /* -------- convert functions ---------------------------------------- */
 
@@ -158,11 +158,11 @@ static inline u32 b1prot(int l2, int l3)
 		return 0;
 	case ISDN_PROTO_L2_TRANS:
 		return 1;
-        case ISDN_PROTO_L2_V11096:
-        case ISDN_PROTO_L2_V11019:
-        case ISDN_PROTO_L2_V11038:
+	case ISDN_PROTO_L2_V11096:
+	case ISDN_PROTO_L2_V11019:
+	case ISDN_PROTO_L2_V11038:
 		return 2;
-        case ISDN_PROTO_L2_FAX:
+	case ISDN_PROTO_L2_FAX:
 		return 4;
 	case ISDN_PROTO_L2_MODEM:
 		return 8;
@@ -179,12 +179,12 @@ static inline u32 b2prot(int l2, int l3)
 		return 0;
 	case ISDN_PROTO_L2_HDLC:
 	case ISDN_PROTO_L2_TRANS:
-        case ISDN_PROTO_L2_V11096:
-        case ISDN_PROTO_L2_V11019:
-        case ISDN_PROTO_L2_V11038:
+	case ISDN_PROTO_L2_V11096:
+	case ISDN_PROTO_L2_V11019:
+	case ISDN_PROTO_L2_V11038:
 	case ISDN_PROTO_L2_MODEM:
 		return 1;
-        case ISDN_PROTO_L2_FAX:
+	case ISDN_PROTO_L2_FAX:
 		return 4;
 	}
 }
@@ -197,13 +197,13 @@ static inline u32 b3prot(int l2, int l3)
 	case ISDN_PROTO_L2_X75BUI:
 	case ISDN_PROTO_L2_HDLC:
 	case ISDN_PROTO_L2_TRANS:
-        case ISDN_PROTO_L2_V11096:
-        case ISDN_PROTO_L2_V11019:
-        case ISDN_PROTO_L2_V11038:
+	case ISDN_PROTO_L2_V11096:
+	case ISDN_PROTO_L2_V11019:
+	case ISDN_PROTO_L2_V11038:
 	case ISDN_PROTO_L2_MODEM:
 	default:
 		return 0;
-        case ISDN_PROTO_L2_FAX:
+	case ISDN_PROTO_L2_FAX:
 		return 4;
 	}
 }
@@ -231,38 +231,38 @@ static _cstruct b1config(int l2, int l3)
 	case ISDN_PROTO_L2_TRANS:
 	default:
 		return NULL;
-        case ISDN_PROTO_L2_V11096:
-	    return b1config_async_v110(9600);
-        case ISDN_PROTO_L2_V11019:
-	    return b1config_async_v110(19200);
-        case ISDN_PROTO_L2_V11038:
-	    return b1config_async_v110(38400);
+	case ISDN_PROTO_L2_V11096:
+		return b1config_async_v110(9600);
+	case ISDN_PROTO_L2_V11019:
+		return b1config_async_v110(19200);
+	case ISDN_PROTO_L2_V11038:
+		return b1config_async_v110(38400);
 	}
 }
 
 static inline u16 si2cip(u8 si1, u8 si2)
 {
 	static const u8 cip[17][5] =
-	{
-	/*  0  1  2  3  4  */
-		{0, 0, 0, 0, 0},	/*0 */
-		{16, 16, 4, 26, 16},	/*1 */
-		{17, 17, 17, 4, 4},	/*2 */
-		{2, 2, 2, 2, 2},	/*3 */
-		{18, 18, 18, 18, 18},	/*4 */
-		{2, 2, 2, 2, 2},	/*5 */
-		{0, 0, 0, 0, 0},	/*6 */
-		{2, 2, 2, 2, 2},	/*7 */
-		{2, 2, 2, 2, 2},	/*8 */
-		{21, 21, 21, 21, 21},	/*9 */
-		{19, 19, 19, 19, 19},	/*10 */
-		{0, 0, 0, 0, 0},	/*11 */
-		{0, 0, 0, 0, 0},	/*12 */
-		{0, 0, 0, 0, 0},	/*13 */
-		{0, 0, 0, 0, 0},	/*14 */
-		{22, 22, 22, 22, 22},	/*15 */
-		{27, 27, 27, 28, 27}	/*16 */
-	};
+		{
+			/*  0  1  2  3  4  */
+			{0, 0, 0, 0, 0},	/*0 */
+			{16, 16, 4, 26, 16},	/*1 */
+			{17, 17, 17, 4, 4},	/*2 */
+			{2, 2, 2, 2, 2},	/*3 */
+			{18, 18, 18, 18, 18},	/*4 */
+			{2, 2, 2, 2, 2},	/*5 */
+			{0, 0, 0, 0, 0},	/*6 */
+			{2, 2, 2, 2, 2},	/*7 */
+			{2, 2, 2, 2, 2},	/*8 */
+			{21, 21, 21, 21, 21},	/*9 */
+			{19, 19, 19, 19, 19},	/*10 */
+			{0, 0, 0, 0, 0},	/*11 */
+			{0, 0, 0, 0, 0},	/*12 */
+			{0, 0, 0, 0, 0},	/*13 */
+			{0, 0, 0, 0, 0},	/*14 */
+			{22, 22, 22, 22, 22},	/*15 */
+			{27, 27, 27, 28, 27}	/*16 */
+		};
 	if (si1 > 16)
 		si1 = 0;
 	if (si2 > 4)
@@ -274,10 +274,10 @@ static inline u16 si2cip(u8 si1, u8 si2)
 static inline u8 cip2si1(u16 cipval)
 {
 	static const u8 si[32] =
-	{7, 1, 7, 7, 1, 1, 7, 7,	/*0-7 */
-	 7, 1, 0, 0, 0, 0, 0, 0,	/*8-15 */
-	 1, 2, 4, 10, 9, 9, 15, 7,	/*16-23 */
-	 7, 7, 1, 16, 16, 0, 0, 0};	/*24-31 */
+		{7, 1, 7, 7, 1, 1, 7, 7,	/*0-7 */
+		 7, 1, 0, 0, 0, 0, 0, 0,	/*8-15 */
+		 1, 2, 4, 10, 9, 9, 15, 7,	/*16-23 */
+		 7, 7, 1, 16, 16, 0, 0, 0};	/*24-31 */
 
 	if (cipval > 31)
 		cipval = 0;	/* .... */
@@ -287,10 +287,10 @@ static inline u8 cip2si1(u16 cipval)
 static inline u8 cip2si2(u16 cipval)
 {
 	static const u8 si[32] =
-	{0, 0, 0, 0, 2, 3, 0, 0,	/*0-7 */
-	 0, 3, 0, 0, 0, 0, 0, 0,	/*8-15 */
-	 1, 2, 0, 0, 9, 0, 0, 0,	/*16-23 */
-	 0, 0, 3, 2, 3, 0, 0, 0};	/*24-31 */
+		{0, 0, 0, 0, 2, 3, 0, 0,	/*0-7 */
+		 0, 3, 0, 0, 0, 0, 0, 0,	/*8-15 */
+		 1, 2, 0, 0, 9, 0, 0, 0,	/*16-23 */
+		 0, 0, 3, 2, 3, 0, 0, 0};	/*24-31 */
 
 	if (cipval > 31)
 		cipval = 0;	/* .... */
@@ -302,7 +302,7 @@ static inline u8 cip2si2(u16 cipval)
 
 static inline capidrv_contr *findcontrbydriverid(int driverid)
 {
-    	unsigned long flags;
+	unsigned long flags;
 	capidrv_contr *p;
 
 	spin_lock_irqsave(&global_lock, flags);
@@ -329,7 +329,7 @@ static capidrv_contr *findcontrbynumber(u32 contr)
 
 /* -------- plci management ------------------------------------------ */
 
-static capidrv_plci *new_plci(capidrv_contr * card, int chan)
+static capidrv_plci *new_plci(capidrv_contr *card, int chan)
 {
 	capidrv_plci *plcip;
 
@@ -349,7 +349,7 @@ static capidrv_plci *new_plci(capidrv_contr * card, int chan)
 	return plcip;
 }
 
-static capidrv_plci *find_plci_by_plci(capidrv_contr * card, u32 plci)
+static capidrv_plci *find_plci_by_plci(capidrv_contr *card, u32 plci)
 {
 	capidrv_plci *p;
 	for (p = card->plci_list; p; p = p->next)
@@ -358,7 +358,7 @@ static capidrv_plci *find_plci_by_plci(capidrv_contr * card, u32 plci)
 	return NULL;
 }
 
-static capidrv_plci *find_plci_by_msgid(capidrv_contr * card, u16 msgid)
+static capidrv_plci *find_plci_by_msgid(capidrv_contr *card, u16 msgid)
 {
 	capidrv_plci *p;
 	for (p = card->plci_list; p; p = p->next)
@@ -367,7 +367,7 @@ static capidrv_plci *find_plci_by_msgid(capidrv_contr * card, u16 msgid)
 	return NULL;
 }
 
-static capidrv_plci *find_plci_by_ncci(capidrv_contr * card, u32 ncci)
+static capidrv_plci *find_plci_by_ncci(capidrv_contr *card, u32 ncci)
 {
 	capidrv_plci *p;
 	for (p = card->plci_list; p; p = p->next)
@@ -376,7 +376,7 @@ static capidrv_plci *find_plci_by_ncci(capidrv_contr * card, u32 ncci)
 	return NULL;
 }
 
-static void free_plci(capidrv_contr * card, capidrv_plci * plcip)
+static void free_plci(capidrv_contr *card, capidrv_plci *plcip)
 {
 	capidrv_plci **pp;
 
@@ -396,8 +396,8 @@ static void free_plci(capidrv_contr * card, capidrv_plci * plcip)
 
 /* -------- ncci management ------------------------------------------ */
 
-static inline capidrv_ncci *new_ncci(capidrv_contr * card,
-				     capidrv_plci * plcip,
+static inline capidrv_ncci *new_ncci(capidrv_contr *card,
+				     capidrv_plci *plcip,
 				     u32 ncci)
 {
 	capidrv_ncci *nccip;
@@ -421,7 +421,7 @@ static inline capidrv_ncci *new_ncci(capidrv_contr * card,
 	return nccip;
 }
 
-static inline capidrv_ncci *find_ncci(capidrv_contr * card, u32 ncci)
+static inline capidrv_ncci *find_ncci(capidrv_contr *card, u32 ncci)
 {
 	capidrv_plci *plcip;
 	capidrv_ncci *p;
@@ -435,7 +435,7 @@ static inline capidrv_ncci *find_ncci(capidrv_contr * card, u32 ncci)
 	return NULL;
 }
 
-static inline capidrv_ncci *find_ncci_by_msgid(capidrv_contr * card,
+static inline capidrv_ncci *find_ncci_by_msgid(capidrv_contr *card,
 					       u32 ncci, u16 msgid)
 {
 	capidrv_plci *plcip;
@@ -450,7 +450,7 @@ static inline capidrv_ncci *find_ncci_by_msgid(capidrv_contr * card,
 	return NULL;
 }
 
-static void free_ncci(capidrv_contr * card, struct capidrv_ncci *nccip)
+static void free_ncci(capidrv_contr *card, struct capidrv_ncci *nccip)
 {
 	struct capidrv_ncci **pp;
 
@@ -465,20 +465,20 @@ static void free_ncci(capidrv_contr * card, struct capidrv_ncci *nccip)
 }
 
 static int capidrv_add_ack(struct capidrv_ncci *nccip,
-		           u16 datahandle, int len)
+			   u16 datahandle, int len)
 {
 	struct ncci_datahandle_queue *n, **pp;
 
 	n = (struct ncci_datahandle_queue *)
 		kmalloc(sizeof(struct ncci_datahandle_queue), GFP_ATOMIC);
 	if (!n) {
-	   printk(KERN_ERR "capidrv: kmalloc ncci_datahandle failed\n");
-	   return -1;
+		printk(KERN_ERR "capidrv: kmalloc ncci_datahandle failed\n");
+		return -1;
 	}
 	n->next = NULL;
 	n->datahandle = datahandle;
 	n->len = len;
-	for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) ;
+	for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next);
 	*pp = n;
 	return 0;
 }
@@ -489,11 +489,11 @@ static int capidrv_del_ack(struct capidrv_ncci *nccip, u16 datahandle)
 	int len;
 
 	for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) {
- 		if ((*pp)->datahandle == datahandle) {
+		if ((*pp)->datahandle == datahandle) {
 			p = *pp;
 			len = p->len;
 			*pp = (*pp)->next;
-		        kfree(p);
+			kfree(p);
 			return len;
 		}
 	}
@@ -502,7 +502,7 @@ static int capidrv_del_ack(struct capidrv_ncci *nccip, u16 datahandle)
 
 /* -------- convert and send capi message ---------------------------- */
 
-static void send_message(capidrv_contr * card, _cmsg * cmsg)
+static void send_message(capidrv_contr *card, _cmsg *cmsg)
 {
 	struct sk_buff *skb;
 	size_t len;
@@ -529,18 +529,18 @@ struct listenstatechange {
 
 static struct listenstatechange listentable[] =
 {
-  {ST_LISTEN_NONE, ST_LISTEN_WAIT_CONF, EV_LISTEN_REQ},
-  {ST_LISTEN_ACTIVE, ST_LISTEN_ACTIVE_WAIT_CONF, EV_LISTEN_REQ},
-  {ST_LISTEN_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_ERROR},
-  {ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_ERROR},
-  {ST_LISTEN_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_EMPTY},
-  {ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_EMPTY},
-  {ST_LISTEN_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_OK},
-  {ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_OK},
-  {},
+	{ST_LISTEN_NONE, ST_LISTEN_WAIT_CONF, EV_LISTEN_REQ},
+	{ST_LISTEN_ACTIVE, ST_LISTEN_ACTIVE_WAIT_CONF, EV_LISTEN_REQ},
+	{ST_LISTEN_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_ERROR},
+	{ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_ERROR},
+	{ST_LISTEN_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_EMPTY},
+	{ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_EMPTY},
+	{ST_LISTEN_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_OK},
+	{ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_OK},
+	{},
 };
 
-static void listen_change_state(capidrv_contr * card, int event)
+static void listen_change_state(capidrv_contr *card, int event)
 {
 	struct listenstatechange *p = listentable;
 	while (p->event) {
@@ -560,7 +560,7 @@ static void listen_change_state(capidrv_contr * card, int event)
 
 /* ------------------------------------------------------------------ */
 
-static void p0(capidrv_contr * card, capidrv_plci * plci)
+static void p0(capidrv_contr *card, capidrv_plci *plci)
 {
 	isdn_ctrl cmd;
 
@@ -578,71 +578,71 @@ struct plcistatechange {
 	int actstate;
 	int nextstate;
 	int event;
-	void (*changefunc) (capidrv_contr * card, capidrv_plci * plci);
+	void (*changefunc)(capidrv_contr *card, capidrv_plci *plci);
 };
 
 static struct plcistatechange plcitable[] =
 {
-  /* P-0 */
-  {ST_PLCI_NONE, ST_PLCI_OUTGOING, EV_PLCI_CONNECT_REQ, NULL},
-  {ST_PLCI_NONE, ST_PLCI_ALLOCATED, EV_PLCI_FACILITY_IND_UP, NULL},
-  {ST_PLCI_NONE, ST_PLCI_INCOMING, EV_PLCI_CONNECT_IND, NULL},
-  {ST_PLCI_NONE, ST_PLCI_RESUMEING, EV_PLCI_RESUME_REQ, NULL},
-  /* P-0.1 */
-  {ST_PLCI_OUTGOING, ST_PLCI_NONE, EV_PLCI_CONNECT_CONF_ERROR, p0},
-  {ST_PLCI_OUTGOING, ST_PLCI_ALLOCATED, EV_PLCI_CONNECT_CONF_OK, NULL},
-  /* P-1 */
-  {ST_PLCI_ALLOCATED, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
-  {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
-  {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
-  {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
-  /* P-ACT */
-  {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
-  {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
-  {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
-  {ST_PLCI_ACTIVE, ST_PLCI_HELD, EV_PLCI_HOLD_IND, NULL},
-  {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_SUSPEND_IND, NULL},
-  /* P-2 */
-  {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_CONNECT_REJECT, NULL},
-  {ST_PLCI_INCOMING, ST_PLCI_FACILITY_IND, EV_PLCI_FACILITY_IND_UP, NULL},
-  {ST_PLCI_INCOMING, ST_PLCI_ACCEPTING, EV_PLCI_CONNECT_RESP, NULL},
-  {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
-  {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
-  {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
-  {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_CD_IND, NULL},
-  /* P-3 */
-  {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_CONNECT_REJECT, NULL},
-  {ST_PLCI_FACILITY_IND, ST_PLCI_ACCEPTING, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
-  {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
-  {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
-  {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
-  /* P-4 */
-  {ST_PLCI_ACCEPTING, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
-  {ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
-  {ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
-  {ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
-  /* P-5 */
-  {ST_PLCI_DISCONNECTING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
-  /* P-6 */
-  {ST_PLCI_DISCONNECTED, ST_PLCI_NONE, EV_PLCI_DISCONNECT_RESP, p0},
-  /* P-0.Res */
-  {ST_PLCI_RESUMEING, ST_PLCI_NONE, EV_PLCI_RESUME_CONF_ERROR, p0},
-  {ST_PLCI_RESUMEING, ST_PLCI_RESUME, EV_PLCI_RESUME_CONF_OK, NULL},
-  /* P-RES */
-  {ST_PLCI_RESUME, ST_PLCI_ACTIVE, EV_PLCI_RESUME_IND, NULL},
-  /* P-HELD */
-  {ST_PLCI_HELD, ST_PLCI_ACTIVE, EV_PLCI_RETRIEVE_IND, NULL},
-  {},
+	/* P-0 */
+	{ST_PLCI_NONE, ST_PLCI_OUTGOING, EV_PLCI_CONNECT_REQ, NULL},
+	{ST_PLCI_NONE, ST_PLCI_ALLOCATED, EV_PLCI_FACILITY_IND_UP, NULL},
+	{ST_PLCI_NONE, ST_PLCI_INCOMING, EV_PLCI_CONNECT_IND, NULL},
+	{ST_PLCI_NONE, ST_PLCI_RESUMEING, EV_PLCI_RESUME_REQ, NULL},
+	/* P-0.1 */
+	{ST_PLCI_OUTGOING, ST_PLCI_NONE, EV_PLCI_CONNECT_CONF_ERROR, p0},
+	{ST_PLCI_OUTGOING, ST_PLCI_ALLOCATED, EV_PLCI_CONNECT_CONF_OK, NULL},
+	/* P-1 */
+	{ST_PLCI_ALLOCATED, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
+	{ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
+	{ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
+	{ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
+	/* P-ACT */
+	{ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
+	{ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
+	{ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
+	{ST_PLCI_ACTIVE, ST_PLCI_HELD, EV_PLCI_HOLD_IND, NULL},
+	{ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_SUSPEND_IND, NULL},
+	/* P-2 */
+	{ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_CONNECT_REJECT, NULL},
+	{ST_PLCI_INCOMING, ST_PLCI_FACILITY_IND, EV_PLCI_FACILITY_IND_UP, NULL},
+	{ST_PLCI_INCOMING, ST_PLCI_ACCEPTING, EV_PLCI_CONNECT_RESP, NULL},
+	{ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
+	{ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
+	{ST_PLCI_INCOMING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
+	{ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_CD_IND, NULL},
+	/* P-3 */
+	{ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_CONNECT_REJECT, NULL},
+	{ST_PLCI_FACILITY_IND, ST_PLCI_ACCEPTING, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
+	{ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
+	{ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
+	{ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
+	/* P-4 */
+	{ST_PLCI_ACCEPTING, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
+	{ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
+	{ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
+	{ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
+	/* P-5 */
+	{ST_PLCI_DISCONNECTING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
+	/* P-6 */
+	{ST_PLCI_DISCONNECTED, ST_PLCI_NONE, EV_PLCI_DISCONNECT_RESP, p0},
+	/* P-0.Res */
+	{ST_PLCI_RESUMEING, ST_PLCI_NONE, EV_PLCI_RESUME_CONF_ERROR, p0},
+	{ST_PLCI_RESUMEING, ST_PLCI_RESUME, EV_PLCI_RESUME_CONF_OK, NULL},
+	/* P-RES */
+	{ST_PLCI_RESUME, ST_PLCI_ACTIVE, EV_PLCI_RESUME_IND, NULL},
+	/* P-HELD */
+	{ST_PLCI_HELD, ST_PLCI_ACTIVE, EV_PLCI_RETRIEVE_IND, NULL},
+	{},
 };
 
-static void plci_change_state(capidrv_contr * card, capidrv_plci * plci, int event)
+static void plci_change_state(capidrv_contr *card, capidrv_plci *plci, int event)
 {
 	struct plcistatechange *p = plcitable;
 	while (p->event) {
 		if (plci->state == p->actstate && p->event == event) {
 			if (debugmode)
 				printk(KERN_DEBUG "capidrv-%d: plci_change_state:0x%x %d -> %d\n",
-				  card->contrnr, plci->plci, plci->state, p->nextstate);
+				       card->contrnr, plci->plci, plci->state, p->nextstate);
 			plci->state = p->nextstate;
 			if (p->changefunc)
 				p->changefunc(card, plci);
@@ -658,7 +658,7 @@ static void plci_change_state(capidrv_contr * card, capidrv_plci * plci, int eve
 
 static _cmsg cmsg;
 
-static void n0(capidrv_contr * card, capidrv_ncci * ncci)
+static void n0(capidrv_contr *card, capidrv_ncci *ncci)
 {
 	isdn_ctrl cmd;
 
@@ -670,7 +670,7 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
 				 NULL,	/* Keypadfacility */
 				 NULL,	/* Useruserdata */   /* $$$$ */
 				 NULL	/* Facilitydataarray */
-	);
+		);
 	plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
 	send_message(card, &cmsg);
 
@@ -687,51 +687,51 @@ struct nccistatechange {
 	int actstate;
 	int nextstate;
 	int event;
-	void (*changefunc) (capidrv_contr * card, capidrv_ncci * ncci);
+	void (*changefunc)(capidrv_contr *card, capidrv_ncci *ncci);
 };
 
 static struct nccistatechange nccitable[] =
 {
-  /* N-0 */
-  {ST_NCCI_NONE, ST_NCCI_OUTGOING, EV_NCCI_CONNECT_B3_REQ, NULL},
-  {ST_NCCI_NONE, ST_NCCI_INCOMING, EV_NCCI_CONNECT_B3_IND, NULL},
-  /* N-0.1 */
-  {ST_NCCI_OUTGOING, ST_NCCI_ALLOCATED, EV_NCCI_CONNECT_B3_CONF_OK, NULL},
-  {ST_NCCI_OUTGOING, ST_NCCI_NONE, EV_NCCI_CONNECT_B3_CONF_ERROR, n0},
-  /* N-1 */
-  {ST_NCCI_INCOMING, ST_NCCI_DISCONNECTING, EV_NCCI_CONNECT_B3_REJECT, NULL},
-  {ST_NCCI_INCOMING, ST_NCCI_ALLOCATED, EV_NCCI_CONNECT_B3_RESP, NULL},
-  {ST_NCCI_INCOMING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
-  {ST_NCCI_INCOMING, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
-  /* N-2 */
-  {ST_NCCI_ALLOCATED, ST_NCCI_ACTIVE, EV_NCCI_CONNECT_B3_ACTIVE_IND, NULL},
-  {ST_NCCI_ALLOCATED, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
-  {ST_NCCI_ALLOCATED, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
-  /* N-ACT */
-  {ST_NCCI_ACTIVE, ST_NCCI_ACTIVE, EV_NCCI_RESET_B3_IND, NULL},
-  {ST_NCCI_ACTIVE, ST_NCCI_RESETING, EV_NCCI_RESET_B3_REQ, NULL},
-  {ST_NCCI_ACTIVE, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
-  {ST_NCCI_ACTIVE, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
-  /* N-3 */
-  {ST_NCCI_RESETING, ST_NCCI_ACTIVE, EV_NCCI_RESET_B3_IND, NULL},
-  {ST_NCCI_RESETING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
-  {ST_NCCI_RESETING, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
-  /* N-4 */
-  {ST_NCCI_DISCONNECTING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
-  {ST_NCCI_DISCONNECTING, ST_NCCI_PREVIOUS, EV_NCCI_DISCONNECT_B3_CONF_ERROR,NULL},
-  /* N-5 */
-  {ST_NCCI_DISCONNECTED, ST_NCCI_NONE, EV_NCCI_DISCONNECT_B3_RESP, n0},
-  {},
+	/* N-0 */
+	{ST_NCCI_NONE, ST_NCCI_OUTGOING, EV_NCCI_CONNECT_B3_REQ, NULL},
+	{ST_NCCI_NONE, ST_NCCI_INCOMING, EV_NCCI_CONNECT_B3_IND, NULL},
+	/* N-0.1 */
+	{ST_NCCI_OUTGOING, ST_NCCI_ALLOCATED, EV_NCCI_CONNECT_B3_CONF_OK, NULL},
+	{ST_NCCI_OUTGOING, ST_NCCI_NONE, EV_NCCI_CONNECT_B3_CONF_ERROR, n0},
+	/* N-1 */
+	{ST_NCCI_INCOMING, ST_NCCI_DISCONNECTING, EV_NCCI_CONNECT_B3_REJECT, NULL},
+	{ST_NCCI_INCOMING, ST_NCCI_ALLOCATED, EV_NCCI_CONNECT_B3_RESP, NULL},
+	{ST_NCCI_INCOMING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
+	{ST_NCCI_INCOMING, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
+	/* N-2 */
+	{ST_NCCI_ALLOCATED, ST_NCCI_ACTIVE, EV_NCCI_CONNECT_B3_ACTIVE_IND, NULL},
+	{ST_NCCI_ALLOCATED, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
+	{ST_NCCI_ALLOCATED, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
+	/* N-ACT */
+	{ST_NCCI_ACTIVE, ST_NCCI_ACTIVE, EV_NCCI_RESET_B3_IND, NULL},
+	{ST_NCCI_ACTIVE, ST_NCCI_RESETING, EV_NCCI_RESET_B3_REQ, NULL},
+	{ST_NCCI_ACTIVE, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
+	{ST_NCCI_ACTIVE, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
+	/* N-3 */
+	{ST_NCCI_RESETING, ST_NCCI_ACTIVE, EV_NCCI_RESET_B3_IND, NULL},
+	{ST_NCCI_RESETING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
+	{ST_NCCI_RESETING, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
+	/* N-4 */
+	{ST_NCCI_DISCONNECTING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
+	{ST_NCCI_DISCONNECTING, ST_NCCI_PREVIOUS, EV_NCCI_DISCONNECT_B3_CONF_ERROR, NULL},
+	/* N-5 */
+	{ST_NCCI_DISCONNECTED, ST_NCCI_NONE, EV_NCCI_DISCONNECT_B3_RESP, n0},
+	{},
 };
 
-static void ncci_change_state(capidrv_contr * card, capidrv_ncci * ncci, int event)
+static void ncci_change_state(capidrv_contr *card, capidrv_ncci *ncci, int event)
 {
 	struct nccistatechange *p = nccitable;
 	while (p->event) {
 		if (ncci->state == p->actstate && p->event == event) {
 			if (debugmode)
 				printk(KERN_DEBUG "capidrv-%d: ncci_change_state:0x%x %d -> %d\n",
-				  card->contrnr, ncci->ncci, ncci->state, p->nextstate);
+				       card->contrnr, ncci->ncci, ncci->state, p->nextstate);
 			if (p->nextstate == ST_NCCI_PREVIOUS) {
 				ncci->state = ncci->oldstate;
 				ncci->oldstate = p->actstate;
@@ -751,7 +751,7 @@ static void ncci_change_state(capidrv_contr * card, capidrv_ncci * ncci, int eve
 
 /* ------------------------------------------------------------------- */
 
-static inline int new_bchan(capidrv_contr * card)
+static inline int new_bchan(capidrv_contr *card)
 {
 	int i;
 	for (i = 0; i < card->nbchan; i++) {
@@ -765,7 +765,7 @@ static inline int new_bchan(capidrv_contr * card)
 
 /* ------------------------------------------------------------------- */
 
-static void handle_controller(_cmsg * cmsg)
+static void handle_controller(_cmsg *cmsg)
 {
 	capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
 
@@ -791,54 +791,54 @@ static void handle_controller(_cmsg * cmsg)
 		break;
 
 	case CAPI_MANUFACTURER_IND:	/* Controller */
-		if (   cmsg->ManuID == 0x214D5641
+		if (cmsg->ManuID == 0x214D5641
 		    && cmsg->Class == 0
 		    && cmsg->Function == 1) {
-		   u8  *data = cmsg->ManuData+3;
-		   u16  len = cmsg->ManuData[0];
-		   u16 layer;
-		   int direction;
-		   if (len == 255) {
-		      len = (cmsg->ManuData[1] | (cmsg->ManuData[2] << 8));
-		      data += 2;
-		   }
-		   len -= 2;
-		   layer = ((*(data-1)) << 8) | *(data-2);
-		   if (layer & 0x300)
-			direction = (layer & 0x200) ? 0 : 1;
-		   else direction = (layer & 0x800) ? 0 : 1;
-		   if (layer & 0x0C00) {
-		   	if ((layer & 0xff) == 0x80) {
-		           handle_dtrace_data(card, direction, 1, data, len);
-		           break;
-		   	}
-		   } else if ((layer & 0xff) < 0x80) {
-		      handle_dtrace_data(card, direction, 0, data, len);
-		      break;
-		   }
-	           printk(KERN_INFO "capidrv-%d: %s from controller 0x%x layer 0x%x, ignored\n",
-                        card->contrnr, 
-			capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			cmsg->adr.adrController, layer);
-                   break;
+			u8  *data = cmsg->ManuData + 3;
+			u16  len = cmsg->ManuData[0];
+			u16 layer;
+			int direction;
+			if (len == 255) {
+				len = (cmsg->ManuData[1] | (cmsg->ManuData[2] << 8));
+				data += 2;
+			}
+			len -= 2;
+			layer = ((*(data - 1)) << 8) | *(data - 2);
+			if (layer & 0x300)
+				direction = (layer & 0x200) ? 0 : 1;
+			else direction = (layer & 0x800) ? 0 : 1;
+			if (layer & 0x0C00) {
+				if ((layer & 0xff) == 0x80) {
+					handle_dtrace_data(card, direction, 1, data, len);
+					break;
+				}
+			} else if ((layer & 0xff) < 0x80) {
+				handle_dtrace_data(card, direction, 0, data, len);
+				break;
+			}
+			printk(KERN_INFO "capidrv-%d: %s from controller 0x%x layer 0x%x, ignored\n",
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       cmsg->adr.adrController, layer);
+			break;
 		}
 		goto ignored;
 	case CAPI_MANUFACTURER_CONF:	/* Controller */
 		if (cmsg->ManuID == 0x214D5641) {
-		   char *s = NULL;
-		   switch (cmsg->Class) {
-		      case 0: break;
-		      case 1: s = "unknown class"; break;
-		      case 2: s = "unknown function"; break;
-		      default: s = "unknown error"; break;
-		   }
-		   if (s)
-	           printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
-			card->contrnr,
-			capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			cmsg->adr.adrController,
-			cmsg->Function, s);
-		   break;
+			char *s = NULL;
+			switch (cmsg->Class) {
+			case 0: break;
+			case 1: s = "unknown class"; break;
+			case 2: s = "unknown function"; break;
+			default: s = "unknown error"; break;
+			}
+			if (s)
+				printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
+				       card->contrnr,
+				       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+				       cmsg->adr.adrController,
+				       cmsg->Function, s);
+			break;
 		}
 		goto ignored;
 	case CAPI_FACILITY_IND:	/* Controller/plci/ncci */
@@ -858,14 +858,14 @@ static void handle_controller(_cmsg * cmsg)
 	}
 	return;
 
-      ignored:
+ignored:
 	printk(KERN_INFO "capidrv-%d: %s from controller 0x%x ignored\n",
 	       card->contrnr,
 	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 	       cmsg->adr.adrController);
 }
 
-static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
+static void handle_incoming_call(capidrv_contr *card, _cmsg *cmsg)
 {
 	capidrv_plci *plcip;
 	capidrv_bchan *bchan;
@@ -890,27 +890,27 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
 	cmd.arg = chan;
 	memset(&cmd.parm.setup, 0, sizeof(cmd.parm.setup));
 	strncpy(cmd.parm.setup.phone,
-	        cmsg->CallingPartyNumber + 3,
+		cmsg->CallingPartyNumber + 3,
 		cmsg->CallingPartyNumber[0] - 2);
 	strncpy(cmd.parm.setup.eazmsn,
-	        cmsg->CalledPartyNumber + 2,
+		cmsg->CalledPartyNumber + 2,
 		cmsg->CalledPartyNumber[0] - 1);
 	cmd.parm.setup.si1 = cip2si1(cmsg->CIPValue);
 	cmd.parm.setup.si2 = cip2si2(cmsg->CIPValue);
 	cmd.parm.setup.plan = cmsg->CallingPartyNumber[1];
 	cmd.parm.setup.screen = cmsg->CallingPartyNumber[2];
 
-	printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s\n", 
-			card->contrnr,
-			cmd.parm.setup.phone,
-			cmd.parm.setup.si1,
-			cmd.parm.setup.si2,
-			cmd.parm.setup.eazmsn);
+	printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s\n",
+	       card->contrnr,
+	       cmd.parm.setup.phone,
+	       cmd.parm.setup.si1,
+	       cmd.parm.setup.si2,
+	       cmd.parm.setup.eazmsn);
 
 	if (cmd.parm.setup.si1 == 1 && cmd.parm.setup.si2 != 0) {
-		printk(KERN_INFO "capidrv-%d: patching si2=%d to 0 for VBOX\n", 
-			card->contrnr,
-			cmd.parm.setup.si2);
+		printk(KERN_INFO "capidrv-%d: patching si2=%d to 0 for VBOX\n",
+		       card->contrnr,
+		       cmd.parm.setup.si2);
 		cmd.parm.setup.si2 = 0;
 	}
 
@@ -927,11 +927,11 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
 		plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
 		send_message(card, cmsg);
 		printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
-			card->contrnr,
-			cmd.parm.setup.phone,
-			cmd.parm.setup.si1,
-			cmd.parm.setup.si2,
-			cmd.parm.setup.eazmsn);
+		       card->contrnr,
+		       cmd.parm.setup.phone,
+		       cmd.parm.setup.si1,
+		       cmd.parm.setup.si2,
+		       cmd.parm.setup.eazmsn);
 		break;
 	case 1:
 		/* At least one device matching this call (RING on ttyI)
@@ -945,11 +945,11 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
 		 */
 		if (plcip->state == ST_PLCI_INCOMING) {
 			printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s tty alerting\n",
-				card->contrnr,
-				cmd.parm.setup.phone,
-				cmd.parm.setup.si1,
-				cmd.parm.setup.si2,
-				cmd.parm.setup.eazmsn);
+			       card->contrnr,
+			       cmd.parm.setup.phone,
+			       cmd.parm.setup.si1,
+			       cmd.parm.setup.si2,
+			       cmd.parm.setup.eazmsn);
 			capi_fill_ALERT_REQ(cmsg,
 					    global.ap.applid,
 					    card->msgid++,
@@ -958,16 +958,16 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
 					    NULL,/* Keypadfacility */
 					    NULL,/* Useruserdata */
 					    NULL /* Facilitydataarray */
-			);
+				);
 			plcip->msgid = cmsg->Messagenumber;
 			send_message(card, cmsg);
 		} else {
 			printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s on netdev\n",
-				card->contrnr,
-				cmd.parm.setup.phone,
-				cmd.parm.setup.si1,
-				cmd.parm.setup.si2,
-				cmd.parm.setup.eazmsn);
+			       card->contrnr,
+			       cmd.parm.setup.phone,
+			       cmd.parm.setup.si1,
+			       cmd.parm.setup.si2,
+			       cmd.parm.setup.eazmsn);
 		}
 		break;
 
@@ -990,7 +990,7 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
 	return;
 }
 
-static void handle_plci(_cmsg * cmsg)
+static void handle_plci(_cmsg *cmsg)
 {
 	capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
 	capidrv_plci *plcip;
@@ -1008,8 +1008,8 @@ static void handle_plci(_cmsg * cmsg)
 	case CAPI_DISCONNECT_IND:	/* plci */
 		if (cmsg->Reason) {
 			printk(KERN_INFO "capidrv-%d: %s reason 0x%x (%s) for plci 0x%x\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 			       cmsg->Reason, capi_info2str(cmsg->Reason), cmsg->adr.adrPLCI);
 		}
 		if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI))) {
@@ -1027,9 +1027,9 @@ static void handle_plci(_cmsg * cmsg)
 	case CAPI_DISCONNECT_CONF:	/* plci */
 		if (cmsg->Info) {
 			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			       cmsg->Info, capi_info2str(cmsg->Info), 
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       cmsg->Info, capi_info2str(cmsg->Info),
 			       cmsg->adr.adrPLCI);
 		}
 		if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI)))
@@ -1041,9 +1041,9 @@ static void handle_plci(_cmsg * cmsg)
 	case CAPI_ALERT_CONF:	/* plci */
 		if (cmsg->Info) {
 			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			       cmsg->Info, capi_info2str(cmsg->Info), 
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       cmsg->Info, capi_info2str(cmsg->Info),
 			       cmsg->adr.adrPLCI);
 		}
 		break;
@@ -1055,9 +1055,9 @@ static void handle_plci(_cmsg * cmsg)
 	case CAPI_CONNECT_CONF:	/* plci */
 		if (cmsg->Info) {
 			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			       cmsg->Info, capi_info2str(cmsg->Info), 
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       cmsg->Info, capi_info2str(cmsg->Info),
 			       cmsg->adr.adrPLCI);
 		}
 		if (!(plcip = find_plci_by_msgid(card, cmsg->Messagenumber)))
@@ -1096,7 +1096,7 @@ static void handle_plci(_cmsg * cmsg)
 						 card->msgid++,
 						 plcip->plci,	/* adr */
 						 NULL	/* NCPI */
-			);
+				);
 			nccip->msgid = cmsg->Messagenumber;
 			plci_change_state(card, plcip,
 					  EV_PLCI_CONNECT_ACTIVE_IND);
@@ -1122,8 +1122,8 @@ static void handle_plci(_cmsg * cmsg)
 				sprintf(cmd.parm.num, "%lu",
 					(unsigned long)
 					((u32) cmsg->InfoElement[1]
-				  | ((u32) (cmsg->InfoElement[2]) << 8)
-				 | ((u32) (cmsg->InfoElement[3]) << 16)
+					 | ((u32) (cmsg->InfoElement[2]) << 8)
+					 | ((u32) (cmsg->InfoElement[3]) << 16)
 					 | ((u32) (cmsg->InfoElement[4]) << 24)));
 				card->interface.statcallb(&cmd);
 				break;
@@ -1132,11 +1132,11 @@ static void handle_plci(_cmsg * cmsg)
 		cdb = capi_cmsg2str(cmsg);
 		if (cdb) {
 			printk(KERN_WARNING "capidrv-%d: %s\n",
-				card->contrnr, cdb->buf);
+			       card->contrnr, cdb->buf);
 			cdebbuf_free(cdb);
 		} else
 			printk(KERN_WARNING "capidrv-%d: CAPI_INFO_IND InfoNumber %x not handled\n",
-				card->contrnr, cmsg->InfoNumber);
+			       card->contrnr, cmsg->InfoNumber);
 
 		break;
 
@@ -1159,13 +1159,13 @@ static void handle_plci(_cmsg * cmsg)
 		       cmsg->adr.adrPLCI);
 	}
 	return;
-      ignored:
+ignored:
 	printk(KERN_INFO "capidrv-%d: %s for plci 0x%x ignored\n",
 	       card->contrnr,
 	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 	       cmsg->adr.adrPLCI);
 	return;
-      notfound:
+notfound:
 	printk(KERN_ERR "capidrv-%d: %s: plci 0x%x not found\n",
 	       card->contrnr,
 	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
@@ -1173,7 +1173,7 @@ static void handle_plci(_cmsg * cmsg)
 	return;
 }
 
-static void handle_ncci(_cmsg * cmsg)
+static void handle_ncci(_cmsg *cmsg)
 {
 	capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
 	capidrv_plci *plcip;
@@ -1222,7 +1222,7 @@ static void handle_ncci(_cmsg * cmsg)
 							  nccip->ncci,	/* adr */
 							  0,	/* Reject */
 							  NULL	/* NCPI */
-				);
+					);
 				ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
 				send_message(card, cmsg);
 				break;
@@ -1230,8 +1230,8 @@ static void handle_ncci(_cmsg * cmsg)
 			printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n",							card->contrnr);
 		} else {
 			printk(KERN_ERR "capidrv-%d: %s: plci for ncci 0x%x not found\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 			       cmsg->adr.adrNCCI);
 		}
 		capi_fill_CONNECT_B3_RESP(cmsg,
@@ -1240,7 +1240,7 @@ static void handle_ncci(_cmsg * cmsg)
 					  cmsg->adr.adrNCCI,
 					  2,	/* Reject */
 					  NULL	/* NCPI */
-		);
+			);
 		send_message(card, cmsg);
 		break;
 
@@ -1254,9 +1254,9 @@ static void handle_ncci(_cmsg * cmsg)
 		nccip->ncci = cmsg->adr.adrNCCI;
 		if (cmsg->Info) {
 			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			       cmsg->Info, capi_info2str(cmsg->Info), 
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       cmsg->Info, capi_info2str(cmsg->Info),
 			       cmsg->adr.adrNCCI);
 		}
 
@@ -1278,7 +1278,7 @@ static void handle_ncci(_cmsg * cmsg)
 	case CAPI_DATA_B3_CONF:	/* ncci */
 		if (cmsg->Info) {
 			printk(KERN_WARNING "CAPI_DATA_B3_CONF: Info %x - %s\n",
-				cmsg->Info, capi_info2str(cmsg->Info));
+			       cmsg->Info, capi_info2str(cmsg->Info));
 		}
 		if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
 			goto notfound;
@@ -1286,11 +1286,11 @@ static void handle_ncci(_cmsg * cmsg)
 		len = capidrv_del_ack(nccip, cmsg->DataHandle);
 		if (len < 0)
 			break;
-	        cmd.command = ISDN_STAT_BSENT;
-	        cmd.driver = card->myid;
-	        cmd.arg = nccip->chan;
+		cmd.command = ISDN_STAT_BSENT;
+		cmd.driver = card->myid;
+		cmd.arg = nccip->chan;
 		cmd.parm.length = len;
-	        card->interface.statcallb(&cmd);
+		card->interface.statcallb(&cmd);
 		break;
 
 	case CAPI_DISCONNECT_B3_IND:	/* ncci */
@@ -1309,9 +1309,9 @@ static void handle_ncci(_cmsg * cmsg)
 			goto notfound;
 		if (cmsg->Info) {
 			printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n",
-			   card->contrnr,
-			   capi_cmd2str(cmsg->Command, cmsg->Subcommand),
-			       cmsg->Info, capi_info2str(cmsg->Info), 
+			       card->contrnr,
+			       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
+			       cmsg->Info, capi_info2str(cmsg->Info),
 			       cmsg->adr.adrNCCI);
 			ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_CONF_ERROR);
 		}
@@ -1340,13 +1340,13 @@ static void handle_ncci(_cmsg * cmsg)
 		       cmsg->adr.adrNCCI);
 	}
 	return;
-      ignored:
+ignored:
 	printk(KERN_INFO "capidrv-%d: %s for ncci 0x%x ignored\n",
 	       card->contrnr,
 	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 	       cmsg->adr.adrNCCI);
 	return;
-      notfound:
+notfound:
 	printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n",
 	       card->contrnr,
 	       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
@@ -1354,7 +1354,7 @@ static void handle_ncci(_cmsg * cmsg)
 }
 
 
-static void handle_data(_cmsg * cmsg, struct sk_buff *skb)
+static void handle_data(_cmsg *cmsg, struct sk_buff *skb)
 {
 	capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
 	capidrv_ncci *nccip;
@@ -1390,12 +1390,12 @@ static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 
 		if (cdb) {
 			printk(KERN_DEBUG "%s: applid=%d %s\n", __func__,
-				ap->applid, cdb->buf);
+			       ap->applid, cdb->buf);
 			cdebbuf_free(cdb);
 		} else
 			printk(KERN_DEBUG "%s: applid=%d %s not traced\n",
-				__func__, ap->applid,
-				capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand));
+			       __func__, ap->applid,
+			       capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand));
 	}
 	if (s_cmsg.Command == CAPI_DATA_B3
 	    && s_cmsg.Subcommand == CAPI_IND) {
@@ -1418,38 +1418,38 @@ static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 
 /* ------------------------------------------------------------------- */
 
-#define PUTBYTE_TO_STATUS(card, byte) \
-	do { \
-		*(card)->q931_write++ = (byte); \
-        	if ((card)->q931_write > (card)->q931_end) \
-	  		(card)->q931_write = (card)->q931_buf; \
+#define PUTBYTE_TO_STATUS(card, byte)				\
+	do {							\
+		*(card)->q931_write++ = (byte);			\
+		if ((card)->q931_write > (card)->q931_end)	\
+			(card)->q931_write = (card)->q931_buf;	\
 	} while (0)
 
 static void handle_dtrace_data(capidrv_contr *card,
-			     int send, int level2, u8 *data, u16 len)
+			       int send, int level2, u8 *data, u16 len)
 {
-    	u8 *p, *end;
-    	isdn_ctrl cmd;
+	u8 *p, *end;
+	isdn_ctrl cmd;
 
-    	if (!len) {
+	if (!len) {
 		printk(KERN_DEBUG "capidrv-%d: avmb1_q931_data: len == %d\n",
-				card->contrnr, len);
+		       card->contrnr, len);
 		return;
 	}
 
 	if (level2) {
 		PUTBYTE_TO_STATUS(card, 'D');
 		PUTBYTE_TO_STATUS(card, '2');
-        	PUTBYTE_TO_STATUS(card, send ? '>' : '<');
-        	PUTBYTE_TO_STATUS(card, ':');
+		PUTBYTE_TO_STATUS(card, send ? '>' : '<');
+		PUTBYTE_TO_STATUS(card, ':');
 	} else {
-        	PUTBYTE_TO_STATUS(card, 'D');
-        	PUTBYTE_TO_STATUS(card, '3');
-        	PUTBYTE_TO_STATUS(card, send ? '>' : '<');
-        	PUTBYTE_TO_STATUS(card, ':');
-    	}
+		PUTBYTE_TO_STATUS(card, 'D');
+		PUTBYTE_TO_STATUS(card, '3');
+		PUTBYTE_TO_STATUS(card, send ? '>' : '<');
+		PUTBYTE_TO_STATUS(card, ':');
+	}
 
-	for (p = data, end = data+len; p < end; p++) {
+	for (p = data, end = data + len; p < end; p++) {
 		PUTBYTE_TO_STATUS(card, ' ');
 		PUTBYTE_TO_STATUS(card, hex_asc_hi(*p));
 		PUTBYTE_TO_STATUS(card, hex_asc_lo(*p));
@@ -1458,7 +1458,7 @@ static void handle_dtrace_data(capidrv_contr *card,
 
 	cmd.command = ISDN_STAT_STAVAIL;
 	cmd.driver = card->myid;
-	cmd.arg = len*3+5;
+	cmd.arg = len * 3 + 5;
 	card->interface.statcallb(&cmd);
 }
 
@@ -1466,17 +1466,17 @@ static void handle_dtrace_data(capidrv_contr *card,
 
 static _cmsg cmdcmsg;
 
-static int capidrv_ioctl(isdn_ctrl * c, capidrv_contr * card)
+static int capidrv_ioctl(isdn_ctrl *c, capidrv_contr *card)
 {
 	switch (c->arg) {
 	case 1:
 		debugmode = (int)(*((unsigned int *)c->parm.num));
 		printk(KERN_DEBUG "capidrv-%d: debugmode=%d\n",
-				card->contrnr, debugmode);
+		       card->contrnr, debugmode);
 		return 0;
 	default:
 		printk(KERN_DEBUG "capidrv-%d: capidrv_ioctl(%ld) called ??\n",
-				card->contrnr, c->arg);
+		       card->contrnr, c->arg);
 		return -EINVAL;
 	}
 	return -EINVAL;
@@ -1487,9 +1487,9 @@ static int capidrv_ioctl(isdn_ctrl * c, capidrv_contr * card)
  */
 
 struct internal_bchannelinfo {
-   unsigned short channelalloc;
-   unsigned short operation;
-   unsigned char  cmask[31];
+	unsigned short channelalloc;
+	unsigned short operation;
+	unsigned char  cmask[31];
 };
 
 static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
@@ -1540,10 +1540,10 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
 		if (digit2 <= 0 || digit2 > 30) return -4;
 		if (*s == 0 || *s == ',' || *s == ' ') {
 			if (digit1 > digit2)
-				for (i = digit2; i <= digit1 ; i++)
+				for (i = digit2; i <= digit1; i++)
 					bmask |= (1 << i);
-			else 
-				for (i = digit1; i <= digit2 ; i++)
+			else
+				for (i = digit1; i <= digit2; i++)
 					bmask |= (1 << i);
 			digit1 = digit2 = 0;
 			if (*s) s++;
@@ -1556,131 +1556,131 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
 	return 0;
 }
 
-static int FVteln2capi20(char *teln, u8 AdditionalInfo[1+2+2+31])
+static int FVteln2capi20(char *teln, u8 AdditionalInfo[1 + 2 + 2 + 31])
 {
 	unsigned long bmask;
 	int active;
 	int rc, i;
-   
+
 	rc = decodeFVteln(teln, &bmask, &active);
 	if (rc) return rc;
 	/* Length */
-	AdditionalInfo[0] = 2+2+31;
-        /* Channel: 3 => use channel allocation */
-        AdditionalInfo[1] = 3; AdditionalInfo[2] = 0;
+	AdditionalInfo[0] = 2 + 2 + 31;
+	/* Channel: 3 => use channel allocation */
+	AdditionalInfo[1] = 3; AdditionalInfo[2] = 0;
 	/* Operation: 0 => DTE mode, 1 => DCE mode */
-        if (active) {
-   		AdditionalInfo[3] = 0; AdditionalInfo[4] = 0;
-   	} else {
-   		AdditionalInfo[3] = 1; AdditionalInfo[4] = 0;
+	if (active) {
+		AdditionalInfo[3] = 0; AdditionalInfo[4] = 0;
+	} else {
+		AdditionalInfo[3] = 1; AdditionalInfo[4] = 0;
 	}
 	/* Channel mask array */
 	AdditionalInfo[5] = 0; /* no D-Channel */
-	for (i=1; i <= 30; i++)
-		AdditionalInfo[5+i] = (bmask & (1 << i)) ? 0xff : 0;
+	for (i = 1; i <= 30; i++)
+		AdditionalInfo[5 + i] = (bmask & (1 << i)) ? 0xff : 0;
 	return 0;
 }
 
-static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
+static int capidrv_command(isdn_ctrl *c, capidrv_contr *card)
 {
 	isdn_ctrl cmd;
 	struct capidrv_bchan *bchan;
 	struct capidrv_plci *plcip;
-	u8 AdditionalInfo[1+2+2+31];
-        int rc, isleasedline = 0;
+	u8 AdditionalInfo[1 + 2 + 2 + 31];
+	int rc, isleasedline = 0;
 
 	if (c->command == ISDN_CMD_IOCTL)
 		return capidrv_ioctl(c, card);
 
 	switch (c->command) {
 	case ISDN_CMD_DIAL:{
-			u8 calling[ISDN_MSNLEN + 3];
-			u8 called[ISDN_MSNLEN + 2];
+		u8 calling[ISDN_MSNLEN + 3];
+		u8 called[ISDN_MSNLEN + 2];
 
-			if (debugmode)
-				printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_DIAL(ch=%ld,\"%s,%d,%d,%s\")\n",
-					card->contrnr,
-					c->arg,
-				        c->parm.setup.phone,
-				        c->parm.setup.si1,
-				        c->parm.setup.si2,
-				        c->parm.setup.eazmsn);
-
-			bchan = &card->bchans[c->arg % card->nbchan];
-
-			if (bchan->plcip) {
-				printk(KERN_ERR "capidrv-%d: dail ch=%ld,\"%s,%d,%d,%s\" in use (plci=0x%x)\n",
-					card->contrnr,
-			        	c->arg, 
-				        c->parm.setup.phone,
-				        c->parm.setup.si1,
-				        c->parm.setup.si2,
-				        c->parm.setup.eazmsn,
-				        bchan->plcip->plci);
-				return 0;
-			}
-			bchan->si1 = c->parm.setup.si1;
-			bchan->si2 = c->parm.setup.si2;
-
-			strncpy(bchan->num, c->parm.setup.phone, sizeof(bchan->num));
-			strncpy(bchan->mynum, c->parm.setup.eazmsn, sizeof(bchan->mynum));
-                        rc = FVteln2capi20(bchan->num, AdditionalInfo);
-			isleasedline = (rc == 0);
-			if (rc < 0)
-				printk(KERN_ERR "capidrv-%d: WARNING: invalid leased linedefinition \"%s\"\n", card->contrnr, bchan->num);
-
-			if (isleasedline) {
-				calling[0] = 0;
-				called[0] = 0;
-			        if (debugmode)
-					printk(KERN_DEBUG "capidrv-%d: connecting leased line\n", card->contrnr);
-			} else {
-		        	calling[0] = strlen(bchan->mynum) + 2;
-		        	calling[1] = 0;
-		     		calling[2] = 0x80;
-			   	strncpy(calling + 3, bchan->mynum, ISDN_MSNLEN);
-				called[0] = strlen(bchan->num) + 1;
-				called[1] = 0x80;
-				strncpy(called + 2, bchan->num, ISDN_MSNLEN);
-			}
+		if (debugmode)
+			printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_DIAL(ch=%ld,\"%s,%d,%d,%s\")\n",
+			       card->contrnr,
+			       c->arg,
+			       c->parm.setup.phone,
+			       c->parm.setup.si1,
+			       c->parm.setup.si2,
+			       c->parm.setup.eazmsn);
 
-			capi_fill_CONNECT_REQ(&cmdcmsg,
-					      global.ap.applid,
-					      card->msgid++,
-					      card->contrnr,	/* adr */
-					  si2cip(bchan->si1, bchan->si2),	/* cipvalue */
-					      called,	/* CalledPartyNumber */
-					      calling,	/* CallingPartyNumber */
-					      NULL,	/* CalledPartySubaddress */
-					      NULL,	/* CallingPartySubaddress */
-					    b1prot(bchan->l2, bchan->l3),	/* B1protocol */
-					    b2prot(bchan->l2, bchan->l3),	/* B2protocol */
-					    b3prot(bchan->l2, bchan->l3),	/* B3protocol */
-					    b1config(bchan->l2, bchan->l3),	/* B1configuration */
-					      NULL,	/* B2configuration */
-					      NULL,	/* B3configuration */
-					      NULL,	/* BC */
-					      NULL,	/* LLC */
-					      NULL,	/* HLC */
-					      /* BChannelinformation */
-					      isleasedline ? AdditionalInfo : NULL,
-					      NULL,	/* Keypadfacility */
-					      NULL,	/* Useruserdata */
-					      NULL	/* Facilitydataarray */
-			    );
-			if ((plcip = new_plci(card, (c->arg % card->nbchan))) == NULL) {
-				cmd.command = ISDN_STAT_DHUP;
-				cmd.driver = card->myid;
-				cmd.arg = (c->arg % card->nbchan);
-				card->interface.statcallb(&cmd);
-				return -1;
-			}
-			plcip->msgid = cmdcmsg.Messagenumber;
-			plcip->leasedline = isleasedline;
-			plci_change_state(card, plcip, EV_PLCI_CONNECT_REQ);
-			send_message(card, &cmdcmsg);
+		bchan = &card->bchans[c->arg % card->nbchan];
+
+		if (bchan->plcip) {
+			printk(KERN_ERR "capidrv-%d: dail ch=%ld,\"%s,%d,%d,%s\" in use (plci=0x%x)\n",
+			       card->contrnr,
+			       c->arg,
+			       c->parm.setup.phone,
+			       c->parm.setup.si1,
+			       c->parm.setup.si2,
+			       c->parm.setup.eazmsn,
+			       bchan->plcip->plci);
 			return 0;
 		}
+		bchan->si1 = c->parm.setup.si1;
+		bchan->si2 = c->parm.setup.si2;
+
+		strncpy(bchan->num, c->parm.setup.phone, sizeof(bchan->num));
+		strncpy(bchan->mynum, c->parm.setup.eazmsn, sizeof(bchan->mynum));
+		rc = FVteln2capi20(bchan->num, AdditionalInfo);
+		isleasedline = (rc == 0);
+		if (rc < 0)
+			printk(KERN_ERR "capidrv-%d: WARNING: invalid leased linedefinition \"%s\"\n", card->contrnr, bchan->num);
+
+		if (isleasedline) {
+			calling[0] = 0;
+			called[0] = 0;
+			if (debugmode)
+				printk(KERN_DEBUG "capidrv-%d: connecting leased line\n", card->contrnr);
+		} else {
+			calling[0] = strlen(bchan->mynum) + 2;
+			calling[1] = 0;
+			calling[2] = 0x80;
+			strncpy(calling + 3, bchan->mynum, ISDN_MSNLEN);
+			called[0] = strlen(bchan->num) + 1;
+			called[1] = 0x80;
+			strncpy(called + 2, bchan->num, ISDN_MSNLEN);
+		}
+
+		capi_fill_CONNECT_REQ(&cmdcmsg,
+				      global.ap.applid,
+				      card->msgid++,
+				      card->contrnr,	/* adr */
+				      si2cip(bchan->si1, bchan->si2),	/* cipvalue */
+				      called,	/* CalledPartyNumber */
+				      calling,	/* CallingPartyNumber */
+				      NULL,	/* CalledPartySubaddress */
+				      NULL,	/* CallingPartySubaddress */
+				      b1prot(bchan->l2, bchan->l3),	/* B1protocol */
+				      b2prot(bchan->l2, bchan->l3),	/* B2protocol */
+				      b3prot(bchan->l2, bchan->l3),	/* B3protocol */
+				      b1config(bchan->l2, bchan->l3),	/* B1configuration */
+				      NULL,	/* B2configuration */
+				      NULL,	/* B3configuration */
+				      NULL,	/* BC */
+				      NULL,	/* LLC */
+				      NULL,	/* HLC */
+				      /* BChannelinformation */
+				      isleasedline ? AdditionalInfo : NULL,
+				      NULL,	/* Keypadfacility */
+				      NULL,	/* Useruserdata */
+				      NULL	/* Facilitydataarray */
+			);
+		if ((plcip = new_plci(card, (c->arg % card->nbchan))) == NULL) {
+			cmd.command = ISDN_STAT_DHUP;
+			cmd.driver = card->myid;
+			cmd.arg = (c->arg % card->nbchan);
+			card->interface.statcallb(&cmd);
+			return -1;
+		}
+		plcip->msgid = cmdcmsg.Messagenumber;
+		plcip->leasedline = isleasedline;
+		plci_change_state(card, plcip, EV_PLCI_CONNECT_REQ);
+		send_message(card, &cmdcmsg);
+		return 0;
+	}
 
 	case ISDN_CMD_ACCEPTD:
 
@@ -1708,7 +1708,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
 				       NULL,	/* Keypadfacility */
 				       NULL,	/* Useruserdata */
 				       NULL	/* Facilitydataarray */
-		);
+			);
 		capi_cmsg2message(&cmdcmsg, cmdcmsg.buf);
 		plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP);
 		send_message(card, &cmdcmsg);
@@ -1742,7 +1742,7 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
 						    card->msgid++,
 						    bchan->nccip->ncci,
 						    NULL	/* NCPI */
-			);
+				);
 			ncci_change_state(card, bchan->nccip, EV_NCCI_DISCONNECT_B3_REQ);
 			send_message(card, &cmdcmsg);
 			return 0;
@@ -1761,12 +1761,12 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
 				capi_fill_DISCONNECT_REQ(&cmdcmsg,
 							 global.ap.applid,
 							 card->msgid++,
-						      bchan->plcip->plci,
+							 bchan->plcip->plci,
 							 NULL,	/* BChannelinformation */
 							 NULL,	/* Keypadfacility */
 							 NULL,	/* Useruserdata */
 							 NULL	/* Facilitydataarray */
-				);
+					);
 				plci_change_state(card, bchan->plcip, EV_PLCI_DISCONNECT_REQ);
 				send_message(card, &cmdcmsg);
 				return 0;
@@ -1778,8 +1778,8 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
 			}
 		}
 		printk(KERN_ERR "capidrv-%d: chan %ld disconnect request on free channel\n",
-				       card->contrnr,
-				       c->arg);
+		       card->contrnr,
+		       c->arg);
 		return -EINVAL;
 /* ready */
 
@@ -1813,20 +1813,20 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
 	case ISDN_CMD_CLREAZ:
 		if (debugmode)
 			printk(KERN_DEBUG "capidrv-%d: clearing EAZ on chan %ld\n",
-					card->contrnr, c->arg);
+			       card->contrnr, c->arg);
 		bchan = &card->bchans[c->arg % card->nbchan];
 		bchan->msn[0] = 0;
 		return 0;
 
 	default:
 		printk(KERN_ERR "capidrv-%d: ISDN_CMD_%d, Huh?\n",
-					card->contrnr, c->command);
+		       card->contrnr, c->command);
 		return -EINVAL;
 	}
 	return 0;
 }
 
-static int if_command(isdn_ctrl * c)
+static int if_command(isdn_ctrl *c)
 {
 	capidrv_contr *card = findcontrbydriverid(c->driver);
 
@@ -1834,8 +1834,8 @@ static int if_command(isdn_ctrl * c)
 		return capidrv_command(c, card);
 
 	printk(KERN_ERR
-	     "capidrv: if_command %d called with invalid driverId %d!\n",
-						c->command, c->driver);
+	       "capidrv: if_command %d called with invalid driverId %d!\n",
+	       c->command, c->driver);
 	return -ENODEV;
 }
 
@@ -1859,7 +1859,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
 	}
 	if (debugmode > 4)
 		printk(KERN_DEBUG "capidrv-%d: sendbuf len=%d skb=%p doack=%d\n",
-					card->contrnr, len, skb, doack);
+		       card->contrnr, len, skb, doack);
 	bchan = &card->bchans[channel % card->nbchan];
 	nccip = bchan->nccip;
 	if (!nccip || nccip->state != ST_NCCI_ACTIVE) {
@@ -1891,10 +1891,10 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
 			      skb->len,		/* DataLength */
 			      datahandle,	/* DataHandle */
 			      0	/* Flags */
-	    );
+		);
 
 	if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0)
-	   return 0;
+		return 0;
 
 	capi_cmsg2message(&sendcmsg, sendcmsg.buf);
 	msglen = CAPIMSG_LEN(sendcmsg.buf);
@@ -1902,8 +1902,8 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
 		struct sk_buff *nskb = skb_realloc_headroom(skb, msglen);
 		if (!nskb) {
 			printk(KERN_ERR "capidrv-%d: if_sendbuf: no memory\n",
-				card->contrnr);
-		        (void)capidrv_del_ack(nccip, datahandle);
+			       card->contrnr);
+			(void)capidrv_del_ack(nccip, datahandle);
 			return 0;
 		}
 		printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom, need %d\n",
@@ -1917,9 +1917,9 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
 		}
 		if (debugmode > 3)
 			printk(KERN_DEBUG "capidrv-%d: sendbuf putmsg ret(%x) - %s\n",
-				card->contrnr, errcode, capi_info2str(errcode));
-	        (void)capidrv_del_ack(nccip, datahandle);
-	        dev_kfree_skb(nskb);
+			       card->contrnr, errcode, capi_info2str(errcode));
+		(void)capidrv_del_ack(nccip, datahandle);
+		dev_kfree_skb(nskb);
 		return errcode == CAPI_SENDQUEUEFULL ? 0 : -1;
 	} else {
 		memcpy(skb_push(skb, msglen), sendcmsg.buf, msglen);
@@ -1930,9 +1930,9 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
 		}
 		if (debugmode > 3)
 			printk(KERN_DEBUG "capidrv-%d: sendbuf putmsg ret(%x) - %s\n",
-				card->contrnr, errcode, capi_info2str(errcode));
+			       card->contrnr, errcode, capi_info2str(errcode));
 		skb_pull(skb, msglen);
-	        (void)capidrv_del_ack(nccip, datahandle);
+		(void)capidrv_del_ack(nccip, datahandle);
 		return errcode == CAPI_SENDQUEUEFULL ? 0 : -1;
 	}
 }
@@ -1949,11 +1949,11 @@ static int if_readstat(u8 __user *buf, int len, int id, int channel)
 		return -ENODEV;
 	}
 
-	for (p=buf, count=0; count < len; p++, count++) {
+	for (p = buf, count = 0; count < len; p++, count++) {
 		if (put_user(*card->q931_read++, p))
 			return -EFAULT;
-	        if (card->q931_read > card->q931_end)
-	                card->q931_read = card->q931_buf;
+		if (card->q931_read > card->q931_end)
+			card->q931_read = card->q931_buf;
 	}
 	return count;
 
@@ -1961,35 +1961,35 @@ static int if_readstat(u8 __user *buf, int len, int id, int channel)
 
 static void enable_dchannel_trace(capidrv_contr *card)
 {
-        u8 manufacturer[CAPI_MANUFACTURER_LEN];
-        capi_version version;
+	u8 manufacturer[CAPI_MANUFACTURER_LEN];
+	capi_version version;
 	u16 contr = card->contrnr;
 	u16 errcode;
 	u16 avmversion[3];
 
-        errcode = capi20_get_manufacturer(contr, manufacturer);
-        if (errcode != CAPI_NOERROR) {
-	   printk(KERN_ERR "%s: can't get manufacturer (0x%x)\n",
-			card->name, errcode);
-	   return;
+	errcode = capi20_get_manufacturer(contr, manufacturer);
+	if (errcode != CAPI_NOERROR) {
+		printk(KERN_ERR "%s: can't get manufacturer (0x%x)\n",
+		       card->name, errcode);
+		return;
 	}
 	if (strstr(manufacturer, "AVM") == NULL) {
-	   printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
-			card->name, manufacturer);
-	   return;
+		printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
+		       card->name, manufacturer);
+		return;
 	}
-        errcode = capi20_get_version(contr, &version);
-        if (errcode != CAPI_NOERROR) {
-	   printk(KERN_ERR "%s: can't get version (0x%x)\n",
-			card->name, errcode);
-	   return;
+	errcode = capi20_get_version(contr, &version);
+	if (errcode != CAPI_NOERROR) {
+		printk(KERN_ERR "%s: can't get version (0x%x)\n",
+		       card->name, errcode);
+		return;
 	}
 	avmversion[0] = (version.majormanuversion >> 4) & 0x0f;
 	avmversion[1] = (version.majormanuversion << 4) & 0xf0;
 	avmversion[1] |= (version.minormanuversion >> 4) & 0x0f;
 	avmversion[2] |= version.minormanuversion & 0x0f;
 
-        if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) {
+	if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) {
 		printk(KERN_INFO "%s: D2 trace enabled\n", card->name);
 		capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.ap.applid,
 					   card->msgid++,
@@ -2030,8 +2030,8 @@ static void listentimerfunc(unsigned long x)
 	capidrv_contr *card = (capidrv_contr *)x;
 	if (card->state != ST_LISTEN_NONE && card->state != ST_LISTEN_ACTIVE)
 		printk(KERN_ERR "%s: controller dead ??\n", card->name);
-        send_listen(card);
-	mod_timer(&card->listentimer, jiffies + 60*HZ);
+	send_listen(card);
+	mod_timer(&card->listentimer, jiffies + 60 * HZ);
 }
 
 
@@ -2050,7 +2050,7 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
 	}
 	if (!(card = kzalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
 		printk(KERN_WARNING
-		 "capidrv: (%s) Could not allocate contr-struct.\n", id);
+		       "capidrv: (%s) Could not allocate contr-struct.\n", id);
 		return -1;
 	}
 	card->owner = THIS_MODULE;
@@ -2061,7 +2061,7 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
 	card->bchans = kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
 	if (!card->bchans) {
 		printk(KERN_WARNING
-		"capidrv: (%s) Could not allocate bchan-structs.\n", id);
+		       "capidrv: (%s) Could not allocate bchan-structs.\n", id);
 		module_put(card->owner);
 		kfree(card);
 		return -1;
@@ -2073,17 +2073,17 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
 	card->interface.writecmd = NULL;
 	card->interface.readstat = if_readstat;
 	card->interface.features = ISDN_FEATURE_L2_HDLC |
-	    			   ISDN_FEATURE_L2_TRANS |
-	    			   ISDN_FEATURE_L3_TRANS |
-				   ISDN_FEATURE_P_UNKNOWN |
-				   ISDN_FEATURE_L2_X75I |
-				   ISDN_FEATURE_L2_X75UI |
-				   ISDN_FEATURE_L2_X75BUI;
-	if (profp->support1 & (1<<2))
+		ISDN_FEATURE_L2_TRANS |
+		ISDN_FEATURE_L3_TRANS |
+		ISDN_FEATURE_P_UNKNOWN |
+		ISDN_FEATURE_L2_X75I |
+		ISDN_FEATURE_L2_X75UI |
+		ISDN_FEATURE_L2_X75BUI;
+	if (profp->support1 & (1 << 2))
 		card->interface.features |= ISDN_FEATURE_L2_V11096 |
-	    				    ISDN_FEATURE_L2_V11019 |
-	    				    ISDN_FEATURE_L2_V11038;
-	if (profp->support1 & (1<<8))
+			ISDN_FEATURE_L2_V11019 |
+			ISDN_FEATURE_L2_V11038;
+	if (profp->support1 & (1 << 8))
 		card->interface.features |= ISDN_FEATURE_L2_MODEM;
 	card->interface.hl_hdrlen = 22; /* len of DATA_B3_REQ */
 	strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
@@ -2122,10 +2122,10 @@ static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
 	card->listentimer.data = (unsigned long)card;
 	card->listentimer.function = listentimerfunc;
 	send_listen(card);
-	mod_timer(&card->listentimer, jiffies + 60*HZ);
+	mod_timer(&card->listentimer, jiffies + 60 * HZ);
 
 	printk(KERN_INFO "%s: now up (%d B channels)\n",
-		card->name, card->nbchan);
+	       card->name, card->nbchan);
 
 	enable_dchannel_trace(card);
 
@@ -2158,7 +2158,7 @@ static int capidrv_delcontr(u16 contr)
 
 	if (debugmode)
 		printk(KERN_DEBUG "capidrv-%d: id=%d unloading\n",
-					card->contrnr, card->myid);
+		       card->contrnr, card->myid);
 
 	cmd.command = ISDN_STAT_STOP;
 	cmd.driver = card->myid;
@@ -2168,17 +2168,17 @@ static int capidrv_delcontr(u16 contr)
 
 		cmd.command = ISDN_STAT_DISCH;
 		cmd.driver = card->myid;
-		cmd.arg = card->nbchan-1;
-	        cmd.parm.num[0] = 0;
+		cmd.arg = card->nbchan - 1;
+		cmd.parm.num[0] = 0;
 		if (debugmode)
 			printk(KERN_DEBUG "capidrv-%d: id=%d disable chan=%ld\n",
-					card->contrnr, card->myid, cmd.arg);
+			       card->contrnr, card->myid, cmd.arg);
 		card->interface.statcallb(&cmd);
 
-		if (card->bchans[card->nbchan-1].nccip)
-			free_ncci(card, card->bchans[card->nbchan-1].nccip);
-		if (card->bchans[card->nbchan-1].plcip)
-			free_plci(card, card->bchans[card->nbchan-1].plcip);
+		if (card->bchans[card->nbchan - 1].nccip)
+			free_ncci(card, card->bchans[card->nbchan - 1].nccip);
+		if (card->bchans[card->nbchan - 1].plcip)
+			free_plci(card, card->bchans[card->nbchan - 1].plcip);
 		if (card->plci_list)
 			printk(KERN_ERR "capidrv: bug in free_plci()\n");
 		card->nbchan--;
@@ -2188,7 +2188,7 @@ static int capidrv_delcontr(u16 contr)
 
 	if (debugmode)
 		printk(KERN_DEBUG "capidrv-%d: id=%d isdn unload\n",
-					card->contrnr, card->myid);
+		       card->contrnr, card->myid);
 
 	cmd.command = ISDN_STAT_UNLOAD;
 	cmd.driver = card->myid;
@@ -2196,7 +2196,7 @@ static int capidrv_delcontr(u16 contr)
 
 	if (debugmode)
 		printk(KERN_DEBUG "capidrv-%d: id=%d remove contr from list\n",
-					card->contrnr, card->myid);
+		       card->contrnr, card->myid);
 
 	spin_lock_irqsave(&global_lock, flags);
 	for (pp = &global.contr_list; *pp; pp = &(*pp)->next) {
@@ -2243,10 +2243,10 @@ lower_callback(struct notifier_block *nb, unsigned long val, void *v)
 static int capidrv_proc_show(struct seq_file *m, void *v)
 {
 	seq_printf(m, "%lu %lu %lu %lu\n",
-			global.ap.nrecvctlpkt,
-			global.ap.nrecvdatapkt,
-			global.ap.nsentctlpkt,
-			global.ap.nsentdatapkt);
+		   global.ap.nrecvctlpkt,
+		   global.ap.nrecvdatapkt,
+		   global.ap.nsentctlpkt,
+		   global.ap.nsentdatapkt);
 	return 0;
 }
 
diff --git a/drivers/isdn/capi/capidrv.h b/drivers/isdn/capi/capidrv.h
index 1e698e1..4466b2e 100644
--- a/drivers/isdn/capi/capidrv.h
+++ b/drivers/isdn/capi/capidrv.h
@@ -34,7 +34,7 @@
  * per plci state machine
  */
 #define ST_PLCI_NONE			0	/* P-0 */
-#define ST_PLCI_OUTGOING 		1	/* P-0.1 */
+#define ST_PLCI_OUTGOING		1	/* P-0.1 */
 #define ST_PLCI_ALLOCATED		2	/* P-1 */
 #define ST_PLCI_ACTIVE			3	/* P-ACT */
 #define ST_PLCI_INCOMING		4	/* P-2 */
@@ -47,20 +47,20 @@
 #define ST_PLCI_HELD			11	/* P-HELD */
 
 #define EV_PLCI_CONNECT_REQ		1	/* P-0 -> P-0.1
-                                                 */
+						 */
 #define EV_PLCI_CONNECT_CONF_ERROR	2	/* P-0.1 -> P-0
-                                                 */
+						 */
 #define EV_PLCI_CONNECT_CONF_OK		3	/* P-0.1 -> P-1
-                                                 */
+						 */
 #define EV_PLCI_FACILITY_IND_UP		4	/* P-0 -> P-1
-                                                 */
+						 */
 #define EV_PLCI_CONNECT_IND		5	/* P-0 -> P-2
-                                                 */
+						 */
 #define EV_PLCI_CONNECT_ACTIVE_IND	6	/* P-1 -> P-ACT
-                                                 */
+						 */
 #define EV_PLCI_CONNECT_REJECT		7	/* P-2 -> P-5
 						   P-3 -> P-5
-						 */
+						*/
 #define EV_PLCI_DISCONNECT_REQ		8	/* P-1 -> P-5
 						   P-2 -> P-5
 						   P-3 -> P-5
@@ -68,7 +68,7 @@
 						   P-ACT -> P-5
 						   P-Res -> P-5 (*)
 						   P-HELD -> P-5 (*)
-						   */
+						*/
 #define EV_PLCI_DISCONNECT_IND		9	/* P-1 -> P-6
 						   P-2 -> P-6
 						   P-3 -> P-6
@@ -77,35 +77,35 @@
 						   P-ACT -> P-6
 						   P-Res -> P-6 (*)
 						   P-HELD -> P-6 (*)
-						   */
+						*/
 #define EV_PLCI_FACILITY_IND_DOWN	10	/* P-0.1 -> P-5
 						   P-1 -> P-5
 						   P-ACT -> P-5
 						   P-2 -> P-5
 						   P-3 -> P-5
 						   P-4 -> P-5
-						   */
+						*/
 #define EV_PLCI_DISCONNECT_RESP		11	/* P-6 -> P-0
-                                                   */
+						 */
 #define EV_PLCI_CONNECT_RESP		12	/* P-6 -> P-0
-                                                   */
+						 */
 
 #define EV_PLCI_RESUME_REQ		13	/* P-0 -> P-0.Res
-                                                 */
+						 */
 #define EV_PLCI_RESUME_CONF_OK		14	/* P-0.Res -> P-Res
-                                                 */
+						 */
 #define EV_PLCI_RESUME_CONF_ERROR	15	/* P-0.Res -> P-0
-                                                 */
+						 */
 #define EV_PLCI_RESUME_IND		16	/* P-Res -> P-ACT
-                                                 */
+						 */
 #define EV_PLCI_HOLD_IND		17	/* P-ACT -> P-HELD
-                                                 */
+						 */
 #define EV_PLCI_RETRIEVE_IND		18	/* P-HELD -> P-ACT
-                                                 */
+						 */
 #define EV_PLCI_SUSPEND_IND		19	/* P-ACT -> P-5
-                                                 */
+						 */
 #define EV_PLCI_CD_IND			20	/* P-2 -> P-5
-                                                 */
+						 */
 
 /*
  * per ncci state machine
diff --git a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c
index 0b041df..33361f8 100644
--- a/drivers/isdn/capi/capilib.c
+++ b/drivers/isdn/capi/capilib.c
@@ -4,9 +4,9 @@
 #include <linux/module.h>
 #include <linux/isdn/capilli.h>
 
-#define DBG(format, arg...) do { \
-printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
-} while (0)
+#define DBG(format, arg...) do {					\
+		printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
+	} while (0)
 
 struct capilib_msgidqueue {
 	struct capilib_msgidqueue *next;
@@ -28,7 +28,7 @@ struct capilib_ncci {
 // ---------------------------------------------------------------------------
 // NCCI Handling
 
-static inline void mq_init(struct capilib_ncci * np)
+static inline void mq_init(struct capilib_ncci *np)
 {
 	u_int i;
 	np->msgidqueue = NULL;
@@ -42,7 +42,7 @@ static inline void mq_init(struct capilib_ncci * np)
 	}
 }
 
-static inline int mq_enqueue(struct capilib_ncci * np, u16 msgid)
+static inline int mq_enqueue(struct capilib_ncci *np, u16 msgid)
 {
 	struct capilib_msgidqueue *mq;
 	if ((mq = np->msgidfree) == NULL)
@@ -59,7 +59,7 @@ static inline int mq_enqueue(struct capilib_ncci * np, u16 msgid)
 	return 1;
 }
 
-static inline int mq_dequeue(struct capilib_ncci * np, u16 msgid)
+static inline int mq_dequeue(struct capilib_ncci *np, u16 msgid)
 {
 	struct capilib_msgidqueue **pp;
 	for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
@@ -165,7 +165,7 @@ u16 capilib_data_b3_req(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
 			continue;
 		if (np->ncci != ncci)
 			continue;
-		
+
 		if (mq_enqueue(np, msgid) == 0)
 			return CAPI_SENDQUEUEFULL;
 
@@ -188,7 +188,7 @@ void capilib_data_b3_conf(struct list_head *head, u16 applid, u32 ncci, u16 msgi
 			continue;
 		if (np->ncci != ncci)
 			continue;
-		
+
 		if (mq_dequeue(np, msgid) == 0) {
 			printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
 			       msgid, ncci);
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index 03c469e..d26f170 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -25,149 +25,149 @@
 #ifndef CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
 char *capi_info2str(u16 reason)
 {
-    return "..";
+	return "..";
 }
 #else
 char *capi_info2str(u16 reason)
 {
-    switch (reason) {
+	switch (reason) {
 
 /*-- informative values (corresponding message was processed) -----*/
 	case 0x0001:
-	   return "NCPI not supported by current protocol, NCPI ignored";
+		return "NCPI not supported by current protocol, NCPI ignored";
 	case 0x0002:
-	   return "Flags not supported by current protocol, flags ignored";
+		return "Flags not supported by current protocol, flags ignored";
 	case 0x0003:
-	   return "Alert already sent by another application";
+		return "Alert already sent by another application";
 
 /*-- error information concerning CAPI_REGISTER -----*/
 	case 0x1001:
-	   return "Too many applications";
+		return "Too many applications";
 	case 0x1002:
-	   return "Logical block size too small, must be at least 128 Bytes";
+		return "Logical block size too small, must be at least 128 Bytes";
 	case 0x1003:
-	   return "Buffer exceeds 64 kByte";
+		return "Buffer exceeds 64 kByte";
 	case 0x1004:
-	   return "Message buffer size too small, must be at least 1024 Bytes";
+		return "Message buffer size too small, must be at least 1024 Bytes";
 	case 0x1005:
-	   return "Max. number of logical connections not supported";
+		return "Max. number of logical connections not supported";
 	case 0x1006:
-	   return "Reserved";
+		return "Reserved";
 	case 0x1007:
-	   return "The message could not be accepted because of an internal busy condition";
+		return "The message could not be accepted because of an internal busy condition";
 	case 0x1008:
-	   return "OS resource error (no memory ?)";
+		return "OS resource error (no memory ?)";
 	case 0x1009:
-	   return "CAPI not installed";
+		return "CAPI not installed";
 	case 0x100A:
-	   return "Controller does not support external equipment";
+		return "Controller does not support external equipment";
 	case 0x100B:
-	   return "Controller does only support external equipment";
+		return "Controller does only support external equipment";
 
 /*-- error information concerning message exchange functions -----*/
 	case 0x1101:
-	   return "Illegal application number";
+		return "Illegal application number";
 	case 0x1102:
-	   return "Illegal command or subcommand or message length less than 12 bytes";
+		return "Illegal command or subcommand or message length less than 12 bytes";
 	case 0x1103:
-	   return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI";
+		return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI";
 	case 0x1104:
-	   return "Queue is empty";
+		return "Queue is empty";
 	case 0x1105:
-	   return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE";
+		return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE";
 	case 0x1106:
-	   return "Unknown notification parameter";
+		return "Unknown notification parameter";
 	case 0x1107:
-	   return "The Message could not be accepted because of an internal busy condition";
+		return "The Message could not be accepted because of an internal busy condition";
 	case 0x1108:
-	   return "OS Resource error (no memory ?)";
+		return "OS Resource error (no memory ?)";
 	case 0x1109:
-	   return "CAPI not installed";
+		return "CAPI not installed";
 	case 0x110A:
-	   return "Controller does not support external equipment";
+		return "Controller does not support external equipment";
 	case 0x110B:
-	   return "Controller does only support external equipment";
+		return "Controller does only support external equipment";
 
 /*-- error information concerning resource / coding problems -----*/
 	case 0x2001:
-	   return "Message not supported in current state";
+		return "Message not supported in current state";
 	case 0x2002:
-	   return "Illegal Controller / PLCI / NCCI";
+		return "Illegal Controller / PLCI / NCCI";
 	case 0x2003:
-	   return "Out of PLCI";
+		return "Out of PLCI";
 	case 0x2004:
-	   return "Out of NCCI";
+		return "Out of NCCI";
 	case 0x2005:
-	   return "Out of LISTEN";
+		return "Out of LISTEN";
 	case 0x2006:
-	   return "Out of FAX resources (protocol T.30)";
+		return "Out of FAX resources (protocol T.30)";
 	case 0x2007:
-	   return "Illegal message parameter coding";
+		return "Illegal message parameter coding";
 
 /*-- error information concerning requested services  -----*/
 	case 0x3001:
-	   return "B1 protocol not supported";
-	case 0x3002: 
-	   return "B2 protocol not supported";
-	case 0x3003: 
-	   return "B3 protocol not supported";
-	case 0x3004: 
-	   return "B1 protocol parameter not supported";
-	case 0x3005: 
-	   return "B2 protocol parameter not supported";
-	case 0x3006: 
-	   return "B3 protocol parameter not supported";
-	case 0x3007: 
-	   return "B protocol combination not supported";
-	case 0x3008: 
-	   return "NCPI not supported";
-	case 0x3009: 
-	   return "CIP Value unknown";
-	case 0x300A: 
-	   return "Flags not supported (reserved bits)";
-	case 0x300B: 
-	   return "Facility not supported";
-	case 0x300C: 
-	   return "Data length not supported by current protocol";
-	case 0x300D: 
-	   return "Reset procedure not supported by current protocol";
+		return "B1 protocol not supported";
+	case 0x3002:
+		return "B2 protocol not supported";
+	case 0x3003:
+		return "B3 protocol not supported";
+	case 0x3004:
+		return "B1 protocol parameter not supported";
+	case 0x3005:
+		return "B2 protocol parameter not supported";
+	case 0x3006:
+		return "B3 protocol parameter not supported";
+	case 0x3007:
+		return "B protocol combination not supported";
+	case 0x3008:
+		return "NCPI not supported";
+	case 0x3009:
+		return "CIP Value unknown";
+	case 0x300A:
+		return "Flags not supported (reserved bits)";
+	case 0x300B:
+		return "Facility not supported";
+	case 0x300C:
+		return "Data length not supported by current protocol";
+	case 0x300D:
+		return "Reset procedure not supported by current protocol";
 
 /*-- informations about the clearing of a physical connection -----*/
-	case 0x3301: 
-	   return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)";
-	case 0x3302: 
-	   return "Protocol error layer 2";
-	case 0x3303: 
-	   return "Protocol error layer 3";
-	case 0x3304: 
-	   return "Another application got that call";
+	case 0x3301:
+		return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)";
+	case 0x3302:
+		return "Protocol error layer 2";
+	case 0x3303:
+		return "Protocol error layer 3";
+	case 0x3304:
+		return "Another application got that call";
 /*-- T.30 specific reasons -----*/
-	case 0x3311: 
-	   return "Connecting not successful (remote station is no FAX G3 machine)";
-	case 0x3312: 
-	   return "Connecting not successful (training error)";
-	case 0x3313: 
-	   return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)";
-	case 0x3314: 
-	   return "Disconnected during transfer (remote abort)";
-	case 0x3315: 
-	   return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)";
-	case 0x3316: 
-	   return "Disconnected during transfer (local tx data underrun)";
-	case 0x3317: 
-	   return "Disconnected during transfer (local rx data overflow)";
-	case 0x3318: 
-	   return "Disconnected during transfer (local abort)";
-	case 0x3319: 
-	   return "Illegal parameter coding (e.g. SFF coding error)";
+	case 0x3311:
+		return "Connecting not successful (remote station is no FAX G3 machine)";
+	case 0x3312:
+		return "Connecting not successful (training error)";
+	case 0x3313:
+		return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)";
+	case 0x3314:
+		return "Disconnected during transfer (remote abort)";
+	case 0x3315:
+		return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)";
+	case 0x3316:
+		return "Disconnected during transfer (local tx data underrun)";
+	case 0x3317:
+		return "Disconnected during transfer (local rx data overflow)";
+	case 0x3318:
+		return "Disconnected during transfer (local abort)";
+	case 0x3319:
+		return "Illegal parameter coding (e.g. SFF coding error)";
 
 /*-- disconnect causes from the network according to ETS 300 102-1/Q.931 -----*/
 	case 0x3481: return "Unallocated (unassigned) number";
 	case 0x3482: return "No route to specified transit network";
 	case 0x3483: return "No route to destination";
 	case 0x3486: return "Channel unacceptable";
-	case 0x3487: 
-	   return "Call awarded and being delivered in an established channel";
+	case 0x3487:
+		return "Call awarded and being delivered in an established channel";
 	case 0x3490: return "Normal call clearing";
 	case 0x3491: return "User busy";
 	case 0x3492: return "No user responding";
@@ -217,7 +217,7 @@ char *capi_info2str(u16 reason)
 	case 0x34FF: return "Interworking, unspecified";
 
 	default: return "No additional information";
-    }
+	}
 }
 #endif
 
@@ -235,169 +235,169 @@ typedef struct {
 
 static _cdef cdef[] =
 {
-    /*00 */ 
- {_CEND},
-    /*01 */ 
- {_CEND},
-    /*02 */ 
- {_CEND},
-    /*03 */ 
- {_CDWORD, offsetof(_cmsg, adr.adrController)},
-    /*04 */ 
- {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
-    /*05 */ 
- {_CSTRUCT, offsetof(_cmsg, B1configuration)},
-    /*06 */ 
- {_CWORD, offsetof(_cmsg, B1protocol)},
-    /*07 */ 
- {_CSTRUCT, offsetof(_cmsg, B2configuration)},
-    /*08 */ 
- {_CWORD, offsetof(_cmsg, B2protocol)},
-    /*09 */ 
- {_CSTRUCT, offsetof(_cmsg, B3configuration)},
-    /*0a */ 
- {_CWORD, offsetof(_cmsg, B3protocol)},
-    /*0b */ 
- {_CSTRUCT, offsetof(_cmsg, BC)},
-    /*0c */ 
- {_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
-    /*0d */ 
- {_CMSTRUCT, offsetof(_cmsg, BProtocol)},
-    /*0e */ 
- {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
-    /*0f */ 
- {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
-    /*10 */ 
- {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
-    /*11 */ 
- {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
-    /*12 */ 
- {_CDWORD, offsetof(_cmsg, CIPmask)},
-    /*13 */ 
- {_CDWORD, offsetof(_cmsg, CIPmask2)},
-    /*14 */ 
- {_CWORD, offsetof(_cmsg, CIPValue)},
-    /*15 */ 
- {_CDWORD, offsetof(_cmsg, Class)},
-    /*16 */ 
- {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
-    /*17 */ 
- {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
-    /*18 */ 
- {_CDWORD, offsetof(_cmsg, Data)},
-    /*19 */ 
- {_CWORD, offsetof(_cmsg, DataHandle)},
-    /*1a */ 
- {_CWORD, offsetof(_cmsg, DataLength)},
-    /*1b */ 
- {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
-    /*1c */ 
- {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
-    /*1d */ 
- {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
-    /*1e */ 
- {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
-    /*1f */ 
- {_CWORD, offsetof(_cmsg, FacilitySelector)},
-    /*20 */ 
- {_CWORD, offsetof(_cmsg, Flags)},
-    /*21 */ 
- {_CDWORD, offsetof(_cmsg, Function)},
-    /*22 */ 
- {_CSTRUCT, offsetof(_cmsg, HLC)},
-    /*23 */ 
- {_CWORD, offsetof(_cmsg, Info)},
-    /*24 */ 
- {_CSTRUCT, offsetof(_cmsg, InfoElement)},
-    /*25 */ 
- {_CDWORD, offsetof(_cmsg, InfoMask)},
-    /*26 */ 
- {_CWORD, offsetof(_cmsg, InfoNumber)},
-    /*27 */ 
- {_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
-    /*28 */ 
- {_CSTRUCT, offsetof(_cmsg, LLC)},
-    /*29 */ 
- {_CSTRUCT, offsetof(_cmsg, ManuData)},
-    /*2a */ 
- {_CDWORD, offsetof(_cmsg, ManuID)},
-    /*2b */ 
- {_CSTRUCT, offsetof(_cmsg, NCPI)},
-    /*2c */ 
- {_CWORD, offsetof(_cmsg, Reason)},
-    /*2d */ 
- {_CWORD, offsetof(_cmsg, Reason_B3)},
-    /*2e */ 
- {_CWORD, offsetof(_cmsg, Reject)},
-    /*2f */ 
- {_CSTRUCT, offsetof(_cmsg, Useruserdata)}
+	/*00 */
+	{_CEND},
+	/*01 */
+	{_CEND},
+	/*02 */
+	{_CEND},
+	/*03 */
+	{_CDWORD, offsetof(_cmsg, adr.adrController)},
+	/*04 */
+	{_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)},
+	/*05 */
+	{_CSTRUCT, offsetof(_cmsg, B1configuration)},
+	/*06 */
+	{_CWORD, offsetof(_cmsg, B1protocol)},
+	/*07 */
+	{_CSTRUCT, offsetof(_cmsg, B2configuration)},
+	/*08 */
+	{_CWORD, offsetof(_cmsg, B2protocol)},
+	/*09 */
+	{_CSTRUCT, offsetof(_cmsg, B3configuration)},
+	/*0a */
+	{_CWORD, offsetof(_cmsg, B3protocol)},
+	/*0b */
+	{_CSTRUCT, offsetof(_cmsg, BC)},
+	/*0c */
+	{_CSTRUCT, offsetof(_cmsg, BChannelinformation)},
+	/*0d */
+	{_CMSTRUCT, offsetof(_cmsg, BProtocol)},
+	/*0e */
+	{_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)},
+	/*0f */
+	{_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)},
+	/*10 */
+	{_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)},
+	/*11 */
+	{_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)},
+	/*12 */
+	{_CDWORD, offsetof(_cmsg, CIPmask)},
+	/*13 */
+	{_CDWORD, offsetof(_cmsg, CIPmask2)},
+	/*14 */
+	{_CWORD, offsetof(_cmsg, CIPValue)},
+	/*15 */
+	{_CDWORD, offsetof(_cmsg, Class)},
+	/*16 */
+	{_CSTRUCT, offsetof(_cmsg, ConnectedNumber)},
+	/*17 */
+	{_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)},
+	/*18 */
+	{_CDWORD, offsetof(_cmsg, Data)},
+	/*19 */
+	{_CWORD, offsetof(_cmsg, DataHandle)},
+	/*1a */
+	{_CWORD, offsetof(_cmsg, DataLength)},
+	/*1b */
+	{_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)},
+	/*1c */
+	{_CSTRUCT, offsetof(_cmsg, Facilitydataarray)},
+	/*1d */
+	{_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)},
+	/*1e */
+	{_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)},
+	/*1f */
+	{_CWORD, offsetof(_cmsg, FacilitySelector)},
+	/*20 */
+	{_CWORD, offsetof(_cmsg, Flags)},
+	/*21 */
+	{_CDWORD, offsetof(_cmsg, Function)},
+	/*22 */
+	{_CSTRUCT, offsetof(_cmsg, HLC)},
+	/*23 */
+	{_CWORD, offsetof(_cmsg, Info)},
+	/*24 */
+	{_CSTRUCT, offsetof(_cmsg, InfoElement)},
+	/*25 */
+	{_CDWORD, offsetof(_cmsg, InfoMask)},
+	/*26 */
+	{_CWORD, offsetof(_cmsg, InfoNumber)},
+	/*27 */
+	{_CSTRUCT, offsetof(_cmsg, Keypadfacility)},
+	/*28 */
+	{_CSTRUCT, offsetof(_cmsg, LLC)},
+	/*29 */
+	{_CSTRUCT, offsetof(_cmsg, ManuData)},
+	/*2a */
+	{_CDWORD, offsetof(_cmsg, ManuID)},
+	/*2b */
+	{_CSTRUCT, offsetof(_cmsg, NCPI)},
+	/*2c */
+	{_CWORD, offsetof(_cmsg, Reason)},
+	/*2d */
+	{_CWORD, offsetof(_cmsg, Reason_B3)},
+	/*2e */
+	{_CWORD, offsetof(_cmsg, Reject)},
+	/*2f */
+	{_CSTRUCT, offsetof(_cmsg, Useruserdata)}
 };
 
 static unsigned char *cpars[] =
 {
-    /* ALERT_REQ */ [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
-    /* CONNECT_REQ */ [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
-    /* DISCONNECT_REQ */ [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
-    /* LISTEN_REQ */ [0x05] = "\x03\x25\x12\x13\x10\x11\x01",
-    /* INFO_REQ */ [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01",
-    /* FACILITY_REQ */ [0x09] = "\x03\x1f\x1e\x01",
-    /* SELECT_B_PROTOCOL_REQ */ [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
-    /* CONNECT_B3_REQ */ [0x0b] = "\x03\x2b\x01",
-    /* DISCONNECT_B3_REQ */ [0x0d] = "\x03\x2b\x01",
-    /* DATA_B3_REQ */ [0x0f] = "\x03\x18\x1a\x19\x20\x01",
-    /* RESET_B3_REQ */ [0x10] = "\x03\x2b\x01",
-    /* ALERT_CONF */ [0x13] = "\x03\x23\x01",
-    /* CONNECT_CONF */ [0x14] = "\x03\x23\x01",
-    /* DISCONNECT_CONF */ [0x16] = "\x03\x23\x01",
-    /* LISTEN_CONF */ [0x17] = "\x03\x23\x01",
-    /* MANUFACTURER_REQ */ [0x18] = "\x03\x2a\x15\x21\x29\x01",
-    /* INFO_CONF */ [0x1a] = "\x03\x23\x01",
-    /* FACILITY_CONF */ [0x1b] = "\x03\x23\x1f\x1b\x01",
-    /* SELECT_B_PROTOCOL_CONF */ [0x1c] = "\x03\x23\x01",
-    /* CONNECT_B3_CONF */ [0x1d] = "\x03\x23\x01",
-    /* DISCONNECT_B3_CONF */ [0x1f] = "\x03\x23\x01",
-    /* DATA_B3_CONF */ [0x21] = "\x03\x19\x23\x01",
-    /* RESET_B3_CONF */ [0x22] = "\x03\x23\x01",
-    /* CONNECT_IND */ [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
-    /* CONNECT_ACTIVE_IND */ [0x27] = "\x03\x16\x17\x28\x01",
-    /* DISCONNECT_IND */ [0x28] = "\x03\x2c\x01",
-    /* MANUFACTURER_CONF */ [0x2a] = "\x03\x2a\x15\x21\x29\x01",
-    /* INFO_IND */ [0x2c] = "\x03\x26\x24\x01",
-    /* FACILITY_IND */ [0x2d] = "\x03\x1f\x1d\x01",
-    /* CONNECT_B3_IND */ [0x2f] = "\x03\x2b\x01",
-    /* CONNECT_B3_ACTIVE_IND */ [0x30] = "\x03\x2b\x01",
-    /* DISCONNECT_B3_IND */ [0x31] = "\x03\x2d\x2b\x01",
-    /* DATA_B3_IND */ [0x33] = "\x03\x18\x1a\x19\x20\x01",
-    /* RESET_B3_IND */ [0x34] = "\x03\x2b\x01",
-    /* CONNECT_B3_T90_ACTIVE_IND */ [0x35] = "\x03\x2b\x01",
-    /* CONNECT_RESP */ [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01",
-    /* CONNECT_ACTIVE_RESP */ [0x39] = "\x03\x01",
-    /* DISCONNECT_RESP */ [0x3a] = "\x03\x01",
-    /* MANUFACTURER_IND */ [0x3c] = "\x03\x2a\x15\x21\x29\x01",
-    /* INFO_RESP */ [0x3e] = "\x03\x01",
-    /* FACILITY_RESP */ [0x3f] = "\x03\x1f\x01",
-    /* CONNECT_B3_RESP */ [0x41] = "\x03\x2e\x2b\x01",
-    /* CONNECT_B3_ACTIVE_RESP */ [0x42] = "\x03\x01",
-    /* DISCONNECT_B3_RESP */ [0x43] = "\x03\x01",
-    /* DATA_B3_RESP */ [0x45] = "\x03\x19\x01",
-    /* RESET_B3_RESP */ [0x46] = "\x03\x01",
-    /* CONNECT_B3_T90_ACTIVE_RESP */ [0x47] = "\x03\x01",
-    /* MANUFACTURER_RESP */ [0x4e] = "\x03\x2a\x15\x21\x29\x01",
+	/* ALERT_REQ */ [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
+	/* CONNECT_REQ */ [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
+	/* DISCONNECT_REQ */ [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01",
+	/* LISTEN_REQ */ [0x05] = "\x03\x25\x12\x13\x10\x11\x01",
+	/* INFO_REQ */ [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01",
+	/* FACILITY_REQ */ [0x09] = "\x03\x1f\x1e\x01",
+	/* SELECT_B_PROTOCOL_REQ */ [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01",
+	/* CONNECT_B3_REQ */ [0x0b] = "\x03\x2b\x01",
+	/* DISCONNECT_B3_REQ */ [0x0d] = "\x03\x2b\x01",
+	/* DATA_B3_REQ */ [0x0f] = "\x03\x18\x1a\x19\x20\x01",
+	/* RESET_B3_REQ */ [0x10] = "\x03\x2b\x01",
+	/* ALERT_CONF */ [0x13] = "\x03\x23\x01",
+	/* CONNECT_CONF */ [0x14] = "\x03\x23\x01",
+	/* DISCONNECT_CONF */ [0x16] = "\x03\x23\x01",
+	/* LISTEN_CONF */ [0x17] = "\x03\x23\x01",
+	/* MANUFACTURER_REQ */ [0x18] = "\x03\x2a\x15\x21\x29\x01",
+	/* INFO_CONF */ [0x1a] = "\x03\x23\x01",
+	/* FACILITY_CONF */ [0x1b] = "\x03\x23\x1f\x1b\x01",
+	/* SELECT_B_PROTOCOL_CONF */ [0x1c] = "\x03\x23\x01",
+	/* CONNECT_B3_CONF */ [0x1d] = "\x03\x23\x01",
+	/* DISCONNECT_B3_CONF */ [0x1f] = "\x03\x23\x01",
+	/* DATA_B3_CONF */ [0x21] = "\x03\x19\x23\x01",
+	/* RESET_B3_CONF */ [0x22] = "\x03\x23\x01",
+	/* CONNECT_IND */ [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01",
+	/* CONNECT_ACTIVE_IND */ [0x27] = "\x03\x16\x17\x28\x01",
+	/* DISCONNECT_IND */ [0x28] = "\x03\x2c\x01",
+	/* MANUFACTURER_CONF */ [0x2a] = "\x03\x2a\x15\x21\x29\x01",
+	/* INFO_IND */ [0x2c] = "\x03\x26\x24\x01",
+	/* FACILITY_IND */ [0x2d] = "\x03\x1f\x1d\x01",
+	/* CONNECT_B3_IND */ [0x2f] = "\x03\x2b\x01",
+	/* CONNECT_B3_ACTIVE_IND */ [0x30] = "\x03\x2b\x01",
+	/* DISCONNECT_B3_IND */ [0x31] = "\x03\x2d\x2b\x01",
+	/* DATA_B3_IND */ [0x33] = "\x03\x18\x1a\x19\x20\x01",
+	/* RESET_B3_IND */ [0x34] = "\x03\x2b\x01",
+	/* CONNECT_B3_T90_ACTIVE_IND */ [0x35] = "\x03\x2b\x01",
+	/* CONNECT_RESP */ [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01",
+	/* CONNECT_ACTIVE_RESP */ [0x39] = "\x03\x01",
+	/* DISCONNECT_RESP */ [0x3a] = "\x03\x01",
+	/* MANUFACTURER_IND */ [0x3c] = "\x03\x2a\x15\x21\x29\x01",
+	/* INFO_RESP */ [0x3e] = "\x03\x01",
+	/* FACILITY_RESP */ [0x3f] = "\x03\x1f\x01",
+	/* CONNECT_B3_RESP */ [0x41] = "\x03\x2e\x2b\x01",
+	/* CONNECT_B3_ACTIVE_RESP */ [0x42] = "\x03\x01",
+	/* DISCONNECT_B3_RESP */ [0x43] = "\x03\x01",
+	/* DATA_B3_RESP */ [0x45] = "\x03\x19\x01",
+	/* RESET_B3_RESP */ [0x46] = "\x03\x01",
+	/* CONNECT_B3_T90_ACTIVE_RESP */ [0x47] = "\x03\x01",
+	/* MANUFACTURER_RESP */ [0x4e] = "\x03\x2a\x15\x21\x29\x01",
 };
 
 /*-------------------------------------------------------*/
 
-#define byteTLcpy(x,y)        *(u8 *)(x)=*(u8 *)(y);
-#define wordTLcpy(x,y)        *(u16 *)(x)=*(u16 *)(y);
-#define dwordTLcpy(x,y)       memcpy(x,y,4);
-#define structTLcpy(x,y,l)    memcpy (x,y,l)
-#define structTLcpyovl(x,y,l) memmove (x,y,l)
+#define byteTLcpy(x, y)         *(u8 *)(x) = *(u8 *)(y);
+#define wordTLcpy(x, y)         *(u16 *)(x) = *(u16 *)(y);
+#define dwordTLcpy(x, y)        memcpy(x, y, 4);
+#define structTLcpy(x, y, l)    memcpy(x, y, l)
+#define structTLcpyovl(x, y, l) memmove(x, y, l)
 
-#define byteTRcpy(x,y)        *(u8 *)(y)=*(u8 *)(x);
-#define wordTRcpy(x,y)        *(u16 *)(y)=*(u16 *)(x);
-#define dwordTRcpy(x,y)       memcpy(y,x,4);
-#define structTRcpy(x,y,l)    memcpy (y,x,l)
-#define structTRcpyovl(x,y,l) memmove (y,x,l)
+#define byteTRcpy(x, y)         *(u8 *)(y) = *(u8 *)(x);
+#define wordTRcpy(x, y)         *(u16 *)(y) = *(u16 *)(x);
+#define dwordTRcpy(x, y)        memcpy(y, x, 4);
+#define structTRcpy(x, y, l)    memcpy(y, x, l)
+#define structTRcpyovl(x, y, l) memmove(y, x, l)
 
 /*-------------------------------------------------------*/
 static unsigned command_2_index(unsigned c, unsigned sc)
@@ -414,9 +414,9 @@ static unsigned command_2_index(unsigned c, unsigned sc)
 
 /*-------------------------------------------------------*/
 #define TYP (cdef[cmsg->par[cmsg->p]].typ)
-#define OFF (((u8 *)cmsg)+cdef[cmsg->par[cmsg->p]].off)
+#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off)
 
-static void jumpcstruct(_cmsg * cmsg)
+static void jumpcstruct(_cmsg *cmsg)
 {
 	unsigned layer;
 	for (cmsg->p++, layer = 1; layer;) {
@@ -433,7 +433,7 @@ static void jumpcstruct(_cmsg * cmsg)
 	}
 }
 /*-------------------------------------------------------*/
-static void pars_2_message(_cmsg * cmsg)
+static void pars_2_message(_cmsg *cmsg)
 {
 
 	for (; TYP != _CEND; cmsg->p++) {
@@ -499,7 +499,7 @@ static void pars_2_message(_cmsg * cmsg)
  * Return value: 0 for success
  */
 
-unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg)
+unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
 {
 	cmsg->m = msg;
 	cmsg->l = 8;
@@ -518,7 +518,7 @@ unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg)
 }
 
 /*-------------------------------------------------------*/
-static void message_2_pars(_cmsg * cmsg)
+static void message_2_pars(_cmsg *cmsg)
 {
 	for (; TYP != _CEND; cmsg->p++) {
 
@@ -569,7 +569,7 @@ static void message_2_pars(_cmsg * cmsg)
  * Return value: 0 for success
  */
 
-unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
+unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
 {
 	memset(cmsg, 0, sizeof(_cmsg));
 	cmsg->m = msg;
@@ -600,7 +600,7 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
  * Return value: 0 for success
  */
 
-unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId,
+unsigned capi_cmsg_header(_cmsg *cmsg, u16 _ApplId,
 			  u8 _Command, u8 _Subcommand,
 			  u16 _Messagenumber, u32 _Controller)
 {
@@ -689,54 +689,54 @@ char *capi_cmd2str(u8 cmd, u8 subcmd)
 
 static char *pnames[] =
 {
-    /*00 */ NULL,
-    /*01 */ NULL,
-    /*02 */ NULL,
-    /*03 */ "Controller/PLCI/NCCI",
-    /*04 */ "AdditionalInfo",
-    /*05 */ "B1configuration",
-    /*06 */ "B1protocol",
-    /*07 */ "B2configuration",
-    /*08 */ "B2protocol",
-    /*09 */ "B3configuration",
-    /*0a */ "B3protocol",
-    /*0b */ "BC",
-    /*0c */ "BChannelinformation",
-    /*0d */ "BProtocol",
-    /*0e */ "CalledPartyNumber",
-    /*0f */ "CalledPartySubaddress",
-    /*10 */ "CallingPartyNumber",
-    /*11 */ "CallingPartySubaddress",
-    /*12 */ "CIPmask",
-    /*13 */ "CIPmask2",
-    /*14 */ "CIPValue",
-    /*15 */ "Class",
-    /*16 */ "ConnectedNumber",
-    /*17 */ "ConnectedSubaddress",
-    /*18 */ "Data32",
-    /*19 */ "DataHandle",
-    /*1a */ "DataLength",
-    /*1b */ "FacilityConfirmationParameter",
-    /*1c */ "Facilitydataarray",
-    /*1d */ "FacilityIndicationParameter",
-    /*1e */ "FacilityRequestParameter",
-    /*1f */ "FacilitySelector",
-    /*20 */ "Flags",
-    /*21 */ "Function",
-    /*22 */ "HLC",
-    /*23 */ "Info",
-    /*24 */ "InfoElement",
-    /*25 */ "InfoMask",
-    /*26 */ "InfoNumber",
-    /*27 */ "Keypadfacility",
-    /*28 */ "LLC",
-    /*29 */ "ManuData",
-    /*2a */ "ManuID",
-    /*2b */ "NCPI",
-    /*2c */ "Reason",
-    /*2d */ "Reason_B3",
-    /*2e */ "Reject",
-    /*2f */ "Useruserdata"
+	/*00 */ NULL,
+	/*01 */ NULL,
+	/*02 */ NULL,
+	/*03 */ "Controller/PLCI/NCCI",
+	/*04 */ "AdditionalInfo",
+	/*05 */ "B1configuration",
+	/*06 */ "B1protocol",
+	/*07 */ "B2configuration",
+	/*08 */ "B2protocol",
+	/*09 */ "B3configuration",
+	/*0a */ "B3protocol",
+	/*0b */ "BC",
+	/*0c */ "BChannelinformation",
+	/*0d */ "BProtocol",
+	/*0e */ "CalledPartyNumber",
+	/*0f */ "CalledPartySubaddress",
+	/*10 */ "CallingPartyNumber",
+	/*11 */ "CallingPartySubaddress",
+	/*12 */ "CIPmask",
+	/*13 */ "CIPmask2",
+	/*14 */ "CIPValue",
+	/*15 */ "Class",
+	/*16 */ "ConnectedNumber",
+	/*17 */ "ConnectedSubaddress",
+	/*18 */ "Data32",
+	/*19 */ "DataHandle",
+	/*1a */ "DataLength",
+	/*1b */ "FacilityConfirmationParameter",
+	/*1c */ "Facilitydataarray",
+	/*1d */ "FacilityIndicationParameter",
+	/*1e */ "FacilityRequestParameter",
+	/*1f */ "FacilitySelector",
+	/*20 */ "Flags",
+	/*21 */ "Function",
+	/*22 */ "HLC",
+	/*23 */ "Info",
+	/*24 */ "InfoElement",
+	/*25 */ "InfoMask",
+	/*26 */ "InfoNumber",
+	/*27 */ "Keypadfacility",
+	/*28 */ "LLC",
+	/*29 */ "ManuData",
+	/*2a */ "ManuID",
+	/*2b */ "NCPI",
+	/*2c */ "Reason",
+	/*2d */ "Reason_B3",
+	/*2e */ "Reject",
+	/*2f */ "Useruserdata"
 };
 
 
@@ -744,10 +744,10 @@ static char *pnames[] =
 #include <stdarg.h>
 
 /*-------------------------------------------------------*/
-static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt,...)
+static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt, ...)
 {
 	va_list f;
-	size_t n,r;
+	size_t n, r;
 
 	if (!cdb)
 		return NULL;
@@ -783,7 +783,7 @@ static _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt,...)
 	return cdb;
 }
 
-static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 * m, unsigned len)
+static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 *m, unsigned len)
 {
 	unsigned hex = 0;
 
@@ -807,7 +807,7 @@ static _cdebbuf *printstructlen(_cdebbuf *cdb, u8 * m, unsigned len)
 	return cdb;
 }
 
-static _cdebbuf *printstruct(_cdebbuf *cdb, u8 * m)
+static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m)
 {
 	unsigned len;
 
@@ -940,7 +940,7 @@ void cdebbuf_free(_cdebbuf *cdb)
  * The returned buffer should be freed by a call to cdebbuf_free() after use.
  */
 
-_cdebbuf *capi_message2str(u8 * msg)
+_cdebbuf *capi_message2str(u8 *msg)
 {
 	_cdebbuf *cdb;
 	_cmsg	*cmsg;
@@ -964,10 +964,10 @@ _cdebbuf *capi_message2str(u8 * msg)
 	cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)];
 
 	cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
-		 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
-		 ((unsigned short *) msg)[1],
-		 ((unsigned short *) msg)[3],
-		 ((unsigned short *) msg)[0]);
+		       mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
+		       ((unsigned short *) msg)[1],
+		       ((unsigned short *) msg)[3],
+		       ((unsigned short *) msg)[0]);
 
 	cdb = protocol_message_2_pars(cdb, cmsg, 1);
 	if (unlikely(cmsg != g_cmsg))
@@ -986,7 +986,7 @@ _cdebbuf *capi_message2str(u8 * msg)
  * The returned buffer should be freed by a call to cdebbuf_free() after use.
  */
 
-_cdebbuf *capi_cmsg2str(_cmsg * cmsg)
+_cdebbuf *capi_cmsg2str(_cmsg *cmsg)
 {
 	_cdebbuf *cdb;
 
@@ -998,17 +998,17 @@ _cdebbuf *capi_cmsg2str(_cmsg * cmsg)
 	cmsg->l = 8;
 	cmsg->p = 0;
 	cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n",
-		 mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
-		 ((u16 *) cmsg->m)[1],
-		 ((u16 *) cmsg->m)[3],
-		 ((u16 *) cmsg->m)[0]);
+		       mnames[command_2_index(cmsg->Command, cmsg->Subcommand)],
+		       ((u16 *) cmsg->m)[1],
+		       ((u16 *) cmsg->m)[3],
+		       ((u16 *) cmsg->m)[0]);
 	cdb = protocol_message_2_pars(cdb, cmsg, 1);
 	return cdb;
 }
 
 int __init cdebug_init(void)
 {
-	g_cmsg= kmalloc(sizeof(_cmsg), GFP_KERNEL);
+	g_cmsg = kmalloc(sizeof(_cmsg), GFP_KERNEL);
 	if (!g_cmsg)
 		return -ENOMEM;
 	g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL);
@@ -1041,12 +1041,12 @@ void __exit cdebug_exit(void)
 
 static _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0};
 
-_cdebbuf *capi_message2str(u8 * msg)
+_cdebbuf *capi_message2str(u8 *msg)
 {
 	return &g_debbuf;
 }
 
-_cdebbuf *capi_cmsg2str(_cmsg * cmsg)
+_cdebbuf *capi_cmsg2str(_cmsg *cmsg)
 {
 	return &g_debbuf;
 }
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 2b33b26..9b1b274 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -1,10 +1,10 @@
 /* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $
- * 
+ *
  * Kernel CAPI 2.0 Module
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -55,7 +55,7 @@ struct capictr_event {
 
 /* ------------------------------------------------------------- */
 
-static struct capi_version driver_version = {2, 0, 1, 1<<4};
+static struct capi_version driver_version = {2, 0, 1, 1 << 4};
 static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
 static char capi_manufakturer[64] = "AVM Berlin";
 
@@ -172,7 +172,7 @@ register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
 static void release_appl(struct capi_ctr *ctr, u16 applid)
 {
 	DBG("applid %#x", applid);
-	
+
 	ctr->release_appl(ctr, applid);
 	capi_ctr_put(ctr);
 }
@@ -186,7 +186,7 @@ static void notify_up(u32 contr)
 	mutex_lock(&capi_controller_lock);
 
 	if (showcapimsgs & 1)
-	        printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
+		printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
 
 	ctr = get_capi_ctr_by_nr(contr);
 	if (ctr) {
@@ -352,16 +352,16 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
 		cdb = capi_message2str(skb->data);
 		if (cdb) {
 			printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
-				ctr->cnr, cdb->buf);
+			       ctr->cnr, cdb->buf);
 			cdebbuf_free(cdb);
 		} else
 			printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
-				ctr->cnr);
+			       ctr->cnr);
 		goto error;
 	}
 
 	cmd = CAPIMSG_COMMAND(skb->data);
-        subcmd = CAPIMSG_SUBCOMMAND(skb->data);
+	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
 		ctr->nrecvdatapkt++;
 		if (ctr->traceflag > 2)
@@ -382,13 +382,13 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
 			cdb = capi_message2str(skb->data);
 			if (cdb) {
 				printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
-					ctr->cnr, cdb->buf);
+				       ctr->cnr, cdb->buf);
 				cdebbuf_free(cdb);
 			} else
 				printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
-					ctr->cnr, CAPIMSG_APPID(skb->data),
-					capi_cmd2str(cmd, subcmd),
-					CAPIMSG_LEN(skb->data));
+				       ctr->cnr, CAPIMSG_APPID(skb->data),
+				       capi_cmd2str(cmd, subcmd),
+				       CAPIMSG_LEN(skb->data));
 		}
 
 	}
@@ -400,12 +400,12 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
 		cdb = capi_message2str(skb->data);
 		if (cdb) {
 			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
-			CAPIMSG_APPID(skb->data), cdb->buf);
+			       CAPIMSG_APPID(skb->data), cdb->buf);
 			cdebbuf_free(cdb);
 		} else
 			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
-				CAPIMSG_APPID(skb->data),
-				capi_cmd2str(cmd, subcmd));
+			       CAPIMSG_APPID(skb->data),
+			       capi_cmd2str(cmd, subcmd));
 		goto error;
 	}
 	skb_queue_tail(&ap->recv_queue, skb);
@@ -519,7 +519,7 @@ int attach_capi_ctr(struct capi_ctr *ctr)
 	if (i == CAPI_MAXCONTR) {
 		mutex_unlock(&capi_controller_lock);
 		printk(KERN_ERR "kcapi: out of controller slots\n");
-	   	return -EBUSY;
+		return -EBUSY;
 	}
 	capi_controller[i] = ctr;
 
@@ -541,7 +541,7 @@ int attach_capi_ctr(struct capi_ctr *ctr)
 	mutex_unlock(&capi_controller_lock);
 
 	printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
-			ctr->cnr, ctr->name);
+	       ctr->cnr, ctr->name);
 	return 0;
 }
 
@@ -772,7 +772,7 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
 	u8 cmd, subcmd;
 
 	DBG("applid %#x", ap->applid);
- 
+
 	if (ncontrollers == 0)
 		return CAPI_REGNOTINSTALLED;
 	if ((ap->applid == 0) || ap->release_in_progress)
@@ -794,9 +794,9 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
 		return CAPI_SENDQUEUEFULL;
 
 	cmd = CAPIMSG_COMMAND(skb->data);
-        subcmd = CAPIMSG_SUBCOMMAND(skb->data);
+	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
 
-	if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
+	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
 		ctr->nsentdatapkt++;
 		ap->nsentdatapkt++;
 		if (ctr->traceflag > 2)
@@ -819,15 +819,15 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
 			_cdebbuf *cdb = capi_message2str(skb->data);
 			if (cdb) {
 				printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
-					CAPIMSG_CONTROLLER(skb->data),
-					cdb->buf);
+				       CAPIMSG_CONTROLLER(skb->data),
+				       cdb->buf);
 				cdebbuf_free(cdb);
 			} else
 				printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
-					CAPIMSG_CONTROLLER(skb->data),
-					CAPIMSG_APPID(skb->data),
-					capi_cmd2str(cmd, subcmd),
-					CAPIMSG_LEN(skb->data));
+				       CAPIMSG_CONTROLLER(skb->data),
+				       CAPIMSG_APPID(skb->data),
+				       capi_cmd2str(cmd, subcmd),
+				       CAPIMSG_LEN(skb->data));
 		}
 	}
 	return ctr->send_message(ctr, skb);
@@ -1028,14 +1028,14 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
 	case AVMB1_ADDCARD:
 	case AVMB1_ADDCARD_WITH_TYPE:
 		if (cmd == AVMB1_ADDCARD) {
-		   if ((retval = copy_from_user(&cdef, data,
-					    sizeof(avmb1_carddef))))
-			   return -EFAULT;
-		   cdef.cardtype = AVM_CARDTYPE_B1;
+			if ((retval = copy_from_user(&cdef, data,
+						     sizeof(avmb1_carddef))))
+				return -EFAULT;
+			cdef.cardtype = AVM_CARDTYPE_B1;
 		} else {
-		   if ((retval = copy_from_user(&cdef, data,
-					    sizeof(avmb1_extcarddef))))
-			   return -EFAULT;
+			if ((retval = copy_from_user(&cdef, data,
+						     sizeof(avmb1_extcarddef))))
+				return -EFAULT;
 		}
 		cparams.port = cdef.port;
 		cparams.irq = cdef.irq;
@@ -1043,24 +1043,24 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
 
 		mutex_lock(&capi_drivers_lock);
 
-                switch (cdef.cardtype) {
-			case AVM_CARDTYPE_B1:
-				list_for_each(l, &capi_drivers) {
-					driver = list_entry(l, struct capi_driver, list);
-					if (strcmp(driver->name, "b1isa") == 0)
-						break;
-				}
-				break;
-			case AVM_CARDTYPE_T1:
-				list_for_each(l, &capi_drivers) {
-					driver = list_entry(l, struct capi_driver, list);
-					if (strcmp(driver->name, "t1isa") == 0)
-						break;
-				}
-				break;
-			default:
-				driver = NULL;
-				break;
+		switch (cdef.cardtype) {
+		case AVM_CARDTYPE_B1:
+			list_for_each(l, &capi_drivers) {
+				driver = list_entry(l, struct capi_driver, list);
+				if (strcmp(driver->name, "b1isa") == 0)
+					break;
+			}
+			break;
+		case AVM_CARDTYPE_T1:
+			list_for_each(l, &capi_drivers) {
+				driver = list_entry(l, struct capi_driver, list);
+				if (strcmp(driver->name, "t1isa") == 0)
+					break;
+			}
+			break;
+		default:
+			driver = NULL;
+			break;
 		}
 		if (!driver) {
 			printk(KERN_ERR "kcapi: driver not loaded.\n");
@@ -1136,7 +1136,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
 
 		retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING);
 
-load_unlock_out:
+	load_unlock_out:
 		mutex_unlock(&capi_controller_lock);
 		return retval;
 
@@ -1167,7 +1167,7 @@ load_unlock_out:
 
 		retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
 
-reset_unlock_out:
+	reset_unlock_out:
 		mutex_unlock(&capi_controller_lock);
 		return retval;
 	}
@@ -1235,7 +1235,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
 		cparams.membase = cdef.membase;
 		cparams.cardnr = cdef.cardnr;
 		cparams.cardtype = 0;
-		cdef.driver[sizeof(cdef.driver)-1] = 0;
+		cdef.driver[sizeof(cdef.driver) - 1] = 0;
 
 		mutex_lock(&capi_drivers_lock);
 
@@ -1246,7 +1246,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
 		}
 		if (driver == NULL) {
 			printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
-					cdef.driver);
+			       cdef.driver);
 			retval = -ESRCH;
 		} else if (!driver->add_card) {
 			printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
@@ -1260,7 +1260,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
 
 	default:
 		printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
-					cmd);
+		       cmd);
 		break;
 
 	}
@@ -1305,7 +1305,7 @@ static int __init kcapi_init(void)
 
 static void __exit kcapi_exit(void)
 {
-        kcapi_proc_exit();
+	kcapi_proc_exit();
 
 	unregister_capictr_notifier(&capictr_nb);
 	cdebug_exit();
diff --git a/drivers/isdn/capi/kcapi.h b/drivers/isdn/capi/kcapi.h
index f4620b3..6d439f9 100644
--- a/drivers/isdn/capi/kcapi.h
+++ b/drivers/isdn/capi/kcapi.h
@@ -1,9 +1,9 @@
 /*
  * Kernel CAPI 2.0 Module
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -16,9 +16,9 @@
 #include <linux/isdn/capilli.h>
 
 #ifdef KCAPI_DEBUG
-#define DBG(format, arg...) do { \
-printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
-} while (0)
+#define DBG(format, arg...) do {					\
+		printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
+	} while (0)
 #else
 #define DBG(format, arg...) /* */
 #endif
@@ -49,4 +49,3 @@ static inline void kcapi_proc_init(void) { };
 static inline void kcapi_proc_exit(void) { };
 
 #endif
-
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index 8d51cd1..68db3c5 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -1,9 +1,9 @@
 /*
  * Kernel CAPI 2.0 Module - /proc/capi handling
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -29,7 +29,7 @@ static char *state2str(unsigned short state)
 // /proc/capi
 // ===========================================================================
 
-// /proc/capi/controller: 
+// /proc/capi/controller:
 //      cnr driver cardstate name driverinfo
 // /proc/capi/contrstats:
 //      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
@@ -85,7 +85,7 @@ static int contrstats_show(struct seq_file *seq, void *v)
 		return 0;
 
 	seq_printf(seq, "%d %lu %lu %lu %lu\n",
-		   ctr->cnr, 
+		   ctr->cnr,
 		   ctr->nrecvctlpkt,
 		   ctr->nrecvdatapkt,
 		   ctr->nsentctlpkt,
@@ -134,9 +134,9 @@ static const struct file_operations proc_contrstats_ops = {
 	.release	= seq_release,
 };
 
-// /proc/capi/applications: 
+// /proc/capi/applications:
 //      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
-// /proc/capi/applstats: 
+// /proc/capi/applstats:
 //      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
 // ---------------------------------------------------------------------------
 
@@ -297,7 +297,7 @@ static const struct file_operations proc_driver_ops = {
 
 // ---------------------------------------------------------------------------
 
-void __init 
+void __init
 kcapi_proc_init(void)
 {
 	proc_mkdir("capi",             NULL);
diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c
index 2f7c9fc..5374c25 100644
--- a/drivers/isdn/divert/divert_init.c
+++ b/drivers/isdn/divert/divert_init.c
@@ -3,7 +3,7 @@
  * Module init for DSS1 diversion services for i4l.
  *
  * Copyright 1999       by Werner Cornelius (werner@isdn4linux.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -23,13 +23,13 @@ MODULE_LICENSE("GPL");
 /* structure containing interface to hl */
 /****************************************/
 isdn_divert_if divert_if =
-  { DIVERT_IF_MAGIC,  /* magic value */
-    DIVERT_CMD_REG,   /* register cmd */
-    ll_callback,      /* callback routine from ll */
-    NULL,             /* command still not specified */
-    NULL,             /* drv_to_name */
-    NULL,             /* name_to_drv */
-  };
+{ DIVERT_IF_MAGIC,  /* magic value */
+  DIVERT_CMD_REG,   /* register cmd */
+  ll_callback,      /* callback routine from ll */
+  NULL,             /* command still not specified */
+  NULL,             /* drv_to_name */
+  NULL,             /* name_to_drv */
+};
 
 /*************************/
 /* Module interface code */
@@ -38,17 +38,17 @@ isdn_divert_if divert_if =
 static int __init divert_init(void)
 { int i;
 
-  if (divert_dev_init())
-   { printk(KERN_WARNING "dss1_divert: cannot install device, not loaded\n");
-     return(-EIO);
-   }
-  if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR)
-   { divert_dev_deinit();
-     printk(KERN_WARNING "dss1_divert: error %d registering module, not loaded\n",i);
-     return(-EIO);
-   } 
-  printk(KERN_INFO "dss1_divert module successfully installed\n");
-  return(0);
+	if (divert_dev_init())
+	{ printk(KERN_WARNING "dss1_divert: cannot install device, not loaded\n");
+		return (-EIO);
+	}
+	if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR)
+	{ divert_dev_deinit();
+		printk(KERN_WARNING "dss1_divert: error %d registering module, not loaded\n", i);
+		return (-EIO);
+	}
+	printk(KERN_INFO "dss1_divert module successfully installed\n");
+	return (0);
 }
 
 /**********************/
@@ -56,27 +56,26 @@ static int __init divert_init(void)
 /**********************/
 static void __exit divert_exit(void)
 {
-  unsigned long flags;
-  int i;
+	unsigned long flags;
+	int i;
 
-  spin_lock_irqsave(&divert_lock, flags);
-  divert_if.cmd = DIVERT_CMD_REL; /* release */
-  if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR)
-   { printk(KERN_WARNING "dss1_divert: error %d releasing module\n",i);
-     spin_unlock_irqrestore(&divert_lock, flags);
-     return;
-   } 
-  if (divert_dev_deinit()) 
-   { printk(KERN_WARNING "dss1_divert: device busy, remove cancelled\n");
-     spin_unlock_irqrestore(&divert_lock, flags);
-     return;
-   }
-  spin_unlock_irqrestore(&divert_lock, flags);
-  deleterule(-1); /* delete all rules and free mem */
-  deleteprocs();
-  printk(KERN_INFO "dss1_divert module successfully removed \n");
+	spin_lock_irqsave(&divert_lock, flags);
+	divert_if.cmd = DIVERT_CMD_REL; /* release */
+	if ((i = DIVERT_REG_NAME(&divert_if)) != DIVERT_NO_ERR)
+	{ printk(KERN_WARNING "dss1_divert: error %d releasing module\n", i);
+		spin_unlock_irqrestore(&divert_lock, flags);
+		return;
+	}
+	if (divert_dev_deinit())
+	{ printk(KERN_WARNING "dss1_divert: device busy, remove cancelled\n");
+		spin_unlock_irqrestore(&divert_lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(&divert_lock, flags);
+	deleterule(-1); /* delete all rules and free mem */
+	deleteprocs();
+	printk(KERN_INFO "dss1_divert module successfully removed \n");
 }
 
 module_init(divert_init);
 module_exit(divert_exit);
-
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 9021182..fb4f1ba 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -50,10 +50,10 @@ put_info_buffer(char *cp)
 	if (!*cp)
 		return;
 	if (!(ib = kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC)))
-		 return;	/* no memory */
+		return;	/* no memory */
 	strcpy(ib->info_start, cp);	/* set output string */
 	ib->next = NULL;
-	spin_lock_irqsave( &divert_info_lock, flags );
+	spin_lock_irqsave(&divert_info_lock, flags);
 	ib->usage_cnt = if_used;
 	if (!divert_info_head)
 		divert_info_head = ib;	/* new head */
@@ -71,7 +71,7 @@ put_info_buffer(char *cp)
 		} else
 			break;
 	}			/* divert_info_head->next */
-	spin_unlock_irqrestore( &divert_info_lock, flags );
+	spin_unlock_irqrestore(&divert_info_lock, flags);
 	wake_up_interruptible(&(rd_queue));
 }				/* put_info_buffer */
 
@@ -81,7 +81,7 @@ put_info_buffer(char *cp)
 /* deflection device read routine */
 /**********************************/
 static ssize_t
-isdn_divert_read(struct file *file, char __user *buf, size_t count, loff_t * off)
+isdn_divert_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
 	struct divert_info *inf;
 	int len;
@@ -109,7 +109,7 @@ isdn_divert_read(struct file *file, char __user *buf, size_t count, loff_t * off
 /* deflection device write routine */
 /**********************************/
 static ssize_t
-isdn_divert_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
+isdn_divert_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
 {
 	return (-ENODEV);
 }				/* isdn_divert_write */
@@ -119,7 +119,7 @@ isdn_divert_write(struct file *file, const char __user *buf, size_t count, loff_
 /* select routines for various kernels */
 /***************************************/
 static unsigned int
-isdn_divert_poll(struct file *file, poll_table * wait)
+isdn_divert_poll(struct file *file, poll_table *wait)
 {
 	unsigned int mask = 0;
 
@@ -139,13 +139,13 @@ isdn_divert_open(struct inode *ino, struct file *filep)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave( &divert_info_lock, flags );
- 	if_used++;
+	spin_lock_irqsave(&divert_info_lock, flags);
+	if_used++;
 	if (divert_info_head)
 		filep->private_data = &(divert_info_tail->next);
 	else
 		filep->private_data = &divert_info_head;
-	spin_unlock_irqrestore( &divert_info_lock, flags );
+	spin_unlock_irqrestore(&divert_info_lock, flags);
 	/*  start_divert(); */
 	return nonseekable_open(ino, filep);
 }				/* isdn_divert_open */
@@ -159,7 +159,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
 	struct divert_info *inf;
 	unsigned long flags;
 
-	spin_lock_irqsave( &divert_info_lock, flags );
+	spin_lock_irqsave(&divert_info_lock, flags);
 	if_used--;
 	inf = *((struct divert_info **) filep->private_data);
 	while (inf) {
@@ -172,7 +172,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
 			divert_info_head = divert_info_head->next;
 			kfree(inf);
 		}
-	spin_unlock_irqrestore( &divert_info_lock, flags );
+	spin_unlock_irqrestore(&divert_info_lock, flags);
 	return (0);
 }				/* isdn_divert_close */
 
@@ -191,75 +191,75 @@ static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg)
 		return -EFAULT;
 
 	switch (cmd) {
-		case IIOCGETVER:
-			dioctl.drv_version = DIVERT_IIOC_VERSION;	/* set version */
-			break;
-
-		case IIOCGETDRV:
-			if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0)
-				return (-EINVAL);
-			break;
-
-		case IIOCGETNAM:
-			cp = divert_if.drv_to_name(dioctl.getid.drvid);
-			if (!cp)
-				return (-EINVAL);
-			if (!*cp)
-				return (-EINVAL);
-			strcpy(dioctl.getid.drvnam, cp);
-			break;
-
-		case IIOCGETRULE:
-			if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
-				return (-EINVAL);
-			dioctl.getsetrule.rule = *rulep;	/* copy data */
-			break;
-
-		case IIOCMODRULE:
-			if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
-				return (-EINVAL);
-            spin_lock_irqsave(&divert_lock, flags);
-			*rulep = dioctl.getsetrule.rule;	/* copy data */
-			spin_unlock_irqrestore(&divert_lock, flags);
-			return (0);	/* no copy required */
-			break;
+	case IIOCGETVER:
+		dioctl.drv_version = DIVERT_IIOC_VERSION;	/* set version */
+		break;
 
-		case IIOCINSRULE:
-			return (insertrule(dioctl.getsetrule.ruleidx, &dioctl.getsetrule.rule));
-			break;
+	case IIOCGETDRV:
+		if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0)
+			return (-EINVAL);
+		break;
 
-		case IIOCDELRULE:
-			return (deleterule(dioctl.getsetrule.ruleidx));
-			break;
+	case IIOCGETNAM:
+		cp = divert_if.drv_to_name(dioctl.getid.drvid);
+		if (!cp)
+			return (-EINVAL);
+		if (!*cp)
+			return (-EINVAL);
+		strcpy(dioctl.getid.drvnam, cp);
+		break;
 
-		case IIOCDODFACT:
-			return (deflect_extern_action(dioctl.fwd_ctrl.subcmd,
-						  dioctl.fwd_ctrl.callid,
-						 dioctl.fwd_ctrl.to_nr));
-
-		case IIOCDOCFACT:
-		case IIOCDOCFDIS:
-		case IIOCDOCFINT:
-			if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
-				return (-EINVAL);	/* invalid driver */
-			if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) ==
-					sizeof(dioctl.cf_ctrl.msn))
-				return -EINVAL;
-			if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) ==
-					sizeof(dioctl.cf_ctrl.fwd_nr))
-				return -EINVAL;
-			if ((i = cf_command(dioctl.cf_ctrl.drvid,
-					    (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
-					    dioctl.cf_ctrl.cfproc,
-					    dioctl.cf_ctrl.msn,
-					    dioctl.cf_ctrl.service,
-					    dioctl.cf_ctrl.fwd_nr,
-					    &dioctl.cf_ctrl.procid)))
-				return (i);
-			break;
+	case IIOCGETRULE:
+		if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
+			return (-EINVAL);
+		dioctl.getsetrule.rule = *rulep;	/* copy data */
+		break;
 
-		default:
+	case IIOCMODRULE:
+		if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
 			return (-EINVAL);
+		spin_lock_irqsave(&divert_lock, flags);
+		*rulep = dioctl.getsetrule.rule;	/* copy data */
+		spin_unlock_irqrestore(&divert_lock, flags);
+		return (0);	/* no copy required */
+		break;
+
+	case IIOCINSRULE:
+		return (insertrule(dioctl.getsetrule.ruleidx, &dioctl.getsetrule.rule));
+		break;
+
+	case IIOCDELRULE:
+		return (deleterule(dioctl.getsetrule.ruleidx));
+		break;
+
+	case IIOCDODFACT:
+		return (deflect_extern_action(dioctl.fwd_ctrl.subcmd,
+					      dioctl.fwd_ctrl.callid,
+					      dioctl.fwd_ctrl.to_nr));
+
+	case IIOCDOCFACT:
+	case IIOCDOCFDIS:
+	case IIOCDOCFINT:
+		if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
+			return (-EINVAL);	/* invalid driver */
+		if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) ==
+		    sizeof(dioctl.cf_ctrl.msn))
+			return -EINVAL;
+		if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) ==
+		    sizeof(dioctl.cf_ctrl.fwd_nr))
+			return -EINVAL;
+		if ((i = cf_command(dioctl.cf_ctrl.drvid,
+				    (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
+				    dioctl.cf_ctrl.cfproc,
+				    dioctl.cf_ctrl.msn,
+				    dioctl.cf_ctrl.service,
+				    dioctl.cf_ctrl.fwd_nr,
+				    &dioctl.cf_ctrl.procid)))
+			return (i);
+		break;
+
+	default:
+		return (-EINVAL);
 	}			/* switch cmd */
 	return copy_to_user((void __user *)arg, &dioctl, sizeof(dioctl)) ? -EFAULT : 0;
 }				/* isdn_divert_ioctl */
@@ -284,7 +284,7 @@ static const struct file_operations isdn_fops =
 	.poll           = isdn_divert_poll,
 	.unlocked_ioctl = isdn_divert_ioctl,
 	.open           = isdn_divert_open,
-	.release        = isdn_divert_close,                                      
+	.release        = isdn_divert_close,
 };
 
 /****************************/
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 48e6d22..e61e55f 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -3,7 +3,7 @@
  * DSS1 main diversion supplementary handling for i4l.
  *
  * Copyright 1999       by Werner Cornelius (werner@isdn4linux.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -20,24 +20,24 @@
 /* structure keeping calling info */
 /**********************************/
 struct call_struc
-  { isdn_ctrl ics; /* delivered setup + driver parameters */
-    ulong divert_id; /* Id delivered to user */
-    unsigned char akt_state; /* actual state */
-    char deflect_dest[35]; /* deflection destination */   
-    struct timer_list timer; /* timer control structure */
-    char info[90]; /* device info output */ 
-    struct call_struc *next; /* pointer to next entry */
-    struct call_struc *prev;
-  };
+{ isdn_ctrl ics; /* delivered setup + driver parameters */
+	ulong divert_id; /* Id delivered to user */
+	unsigned char akt_state; /* actual state */
+	char deflect_dest[35]; /* deflection destination */
+	struct timer_list timer; /* timer control structure */
+	char info[90]; /* device info output */
+	struct call_struc *next; /* pointer to next entry */
+	struct call_struc *prev;
+};
 
 
 /********************************************/
 /* structure keeping deflection table entry */
 /********************************************/
 struct deflect_struc
-  { struct deflect_struc *next,*prev; 
-    divert_rule rule; /* used rule */
-  };
+{ struct deflect_struc *next, *prev;
+	divert_rule rule; /* used rule */
+};
 
 
 /*****************************************/
@@ -45,10 +45,10 @@ struct deflect_struc
 /*****************************************/
 /* diversion/deflection processes */
 static struct call_struc *divert_head = NULL; /* head of remembered entrys */
-static ulong next_id = 1; /* next info id */   
+static ulong next_id = 1; /* next info id */
 static struct deflect_struc *table_head = NULL;
-static struct deflect_struc *table_tail = NULL; 
-static unsigned char extern_wait_max = 4; /* maximum wait in s for external process */ 
+static struct deflect_struc *table_tail = NULL;
+static unsigned char extern_wait_max = 4; /* maximum wait in s for external process */
 
 DEFINE_SPINLOCK(divert_lock);
 
@@ -57,50 +57,50 @@ DEFINE_SPINLOCK(divert_lock);
 /***************************/
 static void deflect_timer_expire(ulong arg)
 {
-  unsigned long flags;
-  struct call_struc *cs = (struct call_struc *) arg;
-
-  spin_lock_irqsave(&divert_lock, flags);
-  del_timer(&cs->timer); /* delete active timer */
-  spin_unlock_irqrestore(&divert_lock, flags);
-
-  switch(cs->akt_state)
-   { case DEFLECT_PROCEED:
-       cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */
-       divert_if.ll_cmd(&cs->ics);                   	  
-       spin_lock_irqsave(&divert_lock, flags);
-       cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
-       cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
-       add_timer(&cs->timer);
-       spin_unlock_irqrestore(&divert_lock, flags);
-       break;
-
-     case DEFLECT_ALERT:
-       cs->ics.command = ISDN_CMD_REDIR; /* protocol */
-       strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone));
-       strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed");
-       divert_if.ll_cmd(&cs->ics);
-       spin_lock_irqsave(&divert_lock, flags);
-       cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
-       cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
-       add_timer(&cs->timer);
-       spin_unlock_irqrestore(&divert_lock, flags);
-       break;
-
-     case DEFLECT_AUTODEL:
-     default:
-       spin_lock_irqsave(&divert_lock, flags);
-       if (cs->prev) 
-         cs->prev->next = cs->next; /* forward link */
-        else
-         divert_head = cs->next;
-       if (cs->next)
-         cs->next->prev = cs->prev; /* back link */           
-       spin_unlock_irqrestore(&divert_lock, flags);
-       kfree(cs);
-       return;
-
-   } /* switch */
+	unsigned long flags;
+	struct call_struc *cs = (struct call_struc *) arg;
+
+	spin_lock_irqsave(&divert_lock, flags);
+	del_timer(&cs->timer); /* delete active timer */
+	spin_unlock_irqrestore(&divert_lock, flags);
+
+	switch (cs->akt_state)
+	{ case DEFLECT_PROCEED:
+			cs->ics.command = ISDN_CMD_HANGUP; /* cancel action */
+			divert_if.ll_cmd(&cs->ics);
+			spin_lock_irqsave(&divert_lock, flags);
+			cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
+			cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
+			add_timer(&cs->timer);
+			spin_unlock_irqrestore(&divert_lock, flags);
+			break;
+
+	case DEFLECT_ALERT:
+		cs->ics.command = ISDN_CMD_REDIR; /* protocol */
+		strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone));
+		strcpy(cs->ics.parm.setup.eazmsn, "Testtext delayed");
+		divert_if.ll_cmd(&cs->ics);
+		spin_lock_irqsave(&divert_lock, flags);
+		cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
+		cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
+		add_timer(&cs->timer);
+		spin_unlock_irqrestore(&divert_lock, flags);
+		break;
+
+	case DEFLECT_AUTODEL:
+	default:
+		spin_lock_irqsave(&divert_lock, flags);
+		if (cs->prev)
+			cs->prev->next = cs->next; /* forward link */
+		else
+			divert_head = cs->next;
+		if (cs->next)
+			cs->next->prev = cs->prev; /* back link */
+		spin_unlock_irqrestore(&divert_lock, flags);
+		kfree(cs);
+		return;
+
+	} /* switch */
 } /* deflect_timer_func */
 
 
@@ -108,94 +108,94 @@ static void deflect_timer_expire(ulong arg)
 /* handle call forwarding de/activations */
 /* 0 = deact, 1 = act, 2 = interrogate   */
 /*****************************************/
-int cf_command(int drvid, int mode, 
-               u_char proc, char *msn, 
-               u_char service, char *fwd_nr, ulong *procid)
+int cf_command(int drvid, int mode,
+	       u_char proc, char *msn,
+	       u_char service, char *fwd_nr, ulong *procid)
 { unsigned long flags;
-  int retval,msnlen;
-  int fwd_len;
-  char *p,*ielenp,tmp[60];
-  struct call_struc *cs;
-
-  if (strchr(msn,'.')) return(-EINVAL); /* subaddress not allowed in msn */
-  if ((proc & 0x7F) > 2) return(-EINVAL);
-  proc &= 3;
-  p = tmp;
-  *p++ = 0x30; /* enumeration */
-  ielenp = p++; /* remember total length position */
-  *p++ = 0xa; /* proc tag */
-  *p++ = 1;   /* length */
-  *p++ = proc & 0x7F; /* procedure to de/activate/interrogate */
-  *p++ = 0xa; /* service tag */
-  *p++ = 1;   /* length */
-  *p++ = service; /* service to handle */
-
-  if (mode == 1) 
-   { if (!*fwd_nr) return(-EINVAL); /* destination missing */
-     if (strchr(fwd_nr,'.')) return(-EINVAL); /* subaddress not allowed */
-     fwd_len = strlen(fwd_nr);
-     *p++ = 0x30; /* number enumeration */
-     *p++ = fwd_len + 2; /* complete forward to len */ 
-     *p++ = 0x80; /* fwd to nr */
-     *p++ = fwd_len; /* length of number */
-     strcpy(p,fwd_nr); /* copy number */
-     p += fwd_len; /* pointer beyond fwd */
-   } /* activate */
-
-  msnlen = strlen(msn);
-  *p++ = 0x80; /* msn number */
-  if (msnlen > 1)
-   { *p++ = msnlen; /* length */
-     strcpy(p,msn);
-     p += msnlen;
-   }
-  else *p++ = 0;
-
-  *ielenp = p - ielenp - 1; /* set total IE length */ 
-
-  /* allocate mem for information struct */  
-  if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
-             return(-ENOMEM); /* no memory */
-  init_timer(&cs->timer);
-  cs->info[0] = '\0';
-  cs->timer.function = deflect_timer_expire;
-  cs->timer.data = (ulong) cs; /* pointer to own structure */
-  cs->ics.driver = drvid;
-  cs->ics.command = ISDN_CMD_PROT_IO; /* protocol specific io */
-  cs->ics.arg = DSS1_CMD_INVOKE; /* invoke supplementary service */
-  cs->ics.parm.dss1_io.proc = (mode == 1) ? 7: (mode == 2) ? 11:8; /* operation */ 
-  cs->ics.parm.dss1_io.timeout = 4000; /* from ETS 300 207-1 */
-  cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */
-  cs->ics.parm.dss1_io.data = tmp; /* start of buffer */
-  
-  spin_lock_irqsave(&divert_lock, flags);
-  cs->ics.parm.dss1_io.ll_id = next_id++; /* id for callback */
-  spin_unlock_irqrestore(&divert_lock, flags);
-  *procid = cs->ics.parm.dss1_io.ll_id;  
-
-  sprintf(cs->info,"%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
-	  (!mode ) ? DIVERT_DEACTIVATE : (mode == 1) ? DIVERT_ACTIVATE : DIVERT_REPORT,
-          cs->ics.parm.dss1_io.ll_id,
-          (mode != 2) ? "" : "0 ",
-          divert_if.drv_to_name(cs->ics.driver),
-          msn,
-          service & 0xFF,
-          proc,
-          (mode != 1) ? "" : " 0 ",
-          (mode != 1) ? "" : fwd_nr);
- 
-  retval = divert_if.ll_cmd(&cs->ics); /* execute command */
-
-  if (!retval)
-   { cs->prev = NULL;
-     spin_lock_irqsave(&divert_lock, flags);
-     cs->next = divert_head;
-     divert_head = cs; 
-     spin_unlock_irqrestore(&divert_lock, flags);
-   }
-  else
-   kfree(cs);
-  return(retval); 
+	int retval, msnlen;
+	int fwd_len;
+	char *p, *ielenp, tmp[60];
+	struct call_struc *cs;
+
+	if (strchr(msn, '.')) return (-EINVAL); /* subaddress not allowed in msn */
+	if ((proc & 0x7F) > 2) return (-EINVAL);
+	proc &= 3;
+	p = tmp;
+	*p++ = 0x30; /* enumeration */
+	ielenp = p++; /* remember total length position */
+	*p++ = 0xa; /* proc tag */
+	*p++ = 1;   /* length */
+	*p++ = proc & 0x7F; /* procedure to de/activate/interrogate */
+	*p++ = 0xa; /* service tag */
+	*p++ = 1;   /* length */
+	*p++ = service; /* service to handle */
+
+	if (mode == 1)
+	{ if (!*fwd_nr) return (-EINVAL); /* destination missing */
+		if (strchr(fwd_nr, '.')) return (-EINVAL); /* subaddress not allowed */
+		fwd_len = strlen(fwd_nr);
+		*p++ = 0x30; /* number enumeration */
+		*p++ = fwd_len + 2; /* complete forward to len */
+		*p++ = 0x80; /* fwd to nr */
+		*p++ = fwd_len; /* length of number */
+		strcpy(p, fwd_nr); /* copy number */
+		p += fwd_len; /* pointer beyond fwd */
+	} /* activate */
+
+	msnlen = strlen(msn);
+	*p++ = 0x80; /* msn number */
+	if (msnlen > 1)
+	{ *p++ = msnlen; /* length */
+		strcpy(p, msn);
+		p += msnlen;
+	}
+	else *p++ = 0;
+
+	*ielenp = p - ielenp - 1; /* set total IE length */
+
+	/* allocate mem for information struct */
+	if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
+		return (-ENOMEM); /* no memory */
+	init_timer(&cs->timer);
+	cs->info[0] = '\0';
+	cs->timer.function = deflect_timer_expire;
+	cs->timer.data = (ulong) cs; /* pointer to own structure */
+	cs->ics.driver = drvid;
+	cs->ics.command = ISDN_CMD_PROT_IO; /* protocol specific io */
+	cs->ics.arg = DSS1_CMD_INVOKE; /* invoke supplementary service */
+	cs->ics.parm.dss1_io.proc = (mode == 1) ? 7 : (mode == 2) ? 11 : 8; /* operation */
+	cs->ics.parm.dss1_io.timeout = 4000; /* from ETS 300 207-1 */
+	cs->ics.parm.dss1_io.datalen = p - tmp; /* total len */
+	cs->ics.parm.dss1_io.data = tmp; /* start of buffer */
+
+	spin_lock_irqsave(&divert_lock, flags);
+	cs->ics.parm.dss1_io.ll_id = next_id++; /* id for callback */
+	spin_unlock_irqrestore(&divert_lock, flags);
+	*procid = cs->ics.parm.dss1_io.ll_id;
+
+	sprintf(cs->info, "%d 0x%lx %s%s 0 %s %02x %d%s%s\n",
+		(!mode) ? DIVERT_DEACTIVATE : (mode == 1) ? DIVERT_ACTIVATE : DIVERT_REPORT,
+		cs->ics.parm.dss1_io.ll_id,
+		(mode != 2) ? "" : "0 ",
+		divert_if.drv_to_name(cs->ics.driver),
+		msn,
+		service & 0xFF,
+		proc,
+		(mode != 1) ? "" : " 0 ",
+		(mode != 1) ? "" : fwd_nr);
+
+	retval = divert_if.ll_cmd(&cs->ics); /* execute command */
+
+	if (!retval)
+	{ cs->prev = NULL;
+		spin_lock_irqsave(&divert_lock, flags);
+		cs->next = divert_head;
+		divert_head = cs;
+		spin_unlock_irqrestore(&divert_lock, flags);
+	}
+	else
+		kfree(cs);
+	return (retval);
 } /* cf_command */
 
 
@@ -204,165 +204,165 @@ int cf_command(int drvid, int mode,
 /****************************************/
 int deflect_extern_action(u_char cmd, ulong callid, char *to_nr)
 { struct call_struc *cs;
-  isdn_ctrl ic;
-  unsigned long flags;
-  int i;
-
-  if ((cmd & 0x7F) > 2) return(-EINVAL); /* invalid command */
-  cs = divert_head; /* start of parameter list */
-  while (cs)
-   { if (cs->divert_id == callid) break; /* found */
-     cs = cs->next;  
-   } /* search entry */
-  if (!cs) return(-EINVAL); /* invalid callid */
-
-  ic.driver = cs->ics.driver;
-  ic.arg = cs->ics.arg;
-  i = -EINVAL;
-  if (cs->akt_state == DEFLECT_AUTODEL) return(i); /* no valid call */
-  switch (cmd & 0x7F)
-   { case 0: /* hangup */
-       del_timer(&cs->timer); 
-       ic.command = ISDN_CMD_HANGUP;
-       i = divert_if.ll_cmd(&ic);
-       spin_lock_irqsave(&divert_lock, flags);
-       cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
-       cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
-       add_timer(&cs->timer);
-       spin_unlock_irqrestore(&divert_lock, flags);
-     break;      
-
-     case 1: /* alert */
-       if (cs->akt_state == DEFLECT_ALERT) return(0);
-       cmd &= 0x7F; /* never wait */
-       del_timer(&cs->timer); 
-       ic.command = ISDN_CMD_ALERT;
-       if ((i = divert_if.ll_cmd(&ic)))
-	{
-          spin_lock_irqsave(&divert_lock, flags);
-          cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
-          cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
-          add_timer(&cs->timer);
-          spin_unlock_irqrestore(&divert_lock, flags);
-        }
-       else
-          cs->akt_state = DEFLECT_ALERT; 
-     break;      
-
-     case 2: /* redir */
-       del_timer(&cs->timer); 
-       strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone));
-       strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
-       ic.command = ISDN_CMD_REDIR;
-       if ((i = divert_if.ll_cmd(&ic)))
-	{
-          spin_lock_irqsave(&divert_lock, flags);
-          cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
-          cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
-          add_timer(&cs->timer);
-          spin_unlock_irqrestore(&divert_lock, flags);
-        }
-       else
-          cs->akt_state = DEFLECT_ALERT; 
-     break;      
-
-   } /* switch */
-  return(i);
+	isdn_ctrl ic;
+	unsigned long flags;
+	int i;
+
+	if ((cmd & 0x7F) > 2) return (-EINVAL); /* invalid command */
+	cs = divert_head; /* start of parameter list */
+	while (cs)
+	{ if (cs->divert_id == callid) break; /* found */
+		cs = cs->next;
+	} /* search entry */
+	if (!cs) return (-EINVAL); /* invalid callid */
+
+	ic.driver = cs->ics.driver;
+	ic.arg = cs->ics.arg;
+	i = -EINVAL;
+	if (cs->akt_state == DEFLECT_AUTODEL) return (i); /* no valid call */
+	switch (cmd & 0x7F)
+	{ case 0: /* hangup */
+			del_timer(&cs->timer);
+			ic.command = ISDN_CMD_HANGUP;
+			i = divert_if.ll_cmd(&ic);
+			spin_lock_irqsave(&divert_lock, flags);
+			cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
+			cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
+			add_timer(&cs->timer);
+			spin_unlock_irqrestore(&divert_lock, flags);
+			break;
+
+	case 1: /* alert */
+		if (cs->akt_state == DEFLECT_ALERT) return (0);
+		cmd &= 0x7F; /* never wait */
+		del_timer(&cs->timer);
+		ic.command = ISDN_CMD_ALERT;
+		if ((i = divert_if.ll_cmd(&ic)))
+		{
+			spin_lock_irqsave(&divert_lock, flags);
+			cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
+			cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
+			add_timer(&cs->timer);
+			spin_unlock_irqrestore(&divert_lock, flags);
+		}
+		else
+			cs->akt_state = DEFLECT_ALERT;
+		break;
+
+	case 2: /* redir */
+		del_timer(&cs->timer);
+		strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone));
+		strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual");
+		ic.command = ISDN_CMD_REDIR;
+		if ((i = divert_if.ll_cmd(&ic)))
+		{
+			spin_lock_irqsave(&divert_lock, flags);
+			cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
+			cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
+			add_timer(&cs->timer);
+			spin_unlock_irqrestore(&divert_lock, flags);
+		}
+		else
+			cs->akt_state = DEFLECT_ALERT;
+		break;
+
+	} /* switch */
+	return (i);
 } /* deflect_extern_action */
 
 /********************************/
 /* insert a new rule before idx */
 /********************************/
 int insertrule(int idx, divert_rule *newrule)
-{ struct deflect_struc *ds,*ds1=NULL;
-  unsigned long flags;
-
-  if (!(ds = kmalloc(sizeof(struct deflect_struc),
-                                              GFP_KERNEL))) 
-    return(-ENOMEM); /* no memory */
-
-  ds->rule = *newrule; /* set rule */
-
-  spin_lock_irqsave(&divert_lock, flags);
-
-  if (idx >= 0)
-   { ds1 = table_head;
-     while ((ds1) && (idx > 0))
-      { idx--;
-        ds1 = ds1->next;
-      } 
-     if (!ds1) idx = -1; 
-   }
-
-  if (idx < 0)
-   { ds->prev = table_tail; /* previous entry */
-     ds->next = NULL; /* end of chain */
-     if (ds->prev) 
-       ds->prev->next = ds; /* last forward */
-      else
-        table_head = ds; /* is first entry */
-     table_tail = ds; /* end of queue */
-   }
-  else
-    { ds->next = ds1; /* next entry */
-      ds->prev = ds1->prev; /* prev entry */
-      ds1->prev = ds; /* backward chain old element */
-      if (!ds->prev)
-        table_head = ds; /* first element */
-   }
-
-  spin_unlock_irqrestore(&divert_lock, flags);
-  return(0);
+{ struct deflect_struc *ds, *ds1 = NULL;
+	unsigned long flags;
+
+	if (!(ds = kmalloc(sizeof(struct deflect_struc),
+			   GFP_KERNEL)))
+		return (-ENOMEM); /* no memory */
+
+	ds->rule = *newrule; /* set rule */
+
+	spin_lock_irqsave(&divert_lock, flags);
+
+	if (idx >= 0)
+	{ ds1 = table_head;
+		while ((ds1) && (idx > 0))
+		{ idx--;
+			ds1 = ds1->next;
+		}
+		if (!ds1) idx = -1;
+	}
+
+	if (idx < 0)
+	{ ds->prev = table_tail; /* previous entry */
+		ds->next = NULL; /* end of chain */
+		if (ds->prev)
+			ds->prev->next = ds; /* last forward */
+		else
+			table_head = ds; /* is first entry */
+		table_tail = ds; /* end of queue */
+	}
+	else
+	{ ds->next = ds1; /* next entry */
+		ds->prev = ds1->prev; /* prev entry */
+		ds1->prev = ds; /* backward chain old element */
+		if (!ds->prev)
+			table_head = ds; /* first element */
+	}
+
+	spin_unlock_irqrestore(&divert_lock, flags);
+	return (0);
 } /* insertrule */
 
 /***********************************/
 /* delete the rule at position idx */
 /***********************************/
 int deleterule(int idx)
-{ struct deflect_struc *ds,*ds1;
-  unsigned long flags;
-  
-  if (idx < 0) 
-   { spin_lock_irqsave(&divert_lock, flags);
-     ds = table_head;
-     table_head = NULL;
-     table_tail = NULL;
-     spin_unlock_irqrestore(&divert_lock, flags);
-     while (ds)
-      { ds1 = ds; 
-        ds = ds->next;
-        kfree(ds1);
-      } 
-     return(0); 
-   }
-
-  spin_lock_irqsave(&divert_lock, flags);
-  ds = table_head;
-
-  while ((ds) && (idx > 0))
-   { idx--; 
-     ds = ds->next;  
-   }
-
-  if (!ds) 
-   {
-     spin_unlock_irqrestore(&divert_lock, flags);
-     return(-EINVAL);
-   }  
-
-  if (ds->next) 
-    ds->next->prev = ds->prev; /* backward chain */
-   else
-     table_tail = ds->prev; /* end of chain */
-
-  if (ds->prev)
-    ds->prev->next = ds->next; /* forward chain */
-   else
-     table_head = ds->next; /* start of chain */      
-  
-  spin_unlock_irqrestore(&divert_lock, flags);
-  kfree(ds);
-  return(0);
+{ struct deflect_struc *ds, *ds1;
+	unsigned long flags;
+
+	if (idx < 0)
+	{ spin_lock_irqsave(&divert_lock, flags);
+		ds = table_head;
+		table_head = NULL;
+		table_tail = NULL;
+		spin_unlock_irqrestore(&divert_lock, flags);
+		while (ds)
+		{ ds1 = ds;
+			ds = ds->next;
+			kfree(ds1);
+		}
+		return (0);
+	}
+
+	spin_lock_irqsave(&divert_lock, flags);
+	ds = table_head;
+
+	while ((ds) && (idx > 0))
+	{ idx--;
+		ds = ds->next;
+	}
+
+	if (!ds)
+	{
+		spin_unlock_irqrestore(&divert_lock, flags);
+		return (-EINVAL);
+	}
+
+	if (ds->next)
+		ds->next->prev = ds->prev; /* backward chain */
+	else
+		table_tail = ds->prev; /* end of chain */
+
+	if (ds->prev)
+		ds->prev->next = ds->next; /* forward chain */
+	else
+		table_head = ds->next; /* start of chain */
+
+	spin_unlock_irqrestore(&divert_lock, flags);
+	kfree(ds);
+	return (0);
 } /* deleterule */
 
 /*******************************************/
@@ -370,16 +370,16 @@ int deleterule(int idx)
 /*******************************************/
 divert_rule *getruleptr(int idx)
 { struct deflect_struc *ds = table_head;
-  
-  if (idx < 0) return(NULL);
-  while ((ds) && (idx >= 0))
-   { if (!(idx--)) 
-      { return(&ds->rule);
-        break;
-      }
-     ds = ds->next;  
-   }
-  return(NULL);
+
+	if (idx < 0) return (NULL);
+	while ((ds) && (idx >= 0))
+	{ if (!(idx--))
+		{ return (&ds->rule);
+			break;
+		}
+		ds = ds->next;
+	}
+	return (NULL);
 } /* getruleptr */
 
 /*************************************************/
@@ -387,168 +387,168 @@ divert_rule *getruleptr(int idx)
 /*************************************************/
 static int isdn_divert_icall(isdn_ctrl *ic)
 { int retval = 0;
-  unsigned long flags;
-  struct call_struc *cs = NULL; 
-  struct deflect_struc *dv;
-  char *p,*p1;
-  u_char accept;
-
-  /* first check the internal deflection table */
-  for (dv = table_head; dv ; dv = dv->next )
-   { /* scan table */
-     if (((dv->rule.callopt == 1) && (ic->command == ISDN_STAT_ICALLW)) ||
-         ((dv->rule.callopt == 2) && (ic->command == ISDN_STAT_ICALL)))
-       continue; /* call option check */  
-     if (!(dv->rule.drvid & (1L << ic->driver))) 
-       continue; /* driver not matching */ 
-     if ((dv->rule.si1) && (dv->rule.si1 != ic->parm.setup.si1)) 
-       continue; /* si1 not matching */
-     if ((dv->rule.si2) && (dv->rule.si2 != ic->parm.setup.si2)) 
-       continue; /* si2 not matching */
-
-     p = dv->rule.my_msn;
-     p1 = ic->parm.setup.eazmsn;
-     accept = 0;
-     while (*p)
-      { /* complete compare */
-        if (*p == '-')
-	  { accept = 1; /* call accepted */
-            break;
-          }
-        if (*p++ != *p1++) 
-          break; /* not accepted */
-        if ((!*p) && (!*p1))
-          accept = 1;
-      } /* complete compare */
-     if (!accept) continue; /* not accepted */
- 
-     if ((strcmp(dv->rule.caller,"0")) || (ic->parm.setup.phone[0]))
-      { p = dv->rule.caller;
-        p1 = ic->parm.setup.phone;
-        accept = 0;
-        while (*p)
-	 { /* complete compare */
-           if (*p == '-')
-	    { accept = 1; /* call accepted */
-              break;
-            }
-           if (*p++ != *p1++) 
-             break; /* not accepted */
-           if ((!*p) && (!*p1))
-             accept = 1;
-         } /* complete compare */
-        if (!accept) continue; /* not accepted */
-      }  
-
-     switch (dv->rule.action)
-       { case DEFLECT_IGNORE:
-           return(0);
-           break;
-
-         case DEFLECT_ALERT:
-         case DEFLECT_PROCEED:
-         case DEFLECT_REPORT:
-         case DEFLECT_REJECT:
-           if (dv->rule.action == DEFLECT_PROCEED)
-	    if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime))) 
-              return(0); /* no external deflection needed */  
-           if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
-             return(0); /* no memory */
-           init_timer(&cs->timer);
-           cs->info[0] = '\0';
-           cs->timer.function = deflect_timer_expire;
-           cs->timer.data = (ulong) cs; /* pointer to own structure */
-           
-           cs->ics = *ic; /* copy incoming data */
-           if (!cs->ics.parm.setup.phone[0]) strcpy(cs->ics.parm.setup.phone,"0");
-           if (!cs->ics.parm.setup.eazmsn[0]) strcpy(cs->ics.parm.setup.eazmsn,"0");
-	   cs->ics.parm.setup.screen = dv->rule.screen;  
-           if (dv->rule.waittime) 
-             cs->timer.expires = jiffies + (HZ * dv->rule.waittime);
-           else
-            if (dv->rule.action == DEFLECT_PROCEED)
-              cs->timer.expires = jiffies + (HZ * extern_wait_max); 
-            else  
-              cs->timer.expires = 0;
-           cs->akt_state = dv->rule.action;                
-           spin_lock_irqsave(&divert_lock, flags);
-           cs->divert_id = next_id++; /* new sequence number */
-           spin_unlock_irqrestore(&divert_lock, flags);
-           cs->prev = NULL;
-           if (cs->akt_state == DEFLECT_ALERT)
-             { strcpy(cs->deflect_dest,dv->rule.to_nr);
-               if (!cs->timer.expires)
-		 { strcpy(ic->parm.setup.eazmsn,"Testtext direct");
-                   ic->parm.setup.screen = dv->rule.screen;
-                   strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone));
-                   cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
-                   cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
-                   retval = 5; 
-                 }
-               else
-                 retval = 1; /* alerting */                 
-             }
-           else
-             { cs->deflect_dest[0] = '\0';
-	       retval = 4; /* only proceed */
-             }  
-           sprintf(cs->info,"%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
-                   cs->akt_state,
-                   cs->divert_id,
-                   divert_if.drv_to_name(cs->ics.driver),
-                   (ic->command == ISDN_STAT_ICALLW) ? "1":"0", 
-                   cs->ics.parm.setup.phone, 
-                   cs->ics.parm.setup.eazmsn,
-                   cs->ics.parm.setup.si1,
-                   cs->ics.parm.setup.si2,
-                   cs->ics.parm.setup.screen,
-                   dv->rule.waittime,
-                   cs->deflect_dest);
-           if ((dv->rule.action == DEFLECT_REPORT) ||
-               (dv->rule.action == DEFLECT_REJECT))
-	    { put_info_buffer(cs->info);
-	      kfree(cs); /* remove */
-              return((dv->rule.action == DEFLECT_REPORT) ? 0:2); /* nothing to do */ 
-            }              
-           break;
-  
-         default:
-           return(0); /* ignore call */
-           break;
-       } /* switch action */    
-     break; 
-   } /* scan_table */
-
-  if (cs) 
-   { cs->prev = NULL;
-     spin_lock_irqsave(&divert_lock, flags);
-     cs->next = divert_head;
-     divert_head = cs; 
-     if (cs->timer.expires) add_timer(&cs->timer);
-     spin_unlock_irqrestore(&divert_lock, flags);
-
-     put_info_buffer(cs->info); 
-     return(retval);
-   }
-  else
-     return(0);
+	unsigned long flags;
+	struct call_struc *cs = NULL;
+	struct deflect_struc *dv;
+	char *p, *p1;
+	u_char accept;
+
+	/* first check the internal deflection table */
+	for (dv = table_head; dv; dv = dv->next)
+	{ /* scan table */
+		if (((dv->rule.callopt == 1) && (ic->command == ISDN_STAT_ICALLW)) ||
+		    ((dv->rule.callopt == 2) && (ic->command == ISDN_STAT_ICALL)))
+			continue; /* call option check */
+		if (!(dv->rule.drvid & (1L << ic->driver)))
+			continue; /* driver not matching */
+		if ((dv->rule.si1) && (dv->rule.si1 != ic->parm.setup.si1))
+			continue; /* si1 not matching */
+		if ((dv->rule.si2) && (dv->rule.si2 != ic->parm.setup.si2))
+			continue; /* si2 not matching */
+
+		p = dv->rule.my_msn;
+		p1 = ic->parm.setup.eazmsn;
+		accept = 0;
+		while (*p)
+		{ /* complete compare */
+			if (*p == '-')
+			{ accept = 1; /* call accepted */
+				break;
+			}
+			if (*p++ != *p1++)
+				break; /* not accepted */
+			if ((!*p) && (!*p1))
+				accept = 1;
+		} /* complete compare */
+		if (!accept) continue; /* not accepted */
+
+		if ((strcmp(dv->rule.caller, "0")) || (ic->parm.setup.phone[0]))
+		{ p = dv->rule.caller;
+			p1 = ic->parm.setup.phone;
+			accept = 0;
+			while (*p)
+			{ /* complete compare */
+				if (*p == '-')
+				{ accept = 1; /* call accepted */
+					break;
+				}
+				if (*p++ != *p1++)
+					break; /* not accepted */
+				if ((!*p) && (!*p1))
+					accept = 1;
+			} /* complete compare */
+			if (!accept) continue; /* not accepted */
+		}
+
+		switch (dv->rule.action)
+		{ case DEFLECT_IGNORE:
+				return (0);
+				break;
+
+		case DEFLECT_ALERT:
+		case DEFLECT_PROCEED:
+		case DEFLECT_REPORT:
+		case DEFLECT_REJECT:
+			if (dv->rule.action == DEFLECT_PROCEED)
+				if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime)))
+					return (0); /* no external deflection needed */
+			if (!(cs = kmalloc(sizeof(struct call_struc), GFP_ATOMIC)))
+				return (0); /* no memory */
+			init_timer(&cs->timer);
+			cs->info[0] = '\0';
+			cs->timer.function = deflect_timer_expire;
+			cs->timer.data = (ulong) cs; /* pointer to own structure */
+
+			cs->ics = *ic; /* copy incoming data */
+			if (!cs->ics.parm.setup.phone[0]) strcpy(cs->ics.parm.setup.phone, "0");
+			if (!cs->ics.parm.setup.eazmsn[0]) strcpy(cs->ics.parm.setup.eazmsn, "0");
+			cs->ics.parm.setup.screen = dv->rule.screen;
+			if (dv->rule.waittime)
+				cs->timer.expires = jiffies + (HZ * dv->rule.waittime);
+			else
+				if (dv->rule.action == DEFLECT_PROCEED)
+					cs->timer.expires = jiffies + (HZ * extern_wait_max);
+				else
+					cs->timer.expires = 0;
+			cs->akt_state = dv->rule.action;
+			spin_lock_irqsave(&divert_lock, flags);
+			cs->divert_id = next_id++; /* new sequence number */
+			spin_unlock_irqrestore(&divert_lock, flags);
+			cs->prev = NULL;
+			if (cs->akt_state == DEFLECT_ALERT)
+			{ strcpy(cs->deflect_dest, dv->rule.to_nr);
+				if (!cs->timer.expires)
+				{ strcpy(ic->parm.setup.eazmsn, "Testtext direct");
+					ic->parm.setup.screen = dv->rule.screen;
+					strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone));
+					cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */
+					cs->timer.expires = jiffies + (HZ * AUTODEL_TIME);
+					retval = 5;
+				}
+				else
+					retval = 1; /* alerting */
+			}
+			else
+			{ cs->deflect_dest[0] = '\0';
+				retval = 4; /* only proceed */
+			}
+			sprintf(cs->info, "%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
+				cs->akt_state,
+				cs->divert_id,
+				divert_if.drv_to_name(cs->ics.driver),
+				(ic->command == ISDN_STAT_ICALLW) ? "1" : "0",
+				cs->ics.parm.setup.phone,
+				cs->ics.parm.setup.eazmsn,
+				cs->ics.parm.setup.si1,
+				cs->ics.parm.setup.si2,
+				cs->ics.parm.setup.screen,
+				dv->rule.waittime,
+				cs->deflect_dest);
+			if ((dv->rule.action == DEFLECT_REPORT) ||
+			    (dv->rule.action == DEFLECT_REJECT))
+			{ put_info_buffer(cs->info);
+				kfree(cs); /* remove */
+				return ((dv->rule.action == DEFLECT_REPORT) ? 0 : 2); /* nothing to do */
+			}
+			break;
+
+		default:
+			return (0); /* ignore call */
+			break;
+		} /* switch action */
+		break;
+	} /* scan_table */
+
+	if (cs)
+	{ cs->prev = NULL;
+		spin_lock_irqsave(&divert_lock, flags);
+		cs->next = divert_head;
+		divert_head = cs;
+		if (cs->timer.expires) add_timer(&cs->timer);
+		spin_unlock_irqrestore(&divert_lock, flags);
+
+		put_info_buffer(cs->info);
+		return (retval);
+	}
+	else
+		return (0);
 } /* isdn_divert_icall */
 
 
 void deleteprocs(void)
-{ struct call_struc *cs, *cs1; 
-  unsigned long flags;
-
-  spin_lock_irqsave(&divert_lock, flags);
-  cs = divert_head;
-  divert_head = NULL;
-  while (cs)
-   { del_timer(&cs->timer);
-     cs1 = cs;
-     cs = cs->next;
-     kfree(cs1);
-   } 
-  spin_unlock_irqrestore(&divert_lock, flags);
+{ struct call_struc *cs, *cs1;
+	unsigned long flags;
+
+	spin_lock_irqsave(&divert_lock, flags);
+	cs = divert_head;
+	divert_head = NULL;
+	while (cs)
+	{ del_timer(&cs->timer);
+		cs1 = cs;
+		cs = cs->next;
+		kfree(cs1);
+	}
+	spin_unlock_irqrestore(&divert_lock, flags);
 } /* deleteprocs */
 
 /****************************************************/
@@ -556,42 +556,42 @@ void deleteprocs(void)
 /****************************************************/
 static int put_address(char *st, u_char *p, int len)
 { u_char retval = 0;
-  u_char adr_typ = 0; /* network standard */
-
-  if (len < 2) return(retval);
-  if (*p == 0xA1)
-   { retval = *(++p) + 2; /* total length */
-     if (retval > len) return(0); /* too short */
-     len = retval - 2; /* remaining length */
-     if (len < 3) return(0);
-     if ((*(++p) != 0x0A) || (*(++p) != 1)) return(0);
-     adr_typ = *(++p);
-     len -= 3;
-     p++;
-     if (len < 2) return(0);
-     if (*p++ != 0x12) return(0);
-     if (*p > len) return(0); /* check number length */
-     len = *p++;
-   }   
-  else
-   if (*p == 0x80)
-    { retval = *(++p) + 2; /* total length */
-      if (retval > len) return(0);
-      len = retval - 2;
-      p++;
-    }
-   else  
-    return(0); /* invalid address information */
-
-  sprintf(st,"%d ",adr_typ);
-  st += strlen(st);
-  if (!len) 
-    *st++ = '-';
-  else
-   while (len--)
-     *st++ = *p++;
-  *st = '\0';
-  return(retval);
+	u_char adr_typ = 0; /* network standard */
+
+	if (len < 2) return (retval);
+	if (*p == 0xA1)
+	{ retval = *(++p) + 2; /* total length */
+		if (retval > len) return (0); /* too short */
+		len = retval - 2; /* remaining length */
+		if (len < 3) return (0);
+		if ((*(++p) != 0x0A) || (*(++p) != 1)) return (0);
+		adr_typ = *(++p);
+		len -= 3;
+		p++;
+		if (len < 2) return (0);
+		if (*p++ != 0x12) return (0);
+		if (*p > len) return (0); /* check number length */
+		len = *p++;
+	}
+	else
+		if (*p == 0x80)
+		{ retval = *(++p) + 2; /* total length */
+			if (retval > len) return (0);
+			len = retval - 2;
+			p++;
+		}
+		else
+			return (0); /* invalid address information */
+
+	sprintf(st, "%d ", adr_typ);
+	st += strlen(st);
+	if (!len)
+		*st++ = '-';
+	else
+		while (len--)
+			*st++ = *p++;
+	*st = '\0';
+	return (retval);
 } /* put_address */
 
 /*************************************/
@@ -599,93 +599,93 @@ static int put_address(char *st, u_char *p, int len)
 /*************************************/
 static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
 { char *src = ic->parm.dss1_io.data;
-  int restlen = ic->parm.dss1_io.datalen;
-  int cnt = 1;
-  u_char n,n1;
-  char st[90], *p, *stp;
-
-  if (restlen < 2) return(-100); /* frame too short */
-  if (*src++ != 0x30) return(-101);
-  if ((n = *src++) > 0x81) return(-102); /* invalid length field */
-  restlen -= 2; /* remaining bytes */
-  if (n == 0x80)
-   { if (restlen < 2) return(-103);
-     if ((*(src+restlen-1)) || (*(src+restlen-2))) return(-104);
-     restlen -= 2;
-   }
-  else
-   if ( n == 0x81)
-    { n = *src++;
-      restlen--;
-      if (n > restlen) return(-105);
-      restlen = n;
-    }
-   else
-    if (n > restlen) return(-106);
-     else 
-      restlen = n; /* standard format */   
-  if (restlen < 3) return(-107); /* no procedure */
-  if ((*src++ != 2) || (*src++ != 1) || (*src++ != 0x0B)) return(-108);
-  restlen -= 3; 
-  if (restlen < 2) return(-109); /* list missing */
-  if (*src == 0x31)
-   { src++; 
-     if ((n = *src++) > 0x81) return(-110); /* invalid length field */
-     restlen -= 2; /* remaining bytes */
-     if (n == 0x80)
-      { if (restlen < 2) return(-111);
-        if ((*(src+restlen-1)) || (*(src+restlen-2))) return(-112);
-        restlen -= 2;
-      }
-     else
-      if ( n == 0x81)
-       { n = *src++;
-         restlen--;
-         if (n > restlen) return(-113);
-         restlen = n;
-       }
-      else
-       if (n > restlen) return(-114);
-        else 
-         restlen = n; /* standard format */   
-   } /* result list header */ 
-
-  while (restlen >= 2)
-   { stp = st;
-     sprintf(stp,"%d 0x%lx %d %s ",DIVERT_REPORT, ic->parm.dss1_io.ll_id,
-                 cnt++,divert_if.drv_to_name(ic->driver));
-     stp += strlen(stp);
-     if (*src++ != 0x30) return(-115); /* invalid enum */
-     n = *src++;
-     restlen -= 2;
-     if (n > restlen) return(-116); /* enum length wrong */
-     restlen -= n;
-     p = src; /* one entry */
-     src += n;
-     if (!(n1 = put_address(stp,p,n & 0xFF))) continue;
-     stp += strlen(stp);
-     p += n1;
-     n -= n1;
-     if (n < 6) continue; /* no service and proc */
-     if ((*p++ != 0x0A) || (*p++ != 1)) continue;
-     sprintf(stp," 0x%02x ",(*p++) & 0xFF);
-     stp += strlen(stp);
-     if ((*p++ != 0x0A) || (*p++ != 1)) continue;
-     sprintf(stp,"%d ",(*p++) & 0xFF);
-     stp += strlen(stp);
-     n -= 6;
-     if (n > 2)
-      { if (*p++ != 0x30) continue;
-        if (*p > (n-2)) continue;
-        n = *p++;
-        if (!(n1 = put_address(stp,p,n & 0xFF))) continue;
-        stp += strlen(stp);
-      }
-     sprintf(stp,"\n");
-     put_info_buffer(st);
-   } /* while restlen */
-  if (restlen) return(-117);
-  return(0);   
+	int restlen = ic->parm.dss1_io.datalen;
+	int cnt = 1;
+	u_char n, n1;
+	char st[90], *p, *stp;
+
+	if (restlen < 2) return (-100); /* frame too short */
+	if (*src++ != 0x30) return (-101);
+	if ((n = *src++) > 0x81) return (-102); /* invalid length field */
+	restlen -= 2; /* remaining bytes */
+	if (n == 0x80)
+	{ if (restlen < 2) return (-103);
+		if ((*(src + restlen - 1)) || (*(src + restlen - 2))) return (-104);
+		restlen -= 2;
+	}
+	else
+		if (n == 0x81)
+		{ n = *src++;
+			restlen--;
+			if (n > restlen) return (-105);
+			restlen = n;
+		}
+		else
+			if (n > restlen) return (-106);
+			else
+				restlen = n; /* standard format */
+	if (restlen < 3) return (-107); /* no procedure */
+	if ((*src++ != 2) || (*src++ != 1) || (*src++ != 0x0B)) return (-108);
+	restlen -= 3;
+	if (restlen < 2) return (-109); /* list missing */
+	if (*src == 0x31)
+	{ src++;
+		if ((n = *src++) > 0x81) return (-110); /* invalid length field */
+		restlen -= 2; /* remaining bytes */
+		if (n == 0x80)
+		{ if (restlen < 2) return (-111);
+			if ((*(src + restlen - 1)) || (*(src + restlen - 2))) return (-112);
+			restlen -= 2;
+		}
+		else
+			if (n == 0x81)
+			{ n = *src++;
+				restlen--;
+				if (n > restlen) return (-113);
+				restlen = n;
+			}
+			else
+				if (n > restlen) return (-114);
+				else
+					restlen = n; /* standard format */
+	} /* result list header */
+
+	while (restlen >= 2)
+	{ stp = st;
+		sprintf(stp, "%d 0x%lx %d %s ", DIVERT_REPORT, ic->parm.dss1_io.ll_id,
+			cnt++, divert_if.drv_to_name(ic->driver));
+		stp += strlen(stp);
+		if (*src++ != 0x30) return (-115); /* invalid enum */
+		n = *src++;
+		restlen -= 2;
+		if (n > restlen) return (-116); /* enum length wrong */
+		restlen -= n;
+		p = src; /* one entry */
+		src += n;
+		if (!(n1 = put_address(stp, p, n & 0xFF))) continue;
+		stp += strlen(stp);
+		p += n1;
+		n -= n1;
+		if (n < 6) continue; /* no service and proc */
+		if ((*p++ != 0x0A) || (*p++ != 1)) continue;
+		sprintf(stp, " 0x%02x ", (*p++) & 0xFF);
+		stp += strlen(stp);
+		if ((*p++ != 0x0A) || (*p++ != 1)) continue;
+		sprintf(stp, "%d ", (*p++) & 0xFF);
+		stp += strlen(stp);
+		n -= 6;
+		if (n > 2)
+		{ if (*p++ != 0x30) continue;
+			if (*p > (n - 2)) continue;
+			n = *p++;
+			if (!(n1 = put_address(stp, p, n & 0xFF))) continue;
+			stp += strlen(stp);
+		}
+		sprintf(stp, "\n");
+		put_info_buffer(st);
+	} /* while restlen */
+	if (restlen) return (-117);
+	return (0);
 } /* interrogate_success */
 
 /*********************************************/
@@ -693,90 +693,90 @@ static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs)
 /*********************************************/
 static int prot_stat_callback(isdn_ctrl *ic)
 { struct call_struc *cs, *cs1;
-  int i;
-  unsigned long flags;
-
-  cs = divert_head; /* start of list */
-  cs1 = NULL;
-  while (cs)
-   { if (ic->driver == cs->ics.driver) 
-      { switch (cs->ics.arg)
-	 { case DSS1_CMD_INVOKE:
-             if ((cs->ics.parm.dss1_io.ll_id == ic->parm.dss1_io.ll_id) &&
-                 (cs->ics.parm.dss1_io.hl_id == ic->parm.dss1_io.hl_id))
-	      { switch (ic->arg)
-		{  case DSS1_STAT_INVOKE_ERR:
-                     sprintf(cs->info,"128 0x%lx 0x%x\n", 
-                             ic->parm.dss1_io.ll_id,
-                             ic->parm.dss1_io.timeout);
-                     put_info_buffer(cs->info);
-                   break;
-                   
-                   case DSS1_STAT_INVOKE_RES:
-                     switch (cs->ics.parm.dss1_io.proc)
-		      {  case  7:
-                         case  8:
-                            put_info_buffer(cs->info); 
-                           break;
-                       
-                         case  11:
-                           i = interrogate_success(ic,cs);
-                           if (i)
-                             sprintf(cs->info,"%d 0x%lx %d\n",DIVERT_REPORT, 
-                                     ic->parm.dss1_io.ll_id,i);
-                           put_info_buffer(cs->info); 
-                           break;
-                       
-		         default: 
-                           printk(KERN_WARNING "dss1_divert: unknown proc %d\n",cs->ics.parm.dss1_io.proc);
-                           break;
-                      } 
-
-
-                   break;
- 
-		   default:
-                     printk(KERN_WARNING "dss1_divert unknown invoke answer %lx\n",ic->arg);
-                   break;  
-                 } 
-                cs1 = cs; /* remember structure */
-                cs = NULL; 
-                continue; /* abort search */
-              } /* id found */ 
-           break;
-   
-	   case DSS1_CMD_INVOKE_ABORT:
-             printk(KERN_WARNING "dss1_divert unhandled invoke abort\n"); 
-           break;   
-         
-	   default:
-             printk(KERN_WARNING "dss1_divert unknown cmd 0x%lx\n",cs->ics.arg); 
-           break; 
-         } /* switch ics.arg */ 
-        cs = cs->next; 
-      } /* driver ok */
-   }  
-   
-  if (!cs1) 
-   { printk(KERN_WARNING "dss1_divert unhandled process\n");
-     return(0);
-   }  
-
-  if (cs1->ics.driver == -1)
-   {
-     spin_lock_irqsave(&divert_lock, flags);
-     del_timer(&cs1->timer);
-     if (cs1->prev) 
-       cs1->prev->next = cs1->next; /* forward link */
-     else
-       divert_head = cs1->next;
-     if (cs1->next)
-       cs1->next->prev = cs1->prev; /* back link */           
-     spin_unlock_irqrestore(&divert_lock, flags);
-     kfree(cs1);
-   } 
-
-  return(0);
+	int i;
+	unsigned long flags;
+
+	cs = divert_head; /* start of list */
+	cs1 = NULL;
+	while (cs)
+	{ if (ic->driver == cs->ics.driver)
+		{ switch (cs->ics.arg)
+			{ case DSS1_CMD_INVOKE:
+					if ((cs->ics.parm.dss1_io.ll_id == ic->parm.dss1_io.ll_id) &&
+					    (cs->ics.parm.dss1_io.hl_id == ic->parm.dss1_io.hl_id))
+					{ switch (ic->arg)
+						{  case DSS1_STAT_INVOKE_ERR:
+								sprintf(cs->info, "128 0x%lx 0x%x\n",
+									ic->parm.dss1_io.ll_id,
+									ic->parm.dss1_io.timeout);
+								put_info_buffer(cs->info);
+								break;
+
+						case DSS1_STAT_INVOKE_RES:
+							switch (cs->ics.parm.dss1_io.proc)
+							{  case  7:
+							case  8:
+								put_info_buffer(cs->info);
+								break;
+
+							case  11:
+								i = interrogate_success(ic, cs);
+								if (i)
+									sprintf(cs->info, "%d 0x%lx %d\n", DIVERT_REPORT,
+										ic->parm.dss1_io.ll_id, i);
+								put_info_buffer(cs->info);
+								break;
+
+							default:
+								printk(KERN_WARNING "dss1_divert: unknown proc %d\n", cs->ics.parm.dss1_io.proc);
+								break;
+							}
+
+
+							break;
+
+						default:
+							printk(KERN_WARNING "dss1_divert unknown invoke answer %lx\n", ic->arg);
+							break;
+						}
+						cs1 = cs; /* remember structure */
+						cs = NULL;
+						continue; /* abort search */
+					} /* id found */
+					break;
+
+			case DSS1_CMD_INVOKE_ABORT:
+				printk(KERN_WARNING "dss1_divert unhandled invoke abort\n");
+				break;
+
+			default:
+				printk(KERN_WARNING "dss1_divert unknown cmd 0x%lx\n", cs->ics.arg);
+				break;
+			} /* switch ics.arg */
+			cs = cs->next;
+		} /* driver ok */
+	}
+
+	if (!cs1)
+	{ printk(KERN_WARNING "dss1_divert unhandled process\n");
+		return (0);
+	}
+
+	if (cs1->ics.driver == -1)
+	{
+		spin_lock_irqsave(&divert_lock, flags);
+		del_timer(&cs1->timer);
+		if (cs1->prev)
+			cs1->prev->next = cs1->next; /* forward link */
+		else
+			divert_head = cs1->next;
+		if (cs1->next)
+			cs1->next->prev = cs1->prev; /* back link */
+		spin_unlock_irqrestore(&divert_lock, flags);
+		kfree(cs1);
+	}
+
+	return (0);
 } /* prot_stat_callback */
 
 
@@ -785,79 +785,78 @@ static int prot_stat_callback(isdn_ctrl *ic)
 /***************************/
 static int isdn_divert_stat_callback(isdn_ctrl *ic)
 { struct call_struc *cs, *cs1;
-  unsigned long flags;
-  int retval;
-
-  retval = -1;
-  cs = divert_head; /* start of list */
-     while (cs)
-      { if ((ic->driver == cs->ics.driver) && (ic->arg == cs->ics.arg))
-         { switch (ic->command)
-	    { case ISDN_STAT_DHUP:
-                sprintf(cs->info,"129 0x%lx\n",cs->divert_id);
-                del_timer(&cs->timer);
-                cs->ics.driver = -1;
-                break;
-
-	      case ISDN_STAT_CAUSE:
-                sprintf(cs->info,"130 0x%lx %s\n",cs->divert_id,ic->parm.num);
-                break;
-
-	      case ISDN_STAT_REDIR:
-                sprintf(cs->info,"131 0x%lx\n",cs->divert_id);
-                del_timer(&cs->timer);
-                cs->ics.driver = -1;
-                break; 
-
-	      default:
-                sprintf(cs->info,"999 0x%lx 0x%x\n",cs->divert_id,(int)(ic->command));
-                break; 
-            }
-          put_info_buffer(cs->info);
-          retval = 0; 
-         }
-        cs1 = cs; 
-        cs = cs->next;
-        if (cs1->ics.driver == -1)
-          { 
-            spin_lock_irqsave(&divert_lock, flags);
-            if (cs1->prev) 
-              cs1->prev->next = cs1->next; /* forward link */
-            else
-              divert_head = cs1->next;
-            if (cs1->next)
-              cs1->next->prev = cs1->prev; /* back link */           
-            spin_unlock_irqrestore(&divert_lock, flags);
-            kfree(cs1);
-          } 
-      }  
-  return(retval); /* not found */
-} /* isdn_divert_stat_callback */ 
+	unsigned long flags;
+	int retval;
+
+	retval = -1;
+	cs = divert_head; /* start of list */
+	while (cs)
+	{ if ((ic->driver == cs->ics.driver) && (ic->arg == cs->ics.arg))
+		{ switch (ic->command)
+			{ case ISDN_STAT_DHUP:
+					sprintf(cs->info, "129 0x%lx\n", cs->divert_id);
+					del_timer(&cs->timer);
+					cs->ics.driver = -1;
+					break;
+
+			case ISDN_STAT_CAUSE:
+				sprintf(cs->info, "130 0x%lx %s\n", cs->divert_id, ic->parm.num);
+				break;
+
+			case ISDN_STAT_REDIR:
+				sprintf(cs->info, "131 0x%lx\n", cs->divert_id);
+				del_timer(&cs->timer);
+				cs->ics.driver = -1;
+				break;
+
+			default:
+				sprintf(cs->info, "999 0x%lx 0x%x\n", cs->divert_id, (int)(ic->command));
+				break;
+			}
+			put_info_buffer(cs->info);
+			retval = 0;
+		}
+		cs1 = cs;
+		cs = cs->next;
+		if (cs1->ics.driver == -1)
+		{
+			spin_lock_irqsave(&divert_lock, flags);
+			if (cs1->prev)
+				cs1->prev->next = cs1->next; /* forward link */
+			else
+				divert_head = cs1->next;
+			if (cs1->next)
+				cs1->next->prev = cs1->prev; /* back link */
+			spin_unlock_irqrestore(&divert_lock, flags);
+			kfree(cs1);
+		}
+	}
+	return (retval); /* not found */
+} /* isdn_divert_stat_callback */
 
 
 /********************/
 /* callback from ll */
-/********************/ 
+/********************/
 int ll_callback(isdn_ctrl *ic)
 {
-  switch (ic->command)
-   { case ISDN_STAT_ICALL:
-     case ISDN_STAT_ICALLW:
-       return(isdn_divert_icall(ic));
-     break;
-
-     case ISDN_STAT_PROT:
-       if ((ic->arg & 0xFF) == ISDN_PTYPE_EURO)
-	{ if (ic->arg != DSS1_STAT_INVOKE_BRD)
-            return(prot_stat_callback(ic));
-          else
-            return(0); /* DSS1 invoke broadcast */
-        }
-       else
-         return(-1); /* protocol not euro */    
-
-     default:
-       return(isdn_divert_stat_callback(ic));
-   }
+	switch (ic->command)
+	{ case ISDN_STAT_ICALL:
+	case ISDN_STAT_ICALLW:
+		return (isdn_divert_icall(ic));
+		break;
+
+	case ISDN_STAT_PROT:
+		if ((ic->arg & 0xFF) == ISDN_PTYPE_EURO)
+		{ if (ic->arg != DSS1_STAT_INVOKE_BRD)
+				return (prot_stat_callback(ic));
+			else
+				return (0); /* DSS1 invoke broadcast */
+		}
+		else
+			return (-1); /* protocol not euro */
+
+	default:
+		return (isdn_divert_stat_callback(ic));
+	}
 } /* ll_callback */
-
diff --git a/drivers/isdn/divert/isdn_divert.h b/drivers/isdn/divert/isdn_divert.h
index 19439a6..42f2893 100644
--- a/drivers/isdn/divert/isdn_divert.h
+++ b/drivers/isdn/divert/isdn_divert.h
@@ -3,7 +3,7 @@
  * Header for the diversion supplementary ioctl interface.
  *
  * Copyright 1998       by Werner Cornelius (werner@ikt.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -20,13 +20,13 @@
 #define IIOCGETDRV   _IO('I', 2)  /* get driver number */
 #define IIOCGETNAM   _IO('I', 3)  /* get driver name */
 #define IIOCGETRULE  _IO('I', 4)  /* read one rule */
-#define IIOCMODRULE  _IO('I', 5)  /* modify/replace a rule */  
+#define IIOCMODRULE  _IO('I', 5)  /* modify/replace a rule */
 #define IIOCINSRULE  _IO('I', 6)  /* insert/append one rule */
 #define IIOCDELRULE  _IO('I', 7)  /* delete a rule */
 #define IIOCDODFACT  _IO('I', 8)  /* hangup/reject/alert/immediately deflect a call */
 #define IIOCDOCFACT  _IO('I', 9)  /* activate control forwarding in PBX */
-#define IIOCDOCFDIS  _IO('I',10)  /* deactivate control forwarding in PBX */
-#define IIOCDOCFINT  _IO('I',11)  /* interrogate control forwarding in PBX */
+#define IIOCDOCFDIS  _IO('I', 10)  /* deactivate control forwarding in PBX */
+#define IIOCDOCFINT  _IO('I', 11)  /* interrogate control forwarding in PBX */
 
 /*************************************/
 /* states reported through interface */
@@ -34,65 +34,65 @@
 #define DEFLECT_IGNORE    0  /* ignore incoming call */
 #define DEFLECT_REPORT    1  /* only report */
 #define DEFLECT_PROCEED   2  /* deflect when externally triggered */
-#define DEFLECT_ALERT     3  /* alert and deflect after delay */ 
+#define DEFLECT_ALERT     3  /* alert and deflect after delay */
 #define DEFLECT_REJECT    4  /* reject immediately */
 #define DIVERT_ACTIVATE   5  /* diversion activate */
 #define DIVERT_DEACTIVATE 6  /* diversion deactivate */
-#define DIVERT_REPORT     7  /* interrogation result */ 
-#define DEFLECT_AUTODEL 255  /* only for internal use */ 
+#define DIVERT_REPORT     7  /* interrogation result */
+#define DEFLECT_AUTODEL 255  /* only for internal use */
 
 #define DEFLECT_ALL_IDS   0xFFFFFFFF /* all drivers selected */
 
 typedef struct
- { ulong drvid;     /* driver ids, bit mapped */
-   char my_msn[35]; /* desired msn, subaddr allowed */
-   char caller[35]; /* caller id, partial string with * + subaddr allowed */
-   char to_nr[35];  /* deflected to number incl. subaddress */
-   u_char si1,si2;  /* service indicators, si1=bitmask, si1+2 0 = all */
-   u_char screen;   /* screening: 0 = no info, 1 = info, 2 = nfo with nr */
-   u_char callopt;  /* option for call handling: 
-                       0 = all calls
-                       1 = only non waiting calls
-                       2 = only waiting calls */
-   u_char action;   /* desired action: 
-                       0 = don't report call -> ignore
-                       1 = report call, do not allow/proceed for deflection
-                       2 = report call, send proceed, wait max waittime secs
-                       3 = report call, alert and deflect after waittime 
-                       4 = report call, reject immediately  
-                       actions 1-2 only take place if interface is opened 
-		    */
-   u_char waittime; /* maximum wait time for proceeding */ 
- } divert_rule;
+{ ulong drvid;     /* driver ids, bit mapped */
+	char my_msn[35]; /* desired msn, subaddr allowed */
+	char caller[35]; /* caller id, partial string with * + subaddr allowed */
+	char to_nr[35];  /* deflected to number incl. subaddress */
+	u_char si1, si2;  /* service indicators, si1=bitmask, si1+2 0 = all */
+	u_char screen;   /* screening: 0 = no info, 1 = info, 2 = nfo with nr */
+	u_char callopt;  /* option for call handling:
+			    0 = all calls
+			    1 = only non waiting calls
+			    2 = only waiting calls */
+	u_char action;   /* desired action:
+			    0 = don't report call -> ignore
+			    1 = report call, do not allow/proceed for deflection
+			    2 = report call, send proceed, wait max waittime secs
+			    3 = report call, alert and deflect after waittime
+			    4 = report call, reject immediately
+			    actions 1-2 only take place if interface is opened
+			 */
+	u_char waittime; /* maximum wait time for proceeding */
+} divert_rule;
 
 typedef union
- { int drv_version; /* return of driver version */
-   struct 
-   { int drvid;		/* id of driver */
-     char drvnam[30];	/* name of driver */
-   } getid;
-   struct
-   { int ruleidx;	/* index of rule */
-     divert_rule rule;	/* rule parms */ 
-   } getsetrule;
-   struct
-   { u_char subcmd;  /* 0 = hangup/reject,
-                        1 = alert,
-                        2 = deflect */
-     ulong callid;   /* id of call delivered by ascii output */
-     char to_nr[35]; /* destination when deflect,
-                        else uus1 string (maxlen 31),
-                        data from rule used if empty */ 
-   } fwd_ctrl; 
-   struct
-   { int drvid;      /* id of driver */
-     u_char cfproc;  /* cfu = 0, cfb = 1, cfnr = 2 */
-     ulong procid;   /* process id returned when no error */ 
-     u_char service; /* basically coded service, 0 = all */
-     char msn[25];   /* desired msn, empty = all */
-     char fwd_nr[35];/* forwarded to number + subaddress */
-   } cf_ctrl;  
- } divert_ioctl;
+{ int drv_version; /* return of driver version */
+	struct
+	{ int drvid;		/* id of driver */
+		char drvnam[30];	/* name of driver */
+	} getid;
+	struct
+	{ int ruleidx;	/* index of rule */
+		divert_rule rule;	/* rule parms */
+	} getsetrule;
+	struct
+	{ u_char subcmd;  /* 0 = hangup/reject,
+			     1 = alert,
+			     2 = deflect */
+		ulong callid;   /* id of call delivered by ascii output */
+		char to_nr[35]; /* destination when deflect,
+				   else uus1 string (maxlen 31),
+				   data from rule used if empty */
+	} fwd_ctrl;
+	struct
+	{ int drvid;      /* id of driver */
+		u_char cfproc;  /* cfu = 0, cfb = 1, cfnr = 2 */
+		ulong procid;   /* process id returned when no error */
+		u_char service; /* basically coded service, 0 = all */
+		char msn[25];   /* desired msn, empty = all */
+		char fwd_nr[35];/* forwarded to number + subaddress */
+	} cf_ctrl;
+} divert_ioctl;
 
 #ifdef __KERNEL__
 
@@ -105,10 +105,10 @@ typedef union
 /* structure keeping ascii info for device output */
 /**************************************************/
 struct divert_info
-  { struct divert_info *next;
-    ulong usage_cnt; /* number of files still to work */   
-    char info_start[2]; /* info string start */ 
-  }; 
+{ struct divert_info *next;
+	ulong usage_cnt; /* number of files still to work */
+	char info_start[2]; /* info string start */
+};
 
 
 /**************/
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index fddae72..c90dca5 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -214,7 +214,7 @@ byte_stuff:
 				} else if (fcs != PPP_GOODFCS) {
 					/* frame check error */
 					dev_err(cs->dev,
-				"Checksum failed, %u bytes corrupted!\n",
+						"Checksum failed, %u bytes corrupted!\n",
 						skb->len);
 					gigaset_isdn_rcv_err(bcs);
 					dev_kfree_skb_any(skb);
@@ -543,7 +543,7 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb)
 	/* size of new buffer (worst case = every byte must be stuffed):
 	 * 2 * original size + room for link layer header
 	 */
-	iraw_skb = dev_alloc_skb(2*skb->len + skb->mac_len);
+	iraw_skb = dev_alloc_skb(2 * skb->len + skb->mac_len);
 	if (!iraw_skb) {
 		dev_kfree_skb_any(skb);
 		return NULL;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 3913f47..afa0802 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -410,10 +410,10 @@ static void check_pending(struct bas_cardstate *ucs)
 		if (!(ucs->basstate & BS_RESETTING))
 			ucs->pending = 0;
 		break;
-	/*
-	 * HD_READ_ATMESSAGE and HD_WRITE_ATMESSAGE are handled separately
-	 * and should never end up here
-	 */
+		/*
+		 * HD_READ_ATMESSAGE and HD_WRITE_ATMESSAGE are handled separately
+		 * and should never end up here
+		 */
 	default:
 		dev_warn(&ucs->interface->dev,
 			 "unknown pending request 0x%02x cleared\n",
@@ -491,7 +491,7 @@ static void read_ctrl_callback(struct urb *urb)
 		numbytes = urb->actual_length;
 		if (unlikely(numbytes != ucs->rcvbuf_size)) {
 			dev_warn(cs->dev,
-			       "control read: received %d chars, expected %d\n",
+				 "control read: received %d chars, expected %d\n",
 				 numbytes, ucs->rcvbuf_size);
 			if (numbytes > ucs->rcvbuf_size)
 				numbytes = ucs->rcvbuf_size;
@@ -710,7 +710,7 @@ static void read_int_callback(struct urb *urb)
 	}
 
 	l = (unsigned) ucs->int_in_buf[1] +
-	    (((unsigned) ucs->int_in_buf[2]) << 8);
+		(((unsigned) ucs->int_in_buf[2]) << 8);
 
 	gig_dbg(DEBUG_USBREQ, "<-------%d: 0x%02x (%u [0x%02x 0x%02x])",
 		urb->actual_length, (int)ucs->int_in_buf[0], l,
@@ -770,14 +770,14 @@ static void read_int_callback(struct urb *urb)
 	case HD_RECEIVEATDATA_ACK:	/* AT response ready to be received */
 		if (!l) {
 			dev_warn(cs->dev,
-				"HD_RECEIVEATDATA_ACK with length 0 ignored\n");
+				 "HD_RECEIVEATDATA_ACK with length 0 ignored\n");
 			break;
 		}
 		spin_lock_irqsave(&cs->lock, flags);
 		if (ucs->basstate & BS_ATRDPEND) {
 			spin_unlock_irqrestore(&cs->lock, flags);
 			dev_warn(cs->dev,
-	"HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n",
+				 "HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n",
 				 l, ucs->rcvbuf_size);
 			break;
 		}
@@ -878,7 +878,7 @@ static void read_iso_callback(struct urb *urb)
 			ubc->isoinlost += urb->iso_frame_desc[i].actual_length;
 			if (unlikely(urb->iso_frame_desc[i].status != 0 &&
 				     urb->iso_frame_desc[i].status !=
-								-EINPROGRESS))
+				     -EINPROGRESS))
 				ubc->loststatus = urb->iso_frame_desc[i].status;
 			urb->iso_frame_desc[i].status = 0;
 			urb->iso_frame_desc[i].actual_length = 0;
@@ -891,7 +891,7 @@ static void read_iso_callback(struct urb *urb)
 			rc = usb_submit_urb(urb, GFP_ATOMIC);
 			if (unlikely(rc != 0 && rc != -ENODEV)) {
 				dev_err(bcs->cs->dev,
-				       "could not resubmit isoc read URB: %s\n",
+					"could not resubmit isoc read URB: %s\n",
 					get_usb_rcmsg(rc));
 				dump_urb(DEBUG_ISO, "isoc read", urb);
 				error_hangup(bcs);
@@ -1017,17 +1017,17 @@ static int starturbs(struct bc_state *bcs)
 	}
 
 	/* keep one URB free, submit the others */
-	for (k = 0; k < BAS_OUTURBS-1; ++k) {
+	for (k = 0; k < BAS_OUTURBS - 1; ++k) {
 		dump_urb(DEBUG_ISO, "Initial isoc write", urb);
 		rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC);
 		if (rc != 0)
 			goto error;
 	}
 	dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb);
-	ubc->isooutfree = &ubc->isoouturbs[BAS_OUTURBS-1];
+	ubc->isooutfree = &ubc->isoouturbs[BAS_OUTURBS - 1];
 	ubc->isooutdone = ubc->isooutovfl = NULL;
 	return 0;
- error:
+error:
 	stopurbs(ubc);
 	return rc;
 }
@@ -1229,7 +1229,7 @@ static void write_iso_tasklet(unsigned long data)
 				if (ifd->status ||
 				    ifd->actual_length != ifd->length) {
 					dev_warn(cs->dev,
-					    "isoc write: frame %d[%d/%d]: %s\n",
+						 "isoc write: frame %d[%d/%d]: %s\n",
 						 i, ifd->actual_length,
 						 ifd->length,
 						 get_usb_statmsg(ifd->status));
@@ -1316,7 +1316,7 @@ static void read_iso_tasklet(unsigned long data)
 		ubc->isoindone = NULL;
 		if (unlikely(ubc->loststatus != -EINPROGRESS)) {
 			dev_warn(cs->dev,
-		"isoc read overrun, URB dropped (status: %s, %d bytes)\n",
+				 "isoc read overrun, URB dropped (status: %s, %d bytes)\n",
 				 get_usb_statmsg(ubc->loststatus),
 				 ubc->isoinlost);
 			ubc->loststatus = -EINPROGRESS;
@@ -1965,7 +1965,7 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
 	int rc;
 
 	gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
-			     DEBUG_TRANSCMD : DEBUG_LOCKCMD,
+			   DEBUG_TRANSCMD : DEBUG_LOCKCMD,
 			   "CMD Transmit", cb->len, cb->buf);
 
 	/* translate "+++" escape sequence sent as a single separate command
@@ -2453,13 +2453,13 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
 
 	/* wait a bit for blocking conditions to go away */
 	rc = wait_event_timeout(ucs->waitqueue,
-			!(ucs->basstate &
-			  (BS_B1OPEN|BS_B2OPEN|BS_ATRDPEND|BS_ATWRPEND)),
-			BAS_TIMEOUT*HZ/10);
+				!(ucs->basstate &
+				  (BS_B1OPEN | BS_B2OPEN | BS_ATRDPEND | BS_ATWRPEND)),
+				BAS_TIMEOUT * HZ / 10);
 	gig_dbg(DEBUG_SUSPEND, "wait_event_timeout() -> %d", rc);
 
 	/* check for conditions preventing suspend */
-	if (ucs->basstate & (BS_B1OPEN|BS_B2OPEN|BS_ATRDPEND|BS_ATWRPEND)) {
+	if (ucs->basstate & (BS_B1OPEN | BS_B2OPEN | BS_ATRDPEND | BS_ATWRPEND)) {
 		dev_warn(cs->dev, "cannot suspend:\n");
 		if (ucs->basstate & BS_B1OPEN)
 			dev_warn(cs->dev, " B channel 1 open\n");
@@ -2482,7 +2482,7 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
 			return rc;
 		}
 		wait_event_timeout(ucs->waitqueue, !ucs->pending,
-				   BAS_TIMEOUT*HZ/10);
+				   BAS_TIMEOUT * HZ / 10);
 		/* in case of timeout, proceed anyway */
 	}
 
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 6d5ceee..343b5c8 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -26,17 +26,17 @@
 #define CapiFacilitySpecificFunctionNotSupported	0x3011
 
 /* missing from capicmd.h */
-#define CAPI_CONNECT_IND_BASELEN	(CAPI_MSG_BASELEN+4+2+8*1)
-#define CAPI_CONNECT_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN+4+3*1)
-#define CAPI_CONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN+4+1)
-#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN+4+1)
-#define CAPI_DATA_B3_REQ_LEN64		(CAPI_MSG_BASELEN+4+4+2+2+2+8)
-#define CAPI_DATA_B3_CONF_LEN		(CAPI_MSG_BASELEN+4+2+2)
-#define CAPI_DISCONNECT_IND_LEN		(CAPI_MSG_BASELEN+4+2)
-#define CAPI_DISCONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN+4+2+1)
-#define CAPI_FACILITY_CONF_BASELEN	(CAPI_MSG_BASELEN+4+2+2+1)
+#define CAPI_CONNECT_IND_BASELEN	(CAPI_MSG_BASELEN + 4 + 2 + 8 * 1)
+#define CAPI_CONNECT_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN + 4 + 3 * 1)
+#define CAPI_CONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN + 4 + 1)
+#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN + 4 + 1)
+#define CAPI_DATA_B3_REQ_LEN64		(CAPI_MSG_BASELEN + 4 + 4 + 2 + 2 + 2 + 8)
+#define CAPI_DATA_B3_CONF_LEN		(CAPI_MSG_BASELEN + 4 + 2 + 2)
+#define CAPI_DISCONNECT_IND_LEN		(CAPI_MSG_BASELEN + 4 + 2)
+#define CAPI_DISCONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN + 4 + 2 + 1)
+#define CAPI_FACILITY_CONF_BASELEN	(CAPI_MSG_BASELEN + 4 + 2 + 2 + 1)
 /* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
-#define CAPI_STDCONF_LEN		(CAPI_MSG_BASELEN+4+2)
+#define CAPI_STDCONF_LEN		(CAPI_MSG_BASELEN + 4 + 2)
 
 #define CAPI_FACILITY_HANDSET	0x0000
 #define CAPI_FACILITY_DTMF	0x0001
@@ -97,10 +97,10 @@ struct gigaset_capi_ctr {
 	/* two _cmsg structures possibly used concurrently: */
 	_cmsg hcmsg;	/* for message composition triggered from hardware */
 	_cmsg acmsg;	/* for dissection of messages sent from application */
-	u8 bc_buf[MAX_BC_OCTETS+1];
-	u8 hlc_buf[MAX_HLC_OCTETS+1];
-	u8 cgpty_buf[MAX_NUMBER_DIGITS+3];
-	u8 cdpty_buf[MAX_NUMBER_DIGITS+2];
+	u8 bc_buf[MAX_BC_OCTETS + 1];
+	u8 hlc_buf[MAX_HLC_OCTETS + 1];
+	u8 cgpty_buf[MAX_NUMBER_DIGITS + 3];
+	u8 cdpty_buf[MAX_NUMBER_DIGITS + 2];
 };
 
 /* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
@@ -109,50 +109,50 @@ static struct {
 	u8 *hlc;
 } cip2bchlc[] = {
 	[1] = { "8090A3", NULL },
-		/* Speech (A-law) */
+	/* Speech (A-law) */
 	[2] = { "8890", NULL },
-		/* Unrestricted digital information */
+	/* Unrestricted digital information */
 	[3] = { "8990", NULL },
-		/* Restricted digital information */
+	/* Restricted digital information */
 	[4] = { "9090A3", NULL },
-		/* 3,1 kHz audio (A-law) */
+	/* 3,1 kHz audio (A-law) */
 	[5] = { "9190", NULL },
-		/* 7 kHz audio */
+	/* 7 kHz audio */
 	[6] = { "9890", NULL },
-		/* Video */
+	/* Video */
 	[7] = { "88C0C6E6", NULL },
-		/* Packet mode */
+	/* Packet mode */
 	[8] = { "8890218F", NULL },
-		/* 56 kbit/s rate adaptation */
+	/* 56 kbit/s rate adaptation */
 	[9] = { "9190A5", NULL },
-		/* Unrestricted digital information with tones/announcements */
+	/* Unrestricted digital information with tones/announcements */
 	[16] = { "8090A3", "9181" },
-		/* Telephony */
+	/* Telephony */
 	[17] = { "9090A3", "9184" },
-		/* Group 2/3 facsimile */
+	/* Group 2/3 facsimile */
 	[18] = { "8890", "91A1" },
-		/* Group 4 facsimile Class 1 */
+	/* Group 4 facsimile Class 1 */
 	[19] = { "8890", "91A4" },
-		/* Teletex service basic and mixed mode
-		   and Group 4 facsimile service Classes II and III */
+	/* Teletex service basic and mixed mode
+	   and Group 4 facsimile service Classes II and III */
 	[20] = { "8890", "91A8" },
-		/* Teletex service basic and processable mode */
+	/* Teletex service basic and processable mode */
 	[21] = { "8890", "91B1" },
-		/* Teletex service basic mode */
+	/* Teletex service basic mode */
 	[22] = { "8890", "91B2" },
-		/* International interworking for Videotex */
+	/* International interworking for Videotex */
 	[23] = { "8890", "91B5" },
-		/* Telex */
+	/* Telex */
 	[24] = { "8890", "91B8" },
-		/* Message Handling Systems in accordance with X.400 */
+	/* Message Handling Systems in accordance with X.400 */
 	[25] = { "8890", "91C1" },
-		/* OSI application in accordance with X.200 */
+	/* OSI application in accordance with X.200 */
 	[26] = { "9190A5", "9181" },
-		/* 7 kHz telephony */
+	/* 7 kHz telephony */
 	[27] = { "9190A5", "916001" },
-		/* Video telephony, first connection */
+	/* Video telephony, first connection */
 	[28] = { "8890", "916002" },
-		/* Video telephony, second connection */
+	/* Video telephony, second connection */
 };
 
 /*
@@ -164,7 +164,7 @@ static struct {
  * emit unsupported parameter warning
  */
 static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
-				       char *msgname, char *paramname)
+					char *msgname, char *paramname)
 {
 	if (param && *param)
 		dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
@@ -259,15 +259,15 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
 		CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
 		CAPIMSG_CONTROL(data));
 	l -= 12;
-	dbgline = kmalloc(3*l, GFP_ATOMIC);
+	dbgline = kmalloc(3 * l, GFP_ATOMIC);
 	if (!dbgline)
 		return;
 	for (i = 0; i < l; i++) {
-		dbgline[3*i] = hex_asc_hi(data[12+i]);
-		dbgline[3*i+1] = hex_asc_lo(data[12+i]);
-		dbgline[3*i+2] = ' ';
+		dbgline[3 * i] = hex_asc_hi(data[12 + i]);
+		dbgline[3 * i + 1] = hex_asc_lo(data[12 + i]);
+		dbgline[3 * i + 2] = ' ';
 	}
-	dbgline[3*l-1] = '\0';
+	dbgline[3 * l - 1] = '\0';
 	gig_dbg(level, "  %s", dbgline);
 	kfree(dbgline);
 	if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
@@ -279,16 +279,16 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
 			return;
 		if (l > 64)
 			l = 64; /* arbitrary limit */
-		dbgline = kmalloc(3*l, GFP_ATOMIC);
+		dbgline = kmalloc(3 * l, GFP_ATOMIC);
 		if (!dbgline)
 			return;
 		data += CAPIMSG_LEN(data);
 		for (i = 0; i < l; i++) {
-			dbgline[3*i] = hex_asc_hi(data[i]);
-			dbgline[3*i+1] = hex_asc_lo(data[i]);
-			dbgline[3*i+2] = ' ';
+			dbgline[3 * i] = hex_asc_hi(data[i]);
+			dbgline[3 * i + 1] = hex_asc_lo(data[i]);
+			dbgline[3 * i + 2] = ' ';
 		}
-		dbgline[3*l-1] = '\0';
+		dbgline[3 * l - 1] = '\0';
 		gig_dbg(level, "  %s", dbgline);
 		kfree(dbgline);
 	}
@@ -301,7 +301,7 @@ static inline void dump_rawmsg(enum debuglevel level, const char *tag,
 
 static const char *format_ie(const char *ie)
 {
-	static char result[3*MAX_FMT_IE_LEN];
+	static char result[3 * MAX_FMT_IE_LEN];
 	int len, count;
 	char *pout = result;
 
@@ -310,7 +310,7 @@ static const char *format_ie(const char *ie)
 
 	count = len = ie[0];
 	if (count > MAX_FMT_IE_LEN)
-		count = MAX_FMT_IE_LEN-1;
+		count = MAX_FMT_IE_LEN - 1;
 	while (count--) {
 		*pout++ = hex_asc_hi(*++ie);
 		*pout++ = hex_asc_lo(*ie);
@@ -403,8 +403,8 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
 		send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req),
 				  bcs->channel + 1, CAPIMSG_HANDLE_REQ(req),
 				  (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
-					CapiFlagsNotSupportedByProtocol :
-					CAPI_NOERROR);
+				  CapiFlagsNotSupportedByProtocol :
+				  CAPI_NOERROR);
 }
 EXPORT_SYMBOL_GPL(gigaset_skb_sent);
 
@@ -589,7 +589,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 		}
 		iif->cdpty_buf[0] = i + 1;
 		iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
-		memcpy(iif->cdpty_buf+2, at_state->str_var[STR_ZCPN], i);
+		memcpy(iif->cdpty_buf + 2, at_state->str_var[STR_ZCPN], i);
 		iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
 		msgsize += iif->hcmsg.CalledPartyNumber[0];
 	}
@@ -605,7 +605,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 		iif->cgpty_buf[0] = i + 2;
 		iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
 		iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
-		memcpy(iif->cgpty_buf+3, at_state->str_var[STR_NMBR], i);
+		memcpy(iif->cgpty_buf + 3, at_state->str_var[STR_NMBR], i);
 		iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
 		msgsize += iif->hcmsg.CallingPartyNumber[0];
 	}
@@ -977,7 +977,7 @@ void gigaset_isdn_stop(struct cardstate *cs)
  * register CAPI application
  */
 static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
-			   capi_register_params *rp)
+				  capi_register_params *rp)
 {
 	struct gigaset_capi_ctr *iif
 		= container_of(ctr, struct gigaset_capi_ctr, ctr);
@@ -1181,21 +1181,21 @@ static void do_facility_req(struct gigaset_capi_ctr *iif,
 			}
 			if (CAPIMSG_U32(pparam, 4) != 0) {
 				dev_notice(cs->dev,
-	"%s: unsupported supplementary service notification mask 0x%x\n",
-				   "FACILITY_REQ", CAPIMSG_U32(pparam, 4));
+					   "%s: unsupported supplementary service notification mask 0x%x\n",
+					   "FACILITY_REQ", CAPIMSG_U32(pparam, 4));
 				info = CapiFacilitySpecificFunctionNotSupported;
 				confparam[3] = 2;	/* length */
 				capimsg_setu16(confparam, 4,
-					CapiSupplementaryServiceNotSupported);
+					       CapiSupplementaryServiceNotSupported);
 			}
 			info = CapiSuccess;
 			confparam[3] = 2;	/* length */
 			capimsg_setu16(confparam, 4, CapiSuccess);
 			break;
-		/* ToDo: add supported services */
+			/* ToDo: add supported services */
 		default:
 			dev_notice(cs->dev,
-		"%s: unsupported supplementary service function 0x%04x\n",
+				   "%s: unsupported supplementary service function 0x%04x\n",
 				   "FACILITY_REQ", function);
 			info = CapiFacilitySpecificFunctionNotSupported;
 			/* Supplementary Service specific parameter */
@@ -1318,7 +1318,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 	cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
 
 	/* build command table */
-	commands = kzalloc(AT_NUM*(sizeof *commands), GFP_KERNEL);
+	commands = kzalloc(AT_NUM * (sizeof *commands), GFP_KERNEL);
 	if (!commands)
 		goto oom;
 
@@ -1353,10 +1353,10 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 	commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
 	if (!commands[AT_TYPE])
 		goto oom;
-	commands[AT_DIAL] = kmalloc(l+3, GFP_KERNEL);
+	commands[AT_DIAL] = kmalloc(l + 3, GFP_KERNEL);
 	if (!commands[AT_DIAL])
 		goto oom;
-	snprintf(commands[AT_DIAL], l+3, "D%.*s\r", l, pp);
+	snprintf(commands[AT_DIAL], l + 3, "D%.*s\r", l, pp);
 
 	/* encode parameter: Calling party number */
 	pp = cmsg->CallingPartyNumber;
@@ -1406,10 +1406,10 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 
 		if (l) {
 			/* number */
-			commands[AT_MSN] = kmalloc(l+8, GFP_KERNEL);
+			commands[AT_MSN] = kmalloc(l + 8, GFP_KERNEL);
 			if (!commands[AT_MSN])
 				goto oom;
-			snprintf(commands[AT_MSN], l+8, "^SMSN=%*s\r", l, pp);
+			snprintf(commands[AT_MSN], l + 8, "^SMSN=%*s\r", l, pp);
 		}
 	}
 
@@ -1430,13 +1430,13 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 
 	/* determine lengths */
 	if (cmsg->BC && cmsg->BC[0])		/* BC specified explicitly */
-		lbc = 2*cmsg->BC[0];
+		lbc = 2 * cmsg->BC[0];
 	else if (cip2bchlc[cmsg->CIPValue].bc)	/* BC derived from CIP */
 		lbc = strlen(cip2bchlc[cmsg->CIPValue].bc);
 	else					/* no BC */
 		lbc = 0;
 	if (cmsg->HLC && cmsg->HLC[0])		/* HLC specified explicitly */
-		lhlc = 2*cmsg->HLC[0];
+		lhlc = 2 * cmsg->HLC[0];
 	else if (cip2bchlc[cmsg->CIPValue].hlc)	/* HLC derived from CIP */
 		lhlc = strlen(cip2bchlc[cmsg->CIPValue].hlc);
 	else					/* no HLC */
@@ -1481,7 +1481,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 	if (cmsg->BProtocol == CAPI_DEFAULT) {
 		bcs->proto2 = L2_HDLC;
 		dev_warn(cs->dev,
-		    "B2 Protocol X.75 SLP unsupported, using Transparent\n");
+			 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
 	} else {
 		switch (cmsg->B1protocol) {
 		case 0:
@@ -1492,24 +1492,24 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 			break;
 		default:
 			dev_warn(cs->dev,
-			    "B1 Protocol %u unsupported, using Transparent\n",
+				 "B1 Protocol %u unsupported, using Transparent\n",
 				 cmsg->B1protocol);
 			bcs->proto2 = L2_VOICE;
 		}
 		if (cmsg->B2protocol != 1)
 			dev_warn(cs->dev,
-			    "B2 Protocol %u unsupported, using Transparent\n",
+				 "B2 Protocol %u unsupported, using Transparent\n",
 				 cmsg->B2protocol);
 		if (cmsg->B3protocol != 0)
 			dev_warn(cs->dev,
-			    "B3 Protocol %u unsupported, using Transparent\n",
+				 "B3 Protocol %u unsupported, using Transparent\n",
 				 cmsg->B3protocol);
 		ignore_cstruct_param(cs, cmsg->B1configuration,
-					"CONNECT_REQ", "B1 Configuration");
+				     "CONNECT_REQ", "B1 Configuration");
 		ignore_cstruct_param(cs, cmsg->B2configuration,
-					"CONNECT_REQ", "B2 Configuration");
+				     "CONNECT_REQ", "B2 Configuration");
 		ignore_cstruct_param(cs, cmsg->B3configuration,
-					"CONNECT_REQ", "B3 Configuration");
+				     "CONNECT_REQ", "B3 Configuration");
 	}
 	commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
 	if (!commands[AT_PROTO])
@@ -1518,20 +1518,20 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
 
 	/* ToDo: check/encode remaining parameters */
 	ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
-					"CONNECT_REQ", "Called pty subaddr");
+			     "CONNECT_REQ", "Called pty subaddr");
 	ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
-					"CONNECT_REQ", "Calling pty subaddr");
+			     "CONNECT_REQ", "Calling pty subaddr");
 	ignore_cstruct_param(cs, cmsg->LLC,
-					"CONNECT_REQ", "LLC");
+			     "CONNECT_REQ", "LLC");
 	if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
 		ignore_cstruct_param(cs, cmsg->BChannelinformation,
-					"CONNECT_REQ", "B Channel Information");
+				     "CONNECT_REQ", "B Channel Information");
 		ignore_cstruct_param(cs, cmsg->Keypadfacility,
-					"CONNECT_REQ", "Keypad Facility");
+				     "CONNECT_REQ", "Keypad Facility");
 		ignore_cstruct_param(cs, cmsg->Useruserdata,
-					"CONNECT_REQ", "User-User Data");
+				     "CONNECT_REQ", "User-User Data");
 		ignore_cstruct_param(cs, cmsg->Facilitydataarray,
-					"CONNECT_REQ", "Facility Data Array");
+				     "CONNECT_REQ", "Facility Data Array");
 	}
 
 	/* encode parameter: B channel to use */
@@ -1602,7 +1602,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 			if (oap != ap) {
 				spin_unlock_irqrestore(&bcs->aplock, flags);
 				send_disconnect_ind(bcs, oap,
-					CapiCallGivenToOtherApplication);
+						    CapiCallGivenToOtherApplication);
 				spin_lock_irqsave(&bcs->aplock, flags);
 			}
 		}
@@ -1619,7 +1619,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 		if (cmsg->BProtocol == CAPI_DEFAULT) {
 			bcs->proto2 = L2_HDLC;
 			dev_warn(cs->dev,
-		"B2 Protocol X.75 SLP unsupported, using Transparent\n");
+				 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
 		} else {
 			switch (cmsg->B1protocol) {
 			case 0:
@@ -1630,46 +1630,46 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 				break;
 			default:
 				dev_warn(cs->dev,
-			"B1 Protocol %u unsupported, using Transparent\n",
+					 "B1 Protocol %u unsupported, using Transparent\n",
 					 cmsg->B1protocol);
 				bcs->proto2 = L2_VOICE;
 			}
 			if (cmsg->B2protocol != 1)
 				dev_warn(cs->dev,
-			"B2 Protocol %u unsupported, using Transparent\n",
+					 "B2 Protocol %u unsupported, using Transparent\n",
 					 cmsg->B2protocol);
 			if (cmsg->B3protocol != 0)
 				dev_warn(cs->dev,
-			"B3 Protocol %u unsupported, using Transparent\n",
+					 "B3 Protocol %u unsupported, using Transparent\n",
 					 cmsg->B3protocol);
 			ignore_cstruct_param(cs, cmsg->B1configuration,
-					"CONNECT_RESP", "B1 Configuration");
+					     "CONNECT_RESP", "B1 Configuration");
 			ignore_cstruct_param(cs, cmsg->B2configuration,
-					"CONNECT_RESP", "B2 Configuration");
+					     "CONNECT_RESP", "B2 Configuration");
 			ignore_cstruct_param(cs, cmsg->B3configuration,
-					"CONNECT_RESP", "B3 Configuration");
+					     "CONNECT_RESP", "B3 Configuration");
 		}
 
 		/* ToDo: check/encode remaining parameters */
 		ignore_cstruct_param(cs, cmsg->ConnectedNumber,
-					"CONNECT_RESP", "Connected Number");
+				     "CONNECT_RESP", "Connected Number");
 		ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
-					"CONNECT_RESP", "Connected Subaddress");
+				     "CONNECT_RESP", "Connected Subaddress");
 		ignore_cstruct_param(cs, cmsg->LLC,
-					"CONNECT_RESP", "LLC");
+				     "CONNECT_RESP", "LLC");
 		if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
 			ignore_cstruct_param(cs, cmsg->BChannelinformation,
-					"CONNECT_RESP", "BChannel Information");
+					     "CONNECT_RESP", "BChannel Information");
 			ignore_cstruct_param(cs, cmsg->Keypadfacility,
-					"CONNECT_RESP", "Keypad Facility");
+					     "CONNECT_RESP", "Keypad Facility");
 			ignore_cstruct_param(cs, cmsg->Useruserdata,
-					"CONNECT_RESP", "User-User Data");
+					     "CONNECT_RESP", "User-User Data");
 			ignore_cstruct_param(cs, cmsg->Facilitydataarray,
-					"CONNECT_RESP", "Facility Data Array");
+					     "CONNECT_RESP", "Facility Data Array");
 		}
 
 		/* Accept call */
-		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+		if (!gigaset_add_event(cs, &cs->bcs[channel - 1].at_state,
 				       EV_ACCEPT, NULL, 0, NULL))
 			return;
 		gigaset_schedule_event(cs);
@@ -1712,7 +1712,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 			if (oap != ap) {
 				spin_unlock_irqrestore(&bcs->aplock, flags);
 				send_disconnect_ind(bcs, oap,
-					CapiCallGivenToOtherApplication);
+						    CapiCallGivenToOtherApplication);
 				spin_lock_irqsave(&bcs->aplock, flags);
 			}
 		}
@@ -1723,7 +1723,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
 		/* reject call - will trigger DISCONNECT_IND for this app */
 		dev_info(cs->dev, "%s: Reject=%x\n",
 			 "CONNECT_RESP", cmsg->Reject);
-		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
+		if (!gigaset_add_event(cs, &cs->bcs[channel - 1].at_state,
 				       EV_HUP, NULL, 0, NULL))
 			return;
 		gigaset_schedule_event(cs);
@@ -1756,7 +1756,7 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
 		return;
 	}
-	bcs = &cs->bcs[channel-1];
+	bcs = &cs->bcs[channel - 1];
 
 	/* mark logical connection active */
 	bcs->apconnstate = APCONN_ACTIVE;
@@ -1767,7 +1767,7 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
 	/* NCPI parameter: not applicable for B3 Transparent */
 	ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
 	send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
-				CapiNcpiNotSupportedByProtocol : CapiSuccess);
+		  CapiNcpiNotSupportedByProtocol : CapiSuccess);
 }
 
 /*
@@ -1801,7 +1801,7 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
 		dev_kfree_skb_any(skb);
 		return;
 	}
-	bcs = &cs->bcs[channel-1];
+	bcs = &cs->bcs[channel - 1];
 
 	if (cmsg->Reject) {
 		/* Reject: clear B3 connect received flag */
@@ -1905,7 +1905,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
 			return;
 		}
 		capi_cmsg2message(b3cmsg,
-			__skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
+				  __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
 		kfree(b3cmsg);
 		capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
 	}
@@ -1947,7 +1947,7 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
 		return;
 	}
-	bcs = &cs->bcs[channel-1];
+	bcs = &cs->bcs[channel - 1];
 
 	/* reject if logical connection not active */
 	if (bcs->apconnstate < APCONN_ACTIVE) {
@@ -1965,9 +1965,9 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
 
 	/* NCPI parameter: not applicable for B3 Transparent */
 	ignore_cstruct_param(cs, cmsg->NCPI,
-				"DISCONNECT_B3_REQ", "NCPI");
+			     "DISCONNECT_B3_REQ", "NCPI");
 	send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
-				CapiNcpiNotSupportedByProtocol : CapiSuccess);
+		  CapiNcpiNotSupportedByProtocol : CapiSuccess);
 }
 
 /*
@@ -1997,7 +1997,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
 		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
 		return;
 	}
-	bcs = &cs->bcs[channel-1];
+	bcs = &cs->bcs[channel - 1];
 	if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
 		dev_notice(cs->dev, "%s: unexpected length %d\n",
 			   "DATA_B3_REQ", msglen);
@@ -2040,7 +2040,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif,
 	if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION))
 		send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle,
 				  flags ? CapiFlagsNotSupportedByProtocol
-					: CAPI_NOERROR);
+				  : CAPI_NOERROR);
 }
 
 /*
@@ -2258,11 +2258,11 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
 
 	seq_printf(m, "%-16s %s\n", "name", ctr->name);
 	seq_printf(m, "%-16s %s %s\n", "dev",
-			dev_driver_string(cs->dev), dev_name(cs->dev));
+		   dev_driver_string(cs->dev), dev_name(cs->dev));
 	seq_printf(m, "%-16s %d\n", "id", cs->myid);
 	if (cs->gotfwver)
 		seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
-			cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
+			   cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
 	seq_printf(m, "%-16s %d\n", "channels", cs->channels);
 	seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
 
@@ -2315,13 +2315,13 @@ static int gigaset_proc_show(struct seq_file *m, void *v)
 
 	for (i = 0; i < cs->channels; i++) {
 		seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
-				cs->bcs[i].corrupted);
+			   cs->bcs[i].corrupted);
 		seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
-				cs->bcs[i].trans_down);
+			   cs->bcs[i].trans_down);
 		seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
-				cs->bcs[i].trans_up);
+			   cs->bcs[i].trans_up);
 		seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
-				cs->bcs[i].chstate);
+			   cs->bcs[i].chstate);
 		switch (cs->bcs[i].proto2) {
 		case L2_BITSYNC:
 			s = "bitsync";
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index db621db..e55aabf 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -30,7 +30,7 @@
 /* Module parameters */
 int gigaset_debuglevel;
 EXPORT_SYMBOL_GPL(gigaset_debuglevel);
-module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR);
+module_param_named(debug, gigaset_debuglevel, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "debug level");
 
 /* driver state flags */
@@ -123,7 +123,7 @@ int gigaset_enterconfigmode(struct cardstate *cs)
 		if (r < 0)
 			goto error;
 	}
-	r = setflags(cs, TIOCM_RTS|TIOCM_DTR, 800);
+	r = setflags(cs, TIOCM_RTS | TIOCM_DTR, 800);
 	if (r < 0)
 		goto error;
 
@@ -131,8 +131,8 @@ int gigaset_enterconfigmode(struct cardstate *cs)
 
 error:
 	dev_err(cs->dev, "error %d on setuartbits\n", -r);
-	cs->control_state = TIOCM_RTS|TIOCM_DTR;
-	cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR);
+	cs->control_state = TIOCM_RTS | TIOCM_DTR;
+	cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS | TIOCM_DTR);
 
 	return -1;
 }
@@ -591,7 +591,7 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
 		if (head > tail)
 			n = head - 1 - tail;
 		else if (head == 0)
-			n = (RBUFSIZE-1) - tail;
+			n = (RBUFSIZE - 1) - tail;
 		else
 			n = RBUFSIZE - tail;
 		if (!n) {
@@ -911,10 +911,10 @@ int gigaset_start(struct cardstate *cs)
 	spin_unlock_irqrestore(&cs->lock, flags);
 
 	if (cs->mstate != MS_LOCKED) {
-		cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
+		cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR | TIOCM_RTS);
 		cs->ops->baud_rate(cs, B115200);
 		cs->ops->set_line_ctrl(cs, CS8);
-		cs->control_state = TIOCM_DTR|TIOCM_RTS;
+		cs->control_state = TIOCM_DTR | TIOCM_RTS;
 	}
 
 	cs->waiting = 1;
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 6d12623..624a825 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -153,104 +153,104 @@ struct reply_t gigaset_tab_nocid[] =
  * action, command */
 
 /* initialize device, set cid mode if possible */
-{RSP_INIT,	 -1,  -1, SEQ_INIT,		100,  1, {ACT_TIMEOUT} },
+	{RSP_INIT,	 -1,  -1, SEQ_INIT,		100,  1, {ACT_TIMEOUT} },
 
-{EV_TIMEOUT,	100, 100, -1,			101,  3, {0},	"Z\r"},
-{RSP_OK,	101, 103, -1,			120,  5, {ACT_GETSTRING},
-								"+GMR\r"},
+	{EV_TIMEOUT,	100, 100, -1,			101,  3, {0},	"Z\r"},
+	{RSP_OK,	101, 103, -1,			120,  5, {ACT_GETSTRING},
+	 "+GMR\r"},
 
-{EV_TIMEOUT,	101, 101, -1,			102,  5, {0},	"Z\r"},
-{RSP_ERROR,	101, 101, -1,			102,  5, {0},	"Z\r"},
+	{EV_TIMEOUT,	101, 101, -1,			102,  5, {0},	"Z\r"},
+	{RSP_ERROR,	101, 101, -1,			102,  5, {0},	"Z\r"},
 
-{EV_TIMEOUT,	102, 102, -1,			108,  5, {ACT_SETDLE1},
-								"^SDLE=0\r"},
-{RSP_OK,	108, 108, -1,			104, -1},
-{RSP_ZDLE,	104, 104,  0,			103,  5, {0},	"Z\r"},
-{EV_TIMEOUT,	104, 104, -1,			  0,  0, {ACT_FAILINIT} },
-{RSP_ERROR,	108, 108, -1,			  0,  0, {ACT_FAILINIT} },
+	{EV_TIMEOUT,	102, 102, -1,			108,  5, {ACT_SETDLE1},
+	 "^SDLE=0\r"},
+	{RSP_OK,	108, 108, -1,			104, -1},
+	{RSP_ZDLE,	104, 104,  0,			103,  5, {0},	"Z\r"},
+	{EV_TIMEOUT,	104, 104, -1,			  0,  0, {ACT_FAILINIT} },
+	{RSP_ERROR,	108, 108, -1,			  0,  0, {ACT_FAILINIT} },
 
-{EV_TIMEOUT,	108, 108, -1,			105,  2, {ACT_SETDLE0,
-							  ACT_HUPMODEM,
-							  ACT_TIMEOUT} },
-{EV_TIMEOUT,	105, 105, -1,			103,  5, {0},	"Z\r"},
+	{EV_TIMEOUT,	108, 108, -1,			105,  2, {ACT_SETDLE0,
+								  ACT_HUPMODEM,
+								  ACT_TIMEOUT} },
+	{EV_TIMEOUT,	105, 105, -1,			103,  5, {0},	"Z\r"},
 
-{RSP_ERROR,	102, 102, -1,			107,  5, {0},	"^GETPRE\r"},
-{RSP_OK,	107, 107, -1,			  0,  0, {ACT_CONFIGMODE} },
-{RSP_ERROR,	107, 107, -1,			  0,  0, {ACT_FAILINIT} },
-{EV_TIMEOUT,	107, 107, -1,			  0,  0, {ACT_FAILINIT} },
+	{RSP_ERROR,	102, 102, -1,			107,  5, {0},	"^GETPRE\r"},
+	{RSP_OK,	107, 107, -1,			  0,  0, {ACT_CONFIGMODE} },
+	{RSP_ERROR,	107, 107, -1,			  0,  0, {ACT_FAILINIT} },
+	{EV_TIMEOUT,	107, 107, -1,			  0,  0, {ACT_FAILINIT} },
 
-{RSP_ERROR,	103, 103, -1,			  0,  0, {ACT_FAILINIT} },
-{EV_TIMEOUT,	103, 103, -1,			  0,  0, {ACT_FAILINIT} },
+	{RSP_ERROR,	103, 103, -1,			  0,  0, {ACT_FAILINIT} },
+	{EV_TIMEOUT,	103, 103, -1,			  0,  0, {ACT_FAILINIT} },
 
-{RSP_STRING,	120, 120, -1,			121, -1, {ACT_SETVER} },
+	{RSP_STRING,	120, 120, -1,			121, -1, {ACT_SETVER} },
 
-{EV_TIMEOUT,	120, 121, -1,			  0,  0, {ACT_FAILVER,
-							  ACT_INIT} },
-{RSP_ERROR,	120, 121, -1,			  0,  0, {ACT_FAILVER,
-							  ACT_INIT} },
-{RSP_OK,	121, 121, -1,			  0,  0, {ACT_GOTVER,
-							  ACT_INIT} },
+	{EV_TIMEOUT,	120, 121, -1,			  0,  0, {ACT_FAILVER,
+								  ACT_INIT} },
+	{RSP_ERROR,	120, 121, -1,			  0,  0, {ACT_FAILVER,
+								  ACT_INIT} },
+	{RSP_OK,	121, 121, -1,			  0,  0, {ACT_GOTVER,
+								  ACT_INIT} },
 
 /* leave dle mode */
-{RSP_INIT,	  0,   0, SEQ_DLE0,		201,  5, {0},	"^SDLE=0\r"},
-{RSP_OK,	201, 201, -1,			202, -1},
-{RSP_ZDLE,	202, 202,  0,			  0,  0, {ACT_DLE0} },
-{RSP_NODEV,	200, 249, -1,			  0,  0, {ACT_FAKEDLE0} },
-{RSP_ERROR,	200, 249, -1,			  0,  0, {ACT_FAILDLE0} },
-{EV_TIMEOUT,	200, 249, -1,			  0,  0, {ACT_FAILDLE0} },
+	{RSP_INIT,	  0,   0, SEQ_DLE0,		201,  5, {0},	"^SDLE=0\r"},
+	{RSP_OK,	201, 201, -1,			202, -1},
+	{RSP_ZDLE,	202, 202,  0,			  0,  0, {ACT_DLE0} },
+	{RSP_NODEV,	200, 249, -1,			  0,  0, {ACT_FAKEDLE0} },
+	{RSP_ERROR,	200, 249, -1,			  0,  0, {ACT_FAILDLE0} },
+	{EV_TIMEOUT,	200, 249, -1,			  0,  0, {ACT_FAILDLE0} },
 
 /* enter dle mode */
-{RSP_INIT,	  0,   0, SEQ_DLE1,		251,  5, {0},	"^SDLE=1\r"},
-{RSP_OK,	251, 251, -1,			252, -1},
-{RSP_ZDLE,	252, 252,  1,			  0,  0, {ACT_DLE1} },
-{RSP_ERROR,	250, 299, -1,			  0,  0, {ACT_FAILDLE1} },
-{EV_TIMEOUT,	250, 299, -1,			  0,  0, {ACT_FAILDLE1} },
+	{RSP_INIT,	  0,   0, SEQ_DLE1,		251,  5, {0},	"^SDLE=1\r"},
+	{RSP_OK,	251, 251, -1,			252, -1},
+	{RSP_ZDLE,	252, 252,  1,			  0,  0, {ACT_DLE1} },
+	{RSP_ERROR,	250, 299, -1,			  0,  0, {ACT_FAILDLE1} },
+	{EV_TIMEOUT,	250, 299, -1,			  0,  0, {ACT_FAILDLE1} },
 
 /* incoming call */
-{RSP_RING,	 -1,  -1, -1,			 -1, -1, {ACT_RING} },
+	{RSP_RING,	 -1,  -1, -1,			 -1, -1, {ACT_RING} },
 
 /* get cid */
-{RSP_INIT,	  0,   0, SEQ_CID,		301,  5, {0},	"^SGCI?\r"},
-{RSP_OK,	301, 301, -1,			302, -1},
-{RSP_ZGCI,	302, 302, -1,			  0,  0, {ACT_CID} },
-{RSP_ERROR,	301, 349, -1,			  0,  0, {ACT_FAILCID} },
-{EV_TIMEOUT,	301, 349, -1,			  0,  0, {ACT_FAILCID} },
+	{RSP_INIT,	  0,   0, SEQ_CID,		301,  5, {0},	"^SGCI?\r"},
+	{RSP_OK,	301, 301, -1,			302, -1},
+	{RSP_ZGCI,	302, 302, -1,			  0,  0, {ACT_CID} },
+	{RSP_ERROR,	301, 349, -1,			  0,  0, {ACT_FAILCID} },
+	{EV_TIMEOUT,	301, 349, -1,			  0,  0, {ACT_FAILCID} },
 
 /* enter cid mode */
-{RSP_INIT,	  0,   0, SEQ_CIDMODE,		150,  5, {0},	"^SGCI=1\r"},
-{RSP_OK,	150, 150, -1,			  0,  0, {ACT_CMODESET} },
-{RSP_ERROR,	150, 150, -1,			  0,  0, {ACT_FAILCMODE} },
-{EV_TIMEOUT,	150, 150, -1,			  0,  0, {ACT_FAILCMODE} },
+	{RSP_INIT,	  0,   0, SEQ_CIDMODE,		150,  5, {0},	"^SGCI=1\r"},
+	{RSP_OK,	150, 150, -1,			  0,  0, {ACT_CMODESET} },
+	{RSP_ERROR,	150, 150, -1,			  0,  0, {ACT_FAILCMODE} },
+	{EV_TIMEOUT,	150, 150, -1,			  0,  0, {ACT_FAILCMODE} },
 
 /* leave cid mode */
-{RSP_INIT,	  0,   0, SEQ_UMMODE,		160,  5, {0},	"Z\r"},
-{RSP_OK,	160, 160, -1,			  0,  0, {ACT_UMODESET} },
-{RSP_ERROR,	160, 160, -1,			  0,  0, {ACT_FAILUMODE} },
-{EV_TIMEOUT,	160, 160, -1,			  0,  0, {ACT_FAILUMODE} },
+	{RSP_INIT,	  0,   0, SEQ_UMMODE,		160,  5, {0},	"Z\r"},
+	{RSP_OK,	160, 160, -1,			  0,  0, {ACT_UMODESET} },
+	{RSP_ERROR,	160, 160, -1,			  0,  0, {ACT_FAILUMODE} },
+	{EV_TIMEOUT,	160, 160, -1,			  0,  0, {ACT_FAILUMODE} },
 
 /* abort getting cid */
-{RSP_INIT,	  0,   0, SEQ_NOCID,		  0,  0, {ACT_ABORTCID} },
+	{RSP_INIT,	  0,   0, SEQ_NOCID,		  0,  0, {ACT_ABORTCID} },
 
 /* reset */
-{RSP_INIT,	  0,   0, SEQ_SHUTDOWN,		504,  5, {0},	"Z\r"},
-{RSP_OK,	504, 504, -1,			  0,  0, {ACT_SDOWN} },
-{RSP_ERROR,	501, 599, -1,			  0,  0, {ACT_FAILSDOWN} },
-{EV_TIMEOUT,	501, 599, -1,			  0,  0, {ACT_FAILSDOWN} },
-{RSP_NODEV,	501, 599, -1,			  0,  0, {ACT_FAKESDOWN} },
-
-{EV_PROC_CIDMODE, -1, -1, -1,			 -1, -1, {ACT_PROC_CIDMODE} },
-{EV_IF_LOCK,	 -1,  -1, -1,			 -1, -1, {ACT_IF_LOCK} },
-{EV_IF_VER,	 -1,  -1, -1,			 -1, -1, {ACT_IF_VER} },
-{EV_START,	 -1,  -1, -1,			 -1, -1, {ACT_START} },
-{EV_STOP,	 -1,  -1, -1,			 -1, -1, {ACT_STOP} },
-{EV_SHUTDOWN,	 -1,  -1, -1,			 -1, -1, {ACT_SHUTDOWN} },
+	{RSP_INIT,	  0,   0, SEQ_SHUTDOWN,		504,  5, {0},	"Z\r"},
+	{RSP_OK,	504, 504, -1,			  0,  0, {ACT_SDOWN} },
+	{RSP_ERROR,	501, 599, -1,			  0,  0, {ACT_FAILSDOWN} },
+	{EV_TIMEOUT,	501, 599, -1,			  0,  0, {ACT_FAILSDOWN} },
+	{RSP_NODEV,	501, 599, -1,			  0,  0, {ACT_FAKESDOWN} },
+
+	{EV_PROC_CIDMODE, -1, -1, -1,			 -1, -1, {ACT_PROC_CIDMODE} },
+	{EV_IF_LOCK,	 -1,  -1, -1,			 -1, -1, {ACT_IF_LOCK} },
+	{EV_IF_VER,	 -1,  -1, -1,			 -1, -1, {ACT_IF_VER} },
+	{EV_START,	 -1,  -1, -1,			 -1, -1, {ACT_START} },
+	{EV_STOP,	 -1,  -1, -1,			 -1, -1, {ACT_STOP} },
+	{EV_SHUTDOWN,	 -1,  -1, -1,			 -1, -1, {ACT_SHUTDOWN} },
 
 /* misc. */
-{RSP_ERROR,	 -1,  -1, -1,			 -1, -1, {ACT_ERROR} },
-{RSP_ZCAU,	 -1,  -1, -1,			 -1, -1, {ACT_ZCAU} },
-{RSP_NONE,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
-{RSP_ANY,	 -1,  -1, -1,			 -1, -1, {ACT_WARN} },
-{RSP_LAST}
+	{RSP_ERROR,	 -1,  -1, -1,			 -1, -1, {ACT_ERROR} },
+	{RSP_ZCAU,	 -1,  -1, -1,			 -1, -1, {ACT_ZCAU} },
+	{RSP_NONE,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+	{RSP_ANY,	 -1,  -1, -1,			 -1, -1, {ACT_WARN} },
+	{RSP_LAST}
 };
 
 /* 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring,
@@ -261,91 +261,91 @@ struct reply_t gigaset_tab_cid[] =
  * action, command */
 
 /* dial */
-{EV_DIAL,	 -1,  -1, -1,			 -1, -1, {ACT_DIAL} },
-{RSP_INIT,	  0,   0, SEQ_DIAL,		601,  5, {ACT_CMD+AT_BC} },
-{RSP_OK,	601, 601, -1,			603,  5, {ACT_CMD+AT_PROTO} },
-{RSP_OK,	603, 603, -1,			604,  5, {ACT_CMD+AT_TYPE} },
-{RSP_OK,	604, 604, -1,			605,  5, {ACT_CMD+AT_MSN} },
-{RSP_NULL,	605, 605, -1,			606,  5, {ACT_CMD+AT_CLIP} },
-{RSP_OK,	605, 605, -1,			606,  5, {ACT_CMD+AT_CLIP} },
-{RSP_NULL,	606, 606, -1,			607,  5, {ACT_CMD+AT_ISO} },
-{RSP_OK,	606, 606, -1,			607,  5, {ACT_CMD+AT_ISO} },
-{RSP_OK,	607, 607, -1,			608,  5, {0},	"+VLS=17\r"},
-{RSP_OK,	608, 608, -1,			609, -1},
-{RSP_ZSAU,	609, 609, ZSAU_PROCEEDING,	610,  5, {ACT_CMD+AT_DIAL} },
-{RSP_OK,	610, 610, -1,			650,  0, {ACT_DIALING} },
-
-{RSP_ERROR,	601, 610, -1,			  0,  0, {ACT_ABORTDIAL} },
-{EV_TIMEOUT,	601, 610, -1,			  0,  0, {ACT_ABORTDIAL} },
+	{EV_DIAL,	 -1,  -1, -1,			 -1, -1, {ACT_DIAL} },
+	{RSP_INIT,	  0,   0, SEQ_DIAL,		601,  5, {ACT_CMD + AT_BC} },
+	{RSP_OK,	601, 601, -1,			603,  5, {ACT_CMD + AT_PROTO} },
+	{RSP_OK,	603, 603, -1,			604,  5, {ACT_CMD + AT_TYPE} },
+	{RSP_OK,	604, 604, -1,			605,  5, {ACT_CMD + AT_MSN} },
+	{RSP_NULL,	605, 605, -1,			606,  5, {ACT_CMD + AT_CLIP} },
+	{RSP_OK,	605, 605, -1,			606,  5, {ACT_CMD + AT_CLIP} },
+	{RSP_NULL,	606, 606, -1,			607,  5, {ACT_CMD + AT_ISO} },
+	{RSP_OK,	606, 606, -1,			607,  5, {ACT_CMD + AT_ISO} },
+	{RSP_OK,	607, 607, -1,			608,  5, {0},	"+VLS=17\r"},
+	{RSP_OK,	608, 608, -1,			609, -1},
+	{RSP_ZSAU,	609, 609, ZSAU_PROCEEDING,	610,  5, {ACT_CMD + AT_DIAL} },
+	{RSP_OK,	610, 610, -1,			650,  0, {ACT_DIALING} },
+
+	{RSP_ERROR,	601, 610, -1,			  0,  0, {ACT_ABORTDIAL} },
+	{EV_TIMEOUT,	601, 610, -1,			  0,  0, {ACT_ABORTDIAL} },
 
 /* optional dialing responses */
-{EV_BC_OPEN,	650, 650, -1,			651, -1},
-{RSP_ZVLS,	609, 651, 17,			 -1, -1, {ACT_DEBUG} },
-{RSP_ZCTP,	610, 651, -1,			 -1, -1, {ACT_DEBUG} },
-{RSP_ZCPN,	610, 651, -1,			 -1, -1, {ACT_DEBUG} },
-{RSP_ZSAU,	650, 651, ZSAU_CALL_DELIVERED,	 -1, -1, {ACT_DEBUG} },
+	{EV_BC_OPEN,	650, 650, -1,			651, -1},
+	{RSP_ZVLS,	609, 651, 17,			 -1, -1, {ACT_DEBUG} },
+	{RSP_ZCTP,	610, 651, -1,			 -1, -1, {ACT_DEBUG} },
+	{RSP_ZCPN,	610, 651, -1,			 -1, -1, {ACT_DEBUG} },
+	{RSP_ZSAU,	650, 651, ZSAU_CALL_DELIVERED,	 -1, -1, {ACT_DEBUG} },
 
 /* connect */
-{RSP_ZSAU,	650, 650, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT} },
-{RSP_ZSAU,	651, 651, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT,
-							  ACT_NOTIFY_BC_UP} },
-{RSP_ZSAU,	750, 750, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT} },
-{RSP_ZSAU,	751, 751, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT,
-							  ACT_NOTIFY_BC_UP} },
-{EV_BC_OPEN,	800, 800, -1,			800, -1, {ACT_NOTIFY_BC_UP} },
+	{RSP_ZSAU,	650, 650, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT} },
+	{RSP_ZSAU,	651, 651, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT,
+								  ACT_NOTIFY_BC_UP} },
+	{RSP_ZSAU,	750, 750, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT} },
+	{RSP_ZSAU,	751, 751, ZSAU_ACTIVE,		800, -1, {ACT_CONNECT,
+								  ACT_NOTIFY_BC_UP} },
+	{EV_BC_OPEN,	800, 800, -1,			800, -1, {ACT_NOTIFY_BC_UP} },
 
 /* remote hangup */
-{RSP_ZSAU,	650, 651, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEREJECT} },
-{RSP_ZSAU,	750, 751, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEHUP} },
-{RSP_ZSAU,	800, 800, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEHUP} },
+	{RSP_ZSAU,	650, 651, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEREJECT} },
+	{RSP_ZSAU,	750, 751, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEHUP} },
+	{RSP_ZSAU,	800, 800, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_REMOTEHUP} },
 
 /* hangup */
-{EV_HUP,	 -1,  -1, -1,			 -1, -1, {ACT_HUP} },
-{RSP_INIT,	 -1,  -1, SEQ_HUP,		401,  5, {0},	"+VLS=0\r"},
-{RSP_OK,	401, 401, -1,			402,  5},
-{RSP_ZVLS,	402, 402,  0,			403,  5},
-{RSP_ZSAU,	403, 403, ZSAU_DISCONNECT_REQ,	 -1, -1, {ACT_DEBUG} },
-{RSP_ZSAU,	403, 403, ZSAU_NULL,		  0,  0, {ACT_DISCONNECT} },
-{RSP_NODEV,	401, 403, -1,			  0,  0, {ACT_FAKEHUP} },
-{RSP_ERROR,	401, 401, -1,			  0,  0, {ACT_ABORTHUP} },
-{EV_TIMEOUT,	401, 403, -1,			  0,  0, {ACT_ABORTHUP} },
-
-{EV_BC_CLOSED,	  0,   0, -1,			  0, -1, {ACT_NOTIFY_BC_DOWN} },
+	{EV_HUP,	 -1,  -1, -1,			 -1, -1, {ACT_HUP} },
+	{RSP_INIT,	 -1,  -1, SEQ_HUP,		401,  5, {0},	"+VLS=0\r"},
+	{RSP_OK,	401, 401, -1,			402,  5},
+	{RSP_ZVLS,	402, 402,  0,			403,  5},
+	{RSP_ZSAU,	403, 403, ZSAU_DISCONNECT_REQ,	 -1, -1, {ACT_DEBUG} },
+	{RSP_ZSAU,	403, 403, ZSAU_NULL,		  0,  0, {ACT_DISCONNECT} },
+	{RSP_NODEV,	401, 403, -1,			  0,  0, {ACT_FAKEHUP} },
+	{RSP_ERROR,	401, 401, -1,			  0,  0, {ACT_ABORTHUP} },
+	{EV_TIMEOUT,	401, 403, -1,			  0,  0, {ACT_ABORTHUP} },
+
+	{EV_BC_CLOSED,	  0,   0, -1,			  0, -1, {ACT_NOTIFY_BC_DOWN} },
 
 /* ring */
-{RSP_ZBC,	700, 700, -1,			 -1, -1, {0} },
-{RSP_ZHLC,	700, 700, -1,			 -1, -1, {0} },
-{RSP_NMBR,	700, 700, -1,			 -1, -1, {0} },
-{RSP_ZCPN,	700, 700, -1,			 -1, -1, {0} },
-{RSP_ZCTP,	700, 700, -1,			 -1, -1, {0} },
-{EV_TIMEOUT,	700, 700, -1,			720, 720, {ACT_ICALL} },
-{EV_BC_CLOSED,	720, 720, -1,			  0, -1, {ACT_NOTIFY_BC_DOWN} },
+	{RSP_ZBC,	700, 700, -1,			 -1, -1, {0} },
+	{RSP_ZHLC,	700, 700, -1,			 -1, -1, {0} },
+	{RSP_NMBR,	700, 700, -1,			 -1, -1, {0} },
+	{RSP_ZCPN,	700, 700, -1,			 -1, -1, {0} },
+	{RSP_ZCTP,	700, 700, -1,			 -1, -1, {0} },
+	{EV_TIMEOUT,	700, 700, -1,			720, 720, {ACT_ICALL} },
+	{EV_BC_CLOSED,	720, 720, -1,			  0, -1, {ACT_NOTIFY_BC_DOWN} },
 
 /*accept icall*/
-{EV_ACCEPT,	 -1,  -1, -1,			 -1, -1, {ACT_ACCEPT} },
-{RSP_INIT,	720, 720, SEQ_ACCEPT,		721,  5, {ACT_CMD+AT_PROTO} },
-{RSP_OK,	721, 721, -1,			722,  5, {ACT_CMD+AT_ISO} },
-{RSP_OK,	722, 722, -1,			723,  5, {0},	"+VLS=17\r"},
-{RSP_OK,	723, 723, -1,			724,  5, {0} },
-{RSP_ZVLS,	724, 724, 17,			750, 50, {ACT_ACCEPTED} },
-{RSP_ERROR,	721, 729, -1,			  0,  0, {ACT_ABORTACCEPT} },
-{EV_TIMEOUT,	721, 729, -1,			  0,  0, {ACT_ABORTACCEPT} },
-{RSP_ZSAU,	700, 729, ZSAU_NULL,		  0,  0, {ACT_ABORTACCEPT} },
-{RSP_ZSAU,	700, 729, ZSAU_ACTIVE,		  0,  0, {ACT_ABORTACCEPT} },
-{RSP_ZSAU,	700, 729, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_ABORTACCEPT} },
-
-{EV_BC_OPEN,	750, 750, -1,			751, -1},
-{EV_TIMEOUT,	750, 751, -1,			  0,  0, {ACT_CONNTIMEOUT} },
+	{EV_ACCEPT,	 -1,  -1, -1,			 -1, -1, {ACT_ACCEPT} },
+	{RSP_INIT,	720, 720, SEQ_ACCEPT,		721,  5, {ACT_CMD + AT_PROTO} },
+	{RSP_OK,	721, 721, -1,			722,  5, {ACT_CMD + AT_ISO} },
+	{RSP_OK,	722, 722, -1,			723,  5, {0},	"+VLS=17\r"},
+	{RSP_OK,	723, 723, -1,			724,  5, {0} },
+	{RSP_ZVLS,	724, 724, 17,			750, 50, {ACT_ACCEPTED} },
+	{RSP_ERROR,	721, 729, -1,			  0,  0, {ACT_ABORTACCEPT} },
+	{EV_TIMEOUT,	721, 729, -1,			  0,  0, {ACT_ABORTACCEPT} },
+	{RSP_ZSAU,	700, 729, ZSAU_NULL,		  0,  0, {ACT_ABORTACCEPT} },
+	{RSP_ZSAU,	700, 729, ZSAU_ACTIVE,		  0,  0, {ACT_ABORTACCEPT} },
+	{RSP_ZSAU,	700, 729, ZSAU_DISCONNECT_IND,	  0,  0, {ACT_ABORTACCEPT} },
+
+	{EV_BC_OPEN,	750, 750, -1,			751, -1},
+	{EV_TIMEOUT,	750, 751, -1,			  0,  0, {ACT_CONNTIMEOUT} },
 
 /* B channel closed (general case) */
-{EV_BC_CLOSED,	 -1,  -1, -1,			 -1, -1, {ACT_NOTIFY_BC_DOWN} },
+	{EV_BC_CLOSED,	 -1,  -1, -1,			 -1, -1, {ACT_NOTIFY_BC_DOWN} },
 
 /* misc. */
-{RSP_ZCON,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
-{RSP_ZCAU,	 -1,  -1, -1,			 -1, -1, {ACT_ZCAU} },
-{RSP_NONE,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
-{RSP_ANY,	 -1,  -1, -1,			 -1, -1, {ACT_WARN} },
-{RSP_LAST}
+	{RSP_ZCON,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+	{RSP_ZCAU,	 -1,  -1, -1,			 -1, -1, {ACT_ZCAU} },
+	{RSP_NONE,	 -1,  -1, -1,			 -1, -1, {ACT_DEBUG} },
+	{RSP_ANY,	 -1,  -1, -1,			 -1, -1, {ACT_WARN} },
+	{RSP_LAST}
 };
 
 
@@ -453,7 +453,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
 			case '=':
 				if (params > MAX_REC_PARAMS) {
 					dev_warn(cs->dev,
-					   "too many parameters in response\n");
+						 "too many parameters in response\n");
 					/* need last parameter (might be CID) */
 					params--;
 				}
@@ -461,7 +461,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
 			}
 
 		rawstring = 0;
-		cid = params > 1 ? cid_of_response(argv[params-1]) : 0;
+		cid = params > 1 ? cid_of_response(argv[params - 1]) : 0;
 		if (cid < 0) {
 			gigaset_add_event(cs, &cs->at_state, RSP_INVAL,
 					  NULL, 0, NULL);
@@ -550,7 +550,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
 			event->parameter = zr->code;
 			if (!zr->str)
 				dev_warn(cs->dev,
-					"%s: unknown parameter %s after ZSAU\n",
+					 "%s: unknown parameter %s after ZSAU\n",
 					 __func__, argv[curarg]);
 			++curarg;
 			break;
@@ -648,8 +648,8 @@ static void disconnect(struct at_state_t **at_state_p)
 static inline struct at_state_t *get_free_channel(struct cardstate *cs,
 						  int cid)
 /* cids: >0: siemens-cid
-	  0: without cid
-	 -1: no cid assigned yet
+   0: without cid
+   -1: no cid assigned yet
 */
 {
 	unsigned long flags;
@@ -722,12 +722,12 @@ static void send_command(struct cardstate *cs, const char *cmd, int cid,
 	}
 	if (cid > 0 && cid <= 65535)
 		cb->len = snprintf(cb->buf, buflen,
-				  dle ? "\020(AT%d%s\020)" : "AT%d%s",
-				  cid, cmd);
+				   dle ? "\020(AT%d%s\020)" : "AT%d%s",
+				   cid, cmd);
 	else
 		cb->len = snprintf(cb->buf, buflen,
-				  dle ? "\020(AT%s\020)" : "AT%s",
-				  cmd);
+				   dle ? "\020(AT%s\020)" : "AT%s",
+				   cmd);
 	cb->offset = 0;
 	cb->next = NULL;
 	cb->wake_tasklet = NULL;
@@ -790,7 +790,7 @@ static void bchannel_up(struct bc_state *bcs)
 }
 
 static void start_dial(struct at_state_t *at_state, void *data,
-			unsigned seq_index)
+		       unsigned seq_index)
 {
 	struct bc_state *bcs = at_state->bcs;
 	struct cardstate *cs = at_state->cs;
@@ -937,10 +937,10 @@ static int reinit_and_retry(struct cardstate *cs, int channel)
 
 	if (channel < 0)
 		dev_warn(cs->dev,
-		    "Could not enter cid mode. Reinit device and try again.\n");
+			 "Could not enter cid mode. Reinit device and try again.\n");
 	else {
 		dev_warn(cs->dev,
-		    "Could not get a call id. Reinit device and try again.\n");
+			 "Could not get a call id. Reinit device and try again.\n");
 		cs->bcs[channel].at_state.pending_commands |= PC_CID;
 	}
 	schedule_init(cs, MS_INIT);
@@ -1155,7 +1155,7 @@ static void do_action(int action, struct cardstate *cs,
 		at_state2 = get_free_channel(cs, ev->parameter);
 		if (!at_state2) {
 			dev_warn(cs->dev,
-			"RING ignored: could not allocate channel structure\n");
+				 "RING ignored: could not allocate channel structure\n");
 			break;
 		}
 
@@ -1372,7 +1372,7 @@ static void do_action(int action, struct cardstate *cs,
 			 ev->parameter, at_state->ConState);
 		break;
 
-	/* events from the LL */
+		/* events from the LL */
 	case ACT_DIAL:
 		start_dial(at_state, ev->ptr, ev->parameter);
 		break;
@@ -1385,7 +1385,7 @@ static void do_action(int action, struct cardstate *cs,
 		cs->commands_pending = 1;
 		break;
 
-	/* hotplug events */
+		/* hotplug events */
 	case ACT_STOP:
 		do_stop(cs);
 		break;
@@ -1393,7 +1393,7 @@ static void do_action(int action, struct cardstate *cs,
 		do_start(cs);
 		break;
 
-	/* events from the interface */
+		/* events from the interface */
 	case ACT_IF_LOCK:
 		cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs);
 		cs->waiting = 0;
@@ -1412,7 +1412,7 @@ static void do_action(int action, struct cardstate *cs,
 		wake_up(&cs->waitqueue);
 		break;
 
-	/* events from the proc file system */
+		/* events from the proc file system */
 	case ACT_PROC_CIDMODE:
 		spin_lock_irqsave(&cs->lock, flags);
 		if (ev->parameter != cs->cidmode) {
@@ -1431,7 +1431,7 @@ static void do_action(int action, struct cardstate *cs,
 		wake_up(&cs->waitqueue);
 		break;
 
-	/* events from the hardware drivers */
+		/* events from the hardware drivers */
 	case ACT_NOTIFY_BC_DOWN:
 		bchannel_down(bcs);
 		break;
@@ -1533,15 +1533,15 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
 		if (rcode == RSP_LAST) {
 			/* found nothing...*/
 			dev_warn(cs->dev, "%s: rcode=RSP_LAST: "
-					"resp_code %d in ConState %d!\n",
+				 "resp_code %d in ConState %d!\n",
 				 __func__, ev->type, at_state->ConState);
 			return;
 		}
 		if ((rcode == RSP_ANY || rcode == ev->type)
-		  && ((int) at_state->ConState >= rep->min_ConState)
-		  && (rep->max_ConState < 0
-		      || (int) at_state->ConState <= rep->max_ConState)
-		  && (rep->parameter < 0 || rep->parameter == ev->parameter))
+		    && ((int) at_state->ConState >= rep->min_ConState)
+		    && (rep->max_ConState < 0
+			|| (int) at_state->ConState <= rep->max_ConState)
+		    && (rep->parameter < 0 || rep->parameter == ev->parameter))
 			break;
 	}
 
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 212efaf..8fad99e 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -91,11 +91,11 @@ enum debuglevel {
 
 #ifdef CONFIG_GIGASET_DEBUG
 
-#define gig_dbg(level, format, arg...) \
-	do { \
+#define gig_dbg(level, format, arg...)					\
+	do {								\
 		if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \
 			printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \
-			       ## arg); \
+			       ## arg);					\
 	} while (0)
 #define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ)
 
@@ -164,7 +164,7 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
 #define BAS_CORRFRAMES	4	/* flow control multiplicator */
 
 #define BAS_INBUFSIZE	(BAS_MAXFRAME * BAS_NUMFRAMES)
-					/* size of isoc in buf per URB */
+/* size of isoc in buf per URB */
 #define BAS_OUTBUFSIZE	4096		/* size of common isoc out buffer */
 #define BAS_OUTBUFPAD	BAS_MAXFRAME	/* size of pad area for isoc out buf */
 
@@ -473,17 +473,17 @@ struct cardstate {
 	int commands_pending;		/* flag(s) in xxx.commands_pending have
 					   been set */
 	struct tasklet_struct event_tasklet;
-					/* tasklet for serializing AT commands.
-					 * Scheduled
-					 *   -> for modem reponses (and
-					 *      incoming data for M10x)
-					 *   -> on timeout
-					 *   -> after setting bits in
-					 *      xxx.at_state.pending_command
-					 *      (e.g. command from LL) */
+	/* tasklet for serializing AT commands.
+	 * Scheduled
+	 *   -> for modem reponses (and
+	 *      incoming data for M10x)
+	 *   -> on timeout
+	 *   -> after setting bits in
+	 *      xxx.at_state.pending_command
+	 *      (e.g. command from LL) */
 	struct tasklet_struct write_tasklet;
-					/* tasklet for serial output
-					 * (not used in base driver) */
+	/* tasklet for serial output
+	 * (not used in base driver) */
 
 	/* event queue */
 	struct event_t events[MAX_EVENTS];
@@ -491,7 +491,7 @@ struct cardstate {
 	spinlock_t ev_lock;
 
 	/* current modem response */
-	unsigned char respdata[MAX_RESP_SIZE+1];
+	unsigned char respdata[MAX_RESP_SIZE + 1];
 	unsigned cbytes;
 
 	/* private data of hardware drivers */
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 1793ba1..0f13eb1 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -243,7 +243,7 @@ static int command_from_LL(isdn_ctrl *cntrl)
 		dev_kfree_skb(bcs->rx_skb);
 		gigaset_new_rx_skb(bcs);
 
-		commands = kzalloc(AT_NUM*(sizeof *commands), GFP_ATOMIC);
+		commands = kzalloc(AT_NUM * (sizeof *commands), GFP_ATOMIC);
 		if (!commands) {
 			gigaset_free_channel(bcs);
 			dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n");
@@ -261,7 +261,7 @@ static int command_from_LL(isdn_ctrl *cntrl)
 			if (!commands[AT_TYPE])
 				goto oom;
 			snprintf(commands[AT_DIAL], l,
-				 "D%s\r", cntrl->parm.setup.phone+2);
+				 "D%s\r", cntrl->parm.setup.phone + 2);
 		} else {
 			commands[AT_TYPE] = kstrdup("^SCTP=1\r", GFP_ATOMIC);
 			if (!commands[AT_TYPE])
@@ -482,7 +482,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 		response.parm.setup.si2 = 2;
 	} else {
 		dev_warn(cs->dev, "RING ignored - unsupported BC %s\n",
-		     at_state->str_var[STR_ZBC]);
+			 at_state->str_var[STR_ZBC]);
 		return ICALL_IGNORE;
 	}
 	if (at_state->str_var[STR_NMBR]) {
@@ -518,7 +518,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
 		return ICALL_REJECT;
 	case 3:	/* incomplete */
 		dev_warn(cs->dev,
-		       "LL requested unsupported feature: Incomplete Number\n");
+			 "LL requested unsupported feature: Incomplete Number\n");
 		return ICALL_IGNORE;
 	case 4:	/* proceeding */
 		/* Gigaset will send ALERTING anyway.
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index ee0a549..da2486e 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -33,10 +33,10 @@ static int if_lock(struct cardstate *cs, int *arg)
 	}
 
 	if (!cmd && cs->mstate == MS_LOCKED && cs->connected) {
-		cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS);
+		cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR | TIOCM_RTS);
 		cs->ops->baud_rate(cs, B115200);
 		cs->ops->set_line_ctrl(cs, CS8);
-		cs->control_state = TIOCM_DTR|TIOCM_RTS;
+		cs->control_state = TIOCM_DTR | TIOCM_RTS;
 	}
 
 	cs->waiting = 1;
@@ -252,17 +252,17 @@ static int if_ioctl(struct tty_struct *tty,
 			break;
 		case GIGASET_BRKCHARS:
 			retval = copy_from_user(&buf,
-					(const unsigned char __user *) arg, 6)
+						(const unsigned char __user *) arg, 6)
 				? -EFAULT : 0;
 			if (retval >= 0) {
 				gigaset_dbg_buffer(DEBUG_IF, "GIGASET_BRKCHARS",
-						6, (const unsigned char *) arg);
+						   6, (const unsigned char *) arg);
 				retval = cs->ops->brkchars(cs, buf);
 			}
 			break;
 		case GIGASET_VERSION:
 			retval = copy_from_user(version,
-					(unsigned __user *) arg, sizeof version)
+						(unsigned __user *) arg, sizeof version)
 				? -EFAULT : 0;
 			if (retval >= 0)
 				retval = if_version(cs, version);
@@ -299,7 +299,7 @@ static int if_tiocmget(struct tty_struct *tty)
 	if (mutex_lock_interruptible(&cs->mutex))
 		return -ERESTARTSYS;
 
-	retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR);
+	retval = cs->control_state & (TIOCM_RTS | TIOCM_DTR);
 
 	mutex_unlock(&cs->mutex);
 
@@ -329,7 +329,7 @@ static int if_tiocmset(struct tty_struct *tty,
 		gig_dbg(DEBUG_IF, "not connected");
 		retval = -ENODEV;
 	} else {
-		mc = (cs->control_state | set) & ~clear & (TIOCM_RTS|TIOCM_DTR);
+		mc = (cs->control_state | set) & ~clear & (TIOCM_RTS | TIOCM_DTR);
 		retval = cs->ops->set_modem_ctrl(cs, cs->control_state, mc);
 		cs->control_state = mc;
 	}
@@ -680,9 +680,9 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
 		goto enomem;
 
 	tty->magic =		TTY_DRIVER_MAGIC,
-	tty->type =		TTY_DRIVER_TYPE_SERIAL,
-	tty->subtype =		SERIAL_TYPE_NORMAL,
-	tty->flags =		TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+		tty->type =		TTY_DRIVER_TYPE_SERIAL,
+		tty->subtype =		SERIAL_TYPE_NORMAL,
+		tty->flags =		TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
 
 	tty->driver_name =	procname;
 	tty->name =		devname;
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index f39ccdf..a351c16 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -250,94 +250,94 @@ static inline void dump_bytes(enum debuglevel level, const char *tag,
  */
 static const u16 stufftab[5 * 256] = {
 /* previous 1s = 0: */
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f,
- 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf,
- 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
- 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
+	0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+	0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
+	0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
+	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x205f,
+	0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
+	0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x209f,
+	0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
+	0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20df,
+	0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x048f,
+	0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x251f,
+	0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x04af,
+	0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x255f,
+	0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x08cf,
+	0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x299f,
+	0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
+	0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
 
 /* previous 1s = 1: */
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f,
- 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f,
- 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
- 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
+	0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
+	0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
+	0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
+	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x206f,
+	0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x208f,
+	0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20af,
+	0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20cf,
+	0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20ef,
+	0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x250f,
+	0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x252f,
+	0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x04a7, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x254f,
+	0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x04b7, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x256f,
+	0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x08c7, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x298f,
+	0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x08d7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29af,
+	0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
+	0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
 
 /* previous 1s = 2: */
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
- 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
- 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
- 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097,
- 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7,
- 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7,
- 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7,
- 0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517,
- 0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537,
- 0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557,
- 0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577,
- 0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997,
- 0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
- 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
+	0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
+	0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
+	0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
+	0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x2067, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x203e, 0x2077,
+	0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x2087, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x2097,
+	0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x20a7, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x20b7,
+	0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x20c7, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x20d7,
+	0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x20e7, 0x0078, 0x0079, 0x007a, 0x007b, 0x207c, 0x207d, 0x20be, 0x20f7,
+	0x0480, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x2507, 0x0488, 0x0489, 0x048a, 0x048b, 0x048c, 0x048d, 0x048e, 0x2517,
+	0x0490, 0x0491, 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x2527, 0x0498, 0x0499, 0x049a, 0x049b, 0x049c, 0x049d, 0x049e, 0x2537,
+	0x04a0, 0x04a1, 0x04a2, 0x04a3, 0x04a4, 0x04a5, 0x04a6, 0x2547, 0x04a8, 0x04a9, 0x04aa, 0x04ab, 0x04ac, 0x04ad, 0x04ae, 0x2557,
+	0x04b0, 0x04b1, 0x04b2, 0x04b3, 0x04b4, 0x04b5, 0x04b6, 0x2567, 0x04b8, 0x04b9, 0x04ba, 0x04bb, 0x04bc, 0x04bd, 0x253e, 0x2577,
+	0x08c0, 0x08c1, 0x08c2, 0x08c3, 0x08c4, 0x08c5, 0x08c6, 0x2987, 0x08c8, 0x08c9, 0x08ca, 0x08cb, 0x08cc, 0x08cd, 0x08ce, 0x2997,
+	0x08d0, 0x08d1, 0x08d2, 0x08d3, 0x08d4, 0x08d5, 0x08d6, 0x29a7, 0x08d8, 0x08d9, 0x08da, 0x08db, 0x08dc, 0x08dd, 0x08de, 0x29b7,
+	0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
+	0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
 
 /* previous 1s = 3: */
- 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
- 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
- 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
- 0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b,
- 0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b,
- 0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb,
- 0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db,
- 0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb,
- 0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b,
- 0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b,
- 0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b,
- 0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b,
- 0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b,
- 0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb,
- 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
- 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
+	0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
+	0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
+	0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
+	0x0030, 0x0031, 0x0032, 0x2063, 0x0034, 0x0035, 0x0036, 0x206b, 0x0038, 0x0039, 0x003a, 0x2073, 0x003c, 0x003d, 0x203e, 0x207b,
+	0x0040, 0x0041, 0x0042, 0x2083, 0x0044, 0x0045, 0x0046, 0x208b, 0x0048, 0x0049, 0x004a, 0x2093, 0x004c, 0x004d, 0x004e, 0x209b,
+	0x0050, 0x0051, 0x0052, 0x20a3, 0x0054, 0x0055, 0x0056, 0x20ab, 0x0058, 0x0059, 0x005a, 0x20b3, 0x005c, 0x005d, 0x005e, 0x20bb,
+	0x0060, 0x0061, 0x0062, 0x20c3, 0x0064, 0x0065, 0x0066, 0x20cb, 0x0068, 0x0069, 0x006a, 0x20d3, 0x006c, 0x006d, 0x006e, 0x20db,
+	0x0070, 0x0071, 0x0072, 0x20e3, 0x0074, 0x0075, 0x0076, 0x20eb, 0x0078, 0x0079, 0x007a, 0x20f3, 0x207c, 0x207d, 0x20be, 0x40fb,
+	0x0480, 0x0481, 0x0482, 0x2503, 0x0484, 0x0485, 0x0486, 0x250b, 0x0488, 0x0489, 0x048a, 0x2513, 0x048c, 0x048d, 0x048e, 0x251b,
+	0x0490, 0x0491, 0x0492, 0x2523, 0x0494, 0x0495, 0x0496, 0x252b, 0x0498, 0x0499, 0x049a, 0x2533, 0x049c, 0x049d, 0x049e, 0x253b,
+	0x04a0, 0x04a1, 0x04a2, 0x2543, 0x04a4, 0x04a5, 0x04a6, 0x254b, 0x04a8, 0x04a9, 0x04aa, 0x2553, 0x04ac, 0x04ad, 0x04ae, 0x255b,
+	0x04b0, 0x04b1, 0x04b2, 0x2563, 0x04b4, 0x04b5, 0x04b6, 0x256b, 0x04b8, 0x04b9, 0x04ba, 0x2573, 0x04bc, 0x04bd, 0x253e, 0x257b,
+	0x08c0, 0x08c1, 0x08c2, 0x2983, 0x08c4, 0x08c5, 0x08c6, 0x298b, 0x08c8, 0x08c9, 0x08ca, 0x2993, 0x08cc, 0x08cd, 0x08ce, 0x299b,
+	0x08d0, 0x08d1, 0x08d2, 0x29a3, 0x08d4, 0x08d5, 0x08d6, 0x29ab, 0x08d8, 0x08d9, 0x08da, 0x29b3, 0x08dc, 0x08dd, 0x08de, 0x29bb,
+	0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
+	0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
 
 /* previous 1s = 4: */
- 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
- 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
- 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
- 0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d,
- 0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d,
- 0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd,
- 0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd,
- 0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d,
- 0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d,
- 0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d,
- 0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d,
- 0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d,
- 0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d,
- 0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd,
- 0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd,
- 0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d
+	0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
+	0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
+	0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
+	0x0030, 0x2061, 0x0032, 0x2065, 0x0034, 0x2069, 0x0036, 0x206d, 0x0038, 0x2071, 0x003a, 0x2075, 0x003c, 0x2079, 0x203e, 0x407d,
+	0x0040, 0x2081, 0x0042, 0x2085, 0x0044, 0x2089, 0x0046, 0x208d, 0x0048, 0x2091, 0x004a, 0x2095, 0x004c, 0x2099, 0x004e, 0x209d,
+	0x0050, 0x20a1, 0x0052, 0x20a5, 0x0054, 0x20a9, 0x0056, 0x20ad, 0x0058, 0x20b1, 0x005a, 0x20b5, 0x005c, 0x20b9, 0x005e, 0x20bd,
+	0x0060, 0x20c1, 0x0062, 0x20c5, 0x0064, 0x20c9, 0x0066, 0x20cd, 0x0068, 0x20d1, 0x006a, 0x20d5, 0x006c, 0x20d9, 0x006e, 0x20dd,
+	0x0070, 0x20e1, 0x0072, 0x20e5, 0x0074, 0x20e9, 0x0076, 0x20ed, 0x0078, 0x20f1, 0x007a, 0x20f5, 0x207c, 0x40f9, 0x20be, 0x417d,
+	0x0480, 0x2501, 0x0482, 0x2505, 0x0484, 0x2509, 0x0486, 0x250d, 0x0488, 0x2511, 0x048a, 0x2515, 0x048c, 0x2519, 0x048e, 0x251d,
+	0x0490, 0x2521, 0x0492, 0x2525, 0x0494, 0x2529, 0x0496, 0x252d, 0x0498, 0x2531, 0x049a, 0x2535, 0x049c, 0x2539, 0x049e, 0x253d,
+	0x04a0, 0x2541, 0x04a2, 0x2545, 0x04a4, 0x2549, 0x04a6, 0x254d, 0x04a8, 0x2551, 0x04aa, 0x2555, 0x04ac, 0x2559, 0x04ae, 0x255d,
+	0x04b0, 0x2561, 0x04b2, 0x2565, 0x04b4, 0x2569, 0x04b6, 0x256d, 0x04b8, 0x2571, 0x04ba, 0x2575, 0x04bc, 0x2579, 0x253e, 0x467d,
+	0x08c0, 0x2981, 0x08c2, 0x2985, 0x08c4, 0x2989, 0x08c6, 0x298d, 0x08c8, 0x2991, 0x08ca, 0x2995, 0x08cc, 0x2999, 0x08ce, 0x299d,
+	0x08d0, 0x29a1, 0x08d2, 0x29a5, 0x08d4, 0x29a9, 0x08d6, 0x29ad, 0x08d8, 0x29b1, 0x08da, 0x29b5, 0x08dc, 0x29b9, 0x08de, 0x29bd,
+	0x0ce0, 0x2dc1, 0x0ce2, 0x2dc5, 0x0ce4, 0x2dc9, 0x0ce6, 0x2dcd, 0x0ce8, 0x2dd1, 0x0cea, 0x2dd5, 0x0cec, 0x2dd9, 0x0cee, 0x2ddd,
+	0x10f0, 0x31e1, 0x10f2, 0x31e5, 0x10f4, 0x31e9, 0x10f6, 0x31ed, 0x20f8, 0x41f1, 0x20fa, 0x41f5, 0x257c, 0x46f9, 0x29be, 0x4b7d
 };
 
 /* hdlc_bitstuff_byte
@@ -598,22 +598,22 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
  *        bit 7 set if there are 5 or more "interior" consecutive '1' bits
  */
 static const unsigned char bitcounts[256] = {
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
-  0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,
-  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
-  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,
-  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
-  0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,
-  0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,
-  0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,
-  0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,
-  0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x80, 0x06,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
+	0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x80, 0x81, 0x80, 0x07,
+	0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
+	0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x15,
+	0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x14,
+	0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x10, 0x13, 0x10, 0x11, 0x10, 0x12, 0x10, 0x11, 0x90, 0x16,
+	0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x24,
+	0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x23, 0x20, 0x21, 0x20, 0x22, 0x20, 0x21, 0x20, 0x25,
+	0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x31, 0x30, 0x32, 0x30, 0x31, 0x30, 0x34,
+	0x40, 0x41, 0x40, 0x42, 0x40, 0x41, 0x40, 0x43, 0x50, 0x51, 0x50, 0x52, 0x60, 0x61, 0x70, 0x78
 };
 
 /* hdlc_unpack
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index b943efb..e3f9d0f 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -35,7 +35,7 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
 		if (!isspace(*end++))
 			return -EINVAL;
 	if (value < 0 || value > 1)
-			return -EINVAL;
+		return -EINVAL;
 
 	if (mutex_lock_interruptible(&cs->mutex))
 		return -ERESTARTSYS;
@@ -56,7 +56,7 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
-static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode);
+static DEVICE_ATTR(cidmode, S_IRUGO | S_IWUSR, show_cidmode, set_cidmode);
 
 /* free sysfs for device */
 void gigaset_free_dev_sysfs(struct cardstate *cs)
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 86a5c4f..6f3fd4c 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -246,7 +246,7 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
 	unsigned long flags;
 
 	gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
-				DEBUG_TRANSCMD : DEBUG_LOCKCMD,
+			   DEBUG_TRANSCMD : DEBUG_LOCKCMD,
 			   "CMD Transmit", cb->len, cb->buf);
 
 	spin_lock_irqsave(&cs->cmdlock, flags);
@@ -773,8 +773,8 @@ static int __init ser_gigaset_init(void)
 
 	/* allocate memory for our driver state and initialize it */
 	driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
-					  GIGASET_MODULENAME, GIGASET_DEVNAME,
-					  &ops, THIS_MODULE);
+				    GIGASET_MODULENAME, GIGASET_DEVNAME,
+				    &ops, THIS_MODULE);
 	if (!driver)
 		goto error;
 
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 5e3300d..049da67 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -184,7 +184,7 @@ static int set_value(struct cardstate *cs, u8 req, u16 val)
 		(unsigned)req, (unsigned)val);
 	r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x12, 0x41,
 			    0xf /*?*/, 0, NULL, 0, 2000 /*?*/);
-			    /* no idea what this does */
+	/* no idea what this does */
 	if (r < 0) {
 		dev_err(&udev->dev, "error %d on request 0x12\n", -r);
 		return r;
@@ -365,7 +365,7 @@ static void gigaset_read_int_callback(struct urb *urb)
 			src = cs->hw.usb->rcvbuf;
 			if (unlikely(*src))
 				dev_warn(cs->dev,
-				    "%s: There was no leading 0, but 0x%02x!\n",
+					 "%s: There was no leading 0, but 0x%02x!\n",
 					 __func__, (unsigned) *src);
 			++src; /* skip leading 0x00 */
 			--numbytes;
@@ -465,7 +465,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
 
 			usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
 					  usb_sndbulkpipe(ucs->udev,
-					     ucs->bulk_out_endpointAddr & 0x0f),
+							  ucs->bulk_out_endpointAddr & 0x0f),
 					  cb->buf + cb->offset, count,
 					  gigaset_write_bulk_callback, cs);
 
@@ -499,7 +499,7 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
 	unsigned long flags;
 
 	gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
-			     DEBUG_TRANSCMD : DEBUG_LOCKCMD,
+			   DEBUG_TRANSCMD : DEBUG_LOCKCMD,
 			   "CMD Transmit", cb->len, cb->buf);
 
 	spin_lock_irqsave(&cs->cmdlock, flags);
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 61f516f..44b50cc 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -44,12 +44,12 @@ static void avmcs_detach(struct pcmcia_device *p_dev);
 
 static int avmcs_probe(struct pcmcia_device *p_dev)
 {
-    /* General socket configuration */
-    p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-    p_dev->config_index = 1;
-    p_dev->config_regs = PRESENT_OPTION;
+	/* General socket configuration */
+	p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+	p_dev->config_index = 1;
+	p_dev->config_regs = PRESENT_OPTION;
 
-    return avmcs_config(p_dev);
+	return avmcs_config(p_dev);
 } /* avmcs_attach */
 
 
@@ -69,75 +69,75 @@ static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
 
 static int avmcs_config(struct pcmcia_device *link)
 {
-    int i = -1;
-    char devname[128];
-    int cardtype;
-    int (*addcard)(unsigned int port, unsigned irq);
-
-    devname[0] = 0;
-    if (link->prod_id[1])
-	    strlcpy(devname, link->prod_id[1], sizeof(devname));
-
-    /*
-     * find IO port
-     */
-    if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
-	    return -ENODEV;
-
-    do {
-	if (!link->irq) {
-	    /* undo */
-	    pcmcia_disable_device(link);
-	    break;
-	}
+	int i = -1;
+	char devname[128];
+	int cardtype;
+	int (*addcard)(unsigned int port, unsigned irq);
+
+	devname[0] = 0;
+	if (link->prod_id[1])
+		strlcpy(devname, link->prod_id[1], sizeof(devname));
 
 	/*
-         * configure the PCMCIA socket
-	  */
-	i = pcmcia_enable_device(link);
+	 * find IO port
+	 */
+	if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
+		return -ENODEV;
+
+	do {
+		if (!link->irq) {
+			/* undo */
+			pcmcia_disable_device(link);
+			break;
+		}
+
+		/*
+		 * configure the PCMCIA socket
+		 */
+		i = pcmcia_enable_device(link);
+		if (i != 0) {
+			pcmcia_disable_device(link);
+			break;
+		}
+
+	} while (0);
+
+	if (devname[0]) {
+		char *s = strrchr(devname, ' ');
+		if (!s)
+			s = devname;
+		else s++;
+		if (strcmp("M1", s) == 0) {
+			cardtype = AVM_CARDTYPE_M1;
+		} else if (strcmp("M2", s) == 0) {
+			cardtype = AVM_CARDTYPE_M2;
+		} else {
+			cardtype = AVM_CARDTYPE_B1;
+		}
+	} else
+		cardtype = AVM_CARDTYPE_B1;
+
+	/* If any step failed, release any partially configured state */
 	if (i != 0) {
-	    pcmcia_disable_device(link);
-	    break;
-	}
-
-    } while (0);
-
-    if (devname[0]) {
-	char *s = strrchr(devname, ' ');
-	if (!s)
-	   s = devname;
-	else s++;
-        if (strcmp("M1", s) == 0) {
-           cardtype = AVM_CARDTYPE_M1;
-        } else if (strcmp("M2", s) == 0) {
-           cardtype = AVM_CARDTYPE_M2;
-	} else {
-           cardtype = AVM_CARDTYPE_B1;
+		avmcs_release(link);
+		return -ENODEV;
 	}
-    } else
-        cardtype = AVM_CARDTYPE_B1;
-
-    /* If any step failed, release any partially configured state */
-    if (i != 0) {
-	avmcs_release(link);
-	return -ENODEV;
-    }
 
 
-    switch (cardtype) {
-        case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
-        case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
+	switch (cardtype) {
+	case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
+	case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
 	default:
-        case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
-    }
-    if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) {
-	    dev_err(&link->dev,
-		    "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
-		    (unsigned int) link->resource[0]->start, link->irq);
-	    avmcs_release(link);
-	    return -ENODEV;
-    }
-    return 0;
+	case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
+	}
+	if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) {
+		dev_err(&link->dev,
+			"avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
+			(unsigned int) link->resource[0]->start, link->irq);
+		avmcs_release(link);
+		return -ENODEV;
+	}
+	return 0;
 
 } /* avmcs_config */
 
diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h
index a70e885..c95712d 100644
--- a/drivers/isdn/hardware/avm/avmcard.h
+++ b/drivers/isdn/hardware/avm/avmcard.h
@@ -44,16 +44,16 @@ enum avmcardtype {
 };
 
 typedef struct avmcard_dmabuf {
-    long        size;
-    u8       *dmabuf;
-    dma_addr_t  dmaaddr;
+	long        size;
+	u8       *dmabuf;
+	dma_addr_t  dmaaddr;
 } avmcard_dmabuf;
 
 typedef struct avmcard_dmainfo {
 	u32                recvlen;
-        avmcard_dmabuf       recvbuf;
+	avmcard_dmabuf       recvbuf;
 
-        avmcard_dmabuf       sendbuf;
+	avmcard_dmabuf       sendbuf;
 	struct sk_buff_head  send_queue;
 
 	struct pci_dev      *pcidev;
@@ -61,22 +61,22 @@ typedef struct avmcard_dmainfo {
 
 typedef	struct avmctrl_info {
 	char cardname[32];
-	
+
 	int versionlen;
 	char versionbuf[1024];
 	char *version[AVM_MAXVERSION];
-	
+
 	char infobuf[128];	/* for function procinfo */
-	
+
 	struct avmcard  *card;
 	struct capi_ctr  capi_ctrl;
-	
+
 	struct list_head ncci_head;
 } avmctrl_info;
 
 typedef struct avmcard {
 	char name[32];
-  
+
 	spinlock_t lock;
 	unsigned int port;
 	unsigned irq;
@@ -103,95 +103,95 @@ typedef struct avmcard {
 extern int b1_irq_table[16];
 
 /*
- * LLI Messages to the ISDN-ControllerISDN Controller 
+ * LLI Messages to the ISDN-ControllerISDN Controller
  */
 
 #define	SEND_POLL		0x72	/*
-					   * after load <- RECEIVE_POLL 
+					 * after load <- RECEIVE_POLL
 					 */
 #define SEND_INIT		0x11	/*
-					   * first message <- RECEIVE_INIT
-					   * int32 NumApplications  int32
-					   * NumNCCIs int32 BoardNumber 
+					 * first message <- RECEIVE_INIT
+					 * int32 NumApplications  int32
+					 * NumNCCIs int32 BoardNumber
 					 */
 #define SEND_REGISTER		0x12	/*
-					   * register an application int32
-					   * ApplIDId int32 NumMessages
-					   * int32 NumB3Connections int32
-					   * NumB3Blocks int32 B3Size
-					   * 
-					   * AnzB3Connection != 0 &&
-					   * AnzB3Blocks >= 1 && B3Size >= 1 
+					 * register an application int32
+					 * ApplIDId int32 NumMessages
+					 * int32 NumB3Connections int32
+					 * NumB3Blocks int32 B3Size
+					 *
+					 * AnzB3Connection != 0 &&
+					 * AnzB3Blocks >= 1 && B3Size >= 1
 					 */
 #define SEND_RELEASE		0x14	/*
-					   * deregister an application int32 
-					   * ApplID 
+					 * deregister an application int32
+					 * ApplID
 					 */
 #define SEND_MESSAGE		0x15	/*
-					   * send capi-message int32 length
-					   * capi-data ... 
+					 * send capi-message int32 length
+					 * capi-data ...
 					 */
 #define SEND_DATA_B3_REQ	0x13	/*
-					   * send capi-data-message int32
-					   * MsgLength capi-data ... int32
-					   * B3Length data .... 
+					 * send capi-data-message int32
+					 * MsgLength capi-data ... int32
+					 * B3Length data ....
 					 */
 
 #define SEND_CONFIG		0x21    /*
-                                         */
+					 */
 
 #define SEND_POLLACK		0x73    /* T1 Watchdog */
 
 /*
- * LLI Messages from the ISDN-ControllerISDN Controller 
+ * LLI Messages from the ISDN-ControllerISDN Controller
  */
 
 #define RECEIVE_POLL		0x32	/*
-					   * <- after SEND_POLL 
+					 * <- after SEND_POLL
 					 */
 #define RECEIVE_INIT		0x27	/*
-					   * <- after SEND_INIT int32 length
-					   * byte total length b1struct board 
-					   * driver revision b1struct card
-					   * type b1struct reserved b1struct
-					   * serial number b1struct driver
-					   * capability b1struct d-channel
-					   * protocol b1struct CAPI-2.0
-					   * profile b1struct capi version 
+					 * <- after SEND_INIT int32 length
+					 * byte total length b1struct board
+					 * driver revision b1struct card
+					 * type b1struct reserved b1struct
+					 * serial number b1struct driver
+					 * capability b1struct d-channel
+					 * protocol b1struct CAPI-2.0
+					 * profile b1struct capi version
 					 */
 #define RECEIVE_MESSAGE		0x21	/*
-					   * <- after SEND_MESSAGE int32
-					   * AppllID int32 Length capi-data
-					   * .... 
+					 * <- after SEND_MESSAGE int32
+					 * AppllID int32 Length capi-data
+					 * ....
 					 */
 #define RECEIVE_DATA_B3_IND	0x22	/*
-					   * received data int32 AppllID
-					   * int32 Length capi-data ...
-					   * int32 B3Length data ... 
+					 * received data int32 AppllID
+					 * int32 Length capi-data ...
+					 * int32 B3Length data ...
 					 */
 #define RECEIVE_START		0x23	/*
-					   * Handshake 
+					 * Handshake
 					 */
 #define RECEIVE_STOP		0x24	/*
-					   * Handshake 
+					 * Handshake
 					 */
 #define RECEIVE_NEW_NCCI	0x25	/*
-					   * int32 AppllID int32 NCCI int32
-					   * WindowSize 
+					 * int32 AppllID int32 NCCI int32
+					 * WindowSize
 					 */
 #define RECEIVE_FREE_NCCI	0x26	/*
-					   * int32 AppllID int32 NCCI 
+					 * int32 AppllID int32 NCCI
 					 */
 #define RECEIVE_RELEASE		0x26	/*
-					   * int32 AppllID int32 0xffffffff 
+					 * int32 AppllID int32 0xffffffff
 					 */
 #define RECEIVE_TASK_READY	0x31	/*
-					   * int32 tasknr
-					   * int32 Length Taskname ...
+					 * int32 tasknr
+					 * int32 Length Taskname ...
 					 */
 #define RECEIVE_DEBUGMSG	0x71	/*
-					   * int32 Length message
-					   * 
+					 * int32 Length message
+					 *
 					 */
 #define RECEIVE_POLLDWORD	0x75	/* t1pci in dword mode */
 
@@ -264,7 +264,7 @@ static inline void b1_put_byte(unsigned int base, unsigned char val)
 static inline int b1_save_put_byte(unsigned int base, unsigned char val)
 {
 	unsigned long stop = jiffies + 2 * HZ;
-	while (!b1_tx_empty(base) && time_before(jiffies,stop));
+	while (!b1_tx_empty(base) && time_before(jiffies, stop));
 	if (!b1_tx_empty(base)) return -1;
 	b1outp(base, B1_WRITE, val);
 	return 0;
@@ -298,21 +298,21 @@ static inline void b1_put_slice(unsigned int base,
 }
 
 static void b1_wr_reg(unsigned int base,
-                      unsigned int reg,
+		      unsigned int reg,
 		      unsigned int value)
 {
 	b1_put_byte(base, WRITE_REGISTER);
-        b1_put_word(base, reg);
-        b1_put_word(base, value);
+	b1_put_word(base, reg);
+	b1_put_word(base, value);
 }
 
 static inline unsigned int b1_rd_reg(unsigned int base,
-                                     unsigned int reg)
+				     unsigned int reg)
 {
 	b1_put_byte(base, READ_REGISTER);
-        b1_put_word(base, reg);
-        return b1_get_word(base);
-	
+	b1_put_word(base, reg);
+	return b1_get_word(base);
+
 }
 
 static inline void b1_reset(unsigned int base)
@@ -338,13 +338,13 @@ static inline void b1_set_test_bit(unsigned int base,
 				   enum avmcardtype cardtype,
 				   int onoff)
 {
-    b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20);
+	b1_wr_reg(base, B1_STAT0(cardtype), onoff ? 0x21 : 0x20);
 }
 
 static inline int b1_get_test_bit(unsigned int base,
-                                  enum avmcardtype cardtype)
+				  enum avmcardtype cardtype)
 {
-    return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0;
+	return (b1_rd_reg(base, B1_STAT0(cardtype)) & 0x01) != 0;
 }
 
 /* ---------------------------------------------------------------- */
@@ -391,7 +391,7 @@ static inline void t1outp(unsigned int base,
 }
 
 static inline unsigned char t1inp(unsigned int base,
-			          unsigned short offset)
+				  unsigned short offset)
 {
 	return inb(base + offset);
 }
@@ -415,42 +415,42 @@ static inline unsigned int t1_get_slice(unsigned int base,
 #endif
 
 	len = i = b1_get_word(base);
-        if (t1_isfastlink(base)) {
+	if (t1_isfastlink(base)) {
 		int status;
 		while (i > 0) {
-			status = t1_fifostatus(base) & (T1F_IREADY|T1F_IHALF);
+			status = t1_fifostatus(base) & (T1F_IREADY | T1F_IHALF);
 			if (i >= FIFO_INPBSIZE) status |= T1F_IFULL;
 
 			switch (status) {
-				case T1F_IREADY|T1F_IHALF|T1F_IFULL:
-					insb(base+B1_READ, dp, FIFO_INPBSIZE);
-					dp += FIFO_INPBSIZE;
-					i -= FIFO_INPBSIZE;
+			case T1F_IREADY | T1F_IHALF | T1F_IFULL:
+				insb(base + B1_READ, dp, FIFO_INPBSIZE);
+				dp += FIFO_INPBSIZE;
+				i -= FIFO_INPBSIZE;
 #ifdef FASTLINK_DEBUG
-					wcnt += FIFO_INPBSIZE;
+				wcnt += FIFO_INPBSIZE;
 #endif
-					break;
-				case T1F_IREADY|T1F_IHALF: 
-					insb(base+B1_READ,dp, i);
+				break;
+			case T1F_IREADY | T1F_IHALF:
+				insb(base + B1_READ, dp, i);
 #ifdef FASTLINK_DEBUG
-					wcnt += i;
+				wcnt += i;
 #endif
-					dp += i;
-					i = 0;
-					break;
-				default:
-					*dp++ = b1_get_byte(base);
-					i--;
+				dp += i;
+				i = 0;
+				break;
+			default:
+				*dp++ = b1_get_byte(base);
+				i--;
 #ifdef FASTLINK_DEBUG
-					bcnt++;
+				bcnt++;
 #endif
-					break;
+				break;
 			}
-	    }
+		}
 #ifdef FASTLINK_DEBUG
-	    if (wcnt)
-	    printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n",
-				base, len, wcnt, bcnt);
+		if (wcnt)
+			printk(KERN_DEBUG "b1lli(0x%x): get_slice l=%d w=%d b=%d\n",
+			       base, len, wcnt, bcnt);
 #endif
 	} else {
 		while (i-- > 0)
@@ -464,26 +464,26 @@ static inline void t1_put_slice(unsigned int base,
 {
 	unsigned i = len;
 	b1_put_word(base, i);
-        if (t1_isfastlink(base)) {
+	if (t1_isfastlink(base)) {
 		int status;
 		while (i > 0) {
-			status = t1_fifostatus(base) & (T1F_OREADY|T1F_OHALF);
+			status = t1_fifostatus(base) & (T1F_OREADY | T1F_OHALF);
 			if (i >= FIFO_OUTBSIZE) status |= T1F_OEMPTY;
 			switch (status) {
-				case T1F_OREADY|T1F_OHALF|T1F_OEMPTY: 
-					outsb(base+B1_WRITE, dp, FIFO_OUTBSIZE);
-					dp += FIFO_OUTBSIZE;
-					i -= FIFO_OUTBSIZE;
-					break;
-				case T1F_OREADY|T1F_OHALF: 
-					outsb(base+B1_WRITE, dp, i);
-					dp += i;
-					i = 0;
-				        break;
-				default:
-					b1_put_byte(base, *dp++);
-					i--;
-					break;
+			case T1F_OREADY | T1F_OHALF | T1F_OEMPTY:
+				outsb(base + B1_WRITE, dp, FIFO_OUTBSIZE);
+				dp += FIFO_OUTBSIZE;
+				i -= FIFO_OUTBSIZE;
+				break;
+			case T1F_OREADY | T1F_OHALF:
+				outsb(base + B1_WRITE, dp, i);
+				dp += i;
+				i = 0;
+				break;
+			default:
+				b1_put_byte(base, *dp++);
+				i--;
+				break;
 			}
 		}
 	} else {
@@ -494,18 +494,18 @@ static inline void t1_put_slice(unsigned int base,
 
 static inline void t1_disable_irq(unsigned int base)
 {
-      t1outp(base, T1_IRQMASTER, 0x00);
+	t1outp(base, T1_IRQMASTER, 0x00);
 }
 
 static inline void t1_reset(unsigned int base)
 {
-        /* reset T1 Controller */
-        b1_reset(base);
-        /* disable irq on HEMA */
-        t1outp(base, B1_INSTAT, 0x00);
-        t1outp(base, B1_OUTSTAT, 0x00);
-        t1outp(base, T1_IRQMASTER, 0x00);
-        /* reset HEMA board configuration */
+	/* reset T1 Controller */
+	b1_reset(base);
+	/* disable irq on HEMA */
+	t1outp(base, B1_INSTAT, 0x00);
+	t1outp(base, B1_OUTSTAT, 0x00);
+	t1outp(base, T1_IRQMASTER, 0x00);
+	/* reset HEMA board configuration */
 	t1outp(base, T1_RESETBOARD, 0xf);
 }
 
@@ -513,29 +513,29 @@ static inline void b1_setinterrupt(unsigned int base, unsigned irq,
 				   enum avmcardtype cardtype)
 {
 	switch (cardtype) {
-	   case avm_t1isa:
-              t1outp(base, B1_INSTAT, 0x00);
-              t1outp(base, B1_INSTAT, 0x02);
-	      t1outp(base, T1_IRQMASTER, 0x08);
-	      break;
-	   case avm_b1isa:
-	      b1outp(base, B1_INSTAT, 0x00);
-	      b1outp(base, B1_RESET, b1_irq_table[irq]);
-	      b1outp(base, B1_INSTAT, 0x02);
-	      break;
-	   default:
-	   case avm_m1:
-	   case avm_m2:
-	   case avm_b1pci:
-	      b1outp(base, B1_INSTAT, 0x00);
-	      b1outp(base, B1_RESET, 0xf0);
-	      b1outp(base, B1_INSTAT, 0x02);
-	      break;
-	   case avm_c4:
-	   case avm_t1pci:
-	      b1outp(base, B1_RESET, 0xf0);
-	      break;
-	 }
+	case avm_t1isa:
+		t1outp(base, B1_INSTAT, 0x00);
+		t1outp(base, B1_INSTAT, 0x02);
+		t1outp(base, T1_IRQMASTER, 0x08);
+		break;
+	case avm_b1isa:
+		b1outp(base, B1_INSTAT, 0x00);
+		b1outp(base, B1_RESET, b1_irq_table[irq]);
+		b1outp(base, B1_INSTAT, 0x02);
+		break;
+	default:
+	case avm_m1:
+	case avm_m2:
+	case avm_b1pci:
+		b1outp(base, B1_INSTAT, 0x00);
+		b1outp(base, B1_RESET, 0xf0);
+		b1outp(base, B1_INSTAT, 0x02);
+		break;
+	case avm_c4:
+	case avm_t1pci:
+		b1outp(base, B1_RESET, 0xf0);
+		break;
+	}
 }
 
 /* b1.c */
@@ -543,14 +543,14 @@ avmcard *b1_alloc_card(int nr_controllers);
 void b1_free_card(avmcard *card);
 int b1_detect(unsigned int base, enum avmcardtype cardtype);
 void b1_getrevision(avmcard *card);
-int b1_load_t4file(avmcard *card, capiloaddatapart * t4file);
-int b1_load_config(avmcard *card, capiloaddatapart * config);
+int b1_load_t4file(avmcard *card, capiloaddatapart *t4file);
+int b1_load_config(avmcard *card, capiloaddatapart *config);
 int b1_loaded(avmcard *card);
 
 int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
 void b1_reset_ctr(struct capi_ctr *ctrl);
 void b1_register_appl(struct capi_ctr *ctrl, u16 appl,
-				capi_register_params *rp);
+		      capi_register_params *rp);
 void b1_release_appl(struct capi_ctr *ctrl, u16 appl);
 u16  b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
 void b1_parse_version(avmctrl_info *card);
@@ -572,8 +572,8 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
 void b1dma_reset_ctr(struct capi_ctr *ctrl);
 void b1dma_remove_ctr(struct capi_ctr *ctrl);
 void b1dma_register_appl(struct capi_ctr *ctrl,
-				u16 appl,
-				capi_register_params *rp);
+			 u16 appl,
+			 capi_register_params *rp);
 void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
 u16  b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
 extern const struct file_operations b1dmactl_proc_fops;
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index 2a57da59..821f7ac 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -1,7 +1,7 @@
 /* $Id: b1.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- * 
+ *
  * Common module for AVM B1 cards.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  *
  * This software may be used and distributed according to the terms
@@ -60,7 +60,7 @@ int b1_irq_table[16] =
  112,				/* irq 15 */
 };
 
-/* ------------------------------------------------------------- */	
+/* ------------------------------------------------------------- */
 
 avmcard *b1_alloc_card(int nr_controllers)
 {
@@ -104,13 +104,13 @@ int b1_detect(unsigned int base, enum avmcardtype cardtype)
 	int onoff, i;
 
 	/*
-	 * Statusregister 0000 00xx 
+	 * Statusregister 0000 00xx
 	 */
 	if ((inb(base + B1_INSTAT) & 0xfc)
 	    || (inb(base + B1_OUTSTAT) & 0xfc))
 		return 1;
 	/*
-	 * Statusregister 0000 001x 
+	 * Statusregister 0000 001x
 	 */
 	b1outp(base, B1_INSTAT, 0x2);	/* enable irq */
 	/* b1outp(base, B1_OUTSTAT, 0x2); */
@@ -118,38 +118,38 @@ int b1_detect(unsigned int base, enum avmcardtype cardtype)
 	    /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */)
 		return 2;
 	/*
-	 * Statusregister 0000 000x 
+	 * Statusregister 0000 000x
 	 */
 	b1outp(base, B1_INSTAT, 0x0);	/* disable irq */
 	b1outp(base, B1_OUTSTAT, 0x0);
 	if ((inb(base + B1_INSTAT) & 0xfe)
 	    || (inb(base + B1_OUTSTAT) & 0xfe))
 		return 3;
-        
-	for (onoff = !0, i= 0; i < 10 ; i++) {
+
+	for (onoff = !0, i = 0; i < 10; i++) {
 		b1_set_test_bit(base, cardtype, onoff);
 		if (b1_get_test_bit(base, cardtype) != onoff)
-		   return 4;
+			return 4;
 		onoff = !onoff;
 	}
 
 	if (cardtype == avm_m1)
-	   return 0;
+		return 0;
 
-        if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01)
-	   return 5;
+	if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01)
+		return 5;
 
 	return 0;
 }
 
 void b1_getrevision(avmcard *card)
 {
-    card->class = inb(card->port + B1_ANALYSE);
-    card->revision = inb(card->port + B1_REVISION);
+	card->class = inb(card->port + B1_ANALYSE);
+	card->revision = inb(card->port + B1_REVISION);
 }
 
 #define FWBUF_SIZE	256
-int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
+int b1_load_t4file(avmcard *card, capiloaddatapart *t4file)
 {
 	unsigned char buf[FWBUF_SIZE];
 	unsigned char *dp;
@@ -168,7 +168,7 @@ int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
 		for (i = 0; i < FWBUF_SIZE; i++)
 			if (b1_save_put_byte(base, buf[i]) < 0) {
 				printk(KERN_ERR "%s: corrupted firmware file ?\n",
-						card->name);
+				       card->name);
 				return -EIO;
 			}
 		left -= FWBUF_SIZE;
@@ -184,14 +184,14 @@ int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
 		for (i = 0; i < left; i++)
 			if (b1_save_put_byte(base, buf[i]) < 0) {
 				printk(KERN_ERR "%s: corrupted firmware file ?\n",
-						card->name);
+				       card->name);
 				return -EIO;
 			}
 	}
 	return 0;
 }
 
-int b1_load_config(avmcard *card, capiloaddatapart * config)
+int b1_load_config(avmcard *card, capiloaddatapart *config)
 {
 	unsigned char buf[FWBUF_SIZE];
 	unsigned char *dp;
@@ -202,9 +202,9 @@ int b1_load_config(avmcard *card, capiloaddatapart * config)
 	left = config->len;
 	if (left) {
 		b1_put_byte(base, SEND_CONFIG);
-        	b1_put_word(base, 1);
+		b1_put_word(base, 1);
 		b1_put_byte(base, SEND_CONFIG);
-        	b1_put_word(base, left);
+		b1_put_word(base, left);
 	}
 	while (left > FWBUF_SIZE) {
 		if (config->user) {
@@ -215,7 +215,7 @@ int b1_load_config(avmcard *card, capiloaddatapart * config)
 		}
 		for (i = 0; i < FWBUF_SIZE; ) {
 			b1_put_byte(base, SEND_CONFIG);
-			for (j=0; j < 4; j++) {
+			for (j = 0; j < 4; j++) {
 				b1_put_byte(base, buf[i++]);
 			}
 		}
@@ -231,7 +231,7 @@ int b1_load_config(avmcard *card, capiloaddatapart * config)
 		}
 		for (i = 0; i < left; ) {
 			b1_put_byte(base, SEND_CONFIG);
-			for (j=0; j < 4; j++) {
+			for (j = 0; j < 4; j++) {
 				if (i < left)
 					b1_put_byte(base, buf[i++]);
 				else
@@ -255,7 +255,7 @@ int b1_loaded(avmcard *card)
 	}
 	if (!b1_tx_empty(base)) {
 		printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n",
-				card->name);
+		       card->name);
 		return 0;
 	}
 	b1_put_byte(base, SEND_POLL);
@@ -265,7 +265,7 @@ int b1_loaded(avmcard *card)
 				return 1;
 			}
 			printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n",
-					card->name, ans);
+			       card->name, ans);
 			return 0;
 		}
 	}
@@ -288,7 +288,7 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 	if ((retval = b1_load_t4file(card, &data->firmware))) {
 		b1_reset(port);
 		printk(KERN_ERR "%s: failed to load t4file!!\n",
-					card->name);
+		       card->name);
 		return retval;
 	}
 
@@ -298,7 +298,7 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 		if ((retval = b1_load_config(card, &data->configuration))) {
 			b1_reset(port);
 			printk(KERN_ERR "%s: failed to load config!!\n",
-					card->name);
+			       card->name);
 			return retval;
 		}
 	}
@@ -312,7 +312,7 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 	b1_setinterrupt(port, card->irq, card->cardtype);
 	b1_put_byte(port, SEND_INIT);
 	b1_put_word(port, CAPI_MAXAPPL);
-	b1_put_word(port, AVM_NCCI_PER_CHANNEL*2);
+	b1_put_word(port, AVM_NCCI_PER_CHANNEL * 2);
 	b1_put_word(port, ctrl->cnr - 1);
 	spin_unlock_irqrestore(&card->lock, flags);
 
@@ -337,8 +337,8 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
 }
 
 void b1_register_appl(struct capi_ctr *ctrl,
-				u16 appl,
-				capi_register_params *rp)
+		      u16 appl,
+		      capi_register_params *rp)
 {
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
@@ -353,7 +353,7 @@ void b1_register_appl(struct capi_ctr *ctrl,
 	spin_lock_irqsave(&card->lock, flags);
 	b1_put_byte(port, SEND_REGISTER);
 	b1_put_word(port, appl);
-	b1_put_word(port, 1024 * (nconn+1));
+	b1_put_word(port, 1024 * (nconn + 1));
 	b1_put_word(port, nconn);
 	b1_put_word(port, rp->datablkcnt);
 	b1_put_word(port, rp->datablklen);
@@ -430,7 +430,7 @@ void b1_parse_version(avmctrl_info *cinfo)
 		cinfo->version[j] = &cinfo->versionbuf[i + 1];
 
 	strlcpy(ctrl->serial, cinfo->version[VER_SERIAL], sizeof(ctrl->serial));
-	memcpy(&ctrl->profile, cinfo->version[VER_PROFILE],sizeof(capi_profile));
+	memcpy(&ctrl->profile, cinfo->version[VER_PROFILE], sizeof(capi_profile));
 	strlcpy(ctrl->manu, "AVM GmbH", sizeof(ctrl->manu));
 	dversion = cinfo->version[VER_DRIVER];
 	ctrl->version.majorversion = 2;
@@ -439,49 +439,49 @@ void b1_parse_version(avmctrl_info *cinfo)
 	ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf);
 	ctrl->version.minormanuversion = (dversion[3] - '0') << 4;
 	ctrl->version.minormanuversion |=
-			(dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf);
+		(dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf);
 
 	profp = &ctrl->profile;
 
 	flag = ((u8 *)(profp->manu))[1];
 	switch (flag) {
 	case 0: if (cinfo->version[VER_CARDTYPE])
-	           strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]);
-	        else strcpy(cinfo->cardname, "B1");
+			strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]);
+		else strcpy(cinfo->cardname, "B1");
 		break;
-	case 3: strcpy(cinfo->cardname,"PCMCIA B"); break;
-	case 4: strcpy(cinfo->cardname,"PCMCIA M1"); break;
-	case 5: strcpy(cinfo->cardname,"PCMCIA M2"); break;
-	case 6: strcpy(cinfo->cardname,"B1 V3.0"); break;
-	case 7: strcpy(cinfo->cardname,"B1 PCI"); break;
+	case 3: strcpy(cinfo->cardname, "PCMCIA B"); break;
+	case 4: strcpy(cinfo->cardname, "PCMCIA M1"); break;
+	case 5: strcpy(cinfo->cardname, "PCMCIA M2"); break;
+	case 6: strcpy(cinfo->cardname, "B1 V3.0"); break;
+	case 7: strcpy(cinfo->cardname, "B1 PCI"); break;
 	default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break;
-        }
-        printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n",
-				card->name, ctrl->cnr, cinfo->cardname);
+	}
+	printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n",
+	       card->name, ctrl->cnr, cinfo->cardname);
 
-        flag = ((u8 *)(profp->manu))[3];
-        if (flag)
+	flag = ((u8 *)(profp->manu))[3];
+	if (flag)
 		printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n",
-			card->name,
-			ctrl->cnr,
-			(flag & 0x01) ? " DSS1" : "",
-			(flag & 0x02) ? " CT1" : "",
-			(flag & 0x04) ? " VN3" : "",
-			(flag & 0x08) ? " NI1" : "",
-			(flag & 0x10) ? " AUSTEL" : "",
-			(flag & 0x20) ? " ESS" : "",
-			(flag & 0x40) ? " 1TR6" : ""
+		       card->name,
+		       ctrl->cnr,
+		       (flag & 0x01) ? " DSS1" : "",
+		       (flag & 0x02) ? " CT1" : "",
+		       (flag & 0x04) ? " VN3" : "",
+		       (flag & 0x08) ? " NI1" : "",
+		       (flag & 0x10) ? " AUSTEL" : "",
+		       (flag & 0x20) ? " ESS" : "",
+		       (flag & 0x40) ? " 1TR6" : ""
 			);
 
-        flag = ((u8 *)(profp->manu))[5];
+	flag = ((u8 *)(profp->manu))[5];
 	if (flag)
 		printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n",
-			card->name,
-			ctrl->cnr,
-			(flag & 0x01) ? " point to point" : "",
-			(flag & 0x02) ? " point to multipoint" : "",
-			(flag & 0x08) ? " leased line without D-channel" : "",
-			(flag & 0x04) ? " leased line with D-channel" : ""
+		       card->name,
+		       ctrl->cnr,
+		       (flag & 0x01) ? " point to point" : "",
+		       (flag & 0x02) ? " point to multipoint" : "",
+		       (flag & 0x08) ? " leased line without D-channel" : "",
+		       (flag & 0x04) ? " leased line with D-channel" : ""
 			);
 }
 
@@ -521,13 +521,13 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 		spin_unlock_irqrestore(&card->lock, flags);
 
 		if (MsgLen < 30) { /* not CAPI 64Bit */
-			memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
+			memset(card->msgbuf + MsgLen, 0, 30-MsgLen);
 			MsgLen = 30;
 			CAPIMSG_SETLEN(card->msgbuf, 30);
 		}
 		if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+			       card->name);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 			memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
@@ -541,7 +541,7 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 		MsgLen = b1_get_slice(card->port, card->msgbuf);
 		if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+			       card->name);
 			spin_unlock_irqrestore(&card->lock, flags);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
@@ -573,7 +573,7 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 		break;
 
 	case RECEIVE_START:
-	   	/* b1_put_byte(card->port, SEND_POLLACK); */
+		/* b1_put_byte(card->port, SEND_POLLACK); */
 		spin_unlock_irqrestore(&card->lock, flags);
 		capi_ctr_resume_output(ctrl);
 		break;
@@ -600,24 +600,24 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 		MsgLen = b1_get_slice(card->port, card->msgbuf);
 		spin_unlock_irqrestore(&card->lock, flags);
 		card->msgbuf[MsgLen] = 0;
-		while (    MsgLen > 0
-		       && (   card->msgbuf[MsgLen-1] == '\n'
-			   || card->msgbuf[MsgLen-1] == '\r')) {
-			card->msgbuf[MsgLen-1] = 0;
+		while (MsgLen > 0
+		       && (card->msgbuf[MsgLen - 1] == '\n'
+			   || card->msgbuf[MsgLen - 1] == '\r')) {
+			card->msgbuf[MsgLen - 1] = 0;
 			MsgLen--;
 		}
 		printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
-				card->name, ApplId, card->msgbuf);
+		       card->name, ApplId, card->msgbuf);
 		break;
 
 	case RECEIVE_DEBUGMSG:
 		MsgLen = b1_get_slice(card->port, card->msgbuf);
 		spin_unlock_irqrestore(&card->lock, flags);
 		card->msgbuf[MsgLen] = 0;
-		while (    MsgLen > 0
-		       && (   card->msgbuf[MsgLen-1] == '\n'
-			   || card->msgbuf[MsgLen-1] == '\r')) {
-			card->msgbuf[MsgLen-1] = 0;
+		while (MsgLen > 0
+		       && (card->msgbuf[MsgLen - 1] == '\n'
+			   || card->msgbuf[MsgLen - 1] == '\r')) {
+			card->msgbuf[MsgLen - 1] = 0;
 			MsgLen--;
 		}
 		printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
@@ -630,7 +630,7 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
 	default:
 		spin_unlock_irqrestore(&card->lock, flags);
 		printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
-				card->name, b1cmd);
+		       card->name, b1cmd);
 		return IRQ_HANDLED;
 	}
 	return IRQ_HANDLED;
@@ -671,29 +671,29 @@ static int b1ctl_proc_show(struct seq_file *m, void *v)
 		seq_printf(m, "%-16s %s\n", "ver_serial", s);
 
 	if (card->cardtype != avm_m1) {
-        	flag = ((u8 *)(ctrl->profile.manu))[3];
-        	if (flag)
+		flag = ((u8 *)(ctrl->profile.manu))[3];
+		if (flag)
 			seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
-			"protocol",
-			(flag & 0x01) ? " DSS1" : "",
-			(flag & 0x02) ? " CT1" : "",
-			(flag & 0x04) ? " VN3" : "",
-			(flag & 0x08) ? " NI1" : "",
-			(flag & 0x10) ? " AUSTEL" : "",
-			(flag & 0x20) ? " ESS" : "",
-			(flag & 0x40) ? " 1TR6" : ""
-			);
+				   "protocol",
+				   (flag & 0x01) ? " DSS1" : "",
+				   (flag & 0x02) ? " CT1" : "",
+				   (flag & 0x04) ? " VN3" : "",
+				   (flag & 0x08) ? " NI1" : "",
+				   (flag & 0x10) ? " AUSTEL" : "",
+				   (flag & 0x20) ? " ESS" : "",
+				   (flag & 0x40) ? " 1TR6" : ""
+				);
 	}
 	if (card->cardtype != avm_m1) {
-        	flag = ((u8 *)(ctrl->profile.manu))[5];
+		flag = ((u8 *)(ctrl->profile.manu))[5];
 		if (flag)
 			seq_printf(m, "%-16s%s%s%s%s\n",
-			"linetype",
-			(flag & 0x01) ? " point to point" : "",
-			(flag & 0x02) ? " point to multipoint" : "",
-			(flag & 0x08) ? " leased line without D-channel" : "",
-			(flag & 0x04) ? " leased line with D-channel" : ""
-			);
+				   "linetype",
+				   (flag & 0x01) ? " point to point" : "",
+				   (flag & 0x02) ? " point to multipoint" : "",
+				   (flag & 0x08) ? " leased line without D-channel" : "",
+				   (flag & 0x04) ? " leased line with D-channel" : ""
+				);
 	}
 	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
 
@@ -750,12 +750,12 @@ avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize)
 
 	return p;
 
- err_free_consistent:
+err_free_consistent:
 	pci_free_consistent(p->pcidev, p->recvbuf.size,
 			    p->recvbuf.dmabuf, p->recvbuf.dmaaddr);
- err_kfree:
+err_kfree:
 	kfree(p);
- err:
+err:
 	return NULL;
 }
 
@@ -800,7 +800,7 @@ static int __init b1_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index a0ed668..0896aa8 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -1,9 +1,9 @@
 /* $Id: b1dma.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
- * 
+ *
  * Common module for AVM B1 cards that support dma with AMCC
- * 
+ *
  * Copyright 2000 by Carsten Paeth <calle@calle.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -110,11 +110,11 @@ static int b1dma_tolink(avmcard *card, void *buf, unsigned int len)
 	unsigned long stop = jiffies + 1 * HZ;	/* maximum wait time 1 sec */
 	unsigned char *s = (unsigned char *)buf;
 	while (len--) {
-		while (   !b1dma_tx_empty(card->port)
+		while (!b1dma_tx_empty(card->port)
 		       && time_before(jiffies, stop));
-		if (!b1dma_tx_empty(card->port)) 
+		if (!b1dma_tx_empty(card->port))
 			return -1;
-	        t1outp(card->port, 0x01, *s++);
+		t1outp(card->port, 0x01, *s++);
 	}
 	return 0;
 }
@@ -124,11 +124,11 @@ static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len)
 	unsigned long stop = jiffies + 1 * HZ;	/* maximum wait time 1 sec */
 	unsigned char *s = (unsigned char *)buf;
 	while (len--) {
-		while (   !b1dma_rx_full(card->port)
+		while (!b1dma_rx_full(card->port)
 		       && time_before(jiffies, stop));
-		if (!b1dma_rx_full(card->port)) 
+		if (!b1dma_rx_full(card->port))
 			return -1;
-	        *s++ = t1inp(card->port, 0x00);
+		*s++ = t1inp(card->port, 0x00);
 	}
 	return 0;
 }
@@ -136,7 +136,7 @@ static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len)
 static int WriteReg(avmcard *card, u32 reg, u8 val)
 {
 	u8 cmd = 0x00;
-	if (   b1dma_tolink(card, &cmd, 1) == 0
+	if (b1dma_tolink(card, &cmd, 1) == 0
 	    && b1dma_tolink(card, &reg, 4) == 0) {
 		u32 tmp = val;
 		return b1dma_tolink(card, &tmp, 4);
@@ -147,7 +147,7 @@ static int WriteReg(avmcard *card, u32 reg, u8 val)
 static u8 ReadReg(avmcard *card, u32 reg)
 {
 	u8 cmd = 0x01;
-	if (   b1dma_tolink(card, &cmd, 1) == 0
+	if (b1dma_tolink(card, &cmd, 1) == 0
 	    && b1dma_tolink(card, &reg, 4) == 0) {
 		u32 tmp;
 		if (b1dma_fromlink(card, &tmp, 4) == 0)
@@ -258,30 +258,30 @@ static int b1dma_detect(avmcard *card)
 
 	b1dma_writel(card, 0xffffffff, AMCC_RXPTR);
 	b1dma_writel(card, 0xffffffff, AMCC_TXPTR);
-	if (   b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc
+	if (b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc
 	    || b1dma_readl(card, AMCC_TXPTR) != 0xfffffffc)
 		return 2;
 
 	b1dma_writel(card, 0x0, AMCC_RXPTR);
 	b1dma_writel(card, 0x0, AMCC_TXPTR);
-	if (   b1dma_readl(card, AMCC_RXPTR) != 0x0
+	if (b1dma_readl(card, AMCC_RXPTR) != 0x0
 	    || b1dma_readl(card, AMCC_TXPTR) != 0x0)
 		return 3;
 
 	t1outp(card->port, 0x10, 0x00);
 	t1outp(card->port, 0x07, 0x00);
-	
+
 	t1outp(card->port, 0x02, 0x02);
 	t1outp(card->port, 0x03, 0x02);
 
-	if (   (t1inp(card->port, 0x02) & 0xFE) != 0x02
+	if ((t1inp(card->port, 0x02) & 0xFE) != 0x02
 	    || t1inp(card->port, 0x3) != 0x03)
 		return 4;
 
 	t1outp(card->port, 0x02, 0x00);
 	t1outp(card->port, 0x03, 0x00);
 
-	if (   (t1inp(card->port, 0x02) & 0xFE) != 0x00
+	if ((t1inp(card->port, 0x02) & 0xFE) != 0x00
 	    || t1inp(card->port, 0x3) != 0x01)
 		return 5;
 
@@ -294,28 +294,28 @@ int t1pci_detect(avmcard *card)
 
 	if ((ret = b1dma_detect(card)) != 0)
 		return ret;
-	
+
 	/* Transputer test */
-	
-	if (   WriteReg(card, 0x80001000, 0x11) != 0
+
+	if (WriteReg(card, 0x80001000, 0x11) != 0
 	    || WriteReg(card, 0x80101000, 0x22) != 0
 	    || WriteReg(card, 0x80201000, 0x33) != 0
 	    || WriteReg(card, 0x80301000, 0x44) != 0)
 		return 6;
 
-	if (   ReadReg(card, 0x80001000) != 0x11
+	if (ReadReg(card, 0x80001000) != 0x11
 	    || ReadReg(card, 0x80101000) != 0x22
 	    || ReadReg(card, 0x80201000) != 0x33
 	    || ReadReg(card, 0x80301000) != 0x44)
 		return 7;
 
-	if (   WriteReg(card, 0x80001000, 0x55) != 0
+	if (WriteReg(card, 0x80001000, 0x55) != 0
 	    || WriteReg(card, 0x80101000, 0x66) != 0
 	    || WriteReg(card, 0x80201000, 0x77) != 0
 	    || WriteReg(card, 0x80301000, 0x88) != 0)
 		return 8;
 
-	if (   ReadReg(card, 0x80001000) != 0x55
+	if (ReadReg(card, 0x80001000) != 0x55
 	    || ReadReg(card, 0x80101000) != 0x66
 	    || ReadReg(card, 0x80201000) != 0x77
 	    || ReadReg(card, 0x80301000) != 0x88)
@@ -330,20 +330,20 @@ int b1pciv4_detect(avmcard *card)
 
 	if ((ret = b1dma_detect(card)) != 0)
 		return ret;
-	
-	for (i=0; i < 5 ; i++) {
+
+	for (i = 0; i < 5; i++) {
 		if (WriteReg(card, 0x80A00000, 0x21) != 0)
 			return 6;
 		if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01)
 			return 7;
 	}
-	for (i=0; i < 5 ; i++) {
+	for (i = 0; i < 5; i++) {
 		if (WriteReg(card, 0x80A00000, 0x20) != 0)
 			return 8;
 		if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00)
 			return 9;
 	}
-	
+
 	return 0;
 }
 
@@ -373,7 +373,7 @@ static void b1dma_dispatch_tx(avmcard *card)
 	u16 len;
 	u32 txlen;
 	void *p;
-	
+
 	skb = skb_dequeue(&dma->send_queue);
 
 	len = CAPIMSG_LEN(skb->data);
@@ -398,13 +398,13 @@ static void b1dma_dispatch_tx(avmcard *card)
 		printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
 #endif
 	} else {
-		txlen = skb->len-2;
+		txlen = skb->len - 2;
 #ifdef AVM_B1DMA_POLLDEBUG
 		if (skb->data[2] == SEND_POLLACK)
 			printk(KERN_INFO "%s: send ack\n", card->name);
 #endif
 #ifdef AVM_B1DMA_DEBUG
-		printk(KERN_DEBUG "tx: put 0x%x len=%d\n", 
+		printk(KERN_DEBUG "tx: put 0x%x len=%d\n",
 		       skb->data[2], txlen);
 #endif
 		skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf,
@@ -430,7 +430,7 @@ static void queue_pollack(avmcard *card)
 	skb = alloc_skb(3, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, lost poll ack\n",
-					card->name);
+		       card->name);
 		return;
 	}
 	p = skb->data;
@@ -450,14 +450,14 @@ static void b1dma_handle_rx(avmcard *card)
 	avmcard_dmainfo *dma = card->dma;
 	struct capi_ctr *ctrl = &cinfo->capi_ctrl;
 	struct sk_buff *skb;
-	void *p = dma->recvbuf.dmabuf+4;
+	void *p = dma->recvbuf.dmabuf + 4;
 	u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
 	u8 b1cmd =  _get_byte(&p);
 
 #ifdef AVM_B1DMA_DEBUG
 	printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
 #endif
-	
+
 	switch (b1cmd) {
 	case RECEIVE_DATA_B3_IND:
 
@@ -466,13 +466,13 @@ static void b1dma_handle_rx(avmcard *card)
 		DataB3Len = _get_slice(&p, card->databuf);
 
 		if (MsgLen < 30) { /* not CAPI 64Bit */
-			memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
+			memset(card->msgbuf + MsgLen, 0, 30 - MsgLen);
 			MsgLen = 30;
 			CAPIMSG_SETLEN(card->msgbuf, 30);
 		}
-		if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
+		if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+			       card->name);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 			memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
@@ -486,14 +486,14 @@ static void b1dma_handle_rx(avmcard *card)
 		MsgLen = _get_slice(&p, card->msgbuf);
 		if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+			       card->name);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 			if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) {
 				spin_lock(&card->lock);
 				capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
-					CAPIMSG_NCCI(skb->data),
-					CAPIMSG_MSGID(skb->data));
+						     CAPIMSG_NCCI(skb->data),
+						     CAPIMSG_MSGID(skb->data));
 				spin_unlock(&card->lock);
 			}
 			capi_ctr_handle_message(ctrl, ApplId, skb);
@@ -550,23 +550,23 @@ static void b1dma_handle_rx(avmcard *card)
 		ApplId = (unsigned) _get_word(&p);
 		MsgLen = _get_slice(&p, card->msgbuf);
 		card->msgbuf[MsgLen] = 0;
-		while (    MsgLen > 0
-		       && (   card->msgbuf[MsgLen-1] == '\n'
-			   || card->msgbuf[MsgLen-1] == '\r')) {
-			card->msgbuf[MsgLen-1] = 0;
+		while (MsgLen > 0
+		       && (card->msgbuf[MsgLen - 1] == '\n'
+			   || card->msgbuf[MsgLen - 1] == '\r')) {
+			card->msgbuf[MsgLen - 1] = 0;
 			MsgLen--;
 		}
 		printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
-				card->name, ApplId, card->msgbuf);
+		       card->name, ApplId, card->msgbuf);
 		break;
 
 	case RECEIVE_DEBUGMSG:
 		MsgLen = _get_slice(&p, card->msgbuf);
 		card->msgbuf[MsgLen] = 0;
-		while (    MsgLen > 0
-		       && (   card->msgbuf[MsgLen-1] == '\n'
-			   || card->msgbuf[MsgLen-1] == '\r')) {
-			card->msgbuf[MsgLen-1] = 0;
+		while (MsgLen > 0
+		       && (card->msgbuf[MsgLen - 1] == '\n'
+			   || card->msgbuf[MsgLen - 1] == '\r')) {
+			card->msgbuf[MsgLen - 1] = 0;
 			MsgLen--;
 		}
 		printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
@@ -574,7 +574,7 @@ static void b1dma_handle_rx(avmcard *card)
 
 	default:
 		printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n",
-				card->name, b1cmd);
+		       card->name, b1cmd);
 		return;
 	}
 }
@@ -594,7 +594,7 @@ static void b1dma_handle_interrupt(avmcard *card)
 		return;
 	}
 
-        newcsr = card->csr | (status & ALL_INT);
+	newcsr = card->csr | (status & ALL_INT);
 	if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
 	if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
 	b1dma_writel(card, newcsr, AMCC_INTCSR);
@@ -602,23 +602,23 @@ static void b1dma_handle_interrupt(avmcard *card)
 	if ((status & RX_TC_INT) != 0) {
 		struct avmcard_dmainfo *dma = card->dma;
 		u32 rxlen;
-	   	if (card->dma->recvlen == 0) {
-	        	rxlen = b1dma_readl(card, AMCC_RXLEN);
+		if (card->dma->recvlen == 0) {
+			rxlen = b1dma_readl(card, AMCC_RXLEN);
 			if (rxlen == 0) {
 				dma->recvlen = *((u32 *)dma->recvbuf.dmabuf);
 				rxlen = (dma->recvlen + 3) & ~3;
-				b1dma_writel(card, dma->recvbuf.dmaaddr+4, AMCC_RXPTR);
+				b1dma_writel(card, dma->recvbuf.dmaaddr + 4, AMCC_RXPTR);
 				b1dma_writel(card, rxlen, AMCC_RXLEN);
 #ifdef AVM_B1DMA_DEBUG
 			} else {
 				printk(KERN_ERR "%s: rx not complete (%d).\n",
-					card->name, rxlen);
+				       card->name, rxlen);
 #endif
 			}
 		} else {
 			spin_unlock(&card->lock);
 			b1dma_handle_rx(card);
-	   		dma->recvlen = 0;
+			dma->recvlen = 0;
 			spin_lock(&card->lock);
 			b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR);
 			b1dma_writel(card, 4, AMCC_RXLEN);
@@ -659,7 +659,7 @@ static int b1dma_loaded(avmcard *card)
 	}
 	if (!b1_tx_empty(base)) {
 		printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n",
-				card->name);
+		       card->name);
 		return 0;
 	}
 	b1_put_byte(base, SEND_POLLACK);
@@ -686,7 +686,7 @@ static void b1dma_send_init(avmcard *card)
 	skb = alloc_skb(15, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, lost register appl.\n",
-					card->name);
+		       card->name);
 		return;
 	}
 	p = skb->data;
@@ -694,7 +694,7 @@ static void b1dma_send_init(avmcard *card)
 	_put_byte(&p, 0);
 	_put_byte(&p, SEND_INIT);
 	_put_word(&p, CAPI_MAXAPPL);
-	_put_word(&p, AVM_NCCI_PER_CHANNEL*30);
+	_put_word(&p, AVM_NCCI_PER_CHANNEL * 30);
 	_put_word(&p, card->cardnr - 1);
 	skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
@@ -712,7 +712,7 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 	if ((retval = b1_load_t4file(card, &data->firmware))) {
 		b1dma_reset(card);
 		printk(KERN_ERR "%s: failed to load t4file!!\n",
-					card->name);
+		       card->name);
 		return retval;
 	}
 
@@ -720,7 +720,7 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 		if ((retval = b1_load_config(card, &data->configuration))) {
 			b1dma_reset(card);
 			printk(KERN_ERR "%s: failed to load config!!\n",
-					card->name);
+			       card->name);
 			return retval;
 		}
 	}
@@ -733,8 +733,8 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 
 	card->csr = AVM_FLAG;
 	b1dma_writel(card, card->csr, AMCC_INTCSR);
-	b1dma_writel(card, EN_A2P_TRANSFERS|EN_P2A_TRANSFERS|A2P_HI_PRIORITY|
-		     P2A_HI_PRIORITY|RESET_A2P_FLAGS|RESET_P2A_FLAGS, 
+	b1dma_writel(card, EN_A2P_TRANSFERS | EN_P2A_TRANSFERS | A2P_HI_PRIORITY |
+		     P2A_HI_PRIORITY | RESET_A2P_FLAGS | RESET_P2A_FLAGS,
 		     AMCC_MCSR);
 	t1outp(card->port, 0x07, 0x30);
 	t1outp(card->port, 0x10, 0xF0);
@@ -745,7 +745,7 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 	card->csr |= EN_RX_TC_INT;
 	b1dma_writel(card, card->csr, AMCC_INTCSR);
 
-        b1dma_send_init(card);
+	b1dma_send_init(card);
 
 	return 0;
 }
@@ -757,7 +757,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl)
 	unsigned long flags;
 
 	spin_lock_irqsave(&card->lock, flags);
- 	b1dma_reset(card);
+	b1dma_reset(card);
 
 	memset(cinfo->version, 0, sizeof(cinfo->version));
 	capilib_release(&cinfo->ncci_head);
@@ -768,8 +768,8 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl)
 /* ------------------------------------------------------------- */
 
 void b1dma_register_appl(struct capi_ctr *ctrl,
-				u16 appl,
-				capi_register_params *rp)
+			 u16 appl,
+			 capi_register_params *rp)
 {
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
@@ -785,7 +785,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
 	skb = alloc_skb(23, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, lost register appl.\n",
-					card->name);
+		       card->name);
 		return;
 	}
 	p = skb->data;
@@ -793,7 +793,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
 	_put_byte(&p, 0);
 	_put_byte(&p, SEND_REGISTER);
 	_put_word(&p, appl);
-	_put_word(&p, 1024 * (nconn+1));
+	_put_word(&p, 1024 * (nconn + 1));
 	_put_word(&p, nconn);
 	_put_word(&p, rp->datablkcnt);
 	_put_word(&p, rp->datablklen);
@@ -819,7 +819,7 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl)
 	skb = alloc_skb(7, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, lost release appl.\n",
-					card->name);
+		       card->name);
 		return;
 	}
 	p = skb->data;
@@ -841,7 +841,7 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
 	avmcard *card = cinfo->card;
 	u16 retval = CAPI_NOERROR;
 
- 	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
 		unsigned long flags;
 		spin_lock_irqsave(&card->lock, flags);
 		retval = capilib_data_b3_req(&cinfo->ncci_head,
@@ -850,7 +850,7 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
 					     CAPIMSG_MSGID(skb->data));
 		spin_unlock_irqrestore(&card->lock, flags);
 	}
-	if (retval == CAPI_NOERROR) 
+	if (retval == CAPI_NOERROR)
 		b1dma_queue_tx(card, skb);
 
 	return retval;
@@ -893,29 +893,29 @@ static int b1dmactl_proc_show(struct seq_file *m, void *v)
 		seq_printf(m, "%-16s %s\n", "ver_serial", s);
 
 	if (card->cardtype != avm_m1) {
-        	flag = ((u8 *)(ctrl->profile.manu))[3];
-        	if (flag)
+		flag = ((u8 *)(ctrl->profile.manu))[3];
+		if (flag)
 			seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
-			"protocol",
-			(flag & 0x01) ? " DSS1" : "",
-			(flag & 0x02) ? " CT1" : "",
-			(flag & 0x04) ? " VN3" : "",
-			(flag & 0x08) ? " NI1" : "",
-			(flag & 0x10) ? " AUSTEL" : "",
-			(flag & 0x20) ? " ESS" : "",
-			(flag & 0x40) ? " 1TR6" : ""
-			);
+				   "protocol",
+				   (flag & 0x01) ? " DSS1" : "",
+				   (flag & 0x02) ? " CT1" : "",
+				   (flag & 0x04) ? " VN3" : "",
+				   (flag & 0x08) ? " NI1" : "",
+				   (flag & 0x10) ? " AUSTEL" : "",
+				   (flag & 0x20) ? " ESS" : "",
+				   (flag & 0x40) ? " 1TR6" : ""
+				);
 	}
 	if (card->cardtype != avm_m1) {
-        	flag = ((u8 *)(ctrl->profile.manu))[5];
+		flag = ((u8 *)(ctrl->profile.manu))[5];
 		if (flag)
 			seq_printf(m, "%-16s%s%s%s%s\n",
-			"linetype",
-			(flag & 0x01) ? " point to point" : "",
-			(flag & 0x02) ? " point to multipoint" : "",
-			(flag & 0x08) ? " leased line without D-channel" : "",
-			(flag & 0x04) ? " leased line with D-channel" : ""
-			);
+				   "linetype",
+				   (flag & 0x01) ? " point to point" : "",
+				   (flag & 0x02) ? " point to multipoint" : "",
+				   (flag & 0x08) ? " leased line without D-channel" : "",
+				   (flag & 0x04) ? " leased line with D-channel" : ""
+				);
 	}
 	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
 
@@ -977,7 +977,7 @@ static int __init b1dma_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, sizeof(rev));
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c
index ff53905..31ef813 100644
--- a/drivers/isdn/hardware/avm/b1isa.c
+++ b/drivers/isdn/hardware/avm/b1isa.c
@@ -1,9 +1,9 @@
 /* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
- * 
+ *
  * Module for AVM B1 ISA-card.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -80,7 +80,7 @@ static int b1isa_probe(struct pci_dev *pdev)
 	card->cardtype = avm_b1isa;
 	sprintf(card->name, "b1isa-%x", card->port);
 
-	if (   card->port != 0x150 && card->port != 0x250
+	if (card->port != 0x150 && card->port != 0x250
 	    && card->port != 0x300 && card->port != 0x340) {
 		printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port);
 		retval = -EINVAL;
@@ -136,13 +136,13 @@ static int b1isa_probe(struct pci_dev *pdev)
 	pci_set_drvdata(pdev, cinfo);
 	return 0;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_release_region:
+err_release_region:
 	release_region(card->port, AVMB1_PORTLEN);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 }
 
@@ -206,7 +206,7 @@ static int __init b1isa_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/b1pci.c b/drivers/isdn/hardware/avm/b1pci.c
index c97e431..b305e6b 100644
--- a/drivers/isdn/hardware/avm/b1pci.c
+++ b/drivers/isdn/hardware/avm/b1pci.c
@@ -1,9 +1,9 @@
 /* $Id: b1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- * 
+ *
  * Module for AVM B1 PCI-card.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -79,7 +79,7 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
 	card->port = p->port;
 	card->irq = p->irq;
 	card->cardtype = avm_b1pci;
-	
+
 	if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
 		printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
 		       card->port, card->port + AVMB1_PORTLEN);
@@ -96,14 +96,14 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
 	}
 	b1_reset(card->port);
 	b1_getrevision(card);
-	
+
 	retval = request_irq(card->irq, b1_interrupt, IRQF_SHARED, card->name, card);
 	if (retval) {
 		printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq);
 		retval = -EBUSY;
 		goto err_release_region;
 	}
-	
+
 	cinfo->capi_ctrl.driver_name   = "b1pci";
 	cinfo->capi_ctrl.driverdata    = cinfo;
 	cinfo->capi_ctrl.register_appl = b1_register_appl;
@@ -133,13 +133,13 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
 	pci_set_drvdata(pdev, card);
 	return 0;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_release_region:
+err_release_region:
 	release_region(card->port, AVMB1_PORTLEN);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 }
 
@@ -193,7 +193,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
 		goto err;
 	}
 
-        card->dma = avmcard_dma_alloc("b1pci", pdev, 2048+128, 2048+128);
+	card->dma = avmcard_dma_alloc("b1pci", pdev, 2048 + 128, 2048 + 128);
 	if (!card->dma) {
 		printk(KERN_WARNING "b1pci: dma alloc.\n");
 		retval = -ENOMEM;
@@ -267,17 +267,17 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
 	pci_set_drvdata(pdev, card);
 	return 0;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_unmap:
+err_unmap:
 	iounmap(card->mbase);
- err_release_region:
+err_release_region:
 	release_region(card->port, AVMB1_PORTLEN);
- err_free_dma:
+err_free_dma:
 	avmcard_dma_free(card->dma);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 
 }
@@ -287,13 +287,13 @@ static void b1pciv4_remove(struct pci_dev *pdev)
 	avmcard *card = pci_get_drvdata(pdev);
 	avmctrl_info *cinfo = card->ctrlinfo;
 
- 	b1dma_reset(card);
+	b1dma_reset(card);
 
 	detach_capi_ctr(&cinfo->capi_ctrl);
 	free_irq(card->irq, card);
 	iounmap(card->mbase);
 	release_region(card->port, AVMB1_PORTLEN);
-        avmcard_dma_free(card->dma);
+	avmcard_dma_free(card->dma);
 	b1_free_card(card);
 }
 
@@ -326,7 +326,7 @@ static int __devinit b1pci_pci_probe(struct pci_dev *pdev,
 		retval = b1pci_probe(&param, pdev);
 #endif
 		if (retval != 0) {
-		        printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
+			printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
 			       param.port, param.irq, param.membase);
 		}
 	} else {
@@ -337,7 +337,7 @@ static int __devinit b1pci_pci_probe(struct pci_dev *pdev,
 		       param.port, param.irq);
 		retval = b1pci_probe(&param, pdev);
 		if (retval != 0) {
-		        printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n",
+			printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n",
 			       param.port, param.irq);
 		}
 	}
@@ -385,7 +385,7 @@ static int __init b1pci_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c
index d6391e0..6b0d19d 100644
--- a/drivers/isdn/hardware/avm/b1pcmcia.c
+++ b/drivers/isdn/hardware/avm/b1pcmcia.c
@@ -1,9 +1,9 @@
 /* $Id: b1pcmcia.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- * 
+ *
  * Module for AVM B1/M1/M2 PCMCIA-card.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -74,9 +74,9 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
 	cinfo = card->ctrlinfo;
 
 	switch (cardtype) {
-		case avm_m1: sprintf(card->name, "m1-%x", port); break;
-		case avm_m2: sprintf(card->name, "m2-%x", port); break;
-		default: sprintf(card->name, "b1pcmcia-%x", port); break;
+	case avm_m1: sprintf(card->name, "m1-%x", port); break;
+	case avm_m2: sprintf(card->name, "m2-%x", port); break;
+	default: sprintf(card->name, "b1pcmcia-%x", port); break;
 	}
 	card->port = port;
 	card->irq = irq;
@@ -117,9 +117,9 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
 		goto err_free_irq;
 	}
 	switch (cardtype) {
-		case avm_m1: cardname = "M1"; break;
-		case avm_m2: cardname = "M2"; break;
-		default    : cardname = "B1 PCMCIA"; break;
+	case avm_m1: cardname = "M1"; break;
+	case avm_m2: cardname = "M2"; break;
+	default: cardname = "B1 PCMCIA"; break;
 	}
 
 	printk(KERN_INFO "b1pcmcia: AVM %s at i/o %#x, irq %d, revision %d\n",
@@ -128,11 +128,11 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
 	list_add(&card->list, &cards);
 	return cinfo->capi_ctrl.cnr;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 }
 
@@ -175,7 +175,7 @@ int b1pcmcia_delcard(unsigned int port, unsigned irq)
 {
 	struct list_head *l;
 	avmcard *card;
-	
+
 	list_for_each(l, &cards) {
 		card = list_entry(l, avmcard, list);
 		if (card->port == port && card->irq == irq) {
@@ -204,7 +204,7 @@ static int __init b1pcmcia_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index 9743b24..98f1881 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -1,7 +1,7 @@
 /* $Id: c4.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- * 
+ *
  * Module for AVM C4 & C2 card.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  *
  * This software may be used and distributed according to the terms
@@ -129,8 +129,8 @@ static void c4_dispatch_tx(avmcard *card);
 
 /* ------------------------------------------------------------- */
 
-#define	RESET_TIMEOUT		(15*HZ)	/* 15 sec */
-#define	PEEK_POKE_TIMEOUT	(HZ/10)	/* 0.1 sec */
+#define	RESET_TIMEOUT		(15 * HZ)	/* 15 sec */
+#define	PEEK_POKE_TIMEOUT	(HZ / 10)	/* 0.1 sec */
 
 /* ------------------------------------------------------------- */
 
@@ -148,7 +148,7 @@ static inline int wait_for_doorbell(avmcard *card, unsigned long t)
 	unsigned long stop;
 
 	stop = jiffies + t;
-	while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
+	while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) {
 		if (!time_before(jiffies, stop))
 			return -1;
 		mb();
@@ -159,40 +159,40 @@ static inline int wait_for_doorbell(avmcard *card, unsigned long t)
 static int c4_poke(avmcard *card,  unsigned long off, unsigned long value)
 {
 
-	if (wait_for_doorbell(card, HZ/10) < 0)
+	if (wait_for_doorbell(card, HZ / 10) < 0)
 		return -1;
-	
-	c4outmeml(card->mbase+MBOX_PEEK_POKE, off);
-	c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
 
-	if (wait_for_doorbell(card, HZ/10) < 0)
+	c4outmeml(card->mbase + MBOX_PEEK_POKE, off);
+	c4outmeml(card->mbase + DOORBELL, DBELL_ADDR);
+
+	if (wait_for_doorbell(card, HZ / 10) < 0)
 		return -1;
 
-	c4outmeml(card->mbase+MBOX_PEEK_POKE, value);
-	c4outmeml(card->mbase+DOORBELL, DBELL_DATA | DBELL_ADDR);
+	c4outmeml(card->mbase + MBOX_PEEK_POKE, value);
+	c4outmeml(card->mbase + DOORBELL, DBELL_DATA | DBELL_ADDR);
 
 	return 0;
 }
 
 static int c4_peek(avmcard *card,  unsigned long off, unsigned long *valuep)
 {
-	if (wait_for_doorbell(card, HZ/10) < 0)
+	if (wait_for_doorbell(card, HZ / 10) < 0)
 		return -1;
 
-	c4outmeml(card->mbase+MBOX_PEEK_POKE, off);
-	c4outmeml(card->mbase+DOORBELL, DBELL_RNWR | DBELL_ADDR);
+	c4outmeml(card->mbase + MBOX_PEEK_POKE, off);
+	c4outmeml(card->mbase + DOORBELL, DBELL_RNWR | DBELL_ADDR);
 
-	if (wait_for_doorbell(card, HZ/10) < 0)
+	if (wait_for_doorbell(card, HZ / 10) < 0)
 		return -1;
 
-	*valuep = c4inmeml(card->mbase+MBOX_PEEK_POKE);
+	*valuep = c4inmeml(card->mbase + MBOX_PEEK_POKE);
 
 	return 0;
 }
 
 /* ------------------------------------------------------------- */
 
-static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file)
+static int c4_load_t4file(avmcard *card, capiloaddatapart *t4file)
 {
 	u32 val;
 	unsigned char *dp;
@@ -202,7 +202,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file)
 	dp = t4file->data;
 	left = t4file->len;
 	while (left >= sizeof(u32)) {
-	        if (t4file->user) {
+		if (t4file->user) {
 			if (copy_from_user(&val, dp, sizeof(val)))
 				return -EFAULT;
 		} else {
@@ -210,7 +210,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file)
 		}
 		if (c4_poke(card, loadoff, val)) {
 			printk(KERN_ERR "%s: corrupted firmware file ?\n",
-					card->name);
+			       card->name);
 			return -EIO;
 		}
 		left -= sizeof(u32);
@@ -227,7 +227,7 @@ static int c4_load_t4file(avmcard *card, capiloaddatapart * t4file)
 		}
 		if (c4_poke(card, loadoff, val)) {
 			printk(KERN_ERR "%s: corrupted firmware file ?\n",
-					card->name);
+			       card->name);
 			return -EIO;
 		}
 	}
@@ -297,13 +297,13 @@ static void c4_reset(avmcard *card)
 {
 	unsigned long stop;
 
-	c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM);
+	c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM);
 
-	stop = jiffies + HZ*10;
-	while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
+	stop = jiffies + HZ * 10;
+	while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) {
 		if (!time_before(jiffies, stop))
 			return;
-		c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
+		c4outmeml(card->mbase + DOORBELL, DBELL_ADDR);
 		mb();
 	}
 
@@ -317,89 +317,89 @@ static int c4_detect(avmcard *card)
 {
 	unsigned long stop, dummy;
 
-	c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);
-	if (c4inmeml(card->mbase+PCI_OUT_INT_MASK) != 0x0c)
+	c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c);
+	if (c4inmeml(card->mbase + PCI_OUT_INT_MASK) != 0x0c)
 		return	1;
 
-	c4outmeml(card->mbase+DOORBELL, DBELL_RESET_ARM);
+	c4outmeml(card->mbase + DOORBELL, DBELL_RESET_ARM);
 
-	stop = jiffies + HZ*10;
-	while (c4inmeml(card->mbase+DOORBELL) != 0xffffffff) {
+	stop = jiffies + HZ * 10;
+	while (c4inmeml(card->mbase + DOORBELL) != 0xffffffff) {
 		if (!time_before(jiffies, stop))
 			return 2;
-		c4outmeml(card->mbase+DOORBELL, DBELL_ADDR);
+		c4outmeml(card->mbase + DOORBELL, DBELL_ADDR);
 		mb();
 	}
 
 	c4_poke(card, DC21285_ARMCSR_BASE + CHAN_1_CONTROL, 0);
 	c4_poke(card, DC21285_ARMCSR_BASE + CHAN_2_CONTROL, 0);
 
-	c4outmeml(card->mbase+MAILBOX_0, 0x55aa55aa);
-	if (c4inmeml(card->mbase+MAILBOX_0) != 0x55aa55aa) return 3;
+	c4outmeml(card->mbase + MAILBOX_0, 0x55aa55aa);
+	if (c4inmeml(card->mbase + MAILBOX_0) != 0x55aa55aa) return 3;
 
-	c4outmeml(card->mbase+MAILBOX_0, 0xaa55aa55);
-	if (c4inmeml(card->mbase+MAILBOX_0) != 0xaa55aa55) return 4;
+	c4outmeml(card->mbase + MAILBOX_0, 0xaa55aa55);
+	if (c4inmeml(card->mbase + MAILBOX_0) != 0xaa55aa55) return 4;
 
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_SA_MASK, 0)) return 5;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DBELL_PCI_MASK, 0)) return 6;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+SA_CONTROL, SA_CTL_ALLRIGHT))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_SA_MASK, 0)) return 5;
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DBELL_PCI_MASK, 0)) return 6;
+	if (c4_poke(card, DC21285_ARMCSR_BASE + SA_CONTROL, SA_CTL_ALLRIGHT))
 		return 7;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_CYCLE, INIT_XBUS_CYCLE))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_CYCLE, INIT_XBUS_CYCLE))
 		return 8;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+XBUS_STROBE, INIT_XBUS_STROBE))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + XBUS_STROBE, INIT_XBUS_STROBE))
 		return 8;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, 0)) return 9;
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, 0)) return 9;
 
-        mdelay(1);
+	mdelay(1);
 
 	if (c4_peek(card, DC21285_DRAM_A0MR, &dummy)) return 10;
 	if (c4_peek(card, DC21285_DRAM_A1MR, &dummy)) return 11;
 	if (c4_peek(card, DC21285_DRAM_A2MR, &dummy)) return 12;
 	if (c4_peek(card, DC21285_DRAM_A3MR, &dummy)) return 13;
 
-	if (c4_poke(card, DC21285_DRAM_A0MR+CAS_OFFSET, 0)) return 14;
-	if (c4_poke(card, DC21285_DRAM_A1MR+CAS_OFFSET, 0)) return 15;
-	if (c4_poke(card, DC21285_DRAM_A2MR+CAS_OFFSET, 0)) return 16;
-	if (c4_poke(card, DC21285_DRAM_A3MR+CAS_OFFSET, 0)) return 17;
+	if (c4_poke(card, DC21285_DRAM_A0MR + CAS_OFFSET, 0)) return 14;
+	if (c4_poke(card, DC21285_DRAM_A1MR + CAS_OFFSET, 0)) return 15;
+	if (c4_poke(card, DC21285_DRAM_A2MR + CAS_OFFSET, 0)) return 16;
+	if (c4_poke(card, DC21285_DRAM_A3MR + CAS_OFFSET, 0)) return 17;
 
-        mdelay(1);
+	mdelay(1);
 
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_TIMING, DRAM_TIMING_DEF))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_TIMING, DRAM_TIMING_DEF))
 		return 18;
 
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_0,DRAM_AD_SZ_DEF0))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_0, DRAM_AD_SZ_DEF0))
 		return 19;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_1,DRAM_AD_SZ_NULL))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_1, DRAM_AD_SZ_NULL))
 		return 20;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_2,DRAM_AD_SZ_NULL))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_2, DRAM_AD_SZ_NULL))
 		return 21;
-	if (c4_poke(card, DC21285_ARMCSR_BASE+DRAM_ADDR_SIZE_3,DRAM_AD_SZ_NULL))
+	if (c4_poke(card, DC21285_ARMCSR_BASE + DRAM_ADDR_SIZE_3, DRAM_AD_SZ_NULL))
 		return 22;
 
 	/* Transputer test */
-	
-	if (   c4_poke(card, 0x000000, 0x11111111)
+
+	if (c4_poke(card, 0x000000, 0x11111111)
 	    || c4_poke(card, 0x400000, 0x22222222)
-	    || c4_poke(card, 0x800000, 0x33333333)
-	    || c4_poke(card, 0xC00000, 0x44444444))
+	       || c4_poke(card, 0x800000, 0x33333333)
+	       || c4_poke(card, 0xC00000, 0x44444444))
 		return 23;
 
-	if (   c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111
+	if (c4_peek(card, 0x000000, &dummy) || dummy != 0x11111111
 	    || c4_peek(card, 0x400000, &dummy) || dummy != 0x22222222
-	    || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333
-	    || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444)
+	       || c4_peek(card, 0x800000, &dummy) || dummy != 0x33333333
+	       || c4_peek(card, 0xC00000, &dummy) || dummy != 0x44444444)
 		return 24;
 
-	if (   c4_poke(card, 0x000000, 0x55555555)
+	if (c4_poke(card, 0x000000, 0x55555555)
 	    || c4_poke(card, 0x400000, 0x66666666)
-	    || c4_poke(card, 0x800000, 0x77777777)
-	    || c4_poke(card, 0xC00000, 0x88888888))
+	       || c4_poke(card, 0x800000, 0x77777777)
+	       || c4_poke(card, 0xC00000, 0x88888888))
 		return 25;
 
-	if (   c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555
+	if (c4_peek(card, 0x000000, &dummy) || dummy != 0x55555555
 	    || c4_peek(card, 0x400000, &dummy) || dummy != 0x66666666
-	    || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777
-	    || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888)
+	       || c4_peek(card, 0x800000, &dummy) || dummy != 0x77777777
+	       || c4_peek(card, 0xC00000, &dummy) || dummy != 0x88888888)
 		return 26;
 
 	return 0;
@@ -451,26 +451,26 @@ static void c4_dispatch_tx(avmcard *card)
 		printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen);
 #endif
 	} else {
-		txlen = skb->len-2;
+		txlen = skb->len - 2;
 #ifdef AVM_C4_POLLDEBUG
 		if (skb->data[2] == SEND_POLLACK)
 			printk(KERN_INFO "%s: ack to c4\n", card->name);
 #endif
 #ifdef AVM_C4_DEBUG
 		printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n",
-				card->name, skb->data[2], txlen);
+		       card->name, skb->data[2], txlen);
 #endif
 		skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf,
 						 skb->len - 2);
 	}
 	txlen = (txlen + 3) & ~3;
 
-	c4outmeml(card->mbase+MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr);
-	c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen);
+	c4outmeml(card->mbase + MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr);
+	c4outmeml(card->mbase + MBOX_DOWN_LEN, txlen);
 
 	card->csr |= DBELL_DOWN_ARM;
 
-	c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM);
+	c4outmeml(card->mbase + DOORBELL, DBELL_DOWN_ARM);
 
 	dev_kfree_skb_any(skb);
 }
@@ -485,7 +485,7 @@ static void queue_pollack(avmcard *card)
 	skb = alloc_skb(3, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, lost poll ack\n",
-					card->name);
+		       card->name);
 		return;
 	}
 	p = skb->data;
@@ -514,9 +514,9 @@ static void c4_handle_rx(avmcard *card)
 
 #ifdef AVM_C4_DEBUG
 	printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name,
-				b1cmd, (unsigned long)dma->recvlen);
+	       b1cmd, (unsigned long)dma->recvlen);
 #endif
-	
+
 	switch (b1cmd) {
 	case RECEIVE_DATA_B3_IND:
 
@@ -528,13 +528,13 @@ static void c4_handle_rx(avmcard *card)
 		ctrl = &card->ctrlinfo[cidx].capi_ctrl;
 
 		if (MsgLen < 30) { /* not CAPI 64Bit */
-			memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
+			memset(card->msgbuf + MsgLen, 0, 30 - MsgLen);
 			MsgLen = 30;
 			CAPIMSG_SETLEN(card->msgbuf, 30);
 		}
-		if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
+		if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+			       card->name);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 			memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
@@ -553,7 +553,7 @@ static void c4_handle_rx(avmcard *card)
 
 		if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
 			printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+			       card->name);
 		} else {
 			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 			if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
@@ -570,7 +570,7 @@ static void c4_handle_rx(avmcard *card)
 		ApplId = _get_word(&p);
 		NCCI = _get_word(&p);
 		WindowSize = _get_word(&p);
-		cidx = (NCCI&0x7f) - card->cardnr;
+		cidx = (NCCI & 0x7f) - card->cardnr;
 		if (cidx >= card->nlogcontr) cidx = 0;
 
 		capilib_new_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI, WindowSize);
@@ -583,7 +583,7 @@ static void c4_handle_rx(avmcard *card)
 		NCCI = _get_word(&p);
 
 		if (NCCI != 0xffffffff) {
-			cidx = (NCCI&0x7f) - card->cardnr;
+			cidx = (NCCI & 0x7f) - card->cardnr;
 			if (cidx >= card->nlogcontr) cidx = 0;
 			capilib_free_ncci(&card->ctrlinfo[cidx].ncci_head, ApplId, NCCI);
 		}
@@ -595,14 +595,14 @@ static void c4_handle_rx(avmcard *card)
 #endif
 		if (!suppress_pollack)
 			queue_pollack(card);
-		for (cidx=0; cidx < card->nr_controllers; cidx++) {
+		for (cidx = 0; cidx < card->nr_controllers; cidx++) {
 			ctrl = &card->ctrlinfo[cidx].capi_ctrl;
 			capi_ctr_resume_output(ctrl);
 		}
 		break;
 
 	case RECEIVE_STOP:
-		for (cidx=0; cidx < card->nr_controllers; cidx++) {
+		for (cidx = 0; cidx < card->nr_controllers; cidx++) {
 			ctrl = &card->ctrlinfo[cidx].capi_ctrl;
 			capi_ctr_suspend_output(ctrl);
 		}
@@ -610,14 +610,14 @@ static void c4_handle_rx(avmcard *card)
 
 	case RECEIVE_INIT:
 
-	        cidx = card->nlogcontr;
+		cidx = card->nlogcontr;
 		if (cidx >= card->nr_controllers) {
 			printk(KERN_ERR "%s: card with %d controllers ??\n",
-					card->name, cidx+1);
+			       card->name, cidx + 1);
 			break;
 		}
-	        card->nlogcontr++;
-	        cinfo = &card->ctrlinfo[cidx];
+		card->nlogcontr++;
+		cinfo = &card->ctrlinfo[cidx];
 		ctrl = &cinfo->capi_ctrl;
 		cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
 		b1_parse_version(cinfo);
@@ -632,23 +632,23 @@ static void c4_handle_rx(avmcard *card)
 		ApplId = (unsigned) _get_word(&p);
 		MsgLen = _get_slice(&p, card->msgbuf);
 		card->msgbuf[MsgLen] = 0;
-		while (    MsgLen > 0
-		       && (   card->msgbuf[MsgLen-1] == '\n'
-			   || card->msgbuf[MsgLen-1] == '\r')) {
-			card->msgbuf[MsgLen-1] = 0;
+		while (MsgLen > 0
+		       && (card->msgbuf[MsgLen - 1] == '\n'
+			   || card->msgbuf[MsgLen - 1] == '\r')) {
+			card->msgbuf[MsgLen - 1] = 0;
 			MsgLen--;
 		}
 		printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
-				card->name, ApplId, card->msgbuf);
+		       card->name, ApplId, card->msgbuf);
 		break;
 
 	case RECEIVE_DEBUGMSG:
 		MsgLen = _get_slice(&p, card->msgbuf);
 		card->msgbuf[MsgLen] = 0;
-		while (    MsgLen > 0
-		       && (   card->msgbuf[MsgLen-1] == '\n'
-			   || card->msgbuf[MsgLen-1] == '\r')) {
-			card->msgbuf[MsgLen-1] = 0;
+		while (MsgLen > 0
+		       && (card->msgbuf[MsgLen - 1] == '\n'
+			   || card->msgbuf[MsgLen - 1] == '\r')) {
+			card->msgbuf[MsgLen - 1] = 0;
 			MsgLen--;
 		}
 		printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
@@ -656,7 +656,7 @@ static void c4_handle_rx(avmcard *card)
 
 	default:
 		printk(KERN_ERR "%s: c4_interrupt: 0x%x ???\n",
-				card->name, b1cmd);
+		       card->name, b1cmd);
 		return;
 	}
 }
@@ -669,16 +669,16 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
 	u32 status;
 
 	spin_lock_irqsave(&card->lock, flags);
-	status = c4inmeml(card->mbase+DOORBELL);
+	status = c4inmeml(card->mbase + DOORBELL);
 
 	if (status & DBELL_RESET_HOST) {
 		u_int i;
-		c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x0c);
+		c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x0c);
 		spin_unlock_irqrestore(&card->lock, flags);
 		if (card->nlogcontr == 0)
 			return IRQ_HANDLED;
 		printk(KERN_ERR "%s: unexpected reset\n", card->name);
-                for (i=0; i < card->nr_controllers; i++) {
+		for (i = 0; i < card->nr_controllers; i++) {
 			avmctrl_info *cinfo = &card->ctrlinfo[i];
 			memset(cinfo->version, 0, sizeof(cinfo->version));
 			spin_lock_irqsave(&card->lock, flags);
@@ -695,23 +695,23 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
 		spin_unlock_irqrestore(&card->lock, flags);
 		return IRQ_HANDLED;
 	}
-	c4outmeml(card->mbase+DOORBELL, status);
+	c4outmeml(card->mbase + DOORBELL, status);
 
 	if ((status & DBELL_UP_HOST) != 0) {
-		card->dma->recvlen = c4inmeml(card->mbase+MBOX_UP_LEN);
-		c4outmeml(card->mbase+MBOX_UP_LEN, 0);
+		card->dma->recvlen = c4inmeml(card->mbase + MBOX_UP_LEN);
+		c4outmeml(card->mbase + MBOX_UP_LEN, 0);
 		c4_handle_rx(card);
 		card->dma->recvlen = 0;
-		c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size);
-		c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);
+		c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size);
+		c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM);
 	}
 
 	if ((status & DBELL_DOWN_HOST) != 0) {
 		card->csr &= ~DBELL_DOWN_ARM;
-	        c4_dispatch_tx(card);
+		c4_dispatch_tx(card);
 	} else if (card->csr & DBELL_DOWN_HOST) {
-		if (c4inmeml(card->mbase+MBOX_DOWN_LEN) == 0) {
-		        card->csr &= ~DBELL_DOWN_ARM;
+		if (c4inmeml(card->mbase + MBOX_DOWN_LEN) == 0) {
+			card->csr &= ~DBELL_DOWN_ARM;
 			c4_dispatch_tx(card);
 		}
 	}
@@ -737,7 +737,7 @@ static void c4_send_init(avmcard *card)
 	skb = alloc_skb(15, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, lost register appl.\n",
-					card->name);
+		       card->name);
 		return;
 	}
 	p = skb->data;
@@ -745,7 +745,7 @@ static void c4_send_init(avmcard *card)
 	_put_byte(&p, 0);
 	_put_byte(&p, SEND_INIT);
 	_put_word(&p, CAPI_MAXAPPL);
-	_put_word(&p, AVM_NCCI_PER_CHANNEL*30);
+	_put_word(&p, AVM_NCCI_PER_CHANNEL * 30);
 	_put_word(&p, card->cardnr - 1);
 	skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
@@ -761,10 +761,10 @@ static int queue_sendconfigword(avmcard *card, u32 val)
 	unsigned long flags;
 	void *p;
 
-	skb = alloc_skb(3+4, GFP_ATOMIC);
+	skb = alloc_skb(3 + 4, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, send config\n",
-					card->name);
+		       card->name);
 		return -ENOMEM;
 	}
 	p = skb->data;
@@ -787,10 +787,10 @@ static int queue_sendconfig(avmcard *card, char cval[4])
 	unsigned long flags;
 	void *p;
 
-	skb = alloc_skb(3+4, GFP_ATOMIC);
+	skb = alloc_skb(3 + 4, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_CRIT "%s: no memory, send config\n",
-					card->name);
+		       card->name);
 		return -ENOMEM;
 	}
 	p = skb->data;
@@ -804,20 +804,20 @@ static int queue_sendconfig(avmcard *card, char cval[4])
 	skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
 	skb_queue_tail(&card->dma->send_queue, skb);
-	
+
 	spin_lock_irqsave(&card->lock, flags);
 	c4_dispatch_tx(card);
 	spin_unlock_irqrestore(&card->lock, flags);
 	return 0;
 }
 
-static int c4_send_config(avmcard *card, capiloaddatapart * config)
+static int c4_send_config(avmcard *card, capiloaddatapart *config)
 {
 	u8 val[4];
 	unsigned char *dp;
 	u_int left;
 	int retval;
-	
+
 	if ((retval = queue_sendconfigword(card, 1)) != 0)
 		return retval;
 	if ((retval = queue_sendconfigword(card, config->len)) != 0)
@@ -826,7 +826,7 @@ static int c4_send_config(avmcard *card, capiloaddatapart * config)
 	dp = config->data;
 	left = config->len;
 	while (left >= sizeof(u32)) {
-	        if (config->user) {
+		if (config->user) {
 			if (copy_from_user(val, dp, sizeof(val)))
 				return -EFAULT;
 		} else {
@@ -860,37 +860,37 @@ static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 
 	if ((retval = c4_load_t4file(card, &data->firmware))) {
 		printk(KERN_ERR "%s: failed to load t4file!!\n",
-					card->name);
+		       card->name);
 		c4_reset(card);
 		return retval;
 	}
 
 	card->csr = 0;
-	c4outmeml(card->mbase+MBOX_UP_LEN, 0);
-	c4outmeml(card->mbase+MBOX_DOWN_LEN, 0);
-	c4outmeml(card->mbase+DOORBELL, DBELL_INIT);
+	c4outmeml(card->mbase + MBOX_UP_LEN, 0);
+	c4outmeml(card->mbase + MBOX_DOWN_LEN, 0);
+	c4outmeml(card->mbase + DOORBELL, DBELL_INIT);
 	mdelay(1);
-	c4outmeml(card->mbase+DOORBELL,
-			DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST);
+	c4outmeml(card->mbase + DOORBELL,
+		  DBELL_UP_HOST | DBELL_DOWN_HOST | DBELL_RESET_HOST);
 
-	c4outmeml(card->mbase+PCI_OUT_INT_MASK, 0x08);
+	c4outmeml(card->mbase + PCI_OUT_INT_MASK, 0x08);
 
 	card->dma->recvlen = 0;
-	c4outmeml(card->mbase+MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr);
-	c4outmeml(card->mbase+MBOX_UP_LEN, card->dma->recvbuf.size);
-	c4outmeml(card->mbase+DOORBELL, DBELL_UP_ARM);
+	c4outmeml(card->mbase + MBOX_UP_ADDR, card->dma->recvbuf.dmaaddr);
+	c4outmeml(card->mbase + MBOX_UP_LEN, card->dma->recvbuf.size);
+	c4outmeml(card->mbase + DOORBELL, DBELL_UP_ARM);
 
 	if (data->configuration.len > 0 && data->configuration.data) {
 		retval = c4_send_config(card, &data->configuration);
 		if (retval) {
 			printk(KERN_ERR "%s: failed to set config!!\n",
-					card->name);
+			       card->name);
 			c4_reset(card);
 			return retval;
 		}
 	}
 
-        c4_send_init(card);
+	c4_send_init(card);
 
 	return 0;
 }
@@ -905,11 +905,11 @@ static void c4_reset_ctr(struct capi_ctr *ctrl)
 
 	spin_lock_irqsave(&card->lock, flags);
 
- 	c4_reset(card);
+	c4_reset(card);
 
 	spin_unlock_irqrestore(&card->lock, flags);
 
-        for (i=0; i < card->nr_controllers; i++) {
+	for (i = 0; i < card->nr_controllers; i++) {
 		cinfo = &card->ctrlinfo[i];
 		memset(cinfo->version, 0, sizeof(cinfo->version));
 		capi_ctr_down(&cinfo->capi_ctrl);
@@ -926,9 +926,9 @@ static void c4_remove(struct pci_dev *pdev)
 	if (!card)
 		return;
 
- 	c4_reset(card);
+	c4_reset(card);
 
-        for (i=0; i < card->nr_controllers; i++) {
+	for (i = 0; i < card->nr_controllers; i++) {
 		cinfo = &card->ctrlinfo[i];
 		detach_capi_ctr(&cinfo->capi_ctrl);
 	}
@@ -936,8 +936,8 @@ static void c4_remove(struct pci_dev *pdev)
 	free_irq(card->irq, card);
 	iounmap(card->mbase);
 	release_region(card->port, AVMB1_PORTLEN);
-        avmcard_dma_free(card->dma);
-        pci_set_drvdata(pdev, NULL);
+	avmcard_dma_free(card->dma);
+	pci_set_drvdata(pdev, NULL);
 	b1_free_card(card);
 }
 
@@ -945,8 +945,8 @@ static void c4_remove(struct pci_dev *pdev)
 
 
 static void c4_register_appl(struct capi_ctr *ctrl,
-				u16 appl,
-				capi_register_params *rp)
+			     u16 appl,
+			     capi_register_params *rp)
 {
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
@@ -965,7 +965,7 @@ static void c4_register_appl(struct capi_ctr *ctrl,
 		skb = alloc_skb(23, GFP_ATOMIC);
 		if (!skb) {
 			printk(KERN_CRIT "%s: no memory, lost register appl.\n",
-						card->name);
+			       card->name);
 			return;
 		}
 		p = skb->data;
@@ -973,14 +973,14 @@ static void c4_register_appl(struct capi_ctr *ctrl,
 		_put_byte(&p, 0);
 		_put_byte(&p, SEND_REGISTER);
 		_put_word(&p, appl);
-		_put_word(&p, 1024 * (nconn+1));
+		_put_word(&p, 1024 * (nconn + 1));
 		_put_word(&p, nconn);
 		_put_word(&p, rp->datablkcnt);
 		_put_word(&p, rp->datablklen);
 		skb_put(skb, (u8 *)p - (u8 *)skb->data);
 
 		skb_queue_tail(&card->dma->send_queue, skb);
-	
+
 		spin_lock_irqsave(&card->lock, flags);
 		c4_dispatch_tx(card);
 		spin_unlock_irqrestore(&card->lock, flags);
@@ -1005,7 +1005,7 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
 		skb = alloc_skb(7, GFP_ATOMIC);
 		if (!skb) {
 			printk(KERN_CRIT "%s: no memory, lost release appl.\n",
-						card->name);
+			       card->name);
 			return;
 		}
 		p = skb->data;
@@ -1098,29 +1098,29 @@ static int c4_proc_show(struct seq_file *m, void *v)
 		seq_printf(m, "%-16s %s\n", "ver_serial", s);
 
 	if (card->cardtype != avm_m1) {
-        	flag = ((u8 *)(ctrl->profile.manu))[3];
-        	if (flag)
+		flag = ((u8 *)(ctrl->profile.manu))[3];
+		if (flag)
 			seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
-			"protocol",
-			(flag & 0x01) ? " DSS1" : "",
-			(flag & 0x02) ? " CT1" : "",
-			(flag & 0x04) ? " VN3" : "",
-			(flag & 0x08) ? " NI1" : "",
-			(flag & 0x10) ? " AUSTEL" : "",
-			(flag & 0x20) ? " ESS" : "",
-			(flag & 0x40) ? " 1TR6" : ""
-			);
+				   "protocol",
+				   (flag & 0x01) ? " DSS1" : "",
+				   (flag & 0x02) ? " CT1" : "",
+				   (flag & 0x04) ? " VN3" : "",
+				   (flag & 0x08) ? " NI1" : "",
+				   (flag & 0x10) ? " AUSTEL" : "",
+				   (flag & 0x20) ? " ESS" : "",
+				   (flag & 0x40) ? " 1TR6" : ""
+				);
 	}
 	if (card->cardtype != avm_m1) {
-        	flag = ((u8 *)(ctrl->profile.manu))[5];
+		flag = ((u8 *)(ctrl->profile.manu))[5];
 		if (flag)
 			seq_printf(m, "%-16s%s%s%s%s\n",
-			"linetype",
-			(flag & 0x01) ? " point to point" : "",
-			(flag & 0x02) ? " point to multipoint" : "",
-			(flag & 0x08) ? " leased line without D-channel" : "",
-			(flag & 0x04) ? " leased line with D-channel" : ""
-			);
+				   "linetype",
+				   (flag & 0x01) ? " point to point" : "",
+				   (flag & 0x02) ? " point to multipoint" : "",
+				   (flag & 0x08) ? " leased line without D-channel" : "",
+				   (flag & 0x04) ? " leased line with D-channel" : ""
+				);
 	}
 	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
 
@@ -1156,7 +1156,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
 		retval = -ENOMEM;
 		goto err;
 	}
-        card->dma = avmcard_dma_alloc("c4", dev, 2048+128, 2048+128);
+	card->dma = avmcard_dma_alloc("c4", dev, 2048 + 128, 2048 + 128);
 	if (!card->dma) {
 		printk(KERN_WARNING "c4: no memory.\n");
 		retval = -ENOMEM;
@@ -1195,12 +1195,12 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
 
 	retval = request_irq(card->irq, c4_interrupt, IRQF_SHARED, card->name, card);
 	if (retval) {
-		printk(KERN_ERR "c4: unable to get IRQ %d.\n",card->irq);
+		printk(KERN_ERR "c4: unable to get IRQ %d.\n", card->irq);
 		retval = -EBUSY;
 		goto err_unmap;
 	}
 
-	for (i=0; i < nr_controllers ; i++) {
+	for (i = 0; i < nr_controllers; i++) {
 		cinfo = &card->ctrlinfo[i];
 		cinfo->capi_ctrl.owner = THIS_MODULE;
 		cinfo->capi_ctrl.driver_name   = "c4";
@@ -1233,17 +1233,17 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
 	pci_set_drvdata(dev, card);
 	return 0;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_unmap:
+err_unmap:
 	iounmap(card->mbase);
- err_release_region:
+err_release_region:
 	release_region(card->port, AVMB1_PORTLEN);
- err_free_dma:
+err_free_dma:
 	avmcard_dma_free(card->dma);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 }
 
@@ -1265,10 +1265,10 @@ static int __devinit c4_probe(struct pci_dev *dev,
 	param.port = pci_resource_start(dev, 1);
 	param.irq = dev->irq;
 	param.membase = pci_resource_start(dev, 0);
-	
+
 	printk(KERN_INFO "c4: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n",
 	       nr, param.port, param.irq, param.membase);
-	
+
 	retval = c4_add_card(&param, dev, nr);
 	if (retval != 0) {
 		printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n",
@@ -1280,10 +1280,10 @@ static int __devinit c4_probe(struct pci_dev *dev,
 }
 
 static struct pci_driver c4_pci_driver = {
-       .name           = "c4",
-       .id_table       = c4_pci_tbl,
-       .probe          = c4_probe,
-       .remove         = c4_remove,
+	.name           = "c4",
+	.id_table       = c4_pci_tbl,
+	.probe          = c4_probe,
+	.remove         = c4_remove,
 };
 
 static struct capi_driver capi_driver_c2 = {
@@ -1305,7 +1305,7 @@ static int __init c4_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index 08216b1..72ef188 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -1,9 +1,9 @@
 /* $Id: t1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
- * 
+ *
  * Module for AVM T1 HEMA-card.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -67,7 +67,7 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
 	int i;
 
 	reverse_cardnr =   ((cardnr & 0x01) << 3) | ((cardnr & 0x02) << 1)
-		         | ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);
+		| ((cardnr & 0x04) >> 1) | ((cardnr & 0x08) >> 3);
 	cregs[0] = (HEMA_VERSION_ID << 4) | (reverse_cardnr & 0xf);
 	cregs[1] = 0x00; /* fast & slow link connected to CON1 */
 	cregs[2] = 0x05; /* fast link 20MBit, slow link 20 MBit */
@@ -86,50 +86,50 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
 	/* board reset */
 	t1outp(base, T1_RESETBOARD, 0xf);
 	mdelay(100);
-	dummy = t1inp(base, T1_FASTLINK+T1_OUTSTAT); /* first read */
+	dummy = t1inp(base, T1_FASTLINK + T1_OUTSTAT); /* first read */
 
 	/* write config */
 	dummy = (base >> 4) & 0xff;
-	for (i=1;i<=0xf;i++) t1outp(base, i, dummy);
+	for (i = 1; i <= 0xf; i++) t1outp(base, i, dummy);
 	t1outp(base, HEMA_PAL_ID & 0xf, dummy);
 	t1outp(base, HEMA_PAL_ID >> 4, cregs[0]);
-	for(i=1;i<7;i++) t1outp(base, 0, cregs[i]);
+	for (i = 1; i < 7; i++) t1outp(base, 0, cregs[i]);
 	t1outp(base, ((base >> 4)) & 0x3, cregs[7]);
 	/* restore_flags(flags); */
 
 	mdelay(100);
-	t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
-	t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
+	t1outp(base, T1_FASTLINK + T1_RESETLINK, 0);
+	t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0);
 	mdelay(10);
-	t1outp(base, T1_FASTLINK+T1_RESETLINK, 1);
-	t1outp(base, T1_SLOWLINK+T1_RESETLINK, 1);
+	t1outp(base, T1_FASTLINK + T1_RESETLINK, 1);
+	t1outp(base, T1_SLOWLINK + T1_RESETLINK, 1);
 	mdelay(100);
-	t1outp(base, T1_FASTLINK+T1_RESETLINK, 0);
-	t1outp(base, T1_SLOWLINK+T1_RESETLINK, 0);
+	t1outp(base, T1_FASTLINK + T1_RESETLINK, 0);
+	t1outp(base, T1_SLOWLINK + T1_RESETLINK, 0);
 	mdelay(10);
-	t1outp(base, T1_FASTLINK+T1_ANALYSE, 0);
+	t1outp(base, T1_FASTLINK + T1_ANALYSE, 0);
 	mdelay(5);
-	t1outp(base, T1_SLOWLINK+T1_ANALYSE, 0);
+	t1outp(base, T1_SLOWLINK + T1_ANALYSE, 0);
 
-	if (t1inp(base, T1_FASTLINK+T1_OUTSTAT) != 0x1) /* tx empty */
+	if (t1inp(base, T1_FASTLINK + T1_OUTSTAT) != 0x1) /* tx empty */
 		return 1;
-	if (t1inp(base, T1_FASTLINK+T1_INSTAT) != 0x0) /* rx empty */
+	if (t1inp(base, T1_FASTLINK + T1_INSTAT) != 0x0) /* rx empty */
 		return 2;
-	if (t1inp(base, T1_FASTLINK+T1_IRQENABLE) != 0x0)
+	if (t1inp(base, T1_FASTLINK + T1_IRQENABLE) != 0x0)
 		return 3;
-	if ((t1inp(base, T1_FASTLINK+T1_FIFOSTAT) & 0xf0) != 0x70)
+	if ((t1inp(base, T1_FASTLINK + T1_FIFOSTAT) & 0xf0) != 0x70)
 		return 4;
-	if ((t1inp(base, T1_FASTLINK+T1_IRQMASTER) & 0x0e) != 0)
+	if ((t1inp(base, T1_FASTLINK + T1_IRQMASTER) & 0x0e) != 0)
 		return 5;
-	if ((t1inp(base, T1_FASTLINK+T1_IDENT) & 0x7d) != 1)
+	if ((t1inp(base, T1_FASTLINK + T1_IDENT) & 0x7d) != 1)
 		return 6;
-	if (t1inp(base, T1_SLOWLINK+T1_OUTSTAT) != 0x1) /* tx empty */
+	if (t1inp(base, T1_SLOWLINK + T1_OUTSTAT) != 0x1) /* tx empty */
 		return 7;
-	if ((t1inp(base, T1_SLOWLINK+T1_IRQMASTER) & 0x0e) != 0)
+	if ((t1inp(base, T1_SLOWLINK + T1_IRQMASTER) & 0x0e) != 0)
 		return 8;
-	if ((t1inp(base, T1_SLOWLINK+T1_IDENT) & 0x7d) != 0)
+	if ((t1inp(base, T1_SLOWLINK + T1_IDENT) & 0x7d) != 0)
 		return 9;
-        return 0;
+	return 0;
 }
 
 static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
@@ -163,13 +163,13 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
 			spin_unlock_irqrestore(&card->lock, flags);
 
 			if (MsgLen < 30) { /* not CAPI 64Bit */
-				memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
+				memset(card->msgbuf + MsgLen, 0, 30 - MsgLen);
 				MsgLen = 30;
 				CAPIMSG_SETLEN(card->msgbuf, 30);
 			}
-			if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
+			if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
 				printk(KERN_ERR "%s: incoming packet dropped\n",
-					card->name);
+				       card->name);
 			} else {
 				memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 				memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
@@ -184,7 +184,7 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
 			if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
 				spin_unlock_irqrestore(&card->lock, flags);
 				printk(KERN_ERR "%s: incoming packet dropped\n",
-						card->name);
+				       card->name);
 			} else {
 				memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
 				if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3)
@@ -242,24 +242,24 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
 			MsgLen = t1_get_slice(card->port, card->msgbuf);
 			spin_unlock_irqrestore(&card->lock, flags);
 			card->msgbuf[MsgLen] = 0;
-			while (    MsgLen > 0
-			       && (   card->msgbuf[MsgLen-1] == '\n'
-				   || card->msgbuf[MsgLen-1] == '\r')) {
-				card->msgbuf[MsgLen-1] = 0;
+			while (MsgLen > 0
+			       && (card->msgbuf[MsgLen - 1] == '\n'
+				   || card->msgbuf[MsgLen - 1] == '\r')) {
+				card->msgbuf[MsgLen - 1] = 0;
 				MsgLen--;
 			}
 			printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
-					card->name, ApplId, card->msgbuf);
+			       card->name, ApplId, card->msgbuf);
 			break;
 
 		case RECEIVE_DEBUGMSG:
 			MsgLen = t1_get_slice(card->port, card->msgbuf);
 			spin_unlock_irqrestore(&card->lock, flags);
 			card->msgbuf[MsgLen] = 0;
-			while (    MsgLen > 0
-			       && (   card->msgbuf[MsgLen-1] == '\n'
-				   || card->msgbuf[MsgLen-1] == '\r')) {
-				card->msgbuf[MsgLen-1] = 0;
+			while (MsgLen > 0
+			       && (card->msgbuf[MsgLen - 1] == '\n'
+				   || card->msgbuf[MsgLen - 1] == '\r')) {
+				card->msgbuf[MsgLen - 1] = 0;
 				MsgLen--;
 			}
 			printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
@@ -273,7 +273,7 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
 		default:
 			spin_unlock_irqrestore(&card->lock, flags);
 			printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n",
-					card->name, b1cmd);
+			       card->name, b1cmd);
 			return IRQ_NONE;
 		}
 	}
@@ -296,7 +296,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 	if ((retval = b1_load_t4file(card, &data->firmware))) {
 		b1_reset(port);
 		printk(KERN_ERR "%s: failed to load t4file!!\n",
-					card->name);
+		       card->name);
 		return retval;
 	}
 
@@ -304,7 +304,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 		if ((retval = b1_load_config(card, &data->configuration))) {
 			b1_reset(port);
 			printk(KERN_ERR "%s: failed to load config!!\n",
-					card->name);
+			       card->name);
 			return retval;
 		}
 	}
@@ -318,7 +318,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 	b1_setinterrupt(port, card->irq, card->cardtype);
 	b1_put_byte(port, SEND_INIT);
 	b1_put_word(port, CAPI_MAXAPPL);
-	b1_put_word(port, AVM_NCCI_PER_CHANNEL*30);
+	b1_put_word(port, AVM_NCCI_PER_CHANNEL * 30);
 	b1_put_word(port, ctrl->cnr - 1);
 	spin_unlock_irqrestore(&card->lock, flags);
 
@@ -347,7 +347,7 @@ static void t1isa_remove(struct pci_dev *pdev)
 {
 	avmctrl_info *cinfo = pci_get_drvdata(pdev);
 	avmcard *card;
-	
+
 	if (!cinfo)
 		return;
 
@@ -393,7 +393,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr)
 		printk(KERN_WARNING "t1isa: invalid port 0x%x.\n", card->port);
 		retval = -EINVAL;
 		goto err_free;
-        }
+	}
 	if (hema_irq_table[card->irq & 0xf] == 0) {
 		printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq);
 		retval = -EINVAL;
@@ -412,7 +412,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr)
 		goto err_release_region;
 	}
 
-        if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) {
+	if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) {
 		printk(KERN_INFO "t1isa: NO card at 0x%x (%d)\n",
 		       card->port, retval);
 		retval = -ENODEV;
@@ -445,13 +445,13 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr)
 	pci_set_drvdata(pdev, cinfo);
 	return 0;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_release_region:
+err_release_region:
 	release_region(card->port, AVMB1_PORTLEN);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 }
 
@@ -555,7 +555,7 @@ static int __init t1isa_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c
index a79eb5a..cb9a304 100644
--- a/drivers/isdn/hardware/avm/t1pci.c
+++ b/drivers/isdn/hardware/avm/t1pci.c
@@ -1,9 +1,9 @@
 /* $Id: t1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
- * 
+ *
  * Module for AVM T1 PCI-card.
- * 
+ *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -59,7 +59,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
 		goto err;
 	}
 
-        card->dma = avmcard_dma_alloc("t1pci", pdev, 2048+128, 2048+128);
+	card->dma = avmcard_dma_alloc("t1pci", pdev, 2048 + 128, 2048 + 128);
 	if (!card->dma) {
 		printk(KERN_WARNING "t1pci: no memory.\n");
 		retval = -ENOMEM;
@@ -136,17 +136,17 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
 	pci_set_drvdata(pdev, card);
 	return 0;
 
- err_free_irq:
+err_free_irq:
 	free_irq(card->irq, card);
- err_unmap:
+err_unmap:
 	iounmap(card->mbase);
- err_release_region:
+err_release_region:
 	release_region(card->port, AVMB1_PORTLEN);
- err_free_dma:
+err_free_dma:
 	avmcard_dma_free(card->dma);
- err_free:
+err_free:
 	b1_free_card(card);
- err:
+err:
 	return retval;
 }
 
@@ -157,7 +157,7 @@ static void t1pci_remove(struct pci_dev *pdev)
 	avmcard *card = pci_get_drvdata(pdev);
 	avmctrl_info *cinfo = card->ctrlinfo;
 
- 	b1dma_reset(card);
+	b1dma_reset(card);
 
 	detach_capi_ctr(&cinfo->capi_ctrl);
 	free_irq(card->irq, card);
@@ -217,10 +217,10 @@ static int __devinit t1pci_probe(struct pci_dev *dev,
 }
 
 static struct pci_driver t1pci_pci_driver = {
-       .name           = "t1pci",
-       .id_table       = t1pci_pci_tbl,
-       .probe          = t1pci_probe,
-       .remove         = t1pci_remove,
+	.name           = "t1pci",
+	.id_table       = t1pci_pci_tbl,
+	.probe          = t1pci_probe,
+	.remove         = t1pci_remove,
 };
 
 static struct capi_driver capi_driver_t1pci = {
@@ -237,7 +237,7 @@ static int __init t1pci_init(void)
 	if ((p = strchr(revision, ':')) != NULL && p[1]) {
 		strlcpy(rev, p + 2, 32);
 		if ((p = strchr(rev, '$')) != NULL && p > rev)
-		   *(p-1) = 0;
+			*(p - 1) = 0;
 	} else
 		strcpy(rev, "1.0");
 
diff --git a/drivers/isdn/hardware/eicon/capi20.h b/drivers/isdn/hardware/eicon/capi20.h
index 7ebcccd..391e417 100644
--- a/drivers/isdn/hardware/eicon/capi20.h
+++ b/drivers/isdn/hardware/eicon/capi20.h
@@ -1,74 +1,74 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 _INC_CAPI20  
+#ifndef _INC_CAPI20
 #define _INC_CAPI20
-        /* operations on message queues                             */
-        /* the common device type for CAPI20 drivers */
+/* operations on message queues                             */
+/* the common device type for CAPI20 drivers */
 #define FILE_DEVICE_CAPI20 0x8001
-        /* DEVICE_CONTROL codes for user and kernel mode applications */
+/* DEVICE_CONTROL codes for user and kernel mode applications */
 #define CAPI20_CTL_REGISTER             0x0801
 #define CAPI20_CTL_RELEASE              0x0802
 #define CAPI20_CTL_GET_MANUFACTURER     0x0805
 #define CAPI20_CTL_GET_VERSION          0x0806
 #define CAPI20_CTL_GET_SERIAL           0x0807
 #define CAPI20_CTL_GET_PROFILE          0x0808
-        /* INTERNAL_DEVICE_CONTROL codes for kernel mode applicatios only */
+/* INTERNAL_DEVICE_CONTROL codes for kernel mode applicatios only */
 #define CAPI20_CTL_PUT_MESSAGE          0x0803
 #define CAPI20_CTL_GET_MESSAGE          0x0804
-        /* the wrapped codes as required by the system */
-#define CAPI_CTL_CODE(f,m)              CTL_CODE(FILE_DEVICE_CAPI20,f,m,FILE_ANY_ACCESS)
-#define IOCTL_CAPI_REGISTER             CAPI_CTL_CODE(CAPI20_CTL_REGISTER,METHOD_BUFFERED)
-#define IOCTL_CAPI_RELEASE              CAPI_CTL_CODE(CAPI20_CTL_RELEASE,METHOD_BUFFERED)
-#define IOCTL_CAPI_GET_MANUFACTURER     CAPI_CTL_CODE(CAPI20_CTL_GET_MANUFACTURER,METHOD_BUFFERED)
-#define IOCTL_CAPI_GET_VERSION          CAPI_CTL_CODE(CAPI20_CTL_GET_VERSION,METHOD_BUFFERED)
-#define IOCTL_CAPI_GET_SERIAL           CAPI_CTL_CODE(CAPI20_CTL_GET_SERIAL,METHOD_BUFFERED)
-#define IOCTL_CAPI_GET_PROFILE          CAPI_CTL_CODE(CAPI20_CTL_GET_PROFILE,METHOD_BUFFERED)
-#define IOCTL_CAPI_PUT_MESSAGE          CAPI_CTL_CODE(CAPI20_CTL_PUT_MESSAGE,METHOD_BUFFERED)
-#define IOCTL_CAPI_GET_MESSAGE          CAPI_CTL_CODE(CAPI20_CTL_GET_MESSAGE,METHOD_BUFFERED)
+/* the wrapped codes as required by the system */
+#define CAPI_CTL_CODE(f, m)             CTL_CODE(FILE_DEVICE_CAPI20, f, m, FILE_ANY_ACCESS)
+#define IOCTL_CAPI_REGISTER             CAPI_CTL_CODE(CAPI20_CTL_REGISTER, METHOD_BUFFERED)
+#define IOCTL_CAPI_RELEASE              CAPI_CTL_CODE(CAPI20_CTL_RELEASE, METHOD_BUFFERED)
+#define IOCTL_CAPI_GET_MANUFACTURER     CAPI_CTL_CODE(CAPI20_CTL_GET_MANUFACTURER, METHOD_BUFFERED)
+#define IOCTL_CAPI_GET_VERSION          CAPI_CTL_CODE(CAPI20_CTL_GET_VERSION, METHOD_BUFFERED)
+#define IOCTL_CAPI_GET_SERIAL           CAPI_CTL_CODE(CAPI20_CTL_GET_SERIAL, METHOD_BUFFERED)
+#define IOCTL_CAPI_GET_PROFILE          CAPI_CTL_CODE(CAPI20_CTL_GET_PROFILE, METHOD_BUFFERED)
+#define IOCTL_CAPI_PUT_MESSAGE          CAPI_CTL_CODE(CAPI20_CTL_PUT_MESSAGE, METHOD_BUFFERED)
+#define IOCTL_CAPI_GET_MESSAGE          CAPI_CTL_CODE(CAPI20_CTL_GET_MESSAGE, METHOD_BUFFERED)
 struct divas_capi_register_params  {
-  word MessageBufferSize;
-  word maxLogicalConnection;
-  word maxBDataBlocks;
-  word maxBDataLen;
+	word MessageBufferSize;
+	word maxLogicalConnection;
+	word maxBDataBlocks;
+	word maxBDataLen;
 };
 struct divas_capi_version  {
-  word CapiMajor;
-  word CapiMinor;
-  word ManuMajor;
-  word ManuMinor;
+	word CapiMajor;
+	word CapiMinor;
+	word ManuMajor;
+	word ManuMinor;
 };
 typedef struct api_profile_s {
-  word          Number;
-  word          Channels;
-  dword         Global_Options;
-  dword         B1_Protocols;
-  dword         B2_Protocols;
-  dword         B3_Protocols;
+	word          Number;
+	word          Channels;
+	dword         Global_Options;
+	dword         B1_Protocols;
+	dword         B2_Protocols;
+	dword         B3_Protocols;
 } API_PROFILE;
-        /* ISDN Common API message types                            */
+/* ISDN Common API message types                            */
 #define _ALERT_R                        0x8001
 #define _CONNECT_R                      0x8002
 #define _CONNECT_I                      0x8202
@@ -93,9 +93,9 @@ typedef struct api_profile_s {
 #define _CONNECT_B3_T90_ACTIVE_I        0x8288
 #define _MANUFACTURER_R                 0x80ff
 #define _MANUFACTURER_I                 0x82ff
-        /* OR this to convert a REQUEST to a CONFIRM                */
+/* OR this to convert a REQUEST to a CONFIRM                */
 #define CONFIRM                 0x0100
-        /* OR this to convert a INDICATION to a RESPONSE            */
+/* OR this to convert a INDICATION to a RESPONSE            */
 #define RESPONSE                0x0100
 /*------------------------------------------------------------------*/
 /* diehl isdn private MANUFACTURER codes                            */
@@ -115,248 +115,248 @@ typedef struct api_profile_s {
 /*------------------------------------------------------------------*/
 /* parameter structures                                             */
 /*------------------------------------------------------------------*/
-        /* ALERT-REQUEST                                            */
+/* ALERT-REQUEST                                            */
 typedef struct {
-  byte structs[1];      /* Additional Info */
+	byte structs[0];      /* Additional Info */
 } _ALT_REQP;
-        /* ALERT-CONFIRM                                            */
+/* ALERT-CONFIRM                                            */
 typedef struct {
-  word Info;
+	word Info;
 } _ALT_CONP;
-        /* CONNECT-REQUEST                                          */
-typedef struct {
-  word CIP_Value;
-  byte structs[1];      /* Called party number,
-                           Called party subaddress,
-                           Calling party number,
-                           Calling party subaddress,
-                           B_protocol,
-                           BC,
-                           LLC,
-                           HLC,
-                           Additional Info */
+/* CONNECT-REQUEST                                          */
+typedef struct {
+	word CIP_Value;
+	byte structs[0];      /* Called party number,
+				 Called party subaddress,
+				 Calling party number,
+				 Calling party subaddress,
+				 B_protocol,
+				 BC,
+				 LLC,
+				 HLC,
+				 Additional Info */
 } _CON_REQP;
-        /* CONNECT-CONFIRM                                          */
+/* CONNECT-CONFIRM                                          */
 typedef struct {
-  word Info;
+	word Info;
 } _CON_CONP;
-        /* CONNECT-INDICATION                                       */
-typedef struct {
-  word CIP_Value;
-  byte structs[1];      /* Called party number,
-                           Called party subaddress,
-                           Calling party number,
-                           Calling party subaddress,
-                           BC,
-                           LLC,
-                           HLC,
-                           Additional Info */
+/* CONNECT-INDICATION                                       */
+typedef struct {
+	word CIP_Value;
+	byte structs[0];      /* Called party number,
+				 Called party subaddress,
+				 Calling party number,
+				 Calling party subaddress,
+				 BC,
+				 LLC,
+				 HLC,
+				 Additional Info */
 } _CON_INDP;
-        /* CONNECT-RESPONSE                                         */
+/* CONNECT-RESPONSE                                         */
 typedef struct {
-  word Accept;
-  byte structs[1];      /* B_protocol,
-                           Connected party number,
-                           Connected party subaddress,
-                           LLC */
+	word Accept;
+	byte structs[0];      /* B_protocol,
+				 Connected party number,
+				 Connected party subaddress,
+				 LLC */
 } _CON_RESP;
-        /* CONNECT-ACTIVE-INDICATION                                */
+/* CONNECT-ACTIVE-INDICATION                                */
 typedef struct {
-  byte structs[1];      /* Connected party number,
-                           Connected party subaddress,
-                           LLC */
+	byte structs[0];      /* Connected party number,
+				 Connected party subaddress,
+				 LLC */
 } _CON_A_INDP;
-        /* CONNECT-ACTIVE-RESPONSE                                  */
+/* CONNECT-ACTIVE-RESPONSE                                  */
 typedef struct {
-  byte structs[1];      /* empty */
+	byte structs[0];      /* empty */
 } _CON_A_RESP;
-        /* DISCONNECT-REQUEST                                       */
+/* DISCONNECT-REQUEST                                       */
 typedef struct {
-  byte structs[1];      /* Additional Info */
+	byte structs[0];      /* Additional Info */
 } _DIS_REQP;
-        /* DISCONNECT-CONFIRM                                       */
+/* DISCONNECT-CONFIRM                                       */
 typedef struct {
-  word Info;
+	word Info;
 } _DIS_CONP;
-        /* DISCONNECT-INDICATION                                    */
+/* DISCONNECT-INDICATION                                    */
 typedef struct {
-  word Info;
+	word Info;
 } _DIS_INDP;
-        /* DISCONNECT-RESPONSE                                      */
+/* DISCONNECT-RESPONSE                                      */
 typedef struct {
-  byte structs[1];      /* empty */
+	byte structs[0];      /* empty */
 } _DIS_RESP;
-        /* LISTEN-REQUEST                                           */
+/* LISTEN-REQUEST                                           */
 typedef struct {
-  dword Info_Mask;
-  dword CIP_Mask;
-  byte structs[1];      /* Calling party number,
-                           Calling party subaddress */
+	dword Info_Mask;
+	dword CIP_Mask;
+	byte structs[0];      /* Calling party number,
+				 Calling party subaddress */
 } _LIS_REQP;
-        /* LISTEN-CONFIRM                                           */
+/* LISTEN-CONFIRM                                           */
 typedef struct {
-  word Info;
+	word Info;
 } _LIS_CONP;
-        /* INFO-REQUEST                                             */
+/* INFO-REQUEST                                             */
 typedef struct {
-  byte structs[1];      /* Called party number,
-                           Additional Info */
+	byte structs[0];      /* Called party number,
+				 Additional Info */
 } _INF_REQP;
-        /* INFO-CONFIRM                                             */
+/* INFO-CONFIRM                                             */
 typedef struct {
-  word Info;
+	word Info;
 } _INF_CONP;
-        /* INFO-INDICATION                                          */
+/* INFO-INDICATION                                          */
 typedef struct {
-  word Number;
-  byte structs[1];      /* Info element */
+	word Number;
+	byte structs[0];      /* Info element */
 } _INF_INDP;
-        /* INFO-RESPONSE                                            */
+/* INFO-RESPONSE                                            */
 typedef struct {
-  byte structs[1];      /* empty */
+	byte structs[0];      /* empty */
 } _INF_RESP;
-        /* SELECT-B-REQUEST                                         */
+/* SELECT-B-REQUEST                                         */
 typedef struct {
-  byte structs[1];      /* B-protocol */
+	byte structs[0];      /* B-protocol */
 } _SEL_B_REQP;
-        /* SELECT-B-CONFIRM                                         */
+/* SELECT-B-CONFIRM                                         */
 typedef struct {
-  word Info;
+	word Info;
 } _SEL_B_CONP;
-        /* FACILITY-REQUEST */
+/* FACILITY-REQUEST */
 typedef struct {
-  word Selector;
-  byte structs[1];      /* Facility parameters */
+	word Selector;
+	byte structs[0];      /* Facility parameters */
 } _FAC_REQP;
-        /* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */
+/* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */
 typedef struct {
-  byte  struct_length;
-  word  function;
-  byte  length;
-  word  SupplementaryServiceInfo;
-  dword SupportedServices;
+	byte  struct_length;
+	word  function;
+	byte  length;
+	word  SupplementaryServiceInfo;
+	dword SupportedServices;
 } _FAC_CON_STRUCTS;
-        /* FACILITY-CONFIRM */
+/* FACILITY-CONFIRM */
 typedef struct {
-  word Info;
-  word Selector;
-  byte structs[1];      /* Facility parameters */
+	word Info;
+	word Selector;
+	byte structs[0];      /* Facility parameters */
 } _FAC_CONP;
-        /* FACILITY-INDICATION */
+/* FACILITY-INDICATION */
 typedef struct {
-  word Selector;
-  byte structs[1];      /* Facility parameters */
+	word Selector;
+	byte structs[0];      /* Facility parameters */
 } _FAC_INDP;
-        /* FACILITY-RESPONSE */
+/* FACILITY-RESPONSE */
 typedef struct {
-  word Selector;
-  byte structs[1];      /* Facility parameters */
+	word Selector;
+	byte structs[0];      /* Facility parameters */
 } _FAC_RESP;
-        /* CONNECT-B3-REQUEST                                       */
+/* CONNECT-B3-REQUEST                                       */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _CON_B3_REQP;
-        /* CONNECT-B3-CONFIRM                                       */
+/* CONNECT-B3-CONFIRM                                       */
 typedef struct {
-  word Info;
+	word Info;
 } _CON_B3_CONP;
-        /* CONNECT-B3-INDICATION                                    */
+/* CONNECT-B3-INDICATION                                    */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _CON_B3_INDP;
-        /* CONNECT-B3-RESPONSE                                      */
+/* CONNECT-B3-RESPONSE                                      */
 typedef struct {
-  word Accept;
-  byte structs[1];      /* NCPI */
+	word Accept;
+	byte structs[0];      /* NCPI */
 } _CON_B3_RESP;
-        /* CONNECT-B3-ACTIVE-INDICATION                             */
+/* CONNECT-B3-ACTIVE-INDICATION                             */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _CON_B3_A_INDP;
-        /* CONNECT-B3-ACTIVE-RESPONSE                               */
+/* CONNECT-B3-ACTIVE-RESPONSE                               */
 typedef struct {
-  byte structs[1];      /* empty */
+	byte structs[0];      /* empty */
 } _CON_B3_A_RESP;
-        /* DISCONNECT-B3-REQUEST                                    */
+/* DISCONNECT-B3-REQUEST                                    */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _DIS_B3_REQP;
-        /* DISCONNECT-B3-CONFIRM                                    */
+/* DISCONNECT-B3-CONFIRM                                    */
 typedef struct {
-  word Info;
+	word Info;
 } _DIS_B3_CONP;
-        /* DISCONNECT-B3-INDICATION                                 */
+/* DISCONNECT-B3-INDICATION                                 */
 typedef struct {
-  word Info;
-  byte structs[1];      /* NCPI */
+	word Info;
+	byte structs[0];      /* NCPI */
 } _DIS_B3_INDP;
-        /* DISCONNECT-B3-RESPONSE                                   */
+/* DISCONNECT-B3-RESPONSE                                   */
 typedef struct {
-  byte structs[1];      /* empty */
+	byte structs[0];      /* empty */
 } _DIS_B3_RESP;
-        /* DATA-B3-REQUEST                                          */
+/* DATA-B3-REQUEST                                          */
 typedef struct {
-  dword         Data;
-  word          Data_Length;
-  word          Number;
-  word          Flags;
+	dword         Data;
+	word          Data_Length;
+	word          Number;
+	word          Flags;
 } _DAT_B3_REQP;
-        /* DATA-B3-REQUEST 64 BIT Systems                           */
+/* DATA-B3-REQUEST 64 BIT Systems                           */
 typedef struct {
-  dword         Data;
-  word          Data_Length;
-  word          Number;
-  word          Flags;
-  void          *pData;
+	dword         Data;
+	word          Data_Length;
+	word          Number;
+	word          Flags;
+	void          *pData;
 } _DAT_B3_REQ64P;
-        /* DATA-B3-CONFIRM                                          */
+/* DATA-B3-CONFIRM                                          */
 typedef struct {
-  word          Number;
-  word          Info;
+	word          Number;
+	word          Info;
 } _DAT_B3_CONP;
-        /* DATA-B3-INDICATION                                       */
+/* DATA-B3-INDICATION                                       */
 typedef struct {
-  dword         Data;
-  word          Data_Length;
-  word          Number;
-  word          Flags;
+	dword         Data;
+	word          Data_Length;
+	word          Number;
+	word          Flags;
 } _DAT_B3_INDP;
-        /* DATA-B3-INDICATION  64 BIT Systems                       */
+/* DATA-B3-INDICATION  64 BIT Systems                       */
 typedef struct {
-  dword         Data;
-  word          Data_Length;
-  word          Number;
-  word          Flags;
-  void          *pData;
+	dword         Data;
+	word          Data_Length;
+	word          Number;
+	word          Flags;
+	void          *pData;
 } _DAT_B3_IND64P;
-        /* DATA-B3-RESPONSE                                         */
+/* DATA-B3-RESPONSE                                         */
 typedef struct {
-  word          Number;
+	word          Number;
 } _DAT_B3_RESP;
-        /* RESET-B3-REQUEST                                         */
+/* RESET-B3-REQUEST                                         */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _RES_B3_REQP;
-        /* RESET-B3-CONFIRM                                         */
+/* RESET-B3-CONFIRM                                         */
 typedef struct {
-  word Info;
+	word Info;
 } _RES_B3_CONP;
-        /* RESET-B3-INDICATION                                      */
+/* RESET-B3-INDICATION                                      */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _RES_B3_INDP;
-        /* RESET-B3-RESPONSE                                        */
+/* RESET-B3-RESPONSE                                        */
 typedef struct {
-  byte structs[1];      /* empty */
+	byte structs[0];      /* empty */
 } _RES_B3_RESP;
-        /* CONNECT-B3-T90-ACTIVE-INDICATION                         */
+/* CONNECT-B3-T90-ACTIVE-INDICATION                         */
 typedef struct {
-  byte structs[1];      /* NCPI */
+	byte structs[0];      /* NCPI */
 } _CON_B3_T90_A_INDP;
-        /* CONNECT-B3-T90-ACTIVE-RESPONSE                           */
+/* CONNECT-B3-T90-ACTIVE-RESPONSE                           */
 typedef struct {
-  word Reject;
-  byte structs[1];      /* NCPI */
+	word Reject;
+	byte structs[0];      /* NCPI */
 } _CON_B3_T90_A_RESP;
 /*------------------------------------------------------------------*/
 /* message structure                                                */
@@ -364,64 +364,64 @@ typedef struct {
 typedef struct _API_MSG CAPI_MSG;
 typedef struct _MSG_HEADER CAPI_MSG_HEADER;
 struct _API_MSG {
-  struct _MSG_HEADER {
-    word        length;
-    word        appl_id;
-    word        command;
-    word        number;
-    byte        controller;
-    byte        plci;
-    word        ncci;
-  } header;
-  union {
-    _ALT_REQP           alert_req;
-    _ALT_CONP           alert_con;
-    _CON_REQP           connect_req;
-    _CON_CONP           connect_con;
-    _CON_INDP           connect_ind;
-    _CON_RESP           connect_res;
-    _CON_A_INDP         connect_a_ind;
-    _CON_A_RESP         connect_a_res;
-    _DIS_REQP           disconnect_req;
-    _DIS_CONP           disconnect_con;
-    _DIS_INDP           disconnect_ind;
-    _DIS_RESP           disconnect_res;
-    _LIS_REQP           listen_req;
-    _LIS_CONP           listen_con;
-    _INF_REQP           info_req;
-    _INF_CONP           info_con;
-    _INF_INDP           info_ind;
-    _INF_RESP           info_res;
-    _SEL_B_REQP         select_b_req;
-    _SEL_B_CONP         select_b_con;
-    _FAC_REQP           facility_req;
-    _FAC_CONP           facility_con;
-    _FAC_INDP           facility_ind;
-    _FAC_RESP           facility_res;
-    _CON_B3_REQP        connect_b3_req;
-    _CON_B3_CONP        connect_b3_con;
-    _CON_B3_INDP        connect_b3_ind;
-    _CON_B3_RESP        connect_b3_res;
-    _CON_B3_A_INDP      connect_b3_a_ind;
-    _CON_B3_A_RESP      connect_b3_a_res;
-    _DIS_B3_REQP        disconnect_b3_req;
-    _DIS_B3_CONP        disconnect_b3_con;
-    _DIS_B3_INDP        disconnect_b3_ind;
-    _DIS_B3_RESP        disconnect_b3_res;
-    _DAT_B3_REQP        data_b3_req;
-    _DAT_B3_REQ64P      data_b3_req64;
-    _DAT_B3_CONP        data_b3_con;
-    _DAT_B3_INDP        data_b3_ind;
-    _DAT_B3_IND64P      data_b3_ind64;
-    _DAT_B3_RESP        data_b3_res;
-    _RES_B3_REQP        reset_b3_req;
-    _RES_B3_CONP        reset_b3_con;
-    _RES_B3_INDP        reset_b3_ind;
-    _RES_B3_RESP        reset_b3_res;
-    _CON_B3_T90_A_INDP  connect_b3_t90_a_ind;
-    _CON_B3_T90_A_RESP  connect_b3_t90_a_res;
-    byte                b[200];
-  } info;
+	struct _MSG_HEADER {
+		word        length;
+		word        appl_id;
+		word        command;
+		word        number;
+		byte        controller;
+		byte        plci;
+		word        ncci;
+	} header;
+	union {
+		_ALT_REQP           alert_req;
+		_ALT_CONP           alert_con;
+		_CON_REQP           connect_req;
+		_CON_CONP           connect_con;
+		_CON_INDP           connect_ind;
+		_CON_RESP           connect_res;
+		_CON_A_INDP         connect_a_ind;
+		_CON_A_RESP         connect_a_res;
+		_DIS_REQP           disconnect_req;
+		_DIS_CONP           disconnect_con;
+		_DIS_INDP           disconnect_ind;
+		_DIS_RESP           disconnect_res;
+		_LIS_REQP           listen_req;
+		_LIS_CONP           listen_con;
+		_INF_REQP           info_req;
+		_INF_CONP           info_con;
+		_INF_INDP           info_ind;
+		_INF_RESP           info_res;
+		_SEL_B_REQP         select_b_req;
+		_SEL_B_CONP         select_b_con;
+		_FAC_REQP           facility_req;
+		_FAC_CONP           facility_con;
+		_FAC_INDP           facility_ind;
+		_FAC_RESP           facility_res;
+		_CON_B3_REQP        connect_b3_req;
+		_CON_B3_CONP        connect_b3_con;
+		_CON_B3_INDP        connect_b3_ind;
+		_CON_B3_RESP        connect_b3_res;
+		_CON_B3_A_INDP      connect_b3_a_ind;
+		_CON_B3_A_RESP      connect_b3_a_res;
+		_DIS_B3_REQP        disconnect_b3_req;
+		_DIS_B3_CONP        disconnect_b3_con;
+		_DIS_B3_INDP        disconnect_b3_ind;
+		_DIS_B3_RESP        disconnect_b3_res;
+		_DAT_B3_REQP        data_b3_req;
+		_DAT_B3_REQ64P      data_b3_req64;
+		_DAT_B3_CONP        data_b3_con;
+		_DAT_B3_INDP        data_b3_ind;
+		_DAT_B3_IND64P      data_b3_ind64;
+		_DAT_B3_RESP        data_b3_res;
+		_RES_B3_REQP        reset_b3_req;
+		_RES_B3_CONP        reset_b3_con;
+		_RES_B3_INDP        reset_b3_ind;
+		_RES_B3_RESP        reset_b3_res;
+		_CON_B3_T90_A_INDP  connect_b3_t90_a_ind;
+		_CON_B3_T90_A_RESP  connect_b3_t90_a_res;
+		byte                b[200];
+	} info;
 };
 /*------------------------------------------------------------------*/
 /* non-fatal errors                                                 */
@@ -696,4 +696,4 @@ struct _API_MSG {
 /* function prototypes                                              */
 /*------------------------------------------------------------------*/
 /*------------------------------------------------------------------*/
-#endif /* _INC_CAPI20 */  
+#endif /* _INC_CAPI20 */
diff --git a/drivers/isdn/hardware/eicon/capidtmf.c b/drivers/isdn/hardware/eicon/capidtmf.c
index f130724..e3f7784 100644
--- a/drivers/isdn/hardware/eicon/capidtmf.c
+++ b/drivers/isdn/hardware/eicon/capidtmf.c
@@ -1,34 +1,34 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
 
 
-  
-  
+
+
 
 
 
@@ -51,74 +51,74 @@
 
 static short capidtmf_expand_table_alaw[0x0100] =
 {
-   -5504,   5504,   -344,    344, -22016,  22016,  -1376,   1376,
-   -2752,   2752,    -88,     88, -11008,  11008,   -688,    688,
-   -7552,   7552,   -472,    472, -30208,  30208,  -1888,   1888,
-   -3776,   3776,   -216,    216, -15104,  15104,   -944,    944,
-   -4480,   4480,   -280,    280, -17920,  17920,  -1120,   1120,
-   -2240,   2240,    -24,     24,  -8960,   8960,   -560,    560,
-   -6528,   6528,   -408,    408, -26112,  26112,  -1632,   1632,
-   -3264,   3264,   -152,    152, -13056,  13056,   -816,    816,
-   -6016,   6016,   -376,    376, -24064,  24064,  -1504,   1504,
-   -3008,   3008,   -120,    120, -12032,  12032,   -752,    752,
-   -8064,   8064,   -504,    504, -32256,  32256,  -2016,   2016,
-   -4032,   4032,   -248,    248, -16128,  16128,  -1008,   1008,
-   -4992,   4992,   -312,    312, -19968,  19968,  -1248,   1248,
-   -2496,   2496,    -56,     56,  -9984,   9984,   -624,    624,
-   -7040,   7040,   -440,    440, -28160,  28160,  -1760,   1760,
-   -3520,   3520,   -184,    184, -14080,  14080,   -880,    880,
-   -5248,   5248,   -328,    328, -20992,  20992,  -1312,   1312,
-   -2624,   2624,    -72,     72, -10496,  10496,   -656,    656,
-   -7296,   7296,   -456,    456, -29184,  29184,  -1824,   1824,
-   -3648,   3648,   -200,    200, -14592,  14592,   -912,    912,
-   -4224,   4224,   -264,    264, -16896,  16896,  -1056,   1056,
-   -2112,   2112,     -8,      8,  -8448,   8448,   -528,    528,
-   -6272,   6272,   -392,    392, -25088,  25088,  -1568,   1568,
-   -3136,   3136,   -136,    136, -12544,  12544,   -784,    784,
-   -5760,   5760,   -360,    360, -23040,  23040,  -1440,   1440,
-   -2880,   2880,   -104,    104, -11520,  11520,   -720,    720,
-   -7808,   7808,   -488,    488, -31232,  31232,  -1952,   1952,
-   -3904,   3904,   -232,    232, -15616,  15616,   -976,    976,
-   -4736,   4736,   -296,    296, -18944,  18944,  -1184,   1184,
-   -2368,   2368,    -40,     40,  -9472,   9472,   -592,    592,
-   -6784,   6784,   -424,    424, -27136,  27136,  -1696,   1696,
-   -3392,   3392,   -168,    168, -13568,  13568,   -848,    848
+	-5504,   5504,   -344,    344, -22016,  22016,  -1376,   1376,
+	-2752,   2752,    -88,     88, -11008,  11008,   -688,    688,
+	-7552,   7552,   -472,    472, -30208,  30208,  -1888,   1888,
+	-3776,   3776,   -216,    216, -15104,  15104,   -944,    944,
+	-4480,   4480,   -280,    280, -17920,  17920,  -1120,   1120,
+	-2240,   2240,    -24,     24,  -8960,   8960,   -560,    560,
+	-6528,   6528,   -408,    408, -26112,  26112,  -1632,   1632,
+	-3264,   3264,   -152,    152, -13056,  13056,   -816,    816,
+	-6016,   6016,   -376,    376, -24064,  24064,  -1504,   1504,
+	-3008,   3008,   -120,    120, -12032,  12032,   -752,    752,
+	-8064,   8064,   -504,    504, -32256,  32256,  -2016,   2016,
+	-4032,   4032,   -248,    248, -16128,  16128,  -1008,   1008,
+	-4992,   4992,   -312,    312, -19968,  19968,  -1248,   1248,
+	-2496,   2496,    -56,     56,  -9984,   9984,   -624,    624,
+	-7040,   7040,   -440,    440, -28160,  28160,  -1760,   1760,
+	-3520,   3520,   -184,    184, -14080,  14080,   -880,    880,
+	-5248,   5248,   -328,    328, -20992,  20992,  -1312,   1312,
+	-2624,   2624,    -72,     72, -10496,  10496,   -656,    656,
+	-7296,   7296,   -456,    456, -29184,  29184,  -1824,   1824,
+	-3648,   3648,   -200,    200, -14592,  14592,   -912,    912,
+	-4224,   4224,   -264,    264, -16896,  16896,  -1056,   1056,
+	-2112,   2112,     -8,      8,  -8448,   8448,   -528,    528,
+	-6272,   6272,   -392,    392, -25088,  25088,  -1568,   1568,
+	-3136,   3136,   -136,    136, -12544,  12544,   -784,    784,
+	-5760,   5760,   -360,    360, -23040,  23040,  -1440,   1440,
+	-2880,   2880,   -104,    104, -11520,  11520,   -720,    720,
+	-7808,   7808,   -488,    488, -31232,  31232,  -1952,   1952,
+	-3904,   3904,   -232,    232, -15616,  15616,   -976,    976,
+	-4736,   4736,   -296,    296, -18944,  18944,  -1184,   1184,
+	-2368,   2368,    -40,     40,  -9472,   9472,   -592,    592,
+	-6784,   6784,   -424,    424, -27136,  27136,  -1696,   1696,
+	-3392,   3392,   -168,    168, -13568,  13568,   -848,    848
 };
 
 static short capidtmf_expand_table_ulaw[0x0100] =
 {
-  -32124,  32124,  -1884,   1884,  -7932,   7932,   -372,    372,
-  -15996,  15996,   -876,    876,  -3900,   3900,   -120,    120,
-  -23932,  23932,  -1372,   1372,  -5884,   5884,   -244,    244,
-  -11900,  11900,   -620,    620,  -2876,   2876,    -56,     56,
-  -28028,  28028,  -1628,   1628,  -6908,   6908,   -308,    308,
-  -13948,  13948,   -748,    748,  -3388,   3388,    -88,     88,
-  -19836,  19836,  -1116,   1116,  -4860,   4860,   -180,    180,
-   -9852,   9852,   -492,    492,  -2364,   2364,    -24,     24,
-  -30076,  30076,  -1756,   1756,  -7420,   7420,   -340,    340,
-  -14972,  14972,   -812,    812,  -3644,   3644,   -104,    104,
-  -21884,  21884,  -1244,   1244,  -5372,   5372,   -212,    212,
-  -10876,  10876,   -556,    556,  -2620,   2620,    -40,     40,
-  -25980,  25980,  -1500,   1500,  -6396,   6396,   -276,    276,
-  -12924,  12924,   -684,    684,  -3132,   3132,    -72,     72,
-  -17788,  17788,   -988,    988,  -4348,   4348,   -148,    148,
-   -8828,   8828,   -428,    428,  -2108,   2108,     -8,      8,
-  -31100,  31100,  -1820,   1820,  -7676,   7676,   -356,    356,
-  -15484,  15484,   -844,    844,  -3772,   3772,   -112,    112,
-  -22908,  22908,  -1308,   1308,  -5628,   5628,   -228,    228,
-  -11388,  11388,   -588,    588,  -2748,   2748,    -48,     48,
-  -27004,  27004,  -1564,   1564,  -6652,   6652,   -292,    292,
-  -13436,  13436,   -716,    716,  -3260,   3260,    -80,     80,
-  -18812,  18812,  -1052,   1052,  -4604,   4604,   -164,    164,
-   -9340,   9340,   -460,    460,  -2236,   2236,    -16,     16,
-  -29052,  29052,  -1692,   1692,  -7164,   7164,   -324,    324,
-  -14460,  14460,   -780,    780,  -3516,   3516,    -96,     96,
-  -20860,  20860,  -1180,   1180,  -5116,   5116,   -196,    196,
-  -10364,  10364,   -524,    524,  -2492,   2492,    -32,     32,
-  -24956,  24956,  -1436,   1436,  -6140,   6140,   -260,    260,
-  -12412,  12412,   -652,    652,  -3004,   3004,    -64,     64,
-  -16764,  16764,   -924,    924,  -4092,   4092,   -132,    132,
-   -8316,   8316,   -396,    396,  -1980,   1980,      0,      0
+	-32124,  32124,  -1884,   1884,  -7932,   7932,   -372,    372,
+	-15996,  15996,   -876,    876,  -3900,   3900,   -120,    120,
+	-23932,  23932,  -1372,   1372,  -5884,   5884,   -244,    244,
+	-11900,  11900,   -620,    620,  -2876,   2876,    -56,     56,
+	-28028,  28028,  -1628,   1628,  -6908,   6908,   -308,    308,
+	-13948,  13948,   -748,    748,  -3388,   3388,    -88,     88,
+	-19836,  19836,  -1116,   1116,  -4860,   4860,   -180,    180,
+	-9852,   9852,   -492,    492,  -2364,   2364,    -24,     24,
+	-30076,  30076,  -1756,   1756,  -7420,   7420,   -340,    340,
+	-14972,  14972,   -812,    812,  -3644,   3644,   -104,    104,
+	-21884,  21884,  -1244,   1244,  -5372,   5372,   -212,    212,
+	-10876,  10876,   -556,    556,  -2620,   2620,    -40,     40,
+	-25980,  25980,  -1500,   1500,  -6396,   6396,   -276,    276,
+	-12924,  12924,   -684,    684,  -3132,   3132,    -72,     72,
+	-17788,  17788,   -988,    988,  -4348,   4348,   -148,    148,
+	-8828,   8828,   -428,    428,  -2108,   2108,     -8,      8,
+	-31100,  31100,  -1820,   1820,  -7676,   7676,   -356,    356,
+	-15484,  15484,   -844,    844,  -3772,   3772,   -112,    112,
+	-22908,  22908,  -1308,   1308,  -5628,   5628,   -228,    228,
+	-11388,  11388,   -588,    588,  -2748,   2748,    -48,     48,
+	-27004,  27004,  -1564,   1564,  -6652,   6652,   -292,    292,
+	-13436,  13436,   -716,    716,  -3260,   3260,    -80,     80,
+	-18812,  18812,  -1052,   1052,  -4604,   4604,   -164,    164,
+	-9340,   9340,   -460,    460,  -2236,   2236,    -16,     16,
+	-29052,  29052,  -1692,   1692,  -7164,   7164,   -324,    324,
+	-14460,  14460,   -780,    780,  -3516,   3516,    -96,     96,
+	-20860,  20860,  -1180,   1180,  -5116,   5116,   -196,    196,
+	-10364,  10364,   -524,    524,  -2492,   2492,    -32,     32,
+	-24956,  24956,  -1436,   1436,  -6140,   6140,   -260,    260,
+	-12412,  12412,   -652,    652,  -3004,   3004,    -64,     64,
+	-16764,  16764,   -924,    924,  -4092,   4092,   -132,    132,
+	-8316,   8316,   -396,    396,  -1980,   1980,      0,      0
 };
 
 
@@ -126,52 +126,52 @@ static short capidtmf_expand_table_ulaw[0x0100] =
 
 static short capidtmf_recv_window_function[CAPIDTMF_RECV_ACCUMULATE_CYCLES] =
 {
-    -500L,   -999L,  -1499L,  -1998L,  -2496L,  -2994L,  -3491L,  -3988L,
-   -4483L,  -4978L,  -5471L,  -5963L,  -6454L,  -6943L,  -7431L,  -7917L,
-   -8401L,  -8883L,  -9363L,  -9840L, -10316L, -10789L, -11259L, -11727L,
-  -12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L,
-  -15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L,
-  -19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L,
-  -22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L,
-  -25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L,
-  -27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L,
-  -29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L,
-  -30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L,
-  -32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L,
-  -32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L,
-  -32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L,
-  -32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L,
-  -31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L,
-  -30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L,
-  -28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L,
-  -26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L,
-  -23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L,
-  -20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L,
-  -17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L,
-  -14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L,
-  -10316L,  -9840L,  -9363L,  -8883L,  -8401L,  -7917L,  -7431L,  -6943L,
-   -6454L,  -5963L,  -5471L,  -4978L,  -4483L,  -3988L,  -3491L,  -2994L,
-   -2496L,  -1998L,  -1499L,   -999L,   -500L, 
+	-500L,   -999L,  -1499L,  -1998L,  -2496L,  -2994L,  -3491L,  -3988L,
+	-4483L,  -4978L,  -5471L,  -5963L,  -6454L,  -6943L,  -7431L,  -7917L,
+	-8401L,  -8883L,  -9363L,  -9840L, -10316L, -10789L, -11259L, -11727L,
+	-12193L, -12655L, -13115L, -13571L, -14024L, -14474L, -14921L, -15364L,
+	-15804L, -16240L, -16672L, -17100L, -17524L, -17944L, -18360L, -18772L,
+	-19180L, -19583L, -19981L, -20375L, -20764L, -21148L, -21527L, -21901L,
+	-22270L, -22634L, -22993L, -23346L, -23694L, -24037L, -24374L, -24705L,
+	-25030L, -25350L, -25664L, -25971L, -26273L, -26568L, -26858L, -27141L,
+	-27418L, -27688L, -27952L, -28210L, -28461L, -28705L, -28943L, -29174L,
+	-29398L, -29615L, -29826L, -30029L, -30226L, -30415L, -30598L, -30773L,
+	-30941L, -31102L, -31256L, -31402L, -31541L, -31673L, -31797L, -31914L,
+	-32024L, -32126L, -32221L, -32308L, -32388L, -32460L, -32524L, -32581L,
+	-32631L, -32673L, -32707L, -32734L, -32753L, -32764L, -32768L, -32764L,
+	-32753L, -32734L, -32707L, -32673L, -32631L, -32581L, -32524L, -32460L,
+	-32388L, -32308L, -32221L, -32126L, -32024L, -31914L, -31797L, -31673L,
+	-31541L, -31402L, -31256L, -31102L, -30941L, -30773L, -30598L, -30415L,
+	-30226L, -30029L, -29826L, -29615L, -29398L, -29174L, -28943L, -28705L,
+	-28461L, -28210L, -27952L, -27688L, -27418L, -27141L, -26858L, -26568L,
+	-26273L, -25971L, -25664L, -25350L, -25030L, -24705L, -24374L, -24037L,
+	-23694L, -23346L, -22993L, -22634L, -22270L, -21901L, -21527L, -21148L,
+	-20764L, -20375L, -19981L, -19583L, -19180L, -18772L, -18360L, -17944L,
+	-17524L, -17100L, -16672L, -16240L, -15804L, -15364L, -14921L, -14474L,
+	-14024L, -13571L, -13115L, -12655L, -12193L, -11727L, -11259L, -10789L,
+	-10316L,  -9840L,  -9363L,  -8883L,  -8401L,  -7917L,  -7431L,  -6943L,
+	-6454L,  -5963L,  -5471L,  -4978L,  -4483L,  -3988L,  -3491L,  -2994L,
+	-2496L,  -1998L,  -1499L,   -999L,   -500L,
 };
 
 static byte capidtmf_leading_zeroes_table[0x100] =
 {
-  8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
-  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
 #define capidtmf_byte_leading_zeroes(b)  (capidtmf_leading_zeroes_table[(BYTE)(b)])
@@ -182,140 +182,140 @@ static byte capidtmf_leading_zeroes_table[0x100] =
 /*---------------------------------------------------------------------------*/
 
 
-static void capidtmf_goertzel_loop (long *buffer, long *coeffs, short *sample, long count)
+static void capidtmf_goertzel_loop(long *buffer, long *coeffs, short *sample, long count)
 {
-  int i, j;
-  long c, d, q0, q1, q2;
-
-  for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++)
-  {
-    q1 = buffer[i];
-    q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
-    d = coeffs[i] >> 1;
-    c = d << 1;
-    if (c >= 0)
-    {
-      for (j = 0; j < count; j++)
-      {
-        q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15);
-        q2 = q1;
-        q1 = q0;
-      }
-    }
-    else
-    {
-      c = -c;
-      d = -d;
-      for (j = 0; j < count; j++)
-      {
-        q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15));
-        q2 = q1;
-        q1 = q0;
-      }
-    }
-    buffer[i] = q1;
-    buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
-  }
-  q1 = buffer[i];
-  q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
-  c = (coeffs[i] >> 1) << 1;
-  if (c >= 0)
-  {
-    for (j = 0; j < count; j++)
-    {
-      q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15);
-      q2 = q1;
-      q1 = q0;
-      c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
-    }
-  }
-  else
-  {
-    c = -c;
-    for (j = 0; j < count; j++)
-    {
-      q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15));
-      q2 = q1;
-      q1 = q0;
-      c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
-    }
-  }
-  coeffs[i] = c;
-  buffer[i] = q1;
-  buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
+	int i, j;
+	long c, d, q0, q1, q2;
+
+	for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1; i++)
+	{
+		q1 = buffer[i];
+		q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
+		d = coeffs[i] >> 1;
+		c = d << 1;
+		if (c >= 0)
+		{
+			for (j = 0; j < count; j++)
+			{
+				q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15);
+				q2 = q1;
+				q1 = q0;
+			}
+		}
+		else
+		{
+			c = -c;
+			d = -d;
+			for (j = 0; j < count; j++)
+			{
+				q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword) d) * ((dword)(q1 & 0xffff)))) >> 15));
+				q2 = q1;
+				q1 = q0;
+			}
+		}
+		buffer[i] = q1;
+		buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
+	}
+	q1 = buffer[i];
+	q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
+	c = (coeffs[i] >> 1) << 1;
+	if (c >= 0)
+	{
+		for (j = 0; j < count; j++)
+		{
+			q0 = sample[j] - q2 + (c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15);
+			q2 = q1;
+			q1 = q0;
+			c -= CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
+		}
+	}
+	else
+	{
+		c = -c;
+		for (j = 0; j < count; j++)
+		{
+			q0 = sample[j] - q2 - ((c * (q1 >> 16)) + (((dword)(((dword)(c >> 1)) * ((dword)(q1 & 0xffff)))) >> 15));
+			q2 = q1;
+			q1 = q0;
+			c += CAPIDTMF_RECV_FUNDAMENTAL_DECREMENT;
+		}
+	}
+	coeffs[i] = c;
+	buffer[i] = q1;
+	buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = q2;
 }
 
 
-static void capidtmf_goertzel_result (long *buffer, long *coeffs)
+static void capidtmf_goertzel_result(long *buffer, long *coeffs)
 {
-  int i;
-  long d, e, q1, q2, lo, mid, hi;
-  dword k;
-
-  for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
-  {
-    q1 = buffer[i];
-    q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
-    d = coeffs[i] >> 1;
-    if (d >= 0)
-      d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15);
-    else
-      d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15);
-    e = (q2 >= 0) ? q2 : -q2;
-    if (d >= 0)
-    {
-      k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
-      lo = k & 0xffff;
-      mid = k >> 16;
-      k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
-      mid += k & 0xffff;
-      hi = k >> 16;
-      k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
-      mid += k & 0xffff;
-      hi += k >> 16;
-      hi += ((dword)(d >> 16)) * ((dword)(e >> 16));
-    }
-    else
-    {
-      d = -d;
-      k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
-      lo = -((long)(k & 0xffff));
-      mid = -((long)(k >> 16));
-      k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
-      mid -= k & 0xffff;
-      hi = -((long)(k >> 16));
-      k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
-      mid -= k & 0xffff;
-      hi -= k >> 16;
-      hi -= ((dword)(d >> 16)) * ((dword)(e >> 16));
-    }
-    if (q2 < 0)
-    {
-      lo = -lo;
-      mid = -mid;
-      hi = -hi;
-    }
-    d = (q1 >= 0) ? q1 : -q1;
-    k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
-    lo += k & 0xffff;
-    mid += k >> 16;
-    k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
-    mid += (k & 0xffff) << 1;
-    hi += (k >> 16) << 1;
-    hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
-    d = (q2 >= 0) ? q2 : -q2;
-    k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
-    lo += k & 0xffff;
-    mid += k >> 16;
-    k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
-    mid += (k & 0xffff) << 1;
-    hi += (k >> 16) << 1;
-    hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
-    mid += lo >> 16;
-    hi += mid >> 16;
-    buffer[i] = (lo & 0xffff) | (mid << 16);
-    buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi;
-  }
+	int i;
+	long d, e, q1, q2, lo, mid, hi;
+	dword k;
+
+	for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
+	{
+		q1 = buffer[i];
+		q2 = buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
+		d = coeffs[i] >> 1;
+		if (d >= 0)
+			d = ((d << 1) * (-q1 >> 16)) + (((dword)(((dword) d) * ((dword)(-q1 & 0xffff)))) >> 15);
+		else
+			d = ((-d << 1) * (-q1 >> 16)) + (((dword)(((dword) -d) * ((dword)(-q1 & 0xffff)))) >> 15);
+		e = (q2 >= 0) ? q2 : -q2;
+		if (d >= 0)
+		{
+			k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
+			lo = k & 0xffff;
+			mid = k >> 16;
+			k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
+			mid += k & 0xffff;
+			hi = k >> 16;
+			k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
+			mid += k & 0xffff;
+			hi += k >> 16;
+			hi += ((dword)(d >> 16)) * ((dword)(e >> 16));
+		}
+		else
+		{
+			d = -d;
+			k = ((dword)(d & 0xffff)) * ((dword)(e & 0xffff));
+			lo = -((long)(k & 0xffff));
+			mid = -((long)(k >> 16));
+			k = ((dword)(d >> 16)) * ((dword)(e & 0xffff));
+			mid -= k & 0xffff;
+			hi = -((long)(k >> 16));
+			k = ((dword)(d & 0xffff)) * ((dword)(e >> 16));
+			mid -= k & 0xffff;
+			hi -= k >> 16;
+			hi -= ((dword)(d >> 16)) * ((dword)(e >> 16));
+		}
+		if (q2 < 0)
+		{
+			lo = -lo;
+			mid = -mid;
+			hi = -hi;
+		}
+		d = (q1 >= 0) ? q1 : -q1;
+		k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
+		lo += k & 0xffff;
+		mid += k >> 16;
+		k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
+		mid += (k & 0xffff) << 1;
+		hi += (k >> 16) << 1;
+		hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
+		d = (q2 >= 0) ? q2 : -q2;
+		k = ((dword)(d & 0xffff)) * ((dword)(d & 0xffff));
+		lo += k & 0xffff;
+		mid += k >> 16;
+		k = ((dword)(d >> 16)) * ((dword)(d & 0xffff));
+		mid += (k & 0xffff) << 1;
+		hi += (k >> 16) << 1;
+		hi += ((dword)(d >> 16)) * ((dword)(d >> 16));
+		mid += lo >> 16;
+		hi += mid >> 16;
+		buffer[i] = (lo & 0xffff) | (mid << 16);
+		buffer[i + CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] = hi;
+	}
 }
 
 
@@ -346,339 +346,339 @@ static void capidtmf_goertzel_result (long *buffer, long *coeffs)
 
 static long capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
 {
-  0xda97L * 2,  /* 697 Hz (Low group 697 Hz) */
-  0xd299L * 2,  /* 770 Hz (Low group 770 Hz) */
-  0xc8cbL * 2,  /* 852 Hz (Low group 852 Hz) */
-  0xbd36L * 2,  /* 941 Hz (Low group 941 Hz) */
-  0x9501L * 2,  /* 1209 Hz (High group 1209 Hz) */
-  0x7f89L * 2,  /* 1336 Hz (High group 1336 Hz) */
-  0x6639L * 2,  /* 1477 Hz (High group 1477 Hz) */
-  0x48c6L * 2,  /* 1633 Hz (High group 1633 Hz) */
-  0xe14cL * 2,  /* 630 Hz (Lower guard of low group 631 Hz) */
-  0xb2e0L * 2,  /* 1015 Hz (Upper guard of low group 1039 Hz) */
-  0xa1a0L * 2,  /* 1130 Hz (Lower guard of high group 1140 Hz) */
-  0x8a87L * 2,  /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */
-  0x7353L * 2,  /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */
-  0x583bL * 2,  /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */
-  0x37d8L * 2,  /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */
-  0x0000L * 2   /* 100-630 Hz (fundamentals) */
+	0xda97L * 2,  /* 697 Hz (Low group 697 Hz) */
+	0xd299L * 2,  /* 770 Hz (Low group 770 Hz) */
+	0xc8cbL * 2,  /* 852 Hz (Low group 852 Hz) */
+	0xbd36L * 2,  /* 941 Hz (Low group 941 Hz) */
+	0x9501L * 2,  /* 1209 Hz (High group 1209 Hz) */
+	0x7f89L * 2,  /* 1336 Hz (High group 1336 Hz) */
+	0x6639L * 2,  /* 1477 Hz (High group 1477 Hz) */
+	0x48c6L * 2,  /* 1633 Hz (High group 1633 Hz) */
+	0xe14cL * 2,  /* 630 Hz (Lower guard of low group 631 Hz) */
+	0xb2e0L * 2,  /* 1015 Hz (Upper guard of low group 1039 Hz) */
+	0xa1a0L * 2,  /* 1130 Hz (Lower guard of high group 1140 Hz) */
+	0x8a87L * 2,  /* 1272 Hz (Guard between 1209 Hz and 1336 Hz: 1271 Hz) */
+	0x7353L * 2,  /* 1405 Hz (2nd harmonics of 697 Hz and guard between 1336 Hz and 1477 Hz: 1405 Hz) */
+	0x583bL * 2,  /* 1552 Hz (2nd harmonics of 770 Hz and guard between 1477 Hz and 1633 Hz: 1553 Hz) */
+	0x37d8L * 2,  /* 1720 Hz (2nd harmonics of 852 Hz and upper guard of high group: 1715 Hz) */
+	0x0000L * 2   /* 100-630 Hz (fundamentals) */
 };
 
 
 static word capidtmf_recv_guard_snr_low_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
 {
-  14,                                    /* Low group peak versus 697 Hz */
-  14,                                    /* Low group peak versus 770 Hz */
-  16,                                    /* Low group peak versus 852 Hz */
-  16,                                    /* Low group peak versus 941 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1209 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1336 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1477 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1633 Hz */
-  14,                                    /* Low group peak versus 635 Hz */
-  16,                                    /* Low group peak versus 1010 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1140 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1272 Hz */
-  DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8,  /* Low group peak versus 1405 Hz */
-  DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4,  /* Low group peak versus 1555 Hz */
-  DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4,  /* Low group peak versus 1715 Hz */
-  12                                     /* Low group peak versus 100-630 Hz */
+	14,                                    /* Low group peak versus 697 Hz */
+	14,                                    /* Low group peak versus 770 Hz */
+	16,                                    /* Low group peak versus 852 Hz */
+	16,                                    /* Low group peak versus 941 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1209 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1336 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1477 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1633 Hz */
+	14,                                    /* Low group peak versus 635 Hz */
+	16,                                    /* Low group peak versus 1010 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1140 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* Low group peak versus 1272 Hz */
+	DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 8,  /* Low group peak versus 1405 Hz */
+	DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4,  /* Low group peak versus 1555 Hz */
+	DSPDTMF_RX_HARMONICS_SEL_DEFAULT - 4,  /* Low group peak versus 1715 Hz */
+	12                                     /* Low group peak versus 100-630 Hz */
 };
 
 
 static word capidtmf_recv_guard_snr_high_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT] =
 {
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 697 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 770 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 852 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 941 Hz */
-  20,                                    /* High group peak versus 1209 Hz */
-  20,                                    /* High group peak versus 1336 Hz */
-  20,                                    /* High group peak versus 1477 Hz */
-  20,                                    /* High group peak versus 1633 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 635 Hz */
-  CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 1010 Hz */
-  16,                                    /* High group peak versus 1140 Hz */
-  4,                                     /* High group peak versus 1272 Hz */
-  6,                                     /* High group peak versus 1405 Hz */
-  8,                                     /* High group peak versus 1555 Hz */
-  16,                                    /* High group peak versus 1715 Hz */
-  12                                     /* High group peak versus 100-630 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 697 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 770 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 852 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 941 Hz */
+	20,                                    /* High group peak versus 1209 Hz */
+	20,                                    /* High group peak versus 1336 Hz */
+	20,                                    /* High group peak versus 1477 Hz */
+	20,                                    /* High group peak versus 1633 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 635 Hz */
+	CAPIDTMF_RECV_GUARD_SNR_DONTCARE,      /* High group peak versus 1010 Hz */
+	16,                                    /* High group peak versus 1140 Hz */
+	4,                                     /* High group peak versus 1272 Hz */
+	6,                                     /* High group peak versus 1405 Hz */
+	8,                                     /* High group peak versus 1555 Hz */
+	16,                                    /* High group peak versus 1715 Hz */
+	12                                     /* High group peak versus 100-630 Hz */
 };
 
 
 /*---------------------------------------------------------------------------*/
 
-static void capidtmf_recv_init (t_capidtmf_state   *p_state)
+static void capidtmf_recv_init(t_capidtmf_state *p_state)
 {
-  p_state->recv.min_gap_duration = 1;
-  p_state->recv.min_digit_duration = 1;
-
-  p_state->recv.cycle_counter = 0;
-  p_state->recv.current_digit_on_time = 0;
-  p_state->recv.current_digit_off_time = 0;
-  p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
-
-  p_state->recv.digit_write_pos = 0;
-  p_state->recv.digit_read_pos = 0;
-  p_state->recv.indication_state = 0;
-  p_state->recv.indication_state_ack = 0;
-  p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE;
+	p_state->recv.min_gap_duration = 1;
+	p_state->recv.min_digit_duration = 1;
+
+	p_state->recv.cycle_counter = 0;
+	p_state->recv.current_digit_on_time = 0;
+	p_state->recv.current_digit_off_time = 0;
+	p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
+
+	p_state->recv.digit_write_pos = 0;
+	p_state->recv.digit_read_pos = 0;
+	p_state->recv.indication_state = 0;
+	p_state->recv.indication_state_ack = 0;
+	p_state->recv.state = CAPIDTMF_RECV_STATE_IDLE;
 }
 
 
-void capidtmf_recv_enable (t_capidtmf_state   *p_state, word min_digit_duration, word min_gap_duration)
+void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration)
 {
-  p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT;
-  p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) +
-    ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
-  if (p_state->recv.min_digit_duration <= 1)
-    p_state->recv.min_digit_duration = 1;
-  else
-    (p_state->recv.min_digit_duration)--;
-  p_state->recv.min_gap_duration =
-    (word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
-  if (p_state->recv.min_gap_duration <= 1)
-    p_state->recv.min_gap_duration = 1;
-  else
-    (p_state->recv.min_gap_duration)--;
-  p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
+	p_state->recv.indication_state_ack &= CAPIDTMF_RECV_INDICATION_DIGIT;
+	p_state->recv.min_digit_duration = (word)(((((dword) min_digit_duration) * 8) +
+						   ((dword)(CAPIDTMF_RECV_TIME_GRANULARITY / 2))) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
+	if (p_state->recv.min_digit_duration <= 1)
+		p_state->recv.min_digit_duration = 1;
+	else
+		(p_state->recv.min_digit_duration)--;
+	p_state->recv.min_gap_duration =
+		(word)((((dword) min_gap_duration) * 8) / ((dword) CAPIDTMF_RECV_TIME_GRANULARITY));
+	if (p_state->recv.min_gap_duration <= 1)
+		p_state->recv.min_gap_duration = 1;
+	else
+		(p_state->recv.min_gap_duration)--;
+	p_state->recv.state |= CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
 }
 
 
-void capidtmf_recv_disable (t_capidtmf_state   *p_state)
+void capidtmf_recv_disable(t_capidtmf_state *p_state)
 {
-  p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
-  if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE)
-    capidtmf_recv_init (p_state);
-  else
-  {
-    p_state->recv.cycle_counter = 0;
-    p_state->recv.current_digit_on_time = 0;
-    p_state->recv.current_digit_off_time = 0;
-    p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
-  }
+	p_state->recv.state &= ~CAPIDTMF_RECV_STATE_DTMF_ACTIVE;
+	if (p_state->recv.state == CAPIDTMF_RECV_STATE_IDLE)
+		capidtmf_recv_init(p_state);
+	else
+	{
+		p_state->recv.cycle_counter = 0;
+		p_state->recv.current_digit_on_time = 0;
+		p_state->recv.current_digit_off_time = 0;
+		p_state->recv.current_digit_value = CAPIDTMF_RECV_NO_DIGIT;
+	}
 }
 
 
-word capidtmf_recv_indication (t_capidtmf_state   *p_state, byte *buffer)
+word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer)
 {
-  word i, j, k, flags;
-
-  flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack;
-  p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT;
-  if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos)
-  {
-    i = 0;
-    k = p_state->recv.digit_write_pos;
-    j = p_state->recv.digit_read_pos;
-    do
-    {
-      buffer[i++] = p_state->recv.digit_buffer[j];
-      j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1;
-    } while (j != k);
-    p_state->recv.digit_read_pos = k;
-    return (i);
-  }
-  p_state->recv.indication_state_ack ^= flags;
-  return (0);
+	word i, j, k, flags;
+
+	flags = p_state->recv.indication_state ^ p_state->recv.indication_state_ack;
+	p_state->recv.indication_state_ack ^= flags & CAPIDTMF_RECV_INDICATION_DIGIT;
+	if (p_state->recv.digit_write_pos != p_state->recv.digit_read_pos)
+	{
+		i = 0;
+		k = p_state->recv.digit_write_pos;
+		j = p_state->recv.digit_read_pos;
+		do
+		{
+			buffer[i++] = p_state->recv.digit_buffer[j];
+			j = (j == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ? 0 : j + 1;
+		} while (j != k);
+		p_state->recv.digit_read_pos = k;
+		return (i);
+	}
+	p_state->recv.indication_state_ack ^= flags;
+	return (0);
 }
 
 
 #define CAPIDTMF_RECV_WINDOWED_SAMPLES  32
 
-void capidtmf_recv_block (t_capidtmf_state   *p_state, byte   *buffer, word length)
+void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length)
 {
-  byte result_digit;
-  word sample_number, cycle_counter, n, i;
-  word low_peak, high_peak;
-  dword lo, hi;
-  byte   *p;
-  short *q;
-  byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
-    short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES];
-
-
-  if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE)
-  {
-    cycle_counter = p_state->recv.cycle_counter;
-    sample_number = 0;
-    while (sample_number < length)
-    {
-      if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES)
-      {
-        if (cycle_counter == 0)
-        {
-          for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
-          {
-            p_state->recv.goertzel_buffer[0][i] = 0;
-            p_state->recv.goertzel_buffer[1][i] = 0;
-          }
-        }
-        n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter;
-        if (n > length - sample_number)
-          n = length - sample_number;
-        if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES)
-          n = CAPIDTMF_RECV_WINDOWED_SAMPLES;
-        p = buffer + sample_number;
-        q = capidtmf_recv_window_function + cycle_counter;
-        if (p_state->ulaw)
-        {
-          for (i = 0; i < n; i++)
-          {
-            windowed_sample_buffer[i] =
-              (short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15);
-	  }
-        }
-        else
-        {
-          for (i = 0; i < n; i++)
-          {
-            windowed_sample_buffer[i] =
-              (short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15);
-	  }
-        }
-        capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET;
-        capidtmf_goertzel_loop (p_state->recv.goertzel_buffer[0],
-          capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n);
-        cycle_counter += n;
-        sample_number += n;
-      }
-      else
-      {
-        capidtmf_goertzel_result (p_state->recv.goertzel_buffer[0],
-          capidtmf_recv_goertzel_coef_table);
-        for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
-        {
-          lo = (dword)(p_state->recv.goertzel_buffer[0][i]);
-          hi = (dword)(p_state->recv.goertzel_buffer[1][i]);
-          if (hi != 0)
-          {
-            n = capidtmf_dword_leading_zeroes (hi);
-            hi = (hi << n) | (lo >> (32 - n));
-          }
-          else
-          {
-            n = capidtmf_dword_leading_zeroes (lo);
-            hi = lo << n;
-	    n += 32;
-          }
-          n = 195 - 3 * n;
-          if (hi >= 0xcb300000L)
-            n += 2;
-          else if (hi >= 0xa1450000L)
-            n++;
-	  goertzel_result_buffer[i] = (byte) n;
-        }
-        low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT;
-        result_digit = CAPIDTMF_RECV_NO_DIGIT;
-        for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++)
-        {
-          if (goertzel_result_buffer[i] > low_peak)
-	  {
-	    low_peak = goertzel_result_buffer[i];
-	    result_digit = (byte) i;
-	  }
-        }
-        high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT;
-        n = CAPIDTMF_RECV_NO_DIGIT;
-        for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++)
-        {
-          if (goertzel_result_buffer[i] > high_peak)
-	  {
-	    high_peak = goertzel_result_buffer[i];
-	    n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2;
-	  }
-        }
-        result_digit |= (byte) n;
-        if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak)
-          result_digit = CAPIDTMF_RECV_NO_DIGIT;
-        if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak)
-          result_digit = CAPIDTMF_RECV_NO_DIGIT;
-        n = 0;
-        for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
-        {
-          if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0)
-           || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0))
-	  {
-	    n++;
-	  }
-        }
-        if (n != 2)
-          result_digit = CAPIDTMF_RECV_NO_DIGIT;
-
-        if (result_digit == CAPIDTMF_RECV_NO_DIGIT)
-        {
-          if (p_state->recv.current_digit_on_time != 0)
-          {
-            if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration)
-            {
-              p_state->recv.current_digit_on_time = 0;
-              p_state->recv.current_digit_off_time = 0;
-            }
-          }
-          else
-          {
-            if (p_state->recv.current_digit_off_time != 0)
-              (p_state->recv.current_digit_off_time)--;
-          }
-        }
-        else
-        {
-          if ((p_state->recv.current_digit_on_time == 0)
-           && (p_state->recv.current_digit_off_time != 0))
-          {
-            (p_state->recv.current_digit_off_time)--;
-          }
-          else
-          {
-            n = p_state->recv.current_digit_off_time;
-            if ((p_state->recv.current_digit_on_time != 0)
-             && (result_digit != p_state->recv.current_digit_value))
-            {
-              p_state->recv.current_digit_on_time = 0;
-              n = 0;
-            }
-            p_state->recv.current_digit_value = result_digit;
-            p_state->recv.current_digit_off_time = 0;
-            if (p_state->recv.current_digit_on_time != 0xffff)
-            {
-              p_state->recv.current_digit_on_time += n + 1;
-              if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration)
-              {
-                p_state->recv.current_digit_on_time = 0xffff;
-                i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ?
-                  0 : p_state->recv.digit_write_pos + 1;
-                if (i == p_state->recv.digit_read_pos)
-                {
-                  trace (dprintf ("%s,%d: Receive digit overrun",
-                    (char   *)(FILE_), __LINE__));
-                }
-                else
-                {
-                  p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit;
-                  p_state->recv.digit_write_pos = i;
-                  p_state->recv.indication_state =
-                    (p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) |
-                    (~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT);
-                }
-              }
-            }
-          }
-        }
-        cycle_counter = 0;
-        sample_number++;
-      }
-    }
-    p_state->recv.cycle_counter = cycle_counter;
-  }
+	byte result_digit;
+	word sample_number, cycle_counter, n, i;
+	word low_peak, high_peak;
+	dword lo, hi;
+	byte   *p;
+	short *q;
+	byte goertzel_result_buffer[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
+	short windowed_sample_buffer[CAPIDTMF_RECV_WINDOWED_SAMPLES];
+
+
+	if (p_state->recv.state & CAPIDTMF_RECV_STATE_DTMF_ACTIVE)
+	{
+		cycle_counter = p_state->recv.cycle_counter;
+		sample_number = 0;
+		while (sample_number < length)
+		{
+			if (cycle_counter < CAPIDTMF_RECV_ACCUMULATE_CYCLES)
+			{
+				if (cycle_counter == 0)
+				{
+					for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
+					{
+						p_state->recv.goertzel_buffer[0][i] = 0;
+						p_state->recv.goertzel_buffer[1][i] = 0;
+					}
+				}
+				n = CAPIDTMF_RECV_ACCUMULATE_CYCLES - cycle_counter;
+				if (n > length - sample_number)
+					n = length - sample_number;
+				if (n > CAPIDTMF_RECV_WINDOWED_SAMPLES)
+					n = CAPIDTMF_RECV_WINDOWED_SAMPLES;
+				p = buffer + sample_number;
+				q = capidtmf_recv_window_function + cycle_counter;
+				if (p_state->ulaw)
+				{
+					for (i = 0; i < n; i++)
+					{
+						windowed_sample_buffer[i] =
+							(short)((capidtmf_expand_table_ulaw[p[i]] * ((long)(q[i]))) >> 15);
+					}
+				}
+				else
+				{
+					for (i = 0; i < n; i++)
+					{
+						windowed_sample_buffer[i] =
+							(short)((capidtmf_expand_table_alaw[p[i]] * ((long)(q[i]))) >> 15);
+					}
+				}
+				capidtmf_recv_goertzel_coef_table[CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT - 1] = CAPIDTMF_RECV_FUNDAMENTAL_OFFSET;
+				capidtmf_goertzel_loop(p_state->recv.goertzel_buffer[0],
+						       capidtmf_recv_goertzel_coef_table, windowed_sample_buffer, n);
+				cycle_counter += n;
+				sample_number += n;
+			}
+			else
+			{
+				capidtmf_goertzel_result(p_state->recv.goertzel_buffer[0],
+							 capidtmf_recv_goertzel_coef_table);
+				for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
+				{
+					lo = (dword)(p_state->recv.goertzel_buffer[0][i]);
+					hi = (dword)(p_state->recv.goertzel_buffer[1][i]);
+					if (hi != 0)
+					{
+						n = capidtmf_dword_leading_zeroes(hi);
+						hi = (hi << n) | (lo >> (32 - n));
+					}
+					else
+					{
+						n = capidtmf_dword_leading_zeroes(lo);
+						hi = lo << n;
+						n += 32;
+					}
+					n = 195 - 3 * n;
+					if (hi >= 0xcb300000L)
+						n += 2;
+					else if (hi >= 0xa1450000L)
+						n++;
+					goertzel_result_buffer[i] = (byte) n;
+				}
+				low_peak = DSPDTMF_RX_SENSITIVITY_LOW_DEFAULT;
+				result_digit = CAPIDTMF_RECV_NO_DIGIT;
+				for (i = 0; i < CAPIDTMF_LOW_GROUP_FREQUENCIES; i++)
+				{
+					if (goertzel_result_buffer[i] > low_peak)
+					{
+						low_peak = goertzel_result_buffer[i];
+						result_digit = (byte) i;
+					}
+				}
+				high_peak = DSPDTMF_RX_SENSITIVITY_HIGH_DEFAULT;
+				n = CAPIDTMF_RECV_NO_DIGIT;
+				for (i = CAPIDTMF_LOW_GROUP_FREQUENCIES; i < CAPIDTMF_RECV_BASE_FREQUENCY_COUNT; i++)
+				{
+					if (goertzel_result_buffer[i] > high_peak)
+					{
+						high_peak = goertzel_result_buffer[i];
+						n = (i - CAPIDTMF_LOW_GROUP_FREQUENCIES) << 2;
+					}
+				}
+				result_digit |= (byte) n;
+				if (low_peak + DSPDTMF_RX_HIGH_EXCEEDING_LOW_DEFAULT < high_peak)
+					result_digit = CAPIDTMF_RECV_NO_DIGIT;
+				if (high_peak + DSPDTMF_RX_LOW_EXCEEDING_HIGH_DEFAULT < low_peak)
+					result_digit = CAPIDTMF_RECV_NO_DIGIT;
+				n = 0;
+				for (i = 0; i < CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT; i++)
+				{
+					if ((((short)(low_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_low_table[i])) < 0)
+					    || (((short)(high_peak - goertzel_result_buffer[i] - capidtmf_recv_guard_snr_high_table[i])) < 0))
+					{
+						n++;
+					}
+				}
+				if (n != 2)
+					result_digit = CAPIDTMF_RECV_NO_DIGIT;
+
+				if (result_digit == CAPIDTMF_RECV_NO_DIGIT)
+				{
+					if (p_state->recv.current_digit_on_time != 0)
+					{
+						if (++(p_state->recv.current_digit_off_time) >= p_state->recv.min_gap_duration)
+						{
+							p_state->recv.current_digit_on_time = 0;
+							p_state->recv.current_digit_off_time = 0;
+						}
+					}
+					else
+					{
+						if (p_state->recv.current_digit_off_time != 0)
+							(p_state->recv.current_digit_off_time)--;
+					}
+				}
+				else
+				{
+					if ((p_state->recv.current_digit_on_time == 0)
+					    && (p_state->recv.current_digit_off_time != 0))
+					{
+						(p_state->recv.current_digit_off_time)--;
+					}
+					else
+					{
+						n = p_state->recv.current_digit_off_time;
+						if ((p_state->recv.current_digit_on_time != 0)
+						    && (result_digit != p_state->recv.current_digit_value))
+						{
+							p_state->recv.current_digit_on_time = 0;
+							n = 0;
+						}
+						p_state->recv.current_digit_value = result_digit;
+						p_state->recv.current_digit_off_time = 0;
+						if (p_state->recv.current_digit_on_time != 0xffff)
+						{
+							p_state->recv.current_digit_on_time += n + 1;
+							if (p_state->recv.current_digit_on_time >= p_state->recv.min_digit_duration)
+							{
+								p_state->recv.current_digit_on_time = 0xffff;
+								i = (p_state->recv.digit_write_pos == CAPIDTMF_RECV_DIGIT_BUFFER_SIZE - 1) ?
+									0 : p_state->recv.digit_write_pos + 1;
+								if (i == p_state->recv.digit_read_pos)
+								{
+									trace(dprintf("%s,%d: Receive digit overrun",
+										      (char *)(FILE_), __LINE__));
+								}
+								else
+								{
+									p_state->recv.digit_buffer[p_state->recv.digit_write_pos] = result_digit;
+									p_state->recv.digit_write_pos = i;
+									p_state->recv.indication_state =
+										(p_state->recv.indication_state & ~CAPIDTMF_RECV_INDICATION_DIGIT) |
+										(~p_state->recv.indication_state_ack & CAPIDTMF_RECV_INDICATION_DIGIT);
+								}
+							}
+						}
+					}
+				}
+				cycle_counter = 0;
+				sample_number++;
+			}
+		}
+		p_state->recv.cycle_counter = cycle_counter;
+	}
 }
 
 
-void capidtmf_init (t_capidtmf_state   *p_state, byte ulaw)
+void capidtmf_init(t_capidtmf_state *p_state, byte ulaw)
 {
-  p_state->ulaw = ulaw;
-  capidtmf_recv_init (p_state);
+	p_state->ulaw = ulaw;
+	capidtmf_recv_init(p_state);
 }
 
 
diff --git a/drivers/isdn/hardware/eicon/capidtmf.h b/drivers/isdn/hardware/eicon/capidtmf.h
index 242048f..0a9cf59 100644
--- a/drivers/isdn/hardware/eicon/capidtmf.h
+++ b/drivers/isdn/hardware/eicon/capidtmf.h
@@ -1,29 +1,29 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 CAPIDTMF_H_  
+#ifndef CAPIDTMF_H_
 #define CAPIDTMF_H_
 /*---------------------------------------------------------------------------*/
 /*---------------------------------------------------------------------------*/
@@ -48,32 +48,32 @@
 #define CAPIDTMF_RECV_STATE_DTMF_ACTIVE      0x01
 typedef struct tag_capidtmf_recv_state
 {
-  byte digit_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE];
-  word digit_write_pos;
-  word digit_read_pos;
-  word indication_state;
-  word indication_state_ack;
-  long goertzel_buffer[2][CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
-  word min_gap_duration;
-  word min_digit_duration;
-  word cycle_counter;
-  word current_digit_on_time;
-  word current_digit_off_time;
-  byte current_digit_value;
-  byte state;
+	byte digit_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE];
+	word digit_write_pos;
+	word digit_read_pos;
+	word indication_state;
+	word indication_state_ack;
+	long goertzel_buffer[2][CAPIDTMF_RECV_TOTAL_FREQUENCY_COUNT];
+	word min_gap_duration;
+	word min_digit_duration;
+	word cycle_counter;
+	word current_digit_on_time;
+	word current_digit_off_time;
+	byte current_digit_value;
+	byte state;
 } t_capidtmf_recv_state;
 typedef struct tag_capidtmf_state
 {
-  byte ulaw;
-  t_capidtmf_recv_state recv;
+	byte ulaw;
+	t_capidtmf_recv_state recv;
 } t_capidtmf_state;
-word capidtmf_recv_indication (t_capidtmf_state   *p_state, byte *buffer);
-void capidtmf_recv_block (t_capidtmf_state   *p_state, byte   *buffer, word length);
-void capidtmf_init (t_capidtmf_state   *p_state, byte ulaw);
-void capidtmf_recv_enable (t_capidtmf_state   *p_state, word min_digit_duration, word min_gap_duration);
-void capidtmf_recv_disable (t_capidtmf_state   *p_state);
-#define capidtmf_indication(p_state,buffer)  (((p_state)->recv.indication_state != (p_state)->recv.indication_state_ack) ?    capidtmf_recv_indication (p_state, buffer) : 0)
-#define capidtmf_recv_process_block(p_state,buffer,length)  { if ((p_state)->recv.state != CAPIDTMF_RECV_STATE_IDLE) capidtmf_recv_block (p_state, buffer, length); }
+word capidtmf_recv_indication(t_capidtmf_state *p_state, byte *buffer);
+void capidtmf_recv_block(t_capidtmf_state *p_state, byte *buffer, word length);
+void capidtmf_init(t_capidtmf_state *p_state, byte ulaw);
+void capidtmf_recv_enable(t_capidtmf_state *p_state, word min_digit_duration, word min_gap_duration);
+void capidtmf_recv_disable(t_capidtmf_state *p_state);
+#define capidtmf_indication(p_state, buffer)  (((p_state)->recv.indication_state != (p_state)->recv.indication_state_ack) ? capidtmf_recv_indication(p_state, buffer) : 0)
+#define capidtmf_recv_process_block(p_state, buffer, length)  { if ((p_state)->recv.state != CAPIDTMF_RECV_STATE_IDLE) capidtmf_recv_block(p_state, buffer, length); }
 /*---------------------------------------------------------------------------*/
 /*---------------------------------------------------------------------------*/
-#endif  
+#endif
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index 4d425c6..a576f32 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -2,10 +2,10 @@
  *
  * ISDN interface module for Eicon active cards DIVA.
  * CAPI Interface common functions
- * 
- * Copyright 2000-2003 by Armin Schindler (mac@melware.de) 
+ *
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -43,7 +43,7 @@ static diva_os_spin_lock_t api_lock;
 static LIST_HEAD(cards);
 
 static dword notify_handle;
-static void DIRequest(ENTITY * e);
+static void DIRequest(ENTITY *e);
 static DESCRIPTOR MAdapter;
 static DESCRIPTOR DAdapter;
 static byte ControllerMap[MAX_DESCRIPTORS + 1];
@@ -160,7 +160,7 @@ static int find_free_id(void)
 			break;
 		num++;
 	}
-	return(num + 1);
+	return (num + 1);
 }
 
 /*
@@ -176,23 +176,23 @@ static diva_card *find_card_by_ctrl(word controller)
 		if (ControllerMap[card->Id] == controller) {
 			if (card->remove_in_progress)
 				card = NULL;
-			return(card);
+			return (card);
 		}
 	}
 	return (diva_card *) 0;
 }
 
 /*
- * Buffer RX/TX 
+ * Buffer RX/TX
  */
-void *TransmitBufferSet(APPL * appl, dword ref)
+void *TransmitBufferSet(APPL *appl, dword ref)
 {
 	appl->xbuffer_used[ref] = true;
 	DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
-	    return (void *)(long)ref;
+		return (void *)(long)ref;
 }
 
-void *TransmitBufferGet(APPL * appl, void *p)
+void *TransmitBufferGet(APPL *appl, void *p)
 {
 	if (appl->xbuffer_internal[(dword)(long)p])
 		return appl->xbuffer_internal[(dword)(long)p];
@@ -200,13 +200,13 @@ void *TransmitBufferGet(APPL * appl, void *p)
 	return appl->xbuffer_ptr[(dword)(long)p];
 }
 
-void TransmitBufferFree(APPL * appl, void *p)
+void TransmitBufferFree(APPL *appl, void *p)
 {
 	appl->xbuffer_used[(dword)(long)p] = false;
 	DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1))
-}
+		}
 
-void *ReceiveBufferGet(APPL * appl, int Num)
+void *ReceiveBufferGet(APPL *appl, int Num)
 {
 	return &appl->ReceiveBuffer[Num * appl->MaxDataLength];
 }
@@ -217,12 +217,12 @@ void *ReceiveBufferGet(APPL * appl, int Num)
 void api_remove_complete(void)
 {
 	DBG_PRV1(("api_remove_complete"))
-}
+		}
 
 /*
  * main function called by message.c
  */
-void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
+void sendf(APPL *appl, word command, dword Id, word Number, byte *format, ...)
 {
 	word i, j;
 	word length = 12, dlength = 0;
@@ -240,14 +240,14 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
 	DBG_PRV1(("sendf(a=%d,cmd=%x,format=%s)",
 		  appl->Id, command, (byte *) format))
 
-	PUT_WORD(&msg.header.appl_id, appl->Id);
+		PUT_WORD(&msg.header.appl_id, appl->Id);
 	PUT_WORD(&msg.header.command, command);
 	if ((byte) (command >> 8) == 0x82)
 		Number = appl->Number++;
 	PUT_WORD(&msg.header.number, Number);
 
 	PUT_DWORD(&msg.header.controller, Id);
-	write = (byte *) & msg;
+	write = (byte *)&msg;
 	write += 12;
 
 	va_start(ap, format);
@@ -287,16 +287,16 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
 
 	if (command == _DATA_B3_I)
 		dlength = GET_WORD(
-			      ((byte *) & msg.info.data_b3_ind.Data_Length));
+			((byte *)&msg.info.data_b3_ind.Data_Length));
 
 	if (!(dmb = diva_os_alloc_message_buffer(length + dlength,
-					  (void **) &write))) {
+						 (void **) &write))) {
 		DBG_ERR(("sendf: alloc_message_buffer failed, incoming msg dropped."))
-		return;
+			return;
 	}
 
 	/* copy msg header to sk_buff */
-	memcpy(write, (byte *) & msg, length);
+	memcpy(write, (byte *)&msg, length);
 
 	/* if DATA_B3_IND, copy data too */
 	if (command == _DATA_B3_I) {
@@ -318,10 +318,10 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
 			if (myDriverDebugHandle.dbgMask & DL_BLK) {
 				xlog("\x00\x02", &msg, 0x81, length);
 				for (i = 0; i < dlength; i += 256) {
-				  DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
-				  	((dlength - i) < 256) ? (dlength - i) : 256))
-				  if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
-					  break; /* not more if not explicitly requested */
+					DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
+						 ((dlength - i) < 256) ? (dlength - i) : 256))
+						if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
+							break; /* not more if not explicitly requested */
 				}
 			}
 			break;
@@ -333,7 +333,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
 	if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {
 		DBG_ERR(("sendf - controller %d not found, incoming msg dropped",
 			 write[8] & 0x7f))
-		diva_os_free_message_buffer(dmb);
+			diva_os_free_message_buffer(dmb);
 		return;
 	}
 	/* send capi msg to capi layer */
@@ -388,7 +388,7 @@ static void clean_adapter(int id, struct list_head *free_mem_q)
  * remove a card, but ensures consistent state of LI tables
  * in the time adapter is removed
  */
-static void divacapi_remove_card(DESCRIPTOR * d)
+static void divacapi_remove_card(DESCRIPTOR *d)
 {
 	diva_card *card = NULL;
 	diva_os_spin_lock_magic_t old_irql;
@@ -427,14 +427,14 @@ static void divacapi_remove_card(DESCRIPTOR * d)
 
 		clean_adapter(card->Id - 1, &free_mem_q);
 		DBG_TRC(("DelAdapterMap (%d) -> (%d)",
-				ControllerMap[card->Id], card->Id))
-				ControllerMap[card->Id] = 0;
+			 ControllerMap[card->Id], card->Id))
+			ControllerMap[card->Id] = 0;
 		DBG_TRC(("adapter remove, max_adapter=%d",
-				max_adapter));
+			 max_adapter));
 		diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");
-		
+
 		/* After releasing the lock, we can free the memory */
-		diva_os_free (0, card);
+		diva_os_free(0, card);
 	}
 
 	/* free queued memory areas */
@@ -469,13 +469,13 @@ rescan:
 /*
  * sync_callback
  */
-static void sync_callback(ENTITY * e)
+static void sync_callback(ENTITY *e)
 {
 	diva_os_spin_lock_magic_t old_irql;
 
 	DBG_TRC(("cb:Id=%x,Rc=%x,Ind=%x", e->Id, e->Rc, e->Ind))
 
-	diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback");
+		diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback");
 	callback(e);
 	diva_os_leave_spin_lock(&api_lock, &old_irql, "sync_callback");
 }
@@ -483,7 +483,7 @@ static void sync_callback(ENTITY * e)
 /*
  * add a new card
  */
-static int diva_add_card(DESCRIPTOR * d)
+static int diva_add_card(DESCRIPTOR *d)
 {
 	int k = 0, i = 0;
 	diva_os_spin_lock_magic_t old_irql;
@@ -492,19 +492,19 @@ static int diva_add_card(DESCRIPTOR * d)
 	DIVA_CAPI_ADAPTER *a = NULL;
 	IDI_SYNC_REQ sync_req;
 	char serial[16];
-	void* mem_to_free;
+	void *mem_to_free;
 	LI_CONFIG *new_li_config_table;
 	int j;
 
 	if (!(card = (diva_card *) diva_os_malloc(0, sizeof(diva_card)))) {
 		DBG_ERR(("diva_add_card: failed to allocate card struct."))
-		    return (0);
+			return (0);
 	}
 	memset((char *) card, 0x00, sizeof(diva_card));
 	memcpy(&card->d, d, sizeof(DESCRIPTOR));
 	sync_req.GetName.Req = 0;
 	sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME;
-	card->d.request((ENTITY *) & sync_req);
+	card->d.request((ENTITY *)&sync_req);
 	strlcpy(card->name, sync_req.GetName.name, sizeof(card->name));
 	ctrl = &card->capi_ctrl;
 	strcpy(ctrl->name, card->name);
@@ -517,14 +517,14 @@ static int diva_add_card(DESCRIPTOR * d)
 
 	if (attach_capi_ctr(ctrl)) {
 		DBG_ERR(("diva_add_card: failed to attach controller."))
-		    diva_os_free(0, card);
+			diva_os_free(0, card);
 		return (0);
 	}
-	
+
 	diva_os_enter_spin_lock(&api_lock, &old_irql, "find id");
 	card->Id = find_free_id();
 	diva_os_leave_spin_lock(&api_lock, &old_irql, "find id");
-	
+
 	strlcpy(ctrl->manu, M_COMPANY, sizeof(ctrl->manu));
 	ctrl->version.majorversion = 2;
 	ctrl->version.minorversion = 0;
@@ -533,7 +533,7 @@ static int diva_add_card(DESCRIPTOR * d)
 	sync_req.GetSerial.Req = 0;
 	sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
 	sync_req.GetSerial.serial = 0;
-	card->d.request((ENTITY *) & sync_req);
+	card->d.request((ENTITY *)&sync_req);
 	if ((i = ((sync_req.GetSerial.serial & 0xff000000) >> 24))) {
 		sprintf(serial, "%ld-%d",
 			sync_req.GetSerial.serial & 0x00ffffff, i + 1);
@@ -550,15 +550,15 @@ static int diva_add_card(DESCRIPTOR * d)
 
 	DBG_TRC(("AddAdapterMap (%d) -> (%d)", ctrl->cnr, card->Id))
 
-	    sync_req.xdi_capi_prms.Req = 0;
+		sync_req.xdi_capi_prms.Req = 0;
 	sync_req.xdi_capi_prms.Rc = IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS;
 	sync_req.xdi_capi_prms.info.structure_length =
-	    sizeof(diva_xdi_get_capi_parameters_t);
-	card->d.request((ENTITY *) & sync_req);
+		sizeof(diva_xdi_get_capi_parameters_t);
+	card->d.request((ENTITY *)&sync_req);
 	a->flag_dynamic_l1_down =
-	    sync_req.xdi_capi_prms.info.flag_dynamic_l1_down;
+		sync_req.xdi_capi_prms.info.flag_dynamic_l1_down;
 	a->group_optimization_enabled =
-	    sync_req.xdi_capi_prms.info.group_optimization_enabled;
+		sync_req.xdi_capi_prms.info.group_optimization_enabled;
 	a->request = DIRequest;	/* card->d.request; */
 	a->max_plci = card->d.channels + 30;
 	a->max_listen = (card->d.channels > 2) ? 8 : 2;
@@ -566,7 +566,7 @@ static int diva_add_card(DESCRIPTOR * d)
 	    (a->plci =
 	     (PLCI *) diva_os_malloc(0, sizeof(PLCI) * a->max_plci))) {
 		DBG_ERR(("diva_add_card: failed alloc plci struct."))
-		    memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
+			memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
 		return (0);
 	}
 	memset(a->plci, 0, sizeof(PLCI) * a->max_plci);
@@ -625,13 +625,13 @@ static int diva_add_card(DESCRIPTOR * d)
 		(LI_CONFIG *) diva_os_malloc(0, ((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * k) * ((k + 3) & ~3));
 	if (new_li_config_table == NULL) {
 		DBG_ERR(("diva_add_card: failed alloc li_config table."))
-		memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
+			memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
 		return (0);
 	}
 
 	/* Prevent access to line interconnect table in process update */
 	diva_os_enter_spin_lock(&api_lock, &old_irql, "add card");
-	
+
 	j = 0;
 	for (i = 0; i < k; i++) {
 		if ((i >= a->li_base) && (i < a->li_base + a->li_channels))
@@ -659,11 +659,11 @@ static int diva_add_card(DESCRIPTOR * d)
 			memset(&new_li_config_table[i].coef_table[a->li_base], 0, a->li_channels);
 			if (a->li_base + a->li_channels < k) {
 				memcpy(&new_li_config_table[i].flag_table[a->li_base +
-				       a->li_channels],
+									  a->li_channels],
 				       &li_config_table[j].flag_table[a->li_base],
 				       k - (a->li_base + a->li_channels));
 				memcpy(&new_li_config_table[i].coef_table[a->li_base +
-				       a->li_channels],
+									  a->li_channels],
 				       &li_config_table[j].coef_table[a->li_base],
 				       k - (a->li_base + a->li_channels));
 			}
@@ -689,7 +689,7 @@ static int diva_add_card(DESCRIPTOR * d)
 	diva_os_leave_spin_lock(&api_lock, &old_irql, "add card");
 
 	if (mem_to_free) {
-		diva_os_free (0, mem_to_free);
+		diva_os_free(0, mem_to_free);
 	}
 
 	i = 0;
@@ -722,7 +722,7 @@ static int diva_add_card(DESCRIPTOR * d)
  *  register appl
  */
 static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
-			       capi_register_params * rp)
+			       capi_register_params *rp)
 {
 	APPL *this;
 	word bnum, xnum;
@@ -737,38 +737,38 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
 
 	if (diva_os_in_irq()) {
 		DBG_ERR(("CAPI_REGISTER - in irq context !"))
-		return;
+			return;
 	}
 
 	DBG_TRC(("application register Id=%d", appl))
 
-	if (appl > MAX_APPL) {
-		DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
-		return;
-	}
+		if (appl > MAX_APPL) {
+			DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
+				return;
+		}
 
 	if (nconn <= 0)
 		nconn = ctrl->profile.nbchannel * -nconn;
 
-        if (nconn == 0)
+	if (nconn == 0)
 		nconn = ctrl->profile.nbchannel;
 
 	DBG_LOG(("CAPI_REGISTER - Id = %d", appl))
-	DBG_LOG(("  MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt))
-	DBG_LOG(("  MaxBDataBuffers       = %d", rp->datablkcnt))
-	DBG_LOG(("  MaxBDataLength        = %d", rp->datablklen))
-
-	if (nconn < 1 ||
-	    nconn > 255 ||
-	    rp->datablklen < 80 ||
-	    rp->datablklen > 2150 || rp->datablkcnt > 255) {
-		DBG_ERR(("CAPI_REGISTER - invalid parameters"))
-		return;
-	}
+		DBG_LOG(("  MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt))
+		DBG_LOG(("  MaxBDataBuffers       = %d", rp->datablkcnt))
+		DBG_LOG(("  MaxBDataLength        = %d", rp->datablklen))
+
+		if (nconn < 1 ||
+		    nconn > 255 ||
+		    rp->datablklen < 80 ||
+		    rp->datablklen > 2150 || rp->datablkcnt > 255) {
+			DBG_ERR(("CAPI_REGISTER - invalid parameters"))
+				return;
+		}
 
 	if (application[appl - 1].Id == appl) {
 		DBG_LOG(("CAPI_REGISTER - appl already registered"))
-		return;	/* appl already registered */
+			return;	/* appl already registered */
 	}
 
 	/* alloc memory */
@@ -785,10 +785,10 @@ static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
 	mem_len += xnum * rp->datablklen;	/* xbuffer_ptr[xnum] */
 
 	DBG_LOG(("  Allocated Memory      = %d", mem_len))
-	if (!(p = diva_os_malloc(0, mem_len))) {
-		DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
-		return;
-	}
+		if (!(p = diva_os_malloc(0, mem_len))) {
+			DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
+				return;
+		}
 	memset(p, 0, mem_len);
 
 	DataNCCI = (void *)p;
@@ -853,10 +853,10 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
 
 	DBG_TRC(("application %d(%d) cleanup", this->Id, appl))
 
-	if (diva_os_in_irq()) {
-		DBG_ERR(("CAPI_RELEASE - in irq context !"))
-		return;
-	}
+		if (diva_os_in_irq()) {
+			DBG_ERR(("CAPI_RELEASE - in irq context !"))
+				return;
+		}
 
 	diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl");
 	if (this->Id) {
@@ -876,7 +876,7 @@ static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
  *  send message
  */
 static u16 diva_send_message(struct capi_ctr *ctrl,
-			     diva_os_message_buffer_s * dmb)
+			     diva_os_message_buffer_s *dmb)
 {
 	int i = 0;
 	word ret = 0;
@@ -891,14 +891,14 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
 
 	if (diva_os_in_irq()) {
 		DBG_ERR(("CAPI_SEND_MSG - in irq context !"))
-		return CAPI_REGOSRESOURCEERR;
+			return CAPI_REGOSRESOURCEERR;
 	}
 	DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command))
 
-	if (card->remove_in_progress) {
-		DBG_ERR(("CAPI_SEND_MSG - remove in progress!"))
-		return CAPI_REGOSRESOURCEERR;
-	}
+		if (card->remove_in_progress) {
+			DBG_ERR(("CAPI_SEND_MSG - remove in progress!"))
+				return CAPI_REGOSRESOURCEERR;
+		}
 
 	diva_os_enter_spin_lock(&api_lock, &old_irql, "send message");
 
@@ -909,7 +909,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
 
 	/* patch controller number */
 	msg->header.controller = ControllerMap[card->Id]
-	    | (msg->header.controller & 0x80);	/* preserve external controller bit */
+		| (msg->header.controller & 0x80);	/* preserve external controller bit */
 
 	switch (command) {
 	default:
@@ -937,15 +937,15 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
 		    || GET_WORD(&msg->info.data_b3_req.Data_Length) >
 		    (length - clength)) {
 			DBG_ERR(("Write - invalid message size"))
-			retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
+				retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
 			goto write_end;
 		}
 
 		for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI)
-		     && this->xbuffer_used[i]; i++);
+			     && this->xbuffer_used[i]; i++);
 		if (i == (MAX_DATA_B3 * this->MaxNCCI)) {
 			DBG_ERR(("Write - too many data pending"))
-			retval = CAPI_SENDQUEUEFULL;
+				retval = CAPI_SENDQUEUEFULL;
 			goto write_end;
 		}
 		msg->info.data_b3_req.Data = i;
@@ -959,13 +959,13 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
 		    && (myDriverDebugHandle.dbgMask & DL_XLOG)) {
 			int j;
 			for (j = 0; j <
-			     GET_WORD(&msg->info.data_b3_req.Data_Length);
+				     GET_WORD(&msg->info.data_b3_req.Data_Length);
 			     j += 256) {
 				DBG_BLK((((char *) this->xbuffer_ptr[i]) + j,
-					((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
+					 ((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
 					  256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256))
-				if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
-					break;	/* not more if not explicitly requested */
+					if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
+						break;	/* not more if not explicitly requested */
 			}
 		}
 #endif
@@ -984,19 +984,19 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
 		break;
 	case _BAD_MSG:
 		DBG_ERR(("Write - bad message"))
-		retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
+			retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
 		break;
 	case _QUEUE_FULL:
 		DBG_ERR(("Write - queue full"))
-		retval = CAPI_SENDQUEUEFULL;
+			retval = CAPI_SENDQUEUEFULL;
 		break;
 	default:
 		DBG_ERR(("Write - api_put returned unknown error"))
-		retval = CAPI_UNKNOWNNOTPAR;
+			retval = CAPI_UNKNOWNNOTPAR;
 		break;
 	}
 
-      write_end:
+write_end:
 	diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
 	if (retval == CAPI_NOERROR)
 		diva_os_free_message_buffer(dmb);
@@ -1007,7 +1007,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
 /*
  * cards request function
  */
-static void DIRequest(ENTITY * e)
+static void DIRequest(ENTITY *e)
 {
 	DIVA_CAPI_ADAPTER *a = &(adapter[(byte) e->user[0]]);
 	diva_card *os_card = (diva_card *) a->os_card;
@@ -1022,7 +1022,7 @@ static void DIRequest(ENTITY * e)
 /*
  * callback function from didd
  */
-static void didd_callback(void *context, DESCRIPTOR * adapter, int removal)
+static void didd_callback(void *context, DESCRIPTOR *adapter, int removal)
 {
 	if (adapter->type == IDI_DADAPTER) {
 		DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
@@ -1071,17 +1071,17 @@ static int divacapi_connect_didd(void)
 			memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
 			req.didd_notify.e.Req = 0;
 			req.didd_notify.e.Rc =
-			    IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+				IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 			req.didd_notify.info.callback = (void *)didd_callback;
 			req.didd_notify.info.context = NULL;
-			DAdapter.request((ENTITY *) & req);
+			DAdapter.request((ENTITY *)&req);
 			if (req.didd_notify.e.Rc != 0xff) {
 				stop_dbg();
 				return (0);
 			}
 			notify_handle = req.didd_notify.info.handle;
 		}
-			else if ((DIDD_Table[x].type > 0) && (DIDD_Table[x].type < 16)) {	/* IDI Adapter found */
+		else if ((DIDD_Table[x].type > 0) && (DIDD_Table[x].type < 16)) {	/* IDI Adapter found */
 			diva_add_card(&DIDD_Table[x]);
 		}
 	}
@@ -1105,12 +1105,12 @@ static void divacapi_disconnect_didd(void)
 	req.didd_notify.e.Req = 0;
 	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 	req.didd_notify.info.handle = notify_handle;
-	DAdapter.request((ENTITY *) & req);
+	DAdapter.request((ENTITY *)&req);
 }
 
 /*
  * we do not provide date/time here,
- * the application should do this. 
+ * the application should do this.
  */
 int fax_head_line_time(char *buffer)
 {
@@ -1124,19 +1124,19 @@ static int DIVA_INIT_FUNCTION init_main_structs(void)
 {
 	if (!(mapped_msg = (CAPI_MSG *) diva_os_malloc(0, MAX_MSG_SIZE))) {
 		DBG_ERR(("init: failed alloc mapped_msg."))
-		    return 0;
+			return 0;
 	}
 
 	if (!(adapter = diva_os_malloc(0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS))) {
 		DBG_ERR(("init: failed alloc adapter struct."))
-		diva_os_free(0, mapped_msg);
+			diva_os_free(0, mapped_msg);
 		return 0;
 	}
 	memset(adapter, 0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS);
 
 	if (!(application = diva_os_malloc(0, sizeof(APPL) * MAX_APPL))) {
 		DBG_ERR(("init: failed alloc application struct."))
-		diva_os_free(0, mapped_msg);
+			diva_os_free(0, mapped_msg);
 		diva_os_free(0, adapter);
 		return 0;
 	}
@@ -1176,7 +1176,7 @@ static void do_api_remove_start(void)
 
 	if (ret)
 		DBG_ERR(("could not remove signaling ID's"))
-}
+			}
 
 /*
  * init
@@ -1190,13 +1190,13 @@ int DIVA_INIT_FUNCTION init_capifunc(void)
 
 	if (!init_main_structs()) {
 		DBG_ERR(("init: failed to init main structs."))
-		diva_os_destroy_spin_lock(&api_lock, "capifunc");
+			diva_os_destroy_spin_lock(&api_lock, "capifunc");
 		return (0);
 	}
 
 	if (!divacapi_connect_didd()) {
 		DBG_ERR(("init: failed to connect to DIDD."))
-		do_api_remove_start();
+			do_api_remove_start();
 		divacapi_remove_cards();
 		remove_main_structs();
 		diva_os_destroy_spin_lock(&api_lock, "capifunc");
diff --git a/drivers/isdn/hardware/eicon/capifunc.h b/drivers/isdn/hardware/eicon/capifunc.h
index bd256f2..e96c45b 100644
--- a/drivers/isdn/hardware/eicon/capifunc.h
+++ b/drivers/isdn/hardware/eicon/capifunc.h
@@ -2,8 +2,8 @@
  *
  * ISDN interface module for Eicon active cards DIVA.
  * CAPI Interface common functions
- * 
- * Copyright 2000-2003 by Armin Schindler (mac@melware.de) 
+ *
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
  *
  * This software may be used and distributed according to the terms
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 97a2096..eabe0fa 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -2,10 +2,10 @@
  *
  * ISDN interface module for Eicon active cards DIVA.
  * CAPI Interface
- * 
- * Copyright 2000-2003 by Armin Schindler (mac@melware.de) 
+ *
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  */
@@ -28,7 +28,7 @@
 
 static char *main_revision = "$Revision: 1.24 $";
 static char *DRIVERNAME =
-    "Eicon DIVA - CAPI Interface driver (http://www.melware.net)";
+	"Eicon DIVA - CAPI Interface driver (http://www.melware.net)";
 static char *DRIVERLNAME = "divacapi";
 
 MODULE_DESCRIPTION("CAPI driver for Eicon DIVA cards");
@@ -69,7 +69,7 @@ diva_os_message_buffer_s *diva_os_alloc_message_buffer(unsigned long size,
 /*
  * free a message buffer
  */
-void diva_os_free_message_buffer(diva_os_message_buffer_s * dmb)
+void diva_os_free_message_buffer(diva_os_message_buffer_s *dmb)
 {
 	kfree_skb(dmb);
 }
diff --git a/drivers/isdn/hardware/eicon/cardtype.h b/drivers/isdn/hardware/eicon/cardtype.h
index 18a5c42..8b20e22 100644
--- a/drivers/isdn/hardware/eicon/cardtype.h
+++ b/drivers/isdn/hardware/eicon/cardtype.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 _CARDTYPE_H_
@@ -94,7 +94,7 @@
  */
 #define CARD_UNKNOWN                      0
 #define CARD_NONE                         0
-  /* DIVA cards */
+/* DIVA cards */
 #define CARDTYPE_DIVA_MCA                 0
 #define CARDTYPE_DIVA_ISA                 1
 #define CARDTYPE_DIVA_PCM                 2
@@ -102,10 +102,10 @@
 #define CARDTYPE_DIVAPRO_PCM              4
 #define CARDTYPE_DIVAPICO_ISA             5
 #define CARDTYPE_DIVAPICO_PCM             6
-  /* DIVA 2.0 cards */
+/* DIVA 2.0 cards */
 #define CARDTYPE_DIVAPRO20_PCI            7
 #define CARDTYPE_DIVA20_PCI               8
-  /* S cards */
+/* S cards */
 #define CARDTYPE_QUADRO_ISA               9
 #define CARDTYPE_S_ISA                    10
 #define CARDTYPE_S_MCA                    11
@@ -117,57 +117,57 @@
 #define CARDTYPE_SCOM_MCA                 17
 #define CARDTYPE_PR_ISA                   18
 #define CARDTYPE_PR_MCA                   19
-  /* Diva Server cards (formerly called Maestra, later Amadeo) */
+/* Diva Server cards (formerly called Maestra, later Amadeo) */
 #define CARDTYPE_MAESTRA_ISA              20
 #define CARDTYPE_MAESTRA_PCI              21
-  /* Diva Server cards to be developed (Quadro, Primary rate) */
+/* Diva Server cards to be developed (Quadro, Primary rate) */
 #define CARDTYPE_DIVASRV_Q_8M_PCI         22
 #define CARDTYPE_DIVASRV_P_30M_PCI        23
 #define CARDTYPE_DIVASRV_P_2M_PCI         24
 #define CARDTYPE_DIVASRV_P_9M_PCI         25
-  /* DIVA 2.0 cards */
+/* DIVA 2.0 cards */
 #define CARDTYPE_DIVA20_ISA               26
 #define CARDTYPE_DIVA20U_ISA              27
 #define CARDTYPE_DIVA20U_PCI              28
 #define CARDTYPE_DIVAPRO20_ISA            29
 #define CARDTYPE_DIVAPRO20U_ISA           30
 #define CARDTYPE_DIVAPRO20U_PCI           31
-  /* DIVA combi cards (piccola ISDN + rockwell V.34 modem) */
+/* DIVA combi cards (piccola ISDN + rockwell V.34 modem) */
 #define CARDTYPE_DIVAMOBILE_PCM           32
 #define CARDTYPE_TDKGLOBALPRO_PCM         33
-  /* DIVA Pro PC OEM card for 'New Media Corporation' */
+/* DIVA Pro PC OEM card for 'New Media Corporation' */
 #define CARDTYPE_NMC_DIVAPRO_PCM          34
-  /* DIVA Pro 2.0 OEM cards for 'British Telecom' */
+/* DIVA Pro 2.0 OEM cards for 'British Telecom' */
 #define CARDTYPE_BT_EXLANE_PCI            35
 #define CARDTYPE_BT_EXLANE_ISA            36
-  /* DIVA low cost cards, 1st name DIVA 3.0, 2nd DIVA 2.01, 3rd ??? */
+/* DIVA low cost cards, 1st name DIVA 3.0, 2nd DIVA 2.01, 3rd ??? */
 #define CARDTYPE_DIVALOW_ISA              37
 #define CARDTYPE_DIVALOWU_ISA             38
 #define CARDTYPE_DIVALOW_PCI              39
 #define CARDTYPE_DIVALOWU_PCI             40
-  /* DIVA combi cards (piccola ISDN + rockwell V.90 modem) */
+/* DIVA combi cards (piccola ISDN + rockwell V.90 modem) */
 #define CARDTYPE_DIVAMOBILE_V90_PCM       41
 #define CARDTYPE_TDKGLOBPRO_V90_PCM       42
 #define CARDTYPE_DIVASRV_P_23M_PCI        43
 #define CARDTYPE_DIVALOW_USB              44
-  /* DIVA Audio (CT) family */
+/* DIVA Audio (CT) family */
 #define CARDTYPE_DIVA_CT_ST               45
 #define CARDTYPE_DIVA_CT_U                46
 #define CARDTYPE_DIVA_CTLITE_ST           47
 #define CARDTYPE_DIVA_CTLITE_U            48
-  /* DIVA ISDN plus V.90 series */
+/* DIVA ISDN plus V.90 series */
 #define CARDTYPE_DIVAISDN_V90_PCM         49
 #define CARDTYPE_DIVAISDN_V90_PCI         50
 #define CARDTYPE_DIVAISDN_TA              51
-  /* DIVA Server Voice cards */
+/* DIVA Server Voice cards */
 #define CARDTYPE_DIVASRV_VOICE_Q_8M_PCI   52
-  /* DIVA Server V2 cards */
+/* DIVA Server V2 cards */
 #define CARDTYPE_DIVASRV_Q_8M_V2_PCI      53
 #define CARDTYPE_DIVASRV_P_30M_V2_PCI     54
-  /* DIVA Server Voice V2 cards */
+/* DIVA Server Voice V2 cards */
 #define CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI 55
 #define CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI 56
-    /* Diva LAN */
+/* Diva LAN */
 #define CARDTYPE_DIVAISDN_LAN             57
 #define CARDTYPE_DIVA_202_PCI_ST          58
 #define CARDTYPE_DIVA_202_PCI_U           59
@@ -182,7 +182,7 @@
 #define CARDTYPE_DIVA_V2_PCM              67
 /* Re-badged Diva Pro PC Card */
 #define CARDTYPE_DIVA_PC_CARD             68
-  /* next free card type identifier */
+/* next free card type identifier */
 #define CARDTYPE_MAX                      69
 /*
  * The card families
@@ -246,47 +246,47 @@
  */
 typedef struct CARD_PROPERTIES
 {   char     *Name;  /* official marketing name     */
- unsigned short PnPId;  /* plug and play ID (for non PCMIA cards) */
- unsigned short Version; /* major and minor version no of the card */
- unsigned char DescType; /* card type to set in the IDI descriptor */
- unsigned char  Family;  /* basic family of the card     */
- unsigned short  Features; /* features bits to set in the IDI desc. */
- unsigned char Card;  /* basic card type       */
- unsigned char IType;  /* internal type of S cards (read from ram) */
- unsigned char  Bus;  /* bus type this card is designed for  */
- unsigned char  Chip;  /* chipset used on card      */
- unsigned char Adapters; /* number of adapters on card    */
- unsigned char Channels; /* # of channels per adapter    */
- unsigned short E_info;  /* # of ram entity info structs per adapter */
- unsigned short SizeIo;  /* size of IO window per adapter   */
- unsigned short SizeMem; /* size of memory window per adapter  */
+	unsigned short PnPId;  /* plug and play ID (for non PCMIA cards) */
+	unsigned short Version; /* major and minor version no of the card */
+	unsigned char DescType; /* card type to set in the IDI descriptor */
+	unsigned char  Family;  /* basic family of the card     */
+	unsigned short  Features; /* features bits to set in the IDI desc. */
+	unsigned char Card;  /* basic card type       */
+	unsigned char IType;  /* internal type of S cards (read from ram) */
+	unsigned char  Bus;  /* bus type this card is designed for  */
+	unsigned char  Chip;  /* chipset used on card      */
+	unsigned char Adapters; /* number of adapters on card    */
+	unsigned char Channels; /* # of channels per adapter    */
+	unsigned short E_info;  /* # of ram entity info structs per adapter */
+	unsigned short SizeIo;  /* size of IO window per adapter   */
+	unsigned short SizeMem; /* size of memory window per adapter  */
 } CARD_PROPERTIES;
 typedef struct CARD_RESOURCE
-{ unsigned char Int [10];
- unsigned short IoFirst;
- unsigned short IoStep;
- unsigned short IoCnt;
- unsigned long MemFirst;
- unsigned long MemStep;
- unsigned short MemCnt;
+{ unsigned char Int[10];
+	unsigned short IoFirst;
+	unsigned short IoStep;
+	unsigned short IoCnt;
+	unsigned long MemFirst;
+	unsigned long MemStep;
+	unsigned short MemCnt;
 } CARD_RESOURCE;
 /* test if the card of type 't' is a plug & play card */
-#define IS_PNP(t) \
-( \
- ( \
-  CardProperties[t].Bus != BUS_ISA \
-  && \
-  CardProperties[t].Bus != BUS_MCA \
- ) \
- || \
- ( \
-  CardProperties[t].Family != FAMILY_S \
-  && \
-  CardProperties[t].Card != CARD_DIVA \
- ) \
-)
+#define IS_PNP(t)						\
+	(							\
+		(						\
+			CardProperties[t].Bus != BUS_ISA	\
+			&&					\
+			CardProperties[t].Bus != BUS_MCA	\
+			)					\
+		||						\
+		(						\
+			CardProperties[t].Family != FAMILY_S	\
+			&&					\
+			CardProperties[t].Card != CARD_DIVA	\
+			)					\
+		)
 /* extract IDI Descriptor info for card type 't' (p == DescType/Features) */
-#define IDI_PROP(t,p) (CardProperties[t].p)
+#define IDI_PROP(t, p) (CardProperties[t].p)
 #if CARDTYPE_H_WANT_DATA
 #if CARDTYPE_H_WANT_IDI_DATA
 /* include "di_defs.h" for IDI adapter type and feature flag definitions */
@@ -328,502 +328,502 @@ typedef struct CARD_RESOURCE
 #define DI_SOFT_V110  0
 #endif
 /*--- CardProperties [Index=CARDTYPE_....] ---------------------------------*/
-CARD_PROPERTIES CardProperties [ ] =
+CARD_PROPERTIES CardProperties[] =
 {
-{ /*  0  */
- "Diva MCA",       0x6336,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
- CARD_DIVA,   CARD_I_NONE, BUS_MCA, CHIP_DSP,
- 1, 2,  0,   8,      0
-},
-{ /*  1  */
- "Diva ISA",       0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
- CARD_DIVA,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
- 1, 2,  0,   8,      0
-},
-{ /*  2  */
- "Diva/PCM",       0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
- CARD_DIVA,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
- 1, 2,  0,   8,      0
-},
-{ /*  3  */
- "Diva PRO ISA",      0x0031,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
- 1, 2,  0,   8,      0
-},
-{ /*  4  */
- "Diva PRO PC-Card",     0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_PRO,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
- 1, 2,   0,   8,      0
-},
-{ /*  5  */
- "Diva PICCOLA ISA",     0x0051,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_ISA, CHIP_HSCX,
- 1, 2,   0,   8,      0
-},
-{ /*  6  */
- "Diva PICCOLA PCM",     0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
- 1, 2,   0,   8,      0
-},
-{ /*  7  */
- "Diva PRO 2.0 S/T PCI",    0xe001,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
- CARD_PRO,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 2,   0,   8,      0
-},
-{ /*  8  */
- "Diva 2.0 S/T PCI",     0xe002,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCI, CHIP_HSCX,
- 1, 2,   0,   8,      0
-},
-{ /*  9  */
- "QUADRO ISA",      0x0000,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
- CARD_QUAD,   CARD_I_QUAD, BUS_ISA, CHIP_NONE,
- 4, 2,   16,  0,  0x800
-},
-{ /* 10  */
- "S ISA",       0x0000,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
- CARD_S,    CARD_I_S,  BUS_ISA, CHIP_NONE,
- 1, 1,   16,  0,  0x800
-},
-{ /* 11  */
- "S MCA",       0x6a93,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
- CARD_S,    CARD_I_S,  BUS_MCA, CHIP_NONE,
- 1, 1,   16,  16,  0x400
-},
-{ /* 12 */
- "SX ISA",       0x0000,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
- CARD_SX,   CARD_I_SX,  BUS_ISA, CHIP_NONE,
- 1, 2,  16,  0,  0x800
-},
-{ /* 13 */
- "SX MCA",       0x6a93,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
- CARD_SX,   CARD_I_SX,  BUS_MCA, CHIP_NONE,
- 1, 2,  16,  16,  0x400
-},
-{ /* 14 */
- "SXN ISA",       0x0000,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
- CARD_SXN,   CARD_I_SCOM, BUS_ISA, CHIP_NONE,
- 1, 2,   16,  0,   0x800
-},
-{ /* 15 */
- "SXN MCA",       0x6a93,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
- CARD_SXN,   CARD_I_SCOM, BUS_MCA, CHIP_NONE,
- 1, 2,  16,  16,  0x400
-},
-{ /* 16 */
- "SCOM ISA",       0x0000,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
- CARD_SCOM,   CARD_I_SCOM, BUS_ISA, CHIP_NONE,
- 1, 2,   16,  0,   0x800
-},
-{ /* 17 */
- "SCOM MCA",       0x6a93,  0x0100,
- IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
- CARD_SCOM,   CARD_I_SCOM, BUS_MCA, CHIP_NONE,
- 1, 2,  16,  16,  0x400
-},
-{ /* 18 */
- "S2M ISA",       0x0000,  0x0100,
- IDI_ADAPTER_PR,  FAMILY_S,  DI_NULL,
- CARD_PR,   CARD_I_PR,  BUS_ISA, CHIP_NONE,
- 1, 30,  256, 0,   0x4000
-},
-{ /* 19 */
- "S2M MCA",       0x6abb,  0x0100,
- IDI_ADAPTER_PR,  FAMILY_S,  DI_NULL,
- CARD_PR,   CARD_I_PR,  BUS_MCA, CHIP_NONE,
- 1, 30,  256, 16,  0x4000
-},
-{ /* 20 */
- "Diva Server BRI-2M ISA",   0x0041,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAE,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
- 1, 2,   16,  8,  0
-},
-{ /* 21 */
- "Diva Server BRI-2M PCI",   0xE010,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAE,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 2,   16,  8,   0
-},
-{ /* 22 */
- "Diva Server 4BRI-8M PCI",   0xE012,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 4, 2,   16,  8,   0
-},
-{ /* 23 */
- "Diva Server PRI-30M PCI",   0xE014,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 30,  256,  8,   0
-},
-{ /* 24 */
- "Diva Server PRI-2M PCI",   0xe014,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 30,  256,  8,   0
-},
-{ /* 25 */
- "Diva Server PRI-9M PCI",   0x0000,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 30,     256,  8,   0
-},
-{ /* 26 */
- "Diva 2.0 S/T ISA",     0x0071,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_ISA, CHIP_HSCX,
- 1, 2,  0,   8,   0
-},
-{ /* 27 */
- "Diva 2.0 U ISA",     0x0091,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_ISA, CHIP_HSCX,
- 1, 2,   0,   8,   0
-},
-{ /* 28 */
- "Diva 2.0 U PCI",     0xe004,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCI, CHIP_HSCX,
- 1, 2,   0,   8,   0
-},
-{ /* 29 */
- "Diva PRO 2.0 S/T ISA",    0x0061,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
- CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
- 1, 2,  0,   8,   0
-},
-{ /* 30 */
- "Diva PRO 2.0 U ISA",    0x0081,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
- CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
- 1, 2,  0,   8,   0
-},
-{ /* 31 */
- "Diva PRO 2.0 U PCI",    0xe003,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
- CARD_PRO,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 2,   0,   8,   0
-},
-{ /* 32 */
- "Diva MOBILE",      0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
- 1, 2,  0,   8,   0
-},
-{ /* 33 */
- "TDK DFI3600",      0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
- 1, 2,  0,   8,   0
-},
-{ /* 34 (OEM version of 4 - "Diva PRO PC-Card") */
- "New Media ISDN",     0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_PRO,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
- 1, 2,   0,   8,   0
-},
-{ /* 35 (OEM version of 7 - "Diva PRO 2.0 S/T PCI") */
- "BT ExLane PCI",     0xe101,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
- CARD_PRO,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 2,   0,   8,   0
-},
-{ /* 36 (OEM version of 29 - "Diva PRO 2.0 S/T ISA") */
- "BT ExLane ISA",     0x1061,  0x0200,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
- CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
- 1, 2,   0,   8,   0
-},
-{ /* 37 */
- "Diva 2.01 S/T ISA",    0x00A1,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_ISA, CHIP_IPAC,
- 1, 2,   0,   8,      0
-},
-{ /* 38 */
- "Diva 2.01 U ISA",     0x00B1,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_ISA, CHIP_IPAC,
- 1, 2,   0,   8,      0
-},
-{ /* 39 */
- "Diva 2.01 S/T PCI",    0xe005,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPAC,
- 1, 2,   0,   8,   0
-},
-{ /* 40        no ID yet */
- "Diva 2.01 U PCI",     0x0000,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPAC,
- 1, 2,   0,   8,   0
-},
-{ /* 41 */
- "Diva MOBILE V.90",     0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
- 1, 2,  0,   8,   0
-},
-{ /* 42 */
- "TDK DFI3600 V.90",     0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
- 1, 2,  0,   8,   0
-},
-{ /* 43 */
- "Diva Server PRI-23M PCI",   0xe014,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 30,  256,  8,   0
-},
-{ /* 44 */
- "Diva 2.01 S/T USB",    0x1000,     0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_USB, CHIP_IPAC,
- 1,  2,  0,  8,   0
-},
-{ /* 45 */
- "Diva CT S/T PCI",    0xe006,  0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1,  2,  0,  0,   0
-},
-{ /* 46 */
- "Diva CT U PCI",     0xe007,  0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1,  2,  0,  0,   0
-},
-{ /* 47 */
- "Diva CT Lite S/T PCI",   0xe008,  0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1,  2,  0,  0,   0
-},
-{ /* 48 */
- "Diva CT Lite U PCI",   0xe009,  0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1,  2,  0,  0,   0
-},
-{ /* 49 */
- "Diva ISDN+V.90 PC Card", 0x8D8C, 0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_DIVALOW, CARD_I_NONE, BUS_PCM, CHIP_IPAC,
- 1, 2,  0,   8,   0
-},
-{ /* 50 */
- "Diva ISDN+V.90 PCI",    0xe00A,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120  | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPAC,
- 1, 2,   0,   8,   0
-},
-{ /* 51 (DivaTA)      no ID */
- "Diva TA",       0x0000,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVATA,  CARD_I_NONE, BUS_COM, CHIP_EXTERN,
- 1, 1,   0,   8,   0
-},
-{ /* 52 (Diva Server 4BRI-8M PCI adapter enabled for Voice) */
- "Diva Server Voice 4BRI-8M PCI", 0xE016,  0x0100,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
- CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 4, 2,   16,  8,   0
-},
-{ /* 53 (Diva Server 4BRI 2.0 adapter) */
- "Diva Server 4BRI-8M 2.0 PCI",  0xE013,  0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 4, 2,   16,  8,   0
-},
-{ /* 54 (Diva Server PRI 2.0 adapter) */
- "Diva Server PRI 2.0 PCI",   0xE015,  0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 30,  256,  8,   0
-},
-{ /* 55 (Diva Server 4BRI-8M 2.0 PCI adapter enabled for Voice) */
- "Diva Server Voice 4BRI-8M 2.0 PCI", 0xE017,  0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
- CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 4, 2,   16,  8,   0
-},
-{ /* 56 (Diva Server PRI 2.0 PCI adapter enabled for Voice) */
- "Diva Server Voice PRI 2.0 PCI",  0xE019,  0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
- CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 30,  256,  8,   0
-},
-{
- /* 57 (DivaLan )      no ID */
- "Diva LAN",       0x0000,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALAN,  CARD_I_NONE, BUS_LAN, CHIP_EXTERN,
- 1, 1,   0,   8,   0
-},
-{ /* 58 */
- "Diva 2.02 PCI S/T",    0xE00B,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES | DI_SOFT_V110,
- CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPACX,
- 1, 2,   0,   8,   0
-},
-{ /* 59 */
- "Diva 2.02 PCI U",     0xE00C,  0x0300,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPACX,
- 1, 2,   0,   8,   0
-},
-{ /* 60 */
- "Diva Server BRI-2M 2.0 PCI",     0xE018,  0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_MAE2,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 2,   16,  8,   0
-},
-{ /* 61  (the previous name was Diva Server BRI-2F 2.0 PCI) */
- "Diva Server 2FX",                      0xE01A,     0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_SOFT_V110,
- CARD_MAE2,          CARD_I_NONE,    BUS_PCI,    CHIP_IPACX,
- 1,  2,      16,     8,   0
-},
-{ /* 62 */
- " Diva ISDN USB 2.0",    0x1003,     0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_DIVALOW,  CARD_I_NONE, BUS_USB, CHIP_IPACX,
- 1, 2,  0,  8,   0
-},
-{ /* 63 (Diva Server BRI-2M 2.0 PCI adapter enabled for Voice) */
- "Diva Server Voice BRI-2M 2.0 PCI", 0xE01B,  0x0200,
- IDI_ADAPTER_MAESTRA,FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
- CARD_MAE2,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1, 2,   16,  8,   0
-},
-{ /* 64 */
- "Diva Pro 3.0 PCI",    0xe00d,  0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
- CARD_PRO,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1,  2,  0,  0,   0
-},
-{ /* 65 */
- "Diva ISDN + CT 2.0",    0xE00E,  0x0300,
- IDI_ADAPTER_DIVA   ,FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
- CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
- 1,  2,  0,  0,   0
-},
-{ /* 66 */
- "Diva Mobile V.90 PC Card",  0x8331,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_IPACX,
- 1, 2,  0,   8,   0
-},
-{ /* 67 */
- "Diva ISDN PC Card",  0x8311,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_IPACX,
- 1, 2,  0,   8,   0
-},
-{ /* 68 */
- "Diva ISDN PC Card",  0x0000,  0x0100,
- IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
- CARD_PRO,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
- 1, 2,   0,   8,      0
-},
-} ;
+	{ /*  0  */
+		"Diva MCA",       0x6336,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
+		CARD_DIVA,   CARD_I_NONE, BUS_MCA, CHIP_DSP,
+		1, 2,  0,   8,      0
+	},
+	{ /*  1  */
+		"Diva ISA",       0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
+		CARD_DIVA,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
+		1, 2,  0,   8,      0
+	},
+	{ /*  2  */
+		"Diva/PCM",       0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3,
+		CARD_DIVA,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
+		1, 2,  0,   8,      0
+	},
+	{ /*  3  */
+		"Diva PRO ISA",      0x0031,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
+		1, 2,  0,   8,      0
+	},
+	{ /*  4  */
+		"Diva PRO PC-Card",     0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_PRO,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
+		1, 2,   0,   8,      0
+	},
+	{ /*  5  */
+		"Diva PICCOLA ISA",     0x0051,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_ISA, CHIP_HSCX,
+		1, 2,   0,   8,      0
+	},
+	{ /*  6  */
+		"Diva PICCOLA PCM",     0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
+		1, 2,   0,   8,      0
+	},
+	{ /*  7  */
+		"Diva PRO 2.0 S/T PCI",    0xe001,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
+		CARD_PRO,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 2,   0,   8,      0
+	},
+	{ /*  8  */
+		"Diva 2.0 S/T PCI",     0xe002,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCI, CHIP_HSCX,
+		1, 2,   0,   8,      0
+	},
+	{ /*  9  */
+		"QUADRO ISA",      0x0000,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
+		CARD_QUAD,   CARD_I_QUAD, BUS_ISA, CHIP_NONE,
+		4, 2,   16,  0,  0x800
+	},
+	{ /* 10  */
+		"S ISA",       0x0000,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
+		CARD_S,    CARD_I_S,  BUS_ISA, CHIP_NONE,
+		1, 1,   16,  0,  0x800
+	},
+	{ /* 11  */
+		"S MCA",       0x6a93,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
+		CARD_S,    CARD_I_S,  BUS_MCA, CHIP_NONE,
+		1, 1,   16,  16,  0x400
+	},
+	{ /* 12 */
+		"SX ISA",       0x0000,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
+		CARD_SX,   CARD_I_SX,  BUS_ISA, CHIP_NONE,
+		1, 2,  16,  0,  0x800
+	},
+	{ /* 13 */
+		"SX MCA",       0x6a93,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
+		CARD_SX,   CARD_I_SX,  BUS_MCA, CHIP_NONE,
+		1, 2,  16,  16,  0x400
+	},
+	{ /* 14 */
+		"SXN ISA",       0x0000,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
+		CARD_SXN,   CARD_I_SCOM, BUS_ISA, CHIP_NONE,
+		1, 2,   16,  0,   0x800
+	},
+	{ /* 15 */
+		"SXN MCA",       0x6a93,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_NULL,
+		CARD_SXN,   CARD_I_SCOM, BUS_MCA, CHIP_NONE,
+		1, 2,  16,  16,  0x400
+	},
+	{ /* 16 */
+		"SCOM ISA",       0x0000,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
+		CARD_SCOM,   CARD_I_SCOM, BUS_ISA, CHIP_NONE,
+		1, 2,   16,  0,   0x800
+	},
+	{ /* 17 */
+		"SCOM MCA",       0x6a93,  0x0100,
+		IDI_ADAPTER_S,  FAMILY_S,  DI_CODEC,
+		CARD_SCOM,   CARD_I_SCOM, BUS_MCA, CHIP_NONE,
+		1, 2,  16,  16,  0x400
+	},
+	{ /* 18 */
+		"S2M ISA",       0x0000,  0x0100,
+		IDI_ADAPTER_PR,  FAMILY_S,  DI_NULL,
+		CARD_PR,   CARD_I_PR,  BUS_ISA, CHIP_NONE,
+		1, 30,  256, 0,   0x4000
+	},
+	{ /* 19 */
+		"S2M MCA",       0x6abb,  0x0100,
+		IDI_ADAPTER_PR,  FAMILY_S,  DI_NULL,
+		CARD_PR,   CARD_I_PR,  BUS_MCA, CHIP_NONE,
+		1, 30,  256, 16,  0x4000
+	},
+	{ /* 20 */
+		"Diva Server BRI-2M ISA",   0x0041,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAE,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
+		1, 2,   16,  8,  0
+	},
+	{ /* 21 */
+		"Diva Server BRI-2M PCI",   0xE010,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAE,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 2,   16,  8,   0
+	},
+	{ /* 22 */
+		"Diva Server 4BRI-8M PCI",   0xE012,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		4, 2,   16,  8,   0
+	},
+	{ /* 23 */
+		"Diva Server PRI-30M PCI",   0xE014,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 30,  256,  8,   0
+	},
+	{ /* 24 */
+		"Diva Server PRI-2M PCI",   0xe014,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 30,  256,  8,   0
+	},
+	{ /* 25 */
+		"Diva Server PRI-9M PCI",   0x0000,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 30,     256,  8,   0
+	},
+	{ /* 26 */
+		"Diva 2.0 S/T ISA",     0x0071,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_ISA, CHIP_HSCX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 27 */
+		"Diva 2.0 U ISA",     0x0091,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_ISA, CHIP_HSCX,
+		1, 2,   0,   8,   0
+	},
+	{ /* 28 */
+		"Diva 2.0 U PCI",     0xe004,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | DI_POTS | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCI, CHIP_HSCX,
+		1, 2,   0,   8,   0
+	},
+	{ /* 29 */
+		"Diva PRO 2.0 S/T ISA",    0x0061,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
+		CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
+		1, 2,  0,   8,   0
+	},
+	{ /* 30 */
+		"Diva PRO 2.0 U ISA",    0x0081,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
+		CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
+		1, 2,  0,   8,   0
+	},
+	{ /* 31 */
+		"Diva PRO 2.0 U PCI",    0xe003,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
+		CARD_PRO,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 2,   0,   8,   0
+	},
+	{ /* 32 */
+		"Diva MOBILE",      0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 33 */
+		"TDK DFI3600",      0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 34 (OEM version of 4 - "Diva PRO PC-Card") */
+		"New Media ISDN",     0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_PRO,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
+		1, 2,   0,   8,   0
+	},
+	{ /* 35 (OEM version of 7 - "Diva PRO 2.0 S/T PCI") */
+		"BT ExLane PCI",     0xe101,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
+		CARD_PRO,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 2,   0,   8,   0
+	},
+	{ /* 36 (OEM version of 29 - "Diva PRO 2.0 S/T ISA") */
+		"BT ExLane ISA",     0x1061,  0x0200,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_POTS,
+		CARD_PRO,   CARD_I_NONE, BUS_ISA, CHIP_DSP,
+		1, 2,   0,   8,   0
+	},
+	{ /* 37 */
+		"Diva 2.01 S/T ISA",    0x00A1,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_ISA, CHIP_IPAC,
+		1, 2,   0,   8,      0
+	},
+	{ /* 38 */
+		"Diva 2.01 U ISA",     0x00B1,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_ISA, CHIP_IPAC,
+		1, 2,   0,   8,      0
+	},
+	{ /* 39 */
+		"Diva 2.01 S/T PCI",    0xe005,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPAC,
+		1, 2,   0,   8,   0
+	},
+	{ /* 40        no ID yet */
+		"Diva 2.01 U PCI",     0x0000,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPAC,
+		1, 2,   0,   8,   0
+	},
+	{ /* 41 */
+		"Diva MOBILE V.90",     0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 42 */
+		"TDK DFI3600 V.90",     0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_HSCX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 43 */
+		"Diva Server PRI-23M PCI",   0xe014,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 30,  256,  8,   0
+	},
+	{ /* 44 */
+		"Diva 2.01 S/T USB",    0x1000,     0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_USB, CHIP_IPAC,
+		1,  2,  0,  8,   0
+	},
+	{ /* 45 */
+		"Diva CT S/T PCI",    0xe006,  0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1,  2,  0,  0,   0
+	},
+	{ /* 46 */
+		"Diva CT U PCI",     0xe007,  0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1,  2,  0,  0,   0
+	},
+	{ /* 47 */
+		"Diva CT Lite S/T PCI",   0xe008,  0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1,  2,  0,  0,   0
+	},
+	{ /* 48 */
+		"Diva CT Lite U PCI",   0xe009,  0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1,  2,  0,  0,   0
+	},
+	{ /* 49 */
+		"Diva ISDN+V.90 PC Card", 0x8D8C, 0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_DIVALOW, CARD_I_NONE, BUS_PCM, CHIP_IPAC,
+		1, 2,  0,   8,   0
+	},
+	{ /* 50 */
+		"Diva ISDN+V.90 PCI",    0xe00A,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120  | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPAC,
+		1, 2,   0,   8,   0
+	},
+	{ /* 51 (DivaTA)      no ID */
+		"Diva TA",       0x0000,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVATA,  CARD_I_NONE, BUS_COM, CHIP_EXTERN,
+		1, 1,   0,   8,   0
+	},
+	{ /* 52 (Diva Server 4BRI-8M PCI adapter enabled for Voice) */
+		"Diva Server Voice 4BRI-8M PCI", 0xE016,  0x0100,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
+		CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		4, 2,   16,  8,   0
+	},
+	{ /* 53 (Diva Server 4BRI 2.0 adapter) */
+		"Diva Server 4BRI-8M 2.0 PCI",  0xE013,  0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		4, 2,   16,  8,   0
+	},
+	{ /* 54 (Diva Server PRI 2.0 adapter) */
+		"Diva Server PRI 2.0 PCI",   0xE015,  0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 30,  256,  8,   0
+	},
+	{ /* 55 (Diva Server 4BRI-8M 2.0 PCI adapter enabled for Voice) */
+		"Diva Server Voice 4BRI-8M 2.0 PCI", 0xE017,  0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
+		CARD_MAEQ,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		4, 2,   16,  8,   0
+	},
+	{ /* 56 (Diva Server PRI 2.0 PCI adapter enabled for Voice) */
+		"Diva Server Voice PRI 2.0 PCI",  0xE019,  0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
+		CARD_MAEP,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 30,  256,  8,   0
+	},
+	{
+		/* 57 (DivaLan )      no ID */
+		"Diva LAN",       0x0000,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V110 | DI_FAX3 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALAN,  CARD_I_NONE, BUS_LAN, CHIP_EXTERN,
+		1, 1,   0,   8,   0
+	},
+	{ /* 58 */
+		"Diva 2.02 PCI S/T",    0xE00B,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES | DI_SOFT_V110,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPACX,
+		1, 2,   0,   8,   0
+	},
+	{ /* 59 */
+		"Diva 2.02 PCI U",     0xE00C,  0x0300,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_PCI, CHIP_IPACX,
+		1, 2,   0,   8,   0
+	},
+	{ /* 60 */
+		"Diva Server BRI-2M 2.0 PCI",     0xE018,  0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_MAE2,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 2,   16,  8,   0
+	},
+	{ /* 61  (the previous name was Diva Server BRI-2F 2.0 PCI) */
+		"Diva Server 2FX",                      0xE01A,     0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_SOFT_V110,
+		CARD_MAE2,          CARD_I_NONE,    BUS_PCI,    CHIP_IPACX,
+		1,  2,      16,     8,   0
+	},
+	{ /* 62 */
+		" Diva ISDN USB 2.0",    0x1003,     0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_DIVALOW,  CARD_I_NONE, BUS_USB, CHIP_IPACX,
+		1, 2,  0,  8,   0
+	},
+	{ /* 63 (Diva Server BRI-2M 2.0 PCI adapter enabled for Voice) */
+		"Diva Server Voice BRI-2M 2.0 PCI", 0xE01B,  0x0200,
+		IDI_ADAPTER_MAESTRA, FAMILY_MAESTRA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_VOICE_OVER_IP,
+		CARD_MAE2,   CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1, 2,   16,  8,   0
+	},
+	{ /* 64 */
+		"Diva Pro 3.0 PCI",    0xe00d,  0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM,
+		CARD_PRO,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1,  2,  0,  0,   0
+	},
+	{ /* 65 */
+		"Diva ISDN + CT 2.0",    0xE00E,  0x0300,
+		IDI_ADAPTER_DIVA   , FAMILY_DIVA, DI_V1x0 | DI_FAX3 | DI_MODEM | DI_CODEC,
+		CARD_CT,       CARD_I_NONE, BUS_PCI, CHIP_DSP,
+		1,  2,  0,  0,   0
+	},
+	{ /* 66 */
+		"Diva Mobile V.90 PC Card",  0x8331,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_IPACX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 67 */
+		"Diva ISDN PC Card",  0x8311,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PICO,   CARD_I_NONE, BUS_PCM, CHIP_IPACX,
+		1, 2,  0,   8,   0
+	},
+	{ /* 68 */
+		"Diva ISDN PC Card",  0x0000,  0x0100,
+		IDI_ADAPTER_DIVA, FAMILY_DIVA, DI_V120 | SOFT_DSP_ADD_FEATURES,
+		CARD_PRO,   CARD_I_NONE, BUS_PCM, CHIP_DSP,
+		1, 2,   0,   8,      0
+	},
+};
 #if CARDTYPE_H_WANT_RESOURCE_DATA
 /*--- CardResource [Index=CARDTYPE_....]   ---------------------------(GEI)-*/
-CARD_RESOURCE CardResource [ ] =  {
+CARD_RESOURCE CardResource[] = {
 /*   Interrupts     IO-Address   Mem-Address */
-/* 0*/ {  3,4,9,0,0,0,0,0,0,0,   0x200,0x20,16,   0x0,0x0,0   }, // DIVA MCA
-/* 1*/ {  3,4,9,10,11,12,0,0,0,0,  0x200,0x20,16,   0x0,0x0,0   }, // DIVA ISA
-/* 2*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PCMCIA
-/* 3*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // DIVA PRO ISA
-/* 4*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PRO PCMCIA
-/* 5*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA PICCOLA ISA
-/* 6*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA PICCOLA PCMCIA
-/* 7*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PRO 2.0 PCI
-/* 8*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.0 PCI
-/* 9*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0x80000,0x2000,64 }, // QUADRO ISA
-/*10*/ {  3,4,9,10,11,12,0,0,0,0,  0x0,0x0,0,   0xc0000,0x2000,16 }, // S ISA
-/*11*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // S MCA
-/*12*/ {  3,4,9,10,11,12,0,0,0,0,  0x0,0x0,0,   0xc0000,0x2000,16 }, // SX ISA
-/*13*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // SX MCA
-/*14*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0x80000,0x0800,256 }, // SXN ISA
-/*15*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // SXN MCA
-/*16*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0x80000,0x0800,256 }, // SCOM ISA
-/*17*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // SCOM MCA
-/*18*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0xc0000,0x4000,16 }, // S2M ISA
-/*19*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x4000,16 }, // S2M MCA
-/*20*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // MAESTRA ISA
-/*21*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA PCI
-/*22*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // MAESTRA QUADRO ISA
-/*23*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA QUADRO PCI
-/*24*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // MAESTRA PRIMARY ISA
-/*25*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA PRIMARY PCI
-/*26*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.0 ISA
-/*27*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.0 /U ISA
-/*28*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.0 /U PCI
-/*29*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // DIVA PRO 2.0 ISA
-/*30*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // DIVA PRO 2.0 /U ISA
-/*31*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PRO 2.0 /U PCI
-/*32*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA MOBILE
-/*33*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // TDK DFI3600 (same as DIVA MOBILE [32])
-/*34*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // New Media ISDN (same as DIVA PRO PCMCIA [4])
-/*35*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // BT ExLane PCI (same as DIVA PRO 2.0 PCI [7])
-/*36*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // BT ExLane ISA (same as DIVA PRO 2.0 ISA [29])
-/*37*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.01 S/T ISA
-/*38*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.01 U ISA
-/*39*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.01 S/T PCI
-/*40*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.01 U PCI
-/*41*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA MOBILE V.90
-/*42*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // TDK DFI3600 V.90 (same as DIVA MOBILE V.90 [39])
-/*43*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // DIVA Server PRI-23M PCI
-/*44*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA 2.01 S/T USB
-/*45*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT S/T PCI
-/*46*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT U PCI
-/*47*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT Lite S/T PCI
-/*48*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT Lite U PCI
-/*49*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA ISDN+V.90 PC Card
-/*50*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA ISDN+V.90 PCI
-/*51*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA TA
-/*52*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA VOICE QUADRO PCI
-/*53*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA VOICE QUADRO PCI
-/*54*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA VOICE PRIMARY PCI
-/*55*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA VOICE QUADRO PCI
-/*56*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA VOICE PRIMARY PCI
-/*57*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA LAN
-/*58*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.02 S/T PCI
-/*59*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.02 U PCI
-/*60*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // Diva Server BRI-2M 2.0 PCI
-/*61*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // Diva Server BRI-2F PCI
-/*62*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA 2.01 S/T USB
-/*63*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // Diva Server Voice BRI-2M 2.0 PCI
-/*64*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 3.0 PCI
-/*65*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT S/T PCI V2.0
-/*66*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA Mobile V.90 PC Card
-/*67*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA ISDN PC Card
-/*68*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA ISDN PC Card
+	/* 0*/ {  3,4,9,0,0,0,0,0,0,0,   0x200,0x20,16,   0x0,0x0,0   }, // DIVA MCA
+	/* 1*/ {  3,4,9,10,11,12,0,0,0,0,  0x200,0x20,16,   0x0,0x0,0   }, // DIVA ISA
+	/* 2*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PCMCIA
+	/* 3*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // DIVA PRO ISA
+	/* 4*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PRO PCMCIA
+	/* 5*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA PICCOLA ISA
+	/* 6*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA PICCOLA PCMCIA
+	/* 7*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PRO 2.0 PCI
+	/* 8*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.0 PCI
+	/* 9*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0x80000,0x2000,64 }, // QUADRO ISA
+	/*10*/ {  3,4,9,10,11,12,0,0,0,0,  0x0,0x0,0,   0xc0000,0x2000,16 }, // S ISA
+	/*11*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // S MCA
+	/*12*/ {  3,4,9,10,11,12,0,0,0,0,  0x0,0x0,0,   0xc0000,0x2000,16 }, // SX ISA
+	/*13*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // SX MCA
+	/*14*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0x80000,0x0800,256 }, // SXN ISA
+	/*15*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // SXN MCA
+	/*16*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0x80000,0x0800,256 }, // SCOM ISA
+	/*17*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x2000,16 }, // SCOM MCA
+	/*18*/ {  3,4,5,7,9,10,11,12,0,0,  0x0,0x0,0,   0xc0000,0x4000,16 }, // S2M ISA
+	/*19*/ {  3,4,9,0,0,0,0,0,0,0,  0xc00,0x10,16,  0xc0000,0x4000,16 }, // S2M MCA
+	/*20*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // MAESTRA ISA
+	/*21*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA PCI
+	/*22*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // MAESTRA QUADRO ISA
+	/*23*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA QUADRO PCI
+	/*24*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // MAESTRA PRIMARY ISA
+	/*25*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA PRIMARY PCI
+	/*26*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.0 ISA
+	/*27*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.0 /U ISA
+	/*28*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.0 /U PCI
+	/*29*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // DIVA PRO 2.0 ISA
+	/*30*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // DIVA PRO 2.0 /U ISA
+	/*31*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA PRO 2.0 /U PCI
+	/*32*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA MOBILE
+	/*33*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // TDK DFI3600 (same as DIVA MOBILE [32])
+	/*34*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // New Media ISDN (same as DIVA PRO PCMCIA [4])
+	/*35*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // BT ExLane PCI (same as DIVA PRO 2.0 PCI [7])
+	/*36*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,   0x0,0x0,0   }, // BT ExLane ISA (same as DIVA PRO 2.0 ISA [29])
+	/*37*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.01 S/T ISA
+	/*38*/ {  3,5,7,9,10,11,12,14,15,0, 0x200,0x20,16,  0x0,0x0,0   }, // DIVA 2.01 U ISA
+	/*39*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.01 S/T PCI
+	/*40*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.01 U PCI
+	/*41*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA MOBILE V.90
+	/*42*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // TDK DFI3600 V.90 (same as DIVA MOBILE V.90 [39])
+	/*43*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // DIVA Server PRI-23M PCI
+	/*44*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA 2.01 S/T USB
+	/*45*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT S/T PCI
+	/*46*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT U PCI
+	/*47*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT Lite S/T PCI
+	/*48*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT Lite U PCI
+	/*49*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA ISDN+V.90 PC Card
+	/*50*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA ISDN+V.90 PCI
+	/*51*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA TA
+	/*52*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA VOICE QUADRO PCI
+	/*53*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA VOICE QUADRO PCI
+	/*54*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA VOICE PRIMARY PCI
+	/*55*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x20,2048,  0x0,0x0,0   }, // MAESTRA VOICE QUADRO PCI
+	/*56*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // MAESTRA VOICE PRIMARY PCI
+	/*57*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA LAN
+	/*58*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.02 S/T PCI
+	/*59*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 2.02 U PCI
+	/*60*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // Diva Server BRI-2M 2.0 PCI
+	/*61*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // Diva Server BRI-2F PCI
+	/*62*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA 2.01 S/T USB
+	/*63*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // Diva Server Voice BRI-2M 2.0 PCI
+	/*64*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA 3.0 PCI
+	/*65*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA CT S/T PCI V2.0
+	/*66*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA Mobile V.90 PC Card
+	/*67*/ {  0,0,0,0,0,0,0,0,0,0,  0x0,0x0,0,   0x0,0x0,0   }, // DIVA ISDN PC Card
+	/*68*/ {  3,4,5,7,9,10,11,12,14,15, 0x0,0x8,8192,  0x0,0x0,0   }, // DIVA ISDN PC Card
 };
 #endif /*CARDTYPE_H_WANT_RESOURCE_DATA*/
 #else /*!CARDTYPE_H_WANT_DATA*/
-extern CARD_PROPERTIES  CardProperties [] ;
-extern CARD_RESOURCE  CardResource [] ;
+extern CARD_PROPERTIES  CardProperties[];
+extern CARD_RESOURCE  CardResource[];
 #endif /*CARDTYPE_H_WANT_DATA*/
 /*
  * all existing download files
@@ -902,197 +902,197 @@ extern CARD_RESOURCE  CardResource [] ;
 #define CARD_D_NEW_DSP_COMBIFILE 63
 typedef struct CARD_FILES_DATA
 {
- char *    Name;
- unsigned char  Type;
+	char *Name;
+	unsigned char  Type;
 }
-CARD_FILES_DATA;
+	CARD_FILES_DATA;
 typedef struct CARD_FILES
 {
- unsigned char  Boot;
- unsigned char  Dsp  [CARD_DSP_CNT];
- unsigned char  DspTelindus;
- unsigned char  Prot [CARD_PROT_CNT];
+	unsigned char  Boot;
+	unsigned char  Dsp[CARD_DSP_CNT];
+	unsigned char  DspTelindus;
+	unsigned char  Prot[CARD_PROT_CNT];
 }
-CARD_FILES;
+	CARD_FILES;
 #if CARDTYPE_H_WANT_DATA
 #if CARDTYPE_H_WANT_FILE_DATA
-CARD_FILES_DATA CardFData [] =  {
+CARD_FILES_DATA CardFData[] = {
 // Filename   Filetype
- 0,     CARD_FT_UNKNOWN,
- "didnload.bin",  CARD_FT_B,
- "diprload.bin",  CARD_FT_B,
- "didiva.bin",  CARD_FT_D,
- "didivapp.bin",  CARD_FT_D,
- "dihscx.bin",  CARD_FT_D,
- "div110.bin",  CARD_FT_D,
- "dimodem.bin",  CARD_FT_D,
- "difax.bin",  CARD_FT_D,
- "di_etsi.bin",  CARD_FT_S,
- "di_1tr6.bin",  CARD_FT_S,
- "di_belg.bin",  CARD_FT_S,
- "di_franc.bin",  CARD_FT_S,
- "di_atel.bin",  CARD_FT_S,
- "di_ni.bin",  CARD_FT_S,
- "di_5ess.bin",  CARD_FT_S,
- "di_japan.bin",  CARD_FT_S,
- "di_etsi.sx",  CARD_FT_S,
- "di_1tr6.sx",  CARD_FT_S,
- "di_belg.sx",  CARD_FT_S,
- "di_franc.sx",  CARD_FT_S,
- "di_atel.sx",  CARD_FT_S,
- "di_ni.sx",   CARD_FT_S,
- "di_5ess.sx",  CARD_FT_S,
- "di_japan.sx",  CARD_FT_S,
- "di_etsi.sy",  CARD_FT_S,
- "di_1tr6.sy",  CARD_FT_S,
- "di_belg.sy",  CARD_FT_S,
- "di_franc.sy",  CARD_FT_S,
- "di_atel.sy",  CARD_FT_S,
- "di_ni.sy",   CARD_FT_S,
- "di_5ess.sy",  CARD_FT_S,
- "di_japan.sy",  CARD_FT_S,
- "di_etsi.sq",  CARD_FT_S,
- "di_1tr6.sq",  CARD_FT_S,
- "di_belg.sq",  CARD_FT_S,
- "di_franc.sq",  CARD_FT_S,
- "di_atel.sq",  CARD_FT_S,
- "di_ni.sq",   CARD_FT_S,
- "di_5ess.sq",  CARD_FT_S,
- "di_japan.sq",  CARD_FT_S,
- "di_etsi.p",  CARD_FT_S,
- "di_1tr6.p",  CARD_FT_S,
- "di_belg.p",  CARD_FT_S,
- "di_franc.p",  CARD_FT_S,
- "di_atel.p",  CARD_FT_S,
- "di_ni.p",   CARD_FT_S,
- "di_5ess.p",  CARD_FT_S,
- "di_japan.p",  CARD_FT_S,
- "di_etsi.sm",  CARD_FT_M,
- "di_1tr6.sm",  CARD_FT_M,
- "di_belg.sm",  CARD_FT_M,
- "di_franc.sm",  CARD_FT_M,
- "di_atel.sm",  CARD_FT_M,
- "di_ni.sm",   CARD_FT_M,
- "di_5ess.sm",  CARD_FT_M,
- "di_japan.sm",  CARD_FT_M,
- "di_swed.bin",  CARD_FT_S,
- "di_swed.sx",  CARD_FT_S,
- "di_swed.sy",  CARD_FT_S,
- "di_swed.sq",  CARD_FT_S,
- "di_swed.p",  CARD_FT_S,
- "di_swed.sm",  CARD_FT_M,
-    "didspdld.bin",     CARD_FT_NEW_DSP_COMBIFILE
+	0,     CARD_FT_UNKNOWN,
+	"didnload.bin",  CARD_FT_B,
+	"diprload.bin",  CARD_FT_B,
+	"didiva.bin",  CARD_FT_D,
+	"didivapp.bin",  CARD_FT_D,
+	"dihscx.bin",  CARD_FT_D,
+	"div110.bin",  CARD_FT_D,
+	"dimodem.bin",  CARD_FT_D,
+	"difax.bin",  CARD_FT_D,
+	"di_etsi.bin",  CARD_FT_S,
+	"di_1tr6.bin",  CARD_FT_S,
+	"di_belg.bin",  CARD_FT_S,
+	"di_franc.bin",  CARD_FT_S,
+	"di_atel.bin",  CARD_FT_S,
+	"di_ni.bin",  CARD_FT_S,
+	"di_5ess.bin",  CARD_FT_S,
+	"di_japan.bin",  CARD_FT_S,
+	"di_etsi.sx",  CARD_FT_S,
+	"di_1tr6.sx",  CARD_FT_S,
+	"di_belg.sx",  CARD_FT_S,
+	"di_franc.sx",  CARD_FT_S,
+	"di_atel.sx",  CARD_FT_S,
+	"di_ni.sx",   CARD_FT_S,
+	"di_5ess.sx",  CARD_FT_S,
+	"di_japan.sx",  CARD_FT_S,
+	"di_etsi.sy",  CARD_FT_S,
+	"di_1tr6.sy",  CARD_FT_S,
+	"di_belg.sy",  CARD_FT_S,
+	"di_franc.sy",  CARD_FT_S,
+	"di_atel.sy",  CARD_FT_S,
+	"di_ni.sy",   CARD_FT_S,
+	"di_5ess.sy",  CARD_FT_S,
+	"di_japan.sy",  CARD_FT_S,
+	"di_etsi.sq",  CARD_FT_S,
+	"di_1tr6.sq",  CARD_FT_S,
+	"di_belg.sq",  CARD_FT_S,
+	"di_franc.sq",  CARD_FT_S,
+	"di_atel.sq",  CARD_FT_S,
+	"di_ni.sq",   CARD_FT_S,
+	"di_5ess.sq",  CARD_FT_S,
+	"di_japan.sq",  CARD_FT_S,
+	"di_etsi.p",  CARD_FT_S,
+	"di_1tr6.p",  CARD_FT_S,
+	"di_belg.p",  CARD_FT_S,
+	"di_franc.p",  CARD_FT_S,
+	"di_atel.p",  CARD_FT_S,
+	"di_ni.p",   CARD_FT_S,
+	"di_5ess.p",  CARD_FT_S,
+	"di_japan.p",  CARD_FT_S,
+	"di_etsi.sm",  CARD_FT_M,
+	"di_1tr6.sm",  CARD_FT_M,
+	"di_belg.sm",  CARD_FT_M,
+	"di_franc.sm",  CARD_FT_M,
+	"di_atel.sm",  CARD_FT_M,
+	"di_ni.sm",   CARD_FT_M,
+	"di_5ess.sm",  CARD_FT_M,
+	"di_japan.sm",  CARD_FT_M,
+	"di_swed.bin",  CARD_FT_S,
+	"di_swed.sx",  CARD_FT_S,
+	"di_swed.sy",  CARD_FT_S,
+	"di_swed.sq",  CARD_FT_S,
+	"di_swed.p",  CARD_FT_S,
+	"di_swed.sm",  CARD_FT_M,
+	"didspdld.bin",     CARD_FT_NEW_DSP_COMBIFILE
 };
-CARD_FILES CardFiles [] =
+CARD_FILES CardFiles[] =
 {
- { /* CARD_UNKNOWN */
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE
- },
- { /* CARD_DIVA */
-  CARD_FILE_NONE,
-  CARD_D_K1, CARD_D_H, CARD_D_V, CARD_FILE_NONE, CARD_D_F,
-  CARD_D_NEW_DSP_COMBIFILE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE
- },
- { /* CARD_PRO  */
-  CARD_FILE_NONE,
-  CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F,
-  CARD_D_NEW_DSP_COMBIFILE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE
- },
- { /* CARD_PICO */
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE
- },
- { /* CARD_S    */
-  CARD_B_S,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_P_S_E, CARD_P_S_1, CARD_P_S_B, CARD_P_S_F,
-  CARD_P_S_A, CARD_P_S_N, CARD_P_S_5, CARD_P_S_J,
-  CARD_P_S_S
- },
- { /* CARD_SX   */
-  CARD_B_S,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_P_SX_E, CARD_P_SX_1, CARD_P_SX_B, CARD_P_SX_F,
-  CARD_P_SX_A, CARD_P_SX_N, CARD_P_SX_5, CARD_P_SX_J,
-  CARD_P_SX_S
- },
- { /* CARD_SXN  */
-  CARD_B_S,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F,
-  CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J,
-  CARD_P_SY_S
- },
- { /* CARD_SCOM */
-  CARD_B_S,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F,
-  CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J,
-  CARD_P_SY_S
- },
- { /* CARD_QUAD */
-  CARD_B_S,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_P_SQ_E, CARD_P_SQ_1, CARD_P_SQ_B, CARD_P_SQ_F,
-  CARD_P_SQ_A, CARD_P_SQ_N, CARD_P_SQ_5, CARD_P_SQ_J,
-  CARD_P_SQ_S
- },
- { /* CARD_PR   */
-  CARD_B_P,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_P_P_E, CARD_P_P_1, CARD_P_P_B, CARD_P_P_F,
-  CARD_P_P_A, CARD_P_P_N, CARD_P_P_5, CARD_P_P_J,
-  CARD_P_P_S
- },
- { /* CARD_MAE  */
-  CARD_FILE_NONE,
-  CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F,
-  CARD_D_NEW_DSP_COMBIFILE,
-  CARD_P_M_E, CARD_P_M_1, CARD_P_M_B, CARD_P_M_F,
-  CARD_P_M_A, CARD_P_M_N, CARD_P_M_5, CARD_P_M_J,
-  CARD_P_M_S
- },
- { /* CARD_MAEQ */  /* currently not supported */
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE
- },
- { /* CARD_MAEP */  /* currently not supported */
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
-  CARD_FILE_NONE
- }
+	{ /* CARD_UNKNOWN */
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE
+	},
+	{ /* CARD_DIVA */
+		CARD_FILE_NONE,
+		CARD_D_K1, CARD_D_H, CARD_D_V, CARD_FILE_NONE, CARD_D_F,
+		CARD_D_NEW_DSP_COMBIFILE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE
+	},
+	{ /* CARD_PRO  */
+		CARD_FILE_NONE,
+		CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F,
+		CARD_D_NEW_DSP_COMBIFILE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE
+	},
+	{ /* CARD_PICO */
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE
+	},
+	{ /* CARD_S    */
+		CARD_B_S,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_P_S_E, CARD_P_S_1, CARD_P_S_B, CARD_P_S_F,
+		CARD_P_S_A, CARD_P_S_N, CARD_P_S_5, CARD_P_S_J,
+		CARD_P_S_S
+	},
+	{ /* CARD_SX   */
+		CARD_B_S,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_P_SX_E, CARD_P_SX_1, CARD_P_SX_B, CARD_P_SX_F,
+		CARD_P_SX_A, CARD_P_SX_N, CARD_P_SX_5, CARD_P_SX_J,
+		CARD_P_SX_S
+	},
+	{ /* CARD_SXN  */
+		CARD_B_S,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F,
+		CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J,
+		CARD_P_SY_S
+	},
+	{ /* CARD_SCOM */
+		CARD_B_S,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_P_SY_E, CARD_P_SY_1, CARD_P_SY_B, CARD_P_SY_F,
+		CARD_P_SY_A, CARD_P_SY_N, CARD_P_SY_5, CARD_P_SY_J,
+		CARD_P_SY_S
+	},
+	{ /* CARD_QUAD */
+		CARD_B_S,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_P_SQ_E, CARD_P_SQ_1, CARD_P_SQ_B, CARD_P_SQ_F,
+		CARD_P_SQ_A, CARD_P_SQ_N, CARD_P_SQ_5, CARD_P_SQ_J,
+		CARD_P_SQ_S
+	},
+	{ /* CARD_PR   */
+		CARD_B_P,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_P_P_E, CARD_P_P_1, CARD_P_P_B, CARD_P_P_F,
+		CARD_P_P_A, CARD_P_P_N, CARD_P_P_5, CARD_P_P_J,
+		CARD_P_P_S
+	},
+	{ /* CARD_MAE  */
+		CARD_FILE_NONE,
+		CARD_D_K2, CARD_D_H, CARD_D_V, CARD_D_M, CARD_D_F,
+		CARD_D_NEW_DSP_COMBIFILE,
+		CARD_P_M_E, CARD_P_M_1, CARD_P_M_B, CARD_P_M_F,
+		CARD_P_M_A, CARD_P_M_N, CARD_P_M_5, CARD_P_M_J,
+		CARD_P_M_S
+	},
+	{ /* CARD_MAEQ */  /* currently not supported */
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE
+	},
+	{ /* CARD_MAEP */  /* currently not supported */
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE, CARD_FILE_NONE,
+		CARD_FILE_NONE
+	}
 };
 #endif /*CARDTYPE_H_WANT_FILE_DATA*/
 #else /*!CARDTYPE_H_WANT_DATA*/
-extern CARD_FILES_DATA  CardFData [] ;
-extern CARD_FILES   CardFiles [] ;
+extern CARD_FILES_DATA  CardFData[];
+extern CARD_FILES   CardFiles[];
 #endif /*CARDTYPE_H_WANT_DATA*/
 #endif /* _CARDTYPE_H_ */
diff --git a/drivers/isdn/hardware/eicon/cp_vers.h b/drivers/isdn/hardware/eicon/cp_vers.h
index cb5ada3..c97230c 100644
--- a/drivers/isdn/hardware/eicon/cp_vers.h
+++ b/drivers/isdn/hardware/eicon/cp_vers.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
-static char diva_capi_common_code_build[] = "102-28";  
+static char diva_capi_common_code_build[] = "102-28";
diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
index 8949789..5142099 100644
--- a/drivers/isdn/hardware/eicon/dadapter.c
+++ b/drivers/isdn/hardware/eicon/dadapter.c
@@ -1,26 +1,25 @@
-
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -30,337 +29,336 @@
 #include "divasync.h"
 #include "dadapter.h"
 /* --------------------------------------------------------------------------
-  Adapter array change notification framework
+   Adapter array change notification framework
    -------------------------------------------------------------------------- */
 typedef struct _didd_adapter_change_notification {
- didd_adapter_change_callback_t callback;
- void IDI_CALL_ENTITY_T *    context;
-} didd_adapter_change_notification_t, \
- * IDI_CALL_ENTITY_T pdidd_adapter_change_notification_t;
+	didd_adapter_change_callback_t callback;
+	void IDI_CALL_ENTITY_T *context;
+} didd_adapter_change_notification_t,				\
+	* IDI_CALL_ENTITY_T pdidd_adapter_change_notification_t;
 #define DIVA_DIDD_MAX_NOTIFICATIONS 256
-static didd_adapter_change_notification_t\
-              NotificationTable[DIVA_DIDD_MAX_NOTIFICATIONS];
+static didd_adapter_change_notification_t	\
+NotificationTable[DIVA_DIDD_MAX_NOTIFICATIONS];
 /* --------------------------------------------------------------------------
-  Array to held adapter information
+   Array to held adapter information
    -------------------------------------------------------------------------- */
 static DESCRIPTOR  HandleTable[NEW_MAX_DESCRIPTORS];
 static dword Adapters = 0; /* Number of adapters */
 /* --------------------------------------------------------------------------
-  Shadow IDI_DIMAINT
-  and 'shadow' debug stuff
+   Shadow IDI_DIMAINT
+   and 'shadow' debug stuff
    -------------------------------------------------------------------------- */
-static void no_printf (unsigned char * format, ...)
+static void no_printf(unsigned char *format, ...)
 {
 #ifdef EBUG
 	va_list ap;
-	va_start (ap, format);
+	va_start(ap, format);
 	debug((format, ap));
-	va_end (ap);
+	va_end(ap);
 #endif
 }
 
 /* -------------------------------------------------------------------------
-  Portable debug Library
-  ------------------------------------------------------------------------- */
+   Portable debug Library
+   ------------------------------------------------------------------------- */
 #include "debuglib.c"
-  
+
 static DESCRIPTOR  MAdapter =  {IDI_DIMAINT, /* Adapter Type */
-                0x00,     /* Channels */
-                0x0000,    /* Features */
-                (IDI_CALL)no_printf};
+				0x00,     /* Channels */
+				0x0000,    /* Features */
+				(IDI_CALL)no_printf};
 /* --------------------------------------------------------------------------
-  DAdapter. Only IDI clients with buffer, that is huge enough to
-  get all descriptors will receive information about DAdapter
-  { byte type, byte channels, word features, IDI_CALL request }
+   DAdapter. Only IDI clients with buffer, that is huge enough to
+   get all descriptors will receive information about DAdapter
+   { byte type, byte channels, word features, IDI_CALL request }
    -------------------------------------------------------------------------- */
-static void IDI_CALL_LINK_T diva_dadapter_request (ENTITY IDI_CALL_ENTITY_T *);
+static void IDI_CALL_LINK_T diva_dadapter_request(ENTITY IDI_CALL_ENTITY_T *);
 static DESCRIPTOR  DAdapter =  {IDI_DADAPTER, /* Adapter Type */
-                0x00,     /* Channels */
-                0x0000,    /* Features */
-                diva_dadapter_request };
+				0x00,     /* Channels */
+				0x0000,    /* Features */
+				diva_dadapter_request };
 /* --------------------------------------------------------------------------
-  LOCALS
+   LOCALS
    -------------------------------------------------------------------------- */
-static dword diva_register_adapter_callback (\
-                   didd_adapter_change_callback_t callback,
-                   void IDI_CALL_ENTITY_T* context);
-static void diva_remove_adapter_callback (dword handle);
-static void diva_notify_adapter_change (DESCRIPTOR* d, int removal);
+static dword diva_register_adapter_callback(\
+	didd_adapter_change_callback_t callback,
+	void IDI_CALL_ENTITY_T *context);
+static void diva_remove_adapter_callback(dword handle);
+static void diva_notify_adapter_change(DESCRIPTOR *d, int removal);
 static diva_os_spin_lock_t didd_spin;
 /* --------------------------------------------------------------------------
-  Should be called as first step, after driver init
-  -------------------------------------------------------------------------- */
-void diva_didd_load_time_init (void) {
- memset (&HandleTable[0], 0x00, sizeof(HandleTable));
- memset (&NotificationTable[0], 0x00, sizeof(NotificationTable));
- diva_os_initialize_spin_lock (&didd_spin, "didd");
+   Should be called as first step, after driver init
+   -------------------------------------------------------------------------- */
+void diva_didd_load_time_init(void) {
+	memset(&HandleTable[0], 0x00, sizeof(HandleTable));
+	memset(&NotificationTable[0], 0x00, sizeof(NotificationTable));
+	diva_os_initialize_spin_lock(&didd_spin, "didd");
 }
 /* --------------------------------------------------------------------------
-  Should be called as last step, if driver does unload
-  -------------------------------------------------------------------------- */
-void diva_didd_load_time_finit (void) {
- diva_os_destroy_spin_lock (&didd_spin, "didd");
+   Should be called as last step, if driver does unload
+   -------------------------------------------------------------------------- */
+void diva_didd_load_time_finit(void) {
+	diva_os_destroy_spin_lock(&didd_spin, "didd");
 }
 /* --------------------------------------------------------------------------
-  Called in order to register new adapter in adapter array
-  return adapter handle (> 0) on success
-  return -1 adapter array overflow
-  -------------------------------------------------------------------------- */
-static int diva_didd_add_descriptor (DESCRIPTOR* d) {
- diva_os_spin_lock_magic_t      irql;
- int i;
- if (d->type == IDI_DIMAINT) {
-  if (d->request) {
-   MAdapter.request = d->request;
-   dprintf = (DIVA_DI_PRINTF)d->request;
-   diva_notify_adapter_change (&MAdapter, 0); /* Inserted */
-   DBG_TRC (("DIMAINT registered, dprintf=%08x", d->request))
-  } else {
-   DBG_TRC (("DIMAINT removed"))
-   diva_notify_adapter_change (&MAdapter, 1); /* About to remove */
-   MAdapter.request = (IDI_CALL)no_printf;
-   dprintf = no_printf;
-  }
-  return (NEW_MAX_DESCRIPTORS);
- }
- for (i = 0; i < NEW_MAX_DESCRIPTORS; i++) {
-  diva_os_enter_spin_lock (&didd_spin, &irql, "didd_add");
-  if (HandleTable[i].type == 0) {
-   memcpy (&HandleTable[i], d, sizeof(*d));
-   Adapters++;
-   diva_os_leave_spin_lock (&didd_spin, &irql, "didd_add");
-   diva_notify_adapter_change (d, 0); /* we have new adapter */
-   DBG_TRC (("Add adapter[%d], request=%08x", (i+1), d->request))
-   return (i+1);
-  }
-  diva_os_leave_spin_lock (&didd_spin, &irql, "didd_add");
- }
- DBG_ERR (("Can't add adapter, out of resources"))
- return (-1);
+   Called in order to register new adapter in adapter array
+   return adapter handle (> 0) on success
+   return -1 adapter array overflow
+   -------------------------------------------------------------------------- */
+static int diva_didd_add_descriptor(DESCRIPTOR *d) {
+	diva_os_spin_lock_magic_t      irql;
+	int i;
+	if (d->type == IDI_DIMAINT) {
+		if (d->request) {
+			MAdapter.request = d->request;
+			dprintf = (DIVA_DI_PRINTF)d->request;
+			diva_notify_adapter_change(&MAdapter, 0); /* Inserted */
+			DBG_TRC(("DIMAINT registered, dprintf=%08x", d->request))
+				} else {
+			DBG_TRC(("DIMAINT removed"))
+				diva_notify_adapter_change(&MAdapter, 1); /* About to remove */
+			MAdapter.request = (IDI_CALL)no_printf;
+			dprintf = no_printf;
+		}
+		return (NEW_MAX_DESCRIPTORS);
+	}
+	for (i = 0; i < NEW_MAX_DESCRIPTORS; i++) {
+		diva_os_enter_spin_lock(&didd_spin, &irql, "didd_add");
+		if (HandleTable[i].type == 0) {
+			memcpy(&HandleTable[i], d, sizeof(*d));
+			Adapters++;
+			diva_os_leave_spin_lock(&didd_spin, &irql, "didd_add");
+			diva_notify_adapter_change(d, 0); /* we have new adapter */
+			DBG_TRC(("Add adapter[%d], request=%08x", (i + 1), d->request))
+				return (i + 1);
+		}
+		diva_os_leave_spin_lock(&didd_spin, &irql, "didd_add");
+	}
+	DBG_ERR(("Can't add adapter, out of resources"))
+		return (-1);
 }
 /* --------------------------------------------------------------------------
-  Called in order to remove one registered adapter from array
-  return adapter handle (> 0) on success
-  return 0 on success
-  -------------------------------------------------------------------------- */
-static int diva_didd_remove_descriptor (IDI_CALL request) {
- diva_os_spin_lock_magic_t      irql;
- int i;
- if (request == MAdapter.request) {
-  DBG_TRC(("DIMAINT removed"))
-  dprintf = no_printf;
-  diva_notify_adapter_change (&MAdapter, 1); /* About to remove */
-  MAdapter.request = (IDI_CALL)no_printf;
-  return (0);
- }
- for (i = 0; (Adapters && (i < NEW_MAX_DESCRIPTORS)); i++) {
-  if (HandleTable[i].request == request) {
-   diva_notify_adapter_change (&HandleTable[i], 1); /* About to remove */
-   diva_os_enter_spin_lock (&didd_spin, &irql, "didd_rm");
-   memset (&HandleTable[i], 0x00, sizeof(HandleTable[0]));
-   Adapters--;
-   diva_os_leave_spin_lock (&didd_spin, &irql, "didd_rm");
-   DBG_TRC (("Remove adapter[%d], request=%08x", (i+1), request))
-   return (0);
-  }
- }
- DBG_ERR (("Invalid request=%08x, can't remove adapter", request))
- return (-1);
+   Called in order to remove one registered adapter from array
+   return adapter handle (> 0) on success
+   return 0 on success
+   -------------------------------------------------------------------------- */
+static int diva_didd_remove_descriptor(IDI_CALL request) {
+	diva_os_spin_lock_magic_t      irql;
+	int i;
+	if (request == MAdapter.request) {
+		DBG_TRC(("DIMAINT removed"))
+			dprintf = no_printf;
+		diva_notify_adapter_change(&MAdapter, 1); /* About to remove */
+		MAdapter.request = (IDI_CALL)no_printf;
+		return (0);
+	}
+	for (i = 0; (Adapters && (i < NEW_MAX_DESCRIPTORS)); i++) {
+		if (HandleTable[i].request == request) {
+			diva_notify_adapter_change(&HandleTable[i], 1); /* About to remove */
+			diva_os_enter_spin_lock(&didd_spin, &irql, "didd_rm");
+			memset(&HandleTable[i], 0x00, sizeof(HandleTable[0]));
+			Adapters--;
+			diva_os_leave_spin_lock(&didd_spin, &irql, "didd_rm");
+			DBG_TRC(("Remove adapter[%d], request=%08x", (i + 1), request))
+				return (0);
+		}
+	}
+	DBG_ERR(("Invalid request=%08x, can't remove adapter", request))
+		return (-1);
 }
 /* --------------------------------------------------------------------------
-  Read adapter array
-  return 1 if not enough space to save all available adapters
+   Read adapter array
+   return 1 if not enough space to save all available adapters
    -------------------------------------------------------------------------- */
-static int diva_didd_read_adapter_array (DESCRIPTOR* buffer, int length) {
- diva_os_spin_lock_magic_t      irql;
- int src, dst;
- memset (buffer, 0x00, length);
- length /= sizeof(DESCRIPTOR);
- DBG_TRC (("DIDD_Read, space = %d, Adapters = %d", length, Adapters+2))
- 
- diva_os_enter_spin_lock (&didd_spin, &irql, "didd_read");
- for (src = 0, dst = 0;
-    (Adapters && (src < NEW_MAX_DESCRIPTORS) && (dst < length));
-    src++) {
-  if (HandleTable[src].type) {
-   memcpy (&buffer[dst], &HandleTable[src], sizeof(DESCRIPTOR));
-   dst++;
-  }
- }
- diva_os_leave_spin_lock (&didd_spin, &irql, "didd_read");
- if (dst < length) {
-  memcpy (&buffer[dst], &MAdapter, sizeof(DESCRIPTOR));
-  dst++;
- } else {
-  DBG_ERR (("Can't write DIMAINT. Array too small"))
- }
- if (dst < length) {
-  memcpy (&buffer[dst], &DAdapter, sizeof(DESCRIPTOR));
-  dst++;
- } else {
-  DBG_ERR (("Can't write DADAPTER. Array too small"))
- }
- DBG_TRC (("Read %d adapters", dst))
- return (dst == length);
+static int diva_didd_read_adapter_array(DESCRIPTOR *buffer, int length) {
+	diva_os_spin_lock_magic_t      irql;
+	int src, dst;
+	memset(buffer, 0x00, length);
+	length /= sizeof(DESCRIPTOR);
+	DBG_TRC(("DIDD_Read, space = %d, Adapters = %d", length, Adapters + 2))
+
+		diva_os_enter_spin_lock(&didd_spin, &irql, "didd_read");
+	for (src = 0, dst = 0;
+	     (Adapters && (src < NEW_MAX_DESCRIPTORS) && (dst < length));
+	     src++) {
+		if (HandleTable[src].type) {
+			memcpy(&buffer[dst], &HandleTable[src], sizeof(DESCRIPTOR));
+			dst++;
+		}
+	}
+	diva_os_leave_spin_lock(&didd_spin, &irql, "didd_read");
+	if (dst < length) {
+		memcpy(&buffer[dst], &MAdapter, sizeof(DESCRIPTOR));
+		dst++;
+	} else {
+		DBG_ERR(("Can't write DIMAINT. Array too small"))
+			}
+	if (dst < length) {
+		memcpy(&buffer[dst], &DAdapter, sizeof(DESCRIPTOR));
+		dst++;
+	} else {
+		DBG_ERR(("Can't write DADAPTER. Array too small"))
+			}
+	DBG_TRC(("Read %d adapters", dst))
+		return (dst == length);
 }
 /* --------------------------------------------------------------------------
-  DAdapter request function.
-  This function does process only synchronous requests, and is used
-  for reception/registration of new interfaces
+   DAdapter request function.
+   This function does process only synchronous requests, and is used
+   for reception/registration of new interfaces
    -------------------------------------------------------------------------- */
-static void IDI_CALL_LINK_T diva_dadapter_request (\
-                      ENTITY IDI_CALL_ENTITY_T *e) {
- IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e ;
- if (e->Req) { /* We do not process it, also return error */
-  e->Rc = OUT_OF_RESOURCES;
-  DBG_ERR (("Can't process async request, Req=%02x", e->Req))
-  return;
- }
- /*
-  So, we process sync request
-  */
- switch (e->Rc) {
-  case IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY: {
-   diva_didd_adapter_notify_t* pinfo = &syncReq->didd_notify.info;
-   pinfo->handle = diva_register_adapter_callback (\
-             (didd_adapter_change_callback_t)pinfo->callback,
-             (void IDI_CALL_ENTITY_T *)pinfo->context);
-   e->Rc = 0xff;
-  } break;
-  case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY: {
-   diva_didd_adapter_notify_t* pinfo = &syncReq->didd_notify.info;
-   diva_remove_adapter_callback (pinfo->handle);
-   e->Rc = 0xff;
-  } break;
-  case IDI_SYNC_REQ_DIDD_ADD_ADAPTER: {
-   diva_didd_add_adapter_t* pinfo = &syncReq->didd_add_adapter.info;
-   if (diva_didd_add_descriptor ((DESCRIPTOR*)pinfo->descriptor) < 0) {
-    e->Rc = OUT_OF_RESOURCES;
-   } else {
-    e->Rc = 0xff;
-   }
-  } break;
-  case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER: {
-   diva_didd_remove_adapter_t* pinfo = &syncReq->didd_remove_adapter.info;
-   if (diva_didd_remove_descriptor ((IDI_CALL)pinfo->p_request) < 0) {
-    e->Rc = OUT_OF_RESOURCES;
-   } else {
-    e->Rc = 0xff;
-   }
-  } break;
-  case IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY: {
-   diva_didd_read_adapter_array_t* pinfo =\
-                &syncReq->didd_read_adapter_array.info;
-   if (diva_didd_read_adapter_array ((DESCRIPTOR*)pinfo->buffer,
-                  (int)pinfo->length)) {
-    e->Rc = OUT_OF_RESOURCES;
-   } else {
-    e->Rc = 0xff;
-   }
-  } break;
-  default:
-   DBG_ERR (("Can't process sync request, Req=%02x", e->Rc))
-   e->Rc = OUT_OF_RESOURCES;
- }
+static void IDI_CALL_LINK_T diva_dadapter_request(	\
+	ENTITY IDI_CALL_ENTITY_T *e) {
+	IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e;
+	if (e->Req) { /* We do not process it, also return error */
+		e->Rc = OUT_OF_RESOURCES;
+		DBG_ERR(("Can't process async request, Req=%02x", e->Req))
+			return;
+	}
+	/*
+	  So, we process sync request
+	*/
+	switch (e->Rc) {
+	case IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY: {
+		diva_didd_adapter_notify_t *pinfo = &syncReq->didd_notify.info;
+		pinfo->handle = diva_register_adapter_callback(		\
+			(didd_adapter_change_callback_t)pinfo->callback,
+			(void IDI_CALL_ENTITY_T *)pinfo->context);
+		e->Rc = 0xff;
+	} break;
+	case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY: {
+		diva_didd_adapter_notify_t *pinfo = &syncReq->didd_notify.info;
+		diva_remove_adapter_callback(pinfo->handle);
+		e->Rc = 0xff;
+	} break;
+	case IDI_SYNC_REQ_DIDD_ADD_ADAPTER: {
+		diva_didd_add_adapter_t *pinfo = &syncReq->didd_add_adapter.info;
+		if (diva_didd_add_descriptor((DESCRIPTOR *)pinfo->descriptor) < 0) {
+			e->Rc = OUT_OF_RESOURCES;
+		} else {
+			e->Rc = 0xff;
+		}
+	} break;
+	case IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER: {
+		diva_didd_remove_adapter_t *pinfo = &syncReq->didd_remove_adapter.info;
+		if (diva_didd_remove_descriptor((IDI_CALL)pinfo->p_request) < 0) {
+			e->Rc = OUT_OF_RESOURCES;
+		} else {
+			e->Rc = 0xff;
+		}
+	} break;
+	case IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY: {
+		diva_didd_read_adapter_array_t *pinfo =\
+			&syncReq->didd_read_adapter_array.info;
+		if (diva_didd_read_adapter_array((DESCRIPTOR *)pinfo->buffer,
+						  (int)pinfo->length)) {
+			e->Rc = OUT_OF_RESOURCES;
+		} else {
+			e->Rc = 0xff;
+		}
+	} break;
+	default:
+		DBG_ERR(("Can't process sync request, Req=%02x", e->Rc))
+			e->Rc = OUT_OF_RESOURCES;
+	}
 }
 /* --------------------------------------------------------------------------
-  IDI client does register his notification function
-  -------------------------------------------------------------------------- */
-static dword diva_register_adapter_callback (\
-                   didd_adapter_change_callback_t callback,
-                   void IDI_CALL_ENTITY_T* context) {
- diva_os_spin_lock_magic_t irql;
- dword i;
- 
- for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) {
-  diva_os_enter_spin_lock (&didd_spin, &irql, "didd_nfy_add");
-  if (!NotificationTable[i].callback) {
-   NotificationTable[i].callback = callback;
-   NotificationTable[i].context = context;
-   diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy_add");
-   DBG_TRC(("Register adapter notification[%d]=%08x", i+1, callback))
-   return (i+1);
-  }
-  diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy_add");
- }
- DBG_ERR (("Can't register adapter notification, overflow"))
- return (0);
+   IDI client does register his notification function
+   -------------------------------------------------------------------------- */
+static dword diva_register_adapter_callback(		\
+	didd_adapter_change_callback_t callback,
+	void IDI_CALL_ENTITY_T *context) {
+	diva_os_spin_lock_magic_t irql;
+	dword i;
+
+	for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) {
+		diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy_add");
+		if (!NotificationTable[i].callback) {
+			NotificationTable[i].callback = callback;
+			NotificationTable[i].context = context;
+			diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_add");
+			DBG_TRC(("Register adapter notification[%d]=%08x", i + 1, callback))
+				return (i + 1);
+		}
+		diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_add");
+	}
+	DBG_ERR(("Can't register adapter notification, overflow"))
+		return (0);
 }
 /* --------------------------------------------------------------------------
-  IDI client does register his notification function
-  -------------------------------------------------------------------------- */
-static void diva_remove_adapter_callback (dword handle) {
- diva_os_spin_lock_magic_t irql;
- if (handle && ((--handle) < DIVA_DIDD_MAX_NOTIFICATIONS)) {
-  diva_os_enter_spin_lock (&didd_spin, &irql, "didd_nfy_rm");
-  NotificationTable[handle].callback = NULL;
-  NotificationTable[handle].context  = NULL;
-  diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy_rm");
-  DBG_TRC(("Remove adapter notification[%d]", (int)(handle+1)))
-  return;
- }
- DBG_ERR(("Can't remove adapter notification, handle=%d", handle))
-}
+   IDI client does register his notification function
+   -------------------------------------------------------------------------- */
+static void diva_remove_adapter_callback(dword handle) {
+	diva_os_spin_lock_magic_t irql;
+	if (handle && ((--handle) < DIVA_DIDD_MAX_NOTIFICATIONS)) {
+		diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy_rm");
+		NotificationTable[handle].callback = NULL;
+		NotificationTable[handle].context  = NULL;
+		diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy_rm");
+		DBG_TRC(("Remove adapter notification[%d]", (int)(handle + 1)))
+			return;
+	}
+	DBG_ERR(("Can't remove adapter notification, handle=%d", handle))
+		}
 /* --------------------------------------------------------------------------
-  Notify all client about adapter array change
-  Does suppose following behavior in the client side:
-  Step 1: Redister Notification
-  Step 2: Read Adapter Array
-  -------------------------------------------------------------------------- */
-static void diva_notify_adapter_change (DESCRIPTOR* d, int removal) {
- int i, do_notify;
- didd_adapter_change_notification_t nfy;
- diva_os_spin_lock_magic_t irql;
- for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) {
-  do_notify = 0;
-  diva_os_enter_spin_lock (&didd_spin, &irql, "didd_nfy");
-  if (NotificationTable[i].callback) {
-   memcpy (&nfy, &NotificationTable[i], sizeof(nfy));
-   do_notify = 1;
-  }
-  diva_os_leave_spin_lock (&didd_spin, &irql, "didd_nfy");
-  if (do_notify) {
-   (*(nfy.callback))(nfy.context, d, removal);
-  }
- }
+   Notify all client about adapter array change
+   Does suppose following behavior in the client side:
+   Step 1: Redister Notification
+   Step 2: Read Adapter Array
+   -------------------------------------------------------------------------- */
+static void diva_notify_adapter_change(DESCRIPTOR *d, int removal) {
+	int i, do_notify;
+	didd_adapter_change_notification_t nfy;
+	diva_os_spin_lock_magic_t irql;
+	for (i = 0; i < DIVA_DIDD_MAX_NOTIFICATIONS; i++) {
+		do_notify = 0;
+		diva_os_enter_spin_lock(&didd_spin, &irql, "didd_nfy");
+		if (NotificationTable[i].callback) {
+			memcpy(&nfy, &NotificationTable[i], sizeof(nfy));
+			do_notify = 1;
+		}
+		diva_os_leave_spin_lock(&didd_spin, &irql, "didd_nfy");
+		if (do_notify) {
+			(*(nfy.callback))(nfy.context, d, removal);
+		}
+	}
 }
 /* --------------------------------------------------------------------------
-  For all systems, that are linked by Kernel Mode Linker this is ONLY one
-  function thet should be exported by this device driver
-  IDI clients should look for IDI_DADAPTER, and use request function
-  of this adapter (sync request) in order to receive appropriate services:
-  - add new adapter
-  - remove existing adapter
-  - add adapter array notification
-  - remove adapter array notification
-  (read adapter is redundant in this case)
-  INPUT:
+   For all systems, that are linked by Kernel Mode Linker this is ONLY one
+   function thet should be exported by this device driver
+   IDI clients should look for IDI_DADAPTER, and use request function
+   of this adapter (sync request) in order to receive appropriate services:
+   - add new adapter
+   - remove existing adapter
+   - add adapter array notification
+   - remove adapter array notification
+   (read adapter is redundant in this case)
+   INPUT:
    buffer - pointer to buffer that will receive adapter array
    length  - length (in bytes) of space in buffer
-  OUTPUT:
+   OUTPUT:
    Adapter array will be written to memory described by 'buffer'
    If the last adapter seen in the returned adapter array is
    IDI_DADAPTER or if last adapter in array does have type '0', then
    it was enougth space in buffer to accommodate all available
    adapter descriptors
-  *NOTE 1 (debug interface):
+   *NOTE 1 (debug interface):
    The IDI adapter of type 'IDI_DIMAINT' does register as 'request'
    famous 'dprintf' function (of type DI_PRINTF, please look
    include/debuglib.c and include/debuglib.h) for details.
    So dprintf is not exported from module debug module directly,
    instead of this IDI_DIMAINT is registered.
    Module load order will receive in this case:
-    1. DIDD (this file)
-    2. DIMAINT does load and register 'IDI_DIMAINT', at this step
-      DIDD should be able to get 'dprintf', save it, and
-      register with DIDD by means of 'dprintf' function.
-    3. any other driver is loaded and is able to access adapter array
-      and debug interface
+   1. DIDD (this file)
+   2. DIMAINT does load and register 'IDI_DIMAINT', at this step
+   DIDD should be able to get 'dprintf', save it, and
+   register with DIDD by means of 'dprintf' function.
+   3. any other driver is loaded and is able to access adapter array
+   and debug interface
    This approach does allow to load/unload debug interface on demand,
    and save memory, it it is necessary.
-  -------------------------------------------------------------------------- */
-void IDI_CALL_LINK_T DIVA_DIDD_Read (void IDI_CALL_ENTITY_T * buffer,
-                   int length) {
- diva_didd_read_adapter_array (buffer, length);
+   -------------------------------------------------------------------------- */
+void IDI_CALL_LINK_T DIVA_DIDD_Read(void IDI_CALL_ENTITY_T *buffer,
+				    int length) {
+	diva_didd_read_adapter_array(buffer, length);
 }
-
diff --git a/drivers/isdn/hardware/eicon/dadapter.h b/drivers/isdn/hardware/eicon/dadapter.h
index 3575ac9..5540f46 100644
--- a/drivers/isdn/hardware/eicon/dadapter.h
+++ b/drivers/isdn/hardware/eicon/dadapter.h
@@ -1,33 +1,33 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_DIDD_DADAPTER_INC__
 #define __DIVA_DIDD_DADAPTER_INC__
- 
-void diva_didd_load_time_init (void);
-void diva_didd_load_time_finit (void);
+
+void diva_didd_load_time_init(void);
+void diva_didd_load_time_finit(void);
 
 #define NEW_MAX_DESCRIPTORS     64
 
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 7a9894c..b5226af 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -9,67 +9,67 @@
 
 /*
   LOCALS
-  */
+*/
 #define DBG_MAGIC (0x47114711L)
 
-static void DI_register (void *arg);
-static void DI_deregister (pDbgHandle hDbg);
-static void DI_format (int do_lock, word id, int type, char *format, va_list argument_list);
-static void DI_format_locked   (word id, int type, char *format, va_list argument_list);
-static void DI_format_old (word id, char *format, va_list ap) { }
-static void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap) { }
-static void single_p (byte * P, word * PLength, byte Id);
-static void diva_maint_xdi_cb (ENTITY* e);
-static word SuperTraceCreateReadReq (byte* P, const char* path);
-static int diva_mnt_cmp_nmbr (const char* nmbr);
-static void diva_free_dma_descriptor (IDI_CALL request, int nr);
-static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic);
-void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...);
-
-static dword MaxDumpSize = 256 ;
-static dword MaxXlogSize = 2 + 128 ;
-static char  TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH+1];
+static void DI_register(void *arg);
+static void DI_deregister(pDbgHandle hDbg);
+static void DI_format(int do_lock, word id, int type, char *format, va_list argument_list);
+static void DI_format_locked(word id, int type, char *format, va_list argument_list);
+static void DI_format_old(word id, char *format, va_list ap) { }
+static void DiProcessEventLog(unsigned short id, unsigned long msgID, va_list ap) { }
+static void single_p(byte *P, word *PLength, byte Id);
+static void diva_maint_xdi_cb(ENTITY *e);
+static word SuperTraceCreateReadReq(byte *P, const char *path);
+static int diva_mnt_cmp_nmbr(const char *nmbr);
+static void diva_free_dma_descriptor(IDI_CALL request, int nr);
+static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic);
+void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
+
+static dword MaxDumpSize = 256;
+static dword MaxXlogSize = 2 + 128;
+static char  TraceFilter[DIVA_MAX_SELECTIVE_FILTER_LENGTH + 1];
 static int TraceFilterIdent   = -1;
 static int TraceFilterChannel = -1;
 
 typedef struct _diva_maint_client {
-  dword       sec;
-  dword       usec;
-  pDbgHandle  hDbg;
-  char        drvName[128];
-  dword       dbgMask;
-  dword       last_dbgMask;
-  IDI_CALL    request;
-  _DbgHandle_ Dbg;
-  int         logical;
-  int         channels;
-  diva_strace_library_interface_t* pIdiLib;
-  BUFFERS     XData;
-  char        xbuffer[2048+512];
-  byte*       pmem;
-  int         request_pending;
-  int         dma_handle;
+	dword       sec;
+	dword       usec;
+	pDbgHandle  hDbg;
+	char        drvName[128];
+	dword       dbgMask;
+	dword       last_dbgMask;
+	IDI_CALL    request;
+	_DbgHandle_ Dbg;
+	int         logical;
+	int         channels;
+	diva_strace_library_interface_t *pIdiLib;
+	BUFFERS     XData;
+	char        xbuffer[2048 + 512];
+	byte        *pmem;
+	int         request_pending;
+	int         dma_handle;
 } diva_maint_client_t;
 static diva_maint_client_t clients[MAX_DESCRIPTORS];
 
-static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask);
+static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask);
 
-static void diva_maint_error (void* user_context,
-                              diva_strace_library_interface_t* hLib,
-                              int Adapter,
-                              int error,
-                              const char* file,
-                              int line);
-static void diva_maint_state_change_notify (void* user_context,
-                                            diva_strace_library_interface_t* hLib,
-                                            int Adapter,
-                                            diva_trace_line_state_t* channel,
-                                            int notify_subject);
-static void diva_maint_trace_notify (void* user_context,
-                                     diva_strace_library_interface_t* hLib,
-                                     int Adapter,
-                                     void* xlog_buffer,
-                                     int length);
+static void diva_maint_error(void *user_context,
+			     diva_strace_library_interface_t *hLib,
+			     int Adapter,
+			     int error,
+			     const char *file,
+			     int line);
+static void diva_maint_state_change_notify(void *user_context,
+					   diva_strace_library_interface_t *hLib,
+					   int Adapter,
+					   diva_trace_line_state_t *channel,
+					   int notify_subject);
+static void diva_maint_trace_notify(void *user_context,
+				    diva_strace_library_interface_t *hLib,
+				    int Adapter,
+				    void *xlog_buffer,
+				    int length);
 
 
 
@@ -79,36 +79,36 @@ typedef struct MSG_QUEUE {
 	byte	*High;		/* Base + Size (constant)		*/
 	byte	*Head;		/* first message in queue (if any)	*/
 	byte	*Tail;		/* first free position			*/
-	byte	*Wrap;		/* current wraparound position 		*/
+	byte	*Wrap;		/* current wraparound position		*/
 	dword	Count;		/* current no of bytes in queue		*/
 } MSG_QUEUE;
 
 typedef struct MSG_HEAD {
 	volatile dword	Size;		/* size of data following MSG_HEAD	*/
-#define	MSG_INCOMPLETE	0x8000	/* ored to Size until queueCompleteMsg 	*/
+#define	MSG_INCOMPLETE	0x8000	/* ored to Size until queueCompleteMsg	*/
 } MSG_HEAD;
 
-#define queueCompleteMsg(p) do{ ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; }while(0)
+#define queueCompleteMsg(p) do { ((MSG_HEAD *)p - 1)->Size &= ~MSG_INCOMPLETE; } while (0)
 #define queueCount(q)	((q)->Count)
-#define MSG_NEED(size) \
-	( (sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1) )
+#define MSG_NEED(size)							\
+	((sizeof(MSG_HEAD) + size + sizeof(dword) - 1) & ~(sizeof(dword) - 1))
 
-static void queueInit (MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {
+static void queueInit(MSG_QUEUE *Q, byte *Buffer, dword sizeBuffer) {
 	Q->Size = sizeBuffer;
 	Q->Base = Q->Head = Q->Tail = Buffer;
 	Q->High = Buffer + sizeBuffer;
 	Q->Wrap = NULL;
-	Q->Count= 0;
+	Q->Count = 0;
 }
 
-static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {
+static byte *queueAllocMsg(MSG_QUEUE *Q, word size) {
 	/* Allocate 'size' bytes at tail of queue which will be filled later
-   * directly with callers own message header info and/or message.
-   * An 'alloced' message is marked incomplete by oring the 'Size' field
-   * with MSG_INCOMPLETE.
-   * This must be reset via queueCompleteMsg() after the message is filled.
-   * As long as a message is marked incomplete queuePeekMsg() will return
-   * a 'queue empty' condition when it reaches such a message.  */
+	 * directly with callers own message header info and/or message.
+	 * An 'alloced' message is marked incomplete by oring the 'Size' field
+	 * with MSG_INCOMPLETE.
+	 * This must be reset via queueCompleteMsg() after the message is filled.
+	 * As long as a message is marked incomplete queuePeekMsg() will return
+	 * a 'queue empty' condition when it reaches such a message.  */
 
 	MSG_HEAD *Msg;
 	word need = MSG_NEED(size);
@@ -119,7 +119,7 @@ static byte *queueAllocMsg (MSG_QUEUE *Q, word size) {
 		}
 		goto alloc; /* empty */
 	}
-	
+
 	if (Q->Tail > Q->Head) {
 		if (Q->Tail + need <= Q->High) goto alloc; /* append */
 		if (Q->Base + need > Q->Head) {
@@ -145,10 +145,10 @@ alloc:
 
 
 
-	return ((byte*)(Msg + 1));
+	return ((byte *)(Msg + 1));
 }
 
-static void queueFreeMsg (MSG_QUEUE *Q) {
+static void queueFreeMsg(MSG_QUEUE *Q) {
 /* Free the message at head of queue */
 
 	word size = ((MSG_HEAD *)Q->Head)->Size & ~MSG_INCOMPLETE;
@@ -166,10 +166,10 @@ static void queueFreeMsg (MSG_QUEUE *Q) {
 	}
 }
 
-static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {
+static byte *queuePeekMsg(MSG_QUEUE *Q, word *size) {
 	/* Show the first valid message in queue BUT DON'T free the message.
-   * After looking on the message contents it can be freed queueFreeMsg()
-   * or simply remain in message queue.  */
+	 * After looking on the message contents it can be freed queueFreeMsg()
+	 * or simply remain in message queue.  */
 
 	MSG_HEAD *Msg = (MSG_HEAD *)Q->Head;
 
@@ -184,9 +184,9 @@ static byte *queuePeekMsg (MSG_QUEUE *Q, word *size) {
 
 /*
   Message queue header
-  */
-static MSG_QUEUE*          dbg_queue;
-static byte*               dbg_base;
+*/
+static MSG_QUEUE *dbg_queue;
+static byte *dbg_base;
 static int                 external_dbg_queue;
 static diva_os_spin_lock_t dbg_q_lock;
 static diva_os_spin_lock_t dbg_adapter_lock;
@@ -196,1147 +196,1147 @@ static dword               start_sec;
 static dword               start_usec;
 
 /*
-	INTERFACE:
-    Initialize run time queue structures.
-    base:    base of the message queue
-    length:  length of the message queue
-    do_init: perfor queue reset
-
-    return:  zero on success, -1 on error
-  */
-int diva_maint_init (byte* base, unsigned long length, int do_init) {
-  if (dbg_queue || (!base) || (length < (4096*4))) {
-    return (-1);
-  }
+  INTERFACE:
+  Initialize run time queue structures.
+  base:    base of the message queue
+  length:  length of the message queue
+  do_init: perfor queue reset
+
+  return:  zero on success, -1 on error
+*/
+int diva_maint_init(byte *base, unsigned long length, int do_init) {
+	if (dbg_queue || (!base) || (length < (4096 * 4))) {
+		return (-1);
+	}
 
-  TraceFilter[0]     =  0;
-  TraceFilterIdent   = -1;
-  TraceFilterChannel = -1;
+	TraceFilter[0]     =  0;
+	TraceFilterIdent   = -1;
+	TraceFilterChannel = -1;
 
-  dbg_base = base;
+	dbg_base = base;
 
-  diva_os_get_time (&start_sec, &start_usec);
+	diva_os_get_time(&start_sec, &start_usec);
 
-  *(dword*)base  = (dword)DBG_MAGIC; /* Store Magic */
-  base   += sizeof(dword);
-  length -= sizeof(dword);
+	*(dword *)base  = (dword)DBG_MAGIC; /* Store Magic */
+	base   += sizeof(dword);
+	length -= sizeof(dword);
 
-  *(dword*)base = 2048; /* Extension Field Length */
-  base   += sizeof(dword);
-  length -= sizeof(dword);
+	*(dword *)base = 2048; /* Extension Field Length */
+	base   += sizeof(dword);
+	length -= sizeof(dword);
 
-  strcpy (base, "KERNEL MODE BUFFER\n");
-  base   += 2048;
-  length -= 2048;
+	strcpy(base, "KERNEL MODE BUFFER\n");
+	base   += 2048;
+	length -= 2048;
 
-  *(dword*)base = 0; /* Terminate extension */
-  base   += sizeof(dword);
-  length -= sizeof(dword);
+	*(dword *)base = 0; /* Terminate extension */
+	base   += sizeof(dword);
+	length -= sizeof(dword);
 
-  *(void**)base  =  (void*)(base+sizeof(void*)); /* Store Base  */
-  base   += sizeof(void*);
-  length -= sizeof(void*);
+	*(void **)base  =  (void *)(base + sizeof(void *)); /* Store Base  */
+	base   += sizeof(void *);
+	length -= sizeof(void *);
 
-  dbg_queue = (MSG_QUEUE*)base;
-  queueInit (dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512);
-  external_dbg_queue = 0;
+	dbg_queue = (MSG_QUEUE *)base;
+	queueInit(dbg_queue, base + sizeof(MSG_QUEUE), length - sizeof(MSG_QUEUE) - 512);
+	external_dbg_queue = 0;
 
-  if (!do_init) {
-    external_dbg_queue = 1; /* memory was located on the external device */
-  }
+	if (!do_init) {
+		external_dbg_queue = 1; /* memory was located on the external device */
+	}
 
 
-	if (diva_os_initialize_spin_lock (&dbg_q_lock, "dbg_init")) {
-    dbg_queue = NULL;
-    dbg_base = NULL;
-    external_dbg_queue = 0;
+	if (diva_os_initialize_spin_lock(&dbg_q_lock, "dbg_init")) {
+		dbg_queue = NULL;
+		dbg_base = NULL;
+		external_dbg_queue = 0;
 		return (-1);
-  }
+	}
 
-	if (diva_os_initialize_spin_lock (&dbg_adapter_lock, "dbg_init")) {
-    diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init");
-    dbg_queue = NULL;
-    dbg_base = NULL;
-    external_dbg_queue = 0;
+	if (diva_os_initialize_spin_lock(&dbg_adapter_lock, "dbg_init")) {
+		diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_init");
+		dbg_queue = NULL;
+		dbg_base = NULL;
+		external_dbg_queue = 0;
 		return (-1);
-  }
+	}
 
-  return (0);
+	return (0);
 }
 
 /*
   INTERFACE:
-    Finit at unload time
-    return address of internal queue or zero if queue
-    was external
-  */
-void* diva_maint_finit (void) {
-  void* ret = (void*)dbg_base;
-  int i;
-
-  dbg_queue = NULL;
-  dbg_base  = NULL;
-
-  if (ret) {
-    diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit");
-    diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit");
-  }
-
-  if (external_dbg_queue) {
-    ret = NULL;
-  }
-  external_dbg_queue = 0;
-
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    if (clients[i].pmem) {
-      diva_os_free (0, clients[i].pmem);
-    }
-  }
-
-  return (ret);
+  Finit at unload time
+  return address of internal queue or zero if queue
+  was external
+*/
+void *diva_maint_finit(void) {
+	void *ret = (void *)dbg_base;
+	int i;
+
+	dbg_queue = NULL;
+	dbg_base  = NULL;
+
+	if (ret) {
+		diva_os_destroy_spin_lock(&dbg_q_lock, "dbg_finit");
+		diva_os_destroy_spin_lock(&dbg_adapter_lock, "dbg_finit");
+	}
+
+	if (external_dbg_queue) {
+		ret = NULL;
+	}
+	external_dbg_queue = 0;
+
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		if (clients[i].pmem) {
+			diva_os_free(0, clients[i].pmem);
+		}
+	}
+
+	return (ret);
 }
 
 /*
   INTERFACE:
-    Return amount of messages in debug queue
-  */
-dword diva_dbg_q_length (void) {
+  Return amount of messages in debug queue
+*/
+dword diva_dbg_q_length(void) {
 	return (dbg_queue ? queueCount(dbg_queue)	: 0);
 }
 
 /*
   INTERFACE:
-    Lock message queue and return the pointer to the first
-    entry.
-  */
-diva_dbg_entry_head_t* diva_maint_get_message (word* size,
-                                               diva_os_spin_lock_magic_t* old_irql) {
-  diva_dbg_entry_head_t*     pmsg = NULL;
-
-  diva_os_enter_spin_lock (&dbg_q_lock, old_irql, "read");
-  if (dbg_q_busy) {
-    diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_busy");
-    return NULL;
-  }
-  dbg_q_busy = 1;
-
-  if (!(pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, size))) {
-    dbg_q_busy = 0;
-    diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_empty");
-  }
-
-  return (pmsg);
+  Lock message queue and return the pointer to the first
+  entry.
+*/
+diva_dbg_entry_head_t *diva_maint_get_message(word *size,
+					      diva_os_spin_lock_magic_t *old_irql) {
+	diva_dbg_entry_head_t *pmsg = NULL;
+
+	diva_os_enter_spin_lock(&dbg_q_lock, old_irql, "read");
+	if (dbg_q_busy) {
+		diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_busy");
+		return NULL;
+	}
+	dbg_q_busy = 1;
+
+	if (!(pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, size))) {
+		dbg_q_busy = 0;
+		diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_empty");
+	}
+
+	return (pmsg);
 }
 
 /*
   INTERFACE:
-    acknowledge last message and unlock queue
-  */
-void diva_maint_ack_message (int do_release,
-                             diva_os_spin_lock_magic_t* old_irql) {
+  acknowledge last message and unlock queue
+*/
+void diva_maint_ack_message(int do_release,
+			    diva_os_spin_lock_magic_t *old_irql) {
 	if (!dbg_q_busy) {
 		return;
 	}
 	if (do_release) {
-		queueFreeMsg (dbg_queue);
+		queueFreeMsg(dbg_queue);
 	}
 	dbg_q_busy = 0;
-  diva_os_leave_spin_lock (&dbg_q_lock, old_irql, "read_ack");
+	diva_os_leave_spin_lock(&dbg_q_lock, old_irql, "read_ack");
 }
 
 
 /*
   INTERFACE:
-    PRT COMP function used to register
-    with MAINT adapter or log in compatibility
-    mode in case older driver version is connected too
-  */
-void diva_maint_prtComp (char *format, ...) {
-  void    *hDbg;
-  va_list ap;
-
-  if (!format)
-    return;
-
-  va_start(ap, format);
-
-  /*
-    register to new log driver functions
-   */
-  if ((format[0] == 0) && ((unsigned char)format[1] == 255)) {
-    hDbg = va_arg(ap, void *); /* ptr to DbgHandle */
-    DI_register (hDbg);
-  }
-
-  va_end (ap);
+  PRT COMP function used to register
+  with MAINT adapter or log in compatibility
+  mode in case older driver version is connected too
+*/
+void diva_maint_prtComp(char *format, ...) {
+	void    *hDbg;
+	va_list ap;
+
+	if (!format)
+		return;
+
+	va_start(ap, format);
+
+	/*
+	  register to new log driver functions
+	*/
+	if ((format[0] == 0) && ((unsigned char)format[1] == 255)) {
+		hDbg = va_arg(ap, void *); /* ptr to DbgHandle */
+		DI_register(hDbg);
+	}
+
+	va_end(ap);
 }
 
-static void DI_register (void *arg) {
-  diva_os_spin_lock_magic_t old_irql;
-  dword sec, usec;
-  pDbgHandle  	hDbg ;
-  int id, free_id = -1, best_id = 0;
-  
-  diva_os_get_time (&sec, &usec);
-
-	hDbg = (pDbgHandle)arg ;
-  /*
-    Check for bad args, specially for the old obsolete debug handle
-    */
-  if ((hDbg == NULL) ||
-      ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) ||
-      (hDbg->Registered != 0)) {
-		return ;
-  }
-
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");
-
-  for (id = 1; id < ARRAY_SIZE(clients); id++) {
-    if (clients[id].hDbg == hDbg) {
-      /*
-        driver already registered
-        */
-      diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
-      return;
-    }
-    if (clients[id].hDbg) { /* slot is busy */
-      continue;
-    }
-    free_id = id;
-    if (!strcmp (clients[id].drvName, hDbg->drvName)) {
-      /*
-        This driver was already registered with this name
-        and slot is still free - reuse it
-        */
-      best_id = 1;
-      break;
-    }
-    if (!clients[id].hDbg) { /* slot is busy */
-      break;
-    }
-  }
-
-  if (free_id != -1) {
-    diva_dbg_entry_head_t* pmsg = NULL;
-    int len;
-    char tmp[256];
-    word size;
-
-    /*
-      Register new driver with id == free_id
-      */
-    clients[free_id].hDbg = hDbg;
-    clients[free_id].sec  = sec;
-    clients[free_id].usec = usec;
-    strcpy (clients[free_id].drvName, hDbg->drvName);
-
-    clients[free_id].dbgMask = hDbg->dbgMask;
-    if (best_id) {
-      hDbg->dbgMask |= clients[free_id].last_dbgMask;
-    } else {
-      clients[free_id].last_dbgMask = 0;
-    }
-
-    hDbg->Registered = DBG_HANDLE_REG_NEW ;
-    hDbg->id         = (byte)free_id;
-    hDbg->dbg_end    = DI_deregister;
-    hDbg->dbg_prt    = DI_format_locked;
-    hDbg->dbg_ev     = DiProcessEventLog;
-    hDbg->dbg_irq    = DI_format_locked;
-    if (hDbg->Version > 0) {
-      hDbg->dbg_old  = DI_format_old;
-    }
-    hDbg->next       = (pDbgHandle)DBG_MAGIC;
-
-    /*
-      Log driver register, MAINT driver ID is '0'
-      */
-    len = sprintf (tmp, "DIMAINT - drv # %d = '%s' registered",
-                   free_id, hDbg->drvName);
-
-    while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                        (word)(len+1+sizeof(*pmsg))))) {
-      if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-        queueFreeMsg (dbg_queue);
-      } else {
-        break;
-      }
-    }
-
-    if (pmsg) {
-      pmsg->sequence    = dbg_sequence++;
-      pmsg->time_sec    = sec;
-      pmsg->time_usec   = usec;
-      pmsg->facility    = MSG_TYPE_STRING;
-      pmsg->dli         = DLI_REG;
-      pmsg->drv_id      = 0; /* id 0 - DIMAINT */
-      pmsg->di_cpu      = 0;
-      pmsg->data_length = len+1;
-
-      memcpy (&pmsg[1], tmp, len+1);
-		  queueCompleteMsg (pmsg);
-      diva_maint_wakeup_read();
-    }
-  }
-
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
+static void DI_register(void *arg) {
+	diva_os_spin_lock_magic_t old_irql;
+	dword sec, usec;
+	pDbgHandle	hDbg;
+	int id, free_id = -1, best_id = 0;
+
+	diva_os_get_time(&sec, &usec);
+
+	hDbg = (pDbgHandle)arg;
+	/*
+	  Check for bad args, specially for the old obsolete debug handle
+	*/
+	if ((hDbg == NULL) ||
+	    ((hDbg->id == 0) && (((_OldDbgHandle_ *)hDbg)->id == -1)) ||
+	    (hDbg->Registered != 0)) {
+		return;
+	}
+
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register");
+
+	for (id = 1; id < ARRAY_SIZE(clients); id++) {
+		if (clients[id].hDbg == hDbg) {
+			/*
+			  driver already registered
+			*/
+			diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
+			return;
+		}
+		if (clients[id].hDbg) { /* slot is busy */
+			continue;
+		}
+		free_id = id;
+		if (!strcmp(clients[id].drvName, hDbg->drvName)) {
+			/*
+			  This driver was already registered with this name
+			  and slot is still free - reuse it
+			*/
+			best_id = 1;
+			break;
+		}
+		if (!clients[id].hDbg) { /* slot is busy */
+			break;
+		}
+	}
+
+	if (free_id != -1) {
+		diva_dbg_entry_head_t *pmsg = NULL;
+		int len;
+		char tmp[256];
+		word size;
+
+		/*
+		  Register new driver with id == free_id
+		*/
+		clients[free_id].hDbg = hDbg;
+		clients[free_id].sec  = sec;
+		clients[free_id].usec = usec;
+		strcpy(clients[free_id].drvName, hDbg->drvName);
+
+		clients[free_id].dbgMask = hDbg->dbgMask;
+		if (best_id) {
+			hDbg->dbgMask |= clients[free_id].last_dbgMask;
+		} else {
+			clients[free_id].last_dbgMask = 0;
+		}
+
+		hDbg->Registered = DBG_HANDLE_REG_NEW;
+		hDbg->id         = (byte)free_id;
+		hDbg->dbg_end    = DI_deregister;
+		hDbg->dbg_prt    = DI_format_locked;
+		hDbg->dbg_ev     = DiProcessEventLog;
+		hDbg->dbg_irq    = DI_format_locked;
+		if (hDbg->Version > 0) {
+			hDbg->dbg_old  = DI_format_old;
+		}
+		hDbg->next       = (pDbgHandle)DBG_MAGIC;
+
+		/*
+		  Log driver register, MAINT driver ID is '0'
+		*/
+		len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered",
+			      free_id, hDbg->drvName);
+
+		while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+								       (word)(len + 1 + sizeof(*pmsg))))) {
+			if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+				queueFreeMsg(dbg_queue);
+			} else {
+				break;
+			}
+		}
+
+		if (pmsg) {
+			pmsg->sequence    = dbg_sequence++;
+			pmsg->time_sec    = sec;
+			pmsg->time_usec   = usec;
+			pmsg->facility    = MSG_TYPE_STRING;
+			pmsg->dli         = DLI_REG;
+			pmsg->drv_id      = 0; /* id 0 - DIMAINT */
+			pmsg->di_cpu      = 0;
+			pmsg->data_length = len + 1;
+
+			memcpy(&pmsg[1], tmp, len + 1);
+			queueCompleteMsg(pmsg);
+			diva_maint_wakeup_read();
+		}
+	}
+
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
 }
 
-static void DI_deregister (pDbgHandle hDbg) {
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
-  dword sec, usec;
-  int i;
-  word size;
-  byte* pmem = NULL;
-
-  diva_os_get_time (&sec, &usec);
-
-  diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read");
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read");
-
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    if (clients[i].hDbg == hDbg) {
-      diva_dbg_entry_head_t* pmsg;
-      char tmp[256];
-      int len;
-
-      clients[i].hDbg = NULL;
-
-      hDbg->id       = -1;
-      hDbg->dbgMask  = 0;
-      hDbg->dbg_end  = NULL;
-      hDbg->dbg_prt  = NULL;
-      hDbg->dbg_irq  = NULL;
-      if (hDbg->Version > 0)
-        hDbg->dbg_old = NULL;
-      hDbg->Registered = 0;
-      hDbg->next     = NULL;
-
-      if (clients[i].pIdiLib) {
-        (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
-        clients[i].pIdiLib = NULL;
-
-        pmem = clients[i].pmem;
-        clients[i].pmem = NULL;
-      }
-
-      /*
-        Log driver register, MAINT driver ID is '0'
-        */
-      len = sprintf (tmp, "DIMAINT - drv # %d = '%s' de-registered",
-                     i, hDbg->drvName);
-
-      while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                        (word)(len+1+sizeof(*pmsg))))) {
-        if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-          queueFreeMsg (dbg_queue);
-        } else {
-          break;
-        }
-      }
-
-      if (pmsg) {
-        pmsg->sequence    = dbg_sequence++;
-        pmsg->time_sec    = sec;
-        pmsg->time_usec   = usec;
-        pmsg->facility    = MSG_TYPE_STRING;
-        pmsg->dli         = DLI_REG;
-        pmsg->drv_id      = 0; /* id 0 - DIMAINT */
-        pmsg->di_cpu      = 0;
-        pmsg->data_length = len+1;
-
-        memcpy (&pmsg[1], tmp, len+1);
-  		  queueCompleteMsg (pmsg);
-        diva_maint_wakeup_read();
-      }
-
-      break;
-    }
-  }
-
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_ack");
-  diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "read_ack");
-
-  if (pmem) {
-    diva_os_free (0, pmem);
-  }
+static void DI_deregister(pDbgHandle hDbg) {
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
+	dword sec, usec;
+	int i;
+	word size;
+	byte *pmem = NULL;
+
+	diva_os_get_time(&sec, &usec);
+
+	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read");
+
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		if (clients[i].hDbg == hDbg) {
+			diva_dbg_entry_head_t *pmsg;
+			char tmp[256];
+			int len;
+
+			clients[i].hDbg = NULL;
+
+			hDbg->id       = -1;
+			hDbg->dbgMask  = 0;
+			hDbg->dbg_end  = NULL;
+			hDbg->dbg_prt  = NULL;
+			hDbg->dbg_irq  = NULL;
+			if (hDbg->Version > 0)
+				hDbg->dbg_old = NULL;
+			hDbg->Registered = 0;
+			hDbg->next     = NULL;
+
+			if (clients[i].pIdiLib) {
+				(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
+				clients[i].pIdiLib = NULL;
+
+				pmem = clients[i].pmem;
+				clients[i].pmem = NULL;
+			}
+
+			/*
+			  Log driver register, MAINT driver ID is '0'
+			*/
+			len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered",
+				      i, hDbg->drvName);
+
+			while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+									      (word)(len + 1 + sizeof(*pmsg))))) {
+				if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+					queueFreeMsg(dbg_queue);
+				} else {
+					break;
+				}
+			}
+
+			if (pmsg) {
+				pmsg->sequence    = dbg_sequence++;
+				pmsg->time_sec    = sec;
+				pmsg->time_usec   = usec;
+				pmsg->facility    = MSG_TYPE_STRING;
+				pmsg->dli         = DLI_REG;
+				pmsg->drv_id      = 0; /* id 0 - DIMAINT */
+				pmsg->di_cpu      = 0;
+				pmsg->data_length = len + 1;
+
+				memcpy(&pmsg[1], tmp, len + 1);
+				queueCompleteMsg(pmsg);
+				diva_maint_wakeup_read();
+			}
+
+			break;
+		}
+	}
+
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack");
+	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack");
+
+	if (pmem) {
+		diva_os_free(0, pmem);
+	}
 }
 
-static void DI_format_locked (unsigned short id,
-                       int type,
-                       char *format,
-                       va_list argument_list) {
-  DI_format (1, id, type, format, argument_list);
+static void DI_format_locked(unsigned short id,
+			     int type,
+			     char *format,
+			     va_list argument_list) {
+	DI_format(1, id, type, format, argument_list);
 }
 
-static void DI_format (int do_lock,
-                       unsigned short id,
-                       int type,
-                       char *format,
-                       va_list ap) {
-  diva_os_spin_lock_magic_t old_irql;
-  dword sec, usec;
-  diva_dbg_entry_head_t* pmsg = NULL;
-  dword length;
-  word size;
-  static char fmtBuf[MSG_FRAME_MAX_SIZE+sizeof(*pmsg)+1];
-  char          *data;
-  unsigned short code;
-
-  if (diva_os_in_irq()) {
-    dbg_sequence++;
-    return;
-  }
+static void DI_format(int do_lock,
+		      unsigned short id,
+		      int type,
+		      char *format,
+		      va_list ap) {
+	diva_os_spin_lock_magic_t old_irql;
+	dword sec, usec;
+	diva_dbg_entry_head_t *pmsg = NULL;
+	dword length;
+	word size;
+	static char fmtBuf[MSG_FRAME_MAX_SIZE + sizeof(*pmsg) + 1];
+	char          *data;
+	unsigned short code;
+
+	if (diva_os_in_irq()) {
+		dbg_sequence++;
+		return;
+	}
 
 	if ((!format) ||
-			((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) {
+	    ((TraceFilter[0] != 0) && ((TraceFilterIdent < 0) || (TraceFilterChannel < 0)))) {
 		return;
 	}
 
 
-  
-  diva_os_get_time (&sec, &usec);
-
-  if (do_lock) {
-    diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "format");
-  }
-
-  switch (type) {
-  case DLI_MXLOG :
-  case DLI_BLK :
-  case DLI_SEND:
-  case DLI_RECV:
-    if (!(length = va_arg(ap, unsigned long))) {
-      break;
-    }
-    if (length > MaxDumpSize) {
-      length = MaxDumpSize;
-    }
-    while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                (word)length+sizeof(*pmsg)))) {
-      if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-        queueFreeMsg (dbg_queue);
-      } else {
-        break;
-      }
-    }
-    if (pmsg) {
-      memcpy (&pmsg[1], format, length);
-      pmsg->sequence    = dbg_sequence++;
-      pmsg->time_sec    = sec;
-      pmsg->time_usec   = usec;
-      pmsg->facility    = MSG_TYPE_BINARY ;
-      pmsg->dli         = type; /* DLI_XXX */
-      pmsg->drv_id      = id;   /* driver MAINT id */
-      pmsg->di_cpu      = 0;
-      pmsg->data_length = length;
-      queueCompleteMsg (pmsg);
-    }
+
+	diva_os_get_time(&sec, &usec);
+
+	if (do_lock) {
+		diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "format");
+	}
+
+	switch (type) {
+	case DLI_MXLOG:
+	case DLI_BLK:
+	case DLI_SEND:
+	case DLI_RECV:
+		if (!(length = va_arg(ap, unsigned long))) {
+			break;
+		}
+		if (length > MaxDumpSize) {
+			length = MaxDumpSize;
+		}
+		while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+								       (word)length + sizeof(*pmsg)))) {
+			if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+				queueFreeMsg(dbg_queue);
+			} else {
+				break;
+			}
+		}
+		if (pmsg) {
+			memcpy(&pmsg[1], format, length);
+			pmsg->sequence    = dbg_sequence++;
+			pmsg->time_sec    = sec;
+			pmsg->time_usec   = usec;
+			pmsg->facility    = MSG_TYPE_BINARY;
+			pmsg->dli         = type; /* DLI_XXX */
+			pmsg->drv_id      = id;   /* driver MAINT id */
+			pmsg->di_cpu      = 0;
+			pmsg->data_length = length;
+			queueCompleteMsg(pmsg);
+		}
 		break;
 
-  case DLI_XLOG: {
-    byte* p;
-    data    = va_arg(ap, char*);
-    code    = (unsigned short)va_arg(ap, unsigned int);
-    length	= (unsigned long) va_arg(ap, unsigned int);
-
-    if (length > MaxXlogSize)
-      length = MaxXlogSize;
-
-    while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                  (word)length+sizeof(*pmsg)+2))) {
-      if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-        queueFreeMsg (dbg_queue);
-      } else {
-        break;
-      }
-    }
-    if (pmsg) {
-      p = (byte*)&pmsg[1];
-      p[0] = (char)(code) ;
-      p[1] = (char)(code >> 8) ;
-      if (data && length) {
-        memcpy (&p[2], &data[0], length) ;
-      }
-      length += 2 ;
-
-      pmsg->sequence    = dbg_sequence++;
-      pmsg->time_sec    = sec;
-      pmsg->time_usec   = usec;
-      pmsg->facility    = MSG_TYPE_BINARY ;
-      pmsg->dli         = type; /* DLI_XXX */
-      pmsg->drv_id      = id;   /* driver MAINT id */
-      pmsg->di_cpu      = 0;
-      pmsg->data_length = length;
-      queueCompleteMsg (pmsg);
-    }
-  } break;
-
-  case DLI_LOG :
-  case DLI_FTL :
-  case DLI_ERR :
-  case DLI_TRC :
-  case DLI_REG :
-  case DLI_MEM :
-  case DLI_SPL :
-  case DLI_IRP :
-  case DLI_TIM :
-  case DLI_TAPI:
-  case DLI_NDIS:
-  case DLI_CONN:
-  case DLI_STAT:
-  case DLI_PRV0:
-  case DLI_PRV1:
-  case DLI_PRV2:
-  case DLI_PRV3:
-    if ((length = (unsigned long)vsprintf (&fmtBuf[0], format, ap)) > 0) {
-      length += (sizeof(*pmsg)+1);
-
-      while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                                          (word)length))) {
-        if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-          queueFreeMsg (dbg_queue);
-        } else {
-          break;
-        }
-      }
-
-      pmsg->sequence    = dbg_sequence++;
-      pmsg->time_sec    = sec;
-      pmsg->time_usec   = usec;
-      pmsg->facility    = MSG_TYPE_STRING;
-      pmsg->dli         = type; /* DLI_XXX */
-      pmsg->drv_id      = id;   /* driver MAINT id */
-      pmsg->di_cpu      = 0;
-      pmsg->data_length = length - sizeof(*pmsg);
-
-      memcpy (&pmsg[1], fmtBuf, pmsg->data_length);
-		  queueCompleteMsg (pmsg);
-    }
-    break;
-
-  } /* switch type */
-
-
-  if (queueCount(dbg_queue)) {
-    diva_maint_wakeup_read();
-  }
-
-  if (do_lock) {
-    diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "format");
-  }
+	case DLI_XLOG: {
+		byte *p;
+		data    = va_arg(ap, char *);
+		code    = (unsigned short)va_arg(ap, unsigned int);
+		length	= (unsigned long)va_arg(ap, unsigned int);
+
+		if (length > MaxXlogSize)
+			length = MaxXlogSize;
+
+		while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+								      (word)length + sizeof(*pmsg) + 2))) {
+			if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+				queueFreeMsg(dbg_queue);
+			} else {
+				break;
+			}
+		}
+		if (pmsg) {
+			p = (byte *)&pmsg[1];
+			p[0] = (char)(code);
+			p[1] = (char)(code >> 8);
+			if (data && length) {
+				memcpy(&p[2], &data[0], length);
+			}
+			length += 2;
+
+			pmsg->sequence    = dbg_sequence++;
+			pmsg->time_sec    = sec;
+			pmsg->time_usec   = usec;
+			pmsg->facility    = MSG_TYPE_BINARY;
+			pmsg->dli         = type; /* DLI_XXX */
+			pmsg->drv_id      = id;   /* driver MAINT id */
+			pmsg->di_cpu      = 0;
+			pmsg->data_length = length;
+			queueCompleteMsg(pmsg);
+		}
+	} break;
+
+	case DLI_LOG:
+	case DLI_FTL:
+	case DLI_ERR:
+	case DLI_TRC:
+	case DLI_REG:
+	case DLI_MEM:
+	case DLI_SPL:
+	case DLI_IRP:
+	case DLI_TIM:
+	case DLI_TAPI:
+	case DLI_NDIS:
+	case DLI_CONN:
+	case DLI_STAT:
+	case DLI_PRV0:
+	case DLI_PRV1:
+	case DLI_PRV2:
+	case DLI_PRV3:
+		if ((length = (unsigned long)vsprintf(&fmtBuf[0], format, ap)) > 0) {
+			length += (sizeof(*pmsg) + 1);
+
+			while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+									       (word)length))) {
+				if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+					queueFreeMsg(dbg_queue);
+				} else {
+					break;
+				}
+			}
+
+			pmsg->sequence    = dbg_sequence++;
+			pmsg->time_sec    = sec;
+			pmsg->time_usec   = usec;
+			pmsg->facility    = MSG_TYPE_STRING;
+			pmsg->dli         = type; /* DLI_XXX */
+			pmsg->drv_id      = id;   /* driver MAINT id */
+			pmsg->di_cpu      = 0;
+			pmsg->data_length = length - sizeof(*pmsg);
+
+			memcpy(&pmsg[1], fmtBuf, pmsg->data_length);
+			queueCompleteMsg(pmsg);
+		}
+		break;
+
+	} /* switch type */
+
+
+	if (queueCount(dbg_queue)) {
+		diva_maint_wakeup_read();
+	}
+
+	if (do_lock) {
+		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "format");
+	}
 }
 
 /*
   Write driver ID and driver revision to callers buffer
-  */
-int diva_get_driver_info (dword id, byte* data, int data_length) {
-  diva_os_spin_lock_magic_t old_irql;
-  byte* p = data;
-  int to_copy;
-
-  if (!data || !id || (data_length < 17) ||
-      (id >= ARRAY_SIZE(clients))) {
-    return (-1);
-  }
-
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info");
-
-  if (clients[id].hDbg) {
-    *p++ = 1;
-    *p++ = (byte)clients[id].sec; /* save seconds */
-    *p++ = (byte)(clients[id].sec >>  8);
-    *p++ = (byte)(clients[id].sec >> 16);
-    *p++ = (byte)(clients[id].sec >> 24);
-
-    *p++ = (byte)(clients[id].usec/1000); /* save mseconds */
-    *p++ = (byte)((clients[id].usec/1000) >>  8);
-    *p++ = (byte)((clients[id].usec/1000) >> 16);
-    *p++ = (byte)((clients[id].usec/1000) >> 24);
-
-    data_length -= 9;
-
-    if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length-1)))) {
-      memcpy (p, clients[id].drvName, to_copy);
-      p += to_copy;
-      data_length -= to_copy;
-      if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) {
-        *p++ = '(';
-        data_length -= 1;
-        if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length-2)))) {
-          memcpy (p, clients[id].hDbg->drvTag, to_copy);
-          p += to_copy;
-          data_length -= to_copy;
-          if (data_length >= 2) {
-            *p++ = ')';
-            data_length--;
-          }
-        }
-      }
-    }
-  }
-  *p++ = 0;
-
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "driver info");
-
-  return (p - data);
-}
+*/
+int diva_get_driver_info(dword id, byte *data, int data_length) {
+	diva_os_spin_lock_magic_t old_irql;
+	byte *p = data;
+	int to_copy;
+
+	if (!data || !id || (data_length < 17) ||
+	    (id >= ARRAY_SIZE(clients))) {
+		return (-1);
+	}
 
-int diva_get_driver_dbg_mask (dword id, byte* data) {
-  diva_os_spin_lock_magic_t old_irql;
-  int ret = -1;
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info");
+
+	if (clients[id].hDbg) {
+		*p++ = 1;
+		*p++ = (byte)clients[id].sec; /* save seconds */
+		*p++ = (byte)(clients[id].sec >>  8);
+		*p++ = (byte)(clients[id].sec >> 16);
+		*p++ = (byte)(clients[id].sec >> 24);
+
+		*p++ = (byte)(clients[id].usec / 1000); /* save mseconds */
+		*p++ = (byte)((clients[id].usec / 1000) >>  8);
+		*p++ = (byte)((clients[id].usec / 1000) >> 16);
+		*p++ = (byte)((clients[id].usec / 1000) >> 24);
+
+		data_length -= 9;
+
+		if ((to_copy = min(strlen(clients[id].drvName), (size_t)(data_length - 1)))) {
+			memcpy(p, clients[id].drvName, to_copy);
+			p += to_copy;
+			data_length -= to_copy;
+			if ((data_length >= 4) && clients[id].hDbg->drvTag[0]) {
+				*p++ = '(';
+				data_length -= 1;
+				if ((to_copy = min(strlen(clients[id].hDbg->drvTag), (size_t)(data_length - 2)))) {
+					memcpy(p, clients[id].hDbg->drvTag, to_copy);
+					p += to_copy;
+					data_length -= to_copy;
+					if (data_length >= 2) {
+						*p++ = ')';
+						data_length--;
+					}
+				}
+			}
+		}
+	}
+	*p++ = 0;
 
-  if (!data || !id || (id >= ARRAY_SIZE(clients))) {
-    return (-1);
-  }
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info");
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info");
 
-  if (clients[id].hDbg) {
-    ret = 4;
-    *data++= (byte)(clients[id].hDbg->dbgMask);
-    *data++= (byte)(clients[id].hDbg->dbgMask >>  8);
-    *data++= (byte)(clients[id].hDbg->dbgMask >> 16);
-    *data++= (byte)(clients[id].hDbg->dbgMask >> 24);
-  }
+	return (p - data);
+}
+
+int diva_get_driver_dbg_mask(dword id, byte *data) {
+	diva_os_spin_lock_magic_t old_irql;
+	int ret = -1;
+
+	if (!data || !id || (id >= ARRAY_SIZE(clients))) {
+		return (-1);
+	}
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "driver info");
+
+	if (clients[id].hDbg) {
+		ret = 4;
+		*data++ = (byte)(clients[id].hDbg->dbgMask);
+		*data++ = (byte)(clients[id].hDbg->dbgMask >>  8);
+		*data++ = (byte)(clients[id].hDbg->dbgMask >> 16);
+		*data++ = (byte)(clients[id].hDbg->dbgMask >> 24);
+	}
 
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "driver info");
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "driver info");
 
-  return (ret);
+	return (ret);
 }
 
-int diva_set_driver_dbg_mask (dword id, dword mask) {
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
-  int ret = -1;
-  
+int diva_set_driver_dbg_mask(dword id, dword mask) {
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
+	int ret = -1;
 
-  if (!id || (id >= ARRAY_SIZE(clients))) {
-    return (-1);
-  }
 
-  diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "dbg mask");
+	if (!id || (id >= ARRAY_SIZE(clients))) {
+		return (-1);
+	}
 
-  if (clients[id].hDbg) {
-    dword old_mask = clients[id].hDbg->dbgMask;
-    mask &= 0x7fffffff;
-    clients[id].hDbg->dbgMask = mask;
-    clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask);
-    ret = 4;
-    diva_change_management_debug_mask (&clients[id], old_mask);
-  }
+	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "dbg mask");
 
+	if (clients[id].hDbg) {
+		dword old_mask = clients[id].hDbg->dbgMask;
+		mask &= 0x7fffffff;
+		clients[id].hDbg->dbgMask = mask;
+		clients[id].last_dbgMask = (clients[id].hDbg->dbgMask | clients[id].dbgMask);
+		ret = 4;
+		diva_change_management_debug_mask(&clients[id], old_mask);
+	}
 
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "dbg mask");
 
-  if (clients[id].request_pending) {
-    clients[id].request_pending = 0;
-    (*(clients[id].request))((ENTITY*)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
-  }
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "dbg mask");
 
-  diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");
+	if (clients[id].request_pending) {
+		clients[id].request_pending = 0;
+		(*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
+	}
+
+	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
 
-  return (ret);
+	return (ret);
 }
 
-static int diva_get_idi_adapter_info (IDI_CALL request, dword* serial, dword* logical) {
-  IDI_SYNC_REQ sync_req;
+static int diva_get_idi_adapter_info(IDI_CALL request, dword *serial, dword *logical) {
+	IDI_SYNC_REQ sync_req;
 
-  sync_req.xdi_logical_adapter_number.Req = 0;
-  sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
-  (*request)((ENTITY *)&sync_req);
-  *logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
+	sync_req.xdi_logical_adapter_number.Req = 0;
+	sync_req.xdi_logical_adapter_number.Rc = IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
+	(*request)((ENTITY *)&sync_req);
+	*logical = sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
 
-  sync_req.GetSerial.Req = 0;
-  sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
-  sync_req.GetSerial.serial = 0;
-  (*request)((ENTITY *)&sync_req);
+	sync_req.GetSerial.Req = 0;
+	sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
+	sync_req.GetSerial.serial = 0;
+	(*request)((ENTITY *)&sync_req);
 	*serial = sync_req.GetSerial.serial;
 
-  return (0);
+	return (0);
 }
 
 /*
   Register XDI adapter as MAINT compatible driver
-  */
-void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
-  dword sec, usec, logical, serial, org_mask;
-  int id, free_id = -1;
-  char tmp[128];
-  diva_dbg_entry_head_t* pmsg = NULL;
-  int len;
-  word size;
-  byte* pmem;
-
-  diva_os_get_time (&sec, &usec);
-  diva_get_idi_adapter_info (d->request, &serial, &logical);
-  if (serial & 0xff000000) {
-    sprintf (tmp, "ADAPTER:%d SN:%u-%d",
-             (int)logical,
-             serial & 0x00ffffff,
-             (byte)(((serial & 0xff000000) >> 24) + 1));
-  } else {
-    sprintf (tmp, "ADAPTER:%d SN:%u", (int)logical, serial);
-  }
-
-  if (!(pmem = diva_os_malloc (0, DivaSTraceGetMemotyRequirement (d->channels)))) {
-    return;
-  }
-  memset (pmem, 0x00, DivaSTraceGetMemotyRequirement (d->channels));
-
-  diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");
-
-  for (id = 1; id < ARRAY_SIZE(clients); id++) {
-    if (clients[id].hDbg && (clients[id].request == d->request)) {
-      diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
-      diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
-      diva_os_free(0, pmem);
-      return;
-    }
-    if (clients[id].hDbg) { /* slot is busy */
-      continue;
-    }
-    if (free_id < 0) {
-      free_id = id;
-    }
-    if (!strcmp (clients[id].drvName, tmp)) {
-      /*
-        This driver was already registered with this name
-        and slot is still free - reuse it
-        */
-      free_id = id;
-      break;
-    }
-  }
-
-  if (free_id < 0) {
-    diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
-    diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
-    diva_os_free (0, pmem);
-    return;
-  }
-
-  id = free_id;
-  clients[id].request  = d->request;
-  clients[id].request_pending = 0;
-  clients[id].hDbg     = &clients[id].Dbg;
-  clients[id].sec      = sec;
-  clients[id].usec     = usec;
-  strcpy (clients[id].drvName,     tmp);
-  strcpy (clients[id].Dbg.drvName, tmp);
-  clients[id].Dbg.drvTag[0] = 0;
-  clients[id].logical  = (int)logical;
-  clients[id].channels = (int)d->channels;
-  clients[id].dma_handle = -1;
-
-  clients[id].Dbg.dbgMask    = 0;
-  clients[id].dbgMask        = clients[id].Dbg.dbgMask;
-  if (id) {
-    clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask;
-  } else {
-    clients[id].last_dbgMask = 0;
-  }
-  clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW;
-  clients[id].Dbg.id         = (byte)id;
-  clients[id].Dbg.dbg_end    = DI_deregister;
-  clients[id].Dbg.dbg_prt    = DI_format_locked;
-  clients[id].Dbg.dbg_ev     = DiProcessEventLog;
-  clients[id].Dbg.dbg_irq    = DI_format_locked;
-  clients[id].Dbg.next       = (pDbgHandle)DBG_MAGIC;
-
-  {
-    diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id],
-																							 diva_maint_state_change_notify,
-																							 diva_maint_trace_notify,
-																							 diva_maint_error };
-
-    /*
-      Attach to adapter management interface
-      */
-    if ((clients[id].pIdiLib =
-               DivaSTraceLibraryCreateInstance ((int)logical, &diva_maint_user_ifc, pmem))) {
-      if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) {
-        diva_mnt_internal_dprintf (0, DLI_ERR, "Adapter(%d) Start failed", (int)logical);
-        (*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib);
-        clients[id].pIdiLib = NULL;
-      }
-    } else {
-      diva_mnt_internal_dprintf (0, DLI_ERR, "A(%d) management init failed", (int)logical);
-    }
-  }
-
-  if (!clients[id].pIdiLib) {
-    clients[id].request = NULL;
-    clients[id].request_pending = 0;
-    clients[id].hDbg    = NULL;
-    diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
-    diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
-    diva_os_free (0, pmem);
-    return;
-  }
-
-  /*
-    Log driver register, MAINT driver ID is '0'
-    */
-  len = sprintf (tmp, "DIMAINT - drv # %d = '%s' registered",
-                 id, clients[id].Dbg.drvName);
-
-  while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                      (word)(len+1+sizeof(*pmsg))))) {
-    if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-      queueFreeMsg (dbg_queue);
-    } else {
-      break;
-    }
-  }
-
-  if (pmsg) {
-    pmsg->sequence    = dbg_sequence++;
-    pmsg->time_sec    = sec;
-    pmsg->time_usec   = usec;
-    pmsg->facility    = MSG_TYPE_STRING;
-    pmsg->dli         = DLI_REG;
-    pmsg->drv_id      = 0; /* id 0 - DIMAINT */
-    pmsg->di_cpu      = 0;
-    pmsg->data_length = len+1;
-
-    memcpy (&pmsg[1], tmp, len+1);
-    queueCompleteMsg (pmsg);
-    diva_maint_wakeup_read();
-  }
-
-  org_mask = clients[id].Dbg.dbgMask;
-  clients[id].Dbg.dbgMask = 0;
-
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
-
-  if (clients[id].request_pending) {
-    clients[id].request_pending = 0;
-    (*(clients[id].request))((ENTITY*)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
-  }
-
-  diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
-
-	diva_set_driver_dbg_mask (id, org_mask);
+*/
+void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d) {
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
+	dword sec, usec, logical, serial, org_mask;
+	int id, free_id = -1;
+	char tmp[128];
+	diva_dbg_entry_head_t *pmsg = NULL;
+	int len;
+	word size;
+	byte *pmem;
+
+	diva_os_get_time(&sec, &usec);
+	diva_get_idi_adapter_info(d->request, &serial, &logical);
+	if (serial & 0xff000000) {
+		sprintf(tmp, "ADAPTER:%d SN:%u-%d",
+			(int)logical,
+			serial & 0x00ffffff,
+			(byte)(((serial & 0xff000000) >> 24) + 1));
+	} else {
+		sprintf(tmp, "ADAPTER:%d SN:%u", (int)logical, serial);
+	}
+
+	if (!(pmem = diva_os_malloc(0, DivaSTraceGetMemotyRequirement(d->channels)))) {
+		return;
+	}
+	memset(pmem, 0x00, DivaSTraceGetMemotyRequirement(d->channels));
+
+	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "register");
+
+	for (id = 1; id < ARRAY_SIZE(clients); id++) {
+		if (clients[id].hDbg && (clients[id].request == d->request)) {
+			diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
+			diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
+			diva_os_free(0, pmem);
+			return;
+		}
+		if (clients[id].hDbg) { /* slot is busy */
+			continue;
+		}
+		if (free_id < 0) {
+			free_id = id;
+		}
+		if (!strcmp(clients[id].drvName, tmp)) {
+			/*
+			  This driver was already registered with this name
+			  and slot is still free - reuse it
+			*/
+			free_id = id;
+			break;
+		}
+	}
+
+	if (free_id < 0) {
+		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
+		diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
+		diva_os_free(0, pmem);
+		return;
+	}
+
+	id = free_id;
+	clients[id].request  = d->request;
+	clients[id].request_pending = 0;
+	clients[id].hDbg     = &clients[id].Dbg;
+	clients[id].sec      = sec;
+	clients[id].usec     = usec;
+	strcpy(clients[id].drvName,     tmp);
+	strcpy(clients[id].Dbg.drvName, tmp);
+	clients[id].Dbg.drvTag[0] = 0;
+	clients[id].logical  = (int)logical;
+	clients[id].channels = (int)d->channels;
+	clients[id].dma_handle = -1;
+
+	clients[id].Dbg.dbgMask    = 0;
+	clients[id].dbgMask        = clients[id].Dbg.dbgMask;
+	if (id) {
+		clients[id].Dbg.dbgMask |= clients[free_id].last_dbgMask;
+	} else {
+		clients[id].last_dbgMask = 0;
+	}
+	clients[id].Dbg.Registered = DBG_HANDLE_REG_NEW;
+	clients[id].Dbg.id         = (byte)id;
+	clients[id].Dbg.dbg_end    = DI_deregister;
+	clients[id].Dbg.dbg_prt    = DI_format_locked;
+	clients[id].Dbg.dbg_ev     = DiProcessEventLog;
+	clients[id].Dbg.dbg_irq    = DI_format_locked;
+	clients[id].Dbg.next       = (pDbgHandle)DBG_MAGIC;
+
+	{
+		diva_trace_library_user_interface_t diva_maint_user_ifc = { &clients[id],
+									    diva_maint_state_change_notify,
+									    diva_maint_trace_notify,
+									    diva_maint_error };
+
+		/*
+		  Attach to adapter management interface
+		*/
+		if ((clients[id].pIdiLib =
+		     DivaSTraceLibraryCreateInstance((int)logical, &diva_maint_user_ifc, pmem))) {
+			if (((*(clients[id].pIdiLib->DivaSTraceLibraryStart))(clients[id].pIdiLib->hLib))) {
+				diva_mnt_internal_dprintf(0, DLI_ERR, "Adapter(%d) Start failed", (int)logical);
+				(*(clients[id].pIdiLib->DivaSTraceLibraryFinit))(clients[id].pIdiLib->hLib);
+				clients[id].pIdiLib = NULL;
+			}
+		} else {
+			diva_mnt_internal_dprintf(0, DLI_ERR, "A(%d) management init failed", (int)logical);
+		}
+	}
+
+	if (!clients[id].pIdiLib) {
+		clients[id].request = NULL;
+		clients[id].request_pending = 0;
+		clients[id].hDbg    = NULL;
+		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
+		diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
+		diva_os_free(0, pmem);
+		return;
+	}
+
+	/*
+	  Log driver register, MAINT driver ID is '0'
+	*/
+	len = sprintf(tmp, "DIMAINT - drv # %d = '%s' registered",
+		      id, clients[id].Dbg.drvName);
+
+	while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+							       (word)(len + 1 + sizeof(*pmsg))))) {
+		if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+			queueFreeMsg(dbg_queue);
+		} else {
+			break;
+		}
+	}
+
+	if (pmsg) {
+		pmsg->sequence    = dbg_sequence++;
+		pmsg->time_sec    = sec;
+		pmsg->time_usec   = usec;
+		pmsg->facility    = MSG_TYPE_STRING;
+		pmsg->dli         = DLI_REG;
+		pmsg->drv_id      = 0; /* id 0 - DIMAINT */
+		pmsg->di_cpu      = 0;
+		pmsg->data_length = len + 1;
+
+		memcpy(&pmsg[1], tmp, len + 1);
+		queueCompleteMsg(pmsg);
+		diva_maint_wakeup_read();
+	}
+
+	org_mask = clients[id].Dbg.dbgMask;
+	clients[id].Dbg.dbgMask = 0;
+
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "register");
+
+	if (clients[id].request_pending) {
+		clients[id].request_pending = 0;
+		(*(clients[id].request))((ENTITY *)(*(clients[id].pIdiLib->DivaSTraceGetHandle))(clients[id].pIdiLib->hLib));
+	}
+
+	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "register");
+
+	diva_set_driver_dbg_mask(id, org_mask);
 }
 
 /*
   De-Register XDI adapter
-  */
-void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d) {
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
-  dword sec, usec;
-  int i;
-  word size;
-  byte* pmem = NULL;
-
-  diva_os_get_time (&sec, &usec);
-
-  diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read");
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read");
-
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    if (clients[i].hDbg && (clients[i].request == d->request)) {
-      diva_dbg_entry_head_t* pmsg;
-      char tmp[256];
-      int len;
-
-      if (clients[i].pIdiLib) {
-        (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
-        clients[i].pIdiLib = NULL;
-
-        pmem = clients[i].pmem;
-        clients[i].pmem = NULL;
-      }
-
-      clients[i].hDbg    = NULL;
-      clients[i].request_pending = 0;
-      if (clients[i].dma_handle >= 0) {
-        /*
-          Free DMA handle
-          */
-        diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle);
-        clients[i].dma_handle = -1;
-      }
-      clients[i].request = NULL;
-
-      /*
-        Log driver register, MAINT driver ID is '0'
-        */
-      len = sprintf (tmp, "DIMAINT - drv # %d = '%s' de-registered",
-                     i, clients[i].Dbg.drvName);
-
-      memset (&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg));
-
-      while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                                        (word)(len+1+sizeof(*pmsg))))) {
-        if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-          queueFreeMsg (dbg_queue);
-        } else {
-          break;
-        }
-      }
-
-      if (pmsg) {
-        pmsg->sequence    = dbg_sequence++;
-        pmsg->time_sec    = sec;
-        pmsg->time_usec   = usec;
-        pmsg->facility    = MSG_TYPE_STRING;
-        pmsg->dli         = DLI_REG;
-        pmsg->drv_id      = 0; /* id 0 - DIMAINT */
-        pmsg->di_cpu      = 0;
-        pmsg->data_length = len+1;
-
-        memcpy (&pmsg[1], tmp, len+1);
-  		  queueCompleteMsg (pmsg);
-        diva_maint_wakeup_read();
-      }
-
-      break;
-    }
-  }
-
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_ack");
-  diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "read_ack");
-
-  if (pmem) {
-    diva_os_free (0, pmem);
-  }
+*/
+void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d) {
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
+	dword sec, usec;
+	int i;
+	word size;
+	byte *pmem = NULL;
+
+	diva_os_get_time(&sec, &usec);
+
+	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "read");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read");
+
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		if (clients[i].hDbg && (clients[i].request == d->request)) {
+			diva_dbg_entry_head_t *pmsg;
+			char tmp[256];
+			int len;
+
+			if (clients[i].pIdiLib) {
+				(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
+				clients[i].pIdiLib = NULL;
+
+				pmem = clients[i].pmem;
+				clients[i].pmem = NULL;
+			}
+
+			clients[i].hDbg    = NULL;
+			clients[i].request_pending = 0;
+			if (clients[i].dma_handle >= 0) {
+				/*
+				  Free DMA handle
+				*/
+				diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
+				clients[i].dma_handle = -1;
+			}
+			clients[i].request = NULL;
+
+			/*
+			  Log driver register, MAINT driver ID is '0'
+			*/
+			len = sprintf(tmp, "DIMAINT - drv # %d = '%s' de-registered",
+				      i, clients[i].Dbg.drvName);
+
+			memset(&clients[i].Dbg, 0x00, sizeof(clients[i].Dbg));
+
+			while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+									       (word)(len + 1 + sizeof(*pmsg))))) {
+				if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+					queueFreeMsg(dbg_queue);
+				} else {
+					break;
+				}
+			}
+
+			if (pmsg) {
+				pmsg->sequence    = dbg_sequence++;
+				pmsg->time_sec    = sec;
+				pmsg->time_usec   = usec;
+				pmsg->facility    = MSG_TYPE_STRING;
+				pmsg->dli         = DLI_REG;
+				pmsg->drv_id      = 0; /* id 0 - DIMAINT */
+				pmsg->di_cpu      = 0;
+				pmsg->data_length = len + 1;
+
+				memcpy(&pmsg[1], tmp, len + 1);
+				queueCompleteMsg(pmsg);
+				diva_maint_wakeup_read();
+			}
+
+			break;
+		}
+	}
+
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_ack");
+	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "read_ack");
+
+	if (pmem) {
+		diva_os_free(0, pmem);
+	}
 }
 
 /* ----------------------------------------------------------------
-     Low level interface for management interface client
+   Low level interface for management interface client
    ---------------------------------------------------------------- */
 /*
   Return handle to client structure
-  */
-void* SuperTraceOpenAdapter   (int AdapterNumber) {
-  int i;
+*/
+void *SuperTraceOpenAdapter(int AdapterNumber) {
+	int i;
 
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) {
-      return (&clients[i]);
-    }
-  }
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) {
+			return (&clients[i]);
+		}
+	}
 
-  return NULL;
+	return NULL;
 }
 
-int SuperTraceCloseAdapter  (void* AdapterHandle) {
-  return (0);
+int SuperTraceCloseAdapter(void *AdapterHandle) {
+	return (0);
 }
 
-int SuperTraceReadRequest (void* AdapterHandle, const char* name, byte* data) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;
+int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
 
-  if (pC && pC->pIdiLib && pC->request) {
-    ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
-    byte* xdata = (byte*)&pC->xbuffer[0];
-    char tmp = 0;
-    word length;
+	if (pC && pC->pIdiLib && pC->request) {
+		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
+		byte *xdata = (byte *)&pC->xbuffer[0];
+		char tmp = 0;
+		word length;
 
-    if (!strcmp(name, "\\")) { /* Read ROOT */
-      name = &tmp;
-    }
-    length = SuperTraceCreateReadReq (xdata, name);
-    single_p (xdata, &length, 0); /* End Of Message */
+		if (!strcmp(name, "\\")) { /* Read ROOT */
+			name = &tmp;
+		}
+		length = SuperTraceCreateReadReq(xdata, name);
+		single_p(xdata, &length, 0); /* End Of Message */
 
-    e->Req        = MAN_READ;
-    e->ReqCh      = 0;
-    e->X->PLength = length;
-    e->X->P			  = (byte*)xdata;
+		e->Req        = MAN_READ;
+		e->ReqCh      = 0;
+		e->X->PLength = length;
+		e->X->P	= (byte *)xdata;
 
-    pC->request_pending = 1;
+		pC->request_pending = 1;
 
-    return (0);
-  }
+		return (0);
+	}
 
-  return (-1);
+	return (-1);
 }
 
-int SuperTraceGetNumberOfChannels (void* AdapterHandle) {
-  if (AdapterHandle) {
-    diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;
+int SuperTraceGetNumberOfChannels(void *AdapterHandle) {
+	if (AdapterHandle) {
+		diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
 
-    return (pC->channels);
-  }
+		return (pC->channels);
+	}
 
-  return (0);
+	return (0);
 }
 
-int SuperTraceASSIGN (void* AdapterHandle, byte* data) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;
-
-  if (pC && pC->pIdiLib && pC->request) {
-    ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
-    IDI_SYNC_REQ* preq;
-    char buffer[((sizeof(preq->xdi_extended_features)+4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features)+4) : sizeof(ENTITY)];
-    char features[4];
-    word assign_data_length = 1;
-
-    features[0] = 0;
-    pC->xbuffer[0] = 0;
-    preq = (IDI_SYNC_REQ*)&buffer[0];
-    preq->xdi_extended_features.Req = 0;
-    preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
-    preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
-    preq->xdi_extended_features.info.features = &features[0];
-
-    (*(pC->request))((ENTITY*)preq);
-
-    if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) &&
-        (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) {
-      dword uninitialized_var(rx_dma_magic);
-      if ((pC->dma_handle = diva_get_dma_descriptor (pC->request, &rx_dma_magic)) >= 0) {
-        pC->xbuffer[0] = LLI;
-        pC->xbuffer[1] = 8;
-        pC->xbuffer[2] = 0x40;
-        pC->xbuffer[3] = (byte)pC->dma_handle;
-        pC->xbuffer[4] = (byte)rx_dma_magic;
-        pC->xbuffer[5] = (byte)(rx_dma_magic >>  8);
-        pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
-        pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
-	pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
-        pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
-        pC->xbuffer[10] = 0;
-
-        assign_data_length = 11;
-      }
-    } else {
-      pC->dma_handle = -1;
-    }
-
-    e->Id          = MAN_ID;
-    e->callback    = diva_maint_xdi_cb;
-    e->XNum        = 1;
-    e->X           = &pC->XData;
-    e->Req         = ASSIGN;
-    e->ReqCh       = 0;
-    e->X->PLength  = assign_data_length;
-    e->X->P        = (byte*)&pC->xbuffer[0];
-
-    pC->request_pending = 1;
-
-    return (0);
-  }
-
-  return (-1);
+int SuperTraceASSIGN(void *AdapterHandle, byte *data) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
+
+	if (pC && pC->pIdiLib && pC->request) {
+		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
+		IDI_SYNC_REQ *preq;
+		char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)];
+		char features[4];
+		word assign_data_length = 1;
+
+		features[0] = 0;
+		pC->xbuffer[0] = 0;
+		preq = (IDI_SYNC_REQ *)&buffer[0];
+		preq->xdi_extended_features.Req = 0;
+		preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
+		preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
+		preq->xdi_extended_features.info.features = &features[0];
+
+		(*(pC->request))((ENTITY *)preq);
+
+		if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) &&
+		    (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) {
+			dword uninitialized_var(rx_dma_magic);
+			if ((pC->dma_handle = diva_get_dma_descriptor(pC->request, &rx_dma_magic)) >= 0) {
+				pC->xbuffer[0] = LLI;
+				pC->xbuffer[1] = 8;
+				pC->xbuffer[2] = 0x40;
+				pC->xbuffer[3] = (byte)pC->dma_handle;
+				pC->xbuffer[4] = (byte)rx_dma_magic;
+				pC->xbuffer[5] = (byte)(rx_dma_magic >>  8);
+				pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
+				pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
+				pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
+				pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
+				pC->xbuffer[10] = 0;
+
+				assign_data_length = 11;
+			}
+		} else {
+			pC->dma_handle = -1;
+		}
+
+		e->Id          = MAN_ID;
+		e->callback    = diva_maint_xdi_cb;
+		e->XNum        = 1;
+		e->X           = &pC->XData;
+		e->Req         = ASSIGN;
+		e->ReqCh       = 0;
+		e->X->PLength  = assign_data_length;
+		e->X->P        = (byte *)&pC->xbuffer[0];
+
+		pC->request_pending = 1;
+
+		return (0);
+	}
+
+	return (-1);
 }
 
-int SuperTraceREMOVE (void* AdapterHandle) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;
+int SuperTraceREMOVE(void *AdapterHandle) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
 
-  if (pC && pC->pIdiLib && pC->request) {
-    ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
+	if (pC && pC->pIdiLib && pC->request) {
+		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
 
-    e->XNum        = 1;
-    e->X           = &pC->XData;
-    e->Req         = REMOVE;
-    e->ReqCh       = 0;
-    e->X->PLength  = 1;
-    e->X->P        = (byte*)&pC->xbuffer[0];
-    pC->xbuffer[0] = 0;
+		e->XNum        = 1;
+		e->X           = &pC->XData;
+		e->Req         = REMOVE;
+		e->ReqCh       = 0;
+		e->X->PLength  = 1;
+		e->X->P        = (byte *)&pC->xbuffer[0];
+		pC->xbuffer[0] = 0;
 
-    pC->request_pending = 1;
+		pC->request_pending = 1;
 
-    return (0);
-  }
+		return (0);
+	}
 
-  return (-1);
+	return (-1);
 }
 
-int SuperTraceTraceOnRequest(void* hAdapter, const char* name, byte* data) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)hAdapter;
+int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)hAdapter;
 
-  if (pC && pC->pIdiLib && pC->request) {
-    ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
-    byte* xdata = (byte*)&pC->xbuffer[0];
-    char tmp = 0;
-    word length;
+	if (pC && pC->pIdiLib && pC->request) {
+		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
+		byte *xdata = (byte *)&pC->xbuffer[0];
+		char tmp = 0;
+		word length;
 
-    if (!strcmp(name, "\\")) { /* Read ROOT */
-      name = &tmp;
-    }
-    length = SuperTraceCreateReadReq (xdata, name);
-    single_p (xdata, &length, 0); /* End Of Message */
-    e->Req          = MAN_EVENT_ON;
-    e->ReqCh        = 0;
-    e->X->PLength   = length;
-    e->X->P			    = (byte*)xdata;
+		if (!strcmp(name, "\\")) { /* Read ROOT */
+			name = &tmp;
+		}
+		length = SuperTraceCreateReadReq(xdata, name);
+		single_p(xdata, &length, 0); /* End Of Message */
+		e->Req          = MAN_EVENT_ON;
+		e->ReqCh        = 0;
+		e->X->PLength   = length;
+		e->X->P = (byte *)xdata;
 
-    pC->request_pending = 1;
+		pC->request_pending = 1;
 
-    return (0);
-  }
+		return (0);
+	}
 
-  return (-1);
+	return (-1);
 }
 
-int SuperTraceWriteVar (void* AdapterHandle,
-                        byte* data,
-                        const char* name,
-                        void* var,
-                        byte type,
-                        byte var_length) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;
-
-  if (pC && pC->pIdiLib && pC->request) {
-    ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
-    diva_man_var_header_t* pVar = (diva_man_var_header_t*)&pC->xbuffer[0];
-    word length = SuperTraceCreateReadReq ((byte*)pVar, name);
-
-    memcpy (&pC->xbuffer[length], var, var_length);
-    length += var_length;
-    pVar->length += var_length;
-    pVar->value_length = var_length;
-    pVar->type = type;
-    single_p ((byte*)pVar, &length, 0); /* End Of Message */
-
-    e->Req          = MAN_WRITE;
-    e->ReqCh			  = 0;
-    e->X->PLength   = length;
-    e->X->P			    = (byte*)pVar;
-
-    pC->request_pending = 1;
-
-    return (0);
-  }
-
-  return (-1);
+int SuperTraceWriteVar(void *AdapterHandle,
+		       byte *data,
+		       const char *name,
+		       void *var,
+		       byte type,
+		       byte var_length) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
+
+	if (pC && pC->pIdiLib && pC->request) {
+		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
+		diva_man_var_header_t *pVar = (diva_man_var_header_t *)&pC->xbuffer[0];
+		word length = SuperTraceCreateReadReq((byte *)pVar, name);
+
+		memcpy(&pC->xbuffer[length], var, var_length);
+		length += var_length;
+		pVar->length += var_length;
+		pVar->value_length = var_length;
+		pVar->type = type;
+		single_p((byte *)pVar, &length, 0); /* End Of Message */
+
+		e->Req = MAN_WRITE;
+		e->ReqCh = 0;
+		e->X->PLength   = length;
+		e->X->P = (byte *)pVar;
+
+		pC->request_pending = 1;
+
+		return (0);
+	}
+
+	return (-1);
 }
 
-int SuperTraceExecuteRequest (void* AdapterHandle,
-                              const char* name,
-                              byte* data) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)AdapterHandle;
+int SuperTraceExecuteRequest(void *AdapterHandle,
+			     const char *name,
+			     byte *data) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)AdapterHandle;
 
-  if (pC && pC->pIdiLib && pC->request) {
-    ENTITY* e = (ENTITY*)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
-    byte* xdata = (byte*)&pC->xbuffer[0];
-    word length;
+	if (pC && pC->pIdiLib && pC->request) {
+		ENTITY *e = (ENTITY *)(*(pC->pIdiLib->DivaSTraceGetHandle))(pC->pIdiLib->hLib);
+		byte *xdata = (byte *)&pC->xbuffer[0];
+		word length;
 
-    length = SuperTraceCreateReadReq (xdata, name);
-    single_p (xdata, &length, 0); /* End Of Message */
+		length = SuperTraceCreateReadReq(xdata, name);
+		single_p(xdata, &length, 0); /* End Of Message */
 
-    e->Req          = MAN_EXECUTE;
-    e->ReqCh			  = 0;
-    e->X->PLength   = length;
-    e->X->P			    = (byte*)xdata;
+		e->Req = MAN_EXECUTE;
+		e->ReqCh = 0;
+		e->X->PLength = length;
+		e->X->P = (byte *)xdata;
 
-    pC->request_pending = 1;
+		pC->request_pending = 1;
 
-    return (0);
-  }
+		return (0);
+	}
 
-  return (-1);
+	return (-1);
 }
 
-static word SuperTraceCreateReadReq (byte* P, const char* path) {
+static word SuperTraceCreateReadReq(byte *P, const char *path) {
 	byte var_length;
-	byte* plen;
+	byte *plen;
 
-	var_length = (byte)strlen (path);
+	var_length = (byte)strlen(path);
 
 	*P++ = ESC;
 	plen = P++;
@@ -1346,708 +1346,708 @@ static word SuperTraceCreateReadReq (byte* P, const char* path) {
 	*P++ = 0x00; /* Status */
 	*P++ = 0x00; /* Variable Length */
 	*P++ = var_length;
-	memcpy (P, path, var_length);
+	memcpy(P, path, var_length);
 	P += var_length;
 	*plen = var_length + 0x06;
 
 	return ((word)(var_length + 0x08));
 }
 
-static void single_p (byte * P, word * PLength, byte Id) {
-  P[(*PLength)++] = Id;
+static void single_p(byte *P, word *PLength, byte Id) {
+	P[(*PLength)++] = Id;
 }
 
-static void diva_maint_xdi_cb (ENTITY* e) {
-  diva_strace_context_t* pLib = DIVAS_CONTAINING_RECORD(e,diva_strace_context_t,e);
-  diva_maint_client_t* pC;
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
+static void diva_maint_xdi_cb(ENTITY *e) {
+	diva_strace_context_t *pLib = DIVAS_CONTAINING_RECORD(e, diva_strace_context_t, e);
+	diva_maint_client_t *pC;
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
 
 
-  diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "xdi_cb");
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "xdi_cb");
+	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb");
 
-  pC = (diva_maint_client_t*)pLib->hAdapter;
+	pC = (diva_maint_client_t *)pLib->hAdapter;
 
-  if ((e->complete == 255) || (pC->dma_handle < 0)) {
-    if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
-      diva_mnt_internal_dprintf (0, DLI_ERR, "Trace internal library error");
-    }
-  } else {
-    /*
-      Process combined management interface indication
-      */
-    if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
-      diva_mnt_internal_dprintf (0, DLI_ERR, "Trace internal library error (DMA mode)");
-    }
-  }
+	if ((e->complete == 255) || (pC->dma_handle < 0)) {
+		if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
+			diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error");
+		}
+	} else {
+		/*
+		  Process combined management interface indication
+		*/
+		if ((*(pLib->instance.DivaSTraceMessageInput))(&pLib->instance)) {
+			diva_mnt_internal_dprintf(0, DLI_ERR, "Trace internal library error (DMA mode)");
+		}
+	}
 
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "xdi_cb");
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "xdi_cb");
 
 
 	if (pC->request_pending) {
-    pC->request_pending = 0;
-    (*(pC->request))(e);
+		pC->request_pending = 0;
+		(*(pC->request))(e);
 	}
 
-  diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "xdi_cb");
+	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "xdi_cb");
 }
 
 
-static void diva_maint_error (void* user_context,
-                              diva_strace_library_interface_t* hLib,
-                              int Adapter,
-                              int error,
-                              const char* file,
-                              int line) {
-	diva_mnt_internal_dprintf (0, DLI_ERR,
-                             "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line);
+static void diva_maint_error(void *user_context,
+			     diva_strace_library_interface_t *hLib,
+			     int Adapter,
+			     int error,
+			     const char *file,
+			     int line) {
+	diva_mnt_internal_dprintf(0, DLI_ERR,
+				  "Trace library error(%d) A(%d) %s %d", error, Adapter, file, line);
 }
 
-static void print_ie (diva_trace_ie_t* ie, char* buffer, int length) {
+static void print_ie(diva_trace_ie_t *ie, char *buffer, int length) {
 	int i;
 
-  buffer[0] = 0;
-
-  if (length > 32) {
-    for (i = 0; ((i < ie->length) && (length > 3)); i++) {
-      sprintf (buffer, "%02x", ie->data[i]);
-      buffer += 2;
-      length -= 2;
-      if (i < (ie->length-1)) {
-        strcpy (buffer, " ");
-        buffer++;
-        length--;
-      }
-    }
-  }
+	buffer[0] = 0;
+
+	if (length > 32) {
+		for (i = 0; ((i < ie->length) && (length > 3)); i++) {
+			sprintf(buffer, "%02x", ie->data[i]);
+			buffer += 2;
+			length -= 2;
+			if (i < (ie->length - 1)) {
+				strcpy(buffer, " ");
+				buffer++;
+				length--;
+			}
+		}
+	}
 }
 
-static void diva_maint_state_change_notify (void* user_context,
-                                            diva_strace_library_interface_t* hLib,
-                                            int Adapter,
-                                            diva_trace_line_state_t* channel,
-                                            int notify_subject) {
-  diva_maint_client_t*      pC    = (diva_maint_client_t*)user_context;
-  diva_trace_fax_state_t*   fax   = &channel->fax;
-  diva_trace_modem_state_t* modem = &channel->modem;
-  char tmp[256];
-
-  if (!pC->hDbg) {
-    return;
-  }
-
-  switch (notify_subject) {
-    case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: {
-      int view = (TraceFilter[0] == 0);
-      /*
-        Process selective Trace
-        */
-      if (channel->Line[0] == 'I' && channel->Line[1] == 'd' &&
-          channel->Line[2] == 'l' && channel->Line[3] == 'e') {
-        if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) {
-          (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0);
-          (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0);
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d",
-                                     (int)channel->ChannelNumber);
-          TraceFilterIdent   = -1;
-          TraceFilterChannel = -1;
-          view = 1;
-        }
-      } else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr (&channel->RemoteAddress[0]) &&
-                                                               diva_mnt_cmp_nmbr (&channel->LocalAddress[0]))) {
-
-        if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */
-          (*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1);
-        }
-        if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */
-          (*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1);
-        }
-
-        TraceFilterIdent   = pC->hDbg->id;
-        TraceFilterChannel = (int)channel->ChannelNumber;
-
-        if (TraceFilterIdent >= 0) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d",
-                                     (int)channel->ChannelNumber);
-          view = 1;
-        }
-      }
-      if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Ch     = %d",
-                                                                     (int)channel->ChannelNumber);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L RAddr  = <%s>",
-                                                                     &channel->RemoteAddress[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>",
-                                                                     &channel->RemoteSubAddress[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LAddr  = <%s>",
-                                                                     &channel->LocalAddress[0]);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>",
-                                                                     &channel->LocalSubAddress[0]);
-        print_ie(&channel->call_BC, tmp, sizeof(tmp));
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L BC     = <%s>", tmp);
-        print_ie(&channel->call_HLC, tmp, sizeof(tmp));
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L HLC    = <%s>", tmp);
-        print_ie(&channel->call_LLC, tmp, sizeof(tmp));
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L LLC    = <%s>", tmp);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L CR     = 0x%x", channel->CallReference);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Disc   = 0x%x",
-                                                                    channel->LastDisconnecCause);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT, "L Owner  = <%s>", &channel->UserID[0]);
-      }
-
-		} break;
-
-    case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE:
-      if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) {
-				{
-					int ch = TraceFilterChannel;
-					int id = TraceFilterIdent;
-
-					if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
-						(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
-						if (ch != (int)modem->ChannelNumber) {
-							break;
-						}
-					} else if (TraceFilter[0] != 0) {
+static void diva_maint_state_change_notify(void *user_context,
+					   diva_strace_library_interface_t *hLib,
+					   int Adapter,
+					   diva_trace_line_state_t *channel,
+					   int notify_subject) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)user_context;
+	diva_trace_fax_state_t *fax = &channel->fax;
+	diva_trace_modem_state_t *modem = &channel->modem;
+	char tmp[256];
+
+	if (!pC->hDbg) {
+		return;
+	}
+
+	switch (notify_subject) {
+	case DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE: {
+		int view = (TraceFilter[0] == 0);
+		/*
+		  Process selective Trace
+		*/
+		if (channel->Line[0] == 'I' && channel->Line[1] == 'd' &&
+		    channel->Line[2] == 'l' && channel->Line[3] == 'e') {
+			if ((TraceFilterIdent == pC->hDbg->id) && (TraceFilterChannel == (int)channel->ChannelNumber)) {
+				(*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 0);
+				(*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 0);
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace OFF for Ch=%d",
+							  (int)channel->ChannelNumber);
+				TraceFilterIdent   = -1;
+				TraceFilterChannel = -1;
+				view = 1;
+			}
+		} else if (TraceFilter[0] && (TraceFilterIdent < 0) && !(diva_mnt_cmp_nmbr(&channel->RemoteAddress[0]) &&
+									 diva_mnt_cmp_nmbr(&channel->LocalAddress[0]))) {
+
+			if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0) { /* Activate B-channel trace */
+				(*(hLib->DivaSTraceSetBChannel))(hLib, (int)channel->ChannelNumber, 1);
+			}
+			if ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0) { /* Activate AudioTap Trace */
+				(*(hLib->DivaSTraceSetAudioTap))(hLib, (int)channel->ChannelNumber, 1);
+			}
+
+			TraceFilterIdent   = pC->hDbg->id;
+			TraceFilterChannel = (int)channel->ChannelNumber;
+
+			if (TraceFilterIdent >= 0) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG, "Selective Trace ON for Ch=%d",
+							  (int)channel->ChannelNumber);
+				view = 1;
+			}
+		}
+		if (view && (pC->hDbg->dbgMask & DIVA_MGT_DBG_LINE_EVENTS)) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Ch     = %d",
+						  (int)channel->ChannelNumber);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Status = <%s>", &channel->Line[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer1 = <%s>", &channel->Framing[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer2 = <%s>", &channel->Layer2[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Layer3 = <%s>", &channel->Layer3[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RAddr  = <%s>",
+						  &channel->RemoteAddress[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L RSAddr = <%s>",
+						  &channel->RemoteSubAddress[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LAddr  = <%s>",
+						  &channel->LocalAddress[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LSAddr = <%s>",
+						  &channel->LocalSubAddress[0]);
+			print_ie(&channel->call_BC, tmp, sizeof(tmp));
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L BC     = <%s>", tmp);
+			print_ie(&channel->call_HLC, tmp, sizeof(tmp));
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L HLC    = <%s>", tmp);
+			print_ie(&channel->call_LLC, tmp, sizeof(tmp));
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L LLC    = <%s>", tmp);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L CR     = 0x%x", channel->CallReference);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Disc   = 0x%x",
+						  channel->LastDisconnecCause);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "L Owner  = <%s>", &channel->UserID[0]);
+		}
+
+	} break;
+
+	case DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE:
+		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_PROGRESS) {
+			{
+				int ch = TraceFilterChannel;
+				int id = TraceFilterIdent;
+
+				if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
+				    (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
+					if (ch != (int)modem->ChannelNumber) {
 						break;
 					}
+				} else if (TraceFilter[0] != 0) {
+					break;
 				}
+			}
+
+
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch    = %lu",
+						  (int)modem->ChannelNumber);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu", modem->Event);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm  = %lu", modem->Norm);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x", modem->Options);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx    = %lu Bps", modem->TxSpeed);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx    = %lu Bps", modem->RxSpeed);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT    = %lu mSec",
+						  modem->RoundtripMsec);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr    = %lu", modem->SymbolRate);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl   = %d dBm", modem->RxLeveldBm);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El    = %d dBm", modem->EchoLeveldBm);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR   = %lu dB", modem->SNRdb);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE   = %lu", modem->MAE);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet  = %lu",
+						  modem->LocalRetrains);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet  = %lu",
+						  modem->RemoteRetrains);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes  = %lu", modem->LocalResyncs);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes  = %lu",
+						  modem->RemoteResyncs);
+			if (modem->Event == 3) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Disc  =  %lu", modem->DiscReason);
+			}
+		}
+		if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) {
+			(*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib);
+		}
+		break;
 
+	case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE:
+		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) {
+			{
+				int ch = TraceFilterChannel;
+				int id = TraceFilterIdent;
 
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Ch    = %lu",
-                                                                     (int)modem->ChannelNumber);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Event = %lu",     modem->Event);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Norm  = %lu",     modem->Norm);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Opts. = 0x%08x",  modem->Options);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Tx    = %lu Bps", modem->TxSpeed);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rx    = %lu Bps", modem->RxSpeed);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RT    = %lu mSec",
-                                                                     modem->RoundtripMsec);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Sr    = %lu",     modem->SymbolRate);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM Rxl   = %d dBm",  modem->RxLeveldBm);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM El    = %d dBm",  modem->EchoLeveldBm);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM SNR   = %lu dB",  modem->SNRdb);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM MAE   = %lu",     modem->MAE);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRet  = %lu",
-                                                                     modem->LocalRetrains);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRet  = %lu",
-                                                                     modem->RemoteRetrains);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM LRes  = %lu",     modem->LocalResyncs);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "MDM RRes  = %lu",
-                                                                     modem->RemoteResyncs);
-        if (modem->Event == 3) {
-          diva_mnt_internal_dprintf(pC->hDbg->id,DLI_STAT,"MDM Disc  =  %lu",    modem->DiscReason);
-        }
-      }
-      if ((modem->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_MDM_STATISTICS)) {
-        (*(pC->pIdiLib->DivaSTraceGetModemStatistics))(pC->pIdiLib);
-      }
-      break;
-
-    case DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE:
-      if (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_PROGRESS) {
-				{
-					int ch = TraceFilterChannel;
-					int id = TraceFilterIdent;
-
-					if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
-						(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
-						if (ch != (int)fax->ChannelNumber) {
-							break;
-						}
-					} else if (TraceFilter[0] != 0) {
+				if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
+				    (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
+					if (ch != (int)fax->ChannelNumber) {
 						break;
 					}
+				} else if (TraceFilter[0] != 0) {
+					break;
 				}
+			}
+
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch    = %lu", (int)fax->ChannelNumber);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu",     fax->Event);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu",     fax->Page_Counter);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x",  fax->Features);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID    = <%s>",    &fax->Station_ID[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>",    &fax->Subaddress[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd   = <%s>",    &fax->Password[0]);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu",     fax->Speed);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res.  = 0x%08x",  fax->Resolution);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu",     fax->Paper_Width);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu",     fax->Paper_Length);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT   = %lu",     fax->Scanline_Time);
+			if (fax->Event == 3) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc  = %lu",     fax->Disc_Reason);
+			}
+		}
+		if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) {
+			(*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib);
+		}
+		break;
+
+	case DIVA_SUPER_TRACE_INTERFACE_CHANGE:
+		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT,
+						  "Layer 1 -> [%s]", channel->pInterface->Layer1);
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT,
+						  "Layer 2 -> [%s]", channel->pInterface->Layer2);
+		}
+		break;
+
+	case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
+		if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
+			/*
+			  Incoming Statistics
+			*/
+			if (channel->pInterfaceStat->inc.Calls) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Calls                     =%lu", channel->pInterfaceStat->inc.Calls);
+			}
+			if (channel->pInterfaceStat->inc.Connected) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Connected                 =%lu", channel->pInterfaceStat->inc.Connected);
+			}
+			if (channel->pInterfaceStat->inc.User_Busy) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Busy                      =%lu", channel->pInterfaceStat->inc.User_Busy);
+			}
+			if (channel->pInterfaceStat->inc.Call_Rejected) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Rejected                  =%lu", channel->pInterfaceStat->inc.Call_Rejected);
+			}
+			if (channel->pInterfaceStat->inc.Wrong_Number) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Wrong Nr                  =%lu", channel->pInterfaceStat->inc.Wrong_Number);
+			}
+			if (channel->pInterfaceStat->inc.Incompatible_Dst) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Incomp. Dest              =%lu", channel->pInterfaceStat->inc.Incompatible_Dst);
+			}
+			if (channel->pInterfaceStat->inc.Out_of_Order) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Out of Order              =%lu", channel->pInterfaceStat->inc.Out_of_Order);
+			}
+			if (channel->pInterfaceStat->inc.Ignored) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Inc Ignored                   =%lu", channel->pInterfaceStat->inc.Ignored);
+			}
+
+			/*
+			  Outgoing Statistics
+			*/
+			if (channel->pInterfaceStat->outg.Calls) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg Calls                    =%lu", channel->pInterfaceStat->outg.Calls);
+			}
+			if (channel->pInterfaceStat->outg.Connected) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg Connected                =%lu", channel->pInterfaceStat->outg.Connected);
+			}
+			if (channel->pInterfaceStat->outg.User_Busy) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg Busy                     =%lu", channel->pInterfaceStat->outg.User_Busy);
+			}
+			if (channel->pInterfaceStat->outg.No_Answer) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg No Answer                =%lu", channel->pInterfaceStat->outg.No_Answer);
+			}
+			if (channel->pInterfaceStat->outg.Wrong_Number) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg Wrong Nr                 =%lu", channel->pInterfaceStat->outg.Wrong_Number);
+			}
+			if (channel->pInterfaceStat->outg.Call_Rejected) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg Rejected                 =%lu", channel->pInterfaceStat->outg.Call_Rejected);
+			}
+			if (channel->pInterfaceStat->outg.Other_Failures) {
+				diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+							  "Outg Other Failures           =%lu", channel->pInterfaceStat->outg.Other_Failures);
+			}
+		}
+		break;
+
+	case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE:
+		if (channel->pInterfaceStat->mdm.Disc_Normal) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Normal        = %lu", channel->pInterfaceStat->mdm.Disc_Normal);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Unspecified) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Unsp.         = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Busy Tone     = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Congestion) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Congestion    = %lu", channel->pInterfaceStat->mdm.Disc_Congestion);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Carrier Wait  = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Trn. T.o.     = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Incompat) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Incompatible  = %lu", channel->pInterfaceStat->mdm.Disc_Incompat);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc Frame Reject  = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej);
+		}
+		if (channel->pInterfaceStat->mdm.Disc_V42bis) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "MDM Disc V.42bis       = %lu", channel->pInterfaceStat->mdm.Disc_V42bis);
+		}
+		break;
 
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Ch    = %lu",(int)fax->ChannelNumber);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Event = %lu",     fax->Event);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pages = %lu",     fax->Page_Counter);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Feat. = 0x%08x",  fax->Features);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX ID    = <%s>",    &fax->Station_ID[0]);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Saddr = <%s>",    &fax->Subaddress[0]);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Pwd   = <%s>",    &fax->Password[0]);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Speed = %lu",     fax->Speed);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Res.  = 0x%08x",  fax->Resolution);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Width = %lu",     fax->Paper_Width);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Length= %lu",     fax->Paper_Length);
-        diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX SLT   = %lu",     fax->Scanline_Time);
-        if (fax->Event == 3) {
-          diva_mnt_internal_dprintf(pC->hDbg->id, DLI_STAT, "FAX Disc  = %lu",     fax->Disc_Reason);
-        }
-      }
-      if ((fax->Event == 3) && (pC->hDbg->dbgMask & DIVA_MGT_DBG_FAX_STATISTICS)) {
-        (*(pC->pIdiLib->DivaSTraceGetFaxStatistics))(pC->pIdiLib);
-      }
-      break;
-
-    case DIVA_SUPER_TRACE_INTERFACE_CHANGE:
-      if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_EVENTS) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT,
-                                 "Layer 1 -> [%s]", channel->pInterface->Layer1);
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_STAT,
-                                 "Layer 2 -> [%s]", channel->pInterface->Layer2);
-      }
-      break;
-
-    case DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE:
-      if (pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_STATISTICS) {
-        /*
-          Incoming Statistics
-          */
-        if (channel->pInterfaceStat->inc.Calls) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Calls                     =%lu", channel->pInterfaceStat->inc.Calls);
-        }
-        if (channel->pInterfaceStat->inc.Connected) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Connected                 =%lu", channel->pInterfaceStat->inc.Connected);
-        }
-        if (channel->pInterfaceStat->inc.User_Busy) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Busy                      =%lu", channel->pInterfaceStat->inc.User_Busy);
-        }
-        if (channel->pInterfaceStat->inc.Call_Rejected) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Rejected                  =%lu", channel->pInterfaceStat->inc.Call_Rejected);
-        }
-        if (channel->pInterfaceStat->inc.Wrong_Number) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Wrong Nr                  =%lu", channel->pInterfaceStat->inc.Wrong_Number);
-        }
-        if (channel->pInterfaceStat->inc.Incompatible_Dst) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Incomp. Dest              =%lu", channel->pInterfaceStat->inc.Incompatible_Dst);
-        }
-        if (channel->pInterfaceStat->inc.Out_of_Order) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Out of Order              =%lu", channel->pInterfaceStat->inc.Out_of_Order);
-        }
-        if (channel->pInterfaceStat->inc.Ignored) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Inc Ignored                   =%lu", channel->pInterfaceStat->inc.Ignored);
-        }
-        
-        /*
-          Outgoing Statistics
-          */
-        if (channel->pInterfaceStat->outg.Calls) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg Calls                    =%lu", channel->pInterfaceStat->outg.Calls);
-        }
-        if (channel->pInterfaceStat->outg.Connected) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg Connected                =%lu", channel->pInterfaceStat->outg.Connected);
-        }
-        if (channel->pInterfaceStat->outg.User_Busy) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg Busy                     =%lu", channel->pInterfaceStat->outg.User_Busy);
-        }
-        if (channel->pInterfaceStat->outg.No_Answer) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg No Answer                =%lu", channel->pInterfaceStat->outg.No_Answer);
-        }
-        if (channel->pInterfaceStat->outg.Wrong_Number) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg Wrong Nr                 =%lu", channel->pInterfaceStat->outg.Wrong_Number);
-        }
-        if (channel->pInterfaceStat->outg.Call_Rejected) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg Rejected                 =%lu", channel->pInterfaceStat->outg.Call_Rejected);
-        }
-        if (channel->pInterfaceStat->outg.Other_Failures) {
-          diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-          "Outg Other Failures           =%lu", channel->pInterfaceStat->outg.Other_Failures);
-        }
-      }
-      break;
-
-    case DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE:
-      if (channel->pInterfaceStat->mdm.Disc_Normal) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Normal        = %lu", channel->pInterfaceStat->mdm.Disc_Normal);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Unspecified) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Unsp.         = %lu", channel->pInterfaceStat->mdm.Disc_Unspecified);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Busy_Tone) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Busy Tone     = %lu", channel->pInterfaceStat->mdm.Disc_Busy_Tone);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Congestion) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Congestion    = %lu", channel->pInterfaceStat->mdm.Disc_Congestion);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Carr_Wait) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Carrier Wait  = %lu", channel->pInterfaceStat->mdm.Disc_Carr_Wait);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Trn_Timeout) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Trn. T.o.     = %lu", channel->pInterfaceStat->mdm.Disc_Trn_Timeout);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Incompat) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Incompatible  = %lu", channel->pInterfaceStat->mdm.Disc_Incompat);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_Frame_Rej) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc Frame Reject  = %lu", channel->pInterfaceStat->mdm.Disc_Frame_Rej);
-      }
-      if (channel->pInterfaceStat->mdm.Disc_V42bis) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "MDM Disc V.42bis       = %lu", channel->pInterfaceStat->mdm.Disc_V42bis);
-      }
-      break;
-
-    case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE:
-      if (channel->pInterfaceStat->fax.Disc_Normal) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Normal        = %lu", channel->pInterfaceStat->fax.Disc_Normal);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Not_Ident) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Not Ident.    = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident);
-      }
-      if (channel->pInterfaceStat->fax.Disc_No_Response) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc No Response   = %lu", channel->pInterfaceStat->fax.Disc_No_Response);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Retries) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Max Retries   = %lu", channel->pInterfaceStat->fax.Disc_Retries);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Unexp. Msg.        = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg);
-      }
-      if (channel->pInterfaceStat->fax.Disc_No_Polling) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc No Polling    = %lu", channel->pInterfaceStat->fax.Disc_No_Polling);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Training) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Training      = %lu", channel->pInterfaceStat->fax.Disc_Training);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Unexpected) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Unexpected    = %lu", channel->pInterfaceStat->fax.Disc_Unexpected);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Application) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Application   = %lu", channel->pInterfaceStat->fax.Disc_Application);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Incompat) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Incompatible  = %lu", channel->pInterfaceStat->fax.Disc_Incompat);
-      }
-      if (channel->pInterfaceStat->fax.Disc_No_Command) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc No Command    = %lu", channel->pInterfaceStat->fax.Disc_No_Command);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Long_Msg) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Long Msg.     = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Supervisor) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Supervisor    = %lu", channel->pInterfaceStat->fax.Disc_Supervisor);
-      }
-      if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc SUP SEP PWD   = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Invalid Msg.  = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Page_Coding) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Page Coding   = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding);
-      }
-      if (channel->pInterfaceStat->fax.Disc_App_Timeout) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Appl. T.o.    = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout);
-      }
-      if (channel->pInterfaceStat->fax.Disc_Unspecified) {
-        diva_mnt_internal_dprintf (pC->hDbg->id, DLI_LOG,
-        "FAX Disc Unspec.       = %lu", channel->pInterfaceStat->fax.Disc_Unspecified);
-      }
-      break;
-  }
+	case DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE:
+		if (channel->pInterfaceStat->fax.Disc_Normal) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Normal        = %lu", channel->pInterfaceStat->fax.Disc_Normal);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Not_Ident) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Not Ident.    = %lu", channel->pInterfaceStat->fax.Disc_Not_Ident);
+		}
+		if (channel->pInterfaceStat->fax.Disc_No_Response) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc No Response   = %lu", channel->pInterfaceStat->fax.Disc_No_Response);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Retries) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Max Retries   = %lu", channel->pInterfaceStat->fax.Disc_Retries);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Unexp_Msg) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Unexp. Msg.        = %lu", channel->pInterfaceStat->fax.Disc_Unexp_Msg);
+		}
+		if (channel->pInterfaceStat->fax.Disc_No_Polling) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc No Polling    = %lu", channel->pInterfaceStat->fax.Disc_No_Polling);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Training) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Training      = %lu", channel->pInterfaceStat->fax.Disc_Training);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Unexpected) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Unexpected    = %lu", channel->pInterfaceStat->fax.Disc_Unexpected);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Application) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Application   = %lu", channel->pInterfaceStat->fax.Disc_Application);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Incompat) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Incompatible  = %lu", channel->pInterfaceStat->fax.Disc_Incompat);
+		}
+		if (channel->pInterfaceStat->fax.Disc_No_Command) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc No Command    = %lu", channel->pInterfaceStat->fax.Disc_No_Command);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Long_Msg) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Long Msg.     = %lu", channel->pInterfaceStat->fax.Disc_Long_Msg);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Supervisor) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Supervisor    = %lu", channel->pInterfaceStat->fax.Disc_Supervisor);
+		}
+		if (channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc SUP SEP PWD   = %lu", channel->pInterfaceStat->fax.Disc_SUB_SEP_PWD);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Invalid_Msg) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Invalid Msg.  = %lu", channel->pInterfaceStat->fax.Disc_Invalid_Msg);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Page_Coding) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Page Coding   = %lu", channel->pInterfaceStat->fax.Disc_Page_Coding);
+		}
+		if (channel->pInterfaceStat->fax.Disc_App_Timeout) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Appl. T.o.    = %lu", channel->pInterfaceStat->fax.Disc_App_Timeout);
+		}
+		if (channel->pInterfaceStat->fax.Disc_Unspecified) {
+			diva_mnt_internal_dprintf(pC->hDbg->id, DLI_LOG,
+						  "FAX Disc Unspec.       = %lu", channel->pInterfaceStat->fax.Disc_Unspecified);
+		}
+		break;
+	}
 }
 
 /*
   Receive trace information from the Management Interface and store it in the
   internal trace buffer with MSG_TYPE_MLOG as is, without any filtering.
   Event Filtering and formatting is done in  Management Interface self.
-  */
-static void diva_maint_trace_notify (void* user_context,
-                                     diva_strace_library_interface_t* hLib,
-                                     int Adapter,
-                                     void* xlog_buffer,
-                                     int length) {
-  diva_maint_client_t* pC = (diva_maint_client_t*)user_context;
-  diva_dbg_entry_head_t* pmsg;
-  word size;
-  dword sec, usec;
-  int ch = TraceFilterChannel;
-  int id = TraceFilterIdent;
-
-  /*
-    Selective trace
-    */
-  if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
-      (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
-    const char* p = NULL;
-    int ch_value = -1;
-    MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer;
-
-    if (Adapter != clients[id].logical) {
-      return; /* Ignore all trace messages from other adapters */
-    }
-
-    if (TrcData->code == 24) {
-      p = (char*)&TrcData->code;
-      p += 2;
-    }
-
-    /*
-      All L1 messages start as [dsp,ch], so we can filter this information
-      and filter out all messages that use different channel
-      */
-    if (p && p[0] == '[') {
-      if (p[2] == ',') {
-        p += 3;
-        ch_value = *p - '0';
-      } else if (p[3] == ',') {
-        p += 4;
-        ch_value = *p - '0';
-      }
-      if (ch_value >= 0) {
-        if (p[2] == ']') {
-          ch_value = ch_value * 10 + p[1] - '0';
-        }
-        if (ch_value != ch) {
-          return; /* Ignore other channels */
-        }
-      }
-    }
+*/
+static void diva_maint_trace_notify(void *user_context,
+				    diva_strace_library_interface_t *hLib,
+				    int Adapter,
+				    void *xlog_buffer,
+				    int length) {
+	diva_maint_client_t *pC = (diva_maint_client_t *)user_context;
+	diva_dbg_entry_head_t *pmsg;
+	word size;
+	dword sec, usec;
+	int ch = TraceFilterChannel;
+	int id = TraceFilterIdent;
+
+	/*
+	  Selective trace
+	*/
+	if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
+	    (clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
+		const char *p = NULL;
+		int ch_value = -1;
+		MI_XLOG_HDR *TrcData = (MI_XLOG_HDR *)xlog_buffer;
+
+		if (Adapter != clients[id].logical) {
+			return; /* Ignore all trace messages from other adapters */
+		}
+
+		if (TrcData->code == 24) {
+			p = (char *)&TrcData->code;
+			p += 2;
+		}
+
+		/*
+		  All L1 messages start as [dsp,ch], so we can filter this information
+		  and filter out all messages that use different channel
+		*/
+		if (p && p[0] == '[') {
+			if (p[2] == ',') {
+				p += 3;
+				ch_value = *p - '0';
+			} else if (p[3] == ',') {
+				p += 4;
+				ch_value = *p - '0';
+			}
+			if (ch_value >= 0) {
+				if (p[2] == ']') {
+					ch_value = ch_value * 10 + p[1] - '0';
+				}
+				if (ch_value != ch) {
+					return; /* Ignore other channels */
+				}
+			}
+		}
 
 	} else if (TraceFilter[0] != 0) {
-    return; /* Ignore trace if trace filter is activated, but idle */
-  }
-
-  diva_os_get_time (&sec, &usec);
-
-  while (!(pmsg = (diva_dbg_entry_head_t*)queueAllocMsg (dbg_queue,
-                              (word)length+sizeof(*pmsg)))) {
-    if ((pmsg = (diva_dbg_entry_head_t*)queuePeekMsg (dbg_queue, &size))) {
-      queueFreeMsg (dbg_queue);
-    } else {
-      break;
-    }
-  }
-  if (pmsg) {
-    memcpy (&pmsg[1], xlog_buffer, length);
-    pmsg->sequence    = dbg_sequence++;
-    pmsg->time_sec    = sec;
-    pmsg->time_usec   = usec;
-    pmsg->facility    = MSG_TYPE_MLOG;
-    pmsg->dli         = pC->logical;
-    pmsg->drv_id      = pC->hDbg->id;
-    pmsg->di_cpu      = 0;
-    pmsg->data_length = length;
-    queueCompleteMsg (pmsg);
-    if (queueCount(dbg_queue)) {
-      diva_maint_wakeup_read();
-    }
-  }
+		return; /* Ignore trace if trace filter is activated, but idle */
+	}
+
+	diva_os_get_time(&sec, &usec);
+
+	while (!(pmsg = (diva_dbg_entry_head_t *)queueAllocMsg(dbg_queue,
+							       (word)length + sizeof(*pmsg)))) {
+		if ((pmsg = (diva_dbg_entry_head_t *)queuePeekMsg(dbg_queue, &size))) {
+			queueFreeMsg(dbg_queue);
+		} else {
+			break;
+		}
+	}
+	if (pmsg) {
+		memcpy(&pmsg[1], xlog_buffer, length);
+		pmsg->sequence    = dbg_sequence++;
+		pmsg->time_sec    = sec;
+		pmsg->time_usec   = usec;
+		pmsg->facility    = MSG_TYPE_MLOG;
+		pmsg->dli         = pC->logical;
+		pmsg->drv_id      = pC->hDbg->id;
+		pmsg->di_cpu      = 0;
+		pmsg->data_length = length;
+		queueCompleteMsg(pmsg);
+		if (queueCount(dbg_queue)) {
+			diva_maint_wakeup_read();
+		}
+	}
 }
 
 
 /*
   Convert MAINT trace mask to management interface trace mask/work/facility and
   issue command to management interface
-  */
-static void diva_change_management_debug_mask (diva_maint_client_t* pC, dword old_mask) {
-  if (pC->request && pC->hDbg && pC->pIdiLib) {
-    dword changed = pC->hDbg->dbgMask ^ old_mask;
-
-    if (changed & DIVA_MGT_DBG_TRACE) {
-      (*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib,
-                                          (pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0);
-    }
-    if (changed & DIVA_MGT_DBG_DCHAN) {
-      (*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib,
-                                              (pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0);
-    }
-    if (!TraceFilter[0]) {
-      if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) {
-        int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
-
-        for (i = 0; i < pC->channels; i++) {
-          (*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i+1, state);
-        }
-      }
-      if (changed & DIVA_MGT_DBG_IFC_AUDIO) {
-        int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);
-
-        for (i = 0; i < pC->channels; i++) {
-          (*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i+1, state);
-        }
-      }
-    }
-  }
+*/
+static void diva_change_management_debug_mask(diva_maint_client_t *pC, dword old_mask) {
+	if (pC->request && pC->hDbg && pC->pIdiLib) {
+		dword changed = pC->hDbg->dbgMask ^ old_mask;
+
+		if (changed & DIVA_MGT_DBG_TRACE) {
+			(*(pC->pIdiLib->DivaSTraceSetInfo))(pC->pIdiLib,
+							    (pC->hDbg->dbgMask & DIVA_MGT_DBG_TRACE) != 0);
+		}
+		if (changed & DIVA_MGT_DBG_DCHAN) {
+			(*(pC->pIdiLib->DivaSTraceSetDChannel))(pC->pIdiLib,
+								(pC->hDbg->dbgMask & DIVA_MGT_DBG_DCHAN) != 0);
+		}
+		if (!TraceFilter[0]) {
+			if (changed & DIVA_MGT_DBG_IFC_BCHANNEL) {
+				int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
+
+				for (i = 0; i < pC->channels; i++) {
+					(*(pC->pIdiLib->DivaSTraceSetBChannel))(pC->pIdiLib, i + 1, state);
+				}
+			}
+			if (changed & DIVA_MGT_DBG_IFC_AUDIO) {
+				int i, state = ((pC->hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);
+
+				for (i = 0; i < pC->channels; i++) {
+					(*(pC->pIdiLib->DivaSTraceSetAudioTap))(pC->pIdiLib, i + 1, state);
+				}
+			}
+		}
+	}
 }
 
 
-void diva_mnt_internal_dprintf (dword drv_id, dword type, char* fmt, ...) {
-  va_list ap;
+void diva_mnt_internal_dprintf(dword drv_id, dword type, char *fmt, ...) {
+	va_list ap;
 
 	va_start(ap, fmt);
-  DI_format (0, (word)drv_id, (int)type, fmt, ap);
+	DI_format(0, (word)drv_id, (int)type, fmt, ap);
 	va_end(ap);
 }
 
 /*
   Shutdown all adapters before driver removal
-  */
-int diva_mnt_shutdown_xdi_adapters (void) {
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
-  int i, fret = 0;
-  byte * pmem;
-
-
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    pmem = NULL;
-
-    diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "unload");
-    diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "unload");
-
-    if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
-      if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) {
-        /*
-          Adapter removal complete
-          */
-        if (clients[i].pIdiLib) {
-          (*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
-          clients[i].pIdiLib = NULL;
-
-          pmem = clients[i].pmem;
-          clients[i].pmem = NULL;
-        }
-        clients[i].hDbg    = NULL;
-        clients[i].request_pending = 0;
-
-        if (clients[i].dma_handle >= 0) {
-          /*
-            Free DMA handle
-            */
-          diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle);
-          clients[i].dma_handle = -1;
+*/
+int diva_mnt_shutdown_xdi_adapters(void) {
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
+	int i, fret = 0;
+	byte *pmem;
+
+
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		pmem = NULL;
+
+		diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "unload");
+		diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "unload");
+
+		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
+			if ((*(clients[i].pIdiLib->DivaSTraceLibraryStop))(clients[i].pIdiLib) == 1) {
+				/*
+				  Adapter removal complete
+				*/
+				if (clients[i].pIdiLib) {
+					(*(clients[i].pIdiLib->DivaSTraceLibraryFinit))(clients[i].pIdiLib->hLib);
+					clients[i].pIdiLib = NULL;
+
+					pmem = clients[i].pmem;
+					clients[i].pmem = NULL;
 				}
-        clients[i].request = NULL;
-      } else {
-        fret = -1;
-      }
-    }
-
-    diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "unload");
-    if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
-      clients[i].request_pending = 0;
-      (*(clients[i].request))((ENTITY*)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
-      if (clients[i].dma_handle >= 0) {
-        diva_free_dma_descriptor (clients[i].request, clients[i].dma_handle);
-        clients[i].dma_handle = -1;
-      }
-    }
-    diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "unload");
-
-    if (pmem) {
-      diva_os_free (0, pmem);
-    }
-  }
-
-  return (fret);
+				clients[i].hDbg    = NULL;
+				clients[i].request_pending = 0;
+
+				if (clients[i].dma_handle >= 0) {
+					/*
+					  Free DMA handle
+					*/
+					diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
+					clients[i].dma_handle = -1;
+				}
+				clients[i].request = NULL;
+			} else {
+				fret = -1;
+			}
+		}
+
+		diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "unload");
+		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
+			clients[i].request_pending = 0;
+			(*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
+			if (clients[i].dma_handle >= 0) {
+				diva_free_dma_descriptor(clients[i].request, clients[i].dma_handle);
+				clients[i].dma_handle = -1;
+			}
+		}
+		diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "unload");
+
+		if (pmem) {
+			diva_os_free(0, pmem);
+		}
+	}
+
+	return (fret);
 }
 
 /*
   Set/Read the trace filter used for selective tracing.
   Affects B- and Audio Tap trace mask at run time
-  */
-int diva_set_trace_filter (int filter_length, const char* filter) {
-  diva_os_spin_lock_magic_t old_irql, old_irql1;
-  int i, ch, on, client_b_on, client_atap_on;
-
-  diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "write_filter");
-
-  if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) {
-    memcpy (&TraceFilter[0], filter, filter_length);
-    if (TraceFilter[filter_length]) {
-      TraceFilter[filter_length] = 0;
-    }
-    if (TraceFilter[0] == '*') {
-      TraceFilter[0] = 0;
-    }
-  } else {
-    filter_length = -1;
-  }
-
-  TraceFilterIdent   = -1;
-  TraceFilterChannel = -1;
-
-  on = (TraceFilter[0] == 0);
-
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
-      client_b_on    = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
-      client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO)    != 0);
-      for (ch = 0; ch < clients[i].channels; ch++) {
-        (*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch+1, client_b_on);
-        (*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch+1, client_atap_on);
-      }
-    }
-  }
-
-  for (i = 1; i < ARRAY_SIZE(clients); i++) {
-    if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
-      diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter");
-      clients[i].request_pending = 0;
-      (*(clients[i].request))((ENTITY*)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
-      diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "write_filter");
-    }
-  }
-
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter");
-  diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "dbg mask");
-
-  return (filter_length);
+*/
+int diva_set_trace_filter(int filter_length, const char *filter) {
+	diva_os_spin_lock_magic_t old_irql, old_irql1;
+	int i, ch, on, client_b_on, client_atap_on;
+
+	diva_os_enter_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
+
+	if (filter_length <= DIVA_MAX_SELECTIVE_FILTER_LENGTH) {
+		memcpy(&TraceFilter[0], filter, filter_length);
+		if (TraceFilter[filter_length]) {
+			TraceFilter[filter_length] = 0;
+		}
+		if (TraceFilter[0] == '*') {
+			TraceFilter[0] = 0;
+		}
+	} else {
+		filter_length = -1;
+	}
+
+	TraceFilterIdent   = -1;
+	TraceFilterChannel = -1;
+
+	on = (TraceFilter[0] == 0);
+
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
+			client_b_on    = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
+			client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO)    != 0);
+			for (ch = 0; ch < clients[i].channels; ch++) {
+				(*(clients[i].pIdiLib->DivaSTraceSetBChannel))(clients[i].pIdiLib->hLib, ch + 1, client_b_on);
+				(*(clients[i].pIdiLib->DivaSTraceSetAudioTap))(clients[i].pIdiLib->hLib, ch + 1, client_atap_on);
+			}
+		}
+	}
+
+	for (i = 1; i < ARRAY_SIZE(clients); i++) {
+		if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
+			diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
+			clients[i].request_pending = 0;
+			(*(clients[i].request))((ENTITY *)(*(clients[i].pIdiLib->DivaSTraceGetHandle))(clients[i].pIdiLib->hLib));
+			diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
+		}
+	}
+
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "write_filter");
+	diva_os_leave_spin_lock(&dbg_adapter_lock, &old_irql1, "dbg mask");
+
+	return (filter_length);
 }
 
-int diva_get_trace_filter (int max_length, char* filter) {
-  diva_os_spin_lock_magic_t old_irql;
-  int len;
+int diva_get_trace_filter(int max_length, char *filter) {
+	diva_os_spin_lock_magic_t old_irql;
+	int len;
 
-  diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read_filter");
-  len = strlen (&TraceFilter[0]) + 1;
-  if (max_length >= len) {
-    memcpy (filter, &TraceFilter[0], len);
-  }
-  diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "read_filter");
+	diva_os_enter_spin_lock(&dbg_q_lock, &old_irql, "read_filter");
+	len = strlen(&TraceFilter[0]) + 1;
+	if (max_length >= len) {
+		memcpy(filter, &TraceFilter[0], len);
+	}
+	diva_os_leave_spin_lock(&dbg_q_lock, &old_irql, "read_filter");
 
-  return (len);
+	return (len);
 }
 
-static int diva_dbg_cmp_key (const char* ref, const char* key) {
+static int diva_dbg_cmp_key(const char *ref, const char *key) {
 	while (*key && (*ref++ == *key++));
-  return (!*key && !*ref);
+	return (!*key && !*ref);
 }
 
 /*
@@ -2055,78 +2055,77 @@ static int diva_dbg_cmp_key (const char* ref, const char* key) {
   all following characters are interpreted as command.
   Followings commands are available:
   - single, trace single call at time, independent from CPN/CiPN
-  */
-static int diva_mnt_cmp_nmbr (const char* nmbr) {
-  const char* ref = &TraceFilter[0];
-  int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr);
-
-  if (ref[0] == 'C') {
-    if (diva_dbg_cmp_key (&ref[1], "single")) {
-      return (0);
-    }
-    return (-1);
-  }
-
-  if (!ref_len || (ref_len > nmbr_len)) {
-    return (-1);
-  }
-
-  nmbr = nmbr + nmbr_len - 1;
-  ref  = ref  + ref_len  - 1;
-
-  while (ref_len--) {
-    if (*nmbr-- != *ref--) {
-      return (-1);
-    }
-  }
-
-  return (0);
+*/
+static int diva_mnt_cmp_nmbr(const char *nmbr) {
+	const char *ref = &TraceFilter[0];
+	int ref_len = strlen(&TraceFilter[0]), nmbr_len = strlen(nmbr);
+
+	if (ref[0] == 'C') {
+		if (diva_dbg_cmp_key(&ref[1], "single")) {
+			return (0);
+		}
+		return (-1);
+	}
+
+	if (!ref_len || (ref_len > nmbr_len)) {
+		return (-1);
+	}
+
+	nmbr = nmbr + nmbr_len - 1;
+	ref  = ref  + ref_len  - 1;
+
+	while (ref_len--) {
+		if (*nmbr-- != *ref--) {
+			return (-1);
+		}
+	}
+
+	return (0);
 }
 
-static int diva_get_dma_descriptor (IDI_CALL request, dword *dma_magic) {
-  ENTITY e;
-  IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;
+static int diva_get_dma_descriptor(IDI_CALL request, dword *dma_magic) {
+	ENTITY e;
+	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
 
-  if (!request) {
-    return (-1);
-  }
+	if (!request) {
+		return (-1);
+	}
 
-  pReq->xdi_dma_descriptor_operation.Req = 0;
-  pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
+	pReq->xdi_dma_descriptor_operation.Req = 0;
+	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
 
-  pReq->xdi_dma_descriptor_operation.info.operation =     IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
+	pReq->xdi_dma_descriptor_operation.info.operation =     IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
 
-  (*request)((ENTITY*)pReq);
+	(*request)((ENTITY *)pReq);
 
-  if (!pReq->xdi_dma_descriptor_operation.info.operation &&
-      (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
-      pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
-    *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
-    return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
-  } else {
-    return (-1);
-  }
+	if (!pReq->xdi_dma_descriptor_operation.info.operation &&
+	    (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
+	    pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
+		*dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
+		return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
+	} else {
+		return (-1);
+	}
 }
 
-static void diva_free_dma_descriptor (IDI_CALL request, int nr) {
-  ENTITY e;
-  IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;
+static void diva_free_dma_descriptor(IDI_CALL request, int nr) {
+	ENTITY e;
+	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
 
-  if (!request || (nr < 0)) {
-    return;
-  }
+	if (!request || (nr < 0)) {
+		return;
+	}
 
-  pReq->xdi_dma_descriptor_operation.Req = 0;
-  pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
+	pReq->xdi_dma_descriptor_operation.Req = 0;
+	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
 
-  pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
+	pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
 
-  (*request)((ENTITY*)pReq);
+	(*request)((ENTITY *)pReq);
 }
-
diff --git a/drivers/isdn/hardware/eicon/debug_if.h b/drivers/isdn/hardware/eicon/debug_if.h
index 4db739d..fc5953a 100644
--- a/drivers/isdn/hardware/eicon/debug_if.h
+++ b/drivers/isdn/hardware/eicon/debug_if.h
@@ -1,23 +1,23 @@
 /*
  *
-  Copyright (c) Eicon Technology Corporation, 2000.
+ Copyright (c) Eicon Technology Corporation, 2000.
  *
-  This source file is supplied for the use with Eicon
-  Technology Corporation's range of DIVA Server Adapters.
+ This source file is supplied for the use with Eicon
+ Technology Corporation's range of DIVA Server Adapters.
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_DEBUG_IF_H__
@@ -31,35 +31,35 @@
 #define MSG_FRAME_MAX_SIZE 2150
 
 typedef struct _diva_dbg_entry_head {
-  dword sequence;
-  dword time_sec;
-  dword time_usec;
-  dword facility;
-  dword dli;
-  dword drv_id;
-  dword di_cpu;
-  dword data_length;
+	dword sequence;
+	dword time_sec;
+	dword time_usec;
+	dword facility;
+	dword dli;
+	dword drv_id;
+	dword di_cpu;
+	dword data_length;
 } diva_dbg_entry_head_t;
 
-int diva_maint_init (byte* base, unsigned long length, int do_init);
-void* diva_maint_finit (void);
-dword diva_dbg_q_length (void);
-diva_dbg_entry_head_t* diva_maint_get_message (word* size,
-                                               diva_os_spin_lock_magic_t* old_irql);
-void diva_maint_ack_message (int do_release,
-                             diva_os_spin_lock_magic_t* old_irql);
-void diva_maint_prtComp (char *format, ...);
-void diva_maint_wakeup_read (void);
-int diva_get_driver_info (dword id, byte* data, int data_length);
-int diva_get_driver_dbg_mask (dword id, byte* data);
-int diva_set_driver_dbg_mask (dword id, dword mask);
-void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d);
-void diva_mnt_add_xdi_adapter    (const DESCRIPTOR* d);
-int diva_mnt_shutdown_xdi_adapters (void);
+int diva_maint_init(byte *base, unsigned long length, int do_init);
+void *diva_maint_finit(void);
+dword diva_dbg_q_length(void);
+diva_dbg_entry_head_t *diva_maint_get_message(word *size,
+					      diva_os_spin_lock_magic_t *old_irql);
+void diva_maint_ack_message(int do_release,
+			    diva_os_spin_lock_magic_t *old_irql);
+void diva_maint_prtComp(char *format, ...);
+void diva_maint_wakeup_read(void);
+int diva_get_driver_info(dword id, byte *data, int data_length);
+int diva_get_driver_dbg_mask(dword id, byte *data);
+int diva_set_driver_dbg_mask(dword id, dword mask);
+void diva_mnt_remove_xdi_adapter(const DESCRIPTOR *d);
+void diva_mnt_add_xdi_adapter(const DESCRIPTOR *d);
+int diva_mnt_shutdown_xdi_adapters(void);
 
 #define DIVA_MAX_SELECTIVE_FILTER_LENGTH 127
-int diva_set_trace_filter (int filter_length, const char* filter);
-int diva_get_trace_filter (int max_length,    char*       filter);
+int diva_set_trace_filter(int filter_length, const char *filter);
+int diva_get_trace_filter(int max_length, char *filter);
 
 
 #define DITRACE_CMD_GET_DRIVER_INFO   1
@@ -72,7 +72,7 @@ int diva_get_trace_filter (int max_length,    char*       filter);
 
 /*
   Trace lavels for debug via management interface
-  */
+*/
 #define DIVA_MGT_DBG_TRACE          0x00000001 /* All trace messages from the card */
 #define DIVA_MGT_DBG_DCHAN          0x00000002 /* All D-channel relater trace messages */
 #define DIVA_MGT_DBG_MDM_PROGRESS   0x00000004 /* Modem progress events */
@@ -86,5 +86,3 @@ int diva_get_trace_filter (int max_length,    char*       filter);
 #define DIVA_MGT_DBG_IFC_AUDIO      0x00000400 /* Audio Tap trace for all channels */
 
 # endif /* DEBUG_IF___H */
-
-
diff --git a/drivers/isdn/hardware/eicon/debuglib.c b/drivers/isdn/hardware/eicon/debuglib.c
index e39c5c1..d5b1092 100644
--- a/drivers/isdn/hardware/eicon/debuglib.c
+++ b/drivers/isdn/hardware/eicon/debuglib.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 
@@ -29,35 +29,35 @@
 #ifdef DIVA_NO_DEBUGLIB
 static DIVA_DI_PRINTF dprintf;
 #else /* DIVA_NO_DEBUGLIB */
- 
+
 _DbgHandle_ myDriverDebugHandle = { 0 /*!Registered*/, DBG_HANDLE_VERSION };
 DIVA_DI_PRINTF dprintf = no_printf;
 /*****************************************************************************/
-#define DBG_FUNC(name) \
-void  \
-myDbgPrint_##name (char *format, ...) \
-{ va_list ap ; \
- if ( myDriverDebugHandle.dbg_prt ) \
- { va_start (ap, format) ; \
-  (myDriverDebugHandle.dbg_prt) \
-   (myDriverDebugHandle.id, DLI_##name, format, ap) ; \
-  va_end (ap) ; \
-} }
+#define DBG_FUNC(name)							\
+	void								\
+	myDbgPrint_##name(char *format, ...)				\
+	{ va_list ap;							\
+		if (myDriverDebugHandle.dbg_prt)			\
+		{ va_start(ap, format);				\
+			(myDriverDebugHandle.dbg_prt)			\
+				(myDriverDebugHandle.id, DLI_##name, format, ap); \
+			va_end(ap);					\
+		} }
 DBG_FUNC(LOG)
 DBG_FUNC(FTL)
 DBG_FUNC(ERR)
 DBG_FUNC(TRC)
 DBG_FUNC(MXLOG)
 DBG_FUNC(FTL_MXLOG)
-void 
-myDbgPrint_EVL (long msgID, ...)
-{ va_list ap ;
- if ( myDriverDebugHandle.dbg_ev )
- { va_start (ap, msgID) ;
-  (myDriverDebugHandle.dbg_ev)
-   (myDriverDebugHandle.id, (unsigned long)msgID, ap) ;
-  va_end (ap) ;
-} }
+void
+myDbgPrint_EVL(long msgID, ...)
+{ va_list ap;
+	if (myDriverDebugHandle.dbg_ev)
+	{ va_start(ap, msgID);
+		(myDriverDebugHandle.dbg_ev)
+			(myDriverDebugHandle.id, (unsigned long)msgID, ap);
+		va_end(ap);
+	} }
 DBG_FUNC(REG)
 DBG_FUNC(MEM)
 DBG_FUNC(SPL)
@@ -76,81 +76,81 @@ DBG_FUNC(PRV2)
 DBG_FUNC(PRV3)
 /*****************************************************************************/
 int
-DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask)
+DbgRegister(char *drvName, char *drvTag, unsigned long dbgMask)
 {
- int len;
+	int len;
 /*
  * deregister (if already registered) and zero out myDriverDebugHandle
  */
- DbgDeregister () ;
+	DbgDeregister();
 /*
  * initialize the debug handle
  */
- myDriverDebugHandle.Version = DBG_HANDLE_VERSION ;
- myDriverDebugHandle.id  = -1 ;
- myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG) ;
- len = strlen (drvName) ;
- memcpy (myDriverDebugHandle.drvName, drvName,
-         (len < sizeof(myDriverDebugHandle.drvName)) ?
-    len : sizeof(myDriverDebugHandle.drvName) - 1) ;
- len = strlen (drvTag) ;
- memcpy (myDriverDebugHandle.drvTag, drvTag,
-         (len < sizeof(myDriverDebugHandle.drvTag)) ?
-    len : sizeof(myDriverDebugHandle.drvTag) - 1) ;
+	myDriverDebugHandle.Version = DBG_HANDLE_VERSION;
+	myDriverDebugHandle.id  = -1;
+	myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG);
+	len = strlen(drvName);
+	memcpy(myDriverDebugHandle.drvName, drvName,
+	       (len < sizeof(myDriverDebugHandle.drvName)) ?
+	       len : sizeof(myDriverDebugHandle.drvName) - 1);
+	len = strlen(drvTag);
+	memcpy(myDriverDebugHandle.drvTag, drvTag,
+	       (len < sizeof(myDriverDebugHandle.drvTag)) ?
+	       len : sizeof(myDriverDebugHandle.drvTag) - 1);
 /*
  * Try to register debugging via old (and only) interface
  */
- dprintf("\000\377", &myDriverDebugHandle) ;
- if ( myDriverDebugHandle.dbg_prt )
- {
-  return (1) ;
- }
+	dprintf("\000\377", &myDriverDebugHandle);
+	if (myDriverDebugHandle.dbg_prt)
+	{
+		return (1);
+	}
 /*
  * Check if we registered with an old maint driver (see debuglib.h)
  */
- if ( myDriverDebugHandle.dbg_end != NULL
-   /* location of 'dbg_prt' in _OldDbgHandle_ struct */
-   && (myDriverDebugHandle.regTime.LowPart ||
-       myDriverDebugHandle.regTime.HighPart  ) )
-   /* same location as in _OldDbgHandle_ struct */
- {
-  dprintf("%s: Cannot log to old maint driver !", drvName) ;
-  myDriverDebugHandle.dbg_end =
-  ((_OldDbgHandle_ *)&myDriverDebugHandle)->dbg_end ;
-  DbgDeregister () ;
- }
- return (0) ;
+	if (myDriverDebugHandle.dbg_end != NULL
+	     /* location of 'dbg_prt' in _OldDbgHandle_ struct */
+	     && (myDriverDebugHandle.regTime.LowPart ||
+		 myDriverDebugHandle.regTime.HighPart))
+		/* same location as in _OldDbgHandle_ struct */
+	{
+		dprintf("%s: Cannot log to old maint driver !", drvName);
+		myDriverDebugHandle.dbg_end =
+			((_OldDbgHandle_ *)&myDriverDebugHandle)->dbg_end;
+		DbgDeregister();
+	}
+	return (0);
 }
 /*****************************************************************************/
 void
-DbgSetLevel (unsigned long dbgMask)
+DbgSetLevel(unsigned long dbgMask)
 {
- myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG) ;
+	myDriverDebugHandle.dbgMask = dbgMask | (DL_EVL | DL_FTL | DL_LOG);
 }
 /*****************************************************************************/
 void
-DbgDeregister (void)
+DbgDeregister(void)
 {
- if ( myDriverDebugHandle.dbg_end )
- {
-  (myDriverDebugHandle.dbg_end)(&myDriverDebugHandle) ;
- }
- memset (&myDriverDebugHandle, 0, sizeof(myDriverDebugHandle)) ;
+	if (myDriverDebugHandle.dbg_end)
+	{
+		(myDriverDebugHandle.dbg_end)(&myDriverDebugHandle);
+	}
+	memset(&myDriverDebugHandle, 0, sizeof(myDriverDebugHandle));
 }
-void  xdi_dbg_xlog (char* x, ...) {
- va_list ap;
- va_start (ap, x);
- if (myDriverDebugHandle.dbg_end &&
-   (myDriverDebugHandle.dbg_irq || myDriverDebugHandle.dbg_old) &&
-   (myDriverDebugHandle.dbgMask & DL_STAT)) {
-  if (myDriverDebugHandle.dbg_irq) {
-   (*(myDriverDebugHandle.dbg_irq))(myDriverDebugHandle.id,
-       (x[0] != 0) ? DLI_TRC : DLI_XLOG, x, ap);
-  } else {
-   (*(myDriverDebugHandle.dbg_old))(myDriverDebugHandle.id, x, ap);
-  }
- }
- va_end(ap);
+void xdi_dbg_xlog(char *x, ...) {
+	va_list ap;
+	va_start(ap, x);
+	if (myDriverDebugHandle.dbg_end &&
+	    (myDriverDebugHandle.dbg_irq || myDriverDebugHandle.dbg_old) &&
+	    (myDriverDebugHandle.dbgMask & DL_STAT)) {
+		if (myDriverDebugHandle.dbg_irq) {
+			(*(myDriverDebugHandle.dbg_irq))(myDriverDebugHandle.id,
+							 (x[0] != 0) ? DLI_TRC : DLI_XLOG, x, ap);
+		} else {
+			(*(myDriverDebugHandle.dbg_old))(myDriverDebugHandle.id, x, ap);
+		}
+	}
+	va_end(ap);
 }
 /*****************************************************************************/
 #endif /* DIVA_NO_DEBUGLIB */
diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h
index 02eed6b..6dcbf6a 100644
--- a/drivers/isdn/hardware/eicon/debuglib.h
+++ b/drivers/isdn/hardware/eicon/debuglib.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 #if !defined(__DEBUGLIB_H__)
@@ -103,43 +103,43 @@
 #define DL_TO_KERNEL    0x40000000
 
 #ifdef DIVA_NO_DEBUGLIB
-#define myDbgPrint_LOG(x...) do { } while(0);
-#define myDbgPrint_FTL(x...) do { } while(0);
-#define myDbgPrint_ERR(x...) do { } while(0);
-#define myDbgPrint_TRC(x...) do { } while(0);
-#define myDbgPrint_MXLOG(x...) do { } while(0);
-#define myDbgPrint_EVL(x...) do { } while(0);
-#define myDbgPrint_REG(x...) do { } while(0);
-#define myDbgPrint_MEM(x...) do { } while(0);
-#define myDbgPrint_SPL(x...) do { } while(0);
-#define myDbgPrint_IRP(x...) do { } while(0);
-#define myDbgPrint_TIM(x...) do { } while(0);
-#define myDbgPrint_BLK(x...) do { } while(0);
-#define myDbgPrint_TAPI(x...) do { } while(0);
-#define myDbgPrint_NDIS(x...) do { } while(0);
-#define myDbgPrint_CONN(x...) do { } while(0);
-#define myDbgPrint_STAT(x...) do { } while(0);
-#define myDbgPrint_SEND(x...) do { } while(0);
-#define myDbgPrint_RECV(x...) do { } while(0);
-#define myDbgPrint_PRV0(x...) do { } while(0);
-#define myDbgPrint_PRV1(x...) do { } while(0);
-#define myDbgPrint_PRV2(x...) do { } while(0);
-#define myDbgPrint_PRV3(x...) do { } while(0);
-#define DBG_TEST(func,args) do { } while(0);
-#define DBG_EVL_ID(args) do { } while(0);
+#define myDbgPrint_LOG(x...) do { } while (0);
+#define myDbgPrint_FTL(x...) do { } while (0);
+#define myDbgPrint_ERR(x...) do { } while (0);
+#define myDbgPrint_TRC(x...) do { } while (0);
+#define myDbgPrint_MXLOG(x...) do { } while (0);
+#define myDbgPrint_EVL(x...) do { } while (0);
+#define myDbgPrint_REG(x...) do { } while (0);
+#define myDbgPrint_MEM(x...) do { } while (0);
+#define myDbgPrint_SPL(x...) do { } while (0);
+#define myDbgPrint_IRP(x...) do { } while (0);
+#define myDbgPrint_TIM(x...) do { } while (0);
+#define myDbgPrint_BLK(x...) do { } while (0);
+#define myDbgPrint_TAPI(x...) do { } while (0);
+#define myDbgPrint_NDIS(x...) do { } while (0);
+#define myDbgPrint_CONN(x...) do { } while (0);
+#define myDbgPrint_STAT(x...) do { } while (0);
+#define myDbgPrint_SEND(x...) do { } while (0);
+#define myDbgPrint_RECV(x...) do { } while (0);
+#define myDbgPrint_PRV0(x...) do { } while (0);
+#define myDbgPrint_PRV1(x...) do { } while (0);
+#define myDbgPrint_PRV2(x...) do { } while (0);
+#define myDbgPrint_PRV3(x...) do { } while (0);
+#define DBG_TEST(func, args) do { } while (0);
+#define DBG_EVL_ID(args) do { } while (0);
 
 #else /* DIVA_NO_DEBUGLIB */
 /*
  * define low level macros for formatted & raw debugging
  */
-#define DBG_DECL(func) extern void  myDbgPrint_##func (char *, ...) ;
+#define DBG_DECL(func) extern void  myDbgPrint_##func(char *, ...);
 DBG_DECL(LOG)
 DBG_DECL(FTL)
 DBG_DECL(ERR)
 DBG_DECL(TRC)
 DBG_DECL(MXLOG)
 DBG_DECL(FTL_MXLOG)
-extern void  myDbgPrint_EVL (long, ...) ;
+extern void  myDbgPrint_EVL(long, ...);
 DBG_DECL(REG)
 DBG_DECL(MEM)
 DBG_DECL(SPL)
@@ -156,34 +156,34 @@ DBG_DECL(PRV0)
 DBG_DECL(PRV1)
 DBG_DECL(PRV2)
 DBG_DECL(PRV3)
-#ifdef  _KERNEL_DBG_PRINT_
+#ifdef _KERNEL_DBG_PRINT_
 /*
  * tracing to maint and kernel if selected in the trace mask.
  */
-#define DBG_TEST(func,args) \
-{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func ) \
- { \
-        if ( (myDriverDebugHandle.dbgMask) & DL_TO_KERNEL ) \
-            {DbgPrint args; DbgPrint ("\r\n");} \
-        myDbgPrint_##func args ; \
-} }
+#define DBG_TEST(func, args)						\
+	{ if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func) \
+		{							\
+			if ((myDriverDebugHandle.dbgMask) & DL_TO_KERNEL) \
+			{ DbgPrint args; DbgPrint("\r\n"); }		\
+			myDbgPrint_##func args;			\
+		} }
 #else
 /*
  * Standard tracing to maint driver.
  */
-#define DBG_TEST(func,args) \
-{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func ) \
- { myDbgPrint_##func args ; \
-} }
+#define DBG_TEST(func, args)						\
+	{ if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_##func) \
+		{ myDbgPrint_##func args;				\
+		} }
 #endif
 /*
  * For event level debug use a separate define, the parameter are
  * different and cause compiler errors on some systems.
  */
-#define DBG_EVL_ID(args) \
-{ if ( (myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL ) \
- { myDbgPrint_EVL args ; \
-} }
+#define DBG_EVL_ID(args)						\
+	{ if ((myDriverDebugHandle.dbgMask) & (unsigned long)DL_EVL)	\
+		{ myDbgPrint_EVL args;					\
+		} }
 
 #endif /* DIVA_NO_DEBUGLIB */
 
@@ -214,109 +214,109 @@ DBG_DECL(PRV3)
  * prototypes for debug register/deregister functions in "debuglib.c"
  */
 #ifdef DIVA_NO_DEBUGLIB
-#define DbgRegister(name,tag, mask) do { } while(0)
-#define DbgDeregister() do { } while(0)
-#define DbgSetLevel(mask) do { } while(0)
+#define DbgRegister(name, tag, mask) do { } while (0)
+#define DbgDeregister() do { } while (0)
+#define DbgSetLevel(mask) do { } while (0)
 #else
 extern DIVA_DI_PRINTF dprintf;
-extern int  DbgRegister (char *drvName, char *drvTag, unsigned long dbgMask) ;
-extern void DbgDeregister (void) ;
-extern void DbgSetLevel (unsigned long dbgMask) ;
+extern int  DbgRegister(char *drvName, char *drvTag, unsigned long dbgMask);
+extern void DbgDeregister(void);
+extern void DbgSetLevel(unsigned long dbgMask);
 #endif
 /*
  * driver internal structure for debug handling;
  * in client drivers this structure is maintained in "debuglib.c",
  * in the debug driver "debug.c" maintains a chain of such structs.
  */
-typedef struct _DbgHandle_ *pDbgHandle ;
-typedef void ( * DbgEnd) (pDbgHandle) ;
-typedef void ( * DbgLog) (unsigned short, int, char *, va_list) ;
-typedef void ( * DbgOld) (unsigned short, char *, va_list) ;
-typedef void ( * DbgEv)  (unsigned short, unsigned long, va_list) ;
-typedef void ( * DbgIrq) (unsigned short, int, char *, va_list) ;
+typedef struct _DbgHandle_ *pDbgHandle;
+typedef void (*DbgEnd)(pDbgHandle);
+typedef void (*DbgLog)(unsigned short, int, char *, va_list);
+typedef void (*DbgOld)(unsigned short, char *, va_list);
+typedef void (*DbgEv)(unsigned short, unsigned long, va_list);
+typedef void (*DbgIrq)(unsigned short, int, char *, va_list);
 typedef struct _DbgHandle_
-{ char    Registered ; /* driver successfully registered */
+{ char    Registered; /* driver successfully registered */
 #define DBG_HANDLE_REG_NEW 0x01  /* this (new) structure    */
 #define DBG_HANDLE_REG_OLD 0x7f  /* old structure (see below)  */
- char    Version;  /* version of this structure  */
+	char    Version;  /* version of this structure  */
 #define DBG_HANDLE_VERSION 1   /* contains dbg_old function now */
 #define DBG_HANDLE_VER_EXT  2           /* pReserved points to extended info*/
- short               id ;   /* internal id of registered driver */
-  struct _DbgHandle_ *next ;   /* ptr to next registered driver    */
- struct /*LARGE_INTEGER*/ {
-  unsigned long LowPart;
-  long          HighPart;
- }     regTime ;  /* timestamp for registration       */
- void               *pIrp ;   /* ptr to pending i/o request       */
- unsigned long       dbgMask ;  /* current debug mask               */
- char                drvName[128] ; /* ASCII name of registered driver  */
- char                drvTag[64] ; /* revision string     */
- DbgEnd              dbg_end ;  /* function for debug closing       */
- DbgLog              dbg_prt ;  /* function for debug appending     */
- DbgOld              dbg_old ;  /* function for old debug appending */
- DbgEv       dbg_ev ;  /* function for Windows NT Eventlog */
- DbgIrq    dbg_irq ;  /* function for irql checked debug  */
- void      *pReserved3 ;
-} _DbgHandle_ ;
-extern _DbgHandle_ myDriverDebugHandle ;
+	short               id;   /* internal id of registered driver */
+	struct _DbgHandle_ *next;   /* ptr to next registered driver    */
+	struct /*LARGE_INTEGER*/ {
+		unsigned long LowPart;
+		long          HighPart;
+	}     regTime;  /* timestamp for registration       */
+	void               *pIrp;   /* ptr to pending i/o request       */
+	unsigned long       dbgMask;  /* current debug mask               */
+	char                drvName[128]; /* ASCII name of registered driver  */
+	char                drvTag[64]; /* revision string     */
+	DbgEnd              dbg_end;  /* function for debug closing       */
+	DbgLog              dbg_prt;  /* function for debug appending     */
+	DbgOld              dbg_old;  /* function for old debug appending */
+	DbgEv       dbg_ev;  /* function for Windows NT Eventlog */
+	DbgIrq    dbg_irq;  /* function for irql checked debug  */
+	void      *pReserved3;
+} _DbgHandle_;
+extern _DbgHandle_ myDriverDebugHandle;
 typedef struct _OldDbgHandle_
-{ struct _OldDbgHandle_ *next ;
- void                *pIrp ;
- long    regTime[2] ;
- unsigned long       dbgMask ;
- short               id ;
- char                drvName[78] ;
- DbgEnd              dbg_end ;
- DbgLog              dbg_prt ;
-} _OldDbgHandle_ ;
+{ struct _OldDbgHandle_ *next;
+	void                *pIrp;
+	long    regTime[2];
+	unsigned long       dbgMask;
+	short               id;
+	char                drvName[78];
+	DbgEnd              dbg_end;
+	DbgLog              dbg_prt;
+} _OldDbgHandle_;
 /* the differences in DbgHandles
    old:    tmp:     new:
- 0 long next  char Registered  char Registered
-       char filler   char Version
-       short id    short id
- 4 long pIrp  long    regTime.lo  long next
- 8 long    regTime.lo long    regTime.hi  long    regTime.lo
- 12 long    regTime.hi long next   long regTime.hi
- 16 long dbgMask  long pIrp   long pIrp
- 20 short id   long dbgMask   long dbgMask
- 22 char    drvName[78] ..
- 24 ..     char drvName[16]  char drvName[16]
- 40 ..     char drvTag[64]  char drvTag[64]
- 100 void *dbg_end ..      ..
- 104 void *dbg_prt void *dbg_end  void *dbg_end
- 108 ..     void *dbg_prt  void *dbg_prt
- 112 ..     ..      void *dbg_old
- 116 ..     ..      void *dbg_ev
- 120 ..     ..      void *dbg_irq
- 124 ..     ..      void *pReserved3
- ( new->id == 0 && *((short *)&new->dbgMask) == -1 ) identifies "old",
- new->Registered and new->Version overlay old->next,
- new->next overlays old->pIrp, new->regTime matches old->regTime and
- thus these fields can be maintained in new struct whithout trouble;
- id, dbgMask, drvName, dbg_end and dbg_prt need special handling !
+   0 long next  char Registered  char Registered
+   char filler   char Version
+   short id    short id
+   4 long pIrp  long    regTime.lo  long next
+   8 long    regTime.lo long    regTime.hi  long    regTime.lo
+   12 long    regTime.hi long next   long regTime.hi
+   16 long dbgMask  long pIrp   long pIrp
+   20 short id   long dbgMask   long dbgMask
+   22 char    drvName[78] ..
+   24 ..     char drvName[16]  char drvName[16]
+   40 ..     char drvTag[64]  char drvTag[64]
+   100 void *dbg_end ..      ..
+   104 void *dbg_prt void *dbg_end  void *dbg_end
+   108 ..     void *dbg_prt  void *dbg_prt
+   112 ..     ..      void *dbg_old
+   116 ..     ..      void *dbg_ev
+   120 ..     ..      void *dbg_irq
+   124 ..     ..      void *pReserved3
+   ( new->id == 0 && *((short *)&new->dbgMask) == -1 ) identifies "old",
+   new->Registered and new->Version overlay old->next,
+   new->next overlays old->pIrp, new->regTime matches old->regTime and
+   thus these fields can be maintained in new struct whithout trouble;
+   id, dbgMask, drvName, dbg_end and dbg_prt need special handling !
 */
 #define DBG_EXT_TYPE_CARD_TRACE     0x00000001
 typedef struct
 {
-    unsigned long       ExtendedType;
-    union
-    {
-        /* DBG_EXT_TYPE_CARD_TRACE */
-        struct
-        {
-            void ( * MaskChangedNotify) (void *pContext);
-            unsigned long   ModuleTxtMask;
-            unsigned long   DebugLevel;
-            unsigned long   B_ChannelMask;
-            unsigned long   LogBufferSize;
-        } CardTrace;
-    }Data;     
+	unsigned long ExtendedType;
+	union
+	{
+		/* DBG_EXT_TYPE_CARD_TRACE */
+		struct
+		{
+			void (*MaskChangedNotify)(void *pContext);
+			unsigned long ModuleTxtMask;
+			unsigned long DebugLevel;
+			unsigned long B_ChannelMask;
+			unsigned long LogBufferSize;
+		} CardTrace;
+	} Data;
 } _DbgExtendedInfo_;
 #ifndef DIVA_NO_DEBUGLIB
 /* -------------------------------------------------------------
-    Function used for xlog-style debug
+   Function used for xlog-style debug
    ------------------------------------------------------------- */
 #define XDI_USE_XLOG 1
-void  xdi_dbg_xlog (char* x, ...);
+void xdi_dbg_xlog(char *x, ...);
 #endif /* DIVA_NO_DEBUGLIB */
 #endif /* __DEBUGLIB_H__ */
diff --git a/drivers/isdn/hardware/eicon/dfifo.h b/drivers/isdn/hardware/eicon/dfifo.h
index 9a109c7..6a1d333 100644
--- a/drivers/isdn/hardware/eicon/dfifo.h
+++ b/drivers/isdn/hardware/eicon/dfifo.h
@@ -1,54 +1,54 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_IDI_DFIFO_INC__
 #define __DIVA_IDI_DFIFO_INC__
 #define DIVA_DFIFO_CACHE_SZ   64 /* Used to isolate pipe from
-                    rest of the world
-                   should be divisible by 4
-                   */
-#define DIVA_DFIFO_RAW_SZ    (2512*8)
+				    rest of the world
+				    should be divisible by 4
+				 */
+#define DIVA_DFIFO_RAW_SZ    (2512 * 8)
 #define DIVA_DFIFO_DATA_SZ   68
 #define DIVA_DFIFO_HDR_SZ    4
-#define DIVA_DFIFO_SEGMENT_SZ  (DIVA_DFIFO_DATA_SZ+DIVA_DFIFO_HDR_SZ)
-#define DIVA_DFIFO_SEGMENTS   ((DIVA_DFIFO_RAW_SZ)/(DIVA_DFIFO_SEGMENT_SZ)+1)
-#define DIVA_DFIFO_MEM_SZ (\
-        (DIVA_DFIFO_SEGMENT_SZ)*(DIVA_DFIFO_SEGMENTS)+\
-        (DIVA_DFIFO_CACHE_SZ)*2\
-             )
+#define DIVA_DFIFO_SEGMENT_SZ  (DIVA_DFIFO_DATA_SZ + DIVA_DFIFO_HDR_SZ)
+#define DIVA_DFIFO_SEGMENTS   ((DIVA_DFIFO_RAW_SZ) / (DIVA_DFIFO_SEGMENT_SZ) + 1)
+#define DIVA_DFIFO_MEM_SZ (						\
+		(DIVA_DFIFO_SEGMENT_SZ) * (DIVA_DFIFO_SEGMENTS) +	\
+		(DIVA_DFIFO_CACHE_SZ) * 2				\
+		)
 #define DIVA_DFIFO_STEP DIVA_DFIFO_SEGMENT_SZ
 /* -------------------------------------------------------------------------
-  Block header layout is:
+   Block header layout is:
    byte[0] -> flags
    byte[1] -> length of data in block
    byte[2] -> reserved
    byte[4] -> reserved
-  ------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------- */
 #define DIVA_DFIFO_WRAP   0x80 /* This is the last block in fifo   */
 #define DIVA_DFIFO_READY  0x40 /* This block is ready for processing */
 #define DIVA_DFIFO_LAST   0x20 /* This block is last in message      */
 #define DIVA_DFIFO_AUTO   0x10 /* Don't look for 'ready', don't ack */
-int diva_dfifo_create (void* start, int length);
+int diva_dfifo_create(void *start, int length);
 #endif
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
index cb14ae3..cd3fba1 100644
--- a/drivers/isdn/hardware/eicon/di.c
+++ b/drivers/isdn/hardware/eicon/di.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -29,9 +29,9 @@
 #include "di_defs.h"
 #include "di.h"
 #if !defined USE_EXTENDED_DEBUGS
-  #include "dimaint.h"
+#include "dimaint.h"
 #else
-  #define dprintf
+#define dprintf
 #endif
 #include "io.h"
 #include "dfifo.h"
@@ -40,315 +40,315 @@
 /*------------------------------------------------------------------*/
 /* local function prototypes                                        */
 /*------------------------------------------------------------------*/
-void pr_out(ADAPTER * a);
-byte pr_dpc(ADAPTER * a);
-static byte pr_ready(ADAPTER * a);
+void pr_out(ADAPTER *a);
+byte pr_dpc(ADAPTER *a);
+static byte pr_ready(ADAPTER *a);
 static byte isdn_rc(ADAPTER *, byte, byte, byte, word, dword, dword);
 static byte isdn_ind(ADAPTER *, byte, byte, byte, PBUFFER *, byte, word);
 /* -----------------------------------------------------------------
-    Functions used for the extended XDI Debug
-    macros
-    global convergence counter (used by all adapters)
-    Look by the implementation part of the functions
-    about the parameters.
-    If you change the dubugging parameters, then you should update
-    the aididbg.doc in the IDI doc's.
+   Functions used for the extended XDI Debug
+   macros
+   global convergence counter (used by all adapters)
+   Look by the implementation part of the functions
+   about the parameters.
+   If you change the dubugging parameters, then you should update
+   the aididbg.doc in the IDI doc's.
    ----------------------------------------------------------------- */
 #if defined(XDI_USE_XLOG)
 #define XDI_A_NR(_x_) ((byte)(((ISDN_ADAPTER *)(_x_->io))->ANum))
-static void xdi_xlog (byte *msg, word code, int length);
+static void xdi_xlog(byte *msg, word code, int length);
 static byte xdi_xlog_sec = 0;
 #else
 #define XDI_A_NR(_x_) ((byte)0)
 #endif
-static void xdi_xlog_rc_event (byte Adapter,
-                               byte Id, byte Ch, byte Rc, byte cb, byte type);
-static void xdi_xlog_request (byte Adapter, byte Id,
-                              byte Ch, byte Req, byte type);
-static void xdi_xlog_ind (byte Adapter,
-                          byte Id,
-                          byte Ch,
-                          byte Ind,
-                          byte rnr_valid,
-                          byte rnr,
-                          byte type);
+static void xdi_xlog_rc_event(byte Adapter,
+			      byte Id, byte Ch, byte Rc, byte cb, byte type);
+static void xdi_xlog_request(byte Adapter, byte Id,
+			     byte Ch, byte Req, byte type);
+static void xdi_xlog_ind(byte Adapter,
+			 byte Id,
+			 byte Ch,
+			 byte Ind,
+			 byte rnr_valid,
+			 byte rnr,
+			 byte type);
 /*------------------------------------------------------------------*/
 /* output function                                                  */
 /*------------------------------------------------------------------*/
-void pr_out(ADAPTER * a)
+void pr_out(ADAPTER *a)
 {
-  byte e_no;
-  ENTITY  * this = NULL;
-  BUFFERS  *X;
-  word length;
-  word i;
-  word clength;
-  REQ * ReqOut;
-  byte more;
-  byte ReadyCount;
-  byte ReqCount;
-  byte Id;
-  dtrc(dprintf("pr_out"));
-        /* while a request is pending ...                           */
-  e_no = look_req(a);
-  if(!e_no)
-  {
-    dtrc(dprintf("no_req"));
-    return;
-  }
-  ReadyCount = pr_ready(a);
-  if(!ReadyCount)
-  {
-    dtrc(dprintf("not_ready"));
-    return;
-  }
-  ReqCount = 0;
-  while(e_no && ReadyCount) {
-    next_req(a);
-    this = entity_ptr(a, e_no);
+	byte e_no;
+	ENTITY *this = NULL;
+	BUFFERS *X;
+	word length;
+	word i;
+	word clength;
+	REQ *ReqOut;
+	byte more;
+	byte ReadyCount;
+	byte ReqCount;
+	byte Id;
+	dtrc(dprintf("pr_out"));
+	/* while a request is pending ...                           */
+	e_no = look_req(a);
+	if (!e_no)
+	{
+		dtrc(dprintf("no_req"));
+		return;
+	}
+	ReadyCount = pr_ready(a);
+	if (!ReadyCount)
+	{
+		dtrc(dprintf("not_ready"));
+		return;
+	}
+	ReqCount = 0;
+	while (e_no && ReadyCount) {
+		next_req(a);
+		this = entity_ptr(a, e_no);
 #ifdef USE_EXTENDED_DEBUGS
-    if ( !this )
-    {
-      DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
-               xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
-      e_no = look_req(a) ;
-      ReadyCount-- ;
-      continue ;
-    }
-    {
-      DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
-    }
+		if (!this)
+		{
+			DBG_FTL(("XDI: [%02x] !A%d ==> NULL entity ptr - try to ignore",
+				 xdi_xlog_sec++, (int)((ISDN_ADAPTER *)a->io)->ANum))
+				e_no = look_req(a);
+			ReadyCount--;
+			continue;
+		}
+		{
+			DBG_TRC((">A%d Id=0x%x Req=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, this->Id, this->Req))
+				}
 #else
-    dbug(dprintf("out:Req=%x,Id=%x,Ch=%x",this->Req,this->Id,this->ReqCh));
+		dbug(dprintf("out:Req=%x,Id=%x,Ch=%x", this->Req, this->Id, this->ReqCh));
 #endif
-        /* get address of next available request buffer             */
-    ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)];
+		/* get address of next available request buffer             */
+		ReqOut = (REQ *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextReq)];
 #if defined(DIVA_ISTREAM)
-    if (!(a->tx_stream[this->Id]   &&
-        this->Req == N_DATA)) {
+		if (!(a->tx_stream[this->Id]   &&
+		      this->Req == N_DATA)) {
 #endif
-        /* now copy the data from the current data buffer into the  */
-        /* adapters request buffer                                  */
-    length = 0;
-    i = this->XCurrent;
-    X = PTR_X(a,this);
-    while(i<this->XNum && length<270) {
-      clength = min((word)(270-length),(word)(X[i].PLength-this->XOffset));
-      a->ram_out_buffer(a,
-                        &ReqOut->XBuffer.P[length],
-                        PTR_P(a,this,&X[i].P[this->XOffset]),
-                        clength);
-      length +=clength;
-      this->XOffset +=clength;
-      if(this->XOffset==X[i].PLength) {
-        this->XCurrent = (byte)++i;
-        this->XOffset = 0;
-      }
-    }
+			/* now copy the data from the current data buffer into the  */
+			/* adapters request buffer                                  */
+			length = 0;
+			i = this->XCurrent;
+			X = PTR_X(a, this);
+			while (i < this->XNum && length < 270) {
+				clength = min((word)(270 - length), (word)(X[i].PLength-this->XOffset));
+				a->ram_out_buffer(a,
+						  &ReqOut->XBuffer.P[length],
+						  PTR_P(a, this, &X[i].P[this->XOffset]),
+						  clength);
+				length += clength;
+				this->XOffset += clength;
+				if (this->XOffset == X[i].PLength) {
+					this->XCurrent = (byte)++i;
+					this->XOffset = 0;
+				}
+			}
 #if defined(DIVA_ISTREAM)
-   } else { /* Use CMA extension in order to transfer data to the card */
-      i = this->XCurrent;
-      X = PTR_X(a,this);
-      while (i < this->XNum) {
-        diva_istream_write (a,
-                            this->Id,
-                            PTR_P(a,this,&X[i].P[0]),
-                            X[i].PLength,
-                            ((i+1) == this->XNum),
-                            0, 0);
-        this->XCurrent = (byte)++i;
-      }
-      length = 0;
-   }
+		} else { /* Use CMA extension in order to transfer data to the card */
+			i = this->XCurrent;
+			X = PTR_X(a, this);
+			while (i < this->XNum) {
+				diva_istream_write(a,
+						   this->Id,
+						   PTR_P(a, this, &X[i].P[0]),
+						   X[i].PLength,
+						   ((i + 1) == this->XNum),
+						   0, 0);
+				this->XCurrent = (byte)++i;
+			}
+			length = 0;
+		}
 #endif
-    a->ram_outw(a, &ReqOut->XBuffer.length, length);
-    a->ram_out(a, &ReqOut->ReqId, this->Id);
-    a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
-        /* if it's a specific request (no ASSIGN) ...                */
-    if(this->Id &0x1f) {
-        /* if buffers are left in the list of data buffers do       */
-        /* do chaining (LL_MDATA, N_MDATA)                          */
-      this->More++;
-      if(i<this->XNum && this->MInd) {
-        xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->MInd,
-                          a->IdTypeTable[this->No]);
-        a->ram_out(a, &ReqOut->Req, this->MInd);
-        more = true;
-      }
-      else {
-        xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->Req,
-                          a->IdTypeTable[this->No]);
-        this->More |=XMOREF;
-        a->ram_out(a, &ReqOut->Req, this->Req);
-        more = false;
-        if (a->FlowControlIdTable[this->ReqCh] == this->Id)
-          a->FlowControlSkipTable[this->ReqCh] = true;
-        /*
-           Note that remove request was sent to the card
-           */
-        if (this->Req == REMOVE) {
-          a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING;
-        }
-      }
-        /* if we did chaining, this entity is put back into the     */
-        /* request queue                                            */
-      if(more) {
-        req_queue(a,this->No);
-      }
-    }
-        /* else it's a ASSIGN                                       */
-    else {
-        /* save the request code used for buffer chaining           */
-      this->MInd = 0;
-      if (this->Id==BLLC_ID) this->MInd = LL_MDATA;
-      if (this->Id==NL_ID   ||
-          this->Id==TASK_ID ||
-          this->Id==MAN_ID
-        ) this->MInd = N_MDATA;
-        /* send the ASSIGN                                          */
-      a->IdTypeTable[this->No] = this->Id;
-      xdi_xlog_request (XDI_A_NR(a),this->Id,this->ReqCh,this->Req, this->Id);
-      this->More |=XMOREF;
-      a->ram_out(a, &ReqOut->Req, this->Req);
-        /* save the reference of the ASSIGN                         */
-      assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference));
-    }
-    a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next));
-    ReadyCount--;
-    ReqCount++;
-    e_no = look_req(a);
-  }
-        /* send the filled request buffers to the ISDN adapter      */
-  a->ram_out(a, &PR_RAM->ReqInput,
-             (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount));
-        /* if it is a 'unreturncoded' UREMOVE request, remove the  */
-        /* Id from our table after sending the request             */
-  if(this && (this->Req==UREMOVE) && this->Id) {
-    Id = this->Id;
-    e_no = a->IdTable[Id];
-    free_entity(a, e_no);
-    for (i = 0; i < 256; i++)
-    {
-      if (a->FlowControlIdTable[i] == Id)
-        a->FlowControlIdTable[i] = 0;
-    }
-    a->IdTable[Id] = 0;
-    this->Id = 0;
-  }
+		a->ram_outw(a, &ReqOut->XBuffer.length, length);
+		a->ram_out(a, &ReqOut->ReqId, this->Id);
+		a->ram_out(a, &ReqOut->ReqCh, this->ReqCh);
+		/* if it's a specific request (no ASSIGN) ...                */
+		if (this->Id & 0x1f) {
+			/* if buffers are left in the list of data buffers do       */
+			/* do chaining (LL_MDATA, N_MDATA)                          */
+			this->More++;
+			if (i < this->XNum && this->MInd) {
+				xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->MInd,
+						 a->IdTypeTable[this->No]);
+				a->ram_out(a, &ReqOut->Req, this->MInd);
+				more = true;
+			}
+			else {
+				xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req,
+						 a->IdTypeTable[this->No]);
+				this->More |= XMOREF;
+				a->ram_out(a, &ReqOut->Req, this->Req);
+				more = false;
+				if (a->FlowControlIdTable[this->ReqCh] == this->Id)
+					a->FlowControlSkipTable[this->ReqCh] = true;
+				/*
+				  Note that remove request was sent to the card
+				*/
+				if (this->Req == REMOVE) {
+					a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_REMOVE_PENDING;
+				}
+			}
+			/* if we did chaining, this entity is put back into the     */
+			/* request queue                                            */
+			if (more) {
+				req_queue(a, this->No);
+			}
+		}
+		/* else it's a ASSIGN                                       */
+		else {
+			/* save the request code used for buffer chaining           */
+			this->MInd = 0;
+			if (this->Id == BLLC_ID) this->MInd = LL_MDATA;
+			if (this->Id == NL_ID ||
+			    this->Id == TASK_ID ||
+			    this->Id == MAN_ID
+				) this->MInd = N_MDATA;
+			/* send the ASSIGN                                          */
+			a->IdTypeTable[this->No] = this->Id;
+			xdi_xlog_request(XDI_A_NR(a), this->Id, this->ReqCh, this->Req, this->Id);
+			this->More |= XMOREF;
+			a->ram_out(a, &ReqOut->Req, this->Req);
+			/* save the reference of the ASSIGN                         */
+			assign_queue(a, this->No, a->ram_inw(a, &ReqOut->Reference));
+		}
+		a->ram_outw(a, &PR_RAM->NextReq, a->ram_inw(a, &ReqOut->next));
+		ReadyCount--;
+		ReqCount++;
+		e_no = look_req(a);
+	}
+	/* send the filled request buffers to the ISDN adapter      */
+	a->ram_out(a, &PR_RAM->ReqInput,
+		   (byte)(a->ram_in(a, &PR_RAM->ReqInput) + ReqCount));
+	/* if it is a 'unreturncoded' UREMOVE request, remove the  */
+	/* Id from our table after sending the request             */
+	if (this && (this->Req == UREMOVE) && this->Id) {
+		Id = this->Id;
+		e_no = a->IdTable[Id];
+		free_entity(a, e_no);
+		for (i = 0; i < 256; i++)
+		{
+			if (a->FlowControlIdTable[i] == Id)
+				a->FlowControlIdTable[i] = 0;
+		}
+		a->IdTable[Id] = 0;
+		this->Id = 0;
+	}
 }
-static byte pr_ready(ADAPTER * a)
+static byte pr_ready(ADAPTER *a)
 {
-  byte ReadyCount;
-  ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
-                      a->ram_in(a, &PR_RAM->ReqInput));
-  if(!ReadyCount) {
-    if(!a->ReadyInt) {
-      a->ram_inc(a, &PR_RAM->ReadyInt);
-      a->ReadyInt++;
-    }
-  }
-  return ReadyCount;
+	byte ReadyCount;
+	ReadyCount = (byte)(a->ram_in(a, &PR_RAM->ReqOutput) -
+			    a->ram_in(a, &PR_RAM->ReqInput));
+	if (!ReadyCount) {
+		if (!a->ReadyInt) {
+			a->ram_inc(a, &PR_RAM->ReadyInt);
+			a->ReadyInt++;
+		}
+	}
+	return ReadyCount;
 }
 /*------------------------------------------------------------------*/
 /* isdn interrupt handler                                           */
 /*------------------------------------------------------------------*/
-byte pr_dpc(ADAPTER * a)
+byte pr_dpc(ADAPTER *a)
 {
-  byte Count;
-  RC * RcIn;
-  IND * IndIn;
-  byte c;
-  byte RNRId;
-  byte Rc;
-  byte Ind;
-        /* if return codes are available ...                        */
-  if((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) {
-    dtrc(dprintf("#Rc=%x",Count));
-        /* get the buffer address of the first return code          */
-    RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];
-        /* for all return codes do ...                              */
-    while(Count--) {
-      if((Rc=a->ram_in(a, &RcIn->Rc)) != 0) {
-        dword tmp[2];
-        /*
-          Get extended information, associated with return code
-          */
-        a->ram_in_buffer(a,
-                         &RcIn->Reserved2[0],
-                         (byte*)&tmp[0],
-                         8);
-        /* call return code handler, if it is not our return code   */
-        /* the handler returns 2                                    */
-        /* for all return codes we process, we clear the Rc field   */
-        isdn_rc(a,
-                Rc,
-                a->ram_in(a, &RcIn->RcId),
-                a->ram_in(a, &RcIn->RcCh),
-                a->ram_inw(a, &RcIn->Reference),
-                tmp[0],  /* type of extended information */
-                tmp[1]); /* extended information        */
-        a->ram_out(a, &RcIn->Rc, 0);
-      }
-        /* get buffer address of next return code                   */
-      RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
-    }
-        /* clear all return codes (no chaining!)                    */
-    a->ram_out(a, &PR_RAM->RcOutput ,0);
-        /* call output function                                     */
-    pr_out(a);
-  }
-        /* clear RNR flag                                           */
-  RNRId = 0;
-        /* if indications are available ...                         */
-  if((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) {
-    dtrc(dprintf("#Ind=%x",Count));
-        /* get the buffer address of the first indication           */
-    IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];
-        /* for all indications do ...                               */
-    while(Count--) {
-        /* if the application marks an indication as RNR, all       */
-        /* indications from the same Id delivered in this interrupt */
-        /* are marked RNR                                           */
-      if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) {
-        a->ram_out(a, &IndIn->Ind, 0);
-        a->ram_out(a, &IndIn->RNR, true);
-      }
-      else {
-        Ind = a->ram_in(a, &IndIn->Ind);
-        if(Ind) {
-          RNRId = 0;
-        /* call indication handler, a return value of 2 means chain */
-        /* a return value of 1 means RNR                            */
-        /* for all indications we process, we clear the Ind field   */
-          c = isdn_ind(a,
-                       Ind,
-                       a->ram_in(a, &IndIn->IndId),
-                       a->ram_in(a, &IndIn->IndCh),
-                       &IndIn->RBuffer,
-                       a->ram_in(a, &IndIn->MInd),
-                       a->ram_inw(a, &IndIn->MLength));
-          if(c==1) {
-            dtrc(dprintf("RNR"));
-            a->ram_out(a, &IndIn->Ind, 0);
-            RNRId = a->ram_in(a, &IndIn->IndId);
-            a->ram_out(a, &IndIn->RNR, true);
-          }
-        }
-      }
-        /* get buffer address of next indication                    */
-      IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
-    }
-    a->ram_out(a, &PR_RAM->IndOutput, 0);
-  }
-  return false;
+	byte Count;
+	RC *RcIn;
+	IND *IndIn;
+	byte c;
+	byte RNRId;
+	byte Rc;
+	byte Ind;
+	/* if return codes are available ...                        */
+	if ((Count = a->ram_in(a, &PR_RAM->RcOutput)) != 0) {
+		dtrc(dprintf("#Rc=%x", Count));
+		/* get the buffer address of the first return code          */
+		RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextRc)];
+		/* for all return codes do ...                              */
+		while (Count--) {
+			if ((Rc = a->ram_in(a, &RcIn->Rc)) != 0) {
+				dword tmp[2];
+				/*
+				  Get extended information, associated with return code
+				*/
+				a->ram_in_buffer(a,
+						 &RcIn->Reserved2[0],
+						 (byte *)&tmp[0],
+						 8);
+				/* call return code handler, if it is not our return code   */
+				/* the handler returns 2                                    */
+				/* for all return codes we process, we clear the Rc field   */
+				isdn_rc(a,
+					Rc,
+					a->ram_in(a, &RcIn->RcId),
+					a->ram_in(a, &RcIn->RcCh),
+					a->ram_inw(a, &RcIn->Reference),
+					tmp[0],  /* type of extended information */
+					tmp[1]); /* extended information        */
+				a->ram_out(a, &RcIn->Rc, 0);
+			}
+			/* get buffer address of next return code                   */
+			RcIn = (RC *)&PR_RAM->B[a->ram_inw(a, &RcIn->next)];
+		}
+		/* clear all return codes (no chaining!)                    */
+		a->ram_out(a, &PR_RAM->RcOutput, 0);
+		/* call output function                                     */
+		pr_out(a);
+	}
+	/* clear RNR flag                                           */
+	RNRId = 0;
+	/* if indications are available ...                         */
+	if ((Count = a->ram_in(a, &PR_RAM->IndOutput)) != 0) {
+		dtrc(dprintf("#Ind=%x", Count));
+		/* get the buffer address of the first indication           */
+		IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &PR_RAM->NextInd)];
+		/* for all indications do ...                               */
+		while (Count--) {
+			/* if the application marks an indication as RNR, all       */
+			/* indications from the same Id delivered in this interrupt */
+			/* are marked RNR                                           */
+			if (RNRId && RNRId == a->ram_in(a, &IndIn->IndId)) {
+				a->ram_out(a, &IndIn->Ind, 0);
+				a->ram_out(a, &IndIn->RNR, true);
+			}
+			else {
+				Ind = a->ram_in(a, &IndIn->Ind);
+				if (Ind) {
+					RNRId = 0;
+					/* call indication handler, a return value of 2 means chain */
+					/* a return value of 1 means RNR                            */
+					/* for all indications we process, we clear the Ind field   */
+					c = isdn_ind(a,
+						     Ind,
+						     a->ram_in(a, &IndIn->IndId),
+						     a->ram_in(a, &IndIn->IndCh),
+						     &IndIn->RBuffer,
+						     a->ram_in(a, &IndIn->MInd),
+						     a->ram_inw(a, &IndIn->MLength));
+					if (c == 1) {
+						dtrc(dprintf("RNR"));
+						a->ram_out(a, &IndIn->Ind, 0);
+						RNRId = a->ram_in(a, &IndIn->IndId);
+						a->ram_out(a, &IndIn->RNR, true);
+					}
+				}
+			}
+			/* get buffer address of next indication                    */
+			IndIn = (IND *)&PR_RAM->B[a->ram_inw(a, &IndIn->next)];
+		}
+		a->ram_out(a, &PR_RAM->IndOutput, 0);
+	}
+	return false;
 }
-byte scom_test_int(ADAPTER * a)
+byte scom_test_int(ADAPTER *a)
 {
-  return a->ram_in(a,(void *)0x3fe);
+	return a->ram_in(a, (void *)0x3fe);
 }
-void scom_clear_int(ADAPTER * a)
+void scom_clear_int(ADAPTER *a)
 {
-  a->ram_out(a,(void *)0x3fe,0);
+	a->ram_out(a, (void *)0x3fe, 0);
 }
 /*------------------------------------------------------------------*/
 /* return code handler                                              */
@@ -361,196 +361,196 @@ static byte isdn_rc(ADAPTER *a,
 		    dword extended_info_type,
 		    dword extended_info)
 {
-  ENTITY  * this;
-  byte e_no;
-  word i;
-  int cancel_rc;
+	ENTITY *this;
+	byte e_no;
+	word i;
+	int cancel_rc;
 #ifdef USE_EXTENDED_DEBUGS
-  {
-    DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
-  }
+	{
+		DBG_TRC(("<A%d Id=0x%x Rc=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Rc))
+			}
 #else
-  dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)",Rc,Id,Ch));
+	dbug(dprintf("isdn_rc(Rc=%x,Id=%x,Ch=%x)", Rc, Id, Ch));
 #endif
-        /* check for ready interrupt                                */
-  if(Rc==READY_INT) {
-    xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, 0);
-    if(a->ReadyInt) {
-      a->ReadyInt--;
-      return 0;
-    }
-    return 2;
-  }
-        /* if we know this Id ...                                   */
-  e_no = a->IdTable[Id];
-  if(e_no) {
-    this = entity_ptr(a,e_no);
-    xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]);
-    this->RcCh = Ch;
-        /* if it is a return code to a REMOVE request, remove the   */
-        /* Id from our table                                        */
-    if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) &&
-        (Rc==OK)) {
-      if (a->IdTypeTable[e_no] == NL_ID) {
-        if (a->RcExtensionSupported &&
-            (extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) {
-        dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK",
-                        XDI_A_NR(a),Id));
-          return (0);
-        }
-        if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE)
-          a->RcExtensionSupported = true;
-      }
-      a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING;
-      a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING;
-      free_entity(a, e_no);
-      for (i = 0; i < 256; i++)
-      {
-        if (a->FlowControlIdTable[i] == Id)
-          a->FlowControlIdTable[i] = 0;
-      }
-      a->IdTable[Id] = 0;
-      this->Id = 0;
-      /* ---------------------------------------------------------------
-        If we send N_DISC or N_DISK_ACK after we have received OK_FC
-        then the card will respond with OK_FC and later with RC==OK.
-        If we send N_REMOVE in this state we will receive only RC==OK
-        This will create the state in that the XDI is waiting for the
-        additional RC and does not delivery the RC to the client. This
-        code corrects the counter of outstanding RC's in this case.
-      --------------------------------------------------------------- */
-      if ((this->More & XMOREC) > 1) {
-        this->More &= ~XMOREC;
-        this->More |= 1;
-        dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x",
-                     XDI_A_NR(a),Id));
-      }
-    }
-    if (Rc==OK_FC) {
-      a->FlowControlIdTable[Ch] = Id;
-      a->FlowControlSkipTable[Ch] = false;
-      this->Rc = Rc;
-      this->More &= ~(XBUSY | XMOREC);
-      this->complete=0xff;
-      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
-      CALLBACK(a, this);
-      return 0;
-    }
-    /*
-      New protocol code sends return codes that comes from release
-      of flow control condition marked with DIVA_RC_TYPE_OK_FC extended
-      information element type.
-      If like return code arrives then application is able to process
-      all return codes self and XDI should not cances return codes.
-      This return code does not decrement XMOREC partial return code
-      counter due to fact that it was no request for this return code,
-      also XMOREC was not incremented.
-      */
-    if (extended_info_type == DIVA_RC_TYPE_OK_FC) {
-      a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING;
-      this->Rc = Rc;
-      this->complete=0xff;
-      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
-      DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x",
-      XDI_A_NR(a), Id, Ch, Rc))
-      CALLBACK(a, this);
-      return 0;
-    }
-    cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING);
-    if (cancel_rc && (a->FlowControlIdTable[Ch] == Id))
-    {
-      a->FlowControlIdTable[Ch] = 0;
-      if ((Rc != OK) || !a->FlowControlSkipTable[Ch])
-      {
-        this->Rc = Rc;
-        if (Ch == this->ReqCh)
-        {
-          this->More &=~(XBUSY | XMOREC);
-          this->complete=0xff;
-        }
-        xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
-        CALLBACK(a, this);
-      }
-      return 0;
-    }
-    if (this->More &XMOREC)
-      this->More--;
-        /* call the application callback function                   */
-    if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) {
-      this->Rc = Rc;
-      this->More &=~XBUSY;
-      this->complete=0xff;
-      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
-      CALLBACK(a, this);
-    }
-    return 0;
-  }
-        /* if it's an ASSIGN return code check if it's a return     */
-        /* code to an ASSIGN request from us                        */
-  if((Rc &0xf0)==ASSIGN_RC) {
-    e_no = get_assign(a, Ref);
-    if(e_no) {
-      this = entity_ptr(a,e_no);
-      this->Id = Id;
-      xdi_xlog_rc_event (XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]);
-        /* call the application callback function                   */
-      this->Rc = Rc;
-      this->More &=~XBUSY;
-      this->complete=0xff;
+	/* check for ready interrupt                                */
+	if (Rc == READY_INT) {
+		xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 0, 0);
+		if (a->ReadyInt) {
+			a->ReadyInt--;
+			return 0;
+		}
+		return 2;
+	}
+	/* if we know this Id ...                                   */
+	e_no = a->IdTable[Id];
+	if (e_no) {
+		this = entity_ptr(a, e_no);
+		xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 0, a->IdTypeTable[this->No]);
+		this->RcCh = Ch;
+		/* if it is a return code to a REMOVE request, remove the   */
+		/* Id from our table                                        */
+		if ((a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_REMOVE_PENDING) &&
+		    (Rc == OK)) {
+			if (a->IdTypeTable[e_no] == NL_ID) {
+				if (a->RcExtensionSupported &&
+				    (extended_info_type != DIVA_RC_TYPE_REMOVE_COMPLETE)) {
+					dtrc(dprintf("XDI: N-REMOVE, A(%02x) Id:%02x, ignore RC=OK",
+						     XDI_A_NR(a), Id));
+					return (0);
+				}
+				if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE)
+					a->RcExtensionSupported = true;
+			}
+			a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING;
+			a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING;
+			free_entity(a, e_no);
+			for (i = 0; i < 256; i++)
+			{
+				if (a->FlowControlIdTable[i] == Id)
+					a->FlowControlIdTable[i] = 0;
+			}
+			a->IdTable[Id] = 0;
+			this->Id = 0;
+			/* ---------------------------------------------------------------
+			   If we send N_DISC or N_DISK_ACK after we have received OK_FC
+			   then the card will respond with OK_FC and later with RC==OK.
+			   If we send N_REMOVE in this state we will receive only RC==OK
+			   This will create the state in that the XDI is waiting for the
+			   additional RC and does not delivery the RC to the client. This
+			   code corrects the counter of outstanding RC's in this case.
+			   --------------------------------------------------------------- */
+			if ((this->More & XMOREC) > 1) {
+				this->More &= ~XMOREC;
+				this->More |= 1;
+				dtrc(dprintf("XDI: correct MORE on REMOVE A(%02x) Id:%02x",
+					     XDI_A_NR(a), Id));
+			}
+		}
+		if (Rc == OK_FC) {
+			a->FlowControlIdTable[Ch] = Id;
+			a->FlowControlSkipTable[Ch] = false;
+			this->Rc = Rc;
+			this->More &= ~(XBUSY | XMOREC);
+			this->complete = 0xff;
+			xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
+			CALLBACK(a, this);
+			return 0;
+		}
+		/*
+		  New protocol code sends return codes that comes from release
+		  of flow control condition marked with DIVA_RC_TYPE_OK_FC extended
+		  information element type.
+		  If like return code arrives then application is able to process
+		  all return codes self and XDI should not cances return codes.
+		  This return code does not decrement XMOREC partial return code
+		  counter due to fact that it was no request for this return code,
+		  also XMOREC was not incremented.
+		*/
+		if (extended_info_type == DIVA_RC_TYPE_OK_FC) {
+			a->misc_flags_table[e_no] |= DIVA_MISC_FLAGS_NO_RC_CANCELLING;
+			this->Rc = Rc;
+			this->complete = 0xff;
+			xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
+			DBG_TRC(("XDI OK_FC A(%02x) Id:%02x Ch:%02x Rc:%02x",
+				 XDI_A_NR(a), Id, Ch, Rc))
+				CALLBACK(a, this);
+			return 0;
+		}
+		cancel_rc = !(a->misc_flags_table[e_no] & DIVA_MISC_FLAGS_NO_RC_CANCELLING);
+		if (cancel_rc && (a->FlowControlIdTable[Ch] == Id))
+		{
+			a->FlowControlIdTable[Ch] = 0;
+			if ((Rc != OK) || !a->FlowControlSkipTable[Ch])
+			{
+				this->Rc = Rc;
+				if (Ch == this->ReqCh)
+				{
+					this->More &= ~(XBUSY | XMOREC);
+					this->complete = 0xff;
+				}
+				xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
+				CALLBACK(a, this);
+			}
+			return 0;
+		}
+		if (this->More & XMOREC)
+			this->More--;
+		/* call the application callback function                   */
+		if (((!cancel_rc) || (this->More & XMOREF)) && !(this->More & XMOREC)) {
+			this->Rc = Rc;
+			this->More &= ~XBUSY;
+			this->complete = 0xff;
+			xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 1, a->IdTypeTable[this->No]);
+			CALLBACK(a, this);
+		}
+		return 0;
+	}
+	/* if it's an ASSIGN return code check if it's a return     */
+	/* code to an ASSIGN request from us                        */
+	if ((Rc & 0xf0) == ASSIGN_RC) {
+		e_no = get_assign(a, Ref);
+		if (e_no) {
+			this = entity_ptr(a, e_no);
+			this->Id = Id;
+			xdi_xlog_rc_event(XDI_A_NR(a), Id, Ch, Rc, 2, a->IdTypeTable[this->No]);
+			/* call the application callback function                   */
+			this->Rc = Rc;
+			this->More &= ~XBUSY;
+			this->complete = 0xff;
 #if defined(DIVA_ISTREAM) /* { */
-      if ((Rc == ASSIGN_OK) && a->ram_offset &&
-          (a->IdTypeTable[this->No] == NL_ID) &&
-          ((extended_info_type == DIVA_RC_TYPE_RX_DMA) ||
-          (extended_info_type == DIVA_RC_TYPE_CMA_PTR)) &&
-          extended_info) {
-        dword offset = (*(a->ram_offset)) (a);
-        dword tmp[2];
-        extended_info -= offset;
+			if ((Rc == ASSIGN_OK) && a->ram_offset &&
+			    (a->IdTypeTable[this->No] == NL_ID) &&
+			    ((extended_info_type == DIVA_RC_TYPE_RX_DMA) ||
+			     (extended_info_type == DIVA_RC_TYPE_CMA_PTR)) &&
+			    extended_info) {
+				dword offset = (*(a->ram_offset)) (a);
+				dword tmp[2];
+				extended_info -= offset;
 #ifdef PLATFORM_GT_32BIT
-        a->ram_in_dw(a, (void*)ULongToPtr(extended_info), (dword*)&tmp[0], 2);
+				a->ram_in_dw(a, (void *)ULongToPtr(extended_info), (dword *)&tmp[0], 2);
 #else
-        a->ram_in_dw(a, (void*)extended_info, (dword*)&tmp[0], 2);
+				a->ram_in_dw(a, (void *)extended_info, (dword *)&tmp[0], 2);
 #endif
-        a->tx_stream[Id]  = tmp[0];
-        a->rx_stream[Id]  = tmp[1];
-        if (extended_info_type == DIVA_RC_TYPE_RX_DMA) {
-          DBG_TRC(("Id=0x%x RxDMA=%08x:%08x",
-                    Id, a->tx_stream[Id], a->rx_stream[Id]))
-          a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA;
-        } else {
-          DBG_TRC(("Id=0x%x CMA=%08x:%08x",
-                    Id, a->tx_stream[Id], a->rx_stream[Id]))
-          a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
-          a->rx_pos[Id]     = 0;
-          a->rx_stream[Id] -= offset;
-        }
-        a->tx_pos[Id]     = 0;
-        a->tx_stream[Id] -= offset;
-      } else {
-        a->tx_stream[Id] = 0;
-        a->rx_stream[Id] = 0;
-        a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
-      }
+				a->tx_stream[Id]  = tmp[0];
+				a->rx_stream[Id]  = tmp[1];
+				if (extended_info_type == DIVA_RC_TYPE_RX_DMA) {
+					DBG_TRC(("Id=0x%x RxDMA=%08x:%08x",
+						 Id, a->tx_stream[Id], a->rx_stream[Id]))
+						a->misc_flags_table[this->No] |= DIVA_MISC_FLAGS_RX_DMA;
+				} else {
+					DBG_TRC(("Id=0x%x CMA=%08x:%08x",
+						 Id, a->tx_stream[Id], a->rx_stream[Id]))
+						a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
+					a->rx_pos[Id]     = 0;
+					a->rx_stream[Id] -= offset;
+				}
+				a->tx_pos[Id]     = 0;
+				a->tx_stream[Id] -= offset;
+			} else {
+				a->tx_stream[Id] = 0;
+				a->rx_stream[Id] = 0;
+				a->misc_flags_table[this->No] &= ~DIVA_MISC_FLAGS_RX_DMA;
+			}
 #endif /* } */
-      CALLBACK(a, this);
-      if(Rc==ASSIGN_OK) {
-        a->IdTable[Id] = e_no;
-      }
-      else
-      {
-        free_entity(a, e_no);
-        for (i = 0; i < 256; i++)
-        {
-          if (a->FlowControlIdTable[i] == Id)
-            a->FlowControlIdTable[i] = 0;
-        }
-        a->IdTable[Id] = 0;
-        this->Id = 0;
-      }
-      return 1;
-    }
-  }
-  return 2;
+			CALLBACK(a, this);
+			if (Rc == ASSIGN_OK) {
+				a->IdTable[Id] = e_no;
+			}
+			else
+			{
+				free_entity(a, e_no);
+				for (i = 0; i < 256; i++)
+				{
+					if (a->FlowControlIdTable[i] == Id)
+						a->FlowControlIdTable[i] = 0;
+				}
+				a->IdTable[Id] = 0;
+				this->Id = 0;
+			}
+			return 1;
+		}
+	}
+	return 2;
 }
 /*------------------------------------------------------------------*/
 /* indication handler                                               */
@@ -563,273 +563,273 @@ static byte isdn_ind(ADAPTER *a,
 		     byte MInd,
 		     word MLength)
 {
-  ENTITY  * this;
-  word clength;
-  word offset;
-  BUFFERS  *R;
-  byte* cma = NULL;
+	ENTITY *this;
+	word clength;
+	word offset;
+	BUFFERS *R;
+	byte *cma = NULL;
 #ifdef USE_EXTENDED_DEBUGS
-  {
-    DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
-  }
+	{
+		DBG_TRC(("<A%d Id=0x%x Ind=0x%x", ((ISDN_ADAPTER *)a->io)->ANum, Id, Ind))
+			}
 #else
-  dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)",Ind,Id,Ch));
+	dbug(dprintf("isdn_ind(Ind=%x,Id=%x,Ch=%x)", Ind, Id, Ch));
 #endif
-  if(a->IdTable[Id]) {
-    this = entity_ptr(a,a->IdTable[Id]);
-    this->IndCh = Ch;
-    xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
-                  0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]);
-        /* if the Receive More flag is not yet set, this is the     */
-        /* first buffer of the packet                               */
-    if(this->RCurrent==0xff) {
-        /* check for receive buffer chaining                        */
-      if(Ind==this->MInd) {
-        this->complete = 0;
-        this->Ind = MInd;
-      }
-      else {
-        this->complete = 1;
-        this->Ind = Ind;
-      }
-        /* call the application callback function for the receive   */
-        /* look ahead                                               */
-      this->RLength = MLength;
+	if (a->IdTable[Id]) {
+		this = entity_ptr(a, a->IdTable[Id]);
+		this->IndCh = Ch;
+		xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
+			     0/* rnr_valid */, 0 /* rnr */, a->IdTypeTable[this->No]);
+		/* if the Receive More flag is not yet set, this is the     */
+		/* first buffer of the packet                               */
+		if (this->RCurrent == 0xff) {
+			/* check for receive buffer chaining                        */
+			if (Ind == this->MInd) {
+				this->complete = 0;
+				this->Ind = MInd;
+			}
+			else {
+				this->complete = 1;
+				this->Ind = Ind;
+			}
+			/* call the application callback function for the receive   */
+			/* look ahead                                               */
+			this->RLength = MLength;
 #if defined(DIVA_ISTREAM)
-      if ((a->rx_stream[this->Id] ||
-           (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) &&
-          ((Ind == N_DATA) ||
-           (a->protocol_capabilities & PROTCAP_CMA_ALLPR))) {
-        PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io ;
-        if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) {
+			if ((a->rx_stream[this->Id] ||
+			     (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA)) &&
+			    ((Ind == N_DATA) ||
+			     (a->protocol_capabilities & PROTCAP_CMA_ALLPR))) {
+				PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io;
+				if (a->misc_flags_table[this->No] & DIVA_MISC_FLAGS_RX_DMA) {
 #if defined(DIVA_IDI_RX_DMA)
-          dword d;
-          diva_get_dma_map_entry (\
-                   (struct _diva_dma_map_entry*)IoAdapter->dma_map,
-                   (int)a->rx_stream[this->Id], (void**)&cma, &d);
+					dword d;
+					diva_get_dma_map_entry(\
+						(struct _diva_dma_map_entry *)IoAdapter->dma_map,
+						(int)a->rx_stream[this->Id], (void **)&cma, &d);
 #else
-          cma = &a->stream_buffer[0];
-          cma[0] = cma[1] = cma[2] = cma[3] = 0;
+					cma = &a->stream_buffer[0];
+					cma[0] = cma[1] = cma[2] = cma[3] = 0;
 #endif
-          this->RLength = MLength = (word)*(dword*)cma;
-          cma += 4;
-        } else {
-        int final = 0;
-        cma = &a->stream_buffer[0];
-        this->RLength = MLength = (word)diva_istream_read (a,
-                                                     Id,
-                                                     cma,
-                                                     sizeof(a->stream_buffer),
-                                                     &final, NULL, NULL);
-        }
-        IoAdapter->RBuffer.length = min(MLength, (word)270);
-        if (IoAdapter->RBuffer.length != MLength) {
-          this->complete = 0;
-        } else {
-          this->complete = 1;
-        }
-        memcpy (IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length) ;
-        this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer ;
-      }
+					this->RLength = MLength = (word)*(dword *)cma;
+					cma += 4;
+				} else {
+					int final = 0;
+					cma = &a->stream_buffer[0];
+					this->RLength = MLength = (word)diva_istream_read(a,
+											  Id,
+											  cma,
+											  sizeof(a->stream_buffer),
+											  &final, NULL, NULL);
+				}
+				IoAdapter->RBuffer.length = min(MLength, (word)270);
+				if (IoAdapter->RBuffer.length != MLength) {
+					this->complete = 0;
+				} else {
+					this->complete = 1;
+				}
+				memcpy(IoAdapter->RBuffer.P, cma, IoAdapter->RBuffer.length);
+				this->RBuffer = (DBUFFER *)&IoAdapter->RBuffer;
+			}
 #endif
-      if (!cma) {
-        a->ram_look_ahead(a, RBuffer, this);
-      }
-      this->RNum = 0;
-      CALLBACK(a, this);
-        /* map entity ptr, selector could be re-mapped by call to   */
-        /* IDI from within callback                                 */
-      this = entity_ptr(a,a->IdTable[Id]);
-      xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
-          1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]);
-        /* check for RNR                                            */
-      if(this->RNR==1) {
-        this->RNR = 0;
-        return 1;
-      }
-        /* if no buffers are provided by the application, the       */
-        /* application want to copy the data itself including       */
-        /* N_MDATA/LL_MDATA chaining                                */
-      if(!this->RNR && !this->RNum) {
-        xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
-            2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
-        return 0;
-      }
-        /* if there is no RNR, set the More flag                    */
-      this->RCurrent = 0;
-      this->ROffset = 0;
-    }
-    if(this->RNR==2) {
-      if(Ind!=this->MInd) {
-        this->RCurrent = 0xff;
-        this->RNR = 0;
-      }
-      return 0;
-    }
-        /* if we have received buffers from the application, copy   */
-        /* the data into these buffers                              */
-    offset = 0;
-    R = PTR_R(a,this);
-    do {
-      if(this->ROffset==R[this->RCurrent].PLength) {
-        this->ROffset = 0;
-        this->RCurrent++;
-      }
-      if (cma) {
-        clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset));
-      } else {
-        clength = min(a->ram_inw(a, &RBuffer->length)-offset,
-                      R[this->RCurrent].PLength-this->ROffset);
-      }
-      if(R[this->RCurrent].P) {
-        if (cma) {
-          memcpy (PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
-                  &cma[offset],
-                  clength);
-        } else {
-          a->ram_in_buffer(a,
-                           &RBuffer->P[offset],
-                           PTR_P(a,this,&R[this->RCurrent].P[this->ROffset]),
-                           clength);
-        }
-      }
-      offset +=clength;
-      this->ROffset +=clength;
-      if (cma) {
-        if (offset >= MLength) {
-          break;
-        }
-        continue;
-      }
-    } while(offset<(a->ram_inw(a, &RBuffer->length)));
-        /* if it's the last buffer of the packet, call the          */
-        /* application callback function for the receive complete   */
-        /* call                                                     */
-    if(Ind!=this->MInd) {
-      R[this->RCurrent].PLength = this->ROffset;
-      if(this->ROffset) this->RCurrent++;
-      this->RNum = this->RCurrent;
-      this->RCurrent = 0xff;
-      this->Ind = Ind;
-      this->complete = 2;
-      xdi_xlog_ind (XDI_A_NR(a), Id, Ch, Ind,
-          3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
-      CALLBACK(a, this);
-    }
-    return 0;
-  }
-  return 2;
+			if (!cma) {
+				a->ram_look_ahead(a, RBuffer, this);
+			}
+			this->RNum = 0;
+			CALLBACK(a, this);
+			/* map entity ptr, selector could be re-mapped by call to   */
+			/* IDI from within callback                                 */
+			this = entity_ptr(a, a->IdTable[Id]);
+			xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
+				     1/* rnr_valid */, this->RNR/* rnr */, a->IdTypeTable[this->No]);
+			/* check for RNR                                            */
+			if (this->RNR == 1) {
+				this->RNR = 0;
+				return 1;
+			}
+			/* if no buffers are provided by the application, the       */
+			/* application want to copy the data itself including       */
+			/* N_MDATA/LL_MDATA chaining                                */
+			if (!this->RNR && !this->RNum) {
+				xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
+					     2/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
+				return 0;
+			}
+			/* if there is no RNR, set the More flag                    */
+			this->RCurrent = 0;
+			this->ROffset = 0;
+		}
+		if (this->RNR == 2) {
+			if (Ind != this->MInd) {
+				this->RCurrent = 0xff;
+				this->RNR = 0;
+			}
+			return 0;
+		}
+		/* if we have received buffers from the application, copy   */
+		/* the data into these buffers                              */
+		offset = 0;
+		R = PTR_R(a, this);
+		do {
+			if (this->ROffset == R[this->RCurrent].PLength) {
+				this->ROffset = 0;
+				this->RCurrent++;
+			}
+			if (cma) {
+				clength = min(MLength, (word)(R[this->RCurrent].PLength-this->ROffset));
+			} else {
+				clength = min(a->ram_inw(a, &RBuffer->length)-offset,
+					      R[this->RCurrent].PLength-this->ROffset);
+			}
+			if (R[this->RCurrent].P) {
+				if (cma) {
+					memcpy(PTR_P(a, this, &R[this->RCurrent].P[this->ROffset]),
+					       &cma[offset],
+					       clength);
+				} else {
+					a->ram_in_buffer(a,
+							 &RBuffer->P[offset],
+							 PTR_P(a, this, &R[this->RCurrent].P[this->ROffset]),
+							 clength);
+				}
+			}
+			offset += clength;
+			this->ROffset += clength;
+			if (cma) {
+				if (offset >= MLength) {
+					break;
+				}
+				continue;
+			}
+		} while (offset < (a->ram_inw(a, &RBuffer->length)));
+		/* if it's the last buffer of the packet, call the          */
+		/* application callback function for the receive complete   */
+		/* call                                                     */
+		if (Ind != this->MInd) {
+			R[this->RCurrent].PLength = this->ROffset;
+			if (this->ROffset) this->RCurrent++;
+			this->RNum = this->RCurrent;
+			this->RCurrent = 0xff;
+			this->Ind = Ind;
+			this->complete = 2;
+			xdi_xlog_ind(XDI_A_NR(a), Id, Ch, Ind,
+				     3/* rnr_valid */, 0/* rnr */, a->IdTypeTable[this->No]);
+			CALLBACK(a, this);
+		}
+		return 0;
+	}
+	return 2;
 }
 #if defined(XDI_USE_XLOG)
 /* -----------------------------------------------------------
    This function works in the same way as xlog on the
    active board
    ----------------------------------------------------------- */
-static void xdi_xlog (byte *msg, word code, int length) {
-  xdi_dbg_xlog ("\x00\x02", msg, code, length);
+static void xdi_xlog(byte *msg, word code, int length) {
+	xdi_dbg_xlog("\x00\x02", msg, code, length);
 }
 #endif
 /* -----------------------------------------------------------
-    This function writes the information about the Return Code
-    processing in the trace buffer. Trace ID is 221.
-    INPUT:
-        Adapter - system unicue adapter number (0 ... 255)
-        Id      - Id of the entity that had sent this return code
-        Ch      - Channel of the entity that had sent this return code
-        Rc      - return code value
-        cb:       (0...2)
-                  switch (cb) {
-                   case 0: printf ("DELIVERY"); break;
-                   case 1: printf ("CALLBACK"); break;
-                   case 2: printf ("ASSIGN"); break;
-                  }
-                  DELIVERY - have entered isdn_rc with this RC
-                  CALLBACK - about to make callback to the application
-                             for this RC
-                  ASSIGN   - about to make callback for RC that is result
-                             of ASSIGN request. It is no DELIVERY message
-                             before of this message
-        type   - the Id that was sent by the ASSIGN of this entity.
-                 This should be global Id like NL_ID, DSIG_ID, MAN_ID.
-                 An unknown Id will cause "?-" in the front of the request.
-                 In this case the log.c is to be extended.
+   This function writes the information about the Return Code
+   processing in the trace buffer. Trace ID is 221.
+   INPUT:
+   Adapter - system unicue adapter number (0 ... 255)
+   Id      - Id of the entity that had sent this return code
+   Ch      - Channel of the entity that had sent this return code
+   Rc      - return code value
+   cb:       (0...2)
+   switch (cb) {
+   case 0: printf ("DELIVERY"); break;
+   case 1: printf ("CALLBACK"); break;
+   case 2: printf ("ASSIGN"); break;
+   }
+   DELIVERY - have entered isdn_rc with this RC
+   CALLBACK - about to make callback to the application
+   for this RC
+   ASSIGN   - about to make callback for RC that is result
+   of ASSIGN request. It is no DELIVERY message
+   before of this message
+   type   - the Id that was sent by the ASSIGN of this entity.
+   This should be global Id like NL_ID, DSIG_ID, MAN_ID.
+   An unknown Id will cause "?-" in the front of the request.
+   In this case the log.c is to be extended.
    ----------------------------------------------------------- */
-static void xdi_xlog_rc_event (byte Adapter,
-                               byte Id, byte Ch, byte Rc, byte cb, byte type) {
+static void xdi_xlog_rc_event(byte Adapter,
+			      byte Id, byte Ch, byte Rc, byte cb, byte type) {
 #if defined(XDI_USE_XLOG)
-  word LogInfo[4];
-  PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
-  PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
-  PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
-  PUT_WORD(&LogInfo[3], cb);
-  xdi_xlog ((byte*)&LogInfo[0], 221, sizeof(LogInfo));
+	word LogInfo[4];
+	PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
+	PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
+	PUT_WORD(&LogInfo[2], ((word)Rc | (word)(type << 8)));
+	PUT_WORD(&LogInfo[3], cb);
+	xdi_xlog((byte *)&LogInfo[0], 221, sizeof(LogInfo));
 #endif
 }
 /* ------------------------------------------------------------------------
-    This function writes the information about the request processing
-    in the trace buffer. Trace ID is 220.
-    INPUT:
-        Adapter - system unicue adapter number (0 ... 255)
-        Id      - Id of the entity that had sent this request
-        Ch      - Channel of the entity that had sent this request
-        Req     - Code of the request
-        type    - the Id that was sent by the ASSIGN of this entity.
-                  This should be global Id like NL_ID, DSIG_ID, MAN_ID.
-                  An unknown Id will cause "?-" in the front of the request.
-                  In this case the log.c is to be extended.
+   This function writes the information about the request processing
+   in the trace buffer. Trace ID is 220.
+   INPUT:
+   Adapter - system unicue adapter number (0 ... 255)
+   Id      - Id of the entity that had sent this request
+   Ch      - Channel of the entity that had sent this request
+   Req     - Code of the request
+   type    - the Id that was sent by the ASSIGN of this entity.
+   This should be global Id like NL_ID, DSIG_ID, MAN_ID.
+   An unknown Id will cause "?-" in the front of the request.
+   In this case the log.c is to be extended.
    ------------------------------------------------------------------------ */
-static void xdi_xlog_request (byte Adapter, byte Id,
-                              byte Ch, byte Req, byte type) {
+static void xdi_xlog_request(byte Adapter, byte Id,
+			     byte Ch, byte Req, byte type) {
 #if defined(XDI_USE_XLOG)
-  word LogInfo[3];
-  PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
-  PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
-  PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
-  xdi_xlog ((byte*)&LogInfo[0], 220, sizeof(LogInfo));
+	word LogInfo[3];
+	PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
+	PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
+	PUT_WORD(&LogInfo[2], ((word)Req | (word)(type << 8)));
+	xdi_xlog((byte *)&LogInfo[0], 220, sizeof(LogInfo));
 #endif
 }
 /* ------------------------------------------------------------------------
-    This function writes the information about the indication processing
-    in the trace buffer. Trace ID is 222.
-    INPUT:
-        Adapter - system unicue adapter number (0 ... 255)
-        Id      - Id of the entity that had sent this indication
-        Ch      - Channel of the entity that had sent this indication
-        Ind     - Code of the indication
-        rnr_valid: (0 .. 3) supported
-          switch (rnr_valid) {
-            case 0: printf ("DELIVERY"); break;
-            case 1: printf ("RNR=%d", rnr);
-            case 2: printf ("RNum=0");
-            case 3: printf ("COMPLETE");
-          }
-          DELIVERY - indication entered isdn_rc function
-          RNR=...  - application had returned RNR=... after the
-                     look ahead callback
-          RNum=0   - application had not returned any buffer to copy
-                     this indication and will copy it self
-          COMPLETE - XDI had copied the data to the buffers provided
-                     bu the application and is about to issue the
-                     final callback
-        rnr:  Look case 1 of the rnr_valid
-        type: the Id that was sent by the ASSIGN of this entity. This should
-              be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will
-              cause "?-" in the front of the request. In this case the
-              log.c is to be extended.
+   This function writes the information about the indication processing
+   in the trace buffer. Trace ID is 222.
+   INPUT:
+   Adapter - system unicue adapter number (0 ... 255)
+   Id      - Id of the entity that had sent this indication
+   Ch      - Channel of the entity that had sent this indication
+   Ind     - Code of the indication
+   rnr_valid: (0 .. 3) supported
+   switch (rnr_valid) {
+   case 0: printf ("DELIVERY"); break;
+   case 1: printf ("RNR=%d", rnr);
+   case 2: printf ("RNum=0");
+   case 3: printf ("COMPLETE");
+   }
+   DELIVERY - indication entered isdn_rc function
+   RNR=...  - application had returned RNR=... after the
+   look ahead callback
+   RNum=0   - application had not returned any buffer to copy
+   this indication and will copy it self
+   COMPLETE - XDI had copied the data to the buffers provided
+   bu the application and is about to issue the
+   final callback
+   rnr:  Look case 1 of the rnr_valid
+   type: the Id that was sent by the ASSIGN of this entity. This should
+   be global Id like NL_ID, DSIG_ID, MAN_ID. An unknown Id will
+   cause "?-" in the front of the request. In this case the
+   log.c is to be extended.
    ------------------------------------------------------------------------ */
-static void xdi_xlog_ind (byte Adapter,
-                          byte Id,
-                          byte Ch,
-                          byte Ind,
-                          byte rnr_valid,
-                          byte rnr,
-                          byte type) {
+static void xdi_xlog_ind(byte Adapter,
+			 byte Id,
+			 byte Ch,
+			 byte Ind,
+			 byte rnr_valid,
+			 byte rnr,
+			 byte type) {
 #if defined(XDI_USE_XLOG)
-  word LogInfo[4];
-  PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
-  PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
-  PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
-  PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
-  xdi_xlog ((byte*)&LogInfo[0], 222, sizeof(LogInfo));
+	word LogInfo[4];
+	PUT_WORD(&LogInfo[0], ((word)Adapter | (word)(xdi_xlog_sec++ << 8)));
+	PUT_WORD(&LogInfo[1], ((word)Id | (word)(Ch << 8)));
+	PUT_WORD(&LogInfo[2], ((word)Ind | (word)(type << 8)));
+	PUT_WORD(&LogInfo[3], ((word)rnr | (word)(rnr_valid << 8)));
+	xdi_xlog((byte *)&LogInfo[0], 222, sizeof(LogInfo));
 #endif
 }
diff --git a/drivers/isdn/hardware/eicon/di.h b/drivers/isdn/hardware/eicon/di.h
index dcf37b1..ff26c65 100644
--- a/drivers/isdn/hardware/eicon/di.h
+++ b/drivers/isdn/hardware/eicon/di.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 /*
@@ -35,83 +35,83 @@
 #define DIVA_MISC_FLAGS_REMOVE_PENDING    0x01
 #define DIVA_MISC_FLAGS_NO_RC_CANCELLING  0x02
 #define DIVA_MISC_FLAGS_RX_DMA            0x04
-        /* structure for all information we have to keep on a per   */
-        /* adapater basis                                           */
+/* structure for all information we have to keep on a per   */
+/* adapater basis                                           */
 typedef struct adapter_s ADAPTER;
 struct adapter_s {
-  void * io;
-  byte IdTable[256];
-  byte IdTypeTable[256];
-  byte FlowControlIdTable[256];
-  byte FlowControlSkipTable[256];
-  byte ReadyInt;
-  byte RcExtensionSupported;
-  byte misc_flags_table[256];
-  dword protocol_capabilities;
-  byte ( * ram_in)(ADAPTER * a, void * adr);
-  word ( * ram_inw)(ADAPTER * a, void * adr);
-  void (* ram_in_buffer)(ADAPTER * a, void * adr, void  * P, word length);
-  void (* ram_look_ahead)(ADAPTER * a, PBUFFER * RBuffer, ENTITY  * e);
-  void ( * ram_out)(ADAPTER * a, void * adr, byte data);
-  void ( * ram_outw)(ADAPTER * a, void * adr, word data);
-  void (* ram_out_buffer)(ADAPTER * a, void * adr, void  * P, word length);
-  void ( * ram_inc)(ADAPTER * a, void * adr);
+	void *io;
+	byte IdTable[256];
+	byte IdTypeTable[256];
+	byte FlowControlIdTable[256];
+	byte FlowControlSkipTable[256];
+	byte ReadyInt;
+	byte RcExtensionSupported;
+	byte misc_flags_table[256];
+	dword protocol_capabilities;
+	byte (*ram_in)(ADAPTER *a, void *adr);
+	word (*ram_inw)(ADAPTER *a, void *adr);
+	void (*ram_in_buffer)(ADAPTER *a, void *adr, void *P, word length);
+	void (*ram_look_ahead)(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
+	void (*ram_out)(ADAPTER *a, void *adr, byte data);
+	void (*ram_outw)(ADAPTER *a, void *adr, word data);
+	void (*ram_out_buffer)(ADAPTER *a, void *adr, void *P, word length);
+	void (*ram_inc)(ADAPTER *a, void *adr);
 #if defined(DIVA_ISTREAM)
-  dword rx_stream[256];
-  dword tx_stream[256];
-  word tx_pos[256];
-  word rx_pos[256];
-  byte stream_buffer[2512];
-  dword ( * ram_offset)(ADAPTER * a);
-  void ( * ram_out_dw) (ADAPTER *a,
-                                    void *addr,
-                                    const dword* data,
-                                    int dwords);
-  void ( * ram_in_dw) (ADAPTER *a,
-                                   void *addr,
-                                   dword* data,
-                                   int dwords);
-  void ( * istream_wakeup)(ADAPTER* a);
+	dword rx_stream[256];
+	dword tx_stream[256];
+	word tx_pos[256];
+	word rx_pos[256];
+	byte stream_buffer[2512];
+	dword (*ram_offset)(ADAPTER *a);
+	void (*ram_out_dw)(ADAPTER *a,
+			   void *addr,
+			   const dword *data,
+			   int dwords);
+	void (*ram_in_dw)(ADAPTER *a,
+			  void *addr,
+			  dword *data,
+			  int dwords);
+	void (*istream_wakeup)(ADAPTER *a);
 #else
-  byte stream_buffer[4];
+	byte stream_buffer[4];
 #endif
 };
 /*------------------------------------------------------------------*/
 /* public functions of IDI common code                              */
 /*------------------------------------------------------------------*/
-void pr_out(ADAPTER * a);
-byte pr_dpc(ADAPTER * a);
-byte scom_test_int(ADAPTER * a);
-void scom_clear_int(ADAPTER * a);
+void pr_out(ADAPTER *a);
+byte pr_dpc(ADAPTER *a);
+byte scom_test_int(ADAPTER *a);
+void scom_clear_int(ADAPTER *a);
 /*------------------------------------------------------------------*/
 /* OS specific functions used by IDI common code                    */
 /*------------------------------------------------------------------*/
-void free_entity(ADAPTER * a, byte e_no);
-void assign_queue(ADAPTER * a, byte e_no, word ref);
-byte get_assign(ADAPTER * a, word ref);
-void req_queue(ADAPTER * a, byte e_no);
-byte look_req(ADAPTER * a);
-void next_req(ADAPTER * a);
-ENTITY  * entity_ptr(ADAPTER * a, byte e_no);
+void free_entity(ADAPTER *a, byte e_no);
+void assign_queue(ADAPTER *a, byte e_no, word ref);
+byte get_assign(ADAPTER *a, word ref);
+void req_queue(ADAPTER *a, byte e_no);
+byte look_req(ADAPTER *a);
+void next_req(ADAPTER *a);
+ENTITY *entity_ptr(ADAPTER *a, byte e_no);
 #if defined(DIVA_ISTREAM)
 struct _diva_xdi_stream_interface;
-void diva_xdi_provide_istream_info (ADAPTER* a,
-                                    struct _diva_xdi_stream_interface* pI);
-void pr_stream (ADAPTER * a);
-int diva_istream_write (void* context,
-                        int Id,
-                        void* data,
-                        int length,
-                        int final,
-                        byte usr1,
-                        byte usr2);
-int diva_istream_read (void* context,
-                        int Id,
-                        void* data,
-                        int max_length,
-                        int* final,
-                        byte* usr1,
-                        byte* usr2);
+void diva_xdi_provide_istream_info(ADAPTER *a,
+				   struct _diva_xdi_stream_interface *pI);
+void pr_stream(ADAPTER *a);
+int diva_istream_write(void *context,
+		       int Id,
+		       void *data,
+		       int length,
+		       int final,
+		       byte usr1,
+		       byte usr2);
+int diva_istream_read(void *context,
+		      int Id,
+		      void *data,
+		      int max_length,
+		      int *final,
+		      byte *usr1,
+		      byte *usr2);
 #if defined(DIVA_IDI_RX_DMA)
 #include "diva_dma.h"
 #endif
diff --git a/drivers/isdn/hardware/eicon/di_dbg.h b/drivers/isdn/hardware/eicon/di_dbg.h
index d576ff3..1380b60 100644
--- a/drivers/isdn/hardware/eicon/di_dbg.h
+++ b/drivers/isdn/hardware/eicon/di_dbg.h
@@ -1,34 +1,34 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_DI_DBG_INC__
 #define __DIVA_DI_DBG_INC__
-#if !defined (dtrc)
+#if !defined(dtrc)
 #define dtrc(a)
 #endif
-#if !defined (dbug)
+#if !defined(dbug)
 #define dbug(a)
 #endif
 #if !defined USE_EXTENDED_DEBUGS
diff --git a/drivers/isdn/hardware/eicon/di_defs.h b/drivers/isdn/hardware/eicon/di_defs.h
index 4c2f612..a5094d2 100644
--- a/drivers/isdn/hardware/eicon/di_defs.h
+++ b/drivers/isdn/hardware/eicon/di_defs.h
@@ -1,31 +1,31 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 _DI_DEFS_  
+#ifndef _DI_DEFS_
 #define _DI_DEFS_
-        /* typedefs for our data structures                         */
+/* typedefs for our data structures                         */
 typedef struct get_name_s GET_NAME;
 /*  The entity_s structure is used to pass all
     parameters between application and IDI   */
@@ -38,72 +38,72 @@ typedef struct get_para_s GET_PARA;
 #define IDI_CALL_ENTITY_T
 /* typedef void ( * IDI_CALL)(ENTITY *); */
 /* --------------------------------------------------------
-    IDI_CALL
+   IDI_CALL
    -------------------------------------------------------- */
-typedef void (IDI_CALL_LINK_T * IDI_CALL)(ENTITY IDI_CALL_ENTITY_T *);
+typedef void (IDI_CALL_LINK_T *IDI_CALL)(ENTITY IDI_CALL_ENTITY_T *);
 typedef struct {
-  word length;          /* length of data/parameter field           */
-  byte P[270];          /* data/parameter field                     */
+	word length;          /* length of data/parameter field           */
+	byte P[270];          /* data/parameter field                     */
 } DBUFFER;
 struct get_name_s {
-  word command;         /* command = 0x0100 */
-  byte name[BOARD_NAME_LENGTH];
+	word command;         /* command = 0x0100 */
+	byte name[BOARD_NAME_LENGTH];
 };
 struct postcall_s {
-  word      command;                           /* command = 0x0300 */
-  word      dummy;                             /* not used */
-  void      (  * callback)(void   *);      /* call back */
-  void    *context;                          /* context pointer */
+	word      command;                           /* command = 0x0300 */
+	word      dummy;                             /* not used */
+	void      (*callback)(void *);      /* call back */
+	void      *context;                          /* context pointer */
 };
 #define REQ_PARA            0x0600   /* request command line parameters */
 #define REQ_PARA_LEN             1   /* number of data bytes */
 #define L1_STARTUP_DOWN_POS      0   /* '-y' command line parameter in......*/
 #define L1_STARTUP_DOWN_MSK   0x01   /* first byte position (index 0) with value 0x01 */
 struct get_para_s {
-  word  command;            /* command = 0x0600 */
-  byte  len;                /* max length of para field in bytes */
-  byte  para[REQ_PARA_LEN]; /* parameter field */
+	word  command;            /* command = 0x0600 */
+	byte  len;                /* max length of para field in bytes */
+	byte  para[REQ_PARA_LEN]; /* parameter field */
 };
 struct buffers_s {
-  word PLength;
-  byte   * P;
+	word PLength;
+	byte *P;
 };
 struct entity_s {
-  byte                  Req;            /* pending request          */
-  byte                  Rc;             /* return code received     */
-  byte                  Ind;            /* indication received      */
-  byte                  ReqCh;          /* channel of current Req   */
-  byte                  RcCh;           /* channel of current Rc    */
-  byte                  IndCh;          /* channel of current Ind   */
-  byte                  Id;             /* ID used by this entity   */
-  byte                  GlobalId;       /* reserved field           */
-  byte                  XNum;           /* number of X-buffers      */
-  byte                  RNum;           /* number of R-buffers      */
-  BUFFERS                 * X;        /* pointer to X-buffer list */
-  BUFFERS                 * R;        /* pointer to R-buffer list */
-  word                  RLength;        /* length of current R-data */
-  DBUFFER   *         RBuffer;        /* buffer of current R-data */
-  byte                  RNR;            /* receive not ready flag   */
-  byte                  complete;       /* receive complete status  */
-  IDI_CALL              callback;
-  word                  user[2];
-        /* fields used by the driver internally                     */
-  byte                  No;             /* entity number            */
-  byte                  reserved2;      /* reserved field           */
-  byte                  More;           /* R/X More flags           */
-  byte                  MInd;           /* MDATA coding for this ID */
-  byte                  XCurrent;       /* current transmit buffer  */
-  byte                  RCurrent;       /* current receive buffer   */
-  word                  XOffset;        /* offset in x-buffer       */
-  word                  ROffset;        /* offset in r-buffer       */
+	byte                  Req;            /* pending request          */
+	byte                  Rc;             /* return code received     */
+	byte                  Ind;            /* indication received      */
+	byte                  ReqCh;          /* channel of current Req   */
+	byte                  RcCh;           /* channel of current Rc    */
+	byte                  IndCh;          /* channel of current Ind   */
+	byte                  Id;             /* ID used by this entity   */
+	byte                  GlobalId;       /* reserved field           */
+	byte                  XNum;           /* number of X-buffers      */
+	byte                  RNum;           /* number of R-buffers      */
+	BUFFERS               *X;             /* pointer to X-buffer list */
+	BUFFERS               *R;             /* pointer to R-buffer list */
+	word                  RLength;        /* length of current R-data */
+	DBUFFER               *RBuffer;       /* buffer of current R-data */
+	byte                  RNR;            /* receive not ready flag   */
+	byte                  complete;       /* receive complete status  */
+	IDI_CALL              callback;
+	word                  user[2];
+	/* fields used by the driver internally                     */
+	byte                  No;             /* entity number            */
+	byte                  reserved2;      /* reserved field           */
+	byte                  More;           /* R/X More flags           */
+	byte                  MInd;           /* MDATA coding for this ID */
+	byte                  XCurrent;       /* current transmit buffer  */
+	byte                  RCurrent;       /* current receive buffer   */
+	word                  XOffset;        /* offset in x-buffer       */
+	word                  ROffset;        /* offset in r-buffer       */
 };
 typedef struct {
-  byte                  type;
-  byte                  channels;
-  word                  features;
-  IDI_CALL              request;
+	byte                  type;
+	byte                  channels;
+	word                  features;
+	IDI_CALL              request;
 } DESCRIPTOR;
-        /* descriptor type field coding */
+/* descriptor type field coding */
 #define IDI_ADAPTER_S           1
 #define IDI_ADAPTER_PR          2
 #define IDI_ADAPTER_DIVA        3
@@ -113,7 +113,7 @@ typedef struct {
 #define IDI_DADAPTER            0xfd
 #define IDI_DIDDPNP             0xfe
 #define IDI_DIMAINT             0xff
-        /* Hardware IDs ISA PNP */
+/* Hardware IDs ISA PNP */
 #define HW_ID_DIVA_PRO     3    /* same as IDI_ADAPTER_DIVA    */
 #define HW_ID_MAESTRA      4    /* same as IDI_ADAPTER_MAESTRA */
 #define HW_ID_PICCOLA      5
@@ -123,7 +123,7 @@ typedef struct {
 #define HW_ID_DIVA20_U     9
 #define HW_ID_DIVA30       10
 #define HW_ID_DIVA30_U     11
-        /* Hardware IDs PCI */
+/* Hardware IDs PCI */
 #define HW_ID_EICON_PCI              0x1133
 #define HW_ID_SIEMENS_PCI            0x8001 /* unused SubVendor ID for Siemens Cornet-N cards */
 #define HW_ID_PROTTYPE_CORNETN       0x0014 /* SubDevice ID for Siemens Cornet-N cards */
@@ -153,16 +153,16 @@ typedef struct {
 #define HW_ID_DSRV_VOICE_P30M_V2_PCI 0xe019
 #define HW_ID_DSRV_B2F_PCI           0xe01a
 #define HW_ID_DSRV_VOICE_B2M_V2_PCI  0xe01b
-        /* Hardware IDs USB */
+/* Hardware IDs USB */
 #define EICON_USB_VENDOR_ID          0x071D
 #define HW_ID_DIVA_USB_REV1          0x1000
 #define HW_ID_DIVA_USB_REV2          0x1003
 #define HW_ID_TELEDAT_SURF_USB_REV2  0x1004
 #define HW_ID_TELEDAT_SURF_USB_REV1  0x2000
 /* --------------------------------------------------------------------------
-  Adapter array change notification framework
-  -------------------------------------------------------------------------- */
-typedef void (IDI_CALL_LINK_T* didd_adapter_change_callback_t)(     void IDI_CALL_ENTITY_T * context, DESCRIPTOR* adapter, int removal);
+   Adapter array change notification framework
+   -------------------------------------------------------------------------- */
+typedef void (IDI_CALL_LINK_T *didd_adapter_change_callback_t)(void IDI_CALL_ENTITY_T *context, DESCRIPTOR *adapter, int removal);
 /* -------------------------------------------------------------------------- */
 #define DI_VOICE          0x0 /* obsolete define */
 #define DI_FAX3           0x1
@@ -177,5 +177,5 @@ typedef void (IDI_CALL_LINK_T* didd_adapter_change_callback_t)(     void IDI_CAL
 #define DI_EXTD_FAX       0x0200 /* Extended FAX (ECM, 2D, T.6, Polling) */
 #define DI_AT_PARSER      0x0400 /* Build-in AT Parser in the L2 */
 #define DI_VOICE_OVER_IP  0x0800 /* Voice over IP support */
-typedef void (IDI_CALL_LINK_T* _IDI_CALL)(void*, ENTITY*);  
-#endif  
+typedef void (IDI_CALL_LINK_T *_IDI_CALL)(void *, ENTITY *);
+#endif
diff --git a/drivers/isdn/hardware/eicon/did_vers.h b/drivers/isdn/hardware/eicon/did_vers.h
index 538c590f..fa8db82 100644
--- a/drivers/isdn/hardware/eicon/did_vers.h
+++ b/drivers/isdn/hardware/eicon/did_vers.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
-static char diva_didd_common_code_build[] = "102-51";  
+static char diva_didd_common_code_build[] = "102-51";
diff --git a/drivers/isdn/hardware/eicon/diddfunc.c b/drivers/isdn/hardware/eicon/diddfunc.c
index 3029234..c4c8220 100644
--- a/drivers/isdn/hardware/eicon/diddfunc.c
+++ b/drivers/isdn/hardware/eicon/diddfunc.c
@@ -1,12 +1,12 @@
 /* $Id: diddfunc.c,v 1.14.6.2 2004/08/28 20:03:53 armin Exp $
  *
  * DIDD Interface module for Eicon active cards.
- * 
- * Functions are in dadapter.c 
- * 
- * Copyright 2002-2003 by Armin Schindler (mac@melware.de) 
+ *
+ * Functions are in dadapter.c
+ *
+ * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  */
@@ -28,12 +28,12 @@ static DESCRIPTOR _DAdapter;
 /*
  * didd callback function
  */
-static void *didd_callback(void *context, DESCRIPTOR * adapter,
+static void *didd_callback(void *context, DESCRIPTOR *adapter,
 			   int removal)
 {
 	if (adapter->type == IDI_DADAPTER) {
 		DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."))
-		return (NULL);
+			return (NULL);
 	} else if (adapter->type == IDI_DIMAINT) {
 		if (removal) {
 			DbgDeregister();
@@ -62,10 +62,10 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
 			memcpy(&_DAdapter, &DIDD_Table[x], sizeof(_DAdapter));
 			req.didd_notify.e.Req = 0;
 			req.didd_notify.e.Rc =
-			    IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+				IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 			req.didd_notify.info.callback = (void *)didd_callback;
 			req.didd_notify.info.context = NULL;
-			_DAdapter.request((ENTITY *) & req);
+			_DAdapter.request((ENTITY *)&req);
 			if (req.didd_notify.e.Rc != 0xff)
 				return (0);
 			notify_handle = req.didd_notify.info.handle;
@@ -86,7 +86,7 @@ static void DIVA_EXIT_FUNCTION disconnect_didd(void)
 	req.didd_notify.e.Req = 0;
 	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 	req.didd_notify.info.handle = notify_handle;
-	_DAdapter.request((ENTITY *) & req);
+	_DAdapter.request((ENTITY *)&req);
 }
 
 /*
@@ -98,7 +98,7 @@ int DIVA_INIT_FUNCTION diddfunc_init(void)
 
 	if (!connect_didd()) {
 		DBG_ERR(("init: failed to connect to DIDD."))
-		diva_didd_load_time_finit();
+			diva_didd_load_time_finit();
 		return (0);
 	}
 	return (1);
diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c
index 1403a54..d91dd58 100644
--- a/drivers/isdn/hardware/eicon/diva.c
+++ b/drivers/isdn/hardware/eicon/diva.c
@@ -28,12 +28,12 @@
 
 PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
 extern IDI_CALL Requests[MAX_ADAPTER];
-extern int create_adapter_proc(diva_os_xdi_adapter_t * a);
-extern void remove_adapter_proc(diva_os_xdi_adapter_t * a);
+extern int create_adapter_proc(diva_os_xdi_adapter_t *a);
+extern void remove_adapter_proc(diva_os_xdi_adapter_t *a);
 
-#define DivaIdiReqFunc(N) \
-static void DivaIdiRequest##N(ENTITY *e) \
-{ if ( IoAdapters[N] ) (* IoAdapters[N]->DIRequest)(IoAdapters[N], e) ; }
+#define DivaIdiReqFunc(N)						\
+	static void DivaIdiRequest##N(ENTITY *e)			\
+	{ if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
 
 /*
 **  Create own 32 Adapters
@@ -91,44 +91,44 @@ typedef struct _diva_supported_cards_info {
 static diva_supported_cards_info_t divas_supported_cards[] = {
 #ifdef CONFIG_ISDN_DIVAS_PRIPCI
 	/*
-	   PRI Cards
-	 */
+	  PRI Cards
+	*/
 	{CARDTYPE_DIVASRV_P_30M_PCI, diva_pri_init_card},
 	/*
-	   PRI Rev.2 Cards
-	 */
+	  PRI Rev.2 Cards
+	*/
 	{CARDTYPE_DIVASRV_P_30M_V2_PCI, diva_pri_init_card},
 	/*
-	   PRI Rev.2 VoIP Cards
-	 */
+	  PRI Rev.2 VoIP Cards
+	*/
 	{CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},
 #endif
 #ifdef CONFIG_ISDN_DIVAS_BRIPCI
 	/*
-	   4BRI Rev 1 Cards
-	 */
+	  4BRI Rev 1 Cards
+	*/
 	{CARDTYPE_DIVASRV_Q_8M_PCI, diva_4bri_init_card},
 	{CARDTYPE_DIVASRV_VOICE_Q_8M_PCI, diva_4bri_init_card},
 	/*
-	   4BRI Rev 2 Cards
-	 */
+	  4BRI Rev 2 Cards
+	*/
 	{CARDTYPE_DIVASRV_Q_8M_V2_PCI, diva_4bri_init_card},
 	{CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI, diva_4bri_init_card},
 	/*
-	   4BRI Based BRI Rev 2 Cards
-	 */
+	  4BRI Based BRI Rev 2 Cards
+	*/
 	{CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card},
 	{CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card},
 	{CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card},
 	/*
-	   BRI
-	 */
+	  BRI
+	*/
 	{CARDTYPE_MAESTRA_PCI, diva_bri_init_card},
 #endif
 
 	/*
-	   EOL
-	 */
+	  EOL
+	*/
 	{-1}
 };
 
@@ -150,18 +150,18 @@ static int diva_find_free_adapters(int base, int nr)
 	return (0);
 }
 
-static diva_os_xdi_adapter_t *diva_q_get_next(struct list_head * what)
+static diva_os_xdi_adapter_t *diva_q_get_next(struct list_head *what)
 {
 	diva_os_xdi_adapter_t *a = NULL;
 
 	if (what && (what->next != &adapter_queue))
 		a = list_entry(what->next, diva_os_xdi_adapter_t, link);
 
-	return(a);
+	return (a);
 }
 
 /* --------------------------------------------------------------------------
-    Add card to the card list
+   Add card to the card list
    -------------------------------------------------------------------------- */
 void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
 {
@@ -203,7 +203,7 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
 						 [CardOrdinal].Name,
 						 pdiva->controller))
 
-					diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
+						diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
 					pa = pdiva;
 					for (j = 1; j < nr; j++) {	/* slave adapters, if any */
 						pa = diva_q_get_next(&pa->link);
@@ -214,11 +214,11 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
 							diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
 							DBG_LOG(("add slave adapter (%d)",
 								 pa->controller))
-							create_adapter_proc(pa);	/* add adapter to proc file system */
+								create_adapter_proc(pa);	/* add adapter to proc file system */
 							diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card");
 						} else {
 							DBG_ERR(("slave adapter problem"))
-							break;
+								break;
 						}
 					}
 
@@ -230,10 +230,10 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
 			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card");
 
 			/*
-			   Not able to add adapter - remove it and return error
-			 */
+			  Not able to add adapter - remove it and return error
+			*/
 			DBG_ERR(("can not alloc request array"))
-			diva_driver_remove_card(pdiva);
+				diva_driver_remove_card(pdiva);
 
 			return NULL;
 		}
@@ -243,7 +243,7 @@ void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal)
 }
 
 /* --------------------------------------------------------------------------
-    Called on driver load, MAIN, main, DriverEntry
+   Called on driver load, MAIN, main, DriverEntry
    -------------------------------------------------------------------------- */
 int divasa_xdi_driver_entry(void)
 {
@@ -255,7 +255,7 @@ int divasa_xdi_driver_entry(void)
 }
 
 /* --------------------------------------------------------------------------
-    Remove adapter from list
+   Remove adapter from list
    -------------------------------------------------------------------------- */
 static diva_os_xdi_adapter_t *get_and_remove_from_queue(void)
 {
@@ -274,7 +274,7 @@ static diva_os_xdi_adapter_t *get_and_remove_from_queue(void)
 }
 
 /* --------------------------------------------------------------------------
-    Remove card from the card list
+   Remove card from the card list
    -------------------------------------------------------------------------- */
 void diva_driver_remove_card(void *pdiva)
 {
@@ -318,7 +318,7 @@ void diva_driver_remove_card(void *pdiva)
 }
 
 /* --------------------------------------------------------------------------
-    Create diva PCI adapter and init internal adapter structures
+   Create diva PCI adapter and init internal adapter structures
    -------------------------------------------------------------------------- */
 static void *divas_create_pci_card(int handle, void *pci_dev_handle)
 {
@@ -328,10 +328,10 @@ static void *divas_create_pci_card(int handle, void *pci_dev_handle)
 
 	DBG_LOG(("found %d-%s", pI->CardOrdinal, CardProperties[pI->CardOrdinal].Name))
 
-	if (!(a = (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) {
-		DBG_ERR(("A: can't alloc adapter"));
-		return NULL;
-	}
+		if (!(a = (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a)))) {
+			DBG_ERR(("A: can't alloc adapter"));
+			return NULL;
+		}
 
 	memset(a, 0x00, sizeof(*a));
 
@@ -344,9 +344,9 @@ static void *divas_create_pci_card(int handle, void *pci_dev_handle)
 	a->resources.pci.hdev = pci_dev_handle;
 
 	/*
-	   Add master adapter first, so slave adapters will receive higher
-	   numbers as master adapter
-	 */
+	  Add master adapter first, so slave adapters will receive higher
+	  numbers as master adapter
+	*/
 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
 	list_add_tail(&a->link, &adapter_queue);
 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "found_pci_card");
@@ -364,7 +364,7 @@ static void *divas_create_pci_card(int handle, void *pci_dev_handle)
 }
 
 /* --------------------------------------------------------------------------
-    Called on driver unload FINIT, finit, Unload
+   Called on driver unload FINIT, finit, Unload
    -------------------------------------------------------------------------- */
 void divasa_xdi_driver_unload(void)
 {
@@ -398,11 +398,11 @@ void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
 	if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
 		DBG_ERR(("A: A(?) open, msg too small (%d < %d)",
 			 length, sizeof(diva_xdi_um_cfg_cmd_t)))
-		return NULL;
+			return NULL;
 	}
 	if ((*cp_fn) (os_handle, &msg, src, sizeof(msg)) <= 0) {
 		DBG_ERR(("A: A(?) open, write error"))
-		return NULL;
+			return NULL;
 	}
 	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter");
 	list_for_each(tmp, &adapter_queue) {
@@ -415,7 +415,7 @@ void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
 
 	if (!a) {
 		DBG_ERR(("A: A(%d) open, adapter not found", msg.adapter))
-	}
+			}
 
 	return (a);
 }
@@ -443,19 +443,19 @@ diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
 
 	if (a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY) {
 		DBG_ERR(("A: A(%d) write, mbox busy", a->controller))
-		return (-1);
+			return (-1);
 	}
 
 	if (length < sizeof(diva_xdi_um_cfg_cmd_t)) {
 		DBG_ERR(("A: A(%d) write, message too small (%d < %d)",
 			 a->controller, length,
 			 sizeof(diva_xdi_um_cfg_cmd_t)))
-		return (-3);
+			return (-3);
 	}
 
 	if (!(data = diva_os_malloc(0, length))) {
 		DBG_ERR(("A: A(%d) write, ENOMEM", a->controller))
-		return (-2);
+			return (-2);
 	}
 
 	length = (*cp_fn) (os_handle, data, src, length);
@@ -467,7 +467,7 @@ diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
 	} else {
 		DBG_ERR(("A: A(%d) write error (%d)", a->controller,
 			 length))
-	}
+			}
 
 	diva_os_free(0, data);
 
@@ -486,23 +486,23 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
 
 	if (!(a->xdi_mbox.status & DIVA_XDI_MBOX_BUSY)) {
 		DBG_ERR(("A: A(%d) rx mbox empty", a->controller))
-		return (-1);
+			return (-1);
 	}
 	if (!a->xdi_mbox.data) {
 		a->xdi_mbox.status &= ~DIVA_XDI_MBOX_BUSY;
 		DBG_ERR(("A: A(%d) rx ENOMEM", a->controller))
-		return (-2);
+			return (-2);
 	}
 
 	if (max_length < a->xdi_mbox.data_length) {
 		DBG_ERR(("A: A(%d) rx buffer too short(%d < %d)",
 			 a->controller, max_length,
 			 a->xdi_mbox.data_length))
-		return (-3);
+			return (-3);
 	}
 
 	ret = (*cp_fn) (os_handle, dst, a->xdi_mbox.data,
-		      a->xdi_mbox.data_length);
+			a->xdi_mbox.data_length);
 	if (ret > 0) {
 		diva_os_free(0, a->xdi_mbox.data);
 		a->xdi_mbox.data = NULL;
@@ -577,33 +577,33 @@ void diva_xdi_display_adapter_features(int card)
 	features = IoAdapters[card]->Properties.Features;
 
 	DBG_LOG(("FEATURES FOR ADAPTER: %d", card + 1))
-	DBG_LOG((" DI_FAX3          :  %s",
-		     (features & DI_FAX3) ? "Y" : "N"))
-	DBG_LOG((" DI_MODEM         :  %s",
-		     (features & DI_MODEM) ? "Y" : "N"))
-	DBG_LOG((" DI_POST          :  %s",
-		     (features & DI_POST) ? "Y" : "N"))
-	DBG_LOG((" DI_V110          :  %s",
-		     (features & DI_V110) ? "Y" : "N"))
-	DBG_LOG((" DI_V120          :  %s",
-		     (features & DI_V120) ? "Y" : "N"))
-	DBG_LOG((" DI_POTS          :  %s",
-		     (features & DI_POTS) ? "Y" : "N"))
-	DBG_LOG((" DI_CODEC         :  %s",
-		     (features & DI_CODEC) ? "Y" : "N"))
-	DBG_LOG((" DI_MANAGE        :  %s",
-		     (features & DI_MANAGE) ? "Y" : "N"))
-	DBG_LOG((" DI_V_42          :  %s",
-		     (features & DI_V_42) ? "Y" : "N"))
-	DBG_LOG((" DI_EXTD_FAX      :  %s",
-		     (features & DI_EXTD_FAX) ? "Y" : "N"))
-	DBG_LOG((" DI_AT_PARSER     :  %s",
-		     (features & DI_AT_PARSER) ? "Y" : "N"))
-	DBG_LOG((" DI_VOICE_OVER_IP :  %s",
-		     (features & DI_VOICE_OVER_IP) ? "Y" : "N"))
-}
+		DBG_LOG((" DI_FAX3          :  %s",
+			 (features & DI_FAX3) ? "Y" : "N"))
+		DBG_LOG((" DI_MODEM         :  %s",
+			 (features & DI_MODEM) ? "Y" : "N"))
+		DBG_LOG((" DI_POST          :  %s",
+			 (features & DI_POST) ? "Y" : "N"))
+		DBG_LOG((" DI_V110          :  %s",
+			 (features & DI_V110) ? "Y" : "N"))
+		DBG_LOG((" DI_V120          :  %s",
+			 (features & DI_V120) ? "Y" : "N"))
+		DBG_LOG((" DI_POTS          :  %s",
+			 (features & DI_POTS) ? "Y" : "N"))
+		DBG_LOG((" DI_CODEC         :  %s",
+			 (features & DI_CODEC) ? "Y" : "N"))
+		DBG_LOG((" DI_MANAGE        :  %s",
+			 (features & DI_MANAGE) ? "Y" : "N"))
+		DBG_LOG((" DI_V_42          :  %s",
+			 (features & DI_V_42) ? "Y" : "N"))
+		DBG_LOG((" DI_EXTD_FAX      :  %s",
+			 (features & DI_EXTD_FAX) ? "Y" : "N"))
+		DBG_LOG((" DI_AT_PARSER     :  %s",
+			 (features & DI_AT_PARSER) ? "Y" : "N"))
+		DBG_LOG((" DI_VOICE_OVER_IP :  %s",
+			 (features & DI_VOICE_OVER_IP) ? "Y" : "N"))
+		}
 
-void diva_add_slave_adapter(diva_os_xdi_adapter_t * a)
+void diva_add_slave_adapter(diva_os_xdi_adapter_t *a)
 {
 	diva_os_spin_lock_magic_t old_irql;
 
@@ -612,7 +612,7 @@ void diva_add_slave_adapter(diva_os_xdi_adapter_t * a)
 	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add_slave");
 }
 
-int diva_card_read_xlog(diva_os_xdi_adapter_t * a)
+int diva_card_read_xlog(diva_os_xdi_adapter_t *a)
 {
 	diva_get_xlog_t *req;
 	byte *data;
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
index 5d06a74..d1d3de0 100644
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ b/drivers/isdn/hardware/eicon/diva_didd.c
@@ -1,12 +1,12 @@
 /* $Id: diva_didd.c,v 1.13.6.4 2005/02/11 19:40:25 armin Exp $
  *
  * DIDD Interface module for Eicon active cards.
- * 
- * Functions are in dadapter.c 
- * 
- * Copyright 2002-2003 by Armin Schindler (mac@melware.de) 
+ *
+ * Functions are in dadapter.c
+ *
+ * Copyright 2002-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2002-2003 Cytronics & Melware (info@melware.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  */
@@ -27,7 +27,7 @@
 static char *main_revision = "$Revision: 1.13.6.4 $";
 
 static char *DRIVERNAME =
-    "Eicon DIVA - DIDD table (http://www.melware.net)";
+	"Eicon DIVA - DIDD table (http://www.melware.net)";
 static char *DRIVERLNAME = "divadidd";
 char *DRIVERRELEASE_DIDD = "2.0";
 
@@ -72,7 +72,7 @@ static int divadidd_proc_show(struct seq_file *m, void *v)
 	seq_printf(m, "name     : %s\n", DRIVERLNAME);
 	seq_printf(m, "release  : %s\n", DRIVERRELEASE_DIDD);
 	seq_printf(m, "build    : %s(%s)\n",
-		       diva_didd_common_code_build, DIVA_BUILD);
+		   diva_didd_common_code_build, DIVA_BUILD);
 	seq_printf(m, "revision : %s\n", getrev(tmprev));
 
 	return 0;
@@ -137,7 +137,7 @@ static int DIVA_INIT_FUNCTION divadidd_init(void)
 		goto out;
 	}
 
-      out:
+out:
 	return (ret);
 }
 
diff --git a/drivers/isdn/hardware/eicon/diva_dma.c b/drivers/isdn/hardware/eicon/diva_dma.c
index f53a740..217b6aa 100644
--- a/drivers/isdn/hardware/eicon/diva_dma.c
+++ b/drivers/isdn/hardware/eicon/diva_dma.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -28,67 +28,67 @@
 /*
   Every entry has length of PAGE_SIZE
   and represents one single physical page
-  */
+*/
 struct _diva_dma_map_entry {
-  int   busy;
-  dword phys_bus_addr;  /* 32bit address as seen by the card */
-  void* local_ram_addr; /* local address as seen by the host */
-  void* addr_handle;    /* handle uset to free allocated memory */
+	int busy;
+	dword phys_bus_addr;  /* 32bit address as seen by the card */
+	void *local_ram_addr; /* local address as seen by the host */
+	void *addr_handle;    /* handle uset to free allocated memory */
 };
 /*
   Create local mapping structure and init it to default state
-  */
-struct _diva_dma_map_entry* diva_alloc_dma_map (void* os_context, int nentries) {
-  diva_dma_map_entry_t* pmap = diva_os_malloc(0, sizeof(*pmap)*(nentries+1));
-  if (pmap)
-	  memset (pmap, 0, sizeof(*pmap)*(nentries+1));
-  return pmap;
+*/
+struct _diva_dma_map_entry *diva_alloc_dma_map(void *os_context, int nentries) {
+	diva_dma_map_entry_t *pmap = diva_os_malloc(0, sizeof(*pmap) * (nentries + 1));
+	if (pmap)
+		memset(pmap, 0, sizeof(*pmap) * (nentries + 1));
+	return pmap;
 }
 /*
   Free local map (context should be freed before) if any
-  */
-void diva_free_dma_mapping (struct _diva_dma_map_entry* pmap) {
-  if (pmap) {
-    diva_os_free (0, pmap);
-  }
+*/
+void diva_free_dma_mapping(struct _diva_dma_map_entry *pmap) {
+	if (pmap) {
+		diva_os_free(0, pmap);
+	}
 }
 /*
   Set information saved on the map entry
-  */
-void diva_init_dma_map_entry (struct _diva_dma_map_entry* pmap,
-                              int nr, void* virt, dword phys,
-                              void* addr_handle) {
-  pmap[nr].phys_bus_addr  = phys;
-  pmap[nr].local_ram_addr = virt;
-  pmap[nr].addr_handle    = addr_handle;
+*/
+void diva_init_dma_map_entry(struct _diva_dma_map_entry *pmap,
+			     int nr, void *virt, dword phys,
+			     void *addr_handle) {
+	pmap[nr].phys_bus_addr  = phys;
+	pmap[nr].local_ram_addr = virt;
+	pmap[nr].addr_handle    = addr_handle;
 }
 /*
   Allocate one single entry in the map
-  */
-int diva_alloc_dma_map_entry (struct _diva_dma_map_entry* pmap) {
-  int i;
-  for (i = 0; (pmap && pmap[i].local_ram_addr); i++) {
-    if (!pmap[i].busy) {
-      pmap[i].busy = 1;
-      return (i);
-    }
-  }
-  return (-1);
+*/
+int diva_alloc_dma_map_entry(struct _diva_dma_map_entry *pmap) {
+	int i;
+	for (i = 0; (pmap && pmap[i].local_ram_addr); i++) {
+		if (!pmap[i].busy) {
+			pmap[i].busy = 1;
+			return (i);
+		}
+	}
+	return (-1);
 }
 /*
   Free one single entry in the map
-  */
-void diva_free_dma_map_entry (struct _diva_dma_map_entry* pmap, int nr) {
-  pmap[nr].busy = 0;
+*/
+void diva_free_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr) {
+	pmap[nr].busy = 0;
 }
 /*
   Get information saved on the map entry
-  */
-void diva_get_dma_map_entry (struct _diva_dma_map_entry* pmap, int nr,
-                             void** pvirt, dword* pphys) {
-  *pphys = pmap[nr].phys_bus_addr;
-  *pvirt = pmap[nr].local_ram_addr;
+*/
+void diva_get_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr,
+			    void **pvirt, dword *pphys) {
+	*pphys = pmap[nr].phys_bus_addr;
+	*pvirt = pmap[nr].local_ram_addr;
 }
-void* diva_get_entry_handle (struct _diva_dma_map_entry* pmap, int nr) {
-  return (pmap[nr].addr_handle);
+void *diva_get_entry_handle(struct _diva_dma_map_entry *pmap, int nr) {
+	return (pmap[nr].addr_handle);
 }
diff --git a/drivers/isdn/hardware/eicon/diva_dma.h b/drivers/isdn/hardware/eicon/diva_dma.h
index dff8072..d32c91b 100644
--- a/drivers/isdn/hardware/eicon/diva_dma.h
+++ b/drivers/isdn/hardware/eicon/diva_dma.h
@@ -1,48 +1,48 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_DMA_MAPPING_IFC_H__
 #define __DIVA_DMA_MAPPING_IFC_H__
 typedef struct _diva_dma_map_entry  diva_dma_map_entry_t;
-struct _diva_dma_map_entry* diva_alloc_dma_map (void* os_context, int nentries);
-void diva_init_dma_map_entry (struct _diva_dma_map_entry* pmap,
-                              int nr, void* virt, dword phys,
-                              void* addr_handle);
-int diva_alloc_dma_map_entry (struct _diva_dma_map_entry* pmap);
-void diva_free_dma_map_entry (struct _diva_dma_map_entry* pmap, int entry);
-void diva_get_dma_map_entry (struct _diva_dma_map_entry* pmap, int nr,
-                             void** pvirt, dword* pphys);
-void diva_free_dma_mapping (struct _diva_dma_map_entry* pmap);
+struct _diva_dma_map_entry *diva_alloc_dma_map(void *os_context, int nentries);
+void diva_init_dma_map_entry(struct _diva_dma_map_entry *pmap,
+			     int nr, void *virt, dword phys,
+			     void *addr_handle);
+int diva_alloc_dma_map_entry(struct _diva_dma_map_entry *pmap);
+void diva_free_dma_map_entry(struct _diva_dma_map_entry *pmap, int entry);
+void diva_get_dma_map_entry(struct _diva_dma_map_entry *pmap, int nr,
+			    void **pvirt, dword *pphys);
+void diva_free_dma_mapping(struct _diva_dma_map_entry *pmap);
 /*
   Functionality to be implemented by OS wrapper
   and running in process context
-  */
-void diva_init_dma_map (void* hdev,
-                        struct _diva_dma_map_entry** ppmap,
-                        int nentries);
-void diva_free_dma_map (void* hdev,
-                        struct _diva_dma_map_entry* pmap);
-void* diva_get_entry_handle (struct _diva_dma_map_entry* pmap, int nr);
+*/
+void diva_init_dma_map(void *hdev,
+		       struct _diva_dma_map_entry **ppmap,
+		       int nentries);
+void diva_free_dma_map(void *hdev,
+		       struct _diva_dma_map_entry *pmap);
+void *diva_get_entry_handle(struct _diva_dma_map_entry *pmap, int nr);
 #endif
diff --git a/drivers/isdn/hardware/eicon/diva_pci.h b/drivers/isdn/hardware/eicon/diva_pci.h
index cc0d510..bb4b562 100644
--- a/drivers/isdn/hardware/eicon/diva_pci.h
+++ b/drivers/isdn/hardware/eicon/diva_pci.h
@@ -4,9 +4,9 @@
 #define __DIVA_PCI_INTERFACE_H__
 
 void __iomem *divasa_remap_pci_bar(diva_os_xdi_adapter_t *a,
-			   int id,
-			   unsigned long bar,
-			   unsigned long area_length);
+				   int id,
+				   unsigned long bar,
+				   unsigned long area_length);
 void divasa_unmap_pci_bar(void __iomem *bar);
 unsigned long divasa_get_pci_irq(unsigned char bus,
 				 unsigned char func, void *pci_dev_handle);
diff --git a/drivers/isdn/hardware/eicon/divacapi.h b/drivers/isdn/hardware/eicon/divacapi.h
index e330da0..3942efb 100644
--- a/drivers/isdn/hardware/eicon/divacapi.h
+++ b/drivers/isdn/hardware/eicon/divacapi.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 
@@ -29,8 +29,8 @@
 
 
 
-  
-  
+
+
 
 
 
@@ -82,7 +82,7 @@
 #define CODEC_PERMANENT    0x02
 #define ADV_VOICE          0x03
 #define MAX_CIP_TYPES      5  /* kind of CIP types for group optimization */
-#define C_IND_MASK_DWORDS  ((MAX_APPL+32) >> 5)
+#define C_IND_MASK_DWORDS  ((MAX_APPL + 32) >> 5)
 
 
 #define FAX_CONNECT_INFO_BUFFER_SIZE  256
@@ -116,289 +116,289 @@ typedef struct msn_config_max_s MSN_CONFIG_MAX;
 typedef struct msn_ld_s MSN_LD;
 
 struct manufacturer_profile_s {
-  dword private_options;
-  dword rtp_primary_payloads;
-  dword rtp_additional_payloads;
+	dword private_options;
+	dword rtp_primary_payloads;
+	dword rtp_additional_payloads;
 };
 
 struct fax_ncpi_s {
-  word options;
-  word format;
+	word options;
+	word format;
 };
 
 struct msn_config_s {
-  byte msn[MAX_CPN_MASK_SIZE];
+	byte msn[MAX_CPN_MASK_SIZE];
 };
 
 struct msn_config_max_s {
-  MSN_CONFIG    msn_conf[MAX_MSN_CONFIG];
+	MSN_CONFIG    msn_conf[MAX_MSN_CONFIG];
 };
 
 struct msn_ld_s {
-  dword low;
-  dword high;
+	dword low;
+	dword high;
 };
 
 struct api_parse_s {
-  word          length;
-  byte   *    info;
+	word          length;
+	byte *info;
 };
 
 struct api_save_s {
-  API_PARSE     parms[MAX_MSG_PARMS+1];
-  byte          info[MAX_MSG_SIZE];
+	API_PARSE     parms[MAX_MSG_PARMS + 1];
+	byte          info[MAX_MSG_SIZE];
 };
 
 struct _DATA_B3_DESC {
-  word          Handle;
-  word          Number;
-  word          Flags;
-  word          Length;
-  void   *    P;
+	word          Handle;
+	word          Number;
+	word          Flags;
+	word          Length;
+	void *P;
 };
 
 struct _DATA_ACK_DESC {
-  word          Handle;
-  word          Number;
+	word          Handle;
+	word          Number;
 };
 
-typedef void (* t_std_internal_command)(dword Id, PLCI   *plci, byte Rc);
+typedef void (*t_std_internal_command)(dword Id, PLCI *plci, byte Rc);
 
 /************************************************************************/
 /* Don't forget to adapt dos.asm after changing the _APPL structure!!!! */
 struct _APPL {
-  word          Id;
-  word          NullCREnable;
-  word          CDEnable;
-  dword         S_Handle;
+	word          Id;
+	word          NullCREnable;
+	word          CDEnable;
+	dword         S_Handle;
 
 
 
 
 
 
-  LIST_ENTRY    s_function;
-  dword         s_context;
-  word          s_count;
-  APPL *        s_next;
-  byte *        xbuffer_used;
-  void **       xbuffer_internal;
-  void **       xbuffer_ptr;
+	LIST_ENTRY    s_function;
+	dword         s_context;
+	word          s_count;
+	APPL *s_next;
+	byte *xbuffer_used;
+	void **xbuffer_internal;
+	void **xbuffer_ptr;
 
 
 
 
 
 
-  byte   *    queue;
-  word          queue_size;
-  word          queue_free;
-  word          queue_read;
-  word          queue_write;
-  word          queue_signal;
-  byte          msg_lost;
-  byte          appl_flags;
-  word          Number;
+	byte *queue;
+	word          queue_size;
+	word          queue_free;
+	word          queue_read;
+	word          queue_write;
+	word          queue_signal;
+	byte          msg_lost;
+	byte          appl_flags;
+	word          Number;
 
-  word          MaxBuffer;
-  byte          MaxNCCI;
-  byte          MaxNCCIData;
-  word          MaxDataLength;
-  word          NCCIDataFlowCtrlTimer;
-  byte   *    ReceiveBuffer;
-  word   *    DataNCCI;
-  word   *    DataFlags;
+	word          MaxBuffer;
+	byte          MaxNCCI;
+	byte          MaxNCCIData;
+	word          MaxDataLength;
+	word          NCCIDataFlowCtrlTimer;
+	byte *ReceiveBuffer;
+	word *DataNCCI;
+	word *DataFlags;
 };
 
 
 struct _PLCI {
-  ENTITY        Sig;
-  ENTITY        NL;
-  word          RNum;
-  word          RFlags;
-  BUFFERS       RData[2];
-  BUFFERS       XData[1];
-  BUFFERS       NData[2];
-
-  DIVA_CAPI_ADAPTER   *adapter;
-  APPL      *appl;
-  PLCI      *relatedPTYPLCI;
-  byte          Id;
-  byte          State;
-  byte          sig_req;
-  byte          nl_req;
-  byte          SuppState;
-  byte          channels;
-  byte          tel;
-  byte          B1_resource;
-  byte          B2_prot;
-  byte          B3_prot;
-
-  word          command;
-  word          m_command;
-  word          internal_command;
-  word          number;
-  word          req_in_start;
-  word          req_in;
-  word          req_out;
-  word          msg_in_write_pos;
-  word          msg_in_read_pos;
-  word          msg_in_wrap_pos;
-
-  void   *    data_sent_ptr;
-  byte          data_sent;
-  byte          send_disc;
-  byte          sig_global_req;
-  byte          sig_remove_id;
-  byte          nl_global_req;
-  byte          nl_remove_id;
-  byte          b_channel;
-  byte          adv_nl;
-  byte          manufacturer;
-  byte          call_dir;
-  byte          hook_state;
-  byte          spoofed_msg;
-  byte          ptyState;
-  byte          cr_enquiry;
-  word          hangup_flow_ctrl_timer;
-
-  word          ncci_ring_list;
-  byte          inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI];
-  t_std_internal_command internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS];
-  dword         c_ind_mask_table[C_IND_MASK_DWORDS];
-  dword         group_optimization_mask_table[C_IND_MASK_DWORDS];
-  byte          RBuffer[200];
-  dword         msg_in_queue[MSG_IN_QUEUE_SIZE/sizeof(dword)];
-  API_SAVE      saved_msg;
-  API_SAVE      B_protocol;
-  byte          fax_connect_info_length;
-  byte          fax_connect_info_buffer[FAX_CONNECT_INFO_BUFFER_SIZE];
-  byte          fax_edata_ack_length;
-  word          nsf_control_bits;
-  byte          ncpi_state;
-  byte          ncpi_buffer[NCPI_BUFFER_SIZE];
-
-  byte          internal_req_buffer[INTERNAL_REQ_BUFFER_SIZE];
-  byte          internal_ind_buffer[INTERNAL_IND_BUFFER_SIZE + 3];
-  dword         requested_options_conn;
-  dword         requested_options;
-  word          B1_facilities;
-  API_SAVE   *adjust_b_parms_msg;
-  word          adjust_b_facilities;
-  word          adjust_b_command;
-  word          adjust_b_ncci;
-  word          adjust_b_mode;
-  word          adjust_b_state;
-  byte          adjust_b_restore;
-
-  byte          dtmf_rec_active;
-  word          dtmf_rec_pulse_ms;
-  word          dtmf_rec_pause_ms;
-  byte          dtmf_send_requests;
-  word          dtmf_send_pulse_ms;
-  word          dtmf_send_pause_ms;
-  word          dtmf_cmd;
-  word          dtmf_msg_number_queue[8];
-  byte          dtmf_parameter_length;
-  byte          dtmf_parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE];
-
-
-  t_capidtmf_state capidtmf_state;
-
-
-  byte          li_bchannel_id;    /* BRI: 1..2, PRI: 1..32 */
-  byte          li_channel_bits;
-  byte          li_notify_update;
-  word          li_cmd;
-  word          li_write_command;
-  word          li_write_channel;
-  word          li_plci_b_write_pos;
-  word          li_plci_b_read_pos;
-  word          li_plci_b_req_pos;
-  dword         li_plci_b_queue[LI_PLCI_B_QUEUE_ENTRIES];
-
-
-  word          ec_cmd;
-  word          ec_idi_options;
-  word          ec_tail_length;
-
-
-  byte          tone_last_indication_code;
-
-  byte          vswitchstate;
-  byte          vsprot;
-  byte          vsprotdialect;
-  byte          notifiedcall; /* Flag if it is a spoofed call */
-
-  int           rx_dma_descriptor;
-  dword         rx_dma_magic;
+	ENTITY        Sig;
+	ENTITY        NL;
+	word          RNum;
+	word          RFlags;
+	BUFFERS       RData[2];
+	BUFFERS       XData[1];
+	BUFFERS       NData[2];
+
+	DIVA_CAPI_ADAPTER   *adapter;
+	APPL      *appl;
+	PLCI      *relatedPTYPLCI;
+	byte          Id;
+	byte          State;
+	byte          sig_req;
+	byte          nl_req;
+	byte          SuppState;
+	byte          channels;
+	byte          tel;
+	byte          B1_resource;
+	byte          B2_prot;
+	byte          B3_prot;
+
+	word          command;
+	word          m_command;
+	word          internal_command;
+	word          number;
+	word          req_in_start;
+	word          req_in;
+	word          req_out;
+	word          msg_in_write_pos;
+	word          msg_in_read_pos;
+	word          msg_in_wrap_pos;
+
+	void *data_sent_ptr;
+	byte          data_sent;
+	byte          send_disc;
+	byte          sig_global_req;
+	byte          sig_remove_id;
+	byte          nl_global_req;
+	byte          nl_remove_id;
+	byte          b_channel;
+	byte          adv_nl;
+	byte          manufacturer;
+	byte          call_dir;
+	byte          hook_state;
+	byte          spoofed_msg;
+	byte          ptyState;
+	byte          cr_enquiry;
+	word          hangup_flow_ctrl_timer;
+
+	word          ncci_ring_list;
+	byte          inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI];
+	t_std_internal_command internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS];
+	dword         c_ind_mask_table[C_IND_MASK_DWORDS];
+	dword         group_optimization_mask_table[C_IND_MASK_DWORDS];
+	byte          RBuffer[200];
+	dword         msg_in_queue[MSG_IN_QUEUE_SIZE/sizeof(dword)];
+	API_SAVE      saved_msg;
+	API_SAVE      B_protocol;
+	byte          fax_connect_info_length;
+	byte          fax_connect_info_buffer[FAX_CONNECT_INFO_BUFFER_SIZE];
+	byte          fax_edata_ack_length;
+	word          nsf_control_bits;
+	byte          ncpi_state;
+	byte          ncpi_buffer[NCPI_BUFFER_SIZE];
+
+	byte          internal_req_buffer[INTERNAL_REQ_BUFFER_SIZE];
+	byte          internal_ind_buffer[INTERNAL_IND_BUFFER_SIZE + 3];
+	dword         requested_options_conn;
+	dword         requested_options;
+	word          B1_facilities;
+	API_SAVE   *adjust_b_parms_msg;
+	word          adjust_b_facilities;
+	word          adjust_b_command;
+	word          adjust_b_ncci;
+	word          adjust_b_mode;
+	word          adjust_b_state;
+	byte          adjust_b_restore;
+
+	byte          dtmf_rec_active;
+	word          dtmf_rec_pulse_ms;
+	word          dtmf_rec_pause_ms;
+	byte          dtmf_send_requests;
+	word          dtmf_send_pulse_ms;
+	word          dtmf_send_pause_ms;
+	word          dtmf_cmd;
+	word          dtmf_msg_number_queue[8];
+	byte          dtmf_parameter_length;
+	byte          dtmf_parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE];
+
+
+	t_capidtmf_state capidtmf_state;
+
+
+	byte          li_bchannel_id;    /* BRI: 1..2, PRI: 1..32 */
+	byte          li_channel_bits;
+	byte          li_notify_update;
+	word          li_cmd;
+	word          li_write_command;
+	word          li_write_channel;
+	word          li_plci_b_write_pos;
+	word          li_plci_b_read_pos;
+	word          li_plci_b_req_pos;
+	dword         li_plci_b_queue[LI_PLCI_B_QUEUE_ENTRIES];
+
+
+	word          ec_cmd;
+	word          ec_idi_options;
+	word          ec_tail_length;
+
+
+	byte          tone_last_indication_code;
+
+	byte          vswitchstate;
+	byte          vsprot;
+	byte          vsprotdialect;
+	byte          notifiedcall; /* Flag if it is a spoofed call */
+
+	int           rx_dma_descriptor;
+	dword         rx_dma_magic;
 };
 
 
 struct _NCCI {
-  byte          data_out;
-  byte          data_pending;
-  byte          data_ack_out;
-  byte          data_ack_pending;
-  DATA_B3_DESC  DBuffer[MAX_DATA_B3];
-  DATA_ACK_DESC DataAck[MAX_DATA_ACK];
+	byte          data_out;
+	byte          data_pending;
+	byte          data_ack_out;
+	byte          data_ack_pending;
+	DATA_B3_DESC  DBuffer[MAX_DATA_B3];
+	DATA_ACK_DESC DataAck[MAX_DATA_ACK];
 };
 
 
 struct _DIVA_CAPI_ADAPTER {
-  IDI_CALL      request;
-  byte          Id;
-  byte          max_plci;
-  byte          max_listen;
-  byte          listen_active;
-  PLCI      *plci;
-  byte          ch_ncci[MAX_NL_CHANNEL+1];
-  byte          ncci_ch[MAX_NCCI+1];
-  byte          ncci_plci[MAX_NCCI+1];
-  byte          ncci_state[MAX_NCCI+1];
-  byte          ncci_next[MAX_NCCI+1];
-  NCCI          ncci[MAX_NCCI+1];
-
-  byte          ch_flow_control[MAX_NL_CHANNEL+1];  /* Used by XON protocol */
-  byte          ch_flow_control_pending;
-  byte          ch_flow_plci[MAX_NL_CHANNEL+1];
-  int           last_flow_control_ch;
-
-  dword         Info_Mask[MAX_APPL];
-  dword         CIP_Mask[MAX_APPL];
-
-  dword         Notification_Mask[MAX_APPL];
-  PLCI      *codec_listen[MAX_APPL];
-  dword         requested_options_table[MAX_APPL];
-  API_PROFILE   profile;
-  MANUFACTURER_PROFILE man_profile;
-  dword         manufacturer_features;
-
-  byte          AdvCodecFLAG;
-  PLCI      *AdvCodecPLCI;
-  PLCI      *AdvSignalPLCI;
-  APPL      *AdvSignalAppl;
-  byte          TelOAD[23];
-  byte          TelOSA[23];
-  byte          scom_appl_disable;
-  PLCI      *automatic_lawPLCI;
-  byte          automatic_law;
-  byte          u_law;
-
-  byte          adv_voice_coef_length;
-  byte          adv_voice_coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE];
-
-  byte          li_pri;
-  byte          li_channels;
-  word          li_base;
-
-  byte adapter_disabled;
-  byte group_optimization_enabled; /* use application groups if enabled */
-  dword sdram_bar;
-  byte flag_dynamic_l1_down; /* for hunt groups:down layer 1 if no appl present*/
-  byte FlowControlIdTable[256];
-  byte FlowControlSkipTable[256];
-  void* os_card; /* pointer to associated OS dependent adapter structure */
+	IDI_CALL      request;
+	byte          Id;
+	byte          max_plci;
+	byte          max_listen;
+	byte          listen_active;
+	PLCI      *plci;
+	byte          ch_ncci[MAX_NL_CHANNEL + 1];
+	byte          ncci_ch[MAX_NCCI + 1];
+	byte          ncci_plci[MAX_NCCI + 1];
+	byte          ncci_state[MAX_NCCI + 1];
+	byte          ncci_next[MAX_NCCI + 1];
+	NCCI          ncci[MAX_NCCI + 1];
+
+	byte          ch_flow_control[MAX_NL_CHANNEL + 1];  /* Used by XON protocol */
+	byte          ch_flow_control_pending;
+	byte          ch_flow_plci[MAX_NL_CHANNEL + 1];
+	int           last_flow_control_ch;
+
+	dword         Info_Mask[MAX_APPL];
+	dword         CIP_Mask[MAX_APPL];
+
+	dword         Notification_Mask[MAX_APPL];
+	PLCI      *codec_listen[MAX_APPL];
+	dword         requested_options_table[MAX_APPL];
+	API_PROFILE   profile;
+	MANUFACTURER_PROFILE man_profile;
+	dword         manufacturer_features;
+
+	byte          AdvCodecFLAG;
+	PLCI      *AdvCodecPLCI;
+	PLCI      *AdvSignalPLCI;
+	APPL      *AdvSignalAppl;
+	byte          TelOAD[23];
+	byte          TelOSA[23];
+	byte          scom_appl_disable;
+	PLCI      *automatic_lawPLCI;
+	byte          automatic_law;
+	byte          u_law;
+
+	byte          adv_voice_coef_length;
+	byte          adv_voice_coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE];
+
+	byte          li_pri;
+	byte          li_channels;
+	word          li_base;
+
+	byte adapter_disabled;
+	byte group_optimization_enabled; /* use application groups if enabled */
+	dword sdram_bar;
+	byte flag_dynamic_l1_down; /* for hunt groups:down layer 1 if no appl present*/
+	byte FlowControlIdTable[256];
+	byte FlowControlSkipTable[256];
+	void *os_card; /* pointer to associated OS dependent adapter structure */
 };
 
 
@@ -451,23 +451,23 @@ struct _DIVA_CAPI_ADAPTER {
 
 typedef struct t30_info_s T30_INFO;
 struct t30_info_s {
-  byte          code;
-  byte          rate_div_2400;
-  byte          resolution;
-  byte          data_format;
-  byte          pages_low;
-  byte          pages_high;
-  byte          operating_mode;
-  byte          control_bits_low;
-  byte          control_bits_high;
-  byte          feature_bits_low;
-  byte          feature_bits_high;
-  byte          recording_properties;
-  byte          universal_6;
-  byte          universal_7;
-  byte          station_id_len;
-  byte          head_line_len;
-  byte          station_id[T30_MAX_STATION_ID_LENGTH];
+	byte          code;
+	byte          rate_div_2400;
+	byte          resolution;
+	byte          data_format;
+	byte          pages_low;
+	byte          pages_high;
+	byte          operating_mode;
+	byte          control_bits_low;
+	byte          control_bits_high;
+	byte          feature_bits_low;
+	byte          feature_bits_high;
+	byte          recording_properties;
+	byte          universal_6;
+	byte          universal_7;
+	byte          station_id_len;
+	byte          head_line_len;
+	byte          station_id[T30_MAX_STATION_ID_LENGTH];
 /* byte          head_line[];      */
 /* byte          sub_sep_length;   */
 /* byte          sub_sep_field[];  */
@@ -528,13 +528,13 @@ struct t30_info_s {
 #define T30_OPERATING_MODE_CAPI_NEG     4
 #define T30_OPERATING_MODE_COUNT        5
 
-        /* EDATA transmit messages */
+/* EDATA transmit messages */
 #define EDATA_T30_DIS         0x01
 #define EDATA_T30_FTT         0x02
 #define EDATA_T30_MCF         0x03
 #define EDATA_T30_PARAMETERS  0x04
 
-        /* EDATA receive messages */
+/* EDATA receive messages */
 #define EDATA_T30_DCS         0x81
 #define EDATA_T30_TRAIN_OK    0x82
 #define EDATA_T30_EOP         0x83
@@ -639,11 +639,11 @@ struct t30_info_s {
 
 typedef struct async_s ASYNC_FORMAT;
 struct async_s {
-  unsigned pe:    1;
-  unsigned parity:2;
-  unsigned spare: 2;
-  unsigned stp:   1;
-  unsigned ch_len:2;   /* 3th octett in CAI */
+	unsigned pe:1;
+	unsigned parity:2;
+	unsigned spare:2;
+	unsigned stp:1;
+	unsigned ch_len:2;   /* 3th octett in CAI */
 };
 
 
@@ -686,14 +686,14 @@ struct async_s {
 /*------------------------------------------------------------------*/
 /* Capi IE + Msg types                                              */
 /*------------------------------------------------------------------*/
-#define ESC_CAUSE        0x800|CAU          /* Escape cause element */
-#define ESC_MSGTYPE      0x800|MSGTYPEIE    /* Escape message type  */
-#define ESC_CHI          0x800|CHI          /* Escape channel id    */
-#define ESC_LAW          0x800|BC           /* Escape law info      */
-#define ESC_CR           0x800|CRIE         /* Escape CallReference */
-#define ESC_PROFILE      0x800|PROFILEIE    /* Escape profile       */
-#define ESC_SSEXT        0x800|SSEXTIE      /* Escape Supplem. Serv.*/
-#define ESC_VSWITCH      0x800|VSWITCHIE    /* Escape VSwitch       */
+#define ESC_CAUSE        0x800 | CAU        /* Escape cause element */
+#define ESC_MSGTYPE      0x800 | MSGTYPEIE  /* Escape message type  */
+#define ESC_CHI          0x800 | CHI        /* Escape channel id    */
+#define ESC_LAW          0x800 | BC         /* Escape law info      */
+#define ESC_CR           0x800 | CRIE       /* Escape CallReference */
+#define ESC_PROFILE      0x800 | PROFILEIE  /* Escape profile       */
+#define ESC_SSEXT        0x800 | SSEXTIE    /* Escape Supplem. Serv.*/
+#define ESC_VSWITCH      0x800 | VSWITCHIE  /* Escape VSwitch       */
 #define CST              0x14               /* Call State i.e.      */
 #define PI               0x1E               /* Progress Indicator   */
 #define NI               0x27               /* Notification Ind     */
@@ -903,25 +903,25 @@ struct async_s {
 typedef struct li_config_s LI_CONFIG;
 
 struct xconnect_card_address_s {
-  dword low;
-  dword high;
+	dword low;
+	dword high;
 };
 
 struct xconnect_transfer_address_s {
-  struct xconnect_card_address_s card_address;
-  dword offset;
+	struct xconnect_card_address_s card_address;
+	dword offset;
 };
 
 struct li_config_s {
-  DIVA_CAPI_ADAPTER   *adapter;
-  PLCI   *plci;
-  struct xconnect_transfer_address_s send_b;
-  struct xconnect_transfer_address_s send_pc;
-  byte   *flag_table;  /* dword aligned and sized */
-  byte   *coef_table;  /* dword aligned and sized */
-  byte channel;
-  byte curchnl;
-  byte chflags;
+	DIVA_CAPI_ADAPTER   *adapter;
+	PLCI   *plci;
+	struct xconnect_transfer_address_s send_b;
+	struct xconnect_transfer_address_s send_pc;
+	byte   *flag_table;  /* dword aligned and sized */
+	byte   *coef_table;  /* dword aligned and sized */
+	byte channel;
+	byte curchnl;
+	byte chflags;
 };
 
 extern LI_CONFIG   *li_config_table;
@@ -1110,33 +1110,33 @@ extern word li_total_channels;
 #define B1_PIAFS                29
 #define B2_PIAFS                29
 
-#define PRIVATE_PIAFS           29 
+#define PRIVATE_PIAFS           29
 
 /*
   B2 configuration for PIAFS:
-+---------------------+------+-----------------------------------------+
-| PIAFS Protocol      | byte | Bit 1 - Protocol Speed                  |
-| Speed configuration |      |         0 - 32K                         |
-|                     |      |         1 - 64K (default)               |
-|                     |      | Bit 2 - Variable Protocol Speed         |
-|                     |      |         0 - Speed is fix                |
-|                     |      |         1 - Speed is variable (default) |
-+---------------------+------+-----------------------------------------+
-| Direction           | word | Enable compression/decompression for    |
-|                     |      | 0: All direction                        |
-|                     |      | 1: disable outgoing data                |
-|                     |      | 2: disable incomming data               |
-|                     |      | 3: disable both direction (default)     |
-+---------------------+------+-----------------------------------------+
-| Number of code      | word | Parameter P1 of V.42bis in accordance   |
-| words               |      | with V.42bis                            |
-+---------------------+------+-----------------------------------------+
-| Maximum String      | word | Parameter P2 of V.42bis in accordance   |
-| Length              |      | with V.42bis                            |
-+---------------------+------+-----------------------------------------+
-| control (UDATA)     | byte | enable PIAFS control communication      |
-| abilities           |      |                                         |
-+---------------------+------+-----------------------------------------+
+  +---------------------+------+-----------------------------------------+
+  | PIAFS Protocol      | byte | Bit 1 - Protocol Speed                  |
+  | Speed configuration |      |         0 - 32K                         |
+  |                     |      |         1 - 64K (default)               |
+  |                     |      | Bit 2 - Variable Protocol Speed         |
+  |                     |      |         0 - Speed is fix                |
+  |                     |      |         1 - Speed is variable (default) |
+  +---------------------+------+-----------------------------------------+
+  | Direction           | word | Enable compression/decompression for    |
+  |                     |      | 0: All direction                        |
+  |                     |      | 1: disable outgoing data                |
+  |                     |      | 2: disable incomming data               |
+  |                     |      | 3: disable both direction (default)     |
+  +---------------------+------+-----------------------------------------+
+  | Number of code      | word | Parameter P1 of V.42bis in accordance   |
+  | words               |      | with V.42bis                            |
+  +---------------------+------+-----------------------------------------+
+  | Maximum String      | word | Parameter P2 of V.42bis in accordance   |
+  | Length              |      | with V.42bis                            |
+  +---------------------+------+-----------------------------------------+
+  | control (UDATA)     | byte | enable PIAFS control communication      |
+  | abilities           |      |                                         |
+  +---------------------+------+-----------------------------------------+
 */
 #define PIAFS_UDATA_ABILITIES  0x80
 
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index f1d464f..ffa0c31 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -38,7 +38,7 @@ static unsigned long diva_dbg_mem = 0;
 module_param(diva_dbg_mem, ulong, 0);
 
 static char *DRIVERNAME =
-    "Eicon DIVA - MAINT module (http://www.melware.net)";
+	"Eicon DIVA - MAINT module (http://www.melware.net)";
 static char *DRIVERLNAME = "diva_mnt";
 static char *DEVNAME = "DivasMAINT";
 char *DRIVERRELEASE_MNT = "2.0";
@@ -86,7 +86,7 @@ int diva_os_copy_from_user(void *os_handle, void *dst, const void __user *src,
 /*
  * get time
  */
-void diva_os_get_time(dword * sec, dword * usec)
+void diva_os_get_time(dword *sec, dword *usec)
 {
 	struct timeval tv;
 
@@ -115,7 +115,7 @@ void diva_os_get_time(dword * sec, dword * usec)
 /*
  * device node operations
  */
-static unsigned int maint_poll(struct file *file, poll_table * wait)
+static unsigned int maint_poll(struct file *file, poll_table *wait)
 {
 	unsigned int mask = 0;
 
@@ -153,18 +153,18 @@ static int maint_close(struct inode *ino, struct file *filep)
 
 	/* clear 'used' flag */
 	clear_bit(0, &opened);
-	
+
 	return (0);
 }
 
 static ssize_t divas_maint_write(struct file *file, const char __user *buf,
-				 size_t count, loff_t * ppos)
+				 size_t count, loff_t *ppos)
 {
 	return (maint_read_write((char __user *) buf, (int) count));
 }
 
 static ssize_t divas_maint_read(struct file *file, char __user *buf,
-				size_t count, loff_t * ppos)
+				size_t count, loff_t *ppos)
 {
 	return (maint_read_write(buf, (int) count));
 }
@@ -238,7 +238,7 @@ static int DIVA_INIT_FUNCTION maint_init(void)
 	       DRIVERLNAME, buffer, (buffer_length / 1024),
 	       (diva_dbg_mem == 0) ? "internal" : "external", major);
 
-      out:
+out:
 	return (ret);
 }
 
@@ -255,4 +255,3 @@ static void DIVA_EXIT_FUNCTION maint_exit(void)
 
 module_init(maint_init);
 module_exit(maint_exit);
-
diff --git a/drivers/isdn/hardware/eicon/divasfunc.c b/drivers/isdn/hardware/eicon/divasfunc.c
index 0bbee78..60aaf95 100644
--- a/drivers/isdn/hardware/eicon/divasfunc.c
+++ b/drivers/isdn/hardware/eicon/divasfunc.c
@@ -34,7 +34,7 @@ static DESCRIPTOR DAdapter;
 static DESCRIPTOR MAdapter;
 
 /* --------------------------------------------------------------------------
-    MAINT driver connector section
+   MAINT driver connector section
    -------------------------------------------------------------------------- */
 static void no_printf(unsigned char *x, ...)
 {
@@ -74,17 +74,17 @@ void diva_xdi_didd_register_adapter(int card)
 		d.features = IoAdapters[card - 1]->Properties.Features;
 		DBG_TRC(("DIDD register A(%d) channels=%d", card,
 			 d.channels))
-		    /* workaround for different Name in structure */
-		    strlcpy(IoAdapters[card - 1]->Name,
-			    IoAdapters[card - 1]->Properties.Name,
-			    sizeof(IoAdapters[card - 1]->Name));
+			/* workaround for different Name in structure */
+			strlcpy(IoAdapters[card - 1]->Name,
+				IoAdapters[card - 1]->Properties.Name,
+				sizeof(IoAdapters[card - 1]->Name));
 		req.didd_remove_adapter.e.Req = 0;
 		req.didd_add_adapter.e.Rc = IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
 		req.didd_add_adapter.info.descriptor = (void *) &d;
-		DAdapter.request((ENTITY *) & req);
+		DAdapter.request((ENTITY *)&req);
 		if (req.didd_add_adapter.e.Rc != 0xff) {
 			DBG_ERR(("DIDD register A(%d) failed !", card))
-		}
+				}
 		IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
 	}
 }
@@ -99,11 +99,11 @@ void diva_xdi_didd_remove_adapter(int card)
 
 	IoAdapters[card - 1]->os_trap_nfy_Fnc = NULL;
 	DBG_TRC(("DIDD de-register A(%d)", card))
-	req.didd_remove_adapter.e.Req = 0;
+		req.didd_remove_adapter.e.Req = 0;
 	req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;
 	req.didd_remove_adapter.info.p_request =
-	    (IDI_CALL) Requests[card - 1];
-	DAdapter.request((ENTITY *) & req);
+		(IDI_CALL) Requests[card - 1];
+	DAdapter.request((ENTITY *)&req);
 	memset(&(a->IdTable), 0x00, 256);
 }
 
@@ -115,7 +115,7 @@ static void start_dbg(void)
 	DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
 	DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])",
 		 DIVA_BUILD, diva_xdi_common_code_build))
-}
+		}
 
 /*
  * stop debug
@@ -130,7 +130,7 @@ static void stop_dbg(void)
 /*
  * didd callback function
  */
-static void *didd_callback(void *context, DESCRIPTOR * adapter,
+static void *didd_callback(void *context, DESCRIPTOR *adapter,
 			   int removal)
 {
 	if (adapter->type == IDI_DADAPTER) {
@@ -168,10 +168,10 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
 			memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
 			req.didd_notify.e.Req = 0;
 			req.didd_notify.e.Rc =
-			    IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+				IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 			req.didd_notify.info.callback = (void *)didd_callback;
 			req.didd_notify.info.context = NULL;
-			DAdapter.request((ENTITY *) & req);
+			DAdapter.request((ENTITY *)&req);
 			if (req.didd_notify.e.Rc != 0xff) {
 				stop_dbg();
 				return (0);
@@ -203,7 +203,7 @@ static void disconnect_didd(void)
 	req.didd_notify.e.Req = 0;
 	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 	req.didd_notify.info.handle = notify_handle;
-	DAdapter.request((ENTITY *) & req);
+	DAdapter.request((ENTITY *)&req);
 }
 
 /*
@@ -214,10 +214,10 @@ int DIVA_INIT_FUNCTION divasfunc_init(int dbgmask)
 	char *version;
 
 	debugmask = dbgmask;
-	
+
 	if (!connect_didd()) {
 		DBG_ERR(("divasfunc: failed to connect to DIDD."))
-		return (0);
+			return (0);
 	}
 
 	version = diva_xdi_common_code_build;
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 42d3b834..a5c8f90 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -1,7 +1,7 @@
 /* $Id: divasi.c,v 1.25.6.2 2005/01/31 12:22:20 armin Exp $
  *
  * Driver for Eicon DIVA Server ISDN cards.
- * User Mode IDI Interface 
+ * User Mode IDI Interface
  *
  * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
@@ -71,10 +71,10 @@ static char *getrev(const char *revision)
  *  LOCALS
  */
 static ssize_t um_idi_read(struct file *file, char __user *buf, size_t count,
-			   loff_t * offset);
+			   loff_t *offset);
 static ssize_t um_idi_write(struct file *file, const char __user *buf,
-			    size_t count, loff_t * offset);
-static unsigned int um_idi_poll(struct file *file, poll_table * wait);
+			    size_t count, loff_t *offset);
+static unsigned int um_idi_poll(struct file *file, poll_table *wait);
 static int um_idi_open(struct inode *inode, struct file *file);
 static int um_idi_release(struct inode *inode, struct file *file);
 static int remove_entity(void *entity);
@@ -194,7 +194,7 @@ static int DIVA_INIT_FUNCTION divasi_init(void)
 	}
 	printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
 
-      out:
+out:
 	return (ret);
 }
 
@@ -228,7 +228,7 @@ divas_um_idi_copy_to_user(void *os_handle, void *dst, const void *src,
 }
 
 static ssize_t
-um_idi_read(struct file *file, char __user *buf, size_t count, loff_t * offset)
+um_idi_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
 	diva_um_idi_os_context_t *p_os;
 	int ret = -EINVAL;
@@ -292,7 +292,7 @@ static int um_idi_open_adapter(struct file *file, int adapter_nr)
 {
 	diva_um_idi_os_context_t *p_os;
 	void *e =
-	    divas_um_idi_create_entity((dword) adapter_nr, (void *) file);
+		divas_um_idi_create_entity((dword) adapter_nr, (void *) file);
 
 	if (!(file->private_data = e)) {
 		return (0);
@@ -310,7 +310,7 @@ static int um_idi_open_adapter(struct file *file, int adapter_nr)
 
 static ssize_t
 um_idi_write(struct file *file, const char __user *buf, size_t count,
-	     loff_t * offset)
+	     loff_t *offset)
 {
 	diva_um_idi_os_context_t *p_os;
 	int ret = -EINVAL;
@@ -331,8 +331,8 @@ um_idi_write(struct file *file, const char __user *buf, size_t count,
 	}
 
 	if (!(p_os =
-	     (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->
-								    private_data)))
+	      (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->
+								     private_data)))
 	{
 		return (-ENODEV);
 	}
@@ -367,7 +367,7 @@ um_idi_write(struct file *file, const char __user *buf, size_t count,
 	return (ret);
 }
 
-static unsigned int um_idi_poll(struct file *file, poll_table * wait)
+static unsigned int um_idi_poll(struct file *file, poll_table *wait)
 {
 	diva_um_idi_os_context_t *p_os;
 
@@ -417,7 +417,7 @@ static int um_idi_release(struct inode *inode, struct file *file)
 	}
 
 	if (!(p_os =
-		(diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
+	      (diva_um_idi_os_context_t *) diva_um_id_get_os_context(file->private_data))) {
 		ret = -ENODEV;
 		goto out;
 	}
@@ -434,7 +434,7 @@ static int um_idi_release(struct inode *inode, struct file *file)
 		goto out;
 	}
 
-      out:
+out:
 	return (ret);
 }
 
@@ -446,14 +446,14 @@ int diva_os_get_context_size(void)
 void diva_os_wakeup_read(void *os_context)
 {
 	diva_um_idi_os_context_t *p_os =
-	    (diva_um_idi_os_context_t *) os_context;
+		(diva_um_idi_os_context_t *) os_context;
 	wake_up_interruptible(&p_os->read_wait);
 }
 
 void diva_os_wakeup_close(void *os_context)
 {
 	diva_um_idi_os_context_t *p_os =
-	    (diva_um_idi_os_context_t *) os_context;
+		(diva_um_idi_os_context_t *) os_context;
 	wake_up_interruptible(&p_os->close_wait);
 }
 
@@ -466,7 +466,7 @@ void diva_um_timer_function(unsigned long data)
 	wake_up_interruptible(&p_os->read_wait);
 	wake_up_interruptible(&p_os->close_wait);
 	DBG_ERR(("entity removal watchdog"))
-}
+		}
 
 /*
 **  If application exits without entity removal this function will remove
@@ -481,30 +481,30 @@ static int remove_entity(void *entity)
 
 	if (!entity) {
 		DBG_FTL(("Zero entity on remove"))
-		return (0);
+			return (0);
 	}
 
 	if (!(p_os =
-	     (diva_um_idi_os_context_t *)
-	     diva_um_id_get_os_context(entity))) {
+	      (diva_um_idi_os_context_t *)
+	      diva_um_id_get_os_context(entity))) {
 		DBG_FTL(("Zero entity os context on remove"))
-		return (0);
+			return (0);
 	}
 
 	if (!divas_um_idi_entity_assigned(entity) || p_os->aborted) {
 		/*
-		   Entity is not assigned, also can be removed
-		 */
+		  Entity is not assigned, also can be removed
+		*/
 		return (0);
 	}
 
 	DBG_TRC(("E(%08x) check remove", entity))
 
-	/*
-	   If adapter not answers on remove request inside of
-	   10 Sec, then adapter is dead
-	 */
-	diva_um_idi_start_wdog(entity);
+		/*
+		  If adapter not answers on remove request inside of
+		  10 Sec, then adapter is dead
+		*/
+		diva_um_idi_start_wdog(entity);
 
 	{
 		DECLARE_WAITQUEUE(wait, curtask);
@@ -542,7 +542,7 @@ static int remove_entity(void *entity)
 	DBG_TRC(("E(%08x) remove complete, aborted:%d", entity,
 		 p_os->aborted))
 
-	diva_um_idi_stop_wdog(entity);
+		diva_um_idi_stop_wdog(entity);
 
 	p_os->aborted = 0;
 
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index f332b60..7eaab06 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -50,7 +50,7 @@ module_param(dbgmask, int, 0);
 MODULE_PARM_DESC(dbgmask, "initial debug mask");
 
 static char *DRIVERNAME =
-    "Eicon DIVA Server driver (http://www.melware.net)";
+	"Eicon DIVA Server driver (http://www.melware.net)";
 static char *DRIVERLNAME = "divas";
 static char *DEVNAME = "Divas";
 char *DRIVERRELEASE_DIVAS = "2.0";
@@ -68,7 +68,7 @@ typedef struct _diva_os_thread_dpc {
 } diva_os_thread_dpc_t;
 
 /* --------------------------------------------------------------------------
-    PCI driver interface section
+   PCI driver interface section
    -------------------------------------------------------------------------- */
 /*
   vendor, device	Vendor and device ID to match (or PCI_ANY_ID)
@@ -77,7 +77,7 @@ typedef struct _diva_os_thread_dpc {
   class,		Device class to match. The class_mask tells which bits
   class_mask	of the class are honored during the comparison.
   driver_data	Data private to the driver.
-  */
+*/
 
 #if !defined(PCI_DEVICE_ID_EICON_MAESTRAP_2)
 #define PCI_DEVICE_ID_EICON_MAESTRAP_2       0xE015
@@ -109,41 +109,41 @@ typedef struct _diva_os_thread_dpc {
 
 /*
   This table should be sorted by PCI device ID
-  */
+*/
 static struct pci_device_id divas_pci_tbl[] = {
 	/* Diva Server BRI-2M PCI 0xE010 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRA),
-		CARDTYPE_MAESTRA_PCI },
+	  CARDTYPE_MAESTRA_PCI },
 	/* Diva Server 4BRI-8M PCI 0xE012 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ),
-		CARDTYPE_DIVASRV_Q_8M_PCI },
+	  CARDTYPE_DIVASRV_Q_8M_PCI },
 	/* Diva Server 4BRI-8M 2.0 PCI 0xE013 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAQ_U),
-		CARDTYPE_DIVASRV_Q_8M_V2_PCI },
+	  CARDTYPE_DIVASRV_Q_8M_V2_PCI },
 	/* Diva Server PRI-30M PCI 0xE014 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP),
-		CARDTYPE_DIVASRV_P_30M_PCI },
+	  CARDTYPE_DIVASRV_P_30M_PCI },
 	/* Diva Server PRI 2.0 adapter 0xE015 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2),
-		CARDTYPE_DIVASRV_P_30M_V2_PCI },
+	  CARDTYPE_DIVASRV_P_30M_V2_PCI },
 	/* Diva Server Voice 4BRI-8M PCI 0xE016 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_VOIP),
-		CARDTYPE_DIVASRV_VOICE_Q_8M_PCI },
+	  CARDTYPE_DIVASRV_VOICE_Q_8M_PCI },
 	/* Diva Server Voice 4BRI-8M 2.0 PCI 0xE017 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_4BRI_2_VOIP),
-		CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI },
+	  CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI },
 	/* Diva Server BRI-2M 2.0 PCI 0xE018 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2),
-		CARDTYPE_DIVASRV_B_2M_V2_PCI },
+	  CARDTYPE_DIVASRV_B_2M_V2_PCI },
 	/* Diva Server Voice PRI 2.0 PCI 0xE019 */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_MAESTRAP_2_VOIP),
-		CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI },
+	  CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI },
 	/* Diva Server 2FX 0xE01A */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_2F),
-		CARDTYPE_DIVASRV_B_2F_PCI },
+	  CARDTYPE_DIVASRV_B_2F_PCI },
 	/* Diva Server Voice BRI-2M 2.0 PCI 0xE01B */
 	{ PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_BRI2M_2_VOIP),
-		CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI },
+	  CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI },
 	{ 0, }			/* 0 terminated list. */
 };
 MODULE_DEVICE_TABLE(pci, divas_pci_tbl);
@@ -197,7 +197,7 @@ void divas_get_version(char *p)
 }
 
 /* --------------------------------------------------------------------------
-    PCI Bus services  
+   PCI Bus services
    -------------------------------------------------------------------------- */
 byte diva_os_get_pci_bus(void *pci_dev_handle)
 {
@@ -332,10 +332,10 @@ void PCIread(byte bus, byte func, int offset, void *data, int length,
   Init map with DMA pages. It is not problem if some allocations fail -
   the channels that will not get one DMA page will use standard PIO
   interface
-  */
+*/
 static void *diva_pci_alloc_consistent(struct pci_dev *hwdev,
 				       size_t size,
-				       dma_addr_t * dma_handle,
+				       dma_addr_t *dma_handle,
 				       void **addr_handle)
 {
 	void *addr = pci_alloc_consistent(hwdev, size, dma_handle);
@@ -350,7 +350,7 @@ void diva_init_dma_map(void *hdev,
 {
 	struct pci_dev *pdev = (struct pci_dev *) hdev;
 	struct _diva_dma_map_entry *pmap =
-	    diva_alloc_dma_map(hdev, nentries);
+		diva_alloc_dma_map(hdev, nentries);
 
 	if (pmap) {
 		int i;
@@ -381,7 +381,7 @@ void diva_init_dma_map(void *hdev,
 /*
   Free all contained in the map entries and memory used by the map
   Should be always called after adapter removal from DIDD array
-  */
+*/
 void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap)
 {
 	struct pci_dev *pdev = (struct pci_dev *) hdev;
@@ -403,14 +403,14 @@ void diva_free_dma_map(void *hdev, struct _diva_dma_map_entry *pmap)
 		DBG_TRC(("dma map free [%d]=(%08lx:%08x:%08lx)", i,
 			 (unsigned long) cpu_addr, (dword) dma_handle,
 			 (unsigned long) addr_handle))
-	}
+			}
 
 	diva_free_dma_mapping(pmap);
 }
 
 
 /*********************************************************
- ** I/O port utilities  
+ ** I/O port utilities
  *********************************************************/
 
 int
@@ -420,7 +420,7 @@ diva_os_register_io_port(void *adapter, int on, unsigned long port,
 	if (on) {
 		if (!request_region(port, length, name)) {
 			DBG_ERR(("A: I/O: can't register port=%08x", port))
-			return (-1);
+				return (-1);
 		}
 	} else {
 		release_region(port, length);
@@ -443,7 +443,7 @@ void divasa_unmap_pci_bar(void __iomem *bar)
 }
 
 /*********************************************************
- ** I/O port access 
+ ** I/O port access
  *********************************************************/
 byte __inline__ inpp(void __iomem *addr)
 {
@@ -476,7 +476,7 @@ void __inline__ outpp(void __iomem *addr, word p)
 }
 
 /* --------------------------------------------------------------------------
-    IRQ request / remove  
+   IRQ request / remove
    -------------------------------------------------------------------------- */
 int diva_os_register_irq(void *context, byte irq, const char *name)
 {
@@ -491,7 +491,7 @@ void diva_os_remove_irq(void *context, byte irq)
 }
 
 /* --------------------------------------------------------------------------
-    DPC framework implementation
+   DPC framework implementation
    -------------------------------------------------------------------------- */
 static void diva_os_dpc_proc(unsigned long context)
 {
@@ -501,7 +501,7 @@ static void diva_os_dpc_proc(unsigned long context)
 	(*(pisr->callback)) (pisr, pisr->callback_context);
 }
 
-int diva_os_initialize_soft_isr(diva_os_soft_isr_t * psoft_isr,
+int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr,
 				diva_os_soft_isr_callback_t callback,
 				void *callback_context)
 {
@@ -520,11 +520,11 @@ int diva_os_initialize_soft_isr(diva_os_soft_isr_t * psoft_isr,
 	return (0);
 }
 
-int diva_os_schedule_soft_isr(diva_os_soft_isr_t * psoft_isr)
+int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr)
 {
 	if (psoft_isr && psoft_isr->object) {
 		diva_os_thread_dpc_t *pdpc =
-		    (diva_os_thread_dpc_t *) psoft_isr->object;
+			(diva_os_thread_dpc_t *) psoft_isr->object;
 
 		tasklet_schedule(&pdpc->divas_task);
 	}
@@ -532,16 +532,16 @@ int diva_os_schedule_soft_isr(diva_os_soft_isr_t * psoft_isr)
 	return (1);
 }
 
-int diva_os_cancel_soft_isr(diva_os_soft_isr_t * psoft_isr)
+int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr)
 {
 	return (0);
 }
 
-void diva_os_remove_soft_isr(diva_os_soft_isr_t * psoft_isr)
+void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr)
 {
 	if (psoft_isr && psoft_isr->object) {
 		diva_os_thread_dpc_t *pdpc =
-		    (diva_os_thread_dpc_t *) psoft_isr->object;
+			(diva_os_thread_dpc_t *) psoft_isr->object;
 		void *mem;
 
 		tasklet_kill(&pdpc->divas_task);
@@ -589,7 +589,7 @@ static int divas_release(struct inode *inode, struct file *file)
 }
 
 static ssize_t divas_write(struct file *file, const char __user *buf,
-			   size_t count, loff_t * ppos)
+			   size_t count, loff_t *ppos)
 {
 	int ret = -EINVAL;
 
@@ -620,7 +620,7 @@ static ssize_t divas_write(struct file *file, const char __user *buf,
 }
 
 static ssize_t divas_read(struct file *file, char __user *buf,
-			  size_t count, loff_t * ppos)
+			  size_t count, loff_t *ppos)
 {
 	int ret = -EINVAL;
 
@@ -650,7 +650,7 @@ static ssize_t divas_read(struct file *file, char __user *buf,
 	return (ret);
 }
 
-static unsigned int divas_poll(struct file *file, poll_table * wait)
+static unsigned int divas_poll(struct file *file, poll_table *wait)
 {
 	if (!file->private_data) {
 		return (POLLERR);
@@ -686,7 +686,7 @@ static int DIVA_INIT_FUNCTION divas_register_chrdev(void)
 }
 
 /* --------------------------------------------------------------------------
-    PCI driver section
+   PCI driver section
    -------------------------------------------------------------------------- */
 static int __devinit divas_init_one(struct pci_dev *pdev,
 				    const struct pci_device_id *ent)
@@ -698,9 +698,9 @@ static int __devinit divas_init_one(struct pci_dev *pdev,
 	DBG_TRC(("%s bus: %08x fn: %08x insertion.\n",
 		 CardProperties[ent->driver_data].Name,
 		 pdev->bus->number, pdev->devfn))
-	printk(KERN_INFO "%s: %s bus: %08x fn: %08x insertion.\n",
-		DRIVERLNAME, CardProperties[ent->driver_data].Name,
-		pdev->bus->number, pdev->devfn);
+		printk(KERN_INFO "%s: %s bus: %08x fn: %08x insertion.\n",
+		       DRIVERLNAME, CardProperties[ent->driver_data].Name,
+		       pdev->bus->number, pdev->devfn);
 
 	if (pci_enable_device(pdev)) {
 		DBG_TRC(("%s: %s bus: %08x fn: %08x device init failed.\n",
@@ -708,12 +708,12 @@ static int __devinit divas_init_one(struct pci_dev *pdev,
 			 CardProperties[ent->driver_data].Name,
 			 pdev->bus->number,
 			 pdev->devfn))
-		printk(KERN_ERR
-			"%s: %s bus: %08x fn: %08x device init failed.\n",
-			DRIVERLNAME,
-			CardProperties[ent->driver_data].
-			Name, pdev->bus->number,
-			pdev->devfn);
+			printk(KERN_ERR
+			       "%s: %s bus: %08x fn: %08x device init failed.\n",
+			       DRIVERLNAME,
+			       CardProperties[ent->driver_data].
+			       Name, pdev->bus->number,
+			       pdev->devfn);
 		return (-EIO);
 	}
 
@@ -723,9 +723,9 @@ static int __devinit divas_init_one(struct pci_dev *pdev,
 	if (!pci_latency) {
 		DBG_TRC(("%s: bus: %08x fn: %08x fix latency.\n",
 			 DRIVERLNAME, pdev->bus->number, pdev->devfn))
-		printk(KERN_INFO
-			"%s: bus: %08x fn: %08x fix latency.\n",
-			 DRIVERLNAME, pdev->bus->number, pdev->devfn);
+			printk(KERN_INFO
+			       "%s: bus: %08x fn: %08x fix latency.\n",
+			       DRIVERLNAME, pdev->bus->number, pdev->devfn);
 		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
 	}
 
@@ -735,12 +735,12 @@ static int __devinit divas_init_one(struct pci_dev *pdev,
 			 CardProperties[ent->driver_data].Name,
 			 pdev->bus->number,
 			 pdev->devfn))
-		printk(KERN_ERR
-			"%s: %s bus: %08x fn: %08x card init failed.\n",
-			DRIVERLNAME,
-			CardProperties[ent->driver_data].
-			Name, pdev->bus->number,
-			pdev->devfn);
+			printk(KERN_ERR
+			       "%s: %s bus: %08x fn: %08x card init failed.\n",
+			       DRIVERLNAME,
+			       CardProperties[ent->driver_data].
+			       Name, pdev->bus->number,
+			       pdev->devfn);
 		return (-EIO);
 	}
 
@@ -755,8 +755,8 @@ static void __devexit divas_remove_one(struct pci_dev *pdev)
 
 	DBG_TRC(("bus: %08x fn: %08x removal.\n",
 		 pdev->bus->number, pdev->devfn))
-	printk(KERN_INFO "%s: bus: %08x fn: %08x removal.\n",
-		DRIVERLNAME, pdev->bus->number, pdev->devfn);
+		printk(KERN_INFO "%s: bus: %08x fn: %08x removal.\n",
+		       DRIVERLNAME, pdev->bus->number, pdev->devfn);
 
 	if (pdiva) {
 		diva_driver_remove_card(pdiva);
@@ -765,7 +765,7 @@ static void __devexit divas_remove_one(struct pci_dev *pdev)
 }
 
 /* --------------------------------------------------------------------------
-    Driver Load / Startup  
+   Driver Load / Startup
    -------------------------------------------------------------------------- */
 static int DIVA_INIT_FUNCTION divas_init(void)
 {
@@ -824,12 +824,12 @@ static int DIVA_INIT_FUNCTION divas_init(void)
 	}
 	printk(KERN_INFO "%s: started with major %d\n", DRIVERLNAME, major);
 
-      out:
+out:
 	return (ret);
 }
 
 /* --------------------------------------------------------------------------
-    Driver Unload
+   Driver Unload
    -------------------------------------------------------------------------- */
 static void DIVA_EXIT_FUNCTION divas_exit(void)
 {
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
index 46d44a9..af4fd3d 100644
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ b/drivers/isdn/hardware/eicon/divasproc.c
@@ -55,7 +55,7 @@ extern struct proc_dir_entry *proc_net_eicon;
 static struct proc_dir_entry *divas_proc_entry = NULL;
 
 static ssize_t
-divas_read(struct file *file, char __user *buf, size_t count, loff_t * off)
+divas_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
 	int len = 0;
 	int cadapter;
@@ -94,12 +94,12 @@ divas_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 }
 
 static ssize_t
-divas_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
+divas_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
 {
 	return (-ENODEV);
 }
 
-static unsigned int divas_poll(struct file *file, poll_table * wait)
+static unsigned int divas_poll(struct file *file, poll_table *wait)
 {
 	return (POLLERR);
 }
@@ -127,7 +127,7 @@ static const struct file_operations divas_fops = {
 int create_divas_proc(void)
 {
 	divas_proc_entry = proc_create(divas_proc_name, S_IFREG | S_IRUGO,
-					proc_net_eicon, &divas_fops);
+				       proc_net_eicon, &divas_fops);
 	if (!divas_proc_entry)
 		return (0);
 
@@ -155,11 +155,11 @@ static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
 		switch (c) {
 		case '0':
 			IoAdapter->capi_cfg.cfg_1 &=
-			    ~DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON;
+				~DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON;
 			break;
 		case '1':
 			IoAdapter->capi_cfg.cfg_1 |=
-			    DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON;
+				DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON;
 			break;
 		default:
 			return (-EINVAL);
@@ -182,11 +182,11 @@ static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer
 		switch (c) {
 		case '0':
 			IoAdapter->capi_cfg.cfg_1 &=
-			    ~DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON;
+				~DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON;
 			break;
 		case '1':
 			IoAdapter->capi_cfg.cfg_1 |=
-			    DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON;
+				DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON;
 			break;
 		default:
 			return (-EINVAL);
@@ -202,9 +202,9 @@ static int d_l1_down_proc_show(struct seq_file *m, void *v)
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
 	seq_printf(m, "%s\n",
-		       (IoAdapter->capi_cfg.
-			cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" :
-		       "0");
+		   (IoAdapter->capi_cfg.
+		    cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" :
+		   "0");
 	return 0;
 }
 
@@ -228,9 +228,9 @@ static int grp_opt_proc_show(struct seq_file *m, void *v)
 	PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
 
 	seq_printf(m, "%s\n",
-		       (IoAdapter->capi_cfg.
-			cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON)
-		       ? "1" : "0");
+		   (IoAdapter->capi_cfg.
+		    cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON)
+		   ? "1" : "0");
 	return 0;
 }
 
@@ -281,7 +281,7 @@ static int info_proc_show(struct seq_file *m, void *v)
 	seq_printf(m, "DSP state   : %08x\n", a->dsp_mask);
 	seq_printf(m, "Channels    : %02d\n", IoAdapter->Properties.Channels);
 	seq_printf(m, "E. max/used : %03d/%03d\n",
-		       IoAdapter->e_max, IoAdapter->e_count);
+		   IoAdapter->e_max, IoAdapter->e_count);
 	diva_get_vserial_number(IoAdapter, tmpser);
 	seq_printf(m, "Serial      : %s\n", tmpser);
 	seq_printf(m, "IRQ         : %d\n", IoAdapter->irq_info.irq_nr);
@@ -289,8 +289,8 @@ static int info_proc_show(struct seq_file *m, void *v)
 	seq_printf(m, "CardOrdinal : %d\n", a->CardOrdinal);
 	seq_printf(m, "Controller  : %d\n", a->controller);
 	seq_printf(m, "Bus-Type    : %s\n",
-		       (a->Bus ==
-			DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI");
+		   (a->Bus ==
+		    DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI");
 	seq_printf(m, "Port-Name   : %s\n", a->port_name);
 	if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) {
 		seq_printf(m, "PCI-bus     : %d\n", a->resources.pci.bus);
@@ -298,15 +298,15 @@ static int info_proc_show(struct seq_file *m, void *v)
 		for (i = 0; i < 8; i++) {
 			if (a->resources.pci.bar[i]) {
 				seq_printf(m,
-					    "Mem / I/O %d : 0x%x / mapped : 0x%lx",
-					    i, a->resources.pci.bar[i],
-					    (unsigned long) a->resources.
-					    pci.addr[i]);
+					   "Mem / I/O %d : 0x%x / mapped : 0x%lx",
+					   i, a->resources.pci.bar[i],
+					   (unsigned long) a->resources.
+					   pci.addr[i]);
 				if (a->resources.pci.length[i]) {
 					seq_printf(m,
-						    " / length : %d",
-						    a->resources.pci.
-						    length[i]);
+						   " / length : %d",
+						   a->resources.pci.
+						   length[i]);
 				}
 				seq_putc(m, '\n');
 			}
@@ -314,7 +314,7 @@ static int info_proc_show(struct seq_file *m, void *v)
 	}
 	if ((!a->xdi_adapter.port) &&
 	    ((!a->xdi_adapter.ram) ||
-	    (!a->xdi_adapter.reset)
+	     (!a->xdi_adapter.reset)
 	     || (!a->xdi_adapter.cfg))) {
 		if (!IoAdapter->irq_info.irq_nr) {
 			p = "slave";
@@ -352,9 +352,9 @@ static const struct file_operations info_proc_fops = {
 */
 
 /* --------------------------------------------------------------------------
-    Create adapter directory and files in proc file system
+   Create adapter directory and files in proc file system
    -------------------------------------------------------------------------- */
-int create_adapter_proc(diva_os_xdi_adapter_t * a)
+int create_adapter_proc(diva_os_xdi_adapter_t *a)
 {
 	struct proc_dir_entry *de, *pe;
 	char tmp[16];
@@ -385,9 +385,9 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a)
 }
 
 /* --------------------------------------------------------------------------
-    Remove adapter directory and files in proc file system
+   Remove adapter directory and files in proc file system
    -------------------------------------------------------------------------- */
-void remove_adapter_proc(diva_os_xdi_adapter_t * a)
+void remove_adapter_proc(diva_os_xdi_adapter_t *a)
 {
 	char tmp[16];
 
diff --git a/drivers/isdn/hardware/eicon/divasync.h b/drivers/isdn/hardware/eicon/divasync.h
index 85784a7..dd6b53a 100644
--- a/drivers/isdn/hardware/eicon/divasync.h
+++ b/drivers/isdn/hardware/eicon/divasync.h
@@ -1,29 +1,29 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_SYNC__H  
+#ifndef __DIVA_SYNC__H
 #define __DIVA_SYNC__H
 #define IDI_SYNC_REQ_REMOVE             0x00
 #define IDI_SYNC_REQ_GET_NAME           0x01
@@ -59,26 +59,26 @@
 /******************************************************************************/
 #define IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES  0x92
 /*
-   To receive XDI features:
-   1. set 'buffer_length_in_bytes' to length of you buffer
-   2. set 'features' to pointer to your buffer
-   3. issue synchronous request to XDI
-   4. Check that feature 'DIVA_XDI_EXTENDED_FEATURES_VALID' is present
-      after call. This feature does indicate that your request
-      was processed and XDI does support this synchronous request
-   5. if on return bit 31 (0x80000000) in 'buffer_length_in_bytes' is
-      set then provided buffer was too small, and bits 30-0 does
-      contain necessary length of buffer.
-      in this case only features that do find place in the buffer
-      are indicated to caller
+  To receive XDI features:
+  1. set 'buffer_length_in_bytes' to length of you buffer
+  2. set 'features' to pointer to your buffer
+  3. issue synchronous request to XDI
+  4. Check that feature 'DIVA_XDI_EXTENDED_FEATURES_VALID' is present
+  after call. This feature does indicate that your request
+  was processed and XDI does support this synchronous request
+  5. if on return bit 31 (0x80000000) in 'buffer_length_in_bytes' is
+  set then provided buffer was too small, and bits 30-0 does
+  contain necessary length of buffer.
+  in this case only features that do find place in the buffer
+  are indicated to caller
 */
 typedef struct _diva_xdi_get_extended_xdi_features {
-  dword buffer_length_in_bytes;
-  byte  *features;
+	dword buffer_length_in_bytes;
+	byte  *features;
 } diva_xdi_get_extended_xdi_features_t;
 /*
-   features[0]
-  */
+  features[0]
+*/
 #define DIVA_XDI_EXTENDED_FEATURES_VALID          0x01
 #define DIVA_XDI_EXTENDED_FEATURE_CMA             0x02
 #define DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR       0x04
@@ -91,17 +91,17 @@ typedef struct _diva_xdi_get_extended_xdi_features {
 /******************************************************************************/
 #define IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR   0x93
 typedef struct _diva_xdi_get_adapter_sdram_bar {
- dword bar;
+	dword bar;
 } diva_xdi_get_adapter_sdram_bar_t;
 /******************************************************************************/
 #define IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS   0x94
 /*
   CAPI Parameters will be written in the caller's buffer
-  */
+*/
 typedef struct _diva_xdi_get_capi_parameters {
-  dword structure_length;
-  byte flag_dynamic_l1_down;
-  byte group_optimization_enabled;
+	dword structure_length;
+	byte flag_dynamic_l1_down;
+	byte group_optimization_enabled;
 } diva_xdi_get_capi_parameters_t;
 /******************************************************************************/
 #define IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER   0x95
@@ -111,11 +111,11 @@ typedef struct _diva_xdi_get_capi_parameters {
   in case of one adapter that supports multiple interfaces
   'controller' is zero for Master adapter (and adapter that supports
   only one interface)
-  */
+*/
 typedef struct _diva_xdi_get_logical_adapter_number {
-  dword logical_adapter_number;
-  dword controller;
-  dword total_controllers;
+	dword logical_adapter_number;
+	dword controller;
+	dword total_controllers;
 } diva_xdi_get_logical_adapter_number_s_t;
 /******************************************************************************/
 #define IDI_SYNC_REQ_UP1DM_OPERATION   0x96
@@ -124,10 +124,10 @@ typedef struct _diva_xdi_get_logical_adapter_number {
 #define IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC     0x01
 #define IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE      0x02
 typedef struct _diva_xdi_dma_descriptor_operation {
-  int   operation;
-  int   descriptor_number;
-  void* descriptor_address;
-  dword descriptor_magic;
+	int operation;
+	int descriptor_number;
+	void *descriptor_address;
+	dword descriptor_magic;
 } diva_xdi_dma_descriptor_operation_t;
 /******************************************************************************/
 #define IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY   0x01
@@ -137,22 +137,22 @@ typedef struct _diva_xdi_dma_descriptor_operation {
 #define IDI_SYNC_REQ_DIDD_READ_ADAPTER_ARRAY        0x05
 #define IDI_SYNC_REQ_DIDD_GET_CFG_LIB_IFC           0x10
 typedef struct _diva_didd_adapter_notify {
- dword handle; /* Notification handle */
- void   * callback;
- void   * context;
+	dword handle; /* Notification handle */
+	void *callback;
+	void *context;
 } diva_didd_adapter_notify_t;
 typedef struct _diva_didd_add_adapter {
- void   * descriptor;
+	void *descriptor;
 } diva_didd_add_adapter_t;
 typedef struct _diva_didd_remove_adapter {
- IDI_CALL p_request;
+	IDI_CALL p_request;
 } diva_didd_remove_adapter_t;
 typedef struct _diva_didd_read_adapter_array {
- void   * buffer;
- dword length;
+	void *buffer;
+	dword length;
 } diva_didd_read_adapter_array_t;
 typedef struct _diva_didd_get_cfg_lib_ifc {
- void* ifc;
+	void *ifc;
 } diva_didd_get_cfg_lib_ifc_t;
 /******************************************************************************/
 #define IDI_SYNC_REQ_XDI_GET_STREAM    0x91
@@ -163,31 +163,31 @@ typedef struct _diva_didd_get_cfg_lib_ifc {
 #define DIVA_ISTREAM_COMPLETE_READ     1
 #define DIVA_ISTREAM_COMPLETE_WRITE    2
 typedef struct _diva_xdi_stream_interface {
-  unsigned char  Id;                 /* filled by XDI client */
- unsigned char provided_service;    /* filled by XDI        */
- unsigned char requested_service;   /* filled by XDI Client */
- void* xdi_context;    /* filled by XDI     */
- void* client_context;   /* filled by XDI client */
- int (*write)(void* context,
-               int Id,
-               void* data,
-               int length,
-               int final,
-               byte usr1,
-               byte usr2);
- int (*read)(void* context,
-              int Id,
-              void* data,
-              int max_length,
-              int* final,
-              byte* usr1,
-              byte* usr2);
- int (*complete)(void* client_context,
-         int Id,
-          int what,
-         void* data,
-         int length,
-         int* final);
+	unsigned char  Id;                 /* filled by XDI client */
+	unsigned char provided_service;    /* filled by XDI        */
+	unsigned char requested_service;   /* filled by XDI Client */
+	void *xdi_context;    /* filled by XDI */
+	void *client_context;   /* filled by XDI client */
+	int (*write)(void *context,
+		     int Id,
+		     void *data,
+		     int length,
+		     int final,
+		     byte usr1,
+		     byte usr2);
+	int (*read)(void *context,
+		    int Id,
+		    void *data,
+		    int max_length,
+		    int *final,
+		    byte *usr1,
+		    byte *usr2);
+	int (*complete)(void *client_context,
+			int Id,
+			int what,
+			void *data,
+			int length,
+			int *final);
 } diva_xdi_stream_interface_t;
 /******************************************************************************/
 /*
@@ -196,37 +196,37 @@ typedef struct _diva_xdi_stream_interface {
 typedef struct
 { unsigned char LineState;         /* Modem line state (STATUS_R) */
 #define SERIAL_GSM_CELL 0x01   /* GSM or CELL cable attached  */
- unsigned char CardState;          /* PCMCIA card state (0 = down) */
- unsigned char IsdnState;          /* ISDN layer 1 state (0 = down)*/
- unsigned char HookState;          /* current logical hook state */
+	unsigned char CardState;          /* PCMCIA card state (0 = down) */
+	unsigned char IsdnState;          /* ISDN layer 1 state (0 = down)*/
+	unsigned char HookState;          /* current logical hook state */
 #define SERIAL_ON_HOOK 0x02   /* set in DIVA CTRL_R register */
 } SERIAL_STATE;
-typedef int (  * SERIAL_INT_CB) (void *Context) ;
-typedef int (  * SERIAL_DPC_CB) (void *Context) ;
-typedef unsigned char (  * SERIAL_I_SYNC) (void *Context) ;
+typedef int (*SERIAL_INT_CB)(void *Context);
+typedef int (*SERIAL_DPC_CB)(void *Context);
+typedef unsigned char (*SERIAL_I_SYNC)(void *Context);
 typedef struct
 { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
- unsigned char Req;             /* request (must be always 0) */
- unsigned char Rc;              /* return code (is the request) */
- unsigned char Function;           /* private function code  */
+	unsigned char Req;             /* request (must be always 0) */
+	unsigned char Rc;              /* return code (is the request) */
+	unsigned char Function;           /* private function code  */
 #define SERIAL_HOOK_ATTACH 0x81
 #define SERIAL_HOOK_STATUS 0x82
 #define SERIAL_HOOK_I_SYNC 0x83
 #define SERIAL_HOOK_NOECHO 0x84
 #define SERIAL_HOOK_RING 0x85
 #define SERIAL_HOOK_DETACH 0x8f
- unsigned char Flags;           /* function refinements   */
- /* parameters passed by the ATTACH request      */
- SERIAL_INT_CB InterruptHandler; /* called on each interrupt  */
- SERIAL_DPC_CB DeferredHandler; /* called on hook state changes */
- void   *HandlerContext; /* context for both handlers */
- /* return values for both the ATTACH and the STATUS request   */
- unsigned long IoBase;    /* IO port assigned to UART  */
- SERIAL_STATE State;
- /* parameters and return values for the I_SYNC function    */
- SERIAL_I_SYNC SyncFunction;  /* to be called synchronized */
- void   *SyncContext;  /* context for this function */
- unsigned char SyncResult;   /* return value of function  */
+	unsigned char Flags;           /* function refinements   */
+	/* parameters passed by the ATTACH request      */
+	SERIAL_INT_CB InterruptHandler; /* called on each interrupt  */
+	SERIAL_DPC_CB DeferredHandler; /* called on hook state changes */
+	void   *HandlerContext; /* context for both handlers */
+	/* return values for both the ATTACH and the STATUS request   */
+	unsigned long IoBase;    /* IO port assigned to UART  */
+	SERIAL_STATE State;
+	/* parameters and return values for the I_SYNC function    */
+	SERIAL_I_SYNC SyncFunction;  /* to be called synchronized */
+	void   *SyncContext;  /* context for this function */
+	unsigned char SyncResult;   /* return value of function  */
 } SERIAL_HOOK;
 /*
  * IDI_SYNC_REQ_XCHANGE_STATUS - exchange the status between IDI and WMP
@@ -234,22 +234,22 @@ typedef struct
  */
 typedef struct
 { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
- unsigned char Req;             /* request (must be always 0) */
- unsigned char Rc;              /* return code (is the request) */
+	unsigned char Req;             /* request (must be always 0) */
+	unsigned char Rc;              /* return code (is the request) */
 #define DRIVER_STATUS_BOOT  0xA1
 #define DRIVER_STATUS_INIT_DEV 0xA2
 #define DRIVER_STATUS_RUNNING 0xA3
 #define DRIVER_STATUS_SHUTDOWN 0xAF
 #define DRIVER_STATUS_TRAPPED 0xAE
- unsigned char wmpStatus;          /* exported by WMP              */
- unsigned char idiStatus;   /* exported by IDI              */
- unsigned long wizProto ;   /* from WMP registry to IDI     */
- /* the cardtype value is defined by cardtype.h */
- unsigned long cardType ;   /* from IDI registry to WMP     */
- unsigned long nt2 ;    /* from IDI registry to WMP     */
- unsigned long permanent ;   /* from IDI registry to WMP     */
- unsigned long stableL2 ;   /* from IDI registry to WMP     */
- unsigned long tei ;    /* from IDI registry to WMP     */
+	unsigned char wmpStatus;          /* exported by WMP              */
+	unsigned char idiStatus;   /* exported by IDI              */
+	unsigned long wizProto;   /* from WMP registry to IDI     */
+	/* the cardtype value is defined by cardtype.h */
+	unsigned long cardType;   /* from IDI registry to WMP     */
+	unsigned long nt2;    /* from IDI registry to WMP     */
+	unsigned long permanent;   /* from IDI registry to WMP     */
+	unsigned long stableL2;   /* from IDI registry to WMP     */
+	unsigned long tei;    /* from IDI registry to WMP     */
 #define CRC4_MASK   0x00000003
 #define L1_TRISTATE_MASK 0x00000004
 #define WATCHDOG_MASK  0x00000008
@@ -271,36 +271,36 @@ typedef struct
 #define SET_STABLEL2  0x20000000
 #define SET_TEI    0x40000000
 #define SET_NUMBERLEN  0x80000000
- unsigned long Flag ;  /* |31-Type-16|15-Mask-0| */
- unsigned long NumberLen ; /* reconfiguration: union is empty */
- union {
-  struct {    /* possible reconfiguration, but ... ; SET_BOARD */
-   unsigned long SerialNumber ;
-   char     *pCardname ; /* di_defs.h: BOARD_NAME_LENGTH */
-  } board ;
-  struct {      /* reset: need resources */
-   void * pRawResources ;
-   void * pXlatResources ;
-  } res ;
-  struct { /* reconfiguration: wizProto == PROTTYPE_RBSCAS */
+	unsigned long Flag;  /* |31-Type-16|15-Mask-0| */
+	unsigned long NumberLen; /* reconfiguration: union is empty */
+	union {
+		struct {    /* possible reconfiguration, but ... ; SET_BOARD */
+			unsigned long SerialNumber;
+			char     *pCardname; /* di_defs.h: BOARD_NAME_LENGTH */
+		} board;
+		struct {      /* reset: need resources */
+			void *pRawResources;
+			void *pXlatResources;
+		} res;
+		struct { /* reconfiguration: wizProto == PROTTYPE_RBSCAS */
 #define GLARE_RESOLVE_MASK 0x00000001
 #define DID_MASK   0x00000002
 #define BEARER_CAP_MASK  0x0000000c
 #define SET_GLARE_RESOLVE 0x00010000
 #define SET_DID    0x00020000
 #define SET_BEARER_CAP  0x000c0000
-   unsigned long Flag ;  /* |31-Type-16|15-VALUE-0| */
-   unsigned short DigitTimeout ;
-   unsigned short AnswerDelay ;
-  } rbs ;
-  struct { /* reconfiguration: wizProto == PROTTYPE_QSIG */
+			unsigned long Flag;  /* |31-Type-16|15-VALUE-0| */
+			unsigned short DigitTimeout;
+			unsigned short AnswerDelay;
+		} rbs;
+		struct { /* reconfiguration: wizProto == PROTTYPE_QSIG */
 #define CALL_REF_LENGTH1_MASK 0x00000001
 #define BRI_CHANNEL_ID_MASK  0x00000002
 #define SET_CALL_REF_LENGTH  0x00010000
 #define SET_BRI_CHANNEL_ID  0x00020000
-   unsigned long Flag ;  /* |31-Type-16|15-VALUE-0| */
-  } qsig ;
-  struct { /* reconfiguration: NumberLen != 0 */
+			unsigned long Flag;  /* |31-Type-16|15-VALUE-0| */
+		} qsig;
+		struct { /* reconfiguration: NumberLen != 0 */
 #define SET_SPID1   0x00010000
 #define SET_NUMBER1   0x00020000
 #define SET_SUBADDRESS1  0x00040000
@@ -308,50 +308,50 @@ typedef struct
 #define SET_NUMBER2   0x00200000
 #define SET_SUBADDRESS2  0x00400000
 #define MASK_SET   0xffff0000
-   unsigned long Flag ;   /* |31-Type-16|15-Channel-0| */
-   unsigned char *pBuffer ; /* number value */
-  } isdnNo ;
- }
-parms
-;
-} isdnProps ;
+			unsigned long Flag;   /* |31-Type-16|15-Channel-0| */
+			unsigned char *pBuffer; /* number value */
+		} isdnNo;
+	}
+		parms
+		;
+} isdnProps;
 /*
  * IDI_SYNC_REQ_PORTDRV_HOOK - signal plug/unplug (Award Cardware only)
  */
-typedef void (  * PORTDRV_HOOK_CB) (void *Context, int Plug) ;
+typedef void (*PORTDRV_HOOK_CB)(void *Context, int Plug);
 typedef struct
 { /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
- unsigned char Req;             /* request (must be always 0) */
- unsigned char Rc;              /* return code (is the request) */
- unsigned char Function;           /* private function code  */
- unsigned char Flags;           /* function refinements   */
- PORTDRV_HOOK_CB Callback;   /* to be called on plug/unplug */
- void   *Context;   /* context for callback   */
- unsigned long Info;    /* more info if needed   */
-} PORTDRV_HOOK ;
+	unsigned char Req;             /* request (must be always 0) */
+	unsigned char Rc;              /* return code (is the request) */
+	unsigned char Function;           /* private function code  */
+	unsigned char Flags;           /* function refinements   */
+	PORTDRV_HOOK_CB Callback;   /* to be called on plug/unplug */
+	void   *Context;   /* context for callback   */
+	unsigned long Info;    /* more info if needed   */
+} PORTDRV_HOOK;
 /*  Codes for the 'Rc' element in structure below. */
 #define SLI_INSTALL     (0xA1)
 #define SLI_UNINSTALL   (0xA2)
-typedef int ( * SLIENTRYPOINT)(void* p3SignalAPI, void* pContext);
+typedef int (*SLIENTRYPOINT)(void *p3SignalAPI, void *pContext);
 typedef struct
 {   /* 'Req' and 'Rc' must be at the same place as in the ENTITY struct */
-    unsigned char   Req;                /* request (must be always 0)   */
-    unsigned char   Rc;                 /* return code (is the request) */
-    unsigned char   Function;           /* private function code        */
-    unsigned char   Flags;              /* function refinements         */
-    SLIENTRYPOINT   Callback;           /* to be called on plug/unplug  */
-    void            *Context;           /* context for callback         */
-    unsigned long   Info;               /* more info if needed          */
-} SLIENTRYPOINT_REQ ;
+	unsigned char   Req;                /* request (must be always 0)   */
+	unsigned char   Rc;                 /* return code (is the request) */
+	unsigned char   Function;           /* private function code        */
+	unsigned char   Flags;              /* function refinements         */
+	SLIENTRYPOINT   Callback;           /* to be called on plug/unplug  */
+	void            *Context;           /* context for callback         */
+	unsigned long   Info;               /* more info if needed          */
+} SLIENTRYPOINT_REQ;
 /******************************************************************************/
 /*
  *  Definitions for DIVA USB
  */
-typedef int  (  * USB_SEND_REQ) (unsigned char PipeIndex, unsigned char Type,void *Data, int sizeData);
-typedef int  (  * USB_START_DEV) (void *Adapter, void *Ipac) ;
+typedef int (*USB_SEND_REQ)(unsigned char PipeIndex, unsigned char Type, void *Data, int sizeData);
+typedef int (*USB_START_DEV)(void *Adapter, void *Ipac);
 /* called from WDM */
-typedef void (  * USB_RECV_NOTIFY) (void *Ipac, void *msg) ;
-typedef void (  * USB_XMIT_NOTIFY) (void *Ipac, unsigned char PipeIndex) ;
+typedef void (*USB_RECV_NOTIFY)(void *Ipac, void *msg);
+typedef void (*USB_XMIT_NOTIFY)(void *Ipac, unsigned char PipeIndex);
 /******************************************************************************/
 /*
  * Parameter description for synchronous requests.
@@ -361,129 +361,129 @@ typedef void (  * USB_XMIT_NOTIFY) (void *Ipac, unsigned char PipeIndex) ;
  */
 typedef union
 { ENTITY Entity;
- struct
- { /* 'Req' and 'Rc' are at the same place as in the ENTITY struct */
-  unsigned char   Req; /* request (must be always 0) */
-  unsigned char   Rc;  /* return code (is the request) */
- }   Request;
- struct
- { unsigned char   Req; /* request (must be always 0) */
-  unsigned char   Rc;  /* return code (0x01)   */
-  unsigned char   name[BOARD_NAME_LENGTH];
- }   GetName;
- struct
- { unsigned char   Req; /* request (must be always 0) */
-  unsigned char   Rc;  /* return code (0x02)   */
-  unsigned long   serial; /* serial number    */
- }   GetSerial;
- struct
- { unsigned char   Req; /* request (must be always 0) */
-  unsigned char   Rc;  /* return code (0x02)   */
-  unsigned long   lineIdx;/* line, 0 if card has only one */
- }   GetLineIdx;
- struct
- { unsigned char  Req;     /* request (must be always 0) */
-  unsigned char  Rc;      /* return code (0x02)   */
-  unsigned long  cardtype;/* card type        */
- }   GetCardType;
- struct
- { unsigned short command;/* command = 0x0300 */
-  unsigned short dummy; /* not used */
-  IDI_CALL       callback;/* routine to call back */
-  ENTITY      *contxt; /* ptr to entity to use */
- }   PostCall;
- struct
- { unsigned char  Req;  /* request (must be always 0) */
-  unsigned char  Rc;   /* return code (0x04)   */
-  unsigned char  pcm[1]; /* buffer (a pc_maint struct) */
- }   GetXlog;
- struct
- { unsigned char  Req;  /* request (must be always 0) */
-  unsigned char  Rc;   /* return code (0x05)   */
-  unsigned short features;/* feature defines see below */
- }   GetFeatures;
- SERIAL_HOOK  SerialHook;
+	struct
+	{ /* 'Req' and 'Rc' are at the same place as in the ENTITY struct */
+		unsigned char   Req; /* request (must be always 0) */
+		unsigned char   Rc;  /* return code (is the request) */
+	}   Request;
+	struct
+	{ unsigned char   Req; /* request (must be always 0) */
+		unsigned char   Rc;  /* return code (0x01)   */
+		unsigned char   name[BOARD_NAME_LENGTH];
+	}   GetName;
+	struct
+	{ unsigned char   Req; /* request (must be always 0) */
+		unsigned char   Rc;  /* return code (0x02)   */
+		unsigned long   serial; /* serial number    */
+	}   GetSerial;
+	struct
+	{ unsigned char   Req; /* request (must be always 0) */
+		unsigned char   Rc;  /* return code (0x02)   */
+		unsigned long   lineIdx;/* line, 0 if card has only one */
+	}   GetLineIdx;
+	struct
+	{ unsigned char  Req;     /* request (must be always 0) */
+		unsigned char  Rc;      /* return code (0x02)   */
+		unsigned long  cardtype;/* card type        */
+	}   GetCardType;
+	struct
+	{ unsigned short command;/* command = 0x0300 */
+		unsigned short dummy; /* not used */
+		IDI_CALL       callback;/* routine to call back */
+		ENTITY      *contxt; /* ptr to entity to use */
+	}   PostCall;
+	struct
+	{ unsigned char  Req;  /* request (must be always 0) */
+		unsigned char  Rc;   /* return code (0x04)   */
+		unsigned char  pcm[1]; /* buffer (a pc_maint struct) */
+	}   GetXlog;
+	struct
+	{ unsigned char  Req;  /* request (must be always 0) */
+		unsigned char  Rc;   /* return code (0x05)   */
+		unsigned short features;/* feature defines see below */
+	}   GetFeatures;
+	SERIAL_HOOK  SerialHook;
 /* Added for DIVA USB */
- struct
- { unsigned char   Req;
-  unsigned char   Rc;
-  USB_SEND_REQ    UsbSendRequest; /* function in Diva Usb WDM driver in usb_os.c, */
-                                        /* called from usb_drv.c to send a message to our device */
-                                        /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0) ; */
-  USB_RECV_NOTIFY usb_recv;       /* called from usb_os.c to pass a received message and ptr to IPAC */
-                                        /* on to usb_drv.c by a call to usb_recv(). */
-  USB_XMIT_NOTIFY usb_xmit;       /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */
-                                        /* to usb_drv.c by a call to usb_xmit(). */
-  USB_START_DEV   UsbStartDevice; /* Start the USB Device, in usb_os.c */
-  IDI_CALL        callback;       /* routine to call back */
-  ENTITY          *contxt;     /* ptr to entity to use */
-  void            ** ipac_ptr;    /* pointer to struct IPAC in VxD */
- } Usb_Msg_old;
+	struct
+	{ unsigned char   Req;
+		unsigned char   Rc;
+		USB_SEND_REQ    UsbSendRequest; /* function in Diva Usb WDM driver in usb_os.c, */
+		/* called from usb_drv.c to send a message to our device */
+		/* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0); */
+		USB_RECV_NOTIFY usb_recv;       /* called from usb_os.c to pass a received message and ptr to IPAC */
+		/* on to usb_drv.c by a call to usb_recv(). */
+		USB_XMIT_NOTIFY usb_xmit;       /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */
+		/* to usb_drv.c by a call to usb_xmit(). */
+		USB_START_DEV   UsbStartDevice; /* Start the USB Device, in usb_os.c */
+		IDI_CALL        callback;       /* routine to call back */
+		ENTITY          *contxt;     /* ptr to entity to use */
+		void **ipac_ptr;    /* pointer to struct IPAC in VxD */
+	} Usb_Msg_old;
 /* message used by WDM and VXD to pass pointers of function and IPAC* */
- struct
- { unsigned char Req;
-  unsigned char Rc;
-        USB_SEND_REQ    pUsbSendRequest;/* function in Diva Usb WDM driver in usb_os.c, */
-                                        /* called from usb_drv.c to send a message to our device */
-                                        /* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0) ; */
-        USB_RECV_NOTIFY p_usb_recv;     /* called from usb_os.c to pass a received message and ptr to IPAC */
-                                        /* on to usb_drv.c by a call to usb_recv(). */
-        USB_XMIT_NOTIFY p_usb_xmit;     /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */
-                                        /* to usb_drv.c by a call to usb_xmit().*/
-  void            *ipac_ptr;      /* &Diva.ipac pointer to struct IPAC in VxD */
- } Usb_Msg;
- PORTDRV_HOOK PortdrvHook;
-    SLIENTRYPOINT_REQ   sliEntryPointReq;
-  struct {
-    unsigned char Req;
-    unsigned char Rc;
-    diva_xdi_stream_interface_t info;
-  } xdi_stream_info;
-  struct {
-    unsigned char Req;
-    unsigned char Rc;
-    diva_xdi_get_extended_xdi_features_t info;
-  } xdi_extended_features;
- struct {
-    unsigned char Req;
-    unsigned char Rc;
-  diva_xdi_get_adapter_sdram_bar_t info;
- } xdi_sdram_bar;
-  struct {
-    unsigned char Req;
-    unsigned char Rc;
-    diva_xdi_get_capi_parameters_t info;
-  } xdi_capi_prms;
- struct {
-  ENTITY           e;
-  diva_didd_adapter_notify_t info;
- } didd_notify;
- struct {
-  ENTITY           e;
-  diva_didd_add_adapter_t   info;
- } didd_add_adapter;
- struct {
-  ENTITY           e;
-  diva_didd_remove_adapter_t info;
- } didd_remove_adapter;
- struct {
-  ENTITY             e;
-  diva_didd_read_adapter_array_t info;
- } didd_read_adapter_array;
- struct {
-  ENTITY             e;
-  diva_didd_get_cfg_lib_ifc_t     info;
- } didd_get_cfg_lib_ifc;
-  struct {
-    unsigned char Req;
-    unsigned char Rc;
-    diva_xdi_get_logical_adapter_number_s_t info;
-  } xdi_logical_adapter_number;
-  struct {
-    unsigned char Req;
-    unsigned char Rc;
-    diva_xdi_dma_descriptor_operation_t info;
-  } xdi_dma_descriptor_operation;
+	struct
+	{ unsigned char Req;
+		unsigned char Rc;
+		USB_SEND_REQ    pUsbSendRequest;/* function in Diva Usb WDM driver in usb_os.c, */
+		/* called from usb_drv.c to send a message to our device */
+		/* eg UsbSendRequest (USB_PIPE_SIGNAL, USB_IPAC_START, 0, 0); */
+		USB_RECV_NOTIFY p_usb_recv;     /* called from usb_os.c to pass a received message and ptr to IPAC */
+		/* on to usb_drv.c by a call to usb_recv(). */
+		USB_XMIT_NOTIFY p_usb_xmit;     /* called from usb_os.c in DivaUSB.sys WDM to indicate a completed transmit */
+		/* to usb_drv.c by a call to usb_xmit().*/
+		void            *ipac_ptr;      /* &Diva.ipac pointer to struct IPAC in VxD */
+	} Usb_Msg;
+	PORTDRV_HOOK PortdrvHook;
+	SLIENTRYPOINT_REQ   sliEntryPointReq;
+	struct {
+		unsigned char Req;
+		unsigned char Rc;
+		diva_xdi_stream_interface_t info;
+	} xdi_stream_info;
+	struct {
+		unsigned char Req;
+		unsigned char Rc;
+		diva_xdi_get_extended_xdi_features_t info;
+	} xdi_extended_features;
+	struct {
+		unsigned char Req;
+		unsigned char Rc;
+		diva_xdi_get_adapter_sdram_bar_t info;
+	} xdi_sdram_bar;
+	struct {
+		unsigned char Req;
+		unsigned char Rc;
+		diva_xdi_get_capi_parameters_t info;
+	} xdi_capi_prms;
+	struct {
+		ENTITY           e;
+		diva_didd_adapter_notify_t info;
+	} didd_notify;
+	struct {
+		ENTITY           e;
+		diva_didd_add_adapter_t   info;
+	} didd_add_adapter;
+	struct {
+		ENTITY           e;
+		diva_didd_remove_adapter_t info;
+	} didd_remove_adapter;
+	struct {
+		ENTITY             e;
+		diva_didd_read_adapter_array_t info;
+	} didd_read_adapter_array;
+	struct {
+		ENTITY             e;
+		diva_didd_get_cfg_lib_ifc_t     info;
+	} didd_get_cfg_lib_ifc;
+	struct {
+		unsigned char Req;
+		unsigned char Rc;
+		diva_xdi_get_logical_adapter_number_s_t info;
+	} xdi_logical_adapter_number;
+	struct {
+		unsigned char Req;
+		unsigned char Rc;
+		diva_xdi_dma_descriptor_operation_t info;
+	} xdi_dma_descriptor_operation;
 } IDI_SYNC_REQ;
 /******************************************************************************/
-#endif /* __DIVA_SYNC__H */  
+#endif /* __DIVA_SYNC__H */
diff --git a/drivers/isdn/hardware/eicon/dqueue.c b/drivers/isdn/hardware/eicon/dqueue.c
index 9822582..7958a25 100644
--- a/drivers/isdn/hardware/eicon/dqueue.c
+++ b/drivers/isdn/hardware/eicon/dqueue.c
@@ -14,7 +14,7 @@
 #include "dqueue.h"
 
 int
-diva_data_q_init(diva_um_idi_data_queue_t * q,
+diva_data_q_init(diva_um_idi_data_queue_t *q,
 		 int max_length, int max_segments)
 {
 	int i;
@@ -38,7 +38,7 @@ diva_data_q_init(diva_um_idi_data_queue_t * q,
 	return (0);
 }
 
-int diva_data_q_finit(diva_um_idi_data_queue_t * q)
+int diva_data_q_finit(diva_um_idi_data_queue_t *q)
 {
 	int i;
 
@@ -54,12 +54,12 @@ int diva_data_q_finit(diva_um_idi_data_queue_t * q)
 	return (0);
 }
 
-int diva_data_q_get_max_length(const diva_um_idi_data_queue_t * q)
+int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q)
 {
 	return (q->max_length);
 }
 
-void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q)
+void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q)
 {
 	if ((!q->segment_pending) && (q->count < q->segments)) {
 		q->segment_pending = 1;
@@ -70,7 +70,7 @@ void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q)
 }
 
 void
-diva_data_q_ack_segment4write(diva_um_idi_data_queue_t * q, int length)
+diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q, int length)
 {
 	if (q->segment_pending) {
 		q->length[q->write] = length;
@@ -92,12 +92,12 @@ const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t *
 	return NULL;
 }
 
-int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t * q)
+int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q)
 {
 	return (q->length[q->read]);
 }
 
-void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t * q)
+void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q)
 {
 	if (q->count) {
 		q->length[q->read] = 0;
diff --git a/drivers/isdn/hardware/eicon/dqueue.h b/drivers/isdn/hardware/eicon/dqueue.h
index 72d21c9..6992c45 100644
--- a/drivers/isdn/hardware/eicon/dqueue.h
+++ b/drivers/isdn/hardware/eicon/dqueue.h
@@ -16,16 +16,16 @@ typedef struct _diva_um_idi_data_queue {
 	int length[DIVA_UM_IDI_MAX_MSGS];
 } diva_um_idi_data_queue_t;
 
-int diva_data_q_init(diva_um_idi_data_queue_t * q,
+int diva_data_q_init(diva_um_idi_data_queue_t *q,
 		     int max_length, int max_segments);
-int diva_data_q_finit(diva_um_idi_data_queue_t * q);
-int diva_data_q_get_max_length(const diva_um_idi_data_queue_t * q);
-void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t * q);
-void diva_data_q_ack_segment4write(diva_um_idi_data_queue_t * q,
+int diva_data_q_finit(diva_um_idi_data_queue_t *q);
+int diva_data_q_get_max_length(const diva_um_idi_data_queue_t *q);
+void *diva_data_q_get_segment4write(diva_um_idi_data_queue_t *q);
+void diva_data_q_ack_segment4write(diva_um_idi_data_queue_t *q,
 				   int length);
 const void *diva_data_q_get_segment4read(const diva_um_idi_data_queue_t *
 					 q);
-int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t * q);
-void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t * q);
+int diva_data_q_get_segment_length(const diva_um_idi_data_queue_t *q);
+void diva_data_q_ack_segment4read(diva_um_idi_data_queue_t *q);
 
 #endif
diff --git a/drivers/isdn/hardware/eicon/dsp_defs.h b/drivers/isdn/hardware/eicon/dsp_defs.h
index fec1e38..94828c8 100644
--- a/drivers/isdn/hardware/eicon/dsp_defs.h
+++ b/drivers/isdn/hardware/eicon/dsp_defs.h
@@ -1,33 +1,33 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 DSP_DEFS_H_  
+#ifndef DSP_DEFS_H_
 #define DSP_DEFS_H_
 #include "dspdids.h"
 /*---------------------------------------------------------------------------*/
-#define dsp_download_reserve_space(fp,length)
+#define dsp_download_reserve_space(fp, length)
 /*****************************************************************************/
 /*
  * OS file access abstraction layer
@@ -35,25 +35,25 @@
  * I/O functions returns -1 on error, 0 on EOF
  */
 struct _OsFileHandle_;
-typedef long (  * OsFileIo)  (struct _OsFileHandle_    *handle,
-                                void                     *buffer,
-                                long                       size) ;
-typedef long (  * OsFileSeek)(struct _OsFileHandle_    *handle,
-                                long                       position,
-                                int                        mode) ;
-typedef long (  * OsCardLoad)(struct _OsFileHandle_    *handle,
-                                long                       length,
-                                void                         *   *addr) ;
+typedef long (*OsFileIo)(struct _OsFileHandle_ *handle,
+			 void *buffer,
+			 long size);
+typedef long (*OsFileSeek)(struct _OsFileHandle_ *handle,
+			   long position,
+			   int mode);
+typedef long (*OsCardLoad)(struct _OsFileHandle_    *handle,
+			   long length,
+			   void **addr);
 typedef struct _OsFileHandle_
-{ void       *sysFileDesc ;
- unsigned long sysFileSize ;
- OsFileIo      sysFileRead ;
- OsFileSeek    sysFileSeek ;
- void       *sysLoadDesc ;
- OsCardLoad    sysCardLoad ;
-} OsFileHandle ;
-extern OsFileHandle *OsOpenFile (char *path_name) ;
-extern void          OsCloseFile (OsFileHandle *fp) ;
+{ void       *sysFileDesc;
+	unsigned long sysFileSize;
+	OsFileIo      sysFileRead;
+	OsFileSeek    sysFileSeek;
+	void       *sysLoadDesc;
+	OsCardLoad    sysCardLoad;
+} OsFileHandle;
+extern OsFileHandle *OsOpenFile(char *path_name);
+extern void          OsCloseFile(OsFileHandle *fp);
 /*****************************************************************************/
 #define DSP_TELINDUS_FILE "dspdload.bin"
 /* special DSP file for BRI cards for Qsig and CornetN because of missing memory */
@@ -93,109 +93,109 @@ extern void          OsCloseFile (OsFileHandle *fp) ;
 #define DSP_FILE_FORMAT_VERSION_BCD         0x0100
 typedef struct tag_dsp_combifile_header
 {
-  char                  format_identification[DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE];
-  word                  format_version_bcd;
-  word                  header_size;
-  word                  combifile_description_size;
-  word                  directory_entries;
-  word                  directory_size;
-  word                  download_count;
-  word                  usage_mask_size;
+	char                  format_identification[DSP_COMBIFILE_FORMAT_IDENTIFICATION_SIZE];
+	word                  format_version_bcd;
+	word                  header_size;
+	word                  combifile_description_size;
+	word                  directory_entries;
+	word                  directory_size;
+	word                  download_count;
+	word                  usage_mask_size;
 } t_dsp_combifile_header;
 typedef struct tag_dsp_combifile_directory_entry
 {
-  word                  card_type_number;
-  word                  file_set_number;
+	word                  card_type_number;
+	word                  file_set_number;
 } t_dsp_combifile_directory_entry;
 typedef struct tag_dsp_file_header
 {
-  char                  format_identification[DSP_FILE_FORMAT_IDENTIFICATION_SIZE];
-  word                  format_version_bcd;
-  word                  download_id;
-  word                  download_flags;
-  word                  required_processing_power;
-  word                  interface_channel_count;
-  word                  header_size;
-  word                  download_description_size;
-  word                  memory_block_table_size;
-  word                  memory_block_count;
-  word                  segment_table_size;
-  word                  segment_count;
-  word                  symbol_table_size;
-  word                  symbol_count;
-  word                  total_data_size_dm;
-  word                  data_block_count_dm;
-  word                  total_data_size_pm;
-  word                  data_block_count_pm;
+	char                  format_identification[DSP_FILE_FORMAT_IDENTIFICATION_SIZE];
+	word                  format_version_bcd;
+	word                  download_id;
+	word                  download_flags;
+	word                  required_processing_power;
+	word                  interface_channel_count;
+	word                  header_size;
+	word                  download_description_size;
+	word                  memory_block_table_size;
+	word                  memory_block_count;
+	word                  segment_table_size;
+	word                  segment_count;
+	word                  symbol_table_size;
+	word                  symbol_count;
+	word                  total_data_size_dm;
+	word                  data_block_count_dm;
+	word                  total_data_size_pm;
+	word                  data_block_count_pm;
 } t_dsp_file_header;
 typedef struct tag_dsp_memory_block_desc
 {
-  word                  alias_memory_block;
-  word                  memory_type;
-  word                  address;
-  word                  size;             /* DSP words */
+	word                  alias_memory_block;
+	word                  memory_type;
+	word                  address;
+	word                  size;             /* DSP words */
 } t_dsp_memory_block_desc;
 typedef struct tag_dsp_segment_desc
 {
-  word                  memory_block;
-  word                  attributes;
-  word                  base;
-  word                  size;
-  word                  alignment;        /* ==0 -> no other legal start address than base */
+	word                  memory_block;
+	word                  attributes;
+	word                  base;
+	word                  size;
+	word                  alignment;        /* ==0 -> no other legal start address than base */
 } t_dsp_segment_desc;
 typedef struct tag_dsp_symbol_desc
 {
-  word                  symbol_id;
-  word                  segment;
-  word                  offset;
-  word                  size;             /* DSP words */
+	word                  symbol_id;
+	word                  segment;
+	word                  offset;
+	word                  size;             /* DSP words */
 } t_dsp_symbol_desc;
 typedef struct tag_dsp_data_block_header
 {
-  word                  attributes;
-  word                  segment;
-  word                  offset;
-  word                  size;             /* DSP words */
+	word                  attributes;
+	word                  segment;
+	word                  offset;
+	word                  size;             /* DSP words */
 } t_dsp_data_block_header;
 typedef struct tag_dsp_download_desc
 {
-  word                  download_id;
-  word                  download_flags;
-  word                  required_processing_power;
-  word                  interface_channel_count;
-  word                  excess_header_size;
-  word                  memory_block_count;
-  word                  segment_count;
-  word                  symbol_count;
-  word                  data_block_count_dm;
-  word                  data_block_count_pm;
-  byte   *            p_excess_header_data;
-  char   *            p_download_description;
-  t_dsp_memory_block_desc   *p_memory_block_table;
-  t_dsp_segment_desc   *p_segment_table;
-  t_dsp_symbol_desc   *p_symbol_table;
-  word   *            p_data_blocks_dm;
-  word   *            p_data_blocks_pm;
+	word                  download_id;
+	word                  download_flags;
+	word                  required_processing_power;
+	word                  interface_channel_count;
+	word                  excess_header_size;
+	word                  memory_block_count;
+	word                  segment_count;
+	word                  symbol_count;
+	word                  data_block_count_dm;
+	word                  data_block_count_pm;
+	byte *p_excess_header_data;
+	char *p_download_description;
+	t_dsp_memory_block_desc *p_memory_block_table;
+	t_dsp_segment_desc *p_segment_table;
+	t_dsp_symbol_desc *p_symbol_table;
+	word *p_data_blocks_dm;
+	word *p_data_blocks_pm;
 } t_dsp_desc;
 typedef struct tag_dsp_portable_download_desc /* be sure to keep native alignment for MAESTRA's */
 {
-  word                  download_id;
-  word                  download_flags;
-  word                  required_processing_power;
-  word                  interface_channel_count;
-  word                  excess_header_size;
-  word                  memory_block_count;
-  word                  segment_count;
-  word                  symbol_count;
-  word                  data_block_count_dm;
-  word                  data_block_count_pm;
-  dword                 p_excess_header_data;
-  dword                 p_download_description;
-  dword                 p_memory_block_table;
-  dword                 p_segment_table;
-  dword                 p_symbol_table;
-  dword                 p_data_blocks_dm;
-  dword                 p_data_blocks_pm;
+	word                  download_id;
+	word                  download_flags;
+	word                  required_processing_power;
+	word                  interface_channel_count;
+	word                  excess_header_size;
+	word                  memory_block_count;
+	word                  segment_count;
+	word                  symbol_count;
+	word                  data_block_count_dm;
+	word                  data_block_count_pm;
+	dword                 p_excess_header_data;
+	dword                 p_download_description;
+	dword                 p_memory_block_table;
+	dword                 p_segment_table;
+	dword                 p_symbol_table;
+	dword                 p_data_blocks_dm;
+	dword                 p_data_blocks_pm;
 } t_dsp_portable_desc;
 #define DSP_DOWNLOAD_INDEX_KERNEL               0
 #define DSP30TX_DOWNLOAD_INDEX_KERNEL           1
@@ -204,7 +204,7 @@ typedef struct tag_dsp_portable_download_desc /* be sure to keep native alignmen
 #define DSP_DOWNLOAD_MAX_SEGMENTS         16
 #define DSP_UDATA_REQUEST_RECONFIGURE     0
 /*
-parameters:
+  parameters:
   <word> reconfigure delay (in 8kHz samples)
   <word> reconfigure code
   <byte> reconfigure hdlc preamble flags
@@ -229,11 +229,11 @@ parameters:
 #define DSP_RECONFIGURE_V17_12000         11
 #define DSP_RECONFIGURE_V17_14400         12
 /*
-data indications if transparent framer
+  data indications if transparent framer
   <byte> data 0
   <byte> data 1
   ...
-data indications if HDLC framer
+  data indications if HDLC framer
   <byte> data 0
   <byte> data 1
   ...
@@ -243,17 +243,17 @@ data indications if HDLC framer
 */
 #define DSP_UDATA_INDICATION_SYNC         0
 /*
-returns:
+  returns:
   <word> time of sync (sampled from counter at 8kHz)
 */
 #define DSP_UDATA_INDICATION_DCD_OFF      1
 /*
-returns:
+  returns:
   <word> time of DCD off (sampled from counter at 8kHz)
 */
 #define DSP_UDATA_INDICATION_DCD_ON       2
 /*
-returns:
+  returns:
   <word> time of DCD on (sampled from counter at 8kHz)
   <byte> connected norm
   <word> connected options
@@ -261,12 +261,12 @@ returns:
 */
 #define DSP_UDATA_INDICATION_CTS_OFF      3
 /*
-returns:
+  returns:
   <word> time of CTS off (sampled from counter at 8kHz)
 */
 #define DSP_UDATA_INDICATION_CTS_ON       4
 /*
-returns:
+  returns:
   <word> time of CTS on (sampled from counter at 8kHz)
   <byte> connected norm
   <word> connected options
@@ -292,10 +292,10 @@ returns:
 #define DSP_CONNECTED_NORM_V17              17
 #define DSP_CONNECTED_OPTION_TRELLIS        0x0001
 /*---------------------------------------------------------------------------*/
-extern char *dsp_read_file (OsFileHandle          *fp,
-                            word                     card_type_number,
-                            word                  *p_dsp_download_count,
-                            t_dsp_desc            *p_dsp_download_table,
-                            t_dsp_portable_desc   *p_dsp_portable_download_table) ;
+extern char *dsp_read_file(OsFileHandle *fp,
+			   word card_type_number,
+			   word *p_dsp_download_count,
+			   t_dsp_desc *p_dsp_download_table,
+			   t_dsp_portable_desc *p_dsp_portable_download_table);
 /*---------------------------------------------------------------------------*/
-#endif /* DSP_DEFS_H_ */  
+#endif /* DSP_DEFS_H_ */
diff --git a/drivers/isdn/hardware/eicon/dsp_tst.h b/drivers/isdn/hardware/eicon/dsp_tst.h
index a6021e5..fe36f13 100644
--- a/drivers/isdn/hardware/eicon/dsp_tst.h
+++ b/drivers/isdn/hardware/eicon/dsp_tst.h
@@ -4,8 +4,8 @@
 #define __DIVA_PRI_HOST_TEST_DSPS_H__
 
 /*
-   DSP registers on maestra pri
-   */
+  DSP registers on maestra pri
+*/
 #define DSP1_PORT       (0x00)
 #define DSP2_PORT       (0x8)
 #define DSP3_PORT       (0x800)
@@ -39,9 +39,9 @@
 #define DSP_ADR_OFFS    0x80
 
 /*------------------------------------------------------------------
-		Dsp related definitions
+  Dsp related definitions
   ------------------------------------------------------------------ */
 #define DSP_SIGNATURE_PROBE_WORD 0x5a5a
-#define dsp_make_address_ex(pm,address) ((word)((pm) ? (address) : (address) + 0x4000))
+#define dsp_make_address_ex(pm, address) ((word)((pm) ? (address) : (address) + 0x4000))
 
 #endif
diff --git a/drivers/isdn/hardware/eicon/dspdids.h b/drivers/isdn/hardware/eicon/dspdids.h
index ebe131a..957b33c 100644
--- a/drivers/isdn/hardware/eicon/dspdids.h
+++ b/drivers/isdn/hardware/eicon/dspdids.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 DSPDIDS_H_
diff --git a/drivers/isdn/hardware/eicon/dsrv4bri.h b/drivers/isdn/hardware/eicon/dsrv4bri.h
index 732d22d..f353fb6 100644
--- a/drivers/isdn/hardware/eicon/dsrv4bri.h
+++ b/drivers/isdn/hardware/eicon/dsrv4bri.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_XDI_DSRV_4_BRI_INC__
@@ -35,6 +35,6 @@
 #define PLX9054_SOFT_RESET 0x4000
 #define PLX9054_RELOAD_EEPROM 0x2000
 #define DIVA_4BRI_REVISION(__x__) (((__x__)->cardType == CARDTYPE_DIVASRV_Q_8M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_B_2M_V2_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_B_2F_PCI) || ((__x__)->cardType == CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI))
-void diva_os_set_qBri_functions (PISDN_ADAPTER IoAdapter);
-void diva_os_set_qBri2_functions (PISDN_ADAPTER IoAdapter);
+void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter);
+void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter);
 #endif
diff --git a/drivers/isdn/hardware/eicon/dsrv_bri.h b/drivers/isdn/hardware/eicon/dsrv_bri.h
index f38ebbe..8a67dbc 100644
--- a/drivers/isdn/hardware/eicon/dsrv_bri.h
+++ b/drivers/isdn/hardware/eicon/dsrv_bri.h
@@ -1,37 +1,37 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_XDI_DSRV_BRI_INC__
 #define __DIVA_XDI_DSRV_BRI_INC__
 /*
- Functions exported from os dependent part of
- BRI card configuration and used in
- OS independed part
- */
+  Functions exported from os dependent part of
+  BRI card configuration and used in
+  OS independed part
+*/
 /*
- Prepare OS dependent part of BRI functions
- */
-void diva_os_prepare_maestra_functions (PISDN_ADAPTER IoAdapter);
+  Prepare OS dependent part of BRI functions
+*/
+void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
 #endif
diff --git a/drivers/isdn/hardware/eicon/dsrv_pri.h b/drivers/isdn/hardware/eicon/dsrv_pri.h
index 8611826..fd1a9ff 100644
--- a/drivers/isdn/hardware/eicon/dsrv_pri.h
+++ b/drivers/isdn/hardware/eicon/dsrv_pri.h
@@ -1,38 +1,38 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_XDI_DSRV_PRI_INC__
 #define __DIVA_XDI_DSRV_PRI_INC__
 /*
- Functions exported from os dependent part of
- PRI card configuration and used in
- OS independed part
- */
+  Functions exported from os dependent part of
+  PRI card configuration and used in
+  OS independed part
+*/
 /*
- Prepare OS dependent part of PRI/PRI Rev.2 functions
- */
-void diva_os_prepare_pri_functions (PISDN_ADAPTER IoAdapter);
-void diva_os_prepare_pri2_functions (PISDN_ADAPTER IoAdapter);
+  Prepare OS dependent part of PRI/PRI Rev.2 functions
+*/
+void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter);
+void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
 #endif
diff --git a/drivers/isdn/hardware/eicon/entity.h b/drivers/isdn/hardware/eicon/entity.h
index 16252cf..fdb8341 100644
--- a/drivers/isdn/hardware/eicon/entity.h
+++ b/drivers/isdn/hardware/eicon/entity.h
@@ -11,17 +11,17 @@
 
 typedef struct _divas_um_idi_entity {
 	struct list_head          link;
-	diva_um_idi_adapter_t*    adapter; /* Back to adapter */
-	ENTITY                    e;
-	void*                     os_ref;
-	dword                     status;
-	void*                     os_context;
-	int                       rc_count;
+	diva_um_idi_adapter_t *adapter; /* Back to adapter */
+	ENTITY e;
+	void *os_ref;
+	dword status;
+	void *os_context;
+	int rc_count;
 	diva_um_idi_data_queue_t  data; /* definad by user 1 ... MAX */
 	diva_um_idi_data_queue_t  rc;   /* two entries */
 	BUFFERS                   XData;
 	BUFFERS                   RData;
-	byte                      buffer[2048+512];
+	byte                      buffer[2048 + 512];
 } divas_um_idi_entity_t;
 
 
diff --git a/drivers/isdn/hardware/eicon/helpers.h b/drivers/isdn/hardware/eicon/helpers.h
index b212311..c9156b0 100644
--- a/drivers/isdn/hardware/eicon/helpers.h
+++ b/drivers/isdn/hardware/eicon/helpers.h
@@ -1,51 +1,51 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_XDI_CARD_CONFIG_HELPERS_INC__
 #define __DIVA_XDI_CARD_CONFIG_HELPERS_INC__
-dword diva_get_protocol_file_features  (byte* File,
-                      int offset,
-                      char *IdStringBuffer,
-                      dword IdBufferSize);
-void diva_configure_protocol (PISDN_ADAPTER IoAdapter);
+dword diva_get_protocol_file_features(byte *File,
+				      int offset,
+				      char *IdStringBuffer,
+				      dword IdBufferSize);
+void diva_configure_protocol(PISDN_ADAPTER IoAdapter);
 /*
- Low level file access system abstraction
- */
+  Low level file access system abstraction
+*/
 /* -------------------------------------------------------------------------
-  Access to single file
-  Return pointer to the image of the requested file,
-  write image length to 'FileLength'
-  ------------------------------------------------------------------------- */
-void *xdiLoadFile (char *FileName, dword *FileLength, unsigned long MaxLoadSize) ;
+   Access to single file
+   Return pointer to the image of the requested file,
+   write image length to 'FileLength'
+   ------------------------------------------------------------------------- */
+void *xdiLoadFile(char *FileName, dword *FileLength, unsigned long MaxLoadSize);
 /* -------------------------------------------------------------------------
-  Dependent on the protocol settings does read return pointer
-  to the image of appropriate protocol file
-  ------------------------------------------------------------------------- */
-void *xdiLoadArchive (PISDN_ADAPTER IoAdapter, dword *FileLength, unsigned long MaxLoadSize) ;
+   Dependent on the protocol settings does read return pointer
+   to the image of appropriate protocol file
+   ------------------------------------------------------------------------- */
+void *xdiLoadArchive(PISDN_ADAPTER IoAdapter, dword *FileLength, unsigned long MaxLoadSize);
 /* --------------------------------------------------------------------------
-  Free all system resources accessed by xdiLoadFile and xdiLoadArchive
-  -------------------------------------------------------------------------- */
-void xdiFreeFile (void* handle);
+   Free all system resources accessed by xdiLoadFile and xdiLoadArchive
+   -------------------------------------------------------------------------- */
+void xdiFreeFile(void *handle);
 #endif
diff --git a/drivers/isdn/hardware/eicon/idifunc.c b/drivers/isdn/hardware/eicon/idifunc.c
index db87d51..d153e3c 100644
--- a/drivers/isdn/hardware/eicon/idifunc.c
+++ b/drivers/isdn/hardware/eicon/idifunc.c
@@ -1,7 +1,7 @@
 /* $Id: idifunc.c,v 1.14.4.4 2004/08/28 20:03:53 armin Exp $
  *
  * Driver for Eicon DIVA Server ISDN cards.
- * User Mode IDI Interface 
+ * User Mode IDI Interface
  *
  * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
@@ -58,7 +58,7 @@ static diva_os_spin_lock_t ll_lock;
 /*
  * find card in list
  */
-static udiva_card *find_card_in_list(DESCRIPTOR * d)
+static udiva_card *find_card_in_list(DESCRIPTOR *d)
 {
 	udiva_card *card;
 	struct list_head *tmp;
@@ -80,7 +80,7 @@ static udiva_card *find_card_in_list(DESCRIPTOR * d)
 /*
  * new card
  */
-static void um_new_card(DESCRIPTOR * d)
+static void um_new_card(DESCRIPTOR *d)
 {
 	int adapter_nr = 0;
 	udiva_card *card = NULL;
@@ -94,10 +94,10 @@ static void um_new_card(DESCRIPTOR * d)
 	memcpy(&card->d, d, sizeof(DESCRIPTOR));
 	sync_req.xdi_logical_adapter_number.Req = 0;
 	sync_req.xdi_logical_adapter_number.Rc =
-	    IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
-	card->d.request((ENTITY *) & sync_req);
+		IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER;
+	card->d.request((ENTITY *)&sync_req);
 	adapter_nr =
-	    sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
+		sync_req.xdi_logical_adapter_number.info.logical_adapter_number;
 	card->Id = adapter_nr;
 	if (!(diva_user_mode_idi_create_adapter(d, adapter_nr))) {
 		diva_os_enter_spin_lock(&ll_lock, &old_irql, "add card");
@@ -113,7 +113,7 @@ static void um_new_card(DESCRIPTOR * d)
 /*
  * remove card
  */
-static void um_remove_card(DESCRIPTOR * d)
+static void um_remove_card(DESCRIPTOR *d)
 {
 	diva_os_spin_lock_magic_t old_irql;
 	udiva_card *card = NULL;
@@ -154,7 +154,7 @@ rescan:
 /*
  * DIDD notify callback
  */
-static void *didd_callback(void *context, DESCRIPTOR * adapter,
+static void *didd_callback(void *context, DESCRIPTOR *adapter,
 			   int removal)
 {
 	if (adapter->type == IDI_DADAPTER) {
@@ -196,10 +196,10 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
 			memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
 			req.didd_notify.e.Req = 0;
 			req.didd_notify.e.Rc =
-			    IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+				IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 			req.didd_notify.info.callback = (void *)didd_callback;
 			req.didd_notify.info.context = NULL;
-			DAdapter.request((ENTITY *) & req);
+			DAdapter.request((ENTITY *)&req);
 			if (req.didd_notify.e.Rc != 0xff) {
 				stop_dbg();
 				return (0);
@@ -234,7 +234,7 @@ static void DIVA_EXIT_FUNCTION disconnect_didd(void)
 	req.didd_notify.e.Req = 0;
 	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 	req.didd_notify.info.handle = notify_handle;
-	DAdapter.request((ENTITY *) & req);
+	DAdapter.request((ENTITY *)&req);
 }
 
 /*
diff --git a/drivers/isdn/hardware/eicon/io.c b/drivers/isdn/hardware/eicon/io.c
index 6fd9b00..8851ce5 100644
--- a/drivers/isdn/hardware/eicon/io.c
+++ b/drivers/isdn/hardware/eicon/io.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -33,16 +33,16 @@
 #include "di.h"
 #include "mi_pc.h"
 #include "io.h"
-extern ADAPTER * adapter[MAX_ADAPTER];
+extern ADAPTER *adapter[MAX_ADAPTER];
 extern PISDN_ADAPTER IoAdapters[MAX_ADAPTER];
-void request (PISDN_ADAPTER, ENTITY *);
-static void pcm_req (PISDN_ADAPTER, ENTITY *);
+void request(PISDN_ADAPTER, ENTITY *);
+static void pcm_req(PISDN_ADAPTER, ENTITY *);
 /* --------------------------------------------------------------------------
-  local functions
-  -------------------------------------------------------------------------- */
-#define ReqFunc(N) \
-static void Request##N(ENTITY *e) \
-{ if ( IoAdapters[N] ) (* IoAdapters[N]->DIRequest)(IoAdapters[N], e) ; }
+   local functions
+   -------------------------------------------------------------------------- */
+#define ReqFunc(N)							\
+	static void Request##N(ENTITY *e)				\
+	{ if (IoAdapters[N]) (*IoAdapters[N]->DIRequest)(IoAdapters[N], e); }
 ReqFunc(0)
 ReqFunc(1)
 ReqFunc(2)
@@ -61,792 +61,792 @@ ReqFunc(14)
 ReqFunc(15)
 IDI_CALL Requests[MAX_ADAPTER] =
 { &Request0, &Request1, &Request2, &Request3,
- &Request4, &Request5, &Request6, &Request7,
- &Request8, &Request9, &Request10, &Request11,
- &Request12, &Request13, &Request14, &Request15
+  &Request4, &Request5, &Request6, &Request7,
+  &Request8, &Request9, &Request10, &Request11,
+  &Request12, &Request13, &Request14, &Request15
 };
 /*****************************************************************************/
 /*
   This array should indicate all new services, that this version of XDI
   is able to provide to his clients
-  */
-static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ+1] = {
- (DIVA_XDI_EXTENDED_FEATURES_VALID       |
-  DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR    |
-  DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS    |
+*/
+static byte extended_xdi_features[DIVA_XDI_EXTENDED_FEATURES_MAX_SZ + 1] = {
+	(DIVA_XDI_EXTENDED_FEATURES_VALID       |
+	 DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR    |
+	 DIVA_XDI_EXTENDED_FEATURE_CAPI_PRMS    |
 #if defined(DIVA_IDI_RX_DMA)
-  DIVA_XDI_EXTENDED_FEATURE_CMA          |
-  DIVA_XDI_EXTENDED_FEATURE_RX_DMA       |
-  DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA |
+	 DIVA_XDI_EXTENDED_FEATURE_CMA          |
+	 DIVA_XDI_EXTENDED_FEATURE_RX_DMA       |
+	 DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA |
 #endif
-  DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
- 0
+	 DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC),
+	0
 };
 /*****************************************************************************/
 void
-dump_xlog_buffer (PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc)
-{
- dword   logLen ;
- word *Xlog   = xlogDesc->buf ;
- word  logCnt = xlogDesc->cnt ;
- word  logOut = xlogDesc->out / sizeof(*Xlog) ;
- DBG_FTL(("%s: ************* XLOG recovery (%d) *************",
-          &IoAdapter->Name[0], (int)logCnt))
- DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
- for ( ; logCnt > 0 ; --logCnt )
- {
-  if ( !GET_WORD(&Xlog[logOut]) )
-  {
-   if ( --logCnt == 0 )
-    break ;
-   logOut = 0 ;
-  }
-  if ( GET_WORD(&Xlog[logOut]) <= (logOut * sizeof(*Xlog)) )
-  {
-   if ( logCnt > 2 )
-   {
-    DBG_FTL(("Possibly corrupted XLOG: %d entries left",
-             (int)logCnt))
-   }
-   break ;
-  }
-  logLen = (dword)(GET_WORD(&Xlog[logOut]) - (logOut * sizeof(*Xlog))) ;
-  DBG_FTL_MXLOG(( (char *)&Xlog[logOut + 1], (dword)(logLen - 2) ))
-  logOut = (GET_WORD(&Xlog[logOut]) + 1) / sizeof(*Xlog) ;
- }
- DBG_FTL(("%s: ***************** end of XLOG *****************",
-          &IoAdapter->Name[0]))
-}
+dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc)
+{
+	dword   logLen;
+	word *Xlog   = xlogDesc->buf;
+	word  logCnt = xlogDesc->cnt;
+	word  logOut = xlogDesc->out / sizeof(*Xlog);
+	DBG_FTL(("%s: ************* XLOG recovery (%d) *************",
+		 &IoAdapter->Name[0], (int)logCnt))
+		DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
+		for (; logCnt > 0; --logCnt)
+		{
+			if (!GET_WORD(&Xlog[logOut]))
+			{
+				if (--logCnt == 0)
+					break;
+				logOut = 0;
+			}
+			if (GET_WORD(&Xlog[logOut]) <= (logOut * sizeof(*Xlog)))
+			{
+				if (logCnt > 2)
+				{
+					DBG_FTL(("Possibly corrupted XLOG: %d entries left",
+						 (int)logCnt))
+						}
+				break;
+			}
+			logLen = (dword)(GET_WORD(&Xlog[logOut]) - (logOut * sizeof(*Xlog)));
+			DBG_FTL_MXLOG(((char *)&Xlog[logOut + 1], (dword)(logLen - 2)))
+				logOut = (GET_WORD(&Xlog[logOut]) + 1) / sizeof(*Xlog);
+		}
+	DBG_FTL(("%s: ***************** end of XLOG *****************",
+		 &IoAdapter->Name[0]))
+		}
 /*****************************************************************************/
 #if defined(XDI_USE_XLOG)
 static char *(ExceptionCauseTable[]) =
 {
- "Interrupt",
- "TLB mod /IBOUND",
- "TLB load /DBOUND",
- "TLB store",
- "Address error load",
- "Address error store",
- "Instruction load bus error",
- "Data load/store bus error",
- "Syscall",
- "Breakpoint",
- "Reverd instruction",
- "Coprocessor unusable",
- "Overflow",
- "TRAP",
- "VCEI",
- "Floating Point Exception",
- "CP2",
- "Reserved 17",
- "Reserved 18",
- "Reserved 19",
- "Reserved 20",
- "Reserved 21",
- "Reserved 22",
- "WATCH",
- "Reserved 24",
- "Reserved 25",
- "Reserved 26",
- "Reserved 27",
- "Reserved 28",
- "Reserved 29",
- "Reserved 30",
- "VCED"
-} ;
+	"Interrupt",
+	"TLB mod /IBOUND",
+	"TLB load /DBOUND",
+	"TLB store",
+	"Address error load",
+	"Address error store",
+	"Instruction load bus error",
+	"Data load/store bus error",
+	"Syscall",
+	"Breakpoint",
+	"Reverd instruction",
+	"Coprocessor unusable",
+	"Overflow",
+	"TRAP",
+	"VCEI",
+	"Floating Point Exception",
+	"CP2",
+	"Reserved 17",
+	"Reserved 18",
+	"Reserved 19",
+	"Reserved 20",
+	"Reserved 21",
+	"Reserved 22",
+	"WATCH",
+	"Reserved 24",
+	"Reserved 25",
+	"Reserved 26",
+	"Reserved 27",
+	"Reserved 28",
+	"Reserved 29",
+	"Reserved 30",
+	"VCED"
+};
 #endif
 void
-dump_trap_frame (PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame)
-{
- MP_XCPTC __iomem *xcept = (MP_XCPTC __iomem *)exceptionFrame ;
- dword    __iomem *regs;
- regs  = &xcept->regs[0] ;
- DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
-          &IoAdapter->Name[0]))
- DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
- DBG_FTL(("Cause: %s",
-          ExceptionCauseTable[(READ_DWORD(&xcept->cr) & 0x0000007c) >> 2]))
- DBG_FTL(("sr    0x%08x cr    0x%08x epc   0x%08x vaddr 0x%08x",
-          READ_DWORD(&xcept->sr), READ_DWORD(&xcept->cr),
-					READ_DWORD(&xcept->epc), READ_DWORD(&xcept->vaddr)))
- DBG_FTL(("zero  0x%08x at    0x%08x v0    0x%08x v1    0x%08x",
-          READ_DWORD(&regs[ 0]), READ_DWORD(&regs[ 1]),
-					READ_DWORD(&regs[ 2]), READ_DWORD(&regs[ 3])))
- DBG_FTL(("a0    0x%08x a1    0x%08x a2    0x%08x a3    0x%08x",
-          READ_DWORD(&regs[ 4]), READ_DWORD(&regs[ 5]),
-					READ_DWORD(&regs[ 6]), READ_DWORD(&regs[ 7])))
- DBG_FTL(("t0    0x%08x t1    0x%08x t2    0x%08x t3    0x%08x",
-          READ_DWORD(&regs[ 8]), READ_DWORD(&regs[ 9]),
-					READ_DWORD(&regs[10]), READ_DWORD(&regs[11])))
- DBG_FTL(("t4    0x%08x t5    0x%08x t6    0x%08x t7    0x%08x",
-          READ_DWORD(&regs[12]), READ_DWORD(&regs[13]),
-					READ_DWORD(&regs[14]), READ_DWORD(&regs[15])))
- DBG_FTL(("s0    0x%08x s1    0x%08x s2    0x%08x s3    0x%08x",
-          READ_DWORD(&regs[16]), READ_DWORD(&regs[17]),
-					READ_DWORD(&regs[18]), READ_DWORD(&regs[19])))
- DBG_FTL(("s4    0x%08x s5    0x%08x s6    0x%08x s7    0x%08x",
-          READ_DWORD(&regs[20]), READ_DWORD(&regs[21]),
-					READ_DWORD(&regs[22]), READ_DWORD(&regs[23])))
- DBG_FTL(("t8    0x%08x t9    0x%08x k0    0x%08x k1    0x%08x",
-          READ_DWORD(&regs[24]), READ_DWORD(&regs[25]),
-					READ_DWORD(&regs[26]), READ_DWORD(&regs[27])))
- DBG_FTL(("gp    0x%08x sp    0x%08x s8    0x%08x ra    0x%08x",
-          READ_DWORD(&regs[28]), READ_DWORD(&regs[29]),
-					READ_DWORD(&regs[30]), READ_DWORD(&regs[31])))
- DBG_FTL(("md    0x%08x|%08x         resvd 0x%08x class 0x%08x",
-          READ_DWORD(&xcept->mdhi), READ_DWORD(&xcept->mdlo),
-					READ_DWORD(&xcept->reseverd), READ_DWORD(&xcept->xclass)))
-}
+dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exceptionFrame)
+{
+	MP_XCPTC __iomem *xcept = (MP_XCPTC __iomem *)exceptionFrame;
+	dword    __iomem *regs;
+	regs  = &xcept->regs[0];
+	DBG_FTL(("%s: ***************** CPU TRAPPED *****************",
+		 &IoAdapter->Name[0]))
+		DBG_FTL(("Microcode: %s", &IoAdapter->ProtocolIdString[0]))
+		DBG_FTL(("Cause: %s",
+			 ExceptionCauseTable[(READ_DWORD(&xcept->cr) & 0x0000007c) >> 2]))
+		DBG_FTL(("sr    0x%08x cr    0x%08x epc   0x%08x vaddr 0x%08x",
+			 READ_DWORD(&xcept->sr), READ_DWORD(&xcept->cr),
+			 READ_DWORD(&xcept->epc), READ_DWORD(&xcept->vaddr)))
+		DBG_FTL(("zero  0x%08x at    0x%08x v0    0x%08x v1    0x%08x",
+			 READ_DWORD(&regs[0]), READ_DWORD(&regs[1]),
+			 READ_DWORD(&regs[2]), READ_DWORD(&regs[3])))
+		DBG_FTL(("a0    0x%08x a1    0x%08x a2    0x%08x a3    0x%08x",
+			 READ_DWORD(&regs[4]), READ_DWORD(&regs[5]),
+			 READ_DWORD(&regs[6]), READ_DWORD(&regs[7])))
+		DBG_FTL(("t0    0x%08x t1    0x%08x t2    0x%08x t3    0x%08x",
+			 READ_DWORD(&regs[8]), READ_DWORD(&regs[9]),
+			 READ_DWORD(&regs[10]), READ_DWORD(&regs[11])))
+		DBG_FTL(("t4    0x%08x t5    0x%08x t6    0x%08x t7    0x%08x",
+			 READ_DWORD(&regs[12]), READ_DWORD(&regs[13]),
+			 READ_DWORD(&regs[14]), READ_DWORD(&regs[15])))
+		DBG_FTL(("s0    0x%08x s1    0x%08x s2    0x%08x s3    0x%08x",
+			 READ_DWORD(&regs[16]), READ_DWORD(&regs[17]),
+			 READ_DWORD(&regs[18]), READ_DWORD(&regs[19])))
+		DBG_FTL(("s4    0x%08x s5    0x%08x s6    0x%08x s7    0x%08x",
+			 READ_DWORD(&regs[20]), READ_DWORD(&regs[21]),
+			 READ_DWORD(&regs[22]), READ_DWORD(&regs[23])))
+		DBG_FTL(("t8    0x%08x t9    0x%08x k0    0x%08x k1    0x%08x",
+			 READ_DWORD(&regs[24]), READ_DWORD(&regs[25]),
+			 READ_DWORD(&regs[26]), READ_DWORD(&regs[27])))
+		DBG_FTL(("gp    0x%08x sp    0x%08x s8    0x%08x ra    0x%08x",
+			 READ_DWORD(&regs[28]), READ_DWORD(&regs[29]),
+			 READ_DWORD(&regs[30]), READ_DWORD(&regs[31])))
+		DBG_FTL(("md    0x%08x|%08x         resvd 0x%08x class 0x%08x",
+			 READ_DWORD(&xcept->mdhi), READ_DWORD(&xcept->mdlo),
+			 READ_DWORD(&xcept->reseverd), READ_DWORD(&xcept->xclass)))
+		}
 /* --------------------------------------------------------------------------
-  Real XDI Request function
-  -------------------------------------------------------------------------- */
-void request(PISDN_ADAPTER IoAdapter, ENTITY * e)
+   Real XDI Request function
+   -------------------------------------------------------------------------- */
+void request(PISDN_ADAPTER IoAdapter, ENTITY *e)
 {
- byte i;
- diva_os_spin_lock_magic_t irql;
+	byte i;
+	diva_os_spin_lock_magic_t irql;
 /*
  * if the Req field in the entity structure is 0,
  * we treat this request as a special function call
  */
- if ( !e->Req )
- {
-  IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e ;
-  switch (e->Rc)
-  {
+	if (!e->Req)
+	{
+		IDI_SYNC_REQ *syncReq = (IDI_SYNC_REQ *)e;
+		switch (e->Rc)
+		{
 #if defined(DIVA_IDI_RX_DMA)
-    case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION: {
-      diva_xdi_dma_descriptor_operation_t* pI = \
-                                   &syncReq->xdi_dma_descriptor_operation.info;
-      if (!IoAdapter->dma_map) {
-        pI->operation         = -1;
-        pI->descriptor_number = -1;
-        return;
-      }
-      diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "dma_op");
-      if (pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC) {
-        pI->descriptor_number = diva_alloc_dma_map_entry (\
-                               (struct _diva_dma_map_entry*)IoAdapter->dma_map);
-        if (pI->descriptor_number >= 0) {
-          dword dma_magic;
-          void* local_addr;
-          diva_get_dma_map_entry (\
-                               (struct _diva_dma_map_entry*)IoAdapter->dma_map,
-                               pI->descriptor_number,
-                               &local_addr, &dma_magic);
-          pI->descriptor_address  = local_addr;
-          pI->descriptor_magic    = dma_magic;
-          pI->operation           = 0;
-        } else {
-          pI->operation           = -1;
-        }
-      } else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) &&
-                 (pI->descriptor_number >= 0)) {
-        diva_free_dma_map_entry((struct _diva_dma_map_entry*)IoAdapter->dma_map,
-                                pI->descriptor_number);
-        pI->descriptor_number = -1;
-        pI->operation         = 0;
-      } else {
-        pI->descriptor_number = -1;
-        pI->operation         = -1;
-      }
-      diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "dma_op");
-    } return;
+		case IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION: {
+			diva_xdi_dma_descriptor_operation_t *pI = \
+				&syncReq->xdi_dma_descriptor_operation.info;
+			if (!IoAdapter->dma_map) {
+				pI->operation         = -1;
+				pI->descriptor_number = -1;
+				return;
+			}
+			diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op");
+			if (pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC) {
+				pI->descriptor_number = diva_alloc_dma_map_entry(\
+					(struct _diva_dma_map_entry *)IoAdapter->dma_map);
+				if (pI->descriptor_number >= 0) {
+					dword dma_magic;
+					void *local_addr;
+					diva_get_dma_map_entry(\
+						(struct _diva_dma_map_entry *)IoAdapter->dma_map,
+						pI->descriptor_number,
+						&local_addr, &dma_magic);
+					pI->descriptor_address  = local_addr;
+					pI->descriptor_magic    = dma_magic;
+					pI->operation           = 0;
+				} else {
+					pI->operation           = -1;
+				}
+			} else if ((pI->operation == IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE) &&
+				   (pI->descriptor_number >= 0)) {
+				diva_free_dma_map_entry((struct _diva_dma_map_entry *)IoAdapter->dma_map,
+							pI->descriptor_number);
+				pI->descriptor_number = -1;
+				pI->operation         = 0;
+			} else {
+				pI->descriptor_number = -1;
+				pI->operation         = -1;
+			}
+			diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "dma_op");
+		} return;
 #endif
-    case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER: {
-      diva_xdi_get_logical_adapter_number_s_t *pI = \
-                                     &syncReq->xdi_logical_adapter_number.info;
-      pI->logical_adapter_number = IoAdapter->ANum;
-      pI->controller = IoAdapter->ControllerNumber;
-      pI->total_controllers = IoAdapter->Properties.Adapters;
-    } return;
-    case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: {
-       diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info;
-       memset (&prms, 0x00, sizeof(prms));
-       prms.structure_length = min_t(size_t, sizeof(prms), pI->structure_length);
-       memset (pI, 0x00, pI->structure_length);
-       prms.flag_dynamic_l1_down    = (IoAdapter->capi_cfg.cfg_1 & \
-         DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0;
-       prms.group_optimization_enabled = (IoAdapter->capi_cfg.cfg_1 & \
-         DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) ? 1 : 0;
-       memcpy (pI, &prms, prms.structure_length);
-      } return;
-    case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR:
-      syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar;
-      return;
-    case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES: {
-      dword i;
-      diva_xdi_get_extended_xdi_features_t* pI =\
-                                 &syncReq->xdi_extended_features.info;
-      pI->buffer_length_in_bytes &= ~0x80000000;
-      if (pI->buffer_length_in_bytes && pI->features) {
-        memset (pI->features, 0x00, pI->buffer_length_in_bytes);
-      }
-      for (i = 0; ((pI->features) && (i < pI->buffer_length_in_bytes) &&
-                   (i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ)); i++) {
-        pI->features[i] = extended_xdi_features[i];
-      }
-      if ((pI->buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ) ||
-          (!pI->features)) {
-        pI->buffer_length_in_bytes =\
-                           (0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ);
-      }
-     } return;
-    case IDI_SYNC_REQ_XDI_GET_STREAM:
-      if (IoAdapter) {
-        diva_xdi_provide_istream_info (&IoAdapter->a,
-                                       &syncReq->xdi_stream_info.info);
-      } else {
-        syncReq->xdi_stream_info.info.provided_service = 0;
-      }
-      return;
-  case IDI_SYNC_REQ_GET_NAME:
-   if ( IoAdapter )
-   {
-    strcpy (&syncReq->GetName.name[0], IoAdapter->Name) ;
-    DBG_TRC(("xdi: Adapter %d / Name '%s'",
-             IoAdapter->ANum, IoAdapter->Name))
-    return ;
-   }
-   syncReq->GetName.name[0] = '\0' ;
-   break ;
-  case IDI_SYNC_REQ_GET_SERIAL:
-   if ( IoAdapter )
-   {
-    syncReq->GetSerial.serial = IoAdapter->serialNo ;
-    DBG_TRC(("xdi: Adapter %d / SerialNo %ld",
-             IoAdapter->ANum, IoAdapter->serialNo))
-    return ;
-   }
-   syncReq->GetSerial.serial = 0 ;
-   break ;
-  case IDI_SYNC_REQ_GET_CARDTYPE:
-   if ( IoAdapter )
-   {
-    syncReq->GetCardType.cardtype = IoAdapter->cardType ;
-    DBG_TRC(("xdi: Adapter %d / CardType %ld",
-             IoAdapter->ANum, IoAdapter->cardType))
-    return ;
-   }
-   syncReq->GetCardType.cardtype = 0 ;
-   break ;
-  case IDI_SYNC_REQ_GET_XLOG:
-   if ( IoAdapter )
-   {
-    pcm_req (IoAdapter, e) ;
-    return ;
-   }
-   e->Ind = 0 ;
-   break ;
-  case IDI_SYNC_REQ_GET_DBG_XLOG:
-   if ( IoAdapter )
-   {
-    pcm_req (IoAdapter, e) ;
-    return ;
-   }
-   e->Ind = 0 ;
-   break ;
-  case IDI_SYNC_REQ_GET_FEATURES:
-   if ( IoAdapter )
-   {
-    syncReq->GetFeatures.features =
-      (unsigned short)IoAdapter->features ;
-    return ;
-   }
-   syncReq->GetFeatures.features = 0 ;
-   break ;
-        case IDI_SYNC_REQ_PORTDRV_HOOK:
-            if ( IoAdapter )
-            {
-                DBG_TRC(("Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored"))
-                return ;
-            }
-            break;
-  }
-  if ( IoAdapter )
-  {
-   return ;
-  }
- }
- DBG_TRC(("xdi: Id 0x%x / Req 0x%x / Rc 0x%x", e->Id, e->Req, e->Rc))
- if ( !IoAdapter )
- {
-  DBG_FTL(("xdi: uninitialized Adapter used - ignore request"))
-  return ;
- }
- diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req");
+		case IDI_SYNC_REQ_XDI_GET_LOGICAL_ADAPTER_NUMBER: {
+			diva_xdi_get_logical_adapter_number_s_t *pI = \
+				&syncReq->xdi_logical_adapter_number.info;
+			pI->logical_adapter_number = IoAdapter->ANum;
+			pI->controller = IoAdapter->ControllerNumber;
+			pI->total_controllers = IoAdapter->Properties.Adapters;
+		} return;
+		case IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS: {
+			diva_xdi_get_capi_parameters_t prms, *pI = &syncReq->xdi_capi_prms.info;
+			memset(&prms, 0x00, sizeof(prms));
+			prms.structure_length = min_t(size_t, sizeof(prms), pI->structure_length);
+			memset(pI, 0x00, pI->structure_length);
+			prms.flag_dynamic_l1_down    = (IoAdapter->capi_cfg.cfg_1 & \
+							DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? 1 : 0;
+			prms.group_optimization_enabled = (IoAdapter->capi_cfg.cfg_1 & \
+							   DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) ? 1 : 0;
+			memcpy(pI, &prms, prms.structure_length);
+		} return;
+		case IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR:
+			syncReq->xdi_sdram_bar.info.bar = IoAdapter->sdram_bar;
+			return;
+		case IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES: {
+			dword i;
+			diva_xdi_get_extended_xdi_features_t *pI =\
+				&syncReq->xdi_extended_features.info;
+			pI->buffer_length_in_bytes &= ~0x80000000;
+			if (pI->buffer_length_in_bytes && pI->features) {
+				memset(pI->features, 0x00, pI->buffer_length_in_bytes);
+			}
+			for (i = 0; ((pI->features) && (i < pI->buffer_length_in_bytes) &&
+				     (i < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ)); i++) {
+				pI->features[i] = extended_xdi_features[i];
+			}
+			if ((pI->buffer_length_in_bytes < DIVA_XDI_EXTENDED_FEATURES_MAX_SZ) ||
+			    (!pI->features)) {
+				pI->buffer_length_in_bytes =\
+					(0x80000000 | DIVA_XDI_EXTENDED_FEATURES_MAX_SZ);
+			}
+		} return;
+		case IDI_SYNC_REQ_XDI_GET_STREAM:
+			if (IoAdapter) {
+				diva_xdi_provide_istream_info(&IoAdapter->a,
+							      &syncReq->xdi_stream_info.info);
+			} else {
+				syncReq->xdi_stream_info.info.provided_service = 0;
+			}
+			return;
+		case IDI_SYNC_REQ_GET_NAME:
+			if (IoAdapter)
+			{
+				strcpy(&syncReq->GetName.name[0], IoAdapter->Name);
+				DBG_TRC(("xdi: Adapter %d / Name '%s'",
+					 IoAdapter->ANum, IoAdapter->Name))
+					return;
+			}
+			syncReq->GetName.name[0] = '\0';
+			break;
+		case IDI_SYNC_REQ_GET_SERIAL:
+			if (IoAdapter)
+			{
+				syncReq->GetSerial.serial = IoAdapter->serialNo;
+				DBG_TRC(("xdi: Adapter %d / SerialNo %ld",
+					 IoAdapter->ANum, IoAdapter->serialNo))
+					return;
+			}
+			syncReq->GetSerial.serial = 0;
+			break;
+		case IDI_SYNC_REQ_GET_CARDTYPE:
+			if (IoAdapter)
+			{
+				syncReq->GetCardType.cardtype = IoAdapter->cardType;
+				DBG_TRC(("xdi: Adapter %d / CardType %ld",
+					 IoAdapter->ANum, IoAdapter->cardType))
+					return;
+			}
+			syncReq->GetCardType.cardtype = 0;
+			break;
+		case IDI_SYNC_REQ_GET_XLOG:
+			if (IoAdapter)
+			{
+				pcm_req(IoAdapter, e);
+				return;
+			}
+			e->Ind = 0;
+			break;
+		case IDI_SYNC_REQ_GET_DBG_XLOG:
+			if (IoAdapter)
+			{
+				pcm_req(IoAdapter, e);
+				return;
+			}
+			e->Ind = 0;
+			break;
+		case IDI_SYNC_REQ_GET_FEATURES:
+			if (IoAdapter)
+			{
+				syncReq->GetFeatures.features =
+					(unsigned short)IoAdapter->features;
+				return;
+			}
+			syncReq->GetFeatures.features = 0;
+			break;
+		case IDI_SYNC_REQ_PORTDRV_HOOK:
+			if (IoAdapter)
+			{
+				DBG_TRC(("Xdi:IDI_SYNC_REQ_PORTDRV_HOOK - ignored"))
+					return;
+			}
+			break;
+		}
+		if (IoAdapter)
+		{
+			return;
+		}
+	}
+	DBG_TRC(("xdi: Id 0x%x / Req 0x%x / Rc 0x%x", e->Id, e->Req, e->Rc))
+		if (!IoAdapter)
+		{
+			DBG_FTL(("xdi: uninitialized Adapter used - ignore request"))
+				return;
+		}
+	diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
 /*
  * assign an entity
  */
- if ( !(e->Id &0x1f) )
- {
-  if ( IoAdapter->e_count >= IoAdapter->e_max )
-  {
-   DBG_FTL(("xdi: all Ids in use (max=%d) --> Req ignored",
-            IoAdapter->e_max))
-   diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req");
-   return ;
-  }
+	if (!(e->Id & 0x1f))
+	{
+		if (IoAdapter->e_count >= IoAdapter->e_max)
+		{
+			DBG_FTL(("xdi: all Ids in use (max=%d) --> Req ignored",
+				 IoAdapter->e_max))
+				diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
+			return;
+		}
 /*
  * find a new free id
  */
-  for ( i = 1 ; IoAdapter->e_tbl[i].e ; ++i ) ;
-  IoAdapter->e_tbl[i].e = e ;
-  IoAdapter->e_count++ ;
-  e->No = (byte)i ;
-  e->More = 0 ;
-  e->RCurrent = 0xff ;
- }
- else
- {
-  i = e->No ;
- }
+		for (i = 1; IoAdapter->e_tbl[i].e; ++i);
+		IoAdapter->e_tbl[i].e = e;
+		IoAdapter->e_count++;
+		e->No = (byte)i;
+		e->More = 0;
+		e->RCurrent = 0xff;
+	}
+	else
+	{
+		i = e->No;
+	}
 /*
  * if the entity is still busy, ignore the request call
  */
- if ( e->More & XBUSY )
- {
-  DBG_FTL(("xdi: Id 0x%x busy --> Req 0x%x ignored", e->Id, e->Req))
-  if ( !IoAdapter->trapped && IoAdapter->trapFnc )
-  {
-   IoAdapter->trapFnc (IoAdapter) ;
-      /*
-        Firs trap, also notify user if supported
-       */
-      if (IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
-        (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
-      }
-  }
-  diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req");
-  return ;
- }
+	if (e->More & XBUSY)
+	{
+		DBG_FTL(("xdi: Id 0x%x busy --> Req 0x%x ignored", e->Id, e->Req))
+			if (!IoAdapter->trapped && IoAdapter->trapFnc)
+			{
+				IoAdapter->trapFnc(IoAdapter);
+				/*
+				  Firs trap, also notify user if supported
+				*/
+				if (IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
+					(*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
+				}
+			}
+		diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
+		return;
+	}
 /*
  * initialize transmit status variables
  */
- e->More |= XBUSY ;
- e->More &= ~XMOREF ;
- e->XCurrent = 0 ;
- e->XOffset = 0 ;
+	e->More |= XBUSY;
+	e->More &= ~XMOREF;
+	e->XCurrent = 0;
+	e->XOffset = 0;
 /*
  * queue this entity in the adapter request queue
  */
- IoAdapter->e_tbl[i].next = 0 ;
- if ( IoAdapter->head )
- {
-  IoAdapter->e_tbl[IoAdapter->tail].next = i ;
-  IoAdapter->tail = i ;
- }
- else
- {
-  IoAdapter->head = i ;
-  IoAdapter->tail = i ;
- }
+	IoAdapter->e_tbl[i].next = 0;
+	if (IoAdapter->head)
+	{
+		IoAdapter->e_tbl[IoAdapter->tail].next = i;
+		IoAdapter->tail = i;
+	}
+	else
+	{
+		IoAdapter->head = i;
+		IoAdapter->tail = i;
+	}
 /*
  * queue the DPC to process the request
  */
- diva_os_schedule_soft_isr (&IoAdapter->req_soft_isr);
- diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req");
+	diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
+	diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req");
 }
 /* ---------------------------------------------------------------------
-  Main DPC routine
+   Main DPC routine
    --------------------------------------------------------------------- */
-void DIDpcRoutine (struct _diva_os_soft_isr* psoft_isr, void* Context) {
- PISDN_ADAPTER IoAdapter  = (PISDN_ADAPTER)Context ;
- ADAPTER* a        = &IoAdapter->a ;
- diva_os_atomic_t* pin_dpc = &IoAdapter->in_dpc;
- if (diva_os_atomic_increment (pin_dpc) == 1) {
-  do {
-   if ( IoAdapter->tst_irq (a) )
-   {
-    if ( !IoAdapter->Unavailable )
-     IoAdapter->dpc (a) ;
-    IoAdapter->clr_irq (a) ;
-   }
-   IoAdapter->out (a) ;
-  } while (diva_os_atomic_decrement (pin_dpc) > 0);
-  /* ----------------------------------------------------------------
-    Look for XLOG request (cards with indirect addressing)
-    ---------------------------------------------------------------- */
-  if (IoAdapter->pcm_pending) {
-   struct pc_maint *pcm;
-   diva_os_spin_lock_magic_t OldIrql ;
-   diva_os_enter_spin_lock (&IoAdapter->data_spin_lock,
-                &OldIrql,
-                "data_dpc");
-   pcm = (struct pc_maint *)IoAdapter->pcm_data;
-   switch (IoAdapter->pcm_pending) {
-    case 1: /* ask card for XLOG */
-     a->ram_out (a, &IoAdapter->pcm->rc, 0) ;
-     a->ram_out (a, &IoAdapter->pcm->req, pcm->req) ;
-     IoAdapter->pcm_pending = 2;
-     break;
-    case 2: /* Try to get XLOG from the card */
-     if ((int)(a->ram_in (a, &IoAdapter->pcm->rc))) {
-      a->ram_in_buffer (a, IoAdapter->pcm, pcm, sizeof(*pcm)) ;
-      IoAdapter->pcm_pending = 3;
-     }
-     break;
-    case 3: /* let XDI recovery XLOG */
-     break;
-   }
-   diva_os_leave_spin_lock (&IoAdapter->data_spin_lock,
-                &OldIrql,
-                "data_dpc");
-  }
-  /* ---------------------------------------------------------------- */
- }
+void DIDpcRoutine(struct _diva_os_soft_isr *psoft_isr, void *Context) {
+	PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)Context;
+	ADAPTER *a = &IoAdapter->a;
+	diva_os_atomic_t *pin_dpc = &IoAdapter->in_dpc;
+	if (diva_os_atomic_increment(pin_dpc) == 1) {
+		do {
+			if (IoAdapter->tst_irq(a))
+			{
+				if (!IoAdapter->Unavailable)
+					IoAdapter->dpc(a);
+				IoAdapter->clr_irq(a);
+			}
+			IoAdapter->out(a);
+		} while (diva_os_atomic_decrement(pin_dpc) > 0);
+		/* ----------------------------------------------------------------
+		   Look for XLOG request (cards with indirect addressing)
+		   ---------------------------------------------------------------- */
+		if (IoAdapter->pcm_pending) {
+			struct pc_maint *pcm;
+			diva_os_spin_lock_magic_t OldIrql;
+			diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
+						&OldIrql,
+						"data_dpc");
+			pcm = (struct pc_maint *)IoAdapter->pcm_data;
+			switch (IoAdapter->pcm_pending) {
+			case 1: /* ask card for XLOG */
+				a->ram_out(a, &IoAdapter->pcm->rc, 0);
+				a->ram_out(a, &IoAdapter->pcm->req, pcm->req);
+				IoAdapter->pcm_pending = 2;
+				break;
+			case 2: /* Try to get XLOG from the card */
+				if ((int)(a->ram_in(a, &IoAdapter->pcm->rc))) {
+					a->ram_in_buffer(a, IoAdapter->pcm, pcm, sizeof(*pcm));
+					IoAdapter->pcm_pending = 3;
+				}
+				break;
+			case 3: /* let XDI recovery XLOG */
+				break;
+			}
+			diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
+						&OldIrql,
+						"data_dpc");
+		}
+		/* ---------------------------------------------------------------- */
+	}
 }
 /* --------------------------------------------------------------------------
-  XLOG interface
-  -------------------------------------------------------------------------- */
+   XLOG interface
+   -------------------------------------------------------------------------- */
 static void
-pcm_req (PISDN_ADAPTER IoAdapter, ENTITY *e)
+pcm_req(PISDN_ADAPTER IoAdapter, ENTITY *e)
 {
- diva_os_spin_lock_magic_t OldIrql ;
- int              i, rc ;
- ADAPTER         *a = &IoAdapter->a ;
- struct pc_maint *pcm = (struct pc_maint *)&e->Ind ;
+	diva_os_spin_lock_magic_t OldIrql;
+	int              i, rc;
+	ADAPTER         *a = &IoAdapter->a;
+	struct pc_maint *pcm = (struct pc_maint *)&e->Ind;
 /*
  * special handling of I/O based card interface
  * the memory access isn't an atomic operation !
  */
- if ( IoAdapter->Properties.Card == CARD_MAE )
- {
-  diva_os_enter_spin_lock (&IoAdapter->data_spin_lock,
-               &OldIrql,
-               "data_pcm_1");
-  IoAdapter->pcm_data = (void *)pcm;
-  IoAdapter->pcm_pending = 1;
-  diva_os_schedule_soft_isr (&IoAdapter->req_soft_isr);
-  diva_os_leave_spin_lock (&IoAdapter->data_spin_lock,
-               &OldIrql,
-               "data_pcm_1");
-  for ( rc = 0, i = (IoAdapter->trapped ? 3000 : 250) ; !rc && (i > 0) ; --i )
-  {
-   diva_os_sleep (1) ;
-   if (IoAdapter->pcm_pending == 3) {
-    diva_os_enter_spin_lock (&IoAdapter->data_spin_lock,
-                 &OldIrql,
-                 "data_pcm_3");
-    IoAdapter->pcm_pending = 0;
-    IoAdapter->pcm_data    = NULL ;
-    diva_os_leave_spin_lock (&IoAdapter->data_spin_lock,
-                 &OldIrql,
-                 "data_pcm_3");
-    return ;
-   }
-   diva_os_enter_spin_lock (&IoAdapter->data_spin_lock,
-                &OldIrql,
-                "data_pcm_2");
-   diva_os_schedule_soft_isr (&IoAdapter->req_soft_isr);
-   diva_os_leave_spin_lock (&IoAdapter->data_spin_lock,
-                &OldIrql,
-                "data_pcm_2");
-  }
-  diva_os_enter_spin_lock (&IoAdapter->data_spin_lock,
-               &OldIrql,
-               "data_pcm_4");
-  IoAdapter->pcm_pending = 0;
-  IoAdapter->pcm_data    = NULL ;
-  diva_os_leave_spin_lock (&IoAdapter->data_spin_lock,
-               &OldIrql,
-               "data_pcm_4");
-  goto Trapped ;
- }
+	if (IoAdapter->Properties.Card == CARD_MAE)
+	{
+		diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
+					&OldIrql,
+					"data_pcm_1");
+		IoAdapter->pcm_data = (void *)pcm;
+		IoAdapter->pcm_pending = 1;
+		diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
+		diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
+					&OldIrql,
+					"data_pcm_1");
+		for (rc = 0, i = (IoAdapter->trapped ? 3000 : 250); !rc && (i > 0); --i)
+		{
+			diva_os_sleep(1);
+			if (IoAdapter->pcm_pending == 3) {
+				diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
+							&OldIrql,
+							"data_pcm_3");
+				IoAdapter->pcm_pending = 0;
+				IoAdapter->pcm_data    = NULL;
+				diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
+							&OldIrql,
+							"data_pcm_3");
+				return;
+			}
+			diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
+						&OldIrql,
+						"data_pcm_2");
+			diva_os_schedule_soft_isr(&IoAdapter->req_soft_isr);
+			diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
+						&OldIrql,
+						"data_pcm_2");
+		}
+		diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
+					&OldIrql,
+					"data_pcm_4");
+		IoAdapter->pcm_pending = 0;
+		IoAdapter->pcm_data    = NULL;
+		diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
+					&OldIrql,
+					"data_pcm_4");
+		goto Trapped;
+	}
 /*
  * memory based shared ram is accessible from different
  * processors without disturbing concurrent processes.
  */
- a->ram_out (a, &IoAdapter->pcm->rc, 0) ;
- a->ram_out (a, &IoAdapter->pcm->req, pcm->req) ;
- for ( i = (IoAdapter->trapped ? 3000 : 250) ; --i > 0 ; )
- {
-  diva_os_sleep (1) ;
-  rc = (int)(a->ram_in (a, &IoAdapter->pcm->rc)) ;
-  if ( rc )
-  {
-   a->ram_in_buffer (a, IoAdapter->pcm, pcm, sizeof(*pcm)) ;
-   return ;
-  }
- }
+	a->ram_out(a, &IoAdapter->pcm->rc, 0);
+	a->ram_out(a, &IoAdapter->pcm->req, pcm->req);
+	for (i = (IoAdapter->trapped ? 3000 : 250); --i > 0;)
+	{
+		diva_os_sleep(1);
+		rc = (int)(a->ram_in(a, &IoAdapter->pcm->rc));
+		if (rc)
+		{
+			a->ram_in_buffer(a, IoAdapter->pcm, pcm, sizeof(*pcm));
+			return;
+		}
+	}
 Trapped:
- if ( IoAdapter->trapFnc )
- {
-    int trapped = IoAdapter->trapped;
-  IoAdapter->trapFnc (IoAdapter) ;
-    /*
-      Firs trap, also notify user if supported
-     */
-    if (!trapped && IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
-      (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
-    }
- }
+	if (IoAdapter->trapFnc)
+	{
+		int trapped = IoAdapter->trapped;
+		IoAdapter->trapFnc(IoAdapter);
+		/*
+		  Firs trap, also notify user if supported
+		*/
+		if (!trapped && IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) {
+			(*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum);
+		}
+	}
 }
 /*------------------------------------------------------------------*/
 /* ram access functions for memory mapped cards                     */
 /*------------------------------------------------------------------*/
-byte mem_in (ADAPTER *a, void *addr)
+byte mem_in(ADAPTER *a, void *addr)
 {
- byte val;
- volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- val = READ_BYTE(Base + (unsigned long)addr);
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
- return (val);
+	byte val;
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	val = READ_BYTE(Base + (unsigned long)addr);
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	return (val);
 }
-word mem_inw (ADAPTER *a, void *addr)
+word mem_inw(ADAPTER *a, void *addr)
 {
- word val;
- volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- val = READ_WORD((Base + (unsigned long)addr));
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
- return (val);
+	word val;
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	val = READ_WORD((Base + (unsigned long)addr));
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	return (val);
 }
-void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords)
+void mem_in_dw(ADAPTER *a, void *addr, dword *data, int dwords)
 {
- volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- while (dwords--) {
-  *data++ = READ_DWORD((Base + (unsigned long)addr));
-  addr+=4;
- }
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	while (dwords--) {
+		*data++ = READ_DWORD((Base + (unsigned long)addr));
+		addr += 4;
+	}
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
-void mem_in_buffer (ADAPTER *a, void *addr, void *buffer, word length)
+void mem_in_buffer(ADAPTER *a, void *addr, void *buffer, word length)
 {
- volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- memcpy_fromio(buffer, (Base + (unsigned long)addr), length);
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	memcpy_fromio(buffer, (Base + (unsigned long)addr), length);
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
-void mem_look_ahead (ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
+void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
 {
- PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io ;
- IoAdapter->RBuffer.length = mem_inw (a, &RBuffer->length) ;
- mem_in_buffer (a, RBuffer->P, IoAdapter->RBuffer.P,
-                IoAdapter->RBuffer.length) ;
- e->RBuffer = (DBUFFER *)&IoAdapter->RBuffer ;
+	PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io;
+	IoAdapter->RBuffer.length = mem_inw(a, &RBuffer->length);
+	mem_in_buffer(a, RBuffer->P, IoAdapter->RBuffer.P,
+		      IoAdapter->RBuffer.length);
+	e->RBuffer = (DBUFFER *)&IoAdapter->RBuffer;
 }
-void mem_out (ADAPTER *a, void *addr, byte data)
+void mem_out(ADAPTER *a, void *addr, byte data)
 {
- volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- WRITE_BYTE(Base + (unsigned long)addr, data);
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	WRITE_BYTE(Base + (unsigned long)addr, data);
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
-void mem_outw (ADAPTER *a, void *addr, word data)
+void mem_outw(ADAPTER *a, void *addr, word data)
 {
- volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- WRITE_WORD((Base + (unsigned long)addr), data);
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	WRITE_WORD((Base + (unsigned long)addr), data);
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
-void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords)
+void mem_out_dw(ADAPTER *a, void *addr, const dword *data, int dwords)
 {
- volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- while (dwords--) {
-	WRITE_DWORD((Base + (unsigned long)addr), *data);
-  	addr+=4;
-	data++;
- }
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	while (dwords--) {
+		WRITE_DWORD((Base + (unsigned long)addr), *data);
+		addr += 4;
+		data++;
+	}
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
-void mem_out_buffer (ADAPTER *a, void *addr, void *buffer, word length)
+void mem_out_buffer(ADAPTER *a, void *addr, void *buffer, word length)
 {
- volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- memcpy_toio((Base + (unsigned long)addr), buffer, length) ;
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	memcpy_toio((Base + (unsigned long)addr), buffer, length);
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
-void mem_inc (ADAPTER *a, void *addr)
+void mem_inc(ADAPTER *a, void *addr)
 {
- volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
- byte  x = READ_BYTE(Base + (unsigned long)addr);
- WRITE_BYTE(Base + (unsigned long)addr, x + 1);
- DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
+	volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io);
+	byte  x = READ_BYTE(Base + (unsigned long)addr);
+	WRITE_BYTE(Base + (unsigned long)addr, x + 1);
+	DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);
 }
 /*------------------------------------------------------------------*/
 /* ram access functions for io-mapped cards                         */
 /*------------------------------------------------------------------*/
-byte io_in(ADAPTER * a, void * adr)
-{
-  byte val;
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  outppw(Port + 4, (word)(unsigned long)adr);
-  val = inpp(Port);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-  return(val);
-}
-word io_inw(ADAPTER * a, void * adr)
-{
-  word val;
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  outppw(Port + 4, (word)(unsigned long)adr);
-  val = inppw(Port);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-  return(val);
-}
-void io_in_buffer(ADAPTER * a, void * adr, void * buffer, word len)
-{
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  byte* P = (byte*)buffer;
-  if ((long)adr & 1) {
-    outppw(Port+4, (word)(unsigned long)adr);
-    *P = inpp(Port);
-    P++;
-    adr = ((byte *) adr) + 1;
-    len--;
-    if (!len) {
+byte io_in(ADAPTER *a, void *adr)
+{
+	byte val;
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	outppw(Port + 4, (word)(unsigned long)adr);
+	val = inpp(Port);
+	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+	return (val);
+}
+word io_inw(ADAPTER *a, void *adr)
+{
+	word val;
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	outppw(Port + 4, (word)(unsigned long)adr);
+	val = inppw(Port);
+	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+	return (val);
+}
+void io_in_buffer(ADAPTER *a, void *adr, void *buffer, word len)
+{
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	byte *P = (byte *)buffer;
+	if ((long)adr & 1) {
+		outppw(Port + 4, (word)(unsigned long)adr);
+		*P = inpp(Port);
+		P++;
+		adr = ((byte *) adr) + 1;
+		len--;
+		if (!len) {
+			DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+			return;
+		}
+	}
+	outppw(Port + 4, (word)(unsigned long)adr);
+	inppw_buffer(Port, P, len + 1);
+	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+}
+void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
+{
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	outppw(Port + 4, (word)(unsigned long)RBuffer);
+	((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
+	inppw_buffer(Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
+	e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
 	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-	return;
-    }
-  }
-  outppw(Port+4, (word)(unsigned long)adr);
-  inppw_buffer (Port, P, len+1);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-}
-void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e)
-{
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  outppw(Port+4, (word)(unsigned long)RBuffer);
-  ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port);
-  inppw_buffer (Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1);
-  e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-}
-void io_out(ADAPTER * a, void * adr, byte data)
-{
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  outppw(Port+4, (word)(unsigned long)adr);
-  outpp(Port, data);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-}
-void io_outw(ADAPTER * a, void * adr, word data)
-{
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  outppw(Port+4, (word)(unsigned long)adr);
-  outppw(Port, data);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-}
-void io_out_buffer(ADAPTER * a, void * adr, void * buffer, word len)
-{
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  byte* P = (byte*)buffer;
-  if ((long)adr & 1) {
-    outppw(Port+4, (word)(unsigned long)adr);
-    outpp(Port, *P);
-    P++;
-    adr = ((byte *) adr) + 1;
-    len--;
-    if (!len) {
+}
+void io_out(ADAPTER *a, void *adr, byte data)
+{
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	outppw(Port + 4, (word)(unsigned long)adr);
+	outpp(Port, data);
+	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+}
+void io_outw(ADAPTER *a, void *adr, word data)
+{
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	outppw(Port + 4, (word)(unsigned long)adr);
+	outppw(Port, data);
+	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+}
+void io_out_buffer(ADAPTER *a, void *adr, void *buffer, word len)
+{
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	byte *P = (byte *)buffer;
+	if ((long)adr & 1) {
+		outppw(Port + 4, (word)(unsigned long)adr);
+		outpp(Port, *P);
+		P++;
+		adr = ((byte *) adr) + 1;
+		len--;
+		if (!len) {
+			DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+			return;
+		}
+	}
+	outppw(Port + 4, (word)(unsigned long)adr);
+	outppw_buffer(Port, P, len + 1);
+	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
+}
+void io_inc(ADAPTER *a, void *adr)
+{
+	byte x;
+	byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
+	outppw(Port + 4, (word)(unsigned long)adr);
+	x = inpp(Port);
+	outppw(Port + 4, (word)(unsigned long)adr);
+	outpp(Port, x + 1);
 	DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-	return;
-    }
-  }
-  outppw(Port+4, (word)(unsigned long)adr);
-  outppw_buffer (Port, P, len+1);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
-}
-void io_inc(ADAPTER * a, void * adr)
-{
-  byte x;
-  byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io);
-  outppw(Port+4, (word)(unsigned long)adr);
-  x = inpp(Port);
-  outppw(Port+4, (word)(unsigned long)adr);
-  outpp(Port, x+1);
-  DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);
 }
 /*------------------------------------------------------------------*/
 /* OS specific functions related to queuing of entities             */
 /*------------------------------------------------------------------*/
-void free_entity(ADAPTER * a, byte e_no)
-{
-  PISDN_ADAPTER IoAdapter;
- diva_os_spin_lock_magic_t irql;
-  IoAdapter = (PISDN_ADAPTER) a->io;
- diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_free");
-  IoAdapter->e_tbl[e_no].e = NULL;
-  IoAdapter->e_count--;
- diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_free");
-}
-void assign_queue(ADAPTER * a, byte e_no, word ref)
-{
-  PISDN_ADAPTER IoAdapter;
- diva_os_spin_lock_magic_t irql;
-  IoAdapter = (PISDN_ADAPTER) a->io;
- diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_assign");
-  IoAdapter->e_tbl[e_no].assign_ref = ref;
-  IoAdapter->e_tbl[e_no].next = (byte)IoAdapter->assign;
-  IoAdapter->assign = e_no;
- diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_assign");
-}
-byte get_assign(ADAPTER * a, word ref)
-{
-  PISDN_ADAPTER IoAdapter;
- diva_os_spin_lock_magic_t irql;
-  byte e_no;
-  IoAdapter = (PISDN_ADAPTER) a->io;
- diva_os_enter_spin_lock (&IoAdapter->data_spin_lock,
-              &irql,
-              "data_assign_get");
-  for(e_no = (byte)IoAdapter->assign;
-      e_no && IoAdapter->e_tbl[e_no].assign_ref!=ref;
-      e_no = IoAdapter->e_tbl[e_no].next);
- diva_os_leave_spin_lock (&IoAdapter->data_spin_lock,
-              &irql,
-              "data_assign_get");
-  return e_no;
-}
-void req_queue(ADAPTER * a, byte e_no)
-{
-  PISDN_ADAPTER IoAdapter;
- diva_os_spin_lock_magic_t irql;
-  IoAdapter = (PISDN_ADAPTER) a->io;
- diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_q");
-  IoAdapter->e_tbl[e_no].next = 0;
-  if(IoAdapter->head) {
-    IoAdapter->e_tbl[IoAdapter->tail].next = e_no;
-    IoAdapter->tail = e_no;
-  }
-  else {
-    IoAdapter->head = e_no;
-    IoAdapter->tail = e_no;
-  }
- diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_q");
-}
-byte look_req(ADAPTER * a)
-{
-  PISDN_ADAPTER IoAdapter;
-  IoAdapter = (PISDN_ADAPTER) a->io;
-  return ((byte)IoAdapter->head) ;
-}
-void next_req(ADAPTER * a)
-{
-  PISDN_ADAPTER IoAdapter;
- diva_os_spin_lock_magic_t irql;
-  IoAdapter = (PISDN_ADAPTER) a->io;
- diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_next");
-  IoAdapter->head = IoAdapter->e_tbl[IoAdapter->head].next;
-  if(!IoAdapter->head) IoAdapter->tail = 0;
- diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_next");
+void free_entity(ADAPTER *a, byte e_no)
+{
+	PISDN_ADAPTER IoAdapter;
+	diva_os_spin_lock_magic_t irql;
+	IoAdapter = (PISDN_ADAPTER) a->io;
+	diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_free");
+	IoAdapter->e_tbl[e_no].e = NULL;
+	IoAdapter->e_count--;
+	diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_free");
+}
+void assign_queue(ADAPTER *a, byte e_no, word ref)
+{
+	PISDN_ADAPTER IoAdapter;
+	diva_os_spin_lock_magic_t irql;
+	IoAdapter = (PISDN_ADAPTER) a->io;
+	diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_assign");
+	IoAdapter->e_tbl[e_no].assign_ref = ref;
+	IoAdapter->e_tbl[e_no].next = (byte)IoAdapter->assign;
+	IoAdapter->assign = e_no;
+	diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_assign");
+}
+byte get_assign(ADAPTER *a, word ref)
+{
+	PISDN_ADAPTER IoAdapter;
+	diva_os_spin_lock_magic_t irql;
+	byte e_no;
+	IoAdapter = (PISDN_ADAPTER) a->io;
+	diva_os_enter_spin_lock(&IoAdapter->data_spin_lock,
+				&irql,
+				"data_assign_get");
+	for (e_no = (byte)IoAdapter->assign;
+	    e_no && IoAdapter->e_tbl[e_no].assign_ref != ref;
+	    e_no = IoAdapter->e_tbl[e_no].next);
+	diva_os_leave_spin_lock(&IoAdapter->data_spin_lock,
+				&irql,
+				"data_assign_get");
+	return e_no;
+}
+void req_queue(ADAPTER *a, byte e_no)
+{
+	PISDN_ADAPTER IoAdapter;
+	diva_os_spin_lock_magic_t irql;
+	IoAdapter = (PISDN_ADAPTER) a->io;
+	diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_q");
+	IoAdapter->e_tbl[e_no].next = 0;
+	if (IoAdapter->head) {
+		IoAdapter->e_tbl[IoAdapter->tail].next = e_no;
+		IoAdapter->tail = e_no;
+	}
+	else {
+		IoAdapter->head = e_no;
+		IoAdapter->tail = e_no;
+	}
+	diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_q");
+}
+byte look_req(ADAPTER *a)
+{
+	PISDN_ADAPTER IoAdapter;
+	IoAdapter = (PISDN_ADAPTER) a->io;
+	return ((byte)IoAdapter->head);
+}
+void next_req(ADAPTER *a)
+{
+	PISDN_ADAPTER IoAdapter;
+	diva_os_spin_lock_magic_t irql;
+	IoAdapter = (PISDN_ADAPTER) a->io;
+	diva_os_enter_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_next");
+	IoAdapter->head = IoAdapter->e_tbl[IoAdapter->head].next;
+	if (!IoAdapter->head) IoAdapter->tail = 0;
+	diva_os_leave_spin_lock(&IoAdapter->data_spin_lock, &irql, "data_req_next");
 }
 /*------------------------------------------------------------------*/
 /* memory map functions                                             */
 /*------------------------------------------------------------------*/
-ENTITY * entity_ptr(ADAPTER * a, byte e_no)
+ENTITY *entity_ptr(ADAPTER *a, byte e_no)
 {
-  PISDN_ADAPTER IoAdapter;
-  IoAdapter = (PISDN_ADAPTER) a->io;
-  return (IoAdapter->e_tbl[e_no].e);
+	PISDN_ADAPTER IoAdapter;
+	IoAdapter = (PISDN_ADAPTER)a->io;
+	return (IoAdapter->e_tbl[e_no].e);
 }
-void * PTR_X(ADAPTER * a, ENTITY * e)
+void *PTR_X(ADAPTER *a, ENTITY *e)
 {
-  return ((void *) e->X);
+	return ((void *) e->X);
 }
-void * PTR_R(ADAPTER * a, ENTITY * e)
+void *PTR_R(ADAPTER *a, ENTITY *e)
 {
-  return ((void *) e->R);
+	return ((void *) e->R);
 }
-void * PTR_P(ADAPTER * a, ENTITY * e, void * P)
+void *PTR_P(ADAPTER *a, ENTITY *e, void *P)
 {
-  return P;
+	return P;
 }
-void CALLBACK(ADAPTER * a, ENTITY * e)
+void CALLBACK(ADAPTER *a, ENTITY *e)
 {
- if ( e && e->callback )
-  e->callback (e) ;
+	if (e && e->callback)
+		e->callback(e);
 }
diff --git a/drivers/isdn/hardware/eicon/io.h b/drivers/isdn/hardware/eicon/io.h
index a6f1755..01deced 100644
--- a/drivers/isdn/hardware/eicon/io.h
+++ b/drivers/isdn/hardware/eicon/io.h
@@ -1,308 +1,308 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_XDI_COMMON_IO_H_INC__ /* { */
 #define __DIVA_XDI_COMMON_IO_H_INC__
 /*
- maximum = 16 adapters
- */
+  maximum = 16 adapters
+*/
 #define DI_MAX_LINKS    MAX_ADAPTER
 #define ISDN_MAX_NUM_LEN 60
 /* --------------------------------------------------------------------------
-  structure for quadro card management (obsolete for
-  systems that do provide per card load event)
-  -------------------------------------------------------------------------- */
+   structure for quadro card management (obsolete for
+   systems that do provide per card load event)
+   -------------------------------------------------------------------------- */
 typedef struct {
- dword         Num ;
- DEVICE_NAME   DeviceName[4] ;
- PISDN_ADAPTER QuadroAdapter[4] ;
-} ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY ;
+	dword         Num;
+	DEVICE_NAME   DeviceName[4];
+	PISDN_ADAPTER QuadroAdapter[4];
+} ADAPTER_LIST_ENTRY, *PADAPTER_LIST_ENTRY;
 /* --------------------------------------------------------------------------
-  Special OS memory support structures
-  -------------------------------------------------------------------------- */
+   Special OS memory support structures
+   -------------------------------------------------------------------------- */
 #define MAX_MAPPED_ENTRIES 8
 typedef struct {
- void  * Address;
- dword    Length;
-} ADAPTER_MEMORY ;
+	void *Address;
+	dword    Length;
+} ADAPTER_MEMORY;
 /* --------------------------------------------------------------------------
-  Configuration of XDI clients carried by XDI
-  -------------------------------------------------------------------------- */
+   Configuration of XDI clients carried by XDI
+   -------------------------------------------------------------------------- */
 #define DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON      0x01
 #define DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON 0x02
 typedef struct _diva_xdi_capi_cfg {
-  byte cfg_1;
+	byte cfg_1;
 } diva_xdi_capi_cfg_t;
 /* --------------------------------------------------------------------------
-  Main data structure kept per adapter
-  -------------------------------------------------------------------------- */
+   Main data structure kept per adapter
+   -------------------------------------------------------------------------- */
 struct _ISDN_ADAPTER {
- void             (* DIRequest)(PISDN_ADAPTER, ENTITY *) ;
- int                 State ; /* from NT4 1.srv, a good idea, but  a poor achievement */
- int                 Initialized ;
- int         RegisteredWithDidd ;
- int                 Unavailable ;  /* callback function possible? */
- int         ResourcesClaimed ;
- int         PnpBiosConfigUsed ;
- dword        Logging ;
- dword        features ;
- char        ProtocolIdString[80] ;
- /*
-  remember mapped memory areas
- */
- ADAPTER_MEMORY     MappedMemory[MAX_MAPPED_ENTRIES] ;
- CARD_PROPERTIES     Properties ;
- dword               cardType ;
- dword               protocol_id ;       /* configured protocol identifier */
- char                protocol_name[8] ;  /* readable name of protocol */
- dword               BusType ;
- dword               BusNumber ;
- dword               slotNumber ;
- dword               slotId ;
- dword               ControllerNumber ;  /* for QUADRO cards only */
- PISDN_ADAPTER       MultiMaster ;       /* for 4-BRI card only - use MultiMaster or QuadroList */
- PADAPTER_LIST_ENTRY QuadroList ;        /* for QUADRO card  only */
- PDEVICE_OBJECT      DeviceObject ;
- dword               DeviceId ;
- diva_os_adapter_irq_info_t irq_info;
- dword volatile      IrqCount ;
- int                 trapped ;
- dword               DspCodeBaseAddr ;
- dword               MaxDspCodeSize ;
- dword               downloadAddr ;
- dword               DspCodeBaseAddrTable[4] ; /* add. for MultiMaster */
- dword               MaxDspCodeSizeTable[4] ; /* add. for MultiMaster */
- dword               downloadAddrTable[4] ; /* add. for MultiMaster */
- dword               MemoryBase ;
- dword               MemorySize ;
- byte                __iomem *Address ;
- byte                __iomem *Config ;
- byte                __iomem *Control ;
- byte                __iomem *reset ;
- byte                __iomem *port ;
- byte                __iomem *ram ;
- byte                __iomem *cfg ;
- byte                __iomem *prom ;
- byte                __iomem *ctlReg ;
- struct pc_maint  *pcm ;
- diva_os_dependent_devica_name_t os_name;
- byte                Name[32] ;
- dword               serialNo ;
- dword               ANum ;
- dword               ArchiveType ; /* ARCHIVE_TYPE_NONE ..._SINGLE ..._USGEN ..._MULTI */
- char               *ProtocolSuffix ; /* internal protocolfile table */
- char                Archive[32] ;
- char                Protocol[32] ;
- char                AddDownload[32] ; /* Dsp- or other additional download files */
- char                Oad1[ISDN_MAX_NUM_LEN] ;
- char                Osa1[ISDN_MAX_NUM_LEN] ;
- char                Oad2[ISDN_MAX_NUM_LEN] ;
- char                Osa2[ISDN_MAX_NUM_LEN] ;
- char                Spid1[ISDN_MAX_NUM_LEN] ;
- char                Spid2[ISDN_MAX_NUM_LEN] ;
-  byte                nosig ;
-  byte                BriLayer2LinkCount ; /* amount of TEI's that adapter will support in P2MP mode */
- dword               Channels ;
- dword               tei ;
- dword               nt2 ;
- dword               TerminalCount ;
- dword               WatchDog ;
- dword               Permanent ;
- dword               BChMask ; /* B channel mask for unchannelized modes */
- dword               StableL2 ;
- dword               DidLen ;
- dword               NoOrderCheck ;
- dword               ForceLaw; /* VoiceCoding - default:0, a-law: 1, my-law: 2 */
- dword               SigFlags ;
- dword               LowChannel ;
- dword               NoHscx30 ;
- dword               ProtVersion ;
- dword               crc4 ;
- dword               L1TristateOrQsig ; /* enable Layer 1 Tristate (bit 2)Or Qsig params (bit 0,1)*/
- dword               InitialDspInfo ;
- dword               ModemGuardTone ;
- dword               ModemMinSpeed ;
- dword               ModemMaxSpeed ;
- dword               ModemOptions ;
- dword               ModemOptions2 ;
- dword               ModemNegotiationMode ;
- dword               ModemModulationsMask ;
- dword               ModemTransmitLevel ;
- dword               FaxOptions ;
- dword               FaxMaxSpeed ;
- dword               Part68LevelLimiter ;
- dword               UsEktsNumCallApp ;
- byte                UsEktsFeatAddConf ;
- byte                UsEktsFeatRemoveConf ;
- byte                UsEktsFeatCallTransfer ;
- byte                UsEktsFeatMsgWaiting ;
- byte                QsigDialect;
- byte                ForceVoiceMailAlert;
- byte                DisableAutoSpid;
- byte                ModemCarrierWaitTimeSec;
- byte                ModemCarrierLossWaitTimeTenthSec;
- byte                PiafsLinkTurnaroundInFrames;
- byte                DiscAfterProgress;
- byte                AniDniLimiter[3];
- byte                TxAttenuation;  /* PRI/E1 only: attenuate TX signal */
- word                QsigFeatures;
- dword               GenerateRingtone ;
- dword               SupplementaryServicesFeatures;
- dword               R2Dialect;
- dword               R2CasOptions;
- dword               FaxV34Options;
- dword               DisabledDspMask;
- dword               AdapterTestMask;
- dword               DspImageLength;
- word                AlertToIn20mSecTicks;
- word                ModemEyeSetup;
- byte                R2CtryLength;
- byte                CCBSRelTimer;
- byte               *PcCfgBufferFile;/* flexible parameter via file */
- byte               *PcCfgBuffer ; /* flexible parameter via multistring */
- diva_os_dump_file_t dump_file; /* dump memory to file at lowest irq level */
- diva_os_board_trace_t board_trace ; /* traces from the board */
- diva_os_spin_lock_t isr_spin_lock;
- diva_os_spin_lock_t data_spin_lock;
- diva_os_soft_isr_t req_soft_isr;
- diva_os_soft_isr_t isr_soft_isr;
- diva_os_atomic_t  in_dpc;
- PBUFFER             RBuffer;        /* Copy of receive lookahead buffer */
- word                e_max;
- word                e_count;
- E_INFO             *e_tbl;
- word                assign;         /* list of pending ASSIGNs  */
- word                head;           /* head of request queue    */
- word                tail;           /* tail of request queue    */
- ADAPTER             a ;             /* not a separate structure */
- void        (* out)(ADAPTER * a) ;
- byte        (* dpc)(ADAPTER * a) ;
- byte        (* tst_irq)(ADAPTER * a) ;
- void        (* clr_irq)(ADAPTER * a) ;
- int         (* load)(PISDN_ADAPTER) ;
- int         (* mapmem)(PISDN_ADAPTER) ;
- int         (* chkIrq)(PISDN_ADAPTER) ;
- void        (* disIrq)(PISDN_ADAPTER) ;
- void        (* start)(PISDN_ADAPTER) ;
- void        (* stop)(PISDN_ADAPTER) ;
- void        (* rstFnc)(PISDN_ADAPTER) ;
- void        (* trapFnc)(PISDN_ADAPTER) ;
- dword            (* DetectDsps)(PISDN_ADAPTER) ;
- void        (* os_trap_nfy_Fnc)(PISDN_ADAPTER, dword) ;
- diva_os_isr_callback_t diva_isr_handler;
- dword               sdram_bar;  /* must be 32 bit */
- dword               fpga_features;
- volatile int        pcm_pending;
- volatile void *     pcm_data;
- diva_xdi_capi_cfg_t capi_cfg;
- dword               tasks;
- void               *dma_map;
- int             (*DivaAdapterTestProc)(PISDN_ADAPTER);
- void               *AdapterTestMemoryStart;
- dword               AdapterTestMemoryLength;
- const byte* cfg_lib_memory_init;
- dword       cfg_lib_memory_init_length;
+	void (*DIRequest)(PISDN_ADAPTER, ENTITY *);
+	int State; /* from NT4 1.srv, a good idea, but  a poor achievement */
+	int Initialized;
+	int RegisteredWithDidd;
+	int Unavailable;  /* callback function possible? */
+	int ResourcesClaimed;
+	int PnpBiosConfigUsed;
+	dword Logging;
+	dword features;
+	char ProtocolIdString[80];
+	/*
+	  remember mapped memory areas
+	*/
+	ADAPTER_MEMORY MappedMemory[MAX_MAPPED_ENTRIES];
+	CARD_PROPERTIES Properties;
+	dword cardType;
+	dword protocol_id;       /* configured protocol identifier */
+	char protocol_name[8];  /* readable name of protocol */
+	dword BusType;
+	dword BusNumber;
+	dword slotNumber;
+	dword slotId;
+	dword ControllerNumber;  /* for QUADRO cards only */
+	PISDN_ADAPTER MultiMaster;       /* for 4-BRI card only - use MultiMaster or QuadroList */
+	PADAPTER_LIST_ENTRY QuadroList;        /* for QUADRO card  only */
+	PDEVICE_OBJECT DeviceObject;
+	dword DeviceId;
+	diva_os_adapter_irq_info_t irq_info;
+	dword volatile IrqCount;
+	int trapped;
+	dword DspCodeBaseAddr;
+	dword MaxDspCodeSize;
+	dword downloadAddr;
+	dword DspCodeBaseAddrTable[4]; /* add. for MultiMaster */
+	dword MaxDspCodeSizeTable[4]; /* add. for MultiMaster */
+	dword downloadAddrTable[4]; /* add. for MultiMaster */
+	dword MemoryBase;
+	dword MemorySize;
+	byte __iomem *Address;
+	byte __iomem *Config;
+	byte __iomem *Control;
+	byte __iomem *reset;
+	byte __iomem *port;
+	byte __iomem *ram;
+	byte __iomem *cfg;
+	byte __iomem *prom;
+	byte __iomem *ctlReg;
+	struct pc_maint  *pcm;
+	diva_os_dependent_devica_name_t os_name;
+	byte Name[32];
+	dword serialNo;
+	dword ANum;
+	dword ArchiveType; /* ARCHIVE_TYPE_NONE ..._SINGLE ..._USGEN ..._MULTI */
+	char *ProtocolSuffix; /* internal protocolfile table */
+	char Archive[32];
+	char Protocol[32];
+	char AddDownload[32]; /* Dsp- or other additional download files */
+	char Oad1[ISDN_MAX_NUM_LEN];
+	char Osa1[ISDN_MAX_NUM_LEN];
+	char Oad2[ISDN_MAX_NUM_LEN];
+	char Osa2[ISDN_MAX_NUM_LEN];
+	char Spid1[ISDN_MAX_NUM_LEN];
+	char Spid2[ISDN_MAX_NUM_LEN];
+	byte nosig;
+	byte BriLayer2LinkCount; /* amount of TEI's that adapter will support in P2MP mode */
+	dword Channels;
+	dword tei;
+	dword nt2;
+	dword TerminalCount;
+	dword WatchDog;
+	dword Permanent;
+	dword BChMask; /* B channel mask for unchannelized modes */
+	dword StableL2;
+	dword DidLen;
+	dword NoOrderCheck;
+	dword ForceLaw; /* VoiceCoding - default:0, a-law: 1, my-law: 2 */
+	dword SigFlags;
+	dword LowChannel;
+	dword NoHscx30;
+	dword ProtVersion;
+	dword crc4;
+	dword L1TristateOrQsig; /* enable Layer 1 Tristate (bit 2)Or Qsig params (bit 0,1)*/
+	dword InitialDspInfo;
+	dword ModemGuardTone;
+	dword ModemMinSpeed;
+	dword ModemMaxSpeed;
+	dword ModemOptions;
+	dword ModemOptions2;
+	dword ModemNegotiationMode;
+	dword ModemModulationsMask;
+	dword ModemTransmitLevel;
+	dword FaxOptions;
+	dword FaxMaxSpeed;
+	dword Part68LevelLimiter;
+	dword UsEktsNumCallApp;
+	byte UsEktsFeatAddConf;
+	byte UsEktsFeatRemoveConf;
+	byte UsEktsFeatCallTransfer;
+	byte UsEktsFeatMsgWaiting;
+	byte QsigDialect;
+	byte ForceVoiceMailAlert;
+	byte DisableAutoSpid;
+	byte ModemCarrierWaitTimeSec;
+	byte ModemCarrierLossWaitTimeTenthSec;
+	byte PiafsLinkTurnaroundInFrames;
+	byte DiscAfterProgress;
+	byte AniDniLimiter[3];
+	byte TxAttenuation;  /* PRI/E1 only: attenuate TX signal */
+	word QsigFeatures;
+	dword GenerateRingtone;
+	dword SupplementaryServicesFeatures;
+	dword R2Dialect;
+	dword R2CasOptions;
+	dword FaxV34Options;
+	dword DisabledDspMask;
+	dword AdapterTestMask;
+	dword DspImageLength;
+	word AlertToIn20mSecTicks;
+	word ModemEyeSetup;
+	byte R2CtryLength;
+	byte CCBSRelTimer;
+	byte *PcCfgBufferFile;/* flexible parameter via file */
+	byte *PcCfgBuffer; /* flexible parameter via multistring */
+	diva_os_dump_file_t dump_file; /* dump memory to file at lowest irq level */
+	diva_os_board_trace_t board_trace; /* traces from the board */
+	diva_os_spin_lock_t isr_spin_lock;
+	diva_os_spin_lock_t data_spin_lock;
+	diva_os_soft_isr_t req_soft_isr;
+	diva_os_soft_isr_t isr_soft_isr;
+	diva_os_atomic_t  in_dpc;
+	PBUFFER RBuffer;        /* Copy of receive lookahead buffer */
+	word e_max;
+	word e_count;
+	E_INFO *e_tbl;
+	word assign;         /* list of pending ASSIGNs  */
+	word head;           /* head of request queue    */
+	word tail;           /* tail of request queue    */
+	ADAPTER a;             /* not a separate structure */
+	void (*out)(ADAPTER *a);
+	byte (*dpc)(ADAPTER *a);
+	byte (*tst_irq)(ADAPTER *a);
+	void (*clr_irq)(ADAPTER *a);
+	int (*load)(PISDN_ADAPTER);
+	int (*mapmem)(PISDN_ADAPTER);
+	int (*chkIrq)(PISDN_ADAPTER);
+	void (*disIrq)(PISDN_ADAPTER);
+	void (*start)(PISDN_ADAPTER);
+	void (*stop)(PISDN_ADAPTER);
+	void (*rstFnc)(PISDN_ADAPTER);
+	void (*trapFnc)(PISDN_ADAPTER);
+	dword (*DetectDsps)(PISDN_ADAPTER);
+	void (*os_trap_nfy_Fnc)(PISDN_ADAPTER, dword);
+	diva_os_isr_callback_t diva_isr_handler;
+	dword sdram_bar;  /* must be 32 bit */
+	dword fpga_features;
+	volatile int pcm_pending;
+	volatile void *pcm_data;
+	diva_xdi_capi_cfg_t capi_cfg;
+	dword tasks;
+	void *dma_map;
+	int (*DivaAdapterTestProc)(PISDN_ADAPTER);
+	void *AdapterTestMemoryStart;
+	dword AdapterTestMemoryLength;
+	const byte *cfg_lib_memory_init;
+	dword cfg_lib_memory_init_length;
 };
 /* ---------------------------------------------------------------------
-  Entity table
+   Entity table
    --------------------------------------------------------------------- */
 struct e_info_s {
-  ENTITY *      e;
-  byte          next;                   /* chaining index           */
-  word          assign_ref;             /* assign reference         */
+	ENTITY *e;
+	byte          next;                   /* chaining index           */
+	word          assign_ref;             /* assign reference         */
 };
 /* ---------------------------------------------------------------------
-  S-cards shared ram structure for loading
+   S-cards shared ram structure for loading
    --------------------------------------------------------------------- */
 struct s_load {
- byte ctrl;
- byte card;
- byte msize;
- byte fill0;
- word ebit;
- word elocl;
- word eloch;
- byte reserved[20];
- word signature;
- byte fill[224];
- byte b[256];
+	byte ctrl;
+	byte card;
+	byte msize;
+	byte fill0;
+	word ebit;
+	word elocl;
+	word eloch;
+	byte reserved[20];
+	word signature;
+	byte fill[224];
+	byte b[256];
 };
 #define PR_RAM  ((struct pr_ram *)0)
 #define RAM ((struct dual *)0)
 /* ---------------------------------------------------------------------
-  platform specific conversions
+   platform specific conversions
    --------------------------------------------------------------------- */
-extern void * PTR_P(ADAPTER * a, ENTITY * e, void * P);
-extern void * PTR_X(ADAPTER * a, ENTITY * e);
-extern void * PTR_R(ADAPTER * a, ENTITY * e);
-extern void CALLBACK(ADAPTER * a, ENTITY * e);
-extern void set_ram(void * * adr_ptr);
+extern void *PTR_P(ADAPTER *a, ENTITY *e, void *P);
+extern void *PTR_X(ADAPTER *a, ENTITY *e);
+extern void *PTR_R(ADAPTER *a, ENTITY *e);
+extern void CALLBACK(ADAPTER *a, ENTITY *e);
+extern void set_ram(void **adr_ptr);
 /* ---------------------------------------------------------------------
-  ram access functions for io mapped cards
+   ram access functions for io mapped cards
    --------------------------------------------------------------------- */
-byte io_in(ADAPTER * a, void * adr);
-word io_inw(ADAPTER * a, void * adr);
-void io_in_buffer(ADAPTER * a, void * adr, void * P, word length);
-void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e);
-void io_out(ADAPTER * a, void * adr, byte data);
-void io_outw(ADAPTER * a, void * adr, word data);
-void io_out_buffer(ADAPTER * a, void * adr, void * P, word length);
-void io_inc(ADAPTER * a, void * adr);
-void bri_in_buffer (PISDN_ADAPTER IoAdapter, dword Pos,
-                    void *Buf, dword Len);
-int bri_out_buffer (PISDN_ADAPTER IoAdapter, dword Pos,
-                    void *Buf, dword Len, int Verify);
+byte io_in(ADAPTER *a, void *adr);
+word io_inw(ADAPTER *a, void *adr);
+void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);
+void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
+void io_out(ADAPTER *a, void *adr, byte data);
+void io_outw(ADAPTER *a, void *adr, word data);
+void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);
+void io_inc(ADAPTER *a, void *adr);
+void bri_in_buffer(PISDN_ADAPTER IoAdapter, dword Pos,
+		   void *Buf, dword Len);
+int bri_out_buffer(PISDN_ADAPTER IoAdapter, dword Pos,
+		   void *Buf, dword Len, int Verify);
 /* ---------------------------------------------------------------------
-  ram access functions for memory mapped cards
+   ram access functions for memory mapped cards
    --------------------------------------------------------------------- */
-byte mem_in(ADAPTER * a, void * adr);
-word mem_inw(ADAPTER * a, void * adr);
-void mem_in_buffer(ADAPTER * a, void * adr, void * P, word length);
-void mem_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e);
-void mem_out(ADAPTER * a, void * adr, byte data);
-void mem_outw(ADAPTER * a, void * adr, word data);
-void mem_out_buffer(ADAPTER * a, void * adr, void * P, word length);
-void mem_inc(ADAPTER * a, void * adr);
-void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords);
-void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords);
+byte mem_in(ADAPTER *a, void *adr);
+word mem_inw(ADAPTER *a, void *adr);
+void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
+void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
+void mem_out(ADAPTER *a, void *adr, byte data);
+void mem_outw(ADAPTER *a, void *adr, word data);
+void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
+void mem_inc(ADAPTER *a, void *adr);
+void mem_in_dw(ADAPTER *a, void *addr, dword *data, int dwords);
+void mem_out_dw(ADAPTER *a, void *addr, const dword *data, int dwords);
 /* ---------------------------------------------------------------------
-  functions exported by io.c
+   functions exported by io.c
    --------------------------------------------------------------------- */
-extern IDI_CALL Requests[MAX_ADAPTER] ;
-extern void     DIDpcRoutine (struct _diva_os_soft_isr* psoft_isr,
-               void* context);
-extern void     request (PISDN_ADAPTER, ENTITY *) ;
+extern IDI_CALL Requests[MAX_ADAPTER];
+extern void     DIDpcRoutine(struct _diva_os_soft_isr *psoft_isr,
+			     void *context);
+extern void     request(PISDN_ADAPTER, ENTITY *);
 /* ---------------------------------------------------------------------
-  trapFn helpers, used to recover debug trace from dead card
+   trapFn helpers, used to recover debug trace from dead card
    --------------------------------------------------------------------- */
 typedef struct {
- word *buf ;
- word  cnt ;
- word  out ;
-} Xdesc ;
-extern void     dump_trap_frame  (PISDN_ADAPTER IoAdapter, byte __iomem *exception) ;
-extern void     dump_xlog_buffer (PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc) ;
+	word *buf;
+	word  cnt;
+	word  out;
+} Xdesc;
+extern void dump_trap_frame(PISDN_ADAPTER IoAdapter, byte __iomem *exception);
+extern void dump_xlog_buffer(PISDN_ADAPTER IoAdapter, Xdesc *xlogDesc);
 /* --------------------------------------------------------------------- */
 #endif  /* } __DIVA_XDI_COMMON_IO_H_INC__ */
diff --git a/drivers/isdn/hardware/eicon/istream.c b/drivers/isdn/hardware/eicon/istream.c
index 7bd5baa..045bda5 100644
--- a/drivers/isdn/hardware/eicon/istream.c
+++ b/drivers/isdn/hardware/eicon/istream.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -31,196 +31,196 @@
 #include "divasync.h"
 #include "di.h"
 #if !defined USE_EXTENDED_DEBUGS
-  #include "dimaint.h"
+#include "dimaint.h"
 #else
-  #define dprintf
+#define dprintf
 #endif
 #include "dfifo.h"
-int diva_istream_write (void* context,
-             int   Id,
-              void* data,
-             int length,
-             int final,
-            byte usr1,
-            byte usr2);
-int diva_istream_read (void* context,
-            int Id,
-            void* data,
-            int max_length,
-            int* final,
-            byte* usr1,
-            byte* usr2);
+int diva_istream_write(void *context,
+		       int   Id,
+		       void *data,
+		       int length,
+		       int final,
+		       byte usr1,
+		       byte usr2);
+int diva_istream_read(void *context,
+		      int Id,
+		      void *data,
+		      int max_length,
+		      int *final,
+		      byte *usr1,
+		      byte *usr2);
 /* -------------------------------------------------------------------
-  Does provide iStream interface to the client
+   Does provide iStream interface to the client
    ------------------------------------------------------------------- */
-void diva_xdi_provide_istream_info (ADAPTER* a,
-                  diva_xdi_stream_interface_t* pi) {
-  pi->provided_service = 0;
+void diva_xdi_provide_istream_info(ADAPTER *a,
+				   diva_xdi_stream_interface_t *pi) {
+	pi->provided_service = 0;
 }
 /* ------------------------------------------------------------------
-  Does write the data from caller's buffer to the card's
-  stream interface.
-  If synchronous service was requested, then function
-  does return amount of data written to stream.
-  'final' does indicate that piece of data to be written is
-  final part of frame (necessary only by structured datatransfer)
-  return  0 if zero lengh packet was written
-  return -1 if stream is full
-  ------------------------------------------------------------------ */
-int diva_istream_write (void* context,
-                int   Id,
-                  void* data,
-                 int length,
-                 int final,
-                byte usr1,
-                byte usr2) {
- ADAPTER* a = (ADAPTER*)context;
- int written = 0, to_write = -1;
- char tmp[4];
- byte* data_ptr = (byte*)data;
- for (;;) {
-  a->ram_in_dw (a,
+   Does write the data from caller's buffer to the card's
+   stream interface.
+   If synchronous service was requested, then function
+   does return amount of data written to stream.
+   'final' does indicate that piece of data to be written is
+   final part of frame (necessary only by structured datatransfer)
+   return  0 if zero lengh packet was written
+   return -1 if stream is full
+   ------------------------------------------------------------------ */
+int diva_istream_write(void *context,
+		       int Id,
+		       void *data,
+		       int length,
+		       int final,
+		       byte usr1,
+		       byte usr2) {
+	ADAPTER *a = (ADAPTER *)context;
+	int written = 0, to_write = -1;
+	char tmp[4];
+	byte *data_ptr = (byte *)data;
+	for (;;) {
+		a->ram_in_dw(a,
 #ifdef PLATFORM_GT_32BIT
-         ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
+			      ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
 #else
-         (void*)(a->tx_stream[Id] + a->tx_pos[Id]),
+			      (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
 #endif
-                  (dword*)&tmp[0],
-         1);
-  if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */
-   if (to_write < 0)
-    return (-1); /* was not able to write       */
-   break;     /* only part of message was written */
-  }
-  to_write = min(length, DIVA_DFIFO_DATA_SZ);
-  if (to_write) {
-   a->ram_out_buffer (a,
+			      (dword *)&tmp[0],
+			      1);
+		if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */
+			if (to_write < 0)
+				return (-1); /* was not able to write       */
+			break;     /* only part of message was written */
+		}
+		to_write = min(length, DIVA_DFIFO_DATA_SZ);
+		if (to_write) {
+			a->ram_out_buffer(a,
 #ifdef PLATFORM_GT_32BIT
-            ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]+4),
+					   ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id] + 4),
 #else
-              (void*)(a->tx_stream[Id] + a->tx_pos[Id] + 4),
+					   (void *)(a->tx_stream[Id] + a->tx_pos[Id] + 4),
 #endif
-                         data_ptr,
-             (word)to_write);
-   length  -= to_write;
-   written  += to_write;
-   data_ptr += to_write;
-  }
-  tmp[1] = (char)to_write;
-  tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) |
-       DIVA_DFIFO_READY |
-       ((!length && final) ? DIVA_DFIFO_LAST : 0);
-  if (tmp[0] & DIVA_DFIFO_LAST) {
-   tmp[2] = usr1;
-   tmp[3] = usr2;
-  }
-    a->ram_out_dw (a,
+					   data_ptr,
+					   (word)to_write);
+			length  -= to_write;
+			written  += to_write;
+			data_ptr += to_write;
+		}
+		tmp[1] = (char)to_write;
+		tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) |
+			DIVA_DFIFO_READY |
+			((!length && final) ? DIVA_DFIFO_LAST : 0);
+		if (tmp[0] & DIVA_DFIFO_LAST) {
+			tmp[2] = usr1;
+			tmp[3] = usr2;
+		}
+		a->ram_out_dw(a,
 #ifdef PLATFORM_GT_32BIT
-         ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
+			       ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
 #else
-           (void*)(a->tx_stream[Id] + a->tx_pos[Id]),
+			       (void *)(a->tx_stream[Id] + a->tx_pos[Id]),
 #endif
-                   (dword*)&tmp[0],
-          1);
-  if (tmp[0] & DIVA_DFIFO_WRAP) {
-   a->tx_pos[Id]  = 0;
-  } else {
-   a->tx_pos[Id] += DIVA_DFIFO_STEP;
-  }
-  if (!length) {
-   break;
-  }
- }
- return (written);
+			       (dword *)&tmp[0],
+			       1);
+		if (tmp[0] & DIVA_DFIFO_WRAP) {
+			a->tx_pos[Id]  = 0;
+		} else {
+			a->tx_pos[Id] += DIVA_DFIFO_STEP;
+		}
+		if (!length) {
+			break;
+		}
+	}
+	return (written);
 }
 /* -------------------------------------------------------------------
-  In case of SYNCRONOUS service:
-  Does write data from stream in caller's buffer.
-  Does return amount of data written to buffer
-  Final flag is set on return if last part of structured frame
-  was received
-  return 0  if zero packet was received
-  return -1 if stream is empty
-    return -2 if read buffer does not profide sufficient space
-              to accommodate entire segment
-  max_length should be at least 68 bytes
-  ------------------------------------------------------------------- */
-int diva_istream_read (void* context,
-                int Id,
-                void* data,
-                int max_length,
-                int* final,
-               byte* usr1,
-               byte* usr2) {
- ADAPTER* a = (ADAPTER*)context;
- int read = 0, to_read = -1;
- char tmp[4];
- byte* data_ptr = (byte*)data;
- *final = 0;
- for (;;) {
-  a->ram_in_dw (a,
+   In case of SYNCRONOUS service:
+   Does write data from stream in caller's buffer.
+   Does return amount of data written to buffer
+   Final flag is set on return if last part of structured frame
+   was received
+   return 0  if zero packet was received
+   return -1 if stream is empty
+   return -2 if read buffer does not profide sufficient space
+   to accommodate entire segment
+   max_length should be at least 68 bytes
+   ------------------------------------------------------------------- */
+int diva_istream_read(void *context,
+		      int Id,
+		      void *data,
+		      int max_length,
+		      int *final,
+		      byte *usr1,
+		      byte *usr2) {
+	ADAPTER *a = (ADAPTER *)context;
+	int read = 0, to_read = -1;
+	char tmp[4];
+	byte *data_ptr = (byte *)data;
+	*final = 0;
+	for (;;) {
+		a->ram_in_dw(a,
 #ifdef PLATFORM_GT_32BIT
-         ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
+			      ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
 #else
-         (void*)(a->rx_stream[Id] + a->rx_pos[Id]),
+			      (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
 #endif
-                  (dword*)&tmp[0],
-         1);
-  if (tmp[1] > max_length) {
-   if (to_read < 0)
-    return (-2); /* was not able to read */
-   break;
-    }
-  if (!(tmp[0] & DIVA_DFIFO_READY)) {
-   if (to_read < 0)
-    return (-1); /* was not able to read */
-   break;
-  }
-  to_read = min(max_length, (int)tmp[1]);
-  if (to_read) {
-   a->ram_in_buffer(a,
+			      (dword *)&tmp[0],
+			      1);
+		if (tmp[1] > max_length) {
+			if (to_read < 0)
+				return (-2); /* was not able to read */
+			break;
+		}
+		if (!(tmp[0] & DIVA_DFIFO_READY)) {
+			if (to_read < 0)
+				return (-1); /* was not able to read */
+			break;
+		}
+		to_read = min(max_length, (int)tmp[1]);
+		if (to_read) {
+			a->ram_in_buffer(a,
 #ifdef PLATFORM_GT_32BIT
-           ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4),
+					 ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4),
 #else
-            (void*)(a->rx_stream[Id] + a->rx_pos[Id] + 4),
+					 (void *)(a->rx_stream[Id] + a->rx_pos[Id] + 4),
 #endif
-                       data_ptr,
-            (word)to_read);
-   max_length -= to_read;
-   read     += to_read;
-   data_ptr  += to_read;
-  }
-  if (tmp[0] & DIVA_DFIFO_LAST) {
-   *final = 1;
-  }
-  tmp[0] &= DIVA_DFIFO_WRAP;
-    a->ram_out_dw(a,
+					 data_ptr,
+					 (word)to_read);
+			max_length -= to_read;
+			read     += to_read;
+			data_ptr  += to_read;
+		}
+		if (tmp[0] & DIVA_DFIFO_LAST) {
+			*final = 1;
+		}
+		tmp[0] &= DIVA_DFIFO_WRAP;
+		a->ram_out_dw(a,
 #ifdef PLATFORM_GT_32BIT
-         ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
+			      ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
 #else
-         (void*)(a->rx_stream[Id] + a->rx_pos[Id]),
+			      (void *)(a->rx_stream[Id] + a->rx_pos[Id]),
 #endif
-         (dword*)&tmp[0],
-         1);
-  if (tmp[0] & DIVA_DFIFO_WRAP) {
-   a->rx_pos[Id]  = 0;
-  } else {
-   a->rx_pos[Id] += DIVA_DFIFO_STEP;
-  }
-  if (*final) {
-   if (usr1)
-    *usr1 = tmp[2];
-   if (usr2)
-    *usr2 = tmp[3];
-   break;
-  }
- }
- return (read);
+			      (dword *)&tmp[0],
+			      1);
+		if (tmp[0] & DIVA_DFIFO_WRAP) {
+			a->rx_pos[Id]  = 0;
+		} else {
+			a->rx_pos[Id] += DIVA_DFIFO_STEP;
+		}
+		if (*final) {
+			if (usr1)
+				*usr1 = tmp[2];
+			if (usr2)
+				*usr2 = tmp[3];
+			break;
+		}
+	}
+	return (read);
 }
 /* ---------------------------------------------------------------------
-  Does check if one of streams had caused interrupt and does
-  wake up corresponding application
+   Does check if one of streams had caused interrupt and does
+   wake up corresponding application
    --------------------------------------------------------------------- */
-void pr_stream (ADAPTER * a) {
+void pr_stream(ADAPTER *a) {
 }
 #endif /* } */
diff --git a/drivers/isdn/hardware/eicon/kst_ifc.h b/drivers/isdn/hardware/eicon/kst_ifc.h
index 203189a..894fdfd 100644
--- a/drivers/isdn/hardware/eicon/kst_ifc.h
+++ b/drivers/isdn/hardware/eicon/kst_ifc.h
@@ -1,25 +1,25 @@
 /*
  *
-  Copyright (c) Eicon Networks, 2000.
+ Copyright (c) Eicon Networks, 2000.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    1.9
+ Eicon File Revision :    1.9
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_EICON_TRACE_API__
@@ -35,9 +35,9 @@ typedef struct _diva_trace_ie {
 } diva_trace_ie_t;
 
 /*
-	Structure used to represent "State\\BX\\Modem" directory
-	to user.
-	*/
+  Structure used to represent "State\\BX\\Modem" directory
+  to user.
+*/
 typedef struct _diva_trace_modem_state {
 	dword	ChannelNumber;
 
@@ -70,8 +70,8 @@ typedef struct _diva_trace_modem_state {
 } diva_trace_modem_state_t;
 
 /*
-	Representation of "State\\BX\\FAX" directory
-	*/
+  Representation of "State\\BX\\FAX" directory
+*/
 typedef struct _diva_trace_fax_state {
 	dword	ChannelNumber;
 	dword Event;
@@ -90,9 +90,9 @@ typedef struct _diva_trace_fax_state {
 } diva_trace_fax_state_t;
 
 /*
-	Structure used to represent Interface State in the abstract
-	and interface/D-channel protocol independent form.
-	*/
+  Structure used to represent Interface State in the abstract
+  and interface/D-channel protocol independent form.
+*/
 typedef struct _diva_trace_interface_state {
 	char Layer1[DIVA_TRACE_LINE_TYPE_LEN];
 	char Layer2[DIVA_TRACE_LINE_TYPE_LEN];
@@ -164,18 +164,18 @@ typedef struct _diva_prot_statistics {
 typedef struct _diva_ifc_statistics {
 	diva_incoming_call_statistics_t	inc;
 	diva_outgoing_call_statistics_t outg;
-	diva_modem_call_statistics_t		mdm;
-	diva_fax_call_statistics_t			fax;
-	diva_prot_statistics_t					b1;
-	diva_prot_statistics_t					b2;
-	diva_prot_statistics_t					d1;
-	diva_prot_statistics_t					d2;
+	diva_modem_call_statistics_t mdm;
+	diva_fax_call_statistics_t fax;
+	diva_prot_statistics_t b1;
+	diva_prot_statistics_t b2;
+	diva_prot_statistics_t d1;
+	diva_prot_statistics_t d2;
 } diva_ifc_statistics_t;
 
 /*
-	Structure used to represent "State\\BX" directory
-	to user.
-	*/
+  Structure used to represent "State\\BX" directory
+  to user.
+*/
 typedef struct _diva_trace_line_state {
 	dword	ChannelNumber;
 
@@ -192,9 +192,9 @@ typedef struct _diva_trace_line_state {
 	char LocalAddress[DIVA_TRACE_LINE_TYPE_LEN];
 	char LocalSubAddress[DIVA_TRACE_LINE_TYPE_LEN];
 
-	diva_trace_ie_t	call_BC;
-	diva_trace_ie_t	call_HLC;
-	diva_trace_ie_t	call_LLC;
+	diva_trace_ie_t call_BC;
+	diva_trace_ie_t call_HLC;
+	diva_trace_ie_t call_LLC;
 
 	dword Charges;
 
@@ -205,11 +205,11 @@ typedef struct _diva_trace_line_state {
 	char UserID[DIVA_TRACE_LINE_TYPE_LEN];
 
 	diva_trace_modem_state_t modem;
-	diva_trace_fax_state_t   fax;
+	diva_trace_fax_state_t fax;
 
-	diva_trace_interface_state_t* pInterface;
+	diva_trace_interface_state_t *pInterface;
 
-	diva_ifc_statistics_t*				pInterfaceStat;
+	diva_ifc_statistics_t *pInterfaceStat;
 
 } diva_trace_line_state_t;
 
@@ -222,115 +222,114 @@ typedef struct _diva_trace_line_state {
 #define DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE         ('F')
 
 struct _diva_strace_library_interface;
-typedef void (*diva_trace_channel_state_change_proc_t)(void* user_context,
-							struct _diva_strace_library_interface* hLib,
-							int Adapter,
-							diva_trace_line_state_t* channel, int notify_subject);
-typedef void (*diva_trace_channel_trace_proc_t)(void* user_context,
-							struct _diva_strace_library_interface* hLib,
-							int Adapter, void* xlog_buffer, int length);
-typedef void (*diva_trace_error_proc_t)(void* user_context,
-							struct _diva_strace_library_interface* hLib,
-							int Adapter,
-							int error, const char* file, int line);
+typedef void (*diva_trace_channel_state_change_proc_t)(void *user_context,
+						       struct _diva_strace_library_interface *hLib,
+						       int Adapter,
+						       diva_trace_line_state_t *channel, int notify_subject);
+typedef void (*diva_trace_channel_trace_proc_t)(void *user_context,
+						struct _diva_strace_library_interface *hLib,
+						int Adapter, void *xlog_buffer, int length);
+typedef void (*diva_trace_error_proc_t)(void *user_context,
+					struct _diva_strace_library_interface *hLib,
+					int Adapter,
+					int error, const char *file, int line);
 
 /*
-	This structure creates interface from user to library
-	*/
+  This structure creates interface from user to library
+*/
 typedef struct _diva_trace_library_user_interface {
-	void*																		user_context;
-	diva_trace_channel_state_change_proc_t	notify_proc;
-	diva_trace_channel_trace_proc_t					trace_proc;
-	diva_trace_error_proc_t									error_notify_proc;
+	void *user_context;
+	diva_trace_channel_state_change_proc_t notify_proc;
+	diva_trace_channel_trace_proc_t trace_proc;
+	diva_trace_error_proc_t error_notify_proc;
 } diva_trace_library_user_interface_t;
 
 /*
-	Interface from Library to User
-	*/
-typedef int   (*DivaSTraceLibraryStart_proc_t)(void* hLib);
-typedef int   (*DivaSTraceLibraryFinit_proc_t)(void* hLib);
-typedef int   (*DivaSTraceMessageInput_proc_t)(void* hLib);
-typedef void*	(*DivaSTraceGetHandle_proc_t)(void* hLib);
+  Interface from Library to User
+*/
+typedef int (*DivaSTraceLibraryStart_proc_t)(void *hLib);
+typedef int (*DivaSTraceLibraryFinit_proc_t)(void *hLib);
+typedef int (*DivaSTraceMessageInput_proc_t)(void *hLib);
+typedef void* (*DivaSTraceGetHandle_proc_t)(void *hLib);
 
 /*
-	Turn Audio Tap trace on/off
-	Channel should be in the range 1 ... Number of Channels
-	*/
-typedef int (*DivaSTraceSetAudioTap_proc_t)(void* hLib, int Channel, int on);
+  Turn Audio Tap trace on/off
+  Channel should be in the range 1 ... Number of Channels
+*/
+typedef int (*DivaSTraceSetAudioTap_proc_t)(void *hLib, int Channel, int on);
 
 /*
-	Turn B-channel trace on/off
-	Channel should be in the range 1 ... Number of Channels
-	*/
-typedef int (*DivaSTraceSetBChannel_proc_t)(void* hLib, int Channel, int on);
+  Turn B-channel trace on/off
+  Channel should be in the range 1 ... Number of Channels
+*/
+typedef int (*DivaSTraceSetBChannel_proc_t)(void *hLib, int Channel, int on);
 
 /*
-	Turn	D-channel (Layer1/Layer2/Layer3) trace on/off
-		Layer1 - All D-channel frames received/sent over the interface
-						 inclusive Layer 2 headers, Layer 2 frames and TEI management frames
-		Layer2 - Events from LAPD protocol instance with SAPI of signalling protocol
-		Layer3 - All D-channel frames addressed to assigned to the card TEI and
-						 SAPI of signalling protocol, and signalling protocol events.
-	*/
-typedef int (*DivaSTraceSetDChannel_proc_t)(void* hLib, int on);
+  Turn	D-channel (Layer1/Layer2/Layer3) trace on/off
+  Layer1 - All D-channel frames received/sent over the interface
+  inclusive Layer 2 headers, Layer 2 frames and TEI management frames
+  Layer2 - Events from LAPD protocol instance with SAPI of signalling protocol
+  Layer3 - All D-channel frames addressed to assigned to the card TEI and
+  SAPI of signalling protocol, and signalling protocol events.
+*/
+typedef int (*DivaSTraceSetDChannel_proc_t)(void *hLib, int on);
 
 /*
-	Get overall card statistics
-	*/
-typedef int (*DivaSTraceGetOutgoingCallStatistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetIncomingCallStatistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetModemStatistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetFaxStatistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetBLayer1Statistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetBLayer2Statistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetDLayer1Statistics_proc_t)(void* hLib);
-typedef int (*DivaSTraceGetDLayer2Statistics_proc_t)(void* hLib);
+  Get overall card statistics
+*/
+typedef int (*DivaSTraceGetOutgoingCallStatistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetIncomingCallStatistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetModemStatistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetFaxStatistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetBLayer1Statistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetBLayer2Statistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetDLayer1Statistics_proc_t)(void *hLib);
+typedef int (*DivaSTraceGetDLayer2Statistics_proc_t)(void *hLib);
 
 /*
-	Call control
-	*/
-typedef int (*DivaSTraceClearCall_proc_t)(void* hLib, int Channel);
+  Call control
+*/
+typedef int (*DivaSTraceClearCall_proc_t)(void *hLib, int Channel);
 
 typedef struct _diva_strace_library_interface {
-	void* hLib;
-  DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStart;
-  DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStop;
+	void *hLib;
+	DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStart;
+	DivaSTraceLibraryStart_proc_t DivaSTraceLibraryStop;
 	DivaSTraceLibraryFinit_proc_t DivaSTraceLibraryFinit;
 	DivaSTraceMessageInput_proc_t DivaSTraceMessageInput;
-	DivaSTraceGetHandle_proc_t    DivaSTraceGetHandle;
-	DivaSTraceSetAudioTap_proc_t  DivaSTraceSetAudioTap;
-	DivaSTraceSetBChannel_proc_t  DivaSTraceSetBChannel;
-	DivaSTraceSetDChannel_proc_t  DivaSTraceSetDChannel;
-	DivaSTraceSetDChannel_proc_t  DivaSTraceSetInfo;
+	DivaSTraceGetHandle_proc_t DivaSTraceGetHandle;
+	DivaSTraceSetAudioTap_proc_t DivaSTraceSetAudioTap;
+	DivaSTraceSetBChannel_proc_t DivaSTraceSetBChannel;
+	DivaSTraceSetDChannel_proc_t DivaSTraceSetDChannel;
+	DivaSTraceSetDChannel_proc_t DivaSTraceSetInfo;
 	DivaSTraceGetOutgoingCallStatistics_proc_t \
-																DivaSTraceGetOutgoingCallStatistics;
+	DivaSTraceGetOutgoingCallStatistics;
 	DivaSTraceGetIncomingCallStatistics_proc_t \
-																DivaSTraceGetIncomingCallStatistics;
+	DivaSTraceGetIncomingCallStatistics;
 	DivaSTraceGetModemStatistics_proc_t \
-																DivaSTraceGetModemStatistics;
+	DivaSTraceGetModemStatistics;
 	DivaSTraceGetFaxStatistics_proc_t \
-																DivaSTraceGetFaxStatistics;
+	DivaSTraceGetFaxStatistics;
 	DivaSTraceGetBLayer1Statistics_proc_t \
-																DivaSTraceGetBLayer1Statistics;
+	DivaSTraceGetBLayer1Statistics;
 	DivaSTraceGetBLayer2Statistics_proc_t \
-																DivaSTraceGetBLayer2Statistics;
+	DivaSTraceGetBLayer2Statistics;
 	DivaSTraceGetDLayer1Statistics_proc_t \
-																DivaSTraceGetDLayer1Statistics;
+	DivaSTraceGetDLayer1Statistics;
 	DivaSTraceGetDLayer2Statistics_proc_t \
-																DivaSTraceGetDLayer2Statistics;
-	DivaSTraceClearCall_proc_t    DivaSTraceClearCall;
+	DivaSTraceGetDLayer2Statistics;
+	DivaSTraceClearCall_proc_t DivaSTraceClearCall;
 } diva_strace_library_interface_t;
 
 /*
-	Create and return Library interface
-	*/
-diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter,
-													const diva_trace_library_user_interface_t* user_proc,
-                          byte* pmem);
-dword DivaSTraceGetMemotyRequirement (int channels);
+  Create and return Library interface
+*/
+diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter,
+								 const diva_trace_library_user_interface_t *user_proc,
+								 byte *pmem);
+dword DivaSTraceGetMemotyRequirement(int channels);
 
 #define DIVA_MAX_ADAPTERS  64
 #define DIVA_MAX_LINES     32
 
 #endif
-
diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c
index 534978b..2ee789f 100644
--- a/drivers/isdn/hardware/eicon/maintidi.c
+++ b/drivers/isdn/hardware/eicon/maintidi.c
@@ -1,25 +1,25 @@
 /*
  *
-  Copyright (c) Eicon Networks, 2000.
+ Copyright (c) Eicon Networks, 2000.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    1.9
+ Eicon File Revision :    1.9
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -30,7 +30,7 @@
 #include "man_defs.h"
 
 
-extern void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...);
+extern void diva_mnt_internal_dprintf(dword drv_id, dword type, char *p, ...);
 
 #define MODEM_PARSE_ENTRIES  16 /* amount of variables of interest */
 #define FAX_PARSE_ENTRIES    12 /* amount of variables of interest */
@@ -38,77 +38,77 @@ extern void diva_mnt_internal_dprintf (dword drv_id, dword type, char* p, ...);
 #define STAT_PARSE_ENTRIES   70 /* amount of variables of interest */
 
 /*
-	LOCAL FUNCTIONS
-	*/
-static int DivaSTraceLibraryStart (void* hLib);
-static int DivaSTraceLibraryStop  (void* hLib);
-static int SuperTraceLibraryFinit (void* hLib);
-static void*	SuperTraceGetHandle (void* hLib);
-static int SuperTraceMessageInput (void* hLib);
-static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on);
-static int SuperTraceSetBChannel  (void* hLib, int Channel, int on);
-static int SuperTraceSetDChannel  (void* hLib, int on);
-static int SuperTraceSetInfo      (void* hLib, int on);
-static int SuperTraceClearCall (void* hLib, int Channel);
-static int SuperTraceGetOutgoingCallStatistics (void* hLib);
-static int SuperTraceGetIncomingCallStatistics (void* hLib);
-static int SuperTraceGetModemStatistics (void* hLib);
-static int SuperTraceGetFaxStatistics (void* hLib);
-static int SuperTraceGetBLayer1Statistics (void* hLib);
-static int SuperTraceGetBLayer2Statistics (void* hLib);
-static int SuperTraceGetDLayer1Statistics (void* hLib);
-static int SuperTraceGetDLayer2Statistics (void* hLib);
+  LOCAL FUNCTIONS
+*/
+static int DivaSTraceLibraryStart(void *hLib);
+static int DivaSTraceLibraryStop(void *hLib);
+static int SuperTraceLibraryFinit(void *hLib);
+static void *SuperTraceGetHandle(void *hLib);
+static int SuperTraceMessageInput(void *hLib);
+static int SuperTraceSetAudioTap(void *hLib, int Channel, int on);
+static int SuperTraceSetBChannel(void *hLib, int Channel, int on);
+static int SuperTraceSetDChannel(void *hLib, int on);
+static int SuperTraceSetInfo(void *hLib, int on);
+static int SuperTraceClearCall(void *hLib, int Channel);
+static int SuperTraceGetOutgoingCallStatistics(void *hLib);
+static int SuperTraceGetIncomingCallStatistics(void *hLib);
+static int SuperTraceGetModemStatistics(void *hLib);
+static int SuperTraceGetFaxStatistics(void *hLib);
+static int SuperTraceGetBLayer1Statistics(void *hLib);
+static int SuperTraceGetBLayer2Statistics(void *hLib);
+static int SuperTraceGetDLayer1Statistics(void *hLib);
+static int SuperTraceGetDLayer2Statistics(void *hLib);
 
 /*
-	LOCAL FUNCTIONS
-	*/
-static int ScheduleNextTraceRequest (diva_strace_context_t* pLib);
-static int process_idi_event (diva_strace_context_t* pLib,
-															diva_man_var_header_t* pVar);
-static int process_idi_info  (diva_strace_context_t* pLib,
-															diva_man_var_header_t* pVar);
-static int diva_modem_event (diva_strace_context_t* pLib, int Channel);
-static int diva_fax_event   (diva_strace_context_t* pLib, int Channel);
-static int diva_line_event (diva_strace_context_t* pLib, int Channel);
-static int diva_modem_info (diva_strace_context_t* pLib,
-														int Channel,
-														diva_man_var_header_t* pVar);
-static int diva_fax_info   (diva_strace_context_t* pLib,
-														int Channel,
-														diva_man_var_header_t* pVar);
-static int diva_line_info  (diva_strace_context_t* pLib,
-														int Channel,
-														diva_man_var_header_t* pVar);
-static int diva_ifc_statistics (diva_strace_context_t* pLib,
-																diva_man_var_header_t* pVar);
-static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar);
-static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar,
-																				const char* name);
-static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var);
-static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var);
-static int diva_strace_read_asz  (diva_man_var_header_t* pVar, char* var);
-static int diva_strace_read_asc  (diva_man_var_header_t* pVar, char* var);
-static int  diva_strace_read_ie  (diva_man_var_header_t* pVar,
-																	diva_trace_ie_t* var);
-static void diva_create_parse_table (diva_strace_context_t* pLib);
-static void diva_trace_error (diva_strace_context_t* pLib,
-															int error, const char* file, int line);
-static void diva_trace_notify_user (diva_strace_context_t* pLib,
-														 int Channel,
-														 int notify_subject);
-static int diva_trace_read_variable (diva_man_var_header_t* pVar,
-																		 void* variable);
+  LOCAL FUNCTIONS
+*/
+static int ScheduleNextTraceRequest(diva_strace_context_t *pLib);
+static int process_idi_event(diva_strace_context_t *pLib,
+			     diva_man_var_header_t *pVar);
+static int process_idi_info(diva_strace_context_t *pLib,
+			    diva_man_var_header_t *pVar);
+static int diva_modem_event(diva_strace_context_t *pLib, int Channel);
+static int diva_fax_event(diva_strace_context_t *pLib, int Channel);
+static int diva_line_event(diva_strace_context_t *pLib, int Channel);
+static int diva_modem_info(diva_strace_context_t *pLib,
+			   int Channel,
+			   diva_man_var_header_t *pVar);
+static int diva_fax_info(diva_strace_context_t *pLib,
+			 int Channel,
+			 diva_man_var_header_t *pVar);
+static int diva_line_info(diva_strace_context_t *pLib,
+			  int Channel,
+			  diva_man_var_header_t *pVar);
+static int diva_ifc_statistics(diva_strace_context_t *pLib,
+			       diva_man_var_header_t *pVar);
+static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar);
+static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
+				       const char *name);
+static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var);
+static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var);
+static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var);
+static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var);
+static int diva_strace_read_ie(diva_man_var_header_t *pVar,
+			       diva_trace_ie_t *var);
+static void diva_create_parse_table(diva_strace_context_t *pLib);
+static void diva_trace_error(diva_strace_context_t *pLib,
+			     int error, const char *file, int line);
+static void diva_trace_notify_user(diva_strace_context_t *pLib,
+				   int Channel,
+				   int notify_subject);
+static int diva_trace_read_variable(diva_man_var_header_t *pVar,
+				    void *variable);
 
 /*
-	Initialize the library and return context
-	of the created trace object that will represent
-	the IDI adapter.
-	Return 0 on error.
-	*/
-diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter,
-											const diva_trace_library_user_interface_t* user_proc,
-                      byte* pmem) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)pmem;
+  Initialize the library and return context
+  of the created trace object that will represent
+  the IDI adapter.
+  Return 0 on error.
+*/
+diva_strace_library_interface_t *DivaSTraceLibraryCreateInstance(int Adapter,
+								 const diva_trace_library_user_interface_t *user_proc,
+								 byte *pmem) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)pmem;
 	int i;
 
 	if (!pLib) {
@@ -121,11 +121,11 @@ diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter,
 	pLib->Adapter  = Adapter;
 
 	/*
-		Set up Library Interface
-		*/
+	  Set up Library Interface
+	*/
 	pLib->instance.hLib                                = pLib;
-  pLib->instance.DivaSTraceLibraryStart              = DivaSTraceLibraryStart;
-  pLib->instance.DivaSTraceLibraryStop               = DivaSTraceLibraryStop;
+	pLib->instance.DivaSTraceLibraryStart              = DivaSTraceLibraryStart;
+	pLib->instance.DivaSTraceLibraryStop               = DivaSTraceLibraryStop;
 	pLib->instance.DivaSTraceLibraryFinit              = SuperTraceLibraryFinit;
 	pLib->instance.DivaSTraceMessageInput              = SuperTraceMessageInput;
 	pLib->instance.DivaSTraceGetHandle                 = SuperTraceGetHandle;
@@ -134,21 +134,21 @@ diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter,
 	pLib->instance.DivaSTraceSetDChannel               = SuperTraceSetDChannel;
 	pLib->instance.DivaSTraceSetInfo                   = SuperTraceSetInfo;
 	pLib->instance.DivaSTraceGetOutgoingCallStatistics = \
-																			SuperTraceGetOutgoingCallStatistics;
+		SuperTraceGetOutgoingCallStatistics;
 	pLib->instance.DivaSTraceGetIncomingCallStatistics = \
-																			SuperTraceGetIncomingCallStatistics;
+		SuperTraceGetIncomingCallStatistics;
 	pLib->instance.DivaSTraceGetModemStatistics        = \
-																			SuperTraceGetModemStatistics;
+		SuperTraceGetModemStatistics;
 	pLib->instance.DivaSTraceGetFaxStatistics          = \
-																			SuperTraceGetFaxStatistics;
+		SuperTraceGetFaxStatistics;
 	pLib->instance.DivaSTraceGetBLayer1Statistics      = \
-																			SuperTraceGetBLayer1Statistics;
+		SuperTraceGetBLayer1Statistics;
 	pLib->instance.DivaSTraceGetBLayer2Statistics      = \
-																			SuperTraceGetBLayer2Statistics;
+		SuperTraceGetBLayer2Statistics;
 	pLib->instance.DivaSTraceGetDLayer1Statistics      = \
-																			SuperTraceGetDLayer1Statistics;
+		SuperTraceGetDLayer1Statistics;
 	pLib->instance.DivaSTraceGetDLayer2Statistics      = \
-																			SuperTraceGetDLayer2Statistics;
+		SuperTraceGetDLayer2Statistics;
 	pLib->instance.DivaSTraceClearCall                 = SuperTraceClearCall;
 
 
@@ -159,272 +159,272 @@ diva_strace_library_interface_t* DivaSTraceLibraryCreateInstance (int Adapter,
 		pLib->user_proc_table.error_notify_proc = user_proc->error_notify_proc;
 	}
 
-	if (!(pLib->hAdapter = SuperTraceOpenAdapter (Adapter))) {
-    diva_mnt_internal_dprintf (0, DLI_ERR, "Can not open XDI adapter");
+	if (!(pLib->hAdapter = SuperTraceOpenAdapter(Adapter))) {
+		diva_mnt_internal_dprintf(0, DLI_ERR, "Can not open XDI adapter");
 		return NULL;
 	}
-	pLib->Channels = SuperTraceGetNumberOfChannels (pLib->hAdapter);
+	pLib->Channels = SuperTraceGetNumberOfChannels(pLib->hAdapter);
 
 	/*
-		Calculate amount of parte table entites necessary to translate
-		information from all events of onterest
-		*/
+	  Calculate amount of parte table entites necessary to translate
+	  information from all events of onterest
+	*/
 	pLib->parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
-												 STAT_PARSE_ENTRIES + \
-												 LINE_PARSE_ENTRIES + 1) * pLib->Channels;
-	pLib->parse_table = (diva_strace_path2action_t*)pmem;
+			       STAT_PARSE_ENTRIES + \
+			       LINE_PARSE_ENTRIES + 1) * pLib->Channels;
+	pLib->parse_table = (diva_strace_path2action_t *)pmem;
 
 	for (i = 0; i < 30; i++) {
 		pLib->lines[i].pInterface     = &pLib->Interface;
 		pLib->lines[i].pInterfaceStat = &pLib->InterfaceStat;
 	}
 
-  pLib->e.R = &pLib->RData;
+	pLib->e.R = &pLib->RData;
 
 	pLib->req_busy = 1;
 	pLib->rc_ok    = ASSIGN_OK;
 
-	diva_create_parse_table (pLib);
+	diva_create_parse_table(pLib);
 
-	return ((diva_strace_library_interface_t*)pLib);
+	return ((diva_strace_library_interface_t *)pLib);
 }
 
-static int DivaSTraceLibraryStart (void* hLib) {
-  diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int DivaSTraceLibraryStart(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
-  return (SuperTraceASSIGN (pLib->hAdapter, pLib->buffer));
+	return (SuperTraceASSIGN(pLib->hAdapter, pLib->buffer));
 }
 
 /*
   Return (-1) on error
   Return (0) if was initiated or pending
   Return (1) if removal is complete
-  */
-static int DivaSTraceLibraryStop  (void* hLib) {
-  diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+*/
+static int DivaSTraceLibraryStop(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
-  if (!pLib->e.Id) { /* Was never started/assigned */
-    return (1);
-  }
+	if (!pLib->e.Id) { /* Was never started/assigned */
+		return (1);
+	}
 
-  switch (pLib->removal_state) {
-    case 0:
-      pLib->removal_state = 1;
-      ScheduleNextTraceRequest(pLib);
-      break;
+	switch (pLib->removal_state) {
+	case 0:
+		pLib->removal_state = 1;
+		ScheduleNextTraceRequest(pLib);
+		break;
 
-    case 3:
-      return (1);
-  }
+	case 3:
+		return (1);
+	}
 
-  return (0);
+	return (0);
 }
 
-static int SuperTraceLibraryFinit (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceLibraryFinit(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	if (pLib) {
 		if (pLib->hAdapter) {
-			SuperTraceCloseAdapter  (pLib->hAdapter);
+			SuperTraceCloseAdapter(pLib->hAdapter);
 		}
 		return (0);
 	}
 	return (-1);
 }
 
-static void*	SuperTraceGetHandle (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static void *SuperTraceGetHandle(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
-  return (&pLib->e);
+	return (&pLib->e);
 }
 
 /*
-	After library handle object is gone in signaled state
-	this function should be called and will pick up incoming
-	IDI messages (return codes and indications).
-	*/
-static int SuperTraceMessageInput (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+  After library handle object is gone in signaled state
+  this function should be called and will pick up incoming
+  IDI messages (return codes and indications).
+*/
+static int SuperTraceMessageInput(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	int ret = 0;
-  byte Rc, Ind;
+	byte Rc, Ind;
 
-  if (pLib->e.complete == 255) {
-    /*
-      Process return code
-      */
-    pLib->req_busy = 0;
-    Rc             = pLib->e.Rc;
-    pLib->e.Rc     = 0;
+	if (pLib->e.complete == 255) {
+		/*
+		  Process return code
+		*/
+		pLib->req_busy = 0;
+		Rc             = pLib->e.Rc;
+		pLib->e.Rc     = 0;
 
-    if (pLib->removal_state == 2) {
-      pLib->removal_state = 3;
-      return (0);
-    }
+		if (pLib->removal_state == 2) {
+			pLib->removal_state = 3;
+			return (0);
+		}
 
 		if (Rc != pLib->rc_ok) {
-      int ignore = 0;
-      /*
-        Auto-detect amount of events/channels and features
-        */
-      if (pLib->general_b_ch_event == 1) {
-        pLib->general_b_ch_event = 2;
-        ignore = 1;
-      } else if (pLib->general_fax_event == 1) {
-        pLib->general_fax_event = 2;
-        ignore = 1;
-      } else if (pLib->general_mdm_event == 1) {
-        pLib->general_mdm_event = 2;
-        ignore = 1;
-      } else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
-        pLib->ChannelsTraceActive = pLib->Channels;
-        ignore = 1;
-      } else if (pLib->ModemTraceActive < pLib->Channels) {
-        pLib->ModemTraceActive = pLib->Channels;
-        ignore = 1;
-      } else if (pLib->FaxTraceActive < pLib->Channels) {
-        pLib->FaxTraceActive = pLib->Channels;
-        ignore = 1;
-      } else if (pLib->audio_trace_init == 2) {
-        ignore = 1;
-        pLib->audio_trace_init = 1;
-      } else if (pLib->eye_pattern_pending) {
+			int ignore = 0;
+			/*
+			  Auto-detect amount of events/channels and features
+			*/
+			if (pLib->general_b_ch_event == 1) {
+				pLib->general_b_ch_event = 2;
+				ignore = 1;
+			} else if (pLib->general_fax_event == 1) {
+				pLib->general_fax_event = 2;
+				ignore = 1;
+			} else if (pLib->general_mdm_event == 1) {
+				pLib->general_mdm_event = 2;
+				ignore = 1;
+			} else if ((pLib->ChannelsTraceActive < pLib->Channels) && pLib->ChannelsTraceActive) {
+				pLib->ChannelsTraceActive = pLib->Channels;
+				ignore = 1;
+			} else if (pLib->ModemTraceActive < pLib->Channels) {
+				pLib->ModemTraceActive = pLib->Channels;
+				ignore = 1;
+			} else if (pLib->FaxTraceActive < pLib->Channels) {
+				pLib->FaxTraceActive = pLib->Channels;
+				ignore = 1;
+			} else if (pLib->audio_trace_init == 2) {
+				ignore = 1;
+				pLib->audio_trace_init = 1;
+			} else if (pLib->eye_pattern_pending) {
 				pLib->eye_pattern_pending =  0;
 				ignore = 1;
 			} else if (pLib->audio_tap_pending) {
 				pLib->audio_tap_pending = 0;
 				ignore = 1;
-      }
-
-      if (!ignore) {
-        return (-1); /* request failed */
-      }
-    } else {
-      if (pLib->general_b_ch_event == 1) {
-        pLib->ChannelsTraceActive = pLib->Channels;
-        pLib->general_b_ch_event = 2;
-      } else if (pLib->general_fax_event == 1) {
-        pLib->general_fax_event = 2;
-        pLib->FaxTraceActive = pLib->Channels;
-      } else if (pLib->general_mdm_event == 1) {
-        pLib->general_mdm_event = 2;
-        pLib->ModemTraceActive = pLib->Channels;
-      }
-    }
-    if (pLib->audio_trace_init == 2) {
-      pLib->audio_trace_init = 1;
-    }
-    pLib->rc_ok = 0xff; /* default OK after assign was done */
-    if ((ret = ScheduleNextTraceRequest(pLib))) {
-      return (-1);
-    }
-  } else {
-    /*
-      Process indication
-      Always 'RNR' indication if return code is pending
-      */
-    Ind         = pLib->e.Ind;
-    pLib->e.Ind = 0;
-    if (pLib->removal_state) {
-      pLib->e.RNum	= 0;
-      pLib->e.RNR	= 2;
-    } else if (pLib->req_busy) {
-      pLib->e.RNum	= 0;
-      pLib->e.RNR	= 1;
-    } else {
-      if (pLib->e.complete != 0x02) {
-        /*
-          Look-ahead call, set up buffers
-          */
-        pLib->e.RNum       = 1;
-        pLib->e.R->P       = (byte*)&pLib->buffer[0];
-        pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
-
-      } else {
-        /*
-          Indication reception complete, process it now
-          */
-        byte* p = (byte*)&pLib->buffer[0];
-        pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
-
-        switch (Ind) {
-          case MAN_COMBI_IND: {
-            int total_length    = pLib->e.R->PLength;
-            word  this_ind_length;
-
-            while (total_length > 3 && *p) {
-              Ind = *p++;
-              this_ind_length = (word)p[0] | ((word)p[1] << 8);
-              p += 2;
-
-              switch (Ind) {
-                case MAN_INFO_IND:
-                  if (process_idi_info (pLib, (diva_man_var_header_t*)p)) {
-                    return (-1);
-                  }
-                  break;
-      					case MAN_EVENT_IND:
-                  if (process_idi_event (pLib, (diva_man_var_header_t*)p)) {
-                    return (-1);
-                  }
-                  break;
-                case MAN_TRACE_IND:
-                  if (pLib->trace_on == 1) {
-                    /*
-                      Ignore first trace event that is result of
-                      EVENT_ON operation
-                    */
-                    pLib->trace_on++;
-                  } else {
-                    /*
-                      Delivery XLOG buffer to application
-                      */
-                    if (pLib->user_proc_table.trace_proc) {
-                      (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
-                                                            &pLib->instance, pLib->Adapter,
-                                                            p, this_ind_length);
-                    }
-                  }
-                  break;
-                default:
-                  diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
-              }
-              p += (this_ind_length+1);
-              total_length -= (4 + this_ind_length);
-            }
-          } break;
-          case MAN_INFO_IND:
-            if (process_idi_info (pLib, (diva_man_var_header_t*)p)) {
-              return (-1);
-            }
-            break;
-					case MAN_EVENT_IND:
-            if (process_idi_event (pLib, (diva_man_var_header_t*)p)) {
-              return (-1);
-            }
-            break;
-          case MAN_TRACE_IND:
-            if (pLib->trace_on == 1) {
-              /*
-                Ignore first trace event that is result of
-                EVENT_ON operation
-              */
-              pLib->trace_on++;
-            } else {
-              /*
-                Delivery XLOG buffer to application
-                */
-              if (pLib->user_proc_table.trace_proc) {
-                (*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
-                                                      &pLib->instance, pLib->Adapter,
-                                                      p, pLib->e.R->PLength);
-              }
-            }
-            break;
-          default:
-            diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
-        }
-      }
-    }
-  }
+			}
+
+			if (!ignore) {
+				return (-1); /* request failed */
+			}
+		} else {
+			if (pLib->general_b_ch_event == 1) {
+				pLib->ChannelsTraceActive = pLib->Channels;
+				pLib->general_b_ch_event = 2;
+			} else if (pLib->general_fax_event == 1) {
+				pLib->general_fax_event = 2;
+				pLib->FaxTraceActive = pLib->Channels;
+			} else if (pLib->general_mdm_event == 1) {
+				pLib->general_mdm_event = 2;
+				pLib->ModemTraceActive = pLib->Channels;
+			}
+		}
+		if (pLib->audio_trace_init == 2) {
+			pLib->audio_trace_init = 1;
+		}
+		pLib->rc_ok = 0xff; /* default OK after assign was done */
+		if ((ret = ScheduleNextTraceRequest(pLib))) {
+			return (-1);
+		}
+	} else {
+		/*
+		  Process indication
+		  Always 'RNR' indication if return code is pending
+		*/
+		Ind         = pLib->e.Ind;
+		pLib->e.Ind = 0;
+		if (pLib->removal_state) {
+			pLib->e.RNum	= 0;
+			pLib->e.RNR	= 2;
+		} else if (pLib->req_busy) {
+			pLib->e.RNum	= 0;
+			pLib->e.RNR	= 1;
+		} else {
+			if (pLib->e.complete != 0x02) {
+				/*
+				  Look-ahead call, set up buffers
+				*/
+				pLib->e.RNum       = 1;
+				pLib->e.R->P       = (byte *)&pLib->buffer[0];
+				pLib->e.R->PLength = (word)(sizeof(pLib->buffer) - 1);
+
+			} else {
+				/*
+				  Indication reception complete, process it now
+				*/
+				byte *p = (byte *)&pLib->buffer[0];
+				pLib->buffer[pLib->e.R->PLength] = 0; /* terminate I.E. with zero */
+
+				switch (Ind) {
+				case MAN_COMBI_IND: {
+					int total_length    = pLib->e.R->PLength;
+					word  this_ind_length;
+
+					while (total_length > 3 && *p) {
+						Ind = *p++;
+						this_ind_length = (word)p[0] | ((word)p[1] << 8);
+						p += 2;
+
+						switch (Ind) {
+						case MAN_INFO_IND:
+							if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
+								return (-1);
+							}
+							break;
+						case MAN_EVENT_IND:
+							if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
+								return (-1);
+							}
+							break;
+						case MAN_TRACE_IND:
+							if (pLib->trace_on == 1) {
+								/*
+								  Ignore first trace event that is result of
+								  EVENT_ON operation
+								*/
+								pLib->trace_on++;
+							} else {
+								/*
+								  Delivery XLOG buffer to application
+								*/
+								if (pLib->user_proc_table.trace_proc) {
+									(*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
+													      &pLib->instance, pLib->Adapter,
+													      p, this_ind_length);
+								}
+							}
+							break;
+						default:
+							diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
+						}
+						p += (this_ind_length + 1);
+						total_length -= (4 + this_ind_length);
+					}
+				} break;
+				case MAN_INFO_IND:
+					if (process_idi_info(pLib, (diva_man_var_header_t *)p)) {
+						return (-1);
+					}
+					break;
+				case MAN_EVENT_IND:
+					if (process_idi_event(pLib, (diva_man_var_header_t *)p)) {
+						return (-1);
+					}
+					break;
+				case MAN_TRACE_IND:
+					if (pLib->trace_on == 1) {
+						/*
+						  Ignore first trace event that is result of
+						  EVENT_ON operation
+						*/
+						pLib->trace_on++;
+					} else {
+						/*
+						  Delivery XLOG buffer to application
+						*/
+						if (pLib->user_proc_table.trace_proc) {
+							(*(pLib->user_proc_table.trace_proc))(pLib->user_proc_table.user_context,
+											      &pLib->instance, pLib->Adapter,
+											      p, pLib->e.R->PLength);
+						}
+					}
+					break;
+				default:
+					diva_mnt_internal_dprintf(0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
+				}
+			}
+		}
+	}
 
 	if ((ret = ScheduleNextTraceRequest(pLib))) {
 		return (-1);
@@ -434,9 +434,9 @@ static int SuperTraceMessageInput (void* hLib) {
 }
 
 /*
-	Internal state machine responsible for scheduling of requests
-	*/
-static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
+  Internal state machine responsible for scheduling of requests
+*/
+static int ScheduleNextTraceRequest(diva_strace_context_t *pLib) {
 	char name[64];
 	int ret = 0;
 	int i;
@@ -445,50 +445,50 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 		return (0);
 	}
 
-  if (pLib->removal_state == 1) {
-		if (SuperTraceREMOVE (pLib->hAdapter)) {
-      pLib->removal_state = 3;
-    } else {
-      pLib->req_busy = 1;
-      pLib->removal_state = 2;
-    }
-    return (0);
-  }
+	if (pLib->removal_state == 1) {
+		if (SuperTraceREMOVE(pLib->hAdapter)) {
+			pLib->removal_state = 3;
+		} else {
+			pLib->req_busy = 1;
+			pLib->removal_state = 2;
+		}
+		return (0);
+	}
 
-  if (pLib->removal_state) {
-    return (0);
-  }
+	if (pLib->removal_state) {
+		return (0);
+	}
 
-  if (!pLib->general_b_ch_event) {
+	if (!pLib->general_b_ch_event) {
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\B Event", pLib->buffer))) {
-      return (-1);
-    }
-    pLib->general_b_ch_event = 1;
+			return (-1);
+		}
+		pLib->general_b_ch_event = 1;
 		pLib->req_busy = 1;
 		return (0);
-  }
+	}
 
-  if (!pLib->general_fax_event) {
+	if (!pLib->general_fax_event) {
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\FAX Event", pLib->buffer))) {
-      return (-1);
-    }
-    pLib->general_fax_event = 1;
+			return (-1);
+		}
+		pLib->general_fax_event = 1;
 		pLib->req_busy = 1;
 		return (0);
-  }
+	}
 
-  if (!pLib->general_mdm_event) {
+	if (!pLib->general_mdm_event) {
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, "State\\Modem Event", pLib->buffer))) {
-      return (-1);
-    }
-    pLib->general_mdm_event = 1;
+			return (-1);
+		}
+		pLib->general_mdm_event = 1;
 		pLib->req_busy = 1;
 		return (0);
-  }
+	}
 
 	if (pLib->ChannelsTraceActive < pLib->Channels) {
 		pLib->ChannelsTraceActive++;
-		sprintf (name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
+		sprintf(name, "State\\B%d\\Line", pLib->ChannelsTraceActive);
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->ChannelsTraceActive--;
 			return (-1);
@@ -499,7 +499,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (pLib->ModemTraceActive < pLib->Channels) {
 		pLib->ModemTraceActive++;
-		sprintf (name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
+		sprintf(name, "State\\B%d\\Modem\\Event", pLib->ModemTraceActive);
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->ModemTraceActive--;
 			return (-1);
@@ -510,7 +510,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (pLib->FaxTraceActive < pLib->Channels) {
 		pLib->FaxTraceActive++;
-		sprintf (name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
+		sprintf(name, "State\\B%d\\FAX\\Event", pLib->FaxTraceActive);
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->FaxTraceActive--;
 			return (-1);
@@ -521,12 +521,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (!pLib->trace_mask_init) {
 		word tmp = 0x0000;
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\Event Enable",
-												 		&tmp,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(tmp))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\Event Enable",
+				       &tmp,
+				       0x87, /* MI_BITFLD */
+					sizeof(tmp))) {
 			return (-1);
 		}
 		pLib->trace_mask_init = 1;
@@ -536,12 +536,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (!pLib->audio_trace_init) {
 		dword tmp = 0x00000000;
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\AudioCh# Enable",
-												 		&tmp,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(tmp))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\AudioCh# Enable",
+				       &tmp,
+				       0x87, /* MI_BITFLD */
+					sizeof(tmp))) {
 			return (-1);
 		}
 		pLib->audio_trace_init = 2;
@@ -551,12 +551,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (!pLib->bchannel_init) {
 		dword tmp = 0x00000000;
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\B-Ch# Enable",
-												 		&tmp,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(tmp))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\B-Ch# Enable",
+				       &tmp,
+				       0x87, /* MI_BITFLD */
+					sizeof(tmp))) {
 			return (-1);
 		}
 		pLib->bchannel_init = 1;
@@ -566,12 +566,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (!pLib->trace_length_init) {
 		word tmp = 30;
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\Max Log Length",
-												 		&tmp,
-														0x82, /* MI_UINT */
-												 		sizeof(tmp))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\Max Log Length",
+				       &tmp,
+				       0x82, /* MI_UINT */
+					sizeof(tmp))) {
 			return (-1);
 		}
 		pLib->trace_length_init = 1;
@@ -580,9 +580,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (!pLib->trace_on) {
-		if (SuperTraceTraceOnRequest (pLib->hAdapter,
-																	"Trace\\Log Buffer",
-																	pLib->buffer)) {
+		if (SuperTraceTraceOnRequest(pLib->hAdapter,
+					     "Trace\\Log Buffer",
+					     pLib->buffer)) {
 			return (-1);
 		}
 		pLib->trace_on = 1;
@@ -591,12 +591,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->trace_event_mask != pLib->current_trace_event_mask) {
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\Event Enable",
-												 		&pLib->trace_event_mask,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(pLib->trace_event_mask))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\Event Enable",
+				       &pLib->trace_event_mask,
+				       0x87, /* MI_BITFLD */
+					sizeof(pLib->trace_event_mask))) {
 			return (-1);
 		}
 		pLib->current_trace_event_mask = pLib->trace_event_mask;
@@ -605,12 +605,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if ((pLib->audio_tap_pending >= 0) && (pLib->audio_tap_mask != pLib->current_audio_tap_mask)) {
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\AudioCh# Enable",
-												 		&pLib->audio_tap_mask,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(pLib->audio_tap_mask))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\AudioCh# Enable",
+				       &pLib->audio_tap_mask,
+				       0x87, /* MI_BITFLD */
+					sizeof(pLib->audio_tap_mask))) {
 			return (-1);
 		}
 		pLib->current_audio_tap_mask = pLib->audio_tap_mask;
@@ -620,12 +620,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if ((pLib->eye_pattern_pending >= 0) && (pLib->audio_tap_mask != pLib->current_eye_pattern_mask)) {
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\EyeCh# Enable",
-												 		&pLib->audio_tap_mask,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(pLib->audio_tap_mask))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\EyeCh# Enable",
+				       &pLib->audio_tap_mask,
+				       0x87, /* MI_BITFLD */
+					sizeof(pLib->audio_tap_mask))) {
 			return (-1);
 		}
 		pLib->current_eye_pattern_mask = pLib->audio_tap_mask;
@@ -635,12 +635,12 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->bchannel_trace_mask != pLib->current_bchannel_trace_mask) {
-		if (SuperTraceWriteVar (pLib->hAdapter,
-														pLib->buffer,
-												 		"Trace\\B-Ch# Enable",
-												 		&pLib->bchannel_trace_mask,
-												 		0x87, /* MI_BITFLD */
-												 		sizeof(pLib->bchannel_trace_mask))) {
+		if (SuperTraceWriteVar(pLib->hAdapter,
+				       pLib->buffer,
+				       "Trace\\B-Ch# Enable",
+				       &pLib->bchannel_trace_mask,
+				       0x87, /* MI_BITFLD */
+					sizeof(pLib->bchannel_trace_mask))) {
 			return (-1);
 		}
 		pLib->current_bchannel_trace_mask = pLib->bchannel_trace_mask;
@@ -649,9 +649,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (!pLib->trace_events_down) {
-		if (SuperTraceTraceOnRequest (pLib->hAdapter,
-																	"Events Down",
-																	pLib->buffer)) {
+		if (SuperTraceTraceOnRequest(pLib->hAdapter,
+					     "Events Down",
+					     pLib->buffer)) {
 			return (-1);
 		}
 		pLib->trace_events_down = 1;
@@ -660,9 +660,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (!pLib->l1_trace) {
-		if (SuperTraceTraceOnRequest (pLib->hAdapter,
-																	"State\\Layer1",
-																	pLib->buffer)) {
+		if (SuperTraceTraceOnRequest(pLib->hAdapter,
+					     "State\\Layer1",
+					     pLib->buffer)) {
 			return (-1);
 		}
 		pLib->l1_trace = 1;
@@ -671,9 +671,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (!pLib->l2_trace) {
-		if (SuperTraceTraceOnRequest (pLib->hAdapter,
-																	"State\\Layer2 No1",
-																	pLib->buffer)) {
+		if (SuperTraceTraceOnRequest(pLib->hAdapter,
+					     "State\\Layer2 No1",
+					     pLib->buffer)) {
 			return (-1);
 		}
 		pLib->l2_trace = 1;
@@ -683,8 +683,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	for (i = 0; i < 30; i++) {
 		if (pLib->pending_line_status & (1L << i)) {
-			sprintf (name, "State\\B%d", i+1);
-			if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) {
+			sprintf(name, "State\\B%d", i + 1);
+			if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
 				return (-1);
 			}
 			pLib->pending_line_status &= ~(1L << i);
@@ -692,8 +692,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 			return (0);
 		}
 		if (pLib->pending_modem_status & (1L << i)) {
-			sprintf (name, "State\\B%d\\Modem", i+1);
-			if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) {
+			sprintf(name, "State\\B%d\\Modem", i + 1);
+			if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
 				return (-1);
 			}
 			pLib->pending_modem_status &= ~(1L << i);
@@ -701,8 +701,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 			return (0);
 		}
 		if (pLib->pending_fax_status & (1L << i)) {
-			sprintf (name, "State\\B%d\\FAX", i+1);
-			if (SuperTraceReadRequest (pLib->hAdapter, name, pLib->buffer)) {
+			sprintf(name, "State\\B%d\\FAX", i + 1);
+			if (SuperTraceReadRequest(pLib->hAdapter, name, pLib->buffer)) {
 				return (-1);
 			}
 			pLib->pending_fax_status &= ~(1L << i);
@@ -710,8 +710,8 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 			return (0);
 		}
 		if (pLib->clear_call_command & (1L << i)) {
-			sprintf (name, "State\\B%d\\Clear Call", i+1);
-			if (SuperTraceExecuteRequest (pLib->hAdapter, name, pLib->buffer)) {
+			sprintf(name, "State\\B%d\\Clear Call", i + 1);
+			if (SuperTraceExecuteRequest(pLib->hAdapter, name, pLib->buffer)) {
 				return (-1);
 			}
 			pLib->clear_call_command &= ~(1L << i);
@@ -721,9 +721,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->outgoing_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\Outgoing Calls",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\Outgoing Calls",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->outgoing_ifc_stats = 0;
@@ -732,9 +732,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->incoming_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\Incoming Calls",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\Incoming Calls",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->incoming_ifc_stats = 0;
@@ -743,9 +743,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->modem_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\Modem",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\Modem",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->modem_ifc_stats = 0;
@@ -754,9 +754,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->fax_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\FAX",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\FAX",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->fax_ifc_stats = 0;
@@ -765,9 +765,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->b1_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\B-Layer1",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\B-Layer1",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->b1_ifc_stats = 0;
@@ -776,9 +776,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->b2_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\B-Layer2",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\B-Layer2",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->b2_ifc_stats = 0;
@@ -787,9 +787,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->d1_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\D-Layer1",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\D-Layer1",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->d1_ifc_stats = 0;
@@ -798,9 +798,9 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 
 	if (pLib->d2_ifc_stats) {
-		if (SuperTraceReadRequest (pLib->hAdapter,
-															 "Statistics\\D-Layer2",
-															 pLib->buffer)) {
+		if (SuperTraceReadRequest(pLib->hAdapter,
+					  "Statistics\\D-Layer2",
+					  pLib->buffer)) {
 			return (-1);
 		}
 		pLib->d2_ifc_stats = 0;
@@ -810,7 +810,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 
 	if (!pLib->IncomingCallsCallsActive) {
 		pLib->IncomingCallsCallsActive = 1;
-		sprintf (name, "%s", "Statistics\\Incoming Calls\\Calls");
+		sprintf(name, "%s", "Statistics\\Incoming Calls\\Calls");
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->IncomingCallsCallsActive = 0;
 			return (-1);
@@ -820,7 +820,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 	if (!pLib->IncomingCallsConnectedActive) {
 		pLib->IncomingCallsConnectedActive = 1;
-		sprintf (name, "%s", "Statistics\\Incoming Calls\\Connected");
+		sprintf(name, "%s", "Statistics\\Incoming Calls\\Connected");
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->IncomingCallsConnectedActive = 0;
 			return (-1);
@@ -830,7 +830,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 	if (!pLib->OutgoingCallsCallsActive) {
 		pLib->OutgoingCallsCallsActive = 1;
-		sprintf (name, "%s", "Statistics\\Outgoing Calls\\Calls");
+		sprintf(name, "%s", "Statistics\\Outgoing Calls\\Calls");
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->OutgoingCallsCallsActive = 0;
 			return (-1);
@@ -840,7 +840,7 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	}
 	if (!pLib->OutgoingCallsConnectedActive) {
 		pLib->OutgoingCallsConnectedActive = 1;
-		sprintf (name, "%s", "Statistics\\Outgoing Calls\\Connected");
+		sprintf(name, "%s", "Statistics\\Outgoing Calls\\Connected");
 		if ((ret = SuperTraceTraceOnRequest(pLib->hAdapter, name, pLib->buffer))) {
 			pLib->OutgoingCallsConnectedActive = 0;
 			return (-1);
@@ -852,241 +852,241 @@ static int ScheduleNextTraceRequest (diva_strace_context_t* pLib) {
 	return (0);
 }
 
-static int process_idi_event (diva_strace_context_t* pLib,
-				diva_man_var_header_t* pVar) {
-	const char* path = (char*)&pVar->path_length+1;
+static int process_idi_event(diva_strace_context_t *pLib,
+			     diva_man_var_header_t *pVar) {
+	const char *path = (char *)&pVar->path_length + 1;
 	char name[64];
 	int i;
 
 	if (!strncmp("State\\B Event", path, pVar->path_length)) {
-    dword ch_id;
-    if (!diva_trace_read_variable (pVar, &ch_id)) {
-      if (!pLib->line_init_event && !pLib->pending_line_status) {
-        for (i = 1; i <= pLib->Channels; i++) {
-          diva_line_event(pLib, i);
-        }
-        return (0);
-      } else if (ch_id && ch_id <= pLib->Channels) {
-        return (diva_line_event(pLib, (int)ch_id));
-      }
-      return (0);
-    }
-    return (-1);
-  }
+		dword ch_id;
+		if (!diva_trace_read_variable(pVar, &ch_id)) {
+			if (!pLib->line_init_event && !pLib->pending_line_status) {
+				for (i = 1; i <= pLib->Channels; i++) {
+					diva_line_event(pLib, i);
+				}
+				return (0);
+			} else if (ch_id && ch_id <= pLib->Channels) {
+				return (diva_line_event(pLib, (int)ch_id));
+			}
+			return (0);
+		}
+		return (-1);
+	}
 
 	if (!strncmp("State\\FAX Event", path, pVar->path_length)) {
-    dword ch_id;
-    if (!diva_trace_read_variable (pVar, &ch_id)) {
-      if (!pLib->pending_fax_status && !pLib->fax_init_event) {
-        for (i = 1; i <= pLib->Channels; i++) {
-          diva_fax_event(pLib, i);
-        }
-        return (0);
-      } else if (ch_id && ch_id <= pLib->Channels) {
-        return (diva_fax_event(pLib, (int)ch_id));
-      }
-      return (0);
-    }
-    return (-1);
-  }
+		dword ch_id;
+		if (!diva_trace_read_variable(pVar, &ch_id)) {
+			if (!pLib->pending_fax_status && !pLib->fax_init_event) {
+				for (i = 1; i <= pLib->Channels; i++) {
+					diva_fax_event(pLib, i);
+				}
+				return (0);
+			} else if (ch_id && ch_id <= pLib->Channels) {
+				return (diva_fax_event(pLib, (int)ch_id));
+			}
+			return (0);
+		}
+		return (-1);
+	}
 
 	if (!strncmp("State\\Modem Event", path, pVar->path_length)) {
-    dword ch_id;
-    if (!diva_trace_read_variable (pVar, &ch_id)) {
-      if (!pLib->pending_modem_status && !pLib->modem_init_event) {
-        for (i = 1; i <= pLib->Channels; i++) {
-          diva_modem_event(pLib, i);
-        }
-        return (0);
-      } else if (ch_id && ch_id <= pLib->Channels) {
-        return (diva_modem_event(pLib, (int)ch_id));
-      }
-      return (0);
-    }
-    return (-1);
-  }
+		dword ch_id;
+		if (!diva_trace_read_variable(pVar, &ch_id)) {
+			if (!pLib->pending_modem_status && !pLib->modem_init_event) {
+				for (i = 1; i <= pLib->Channels; i++) {
+					diva_modem_event(pLib, i);
+				}
+				return (0);
+			} else if (ch_id && ch_id <= pLib->Channels) {
+				return (diva_modem_event(pLib, (int)ch_id));
+			}
+			return (0);
+		}
+		return (-1);
+	}
 
 	/*
-		First look for Line Event
-		*/
+	  First look for Line Event
+	*/
 	for (i = 1; i <= pLib->Channels; i++) {
-		sprintf (name, "State\\B%d\\Line", i);
-		if (find_var (pVar, name)) {
+		sprintf(name, "State\\B%d\\Line", i);
+		if (find_var(pVar, name)) {
 			return (diva_line_event(pLib, i));
 		}
 	}
 
 	/*
-		Look for Moden Progress Event
-		*/
+	  Look for Moden Progress Event
+	*/
 	for (i = 1; i <= pLib->Channels; i++) {
-		sprintf (name, "State\\B%d\\Modem\\Event", i);
-		if (find_var (pVar, name)) {
-			return (diva_modem_event (pLib, i));
+		sprintf(name, "State\\B%d\\Modem\\Event", i);
+		if (find_var(pVar, name)) {
+			return (diva_modem_event(pLib, i));
 		}
 	}
 
 	/*
-		Look for Fax Event
-		*/
+	  Look for Fax Event
+	*/
 	for (i = 1; i <= pLib->Channels; i++) {
-		sprintf (name, "State\\B%d\\FAX\\Event", i);
-		if (find_var (pVar, name)) {
-			return (diva_fax_event (pLib, i));
+		sprintf(name, "State\\B%d\\FAX\\Event", i);
+		if (find_var(pVar, name)) {
+			return (diva_fax_event(pLib, i));
 		}
 	}
 
 	/*
-		Notification about loss of events
-		*/
+	  Notification about loss of events
+	*/
 	if (!strncmp("Events Down", path, pVar->path_length)) {
 		if (pLib->trace_events_down == 1) {
 			pLib->trace_events_down = 2;
 		} else {
-			diva_trace_error (pLib, 1, "Events Down", 0);
+			diva_trace_error(pLib, 1, "Events Down", 0);
 		}
 		return (0);
 	}
 
 	if (!strncmp("State\\Layer1", path, pVar->path_length)) {
-		diva_strace_read_asz  (pVar, &pLib->lines[0].pInterface->Layer1[0]);
+		diva_strace_read_asz(pVar, &pLib->lines[0].pInterface->Layer1[0]);
 		if (pLib->l1_trace == 1) {
 			pLib->l1_trace = 2;
 		} else {
-			diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
+			diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
 		}
 		return (0);
 	}
 	if (!strncmp("State\\Layer2 No1", path, pVar->path_length)) {
-		char* tmp = &pLib->lines[0].pInterface->Layer2[0];
+		char *tmp = &pLib->lines[0].pInterface->Layer2[0];
 		dword l2_state;
 		if (diva_strace_read_uint(pVar, &l2_state))
 			return -1;
 
 		switch (l2_state) {
-			case 0:
-				strcpy (tmp, "Idle");
-				break;
-			case 1:
-				strcpy (tmp, "Layer2 UP");
-				break;
-			case 2:
-				strcpy (tmp, "Layer2 Disconnecting");
-				break;
-			case 3:
-				strcpy (tmp, "Layer2 Connecting");
-				break;
-			case 4:
-				strcpy (tmp, "SPID Initializing");
-				break;
-			case 5:
-				strcpy (tmp, "SPID Initialised");
-				break;
-			case 6:
-				strcpy (tmp, "Layer2 Connecting");
-				break;
-
-			case  7:
-				strcpy (tmp, "Auto SPID Stopped");
-				break;
-
-			case  8:
-				strcpy (tmp, "Auto SPID Idle");
-				break;
-
-			case  9:
-				strcpy (tmp, "Auto SPID Requested");
-				break;
-
-			case  10:
-				strcpy (tmp, "Auto SPID Delivery");
-				break;
-
-			case 11:
-				strcpy (tmp, "Auto SPID Complete");
-				break;
-
-			default:
-				sprintf (tmp, "U:%d", (int)l2_state);
+		case 0:
+			strcpy(tmp, "Idle");
+			break;
+		case 1:
+			strcpy(tmp, "Layer2 UP");
+			break;
+		case 2:
+			strcpy(tmp, "Layer2 Disconnecting");
+			break;
+		case 3:
+			strcpy(tmp, "Layer2 Connecting");
+			break;
+		case 4:
+			strcpy(tmp, "SPID Initializing");
+			break;
+		case 5:
+			strcpy(tmp, "SPID Initialised");
+			break;
+		case 6:
+			strcpy(tmp, "Layer2 Connecting");
+			break;
+
+		case  7:
+			strcpy(tmp, "Auto SPID Stopped");
+			break;
+
+		case  8:
+			strcpy(tmp, "Auto SPID Idle");
+			break;
+
+		case  9:
+			strcpy(tmp, "Auto SPID Requested");
+			break;
+
+		case  10:
+			strcpy(tmp, "Auto SPID Delivery");
+			break;
+
+		case 11:
+			strcpy(tmp, "Auto SPID Complete");
+			break;
+
+		default:
+			sprintf(tmp, "U:%d", (int)l2_state);
 		}
 		if (pLib->l2_trace == 1) {
 			pLib->l2_trace = 2;
 		} else {
-			diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
+			diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_INTERFACE_CHANGE);
 		}
 		return (0);
 	}
 
 	if (!strncmp("Statistics\\Incoming Calls\\Calls", path, pVar->path_length) ||
-			!strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
-		return (SuperTraceGetIncomingCallStatistics (pLib));
+	    !strncmp("Statistics\\Incoming Calls\\Connected", path, pVar->path_length)) {
+		return (SuperTraceGetIncomingCallStatistics(pLib));
 	}
 
 	if (!strncmp("Statistics\\Outgoing Calls\\Calls", path, pVar->path_length) ||
-			!strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
-		return (SuperTraceGetOutgoingCallStatistics (pLib));
+	    !strncmp("Statistics\\Outgoing Calls\\Connected", path, pVar->path_length)) {
+		return (SuperTraceGetOutgoingCallStatistics(pLib));
 	}
 
 	return (-1);
 }
 
-static int diva_line_event (diva_strace_context_t* pLib, int Channel) {
-	pLib->pending_line_status |= (1L << (Channel-1));
+static int diva_line_event(diva_strace_context_t *pLib, int Channel) {
+	pLib->pending_line_status |= (1L << (Channel - 1));
 	return (0);
 }
 
-static int diva_modem_event (diva_strace_context_t* pLib, int Channel) {
-	pLib->pending_modem_status |= (1L << (Channel-1));
+static int diva_modem_event(diva_strace_context_t *pLib, int Channel) {
+	pLib->pending_modem_status |= (1L << (Channel - 1));
 	return (0);
 }
 
-static int diva_fax_event (diva_strace_context_t* pLib, int Channel) {
-	pLib->pending_fax_status |= (1L << (Channel-1));
+static int diva_fax_event(diva_strace_context_t *pLib, int Channel) {
+	pLib->pending_fax_status |= (1L << (Channel - 1));
 	return (0);
 }
 
 /*
-	Process INFO indications that arrive from the card
-	Uses path of first I.E. to detect the source of the
-	infication
-	*/
-static int process_idi_info  (diva_strace_context_t* pLib,
-															diva_man_var_header_t* pVar) {
-	const char* path = (char*)&pVar->path_length+1;
+  Process INFO indications that arrive from the card
+  Uses path of first I.E. to detect the source of the
+  infication
+*/
+static int process_idi_info(diva_strace_context_t *pLib,
+			    diva_man_var_header_t *pVar) {
+	const char *path = (char *)&pVar->path_length + 1;
 	char name[64];
 	int i, len;
 
 	/*
-		First look for Modem Status Info
-		*/
+	  First look for Modem Status Info
+	*/
 	for (i = pLib->Channels; i > 0; i--) {
-		len = sprintf (name, "State\\B%d\\Modem", i);
+		len = sprintf(name, "State\\B%d\\Modem", i);
 		if (!strncmp(name, path, len)) {
-			return (diva_modem_info (pLib, i, pVar));
+			return (diva_modem_info(pLib, i, pVar));
 		}
 	}
 
 	/*
-		Look for Fax Status Info
-		*/
+	  Look for Fax Status Info
+	*/
 	for (i = pLib->Channels; i > 0; i--) {
-		len = sprintf (name, "State\\B%d\\FAX", i);
+		len = sprintf(name, "State\\B%d\\FAX", i);
 		if (!strncmp(name, path, len)) {
-			return (diva_fax_info (pLib, i, pVar));
+			return (diva_fax_info(pLib, i, pVar));
 		}
 	}
 
 	/*
-		Look for Line Status Info
-		*/
+	  Look for Line Status Info
+	*/
 	for (i = pLib->Channels; i > 0; i--) {
-		len = sprintf (name, "State\\B%d", i);
+		len = sprintf(name, "State\\B%d", i);
 		if (!strncmp(name, path, len)) {
-			return (diva_line_info (pLib, i, pVar));
+			return (diva_line_info(pLib, i, pVar));
 		}
 	}
 
-	if (!diva_ifc_statistics (pLib, pVar)) {
+	if (!diva_ifc_statistics(pLib, pVar)) {
 		return (0);
 	}
 
@@ -1094,38 +1094,38 @@ static int process_idi_info  (diva_strace_context_t* pLib,
 }
 
 /*
-	MODEM INSTANCE STATE UPDATE
-
-	Update Modem Status Information and issue notification to user,
-	that will inform about change in the state of modem instance, that is
-	associuated with this channel
-	*/
-static int diva_modem_info (diva_strace_context_t* pLib,
-														int Channel,
-														diva_man_var_header_t* pVar) {
-	diva_man_var_header_t* cur;
+  MODEM INSTANCE STATE UPDATE
+
+  Update Modem Status Information and issue notification to user,
+  that will inform about change in the state of modem instance, that is
+  associuated with this channel
+*/
+static int diva_modem_info(diva_strace_context_t *pLib,
+			   int Channel,
+			   diva_man_var_header_t *pVar) {
+	diva_man_var_header_t *cur;
 	int i, nr = Channel - 1;
 
 	for (i  = pLib->modem_parse_entry_first[nr];
-			 i <= pLib->modem_parse_entry_last[nr]; i++) {
-		if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
-			if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
-				diva_trace_error (pLib, -3 , __FILE__, __LINE__);
+	     i <= pLib->modem_parse_entry_last[nr]; i++) {
+		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+				diva_trace_error(pLib, -3, __FILE__, __LINE__);
 				return (-1);
 			}
 		} else {
-			diva_trace_error (pLib, -2 , __FILE__, __LINE__);
+			diva_trace_error(pLib, -2, __FILE__, __LINE__);
 			return (-1);
 		}
 	}
 
 	/*
-		We do not use first event to notify user - this is the event that is
-		generated as result of EVENT ON operation and is used only to initialize
-		internal variables of application
-		*/
+	  We do not use first event to notify user - this is the event that is
+	  generated as result of EVENT ON operation and is used only to initialize
+	  internal variables of application
+	*/
 	if (pLib->modem_init_event & (1L << nr)) {
-		diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
+		diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_MODEM_CHANGE);
 	} else {
 		pLib->modem_init_event |= (1L << nr);
 	}
@@ -1133,32 +1133,32 @@ static int diva_modem_info (diva_strace_context_t* pLib,
 	return (0);
 }
 
-static int diva_fax_info (diva_strace_context_t* pLib,
-													int Channel,
-													diva_man_var_header_t* pVar) {
-	diva_man_var_header_t* cur;
+static int diva_fax_info(diva_strace_context_t *pLib,
+			 int Channel,
+			 diva_man_var_header_t *pVar) {
+	diva_man_var_header_t *cur;
 	int i, nr = Channel - 1;
 
 	for (i  = pLib->fax_parse_entry_first[nr];
-			 i <= pLib->fax_parse_entry_last[nr]; i++) {
-		if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
-			if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
-				diva_trace_error (pLib, -3 , __FILE__, __LINE__);
+	     i <= pLib->fax_parse_entry_last[nr]; i++) {
+		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+				diva_trace_error(pLib, -3, __FILE__, __LINE__);
 				return (-1);
 			}
 		} else {
-			diva_trace_error (pLib, -2 , __FILE__, __LINE__);
+			diva_trace_error(pLib, -2, __FILE__, __LINE__);
 			return (-1);
 		}
 	}
 
 	/*
-		We do not use first event to notify user - this is the event that is
-		generated as result of EVENT ON operation and is used only to initialize
-		internal variables of application
-		*/
+	  We do not use first event to notify user - this is the event that is
+	  generated as result of EVENT ON operation and is used only to initialize
+	  internal variables of application
+	*/
 	if (pLib->fax_init_event & (1L << nr)) {
-		diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
+		diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_FAX_CHANGE);
 	} else {
 		pLib->fax_init_event |= (1L << nr);
 	}
@@ -1167,43 +1167,43 @@ static int diva_fax_info (diva_strace_context_t* pLib,
 }
 
 /*
-	LINE STATE UPDATE
-	Update Line Status Information and issue notification to user,
-	that will inform about change in the line state.
-	*/
-static int diva_line_info  (diva_strace_context_t* pLib,
-														int Channel,
-														diva_man_var_header_t* pVar) {
-	diva_man_var_header_t* cur;
+  LINE STATE UPDATE
+  Update Line Status Information and issue notification to user,
+  that will inform about change in the line state.
+*/
+static int diva_line_info(diva_strace_context_t *pLib,
+			  int Channel,
+			  diva_man_var_header_t *pVar) {
+	diva_man_var_header_t *cur;
 	int i, nr = Channel - 1;
 
-	for (i  = pLib->line_parse_entry_first[nr];
-			 i <= pLib->line_parse_entry_last[nr]; i++) {
-		if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
-			if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
-				diva_trace_error (pLib, -3 , __FILE__, __LINE__);
+	for (i = pLib->line_parse_entry_first[nr];
+	     i <= pLib->line_parse_entry_last[nr]; i++) {
+		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+				diva_trace_error(pLib, -3, __FILE__, __LINE__);
 				return (-1);
 			}
 		} else {
-			diva_trace_error (pLib, -2 , __FILE__, __LINE__);
+			diva_trace_error(pLib, -2 , __FILE__, __LINE__);
 			return (-1);
 		}
 	}
 
 	/*
-		We do not use first event to notify user - this is the event that is
-		generated as result of EVENT ON operation and is used only to initialize
-		internal variables of application
+	  We do not use first event to notify user - this is the event that is
+	  generated as result of EVENT ON operation and is used only to initialize
+	  internal variables of application
 
-		Exception is is if the line is "online". In this case we have to notify
-		user about this confition.
-		*/
+	  Exception is is if the line is "online". In this case we have to notify
+	  user about this confition.
+	*/
 	if (pLib->line_init_event & (1L << nr)) {
-		diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
+		diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
 	} else {
 		pLib->line_init_event |= (1L << nr);
-		if (strcmp (&pLib->lines[nr].Line[0], "Idle")) {
-			diva_trace_notify_user (pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
+		if (strcmp(&pLib->lines[nr].Line[0], "Idle")) {
+			diva_trace_notify_user(pLib, nr, DIVA_SUPER_TRACE_NOTIFY_LINE_CHANGE);
 		}
 	}
 
@@ -1211,49 +1211,49 @@ static int diva_line_info  (diva_strace_context_t* pLib,
 }
 
 /*
-	Move position to next vatianle in the chain
-	*/
-static diva_man_var_header_t* get_next_var (diva_man_var_header_t* pVar) {
-	byte* msg   = (byte*)pVar;
-	byte* start;
+  Move position to next vatianle in the chain
+*/
+static diva_man_var_header_t *get_next_var(diva_man_var_header_t *pVar) {
+	byte *msg = (byte *)pVar;
+	byte *start;
 	int msg_length;
 
 	if (*msg != ESC) return NULL;
 
 	start = msg + 2;
-	msg_length = *(msg+1);
-	msg = (start+msg_length);
+	msg_length = *(msg + 1);
+	msg = (start + msg_length);
 
 	if (*msg != ESC) return NULL;
 
-	return ((diva_man_var_header_t*)msg);
+	return ((diva_man_var_header_t *)msg);
 }
 
 /*
-	Move position to variable with given name
-	*/
-static diva_man_var_header_t* find_var (diva_man_var_header_t* pVar,
-																				const char* name) {
-	const char* path;
+  Move position to variable with given name
+*/
+static diva_man_var_header_t *find_var(diva_man_var_header_t *pVar,
+				       const char *name) {
+	const char *path;
 
 	do {
-		path = (char*)&pVar->path_length+1;
+		path = (char *)&pVar->path_length + 1;
 
-		if (!strncmp (name, path, pVar->path_length)) {
+		if (!strncmp(name, path, pVar->path_length)) {
 			break;
 		}
-	} while ((pVar = get_next_var (pVar)));
+	} while ((pVar = get_next_var(pVar)));
 
 	return (pVar);
 }
 
-static void diva_create_line_parse_table  (diva_strace_context_t* pLib,
-																					 int Channel) {
-	diva_trace_line_state_t* pLine = &pLib->lines[Channel];
-	int nr = Channel+1;
+static void diva_create_line_parse_table(diva_strace_context_t *pLib,
+					 int Channel) {
+	diva_trace_line_state_t *pLine = &pLib->lines[Channel];
+	int nr = Channel + 1;
 
 	if ((pLib->cur_parse_entry + LINE_PARSE_ENTRIES) >= pLib->parse_entries) {
-		diva_trace_error (pLib, -1, __FILE__, __LINE__);
+		diva_trace_error(pLib, -1, __FILE__, __LINE__);
 		return;
 	}
 
@@ -1261,674 +1261,674 @@ static void diva_create_line_parse_table  (diva_strace_context_t* pLib,
 
 	pLib->line_parse_entry_first[Channel] = pLib->cur_parse_entry;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Framing", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Framing", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Framing[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Line", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Line", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Line[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Layer2", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Layer2", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer2[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Layer3", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Layer3", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Layer3[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Remote Address", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Remote Address", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																								&pLine->RemoteAddress[0];
+		&pLine->RemoteAddress[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Remote SubAddr", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Remote SubAddr", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																								&pLine->RemoteSubAddress[0];
+		&pLine->RemoteSubAddress[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Local Address", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Local Address", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																								&pLine->LocalAddress[0];
+		&pLine->LocalAddress[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Local SubAddr", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Local SubAddr", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																								&pLine->LocalSubAddress[0];
+		&pLine->LocalSubAddress[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\BC", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\BC", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_BC;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\HLC", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\HLC", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_HLC;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\LLC", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\LLC", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->call_LLC;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Charges", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Charges", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->Charges;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Call Reference", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Call Reference", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->CallReference;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Last Disc Cause", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Last Disc Cause", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																										&pLine->LastDisconnecCause;
+		&pLine->LastDisconnecCause;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\User ID", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\User ID", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pLine->UserID[0];
 
 	pLib->line_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
 }
 
-static void diva_create_fax_parse_table (diva_strace_context_t* pLib,
-																				 int Channel) {
-	diva_trace_fax_state_t* pFax = &pLib->lines[Channel].fax;
-	int nr = Channel+1;
+static void diva_create_fax_parse_table(diva_strace_context_t *pLib,
+					int Channel) {
+	diva_trace_fax_state_t *pFax = &pLib->lines[Channel].fax;
+	int nr = Channel + 1;
 
 	if ((pLib->cur_parse_entry + FAX_PARSE_ENTRIES) >= pLib->parse_entries) {
-		diva_trace_error (pLib, -1, __FILE__, __LINE__);
+		diva_trace_error(pLib, -1, __FILE__, __LINE__);
 		return;
 	}
 	pFax->ChannelNumber = nr;
 
 	pLib->fax_parse_entry_first[Channel] = pLib->cur_parse_entry;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Event", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Event", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Event;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Page Counter", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Page Counter", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Page_Counter;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Features", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Features", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Features;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Station ID", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Station ID", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Station_ID[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Subaddress", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Subaddress", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Subaddress[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Password", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Password", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Password[0];
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Speed", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Speed", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Speed;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Resolution", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Resolution", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Resolution;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Paper Width", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Paper Width", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Width;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Paper Length", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Paper Length", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Paper_Length;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Scanline Time", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Scanline Time", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Scanline_Time;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\FAX\\Disc Reason", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\FAX\\Disc Reason", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pFax->Disc_Reason;
 
 	pLib->fax_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
 }
 
-static void diva_create_modem_parse_table (diva_strace_context_t* pLib,
-																					 int Channel) {
-	diva_trace_modem_state_t* pModem = &pLib->lines[Channel].modem;
-	int nr = Channel+1;
+static void diva_create_modem_parse_table(diva_strace_context_t *pLib,
+					  int Channel) {
+	diva_trace_modem_state_t *pModem = &pLib->lines[Channel].modem;
+	int nr = Channel + 1;
 
 	if ((pLib->cur_parse_entry + MODEM_PARSE_ENTRIES) >= pLib->parse_entries) {
-		diva_trace_error (pLib, -1, __FILE__, __LINE__);
+		diva_trace_error(pLib, -1, __FILE__, __LINE__);
 		return;
 	}
 	pModem->ChannelNumber = nr;
 
 	pLib->modem_parse_entry_first[Channel] = pLib->cur_parse_entry;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Event", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Event", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Event;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Norm", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Norm", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Norm;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Options", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Options", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->Options;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\TX Speed", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\TX Speed", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->TxSpeed;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\RX Speed", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\RX Speed", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxSpeed;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Roundtrip ms", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Roundtrip ms", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RoundtripMsec;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Symbol Rate", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Symbol Rate", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SymbolRate;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\RX Level dBm", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\RX Level dBm", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RxLeveldBm;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Echo Level dBm", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Echo Level dBm", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->EchoLeveldBm;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\SNR dB", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\SNR dB", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->SNRdb;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\MAE", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\MAE", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->MAE;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Local Retrains", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Local Retrains", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalRetrains;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Remote Retrains", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Remote Retrains", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteRetrains;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Local Resyncs", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Local Resyncs", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->LocalResyncs;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Remote Resyncs", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Remote Resyncs", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->RemoteResyncs;
 
-	sprintf (pLib->parse_table[pLib->cur_parse_entry].path,
-					 "State\\B%d\\Modem\\Disc Reason", nr);
+	sprintf(pLib->parse_table[pLib->cur_parse_entry].path,
+		"State\\B%d\\Modem\\Disc Reason", nr);
 	pLib->parse_table[pLib->cur_parse_entry++].variable = &pModem->DiscReason;
 
 	pLib->modem_parse_entry_last[Channel] = pLib->cur_parse_entry - 1;
 }
 
-static void diva_create_parse_table (diva_strace_context_t* pLib) {
+static void diva_create_parse_table(diva_strace_context_t *pLib) {
 	int i;
 
 	for (i = 0; i < pLib->Channels; i++) {
-		diva_create_line_parse_table  (pLib, i);
-		diva_create_modem_parse_table (pLib, i);
-		diva_create_fax_parse_table   (pLib, i);
+		diva_create_line_parse_table(pLib, i);
+		diva_create_modem_parse_table(pLib, i);
+		diva_create_fax_parse_table(pLib, i);
 	}
 
 	pLib->statistic_parse_first = pLib->cur_parse_entry;
 
 	/*
-		Outgoing Calls
-		*/
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\Calls");
+	  Outgoing Calls
+	*/
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\Calls");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.Calls;
+		&pLib->InterfaceStat.outg.Calls;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\Connected");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\Connected");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.Connected;
+		&pLib->InterfaceStat.outg.Connected;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\User Busy");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\User Busy");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.User_Busy;
+		&pLib->InterfaceStat.outg.User_Busy;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\No Answer");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\No Answer");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.No_Answer;
+		&pLib->InterfaceStat.outg.No_Answer;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\Wrong Number");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\Wrong Number");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.Wrong_Number;
+		&pLib->InterfaceStat.outg.Wrong_Number;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\Call Rejected");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\Call Rejected");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.Call_Rejected;
+		&pLib->InterfaceStat.outg.Call_Rejected;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Outgoing Calls\\Other Failures");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Outgoing Calls\\Other Failures");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.outg.Other_Failures;
+		&pLib->InterfaceStat.outg.Other_Failures;
 
 	/*
-		Incoming Calls
-		*/
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Calls");
+	  Incoming Calls
+	*/
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Calls");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Calls;
+		&pLib->InterfaceStat.inc.Calls;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Connected");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Connected");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Connected;
+		&pLib->InterfaceStat.inc.Connected;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\User Busy");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\User Busy");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.User_Busy;
+		&pLib->InterfaceStat.inc.User_Busy;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Call Rejected");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Call Rejected");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Call_Rejected;
+		&pLib->InterfaceStat.inc.Call_Rejected;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Wrong Number");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Wrong Number");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Wrong_Number;
+		&pLib->InterfaceStat.inc.Wrong_Number;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Incompatible Dst");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Incompatible Dst");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Incompatible_Dst;
+		&pLib->InterfaceStat.inc.Incompatible_Dst;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Out of Order");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Out of Order");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Out_of_Order;
+		&pLib->InterfaceStat.inc.Out_of_Order;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Incoming Calls\\Ignored");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Incoming Calls\\Ignored");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.inc.Ignored;
+		&pLib->InterfaceStat.inc.Ignored;
 
 	/*
-		Modem Statistics
-		*/
+	  Modem Statistics
+	*/
 	pLib->mdm_statistic_parse_first = pLib->cur_parse_entry;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Normal");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Normal");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Normal;
+		&pLib->InterfaceStat.mdm.Disc_Normal;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Unspecified");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Unspecified");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Unspecified;
+		&pLib->InterfaceStat.mdm.Disc_Unspecified;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Busy Tone");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Busy Tone");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Busy_Tone;
+		&pLib->InterfaceStat.mdm.Disc_Busy_Tone;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Congestion");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Congestion");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Congestion;
+		&pLib->InterfaceStat.mdm.Disc_Congestion;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Carr. Wait");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Carr. Wait");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Carr_Wait;
+		&pLib->InterfaceStat.mdm.Disc_Carr_Wait;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Trn Timeout");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Trn Timeout");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
+		&pLib->InterfaceStat.mdm.Disc_Trn_Timeout;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Incompat.");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Incompat.");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Incompat;
+		&pLib->InterfaceStat.mdm.Disc_Incompat;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc Frame Rej.");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc Frame Rej.");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_Frame_Rej;
+		&pLib->InterfaceStat.mdm.Disc_Frame_Rej;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\Modem\\Disc V42bis");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\Modem\\Disc V42bis");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.mdm.Disc_V42bis;
+		&pLib->InterfaceStat.mdm.Disc_V42bis;
 
 	pLib->mdm_statistic_parse_last  = pLib->cur_parse_entry - 1;
 
 	/*
-		Fax Statistics
-		*/
+	  Fax Statistics
+	*/
 	pLib->fax_statistic_parse_first = pLib->cur_parse_entry;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Normal");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Normal");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Normal;
+		&pLib->InterfaceStat.fax.Disc_Normal;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Not Ident.");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Not Ident.");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Not_Ident;
+		&pLib->InterfaceStat.fax.Disc_Not_Ident;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc No Response");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc No Response");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_No_Response;
+		&pLib->InterfaceStat.fax.Disc_No_Response;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Retries");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Retries");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Retries;
+		&pLib->InterfaceStat.fax.Disc_Retries;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Unexp. Msg.");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Unexp. Msg.");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Unexp_Msg;
+		&pLib->InterfaceStat.fax.Disc_Unexp_Msg;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc No Polling.");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc No Polling.");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_No_Polling;
+		&pLib->InterfaceStat.fax.Disc_No_Polling;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Training");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Training");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Training;
+		&pLib->InterfaceStat.fax.Disc_Training;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Unexpected");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Unexpected");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Unexpected;
+		&pLib->InterfaceStat.fax.Disc_Unexpected;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Application");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Application");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Application;
+		&pLib->InterfaceStat.fax.Disc_Application;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Incompat.");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Incompat.");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Incompat;
+		&pLib->InterfaceStat.fax.Disc_Incompat;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc No Command");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc No Command");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_No_Command;
+		&pLib->InterfaceStat.fax.Disc_No_Command;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Long Msg");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Long Msg");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Long_Msg;
+		&pLib->InterfaceStat.fax.Disc_Long_Msg;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Supervisor");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Supervisor");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Supervisor;
+		&pLib->InterfaceStat.fax.Disc_Supervisor;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc SUB SEP PWD");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc SUB SEP PWD");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD;
+		&pLib->InterfaceStat.fax.Disc_SUB_SEP_PWD;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Invalid Msg");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Invalid Msg");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Invalid_Msg;
+		&pLib->InterfaceStat.fax.Disc_Invalid_Msg;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Page Coding");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Page Coding");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Page_Coding;
+		&pLib->InterfaceStat.fax.Disc_Page_Coding;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc App Timeout");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc App Timeout");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_App_Timeout;
+		&pLib->InterfaceStat.fax.Disc_App_Timeout;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\FAX\\Disc Unspecified");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\FAX\\Disc Unspecified");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.fax.Disc_Unspecified;
+		&pLib->InterfaceStat.fax.Disc_Unspecified;
 
 	pLib->fax_statistic_parse_last  = pLib->cur_parse_entry - 1;
 
 	/*
-		B-Layer1"
-		*/
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer1\\X-Frames");
+	  B-Layer1"
+	*/
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer1\\X-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b1.X_Frames;
+		&pLib->InterfaceStat.b1.X_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer1\\X-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer1\\X-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b1.X_Bytes;
+		&pLib->InterfaceStat.b1.X_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer1\\X-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer1\\X-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b1.X_Errors;
+		&pLib->InterfaceStat.b1.X_Errors;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer1\\R-Frames");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer1\\R-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b1.R_Frames;
+		&pLib->InterfaceStat.b1.R_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer1\\R-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer1\\R-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b1.R_Bytes;
+		&pLib->InterfaceStat.b1.R_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer1\\R-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer1\\R-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b1.R_Errors;
+		&pLib->InterfaceStat.b1.R_Errors;
 
 	/*
-		B-Layer2
-		*/
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer2\\X-Frames");
+	  B-Layer2
+	*/
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer2\\X-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b2.X_Frames;
+		&pLib->InterfaceStat.b2.X_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer2\\X-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer2\\X-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b2.X_Bytes;
+		&pLib->InterfaceStat.b2.X_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer2\\X-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer2\\X-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b2.X_Errors;
+		&pLib->InterfaceStat.b2.X_Errors;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer2\\R-Frames");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer2\\R-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b2.R_Frames;
+		&pLib->InterfaceStat.b2.R_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer2\\R-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer2\\R-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b2.R_Bytes;
+		&pLib->InterfaceStat.b2.R_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\B-Layer2\\R-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\B-Layer2\\R-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.b2.R_Errors;
+		&pLib->InterfaceStat.b2.R_Errors;
 
 	/*
-		D-Layer1
-		*/
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer1\\X-Frames");
+	  D-Layer1
+	*/
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer1\\X-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d1.X_Frames;
+		&pLib->InterfaceStat.d1.X_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer1\\X-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer1\\X-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d1.X_Bytes;
+		&pLib->InterfaceStat.d1.X_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer1\\X-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer1\\X-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d1.X_Errors;
+		&pLib->InterfaceStat.d1.X_Errors;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer1\\R-Frames");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer1\\R-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d1.R_Frames;
+		&pLib->InterfaceStat.d1.R_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer1\\R-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer1\\R-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d1.R_Bytes;
+		&pLib->InterfaceStat.d1.R_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer1\\R-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer1\\R-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d1.R_Errors;
+		&pLib->InterfaceStat.d1.R_Errors;
 
 	/*
-		D-Layer2
-		*/
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer2\\X-Frames");
+	  D-Layer2
+	*/
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer2\\X-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d2.X_Frames;
+		&pLib->InterfaceStat.d2.X_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer2\\X-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer2\\X-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d2.X_Bytes;
+		&pLib->InterfaceStat.d2.X_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer2\\X-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer2\\X-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d2.X_Errors;
+		&pLib->InterfaceStat.d2.X_Errors;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer2\\R-Frames");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer2\\R-Frames");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d2.R_Frames;
+		&pLib->InterfaceStat.d2.R_Frames;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer2\\R-Bytes");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer2\\R-Bytes");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d2.R_Bytes;
+		&pLib->InterfaceStat.d2.R_Bytes;
 
-	strcpy (pLib->parse_table[pLib->cur_parse_entry].path,
-					"Statistics\\D-Layer2\\R-Errors");
+	strcpy(pLib->parse_table[pLib->cur_parse_entry].path,
+	       "Statistics\\D-Layer2\\R-Errors");
 	pLib->parse_table[pLib->cur_parse_entry++].variable = \
-																		&pLib->InterfaceStat.d2.R_Errors;
+		&pLib->InterfaceStat.d2.R_Errors;
 
 
 	pLib->statistic_parse_last  = pLib->cur_parse_entry - 1;
 }
 
-static void diva_trace_error (diva_strace_context_t* pLib,
-															int error, const char* file, int line) {
+static void diva_trace_error(diva_strace_context_t *pLib,
+			     int error, const char *file, int line) {
 	if (pLib->user_proc_table.error_notify_proc) {
 		(*(pLib->user_proc_table.error_notify_proc))(\
-																						pLib->user_proc_table.user_context,
-																						&pLib->instance, pLib->Adapter,
-																						error, file, line);
+			pLib->user_proc_table.user_context,
+			&pLib->instance, pLib->Adapter,
+			error, file, line);
 	}
 }
 
 /*
-	Delivery notification to user
-	*/
-static void diva_trace_notify_user (diva_strace_context_t* pLib,
-														 int Channel,
-														 int notify_subject) {
+  Delivery notification to user
+*/
+static void diva_trace_notify_user(diva_strace_context_t *pLib,
+				   int Channel,
+				   int notify_subject) {
 	if (pLib->user_proc_table.notify_proc) {
 		(*(pLib->user_proc_table.notify_proc))(pLib->user_proc_table.user_context,
-																					 &pLib->instance,
-																					 pLib->Adapter,
-																					 &pLib->lines[Channel],
-																					 notify_subject);
+						       &pLib->instance,
+						       pLib->Adapter,
+						       &pLib->lines[Channel],
+						       notify_subject);
 	}
 }
 
 /*
-	Read variable value to they destination based on the variable type
-	*/
-static int diva_trace_read_variable (diva_man_var_header_t* pVar,
-																		 void* variable) {
+  Read variable value to they destination based on the variable type
+*/
+static int diva_trace_read_variable(diva_man_var_header_t *pVar,
+				    void *variable) {
 	switch (pVar->type) {
-		case 0x03: /* MI_ASCIIZ - syting                               */
-			return (diva_strace_read_asz  (pVar, (char*)variable));
-		case 0x04: /* MI_ASCII  - string                               */
-			return (diva_strace_read_asc  (pVar, (char*)variable));
-		case 0x05: /* MI_NUMBER - counted sequence of bytes            */
-			return (diva_strace_read_ie  (pVar, (diva_trace_ie_t*)variable));
-		case 0x81: /* MI_INT    - signed integer                       */
-			return (diva_strace_read_int (pVar, (int*)variable));
-		case 0x82: /* MI_UINT   - unsigned integer                     */
-			return (diva_strace_read_uint (pVar, (dword*)variable));
-		case 0x83: /* MI_HINT   - unsigned integer, hex representetion */
-			return (diva_strace_read_uint (pVar, (dword*)variable));
-		case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
-			return (diva_strace_read_uint (pVar, (dword*)variable));
+	case 0x03: /* MI_ASCIIZ - syting                               */
+		return (diva_strace_read_asz(pVar, (char *)variable));
+	case 0x04: /* MI_ASCII  - string                               */
+		return (diva_strace_read_asc(pVar, (char *)variable));
+	case 0x05: /* MI_NUMBER - counted sequence of bytes            */
+		return (diva_strace_read_ie(pVar, (diva_trace_ie_t *)variable));
+	case 0x81: /* MI_INT    - signed integer                       */
+		return (diva_strace_read_int(pVar, (int *)variable));
+	case 0x82: /* MI_UINT   - unsigned integer                     */
+		return (diva_strace_read_uint(pVar, (dword *)variable));
+	case 0x83: /* MI_HINT   - unsigned integer, hex representetion */
+		return (diva_strace_read_uint(pVar, (dword *)variable));
+	case 0x87: /* MI_BITFLD - unsigned integer, bit representation */
+		return (diva_strace_read_uint(pVar, (dword *)variable));
 	}
 
 	/*
-		This type of variable is not handled, indicate error
-		Or one problem in management interface, or in application recodeing
-		table, or this application should handle it.
-		*/
+	  This type of variable is not handled, indicate error
+	  Or one problem in management interface, or in application recodeing
+	  table, or this application should handle it.
+	*/
 	return (-1);
 }
 
 /*
-	Read signed integer to destination
-	*/
-static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var) {
-	byte* ptr = (char*)&pVar->path_length;
+  Read signed integer to destination
+*/
+static int diva_strace_read_int(diva_man_var_header_t *pVar, int *var) {
+	byte *ptr = (char *)&pVar->path_length;
 	int value;
 
 	ptr += (pVar->path_length + 1);
 
 	switch (pVar->value_length) {
-		case 1:
-			value = *(char*)ptr;
-			break;
+	case 1:
+		value = *(char *)ptr;
+		break;
 
-		case 2:
-			value = (short)GET_WORD(ptr);
-			break;
+	case 2:
+		value = (short)GET_WORD(ptr);
+		break;
 
-		case 4:
-			value = (int)GET_DWORD(ptr);
-			break;
+	case 4:
+		value = (int)GET_DWORD(ptr);
+		break;
 
-		default:
-			return (-1);
+	default:
+		return (-1);
 	}
 
 	*var = value;
@@ -1936,32 +1936,32 @@ static int diva_strace_read_int  (diva_man_var_header_t* pVar, int* var) {
 	return (0);
 }
 
-static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var) {
-	byte* ptr = (char*)&pVar->path_length;
+static int diva_strace_read_uint(diva_man_var_header_t *pVar, dword *var) {
+	byte *ptr = (char *)&pVar->path_length;
 	dword value;
 
 	ptr += (pVar->path_length + 1);
 
 	switch (pVar->value_length) {
-		case 1:
-			value = (byte)(*ptr);
-			break;
+	case 1:
+		value = (byte)(*ptr);
+		break;
 
-		case 2:
-			value = (word)GET_WORD(ptr);
-			break;
+	case 2:
+		value = (word)GET_WORD(ptr);
+		break;
 
-		case 3:
-			value  = (dword)GET_DWORD(ptr);
-			value &= 0x00ffffff;
-			break;
+	case 3:
+		value  = (dword)GET_DWORD(ptr);
+		value &= 0x00ffffff;
+		break;
 
-		case 4:
-			value = (dword)GET_DWORD(ptr);
-			break;
+	case 4:
+		value = (dword)GET_DWORD(ptr);
+		break;
 
-		default:
-			return (-1);
+	default:
+		return (-1);
 	}
 
 	*var = value;
@@ -1970,54 +1970,54 @@ static int diva_strace_read_uint (diva_man_var_header_t* pVar, dword* var) {
 }
 
 /*
-	Read zero terminated ASCII string
-	*/
-static int diva_strace_read_asz  (diva_man_var_header_t* pVar, char* var) {
-	char* ptr = (char*)&pVar->path_length;
+  Read zero terminated ASCII string
+*/
+static int diva_strace_read_asz(diva_man_var_header_t *pVar, char *var) {
+	char *ptr = (char *)&pVar->path_length;
 	int length;
 
 	ptr += (pVar->path_length + 1);
 
 	if (!(length = pVar->value_length)) {
-		length = strlen (ptr);
+		length = strlen(ptr);
 	}
-	memcpy (var, ptr, length);
+	memcpy(var, ptr, length);
 	var[length] = 0;
 
 	return (0);
 }
 
 /*
-	Read counted (with leading length byte) ASCII string
-	*/
-static int diva_strace_read_asc  (diva_man_var_header_t* pVar, char* var) {
-	char* ptr = (char*)&pVar->path_length;
+  Read counted (with leading length byte) ASCII string
+*/
+static int diva_strace_read_asc(diva_man_var_header_t *pVar, char *var) {
+	char *ptr = (char *)&pVar->path_length;
 
 	ptr += (pVar->path_length + 1);
-	memcpy (var, ptr+1, *ptr);
+	memcpy(var, ptr + 1, *ptr);
 	var[(int)*ptr] = 0;
 
 	return (0);
 }
 
 /*
-		Read one information element - i.e. one string of byte values with
-		one length byte in front
-	*/
-static int  diva_strace_read_ie  (diva_man_var_header_t* pVar,
-																	diva_trace_ie_t* var) {
-	char* ptr = (char*)&pVar->path_length;
+  Read one information element - i.e. one string of byte values with
+  one length byte in front
+*/
+static int diva_strace_read_ie(diva_man_var_header_t *pVar,
+			       diva_trace_ie_t *var) {
+	char *ptr = (char *)&pVar->path_length;
 
 	ptr += (pVar->path_length + 1);
 
 	var->length = *ptr;
-	memcpy (&var->data[0], ptr+1, *ptr);
+	memcpy(&var->data[0], ptr + 1, *ptr);
 
 	return (0);
 }
 
-static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceSetAudioTap(void *hLib, int Channel, int on) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
 	if ((Channel < 1) || (Channel > pLib->Channels)) {
 		return (-1);
@@ -2030,21 +2030,21 @@ static int SuperTraceSetAudioTap  (void* hLib, int Channel, int on) {
 		pLib->audio_tap_mask &= ~(1L << Channel);
 	}
 
-  /*
-    EYE patterns have TM_M_DATA set as additional
-    condition
-    */
-  if (pLib->audio_tap_mask) {
-    pLib->trace_event_mask |= TM_M_DATA;
-  } else {
-    pLib->trace_event_mask &= ~TM_M_DATA;
-  }
+	/*
+	  EYE patterns have TM_M_DATA set as additional
+	  condition
+	*/
+	if (pLib->audio_tap_mask) {
+		pLib->trace_event_mask |= TM_M_DATA;
+	} else {
+		pLib->trace_event_mask &= ~TM_M_DATA;
+	}
 
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceSetBChannel  (void* hLib, int Channel, int on) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceSetBChannel(void *hLib, int Channel, int on) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
 	if ((Channel < 1) || (Channel > pLib->Channels)) {
 		return (-1);
@@ -2057,11 +2057,11 @@ static int SuperTraceSetBChannel  (void* hLib, int Channel, int on) {
 		pLib->bchannel_trace_mask &= ~(1L << Channel);
 	}
 
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceSetDChannel  (void* hLib, int on) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceSetDChannel(void *hLib, int on) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
 	if (on) {
 		pLib->trace_event_mask |= (TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
@@ -2069,11 +2069,11 @@ static int SuperTraceSetDChannel  (void* hLib, int on) {
 		pLib->trace_event_mask &= ~(TM_D_CHAN | TM_C_COMM | TM_DL_ERR | TM_LAYER1);
 	}
 
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceSetInfo (void* hLib, int on) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceSetInfo(void *hLib, int on) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
 	if (on) {
 		pLib->trace_event_mask |= TM_STRING;
@@ -2081,11 +2081,11 @@ static int SuperTraceSetInfo (void* hLib, int on) {
 		pLib->trace_event_mask &= ~TM_STRING;
 	}
 
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceClearCall (void* hLib, int Channel) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceClearCall(void *hLib, int Channel) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 
 	if ((Channel < 1) || (Channel > pLib->Channels)) {
 		return (-1);
@@ -2094,102 +2094,101 @@ static int SuperTraceClearCall (void* hLib, int Channel) {
 
 	pLib->clear_call_command |= (1L << Channel);
 
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
 /*
-	Parse and update cumulative statistice
-	*/
-static int diva_ifc_statistics (diva_strace_context_t* pLib,
-																diva_man_var_header_t* pVar) {
-	diva_man_var_header_t* cur;
+  Parse and update cumulative statistice
+*/
+static int diva_ifc_statistics(diva_strace_context_t *pLib,
+			       diva_man_var_header_t *pVar) {
+	diva_man_var_header_t *cur;
 	int i, one_updated = 0, mdm_updated = 0, fax_updated = 0;
 
 	for (i  = pLib->statistic_parse_first; i <= pLib->statistic_parse_last; i++) {
-		if ((cur = find_var (pVar, pLib->parse_table[i].path))) {
-			if (diva_trace_read_variable (cur, pLib->parse_table[i].variable)) {
-				diva_trace_error (pLib, -3 , __FILE__, __LINE__);
+		if ((cur = find_var(pVar, pLib->parse_table[i].path))) {
+			if (diva_trace_read_variable(cur, pLib->parse_table[i].variable)) {
+				diva_trace_error(pLib, -3 , __FILE__, __LINE__);
 				return (-1);
 			}
 			one_updated = 1;
-      if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
-        mdm_updated = 1;
-      }
-      if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
-        fax_updated = 1;
-      }
+			if ((i >= pLib->mdm_statistic_parse_first) && (i <= pLib->mdm_statistic_parse_last)) {
+				mdm_updated = 1;
+			}
+			if ((i >= pLib->fax_statistic_parse_first) && (i <= pLib->fax_statistic_parse_last)) {
+				fax_updated = 1;
+			}
 		}
 	}
 
 	/*
-		We do not use first event to notify user - this is the event that is
-		generated as result of EVENT ON operation and is used only to initialize
-		internal variables of application
-		*/
-  if (mdm_updated) {
-		diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
-  } else if (fax_updated) {
-		diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
-  } else if (one_updated) {
-		diva_trace_notify_user (pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
+	  We do not use first event to notify user - this is the event that is
+	  generated as result of EVENT ON operation and is used only to initialize
+	  internal variables of application
+	*/
+	if (mdm_updated) {
+		diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_MDM_STAT_CHANGE);
+	} else if (fax_updated) {
+		diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_FAX_STAT_CHANGE);
+	} else if (one_updated) {
+		diva_trace_notify_user(pLib, 0, DIVA_SUPER_TRACE_NOTIFY_STAT_CHANGE);
 	}
 
 	return (one_updated ? 0 : -1);
 }
 
-static int SuperTraceGetOutgoingCallStatistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetOutgoingCallStatistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->outgoing_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetIncomingCallStatistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetIncomingCallStatistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->incoming_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetModemStatistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetModemStatistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->modem_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetFaxStatistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetFaxStatistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->fax_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetBLayer1Statistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetBLayer1Statistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->b1_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetBLayer2Statistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetBLayer2Statistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->b2_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetDLayer1Statistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetDLayer1Statistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->d1_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-static int SuperTraceGetDLayer2Statistics (void* hLib) {
-	diva_strace_context_t* pLib = (diva_strace_context_t*)hLib;
+static int SuperTraceGetDLayer2Statistics(void *hLib) {
+	diva_strace_context_t *pLib = (diva_strace_context_t *)hLib;
 	pLib->d2_ifc_stats = 1;
-	return (ScheduleNextTraceRequest (pLib));
+	return (ScheduleNextTraceRequest(pLib));
 }
 
-dword DivaSTraceGetMemotyRequirement (int channels) {
-  dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
-												 STAT_PARSE_ENTRIES + \
-												 LINE_PARSE_ENTRIES + 1) * channels;
-  return (sizeof(diva_strace_context_t) + \
-          (parse_entries * sizeof(diva_strace_path2action_t)));
+dword DivaSTraceGetMemotyRequirement(int channels) {
+	dword parse_entries = (MODEM_PARSE_ENTRIES + FAX_PARSE_ENTRIES + \
+			       STAT_PARSE_ENTRIES + \
+			       LINE_PARSE_ENTRIES + 1) * channels;
+	return (sizeof(diva_strace_context_t) + \
+		(parse_entries * sizeof(diva_strace_path2action_t)));
 }
-
diff --git a/drivers/isdn/hardware/eicon/maintidi.h b/drivers/isdn/hardware/eicon/maintidi.h
index 4f06294..2b46147 100644
--- a/drivers/isdn/hardware/eicon/maintidi.h
+++ b/drivers/isdn/hardware/eicon/maintidi.h
@@ -1,52 +1,52 @@
 /*
  *
-  Copyright (c) Eicon Networks, 2000.
+ Copyright (c) Eicon Networks, 2000.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    1.9
+ Eicon File Revision :    1.9
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_EICON_TRACE_IDI_IFC_H__
 #define __DIVA_EICON_TRACE_IDI_IFC_H__
 
-void* SuperTraceOpenAdapter   (int AdapterNumber);
-int   SuperTraceCloseAdapter  (void* AdapterHandle);
-int   SuperTraceWrite         (void* AdapterHandle,
-                               const void* data, int length);
-int   SuperTraceReadRequest   (void* AdapterHandle,const char* name,byte* data);
-int   SuperTraceGetNumberOfChannels (void* AdapterHandle);
-int   SuperTraceASSIGN        (void* AdapterHandle, byte* data);
-int   SuperTraceREMOVE        (void* AdapterHandle);
-int   SuperTraceTraceOnRequest(void* hAdapter, const char* name, byte* data);
-int   SuperTraceWriteVar (void* AdapterHandle,
-												byte* data,
-										 		const char* name,
-										 		void* var,
-										 		byte type,
-										 		byte var_length);
-int   SuperTraceExecuteRequest (void* AdapterHandle,
-																const char* name,
-																byte* data);
+void *SuperTraceOpenAdapter(int AdapterNumber);
+int SuperTraceCloseAdapter(void *AdapterHandle);
+int SuperTraceWrite(void *AdapterHandle,
+		    const void *data, int length);
+int SuperTraceReadRequest(void *AdapterHandle, const char *name, byte *data);
+int SuperTraceGetNumberOfChannels(void *AdapterHandle);
+int SuperTraceASSIGN(void *AdapterHandle, byte *data);
+int SuperTraceREMOVE(void *AdapterHandle);
+int SuperTraceTraceOnRequest(void *hAdapter, const char *name, byte *data);
+int SuperTraceWriteVar(void *AdapterHandle,
+		       byte *data,
+		       const char *name,
+		       void *var,
+		       byte type,
+		       byte var_length);
+int SuperTraceExecuteRequest(void *AdapterHandle,
+			     const char *name,
+			     byte *data);
 
 typedef struct _diva_strace_path2action {
-	char               path[64]; /* Full path to variable            */
-	void*							 variable; /* Variable that will receive value */
+	char path[64]; /* Full path to variable            */
+	void *variable; /* Variable that will receive value */
 } diva_strace_path2action_t;
 
 #define DIVA_MAX_MANAGEMENT_TRANSFER_SIZE 4096
@@ -54,27 +54,27 @@ typedef struct _diva_strace_path2action {
 typedef struct _diva_strace_context {
 	diva_strace_library_interface_t	instance;
 
-	int   Adapter;
-	void* hAdapter;
+	int Adapter;
+	void *hAdapter;
 
 	int Channels;
-	int	req_busy;
+	int req_busy;
 
-  ENTITY   e;
-  IDI_CALL request;
-  BUFFERS  XData;
-  BUFFERS  RData;
+	ENTITY e;
+	IDI_CALL request;
+	BUFFERS XData;
+	BUFFERS RData;
 	byte buffer[DIVA_MAX_MANAGEMENT_TRANSFER_SIZE + 1];
-  int removal_state;
-  int general_b_ch_event;
-  int general_fax_event;
-  int general_mdm_event;
+	int removal_state;
+	int general_b_ch_event;
+	int general_fax_event;
+	int general_mdm_event;
 
-	byte	rc_ok;
+	byte rc_ok;
 
 	/*
-		Initialization request state machine
-		*/
+	  Initialization request state machine
+	*/
 	int ChannelsTraceActive;
 	int ModemTraceActive;
 	int FaxTraceActive;
@@ -93,8 +93,8 @@ typedef struct _diva_strace_context {
 	int l2_trace;
 
 	/*
-		Trace\Event Enable
-		*/
+	  Trace\Event Enable
+	*/
 	word trace_event_mask;
 	word current_trace_event_mask;
 
@@ -112,7 +112,7 @@ typedef struct _diva_strace_context {
 
 	int	parse_entries;
 	int	cur_parse_entry;
-	diva_strace_path2action_t* parse_table;
+	diva_strace_path2action_t *parse_table;
 
 	diva_trace_library_user_interface_t user_proc_table;
 
@@ -169,4 +169,3 @@ typedef struct _diva_man_var_header {
 } diva_man_var_header_t;
 
 #endif
-
diff --git a/drivers/isdn/hardware/eicon/man_defs.h b/drivers/isdn/hardware/eicon/man_defs.h
index cb4ef4c..249c471 100644
--- a/drivers/isdn/hardware/eicon/man_defs.h
+++ b/drivers/isdn/hardware/eicon/man_defs.h
@@ -1,25 +1,25 @@
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    1.9
+ Eicon File Revision :    1.9
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 /* Definitions for use with the Management Information Element      */
@@ -104,9 +104,9 @@
 typedef struct mi_xlog_hdr_s MI_XLOG_HDR;
 struct mi_xlog_hdr_s
 {
-  unsigned long  time;   /* Timestamp in msec units                 */
-  unsigned short size;   /* Size of data that follows               */
-  unsigned short code;   /* code of trace event                     */
+	unsigned long  time;   /* Timestamp in msec units                 */
+	unsigned short size;   /* Size of data that follows               */
+	unsigned short code;   /* code of trace event                     */
 };                       /* unspecified data follows this header    */
 
 /*------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/mdm_msg.h b/drivers/isdn/hardware/eicon/mdm_msg.h
index 7a737e1..0e6b2e0 100644
--- a/drivers/isdn/hardware/eicon/mdm_msg.h
+++ b/drivers/isdn/hardware/eicon/mdm_msg.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __EICON_MDM_MSG_H__
@@ -30,18 +30,18 @@
 #define DSP_UDATA_INDICATION_CTS_OFF  0x03
 #define DSP_UDATA_INDICATION_CTS_ON  0x04
 /* =====================================================================
-DCD_OFF Message:
-  <word> time of DCD off (sampled from counter at 8kHz)
-DCD_ON Message:
-  <word> time of DCD on (sampled from counter at 8kHz)
-  <byte> connected norm
-  <word> connected options
-  <dword> connected speed (bit/s, max of tx and rx speed)
-  <word> roundtrip delay (ms)
-  <dword> connected speed tx (bit/s)
-  <dword> connected speed rx (bit/s)
-  Size of this message == 19 bytes, but we will receive only 11
-  ===================================================================== */
+   DCD_OFF Message:
+   <word> time of DCD off (sampled from counter at 8kHz)
+   DCD_ON Message:
+   <word> time of DCD on (sampled from counter at 8kHz)
+   <byte> connected norm
+   <word> connected options
+   <dword> connected speed (bit/s, max of tx and rx speed)
+   <word> roundtrip delay (ms)
+   <dword> connected speed tx (bit/s)
+   <dword> connected speed rx (bit/s)
+   Size of this message == 19 bytes, but we will receive only 11
+   ===================================================================== */
 #define DSP_CONNECTED_NORM_UNSPECIFIED      0
 #define DSP_CONNECTED_NORM_V21              1
 #define DSP_CONNECTED_NORM_V23              2
@@ -129,14 +129,14 @@ DCD_ON Message:
 #define DSP_CONNECTED_OPTION_MASK_COMPRESSION    0x0320
 #define DSP_UDATA_INDICATION_DISCONNECT         5
 /*
-returns:
+  returns:
   <byte> cause
 */
 /* ==========================================================
-    DLC: B2 modem configuration
+   DLC: B2 modem configuration
    ========================================================== */
 /*
-Fields in assign DLC information element for modem protocol V.42/MNP:
+  Fields in assign DLC information element for modem protocol V.42/MNP:
   <byte> length of information element
   <word> information field length
   <byte> address A       (not used, default 3)
@@ -172,10 +172,10 @@ Fields in assign DLC information element for modem protocol V.42/MNP:
 #define DLC_MODEMPROT_APPL_EARLY_CONNECT     0x01
 #define DLC_MODEMPROT_APPL_PASS_INDICATIONS  0x02
 /* ==========================================================
-    CAI parameters used for the modem L1 configuration
+   CAI parameters used for the modem L1 configuration
    ========================================================== */
 /*
-Fields in assign CAI information element:
+  Fields in assign CAI information element:
   <byte> length of information element
   <byte> info field and B-channel hardware
   <byte> rate adaptation bit rate
@@ -311,21 +311,21 @@ Fields in assign CAI information element:
 #define DSP_CAI_MODEM_SPEAKER_VOLUME_MAX   0x0c
 #define DSP_CAI_MODEM_SPEAKER_VOLUME_MASK  0x0c
 /* ==========================================================
-    DCD/CTS State
+   DCD/CTS State
    ========================================================== */
 #define MDM_WANT_CONNECT_B3_ACTIVE_I  0x01
 #define MDM_NCPI_VALID                0x02
 #define MDM_NCPI_CTS_ON_RECEIVED      0x04
 #define MDM_NCPI_DCD_ON_RECEIVED      0x08
 /* ==========================================================
-    CAPI NCPI Constants
+   CAPI NCPI Constants
    ========================================================== */
 #define MDM_NCPI_ECM_V42              0x0001
 #define MDM_NCPI_ECM_MNP              0x0002
 #define MDM_NCPI_TRANSPARENT          0x0004
 #define MDM_NCPI_COMPRESSED           0x0010
 /* ==========================================================
-    CAPI B2 Config Constants
+   CAPI B2 Config Constants
    ========================================================== */
 #define MDM_B2_DISABLE_V42bis         0x0001
 #define MDM_B2_DISABLE_MNP            0x0002
@@ -333,7 +333,7 @@ Fields in assign CAI information element:
 #define MDM_B2_DISABLE_V42            0x0008
 #define MDM_B2_DISABLE_COMP           0x0010
 /* ==========================================================
-    CAPI B1 Config Constants
+   CAPI B1 Config Constants
    ========================================================== */
 #define MDM_CAPI_DISABLE_RETRAIN      0x0001
 #define MDM_CAPI_DISABLE_RING_TONE    0x0002
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index a339598..a82e542 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1,25 +1,25 @@
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 
@@ -64,178 +64,178 @@ static dword diva_xdi_extended_features = 0;
 /*
   CAPI can request to process all return codes self only if:
   protocol code supports this && xdi supports this
- */
-#define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__)   (((__a__)->manufacturer_features&MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)&&    ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) &&     (diva_xdi_extended_features   & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL))
+*/
+#define DIVA_CAPI_SUPPORTS_NO_CANCEL(__a__)   (((__a__)->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL) && ((__a__)->manufacturer_features & MANUFACTURER_FEATURE_OK_FC_LABEL) && (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_NO_CANCEL))
 
 /*------------------------------------------------------------------*/
 /* local function prototypes                                        */
 /*------------------------------------------------------------------*/
 
-static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci);
-static void set_group_ind_mask (PLCI   *plci);
-static void clear_group_ind_mask_bit (PLCI   *plci, word b);
-static byte test_group_ind_mask_bit (PLCI   *plci, word b);
-void AutomaticLaw(DIVA_CAPI_ADAPTER   *);
+static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci);
+static void set_group_ind_mask(PLCI *plci);
+static void clear_group_ind_mask_bit(PLCI *plci, word b);
+static byte test_group_ind_mask_bit(PLCI *plci, word b);
+void AutomaticLaw(DIVA_CAPI_ADAPTER *);
 word CapiRelease(word);
 word CapiRegister(word);
-word api_put(APPL   *, CAPI_MSG   *);
-static word api_parse(byte   *, word, byte *, API_PARSE *);
-static void api_save_msg(API_PARSE   *in, byte *format, API_SAVE   *out);
-static void api_load_msg(API_SAVE   *in, API_PARSE   *out);
+word api_put(APPL *, CAPI_MSG *);
+static word api_parse(byte *, word, byte *, API_PARSE *);
+static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out);
+static void api_load_msg(API_SAVE *in, API_PARSE *out);
 
 word api_remove_start(void);
 void api_remove_complete(void);
 
-static void plci_remove(PLCI   *);
-static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER  * a);
-static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER  *, IDI_SYNC_REQ  *);
-
-void   callback(ENTITY   *);
-
-static void control_rc(PLCI   *, byte, byte, byte, byte, byte);
-static void data_rc(PLCI   *, byte);
-static void data_ack(PLCI   *, byte);
-static void sig_ind(PLCI   *);
-static void SendInfo(PLCI   *, dword, byte   * *, byte);
-static void SendSetupInfo(APPL   *, PLCI   *, dword, byte   * *, byte);
-static void SendSSExtInd(APPL   *, PLCI   * plci, dword Id, byte   * * parms);
-
-static void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms);
-
-static void nl_ind(PLCI   *);
-
-static byte connect_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte connect_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte connect_a_res(dword,word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte listen_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte info_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte info_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte alert_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte facility_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte facility_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
-
-static word get_plci(DIVA_CAPI_ADAPTER   *);
-static void add_p(PLCI   *, byte, byte   *);
-static void add_s(PLCI   * plci, byte code, API_PARSE * p);
-static void add_ss(PLCI   * plci, byte code, API_PARSE * p);
-static void add_ie(PLCI   * plci, byte code, byte   * p, word p_length);
-static void add_d(PLCI   *, word, byte   *);
-static void add_ai(PLCI   *, API_PARSE *);
-static word add_b1(PLCI   *, API_PARSE *, word, word);
-static word add_b23(PLCI   *, API_PARSE *);
-static word add_modem_b23 (PLCI  * plci, API_PARSE* bp_parms);
-static void sig_req(PLCI   *, byte, byte);
-static void nl_req_ncci(PLCI   *, byte, byte);
-static void send_req(PLCI   *);
-static void send_data(PLCI   *);
-static word plci_remove_check(PLCI   *);
-static void listen_check(DIVA_CAPI_ADAPTER   *);
-static byte AddInfo(byte   **, byte   **, byte   *, byte *);
+static void plci_remove(PLCI *);
+static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a);
+static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *, IDI_SYNC_REQ *);
+
+void callback(ENTITY *);
+
+static void control_rc(PLCI *, byte, byte, byte, byte, byte);
+static void data_rc(PLCI *, byte);
+static void data_ack(PLCI *, byte);
+static void sig_ind(PLCI *);
+static void SendInfo(PLCI *, dword, byte **, byte);
+static void SendSetupInfo(APPL *, PLCI *, dword, byte **, byte);
+static void SendSSExtInd(APPL *, PLCI *plci, dword Id, byte **parms);
+
+static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms);
+
+static void nl_ind(PLCI *);
+
+static byte connect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte connect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte connect_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte disconnect_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte disconnect_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte listen_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte info_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte info_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte alert_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte facility_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte facility_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte connect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte connect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte connect_b3_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte disconnect_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte disconnect_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte data_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte data_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte reset_b3_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte reset_b3_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte connect_b3_t90_a_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte select_b_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte manufacturer_req(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+static byte manufacturer_res(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
+
+static word get_plci(DIVA_CAPI_ADAPTER *);
+static void add_p(PLCI *, byte, byte *);
+static void add_s(PLCI *plci, byte code, API_PARSE *p);
+static void add_ss(PLCI *plci, byte code, API_PARSE *p);
+static void add_ie(PLCI *plci, byte code, byte *p, word p_length);
+static void add_d(PLCI *, word, byte *);
+static void add_ai(PLCI *, API_PARSE *);
+static word add_b1(PLCI *, API_PARSE *, word, word);
+static word add_b23(PLCI *, API_PARSE *);
+static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms);
+static void sig_req(PLCI *, byte, byte);
+static void nl_req_ncci(PLCI *, byte, byte);
+static void send_req(PLCI *);
+static void send_data(PLCI *);
+static word plci_remove_check(PLCI *);
+static void listen_check(DIVA_CAPI_ADAPTER *);
+static byte AddInfo(byte **, byte **, byte *, byte *);
 static byte getChannel(API_PARSE *);
-static void IndParse(PLCI   *, word *, byte   **, byte);
-static byte ie_compare(byte   *, byte *);
-static word find_cip(DIVA_CAPI_ADAPTER   *, byte   *, byte   *);
-static word CPN_filter_ok(byte   *cpn,DIVA_CAPI_ADAPTER   *,word);
+static void IndParse(PLCI *, word *, byte **, byte);
+static byte ie_compare(byte *, byte *);
+static word find_cip(DIVA_CAPI_ADAPTER *, byte *, byte *);
+static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *, word);
 
 /*
   XON protocol helpers
-  */
-static void channel_flow_control_remove (PLCI   * plci);
-static void channel_x_off (PLCI   * plci, byte ch, byte flag);
-static void channel_x_on (PLCI   * plci, byte ch);
-static void channel_request_xon (PLCI   * plci, byte ch);
-static void channel_xmit_xon (PLCI   * plci);
-static int channel_can_xon (PLCI   * plci, byte ch);
-static void channel_xmit_extended_xon (PLCI   * plci);
-
-static byte SendMultiIE(PLCI   * plci, dword Id, byte   * * parms, byte ie_type, dword info_mask, byte setupParse);
-static word AdvCodecSupport(DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, byte);
-static void CodecIdCheck(DIVA_CAPI_ADAPTER   *, PLCI   *);
-static void SetVoiceChannel(PLCI   *, byte   *, DIVA_CAPI_ADAPTER   * );
-static void VoiceChannelOff(PLCI   *plci);
-static void adv_voice_write_coefs (PLCI   *plci, word write_command);
-static void adv_voice_clear_config (PLCI   *plci);
-
-static word get_b1_facilities (PLCI   * plci, byte b1_resource);
-static byte add_b1_facilities (PLCI   * plci, byte b1_resource, word b1_facilities);
-static void adjust_b1_facilities (PLCI   *plci, byte new_b1_resource, word new_b1_facilities);
-static word adjust_b_process (dword Id, PLCI   *plci, byte Rc);
-static void adjust_b1_resource (dword Id, PLCI   *plci, API_SAVE   *bp_msg, word b1_facilities, word internal_command);
-static void adjust_b_restore (dword Id, PLCI   *plci, byte Rc);
-static void reset_b3_command (dword Id, PLCI   *plci, byte Rc);
-static void select_b_command (dword Id, PLCI   *plci, byte Rc);
-static void fax_connect_ack_command (dword Id, PLCI   *plci, byte Rc);
-static void fax_edata_ack_command (dword Id, PLCI   *plci, byte Rc);
-static void fax_connect_info_command (dword Id, PLCI   *plci, byte Rc);
-static void fax_adjust_b23_command (dword Id, PLCI   *plci, byte Rc);
-static void fax_disconnect_command (dword Id, PLCI   *plci, byte Rc);
-static void hold_save_command (dword Id, PLCI   *plci, byte Rc);
-static void retrieve_restore_command (dword Id, PLCI   *plci, byte Rc);
-static void init_b1_config (PLCI   *plci);
-static void clear_b1_config (PLCI   *plci);
-
-static void dtmf_command (dword Id, PLCI   *plci, byte Rc);
-static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg);
-static void dtmf_confirmation (dword Id, PLCI   *plci);
-static void dtmf_indication (dword Id, PLCI   *plci, byte   *msg, word length);
-static void dtmf_parameter_write (PLCI   *plci);
-
-
-static void mixer_set_bchannel_id_esc (PLCI   *plci, byte bchannel_id);
-static void mixer_set_bchannel_id (PLCI   *plci, byte   *chi);
-static void mixer_clear_config (PLCI   *plci);
-static void mixer_notify_update (PLCI   *plci, byte others);
-static void mixer_command (dword Id, PLCI   *plci, byte Rc);
-static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg);
-static void mixer_indication_coefs_set (dword Id, PLCI   *plci);
-static void mixer_indication_xconnect_from (dword Id, PLCI   *plci, byte   *msg, word length);
-static void mixer_indication_xconnect_to (dword Id, PLCI   *plci, byte   *msg, word length);
-static void mixer_remove (PLCI   *plci);
-
-
-static void ec_command (dword Id, PLCI   *plci, byte Rc);
-static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg);
-static void ec_indication (dword Id, PLCI   *plci, byte   *msg, word length);
-
-
-static void rtp_connect_b3_req_command (dword Id, PLCI   *plci, byte Rc);
-static void rtp_connect_b3_res_command (dword Id, PLCI   *plci, byte Rc);
-
-
-static int  diva_get_dma_descriptor  (PLCI   *plci, dword   *dma_magic);
-static void diva_free_dma_descriptor (PLCI   *plci, int nr);
+*/
+static void channel_flow_control_remove(PLCI *plci);
+static void channel_x_off(PLCI *plci, byte ch, byte flag);
+static void channel_x_on(PLCI *plci, byte ch);
+static void channel_request_xon(PLCI *plci, byte ch);
+static void channel_xmit_xon(PLCI *plci);
+static int channel_can_xon(PLCI *plci, byte ch);
+static void channel_xmit_extended_xon(PLCI *plci);
+
+static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type, dword info_mask, byte setupParse);
+static word AdvCodecSupport(DIVA_CAPI_ADAPTER *, PLCI *, APPL *, byte);
+static void CodecIdCheck(DIVA_CAPI_ADAPTER *, PLCI *);
+static void SetVoiceChannel(PLCI *, byte *, DIVA_CAPI_ADAPTER *);
+static void VoiceChannelOff(PLCI *plci);
+static void adv_voice_write_coefs(PLCI *plci, word write_command);
+static void adv_voice_clear_config(PLCI *plci);
+
+static word get_b1_facilities(PLCI *plci, byte b1_resource);
+static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities);
+static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities);
+static word adjust_b_process(dword Id, PLCI *plci, byte Rc);
+static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE *bp_msg, word b1_facilities, word internal_command);
+static void adjust_b_restore(dword Id, PLCI *plci, byte Rc);
+static void reset_b3_command(dword Id, PLCI *plci, byte Rc);
+static void select_b_command(dword Id, PLCI *plci, byte Rc);
+static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc);
+static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc);
+static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc);
+static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc);
+static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc);
+static void hold_save_command(dword Id, PLCI *plci, byte Rc);
+static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc);
+static void init_b1_config(PLCI *plci);
+static void clear_b1_config(PLCI *plci);
+
+static void dtmf_command(dword Id, PLCI *plci, byte Rc);
+static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
+static void dtmf_confirmation(dword Id, PLCI *plci);
+static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length);
+static void dtmf_parameter_write(PLCI *plci);
+
+
+static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id);
+static void mixer_set_bchannel_id(PLCI *plci, byte *chi);
+static void mixer_clear_config(PLCI *plci);
+static void mixer_notify_update(PLCI *plci, byte others);
+static void mixer_command(dword Id, PLCI *plci, byte Rc);
+static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
+static void mixer_indication_coefs_set(dword Id, PLCI *plci);
+static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length);
+static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length);
+static void mixer_remove(PLCI *plci);
+
+
+static void ec_command(dword Id, PLCI *plci, byte Rc);
+static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, API_PARSE *msg);
+static void ec_indication(dword Id, PLCI *plci, byte *msg, word length);
+
+
+static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc);
+static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc);
+
+
+static int diva_get_dma_descriptor(PLCI *plci, dword *dma_magic);
+static void diva_free_dma_descriptor(PLCI *plci, int nr);
 
 /*------------------------------------------------------------------*/
 /* external function prototypes                                     */
 /*------------------------------------------------------------------*/
 
-extern byte MapController (byte);
-extern byte UnMapController (byte);
-#define MapId(Id) (((Id) & 0xffffff00L) | MapController ((byte)(Id)))
-#define UnMapId(Id) (((Id) & 0xffffff00L) | UnMapController ((byte)(Id)))
+extern byte MapController(byte);
+extern byte UnMapController(byte);
+#define MapId(Id)(((Id) & 0xffffff00L) | MapController((byte)(Id)))
+#define UnMapId(Id)(((Id) & 0xffffff00L) | UnMapController((byte)(Id)))
 
-void   sendf(APPL   *, word, dword, word, byte *, ...);
-void   * TransmitBufferSet(APPL   * appl, dword ref);
-void   * TransmitBufferGet(APPL   * appl, void   * p);
-void TransmitBufferFree(APPL   * appl, void   * p);
-void   * ReceiveBufferGet(APPL   * appl, int Num);
+void sendf(APPL *, word, dword, word, byte *, ...);
+void *TransmitBufferSet(APPL *appl, dword ref);
+void *TransmitBufferGet(APPL *appl, void *p);
+void TransmitBufferFree(APPL *appl, void *p);
+void *ReceiveBufferGet(APPL *appl, int Num);
 
-int fax_head_line_time (char *buffer);
+int fax_head_line_time(char *buffer);
 
 
 /*------------------------------------------------------------------*/
@@ -243,8 +243,8 @@ int fax_head_line_time (char *buffer);
 /*------------------------------------------------------------------*/
 extern byte max_adapter;
 extern byte max_appl;
-extern DIVA_CAPI_ADAPTER   * adapter;
-extern APPL   * application;
+extern DIVA_CAPI_ADAPTER *adapter;
+extern APPL *application;
 
 
 
@@ -257,102 +257,102 @@ static PLCI dummy_plci;
 
 
 static struct _ftable {
-  word command;
-  byte * format;
-  byte (* function)(dword, word, DIVA_CAPI_ADAPTER   *, PLCI   *, APPL   *, API_PARSE *);
+	word command;
+	byte *format;
+	byte (*function)(dword, word, DIVA_CAPI_ADAPTER *, PLCI *, APPL *, API_PARSE *);
 } ftable[] = {
-  {_DATA_B3_R,                          "dwww",         data_b3_req},
-  {_DATA_B3_I|RESPONSE,                 "w",            data_b3_res},
-  {_INFO_R,                             "ss",           info_req},
-  {_INFO_I|RESPONSE,                    "",             info_res},
-  {_CONNECT_R,                          "wsssssssss",   connect_req},
-  {_CONNECT_I|RESPONSE,                 "wsssss",       connect_res},
-  {_CONNECT_ACTIVE_I|RESPONSE,          "",             connect_a_res},
-  {_DISCONNECT_R,                       "s",            disconnect_req},
-  {_DISCONNECT_I|RESPONSE,              "",             disconnect_res},
-  {_LISTEN_R,                           "dddss",        listen_req},
-  {_ALERT_R,                            "s",            alert_req},
-  {_FACILITY_R,                         "ws",           facility_req},
-  {_FACILITY_I|RESPONSE,                "ws",           facility_res},
-  {_CONNECT_B3_R,                       "s",            connect_b3_req},
-  {_CONNECT_B3_I|RESPONSE,              "ws",           connect_b3_res},
-  {_CONNECT_B3_ACTIVE_I|RESPONSE,       "",             connect_b3_a_res},
-  {_DISCONNECT_B3_R,                    "s",            disconnect_b3_req},
-  {_DISCONNECT_B3_I|RESPONSE,           "",             disconnect_b3_res},
-  {_RESET_B3_R,                         "s",            reset_b3_req},
-  {_RESET_B3_I|RESPONSE,                "",             reset_b3_res},
-  {_CONNECT_B3_T90_ACTIVE_I|RESPONSE,   "ws",           connect_b3_t90_a_res},
-  {_CONNECT_B3_T90_ACTIVE_I|RESPONSE,   "",             connect_b3_t90_a_res},
-  {_SELECT_B_REQ,                       "s",            select_b_req},
-  {_MANUFACTURER_R,                     "dws",          manufacturer_req},
-  {_MANUFACTURER_I|RESPONSE,            "dws",          manufacturer_res},
-  {_MANUFACTURER_I|RESPONSE,            "",             manufacturer_res}
+	{_DATA_B3_R,                          "dwww",         data_b3_req},
+	{_DATA_B3_I | RESPONSE,               "w",            data_b3_res},
+	{_INFO_R,                             "ss",           info_req},
+	{_INFO_I | RESPONSE,                  "",             info_res},
+	{_CONNECT_R,                          "wsssssssss",   connect_req},
+	{_CONNECT_I | RESPONSE,               "wsssss",       connect_res},
+	{_CONNECT_ACTIVE_I | RESPONSE,        "",             connect_a_res},
+	{_DISCONNECT_R,                       "s",            disconnect_req},
+	{_DISCONNECT_I | RESPONSE,            "",             disconnect_res},
+	{_LISTEN_R,                           "dddss",        listen_req},
+	{_ALERT_R,                            "s",            alert_req},
+	{_FACILITY_R,                         "ws",           facility_req},
+	{_FACILITY_I | RESPONSE,              "ws",           facility_res},
+	{_CONNECT_B3_R,                       "s",            connect_b3_req},
+	{_CONNECT_B3_I | RESPONSE,            "ws",           connect_b3_res},
+	{_CONNECT_B3_ACTIVE_I | RESPONSE,     "",             connect_b3_a_res},
+	{_DISCONNECT_B3_R,                    "s",            disconnect_b3_req},
+	{_DISCONNECT_B3_I | RESPONSE,         "",             disconnect_b3_res},
+	{_RESET_B3_R,                         "s",            reset_b3_req},
+	{_RESET_B3_I | RESPONSE,              "",             reset_b3_res},
+	{_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "ws",           connect_b3_t90_a_res},
+	{_CONNECT_B3_T90_ACTIVE_I | RESPONSE, "",             connect_b3_t90_a_res},
+	{_SELECT_B_REQ,                       "s",            select_b_req},
+	{_MANUFACTURER_R,                     "dws",          manufacturer_req},
+	{_MANUFACTURER_I | RESPONSE,          "dws",          manufacturer_res},
+	{_MANUFACTURER_I | RESPONSE,          "",             manufacturer_res}
 };
 
-static byte * cip_bc[29][2] = {
-  { "",                     ""                     }, /* 0 */
-  { "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 1 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 2 */
-  { "\x02\x89\x90",         "\x02\x89\x90"         }, /* 3 */
-  { "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 4 */
-  { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 5 */
-  { "\x02\x98\x90",         "\x02\x98\x90"         }, /* 6 */
-  { "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */
-  { "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */
-  { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 9 */
-  { "",                     ""                     }, /* 10 */
-  { "",                     ""                     }, /* 11 */
-  { "",                     ""                     }, /* 12 */
-  { "",                     ""                     }, /* 13 */
-  { "",                     ""                     }, /* 14 */
-  { "",                     ""                     }, /* 15 */
-
-  { "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 16 */
-  { "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 17 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 18 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 19 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 20 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 21 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 22 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 23 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 24 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }, /* 25 */
-  { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 26 */
-  { "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 27 */
-  { "\x02\x88\x90",         "\x02\x88\x90"         }  /* 28 */
+static byte *cip_bc[29][2] = {
+	{ "",                     ""                     }, /* 0 */
+	{ "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 1 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 2 */
+	{ "\x02\x89\x90",         "\x02\x89\x90"         }, /* 3 */
+	{ "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 4 */
+	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 5 */
+	{ "\x02\x98\x90",         "\x02\x98\x90"         }, /* 6 */
+	{ "\x04\x88\xc0\xc6\xe6", "\x04\x88\xc0\xc6\xe6" }, /* 7 */
+	{ "\x04\x88\x90\x21\x8f", "\x04\x88\x90\x21\x8f" }, /* 8 */
+	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 9 */
+	{ "",                     ""                     }, /* 10 */
+	{ "",                     ""                     }, /* 11 */
+	{ "",                     ""                     }, /* 12 */
+	{ "",                     ""                     }, /* 13 */
+	{ "",                     ""                     }, /* 14 */
+	{ "",                     ""                     }, /* 15 */
+
+	{ "\x03\x80\x90\xa3",     "\x03\x80\x90\xa2"     }, /* 16 */
+	{ "\x03\x90\x90\xa3",     "\x03\x90\x90\xa2"     }, /* 17 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 18 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 19 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 20 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 21 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 22 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 23 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 24 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }, /* 25 */
+	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 26 */
+	{ "\x03\x91\x90\xa5",     "\x03\x91\x90\xa5"     }, /* 27 */
+	{ "\x02\x88\x90",         "\x02\x88\x90"         }  /* 28 */
 };
 
-static byte * cip_hlc[29] = {
-  "",                           /* 0 */
-  "",                           /* 1 */
-  "",                           /* 2 */
-  "",                           /* 3 */
-  "",                           /* 4 */
-  "",                           /* 5 */
-  "",                           /* 6 */
-  "",                           /* 7 */
-  "",                           /* 8 */
-  "",                           /* 9 */
-  "",                           /* 10 */
-  "",                           /* 11 */
-  "",                           /* 12 */
-  "",                           /* 13 */
-  "",                           /* 14 */
-  "",                           /* 15 */
-
-  "\x02\x91\x81",               /* 16 */
-  "\x02\x91\x84",               /* 17 */
-  "\x02\x91\xa1",               /* 18 */
-  "\x02\x91\xa4",               /* 19 */
-  "\x02\x91\xa8",               /* 20 */
-  "\x02\x91\xb1",               /* 21 */
-  "\x02\x91\xb2",               /* 22 */
-  "\x02\x91\xb5",               /* 23 */
-  "\x02\x91\xb8",               /* 24 */
-  "\x02\x91\xc1",               /* 25 */
-  "\x02\x91\x81",               /* 26 */
-  "\x03\x91\xe0\x01",           /* 27 */
-  "\x03\x91\xe0\x02"            /* 28 */
+static byte *cip_hlc[29] = {
+	"",                           /* 0 */
+	"",                           /* 1 */
+	"",                           /* 2 */
+	"",                           /* 3 */
+	"",                           /* 4 */
+	"",                           /* 5 */
+	"",                           /* 6 */
+	"",                           /* 7 */
+	"",                           /* 8 */
+	"",                           /* 9 */
+	"",                           /* 10 */
+	"",                           /* 11 */
+	"",                           /* 12 */
+	"",                           /* 13 */
+	"",                           /* 14 */
+	"",                           /* 15 */
+
+	"\x02\x91\x81",               /* 16 */
+	"\x02\x91\x84",               /* 17 */
+	"\x02\x91\xa1",               /* 18 */
+	"\x02\x91\xa4",               /* 19 */
+	"\x02\x91\xa8",               /* 20 */
+	"\x02\x91\xb1",               /* 21 */
+	"\x02\x91\xb2",               /* 22 */
+	"\x02\x91\xb5",               /* 23 */
+	"\x02\x91\xb8",               /* 24 */
+	"\x02\x91\xc1",               /* 25 */
+	"\x02\x91\x81",               /* 26 */
+	"\x03\x91\xe0\x01",           /* 27 */
+	"\x03\x91\xe0\x02"            /* 28 */
 };
 
 /*------------------------------------------------------------------*/
@@ -367,14 +367,14 @@ static byte * cip_hlc[29] = {
 static byte v120_default_header[] =
 {
 
-  0x83                          /*  Ext, BR , res, res, C2 , C1 , B  , F   */
+	0x83                          /*  Ext, BR , res, res, C2 , C1 , B  , F   */
 
 };
 
 static byte v120_break_header[] =
 {
 
-  0xc3 | V120_HEADER_BREAK_BIT  /*  Ext, BR , res, res, C2 , C1 , B  , F   */
+	0xc3 | V120_HEADER_BREAK_BIT  /*  Ext, BR , res, res, C2 , C1 , B  , F   */
 
 };
 
@@ -383,206 +383,206 @@ static byte v120_break_header[] =
 /* API_PUT function                                                 */
 /*------------------------------------------------------------------*/
 
-word api_put(APPL   * appl, CAPI_MSG   * msg)
-{
-  word i, j, k, l, n;
-  word ret;
-  byte c;
-  byte controller;
-  DIVA_CAPI_ADAPTER   * a;
-  PLCI   * plci;
-  NCCI   * ncci_ptr;
-  word ncci;
-  CAPI_MSG   *m;
-    API_PARSE msg_parms[MAX_MSG_PARMS+1];
-
-  if (msg->header.length < sizeof (msg->header) ||
-      msg->header.length > MAX_MSG_SIZE) {
-    dbug(1,dprintf("bad len"));
-    return _BAD_MSG;
-  }
-
-  controller = (byte)((msg->header.controller &0x7f)-1);
-
-  /* controller starts with 0 up to (max_adapter - 1) */
-  if ( controller >= max_adapter )
-  {
-    dbug(1,dprintf("invalid ctrl"));
-    return _BAD_MSG;
-  }
-  
-  a = &adapter[controller];
-  plci = NULL;
-  if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled)
-  {
-    dbug(1,dprintf("plci=%x",msg->header.plci));
-    plci = &a->plci[msg->header.plci-1];
-    ncci = GET_WORD(&msg->header.ncci);
-    if (plci->Id
-     && (plci->appl
-      || (plci->State == INC_CON_PENDING)
-      || (plci->State == INC_CON_ALERT)
-      || (msg->header.command == (_DISCONNECT_I|RESPONSE)))
-     && ((ncci == 0)
-      || (msg->header.command == (_DISCONNECT_B3_I|RESPONSE))
-      || ((ncci < MAX_NCCI+1) && (a->ncci_plci[ncci] == plci->Id))))
-    {
-      i = plci->msg_in_read_pos;
-      j = plci->msg_in_write_pos;
-      if (j >= i)
-      {
-        if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE)
-          i += MSG_IN_QUEUE_SIZE - j;
-        else
-          j = 0;
-      }
-      else
-      {
-
-        n = (((CAPI_MSG   *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc;
-
-        if (i > MSG_IN_QUEUE_SIZE - n)
-          i = MSG_IN_QUEUE_SIZE - n + 1;
-        i -= j;
-      }
-
-      if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc))
-
-      {
-        dbug(0,dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d",
-          msg->header.length, plci->msg_in_write_pos,
-          plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
-
-        return _QUEUE_FULL;
-      }
-      c = false;
-      if ((((byte   *) msg) < ((byte   *)(plci->msg_in_queue)))
-       || (((byte   *) msg) >= ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
-      {
-        if (plci->msg_in_write_pos != plci->msg_in_read_pos)
-          c = true;
-      }
-      if (msg->header.command == _DATA_B3_R)
-      {
-        if (msg->header.length < 20)
-        {
-          dbug(1,dprintf("DATA_B3 REQ wrong length %d", msg->header.length));
-          return _BAD_MSG;
-        }
-        ncci_ptr = &(a->ncci[ncci]);
-        n = ncci_ptr->data_pending;
-        l = ncci_ptr->data_ack_pending;
-        k = plci->msg_in_read_pos;
-        while (k != plci->msg_in_write_pos)
-        {
-          if (k == plci->msg_in_wrap_pos)
-            k = 0;
-          if ((((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R)
-           && (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->header.ncci == ncci))
-          {
-            n++;
-            if (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004)
-              l++;
-          }
-
-          k += (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[k]))->header.length +
-            MSG_IN_OVERHEAD + 3) & 0xfffc;
-
-        }
-        if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK))
-        {
-          dbug(0,dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d",
-                          ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l));
-
-          return _QUEUE_FULL;
-        }
-        if (plci->req_in || plci->internal_command)
-        {
-          if ((((byte   *) msg) >= ((byte   *)(plci->msg_in_queue)))
-           && (((byte   *) msg) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
-          {
-            dbug(0,dprintf("Q-FULL3(requeue)"));
-
-            return _QUEUE_FULL;
-          }
-          c = true;
-        }
-      }
-      else
-      {
-        if (plci->req_in || plci->internal_command)
-          c = true;
-        else
-        {
-          plci->command = msg->header.command;
-          plci->number = msg->header.number;
-        }
-      }
-      if (c)
-      {
-        dbug(1,dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d",
-          msg->header.command, plci->req_in, plci->internal_command,
-          msg->header.length, plci->msg_in_write_pos,
-          plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
-        if (j == 0)
-          plci->msg_in_wrap_pos = plci->msg_in_write_pos;
-        m = (CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[j]);
-        for (i = 0; i < msg->header.length; i++)
-          ((byte   *)(plci->msg_in_queue))[j++] = ((byte   *) msg)[i];
-        if (m->header.command == _DATA_B3_R)
-        {
-
-          m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
-
-        }
-
-        j = (j + 3) & 0xfffc;
-
-        *((APPL   *   *)(&((byte   *)(plci->msg_in_queue))[j])) = appl;
-        plci->msg_in_write_pos = j + MSG_IN_OVERHEAD;
-        return 0;
-      }
-    }
-    else
-    {
-      plci = NULL;
-    }
-  }
-  dbug(1,dprintf("com=%x",msg->header.command));
-
-  for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0;
-  for(i=0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) {
-
-    if(ftable[i].command==msg->header.command) {
-      /* break loop if the message is correct, otherwise continue scan  */
-      /* (for example: CONNECT_B3_T90_ACT_RES has two specifications)   */
-      if(!api_parse(msg->info.b,(word)(msg->header.length-12),ftable[i].format,msg_parms)) {
-        ret = 0;
-        break;
-      }
-      for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0;
-    }
-  }
-  if(ret) {
-    dbug(1,dprintf("BAD_MSG"));
-    if(plci) plci->command = 0;
-    return ret;
-  }
-
-
-  c = ftable[i].function(GET_DWORD(&msg->header.controller),
-                         msg->header.number,
-                         a,
-                         plci,
-                         appl,
-                         msg_parms);
-
-  channel_xmit_extended_xon (plci);
-
-  if(c==1) send_req(plci);
-  if(c==2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0;
-  if(plci && !plci->req_in) plci->command = 0;
-  return 0;
+word api_put(APPL *appl, CAPI_MSG *msg)
+{
+	word i, j, k, l, n;
+	word ret;
+	byte c;
+	byte controller;
+	DIVA_CAPI_ADAPTER *a;
+	PLCI *plci;
+	NCCI *ncci_ptr;
+	word ncci;
+	CAPI_MSG *m;
+	API_PARSE msg_parms[MAX_MSG_PARMS + 1];
+
+	if (msg->header.length < sizeof(msg->header) ||
+	    msg->header.length > MAX_MSG_SIZE) {
+		dbug(1, dprintf("bad len"));
+		return _BAD_MSG;
+	}
+
+	controller = (byte)((msg->header.controller & 0x7f) - 1);
+
+	/* controller starts with 0 up to (max_adapter - 1) */
+	if (controller >= max_adapter)
+	{
+		dbug(1, dprintf("invalid ctrl"));
+		return _BAD_MSG;
+	}
+
+	a = &adapter[controller];
+	plci = NULL;
+	if ((msg->header.plci != 0) && (msg->header.plci <= a->max_plci) && !a->adapter_disabled)
+	{
+		dbug(1, dprintf("plci=%x", msg->header.plci));
+		plci = &a->plci[msg->header.plci - 1];
+		ncci = GET_WORD(&msg->header.ncci);
+		if (plci->Id
+		    && (plci->appl
+			|| (plci->State == INC_CON_PENDING)
+			|| (plci->State == INC_CON_ALERT)
+			|| (msg->header.command == (_DISCONNECT_I | RESPONSE)))
+		    && ((ncci == 0)
+			|| (msg->header.command == (_DISCONNECT_B3_I | RESPONSE))
+			|| ((ncci < MAX_NCCI + 1) && (a->ncci_plci[ncci] == plci->Id))))
+		{
+			i = plci->msg_in_read_pos;
+			j = plci->msg_in_write_pos;
+			if (j >= i)
+			{
+				if (j + msg->header.length + MSG_IN_OVERHEAD <= MSG_IN_QUEUE_SIZE)
+					i += MSG_IN_QUEUE_SIZE - j;
+				else
+					j = 0;
+			}
+			else
+			{
+
+				n = (((CAPI_MSG *)(plci->msg_in_queue))->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc;
+
+				if (i > MSG_IN_QUEUE_SIZE - n)
+					i = MSG_IN_QUEUE_SIZE - n + 1;
+				i -= j;
+			}
+
+			if (i <= ((msg->header.length + MSG_IN_OVERHEAD + 3) & 0xfffc))
+
+			{
+				dbug(0, dprintf("Q-FULL1(msg) - len=%d write=%d read=%d wrap=%d free=%d",
+						msg->header.length, plci->msg_in_write_pos,
+						plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
+
+				return _QUEUE_FULL;
+			}
+			c = false;
+			if ((((byte *) msg) < ((byte *)(plci->msg_in_queue)))
+			    || (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
+			{
+				if (plci->msg_in_write_pos != plci->msg_in_read_pos)
+					c = true;
+			}
+			if (msg->header.command == _DATA_B3_R)
+			{
+				if (msg->header.length < 20)
+				{
+					dbug(1, dprintf("DATA_B3 REQ wrong length %d", msg->header.length));
+					return _BAD_MSG;
+				}
+				ncci_ptr = &(a->ncci[ncci]);
+				n = ncci_ptr->data_pending;
+				l = ncci_ptr->data_ack_pending;
+				k = plci->msg_in_read_pos;
+				while (k != plci->msg_in_write_pos)
+				{
+					if (k == plci->msg_in_wrap_pos)
+						k = 0;
+					if ((((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.command == _DATA_B3_R)
+					    && (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.ncci == ncci))
+					{
+						n++;
+						if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->info.data_b3_req.Flags & 0x0004)
+							l++;
+					}
+
+					k += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[k]))->header.length +
+					      MSG_IN_OVERHEAD + 3) & 0xfffc;
+
+				}
+				if ((n >= MAX_DATA_B3) || (l >= MAX_DATA_ACK))
+				{
+					dbug(0, dprintf("Q-FULL2(data) - pending=%d/%d ack_pending=%d/%d",
+							ncci_ptr->data_pending, n, ncci_ptr->data_ack_pending, l));
+
+					return _QUEUE_FULL;
+				}
+				if (plci->req_in || plci->internal_command)
+				{
+					if ((((byte *) msg) >= ((byte *)(plci->msg_in_queue)))
+					    && (((byte *) msg) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
+					{
+						dbug(0, dprintf("Q-FULL3(requeue)"));
+
+						return _QUEUE_FULL;
+					}
+					c = true;
+				}
+			}
+			else
+			{
+				if (plci->req_in || plci->internal_command)
+					c = true;
+				else
+				{
+					plci->command = msg->header.command;
+					plci->number = msg->header.number;
+				}
+			}
+			if (c)
+			{
+				dbug(1, dprintf("enqueue msg(0x%04x,0x%x,0x%x) - len=%d write=%d read=%d wrap=%d free=%d",
+						msg->header.command, plci->req_in, plci->internal_command,
+						msg->header.length, plci->msg_in_write_pos,
+						plci->msg_in_read_pos, plci->msg_in_wrap_pos, i));
+				if (j == 0)
+					plci->msg_in_wrap_pos = plci->msg_in_write_pos;
+				m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]);
+				for (i = 0; i < msg->header.length; i++)
+					((byte *)(plci->msg_in_queue))[j++] = ((byte *) msg)[i];
+				if (m->header.command == _DATA_B3_R)
+				{
+
+					m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet(appl, m->info.data_b3_req.Data));
+
+				}
+
+				j = (j + 3) & 0xfffc;
+
+				*((APPL **)(&((byte *)(plci->msg_in_queue))[j])) = appl;
+				plci->msg_in_write_pos = j + MSG_IN_OVERHEAD;
+				return 0;
+			}
+		}
+		else
+		{
+			plci = NULL;
+		}
+	}
+	dbug(1, dprintf("com=%x", msg->header.command));
+
+	for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0;
+	for (i = 0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) {
+
+		if (ftable[i].command == msg->header.command) {
+			/* break loop if the message is correct, otherwise continue scan  */
+			/* (for example: CONNECT_B3_T90_ACT_RES has two specifications)   */
+			if (!api_parse(msg->info.b, (word)(msg->header.length - 12), ftable[i].format, msg_parms)) {
+				ret = 0;
+				break;
+			}
+			for (j = 0; j < MAX_MSG_PARMS + 1; j++) msg_parms[j].length = 0;
+		}
+	}
+	if (ret) {
+		dbug(1, dprintf("BAD_MSG"));
+		if (plci) plci->command = 0;
+		return ret;
+	}
+
+
+	c = ftable[i].function(GET_DWORD(&msg->header.controller),
+			       msg->header.number,
+			       a,
+			       plci,
+			       appl,
+			       msg_parms);
+
+	channel_xmit_extended_xon(plci);
+
+	if (c == 1) send_req(plci);
+	if (c == 2 && plci) plci->req_in = plci->req_in_start = plci->req_out = 0;
+	if (plci && !plci->req_in) plci->command = 0;
+	return 0;
 }
 
 
@@ -592,85 +592,85 @@ word api_put(APPL   * appl, CAPI_MSG   * msg)
 
 static word api_parse(byte *msg, word length, byte *format, API_PARSE *parms)
 {
-  word i;
-  word p;
-
-  for(i=0,p=0; format[i]; i++) {
-    if(parms)
-    {
-      parms[i].info = &msg[p];
-    }
-    switch(format[i]) {
-    case 'b':
-      p +=1;
-      break;
-    case 'w':
-      p +=2;
-      break;
-    case 'd':
-      p +=4;
-      break;
-    case 's':
-      if(msg[p]==0xff) {
-        parms[i].info +=2;
-        parms[i].length = msg[p+1] + (msg[p+2]<<8);
-        p +=(parms[i].length +3);
-      }
-      else {
-        parms[i].length = msg[p];
-        p +=(parms[i].length +1);
-      }
-      break;
-    }
-
-    if(p>length) return true;
-  }
-  if(parms) parms[i].info = NULL;
-  return false;
+	word i;
+	word p;
+
+	for (i = 0, p = 0; format[i]; i++) {
+		if (parms)
+		{
+			parms[i].info = &msg[p];
+		}
+		switch (format[i]) {
+		case 'b':
+			p += 1;
+			break;
+		case 'w':
+			p += 2;
+			break;
+		case 'd':
+			p += 4;
+			break;
+		case 's':
+			if (msg[p] == 0xff) {
+				parms[i].info += 2;
+				parms[i].length = msg[p + 1] + (msg[p + 2] << 8);
+				p += (parms[i].length + 3);
+			}
+			else {
+				parms[i].length = msg[p];
+				p += (parms[i].length + 1);
+			}
+			break;
+		}
+
+		if (p > length) return true;
+	}
+	if (parms) parms[i].info = NULL;
+	return false;
 }
 
 static void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out)
 {
-  word i, j, n = 0;
-  byte   *p;
-
-  p = out->info;
-  for (i = 0; format[i] != '\0'; i++)
-  {
-    out->parms[i].info = p;
-    out->parms[i].length = in[i].length;
-    switch (format[i])
-    {
-    case 'b':
-      n = 1;
-      break;
-    case 'w':
-      n = 2;
-      break;
-    case 'd':
-      n = 4;
-      break;
-    case 's':
-      n = in[i].length + 1;
-      break;
-    }
-    for (j = 0; j < n; j++)
-      *(p++) = in[i].info[j];
-  }
-  out->parms[i].info = NULL;
-  out->parms[i].length = 0;
+	word i, j, n = 0;
+	byte *p;
+
+	p = out->info;
+	for (i = 0; format[i] != '\0'; i++)
+	{
+		out->parms[i].info = p;
+		out->parms[i].length = in[i].length;
+		switch (format[i])
+		{
+		case 'b':
+			n = 1;
+			break;
+		case 'w':
+			n = 2;
+			break;
+		case 'd':
+			n = 4;
+			break;
+		case 's':
+			n = in[i].length + 1;
+			break;
+		}
+		for (j = 0; j < n; j++)
+			*(p++) = in[i].info[j];
+	}
+	out->parms[i].info = NULL;
+	out->parms[i].length = 0;
 }
 
 static void api_load_msg(API_SAVE *in, API_PARSE *out)
 {
-  word i;
+	word i;
 
-  i = 0;
-  do
-  {
-    out[i].info = in->parms[i].info;
-    out[i].length = in->parms[i].length;
-  } while (in->parms[i++].info);
+	i = 0;
+	do
+	{
+		out[i].info = in->parms[i].info;
+		out[i].length = in->parms[i].length;
+	} while (in->parms[i++].info);
 }
 
 
@@ -680,31 +680,31 @@ static void api_load_msg(API_SAVE *in, API_PARSE *out)
 
 word api_remove_start(void)
 {
-  word i;
-  word j;
-
-  if(!remove_started) {
-    remove_started = true;
-    for(i=0;i<max_adapter;i++) {
-      if(adapter[i].request) {
-        for(j=0;j<adapter[i].max_plci;j++) {
-          if(adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]);
-        }
-      }
-    }
-    return 1;
-  }
-  else {
-    for(i=0;i<max_adapter;i++) {
-      if(adapter[i].request) {
-        for(j=0;j<adapter[i].max_plci;j++) {
-          if(adapter[i].plci[j].Sig.Id) return 1;
-        }
-      }
-    }
-  }
-  api_remove_complete();
-  return 0;
+	word i;
+	word j;
+
+	if (!remove_started) {
+		remove_started = true;
+		for (i = 0; i < max_adapter; i++) {
+			if (adapter[i].request) {
+				for (j = 0; j < adapter[i].max_plci; j++) {
+					if (adapter[i].plci[j].Sig.Id) plci_remove(&adapter[i].plci[j]);
+				}
+			}
+		}
+		return 1;
+	}
+	else {
+		for (i = 0; i < max_adapter; i++) {
+			if (adapter[i].request) {
+				for (j = 0; j < adapter[i].max_plci; j++) {
+					if (adapter[i].plci[j].Sig.Id) return 1;
+				}
+			}
+		}
+	}
+	api_remove_complete();
+	return 0;
 }
 
 
@@ -712,60 +712,60 @@ word api_remove_start(void)
 /* internal command queue                                           */
 /*------------------------------------------------------------------*/
 
-static void init_internal_command_queue (PLCI   *plci)
+static void init_internal_command_queue(PLCI *plci)
 {
-  word i;
+	word i;
 
-  dbug (1, dprintf ("%s,%d: init_internal_command_queue",
-    (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("%s,%d: init_internal_command_queue",
+			(char *)(FILE_), __LINE__));
 
-  plci->internal_command = 0;
-  for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++)
-    plci->internal_command_queue[i] = NULL;
+	plci->internal_command = 0;
+	for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS; i++)
+		plci->internal_command_queue[i] = NULL;
 }
 
 
-static void start_internal_command (dword Id, PLCI   *plci, t_std_internal_command command_function)
+static void start_internal_command(dword Id, PLCI *plci, t_std_internal_command command_function)
 {
-  word i;
+	word i;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: start_internal_command",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: start_internal_command",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
 
-  if (plci->internal_command == 0)
-  {
-    plci->internal_command_queue[0] = command_function;
-    (* command_function)(Id, plci, OK);
-  }
-  else
-  {
-    i = 1;
-    while (plci->internal_command_queue[i] != NULL)
-      i++;
-    plci->internal_command_queue[i] = command_function;
-  }
+	if (plci->internal_command == 0)
+	{
+		plci->internal_command_queue[0] = command_function;
+		(*command_function)(Id, plci, OK);
+	}
+	else
+	{
+		i = 1;
+		while (plci->internal_command_queue[i] != NULL)
+			i++;
+		plci->internal_command_queue[i] = command_function;
+	}
 }
 
 
-static void next_internal_command (dword Id, PLCI   *plci)
+static void next_internal_command(dword Id, PLCI *plci)
 {
-  word i;
+	word i;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: next_internal_command",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: next_internal_command",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
 
-  plci->internal_command = 0;
-  plci->internal_command_queue[0] = NULL;
-  while (plci->internal_command_queue[1] != NULL)
-  {
-    for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++)
-      plci->internal_command_queue[i] = plci->internal_command_queue[i+1];
-    plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL;
-    (*(plci->internal_command_queue[0]))(Id, plci, OK);
-    if (plci->internal_command != 0)
-      return;
-    plci->internal_command_queue[0] = NULL;
-  }
+	plci->internal_command = 0;
+	plci->internal_command_queue[0] = NULL;
+	while (plci->internal_command_queue[1] != NULL)
+	{
+		for (i = 0; i < MAX_INTERNAL_COMMAND_LEVELS - 1; i++)
+			plci->internal_command_queue[i] = plci->internal_command_queue[i + 1];
+		plci->internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS - 1] = NULL;
+		(*(plci->internal_command_queue[0]))(Id, plci, OK);
+		if (plci->internal_command != 0)
+			return;
+		plci->internal_command_queue[0] = NULL;
+	}
 }
 
 
@@ -775,238 +775,238 @@ static void next_internal_command (dword Id, PLCI   *plci)
 
 static dword ncci_mapping_bug = 0;
 
-static word get_ncci (PLCI   *plci, byte ch, word force_ncci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word ncci, i, j, k;
-
-  a = plci->adapter;
-  if (!ch || a->ch_ncci[ch])
-  {
-    ncci_mapping_bug++;
-    dbug(1,dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x",
-      ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch]));
-    ncci = ch;
-  }
-  else
-  {
-    if (force_ncci)
-      ncci = force_ncci;
-    else
-    {
-      if ((ch < MAX_NCCI+1) && !a->ncci_ch[ch])
-        ncci = ch;
-      else
-      {
-        ncci = 1;
-        while ((ncci < MAX_NCCI+1) && a->ncci_ch[ncci])
-          ncci++;
-        if (ncci == MAX_NCCI+1)
-        {
-          ncci_mapping_bug++;
-          i = 1;
-          do
-          {
-            j = 1;
-            while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i))
-              j++;
-            k = j;
-            if (j < MAX_NCCI+1)
-            {
-              do
-              {
-                j++;
-              } while ((j < MAX_NCCI+1) && (a->ncci_ch[j] != i));
-            }
-          } while ((i < MAX_NL_CHANNEL+1) && (j < MAX_NCCI+1));
-          if (i < MAX_NL_CHANNEL+1)
-          {
-            dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
-              ncci_mapping_bug, ch, force_ncci, i, k, j));
-          }
-          else
-          {
-            dbug(1,dprintf("NCCI mapping overflow %ld %02x %02x",
-              ncci_mapping_bug, ch, force_ncci));
-          }
-          ncci = ch;
-        }
-      }
-      a->ncci_plci[ncci] = plci->Id;
-      a->ncci_state[ncci] = IDLE;
-      if (!plci->ncci_ring_list)
-        plci->ncci_ring_list = ncci;
-      else
-        a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list];
-      a->ncci_next[plci->ncci_ring_list] = (byte) ncci;
-    }
-    a->ncci_ch[ncci] = ch;
-    a->ch_ncci[ch] = (byte) ncci;
-    dbug(1,dprintf("NCCI mapping established %ld %02x %02x %02x-%02x",
-      ncci_mapping_bug, ch, force_ncci, ch, ncci));
-  }
-  return (ncci);
-}
-
-
-static void ncci_free_receive_buffers (PLCI   *plci, word ncci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  APPL   *appl;
-  word i, ncci_code;
-  dword Id;
-
-  a = plci->adapter;
-  Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
-  if (ncci)
-  {
-    if (a->ncci_plci[ncci] == plci->Id)
-    {
-      if (!plci->appl)
-      {
-        ncci_mapping_bug++;
-        dbug(1,dprintf("NCCI mapping appl expected %ld %08lx",
-          ncci_mapping_bug, Id));
-      }
-      else
-      {
-        appl = plci->appl;
-        ncci_code = ncci | (((word) a->Id) << 8);
-        for (i = 0; i < appl->MaxBuffer; i++)
-        {
-          if ((appl->DataNCCI[i] == ncci_code)
-           && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
-          {
-            appl->DataNCCI[i] = 0;
-          }
-        }
-      }
-    }
-  }
-  else
-  {
-    for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
-    {
-      if (a->ncci_plci[ncci] == plci->Id)
-      {
-        if (!plci->appl)
-        {
-          ncci_mapping_bug++;
-          dbug(1,dprintf("NCCI mapping no appl %ld %08lx",
-            ncci_mapping_bug, Id));
-        }
-        else
-        {
-          appl = plci->appl;
-          ncci_code = ncci | (((word) a->Id) << 8);
-          for (i = 0; i < appl->MaxBuffer; i++)
-          {
-            if ((appl->DataNCCI[i] == ncci_code)
-             && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
-            {
-              appl->DataNCCI[i] = 0;
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-
-static void cleanup_ncci_data (PLCI   *plci, word ncci)
-{
-  NCCI   *ncci_ptr;
-
-  if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id))
-  {
-    ncci_ptr = &(plci->adapter->ncci[ncci]);
-    if (plci->appl)
-    {
-      while (ncci_ptr->data_pending != 0)
-      {
-        if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr))
-          TransmitBufferFree (plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P);
-        (ncci_ptr->data_out)++;
-        if (ncci_ptr->data_out == MAX_DATA_B3)
-          ncci_ptr->data_out = 0;
-        (ncci_ptr->data_pending)--;
-      }
-    }
-    ncci_ptr->data_out = 0;
-    ncci_ptr->data_pending = 0;
-    ncci_ptr->data_ack_out = 0;
-    ncci_ptr->data_ack_pending = 0;
-  }
-}
-
-
-static void ncci_remove (PLCI   *plci, word ncci, byte preserve_ncci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  dword Id;
-  word i;
-
-  a = plci->adapter;
-  Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
-  if (!preserve_ncci)
-    ncci_free_receive_buffers (plci, ncci);
-  if (ncci)
-  {
-    if (a->ncci_plci[ncci] != plci->Id)
-    {
-      ncci_mapping_bug++;
-      dbug(1,dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
-        ncci_mapping_bug, Id, preserve_ncci));
-    }
-    else
-    {
-      cleanup_ncci_data (plci, ncci);
-      dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
-        ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
-      a->ch_ncci[a->ncci_ch[ncci]] = 0;
-      if (!preserve_ncci)
-      {
-        a->ncci_ch[ncci] = 0;
-        a->ncci_plci[ncci] = 0;
-        a->ncci_state[ncci] = IDLE;
-        i = plci->ncci_ring_list;
-        while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci))
-          i = a->ncci_next[i];
-        if ((i != 0) && (a->ncci_next[i] == ncci))
-        {
-          if (i == ncci)
-            plci->ncci_ring_list = 0;
-          else if (plci->ncci_ring_list == ncci)
-            plci->ncci_ring_list = i;
-          a->ncci_next[i] = a->ncci_next[ncci];
-        }
-        a->ncci_next[ncci] = 0;
-      }
-    }
-  }
-  else
-  {
-    for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
-    {
-      if (a->ncci_plci[ncci] == plci->Id)
-      {
-        cleanup_ncci_data (plci, ncci);
-        dbug(1,dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
-          ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
-        a->ch_ncci[a->ncci_ch[ncci]] = 0;
-        if (!preserve_ncci)
-        {
-          a->ncci_ch[ncci] = 0;
-          a->ncci_plci[ncci] = 0;
-          a->ncci_state[ncci] = IDLE;
-          a->ncci_next[ncci] = 0;
-        }
-      }
-    }
-    if (!preserve_ncci)
-      plci->ncci_ring_list = 0;
-  }
+static word get_ncci(PLCI *plci, byte ch, word force_ncci)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word ncci, i, j, k;
+
+	a = plci->adapter;
+	if (!ch || a->ch_ncci[ch])
+	{
+		ncci_mapping_bug++;
+		dbug(1, dprintf("NCCI mapping exists %ld %02x %02x %02x-%02x",
+				ncci_mapping_bug, ch, force_ncci, a->ncci_ch[a->ch_ncci[ch]], a->ch_ncci[ch]));
+		ncci = ch;
+	}
+	else
+	{
+		if (force_ncci)
+			ncci = force_ncci;
+		else
+		{
+			if ((ch < MAX_NCCI + 1) && !a->ncci_ch[ch])
+				ncci = ch;
+			else
+			{
+				ncci = 1;
+				while ((ncci < MAX_NCCI + 1) && a->ncci_ch[ncci])
+					ncci++;
+				if (ncci == MAX_NCCI + 1)
+				{
+					ncci_mapping_bug++;
+					i = 1;
+					do
+					{
+						j = 1;
+						while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i))
+							j++;
+						k = j;
+						if (j < MAX_NCCI + 1)
+						{
+							do
+							{
+								j++;
+							} while ((j < MAX_NCCI + 1) && (a->ncci_ch[j] != i));
+						}
+					} while ((i < MAX_NL_CHANNEL + 1) && (j < MAX_NCCI + 1));
+					if (i < MAX_NL_CHANNEL + 1)
+					{
+						dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x %02x-%02x-%02x",
+								ncci_mapping_bug, ch, force_ncci, i, k, j));
+					}
+					else
+					{
+						dbug(1, dprintf("NCCI mapping overflow %ld %02x %02x",
+								ncci_mapping_bug, ch, force_ncci));
+					}
+					ncci = ch;
+				}
+			}
+			a->ncci_plci[ncci] = plci->Id;
+			a->ncci_state[ncci] = IDLE;
+			if (!plci->ncci_ring_list)
+				plci->ncci_ring_list = ncci;
+			else
+				a->ncci_next[ncci] = a->ncci_next[plci->ncci_ring_list];
+			a->ncci_next[plci->ncci_ring_list] = (byte) ncci;
+		}
+		a->ncci_ch[ncci] = ch;
+		a->ch_ncci[ch] = (byte) ncci;
+		dbug(1, dprintf("NCCI mapping established %ld %02x %02x %02x-%02x",
+				ncci_mapping_bug, ch, force_ncci, ch, ncci));
+	}
+	return (ncci);
+}
+
+
+static void ncci_free_receive_buffers(PLCI *plci, word ncci)
+{
+	DIVA_CAPI_ADAPTER *a;
+	APPL *appl;
+	word i, ncci_code;
+	dword Id;
+
+	a = plci->adapter;
+	Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
+	if (ncci)
+	{
+		if (a->ncci_plci[ncci] == plci->Id)
+		{
+			if (!plci->appl)
+			{
+				ncci_mapping_bug++;
+				dbug(1, dprintf("NCCI mapping appl expected %ld %08lx",
+						ncci_mapping_bug, Id));
+			}
+			else
+			{
+				appl = plci->appl;
+				ncci_code = ncci | (((word) a->Id) << 8);
+				for (i = 0; i < appl->MaxBuffer; i++)
+				{
+					if ((appl->DataNCCI[i] == ncci_code)
+					    && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
+					{
+						appl->DataNCCI[i] = 0;
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
+		{
+			if (a->ncci_plci[ncci] == plci->Id)
+			{
+				if (!plci->appl)
+				{
+					ncci_mapping_bug++;
+					dbug(1, dprintf("NCCI mapping no appl %ld %08lx",
+							ncci_mapping_bug, Id));
+				}
+				else
+				{
+					appl = plci->appl;
+					ncci_code = ncci | (((word) a->Id) << 8);
+					for (i = 0; i < appl->MaxBuffer; i++)
+					{
+						if ((appl->DataNCCI[i] == ncci_code)
+						    && (((byte)(appl->DataFlags[i] >> 8)) == plci->Id))
+						{
+							appl->DataNCCI[i] = 0;
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+
+static void cleanup_ncci_data(PLCI *plci, word ncci)
+{
+	NCCI *ncci_ptr;
+
+	if (ncci && (plci->adapter->ncci_plci[ncci] == plci->Id))
+	{
+		ncci_ptr = &(plci->adapter->ncci[ncci]);
+		if (plci->appl)
+		{
+			while (ncci_ptr->data_pending != 0)
+			{
+				if (!plci->data_sent || (ncci_ptr->DBuffer[ncci_ptr->data_out].P != plci->data_sent_ptr))
+					TransmitBufferFree(plci->appl, ncci_ptr->DBuffer[ncci_ptr->data_out].P);
+				(ncci_ptr->data_out)++;
+				if (ncci_ptr->data_out == MAX_DATA_B3)
+					ncci_ptr->data_out = 0;
+				(ncci_ptr->data_pending)--;
+			}
+		}
+		ncci_ptr->data_out = 0;
+		ncci_ptr->data_pending = 0;
+		ncci_ptr->data_ack_out = 0;
+		ncci_ptr->data_ack_pending = 0;
+	}
+}
+
+
+static void ncci_remove(PLCI *plci, word ncci, byte preserve_ncci)
+{
+	DIVA_CAPI_ADAPTER *a;
+	dword Id;
+	word i;
+
+	a = plci->adapter;
+	Id = (((dword) ncci) << 16) | (((word)(plci->Id)) << 8) | a->Id;
+	if (!preserve_ncci)
+		ncci_free_receive_buffers(plci, ncci);
+	if (ncci)
+	{
+		if (a->ncci_plci[ncci] != plci->Id)
+		{
+			ncci_mapping_bug++;
+			dbug(1, dprintf("NCCI mapping doesn't exist %ld %08lx %02x",
+					ncci_mapping_bug, Id, preserve_ncci));
+		}
+		else
+		{
+			cleanup_ncci_data(plci, ncci);
+			dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
+					ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
+			a->ch_ncci[a->ncci_ch[ncci]] = 0;
+			if (!preserve_ncci)
+			{
+				a->ncci_ch[ncci] = 0;
+				a->ncci_plci[ncci] = 0;
+				a->ncci_state[ncci] = IDLE;
+				i = plci->ncci_ring_list;
+				while ((i != 0) && (a->ncci_next[i] != plci->ncci_ring_list) && (a->ncci_next[i] != ncci))
+					i = a->ncci_next[i];
+				if ((i != 0) && (a->ncci_next[i] == ncci))
+				{
+					if (i == ncci)
+						plci->ncci_ring_list = 0;
+					else if (plci->ncci_ring_list == ncci)
+						plci->ncci_ring_list = i;
+					a->ncci_next[i] = a->ncci_next[ncci];
+				}
+				a->ncci_next[ncci] = 0;
+			}
+		}
+	}
+	else
+	{
+		for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
+		{
+			if (a->ncci_plci[ncci] == plci->Id)
+			{
+				cleanup_ncci_data(plci, ncci);
+				dbug(1, dprintf("NCCI mapping released %ld %08lx %02x %02x-%02x",
+						ncci_mapping_bug, Id, preserve_ncci, a->ncci_ch[ncci], ncci));
+				a->ch_ncci[a->ncci_ch[ncci]] = 0;
+				if (!preserve_ncci)
+				{
+					a->ncci_ch[ncci] = 0;
+					a->ncci_plci[ncci] = 0;
+					a->ncci_state[ncci] = IDLE;
+					a->ncci_next[ncci] = 0;
+				}
+			}
+		}
+		if (!preserve_ncci)
+			plci->ncci_ring_list = 0;
+	}
 }
 
 
@@ -1014,170 +1014,170 @@ static void ncci_remove (PLCI   *plci, word ncci, byte preserve_ncci)
 /* PLCI remove function                                             */
 /*------------------------------------------------------------------*/
 
-static void plci_free_msg_in_queue (PLCI   *plci)
-{
-  word i;
-
-  if (plci->appl)
-  {
-    i = plci->msg_in_read_pos;
-    while (i != plci->msg_in_write_pos)
-    {
-      if (i == plci->msg_in_wrap_pos)
-        i = 0;
-      if (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R)
-      {
-
-        TransmitBufferFree (plci->appl,
-          (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
-
-      }
-
-      i += (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[i]))->header.length +
-        MSG_IN_OVERHEAD + 3) & 0xfffc;
-
-    }
-  }
-  plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
-  plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
-  plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
-}
-
-
-static void plci_remove(PLCI   * plci)
-{
-
-  if(!plci) {
-    dbug(1,dprintf("plci_remove(no plci)"));
-    return;
-  }
-  init_internal_command_queue (plci);
-  dbug(1,dprintf("plci_remove(%x,tel=%x)",plci->Id,plci->tel));
-  if(plci_remove_check(plci))
-  {
-    return;
-  }
-  if (plci->Sig.Id == 0xff)
-  {
-    dbug(1,dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id));
-    if (plci->NL.Id && !plci->nl_remove_id)
-    {
-      nl_req_ncci(plci,REMOVE,0);
-      send_req(plci);
-    }
-  }
-  else
-  {
-    if (!plci->sig_remove_id
-     && (plci->Sig.Id
-      || (plci->req_in!=plci->req_out)
-      || (plci->nl_req || plci->sig_req)))
-    {
-      sig_req(plci,HANGUP,0);
-      send_req(plci);
-    }
-  }
-  ncci_remove (plci, 0, false);
-  plci_free_msg_in_queue (plci);
-
-  plci->channels = 0;
-  plci->appl = NULL;
-  if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT))
-    plci->State = OUTG_DIS_PENDING;
+static void plci_free_msg_in_queue(PLCI *plci)
+{
+	word i;
+
+	if (plci->appl)
+	{
+		i = plci->msg_in_read_pos;
+		while (i != plci->msg_in_write_pos)
+		{
+			if (i == plci->msg_in_wrap_pos)
+				i = 0;
+			if (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.command == _DATA_B3_R)
+			{
+
+				TransmitBufferFree(plci->appl,
+						   (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
+
+			}
+
+			i += (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->header.length +
+			      MSG_IN_OVERHEAD + 3) & 0xfffc;
+
+		}
+	}
+	plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
+	plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
+	plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
+}
+
+
+static void plci_remove(PLCI *plci)
+{
+
+	if (!plci) {
+		dbug(1, dprintf("plci_remove(no plci)"));
+		return;
+	}
+	init_internal_command_queue(plci);
+	dbug(1, dprintf("plci_remove(%x,tel=%x)", plci->Id, plci->tel));
+	if (plci_remove_check(plci))
+	{
+		return;
+	}
+	if (plci->Sig.Id == 0xff)
+	{
+		dbug(1, dprintf("D-channel X.25 plci->NL.Id:%0x", plci->NL.Id));
+		if (plci->NL.Id && !plci->nl_remove_id)
+		{
+			nl_req_ncci(plci, REMOVE, 0);
+			send_req(plci);
+		}
+	}
+	else
+	{
+		if (!plci->sig_remove_id
+		    && (plci->Sig.Id
+			|| (plci->req_in != plci->req_out)
+			|| (plci->nl_req || plci->sig_req)))
+		{
+			sig_req(plci, HANGUP, 0);
+			send_req(plci);
+		}
+	}
+	ncci_remove(plci, 0, false);
+	plci_free_msg_in_queue(plci);
+
+	plci->channels = 0;
+	plci->appl = NULL;
+	if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT))
+		plci->State = OUTG_DIS_PENDING;
 }
 
 /*------------------------------------------------------------------*/
 /* Application Group function helpers                               */
 /*------------------------------------------------------------------*/
 
-static void set_group_ind_mask (PLCI   *plci)
+static void set_group_ind_mask(PLCI *plci)
 {
-  word i;
+	word i;
 
-  for (i = 0; i < C_IND_MASK_DWORDS; i++)
-    plci->group_optimization_mask_table[i] = 0xffffffffL;
+	for (i = 0; i < C_IND_MASK_DWORDS; i++)
+		plci->group_optimization_mask_table[i] = 0xffffffffL;
 }
 
-static void clear_group_ind_mask_bit (PLCI   *plci, word b)
+static void clear_group_ind_mask_bit(PLCI *plci, word b)
 {
-  plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
+	plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
 }
 
-static byte test_group_ind_mask_bit (PLCI   *plci, word b)
+static byte test_group_ind_mask_bit(PLCI *plci, word b)
 {
-  return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
+	return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
 }
 
 /*------------------------------------------------------------------*/
 /* c_ind_mask operations for arbitrary MAX_APPL                     */
 /*------------------------------------------------------------------*/
 
-static void clear_c_ind_mask (PLCI   *plci)
+static void clear_c_ind_mask(PLCI *plci)
 {
-  word i;
+	word i;
 
-  for (i = 0; i < C_IND_MASK_DWORDS; i++)
-    plci->c_ind_mask_table[i] = 0;
+	for (i = 0; i < C_IND_MASK_DWORDS; i++)
+		plci->c_ind_mask_table[i] = 0;
 }
 
-static byte c_ind_mask_empty (PLCI   *plci)
+static byte c_ind_mask_empty(PLCI *plci)
 {
-  word i;
+	word i;
 
-  i = 0;
-  while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0))
-    i++;
-  return (i == C_IND_MASK_DWORDS);
+	i = 0;
+	while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0))
+		i++;
+	return (i == C_IND_MASK_DWORDS);
 }
 
-static void set_c_ind_mask_bit (PLCI   *plci, word b)
+static void set_c_ind_mask_bit(PLCI *plci, word b)
 {
-  plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f));
+	plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f));
 }
 
-static void clear_c_ind_mask_bit (PLCI   *plci, word b)
+static void clear_c_ind_mask_bit(PLCI *plci, word b)
 {
-  plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
+	plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
 }
 
-static byte test_c_ind_mask_bit (PLCI   *plci, word b)
+static byte test_c_ind_mask_bit(PLCI *plci, word b)
 {
-  return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
+	return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
 }
 
-static void dump_c_ind_mask (PLCI   *plci)
+static void dump_c_ind_mask(PLCI *plci)
 {
-static char hex_digit_table[0x10] =
-  {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
-  word i, j, k;
-  dword d;
-    char *p;
-    char buf[40];
+	static char hex_digit_table[0x10] =
+		{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+	word i, j, k;
+	dword d;
+	char *p;
+	char buf[40];
 
-  for (i = 0; i < C_IND_MASK_DWORDS; i += 4)
-  {
-    p = buf + 36;
-    *p = '\0';
-    for (j = 0; j < 4; j++)
-    {
-      if (i+j < C_IND_MASK_DWORDS)
-      {
-        d = plci->c_ind_mask_table[i+j];
-        for (k = 0; k < 8; k++)
-        {
-          *(--p) = hex_digit_table[d & 0xf];
-          d >>= 4;
-        }
-      }
-      else if (i != 0)
-      {
-        for (k = 0; k < 8; k++)
-          *(--p) = ' ';
-      }
-      *(--p) = ' ';
-    }
-    dbug(1,dprintf ("c_ind_mask =%s", (char   *) p));
-  }
+	for (i = 0; i < C_IND_MASK_DWORDS; i += 4)
+	{
+		p = buf + 36;
+		*p = '\0';
+		for (j = 0; j < 4; j++)
+		{
+			if (i + j < C_IND_MASK_DWORDS)
+			{
+				d = plci->c_ind_mask_table[i + j];
+				for (k = 0; k < 8; k++)
+				{
+					*(--p) = hex_digit_table[d & 0xf];
+					d >>= 4;
+				}
+			}
+			else if (i != 0)
+			{
+				for (k = 0; k < 8; k++)
+					*(--p) = ' ';
+			}
+			*(--p) = ' ';
+		}
+		dbug(1, dprintf("c_ind_mask =%s", (char *) p));
+	}
 }
 
 
@@ -1195,6204 +1195,6204 @@ static char hex_digit_table[0x10] =
 static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word ch;
-  word i;
-  word Info;
-  byte LinkLayer;
-  API_PARSE * ai;
-  API_PARSE * bp;
-    API_PARSE ai_parms[5];
-  word channel = 0;
-  dword ch_mask;
-  byte m;
-  static byte esc_chi[35] = {0x02,0x18,0x01};
-  static byte lli[2] = {0x01,0x00};
-  byte noCh = 0;
-  word dir = 0;
-  byte   *p_chi = "";
-
-  for(i=0;i<5;i++) ai_parms[i].length = 0;
-
-  dbug(1,dprintf("connect_req(%d)",parms->length));
-  Info = _WRONG_IDENTIFIER;
-  if(a)
-  {
-    if(a->adapter_disabled)
-    {
-      dbug(1,dprintf("adapter disabled"));
-      Id = ((word)1<<8)|a->Id;
-      sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
-      sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR);
-      return false;
-    }
-    Info = _OUT_OF_PLCI;
-    if((i=get_plci(a)))
-    {
-      Info = 0;
-      plci = &a->plci[i-1];
-      plci->appl = appl;
-      plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
-      /* check 'external controller' bit for codec support */
-      if(Id & EXT_CONTROLLER)
-      {
-        if(AdvCodecSupport(a, plci, appl, 0) )
-        {
-          plci->Id = 0;
-          sendf(appl, _CONNECT_R|CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
-          return 2;
-        }
-      }
-      ai = &parms[9];
-      bp = &parms[5];
-      ch = 0;
-      if(bp->length)LinkLayer = bp->info[3];
-      else LinkLayer = 0;
-      if(ai->length)
-      {
-        ch=0xffff;
-        if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms))
-        {
-          ch = 0;
-          if(ai_parms[0].length)
-          {
-            ch = GET_WORD(ai_parms[0].info+1);
-            if(ch>4) ch=0; /* safety -> ignore ChannelID */
-            if(ch==4) /* explizit CHI in message */
-            {
-              /* check length of B-CH struct */
-              if((ai_parms[0].info)[3]>=1)
-              {
-                if((ai_parms[0].info)[4]==CHI)
-                {
-                  p_chi = &((ai_parms[0].info)[5]);
-                }
-                else
-                {
-                  p_chi = &((ai_parms[0].info)[3]);
-                }
-                if(p_chi[0]>35) /* check length of channel ID */
-                {
-                  Info = _WRONG_MESSAGE_FORMAT;    
-                }
-              }
-              else Info = _WRONG_MESSAGE_FORMAT;    
-            }
-
-            if(ch==3 && ai_parms[0].length>=7 && ai_parms[0].length<=36)
-            {
-              dir = GET_WORD(ai_parms[0].info+3);
-              ch_mask = 0;
-              m = 0x3f;
-              for(i=0; i+5<=ai_parms[0].length; i++)
-              {
-                if(ai_parms[0].info[i+5]!=0)
-                {
-                  if((ai_parms[0].info[i+5] | m) != 0xff)
-                    Info = _WRONG_MESSAGE_FORMAT;
-                  else
-                  {
-                    if (ch_mask == 0)
-                      channel = i;
-                    ch_mask |= 1L << i;
-                  }
-                }
-                m = 0;
-              }
-              if (ch_mask == 0)
-                Info = _WRONG_MESSAGE_FORMAT;
-              if (!Info)
-              {
-                if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel))))
-                {
-                  esc_chi[0] = (byte)(ai_parms[0].length - 2);
-                  for(i=0; i+5<=ai_parms[0].length; i++)
-                    esc_chi[i+3] = ai_parms[0].info[i+5];
-                }
-                else
-                  esc_chi[0] = 2;
-                esc_chi[2] = (byte)channel;
-                plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */
-                add_p(plci,LLI,lli);
-                add_p(plci,ESC,esc_chi);
-                plci->State = LOCAL_CONNECT;
-                if(!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;     /* dir 0=DTE, 1=DCE */
-              }
-            }
-          }
-        }
-        else  Info = _WRONG_MESSAGE_FORMAT;
-      }
-
-      dbug(1,dprintf("ch=%x,dir=%x,p_ch=%d",ch,dir,channel));
-      plci->command = _CONNECT_R;
-      plci->number = Number;
-      /* x.31 or D-ch free SAPI in LinkLayer? */
-      if(ch==1 && LinkLayer!=3 && LinkLayer!=12) noCh = true;
-      if((ch==0 || ch==2 || noCh || ch==3 || ch==4) && !Info)
-      {
-        /* B-channel used for B3 connections (ch==0), or no B channel    */
-        /* is used (ch==2) or perm. connection (3) is used  do a CALL    */
-        if(noCh) Info = add_b1(plci,&parms[5],2,0);    /* no resource    */
-        else     Info = add_b1(plci,&parms[5],ch,0); 
-        add_s(plci,OAD,&parms[2]);
-        add_s(plci,OSA,&parms[4]);
-        add_s(plci,BC,&parms[6]);
-        add_s(plci,LLC,&parms[7]);
-        add_s(plci,HLC,&parms[8]);
-        if (a->Info_Mask[appl->Id-1] & 0x200)
-        {
-          /* early B3 connect (CIP mask bit 9) no release after a disc */
-          add_p(plci,LLI,"\x01\x01");
-        }
-        if(GET_WORD(parms[0].info)<29) {
-          add_p(plci,BC,cip_bc[GET_WORD(parms[0].info)][a->u_law]);
-          add_p(plci,HLC,cip_hlc[GET_WORD(parms[0].info)]);
-        }
-        add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-        sig_req(plci,ASSIGN,DSIG_ID);
-      }
-      else if(ch==1) {
-
-        /* D-Channel used for B3 connections */
-        plci->Sig.Id = 0xff;
-        Info = 0;
-      }
-
-      if(!Info && ch!=2 && !noCh ) {
-        Info = add_b23(plci,&parms[5]);
-        if(!Info) {
-          if(!(plci->tel && !plci->adv_nl))nl_req_ncci(plci,ASSIGN,0);
-        }
-      }
-
-      if(!Info)
-      {
-        if(ch==0 || ch==2 || ch==3 || noCh || ch==4)
-        {
-          if(plci->spoofed_msg==SPOOFING_REQUIRED)
-          {
-            api_save_msg(parms, "wsssssssss", &plci->saved_msg);
-            plci->spoofed_msg = CALL_REQ;
-            plci->internal_command = BLOCK_PLCI;
-            plci->command = 0;
-            dbug(1,dprintf("Spoof"));
-            send_req(plci);
-            return false;
-          }
-          if(ch==4)add_p(plci,CHI,p_chi);
-          add_s(plci,CPN,&parms[1]);
-          add_s(plci,DSA,&parms[3]);
-          if(noCh) add_p(plci,ESC,"\x02\x18\xfd");  /* D-channel, no B-L3 */
-          add_ai(plci,&parms[9]);
-          if(!dir)sig_req(plci,CALL_REQ,0);
-          else
-          {
-            plci->command = PERM_LIST_REQ;
-            plci->appl = appl;
-            sig_req(plci,LISTEN_REQ,0);
-            send_req(plci);
-            return false;
-          }
-        }
-        send_req(plci);
-        return false;
-      }
-      plci->Id = 0;
-    }
-  }
-  sendf(appl,
-        _CONNECT_R|CONFIRM,
-        Id,
-        Number,
-        "w",Info);
-  return 2;
+	word ch;
+	word i;
+	word Info;
+	byte LinkLayer;
+	API_PARSE *ai;
+	API_PARSE *bp;
+	API_PARSE ai_parms[5];
+	word channel = 0;
+	dword ch_mask;
+	byte m;
+	static byte esc_chi[35] = {0x02, 0x18, 0x01};
+	static byte lli[2] = {0x01, 0x00};
+	byte noCh = 0;
+	word dir = 0;
+	byte *p_chi = "";
+
+	for (i = 0; i < 5; i++) ai_parms[i].length = 0;
+
+	dbug(1, dprintf("connect_req(%d)", parms->length));
+	Info = _WRONG_IDENTIFIER;
+	if (a)
+	{
+		if (a->adapter_disabled)
+		{
+			dbug(1, dprintf("adapter disabled"));
+			Id = ((word)1 << 8) | a->Id;
+			sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
+			sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR);
+			return false;
+		}
+		Info = _OUT_OF_PLCI;
+		if ((i = get_plci(a)))
+		{
+			Info = 0;
+			plci = &a->plci[i - 1];
+			plci->appl = appl;
+			plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
+			/* check 'external controller' bit for codec support */
+			if (Id & EXT_CONTROLLER)
+			{
+				if (AdvCodecSupport(a, plci, appl, 0))
+				{
+					plci->Id = 0;
+					sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
+					return 2;
+				}
+			}
+			ai = &parms[9];
+			bp = &parms[5];
+			ch = 0;
+			if (bp->length)LinkLayer = bp->info[3];
+			else LinkLayer = 0;
+			if (ai->length)
+			{
+				ch = 0xffff;
+				if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
+				{
+					ch = 0;
+					if (ai_parms[0].length)
+					{
+						ch = GET_WORD(ai_parms[0].info + 1);
+						if (ch > 4) ch = 0; /* safety -> ignore ChannelID */
+						if (ch == 4) /* explizit CHI in message */
+						{
+							/* check length of B-CH struct */
+							if ((ai_parms[0].info)[3] >= 1)
+							{
+								if ((ai_parms[0].info)[4] == CHI)
+								{
+									p_chi = &((ai_parms[0].info)[5]);
+								}
+								else
+								{
+									p_chi = &((ai_parms[0].info)[3]);
+								}
+								if (p_chi[0] > 35) /* check length of channel ID */
+								{
+									Info = _WRONG_MESSAGE_FORMAT;
+								}
+							}
+							else Info = _WRONG_MESSAGE_FORMAT;
+						}
+
+						if (ch == 3 && ai_parms[0].length >= 7 && ai_parms[0].length <= 36)
+						{
+							dir = GET_WORD(ai_parms[0].info + 3);
+							ch_mask = 0;
+							m = 0x3f;
+							for (i = 0; i + 5 <= ai_parms[0].length; i++)
+							{
+								if (ai_parms[0].info[i + 5] != 0)
+								{
+									if ((ai_parms[0].info[i + 5] | m) != 0xff)
+										Info = _WRONG_MESSAGE_FORMAT;
+									else
+									{
+										if (ch_mask == 0)
+											channel = i;
+										ch_mask |= 1L << i;
+									}
+								}
+								m = 0;
+							}
+							if (ch_mask == 0)
+								Info = _WRONG_MESSAGE_FORMAT;
+							if (!Info)
+							{
+								if ((ai_parms[0].length == 36) || (ch_mask != ((dword)(1L << channel))))
+								{
+									esc_chi[0] = (byte)(ai_parms[0].length - 2);
+									for (i = 0; i + 5 <= ai_parms[0].length; i++)
+										esc_chi[i + 3] = ai_parms[0].info[i + 5];
+								}
+								else
+									esc_chi[0] = 2;
+								esc_chi[2] = (byte)channel;
+								plci->b_channel = (byte)channel; /* not correct for ETSI ch 17..31 */
+								add_p(plci, LLI, lli);
+								add_p(plci, ESC, esc_chi);
+								plci->State = LOCAL_CONNECT;
+								if (!dir) plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;     /* dir 0=DTE, 1=DCE */
+							}
+						}
+					}
+				}
+				else  Info = _WRONG_MESSAGE_FORMAT;
+			}
+
+			dbug(1, dprintf("ch=%x,dir=%x,p_ch=%d", ch, dir, channel));
+			plci->command = _CONNECT_R;
+			plci->number = Number;
+			/* x.31 or D-ch free SAPI in LinkLayer? */
+			if (ch == 1 && LinkLayer != 3 && LinkLayer != 12) noCh = true;
+			if ((ch == 0 || ch == 2 || noCh || ch == 3 || ch == 4) && !Info)
+			{
+				/* B-channel used for B3 connections (ch==0), or no B channel    */
+				/* is used (ch==2) or perm. connection (3) is used  do a CALL    */
+				if (noCh) Info = add_b1(plci, &parms[5], 2, 0);    /* no resource    */
+				else     Info = add_b1(plci, &parms[5], ch, 0);
+				add_s(plci, OAD, &parms[2]);
+				add_s(plci, OSA, &parms[4]);
+				add_s(plci, BC, &parms[6]);
+				add_s(plci, LLC, &parms[7]);
+				add_s(plci, HLC, &parms[8]);
+				if (a->Info_Mask[appl->Id - 1] & 0x200)
+				{
+					/* early B3 connect (CIP mask bit 9) no release after a disc */
+					add_p(plci, LLI, "\x01\x01");
+				}
+				if (GET_WORD(parms[0].info) < 29) {
+					add_p(plci, BC, cip_bc[GET_WORD(parms[0].info)][a->u_law]);
+					add_p(plci, HLC, cip_hlc[GET_WORD(parms[0].info)]);
+				}
+				add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+				sig_req(plci, ASSIGN, DSIG_ID);
+			}
+			else if (ch == 1) {
+
+				/* D-Channel used for B3 connections */
+				plci->Sig.Id = 0xff;
+				Info = 0;
+			}
+
+			if (!Info && ch != 2 && !noCh) {
+				Info = add_b23(plci, &parms[5]);
+				if (!Info) {
+					if (!(plci->tel && !plci->adv_nl))nl_req_ncci(plci, ASSIGN, 0);
+				}
+			}
+
+			if (!Info)
+			{
+				if (ch == 0 || ch == 2 || ch == 3 || noCh || ch == 4)
+				{
+					if (plci->spoofed_msg == SPOOFING_REQUIRED)
+					{
+						api_save_msg(parms, "wsssssssss", &plci->saved_msg);
+						plci->spoofed_msg = CALL_REQ;
+						plci->internal_command = BLOCK_PLCI;
+						plci->command = 0;
+						dbug(1, dprintf("Spoof"));
+						send_req(plci);
+						return false;
+					}
+					if (ch == 4)add_p(plci, CHI, p_chi);
+					add_s(plci, CPN, &parms[1]);
+					add_s(plci, DSA, &parms[3]);
+					if (noCh) add_p(plci, ESC, "\x02\x18\xfd");  /* D-channel, no B-L3 */
+					add_ai(plci, &parms[9]);
+					if (!dir)sig_req(plci, CALL_REQ, 0);
+					else
+					{
+						plci->command = PERM_LIST_REQ;
+						plci->appl = appl;
+						sig_req(plci, LISTEN_REQ, 0);
+						send_req(plci);
+						return false;
+					}
+				}
+				send_req(plci);
+				return false;
+			}
+			plci->Id = 0;
+		}
+	}
+	sendf(appl,
+	      _CONNECT_R | CONFIRM,
+	      Id,
+	      Number,
+	      "w", Info);
+	return 2;
 }
 
 static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word i, Info;
-  word Reject;
-  static byte cau_t[] = {0,0,0x90,0x91,0xac,0x9d,0x86,0xd8,0x9b};
-  static byte esc_t[] = {0x03,0x08,0x00,0x00};
-  API_PARSE * ai;
-    API_PARSE ai_parms[5];
-  word ch=0;
-
-  if(!plci) {
-    dbug(1,dprintf("connect_res(no plci)"));
-    return 0;  /* no plci, no send */
-  }
-
-  dbug(1,dprintf("connect_res(State=0x%x)",plci->State));
-  for(i=0;i<5;i++) ai_parms[i].length = 0;
-  ai = &parms[5];
-  dbug(1,dprintf("ai->length=%d",ai->length));
-
-  if(ai->length)
-  {
-    if(!api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms))
-    {
-      dbug(1,dprintf("ai_parms[0].length=%d/0x%x",ai_parms[0].length,GET_WORD(ai_parms[0].info+1)));
-      ch = 0;
-      if(ai_parms[0].length)
-      {
-        ch = GET_WORD(ai_parms[0].info+1);
-        dbug(1,dprintf("BCH-I=0x%x",ch));
-      }
-    }
-  }
-
-  if(plci->State==INC_CON_CONNECTED_ALERT)
-  {
-    dbug(1,dprintf("Connected Alert Call_Res"));
-    if (a->Info_Mask[appl->Id-1] & 0x200)
-    {
-    /* early B3 connect (CIP mask bit 9) no release after a disc */
-      add_p(plci,LLI,"\x01\x01");
-    }
-    add_s(plci, CONN_NR, &parms[2]);
-    add_s(plci, LLC, &parms[4]);
-    add_ai(plci, &parms[5]);
-    plci->State = INC_CON_ACCEPT;
-    sig_req(plci, CALL_RES,0);
-    return 1;
-  }
-  else if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT) {
-    clear_c_ind_mask_bit (plci, (word)(appl->Id-1));
-    dump_c_ind_mask (plci);
-    Reject = GET_WORD(parms[0].info);
-    dbug(1,dprintf("Reject=0x%x",Reject));
-    if(Reject) 
-    {
-      if(c_ind_mask_empty (plci)) 
-      {
-        if((Reject&0xff00)==0x3400) 
-        {
-          esc_t[2] = ((byte)(Reject&0x00ff)) | 0x80;
-          add_p(plci,ESC,esc_t);
-          add_ai(plci, &parms[5]);
-          sig_req(plci,REJECT,0);
-        }      
-        else if(Reject==1 || Reject>9) 
-        {
-          add_ai(plci, &parms[5]);
-          sig_req(plci,HANGUP,0);
-        }
-        else 
-        {
-          esc_t[2] = cau_t[(Reject&0x000f)];
-          add_p(plci,ESC,esc_t);
-          add_ai(plci, &parms[5]);
-          sig_req(plci,REJECT,0);
-        }
-        plci->appl = appl;
-      }
-      else 
-      {
-        sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
-      }
-    }
-    else {
-      plci->appl = appl;
-      if(Id & EXT_CONTROLLER){
-        if(AdvCodecSupport(a, plci, appl, 0)){
-          dbug(1,dprintf("connect_res(error from AdvCodecSupport)"));
-          sig_req(plci,HANGUP,0);
-          return 1;
-        }
-        if(plci->tel == ADV_VOICE && a->AdvCodecPLCI)
-        {
-          Info = add_b23(plci, &parms[1]);
-          if (Info)
-          {
-            dbug(1,dprintf("connect_res(error from add_b23)"));
-            sig_req(plci,HANGUP,0);
-            return 1;
-          }
-          if(plci->adv_nl)
-          {
-            nl_req_ncci(plci, ASSIGN, 0);
-          }
-        }
-      }
-      else
-      {
-        plci->tel = 0;
-        if(ch!=2)
-        {
-          Info = add_b23(plci, &parms[1]);
-          if (Info)
-          {
-            dbug(1,dprintf("connect_res(error from add_b23 2)"));
-            sig_req(plci,HANGUP,0);
-            return 1;
-          }
-        }
-        nl_req_ncci(plci, ASSIGN, 0);
-      }
-
-      if(plci->spoofed_msg==SPOOFING_REQUIRED)
-      {
-        api_save_msg(parms, "wsssss", &plci->saved_msg);
-        plci->spoofed_msg = CALL_RES;
-        plci->internal_command = BLOCK_PLCI;
-        plci->command = 0;
-        dbug(1,dprintf("Spoof"));
-      }
-      else
-      {
-        add_b1 (plci, &parms[1], ch, plci->B1_facilities);
-        if (a->Info_Mask[appl->Id-1] & 0x200)
-        {
-          /* early B3 connect (CIP mask bit 9) no release after a disc */
-          add_p(plci,LLI,"\x01\x01");
-        }
-        add_s(plci, CONN_NR, &parms[2]);
-        add_s(plci, LLC, &parms[4]);
-        add_ai(plci, &parms[5]);
-        plci->State = INC_CON_ACCEPT;
-        sig_req(plci, CALL_RES,0);
-      }
-
-      for(i=0; i<max_appl; i++) {
-        if(test_c_ind_mask_bit (plci, i)) {
-          sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
-        }
-      }
-    }
-  }
-  return 1;
+	word i, Info;
+	word Reject;
+	static byte cau_t[] = {0, 0, 0x90, 0x91, 0xac, 0x9d, 0x86, 0xd8, 0x9b};
+	static byte esc_t[] = {0x03, 0x08, 0x00, 0x00};
+	API_PARSE *ai;
+	API_PARSE ai_parms[5];
+	word ch = 0;
+
+	if (!plci) {
+		dbug(1, dprintf("connect_res(no plci)"));
+		return 0;  /* no plci, no send */
+	}
+
+	dbug(1, dprintf("connect_res(State=0x%x)", plci->State));
+	for (i = 0; i < 5; i++) ai_parms[i].length = 0;
+	ai = &parms[5];
+	dbug(1, dprintf("ai->length=%d", ai->length));
+
+	if (ai->length)
+	{
+		if (!api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
+		{
+			dbug(1, dprintf("ai_parms[0].length=%d/0x%x", ai_parms[0].length, GET_WORD(ai_parms[0].info + 1)));
+			ch = 0;
+			if (ai_parms[0].length)
+			{
+				ch = GET_WORD(ai_parms[0].info + 1);
+				dbug(1, dprintf("BCH-I=0x%x", ch));
+			}
+		}
+	}
+
+	if (plci->State == INC_CON_CONNECTED_ALERT)
+	{
+		dbug(1, dprintf("Connected Alert Call_Res"));
+		if (a->Info_Mask[appl->Id - 1] & 0x200)
+		{
+			/* early B3 connect (CIP mask bit 9) no release after a disc */
+			add_p(plci, LLI, "\x01\x01");
+		}
+		add_s(plci, CONN_NR, &parms[2]);
+		add_s(plci, LLC, &parms[4]);
+		add_ai(plci, &parms[5]);
+		plci->State = INC_CON_ACCEPT;
+		sig_req(plci, CALL_RES, 0);
+		return 1;
+	}
+	else if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) {
+		clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
+		dump_c_ind_mask(plci);
+		Reject = GET_WORD(parms[0].info);
+		dbug(1, dprintf("Reject=0x%x", Reject));
+		if (Reject)
+		{
+			if (c_ind_mask_empty(plci))
+			{
+				if ((Reject & 0xff00) == 0x3400)
+				{
+					esc_t[2] = ((byte)(Reject & 0x00ff)) | 0x80;
+					add_p(plci, ESC, esc_t);
+					add_ai(plci, &parms[5]);
+					sig_req(plci, REJECT, 0);
+				}
+				else if (Reject == 1 || Reject > 9)
+				{
+					add_ai(plci, &parms[5]);
+					sig_req(plci, HANGUP, 0);
+				}
+				else
+				{
+					esc_t[2] = cau_t[(Reject&0x000f)];
+					add_p(plci, ESC, esc_t);
+					add_ai(plci, &parms[5]);
+					sig_req(plci, REJECT, 0);
+				}
+				plci->appl = appl;
+			}
+			else
+			{
+				sendf(appl, _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
+			}
+		}
+		else {
+			plci->appl = appl;
+			if (Id & EXT_CONTROLLER) {
+				if (AdvCodecSupport(a, plci, appl, 0)) {
+					dbug(1, dprintf("connect_res(error from AdvCodecSupport)"));
+					sig_req(plci, HANGUP, 0);
+					return 1;
+				}
+				if (plci->tel == ADV_VOICE && a->AdvCodecPLCI)
+				{
+					Info = add_b23(plci, &parms[1]);
+					if (Info)
+					{
+						dbug(1, dprintf("connect_res(error from add_b23)"));
+						sig_req(plci, HANGUP, 0);
+						return 1;
+					}
+					if (plci->adv_nl)
+					{
+						nl_req_ncci(plci, ASSIGN, 0);
+					}
+				}
+			}
+			else
+			{
+				plci->tel = 0;
+				if (ch != 2)
+				{
+					Info = add_b23(plci, &parms[1]);
+					if (Info)
+					{
+						dbug(1, dprintf("connect_res(error from add_b23 2)"));
+						sig_req(plci, HANGUP, 0);
+						return 1;
+					}
+				}
+				nl_req_ncci(plci, ASSIGN, 0);
+			}
+
+			if (plci->spoofed_msg == SPOOFING_REQUIRED)
+			{
+				api_save_msg(parms, "wsssss", &plci->saved_msg);
+				plci->spoofed_msg = CALL_RES;
+				plci->internal_command = BLOCK_PLCI;
+				plci->command = 0;
+				dbug(1, dprintf("Spoof"));
+			}
+			else
+			{
+				add_b1(plci, &parms[1], ch, plci->B1_facilities);
+				if (a->Info_Mask[appl->Id - 1] & 0x200)
+				{
+					/* early B3 connect (CIP mask bit 9) no release after a disc */
+					add_p(plci, LLI, "\x01\x01");
+				}
+				add_s(plci, CONN_NR, &parms[2]);
+				add_s(plci, LLC, &parms[4]);
+				add_ai(plci, &parms[5]);
+				plci->State = INC_CON_ACCEPT;
+				sig_req(plci, CALL_RES, 0);
+			}
+
+			for (i = 0; i < max_appl; i++) {
+				if (test_c_ind_mask_bit(plci, i)) {
+					sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
+				}
+			}
+		}
+	}
+	return 1;
 }
 
 static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			  PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  dbug(1,dprintf("connect_a_res"));
-  return false;
+	dbug(1, dprintf("connect_a_res"));
+	return false;
 }
 
 static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			   PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  word Info;
-  word i;
-
-  dbug(1,dprintf("disconnect_req"));
-
-  Info = _WRONG_IDENTIFIER;
-
-  if(plci)
-  {
-    if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT)
-    {
-      clear_c_ind_mask_bit (plci, (word)(appl->Id-1));
-      plci->appl = appl;
-      for(i=0; i<max_appl; i++)
-      {
-        if(test_c_ind_mask_bit (plci, i))
-          sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
-      }
-      plci->State = OUTG_DIS_PENDING;
-    }
-    if(plci->Sig.Id && plci->appl)
-    {
-      Info = 0;
-        if(plci->Sig.Id!=0xff)
-        {
-          if(plci->State!=INC_DIS_PENDING)
-          {
-            add_ai(plci, &msg[0]);
-            sig_req(plci,HANGUP,0);
-            plci->State = OUTG_DIS_PENDING;
-            return 1;
-          }
-        }
-        else
-        {
-          if (plci->NL.Id && !plci->nl_remove_id)
-          {
-            mixer_remove (plci);
-            nl_req_ncci(plci,REMOVE,0);
-          sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0);
-          sendf(appl, _DISCONNECT_I, Id, 0, "w", 0);
-          plci->State = INC_DIS_PENDING;
-          }
-          return 1;
-        }
-      }
-    }
-
-  if(!appl)  return false;
-  sendf(appl, _DISCONNECT_R|CONFIRM, Id, Number, "w",Info);
-  return false;
+	word Info;
+	word i;
+
+	dbug(1, dprintf("disconnect_req"));
+
+	Info = _WRONG_IDENTIFIER;
+
+	if (plci)
+	{
+		if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
+		{
+			clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
+			plci->appl = appl;
+			for (i = 0; i < max_appl; i++)
+			{
+				if (test_c_ind_mask_bit(plci, i))
+					sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
+			}
+			plci->State = OUTG_DIS_PENDING;
+		}
+		if (plci->Sig.Id && plci->appl)
+		{
+			Info = 0;
+			if (plci->Sig.Id != 0xff)
+			{
+				if (plci->State != INC_DIS_PENDING)
+				{
+					add_ai(plci, &msg[0]);
+					sig_req(plci, HANGUP, 0);
+					plci->State = OUTG_DIS_PENDING;
+					return 1;
+				}
+			}
+			else
+			{
+				if (plci->NL.Id && !plci->nl_remove_id)
+				{
+					mixer_remove(plci);
+					nl_req_ncci(plci, REMOVE, 0);
+					sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0);
+					sendf(appl, _DISCONNECT_I, Id, 0, "w", 0);
+					plci->State = INC_DIS_PENDING;
+				}
+				return 1;
+			}
+		}
+	}
+
+	if (!appl)  return false;
+	sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", Info);
+	return false;
 }
 
 static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			   PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  dbug(1,dprintf("disconnect_res"));
-  if(plci)
-  {
-        /* clear ind mask bit, just in case of collsion of          */
-        /* DISCONNECT_IND and CONNECT_RES                           */
-    clear_c_ind_mask_bit (plci, (word)(appl->Id-1));
-    ncci_free_receive_buffers (plci, 0);
-    if(plci_remove_check(plci))
-    {
-      return 0;
-    }
-    if(plci->State==INC_DIS_PENDING
-    || plci->State==SUSPENDING) {
-      if(c_ind_mask_empty (plci)) {
-        if(plci->State!=SUSPENDING)plci->State = IDLE;
-        dbug(1,dprintf("chs=%d",plci->channels));
-        if(!plci->channels) {
-          plci_remove(plci);
-        }
-      }
-    }
-  }
-  return 0;
+	dbug(1, dprintf("disconnect_res"));
+	if (plci)
+	{
+		/* clear ind mask bit, just in case of collsion of          */
+		/* DISCONNECT_IND and CONNECT_RES                           */
+		clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
+		ncci_free_receive_buffers(plci, 0);
+		if (plci_remove_check(plci))
+		{
+			return 0;
+		}
+		if (plci->State == INC_DIS_PENDING
+		    || plci->State == SUSPENDING) {
+			if (c_ind_mask_empty(plci)) {
+				if (plci->State != SUSPENDING) plci->State = IDLE;
+				dbug(1, dprintf("chs=%d", plci->channels));
+				if (!plci->channels) {
+					plci_remove(plci);
+				}
+			}
+		}
+	}
+	return 0;
 }
 
 static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 		       PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word Info;
-  byte i;
-
-  dbug(1,dprintf("listen_req(Appl=0x%x)",appl->Id));
-
-  Info = _WRONG_IDENTIFIER;
-  if(a) {
-    Info = 0;
-    a->Info_Mask[appl->Id-1] = GET_DWORD(parms[0].info);
-    a->CIP_Mask[appl->Id-1] = GET_DWORD(parms[1].info);
-    dbug(1,dprintf("CIP_MASK=0x%lx",GET_DWORD(parms[1].info)));
-    if (a->Info_Mask[appl->Id-1] & 0x200){ /* early B3 connect provides */
-      a->Info_Mask[appl->Id-1] |=  0x10;   /* call progression infos    */
-    }
-
-    /* check if external controller listen and switch listen on or off*/
-    if(Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)){
-      if(a->profile.Global_Options & ON_BOARD_CODEC) {
-        dummy_plci.State = IDLE;
-        a->codec_listen[appl->Id-1] = &dummy_plci;
-        a->TelOAD[0] = (byte)(parms[3].length);
-        for(i=1;parms[3].length>=i && i<22;i++) {
-          a->TelOAD[i] = parms[3].info[i];
-        }
-        a->TelOAD[i] = 0;
-        a->TelOSA[0] = (byte)(parms[4].length);
-        for(i=1;parms[4].length>=i && i<22;i++) {
-          a->TelOSA[i] = parms[4].info[i];
-        }
-        a->TelOSA[i] = 0;
-      }
-      else Info = 0x2002; /* wrong controller, codec not supported */
-    }
-    else{               /* clear listen */
-      a->codec_listen[appl->Id-1] = (PLCI   *)0;
-    }
-  }
-  sendf(appl,
-        _LISTEN_R|CONFIRM,
-        Id,
-        Number,
-        "w",Info);
-
-  if (a) listen_check(a);
-  return false;
+	word Info;
+	byte i;
+
+	dbug(1, dprintf("listen_req(Appl=0x%x)", appl->Id));
+
+	Info = _WRONG_IDENTIFIER;
+	if (a) {
+		Info = 0;
+		a->Info_Mask[appl->Id - 1] = GET_DWORD(parms[0].info);
+		a->CIP_Mask[appl->Id - 1] = GET_DWORD(parms[1].info);
+		dbug(1, dprintf("CIP_MASK=0x%lx", GET_DWORD(parms[1].info)));
+		if (a->Info_Mask[appl->Id - 1] & 0x200) { /* early B3 connect provides */
+			a->Info_Mask[appl->Id - 1] |=  0x10;   /* call progression infos    */
+		}
+
+		/* check if external controller listen and switch listen on or off*/
+		if (Id&EXT_CONTROLLER && GET_DWORD(parms[1].info)) {
+			if (a->profile.Global_Options & ON_BOARD_CODEC) {
+				dummy_plci.State = IDLE;
+				a->codec_listen[appl->Id - 1] = &dummy_plci;
+				a->TelOAD[0] = (byte)(parms[3].length);
+				for (i = 1; parms[3].length >= i && i < 22; i++) {
+					a->TelOAD[i] = parms[3].info[i];
+				}
+				a->TelOAD[i] = 0;
+				a->TelOSA[0] = (byte)(parms[4].length);
+				for (i = 1; parms[4].length >= i && i < 22; i++) {
+					a->TelOSA[i] = parms[4].info[i];
+				}
+				a->TelOSA[i] = 0;
+			}
+			else Info = 0x2002; /* wrong controller, codec not supported */
+		}
+		else{               /* clear listen */
+			a->codec_listen[appl->Id - 1] = (PLCI *)0;
+		}
+	}
+	sendf(appl,
+	      _LISTEN_R | CONFIRM,
+	      Id,
+	      Number,
+	      "w", Info);
+
+	if (a) listen_check(a);
+	return false;
 }
 
 static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 		     PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  word i;
-  API_PARSE * ai;
-  PLCI   * rc_plci = NULL;
-    API_PARSE ai_parms[5];
-  word Info = 0;
-
-  dbug(1,dprintf("info_req"));
-  for(i=0;i<5;i++) ai_parms[i].length = 0;
-
-  ai = &msg[1];
-
-  if(ai->length)
-  {
-    if(api_parse(&ai->info[1],(word)ai->length,"ssss",ai_parms))
-    {
-      dbug(1,dprintf("AddInfo wrong"));
-      Info = _WRONG_MESSAGE_FORMAT;
-    }
-  }
-  if(!a) Info = _WRONG_STATE;
-
-  if(!Info && plci)
-  {                /* no fac, with CPN, or KEY */
-    rc_plci = plci;
-    if(!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length) )
-    {
-      /* overlap sending option */
-      dbug(1,dprintf("OvlSnd"));
-      add_s(plci,CPN,&msg[0]);
-      add_s(plci,KEY,&ai_parms[1]);
-      sig_req(plci,INFO_REQ,0);
-      send_req(plci);
-      return false;
-    }
-
-    if(plci->State && ai_parms[2].length)
-    {
-      /* User_Info option */
-      dbug(1,dprintf("UUI"));
-      add_s(plci,UUI,&ai_parms[2]);
-      sig_req(plci,USER_DATA,0);
-    }
-    else if(plci->State && ai_parms[3].length)
-    {
-      /* Facility option */
-      dbug(1,dprintf("FAC"));
-      add_s(plci,CPN,&msg[0]);
-      add_ai(plci, &msg[1]);
-      sig_req(plci,FACILITY_REQ,0);
-    }
-    else
-    {
-      Info = _WRONG_STATE;
-    }
-  }
-  else if((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info)
-  {
-    /* NCR_Facility option -> send UUI and Keypad too */
-    dbug(1,dprintf("NCR_FAC"));
-    if((i=get_plci(a)))
-    {
-      rc_plci = &a->plci[i-1];
-      appl->NullCREnable  = true;
-      rc_plci->internal_command = C_NCR_FAC_REQ;
-      rc_plci->appl = appl;
-      add_p(rc_plci,CAI,"\x01\x80");
-      add_p(rc_plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-      sig_req(rc_plci,ASSIGN,DSIG_ID);
-      send_req(rc_plci);
-    }
-    else
-    {
-      Info = _OUT_OF_PLCI;
-    }
-
-    if(!Info)
-    {
-      add_s(rc_plci,CPN,&msg[0]);
-      add_ai(rc_plci, &msg[1]);
-      sig_req(rc_plci,NCR_FACILITY,0);
-      send_req(rc_plci);
-      return false;
-     /* for application controlled supplementary services    */
-    }
-  }
-
-  if (!rc_plci)
-  {
-    Info = _WRONG_MESSAGE_FORMAT;
-  }
-
-  if(!Info)
-  {
-    send_req(rc_plci);
-  }
-  else
-  {  /* appl is not assigned to a PLCI or error condition */
-    dbug(1,dprintf("localInfoCon"));
-    sendf(appl,
-          _INFO_R|CONFIRM,
-          Id,
-          Number,
-          "w",Info);
-  }
-  return false;
+	word i;
+	API_PARSE *ai;
+	PLCI *rc_plci = NULL;
+	API_PARSE ai_parms[5];
+	word Info = 0;
+
+	dbug(1, dprintf("info_req"));
+	for (i = 0; i < 5; i++) ai_parms[i].length = 0;
+
+	ai = &msg[1];
+
+	if (ai->length)
+	{
+		if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
+		{
+			dbug(1, dprintf("AddInfo wrong"));
+			Info = _WRONG_MESSAGE_FORMAT;
+		}
+	}
+	if (!a) Info = _WRONG_STATE;
+
+	if (!Info && plci)
+	{                /* no fac, with CPN, or KEY */
+		rc_plci = plci;
+		if (!ai_parms[3].length && plci->State && (msg[0].length || ai_parms[1].length))
+		{
+			/* overlap sending option */
+			dbug(1, dprintf("OvlSnd"));
+			add_s(plci, CPN, &msg[0]);
+			add_s(plci, KEY, &ai_parms[1]);
+			sig_req(plci, INFO_REQ, 0);
+			send_req(plci);
+			return false;
+		}
+
+		if (plci->State && ai_parms[2].length)
+		{
+			/* User_Info option */
+			dbug(1, dprintf("UUI"));
+			add_s(plci, UUI, &ai_parms[2]);
+			sig_req(plci, USER_DATA, 0);
+		}
+		else if (plci->State && ai_parms[3].length)
+		{
+			/* Facility option */
+			dbug(1, dprintf("FAC"));
+			add_s(plci, CPN, &msg[0]);
+			add_ai(plci, &msg[1]);
+			sig_req(plci, FACILITY_REQ, 0);
+		}
+		else
+		{
+			Info = _WRONG_STATE;
+		}
+	}
+	else if ((ai_parms[1].length || ai_parms[2].length || ai_parms[3].length) && !Info)
+	{
+		/* NCR_Facility option -> send UUI and Keypad too */
+		dbug(1, dprintf("NCR_FAC"));
+		if ((i = get_plci(a)))
+		{
+			rc_plci = &a->plci[i - 1];
+			appl->NullCREnable = true;
+			rc_plci->internal_command = C_NCR_FAC_REQ;
+			rc_plci->appl = appl;
+			add_p(rc_plci, CAI, "\x01\x80");
+			add_p(rc_plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+			sig_req(rc_plci, ASSIGN, DSIG_ID);
+			send_req(rc_plci);
+		}
+		else
+		{
+			Info = _OUT_OF_PLCI;
+		}
+
+		if (!Info)
+		{
+			add_s(rc_plci, CPN, &msg[0]);
+			add_ai(rc_plci, &msg[1]);
+			sig_req(rc_plci, NCR_FACILITY, 0);
+			send_req(rc_plci);
+			return false;
+			/* for application controlled supplementary services    */
+		}
+	}
+
+	if (!rc_plci)
+	{
+		Info = _WRONG_MESSAGE_FORMAT;
+	}
+
+	if (!Info)
+	{
+		send_req(rc_plci);
+	}
+	else
+	{  /* appl is not assigned to a PLCI or error condition */
+		dbug(1, dprintf("localInfoCon"));
+		sendf(appl,
+		      _INFO_R | CONFIRM,
+		      Id,
+		      Number,
+		      "w", Info);
+	}
+	return false;
 }
 
 static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 		     PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  dbug(1,dprintf("info_res"));
-  return false;
+	dbug(1, dprintf("info_res"));
+	return false;
 }
 
 static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 		      PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  word Info;
-  byte ret;
-
-  dbug(1,dprintf("alert_req"));
-
-  Info = _WRONG_IDENTIFIER;
-  ret = false;
-  if(plci) {
-    Info = _ALERT_IGNORED;
-    if(plci->State!=INC_CON_ALERT) {
-      Info = _WRONG_STATE;
-      if(plci->State==INC_CON_PENDING) {
-        Info = 0;
-        plci->State=INC_CON_ALERT;
-        add_ai(plci, &msg[0]);
-        sig_req(plci,CALL_ALERT,0);
-        ret = 1;
-      }
-    }
-  }
-  sendf(appl,
-        _ALERT_R|CONFIRM,
-        Id,
-        Number,
-        "w",Info);
-  return ret;
+	word Info;
+	byte ret;
+
+	dbug(1, dprintf("alert_req"));
+
+	Info = _WRONG_IDENTIFIER;
+	ret = false;
+	if (plci) {
+		Info = _ALERT_IGNORED;
+		if (plci->State != INC_CON_ALERT) {
+			Info = _WRONG_STATE;
+			if (plci->State == INC_CON_PENDING) {
+				Info = 0;
+				plci->State = INC_CON_ALERT;
+				add_ai(plci, &msg[0]);
+				sig_req(plci, CALL_ALERT, 0);
+				ret = 1;
+			}
+		}
+	}
+	sendf(appl,
+	      _ALERT_R | CONFIRM,
+	      Id,
+	      Number,
+	      "w", Info);
+	return ret;
 }
 
 static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			 PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  word Info = 0;
-  word i    = 0;
-
-  word selector;
-  word SSreq;
-  long relatedPLCIvalue;
-  DIVA_CAPI_ADAPTER   * relatedadapter;
-  byte * SSparms  = "";
-    byte RCparms[]  = "\x05\x00\x00\x02\x00\x00";
-    byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
-  API_PARSE * parms;
-    API_PARSE ss_parms[11];
-  PLCI   *rplci;
-    byte cai[15];
-  dword d;
-    API_PARSE dummy;
-
-  dbug(1,dprintf("facility_req"));
-  for(i=0;i<9;i++) ss_parms[i].length = 0;
-
-  parms = &msg[1];
-
-  if(!a)
-  {
-    dbug(1,dprintf("wrong Ctrl"));
-    Info = _WRONG_IDENTIFIER;
-  }
-
-  selector = GET_WORD(msg[0].info);
-
-  if(!Info)
-  {
-    switch(selector)
-    {
-      case SELECTOR_HANDSET:
-        Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT);
-        break;
-
-      case SELECTOR_SU_SERV:
-        if(!msg[1].length)
-        {
-          Info = _WRONG_MESSAGE_FORMAT;
-          break;
-        }
-        SSreq = GET_WORD(&(msg[1].info[1]));
-        PUT_WORD(&RCparms[1],SSreq);
-        SSparms = RCparms;
-        switch(SSreq)
-        {
-          case S_GET_SUPPORTED_SERVICES:
-            if((i=get_plci(a)))
-            {
-              rplci = &a->plci[i-1];
-              rplci->appl = appl;
-              add_p(rplci,CAI,"\x01\x80");
-              add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-              sig_req(rplci,ASSIGN,DSIG_ID);
-              send_req(rplci);
-            }
-            else
-            {
-              PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
-              SSparms = (byte *)SSstruct;
-              break;
-            }
-            rplci->internal_command = GETSERV_REQ_PEND;
-            rplci->number = Number;
-            rplci->appl = appl;
-            sig_req(rplci,S_SUPPORTED,0);
-            send_req(rplci);
-            return false;
-            break;
-
-          case S_LISTEN:
-            if(parms->length==7)
-            {
-              if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
-              {
-                dbug(1,dprintf("format wrong"));
-                Info = _WRONG_MESSAGE_FORMAT;
-                break;
-              }
-            }
-            else
-            {
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            a->Notification_Mask[appl->Id-1] = GET_DWORD(ss_parms[2].info);
-            if(a->Notification_Mask[appl->Id-1] & SMASK_MWI) /* MWI active? */
-            {
-              if((i=get_plci(a)))
-              {
-                rplci = &a->plci[i-1];
-                rplci->appl = appl;
-                add_p(rplci,CAI,"\x01\x80");
-                add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-                sig_req(rplci,ASSIGN,DSIG_ID);
-                send_req(rplci);
-              }
-              else
-              {
-                break;
-              }
-              rplci->internal_command = GET_MWI_STATE;
-              rplci->number = Number;
-              sig_req(rplci,MWI_POLL,0);
-              send_req(rplci);
-            }
-            break;
-
-          case S_HOLD:
-            api_parse(&parms->info[1],(word)parms->length,"ws",ss_parms);
-            if(plci && plci->State && plci->SuppState==IDLE)
-            {
-              plci->SuppState = HOLD_REQUEST;
-              plci->command = C_HOLD_REQ;
-              add_s(plci,CAI,&ss_parms[1]);
-              sig_req(plci,CALL_HOLD,0);
-              send_req(plci);
-              return false;
-            }
-            else Info = 0x3010;                    /* wrong state           */
-            break;
-          case S_RETRIEVE:
-            if(plci && plci->State && plci->SuppState==CALL_HELD)
-            {
-              if(Id & EXT_CONTROLLER)
-              {
-                if(AdvCodecSupport(a, plci, appl, 0))
-                {
-                  Info = 0x3010;                    /* wrong state           */
-                  break;
-                }
-              }
-              else plci->tel = 0;
-
-              plci->SuppState = RETRIEVE_REQUEST;
-              plci->command = C_RETRIEVE_REQ;
-              if(plci->spoofed_msg==SPOOFING_REQUIRED)
-              {
-                plci->spoofed_msg = CALL_RETRIEVE;
-                plci->internal_command = BLOCK_PLCI;
-                plci->command = 0;
-                dbug(1,dprintf("Spoof"));
-                return false;
-              }
-              else
-              {
-                sig_req(plci,CALL_RETRIEVE,0);
-                send_req(plci);
-                return false;
-              }
-            }
-            else Info = 0x3010;                    /* wrong state           */
-            break;
-          case S_SUSPEND:
-            if(parms->length)
-            {
-              if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms))
-              {
-                dbug(1,dprintf("format wrong"));
-                Info = _WRONG_MESSAGE_FORMAT;
-                break;
-              }
-            }
-            if(plci && plci->State)
-            {
-              add_s(plci,CAI,&ss_parms[2]);
-              plci->command = SUSPEND_REQ;
-              sig_req(plci,SUSPEND,0);
-              plci->State = SUSPENDING;
-              send_req(plci);
-            }
-            else Info = 0x3010;                    /* wrong state           */
-            break;
-
-          case S_RESUME:
-            if(!(i=get_plci(a)) )
-            {
-              Info = _OUT_OF_PLCI;
-              break;
-            }
-            rplci = &a->plci[i-1];
-            rplci->appl = appl;
-            rplci->number = Number;
-            rplci->tel = 0;
-            rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
-            /* check 'external controller' bit for codec support */
-            if(Id & EXT_CONTROLLER)
-            {
-              if(AdvCodecSupport(a, rplci, appl, 0) )
-              {
-                rplci->Id = 0;
-                Info = 0x300A;
-                break;
-              }
-            }
-            if(parms->length)
-            {
-              if(api_parse(&parms->info[1],(word)parms->length,"wbs",ss_parms))
-              {
-                dbug(1,dprintf("format wrong"));
-                rplci->Id = 0;
-                Info = _WRONG_MESSAGE_FORMAT;
-                break;
-              }
-            }
-            dummy.length = 0;
-            dummy.info = "\x00";
-            add_b1(rplci, &dummy, 0, 0);
-            if (a->Info_Mask[appl->Id-1] & 0x200)
-            {
-              /* early B3 connect (CIP mask bit 9) no release after a disc */
-              add_p(rplci,LLI,"\x01\x01");
-            }
-            add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-            sig_req(rplci,ASSIGN,DSIG_ID);
-            send_req(rplci);
-            add_s(rplci,CAI,&ss_parms[2]);
-            rplci->command = RESUME_REQ;
-            sig_req(rplci,RESUME,0);
-            rplci->State = RESUMING;
-            send_req(rplci);
-            break;
-
-          case S_CONF_BEGIN: /* Request */
-          case S_CONF_DROP:
-          case S_CONF_ISOLATE:
-          case S_CONF_REATTACH:
-            if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
-            {
-              dbug(1,dprintf("format wrong"));
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            if(plci && plci->State && ((plci->SuppState==IDLE)||(plci->SuppState==CALL_HELD)))
-            {
-              d = GET_DWORD(ss_parms[2].info);     
-              if(d>=0x80)
-              {
-                dbug(1,dprintf("format wrong"));
-                Info = _WRONG_MESSAGE_FORMAT;
-                break;
-              }
-              plci->ptyState = (byte)SSreq;
-              plci->command = 0;
-              cai[0] = 2;
-              switch(SSreq)
-              {
-              case S_CONF_BEGIN:
-                  cai[1] = CONF_BEGIN;
-                  plci->internal_command = CONF_BEGIN_REQ_PEND;
-                  break;
-              case S_CONF_DROP:
-                  cai[1] = CONF_DROP;
-                  plci->internal_command = CONF_DROP_REQ_PEND;
-                  break;
-              case S_CONF_ISOLATE:
-                  cai[1] = CONF_ISOLATE;
-                  plci->internal_command = CONF_ISOLATE_REQ_PEND;
-                  break;
-              case S_CONF_REATTACH:
-                  cai[1] = CONF_REATTACH;
-                  plci->internal_command = CONF_REATTACH_REQ_PEND;
-                  break;
-              }
-              cai[2] = (byte)d; /* Conference Size resp. PartyId */
-              add_p(plci,CAI,cai);
-              sig_req(plci,S_SERVICE,0);
-              send_req(plci);
-              return false;
-            }
-            else Info = 0x3010;                    /* wrong state           */
-            break;
-
-          case S_ECT:
-          case S_3PTY_BEGIN:
-          case S_3PTY_END:
-          case S_CONF_ADD:
-            if(parms->length==7)
-            {
-              if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
-              {
-                dbug(1,dprintf("format wrong"));
-                Info = _WRONG_MESSAGE_FORMAT;
-                break;
-              }
-            }
-            else if(parms->length==8) /* workaround for the T-View-S */
-            {
-              if(api_parse(&parms->info[1],(word)parms->length,"wbdb",ss_parms))
-              {
-                dbug(1,dprintf("format wrong"));
-                Info = _WRONG_MESSAGE_FORMAT;
-                break;
-              }
-            }
-            else
-            {
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            if(!msg[1].length)
-            {
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            if (!plci)
-            {
-              Info = _WRONG_IDENTIFIER;
-              break;
-            }
-            relatedPLCIvalue = GET_DWORD(ss_parms[2].info);
-            relatedPLCIvalue &= 0x0000FFFF;
-            dbug(1,dprintf("PTY/ECT/addCONF,relPLCI=%lx",relatedPLCIvalue));
-            /* controller starts with 0 up to (max_adapter - 1) */
-            if (((relatedPLCIvalue & 0x7f) == 0)
-             || (MapController ((byte)(relatedPLCIvalue & 0x7f)) == 0)
-             || (MapController ((byte)(relatedPLCIvalue & 0x7f)) > max_adapter))
-            {
-              if(SSreq==S_3PTY_END)
-              {
-                dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
-                rplci = plci;
-              }
-              else
-              {
-                Info = 0x3010;                    /* wrong state           */
-                break;
-              }
-            }
-            else
-            {  
-              relatedadapter = &adapter[MapController ((byte)(relatedPLCIvalue & 0x7f))-1];
-              relatedPLCIvalue >>=8;
-              /* find PLCI PTR*/
-              for(i=0,rplci=NULL;i<relatedadapter->max_plci;i++)
-              {
-                if(relatedadapter->plci[i].Id == (byte)relatedPLCIvalue)
-                {
-                  rplci = &relatedadapter->plci[i];
-                }
-              }
-              if(!rplci || !relatedPLCIvalue)
-              {
-                if(SSreq==S_3PTY_END)
-                {
-                  dbug(1, dprintf("use 2nd PLCI=PLCI"));
-                  rplci = plci;
-                }
-                else
-                {
-                  Info = 0x3010;                    /* wrong state           */
-                  break;
-                }
-              }
-            }
+	word Info = 0;
+	word i    = 0;
+
+	word selector;
+	word SSreq;
+	long relatedPLCIvalue;
+	DIVA_CAPI_ADAPTER *relatedadapter;
+	byte *SSparms  = "";
+	byte RCparms[]  = "\x05\x00\x00\x02\x00\x00";
+	byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
+	API_PARSE *parms;
+	API_PARSE ss_parms[11];
+	PLCI *rplci;
+	byte cai[15];
+	dword d;
+	API_PARSE dummy;
+
+	dbug(1, dprintf("facility_req"));
+	for (i = 0; i < 9; i++) ss_parms[i].length = 0;
+
+	parms = &msg[1];
+
+	if (!a)
+	{
+		dbug(1, dprintf("wrong Ctrl"));
+		Info = _WRONG_IDENTIFIER;
+	}
+
+	selector = GET_WORD(msg[0].info);
+
+	if (!Info)
+	{
+		switch (selector)
+		{
+		case SELECTOR_HANDSET:
+			Info = AdvCodecSupport(a, plci, appl, HOOK_SUPPORT);
+			break;
+
+		case SELECTOR_SU_SERV:
+			if (!msg[1].length)
+			{
+				Info = _WRONG_MESSAGE_FORMAT;
+				break;
+			}
+			SSreq = GET_WORD(&(msg[1].info[1]));
+			PUT_WORD(&RCparms[1], SSreq);
+			SSparms = RCparms;
+			switch (SSreq)
+			{
+			case S_GET_SUPPORTED_SERVICES:
+				if ((i = get_plci(a)))
+				{
+					rplci = &a->plci[i - 1];
+					rplci->appl = appl;
+					add_p(rplci, CAI, "\x01\x80");
+					add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+					sig_req(rplci, ASSIGN, DSIG_ID);
+					send_req(rplci);
+				}
+				else
+				{
+					PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
+					SSparms = (byte *)SSstruct;
+					break;
+				}
+				rplci->internal_command = GETSERV_REQ_PEND;
+				rplci->number = Number;
+				rplci->appl = appl;
+				sig_req(rplci, S_SUPPORTED, 0);
+				send_req(rplci);
+				return false;
+				break;
+
+			case S_LISTEN:
+				if (parms->length == 7)
+				{
+					if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
+					{
+						dbug(1, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+				}
+				else
+				{
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				a->Notification_Mask[appl->Id - 1] = GET_DWORD(ss_parms[2].info);
+				if (a->Notification_Mask[appl->Id - 1] & SMASK_MWI) /* MWI active? */
+				{
+					if ((i = get_plci(a)))
+					{
+						rplci = &a->plci[i - 1];
+						rplci->appl = appl;
+						add_p(rplci, CAI, "\x01\x80");
+						add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						sig_req(rplci, ASSIGN, DSIG_ID);
+						send_req(rplci);
+					}
+					else
+					{
+						break;
+					}
+					rplci->internal_command = GET_MWI_STATE;
+					rplci->number = Number;
+					sig_req(rplci, MWI_POLL, 0);
+					send_req(rplci);
+				}
+				break;
+
+			case S_HOLD:
+				api_parse(&parms->info[1], (word)parms->length, "ws", ss_parms);
+				if (plci && plci->State && plci->SuppState == IDLE)
+				{
+					plci->SuppState = HOLD_REQUEST;
+					plci->command = C_HOLD_REQ;
+					add_s(plci, CAI, &ss_parms[1]);
+					sig_req(plci, CALL_HOLD, 0);
+					send_req(plci);
+					return false;
+				}
+				else Info = 0x3010;                    /* wrong state           */
+				break;
+			case S_RETRIEVE:
+				if (plci && plci->State && plci->SuppState == CALL_HELD)
+				{
+					if (Id & EXT_CONTROLLER)
+					{
+						if (AdvCodecSupport(a, plci, appl, 0))
+						{
+							Info = 0x3010;                    /* wrong state           */
+							break;
+						}
+					}
+					else plci->tel = 0;
+
+					plci->SuppState = RETRIEVE_REQUEST;
+					plci->command = C_RETRIEVE_REQ;
+					if (plci->spoofed_msg == SPOOFING_REQUIRED)
+					{
+						plci->spoofed_msg = CALL_RETRIEVE;
+						plci->internal_command = BLOCK_PLCI;
+						plci->command = 0;
+						dbug(1, dprintf("Spoof"));
+						return false;
+					}
+					else
+					{
+						sig_req(plci, CALL_RETRIEVE, 0);
+						send_req(plci);
+						return false;
+					}
+				}
+				else Info = 0x3010;                    /* wrong state           */
+				break;
+			case S_SUSPEND:
+				if (parms->length)
+				{
+					if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms))
+					{
+						dbug(1, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+				}
+				if (plci && plci->State)
+				{
+					add_s(plci, CAI, &ss_parms[2]);
+					plci->command = SUSPEND_REQ;
+					sig_req(plci, SUSPEND, 0);
+					plci->State = SUSPENDING;
+					send_req(plci);
+				}
+				else Info = 0x3010;                    /* wrong state           */
+				break;
+
+			case S_RESUME:
+				if (!(i = get_plci(a)))
+				{
+					Info = _OUT_OF_PLCI;
+					break;
+				}
+				rplci = &a->plci[i - 1];
+				rplci->appl = appl;
+				rplci->number = Number;
+				rplci->tel = 0;
+				rplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
+				/* check 'external controller' bit for codec support */
+				if (Id & EXT_CONTROLLER)
+				{
+					if (AdvCodecSupport(a, rplci, appl, 0))
+					{
+						rplci->Id = 0;
+						Info = 0x300A;
+						break;
+					}
+				}
+				if (parms->length)
+				{
+					if (api_parse(&parms->info[1], (word)parms->length, "wbs", ss_parms))
+					{
+						dbug(1, dprintf("format wrong"));
+						rplci->Id = 0;
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+				}
+				dummy.length = 0;
+				dummy.info = "\x00";
+				add_b1(rplci, &dummy, 0, 0);
+				if (a->Info_Mask[appl->Id - 1] & 0x200)
+				{
+					/* early B3 connect (CIP mask bit 9) no release after a disc */
+					add_p(rplci, LLI, "\x01\x01");
+				}
+				add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+				sig_req(rplci, ASSIGN, DSIG_ID);
+				send_req(rplci);
+				add_s(rplci, CAI, &ss_parms[2]);
+				rplci->command = RESUME_REQ;
+				sig_req(rplci, RESUME, 0);
+				rplci->State = RESUMING;
+				send_req(rplci);
+				break;
+
+			case S_CONF_BEGIN: /* Request */
+			case S_CONF_DROP:
+			case S_CONF_ISOLATE:
+			case S_CONF_REATTACH:
+				if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
+				{
+					dbug(1, dprintf("format wrong"));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (plci && plci->State && ((plci->SuppState == IDLE) || (plci->SuppState == CALL_HELD)))
+				{
+					d = GET_DWORD(ss_parms[2].info);
+					if (d >= 0x80)
+					{
+						dbug(1, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+					plci->ptyState = (byte)SSreq;
+					plci->command = 0;
+					cai[0] = 2;
+					switch (SSreq)
+					{
+					case S_CONF_BEGIN:
+						cai[1] = CONF_BEGIN;
+						plci->internal_command = CONF_BEGIN_REQ_PEND;
+						break;
+					case S_CONF_DROP:
+						cai[1] = CONF_DROP;
+						plci->internal_command = CONF_DROP_REQ_PEND;
+						break;
+					case S_CONF_ISOLATE:
+						cai[1] = CONF_ISOLATE;
+						plci->internal_command = CONF_ISOLATE_REQ_PEND;
+						break;
+					case S_CONF_REATTACH:
+						cai[1] = CONF_REATTACH;
+						plci->internal_command = CONF_REATTACH_REQ_PEND;
+						break;
+					}
+					cai[2] = (byte)d; /* Conference Size resp. PartyId */
+					add_p(plci, CAI, cai);
+					sig_req(plci, S_SERVICE, 0);
+					send_req(plci);
+					return false;
+				}
+				else Info = 0x3010;                    /* wrong state           */
+				break;
+
+			case S_ECT:
+			case S_3PTY_BEGIN:
+			case S_3PTY_END:
+			case S_CONF_ADD:
+				if (parms->length == 7)
+				{
+					if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
+					{
+						dbug(1, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+				}
+				else if (parms->length == 8) /* workaround for the T-View-S */
+				{
+					if (api_parse(&parms->info[1], (word)parms->length, "wbdb", ss_parms))
+					{
+						dbug(1, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+				}
+				else
+				{
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (!msg[1].length)
+				{
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (!plci)
+				{
+					Info = _WRONG_IDENTIFIER;
+					break;
+				}
+				relatedPLCIvalue = GET_DWORD(ss_parms[2].info);
+				relatedPLCIvalue &= 0x0000FFFF;
+				dbug(1, dprintf("PTY/ECT/addCONF,relPLCI=%lx", relatedPLCIvalue));
+				/* controller starts with 0 up to (max_adapter - 1) */
+				if (((relatedPLCIvalue & 0x7f) == 0)
+				    || (MapController((byte)(relatedPLCIvalue & 0x7f)) == 0)
+				    || (MapController((byte)(relatedPLCIvalue & 0x7f)) > max_adapter))
+				{
+					if (SSreq == S_3PTY_END)
+					{
+						dbug(1, dprintf("wrong Controller use 2nd PLCI=PLCI"));
+						rplci = plci;
+					}
+					else
+					{
+						Info = 0x3010;                    /* wrong state           */
+						break;
+					}
+				}
+				else
+				{
+					relatedadapter = &adapter[MapController((byte)(relatedPLCIvalue & 0x7f)) - 1];
+					relatedPLCIvalue >>= 8;
+					/* find PLCI PTR*/
+					for (i = 0, rplci = NULL; i < relatedadapter->max_plci; i++)
+					{
+						if (relatedadapter->plci[i].Id == (byte)relatedPLCIvalue)
+						{
+							rplci = &relatedadapter->plci[i];
+						}
+					}
+					if (!rplci || !relatedPLCIvalue)
+					{
+						if (SSreq == S_3PTY_END)
+						{
+							dbug(1, dprintf("use 2nd PLCI=PLCI"));
+							rplci = plci;
+						}
+						else
+						{
+							Info = 0x3010;                    /* wrong state           */
+							break;
+						}
+					}
+				}
 /*
-            dbug(1,dprintf("rplci:%x",rplci));
-            dbug(1,dprintf("plci:%x",plci));
-            dbug(1,dprintf("rplci->ptyState:%x",rplci->ptyState));
-            dbug(1,dprintf("plci->ptyState:%x",plci->ptyState));
-            dbug(1,dprintf("SSreq:%x",SSreq));
-            dbug(1,dprintf("rplci->internal_command:%x",rplci->internal_command));
-            dbug(1,dprintf("rplci->appl:%x",rplci->appl));
-            dbug(1,dprintf("rplci->Id:%x",rplci->Id));
+  dbug(1, dprintf("rplci:%x", rplci));
+  dbug(1, dprintf("plci:%x", plci));
+  dbug(1, dprintf("rplci->ptyState:%x", rplci->ptyState));
+  dbug(1, dprintf("plci->ptyState:%x", plci->ptyState));
+  dbug(1, dprintf("SSreq:%x", SSreq));
+  dbug(1, dprintf("rplci->internal_command:%x", rplci->internal_command));
+  dbug(1, dprintf("rplci->appl:%x", rplci->appl));
+  dbug(1, dprintf("rplci->Id:%x", rplci->Id));
 */
-            /* send PTY/ECT req, cannot check all states because of US stuff */
-            if( !rplci->internal_command && rplci->appl )
-            {
-              plci->command = 0;
-              rplci->relatedPTYPLCI = plci;
-              plci->relatedPTYPLCI = rplci;
-              rplci->ptyState = (byte)SSreq;
-              if(SSreq==S_ECT)
-              {
-                rplci->internal_command = ECT_REQ_PEND;
-                cai[1] = ECT_EXECUTE;
-
-                rplci->vswitchstate=0;
-                rplci->vsprot=0;
-                rplci->vsprotdialect=0;
-                plci->vswitchstate=0;
-                plci->vsprot=0;
-                plci->vsprotdialect=0;
-
-              }
-              else if(SSreq==S_CONF_ADD)
-              {
-                rplci->internal_command = CONF_ADD_REQ_PEND;
-                cai[1] = CONF_ADD;
-              }
-              else
-              {
-                rplci->internal_command = PTY_REQ_PEND;
-                cai[1] = (byte)(SSreq-3);
-              }
-              rplci->number = Number;
-              if(plci!=rplci) /* explicit invocation */
-              {
-                cai[0] = 2;
-                cai[2] = plci->Sig.Id;
-                dbug(1,dprintf("explicit invocation"));
-              }
-              else
-              {
-                dbug(1,dprintf("implicit invocation"));
-                cai[0] = 1;
-              }
-              add_p(rplci,CAI,cai);
-              sig_req(rplci,S_SERVICE,0);
-              send_req(rplci);
-              return false;
-            }
-            else
-            {
-              dbug(0,dprintf("Wrong line"));
-              Info = 0x3010;                    /* wrong state           */
-              break;
-            }
-            break;
-
-          case S_CALL_DEFLECTION:
-            if(api_parse(&parms->info[1],(word)parms->length,"wbwss",ss_parms))
-            {
-              dbug(1,dprintf("format wrong"));
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            if (!plci)
-            {
-              Info = _WRONG_IDENTIFIER;
-              break;
-            }
-            /* reuse unused screening indicator */
-            ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0]));
-            plci->command = 0;
-            plci->internal_command = CD_REQ_PEND;
-            appl->CDEnable = true;
-            cai[0] = 1;
-            cai[1] = CALL_DEFLECTION;
-            add_p(plci,CAI,cai);
-            add_p(plci,CPN,ss_parms[3].info);
-            sig_req(plci,S_SERVICE,0);
-            send_req(plci);
-            return false;
-            break;
-
-          case S_CALL_FORWARDING_START:
-            if(api_parse(&parms->info[1],(word)parms->length,"wbdwwsss",ss_parms))
-            {
-              dbug(1,dprintf("format wrong"));
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-
-            if((i=get_plci(a)))
-            {
-              rplci = &a->plci[i-1];
-              rplci->appl = appl;
-              add_p(rplci,CAI,"\x01\x80");
-              add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-              sig_req(rplci,ASSIGN,DSIG_ID);
-              send_req(rplci);
-            }
-            else
-            {
-              Info = _OUT_OF_PLCI;
-              break;
-            }
-
-            /* reuse unused screening indicator */
-            rplci->internal_command = CF_START_PEND;
-            rplci->appl = appl;
-            rplci->number = Number;
-            appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
-            cai[0] = 2;
-            cai[1] = 0x70|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
-            cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
-            add_p(rplci,CAI,cai);
-            add_p(rplci,OAD,ss_parms[5].info);
-            add_p(rplci,CPN,ss_parms[6].info);
-            sig_req(rplci,S_SERVICE,0);
-            send_req(rplci);
-            return false;
-            break;
-
-          case S_INTERROGATE_DIVERSION:
-          case S_INTERROGATE_NUMBERS:
-          case S_CALL_FORWARDING_STOP:
-          case S_CCBS_REQUEST:
-          case S_CCBS_DEACTIVATE:
-          case S_CCBS_INTERROGATE:
-            switch(SSreq)
-            {
-            case S_INTERROGATE_NUMBERS:
-                if(api_parse(&parms->info[1],(word)parms->length,"wbd",ss_parms))
-                {
-                  dbug(0,dprintf("format wrong"));
-                  Info = _WRONG_MESSAGE_FORMAT;
-                }
-                break;
-            case S_CCBS_REQUEST:
-            case S_CCBS_DEACTIVATE:
-                if(api_parse(&parms->info[1],(word)parms->length,"wbdw",ss_parms))
-                {
-                  dbug(0,dprintf("format wrong"));
-                  Info = _WRONG_MESSAGE_FORMAT;
-                }
-                break;
-            case S_CCBS_INTERROGATE:
-                if(api_parse(&parms->info[1],(word)parms->length,"wbdws",ss_parms))
-                {
-                  dbug(0,dprintf("format wrong"));
-                  Info = _WRONG_MESSAGE_FORMAT;
-                }
-                break;
-            default:
-            if(api_parse(&parms->info[1],(word)parms->length,"wbdwws",ss_parms))
-            {
-              dbug(0,dprintf("format wrong"));
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-                break;
-            }
-
-            if(Info) break;
-            if((i=get_plci(a)))
-            {
-              rplci = &a->plci[i-1];
-              switch(SSreq)
-              {
-                case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */
-                  cai[1] = 0x60|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
-                  rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */
-                  break;
-                case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */
-                  cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */
-                  rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */
-                  break;
-                case S_CALL_FORWARDING_STOP:
-                  rplci->internal_command = CF_STOP_PEND;
-                  cai[1] = 0x80|(byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
-                  break;
-                case S_CCBS_REQUEST:
-                  cai[1] = CCBS_REQUEST;
-                  rplci->internal_command = CCBS_REQUEST_REQ_PEND;
-                  break;
-                case S_CCBS_DEACTIVATE:
-                  cai[1] = CCBS_DEACTIVATE;
-                  rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND;
-                  break;
-                case S_CCBS_INTERROGATE:
-                  cai[1] = CCBS_INTERROGATE;
-                  rplci->internal_command = CCBS_INTERROGATE_REQ_PEND;
-                  break;
-                default:
-                  cai[1] = 0;
-                break;
-              }
-              rplci->appl = appl;
-              rplci->number = Number;
-              add_p(rplci,CAI,"\x01\x80");
-              add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-              sig_req(rplci,ASSIGN,DSIG_ID);
-              send_req(rplci);
-            }
-            else
-            {
-              Info = _OUT_OF_PLCI;
-              break;
-            }
-
-            appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
-            switch(SSreq)
-            {
-            case S_INTERROGATE_NUMBERS:
-                cai[0] = 1;
-                add_p(rplci,CAI,cai);
-                break;
-            case S_CCBS_REQUEST:
-            case S_CCBS_DEACTIVATE:
-                cai[0] = 3;
-                PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0])));
-                add_p(rplci,CAI,cai);
-                break;
-            case S_CCBS_INTERROGATE:
-                cai[0] = 3;
-                PUT_WORD(&cai[2],GET_WORD(&(ss_parms[3].info[0])));
-                add_p(rplci,CAI,cai);
-                add_p(rplci,OAD,ss_parms[4].info);
-                break;
-            default:
-            cai[0] = 2;
-            cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
-            add_p(rplci,CAI,cai);
-            add_p(rplci,OAD,ss_parms[5].info);
-                break;
-            }
-                        
-            sig_req(rplci,S_SERVICE,0);
-            send_req(rplci);
-            return false;
-            break;
-
-          case S_MWI_ACTIVATE:
-            if(api_parse(&parms->info[1],(word)parms->length,"wbwdwwwssss",ss_parms))
-            {
-              dbug(1,dprintf("format wrong"));
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            if(!plci)
-            {                               
-              if((i=get_plci(a)))
-              {
-                rplci = &a->plci[i-1];
-                rplci->appl = appl;
-                rplci->cr_enquiry=true;
-                add_p(rplci,CAI,"\x01\x80");
-                add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-                sig_req(rplci,ASSIGN,DSIG_ID);
-                send_req(rplci);
-              }
-              else
-              {
-                Info = _OUT_OF_PLCI;
-                break;
-              }
-            }
-            else
-            {
-              rplci = plci;
-              rplci->cr_enquiry=false;
-            }
-
-            rplci->command = 0;
-            rplci->internal_command = MWI_ACTIVATE_REQ_PEND;
-            rplci->appl = appl;
-            rplci->number = Number;
-
-            cai[0] = 13;
-            cai[1] = ACTIVATION_MWI; /* Function */
-            PUT_WORD(&cai[2],GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
-            PUT_DWORD(&cai[4],GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */
-            PUT_WORD(&cai[8],GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */
-            PUT_WORD(&cai[10],GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */
-            PUT_WORD(&cai[12],GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */
-            add_p(rplci,CAI,cai);
-            add_p(rplci,CPN,ss_parms[7].info); /* Receiving User Number */
-            add_p(rplci,OAD,ss_parms[8].info); /* Controlling User Number */
-            add_p(rplci,OSA,ss_parms[9].info); /* Controlling User Provided Number */
-            add_p(rplci,UID,ss_parms[10].info); /* Time */
-            sig_req(rplci,S_SERVICE,0);
-            send_req(rplci);
-            return false;
-
-          case S_MWI_DEACTIVATE:
-            if(api_parse(&parms->info[1],(word)parms->length,"wbwwss",ss_parms))
-            {
-              dbug(1,dprintf("format wrong"));
-              Info = _WRONG_MESSAGE_FORMAT;
-              break;
-            }
-            if(!plci)
-            {                               
-              if((i=get_plci(a)))
-              {
-                rplci = &a->plci[i-1];
-                rplci->appl = appl;
-                rplci->cr_enquiry=true;
-                add_p(rplci,CAI,"\x01\x80");
-                add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-                sig_req(rplci,ASSIGN,DSIG_ID);
-                send_req(rplci);
-              }
-              else
-              {
-                Info = _OUT_OF_PLCI;
-                break;
-              }
-            }
-            else
-            {
-              rplci = plci;
-              rplci->cr_enquiry=false;
-            }
-
-            rplci->command = 0;
-            rplci->internal_command = MWI_DEACTIVATE_REQ_PEND;
-            rplci->appl = appl;
-            rplci->number = Number;
-
-            cai[0] = 5;
-            cai[1] = DEACTIVATION_MWI; /* Function */
-            PUT_WORD(&cai[2],GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
-            PUT_WORD(&cai[4],GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */
-            add_p(rplci,CAI,cai);
-            add_p(rplci,CPN,ss_parms[4].info); /* Receiving User Number */
-            add_p(rplci,OAD,ss_parms[5].info); /* Controlling User Number */
-            sig_req(rplci,S_SERVICE,0);
-            send_req(rplci);
-            return false;
-
-          default:
-            Info = 0x300E;  /* not supported */
-            break;
-        }
-        break; /* case SELECTOR_SU_SERV: end */
-
-
-      case SELECTOR_DTMF:
-        return (dtmf_request (Id, Number, a, plci, appl, msg));
-
-
-
-      case SELECTOR_LINE_INTERCONNECT:
-        return (mixer_request (Id, Number, a, plci, appl, msg));
-
-
-
-      case PRIV_SELECTOR_ECHO_CANCELLER:
-        appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC;
-        return (ec_request (Id, Number, a, plci, appl, msg));
-
-      case SELECTOR_ECHO_CANCELLER:
-        appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC;
-        return (ec_request (Id, Number, a, plci, appl, msg));
-
-
-      case SELECTOR_V42BIS:
-      default:
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-    } /* end of switch(selector) */
-  }
-
-  dbug(1,dprintf("SendFacRc"));
-  sendf(appl,
-        _FACILITY_R|CONFIRM,
-        Id,
-        Number,
-        "wws",Info,selector,SSparms);
-  return false;
+				/* send PTY/ECT req, cannot check all states because of US stuff */
+				if (!rplci->internal_command && rplci->appl)
+				{
+					plci->command = 0;
+					rplci->relatedPTYPLCI = plci;
+					plci->relatedPTYPLCI = rplci;
+					rplci->ptyState = (byte)SSreq;
+					if (SSreq == S_ECT)
+					{
+						rplci->internal_command = ECT_REQ_PEND;
+						cai[1] = ECT_EXECUTE;
+
+						rplci->vswitchstate = 0;
+						rplci->vsprot = 0;
+						rplci->vsprotdialect = 0;
+						plci->vswitchstate = 0;
+						plci->vsprot = 0;
+						plci->vsprotdialect = 0;
+
+					}
+					else if (SSreq == S_CONF_ADD)
+					{
+						rplci->internal_command = CONF_ADD_REQ_PEND;
+						cai[1] = CONF_ADD;
+					}
+					else
+					{
+						rplci->internal_command = PTY_REQ_PEND;
+						cai[1] = (byte)(SSreq - 3);
+					}
+					rplci->number = Number;
+					if (plci != rplci) /* explicit invocation */
+					{
+						cai[0] = 2;
+						cai[2] = plci->Sig.Id;
+						dbug(1, dprintf("explicit invocation"));
+					}
+					else
+					{
+						dbug(1, dprintf("implicit invocation"));
+						cai[0] = 1;
+					}
+					add_p(rplci, CAI, cai);
+					sig_req(rplci, S_SERVICE, 0);
+					send_req(rplci);
+					return false;
+				}
+				else
+				{
+					dbug(0, dprintf("Wrong line"));
+					Info = 0x3010;                    /* wrong state           */
+					break;
+				}
+				break;
+
+			case S_CALL_DEFLECTION:
+				if (api_parse(&parms->info[1], (word)parms->length, "wbwss", ss_parms))
+				{
+					dbug(1, dprintf("format wrong"));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (!plci)
+				{
+					Info = _WRONG_IDENTIFIER;
+					break;
+				}
+				/* reuse unused screening indicator */
+				ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0]));
+				plci->command = 0;
+				plci->internal_command = CD_REQ_PEND;
+				appl->CDEnable = true;
+				cai[0] = 1;
+				cai[1] = CALL_DEFLECTION;
+				add_p(plci, CAI, cai);
+				add_p(plci, CPN, ss_parms[3].info);
+				sig_req(plci, S_SERVICE, 0);
+				send_req(plci);
+				return false;
+				break;
+
+			case S_CALL_FORWARDING_START:
+				if (api_parse(&parms->info[1], (word)parms->length, "wbdwwsss", ss_parms))
+				{
+					dbug(1, dprintf("format wrong"));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+
+				if ((i = get_plci(a)))
+				{
+					rplci = &a->plci[i - 1];
+					rplci->appl = appl;
+					add_p(rplci, CAI, "\x01\x80");
+					add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+					sig_req(rplci, ASSIGN, DSIG_ID);
+					send_req(rplci);
+				}
+				else
+				{
+					Info = _OUT_OF_PLCI;
+					break;
+				}
+
+				/* reuse unused screening indicator */
+				rplci->internal_command = CF_START_PEND;
+				rplci->appl = appl;
+				rplci->number = Number;
+				appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
+				cai[0] = 2;
+				cai[1] = 0x70 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
+				cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
+				add_p(rplci, CAI, cai);
+				add_p(rplci, OAD, ss_parms[5].info);
+				add_p(rplci, CPN, ss_parms[6].info);
+				sig_req(rplci, S_SERVICE, 0);
+				send_req(rplci);
+				return false;
+				break;
+
+			case S_INTERROGATE_DIVERSION:
+			case S_INTERROGATE_NUMBERS:
+			case S_CALL_FORWARDING_STOP:
+			case S_CCBS_REQUEST:
+			case S_CCBS_DEACTIVATE:
+			case S_CCBS_INTERROGATE:
+				switch (SSreq)
+				{
+				case S_INTERROGATE_NUMBERS:
+					if (api_parse(&parms->info[1], (word)parms->length, "wbd", ss_parms))
+					{
+						dbug(0, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+					}
+					break;
+				case S_CCBS_REQUEST:
+				case S_CCBS_DEACTIVATE:
+					if (api_parse(&parms->info[1], (word)parms->length, "wbdw", ss_parms))
+					{
+						dbug(0, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+					}
+					break;
+				case S_CCBS_INTERROGATE:
+					if (api_parse(&parms->info[1], (word)parms->length, "wbdws", ss_parms))
+					{
+						dbug(0, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+					}
+					break;
+				default:
+					if (api_parse(&parms->info[1], (word)parms->length, "wbdwws", ss_parms))
+					{
+						dbug(0, dprintf("format wrong"));
+						Info = _WRONG_MESSAGE_FORMAT;
+						break;
+					}
+					break;
+				}
+
+				if (Info) break;
+				if ((i = get_plci(a)))
+				{
+					rplci = &a->plci[i - 1];
+					switch (SSreq)
+					{
+					case S_INTERROGATE_DIVERSION: /* use cai with S_SERVICE below */
+						cai[1] = 0x60 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
+						rplci->internal_command = INTERR_DIVERSION_REQ_PEND; /* move to rplci if assigned */
+						break;
+					case S_INTERROGATE_NUMBERS: /* use cai with S_SERVICE below */
+						cai[1] = DIVERSION_INTERROGATE_NUM; /* Function */
+						rplci->internal_command = INTERR_NUMBERS_REQ_PEND; /* move to rplci if assigned */
+						break;
+					case S_CALL_FORWARDING_STOP:
+						rplci->internal_command = CF_STOP_PEND;
+						cai[1] = 0x80 | (byte)GET_WORD(&(ss_parms[3].info[0])); /* Function */
+						break;
+					case S_CCBS_REQUEST:
+						cai[1] = CCBS_REQUEST;
+						rplci->internal_command = CCBS_REQUEST_REQ_PEND;
+						break;
+					case S_CCBS_DEACTIVATE:
+						cai[1] = CCBS_DEACTIVATE;
+						rplci->internal_command = CCBS_DEACTIVATE_REQ_PEND;
+						break;
+					case S_CCBS_INTERROGATE:
+						cai[1] = CCBS_INTERROGATE;
+						rplci->internal_command = CCBS_INTERROGATE_REQ_PEND;
+						break;
+					default:
+						cai[1] = 0;
+						break;
+					}
+					rplci->appl = appl;
+					rplci->number = Number;
+					add_p(rplci, CAI, "\x01\x80");
+					add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+					sig_req(rplci, ASSIGN, DSIG_ID);
+					send_req(rplci);
+				}
+				else
+				{
+					Info = _OUT_OF_PLCI;
+					break;
+				}
+
+				appl->S_Handle = GET_DWORD(&(ss_parms[2].info[0]));
+				switch (SSreq)
+				{
+				case S_INTERROGATE_NUMBERS:
+					cai[0] = 1;
+					add_p(rplci, CAI, cai);
+					break;
+				case S_CCBS_REQUEST:
+				case S_CCBS_DEACTIVATE:
+					cai[0] = 3;
+					PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0])));
+					add_p(rplci, CAI, cai);
+					break;
+				case S_CCBS_INTERROGATE:
+					cai[0] = 3;
+					PUT_WORD(&cai[2], GET_WORD(&(ss_parms[3].info[0])));
+					add_p(rplci, CAI, cai);
+					add_p(rplci, OAD, ss_parms[4].info);
+					break;
+				default:
+					cai[0] = 2;
+					cai[2] = (byte)GET_WORD(&(ss_parms[4].info[0])); /* Basic Service */
+					add_p(rplci, CAI, cai);
+					add_p(rplci, OAD, ss_parms[5].info);
+					break;
+				}
+
+				sig_req(rplci, S_SERVICE, 0);
+				send_req(rplci);
+				return false;
+				break;
+
+			case S_MWI_ACTIVATE:
+				if (api_parse(&parms->info[1], (word)parms->length, "wbwdwwwssss", ss_parms))
+				{
+					dbug(1, dprintf("format wrong"));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (!plci)
+				{
+					if ((i = get_plci(a)))
+					{
+						rplci = &a->plci[i - 1];
+						rplci->appl = appl;
+						rplci->cr_enquiry = true;
+						add_p(rplci, CAI, "\x01\x80");
+						add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						sig_req(rplci, ASSIGN, DSIG_ID);
+						send_req(rplci);
+					}
+					else
+					{
+						Info = _OUT_OF_PLCI;
+						break;
+					}
+				}
+				else
+				{
+					rplci = plci;
+					rplci->cr_enquiry = false;
+				}
+
+				rplci->command = 0;
+				rplci->internal_command = MWI_ACTIVATE_REQ_PEND;
+				rplci->appl = appl;
+				rplci->number = Number;
+
+				cai[0] = 13;
+				cai[1] = ACTIVATION_MWI; /* Function */
+				PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
+				PUT_DWORD(&cai[4], GET_DWORD(&(ss_parms[3].info[0]))); /* Number of Messages */
+				PUT_WORD(&cai[8], GET_WORD(&(ss_parms[4].info[0]))); /* Message Status */
+				PUT_WORD(&cai[10], GET_WORD(&(ss_parms[5].info[0]))); /* Message Reference */
+				PUT_WORD(&cai[12], GET_WORD(&(ss_parms[6].info[0]))); /* Invocation Mode */
+				add_p(rplci, CAI, cai);
+				add_p(rplci, CPN, ss_parms[7].info); /* Receiving User Number */
+				add_p(rplci, OAD, ss_parms[8].info); /* Controlling User Number */
+				add_p(rplci, OSA, ss_parms[9].info); /* Controlling User Provided Number */
+				add_p(rplci, UID, ss_parms[10].info); /* Time */
+				sig_req(rplci, S_SERVICE, 0);
+				send_req(rplci);
+				return false;
+
+			case S_MWI_DEACTIVATE:
+				if (api_parse(&parms->info[1], (word)parms->length, "wbwwss", ss_parms))
+				{
+					dbug(1, dprintf("format wrong"));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (!plci)
+				{
+					if ((i = get_plci(a)))
+					{
+						rplci = &a->plci[i - 1];
+						rplci->appl = appl;
+						rplci->cr_enquiry = true;
+						add_p(rplci, CAI, "\x01\x80");
+						add_p(rplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						sig_req(rplci, ASSIGN, DSIG_ID);
+						send_req(rplci);
+					}
+					else
+					{
+						Info = _OUT_OF_PLCI;
+						break;
+					}
+				}
+				else
+				{
+					rplci = plci;
+					rplci->cr_enquiry = false;
+				}
+
+				rplci->command = 0;
+				rplci->internal_command = MWI_DEACTIVATE_REQ_PEND;
+				rplci->appl = appl;
+				rplci->number = Number;
+
+				cai[0] = 5;
+				cai[1] = DEACTIVATION_MWI; /* Function */
+				PUT_WORD(&cai[2], GET_WORD(&(ss_parms[2].info[0]))); /* Basic Service */
+				PUT_WORD(&cai[4], GET_WORD(&(ss_parms[3].info[0]))); /* Invocation Mode */
+				add_p(rplci, CAI, cai);
+				add_p(rplci, CPN, ss_parms[4].info); /* Receiving User Number */
+				add_p(rplci, OAD, ss_parms[5].info); /* Controlling User Number */
+				sig_req(rplci, S_SERVICE, 0);
+				send_req(rplci);
+				return false;
+
+			default:
+				Info = 0x300E;  /* not supported */
+				break;
+			}
+			break; /* case SELECTOR_SU_SERV: end */
+
+
+		case SELECTOR_DTMF:
+			return (dtmf_request(Id, Number, a, plci, appl, msg));
+
+
+
+		case SELECTOR_LINE_INTERCONNECT:
+			return (mixer_request(Id, Number, a, plci, appl, msg));
+
+
+
+		case PRIV_SELECTOR_ECHO_CANCELLER:
+			appl->appl_flags |= APPL_FLAG_PRIV_EC_SPEC;
+			return (ec_request(Id, Number, a, plci, appl, msg));
+
+		case SELECTOR_ECHO_CANCELLER:
+			appl->appl_flags &= ~APPL_FLAG_PRIV_EC_SPEC;
+			return (ec_request(Id, Number, a, plci, appl, msg));
+
+
+		case SELECTOR_V42BIS:
+		default:
+			Info = _FACILITY_NOT_SUPPORTED;
+			break;
+		} /* end of switch (selector) */
+	}
+
+	dbug(1, dprintf("SendFacRc"));
+	sendf(appl,
+	      _FACILITY_R | CONFIRM,
+	      Id,
+	      Number,
+	      "wws", Info, selector, SSparms);
+	return false;
 }
 
 static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			 PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  dbug(1,dprintf("facility_res"));
-  return false;
+	dbug(1, dprintf("facility_res"));
+	return false;
 }
 
 static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			   PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word Info = 0;
-  byte req;
-  byte len;
-  word w;
-  word fax_control_bits, fax_feature_bits, fax_info_change;
-  API_PARSE * ncpi;
-    byte pvc[2];
-
-    API_PARSE fax_parms[9];
-  word i;
-
-
-  dbug(1,dprintf("connect_b3_req"));
-  if(plci)
-  {
-    if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING)
-     || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE))
-    {
-      Info = _WRONG_STATE;
-    }
-    else
-    {
-      /* local reply if assign unsuccessful
-         or B3 protocol allows only one layer 3 connection
-           and already connected
-             or B2 protocol not any LAPD
-               and connect_b3_req contradicts originate/answer direction */
-      if (!plci->NL.Id
-       || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
-        && ((plci->channels != 0)
-         || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))
-          && ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL))))))
-      {
-        dbug(1,dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x",
-                       plci->channels,plci->NL.Id,plci->call_dir,plci->SuppState));
-        Info = _WRONG_STATE;
-        sendf(appl,                                                        
-              _CONNECT_B3_R|CONFIRM,
-              Id,
-              Number,
-              "w",Info);
-        return false;
-      }
-      plci->requested_options_conn = 0;
-
-      req = N_CONNECT;
-      ncpi = &parms[0];
-      if(plci->B3_prot==2 || plci->B3_prot==3)
-      {
-        if(ncpi->length>2)
-        {
-          /* check for PVC */
-          if(ncpi->info[2] || ncpi->info[3])
-          {
-            pvc[0] = ncpi->info[3];
-            pvc[1] = ncpi->info[2];
-            add_d(plci,2,pvc);
-            req = N_RESET;
-          }
-          else
-          {
-            if(ncpi->info[1] &1) req = N_CONNECT | N_D_BIT;
-            add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]);
-          }
-        }
-      }
-      else if(plci->B3_prot==5)
-      {
-        if (plci->NL.Id && !plci->nl_remove_id)
-        {
-          fax_control_bits = GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low);
-          fax_feature_bits = GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->feature_bits_low);
-          if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
-           || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
-          {
-            len = offsetof(T30_INFO, universal_6);
-            fax_info_change = false;
-            if (ncpi->length >= 4)
-            {
-              w = GET_WORD(&ncpi->info[3]);
-              if ((w & 0x0001) != ((word)(((T30_INFO   *)(plci->fax_connect_info_buffer))->resolution & 0x0001)))
-              {
-                ((T30_INFO   *)(plci->fax_connect_info_buffer))->resolution =
-                  (byte)((((T30_INFO   *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) |
-                  ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0));
-                fax_info_change = true;
-              }
-              fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
-              if (w & 0x0002)  /* Fax-polling request */
-                fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING;
-              if ((w & 0x0004) /* Request to send / poll another document */
-               && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS))
-              {
-                fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS;
-              }
-              if (ncpi->length >= 6)
-              {
-                w = GET_WORD(&ncpi->info[5]);
-                if (((byte) w) != ((T30_INFO   *)(plci->fax_connect_info_buffer))->data_format)
-                {
-                  ((T30_INFO   *)(plci->fax_connect_info_buffer))->data_format = (byte) w;
-                  fax_info_change = true;
-                }
-
-                if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
-                 && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */
-                {
-                  plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD);
-                }
-                if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
-                 && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */
-                {
-                  plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD);
-                }
-                fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING |
-                  T30_CONTROL_BIT_ACCEPT_PASSWORD);
-                if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1])
-                  & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
-                {
-                  if (api_parse (&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms))
-                    Info = _WRONG_MESSAGE_FORMAT;
-                  else
-                  {
-                    if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1])
-                      & (1L << PRIVATE_FAX_SUB_SEP_PWD))
-      {
-                    fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
-                    if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
-                      fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
-      }
-                    w = fax_parms[4].length;
-                    if (w > 20)
-                      w = 20;
-                    ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w;
-                    for (i = 0; i < w; i++)
-                      ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
-                    ((T30_INFO   *)(plci->fax_connect_info_buffer))->head_line_len = 0;
-                    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
-                    w = fax_parms[5].length;
-                    if (w > 20)
-                      w = 20;
-                    plci->fax_connect_info_buffer[len++] = (byte) w;
-                    for (i = 0; i < w; i++)
-                      plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1+i];
-                    w = fax_parms[6].length;
-                    if (w > 20)
-                      w = 20;
-                    plci->fax_connect_info_buffer[len++] = (byte) w;
-                    for (i = 0; i < w; i++)
-                      plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1+i];
-                    if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id-1])
-                      & (1L << PRIVATE_FAX_NONSTANDARD))
-      {
-                      if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
-        {
-                        dbug(1,dprintf("non-standard facilities info missing or wrong format"));
-                        plci->fax_connect_info_buffer[len++] = 0;
-        }
-                      else
-                      {
-          if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
-            plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
-   plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
-          for (i = 0; i < fax_parms[7].length; i++)
-     plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i];
-                      }
-                    }
-                  }
-                }
-                else
-                {
-                  len = offsetof(T30_INFO, universal_6);
-                }
-                fax_info_change = true;
-
-              }
-              if (fax_control_bits != GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low))
-              {
-                PUT_WORD (&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits);
-                fax_info_change = true;
-              }
-            }
-            if (Info == GOOD)
-            {
-              plci->fax_connect_info_length = len;
-              if (fax_info_change)
-              {
-                if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
-                {
-                  start_internal_command (Id, plci, fax_connect_info_command);
-                  return false;
-                }
-                else
-                {
-                  start_internal_command (Id, plci, fax_adjust_b23_command);
-                  return false;
-                }
-              }
-            }
-          }
-          else  Info = _WRONG_STATE;
-        }
-        else  Info = _WRONG_STATE;
-      }
-
-      else if (plci->B3_prot == B3_RTP)
-      {
-        plci->internal_req_buffer[0] = ncpi->length + 1;
-        plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
-        for (w = 0; w < ncpi->length; w++)
-          plci->internal_req_buffer[2+w] = ncpi->info[1+w];
-        start_internal_command (Id, plci, rtp_connect_b3_req_command);
-        return false;
-      }
-
-      if(!Info)
-      {
-        nl_req_ncci(plci,req,0);
-        return 1;
-      }
-    }
-  }
-  else Info = _WRONG_IDENTIFIER;
-
-  sendf(appl,
-        _CONNECT_B3_R|CONFIRM,
-        Id,
-        Number,
-        "w",Info);
-  return false;
+	word Info = 0;
+	byte req;
+	byte len;
+	word w;
+	word fax_control_bits, fax_feature_bits, fax_info_change;
+	API_PARSE *ncpi;
+	byte pvc[2];
+
+	API_PARSE fax_parms[9];
+	word i;
+
+
+	dbug(1, dprintf("connect_b3_req"));
+	if (plci)
+	{
+		if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING)
+		    || (plci->State == INC_DIS_PENDING) || (plci->SuppState != IDLE))
+		{
+			Info = _WRONG_STATE;
+		}
+		else
+		{
+			/* local reply if assign unsuccessful
+			   or B3 protocol allows only one layer 3 connection
+			   and already connected
+			   or B2 protocol not any LAPD
+			   and connect_b3_req contradicts originate/answer direction */
+			if (!plci->NL.Id
+			    || (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
+				&& ((plci->channels != 0)
+				    || (((plci->B2_prot != B2_SDLC) && (plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL))
+					&& ((plci->call_dir & CALL_DIR_ANSWER) && !(plci->call_dir & CALL_DIR_FORCE_OUTG_NL))))))
+			{
+				dbug(1, dprintf("B3 already connected=%d or no NL.Id=0x%x, dir=%d sstate=0x%x",
+						plci->channels, plci->NL.Id, plci->call_dir, plci->SuppState));
+				Info = _WRONG_STATE;
+				sendf(appl,
+				      _CONNECT_B3_R | CONFIRM,
+				      Id,
+				      Number,
+				      "w", Info);
+				return false;
+			}
+			plci->requested_options_conn = 0;
+
+			req = N_CONNECT;
+			ncpi = &parms[0];
+			if (plci->B3_prot == 2 || plci->B3_prot == 3)
+			{
+				if (ncpi->length > 2)
+				{
+					/* check for PVC */
+					if (ncpi->info[2] || ncpi->info[3])
+					{
+						pvc[0] = ncpi->info[3];
+						pvc[1] = ncpi->info[2];
+						add_d(plci, 2, pvc);
+						req = N_RESET;
+					}
+					else
+					{
+						if (ncpi->info[1] & 1) req = N_CONNECT | N_D_BIT;
+						add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
+					}
+				}
+			}
+			else if (plci->B3_prot == 5)
+			{
+				if (plci->NL.Id && !plci->nl_remove_id)
+				{
+					fax_control_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low);
+					fax_feature_bits = GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low);
+					if (!(fax_control_bits & T30_CONTROL_BIT_MORE_DOCUMENTS)
+					    || (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
+					{
+						len = offsetof(T30_INFO, universal_6);
+						fax_info_change = false;
+						if (ncpi->length >= 4)
+						{
+							w = GET_WORD(&ncpi->info[3]);
+							if ((w & 0x0001) != ((word)(((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & 0x0001)))
+							{
+								((T30_INFO *)(plci->fax_connect_info_buffer))->resolution =
+									(byte)((((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) |
+									       ((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0));
+								fax_info_change = true;
+							}
+							fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
+							if (w & 0x0002)  /* Fax-polling request */
+								fax_control_bits |= T30_CONTROL_BIT_REQUEST_POLLING;
+							if ((w & 0x0004) /* Request to send / poll another document */
+							    && (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_MORE_DOCUMENTS))
+							{
+								fax_control_bits |= T30_CONTROL_BIT_MORE_DOCUMENTS;
+							}
+							if (ncpi->length >= 6)
+							{
+								w = GET_WORD(&ncpi->info[5]);
+								if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format)
+								{
+									((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w;
+									fax_info_change = true;
+								}
+
+								if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
+								    && (GET_WORD(&ncpi->info[5]) & 0x8000)) /* Private SEP/SUB/PWD enable */
+								{
+									plci->requested_options_conn |= (1L << PRIVATE_FAX_SUB_SEP_PWD);
+								}
+								if ((a->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
+								    && (GET_WORD(&ncpi->info[5]) & 0x4000)) /* Private non-standard facilities enable */
+								{
+									plci->requested_options_conn |= (1L << PRIVATE_FAX_NONSTANDARD);
+								}
+								fax_control_bits &= ~(T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_SEL_POLLING |
+										      T30_CONTROL_BIT_ACCEPT_PASSWORD);
+								if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
+								    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
+								{
+									if (api_parse(&ncpi->info[1], ncpi->length, "wwwwsss", fax_parms))
+										Info = _WRONG_MESSAGE_FORMAT;
+									else
+									{
+										if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
+										    & (1L << PRIVATE_FAX_SUB_SEP_PWD))
+										{
+											fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
+											if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
+												fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
+										}
+										w = fax_parms[4].length;
+										if (w > 20)
+											w = 20;
+										((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = (byte) w;
+										for (i = 0; i < w; i++)
+											((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1 + i];
+										((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
+										len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
+										w = fax_parms[5].length;
+										if (w > 20)
+											w = 20;
+										plci->fax_connect_info_buffer[len++] = (byte) w;
+										for (i = 0; i < w; i++)
+											plci->fax_connect_info_buffer[len++] = fax_parms[5].info[1 + i];
+										w = fax_parms[6].length;
+										if (w > 20)
+											w = 20;
+										plci->fax_connect_info_buffer[len++] = (byte) w;
+										for (i = 0; i < w; i++)
+											plci->fax_connect_info_buffer[len++] = fax_parms[6].info[1 + i];
+										if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[appl->Id - 1])
+										    & (1L << PRIVATE_FAX_NONSTANDARD))
+										{
+											if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
+											{
+												dbug(1, dprintf("non-standard facilities info missing or wrong format"));
+												plci->fax_connect_info_buffer[len++] = 0;
+											}
+											else
+											{
+												if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
+													plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
+												plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
+												for (i = 0; i < fax_parms[7].length; i++)
+													plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
+											}
+										}
+									}
+								}
+								else
+								{
+									len = offsetof(T30_INFO, universal_6);
+								}
+								fax_info_change = true;
+
+							}
+							if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low))
+							{
+								PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits);
+								fax_info_change = true;
+							}
+						}
+						if (Info == GOOD)
+						{
+							plci->fax_connect_info_length = len;
+							if (fax_info_change)
+							{
+								if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
+								{
+									start_internal_command(Id, plci, fax_connect_info_command);
+									return false;
+								}
+								else
+								{
+									start_internal_command(Id, plci, fax_adjust_b23_command);
+									return false;
+								}
+							}
+						}
+					}
+					else  Info = _WRONG_STATE;
+				}
+				else  Info = _WRONG_STATE;
+			}
+
+			else if (plci->B3_prot == B3_RTP)
+			{
+				plci->internal_req_buffer[0] = ncpi->length + 1;
+				plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
+				for (w = 0; w < ncpi->length; w++)
+					plci->internal_req_buffer[2 + w] = ncpi->info[1 + w];
+				start_internal_command(Id, plci, rtp_connect_b3_req_command);
+				return false;
+			}
+
+			if (!Info)
+			{
+				nl_req_ncci(plci, req, 0);
+				return 1;
+			}
+		}
+	}
+	else Info = _WRONG_IDENTIFIER;
+
+	sendf(appl,
+	      _CONNECT_B3_R | CONFIRM,
+	      Id,
+	      Number,
+	      "w", Info);
+	return false;
 }
 
 static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			   PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word ncci;
-  API_PARSE * ncpi;
-  byte req;
-
-  word w;
-
-
-    API_PARSE fax_parms[9];
-  word i;
-  byte len;
-
-
-  dbug(1,dprintf("connect_b3_res"));
-
-  ncci = (word)(Id>>16);
-  if(plci && ncci) {
-    if(a->ncci_state[ncci]==INC_CON_PENDING) {
-      if (GET_WORD (&parms[0].info[0]) != 0)
-      {
-        a->ncci_state[ncci] = OUTG_REJ_PENDING;
-        channel_request_xon (plci, a->ncci_ch[ncci]);
-        channel_xmit_xon (plci);
-        cleanup_ncci_data (plci, ncci);
-        nl_req_ncci(plci,N_DISC,(byte)ncci);
-        return 1;
-      }
-      a->ncci_state[ncci] = INC_ACT_PENDING;
-
-      req = N_CONNECT_ACK;
-      ncpi = &parms[1];
-      if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
-      {
-
-        if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
-          & (1L << PRIVATE_FAX_NONSTANDARD))
- {
-   if (((plci->B3_prot == 4) || (plci->B3_prot == 5))
-    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
-    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
-   {
-            len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
-            if (plci->fax_connect_info_length < len)
-            {
-              ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
-              ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
-            }
-            if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
-            {
-              dbug(1,dprintf("non-standard facilities info missing or wrong format"));
-            }
-            else
-            {
-              if (plci->fax_connect_info_length <= len)
-                plci->fax_connect_info_buffer[len] = 0;
-              len += 1 + plci->fax_connect_info_buffer[len];
-              if (plci->fax_connect_info_length <= len)
-                plci->fax_connect_info_buffer[len] = 0;
-              len += 1 + plci->fax_connect_info_buffer[len];
-              if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
-                plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
-              plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
-              for (i = 0; i < fax_parms[7].length; i++)
-                plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i];
-            }
-            plci->fax_connect_info_length = len;
-            ((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0;
-            start_internal_command (Id, plci, fax_connect_ack_command);
-     return false;
-          }
-        }
-
-        nl_req_ncci(plci,req,(byte)ncci);
-        if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-         && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-        {
-          if (plci->B3_prot == 4)
-            sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-          else
-            sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
-          plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-        }
-      }
-
-      else if (plci->B3_prot == B3_RTP)
-      {
-        plci->internal_req_buffer[0] = ncpi->length + 1;
-        plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
-        for (w = 0; w < ncpi->length; w++)
-          plci->internal_req_buffer[2+w] = ncpi->info[1+w];
-        start_internal_command (Id, plci, rtp_connect_b3_res_command);
-        return false;
-      }
-
-      else
-      {
-        if(ncpi->length>2) {
-          if(ncpi->info[1] &1) req = N_CONNECT_ACK | N_D_BIT;
-          add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]);
-        }
-        nl_req_ncci(plci,req,(byte)ncci);
-        sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-        if (plci->adjust_b_restore)
-        {
-          plci->adjust_b_restore = false;
-          start_internal_command (Id, plci, adjust_b_restore);
-        }
-      }
-      return 1;
-    }
-  }
-  return false;
+	word ncci;
+	API_PARSE *ncpi;
+	byte req;
+
+	word w;
+
+
+	API_PARSE fax_parms[9];
+	word i;
+	byte len;
+
+
+	dbug(1, dprintf("connect_b3_res"));
+
+	ncci = (word)(Id >> 16);
+	if (plci && ncci) {
+		if (a->ncci_state[ncci] == INC_CON_PENDING) {
+			if (GET_WORD(&parms[0].info[0]) != 0)
+			{
+				a->ncci_state[ncci] = OUTG_REJ_PENDING;
+				channel_request_xon(plci, a->ncci_ch[ncci]);
+				channel_xmit_xon(plci);
+				cleanup_ncci_data(plci, ncci);
+				nl_req_ncci(plci, N_DISC, (byte)ncci);
+				return 1;
+			}
+			a->ncci_state[ncci] = INC_ACT_PENDING;
+
+			req = N_CONNECT_ACK;
+			ncpi = &parms[1];
+			if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
+			{
+
+				if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
+				    & (1L << PRIVATE_FAX_NONSTANDARD))
+				{
+					if (((plci->B3_prot == 4) || (plci->B3_prot == 5))
+					    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
+					    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
+					{
+						len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
+						if (plci->fax_connect_info_length < len)
+						{
+							((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
+							((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
+						}
+						if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
+						{
+							dbug(1, dprintf("non-standard facilities info missing or wrong format"));
+						}
+						else
+						{
+							if (plci->fax_connect_info_length <= len)
+								plci->fax_connect_info_buffer[len] = 0;
+							len += 1 + plci->fax_connect_info_buffer[len];
+							if (plci->fax_connect_info_length <= len)
+								plci->fax_connect_info_buffer[len] = 0;
+							len += 1 + plci->fax_connect_info_buffer[len];
+							if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
+								plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
+							plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
+							for (i = 0; i < fax_parms[7].length; i++)
+								plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
+						}
+						plci->fax_connect_info_length = len;
+						((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0;
+						start_internal_command(Id, plci, fax_connect_ack_command);
+						return false;
+					}
+				}
+
+				nl_req_ncci(plci, req, (byte)ncci);
+				if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+				    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+				{
+					if (plci->B3_prot == 4)
+						sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+					else
+						sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
+					plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+				}
+			}
+
+			else if (plci->B3_prot == B3_RTP)
+			{
+				plci->internal_req_buffer[0] = ncpi->length + 1;
+				plci->internal_req_buffer[1] = UDATA_REQUEST_RTP_RECONFIGURE;
+				for (w = 0; w < ncpi->length; w++)
+					plci->internal_req_buffer[2 + w] = ncpi->info[1+w];
+				start_internal_command(Id, plci, rtp_connect_b3_res_command);
+				return false;
+			}
+
+			else
+			{
+				if (ncpi->length > 2) {
+					if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT;
+					add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
+				}
+				nl_req_ncci(plci, req, (byte)ncci);
+				sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+				if (plci->adjust_b_restore)
+				{
+					plci->adjust_b_restore = false;
+					start_internal_command(Id, plci, adjust_b_restore);
+				}
+			}
+			return 1;
+		}
+	}
+	return false;
 }
 
 static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			     PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word ncci;
+	word ncci;
 
-  ncci = (word)(Id>>16);
-  dbug(1,dprintf("connect_b3_a_res(ncci=0x%x)",ncci));
+	ncci = (word)(Id >> 16);
+	dbug(1, dprintf("connect_b3_a_res(ncci=0x%x)", ncci));
 
-  if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING)
-   && (plci->State != OUTG_DIS_PENDING))
-  {
-    if(a->ncci_state[ncci]==INC_ACT_PENDING) {
-      a->ncci_state[ncci] = CONNECTED;
-      if(plci->State!=INC_CON_CONNECTED_ALERT) plci->State = CONNECTED;
-      channel_request_xon (plci, a->ncci_ch[ncci]);
-      channel_xmit_xon (plci);
-    }
-  }
-  return false;
+	if (plci && ncci && (plci->State != IDLE) && (plci->State != INC_DIS_PENDING)
+	    && (plci->State != OUTG_DIS_PENDING))
+	{
+		if (a->ncci_state[ncci] == INC_ACT_PENDING) {
+			a->ncci_state[ncci] = CONNECTED;
+			if (plci->State != INC_CON_CONNECTED_ALERT) plci->State = CONNECTED;
+			channel_request_xon(plci, a->ncci_ch[ncci]);
+			channel_xmit_xon(plci);
+		}
+	}
+	return false;
 }
 
 static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			      PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word Info;
-  word ncci;
-  API_PARSE * ncpi;
-
-  dbug(1,dprintf("disconnect_b3_req"));
-
-  Info = _WRONG_IDENTIFIER;
-  ncci = (word)(Id>>16);
-  if (plci && ncci)
-  {
-    Info = _WRONG_STATE;
-    if ((a->ncci_state[ncci] == CONNECTED)
-     || (a->ncci_state[ncci] == OUTG_CON_PENDING)
-     || (a->ncci_state[ncci] == INC_CON_PENDING)
-     || (a->ncci_state[ncci] == INC_ACT_PENDING))
-    {
-      a->ncci_state[ncci] = OUTG_DIS_PENDING;
-      channel_request_xon (plci, a->ncci_ch[ncci]);
-      channel_xmit_xon (plci);
-
-      if (a->ncci[ncci].data_pending
-       && ((plci->B3_prot == B3_TRANSPARENT)
-        || (plci->B3_prot == B3_T30)
-        || (plci->B3_prot == B3_T30_WITH_EXTENSIONS)))
-      {
-        plci->send_disc = (byte)ncci;
-        plci->command = 0;
-        return false;
-      }
-      else
-      {
-        cleanup_ncci_data (plci, ncci);
-
-        if(plci->B3_prot==2 || plci->B3_prot==3)
-        {
-          ncpi = &parms[0];
-          if(ncpi->length>3)
-          {
-            add_d(plci, (word)(ncpi->length - 3) ,(byte   *)&(ncpi->info[4]));
-          }
-        }
-        nl_req_ncci(plci,N_DISC,(byte)ncci);
-      }
-      return 1;
-    }
-  }
-  sendf(appl,
-        _DISCONNECT_B3_R|CONFIRM,
-        Id,
-        Number,
-        "w",Info);
-  return false;
+	word Info;
+	word ncci;
+	API_PARSE *ncpi;
+
+	dbug(1, dprintf("disconnect_b3_req"));
+
+	Info = _WRONG_IDENTIFIER;
+	ncci = (word)(Id >> 16);
+	if (plci && ncci)
+	{
+		Info = _WRONG_STATE;
+		if ((a->ncci_state[ncci] == CONNECTED)
+		    || (a->ncci_state[ncci] == OUTG_CON_PENDING)
+		    || (a->ncci_state[ncci] == INC_CON_PENDING)
+		    || (a->ncci_state[ncci] == INC_ACT_PENDING))
+		{
+			a->ncci_state[ncci] = OUTG_DIS_PENDING;
+			channel_request_xon(plci, a->ncci_ch[ncci]);
+			channel_xmit_xon(plci);
+
+			if (a->ncci[ncci].data_pending
+			    && ((plci->B3_prot == B3_TRANSPARENT)
+				|| (plci->B3_prot == B3_T30)
+				|| (plci->B3_prot == B3_T30_WITH_EXTENSIONS)))
+			{
+				plci->send_disc = (byte)ncci;
+				plci->command = 0;
+				return false;
+			}
+			else
+			{
+				cleanup_ncci_data(plci, ncci);
+
+				if (plci->B3_prot == 2 || plci->B3_prot == 3)
+				{
+					ncpi = &parms[0];
+					if (ncpi->length > 3)
+					{
+						add_d(plci, (word)(ncpi->length - 3), (byte *)&(ncpi->info[4]));
+					}
+				}
+				nl_req_ncci(plci, N_DISC, (byte)ncci);
+			}
+			return 1;
+		}
+	}
+	sendf(appl,
+	      _DISCONNECT_B3_R | CONFIRM,
+	      Id,
+	      Number,
+	      "w", Info);
+	return false;
 }
 
 static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			      PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word ncci;
-  word i;
-
-  ncci = (word)(Id>>16);
-  dbug(1,dprintf("disconnect_b3_res(ncci=0x%x",ncci));
-  if(plci && ncci) {
-    plci->requested_options_conn = 0;
-    plci->fax_connect_info_length = 0;
-    plci->ncpi_state = 0x00;
-    if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
-      && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)))
-    {
-      plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
-    }
-    for(i=0; i<MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i]!=(byte)ncci; i++);
-    if(i<MAX_CHANNELS_PER_PLCI) {
-      if(plci->channels)plci->channels--;
-      for(; i<MAX_CHANNELS_PER_PLCI-1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i+1];
-      plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI-1] = 0;
-
-      ncci_free_receive_buffers (plci, ncci);
-
-      if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){
-        if(plci->State == SUSPENDING){
-          sendf(plci->appl,
-                _FACILITY_I,
-                Id & 0xffffL,
-                0,
-                "ws", (word)3, "\x03\x04\x00\x00");
-          sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
-        }
-        plci_remove(plci);
-        plci->State=IDLE;
-      }
-    }
-    else
-    {
-      if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
-       && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
-       && (a->ncci_state[ncci] == INC_DIS_PENDING))
-      {
-        ncci_free_receive_buffers (plci, ncci);
-
-        nl_req_ncci(plci,N_EDATA,(byte)ncci);
-
-        plci->adapter->ncci_state[ncci] = IDLE;
-        start_internal_command (Id, plci, fax_disconnect_command);
-        return 1;
-      }
-    }
-  }
-  return false;
+	word ncci;
+	word i;
+
+	ncci = (word)(Id >> 16);
+	dbug(1, dprintf("disconnect_b3_res(ncci=0x%x", ncci));
+	if (plci && ncci) {
+		plci->requested_options_conn = 0;
+		plci->fax_connect_info_length = 0;
+		plci->ncpi_state = 0x00;
+		if (((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE))
+		    && ((plci->B2_prot != B2_LAPD) && (plci->B2_prot != B2_LAPD_FREE_SAPI_SEL)))
+		{
+			plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
+		}
+		for (i = 0; i < MAX_CHANNELS_PER_PLCI && plci->inc_dis_ncci_table[i] != (byte)ncci; i++);
+		if (i < MAX_CHANNELS_PER_PLCI) {
+			if (plci->channels)plci->channels--;
+			for (; i < MAX_CHANNELS_PER_PLCI - 1; i++) plci->inc_dis_ncci_table[i] = plci->inc_dis_ncci_table[i + 1];
+			plci->inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI - 1] = 0;
+
+			ncci_free_receive_buffers(plci, ncci);
+
+			if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) {
+				if (plci->State == SUSPENDING) {
+					sendf(plci->appl,
+					      _FACILITY_I,
+					      Id & 0xffffL,
+					      0,
+					      "ws", (word)3, "\x03\x04\x00\x00");
+					sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
+				}
+				plci_remove(plci);
+				plci->State = IDLE;
+			}
+		}
+		else
+		{
+			if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
+			    && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
+			    && (a->ncci_state[ncci] == INC_DIS_PENDING))
+			{
+				ncci_free_receive_buffers(plci, ncci);
+
+				nl_req_ncci(plci, N_EDATA, (byte)ncci);
+
+				plci->adapter->ncci_state[ncci] = IDLE;
+				start_internal_command(Id, plci, fax_disconnect_command);
+				return 1;
+			}
+		}
+	}
+	return false;
 }
 
 static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  NCCI   *ncci_ptr;
-  DATA_B3_DESC   *data;
-  word Info;
-  word ncci;
-  word i;
-
-  dbug(1,dprintf("data_b3_req"));
-
-  Info = _WRONG_IDENTIFIER;
-  ncci = (word)(Id>>16);
-  dbug(1,dprintf("ncci=0x%x, plci=0x%x",ncci,plci));
-
-  if (plci && ncci)
-  {
-    Info = _WRONG_STATE;
-    if ((a->ncci_state[ncci] == CONNECTED)
-     || (a->ncci_state[ncci] == INC_ACT_PENDING))
-    {
-        /* queue data */
-      ncci_ptr = &(a->ncci[ncci]);
-      i = ncci_ptr->data_out + ncci_ptr->data_pending;
-      if (i >= MAX_DATA_B3)
-        i -= MAX_DATA_B3;
-      data = &(ncci_ptr->DBuffer[i]);
-      data->Number = Number;
-      if ((((byte   *)(parms[0].info)) >= ((byte   *)(plci->msg_in_queue)))
-       && (((byte   *)(parms[0].info)) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
-      {
-
-        data->P = (byte *)(long)(*((dword *)(parms[0].info)));
-
-      }
-      else
-        data->P = TransmitBufferSet(appl,*(dword *)parms[0].info);
-      data->Length = GET_WORD(parms[1].info);
-      data->Handle = GET_WORD(parms[2].info);
-      data->Flags = GET_WORD(parms[3].info);
-      (ncci_ptr->data_pending)++;
-
-        /* check for delivery confirmation */
-      if (data->Flags & 0x0004)
-      {
-        i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending;
-        if (i >= MAX_DATA_ACK)
-          i -= MAX_DATA_ACK;
-        ncci_ptr->DataAck[i].Number = data->Number;
-        ncci_ptr->DataAck[i].Handle = data->Handle;
-        (ncci_ptr->data_ack_pending)++;
-      }
-
-      send_data(plci);
-      return false;
-    }
-  }
-  if (appl)
-  {
-    if (plci)
-    {
-      if ((((byte   *)(parms[0].info)) >= ((byte   *)(plci->msg_in_queue)))
-       && (((byte   *)(parms[0].info)) < ((byte   *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
-      {
-
-        TransmitBufferFree (appl, (byte *)(long)(*((dword *)(parms[0].info))));
-
-      }
-    }
-    sendf(appl,
-          _DATA_B3_R|CONFIRM,
-          Id,
-          Number,
-          "ww",GET_WORD(parms[2].info),Info);
-  }
-  return false;
+	NCCI *ncci_ptr;
+	DATA_B3_DESC *data;
+	word Info;
+	word ncci;
+	word i;
+
+	dbug(1, dprintf("data_b3_req"));
+
+	Info = _WRONG_IDENTIFIER;
+	ncci = (word)(Id >> 16);
+	dbug(1, dprintf("ncci=0x%x, plci=0x%x", ncci, plci));
+
+	if (plci && ncci)
+	{
+		Info = _WRONG_STATE;
+		if ((a->ncci_state[ncci] == CONNECTED)
+		    || (a->ncci_state[ncci] == INC_ACT_PENDING))
+		{
+			/* queue data */
+			ncci_ptr = &(a->ncci[ncci]);
+			i = ncci_ptr->data_out + ncci_ptr->data_pending;
+			if (i >= MAX_DATA_B3)
+				i -= MAX_DATA_B3;
+			data = &(ncci_ptr->DBuffer[i]);
+			data->Number = Number;
+			if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue)))
+			    && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
+			{
+
+				data->P = (byte *)(long)(*((dword *)(parms[0].info)));
+
+			}
+			else
+				data->P = TransmitBufferSet(appl, *(dword *)parms[0].info);
+			data->Length = GET_WORD(parms[1].info);
+			data->Handle = GET_WORD(parms[2].info);
+			data->Flags = GET_WORD(parms[3].info);
+			(ncci_ptr->data_pending)++;
+
+			/* check for delivery confirmation */
+			if (data->Flags & 0x0004)
+			{
+				i = ncci_ptr->data_ack_out + ncci_ptr->data_ack_pending;
+				if (i >= MAX_DATA_ACK)
+					i -= MAX_DATA_ACK;
+				ncci_ptr->DataAck[i].Number = data->Number;
+				ncci_ptr->DataAck[i].Handle = data->Handle;
+				(ncci_ptr->data_ack_pending)++;
+			}
+
+			send_data(plci);
+			return false;
+		}
+	}
+	if (appl)
+	{
+		if (plci)
+		{
+			if ((((byte *)(parms[0].info)) >= ((byte *)(plci->msg_in_queue)))
+			    && (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
+			{
+
+				TransmitBufferFree(appl, (byte *)(long)(*((dword *)(parms[0].info))));
+
+			}
+		}
+		sendf(appl,
+		      _DATA_B3_R | CONFIRM,
+		      Id,
+		      Number,
+		      "ww", GET_WORD(parms[2].info), Info);
+	}
+	return false;
 }
 
 static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word n;
-  word ncci;
-  word NCCIcode;
-
-  dbug(1,dprintf("data_b3_res"));
-
-  ncci = (word)(Id>>16);
-  if(plci && ncci) {
-    n = GET_WORD(parms[0].info);
-    dbug(1,dprintf("free(%d)",n));
-    NCCIcode = ncci | (((word) a->Id) << 8);
-    if(n<appl->MaxBuffer &&
-       appl->DataNCCI[n]==NCCIcode &&
-       (byte)(appl->DataFlags[n]>>8)==plci->Id) {
-      dbug(1,dprintf("found"));
-      appl->DataNCCI[n] = 0;
-
-      if (channel_can_xon (plci, a->ncci_ch[ncci])) {
-        channel_request_xon (plci, a->ncci_ch[ncci]);
-      }
-      channel_xmit_xon (plci);
-
-      if(appl->DataFlags[n] &4) {
-        nl_req_ncci(plci,N_DATA_ACK,(byte)ncci);
-        return 1;
-      }
-    }
-  }
-  return false;
+	word n;
+	word ncci;
+	word NCCIcode;
+
+	dbug(1, dprintf("data_b3_res"));
+
+	ncci = (word)(Id >> 16);
+	if (plci && ncci) {
+		n = GET_WORD(parms[0].info);
+		dbug(1, dprintf("free(%d)", n));
+		NCCIcode = ncci | (((word) a->Id) << 8);
+		if (n < appl->MaxBuffer &&
+		    appl->DataNCCI[n] == NCCIcode &&
+		    (byte)(appl->DataFlags[n] >> 8) == plci->Id) {
+			dbug(1, dprintf("found"));
+			appl->DataNCCI[n] = 0;
+
+			if (channel_can_xon(plci, a->ncci_ch[ncci])) {
+				channel_request_xon(plci, a->ncci_ch[ncci]);
+			}
+			channel_xmit_xon(plci);
+
+			if (appl->DataFlags[n] & 4) {
+				nl_req_ncci(plci, N_DATA_ACK, (byte)ncci);
+				return 1;
+			}
+		}
+	}
+	return false;
 }
 
 static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			 PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word Info;
-  word ncci;
-
-  dbug(1,dprintf("reset_b3_req"));
-
-  Info = _WRONG_IDENTIFIER;
-  ncci = (word)(Id>>16);
-  if(plci && ncci)
-  {
-    Info = _WRONG_STATE;
-    switch (plci->B3_prot)
-    {
-    case B3_ISO8208:
-    case B3_X25_DCE:
-      if(a->ncci_state[ncci]==CONNECTED)
-      {
-        nl_req_ncci(plci,N_RESET,(byte)ncci);
-        send_req(plci);
-        Info = GOOD;
-      }
-      break;
-    case B3_TRANSPARENT:
-      if(a->ncci_state[ncci]==CONNECTED)
-      {
-        start_internal_command (Id, plci, reset_b3_command);
-        Info = GOOD;
-      }
-      break;
-    }
-  }
-  /* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
-  sendf(appl,
-        _RESET_B3_R|CONFIRM,
-        Id,
-        Number,
-        "w",Info);
-  return false;
+	word Info;
+	word ncci;
+
+	dbug(1, dprintf("reset_b3_req"));
+
+	Info = _WRONG_IDENTIFIER;
+	ncci = (word)(Id >> 16);
+	if (plci && ncci)
+	{
+		Info = _WRONG_STATE;
+		switch (plci->B3_prot)
+		{
+		case B3_ISO8208:
+		case B3_X25_DCE:
+			if (a->ncci_state[ncci] == CONNECTED)
+			{
+				nl_req_ncci(plci, N_RESET, (byte)ncci);
+				send_req(plci);
+				Info = GOOD;
+			}
+			break;
+		case B3_TRANSPARENT:
+			if (a->ncci_state[ncci] == CONNECTED)
+			{
+				start_internal_command(Id, plci, reset_b3_command);
+				Info = GOOD;
+			}
+			break;
+		}
+	}
+	/* reset_b3 must result in a reset_b3_con & reset_b3_Ind */
+	sendf(appl,
+	      _RESET_B3_R | CONFIRM,
+	      Id,
+	      Number,
+	      "w", Info);
+	return false;
 }
 
 static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			 PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word ncci;
-
-  dbug(1,dprintf("reset_b3_res"));
-
-  ncci = (word)(Id>>16);
-  if(plci && ncci) {
-    switch (plci->B3_prot)
-    {
-    case B3_ISO8208:
-    case B3_X25_DCE:
-      if(a->ncci_state[ncci]==INC_RES_PENDING)
-      {
-        a->ncci_state[ncci] = CONNECTED;
-        nl_req_ncci(plci,N_RESET_ACK,(byte)ncci);
-        return true;
-      }
-    break;
-    }
-  }
-  return false;
+	word ncci;
+
+	dbug(1, dprintf("reset_b3_res"));
+
+	ncci = (word)(Id >> 16);
+	if (plci && ncci) {
+		switch (plci->B3_prot)
+		{
+		case B3_ISO8208:
+		case B3_X25_DCE:
+			if (a->ncci_state[ncci] == INC_RES_PENDING)
+			{
+				a->ncci_state[ncci] = CONNECTED;
+				nl_req_ncci(plci, N_RESET_ACK, (byte)ncci);
+				return true;
+			}
+			break;
+		}
+	}
+	return false;
 }
 
 static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 				 PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word ncci;
-  API_PARSE * ncpi;
-  byte req;
-
-  dbug(1,dprintf("connect_b3_t90_a_res"));
-
-  ncci = (word)(Id>>16);
-  if(plci && ncci) {
-    if(a->ncci_state[ncci]==INC_ACT_PENDING) {
-      a->ncci_state[ncci] = CONNECTED;
-    }
-    else if(a->ncci_state[ncci]==INC_CON_PENDING) {
-      a->ncci_state[ncci] = CONNECTED;
-
-      req = N_CONNECT_ACK;
-
-        /* parms[0]==0 for CAPI original message definition! */
-      if(parms[0].info) {
-        ncpi = &parms[1];
-        if(ncpi->length>2) {
-          if(ncpi->info[1] &1) req = N_CONNECT_ACK | N_D_BIT;
-          add_d(plci,(word)(ncpi->length-3),&ncpi->info[4]);
-        }
-      }
-      nl_req_ncci(plci,req,(byte)ncci);
-      return 1;
-    }
-  }
-  return false;
+	word ncci;
+	API_PARSE *ncpi;
+	byte req;
+
+	dbug(1, dprintf("connect_b3_t90_a_res"));
+
+	ncci = (word)(Id >> 16);
+	if (plci && ncci) {
+		if (a->ncci_state[ncci] == INC_ACT_PENDING) {
+			a->ncci_state[ncci] = CONNECTED;
+		}
+		else if (a->ncci_state[ncci] == INC_CON_PENDING) {
+			a->ncci_state[ncci] = CONNECTED;
+
+			req = N_CONNECT_ACK;
+
+			/* parms[0]==0 for CAPI original message definition! */
+			if (parms[0].info) {
+				ncpi = &parms[1];
+				if (ncpi->length > 2) {
+					if (ncpi->info[1] & 1) req = N_CONNECT_ACK | N_D_BIT;
+					add_d(plci, (word)(ncpi->length - 3), &ncpi->info[4]);
+				}
+			}
+			nl_req_ncci(plci, req, (byte)ncci);
+			return 1;
+		}
+	}
+	return false;
 }
 
 
 static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			 PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  word Info=0;
-  word i;
-  byte tel;
-    API_PARSE bp_parms[7];
-
-  if(!plci || !msg)
-  {
-    Info = _WRONG_IDENTIFIER;
-  }
-  else
-  {
-    dbug(1,dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x",
-                   msg->length,plci->Id,plci->tel,plci->NL.Id,plci->appl,plci->SuppState));
-    dbug(1,dprintf("PlciState=0x%x",plci->State));
-    for(i=0;i<7;i++) bp_parms[i].length = 0;
-
-    /* check if no channel is open, no B3 connected only */
-    if((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING)
-     || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id)
-    {
-      Info = _WRONG_STATE;
-    }
-    /* check message format and fill bp_parms pointer */
-    else if(msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms))
-    {
-      Info = _WRONG_MESSAGE_FORMAT;
-    }
-    else
-    {
-      if((plci->State==INC_CON_PENDING) || (plci->State==INC_CON_ALERT)) /* send alert tone inband to the network, */
-      {                                                                  /* e.g. Qsig or RBS or Cornet-N or xess PRI */
-        if(Id & EXT_CONTROLLER)
-        {
-          sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */
-          return 0;
-        }
-        plci->State=INC_CON_CONNECTED_ALERT;
-        plci->appl = appl;
-        clear_c_ind_mask_bit (plci, (word)(appl->Id-1));
-        dump_c_ind_mask (plci);
-        for(i=0; i<max_appl; i++) /* disconnect the other appls */
-        {                         /* its quasi a connect        */
-          if(test_c_ind_mask_bit (plci, i))
-            sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
-        }
-      }
-
-      api_save_msg(msg, "s", &plci->saved_msg);
-      tel = plci->tel;
-      if(Id & EXT_CONTROLLER)
-      {
-        if(tel) /* external controller in use by this PLCI */
-        {
-          if(a->AdvSignalAppl && a->AdvSignalAppl!=appl)
-          {
-            dbug(1,dprintf("Ext_Ctrl in use 1"));
-            Info = _WRONG_STATE;
-          }
-        }
-        else  /* external controller NOT in use by this PLCI ? */
-        {
-          if(a->AdvSignalPLCI)
-          {
-            dbug(1,dprintf("Ext_Ctrl in use 2"));
-            Info = _WRONG_STATE;
-          }
-          else /* activate the codec */
-          {
-            dbug(1,dprintf("Ext_Ctrl start"));
-            if(AdvCodecSupport(a, plci, appl, 0) )
-            {
-              dbug(1,dprintf("Error in codec procedures"));
-              Info = _WRONG_STATE;
-            }
-            else if(plci->spoofed_msg==SPOOFING_REQUIRED) /* wait until codec is active */
-            {
-              plci->spoofed_msg = AWAITING_SELECT_B;
-              plci->internal_command = BLOCK_PLCI; /* lock other commands */
-              plci->command = 0;
-              dbug(1,dprintf("continue if codec loaded"));
-              return false;
-            }
-          }
-        }
-      }
-      else /* external controller bit is OFF */
-      {
-        if(tel) /* external controller in use, need to switch off */
-        {
-          if(a->AdvSignalAppl==appl)
-          {
-            CodecIdCheck(a, plci);
-            plci->tel = 0;
-            plci->adv_nl = 0;
-            dbug(1,dprintf("Ext_Ctrl disable"));
-          }
-          else
-          {
-            dbug(1,dprintf("Ext_Ctrl not requested"));
-          }
-        }
-      }
-      if (!Info)
-      {
-        if (plci->call_dir & CALL_DIR_OUT)
-          plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
-        else if (plci->call_dir & CALL_DIR_IN)
-          plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER;
-        start_internal_command (Id, plci, select_b_command);
-        return false;
-      }
-    }
-  }
-  sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", Info);
-  return false;
+	word Info = 0;
+	word i;
+	byte tel;
+	API_PARSE bp_parms[7];
+
+	if (!plci || !msg)
+	{
+		Info = _WRONG_IDENTIFIER;
+	}
+	else
+	{
+		dbug(1, dprintf("select_b_req[%d],PLCI=0x%x,Tel=0x%x,NL=0x%x,appl=0x%x,sstate=0x%x",
+				msg->length, plci->Id, plci->tel, plci->NL.Id, plci->appl, plci->SuppState));
+		dbug(1, dprintf("PlciState=0x%x", plci->State));
+		for (i = 0; i < 7; i++) bp_parms[i].length = 0;
+
+		/* check if no channel is open, no B3 connected only */
+		if ((plci->State == IDLE) || (plci->State == OUTG_DIS_PENDING) || (plci->State == INC_DIS_PENDING)
+		    || (plci->SuppState != IDLE) || plci->channels || plci->nl_remove_id)
+		{
+			Info = _WRONG_STATE;
+		}
+		/* check message format and fill bp_parms pointer */
+		else if (msg->length && api_parse(&msg->info[1], (word)msg->length, "wwwsss", bp_parms))
+		{
+			Info = _WRONG_MESSAGE_FORMAT;
+		}
+		else
+		{
+			if ((plci->State == INC_CON_PENDING) || (plci->State == INC_CON_ALERT)) /* send alert tone inband to the network, */
+			{                                                                  /* e.g. Qsig or RBS or Cornet-N or xess PRI */
+				if (Id & EXT_CONTROLLER)
+				{
+					sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", 0x2002); /* wrong controller */
+					return 0;
+				}
+				plci->State = INC_CON_CONNECTED_ALERT;
+				plci->appl = appl;
+				clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
+				dump_c_ind_mask(plci);
+				for (i = 0; i < max_appl; i++) /* disconnect the other appls */
+				{                         /* its quasi a connect        */
+					if (test_c_ind_mask_bit(plci, i))
+						sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
+				}
+			}
+
+			api_save_msg(msg, "s", &plci->saved_msg);
+			tel = plci->tel;
+			if (Id & EXT_CONTROLLER)
+			{
+				if (tel) /* external controller in use by this PLCI */
+				{
+					if (a->AdvSignalAppl && a->AdvSignalAppl != appl)
+					{
+						dbug(1, dprintf("Ext_Ctrl in use 1"));
+						Info = _WRONG_STATE;
+					}
+				}
+				else  /* external controller NOT in use by this PLCI ? */
+				{
+					if (a->AdvSignalPLCI)
+					{
+						dbug(1, dprintf("Ext_Ctrl in use 2"));
+						Info = _WRONG_STATE;
+					}
+					else /* activate the codec */
+					{
+						dbug(1, dprintf("Ext_Ctrl start"));
+						if (AdvCodecSupport(a, plci, appl, 0))
+						{
+							dbug(1, dprintf("Error in codec procedures"));
+							Info = _WRONG_STATE;
+						}
+						else if (plci->spoofed_msg == SPOOFING_REQUIRED) /* wait until codec is active */
+						{
+							plci->spoofed_msg = AWAITING_SELECT_B;
+							plci->internal_command = BLOCK_PLCI; /* lock other commands */
+							plci->command = 0;
+							dbug(1, dprintf("continue if codec loaded"));
+							return false;
+						}
+					}
+				}
+			}
+			else /* external controller bit is OFF */
+			{
+				if (tel) /* external controller in use, need to switch off */
+				{
+					if (a->AdvSignalAppl == appl)
+					{
+						CodecIdCheck(a, plci);
+						plci->tel = 0;
+						plci->adv_nl = 0;
+						dbug(1, dprintf("Ext_Ctrl disable"));
+					}
+					else
+					{
+						dbug(1, dprintf("Ext_Ctrl not requested"));
+					}
+				}
+			}
+			if (!Info)
+			{
+				if (plci->call_dir & CALL_DIR_OUT)
+					plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
+				else if (plci->call_dir & CALL_DIR_IN)
+					plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER;
+				start_internal_command(Id, plci, select_b_command);
+				return false;
+			}
+		}
+	}
+	sendf(appl, _SELECT_B_REQ | CONFIRM, Id, Number, "w", Info);
+	return false;
 }
 
 static byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			     PLCI *plci, APPL *appl, API_PARSE *parms)
 {
-  word command;
-  word i;
-  word ncci;
-  API_PARSE * m;
-    API_PARSE m_parms[5];
-  word codec;
-  byte req;
-  byte ch;
-  byte dir;
-  static byte chi[2] = {0x01,0x00};
-  static byte lli[2] = {0x01,0x00};
-  static byte codec_cai[2] = {0x01,0x01};
-  static byte null_msg = {0};
-  static API_PARSE null_parms = { 0, &null_msg };
-  PLCI   * v_plci;
-  word Info=0;
-
-  dbug(1,dprintf("manufacturer_req"));
-  for(i=0;i<5;i++) m_parms[i].length = 0;
-
-  if(GET_DWORD(parms[0].info)!=_DI_MANU_ID) {
-    Info = _WRONG_MESSAGE_FORMAT;
-  }
-  command = GET_WORD(parms[1].info);
-  m = &parms[2];
-  if (!Info)
-  {
-    switch(command) {
-    case _DI_ASSIGN_PLCI:
-      if(api_parse(&m->info[1],(word)m->length,"wbbs",m_parms)) {
-        Info = _WRONG_MESSAGE_FORMAT;
-        break;
-      }
-      codec = GET_WORD(m_parms[0].info);
-      ch = m_parms[1].info[0];
-      dir = m_parms[2].info[0];
-      if((i=get_plci(a))) {
-        plci = &a->plci[i-1];
-        plci->appl = appl;
-        plci->command = _MANUFACTURER_R;
-        plci->m_command = command;
-        plci->number = Number;
-        plci->State = LOCAL_CONNECT;
-        Id = ( ((word)plci->Id<<8)|plci->adapter->Id|0x80);
-        dbug(1,dprintf("ManCMD,plci=0x%x",Id));
-
-        if((ch==1 || ch==2) && (dir<=2)) {
-          chi[1] = (byte)(0x80|ch);
-          lli[1] = 0;
-          plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
-          switch(codec)
-          {
-          case 0:
-            Info = add_b1(plci,&m_parms[3],0,0);
-            break;
-          case 1:
-            add_p(plci,CAI,codec_cai);
-            break;
-          /* manual 'swich on' to the codec support without signalling */
-          /* first 'assign plci' with this function, then use */
-          case 2:
-            if(AdvCodecSupport(a, plci, appl, 0) ) {
-              Info = _RESOURCE_ERROR;
-            }
-            else {
-              Info = add_b1(plci,&null_parms,0,B1_FACILITY_LOCAL);
-              lli[1] = 0x10; /* local call codec stream */
-            }
-            break;
-          }
-
-          plci->State = LOCAL_CONNECT;
-          plci->manufacturer = true;
-          plci->command = _MANUFACTURER_R;
-          plci->m_command = command;
-          plci->number = Number;
-
-          if(!Info)
-          {
-            add_p(plci,LLI,lli);
-            add_p(plci,CHI,chi);
-            add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-            sig_req(plci,ASSIGN,DSIG_ID);
-
-            if(!codec)
-            {
-              Info = add_b23(plci,&m_parms[3]);
-              if(!Info)
-              {
-                nl_req_ncci(plci,ASSIGN,0);
-                send_req(plci);
-              }
-            }
-            if(!Info)
-            {
-              dbug(1,dprintf("dir=0x%x,spoof=0x%x",dir,plci->spoofed_msg));
-              if (plci->spoofed_msg==SPOOFING_REQUIRED)
-              {
-                api_save_msg (m_parms, "wbbs", &plci->saved_msg);
-                plci->spoofed_msg = AWAITING_MANUF_CON;
-                plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
-                plci->command = 0;
-                send_req(plci);
-                return false;
-              }
-              if(dir==1) {
-                sig_req(plci,CALL_REQ,0);
-              }
-              else if(!dir){
-                sig_req(plci,LISTEN_REQ,0);
-              }
-              send_req(plci);
-            }
-            else
-            {
-              sendf(appl,
-                    _MANUFACTURER_R|CONFIRM,
-                    Id,
-                    Number,
-                    "dww",_DI_MANU_ID,command,Info);
-              return 2;
-            }
-          }
-        }
-      }
-      else  Info = _OUT_OF_PLCI;
-      break;
-
-    case _DI_IDI_CTRL:
-      if(!plci)
-      {
-        Info = _WRONG_IDENTIFIER;
-        break;
-      }
-      if(api_parse(&m->info[1],(word)m->length,"bs",m_parms)) {
-        Info = _WRONG_MESSAGE_FORMAT;
-        break;
-      }
-      req = m_parms[0].info[0];
-      plci->command = _MANUFACTURER_R;
-      plci->m_command = command;
-      plci->number = Number;
-      if(req==CALL_REQ)
-      {
-        plci->b_channel = getChannel(&m_parms[1]);
-        mixer_set_bchannel_id_esc (plci, plci->b_channel);
-        if(plci->spoofed_msg==SPOOFING_REQUIRED)
-        {
-          plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON;
-          plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
-          plci->command = 0;
-          break;
-        }
-      }
-      else if(req==LAW_REQ)
-      {
-        plci->cr_enquiry = true;
-      }
-      add_ss(plci,FTY,&m_parms[1]);
-      sig_req(plci,req,0);
-      send_req(plci);
-      if(req==HANGUP)
-      {      
-        if (plci->NL.Id && !plci->nl_remove_id)
-        {
-          if (plci->channels)
-          {
-            for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
-            {
-              if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
-              {
-                a->ncci_state[ncci] = OUTG_DIS_PENDING;
-                cleanup_ncci_data (plci, ncci);
-                nl_req_ncci(plci,N_DISC,(byte)ncci);
-              }
-            }
-          }
-          mixer_remove (plci);
-          nl_req_ncci(plci,REMOVE,0);
-          send_req(plci);
-        }  
-      }
-      break;
-
-    case _DI_SIG_CTRL:
-    /* signalling control for loop activation B-channel */
-      if(!plci)
-      {
-        Info = _WRONG_IDENTIFIER;
-        break;
-      }
-      if(m->length){
-        plci->command = _MANUFACTURER_R;
-        plci->number = Number;
-        add_ss(plci,FTY,m);
-        sig_req(plci,SIG_CTRL,0);
-        send_req(plci);
-      }
-      else Info = _WRONG_MESSAGE_FORMAT;
-      break;
-
-    case _DI_RXT_CTRL:
-    /* activation control for receiver/transmitter B-channel */
-      if(!plci)
-      {
-        Info = _WRONG_IDENTIFIER;
-        break;
-      }
-      if(m->length){
-        plci->command = _MANUFACTURER_R;
-        plci->number = Number;
-        add_ss(plci,FTY,m);
-        sig_req(plci,DSP_CTRL,0);
-        send_req(plci);
-      }
-      else Info = _WRONG_MESSAGE_FORMAT;
-      break;
-
-    case _DI_ADV_CODEC:
-    case _DI_DSP_CTRL:
-      /* TEL_CTRL commands to support non standard adjustments: */
-      /* Ring on/off, Handset micro volume, external micro vol. */
-      /* handset+external speaker volume, receiver+transm. gain,*/
-      /* handsfree on (hookinfo off), set mixer command         */
-
-      if(command == _DI_ADV_CODEC)
-      {
-        if(!a->AdvCodecPLCI) {
-          Info = _WRONG_STATE;
-          break;
-        }
-        v_plci = a->AdvCodecPLCI;
-      }
-      else
-      {
-        if (plci
-         && (m->length >= 3)
-         && (m->info[1] == 0x1c)
-         && (m->info[2] >= 1))
-        {
-          if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS)
-          {
-            if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI))
-            {
-              Info = _WRONG_STATE;
-              break;
-            }
-            a->adv_voice_coef_length = m->info[2] - 1;
-            if (a->adv_voice_coef_length > m->length - 3)
-              a->adv_voice_coef_length = (byte)(m->length - 3);
-            if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE)
-              a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE;
-            for (i = 0; i < a->adv_voice_coef_length; i++)
-              a->adv_voice_coef_buffer[i] = m->info[4 + i];
-            if (plci->B1_facilities & B1_FACILITY_VOICE)
-              adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE);
-            break;
-          }
-          else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS)
-          {
-            if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS))
-            {
-              Info = _FACILITY_NOT_SUPPORTED;
-              break;
-            }
-
-            plci->dtmf_parameter_length = m->info[2] - 1;
-            if (plci->dtmf_parameter_length > m->length - 3)
-              plci->dtmf_parameter_length = (byte)(m->length - 3);
-            if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE)
-              plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE;
-            for (i = 0; i < plci->dtmf_parameter_length; i++)
-              plci->dtmf_parameter_buffer[i] = m->info[4+i];
-            if (plci->B1_facilities & B1_FACILITY_DTMFR)
-              dtmf_parameter_write (plci);
-            break;
-
-          }
-        }
-        v_plci = plci;
-      }
-
-      if(!v_plci)
-      {
-        Info = _WRONG_IDENTIFIER;
-        break;
-      }
-      if(m->length){
-        add_ss(v_plci,FTY,m);
-        sig_req(v_plci,TEL_CTRL,0);
-        send_req(v_plci);
-      }
-      else Info = _WRONG_MESSAGE_FORMAT;
-
-      break;
-
-    case _DI_OPTIONS_REQUEST:
-      if(api_parse(&m->info[1],(word)m->length,"d",m_parms)) {
-        Info = _WRONG_MESSAGE_FORMAT;
-        break;
-      }
-      if (GET_DWORD (m_parms[0].info) & ~a->man_profile.private_options)
-      {
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      a->requested_options_table[appl->Id-1] = GET_DWORD (m_parms[0].info);
-      break;
-
-
-
-    default:
-      Info = _WRONG_MESSAGE_FORMAT;
-      break;
-    }
-  }
-
-  sendf(appl,
-        _MANUFACTURER_R|CONFIRM,
-        Id,
-        Number,
-        "dww",_DI_MANU_ID,command,Info);
-  return false;
+	word command;
+	word i;
+	word ncci;
+	API_PARSE *m;
+	API_PARSE m_parms[5];
+	word codec;
+	byte req;
+	byte ch;
+	byte dir;
+	static byte chi[2] = {0x01, 0x00};
+	static byte lli[2] = {0x01, 0x00};
+	static byte codec_cai[2] = {0x01, 0x01};
+	static byte null_msg = {0};
+	static API_PARSE null_parms = { 0, &null_msg };
+	PLCI *v_plci;
+	word Info = 0;
+
+	dbug(1, dprintf("manufacturer_req"));
+	for (i = 0; i < 5; i++) m_parms[i].length = 0;
+
+	if (GET_DWORD(parms[0].info) != _DI_MANU_ID) {
+		Info = _WRONG_MESSAGE_FORMAT;
+	}
+	command = GET_WORD(parms[1].info);
+	m = &parms[2];
+	if (!Info)
+	{
+		switch (command) {
+		case _DI_ASSIGN_PLCI:
+			if (api_parse(&m->info[1], (word)m->length, "wbbs", m_parms)) {
+				Info = _WRONG_MESSAGE_FORMAT;
+				break;
+			}
+			codec = GET_WORD(m_parms[0].info);
+			ch = m_parms[1].info[0];
+			dir = m_parms[2].info[0];
+			if ((i = get_plci(a))) {
+				plci = &a->plci[i - 1];
+				plci->appl = appl;
+				plci->command = _MANUFACTURER_R;
+				plci->m_command = command;
+				plci->number = Number;
+				plci->State = LOCAL_CONNECT;
+				Id = (((word)plci->Id << 8) | plci->adapter->Id | 0x80);
+				dbug(1, dprintf("ManCMD,plci=0x%x", Id));
+
+				if ((ch == 1 || ch == 2) && (dir <= 2)) {
+					chi[1] = (byte)(0x80 | ch);
+					lli[1] = 0;
+					plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
+					switch (codec)
+					{
+					case 0:
+						Info = add_b1(plci, &m_parms[3], 0, 0);
+						break;
+					case 1:
+						add_p(plci, CAI, codec_cai);
+						break;
+						/* manual 'swich on' to the codec support without signalling */
+						/* first 'assign plci' with this function, then use */
+					case 2:
+						if (AdvCodecSupport(a, plci, appl, 0)) {
+							Info = _RESOURCE_ERROR;
+						}
+						else {
+							Info = add_b1(plci, &null_parms, 0, B1_FACILITY_LOCAL);
+							lli[1] = 0x10; /* local call codec stream */
+						}
+						break;
+					}
+
+					plci->State = LOCAL_CONNECT;
+					plci->manufacturer = true;
+					plci->command = _MANUFACTURER_R;
+					plci->m_command = command;
+					plci->number = Number;
+
+					if (!Info)
+					{
+						add_p(plci, LLI, lli);
+						add_p(plci, CHI, chi);
+						add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						sig_req(plci, ASSIGN, DSIG_ID);
+
+						if (!codec)
+						{
+							Info = add_b23(plci, &m_parms[3]);
+							if (!Info)
+							{
+								nl_req_ncci(plci, ASSIGN, 0);
+								send_req(plci);
+							}
+						}
+						if (!Info)
+						{
+							dbug(1, dprintf("dir=0x%x,spoof=0x%x", dir, plci->spoofed_msg));
+							if (plci->spoofed_msg == SPOOFING_REQUIRED)
+							{
+								api_save_msg(m_parms, "wbbs", &plci->saved_msg);
+								plci->spoofed_msg = AWAITING_MANUF_CON;
+								plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
+								plci->command = 0;
+								send_req(plci);
+								return false;
+							}
+							if (dir == 1) {
+								sig_req(plci, CALL_REQ, 0);
+							}
+							else if (!dir) {
+								sig_req(plci, LISTEN_REQ, 0);
+							}
+							send_req(plci);
+						}
+						else
+						{
+							sendf(appl,
+							      _MANUFACTURER_R | CONFIRM,
+							      Id,
+							      Number,
+							      "dww", _DI_MANU_ID, command, Info);
+							return 2;
+						}
+					}
+				}
+			}
+			else  Info = _OUT_OF_PLCI;
+			break;
+
+		case _DI_IDI_CTRL:
+			if (!plci)
+			{
+				Info = _WRONG_IDENTIFIER;
+				break;
+			}
+			if (api_parse(&m->info[1], (word)m->length, "bs", m_parms)) {
+				Info = _WRONG_MESSAGE_FORMAT;
+				break;
+			}
+			req = m_parms[0].info[0];
+			plci->command = _MANUFACTURER_R;
+			plci->m_command = command;
+			plci->number = Number;
+			if (req == CALL_REQ)
+			{
+				plci->b_channel = getChannel(&m_parms[1]);
+				mixer_set_bchannel_id_esc(plci, plci->b_channel);
+				if (plci->spoofed_msg == SPOOFING_REQUIRED)
+				{
+					plci->spoofed_msg = CALL_REQ | AWAITING_MANUF_CON;
+					plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
+					plci->command = 0;
+					break;
+				}
+			}
+			else if (req == LAW_REQ)
+			{
+				plci->cr_enquiry = true;
+			}
+			add_ss(plci, FTY, &m_parms[1]);
+			sig_req(plci, req, 0);
+			send_req(plci);
+			if (req == HANGUP)
+			{
+				if (plci->NL.Id && !plci->nl_remove_id)
+				{
+					if (plci->channels)
+					{
+						for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
+						{
+							if ((a->ncci_plci[ncci] == plci->Id) && (a->ncci_state[ncci] == CONNECTED))
+							{
+								a->ncci_state[ncci] = OUTG_DIS_PENDING;
+								cleanup_ncci_data(plci, ncci);
+								nl_req_ncci(plci, N_DISC, (byte)ncci);
+							}
+						}
+					}
+					mixer_remove(plci);
+					nl_req_ncci(plci, REMOVE, 0);
+					send_req(plci);
+				}
+			}
+			break;
+
+		case _DI_SIG_CTRL:
+			/* signalling control for loop activation B-channel */
+			if (!plci)
+			{
+				Info = _WRONG_IDENTIFIER;
+				break;
+			}
+			if (m->length) {
+				plci->command = _MANUFACTURER_R;
+				plci->number = Number;
+				add_ss(plci, FTY, m);
+				sig_req(plci, SIG_CTRL, 0);
+				send_req(plci);
+			}
+			else Info = _WRONG_MESSAGE_FORMAT;
+			break;
+
+		case _DI_RXT_CTRL:
+			/* activation control for receiver/transmitter B-channel */
+			if (!plci)
+			{
+				Info = _WRONG_IDENTIFIER;
+				break;
+			}
+			if (m->length) {
+				plci->command = _MANUFACTURER_R;
+				plci->number = Number;
+				add_ss(plci, FTY, m);
+				sig_req(plci, DSP_CTRL, 0);
+				send_req(plci);
+			}
+			else Info = _WRONG_MESSAGE_FORMAT;
+			break;
+
+		case _DI_ADV_CODEC:
+		case _DI_DSP_CTRL:
+			/* TEL_CTRL commands to support non standard adjustments: */
+			/* Ring on/off, Handset micro volume, external micro vol. */
+			/* handset+external speaker volume, receiver+transm. gain,*/
+			/* handsfree on (hookinfo off), set mixer command         */
+
+			if (command == _DI_ADV_CODEC)
+			{
+				if (!a->AdvCodecPLCI) {
+					Info = _WRONG_STATE;
+					break;
+				}
+				v_plci = a->AdvCodecPLCI;
+			}
+			else
+			{
+				if (plci
+				    && (m->length >= 3)
+				    && (m->info[1] == 0x1c)
+				    && (m->info[2] >= 1))
+				{
+					if (m->info[3] == DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS)
+					{
+						if ((plci->tel != ADV_VOICE) || (plci != a->AdvSignalPLCI))
+						{
+							Info = _WRONG_STATE;
+							break;
+						}
+						a->adv_voice_coef_length = m->info[2] - 1;
+						if (a->adv_voice_coef_length > m->length - 3)
+							a->adv_voice_coef_length = (byte)(m->length - 3);
+						if (a->adv_voice_coef_length > ADV_VOICE_COEF_BUFFER_SIZE)
+							a->adv_voice_coef_length = ADV_VOICE_COEF_BUFFER_SIZE;
+						for (i = 0; i < a->adv_voice_coef_length; i++)
+							a->adv_voice_coef_buffer[i] = m->info[4 + i];
+						if (plci->B1_facilities & B1_FACILITY_VOICE)
+							adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE);
+						break;
+					}
+					else if (m->info[3] == DSP_CTRL_SET_DTMF_PARAMETERS)
+					{
+						if (!(a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_PARAMETERS))
+						{
+							Info = _FACILITY_NOT_SUPPORTED;
+							break;
+						}
+
+						plci->dtmf_parameter_length = m->info[2] - 1;
+						if (plci->dtmf_parameter_length > m->length - 3)
+							plci->dtmf_parameter_length = (byte)(m->length - 3);
+						if (plci->dtmf_parameter_length > DTMF_PARAMETER_BUFFER_SIZE)
+							plci->dtmf_parameter_length = DTMF_PARAMETER_BUFFER_SIZE;
+						for (i = 0; i < plci->dtmf_parameter_length; i++)
+							plci->dtmf_parameter_buffer[i] = m->info[4 + i];
+						if (plci->B1_facilities & B1_FACILITY_DTMFR)
+							dtmf_parameter_write(plci);
+						break;
+
+					}
+				}
+				v_plci = plci;
+			}
+
+			if (!v_plci)
+			{
+				Info = _WRONG_IDENTIFIER;
+				break;
+			}
+			if (m->length) {
+				add_ss(v_plci, FTY, m);
+				sig_req(v_plci, TEL_CTRL, 0);
+				send_req(v_plci);
+			}
+			else Info = _WRONG_MESSAGE_FORMAT;
+
+			break;
+
+		case _DI_OPTIONS_REQUEST:
+			if (api_parse(&m->info[1], (word)m->length, "d", m_parms)) {
+				Info = _WRONG_MESSAGE_FORMAT;
+				break;
+			}
+			if (GET_DWORD(m_parms[0].info) & ~a->man_profile.private_options)
+			{
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			a->requested_options_table[appl->Id - 1] = GET_DWORD(m_parms[0].info);
+			break;
+
+
+
+		default:
+			Info = _WRONG_MESSAGE_FORMAT;
+			break;
+		}
+	}
+
+	sendf(appl,
+	      _MANUFACTURER_R | CONFIRM,
+	      Id,
+	      Number,
+	      "dww", _DI_MANU_ID, command, Info);
+	return false;
 }
 
 
 static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
 			     PLCI *plci, APPL *appl, API_PARSE *msg)
 {
-  word indication;
-
-    API_PARSE m_parms[3];
-  API_PARSE *ncpi;
-    API_PARSE fax_parms[9];
-  word i;
-  byte len;
-
-
-  dbug(1,dprintf("manufacturer_res"));
-
-  if ((msg[0].length == 0)
-   || (msg[1].length == 0)
-   || (GET_DWORD(msg[0].info)!=_DI_MANU_ID))
-  {
-    return false;
-  }
-  indication = GET_WORD(msg[1].info);
-  switch (indication)
-  {
-
-  case _DI_NEGOTIATE_B3:
-    if(!plci)
-      break;
-    if (((plci->B3_prot != 4) && (plci->B3_prot != 5))
-     || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
-    {
-      dbug(1,dprintf("wrong state for NEGOTIATE_B3 parameters"));
-      break;
-    }
-    if (api_parse (&msg[2].info[1], msg[2].length, "ws", m_parms))
-    {
-      dbug(1,dprintf("wrong format in NEGOTIATE_B3 parameters"));
-      break;
-    }
-    ncpi = &m_parms[1];
-    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
-    if (plci->fax_connect_info_length < len)
-    {
-      ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
-      ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
-    }
-    if (api_parse (&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
-    {
-      dbug(1,dprintf("non-standard facilities info missing or wrong format"));
-    }
-    else
-    {
-      if (plci->fax_connect_info_length <= len)
-        plci->fax_connect_info_buffer[len] = 0;
-      len += 1 + plci->fax_connect_info_buffer[len];
-      if (plci->fax_connect_info_length <= len)
-        plci->fax_connect_info_buffer[len] = 0;
-      len += 1 + plci->fax_connect_info_buffer[len];
-      if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
-        plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
-      plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
-      for (i = 0; i < fax_parms[7].length; i++)
-        plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1+i];
-    }
-    plci->fax_connect_info_length = len;
-    plci->fax_edata_ack_length = plci->fax_connect_info_length;
-    start_internal_command (Id, plci, fax_edata_ack_command);
-    break;
-
-  }
-  return false;
+	word indication;
+
+	API_PARSE m_parms[3];
+	API_PARSE *ncpi;
+	API_PARSE fax_parms[9];
+	word i;
+	byte len;
+
+
+	dbug(1, dprintf("manufacturer_res"));
+
+	if ((msg[0].length == 0)
+	    || (msg[1].length == 0)
+	    || (GET_DWORD(msg[0].info) != _DI_MANU_ID))
+	{
+		return false;
+	}
+	indication = GET_WORD(msg[1].info);
+	switch (indication)
+	{
+
+	case _DI_NEGOTIATE_B3:
+		if (!plci)
+			break;
+		if (((plci->B3_prot != 4) && (plci->B3_prot != 5))
+		    || !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
+		{
+			dbug(1, dprintf("wrong state for NEGOTIATE_B3 parameters"));
+			break;
+		}
+		if (api_parse(&msg[2].info[1], msg[2].length, "ws", m_parms))
+		{
+			dbug(1, dprintf("wrong format in NEGOTIATE_B3 parameters"));
+			break;
+		}
+		ncpi = &m_parms[1];
+		len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
+		if (plci->fax_connect_info_length < len)
+		{
+			((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
+			((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
+		}
+		if (api_parse(&ncpi->info[1], ncpi->length, "wwwwssss", fax_parms))
+		{
+			dbug(1, dprintf("non-standard facilities info missing or wrong format"));
+		}
+		else
+		{
+			if (plci->fax_connect_info_length <= len)
+				plci->fax_connect_info_buffer[len] = 0;
+			len += 1 + plci->fax_connect_info_buffer[len];
+			if (plci->fax_connect_info_length <= len)
+				plci->fax_connect_info_buffer[len] = 0;
+			len += 1 + plci->fax_connect_info_buffer[len];
+			if ((fax_parms[7].length >= 3) && (fax_parms[7].info[1] >= 2))
+				plci->nsf_control_bits = GET_WORD(&fax_parms[7].info[2]);
+			plci->fax_connect_info_buffer[len++] = (byte)(fax_parms[7].length);
+			for (i = 0; i < fax_parms[7].length; i++)
+				plci->fax_connect_info_buffer[len++] = fax_parms[7].info[1 + i];
+		}
+		plci->fax_connect_info_length = len;
+		plci->fax_edata_ack_length = plci->fax_connect_info_length;
+		start_internal_command(Id, plci, fax_edata_ack_command);
+		break;
+
+	}
+	return false;
 }
 
 /*------------------------------------------------------------------*/
 /* IDI callback function                                            */
 /*------------------------------------------------------------------*/
 
-void   callback(ENTITY   * e)
-{
-  DIVA_CAPI_ADAPTER   * a;
-  APPL   * appl;
-  PLCI   * plci;
-  CAPI_MSG   *m;
-  word i, j;
-  byte rc;
-  byte ch;
-  byte req;
-  byte global_req;
-  int no_cancel_rc;
-
-  dbug(1,dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)",
-                 (e->user[0]+1)&0x7fff,e->Id,e->Req,e->Rc,e->Ind));
-
-  a = &(adapter[(byte)e->user[0]]);
-  plci = &(a->plci[e->user[1]]);
-  no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a);
-
-  /*
-     If new protocol code and new XDI is used then CAPI should work
-     fully in accordance with IDI cpec an look on callback field instead
-     of Rc field for return codes.
-   */
-  if (((e->complete == 0xff) && no_cancel_rc) ||
-      (e->Rc && !no_cancel_rc)) {
-    rc = e->Rc;
-    ch = e->RcCh;
-    req = e->Req;
-    e->Rc = 0;
-
-    if (e->user[0] & 0x8000)
-    {
-      /*
-         If REMOVE request was sent then we have to wait until
-         return code with Id set to zero arrives.
-         All other return codes should be ignored.
-         */
-      if (req == REMOVE)
-      {
-        if (e->Id)
-        {
-          dbug(1,dprintf("cancel RC in REMOVE state"));
-          return;
-        }
-        channel_flow_control_remove (plci);
-        for (i = 0; i < 256; i++)
-        {
-          if (a->FlowControlIdTable[i] == plci->nl_remove_id)
-            a->FlowControlIdTable[i] = 0;
-        }
-        plci->nl_remove_id = 0;
-        if (plci->rx_dma_descriptor > 0) {
-          diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1);
-          plci->rx_dma_descriptor = 0;
-        }
-      }
-      if (rc == OK_FC)
-      {
-        a->FlowControlIdTable[ch] = e->Id;
-        a->FlowControlSkipTable[ch] = 0;
-
-        a->ch_flow_control[ch] |= N_OK_FC_PENDING;
-        a->ch_flow_plci[ch] = plci->Id;
-        plci->nl_req = 0;
-      }
-      else
-      {
-        /*
-          Cancel return codes self, if feature was requested
-          */
-        if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) {
-          a->FlowControlIdTable[ch] = 0;
-          if ((rc == OK) && a->FlowControlSkipTable[ch]) {
-            dbug(3,dprintf ("XDI CAPI: RC cancelled Id:0x02, Ch:%02x",                              e->Id, ch));
-            return;
-          }
-        }
-
-        if (a->ch_flow_control[ch] & N_OK_FC_PENDING)
-        {
-          a->ch_flow_control[ch] &= ~N_OK_FC_PENDING;
-          if (ch == e->ReqCh)
-            plci->nl_req = 0;
-        }
-        else
-          plci->nl_req = 0;
-      }
-      if (plci->nl_req)
-        control_rc (plci, 0, rc, ch, 0, true);
-      else
-      {
-        if (req == N_XON)
-        {
-          channel_x_on (plci, ch);
-          if (plci->internal_command)
-            control_rc (plci, req, rc, ch, 0, true);
-        }
-        else
-        {
-          if (plci->nl_global_req)
-          {
-            global_req = plci->nl_global_req;
-            plci->nl_global_req = 0;
-            if (rc != ASSIGN_OK) {
-              e->Id = 0;
-              if (plci->rx_dma_descriptor > 0) {
-                diva_free_dma_descriptor (plci, plci->rx_dma_descriptor - 1);
-                plci->rx_dma_descriptor = 0;
-              }
-            }
-            channel_xmit_xon (plci);
-            control_rc (plci, 0, rc, ch, global_req, true);
-          }
-          else if (plci->data_sent)
-          {
-            channel_xmit_xon (plci);
-            plci->data_sent = false;
-            plci->NL.XNum = 1;
-            data_rc (plci, ch);
-            if (plci->internal_command)
-              control_rc (plci, req, rc, ch, 0, true);
-          }
-          else
-          {
-            channel_xmit_xon (plci);
-            control_rc (plci, req, rc, ch, 0, true);
-          }
-        }
-      }
-    }
-    else
-    {
-      /*
-         If REMOVE request was sent then we have to wait until
-         return code with Id set to zero arrives.
-         All other return codes should be ignored.
-         */
-      if (req == REMOVE)
-      {
-        if (e->Id)
-        {
-          dbug(1,dprintf("cancel RC in REMOVE state"));
-          return;
-        }
-        plci->sig_remove_id = 0;
-      }
-      plci->sig_req = 0;
-      if (plci->sig_global_req)
-      {
-        global_req = plci->sig_global_req;
-        plci->sig_global_req = 0;
-        if (rc != ASSIGN_OK)
-          e->Id = 0;
-        channel_xmit_xon (plci);
-        control_rc (plci, 0, rc, ch, global_req, false);
-      }
-      else
-      {
-        channel_xmit_xon (plci);
-        control_rc (plci, req, rc, ch, 0, false);
-      }
-    }
-    /*
-      Again: in accordance with IDI spec Rc and Ind can't be delivered in the
-      same callback. Also if new XDI and protocol code used then jump
-      direct to finish.
-      */
-    if (no_cancel_rc) {
-      channel_xmit_xon(plci);
-      goto capi_callback_suffix;
-    }
-  }
-
-  channel_xmit_xon(plci);
-
-  if (e->Ind) {
-    if (e->user[0] &0x8000) {
-      byte Ind = e->Ind & 0x0f;
-      byte Ch = e->IndCh;
-      if (((Ind==N_DISC) || (Ind==N_DISC_ACK)) &&
-          (a->ch_flow_plci[Ch] == plci->Id)) {
-        if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) {
-          dbug(3,dprintf ("XDI CAPI: I: pending N-XON Ch:%02x", Ch));
-        }
-        a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
-      }
-      nl_ind(plci);
-      if ((e->RNR != 1) &&
-          (a->ch_flow_plci[Ch] == plci->Id) &&
-          (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) {
-        a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
-        dbug(3,dprintf ("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch));
-      }
-    } else {
-      sig_ind(plci);
-    }
-    e->Ind = 0;
-  }
+void callback(ENTITY *e)
+{
+	DIVA_CAPI_ADAPTER *a;
+	APPL *appl;
+	PLCI *plci;
+	CAPI_MSG *m;
+	word i, j;
+	byte rc;
+	byte ch;
+	byte req;
+	byte global_req;
+	int no_cancel_rc;
+
+	dbug(1, dprintf("%x:CB(%x:Req=%x,Rc=%x,Ind=%x)",
+			(e->user[0] + 1) & 0x7fff, e->Id, e->Req, e->Rc, e->Ind));
+
+	a = &(adapter[(byte)e->user[0]]);
+	plci = &(a->plci[e->user[1]]);
+	no_cancel_rc = DIVA_CAPI_SUPPORTS_NO_CANCEL(a);
+
+	/*
+	  If new protocol code and new XDI is used then CAPI should work
+	  fully in accordance with IDI cpec an look on callback field instead
+	  of Rc field for return codes.
+	*/
+	if (((e->complete == 0xff) && no_cancel_rc) ||
+	    (e->Rc && !no_cancel_rc)) {
+		rc = e->Rc;
+		ch = e->RcCh;
+		req = e->Req;
+		e->Rc = 0;
+
+		if (e->user[0] & 0x8000)
+		{
+			/*
+			  If REMOVE request was sent then we have to wait until
+			  return code with Id set to zero arrives.
+			  All other return codes should be ignored.
+			*/
+			if (req == REMOVE)
+			{
+				if (e->Id)
+				{
+					dbug(1, dprintf("cancel RC in REMOVE state"));
+					return;
+				}
+				channel_flow_control_remove(plci);
+				for (i = 0; i < 256; i++)
+				{
+					if (a->FlowControlIdTable[i] == plci->nl_remove_id)
+						a->FlowControlIdTable[i] = 0;
+				}
+				plci->nl_remove_id = 0;
+				if (plci->rx_dma_descriptor > 0) {
+					diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1);
+					plci->rx_dma_descriptor = 0;
+				}
+			}
+			if (rc == OK_FC)
+			{
+				a->FlowControlIdTable[ch] = e->Id;
+				a->FlowControlSkipTable[ch] = 0;
+
+				a->ch_flow_control[ch] |= N_OK_FC_PENDING;
+				a->ch_flow_plci[ch] = plci->Id;
+				plci->nl_req = 0;
+			}
+			else
+			{
+				/*
+				  Cancel return codes self, if feature was requested
+				*/
+				if (no_cancel_rc && (a->FlowControlIdTable[ch] == e->Id) && e->Id) {
+					a->FlowControlIdTable[ch] = 0;
+					if ((rc == OK) && a->FlowControlSkipTable[ch]) {
+						dbug(3, dprintf("XDI CAPI: RC cancelled Id:0x02, Ch:%02x", e->Id, ch));
+						return;
+					}
+				}
+
+				if (a->ch_flow_control[ch] & N_OK_FC_PENDING)
+				{
+					a->ch_flow_control[ch] &= ~N_OK_FC_PENDING;
+					if (ch == e->ReqCh)
+						plci->nl_req = 0;
+				}
+				else
+					plci->nl_req = 0;
+			}
+			if (plci->nl_req)
+				control_rc(plci, 0, rc, ch, 0, true);
+			else
+			{
+				if (req == N_XON)
+				{
+					channel_x_on(plci, ch);
+					if (plci->internal_command)
+						control_rc(plci, req, rc, ch, 0, true);
+				}
+				else
+				{
+					if (plci->nl_global_req)
+					{
+						global_req = plci->nl_global_req;
+						plci->nl_global_req = 0;
+						if (rc != ASSIGN_OK) {
+							e->Id = 0;
+							if (plci->rx_dma_descriptor > 0) {
+								diva_free_dma_descriptor(plci, plci->rx_dma_descriptor - 1);
+								plci->rx_dma_descriptor = 0;
+							}
+						}
+						channel_xmit_xon(plci);
+						control_rc(plci, 0, rc, ch, global_req, true);
+					}
+					else if (plci->data_sent)
+					{
+						channel_xmit_xon(plci);
+						plci->data_sent = false;
+						plci->NL.XNum = 1;
+						data_rc(plci, ch);
+						if (plci->internal_command)
+							control_rc(plci, req, rc, ch, 0, true);
+					}
+					else
+					{
+						channel_xmit_xon(plci);
+						control_rc(plci, req, rc, ch, 0, true);
+					}
+				}
+			}
+		}
+		else
+		{
+			/*
+			  If REMOVE request was sent then we have to wait until
+			  return code with Id set to zero arrives.
+			  All other return codes should be ignored.
+			*/
+			if (req == REMOVE)
+			{
+				if (e->Id)
+				{
+					dbug(1, dprintf("cancel RC in REMOVE state"));
+					return;
+				}
+				plci->sig_remove_id = 0;
+			}
+			plci->sig_req = 0;
+			if (plci->sig_global_req)
+			{
+				global_req = plci->sig_global_req;
+				plci->sig_global_req = 0;
+				if (rc != ASSIGN_OK)
+					e->Id = 0;
+				channel_xmit_xon(plci);
+				control_rc(plci, 0, rc, ch, global_req, false);
+			}
+			else
+			{
+				channel_xmit_xon(plci);
+				control_rc(plci, req, rc, ch, 0, false);
+			}
+		}
+		/*
+		  Again: in accordance with IDI spec Rc and Ind can't be delivered in the
+		  same callback. Also if new XDI and protocol code used then jump
+		  direct to finish.
+		*/
+		if (no_cancel_rc) {
+			channel_xmit_xon(plci);
+			goto capi_callback_suffix;
+		}
+	}
+
+	channel_xmit_xon(plci);
+
+	if (e->Ind) {
+		if (e->user[0] & 0x8000) {
+			byte Ind = e->Ind & 0x0f;
+			byte Ch = e->IndCh;
+			if (((Ind == N_DISC) || (Ind == N_DISC_ACK)) &&
+			    (a->ch_flow_plci[Ch] == plci->Id)) {
+				if (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK) {
+					dbug(3, dprintf("XDI CAPI: I: pending N-XON Ch:%02x", Ch));
+				}
+				a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
+			}
+			nl_ind(plci);
+			if ((e->RNR != 1) &&
+			    (a->ch_flow_plci[Ch] == plci->Id) &&
+			    (a->ch_flow_control[Ch] & N_RX_FLOW_CONTROL_MASK)) {
+				a->ch_flow_control[Ch] &= ~N_RX_FLOW_CONTROL_MASK;
+				dbug(3, dprintf("XDI CAPI: I: remove faked N-XON Ch:%02x", Ch));
+			}
+		} else {
+			sig_ind(plci);
+		}
+		e->Ind = 0;
+	}
 
 capi_callback_suffix:
 
-  while (!plci->req_in
-   && !plci->internal_command
-   && (plci->msg_in_write_pos != plci->msg_in_read_pos))
-  {
-    j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos;
-
-    i = (((CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc;
-
-    m = (CAPI_MSG   *)(&((byte   *)(plci->msg_in_queue))[j]);
-    appl = *((APPL   *   *)(&((byte   *)(plci->msg_in_queue))[j+i]));
-    dbug(1,dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d",
-      m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos));
-    if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
-    {
-      plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
-      plci->msg_in_read_pos = i + MSG_IN_OVERHEAD;
-    }
-    else
-    {
-      plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD;
-    }
-    if (plci->msg_in_read_pos == plci->msg_in_write_pos)
-    {
-      plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
-      plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
-    }
-    else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
-    {
-      plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
-      plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
-    }
-    i = api_put (appl, m);
-    if (i != 0)
-    {
-      if (m->header.command == _DATA_B3_R)
-
-        TransmitBufferFree (appl, (byte *)(long)(m->info.data_b3_req.Data));
-
-      dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
-      break;
-    }
-
-    if (plci->li_notify_update)
-    {
-      plci->li_notify_update = false;
-      mixer_notify_update (plci, false);
-    }
-
-  }
-  send_data(plci);
-  send_req(plci);
+	while (!plci->req_in
+	       && !plci->internal_command
+	       && (plci->msg_in_write_pos != plci->msg_in_read_pos))
+	{
+		j = (plci->msg_in_read_pos == plci->msg_in_wrap_pos) ? 0 : plci->msg_in_read_pos;
+
+		i = (((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]))->header.length + 3) & 0xfffc;
+
+		m = (CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[j]);
+		appl = *((APPL **)(&((byte *)(plci->msg_in_queue))[j + i]));
+		dbug(1, dprintf("dequeue msg(0x%04x) - write=%d read=%d wrap=%d",
+				m->header.command, plci->msg_in_write_pos, plci->msg_in_read_pos, plci->msg_in_wrap_pos));
+		if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
+		{
+			plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
+			plci->msg_in_read_pos = i + MSG_IN_OVERHEAD;
+		}
+		else
+		{
+			plci->msg_in_read_pos = j + i + MSG_IN_OVERHEAD;
+		}
+		if (plci->msg_in_read_pos == plci->msg_in_write_pos)
+		{
+			plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
+			plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
+		}
+		else if (plci->msg_in_read_pos == plci->msg_in_wrap_pos)
+		{
+			plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
+			plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
+		}
+		i = api_put(appl, m);
+		if (i != 0)
+		{
+			if (m->header.command == _DATA_B3_R)
+
+				TransmitBufferFree(appl, (byte *)(long)(m->info.data_b3_req.Data));
+
+			dbug(1, dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
+			break;
+		}
+
+		if (plci->li_notify_update)
+		{
+			plci->li_notify_update = false;
+			mixer_notify_update(plci, false);
+		}
+
+	}
+	send_data(plci);
+	send_req(plci);
 }
 
 
 static void control_rc(PLCI *plci, byte req, byte rc, byte ch, byte global_req,
 		       byte nl_rc)
 {
-  dword Id;
-  dword rId;
-  word Number;
-  word Info=0;
-  word i;
-  word ncci;
-  DIVA_CAPI_ADAPTER   * a;
-  APPL   * appl;
-  PLCI   * rplci;
-    byte SSparms[]  = "\x05\x00\x00\x02\x00\x00";
-    byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
-
-  if (!plci) {
-    dbug(0,dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc));
-    return;
-  }
-  dbug(1,dprintf("req0_in/out=%d/%d",plci->req_in,plci->req_out));
-  if(plci->req_in!=plci->req_out)
-  {
-    if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK))
-    {
-      dbug(1,dprintf("req_1return"));
-      return;
-    }
-    /* cancel outstanding request on the PLCI after SIG ASSIGN failure */
-  }
-  plci->req_in = plci->req_in_start = plci->req_out = 0;
-  dbug(1,dprintf("control_rc"));
-
-  appl = plci->appl;
-  a = plci->adapter;
-  ncci = a->ch_ncci[ch];
-  if(appl)
-  {
-    Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id;
-    if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER;
-    Number = plci->number;
-    dbug(1,dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x",Id,plci->Id,plci->tel,plci->Sig.Id,plci->command,plci->internal_command));
-    dbug(1,dprintf("channels=0x%x",plci->channels));
-    if (plci_remove_check(plci))
-      return;
-    if(req==REMOVE && rc==ASSIGN_OK)
-    {
-      sig_req(plci,HANGUP,0);
-      sig_req(plci,REMOVE,0);
-      send_req(plci);
-    }
-    if(plci->command)
-    {
-      switch(plci->command)
-      {
-      case C_HOLD_REQ:
-        dbug(1,dprintf("HoldRC=0x%x",rc));
-        SSparms[1] = (byte)S_HOLD;
-        if(rc!=OK)
-        {
-          plci->SuppState = IDLE;
-          Info = 0x2001;
-        }
-        sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms);
-        break;
-
-      case C_RETRIEVE_REQ:
-        dbug(1,dprintf("RetrieveRC=0x%x",rc));
-        SSparms[1] = (byte)S_RETRIEVE;
-        if(rc!=OK)
-        {
-          plci->SuppState = CALL_HELD;
-          Info = 0x2001;
-        }
-        sendf(appl,_FACILITY_R|CONFIRM,Id,Number,"wws",Info,3,SSparms);
-        break;
-
-      case _INFO_R:
-        dbug(1,dprintf("InfoRC=0x%x",rc));
-        if(rc!=OK) Info=_WRONG_STATE;
-        sendf(appl,_INFO_R|CONFIRM,Id,Number,"w",Info);
-        break;
-
-      case _CONNECT_R:
-        dbug(1,dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x",req,rc,global_req,nl_rc));
-        if (plci->State == INC_DIS_PENDING)
-          break;
-        if(plci->Sig.Id!=0xff)
-        {
-          if (((global_req == ASSIGN) && (rc != ASSIGN_OK))
-           || (!nl_rc && (req == CALL_REQ) && (rc != OK)))
-          {
-            dbug(1,dprintf("No more IDs/Call_Req failed"));
-            sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
-            plci_remove(plci);
-            plci->State = IDLE;
-            break;
-          }
-          if(plci->State!=LOCAL_CONNECT)plci->State = OUTG_CON_PENDING;
-          sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
-        }
-        else /* D-ch activation */
-        {
-          if (rc != ASSIGN_OK)
-          {
-            dbug(1,dprintf("No more IDs/X.25 Call_Req failed"));
-            sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
-            plci_remove(plci);
-            plci->State = IDLE;
-            break;
-          }
-          sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
-          sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"sss","","","");
-          plci->State = INC_ACT_PENDING;
-        }
-        break;
-
-      case _CONNECT_I|RESPONSE:
-        if (plci->State != INC_DIS_PENDING)
-          plci->State = INC_CON_ACCEPT;
-        break;
-
-      case _DISCONNECT_R:
-        if (plci->State == INC_DIS_PENDING)
-          break;
-        if(plci->Sig.Id!=0xff)
-        {
-          plci->State = OUTG_DIS_PENDING;
-          sendf(appl,_DISCONNECT_R|CONFIRM,Id,Number,"w",0);
-        }
-        break;
-
-      case SUSPEND_REQ:
-        break;
-
-      case RESUME_REQ:
-        break;
-
-      case _CONNECT_B3_R:
-        if(rc!=OK)
-        {
-          sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",_WRONG_IDENTIFIER);
-          break;
-        }
-        ncci = get_ncci (plci, ch, 0);
-        Id = (Id & 0xffff) | (((dword) ncci) << 16);
-        plci->channels++;
-        if(req==N_RESET)
-        {
-          a->ncci_state[ncci] = INC_ACT_PENDING;
-          sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0);
-          sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-        }
-        else
-        {
-          a->ncci_state[ncci] = OUTG_CON_PENDING;
-          sendf(appl,_CONNECT_B3_R|CONFIRM,Id,Number,"w",0);
-        }
-        break;
-
-      case _CONNECT_B3_I|RESPONSE:
-        break;
-
-      case _RESET_B3_R:
-/*        sendf(appl,_RESET_B3_R|CONFIRM,Id,Number,"w",0);*/
-        break;
-
-      case _DISCONNECT_B3_R:
-        sendf(appl,_DISCONNECT_B3_R|CONFIRM,Id,Number,"w",0);
-        break;
-
-      case _MANUFACTURER_R:
-        break;
-
-      case PERM_LIST_REQ:
-        if(rc!=OK)
-        {
-          Info = _WRONG_IDENTIFIER;
-          sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info);
-          plci_remove(plci);
-        }
-        else
-          sendf(plci->appl,_CONNECT_R|CONFIRM,Id,Number,"w",Info);
-        break;
-
-      default:
-        break;
-      }
-      plci->command = 0;
-    }
-    else if (plci->internal_command)
-    {
-      switch(plci->internal_command)
-      {
-      case BLOCK_PLCI:
-        return;
-
-      case GET_MWI_STATE:
-        if(rc==OK) /* command supported, wait for indication */
-        {
-          return;
-        }
-        plci_remove(plci);
-        break;
-
-        /* Get Supported Services */
-      case GETSERV_REQ_PEND:
-        if(rc==OK) /* command supported, wait for indication */
-        {
-          break;
-        }
-        PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
-        sendf(appl, _FACILITY_R|CONFIRM, Id, Number, "wws",0,3,SSstruct);
-        plci_remove(plci);
-        break;
-
-      case INTERR_DIVERSION_REQ_PEND:      /* Interrogate Parameters        */
-      case INTERR_NUMBERS_REQ_PEND:
-      case CF_START_PEND:                  /* Call Forwarding Start pending */
-      case CF_STOP_PEND:                   /* Call Forwarding Stop pending  */
-      case CCBS_REQUEST_REQ_PEND:
-      case CCBS_DEACTIVATE_REQ_PEND:
-      case CCBS_INTERROGATE_REQ_PEND:
-        switch(plci->internal_command)
-        {
-          case INTERR_DIVERSION_REQ_PEND:
-            SSparms[1] = S_INTERROGATE_DIVERSION;
-            break;
-          case INTERR_NUMBERS_REQ_PEND:
-            SSparms[1] = S_INTERROGATE_NUMBERS;
-            break;
-          case CF_START_PEND:
-            SSparms[1] = S_CALL_FORWARDING_START;
-            break;
-          case CF_STOP_PEND:
-            SSparms[1] = S_CALL_FORWARDING_STOP;
-            break;
-          case CCBS_REQUEST_REQ_PEND:
-            SSparms[1] = S_CCBS_REQUEST;
-            break;
-          case CCBS_DEACTIVATE_REQ_PEND:
-            SSparms[1] = S_CCBS_DEACTIVATE;
-            break;
-          case CCBS_INTERROGATE_REQ_PEND:
-            SSparms[1] = S_CCBS_INTERROGATE;
-            break;
-        }
-        if(global_req==ASSIGN)
-        {
-          dbug(1,dprintf("AssignDiversion_RC=0x%x/0x%x",req,rc));
-          return;
-        }
-        if(!plci->appl) break;
-        if(rc==ISDN_GUARD_REJ)
-        {
-          Info = _CAPI_GUARD_ERROR;
-        }
-        else if(rc!=OK)
-        {
-          Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED;
-        }
-        sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,
-              plci->number,"wws",Info,(word)3,SSparms);
-        if(Info) plci_remove(plci);
-        break;
-
-        /* 3pty conference pending */
-      case PTY_REQ_PEND:
-        if(!plci->relatedPTYPLCI) break;
-        rplci = plci->relatedPTYPLCI;
-        SSparms[1] = plci->ptyState;
-        rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
-        if(rplci->tel) rId|=EXT_CONTROLLER;
-        if(rc!=OK)
-        {
-          Info = 0x300E; /* not supported */
-          plci->relatedPTYPLCI = NULL;
-          plci->ptyState = 0;
-        }
-        sendf(rplci->appl,
-              _FACILITY_R|CONFIRM,
-              rId,
-              plci->number,
-              "wws",Info,(word)3,SSparms);
-        break;
-
-        /* Explicit Call Transfer pending */
-      case ECT_REQ_PEND:
-        dbug(1,dprintf("ECT_RC=0x%x/0x%x",req,rc));
-        if(!plci->relatedPTYPLCI) break;
-        rplci = plci->relatedPTYPLCI;
-        SSparms[1] = S_ECT;
-        rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
-        if(rplci->tel) rId|=EXT_CONTROLLER;
-        if(rc!=OK)
-        {
-          Info = 0x300E; /* not supported */
-          plci->relatedPTYPLCI = NULL;
-          plci->ptyState = 0;
-        }
-        sendf(rplci->appl,
-              _FACILITY_R|CONFIRM,
-              rId,
-              plci->number,
-              "wws",Info,(word)3,SSparms);
-        break;
-
-      case _MANUFACTURER_R:
-        dbug(1,dprintf("_Manufacturer_R=0x%x/0x%x",req,rc));
-        if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
-        {
-          dbug(1,dprintf("No more IDs"));
-          sendf(appl,_MANUFACTURER_R|CONFIRM,Id,Number,"dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI);
-          plci_remove(plci);  /* after codec init, internal codec commands pending */
-        }
-        break;
-
-      case _CONNECT_R:
-        dbug(1,dprintf("_Connect_R=0x%x/0x%x",req,rc));
-        if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
-        {
-          dbug(1,dprintf("No more IDs"));
-          sendf(appl,_CONNECT_R|CONFIRM,Id&0xffL,Number,"w",_OUT_OF_PLCI);
-          plci_remove(plci);  /* after codec init, internal codec commands pending */
-        }
-        break;
-
-      case PERM_COD_HOOK:                     /* finished with Hook_Ind */
-        return;
-
-      case PERM_COD_CALL:
-        dbug(1,dprintf("***Codec Connect_Pending A, Rc = 0x%x",rc));
-        plci->internal_command = PERM_COD_CONN_PEND;
-        return;
-
-      case PERM_COD_ASSIGN:
-        dbug(1,dprintf("***Codec Assign A, Rc = 0x%x",rc));
-        if(rc!=ASSIGN_OK) break;
-        sig_req(plci,CALL_REQ,0);
-        send_req(plci);
-        plci->internal_command = PERM_COD_CALL;
-        return;
-
-        /* Null Call Reference Request pending */
-      case C_NCR_FAC_REQ:
-        dbug(1,dprintf("NCR_FAC=0x%x/0x%x",req,rc));
-        if(global_req==ASSIGN)
-        {
-          if(rc==ASSIGN_OK)
-          {
-            return;
-          }
-          else
-          {
-            sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
-            appl->NullCREnable = false;
-            plci_remove(plci);
-          }
-        }
-        else if(req==NCR_FACILITY)
-        {
-          if(rc==OK)
-          {
-            sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",0);
-          }
-          else
-          {
-            sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
-            appl->NullCREnable = false;
-          }
-          plci_remove(plci);
-        }
-        break;
-
-      case HOOK_ON_REQ:
-        if(plci->channels)
-        {
-          if(a->ncci_state[ncci]==CONNECTED)
-          {
-            a->ncci_state[ncci] = OUTG_DIS_PENDING;
-            cleanup_ncci_data (plci, ncci);
-            nl_req_ncci(plci,N_DISC,(byte)ncci);
-          }
-          break;
-        }
-        break;
-
-      case HOOK_OFF_REQ:
-        if (plci->State == INC_DIS_PENDING)
-          break;
-        sig_req(plci,CALL_REQ,0);
-        send_req(plci);
-        plci->State=OUTG_CON_PENDING;
-        break;
-
-
-      case MWI_ACTIVATE_REQ_PEND:
-      case MWI_DEACTIVATE_REQ_PEND:
-        if(global_req == ASSIGN && rc==ASSIGN_OK)
-        {
-          dbug(1,dprintf("MWI_REQ assigned"));
-          return;
-        }
-        else if(rc!=OK)
-        {                 
-          if(rc==WRONG_IE)
-          {
-            Info = 0x2007; /* Illegal message parameter coding */
-            dbug(1,dprintf("MWI_REQ invalid parameter"));
-          }
-          else
-          {
-            Info = 0x300B; /* not supported */                      
-            dbug(1,dprintf("MWI_REQ not supported"));
-          }
-          /* 0x3010: Request not allowed in this state */
-          PUT_WORD(&SSparms[4],0x300E); /* SS not supported */
-                    
-        }
-        if(plci->internal_command==MWI_ACTIVATE_REQ_PEND)
-        {
-          PUT_WORD(&SSparms[1],S_MWI_ACTIVATE);
-        }
-        else PUT_WORD(&SSparms[1],S_MWI_DEACTIVATE);
-
-        if(plci->cr_enquiry)
-        {
-          sendf(plci->appl,
-                _FACILITY_R|CONFIRM,
-                Id&0xf,
-                plci->number,
-                "wws",Info,(word)3,SSparms);
-          if(rc!=OK) plci_remove(plci);
-        }
-        else
-        {
-          sendf(plci->appl,
-                _FACILITY_R|CONFIRM,
-                Id,
-                plci->number,
-                "wws",Info,(word)3,SSparms);
-        }
-        break;
-
-      case CONF_BEGIN_REQ_PEND:
-      case CONF_ADD_REQ_PEND:
-      case CONF_SPLIT_REQ_PEND:
-      case CONF_DROP_REQ_PEND:
-      case CONF_ISOLATE_REQ_PEND:
-      case CONF_REATTACH_REQ_PEND:
-        dbug(1,dprintf("CONF_RC=0x%x/0x%x",req,rc));
-        if((plci->internal_command==CONF_ADD_REQ_PEND)&&(!plci->relatedPTYPLCI)) break;
-        rplci = plci;
-        rId = Id;
-        switch(plci->internal_command)
-        {
-          case CONF_BEGIN_REQ_PEND:
-            SSparms[1] = S_CONF_BEGIN;
-            break;
-          case CONF_ADD_REQ_PEND:
-            SSparms[1] = S_CONF_ADD;
-            rplci = plci->relatedPTYPLCI;
-            rId = ((word)rplci->Id<<8)|rplci->adapter->Id;
-            break;
-          case CONF_SPLIT_REQ_PEND:
-            SSparms[1] = S_CONF_SPLIT;
-            break;
-          case CONF_DROP_REQ_PEND:
-            SSparms[1] = S_CONF_DROP;
-            break;
-          case CONF_ISOLATE_REQ_PEND:
-            SSparms[1] = S_CONF_ISOLATE;
-            break;
-          case CONF_REATTACH_REQ_PEND:
-            SSparms[1] = S_CONF_REATTACH;
-            break;
-        }
-        
-        if(rc!=OK)
-        {
-          Info = 0x300E; /* not supported */
-          plci->relatedPTYPLCI = NULL;
-          plci->ptyState = 0;
-        }
-        sendf(rplci->appl,
-              _FACILITY_R|CONFIRM,
-              rId,
-              plci->number,
-              "wws",Info,(word)3,SSparms);
-        break;
-
-      case VSWITCH_REQ_PEND:
-        if(rc!=OK)
-        {
-          if(plci->relatedPTYPLCI)
-          {
-            plci->relatedPTYPLCI->vswitchstate=0;
-            plci->relatedPTYPLCI->vsprot=0;
-            plci->relatedPTYPLCI->vsprotdialect=0;    
-          }
-          plci->vswitchstate=0;
-          plci->vsprot=0;
-          plci->vsprotdialect=0;
-        }
-        else
-        {
-          if(plci->relatedPTYPLCI &&
-             plci->vswitchstate==1 &&
-             plci->relatedPTYPLCI->vswitchstate==3) /* join complete */
-            plci->vswitchstate=3;
-        }
-        break;
-
-  /* Call Deflection Request pending (SSCT) */
-      case CD_REQ_PEND:
-        SSparms[1] = S_CALL_DEFLECTION;
-        if(rc!=OK)
-        {
-          Info = 0x300E; /* not supported */
-          plci->appl->CDEnable = 0;
-        }  
-        sendf(plci->appl,_FACILITY_R|CONFIRM,Id,
-          plci->number,"wws",Info,(word)3,SSparms);
-        break;
-
-      case RTP_CONNECT_B3_REQ_COMMAND_2:
-        if (rc == OK)
-        {
-          ncci = get_ncci (plci, ch, 0);
-          Id = (Id & 0xffff) | (((dword) ncci) << 16);
-          plci->channels++;
-          a->ncci_state[ncci] = OUTG_CON_PENDING;
-        }
-
-      default:
-        if (plci->internal_command_queue[0])
-        {
-          (*(plci->internal_command_queue[0]))(Id, plci, rc);
-          if (plci->internal_command)
-            return;
-        }
-        break;
-      }
-      next_internal_command (Id, plci);
-    }
-  }
-  else /* appl==0 */
-  {
-    Id = ((word)plci->Id<<8)|plci->adapter->Id;
-    if(plci->tel) Id|=EXT_CONTROLLER;
-
-    switch(plci->internal_command)
-    {
-    case BLOCK_PLCI:
-      return;
-
-    case START_L1_SIG_ASSIGN_PEND:
-    case REM_L1_SIG_ASSIGN_PEND:
-      if(global_req == ASSIGN)
-      {
-        break;
-      }
-      else
-      {
-        dbug(1,dprintf("***L1 Req rem PLCI"));
-        plci->internal_command = 0;
-        sig_req(plci,REMOVE,0);
-        send_req(plci);
-      }
-      break;
-
-      /* Call Deflection Request pending, just no appl ptr assigned */
-    case CD_REQ_PEND:
-      SSparms[1] = S_CALL_DEFLECTION;
-      if(rc!=OK)
-      {
-        Info = 0x300E; /* not supported */
-      }
-      for(i=0; i<max_appl; i++)
-      {
-        if(application[i].CDEnable)
-        {
-          if(!application[i].Id) application[i].CDEnable = 0;
-          else
-          {
-            sendf(&application[i],_FACILITY_R|CONFIRM,Id,
-                  plci->number,"wws",Info,(word)3,SSparms);
-            if(Info) application[i].CDEnable = 0;
-          }
-        }
-      }
-      plci->internal_command = 0;
-      break;
-
-    case PERM_COD_HOOK:                   /* finished with Hook_Ind */
-      return;
-
-    case PERM_COD_CALL:
-      plci->internal_command = PERM_COD_CONN_PEND;
-      dbug(1,dprintf("***Codec Connect_Pending, Rc = 0x%x",rc));
-      return;
-
-    case PERM_COD_ASSIGN:
-      dbug(1,dprintf("***Codec Assign, Rc = 0x%x",rc));
-      plci->internal_command = 0;
-      if(rc!=ASSIGN_OK) break;
-      plci->internal_command = PERM_COD_CALL;
-      sig_req(plci,CALL_REQ,0);
-      send_req(plci);
-      return;
-
-    case LISTEN_SIG_ASSIGN_PEND:
-      if(rc == ASSIGN_OK)
-      {
-        plci->internal_command = 0;
-        dbug(1,dprintf("ListenCheck, new SIG_ID = 0x%x",plci->Sig.Id));
-        add_p(plci,ESC,"\x02\x18\x00");             /* support call waiting */
-        sig_req(plci,INDICATE_REQ,0);
-        send_req(plci);
-      }
-      else
-      {
-        dbug(1,dprintf("ListenCheck failed (assignRc=0x%x)",rc));
-        a->listen_active--;
-        plci_remove(plci);
-        plci->State = IDLE;
-      }
-      break;
-
-    case USELAW_REQ:
-      if(global_req == ASSIGN)
-      {
-        if (rc==ASSIGN_OK)
-      {
-        sig_req(plci,LAW_REQ,0);
-        send_req(plci);
-        dbug(1,dprintf("Auto-Law assigned"));
-        }
-        else
-        {
-          dbug(1,dprintf("Auto-Law assign failed"));
-          a->automatic_law = 3;
-          plci->internal_command = 0;
-          a->automatic_lawPLCI = NULL;
-        }
-        break;
-      }
-      else if(req == LAW_REQ && rc==OK)
-      {
-        dbug(1,dprintf("Auto-Law initiated"));
-        a->automatic_law = 2;
-        plci->internal_command = 0;
-      }
-      else
-      {
-        dbug(1,dprintf("Auto-Law not supported"));
-        a->automatic_law = 3;
-        plci->internal_command = 0;
-        sig_req(plci,REMOVE,0);
-        send_req(plci);
-        a->automatic_lawPLCI = NULL;
-      }
-      break;
-    }
-    plci_remove_check(plci);
-  }
+	dword Id;
+	dword rId;
+	word Number;
+	word Info = 0;
+	word i;
+	word ncci;
+	DIVA_CAPI_ADAPTER *a;
+	APPL *appl;
+	PLCI *rplci;
+	byte SSparms[] = "\x05\x00\x00\x02\x00\x00";
+	byte SSstruct[] = "\x09\x00\x00\x06\x00\x00\x00\x00\x00\x00";
+
+	if (!plci) {
+		dbug(0, dprintf("A: control_rc, no plci %02x:%02x:%02x:%02x:%02x", req, rc, ch, global_req, nl_rc));
+		return;
+	}
+	dbug(1, dprintf("req0_in/out=%d/%d", plci->req_in, plci->req_out));
+	if (plci->req_in != plci->req_out)
+	{
+		if (nl_rc || (global_req != ASSIGN) || (rc == ASSIGN_OK))
+		{
+			dbug(1, dprintf("req_1return"));
+			return;
+		}
+		/* cancel outstanding request on the PLCI after SIG ASSIGN failure */
+	}
+	plci->req_in = plci->req_in_start = plci->req_out = 0;
+	dbug(1, dprintf("control_rc"));
+
+	appl = plci->appl;
+	a = plci->adapter;
+	ncci = a->ch_ncci[ch];
+	if (appl)
+	{
+		Id = (((dword)(ncci ? ncci : ch)) << 16) | ((word)plci->Id << 8) | a->Id;
+		if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER;
+		Number = plci->number;
+		dbug(1, dprintf("Contr_RC-Id=%08lx,plci=%x,tel=%x, entity=0x%x, command=0x%x, int_command=0x%x", Id, plci->Id, plci->tel, plci->Sig.Id, plci->command, plci->internal_command));
+		dbug(1, dprintf("channels=0x%x", plci->channels));
+		if (plci_remove_check(plci))
+			return;
+		if (req == REMOVE && rc == ASSIGN_OK)
+		{
+			sig_req(plci, HANGUP, 0);
+			sig_req(plci, REMOVE, 0);
+			send_req(plci);
+		}
+		if (plci->command)
+		{
+			switch (plci->command)
+			{
+			case C_HOLD_REQ:
+				dbug(1, dprintf("HoldRC=0x%x", rc));
+				SSparms[1] = (byte)S_HOLD;
+				if (rc != OK)
+				{
+					plci->SuppState = IDLE;
+					Info = 0x2001;
+				}
+				sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms);
+				break;
+
+			case C_RETRIEVE_REQ:
+				dbug(1, dprintf("RetrieveRC=0x%x", rc));
+				SSparms[1] = (byte)S_RETRIEVE;
+				if (rc != OK)
+				{
+					plci->SuppState = CALL_HELD;
+					Info = 0x2001;
+				}
+				sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", Info, 3, SSparms);
+				break;
+
+			case _INFO_R:
+				dbug(1, dprintf("InfoRC=0x%x", rc));
+				if (rc != OK) Info = _WRONG_STATE;
+				sendf(appl, _INFO_R | CONFIRM, Id, Number, "w", Info);
+				break;
+
+			case _CONNECT_R:
+				dbug(1, dprintf("Connect_R=0x%x/0x%x/0x%x/0x%x", req, rc, global_req, nl_rc));
+				if (plci->State == INC_DIS_PENDING)
+					break;
+				if (plci->Sig.Id != 0xff)
+				{
+					if (((global_req == ASSIGN) && (rc != ASSIGN_OK))
+					    || (!nl_rc && (req == CALL_REQ) && (rc != OK)))
+					{
+						dbug(1, dprintf("No more IDs/Call_Req failed"));
+						sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
+						plci_remove(plci);
+						plci->State = IDLE;
+						break;
+					}
+					if (plci->State != LOCAL_CONNECT) plci->State = OUTG_CON_PENDING;
+					sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
+				}
+				else /* D-ch activation */
+				{
+					if (rc != ASSIGN_OK)
+					{
+						dbug(1, dprintf("No more IDs/X.25 Call_Req failed"));
+						sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
+						plci_remove(plci);
+						plci->State = IDLE;
+						break;
+					}
+					sendf(appl, _CONNECT_R | CONFIRM, Id, Number, "w", 0);
+					sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "sss", "", "", "");
+					plci->State = INC_ACT_PENDING;
+				}
+				break;
+
+			case _CONNECT_I | RESPONSE:
+				if (plci->State != INC_DIS_PENDING)
+					plci->State = INC_CON_ACCEPT;
+				break;
+
+			case _DISCONNECT_R:
+				if (plci->State == INC_DIS_PENDING)
+					break;
+				if (plci->Sig.Id != 0xff)
+				{
+					plci->State = OUTG_DIS_PENDING;
+					sendf(appl, _DISCONNECT_R | CONFIRM, Id, Number, "w", 0);
+				}
+				break;
+
+			case SUSPEND_REQ:
+				break;
+
+			case RESUME_REQ:
+				break;
+
+			case _CONNECT_B3_R:
+				if (rc != OK)
+				{
+					sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", _WRONG_IDENTIFIER);
+					break;
+				}
+				ncci = get_ncci(plci, ch, 0);
+				Id = (Id & 0xffff) | (((dword) ncci) << 16);
+				plci->channels++;
+				if (req == N_RESET)
+				{
+					a->ncci_state[ncci] = INC_ACT_PENDING;
+					sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
+					sendf(appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+				}
+				else
+				{
+					a->ncci_state[ncci] = OUTG_CON_PENDING;
+					sendf(appl, _CONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
+				}
+				break;
+
+			case _CONNECT_B3_I | RESPONSE:
+				break;
+
+			case _RESET_B3_R:
+/*        sendf(appl, _RESET_B3_R | CONFIRM, Id, Number, "w", 0);*/
+				break;
+
+			case _DISCONNECT_B3_R:
+				sendf(appl, _DISCONNECT_B3_R | CONFIRM, Id, Number, "w", 0);
+				break;
+
+			case _MANUFACTURER_R:
+				break;
+
+			case PERM_LIST_REQ:
+				if (rc != OK)
+				{
+					Info = _WRONG_IDENTIFIER;
+					sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info);
+					plci_remove(plci);
+				}
+				else
+					sendf(plci->appl, _CONNECT_R | CONFIRM, Id, Number, "w", Info);
+				break;
+
+			default:
+				break;
+			}
+			plci->command = 0;
+		}
+		else if (plci->internal_command)
+		{
+			switch (plci->internal_command)
+			{
+			case BLOCK_PLCI:
+				return;
+
+			case GET_MWI_STATE:
+				if (rc == OK) /* command supported, wait for indication */
+				{
+					return;
+				}
+				plci_remove(plci);
+				break;
+
+				/* Get Supported Services */
+			case GETSERV_REQ_PEND:
+				if (rc == OK) /* command supported, wait for indication */
+				{
+					break;
+				}
+				PUT_DWORD(&SSstruct[6], MASK_TERMINAL_PORTABILITY);
+				sendf(appl, _FACILITY_R | CONFIRM, Id, Number, "wws", 0, 3, SSstruct);
+				plci_remove(plci);
+				break;
+
+			case INTERR_DIVERSION_REQ_PEND:      /* Interrogate Parameters        */
+			case INTERR_NUMBERS_REQ_PEND:
+			case CF_START_PEND:                  /* Call Forwarding Start pending */
+			case CF_STOP_PEND:                   /* Call Forwarding Stop pending  */
+			case CCBS_REQUEST_REQ_PEND:
+			case CCBS_DEACTIVATE_REQ_PEND:
+			case CCBS_INTERROGATE_REQ_PEND:
+				switch (plci->internal_command)
+				{
+				case INTERR_DIVERSION_REQ_PEND:
+					SSparms[1] = S_INTERROGATE_DIVERSION;
+					break;
+				case INTERR_NUMBERS_REQ_PEND:
+					SSparms[1] = S_INTERROGATE_NUMBERS;
+					break;
+				case CF_START_PEND:
+					SSparms[1] = S_CALL_FORWARDING_START;
+					break;
+				case CF_STOP_PEND:
+					SSparms[1] = S_CALL_FORWARDING_STOP;
+					break;
+				case CCBS_REQUEST_REQ_PEND:
+					SSparms[1] = S_CCBS_REQUEST;
+					break;
+				case CCBS_DEACTIVATE_REQ_PEND:
+					SSparms[1] = S_CCBS_DEACTIVATE;
+					break;
+				case CCBS_INTERROGATE_REQ_PEND:
+					SSparms[1] = S_CCBS_INTERROGATE;
+					break;
+				}
+				if (global_req == ASSIGN)
+				{
+					dbug(1, dprintf("AssignDiversion_RC=0x%x/0x%x", req, rc));
+					return;
+				}
+				if (!plci->appl) break;
+				if (rc == ISDN_GUARD_REJ)
+				{
+					Info = _CAPI_GUARD_ERROR;
+				}
+				else if (rc != OK)
+				{
+					Info = _SUPPLEMENTARY_SERVICE_NOT_SUPPORTED;
+				}
+				sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7,
+				      plci->number, "wws", Info, (word)3, SSparms);
+				if (Info) plci_remove(plci);
+				break;
+
+				/* 3pty conference pending */
+			case PTY_REQ_PEND:
+				if (!plci->relatedPTYPLCI) break;
+				rplci = plci->relatedPTYPLCI;
+				SSparms[1] = plci->ptyState;
+				rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
+				if (rplci->tel) rId |= EXT_CONTROLLER;
+				if (rc != OK)
+				{
+					Info = 0x300E; /* not supported */
+					plci->relatedPTYPLCI = NULL;
+					plci->ptyState = 0;
+				}
+				sendf(rplci->appl,
+				      _FACILITY_R | CONFIRM,
+				      rId,
+				      plci->number,
+				      "wws", Info, (word)3, SSparms);
+				break;
+
+				/* Explicit Call Transfer pending */
+			case ECT_REQ_PEND:
+				dbug(1, dprintf("ECT_RC=0x%x/0x%x", req, rc));
+				if (!plci->relatedPTYPLCI) break;
+				rplci = plci->relatedPTYPLCI;
+				SSparms[1] = S_ECT;
+				rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
+				if (rplci->tel) rId |= EXT_CONTROLLER;
+				if (rc != OK)
+				{
+					Info = 0x300E; /* not supported */
+					plci->relatedPTYPLCI = NULL;
+					plci->ptyState = 0;
+				}
+				sendf(rplci->appl,
+				      _FACILITY_R | CONFIRM,
+				      rId,
+				      plci->number,
+				      "wws", Info, (word)3, SSparms);
+				break;
+
+			case _MANUFACTURER_R:
+				dbug(1, dprintf("_Manufacturer_R=0x%x/0x%x", req, rc));
+				if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
+				{
+					dbug(1, dprintf("No more IDs"));
+					sendf(appl, _MANUFACTURER_R | CONFIRM, Id, Number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI);
+					plci_remove(plci);  /* after codec init, internal codec commands pending */
+				}
+				break;
+
+			case _CONNECT_R:
+				dbug(1, dprintf("_Connect_R=0x%x/0x%x", req, rc));
+				if ((global_req == ASSIGN) && (rc != ASSIGN_OK))
+				{
+					dbug(1, dprintf("No more IDs"));
+					sendf(appl, _CONNECT_R | CONFIRM, Id & 0xffL, Number, "w", _OUT_OF_PLCI);
+					plci_remove(plci);  /* after codec init, internal codec commands pending */
+				}
+				break;
+
+			case PERM_COD_HOOK:                     /* finished with Hook_Ind */
+				return;
+
+			case PERM_COD_CALL:
+				dbug(1, dprintf("***Codec Connect_Pending A, Rc = 0x%x", rc));
+				plci->internal_command = PERM_COD_CONN_PEND;
+				return;
+
+			case PERM_COD_ASSIGN:
+				dbug(1, dprintf("***Codec Assign A, Rc = 0x%x", rc));
+				if (rc != ASSIGN_OK) break;
+				sig_req(plci, CALL_REQ, 0);
+				send_req(plci);
+				plci->internal_command = PERM_COD_CALL;
+				return;
+
+				/* Null Call Reference Request pending */
+			case C_NCR_FAC_REQ:
+				dbug(1, dprintf("NCR_FAC=0x%x/0x%x", req, rc));
+				if (global_req == ASSIGN)
+				{
+					if (rc == ASSIGN_OK)
+					{
+						return;
+					}
+					else
+					{
+						sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE);
+						appl->NullCREnable = false;
+						plci_remove(plci);
+					}
+				}
+				else if (req == NCR_FACILITY)
+				{
+					if (rc == OK)
+					{
+						sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", 0);
+					}
+					else
+					{
+						sendf(appl, _INFO_R | CONFIRM, Id & 0xf, Number, "w", _WRONG_STATE);
+						appl->NullCREnable = false;
+					}
+					plci_remove(plci);
+				}
+				break;
+
+			case HOOK_ON_REQ:
+				if (plci->channels)
+				{
+					if (a->ncci_state[ncci] == CONNECTED)
+					{
+						a->ncci_state[ncci] = OUTG_DIS_PENDING;
+						cleanup_ncci_data(plci, ncci);
+						nl_req_ncci(plci, N_DISC, (byte)ncci);
+					}
+					break;
+				}
+				break;
+
+			case HOOK_OFF_REQ:
+				if (plci->State == INC_DIS_PENDING)
+					break;
+				sig_req(plci, CALL_REQ, 0);
+				send_req(plci);
+				plci->State = OUTG_CON_PENDING;
+				break;
+
+
+			case MWI_ACTIVATE_REQ_PEND:
+			case MWI_DEACTIVATE_REQ_PEND:
+				if (global_req == ASSIGN && rc == ASSIGN_OK)
+				{
+					dbug(1, dprintf("MWI_REQ assigned"));
+					return;
+				}
+				else if (rc != OK)
+				{
+					if (rc == WRONG_IE)
+					{
+						Info = 0x2007; /* Illegal message parameter coding */
+						dbug(1, dprintf("MWI_REQ invalid parameter"));
+					}
+					else
+					{
+						Info = 0x300B; /* not supported */
+						dbug(1, dprintf("MWI_REQ not supported"));
+					}
+					/* 0x3010: Request not allowed in this state */
+					PUT_WORD(&SSparms[4], 0x300E); /* SS not supported */
+
+				}
+				if (plci->internal_command == MWI_ACTIVATE_REQ_PEND)
+				{
+					PUT_WORD(&SSparms[1], S_MWI_ACTIVATE);
+				}
+				else PUT_WORD(&SSparms[1], S_MWI_DEACTIVATE);
+
+				if (plci->cr_enquiry)
+				{
+					sendf(plci->appl,
+					      _FACILITY_R | CONFIRM,
+					      Id & 0xf,
+					      plci->number,
+					      "wws", Info, (word)3, SSparms);
+					if (rc != OK) plci_remove(plci);
+				}
+				else
+				{
+					sendf(plci->appl,
+					      _FACILITY_R | CONFIRM,
+					      Id,
+					      plci->number,
+					      "wws", Info, (word)3, SSparms);
+				}
+				break;
+
+			case CONF_BEGIN_REQ_PEND:
+			case CONF_ADD_REQ_PEND:
+			case CONF_SPLIT_REQ_PEND:
+			case CONF_DROP_REQ_PEND:
+			case CONF_ISOLATE_REQ_PEND:
+			case CONF_REATTACH_REQ_PEND:
+				dbug(1, dprintf("CONF_RC=0x%x/0x%x", req, rc));
+				if ((plci->internal_command == CONF_ADD_REQ_PEND) && (!plci->relatedPTYPLCI)) break;
+				rplci = plci;
+				rId = Id;
+				switch (plci->internal_command)
+				{
+				case CONF_BEGIN_REQ_PEND:
+					SSparms[1] = S_CONF_BEGIN;
+					break;
+				case CONF_ADD_REQ_PEND:
+					SSparms[1] = S_CONF_ADD;
+					rplci = plci->relatedPTYPLCI;
+					rId = ((word)rplci->Id << 8) | rplci->adapter->Id;
+					break;
+				case CONF_SPLIT_REQ_PEND:
+					SSparms[1] = S_CONF_SPLIT;
+					break;
+				case CONF_DROP_REQ_PEND:
+					SSparms[1] = S_CONF_DROP;
+					break;
+				case CONF_ISOLATE_REQ_PEND:
+					SSparms[1] = S_CONF_ISOLATE;
+					break;
+				case CONF_REATTACH_REQ_PEND:
+					SSparms[1] = S_CONF_REATTACH;
+					break;
+				}
+
+				if (rc != OK)
+				{
+					Info = 0x300E; /* not supported */
+					plci->relatedPTYPLCI = NULL;
+					plci->ptyState = 0;
+				}
+				sendf(rplci->appl,
+				      _FACILITY_R | CONFIRM,
+				      rId,
+				      plci->number,
+				      "wws", Info, (word)3, SSparms);
+				break;
+
+			case VSWITCH_REQ_PEND:
+				if (rc != OK)
+				{
+					if (plci->relatedPTYPLCI)
+					{
+						plci->relatedPTYPLCI->vswitchstate = 0;
+						plci->relatedPTYPLCI->vsprot = 0;
+						plci->relatedPTYPLCI->vsprotdialect = 0;
+					}
+					plci->vswitchstate = 0;
+					plci->vsprot = 0;
+					plci->vsprotdialect = 0;
+				}
+				else
+				{
+					if (plci->relatedPTYPLCI &&
+					    plci->vswitchstate == 1 &&
+					    plci->relatedPTYPLCI->vswitchstate == 3) /* join complete */
+						plci->vswitchstate = 3;
+				}
+				break;
+
+				/* Call Deflection Request pending (SSCT) */
+			case CD_REQ_PEND:
+				SSparms[1] = S_CALL_DEFLECTION;
+				if (rc != OK)
+				{
+					Info = 0x300E; /* not supported */
+					plci->appl->CDEnable = 0;
+				}
+				sendf(plci->appl, _FACILITY_R | CONFIRM, Id,
+				      plci->number, "wws", Info, (word)3, SSparms);
+				break;
+
+			case RTP_CONNECT_B3_REQ_COMMAND_2:
+				if (rc == OK)
+				{
+					ncci = get_ncci(plci, ch, 0);
+					Id = (Id & 0xffff) | (((dword) ncci) << 16);
+					plci->channels++;
+					a->ncci_state[ncci] = OUTG_CON_PENDING;
+				}
+
+			default:
+				if (plci->internal_command_queue[0])
+				{
+					(*(plci->internal_command_queue[0]))(Id, plci, rc);
+					if (plci->internal_command)
+						return;
+				}
+				break;
+			}
+			next_internal_command(Id, plci);
+		}
+	}
+	else /* appl==0 */
+	{
+		Id = ((word)plci->Id << 8) | plci->adapter->Id;
+		if (plci->tel) Id |= EXT_CONTROLLER;
+
+		switch (plci->internal_command)
+		{
+		case BLOCK_PLCI:
+			return;
+
+		case START_L1_SIG_ASSIGN_PEND:
+		case REM_L1_SIG_ASSIGN_PEND:
+			if (global_req == ASSIGN)
+			{
+				break;
+			}
+			else
+			{
+				dbug(1, dprintf("***L1 Req rem PLCI"));
+				plci->internal_command = 0;
+				sig_req(plci, REMOVE, 0);
+				send_req(plci);
+			}
+			break;
+
+			/* Call Deflection Request pending, just no appl ptr assigned */
+		case CD_REQ_PEND:
+			SSparms[1] = S_CALL_DEFLECTION;
+			if (rc != OK)
+			{
+				Info = 0x300E; /* not supported */
+			}
+			for (i = 0; i < max_appl; i++)
+			{
+				if (application[i].CDEnable)
+				{
+					if (!application[i].Id) application[i].CDEnable = 0;
+					else
+					{
+						sendf(&application[i], _FACILITY_R | CONFIRM, Id,
+						      plci->number, "wws", Info, (word)3, SSparms);
+						if (Info) application[i].CDEnable = 0;
+					}
+				}
+			}
+			plci->internal_command = 0;
+			break;
+
+		case PERM_COD_HOOK:                   /* finished with Hook_Ind */
+			return;
+
+		case PERM_COD_CALL:
+			plci->internal_command = PERM_COD_CONN_PEND;
+			dbug(1, dprintf("***Codec Connect_Pending, Rc = 0x%x", rc));
+			return;
+
+		case PERM_COD_ASSIGN:
+			dbug(1, dprintf("***Codec Assign, Rc = 0x%x", rc));
+			plci->internal_command = 0;
+			if (rc != ASSIGN_OK) break;
+			plci->internal_command = PERM_COD_CALL;
+			sig_req(plci, CALL_REQ, 0);
+			send_req(plci);
+			return;
+
+		case LISTEN_SIG_ASSIGN_PEND:
+			if (rc == ASSIGN_OK)
+			{
+				plci->internal_command = 0;
+				dbug(1, dprintf("ListenCheck, new SIG_ID = 0x%x", plci->Sig.Id));
+				add_p(plci, ESC, "\x02\x18\x00");             /* support call waiting */
+				sig_req(plci, INDICATE_REQ, 0);
+				send_req(plci);
+			}
+			else
+			{
+				dbug(1, dprintf("ListenCheck failed (assignRc=0x%x)", rc));
+				a->listen_active--;
+				plci_remove(plci);
+				plci->State = IDLE;
+			}
+			break;
+
+		case USELAW_REQ:
+			if (global_req == ASSIGN)
+			{
+				if (rc == ASSIGN_OK)
+				{
+					sig_req(plci, LAW_REQ, 0);
+					send_req(plci);
+					dbug(1, dprintf("Auto-Law assigned"));
+				}
+				else
+				{
+					dbug(1, dprintf("Auto-Law assign failed"));
+					a->automatic_law = 3;
+					plci->internal_command = 0;
+					a->automatic_lawPLCI = NULL;
+				}
+				break;
+			}
+			else if (req == LAW_REQ && rc == OK)
+			{
+				dbug(1, dprintf("Auto-Law initiated"));
+				a->automatic_law = 2;
+				plci->internal_command = 0;
+			}
+			else
+			{
+				dbug(1, dprintf("Auto-Law not supported"));
+				a->automatic_law = 3;
+				plci->internal_command = 0;
+				sig_req(plci, REMOVE, 0);
+				send_req(plci);
+				a->automatic_lawPLCI = NULL;
+			}
+			break;
+		}
+		plci_remove_check(plci);
+	}
 }
 
 static void data_rc(PLCI *plci, byte ch)
 {
-  dword Id;
-  DIVA_CAPI_ADAPTER   * a;
-  NCCI   *ncci_ptr;
-  DATA_B3_DESC   *data;
-  word ncci;
-
-  if (plci->appl)
-  {
-    TransmitBufferFree (plci->appl, plci->data_sent_ptr);
-    a = plci->adapter;
-    ncci = a->ch_ncci[ch];
-    if (ncci && (a->ncci_plci[ncci] == plci->Id))
-    {
-      ncci_ptr = &(a->ncci[ncci]);
-      dbug(1,dprintf("data_out=%d, data_pending=%d",ncci_ptr->data_out,ncci_ptr->data_pending));
-      if (ncci_ptr->data_pending)
-      {
-        data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
-        if (!(data->Flags &4) && a->ncci_state[ncci])
-        {
-          Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id;
-          if(plci->tel) Id|=EXT_CONTROLLER;
-          sendf(plci->appl,_DATA_B3_R|CONFIRM,Id,data->Number,
-                "ww",data->Handle,0);
-        }
-        (ncci_ptr->data_out)++;
-        if (ncci_ptr->data_out == MAX_DATA_B3)
-          ncci_ptr->data_out = 0;
-        (ncci_ptr->data_pending)--;
-      }
-    }
-  }
+	dword Id;
+	DIVA_CAPI_ADAPTER *a;
+	NCCI *ncci_ptr;
+	DATA_B3_DESC *data;
+	word ncci;
+
+	if (plci->appl)
+	{
+		TransmitBufferFree(plci->appl, plci->data_sent_ptr);
+		a = plci->adapter;
+		ncci = a->ch_ncci[ch];
+		if (ncci && (a->ncci_plci[ncci] == plci->Id))
+		{
+			ncci_ptr = &(a->ncci[ncci]);
+			dbug(1, dprintf("data_out=%d, data_pending=%d", ncci_ptr->data_out, ncci_ptr->data_pending));
+			if (ncci_ptr->data_pending)
+			{
+				data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
+				if (!(data->Flags & 4) && a->ncci_state[ncci])
+				{
+					Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id;
+					if (plci->tel) Id |= EXT_CONTROLLER;
+					sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, data->Number,
+					      "ww", data->Handle, 0);
+				}
+				(ncci_ptr->data_out)++;
+				if (ncci_ptr->data_out == MAX_DATA_B3)
+					ncci_ptr->data_out = 0;
+				(ncci_ptr->data_pending)--;
+			}
+		}
+	}
 }
 
 static void data_ack(PLCI *plci, byte ch)
 {
-  dword Id;
-  DIVA_CAPI_ADAPTER   * a;
-  NCCI   *ncci_ptr;
-  word ncci;
-
-  a = plci->adapter;
-  ncci = a->ch_ncci[ch];
-  ncci_ptr = &(a->ncci[ncci]);
-  if (ncci_ptr->data_ack_pending)
-  {
-    if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id))
-    {
-      Id = (((dword)ncci)<<16)|((word)plci->Id<<8)|a->Id;
-      if(plci->tel) Id|=EXT_CONTROLLER;
-      sendf(plci->appl,_DATA_B3_R|CONFIRM,Id,ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number,
-            "ww",ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle,0);
-    }
-    (ncci_ptr->data_ack_out)++;
-    if (ncci_ptr->data_ack_out == MAX_DATA_ACK)
-      ncci_ptr->data_ack_out = 0;
-    (ncci_ptr->data_ack_pending)--;
-  }
+	dword Id;
+	DIVA_CAPI_ADAPTER *a;
+	NCCI *ncci_ptr;
+	word ncci;
+
+	a = plci->adapter;
+	ncci = a->ch_ncci[ch];
+	ncci_ptr = &(a->ncci[ncci]);
+	if (ncci_ptr->data_ack_pending)
+	{
+		if (a->ncci_state[ncci] && (a->ncci_plci[ncci] == plci->Id))
+		{
+			Id = (((dword)ncci) << 16) | ((word)plci->Id << 8) | a->Id;
+			if (plci->tel) Id |= EXT_CONTROLLER;
+			sendf(plci->appl, _DATA_B3_R | CONFIRM, Id, ncci_ptr->DataAck[ncci_ptr->data_ack_out].Number,
+			      "ww", ncci_ptr->DataAck[ncci_ptr->data_ack_out].Handle, 0);
+		}
+		(ncci_ptr->data_ack_out)++;
+		if (ncci_ptr->data_ack_out == MAX_DATA_ACK)
+			ncci_ptr->data_ack_out = 0;
+		(ncci_ptr->data_ack_pending)--;
+	}
 }
 
 static void sig_ind(PLCI *plci)
 {
-  dword x_Id;
-  dword Id;
-  dword rId;
-  word i;
-  word cip;
-  dword cip_mask;
-  byte   *ie;
-  DIVA_CAPI_ADAPTER   * a;
-    API_PARSE saved_parms[MAX_MSG_PARMS+1];
+	dword x_Id;
+	dword Id;
+	dword rId;
+	word i;
+	word cip;
+	dword cip_mask;
+	byte *ie;
+	DIVA_CAPI_ADAPTER *a;
+	API_PARSE saved_parms[MAX_MSG_PARMS + 1];
 #define MAXPARMSIDS 31
-    byte   * parms[MAXPARMSIDS];
-    byte   * add_i[4];
-    byte   * multi_fac_parms[MAX_MULTI_IE];
-    byte   * multi_pi_parms [MAX_MULTI_IE];
-    byte   * multi_ssext_parms [MAX_MULTI_IE];
-    byte   * multi_CiPN_parms [MAX_MULTI_IE];
-
-    byte   * multi_vswitch_parms [MAX_MULTI_IE];
-
-  byte ai_len;
-    byte   *esc_chi = "";
-    byte   *esc_law = "";
-    byte   *pty_cai = "";
-    byte   *esc_cr  = "";
-    byte   *esc_profile = "";
-
-    byte facility[256];
-  PLCI   * tplci = NULL;
-  byte chi[] = "\x02\x18\x01";
-  byte voice_cai[]  = "\x06\x14\x00\x00\x00\x00\x08";
-    byte resume_cau[] = "\x05\x05\x00\x02\x00\x00";
-  /* ESC_MSGTYPE must be the last but one message, a new IE has to be */
-  /* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
-  /* SMSG is situated at the end because its 0 (for compatibility reasons */
-  /* (see Info_Mask Bit 4, first IE. then the message type)           */
-    word parms_id[] =
-         {MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA,
-          UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW,
-          RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR,
-          CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG};
-          /* 14 FTY repl by ESC_CHI */
-          /* 18 PI  repl by ESC_LAW */
-         /* removed OAD changed to 0xff for future use, OAD is multiIE now */
-     word multi_fac_id[] = {1, FTY};
-     word multi_pi_id[]  = {1, PI};
-     word multi_CiPN_id[]  = {1, OAD};
-     word multi_ssext_id[]  = {1, ESC_SSEXT};
-
-     word multi_vswitch_id[]  = {1, ESC_VSWITCH};
-
-  byte   * cau;
-  word ncci;
-    byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
-    byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
-    byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
-    byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
-  byte force_mt_info = false;
-  byte dir;
-  dword d;
-  word w;
-
-  a = plci->adapter;
-  Id = ((word)plci->Id<<8)|a->Id;
-  PUT_WORD(&SS_Ind[4],0x0000);
-
-  if (plci->sig_remove_id)
-  {
-    plci->Sig.RNR = 2; /* discard */
-    dbug(1,dprintf("SIG discard while remove pending"));
-    return;
-  }
-  if(plci->tel && plci->SuppState!=CALL_HELD) Id|=EXT_CONTROLLER;
-  dbug(1,dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
-    Id,plci->Id,plci->tel,plci->State,plci->channels,plci->hangup_flow_ctrl_timer));
-  if(plci->Sig.Ind==CALL_HOLD_ACK && plci->channels)
-  {
-    plci->Sig.RNR = 1;
-    return;
-  }
-  if(plci->Sig.Ind==HANGUP && plci->channels)
-  {
-    plci->Sig.RNR = 1;
-    plci->hangup_flow_ctrl_timer++;
-    /* recover the network layer after timeout */
-    if(plci->hangup_flow_ctrl_timer==100)
-    {
-      dbug(1,dprintf("Exceptional disc"));
-      plci->Sig.RNR = 0;
-      plci->hangup_flow_ctrl_timer = 0;
-      for (ncci = 1; ncci < MAX_NCCI+1; ncci++)
-      {
-        if (a->ncci_plci[ncci] == plci->Id)
-        {
-          cleanup_ncci_data (plci, ncci);
-          if(plci->channels)plci->channels--;
-          if (plci->appl)
-            sendf(plci->appl,_DISCONNECT_B3_I, (((dword) ncci) << 16) | Id,0,"ws",0,"");
-        }
-      }
-      if (plci->appl)
-        sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
-      plci_remove(plci);
-      plci->State=IDLE;
-    }
-    return;
-  }
-
-  /* do first parse the info with no OAD in, because OAD will be converted */
-  /* first the multiple facility IE, then mult. progress ind.              */
-  /* then the parameters for the info_ind + conn_ind                       */
-  IndParse(plci,multi_fac_id,multi_fac_parms,MAX_MULTI_IE);
-  IndParse(plci,multi_pi_id,multi_pi_parms,MAX_MULTI_IE);
-  IndParse(plci,multi_ssext_id,multi_ssext_parms,MAX_MULTI_IE);
-
-  IndParse(plci,multi_vswitch_id,multi_vswitch_parms,MAX_MULTI_IE);
-
-  IndParse(plci,parms_id,parms,0);
-  IndParse(plci,multi_CiPN_id,multi_CiPN_parms,MAX_MULTI_IE);
-  esc_chi  = parms[14];
-  esc_law  = parms[18];
-  pty_cai  = parms[24];
-  esc_cr   = parms[25];
-  esc_profile = parms[27];
-  if(esc_cr[0] && plci)
-  {
-    if(plci->cr_enquiry && plci->appl)
-    {
-      plci->cr_enquiry = false;
-      /* d = MANU_ID            */
-      /* w = m_command          */
-      /* b = total length       */
-      /* b = indication type    */
-      /* b = length of all IEs  */
-      /* b = IE1                */
-      /* S = IE1 length + cont. */
-      /* b = IE2                */
-      /* S = IE2 length + cont. */
-      sendf(plci->appl,
-        _MANUFACTURER_I,
-        Id,
-        0,
-        "dwbbbbSbS",_DI_MANU_ID,plci->m_command,
-        2+1+1+esc_cr[0]+1+1+esc_law[0],plci->Sig.Ind,1+1+esc_cr[0]+1+1+esc_law[0],ESC,esc_cr,ESC,esc_law);
-    }
-  }
-  /* create the additional info structure                                  */
-  add_i[1] = parms[15]; /* KEY of additional info */
-  add_i[2] = parms[11]; /* UUI of additional info */
-  ai_len = AddInfo(add_i,multi_fac_parms, esc_chi, facility);
-
-  /* the ESC_LAW indicates if u-Law or a-Law is actually used by the card  */
-  /* indication returns by the card if requested by the function           */
-  /* AutomaticLaw() after driver init                                      */
-  if (a->automatic_law<4)
-  {
-    if(esc_law[0]){
-      if(esc_law[2]){
-        dbug(0,dprintf("u-Law selected"));
-        a->u_law = 1;
-      }
-      else {
-        dbug(0,dprintf("a-Law selected"));
-        a->u_law = 0;
-      }
-      a->automatic_law = 4;
-      if(plci==a->automatic_lawPLCI) {
-        plci->internal_command = 0;
-        sig_req(plci,REMOVE,0);
-        send_req(plci);
-        a->automatic_lawPLCI = NULL;
-      }
-    }
-    if (esc_profile[0])
-    {
-      dbug (1, dprintf ("[%06x] CardProfile: %lx %lx %lx %lx %lx",
-        UnMapController (a->Id), GET_DWORD (&esc_profile[6]),
-        GET_DWORD (&esc_profile[10]), GET_DWORD (&esc_profile[14]),
-        GET_DWORD (&esc_profile[18]), GET_DWORD (&esc_profile[46])));
-
-      a->profile.Global_Options &= 0x000000ffL;
-      a->profile.B1_Protocols &= 0x000003ffL;
-      a->profile.B2_Protocols &= 0x00001fdfL;
-      a->profile.B3_Protocols &= 0x000000b7L;
-
-      a->profile.Global_Options &= GET_DWORD (&esc_profile[6]) |
-        GL_BCHANNEL_OPERATION_SUPPORTED;
-      a->profile.B1_Protocols &= GET_DWORD (&esc_profile[10]);
-      a->profile.B2_Protocols &= GET_DWORD (&esc_profile[14]);
-      a->profile.B3_Protocols &= GET_DWORD (&esc_profile[18]);
-      a->manufacturer_features = GET_DWORD (&esc_profile[46]);
-      a->man_profile.private_options = 0;
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER)
-      {
-        a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER;
-        a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED;
-      }
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP)
-        a->man_profile.private_options |= 1L << PRIVATE_RTP;
-      a->man_profile.rtp_primary_payloads = GET_DWORD (&esc_profile[50]);
-      a->man_profile.rtp_additional_payloads = GET_DWORD (&esc_profile[54]);
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_T38)
-        a->man_profile.private_options |= 1L << PRIVATE_T38;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD)
-        a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_V18)
-        a->man_profile.private_options |= 1L << PRIVATE_V18;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE)
-        a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS)
-        a->man_profile.private_options |= 1L << PRIVATE_PIAFS;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
-        a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN)
-        a->man_profile.private_options |= 1L << PRIVATE_VOWN;
-
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD)
-        a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD;
-
-    }
-    else
-    {
-      a->profile.Global_Options &= 0x0000007fL;
-      a->profile.B1_Protocols &= 0x000003dfL;
-      a->profile.B2_Protocols &= 0x00001adfL;
-      a->profile.B3_Protocols &= 0x000000b7L;
-      a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF;
-    }
-    if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF |
-      MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
-    {
-      a->profile.Global_Options |= GL_DTMF_SUPPORTED;
-    }
-    a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL;
-    dbug (1, dprintf ("[%06x] Profile: %lx %lx %lx %lx %lx",
-      UnMapController (a->Id), a->profile.Global_Options,
-      a->profile.B1_Protocols, a->profile.B2_Protocols,
-      a->profile.B3_Protocols, a->manufacturer_features));
-  }
-  /* codec plci for the handset/hook state support is just an internal id  */
-  if(plci!=a->AdvCodecPLCI)
-  {
-    force_mt_info =  SendMultiIE(plci,Id,multi_fac_parms, FTY, 0x20, 0);
-    force_mt_info |= SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, 0);
-    SendSSExtInd(NULL,plci,Id,multi_ssext_parms);
-    SendInfo(plci,Id, parms, force_mt_info);
-
-    VSwitchReqInd(plci,Id,multi_vswitch_parms);
-
-  }
-
-  /* switch the codec to the b-channel                                     */
-  if(esc_chi[0] && plci && !plci->SuppState){
-    plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
-    mixer_set_bchannel_id_esc (plci, plci->b_channel);
-    dbug(1,dprintf("storeChannel=0x%x",plci->b_channel));
-    if(plci->tel==ADV_VOICE && plci->appl) {
-      SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
-    }
-  }
-
-  if(plci->appl) plci->appl->Number++;
-
-  switch(plci->Sig.Ind) {
-  /* Response to Get_Supported_Services request */
-  case S_SUPPORTED:
-    dbug(1,dprintf("S_Supported"));
-    if(!plci->appl) break;
-    if(pty_cai[0]==4)
-    {
-      PUT_DWORD(&CF_Ind[6],GET_DWORD(&pty_cai[1]) );
-    }
-    else
-    {
-      PUT_DWORD(&CF_Ind[6],MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE);
-    }
-    PUT_WORD (&CF_Ind[1], 0);
-    PUT_WORD (&CF_Ind[4], 0);
-    sendf(plci->appl,_FACILITY_R|CONFIRM,Id&0x7,plci->number, "wws",0,3,CF_Ind);
-    plci_remove(plci);
-    break;
-                    
-  /* Supplementary Service rejected */
-  case S_SERVICE_REJ:
-    dbug(1,dprintf("S_Reject=0x%x",pty_cai[5]));
-    if(!pty_cai[0]) break;
-    switch (pty_cai[5])
-    {
-    case ECT_EXECUTE:
-    case THREE_PTY_END:
-    case THREE_PTY_BEGIN:
-      if(!plci->relatedPTYPLCI) break;
-      tplci = plci->relatedPTYPLCI;
-      rId = ( (word)tplci->Id<<8)|tplci->adapter->Id;
-      if(tplci->tel) rId|=EXT_CONTROLLER;
-      if(pty_cai[5]==ECT_EXECUTE)
-      {
-        PUT_WORD(&SS_Ind[1],S_ECT);
-
-        plci->vswitchstate=0;
-        plci->relatedPTYPLCI->vswitchstate=0;
-
-      }
-      else
-      {
-        PUT_WORD(&SS_Ind[1],pty_cai[5]+3);
-      }
-      if(pty_cai[2]!=0xff)
-      {
-        PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
-      }
-      else
-      {
-        PUT_WORD(&SS_Ind[4],0x300E);
-      }
-      plci->relatedPTYPLCI = NULL;
-      plci->ptyState = 0;
-      sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
-      break;
-
-    case CALL_DEFLECTION:
-      if(pty_cai[2]!=0xff)
-      {
-        PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
-      }
-      else
-      {
-        PUT_WORD(&SS_Ind[4],0x300E);
-      }
-      PUT_WORD(&SS_Ind[1],pty_cai[5]);
-      for(i=0; i<max_appl; i++)
-      {
-        if(application[i].CDEnable)
-        {
-          if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
-          application[i].CDEnable = false;
-        }
-      }
-      break;
-
-    case DEACTIVATION_DIVERSION:
-    case ACTIVATION_DIVERSION:
-    case DIVERSION_INTERROGATE_CFU:
-    case DIVERSION_INTERROGATE_CFB:
-    case DIVERSION_INTERROGATE_CFNR:
-    case DIVERSION_INTERROGATE_NUM:
-    case CCBS_REQUEST:
-    case CCBS_DEACTIVATE:
-    case CCBS_INTERROGATE:
-      if(!plci->appl) break;
-      if(pty_cai[2]!=0xff)
-      {
-        PUT_WORD(&Interr_Err_Ind[4],0x3600|(word)pty_cai[2]);
-      }
-      else
-      {
-        PUT_WORD(&Interr_Err_Ind[4],0x300E);
-      }
-      switch (pty_cai[5])
-      {
-        case DEACTIVATION_DIVERSION:
-          dbug(1,dprintf("Deact_Div"));
-          Interr_Err_Ind[0]=0x9;
-          Interr_Err_Ind[3]=0x6;
-          PUT_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_STOP);
-          break;
-        case ACTIVATION_DIVERSION:
-          dbug(1,dprintf("Act_Div"));
-          Interr_Err_Ind[0]=0x9;
-          Interr_Err_Ind[3]=0x6;
-          PUT_WORD(&Interr_Err_Ind[1],S_CALL_FORWARDING_START);
-          break;
-        case DIVERSION_INTERROGATE_CFU:
-        case DIVERSION_INTERROGATE_CFB:
-        case DIVERSION_INTERROGATE_CFNR:
-          dbug(1,dprintf("Interr_Div"));
-          Interr_Err_Ind[0]=0xa;
-          Interr_Err_Ind[3]=0x7;
-          PUT_WORD(&Interr_Err_Ind[1],S_INTERROGATE_DIVERSION);
-          break;
-        case DIVERSION_INTERROGATE_NUM:
-          dbug(1,dprintf("Interr_Num"));
-          Interr_Err_Ind[0]=0xa;
-          Interr_Err_Ind[3]=0x7;
-          PUT_WORD(&Interr_Err_Ind[1],S_INTERROGATE_NUMBERS);
-          break;
-        case CCBS_REQUEST:
-          dbug(1,dprintf("CCBS Request"));
-          Interr_Err_Ind[0]=0xd;
-          Interr_Err_Ind[3]=0xa;
-          PUT_WORD(&Interr_Err_Ind[1],S_CCBS_REQUEST);
-          break;
-        case CCBS_DEACTIVATE:
-          dbug(1,dprintf("CCBS Deactivate"));
-          Interr_Err_Ind[0]=0x9;
-          Interr_Err_Ind[3]=0x6;
-          PUT_WORD(&Interr_Err_Ind[1],S_CCBS_DEACTIVATE);
-          break;
-        case CCBS_INTERROGATE:
-          dbug(1,dprintf("CCBS Interrogate"));
-          Interr_Err_Ind[0]=0xb;
-          Interr_Err_Ind[3]=0x8;
-          PUT_WORD(&Interr_Err_Ind[1],S_CCBS_INTERROGATE);
-          break;
-      }
-      PUT_DWORD(&Interr_Err_Ind[6],plci->appl->S_Handle);
-      sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, Interr_Err_Ind);
-      plci_remove(plci);
-      break;
-    case ACTIVATION_MWI:      
-    case DEACTIVATION_MWI:
-      if(pty_cai[5]==ACTIVATION_MWI)
-      {
-        PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE);
-      }
-      else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE);
-      
-      if(pty_cai[2]!=0xff)
-      {
-        PUT_WORD(&SS_Ind[4],0x3600|(word)pty_cai[2]);
-      }
-      else
-      {
-        PUT_WORD(&SS_Ind[4],0x300E);
-      }
-
-      if(plci->cr_enquiry)
-      {
-        sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind);
-        plci_remove(plci);
-      }
-      else
-      {
-        sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
-      }
-      break;
-    case CONF_ADD: /* ERROR */
-    case CONF_BEGIN:
-    case CONF_DROP:
-    case CONF_ISOLATE:
-    case CONF_REATTACH:
-      CONF_Ind[0]=9;
-      CONF_Ind[3]=6;   
-      switch(pty_cai[5])
-      {
-      case CONF_BEGIN:
-          PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN);
-          plci->ptyState = 0;
-          break;
-      case CONF_DROP:
-          CONF_Ind[0]=5;
-          CONF_Ind[3]=2;
-          PUT_WORD(&CONF_Ind[1],S_CONF_DROP);
-          plci->ptyState = CONNECTED;
-          break;
-      case CONF_ISOLATE:
-          CONF_Ind[0]=5;
-          CONF_Ind[3]=2;
-          PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE);
-          plci->ptyState = CONNECTED;
-          break;
-      case CONF_REATTACH:
-          CONF_Ind[0]=5;
-          CONF_Ind[3]=2;
-          PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH);
-          plci->ptyState = CONNECTED;
-          break;
-      case CONF_ADD:
-          PUT_WORD(&CONF_Ind[1],S_CONF_ADD);
-          plci->relatedPTYPLCI = NULL;
-          tplci=plci->relatedPTYPLCI;
-          if(tplci) tplci->ptyState = CONNECTED;
-          plci->ptyState = CONNECTED;
-          break;
-      }
-          
-      if(pty_cai[2]!=0xff)
-      {
-        PUT_WORD(&CONF_Ind[4],0x3600|(word)pty_cai[2]);
-      }
-      else
-      {
-        PUT_WORD(&CONF_Ind[4],0x3303); /* Time-out: network did not respond
-                                            within the required time */
-      }
-
-      PUT_DWORD(&CONF_Ind[6],0x0);
-      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
-      break;
-    }
-    break;
-
-  /* Supplementary Service indicates success */
-  case S_SERVICE:
-    dbug(1,dprintf("Service_Ind"));
-    PUT_WORD (&CF_Ind[4], 0);
-    switch (pty_cai[5])
-    {
-    case THREE_PTY_END:
-    case THREE_PTY_BEGIN:
-    case ECT_EXECUTE:
-      if(!plci->relatedPTYPLCI) break;
-      tplci = plci->relatedPTYPLCI;
-      rId = ( (word)tplci->Id<<8)|tplci->adapter->Id;
-      if(tplci->tel) rId|=EXT_CONTROLLER;
-      if(pty_cai[5]==ECT_EXECUTE)
-      {
-        PUT_WORD(&SS_Ind[1],S_ECT);
-
-        if(plci->vswitchstate!=3)
-        {
-
-        plci->ptyState = IDLE;
-        plci->relatedPTYPLCI = NULL;
-        plci->ptyState = 0;
-
-        }
-
-        dbug(1,dprintf("ECT OK"));
-        sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
-
-
-
-      }
-      else
-      {
-        switch (plci->ptyState)
-        {
-        case S_3PTY_BEGIN:
-          plci->ptyState = CONNECTED;
-          dbug(1,dprintf("3PTY ON"));
-          break;
-
-        case S_3PTY_END:
-          plci->ptyState = IDLE;
-          plci->relatedPTYPLCI = NULL;
-          plci->ptyState = 0;
-          dbug(1,dprintf("3PTY OFF"));
-          break;
-        }
-        PUT_WORD(&SS_Ind[1],pty_cai[5]+3);
-        sendf(tplci->appl,_FACILITY_I,rId,0,"ws",3, SS_Ind);
-      }
-      break;
-
-    case CALL_DEFLECTION:
-      PUT_WORD(&SS_Ind[1],pty_cai[5]);
-      for(i=0; i<max_appl; i++)
-      {
-        if(application[i].CDEnable)
-        {
-          if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
-          application[i].CDEnable = false;
-        }
-      }
-      break;
-
-    case DEACTIVATION_DIVERSION:
-    case ACTIVATION_DIVERSION:
-      if(!plci->appl) break;
-      PUT_WORD(&CF_Ind[1],pty_cai[5]+2);
-      PUT_DWORD(&CF_Ind[6],plci->appl->S_Handle);
-      sendf(plci->appl,_FACILITY_I,Id&0x7,0,"ws",3, CF_Ind);
-      plci_remove(plci);
-      break;
-
-    case DIVERSION_INTERROGATE_CFU:
-    case DIVERSION_INTERROGATE_CFB:
-    case DIVERSION_INTERROGATE_CFNR:
-    case DIVERSION_INTERROGATE_NUM:
-    case CCBS_REQUEST:
-    case CCBS_DEACTIVATE:
-    case CCBS_INTERROGATE:
-      if(!plci->appl) break;
-      switch (pty_cai[5])
-      {
-        case DIVERSION_INTERROGATE_CFU:
-        case DIVERSION_INTERROGATE_CFB:
-        case DIVERSION_INTERROGATE_CFNR:
-          dbug(1,dprintf("Interr_Div"));
-          PUT_WORD(&pty_cai[1],S_INTERROGATE_DIVERSION);
-          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
-          break;
-        case DIVERSION_INTERROGATE_NUM:
-          dbug(1,dprintf("Interr_Num"));
-          PUT_WORD(&pty_cai[1],S_INTERROGATE_NUMBERS);
-          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
-          break;
-        case CCBS_REQUEST:
-          dbug(1,dprintf("CCBS Request"));
-          PUT_WORD(&pty_cai[1],S_CCBS_REQUEST);
-          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
-          break;
-        case CCBS_DEACTIVATE:
-          dbug(1,dprintf("CCBS Deactivate"));
-          PUT_WORD(&pty_cai[1],S_CCBS_DEACTIVATE);
-          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
-          break;
-        case CCBS_INTERROGATE:
-          dbug(1,dprintf("CCBS Interrogate"));
-          PUT_WORD(&pty_cai[1],S_CCBS_INTERROGATE);
-          pty_cai[3]=pty_cai[0]-3; /* Supplementary Service-specific parameter len */
-          break;
-      }
-      PUT_WORD(&pty_cai[4],0); /* Supplementary Service Reason */
-      PUT_DWORD(&pty_cai[6],plci->appl->S_Handle);
-      sendf(plci->appl,_FACILITY_I,Id&0x7,0,"wS",3, pty_cai);
-      plci_remove(plci);
-      break;
-
-    case ACTIVATION_MWI:
-    case DEACTIVATION_MWI:
-      if(pty_cai[5]==ACTIVATION_MWI)
-      {
-        PUT_WORD(&SS_Ind[1],S_MWI_ACTIVATE);
-      }
-      else PUT_WORD(&SS_Ind[1],S_MWI_DEACTIVATE);
-      if(plci->cr_enquiry)
-      {
-        sendf(plci->appl,_FACILITY_I,Id&0xf,0,"ws",3, SS_Ind);
-        plci_remove(plci);
-      }
-      else
-      {
-        sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
-      }
-      break;
-    case MWI_INDICATION:
-      if(pty_cai[0]>=0x12)
-      {
-        PUT_WORD(&pty_cai[3],S_MWI_INDICATE);
-        pty_cai[2]=pty_cai[0]-2; /* len Parameter */
-        pty_cai[5]=pty_cai[0]-5; /* Supplementary Service-specific parameter len */
-        if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_MWI))
-        {
-          if(plci->internal_command==GET_MWI_STATE) /* result on Message Waiting Listen */
-          {
-            sendf(plci->appl,_FACILITY_I,Id&0xf,0,"wS",3, &pty_cai[2]);
-            plci_remove(plci);
-            return;
-          }
-          else  sendf(plci->appl,_FACILITY_I,Id,0,"wS",3, &pty_cai[2]);
-          pty_cai[0]=0;
-        }
-        else
-        {
-          for(i=0; i<max_appl; i++)
-          {                     
-            if(a->Notification_Mask[i]&SMASK_MWI)
-            {
-              sendf(&application[i],_FACILITY_I,Id&0x7,0,"wS",3, &pty_cai[2]);
-              pty_cai[0]=0;
-            }
-          }
-        }
-
-        if(!pty_cai[0])
-        { /* acknowledge */
-          facility[2]= 0; /* returncode */
-        }
-        else facility[2]= 0xff;
-      }
-      else
-      {
-        /* reject */
-        facility[2]= 0xff; /* returncode */
-      }
-      facility[0]= 2;
-      facility[1]= MWI_RESPONSE; /* Function */
-      add_p(plci,CAI,facility);
-      add_p(plci,ESC,multi_ssext_parms[0]); /* remembered parameter -> only one possible */
-      sig_req(plci,S_SERVICE,0);
-      send_req(plci);
-      plci->command = 0;
-      next_internal_command (Id, plci);
-      break;
-    case CONF_ADD: /* OK */
-    case CONF_BEGIN:
-    case CONF_DROP:
-    case CONF_ISOLATE:
-    case CONF_REATTACH:
-    case CONF_PARTYDISC:
-      CONF_Ind[0]=9;
-      CONF_Ind[3]=6;
-      switch(pty_cai[5])
-      {
-      case CONF_BEGIN:
-          PUT_WORD(&CONF_Ind[1],S_CONF_BEGIN);
-          if(pty_cai[0]==6)
-          {
-              d=pty_cai[6];
-              PUT_DWORD(&CONF_Ind[6],d); /* PartyID */
-          }
-          else
-          {
-              PUT_DWORD(&CONF_Ind[6],0x0);
-          }
-          break;
-      case CONF_ISOLATE:
-          PUT_WORD(&CONF_Ind[1],S_CONF_ISOLATE);
-          CONF_Ind[0]=5;
-          CONF_Ind[3]=2;
-          break;
-      case CONF_REATTACH:
-          PUT_WORD(&CONF_Ind[1],S_CONF_REATTACH);
-          CONF_Ind[0]=5;
-          CONF_Ind[3]=2;
-          break;
-      case CONF_DROP:
-          PUT_WORD(&CONF_Ind[1],S_CONF_DROP);
-          CONF_Ind[0]=5;
-          CONF_Ind[3]=2;
-          break;
-      case CONF_ADD:
-          PUT_WORD(&CONF_Ind[1],S_CONF_ADD);
-          d=pty_cai[6];
-          PUT_DWORD(&CONF_Ind[6],d); /* PartyID */
-          tplci=plci->relatedPTYPLCI;
-          if(tplci) tplci->ptyState = CONNECTED;
-          break;
-      case CONF_PARTYDISC:
-          CONF_Ind[0]=7;
-          CONF_Ind[3]=4;          
-          PUT_WORD(&CONF_Ind[1],S_CONF_PARTYDISC);
-          d=pty_cai[6];
-          PUT_DWORD(&CONF_Ind[4],d); /* PartyID */
-          break;
-      }
-      plci->ptyState = CONNECTED;
-      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
-      break;
-    case CCBS_INFO_RETAIN:
-    case CCBS_ERASECALLLINKAGEID:
-    case CCBS_STOP_ALERTING:
-      CONF_Ind[0]=5;
-      CONF_Ind[3]=2;
-      switch(pty_cai[5])
-      {
-      case CCBS_INFO_RETAIN:
-        PUT_WORD(&CONF_Ind[1],S_CCBS_INFO_RETAIN);
-        break;
-      case CCBS_STOP_ALERTING:
-        PUT_WORD(&CONF_Ind[1],S_CCBS_STOP_ALERTING);
-    break;
-      case CCBS_ERASECALLLINKAGEID:
-        PUT_WORD(&CONF_Ind[1],S_CCBS_ERASECALLLINKAGEID);
-        CONF_Ind[0]=7;
-        CONF_Ind[3]=4;
-        CONF_Ind[6]=0;
-        CONF_Ind[7]=0;
-        break;
-      }      
-      w=pty_cai[6];
-      PUT_WORD(&CONF_Ind[4],w); /* PartyID */
-
-      if(plci->appl && (a->Notification_Mask[plci->appl->Id-1]&SMASK_CCBS))
-      {
-        sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, CONF_Ind);
-      }
-      else
-      {
-        for(i=0; i<max_appl; i++)
-            if(a->Notification_Mask[i]&SMASK_CCBS)
-                sendf(&application[i],_FACILITY_I,Id&0x7,0,"ws",3, CONF_Ind);
-      }
-      break;
-    }
-    break;
-  case CALL_HOLD_REJ:
-    cau = parms[7];
-    if(cau)
-    {
-      i = _L3_CAUSE | cau[2];
-      if(cau[2]==0) i = 0x3603;
-    }
-    else
-    {
-      i = 0x3603;
-    }
-    PUT_WORD(&SS_Ind[1],S_HOLD);
-    PUT_WORD(&SS_Ind[4],i);
-    if(plci->SuppState == HOLD_REQUEST)
-    {
-      plci->SuppState = IDLE;
-      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
-    }
-    break;
-
-  case CALL_HOLD_ACK:
-    if(plci->SuppState == HOLD_REQUEST)
-    {
-      plci->SuppState = CALL_HELD;
-      CodecIdCheck(a, plci);
-      start_internal_command (Id, plci, hold_save_command);
-    }
-    break;
-
-  case CALL_RETRIEVE_REJ:
-    cau = parms[7];
-    if(cau)
-    {
-      i = _L3_CAUSE | cau[2];
-      if(cau[2]==0) i = 0x3603;
-    }
-    else
-    {
-      i = 0x3603;
-    }
-    PUT_WORD(&SS_Ind[1],S_RETRIEVE);
-    PUT_WORD(&SS_Ind[4],i);
-    if(plci->SuppState == RETRIEVE_REQUEST)
-    {
-      plci->SuppState = CALL_HELD;
-      CodecIdCheck(a, plci);
-      sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
-    }
-    break;
-
-  case CALL_RETRIEVE_ACK:
-    PUT_WORD(&SS_Ind[1],S_RETRIEVE);
-    if(plci->SuppState == RETRIEVE_REQUEST)
-    {
-      plci->SuppState = IDLE;
-      plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
-      plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
-      if(plci->tel)
-      {
-        mixer_set_bchannel_id_esc (plci, plci->b_channel);
-        dbug(1,dprintf("RetrChannel=0x%x",plci->b_channel));
-        SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
-        if(plci->B2_prot==B2_TRANSPARENT && plci->B3_prot==B3_TRANSPARENT)
-        {
-          dbug(1,dprintf("Get B-ch"));
-          start_internal_command (Id, plci, retrieve_restore_command);
-        }
-        else
-          sendf(plci->appl,_FACILITY_I,Id,0,"ws",3, SS_Ind);
-      }
-      else
-        start_internal_command (Id, plci, retrieve_restore_command);
-    }
-    break;
-
-  case INDICATE_IND:
-    if(plci->State != LISTENING) {
-      sig_req(plci,HANGUP,0);
-      send_req(plci);
-      break;
-    }
-    cip = find_cip(a,parms[4],parms[6]);
-    cip_mask = 1L<<cip;
-    dbug(1,dprintf("cip=%d,cip_mask=%lx",cip,cip_mask));
-    clear_c_ind_mask (plci);
-    if (!remove_started && !a->adapter_disabled)
-    {
-      set_c_ind_mask_bit (plci, MAX_APPL);
-      group_optimization(a, plci);
-      for(i=0; i<max_appl; i++) {
-        if(application[i].Id
-        && (a->CIP_Mask[i]&1 || a->CIP_Mask[i]&cip_mask)
-        && CPN_filter_ok(parms[0],a,i)
-        && test_group_ind_mask_bit (plci, i) ) {
-          dbug(1,dprintf("storedcip_mask[%d]=0x%lx",i,a->CIP_Mask[i] ));
-          set_c_ind_mask_bit (plci, i);
-          dump_c_ind_mask (plci);
-          plci->State = INC_CON_PENDING;
-          plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) |
-            CALL_DIR_IN | CALL_DIR_ANSWER;
-          if(esc_chi[0]) {
-            plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
-            mixer_set_bchannel_id_esc (plci, plci->b_channel);
-          }
-          /* if a listen on the ext controller is done, check if hook states */
-          /* are supported or if just a on board codec must be activated     */
-          if(a->codec_listen[i] && !a->AdvSignalPLCI) {
-            if(a->profile.Global_Options & HANDSET)
-              plci->tel = ADV_VOICE;
-            else if(a->profile.Global_Options & ON_BOARD_CODEC)
-              plci->tel = CODEC;
-            if(plci->tel) Id|=EXT_CONTROLLER;
-            a->codec_listen[i] = plci;
-          }
-
-          sendf(&application[i],_CONNECT_I,Id,0,
-                "wSSSSSSSbSSSSS", cip,    /* CIP                 */
-                             parms[0],    /* CalledPartyNumber   */
-                             multi_CiPN_parms[0],    /* CallingPartyNumber  */
-                             parms[2],    /* CalledPartySubad    */
-                             parms[3],    /* CallingPartySubad   */
-                             parms[4],    /* BearerCapability    */
-                             parms[5],    /* LowLC               */
-                             parms[6],    /* HighLC              */
-                             ai_len,      /* nested struct add_i */
-                             add_i[0],    /* B channel info    */
-                             add_i[1],    /* keypad facility   */
-                             add_i[2],    /* user user data    */
-                             add_i[3],    /* nested facility   */
-                             multi_CiPN_parms[1]    /* second CiPN(SCR)   */
-                             );
-          SendSSExtInd(&application[i],
-                        plci,
-                        Id,
-                        multi_ssext_parms);
-          SendSetupInfo(&application[i],
-                        plci,
-                        Id,
-                        parms,
-                        SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, true));
-        }
-      }
-      clear_c_ind_mask_bit (plci, MAX_APPL);
-      dump_c_ind_mask (plci);
-    }
-    if(c_ind_mask_empty (plci)) {
-      sig_req(plci,HANGUP,0);
-      send_req(plci);
-      plci->State = IDLE;
-    }
-    plci->notifiedcall = 0;
-    a->listen_active--;
-    listen_check(a);
-    break;
-
-  case CALL_PEND_NOTIFY:
-    plci->notifiedcall = 1;
-    listen_check(a);
-    break;
-
-  case CALL_IND:
-  case CALL_CON:
-    if(plci->State==ADVANCED_VOICE_SIG || plci->State==ADVANCED_VOICE_NOSIG)
-    {
-      if(plci->internal_command==PERM_COD_CONN_PEND)
-      {
-        if(plci->State==ADVANCED_VOICE_NOSIG)
-        {
-          dbug(1,dprintf("***Codec OK"));
-          if(a->AdvSignalPLCI)
-          {
-            tplci = a->AdvSignalPLCI;
-            if(tplci->spoofed_msg)
-            {
-              dbug(1,dprintf("***Spoofed Msg(0x%x)",tplci->spoofed_msg));
-              tplci->command = 0;
-              tplci->internal_command = 0;
-              x_Id = ((word)tplci->Id<<8)|tplci->adapter->Id | 0x80;
-              switch (tplci->spoofed_msg)
-              {
-              case CALL_RES:
-                tplci->command = _CONNECT_I|RESPONSE;
-                api_load_msg (&tplci->saved_msg, saved_parms);
-                add_b1(tplci,&saved_parms[1],0,tplci->B1_facilities);
-                if (tplci->adapter->Info_Mask[tplci->appl->Id-1] & 0x200)
-                {
-                  /* early B3 connect (CIP mask bit 9) no release after a disc */
-                  add_p(tplci,LLI,"\x01\x01");
-                }
-                add_s(tplci, CONN_NR, &saved_parms[2]);
-                add_s(tplci, LLC, &saved_parms[4]);
-                add_ai(tplci, &saved_parms[5]);
-                tplci->State = INC_CON_ACCEPT;
-                sig_req(tplci, CALL_RES,0);
-                send_req(tplci);
-                break;
-
-              case AWAITING_SELECT_B:
-                dbug(1,dprintf("Select_B continue"));
-                start_internal_command (x_Id, tplci, select_b_command);
-                break;
-
-              case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */
-                if(!tplci->Sig.Id)
-                {
-                  dbug(1,dprintf("No SigID!"));
-                  sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,_OUT_OF_PLCI);
-                  plci_remove(tplci);
-                  break;
-                }
-                tplci->command = _MANUFACTURER_R;
-                api_load_msg (&tplci->saved_msg, saved_parms);
-                dir = saved_parms[2].info[0];
-                if(dir==1) {
-                  sig_req(tplci,CALL_REQ,0);
-                }
-                else if(!dir){
-                  sig_req(tplci,LISTEN_REQ,0);
-                }
-                send_req(tplci);
-                sendf(tplci->appl, _MANUFACTURER_R|CONFIRM,x_Id,tplci->number, "dww",_DI_MANU_ID,_MANUFACTURER_R,0);
-                break;
-
-              case (CALL_REQ|AWAITING_MANUF_CON):
-                sig_req(tplci,CALL_REQ,0);
-                send_req(tplci);
-                break;
-
-              case CALL_REQ:
-                if(!tplci->Sig.Id)
-                {
-                  dbug(1,dprintf("No SigID!"));
-                  sendf(tplci->appl,_CONNECT_R|CONFIRM,tplci->adapter->Id,0,"w",_OUT_OF_PLCI);
-                  plci_remove(tplci);
-                  break;
-                }
-                tplci->command = _CONNECT_R;
-                api_load_msg (&tplci->saved_msg, saved_parms);
-                add_s(tplci,CPN,&saved_parms[1]);
-                add_s(tplci,DSA,&saved_parms[3]);
-                add_ai(tplci,&saved_parms[9]);
-                sig_req(tplci,CALL_REQ,0);
-                send_req(tplci);
-                break;
-
-              case CALL_RETRIEVE:
-                tplci->command = C_RETRIEVE_REQ;
-                sig_req(tplci,CALL_RETRIEVE,0);
-                send_req(tplci);
-                break;
-              }
-              tplci->spoofed_msg = 0;
-              if (tplci->internal_command == 0)
-                next_internal_command (x_Id, tplci);
-            }
-          }
-          next_internal_command (Id, plci);
-          break;
-        }
-        dbug(1,dprintf("***Codec Hook Init Req"));
-        plci->internal_command = PERM_COD_HOOK;
-        add_p(plci,FTY,"\x01\x09");             /* Get Hook State*/
-        sig_req(plci,TEL_CTRL,0);
-        send_req(plci);
-      }
-    }
-    else if(plci->command != _MANUFACTURER_R  /* old style permanent connect */
-    && plci->State!=INC_ACT_PENDING)
-    {
-      mixer_set_bchannel_id_esc (plci, plci->b_channel);
-      if(plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */
-      {
-        chi[2] = plci->b_channel;
-        SetVoiceChannel(a->AdvCodecPLCI, chi, a);
-      }
-      sendf(plci->appl,_CONNECT_ACTIVE_I,Id,0,"Sss",parms[21],"","");
-      plci->State = INC_ACT_PENDING;
-    }
-    break;
-
-  case TEL_CTRL:
-    ie = multi_fac_parms[0]; /* inspect the facility hook indications */
-    if(plci->State==ADVANCED_VOICE_SIG && ie[0]){
-      switch (ie[1]&0x91) {
-        case 0x80:   /* hook off */
-        case 0x81:
-          if(plci->internal_command==PERM_COD_HOOK)
-          {
-            dbug(1,dprintf("init:hook_off"));
-            plci->hook_state = ie[1];
-            next_internal_command (Id, plci);
-            break;
-          }
-          else /* ignore doubled hook indications */
-          {
-            if( ((plci->hook_state)&0xf0)==0x80)
-            {
-              dbug(1,dprintf("ignore hook"));
-              break;
-            }
-            plci->hook_state = ie[1]&0x91;
-          }
-          /* check for incoming call pending */
-          /* and signal '+'.Appl must decide */
-          /* with connect_res if call must   */
-          /* accepted or not                 */
-          for(i=0, tplci=NULL;i<max_appl;i++){
-            if(a->codec_listen[i]
-            && (a->codec_listen[i]->State==INC_CON_PENDING
-              ||a->codec_listen[i]->State==INC_CON_ALERT) ){
-              tplci = a->codec_listen[i];
-              tplci->appl = &application[i];
-            }
-          }
-          /* no incoming call, do outgoing call */
-          /* and signal '+' if outg. setup   */
-          if(!a->AdvSignalPLCI && !tplci){
-            if((i=get_plci(a))) {
-              a->AdvSignalPLCI = &a->plci[i-1];
-              tplci = a->AdvSignalPLCI;
-              tplci->tel  = ADV_VOICE;
-              PUT_WORD(&voice_cai[5],a->AdvSignalAppl->MaxDataLength);
-              if (a->Info_Mask[a->AdvSignalAppl->Id-1] & 0x200){
-                /* early B3 connect (CIP mask bit 9) no release after a disc */
-                add_p(tplci,LLI,"\x01\x01");
-              }
-              add_p(tplci, CAI, voice_cai);
-              add_p(tplci, OAD, a->TelOAD);
-              add_p(tplci, OSA, a->TelOSA);
-              add_p(tplci,SHIFT|6,NULL);
-              add_p(tplci,SIN,"\x02\x01\x00");
-              add_p(tplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-              sig_req(tplci,ASSIGN,DSIG_ID);
-              a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ;
-              a->AdvSignalPLCI->command = 0;
-              tplci->appl = a->AdvSignalAppl;
-              tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
-              send_req(tplci);
-            }
-
-          }
-
-          if(!tplci) break;
-          Id = ((word)tplci->Id<<8)|a->Id;
-          Id|=EXT_CONTROLLER;
-          sendf(tplci->appl,
-                _FACILITY_I,
-                Id,
-                0,
-                "ws", (word)0, "\x01+");
-          break;
-
-        case 0x90:   /* hook on  */
-        case 0x91:
-          if(plci->internal_command==PERM_COD_HOOK)
-          {
-            dbug(1,dprintf("init:hook_on"));
-            plci->hook_state = ie[1]&0x91;
-            next_internal_command (Id, plci);
-            break;
-          }
-          else /* ignore doubled hook indications */
-          {
-            if( ((plci->hook_state)&0xf0)==0x90) break;
-            plci->hook_state = ie[1]&0x91;
-          }
-          /* hangup the adv. voice call and signal '-' to the appl */
-          if(a->AdvSignalPLCI) {
-            Id = ((word)a->AdvSignalPLCI->Id<<8)|a->Id;
-            if(plci->tel) Id|=EXT_CONTROLLER;
-            sendf(a->AdvSignalAppl,
-                  _FACILITY_I,
-                  Id,
-                  0,
-                  "ws", (word)0, "\x01-");
-            a->AdvSignalPLCI->internal_command = HOOK_ON_REQ;
-            a->AdvSignalPLCI->command = 0;
-            sig_req(a->AdvSignalPLCI,HANGUP,0);
-            send_req(a->AdvSignalPLCI);
-          }
-          break;
-      }
-    }
-    break;
-
-  case RESUME:
-    clear_c_ind_mask_bit (plci, (word)(plci->appl->Id-1));
-    PUT_WORD(&resume_cau[4],GOOD);
-    sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau);
-    break;
-
-  case SUSPEND:
-    clear_c_ind_mask (plci);
-
-    if (plci->NL.Id && !plci->nl_remove_id) {
-      mixer_remove (plci);
-      nl_req_ncci(plci,REMOVE,0);
-    }
-    if (!plci->sig_remove_id) {
-      plci->internal_command = 0;
-      sig_req(plci,REMOVE,0);
-    }
-    send_req(plci);
-    if(!plci->channels) {
-      sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, "\x05\x04\x00\x02\x00\x00");
-      sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
-    }
-    break;
-
-  case SUSPEND_REJ:
-    break;
-
-  case HANGUP:
-    plci->hangup_flow_ctrl_timer=0;
-    if(plci->manufacturer && plci->State==LOCAL_CONNECT) break;
-    cau = parms[7];
-    if(cau) {
-      i = _L3_CAUSE | cau[2];
-      if(cau[2]==0) i = 0;
-      else if(cau[2]==8) i = _L1_ERROR;
-      else if(cau[2]==9 || cau[2]==10) i = _L2_ERROR;
-      else if(cau[2]==5) i = _CAPI_GUARD_ERROR;
-    }
-    else {
-      i = _L3_ERROR;
-    }
-
-    if(plci->State==INC_CON_PENDING || plci->State==INC_CON_ALERT)
-    {
-      for(i=0; i<max_appl; i++)
-      {
-        if(test_c_ind_mask_bit (plci, i))
-          sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
-      }
-    }
-    else
-    {
-      clear_c_ind_mask (plci);
-    }
-    if(!plci->appl)
-    {
-      if (plci->State == LISTENING)
-      {
-        plci->notifiedcall=0;
-        a->listen_active--;
-      }
-      plci->State = INC_DIS_PENDING;
-      if(c_ind_mask_empty (plci))
-      {
-        plci->State = IDLE;
-        if (plci->NL.Id && !plci->nl_remove_id)
-        {
-          mixer_remove (plci);
-          nl_req_ncci(plci,REMOVE,0);
-        }
-        if (!plci->sig_remove_id)
-        {
-          plci->internal_command = 0;
-          sig_req(plci,REMOVE,0);
-        }
-        send_req(plci);
-      }
-    }
-    else
-    {
-        /* collision of DISCONNECT or CONNECT_RES with HANGUP can   */
-        /* result in a second HANGUP! Don't generate another        */
-        /* DISCONNECT                                               */
-      if(plci->State!=IDLE && plci->State!=INC_DIS_PENDING)
-      {
-        if(plci->State==RESUMING)
-        {
-          PUT_WORD(&resume_cau[4],i);
-          sendf(plci->appl,_FACILITY_I,Id,0,"ws", (word)3, resume_cau);
-        }
-        plci->State = INC_DIS_PENDING;
-        sendf(plci->appl,_DISCONNECT_I,Id,0,"w",i);
-      }
-    }
-    break;
-
-  case SSEXT_IND:
-    SendSSExtInd(NULL,plci,Id,multi_ssext_parms);
-    break;
-
-  case VSWITCH_REQ:
-    VSwitchReqInd(plci,Id,multi_vswitch_parms);
-    break;
-  case VSWITCH_IND:
- if(plci->relatedPTYPLCI &&
-  plci->vswitchstate==3 &&
-  plci->relatedPTYPLCI->vswitchstate==3 &&
-  parms[MAXPARMSIDS-1][0])
- {
-  add_p(plci->relatedPTYPLCI,SMSG,parms[MAXPARMSIDS-1]);
-  sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0);
-  send_req(plci->relatedPTYPLCI);
- }
-    else VSwitchReqInd(plci,Id,multi_vswitch_parms);
-    break;
-
-  }
-}
-
-
-static void SendSetupInfo(APPL   * appl, PLCI   * plci, dword Id, byte   * * parms, byte Info_Sent_Flag)
-{
-  word i;
-  byte   * ie;
-  word Info_Number;
-  byte   * Info_Element;
-  word Info_Mask = 0;
-
-  dbug(1,dprintf("SetupInfo"));
-
-  for(i=0; i<MAXPARMSIDS; i++) {
-    ie = parms[i];
-    Info_Number = 0;
-    Info_Element = ie;
-    if(ie[0]) {
-      switch(i) {
-      case 0:
-        dbug(1,dprintf("CPN "));
-        Info_Number = 0x0070;
-        Info_Mask   = 0x80;
-        Info_Sent_Flag = true;
-        break;
-      case 8:  /* display      */
-        dbug(1,dprintf("display(%d)",i));
-        Info_Number = 0x0028;
-        Info_Mask = 0x04;
-        Info_Sent_Flag = true;
-        break;
-      case 16: /* Channel Id */
-        dbug(1,dprintf("CHI"));
-        Info_Number = 0x0018;
-        Info_Mask = 0x100;
-        Info_Sent_Flag = true;
-        mixer_set_bchannel_id (plci, Info_Element);
-        break;
-      case 19: /* Redirected Number */
-        dbug(1,dprintf("RDN"));
-        Info_Number = 0x0074;
-        Info_Mask = 0x400;
-        Info_Sent_Flag = true;
-        break;
-      case 20: /* Redirected Number extended */
-        dbug(1,dprintf("RDX"));
-        Info_Number = 0x0073;
-        Info_Mask = 0x400;
-        Info_Sent_Flag = true;
-        break;
-      case 22: /* Redirecing Number  */
-        dbug(1,dprintf("RIN"));
-        Info_Number = 0x0076;
-        Info_Mask = 0x400;
-        Info_Sent_Flag = true;
-        break;
-      default:
-        Info_Number = 0;
-        break;
-      }
-    }
-
-    if(i==MAXPARMSIDS-2){ /* to indicate the message type "Setup" */
-      Info_Number = 0x8000 |5;
-      Info_Mask = 0x10;
-      Info_Element = "";
-    }
-
-    if(Info_Sent_Flag && Info_Number){
-      if(plci->adapter->Info_Mask[appl->Id-1] & Info_Mask) {
-        sendf(appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
-      }
-    }
-  }
+	byte *parms[MAXPARMSIDS];
+	byte *add_i[4];
+	byte *multi_fac_parms[MAX_MULTI_IE];
+	byte *multi_pi_parms[MAX_MULTI_IE];
+	byte *multi_ssext_parms[MAX_MULTI_IE];
+	byte *multi_CiPN_parms[MAX_MULTI_IE];
+
+	byte *multi_vswitch_parms[MAX_MULTI_IE];
+
+	byte ai_len;
+	byte *esc_chi = "";
+	byte *esc_law = "";
+	byte *pty_cai = "";
+	byte *esc_cr  = "";
+	byte *esc_profile = "";
+
+	byte facility[256];
+	PLCI *tplci = NULL;
+	byte chi[] = "\x02\x18\x01";
+	byte voice_cai[]  = "\x06\x14\x00\x00\x00\x00\x08";
+	byte resume_cau[] = "\x05\x05\x00\x02\x00\x00";
+	/* ESC_MSGTYPE must be the last but one message, a new IE has to be */
+	/* included before the ESC_MSGTYPE and MAXPARMSIDS has to be incremented */
+	/* SMSG is situated at the end because its 0 (for compatibility reasons */
+	/* (see Info_Mask Bit 4, first IE. then the message type)           */
+	word parms_id[] =
+		{MAXPARMSIDS, CPN, 0xff, DSA, OSA, BC, LLC, HLC, ESC_CAUSE, DSP, DT, CHA,
+		 UUI, CONG_RR, CONG_RNR, ESC_CHI, KEY, CHI, CAU, ESC_LAW,
+		 RDN, RDX, CONN_NR, RIN, NI, CAI, ESC_CR,
+		 CST, ESC_PROFILE, 0xff, ESC_MSGTYPE, SMSG};
+	/* 14 FTY repl by ESC_CHI */
+	/* 18 PI  repl by ESC_LAW */
+	/* removed OAD changed to 0xff for future use, OAD is multiIE now */
+	word multi_fac_id[] = {1, FTY};
+	word multi_pi_id[]  = {1, PI};
+	word multi_CiPN_id[]  = {1, OAD};
+	word multi_ssext_id[]  = {1, ESC_SSEXT};
+
+	word multi_vswitch_id[]  = {1, ESC_VSWITCH};
+
+	byte *cau;
+	word ncci;
+	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
+	byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
+	byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+	byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
+	byte force_mt_info = false;
+	byte dir;
+	dword d;
+	word w;
+
+	a = plci->adapter;
+	Id = ((word)plci->Id << 8) | a->Id;
+	PUT_WORD(&SS_Ind[4], 0x0000);
+
+	if (plci->sig_remove_id)
+	{
+		plci->Sig.RNR = 2; /* discard */
+		dbug(1, dprintf("SIG discard while remove pending"));
+		return;
+	}
+	if (plci->tel && plci->SuppState != CALL_HELD) Id |= EXT_CONTROLLER;
+	dbug(1, dprintf("SigInd-Id=%08lx,plci=%x,tel=%x,state=0x%x,channels=%d,Discflowcl=%d",
+			Id, plci->Id, plci->tel, plci->State, plci->channels, plci->hangup_flow_ctrl_timer));
+	if (plci->Sig.Ind == CALL_HOLD_ACK && plci->channels)
+	{
+		plci->Sig.RNR = 1;
+		return;
+	}
+	if (plci->Sig.Ind == HANGUP && plci->channels)
+	{
+		plci->Sig.RNR = 1;
+		plci->hangup_flow_ctrl_timer++;
+		/* recover the network layer after timeout */
+		if (plci->hangup_flow_ctrl_timer == 100)
+		{
+			dbug(1, dprintf("Exceptional disc"));
+			plci->Sig.RNR = 0;
+			plci->hangup_flow_ctrl_timer = 0;
+			for (ncci = 1; ncci < MAX_NCCI + 1; ncci++)
+			{
+				if (a->ncci_plci[ncci] == plci->Id)
+				{
+					cleanup_ncci_data(plci, ncci);
+					if (plci->channels)plci->channels--;
+					if (plci->appl)
+						sendf(plci->appl, _DISCONNECT_B3_I, (((dword) ncci) << 16) | Id, 0, "ws", 0, "");
+				}
+			}
+			if (plci->appl)
+				sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
+			plci_remove(plci);
+			plci->State = IDLE;
+		}
+		return;
+	}
+
+	/* do first parse the info with no OAD in, because OAD will be converted */
+	/* first the multiple facility IE, then mult. progress ind.              */
+	/* then the parameters for the info_ind + conn_ind                       */
+	IndParse(plci, multi_fac_id, multi_fac_parms, MAX_MULTI_IE);
+	IndParse(plci, multi_pi_id, multi_pi_parms, MAX_MULTI_IE);
+	IndParse(plci, multi_ssext_id, multi_ssext_parms, MAX_MULTI_IE);
+
+	IndParse(plci, multi_vswitch_id, multi_vswitch_parms, MAX_MULTI_IE);
+
+	IndParse(plci, parms_id, parms, 0);
+	IndParse(plci, multi_CiPN_id, multi_CiPN_parms, MAX_MULTI_IE);
+	esc_chi  = parms[14];
+	esc_law  = parms[18];
+	pty_cai  = parms[24];
+	esc_cr   = parms[25];
+	esc_profile = parms[27];
+	if (esc_cr[0] && plci)
+	{
+		if (plci->cr_enquiry && plci->appl)
+		{
+			plci->cr_enquiry = false;
+			/* d = MANU_ID            */
+			/* w = m_command          */
+			/* b = total length       */
+			/* b = indication type    */
+			/* b = length of all IEs  */
+			/* b = IE1                */
+			/* S = IE1 length + cont. */
+			/* b = IE2                */
+			/* S = IE2 length + cont. */
+			sendf(plci->appl,
+			      _MANUFACTURER_I,
+			      Id,
+			      0,
+			      "dwbbbbSbS", _DI_MANU_ID, plci->m_command,
+			      2 + 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], plci->Sig.Ind, 1 + 1 + esc_cr[0] + 1 + 1 + esc_law[0], ESC, esc_cr, ESC, esc_law);
+		}
+	}
+	/* create the additional info structure                                  */
+	add_i[1] = parms[15]; /* KEY of additional info */
+	add_i[2] = parms[11]; /* UUI of additional info */
+	ai_len = AddInfo(add_i, multi_fac_parms, esc_chi, facility);
+
+	/* the ESC_LAW indicates if u-Law or a-Law is actually used by the card  */
+	/* indication returns by the card if requested by the function           */
+	/* AutomaticLaw() after driver init                                      */
+	if (a->automatic_law < 4)
+	{
+		if (esc_law[0]) {
+			if (esc_law[2]) {
+				dbug(0, dprintf("u-Law selected"));
+				a->u_law = 1;
+			}
+			else {
+				dbug(0, dprintf("a-Law selected"));
+				a->u_law = 0;
+			}
+			a->automatic_law = 4;
+			if (plci == a->automatic_lawPLCI) {
+				plci->internal_command = 0;
+				sig_req(plci, REMOVE, 0);
+				send_req(plci);
+				a->automatic_lawPLCI = NULL;
+			}
+		}
+		if (esc_profile[0])
+		{
+			dbug(1, dprintf("[%06x] CardProfile: %lx %lx %lx %lx %lx",
+					UnMapController(a->Id), GET_DWORD(&esc_profile[6]),
+					GET_DWORD(&esc_profile[10]), GET_DWORD(&esc_profile[14]),
+					GET_DWORD(&esc_profile[18]), GET_DWORD(&esc_profile[46])));
+
+			a->profile.Global_Options &= 0x000000ffL;
+			a->profile.B1_Protocols &= 0x000003ffL;
+			a->profile.B2_Protocols &= 0x00001fdfL;
+			a->profile.B3_Protocols &= 0x000000b7L;
+
+			a->profile.Global_Options &= GET_DWORD(&esc_profile[6]) |
+				GL_BCHANNEL_OPERATION_SUPPORTED;
+			a->profile.B1_Protocols &= GET_DWORD(&esc_profile[10]);
+			a->profile.B2_Protocols &= GET_DWORD(&esc_profile[14]);
+			a->profile.B3_Protocols &= GET_DWORD(&esc_profile[18]);
+			a->manufacturer_features = GET_DWORD(&esc_profile[46]);
+			a->man_profile.private_options = 0;
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_ECHO_CANCELLER)
+			{
+				a->man_profile.private_options |= 1L << PRIVATE_ECHO_CANCELLER;
+				a->profile.Global_Options |= GL_ECHO_CANCELLER_SUPPORTED;
+			}
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_RTP)
+				a->man_profile.private_options |= 1L << PRIVATE_RTP;
+			a->man_profile.rtp_primary_payloads = GET_DWORD(&esc_profile[50]);
+			a->man_profile.rtp_additional_payloads = GET_DWORD(&esc_profile[54]);
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_T38)
+				a->man_profile.private_options |= 1L << PRIVATE_T38;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_SUB_SEP_PWD)
+				a->man_profile.private_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_V18)
+				a->man_profile.private_options |= 1L << PRIVATE_V18;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_DTMF_TONE)
+				a->man_profile.private_options |= 1L << PRIVATE_DTMF_TONE;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_PIAFS)
+				a->man_profile.private_options |= 1L << PRIVATE_PIAFS;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
+				a->man_profile.private_options |= 1L << PRIVATE_FAX_PAPER_FORMATS;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_VOWN)
+				a->man_profile.private_options |= 1L << PRIVATE_VOWN;
+
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_NONSTANDARD)
+				a->man_profile.private_options |= 1L << PRIVATE_FAX_NONSTANDARD;
+
+		}
+		else
+		{
+			a->profile.Global_Options &= 0x0000007fL;
+			a->profile.B1_Protocols &= 0x000003dfL;
+			a->profile.B2_Protocols &= 0x00001adfL;
+			a->profile.B3_Protocols &= 0x000000b7L;
+			a->manufacturer_features &= MANUFACTURER_FEATURE_HARDDTMF;
+		}
+		if (a->manufacturer_features & (MANUFACTURER_FEATURE_HARDDTMF |
+						MANUFACTURER_FEATURE_SOFTDTMF_SEND | MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
+		{
+			a->profile.Global_Options |= GL_DTMF_SUPPORTED;
+		}
+		a->manufacturer_features &= ~MANUFACTURER_FEATURE_OOB_CHANNEL;
+		dbug(1, dprintf("[%06x] Profile: %lx %lx %lx %lx %lx",
+				UnMapController(a->Id), a->profile.Global_Options,
+				a->profile.B1_Protocols, a->profile.B2_Protocols,
+				a->profile.B3_Protocols, a->manufacturer_features));
+	}
+	/* codec plci for the handset/hook state support is just an internal id  */
+	if (plci != a->AdvCodecPLCI)
+	{
+		force_mt_info = SendMultiIE(plci, Id, multi_fac_parms, FTY, 0x20, 0);
+		force_mt_info |= SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, 0);
+		SendSSExtInd(NULL, plci, Id, multi_ssext_parms);
+		SendInfo(plci, Id, parms, force_mt_info);
+
+		VSwitchReqInd(plci, Id, multi_vswitch_parms);
+
+	}
+
+	/* switch the codec to the b-channel                                     */
+	if (esc_chi[0] && plci && !plci->SuppState) {
+		plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
+		mixer_set_bchannel_id_esc(plci, plci->b_channel);
+		dbug(1, dprintf("storeChannel=0x%x", plci->b_channel));
+		if (plci->tel == ADV_VOICE && plci->appl) {
+			SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
+		}
+	}
+
+	if (plci->appl) plci->appl->Number++;
+
+	switch (plci->Sig.Ind) {
+		/* Response to Get_Supported_Services request */
+	case S_SUPPORTED:
+		dbug(1, dprintf("S_Supported"));
+		if (!plci->appl) break;
+		if (pty_cai[0] == 4)
+		{
+			PUT_DWORD(&CF_Ind[6], GET_DWORD(&pty_cai[1]));
+		}
+		else
+		{
+			PUT_DWORD(&CF_Ind[6], MASK_TERMINAL_PORTABILITY | MASK_HOLD_RETRIEVE);
+		}
+		PUT_WORD(&CF_Ind[1], 0);
+		PUT_WORD(&CF_Ind[4], 0);
+		sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0x7, plci->number, "wws", 0, 3, CF_Ind);
+		plci_remove(plci);
+		break;
+
+		/* Supplementary Service rejected */
+	case S_SERVICE_REJ:
+		dbug(1, dprintf("S_Reject=0x%x", pty_cai[5]));
+		if (!pty_cai[0]) break;
+		switch (pty_cai[5])
+		{
+		case ECT_EXECUTE:
+		case THREE_PTY_END:
+		case THREE_PTY_BEGIN:
+			if (!plci->relatedPTYPLCI) break;
+			tplci = plci->relatedPTYPLCI;
+			rId = ((word)tplci->Id << 8) | tplci->adapter->Id;
+			if (tplci->tel) rId |= EXT_CONTROLLER;
+			if (pty_cai[5] == ECT_EXECUTE)
+			{
+				PUT_WORD(&SS_Ind[1], S_ECT);
+
+				plci->vswitchstate = 0;
+				plci->relatedPTYPLCI->vswitchstate = 0;
+
+			}
+			else
+			{
+				PUT_WORD(&SS_Ind[1], pty_cai[5] + 3);
+			}
+			if (pty_cai[2] != 0xff)
+			{
+				PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
+			}
+			else
+			{
+				PUT_WORD(&SS_Ind[4], 0x300E);
+			}
+			plci->relatedPTYPLCI = NULL;
+			plci->ptyState = 0;
+			sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
+			break;
+
+		case CALL_DEFLECTION:
+			if (pty_cai[2] != 0xff)
+			{
+				PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
+			}
+			else
+			{
+				PUT_WORD(&SS_Ind[4], 0x300E);
+			}
+			PUT_WORD(&SS_Ind[1], pty_cai[5]);
+			for (i = 0; i < max_appl; i++)
+			{
+				if (application[i].CDEnable)
+				{
+					if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+					application[i].CDEnable = false;
+				}
+			}
+			break;
+
+		case DEACTIVATION_DIVERSION:
+		case ACTIVATION_DIVERSION:
+		case DIVERSION_INTERROGATE_CFU:
+		case DIVERSION_INTERROGATE_CFB:
+		case DIVERSION_INTERROGATE_CFNR:
+		case DIVERSION_INTERROGATE_NUM:
+		case CCBS_REQUEST:
+		case CCBS_DEACTIVATE:
+		case CCBS_INTERROGATE:
+			if (!plci->appl) break;
+			if (pty_cai[2] != 0xff)
+			{
+				PUT_WORD(&Interr_Err_Ind[4], 0x3600 | (word)pty_cai[2]);
+			}
+			else
+			{
+				PUT_WORD(&Interr_Err_Ind[4], 0x300E);
+			}
+			switch (pty_cai[5])
+			{
+			case DEACTIVATION_DIVERSION:
+				dbug(1, dprintf("Deact_Div"));
+				Interr_Err_Ind[0] = 0x9;
+				Interr_Err_Ind[3] = 0x6;
+				PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_STOP);
+				break;
+			case ACTIVATION_DIVERSION:
+				dbug(1, dprintf("Act_Div"));
+				Interr_Err_Ind[0] = 0x9;
+				Interr_Err_Ind[3] = 0x6;
+				PUT_WORD(&Interr_Err_Ind[1], S_CALL_FORWARDING_START);
+				break;
+			case DIVERSION_INTERROGATE_CFU:
+			case DIVERSION_INTERROGATE_CFB:
+			case DIVERSION_INTERROGATE_CFNR:
+				dbug(1, dprintf("Interr_Div"));
+				Interr_Err_Ind[0] = 0xa;
+				Interr_Err_Ind[3] = 0x7;
+				PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_DIVERSION);
+				break;
+			case DIVERSION_INTERROGATE_NUM:
+				dbug(1, dprintf("Interr_Num"));
+				Interr_Err_Ind[0] = 0xa;
+				Interr_Err_Ind[3] = 0x7;
+				PUT_WORD(&Interr_Err_Ind[1], S_INTERROGATE_NUMBERS);
+				break;
+			case CCBS_REQUEST:
+				dbug(1, dprintf("CCBS Request"));
+				Interr_Err_Ind[0] = 0xd;
+				Interr_Err_Ind[3] = 0xa;
+				PUT_WORD(&Interr_Err_Ind[1], S_CCBS_REQUEST);
+				break;
+			case CCBS_DEACTIVATE:
+				dbug(1, dprintf("CCBS Deactivate"));
+				Interr_Err_Ind[0] = 0x9;
+				Interr_Err_Ind[3] = 0x6;
+				PUT_WORD(&Interr_Err_Ind[1], S_CCBS_DEACTIVATE);
+				break;
+			case CCBS_INTERROGATE:
+				dbug(1, dprintf("CCBS Interrogate"));
+				Interr_Err_Ind[0] = 0xb;
+				Interr_Err_Ind[3] = 0x8;
+				PUT_WORD(&Interr_Err_Ind[1], S_CCBS_INTERROGATE);
+				break;
+			}
+			PUT_DWORD(&Interr_Err_Ind[6], plci->appl->S_Handle);
+			sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, Interr_Err_Ind);
+			plci_remove(plci);
+			break;
+		case ACTIVATION_MWI:
+		case DEACTIVATION_MWI:
+			if (pty_cai[5] == ACTIVATION_MWI)
+			{
+				PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE);
+			}
+			else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE);
+
+			if (pty_cai[2] != 0xff)
+			{
+				PUT_WORD(&SS_Ind[4], 0x3600 | (word)pty_cai[2]);
+			}
+			else
+			{
+				PUT_WORD(&SS_Ind[4], 0x300E);
+			}
+
+			if (plci->cr_enquiry)
+			{
+				sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind);
+				plci_remove(plci);
+			}
+			else
+			{
+				sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+			}
+			break;
+		case CONF_ADD: /* ERROR */
+		case CONF_BEGIN:
+		case CONF_DROP:
+		case CONF_ISOLATE:
+		case CONF_REATTACH:
+			CONF_Ind[0] = 9;
+			CONF_Ind[3] = 6;
+			switch (pty_cai[5])
+			{
+			case CONF_BEGIN:
+				PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN);
+				plci->ptyState = 0;
+				break;
+			case CONF_DROP:
+				CONF_Ind[0] = 5;
+				CONF_Ind[3] = 2;
+				PUT_WORD(&CONF_Ind[1], S_CONF_DROP);
+				plci->ptyState = CONNECTED;
+				break;
+			case CONF_ISOLATE:
+				CONF_Ind[0] = 5;
+				CONF_Ind[3] = 2;
+				PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE);
+				plci->ptyState = CONNECTED;
+				break;
+			case CONF_REATTACH:
+				CONF_Ind[0] = 5;
+				CONF_Ind[3] = 2;
+				PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH);
+				plci->ptyState = CONNECTED;
+				break;
+			case CONF_ADD:
+				PUT_WORD(&CONF_Ind[1], S_CONF_ADD);
+				plci->relatedPTYPLCI = NULL;
+				tplci = plci->relatedPTYPLCI;
+				if (tplci) tplci->ptyState = CONNECTED;
+				plci->ptyState = CONNECTED;
+				break;
+			}
+
+			if (pty_cai[2] != 0xff)
+			{
+				PUT_WORD(&CONF_Ind[4], 0x3600 | (word)pty_cai[2]);
+			}
+			else
+			{
+				PUT_WORD(&CONF_Ind[4], 0x3303); /* Time-out: network did not respond
+								  within the required time */
+			}
+
+			PUT_DWORD(&CONF_Ind[6], 0x0);
+			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
+			break;
+		}
+		break;
+
+		/* Supplementary Service indicates success */
+	case S_SERVICE:
+		dbug(1, dprintf("Service_Ind"));
+		PUT_WORD(&CF_Ind[4], 0);
+		switch (pty_cai[5])
+		{
+		case THREE_PTY_END:
+		case THREE_PTY_BEGIN:
+		case ECT_EXECUTE:
+			if (!plci->relatedPTYPLCI) break;
+			tplci = plci->relatedPTYPLCI;
+			rId = ((word)tplci->Id << 8) | tplci->adapter->Id;
+			if (tplci->tel) rId |= EXT_CONTROLLER;
+			if (pty_cai[5] == ECT_EXECUTE)
+			{
+				PUT_WORD(&SS_Ind[1], S_ECT);
+
+				if (plci->vswitchstate != 3)
+				{
+
+					plci->ptyState = IDLE;
+					plci->relatedPTYPLCI = NULL;
+					plci->ptyState = 0;
+
+				}
+
+				dbug(1, dprintf("ECT OK"));
+				sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
+
+
+
+			}
+			else
+			{
+				switch (plci->ptyState)
+				{
+				case S_3PTY_BEGIN:
+					plci->ptyState = CONNECTED;
+					dbug(1, dprintf("3PTY ON"));
+					break;
+
+				case S_3PTY_END:
+					plci->ptyState = IDLE;
+					plci->relatedPTYPLCI = NULL;
+					plci->ptyState = 0;
+					dbug(1, dprintf("3PTY OFF"));
+					break;
+				}
+				PUT_WORD(&SS_Ind[1], pty_cai[5] + 3);
+				sendf(tplci->appl, _FACILITY_I, rId, 0, "ws", 3, SS_Ind);
+			}
+			break;
+
+		case CALL_DEFLECTION:
+			PUT_WORD(&SS_Ind[1], pty_cai[5]);
+			for (i = 0; i < max_appl; i++)
+			{
+				if (application[i].CDEnable)
+				{
+					if (application[i].Id) sendf(&application[i], _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+					application[i].CDEnable = false;
+				}
+			}
+			break;
+
+		case DEACTIVATION_DIVERSION:
+		case ACTIVATION_DIVERSION:
+			if (!plci->appl) break;
+			PUT_WORD(&CF_Ind[1], pty_cai[5] + 2);
+			PUT_DWORD(&CF_Ind[6], plci->appl->S_Handle);
+			sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "ws", 3, CF_Ind);
+			plci_remove(plci);
+			break;
+
+		case DIVERSION_INTERROGATE_CFU:
+		case DIVERSION_INTERROGATE_CFB:
+		case DIVERSION_INTERROGATE_CFNR:
+		case DIVERSION_INTERROGATE_NUM:
+		case CCBS_REQUEST:
+		case CCBS_DEACTIVATE:
+		case CCBS_INTERROGATE:
+			if (!plci->appl) break;
+			switch (pty_cai[5])
+			{
+			case DIVERSION_INTERROGATE_CFU:
+			case DIVERSION_INTERROGATE_CFB:
+			case DIVERSION_INTERROGATE_CFNR:
+				dbug(1, dprintf("Interr_Div"));
+				PUT_WORD(&pty_cai[1], S_INTERROGATE_DIVERSION);
+				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
+				break;
+			case DIVERSION_INTERROGATE_NUM:
+				dbug(1, dprintf("Interr_Num"));
+				PUT_WORD(&pty_cai[1], S_INTERROGATE_NUMBERS);
+				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
+				break;
+			case CCBS_REQUEST:
+				dbug(1, dprintf("CCBS Request"));
+				PUT_WORD(&pty_cai[1], S_CCBS_REQUEST);
+				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
+				break;
+			case CCBS_DEACTIVATE:
+				dbug(1, dprintf("CCBS Deactivate"));
+				PUT_WORD(&pty_cai[1], S_CCBS_DEACTIVATE);
+				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
+				break;
+			case CCBS_INTERROGATE:
+				dbug(1, dprintf("CCBS Interrogate"));
+				PUT_WORD(&pty_cai[1], S_CCBS_INTERROGATE);
+				pty_cai[3] = pty_cai[0] - 3; /* Supplementary Service-specific parameter len */
+				break;
+			}
+			PUT_WORD(&pty_cai[4], 0); /* Supplementary Service Reason */
+			PUT_DWORD(&pty_cai[6], plci->appl->S_Handle);
+			sendf(plci->appl, _FACILITY_I, Id & 0x7, 0, "wS", 3, pty_cai);
+			plci_remove(plci);
+			break;
+
+		case ACTIVATION_MWI:
+		case DEACTIVATION_MWI:
+			if (pty_cai[5] == ACTIVATION_MWI)
+			{
+				PUT_WORD(&SS_Ind[1], S_MWI_ACTIVATE);
+			}
+			else PUT_WORD(&SS_Ind[1], S_MWI_DEACTIVATE);
+			if (plci->cr_enquiry)
+			{
+				sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "ws", 3, SS_Ind);
+				plci_remove(plci);
+			}
+			else
+			{
+				sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+			}
+			break;
+		case MWI_INDICATION:
+			if (pty_cai[0] >= 0x12)
+			{
+				PUT_WORD(&pty_cai[3], S_MWI_INDICATE);
+				pty_cai[2] = pty_cai[0] - 2; /* len Parameter */
+				pty_cai[5] = pty_cai[0] - 5; /* Supplementary Service-specific parameter len */
+				if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_MWI))
+				{
+					if (plci->internal_command == GET_MWI_STATE) /* result on Message Waiting Listen */
+					{
+						sendf(plci->appl, _FACILITY_I, Id & 0xf, 0, "wS", 3, &pty_cai[2]);
+						plci_remove(plci);
+						return;
+					}
+					else sendf(plci->appl, _FACILITY_I, Id, 0, "wS", 3, &pty_cai[2]);
+					pty_cai[0] = 0;
+				}
+				else
+				{
+					for (i = 0; i < max_appl; i++)
+					{
+						if (a->Notification_Mask[i]&SMASK_MWI)
+						{
+							sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "wS", 3, &pty_cai[2]);
+							pty_cai[0] = 0;
+						}
+					}
+				}
+
+				if (!pty_cai[0])
+				{ /* acknowledge */
+					facility[2] = 0; /* returncode */
+				}
+				else facility[2] = 0xff;
+			}
+			else
+			{
+				/* reject */
+				facility[2] = 0xff; /* returncode */
+			}
+			facility[0] = 2;
+			facility[1] = MWI_RESPONSE; /* Function */
+			add_p(plci, CAI, facility);
+			add_p(plci, ESC, multi_ssext_parms[0]); /* remembered parameter -> only one possible */
+			sig_req(plci, S_SERVICE, 0);
+			send_req(plci);
+			plci->command = 0;
+			next_internal_command(Id, plci);
+			break;
+		case CONF_ADD: /* OK */
+		case CONF_BEGIN:
+		case CONF_DROP:
+		case CONF_ISOLATE:
+		case CONF_REATTACH:
+		case CONF_PARTYDISC:
+			CONF_Ind[0] = 9;
+			CONF_Ind[3] = 6;
+			switch (pty_cai[5])
+			{
+			case CONF_BEGIN:
+				PUT_WORD(&CONF_Ind[1], S_CONF_BEGIN);
+				if (pty_cai[0] == 6)
+				{
+					d = pty_cai[6];
+					PUT_DWORD(&CONF_Ind[6], d); /* PartyID */
+				}
+				else
+				{
+					PUT_DWORD(&CONF_Ind[6], 0x0);
+				}
+				break;
+			case CONF_ISOLATE:
+				PUT_WORD(&CONF_Ind[1], S_CONF_ISOLATE);
+				CONF_Ind[0] = 5;
+				CONF_Ind[3] = 2;
+				break;
+			case CONF_REATTACH:
+				PUT_WORD(&CONF_Ind[1], S_CONF_REATTACH);
+				CONF_Ind[0] = 5;
+				CONF_Ind[3] = 2;
+				break;
+			case CONF_DROP:
+				PUT_WORD(&CONF_Ind[1], S_CONF_DROP);
+				CONF_Ind[0] = 5;
+				CONF_Ind[3] = 2;
+				break;
+			case CONF_ADD:
+				PUT_WORD(&CONF_Ind[1], S_CONF_ADD);
+				d = pty_cai[6];
+				PUT_DWORD(&CONF_Ind[6], d); /* PartyID */
+				tplci = plci->relatedPTYPLCI;
+				if (tplci) tplci->ptyState = CONNECTED;
+				break;
+			case CONF_PARTYDISC:
+				CONF_Ind[0] = 7;
+				CONF_Ind[3] = 4;
+				PUT_WORD(&CONF_Ind[1], S_CONF_PARTYDISC);
+				d = pty_cai[6];
+				PUT_DWORD(&CONF_Ind[4], d); /* PartyID */
+				break;
+			}
+			plci->ptyState = CONNECTED;
+			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
+			break;
+		case CCBS_INFO_RETAIN:
+		case CCBS_ERASECALLLINKAGEID:
+		case CCBS_STOP_ALERTING:
+			CONF_Ind[0] = 5;
+			CONF_Ind[3] = 2;
+			switch (pty_cai[5])
+			{
+			case CCBS_INFO_RETAIN:
+				PUT_WORD(&CONF_Ind[1], S_CCBS_INFO_RETAIN);
+				break;
+			case CCBS_STOP_ALERTING:
+				PUT_WORD(&CONF_Ind[1], S_CCBS_STOP_ALERTING);
+				break;
+			case CCBS_ERASECALLLINKAGEID:
+				PUT_WORD(&CONF_Ind[1], S_CCBS_ERASECALLLINKAGEID);
+				CONF_Ind[0] = 7;
+				CONF_Ind[3] = 4;
+				CONF_Ind[6] = 0;
+				CONF_Ind[7] = 0;
+				break;
+			}
+			w = pty_cai[6];
+			PUT_WORD(&CONF_Ind[4], w); /* PartyID */
+
+			if (plci->appl && (a->Notification_Mask[plci->appl->Id - 1] & SMASK_CCBS))
+			{
+				sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, CONF_Ind);
+			}
+			else
+			{
+				for (i = 0; i < max_appl; i++)
+					if (a->Notification_Mask[i] & SMASK_CCBS)
+						sendf(&application[i], _FACILITY_I, Id & 0x7, 0, "ws", 3, CONF_Ind);
+			}
+			break;
+		}
+		break;
+	case CALL_HOLD_REJ:
+		cau = parms[7];
+		if (cau)
+		{
+			i = _L3_CAUSE | cau[2];
+			if (cau[2] == 0) i = 0x3603;
+		}
+		else
+		{
+			i = 0x3603;
+		}
+		PUT_WORD(&SS_Ind[1], S_HOLD);
+		PUT_WORD(&SS_Ind[4], i);
+		if (plci->SuppState == HOLD_REQUEST)
+		{
+			plci->SuppState = IDLE;
+			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+		}
+		break;
+
+	case CALL_HOLD_ACK:
+		if (plci->SuppState == HOLD_REQUEST)
+		{
+			plci->SuppState = CALL_HELD;
+			CodecIdCheck(a, plci);
+			start_internal_command(Id, plci, hold_save_command);
+		}
+		break;
+
+	case CALL_RETRIEVE_REJ:
+		cau = parms[7];
+		if (cau)
+		{
+			i = _L3_CAUSE | cau[2];
+			if (cau[2] == 0) i = 0x3603;
+		}
+		else
+		{
+			i = 0x3603;
+		}
+		PUT_WORD(&SS_Ind[1], S_RETRIEVE);
+		PUT_WORD(&SS_Ind[4], i);
+		if (plci->SuppState == RETRIEVE_REQUEST)
+		{
+			plci->SuppState = CALL_HELD;
+			CodecIdCheck(a, plci);
+			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+		}
+		break;
+
+	case CALL_RETRIEVE_ACK:
+		PUT_WORD(&SS_Ind[1], S_RETRIEVE);
+		if (plci->SuppState == RETRIEVE_REQUEST)
+		{
+			plci->SuppState = IDLE;
+			plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
+			plci->b_channel = esc_chi[esc_chi[0]]&0x1f;
+			if (plci->tel)
+			{
+				mixer_set_bchannel_id_esc(plci, plci->b_channel);
+				dbug(1, dprintf("RetrChannel=0x%x", plci->b_channel));
+				SetVoiceChannel(a->AdvCodecPLCI, esc_chi, a);
+				if (plci->B2_prot == B2_TRANSPARENT && plci->B3_prot == B3_TRANSPARENT)
+				{
+					dbug(1, dprintf("Get B-ch"));
+					start_internal_command(Id, plci, retrieve_restore_command);
+				}
+				else
+					sendf(plci->appl, _FACILITY_I, Id, 0, "ws", 3, SS_Ind);
+			}
+			else
+				start_internal_command(Id, plci, retrieve_restore_command);
+		}
+		break;
+
+	case INDICATE_IND:
+		if (plci->State != LISTENING) {
+			sig_req(plci, HANGUP, 0);
+			send_req(plci);
+			break;
+		}
+		cip = find_cip(a, parms[4], parms[6]);
+		cip_mask = 1L << cip;
+		dbug(1, dprintf("cip=%d,cip_mask=%lx", cip, cip_mask));
+		clear_c_ind_mask(plci);
+		if (!remove_started && !a->adapter_disabled)
+		{
+			set_c_ind_mask_bit(plci, MAX_APPL);
+			group_optimization(a, plci);
+			for (i = 0; i < max_appl; i++) {
+				if (application[i].Id
+				    && (a->CIP_Mask[i] & 1 || a->CIP_Mask[i] & cip_mask)
+				    && CPN_filter_ok(parms[0], a, i)
+				    && test_group_ind_mask_bit(plci, i)) {
+					dbug(1, dprintf("storedcip_mask[%d]=0x%lx", i, a->CIP_Mask[i]));
+					set_c_ind_mask_bit(plci, i);
+					dump_c_ind_mask(plci);
+					plci->State = INC_CON_PENDING;
+					plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) |
+						CALL_DIR_IN | CALL_DIR_ANSWER;
+					if (esc_chi[0]) {
+						plci->b_channel = esc_chi[esc_chi[0]] & 0x1f;
+						mixer_set_bchannel_id_esc(plci, plci->b_channel);
+					}
+					/* if a listen on the ext controller is done, check if hook states */
+					/* are supported or if just a on board codec must be activated     */
+					if (a->codec_listen[i] && !a->AdvSignalPLCI) {
+						if (a->profile.Global_Options & HANDSET)
+							plci->tel = ADV_VOICE;
+						else if (a->profile.Global_Options & ON_BOARD_CODEC)
+							plci->tel = CODEC;
+						if (plci->tel) Id |= EXT_CONTROLLER;
+						a->codec_listen[i] = plci;
+					}
+
+					sendf(&application[i], _CONNECT_I, Id, 0,
+					      "wSSSSSSSbSSSSS", cip,    /* CIP                 */
+					      parms[0],    /* CalledPartyNumber   */
+					      multi_CiPN_parms[0],    /* CallingPartyNumber  */
+					      parms[2],    /* CalledPartySubad    */
+					      parms[3],    /* CallingPartySubad   */
+					      parms[4],    /* BearerCapability    */
+					      parms[5],    /* LowLC               */
+					      parms[6],    /* HighLC              */
+					      ai_len,      /* nested struct add_i */
+					      add_i[0],    /* B channel info    */
+					      add_i[1],    /* keypad facility   */
+					      add_i[2],    /* user user data    */
+					      add_i[3],    /* nested facility   */
+					      multi_CiPN_parms[1]    /* second CiPN(SCR)   */
+						);
+					SendSSExtInd(&application[i],
+						     plci,
+						     Id,
+						     multi_ssext_parms);
+					SendSetupInfo(&application[i],
+						      plci,
+						      Id,
+						      parms,
+						      SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, true));
+				}
+			}
+			clear_c_ind_mask_bit(plci, MAX_APPL);
+			dump_c_ind_mask(plci);
+		}
+		if (c_ind_mask_empty(plci)) {
+			sig_req(plci, HANGUP, 0);
+			send_req(plci);
+			plci->State = IDLE;
+		}
+		plci->notifiedcall = 0;
+		a->listen_active--;
+		listen_check(a);
+		break;
+
+	case CALL_PEND_NOTIFY:
+		plci->notifiedcall = 1;
+		listen_check(a);
+		break;
+
+	case CALL_IND:
+	case CALL_CON:
+		if (plci->State == ADVANCED_VOICE_SIG || plci->State == ADVANCED_VOICE_NOSIG)
+		{
+			if (plci->internal_command == PERM_COD_CONN_PEND)
+			{
+				if (plci->State == ADVANCED_VOICE_NOSIG)
+				{
+					dbug(1, dprintf("***Codec OK"));
+					if (a->AdvSignalPLCI)
+					{
+						tplci = a->AdvSignalPLCI;
+						if (tplci->spoofed_msg)
+						{
+							dbug(1, dprintf("***Spoofed Msg(0x%x)", tplci->spoofed_msg));
+							tplci->command = 0;
+							tplci->internal_command = 0;
+							x_Id = ((word)tplci->Id << 8) | tplci->adapter->Id | 0x80;
+							switch (tplci->spoofed_msg)
+							{
+							case CALL_RES:
+								tplci->command = _CONNECT_I | RESPONSE;
+								api_load_msg(&tplci->saved_msg, saved_parms);
+								add_b1(tplci, &saved_parms[1], 0, tplci->B1_facilities);
+								if (tplci->adapter->Info_Mask[tplci->appl->Id - 1] & 0x200)
+								{
+									/* early B3 connect (CIP mask bit 9) no release after a disc */
+									add_p(tplci, LLI, "\x01\x01");
+								}
+								add_s(tplci, CONN_NR, &saved_parms[2]);
+								add_s(tplci, LLC, &saved_parms[4]);
+								add_ai(tplci, &saved_parms[5]);
+								tplci->State = INC_CON_ACCEPT;
+								sig_req(tplci, CALL_RES, 0);
+								send_req(tplci);
+								break;
+
+							case AWAITING_SELECT_B:
+								dbug(1, dprintf("Select_B continue"));
+								start_internal_command(x_Id, tplci, select_b_command);
+								break;
+
+							case AWAITING_MANUF_CON: /* Get_Plci per Manufacturer_Req to ext controller */
+								if (!tplci->Sig.Id)
+								{
+									dbug(1, dprintf("No SigID!"));
+									sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, _OUT_OF_PLCI);
+									plci_remove(tplci);
+									break;
+								}
+								tplci->command = _MANUFACTURER_R;
+								api_load_msg(&tplci->saved_msg, saved_parms);
+								dir = saved_parms[2].info[0];
+								if (dir == 1) {
+									sig_req(tplci, CALL_REQ, 0);
+								}
+								else if (!dir) {
+									sig_req(tplci, LISTEN_REQ, 0);
+								}
+								send_req(tplci);
+								sendf(tplci->appl, _MANUFACTURER_R | CONFIRM, x_Id, tplci->number, "dww", _DI_MANU_ID, _MANUFACTURER_R, 0);
+								break;
+
+							case (CALL_REQ | AWAITING_MANUF_CON):
+								sig_req(tplci, CALL_REQ, 0);
+								send_req(tplci);
+								break;
+
+							case CALL_REQ:
+								if (!tplci->Sig.Id)
+								{
+									dbug(1, dprintf("No SigID!"));
+									sendf(tplci->appl, _CONNECT_R | CONFIRM, tplci->adapter->Id, 0, "w", _OUT_OF_PLCI);
+									plci_remove(tplci);
+									break;
+								}
+								tplci->command = _CONNECT_R;
+								api_load_msg(&tplci->saved_msg, saved_parms);
+								add_s(tplci, CPN, &saved_parms[1]);
+								add_s(tplci, DSA, &saved_parms[3]);
+								add_ai(tplci, &saved_parms[9]);
+								sig_req(tplci, CALL_REQ, 0);
+								send_req(tplci);
+								break;
+
+							case CALL_RETRIEVE:
+								tplci->command = C_RETRIEVE_REQ;
+								sig_req(tplci, CALL_RETRIEVE, 0);
+								send_req(tplci);
+								break;
+							}
+							tplci->spoofed_msg = 0;
+							if (tplci->internal_command == 0)
+								next_internal_command(x_Id, tplci);
+						}
+					}
+					next_internal_command(Id, plci);
+					break;
+				}
+				dbug(1, dprintf("***Codec Hook Init Req"));
+				plci->internal_command = PERM_COD_HOOK;
+				add_p(plci, FTY, "\x01\x09");             /* Get Hook State*/
+				sig_req(plci, TEL_CTRL, 0);
+				send_req(plci);
+			}
+		}
+		else if (plci->command != _MANUFACTURER_R  /* old style permanent connect */
+			 && plci->State != INC_ACT_PENDING)
+		{
+			mixer_set_bchannel_id_esc(plci, plci->b_channel);
+			if (plci->tel == ADV_VOICE && plci->SuppState == IDLE) /* with permanent codec switch on immediately */
+			{
+				chi[2] = plci->b_channel;
+				SetVoiceChannel(a->AdvCodecPLCI, chi, a);
+			}
+			sendf(plci->appl, _CONNECT_ACTIVE_I, Id, 0, "Sss", parms[21], "", "");
+			plci->State = INC_ACT_PENDING;
+		}
+		break;
+
+	case TEL_CTRL:
+		ie = multi_fac_parms[0]; /* inspect the facility hook indications */
+		if (plci->State == ADVANCED_VOICE_SIG && ie[0]) {
+			switch (ie[1] & 0x91) {
+			case 0x80:   /* hook off */
+			case 0x81:
+				if (plci->internal_command == PERM_COD_HOOK)
+				{
+					dbug(1, dprintf("init:hook_off"));
+					plci->hook_state = ie[1];
+					next_internal_command(Id, plci);
+					break;
+				}
+				else /* ignore doubled hook indications */
+				{
+					if (((plci->hook_state) & 0xf0) == 0x80)
+					{
+						dbug(1, dprintf("ignore hook"));
+						break;
+					}
+					plci->hook_state = ie[1]&0x91;
+				}
+				/* check for incoming call pending */
+				/* and signal '+'.Appl must decide */
+				/* with connect_res if call must   */
+				/* accepted or not                 */
+				for (i = 0, tplci = NULL; i < max_appl; i++) {
+					if (a->codec_listen[i]
+					    && (a->codec_listen[i]->State == INC_CON_PENDING
+						|| a->codec_listen[i]->State == INC_CON_ALERT)) {
+						tplci = a->codec_listen[i];
+						tplci->appl = &application[i];
+					}
+				}
+				/* no incoming call, do outgoing call */
+				/* and signal '+' if outg. setup   */
+				if (!a->AdvSignalPLCI && !tplci) {
+					if ((i = get_plci(a))) {
+						a->AdvSignalPLCI = &a->plci[i - 1];
+						tplci = a->AdvSignalPLCI;
+						tplci->tel  = ADV_VOICE;
+						PUT_WORD(&voice_cai[5], a->AdvSignalAppl->MaxDataLength);
+						if (a->Info_Mask[a->AdvSignalAppl->Id - 1] & 0x200) {
+							/* early B3 connect (CIP mask bit 9) no release after a disc */
+							add_p(tplci, LLI, "\x01\x01");
+						}
+						add_p(tplci, CAI, voice_cai);
+						add_p(tplci, OAD, a->TelOAD);
+						add_p(tplci, OSA, a->TelOSA);
+						add_p(tplci, SHIFT | 6, NULL);
+						add_p(tplci, SIN, "\x02\x01\x00");
+						add_p(tplci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						sig_req(tplci, ASSIGN, DSIG_ID);
+						a->AdvSignalPLCI->internal_command = HOOK_OFF_REQ;
+						a->AdvSignalPLCI->command = 0;
+						tplci->appl = a->AdvSignalAppl;
+						tplci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
+						send_req(tplci);
+					}
+
+				}
+
+				if (!tplci) break;
+				Id = ((word)tplci->Id << 8) | a->Id;
+				Id |= EXT_CONTROLLER;
+				sendf(tplci->appl,
+				      _FACILITY_I,
+				      Id,
+				      0,
+				      "ws", (word)0, "\x01+");
+				break;
+
+			case 0x90:   /* hook on  */
+			case 0x91:
+				if (plci->internal_command == PERM_COD_HOOK)
+				{
+					dbug(1, dprintf("init:hook_on"));
+					plci->hook_state = ie[1] & 0x91;
+					next_internal_command(Id, plci);
+					break;
+				}
+				else /* ignore doubled hook indications */
+				{
+					if (((plci->hook_state) & 0xf0) == 0x90) break;
+					plci->hook_state = ie[1] & 0x91;
+				}
+				/* hangup the adv. voice call and signal '-' to the appl */
+				if (a->AdvSignalPLCI) {
+					Id = ((word)a->AdvSignalPLCI->Id << 8) | a->Id;
+					if (plci->tel) Id |= EXT_CONTROLLER;
+					sendf(a->AdvSignalAppl,
+					      _FACILITY_I,
+					      Id,
+					      0,
+					      "ws", (word)0, "\x01-");
+					a->AdvSignalPLCI->internal_command = HOOK_ON_REQ;
+					a->AdvSignalPLCI->command = 0;
+					sig_req(a->AdvSignalPLCI, HANGUP, 0);
+					send_req(a->AdvSignalPLCI);
+				}
+				break;
+			}
+		}
+		break;
+
+	case RESUME:
+		clear_c_ind_mask_bit(plci, (word)(plci->appl->Id - 1));
+		PUT_WORD(&resume_cau[4], GOOD);
+		sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
+		break;
+
+	case SUSPEND:
+		clear_c_ind_mask(plci);
+
+		if (plci->NL.Id && !plci->nl_remove_id) {
+			mixer_remove(plci);
+			nl_req_ncci(plci, REMOVE, 0);
+		}
+		if (!plci->sig_remove_id) {
+			plci->internal_command = 0;
+			sig_req(plci, REMOVE, 0);
+		}
+		send_req(plci);
+		if (!plci->channels) {
+			sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, "\x05\x04\x00\x02\x00\x00");
+			sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", 0);
+		}
+		break;
+
+	case SUSPEND_REJ:
+		break;
+
+	case HANGUP:
+		plci->hangup_flow_ctrl_timer = 0;
+		if (plci->manufacturer && plci->State == LOCAL_CONNECT) break;
+		cau = parms[7];
+		if (cau) {
+			i = _L3_CAUSE | cau[2];
+			if (cau[2] == 0) i = 0;
+			else if (cau[2] == 8) i = _L1_ERROR;
+			else if (cau[2] == 9 || cau[2] == 10) i = _L2_ERROR;
+			else if (cau[2] == 5) i = _CAPI_GUARD_ERROR;
+		}
+		else {
+			i = _L3_ERROR;
+		}
+
+		if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
+		{
+			for (i = 0; i < max_appl; i++)
+			{
+				if (test_c_ind_mask_bit(plci, i))
+					sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
+			}
+		}
+		else
+		{
+			clear_c_ind_mask(plci);
+		}
+		if (!plci->appl)
+		{
+			if (plci->State == LISTENING)
+			{
+				plci->notifiedcall = 0;
+				a->listen_active--;
+			}
+			plci->State = INC_DIS_PENDING;
+			if (c_ind_mask_empty(plci))
+			{
+				plci->State = IDLE;
+				if (plci->NL.Id && !plci->nl_remove_id)
+				{
+					mixer_remove(plci);
+					nl_req_ncci(plci, REMOVE, 0);
+				}
+				if (!plci->sig_remove_id)
+				{
+					plci->internal_command = 0;
+					sig_req(plci, REMOVE, 0);
+				}
+				send_req(plci);
+			}
+		}
+		else
+		{
+			/* collision of DISCONNECT or CONNECT_RES with HANGUP can   */
+			/* result in a second HANGUP! Don't generate another        */
+			/* DISCONNECT                                               */
+			if (plci->State != IDLE && plci->State != INC_DIS_PENDING)
+			{
+				if (plci->State == RESUMING)
+				{
+					PUT_WORD(&resume_cau[4], i);
+					sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
+				}
+				plci->State = INC_DIS_PENDING;
+				sendf(plci->appl, _DISCONNECT_I, Id, 0, "w", i);
+			}
+		}
+		break;
+
+	case SSEXT_IND:
+		SendSSExtInd(NULL, plci, Id, multi_ssext_parms);
+		break;
+
+	case VSWITCH_REQ:
+		VSwitchReqInd(plci, Id, multi_vswitch_parms);
+		break;
+	case VSWITCH_IND:
+		if (plci->relatedPTYPLCI &&
+		    plci->vswitchstate == 3 &&
+		    plci->relatedPTYPLCI->vswitchstate == 3 &&
+		    parms[MAXPARMSIDS - 1][0])
+		{
+			add_p(plci->relatedPTYPLCI, SMSG, parms[MAXPARMSIDS - 1]);
+			sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
+			send_req(plci->relatedPTYPLCI);
+		}
+		else VSwitchReqInd(plci, Id, multi_vswitch_parms);
+		break;
+
+	}
+}
+
+
+static void SendSetupInfo(APPL *appl, PLCI *plci, dword Id, byte **parms, byte Info_Sent_Flag)
+{
+	word i;
+	byte *ie;
+	word Info_Number;
+	byte *Info_Element;
+	word Info_Mask = 0;
+
+	dbug(1, dprintf("SetupInfo"));
+
+	for (i = 0; i < MAXPARMSIDS; i++) {
+		ie = parms[i];
+		Info_Number = 0;
+		Info_Element = ie;
+		if (ie[0]) {
+			switch (i) {
+			case 0:
+				dbug(1, dprintf("CPN "));
+				Info_Number = 0x0070;
+				Info_Mask = 0x80;
+				Info_Sent_Flag = true;
+				break;
+			case 8:  /* display      */
+				dbug(1, dprintf("display(%d)", i));
+				Info_Number = 0x0028;
+				Info_Mask = 0x04;
+				Info_Sent_Flag = true;
+				break;
+			case 16: /* Channel Id */
+				dbug(1, dprintf("CHI"));
+				Info_Number = 0x0018;
+				Info_Mask = 0x100;
+				Info_Sent_Flag = true;
+				mixer_set_bchannel_id(plci, Info_Element);
+				break;
+			case 19: /* Redirected Number */
+				dbug(1, dprintf("RDN"));
+				Info_Number = 0x0074;
+				Info_Mask = 0x400;
+				Info_Sent_Flag = true;
+				break;
+			case 20: /* Redirected Number extended */
+				dbug(1, dprintf("RDX"));
+				Info_Number = 0x0073;
+				Info_Mask = 0x400;
+				Info_Sent_Flag = true;
+				break;
+			case 22: /* Redirecing Number  */
+				dbug(1, dprintf("RIN"));
+				Info_Number = 0x0076;
+				Info_Mask = 0x400;
+				Info_Sent_Flag = true;
+				break;
+			default:
+				Info_Number = 0;
+				break;
+			}
+		}
+
+		if (i == MAXPARMSIDS - 2) { /* to indicate the message type "Setup" */
+			Info_Number = 0x8000 | 5;
+			Info_Mask = 0x10;
+			Info_Element = "";
+		}
+
+		if (Info_Sent_Flag && Info_Number) {
+			if (plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask) {
+				sendf(appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
+			}
+		}
+	}
 }
 
 
 static void SendInfo(PLCI *plci, dword Id, byte **parms, byte iesent)
 {
-  word i;
-  word j;
-  word k;
-  byte   * ie;
-  word Info_Number;
-  byte   * Info_Element;
-  word Info_Mask = 0;
-  static byte charges[5] = {4,0,0,0,0};
-  static byte cause[] = {0x02,0x80,0x00};
-  APPL   *appl;
-
-  dbug(1,dprintf("InfoParse "));
-
-  if(
-        !plci->appl
-        && !plci->State
-        && plci->Sig.Ind!=NCR_FACILITY
-      )
-  {
-    dbug(1,dprintf("NoParse "));
-    return;
-  }
-  cause[2] = 0;
-  for(i=0; i<MAXPARMSIDS; i++) {
-    ie = parms[i];
-    Info_Number = 0;
-    Info_Element = ie;
-    if(ie[0]) {
-      switch(i) {
-      case 0:
-        dbug(1,dprintf("CPN "));
-        Info_Number = 0x0070;
-        Info_Mask   = 0x80;
-        break;
-      case 7: /* ESC_CAU */
-        dbug(1,dprintf("cau(0x%x)",ie[2]));
-        Info_Number = 0x0008;
-        Info_Mask = 0x00;
-        cause[2] = ie[2];
-        Info_Element = NULL;
-        break;
-      case 8:  /* display      */
-        dbug(1,dprintf("display(%d)",i));
-        Info_Number = 0x0028;
-        Info_Mask = 0x04;
-        break;
-      case 9:  /* Date display */
-        dbug(1,dprintf("date(%d)",i));
-        Info_Number = 0x0029;
-        Info_Mask = 0x02;
-        break;
-      case 10: /* charges */
-        for(j=0;j<4;j++) charges[1+j] = 0;
-        for(j=0; j<ie[0] && !(ie[1+j]&0x80); j++);
-        for(k=1,j++; j<ie[0] && k<=4; j++,k++) charges[k] = ie[1+j];
-        Info_Number = 0x4000;
-        Info_Mask = 0x40;
-        Info_Element = charges;
-        break;
-      case 11: /* user user info */
-        dbug(1,dprintf("uui"));
-        Info_Number = 0x007E;
-        Info_Mask = 0x08;
-        break;
-      case 12: /* congestion receiver ready */
-        dbug(1,dprintf("clRDY"));
-        Info_Number = 0x00B0;
-        Info_Mask = 0x08;
-        Info_Element = "";
-        break;
-      case 13: /* congestion receiver not ready */
-        dbug(1,dprintf("clNRDY"));
-        Info_Number = 0x00BF;
-        Info_Mask = 0x08;
-        Info_Element = "";
-        break;
-      case 15: /* Keypad Facility */
-        dbug(1,dprintf("KEY"));
-        Info_Number = 0x002C;
-        Info_Mask = 0x20;
-        break;
-      case 16: /* Channel Id */
-        dbug(1,dprintf("CHI"));
-        Info_Number = 0x0018;
-        Info_Mask = 0x100;
-        mixer_set_bchannel_id (plci, Info_Element);
-        break;
-      case 17: /* if no 1tr6 cause, send full cause, else esc_cause */
-        dbug(1,dprintf("q9cau(0x%x)",ie[2]));
-        if(!cause[2] || cause[2]<0x80) break;  /* eg. layer 1 error */
-        Info_Number = 0x0008;
-        Info_Mask = 0x01;
-        if(cause[2] != ie[2]) Info_Element = cause;
-        break;
-      case 19: /* Redirected Number */
-        dbug(1,dprintf("RDN"));
-        Info_Number = 0x0074;
-        Info_Mask = 0x400;
-        break;
-      case 22: /* Redirecing Number  */
-        dbug(1,dprintf("RIN"));
-        Info_Number = 0x0076;
-        Info_Mask = 0x400;
-        break;
-      case 23: /* Notification Indicator  */
-        dbug(1,dprintf("NI"));
-        Info_Number = (word)NI;
-        Info_Mask = 0x210;
-        break;
-      case 26: /* Call State  */
-        dbug(1,dprintf("CST"));
-        Info_Number = (word)CST;
-        Info_Mask = 0x01; /* do with cause i.e. for now */
-        break;
-      case MAXPARMSIDS-2:  /* Escape Message Type, must be the last indication */
-        dbug(1,dprintf("ESC/MT[0x%x]",ie[3]));
-        Info_Number = 0x8000 |ie[3];
-        if(iesent) Info_Mask = 0xffff;
-        else  Info_Mask = 0x10;
-        Info_Element = "";
-        break;
-      default:
-        Info_Number  = 0;
-        Info_Mask    = 0;
-        Info_Element = "";
-        break;
-      }
-    }
-
-    if(plci->Sig.Ind==NCR_FACILITY)           /* check controller broadcast */
-    {
-      for(j=0; j<max_appl; j++)
-      {
-        appl = &application[j];
-        if(Info_Number
-        && appl->Id
-        && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask)
-        {
-          dbug(1,dprintf("NCR_Ind"));
-          iesent=true;
-          sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element);
-        }
-      }
-    }
-    else if(!plci->appl)
-    { /* overlap receiving broadcast */
-      if(Info_Number==CPN
-      || Info_Number==KEY
-      || Info_Number==NI
-      || Info_Number==DSP
-      || Info_Number==UUI )
-      {
-        for(j=0; j<max_appl; j++)
-        {
-          if(test_c_ind_mask_bit (plci, j))
-          {
-            dbug(1,dprintf("Ovl_Ind"));
-            iesent=true;
-            sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element);
-          }
-        }
-      }
-    }               /* all other signalling states */
-    else if(Info_Number
-    && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask)
-    {
-      dbug(1,dprintf("Std_Ind"));
-      iesent=true;
-      sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
-    }
-  }
+	word i;
+	word j;
+	word k;
+	byte *ie;
+	word Info_Number;
+	byte *Info_Element;
+	word Info_Mask = 0;
+	static byte charges[5] = {4, 0, 0, 0, 0};
+	static byte cause[] = {0x02, 0x80, 0x00};
+	APPL *appl;
+
+	dbug(1, dprintf("InfoParse "));
+
+	if (
+		!plci->appl
+		&& !plci->State
+		&& plci->Sig.Ind != NCR_FACILITY
+		)
+	{
+		dbug(1, dprintf("NoParse "));
+		return;
+	}
+	cause[2] = 0;
+	for (i = 0; i < MAXPARMSIDS; i++) {
+		ie = parms[i];
+		Info_Number = 0;
+		Info_Element = ie;
+		if (ie[0]) {
+			switch (i) {
+			case 0:
+				dbug(1, dprintf("CPN "));
+				Info_Number = 0x0070;
+				Info_Mask   = 0x80;
+				break;
+			case 7: /* ESC_CAU */
+				dbug(1, dprintf("cau(0x%x)", ie[2]));
+				Info_Number = 0x0008;
+				Info_Mask = 0x00;
+				cause[2] = ie[2];
+				Info_Element = NULL;
+				break;
+			case 8:  /* display      */
+				dbug(1, dprintf("display(%d)", i));
+				Info_Number = 0x0028;
+				Info_Mask = 0x04;
+				break;
+			case 9:  /* Date display */
+				dbug(1, dprintf("date(%d)", i));
+				Info_Number = 0x0029;
+				Info_Mask = 0x02;
+				break;
+			case 10: /* charges */
+				for (j = 0; j < 4; j++) charges[1 + j] = 0;
+				for (j = 0; j < ie[0] && !(ie[1 + j] & 0x80); j++);
+				for (k = 1, j++; j < ie[0] && k <= 4; j++, k++) charges[k] = ie[1 + j];
+				Info_Number = 0x4000;
+				Info_Mask = 0x40;
+				Info_Element = charges;
+				break;
+			case 11: /* user user info */
+				dbug(1, dprintf("uui"));
+				Info_Number = 0x007E;
+				Info_Mask = 0x08;
+				break;
+			case 12: /* congestion receiver ready */
+				dbug(1, dprintf("clRDY"));
+				Info_Number = 0x00B0;
+				Info_Mask = 0x08;
+				Info_Element = "";
+				break;
+			case 13: /* congestion receiver not ready */
+				dbug(1, dprintf("clNRDY"));
+				Info_Number = 0x00BF;
+				Info_Mask = 0x08;
+				Info_Element = "";
+				break;
+			case 15: /* Keypad Facility */
+				dbug(1, dprintf("KEY"));
+				Info_Number = 0x002C;
+				Info_Mask = 0x20;
+				break;
+			case 16: /* Channel Id */
+				dbug(1, dprintf("CHI"));
+				Info_Number = 0x0018;
+				Info_Mask = 0x100;
+				mixer_set_bchannel_id(plci, Info_Element);
+				break;
+			case 17: /* if no 1tr6 cause, send full cause, else esc_cause */
+				dbug(1, dprintf("q9cau(0x%x)", ie[2]));
+				if (!cause[2] || cause[2] < 0x80) break;  /* eg. layer 1 error */
+				Info_Number = 0x0008;
+				Info_Mask = 0x01;
+				if (cause[2] != ie[2]) Info_Element = cause;
+				break;
+			case 19: /* Redirected Number */
+				dbug(1, dprintf("RDN"));
+				Info_Number = 0x0074;
+				Info_Mask = 0x400;
+				break;
+			case 22: /* Redirecing Number  */
+				dbug(1, dprintf("RIN"));
+				Info_Number = 0x0076;
+				Info_Mask = 0x400;
+				break;
+			case 23: /* Notification Indicator  */
+				dbug(1, dprintf("NI"));
+				Info_Number = (word)NI;
+				Info_Mask = 0x210;
+				break;
+			case 26: /* Call State  */
+				dbug(1, dprintf("CST"));
+				Info_Number = (word)CST;
+				Info_Mask = 0x01; /* do with cause i.e. for now */
+				break;
+			case MAXPARMSIDS - 2:  /* Escape Message Type, must be the last indication */
+				dbug(1, dprintf("ESC/MT[0x%x]", ie[3]));
+				Info_Number = 0x8000 | ie[3];
+				if (iesent) Info_Mask = 0xffff;
+				else  Info_Mask = 0x10;
+				Info_Element = "";
+				break;
+			default:
+				Info_Number  = 0;
+				Info_Mask    = 0;
+				Info_Element = "";
+				break;
+			}
+		}
+
+		if (plci->Sig.Ind == NCR_FACILITY)           /* check controller broadcast */
+		{
+			for (j = 0; j < max_appl; j++)
+			{
+				appl = &application[j];
+				if (Info_Number
+				    && appl->Id
+				    && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask)
+				{
+					dbug(1, dprintf("NCR_Ind"));
+					iesent = true;
+					sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element);
+				}
+			}
+		}
+		else if (!plci->appl)
+		{ /* overlap receiving broadcast */
+			if (Info_Number == CPN
+			    || Info_Number == KEY
+			    || Info_Number == NI
+			    || Info_Number == DSP
+			    || Info_Number == UUI)
+			{
+				for (j = 0; j < max_appl; j++)
+				{
+					if (test_c_ind_mask_bit(plci, j))
+					{
+						dbug(1, dprintf("Ovl_Ind"));
+						iesent = true;
+						sendf(&application[j], _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
+					}
+				}
+			}
+		}               /* all other signalling states */
+		else if (Info_Number
+			 && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask)
+		{
+			dbug(1, dprintf("Std_Ind"));
+			iesent = true;
+			sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
+		}
+	}
 }
 
 
 static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type,
 			dword info_mask, byte setupParse)
 {
-  word i;
-  word j;
-  byte   * ie;
-  word Info_Number;
-  byte   * Info_Element;
-  APPL   *appl;
-  word Info_Mask = 0;
-  byte iesent=0;
-
-  if(
-      !plci->appl
-      && !plci->State
-      && plci->Sig.Ind!=NCR_FACILITY
-      && !setupParse
-      )
-  {
-    dbug(1,dprintf("NoM-IEParse "));
-    return 0;
-  }
-  dbug(1,dprintf("M-IEParse "));
-
-  for(i=0; i<MAX_MULTI_IE; i++)
-  {
-    ie = parms[i];
-    Info_Number = 0;
-    Info_Element = ie;
-    if(ie[0])
-    {
-      dbug(1,dprintf("[Ind0x%x]:IE=0x%x",plci->Sig.Ind,ie_type));
-      Info_Number = (word)ie_type;
-      Info_Mask = (word)info_mask;
-    }
-
-    if(plci->Sig.Ind==NCR_FACILITY)           /* check controller broadcast */
-    {
-      for(j=0; j<max_appl; j++)
-      {
-        appl = &application[j];
-        if(Info_Number
-        && appl->Id
-        && plci->adapter->Info_Mask[appl->Id-1] &Info_Mask)
-        {
-          iesent = true;
-          dbug(1,dprintf("Mlt_NCR_Ind"));
-          sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element);
-        }
-      }
-    }
-    else if(!plci->appl && Info_Number)
-    {                                        /* overlap receiving broadcast */
-      for(j=0; j<max_appl; j++)
-      {
-        if(test_c_ind_mask_bit (plci, j))
-        {
-          iesent = true;
-          dbug(1,dprintf("Mlt_Ovl_Ind"));
-          sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element);
-        }
-      }
-    }                                        /* all other signalling states */
-    else if(Info_Number
-    && plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask)
-    {
-      iesent = true;
-      dbug(1,dprintf("Mlt_Std_Ind"));
-      sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
-    }
-  }
-  return iesent;
-}
-
-static void SendSSExtInd(APPL   * appl, PLCI   * plci, dword Id, byte   * * parms)
-{
-  word i;
-   /* Format of multi_ssext_parms[i][]:
-   0 byte length
-   1 byte SSEXTIE
-   2 byte SSEXT_REQ/SSEXT_IND
-   3 byte length
-   4 word SSExtCommand
-   6... Params
-   */
-  if(
-   plci
-   && plci->State
-   && plci->Sig.Ind!=NCR_FACILITY
-    )
- for(i=0;i<MAX_MULTI_IE;i++)
-    {
-      if(parms[i][0]<6) continue;
-   if(parms[i][2]==SSEXT_REQ) continue;
-
-   if(appl)
-   {
-    parms[i][0]=0; /* kill it */
-    sendf(appl,_MANUFACTURER_I,
-    Id,
-    0,
-    "dwS",
-    _DI_MANU_ID,
-    _DI_SSEXT_CTRL,
-    &parms[i][3]);
-   }
-   else if(plci->appl)
-   {
-    parms[i][0]=0; /* kill it */
-    sendf(plci->appl,_MANUFACTURER_I,
-    Id,
-    0,
-    "dwS",
-    _DI_MANU_ID,
-    _DI_SSEXT_CTRL,
-    &parms[i][3]);
-   }
-    }
+	word i;
+	word j;
+	byte *ie;
+	word Info_Number;
+	byte *Info_Element;
+	APPL *appl;
+	word Info_Mask = 0;
+	byte iesent = 0;
+
+	if (
+		!plci->appl
+		&& !plci->State
+		&& plci->Sig.Ind != NCR_FACILITY
+		&& !setupParse
+		)
+	{
+		dbug(1, dprintf("NoM-IEParse "));
+		return 0;
+	}
+	dbug(1, dprintf("M-IEParse "));
+
+	for (i = 0; i < MAX_MULTI_IE; i++)
+	{
+		ie = parms[i];
+		Info_Number = 0;
+		Info_Element = ie;
+		if (ie[0])
+		{
+			dbug(1, dprintf("[Ind0x%x]:IE=0x%x", plci->Sig.Ind, ie_type));
+			Info_Number = (word)ie_type;
+			Info_Mask = (word)info_mask;
+		}
+
+		if (plci->Sig.Ind == NCR_FACILITY)           /* check controller broadcast */
+		{
+			for (j = 0; j < max_appl; j++)
+			{
+				appl = &application[j];
+				if (Info_Number
+				    && appl->Id
+				    && plci->adapter->Info_Mask[appl->Id - 1] & Info_Mask)
+				{
+					iesent = true;
+					dbug(1, dprintf("Mlt_NCR_Ind"));
+					sendf(&application[j], _INFO_I, Id & 0x0f, 0, "wS", Info_Number, Info_Element);
+				}
+			}
+		}
+		else if (!plci->appl && Info_Number)
+		{                                        /* overlap receiving broadcast */
+			for (j = 0; j < max_appl; j++)
+			{
+				if (test_c_ind_mask_bit(plci, j))
+				{
+					iesent = true;
+					dbug(1, dprintf("Mlt_Ovl_Ind"));
+					sendf(&application[j] , _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
+				}
+			}
+		}                                        /* all other signalling states */
+		else if (Info_Number
+			 && plci->adapter->Info_Mask[plci->appl->Id - 1] & Info_Mask)
+		{
+			iesent = true;
+			dbug(1, dprintf("Mlt_Std_Ind"));
+			sendf(plci->appl, _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
+		}
+	}
+	return iesent;
+}
+
+static void SendSSExtInd(APPL *appl, PLCI *plci, dword Id, byte **parms)
+{
+	word i;
+	/* Format of multi_ssext_parms[i][]:
+	   0 byte length
+	   1 byte SSEXTIE
+	   2 byte SSEXT_REQ/SSEXT_IND
+	   3 byte length
+	   4 word SSExtCommand
+	   6... Params
+	*/
+	if (
+		plci
+		&& plci->State
+		&& plci->Sig.Ind != NCR_FACILITY
+		)
+		for (i = 0; i < MAX_MULTI_IE; i++)
+		{
+			if (parms[i][0] < 6) continue;
+			if (parms[i][2] == SSEXT_REQ) continue;
+
+			if (appl)
+			{
+				parms[i][0] = 0; /* kill it */
+				sendf(appl, _MANUFACTURER_I,
+				      Id,
+				      0,
+				      "dwS",
+				      _DI_MANU_ID,
+				      _DI_SSEXT_CTRL,
+				      &parms[i][3]);
+			}
+			else if (plci->appl)
+			{
+				parms[i][0] = 0; /* kill it */
+				sendf(plci->appl, _MANUFACTURER_I,
+				      Id,
+				      0,
+				      "dwS",
+				      _DI_MANU_ID,
+				      _DI_SSEXT_CTRL,
+				      &parms[i][3]);
+			}
+		}
 };
 
 static void nl_ind(PLCI *plci)
 {
-  byte ch;
-  word ncci;
-  dword Id;
-  DIVA_CAPI_ADAPTER   * a;
-  word NCCIcode;
-  APPL   * APPLptr;
-  word count;
-  word Num;
-  word i, ncpi_state;
-  byte len, ncci_state;
-  word msg;
-  word info = 0;
-  word fax_feature_bits;
-  byte fax_send_edata_ack;
-  static byte v120_header_buffer[2 + 3];
-  static word fax_info[] = {
-    0,                     /* T30_SUCCESS                        */
-    _FAX_NO_CONNECTION,    /* T30_ERR_NO_DIS_RECEIVED            */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_RESPONSE        */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_RESPONSE          */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_TOO_MANY_REPEATS           */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_UNEXPECTED_MESSAGE         */
-    _FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DCN             */
-    _FAX_LOCAL_ABORT,      /* T30_ERR_DTC_UNSUPPORTED            */
-    _FAX_TRAINING_ERROR,   /* T30_ERR_ALL_RATES_FAILED           */
-    _FAX_TRAINING_ERROR,   /* T30_ERR_TOO_MANY_TRAINS            */
-    _FAX_PARAMETER_ERROR,  /* T30_ERR_RECEIVE_CORRUPTED          */
-    _FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DISC            */
-    _FAX_LOCAL_ABORT,      /* T30_ERR_APPLICATION_DISC           */
-    _FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_DIS           */
-    _FAX_LOCAL_ABORT,      /* T30_ERR_INCOMPATIBLE_DCS           */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_COMMAND         */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_COMMAND           */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG   */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG  */
-    _FAX_NO_CONNECTION,    /* T30_ERR_NOT_IDENTIFIED             */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_SUPERVISORY_TIMEOUT        */
-    _FAX_PARAMETER_ERROR,  /* T30_ERR_TOO_LONG_SCAN_LINE         */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS    */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR    */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_FTT     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_EOM     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_MPS     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_MCF     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_RTN     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_CFR               */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOP     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOM     */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_MPS     */
-    0x331d,                /* T30_ERR_SUB_SEP_UNSUPPORTED        */
-    0x331e,                /* T30_ERR_PWD_UNSUPPORTED            */
-    0x331f,                /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED    */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_INVALID_COMMAND_FRAME      */
-    _FAX_PARAMETER_ERROR,  /* T30_ERR_UNSUPPORTED_PAGE_CODING    */
-    _FAX_PARAMETER_ERROR,  /* T30_ERR_INVALID_PAGE_CODING        */
-    _FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG   */
-    _FAX_LOCAL_ABORT,      /* T30_ERR_TIMEOUT_FROM_APPLICATION   */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_TRAINING_TIMEOUT    */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_UNEXPECTED_V21      */
-    _FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_PRIMARY_CTS_ON      */
-    _FAX_LOCAL_ABORT,      /* T30_ERR_V34FAX_TURNAROUND_POLLING  */
-    _FAX_LOCAL_ABORT       /* T30_ERR_V34FAX_V8_INCOMPATIBILITY  */
-  };
-
-    byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1];
-
-
-  static word rtp_info[] = {
-    GOOD,                  /* RTP_SUCCESS                       */
-    0x3600                 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE    */
-  };
-
-  static dword udata_forwarding_table[0x100 / sizeof(dword)] =
-  {
-    0x0020301e, 0x00000000, 0x00000000, 0x00000000,
-    0x00000000, 0x00000000, 0x00000000, 0x00000000
-  };
-
-  ch = plci->NL.IndCh;
-  a = plci->adapter;
-  ncci = a->ch_ncci[ch];
-  Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id;
-  if(plci->tel) Id|=EXT_CONTROLLER;
-  APPLptr = plci->appl;
-  dbug(1,dprintf("NL_IND-Id(NL:0x%x)=0x%08lx,plci=%x,tel=%x,state=0x%x,ch=0x%x,chs=%d,Ind=%x",
-    plci->NL.Id,Id,plci->Id,plci->tel,plci->State,ch,plci->channels,plci->NL.Ind &0x0f));
-
-  /* in the case if no connect_active_Ind was sent to the appl we wait for */
-
-  if (plci->nl_remove_id)
-  {
-    plci->NL.RNR = 2; /* discard */
-    dbug(1,dprintf("NL discard while remove pending"));
-    return;
-  }
-  if((plci->NL.Ind &0x0f)==N_CONNECT)
-  {
-    if(plci->State==INC_DIS_PENDING
-    || plci->State==OUTG_DIS_PENDING
-    || plci->State==IDLE)
-    {
-      plci->NL.RNR = 2; /* discard */
-      dbug(1,dprintf("discard n_connect"));
-      return;
-    }
-    if(plci->State < INC_ACT_PENDING)
-    {
-      plci->NL.RNR = 1; /* flow control */
-      channel_x_off (plci, ch, N_XON_CONNECT_IND);
-      return;
-    }
-  }
-
-  if(!APPLptr)                         /* no application or invalid data */
-  {                                    /* while reloading the DSP        */
-    dbug(1,dprintf("discard1"));
-    plci->NL.RNR = 2;
-    return;
-  }
-
-  if (((plci->NL.Ind &0x0f) == N_UDATA)
-     && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18)))
-        || (plci->B2_prot == 7)
-        || (plci->B3_prot == 7)) )
-  {
-    plci->ncpi_buffer[0] = 0;
-
-    ncpi_state = plci->ncpi_state;
-    if (plci->NL.complete == 1)
-    {
-      byte  * data = &plci->NL.RBuffer->P[0];
-
-      if ((plci->NL.RBuffer->length >= 12)
-        &&( (*data == DSP_UDATA_INDICATION_DCD_ON)
-          ||(*data == DSP_UDATA_INDICATION_CTS_ON)) )
-      {
-        word conn_opt, ncpi_opt = 0x00;
+	byte ch;
+	word ncci;
+	dword Id;
+	DIVA_CAPI_ADAPTER *a;
+	word NCCIcode;
+	APPL *APPLptr;
+	word count;
+	word Num;
+	word i, ncpi_state;
+	byte len, ncci_state;
+	word msg;
+	word info = 0;
+	word fax_feature_bits;
+	byte fax_send_edata_ack;
+	static byte v120_header_buffer[2 + 3];
+	static word fax_info[] = {
+		0,                     /* T30_SUCCESS                        */
+		_FAX_NO_CONNECTION,    /* T30_ERR_NO_DIS_RECEIVED            */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_RESPONSE        */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_RESPONSE          */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TOO_MANY_REPEATS           */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_UNEXPECTED_MESSAGE         */
+		_FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DCN             */
+		_FAX_LOCAL_ABORT,      /* T30_ERR_DTC_UNSUPPORTED            */
+		_FAX_TRAINING_ERROR,   /* T30_ERR_ALL_RATES_FAILED           */
+		_FAX_TRAINING_ERROR,   /* T30_ERR_TOO_MANY_TRAINS            */
+		_FAX_PARAMETER_ERROR,  /* T30_ERR_RECEIVE_CORRUPTED          */
+		_FAX_REMOTE_ABORT,     /* T30_ERR_UNEXPECTED_DISC            */
+		_FAX_LOCAL_ABORT,      /* T30_ERR_APPLICATION_DISC           */
+		_FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_DIS           */
+		_FAX_LOCAL_ABORT,      /* T30_ERR_INCOMPATIBLE_DCS           */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_NO_COMMAND         */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_COMMAND           */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_COMMAND_TOO_LONG   */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_TIMEOUT_RESPONSE_TOO_LONG  */
+		_FAX_NO_CONNECTION,    /* T30_ERR_NOT_IDENTIFIED             */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_SUPERVISORY_TIMEOUT        */
+		_FAX_PARAMETER_ERROR,  /* T30_ERR_TOO_LONG_SCAN_LINE         */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_MPS    */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_PAGE_AFTER_CFR    */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_FTT     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_EOM     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCS_AFTER_MPS     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_MCF     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_DCN_AFTER_RTN     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_CFR               */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOP     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_EOM     */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_RETRY_NO_MCF_AFTER_MPS     */
+		0x331d,                /* T30_ERR_SUB_SEP_UNSUPPORTED        */
+		0x331e,                /* T30_ERR_PWD_UNSUPPORTED            */
+		0x331f,                /* T30_ERR_SUB_SEP_PWD_UNSUPPORTED    */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_INVALID_COMMAND_FRAME      */
+		_FAX_PARAMETER_ERROR,  /* T30_ERR_UNSUPPORTED_PAGE_CODING    */
+		_FAX_PARAMETER_ERROR,  /* T30_ERR_INVALID_PAGE_CODING        */
+		_FAX_REMOTE_REJECT,    /* T30_ERR_INCOMPATIBLE_PAGE_CONFIG   */
+		_FAX_LOCAL_ABORT,      /* T30_ERR_TIMEOUT_FROM_APPLICATION   */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_NO_REACTION_ON_MARK */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_TRAINING_TIMEOUT    */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_UNEXPECTED_V21      */
+		_FAX_PROTOCOL_ERROR,   /* T30_ERR_V34FAX_PRIMARY_CTS_ON      */
+		_FAX_LOCAL_ABORT,      /* T30_ERR_V34FAX_TURNAROUND_POLLING  */
+		_FAX_LOCAL_ABORT       /* T30_ERR_V34FAX_V8_INCOMPATIBILITY  */
+	};
+
+	byte dtmf_code_buffer[CAPIDTMF_RECV_DIGIT_BUFFER_SIZE + 1];
+
+
+	static word rtp_info[] = {
+		GOOD,                  /* RTP_SUCCESS                       */
+		0x3600                 /* RTP_ERR_SSRC_OR_PAYLOAD_CHANGE    */
+	};
+
+	static dword udata_forwarding_table[0x100 / sizeof(dword)] =
+		{
+			0x0020301e, 0x00000000, 0x00000000, 0x00000000,
+			0x00000000, 0x00000000, 0x00000000, 0x00000000
+		};
+
+	ch = plci->NL.IndCh;
+	a = plci->adapter;
+	ncci = a->ch_ncci[ch];
+	Id = (((dword)(ncci ? ncci : ch)) << 16) | (((word) plci->Id) << 8) | a->Id;
+	if (plci->tel) Id |= EXT_CONTROLLER;
+	APPLptr = plci->appl;
+	dbug(1, dprintf("NL_IND-Id(NL:0x%x)=0x%08lx,plci=%x,tel=%x,state=0x%x,ch=0x%x,chs=%d,Ind=%x",
+			plci->NL.Id, Id, plci->Id, plci->tel, plci->State, ch, plci->channels, plci->NL.Ind & 0x0f));
+
+	/* in the case if no connect_active_Ind was sent to the appl we wait for */
+
+	if (plci->nl_remove_id)
+	{
+		plci->NL.RNR = 2; /* discard */
+		dbug(1, dprintf("NL discard while remove pending"));
+		return;
+	}
+	if ((plci->NL.Ind & 0x0f) == N_CONNECT)
+	{
+		if (plci->State == INC_DIS_PENDING
+		    || plci->State == OUTG_DIS_PENDING
+		    || plci->State == IDLE)
+		{
+			plci->NL.RNR = 2; /* discard */
+			dbug(1, dprintf("discard n_connect"));
+			return;
+		}
+		if (plci->State < INC_ACT_PENDING)
+		{
+			plci->NL.RNR = 1; /* flow control */
+			channel_x_off(plci, ch, N_XON_CONNECT_IND);
+			return;
+		}
+	}
+
+	if (!APPLptr)                         /* no application or invalid data */
+	{                                    /* while reloading the DSP        */
+		dbug(1, dprintf("discard1"));
+		plci->NL.RNR = 2;
+		return;
+	}
+
+	if (((plci->NL.Ind & 0x0f) == N_UDATA)
+	    && (((plci->B2_prot != B2_SDLC) && ((plci->B1_resource == 17) || (plci->B1_resource == 18)))
+		|| (plci->B2_prot == 7)
+		|| (plci->B3_prot == 7)))
+	{
+		plci->ncpi_buffer[0] = 0;
+
+		ncpi_state = plci->ncpi_state;
+		if (plci->NL.complete == 1)
+		{
+			byte *data = &plci->NL.RBuffer->P[0];
+
+			if ((plci->NL.RBuffer->length >= 12)
+			    && ((*data == DSP_UDATA_INDICATION_DCD_ON)
+				|| (*data == DSP_UDATA_INDICATION_CTS_ON)))
+			{
+				word conn_opt, ncpi_opt = 0x00;
 /*      HexDump ("MDM N_UDATA:", plci->NL.RBuffer->length, data); */
 
-        if (*data == DSP_UDATA_INDICATION_DCD_ON)
-          plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
-        if (*data == DSP_UDATA_INDICATION_CTS_ON)
-          plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED;
-
-        data++;    /* indication code */
-        data += 2; /* timestamp */
-        if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN))
-          ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED);
-        data++;    /* connected norm */
-        conn_opt = GET_WORD(data);
-        data += 2; /* connected options */
-
-        PUT_WORD (&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF));
-
-        if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42)
-        {
-          ncpi_opt |= MDM_NCPI_ECM_V42;
-        }
-        else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP)
-        {
-          ncpi_opt |= MDM_NCPI_ECM_MNP;
-        }
-        else
-        {
-          ncpi_opt |= MDM_NCPI_TRANSPARENT;
-        }
-        if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION)
-        {
-          ncpi_opt |= MDM_NCPI_COMPRESSED;
-        }
-        PUT_WORD (&(plci->ncpi_buffer[3]), ncpi_opt);
-        plci->ncpi_buffer[0] = 4;
-
-        plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
-      }
-    }
-    if (plci->B3_prot == 7)
-    {
-      if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING))
-       && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-       && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-      {
-        a->ncci_state[ncci] = INC_ACT_PENDING;
-        sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
-        plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-      }
-    }
-
-    if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
-        & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
-     || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED)
-     || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED))
-
-    {
-      plci->NL.RNR = 2;
-      return;
-    }
-  }
-
-  if(plci->NL.complete == 2)
-    {
-    if (((plci->NL.Ind &0x0f) == N_UDATA)
-     && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f))))
-    {
-      switch(plci->RData[0].P[0])
-      {
-
-      case DTMF_UDATA_INDICATION_FAX_CALLING_TONE:
-        if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
-          sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,"ws", SELECTOR_DTMF, "\x01X");
-        break;
-      case DTMF_UDATA_INDICATION_ANSWER_TONE:
-        if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
-          sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,"ws", SELECTOR_DTMF, "\x01Y");
-        break;
-      case DTMF_UDATA_INDICATION_DIGITS_RECEIVED:
-        dtmf_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
-        break;
-      case DTMF_UDATA_INDICATION_DIGITS_SENT:
-        dtmf_confirmation (Id, plci);
-        break;
-
-
-      case UDATA_INDICATION_MIXER_TAP_DATA:
-        capidtmf_recv_process_block (&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1));
- i = capidtmf_indication (&(plci->capidtmf_state), dtmf_code_buffer + 1);
- if (i != 0)
- {
-   dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED;
-          dtmf_indication (Id, plci, dtmf_code_buffer, (word)(i + 1));
- }
-        break;
-
-
-      case UDATA_INDICATION_MIXER_COEFS_SET:
-        mixer_indication_coefs_set (Id, plci);
-        break;
-      case UDATA_INDICATION_XCONNECT_FROM:
-        mixer_indication_xconnect_from (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
-        break;
-      case UDATA_INDICATION_XCONNECT_TO:
-        mixer_indication_xconnect_to (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
-        break;
-
-
-      case LEC_UDATA_INDICATION_DISABLE_DETECT:
-        ec_indication (Id, plci, plci->RData[0].P, plci->RData[0].PLength);
-        break;
-
-
-
-      default:
-        break;
-      }
-    }
-    else
-  {
-      if ((plci->RData[0].PLength != 0)
-     && ((plci->B2_prot == B2_V120_ASYNC)
-      || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
-      || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
-    {
-
-      sendf(plci->appl,_DATA_B3_I,Id,0,
-            "dwww",
-            plci->RData[1].P,
-              (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength,
-            plci->RNum,
-            plci->RFlags);
-
-    }
-    else
-    {
-
-      sendf(plci->appl,_DATA_B3_I,Id,0,
-            "dwww",
-            plci->RData[0].P,
-            plci->RData[0].PLength,
-            plci->RNum,
-            plci->RFlags);
-
-    }
-    }
-    return;
-  }
-
-  fax_feature_bits = 0;
-  if((plci->NL.Ind &0x0f)==N_CONNECT ||
-     (plci->NL.Ind &0x0f)==N_CONNECT_ACK ||
-     (plci->NL.Ind &0x0f)==N_DISC ||
-     (plci->NL.Ind &0x0f)==N_EDATA ||
-     (plci->NL.Ind &0x0f)==N_DISC_ACK)
-  {
-    info = 0;
-    plci->ncpi_buffer[0] = 0;
-    switch (plci->B3_prot) {
-    case  0: /*XPARENT*/
-    case  1: /*T.90 NL*/
-      break;    /* no network control protocol info - jfr */
-    case  2: /*ISO8202*/
-    case  3: /*X25 DCE*/
-      for(i=0; i<plci->NL.RLength; i++) plci->ncpi_buffer[4+i] = plci->NL.RBuffer->P[i];
-      plci->ncpi_buffer[0] = (byte)(i+3);
-      plci->ncpi_buffer[1] = (byte)(plci->NL.Ind &N_D_BIT? 1:0);
-      plci->ncpi_buffer[2] = 0;
-      plci->ncpi_buffer[3] = 0;
-      break;
-    case  4: /*T.30 - FAX*/
-    case  5: /*T.30 - FAX*/
-      if(plci->NL.RLength>=sizeof(T30_INFO))
-      {
-        dbug(1,dprintf("FaxStatus %04x", ((T30_INFO   *)plci->NL.RBuffer->P)->code));
-        len = 9;
-        PUT_WORD(&(plci->ncpi_buffer[1]),((T30_INFO   *)plci->NL.RBuffer->P)->rate_div_2400 * 2400);
-        fax_feature_bits = GET_WORD(&((T30_INFO   *)plci->NL.RBuffer->P)->feature_bits_low);
-        i = (((T30_INFO   *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000;
-        if (plci->B3_prot == 5)
-        {
-          if (!(fax_feature_bits & T30_FEATURE_BIT_ECM))
-            i |= 0x8000; /* This is not an ECM connection */
-          if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING)
-            i |= 0x4000; /* This is a connection with MMR compression */
-          if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING)
-            i |= 0x2000; /* This is a connection with MR compression */
-          if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
-            i |= 0x0004; /* More documents */
-          if (fax_feature_bits & T30_FEATURE_BIT_POLLING)
-            i |= 0x0002; /* Fax-polling indication */
-        }
-        dbug(1,dprintf("FAX Options %04x %04x",fax_feature_bits,i));
-        PUT_WORD(&(plci->ncpi_buffer[3]),i);
-        PUT_WORD(&(plci->ncpi_buffer[5]),((T30_INFO   *)plci->NL.RBuffer->P)->data_format);
-        plci->ncpi_buffer[7] = ((T30_INFO   *)plci->NL.RBuffer->P)->pages_low;
-        plci->ncpi_buffer[8] = ((T30_INFO   *)plci->NL.RBuffer->P)->pages_high;
-        plci->ncpi_buffer[len] = 0;
-        if(((T30_INFO   *)plci->NL.RBuffer->P)->station_id_len)
-        {
-          plci->ncpi_buffer[len] = 20;
-          for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
-            plci->ncpi_buffer[++len] = ((T30_INFO   *)plci->NL.RBuffer->P)->station_id[i];
-        }
-        if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
-        {
-	  if (((T30_INFO   *)plci->NL.RBuffer->P)->code < ARRAY_SIZE(fax_info))
-            info = fax_info[((T30_INFO   *)plci->NL.RBuffer->P)->code];
-          else
-            info = _FAX_PROTOCOL_ERROR;
-        }
-
-        if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
-          & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
-        {
-          i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
-          while (i < plci->NL.RBuffer->length)
-            plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
-        }
-
-        plci->ncpi_buffer[0] = len;
-        fax_feature_bits = GET_WORD(&((T30_INFO   *)plci->NL.RBuffer->P)->feature_bits_low);
-        PUT_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits);
-
-        plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND;
- if (((plci->NL.Ind &0x0f) == N_CONNECT_ACK)
-         || (((plci->NL.Ind &0x0f) == N_CONNECT)
-          && (fax_feature_bits & T30_FEATURE_BIT_POLLING))
-         || (((plci->NL.Ind &0x0f) == N_EDATA)
-          && ((((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK)
-           || (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
-           || (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC))))
- {
-          plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT;
- }
- if (((plci->NL.Ind &0x0f) == N_DISC)
-  || ((plci->NL.Ind &0x0f) == N_DISC_ACK)
-  || (((plci->NL.Ind &0x0f) == N_EDATA)
-   && (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI)))
- {
-          plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
- }
-      }
-      break;
-
-    case B3_RTP:
-      if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
-      {
-        if (plci->NL.RLength != 0)
-        {
-          info = rtp_info[plci->NL.RBuffer->P[0]];
-          plci->ncpi_buffer[0] = plci->NL.RLength - 1;
-          for (i = 1; i < plci->NL.RLength; i++)
-            plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i];
-        }
-      }
-      break;
-
-    }
-    plci->NL.RNR = 2;
-  }
-  switch(plci->NL.Ind &0x0f) {
-  case N_EDATA:
-    if ((plci->B3_prot == 4) || (plci->B3_prot == 5))
-    {
-      dbug(1,dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci],
-        ((T30_INFO   *)plci->NL.RBuffer->P)->code));
-      fax_send_edata_ack = (((T30_INFO   *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG);
-
-      if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
-       && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
-       && (((T30_INFO   *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
-       && (a->ncci_state[ncci] == OUTG_CON_PENDING)
-       && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-       && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
-      {
-        ((T30_INFO   *)(plci->fax_connect_info_buffer))->code = ((T30_INFO   *)plci->NL.RBuffer->P)->code;
-        sendf(plci->appl,_MANUFACTURER_I,Id,0,"dwbS",_DI_MANU_ID,_DI_NEGOTIATE_B3,
-          (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer);
-        plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT;
- if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)
-   fax_send_edata_ack = false;
-      }
-
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
-      {
-        switch (((T30_INFO   *)plci->NL.RBuffer->P)->code)
-        {
-        case EDATA_T30_DIS:
-          if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
-           && !(GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING)
-           && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-           && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-          {
-            a->ncci_state[ncci] = INC_ACT_PENDING;
-            if (plci->B3_prot == 4)
-              sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-            else
-              sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
-            plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-          }
-          break;
-
-        case EDATA_T30_TRAIN_OK:
-          if ((a->ncci_state[ncci] == INC_ACT_PENDING)
-           && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-           && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-          {
-            if (plci->B3_prot == 4)
-              sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-            else
-              sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
-            plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-          }
-          break;
-
-        case EDATA_T30_EOP_CAPI:
-          if (a->ncci_state[ncci] == CONNECTED)
-          {
-            sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",GOOD,plci->ncpi_buffer);
-            a->ncci_state[ncci] = INC_DIS_PENDING;
-            plci->ncpi_state = 0;
-     fax_send_edata_ack = false;
-          }
-          break;
-        }
-      }
-      else
-      {
-        switch (((T30_INFO   *)plci->NL.RBuffer->P)->code)
-        {
-        case EDATA_T30_TRAIN_OK:
-          if ((a->ncci_state[ncci] == INC_ACT_PENDING)
-           && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-           && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-          {
-            if (plci->B3_prot == 4)
-              sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-            else
-              sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
-            plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-          }
-          break;
-        }
-      }
-      if (fax_send_edata_ack)
-      {
-        ((T30_INFO   *)(plci->fax_connect_info_buffer))->code = ((T30_INFO   *)plci->NL.RBuffer->P)->code;
- plci->fax_edata_ack_length = 1;
-        start_internal_command (Id, plci, fax_edata_ack_command);
-      }
-    }
-    else
-    {
-      dbug(1,dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci]));
-    }
-    break;
-  case N_CONNECT:
-    if (!a->ch_ncci[ch])
-    {
-      ncci = get_ncci (plci, ch, 0);
-      Id = (Id & 0xffff) | (((dword) ncci) << 16);
-    }
-    dbug(1,dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d",
-      ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State));
-
-    msg = _CONNECT_B3_I;
-    if (a->ncci_state[ncci] == IDLE)
-      plci->channels++;
-    else if (plci->B3_prot == 1)
-      msg = _CONNECT_B3_T90_ACTIVE_I;
-
-    a->ncci_state[ncci] = INC_CON_PENDING;
-    if(plci->B3_prot == 4)
-      sendf(plci->appl,msg,Id,0,"s","");
-    else
-      sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
-    break;
-  case N_CONNECT_ACK:
-    dbug(1,dprintf("N_connect_Ack"));
-    if (plci->internal_command_queue[0]
-     && ((plci->adjust_b_state == ADJUST_B_CONNECT_2)
-      || (plci->adjust_b_state == ADJUST_B_CONNECT_3)
-      || (plci->adjust_b_state == ADJUST_B_CONNECT_4)))
-    {
-      (*(plci->internal_command_queue[0]))(Id, plci, 0);
-      if (!plci->internal_command)
-        next_internal_command (Id, plci);
-      break;
-    }
-    msg = _CONNECT_B3_ACTIVE_I;
-    if (plci->B3_prot == 1)
-    {
-      if (a->ncci_state[ncci] != OUTG_CON_PENDING)
-        msg = _CONNECT_B3_T90_ACTIVE_I;
-      a->ncci_state[ncci] = INC_ACT_PENDING;
-      sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
-    }
-    else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
-    {
-      if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
-       && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-       && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-      {
-        a->ncci_state[ncci] = INC_ACT_PENDING;
-        if (plci->B3_prot == 4)
-          sendf(plci->appl,msg,Id,0,"s","");
-        else
-          sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
-        plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-      }
-    }
-    else
-    {
-      a->ncci_state[ncci] = INC_ACT_PENDING;
-      sendf(plci->appl,msg,Id,0,"S",plci->ncpi_buffer);
-    }
-    if (plci->adjust_b_restore)
-    {
-      plci->adjust_b_restore = false;
-      start_internal_command (Id, plci, adjust_b_restore);
-    }
-    break;
-  case N_DISC:
-  case N_DISC_ACK:
-    if (plci->internal_command_queue[0]
-     && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1)
-      || (plci->internal_command == FAX_DISCONNECT_COMMAND_2)
-      || (plci->internal_command == FAX_DISCONNECT_COMMAND_3)))
-    {
-      (*(plci->internal_command_queue[0]))(Id, plci, 0);
-      if (!plci->internal_command)
-        next_internal_command (Id, plci);
-    }
-    ncci_state = a->ncci_state[ncci];
-    ncci_remove (plci, ncci, false);
-
-        /* with N_DISC or N_DISC_ACK the IDI frees the respective   */
-        /* channel, so we cannot store the state in ncci_state! The */
-        /* information which channel we received a N_DISC is thus   */
-        /* stored in the inc_dis_ncci_table buffer.                 */
-    for(i=0; plci->inc_dis_ncci_table[i]; i++);
-    plci->inc_dis_ncci_table[i] = (byte) ncci;
-
-      /* need a connect_b3_ind before a disconnect_b3_ind with FAX */
-    if (!plci->channels
-     && (plci->B1_resource == 16)
-     && (plci->State <= CONNECTED))
-    {
-      len = 9;
-      i = ((T30_INFO   *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400;
-      PUT_WORD (&plci->ncpi_buffer[1], i);
-      PUT_WORD (&plci->ncpi_buffer[3], 0);
-      i = ((T30_INFO   *)plci->fax_connect_info_buffer)->data_format;
-      PUT_WORD (&plci->ncpi_buffer[5], i);
-      PUT_WORD (&plci->ncpi_buffer[7], 0);
-      plci->ncpi_buffer[len] = 0;
-      plci->ncpi_buffer[0] = len;
-      if(plci->B3_prot == 4)
-        sendf(plci->appl,_CONNECT_B3_I,Id,0,"s","");
-      else
-      {
-
-        if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
-          & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
-        {
-          plci->ncpi_buffer[++len] = 0;
-          plci->ncpi_buffer[++len] = 0;
-          plci->ncpi_buffer[++len] = 0;
-          plci->ncpi_buffer[0] = len;
-        }
-
-        sendf(plci->appl,_CONNECT_B3_I,Id,0,"S",plci->ncpi_buffer);
-      }
-      sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",info,plci->ncpi_buffer);
-      plci->ncpi_state = 0;
-      sig_req(plci,HANGUP,0);
-      send_req(plci);
-      plci->State = OUTG_DIS_PENDING;
-      /* disc here */
-    }
-    else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
-     && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
-     && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE)))
-    {
-      if (ncci_state == IDLE)
-      {
-        if (plci->channels)
-          plci->channels--;
-        if((plci->State==IDLE || plci->State==SUSPENDING) && !plci->channels){
-          if(plci->State == SUSPENDING){
-            sendf(plci->appl,
-                  _FACILITY_I,
-                  Id & 0xffffL,
-                  0,
-                  "ws", (word)3, "\x03\x04\x00\x00");
-            sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
-          }
-          plci_remove(plci);
-          plci->State=IDLE;
-        }
-      }
-    }
-    else if (plci->channels)
-    {
-      sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",info,plci->ncpi_buffer);
-      plci->ncpi_state = 0;
-      if ((ncci_state == OUTG_REJ_PENDING)
-       && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)))
-      {
-        sig_req(plci,HANGUP,0);
-        send_req(plci);
-        plci->State = OUTG_DIS_PENDING;
-      }
-    }
-    break;
-  case N_RESET:
-    a->ncci_state[ncci] = INC_RES_PENDING;
-    sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer);
-    break;
-  case N_RESET_ACK:
-    a->ncci_state[ncci] = CONNECTED;
-    sendf(plci->appl,_RESET_B3_I,Id,0,"S",plci->ncpi_buffer);
-    break;
-
-  case N_UDATA:
-    if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
-    {
-      plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
-      plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
-      plci->NL.R = plci->RData;
-      plci->NL.RNum = 1;
-      return;
-    }
-  case N_BDATA:
-  case N_DATA:
-    if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */
-     || (a->ncci_state[ncci] == IDLE)
-     || (a->ncci_state[ncci] == INC_DIS_PENDING))
-    {
-      plci->NL.RNR = 2;
-      break;
-    }
-    if ((a->ncci_state[ncci] != CONNECTED)
-     && (a->ncci_state[ncci] != OUTG_DIS_PENDING)
-     && (a->ncci_state[ncci] != OUTG_REJ_PENDING))
-    {
-      dbug(1,dprintf("flow control"));
-      plci->NL.RNR = 1; /* flow control  */
-      channel_x_off (plci, ch, 0);
-      break;
-    }
-
-    NCCIcode = ncci | (((word)a->Id) << 8);
-
-                /* count all buffers within the Application pool    */
-                /* belonging to the same NCCI. If this is below the */
-                /* number of buffers available per NCCI we accept   */
-                /* this packet, otherwise we reject it              */
-    count = 0;
-    Num = 0xffff;
-    for(i=0; i<APPLptr->MaxBuffer; i++) {
-      if(NCCIcode==APPLptr->DataNCCI[i]) count++;
-      if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i;
-    }
-
-    if(count>=APPLptr->MaxNCCIData || Num==0xffff)
-    {
-      dbug(3,dprintf("Flow-Control"));
-      plci->NL.RNR = 1;
-      if( ++(APPLptr->NCCIDataFlowCtrlTimer)>=
-       (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000))
-      {
-        plci->NL.RNR = 2;
-        dbug(3,dprintf("DiscardData"));
-      } else {
-        channel_x_off (plci, ch, 0);
-      }
-      break;
-    }
-    else
-    {
-      APPLptr->NCCIDataFlowCtrlTimer = 0;
-    }
-
-    plci->RData[0].P = ReceiveBufferGet(APPLptr,Num);
-    if(!plci->RData[0].P) {
-      plci->NL.RNR = 1;
-      channel_x_off (plci, ch, 0);
-      break;
-    }
-
-    APPLptr->DataNCCI[Num] = NCCIcode;
-    APPLptr->DataFlags[Num] = (plci->Id<<8) | (plci->NL.Ind>>4);
-    dbug(3,dprintf("Buffer(%d), Max = %d",Num,APPLptr->MaxBuffer));
-
-    plci->RNum = Num;
-    plci->RFlags = plci->NL.Ind>>4;
-    plci->RData[0].PLength = APPLptr->MaxDataLength;
-    plci->NL.R = plci->RData;
-    if ((plci->NL.RLength != 0)
-     && ((plci->B2_prot == B2_V120_ASYNC)
-      || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
-      || (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
-    {
-      plci->RData[1].P = plci->RData[0].P;
-      plci->RData[1].PLength = plci->RData[0].PLength;
-      plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
-      if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
-        plci->RData[0].PLength = 1;
-      else
-        plci->RData[0].PLength = 2;
-      if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT)
-        plci->RFlags |= 0x0010;
-      if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT))
-        plci->RFlags |= 0x8000;
-      plci->NL.RNum = 2;
-    }
-    else
-    {
-      if((plci->NL.Ind &0x0f)==N_UDATA)
-        plci->RFlags |= 0x0010;
-
-      else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA))
-        plci->RFlags |= 0x0001;
-
-      plci->NL.RNum = 1;
-    }
-    break;
-  case N_DATA_ACK:
-    data_ack (plci, ch);
-    break;
-  default:
-    plci->NL.RNR = 2;
-    break;
-  }
+				if (*data == DSP_UDATA_INDICATION_DCD_ON)
+					plci->ncpi_state |= NCPI_MDM_DCD_ON_RECEIVED;
+				if (*data == DSP_UDATA_INDICATION_CTS_ON)
+					plci->ncpi_state |= NCPI_MDM_CTS_ON_RECEIVED;
+
+				data++;    /* indication code */
+				data += 2; /* timestamp */
+				if ((*data == DSP_CONNECTED_NORM_V18) || (*data == DSP_CONNECTED_NORM_VOWN))
+					ncpi_state &= ~(NCPI_MDM_DCD_ON_RECEIVED | NCPI_MDM_CTS_ON_RECEIVED);
+				data++;    /* connected norm */
+				conn_opt = GET_WORD(data);
+				data += 2; /* connected options */
+
+				PUT_WORD(&(plci->ncpi_buffer[1]), (word)(GET_DWORD(data) & 0x0000FFFF));
+
+				if (conn_opt & DSP_CONNECTED_OPTION_MASK_V42)
+				{
+					ncpi_opt |= MDM_NCPI_ECM_V42;
+				}
+				else if (conn_opt & DSP_CONNECTED_OPTION_MASK_MNP)
+				{
+					ncpi_opt |= MDM_NCPI_ECM_MNP;
+				}
+				else
+				{
+					ncpi_opt |= MDM_NCPI_TRANSPARENT;
+				}
+				if (conn_opt & DSP_CONNECTED_OPTION_MASK_COMPRESSION)
+				{
+					ncpi_opt |= MDM_NCPI_COMPRESSED;
+				}
+				PUT_WORD(&(plci->ncpi_buffer[3]), ncpi_opt);
+				plci->ncpi_buffer[0] = 4;
+
+				plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND | NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
+			}
+		}
+		if (plci->B3_prot == 7)
+		{
+			if (((a->ncci_state[ncci] == INC_ACT_PENDING) || (a->ncci_state[ncci] == OUTG_CON_PENDING))
+			    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+			    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+			{
+				a->ncci_state[ncci] = INC_ACT_PENDING;
+				sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
+				plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+			}
+		}
+
+		if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
+		      & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
+		    || !(ncpi_state & NCPI_MDM_DCD_ON_RECEIVED)
+		    || !(ncpi_state & NCPI_MDM_CTS_ON_RECEIVED))
+
+		{
+			plci->NL.RNR = 2;
+			return;
+		}
+	}
+
+	if (plci->NL.complete == 2)
+	{
+		if (((plci->NL.Ind & 0x0f) == N_UDATA)
+		    && !(udata_forwarding_table[plci->RData[0].P[0] >> 5] & (1L << (plci->RData[0].P[0] & 0x1f))))
+		{
+			switch (plci->RData[0].P[0])
+			{
+
+			case DTMF_UDATA_INDICATION_FAX_CALLING_TONE:
+				if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
+					sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01X");
+				break;
+			case DTMF_UDATA_INDICATION_ANSWER_TONE:
+				if (plci->dtmf_rec_active & DTMF_LISTEN_ACTIVE_FLAG)
+					sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", SELECTOR_DTMF, "\x01Y");
+				break;
+			case DTMF_UDATA_INDICATION_DIGITS_RECEIVED:
+				dtmf_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
+				break;
+			case DTMF_UDATA_INDICATION_DIGITS_SENT:
+				dtmf_confirmation(Id, plci);
+				break;
+
+
+			case UDATA_INDICATION_MIXER_TAP_DATA:
+				capidtmf_recv_process_block(&(plci->capidtmf_state), plci->RData[0].P + 1, (word)(plci->RData[0].PLength - 1));
+				i = capidtmf_indication(&(plci->capidtmf_state), dtmf_code_buffer + 1);
+				if (i != 0)
+				{
+					dtmf_code_buffer[0] = DTMF_UDATA_INDICATION_DIGITS_RECEIVED;
+					dtmf_indication(Id, plci, dtmf_code_buffer, (word)(i + 1));
+				}
+				break;
+
+
+			case UDATA_INDICATION_MIXER_COEFS_SET:
+				mixer_indication_coefs_set(Id, plci);
+				break;
+			case UDATA_INDICATION_XCONNECT_FROM:
+				mixer_indication_xconnect_from(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
+				break;
+			case UDATA_INDICATION_XCONNECT_TO:
+				mixer_indication_xconnect_to(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
+				break;
+
+
+			case LEC_UDATA_INDICATION_DISABLE_DETECT:
+				ec_indication(Id, plci, plci->RData[0].P, plci->RData[0].PLength);
+				break;
+
+
+
+			default:
+				break;
+			}
+		}
+		else
+		{
+			if ((plci->RData[0].PLength != 0)
+			    && ((plci->B2_prot == B2_V120_ASYNC)
+				|| (plci->B2_prot == B2_V120_ASYNC_V42BIS)
+				|| (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
+			{
+
+				sendf(plci->appl, _DATA_B3_I, Id, 0,
+				      "dwww",
+				      plci->RData[1].P,
+				      (plci->NL.RNum < 2) ? 0 : plci->RData[1].PLength,
+				      plci->RNum,
+				      plci->RFlags);
+
+			}
+			else
+			{
+
+				sendf(plci->appl, _DATA_B3_I, Id, 0,
+				      "dwww",
+				      plci->RData[0].P,
+				      plci->RData[0].PLength,
+				      plci->RNum,
+				      plci->RFlags);
+
+			}
+		}
+		return;
+	}
+
+	fax_feature_bits = 0;
+	if ((plci->NL.Ind & 0x0f) == N_CONNECT ||
+	    (plci->NL.Ind & 0x0f) == N_CONNECT_ACK ||
+	    (plci->NL.Ind & 0x0f) == N_DISC ||
+	    (plci->NL.Ind & 0x0f) == N_EDATA ||
+	    (plci->NL.Ind & 0x0f) == N_DISC_ACK)
+	{
+		info = 0;
+		plci->ncpi_buffer[0] = 0;
+		switch (plci->B3_prot) {
+		case  0: /*XPARENT*/
+		case  1: /*T.90 NL*/
+			break;    /* no network control protocol info - jfr */
+		case  2: /*ISO8202*/
+		case  3: /*X25 DCE*/
+			for (i = 0; i < plci->NL.RLength; i++) plci->ncpi_buffer[4 + i] = plci->NL.RBuffer->P[i];
+			plci->ncpi_buffer[0] = (byte)(i + 3);
+			plci->ncpi_buffer[1] = (byte)(plci->NL.Ind & N_D_BIT ? 1 : 0);
+			plci->ncpi_buffer[2] = 0;
+			plci->ncpi_buffer[3] = 0;
+			break;
+		case  4: /*T.30 - FAX*/
+		case  5: /*T.30 - FAX*/
+			if (plci->NL.RLength >= sizeof(T30_INFO))
+			{
+				dbug(1, dprintf("FaxStatus %04x", ((T30_INFO *)plci->NL.RBuffer->P)->code));
+				len = 9;
+				PUT_WORD(&(plci->ncpi_buffer[1]), ((T30_INFO *)plci->NL.RBuffer->P)->rate_div_2400 * 2400);
+				fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low);
+				i = (((T30_INFO *)plci->NL.RBuffer->P)->resolution & T30_RESOLUTION_R8_0770_OR_200) ? 0x0001 : 0x0000;
+				if (plci->B3_prot == 5)
+				{
+					if (!(fax_feature_bits & T30_FEATURE_BIT_ECM))
+						i |= 0x8000; /* This is not an ECM connection */
+					if (fax_feature_bits & T30_FEATURE_BIT_T6_CODING)
+						i |= 0x4000; /* This is a connection with MMR compression */
+					if (fax_feature_bits & T30_FEATURE_BIT_2D_CODING)
+						i |= 0x2000; /* This is a connection with MR compression */
+					if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
+						i |= 0x0004; /* More documents */
+					if (fax_feature_bits & T30_FEATURE_BIT_POLLING)
+						i |= 0x0002; /* Fax-polling indication */
+				}
+				dbug(1, dprintf("FAX Options %04x %04x", fax_feature_bits, i));
+				PUT_WORD(&(plci->ncpi_buffer[3]), i);
+				PUT_WORD(&(plci->ncpi_buffer[5]), ((T30_INFO *)plci->NL.RBuffer->P)->data_format);
+				plci->ncpi_buffer[7] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_low;
+				plci->ncpi_buffer[8] = ((T30_INFO *)plci->NL.RBuffer->P)->pages_high;
+				plci->ncpi_buffer[len] = 0;
+				if (((T30_INFO *)plci->NL.RBuffer->P)->station_id_len)
+				{
+					plci->ncpi_buffer[len] = 20;
+					for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
+						plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i];
+				}
+				if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
+				{
+					if (((T30_INFO *)plci->NL.RBuffer->P)->code < ARRAY_SIZE(fax_info))
+						info = fax_info[((T30_INFO *)plci->NL.RBuffer->P)->code];
+					else
+						info = _FAX_PROTOCOL_ERROR;
+				}
+
+				if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
+				    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
+				{
+					i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
+					while (i < plci->NL.RBuffer->length)
+						plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
+				}
+
+				plci->ncpi_buffer[0] = len;
+				fax_feature_bits = GET_WORD(&((T30_INFO *)plci->NL.RBuffer->P)->feature_bits_low);
+				PUT_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->feature_bits_low, fax_feature_bits);
+
+				plci->ncpi_state |= NCPI_VALID_CONNECT_B3_IND;
+				if (((plci->NL.Ind & 0x0f) == N_CONNECT_ACK)
+				    || (((plci->NL.Ind & 0x0f) == N_CONNECT)
+					&& (fax_feature_bits & T30_FEATURE_BIT_POLLING))
+				    || (((plci->NL.Ind & 0x0f) == N_EDATA)
+					&& ((((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_TRAIN_OK)
+					    || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
+					    || (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DTC))))
+				{
+					plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT;
+				}
+				if (((plci->NL.Ind & 0x0f) == N_DISC)
+				    || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)
+				    || (((plci->NL.Ind & 0x0f) == N_EDATA)
+					&& (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_EOP_CAPI)))
+				{
+					plci->ncpi_state |= NCPI_VALID_CONNECT_B3_ACT | NCPI_VALID_DISC_B3_IND;
+				}
+			}
+			break;
+
+		case B3_RTP:
+			if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
+			{
+				if (plci->NL.RLength != 0)
+				{
+					info = rtp_info[plci->NL.RBuffer->P[0]];
+					plci->ncpi_buffer[0] = plci->NL.RLength - 1;
+					for (i = 1; i < plci->NL.RLength; i++)
+						plci->ncpi_buffer[i] = plci->NL.RBuffer->P[i];
+				}
+			}
+			break;
+
+		}
+		plci->NL.RNR = 2;
+	}
+	switch (plci->NL.Ind & 0x0f) {
+	case N_EDATA:
+		if ((plci->B3_prot == 4) || (plci->B3_prot == 5))
+		{
+			dbug(1, dprintf("EDATA ncci=0x%x state=%d code=%02x", ncci, a->ncci_state[ncci],
+					((T30_INFO *)plci->NL.RBuffer->P)->code));
+			fax_send_edata_ack = (((T30_INFO *)(plci->fax_connect_info_buffer))->operating_mode == T30_OPERATING_MODE_CAPI_NEG);
+
+			if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
+			    && (plci->nsf_control_bits & (T30_NSF_CONTROL_BIT_NEGOTIATE_IND | T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
+			    && (((T30_INFO *)plci->NL.RBuffer->P)->code == EDATA_T30_DIS)
+			    && (a->ncci_state[ncci] == OUTG_CON_PENDING)
+			    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+			    && !(plci->ncpi_state & NCPI_NEGOTIATE_B3_SENT))
+			{
+				((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code;
+				sendf(plci->appl, _MANUFACTURER_I, Id, 0, "dwbS", _DI_MANU_ID, _DI_NEGOTIATE_B3,
+				      (byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer);
+				plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT;
+				if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)
+					fax_send_edata_ack = false;
+			}
+
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
+			{
+				switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
+				{
+				case EDATA_T30_DIS:
+					if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
+					    && !(GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) & T30_CONTROL_BIT_REQUEST_POLLING)
+					    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+					    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+					{
+						a->ncci_state[ncci] = INC_ACT_PENDING;
+						if (plci->B3_prot == 4)
+							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+						else
+							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
+						plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+					}
+					break;
+
+				case EDATA_T30_TRAIN_OK:
+					if ((a->ncci_state[ncci] == INC_ACT_PENDING)
+					    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+					    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+					{
+						if (plci->B3_prot == 4)
+							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+						else
+							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
+						plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+					}
+					break;
+
+				case EDATA_T30_EOP_CAPI:
+					if (a->ncci_state[ncci] == CONNECTED)
+					{
+						sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", GOOD, plci->ncpi_buffer);
+						a->ncci_state[ncci] = INC_DIS_PENDING;
+						plci->ncpi_state = 0;
+						fax_send_edata_ack = false;
+					}
+					break;
+				}
+			}
+			else
+			{
+				switch (((T30_INFO *)plci->NL.RBuffer->P)->code)
+				{
+				case EDATA_T30_TRAIN_OK:
+					if ((a->ncci_state[ncci] == INC_ACT_PENDING)
+					    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+					    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+					{
+						if (plci->B3_prot == 4)
+							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+						else
+							sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
+						plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+					}
+					break;
+				}
+			}
+			if (fax_send_edata_ack)
+			{
+				((T30_INFO *)(plci->fax_connect_info_buffer))->code = ((T30_INFO *)plci->NL.RBuffer->P)->code;
+				plci->fax_edata_ack_length = 1;
+				start_internal_command(Id, plci, fax_edata_ack_command);
+			}
+		}
+		else
+		{
+			dbug(1, dprintf("EDATA ncci=0x%x state=%d", ncci, a->ncci_state[ncci]));
+		}
+		break;
+	case N_CONNECT:
+		if (!a->ch_ncci[ch])
+		{
+			ncci = get_ncci(plci, ch, 0);
+			Id = (Id & 0xffff) | (((dword) ncci) << 16);
+		}
+		dbug(1, dprintf("N_CONNECT: ch=%d state=%d plci=%lx plci_Id=%lx plci_State=%d",
+				ch, a->ncci_state[ncci], a->ncci_plci[ncci], plci->Id, plci->State));
+
+		msg = _CONNECT_B3_I;
+		if (a->ncci_state[ncci] == IDLE)
+			plci->channels++;
+		else if (plci->B3_prot == 1)
+			msg = _CONNECT_B3_T90_ACTIVE_I;
+
+		a->ncci_state[ncci] = INC_CON_PENDING;
+		if (plci->B3_prot == 4)
+			sendf(plci->appl, msg, Id, 0, "s", "");
+		else
+			sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
+		break;
+	case N_CONNECT_ACK:
+		dbug(1, dprintf("N_connect_Ack"));
+		if (plci->internal_command_queue[0]
+		    && ((plci->adjust_b_state == ADJUST_B_CONNECT_2)
+			|| (plci->adjust_b_state == ADJUST_B_CONNECT_3)
+			|| (plci->adjust_b_state == ADJUST_B_CONNECT_4)))
+		{
+			(*(plci->internal_command_queue[0]))(Id, plci, 0);
+			if (!plci->internal_command)
+				next_internal_command(Id, plci);
+			break;
+		}
+		msg = _CONNECT_B3_ACTIVE_I;
+		if (plci->B3_prot == 1)
+		{
+			if (a->ncci_state[ncci] != OUTG_CON_PENDING)
+				msg = _CONNECT_B3_T90_ACTIVE_I;
+			a->ncci_state[ncci] = INC_ACT_PENDING;
+			sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
+		}
+		else if ((plci->B3_prot == 4) || (plci->B3_prot == 5) || (plci->B3_prot == 7))
+		{
+			if ((a->ncci_state[ncci] == OUTG_CON_PENDING)
+			    && (plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+			    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+			{
+				a->ncci_state[ncci] = INC_ACT_PENDING;
+				if (plci->B3_prot == 4)
+					sendf(plci->appl, msg, Id, 0, "s", "");
+				else
+					sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
+				plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+			}
+		}
+		else
+		{
+			a->ncci_state[ncci] = INC_ACT_PENDING;
+			sendf(plci->appl, msg, Id, 0, "S", plci->ncpi_buffer);
+		}
+		if (plci->adjust_b_restore)
+		{
+			plci->adjust_b_restore = false;
+			start_internal_command(Id, plci, adjust_b_restore);
+		}
+		break;
+	case N_DISC:
+	case N_DISC_ACK:
+		if (plci->internal_command_queue[0]
+		    && ((plci->internal_command == FAX_DISCONNECT_COMMAND_1)
+			|| (plci->internal_command == FAX_DISCONNECT_COMMAND_2)
+			|| (plci->internal_command == FAX_DISCONNECT_COMMAND_3)))
+		{
+			(*(plci->internal_command_queue[0]))(Id, plci, 0);
+			if (!plci->internal_command)
+				next_internal_command(Id, plci);
+		}
+		ncci_state = a->ncci_state[ncci];
+		ncci_remove(plci, ncci, false);
+
+		/* with N_DISC or N_DISC_ACK the IDI frees the respective   */
+		/* channel, so we cannot store the state in ncci_state! The */
+		/* information which channel we received a N_DISC is thus   */
+		/* stored in the inc_dis_ncci_table buffer.                 */
+		for (i = 0; plci->inc_dis_ncci_table[i]; i++);
+		plci->inc_dis_ncci_table[i] = (byte) ncci;
+
+		/* need a connect_b3_ind before a disconnect_b3_ind with FAX */
+		if (!plci->channels
+		    && (plci->B1_resource == 16)
+		    && (plci->State <= CONNECTED))
+		{
+			len = 9;
+			i = ((T30_INFO *)plci->fax_connect_info_buffer)->rate_div_2400 * 2400;
+			PUT_WORD(&plci->ncpi_buffer[1], i);
+			PUT_WORD(&plci->ncpi_buffer[3], 0);
+			i = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format;
+			PUT_WORD(&plci->ncpi_buffer[5], i);
+			PUT_WORD(&plci->ncpi_buffer[7], 0);
+			plci->ncpi_buffer[len] = 0;
+			plci->ncpi_buffer[0] = len;
+			if (plci->B3_prot == 4)
+				sendf(plci->appl, _CONNECT_B3_I, Id, 0, "s", "");
+			else
+			{
+
+				if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id - 1])
+				    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
+				{
+					plci->ncpi_buffer[++len] = 0;
+					plci->ncpi_buffer[++len] = 0;
+					plci->ncpi_buffer[++len] = 0;
+					plci->ncpi_buffer[0] = len;
+				}
+
+				sendf(plci->appl, _CONNECT_B3_I, Id, 0, "S", plci->ncpi_buffer);
+			}
+			sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer);
+			plci->ncpi_state = 0;
+			sig_req(plci, HANGUP, 0);
+			send_req(plci);
+			plci->State = OUTG_DIS_PENDING;
+			/* disc here */
+		}
+		else if ((a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
+			 && ((plci->B3_prot == 4) || (plci->B3_prot == 5))
+			 && ((ncci_state == INC_DIS_PENDING) || (ncci_state == IDLE)))
+		{
+			if (ncci_state == IDLE)
+			{
+				if (plci->channels)
+					plci->channels--;
+				if ((plci->State == IDLE || plci->State == SUSPENDING) && !plci->channels) {
+					if (plci->State == SUSPENDING) {
+						sendf(plci->appl,
+						      _FACILITY_I,
+						      Id & 0xffffL,
+						      0,
+						      "ws", (word)3, "\x03\x04\x00\x00");
+						sendf(plci->appl, _DISCONNECT_I, Id & 0xffffL, 0, "w", 0);
+					}
+					plci_remove(plci);
+					plci->State = IDLE;
+				}
+			}
+		}
+		else if (plci->channels)
+		{
+			sendf(plci->appl, _DISCONNECT_B3_I, Id, 0, "wS", info, plci->ncpi_buffer);
+			plci->ncpi_state = 0;
+			if ((ncci_state == OUTG_REJ_PENDING)
+			    && ((plci->B3_prot != B3_T90NL) && (plci->B3_prot != B3_ISO8208) && (plci->B3_prot != B3_X25_DCE)))
+			{
+				sig_req(plci, HANGUP, 0);
+				send_req(plci);
+				plci->State = OUTG_DIS_PENDING;
+			}
+		}
+		break;
+	case N_RESET:
+		a->ncci_state[ncci] = INC_RES_PENDING;
+		sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer);
+		break;
+	case N_RESET_ACK:
+		a->ncci_state[ncci] = CONNECTED;
+		sendf(plci->appl, _RESET_B3_I, Id, 0, "S", plci->ncpi_buffer);
+		break;
+
+	case N_UDATA:
+		if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
+		{
+			plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
+			plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
+			plci->NL.R = plci->RData;
+			plci->NL.RNum = 1;
+			return;
+		}
+	case N_BDATA:
+	case N_DATA:
+		if (((a->ncci_state[ncci] != CONNECTED) && (plci->B2_prot == 1)) /* transparent */
+		    || (a->ncci_state[ncci] == IDLE)
+		    || (a->ncci_state[ncci] == INC_DIS_PENDING))
+		{
+			plci->NL.RNR = 2;
+			break;
+		}
+		if ((a->ncci_state[ncci] != CONNECTED)
+		    && (a->ncci_state[ncci] != OUTG_DIS_PENDING)
+		    && (a->ncci_state[ncci] != OUTG_REJ_PENDING))
+		{
+			dbug(1, dprintf("flow control"));
+			plci->NL.RNR = 1; /* flow control  */
+			channel_x_off(plci, ch, 0);
+			break;
+		}
+
+		NCCIcode = ncci | (((word)a->Id) << 8);
+
+		/* count all buffers within the Application pool    */
+		/* belonging to the same NCCI. If this is below the */
+		/* number of buffers available per NCCI we accept   */
+		/* this packet, otherwise we reject it              */
+		count = 0;
+		Num = 0xffff;
+		for (i = 0; i < APPLptr->MaxBuffer; i++) {
+			if (NCCIcode == APPLptr->DataNCCI[i]) count++;
+			if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i;
+		}
+
+		if (count >= APPLptr->MaxNCCIData || Num == 0xffff)
+		{
+			dbug(3, dprintf("Flow-Control"));
+			plci->NL.RNR = 1;
+			if (++(APPLptr->NCCIDataFlowCtrlTimer) >=
+			    (word)((a->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL) ? 40 : 2000))
+			{
+				plci->NL.RNR = 2;
+				dbug(3, dprintf("DiscardData"));
+			} else {
+				channel_x_off(plci, ch, 0);
+			}
+			break;
+		}
+		else
+		{
+			APPLptr->NCCIDataFlowCtrlTimer = 0;
+		}
+
+		plci->RData[0].P = ReceiveBufferGet(APPLptr, Num);
+		if (!plci->RData[0].P) {
+			plci->NL.RNR = 1;
+			channel_x_off(plci, ch, 0);
+			break;
+		}
+
+		APPLptr->DataNCCI[Num] = NCCIcode;
+		APPLptr->DataFlags[Num] = (plci->Id << 8) | (plci->NL.Ind >> 4);
+		dbug(3, dprintf("Buffer(%d), Max = %d", Num, APPLptr->MaxBuffer));
+
+		plci->RNum = Num;
+		plci->RFlags = plci->NL.Ind >> 4;
+		plci->RData[0].PLength = APPLptr->MaxDataLength;
+		plci->NL.R = plci->RData;
+		if ((plci->NL.RLength != 0)
+		    && ((plci->B2_prot == B2_V120_ASYNC)
+			|| (plci->B2_prot == B2_V120_ASYNC_V42BIS)
+			|| (plci->B2_prot == B2_V120_BIT_TRANSPARENT)))
+		{
+			plci->RData[1].P = plci->RData[0].P;
+			plci->RData[1].PLength = plci->RData[0].PLength;
+			plci->RData[0].P = v120_header_buffer + (-((unsigned long)v120_header_buffer) & 3);
+			if ((plci->NL.RBuffer->P[0] & V120_HEADER_EXTEND_BIT) || (plci->NL.RLength == 1))
+				plci->RData[0].PLength = 1;
+			else
+				plci->RData[0].PLength = 2;
+			if (plci->NL.RBuffer->P[0] & V120_HEADER_BREAK_BIT)
+				plci->RFlags |= 0x0010;
+			if (plci->NL.RBuffer->P[0] & (V120_HEADER_C1_BIT | V120_HEADER_C2_BIT))
+				plci->RFlags |= 0x8000;
+			plci->NL.RNum = 2;
+		}
+		else
+		{
+			if ((plci->NL.Ind & 0x0f) == N_UDATA)
+				plci->RFlags |= 0x0010;
+
+			else if ((plci->B3_prot == B3_RTP) && ((plci->NL.Ind & 0x0f) == N_BDATA))
+				plci->RFlags |= 0x0001;
+
+			plci->NL.RNum = 1;
+		}
+		break;
+	case N_DATA_ACK:
+		data_ack(plci, ch);
+		break;
+	default:
+		plci->NL.RNR = 2;
+		break;
+	}
 }
 
 /*------------------------------------------------------------------*/
-/* find a free PLCI                                                 */
+/* find a free PLCI */
 /*------------------------------------------------------------------*/
 
 static word get_plci(DIVA_CAPI_ADAPTER *a)
 {
-  word i,j;
-  PLCI   * plci;
-
-  dump_plcis (a);
-  for(i=0;i<a->max_plci && a->plci[i].Id;i++);
-  if(i==a->max_plci) {
-    dbug(1,dprintf("get_plci: out of PLCIs"));
-    return 0;
-  }
-  plci = &a->plci[i];
-  plci->Id = (byte)(i+1);
-
-  plci->Sig.Id = 0;
-  plci->NL.Id = 0;
-  plci->sig_req = 0;
-  plci->nl_req = 0;
-
-  plci->appl = NULL;
-  plci->relatedPTYPLCI = NULL;
-  plci->State = IDLE;
-  plci->SuppState = IDLE;
-  plci->channels = 0;
-  plci->tel = 0;
-  plci->B1_resource = 0;
-  plci->B2_prot = 0;
-  plci->B3_prot = 0;
-
-  plci->command = 0;
-  plci->m_command = 0;
-  init_internal_command_queue (plci);
-  plci->number = 0;
-  plci->req_in_start = 0;
-  plci->req_in = 0;
-  plci->req_out = 0;
-  plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
-  plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
-  plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
-
-  plci->data_sent = false;
-  plci->send_disc = 0;
-  plci->sig_global_req = 0;
-  plci->sig_remove_id = 0;
-  plci->nl_global_req = 0;
-  plci->nl_remove_id = 0;
-  plci->adv_nl = 0;
-  plci->manufacturer = false;
-  plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
-  plci->spoofed_msg = 0;
-  plci->ptyState = 0;
-  plci->cr_enquiry = false;
-  plci->hangup_flow_ctrl_timer = 0;
-
-  plci->ncci_ring_list = 0;
-  for(j=0;j<MAX_CHANNELS_PER_PLCI;j++) plci->inc_dis_ncci_table[j] = 0;
-  clear_c_ind_mask (plci);
-  set_group_ind_mask (plci);
-  plci->fax_connect_info_length = 0;
-  plci->nsf_control_bits = 0;
-  plci->ncpi_state = 0x00;
-  plci->ncpi_buffer[0] = 0;
-
-  plci->requested_options_conn = 0;
-  plci->requested_options = 0;
-  plci->notifiedcall = 0;
-  plci->vswitchstate = 0;
-  plci->vsprot = 0;
-  plci->vsprotdialect = 0;
-  init_b1_config (plci);
-  dbug(1,dprintf("get_plci(%x)",plci->Id));
-  return i+1;
+	word i, j;
+	PLCI *plci;
+
+	dump_plcis(a);
+	for (i = 0; i < a->max_plci && a->plci[i].Id; i++);
+	if (i == a->max_plci) {
+		dbug(1, dprintf("get_plci: out of PLCIs"));
+		return 0;
+	}
+	plci = &a->plci[i];
+	plci->Id = (byte)(i + 1);
+
+	plci->Sig.Id = 0;
+	plci->NL.Id = 0;
+	plci->sig_req = 0;
+	plci->nl_req = 0;
+
+	plci->appl = NULL;
+	plci->relatedPTYPLCI = NULL;
+	plci->State = IDLE;
+	plci->SuppState = IDLE;
+	plci->channels = 0;
+	plci->tel = 0;
+	plci->B1_resource = 0;
+	plci->B2_prot = 0;
+	plci->B3_prot = 0;
+
+	plci->command = 0;
+	plci->m_command = 0;
+	init_internal_command_queue(plci);
+	plci->number = 0;
+	plci->req_in_start = 0;
+	plci->req_in = 0;
+	plci->req_out = 0;
+	plci->msg_in_write_pos = MSG_IN_QUEUE_SIZE;
+	plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
+	plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
+
+	plci->data_sent = false;
+	plci->send_disc = 0;
+	plci->sig_global_req = 0;
+	plci->sig_remove_id = 0;
+	plci->nl_global_req = 0;
+	plci->nl_remove_id = 0;
+	plci->adv_nl = 0;
+	plci->manufacturer = false;
+	plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
+	plci->spoofed_msg = 0;
+	plci->ptyState = 0;
+	plci->cr_enquiry = false;
+	plci->hangup_flow_ctrl_timer = 0;
+
+	plci->ncci_ring_list = 0;
+	for (j = 0; j < MAX_CHANNELS_PER_PLCI; j++) plci->inc_dis_ncci_table[j] = 0;
+	clear_c_ind_mask(plci);
+	set_group_ind_mask(plci);
+	plci->fax_connect_info_length = 0;
+	plci->nsf_control_bits = 0;
+	plci->ncpi_state = 0x00;
+	plci->ncpi_buffer[0] = 0;
+
+	plci->requested_options_conn = 0;
+	plci->requested_options = 0;
+	plci->notifiedcall = 0;
+	plci->vswitchstate = 0;
+	plci->vsprot = 0;
+	plci->vsprotdialect = 0;
+	init_b1_config(plci);
+	dbug(1, dprintf("get_plci(%x)", plci->Id));
+	return i + 1;
 }
 
 /*------------------------------------------------------------------*/
 /* put a parameter in the parameter buffer                          */
 /*------------------------------------------------------------------*/
 
-static void add_p(PLCI   * plci, byte code, byte   * p)
+static void add_p(PLCI *plci, byte code, byte *p)
 {
-  word p_length;
+	word p_length;
 
-  p_length = 0;
-  if(p) p_length = p[0];
-  add_ie(plci, code, p, p_length);
+	p_length = 0;
+	if (p) p_length = p[0];
+	add_ie(plci, code, p, p_length);
 }
 
 /*------------------------------------------------------------------*/
 /* put a structure in the parameter buffer                          */
 /*------------------------------------------------------------------*/
-static void add_s(PLCI   * plci, byte code, API_PARSE * p)
+static void add_s(PLCI *plci, byte code, API_PARSE *p)
 {
-  if(p) add_ie(plci, code, p->info, (word)p->length);
+	if (p) add_ie(plci, code, p->info, (word)p->length);
 }
 
 /*------------------------------------------------------------------*/
 /* put multiple structures in the parameter buffer                  */
 /*------------------------------------------------------------------*/
-static void add_ss(PLCI   * plci, byte code, API_PARSE * p)
+static void add_ss(PLCI *plci, byte code, API_PARSE *p)
 {
-  byte i;
+	byte i;
 
-  if(p){
-    dbug(1,dprintf("add_ss(%x,len=%d)",code,p->length));
-    for(i=2;i<(byte)p->length;i+=p->info[i]+2){
-      dbug(1,dprintf("add_ss_ie(%x,len=%d)",p->info[i-1],p->info[i]));
-      add_ie(plci, p->info[i-1], (byte   *)&(p->info[i]), (word)p->info[i]);
-    }
-  }
+	if (p) {
+		dbug(1, dprintf("add_ss(%x,len=%d)", code, p->length));
+		for (i = 2; i < (byte)p->length; i += p->info[i] + 2) {
+			dbug(1, dprintf("add_ss_ie(%x,len=%d)", p->info[i - 1], p->info[i]));
+			add_ie(plci, p->info[i - 1], (byte *)&(p->info[i]), (word)p->info[i]);
+		}
+	}
 }
 
 /*------------------------------------------------------------------*/
 /* return the channel number sent by the application in a esc_chi   */
 /*------------------------------------------------------------------*/
-static byte getChannel(API_PARSE * p)
+static byte getChannel(API_PARSE *p)
 {
-  byte i;
+	byte i;
 
-  if(p){
-    for(i=2;i<(byte)p->length;i+=p->info[i]+2){
-      if(p->info[i]==2){
-        if(p->info[i-1]==ESC && p->info[i+1]==CHI) return (p->info[i+2]);
-      }
-    }
-  }
-  return 0;
+	if (p) {
+		for (i = 2; i < (byte)p->length; i += p->info[i] + 2) {
+			if (p->info[i] == 2) {
+				if (p->info[i - 1] == ESC && p->info[i + 1] == CHI) return (p->info[i + 2]);
+			}
+		}
+	}
+	return 0;
 }
 
 
@@ -7400,26 +7400,26 @@ static byte getChannel(API_PARSE * p)
 /* put an information element in the parameter buffer               */
 /*------------------------------------------------------------------*/
 
-static void add_ie(PLCI   * plci, byte code, byte   * p, word p_length)
+static void add_ie(PLCI *plci, byte code, byte *p, word p_length)
 {
-  word i;
+	word i;
 
-  if(!(code &0x80) && !p_length) return;
+	if (!(code & 0x80) && !p_length) return;
 
-  if(plci->req_in==plci->req_in_start) {
-    plci->req_in +=2;
-  }
-  else {
-    plci->req_in--;
-  }
-  plci->RBuffer[plci->req_in++] = code;
+	if (plci->req_in == plci->req_in_start) {
+		plci->req_in += 2;
+	}
+	else {
+		plci->req_in--;
+	}
+	plci->RBuffer[plci->req_in++] = code;
 
-  if(p) {
-    plci->RBuffer[plci->req_in++] = (byte)p_length;
-    for(i=0;i<p_length;i++) plci->RBuffer[plci->req_in++] = p[1+i];
-  }
+	if (p) {
+		plci->RBuffer[plci->req_in++] = (byte)p_length;
+		for (i = 0; i < p_length; i++) plci->RBuffer[plci->req_in++] = p[1 + i];
+	}
 
-  plci->RBuffer[plci->req_in++] = 0;
+	plci->RBuffer[plci->req_in++] = 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -7428,15 +7428,15 @@ static void add_ie(PLCI   * plci, byte code, byte   * p, word p_length)
 
 static void add_d(PLCI *plci, word length, byte *p)
 {
-  word i;
+	word i;
 
-  if(plci->req_in==plci->req_in_start) {
-    plci->req_in +=2;
-  }
-  else {
-    plci->req_in--;
-  }
-  for(i=0;i<length;i++) plci->RBuffer[plci->req_in++] = p[i];
+	if (plci->req_in == plci->req_in_start) {
+		plci->req_in += 2;
+	}
+	else {
+		plci->req_in--;
+	}
+	for (i = 0; i < length; i++) plci->RBuffer[plci->req_in++] = p[i];
 }
 
 /*------------------------------------------------------------------*/
@@ -7446,19 +7446,19 @@ static void add_d(PLCI *plci, word length, byte *p)
 
 static void add_ai(PLCI *plci, API_PARSE *ai)
 {
-  word i;
-    API_PARSE ai_parms[5];
+	word i;
+	API_PARSE ai_parms[5];
 
-  for(i=0;i<5;i++) ai_parms[i].length = 0;
+	for (i = 0; i < 5; i++) ai_parms[i].length = 0;
 
-  if(!ai->length)
-    return;
-  if(api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
-    return;
+	if (!ai->length)
+		return;
+	if (api_parse(&ai->info[1], (word)ai->length, "ssss", ai_parms))
+		return;
 
-  add_s (plci,KEY,&ai_parms[1]);
-  add_s (plci,UUI,&ai_parms[2]);
-  add_ss(plci,FTY,&ai_parms[3]);
+	add_s(plci, KEY, &ai_parms[1]);
+	add_s(plci, UUI, &ai_parms[2]);
+	add_ss(plci, FTY, &ai_parms[3]);
 }
 
 /*------------------------------------------------------------------*/
@@ -7468,462 +7468,462 @@ static void add_ai(PLCI *plci, API_PARSE *ai)
 static word add_b1(PLCI *plci, API_PARSE *bp, word b_channel_info,
 		   word b1_facilities)
 {
-    API_PARSE bp_parms[8];
-    API_PARSE mdm_cfg[9];
-    API_PARSE global_config[2];
-    byte cai[256];
-  byte resource[] = {5,9,13,12,16,39,9,17,17,18};
-  byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
-  word i;
-
-    API_PARSE mdm_cfg_v18[4];
-  word j, n, w;
-  dword d;
-
-
-  for(i=0;i<8;i++) bp_parms[i].length = 0;
-  for(i=0;i<2;i++) global_config[i].length = 0;
-
-  dbug(1,dprintf("add_b1"));
-  api_save_msg(bp, "s", &plci->B_protocol);
-
-  if(b_channel_info==2){
-    plci->B1_resource = 0;
-    adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
-    add_p(plci, CAI, "\x01\x00");
-    dbug(1,dprintf("Cai=1,0 (no resource)"));
-    return 0;
-  }
-
-  if(plci->tel == CODEC_PERMANENT) return 0;
-  else if(plci->tel == CODEC){
-    plci->B1_resource = 1;
-    adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
-    add_p(plci, CAI, "\x01\x01");
-    dbug(1,dprintf("Cai=1,1 (Codec)"));
-    return 0;
-  }
-  else if(plci->tel == ADV_VOICE){
-    plci->B1_resource = add_b1_facilities (plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE));
-    adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE));
-    voice_cai[1] = plci->B1_resource;
-    PUT_WORD (&voice_cai[5], plci->appl->MaxDataLength);
-    add_p(plci, CAI, voice_cai);
-    dbug(1,dprintf("Cai=1,0x%x (AdvVoice)",voice_cai[1]));
-    return 0;
-  }
-  plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER);
-  if (plci->call_dir & CALL_DIR_OUT)
-    plci->call_dir |= CALL_DIR_ORIGINATE;
-  else if (plci->call_dir & CALL_DIR_IN)
-    plci->call_dir |= CALL_DIR_ANSWER;
-
-  if(!bp->length){
-    plci->B1_resource = 0x5;
-    adjust_b1_facilities (plci, plci->B1_resource, b1_facilities);
-    add_p(plci, CAI, "\x01\x05");
-    return 0;
-  }
-
-  dbug(1,dprintf("b_prot_len=%d",(word)bp->length));
-  if(bp->length>256) return _WRONG_MESSAGE_FORMAT;
-  if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
-  {
-    bp_parms[6].length = 0;
-    if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
-    {
-      dbug(1,dprintf("b-form.!"));
-      return _WRONG_MESSAGE_FORMAT;
-    }
-  }
-  else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
-  {
-    dbug(1,dprintf("b-form.!"));
-    return _WRONG_MESSAGE_FORMAT;
-  }
-
-  if(bp_parms[6].length)
-  {
-    if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
-    {
-      return _WRONG_MESSAGE_FORMAT;
-    }
-    switch(GET_WORD(global_config[0].info))
-    {
-    case 1:
-      plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
-      break;
-    case 2:
-      plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
-      break;
-    }
-  }
-  dbug(1,dprintf("call_dir=%04x", plci->call_dir));
-
-
-  if ((GET_WORD(bp_parms[0].info) == B1_RTP)
-   && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
-  {
-    plci->B1_resource = add_b1_facilities (plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE));
-    adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
-    cai[1] = plci->B1_resource;
-    cai[2] = 0;
-    cai[3] = 0;
-    cai[4] = 0;
-    PUT_WORD(&cai[5],plci->appl->MaxDataLength);
-    for (i = 0; i < bp_parms[3].length; i++)
-      cai[7+i] = bp_parms[3].info[1+i];
-    cai[0] = 6 + bp_parms[3].length;
-    add_p(plci, CAI, cai);
-    return 0;
-  }
-
-
-  if ((GET_WORD(bp_parms[0].info) == B1_PIAFS)
-   && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))
-  {
-    plci->B1_resource = add_b1_facilities (plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE));
-    adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
-    cai[1] = plci->B1_resource;
-    cai[2] = 0;
-    cai[3] = 0;
-    cai[4] = 0;
-    PUT_WORD(&cai[5],plci->appl->MaxDataLength);
-    cai[0] = 6;
-    add_p(plci, CAI, cai);
-    return 0;
-  }
-
-
-  if ((GET_WORD(bp_parms[0].info) >= 32)
-   || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols)
-    && ((GET_WORD(bp_parms[0].info) != 3)
-     || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols)
-     || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000)))))
-  {
-    return _B1_NOT_SUPPORTED;
-  }
-  plci->B1_resource = add_b1_facilities (plci, resource[GET_WORD(bp_parms[0].info)],
-    (word)(b1_facilities & ~B1_FACILITY_VOICE));
-  adjust_b1_facilities (plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
-  cai[0] = 6;
-  cai[1] = plci->B1_resource;
-  for (i=2;i<sizeof(cai);i++) cai[i] = 0;
-
-  if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
-   || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
-   || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))
-  { /* B1 - modem */
-    for (i=0;i<7;i++) mdm_cfg[i].length = 0;
-
-    if (bp_parms[3].length)
-    {
-      if(api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwww", mdm_cfg))
-      {
-        return (_WRONG_MESSAGE_FORMAT);
-      }
-        
-      cai[2] = 0; /* Bit rate for adaptation */
-
-      dbug(1,dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info)));
-
-      PUT_WORD (&cai[13], 0);                          /* Min Tx speed */
-      PUT_WORD (&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */
-      PUT_WORD (&cai[17], 0);                          /* Min Rx speed */
-      PUT_WORD (&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */
-
-      cai[3] = 0; /* Async framing parameters */
-      switch (GET_WORD (mdm_cfg[2].info))
-      {       /* Parity     */
-      case 1: /* odd parity */
-        cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
-        dbug(1,dprintf("MDM: odd parity"));
-        break;
-
-      case 2: /* even parity */
-        cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
-        dbug(1,dprintf("MDM: even parity"));
-        break;
-
-      default:
-        dbug(1,dprintf("MDM: no parity"));
-        break;
-      }
-
-      switch (GET_WORD (mdm_cfg[3].info))
-      {       /* stop bits   */
-      case 1: /* 2 stop bits */
-        cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
-        dbug(1,dprintf("MDM: 2 stop bits"));
-        break;
-
-      default:
-        dbug(1,dprintf("MDM: 1 stop bit"));
-        break;
-      }
-
-      switch (GET_WORD (mdm_cfg[1].info))
-      {     /* char length */
-      case 5:
-        cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
-        dbug(1,dprintf("MDM: 5 bits"));
-        break;
-
-      case 6:
-        cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
-        dbug(1,dprintf("MDM: 6 bits"));
-        break;
-
-      case 7:
-        cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
-        dbug(1,dprintf("MDM: 7 bits"));
-        break;
-
-      default:
-        dbug(1,dprintf("MDM: 8 bits"));
-        break;
-      }
-
-      cai[7] = 0; /* Line taking options */
-      cai[8] = 0; /* Modulation negotiation options */
-      cai[9] = 0; /* Modulation options */
-
-      if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0))
-      {
-        cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION;
-        dbug(1, dprintf("MDM: Reverse direction"));
-      }
-
-      if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN)
-      {
-        cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN;
-        dbug(1, dprintf("MDM: Disable retrain"));
-      }
-
-      if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE)
-      {
-        cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE;
-        dbug(1, dprintf("MDM: Disable ring tone"));
-      }
-
-      if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_1800)
-      {
-        cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ;
-        dbug(1, dprintf("MDM: 1800 guard tone"));
-      }
-      else if (GET_WORD (mdm_cfg[4].info) & MDM_CAPI_GUARD_550 )
-      {
-        cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ;
-        dbug(1, dprintf("MDM: 550 guard tone"));
-      }
-
-      if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100)
-      {
-        cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100;
-        dbug(1, dprintf("MDM: V100"));
-      }
-      else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS)
-      {
-        cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS;
-        dbug(1, dprintf("MDM: IN CLASS"));
-      }
-      else if ((GET_WORD (mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED)
-      {
-        cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED;
-        dbug(1, dprintf("MDM: DISABLED"));
-      }
-      cai[0] = 20;
-
-      if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18))
-       && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */
-      {
-        plci->requested_options |= 1L << PRIVATE_V18;
-      }
-      if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */
-        plci->requested_options |= 1L << PRIVATE_VOWN;
-
-      if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
-        & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
-      {
-        if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwws", mdm_cfg))
-        {
-          i = 27;
-          if (mdm_cfg[6].length >= 4)
-          {
-            d = GET_DWORD(&mdm_cfg[6].info[1]);
-            cai[7] |= (byte) d;          /* line taking options */
-            cai[9] |= (byte)(d >> 8);    /* modulation options */
-            cai[++i] = (byte)(d >> 16);  /* vown modulation options */
-            cai[++i] = (byte)(d >> 24);
-            if (mdm_cfg[6].length >= 8)
-            {
-              d = GET_DWORD(&mdm_cfg[6].info[5]);
-              cai[10] |= (byte) d;        /* disabled modulations mask */
-              cai[11] |= (byte)(d >> 8);
-              if (mdm_cfg[6].length >= 12)
-              {
-                d = GET_DWORD(&mdm_cfg[6].info[9]);
-                cai[12] = (byte) d;          /* enabled modulations mask */
-                cai[++i] = (byte)(d >> 8);   /* vown enabled modulations */
-                cai[++i] = (byte)(d >> 16);
-                cai[++i] = (byte)(d >> 24);
-                cai[++i] = 0;
-                if (mdm_cfg[6].length >= 14)
-                {
-                  w = GET_WORD(&mdm_cfg[6].info[13]);
-                  if (w != 0)
-                    PUT_WORD(&cai[13], w);  /* min tx speed */
-                  if (mdm_cfg[6].length >= 16)
-                  {
-                    w = GET_WORD(&mdm_cfg[6].info[15]);
-                    if (w != 0)
-                      PUT_WORD(&cai[15], w);  /* max tx speed */
-                    if (mdm_cfg[6].length >= 18)
-                    {
-                      w = GET_WORD(&mdm_cfg[6].info[17]);
-                      if (w != 0)
-                        PUT_WORD(&cai[17], w);  /* min rx speed */
-                      if (mdm_cfg[6].length >= 20)
-                      {
-                        w = GET_WORD(&mdm_cfg[6].info[19]);
-                        if (w != 0)
-                          PUT_WORD(&cai[19], w);  /* max rx speed */
-                        if (mdm_cfg[6].length >= 22)
-                        {
-                          w = GET_WORD(&mdm_cfg[6].info[21]);
-                          cai[23] = (byte)(-((short) w));  /* transmit level */
-                          if (mdm_cfg[6].length >= 24)
-                          {
-                            w = GET_WORD(&mdm_cfg[6].info[23]);
-                            cai[22] |= (byte) w;        /* info options mask */
-                            cai[21] |= (byte)(w >> 8);  /* disabled symbol rates */
-                          }
-                        }
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-          cai[27] = i - 27;
-          i++;
-          if (!api_parse(&bp_parms[3].info[1],(word)bp_parms[3].length,"wwwwwwss", mdm_cfg))
-          {
-            if (!api_parse(&mdm_cfg[7].info[1],(word)mdm_cfg[7].length,"sss", mdm_cfg_v18))
-            {
-              for (n = 0; n < 3; n++)
-              {
-                cai[i] = (byte)(mdm_cfg_v18[n].length);
-                for (j = 1; j < ((word)(cai[i] + 1)); j++)
-                  cai[i+j] = mdm_cfg_v18[n].info[j];
-                i += cai[i] + 1;
-              }
-            }
-          }
-          cai[0] = (byte)(i - 1);
-        }
-      }
-
-    }
-  }
-  if(GET_WORD(bp_parms[0].info)==2 ||                         /* V.110 async */
-     GET_WORD(bp_parms[0].info)==3 )                          /* V.110 sync */
-  {
-    if(bp_parms[3].length){
-      dbug(1,dprintf("V.110,%d",GET_WORD(&bp_parms[3].info[1])));
-      switch(GET_WORD(&bp_parms[3].info[1])){                 /* Rate */
-        case 0:
-        case 56000:
-          if(GET_WORD(bp_parms[0].info)==3){                  /* V.110 sync 56k */
-            dbug(1,dprintf("56k sync HSCX"));
-            cai[1] = 8;
-            cai[2] = 0;
-            cai[3] = 0;
-          }
-          else if(GET_WORD(bp_parms[0].info)==2){
-            dbug(1,dprintf("56k async DSP"));
-            cai[2] = 9;
-          }
-          break;
-        case 50:     cai[2] = 1;  break;
-        case 75:     cai[2] = 1;  break;
-        case 110:    cai[2] = 1;  break;
-        case 150:    cai[2] = 1;  break;
-        case 200:    cai[2] = 1;  break;
-        case 300:    cai[2] = 1;  break;
-        case 600:    cai[2] = 1;  break;
-        case 1200:   cai[2] = 2;  break;
-        case 2400:   cai[2] = 3;  break;
-        case 4800:   cai[2] = 4;  break;
-        case 7200:   cai[2] = 10; break;
-        case 9600:   cai[2] = 5;  break;
-        case 12000:  cai[2] = 13; break;
-        case 24000:  cai[2] = 0;  break;
-        case 14400:  cai[2] = 11; break;
-        case 19200:  cai[2] = 6;  break;
-        case 28800:  cai[2] = 12; break;
-        case 38400:  cai[2] = 7;  break;
-        case 48000:  cai[2] = 8;  break;
-        case 76:     cai[2] = 15; break;  /* 75/1200     */
-        case 1201:   cai[2] = 14; break;  /* 1200/75     */
-        case 56001:  cai[2] = 9;  break;  /* V.110 56000 */
-
-        default:
-          return _B1_PARM_NOT_SUPPORTED;
-      }
-      cai[3] = 0;
-      if (cai[1] == 13)                                        /* v.110 async */
-      {
-        if (bp_parms[3].length >= 8)
-        {
-          switch (GET_WORD (&bp_parms[3].info[3]))
-          {       /* char length */
-          case 5:
-            cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
-            break;
-          case 6:
-            cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
-            break;
-          case 7:
-            cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
-            break;
-          }
-          switch (GET_WORD (&bp_parms[3].info[5]))
-          {       /* Parity     */
-          case 1: /* odd parity */
-            cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
-            break;
-          case 2: /* even parity */
-            cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
-            break;
-          }
-          switch (GET_WORD (&bp_parms[3].info[7]))
-          {       /* stop bits   */
-          case 1: /* 2 stop bits */
-            cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
-            break;
-          }
-        }
-      }
-    }
-    else if(cai[1]==8 || GET_WORD(bp_parms[0].info)==3 ){
-      dbug(1,dprintf("V.110 default 56k sync"));
-      cai[1] = 8;
-      cai[2] = 0;
-      cai[3] = 0;
-    }
-    else {
-      dbug(1,dprintf("V.110 default 9600 async"));
-      cai[2] = 5;
-    }
-  }
-  PUT_WORD(&cai[5],plci->appl->MaxDataLength);
-  dbug(1,dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
+	API_PARSE bp_parms[8];
+	API_PARSE mdm_cfg[9];
+	API_PARSE global_config[2];
+	byte cai[256];
+	byte resource[] = {5, 9, 13, 12, 16, 39, 9, 17, 17, 18};
+	byte voice_cai[] = "\x06\x14\x00\x00\x00\x00\x08";
+	word i;
+
+	API_PARSE mdm_cfg_v18[4];
+	word j, n, w;
+	dword d;
+
+
+	for (i = 0; i < 8; i++) bp_parms[i].length = 0;
+	for (i = 0; i < 2; i++) global_config[i].length = 0;
+
+	dbug(1, dprintf("add_b1"));
+	api_save_msg(bp, "s", &plci->B_protocol);
+
+	if (b_channel_info == 2) {
+		plci->B1_resource = 0;
+		adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
+		add_p(plci, CAI, "\x01\x00");
+		dbug(1, dprintf("Cai=1,0 (no resource)"));
+		return 0;
+	}
+
+	if (plci->tel == CODEC_PERMANENT) return 0;
+	else if (plci->tel == CODEC) {
+		plci->B1_resource = 1;
+		adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
+		add_p(plci, CAI, "\x01\x01");
+		dbug(1, dprintf("Cai=1,1 (Codec)"));
+		return 0;
+	}
+	else if (plci->tel == ADV_VOICE) {
+		plci->B1_resource = add_b1_facilities(plci, 9, (word)(b1_facilities | B1_FACILITY_VOICE));
+		adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities | B1_FACILITY_VOICE));
+		voice_cai[1] = plci->B1_resource;
+		PUT_WORD(&voice_cai[5], plci->appl->MaxDataLength);
+		add_p(plci, CAI, voice_cai);
+		dbug(1, dprintf("Cai=1,0x%x (AdvVoice)", voice_cai[1]));
+		return 0;
+	}
+	plci->call_dir &= ~(CALL_DIR_ORIGINATE | CALL_DIR_ANSWER);
+	if (plci->call_dir & CALL_DIR_OUT)
+		plci->call_dir |= CALL_DIR_ORIGINATE;
+	else if (plci->call_dir & CALL_DIR_IN)
+		plci->call_dir |= CALL_DIR_ANSWER;
+
+	if (!bp->length) {
+		plci->B1_resource = 0x5;
+		adjust_b1_facilities(plci, plci->B1_resource, b1_facilities);
+		add_p(plci, CAI, "\x01\x05");
+		return 0;
+	}
+
+	dbug(1, dprintf("b_prot_len=%d", (word)bp->length));
+	if (bp->length > 256) return _WRONG_MESSAGE_FORMAT;
+	if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
+	{
+		bp_parms[6].length = 0;
+		if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
+		{
+			dbug(1, dprintf("b-form.!"));
+			return _WRONG_MESSAGE_FORMAT;
+		}
+	}
+	else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
+	{
+		dbug(1, dprintf("b-form.!"));
+		return _WRONG_MESSAGE_FORMAT;
+	}
+
+	if (bp_parms[6].length)
+	{
+		if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
+		{
+			return _WRONG_MESSAGE_FORMAT;
+		}
+		switch (GET_WORD(global_config[0].info))
+		{
+		case 1:
+			plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
+			break;
+		case 2:
+			plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
+			break;
+		}
+	}
+	dbug(1, dprintf("call_dir=%04x", plci->call_dir));
+
+
+	if ((GET_WORD(bp_parms[0].info) == B1_RTP)
+	    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
+	{
+		plci->B1_resource = add_b1_facilities(plci, 31, (word)(b1_facilities & ~B1_FACILITY_VOICE));
+		adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
+		cai[1] = plci->B1_resource;
+		cai[2] = 0;
+		cai[3] = 0;
+		cai[4] = 0;
+		PUT_WORD(&cai[5], plci->appl->MaxDataLength);
+		for (i = 0; i < bp_parms[3].length; i++)
+			cai[7 + i] = bp_parms[3].info[1 + i];
+		cai[0] = 6 + bp_parms[3].length;
+		add_p(plci, CAI, cai);
+		return 0;
+	}
+
+
+	if ((GET_WORD(bp_parms[0].info) == B1_PIAFS)
+	    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))
+	{
+		plci->B1_resource = add_b1_facilities(plci, 35/* PIAFS HARDWARE FACILITY */, (word)(b1_facilities & ~B1_FACILITY_VOICE));
+		adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
+		cai[1] = plci->B1_resource;
+		cai[2] = 0;
+		cai[3] = 0;
+		cai[4] = 0;
+		PUT_WORD(&cai[5], plci->appl->MaxDataLength);
+		cai[0] = 6;
+		add_p(plci, CAI, cai);
+		return 0;
+	}
+
+
+	if ((GET_WORD(bp_parms[0].info) >= 32)
+	    || (!((1L << GET_WORD(bp_parms[0].info)) & plci->adapter->profile.B1_Protocols)
+		&& ((GET_WORD(bp_parms[0].info) != 3)
+		    || !((1L << B1_HDLC) & plci->adapter->profile.B1_Protocols)
+		    || ((bp_parms[3].length != 0) && (GET_WORD(&bp_parms[3].info[1]) != 0) && (GET_WORD(&bp_parms[3].info[1]) != 56000)))))
+	{
+		return _B1_NOT_SUPPORTED;
+	}
+	plci->B1_resource = add_b1_facilities(plci, resource[GET_WORD(bp_parms[0].info)],
+					      (word)(b1_facilities & ~B1_FACILITY_VOICE));
+	adjust_b1_facilities(plci, plci->B1_resource, (word)(b1_facilities & ~B1_FACILITY_VOICE));
+	cai[0] = 6;
+	cai[1] = plci->B1_resource;
+	for (i = 2; i < sizeof(cai); i++) cai[i] = 0;
+
+	if ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
+	    || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
+	    || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC))
+	{ /* B1 - modem */
+		for (i = 0; i < 7; i++) mdm_cfg[i].length = 0;
+
+		if (bp_parms[3].length)
+		{
+			if (api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwww", mdm_cfg))
+			{
+				return (_WRONG_MESSAGE_FORMAT);
+			}
+
+			cai[2] = 0; /* Bit rate for adaptation */
+
+			dbug(1, dprintf("MDM Max Bit Rate:<%d>", GET_WORD(mdm_cfg[0].info)));
+
+			PUT_WORD(&cai[13], 0);                          /* Min Tx speed */
+			PUT_WORD(&cai[15], GET_WORD(mdm_cfg[0].info)); /* Max Tx speed */
+			PUT_WORD(&cai[17], 0);                          /* Min Rx speed */
+			PUT_WORD(&cai[19], GET_WORD(mdm_cfg[0].info)); /* Max Rx speed */
+
+			cai[3] = 0; /* Async framing parameters */
+			switch (GET_WORD(mdm_cfg[2].info))
+			{       /* Parity     */
+			case 1: /* odd parity */
+				cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
+				dbug(1, dprintf("MDM: odd parity"));
+				break;
+
+			case 2: /* even parity */
+				cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
+				dbug(1, dprintf("MDM: even parity"));
+				break;
+
+			default:
+				dbug(1, dprintf("MDM: no parity"));
+				break;
+			}
+
+			switch (GET_WORD(mdm_cfg[3].info))
+			{       /* stop bits   */
+			case 1: /* 2 stop bits */
+				cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
+				dbug(1, dprintf("MDM: 2 stop bits"));
+				break;
+
+			default:
+				dbug(1, dprintf("MDM: 1 stop bit"));
+				break;
+			}
+
+			switch (GET_WORD(mdm_cfg[1].info))
+			{     /* char length */
+			case 5:
+				cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
+				dbug(1, dprintf("MDM: 5 bits"));
+				break;
+
+			case 6:
+				cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
+				dbug(1, dprintf("MDM: 6 bits"));
+				break;
+
+			case 7:
+				cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
+				dbug(1, dprintf("MDM: 7 bits"));
+				break;
+
+			default:
+				dbug(1, dprintf("MDM: 8 bits"));
+				break;
+			}
+
+			cai[7] = 0; /* Line taking options */
+			cai[8] = 0; /* Modulation negotiation options */
+			cai[9] = 0; /* Modulation options */
+
+			if (((plci->call_dir & CALL_DIR_ORIGINATE) != 0) ^ ((plci->call_dir & CALL_DIR_OUT) != 0))
+			{
+				cai[9] |= DSP_CAI_MODEM_REVERSE_DIRECTION;
+				dbug(1, dprintf("MDM: Reverse direction"));
+			}
+
+			if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RETRAIN)
+			{
+				cai[9] |= DSP_CAI_MODEM_DISABLE_RETRAIN;
+				dbug(1, dprintf("MDM: Disable retrain"));
+			}
+
+			if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_DISABLE_RING_TONE)
+			{
+				cai[7] |= DSP_CAI_MODEM_DISABLE_CALLING_TONE | DSP_CAI_MODEM_DISABLE_ANSWER_TONE;
+				dbug(1, dprintf("MDM: Disable ring tone"));
+			}
+
+			if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_1800)
+			{
+				cai[8] |= DSP_CAI_MODEM_GUARD_TONE_1800HZ;
+				dbug(1, dprintf("MDM: 1800 guard tone"));
+			}
+			else if (GET_WORD(mdm_cfg[4].info) & MDM_CAPI_GUARD_550)
+			{
+				cai[8] |= DSP_CAI_MODEM_GUARD_TONE_550HZ;
+				dbug(1, dprintf("MDM: 550 guard tone"));
+			}
+
+			if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_V100)
+			{
+				cai[8] |= DSP_CAI_MODEM_NEGOTIATE_V100;
+				dbug(1, dprintf("MDM: V100"));
+			}
+			else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_MOD_CLASS)
+			{
+				cai[8] |= DSP_CAI_MODEM_NEGOTIATE_IN_CLASS;
+				dbug(1, dprintf("MDM: IN CLASS"));
+			}
+			else if ((GET_WORD(mdm_cfg[5].info) & 0x00ff) == MDM_CAPI_NEG_DISABLED)
+			{
+				cai[8] |= DSP_CAI_MODEM_NEGOTIATE_DISABLED;
+				dbug(1, dprintf("MDM: DISABLED"));
+			}
+			cai[0] = 20;
+
+			if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_V18))
+			    && (GET_WORD(mdm_cfg[5].info) & 0x8000)) /* Private V.18 enable */
+			{
+				plci->requested_options |= 1L << PRIVATE_V18;
+			}
+			if (GET_WORD(mdm_cfg[5].info) & 0x4000) /* Private VOWN enable */
+				plci->requested_options |= 1L << PRIVATE_VOWN;
+
+			if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
+			    & ((1L << PRIVATE_V18) | (1L << PRIVATE_VOWN)))
+			{
+				if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwws", mdm_cfg))
+				{
+					i = 27;
+					if (mdm_cfg[6].length >= 4)
+					{
+						d = GET_DWORD(&mdm_cfg[6].info[1]);
+						cai[7] |= (byte) d;          /* line taking options */
+						cai[9] |= (byte)(d >> 8);    /* modulation options */
+						cai[++i] = (byte)(d >> 16);  /* vown modulation options */
+						cai[++i] = (byte)(d >> 24);
+						if (mdm_cfg[6].length >= 8)
+						{
+							d = GET_DWORD(&mdm_cfg[6].info[5]);
+							cai[10] |= (byte) d;        /* disabled modulations mask */
+							cai[11] |= (byte)(d >> 8);
+							if (mdm_cfg[6].length >= 12)
+							{
+								d = GET_DWORD(&mdm_cfg[6].info[9]);
+								cai[12] = (byte) d;          /* enabled modulations mask */
+								cai[++i] = (byte)(d >> 8);   /* vown enabled modulations */
+								cai[++i] = (byte)(d >> 16);
+								cai[++i] = (byte)(d >> 24);
+								cai[++i] = 0;
+								if (mdm_cfg[6].length >= 14)
+								{
+									w = GET_WORD(&mdm_cfg[6].info[13]);
+									if (w != 0)
+										PUT_WORD(&cai[13], w);  /* min tx speed */
+									if (mdm_cfg[6].length >= 16)
+									{
+										w = GET_WORD(&mdm_cfg[6].info[15]);
+										if (w != 0)
+											PUT_WORD(&cai[15], w);  /* max tx speed */
+										if (mdm_cfg[6].length >= 18)
+										{
+											w = GET_WORD(&mdm_cfg[6].info[17]);
+											if (w != 0)
+												PUT_WORD(&cai[17], w);  /* min rx speed */
+											if (mdm_cfg[6].length >= 20)
+											{
+												w = GET_WORD(&mdm_cfg[6].info[19]);
+												if (w != 0)
+													PUT_WORD(&cai[19], w);  /* max rx speed */
+												if (mdm_cfg[6].length >= 22)
+												{
+													w = GET_WORD(&mdm_cfg[6].info[21]);
+													cai[23] = (byte)(-((short) w));  /* transmit level */
+													if (mdm_cfg[6].length >= 24)
+													{
+														w = GET_WORD(&mdm_cfg[6].info[23]);
+														cai[22] |= (byte) w;        /* info options mask */
+														cai[21] |= (byte)(w >> 8);  /* disabled symbol rates */
+													}
+												}
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+					cai[27] = i - 27;
+					i++;
+					if (!api_parse(&bp_parms[3].info[1], (word)bp_parms[3].length, "wwwwwwss", mdm_cfg))
+					{
+						if (!api_parse(&mdm_cfg[7].info[1], (word)mdm_cfg[7].length, "sss", mdm_cfg_v18))
+						{
+							for (n = 0; n < 3; n++)
+							{
+								cai[i] = (byte)(mdm_cfg_v18[n].length);
+								for (j = 1; j < ((word)(cai[i] + 1)); j++)
+									cai[i + j] = mdm_cfg_v18[n].info[j];
+								i += cai[i] + 1;
+							}
+						}
+					}
+					cai[0] = (byte)(i - 1);
+				}
+			}
+
+		}
+	}
+	if (GET_WORD(bp_parms[0].info) == 2 ||                         /* V.110 async */
+	    GET_WORD(bp_parms[0].info) == 3)                           /* V.110 sync */
+	{
+		if (bp_parms[3].length) {
+			dbug(1, dprintf("V.110,%d", GET_WORD(&bp_parms[3].info[1])));
+			switch (GET_WORD(&bp_parms[3].info[1])) {                 /* Rate */
+			case 0:
+			case 56000:
+				if (GET_WORD(bp_parms[0].info) == 3) {                  /* V.110 sync 56k */
+					dbug(1, dprintf("56k sync HSCX"));
+					cai[1] = 8;
+					cai[2] = 0;
+					cai[3] = 0;
+				}
+				else if (GET_WORD(bp_parms[0].info) == 2) {
+					dbug(1, dprintf("56k async DSP"));
+					cai[2] = 9;
+				}
+				break;
+			case 50:     cai[2] = 1;  break;
+			case 75:     cai[2] = 1;  break;
+			case 110:    cai[2] = 1;  break;
+			case 150:    cai[2] = 1;  break;
+			case 200:    cai[2] = 1;  break;
+			case 300:    cai[2] = 1;  break;
+			case 600:    cai[2] = 1;  break;
+			case 1200:   cai[2] = 2;  break;
+			case 2400:   cai[2] = 3;  break;
+			case 4800:   cai[2] = 4;  break;
+			case 7200:   cai[2] = 10; break;
+			case 9600:   cai[2] = 5;  break;
+			case 12000:  cai[2] = 13; break;
+			case 24000:  cai[2] = 0;  break;
+			case 14400:  cai[2] = 11; break;
+			case 19200:  cai[2] = 6;  break;
+			case 28800:  cai[2] = 12; break;
+			case 38400:  cai[2] = 7;  break;
+			case 48000:  cai[2] = 8;  break;
+			case 76:     cai[2] = 15; break;  /* 75/1200     */
+			case 1201:   cai[2] = 14; break;  /* 1200/75     */
+			case 56001:  cai[2] = 9;  break;  /* V.110 56000 */
+
+			default:
+				return _B1_PARM_NOT_SUPPORTED;
+			}
+			cai[3] = 0;
+			if (cai[1] == 13)                                        /* v.110 async */
+			{
+				if (bp_parms[3].length >= 8)
+				{
+					switch (GET_WORD(&bp_parms[3].info[3]))
+					{       /* char length */
+					case 5:
+						cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_5;
+						break;
+					case 6:
+						cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_6;
+						break;
+					case 7:
+						cai[3] |= DSP_CAI_ASYNC_CHAR_LENGTH_7;
+						break;
+					}
+					switch (GET_WORD(&bp_parms[3].info[5]))
+					{       /* Parity     */
+					case 1: /* odd parity */
+						cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_ODD);
+						break;
+					case 2: /* even parity */
+						cai[3] |= (DSP_CAI_ASYNC_PARITY_ENABLE | DSP_CAI_ASYNC_PARITY_EVEN);
+						break;
+					}
+					switch (GET_WORD(&bp_parms[3].info[7]))
+					{       /* stop bits   */
+					case 1: /* 2 stop bits */
+						cai[3] |= DSP_CAI_ASYNC_TWO_STOP_BITS;
+						break;
+					}
+				}
+			}
+		}
+		else if (cai[1] == 8 || GET_WORD(bp_parms[0].info) == 3) {
+			dbug(1, dprintf("V.110 default 56k sync"));
+			cai[1] = 8;
+			cai[2] = 0;
+			cai[3] = 0;
+		}
+		else {
+			dbug(1, dprintf("V.110 default 9600 async"));
+			cai[2] = 5;
+		}
+	}
+	PUT_WORD(&cai[5], plci->appl->MaxDataLength);
+	dbug(1, dprintf("CAI[%d]=%x,%x,%x,%x,%x,%x", cai[0], cai[1], cai[2], cai[3], cai[4], cai[5], cai[6]));
 /* HexDump ("CAI", sizeof(cai), &cai[0]); */
 
-  add_p(plci, CAI, cai);
-  return 0;
+	add_p(plci, CAI, cai);
+	return 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -7932,624 +7932,624 @@ static word add_b1(PLCI *plci, API_PARSE *bp, word b_channel_info,
 
 static word add_b23(PLCI *plci, API_PARSE *bp)
 {
-  word i, fax_control_bits;
-  byte pos, len;
-  byte SAPI = 0x40;  /* default SAPI 16 for x.31 */
-    API_PARSE bp_parms[8];
-  API_PARSE * b1_config;
-  API_PARSE * b2_config;
-    API_PARSE b2_config_parms[8];
-  API_PARSE * b3_config;
-    API_PARSE b3_config_parms[6];
-    API_PARSE global_config[2];
-
-  static byte llc[3] = {2,0,0};
-  static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-  static byte nlc[256];
-  static byte lli[12] = {1,1};
-
-  const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
-  const byte llc2_in[]  = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
-
-  const byte llc3[] = {4,3,2,2,6,6,0};
-  const byte header[] = {0,2,3,3,0,0,0};
-
-  for(i=0;i<8;i++) bp_parms[i].length = 0;
-  for(i=0;i<6;i++) b2_config_parms[i].length = 0;
-  for(i=0;i<5;i++) b3_config_parms[i].length = 0;
-
-  lli[0] = 1;
-  lli[1] = 1;
-  if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
-    lli[1] |= 2;
-  if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
-    lli[1] |= 4;
-
-  if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
-    lli[1] |= 0x10;
-    if (plci->rx_dma_descriptor <= 0) {
-      plci->rx_dma_descriptor=diva_get_dma_descriptor(plci,&plci->rx_dma_magic);
-      if (plci->rx_dma_descriptor >= 0)
-        plci->rx_dma_descriptor++;
-    }
-    if (plci->rx_dma_descriptor > 0) {
-      lli[0] = 6;
-      lli[1] |= 0x40;
-      lli[2] = (byte)(plci->rx_dma_descriptor - 1);
-      lli[3] = (byte)plci->rx_dma_magic;
-      lli[4] = (byte)(plci->rx_dma_magic >>  8);
-      lli[5] = (byte)(plci->rx_dma_magic >> 16);
-      lli[6] = (byte)(plci->rx_dma_magic >> 24);
-    }
-  }
-
-  if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
-    lli[1] |= 0x20;
-  }
-
-  dbug(1,dprintf("add_b23"));
-  api_save_msg(bp, "s", &plci->B_protocol);
-
-  if(!bp->length && plci->tel)
-  {
-    plci->adv_nl = true;
-    dbug(1,dprintf("Default adv.Nl"));
-    add_p(plci,LLI,lli);
-    plci->B2_prot = 1 /*XPARENT*/;
-    plci->B3_prot = 0 /*XPARENT*/;
-    llc[1] = 2;
-    llc[2] = 4;
-    add_p(plci, LLC, llc);
-    dlc[0] = 2;
-    PUT_WORD(&dlc[1],plci->appl->MaxDataLength);
-    add_p(plci, DLC, dlc);
-    return 0;
-  }
-
-  if(!bp->length) /*default*/
-  {   
-    dbug(1,dprintf("ret default"));
-    add_p(plci,LLI,lli);
-    plci->B2_prot = 0 /*X.75   */;
-    plci->B3_prot = 0 /*XPARENT*/;
-    llc[1] = 1;
-    llc[2] = 4;
-    add_p(plci, LLC, llc);
-    dlc[0] = 2;
-    PUT_WORD(&dlc[1],plci->appl->MaxDataLength);
-    add_p(plci, DLC, dlc);
-    return 0;
-  }
-  dbug(1,dprintf("b_prot_len=%d",(word)bp->length));
-  if((word)bp->length > 256)    return _WRONG_MESSAGE_FORMAT;
-
-  if(api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
-  {
-    bp_parms[6].length = 0;
-    if(api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
-    {
-      dbug(1,dprintf("b-form.!"));
-      return _WRONG_MESSAGE_FORMAT;
-    }
-  }
-  else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
-  {
-    dbug(1,dprintf("b-form.!"));
-    return _WRONG_MESSAGE_FORMAT;
-  }
-
-  if(plci->tel==ADV_VOICE) /* transparent B on advanced voice */
-  {  
-    if(GET_WORD(bp_parms[1].info)!=1
-    || GET_WORD(bp_parms[2].info)!=0) return _B2_NOT_SUPPORTED;
-    plci->adv_nl = true;
-  }
-  else if(plci->tel) return _B2_NOT_SUPPORTED;
-
-
-  if ((GET_WORD(bp_parms[1].info) == B2_RTP)
-   && (GET_WORD(bp_parms[2].info) == B3_RTP)
-   && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
-  {
-    add_p(plci,LLI,lli);
-    plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
-    plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
-    llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13;
-    llc[2] = 4;
-    add_p(plci, LLC, llc);
-    dlc[0] = 2;
-    PUT_WORD(&dlc[1],plci->appl->MaxDataLength);
-    dlc[3] = 3; /* Addr A */
-    dlc[4] = 1; /* Addr B */
-    dlc[5] = 7; /* modulo mode */
-    dlc[6] = 7; /* window size */
-    dlc[7] = 0; /* XID len Lo  */
-    dlc[8] = 0; /* XID len Hi  */
-    for (i = 0; i < bp_parms[4].length; i++)
-      dlc[9+i] = bp_parms[4].info[1+i];
-    dlc[0] = (byte)(8 + bp_parms[4].length);
-    add_p(plci, DLC, dlc);
-    for (i = 0; i < bp_parms[5].length; i++)
-      nlc[1+i] = bp_parms[5].info[1+i];
-    nlc[0] = (byte)(bp_parms[5].length);
-    add_p(plci, NLC, nlc);
-    return 0;
-  }
-
-
-
-  if ((GET_WORD(bp_parms[1].info) >= 32)
-   || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols)
-    && ((GET_WORD(bp_parms[1].info) != B2_PIAFS)
-     || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))))
-
-  {
-    return _B2_NOT_SUPPORTED;
-  }
-  if ((GET_WORD(bp_parms[2].info) >= 32)
-   || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols))
-  {
-    return _B3_NOT_SUPPORTED;
-  }
-  if ((GET_WORD(bp_parms[1].info) != B2_SDLC)
-   && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
-    || (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
-    || (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)))
-  {
-    return (add_modem_b23 (plci, bp_parms));
-  }
-
-  add_p(plci,LLI,lli);
-
-  plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
-  plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
-  if(plci->B2_prot==12) SAPI = 0; /* default SAPI D-channel */
-
-  if(bp_parms[6].length)
-  {
-    if(api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
-    {
-      return _WRONG_MESSAGE_FORMAT;
-    }
-    switch(GET_WORD(global_config[0].info))
-    {
-    case 1:
-      plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
-      break;
-    case 2:
-      plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
-      break;
-    }
-  }
-  dbug(1,dprintf("call_dir=%04x", plci->call_dir));
-
-
-  if (plci->B2_prot == B2_PIAFS)
-    llc[1] = PIAFS_CRC;
-  else
+	word i, fax_control_bits;
+	byte pos, len;
+	byte SAPI = 0x40;  /* default SAPI 16 for x.31 */
+	API_PARSE bp_parms[8];
+	API_PARSE *b1_config;
+	API_PARSE *b2_config;
+	API_PARSE b2_config_parms[8];
+	API_PARSE *b3_config;
+	API_PARSE b3_config_parms[6];
+	API_PARSE global_config[2];
+
+	static byte llc[3] = {2,0,0};
+	static byte dlc[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	static byte nlc[256];
+	static byte lli[12] = {1,1};
+
+	const byte llc2_out[] = {1,2,4,6,2,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
+	const byte llc2_in[]  = {1,3,4,6,3,0,0,0, X75_V42BIS,V120_L2,V120_V42BIS,V120_L2,6};
+
+	const byte llc3[] = {4,3,2,2,6,6,0};
+	const byte header[] = {0,2,3,3,0,0,0};
+
+	for (i = 0; i < 8; i++) bp_parms[i].length = 0;
+	for (i = 0; i < 6; i++) b2_config_parms[i].length = 0;
+	for (i = 0; i < 5; i++) b3_config_parms[i].length = 0;
+
+	lli[0] = 1;
+	lli[1] = 1;
+	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
+		lli[1] |= 2;
+	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
+		lli[1] |= 4;
+
+	if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
+		lli[1] |= 0x10;
+		if (plci->rx_dma_descriptor <= 0) {
+			plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic);
+			if (plci->rx_dma_descriptor >= 0)
+				plci->rx_dma_descriptor++;
+		}
+		if (plci->rx_dma_descriptor > 0) {
+			lli[0] = 6;
+			lli[1] |= 0x40;
+			lli[2] = (byte)(plci->rx_dma_descriptor - 1);
+			lli[3] = (byte)plci->rx_dma_magic;
+			lli[4] = (byte)(plci->rx_dma_magic >>  8);
+			lli[5] = (byte)(plci->rx_dma_magic >> 16);
+			lli[6] = (byte)(plci->rx_dma_magic >> 24);
+		}
+	}
+
+	if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
+		lli[1] |= 0x20;
+	}
+
+	dbug(1, dprintf("add_b23"));
+	api_save_msg(bp, "s", &plci->B_protocol);
+
+	if (!bp->length && plci->tel)
+	{
+		plci->adv_nl = true;
+		dbug(1, dprintf("Default adv.Nl"));
+		add_p(plci, LLI, lli);
+		plci->B2_prot = 1 /*XPARENT*/;
+		plci->B3_prot = 0 /*XPARENT*/;
+		llc[1] = 2;
+		llc[2] = 4;
+		add_p(plci, LLC, llc);
+		dlc[0] = 2;
+		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
+		add_p(plci, DLC, dlc);
+		return 0;
+	}
+
+	if (!bp->length) /*default*/
+	{
+		dbug(1, dprintf("ret default"));
+		add_p(plci, LLI, lli);
+		plci->B2_prot = 0 /*X.75   */;
+		plci->B3_prot = 0 /*XPARENT*/;
+		llc[1] = 1;
+		llc[2] = 4;
+		add_p(plci, LLC, llc);
+		dlc[0] = 2;
+		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
+		add_p(plci, DLC, dlc);
+		return 0;
+	}
+	dbug(1, dprintf("b_prot_len=%d", (word)bp->length));
+	if ((word)bp->length > 256)    return _WRONG_MESSAGE_FORMAT;
+
+	if (api_parse(&bp->info[1], (word)bp->length, "wwwsssb", bp_parms))
+	{
+		bp_parms[6].length = 0;
+		if (api_parse(&bp->info[1], (word)bp->length, "wwwsss", bp_parms))
+		{
+			dbug(1, dprintf("b-form.!"));
+			return _WRONG_MESSAGE_FORMAT;
+		}
+	}
+	else if (api_parse(&bp->info[1], (word)bp->length, "wwwssss", bp_parms))
+	{
+		dbug(1, dprintf("b-form.!"));
+		return _WRONG_MESSAGE_FORMAT;
+	}
+
+	if (plci->tel == ADV_VOICE) /* transparent B on advanced voice */
+	{
+		if (GET_WORD(bp_parms[1].info) != 1
+		    || GET_WORD(bp_parms[2].info) != 0) return _B2_NOT_SUPPORTED;
+		plci->adv_nl = true;
+	}
+	else if (plci->tel) return _B2_NOT_SUPPORTED;
+
+
+	if ((GET_WORD(bp_parms[1].info) == B2_RTP)
+	    && (GET_WORD(bp_parms[2].info) == B3_RTP)
+	    && (plci->adapter->man_profile.private_options & (1L << PRIVATE_RTP)))
+	{
+		add_p(plci, LLI, lli);
+		plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
+		plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
+		llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ? 14 : 13;
+		llc[2] = 4;
+		add_p(plci, LLC, llc);
+		dlc[0] = 2;
+		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
+		dlc[3] = 3; /* Addr A */
+		dlc[4] = 1; /* Addr B */
+		dlc[5] = 7; /* modulo mode */
+		dlc[6] = 7; /* window size */
+		dlc[7] = 0; /* XID len Lo  */
+		dlc[8] = 0; /* XID len Hi  */
+		for (i = 0; i < bp_parms[4].length; i++)
+			dlc[9 + i] = bp_parms[4].info[1 + i];
+		dlc[0] = (byte)(8 + bp_parms[4].length);
+		add_p(plci, DLC, dlc);
+		for (i = 0; i < bp_parms[5].length; i++)
+			nlc[1 + i] = bp_parms[5].info[1 + i];
+		nlc[0] = (byte)(bp_parms[5].length);
+		add_p(plci, NLC, nlc);
+		return 0;
+	}
+
+
+
+	if ((GET_WORD(bp_parms[1].info) >= 32)
+	    || (!((1L << GET_WORD(bp_parms[1].info)) & plci->adapter->profile.B2_Protocols)
+		&& ((GET_WORD(bp_parms[1].info) != B2_PIAFS)
+		    || !(plci->adapter->man_profile.private_options & (1L << PRIVATE_PIAFS)))))
+
+	{
+		return _B2_NOT_SUPPORTED;
+	}
+	if ((GET_WORD(bp_parms[2].info) >= 32)
+	    || !((1L << GET_WORD(bp_parms[2].info)) & plci->adapter->profile.B3_Protocols))
+	{
+		return _B3_NOT_SUPPORTED;
+	}
+	if ((GET_WORD(bp_parms[1].info) != B2_SDLC)
+	    && ((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
+		|| (GET_WORD(bp_parms[0].info) == B1_MODEM_ASYNC)
+		|| (GET_WORD(bp_parms[0].info) == B1_MODEM_SYNC_HDLC)))
+	{
+		return (add_modem_b23(plci, bp_parms));
+	}
+
+	add_p(plci, LLI, lli);
+
+	plci->B2_prot = (byte)GET_WORD(bp_parms[1].info);
+	plci->B3_prot = (byte)GET_WORD(bp_parms[2].info);
+	if (plci->B2_prot == 12) SAPI = 0; /* default SAPI D-channel */
+
+	if (bp_parms[6].length)
+	{
+		if (api_parse(&bp_parms[6].info[1], (word)bp_parms[6].length, "w", global_config))
+		{
+			return _WRONG_MESSAGE_FORMAT;
+		}
+		switch (GET_WORD(global_config[0].info))
+		{
+		case 1:
+			plci->call_dir = (plci->call_dir & ~CALL_DIR_ANSWER) | CALL_DIR_ORIGINATE;
+			break;
+		case 2:
+			plci->call_dir = (plci->call_dir & ~CALL_DIR_ORIGINATE) | CALL_DIR_ANSWER;
+			break;
+		}
+	}
+	dbug(1, dprintf("call_dir=%04x", plci->call_dir));
+
+
+	if (plci->B2_prot == B2_PIAFS)
+		llc[1] = PIAFS_CRC;
+	else
 /* IMPLEMENT_PIAFS */
-  {
-    llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
-             llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)];
-  }
-  llc[2] = llc3[GET_WORD(bp_parms[2].info)];
-
-  add_p(plci, LLC, llc);
-
-  dlc[0] = 2;
-  PUT_WORD(&dlc[1], plci->appl->MaxDataLength +
-                      header[GET_WORD(bp_parms[2].info)]);
-
-  b1_config = &bp_parms[3];
-  nlc[0] = 0;
-  if(plci->B3_prot == 4
-  || plci->B3_prot == 5)
-  {
-    for (i=0;i<sizeof(T30_INFO);i++) nlc[i] = 0;
-    nlc[0] = sizeof(T30_INFO);
-    if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
-      ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI;
-    ((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff;
-    if(b1_config->length>=2)
-    {
-      ((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1])/2400);
-    }
-  }
-  b2_config = &bp_parms[4];
-
-
-  if (llc[1] == PIAFS_CRC)
-  {
-    if (plci->B3_prot != B3_TRANSPARENT)
-    {
-      return _B_STACK_NOT_SUPPORTED;
-    }
-    if(b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) {
-      return _WRONG_MESSAGE_FORMAT;
-    }
-    PUT_WORD(&dlc[1],plci->appl->MaxDataLength);
-    dlc[3] = 0; /* Addr A */
-    dlc[4] = 0; /* Addr B */
-    dlc[5] = 0; /* modulo mode */
-    dlc[6] = 0; /* window size */
-    if (b2_config->length >= 7){
-      dlc[ 7] = 7; 
-      dlc[ 8] = 0; 
-      dlc[ 9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */
-      dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */
-      dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */
-      dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */
-      dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */
-      dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */
-      dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */
-      dlc[ 0] = 15;
-      if(b2_config->length >= 8) { /* PIAFS control abilities */
-        dlc[ 7] = 10; 
-        dlc[16] = 2; /* Length of PIAFS extension */
-        dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */
-        dlc[18] = b2_config_parms[4].info[0]; /* value */
-        dlc[ 0] = 18;
-      }
-    }
-    else /* default values, 64K, variable, no compression */
-    {
-      dlc[ 7] = 7; 
-      dlc[ 8] = 0; 
-      dlc[ 9] = 0x03; /* PIAFS protocol Speed configuration */
-      dlc[10] = 0x03; /* V.42bis P0 */
-      dlc[11] = 0;    /* V.42bis P0 */
-      dlc[12] = 0;    /* V.42bis P1 */
-      dlc[13] = 0;    /* V.42bis P1 */
-      dlc[14] = 0;    /* V.42bis P2 */
-      dlc[15] = 0;    /* V.42bis P2 */
-    dlc[ 0] = 15;
-    }
-    add_p(plci, DLC, dlc);
-  }
-  else
-
-  if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS))
-  {
-    if (plci->B3_prot != B3_TRANSPARENT)
-      return _B_STACK_NOT_SUPPORTED;
-
-    dlc[0] = 6;
-    PUT_WORD (&dlc[1], GET_WORD (&dlc[1]) + 2);
-    dlc[3] = 0x08;
-    dlc[4] = 0x01;
-    dlc[5] = 127;
-    dlc[6] = 7;
-    if (b2_config->length != 0)
-    {
-      if((llc[1]==V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) {
-        return _WRONG_MESSAGE_FORMAT;
-      }
-      dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04));
-      dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01);
-      if (b2_config->info[3] != 128)
-      {
-        dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
-        return _B2_PARM_NOT_SUPPORTED;
-      }
-      dlc[5] = (byte)(b2_config->info[3] - 1);
-      dlc[6] = b2_config->info[4];
-      if(llc[1]==V120_V42BIS){
-        if (b2_config->length >= 10){
-          dlc[ 7] = 6; 
-          dlc[ 8] = 0; 
-          dlc[ 9] = b2_config_parms[4].info[0];
-          dlc[10] = b2_config_parms[4].info[1];
-          dlc[11] = b2_config_parms[5].info[0];
-          dlc[12] = b2_config_parms[5].info[1];
-          dlc[13] = b2_config_parms[6].info[0];
-          dlc[14] = b2_config_parms[6].info[1];
-          dlc[ 0] = 14;
-          dbug(1,dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
-          dbug(1,dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
-          dbug(1,dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
-        }
-        else {
-          dlc[ 6] = 14;
-        }
-      }
-    }
-  }
-  else
-  {
-    if(b2_config->length)
-    {
-      dbug(1,dprintf("B2-Config"));
-      if(llc[1]==X75_V42BIS){
-        if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms))
-        {
-          return _WRONG_MESSAGE_FORMAT;
-        }
-      }
-      else {
-        if(api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms))
-        {
-          return _WRONG_MESSAGE_FORMAT;
-        }
-      }
-          /* if B2 Protocol is LAPD, b2_config structure is different */
-      if(llc[1]==6)
-      {
-        dlc[0] = 4;
-        if(b2_config->length>=1) dlc[2] = b2_config->info[1];      /* TEI */
-        else dlc[2] = 0x01;
-        if( (b2_config->length>=2) && (plci->B2_prot==12) )
-        {
-          SAPI = b2_config->info[2];    /* SAPI */
-        }
-        dlc[1] = SAPI;
-        if( (b2_config->length>=3) && (b2_config->info[3]==128) )
-        {
-          dlc[3] = 127;      /* Mode */
-        }
-        else
-        {
-          dlc[3] = 7;        /* Mode */
-        }
-   
-        if(b2_config->length>=4) dlc[4] = b2_config->info[4];      /* Window */
-        else dlc[4] = 1;
-        dbug(1,dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
-        if(b2_config->length>5) return _B2_PARM_NOT_SUPPORTED;
-      }
-      else
-      {
-        dlc[0] = (byte)(b2_config_parms[4].length+6);
-        dlc[3] = b2_config->info[1];
-        dlc[4] = b2_config->info[2];
-        if(b2_config->info[3]!=8 && b2_config->info[3]!=128){
-          dbug(1,dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
-          return _B2_PARM_NOT_SUPPORTED;
-        }
-
-        dlc[5] = (byte)(b2_config->info[3]-1);
-        dlc[6] = b2_config->info[4];
-        if(dlc[6]>dlc[5]){
-          dbug(1,dprintf("2D-dlc= %x %x %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4], dlc[5], dlc[6]));
-          return _B2_PARM_NOT_SUPPORTED;
-        }
- 
-        if(llc[1]==X75_V42BIS) {
-          if (b2_config->length >= 10){
-            dlc[ 7] = 6; 
-            dlc[ 8] = 0; 
-            dlc[ 9] = b2_config_parms[4].info[0];
-            dlc[10] = b2_config_parms[4].info[1];
-            dlc[11] = b2_config_parms[5].info[0];
-            dlc[12] = b2_config_parms[5].info[1];
-            dlc[13] = b2_config_parms[6].info[0];
-            dlc[14] = b2_config_parms[6].info[1];
-            dlc[ 0] = 14;
-            dbug(1,dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
-            dbug(1,dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
-            dbug(1,dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
-          }
-          else {
-            dlc[ 6] = 14;
-          }
-
-        }
-        else {
-          PUT_WORD(&dlc[7], (word)b2_config_parms[4].length);
-          for(i=0; i<b2_config_parms[4].length; i++)
-            dlc[11+i] = b2_config_parms[4].info[1+i];
-        }
-      }
-    }
-  }
-  add_p(plci, DLC, dlc);
-
-  b3_config = &bp_parms[5];
-  if(b3_config->length)
-  {
-    if(plci->B3_prot == 4 
-    || plci->B3_prot == 5)
-    {
-      if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms))
-      {
-        return _WRONG_MESSAGE_FORMAT;
-      }
-      i = GET_WORD((byte   *)(b3_config_parms[0].info));
-      ((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) ||
-        ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte   *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0);
-      ((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte   *)b3_config_parms[1].info));
-      fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES;
-      if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6))
-        fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX;
-      if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
-      {
-
-        if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
-          & (1L << PRIVATE_FAX_PAPER_FORMATS))
-        {
-          ((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 |
-            T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 |
-            T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED;
-        }
-
- ((T30_INFO *)&nlc[1])->recording_properties =
-   T30_RECORDING_WIDTH_ISO_A3 |
-   (T30_RECORDING_LENGTH_UNLIMITED << 2) |
-   (T30_MIN_SCANLINE_TIME_00_00_00 << 4);
-      }
-      if(plci->B3_prot == 5)
-      {
-        if (i & 0x0002) /* Accept incoming fax-polling requests */
-          fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING;
-        if (i & 0x2000) /* Do not use MR compression */
-          fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING;
-        if (i & 0x4000) /* Do not use MMR compression */
-          fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING;
-        if (i & 0x8000) /* Do not use ECM */
-          fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM;
-        if (plci->fax_connect_info_length != 0)
-        {
-          ((T30_INFO *)&nlc[1])->resolution = ((T30_INFO   *)plci->fax_connect_info_buffer)->resolution;
-          ((T30_INFO *)&nlc[1])->data_format = ((T30_INFO   *)plci->fax_connect_info_buffer)->data_format;
-          ((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO   *)plci->fax_connect_info_buffer)->recording_properties;
-          fax_control_bits |= GET_WORD(&((T30_INFO   *)plci->fax_connect_info_buffer)->control_bits_low) &
-            (T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
-        }
-      }
-      /* copy station id to NLC */
-      for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++)
-      {
-        if(i<b3_config_parms[2].length)
-        {
-          ((T30_INFO *)&nlc[1])->station_id[i] = ((byte   *)b3_config_parms[2].info)[1+i];
-        }
-        else
-        {
-          ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
-        }
-      }
-      ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
-      /* copy head line to NLC */
-      if(b3_config_parms[3].length)
-      {
-
-        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
-        if (pos != 0)
-        {
-          if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
-            pos = 0;
-          else
-          {
-            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
-            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
-            len = (byte)b3_config_parms[2].length;
-            if (len > 20)
-              len = 20;
-            if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
-            {
-              for (i = 0; i < len; i++)
-                nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
-              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
-              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
-            }
-          }
-        }
-
-        len = (byte)b3_config_parms[3].length;
-        if (len > CAPI_MAX_HEAD_LINE_SPACE - pos)
-          len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos);
-        ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
-        nlc[0] += (byte)(pos + len);
-        for (i = 0; i < len; i++)
-          nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] =  ((byte   *)b3_config_parms[3].info)[1+i];
-      } else
-        ((T30_INFO *)&nlc[1])->head_line_len = 0;
-
-      plci->nsf_control_bits = 0;
-      if(plci->B3_prot == 5)
-      {
-        if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
-         && (GET_WORD((byte   *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */
-        {
-          plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
-        }
-        if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
-         && (GET_WORD((byte   *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */
-        {
-          plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD;
-        }
-        if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
-          & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
-        {
-        if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
-          & (1L << PRIVATE_FAX_SUB_SEP_PWD))
-        {
-          fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
-          if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
-            fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
-          }
-            len = nlc[0];
-          pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
-   if (pos < plci->fax_connect_info_length)
-   {
-     for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
-              nlc[++len] = plci->fax_connect_info_buffer[pos++];
-          }
-   else
-     nlc[++len] = 0;
-   if (pos < plci->fax_connect_info_length)
-   {
-     for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
-              nlc[++len] = plci->fax_connect_info_buffer[pos++];
-          }
-   else
-     nlc[++len] = 0;
-          if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id-1])
-            & (1L << PRIVATE_FAX_NONSTANDARD))
-          {
-     if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0))
-     {
-              if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos+1] >= 2))
-                plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos+2]);
-       for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
-                nlc[++len] = plci->fax_connect_info_buffer[pos++];
-            }
-     else
-     {
-              if(api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms))
-              {
-                dbug(1,dprintf("non-standard facilities info missing or wrong format"));
-                nlc[++len] = 0;
-              }
-       else
-       {
-                if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2))
-                  plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]);
-         nlc[++len] = (byte)(b3_config_parms[4].length);
-         for (i = 0; i < b3_config_parms[4].length; i++)
-    nlc[++len] = b3_config_parms[4].info[1+i];
-       }
-            }
-          }
-            nlc[0] = len;
-   if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
-    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
-   {
-            ((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG;
-          }
-        }
-      }
-
-      PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
-      len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
-      for (i = 0; i < len; i++)
-        plci->fax_connect_info_buffer[i] = nlc[1+i];
-      ((T30_INFO   *) plci->fax_connect_info_buffer)->head_line_len = 0;
-      i += ((T30_INFO *)&nlc[1])->head_line_len;
-      while (i < nlc[0])
-        plci->fax_connect_info_buffer[len++] = nlc[++i];
-      plci->fax_connect_info_length = len;
-    }
-    else
-    {
-      nlc[0] = 14;
-      if(b3_config->length!=16)
-        return _B3_PARM_NOT_SUPPORTED;
-      for(i=0; i<12; i++) nlc[1+i] = b3_config->info[1+i];
-      if(GET_WORD(&b3_config->info[13])!=8 && GET_WORD(&b3_config->info[13])!=128)
-        return _B3_PARM_NOT_SUPPORTED;
-      nlc[13] = b3_config->info[13];
-      if(GET_WORD(&b3_config->info[15])>=nlc[13])
-        return _B3_PARM_NOT_SUPPORTED;
-      nlc[14] = b3_config->info[15];
-    }
-  }
-  else
-  {
-    if (plci->B3_prot == 4 
-     || plci->B3_prot == 5 /*T.30 - FAX*/ ) return _B3_PARM_NOT_SUPPORTED;
-  }
-  add_p(plci, NLC, nlc);
-  return 0;
+	{
+		llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
+			llc2_out[GET_WORD(bp_parms[1].info)] : llc2_in[GET_WORD(bp_parms[1].info)];
+	}
+	llc[2] = llc3[GET_WORD(bp_parms[2].info)];
+
+	add_p(plci, LLC, llc);
+
+	dlc[0] = 2;
+	PUT_WORD(&dlc[1], plci->appl->MaxDataLength +
+		 header[GET_WORD(bp_parms[2].info)]);
+
+	b1_config = &bp_parms[3];
+	nlc[0] = 0;
+	if (plci->B3_prot == 4
+	    || plci->B3_prot == 5)
+	{
+		for (i = 0; i < sizeof(T30_INFO); i++) nlc[i] = 0;
+		nlc[0] = sizeof(T30_INFO);
+		if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
+			((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI;
+		((T30_INFO *)&nlc[1])->rate_div_2400 = 0xff;
+		if (b1_config->length >= 2)
+		{
+			((T30_INFO *)&nlc[1])->rate_div_2400 = (byte)(GET_WORD(&b1_config->info[1]) / 2400);
+		}
+	}
+	b2_config = &bp_parms[4];
+
+
+	if (llc[1] == PIAFS_CRC)
+	{
+		if (plci->B3_prot != B3_TRANSPARENT)
+		{
+			return _B_STACK_NOT_SUPPORTED;
+		}
+		if (b2_config->length && api_parse(&b2_config->info[1], (word)b2_config->length, "bwww", b2_config_parms)) {
+			return _WRONG_MESSAGE_FORMAT;
+		}
+		PUT_WORD(&dlc[1], plci->appl->MaxDataLength);
+		dlc[3] = 0; /* Addr A */
+		dlc[4] = 0; /* Addr B */
+		dlc[5] = 0; /* modulo mode */
+		dlc[6] = 0; /* window size */
+		if (b2_config->length >= 7) {
+			dlc[7] = 7;
+			dlc[8] = 0;
+			dlc[9] = b2_config_parms[0].info[0]; /* PIAFS protocol Speed configuration */
+			dlc[10] = b2_config_parms[1].info[0]; /* V.42bis P0 */
+			dlc[11] = b2_config_parms[1].info[1]; /* V.42bis P0 */
+			dlc[12] = b2_config_parms[2].info[0]; /* V.42bis P1 */
+			dlc[13] = b2_config_parms[2].info[1]; /* V.42bis P1 */
+			dlc[14] = b2_config_parms[3].info[0]; /* V.42bis P2 */
+			dlc[15] = b2_config_parms[3].info[1]; /* V.42bis P2 */
+			dlc[0] = 15;
+			if (b2_config->length >= 8) { /* PIAFS control abilities */
+				dlc[7] = 10;
+				dlc[16] = 2; /* Length of PIAFS extension */
+				dlc[17] = PIAFS_UDATA_ABILITIES; /* control (UDATA) ability */
+				dlc[18] = b2_config_parms[4].info[0]; /* value */
+				dlc[0] = 18;
+			}
+		}
+		else /* default values, 64K, variable, no compression */
+		{
+			dlc[7] = 7;
+			dlc[8] = 0;
+			dlc[9] = 0x03; /* PIAFS protocol Speed configuration */
+			dlc[10] = 0x03; /* V.42bis P0 */
+			dlc[11] = 0;    /* V.42bis P0 */
+			dlc[12] = 0;    /* V.42bis P1 */
+			dlc[13] = 0;    /* V.42bis P1 */
+			dlc[14] = 0;    /* V.42bis P2 */
+			dlc[15] = 0;    /* V.42bis P2 */
+			dlc[0] = 15;
+		}
+		add_p(plci, DLC, dlc);
+	}
+	else
+
+		if ((llc[1] == V120_L2) || (llc[1] == V120_V42BIS))
+		{
+			if (plci->B3_prot != B3_TRANSPARENT)
+				return _B_STACK_NOT_SUPPORTED;
+
+			dlc[0] = 6;
+			PUT_WORD(&dlc[1], GET_WORD(&dlc[1]) + 2);
+			dlc[3] = 0x08;
+			dlc[4] = 0x01;
+			dlc[5] = 127;
+			dlc[6] = 7;
+			if (b2_config->length != 0)
+			{
+				if ((llc[1] == V120_V42BIS) && api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms)) {
+					return _WRONG_MESSAGE_FORMAT;
+				}
+				dlc[3] = (byte)((b2_config->info[2] << 3) | ((b2_config->info[1] >> 5) & 0x04));
+				dlc[4] = (byte)((b2_config->info[1] << 1) | 0x01);
+				if (b2_config->info[3] != 128)
+				{
+					dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
+					return _B2_PARM_NOT_SUPPORTED;
+				}
+				dlc[5] = (byte)(b2_config->info[3] - 1);
+				dlc[6] = b2_config->info[4];
+				if (llc[1] == V120_V42BIS) {
+					if (b2_config->length >= 10) {
+						dlc[7] = 6;
+						dlc[8] = 0;
+						dlc[9] = b2_config_parms[4].info[0];
+						dlc[10] = b2_config_parms[4].info[1];
+						dlc[11] = b2_config_parms[5].info[0];
+						dlc[12] = b2_config_parms[5].info[1];
+						dlc[13] = b2_config_parms[6].info[0];
+						dlc[14] = b2_config_parms[6].info[1];
+						dlc[0] = 14;
+						dbug(1, dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
+						dbug(1, dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
+						dbug(1, dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
+					}
+					else {
+						dlc[6] = 14;
+					}
+				}
+			}
+		}
+		else
+		{
+			if (b2_config->length)
+			{
+				dbug(1, dprintf("B2-Config"));
+				if (llc[1] == X75_V42BIS) {
+					if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbwww", b2_config_parms))
+					{
+						return _WRONG_MESSAGE_FORMAT;
+					}
+				}
+				else {
+					if (api_parse(&b2_config->info[1], (word)b2_config->length, "bbbbs", b2_config_parms))
+					{
+						return _WRONG_MESSAGE_FORMAT;
+					}
+				}
+				/* if B2 Protocol is LAPD, b2_config structure is different */
+				if (llc[1] == 6)
+				{
+					dlc[0] = 4;
+					if (b2_config->length >= 1) dlc[2] = b2_config->info[1];      /* TEI */
+					else dlc[2] = 0x01;
+					if ((b2_config->length >= 2) && (plci->B2_prot == 12))
+					{
+						SAPI = b2_config->info[2];    /* SAPI */
+					}
+					dlc[1] = SAPI;
+					if ((b2_config->length >= 3) && (b2_config->info[3] == 128))
+					{
+						dlc[3] = 127;      /* Mode */
+					}
+					else
+					{
+						dlc[3] = 7;        /* Mode */
+					}
+
+					if (b2_config->length >= 4) dlc[4] = b2_config->info[4];      /* Window */
+					else dlc[4] = 1;
+					dbug(1, dprintf("D-dlc[%d]=%x,%x,%x,%x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
+					if (b2_config->length > 5) return _B2_PARM_NOT_SUPPORTED;
+				}
+				else
+				{
+					dlc[0] = (byte)(b2_config_parms[4].length + 6);
+					dlc[3] = b2_config->info[1];
+					dlc[4] = b2_config->info[2];
+					if (b2_config->info[3] != 8 && b2_config->info[3] != 128) {
+						dbug(1, dprintf("1D-dlc= %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4]));
+						return _B2_PARM_NOT_SUPPORTED;
+					}
+
+					dlc[5] = (byte)(b2_config->info[3] - 1);
+					dlc[6] = b2_config->info[4];
+					if (dlc[6] > dlc[5]) {
+						dbug(1, dprintf("2D-dlc= %x %x %x %x %x %x %x", dlc[0], dlc[1], dlc[2], dlc[3], dlc[4], dlc[5], dlc[6]));
+						return _B2_PARM_NOT_SUPPORTED;
+					}
+
+					if (llc[1] == X75_V42BIS) {
+						if (b2_config->length >= 10) {
+							dlc[7] = 6;
+							dlc[8] = 0;
+							dlc[9] = b2_config_parms[4].info[0];
+							dlc[10] = b2_config_parms[4].info[1];
+							dlc[11] = b2_config_parms[5].info[0];
+							dlc[12] = b2_config_parms[5].info[1];
+							dlc[13] = b2_config_parms[6].info[0];
+							dlc[14] = b2_config_parms[6].info[1];
+							dlc[0] = 14;
+							dbug(1, dprintf("b2_config_parms[4].info[0] [1]:  %x %x", b2_config_parms[4].info[0], b2_config_parms[4].info[1]));
+							dbug(1, dprintf("b2_config_parms[5].info[0] [1]:  %x %x", b2_config_parms[5].info[0], b2_config_parms[5].info[1]));
+							dbug(1, dprintf("b2_config_parms[6].info[0] [1]:  %x %x", b2_config_parms[6].info[0], b2_config_parms[6].info[1]));
+						}
+						else {
+							dlc[6] = 14;
+						}
+
+					}
+					else {
+						PUT_WORD(&dlc[7], (word)b2_config_parms[4].length);
+						for (i = 0; i < b2_config_parms[4].length; i++)
+							dlc[11 + i] = b2_config_parms[4].info[1 + i];
+					}
+				}
+			}
+		}
+	add_p(plci, DLC, dlc);
+
+	b3_config = &bp_parms[5];
+	if (b3_config->length)
+	{
+		if (plci->B3_prot == 4
+		    || plci->B3_prot == 5)
+		{
+			if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwss", b3_config_parms))
+			{
+				return _WRONG_MESSAGE_FORMAT;
+			}
+			i = GET_WORD((byte *)(b3_config_parms[0].info));
+			((T30_INFO *)&nlc[1])->resolution = (byte)(((i & 0x0001) ||
+								    ((plci->B3_prot == 4) && (((byte)(GET_WORD((byte *)b3_config_parms[1].info))) != 5))) ? T30_RESOLUTION_R8_0770_OR_200 : 0);
+			((T30_INFO *)&nlc[1])->data_format = (byte)(GET_WORD((byte *)b3_config_parms[1].info));
+			fax_control_bits = T30_CONTROL_BIT_ALL_FEATURES;
+			if ((((T30_INFO *)&nlc[1])->rate_div_2400 != 0) && (((T30_INFO *)&nlc[1])->rate_div_2400 <= 6))
+				fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_V34FAX;
+			if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
+			{
+
+				if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
+				    & (1L << PRIVATE_FAX_PAPER_FORMATS))
+				{
+					((T30_INFO *)&nlc[1])->resolution |= T30_RESOLUTION_R8_1540 |
+						T30_RESOLUTION_R16_1540_OR_400 | T30_RESOLUTION_300_300 |
+						T30_RESOLUTION_INCH_BASED | T30_RESOLUTION_METRIC_BASED;
+				}
+
+				((T30_INFO *)&nlc[1])->recording_properties =
+					T30_RECORDING_WIDTH_ISO_A3 |
+					(T30_RECORDING_LENGTH_UNLIMITED << 2) |
+					(T30_MIN_SCANLINE_TIME_00_00_00 << 4);
+			}
+			if (plci->B3_prot == 5)
+			{
+				if (i & 0x0002) /* Accept incoming fax-polling requests */
+					fax_control_bits |= T30_CONTROL_BIT_ACCEPT_POLLING;
+				if (i & 0x2000) /* Do not use MR compression */
+					fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_2D_CODING;
+				if (i & 0x4000) /* Do not use MMR compression */
+					fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_T6_CODING;
+				if (i & 0x8000) /* Do not use ECM */
+					fax_control_bits &= ~T30_CONTROL_BIT_ENABLE_ECM;
+				if (plci->fax_connect_info_length != 0)
+				{
+					((T30_INFO *)&nlc[1])->resolution = ((T30_INFO *)plci->fax_connect_info_buffer)->resolution;
+					((T30_INFO *)&nlc[1])->data_format = ((T30_INFO *)plci->fax_connect_info_buffer)->data_format;
+					((T30_INFO *)&nlc[1])->recording_properties = ((T30_INFO *)plci->fax_connect_info_buffer)->recording_properties;
+					fax_control_bits |= GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low) &
+						(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
+				}
+			}
+			/* copy station id to NLC */
+			for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
+			{
+				if (i < b3_config_parms[2].length)
+				{
+					((T30_INFO *)&nlc[1])->station_id[i] = ((byte *)b3_config_parms[2].info)[1 + i];
+				}
+				else
+				{
+					((T30_INFO *)&nlc[1])->station_id[i] = ' ';
+				}
+			}
+			((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
+			/* copy head line to NLC */
+			if (b3_config_parms[3].length)
+			{
+
+				pos = (byte)(fax_head_line_time(&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
+				if (pos != 0)
+				{
+					if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
+						pos = 0;
+					else
+					{
+						nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+						nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+						len = (byte)b3_config_parms[2].length;
+						if (len > 20)
+							len = 20;
+						if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
+						{
+							for (i = 0; i < len; i++)
+								nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1 + i];
+							nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+							nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+						}
+					}
+				}
+
+				len = (byte)b3_config_parms[3].length;
+				if (len > CAPI_MAX_HEAD_LINE_SPACE - pos)
+					len = (byte)(CAPI_MAX_HEAD_LINE_SPACE - pos);
+				((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
+				nlc[0] += (byte)(pos + len);
+				for (i = 0; i < len; i++)
+					nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] =  ((byte *)b3_config_parms[3].info)[1 + i];
+			} else
+				((T30_INFO *)&nlc[1])->head_line_len = 0;
+
+			plci->nsf_control_bits = 0;
+			if (plci->B3_prot == 5)
+			{
+				if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
+				    && (GET_WORD((byte *)b3_config_parms[1].info) & 0x8000)) /* Private SUB/SEP/PWD enable */
+				{
+					plci->requested_options |= 1L << PRIVATE_FAX_SUB_SEP_PWD;
+				}
+				if ((plci->adapter->man_profile.private_options & (1L << PRIVATE_FAX_NONSTANDARD))
+				    && (GET_WORD((byte *)b3_config_parms[1].info) & 0x4000)) /* Private non-standard facilities enable */
+				{
+					plci->requested_options |= 1L << PRIVATE_FAX_NONSTANDARD;
+				}
+				if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
+				    & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
+				{
+					if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
+					    & (1L << PRIVATE_FAX_SUB_SEP_PWD))
+					{
+						fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SUBADDRESS | T30_CONTROL_BIT_ACCEPT_PASSWORD;
+						if (fax_control_bits & T30_CONTROL_BIT_ACCEPT_POLLING)
+							fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
+					}
+					len = nlc[0];
+					pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
+					if (pos < plci->fax_connect_info_length)
+					{
+						for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
+							nlc[++len] = plci->fax_connect_info_buffer[pos++];
+					}
+					else
+						nlc[++len] = 0;
+					if (pos < plci->fax_connect_info_length)
+					{
+						for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
+							nlc[++len] = plci->fax_connect_info_buffer[pos++];
+					}
+					else
+						nlc[++len] = 0;
+					if ((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[plci->appl->Id - 1])
+					    & (1L << PRIVATE_FAX_NONSTANDARD))
+					{
+						if ((pos < plci->fax_connect_info_length) && (plci->fax_connect_info_buffer[pos] != 0))
+						{
+							if ((plci->fax_connect_info_buffer[pos] >= 3) && (plci->fax_connect_info_buffer[pos + 1] >= 2))
+								plci->nsf_control_bits = GET_WORD(&plci->fax_connect_info_buffer[pos + 2]);
+							for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
+								nlc[++len] = plci->fax_connect_info_buffer[pos++];
+						}
+						else
+						{
+							if (api_parse(&b3_config->info[1], (word)b3_config->length, "wwsss", b3_config_parms))
+							{
+								dbug(1, dprintf("non-standard facilities info missing or wrong format"));
+								nlc[++len] = 0;
+							}
+							else
+							{
+								if ((b3_config_parms[4].length >= 3) && (b3_config_parms[4].info[1] >= 2))
+									plci->nsf_control_bits = GET_WORD(&b3_config_parms[4].info[2]);
+								nlc[++len] = (byte)(b3_config_parms[4].length);
+								for (i = 0; i < b3_config_parms[4].length; i++)
+									nlc[++len] = b3_config_parms[4].info[1 + i];
+							}
+						}
+					}
+					nlc[0] = len;
+					if ((plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
+					    && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
+					{
+						((T30_INFO *)&nlc[1])->operating_mode = T30_OPERATING_MODE_CAPI_NEG;
+					}
+				}
+			}
+
+			PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
+			len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
+			for (i = 0; i < len; i++)
+				plci->fax_connect_info_buffer[i] = nlc[1 + i];
+			((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
+			i += ((T30_INFO *)&nlc[1])->head_line_len;
+			while (i < nlc[0])
+				plci->fax_connect_info_buffer[len++] = nlc[++i];
+			plci->fax_connect_info_length = len;
+		}
+		else
+		{
+			nlc[0] = 14;
+			if (b3_config->length != 16)
+				return _B3_PARM_NOT_SUPPORTED;
+			for (i = 0; i < 12; i++) nlc[1 + i] = b3_config->info[1 + i];
+			if (GET_WORD(&b3_config->info[13]) != 8 && GET_WORD(&b3_config->info[13]) != 128)
+				return _B3_PARM_NOT_SUPPORTED;
+			nlc[13] = b3_config->info[13];
+			if (GET_WORD(&b3_config->info[15]) >= nlc[13])
+				return _B3_PARM_NOT_SUPPORTED;
+			nlc[14] = b3_config->info[15];
+		}
+	}
+	else
+	{
+		if (plci->B3_prot == 4
+		    || plci->B3_prot == 5 /*T.30 - FAX*/) return _B3_PARM_NOT_SUPPORTED;
+	}
+	add_p(plci, NLC, nlc);
+	return 0;
 }
 
 /*----------------------------------------------------------------*/
@@ -8567,136 +8567,136 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
 /*      B3 Configuration for modem:                               */
 /*          empty                                                 */
 /*----------------------------------------------------------------*/
-static word add_modem_b23 (PLCI  * plci, API_PARSE* bp_parms)
-{
-  static byte lli[12] = {1,1};
-  static byte llc[3] = {2,0,0};
-  static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-    API_PARSE mdm_config[2];
-  word i;
-  word b2_config = 0;
-
-  for(i=0;i<2;i++) mdm_config[i].length = 0;
-  for(i=0;i<sizeof(dlc);i++) dlc[i] = 0;
-
-  if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
-    && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION))
-   || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE)
-    && (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT)))
-  {
-    return (_B_STACK_NOT_SUPPORTED);
-  }
-  if ((GET_WORD(bp_parms[2].info) != B3_MODEM)
-   && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT))
-  {
-    return (_B_STACK_NOT_SUPPORTED);
-  }
-
-  plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
-  plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
-
-  if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length)
-  {
-    if (api_parse (&bp_parms[4].info[1],
-                  (word)bp_parms[4].length, "w",
-                  mdm_config))
-    {
-      return (_WRONG_MESSAGE_FORMAT);
-    }
-    b2_config = GET_WORD(mdm_config[0].info);
-  }
-
-  /* OK, L2 is modem */
-
-  lli[0] = 1;
-  lli[1] = 1;
-  if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
-    lli[1] |= 2;
-  if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
-    lli[1] |= 4;
-
-  if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
-    lli[1] |= 0x10;
-    if (plci->rx_dma_descriptor <= 0) {
-      plci->rx_dma_descriptor=diva_get_dma_descriptor(plci,&plci->rx_dma_magic);
-      if (plci->rx_dma_descriptor >= 0)
-        plci->rx_dma_descriptor++;
-    }
-    if (plci->rx_dma_descriptor > 0) {
-      lli[1] |= 0x40;
-      lli[0] = 6;
-      lli[2] = (byte)(plci->rx_dma_descriptor - 1);
-      lli[3] = (byte)plci->rx_dma_magic;
-      lli[4] = (byte)(plci->rx_dma_magic >>  8);
-      lli[5] = (byte)(plci->rx_dma_magic >> 16);
-      lli[6] = (byte)(plci->rx_dma_magic >> 24);
-    }
-  }
-
-  if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
-    lli[1] |= 0x20;
-  }
-
-  llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
-    /*V42*/ 10 : /*V42_IN*/ 9;
-  llc[2] = 4;                      /* pass L3 always transparent */
-  add_p(plci, LLI, lli);
-  add_p(plci, LLC, llc);
-  i =  1;
-  PUT_WORD (&dlc[i], plci->appl->MaxDataLength);
-  i += 2;
-  if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION)
-  {
-    if (bp_parms[4].length)
-  {
-    dbug(1, dprintf("MDM b2_config=%02x", b2_config));
-    dlc[i++] = 3; /* Addr A */
-    dlc[i++] = 1; /* Addr B */
-    dlc[i++] = 7; /* modulo mode */
-    dlc[i++] = 7; /* window size */
-    dlc[i++] = 0; /* XID len Lo  */
-    dlc[i++] = 0; /* XID len Hi  */
-
-    if (b2_config & MDM_B2_DISABLE_V42bis)
-    {
-      dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS;
-    }
-    if (b2_config & MDM_B2_DISABLE_MNP)
-    {
-      dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5;
-    }
-    if (b2_config & MDM_B2_DISABLE_TRANS)
-    {
-      dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL;
-    }
-    if (b2_config & MDM_B2_DISABLE_V42)
-    {
-      dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT;
-    }
-    if (b2_config & MDM_B2_DISABLE_COMP)
-    {
-      dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION;
-    }
-    i++;
-  }
-  }
-  else
-  {
-    dlc[i++] = 3; /* Addr A */
-    dlc[i++] = 1; /* Addr B */
-    dlc[i++] = 7; /* modulo mode */
-    dlc[i++] = 7; /* window size */
-    dlc[i++] = 0; /* XID len Lo  */
-    dlc[i++] = 0; /* XID len Hi  */
-    dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS |
-               DLC_MODEMPROT_DISABLE_MNP_MNP5 |
-               DLC_MODEMPROT_DISABLE_V42_DETECT |
-               DLC_MODEMPROT_DISABLE_COMPRESSION;
-  }
-  dlc[0] = (byte)(i - 1);
+static word add_modem_b23(PLCI *plci, API_PARSE *bp_parms)
+{
+	static byte lli[12] = {1,1};
+	static byte llc[3] = {2,0,0};
+	static byte dlc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+	API_PARSE mdm_config[2];
+	word i;
+	word b2_config = 0;
+
+	for (i = 0; i < 2; i++) mdm_config[i].length = 0;
+	for (i = 0; i < sizeof(dlc); i++) dlc[i] = 0;
+
+	if (((GET_WORD(bp_parms[0].info) == B1_MODEM_ALL_NEGOTIATE)
+	     && (GET_WORD(bp_parms[1].info) != B2_MODEM_EC_COMPRESSION))
+	    || ((GET_WORD(bp_parms[0].info) != B1_MODEM_ALL_NEGOTIATE)
+		&& (GET_WORD(bp_parms[1].info) != B2_TRANSPARENT)))
+	{
+		return (_B_STACK_NOT_SUPPORTED);
+	}
+	if ((GET_WORD(bp_parms[2].info) != B3_MODEM)
+	    && (GET_WORD(bp_parms[2].info) != B3_TRANSPARENT))
+	{
+		return (_B_STACK_NOT_SUPPORTED);
+	}
+
+	plci->B2_prot = (byte) GET_WORD(bp_parms[1].info);
+	plci->B3_prot = (byte) GET_WORD(bp_parms[2].info);
+
+	if ((GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION) && bp_parms[4].length)
+	{
+		if (api_parse(&bp_parms[4].info[1],
+			      (word)bp_parms[4].length, "w",
+			      mdm_config))
+		{
+			return (_WRONG_MESSAGE_FORMAT);
+		}
+		b2_config = GET_WORD(mdm_config[0].info);
+	}
+
+	/* OK, L2 is modem */
+
+	lli[0] = 1;
+	lli[1] = 1;
+	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)
+		lli[1] |= 2;
+	if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_OOB_CHANNEL)
+		lli[1] |= 4;
+
+	if ((lli[1] & 0x02) && (diva_xdi_extended_features & DIVA_CAPI_USE_CMA)) {
+		lli[1] |= 0x10;
+		if (plci->rx_dma_descriptor <= 0) {
+			plci->rx_dma_descriptor = diva_get_dma_descriptor(plci, &plci->rx_dma_magic);
+			if (plci->rx_dma_descriptor >= 0)
+				plci->rx_dma_descriptor++;
+		}
+		if (plci->rx_dma_descriptor > 0) {
+			lli[1] |= 0x40;
+			lli[0] = 6;
+			lli[2] = (byte)(plci->rx_dma_descriptor - 1);
+			lli[3] = (byte)plci->rx_dma_magic;
+			lli[4] = (byte)(plci->rx_dma_magic >>  8);
+			lli[5] = (byte)(plci->rx_dma_magic >> 16);
+			lli[6] = (byte)(plci->rx_dma_magic >> 24);
+		}
+	}
+
+	if (DIVA_CAPI_SUPPORTS_NO_CANCEL(plci->adapter)) {
+		lli[1] |= 0x20;
+	}
+
+	llc[1] = (plci->call_dir & (CALL_DIR_ORIGINATE | CALL_DIR_FORCE_OUTG_NL)) ?
+		/*V42*/ 10 : /*V42_IN*/ 9;
+	llc[2] = 4;                      /* pass L3 always transparent */
+	add_p(plci, LLI, lli);
+	add_p(plci, LLC, llc);
+	i =  1;
+	PUT_WORD(&dlc[i], plci->appl->MaxDataLength);
+	i += 2;
+	if (GET_WORD(bp_parms[1].info) == B2_MODEM_EC_COMPRESSION)
+	{
+		if (bp_parms[4].length)
+		{
+			dbug(1, dprintf("MDM b2_config=%02x", b2_config));
+			dlc[i++] = 3; /* Addr A */
+			dlc[i++] = 1; /* Addr B */
+			dlc[i++] = 7; /* modulo mode */
+			dlc[i++] = 7; /* window size */
+			dlc[i++] = 0; /* XID len Lo  */
+			dlc[i++] = 0; /* XID len Hi  */
+
+			if (b2_config & MDM_B2_DISABLE_V42bis)
+			{
+				dlc[i] |= DLC_MODEMPROT_DISABLE_V42_V42BIS;
+			}
+			if (b2_config & MDM_B2_DISABLE_MNP)
+			{
+				dlc[i] |= DLC_MODEMPROT_DISABLE_MNP_MNP5;
+			}
+			if (b2_config & MDM_B2_DISABLE_TRANS)
+			{
+				dlc[i] |= DLC_MODEMPROT_REQUIRE_PROTOCOL;
+			}
+			if (b2_config & MDM_B2_DISABLE_V42)
+			{
+				dlc[i] |= DLC_MODEMPROT_DISABLE_V42_DETECT;
+			}
+			if (b2_config & MDM_B2_DISABLE_COMP)
+			{
+				dlc[i] |= DLC_MODEMPROT_DISABLE_COMPRESSION;
+			}
+			i++;
+		}
+	}
+	else
+	{
+		dlc[i++] = 3; /* Addr A */
+		dlc[i++] = 1; /* Addr B */
+		dlc[i++] = 7; /* modulo mode */
+		dlc[i++] = 7; /* window size */
+		dlc[i++] = 0; /* XID len Lo  */
+		dlc[i++] = 0; /* XID len Hi  */
+		dlc[i++] = DLC_MODEMPROT_DISABLE_V42_V42BIS |
+			DLC_MODEMPROT_DISABLE_MNP_MNP5 |
+			DLC_MODEMPROT_DISABLE_V42_DETECT |
+			DLC_MODEMPROT_DISABLE_COMPRESSION;
+	}
+	dlc[0] = (byte)(i - 1);
 /* HexDump ("DLC", sizeof(dlc), &dlc[0]); */
-  add_p(plci, DLC, dlc);
-  return (0);
+	add_p(plci, DLC, dlc);
+	return (0);
 }
 
 
@@ -8706,20 +8706,20 @@ static word add_modem_b23 (PLCI  * plci, API_PARSE* bp_parms)
 
 static void sig_req(PLCI *plci, byte req, byte Id)
 {
-  if(!plci) return;
-  if(plci->adapter->adapter_disabled) return;
-  dbug(1,dprintf("sig_req(%x)",req));
-  if (req == REMOVE)
-    plci->sig_remove_id = plci->Sig.Id;
-  if(plci->req_in==plci->req_in_start) {
-    plci->req_in +=2;
-    plci->RBuffer[plci->req_in++] = 0;
-  }
-  PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start-2);
-  plci->RBuffer[plci->req_in++] = Id;   /* sig/nl flag */
-  plci->RBuffer[plci->req_in++] = req;  /* request */
-  plci->RBuffer[plci->req_in++] = 0;    /* channel */
-  plci->req_in_start = plci->req_in;
+	if (!plci) return;
+	if (plci->adapter->adapter_disabled) return;
+	dbug(1, dprintf("sig_req(%x)", req));
+	if (req == REMOVE)
+		plci->sig_remove_id = plci->Sig.Id;
+	if (plci->req_in == plci->req_in_start) {
+		plci->req_in += 2;
+		plci->RBuffer[plci->req_in++] = 0;
+	}
+	PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2);
+	plci->RBuffer[plci->req_in++] = Id;   /* sig/nl flag */
+	plci->RBuffer[plci->req_in++] = req;  /* request */
+	plci->RBuffer[plci->req_in++] = 0;    /* channel */
+	plci->req_in_start = plci->req_in;
 }
 
 /*------------------------------------------------------------------*/
@@ -8728,198 +8728,198 @@ static void sig_req(PLCI *plci, byte req, byte Id)
 
 static void nl_req_ncci(PLCI *plci, byte req, byte ncci)
 {
-  if(!plci) return;
-  if(plci->adapter->adapter_disabled) return;
-  dbug(1,dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci));
-  if (req == REMOVE)
-  {
-    plci->nl_remove_id = plci->NL.Id;
-    ncci_remove (plci, 0, (byte)(ncci != 0));
-    ncci = 0;
-  }
-  if(plci->req_in==plci->req_in_start) {
-    plci->req_in +=2;
-    plci->RBuffer[plci->req_in++] = 0;
-  }
-  PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start-2);
-  plci->RBuffer[plci->req_in++] = 1;    /* sig/nl flag */
-  plci->RBuffer[plci->req_in++] = req;  /* request */
-  plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci];   /* channel */
-  plci->req_in_start = plci->req_in;
+	if (!plci) return;
+	if (plci->adapter->adapter_disabled) return;
+	dbug(1, dprintf("nl_req %02x %02x %02x", plci->Id, req, ncci));
+	if (req == REMOVE)
+	{
+		plci->nl_remove_id = plci->NL.Id;
+		ncci_remove(plci, 0, (byte)(ncci != 0));
+		ncci = 0;
+	}
+	if (plci->req_in == plci->req_in_start) {
+		plci->req_in += 2;
+		plci->RBuffer[plci->req_in++] = 0;
+	}
+	PUT_WORD(&plci->RBuffer[plci->req_in_start], plci->req_in-plci->req_in_start - 2);
+	plci->RBuffer[plci->req_in++] = 1;    /* sig/nl flag */
+	plci->RBuffer[plci->req_in++] = req;  /* request */
+	plci->RBuffer[plci->req_in++] = plci->adapter->ncci_ch[ncci];   /* channel */
+	plci->req_in_start = plci->req_in;
 }
 
 static void send_req(PLCI *plci)
 {
-  ENTITY   * e;
-  word l;
+	ENTITY *e;
+	word l;
 /*  word i; */
 
-  if(!plci) return;
-  if(plci->adapter->adapter_disabled) return;
-  channel_xmit_xon (plci);
-
-        /* if nothing to do, return */
-  if(plci->req_in==plci->req_out) return;
-  dbug(1,dprintf("send_req(in=%d,out=%d)",plci->req_in,plci->req_out));
-
-  if(plci->nl_req || plci->sig_req) return;
-
-  l = GET_WORD(&plci->RBuffer[plci->req_out]);
-  plci->req_out += 2;
-  plci->XData[0].P = &plci->RBuffer[plci->req_out];
-  plci->req_out += l;
-  if(plci->RBuffer[plci->req_out]==1)
-  {
-    e = &plci->NL;
-    plci->req_out++;
-    e->Req = plci->nl_req = plci->RBuffer[plci->req_out++];
-    e->ReqCh = plci->RBuffer[plci->req_out++];
-    if(!(e->Id & 0x1f))
-    {
-      e->Id = NL_ID;
-      plci->RBuffer[plci->req_out-4] = CAI;
-      plci->RBuffer[plci->req_out-3] = 1;
-      plci->RBuffer[plci->req_out-2] = (plci->Sig.Id==0xff) ? 0 : plci->Sig.Id;
-      plci->RBuffer[plci->req_out-1] = 0;
-      l+=3;
-      plci->nl_global_req = plci->nl_req;
-    }
-    dbug(1,dprintf("%x:NLREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh));
-  }
-  else
-  {
-    e = &plci->Sig;
-    if(plci->RBuffer[plci->req_out])
-      e->Id = plci->RBuffer[plci->req_out];
-    plci->req_out++;
-    e->Req = plci->sig_req = plci->RBuffer[plci->req_out++];
-    e->ReqCh = plci->RBuffer[plci->req_out++];
-    if(!(e->Id & 0x1f))
-      plci->sig_global_req = plci->sig_req;
-    dbug(1,dprintf("%x:SIGREQ(%x:%x:%x)",plci->adapter->Id,e->Id,e->Req,e->ReqCh));
-  }
-  plci->XData[0].PLength = l;
-  e->X = plci->XData;
-  plci->adapter->request(e);
-  dbug(1,dprintf("send_ok"));
+	if (!plci) return;
+	if (plci->adapter->adapter_disabled) return;
+	channel_xmit_xon(plci);
+
+	/* if nothing to do, return */
+	if (plci->req_in == plci->req_out) return;
+	dbug(1, dprintf("send_req(in=%d,out=%d)", plci->req_in, plci->req_out));
+
+	if (plci->nl_req || plci->sig_req) return;
+
+	l = GET_WORD(&plci->RBuffer[plci->req_out]);
+	plci->req_out += 2;
+	plci->XData[0].P = &plci->RBuffer[plci->req_out];
+	plci->req_out += l;
+	if (plci->RBuffer[plci->req_out] == 1)
+	{
+		e = &plci->NL;
+		plci->req_out++;
+		e->Req = plci->nl_req = plci->RBuffer[plci->req_out++];
+		e->ReqCh = plci->RBuffer[plci->req_out++];
+		if (!(e->Id & 0x1f))
+		{
+			e->Id = NL_ID;
+			plci->RBuffer[plci->req_out - 4] = CAI;
+			plci->RBuffer[plci->req_out - 3] = 1;
+			plci->RBuffer[plci->req_out - 2] = (plci->Sig.Id == 0xff) ? 0 : plci->Sig.Id;
+			plci->RBuffer[plci->req_out - 1] = 0;
+			l += 3;
+			plci->nl_global_req = plci->nl_req;
+		}
+		dbug(1, dprintf("%x:NLREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh));
+	}
+	else
+	{
+		e = &plci->Sig;
+		if (plci->RBuffer[plci->req_out])
+			e->Id = plci->RBuffer[plci->req_out];
+		plci->req_out++;
+		e->Req = plci->sig_req = plci->RBuffer[plci->req_out++];
+		e->ReqCh = plci->RBuffer[plci->req_out++];
+		if (!(e->Id & 0x1f))
+			plci->sig_global_req = plci->sig_req;
+		dbug(1, dprintf("%x:SIGREQ(%x:%x:%x)", plci->adapter->Id, e->Id, e->Req, e->ReqCh));
+	}
+	plci->XData[0].PLength = l;
+	e->X = plci->XData;
+	plci->adapter->request(e);
+	dbug(1, dprintf("send_ok"));
 }
 
 static void send_data(PLCI *plci)
 {
-  DIVA_CAPI_ADAPTER   * a;
-  DATA_B3_DESC   * data;
-  NCCI   *ncci_ptr;
-  word ncci;
-
-  if (!plci->nl_req && plci->ncci_ring_list)
-  {
-    a = plci->adapter;
-    ncci = plci->ncci_ring_list;
-    do
-    {
-      ncci = a->ncci_next[ncci];
-      ncci_ptr = &(a->ncci[ncci]);
-      if (!(a->ncci_ch[ncci]
-         && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING)))
-      {
-        if (ncci_ptr->data_pending)
-        {
-          if ((a->ncci_state[ncci] == CONNECTED)
-           || (a->ncci_state[ncci] == INC_ACT_PENDING)
-           || (plci->send_disc == ncci))
-          {
-            data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
-            if ((plci->B2_prot == B2_V120_ASYNC)
-             || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
-             || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))
-            {
-              plci->NData[1].P = TransmitBufferGet (plci->appl, data->P);
-              plci->NData[1].PLength = data->Length;
-              if (data->Flags & 0x10)
-                plci->NData[0].P = v120_break_header;
-              else
-                plci->NData[0].P = v120_default_header;
-              plci->NData[0].PLength = 1 ;
-              plci->NL.XNum = 2;
-              plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA);
-            }
-            else
-            {
-              plci->NData[0].P = TransmitBufferGet (plci->appl, data->P);
-              plci->NData[0].PLength = data->Length;
-              if (data->Flags & 0x10)
-                plci->NL.Req = plci->nl_req = (byte)N_UDATA;
-
-              else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01))
-                plci->NL.Req = plci->nl_req = (byte)N_BDATA;
-
-              else
-                plci->NL.Req = plci->nl_req = (byte)((data->Flags&0x07)<<4 |N_DATA);
-            }
-            plci->NL.X = plci->NData;
-            plci->NL.ReqCh = a->ncci_ch[ncci];
-            dbug(1,dprintf("%x:DREQ(%x:%x)",a->Id,plci->NL.Id,plci->NL.Req));
-            plci->data_sent = true;
-            plci->data_sent_ptr = data->P;
-            a->request(&plci->NL);
-          }
-          else {
-            cleanup_ncci_data (plci, ncci);
-          }
-        }
-        else if (plci->send_disc == ncci)
-        {
-          /* dprintf("N_DISC"); */
-          plci->NData[0].PLength = 0;
-          plci->NL.ReqCh = a->ncci_ch[ncci];
-          plci->NL.Req = plci->nl_req = N_DISC;
-          a->request(&plci->NL);
-          plci->command = _DISCONNECT_B3_R;
-          plci->send_disc = 0;
-        }
-      }
-    } while (!plci->nl_req && (ncci != plci->ncci_ring_list));
-    plci->ncci_ring_list = ncci;
-  }
+	DIVA_CAPI_ADAPTER *a;
+	DATA_B3_DESC *data;
+	NCCI   *ncci_ptr;
+	word ncci;
+
+	if (!plci->nl_req && plci->ncci_ring_list)
+	{
+		a = plci->adapter;
+		ncci = plci->ncci_ring_list;
+		do
+		{
+			ncci = a->ncci_next[ncci];
+			ncci_ptr = &(a->ncci[ncci]);
+			if (!(a->ncci_ch[ncci]
+			      && (a->ch_flow_control[a->ncci_ch[ncci]] & N_OK_FC_PENDING)))
+			{
+				if (ncci_ptr->data_pending)
+				{
+					if ((a->ncci_state[ncci] == CONNECTED)
+					    || (a->ncci_state[ncci] == INC_ACT_PENDING)
+					    || (plci->send_disc == ncci))
+					{
+						data = &(ncci_ptr->DBuffer[ncci_ptr->data_out]);
+						if ((plci->B2_prot == B2_V120_ASYNC)
+						    || (plci->B2_prot == B2_V120_ASYNC_V42BIS)
+						    || (plci->B2_prot == B2_V120_BIT_TRANSPARENT))
+						{
+							plci->NData[1].P = TransmitBufferGet(plci->appl, data->P);
+							plci->NData[1].PLength = data->Length;
+							if (data->Flags & 0x10)
+								plci->NData[0].P = v120_break_header;
+							else
+								plci->NData[0].P = v120_default_header;
+							plci->NData[0].PLength = 1;
+							plci->NL.XNum = 2;
+							plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA);
+						}
+						else
+						{
+							plci->NData[0].P = TransmitBufferGet(plci->appl, data->P);
+							plci->NData[0].PLength = data->Length;
+							if (data->Flags & 0x10)
+								plci->NL.Req = plci->nl_req = (byte)N_UDATA;
+
+							else if ((plci->B3_prot == B3_RTP) && (data->Flags & 0x01))
+								plci->NL.Req = plci->nl_req = (byte)N_BDATA;
+
+							else
+								plci->NL.Req = plci->nl_req = (byte)((data->Flags & 0x07) << 4 | N_DATA);
+						}
+						plci->NL.X = plci->NData;
+						plci->NL.ReqCh = a->ncci_ch[ncci];
+						dbug(1, dprintf("%x:DREQ(%x:%x)", a->Id, plci->NL.Id, plci->NL.Req));
+						plci->data_sent = true;
+						plci->data_sent_ptr = data->P;
+						a->request(&plci->NL);
+					}
+					else {
+						cleanup_ncci_data(plci, ncci);
+					}
+				}
+				else if (plci->send_disc == ncci)
+				{
+					/* dprintf("N_DISC"); */
+					plci->NData[0].PLength = 0;
+					plci->NL.ReqCh = a->ncci_ch[ncci];
+					plci->NL.Req = plci->nl_req = N_DISC;
+					a->request(&plci->NL);
+					plci->command = _DISCONNECT_B3_R;
+					plci->send_disc = 0;
+				}
+			}
+		} while (!plci->nl_req && (ncci != plci->ncci_ring_list));
+		plci->ncci_ring_list = ncci;
+	}
 }
 
 static void listen_check(DIVA_CAPI_ADAPTER *a)
 {
-  word i,j;
-  PLCI   * plci;
-  byte activnotifiedcalls = 0;
-
-  dbug(1,dprintf("listen_check(%d,%d)",a->listen_active,a->max_listen));
-  if (!remove_started && !a->adapter_disabled)
-  {
-    for(i=0;i<a->max_plci;i++)
-    {
-      plci = &(a->plci[i]);
-      if(plci->notifiedcall) activnotifiedcalls++;
-    }
-    dbug(1,dprintf("listen_check(%d)",activnotifiedcalls));
-
-    for(i=a->listen_active; i < ((word)(a->max_listen+activnotifiedcalls)); i++) {
-      if((j=get_plci(a))) {
-        a->listen_active++;
-        plci = &a->plci[j-1];
-        plci->State = LISTENING;
-
-        add_p(plci,OAD,"\x01\xfd");
-
-        add_p(plci,KEY,"\x04\x43\x41\x32\x30");
-
-        add_p(plci,CAI,"\x01\xc0");
-        add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-        add_p(plci,LLI,"\x01\xc4");                  /* support Dummy CR FAC + MWI + SpoofNotify */       
-        add_p(plci,SHIFT|6,NULL);
-        add_p(plci,SIN,"\x02\x00\x00");
-        plci->internal_command = LISTEN_SIG_ASSIGN_PEND;     /* do indicate_req if OK  */
-        sig_req(plci,ASSIGN,DSIG_ID);
-        send_req(plci);
-      }
-    }
-  }
+	word i, j;
+	PLCI *plci;
+	byte activnotifiedcalls = 0;
+
+	dbug(1, dprintf("listen_check(%d,%d)", a->listen_active, a->max_listen));
+	if (!remove_started && !a->adapter_disabled)
+	{
+		for (i = 0; i < a->max_plci; i++)
+		{
+			plci = &(a->plci[i]);
+			if (plci->notifiedcall) activnotifiedcalls++;
+		}
+		dbug(1, dprintf("listen_check(%d)", activnotifiedcalls));
+
+		for (i = a->listen_active; i < ((word)(a->max_listen + activnotifiedcalls)); i++) {
+			if ((j = get_plci(a))) {
+				a->listen_active++;
+				plci = &a->plci[j - 1];
+				plci->State = LISTENING;
+
+				add_p(plci, OAD, "\x01\xfd");
+
+				add_p(plci, KEY, "\x04\x43\x41\x32\x30");
+
+				add_p(plci, CAI, "\x01\xc0");
+				add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+				add_p(plci, LLI, "\x01\xc4");                  /* support Dummy CR FAC + MWI + SpoofNotify */
+				add_p(plci, SHIFT | 6, NULL);
+				add_p(plci, SIN, "\x02\x00\x00");
+				plci->internal_command = LISTEN_SIG_ASSIGN_PEND;     /* do indicate_req if OK  */
+				sig_req(plci, ASSIGN, DSIG_ID);
+				send_req(plci);
+			}
+		}
+	}
 }
 
 /*------------------------------------------------------------------*/
@@ -8928,83 +8928,83 @@ static void listen_check(DIVA_CAPI_ADAPTER *a)
 
 static void IndParse(PLCI *plci, word *parms_id, byte **parms, byte multiIEsize)
 {
-  word ploc;            /* points to current location within packet */
-  byte w;
-  byte wlen;
-  byte codeset,lock;
-  byte   * in;
-  word i;
-  word code;
-  word mIEindex = 0;
-  ploc = 0;
-  codeset = 0;
-  lock = 0;
-
-  in = plci->Sig.RBuffer->P;
-  for(i=0; i<parms_id[0]; i++)   /* multiIE parms_id contains just the 1st */
-  {                            /* element but parms array is larger      */
-    parms[i] = (byte   *)"";
-  }
-  for(i=0; i<multiIEsize; i++)
-  {
-    parms[i] = (byte   *)"";
-  }
-
-  while(ploc<plci->Sig.RBuffer->length-1) {
-
-        /* read information element id and length                   */
-    w = in[ploc];
-
-    if(w & 0x80) {
+	word ploc;            /* points to current location within packet */
+	byte w;
+	byte wlen;
+	byte codeset, lock;
+	byte *in;
+	word i;
+	word code;
+	word mIEindex = 0;
+	ploc = 0;
+	codeset = 0;
+	lock = 0;
+
+	in = plci->Sig.RBuffer->P;
+	for (i = 0; i < parms_id[0]; i++)   /* multiIE parms_id contains just the 1st */
+	{                            /* element but parms array is larger      */
+		parms[i] = (byte *)"";
+	}
+	for (i = 0; i < multiIEsize; i++)
+	{
+		parms[i] = (byte *)"";
+	}
+
+	while (ploc < plci->Sig.RBuffer->length - 1) {
+
+		/* read information element id and length                   */
+		w = in[ploc];
+
+		if (w & 0x80) {
 /*    w &=0xf0; removed, cannot detect congestion levels */
 /*    upper 4 bit masked with w==SHIFT now               */
-      wlen = 0;
-    }
-    else {
-      wlen = (byte)(in[ploc+1]+1);
-    }
-        /* check if length valid (not exceeding end of packet)      */
-    if((ploc+wlen) > 270) return ;
-    if(lock & 0x80) lock &=0x7f;
-    else codeset = lock;
-
-    if((w&0xf0)==SHIFT) {
-      codeset = in[ploc];
-      if(!(codeset & 0x08)) lock = (byte)(codeset & 7);
-      codeset &=7;
-      lock |=0x80;
-    }
-    else {
-      if(w==ESC && wlen>=3) code = in[ploc+2] |0x800;
-      else code = w;
-      code |= (codeset<<8);
-
-      for(i=1; i<parms_id[0]+1 && parms_id[i]!=code; i++);
-
-      if(i<parms_id[0]+1) {
-        if(!multiIEsize) { /* with multiIEs use next field index,          */
-          mIEindex = i-1;    /* with normal IEs use same index like parms_id */
-        }
-
-        parms[mIEindex] = &in[ploc+1];
-        dbug(1,dprintf("mIE[%d]=0x%x",*parms[mIEindex],in[ploc]));
-        if(parms_id[i]==OAD
-        || parms_id[i]==CONN_NR
-        || parms_id[i]==CAD) {
-          if(in[ploc+2] &0x80) {
-            in[ploc+0] = (byte)(in[ploc+1]+1);
-            in[ploc+1] = (byte)(in[ploc+2] &0x7f);
-            in[ploc+2] = 0x80;
-            parms[mIEindex] = &in[ploc];
-          }
-        }
-        mIEindex++;       /* effects multiIEs only */
-      }
-    }
-
-    ploc +=(wlen+1);
-  }
-  return ;
+			wlen = 0;
+		}
+		else {
+			wlen = (byte)(in[ploc + 1] + 1);
+		}
+		/* check if length valid (not exceeding end of packet)      */
+		if ((ploc + wlen) > 270) return;
+		if (lock & 0x80) lock &= 0x7f;
+		else codeset = lock;
+
+		if ((w & 0xf0) == SHIFT) {
+			codeset = in[ploc];
+			if (!(codeset & 0x08)) lock = (byte)(codeset & 7);
+			codeset &= 7;
+			lock |= 0x80;
+		}
+		else {
+			if (w == ESC && wlen >= 3) code = in[ploc + 2] | 0x800;
+			else code = w;
+			code |= (codeset << 8);
+
+			for (i = 1; i < parms_id[0] + 1 && parms_id[i] != code; i++);
+
+			if (i < parms_id[0] + 1) {
+				if (!multiIEsize) { /* with multiIEs use next field index,          */
+					mIEindex = i - 1;    /* with normal IEs use same index like parms_id */
+				}
+
+				parms[mIEindex] = &in[ploc + 1];
+				dbug(1, dprintf("mIE[%d]=0x%x", *parms[mIEindex], in[ploc]));
+				if (parms_id[i] == OAD
+				    || parms_id[i] == CONN_NR
+				    || parms_id[i] == CAD) {
+					if (in[ploc + 2] & 0x80) {
+						in[ploc + 0] = (byte)(in[ploc + 1] + 1);
+						in[ploc + 1] = (byte)(in[ploc + 2] & 0x7f);
+						in[ploc + 2] = 0x80;
+						parms[mIEindex] = &in[ploc];
+					}
+				}
+				mIEindex++;       /* effects multiIEs only */
+			}
+		}
+
+		ploc += (wlen + 1);
+	}
+	return;
 }
 
 /*------------------------------------------------------------------*/
@@ -9013,75 +9013,75 @@ static void IndParse(PLCI *plci, word *parms_id, byte **parms, byte multiIEsize)
 
 static byte ie_compare(byte *ie1, byte *ie2)
 {
-  word i;
-  if(!ie1 || ! ie2) return false;
-  if(!ie1[0]) return false;
-  for(i=0;i<(word)(ie1[0]+1);i++) if(ie1[i]!=ie2[i]) return false;
-  return true;
+	word i;
+	if (!ie1 || !ie2) return false;
+	if (!ie1[0]) return false;
+	for (i = 0; i < (word)(ie1[0] + 1); i++) if (ie1[i] != ie2[i]) return false;
+	return true;
 }
 
 static word find_cip(DIVA_CAPI_ADAPTER *a, byte *bc, byte *hlc)
 {
-  word i;
-  word j;
+	word i;
+	word j;
 
-  for(i=9;i && !ie_compare(bc,cip_bc[i][a->u_law]);i--);
+	for (i = 9; i && !ie_compare(bc, cip_bc[i][a->u_law]); i--);
 
-  for(j=16;j<29 &&
-           (!ie_compare(bc,cip_bc[j][a->u_law]) || !ie_compare(hlc,cip_hlc[j])); j++);
-  if(j==29) return i;
-  return j;
+	for (j = 16; j < 29 &&
+		     (!ie_compare(bc, cip_bc[j][a->u_law]) || !ie_compare(hlc, cip_hlc[j])); j++);
+	if (j == 29) return i;
+	return j;
 }
 
 
-static byte AddInfo(byte   **add_i,
-                    byte   **fty_i,
-                    byte   *esc_chi,
-                    byte *facility)
+static byte AddInfo(byte **add_i,
+		    byte **fty_i,
+		    byte *esc_chi,
+		    byte *facility)
 {
-  byte i;
-  byte j;
-  byte k;
-  byte flen;
-  byte len=0;
-   /* facility is a nested structure */
-   /* FTY can be more than once      */
+	byte i;
+	byte j;
+	byte k;
+	byte flen;
+	byte len = 0;
+	/* facility is a nested structure */
+	/* FTY can be more than once      */
 
 	if (esc_chi[0] && !(esc_chi[esc_chi[0]] & 0x7f))
-  {
-    add_i[0] = (byte   *)"\x02\x02\x00"; /* use neither b nor d channel */
-  }
-
-  else
-  {
-    add_i[0] = (byte   *)"";
-  }
-  if(!fty_i[0][0])
-  {
-    add_i[3] = (byte   *)"";
-  }
-  else
-  {    /* facility array found  */
-    for(i=0,j=1;i<MAX_MULTI_IE && fty_i[i][0];i++)
-    {
-      dbug(1,dprintf("AddIFac[%d]",fty_i[i][0]));
-      len += fty_i[i][0];
-      len += 2;
-      flen=fty_i[i][0];
-      facility[j++]=0x1c; /* copy fac IE */
-      for(k=0;k<=flen;k++,j++)
-      {
-        facility[j]=fty_i[i][k];
-/*      dbug(1,dprintf("%x ",facility[j])); */
-      }
-    }
-    facility[0] = len;
-    add_i[3] = facility;
-  }
-/*  dbug(1,dprintf("FacArrLen=%d ",len)); */
-  len = add_i[0][0]+add_i[1][0]+add_i[2][0]+add_i[3][0];
-  len += 4;                          /* calculate length of all */
-  return(len);
+	{
+		add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */
+	}
+
+	else
+	{
+		add_i[0] = (byte *)"";
+	}
+	if (!fty_i[0][0])
+	{
+		add_i[3] = (byte *)"";
+	}
+	else
+	{    /* facility array found  */
+		for (i = 0, j = 1; i < MAX_MULTI_IE && fty_i[i][0]; i++)
+		{
+			dbug(1, dprintf("AddIFac[%d]", fty_i[i][0]));
+			len += fty_i[i][0];
+			len += 2;
+			flen = fty_i[i][0];
+			facility[j++] = 0x1c; /* copy fac IE */
+			for (k = 0; k <= flen; k++, j++)
+			{
+				facility[j] = fty_i[i][k];
+/*      dbug(1, dprintf("%x ",facility[j])); */
+			}
+		}
+		facility[0] = len;
+		add_i[3] = facility;
+	}
+/*  dbug(1, dprintf("FacArrLen=%d ",len)); */
+	len = add_i[0][0] + add_i[1][0] + add_i[2][0] + add_i[3][0];
+	len += 4;                          /* calculate length of all */
+	return (len);
 }
 
 /*------------------------------------------------------------------*/
@@ -9090,219 +9090,219 @@ static byte AddInfo(byte   **add_i,
 
 static void SetVoiceChannel(PLCI *plci, byte *chi, DIVA_CAPI_ADAPTER *a)
 {
-  byte voice_chi[] = "\x02\x18\x01";
-  byte channel;
-
-  channel = chi[chi[0]]&0x3;
-  dbug(1,dprintf("ExtDevON(Ch=0x%x)",channel));
-  voice_chi[2] = (channel) ? channel : 1;
-  add_p(plci,FTY,"\x02\x01\x07");             /* B On, default on 1 */
-  add_p(plci,ESC,voice_chi);                  /* Channel */
-  sig_req(plci,TEL_CTRL,0);
-  send_req(plci);
-  if(a->AdvSignalPLCI)
-  {
-    adv_voice_write_coefs (a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION);
-  }
+	byte voice_chi[] = "\x02\x18\x01";
+	byte channel;
+
+	channel = chi[chi[0]] & 0x3;
+	dbug(1, dprintf("ExtDevON(Ch=0x%x)", channel));
+	voice_chi[2] = (channel) ? channel : 1;
+	add_p(plci, FTY, "\x02\x01\x07");             /* B On, default on 1 */
+	add_p(plci, ESC, voice_chi);                  /* Channel */
+	sig_req(plci, TEL_CTRL, 0);
+	send_req(plci);
+	if (a->AdvSignalPLCI)
+	{
+		adv_voice_write_coefs(a->AdvSignalPLCI, ADV_VOICE_WRITE_ACTIVATION);
+	}
 }
 
 static void VoiceChannelOff(PLCI *plci)
 {
-  dbug(1,dprintf("ExtDevOFF"));
-  add_p(plci,FTY,"\x02\x01\x08");             /* B Off */
-  sig_req(plci,TEL_CTRL,0);
-  send_req(plci);
-  if(plci->adapter->AdvSignalPLCI)
-  {
-    adv_voice_clear_config (plci->adapter->AdvSignalPLCI);
-  }
+	dbug(1, dprintf("ExtDevOFF"));
+	add_p(plci, FTY, "\x02\x01\x08");             /* B Off */
+	sig_req(plci, TEL_CTRL, 0);
+	send_req(plci);
+	if (plci->adapter->AdvSignalPLCI)
+	{
+		adv_voice_clear_config(plci->adapter->AdvSignalPLCI);
+	}
 }
 
 
 static word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl,
 			    byte hook_listen)
 {
-  word j;
-  PLCI   *splci;
-
-  /* check if hardware supports handset with hook states (adv.codec) */
-  /* or if just a on board codec is supported                        */
-  /* the advanced codec plci is just for internal use                */
-
-  /* diva Pro with on-board codec:                                   */
-  if(a->profile.Global_Options & HANDSET)
-  {
-    /* new call, but hook states are already signalled */
-    if(a->AdvCodecFLAG)
-    {
-      if(a->AdvSignalAppl!=appl || a->AdvSignalPLCI)
-      {
-        dbug(1,dprintf("AdvSigPlci=0x%x",a->AdvSignalPLCI));
-        return 0x2001; /* codec in use by another application */
-      }
-      if(plci!=NULL)
-      {
-        a->AdvSignalPLCI = plci;
-        plci->tel=ADV_VOICE;
-      }
-      return 0;                      /* adv codec still used */
-    }
-    if((j=get_plci(a)))
-    {
-      splci = &a->plci[j-1];
-      splci->tel = CODEC_PERMANENT;
-      /* hook_listen indicates if a facility_req with handset/hook support */
-      /* was sent. Otherwise if just a call on an external device was made */
-      /* the codec will be used but the hook info will be discarded (just  */
-      /* the external controller is in use                                 */
-      if(hook_listen) splci->State = ADVANCED_VOICE_SIG;
-      else
-      {
-        splci->State = ADVANCED_VOICE_NOSIG;
-        if(plci)
-        {
-          plci->spoofed_msg = SPOOFING_REQUIRED;
-        }
-                                               /* indicate D-ch connect if  */
-      }                                        /* codec is connected OK     */
-      if(plci!=NULL)
-      {
-        a->AdvSignalPLCI = plci;
-        plci->tel=ADV_VOICE;
-      }
-      a->AdvSignalAppl = appl;
-      a->AdvCodecFLAG = true;
-      a->AdvCodecPLCI = splci;
-      add_p(splci,CAI,"\x01\x15");
-      add_p(splci,LLI,"\x01\x00");
-      add_p(splci,ESC,"\x02\x18\x00");
-      add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-      splci->internal_command = PERM_COD_ASSIGN;
-      dbug(1,dprintf("Codec Assign"));
-      sig_req(splci,ASSIGN,DSIG_ID);
-      send_req(splci);
-    }
-    else
-    {
-      return 0x2001; /* wrong state, no more plcis */
-    }
-  }
-  else if(a->profile.Global_Options & ON_BOARD_CODEC)
-  {
-    if(hook_listen) return 0x300B;               /* Facility not supported */
-                                                 /* no hook with SCOM      */
-    if(plci!=NULL) plci->tel = CODEC;
-    dbug(1,dprintf("S/SCOM codec"));
-    /* first time we use the scom-s codec we must shut down the internal   */
-    /* handset application of the card. This can be done by an assign with */
-    /* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/
-    if(!a->scom_appl_disable){
-      if((j=get_plci(a))) {
-        splci = &a->plci[j-1];
-        add_p(splci,CAI,"\x01\x80");
-        add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-        sig_req(splci,ASSIGN,0xC0);  /* 0xc0 is the TEL_ID */
-        send_req(splci);
-        a->scom_appl_disable = true;
-      }
-      else{
-        return 0x2001; /* wrong state, no more plcis */
-      }
-    }
-  }
-  else return 0x300B;               /* Facility not supported */
-
-  return 0;
+	word j;
+	PLCI *splci;
+
+	/* check if hardware supports handset with hook states (adv.codec) */
+	/* or if just a on board codec is supported                        */
+	/* the advanced codec plci is just for internal use                */
+
+	/* diva Pro with on-board codec:                                   */
+	if (a->profile.Global_Options & HANDSET)
+	{
+		/* new call, but hook states are already signalled */
+		if (a->AdvCodecFLAG)
+		{
+			if (a->AdvSignalAppl != appl || a->AdvSignalPLCI)
+			{
+				dbug(1, dprintf("AdvSigPlci=0x%x", a->AdvSignalPLCI));
+				return 0x2001; /* codec in use by another application */
+			}
+			if (plci != NULL)
+			{
+				a->AdvSignalPLCI = plci;
+				plci->tel = ADV_VOICE;
+			}
+			return 0;                      /* adv codec still used */
+		}
+		if ((j = get_plci(a)))
+		{
+			splci = &a->plci[j - 1];
+			splci->tel = CODEC_PERMANENT;
+			/* hook_listen indicates if a facility_req with handset/hook support */
+			/* was sent. Otherwise if just a call on an external device was made */
+			/* the codec will be used but the hook info will be discarded (just  */
+			/* the external controller is in use                                 */
+			if (hook_listen) splci->State = ADVANCED_VOICE_SIG;
+			else
+			{
+				splci->State = ADVANCED_VOICE_NOSIG;
+				if (plci)
+				{
+					plci->spoofed_msg = SPOOFING_REQUIRED;
+				}
+				/* indicate D-ch connect if  */
+			}                                        /* codec is connected OK     */
+			if (plci != NULL)
+			{
+				a->AdvSignalPLCI = plci;
+				plci->tel = ADV_VOICE;
+			}
+			a->AdvSignalAppl = appl;
+			a->AdvCodecFLAG = true;
+			a->AdvCodecPLCI = splci;
+			add_p(splci, CAI, "\x01\x15");
+			add_p(splci, LLI, "\x01\x00");
+			add_p(splci, ESC, "\x02\x18\x00");
+			add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+			splci->internal_command = PERM_COD_ASSIGN;
+			dbug(1, dprintf("Codec Assign"));
+			sig_req(splci, ASSIGN, DSIG_ID);
+			send_req(splci);
+		}
+		else
+		{
+			return 0x2001; /* wrong state, no more plcis */
+		}
+	}
+	else if (a->profile.Global_Options & ON_BOARD_CODEC)
+	{
+		if (hook_listen) return 0x300B;               /* Facility not supported */
+		/* no hook with SCOM      */
+		if (plci != NULL) plci->tel = CODEC;
+		dbug(1, dprintf("S/SCOM codec"));
+		/* first time we use the scom-s codec we must shut down the internal   */
+		/* handset application of the card. This can be done by an assign with */
+		/* a cai with the 0x80 bit set. Assign return code is 'out of resource'*/
+		if (!a->scom_appl_disable) {
+			if ((j = get_plci(a))) {
+				splci = &a->plci[j - 1];
+				add_p(splci, CAI, "\x01\x80");
+				add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+				sig_req(splci, ASSIGN, 0xC0);  /* 0xc0 is the TEL_ID */
+				send_req(splci);
+				a->scom_appl_disable = true;
+			}
+			else{
+				return 0x2001; /* wrong state, no more plcis */
+			}
+		}
+	}
+	else return 0x300B;               /* Facility not supported */
+
+	return 0;
 }
 
 
 static void CodecIdCheck(DIVA_CAPI_ADAPTER *a, PLCI *plci)
 {
 
-  dbug(1,dprintf("CodecIdCheck"));
+	dbug(1, dprintf("CodecIdCheck"));
 
-  if(a->AdvSignalPLCI == plci)
-  {
-    dbug(1,dprintf("PLCI owns codec"));
-    VoiceChannelOff(a->AdvCodecPLCI);
-    if(a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG)
-    {
-      dbug(1,dprintf("remove temp codec PLCI"));
-      plci_remove(a->AdvCodecPLCI);
-      a->AdvCodecFLAG  = 0;
-      a->AdvCodecPLCI  = NULL;
-      a->AdvSignalAppl = NULL;
-    }
-    a->AdvSignalPLCI = NULL;
-  }
+	if (a->AdvSignalPLCI == plci)
+	{
+		dbug(1, dprintf("PLCI owns codec"));
+		VoiceChannelOff(a->AdvCodecPLCI);
+		if (a->AdvCodecPLCI->State == ADVANCED_VOICE_NOSIG)
+		{
+			dbug(1, dprintf("remove temp codec PLCI"));
+			plci_remove(a->AdvCodecPLCI);
+			a->AdvCodecFLAG  = 0;
+			a->AdvCodecPLCI  = NULL;
+			a->AdvSignalAppl = NULL;
+		}
+		a->AdvSignalPLCI = NULL;
+	}
 }
 
 /* -------------------------------------------------------------------
-    Ask for physical address of card on PCI bus
+   Ask for physical address of card on PCI bus
    ------------------------------------------------------------------- */
-static void diva_ask_for_xdi_sdram_bar (DIVA_CAPI_ADAPTER  * a,
-                                        IDI_SYNC_REQ  * preq) {
-  a->sdram_bar = 0;
-  if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) {
-    ENTITY   * e = (ENTITY   *)preq;
+static void diva_ask_for_xdi_sdram_bar(DIVA_CAPI_ADAPTER *a,
+				       IDI_SYNC_REQ *preq) {
+	a->sdram_bar = 0;
+	if (diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR) {
+		ENTITY *e = (ENTITY *)preq;
 
-    e->user[0] = a->Id - 1;
-    preq->xdi_sdram_bar.info.bar    = 0;
-    preq->xdi_sdram_bar.Req         = 0;
-    preq->xdi_sdram_bar.Rc           = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR;
+		e->user[0] = a->Id - 1;
+		preq->xdi_sdram_bar.info.bar    = 0;
+		preq->xdi_sdram_bar.Req         = 0;
+		preq->xdi_sdram_bar.Rc           = IDI_SYNC_REQ_XDI_GET_ADAPTER_SDRAM_BAR;
 
-    (*(a->request))(e);
+		(*(a->request))(e);
 
-    a->sdram_bar = preq->xdi_sdram_bar.info.bar;
-    dbug(3,dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar));
-  }
+		a->sdram_bar = preq->xdi_sdram_bar.info.bar;
+		dbug(3, dprintf("A(%d) SDRAM BAR = %08x", a->Id, a->sdram_bar));
+	}
 }
 
 /* -------------------------------------------------------------------
-     Ask XDI about extended features
+   Ask XDI about extended features
    ------------------------------------------------------------------- */
-static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER  * a) {
-  IDI_SYNC_REQ   * preq;
-    char buffer[              ((sizeof(preq->xdi_extended_features)+4) > sizeof(ENTITY)) ?                     (sizeof(preq->xdi_extended_features)+4) : sizeof(ENTITY)];
-
-    char features[4];
-  preq = (IDI_SYNC_REQ   *)&buffer[0];
-
-  if (!diva_xdi_extended_features) {
-    ENTITY   * e = (ENTITY   *)preq;
-    diva_xdi_extended_features |= 0x80000000;
-
-    e->user[0] = a->Id - 1;
-    preq->xdi_extended_features.Req = 0;
-    preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
-    preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
-    preq->xdi_extended_features.info.features = &features[0];
-
-    (*(a->request))(e);
-
-    if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) {
-      /*
-         Check features located in the byte '0'
-         */
-      if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) {
-        diva_xdi_extended_features |= DIVA_CAPI_USE_CMA;
-      }
-      if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) {
-        diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA;
-        dbug(1,dprintf("XDI provides RxDMA"));
-      }
-      if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) {
-        diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR;
-      }
-      if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) {
-        diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL;
-        dbug(3,dprintf("XDI provides NO_CANCEL_RC feature"));
-      }
-
-    }
-  }
-
-  diva_ask_for_xdi_sdram_bar (a, preq);
+static void diva_get_extended_adapter_features(DIVA_CAPI_ADAPTER *a) {
+	IDI_SYNC_REQ *preq;
+	char buffer[((sizeof(preq->xdi_extended_features) + 4) > sizeof(ENTITY)) ? (sizeof(preq->xdi_extended_features) + 4) : sizeof(ENTITY)];
+
+	char features[4];
+	preq = (IDI_SYNC_REQ *)&buffer[0];
+
+	if (!diva_xdi_extended_features) {
+		ENTITY *e = (ENTITY *)preq;
+		diva_xdi_extended_features |= 0x80000000;
+
+		e->user[0] = a->Id - 1;
+		preq->xdi_extended_features.Req = 0;
+		preq->xdi_extended_features.Rc  = IDI_SYNC_REQ_XDI_GET_EXTENDED_FEATURES;
+		preq->xdi_extended_features.info.buffer_length_in_bytes = sizeof(features);
+		preq->xdi_extended_features.info.features = &features[0];
+
+		(*(a->request))(e);
+
+		if (features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) {
+			/*
+			  Check features located in the byte '0'
+			*/
+			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_CMA) {
+				diva_xdi_extended_features |= DIVA_CAPI_USE_CMA;
+			}
+			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_RX_DMA) {
+				diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_RX_DMA;
+				dbug(1, dprintf("XDI provides RxDMA"));
+			}
+			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_SDRAM_BAR) {
+				diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_SDRAM_BAR;
+			}
+			if (features[0] & DIVA_XDI_EXTENDED_FEATURE_NO_CANCEL_RC) {
+				diva_xdi_extended_features |= DIVA_CAPI_XDI_PROVIDES_NO_CANCEL;
+				dbug(3, dprintf("XDI provides NO_CANCEL_RC feature"));
+			}
+
+		}
+	}
+
+	diva_ask_for_xdi_sdram_bar(a, preq);
 }
 
 /*------------------------------------------------------------------*/
@@ -9310,188 +9310,188 @@ static void diva_get_extended_adapter_features (DIVA_CAPI_ADAPTER  * a) {
 /*------------------------------------------------------------------*/
 /* called from OS specific part after init time to get the Law              */
 /* a-law (Euro) and u-law (us,japan) use different BCs in the Setup message */
-void AutomaticLaw(DIVA_CAPI_ADAPTER   *a)
-{
-  word j;
-  PLCI   *splci;
-
-  if(a->automatic_law) {
-    return;
-  }
-  if((j=get_plci(a))) {
-    diva_get_extended_adapter_features (a);
-    splci = &a->plci[j-1];
-    a->automatic_lawPLCI = splci;
-    a->automatic_law = 1;
-    add_p(splci,CAI,"\x01\x80");
-    add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-    splci->internal_command = USELAW_REQ;
-    splci->command = 0;
-    splci->number = 0;
-    sig_req(splci,ASSIGN,DSIG_ID);
-    send_req(splci);
-  }
+void AutomaticLaw(DIVA_CAPI_ADAPTER *a)
+{
+	word j;
+	PLCI *splci;
+
+	if (a->automatic_law) {
+		return;
+	}
+	if ((j = get_plci(a))) {
+		diva_get_extended_adapter_features(a);
+		splci = &a->plci[j - 1];
+		a->automatic_lawPLCI = splci;
+		a->automatic_law = 1;
+		add_p(splci, CAI, "\x01\x80");
+		add_p(splci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+		splci->internal_command = USELAW_REQ;
+		splci->command = 0;
+		splci->number = 0;
+		sig_req(splci, ASSIGN, DSIG_ID);
+		send_req(splci);
+	}
 }
 
 /* called from OS specific part if an application sends an Capi20Release */
 word CapiRelease(word Id)
 {
-  word i, j, appls_found;
-  PLCI   *plci;
-  APPL   *this;
-  DIVA_CAPI_ADAPTER   *a;
-
-  if (!Id)
-  {
-    dbug(0,dprintf("A: CapiRelease(Id==0)"));
-    return (_WRONG_APPL_ID);
-  }
-
-  this = &application[Id-1];               /* get application pointer */
-
-  for(i=0,appls_found=0; i<max_appl; i++)
-  {
-    if(application[i].Id)       /* an application has been found        */
-    {
-      appls_found++;
-    }
-  }
-
-  for(i=0; i<max_adapter; i++)             /* scan all adapters...    */
-  {
-    a = &adapter[i];
-    if (a->request)
-    {
-      a->Info_Mask[Id-1] = 0;
-      a->CIP_Mask[Id-1] = 0;
-      a->Notification_Mask[Id-1] = 0;
-      a->codec_listen[Id-1] = NULL;
-      a->requested_options_table[Id-1] = 0;
-      for(j=0; j<a->max_plci; j++)           /* and all PLCIs connected */
-      {                                      /* with this application   */
-        plci = &a->plci[j];
-        if(plci->Id)                         /* if plci owns no application */
-        {                                    /* it may be not jet connected */
-          if(plci->State==INC_CON_PENDING
-          || plci->State==INC_CON_ALERT)
-          {
-            if(test_c_ind_mask_bit (plci, (word)(Id-1)))
-            {
-              clear_c_ind_mask_bit (plci, (word)(Id-1));
-              if(c_ind_mask_empty (plci))
-              {
-                sig_req(plci,HANGUP,0);
-                send_req(plci);
-                plci->State = OUTG_DIS_PENDING;
-              }
-            }
-          }
-          if(test_c_ind_mask_bit (plci, (word)(Id-1)))
-          {
-            clear_c_ind_mask_bit (plci, (word)(Id-1));
-            if(c_ind_mask_empty (plci))
-            {
-              if(!plci->appl)
-              {
-                plci_remove(plci);
-                plci->State = IDLE;
-              }
-            }
-          }
-          if(plci->appl==this)
-          {
-            plci->appl = NULL;
-            plci_remove(plci);
-            plci->State = IDLE;
-          }
-        }
-      }
-      listen_check(a);
-
-      if(a->flag_dynamic_l1_down)
-      {
-        if(appls_found==1)            /* last application does a capi release */
-        {
-          if((j=get_plci(a)))
-          {
-            plci = &a->plci[j-1];
-            plci->command = 0;
-            add_p(plci,OAD,"\x01\xfd");
-            add_p(plci,CAI,"\x01\x80");
-            add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-            add_p(plci,SHIFT|6,NULL);
-            add_p(plci,SIN,"\x02\x00\x00");
-            plci->internal_command = REM_L1_SIG_ASSIGN_PEND;
-            sig_req(plci,ASSIGN,DSIG_ID);
-            add_p(plci,FTY,"\x02\xff\x06"); /* l1 down */
-            sig_req(plci,SIG_CTRL,0);
-            send_req(plci);
-          }
-        }
-      }
-      if(a->AdvSignalAppl==this)
-      {
-        this->NullCREnable = false;
-        if (a->AdvCodecPLCI)
-        {
-          plci_remove(a->AdvCodecPLCI);
-          a->AdvCodecPLCI->tel = 0;
-          a->AdvCodecPLCI->adv_nl = 0;
-        }
-        a->AdvSignalAppl = NULL;
-        a->AdvSignalPLCI = NULL;
-        a->AdvCodecFLAG = 0;
-        a->AdvCodecPLCI = NULL;
-      }
-    }
-  }
-
-  this->Id = 0;
-
-  return GOOD;
-}
-
-static word plci_remove_check(PLCI   *plci)
-{
-  if(!plci) return true;
-  if(!plci->NL.Id && c_ind_mask_empty (plci))
-  {
-    if(plci->Sig.Id == 0xff)
-      plci->Sig.Id = 0;
-    if(!plci->Sig.Id)
-    {
-      dbug(1,dprintf("plci_remove_complete(%x)",plci->Id));
-      dbug(1,dprintf("tel=0x%x,Sig=0x%x",plci->tel,plci->Sig.Id));
-      if (plci->Id)
-      {
-        CodecIdCheck(plci->adapter, plci);
-        clear_b1_config (plci);
-        ncci_remove (plci, 0, false);
-        plci_free_msg_in_queue (plci);
-        channel_flow_control_remove (plci);
-        plci->Id = 0;
-        plci->State = IDLE;
-        plci->channels = 0;
-        plci->appl = NULL;
-        plci->notifiedcall = 0;
-      }
-      listen_check(plci->adapter);
-      return true;
-    }
-  }
-  return false;
+	word i, j, appls_found;
+	PLCI *plci;
+	APPL   *this;
+	DIVA_CAPI_ADAPTER *a;
+
+	if (!Id)
+	{
+		dbug(0, dprintf("A: CapiRelease(Id==0)"));
+		return (_WRONG_APPL_ID);
+	}
+
+	this = &application[Id - 1];               /* get application pointer */
+
+	for (i = 0, appls_found = 0; i < max_appl; i++)
+	{
+		if (application[i].Id)       /* an application has been found        */
+		{
+			appls_found++;
+		}
+	}
+
+	for (i = 0; i < max_adapter; i++)             /* scan all adapters...    */
+	{
+		a = &adapter[i];
+		if (a->request)
+		{
+			a->Info_Mask[Id - 1] = 0;
+			a->CIP_Mask[Id - 1] = 0;
+			a->Notification_Mask[Id - 1] = 0;
+			a->codec_listen[Id - 1] = NULL;
+			a->requested_options_table[Id - 1] = 0;
+			for (j = 0; j < a->max_plci; j++)           /* and all PLCIs connected */
+			{                                      /* with this application   */
+				plci = &a->plci[j];
+				if (plci->Id)                         /* if plci owns no application */
+				{                                    /* it may be not jet connected */
+					if (plci->State == INC_CON_PENDING
+					    || plci->State == INC_CON_ALERT)
+					{
+						if (test_c_ind_mask_bit(plci, (word)(Id - 1)))
+						{
+							clear_c_ind_mask_bit(plci, (word)(Id - 1));
+							if (c_ind_mask_empty(plci))
+							{
+								sig_req(plci, HANGUP, 0);
+								send_req(plci);
+								plci->State = OUTG_DIS_PENDING;
+							}
+						}
+					}
+					if (test_c_ind_mask_bit(plci, (word)(Id - 1)))
+					{
+						clear_c_ind_mask_bit(plci, (word)(Id - 1));
+						if (c_ind_mask_empty(plci))
+						{
+							if (!plci->appl)
+							{
+								plci_remove(plci);
+								plci->State = IDLE;
+							}
+						}
+					}
+					if (plci->appl == this)
+					{
+						plci->appl = NULL;
+						plci_remove(plci);
+						plci->State = IDLE;
+					}
+				}
+			}
+			listen_check(a);
+
+			if (a->flag_dynamic_l1_down)
+			{
+				if (appls_found == 1)            /* last application does a capi release */
+				{
+					if ((j = get_plci(a)))
+					{
+						plci = &a->plci[j - 1];
+						plci->command = 0;
+						add_p(plci, OAD, "\x01\xfd");
+						add_p(plci, CAI, "\x01\x80");
+						add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						add_p(plci, SHIFT | 6, NULL);
+						add_p(plci, SIN, "\x02\x00\x00");
+						plci->internal_command = REM_L1_SIG_ASSIGN_PEND;
+						sig_req(plci, ASSIGN, DSIG_ID);
+						add_p(plci, FTY, "\x02\xff\x06"); /* l1 down */
+						sig_req(plci, SIG_CTRL, 0);
+						send_req(plci);
+					}
+				}
+			}
+			if (a->AdvSignalAppl == this)
+			{
+				this->NullCREnable = false;
+				if (a->AdvCodecPLCI)
+				{
+					plci_remove(a->AdvCodecPLCI);
+					a->AdvCodecPLCI->tel = 0;
+					a->AdvCodecPLCI->adv_nl = 0;
+				}
+				a->AdvSignalAppl = NULL;
+				a->AdvSignalPLCI = NULL;
+				a->AdvCodecFLAG = 0;
+				a->AdvCodecPLCI = NULL;
+			}
+		}
+	}
+
+	this->Id = 0;
+
+	return GOOD;
+}
+
+static word plci_remove_check(PLCI *plci)
+{
+	if (!plci) return true;
+	if (!plci->NL.Id && c_ind_mask_empty(plci))
+	{
+		if (plci->Sig.Id == 0xff)
+			plci->Sig.Id = 0;
+		if (!plci->Sig.Id)
+		{
+			dbug(1, dprintf("plci_remove_complete(%x)", plci->Id));
+			dbug(1, dprintf("tel=0x%x,Sig=0x%x", plci->tel, plci->Sig.Id));
+			if (plci->Id)
+			{
+				CodecIdCheck(plci->adapter, plci);
+				clear_b1_config(plci);
+				ncci_remove(plci, 0, false);
+				plci_free_msg_in_queue(plci);
+				channel_flow_control_remove(plci);
+				plci->Id = 0;
+				plci->State = IDLE;
+				plci->channels = 0;
+				plci->appl = NULL;
+				plci->notifiedcall = 0;
+			}
+			listen_check(plci->adapter);
+			return true;
+		}
+	}
+	return false;
 }
 
 
 /*------------------------------------------------------------------*/
 
-static byte plci_nl_busy (PLCI   *plci)
+static byte plci_nl_busy(PLCI *plci)
 {
-  /* only applicable for non-multiplexed protocols */
-  return (plci->nl_req
-    || (plci->ncci_ring_list
-     && plci->adapter->ncci_ch[plci->ncci_ring_list]
-     && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING)));
+	/* only applicable for non-multiplexed protocols */
+	return (plci->nl_req
+		|| (plci->ncci_ring_list
+		    && plci->adapter->ncci_ch[plci->ncci_ring_list]
+		    && (plci->adapter->ch_flow_control[plci->adapter->ncci_ch[plci->ncci_ring_list]] & N_OK_FC_PENDING)));
 }
 
 
@@ -9502,681 +9502,681 @@ static byte plci_nl_busy (PLCI   *plci)
 
 static struct
 {
-  byte send_mask;
-  byte listen_mask;
-  byte character;
-  byte code;
+	byte send_mask;
+	byte listen_mask;
+	byte character;
+	byte code;
 } dtmf_digit_map[] =
 {
-  { 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK },
-  { 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR },
-  { 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 },
-  { 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 },
-  { 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 },
-  { 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 },
-  { 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 },
-  { 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 },
-  { 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 },
-  { 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 },
-  { 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 },
-  { 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 },
-  { 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A },
-  { 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B },
-  { 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C },
-  { 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D },
-  { 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A },
-  { 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B },
-  { 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C },
-  { 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D },
-
-  { 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE },
-  { 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE },
-  { 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE },
-  { 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE },
-  { 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE },
-  { 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE },
-  { 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE },
-  { 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE },
-  { 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE },
-  { 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE },
-  { 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE },
-  { 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE },
-  { 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE },
-  { 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE },
-  { 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE },
-  { 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE },
-  { 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE },
-  { 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE },
-  { 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE },
-  { 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE },
-  { 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE },
-  { 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE },
-  { 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE },
-  { 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL },
-  { 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE },
-  { 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE },
-  { 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE },
-  { 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE },
-  { 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE },
-  { 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE },
-  { 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE },
-  { 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE },
-  { 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE },
-  { 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS },
-  { 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID },
-  { 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH },
-  { 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 },
-  { 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 },
-  { 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 },
-  { 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 },
-  { 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 },
-  { 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 },
-  { 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 },
-  { 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 },
-  { 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 },
-  { 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 },
-  { 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 },
-  { 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 },
-  { 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 },
-  { 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP },
-  { 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 },
-  { 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST },
+	{ 0x01, 0x01, 0x23, DTMF_DIGIT_TONE_CODE_HASHMARK },
+	{ 0x01, 0x01, 0x2a, DTMF_DIGIT_TONE_CODE_STAR },
+	{ 0x01, 0x01, 0x30, DTMF_DIGIT_TONE_CODE_0 },
+	{ 0x01, 0x01, 0x31, DTMF_DIGIT_TONE_CODE_1 },
+	{ 0x01, 0x01, 0x32, DTMF_DIGIT_TONE_CODE_2 },
+	{ 0x01, 0x01, 0x33, DTMF_DIGIT_TONE_CODE_3 },
+	{ 0x01, 0x01, 0x34, DTMF_DIGIT_TONE_CODE_4 },
+	{ 0x01, 0x01, 0x35, DTMF_DIGIT_TONE_CODE_5 },
+	{ 0x01, 0x01, 0x36, DTMF_DIGIT_TONE_CODE_6 },
+	{ 0x01, 0x01, 0x37, DTMF_DIGIT_TONE_CODE_7 },
+	{ 0x01, 0x01, 0x38, DTMF_DIGIT_TONE_CODE_8 },
+	{ 0x01, 0x01, 0x39, DTMF_DIGIT_TONE_CODE_9 },
+	{ 0x01, 0x01, 0x41, DTMF_DIGIT_TONE_CODE_A },
+	{ 0x01, 0x01, 0x42, DTMF_DIGIT_TONE_CODE_B },
+	{ 0x01, 0x01, 0x43, DTMF_DIGIT_TONE_CODE_C },
+	{ 0x01, 0x01, 0x44, DTMF_DIGIT_TONE_CODE_D },
+	{ 0x01, 0x00, 0x61, DTMF_DIGIT_TONE_CODE_A },
+	{ 0x01, 0x00, 0x62, DTMF_DIGIT_TONE_CODE_B },
+	{ 0x01, 0x00, 0x63, DTMF_DIGIT_TONE_CODE_C },
+	{ 0x01, 0x00, 0x64, DTMF_DIGIT_TONE_CODE_D },
+
+	{ 0x04, 0x04, 0x80, DTMF_SIGNAL_NO_TONE },
+	{ 0x00, 0x04, 0x81, DTMF_SIGNAL_UNIDENTIFIED_TONE },
+	{ 0x04, 0x04, 0x82, DTMF_SIGNAL_DIAL_TONE },
+	{ 0x04, 0x04, 0x83, DTMF_SIGNAL_PABX_INTERNAL_DIAL_TONE },
+	{ 0x04, 0x04, 0x84, DTMF_SIGNAL_SPECIAL_DIAL_TONE },
+	{ 0x04, 0x04, 0x85, DTMF_SIGNAL_SECOND_DIAL_TONE },
+	{ 0x04, 0x04, 0x86, DTMF_SIGNAL_RINGING_TONE },
+	{ 0x04, 0x04, 0x87, DTMF_SIGNAL_SPECIAL_RINGING_TONE },
+	{ 0x04, 0x04, 0x88, DTMF_SIGNAL_BUSY_TONE },
+	{ 0x04, 0x04, 0x89, DTMF_SIGNAL_CONGESTION_TONE },
+	{ 0x04, 0x04, 0x8a, DTMF_SIGNAL_SPECIAL_INFORMATION_TONE },
+	{ 0x04, 0x04, 0x8b, DTMF_SIGNAL_COMFORT_TONE },
+	{ 0x04, 0x04, 0x8c, DTMF_SIGNAL_HOLD_TONE },
+	{ 0x04, 0x04, 0x8d, DTMF_SIGNAL_RECORD_TONE },
+	{ 0x04, 0x04, 0x8e, DTMF_SIGNAL_CALLER_WAITING_TONE },
+	{ 0x04, 0x04, 0x8f, DTMF_SIGNAL_CALL_WAITING_TONE },
+	{ 0x04, 0x04, 0x90, DTMF_SIGNAL_PAY_TONE },
+	{ 0x04, 0x04, 0x91, DTMF_SIGNAL_POSITIVE_INDICATION_TONE },
+	{ 0x04, 0x04, 0x92, DTMF_SIGNAL_NEGATIVE_INDICATION_TONE },
+	{ 0x04, 0x04, 0x93, DTMF_SIGNAL_WARNING_TONE },
+	{ 0x04, 0x04, 0x94, DTMF_SIGNAL_INTRUSION_TONE },
+	{ 0x04, 0x04, 0x95, DTMF_SIGNAL_CALLING_CARD_SERVICE_TONE },
+	{ 0x04, 0x04, 0x96, DTMF_SIGNAL_PAYPHONE_RECOGNITION_TONE },
+	{ 0x04, 0x04, 0x97, DTMF_SIGNAL_CPE_ALERTING_SIGNAL },
+	{ 0x04, 0x04, 0x98, DTMF_SIGNAL_OFF_HOOK_WARNING_TONE },
+	{ 0x04, 0x04, 0xbf, DTMF_SIGNAL_INTERCEPT_TONE },
+	{ 0x04, 0x04, 0xc0, DTMF_SIGNAL_MODEM_CALLING_TONE },
+	{ 0x04, 0x04, 0xc1, DTMF_SIGNAL_FAX_CALLING_TONE },
+	{ 0x04, 0x04, 0xc2, DTMF_SIGNAL_ANSWER_TONE },
+	{ 0x04, 0x04, 0xc3, DTMF_SIGNAL_REVERSED_ANSWER_TONE },
+	{ 0x04, 0x04, 0xc4, DTMF_SIGNAL_ANSAM_TONE },
+	{ 0x04, 0x04, 0xc5, DTMF_SIGNAL_REVERSED_ANSAM_TONE },
+	{ 0x04, 0x04, 0xc6, DTMF_SIGNAL_BELL103_ANSWER_TONE },
+	{ 0x04, 0x04, 0xc7, DTMF_SIGNAL_FAX_FLAGS },
+	{ 0x04, 0x04, 0xc8, DTMF_SIGNAL_G2_FAX_GROUP_ID },
+	{ 0x00, 0x04, 0xc9, DTMF_SIGNAL_HUMAN_SPEECH },
+	{ 0x04, 0x04, 0xca, DTMF_SIGNAL_ANSWERING_MACHINE_390 },
+	{ 0x02, 0x02, 0xf1, DTMF_MF_DIGIT_TONE_CODE_1 },
+	{ 0x02, 0x02, 0xf2, DTMF_MF_DIGIT_TONE_CODE_2 },
+	{ 0x02, 0x02, 0xf3, DTMF_MF_DIGIT_TONE_CODE_3 },
+	{ 0x02, 0x02, 0xf4, DTMF_MF_DIGIT_TONE_CODE_4 },
+	{ 0x02, 0x02, 0xf5, DTMF_MF_DIGIT_TONE_CODE_5 },
+	{ 0x02, 0x02, 0xf6, DTMF_MF_DIGIT_TONE_CODE_6 },
+	{ 0x02, 0x02, 0xf7, DTMF_MF_DIGIT_TONE_CODE_7 },
+	{ 0x02, 0x02, 0xf8, DTMF_MF_DIGIT_TONE_CODE_8 },
+	{ 0x02, 0x02, 0xf9, DTMF_MF_DIGIT_TONE_CODE_9 },
+	{ 0x02, 0x02, 0xfa, DTMF_MF_DIGIT_TONE_CODE_0 },
+	{ 0x02, 0x02, 0xfb, DTMF_MF_DIGIT_TONE_CODE_K1 },
+	{ 0x02, 0x02, 0xfc, DTMF_MF_DIGIT_TONE_CODE_K2 },
+	{ 0x02, 0x02, 0xfd, DTMF_MF_DIGIT_TONE_CODE_KP },
+	{ 0x02, 0x02, 0xfe, DTMF_MF_DIGIT_TONE_CODE_S1 },
+	{ 0x02, 0x02, 0xff, DTMF_MF_DIGIT_TONE_CODE_ST },
 
 };
 
 #define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map)
 
 
-static void dtmf_enable_receiver (PLCI   *plci, byte enable_mask)
+static void dtmf_enable_receiver(PLCI *plci, byte enable_mask)
 {
-  word min_digit_duration, min_gap_duration;
+	word min_digit_duration, min_gap_duration;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_enable_receiver %02x",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, enable_mask));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_enable_receiver %02x",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, enable_mask));
 
-  if (enable_mask != 0)
-  {
-    min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms;
-    min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms;
-    plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER;
-    PUT_WORD (&plci->internal_req_buffer[1], min_digit_duration);
-    PUT_WORD (&plci->internal_req_buffer[3], min_gap_duration);
-    plci->NData[0].PLength = 5;
+	if (enable_mask != 0)
+	{
+		min_digit_duration = (plci->dtmf_rec_pulse_ms == 0) ? 40 : plci->dtmf_rec_pulse_ms;
+		min_gap_duration = (plci->dtmf_rec_pause_ms == 0) ? 40 : plci->dtmf_rec_pause_ms;
+		plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_ENABLE_RECEIVER;
+		PUT_WORD(&plci->internal_req_buffer[1], min_digit_duration);
+		PUT_WORD(&plci->internal_req_buffer[3], min_gap_duration);
+		plci->NData[0].PLength = 5;
 
-    PUT_WORD (&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE);
-    plci->NData[0].PLength += 2;
-    capidtmf_recv_enable (&(plci->capidtmf_state), min_digit_duration, min_gap_duration);
+		PUT_WORD(&plci->internal_req_buffer[5], INTERNAL_IND_BUFFER_SIZE);
+		plci->NData[0].PLength += 2;
+		capidtmf_recv_enable(&(plci->capidtmf_state), min_digit_duration, min_gap_duration);
 
-  }
-  else
-  {
-    plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER;
-    plci->NData[0].PLength = 1;
+	}
+	else
+	{
+		plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_DISABLE_RECEIVER;
+		plci->NData[0].PLength = 1;
 
-    capidtmf_recv_disable (&(plci->capidtmf_state));
+		capidtmf_recv_disable(&(plci->capidtmf_state));
 
-  }
-  plci->NData[0].P = plci->internal_req_buffer;
-  plci->NL.X = plci->NData;
-  plci->NL.ReqCh = 0;
-  plci->NL.Req = plci->nl_req = (byte) N_UDATA;
-  plci->adapter->request (&plci->NL);
+	}
+	plci->NData[0].P = plci->internal_req_buffer;
+	plci->NL.X = plci->NData;
+	plci->NL.ReqCh = 0;
+	plci->NL.Req = plci->nl_req = (byte) N_UDATA;
+	plci->adapter->request(&plci->NL);
 }
 
 
-static void dtmf_send_digits (PLCI   *plci, byte   *digit_buffer, word digit_count)
+static void dtmf_send_digits(PLCI *plci, byte *digit_buffer, word digit_count)
 {
-  word w, i;
+	word w, i;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_digits %d",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, digit_count));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_digits %d",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, digit_count));
 
-  plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS;
-  w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms;
-  PUT_WORD (&plci->internal_req_buffer[1], w);
-  w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms;
-  PUT_WORD (&plci->internal_req_buffer[3], w);
-  for (i = 0; i < digit_count; i++)
-  {
-    w = 0;
-    while ((w < DTMF_DIGIT_MAP_ENTRIES)
-      && (digit_buffer[i] != dtmf_digit_map[w].character))
-    {
-      w++;
-    }
-    plci->internal_req_buffer[5+i] = (w < DTMF_DIGIT_MAP_ENTRIES) ?
-      dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR;
-  }
-  plci->NData[0].PLength = 5 + digit_count;
-  plci->NData[0].P = plci->internal_req_buffer;
-  plci->NL.X = plci->NData;
-  plci->NL.ReqCh = 0;
-  plci->NL.Req = plci->nl_req = (byte) N_UDATA;
-  plci->adapter->request (&plci->NL);
+	plci->internal_req_buffer[0] = DTMF_UDATA_REQUEST_SEND_DIGITS;
+	w = (plci->dtmf_send_pulse_ms == 0) ? 40 : plci->dtmf_send_pulse_ms;
+	PUT_WORD(&plci->internal_req_buffer[1], w);
+	w = (plci->dtmf_send_pause_ms == 0) ? 40 : plci->dtmf_send_pause_ms;
+	PUT_WORD(&plci->internal_req_buffer[3], w);
+	for (i = 0; i < digit_count; i++)
+	{
+		w = 0;
+		while ((w < DTMF_DIGIT_MAP_ENTRIES)
+		       && (digit_buffer[i] != dtmf_digit_map[w].character))
+		{
+			w++;
+		}
+		plci->internal_req_buffer[5 + i] = (w < DTMF_DIGIT_MAP_ENTRIES) ?
+			dtmf_digit_map[w].code : DTMF_DIGIT_TONE_CODE_STAR;
+	}
+	plci->NData[0].PLength = 5 + digit_count;
+	plci->NData[0].P = plci->internal_req_buffer;
+	plci->NL.X = plci->NData;
+	plci->NL.ReqCh = 0;
+	plci->NL.Req = plci->nl_req = (byte) N_UDATA;
+	plci->adapter->request(&plci->NL);
 }
 
 
-static void dtmf_rec_clear_config (PLCI   *plci)
+static void dtmf_rec_clear_config(PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_rec_clear_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  plci->dtmf_rec_active = 0;
-  plci->dtmf_rec_pulse_ms = 0;
-  plci->dtmf_rec_pause_ms = 0;
-
-  capidtmf_init (&(plci->capidtmf_state), plci->adapter->u_law);
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_rec_clear_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-}
-
-
-static void dtmf_send_clear_config (PLCI   *plci)
-{
+	plci->dtmf_rec_active = 0;
+	plci->dtmf_rec_pulse_ms = 0;
+	plci->dtmf_rec_pause_ms = 0;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_send_clear_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
+	capidtmf_init(&(plci->capidtmf_state), plci->adapter->u_law);
 
-  plci->dtmf_send_requests = 0;
-  plci->dtmf_send_pulse_ms = 0;
-  plci->dtmf_send_pause_ms = 0;
 }
 
 
-static void dtmf_prepare_switch (dword Id, PLCI   *plci)
+static void dtmf_send_clear_config(PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_prepare_switch",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_send_clear_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-  while (plci->dtmf_send_requests != 0)
-    dtmf_confirmation (Id, plci);
+	plci->dtmf_send_requests = 0;
+	plci->dtmf_send_pulse_ms = 0;
+	plci->dtmf_send_pause_ms = 0;
 }
 
 
-static word dtmf_save_config (dword Id, PLCI   *plci, byte Rc)
+static void dtmf_prepare_switch(dword Id, PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_save_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_prepare_switch",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
 
-  return (GOOD);
+	while (plci->dtmf_send_requests != 0)
+		dtmf_confirmation(Id, plci);
 }
 
 
-static word dtmf_restore_config (dword Id, PLCI   *plci, byte Rc)
+static word dtmf_save_config(dword Id, PLCI *plci, byte Rc)
 {
-  word Info;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_restore_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_save_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
 
-  Info = GOOD;
-  if (plci->B1_facilities & B1_FACILITY_DTMFR)
-  {
-    switch (plci->adjust_b_state)
-    {
-    case ADJUST_B_RESTORE_DTMF_1:
-      plci->internal_command = plci->adjust_b_command;
-      if (plci_nl_busy (plci))
-      {
-        plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
-        break;
-      }
-      dtmf_enable_receiver (plci, plci->dtmf_rec_active);
-      plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2;
-      break;
-    case ADJUST_B_RESTORE_DTMF_2:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _WRONG_STATE;
-        break;
-      }
-      break;
-    }
-  }
-  return (Info);
+	return (GOOD);
 }
 
 
-static void dtmf_command (dword Id, PLCI   *plci, byte Rc)
+static word dtmf_restore_config(dword Id, PLCI *plci, byte Rc)
 {
-  word internal_command, Info;
-  byte mask;
-    byte result[4];
+	word Info;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command,
-    plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms,
-    plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms));
-
-  Info = GOOD;
-  result[0] = 2;
-  PUT_WORD (&result[1], DTMF_SUCCESS);
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  mask = 0x01;
-  switch (plci->dtmf_cmd)
-  {
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_restore_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
 
-  case DTMF_LISTEN_TONE_START:
-    mask <<= 1;
-  case DTMF_LISTEN_MF_START:
-    mask <<= 1;
-
-  case DTMF_LISTEN_START:
-    switch (internal_command)
-    {
-    default:
-      adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities |
-        B1_FACILITY_DTMFR), DTMF_COMMAND_1);
-    case DTMF_COMMAND_1:
-      if (adjust_b_process (Id, plci, Rc) != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      if (plci->internal_command)
-        return;
-    case DTMF_COMMAND_2:
-      if (plci_nl_busy (plci))
-      {
-        plci->internal_command = DTMF_COMMAND_2;
-        return;
-      }
-      plci->internal_command = DTMF_COMMAND_3;
-      dtmf_enable_receiver (plci, (byte)(plci->dtmf_rec_active | mask));
-      return;
-    case DTMF_COMMAND_3:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-
-      plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE;
-
-      plci->dtmf_rec_active |= mask;
-      break;
-    }
-    break;
-
-
-  case DTMF_LISTEN_TONE_STOP:
-    mask <<= 1;
-  case DTMF_LISTEN_MF_STOP:
-    mask <<= 1;
-
-  case DTMF_LISTEN_STOP:
-    switch (internal_command)
-    {
-    default:
-      plci->dtmf_rec_active &= ~mask;
-      if (plci->dtmf_rec_active)
-        break;
-/*
-    case DTMF_COMMAND_1:
-      if (plci->dtmf_rec_active)
-      {
-        if (plci_nl_busy (plci))
-        {
-          plci->internal_command = DTMF_COMMAND_1;
-          return;
-        }
-        plci->dtmf_rec_active &= ~mask;
-        plci->internal_command = DTMF_COMMAND_2;
-        dtmf_enable_receiver (plci, false);
-        return;
-      }
-      Rc = OK;
-    case DTMF_COMMAND_2:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Disable DTMF receiver failed %02x",
-          UnMapId (Id), (char far *)(FILE_), __LINE__, Rc));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-*/
-      adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities &
-        ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3);
-    case DTMF_COMMAND_3:
-      if (adjust_b_process (Id, plci, Rc) != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Unload DTMF failed",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      if (plci->internal_command)
-        return;
-      break;
-    }
-    break;
-
-
-  case DTMF_SEND_TONE:
-    mask <<= 1;
-  case DTMF_SEND_MF:
-    mask <<= 1;
-
-  case DTMF_DIGITS_SEND:
-    switch (internal_command)
-    {
-    default:
-      adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities |
-        ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)),
-        DTMF_COMMAND_1);
-    case DTMF_COMMAND_1:
-      if (adjust_b_process (Id, plci, Rc) != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Load DTMF failed",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      if (plci->internal_command)
-        return;
-    case DTMF_COMMAND_2:
-      if (plci_nl_busy (plci))
-      {
-        plci->internal_command = DTMF_COMMAND_2;
-        return;
-      }
-      plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number;
-      plci->internal_command = DTMF_COMMAND_3;
-      dtmf_send_digits (plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length);
-      return;
-    case DTMF_COMMAND_3:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Send DTMF digits failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        if (plci->dtmf_send_requests != 0)
-          (plci->dtmf_send_requests)--;
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      return;
-    }
-    break;
-  }
-  sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
-    "wws", Info, SELECTOR_DTMF, result);
+	Info = GOOD;
+	if (plci->B1_facilities & B1_FACILITY_DTMFR)
+	{
+		switch (plci->adjust_b_state)
+		{
+		case ADJUST_B_RESTORE_DTMF_1:
+			plci->internal_command = plci->adjust_b_command;
+			if (plci_nl_busy(plci))
+			{
+				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
+				break;
+			}
+			dtmf_enable_receiver(plci, plci->dtmf_rec_active);
+			plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_2;
+			break;
+		case ADJUST_B_RESTORE_DTMF_2:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Reenable DTMF receiver failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _WRONG_STATE;
+				break;
+			}
+			break;
+		}
+	}
+	return (Info);
 }
 
 
-static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg)
+static void dtmf_command(dword Id, PLCI *plci, byte Rc)
 {
-  word Info;
-  word i, j;
-  byte mask;
-    API_PARSE dtmf_parms[5];
-    byte result[40];
+	word internal_command, Info;
+	byte mask;
+	byte result[4];
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_request",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_command %02x %04x %04x %d %d %d %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
+			plci->dtmf_cmd, plci->dtmf_rec_pulse_ms, plci->dtmf_rec_pause_ms,
+			plci->dtmf_send_pulse_ms, plci->dtmf_send_pause_ms));
 
-  Info = GOOD;
-  result[0] = 2;
-  PUT_WORD (&result[1], DTMF_SUCCESS);
-  if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    Info = _FACILITY_NOT_SUPPORTED;
-  }
-  else if (api_parse (&msg[1].info[1], msg[1].length, "w", dtmf_parms))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    Info = _WRONG_MESSAGE_FORMAT;
-  }
+	Info = GOOD;
+	result[0] = 2;
+	PUT_WORD(&result[1], DTMF_SUCCESS);
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	mask = 0x01;
+	switch (plci->dtmf_cmd)
+	{
 
-  else if ((GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
-    || (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES))
-  {
-    if (!((a->requested_options_table[appl->Id-1])
-        & (1L << PRIVATE_DTMF_TONE)))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info)));
-      PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST);
-    }
-    else
-    {
-      for (i = 0; i < 32; i++)
-        result[4 + i] = 0;
-      if (GET_WORD (dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
-      {
-        for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
-        {
-          if (dtmf_digit_map[i].listen_mask != 0)
-            result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
-        }
-      }
-      else
-      {
-        for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
-        {
-          if (dtmf_digit_map[i].send_mask != 0)
-            result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
-        }
-      }
-      result[0] = 3 + 32;
-      result[3] = 32;
-    }
-  }
+	case DTMF_LISTEN_TONE_START:
+		mask <<= 1;
+	case DTMF_LISTEN_MF_START:
+		mask <<= 1;
 
-  else if (plci == NULL)
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    Info = _WRONG_IDENTIFIER;
-  }
-  else
+	case DTMF_LISTEN_START:
+		switch (internal_command)
+		{
+		default:
+			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
+								  B1_FACILITY_DTMFR), DTMF_COMMAND_1);
+		case DTMF_COMMAND_1:
+			if (adjust_b_process(Id, plci, Rc) != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			if (plci->internal_command)
+				return;
+		case DTMF_COMMAND_2:
+			if (plci_nl_busy(plci))
+			{
+				plci->internal_command = DTMF_COMMAND_2;
+				return;
+			}
+			plci->internal_command = DTMF_COMMAND_3;
+			dtmf_enable_receiver(plci, (byte)(plci->dtmf_rec_active | mask));
+			return;
+		case DTMF_COMMAND_3:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Enable DTMF receiver failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+
+			plci->tone_last_indication_code = DTMF_SIGNAL_NO_TONE;
+
+			plci->dtmf_rec_active |= mask;
+			break;
+		}
+		break;
+
+
+	case DTMF_LISTEN_TONE_STOP:
+		mask <<= 1;
+	case DTMF_LISTEN_MF_STOP:
+		mask <<= 1;
+
+	case DTMF_LISTEN_STOP:
+		switch (internal_command)
+		{
+		default:
+			plci->dtmf_rec_active &= ~mask;
+			if (plci->dtmf_rec_active)
+				break;
+/*
+  case DTMF_COMMAND_1:
+  if (plci->dtmf_rec_active)
   {
-    if (!plci->State
-     || !plci->NL.Id || plci->nl_remove_id)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-      Info = _WRONG_STATE;
-    }
-    else
-    {
-      plci->command = 0;
-      plci->dtmf_cmd = GET_WORD (dtmf_parms[0].info);
-      mask = 0x01;
-      switch (plci->dtmf_cmd)
-      {
-
-      case DTMF_LISTEN_TONE_START:
-      case DTMF_LISTEN_TONE_STOP:
-        mask <<= 1;
-      case DTMF_LISTEN_MF_START:
-      case DTMF_LISTEN_MF_STOP:
-        mask <<= 1;
-        if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1])
-          & (1L << PRIVATE_DTMF_TONE)))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
-            UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info)));
-          PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST);
-          break;
-        }
-
-      case DTMF_LISTEN_START:
-      case DTMF_LISTEN_STOP:
-        if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
-         && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _FACILITY_NOT_SUPPORTED;
-          break;
-        }
-        if (mask & DTMF_LISTEN_ACTIVE_FLAG)
-        {
-          if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
-          {
-            plci->dtmf_rec_pulse_ms = 0;
-            plci->dtmf_rec_pause_ms = 0;
-          }
-          else
-          {
-            plci->dtmf_rec_pulse_ms = GET_WORD (dtmf_parms[1].info);
-            plci->dtmf_rec_pause_ms = GET_WORD (dtmf_parms[2].info);
-          }
-        }
-        start_internal_command (Id, plci, dtmf_command);
-        return (false);
-
-
-      case DTMF_SEND_TONE:
-        mask <<= 1;
-      case DTMF_SEND_MF:
-        mask <<= 1;
-        if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id-1])
-          & (1L << PRIVATE_DTMF_TONE)))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
-            UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (dtmf_parms[0].info)));
-          PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST);
-          break;
-        }
-
-      case DTMF_DIGITS_SEND:
-        if (api_parse (&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_MESSAGE_FORMAT;
-          break;
-        }
-        if (mask & DTMF_LISTEN_ACTIVE_FLAG)
-        {
-          plci->dtmf_send_pulse_ms = GET_WORD (dtmf_parms[1].info);
-          plci->dtmf_send_pause_ms = GET_WORD (dtmf_parms[2].info);
-        }
-        i = 0;
-        j = 0;
-        while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES))
-        {
-          j = 0;
-          while ((j < DTMF_DIGIT_MAP_ENTRIES)
-            && ((dtmf_parms[3].info[i+1] != dtmf_digit_map[j].character)
-             || ((dtmf_digit_map[j].send_mask & mask) == 0)))
-          {
-            j++;
-          }
-          i++;
-        }
-        if (j == DTMF_DIGIT_MAP_ENTRIES)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Incorrect DTMF digit %02x",
-            UnMapId (Id), (char   *)(FILE_), __LINE__, dtmf_parms[3].info[i]));
-          PUT_WORD (&result[1], DTMF_INCORRECT_DIGIT);
-          break;
-        }
-        if (plci->dtmf_send_requests >= ARRAY_SIZE(plci->dtmf_msg_number_queue))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: DTMF request overrun",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_STATE;
-          break;
-        }
-        api_save_msg (dtmf_parms, "wwws", &plci->saved_msg);
-        start_internal_command (Id, plci, dtmf_command);
-        return (false);
-
-      default:
-        dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, plci->dtmf_cmd));
-        PUT_WORD (&result[1], DTMF_UNKNOWN_REQUEST);
-      }
-    }
-  }
-  sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
-    "wws", Info, SELECTOR_DTMF, result);
-  return (false);
-}
-
-
-static void dtmf_confirmation (dword Id, PLCI   *plci)
-{
-  word i;
-    byte result[4];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  result[0] = 2;
-  PUT_WORD (&result[1], DTMF_SUCCESS);
-  if (plci->dtmf_send_requests != 0)
+  if (plci_nl_busy (plci))
   {
-    sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0],
-      "wws", GOOD, SELECTOR_DTMF, result);
-    (plci->dtmf_send_requests)--;
-    for (i = 0; i < plci->dtmf_send_requests; i++)
-      plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i+1];      
+  plci->internal_command = DTMF_COMMAND_1;
+  return;
   }
-}
-
-
-static void dtmf_indication (dword Id, PLCI   *plci, byte   *msg, word length)
-{
-  word i, j, n;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_indication",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  n = 0;
-  for (i = 1; i < length; i++)
-  {
-    j = 0;
-    while ((j < DTMF_DIGIT_MAP_ENTRIES)
-      && ((msg[i] != dtmf_digit_map[j].code)
-       || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0)))
-    {
-      j++;
-    }
-    if (j < DTMF_DIGIT_MAP_ENTRIES)
-    {
-
-      if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG)
-       && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE)
-       && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE))
-      {
-        if (n + 1 == i)
-        {
-          for (i = length; i > n + 1; i--)
-            msg[i] = msg[i - 1];
-          length++;
-          i++;
-        }
-        msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE;
-      }
-      plci->tone_last_indication_code = dtmf_digit_map[j].character;
-
-      msg[++n] = dtmf_digit_map[j].character;
-    }
+  plci->dtmf_rec_active &= ~mask;
+  plci->internal_command = DTMF_COMMAND_2;
+  dtmf_enable_receiver (plci, false);
+  return;
   }
-  if (n != 0)
+  Rc = OK;
+  case DTMF_COMMAND_2:
+  if ((Rc != OK) && (Rc != OK_FC))
   {
-    msg[0] = (byte) n;
-    sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg);
+  dbug (1, dprintf("[%06lx] %s,%d: Disable DTMF receiver failed %02x",
+  UnMapId (Id), (char far *)(FILE_), __LINE__, Rc));
+  Info = _FACILITY_NOT_SUPPORTED;
+  break;
   }
+*/
+			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
+								  ~(B1_FACILITY_DTMFX | B1_FACILITY_DTMFR)), DTMF_COMMAND_3);
+		case DTMF_COMMAND_3:
+			if (adjust_b_process(Id, plci, Rc) != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Unload DTMF failed",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			if (plci->internal_command)
+				return;
+			break;
+		}
+		break;
+
+
+	case DTMF_SEND_TONE:
+		mask <<= 1;
+	case DTMF_SEND_MF:
+		mask <<= 1;
+
+	case DTMF_DIGITS_SEND:
+		switch (internal_command)
+		{
+		default:
+			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
+								  ((plci->dtmf_parameter_length != 0) ? B1_FACILITY_DTMFX | B1_FACILITY_DTMFR : B1_FACILITY_DTMFX)),
+					   DTMF_COMMAND_1);
+		case DTMF_COMMAND_1:
+			if (adjust_b_process(Id, plci, Rc) != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Load DTMF failed",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			if (plci->internal_command)
+				return;
+		case DTMF_COMMAND_2:
+			if (plci_nl_busy(plci))
+			{
+				plci->internal_command = DTMF_COMMAND_2;
+				return;
+			}
+			plci->dtmf_msg_number_queue[(plci->dtmf_send_requests)++] = plci->number;
+			plci->internal_command = DTMF_COMMAND_3;
+			dtmf_send_digits(plci, &plci->saved_msg.parms[3].info[1], plci->saved_msg.parms[3].length);
+			return;
+		case DTMF_COMMAND_3:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Send DTMF digits failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				if (plci->dtmf_send_requests != 0)
+					(plci->dtmf_send_requests)--;
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			return;
+		}
+		break;
+	}
+	sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
+	      "wws", Info, SELECTOR_DTMF, result);
+}
+
+
+static byte dtmf_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL   *appl, API_PARSE *msg)
+{
+	word Info;
+	word i, j;
+	byte mask;
+	API_PARSE dtmf_parms[5];
+	byte result[40];
+
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_request",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	Info = GOOD;
+	result[0] = 2;
+	PUT_WORD(&result[1], DTMF_SUCCESS);
+	if (!(a->profile.Global_Options & GL_DTMF_SUPPORTED))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		Info = _FACILITY_NOT_SUPPORTED;
+	}
+	else if (api_parse(&msg[1].info[1], msg[1].length, "w", dtmf_parms))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		Info = _WRONG_MESSAGE_FORMAT;
+	}
+
+	else if ((GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
+		 || (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_SEND_CODES))
+	{
+		if (!((a->requested_options_table[appl->Id - 1])
+		      & (1L << PRIVATE_DTMF_TONE)))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
+			PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
+		}
+		else
+		{
+			for (i = 0; i < 32; i++)
+				result[4 + i] = 0;
+			if (GET_WORD(dtmf_parms[0].info) == DTMF_GET_SUPPORTED_DETECT_CODES)
+			{
+				for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
+				{
+					if (dtmf_digit_map[i].listen_mask != 0)
+						result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
+				}
+			}
+			else
+			{
+				for (i = 0; i < DTMF_DIGIT_MAP_ENTRIES; i++)
+				{
+					if (dtmf_digit_map[i].send_mask != 0)
+						result[4 + (dtmf_digit_map[i].character >> 3)] |= (1 << (dtmf_digit_map[i].character & 0x7));
+				}
+			}
+			result[0] = 3 + 32;
+			result[3] = 32;
+		}
+	}
+
+	else if (plci == NULL)
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		Info = _WRONG_IDENTIFIER;
+	}
+	else
+	{
+		if (!plci->State
+		    || !plci->NL.Id || plci->nl_remove_id)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+			Info = _WRONG_STATE;
+		}
+		else
+		{
+			plci->command = 0;
+			plci->dtmf_cmd = GET_WORD(dtmf_parms[0].info);
+			mask = 0x01;
+			switch (plci->dtmf_cmd)
+			{
+
+			case DTMF_LISTEN_TONE_START:
+			case DTMF_LISTEN_TONE_STOP:
+				mask <<= 1;
+			case DTMF_LISTEN_MF_START:
+			case DTMF_LISTEN_MF_STOP:
+				mask <<= 1;
+				if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1])
+				      & (1L << PRIVATE_DTMF_TONE)))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
+							UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
+					PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
+					break;
+				}
+
+			case DTMF_LISTEN_START:
+			case DTMF_LISTEN_STOP:
+				if (!(a->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
+				    && !(a->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _FACILITY_NOT_SUPPORTED;
+					break;
+				}
+				if (mask & DTMF_LISTEN_ACTIVE_FLAG)
+				{
+					if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
+					{
+						plci->dtmf_rec_pulse_ms = 0;
+						plci->dtmf_rec_pause_ms = 0;
+					}
+					else
+					{
+						plci->dtmf_rec_pulse_ms = GET_WORD(dtmf_parms[1].info);
+						plci->dtmf_rec_pause_ms = GET_WORD(dtmf_parms[2].info);
+					}
+				}
+				start_internal_command(Id, plci, dtmf_command);
+				return (false);
+
+
+			case DTMF_SEND_TONE:
+				mask <<= 1;
+			case DTMF_SEND_MF:
+				mask <<= 1;
+				if (!((plci->requested_options_conn | plci->requested_options | plci->adapter->requested_options_table[appl->Id - 1])
+				      & (1L << PRIVATE_DTMF_TONE)))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
+							UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(dtmf_parms[0].info)));
+					PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
+					break;
+				}
+
+			case DTMF_DIGITS_SEND:
+				if (api_parse(&msg[1].info[1], msg[1].length, "wwws", dtmf_parms))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				if (mask & DTMF_LISTEN_ACTIVE_FLAG)
+				{
+					plci->dtmf_send_pulse_ms = GET_WORD(dtmf_parms[1].info);
+					plci->dtmf_send_pause_ms = GET_WORD(dtmf_parms[2].info);
+				}
+				i = 0;
+				j = 0;
+				while ((i < dtmf_parms[3].length) && (j < DTMF_DIGIT_MAP_ENTRIES))
+				{
+					j = 0;
+					while ((j < DTMF_DIGIT_MAP_ENTRIES)
+					       && ((dtmf_parms[3].info[i + 1] != dtmf_digit_map[j].character)
+						   || ((dtmf_digit_map[j].send_mask & mask) == 0)))
+					{
+						j++;
+					}
+					i++;
+				}
+				if (j == DTMF_DIGIT_MAP_ENTRIES)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Incorrect DTMF digit %02x",
+							UnMapId(Id), (char *)(FILE_), __LINE__, dtmf_parms[3].info[i]));
+					PUT_WORD(&result[1], DTMF_INCORRECT_DIGIT);
+					break;
+				}
+				if (plci->dtmf_send_requests >= ARRAY_SIZE(plci->dtmf_msg_number_queue))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: DTMF request overrun",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_STATE;
+					break;
+				}
+				api_save_msg(dtmf_parms, "wwws", &plci->saved_msg);
+				start_internal_command(Id, plci, dtmf_command);
+				return (false);
+
+			default:
+				dbug(1, dprintf("[%06lx] %s,%d: DTMF unknown request %04x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, plci->dtmf_cmd));
+				PUT_WORD(&result[1], DTMF_UNKNOWN_REQUEST);
+			}
+		}
+	}
+	sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
+	      "wws", Info, SELECTOR_DTMF, result);
+	return (false);
+}
+
+
+static void dtmf_confirmation(dword Id, PLCI *plci)
+{
+	word i;
+	byte result[4];
+
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_confirmation",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	result[0] = 2;
+	PUT_WORD(&result[1], DTMF_SUCCESS);
+	if (plci->dtmf_send_requests != 0)
+	{
+		sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->dtmf_msg_number_queue[0],
+		      "wws", GOOD, SELECTOR_DTMF, result);
+		(plci->dtmf_send_requests)--;
+		for (i = 0; i < plci->dtmf_send_requests; i++)
+			plci->dtmf_msg_number_queue[i] = plci->dtmf_msg_number_queue[i + 1];
+	}
+}
+
+
+static void dtmf_indication(dword Id, PLCI *plci, byte *msg, word length)
+{
+	word i, j, n;
+
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_indication",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	n = 0;
+	for (i = 1; i < length; i++)
+	{
+		j = 0;
+		while ((j < DTMF_DIGIT_MAP_ENTRIES)
+		       && ((msg[i] != dtmf_digit_map[j].code)
+			   || ((dtmf_digit_map[j].listen_mask & plci->dtmf_rec_active) == 0)))
+		{
+			j++;
+		}
+		if (j < DTMF_DIGIT_MAP_ENTRIES)
+		{
+
+			if ((dtmf_digit_map[j].listen_mask & DTMF_TONE_LISTEN_ACTIVE_FLAG)
+			    && (plci->tone_last_indication_code == DTMF_SIGNAL_NO_TONE)
+			    && (dtmf_digit_map[j].character != DTMF_SIGNAL_UNIDENTIFIED_TONE))
+			{
+				if (n + 1 == i)
+				{
+					for (i = length; i > n + 1; i--)
+						msg[i] = msg[i - 1];
+					length++;
+					i++;
+				}
+				msg[++n] = DTMF_SIGNAL_UNIDENTIFIED_TONE;
+			}
+			plci->tone_last_indication_code = dtmf_digit_map[j].character;
+
+			msg[++n] = dtmf_digit_map[j].character;
+		}
+	}
+	if (n != 0)
+	{
+		msg[0] = (byte) n;
+		sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "wS", SELECTOR_DTMF, msg);
+	}
 }
 
 
@@ -10184,90 +10184,90 @@ static void dtmf_indication (dword Id, PLCI   *plci, byte   *msg, word length)
 /* DTMF parameters                                                  */
 /*------------------------------------------------------------------*/
 
-static void dtmf_parameter_write (PLCI   *plci)
+static void dtmf_parameter_write(PLCI *plci)
 {
-  word i;
-    byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2];
+	word i;
+	byte parameter_buffer[DTMF_PARAMETER_BUFFER_SIZE + 2];
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_write",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_write",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-  parameter_buffer[0] = plci->dtmf_parameter_length + 1;
-  parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS;
-  for (i = 0; i < plci->dtmf_parameter_length; i++)
-    parameter_buffer[2+i] = plci->dtmf_parameter_buffer[i];
-  add_p (plci, FTY, parameter_buffer);
-  sig_req (plci, TEL_CTRL, 0);
-  send_req (plci);
+	parameter_buffer[0] = plci->dtmf_parameter_length + 1;
+	parameter_buffer[1] = DSP_CTRL_SET_DTMF_PARAMETERS;
+	for (i = 0; i < plci->dtmf_parameter_length; i++)
+		parameter_buffer[2 + i] = plci->dtmf_parameter_buffer[i];
+	add_p(plci, FTY, parameter_buffer);
+	sig_req(plci, TEL_CTRL, 0);
+	send_req(plci);
 }
 
 
-static void dtmf_parameter_clear_config (PLCI   *plci)
+static void dtmf_parameter_clear_config(PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_clear_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_clear_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-  plci->dtmf_parameter_length = 0;
+	plci->dtmf_parameter_length = 0;
 }
 
 
-static void dtmf_parameter_prepare_switch (dword Id, PLCI   *plci)
+static void dtmf_parameter_prepare_switch(dword Id, PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_prepare_switch",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
 
 }
 
 
-static word dtmf_parameter_save_config (dword Id, PLCI   *plci, byte Rc)
+static word dtmf_parameter_save_config(dword Id, PLCI *plci, byte Rc)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_save_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
 
-  return (GOOD);
+	return (GOOD);
 }
 
 
-static word dtmf_parameter_restore_config (dword Id, PLCI   *plci, byte Rc)
+static word dtmf_parameter_restore_config(dword Id, PLCI *plci, byte Rc)
 {
-  word Info;
+	word Info;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+	dbug(1, dprintf("[%06lx] %s,%d: dtmf_parameter_restore_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
 
-  Info = GOOD;
-  if ((plci->B1_facilities & B1_FACILITY_DTMFR)
-   && (plci->dtmf_parameter_length != 0))
-  {
-    switch (plci->adjust_b_state)
-    {
-    case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
-      plci->internal_command = plci->adjust_b_command;
-      if (plci->sig_req)
-      {
-        plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
-        break;
-      }
-      dtmf_parameter_write (plci);
-      plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2;
-      break;
-    case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _WRONG_STATE;
-        break;
-      }
-      break;
-    }
-  }
-  return (Info);
+	Info = GOOD;
+	if ((plci->B1_facilities & B1_FACILITY_DTMFR)
+	    && (plci->dtmf_parameter_length != 0))
+	{
+		switch (plci->adjust_b_state)
+		{
+		case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
+			plci->internal_command = plci->adjust_b_command;
+			if (plci->sig_req)
+			{
+				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
+				break;
+			}
+			dtmf_parameter_write(plci);
+			plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_2;
+			break;
+		case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Restore DTMF parameters failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _WRONG_STATE;
+				break;
+			}
+			break;
+		}
+	}
+	return (Info);
 }
 
 
@@ -10290,3059 +10290,3059 @@ word li_total_channels;
 /* if channels is provided we accept more than one channel.         */
 /*------------------------------------------------------------------*/
 
-static byte chi_to_channel (byte   *chi, dword *pchannelmap)
-{
-  int p;
-  int i;
-  dword map;
-  byte excl;
-  byte ofs;
-  byte ch;
-
-  if (pchannelmap) *pchannelmap = 0;
-  if(!chi[0]) return 0xff;
-  excl = 0;
-
-  if(chi[1] & 0x20) {
-    if(chi[0]==1 && chi[1]==0xac) return 0xfd; /* exclusive d-channel */
-    for(i=1; i<chi[0] && !(chi[i] &0x80); i++);
-    if(i==chi[0] || !(chi[i] &0x80)) return 0xfe;
-    if((chi[1] |0xc8)!=0xe9) return 0xfe;
-    if(chi[1] &0x08) excl = 0x40;
-
-        /* int. id present */
-    if(chi[1] &0x40) {
-      p=i+1;
-      for(i=p; i<chi[0] && !(chi[i] &0x80); i++);
-      if(i==chi[0] || !(chi[i] &0x80)) return 0xfe;
-    }
-
-        /* coding standard, Number/Map, Channel Type */
-    p=i+1;
-    for(i=p; i<chi[0] && !(chi[i] &0x80); i++);
-    if(i==chi[0] || !(chi[i] &0x80)) return 0xfe;
-    if((chi[p]|0xd0)!=0xd3) return 0xfe;
-
-        /* Number/Map */
-    if(chi[p] &0x10) {
-
-        /* map */
-      if((chi[0]-p)==4) ofs = 0;
-      else if((chi[0]-p)==3) ofs = 1;
-      else return 0xfe;
-      ch = 0;
-      map = 0;
-      for(i=0; i<4 && p<chi[0]; i++) {
-        p++;
-        ch += 8;
-        map <<= 8;
-        if(chi[p]) {
-          for (ch=0; !(chi[p] & (1 << ch)); ch++);
-          map |= chi[p];
-        }
-      }
-      ch += ofs;
-      map <<= ofs;
-    }
-    else {
-
-        /* number */
-      p=i+1;
-      ch = chi[p] &0x3f;
-      if(pchannelmap) {
-        if((byte)(chi[0]-p)>30) return 0xfe;
-        map = 0;
-        for(i=p; i<=chi[0]; i++) {
-          if ((chi[i] &0x7f) > 31) return 0xfe;
-          map |= (1L << (chi[i] &0x7f));
-        }
-      }
-      else {
-        if(p!=chi[0]) return 0xfe;
-        if (ch > 31) return 0xfe;
-        map = (1L << ch);
-      }
-      if(chi[p] &0x40) return 0xfe;
-    }
-    if (pchannelmap) *pchannelmap = map;
-    else if (map != ((dword)(1L << ch))) return 0xfe;
-    return (byte)(excl | ch);
-  }
-  else {  /* not PRI */
-    for(i=1; i<chi[0] && !(chi[i] &0x80); i++);
-    if(i!=chi[0] || !(chi[i] &0x80)) return 0xfe;
-    if(chi[1] &0x08) excl = 0x40;
-
-    switch(chi[1] |0x98) {
-    case 0x98: return 0;
-    case 0x99:
-      if (pchannelmap) *pchannelmap = 2;
-      return excl |1;
-    case 0x9a:
-      if (pchannelmap) *pchannelmap = 4;
-      return excl |2;
-    case 0x9b: return 0xff;
-    case 0x9c: return 0xfd; /* d-ch */
-    default: return 0xfe;
-    }
-  }
+static byte chi_to_channel(byte *chi, dword *pchannelmap)
+{
+	int p;
+	int i;
+	dword map;
+	byte excl;
+	byte ofs;
+	byte ch;
+
+	if (pchannelmap) *pchannelmap = 0;
+	if (!chi[0]) return 0xff;
+	excl = 0;
+
+	if (chi[1] & 0x20) {
+		if (chi[0] == 1 && chi[1] == 0xac) return 0xfd; /* exclusive d-channel */
+		for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++);
+		if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
+		if ((chi[1] | 0xc8) != 0xe9) return 0xfe;
+		if (chi[1] & 0x08) excl = 0x40;
+
+		/* int. id present */
+		if (chi[1] & 0x40) {
+			p = i + 1;
+			for (i = p; i < chi[0] && !(chi[i] & 0x80); i++);
+			if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
+		}
+
+		/* coding standard, Number/Map, Channel Type */
+		p = i + 1;
+		for (i = p; i < chi[0] && !(chi[i] & 0x80); i++);
+		if (i == chi[0] || !(chi[i] & 0x80)) return 0xfe;
+		if ((chi[p] | 0xd0) != 0xd3) return 0xfe;
+
+		/* Number/Map */
+		if (chi[p] & 0x10) {
+
+			/* map */
+			if ((chi[0] - p) == 4) ofs = 0;
+			else if ((chi[0] - p) == 3) ofs = 1;
+			else return 0xfe;
+			ch = 0;
+			map = 0;
+			for (i = 0; i < 4 && p < chi[0]; i++) {
+				p++;
+				ch += 8;
+				map <<= 8;
+				if (chi[p]) {
+					for (ch = 0; !(chi[p] & (1 << ch)); ch++);
+					map |= chi[p];
+				}
+			}
+			ch += ofs;
+			map <<= ofs;
+		}
+		else {
+
+			/* number */
+			p = i + 1;
+			ch = chi[p] & 0x3f;
+			if (pchannelmap) {
+				if ((byte)(chi[0] - p) > 30) return 0xfe;
+				map = 0;
+				for (i = p; i <= chi[0]; i++) {
+					if ((chi[i] & 0x7f) > 31) return 0xfe;
+					map |= (1L << (chi[i] & 0x7f));
+				}
+			}
+			else {
+				if (p != chi[0]) return 0xfe;
+				if (ch > 31) return 0xfe;
+				map = (1L << ch);
+			}
+			if (chi[p] & 0x40) return 0xfe;
+		}
+		if (pchannelmap) *pchannelmap = map;
+		else if (map != ((dword)(1L << ch))) return 0xfe;
+		return (byte)(excl | ch);
+	}
+	else {  /* not PRI */
+		for (i = 1; i < chi[0] && !(chi[i] & 0x80); i++);
+		if (i != chi[0] || !(chi[i] & 0x80)) return 0xfe;
+		if (chi[1] & 0x08) excl = 0x40;
+
+		switch (chi[1] | 0x98) {
+		case 0x98: return 0;
+		case 0x99:
+			if (pchannelmap) *pchannelmap = 2;
+			return excl | 1;
+		case 0x9a:
+			if (pchannelmap) *pchannelmap = 4;
+			return excl | 2;
+		case 0x9b: return 0xff;
+		case 0x9c: return 0xfd; /* d-ch */
+		default: return 0xfe;
+		}
+	}
+}
+
+
+static void mixer_set_bchannel_id_esc(PLCI *plci, byte bchannel_id)
+{
+	DIVA_CAPI_ADAPTER *a;
+	PLCI *splci;
+	byte old_id;
+
+	a = plci->adapter;
+	old_id = plci->li_bchannel_id;
+	if (a->li_pri)
+	{
+		if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
+			li_config_table[a->li_base + (old_id - 1)].plci = NULL;
+		plci->li_bchannel_id = (bchannel_id & 0x1f) + 1;
+		if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
+			li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
+	}
+	else
+	{
+		if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2))
+		{
+			if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
+				li_config_table[a->li_base + (old_id - 1)].plci = NULL;
+			plci->li_bchannel_id = bchannel_id & 0x03;
+			if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
+			{
+				splci = a->AdvSignalPLCI;
+				if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
+				{
+					if ((splci->li_bchannel_id != 0)
+					    && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
+					{
+						li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
+					}
+					splci->li_bchannel_id = 3 - plci->li_bchannel_id;
+					li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
+					dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d",
+							(dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)),
+							(char *)(FILE_), __LINE__, splci->li_bchannel_id));
+				}
+			}
+			if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
+				li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
+		}
+	}
+	if ((old_id == 0) && (plci->li_bchannel_id != 0)
+	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		mixer_clear_config(plci);
+	}
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id));
+}
+
+
+static void mixer_set_bchannel_id(PLCI *plci, byte *chi)
+{
+	DIVA_CAPI_ADAPTER *a;
+	PLCI *splci;
+	byte ch, old_id;
+
+	a = plci->adapter;
+	old_id = plci->li_bchannel_id;
+	ch = chi_to_channel(chi, NULL);
+	if (!(ch & 0x80))
+	{
+		if (a->li_pri)
+		{
+			if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
+				li_config_table[a->li_base + (old_id - 1)].plci = NULL;
+			plci->li_bchannel_id = (ch & 0x1f) + 1;
+			if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
+				li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
+		}
+		else
+		{
+			if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2))
+			{
+				if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
+					li_config_table[a->li_base + (old_id - 1)].plci = NULL;
+				plci->li_bchannel_id = ch & 0x1f;
+				if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
+				{
+					splci = a->AdvSignalPLCI;
+					if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
+					{
+						if ((splci->li_bchannel_id != 0)
+						    && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
+						{
+							li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
+						}
+						splci->li_bchannel_id = 3 - plci->li_bchannel_id;
+						li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
+						dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
+								(dword)((splci->Id << 8) | UnMapController(splci->adapter->Id)),
+								(char *)(FILE_), __LINE__, splci->li_bchannel_id));
+					}
+				}
+				if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
+					li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
+			}
+		}
+	}
+	if ((old_id == 0) && (plci->li_bchannel_id != 0)
+	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		mixer_clear_config(plci);
+	}
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, ch, plci->li_bchannel_id));
 }
 
 
-static void mixer_set_bchannel_id_esc (PLCI   *plci, byte bchannel_id)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  PLCI   *splci;
-  byte old_id;
+#define MIXER_MAX_DUMP_CHANNELS 34
 
-  a = plci->adapter;
-  old_id = plci->li_bchannel_id;
-  if (a->li_pri)
-  {
-    if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
-      li_config_table[a->li_base + (old_id - 1)].plci = NULL;
-    plci->li_bchannel_id = (bchannel_id & 0x1f) + 1;
-    if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
-      li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
-  }
-  else
-  {
-    if (((bchannel_id & 0x03) == 1) || ((bchannel_id & 0x03) == 2))
-    {
-      if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
-        li_config_table[a->li_base + (old_id - 1)].plci = NULL;
-      plci->li_bchannel_id = bchannel_id & 0x03;
-      if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
-      {
-        splci = a->AdvSignalPLCI;
-        if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
-        {
-          if ((splci->li_bchannel_id != 0)
-           && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
-          {
-            li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
-          }
-          splci->li_bchannel_id = 3 - plci->li_bchannel_id;
-          li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
-          dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id_esc %d",
-            (dword)((splci->Id << 8) | UnMapController (splci->adapter->Id)),
-            (char   *)(FILE_), __LINE__, splci->li_bchannel_id));
-        }
-      }
-      if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
-        li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
-    }
-  }
-  if ((old_id == 0) && (plci->li_bchannel_id != 0)
-   && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    mixer_clear_config (plci);
-  }
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id_esc %d %d",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, bchannel_id, plci->li_bchannel_id));
+static void mixer_calculate_coefs(DIVA_CAPI_ADAPTER *a)
+{
+	static char hex_digit_table[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+	word n, i, j;
+	char *p;
+	char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4];
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_calculate_coefs",
+			(dword)(UnMapController(a->Id)), (char *)(FILE_), __LINE__));
+
+	for (i = 0; i < li_total_channels; i++)
+	{
+		li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET;
+		if (li_config_table[i].chflags != 0)
+			li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
+		else
+		{
+			for (j = 0; j < li_total_channels; j++)
+			{
+				if (((li_config_table[i].flag_table[j]) != 0)
+				    || ((li_config_table[j].flag_table[i]) != 0))
+				{
+					li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
+				}
+				if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0)
+				    || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0))
+				{
+					li_config_table[i].channel |= LI_CHANNEL_CONFERENCE;
+				}
+			}
+		}
+	}
+	for (i = 0; i < li_total_channels; i++)
+	{
+		for (j = 0; j < li_total_channels; j++)
+		{
+			li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC);
+			if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE)
+				li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
+		}
+	}
+	for (n = 0; n < li_total_channels; n++)
+	{
+		if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE)
+		{
+			for (i = 0; i < li_total_channels; i++)
+			{
+				if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE)
+				{
+					for (j = 0; j < li_total_channels; j++)
+					{
+						li_config_table[i].coef_table[j] |=
+							li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j];
+					}
+				}
+			}
+		}
+	}
+	for (i = 0; i < li_total_channels; i++)
+	{
+		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
+		{
+			li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH;
+			for (j = 0; j < li_total_channels; j++)
+			{
+				if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH)
+					li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE;
+			}
+			if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE)
+				li_config_table[i].coef_table[i] |= LI_COEF_CH_CH;
+		}
+	}
+	for (i = 0; i < li_total_channels; i++)
+	{
+		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
+		{
+			for (j = 0; j < li_total_channels; j++)
+			{
+				if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
+					li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
+				if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR)
+					li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
+				if (li_config_table[i].flag_table[j] & LI_FLAG_MIX)
+					li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
+				if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT)
+					li_config_table[i].coef_table[j] |= LI_COEF_PC_PC;
+			}
+			if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
+			{
+				for (j = 0; j < li_total_channels; j++)
+				{
+					if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
+					{
+						li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
+						if (li_config_table[j].chflags & LI_CHFLAG_MIX)
+							li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC;
+					}
+				}
+			}
+			if (li_config_table[i].chflags & LI_CHFLAG_MIX)
+			{
+				for (j = 0; j < li_total_channels; j++)
+				{
+					if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)
+						li_config_table[j].coef_table[i] |= LI_COEF_PC_CH;
+				}
+			}
+			if (li_config_table[i].chflags & LI_CHFLAG_LOOP)
+			{
+				for (j = 0; j < li_total_channels; j++)
+				{
+					if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
+					{
+						for (n = 0; n < li_total_channels; n++)
+						{
+							if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT)
+							{
+								li_config_table[n].coef_table[j] |= LI_COEF_CH_CH;
+								if (li_config_table[j].chflags & LI_CHFLAG_MIX)
+								{
+									li_config_table[n].coef_table[j] |= LI_COEF_PC_CH;
+									if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
+										li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC;
+								}
+								else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
+									li_config_table[n].coef_table[j] |= LI_COEF_CH_PC;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	for (i = 0; i < li_total_channels; i++)
+	{
+		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
+		{
+			if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP))
+				li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
+			if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
+				li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
+			if (li_config_table[i].chflags & LI_CHFLAG_MIX)
+				li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
+			for (j = 0; j < li_total_channels; j++)
+			{
+				if ((li_config_table[i].flag_table[j] &
+				     (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR))
+				    || (li_config_table[j].flag_table[i] &
+					(LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)))
+				{
+					li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
+				}
+				if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR))
+					li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
+				if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))
+					li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
+			}
+			if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE))
+			{
+				li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC;
+				li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA;
+			}
+		}
+	}
+	for (i = 0; i < li_total_channels; i++)
+	{
+		if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
+		{
+			j = 0;
+			while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT))
+				j++;
+			if (j < li_total_channels)
+			{
+				for (j = 0; j < li_total_channels; j++)
+				{
+					li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH);
+					if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)
+						li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
+				}
+			}
+		}
+	}
+	n = li_total_channels;
+	if (n > MIXER_MAX_DUMP_CHANNELS)
+		n = MIXER_MAX_DUMP_CHANNELS;
+	p = hex_line;
+	for (j = 0; j < n; j++)
+	{
+		if ((j & 0x7) == 0)
+			*(p++) = ' ';
+		*(p++) = hex_digit_table[li_config_table[j].curchnl >> 4];
+		*(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf];
+	}
+	*p = '\0';
+	dbug(1, dprintf("[%06lx] CURRENT %s",
+			(dword)(UnMapController(a->Id)), (char *)hex_line));
+	p = hex_line;
+	for (j = 0; j < n; j++)
+	{
+		if ((j & 0x7) == 0)
+			*(p++) = ' ';
+		*(p++) = hex_digit_table[li_config_table[j].channel >> 4];
+		*(p++) = hex_digit_table[li_config_table[j].channel & 0xf];
+	}
+	*p = '\0';
+	dbug(1, dprintf("[%06lx] CHANNEL %s",
+			(dword)(UnMapController(a->Id)), (char *)hex_line));
+	p = hex_line;
+	for (j = 0; j < n; j++)
+	{
+		if ((j & 0x7) == 0)
+			*(p++) = ' ';
+		*(p++) = hex_digit_table[li_config_table[j].chflags >> 4];
+		*(p++) = hex_digit_table[li_config_table[j].chflags & 0xf];
+	}
+	*p = '\0';
+	dbug(1, dprintf("[%06lx] CHFLAG  %s",
+			(dword)(UnMapController(a->Id)), (char *)hex_line));
+	for (i = 0; i < n; i++)
+	{
+		p = hex_line;
+		for (j = 0; j < n; j++)
+		{
+			if ((j & 0x7) == 0)
+				*(p++) = ' ';
+			*(p++) = hex_digit_table[li_config_table[i].flag_table[j] >> 4];
+			*(p++) = hex_digit_table[li_config_table[i].flag_table[j] & 0xf];
+		}
+		*p = '\0';
+		dbug(1, dprintf("[%06lx] FLAG[%02x]%s",
+				(dword)(UnMapController(a->Id)), i, (char *)hex_line));
+	}
+	for (i = 0; i < n; i++)
+	{
+		p = hex_line;
+		for (j = 0; j < n; j++)
+		{
+			if ((j & 0x7) == 0)
+				*(p++) = ' ';
+			*(p++) = hex_digit_table[li_config_table[i].coef_table[j] >> 4];
+			*(p++) = hex_digit_table[li_config_table[i].coef_table[j] & 0xf];
+		}
+		*p = '\0';
+		dbug(1, dprintf("[%06lx] COEF[%02x]%s",
+				(dword)(UnMapController(a->Id)), i, (char *)hex_line));
+	}
 }
 
 
-static void mixer_set_bchannel_id (PLCI   *plci, byte   *chi)
+static struct
 {
-  DIVA_CAPI_ADAPTER   *a;
-  PLCI   *splci;
-  byte ch, old_id;
-
-  a = plci->adapter;
-  old_id = plci->li_bchannel_id;
-  ch = chi_to_channel (chi, NULL);
-  if (!(ch & 0x80))
-  {
-    if (a->li_pri)
-    {
-      if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
-        li_config_table[a->li_base + (old_id - 1)].plci = NULL;
-      plci->li_bchannel_id = (ch & 0x1f) + 1;
-      if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
-        li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
-    }
-    else
-    {
-      if (((ch & 0x1f) == 1) || ((ch & 0x1f) == 2))
-      {
-        if ((old_id != 0) && (li_config_table[a->li_base + (old_id - 1)].plci == plci))
-          li_config_table[a->li_base + (old_id - 1)].plci = NULL;
-        plci->li_bchannel_id = ch & 0x1f;
-        if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI != plci) && (a->AdvSignalPLCI->tel == ADV_VOICE))
-        {
-          splci = a->AdvSignalPLCI;
-          if (li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci == NULL)
-          {
-            if ((splci->li_bchannel_id != 0)
-             && (li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci == splci))
-            {
-              li_config_table[a->li_base + (splci->li_bchannel_id - 1)].plci = NULL;
-            }
-            splci->li_bchannel_id = 3 - plci->li_bchannel_id;
-            li_config_table[a->li_base + (2 - plci->li_bchannel_id)].plci = splci;
-            dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
-              (dword)((splci->Id << 8) | UnMapController (splci->adapter->Id)),
-              (char   *)(FILE_), __LINE__, splci->li_bchannel_id));
-          }
-        }
-        if (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == NULL)
-          li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci = plci;
-      }
-    }
-  }
-  if ((old_id == 0) && (plci->li_bchannel_id != 0)
-   && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    mixer_clear_config (plci);
-  }
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_set_bchannel_id %02x %d",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, ch, plci->li_bchannel_id));
-}
-
+	byte mask;
+	byte line_flags;
+} mixer_write_prog_pri[] =
+{
+	{ LI_COEF_CH_CH, 0 },
+	{ LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG },
+	{ LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG },
+	{ LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG }
+};
 
-#define MIXER_MAX_DUMP_CHANNELS 34
+static struct
+{
+	byte from_ch;
+	byte to_ch;
+	byte mask;
+	byte xconnect_override;
+} mixer_write_prog_bri[] =
+{
+	{ 0, 0, LI_COEF_CH_CH, 0x01 },  /* B      to B      */
+	{ 1, 0, LI_COEF_CH_CH, 0x01 },  /* Alt B  to B      */
+	{ 0, 0, LI_COEF_PC_CH, 0x80 },  /* PC     to B      */
+	{ 1, 0, LI_COEF_PC_CH, 0x01 },  /* Alt PC to B      */
+	{ 2, 0, LI_COEF_CH_CH, 0x00 },  /* IC     to B      */
+	{ 3, 0, LI_COEF_CH_CH, 0x00 },  /* Alt IC to B      */
+	{ 0, 0, LI_COEF_CH_PC, 0x80 },  /* B      to PC     */
+	{ 1, 0, LI_COEF_CH_PC, 0x01 },  /* Alt B  to PC     */
+	{ 0, 0, LI_COEF_PC_PC, 0x01 },  /* PC     to PC     */
+	{ 1, 0, LI_COEF_PC_PC, 0x01 },  /* Alt PC to PC     */
+	{ 2, 0, LI_COEF_CH_PC, 0x00 },  /* IC     to PC     */
+	{ 3, 0, LI_COEF_CH_PC, 0x00 },  /* Alt IC to PC     */
+	{ 0, 2, LI_COEF_CH_CH, 0x00 },  /* B      to IC     */
+	{ 1, 2, LI_COEF_CH_CH, 0x00 },  /* Alt B  to IC     */
+	{ 0, 2, LI_COEF_PC_CH, 0x00 },  /* PC     to IC     */
+	{ 1, 2, LI_COEF_PC_CH, 0x00 },  /* Alt PC to IC     */
+	{ 2, 2, LI_COEF_CH_CH, 0x00 },  /* IC     to IC     */
+	{ 3, 2, LI_COEF_CH_CH, 0x00 },  /* Alt IC to IC     */
+	{ 1, 1, LI_COEF_CH_CH, 0x01 },  /* Alt B  to Alt B  */
+	{ 0, 1, LI_COEF_CH_CH, 0x01 },  /* B      to Alt B  */
+	{ 1, 1, LI_COEF_PC_CH, 0x80 },  /* Alt PC to Alt B  */
+	{ 0, 1, LI_COEF_PC_CH, 0x01 },  /* PC     to Alt B  */
+	{ 3, 1, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt B  */
+	{ 2, 1, LI_COEF_CH_CH, 0x00 },  /* IC     to Alt B  */
+	{ 1, 1, LI_COEF_CH_PC, 0x80 },  /* Alt B  to Alt PC */
+	{ 0, 1, LI_COEF_CH_PC, 0x01 },  /* B      to Alt PC */
+	{ 1, 1, LI_COEF_PC_PC, 0x01 },  /* Alt PC to Alt PC */
+	{ 0, 1, LI_COEF_PC_PC, 0x01 },  /* PC     to Alt PC */
+	{ 3, 1, LI_COEF_CH_PC, 0x00 },  /* Alt IC to Alt PC */
+	{ 2, 1, LI_COEF_CH_PC, 0x00 },  /* IC     to Alt PC */
+	{ 1, 3, LI_COEF_CH_CH, 0x00 },  /* Alt B  to Alt IC */
+	{ 0, 3, LI_COEF_CH_CH, 0x00 },  /* B      to Alt IC */
+	{ 1, 3, LI_COEF_PC_CH, 0x00 },  /* Alt PC to Alt IC */
+	{ 0, 3, LI_COEF_PC_CH, 0x00 },  /* PC     to Alt IC */
+	{ 3, 3, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt IC */
+	{ 2, 3, LI_COEF_CH_CH, 0x00 }   /* IC     to Alt IC */
+};
 
-static void mixer_calculate_coefs (DIVA_CAPI_ADAPTER   *a)
+static byte mixer_swapped_index_bri[] =
 {
-static char hex_digit_table[0x10] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
-  word n, i, j;
-  char *p;
-    char hex_line[2 * MIXER_MAX_DUMP_CHANNELS + MIXER_MAX_DUMP_CHANNELS / 8 + 4];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_calculate_coefs",
-    (dword)(UnMapController (a->Id)), (char   *)(FILE_), __LINE__));
-
-  for (i = 0; i < li_total_channels; i++)
-  {
-    li_config_table[i].channel &= LI_CHANNEL_ADDRESSES_SET;
-    if (li_config_table[i].chflags != 0)
-      li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
-    else
-    {
-      for (j = 0; j < li_total_channels; j++)
-      {
-        if (((li_config_table[i].flag_table[j]) != 0)
-         || ((li_config_table[j].flag_table[i]) != 0))
-        {
-          li_config_table[i].channel |= LI_CHANNEL_INVOLVED;
-        }
-        if (((li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE) != 0)
-         || ((li_config_table[j].flag_table[i] & LI_FLAG_CONFERENCE) != 0))
-        {
-          li_config_table[i].channel |= LI_CHANNEL_CONFERENCE;
-        }
-      }
-    }
-  }
-  for (i = 0; i < li_total_channels; i++)
-  {
-    for (j = 0; j < li_total_channels; j++)
-    {
-      li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC);
-      if (li_config_table[i].flag_table[j] & LI_FLAG_CONFERENCE)
-        li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
-    }
-  }
-  for (n = 0; n < li_total_channels; n++)
-  {
-    if (li_config_table[n].channel & LI_CHANNEL_CONFERENCE)
-    {
-      for (i = 0; i < li_total_channels; i++)
-      {
-        if (li_config_table[i].channel & LI_CHANNEL_CONFERENCE)
-        {
-          for (j = 0; j < li_total_channels; j++)
-          {
-            li_config_table[i].coef_table[j] |=
-              li_config_table[i].coef_table[n] & li_config_table[n].coef_table[j];
-          }
-        }
-      }
-    }
-  }
-  for (i = 0; i < li_total_channels; i++)
-  {
-    if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
-    {
-      li_config_table[i].coef_table[i] &= ~LI_COEF_CH_CH;
-      for (j = 0; j < li_total_channels; j++)
-      {
-        if (li_config_table[i].coef_table[j] & LI_COEF_CH_CH)
-          li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE;
-      }
-      if (li_config_table[i].flag_table[i] & LI_FLAG_CONFERENCE)
-        li_config_table[i].coef_table[i] |= LI_COEF_CH_CH;
-    }
-  }
-  for (i = 0; i < li_total_channels; i++)
-  {
-    if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
-    {
-      for (j = 0; j < li_total_channels; j++)
-      {
-        if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
-          li_config_table[i].coef_table[j] |= LI_COEF_CH_CH;
-        if (li_config_table[i].flag_table[j] & LI_FLAG_MONITOR)
-          li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
-        if (li_config_table[i].flag_table[j] & LI_FLAG_MIX)
-          li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
-        if (li_config_table[i].flag_table[j] & LI_FLAG_PCCONNECT)
-          li_config_table[i].coef_table[j] |= LI_COEF_PC_PC;
-      }
-      if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
-      {
-        for (j = 0; j < li_total_channels; j++)
-        {
-          if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
-          {
-            li_config_table[i].coef_table[j] |= LI_COEF_CH_PC;
-            if (li_config_table[j].chflags & LI_CHFLAG_MIX)
-              li_config_table[i].coef_table[j] |= LI_COEF_PC_CH | LI_COEF_PC_PC;
-          }
-        }
-      }
-      if (li_config_table[i].chflags & LI_CHFLAG_MIX)
-      {
-        for (j = 0; j < li_total_channels; j++)
-        {
-          if (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT)
-            li_config_table[j].coef_table[i] |= LI_COEF_PC_CH;
-        }
-      }
-      if (li_config_table[i].chflags & LI_CHFLAG_LOOP)
-      {
-        for (j = 0; j < li_total_channels; j++)
-        {
-          if (li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
-          {
-            for (n = 0; n < li_total_channels; n++)
-            {
-              if (li_config_table[n].flag_table[i] & LI_FLAG_INTERCONNECT)
-              {
-                li_config_table[n].coef_table[j] |= LI_COEF_CH_CH;
-                if (li_config_table[j].chflags & LI_CHFLAG_MIX)
-                {
-                  li_config_table[n].coef_table[j] |= LI_COEF_PC_CH;
-                  if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
-                    li_config_table[n].coef_table[j] |= LI_COEF_CH_PC | LI_COEF_PC_PC;
-                }
-                else if (li_config_table[n].chflags & LI_CHFLAG_MONITOR)
-                  li_config_table[n].coef_table[j] |= LI_COEF_CH_PC;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-  for (i = 0; i < li_total_channels; i++)
-  {
-    if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
-    {
-      if (li_config_table[i].chflags & (LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP))
-        li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
-      if (li_config_table[i].chflags & LI_CHFLAG_MONITOR)
-        li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
-      if (li_config_table[i].chflags & LI_CHFLAG_MIX)
-        li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
-      for (j = 0; j < li_total_channels; j++)
-      {
-        if ((li_config_table[i].flag_table[j] &
-          (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_MONITOR))
-         || (li_config_table[j].flag_table[i] &
-          (LI_FLAG_INTERCONNECT | LI_FLAG_PCCONNECT | LI_FLAG_CONFERENCE | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX)))
-        {
-          li_config_table[i].channel |= LI_CHANNEL_ACTIVE;
-        }
-        if (li_config_table[i].flag_table[j] & (LI_FLAG_PCCONNECT | LI_FLAG_MONITOR))
-          li_config_table[i].channel |= LI_CHANNEL_RX_DATA;
-        if (li_config_table[j].flag_table[i] & (LI_FLAG_PCCONNECT | LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX))
-          li_config_table[i].channel |= LI_CHANNEL_TX_DATA;
-      }
-      if (!(li_config_table[i].channel & LI_CHANNEL_ACTIVE))
-      {
-        li_config_table[i].coef_table[i] |= LI_COEF_PC_CH | LI_COEF_CH_PC;
-        li_config_table[i].channel |= LI_CHANNEL_TX_DATA | LI_CHANNEL_RX_DATA;
-      }
-    }
-  }
-  for (i = 0; i < li_total_channels; i++)
-  {
-    if (li_config_table[i].channel & LI_CHANNEL_INVOLVED)
-    {
-      j = 0;
-      while ((j < li_total_channels) && !(li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT))
-        j++;
-      if (j < li_total_channels)
-      {
-        for (j = 0; j < li_total_channels; j++)
-        {
-          li_config_table[i].coef_table[j] &= ~(LI_COEF_CH_CH | LI_COEF_PC_CH);
-          if (li_config_table[i].flag_table[j] & LI_FLAG_ANNOUNCEMENT)
-            li_config_table[i].coef_table[j] |= LI_COEF_PC_CH;
-        }
-      }
-    }
-  }
-  n = li_total_channels;
-  if (n > MIXER_MAX_DUMP_CHANNELS)
-    n = MIXER_MAX_DUMP_CHANNELS;
-  p = hex_line;
-  for (j = 0; j < n; j++)
-  {
-    if ((j & 0x7) == 0)
-      *(p++) = ' ';
-    *(p++) = hex_digit_table[li_config_table[j].curchnl >> 4];
-    *(p++) = hex_digit_table[li_config_table[j].curchnl & 0xf];
-  }
-  *p = '\0';
-  dbug (1, dprintf ("[%06lx] CURRENT %s",
-    (dword)(UnMapController (a->Id)), (char   *) hex_line));
-  p = hex_line;
-  for (j = 0; j < n; j++)
-  {
-    if ((j & 0x7) == 0)
-      *(p++) = ' ';
-    *(p++) = hex_digit_table[li_config_table[j].channel >> 4];
-    *(p++) = hex_digit_table[li_config_table[j].channel & 0xf];
-  }
-  *p = '\0';
-  dbug (1, dprintf ("[%06lx] CHANNEL %s",
-    (dword)(UnMapController (a->Id)), (char   *) hex_line));
-  p = hex_line;
-  for (j = 0; j < n; j++)
-  {
-    if ((j & 0x7) == 0)
-      *(p++) = ' ';
-    *(p++) = hex_digit_table[li_config_table[j].chflags >> 4];
-    *(p++) = hex_digit_table[li_config_table[j].chflags & 0xf];
-  }
-  *p = '\0';
-  dbug (1, dprintf ("[%06lx] CHFLAG  %s",
-    (dword)(UnMapController (a->Id)), (char   *) hex_line));
-  for (i = 0; i < n; i++)
-  {
-    p = hex_line;
-    for (j = 0; j < n; j++)
-    {
-      if ((j & 0x7) == 0)
-        *(p++) = ' ';
-      *(p++) = hex_digit_table[li_config_table[i].flag_table[j] >> 4];
-      *(p++) = hex_digit_table[li_config_table[i].flag_table[j] & 0xf];
-    }
-    *p = '\0';
-    dbug (1, dprintf ("[%06lx] FLAG[%02x]%s",
-      (dword)(UnMapController (a->Id)), i, (char   *) hex_line));
-  }
-  for (i = 0; i < n; i++)
-  {
-    p = hex_line;
-    for (j = 0; j < n; j++)
-    {
-      if ((j & 0x7) == 0)
-        *(p++) = ' ';
-      *(p++) = hex_digit_table[li_config_table[i].coef_table[j] >> 4];
-      *(p++) = hex_digit_table[li_config_table[i].coef_table[j] & 0xf];
-    }
-    *p = '\0';
-    dbug (1, dprintf ("[%06lx] COEF[%02x]%s",
-      (dword)(UnMapController (a->Id)), i, (char   *) hex_line));
-  }
-}
-
-
-static struct
-{
-  byte mask;
-  byte line_flags;
-} mixer_write_prog_pri[] =
-{
-  { LI_COEF_CH_CH, 0 },
-  { LI_COEF_CH_PC, MIXER_COEF_LINE_TO_PC_FLAG },
-  { LI_COEF_PC_CH, MIXER_COEF_LINE_FROM_PC_FLAG },
-  { LI_COEF_PC_PC, MIXER_COEF_LINE_TO_PC_FLAG | MIXER_COEF_LINE_FROM_PC_FLAG }
-};
+	18,  /* B      to B      */
+	19,  /* Alt B  to B      */
+	20,  /* PC     to B      */
+	21,  /* Alt PC to B      */
+	22,  /* IC     to B      */
+	23,  /* Alt IC to B      */
+	24,  /* B      to PC     */
+	25,  /* Alt B  to PC     */
+	26,  /* PC     to PC     */
+	27,  /* Alt PC to PC     */
+	28,  /* IC     to PC     */
+	29,  /* Alt IC to PC     */
+	30,  /* B      to IC     */
+	31,  /* Alt B  to IC     */
+	32,  /* PC     to IC     */
+	33,  /* Alt PC to IC     */
+	34,  /* IC     to IC     */
+	35,  /* Alt IC to IC     */
+	0,   /* Alt B  to Alt B  */
+	1,   /* B      to Alt B  */
+	2,   /* Alt PC to Alt B  */
+	3,   /* PC     to Alt B  */
+	4,   /* Alt IC to Alt B  */
+	5,   /* IC     to Alt B  */
+	6,   /* Alt B  to Alt PC */
+	7,   /* B      to Alt PC */
+	8,   /* Alt PC to Alt PC */
+	9,   /* PC     to Alt PC */
+	10,  /* Alt IC to Alt PC */
+	11,  /* IC     to Alt PC */
+	12,  /* Alt B  to Alt IC */
+	13,  /* B      to Alt IC */
+	14,  /* Alt PC to Alt IC */
+	15,  /* PC     to Alt IC */
+	16,  /* Alt IC to Alt IC */
+	17   /* IC     to Alt IC */
+};
 
 static struct
 {
-  byte from_ch;
-  byte to_ch;
-  byte mask;
-  byte xconnect_override;
-} mixer_write_prog_bri[] =
-{
-  { 0, 0, LI_COEF_CH_CH, 0x01 },  /* B      to B      */
-  { 1, 0, LI_COEF_CH_CH, 0x01 },  /* Alt B  to B      */
-  { 0, 0, LI_COEF_PC_CH, 0x80 },  /* PC     to B      */
-  { 1, 0, LI_COEF_PC_CH, 0x01 },  /* Alt PC to B      */
-  { 2, 0, LI_COEF_CH_CH, 0x00 },  /* IC     to B      */
-  { 3, 0, LI_COEF_CH_CH, 0x00 },  /* Alt IC to B      */
-  { 0, 0, LI_COEF_CH_PC, 0x80 },  /* B      to PC     */
-  { 1, 0, LI_COEF_CH_PC, 0x01 },  /* Alt B  to PC     */
-  { 0, 0, LI_COEF_PC_PC, 0x01 },  /* PC     to PC     */
-  { 1, 0, LI_COEF_PC_PC, 0x01 },  /* Alt PC to PC     */
-  { 2, 0, LI_COEF_CH_PC, 0x00 },  /* IC     to PC     */
-  { 3, 0, LI_COEF_CH_PC, 0x00 },  /* Alt IC to PC     */
-  { 0, 2, LI_COEF_CH_CH, 0x00 },  /* B      to IC     */
-  { 1, 2, LI_COEF_CH_CH, 0x00 },  /* Alt B  to IC     */
-  { 0, 2, LI_COEF_PC_CH, 0x00 },  /* PC     to IC     */
-  { 1, 2, LI_COEF_PC_CH, 0x00 },  /* Alt PC to IC     */
-  { 2, 2, LI_COEF_CH_CH, 0x00 },  /* IC     to IC     */
-  { 3, 2, LI_COEF_CH_CH, 0x00 },  /* Alt IC to IC     */
-  { 1, 1, LI_COEF_CH_CH, 0x01 },  /* Alt B  to Alt B  */
-  { 0, 1, LI_COEF_CH_CH, 0x01 },  /* B      to Alt B  */
-  { 1, 1, LI_COEF_PC_CH, 0x80 },  /* Alt PC to Alt B  */
-  { 0, 1, LI_COEF_PC_CH, 0x01 },  /* PC     to Alt B  */
-  { 3, 1, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt B  */
-  { 2, 1, LI_COEF_CH_CH, 0x00 },  /* IC     to Alt B  */
-  { 1, 1, LI_COEF_CH_PC, 0x80 },  /* Alt B  to Alt PC */
-  { 0, 1, LI_COEF_CH_PC, 0x01 },  /* B      to Alt PC */
-  { 1, 1, LI_COEF_PC_PC, 0x01 },  /* Alt PC to Alt PC */
-  { 0, 1, LI_COEF_PC_PC, 0x01 },  /* PC     to Alt PC */
-  { 3, 1, LI_COEF_CH_PC, 0x00 },  /* Alt IC to Alt PC */
-  { 2, 1, LI_COEF_CH_PC, 0x00 },  /* IC     to Alt PC */
-  { 1, 3, LI_COEF_CH_CH, 0x00 },  /* Alt B  to Alt IC */
-  { 0, 3, LI_COEF_CH_CH, 0x00 },  /* B      to Alt IC */
-  { 1, 3, LI_COEF_PC_CH, 0x00 },  /* Alt PC to Alt IC */
-  { 0, 3, LI_COEF_PC_CH, 0x00 },  /* PC     to Alt IC */
-  { 3, 3, LI_COEF_CH_CH, 0x00 },  /* Alt IC to Alt IC */
-  { 2, 3, LI_COEF_CH_CH, 0x00 }   /* IC     to Alt IC */
-};
-
-static byte mixer_swapped_index_bri[] =
-{
-  18,  /* B      to B      */
-  19,  /* Alt B  to B      */
-  20,  /* PC     to B      */
-  21,  /* Alt PC to B      */
-  22,  /* IC     to B      */
-  23,  /* Alt IC to B      */
-  24,  /* B      to PC     */
-  25,  /* Alt B  to PC     */
-  26,  /* PC     to PC     */
-  27,  /* Alt PC to PC     */
-  28,  /* IC     to PC     */
-  29,  /* Alt IC to PC     */
-  30,  /* B      to IC     */
-  31,  /* Alt B  to IC     */
-  32,  /* PC     to IC     */
-  33,  /* Alt PC to IC     */
-  34,  /* IC     to IC     */
-  35,  /* Alt IC to IC     */
-  0,   /* Alt B  to Alt B  */
-  1,   /* B      to Alt B  */
-  2,   /* Alt PC to Alt B  */
-  3,   /* PC     to Alt B  */
-  4,   /* Alt IC to Alt B  */
-  5,   /* IC     to Alt B  */
-  6,   /* Alt B  to Alt PC */
-  7,   /* B      to Alt PC */
-  8,   /* Alt PC to Alt PC */
-  9,   /* PC     to Alt PC */
-  10,  /* Alt IC to Alt PC */
-  11,  /* IC     to Alt PC */
-  12,  /* Alt B  to Alt IC */
-  13,  /* B      to Alt IC */
-  14,  /* Alt PC to Alt IC */
-  15,  /* PC     to Alt IC */
-  16,  /* Alt IC to Alt IC */
-  17   /* IC     to Alt IC */
-};
-
-static struct
-{
-  byte mask;
-  byte from_pc;
-  byte to_pc;
-} xconnect_write_prog[] =
-{
-  { LI_COEF_CH_CH, false, false },
-  { LI_COEF_CH_PC, false, true },
-  { LI_COEF_PC_CH, true, false },
-  { LI_COEF_PC_PC, true, true }
-};
-
-
-static void xconnect_query_addresses (PLCI   *plci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word w, ch;
-  byte   *p;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: xconnect_query_addresses",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  a = plci->adapter;
-  if (a->li_pri && ((plci->li_bchannel_id == 0)
-   || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)))
-  {
-    dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
-      (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-      (char   *)(FILE_), __LINE__));
-    return;
-  }
-  p = plci->internal_req_buffer;
-  ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
-  *(p++) = UDATA_REQUEST_XCONNECT_FROM;
-  w = ch;
-  *(p++) = (byte) w;
-  *(p++) = (byte)(w >> 8);
-  w = ch | XCONNECT_CHANNEL_PORT_PC;
-  *(p++) = (byte) w;
-  *(p++) = (byte)(w >> 8);
-  plci->NData[0].P = plci->internal_req_buffer;
-  plci->NData[0].PLength = p - plci->internal_req_buffer;
-  plci->NL.X = plci->NData;
-  plci->NL.ReqCh = 0;
-  plci->NL.Req = plci->nl_req = (byte) N_UDATA;
-  plci->adapter->request (&plci->NL);
-}
-
-
-static void xconnect_write_coefs (PLCI   *plci, word internal_command)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: xconnect_write_coefs %04x",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, internal_command));
-
-  plci->li_write_command = internal_command;
-  plci->li_write_channel = 0;
-}
-
-
-static byte xconnect_write_coefs_process (dword Id, PLCI   *plci, byte Rc)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word w, n, i, j, r, s, to_ch;
-  dword d;
-  byte   *p;
-  struct xconnect_transfer_address_s   *transfer_address;
-  byte ch_map[MIXER_CHANNELS_BRI];
-
-  dbug (1, dprintf ("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->li_write_channel));
-
-  a = plci->adapter;
-  if ((plci->li_bchannel_id == 0)
-   || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
-  {
-    dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    return (true);
-  }
-  i = a->li_base + (plci->li_bchannel_id - 1);
-  j = plci->li_write_channel;
-  p = plci->internal_req_buffer;
-  if (j != 0)
-  {
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: LI write coefs failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      return (false);
-    }
-  }
-  if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-  {
-    r = 0;
-    s = 0;
-    if (j < li_total_channels)
-    {
-      if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET)
-      {
-        s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ?
-            (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) &
-          ((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ?
-            (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH));
-      }
-      r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-      while ((j < li_total_channels)
-        && ((r == 0)
-         || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
-         || (!li_config_table[j].adapter->li_pri
-          && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
-         || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
-           || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
-          && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
-           || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
-         || ((li_config_table[j].adapter->li_base != a->li_base)
-          && !(r & s &
-            ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
-              (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
-            ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
-              (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))))
-      {
-        j++;
-        if (j < li_total_channels)
-          r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-      }
-    }
-    if (j < li_total_channels)
-    {
-      plci->internal_command = plci->li_write_command;
-      if (plci_nl_busy (plci))
-        return (true);
-      to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
-      *(p++) = UDATA_REQUEST_XCONNECT_TO;
-      do
-      {
-        if (li_config_table[j].adapter->li_base != a->li_base)
-        {
-          r &= s &
-            ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
-              (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
-            ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
-              (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC));
-        }
-        n = 0;
-        do
-        {
-          if (r & xconnect_write_prog[n].mask)
-          {
-            if (xconnect_write_prog[n].from_pc)
-              transfer_address = &(li_config_table[j].send_pc);
-            else
-              transfer_address = &(li_config_table[j].send_b);
-            d = transfer_address->card_address.low;
-            *(p++) = (byte) d;
-            *(p++) = (byte)(d >> 8);
-            *(p++) = (byte)(d >> 16);
-            *(p++) = (byte)(d >> 24);
-            d = transfer_address->card_address.high;
-            *(p++) = (byte) d;
-            *(p++) = (byte)(d >> 8);
-            *(p++) = (byte)(d >> 16);
-            *(p++) = (byte)(d >> 24);
-            d = transfer_address->offset;
-            *(p++) = (byte) d;
-            *(p++) = (byte)(d >> 8);
-            *(p++) = (byte)(d >> 16);
-            *(p++) = (byte)(d >> 24);
-            w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch;
-            *(p++) = (byte) w;
-            *(p++) = (byte)(w >> 8);
-            w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 :
-              (li_config_table[i].adapter->u_law ?
-                 (li_config_table[j].adapter->u_law ? 0x80 : 0x86) :
-                 (li_config_table[j].adapter->u_law ? 0x7a : 0x80));
-            *(p++) = (byte) w;
-            *(p++) = (byte) 0;
-            li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4;
-          }
-          n++;
-        } while ((n < ARRAY_SIZE(xconnect_write_prog))
-          && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
-        if (n == ARRAY_SIZE(xconnect_write_prog))
-        {
-          do
-          {
-            j++;
-            if (j < li_total_channels)
-              r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-          } while ((j < li_total_channels)
-            && ((r == 0)
-             || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
-             || (!li_config_table[j].adapter->li_pri
-              && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
-             || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
-               || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
-              && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
-               || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
-             || ((li_config_table[j].adapter->li_base != a->li_base)
-              && !(r & s &
-                ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
-                  (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
-                ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
-                  (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))));
-        }
-      } while ((j < li_total_channels)
-        && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
-    }
-    else if (j == li_total_channels)
-    {
-      plci->internal_command = plci->li_write_command;
-      if (plci_nl_busy (plci))
-        return (true);
-      if (a->li_pri)
-      {
-        *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
-        w = 0;
-        if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
-          w |= MIXER_FEATURE_ENABLE_TX_DATA;
-        if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
-          w |= MIXER_FEATURE_ENABLE_RX_DATA;
-        *(p++) = (byte) w;
-        *(p++) = (byte)(w >> 8);
-      }
-      else
-      {
-        *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
-        w = 0;
-        if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
-         && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
-        {
-          w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
-        }
-        if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
-          w |= MIXER_FEATURE_ENABLE_TX_DATA;
-        if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
-          w |= MIXER_FEATURE_ENABLE_RX_DATA;
-        *(p++) = (byte) w;
-        *(p++) = (byte)(w >> 8);
-        for (j = 0; j < sizeof(ch_map); j += 2)
-        {
-          if (plci->li_bchannel_id == 2)
-          {
-            ch_map[j] = (byte)(j+1);
-            ch_map[j+1] = (byte) j;
-          }
-          else
-          {
-            ch_map[j] = (byte) j;
-            ch_map[j+1] = (byte)(j+1);
-          }
-        }
-        for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
-        {
-          i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
-          j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
-          if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
-          {
-            *p = (mixer_write_prog_bri[n].xconnect_override != 0) ?
-              mixer_write_prog_bri[n].xconnect_override :
-              ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
-            if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI))
-            {
-              w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-              li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
-            }
-          }
-          else
-          {
-            *p = 0x00;
-            if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
-            {
-              w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
-              if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
-                *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
-            }
-          }
-          p++;
-        }
-      }
-      j = li_total_channels + 1;
-    }
-  }
-  else
-  {
-    if (j <= li_total_channels)
-    {
-      plci->internal_command = plci->li_write_command;
-      if (plci_nl_busy (plci))
-        return (true);
-      if (j < a->li_base)
-        j = a->li_base;
-      if (a->li_pri)
-      {
-        *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
-        w = 0;
-        if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
-          w |= MIXER_FEATURE_ENABLE_TX_DATA;
-        if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
-          w |= MIXER_FEATURE_ENABLE_RX_DATA;
-        *(p++) = (byte) w;
-        *(p++) = (byte)(w >> 8);
-        for (n = 0; n < ARRAY_SIZE(mixer_write_prog_pri); n++)
-        {
-          *(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags);
-          for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
-          {
-            w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-            if (w & mixer_write_prog_pri[n].mask)
-            {
-              *(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
-              li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4;
-            }
-            else
-              *(p++) = 0x00;
-          }
-          *(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags);
-          for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
-          {
-            w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4));
-            if (w & mixer_write_prog_pri[n].mask)
-            {
-              *(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
-              li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4;
-            }
-            else
-              *(p++) = 0x00;
-          }
-        }
-      }
-      else
-      {
-        *(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
-        w = 0;
-        if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
-         && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
-        {
-          w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
-        }
-        if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
-          w |= MIXER_FEATURE_ENABLE_TX_DATA;
-        if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
-          w |= MIXER_FEATURE_ENABLE_RX_DATA;
-        *(p++) = (byte) w;
-        *(p++) = (byte)(w >> 8);
-        for (j = 0; j < sizeof(ch_map); j += 2)
-        {
-          if (plci->li_bchannel_id == 2)
-          {
-            ch_map[j] = (byte)(j+1);
-            ch_map[j+1] = (byte) j;
-          }
-          else
-          {
-            ch_map[j] = (byte) j;
-            ch_map[j+1] = (byte)(j+1);
-          }
-        }
-        for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
-        {
-          i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
-          j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
-          if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
-          {
-            *p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
-            w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-            li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
-          }
-          else
-          {
-            *p = 0x00;
-            if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
-            {
-              w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
-              if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
-                *p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
-            }
-          }
-          p++;
-        }
-      }
-      j = li_total_channels + 1;
-    }
-  }
-  plci->li_write_channel = j;
-  if (p != plci->internal_req_buffer)
-  {
-    plci->NData[0].P = plci->internal_req_buffer;
-    plci->NData[0].PLength = p - plci->internal_req_buffer;
-    plci->NL.X = plci->NData;
-    plci->NL.ReqCh = 0;
-    plci->NL.Req = plci->nl_req = (byte) N_UDATA;
-    plci->adapter->request (&plci->NL);
-  }
-  return (true);
-}
-
-
-static void mixer_notify_update (PLCI   *plci, byte others)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word i, w;
-  PLCI   *notify_plci;
-    byte msg[sizeof(CAPI_MSG_HEADER) + 6];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_notify_update %d",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, others));
-
-  a = plci->adapter;
-  if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
-  {
-    if (others)
-      plci->li_notify_update = true;
-    i = 0;
-    do
-    {
-      notify_plci = NULL;
-      if (others)
-      {
-        while ((i < li_total_channels) && (li_config_table[i].plci == NULL))
-          i++;
-        if (i < li_total_channels)
-          notify_plci = li_config_table[i++].plci;
-      }
-      else
-      {
-        if ((plci->li_bchannel_id != 0)
-         && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-        {
-          notify_plci = plci;
-        }
-      }
-      if ((notify_plci != NULL)
-       && !notify_plci->li_notify_update
-       && (notify_plci->appl != NULL)
-       && (notify_plci->State)
-       && notify_plci->NL.Id && !notify_plci->nl_remove_id)
-      {
-        notify_plci->li_notify_update = true;
-        ((CAPI_MSG *) msg)->header.length = 18;
-        ((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id;
-        ((CAPI_MSG *) msg)->header.command = _FACILITY_R;
-        ((CAPI_MSG *) msg)->header.number = 0;
-        ((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id;
-        ((CAPI_MSG *) msg)->header.plci = notify_plci->Id;
-        ((CAPI_MSG *) msg)->header.ncci = 0;
-        ((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT;
-        ((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3;
-        PUT_WORD (&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE);
-        ((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0;
-        w = api_put (notify_plci->appl, (CAPI_MSG *) msg);
-        if (w != _QUEUE_FULL)
-        {
-          if (w != 0)
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: Interconnect notify failed %06x %d",
-              (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-              (char   *)(FILE_), __LINE__,
-              (dword)((notify_plci->Id << 8) | UnMapController (notify_plci->adapter->Id)), w));
-          }
-          notify_plci->li_notify_update = false;
-        }
-      }
-    } while (others && (notify_plci != NULL));
-    if (others)
-      plci->li_notify_update = false;
-  }
-}
-
-
-static void mixer_clear_config (PLCI   *plci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word i, j;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_clear_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  plci->li_notify_update = false;
-  plci->li_plci_b_write_pos = 0;
-  plci->li_plci_b_read_pos = 0;
-  plci->li_plci_b_req_pos = 0;
-  a = plci->adapter;
-  if ((plci->li_bchannel_id != 0)
-   && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    i = a->li_base + (plci->li_bchannel_id - 1);
-    li_config_table[i].curchnl = 0;
-    li_config_table[i].channel = 0;
-    li_config_table[i].chflags = 0;
-    for (j = 0; j < li_total_channels; j++)
-    {
-      li_config_table[j].flag_table[i] = 0;
-      li_config_table[i].flag_table[j] = 0;
-      li_config_table[i].coef_table[j] = 0;
-      li_config_table[j].coef_table[i] = 0;
-    }
-    if (!a->li_pri)
-    {
-      li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
-      if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
-      {
-        i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
-        li_config_table[i].curchnl = 0;
-        li_config_table[i].channel = 0;
-        li_config_table[i].chflags = 0;
-        for (j = 0; j < li_total_channels; j++)
-        {
-          li_config_table[i].flag_table[j] = 0;
-          li_config_table[j].flag_table[i] = 0;
-          li_config_table[i].coef_table[j] = 0;
-          li_config_table[j].coef_table[i] = 0;
-        }
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
-        {
-          i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
-          li_config_table[i].curchnl = 0;
-          li_config_table[i].channel = 0;
-          li_config_table[i].chflags = 0;
-          for (j = 0; j < li_total_channels; j++)
-          {
-            li_config_table[i].flag_table[j] = 0;
-            li_config_table[j].flag_table[i] = 0;
-            li_config_table[i].coef_table[j] = 0;
-            li_config_table[j].coef_table[i] = 0;
-          }
-        }
-      }
-    }
-  }
-}
-
-
-static void mixer_prepare_switch (dword Id, PLCI   *plci)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_prepare_switch",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  do
-  {
-    mixer_indication_coefs_set (Id, plci);
-  } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
-}
-
-
-static word mixer_save_config (dword Id, PLCI   *plci, byte Rc)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word i, j;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_save_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
-
-  a = plci->adapter;
-  if ((plci->li_bchannel_id != 0)
-   && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    i = a->li_base + (plci->li_bchannel_id - 1);
-    for (j = 0; j < li_total_channels; j++)
-    {
-      li_config_table[i].coef_table[j] &= 0xf;
-      li_config_table[j].coef_table[i] &= 0xf;
-    }
-    if (!a->li_pri)
-      li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
-  }
-  return (GOOD);
-}
-
-
-static word mixer_restore_config (dword Id, PLCI   *plci, byte Rc)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word Info;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_restore_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
-
-  Info = GOOD;
-  a = plci->adapter;
-  if ((plci->B1_facilities & B1_FACILITY_MIXER)
-   && (plci->li_bchannel_id != 0)
-   && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    switch (plci->adjust_b_state)
-    {
-    case ADJUST_B_RESTORE_MIXER_1:
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-      {
-        plci->internal_command = plci->adjust_b_command;
-        if (plci_nl_busy (plci))
-        {
-          plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
-          break;
-        }
-        xconnect_query_addresses (plci);
-        plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2;
-        break;
-      }
-      plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
-      Rc = OK;
-    case ADJUST_B_RESTORE_MIXER_2:
-    case ADJUST_B_RESTORE_MIXER_3:
-    case ADJUST_B_RESTORE_MIXER_4:
-      if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Adjust B query addresses failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _WRONG_STATE;
-        break;
-      }
-      if (Rc == OK)
-      {
-        if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
-          plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3;
-        else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)
-          plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
-      }
-      else if (Rc == 0)
-      {
-        if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
-          plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4;
-        else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
-          plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
-      }
-      if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5)
-      {
-        plci->internal_command = plci->adjust_b_command;
-        break;
-      }
-    case ADJUST_B_RESTORE_MIXER_5:
-      xconnect_write_coefs (plci, plci->adjust_b_command);
-      plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6;
-      Rc = OK;
-    case ADJUST_B_RESTORE_MIXER_6:
-      if (!xconnect_write_coefs_process (Id, plci, Rc))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      if (plci->internal_command)
-        break;
-      plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7;
-    case ADJUST_B_RESTORE_MIXER_7:
-      break;
-    }
-  }
-  return (Info);
-}
-
-
-static void mixer_command (dword Id, PLCI   *plci, byte Rc)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word i, internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command,
-    plci->li_cmd));
-
-  a = plci->adapter;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (plci->li_cmd)
-  {
-  case LI_REQ_CONNECT:
-  case LI_REQ_DISCONNECT:
-  case LI_REQ_SILENT_UPDATE:
-    switch (internal_command)
-    {
-    default:
-      if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
-      {
-        adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities |
-          B1_FACILITY_MIXER), MIXER_COMMAND_1);
-      }
-    case MIXER_COMMAND_1:
-      if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
-      {
-        if (adjust_b_process (Id, plci, Rc) != GOOD)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          break;
-        }
-        if (plci->internal_command)
-          return;
-      }
-      plci->li_plci_b_req_pos = plci->li_plci_b_write_pos;
-      if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
-       || ((get_b1_facilities (plci, plci->B1_resource) & B1_FACILITY_MIXER)
-        && (add_b1_facilities (plci, plci->B1_resource, (word)(plci->B1_facilities &
-         ~B1_FACILITY_MIXER)) == plci->B1_resource)))
-      {
-        xconnect_write_coefs (plci, MIXER_COMMAND_2);
-      }
-      else
-      {
-        do
-        {
-          mixer_indication_coefs_set (Id, plci);
-        } while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
-      }
-    case MIXER_COMMAND_2:
-      if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
-       || ((get_b1_facilities (plci, plci->B1_resource) & B1_FACILITY_MIXER)
-        && (add_b1_facilities (plci, plci->B1_resource, (word)(plci->B1_facilities &
-         ~B1_FACILITY_MIXER)) == plci->B1_resource)))
-      {
-        if (!xconnect_write_coefs_process (Id, plci, Rc))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Write mixer coefs failed",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
-          {
-            do
-            {
-              plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ?
-                LI_PLCI_B_QUEUE_ENTRIES-1 : plci->li_plci_b_write_pos - 1;
-              i = (plci->li_plci_b_write_pos == 0) ?
-                LI_PLCI_B_QUEUE_ENTRIES-1 : plci->li_plci_b_write_pos - 1;
-            } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
-              && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
-          }
-          break;
-        }
-        if (plci->internal_command)
-          return;
-      }
-      if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
-      {
-        adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities &
-          ~B1_FACILITY_MIXER), MIXER_COMMAND_3);
-      }
-    case MIXER_COMMAND_3:
-      if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
-      {
-        if (adjust_b_process (Id, plci, Rc) != GOOD)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          break;
-        }
-        if (plci->internal_command)
-          return;
-      }
-      break;
-    }
-    break;
-  }
-  if ((plci->li_bchannel_id == 0)
-   || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
-  {
-    dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out %d",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, (int)(plci->li_bchannel_id)));
-  }
-  else
-  {
-    i = a->li_base + (plci->li_bchannel_id - 1);
-    li_config_table[i].curchnl = plci->li_channel_bits;
-    if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
-    {
-      i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
-      li_config_table[i].curchnl = plci->li_channel_bits;
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
-      {
-        i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
-        li_config_table[i].curchnl = plci->li_channel_bits;
-      }
-    }
-  }
-}
-
-
-static void li_update_connect (dword Id, DIVA_CAPI_ADAPTER   *a, PLCI   *plci,
-  dword plci_b_id, byte connect, dword li_flags)
-{
-  word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
-  PLCI   *plci_b;
-  DIVA_CAPI_ADAPTER   *a_b;
-
-  a_b = &(adapter[MapController ((byte)(plci_b_id & 0x7f)) - 1]);
-  plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
-  ch_a = a->li_base + (plci->li_bchannel_id - 1);
-  if (!a->li_pri && (plci->tel == ADV_VOICE)
-   && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
-  {
-    ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
-    ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
-      a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
-  }
-  else
-  {
-    ch_a_v = ch_a;
-    ch_a_s = ch_a;
-  }
-  ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
-  if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
-   && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
-  {
-    ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
-    ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
-      a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
-  }
-  else
-  {
-    ch_b_v = ch_b;
-    ch_b_s = ch_b;
-  }
-  if (connect)
-  {
-    li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR;
-    li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR;
-    li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
-    li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
-  }
-  li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
-  li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
-  li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
-  li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
-  if (ch_a_v == ch_b_v)
-  {
-    li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE;
-    li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE;
-  }
-  else
-  {
-    if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
-    {
-      for (i = 0; i < li_total_channels; i++)
-      {
-        if (i != ch_a_v)
-          li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE;
-      }
-    }
-    if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
-    {
-      for (i = 0; i < li_total_channels; i++)
-      {
-        if (i != ch_a_s)
-          li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE;
-      }
-    }
-    if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE)
-    {
-      for (i = 0; i < li_total_channels; i++)
-      {
-        if (i != ch_a_v)
-          li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE;
-      }
-    }
-    if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE)
-    {
-      for (i = 0; i < li_total_channels; i++)
-      {
-        if (i != ch_a_s)
-          li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE;
-      }
-    }
-  }
-  if (li_flags & LI_FLAG_CONFERENCE_A_B)
-  {
-    li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
-  }
-  if (li_flags & LI_FLAG_CONFERENCE_B_A)
-  {
-    li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
-  }
-  if (li_flags & LI_FLAG_MONITOR_A)
-  {
-    li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR;
-    li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR;
-  }
-  if (li_flags & LI_FLAG_MONITOR_B)
-  {
-    li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
-    li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
-  }
-  if (li_flags & LI_FLAG_ANNOUNCEMENT_A)
-  {
-    li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
-    li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
-  }
-  if (li_flags & LI_FLAG_ANNOUNCEMENT_B)
-  {
-    li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
-    li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
-  }
-  if (li_flags & LI_FLAG_MIX_A)
-  {
-    li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX;
-    li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX;
-  }
-  if (li_flags & LI_FLAG_MIX_B)
-  {
-    li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX;
-    li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX;
-  }
-  if (ch_a_v != ch_a_s)
-  {
-    li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
-  }
-  if (ch_b_v != ch_b_s)
-  {
-    li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
-  }
-}
-
-
-static void li2_update_connect (dword Id, DIVA_CAPI_ADAPTER   *a, PLCI   *plci,
-  dword plci_b_id, byte connect, dword li_flags)
-{
-  word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
-  PLCI   *plci_b;
-  DIVA_CAPI_ADAPTER   *a_b;
-
-  a_b = &(adapter[MapController ((byte)(plci_b_id & 0x7f)) - 1]);
-  plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
-  ch_a = a->li_base + (plci->li_bchannel_id - 1);
-  if (!a->li_pri && (plci->tel == ADV_VOICE)
-   && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
-  {
-    ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
-    ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
-      a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
-  }
-  else
-  {
-    ch_a_v = ch_a;
-    ch_a_s = ch_a;
-  }
-  ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
-  if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
-   && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
-  {
-    ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
-    ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
-      a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
-  }
-  else
-  {
-    ch_b_v = ch_b;
-    ch_b_s = ch_b;
-  }
-  if (connect)
-  {
-    li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
-    li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
-    li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX;
-    li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX;
-    li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT;
-    li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP);
-  }
-  li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
-  if (li_flags & LI2_FLAG_INTERCONNECT_A_B)
-  {
-    li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
-  }
-  if (li_flags & LI2_FLAG_INTERCONNECT_B_A)
-  {
-    li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
-  }
-  if (li_flags & LI2_FLAG_MONITOR_B)
-  {
-    li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
-    li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
-  }
-  if (li_flags & LI2_FLAG_MIX_B)
-  {
-    li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX;
-    li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX;
-  }
-  if (li_flags & LI2_FLAG_MONITOR_X)
-    li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR;
-  if (li_flags & LI2_FLAG_MIX_X)
-    li_config_table[ch_b].chflags |= LI_CHFLAG_MIX;
-  if (li_flags & LI2_FLAG_LOOP_B)
-  {
-    li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
-    li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
-  }
-  if (li_flags & LI2_FLAG_LOOP_PC)
-    li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT;
-  if (li_flags & LI2_FLAG_LOOP_X)
-    li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP;
-  if (li_flags & LI2_FLAG_PCCONNECT_A_B)
-    li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT;
-  if (li_flags & LI2_FLAG_PCCONNECT_B_A)
-    li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT;
-  if (ch_a_v != ch_a_s)
-  {
-    li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
-  }
-  if (ch_b_v != ch_b_s)
-  {
-    li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
-    li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
-  }
-}
-
-
-static word li_check_main_plci (dword Id, PLCI   *plci)
-{
-  if (plci == NULL)
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    return (_WRONG_IDENTIFIER);
-  }
-  if (!plci->State
-   || !plci->NL.Id || plci->nl_remove_id
-   || (plci->li_bchannel_id == 0))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    return (_WRONG_STATE);
-  }
-  li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci;
-  return (GOOD);
-}
-
-
-static PLCI   *li_check_plci_b (dword Id, PLCI   *plci,
-  dword plci_b_id, word plci_b_write_pos, byte   *p_result)
-{
-  byte ctlr_b;
-  PLCI   *plci_b;
-
-  if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
-    LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
-    return (NULL);
-  }
-  ctlr_b = 0;
-  if ((plci_b_id & 0x7f) != 0)
-  {
-    ctlr_b = MapController ((byte)(plci_b_id & 0x7f));
-    if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
-      ctlr_b = 0;
-  }
-  if ((ctlr_b == 0)
-   || (((plci_b_id >> 8) & 0xff) == 0)
-   || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id));
-    PUT_WORD (p_result, _WRONG_IDENTIFIER);
-    return (NULL);
-  }
-  plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
-  if (!plci_b->State
-   || !plci_b->NL.Id || plci_b->nl_remove_id
-   || (plci_b->li_bchannel_id == 0))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id));
-    PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
-    return (NULL);
-  }
-  li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b;
-  if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
-    ((byte)(UnMapController (plci->adapter->Id) & ~EXT_CONTROLLER))
-   && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-    || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id));
-    PUT_WORD (p_result, _WRONG_IDENTIFIER);
-    return (NULL);
-  }
-  if (!(get_b1_facilities (plci_b, add_b1_facilities (plci_b, plci_b->B1_resource,
-    (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b->B1_resource));
-    PUT_WORD (p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
-    return (NULL);
-  }
-  return (plci_b);
-}
-
-
-static PLCI   *li2_check_plci_b (dword Id, PLCI   *plci,
-  dword plci_b_id, word plci_b_write_pos, byte   *p_result)
-{
-  byte ctlr_b;
-  PLCI   *plci_b;
-
-  if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
-    LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    PUT_WORD (p_result, _WRONG_STATE);
-    return (NULL);
-  }
-  ctlr_b = 0;
-  if ((plci_b_id & 0x7f) != 0)
-  {
-    ctlr_b = MapController ((byte)(plci_b_id & 0x7f));
-    if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
-      ctlr_b = 0;
-  }
-  if ((ctlr_b == 0)
-   || (((plci_b_id >> 8) & 0xff) == 0)
-   || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI invalid second PLCI %08lx",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id));
-    PUT_WORD (p_result, _WRONG_IDENTIFIER);
-    return (NULL);
-  }
-  plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
-  if (!plci_b->State
-   || !plci_b->NL.Id || plci_b->nl_remove_id
-   || (plci_b->li_bchannel_id == 0)
-   || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI peer in wrong state %08lx",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id));
-    PUT_WORD (p_result, _WRONG_STATE);
-    return (NULL);
-  }
-  if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
-    ((byte)(UnMapController (plci->adapter->Id) & ~EXT_CONTROLLER))
-   && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-    || !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI not on same ctrl %08lx",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b_id));
-    PUT_WORD (p_result, _WRONG_IDENTIFIER);
-    return (NULL);
-  }
-  if (!(get_b1_facilities (plci_b, add_b1_facilities (plci_b, plci_b->B1_resource,
-    (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Interconnect peer cannot mix %d",
-      UnMapId (Id), (char   *)(FILE_), __LINE__, plci_b->B1_resource));
-    PUT_WORD (p_result, _WRONG_STATE);
-    return (NULL);
-  }
-  return (plci_b);
-}
-
-
-static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg)
-{
-  word Info;
-  word i;
-  dword d, li_flags, plci_b_id;
-  PLCI   *plci_b;
-    API_PARSE li_parms[3];
-    API_PARSE li_req_parms[3];
-    API_PARSE li_participant_struct[2];
-    API_PARSE li_participant_parms[3];
-  word participant_parms_pos;
-  byte result_buffer[32];
-  byte   *result;
-  word result_pos;
-  word plci_b_write_pos;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_request",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  Info = GOOD;
-  result = result_buffer;
-  result_buffer[0] = 0;
-  if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    Info = _FACILITY_NOT_SUPPORTED;
-  }
-  else if (api_parse (&msg[1].info[1], msg[1].length, "ws", li_parms))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    Info = _WRONG_MESSAGE_FORMAT;
-  }
-  else
-  {
-    result_buffer[0] = 3;
-    PUT_WORD (&result_buffer[1], GET_WORD (li_parms[0].info));
-    result_buffer[3] = 0;
-    switch (GET_WORD (li_parms[0].info))
-    {
-    case LI_GET_SUPPORTED_SERVICES:
-      if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
-      {
-        result_buffer[0] = 17;
-        result_buffer[3] = 14;
-        PUT_WORD (&result_buffer[4], GOOD);
-        d = 0;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH)
-          d |= LI_CONFERENCING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
-          d |= LI_MONITORING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
-          d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-          d |= LI_CROSS_CONTROLLER_SUPPORTED;
-        PUT_DWORD (&result_buffer[6], d);
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-        {
-          d = 0;
-          for (i = 0; i < li_total_channels; i++)
-          {
-            if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-             && (li_config_table[i].adapter->li_pri
-              || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
-            {
-              d++;
-            }
-          }
-        }
-        else
-        {
-          d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
-        }
-        PUT_DWORD (&result_buffer[10], d / 2);
-        PUT_DWORD (&result_buffer[14], d);
-      }
-      else
-      {
-        result_buffer[0] = 25;
-        result_buffer[3] = 22;
-        PUT_WORD (&result_buffer[4], GOOD);
-        d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
-          d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
-          d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC)
-          d |= LI2_PC_LOOPING_SUPPORTED;
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-          d |= LI2_CROSS_CONTROLLER_SUPPORTED;
-        PUT_DWORD (&result_buffer[6], d);
-        d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
-        PUT_DWORD (&result_buffer[10], d / 2);
-        PUT_DWORD (&result_buffer[14], d - 1);
-        if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-        {
-          d = 0;
-          for (i = 0; i < li_total_channels; i++)
-          {
-            if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
-             && (li_config_table[i].adapter->li_pri
-              || (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
-            {
-              d++;
-            }
-          }
-        }
-        PUT_DWORD (&result_buffer[18], d / 2);
-        PUT_DWORD (&result_buffer[22], d - 1);
-      }
-      break;
-
-    case LI_REQ_CONNECT:
-      if (li_parms[1].length == 8)
-      {
-        appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
-        if (api_parse (&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_MESSAGE_FORMAT;
-          break;
-        }
-        plci_b_id = GET_DWORD (li_req_parms[0].info) & 0xffff;
-        li_flags = GET_DWORD (li_req_parms[1].info);
-        Info = li_check_main_plci (Id, plci);
-        result_buffer[0] = 9;
-        result_buffer[3] = 6;
-        PUT_DWORD (&result_buffer[4], plci_b_id);
-        PUT_WORD (&result_buffer[8], GOOD);
-        if (Info != GOOD)
-          break;
-        result = plci->saved_msg.info;
-        for (i = 0; i <= result_buffer[0]; i++)
-          result[i] = result_buffer[i];
-        plci_b_write_pos = plci->li_plci_b_write_pos;
-        plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
-        if (plci_b == NULL)
-          break;
-        li_update_connect (Id, a, plci, plci_b_id, true, li_flags);
-        plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG;
-        plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-        plci->li_plci_b_write_pos = plci_b_write_pos;
-      }
-      else
-      {
-        appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
-        if (api_parse (&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_MESSAGE_FORMAT;
-          break;
-        }
-        li_flags = GET_DWORD (li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A);
-        Info = li_check_main_plci (Id, plci);
-        result_buffer[0] = 7;
-        result_buffer[3] = 4;
-        PUT_WORD (&result_buffer[4], Info);
-        result_buffer[6] = 0;
-        if (Info != GOOD)
-          break;
-        result = plci->saved_msg.info;
-        for (i = 0; i <= result_buffer[0]; i++)
-          result[i] = result_buffer[i];
-        plci_b_write_pos = plci->li_plci_b_write_pos;
-        participant_parms_pos = 0;
-        result_pos = 7;
-        li2_update_connect (Id, a, plci, UnMapId (Id), true, li_flags);
-        while (participant_parms_pos < li_req_parms[1].length)
-        {
-          result[result_pos] = 6;
-          result_pos += 7;
-          PUT_DWORD (&result[result_pos - 6], 0);
-          PUT_WORD (&result[result_pos - 2], GOOD);
-          if (api_parse (&li_req_parms[1].info[1 + participant_parms_pos],
-            (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-              UnMapId (Id), (char   *)(FILE_), __LINE__));
-            PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
-            break;
-          }
-          if (api_parse (&li_participant_struct[0].info[1],
-            li_participant_struct[0].length, "dd", li_participant_parms))
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-              UnMapId (Id), (char   *)(FILE_), __LINE__));
-            PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
-            break;
-          }
-          plci_b_id = GET_DWORD (li_participant_parms[0].info) & 0xffff;
-          li_flags = GET_DWORD (li_participant_parms[1].info);
-          PUT_DWORD (&result[result_pos - 6], plci_b_id);
-          if (sizeof(result) - result_pos < 7)
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun",
-              UnMapId (Id), (char   *)(FILE_), __LINE__));
-            PUT_WORD (&result[result_pos - 2], _WRONG_STATE);
-            break;
-          }
-          plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
-          if (plci_b != NULL)
-          {
-            li2_update_connect (Id, a, plci, plci_b_id, true, li_flags);
-            plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id |
-              ((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A |
-              LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG);
-            plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-          }
-          participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
-            (&li_req_parms[1].info[1]));
-        }
-        result[0] = (byte)(result_pos - 1);
-        result[3] = (byte)(result_pos - 4);
-        result[6] = (byte)(result_pos - 7);
-        i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1;
-        if ((plci_b_write_pos == plci->li_plci_b_read_pos)
-         || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
-        {
-          plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
-          plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-        }
-        else
-          plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
-        plci->li_plci_b_write_pos = plci_b_write_pos;
-      }
-      mixer_calculate_coefs (a);
-      plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
-      mixer_notify_update (plci, true);
-      sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
-        "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
-      plci->command = 0;
-      plci->li_cmd = GET_WORD (li_parms[0].info);
-      start_internal_command (Id, plci, mixer_command);
-      return (false);
-
-    case LI_REQ_DISCONNECT:
-      if (li_parms[1].length == 4)
-      {
-        appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
-        if (api_parse (&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_MESSAGE_FORMAT;
-          break;
-        }
-        plci_b_id = GET_DWORD (li_req_parms[0].info) & 0xffff;
-        Info = li_check_main_plci (Id, plci);
-        result_buffer[0] = 9;
-        result_buffer[3] = 6;
-        PUT_DWORD (&result_buffer[4], GET_DWORD (li_req_parms[0].info));
-        PUT_WORD (&result_buffer[8], GOOD);
-        if (Info != GOOD)
-          break;
-        result = plci->saved_msg.info;
-        for (i = 0; i <= result_buffer[0]; i++)
-          result[i] = result_buffer[i];
-        plci_b_write_pos = plci->li_plci_b_write_pos;
-        plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
-        if (plci_b == NULL)
-          break;
-        li_update_connect (Id, a, plci, plci_b_id, false, 0);
-        plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG;
-        plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-        plci->li_plci_b_write_pos = plci_b_write_pos;
-      }
-      else
-      {
-        appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
-        if (api_parse (&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms))
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_MESSAGE_FORMAT;
-          break;
-        }
-        Info = li_check_main_plci (Id, plci);
-        result_buffer[0] = 7;
-        result_buffer[3] = 4;
-        PUT_WORD (&result_buffer[4], Info);
-        result_buffer[6] = 0;
-        if (Info != GOOD)
-          break;
-        result = plci->saved_msg.info;
-        for (i = 0; i <= result_buffer[0]; i++)
-          result[i] = result_buffer[i];
-        plci_b_write_pos = plci->li_plci_b_write_pos;
-        participant_parms_pos = 0;
-        result_pos = 7;
-        while (participant_parms_pos < li_req_parms[0].length)
-        {
-          result[result_pos] = 6;
-          result_pos += 7;
-          PUT_DWORD (&result[result_pos - 6], 0);
-          PUT_WORD (&result[result_pos - 2], GOOD);
-          if (api_parse (&li_req_parms[0].info[1 + participant_parms_pos],
-            (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-              UnMapId (Id), (char   *)(FILE_), __LINE__));
-            PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
-            break;
-          }
-          if (api_parse (&li_participant_struct[0].info[1],
-            li_participant_struct[0].length, "d", li_participant_parms))
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-              UnMapId (Id), (char   *)(FILE_), __LINE__));
-            PUT_WORD (&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
-            break;
-          }
-          plci_b_id = GET_DWORD (li_participant_parms[0].info) & 0xffff;
-          PUT_DWORD (&result[result_pos - 6], plci_b_id);
-          if (sizeof(result) - result_pos < 7)
-          {
-            dbug (1, dprintf ("[%06lx] %s,%d: LI result overrun",
-              UnMapId (Id), (char   *)(FILE_), __LINE__));
-            PUT_WORD (&result[result_pos - 2], _WRONG_STATE);
-            break;
-          }
-          plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
-          if (plci_b != NULL)
-          {
-            li2_update_connect (Id, a, plci, plci_b_id, false, 0);
-            plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
-            plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-          }
-          participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
-            (&li_req_parms[0].info[1]));
-        }
-        result[0] = (byte)(result_pos - 1);
-        result[3] = (byte)(result_pos - 4);
-        result[6] = (byte)(result_pos - 7);
-        i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1;
-        if ((plci_b_write_pos == plci->li_plci_b_read_pos)
-         || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
-        {
-          plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
-          plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-        }
-        else
-          plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
-        plci->li_plci_b_write_pos = plci_b_write_pos;
-      }
-      mixer_calculate_coefs (a);
-      plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
-      mixer_notify_update (plci, true);
-      sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
-        "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
-      plci->command = 0;
-      plci->li_cmd = GET_WORD (li_parms[0].info);
-      start_internal_command (Id, plci, mixer_command);
-      return (false);
-
-    case LI_REQ_SILENT_UPDATE:
-      if (!plci || !plci->State
-       || !plci->NL.Id || plci->nl_remove_id
-       || (plci->li_bchannel_id == 0)
-       || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        return (false);
-      }
-      plci_b_write_pos = plci->li_plci_b_write_pos;
-      if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
-        LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        return (false);
-      }
-      i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1;
-      if ((plci_b_write_pos == plci->li_plci_b_read_pos)
-       || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
-      {
-        plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
-        plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-      }
-      else
-        plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
-      plci->li_plci_b_write_pos = plci_b_write_pos;
-      plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
-      plci->command = 0;
-      plci->li_cmd = GET_WORD (li_parms[0].info);
-      start_internal_command (Id, plci, mixer_command);
-      return (false);
-
-    default:
-      dbug (1, dprintf ("[%06lx] %s,%d: LI unknown request %04x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, GET_WORD (li_parms[0].info)));
-      Info = _FACILITY_NOT_SUPPORTED;
-    }
-  }
-  sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
-    "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
-  return (false);
-}
-
-
-static void mixer_indication_coefs_set (dword Id, PLCI   *plci)
-{
-  dword d;
-    byte result[12];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
-  {
-    do
-    {
-      d = plci->li_plci_b_queue[plci->li_plci_b_read_pos];
-      if (!(d & LI_PLCI_B_SKIP_FLAG))
-      {
-        if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
-        {
-          if (d & LI_PLCI_B_DISC_FLAG)
-          {
-            result[0] = 5;
-            PUT_WORD (&result[1], LI_IND_DISCONNECT);
-            result[3] = 2;
-            PUT_WORD (&result[4], _LI_USER_INITIATED);
-          }
-          else
-          {
-            result[0] = 7;
-            PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE);
-            result[3] = 4;
-            PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK);
-          }
-        }
-        else
-        {
-          if (d & LI_PLCI_B_DISC_FLAG)
-          {
-            result[0] = 9;
-            PUT_WORD (&result[1], LI_IND_DISCONNECT);
-            result[3] = 6;
-            PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK);
-            PUT_WORD (&result[8], _LI_USER_INITIATED);
-          }
-          else
-          {
-            result[0] = 7;
-            PUT_WORD (&result[1], LI_IND_CONNECT_ACTIVE);
-            result[3] = 4;
-            PUT_DWORD (&result[4], d & ~LI_PLCI_B_FLAG_MASK);
-          }
-        }
-        sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0,
-          "ws", SELECTOR_LINE_INTERCONNECT, result);
-      }
-      plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ?
-        0 : plci->li_plci_b_read_pos + 1;
-    } while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos));
-  }
-}
-
-
-static void mixer_indication_xconnect_from (dword Id, PLCI   *plci, byte   *msg, word length)
-{
-  word i, j, ch;
-  struct xconnect_transfer_address_s s,   *p;
-  DIVA_CAPI_ADAPTER   *a;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, (int) length));
-
-  a = plci->adapter;
-  i = 1;
-  for (i = 1; i < length; i += 16)
-  {
-    s.card_address.low = msg[i] | (msg[i+1] << 8) | (((dword)(msg[i+2])) << 16) | (((dword)(msg[i+3])) << 24);
-    s.card_address.high = msg[i+4] | (msg[i+5] << 8) | (((dword)(msg[i+6])) << 16) | (((dword)(msg[i+7])) << 24);
-    s.offset = msg[i+8] | (msg[i+9] << 8) | (((dword)(msg[i+10])) << 16) | (((dword)(msg[i+11])) << 24);
-    ch = msg[i+12] | (msg[i+13] << 8);
-    j = ch & XCONNECT_CHANNEL_NUMBER_MASK;
-    if (!a->li_pri && (plci->li_bchannel_id == 2))
-      j = 1 - j;
-    j += a->li_base;
-    if (ch & XCONNECT_CHANNEL_PORT_PC)
-      p = &(li_config_table[j].send_pc);
-    else
-      p = &(li_config_table[j].send_b);
-    p->card_address.low = s.card_address.low;
-    p->card_address.high = s.card_address.high;
-    p->offset = s.offset;
-    li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET;
-  }
-  if (plci->internal_command_queue[0]
-   && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
-    || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
-    || (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)))
-  {
-    (*(plci->internal_command_queue[0]))(Id, plci, 0);
-    if (!plci->internal_command)
-      next_internal_command (Id, plci);
-  }
-  mixer_notify_update (plci, true);
-}
-
-
-static void mixer_indication_xconnect_to (dword Id, PLCI   *plci, byte   *msg, word length)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, (int) length));
-
-}
-
-
-static byte mixer_notify_source_removed (PLCI   *plci, dword plci_b_id)
-{
-  word plci_b_write_pos;
-
-  plci_b_write_pos = plci->li_plci_b_write_pos;
-  if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
-    LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1)
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
-      (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-      (char   *)(FILE_), __LINE__));
-    return (false);
-  }
-  plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
-  plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
-  plci->li_plci_b_write_pos = plci_b_write_pos;
-  return (true);
-}
-
-
-static void mixer_remove (PLCI   *plci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  PLCI   *notify_plci;
-  dword plci_b_id;
-  word i, j;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: mixer_remove",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  a = plci->adapter;
-  plci_b_id = (plci->Id << 8) | UnMapController (plci->adapter->Id);
-  if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
-  {
-    if ((plci->li_bchannel_id != 0)
-     && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-    {
-      i = a->li_base + (plci->li_bchannel_id - 1);
-      if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED)
-      {
-        for (j = 0; j < li_total_channels; j++)
-        {
-          if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
-           || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT))
-          {
-            notify_plci = li_config_table[j].plci;
-            if ((notify_plci != NULL)
-             && (notify_plci != plci)
-             && (notify_plci->appl != NULL)
-             && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
-             && (notify_plci->State)
-             && notify_plci->NL.Id && !notify_plci->nl_remove_id)
-            {
-              mixer_notify_source_removed (notify_plci, plci_b_id);
-            }
-          }
-        }
-        mixer_clear_config (plci);
-        mixer_calculate_coefs (a);
-        mixer_notify_update (plci, true);
-      }
-      li_config_table[i].plci = NULL;
-      plci->li_bchannel_id = 0;
-    }
-  }
-}
-
-
-/*------------------------------------------------------------------*/
-/* Echo canceller facilities                                        */
-/*------------------------------------------------------------------*/
-
-
-static void ec_write_parameters (PLCI   *plci)
-{
-  word w;
-    byte parameter_buffer[6];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_write_parameters",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  parameter_buffer[0] = 5;
-  parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS;
-  PUT_WORD (&parameter_buffer[2], plci->ec_idi_options);
-  plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS;
-  w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length;
-  PUT_WORD (&parameter_buffer[4], w);
-  add_p (plci, FTY, parameter_buffer);
-  sig_req (plci, TEL_CTRL, 0);
-  send_req (plci);
-}
-
-
-static void ec_clear_config (PLCI   *plci)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_clear_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
-    LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING;
-  plci->ec_tail_length = 0;
-}
-
-
-static void ec_prepare_switch (dword Id, PLCI   *plci)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_prepare_switch",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-}
-
-
-static word ec_save_config (dword Id, PLCI   *plci, byte Rc)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_save_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
-
-  return (GOOD);
-}
-
-
-static word ec_restore_config (dword Id, PLCI   *plci, byte Rc)
-{
-  word Info;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_restore_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
-
-  Info = GOOD;
-  if (plci->B1_facilities & B1_FACILITY_EC)
-  {
-    switch (plci->adjust_b_state)
-    {
-    case ADJUST_B_RESTORE_EC_1:
-      plci->internal_command = plci->adjust_b_command;
-      if (plci->sig_req)
-      {
-        plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
-        break;
-      }
-      ec_write_parameters (plci);
-      plci->adjust_b_state = ADJUST_B_RESTORE_EC_2;
-      break;
-    case ADJUST_B_RESTORE_EC_2:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Restore EC failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _WRONG_STATE;
-        break;
-      }
-      break;
-    }
-  }
-  return (Info);
-}
-
-
-static void ec_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word internal_command, Info;
-    byte result[8];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command,
-    plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length));
-
-  Info = GOOD;
-  if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
-  {
-    result[0] = 2;
-    PUT_WORD (&result[1], EC_SUCCESS);
-  }
-  else
-  {
-    result[0] = 5;
-    PUT_WORD (&result[1], plci->ec_cmd);
-    result[3] = 2;
-    PUT_WORD (&result[4], GOOD);
-  }
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (plci->ec_cmd)
-  {
-  case EC_ENABLE_OPERATION:
-  case EC_FREEZE_COEFFICIENTS:
-  case EC_RESUME_COEFFICIENT_UPDATE:
-  case EC_RESET_COEFFICIENTS:
-    switch (internal_command)
-    {
-    default:
-      adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities |
-        B1_FACILITY_EC), EC_COMMAND_1);
-    case EC_COMMAND_1:
-      if (adjust_b_process (Id, plci, Rc) != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Load EC failed",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      if (plci->internal_command)
-        return;
-    case EC_COMMAND_2:
-      if (plci->sig_req)
-      {
-        plci->internal_command = EC_COMMAND_2;
-        return;
-      }
-      plci->internal_command = EC_COMMAND_3;
-      ec_write_parameters (plci);
-      return;
-    case EC_COMMAND_3:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Enable EC failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      break;
-    }
-    break;
-
-  case EC_DISABLE_OPERATION:
-    switch (internal_command)
-    {
-    default:
-    case EC_COMMAND_1:
-      if (plci->B1_facilities & B1_FACILITY_EC)
-      {
-        if (plci->sig_req)
-        {
-          plci->internal_command = EC_COMMAND_1;
-          return;
-        }
-        plci->internal_command = EC_COMMAND_2;
-        ec_write_parameters (plci);
-        return;
-      }
-      Rc = OK;
-    case EC_COMMAND_2:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Disable EC failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      adjust_b1_resource (Id, plci, NULL, (word)(plci->B1_facilities &
-        ~B1_FACILITY_EC), EC_COMMAND_3);
-    case EC_COMMAND_3:
-      if (adjust_b_process (Id, plci, Rc) != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Unload EC failed",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _FACILITY_NOT_SUPPORTED;
-        break;
-      }
-      if (plci->internal_command)
-        return;
-      break;
-    }
-    break;
-  }
-  sendf (plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
-    "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
-    PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
-}
-
-
-static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER   *a, PLCI   *plci, APPL   *appl, API_PARSE *msg)
-{
-  word Info;
-  word opt;
-    API_PARSE ec_parms[3];
-    byte result[16];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_request",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  Info = GOOD;
-  result[0] = 0;
-  if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER)))
-  {
-    dbug (1, dprintf ("[%06lx] %s,%d: Facility not supported",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-    Info = _FACILITY_NOT_SUPPORTED;
-  }
-  else
-  {
-    if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
-    {
-      if (api_parse (&msg[1].info[1], msg[1].length, "w", ec_parms))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _WRONG_MESSAGE_FORMAT;
-      }
-      else
-      {
-        if (plci == NULL)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_IDENTIFIER;
-        }
-        else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_STATE;
-        }
-        else
-        {
-          plci->command = 0;
-          plci->ec_cmd = GET_WORD (ec_parms[0].info);
-          plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
-          result[0] = 2;
-          PUT_WORD (&result[1], EC_SUCCESS);
-          if (msg[1].length >= 4)
-          {
-            opt = GET_WORD (&ec_parms[0].info[2]);
-            plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
-              LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
-            if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING))
-              plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
-            if (opt & EC_DETECT_DISABLE_TONE)
-              plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
-            if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
-              plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
-            if (msg[1].length >= 6)
-            {
-              plci->ec_tail_length = GET_WORD (&ec_parms[0].info[4]);
-            }
-          }
-          switch (plci->ec_cmd)
-          {
-          case EC_ENABLE_OPERATION:
-            plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          case EC_DISABLE_OPERATION:
-            plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
-              LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
-              LEC_RESET_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          case EC_FREEZE_COEFFICIENTS:
-            plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          case EC_RESUME_COEFFICIENT_UPDATE:
-            plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          case EC_RESET_COEFFICIENTS:
-            plci->ec_idi_options |= LEC_RESET_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          default:
-            dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x",
-              UnMapId (Id), (char   *)(FILE_), __LINE__, plci->ec_cmd));
-            PUT_WORD (&result[1], EC_UNSUPPORTED_OPERATION);
-          }
-        }
-      }
-    }
-    else
-    {
-      if (api_parse (&msg[1].info[1], msg[1].length, "ws", ec_parms))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Wrong message format",
-          UnMapId (Id), (char   *)(FILE_), __LINE__));
-        Info = _WRONG_MESSAGE_FORMAT;
-      }
-      else
-      {
-        if (GET_WORD (ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES)
-        {
-          result[0] = 11;
-          PUT_WORD (&result[1], EC_GET_SUPPORTED_SERVICES);
-          result[3] = 8;
-          PUT_WORD (&result[4], GOOD);
-          PUT_WORD (&result[6], 0x0007);
-          PUT_WORD (&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH);
-          PUT_WORD (&result[10], 0);
-        }
-        else if (plci == NULL)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong PLCI",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_IDENTIFIER;
-        }
-        else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
-        {
-          dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
-            UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _WRONG_STATE;
-        }
-        else
-        {
-          plci->command = 0;
-          plci->ec_cmd = GET_WORD (ec_parms[0].info);
-          plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
-          result[0] = 5;
-          PUT_WORD (&result[1], plci->ec_cmd);
-          result[3] = 2;
-          PUT_WORD (&result[4], GOOD);
-          plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
-            LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
-          plci->ec_tail_length = 0;
-          if (ec_parms[1].length >= 2)
-          {
-            opt = GET_WORD (&ec_parms[1].info[1]);
-            if (opt & EC_ENABLE_NON_LINEAR_PROCESSING)
-              plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
-            if (opt & EC_DETECT_DISABLE_TONE)
-              plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
-            if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
-              plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
-            if (ec_parms[1].length >= 4)
-            {
-              plci->ec_tail_length = GET_WORD (&ec_parms[1].info[3]);
-            }
-          }
-          switch (plci->ec_cmd)
-          {
-          case EC_ENABLE_OPERATION:
-            plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          case EC_DISABLE_OPERATION:
-            plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
-              LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
-              LEC_RESET_COEFFICIENTS;
-            start_internal_command (Id, plci, ec_command);
-            return (false);
-
-          default:
-            dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x",
-              UnMapId (Id), (char   *)(FILE_), __LINE__, plci->ec_cmd));
-            PUT_WORD (&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP);
-          }
-        }
-      }
-    }
-  }
-  sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
-    "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
-    PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
-  return (false);
-}
-
-
-static void ec_indication (dword Id, PLCI   *plci, byte   *msg, word length)
-{
-    byte result[8];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: ec_indication",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
-
-  if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE))
-  {
-    if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
-    {
-      result[0] = 2;
-      PUT_WORD (&result[1], 0);
-      switch (msg[1])
-      {
-      case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
-        PUT_WORD (&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
-        break;
-      case LEC_DISABLE_TYPE_REVERSED_2100HZ:
-        PUT_WORD (&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
-        break;
-      case LEC_DISABLE_RELEASED:
-        PUT_WORD (&result[1], EC_BYPASS_RELEASED);
-        break;
-      }
-    }
-    else
-    {
-      result[0] = 5;
-      PUT_WORD (&result[1], EC_BYPASS_INDICATION);
-      result[3] = 2;
-      PUT_WORD (&result[4], 0);
-      switch (msg[1])
-      {
-      case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
-        PUT_WORD (&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
-        break;
-      case LEC_DISABLE_TYPE_REVERSED_2100HZ:
-        PUT_WORD (&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
-        break;
-      case LEC_DISABLE_RELEASED:
-        PUT_WORD (&result[4], EC_BYPASS_RELEASED);
-        break;
-      }
-    }
-    sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
-      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
-  }
-}
-
-
-
-/*------------------------------------------------------------------*/
-/* Advanced voice                                                   */
-/*------------------------------------------------------------------*/
-
-static void adv_voice_write_coefs (PLCI   *plci, word write_command)
+	byte mask;
+	byte from_pc;
+	byte to_pc;
+} xconnect_write_prog[] =
 {
-  DIVA_CAPI_ADAPTER   *a;
-  word i;
-  byte *p;
-
-  word w, n, j, k;
-  byte ch_map[MIXER_CHANNELS_BRI];
-
-    byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_write_coefs %d",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, write_command));
-
-  a = plci->adapter;
-  p = coef_buffer + 1;
-  *(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS;
-  i = 0;
-  while (i + sizeof(word) <= a->adv_voice_coef_length)
-  {
-    PUT_WORD (p, GET_WORD (a->adv_voice_coef_buffer + i));
-    p += 2;
-    i += 2;
-  }
-  while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word))
-  {
-    PUT_WORD (p, 0x8000);
-    p += 2;
-    i += 2;
-  }
+	{ LI_COEF_CH_CH, false, false },
+	{ LI_COEF_CH_PC, false, true },
+	{ LI_COEF_PC_CH, true, false },
+	{ LI_COEF_PC_PC, true, true }
+};
 
-  if (!a->li_pri && (plci->li_bchannel_id == 0))
-  {
-    if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL))
-    {
-      plci->li_bchannel_id = 1;
-      li_config_table[a->li_base].plci = plci;
-      dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
-        (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-        (char   *)(FILE_), __LINE__, plci->li_bchannel_id));
-    }
-    else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL))
-    {
-      plci->li_bchannel_id = 2;
-      li_config_table[a->li_base + 1].plci = plci;
-      dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
-        (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-        (char   *)(FILE_), __LINE__, plci->li_bchannel_id));
-    }
-  }
-  if (!a->li_pri && (plci->li_bchannel_id != 0)
-   && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    i = a->li_base + (plci->li_bchannel_id - 1);
-    switch (write_command)
-    {
-    case ADV_VOICE_WRITE_ACTIVATION:
-      j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
-      k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
-      if (!(plci->B1_facilities & B1_FACILITY_MIXER))
-      {
-        li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
-        li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
-      }
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
-      {
-        li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
-        li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
-        li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE;
-        li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE;
-      }
-      mixer_calculate_coefs (a);
-      li_config_table[i].curchnl = li_config_table[i].channel;
-      li_config_table[j].curchnl = li_config_table[j].channel;
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
-        li_config_table[k].curchnl = li_config_table[k].channel;
-      break;
-
-    case ADV_VOICE_WRITE_DEACTIVATION:
-      for (j = 0; j < li_total_channels; j++)
-      {
-        li_config_table[i].flag_table[j] = 0;
-        li_config_table[j].flag_table[i] = 0;
-      }
-      k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
-      for (j = 0; j < li_total_channels; j++)
-      {
-        li_config_table[k].flag_table[j] = 0;
-        li_config_table[j].flag_table[k] = 0;
-      }
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
-      {
-        k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
-        for (j = 0; j < li_total_channels; j++)
-        {
-          li_config_table[k].flag_table[j] = 0;
-          li_config_table[j].flag_table[k] = 0;
-        }
-      }
-      mixer_calculate_coefs (a);
-      break;
-    }
-    if (plci->B1_facilities & B1_FACILITY_MIXER)
-    {
-      w = 0;
-      if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)
-        w = GET_WORD (a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
-      if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
-        w |= MIXER_FEATURE_ENABLE_TX_DATA;
-      if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
-        w |= MIXER_FEATURE_ENABLE_RX_DATA;
-      *(p++) = (byte) w;
-      *(p++) = (byte)(w >> 8);
-      for (j = 0; j < sizeof(ch_map); j += 2)
-      {
-        ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1));
-        ch_map[j+1] = (byte)(j + (2 - plci->li_bchannel_id));
-      }
-      for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
-      {
-        i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
-        j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
-        if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
-        {
-          *(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
-          w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
-          li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
-        }
-        else
-        {
-          *(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ?
-            a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00;
-        }
-      }
-    }
-    else
-    {
-      for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
-        *(p++) = a->adv_voice_coef_buffer[i];
-    }
-  }
-  else
 
-  {
-    for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
-      *(p++) = a->adv_voice_coef_buffer[i];
-  }
-  coef_buffer[0] = (p - coef_buffer) - 1;
-  add_p (plci, FTY, coef_buffer);
-  sig_req (plci, TEL_CTRL, 0);
-  send_req (plci);
+static void xconnect_query_addresses(PLCI *plci)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word w, ch;
+	byte *p;
+
+	dbug(1, dprintf("[%06lx] %s,%d: xconnect_query_addresses",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
+
+	a = plci->adapter;
+	if (a->li_pri && ((plci->li_bchannel_id == 0)
+			  || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci)))
+	{
+		dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
+				(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+				(char *)(FILE_), __LINE__));
+		return;
+	}
+	p = plci->internal_req_buffer;
+	ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
+	*(p++) = UDATA_REQUEST_XCONNECT_FROM;
+	w = ch;
+	*(p++) = (byte) w;
+	*(p++) = (byte)(w >> 8);
+	w = ch | XCONNECT_CHANNEL_PORT_PC;
+	*(p++) = (byte) w;
+	*(p++) = (byte)(w >> 8);
+	plci->NData[0].P = plci->internal_req_buffer;
+	plci->NData[0].PLength = p - plci->internal_req_buffer;
+	plci->NL.X = plci->NData;
+	plci->NL.ReqCh = 0;
+	plci->NL.Req = plci->nl_req = (byte) N_UDATA;
+	plci->adapter->request(&plci->NL);
+}
+
+
+static void xconnect_write_coefs(PLCI *plci, word internal_command)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: xconnect_write_coefs %04x",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, internal_command));
+
+	plci->li_write_command = internal_command;
+	plci->li_write_channel = 0;
+}
+
+
+static byte xconnect_write_coefs_process(dword Id, PLCI *plci, byte Rc)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word w, n, i, j, r, s, to_ch;
+	dword d;
+	byte *p;
+	struct xconnect_transfer_address_s   *transfer_address;
+	byte ch_map[MIXER_CHANNELS_BRI];
+
+	dbug(1, dprintf("[%06x] %s,%d: xconnect_write_coefs_process %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->li_write_channel));
+
+	a = plci->adapter;
+	if ((plci->li_bchannel_id == 0)
+	    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
+	{
+		dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		return (true);
+	}
+	i = a->li_base + (plci->li_bchannel_id - 1);
+	j = plci->li_write_channel;
+	p = plci->internal_req_buffer;
+	if (j != 0)
+	{
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: LI write coefs failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			return (false);
+		}
+	}
+	if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+	{
+		r = 0;
+		s = 0;
+		if (j < li_total_channels)
+		{
+			if (li_config_table[i].channel & LI_CHANNEL_ADDRESSES_SET)
+			{
+				s = ((li_config_table[i].send_b.card_address.low | li_config_table[i].send_b.card_address.high) ?
+				     (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_PC | LI_COEF_PC_PC)) &
+					((li_config_table[i].send_pc.card_address.low | li_config_table[i].send_pc.card_address.high) ?
+					 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_PC_CH));
+			}
+			r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+			while ((j < li_total_channels)
+			       && ((r == 0)
+				   || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
+				   || (!li_config_table[j].adapter->li_pri
+				       && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
+				   || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
+					|| (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
+				       && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
+					   || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
+				   || ((li_config_table[j].adapter->li_base != a->li_base)
+				       && !(r & s &
+					    ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
+					     (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
+					    ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
+					     (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))))
+			{
+				j++;
+				if (j < li_total_channels)
+					r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+			}
+		}
+		if (j < li_total_channels)
+		{
+			plci->internal_command = plci->li_write_command;
+			if (plci_nl_busy(plci))
+				return (true);
+			to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
+			*(p++) = UDATA_REQUEST_XCONNECT_TO;
+			do
+			{
+				if (li_config_table[j].adapter->li_base != a->li_base)
+				{
+					r &= s &
+						((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
+						 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
+						((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
+						 (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC));
+				}
+				n = 0;
+				do
+				{
+					if (r & xconnect_write_prog[n].mask)
+					{
+						if (xconnect_write_prog[n].from_pc)
+							transfer_address = &(li_config_table[j].send_pc);
+						else
+							transfer_address = &(li_config_table[j].send_b);
+						d = transfer_address->card_address.low;
+						*(p++) = (byte) d;
+						*(p++) = (byte)(d >> 8);
+						*(p++) = (byte)(d >> 16);
+						*(p++) = (byte)(d >> 24);
+						d = transfer_address->card_address.high;
+						*(p++) = (byte) d;
+						*(p++) = (byte)(d >> 8);
+						*(p++) = (byte)(d >> 16);
+						*(p++) = (byte)(d >> 24);
+						d = transfer_address->offset;
+						*(p++) = (byte) d;
+						*(p++) = (byte)(d >> 8);
+						*(p++) = (byte)(d >> 16);
+						*(p++) = (byte)(d >> 24);
+						w = xconnect_write_prog[n].to_pc ? to_ch | XCONNECT_CHANNEL_PORT_PC : to_ch;
+						*(p++) = (byte) w;
+						*(p++) = (byte)(w >> 8);
+						w = ((li_config_table[i].coef_table[j] & xconnect_write_prog[n].mask) == 0) ? 0x01 :
+							(li_config_table[i].adapter->u_law ?
+							 (li_config_table[j].adapter->u_law ? 0x80 : 0x86) :
+							 (li_config_table[j].adapter->u_law ? 0x7a : 0x80));
+						*(p++) = (byte) w;
+						*(p++) = (byte) 0;
+						li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4;
+					}
+					n++;
+				} while ((n < ARRAY_SIZE(xconnect_write_prog))
+					 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
+				if (n == ARRAY_SIZE(xconnect_write_prog))
+				{
+					do
+					{
+						j++;
+						if (j < li_total_channels)
+							r = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+					} while ((j < li_total_channels)
+						 && ((r == 0)
+						     || (!(li_config_table[j].channel & LI_CHANNEL_ADDRESSES_SET))
+						     || (!li_config_table[j].adapter->li_pri
+							 && (j >= li_config_table[j].adapter->li_base + MIXER_BCHANNELS_BRI))
+						     || (((li_config_table[j].send_b.card_address.low != li_config_table[i].send_b.card_address.low)
+							  || (li_config_table[j].send_b.card_address.high != li_config_table[i].send_b.card_address.high))
+							 && (!(a->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)
+							     || !(li_config_table[j].adapter->manufacturer_features & MANUFACTURER_FEATURE_DMACONNECT)))
+						     || ((li_config_table[j].adapter->li_base != a->li_base)
+							 && !(r & s &
+							      ((li_config_table[j].send_b.card_address.low | li_config_table[j].send_b.card_address.high) ?
+							       (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_PC_CH | LI_COEF_PC_PC)) &
+							      ((li_config_table[j].send_pc.card_address.low | li_config_table[j].send_pc.card_address.high) ?
+							       (LI_COEF_CH_CH | LI_COEF_CH_PC | LI_COEF_PC_CH | LI_COEF_PC_PC) : (LI_COEF_CH_CH | LI_COEF_CH_PC))))));
+				}
+			} while ((j < li_total_channels)
+				 && ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
+		}
+		else if (j == li_total_channels)
+		{
+			plci->internal_command = plci->li_write_command;
+			if (plci_nl_busy(plci))
+				return (true);
+			if (a->li_pri)
+			{
+				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
+				w = 0;
+				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
+					w |= MIXER_FEATURE_ENABLE_TX_DATA;
+				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
+					w |= MIXER_FEATURE_ENABLE_RX_DATA;
+				*(p++) = (byte) w;
+				*(p++) = (byte)(w >> 8);
+			}
+			else
+			{
+				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
+				w = 0;
+				if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
+				    && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
+				{
+					w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
+				}
+				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
+					w |= MIXER_FEATURE_ENABLE_TX_DATA;
+				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
+					w |= MIXER_FEATURE_ENABLE_RX_DATA;
+				*(p++) = (byte) w;
+				*(p++) = (byte)(w >> 8);
+				for (j = 0; j < sizeof(ch_map); j += 2)
+				{
+					if (plci->li_bchannel_id == 2)
+					{
+						ch_map[j] = (byte)(j + 1);
+						ch_map[j + 1] = (byte) j;
+					}
+					else
+					{
+						ch_map[j] = (byte) j;
+						ch_map[j + 1] = (byte)(j + 1);
+					}
+				}
+				for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
+				{
+					i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
+					j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
+					if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
+					{
+						*p = (mixer_write_prog_bri[n].xconnect_override != 0) ?
+							mixer_write_prog_bri[n].xconnect_override :
+							((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
+						if ((i >= a->li_base + MIXER_BCHANNELS_BRI) || (j >= a->li_base + MIXER_BCHANNELS_BRI))
+						{
+							w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+							li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
+						}
+					}
+					else
+					{
+						*p = 0x00;
+						if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
+						{
+							w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
+							if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
+								*p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
+						}
+					}
+					p++;
+				}
+			}
+			j = li_total_channels + 1;
+		}
+	}
+	else
+	{
+		if (j <= li_total_channels)
+		{
+			plci->internal_command = plci->li_write_command;
+			if (plci_nl_busy(plci))
+				return (true);
+			if (j < a->li_base)
+				j = a->li_base;
+			if (a->li_pri)
+			{
+				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
+				w = 0;
+				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
+					w |= MIXER_FEATURE_ENABLE_TX_DATA;
+				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
+					w |= MIXER_FEATURE_ENABLE_RX_DATA;
+				*(p++) = (byte) w;
+				*(p++) = (byte)(w >> 8);
+				for (n = 0; n < ARRAY_SIZE(mixer_write_prog_pri); n++)
+				{
+					*(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags);
+					for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
+					{
+						w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+						if (w & mixer_write_prog_pri[n].mask)
+						{
+							*(p++) = (li_config_table[i].coef_table[j] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
+							li_config_table[i].coef_table[j] ^= mixer_write_prog_pri[n].mask << 4;
+						}
+						else
+							*(p++) = 0x00;
+					}
+					*(p++) = (byte)((plci->li_bchannel_id - 1) | MIXER_COEF_LINE_ROW_FLAG | mixer_write_prog_pri[n].line_flags);
+					for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
+					{
+						w = ((li_config_table[j].coef_table[i] & 0xf) ^ (li_config_table[j].coef_table[i] >> 4));
+						if (w & mixer_write_prog_pri[n].mask)
+						{
+							*(p++) = (li_config_table[j].coef_table[i] & mixer_write_prog_pri[n].mask) ? 0x80 : 0x01;
+							li_config_table[j].coef_table[i] ^= mixer_write_prog_pri[n].mask << 4;
+						}
+						else
+							*(p++) = 0x00;
+					}
+				}
+			}
+			else
+			{
+				*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_BRI;
+				w = 0;
+				if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI)
+				    && (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length))
+				{
+					w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
+				}
+				if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
+					w |= MIXER_FEATURE_ENABLE_TX_DATA;
+				if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
+					w |= MIXER_FEATURE_ENABLE_RX_DATA;
+				*(p++) = (byte) w;
+				*(p++) = (byte)(w >> 8);
+				for (j = 0; j < sizeof(ch_map); j += 2)
+				{
+					if (plci->li_bchannel_id == 2)
+					{
+						ch_map[j] = (byte)(j + 1);
+						ch_map[j + 1] = (byte) j;
+					}
+					else
+					{
+						ch_map[j] = (byte) j;
+						ch_map[j + 1] = (byte)(j + 1);
+					}
+				}
+				for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
+				{
+					i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
+					j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
+					if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
+					{
+						*p = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
+						w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+						li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
+					}
+					else
+					{
+						*p = 0x00;
+						if ((a->AdvSignalPLCI != NULL) && (a->AdvSignalPLCI->tel == ADV_VOICE))
+						{
+							w = (plci == a->AdvSignalPLCI) ? n : mixer_swapped_index_bri[n];
+							if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w < a->adv_voice_coef_length)
+								*p = a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + w];
+						}
+					}
+					p++;
+				}
+			}
+			j = li_total_channels + 1;
+		}
+	}
+	plci->li_write_channel = j;
+	if (p != plci->internal_req_buffer)
+	{
+		plci->NData[0].P = plci->internal_req_buffer;
+		plci->NData[0].PLength = p - plci->internal_req_buffer;
+		plci->NL.X = plci->NData;
+		plci->NL.ReqCh = 0;
+		plci->NL.Req = plci->nl_req = (byte) N_UDATA;
+		plci->adapter->request(&plci->NL);
+	}
+	return (true);
+}
+
+
+static void mixer_notify_update(PLCI *plci, byte others)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word i, w;
+	PLCI *notify_plci;
+	byte msg[sizeof(CAPI_MSG_HEADER) + 6];
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_notify_update %d",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, others));
+
+	a = plci->adapter;
+	if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
+	{
+		if (others)
+			plci->li_notify_update = true;
+		i = 0;
+		do
+		{
+			notify_plci = NULL;
+			if (others)
+			{
+				while ((i < li_total_channels) && (li_config_table[i].plci == NULL))
+					i++;
+				if (i < li_total_channels)
+					notify_plci = li_config_table[i++].plci;
+			}
+			else
+			{
+				if ((plci->li_bchannel_id != 0)
+				    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+				{
+					notify_plci = plci;
+				}
+			}
+			if ((notify_plci != NULL)
+			    && !notify_plci->li_notify_update
+			    && (notify_plci->appl != NULL)
+			    && (notify_plci->State)
+			    && notify_plci->NL.Id && !notify_plci->nl_remove_id)
+			{
+				notify_plci->li_notify_update = true;
+				((CAPI_MSG *) msg)->header.length = 18;
+				((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id;
+				((CAPI_MSG *) msg)->header.command = _FACILITY_R;
+				((CAPI_MSG *) msg)->header.number = 0;
+				((CAPI_MSG *) msg)->header.controller = notify_plci->adapter->Id;
+				((CAPI_MSG *) msg)->header.plci = notify_plci->Id;
+				((CAPI_MSG *) msg)->header.ncci = 0;
+				((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT;
+				((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3;
+				PUT_WORD(&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE);
+				((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0;
+				w = api_put(notify_plci->appl, (CAPI_MSG *) msg);
+				if (w != _QUEUE_FULL)
+				{
+					if (w != 0)
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: Interconnect notify failed %06x %d",
+								(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+								(char *)(FILE_), __LINE__,
+								(dword)((notify_plci->Id << 8) | UnMapController(notify_plci->adapter->Id)), w));
+					}
+					notify_plci->li_notify_update = false;
+				}
+			}
+		} while (others && (notify_plci != NULL));
+		if (others)
+			plci->li_notify_update = false;
+	}
+}
+
+
+static void mixer_clear_config(PLCI *plci)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word i, j;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_clear_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
+
+	plci->li_notify_update = false;
+	plci->li_plci_b_write_pos = 0;
+	plci->li_plci_b_read_pos = 0;
+	plci->li_plci_b_req_pos = 0;
+	a = plci->adapter;
+	if ((plci->li_bchannel_id != 0)
+	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		i = a->li_base + (plci->li_bchannel_id - 1);
+		li_config_table[i].curchnl = 0;
+		li_config_table[i].channel = 0;
+		li_config_table[i].chflags = 0;
+		for (j = 0; j < li_total_channels; j++)
+		{
+			li_config_table[j].flag_table[i] = 0;
+			li_config_table[i].flag_table[j] = 0;
+			li_config_table[i].coef_table[j] = 0;
+			li_config_table[j].coef_table[i] = 0;
+		}
+		if (!a->li_pri)
+		{
+			li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
+			if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
+			{
+				i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
+				li_config_table[i].curchnl = 0;
+				li_config_table[i].channel = 0;
+				li_config_table[i].chflags = 0;
+				for (j = 0; j < li_total_channels; j++)
+				{
+					li_config_table[i].flag_table[j] = 0;
+					li_config_table[j].flag_table[i] = 0;
+					li_config_table[i].coef_table[j] = 0;
+					li_config_table[j].coef_table[i] = 0;
+				}
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
+				{
+					i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
+					li_config_table[i].curchnl = 0;
+					li_config_table[i].channel = 0;
+					li_config_table[i].chflags = 0;
+					for (j = 0; j < li_total_channels; j++)
+					{
+						li_config_table[i].flag_table[j] = 0;
+						li_config_table[j].flag_table[i] = 0;
+						li_config_table[i].coef_table[j] = 0;
+						li_config_table[j].coef_table[i] = 0;
+					}
+				}
+			}
+		}
+	}
+}
+
+
+static void mixer_prepare_switch(dword Id, PLCI *plci)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_prepare_switch",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	do
+	{
+		mixer_indication_coefs_set(Id, plci);
+	} while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
+}
+
+
+static word mixer_save_config(dword Id, PLCI *plci, byte Rc)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word i, j;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_save_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	a = plci->adapter;
+	if ((plci->li_bchannel_id != 0)
+	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		i = a->li_base + (plci->li_bchannel_id - 1);
+		for (j = 0; j < li_total_channels; j++)
+		{
+			li_config_table[i].coef_table[j] &= 0xf;
+			li_config_table[j].coef_table[i] &= 0xf;
+		}
+		if (!a->li_pri)
+			li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
+	}
+	return (GOOD);
+}
+
+
+static word mixer_restore_config(dword Id, PLCI *plci, byte Rc)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word Info;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_restore_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	Info = GOOD;
+	a = plci->adapter;
+	if ((plci->B1_facilities & B1_FACILITY_MIXER)
+	    && (plci->li_bchannel_id != 0)
+	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		switch (plci->adjust_b_state)
+		{
+		case ADJUST_B_RESTORE_MIXER_1:
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+			{
+				plci->internal_command = plci->adjust_b_command;
+				if (plci_nl_busy(plci))
+				{
+					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
+					break;
+				}
+				xconnect_query_addresses(plci);
+				plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_2;
+				break;
+			}
+			plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
+			Rc = OK;
+		case ADJUST_B_RESTORE_MIXER_2:
+		case ADJUST_B_RESTORE_MIXER_3:
+		case ADJUST_B_RESTORE_MIXER_4:
+			if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Adjust B query addresses failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _WRONG_STATE;
+				break;
+			}
+			if (Rc == OK)
+			{
+				if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
+					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_3;
+				else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)
+					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
+			}
+			else if (Rc == 0)
+			{
+				if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
+					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_4;
+				else if (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
+					plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_5;
+			}
+			if (plci->adjust_b_state != ADJUST_B_RESTORE_MIXER_5)
+			{
+				plci->internal_command = plci->adjust_b_command;
+				break;
+			}
+		case ADJUST_B_RESTORE_MIXER_5:
+			xconnect_write_coefs(plci, plci->adjust_b_command);
+			plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_6;
+			Rc = OK;
+		case ADJUST_B_RESTORE_MIXER_6:
+			if (!xconnect_write_coefs_process(Id, plci, Rc))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			if (plci->internal_command)
+				break;
+			plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_7;
+		case ADJUST_B_RESTORE_MIXER_7:
+			break;
+		}
+	}
+	return (Info);
+}
+
+
+static void mixer_command(dword Id, PLCI *plci, byte Rc)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word i, internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_command %02x %04x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
+			plci->li_cmd));
+
+	a = plci->adapter;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (plci->li_cmd)
+	{
+	case LI_REQ_CONNECT:
+	case LI_REQ_DISCONNECT:
+	case LI_REQ_SILENT_UPDATE:
+		switch (internal_command)
+		{
+		default:
+			if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
+			{
+				adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
+									  B1_FACILITY_MIXER), MIXER_COMMAND_1);
+			}
+		case MIXER_COMMAND_1:
+			if (plci->li_channel_bits & LI_CHANNEL_INVOLVED)
+			{
+				if (adjust_b_process(Id, plci, Rc) != GOOD)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Load mixer failed",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					break;
+				}
+				if (plci->internal_command)
+					return;
+			}
+			plci->li_plci_b_req_pos = plci->li_plci_b_write_pos;
+			if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
+			    || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER)
+				&& (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities &
+										      ~B1_FACILITY_MIXER)) == plci->B1_resource)))
+			{
+				xconnect_write_coefs(plci, MIXER_COMMAND_2);
+			}
+			else
+			{
+				do
+				{
+					mixer_indication_coefs_set(Id, plci);
+				} while (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos);
+			}
+		case MIXER_COMMAND_2:
+			if ((plci->li_channel_bits & LI_CHANNEL_INVOLVED)
+			    || ((get_b1_facilities(plci, plci->B1_resource) & B1_FACILITY_MIXER)
+				&& (add_b1_facilities(plci, plci->B1_resource, (word)(plci->B1_facilities &
+										      ~B1_FACILITY_MIXER)) == plci->B1_resource)))
+			{
+				if (!xconnect_write_coefs_process(Id, plci, Rc))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Write mixer coefs failed",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					if (plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
+					{
+						do
+						{
+							plci->li_plci_b_write_pos = (plci->li_plci_b_write_pos == 0) ?
+								LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1;
+							i = (plci->li_plci_b_write_pos == 0) ?
+								LI_PLCI_B_QUEUE_ENTRIES - 1 : plci->li_plci_b_write_pos - 1;
+						} while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
+							 && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
+					}
+					break;
+				}
+				if (plci->internal_command)
+					return;
+			}
+			if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
+			{
+				adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
+									  ~B1_FACILITY_MIXER), MIXER_COMMAND_3);
+			}
+		case MIXER_COMMAND_3:
+			if (!(plci->li_channel_bits & LI_CHANNEL_INVOLVED))
+			{
+				if (adjust_b_process(Id, plci, Rc) != GOOD)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Unload mixer failed",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					break;
+				}
+				if (plci->internal_command)
+					return;
+			}
+			break;
+		}
+		break;
+	}
+	if ((plci->li_bchannel_id == 0)
+	    || (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci != plci))
+	{
+		dbug(1, dprintf("[%06x] %s,%d: Channel id wiped out %d",
+				UnMapId(Id), (char *)(FILE_), __LINE__, (int)(plci->li_bchannel_id)));
+	}
+	else
+	{
+		i = a->li_base + (plci->li_bchannel_id - 1);
+		li_config_table[i].curchnl = plci->li_channel_bits;
+		if (!a->li_pri && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
+		{
+			i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
+			li_config_table[i].curchnl = plci->li_channel_bits;
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
+			{
+				i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
+				li_config_table[i].curchnl = plci->li_channel_bits;
+			}
+		}
+	}
+}
+
+
+static void li_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
+			      dword plci_b_id, byte connect, dword li_flags)
+{
+	word i, ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
+	PLCI *plci_b;
+	DIVA_CAPI_ADAPTER *a_b;
+
+	a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]);
+	plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
+	ch_a = a->li_base + (plci->li_bchannel_id - 1);
+	if (!a->li_pri && (plci->tel == ADV_VOICE)
+	    && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
+	{
+		ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
+		ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
+			a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
+	}
+	else
+	{
+		ch_a_v = ch_a;
+		ch_a_s = ch_a;
+	}
+	ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
+	if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
+	    && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
+	{
+		ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
+		ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
+			a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
+	}
+	else
+	{
+		ch_b_v = ch_b;
+		ch_b_s = ch_b;
+	}
+	if (connect)
+	{
+		li_config_table[ch_a].flag_table[ch_a_v] &= ~LI_FLAG_MONITOR;
+		li_config_table[ch_a].flag_table[ch_a_s] &= ~LI_FLAG_MONITOR;
+		li_config_table[ch_a_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
+		li_config_table[ch_a_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
+	}
+	li_config_table[ch_a].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
+	li_config_table[ch_a].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
+	li_config_table[ch_b_v].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
+	li_config_table[ch_b_s].flag_table[ch_a] &= ~(LI_FLAG_ANNOUNCEMENT | LI_FLAG_MIX);
+	if (ch_a_v == ch_b_v)
+	{
+		li_config_table[ch_a_v].flag_table[ch_b_v] &= ~LI_FLAG_CONFERENCE;
+		li_config_table[ch_a_s].flag_table[ch_b_s] &= ~LI_FLAG_CONFERENCE;
+	}
+	else
+	{
+		if (li_config_table[ch_a_v].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
+		{
+			for (i = 0; i < li_total_channels; i++)
+			{
+				if (i != ch_a_v)
+					li_config_table[ch_a_v].flag_table[i] &= ~LI_FLAG_CONFERENCE;
+			}
+		}
+		if (li_config_table[ch_a_s].flag_table[ch_b_v] & LI_FLAG_CONFERENCE)
+		{
+			for (i = 0; i < li_total_channels; i++)
+			{
+				if (i != ch_a_s)
+					li_config_table[ch_a_s].flag_table[i] &= ~LI_FLAG_CONFERENCE;
+			}
+		}
+		if (li_config_table[ch_b_v].flag_table[ch_a_v] & LI_FLAG_CONFERENCE)
+		{
+			for (i = 0; i < li_total_channels; i++)
+			{
+				if (i != ch_a_v)
+					li_config_table[i].flag_table[ch_a_v] &= ~LI_FLAG_CONFERENCE;
+			}
+		}
+		if (li_config_table[ch_b_v].flag_table[ch_a_s] & LI_FLAG_CONFERENCE)
+		{
+			for (i = 0; i < li_total_channels; i++)
+			{
+				if (i != ch_a_s)
+					li_config_table[i].flag_table[ch_a_s] &= ~LI_FLAG_CONFERENCE;
+			}
+		}
+	}
+	if (li_flags & LI_FLAG_CONFERENCE_A_B)
+	{
+		li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
+	}
+	if (li_flags & LI_FLAG_CONFERENCE_B_A)
+	{
+		li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
+	}
+	if (li_flags & LI_FLAG_MONITOR_A)
+	{
+		li_config_table[ch_a].flag_table[ch_a_v] |= LI_FLAG_MONITOR;
+		li_config_table[ch_a].flag_table[ch_a_s] |= LI_FLAG_MONITOR;
+	}
+	if (li_flags & LI_FLAG_MONITOR_B)
+	{
+		li_config_table[ch_a].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
+		li_config_table[ch_a].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
+	}
+	if (li_flags & LI_FLAG_ANNOUNCEMENT_A)
+	{
+		li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
+		li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
+	}
+	if (li_flags & LI_FLAG_ANNOUNCEMENT_B)
+	{
+		li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
+		li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_ANNOUNCEMENT;
+	}
+	if (li_flags & LI_FLAG_MIX_A)
+	{
+		li_config_table[ch_a_v].flag_table[ch_a] |= LI_FLAG_MIX;
+		li_config_table[ch_a_s].flag_table[ch_a] |= LI_FLAG_MIX;
+	}
+	if (li_flags & LI_FLAG_MIX_B)
+	{
+		li_config_table[ch_b_v].flag_table[ch_a] |= LI_FLAG_MIX;
+		li_config_table[ch_b_s].flag_table[ch_a] |= LI_FLAG_MIX;
+	}
+	if (ch_a_v != ch_a_s)
+	{
+		li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
+	}
+	if (ch_b_v != ch_b_s)
+	{
+		li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
+	}
+}
+
+
+static void li2_update_connect(dword Id, DIVA_CAPI_ADAPTER *a, PLCI *plci,
+			       dword plci_b_id, byte connect, dword li_flags)
+{
+	word ch_a, ch_a_v, ch_a_s, ch_b, ch_b_v, ch_b_s;
+	PLCI *plci_b;
+	DIVA_CAPI_ADAPTER *a_b;
+
+	a_b = &(adapter[MapController((byte)(plci_b_id & 0x7f)) - 1]);
+	plci_b = &(a_b->plci[((plci_b_id >> 8) & 0xff) - 1]);
+	ch_a = a->li_base + (plci->li_bchannel_id - 1);
+	if (!a->li_pri && (plci->tel == ADV_VOICE)
+	    && (plci == a->AdvSignalPLCI) && (Id & EXT_CONTROLLER))
+	{
+		ch_a_v = ch_a + MIXER_IC_CHANNEL_BASE;
+		ch_a_s = (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
+			a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id) : ch_a_v;
+	}
+	else
+	{
+		ch_a_v = ch_a;
+		ch_a_s = ch_a;
+	}
+	ch_b = a_b->li_base + (plci_b->li_bchannel_id - 1);
+	if (!a_b->li_pri && (plci_b->tel == ADV_VOICE)
+	    && (plci_b == a_b->AdvSignalPLCI) && (plci_b_id & EXT_CONTROLLER))
+	{
+		ch_b_v = ch_b + MIXER_IC_CHANNEL_BASE;
+		ch_b_s = (a_b->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC) ?
+			a_b->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci_b->li_bchannel_id) : ch_b_v;
+	}
+	else
+	{
+		ch_b_v = ch_b;
+		ch_b_s = ch_b;
+	}
+	if (connect)
+	{
+		li_config_table[ch_b].flag_table[ch_b_v] &= ~LI_FLAG_MONITOR;
+		li_config_table[ch_b].flag_table[ch_b_s] &= ~LI_FLAG_MONITOR;
+		li_config_table[ch_b_v].flag_table[ch_b] &= ~LI_FLAG_MIX;
+		li_config_table[ch_b_s].flag_table[ch_b] &= ~LI_FLAG_MIX;
+		li_config_table[ch_b].flag_table[ch_b] &= ~LI_FLAG_PCCONNECT;
+		li_config_table[ch_b].chflags &= ~(LI_CHFLAG_MONITOR | LI_CHFLAG_MIX | LI_CHFLAG_LOOP);
+	}
+	li_config_table[ch_b_v].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_b_s].flag_table[ch_a_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_b_v].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_b_s].flag_table[ch_a_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_a_v].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_a_v].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_a_s].flag_table[ch_b_v] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	li_config_table[ch_a_s].flag_table[ch_b_s] &= ~(LI_FLAG_INTERCONNECT | LI_FLAG_CONFERENCE);
+	if (li_flags & LI2_FLAG_INTERCONNECT_A_B)
+	{
+		li_config_table[ch_b_v].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_b_s].flag_table[ch_a_v] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_b_v].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_INTERCONNECT;
+	}
+	if (li_flags & LI2_FLAG_INTERCONNECT_B_A)
+	{
+		li_config_table[ch_a_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_a_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_a_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
+	}
+	if (li_flags & LI2_FLAG_MONITOR_B)
+	{
+		li_config_table[ch_b].flag_table[ch_b_v] |= LI_FLAG_MONITOR;
+		li_config_table[ch_b].flag_table[ch_b_s] |= LI_FLAG_MONITOR;
+	}
+	if (li_flags & LI2_FLAG_MIX_B)
+	{
+		li_config_table[ch_b_v].flag_table[ch_b] |= LI_FLAG_MIX;
+		li_config_table[ch_b_s].flag_table[ch_b] |= LI_FLAG_MIX;
+	}
+	if (li_flags & LI2_FLAG_MONITOR_X)
+		li_config_table[ch_b].chflags |= LI_CHFLAG_MONITOR;
+	if (li_flags & LI2_FLAG_MIX_X)
+		li_config_table[ch_b].chflags |= LI_CHFLAG_MIX;
+	if (li_flags & LI2_FLAG_LOOP_B)
+	{
+		li_config_table[ch_b_v].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
+		li_config_table[ch_b_s].flag_table[ch_b_s] |= LI_FLAG_INTERCONNECT;
+	}
+	if (li_flags & LI2_FLAG_LOOP_PC)
+		li_config_table[ch_b].flag_table[ch_b] |= LI_FLAG_PCCONNECT;
+	if (li_flags & LI2_FLAG_LOOP_X)
+		li_config_table[ch_b].chflags |= LI_CHFLAG_LOOP;
+	if (li_flags & LI2_FLAG_PCCONNECT_A_B)
+		li_config_table[ch_b_s].flag_table[ch_a_s] |= LI_FLAG_PCCONNECT;
+	if (li_flags & LI2_FLAG_PCCONNECT_B_A)
+		li_config_table[ch_a_s].flag_table[ch_b_s] |= LI_FLAG_PCCONNECT;
+	if (ch_a_v != ch_a_s)
+	{
+		li_config_table[ch_a_v].flag_table[ch_a_s] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_a_s].flag_table[ch_a_v] |= LI_FLAG_CONFERENCE;
+	}
+	if (ch_b_v != ch_b_s)
+	{
+		li_config_table[ch_b_v].flag_table[ch_b_s] |= LI_FLAG_CONFERENCE;
+		li_config_table[ch_b_s].flag_table[ch_b_v] |= LI_FLAG_CONFERENCE;
+	}
+}
+
+
+static word li_check_main_plci(dword Id, PLCI *plci)
+{
+	if (plci == NULL)
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		return (_WRONG_IDENTIFIER);
+	}
+	if (!plci->State
+	    || !plci->NL.Id || plci->nl_remove_id
+	    || (plci->li_bchannel_id == 0))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		return (_WRONG_STATE);
+	}
+	li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = plci;
+	return (GOOD);
+}
+
+
+static PLCI *li_check_plci_b(dword Id, PLCI *plci,
+			     dword plci_b_id, word plci_b_write_pos, byte *p_result)
+{
+	byte ctlr_b;
+	PLCI *plci_b;
+
+	if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
+	     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
+		return (NULL);
+	}
+	ctlr_b = 0;
+	if ((plci_b_id & 0x7f) != 0)
+	{
+		ctlr_b = MapController((byte)(plci_b_id & 0x7f));
+		if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
+			ctlr_b = 0;
+	}
+	if ((ctlr_b == 0)
+	    || (((plci_b_id >> 8) & 0xff) == 0)
+	    || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
+		PUT_WORD(p_result, _WRONG_IDENTIFIER);
+		return (NULL);
+	}
+	plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
+	if (!plci_b->State
+	    || !plci_b->NL.Id || plci_b->nl_remove_id
+	    || (plci_b->li_bchannel_id == 0))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
+		PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
+		return (NULL);
+	}
+	li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci = plci_b;
+	if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
+	    ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER))
+	    && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+		|| !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
+		PUT_WORD(p_result, _WRONG_IDENTIFIER);
+		return (NULL);
+	}
+	if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource,
+							  (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource));
+		PUT_WORD(p_result, _REQUEST_NOT_ALLOWED_IN_THIS_STATE);
+		return (NULL);
+	}
+	return (plci_b);
+}
+
+
+static PLCI *li2_check_plci_b(dword Id, PLCI *plci,
+			      dword plci_b_id, word plci_b_write_pos, byte *p_result)
+{
+	byte ctlr_b;
+	PLCI *plci_b;
+
+	if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
+	     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		PUT_WORD(p_result, _WRONG_STATE);
+		return (NULL);
+	}
+	ctlr_b = 0;
+	if ((plci_b_id & 0x7f) != 0)
+	{
+		ctlr_b = MapController((byte)(plci_b_id & 0x7f));
+		if ((ctlr_b > max_adapter) || ((ctlr_b != 0) && (adapter[ctlr_b - 1].request == NULL)))
+			ctlr_b = 0;
+	}
+	if ((ctlr_b == 0)
+	    || (((plci_b_id >> 8) & 0xff) == 0)
+	    || (((plci_b_id >> 8) & 0xff) > adapter[ctlr_b - 1].max_plci))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI invalid second PLCI %08lx",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
+		PUT_WORD(p_result, _WRONG_IDENTIFIER);
+		return (NULL);
+	}
+	plci_b = &(adapter[ctlr_b - 1].plci[((plci_b_id >> 8) & 0xff) - 1]);
+	if (!plci_b->State
+	    || !plci_b->NL.Id || plci_b->nl_remove_id
+	    || (plci_b->li_bchannel_id == 0)
+	    || (li_config_table[plci_b->adapter->li_base + (plci_b->li_bchannel_id - 1)].plci != plci_b))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI peer in wrong state %08lx",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
+		PUT_WORD(p_result, _WRONG_STATE);
+		return (NULL);
+	}
+	if (((byte)(plci_b_id & ~EXT_CONTROLLER)) !=
+	    ((byte)(UnMapController(plci->adapter->Id) & ~EXT_CONTROLLER))
+	    && (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+		|| !(plci_b->adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI not on same ctrl %08lx",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b_id));
+		PUT_WORD(p_result, _WRONG_IDENTIFIER);
+		return (NULL);
+	}
+	if (!(get_b1_facilities(plci_b, add_b1_facilities(plci_b, plci_b->B1_resource,
+							  (word)(plci_b->B1_facilities | B1_FACILITY_MIXER))) & B1_FACILITY_MIXER))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Interconnect peer cannot mix %d",
+				UnMapId(Id), (char *)(FILE_), __LINE__, plci_b->B1_resource));
+		PUT_WORD(p_result, _WRONG_STATE);
+		return (NULL);
+	}
+	return (plci_b);
+}
+
+
+static byte mixer_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL   *appl, API_PARSE *msg)
+{
+	word Info;
+	word i;
+	dword d, li_flags, plci_b_id;
+	PLCI *plci_b;
+	API_PARSE li_parms[3];
+	API_PARSE li_req_parms[3];
+	API_PARSE li_participant_struct[2];
+	API_PARSE li_participant_parms[3];
+	word participant_parms_pos;
+	byte result_buffer[32];
+	byte *result;
+	word result_pos;
+	word plci_b_write_pos;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_request",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	Info = GOOD;
+	result = result_buffer;
+	result_buffer[0] = 0;
+	if (!(a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		Info = _FACILITY_NOT_SUPPORTED;
+	}
+	else if (api_parse(&msg[1].info[1], msg[1].length, "ws", li_parms))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		Info = _WRONG_MESSAGE_FORMAT;
+	}
+	else
+	{
+		result_buffer[0] = 3;
+		PUT_WORD(&result_buffer[1], GET_WORD(li_parms[0].info));
+		result_buffer[3] = 0;
+		switch (GET_WORD(li_parms[0].info))
+		{
+		case LI_GET_SUPPORTED_SERVICES:
+			if (appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
+			{
+				result_buffer[0] = 17;
+				result_buffer[3] = 14;
+				PUT_WORD(&result_buffer[4], GOOD);
+				d = 0;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_CH)
+					d |= LI_CONFERENCING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
+					d |= LI_MONITORING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
+					d |= LI_ANNOUNCEMENTS_SUPPORTED | LI_MIXING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+					d |= LI_CROSS_CONTROLLER_SUPPORTED;
+				PUT_DWORD(&result_buffer[6], d);
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+				{
+					d = 0;
+					for (i = 0; i < li_total_channels; i++)
+					{
+						if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+						    && (li_config_table[i].adapter->li_pri
+							|| (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
+						{
+							d++;
+						}
+					}
+				}
+				else
+				{
+					d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
+				}
+				PUT_DWORD(&result_buffer[10], d / 2);
+				PUT_DWORD(&result_buffer[14], d);
+			}
+			else
+			{
+				result_buffer[0] = 25;
+				result_buffer[3] = 22;
+				PUT_WORD(&result_buffer[4], GOOD);
+				d = LI2_ASYMMETRIC_SUPPORTED | LI2_B_LOOPING_SUPPORTED | LI2_X_LOOPING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_CH_PC)
+					d |= LI2_MONITORING_SUPPORTED | LI2_REMOTE_MONITORING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_CH)
+					d |= LI2_MIXING_SUPPORTED | LI2_REMOTE_MIXING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_MIXER_PC_PC)
+					d |= LI2_PC_LOOPING_SUPPORTED;
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+					d |= LI2_CROSS_CONTROLLER_SUPPORTED;
+				PUT_DWORD(&result_buffer[6], d);
+				d = a->li_pri ? a->li_channels : MIXER_BCHANNELS_BRI;
+				PUT_DWORD(&result_buffer[10], d / 2);
+				PUT_DWORD(&result_buffer[14], d - 1);
+				if (a->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+				{
+					d = 0;
+					for (i = 0; i < li_total_channels; i++)
+					{
+						if ((li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
+						    && (li_config_table[i].adapter->li_pri
+							|| (i < li_config_table[i].adapter->li_base + MIXER_BCHANNELS_BRI)))
+						{
+							d++;
+						}
+					}
+				}
+				PUT_DWORD(&result_buffer[18], d / 2);
+				PUT_DWORD(&result_buffer[22], d - 1);
+			}
+			break;
+
+		case LI_REQ_CONNECT:
+			if (li_parms[1].length == 8)
+			{
+				appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
+				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "dd", li_req_parms))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff;
+				li_flags = GET_DWORD(li_req_parms[1].info);
+				Info = li_check_main_plci(Id, plci);
+				result_buffer[0] = 9;
+				result_buffer[3] = 6;
+				PUT_DWORD(&result_buffer[4], plci_b_id);
+				PUT_WORD(&result_buffer[8], GOOD);
+				if (Info != GOOD)
+					break;
+				result = plci->saved_msg.info;
+				for (i = 0; i <= result_buffer[0]; i++)
+					result[i] = result_buffer[i];
+				plci_b_write_pos = plci->li_plci_b_write_pos;
+				plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
+				if (plci_b == NULL)
+					break;
+				li_update_connect(Id, a, plci, plci_b_id, true, li_flags);
+				plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG;
+				plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+				plci->li_plci_b_write_pos = plci_b_write_pos;
+			}
+			else
+			{
+				appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
+				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "ds", li_req_parms))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				li_flags = GET_DWORD(li_req_parms[0].info) & ~(LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A);
+				Info = li_check_main_plci(Id, plci);
+				result_buffer[0] = 7;
+				result_buffer[3] = 4;
+				PUT_WORD(&result_buffer[4], Info);
+				result_buffer[6] = 0;
+				if (Info != GOOD)
+					break;
+				result = plci->saved_msg.info;
+				for (i = 0; i <= result_buffer[0]; i++)
+					result[i] = result_buffer[i];
+				plci_b_write_pos = plci->li_plci_b_write_pos;
+				participant_parms_pos = 0;
+				result_pos = 7;
+				li2_update_connect(Id, a, plci, UnMapId(Id), true, li_flags);
+				while (participant_parms_pos < li_req_parms[1].length)
+				{
+					result[result_pos] = 6;
+					result_pos += 7;
+					PUT_DWORD(&result[result_pos - 6], 0);
+					PUT_WORD(&result[result_pos - 2], GOOD);
+					if (api_parse(&li_req_parms[1].info[1 + participant_parms_pos],
+						      (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+								UnMapId(Id), (char *)(FILE_), __LINE__));
+						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
+						break;
+					}
+					if (api_parse(&li_participant_struct[0].info[1],
+						      li_participant_struct[0].length, "dd", li_participant_parms))
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+								UnMapId(Id), (char *)(FILE_), __LINE__));
+						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
+						break;
+					}
+					plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff;
+					li_flags = GET_DWORD(li_participant_parms[1].info);
+					PUT_DWORD(&result[result_pos - 6], plci_b_id);
+					if (sizeof(result) - result_pos < 7)
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
+								UnMapId(Id), (char *)(FILE_), __LINE__));
+						PUT_WORD(&result[result_pos - 2], _WRONG_STATE);
+						break;
+					}
+					plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
+					if (plci_b != NULL)
+					{
+						li2_update_connect(Id, a, plci, plci_b_id, true, li_flags);
+						plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id |
+							((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A |
+								      LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG);
+						plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+					}
+					participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
+								       (&li_req_parms[1].info[1]));
+				}
+				result[0] = (byte)(result_pos - 1);
+				result[3] = (byte)(result_pos - 4);
+				result[6] = (byte)(result_pos - 7);
+				i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
+				if ((plci_b_write_pos == plci->li_plci_b_read_pos)
+				    || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
+				{
+					plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
+					plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+				}
+				else
+					plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
+				plci->li_plci_b_write_pos = plci_b_write_pos;
+			}
+			mixer_calculate_coefs(a);
+			plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
+			mixer_notify_update(plci, true);
+			sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
+			      "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
+			plci->command = 0;
+			plci->li_cmd = GET_WORD(li_parms[0].info);
+			start_internal_command(Id, plci, mixer_command);
+			return (false);
+
+		case LI_REQ_DISCONNECT:
+			if (li_parms[1].length == 4)
+			{
+				appl->appl_flags |= APPL_FLAG_OLD_LI_SPEC;
+				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "d", li_req_parms))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				plci_b_id = GET_DWORD(li_req_parms[0].info) & 0xffff;
+				Info = li_check_main_plci(Id, plci);
+				result_buffer[0] = 9;
+				result_buffer[3] = 6;
+				PUT_DWORD(&result_buffer[4], GET_DWORD(li_req_parms[0].info));
+				PUT_WORD(&result_buffer[8], GOOD);
+				if (Info != GOOD)
+					break;
+				result = plci->saved_msg.info;
+				for (i = 0; i <= result_buffer[0]; i++)
+					result[i] = result_buffer[i];
+				plci_b_write_pos = plci->li_plci_b_write_pos;
+				plci_b = li_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
+				if (plci_b == NULL)
+					break;
+				li_update_connect(Id, a, plci, plci_b_id, false, 0);
+				plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG;
+				plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+				plci->li_plci_b_write_pos = plci_b_write_pos;
+			}
+			else
+			{
+				appl->appl_flags &= ~APPL_FLAG_OLD_LI_SPEC;
+				if (api_parse(&li_parms[1].info[1], li_parms[1].length, "s", li_req_parms))
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_MESSAGE_FORMAT;
+					break;
+				}
+				Info = li_check_main_plci(Id, plci);
+				result_buffer[0] = 7;
+				result_buffer[3] = 4;
+				PUT_WORD(&result_buffer[4], Info);
+				result_buffer[6] = 0;
+				if (Info != GOOD)
+					break;
+				result = plci->saved_msg.info;
+				for (i = 0; i <= result_buffer[0]; i++)
+					result[i] = result_buffer[i];
+				plci_b_write_pos = plci->li_plci_b_write_pos;
+				participant_parms_pos = 0;
+				result_pos = 7;
+				while (participant_parms_pos < li_req_parms[0].length)
+				{
+					result[result_pos] = 6;
+					result_pos += 7;
+					PUT_DWORD(&result[result_pos - 6], 0);
+					PUT_WORD(&result[result_pos - 2], GOOD);
+					if (api_parse(&li_req_parms[0].info[1 + participant_parms_pos],
+						      (word)(li_parms[1].length - participant_parms_pos), "s", li_participant_struct))
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+								UnMapId(Id), (char *)(FILE_), __LINE__));
+						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
+						break;
+					}
+					if (api_parse(&li_participant_struct[0].info[1],
+						      li_participant_struct[0].length, "d", li_participant_parms))
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+								UnMapId(Id), (char *)(FILE_), __LINE__));
+						PUT_WORD(&result[result_pos - 2], _WRONG_MESSAGE_FORMAT);
+						break;
+					}
+					plci_b_id = GET_DWORD(li_participant_parms[0].info) & 0xffff;
+					PUT_DWORD(&result[result_pos - 6], plci_b_id);
+					if (sizeof(result) - result_pos < 7)
+					{
+						dbug(1, dprintf("[%06lx] %s,%d: LI result overrun",
+								UnMapId(Id), (char *)(FILE_), __LINE__));
+						PUT_WORD(&result[result_pos - 2], _WRONG_STATE);
+						break;
+					}
+					plci_b = li2_check_plci_b(Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
+					if (plci_b != NULL)
+					{
+						li2_update_connect(Id, a, plci, plci_b_id, false, 0);
+						plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
+						plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+					}
+					participant_parms_pos = (word)((&li_participant_struct[0].info[1 + li_participant_struct[0].length]) -
+								       (&li_req_parms[0].info[1]));
+				}
+				result[0] = (byte)(result_pos - 1);
+				result[3] = (byte)(result_pos - 4);
+				result[6] = (byte)(result_pos - 7);
+				i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
+				if ((plci_b_write_pos == plci->li_plci_b_read_pos)
+				    || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
+				{
+					plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
+					plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+				}
+				else
+					plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
+				plci->li_plci_b_write_pos = plci_b_write_pos;
+			}
+			mixer_calculate_coefs(a);
+			plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
+			mixer_notify_update(plci, true);
+			sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
+			      "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
+			plci->command = 0;
+			plci->li_cmd = GET_WORD(li_parms[0].info);
+			start_internal_command(Id, plci, mixer_command);
+			return (false);
+
+		case LI_REQ_SILENT_UPDATE:
+			if (!plci || !plci->State
+			    || !plci->NL.Id || plci->nl_remove_id
+			    || (plci->li_bchannel_id == 0)
+			    || (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci != plci))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				return (false);
+			}
+			plci_b_write_pos = plci->li_plci_b_write_pos;
+			if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
+			     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 2)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				return (false);
+			}
+			i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES - 1 : plci_b_write_pos - 1;
+			if ((plci_b_write_pos == plci->li_plci_b_read_pos)
+			    || (plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG))
+			{
+				plci->li_plci_b_queue[plci_b_write_pos] = LI_PLCI_B_SKIP_FLAG | LI_PLCI_B_LAST_FLAG;
+				plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+			}
+			else
+				plci->li_plci_b_queue[i] |= LI_PLCI_B_LAST_FLAG;
+			plci->li_plci_b_write_pos = plci_b_write_pos;
+			plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
+			plci->command = 0;
+			plci->li_cmd = GET_WORD(li_parms[0].info);
+			start_internal_command(Id, plci, mixer_command);
+			return (false);
+
+		default:
+			dbug(1, dprintf("[%06lx] %s,%d: LI unknown request %04x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, GET_WORD(li_parms[0].info)));
+			Info = _FACILITY_NOT_SUPPORTED;
+		}
+	}
+	sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
+	      "wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
+	return (false);
+}
+
+
+static void mixer_indication_coefs_set(dword Id, PLCI *plci)
+{
+	dword d;
+	byte result[12];
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_coefs_set",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
+	{
+		do
+		{
+			d = plci->li_plci_b_queue[plci->li_plci_b_read_pos];
+			if (!(d & LI_PLCI_B_SKIP_FLAG))
+			{
+				if (plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
+				{
+					if (d & LI_PLCI_B_DISC_FLAG)
+					{
+						result[0] = 5;
+						PUT_WORD(&result[1], LI_IND_DISCONNECT);
+						result[3] = 2;
+						PUT_WORD(&result[4], _LI_USER_INITIATED);
+					}
+					else
+					{
+						result[0] = 7;
+						PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE);
+						result[3] = 4;
+						PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
+					}
+				}
+				else
+				{
+					if (d & LI_PLCI_B_DISC_FLAG)
+					{
+						result[0] = 9;
+						PUT_WORD(&result[1], LI_IND_DISCONNECT);
+						result[3] = 6;
+						PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
+						PUT_WORD(&result[8], _LI_USER_INITIATED);
+					}
+					else
+					{
+						result[0] = 7;
+						PUT_WORD(&result[1], LI_IND_CONNECT_ACTIVE);
+						result[3] = 4;
+						PUT_DWORD(&result[4], d & ~LI_PLCI_B_FLAG_MASK);
+					}
+				}
+				sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0,
+				      "ws", SELECTOR_LINE_INTERCONNECT, result);
+			}
+			plci->li_plci_b_read_pos = (plci->li_plci_b_read_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ?
+				0 : plci->li_plci_b_read_pos + 1;
+		} while (!(d & LI_PLCI_B_LAST_FLAG) && (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos));
+	}
+}
+
+
+static void mixer_indication_xconnect_from(dword Id, PLCI *plci, byte *msg, word length)
+{
+	word i, j, ch;
+	struct xconnect_transfer_address_s s,   *p;
+	DIVA_CAPI_ADAPTER *a;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_from %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, (int)length));
+
+	a = plci->adapter;
+	i = 1;
+	for (i = 1; i < length; i += 16)
+	{
+		s.card_address.low = msg[i] | (msg[i + 1] << 8) | (((dword)(msg[i + 2])) << 16) | (((dword)(msg[i + 3])) << 24);
+		s.card_address.high = msg[i + 4] | (msg[i + 5] << 8) | (((dword)(msg[i + 6])) << 16) | (((dword)(msg[i + 7])) << 24);
+		s.offset = msg[i + 8] | (msg[i + 9] << 8) | (((dword)(msg[i + 10])) << 16) | (((dword)(msg[i + 11])) << 24);
+		ch = msg[i + 12] | (msg[i + 13] << 8);
+		j = ch & XCONNECT_CHANNEL_NUMBER_MASK;
+		if (!a->li_pri && (plci->li_bchannel_id == 2))
+			j = 1 - j;
+		j += a->li_base;
+		if (ch & XCONNECT_CHANNEL_PORT_PC)
+			p = &(li_config_table[j].send_pc);
+		else
+			p = &(li_config_table[j].send_b);
+		p->card_address.low = s.card_address.low;
+		p->card_address.high = s.card_address.high;
+		p->offset = s.offset;
+		li_config_table[j].channel |= LI_CHANNEL_ADDRESSES_SET;
+	}
+	if (plci->internal_command_queue[0]
+	    && ((plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_2)
+		|| (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_3)
+		|| (plci->adjust_b_state == ADJUST_B_RESTORE_MIXER_4)))
+	{
+		(*(plci->internal_command_queue[0]))(Id, plci, 0);
+		if (!plci->internal_command)
+			next_internal_command(Id, plci);
+	}
+	mixer_notify_update(plci, true);
+}
+
+
+static void mixer_indication_xconnect_to(dword Id, PLCI *plci, byte *msg, word length)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_indication_xconnect_to %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, (int) length));
+
+}
+
+
+static byte mixer_notify_source_removed(PLCI *plci, dword plci_b_id)
+{
+	word plci_b_write_pos;
+
+	plci_b_write_pos = plci->li_plci_b_write_pos;
+	if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
+	     LI_PLCI_B_QUEUE_ENTRIES + plci->li_plci_b_read_pos) - plci_b_write_pos - 1 < 1)
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: LI request overrun",
+				(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+				(char *)(FILE_), __LINE__));
+		return (false);
+	}
+	plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
+	plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES - 1) ? 0 : plci_b_write_pos + 1;
+	plci->li_plci_b_write_pos = plci_b_write_pos;
+	return (true);
+}
+
+
+static void mixer_remove(PLCI *plci)
+{
+	DIVA_CAPI_ADAPTER *a;
+	PLCI *notify_plci;
+	dword plci_b_id;
+	word i, j;
+
+	dbug(1, dprintf("[%06lx] %s,%d: mixer_remove",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
+
+	a = plci->adapter;
+	plci_b_id = (plci->Id << 8) | UnMapController(plci->adapter->Id);
+	if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
+	{
+		if ((plci->li_bchannel_id != 0)
+		    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+		{
+			i = a->li_base + (plci->li_bchannel_id - 1);
+			if ((li_config_table[i].curchnl | li_config_table[i].channel) & LI_CHANNEL_INVOLVED)
+			{
+				for (j = 0; j < li_total_channels; j++)
+				{
+					if ((li_config_table[i].flag_table[j] & LI_FLAG_INTERCONNECT)
+					    || (li_config_table[j].flag_table[i] & LI_FLAG_INTERCONNECT))
+					{
+						notify_plci = li_config_table[j].plci;
+						if ((notify_plci != NULL)
+						    && (notify_plci != plci)
+						    && (notify_plci->appl != NULL)
+						    && !(notify_plci->appl->appl_flags & APPL_FLAG_OLD_LI_SPEC)
+						    && (notify_plci->State)
+						    && notify_plci->NL.Id && !notify_plci->nl_remove_id)
+						{
+							mixer_notify_source_removed(notify_plci, plci_b_id);
+						}
+					}
+				}
+				mixer_clear_config(plci);
+				mixer_calculate_coefs(a);
+				mixer_notify_update(plci, true);
+			}
+			li_config_table[i].plci = NULL;
+			plci->li_bchannel_id = 0;
+		}
+	}
 }
 
 
-static void adv_voice_clear_config (PLCI   *plci)
-{
-  DIVA_CAPI_ADAPTER   *a;
-
-  word i, j;
+/*------------------------------------------------------------------*/
+/* Echo canceller facilities                                        */
+/*------------------------------------------------------------------*/
 
 
-  dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_clear_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
+static void ec_write_parameters(PLCI *plci)
+{
+	word w;
+	byte parameter_buffer[6];
 
-  a = plci->adapter;
-  if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
-  {
-    a->adv_voice_coef_length = 0;
-
-    if (!a->li_pri && (plci->li_bchannel_id != 0)
-     && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-    {
-      i = a->li_base + (plci->li_bchannel_id - 1);
-      li_config_table[i].curchnl = 0;
-      li_config_table[i].channel = 0;
-      li_config_table[i].chflags = 0;
-      for (j = 0; j < li_total_channels; j++)
-      {
-        li_config_table[i].flag_table[j] = 0;
-        li_config_table[j].flag_table[i] = 0;
-        li_config_table[i].coef_table[j] = 0;
-        li_config_table[j].coef_table[i] = 0;
-      }
-      li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
-      i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
-      li_config_table[i].curchnl = 0;
-      li_config_table[i].channel = 0;
-      li_config_table[i].chflags = 0;
-      for (j = 0; j < li_total_channels; j++)
-      {
-        li_config_table[i].flag_table[j] = 0;
-        li_config_table[j].flag_table[i] = 0;
-        li_config_table[i].coef_table[j] = 0;
-        li_config_table[j].coef_table[i] = 0;
-      }
-      if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
-      {
-        i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
-        li_config_table[i].curchnl = 0;
-        li_config_table[i].channel = 0;
-        li_config_table[i].chflags = 0;
-        for (j = 0; j < li_total_channels; j++)
-        {
-          li_config_table[i].flag_table[j] = 0;
-          li_config_table[j].flag_table[i] = 0;
-          li_config_table[i].coef_table[j] = 0;
-          li_config_table[j].coef_table[i] = 0;
-        }
-      }
-    }
+	dbug(1, dprintf("[%06lx] %s,%d: ec_write_parameters",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-  }
+	parameter_buffer[0] = 5;
+	parameter_buffer[1] = DSP_CTRL_SET_LEC_PARAMETERS;
+	PUT_WORD(&parameter_buffer[2], plci->ec_idi_options);
+	plci->ec_idi_options &= ~LEC_RESET_COEFFICIENTS;
+	w = (plci->ec_tail_length == 0) ? 128 : plci->ec_tail_length;
+	PUT_WORD(&parameter_buffer[4], w);
+	add_p(plci, FTY, parameter_buffer);
+	sig_req(plci, TEL_CTRL, 0);
+	send_req(plci);
 }
 
 
-static void adv_voice_prepare_switch (dword Id, PLCI   *plci)
+static void ec_clear_config(PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_prepare_switch",
-    UnMapId (Id), (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: ec_clear_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
+	plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
+		LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING;
+	plci->ec_tail_length = 0;
 }
 
 
-static word adv_voice_save_config (dword Id, PLCI   *plci, byte Rc)
+static void ec_prepare_switch(dword Id, PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_save_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+	dbug(1, dprintf("[%06lx] %s,%d: ec_prepare_switch",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
 
-  return (GOOD);
 }
 
 
-static word adv_voice_restore_config (dword Id, PLCI   *plci, byte Rc)
-{
-  DIVA_CAPI_ADAPTER   *a;
-  word Info;
+static word ec_save_config(dword Id, PLCI *plci, byte Rc)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: ec_save_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	return (GOOD);
+}
+
+
+static word ec_restore_config(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+
+	dbug(1, dprintf("[%06lx] %s,%d: ec_restore_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	Info = GOOD;
+	if (plci->B1_facilities & B1_FACILITY_EC)
+	{
+		switch (plci->adjust_b_state)
+		{
+		case ADJUST_B_RESTORE_EC_1:
+			plci->internal_command = plci->adjust_b_command;
+			if (plci->sig_req)
+			{
+				plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
+				break;
+			}
+			ec_write_parameters(plci);
+			plci->adjust_b_state = ADJUST_B_RESTORE_EC_2;
+			break;
+		case ADJUST_B_RESTORE_EC_2:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Restore EC failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _WRONG_STATE;
+				break;
+			}
+			break;
+		}
+	}
+	return (Info);
+}
+
+
+static void ec_command(dword Id, PLCI *plci, byte Rc)
+{
+	word internal_command, Info;
+	byte result[8];
+
+	dbug(1, dprintf("[%06lx] %s,%d: ec_command %02x %04x %04x %04x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command,
+			plci->ec_cmd, plci->ec_idi_options, plci->ec_tail_length));
+
+	Info = GOOD;
+	if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
+	{
+		result[0] = 2;
+		PUT_WORD(&result[1], EC_SUCCESS);
+	}
+	else
+	{
+		result[0] = 5;
+		PUT_WORD(&result[1], plci->ec_cmd);
+		result[3] = 2;
+		PUT_WORD(&result[4], GOOD);
+	}
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (plci->ec_cmd)
+	{
+	case EC_ENABLE_OPERATION:
+	case EC_FREEZE_COEFFICIENTS:
+	case EC_RESUME_COEFFICIENT_UPDATE:
+	case EC_RESET_COEFFICIENTS:
+		switch (internal_command)
+		{
+		default:
+			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities |
+								  B1_FACILITY_EC), EC_COMMAND_1);
+		case EC_COMMAND_1:
+			if (adjust_b_process(Id, plci, Rc) != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Load EC failed",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			if (plci->internal_command)
+				return;
+		case EC_COMMAND_2:
+			if (plci->sig_req)
+			{
+				plci->internal_command = EC_COMMAND_2;
+				return;
+			}
+			plci->internal_command = EC_COMMAND_3;
+			ec_write_parameters(plci);
+			return;
+		case EC_COMMAND_3:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Enable EC failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			break;
+		}
+		break;
+
+	case EC_DISABLE_OPERATION:
+		switch (internal_command)
+		{
+		default:
+		case EC_COMMAND_1:
+			if (plci->B1_facilities & B1_FACILITY_EC)
+			{
+				if (plci->sig_req)
+				{
+					plci->internal_command = EC_COMMAND_1;
+					return;
+				}
+				plci->internal_command = EC_COMMAND_2;
+				ec_write_parameters(plci);
+				return;
+			}
+			Rc = OK;
+		case EC_COMMAND_2:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Disable EC failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			adjust_b1_resource(Id, plci, NULL, (word)(plci->B1_facilities &
+								  ~B1_FACILITY_EC), EC_COMMAND_3);
+		case EC_COMMAND_3:
+			if (adjust_b_process(Id, plci, Rc) != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Unload EC failed",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _FACILITY_NOT_SUPPORTED;
+				break;
+			}
+			if (plci->internal_command)
+				return;
+			break;
+		}
+		break;
+	}
+	sendf(plci->appl, _FACILITY_R | CONFIRM, Id & 0xffffL, plci->number,
+	      "wws", Info, (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
+	      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
+}
+
+
+static byte ec_request(dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL   *appl, API_PARSE *msg)
+{
+	word Info;
+	word opt;
+	API_PARSE ec_parms[3];
+	byte result[16];
+
+	dbug(1, dprintf("[%06lx] %s,%d: ec_request",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	Info = GOOD;
+	result[0] = 0;
+	if (!(a->man_profile.private_options & (1L << PRIVATE_ECHO_CANCELLER)))
+	{
+		dbug(1, dprintf("[%06lx] %s,%d: Facility not supported",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+		Info = _FACILITY_NOT_SUPPORTED;
+	}
+	else
+	{
+		if (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
+		{
+			if (api_parse(&msg[1].info[1], msg[1].length, "w", ec_parms))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _WRONG_MESSAGE_FORMAT;
+			}
+			else
+			{
+				if (plci == NULL)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_IDENTIFIER;
+				}
+				else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_STATE;
+				}
+				else
+				{
+					plci->command = 0;
+					plci->ec_cmd = GET_WORD(ec_parms[0].info);
+					plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
+					result[0] = 2;
+					PUT_WORD(&result[1], EC_SUCCESS);
+					if (msg[1].length >= 4)
+					{
+						opt = GET_WORD(&ec_parms[0].info[2]);
+						plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
+									  LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
+						if (!(opt & EC_DISABLE_NON_LINEAR_PROCESSING))
+							plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
+						if (opt & EC_DETECT_DISABLE_TONE)
+							plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
+						if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
+							plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
+						if (msg[1].length >= 6)
+						{
+							plci->ec_tail_length = GET_WORD(&ec_parms[0].info[4]);
+						}
+					}
+					switch (plci->ec_cmd)
+					{
+					case EC_ENABLE_OPERATION:
+						plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					case EC_DISABLE_OPERATION:
+						plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
+							LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
+							LEC_RESET_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					case EC_FREEZE_COEFFICIENTS:
+						plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					case EC_RESUME_COEFFICIENT_UPDATE:
+						plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					case EC_RESET_COEFFICIENTS:
+						plci->ec_idi_options |= LEC_RESET_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					default:
+						dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
+								UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd));
+						PUT_WORD(&result[1], EC_UNSUPPORTED_OPERATION);
+					}
+				}
+			}
+		}
+		else
+		{
+			if (api_parse(&msg[1].info[1], msg[1].length, "ws", ec_parms))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Wrong message format",
+						UnMapId(Id), (char *)(FILE_), __LINE__));
+				Info = _WRONG_MESSAGE_FORMAT;
+			}
+			else
+			{
+				if (GET_WORD(ec_parms[0].info) == EC_GET_SUPPORTED_SERVICES)
+				{
+					result[0] = 11;
+					PUT_WORD(&result[1], EC_GET_SUPPORTED_SERVICES);
+					result[3] = 8;
+					PUT_WORD(&result[4], GOOD);
+					PUT_WORD(&result[6], 0x0007);
+					PUT_WORD(&result[8], LEC_MAX_SUPPORTED_TAIL_LENGTH);
+					PUT_WORD(&result[10], 0);
+				}
+				else if (plci == NULL)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong PLCI",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_IDENTIFIER;
+				}
+				else if (!plci->State || !plci->NL.Id || plci->nl_remove_id)
+				{
+					dbug(1, dprintf("[%06lx] %s,%d: Wrong state",
+							UnMapId(Id), (char *)(FILE_), __LINE__));
+					Info = _WRONG_STATE;
+				}
+				else
+				{
+					plci->command = 0;
+					plci->ec_cmd = GET_WORD(ec_parms[0].info);
+					plci->ec_idi_options &= ~(LEC_MANUAL_DISABLE | LEC_RESET_COEFFICIENTS);
+					result[0] = 5;
+					PUT_WORD(&result[1], plci->ec_cmd);
+					result[3] = 2;
+					PUT_WORD(&result[4], GOOD);
+					plci->ec_idi_options &= ~(LEC_ENABLE_NONLINEAR_PROCESSING |
+								  LEC_ENABLE_2100HZ_DETECTOR | LEC_REQUIRE_2100HZ_REVERSALS);
+					plci->ec_tail_length = 0;
+					if (ec_parms[1].length >= 2)
+					{
+						opt = GET_WORD(&ec_parms[1].info[1]);
+						if (opt & EC_ENABLE_NON_LINEAR_PROCESSING)
+							plci->ec_idi_options |= LEC_ENABLE_NONLINEAR_PROCESSING;
+						if (opt & EC_DETECT_DISABLE_TONE)
+							plci->ec_idi_options |= LEC_ENABLE_2100HZ_DETECTOR;
+						if (!(opt & EC_DO_NOT_REQUIRE_REVERSALS))
+							plci->ec_idi_options |= LEC_REQUIRE_2100HZ_REVERSALS;
+						if (ec_parms[1].length >= 4)
+						{
+							plci->ec_tail_length = GET_WORD(&ec_parms[1].info[3]);
+						}
+					}
+					switch (plci->ec_cmd)
+					{
+					case EC_ENABLE_OPERATION:
+						plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					case EC_DISABLE_OPERATION:
+						plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
+							LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
+							LEC_RESET_COEFFICIENTS;
+						start_internal_command(Id, plci, ec_command);
+						return (false);
+
+					default:
+						dbug(1, dprintf("[%06lx] %s,%d: EC unknown request %04x",
+								UnMapId(Id), (char *)(FILE_), __LINE__, plci->ec_cmd));
+						PUT_WORD(&result[4], _FACILITY_SPECIFIC_FUNCTION_NOT_SUPP);
+					}
+				}
+			}
+		}
+	}
+	sendf(appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
+	      "wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
+	      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
+	return (false);
+}
+
+
+static void ec_indication(dword Id, PLCI *plci, byte *msg, word length)
+{
+	byte result[8];
+
+	dbug(1, dprintf("[%06lx] %s,%d: ec_indication",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+	if (!(plci->ec_idi_options & LEC_MANUAL_DISABLE))
+	{
+		if (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC)
+		{
+			result[0] = 2;
+			PUT_WORD(&result[1], 0);
+			switch (msg[1])
+			{
+			case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
+				PUT_WORD(&result[1], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
+				break;
+			case LEC_DISABLE_TYPE_REVERSED_2100HZ:
+				PUT_WORD(&result[1], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
+				break;
+			case LEC_DISABLE_RELEASED:
+				PUT_WORD(&result[1], EC_BYPASS_RELEASED);
+				break;
+			}
+		}
+		else
+		{
+			result[0] = 5;
+			PUT_WORD(&result[1], EC_BYPASS_INDICATION);
+			result[3] = 2;
+			PUT_WORD(&result[4], 0);
+			switch (msg[1])
+			{
+			case LEC_DISABLE_TYPE_CONTIGNUOUS_2100HZ:
+				PUT_WORD(&result[4], EC_BYPASS_DUE_TO_CONTINUOUS_2100HZ);
+				break;
+			case LEC_DISABLE_TYPE_REVERSED_2100HZ:
+				PUT_WORD(&result[4], EC_BYPASS_DUE_TO_REVERSED_2100HZ);
+				break;
+			case LEC_DISABLE_RELEASED:
+				PUT_WORD(&result[4], EC_BYPASS_RELEASED);
+				break;
+			}
+		}
+		sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", (plci->appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
+		      PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
+	}
+}
+
+
+
+/*------------------------------------------------------------------*/
+/* Advanced voice                                                   */
+/*------------------------------------------------------------------*/
 
-  dbug (1, dprintf ("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+static void adv_voice_write_coefs(PLCI *plci, word write_command)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word i;
+	byte *p;
+
+	word w, n, j, k;
+	byte ch_map[MIXER_CHANNELS_BRI];
+
+	byte coef_buffer[ADV_VOICE_COEF_BUFFER_SIZE + 2];
+
+	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_write_coefs %d",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, write_command));
+
+	a = plci->adapter;
+	p = coef_buffer + 1;
+	*(p++) = DSP_CTRL_OLD_SET_MIXER_COEFFICIENTS;
+	i = 0;
+	while (i + sizeof(word) <= a->adv_voice_coef_length)
+	{
+		PUT_WORD(p, GET_WORD(a->adv_voice_coef_buffer + i));
+		p += 2;
+		i += 2;
+	}
+	while (i < ADV_VOICE_OLD_COEF_COUNT * sizeof(word))
+	{
+		PUT_WORD(p, 0x8000);
+		p += 2;
+		i += 2;
+	}
+
+	if (!a->li_pri && (plci->li_bchannel_id == 0))
+	{
+		if ((li_config_table[a->li_base].plci == NULL) && (li_config_table[a->li_base + 1].plci != NULL))
+		{
+			plci->li_bchannel_id = 1;
+			li_config_table[a->li_base].plci = plci;
+			dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
+					(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+					(char *)(FILE_), __LINE__, plci->li_bchannel_id));
+		}
+		else if ((li_config_table[a->li_base].plci != NULL) && (li_config_table[a->li_base + 1].plci == NULL))
+		{
+			plci->li_bchannel_id = 2;
+			li_config_table[a->li_base + 1].plci = plci;
+			dbug(1, dprintf("[%06lx] %s,%d: adv_voice_set_bchannel_id %d",
+					(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+					(char *)(FILE_), __LINE__, plci->li_bchannel_id));
+		}
+	}
+	if (!a->li_pri && (plci->li_bchannel_id != 0)
+	    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		i = a->li_base + (plci->li_bchannel_id - 1);
+		switch (write_command)
+		{
+		case ADV_VOICE_WRITE_ACTIVATION:
+			j = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
+			k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
+			if (!(plci->B1_facilities & B1_FACILITY_MIXER))
+			{
+				li_config_table[j].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
+				li_config_table[i].flag_table[j] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
+			}
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
+			{
+				li_config_table[k].flag_table[i] |= LI_FLAG_CONFERENCE | LI_FLAG_MIX;
+				li_config_table[i].flag_table[k] |= LI_FLAG_CONFERENCE | LI_FLAG_MONITOR;
+				li_config_table[k].flag_table[j] |= LI_FLAG_CONFERENCE;
+				li_config_table[j].flag_table[k] |= LI_FLAG_CONFERENCE;
+			}
+			mixer_calculate_coefs(a);
+			li_config_table[i].curchnl = li_config_table[i].channel;
+			li_config_table[j].curchnl = li_config_table[j].channel;
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
+				li_config_table[k].curchnl = li_config_table[k].channel;
+			break;
+
+		case ADV_VOICE_WRITE_DEACTIVATION:
+			for (j = 0; j < li_total_channels; j++)
+			{
+				li_config_table[i].flag_table[j] = 0;
+				li_config_table[j].flag_table[i] = 0;
+			}
+			k = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
+			for (j = 0; j < li_total_channels; j++)
+			{
+				li_config_table[k].flag_table[j] = 0;
+				li_config_table[j].flag_table[k] = 0;
+			}
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
+			{
+				k = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
+				for (j = 0; j < li_total_channels; j++)
+				{
+					li_config_table[k].flag_table[j] = 0;
+					li_config_table[j].flag_table[k] = 0;
+				}
+			}
+			mixer_calculate_coefs(a);
+			break;
+		}
+		if (plci->B1_facilities & B1_FACILITY_MIXER)
+		{
+			w = 0;
+			if (ADV_VOICE_NEW_COEF_BASE + sizeof(word) <= a->adv_voice_coef_length)
+				w = GET_WORD(a->adv_voice_coef_buffer + ADV_VOICE_NEW_COEF_BASE);
+			if (li_config_table[i].channel & LI_CHANNEL_TX_DATA)
+				w |= MIXER_FEATURE_ENABLE_TX_DATA;
+			if (li_config_table[i].channel & LI_CHANNEL_RX_DATA)
+				w |= MIXER_FEATURE_ENABLE_RX_DATA;
+			*(p++) = (byte) w;
+			*(p++) = (byte)(w >> 8);
+			for (j = 0; j < sizeof(ch_map); j += 2)
+			{
+				ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1));
+				ch_map[j + 1] = (byte)(j + (2 - plci->li_bchannel_id));
+			}
+			for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
+			{
+				i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
+				j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
+				if (li_config_table[i].channel & li_config_table[j].channel & LI_CHANNEL_INVOLVED)
+				{
+					*(p++) = ((li_config_table[i].coef_table[j] & mixer_write_prog_bri[n].mask) ? 0x80 : 0x01);
+					w = ((li_config_table[i].coef_table[j] & 0xf) ^ (li_config_table[i].coef_table[j] >> 4));
+					li_config_table[i].coef_table[j] ^= (w & mixer_write_prog_bri[n].mask) << 4;
+				}
+				else
+				{
+					*(p++) = (ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n < a->adv_voice_coef_length) ?
+						a->adv_voice_coef_buffer[ADV_VOICE_NEW_COEF_BASE + sizeof(word) + n] : 0x00;
+				}
+			}
+		}
+		else
+		{
+			for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
+				*(p++) = a->adv_voice_coef_buffer[i];
+		}
+	}
+	else
+
+	{
+		for (i = ADV_VOICE_NEW_COEF_BASE; i < a->adv_voice_coef_length; i++)
+			*(p++) = a->adv_voice_coef_buffer[i];
+	}
+	coef_buffer[0] = (p - coef_buffer) - 1;
+	add_p(plci, FTY, coef_buffer);
+	sig_req(plci, TEL_CTRL, 0);
+	send_req(plci);
+}
+
+
+static void adv_voice_clear_config(PLCI *plci)
+{
+	DIVA_CAPI_ADAPTER *a;
+
+	word i, j;
+
+
+	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_clear_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
+
+	a = plci->adapter;
+	if ((plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
+	{
+		a->adv_voice_coef_length = 0;
+
+		if (!a->li_pri && (plci->li_bchannel_id != 0)
+		    && (li_config_table[a->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+		{
+			i = a->li_base + (plci->li_bchannel_id - 1);
+			li_config_table[i].curchnl = 0;
+			li_config_table[i].channel = 0;
+			li_config_table[i].chflags = 0;
+			for (j = 0; j < li_total_channels; j++)
+			{
+				li_config_table[i].flag_table[j] = 0;
+				li_config_table[j].flag_table[i] = 0;
+				li_config_table[i].coef_table[j] = 0;
+				li_config_table[j].coef_table[i] = 0;
+			}
+			li_config_table[i].coef_table[i] |= LI_COEF_CH_PC_SET | LI_COEF_PC_CH_SET;
+			i = a->li_base + MIXER_IC_CHANNEL_BASE + (plci->li_bchannel_id - 1);
+			li_config_table[i].curchnl = 0;
+			li_config_table[i].channel = 0;
+			li_config_table[i].chflags = 0;
+			for (j = 0; j < li_total_channels; j++)
+			{
+				li_config_table[i].flag_table[j] = 0;
+				li_config_table[j].flag_table[i] = 0;
+				li_config_table[i].coef_table[j] = 0;
+				li_config_table[j].coef_table[i] = 0;
+			}
+			if (a->manufacturer_features & MANUFACTURER_FEATURE_SLAVE_CODEC)
+			{
+				i = a->li_base + MIXER_IC_CHANNEL_BASE + (2 - plci->li_bchannel_id);
+				li_config_table[i].curchnl = 0;
+				li_config_table[i].channel = 0;
+				li_config_table[i].chflags = 0;
+				for (j = 0; j < li_total_channels; j++)
+				{
+					li_config_table[i].flag_table[j] = 0;
+					li_config_table[j].flag_table[i] = 0;
+					li_config_table[i].coef_table[j] = 0;
+					li_config_table[j].coef_table[i] = 0;
+				}
+			}
+		}
+
+	}
+}
+
+
+static void adv_voice_prepare_switch(dword Id, PLCI *plci)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_prepare_switch",
+			UnMapId(Id), (char *)(FILE_), __LINE__));
+
+}
+
+
+static word adv_voice_save_config(dword Id, PLCI *plci, byte Rc)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_save_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	return (GOOD);
+}
+
+
+static word adv_voice_restore_config(dword Id, PLCI *plci, byte Rc)
+{
+	DIVA_CAPI_ADAPTER *a;
+	word Info;
 
-  Info = GOOD;
-  a = plci->adapter;
-  if ((plci->B1_facilities & B1_FACILITY_VOICE)
-   && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
-  {
-    switch (plci->adjust_b_state)
-    {
-    case ADJUST_B_RESTORE_VOICE_1:
-      plci->internal_command = plci->adjust_b_command;
-      if (plci->sig_req)
-      {
-        plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
-        break;
-      }
-      adv_voice_write_coefs (plci, ADV_VOICE_WRITE_UPDATE);
-      plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2;
-      break;
-    case ADJUST_B_RESTORE_VOICE_2:
-      if ((Rc != OK) && (Rc != OK_FC))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Restore voice config failed %02x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-        Info = _WRONG_STATE;
-        break;
-      }
-      break;
-    }
-  }
-  return (Info);
+	dbug(1, dprintf("[%06lx] %s,%d: adv_voice_restore_config %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	Info = GOOD;
+	a = plci->adapter;
+	if ((plci->B1_facilities & B1_FACILITY_VOICE)
+	    && (plci->tel == ADV_VOICE) && (plci == a->AdvSignalPLCI))
+	{
+		switch (plci->adjust_b_state)
+		{
+		case ADJUST_B_RESTORE_VOICE_1:
+			plci->internal_command = plci->adjust_b_command;
+			if (plci->sig_req)
+			{
+				plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
+				break;
+			}
+			adv_voice_write_coefs(plci, ADV_VOICE_WRITE_UPDATE);
+			plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_2;
+			break;
+		case ADJUST_B_RESTORE_VOICE_2:
+			if ((Rc != OK) && (Rc != OK_FC))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Restore voice config failed %02x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+				Info = _WRONG_STATE;
+				break;
+			}
+			break;
+		}
+	}
+	return (Info);
 }
 
 
@@ -13354,1373 +13354,1373 @@ static word adv_voice_restore_config (dword Id, PLCI   *plci, byte Rc)
 
 static byte b1_facilities_table[] =
 {
-  0x00,  /* 0  No bchannel resources      */
-  0x00,  /* 1  Codec (automatic law)      */
-  0x00,  /* 2  Codec (A-law)              */
-  0x00,  /* 3  Codec (y-law)              */
-  0x00,  /* 4  HDLC for X.21              */
-  0x00,  /* 5  HDLC                       */
-  0x00,  /* 6  External Device 0          */
-  0x00,  /* 7  External Device 1          */
-  0x00,  /* 8  HDLC 56k                   */
-  0x00,  /* 9  Transparent                */
-  0x00,  /* 10 Loopback to network        */
-  0x00,  /* 11 Test pattern to net        */
-  0x00,  /* 12 Rate adaptation sync       */
-  0x00,  /* 13 Rate adaptation async      */
-  0x00,  /* 14 R-Interface                */
-  0x00,  /* 15 HDLC 128k leased line      */
-  0x00,  /* 16 FAX                        */
-  0x00,  /* 17 Modem async                */
-  0x00,  /* 18 Modem sync HDLC            */
-  0x00,  /* 19 V.110 async HDLC           */
-  0x12,  /* 20 Adv voice (Trans,mixer)    */
-  0x00,  /* 21 Codec connected to IC      */
-  0x0c,  /* 22 Trans,DTMF                 */
-  0x1e,  /* 23 Trans,DTMF+mixer           */
-  0x1f,  /* 24 Trans,DTMF+mixer+local     */
-  0x13,  /* 25 Trans,mixer+local          */
-  0x12,  /* 26 HDLC,mixer                 */
-  0x12,  /* 27 HDLC 56k,mixer             */
-  0x2c,  /* 28 Trans,LEC+DTMF             */
-  0x3e,  /* 29 Trans,LEC+DTMF+mixer       */
-  0x3f,  /* 30 Trans,LEC+DTMF+mixer+local */
-  0x2c,  /* 31 RTP,LEC+DTMF               */
-  0x3e,  /* 32 RTP,LEC+DTMF+mixer         */
-  0x3f,  /* 33 RTP,LEC+DTMF+mixer+local   */
-  0x00,  /* 34 Signaling task             */
-  0x00,  /* 35 PIAFS                      */
-  0x0c,  /* 36 Trans,DTMF+TONE            */
-  0x1e,  /* 37 Trans,DTMF+TONE+mixer      */
-  0x1f   /* 38 Trans,DTMF+TONE+mixer+local*/
+	0x00,  /* 0  No bchannel resources      */
+	0x00,  /* 1  Codec (automatic law)      */
+	0x00,  /* 2  Codec (A-law)              */
+	0x00,  /* 3  Codec (y-law)              */
+	0x00,  /* 4  HDLC for X.21              */
+	0x00,  /* 5  HDLC                       */
+	0x00,  /* 6  External Device 0          */
+	0x00,  /* 7  External Device 1          */
+	0x00,  /* 8  HDLC 56k                   */
+	0x00,  /* 9  Transparent                */
+	0x00,  /* 10 Loopback to network        */
+	0x00,  /* 11 Test pattern to net        */
+	0x00,  /* 12 Rate adaptation sync       */
+	0x00,  /* 13 Rate adaptation async      */
+	0x00,  /* 14 R-Interface                */
+	0x00,  /* 15 HDLC 128k leased line      */
+	0x00,  /* 16 FAX                        */
+	0x00,  /* 17 Modem async                */
+	0x00,  /* 18 Modem sync HDLC            */
+	0x00,  /* 19 V.110 async HDLC           */
+	0x12,  /* 20 Adv voice (Trans,mixer)    */
+	0x00,  /* 21 Codec connected to IC      */
+	0x0c,  /* 22 Trans,DTMF                 */
+	0x1e,  /* 23 Trans,DTMF+mixer           */
+	0x1f,  /* 24 Trans,DTMF+mixer+local     */
+	0x13,  /* 25 Trans,mixer+local          */
+	0x12,  /* 26 HDLC,mixer                 */
+	0x12,  /* 27 HDLC 56k,mixer             */
+	0x2c,  /* 28 Trans,LEC+DTMF             */
+	0x3e,  /* 29 Trans,LEC+DTMF+mixer       */
+	0x3f,  /* 30 Trans,LEC+DTMF+mixer+local */
+	0x2c,  /* 31 RTP,LEC+DTMF               */
+	0x3e,  /* 32 RTP,LEC+DTMF+mixer         */
+	0x3f,  /* 33 RTP,LEC+DTMF+mixer+local   */
+	0x00,  /* 34 Signaling task             */
+	0x00,  /* 35 PIAFS                      */
+	0x0c,  /* 36 Trans,DTMF+TONE            */
+	0x1e,  /* 37 Trans,DTMF+TONE+mixer      */
+	0x1f   /* 38 Trans,DTMF+TONE+mixer+local*/
 };
 
 
-static word get_b1_facilities (PLCI   * plci, byte b1_resource)
+static word get_b1_facilities(PLCI *plci, byte b1_resource)
 {
-  word b1_facilities;
+	word b1_facilities;
 
-  b1_facilities = b1_facilities_table[b1_resource];
-  if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25))
-  {
+	b1_facilities = b1_facilities_table[b1_resource];
+	if ((b1_resource == 9) || (b1_resource == 20) || (b1_resource == 25))
+	{
 
-    if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
-       || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id-1] & (1L << PRIVATE_DTMF_TONE)))))
+		if (!(((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
+		      || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE)))))
 
-    {
-      if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)
-        b1_facilities |= B1_FACILITY_DTMFX;
-      if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)
-        b1_facilities |= B1_FACILITY_DTMFR;
-    }
-  }
-  if ((b1_resource == 17) || (b1_resource == 18))
-  {
-    if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN))
-      b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR;
-  }
+		{
+			if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND)
+				b1_facilities |= B1_FACILITY_DTMFX;
+			if (plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)
+				b1_facilities |= B1_FACILITY_DTMFR;
+		}
+	}
+	if ((b1_resource == 17) || (b1_resource == 18))
+	{
+		if (plci->adapter->manufacturer_features & (MANUFACTURER_FEATURE_V18 | MANUFACTURER_FEATURE_VOWN))
+			b1_facilities |= B1_FACILITY_DTMFX | B1_FACILITY_DTMFR;
+	}
 /*
-  dbug (1, dprintf ("[%06lx] %s,%d: get_b1_facilities %d %04x",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char far *)(FILE_), __LINE__, b1_resource, b1_facilites));
+  dbug (1, dprintf("[%06lx] %s,%d: get_b1_facilities %d %04x",
+  (dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+  (char far *)(FILE_), __LINE__, b1_resource, b1_facilites));
 */
-  return (b1_facilities);
-}
-
-
-static byte add_b1_facilities (PLCI   * plci, byte b1_resource, word b1_facilities)
-{
-  byte b;
-
-  switch (b1_resource)
-  {
-  case 5:
-  case 26:
-    if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-      b = 26;
-    else
-      b = 5;
-    break;
-
-  case 8:
-  case 27:
-    if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-      b = 27;
-    else
-      b = 8;
-    break;
-
-  case 9:
-  case 20:
-  case 22:
-  case 23:
-  case 24:
-  case 25:
-  case 28:
-  case 29:
-  case 30:
-  case 36:
-  case 37:
-  case 38:
-    if (b1_facilities & B1_FACILITY_EC)
-    {
-      if (b1_facilities & B1_FACILITY_LOCAL)
-        b = 30;
-      else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-        b = 29;
-      else
-        b = 28;
-    }
-
-    else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER))
-      && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
-       || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id-1] & (1L << PRIVATE_DTMF_TONE)))))
-    {
-      if (b1_facilities & B1_FACILITY_LOCAL)
-        b = 38;
-      else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-        b = 37;
-      else
-        b = 36;
-    }
-
-    else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
-      && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
-     || ((b1_facilities & B1_FACILITY_DTMFR)
-      && ((b1_facilities & B1_FACILITY_MIXER)
-       || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)))
-     || ((b1_facilities & B1_FACILITY_DTMFX)
-      && ((b1_facilities & B1_FACILITY_MIXER)
-       || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND))))
-    {
-      if (b1_facilities & B1_FACILITY_LOCAL)
-        b = 24;
-      else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-        b = 23;
-      else
-        b = 22;
-    }
-    else
-    {
-      if (b1_facilities & B1_FACILITY_LOCAL)
-        b = 25;
-      else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-        b = 20;
-      else
-        b = 9;
-    }
-    break;
-
-  case 31:
-  case 32:
-  case 33:
-    if (b1_facilities & B1_FACILITY_LOCAL)
-      b = 33;
-    else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
-      b = 32;
-    else
-      b = 31;
-    break;
-
-  default:
-    b = b1_resource;
-  }
-  dbug (1, dprintf ("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__,
-    b1_resource, b1_facilities, b, get_b1_facilities (plci, b)));
-  return (b);
-}
-
-
-static void adjust_b1_facilities (PLCI   *plci, byte new_b1_resource, word new_b1_facilities)
-{
-  word removed_facilities;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities,
-    new_b1_facilities & get_b1_facilities (plci, new_b1_resource)));
-
-  new_b1_facilities &= get_b1_facilities (plci, new_b1_resource);
-  removed_facilities = plci->B1_facilities & ~new_b1_facilities;
-
-  if (removed_facilities & B1_FACILITY_EC)
-    ec_clear_config (plci);
-
-
-  if (removed_facilities & B1_FACILITY_DTMFR)
-  {
-    dtmf_rec_clear_config (plci);
-    dtmf_parameter_clear_config (plci);
-  }
-  if (removed_facilities & B1_FACILITY_DTMFX)
-    dtmf_send_clear_config (plci);
-
-
-  if (removed_facilities & B1_FACILITY_MIXER)
-    mixer_clear_config (plci);
-
-  if (removed_facilities & B1_FACILITY_VOICE)
-    adv_voice_clear_config (plci);
-  plci->B1_facilities = new_b1_facilities;
-}
-
-
-static void adjust_b_clear (PLCI   *plci)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_clear",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  plci->adjust_b_restore = false;
-}
-
-
-static word adjust_b_process (dword Id, PLCI   *plci, byte Rc)
-{
-  word Info;
-  byte b1_resource;
-  NCCI   * ncci_ptr;
-    API_PARSE bp[2];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_process %02x %d",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
-
-  Info = GOOD;
-  switch (plci->adjust_b_state)
-  {
-  case ADJUST_B_START:
-    if ((plci->adjust_b_parms_msg == NULL)
-     && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
-     && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 |
-      ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0))
-    {
-      b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ?
-        0 : add_b1_facilities (plci, plci->B1_resource, plci->adjust_b_facilities);
-      if (b1_resource == plci->B1_resource)
-      {
-        adjust_b1_facilities (plci, b1_resource, plci->adjust_b_facilities);
-        break;
-      }
-      if (plci->adjust_b_facilities & ~get_b1_facilities (plci, b1_resource))
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__,
-          plci->B1_resource, b1_resource, plci->adjust_b_facilities));
-        Info = _WRONG_STATE;
-        break;
-      }
-    }
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
-    {
-
-      mixer_prepare_switch (Id, plci);
-
-
-      dtmf_prepare_switch (Id, plci);
-      dtmf_parameter_prepare_switch (Id, plci);
-
-
-      ec_prepare_switch (Id, plci);
-
-      adv_voice_prepare_switch (Id, plci);
-    }
-    plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1;
-    Rc = OK;
-  case ADJUST_B_SAVE_MIXER_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
-    {
-
-      Info = mixer_save_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1;
-    Rc = OK;
-  case ADJUST_B_SAVE_DTMF_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
-    {
-
-      Info = dtmf_save_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_REMOVE_L23_1;
-  case ADJUST_B_REMOVE_L23_1:
-    if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
-     && plci->NL.Id && !plci->nl_remove_id)
-    {
-      plci->internal_command = plci->adjust_b_command;
-      if (plci->adjust_b_ncci != 0)
-      {
-        ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]);
-        while (ncci_ptr->data_pending)
-        {
-          plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P;
-          data_rc (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
-        }
-        while (ncci_ptr->data_ack_pending)
-          data_ack (plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
-      }
-      nl_req_ncci (plci, REMOVE,
-        (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0));
-      send_req (plci);
-      plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
-      break;
-    }
-    plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
-    Rc = OK;
-  case ADJUST_B_REMOVE_L23_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Adjust B remove failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      Info = _WRONG_STATE;
-      break;
-    }
-    if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
-    {
-      if (plci_nl_busy (plci))
-      {
-        plci->internal_command = plci->adjust_b_command;
-        break;
-      }
-    }
-    plci->adjust_b_state = ADJUST_B_SAVE_EC_1;
-    Rc = OK;
-  case ADJUST_B_SAVE_EC_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
-    {
-
-      Info = ec_save_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1;
-    Rc = OK;
-  case ADJUST_B_SAVE_DTMF_PARAMETER_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
-    {
-
-      Info = dtmf_parameter_save_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1;
-    Rc = OK;
-  case ADJUST_B_SAVE_VOICE_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
-    {
-      Info = adv_voice_save_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-    }
-    plci->adjust_b_state = ADJUST_B_SWITCH_L1_1;
-  case ADJUST_B_SWITCH_L1_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
-    {
-      if (plci->sig_req)
-      {
-        plci->internal_command = plci->adjust_b_command;
-        break;
-      }
-      if (plci->adjust_b_parms_msg != NULL)
-        api_load_msg (plci->adjust_b_parms_msg, bp);
-      else
-        api_load_msg (&plci->B_protocol, bp);
-      Info = add_b1 (plci, bp,
-        (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0),
-        plci->adjust_b_facilities);
-      if (Info != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__,
-          plci->B1_resource, plci->adjust_b_facilities));
-        break;
-      }
-      plci->internal_command = plci->adjust_b_command;
-      sig_req (plci, RESOURCES, 0);
-      send_req (plci);
-      plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
-      break;
-    }
-    plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
-    Rc = OK;
-  case ADJUST_B_SWITCH_L1_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__,
-        Rc, plci->B1_resource, plci->adjust_b_facilities));
-      Info = _WRONG_STATE;
-      break;
-    }
-    plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
-    Rc = OK;
-  case ADJUST_B_RESTORE_VOICE_1:
-  case ADJUST_B_RESTORE_VOICE_2:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
-    {
-      Info = adv_voice_restore_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-    }
-    plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
-    Rc = OK;
-  case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
-  case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
-    {
-
-      Info = dtmf_parameter_restore_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
-    Rc = OK;
-  case ADJUST_B_RESTORE_EC_1:
-  case ADJUST_B_RESTORE_EC_2:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
-    {
-
-      Info = ec_restore_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1;
-  case ADJUST_B_ASSIGN_L23_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
-    {
-      if (plci_nl_busy (plci))
-      {
-        plci->internal_command = plci->adjust_b_command;
-        break;
-      }
-      if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
-        plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
-      if (plci->adjust_b_parms_msg != NULL)
-        api_load_msg (plci->adjust_b_parms_msg, bp);
-      else
-        api_load_msg (&plci->B_protocol, bp);
-      Info = add_b23 (plci, bp);
-      if (Info != GOOD)
-      {
-        dbug (1, dprintf ("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
-          UnMapId (Id), (char   *)(FILE_), __LINE__, Info));
-        break;
-      }
-      plci->internal_command = plci->adjust_b_command;
-      nl_req_ncci (plci, ASSIGN, 0);
-      send_req (plci);
-      plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
-      break;
-    }
-    plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
-    Rc = ASSIGN_OK;
-  case ADJUST_B_ASSIGN_L23_2:
-    if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Adjust B assign failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      Info = _WRONG_STATE;
-      break;
-    }
-    if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
-    {
-      if (Rc != ASSIGN_OK)
-      {
-        plci->internal_command = plci->adjust_b_command;
-        break;
-      }
-    }
-    if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT)
-    {
-      plci->adjust_b_restore = true;
-      break;
-    }
-    plci->adjust_b_state = ADJUST_B_CONNECT_1;
-  case ADJUST_B_CONNECT_1:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
-    {
-      plci->internal_command = plci->adjust_b_command;
-      if (plci_nl_busy (plci))
-        break;
-      nl_req_ncci (plci, N_CONNECT, 0);
-      send_req (plci);
-      plci->adjust_b_state = ADJUST_B_CONNECT_2;
-      break;
-    }
-    plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
-    Rc = OK;
-  case ADJUST_B_CONNECT_2:
-  case ADJUST_B_CONNECT_3:
-  case ADJUST_B_CONNECT_4:
-    if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Adjust B connect failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      Info = _WRONG_STATE;
-      break;
-    }
-    if (Rc == OK)
-    {
-      if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
-      {
-        get_ncci (plci, (byte)(Id >> 16), plci->adjust_b_ncci);
-        Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16);
-      }
-      if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
-        plci->adjust_b_state = ADJUST_B_CONNECT_3;
-      else if (plci->adjust_b_state == ADJUST_B_CONNECT_4)
-        plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
-    }
-    else if (Rc == 0)
-    {
-      if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
-        plci->adjust_b_state = ADJUST_B_CONNECT_4;
-      else if (plci->adjust_b_state == ADJUST_B_CONNECT_3)
-        plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
-    }
-    if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1)
-    {
-      plci->internal_command = plci->adjust_b_command;
-      break;
-    }
-    Rc = OK;
-  case ADJUST_B_RESTORE_DTMF_1:
-  case ADJUST_B_RESTORE_DTMF_2:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
-    {
-
-      Info = dtmf_restore_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
-    Rc = OK;
-  case ADJUST_B_RESTORE_MIXER_1:
-  case ADJUST_B_RESTORE_MIXER_2:
-  case ADJUST_B_RESTORE_MIXER_3:
-  case ADJUST_B_RESTORE_MIXER_4:
-  case ADJUST_B_RESTORE_MIXER_5:
-  case ADJUST_B_RESTORE_MIXER_6:
-  case ADJUST_B_RESTORE_MIXER_7:
-    if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
-    {
-
-      Info = mixer_restore_config (Id, plci, Rc);
-      if ((Info != GOOD) || plci->internal_command)
-        break;
-
-    }
-    plci->adjust_b_state = ADJUST_B_END;
-  case ADJUST_B_END:
-    break;
-  }
-  return (Info);
-}
-
-
-static void adjust_b1_resource (dword Id, PLCI   *plci, API_SAVE   *bp_msg, word b1_facilities, word internal_command)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: adjust_b1_resource %d %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__,
-    plci->B1_resource, b1_facilities));
-
-  plci->adjust_b_parms_msg = bp_msg;
-  plci->adjust_b_facilities = b1_facilities;
-  plci->adjust_b_command = internal_command;
-  plci->adjust_b_ncci = (word)(Id >> 16);
-  if ((bp_msg == NULL) && (plci->B1_resource == 0))
-    plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1;
-  else
-    plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE;
-  plci->adjust_b_state = ADJUST_B_START;
-  dbug (1, dprintf ("[%06lx] %s,%d: Adjust B1 resource %d %04x...",
-    UnMapId (Id), (char   *)(FILE_), __LINE__,
-    plci->B1_resource, b1_facilities));
-}
-
-
-static void adjust_b_restore (dword Id, PLCI   *plci, byte Rc)
-{
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: adjust_b_restore %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-    if (plci->req_in != 0)
-    {
-      plci->internal_command = ADJUST_B_RESTORE_1;
-      break;
-    }
-    Rc = OK;
-  case ADJUST_B_RESTORE_1:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Adjust B enqueued failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-    }
-    plci->adjust_b_parms_msg = NULL;
-    plci->adjust_b_facilities = plci->B1_facilities;
-    plci->adjust_b_command = ADJUST_B_RESTORE_2;
-    plci->adjust_b_ncci = (word)(Id >> 16);
-    plci->adjust_b_mode = ADJUST_B_MODE_RESTORE;
-    plci->adjust_b_state = ADJUST_B_START;
-    dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore...",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-  case ADJUST_B_RESTORE_2:
-    if (adjust_b_process (Id, plci, Rc) != GOOD)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Adjust B restore failed",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-    }
-    if (plci->internal_command)
-      break;
-    break;
-  }
-}
-
-
-static void reset_b3_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word Info;
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: reset_b3_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-    plci->adjust_b_parms_msg = NULL;
-    plci->adjust_b_facilities = plci->B1_facilities;
-    plci->adjust_b_command = RESET_B3_COMMAND_1;
-    plci->adjust_b_ncci = (word)(Id >> 16);
-    plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT;
-    plci->adjust_b_state = ADJUST_B_START;
-    dbug (1, dprintf ("[%06lx] %s,%d: Reset B3...",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-  case RESET_B3_COMMAND_1:
-    Info = adjust_b_process (Id, plci, Rc);
-    if (Info != GOOD)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Reset failed",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-      break;
-    }
-    if (plci->internal_command)
-      return;
-    break;
-  }
+	return (b1_facilities);
+}
+
+
+static byte add_b1_facilities(PLCI *plci, byte b1_resource, word b1_facilities)
+{
+	byte b;
+
+	switch (b1_resource)
+	{
+	case 5:
+	case 26:
+		if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+			b = 26;
+		else
+			b = 5;
+		break;
+
+	case 8:
+	case 27:
+		if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+			b = 27;
+		else
+			b = 8;
+		break;
+
+	case 9:
+	case 20:
+	case 22:
+	case 23:
+	case 24:
+	case 25:
+	case 28:
+	case 29:
+	case 30:
+	case 36:
+	case 37:
+	case 38:
+		if (b1_facilities & B1_FACILITY_EC)
+		{
+			if (b1_facilities & B1_FACILITY_LOCAL)
+				b = 30;
+			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+				b = 29;
+			else
+				b = 28;
+		}
+
+		else if ((b1_facilities & (B1_FACILITY_DTMFX | B1_FACILITY_DTMFR | B1_FACILITY_MIXER))
+			 && (((plci->requested_options_conn | plci->requested_options) & (1L << PRIVATE_DTMF_TONE))
+			     || (plci->appl && (plci->adapter->requested_options_table[plci->appl->Id - 1] & (1L << PRIVATE_DTMF_TONE)))))
+		{
+			if (b1_facilities & B1_FACILITY_LOCAL)
+				b = 38;
+			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+				b = 37;
+			else
+				b = 36;
+		}
+
+		else if (((plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_HARDDTMF)
+			  && !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE))
+			 || ((b1_facilities & B1_FACILITY_DTMFR)
+			     && ((b1_facilities & B1_FACILITY_MIXER)
+				 || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_RECEIVE)))
+			 || ((b1_facilities & B1_FACILITY_DTMFX)
+			     && ((b1_facilities & B1_FACILITY_MIXER)
+				 || !(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_SOFTDTMF_SEND))))
+		{
+			if (b1_facilities & B1_FACILITY_LOCAL)
+				b = 24;
+			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+				b = 23;
+			else
+				b = 22;
+		}
+		else
+		{
+			if (b1_facilities & B1_FACILITY_LOCAL)
+				b = 25;
+			else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+				b = 20;
+			else
+				b = 9;
+		}
+		break;
+
+	case 31:
+	case 32:
+	case 33:
+		if (b1_facilities & B1_FACILITY_LOCAL)
+			b = 33;
+		else if (b1_facilities & (B1_FACILITY_MIXER | B1_FACILITY_VOICE))
+			b = 32;
+		else
+			b = 31;
+		break;
+
+	default:
+		b = b1_resource;
+	}
+	dbug(1, dprintf("[%06lx] %s,%d: add_b1_facilities %d %04x %d %04x",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__,
+			b1_resource, b1_facilities, b, get_b1_facilities(plci, b)));
+	return (b);
+}
+
+
+static void adjust_b1_facilities(PLCI *plci, byte new_b1_resource, word new_b1_facilities)
+{
+	word removed_facilities;
+
+	dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_facilities %d %04x %04x",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__, new_b1_resource, new_b1_facilities,
+			new_b1_facilities & get_b1_facilities(plci, new_b1_resource)));
+
+	new_b1_facilities &= get_b1_facilities(plci, new_b1_resource);
+	removed_facilities = plci->B1_facilities & ~new_b1_facilities;
+
+	if (removed_facilities & B1_FACILITY_EC)
+		ec_clear_config(plci);
+
+
+	if (removed_facilities & B1_FACILITY_DTMFR)
+	{
+		dtmf_rec_clear_config(plci);
+		dtmf_parameter_clear_config(plci);
+	}
+	if (removed_facilities & B1_FACILITY_DTMFX)
+		dtmf_send_clear_config(plci);
+
+
+	if (removed_facilities & B1_FACILITY_MIXER)
+		mixer_clear_config(plci);
+
+	if (removed_facilities & B1_FACILITY_VOICE)
+		adv_voice_clear_config(plci);
+	plci->B1_facilities = new_b1_facilities;
+}
+
+
+static void adjust_b_clear(PLCI *plci)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: adjust_b_clear",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
+
+	plci->adjust_b_restore = false;
+}
+
+
+static word adjust_b_process(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+	byte b1_resource;
+	NCCI *ncci_ptr;
+	API_PARSE bp[2];
+
+	dbug(1, dprintf("[%06lx] %s,%d: adjust_b_process %02x %d",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->adjust_b_state));
+
+	Info = GOOD;
+	switch (plci->adjust_b_state)
+	{
+	case ADJUST_B_START:
+		if ((plci->adjust_b_parms_msg == NULL)
+		    && (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
+		    && ((plci->adjust_b_mode & ~(ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 |
+						 ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_RESTORE)) == 0))
+		{
+			b1_resource = (plci->adjust_b_mode == ADJUST_B_MODE_NO_RESOURCE) ?
+				0 : add_b1_facilities(plci, plci->B1_resource, plci->adjust_b_facilities);
+			if (b1_resource == plci->B1_resource)
+			{
+				adjust_b1_facilities(plci, b1_resource, plci->adjust_b_facilities);
+				break;
+			}
+			if (plci->adjust_b_facilities & ~get_b1_facilities(plci, b1_resource))
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Adjust B nonsupported facilities %d %d %04x",
+						UnMapId(Id), (char *)(FILE_), __LINE__,
+						plci->B1_resource, b1_resource, plci->adjust_b_facilities));
+				Info = _WRONG_STATE;
+				break;
+			}
+		}
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
+		{
+
+			mixer_prepare_switch(Id, plci);
+
+
+			dtmf_prepare_switch(Id, plci);
+			dtmf_parameter_prepare_switch(Id, plci);
+
+
+			ec_prepare_switch(Id, plci);
+
+			adv_voice_prepare_switch(Id, plci);
+		}
+		plci->adjust_b_state = ADJUST_B_SAVE_MIXER_1;
+		Rc = OK;
+	case ADJUST_B_SAVE_MIXER_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
+		{
+
+			Info = mixer_save_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_SAVE_DTMF_1;
+		Rc = OK;
+	case ADJUST_B_SAVE_DTMF_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
+		{
+
+			Info = dtmf_save_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_REMOVE_L23_1;
+	case ADJUST_B_REMOVE_L23_1:
+		if ((plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
+		    && plci->NL.Id && !plci->nl_remove_id)
+		{
+			plci->internal_command = plci->adjust_b_command;
+			if (plci->adjust_b_ncci != 0)
+			{
+				ncci_ptr = &(plci->adapter->ncci[plci->adjust_b_ncci]);
+				while (ncci_ptr->data_pending)
+				{
+					plci->data_sent_ptr = ncci_ptr->DBuffer[ncci_ptr->data_out].P;
+					data_rc(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
+				}
+				while (ncci_ptr->data_ack_pending)
+					data_ack(plci, plci->adapter->ncci_ch[plci->adjust_b_ncci]);
+			}
+			nl_req_ncci(plci, REMOVE,
+				    (byte)((plci->adjust_b_mode & ADJUST_B_MODE_CONNECT) ? plci->adjust_b_ncci : 0));
+			send_req(plci);
+			plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
+			break;
+		}
+		plci->adjust_b_state = ADJUST_B_REMOVE_L23_2;
+		Rc = OK;
+	case ADJUST_B_REMOVE_L23_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Adjust B remove failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			Info = _WRONG_STATE;
+			break;
+		}
+		if (plci->adjust_b_mode & ADJUST_B_MODE_REMOVE_L23)
+		{
+			if (plci_nl_busy(plci))
+			{
+				plci->internal_command = plci->adjust_b_command;
+				break;
+			}
+		}
+		plci->adjust_b_state = ADJUST_B_SAVE_EC_1;
+		Rc = OK;
+	case ADJUST_B_SAVE_EC_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
+		{
+
+			Info = ec_save_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_SAVE_DTMF_PARAMETER_1;
+		Rc = OK;
+	case ADJUST_B_SAVE_DTMF_PARAMETER_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
+		{
+
+			Info = dtmf_parameter_save_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_SAVE_VOICE_1;
+		Rc = OK;
+	case ADJUST_B_SAVE_VOICE_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SAVE)
+		{
+			Info = adv_voice_save_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+		}
+		plci->adjust_b_state = ADJUST_B_SWITCH_L1_1;
+	case ADJUST_B_SWITCH_L1_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_SWITCH_L1)
+		{
+			if (plci->sig_req)
+			{
+				plci->internal_command = plci->adjust_b_command;
+				break;
+			}
+			if (plci->adjust_b_parms_msg != NULL)
+				api_load_msg(plci->adjust_b_parms_msg, bp);
+			else
+				api_load_msg(&plci->B_protocol, bp);
+			Info = add_b1(plci, bp,
+				      (word)((plci->adjust_b_mode & ADJUST_B_MODE_NO_RESOURCE) ? 2 : 0),
+				      plci->adjust_b_facilities);
+			if (Info != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L1 parameters %d %04x",
+						UnMapId(Id), (char *)(FILE_), __LINE__,
+						plci->B1_resource, plci->adjust_b_facilities));
+				break;
+			}
+			plci->internal_command = plci->adjust_b_command;
+			sig_req(plci, RESOURCES, 0);
+			send_req(plci);
+			plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
+			break;
+		}
+		plci->adjust_b_state = ADJUST_B_SWITCH_L1_2;
+		Rc = OK;
+	case ADJUST_B_SWITCH_L1_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Adjust B switch failed %02x %d %04x",
+					UnMapId(Id), (char *)(FILE_), __LINE__,
+					Rc, plci->B1_resource, plci->adjust_b_facilities));
+			Info = _WRONG_STATE;
+			break;
+		}
+		plci->adjust_b_state = ADJUST_B_RESTORE_VOICE_1;
+		Rc = OK;
+	case ADJUST_B_RESTORE_VOICE_1:
+	case ADJUST_B_RESTORE_VOICE_2:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
+		{
+			Info = adv_voice_restore_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+		}
+		plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_PARAMETER_1;
+		Rc = OK;
+	case ADJUST_B_RESTORE_DTMF_PARAMETER_1:
+	case ADJUST_B_RESTORE_DTMF_PARAMETER_2:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
+		{
+
+			Info = dtmf_parameter_restore_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_RESTORE_EC_1;
+		Rc = OK;
+	case ADJUST_B_RESTORE_EC_1:
+	case ADJUST_B_RESTORE_EC_2:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
+		{
+
+			Info = ec_restore_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_ASSIGN_L23_1;
+	case ADJUST_B_ASSIGN_L23_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
+		{
+			if (plci_nl_busy(plci))
+			{
+				plci->internal_command = plci->adjust_b_command;
+				break;
+			}
+			if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
+				plci->call_dir |= CALL_DIR_FORCE_OUTG_NL;
+			if (plci->adjust_b_parms_msg != NULL)
+				api_load_msg(plci->adjust_b_parms_msg, bp);
+			else
+				api_load_msg(&plci->B_protocol, bp);
+			Info = add_b23(plci, bp);
+			if (Info != GOOD)
+			{
+				dbug(1, dprintf("[%06lx] %s,%d: Adjust B invalid L23 parameters %04x",
+						UnMapId(Id), (char *)(FILE_), __LINE__, Info));
+				break;
+			}
+			plci->internal_command = plci->adjust_b_command;
+			nl_req_ncci(plci, ASSIGN, 0);
+			send_req(plci);
+			plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
+			break;
+		}
+		plci->adjust_b_state = ADJUST_B_ASSIGN_L23_2;
+		Rc = ASSIGN_OK;
+	case ADJUST_B_ASSIGN_L23_2:
+		if ((Rc != OK) && (Rc != OK_FC) && (Rc != ASSIGN_OK))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Adjust B assign failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			Info = _WRONG_STATE;
+			break;
+		}
+		if (plci->adjust_b_mode & ADJUST_B_MODE_ASSIGN_L23)
+		{
+			if (Rc != ASSIGN_OK)
+			{
+				plci->internal_command = plci->adjust_b_command;
+				break;
+			}
+		}
+		if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT)
+		{
+			plci->adjust_b_restore = true;
+			break;
+		}
+		plci->adjust_b_state = ADJUST_B_CONNECT_1;
+	case ADJUST_B_CONNECT_1:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
+		{
+			plci->internal_command = plci->adjust_b_command;
+			if (plci_nl_busy(plci))
+				break;
+			nl_req_ncci(plci, N_CONNECT, 0);
+			send_req(plci);
+			plci->adjust_b_state = ADJUST_B_CONNECT_2;
+			break;
+		}
+		plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
+		Rc = OK;
+	case ADJUST_B_CONNECT_2:
+	case ADJUST_B_CONNECT_3:
+	case ADJUST_B_CONNECT_4:
+		if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Adjust B connect failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			Info = _WRONG_STATE;
+			break;
+		}
+		if (Rc == OK)
+		{
+			if (plci->adjust_b_mode & ADJUST_B_MODE_CONNECT)
+			{
+				get_ncci(plci, (byte)(Id >> 16), plci->adjust_b_ncci);
+				Id = (Id & 0xffff) | (((dword)(plci->adjust_b_ncci)) << 16);
+			}
+			if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
+				plci->adjust_b_state = ADJUST_B_CONNECT_3;
+			else if (plci->adjust_b_state == ADJUST_B_CONNECT_4)
+				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
+		}
+		else if (Rc == 0)
+		{
+			if (plci->adjust_b_state == ADJUST_B_CONNECT_2)
+				plci->adjust_b_state = ADJUST_B_CONNECT_4;
+			else if (plci->adjust_b_state == ADJUST_B_CONNECT_3)
+				plci->adjust_b_state = ADJUST_B_RESTORE_DTMF_1;
+		}
+		if (plci->adjust_b_state != ADJUST_B_RESTORE_DTMF_1)
+		{
+			plci->internal_command = plci->adjust_b_command;
+			break;
+		}
+		Rc = OK;
+	case ADJUST_B_RESTORE_DTMF_1:
+	case ADJUST_B_RESTORE_DTMF_2:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
+		{
+
+			Info = dtmf_restore_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_RESTORE_MIXER_1;
+		Rc = OK;
+	case ADJUST_B_RESTORE_MIXER_1:
+	case ADJUST_B_RESTORE_MIXER_2:
+	case ADJUST_B_RESTORE_MIXER_3:
+	case ADJUST_B_RESTORE_MIXER_4:
+	case ADJUST_B_RESTORE_MIXER_5:
+	case ADJUST_B_RESTORE_MIXER_6:
+	case ADJUST_B_RESTORE_MIXER_7:
+		if (plci->adjust_b_mode & ADJUST_B_MODE_RESTORE)
+		{
+
+			Info = mixer_restore_config(Id, plci, Rc);
+			if ((Info != GOOD) || plci->internal_command)
+				break;
+
+		}
+		plci->adjust_b_state = ADJUST_B_END;
+	case ADJUST_B_END:
+		break;
+	}
+	return (Info);
+}
+
+
+static void adjust_b1_resource(dword Id, PLCI *plci, API_SAVE   *bp_msg, word b1_facilities, word internal_command)
+{
+
+	dbug(1, dprintf("[%06lx] %s,%d: adjust_b1_resource %d %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__,
+			plci->B1_resource, b1_facilities));
+
+	plci->adjust_b_parms_msg = bp_msg;
+	plci->adjust_b_facilities = b1_facilities;
+	plci->adjust_b_command = internal_command;
+	plci->adjust_b_ncci = (word)(Id >> 16);
+	if ((bp_msg == NULL) && (plci->B1_resource == 0))
+		plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_NO_RESOURCE | ADJUST_B_MODE_SWITCH_L1;
+	else
+		plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_SWITCH_L1 | ADJUST_B_MODE_RESTORE;
+	plci->adjust_b_state = ADJUST_B_START;
+	dbug(1, dprintf("[%06lx] %s,%d: Adjust B1 resource %d %04x...",
+			UnMapId(Id), (char *)(FILE_), __LINE__,
+			plci->B1_resource, b1_facilities));
+}
+
+
+static void adjust_b_restore(dword Id, PLCI *plci, byte Rc)
+{
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: adjust_b_restore %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+		if (plci->req_in != 0)
+		{
+			plci->internal_command = ADJUST_B_RESTORE_1;
+			break;
+		}
+		Rc = OK;
+	case ADJUST_B_RESTORE_1:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Adjust B enqueued failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+		}
+		plci->adjust_b_parms_msg = NULL;
+		plci->adjust_b_facilities = plci->B1_facilities;
+		plci->adjust_b_command = ADJUST_B_RESTORE_2;
+		plci->adjust_b_ncci = (word)(Id >> 16);
+		plci->adjust_b_mode = ADJUST_B_MODE_RESTORE;
+		plci->adjust_b_state = ADJUST_B_START;
+		dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore...",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+	case ADJUST_B_RESTORE_2:
+		if (adjust_b_process(Id, plci, Rc) != GOOD)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Adjust B restore failed",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+		}
+		if (plci->internal_command)
+			break;
+		break;
+	}
+}
+
+
+static void reset_b3_command(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: reset_b3_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+		plci->adjust_b_parms_msg = NULL;
+		plci->adjust_b_facilities = plci->B1_facilities;
+		plci->adjust_b_command = RESET_B3_COMMAND_1;
+		plci->adjust_b_ncci = (word)(Id >> 16);
+		plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_CONNECT;
+		plci->adjust_b_state = ADJUST_B_START;
+		dbug(1, dprintf("[%06lx] %s,%d: Reset B3...",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+	case RESET_B3_COMMAND_1:
+		Info = adjust_b_process(Id, plci, Rc);
+		if (Info != GOOD)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Reset failed",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+			break;
+		}
+		if (plci->internal_command)
+			return;
+		break;
+	}
 /*  sendf (plci->appl, _RESET_B3_R | CONFIRM, Id, plci->number, "w", Info);*/
-  sendf(plci->appl,_RESET_B3_I,Id,0,"s","");
-}
-
-
-static void select_b_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word Info;
-  word internal_command;
-  byte esc_chi[3];
-
-  dbug (1, dprintf ("[%06lx] %s,%d: select_b_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-    plci->adjust_b_parms_msg = &plci->saved_msg;
-    if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI))
-      plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE;
-    else
-      plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE;
-    plci->adjust_b_command = SELECT_B_COMMAND_1;
-    plci->adjust_b_ncci = (word)(Id >> 16);
-    if (plci->saved_msg.parms[0].length == 0)
-    {
-      plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
-        ADJUST_B_MODE_NO_RESOURCE;
-    }
-    else
-    {
-      plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
-        ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
-    }
-    plci->adjust_b_state = ADJUST_B_START;
-    dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol...",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-  case SELECT_B_COMMAND_1:
-    Info = adjust_b_process (Id, plci, Rc);
-    if (Info != GOOD)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: Select B protocol failed",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-      break;
-    }
-    if (plci->internal_command)
-      return;
-    if (plci->tel == ADV_VOICE)
-    {
-      esc_chi[0] = 0x02;
-      esc_chi[1] = 0x18;
-      esc_chi[2] = plci->b_channel;
-      SetVoiceChannel (plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter);
-    }
-    break;
-  }
-  sendf (plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info);
-}
-
-
-static void fax_connect_ack_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-  case FAX_CONNECT_ACK_COMMAND_1:
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = FAX_CONNECT_ACK_COMMAND_1;
-      return;
-    }
-    plci->internal_command = FAX_CONNECT_ACK_COMMAND_2;
-    plci->NData[0].P = plci->fax_connect_info_buffer;
-    plci->NData[0].PLength = plci->fax_connect_info_length;
-    plci->NL.X = plci->NData;
-    plci->NL.ReqCh = 0;
-    plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK;
-    plci->adapter->request (&plci->NL);
-    return;
-  case FAX_CONNECT_ACK_COMMAND_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      break;
-    }
-  }
-  if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
-   && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
-  {
-    if (plci->B3_prot == 4)
-      sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
-    else
-      sendf(plci->appl,_CONNECT_B3_ACTIVE_I,Id,0,"S",plci->ncpi_buffer);
-    plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
-  }
-}
-
-
-static void fax_edata_ack_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-  case FAX_EDATA_ACK_COMMAND_1:
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = FAX_EDATA_ACK_COMMAND_1;
-      return;
-    }
-    plci->internal_command = FAX_EDATA_ACK_COMMAND_2;
-    plci->NData[0].P = plci->fax_connect_info_buffer;
-    plci->NData[0].PLength = plci->fax_edata_ack_length;
-    plci->NL.X = plci->NData;
-    plci->NL.ReqCh = 0;
-    plci->NL.Req = plci->nl_req = (byte) N_EDATA;
-    plci->adapter->request (&plci->NL);
-    return;
-  case FAX_EDATA_ACK_COMMAND_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      break;
-    }
-  }
-}
-
-
-static void fax_connect_info_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word Info;
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-  case FAX_CONNECT_INFO_COMMAND_1:
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = FAX_CONNECT_INFO_COMMAND_1;
-      return;
-    }
-    plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
-    plci->NData[0].P = plci->fax_connect_info_buffer;
-    plci->NData[0].PLength = plci->fax_connect_info_length;
-    plci->NL.X = plci->NData;
-    plci->NL.ReqCh = 0;
-    plci->NL.Req = plci->nl_req = (byte) N_EDATA;
-    plci->adapter->request (&plci->NL);
-    return;
-  case FAX_CONNECT_INFO_COMMAND_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: FAX setting connect info failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      Info = _WRONG_STATE;
-      break;
-    }
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
-      return;
-    }
-    plci->command = _CONNECT_B3_R;
-    nl_req_ncci (plci, N_CONNECT, 0);
-    send_req (plci);
-    return;
-  }
-  sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
+	sendf(plci->appl, _RESET_B3_I, Id, 0, "s", "");
+}
+
+
+static void select_b_command(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+	word internal_command;
+	byte esc_chi[3];
+
+	dbug(1, dprintf("[%06lx] %s,%d: select_b_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+		plci->adjust_b_parms_msg = &plci->saved_msg;
+		if ((plci->tel == ADV_VOICE) && (plci == plci->adapter->AdvSignalPLCI))
+			plci->adjust_b_facilities = plci->B1_facilities | B1_FACILITY_VOICE;
+		else
+			plci->adjust_b_facilities = plci->B1_facilities & ~B1_FACILITY_VOICE;
+		plci->adjust_b_command = SELECT_B_COMMAND_1;
+		plci->adjust_b_ncci = (word)(Id >> 16);
+		if (plci->saved_msg.parms[0].length == 0)
+		{
+			plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
+				ADJUST_B_MODE_NO_RESOURCE;
+		}
+		else
+		{
+			plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_SWITCH_L1 |
+				ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
+		}
+		plci->adjust_b_state = ADJUST_B_START;
+		dbug(1, dprintf("[%06lx] %s,%d: Select B protocol...",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+	case SELECT_B_COMMAND_1:
+		Info = adjust_b_process(Id, plci, Rc);
+		if (Info != GOOD)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: Select B protocol failed",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+			break;
+		}
+		if (plci->internal_command)
+			return;
+		if (plci->tel == ADV_VOICE)
+		{
+			esc_chi[0] = 0x02;
+			esc_chi[1] = 0x18;
+			esc_chi[2] = plci->b_channel;
+			SetVoiceChannel(plci->adapter->AdvCodecPLCI, esc_chi, plci->adapter);
+		}
+		break;
+	}
+	sendf(plci->appl, _SELECT_B_REQ | CONFIRM, Id, plci->number, "w", Info);
+}
+
+
+static void fax_connect_ack_command(dword Id, PLCI *plci, byte Rc)
+{
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+	case FAX_CONNECT_ACK_COMMAND_1:
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = FAX_CONNECT_ACK_COMMAND_1;
+			return;
+		}
+		plci->internal_command = FAX_CONNECT_ACK_COMMAND_2;
+		plci->NData[0].P = plci->fax_connect_info_buffer;
+		plci->NData[0].PLength = plci->fax_connect_info_length;
+		plci->NL.X = plci->NData;
+		plci->NL.ReqCh = 0;
+		plci->NL.Req = plci->nl_req = (byte) N_CONNECT_ACK;
+		plci->adapter->request(&plci->NL);
+		return;
+	case FAX_CONNECT_ACK_COMMAND_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: FAX issue CONNECT ACK failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			break;
+		}
+	}
+	if ((plci->ncpi_state & NCPI_VALID_CONNECT_B3_ACT)
+	    && !(plci->ncpi_state & NCPI_CONNECT_B3_ACT_SENT))
+	{
+		if (plci->B3_prot == 4)
+			sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+		else
+			sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "S", plci->ncpi_buffer);
+		plci->ncpi_state |= NCPI_CONNECT_B3_ACT_SENT;
+	}
+}
+
+
+static void fax_edata_ack_command(dword Id, PLCI *plci, byte Rc)
+{
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+	case FAX_EDATA_ACK_COMMAND_1:
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = FAX_EDATA_ACK_COMMAND_1;
+			return;
+		}
+		plci->internal_command = FAX_EDATA_ACK_COMMAND_2;
+		plci->NData[0].P = plci->fax_connect_info_buffer;
+		plci->NData[0].PLength = plci->fax_edata_ack_length;
+		plci->NL.X = plci->NData;
+		plci->NL.ReqCh = 0;
+		plci->NL.Req = plci->nl_req = (byte) N_EDATA;
+		plci->adapter->request(&plci->NL);
+		return;
+	case FAX_EDATA_ACK_COMMAND_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: FAX issue EDATA ACK failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			break;
+		}
+	}
+}
+
+
+static void fax_connect_info_command(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: fax_connect_info_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+	case FAX_CONNECT_INFO_COMMAND_1:
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = FAX_CONNECT_INFO_COMMAND_1;
+			return;
+		}
+		plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
+		plci->NData[0].P = plci->fax_connect_info_buffer;
+		plci->NData[0].PLength = plci->fax_connect_info_length;
+		plci->NL.X = plci->NData;
+		plci->NL.ReqCh = 0;
+		plci->NL.Req = plci->nl_req = (byte) N_EDATA;
+		plci->adapter->request(&plci->NL);
+		return;
+	case FAX_CONNECT_INFO_COMMAND_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: FAX setting connect info failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			Info = _WRONG_STATE;
+			break;
+		}
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = FAX_CONNECT_INFO_COMMAND_2;
+			return;
+		}
+		plci->command = _CONNECT_B3_R;
+		nl_req_ncci(plci, N_CONNECT, 0);
+		send_req(plci);
+		return;
+	}
+	sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
+}
+
+
+static void fax_adjust_b23_command(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+		plci->adjust_b_parms_msg = NULL;
+		plci->adjust_b_facilities = plci->B1_facilities;
+		plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1;
+		plci->adjust_b_ncci = (word)(Id >> 16);
+		plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23;
+		plci->adjust_b_state = ADJUST_B_START;
+		dbug(1, dprintf("[%06lx] %s,%d: FAX adjust B23...",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+	case FAX_ADJUST_B23_COMMAND_1:
+		Info = adjust_b_process(Id, plci, Rc);
+		if (Info != GOOD)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: FAX adjust failed",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+			break;
+		}
+		if (plci->internal_command)
+			return;
+	case FAX_ADJUST_B23_COMMAND_2:
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = FAX_ADJUST_B23_COMMAND_2;
+			return;
+		}
+		plci->command = _CONNECT_B3_R;
+		nl_req_ncci(plci, N_CONNECT, 0);
+		send_req(plci);
+		return;
+	}
+	sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
+}
+
+
+static void fax_disconnect_command(dword Id, PLCI *plci, byte Rc)
+{
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+		plci->internal_command = FAX_DISCONNECT_COMMAND_1;
+		return;
+	case FAX_DISCONNECT_COMMAND_1:
+	case FAX_DISCONNECT_COMMAND_2:
+	case FAX_DISCONNECT_COMMAND_3:
+		if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			break;
+		}
+		if (Rc == OK)
+		{
+			if ((internal_command == FAX_DISCONNECT_COMMAND_1)
+			    || (internal_command == FAX_DISCONNECT_COMMAND_2))
+			{
+				plci->internal_command = FAX_DISCONNECT_COMMAND_2;
+			}
+		}
+		else if (Rc == 0)
+		{
+			if (internal_command == FAX_DISCONNECT_COMMAND_1)
+				plci->internal_command = FAX_DISCONNECT_COMMAND_3;
+		}
+		return;
+	}
+}
+
+
+
+static void rtp_connect_b3_req_command(dword Id, PLCI *plci, byte Rc)
+{
+	word Info;
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+	case RTP_CONNECT_B3_REQ_COMMAND_1:
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1;
+			return;
+		}
+		plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
+		nl_req_ncci(plci, N_CONNECT, 0);
+		send_req(plci);
+		return;
+	case RTP_CONNECT_B3_REQ_COMMAND_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect info failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			Info = _WRONG_STATE;
+			break;
+		}
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
+			return;
+		}
+		plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3;
+		plci->NData[0].PLength = plci->internal_req_buffer[0];
+		plci->NData[0].P = plci->internal_req_buffer + 1;
+		plci->NL.X = plci->NData;
+		plci->NL.ReqCh = 0;
+		plci->NL.Req = plci->nl_req = (byte) N_UDATA;
+		plci->adapter->request(&plci->NL);
+		break;
+	case RTP_CONNECT_B3_REQ_COMMAND_3:
+		return;
+	}
+	sendf(plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
+}
+
+
+static void rtp_connect_b3_res_command(dword Id, PLCI *plci, byte Rc)
+{
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+	case RTP_CONNECT_B3_RES_COMMAND_1:
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1;
+			return;
+		}
+		plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
+		nl_req_ncci(plci, N_CONNECT_ACK, (byte)(Id >> 16));
+		send_req(plci);
+		return;
+	case RTP_CONNECT_B3_RES_COMMAND_2:
+		if ((Rc != OK) && (Rc != OK_FC))
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
+					UnMapId(Id), (char *)(FILE_), __LINE__, Rc));
+			break;
+		}
+		if (plci_nl_busy(plci))
+		{
+			plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
+			return;
+		}
+		sendf(plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
+		plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3;
+		plci->NData[0].PLength = plci->internal_req_buffer[0];
+		plci->NData[0].P = plci->internal_req_buffer + 1;
+		plci->NL.X = plci->NData;
+		plci->NL.ReqCh = 0;
+		plci->NL.Req = plci->nl_req = (byte) N_UDATA;
+		plci->adapter->request(&plci->NL);
+		return;
+	case RTP_CONNECT_B3_RES_COMMAND_3:
+		return;
+	}
+}
+
+
+
+static void hold_save_command(dword Id, PLCI *plci, byte Rc)
+{
+	byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
+	word Info;
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: hold_save_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		if (!plci->NL.Id)
+			break;
+		plci->command = 0;
+		plci->adjust_b_parms_msg = NULL;
+		plci->adjust_b_facilities = plci->B1_facilities;
+		plci->adjust_b_command = HOLD_SAVE_COMMAND_1;
+		plci->adjust_b_ncci = (word)(Id >> 16);
+		plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23;
+		plci->adjust_b_state = ADJUST_B_START;
+		dbug(1, dprintf("[%06lx] %s,%d: HOLD save...",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+	case HOLD_SAVE_COMMAND_1:
+		Info = adjust_b_process(Id, plci, Rc);
+		if (Info != GOOD)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: HOLD save failed",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+			break;
+		}
+		if (plci->internal_command)
+			return;
+	}
+	sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
+}
+
+
+static void retrieve_restore_command(dword Id, PLCI *plci, byte Rc)
+{
+	byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
+	word Info;
+	word internal_command;
+
+	dbug(1, dprintf("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
+			UnMapId(Id), (char *)(FILE_), __LINE__, Rc, plci->internal_command));
+
+	Info = GOOD;
+	internal_command = plci->internal_command;
+	plci->internal_command = 0;
+	switch (internal_command)
+	{
+	default:
+		plci->command = 0;
+		plci->adjust_b_parms_msg = NULL;
+		plci->adjust_b_facilities = plci->B1_facilities;
+		plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1;
+		plci->adjust_b_ncci = (word)(Id >> 16);
+		plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
+		plci->adjust_b_state = ADJUST_B_START;
+		dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore...",
+				UnMapId(Id), (char *)(FILE_), __LINE__));
+	case RETRIEVE_RESTORE_COMMAND_1:
+		Info = adjust_b_process(Id, plci, Rc);
+		if (Info != GOOD)
+		{
+			dbug(1, dprintf("[%06lx] %s,%d: RETRIEVE restore failed",
+					UnMapId(Id), (char *)(FILE_), __LINE__));
+			break;
+		}
+		if (plci->internal_command)
+			return;
+	}
+	sendf(plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
 }
 
 
-static void fax_adjust_b23_command (dword Id, PLCI   *plci, byte Rc)
+static void init_b1_config(PLCI *plci)
 {
-  word Info;
-  word internal_command;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: fax_adjust_b23_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
+	dbug(1, dprintf("[%06lx] %s,%d: init_b1_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-    plci->adjust_b_parms_msg = NULL;
-    plci->adjust_b_facilities = plci->B1_facilities;
-    plci->adjust_b_command = FAX_ADJUST_B23_COMMAND_1;
-    plci->adjust_b_ncci = (word)(Id >> 16);
-    plci->adjust_b_mode = ADJUST_B_MODE_REMOVE_L23 | ADJUST_B_MODE_ASSIGN_L23;
-    plci->adjust_b_state = ADJUST_B_START;
-    dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust B23...",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-  case FAX_ADJUST_B23_COMMAND_1:
-    Info = adjust_b_process (Id, plci, Rc);
-    if (Info != GOOD)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: FAX adjust failed",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-      break;
-    }
-    if (plci->internal_command)
-      return;
-  case FAX_ADJUST_B23_COMMAND_2:
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = FAX_ADJUST_B23_COMMAND_2;
-      return;
-    }
-    plci->command = _CONNECT_B3_R;
-    nl_req_ncci (plci, N_CONNECT, 0);
-    send_req (plci);
-    return;
-  }
-  sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
-}
-
-
-static void fax_disconnect_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: fax_disconnect_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-    plci->internal_command = FAX_DISCONNECT_COMMAND_1;
-    return;
-  case FAX_DISCONNECT_COMMAND_1:
-  case FAX_DISCONNECT_COMMAND_2:
-  case FAX_DISCONNECT_COMMAND_3:
-    if ((Rc != OK) && (Rc != OK_FC) && (Rc != 0))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: FAX disconnect EDATA failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      break;
-    }
-    if (Rc == OK)
-    {
-      if ((internal_command == FAX_DISCONNECT_COMMAND_1)
-       || (internal_command == FAX_DISCONNECT_COMMAND_2))
-      {
-        plci->internal_command = FAX_DISCONNECT_COMMAND_2;
-      }
-    }
-    else if (Rc == 0)
-    {
-      if (internal_command == FAX_DISCONNECT_COMMAND_1)
-        plci->internal_command = FAX_DISCONNECT_COMMAND_3;
-    }
-    return;
-  }
-}
-
-
-
-static void rtp_connect_b3_req_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word Info;
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_req_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-  case RTP_CONNECT_B3_REQ_COMMAND_1:
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_1;
-      return;
-    }
-    plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
-    nl_req_ncci (plci, N_CONNECT, 0);
-    send_req (plci);
-    return;
-  case RTP_CONNECT_B3_REQ_COMMAND_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect info failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      Info = _WRONG_STATE;
-      break;
-    }
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_2;
-      return;
-    }
-    plci->internal_command = RTP_CONNECT_B3_REQ_COMMAND_3;
-    plci->NData[0].PLength = plci->internal_req_buffer[0];
-    plci->NData[0].P = plci->internal_req_buffer + 1;
-    plci->NL.X = plci->NData;
-    plci->NL.ReqCh = 0;
-    plci->NL.Req = plci->nl_req = (byte) N_UDATA;
-    plci->adapter->request (&plci->NL);
-    break;
-  case RTP_CONNECT_B3_REQ_COMMAND_3:
-    return;
-  }
-  sendf (plci->appl, _CONNECT_B3_R | CONFIRM, Id, plci->number, "w", Info);
-}
-
-
-static void rtp_connect_b3_res_command (dword Id, PLCI   *plci, byte Rc)
-{
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-  case RTP_CONNECT_B3_RES_COMMAND_1:
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_1;
-      return;
-    }
-    plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
-    nl_req_ncci (plci, N_CONNECT_ACK, (byte)(Id >> 16));
-    send_req (plci);
-    return;
-  case RTP_CONNECT_B3_RES_COMMAND_2:
-    if ((Rc != OK) && (Rc != OK_FC))
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
-        UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      break;
-    }
-    if (plci_nl_busy (plci))
-    {
-      plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_2;
-      return;
-    }
-    sendf (plci->appl, _CONNECT_B3_ACTIVE_I, Id, 0, "s", "");
-    plci->internal_command = RTP_CONNECT_B3_RES_COMMAND_3;
-    plci->NData[0].PLength = plci->internal_req_buffer[0];
-    plci->NData[0].P = plci->internal_req_buffer + 1;
-    plci->NL.X = plci->NData;
-    plci->NL.ReqCh = 0;
-    plci->NL.Req = plci->nl_req = (byte) N_UDATA;
-    plci->adapter->request (&plci->NL);
-    return;
-  case RTP_CONNECT_B3_RES_COMMAND_3:
-    return;
-  }
-}
-
-
-
-static void hold_save_command (dword Id, PLCI   *plci, byte Rc)
-{
-    byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/
-  word Info;
-  word internal_command;
+	plci->B1_resource = 0;
+	plci->B1_facilities = 0;
 
-  dbug (1, dprintf ("[%06lx] %s,%d: hold_save_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
+	plci->li_bchannel_id = 0;
+	mixer_clear_config(plci);
 
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    if (!plci->NL.Id)
-      break;
-    plci->command = 0;
-    plci->adjust_b_parms_msg = NULL;
-    plci->adjust_b_facilities = plci->B1_facilities;
-    plci->adjust_b_command = HOLD_SAVE_COMMAND_1;
-    plci->adjust_b_ncci = (word)(Id >> 16);
-    plci->adjust_b_mode = ADJUST_B_MODE_SAVE | ADJUST_B_MODE_REMOVE_L23;
-    plci->adjust_b_state = ADJUST_B_START;
-    dbug (1, dprintf ("[%06lx] %s,%d: HOLD save...",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-  case HOLD_SAVE_COMMAND_1:
-    Info = adjust_b_process (Id, plci, Rc);
-    if (Info != GOOD)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: HOLD save failed",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-      break;
-    }
-    if (plci->internal_command)
-      return;
-  }
-  sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
-}
-
-
-static void retrieve_restore_command (dword Id, PLCI   *plci, byte Rc)
-{
-    byte SS_Ind[] = "\x05\x03\x00\x02\x00\x00"; /* Retrieve_Ind struct*/
-  word Info;
-  word internal_command;
-
-  dbug (1, dprintf ("[%06lx] %s,%d: retrieve_restore_command %02x %04x",
-    UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
-
-  Info = GOOD;
-  internal_command = plci->internal_command;
-  plci->internal_command = 0;
-  switch (internal_command)
-  {
-  default:
-    plci->command = 0;
-    plci->adjust_b_parms_msg = NULL;
-    plci->adjust_b_facilities = plci->B1_facilities;
-    plci->adjust_b_command = RETRIEVE_RESTORE_COMMAND_1;
-    plci->adjust_b_ncci = (word)(Id >> 16);
-    plci->adjust_b_mode = ADJUST_B_MODE_ASSIGN_L23 | ADJUST_B_MODE_USER_CONNECT | ADJUST_B_MODE_RESTORE;
-    plci->adjust_b_state = ADJUST_B_START;
-    dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore...",
-      UnMapId (Id), (char   *)(FILE_), __LINE__));
-  case RETRIEVE_RESTORE_COMMAND_1:
-    Info = adjust_b_process (Id, plci, Rc);
-    if (Info != GOOD)
-    {
-      dbug (1, dprintf ("[%06lx] %s,%d: RETRIEVE restore failed",
-        UnMapId (Id), (char   *)(FILE_), __LINE__));
-      break;
-    }
-    if (plci->internal_command)
-      return;
-  }
-  sendf (plci->appl, _FACILITY_I, Id & 0xffffL, 0, "ws", 3, SS_Ind);
-}
-
-
-static void init_b1_config (PLCI   *plci)
-{
-
-  dbug (1, dprintf ("[%06lx] %s,%d: init_b1_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
-
-  plci->B1_resource = 0;
-  plci->B1_facilities = 0;
 
-  plci->li_bchannel_id = 0;
-  mixer_clear_config (plci);
+	ec_clear_config(plci);
 
 
-  ec_clear_config (plci);
+	dtmf_rec_clear_config(plci);
+	dtmf_send_clear_config(plci);
+	dtmf_parameter_clear_config(plci);
 
-
-  dtmf_rec_clear_config (plci);
-  dtmf_send_clear_config (plci);
-  dtmf_parameter_clear_config (plci);
-
-  adv_voice_clear_config (plci);
-  adjust_b_clear (plci);
+	adv_voice_clear_config(plci);
+	adjust_b_clear(plci);
 }
 
 
-static void clear_b1_config (PLCI   *plci)
+static void clear_b1_config(PLCI *plci)
 {
 
-  dbug (1, dprintf ("[%06lx] %s,%d: clear_b1_config",
-    (dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
-    (char   *)(FILE_), __LINE__));
+	dbug(1, dprintf("[%06lx] %s,%d: clear_b1_config",
+			(dword)((plci->Id << 8) | UnMapController(plci->adapter->Id)),
+			(char *)(FILE_), __LINE__));
 
-  adv_voice_clear_config (plci);
-  adjust_b_clear (plci);
+	adv_voice_clear_config(plci);
+	adjust_b_clear(plci);
 
-  ec_clear_config (plci);
+	ec_clear_config(plci);
 
 
-  dtmf_rec_clear_config (plci);
-  dtmf_send_clear_config (plci);
-  dtmf_parameter_clear_config (plci);
+	dtmf_rec_clear_config(plci);
+	dtmf_send_clear_config(plci);
+	dtmf_parameter_clear_config(plci);
 
 
-  if ((plci->li_bchannel_id != 0)
-   && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci))
-  {
-    mixer_clear_config (plci);
-    li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL;
-    plci->li_bchannel_id = 0;
-  }
+	if ((plci->li_bchannel_id != 0)
+	    && (li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci == plci))
+	{
+		mixer_clear_config(plci);
+		li_config_table[plci->adapter->li_base + (plci->li_bchannel_id - 1)].plci = NULL;
+		plci->li_bchannel_id = 0;
+	}
 
-  plci->B1_resource = 0;
-  plci->B1_facilities = 0;
+	plci->B1_resource = 0;
+	plci->B1_facilities = 0;
 }
 
 
 /* -----------------------------------------------------------------
-                XON protocol local helpers
+   XON protocol local helpers
    ----------------------------------------------------------------- */
-static void channel_flow_control_remove (PLCI   * plci) {
-  DIVA_CAPI_ADAPTER   * a = plci->adapter;
-  word i;
-  for(i=1;i<MAX_NL_CHANNEL+1;i++) {
-    if (a->ch_flow_plci[i] == plci->Id) {
-      a->ch_flow_plci[i] = 0;
-      a->ch_flow_control[i] = 0;
-    }
-  }
-}
-
-static void channel_x_on (PLCI   * plci, byte ch) {
-  DIVA_CAPI_ADAPTER   * a = plci->adapter;
-  if (a->ch_flow_control[ch] & N_XON_SENT) {
-    a->ch_flow_control[ch] &= ~N_XON_SENT;
-  }
-}
-
-static void channel_x_off (PLCI   * plci, byte ch, byte flag) {
-  DIVA_CAPI_ADAPTER   * a = plci->adapter;
-  if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) {
-    a->ch_flow_control[ch] |= (N_CH_XOFF | flag);
-    a->ch_flow_plci[ch] = plci->Id;
-    a->ch_flow_control_pending++;
-  }
-}
-
-static void channel_request_xon (PLCI   * plci, byte ch) {
-  DIVA_CAPI_ADAPTER   * a = plci->adapter;
-
-  if (a->ch_flow_control[ch] & N_CH_XOFF) {
-    a->ch_flow_control[ch] |= N_XON_REQ;
-    a->ch_flow_control[ch] &= ~N_CH_XOFF;
-    a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND;
-  }
-}
-
-static void channel_xmit_extended_xon (PLCI   * plci) {
-  DIVA_CAPI_ADAPTER   * a;
-  int max_ch = ARRAY_SIZE(a->ch_flow_control);
-  int i, one_requested = 0;
-
-  if ((!plci) || (!plci->Id) || ((a = plci->adapter) == NULL)) {
-    return;
-  }
-
-  for (i = 0; i < max_ch; i++) {
-    if ((a->ch_flow_control[i] & N_CH_XOFF) &&
-        (a->ch_flow_control[i] & N_XON_CONNECT_IND) &&
-        (plci->Id == a->ch_flow_plci[i])) {
-      channel_request_xon (plci, (byte)i);
-      one_requested = 1;
-    }
-  }
-
-  if (one_requested) {
-    channel_xmit_xon (plci);
-  }
+static void channel_flow_control_remove(PLCI *plci) {
+	DIVA_CAPI_ADAPTER *a = plci->adapter;
+	word i;
+	for (i = 1; i < MAX_NL_CHANNEL + 1; i++) {
+		if (a->ch_flow_plci[i] == plci->Id) {
+			a->ch_flow_plci[i] = 0;
+			a->ch_flow_control[i] = 0;
+		}
+	}
+}
+
+static void channel_x_on(PLCI *plci, byte ch) {
+	DIVA_CAPI_ADAPTER *a = plci->adapter;
+	if (a->ch_flow_control[ch] & N_XON_SENT) {
+		a->ch_flow_control[ch] &= ~N_XON_SENT;
+	}
+}
+
+static void channel_x_off(PLCI *plci, byte ch, byte flag) {
+	DIVA_CAPI_ADAPTER *a = plci->adapter;
+	if ((a->ch_flow_control[ch] & N_RX_FLOW_CONTROL_MASK) == 0) {
+		a->ch_flow_control[ch] |= (N_CH_XOFF | flag);
+		a->ch_flow_plci[ch] = plci->Id;
+		a->ch_flow_control_pending++;
+	}
+}
+
+static void channel_request_xon(PLCI *plci, byte ch) {
+	DIVA_CAPI_ADAPTER *a = plci->adapter;
+
+	if (a->ch_flow_control[ch] & N_CH_XOFF) {
+		a->ch_flow_control[ch] |= N_XON_REQ;
+		a->ch_flow_control[ch] &= ~N_CH_XOFF;
+		a->ch_flow_control[ch] &= ~N_XON_CONNECT_IND;
+	}
+}
+
+static void channel_xmit_extended_xon(PLCI *plci) {
+	DIVA_CAPI_ADAPTER *a;
+	int max_ch = ARRAY_SIZE(a->ch_flow_control);
+	int i, one_requested = 0;
+
+	if ((!plci) || (!plci->Id) || ((a = plci->adapter) == NULL)) {
+		return;
+	}
+
+	for (i = 0; i < max_ch; i++) {
+		if ((a->ch_flow_control[i] & N_CH_XOFF) &&
+		    (a->ch_flow_control[i] & N_XON_CONNECT_IND) &&
+		    (plci->Id == a->ch_flow_plci[i])) {
+			channel_request_xon(plci, (byte)i);
+			one_requested = 1;
+		}
+	}
+
+	if (one_requested) {
+		channel_xmit_xon(plci);
+	}
 }
 
 /*
   Try to xmit next X_ON
-  */
-static int find_channel_with_pending_x_on (DIVA_CAPI_ADAPTER   * a, PLCI   * plci) {
-  int max_ch = ARRAY_SIZE(a->ch_flow_control);
-  int i;
-
-  if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) {
-    return (0);
-  }
-
-  if (a->last_flow_control_ch >= max_ch) {
-    a->last_flow_control_ch = 1;
-  }
-  for (i=a->last_flow_control_ch; i < max_ch; i++) {
-    if ((a->ch_flow_control[i] & N_XON_REQ) &&
-        (plci->Id == a->ch_flow_plci[i])) {
-      a->last_flow_control_ch = i+1;
-      return (i);
-    }
-  }
-
-  for (i = 1; i < a->last_flow_control_ch; i++) {
-    if ((a->ch_flow_control[i] & N_XON_REQ) &&
-        (plci->Id == a->ch_flow_plci[i])) {
-      a->last_flow_control_ch = i+1;
-      return (i);
-    }
-  }
-
-  return (0);
-}
-
-static void channel_xmit_xon (PLCI   * plci) {
-  DIVA_CAPI_ADAPTER   * a = plci->adapter;
-  byte ch;
-
-  if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) {
-    return;
-  }
-  if ((ch = (byte)find_channel_with_pending_x_on (a, plci)) == 0) {
-    return;
-  }
-  a->ch_flow_control[ch] &= ~N_XON_REQ;
-  a->ch_flow_control[ch] |= N_XON_SENT;
-
-  plci->NL.Req = plci->nl_req = (byte)N_XON;
-  plci->NL.ReqCh         = ch;
-  plci->NL.X             = plci->NData;
-  plci->NL.XNum          = 1;
-  plci->NData[0].P       = &plci->RBuffer[0];
-  plci->NData[0].PLength = 0;
-
-  plci->adapter->request(&plci->NL);
-}
-
-static int channel_can_xon (PLCI   * plci, byte ch) {
-  APPL   * APPLptr;
-  DIVA_CAPI_ADAPTER   * a;
-  word NCCIcode;
-  dword count;
-  word Num;
-  word i;
-
-  APPLptr = plci->appl;
-  a = plci->adapter;
-
-  if (!APPLptr)
-    return (0);
-
-  NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8);
-
-                /* count all buffers within the Application pool    */
-                /* belonging to the same NCCI. XON if a first is    */
-                /* used.                                            */
-  count = 0;
-  Num = 0xffff;
-  for(i=0; i<APPLptr->MaxBuffer; i++) {
-    if(NCCIcode==APPLptr->DataNCCI[i]) count++;
-    if(!APPLptr->DataNCCI[i] && Num==0xffff) Num = i;
-  }
-  if ((count > 2) || (Num == 0xffff)) {
-    return (0);
-  }
-  return (1);
+*/
+static int find_channel_with_pending_x_on(DIVA_CAPI_ADAPTER *a, PLCI *plci) {
+	int max_ch = ARRAY_SIZE(a->ch_flow_control);
+	int i;
+
+	if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) {
+		return (0);
+	}
+
+	if (a->last_flow_control_ch >= max_ch) {
+		a->last_flow_control_ch = 1;
+	}
+	for (i = a->last_flow_control_ch; i < max_ch; i++) {
+		if ((a->ch_flow_control[i] & N_XON_REQ) &&
+		    (plci->Id == a->ch_flow_plci[i])) {
+			a->last_flow_control_ch = i + 1;
+			return (i);
+		}
+	}
+
+	for (i = 1; i < a->last_flow_control_ch; i++) {
+		if ((a->ch_flow_control[i] & N_XON_REQ) &&
+		    (plci->Id == a->ch_flow_plci[i])) {
+			a->last_flow_control_ch = i + 1;
+			return (i);
+		}
+	}
+
+	return (0);
+}
+
+static void channel_xmit_xon(PLCI *plci) {
+	DIVA_CAPI_ADAPTER *a = plci->adapter;
+	byte ch;
+
+	if (plci->nl_req || !plci->NL.Id || plci->nl_remove_id) {
+		return;
+	}
+	if ((ch = (byte)find_channel_with_pending_x_on(a, plci)) == 0) {
+		return;
+	}
+	a->ch_flow_control[ch] &= ~N_XON_REQ;
+	a->ch_flow_control[ch] |= N_XON_SENT;
+
+	plci->NL.Req = plci->nl_req = (byte)N_XON;
+	plci->NL.ReqCh         = ch;
+	plci->NL.X             = plci->NData;
+	plci->NL.XNum          = 1;
+	plci->NData[0].P       = &plci->RBuffer[0];
+	plci->NData[0].PLength = 0;
+
+	plci->adapter->request(&plci->NL);
+}
+
+static int channel_can_xon(PLCI *plci, byte ch) {
+	APPL *APPLptr;
+	DIVA_CAPI_ADAPTER *a;
+	word NCCIcode;
+	dword count;
+	word Num;
+	word i;
+
+	APPLptr = plci->appl;
+	a = plci->adapter;
+
+	if (!APPLptr)
+		return (0);
+
+	NCCIcode = a->ch_ncci[ch] | (((word) a->Id) << 8);
+
+	/* count all buffers within the Application pool    */
+	/* belonging to the same NCCI. XON if a first is    */
+	/* used.                                            */
+	count = 0;
+	Num = 0xffff;
+	for (i = 0; i < APPLptr->MaxBuffer; i++) {
+		if (NCCIcode == APPLptr->DataNCCI[i]) count++;
+		if (!APPLptr->DataNCCI[i] && Num == 0xffff) Num = i;
+	}
+	if ((count > 2) || (Num == 0xffff)) {
+		return (0);
+	}
+	return (1);
 }
 
 
 /*------------------------------------------------------------------*/
 
-static word CPN_filter_ok(byte   *cpn,DIVA_CAPI_ADAPTER   * a,word offset)
+static word CPN_filter_ok(byte *cpn, DIVA_CAPI_ADAPTER *a, word offset)
 {
-  return 1;
+	return 1;
 }
 
 
@@ -14733,116 +14733,116 @@ static word CPN_filter_ok(byte   *cpn,DIVA_CAPI_ADAPTER   * a,word offset)
 /* function must be enabled by setting "a->group_optimization_enabled" from the   */
 /* OS specific part (per adapter).                                                */
 /**********************************************************************************/
-static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci)
-{
-  word i,j,k,busy,group_found;
-  dword info_mask_group[MAX_CIP_TYPES];
-  dword cip_mask_group[MAX_CIP_TYPES];
-  word appl_number_group_type[MAX_APPL];
-  PLCI   *auxplci;
-
-  set_group_ind_mask (plci); /* all APPLs within this inc. call are allowed to dial in */
-
-  if(!a->group_optimization_enabled)
-  {
-    dbug(1,dprintf("No group optimization"));
-    return;
-  }
-
-  dbug(1,dprintf("Group optimization = 0x%x...", a->group_optimization_enabled));
-
-  for(i=0;i<MAX_CIP_TYPES;i++)
-  {
-    info_mask_group[i] = 0;
-    cip_mask_group [i] = 0;
-  }
-  for(i=0;i<MAX_APPL;i++)
-  {
-    appl_number_group_type[i] = 0;
-  }
-  for(i=0; i<max_appl; i++) /* check if any multi instance capable application is present */
-  {  /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */
-    if(application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i])  && (a->group_optimization_enabled ==1) )
-    {
-      dbug(1,dprintf("Multi-Instance capable, no optimization required"));
-      return; /* allow good application unfiltered access */
-    }
-  }
-  for(i=0; i<max_appl; i++) /* Build CIP Groups */
-  {
-    if(application[i].Id && a->CIP_Mask[i] )
-    {
-      for(k=0,busy=false; k<a->max_plci; k++)
-      {
-        if(a->plci[k].Id) 
-        {
-          auxplci = &a->plci[k];
-          if(auxplci->appl == &application[i]) /* application has a busy PLCI */
-          {
-            busy = true;
-            dbug(1,dprintf("Appl 0x%x is busy",i+1));
-          }
-          else if(test_c_ind_mask_bit (auxplci, i)) /* application has an incoming call pending */
-          {
-            busy = true;
-            dbug(1,dprintf("Appl 0x%x has inc. call pending",i+1));
-          }
-        }
-      }
-
-      for(j=0,group_found=0; j<=(MAX_CIP_TYPES) && !busy &&!group_found; j++)     /* build groups with free applications only */
-      {
-        if(j==MAX_CIP_TYPES)       /* all groups are in use but group still not found */
-        {                           /* the MAX_CIP_TYPES group enables all calls because of field overflow */
-          appl_number_group_type[i] = MAX_CIP_TYPES;
-          group_found=true;
-          dbug(1,dprintf("Field overflow appl 0x%x",i+1));
-        }
-        else if( (info_mask_group[j]==a->CIP_Mask[i]) && (cip_mask_group[j]==a->Info_Mask[i]) )  
-        {                                      /* is group already present ?                  */
-          appl_number_group_type[i] = j|0x80;  /* store the group number for each application */
-          group_found=true;
-          dbug(1,dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx",appl_number_group_type[i],i+1,info_mask_group[j]));
-        }
-        else if(!info_mask_group[j])
-        {                                      /* establish a new group                       */
-          appl_number_group_type[i] = j|0x80;  /* store the group number for each application */
-          info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group    */
-          cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group  */
-          group_found=true;
-          dbug(1,dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx",appl_number_group_type[i],i+1,info_mask_group[j]));
-        }
-      }
-    }
-  }
-        
-  for(i=0; i<max_appl; i++) /* Build group_optimization_mask_table */
-  {
-    if(appl_number_group_type[i]) /* application is free, has listens and is member of a group */
-    {
-      if(appl_number_group_type[i] == MAX_CIP_TYPES)
-      {
-        dbug(1,dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled",appl_number_group_type[i],i+1));
-      }
-      else
-      {
-        dbug(1,dprintf("Group 0x%x, valid appl = 0x%x",appl_number_group_type[i],i+1));
-        for(j=i+1; j<max_appl; j++)   /* search other group members and mark them as busy        */
-        {
-          if(appl_number_group_type[i] == appl_number_group_type[j]) 
-          {
-            dbug(1,dprintf("Appl 0x%x is member of group 0x%x, no call",j+1,appl_number_group_type[j]));
-            clear_group_ind_mask_bit (plci, j);           /* disable call on other group members */
-            appl_number_group_type[j] = 0;       /* remove disabled group member from group list */
-          }
-        }
-      }
-    }
-    else                                                 /* application should not get a call */
-    {
-      clear_group_ind_mask_bit (plci, i);
-    }
-  }
+static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
+{
+	word i, j, k, busy, group_found;
+	dword info_mask_group[MAX_CIP_TYPES];
+	dword cip_mask_group[MAX_CIP_TYPES];
+	word appl_number_group_type[MAX_APPL];
+	PLCI *auxplci;
+
+	set_group_ind_mask(plci); /* all APPLs within this inc. call are allowed to dial in */
+
+	if (!a->group_optimization_enabled)
+	{
+		dbug(1, dprintf("No group optimization"));
+		return;
+	}
+
+	dbug(1, dprintf("Group optimization = 0x%x...", a->group_optimization_enabled));
+
+	for (i = 0; i < MAX_CIP_TYPES; i++)
+	{
+		info_mask_group[i] = 0;
+		cip_mask_group[i] = 0;
+	}
+	for (i = 0; i < MAX_APPL; i++)
+	{
+		appl_number_group_type[i] = 0;
+	}
+	for (i = 0; i < max_appl; i++) /* check if any multi instance capable application is present */
+	{  /* group_optimization set to 1 means not to optimize multi-instance capable applications (default) */
+		if (application[i].Id && (application[i].MaxNCCI) > 1 && (a->CIP_Mask[i]) && (a->group_optimization_enabled == 1))
+		{
+			dbug(1, dprintf("Multi-Instance capable, no optimization required"));
+			return; /* allow good application unfiltered access */
+		}
+	}
+	for (i = 0; i < max_appl; i++) /* Build CIP Groups */
+	{
+		if (application[i].Id && a->CIP_Mask[i])
+		{
+			for (k = 0, busy = false; k < a->max_plci; k++)
+			{
+				if (a->plci[k].Id)
+				{
+					auxplci = &a->plci[k];
+					if (auxplci->appl == &application[i]) /* application has a busy PLCI */
+					{
+						busy = true;
+						dbug(1, dprintf("Appl 0x%x is busy", i + 1));
+					}
+					else if (test_c_ind_mask_bit(auxplci, i)) /* application has an incoming call pending */
+					{
+						busy = true;
+						dbug(1, dprintf("Appl 0x%x has inc. call pending", i + 1));
+					}
+				}
+			}
+
+			for (j = 0, group_found = 0; j <= (MAX_CIP_TYPES) && !busy && !group_found; j++)     /* build groups with free applications only */
+			{
+				if (j == MAX_CIP_TYPES)       /* all groups are in use but group still not found */
+				{                           /* the MAX_CIP_TYPES group enables all calls because of field overflow */
+					appl_number_group_type[i] = MAX_CIP_TYPES;
+					group_found = true;
+					dbug(1, dprintf("Field overflow appl 0x%x", i + 1));
+				}
+				else if ((info_mask_group[j] == a->CIP_Mask[i]) && (cip_mask_group[j] == a->Info_Mask[i]))
+				{                                      /* is group already present ?                  */
+					appl_number_group_type[i] = j | 0x80;  /* store the group number for each application */
+					group_found = true;
+					dbug(1, dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j]));
+				}
+				else if (!info_mask_group[j])
+				{                                      /* establish a new group                       */
+					appl_number_group_type[i] = j | 0x80;  /* store the group number for each application */
+					info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group    */
+					cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group  */
+					group_found = true;
+					dbug(1, dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx", appl_number_group_type[i], i + 1, info_mask_group[j]));
+				}
+			}
+		}
+	}
+
+	for (i = 0; i < max_appl; i++) /* Build group_optimization_mask_table */
+	{
+		if (appl_number_group_type[i]) /* application is free, has listens and is member of a group */
+		{
+			if (appl_number_group_type[i] == MAX_CIP_TYPES)
+			{
+				dbug(1, dprintf("OverflowGroup 0x%x, valid appl = 0x%x, call enabled", appl_number_group_type[i], i + 1));
+			}
+			else
+			{
+				dbug(1, dprintf("Group 0x%x, valid appl = 0x%x", appl_number_group_type[i], i + 1));
+				for (j = i + 1; j < max_appl; j++)   /* search other group members and mark them as busy        */
+				{
+					if (appl_number_group_type[i] == appl_number_group_type[j])
+					{
+						dbug(1, dprintf("Appl 0x%x is member of group 0x%x, no call", j + 1, appl_number_group_type[j]));
+						clear_group_ind_mask_bit(plci, j);           /* disable call on other group members */
+						appl_number_group_type[j] = 0;       /* remove disabled group member from group list */
+					}
+				}
+			}
+		}
+		else                                                 /* application should not get a call */
+		{
+			clear_group_ind_mask_bit(plci, i);
+		}
+	}
 
 }
 
@@ -14851,201 +14851,201 @@ static void group_optimization(DIVA_CAPI_ADAPTER   * a, PLCI   * plci)
 /* OS notifies the driver about a application Capi_Register */
 word CapiRegister(word id)
 {
-  word i,j,appls_found;
-
-  PLCI   *plci;
-  DIVA_CAPI_ADAPTER   *a;
-
-  for(i=0,appls_found=0; i<max_appl; i++)
-  {
-    if( application[i].Id && (application[i].Id!=id) )
-    {
-      appls_found++;                       /* an application has been found */
-    }
-  }
-
-  if(appls_found) return true;
-  for(i=0; i<max_adapter; i++)                   /* scan all adapters...    */
-  {
-    a = &adapter[i];
-    if(a->request)
-    {
-      if(a->flag_dynamic_l1_down)  /* remove adapter from L1 tristate (Huntgroup) */
-      {
-        if(!appls_found)           /* first application does a capi register   */
-        {
-          if((j=get_plci(a)))                    /* activate L1 of all adapters */
-          {
-            plci = &a->plci[j-1];
-            plci->command = 0;
-            add_p(plci,OAD,"\x01\xfd");
-            add_p(plci,CAI,"\x01\x80");
-            add_p(plci,UID,"\x06\x43\x61\x70\x69\x32\x30");
-            add_p(plci,SHIFT|6,NULL);
-            add_p(plci,SIN,"\x02\x00\x00");
-            plci->internal_command = START_L1_SIG_ASSIGN_PEND;
-            sig_req(plci,ASSIGN,DSIG_ID);
-            add_p(plci,FTY,"\x02\xff\x07"); /* l1 start */
-            sig_req(plci,SIG_CTRL,0);
-            send_req(plci);
-          }
-        }
-      }
-    }
-  }
-  return false;
+	word i, j, appls_found;
+
+	PLCI *plci;
+	DIVA_CAPI_ADAPTER *a;
+
+	for (i = 0, appls_found = 0; i < max_appl; i++)
+	{
+		if (application[i].Id && (application[i].Id != id))
+		{
+			appls_found++;                       /* an application has been found */
+		}
+	}
+
+	if (appls_found) return true;
+	for (i = 0; i < max_adapter; i++)                   /* scan all adapters...    */
+	{
+		a = &adapter[i];
+		if (a->request)
+		{
+			if (a->flag_dynamic_l1_down)  /* remove adapter from L1 tristate (Huntgroup) */
+			{
+				if (!appls_found)           /* first application does a capi register   */
+				{
+					if ((j = get_plci(a)))                    /* activate L1 of all adapters */
+					{
+						plci = &a->plci[j - 1];
+						plci->command = 0;
+						add_p(plci, OAD, "\x01\xfd");
+						add_p(plci, CAI, "\x01\x80");
+						add_p(plci, UID, "\x06\x43\x61\x70\x69\x32\x30");
+						add_p(plci, SHIFT | 6, NULL);
+						add_p(plci, SIN, "\x02\x00\x00");
+						plci->internal_command = START_L1_SIG_ASSIGN_PEND;
+						sig_req(plci, ASSIGN, DSIG_ID);
+						add_p(plci, FTY, "\x02\xff\x07"); /* l1 start */
+						sig_req(plci, SIG_CTRL, 0);
+						send_req(plci);
+					}
+				}
+			}
+		}
+	}
+	return false;
 }
 
 /*------------------------------------------------------------------*/
 
 /* Functions for virtual Switching e.g. Transfer by join, Conference */
 
-static void VSwitchReqInd(PLCI   *plci, dword Id, byte   **parms)
-{
- word i;
- /* Format of vswitch_t:
- 0 byte length
- 1 byte VSWITCHIE
- 2 byte VSWITCH_REQ/VSWITCH_IND
- 3 byte reserved
- 4 word VSwitchcommand
- 6 word returnerror
- 8... Params
- */
- if(!plci ||
-  !plci->appl ||
-  !plci->State ||
-  plci->Sig.Ind==NCR_FACILITY
-  )
-  return;
- 
- for(i=0;i<MAX_MULTI_IE;i++)
- {
-        if(!parms[i][0]) continue;
-  if(parms[i][0]<7)
-  {
-   parms[i][0]=0; /* kill it */
-   continue;
-  }
-  dbug(1,dprintf("VSwitchReqInd(%d)",parms[i][4]));
-  switch(parms[i][4])
-  {
-  case VSJOIN:
-   if(!plci->relatedPTYPLCI ||
-    (plci->ptyState!=S_ECT && plci->relatedPTYPLCI->ptyState!=S_ECT))
-   { /* Error */
-    break;
-   }
-   /* remember all necessary informations */
-   if(parms[i][0]!=11 || parms[i][8]!=3) /* Length Test */
-   {
-    break;
-   }
-   if(parms[i][2]==VSWITCH_IND && parms[i][9]==1)
-   {   /* first indication after ECT-Request on Consultation Call */
-    plci->vswitchstate=parms[i][9];
-    parms[i][9]=2; /* State */
-    /* now ask first Call to join */
-   }
-   else if(parms[i][2]==VSWITCH_REQ && parms[i][9]==3)
-   { /* Answer of VSWITCH_REQ from first Call */
-    plci->vswitchstate=parms[i][9];
-    /* tell consultation call to join
-    and the protocol capabilities of the first call */
-   }
-   else
-   { /* Error */
-    break;
-   }    
-   plci->vsprot=parms[i][10]; /* protocol */
-   plci->vsprotdialect=parms[i][11]; /* protocoldialect */
-   /* send join request to related PLCI */
-   parms[i][1]=VSWITCHIE;
-   parms[i][2]=VSWITCH_REQ;
-   
-   plci->relatedPTYPLCI->command = 0;
-   plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND;
-   add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]);
-   sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0);
-   send_req(plci->relatedPTYPLCI);
-   break;
-  case VSTRANSPORT:
-  default:
-   if(plci->relatedPTYPLCI &&
-    plci->vswitchstate==3 &&
-    plci->relatedPTYPLCI->vswitchstate==3)
-   {
-    add_p(plci->relatedPTYPLCI,ESC,&parms[i][0]);
-    sig_req(plci->relatedPTYPLCI,VSWITCH_REQ,0);
-    send_req(plci->relatedPTYPLCI);
-   }
-   break;
-  }  
-  parms[i][0]=0; /* kill it */
- }
+static void VSwitchReqInd(PLCI *plci, dword Id, byte **parms)
+{
+	word i;
+	/* Format of vswitch_t:
+	   0 byte length
+	   1 byte VSWITCHIE
+	   2 byte VSWITCH_REQ/VSWITCH_IND
+	   3 byte reserved
+	   4 word VSwitchcommand
+	   6 word returnerror
+	   8... Params
+	*/
+	if (!plci ||
+	    !plci->appl ||
+	    !plci->State ||
+	    plci->Sig.Ind == NCR_FACILITY
+		)
+		return;
+
+	for (i = 0; i < MAX_MULTI_IE; i++)
+	{
+		if (!parms[i][0]) continue;
+		if (parms[i][0] < 7)
+		{
+			parms[i][0] = 0; /* kill it */
+			continue;
+		}
+		dbug(1, dprintf("VSwitchReqInd(%d)", parms[i][4]));
+		switch (parms[i][4])
+		{
+		case VSJOIN:
+			if (!plci->relatedPTYPLCI ||
+			    (plci->ptyState != S_ECT && plci->relatedPTYPLCI->ptyState != S_ECT))
+			{ /* Error */
+				break;
+			}
+			/* remember all necessary informations */
+			if (parms[i][0] != 11 || parms[i][8] != 3) /* Length Test */
+			{
+				break;
+			}
+			if (parms[i][2] == VSWITCH_IND && parms[i][9] == 1)
+			{   /* first indication after ECT-Request on Consultation Call */
+				plci->vswitchstate = parms[i][9];
+				parms[i][9] = 2; /* State */
+				/* now ask first Call to join */
+			}
+			else if (parms[i][2] == VSWITCH_REQ && parms[i][9] == 3)
+			{ /* Answer of VSWITCH_REQ from first Call */
+				plci->vswitchstate = parms[i][9];
+				/* tell consultation call to join
+				   and the protocol capabilities of the first call */
+			}
+			else
+			{ /* Error */
+				break;
+			}
+			plci->vsprot = parms[i][10]; /* protocol */
+			plci->vsprotdialect = parms[i][11]; /* protocoldialect */
+			/* send join request to related PLCI */
+			parms[i][1] = VSWITCHIE;
+			parms[i][2] = VSWITCH_REQ;
+
+			plci->relatedPTYPLCI->command = 0;
+			plci->relatedPTYPLCI->internal_command = VSWITCH_REQ_PEND;
+			add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]);
+			sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
+			send_req(plci->relatedPTYPLCI);
+			break;
+		case VSTRANSPORT:
+		default:
+			if (plci->relatedPTYPLCI &&
+			    plci->vswitchstate == 3 &&
+			    plci->relatedPTYPLCI->vswitchstate == 3)
+			{
+				add_p(plci->relatedPTYPLCI, ESC, &parms[i][0]);
+				sig_req(plci->relatedPTYPLCI, VSWITCH_REQ, 0);
+				send_req(plci->relatedPTYPLCI);
+			}
+			break;
+		}
+		parms[i][0] = 0; /* kill it */
+	}
 }
 
 
 /*------------------------------------------------------------------*/
 
-static int diva_get_dma_descriptor (PLCI   *plci, dword   *dma_magic) {
-  ENTITY e;
-  IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;
-
-  if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) {
-    return (-1);
-  }
-
-  pReq->xdi_dma_descriptor_operation.Req = 0;
-  pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
-
-  pReq->xdi_dma_descriptor_operation.info.operation =     IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
-
-  e.user[0] = plci->adapter->Id - 1;
-  plci->adapter->request((ENTITY*)pReq);
-
-  if (!pReq->xdi_dma_descriptor_operation.info.operation &&
-      (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
-      pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
-    *dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
-    dbug(3,dprintf("dma_alloc, a:%d (%d-%08x)",
-         plci->adapter->Id,
-         pReq->xdi_dma_descriptor_operation.info.descriptor_number,
-         *dma_magic));
-    return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
-  } else {
-    dbug(1,dprintf("dma_alloc failed"));
-    return (-1);
-  }
-}
-
-static void diva_free_dma_descriptor (PLCI   *plci, int nr) {
-  ENTITY e;
-  IDI_SYNC_REQ* pReq = (IDI_SYNC_REQ*)&e;
-
-  if (nr < 0) {
-    return;
-  }
-
-  pReq->xdi_dma_descriptor_operation.Req = 0;
-  pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
-
-  pReq->xdi_dma_descriptor_operation.info.operation =                                                IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
-  pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
-
-  e.user[0] = plci->adapter->Id - 1;
-  plci->adapter->request((ENTITY*)pReq);
-
-  if (!pReq->xdi_dma_descriptor_operation.info.operation) {
-    dbug(1,dprintf("dma_free(%d)", nr));
-  } else {
-    dbug(1,dprintf("dma_free failed (%d)", nr));
-  }
+static int diva_get_dma_descriptor(PLCI *plci, dword   *dma_magic) {
+	ENTITY e;
+	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
+
+	if (!(diva_xdi_extended_features & DIVA_CAPI_XDI_PROVIDES_RX_DMA)) {
+		return (-1);
+	}
+
+	pReq->xdi_dma_descriptor_operation.Req = 0;
+	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
+
+	pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_ALLOC;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = -1;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
+
+	e.user[0] = plci->adapter->Id - 1;
+	plci->adapter->request((ENTITY *)pReq);
+
+	if (!pReq->xdi_dma_descriptor_operation.info.operation &&
+	    (pReq->xdi_dma_descriptor_operation.info.descriptor_number >= 0) &&
+	    pReq->xdi_dma_descriptor_operation.info.descriptor_magic) {
+		*dma_magic = pReq->xdi_dma_descriptor_operation.info.descriptor_magic;
+		dbug(3, dprintf("dma_alloc, a:%d (%d-%08x)",
+				plci->adapter->Id,
+				pReq->xdi_dma_descriptor_operation.info.descriptor_number,
+				*dma_magic));
+		return (pReq->xdi_dma_descriptor_operation.info.descriptor_number);
+	} else {
+		dbug(1, dprintf("dma_alloc failed"));
+		return (-1);
+	}
+}
+
+static void diva_free_dma_descriptor(PLCI *plci, int nr) {
+	ENTITY e;
+	IDI_SYNC_REQ *pReq = (IDI_SYNC_REQ *)&e;
+
+	if (nr < 0) {
+		return;
+	}
+
+	pReq->xdi_dma_descriptor_operation.Req = 0;
+	pReq->xdi_dma_descriptor_operation.Rc = IDI_SYNC_REQ_DMA_DESCRIPTOR_OPERATION;
+
+	pReq->xdi_dma_descriptor_operation.info.operation = IDI_SYNC_REQ_DMA_DESCRIPTOR_FREE;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_number  = nr;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_address = NULL;
+	pReq->xdi_dma_descriptor_operation.info.descriptor_magic   = 0;
+
+	e.user[0] = plci->adapter->Id - 1;
+	plci->adapter->request((ENTITY *)pReq);
+
+	if (!pReq->xdi_dma_descriptor_operation.info.operation) {
+		dbug(1, dprintf("dma_free(%d)", nr));
+	} else {
+		dbug(1, dprintf("dma_free failed (%d)", nr));
+	}
 }
 
 /*------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/mi_pc.h b/drivers/isdn/hardware/eicon/mi_pc.h
index a861dac..83e9ed8 100644
--- a/drivers/isdn/hardware/eicon/mi_pc.h
+++ b/drivers/isdn/hardware/eicon/mi_pc.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 /*----------------------------------------------------------------------------
@@ -68,30 +68,30 @@
 /* CPU exception context structure in MP shared ram after trap */
 typedef struct mp_xcptcontext_s MP_XCPTC;
 struct mp_xcptcontext_s {
-    dword       sr;
-    dword       cr;
-    dword       epc;
-    dword       vaddr;
-    dword       regs[32];
-    dword       mdlo;
-    dword       mdhi;
-    dword       reseverd;
-    dword       xclass;
+	dword       sr;
+	dword       cr;
+	dword       epc;
+	dword       vaddr;
+	dword       regs[32];
+	dword       mdlo;
+	dword       mdhi;
+	dword       reseverd;
+	dword       xclass;
 };
 /* boot interface structure for PRI */
 struct mp_load {
-  dword     volatile cmd;
-  dword     volatile addr;
-  dword     volatile len;
-  dword     volatile err;
-  dword     volatile live;
-  dword     volatile res1[0x1b];
-  dword     volatile TrapId;    /* has value 0x999999XX on a CPU trap */
-  dword     volatile res2[0x03];
-  MP_XCPTC  volatile xcpt;      /* contains register dump */
-  dword     volatile rest[((0x1020>>2)-6) - 0x1b - 1 - 0x03 - (sizeof(MP_XCPTC)>>2)];
-  dword     volatile signature;
-  dword data[60000]; /* real interface description */
+	dword     volatile cmd;
+	dword     volatile addr;
+	dword     volatile len;
+	dword     volatile err;
+	dword     volatile live;
+	dword     volatile res1[0x1b];
+	dword     volatile TrapId;    /* has value 0x999999XX on a CPU trap */
+	dword     volatile res2[0x03];
+	MP_XCPTC  volatile xcpt;      /* contains register dump */
+	dword     volatile rest[((0x1020 >> 2) - 6) - 0x1b - 1 - 0x03 - (sizeof(MP_XCPTC) >> 2)];
+	dword     volatile signature;
+	dword data[60000]; /* real interface description */
 };
 /*----------------------------------------------------------------------------*/
 /* SERVER 4BRI (Quattro PCI)                                                  */
@@ -150,11 +150,11 @@ struct mp_load {
 #define CS_BASEREG    0x0018
 #define BOOT_BASEREG  0x001c
 #define GTREGS_BASEREG 0x0024   /*GTRegsBase reg-contain the base addr where*/
-                                /*the GT64010 internal regs where mapped    */
+				/*the GT64010 internal regs where mapped    */
 /*
  *  GT64010 internal registers
  */
-        /* DRAM device coding  */
+/* DRAM device coding  */
 #define LOW_RAS0_DREG 0x0400    /*Ras0 low decode address*/
 #define HI_RAS0_DREG  0x0404    /*Ras0 high decode address*/
 #define LOW_RAS1_DREG 0x0408    /*Ras1 low decode address*/
@@ -163,7 +163,7 @@ struct mp_load {
 #define HI_RAS2_DREG  0x0414    /*Ras2 high decode address*/
 #define LOW_RAS3_DREG 0x0418    /*Ras3 low decode address*/
 #define HI_RAS3_DREG  0x041c    /*Ras3 high decode address*/
-        /* I/O CS device coding  */
+/* I/O CS device coding  */
 #define LOW_CS0_DREG  0x0420 /* CS0* low decode register */
 #define HI_CS0_DREG   0x0424 /* CS0* high decode register */
 #define LOW_CS1_DREG  0x0428 /* CS1* low decode register */
@@ -172,20 +172,20 @@ struct mp_load {
 #define HI_CS2_DREG   0x0434 /* CS2* high decode register */
 #define LOW_CS3_DREG  0x0438 /* CS3* low decode register */
 #define HI_CS3_DREG   0x043c /* CS3* high decode register */
-        /* Boot PROM device coding */
+/* Boot PROM device coding */
 #define LOW_BOOTCS_DREG 0x0440 /* Boot CS low decode register */
 #define HI_BOOTCS_DREG 0x0444 /* Boot CS High decode register */
-        /* DRAM group coding (for CPU)  */
+/* DRAM group coding (for CPU)  */
 #define LO_RAS10_GREG 0x0008    /*Ras1..0 group low decode address*/
 #define HI_RAS10_GREG 0x0010    /*Ras1..0 group high decode address*/
 #define LO_RAS32_GREG 0x0018    /*Ras3..2 group low decode address  */
 #define HI_RAS32_GREG 0x0020    /*Ras3..2 group high decode address  */
-        /* I/O CS group coding for (CPU)  */
+/* I/O CS group coding for (CPU)  */
 #define LO_CS20_GREG  0x0028 /* CS2..0 group low decode register */
 #define HI_CS20_GREG  0x0030 /* CS2..0 group high decode register */
 #define LO_CS3B_GREG  0x0038 /* CS3 & PROM group low decode register */
 #define HI_CS3B_GREG  0x0040 /* CS3 & PROM group high decode register */
-        /* Galileo specific PCI config. */
+/* Galileo specific PCI config. */
 #define PCI_TIMEOUT_RET 0x0c04 /* Time Out and retry register */
 #define RAS10_BANKSIZE 0x0c08 /* RAS 1..0 group PCI bank size */
 #define RAS32_BANKSIZE 0x0c0c /* RAS 3..2 group PCI bank size */
diff --git a/drivers/isdn/hardware/eicon/mntfunc.c b/drivers/isdn/hardware/eicon/mntfunc.c
index a564b75..d607260 100644
--- a/drivers/isdn/hardware/eicon/mntfunc.c
+++ b/drivers/isdn/hardware/eicon/mntfunc.c
@@ -27,7 +27,7 @@ static dword notify_handle;
 static DESCRIPTOR DAdapter;
 static DESCRIPTOR MAdapter;
 static DESCRIPTOR MaintDescriptor =
-    { IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp };
+{ IDI_DIMAINT, 0, 0, (IDI_CALL) diva_maint_prtComp };
 
 extern int diva_os_copy_to_user(void *os_handle, void __user *dst,
 				const void *src, int length);
@@ -44,7 +44,7 @@ static void no_printf(unsigned char *x, ...)
 /*
  *  DIDD callback function
  */
-static void *didd_callback(void *context, DESCRIPTOR * adapter,
+static void *didd_callback(void *context, DESCRIPTOR *adapter,
 			   int removal)
 {
 	if (adapter->type == IDI_DADAPTER) {
@@ -87,20 +87,20 @@ static int DIVA_INIT_FUNCTION connect_didd(void)
 			memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
 			req.didd_notify.e.Req = 0;
 			req.didd_notify.e.Rc =
-			    IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
+				IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
 			req.didd_notify.info.callback = (void *)didd_callback;
 			req.didd_notify.info.context = NULL;
-			DAdapter.request((ENTITY *) & req);
+			DAdapter.request((ENTITY *)&req);
 			if (req.didd_notify.e.Rc != 0xff)
 				return (0);
 			notify_handle = req.didd_notify.info.handle;
 			/* Register MAINT (me) */
 			req.didd_add_adapter.e.Req = 0;
 			req.didd_add_adapter.e.Rc =
-			    IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
+				IDI_SYNC_REQ_DIDD_ADD_ADAPTER;
 			req.didd_add_adapter.info.descriptor =
-			    (void *) &MaintDescriptor;
-			DAdapter.request((ENTITY *) & req);
+				(void *) &MaintDescriptor;
+			DAdapter.request((ENTITY *)&req);
 			if (req.didd_add_adapter.e.Rc != 0xff)
 				return (0);
 		} else if ((DIDD_Table[x].type > 0)
@@ -121,13 +121,13 @@ static void DIVA_EXIT_FUNCTION disconnect_didd(void)
 	req.didd_notify.e.Req = 0;
 	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
 	req.didd_notify.info.handle = notify_handle;
-	DAdapter.request((ENTITY *) & req);
+	DAdapter.request((ENTITY *)&req);
 
 	req.didd_remove_adapter.e.Req = 0;
 	req.didd_remove_adapter.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER;
 	req.didd_remove_adapter.info.p_request =
-	    (IDI_CALL) MaintDescriptor.request;
-	DAdapter.request((ENTITY *) & req);
+		(IDI_CALL) MaintDescriptor.request;
+	DAdapter.request((ENTITY *)&req);
 }
 
 /*
@@ -147,9 +147,9 @@ int maint_read_write(void __user *buf, int count)
 		return (-EFAULT);
 	}
 
-	cmd = *(dword *) & data[0];	/* command */
-	id = *(dword *) & data[4];	/* driver id */
-	mask = *(dword *) & data[8];	/* mask or size */
+	cmd = *(dword *)&data[0];	/* command */
+	id = *(dword *)&data[4];	/* driver id */
+	mask = *(dword *)&data[8];	/* mask or size */
 
 	switch (cmd) {
 	case DITRACE_CMD_GET_DRIVER_INFO:
@@ -178,19 +178,19 @@ int maint_read_write(void __user *buf, int count)
 		}
 		break;
 
-    /*
-       Filter commands will ignore the ID due to fact that filtering affects
-       the B- channel and Audio Tap trace levels only. Also MAINT driver will
-       select the right trace ID by itself
-       */
+		/*
+		  Filter commands will ignore the ID due to fact that filtering affects
+		  the B- channel and Audio Tap trace levels only. Also MAINT driver will
+		  select the right trace ID by itself
+		*/
 	case DITRACE_WRITE_SELECTIVE_TRACE_FILTER:
 		if (!mask) {
-			ret = diva_set_trace_filter (1, "*");
+			ret = diva_set_trace_filter(1, "*");
 		} else if (mask < sizeof(data)) {
-			if (diva_os_copy_from_user(NULL, data, (char __user *)buf+12, mask)) {
+			if (diva_os_copy_from_user(NULL, data, (char __user *)buf + 12, mask)) {
 				ret = -EFAULT;
 			} else {
-				ret = diva_set_trace_filter ((int)mask, data);
+				ret = diva_set_trace_filter((int)mask, data);
 			}
 		} else {
 			ret = -EINVAL;
@@ -198,8 +198,8 @@ int maint_read_write(void __user *buf, int count)
 		break;
 
 	case DITRACE_READ_SELECTIVE_TRACE_FILTER:
-		if ((ret = diva_get_trace_filter (sizeof(data), data)) > 0) {
-			if (diva_os_copy_to_user (NULL, buf, data, ret))
+		if ((ret = diva_get_trace_filter(sizeof(data), data)) > 0) {
+			if (diva_os_copy_to_user(NULL, buf, data, ret))
 				ret = -EFAULT;
 		} else {
 			ret = -ENODEV;
@@ -207,88 +207,88 @@ int maint_read_write(void __user *buf, int count)
 		break;
 
 	case DITRACE_READ_TRACE_ENTRY:{
-			diva_os_spin_lock_magic_t old_irql;
-			word size;
-			diva_dbg_entry_head_t *pmsg;
-			byte *pbuf;
+		diva_os_spin_lock_magic_t old_irql;
+		word size;
+		diva_dbg_entry_head_t *pmsg;
+		byte *pbuf;
 
-			if (!(pbuf = diva_os_malloc(0, mask))) {
-				return (-ENOMEM);
-			}
+		if (!(pbuf = diva_os_malloc(0, mask))) {
+			return (-ENOMEM);
+		}
 
-			for(;;) {
-				if (!(pmsg =
-				    diva_maint_get_message(&size, &old_irql))) {
-					break;
-				}
-				if (size > mask) {
-					diva_maint_ack_message(0, &old_irql);
-					ret = -EINVAL;
-					break;
-				}
-				ret = size;
-				memcpy(pbuf, pmsg, size);
-				diva_maint_ack_message(1, &old_irql);
-				if ((count < size) ||
-				     diva_os_copy_to_user (NULL, buf, (void *) pbuf, size))
-							ret = -EFAULT;
+		for (;;) {
+			if (!(pmsg =
+			      diva_maint_get_message(&size, &old_irql))) {
+				break;
+			}
+			if (size > mask) {
+				diva_maint_ack_message(0, &old_irql);
+				ret = -EINVAL;
 				break;
 			}
-			diva_os_free(0, pbuf);
+			ret = size;
+			memcpy(pbuf, pmsg, size);
+			diva_maint_ack_message(1, &old_irql);
+			if ((count < size) ||
+			    diva_os_copy_to_user(NULL, buf, (void *) pbuf, size))
+				ret = -EFAULT;
+			break;
 		}
+		diva_os_free(0, pbuf);
+	}
 		break;
 
 	case DITRACE_READ_TRACE_ENTRYS:{
-			diva_os_spin_lock_magic_t old_irql;
-			word size;
-			diva_dbg_entry_head_t *pmsg;
-			byte *pbuf = NULL;
-			int written = 0;
+		diva_os_spin_lock_magic_t old_irql;
+		word size;
+		diva_dbg_entry_head_t *pmsg;
+		byte *pbuf = NULL;
+		int written = 0;
 
-			if (mask < 4096) {
-				ret = -EINVAL;
+		if (mask < 4096) {
+			ret = -EINVAL;
+			break;
+		}
+		if (!(pbuf = diva_os_malloc(0, mask))) {
+			return (-ENOMEM);
+		}
+
+		for (;;) {
+			if (!(pmsg =
+			      diva_maint_get_message(&size, &old_irql))) {
 				break;
 			}
-			if (!(pbuf = diva_os_malloc(0, mask))) {
-				return (-ENOMEM);
-			}
-
-			for (;;) {
-				if (!(pmsg =
-				     diva_maint_get_message(&size, &old_irql))) {
-					break;
-				}
-				if ((size + 8) > mask) {
-					diva_maint_ack_message(0, &old_irql);
-					break;
-				}
-				/*
-				   Write entry length
-				 */
-				pbuf[written++] = (byte) size;
-				pbuf[written++] = (byte) (size >> 8);
-				pbuf[written++] = 0;
-				pbuf[written++] = 0;
-				/*
-				   Write message
-				 */
-				memcpy(&pbuf[written], pmsg, size);
-				diva_maint_ack_message(1, &old_irql);
-				written += size;
-				mask -= (size + 4);
+			if ((size + 8) > mask) {
+				diva_maint_ack_message(0, &old_irql);
+				break;
 			}
+			/*
+			  Write entry length
+			*/
+			pbuf[written++] = (byte) size;
+			pbuf[written++] = (byte) (size >> 8);
 			pbuf[written++] = 0;
 			pbuf[written++] = 0;
-			pbuf[written++] = 0;
-			pbuf[written++] = 0;
+			/*
+			  Write message
+			*/
+			memcpy(&pbuf[written], pmsg, size);
+			diva_maint_ack_message(1, &old_irql);
+			written += size;
+			mask -= (size + 4);
+		}
+		pbuf[written++] = 0;
+		pbuf[written++] = 0;
+		pbuf[written++] = 0;
+		pbuf[written++] = 0;
 
-			if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) {
-				ret = -EFAULT;
-			} else {
-				ret = written;
-			}
-			diva_os_free(0, pbuf);
+		if ((count < written) || diva_os_copy_to_user(NULL, buf, (void *) pbuf, written)) {
+			ret = -EFAULT;
+		} else {
+			ret = written;
 		}
+		diva_os_free(0, pbuf);
+	}
 		break;
 
 	default:
@@ -316,7 +316,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer,
 	} else {
 		while ((*buffer_length >= (64 * 1024))
 		       &&
-		       (!(*buffer = diva_os_malloc (0, *buffer_length)))) {
+		       (!(*buffer = diva_os_malloc(0, *buffer_length)))) {
 			*buffer_length -= 1024;
 		}
 
@@ -328,7 +328,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer,
 
 	if (diva_maint_init(*buffer, *buffer_length, (diva_dbg_mem == 0))) {
 		if (!diva_dbg_mem) {
-			diva_os_free (0, *buffer);
+			diva_os_free(0, *buffer);
 		}
 		DBG_ERR(("init: maint init failed"));
 		return (0);
@@ -338,7 +338,7 @@ int DIVA_INIT_FUNCTION mntfunc_init(int *buffer_length, void **buffer,
 		DBG_ERR(("init: failed to connect to DIDD."));
 		diva_maint_finit();
 		if (!diva_dbg_mem) {
-			diva_os_free (0, *buffer);
+			diva_os_free(0, *buffer);
 		}
 		return (0);
 	}
@@ -362,7 +362,7 @@ void DIVA_EXIT_FUNCTION mntfunc_finit(void)
 	disconnect_didd();
 
 	if ((buffer = diva_maint_finit())) {
-		diva_os_free (0, buffer);
+		diva_os_free(0, buffer);
 	}
 
 	memset(&MAdapter, 0, sizeof(MAdapter));
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
index cb7616c..1891246 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ b/drivers/isdn/hardware/eicon/os_4bri.c
@@ -27,12 +27,12 @@ static dword diva_xdiLoadFileLength = 0;
 extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter);
 extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter);
 extern void diva_xdi_display_adapter_features(int card);
-extern void diva_add_slave_adapter(diva_os_xdi_adapter_t * a);
+extern void diva_add_slave_adapter(diva_os_xdi_adapter_t *a);
 
 extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
 extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);
 
-extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
+extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
 
 /*
 **  LOCALS
@@ -57,23 +57,23 @@ static unsigned long _4bri_v2_bri_bar_length[4] = {
 };
 
 
-static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a);
-static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a);
+static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
+static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a);
 static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
-				   diva_xdi_um_cfg_cmd_t * cmd,
+				   diva_xdi_um_cfg_cmd_t *cmd,
 				   int length);
-static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a);
-static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a,
-				      byte * data, dword length);
+static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a);
+static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a,
+				      byte *data, dword length);
 static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter);
 static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 				       dword address,
-				       const byte * data,
+				       const byte *data,
 				       dword length, dword limit);
 static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
 				   dword start_address, dword features);
 static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter);
-static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a);
+static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a);
 
 static int _4bri_is_rev_2_card(int card_ordinal)
 {
@@ -112,8 +112,8 @@ static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
 	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;
 
 	/*
-	   Set up hardware related pointers
-	 */
+	  Set up hardware related pointers
+	*/
 	a->xdi_adapter.Address = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
 	a->xdi_adapter.Address += c_offset;
 
@@ -121,15 +121,15 @@ static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
 
 	a->xdi_adapter.ram = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
 	a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
-	
+
 	a->xdi_adapter.reset = a->resources.pci.addr[0];	/* BAR0 CONFIG */
 	/*
-	   ctlReg contains the register address for the MIPS CPU reset control
-	 */
+	  ctlReg contains the register address for the MIPS CPU reset control
+	*/
 	a->xdi_adapter.ctlReg = a->resources.pci.addr[3];	/* BAR3 CNTRL  */
 	/*
-	   prom contains the register address for FPGA and EEPROM programming
-	 */
+	  prom contains the register address for FPGA and EEPROM programming
+	*/
 	a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
 }
 
@@ -141,7 +141,7 @@ static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
 **
 **  Called by master adapter, that will initialize and add slave adapters
 */
-int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
+int diva_4bri_init_card(diva_os_xdi_adapter_t *a)
 {
 	int bar, i;
 	byte __iomem *p;
@@ -168,48 +168,48 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 	DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
 		 bar_length[2], tasks, factor))
 
-	/*
-	   Get Serial Number
-	   The serial number of 4BRI is accessible in accordance with PCI spec
-	   via command register located in configuration space, also we do not
-	   have to map any BAR before we can access it
-	 */
-	if (!_4bri_get_serial_number(a)) {
-		DBG_ERR(("A: 4BRI can't get Serial Number"))
-		diva_4bri_cleanup_adapter(a);
-		return (-1);
-	}
+		/*
+		  Get Serial Number
+		  The serial number of 4BRI is accessible in accordance with PCI spec
+		  via command register located in configuration space, also we do not
+		  have to map any BAR before we can access it
+		*/
+		if (!_4bri_get_serial_number(a)) {
+			DBG_ERR(("A: 4BRI can't get Serial Number"))
+				diva_4bri_cleanup_adapter(a);
+			return (-1);
+		}
 
 	/*
-	   Set properties
-	 */
+	  Set properties
+	*/
 	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
 	DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x",
 		 a->xdi_adapter.Properties.Name,
 		 a->xdi_adapter.serialNo,
 		 a->resources.pci.bus, a->resources.pci.func))
 
-	/*
-	   First initialization step: get and check hardware resoures.
-	   Do not map resources and do not access card at this step
-	 */
-	for (bar = 0; bar < 4; bar++) {
-		a->resources.pci.bar[bar] =
-		    divasa_get_pci_bar(a->resources.pci.bus,
-				       a->resources.pci.func, bar,
-				       a->resources.pci.hdev);
-		if (!a->resources.pci.bar[bar]
-		    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
-			DBG_ERR(
-				("A: invalid bar[%d]=%08x", bar,
-				 a->resources.pci.bar[bar]))
-			return (-1);
+		/*
+		  First initialization step: get and check hardware resoures.
+		  Do not map resources and do not access card at this step
+		*/
+		for (bar = 0; bar < 4; bar++) {
+			a->resources.pci.bar[bar] =
+				divasa_get_pci_bar(a->resources.pci.bus,
+						   a->resources.pci.func, bar,
+						   a->resources.pci.hdev);
+			if (!a->resources.pci.bar[bar]
+			    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
+				DBG_ERR(
+					("A: invalid bar[%d]=%08x", bar,
+					 a->resources.pci.bar[bar]))
+					return (-1);
+			}
 		}
-	}
 	a->resources.pci.irq =
-	    (byte) divasa_get_pci_irq(a->resources.pci.bus,
-				      a->resources.pci.func,
-				      a->resources.pci.hdev);
+		(byte) divasa_get_pci_irq(a->resources.pci.bus,
+					  a->resources.pci.func,
+					  a->resources.pci.hdev);
 	if (!a->resources.pci.irq) {
 		DBG_ERR(("A: invalid irq"));
 		return (-1);
@@ -218,30 +218,30 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 	a->xdi_adapter.sdram_bar = a->resources.pci.bar[2];
 
 	/*
-	   Map all MEMORY BAR's
-	 */
+	  Map all MEMORY BAR's
+	*/
 	for (bar = 0; bar < 4; bar++) {
 		if (bar != 1) {	/* ignore I/O */
 			a->resources.pci.addr[bar] =
-			    divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
-						 bar_length[bar]);
+				divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
+						     bar_length[bar]);
 			if (!a->resources.pci.addr[bar]) {
 				DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
-				diva_4bri_cleanup_adapter(a);
+					diva_4bri_cleanup_adapter(a);
 				return (-1);
 			}
 		}
 	}
 
 	/*
-	   Register I/O port
-	 */
+	  Register I/O port
+	*/
 	sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
 
 	if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
 				     bar_length[1], &a->port_name[0], 1)) {
 		DBG_ERR(("A: 4BRI: can't register bar[1]"))
-		diva_4bri_cleanup_adapter(a);
+			diva_4bri_cleanup_adapter(a);
 		return (-1);
 	}
 
@@ -249,23 +249,23 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 		(void *) (unsigned long) a->resources.pci.bar[1];
 
 	/*
-	   Set cleanup pointer for base adapter only, so slave adapter
-	   will be unable to get cleanup
-	 */
+	  Set cleanup pointer for base adapter only, so slave adapter
+	  will be unable to get cleanup
+	*/
 	a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;
 
 	/*
-	   Create slave adapters
-	 */
+	  Create slave adapters
+	*/
 	if (tasks > 1) {
 		if (!(a->slave_adapters[0] =
-		     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
+		      (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
 		{
 			diva_4bri_cleanup_adapter(a);
 			return (-1);
 		}
 		if (!(a->slave_adapters[1] =
-		     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
+		      (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
 		{
 			diva_os_free(0, a->slave_adapters[0]);
 			a->slave_adapters[0] = NULL;
@@ -273,7 +273,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 			return (-1);
 		}
 		if (!(a->slave_adapters[2] =
-		     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
+		      (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
 		{
 			diva_os_free(0, a->slave_adapters[0]);
 			diva_os_free(0, a->slave_adapters[1]);
@@ -293,10 +293,10 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 	adapter_list[3] = a->slave_adapters[2];
 
 	/*
-	   Allocate slave list
-	 */
+	  Allocate slave list
+	*/
 	quadro_list =
-	    (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
+		(PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
 	if (!(a->slave_list = quadro_list)) {
 		for (i = 0; i < (tasks - 1); i++) {
 			diva_os_free(0, a->slave_adapters[i]);
@@ -308,14 +308,14 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 	memset(quadro_list, 0x00, sizeof(*quadro_list));
 
 	/*
-	   Set interfaces
-	 */
+	  Set interfaces
+	*/
 	a->xdi_adapter.QuadroList = quadro_list;
 	for (i = 0; i < tasks; i++) {
 		adapter_list[i]->xdi_adapter.ControllerNumber = i;
 		adapter_list[i]->xdi_adapter.tasks = tasks;
 		quadro_list->QuadroAdapter[i] =
-		    &adapter_list[i]->xdi_adapter;
+			&adapter_list[i]->xdi_adapter;
 	}
 
 	for (i = 0; i < tasks; i++) {
@@ -324,21 +324,21 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 		diva_current->dsp_mask = 0x00000003;
 
 		diva_current->xdi_adapter.a.io =
-		    &diva_current->xdi_adapter;
+			&diva_current->xdi_adapter;
 		diva_current->xdi_adapter.DIRequest = request;
 		diva_current->interface.cmd_proc = diva_4bri_cmd_card_proc;
 		diva_current->xdi_adapter.Properties =
-		    CardProperties[a->CardOrdinal];
+			CardProperties[a->CardOrdinal];
 		diva_current->CardOrdinal = a->CardOrdinal;
 
 		diva_current->xdi_adapter.Channels =
-		    CardProperties[a->CardOrdinal].Channels;
+			CardProperties[a->CardOrdinal].Channels;
 		diva_current->xdi_adapter.e_max =
-		    CardProperties[a->CardOrdinal].E_info;
+			CardProperties[a->CardOrdinal].E_info;
 		diva_current->xdi_adapter.e_tbl =
-		    diva_os_malloc(0,
-				   diva_current->xdi_adapter.e_max *
-				   sizeof(E_INFO));
+			diva_os_malloc(0,
+				       diva_current->xdi_adapter.e_max *
+				       sizeof(E_INFO));
 
 		if (!diva_current->xdi_adapter.e_tbl) {
 			diva_4bri_cleanup_slave_adapters(a);
@@ -370,8 +370,8 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 
 		strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid");
 
-		if (diva_os_initialize_soft_isr (&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine,
-		     &diva_current->xdi_adapter)) {
+		if (diva_os_initialize_soft_isr(&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine,
+						&diva_current->xdi_adapter)) {
 			diva_4bri_cleanup_slave_adapters(a);
 			diva_4bri_cleanup_adapter(a);
 			for (i = 1; i < (tasks - 1); i++) {
@@ -381,10 +381,10 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 		}
 
 		/*
-		   Do not initialize second DPC - only one thread will be created
-		 */
+		  Do not initialize second DPC - only one thread will be created
+		*/
 		diva_current->xdi_adapter.isr_soft_isr.object =
-		    diva_current->xdi_adapter.req_soft_isr.object;
+			diva_current->xdi_adapter.req_soft_isr.object;
 	}
 
 	if (v2) {
@@ -397,12 +397,12 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 		diva_current = adapter_list[i];
 		if (i)
 			memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
-		diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor); 
+		diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor);
 	}
 
 	/*
-	   Set up hardware related pointers
-	 */
+	  Set up hardware related pointers
+	*/
 	a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0];	/* BAR0 CONFIG */
 	a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1];	/* BAR1        */
 	a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3];	/* BAR3 CNTRL  */
@@ -415,21 +415,21 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 		Slave->sdram_bar = a->xdi_adapter.sdram_bar;
 		if (i) {
 			Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
-					a->xdi_adapter.serialNo;
+				a->xdi_adapter.serialNo;
 			Slave->cardType = a->xdi_adapter.cardType;
 		}
 	}
 
 	/*
-	   reset contains the base address for the PLX 9054 register set
-	 */
+	  reset contains the base address for the PLX 9054 register set
+	*/
 	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
 	WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);	/* disable PCI interrupts */
 	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
 
 	/*
-	   Set IRQ handler
-	 */
+	  Set IRQ handler
+	*/
 	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
 	sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA 4BRI %ld",
 		(long) a->xdi_adapter.serialNo);
@@ -447,8 +447,8 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 	a->xdi_adapter.irq_info.registered = 1;
 
 	/*
-	   Add three slave adapters
-	 */
+	  Add three slave adapters
+	*/
 	if (tasks > 1) {
 		diva_add_slave_adapter(adapter_list[1]);
 		diva_add_slave_adapter(adapter_list[2]);
@@ -466,33 +466,33 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 **  this is guaranteed by design: cleanup callback is set
 **  by master adapter only
 */
-static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
+static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
 {
 	int bar;
 
 	/*
-	   Stop adapter if running
-	 */
+	  Stop adapter if running
+	*/
 	if (a->xdi_adapter.Initialized) {
 		diva_4bri_stop_adapter(a);
 	}
 
 	/*
-	   Remove IRQ handler
-	 */
+	  Remove IRQ handler
+	*/
 	if (a->xdi_adapter.irq_info.registered) {
 		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
 	}
 	a->xdi_adapter.irq_info.registered = 0;
 
 	/*
-	   Free DPC's and spin locks on all adapters
-	 */
+	  Free DPC's and spin locks on all adapters
+	*/
 	diva_4bri_cleanup_slave_adapters(a);
 
 	/*
-	   Unmap all BARS
-	 */
+	  Unmap all BARS
+	*/
 	for (bar = 0; bar < 4; bar++) {
 		if (bar != 1) {
 			if (a->resources.pci.bar[bar]
@@ -505,8 +505,8 @@ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	}
 
 	/*
-	   Unregister I/O
-	 */
+	  Unregister I/O
+	*/
 	if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
 		diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
 					 _4bri_is_rev_2_card(a->
@@ -526,7 +526,7 @@ static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	return (0);
 }
 
-static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a)
+static int _4bri_get_serial_number(diva_os_xdi_adapter_t *a)
 {
 	dword data[64];
 	dword serNo;
@@ -551,13 +551,13 @@ static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a)
 		}
 		if (j >= 5) {
 			DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr))
-			return (0);
+				return (0);
 		}
 		PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev);
 	}
 	DBG_BLK(((char *) &data[0], sizeof(data)))
 
-	serNo = data[32];
+		serNo = data[32];
 	if (serNo == 0 || serNo == 0xffffffff)
 		serNo = data[63];
 
@@ -572,13 +572,13 @@ static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a)
 
 	DBG_REG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
 
-	return (serNo);
+		return (serNo);
 }
 
 /*
 **  Release resources of slave adapters
 */
-static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a)
+static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t *a)
 {
 	diva_os_xdi_adapter_t *adapter_list[4];
 	diva_os_xdi_adapter_t *diva_current;
@@ -625,24 +625,24 @@ static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a)
 
 static int
 diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
-			diva_xdi_um_cfg_cmd_t * cmd, int length)
+			diva_xdi_um_cfg_cmd_t *cmd, int length)
 {
 	int ret = -1;
 
 	if (cmd->adapter != a->controller) {
 		DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
 			 cmd->adapter, a->controller))
-		return (-1);
+			return (-1);
 	}
 
 	switch (cmd->command) {
 	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			*(dword *) a->xdi_mbox.data =
-			    (dword) a->CardOrdinal;
+				(dword) a->CardOrdinal;
 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 			ret = 0;
 		}
@@ -651,10 +651,10 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			*(dword *) a->xdi_mbox.data =
-			    (dword) a->xdi_adapter.serialNo;
+				(dword) a->xdi_adapter.serialNo;
 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 			ret = 0;
 		}
@@ -663,11 +663,11 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
 		if (!a->xdi_adapter.ControllerNumber) {
 			/*
-			   Only master adapter can access hardware config
-			 */
+			  Only master adapter can access hardware config
+			*/
 			a->xdi_mbox.data_length = sizeof(dword) * 9;
 			a->xdi_mbox.data =
-			    diva_os_malloc(0, a->xdi_mbox.data_length);
+				diva_os_malloc(0, a->xdi_mbox.data_length);
 			if (a->xdi_mbox.data) {
 				int i;
 				dword *data = (dword *) a->xdi_mbox.data;
@@ -686,7 +686,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 		if (!a->xdi_adapter.ControllerNumber) {
 			a->xdi_mbox.data_length = sizeof(dword);
 			a->xdi_mbox.data =
-			    diva_os_malloc(0, a->xdi_mbox.data_length);
+				diva_os_malloc(0, a->xdi_mbox.data_length);
 			if (a->xdi_mbox.data) {
 				dword *data = (dword *) a->xdi_mbox.data;
 				if (!a->xdi_adapter.ram
@@ -709,11 +709,11 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_WRITE_FPGA:
 		if (!a->xdi_adapter.ControllerNumber) {
 			ret =
-			    diva_4bri_write_fpga_image(a,
-						       (byte *) & cmd[1],
-						       cmd->command_data.
-						       write_fpga.
-						       image_length);
+				diva_4bri_write_fpga_image(a,
+							   (byte *)&cmd[1],
+							   cmd->command_data.
+							   write_fpga.
+							   image_length);
 		}
 		break;
 
@@ -754,12 +754,12 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
 		if (!a->xdi_adapter.ControllerNumber) {
 			a->xdi_adapter.features =
-			    cmd->command_data.features.features;
+				cmd->command_data.features.features;
 			a->xdi_adapter.a.protocol_capabilities =
-			    a->xdi_adapter.features;
+				a->xdi_adapter.features;
 			DBG_TRC(("Set raw protocol features (%08x)",
 				 a->xdi_adapter.features))
-			ret = 0;
+				ret = 0;
 		}
 		break;
 
@@ -777,16 +777,16 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 		if (!a->xdi_adapter.ControllerNumber
 		    && a->xdi_adapter.Address) {
 			if (
-			    (a->xdi_mbox.data_length =
-			     cmd->command_data.read_sdram.length)) {
+				(a->xdi_mbox.data_length =
+				 cmd->command_data.read_sdram.length)) {
 				if (
-				    (a->xdi_mbox.data_length +
-				     cmd->command_data.read_sdram.offset) <
-				    a->xdi_adapter.MemorySize) {
+					(a->xdi_mbox.data_length +
+					 cmd->command_data.read_sdram.offset) <
+					a->xdi_adapter.MemorySize) {
 					a->xdi_mbox.data =
-					    diva_os_malloc(0,
-							   a->xdi_mbox.
-							   data_length);
+						diva_os_malloc(0,
+							       a->xdi_mbox.
+							       data_length);
 					if (a->xdi_mbox.data) {
 						byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
 						byte __iomem *src = p;
@@ -810,7 +810,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	default:
 		DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
 			 cmd->command))
-	}
+			}
 
 	return (ret);
 }
@@ -838,7 +838,7 @@ void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
 }
 
 static int
-diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, byte * data,
+diva_4bri_write_fpga_image(diva_os_xdi_adapter_t *a, byte *data,
 			   dword length)
 {
 	int ret;
@@ -865,12 +865,12 @@ static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 	if (IoAdapter->Initialized) {
 		DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
 			 IoAdapter->ANum))
-		return (-1);
+			return (-1);
 	}
 
 	/*
-	   Forget all entities on all adapters
-	 */
+	  Forget all entities on all adapters
+	*/
 	for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) {
 		Slave = IoAdapter->QuadroList->QuadroAdapter[i];
 		Slave->e_count = 0;
@@ -908,7 +908,7 @@ static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 static int
 diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 			    dword address,
-			    const byte * data, dword length, dword limit)
+			    const byte *data, dword length, dword limit)
 {
 	byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
 	byte __iomem *mem = p;
@@ -917,7 +917,7 @@ diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
 		DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
 			 IoAdapter->ANum, address + length))
-		return (-1);
+			return (-1);
 	}
 	mem += address;
 
@@ -939,14 +939,14 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
 	byte __iomem *p;
 
 	/*
-	   start adapter
-	 */
+	  start adapter
+	*/
 	start_qBri_hardware(IoAdapter);
 
 	p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
 	/*
-	   wait for signature in shared memory (max. 3 seconds)
-	 */
+	  wait for signature in shared memory (max. 3 seconds)
+	*/
 	signature = (volatile word __iomem *) (&p[0x1E]);
 
 	for (i = 0; i < 300; ++i) {
@@ -954,23 +954,23 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
 		if (READ_WORD(&signature[0]) == 0x4447) {
 			DBG_TRC(("Protocol startup time %d.%02d seconds",
 				 (i / 100), (i % 100)))
-			started = 1;
+				started = 1;
 			break;
 		}
 	}
 
 	for (i = 1; i < IoAdapter->tasks; i++) {
 		IoAdapter->QuadroList->QuadroAdapter[i]->features =
-		    IoAdapter->features;
+			IoAdapter->features;
 		IoAdapter->QuadroList->QuadroAdapter[i]->a.
-		    protocol_capabilities = IoAdapter->features;
+			protocol_capabilities = IoAdapter->features;
 	}
 
 	if (!started) {
 		DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
 			 IoAdapter->Properties.Name,
 			 READ_WORD(&signature[0])))
-		DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
+			DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
 		(*(IoAdapter->trapFnc)) (IoAdapter);
 		IoAdapter->stop(IoAdapter);
 		return (-1);
@@ -985,9 +985,9 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
 	if (check_qBri_interrupt(IoAdapter)) {
 		DBG_ERR(("A: A(%d) interrupt test failed",
 			 IoAdapter->ANum))
-		for (i = 0; i < IoAdapter->tasks; i++) {
-			IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
-		}
+			for (i = 0; i < IoAdapter->tasks; i++) {
+				IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
+			}
 		IoAdapter->stop(IoAdapter);
 		return (-1);
 	}
@@ -999,7 +999,7 @@ diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
 		DBG_LOG(("A(%d) %s adapter successfully started",
 			 IoAdapter->QuadroList->QuadroAdapter[i]->ANum,
 			 (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI"))
-		diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
+			diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
 		IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features;
 	}
 
@@ -1022,8 +1022,8 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
 	WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
 	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
 	/*
-	   interrupt test
-	 */
+	  interrupt test
+	*/
 	a->ReadyInt = 1;
 	a->ram_out(a, &PR_RAM->ReadyInt, 1);
 
@@ -1034,14 +1034,14 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
 	dword volatile __iomem *qBriIrq;
 	byte __iomem *p;
 	/*
-	   Reset on-board interrupt register
-	 */
+	  Reset on-board interrupt register
+	*/
 	IoAdapter->IrqCount = 0;
 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card
-				       (IoAdapter->
-					cardType) ? (MQ2_BREG_IRQ_TEST)
-				       : (MQ_BREG_IRQ_TEST)]);
+						 (IoAdapter->
+						  cardType) ? (MQ2_BREG_IRQ_TEST)
+						 : (MQ_BREG_IRQ_TEST)]);
 
 	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
@@ -1056,13 +1056,13 @@ static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
 #endif				/* SUPPORT_INTERRUPT_TEST_ON_4BRI */
 }
 
-static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)
+static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t *a)
 {
 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 
 	/*
-	   clear any pending interrupt
-	 */
+	  clear any pending interrupt
+	*/
 	IoAdapter->disIrq(IoAdapter);
 
 	IoAdapter->tst_irq(&IoAdapter->a);
@@ -1070,13 +1070,13 @@ static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)
 	IoAdapter->tst_irq(&IoAdapter->a);
 
 	/*
-	   kill pending dpcs
-	 */
+	  kill pending dpcs
+	*/
 	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
 	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
 }
 
-static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
+static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t *a)
 {
 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 	int i;
@@ -1088,7 +1088,7 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
 	if (!IoAdapter->Initialized) {
 		DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
 			 IoAdapter->ANum))
-		return (-1);	/* nothing to stop */
+			return (-1);	/* nothing to stop */
 	}
 
 	for (i = 0; i < IoAdapter->tasks; i++) {
@@ -1096,8 +1096,8 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
 	}
 
 	/*
-	   Disconnect Adapters from DIDD
-	 */
+	  Disconnect Adapters from DIDD
+	*/
 	for (i = 0; i < IoAdapter->tasks; i++) {
 		diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
 	}
@@ -1105,8 +1105,8 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
 	i = 100;
 
 	/*
-	   Stop interrupts
-	 */
+	  Stop interrupts
+	*/
 	a->clear_interrupts_proc = diva_4bri_clear_interrupts;
 	IoAdapter->a.ReadyInt = 1;
 	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
@@ -1119,12 +1119,12 @@ static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
 		a->clear_interrupts_proc = NULL;
 		DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter",
 			 IoAdapter->ANum))
-	}
+			}
 	IoAdapter->a.ReadyInt = 0;
 
 	/*
-	   Stop and reset adapter
-	 */
+	  Stop and reset adapter
+	*/
 	IoAdapter->stop(IoAdapter);
 
 	return (0);
diff --git a/drivers/isdn/hardware/eicon/os_4bri.h b/drivers/isdn/hardware/eicon/os_4bri.h
index 665f0af..7225327 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.h
+++ b/drivers/isdn/hardware/eicon/os_4bri.h
@@ -3,6 +3,6 @@
 #ifndef __DIVA_OS_4_BRI_H__
 #define __DIVA_OS_4_BRI_H__
 
-int diva_4bri_init_card(diva_os_xdi_adapter_t * a);
+int diva_4bri_init_card(diva_os_xdi_adapter_t *a);
 
 #endif
diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c
index 08f0199..20f2653 100644
--- a/drivers/isdn/hardware/eicon/os_bri.c
+++ b/drivers/isdn/hardware/eicon/os_bri.c
@@ -23,7 +23,7 @@
 */
 extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
 extern void diva_xdi_display_adapter_features(int card);
-extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
+extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
 
 /*
 **  LOCALS
@@ -33,20 +33,20 @@ static int bri_bar_length[3] = {
 	0x80,
 	0x20
 };
-static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a);
-static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a);
+static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
+static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a);
 static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
-				  diva_xdi_um_cfg_cmd_t * cmd, int length);
-static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a);
+				  diva_xdi_um_cfg_cmd_t *cmd, int length);
+static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a);
 static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);
 static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 				      dword address,
-				      const byte * data, dword length);
+				      const byte *data, dword length);
 static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 				  dword start_address, dword features);
-static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a);
+static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a);
 
-static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
+static void diva_bri_set_addresses(diva_os_xdi_adapter_t *a)
 {
 	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
 	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
@@ -54,7 +54,7 @@ static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
 	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
 	a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
 	a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
-	
+
 	a->xdi_adapter.ram = a->resources.pci.addr[0];
 	a->xdi_adapter.cfg = a->resources.pci.addr[1];
 	a->xdi_adapter.Address = a->resources.pci.addr[2];
@@ -72,7 +72,7 @@ static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
 **  BAR1 - I/O Addr  - 0x80
 **  BAR2 - I/O Addr  - 0x20
 */
-int diva_bri_init_card(diva_os_xdi_adapter_t * a)
+int diva_bri_init_card(diva_os_xdi_adapter_t *a)
 {
 	int bar;
 	dword bar2 = 0, bar2_length = 0xffffffff;
@@ -82,75 +82,75 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 	byte __iomem *p;
 
 	/*
-	   Set properties
-	 */
+	  Set properties
+	*/
 	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
 	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
 
-	    /*
-	       Get resources
-	     */
-	    for (bar = 0; bar < 3; bar++) {
-		a->resources.pci.bar[bar] =
-		    divasa_get_pci_bar(a->resources.pci.bus,
-				       a->resources.pci.func, bar,
-				       a->resources.pci.hdev);
-		if (!a->resources.pci.bar[bar]) {
-			DBG_ERR(("A: can't get BAR[%d]", bar))
-			return (-1);
+		/*
+		  Get resources
+		*/
+		for (bar = 0; bar < 3; bar++) {
+			a->resources.pci.bar[bar] =
+				divasa_get_pci_bar(a->resources.pci.bus,
+						   a->resources.pci.func, bar,
+						   a->resources.pci.hdev);
+			if (!a->resources.pci.bar[bar]) {
+				DBG_ERR(("A: can't get BAR[%d]", bar))
+					return (-1);
+			}
 		}
-	}
 
 	a->resources.pci.irq =
-	    (byte) divasa_get_pci_irq(a->resources.pci.bus,
-				      a->resources.pci.func,
-				      a->resources.pci.hdev);
+		(byte) divasa_get_pci_irq(a->resources.pci.bus,
+					  a->resources.pci.func,
+					  a->resources.pci.hdev);
 	if (!a->resources.pci.irq) {
 		DBG_ERR(("A: invalid irq"));
 		return (-1);
 	}
 
 	/*
-	   Get length of I/O bar 2 - it is different by older
-	   EEPROM version
-	 */
+	  Get length of I/O bar 2 - it is different by older
+	  EEPROM version
+	*/
 	Bus = a->resources.pci.bus;
 	Slot = a->resources.pci.func;
 	hdev = a->resources.pci.hdev;
 
 	/*
-	   Get plain original values of the BAR2 CDM registers
-	 */
+	  Get plain original values of the BAR2 CDM registers
+	*/
 	PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
 	PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
 	/*
-	   Disable device and get BAR2 length
-	 */
+	  Disable device and get BAR2 length
+	*/
 	PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
 	PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
 	PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
 	/*
-	   Restore BAR2 and CMD registers
-	 */
+	  Restore BAR2 and CMD registers
+	*/
 	PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
 	PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
 
 	/*
-	   Calculate BAR2 length
-	 */
+	  Calculate BAR2 length
+	*/
 	bar2_length = (~(bar2_length & ~7)) + 1;
 	DBG_LOG(("BAR[2] length=%lx", bar2_length))
 
-	    /*
-	       Map and register resources
-	     */
-	    if (!(a->resources.pci.addr[0] =
-		 divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
-				      bri_bar_length[0]))) {
-		DBG_ERR(("A: BRI, can't map BAR[0]"))
-		diva_bri_cleanup_adapter(a);
-		return (-1);
-	}
+		/*
+		  Map and register resources
+		*/
+		if (!(a->resources.pci.addr[0] =
+		      divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
+					   bri_bar_length[0]))) {
+			DBG_ERR(("A: BRI, can't map BAR[0]"))
+				diva_bri_cleanup_adapter(a);
+			return (-1);
+		}
 
 	sprintf(&a->port_name[0], "BRI %02x:%02x",
 		a->resources.pci.bus, a->resources.pci.func);
@@ -158,7 +158,7 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 	if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
 				     bri_bar_length[1], &a->port_name[0], 1)) {
 		DBG_ERR(("A: BRI, can't register BAR[1]"))
-		diva_bri_cleanup_adapter(a);
+			diva_bri_cleanup_adapter(a);
 		return (-1);
 	}
 	a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
@@ -167,33 +167,33 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 	if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
 				     bar2_length, &a->port_name[0], 2)) {
 		DBG_ERR(("A: BRI, can't register BAR[2]"))
-		diva_bri_cleanup_adapter(a);
+			diva_bri_cleanup_adapter(a);
 		return (-1);
 	}
 	a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2];
 	a->resources.pci.length[2] = bar2_length;
 
 	/*
-	   Set all memory areas
-	 */
+	  Set all memory areas
+	*/
 	diva_bri_set_addresses(a);
 
 	/*
-	   Get Serial Number
-	 */
+	  Get Serial Number
+	*/
 	a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
 
 	/*
-	   Register I/O ports with correct name now
-	 */
+	  Register I/O ports with correct name now
+	*/
 	if (diva_bri_reregister_io(a)) {
 		diva_bri_cleanup_adapter(a);
 		return (-1);
 	}
 
 	/*
-	   Initialize OS dependent objects
-	 */
+	  Initialize OS dependent objects
+	*/
 	if (diva_os_initialize_spin_lock
 	    (&a->xdi_adapter.isr_spin_lock, "isr")) {
 		diva_bri_cleanup_adapter(a);
@@ -213,13 +213,13 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 		return (-1);
 	}
 	/*
-	   Do not initialize second DPC - only one thread will be created
-	 */
+	  Do not initialize second DPC - only one thread will be created
+	*/
 	a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object;
 
 	/*
-	   Create entity table
-	 */
+	  Create entity table
+	*/
 	a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
 	a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
 	a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
@@ -230,8 +230,8 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 	memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
 
 	/*
-	   Set up interface
-	 */
+	  Set up interface
+	*/
 	a->xdi_adapter.a.io = &a->xdi_adapter;
 	a->xdi_adapter.DIRequest = request;
 	a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
@@ -246,8 +246,8 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 	a->dsp_mask = 0x00000003;
 
 	/*
-	   Set IRQ handler
-	 */
+	  Set IRQ handler
+	*/
 	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
 	sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld",
 		(long) a->xdi_adapter.serialNo);
@@ -265,7 +265,7 @@ int diva_bri_init_card(diva_os_xdi_adapter_t * a)
 }
 
 
-static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
+static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
 {
 	int i;
 
@@ -274,8 +274,8 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	}
 
 	/*
-	   Remove ISR Handler
-	 */
+	  Remove ISR Handler
+	*/
 	if (a->xdi_adapter.irq_info.registered) {
 		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
 	}
@@ -300,8 +300,8 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	}
 
 	/*
-	   Free OS objects
-	 */
+	  Free OS objects
+	*/
 	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
 	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
 
@@ -312,8 +312,8 @@ static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
 
 	/*
-	   Free memory
-	 */
+	  Free memory
+	*/
 	if (a->xdi_adapter.e_tbl) {
 		diva_os_free(0, a->xdi_adapter.e_tbl);
 		a->xdi_adapter.e_tbl = NULL;
@@ -329,7 +329,7 @@ void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter)
 /*
 **  Get serial number
 */
-static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a)
+static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a)
 {
 	dword serNo = 0;
 	byte __iomem *confIO;
@@ -345,7 +345,7 @@ static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a)
 	if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
 		DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
 
-		confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
+			confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
 		serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
 		serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
 		serNo = (((dword) serHi) << 16) | ((dword) serLo);
@@ -354,14 +354,14 @@ static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a)
 
 	DBG_LOG(("Serial Number=%ld", serNo))
 
-	return (serNo);
+		return (serNo);
 }
 
 /*
 **  Unregister I/O and register it with new name,
 **  based on Serial Number
 */
-static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a)
+static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a)
 {
 	int i;
 
@@ -380,10 +380,10 @@ static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a)
 					     a->resources.pci.length[i],
 					     &a->port_name[0], i)) {
 			DBG_ERR(("A: failed to reregister BAR[%d]", i))
-			return (-1);
+				return (-1);
 		}
 		a->resources.pci.addr[i] =
-		    (void *) (unsigned long) a->resources.pci.bar[i];
+			(void *) (unsigned long) a->resources.pci.bar[i];
 	}
 
 	return (0);
@@ -394,24 +394,24 @@ static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a)
 */
 static int
 diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
-		       diva_xdi_um_cfg_cmd_t * cmd, int length)
+		       diva_xdi_um_cfg_cmd_t *cmd, int length)
 {
 	int ret = -1;
 
 	if (cmd->adapter != a->controller) {
 		DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
 			 cmd->adapter, a->controller))
-		return (-1);
+			return (-1);
 	}
 
 	switch (cmd->command) {
 	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			*(dword *) a->xdi_mbox.data =
-			    (dword) a->CardOrdinal;
+				(dword) a->CardOrdinal;
 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 			ret = 0;
 		}
@@ -420,10 +420,10 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			*(dword *) a->xdi_mbox.data =
-			    (dword) a->xdi_adapter.serialNo;
+				(dword) a->xdi_adapter.serialNo;
 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 			ret = 0;
 		}
@@ -432,7 +432,7 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
 		a->xdi_mbox.data_length = sizeof(dword) * 9;
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			int i;
 			dword *data = (dword *) a->xdi_mbox.data;
@@ -449,7 +449,7 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_CARD_STATE:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			dword *data = (dword *) a->xdi_mbox.data;
 			if (!a->xdi_adapter.port) {
@@ -474,7 +474,7 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 		ret = diva_bri_write_sdram_block(&a->xdi_adapter,
 						 cmd->command_data.
 						 write_sdram.offset,
-						 (byte *) & cmd[1],
+						 (byte *)&cmd[1],
 						 cmd->command_data.
 						 write_sdram.length);
 		break;
@@ -489,9 +489,9 @@ diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 
 	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
 		a->xdi_adapter.features =
-		    cmd->command_data.features.features;
+			cmd->command_data.features.features;
 		a->xdi_adapter.a.protocol_capabilities =
-		    a->xdi_adapter.features;
+			a->xdi_adapter.features;
 		DBG_TRC(
 			("Set raw protocol features (%08x)",
 			 a->xdi_adapter.features)) ret = 0;
@@ -530,18 +530,18 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 	diva_os_wait(100);
 	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
 	addrHi = Port +
-	    ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
 	addrLo = Port + ADDR;
 	ioaddr = Port + DATA;
 	/*
-	   recover
-	 */
+	  recover
+	*/
 	outpp(addrHi, (byte) 0);
 	outppw(addrLo, (word) 0);
 	outppw(ioaddr, (word) 0);
 	/*
-	   clear shared memory
-	 */
+	  clear shared memory
+	*/
 	outpp(addrHi,
 	      (byte) (
 		      (IoAdapter->MemoryBase + IoAdapter->MemorySize -
@@ -551,8 +551,8 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 	diva_os_wait(100);
 
 	/*
-	   clear signature
-	 */
+	  clear signature
+	*/
 	outpp(addrHi,
 	      (byte) (
 		      (IoAdapter->MemoryBase + IoAdapter->MemorySize -
@@ -568,8 +568,8 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
 
 	/*
-	   Forget all outstanding entities
-	 */
+	  Forget all outstanding entities
+	*/
 	IoAdapter->e_count = 0;
 	if (IoAdapter->e_tbl) {
 		memset(IoAdapter->e_tbl, 0x00,
@@ -602,7 +602,7 @@ static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 
 static int
 diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
-			   dword address, const byte * data, dword length)
+			   dword address, const byte *data, dword length)
 {
 	byte __iomem *addrHi, *addrLo, *ioaddr;
 	byte __iomem *Port;
@@ -613,7 +613,7 @@ diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 
 	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
 	addrHi = Port +
-	    ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
 	addrLo = Port + ADDR;
 	ioaddr = Port + DATA;
 
@@ -651,9 +651,9 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
 	DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
 
-	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+		Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
 	addrHi = Port +
-	    ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
 	addrLo = Port + ADDR;
 	ioaddr = Port + DATA;
 
@@ -666,20 +666,20 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
 
 	/*
-	   start the protocol code
-	 */
+	  start the protocol code
+	*/
 	Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	outpp(Port, 0x08);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
 
 	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
 	addrHi = Port +
-	    ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
 	addrLo = Port + ADDR;
 	ioaddr = Port + DATA;
 	/*
-	   wait for signature (max. 3 seconds)
-	 */
+	  wait for signature (max. 3 seconds)
+	*/
 	for (i = 0; i < 300; ++i) {
 		diva_os_wait(10);
 		outpp(addrHi,
@@ -693,7 +693,7 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 			DBG_LOG(
 				("Protocol startup time %d.%02d seconds",
 				 (i / 100), (i % 100)))
-			started = 1;
+				started = 1;
 			break;
 		}
 	}
@@ -703,15 +703,15 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 		DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
 			 IoAdapter->ANum, IoAdapter->Properties.Name,
 			 test))
-		(*(IoAdapter->trapFnc)) (IoAdapter);
+			(*(IoAdapter->trapFnc)) (IoAdapter);
 		return (-1);
 	}
 
 	IoAdapter->Initialized = 1;
 
 	/*
-	   Check Interrupt
-	 */
+	  Check Interrupt
+	*/
 	IoAdapter->IrqCount = 0;
 	a->ReadyInt = 1;
 
@@ -729,7 +729,7 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 		DBG_ERR(
 			("A: A(%d) interrupt test failed",
 			 IoAdapter->ANum))
-		IoAdapter->Initialized = 0;
+			IoAdapter->Initialized = 0;
 		IoAdapter->stop(IoAdapter);
 		return (-1);
 	}
@@ -737,21 +737,21 @@ diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
 	IoAdapter->Properties.Features = (word) features;
 	diva_xdi_display_adapter_features(IoAdapter->ANum);
 	DBG_LOG(("A(%d) BRI adapter successfully started", IoAdapter->ANum))
-	    /*
-	       Register with DIDD
-	     */
-	diva_xdi_didd_register_adapter(IoAdapter->ANum);
+		/*
+		  Register with DIDD
+		*/
+		diva_xdi_didd_register_adapter(IoAdapter->ANum);
 
 	return (0);
 }
 
-static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a)
+static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t *a)
 {
 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 
 	/*
-	   clear any pending interrupt
-	 */
+	  clear any pending interrupt
+	*/
 	IoAdapter->disIrq(IoAdapter);
 
 	IoAdapter->tst_irq(&IoAdapter->a);
@@ -759,8 +759,8 @@ static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a)
 	IoAdapter->tst_irq(&IoAdapter->a);
 
 	/*
-	   kill pending dpcs
-	 */
+	  kill pending dpcs
+	*/
 	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
 	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
 }
@@ -768,7 +768,7 @@ static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a)
 /*
 **  Stop card
 */
-static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a)
+static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a)
 {
 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 	int i = 100;
@@ -779,18 +779,18 @@ static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a)
 	if (!IoAdapter->Initialized) {
 		DBG_ERR(("A: A(%d) can't stop BRI adapter - not running",
 			 IoAdapter->ANum))
-		return (-1);	/* nothing to stop */
+			return (-1);	/* nothing to stop */
 	}
 	IoAdapter->Initialized = 0;
 
 	/*
-	   Disconnect Adapter from DIDD
-	 */
+	  Disconnect Adapter from DIDD
+	*/
 	diva_xdi_didd_remove_adapter(IoAdapter->ANum);
 
 	/*
-	   Stop interrupts
-	 */
+	  Stop interrupts
+	*/
 	a->clear_interrupts_proc = diva_bri_clear_interrupts;
 	IoAdapter->a.ReadyInt = 1;
 	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
@@ -802,12 +802,12 @@ static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a)
 		a->clear_interrupts_proc = NULL;
 		DBG_ERR(("A: A(%d) no final interrupt from BRI adapter",
 			 IoAdapter->ANum))
-	}
+			}
 	IoAdapter->a.ReadyInt = 0;
 
 	/*
-	   Stop and reset adapter
-	 */
+	  Stop and reset adapter
+	*/
 	IoAdapter->stop(IoAdapter);
 
 	return (0);
diff --git a/drivers/isdn/hardware/eicon/os_bri.h b/drivers/isdn/hardware/eicon/os_bri.h
index a54f0ce..02e7456 100644
--- a/drivers/isdn/hardware/eicon/os_bri.h
+++ b/drivers/isdn/hardware/eicon/os_bri.h
@@ -3,6 +3,6 @@
 #ifndef __DIVA_OS_BRI_REV_1_H__
 #define __DIVA_OS_BRI_REV_1_H__
 
-int diva_bri_init_card(diva_os_xdi_adapter_t * a);
+int diva_bri_init_card(diva_os_xdi_adapter_t *a);
 
 #endif
diff --git a/drivers/isdn/hardware/eicon/os_capi.h b/drivers/isdn/hardware/eicon/os_capi.h
index 726f915..e72394b 100644
--- a/drivers/isdn/hardware/eicon/os_capi.h
+++ b/drivers/isdn/hardware/eicon/os_capi.h
@@ -1,16 +1,16 @@
 /* $Id: os_capi.h,v 1.7 2003/04/12 21:40:49 schindler Exp $
  *
  * ISDN interface module for Eicon active cards DIVA.
- * CAPI Interface OS include files 
- * 
- * Copyright 2000-2003 by Armin Schindler (mac@melware.de) 
+ * CAPI Interface OS include files
+ *
+ * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
  * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  */
 
-#ifndef __OS_CAPI_H__ 
+#ifndef __OS_CAPI_H__
 #define __OS_CAPI_H__
 
 #include <linux/capi.h>
diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c
index 5d65405..da4957a 100644
--- a/drivers/isdn/hardware/eicon/os_pri.c
+++ b/drivers/isdn/hardware/eicon/os_pri.c
@@ -24,11 +24,11 @@
    OS Dependent part of XDI driver for DIVA PRI Adapter
 
    DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
--------------------------------------------------------------------------- */
+   -------------------------------------------------------------------------- */
 
 #define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
 
-extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
+extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
 
 /*
 **  IMPORTS
@@ -37,12 +37,12 @@ extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
 extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
 extern void diva_xdi_display_adapter_features(int card);
 
-static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a);
+static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
 static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
-				  diva_xdi_um_cfg_cmd_t * cmd, int length);
-static int pri_get_serial_number(diva_os_xdi_adapter_t * a);
-static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a);
-static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a);
+				  diva_xdi_um_cfg_cmd_t *cmd, int length);
+static int pri_get_serial_number(diva_os_xdi_adapter_t *a);
+static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
+static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);
 
 /*
 **  Check card revision
@@ -57,7 +57,7 @@ static int pri_is_rev_2_card(int card_ordinal)
 	return (0);
 }
 
-static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
+static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
 {
 	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
 	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
@@ -66,7 +66,7 @@ static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
 	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
 	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
 	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
-	
+
 	a->xdi_adapter.Address = a->resources.pci.addr[0];
 	a->xdi_adapter.Control = a->resources.pci.addr[2];
 	a->xdi_adapter.Config = a->resources.pci.addr[4];
@@ -92,7 +92,7 @@ static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
 **  BAR3 - FLASH (REG),		0x8000
 **  BAR4 - CONFIG (CFG),	0x1000
 */
-int diva_pri_init_card(diva_os_xdi_adapter_t * a)
+int diva_pri_init_card(diva_os_xdi_adapter_t *a)
 {
 	int bar = 0;
 	int pri_rev_2;
@@ -110,59 +110,59 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
 		bar_length[0] = MP2_MEMORY_SIZE;
 	}
 	/*
-	   Set properties
-	 */
+	  Set properties
+	*/
 	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
 	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
 
-	/*
-	   First initialization step: get and check hardware resoures.
-	   Do not map resources and do not acecess card at this step
-	 */
-	for (bar = 0; bar < 5; bar++) {
-		a->resources.pci.bar[bar] =
-		    divasa_get_pci_bar(a->resources.pci.bus,
-				       a->resources.pci.func, bar,
-				       a->resources.pci.hdev);
-		if (!a->resources.pci.bar[bar]
-		    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
-			DBG_ERR(("A: invalid bar[%d]=%08x", bar,
-				 a->resources.pci.bar[bar]))
-			return (-1);
+		/*
+		  First initialization step: get and check hardware resoures.
+		  Do not map resources and do not acecess card at this step
+		*/
+		for (bar = 0; bar < 5; bar++) {
+			a->resources.pci.bar[bar] =
+				divasa_get_pci_bar(a->resources.pci.bus,
+						   a->resources.pci.func, bar,
+						   a->resources.pci.hdev);
+			if (!a->resources.pci.bar[bar]
+			    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
+				DBG_ERR(("A: invalid bar[%d]=%08x", bar,
+					 a->resources.pci.bar[bar]))
+					return (-1);
+			}
 		}
-	}
 	a->resources.pci.irq =
-	    (byte) divasa_get_pci_irq(a->resources.pci.bus,
-				      a->resources.pci.func,
-				      a->resources.pci.hdev);
+		(byte) divasa_get_pci_irq(a->resources.pci.bus,
+					  a->resources.pci.func,
+					  a->resources.pci.hdev);
 	if (!a->resources.pci.irq) {
 		DBG_ERR(("A: invalid irq"));
 		return (-1);
 	}
 
 	/*
-	   Map all BAR's
-	 */
+	  Map all BAR's
+	*/
 	for (bar = 0; bar < 5; bar++) {
 		a->resources.pci.addr[bar] =
-		    divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
-					 bar_length[bar]);
+			divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
+					     bar_length[bar]);
 		if (!a->resources.pci.addr[bar]) {
 			DBG_ERR(("A: A(%d), can't map bar[%d]",
 				 a->controller, bar))
-			diva_pri_cleanup_adapter(a);
+				diva_pri_cleanup_adapter(a);
 			return (-1);
 		}
 	}
 
 	/*
-	   Set all memory areas
-	 */
+	  Set all memory areas
+	*/
 	diva_pri_set_addresses(a);
 
 	/*
-	   Get Serial Number of this adapter
-	 */
+	  Get Serial Number of this adapter
+	*/
 	if (pri_get_serial_number(a)) {
 		dword serNo;
 		serNo = a->resources.pci.bar[1] & 0xffff0000;
@@ -171,12 +171,12 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
 		a->xdi_adapter.serialNo = serNo & ~0xFF000000;
 		DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
 			 a->controller, a->xdi_adapter.serialNo))
-	}
+			}
 
 
 	/*
-	   Initialize os objects
-	 */
+	  Initialize os objects
+	*/
 	if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
 		diva_pri_cleanup_adapter(a);
 		return (-1);
@@ -196,20 +196,20 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
 	}
 
 	/*
-	   Do not initialize second DPC - only one thread will be created
-	 */
+	  Do not initialize second DPC - only one thread will be created
+	*/
 	a->xdi_adapter.isr_soft_isr.object =
-	    a->xdi_adapter.req_soft_isr.object;
+		a->xdi_adapter.req_soft_isr.object;
 
 	/*
-	   Next step of card initialization:
-	   set up all interface pointers
-	 */
+	  Next step of card initialization:
+	  set up all interface pointers
+	*/
 	a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
 	a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
 
 	a->xdi_adapter.e_tbl =
-	    diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
+		diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
 	if (!a->xdi_adapter.e_tbl) {
 		diva_pri_cleanup_adapter(a);
 		return (-1);
@@ -230,16 +230,16 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
 	a->dsp_mask = diva_pri_detect_dsps(a);
 
 	/*
-	   Allocate DMA map
-	 */
+	  Allocate DMA map
+	*/
 	if (pri_rev_2) {
 		diva_init_dma_map(a->resources.pci.hdev,
 				  (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
 	}
 
 	/*
-	   Set IRQ handler
-	 */
+	  Set IRQ handler
+	*/
 	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
 	sprintf(a->xdi_adapter.irq_info.irq_name,
 		"DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
@@ -257,28 +257,28 @@ int diva_pri_init_card(diva_os_xdi_adapter_t * a)
 	return (0);
 }
 
-static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
+static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
 {
 	int bar = 0;
 
 	/*
-	   Stop Adapter if adapter is running
-	 */
+	  Stop Adapter if adapter is running
+	*/
 	if (a->xdi_adapter.Initialized) {
 		diva_pri_stop_adapter(a);
 	}
 
 	/*
-	   Remove ISR Handler
-	 */
+	  Remove ISR Handler
+	*/
 	if (a->xdi_adapter.irq_info.registered) {
 		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
 	}
 	a->xdi_adapter.irq_info.registered = 0;
 
 	/*
-	   Step 1: unmap all BAR's, if any was mapped
-	 */
+	  Step 1: unmap all BAR's, if any was mapped
+	*/
 	for (bar = 0; bar < 5; bar++) {
 		if (a->resources.pci.bar[bar]
 		    && a->resources.pci.addr[bar]) {
@@ -289,8 +289,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	}
 
 	/*
-	   Free OS objects
-	 */
+	  Free OS objects
+	*/
 	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
 	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
 
@@ -301,8 +301,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 	diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
 
 	/*
-	   Free memory accupied by XDI adapter
-	 */
+	  Free memory accupied by XDI adapter
+	*/
 	if (a->xdi_adapter.e_tbl) {
 		diva_os_free(0, a->xdi_adapter.e_tbl);
 		a->xdi_adapter.e_tbl = NULL;
@@ -312,8 +312,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 
 
 	/*
-	   Free adapter DMA map
-	 */
+	  Free adapter DMA map
+	*/
 	diva_free_dma_map(a->resources.pci.hdev,
 			  (struct _diva_dma_map_entry *) a->xdi_adapter.
 			  dma_map);
@@ -321,8 +321,8 @@ static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 
 
 	/*
-	   Detach this adapter from debug driver
-	 */
+	  Detach this adapter from debug driver
+	*/
 
 	return (0);
 }
@@ -341,7 +341,7 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
 	if (IoAdapter->Initialized) {
 		DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
 			 IoAdapter->ANum))
-		return (-1);
+			return (-1);
 	}
 
 	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
@@ -360,20 +360,20 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
 		DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
 			 IoAdapter->ANum, IoAdapter->serialNo))
-		return (-1);
+			return (-1);
 	}
 	if (READ_DWORD(&boot->err)) {
 		DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
 			 IoAdapter->ANum, IoAdapter->serialNo,
 			 READ_DWORD(&boot->err)))
-		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
 		return (-1);
 	}
 	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
 
 	/*
-	   Forget all outstanding entities
-	 */
+	  Forget all outstanding entities
+	*/
 	IoAdapter->e_count = 0;
 	if (IoAdapter->e_tbl) {
 		memset(IoAdapter->e_tbl, 0x00,
@@ -407,7 +407,7 @@ static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
 static int
 diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 			   dword address,
-			   const byte * data, dword length, dword limit)
+			   const byte *data, dword length, dword limit)
 {
 	byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
 	byte __iomem *mem = p;
@@ -416,7 +416,7 @@ diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
 		DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
 			 IoAdapter->ANum, address + length))
-		return (-1);
+			return (-1);
 	}
 	mem += address;
 
@@ -443,20 +443,20 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
 		DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
 			 IoAdapter->ANum))
-		return (-1);
+			return (-1);
 	}
 	if (!boot) {
 		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
 		DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
 			 IoAdapter->serialNo))
-		return (-1);
+			return (-1);
 	}
 
 	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
 	DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
 		 start_address))
 
-	WRITE_DWORD(&boot->addr, start_address);
+		WRITE_DWORD(&boot->addr, start_address);
 	WRITE_DWORD(&boot->cmd, 3);
 
 	for (i = 0; i < 300; ++i) {
@@ -464,7 +464,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
 		if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
 			DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
 				 IoAdapter->ANum, (i / 100), (i % 100)))
-			started = 1;
+				started = 1;
 			break;
 		}
 	}
@@ -478,7 +478,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
 		DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
 			 IoAdapter->ANum, READ_DWORD(&boot->signature),
 			 TrapId, debug))
-		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
+			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
 		if (IoAdapter->trapFnc) {
 			(*(IoAdapter->trapFnc)) (IoAdapter);
 		}
@@ -490,11 +490,11 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
 	IoAdapter->Initialized = true;
 
 	/*
-	   Check Interrupt
-	 */
+	  Check Interrupt
+	*/
 	IoAdapter->IrqCount = 0;
 	p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
-	WRITE_DWORD(p, (dword) ~ 0x03E00000);
+	WRITE_DWORD(p, (dword)~0x03E00000);
 	DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
 	a->ReadyInt = 1;
 	a->ram_out(a, &PR_RAM->ReadyInt, 1);
@@ -504,7 +504,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
 	if (!IoAdapter->IrqCount) {
 		DBG_ERR(("A: A(%d) interrupt test failed",
 			 IoAdapter->ANum))
-		IoAdapter->Initialized = false;
+			IoAdapter->Initialized = false;
 		IoAdapter->stop(IoAdapter);
 		return (-1);
 	}
@@ -514,21 +514,21 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
 	diva_xdi_display_adapter_features(IoAdapter->ANum);
 
 	DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
-	/*
-	   Register with DIDD
-	 */
-	diva_xdi_didd_register_adapter(IoAdapter->ANum);
+		/*
+		  Register with DIDD
+		*/
+		diva_xdi_didd_register_adapter(IoAdapter->ANum);
 
 	return (0);
 }
 
-static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a)
+static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a)
 {
 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 
 	/*
-	   clear any pending interrupt
-	 */
+	  clear any pending interrupt
+	*/
 	IoAdapter->disIrq(IoAdapter);
 
 	IoAdapter->tst_irq(&IoAdapter->a);
@@ -536,8 +536,8 @@ static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a)
 	IoAdapter->tst_irq(&IoAdapter->a);
 
 	/*
-	   kill pending dpcs
-	 */
+	  kill pending dpcs
+	*/
 	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
 	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
 }
@@ -546,7 +546,7 @@ static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a)
 **  Stop Adapter, but do not unmap/unregister - adapter
 **  will be restarted later
 */
-static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)
+static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
 {
 	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 	int i = 100;
@@ -557,18 +557,18 @@ static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)
 	if (!IoAdapter->Initialized) {
 		DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
 			 IoAdapter->ANum))
-		return (-1);	/* nothing to stop */
+			return (-1);	/* nothing to stop */
 	}
 	IoAdapter->Initialized = 0;
 
 	/*
-	   Disconnect Adapter from DIDD
-	 */
+	  Disconnect Adapter from DIDD
+	*/
 	diva_xdi_didd_remove_adapter(IoAdapter->ANum);
 
 	/*
-	   Stop interrupts
-	 */
+	  Stop interrupts
+	*/
 	a->clear_interrupts_proc = diva_pri_clear_interrupts;
 	IoAdapter->a.ReadyInt = 1;
 	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
@@ -581,12 +581,12 @@ static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)
 		a->clear_interrupts_proc = NULL;
 		DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
 			 IoAdapter->ANum))
-	}
+			}
 	IoAdapter->a.ReadyInt = 0;
 
 	/*
-	   Stop and reset adapter
-	 */
+	  Stop and reset adapter
+	*/
 	IoAdapter->stop(IoAdapter);
 
 	return (0);
@@ -600,24 +600,24 @@ static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)
 */
 static int
 diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
-		       diva_xdi_um_cfg_cmd_t * cmd, int length)
+		       diva_xdi_um_cfg_cmd_t *cmd, int length)
 {
 	int ret = -1;
 
 	if (cmd->adapter != a->controller) {
 		DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
 			 cmd->adapter, a->controller))
-		return (-1);
+			return (-1);
 	}
 
 	switch (cmd->command) {
 	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			*(dword *) a->xdi_mbox.data =
-			    (dword) a->CardOrdinal;
+				(dword) a->CardOrdinal;
 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 			ret = 0;
 		}
@@ -626,10 +626,10 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			*(dword *) a->xdi_mbox.data =
-			    (dword) a->xdi_adapter.serialNo;
+				(dword) a->xdi_adapter.serialNo;
 			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 			ret = 0;
 		}
@@ -638,7 +638,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
 		a->xdi_mbox.data_length = sizeof(dword) * 9;
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			int i;
 			dword *data = (dword *) a->xdi_mbox.data;
@@ -660,7 +660,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 		ret = diva_pri_write_sdram_block(&a->xdi_adapter,
 						 cmd->command_data.
 						 write_sdram.offset,
-						 (byte *) & cmd[1],
+						 (byte *)&cmd[1],
 						 cmd->command_data.
 						 write_sdram.length,
 						 pri_is_rev_2_card(a->
@@ -683,22 +683,22 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 
 	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
 		a->xdi_adapter.features =
-		    cmd->command_data.features.features;
+			cmd->command_data.features.features;
 		a->xdi_adapter.a.protocol_capabilities =
-		    a->xdi_adapter.features;
+			a->xdi_adapter.features;
 		DBG_TRC(("Set raw protocol features (%08x)",
 			 a->xdi_adapter.features))
-		ret = 0;
+			ret = 0;
 		break;
 
 	case DIVA_XDI_UM_CMD_GET_CARD_STATE:
 		a->xdi_mbox.data_length = sizeof(dword);
 		a->xdi_mbox.data =
-		    diva_os_malloc(0, a->xdi_mbox.data_length);
+			diva_os_malloc(0, a->xdi_mbox.data_length);
 		if (a->xdi_mbox.data) {
 			dword *data = (dword *) a->xdi_mbox.data;
 			if (!a->xdi_adapter.ram ||
-				!a->xdi_adapter.reset ||
+			    !a->xdi_adapter.reset ||
 			    !a->xdi_adapter.cfg) {
 				*data = 3;
 			} else if (a->xdi_adapter.trapped) {
@@ -720,16 +720,16 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	case DIVA_XDI_UM_CMD_READ_SDRAM:
 		if (a->xdi_adapter.Address) {
 			if (
-			    (a->xdi_mbox.data_length =
-			     cmd->command_data.read_sdram.length)) {
+				(a->xdi_mbox.data_length =
+				 cmd->command_data.read_sdram.length)) {
 				if (
-				    (a->xdi_mbox.data_length +
-				     cmd->command_data.read_sdram.offset) <
-				    a->xdi_adapter.MemorySize) {
+					(a->xdi_mbox.data_length +
+					 cmd->command_data.read_sdram.offset) <
+					a->xdi_adapter.MemorySize) {
 					a->xdi_mbox.data =
-					    diva_os_malloc(0,
-							   a->xdi_mbox.
-							   data_length);
+						diva_os_malloc(0,
+							       a->xdi_mbox.
+							       data_length);
 					if (a->xdi_mbox.data) {
 						byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
 						byte __iomem *src = p;
@@ -753,7 +753,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 	default:
 		DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
 			 cmd->command))
-	}
+			}
 
 	return (ret);
 }
@@ -761,7 +761,7 @@ diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 /*
 **  Get Serial Number
 */
-static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
+static int pri_get_serial_number(diva_os_xdi_adapter_t *a)
 {
 	byte data[64];
 	int i;
@@ -773,28 +773,28 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
 /*
  *  First set some GT6401x config registers before accessing the BOOT-ROM
  */
- 	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
 	c = READ_BYTE(&config[0xc3c]);
 	if (!(c & 0x08)) {
 		WRITE_BYTE(&config[0xc3c], c);	/* Base Address enable register */
 	}
 	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
 	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
- 	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
 /*
  *  Read only the last 64 bytes of manufacturing data
  */
 	memset(data, '\0', len);
- 	flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
+	flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
 	for (i = 0; i < len; i++) {
 		data[i] = READ_BYTE(&flash[0x8000 - len + i]);
 	}
- 	DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
+	DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
 
- 	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
 	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC);	/* Disable FLASH EPROM access */
 	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
- 	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
 
 	if (memcmp(&data[48], "DIVAserverPR", 12)) {
 #if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND)	/* { */
@@ -808,11 +808,11 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
 		addr1 = a->resources.pci.bar[1];	/* unused */
 
 		DBG_ERR(("A: apply Compaq BIOS workaround"))
-		DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-			     data[0], data[1], data[2], data[3],
-			     data[4], data[5], data[6], data[7]))
+			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+				 data[0], data[1], data[2], data[3],
+				 data[4], data[5], data[6], data[7]))
 
-		Bus = a->resources.pci.bus;
+			Bus = a->resources.pci.bus;
 		Slot = a->resources.pci.func;
 		hdev = a->resources.pci.hdev;
 		PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
@@ -832,69 +832,69 @@ static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
 		a->resources.pci.bar[4] = addr1;
 
 		/*
-		   Try to read Flash again
-		 */
+		  Try to read Flash again
+		*/
 		len = sizeof(data);
 
- 		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
 		if (!(config[0xc3c] & 0x08)) {
 			config[0xc3c] |= 0x08;	/* Base Address enable register */
 		}
 		config[LOW_BOOTCS_DREG] = 0x00;
 		config[HI_BOOTCS_DREG] = 0xFF;
- 		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
 
 		memset(data, '\0', len);
- 		flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
+		flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
 		for (i = 0; i < len; i++) {
 			data[i] = flash[0x8000 - len + i];
 		}
- 		DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
- 		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
+		DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
+		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
 		config[LOW_BOOTCS_DREG] = 0xFC;
 		config[HI_BOOTCS_DREG] = 0xFF;
- 		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
+		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
 
 		if (memcmp(&data[48], "DIVAserverPR", 12)) {
 			DBG_ERR(("A: failed to read serial number"))
-			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-				     data[0], data[1], data[2], data[3],
-				     data[4], data[5], data[6], data[7]))
-			return (-1);
+				DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+					 data[0], data[1], data[2], data[3],
+					 data[4], data[5], data[6], data[7]))
+				return (-1);
 		}
 #else				/* } { */
 		DBG_ERR(("A: failed to read DIVA signature word"))
-		DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-			     data[0], data[1], data[2], data[3],
-			     data[4], data[5], data[6], data[7]))
-		DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
-			     data[45], data[44]))
+			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+				 data[0], data[1], data[2], data[3],
+				 data[4], data[5], data[6], data[7]))
+			DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
+				 data[45], data[44]))
 #endif				/* } */
-	}
+			}
 
 	a->xdi_adapter.serialNo =
-	    (data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
-	    data[44];
+		(data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
+		data[44];
 	if (!a->xdi_adapter.serialNo
 	    || (a->xdi_adapter.serialNo == 0xffffffff)) {
 		a->xdi_adapter.serialNo = 0;
 		DBG_ERR(("A: failed to read serial number"))
-		return (-1);
+			return (-1);
 	}
 
 	DBG_LOG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
-	DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
-		     (int) data[40]))
-	DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
-		     (int) data[32]))
-	DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
-		     (int) data[36]))
+		DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
+			 (int) data[40]))
+		DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
+			 (int) data[32]))
+		DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
+			 (int) data[36]))
 
-	DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
-		     (int) ((data[28] > 90) ? 1900 : 2000) +
-		     (int) data[28], (int) data[29], (int) data[30]))
+		DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
+			 (int) ((data[28] > 90) ? 1900 : 2000) +
+			 (int) data[28], (int) data[29], (int) data[30]))
 
-	return (0);
+		return (0);
 }
 
 void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
@@ -909,7 +909,7 @@ void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
 **  Checks presence of DSP on board
 */
 static int
-dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, int dsp)
+dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
 {
 	word pattern;
 
@@ -922,7 +922,7 @@ dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, i
 	if (pattern != DSP_SIGNATURE_PROBE_WORD) {
 		DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
 			 dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
-		return (-1);
+			return (-1);
 	}
 
 	WRITE_WORD(addr, 0x4000);
@@ -931,15 +931,15 @@ dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, i
 	WRITE_WORD(addr, 0x4000);
 	pattern = READ_WORD(data);
 
-	if (pattern != (word) ~ DSP_SIGNATURE_PROBE_WORD) {
+	if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
 		DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
-			 dsp, pattern, (word) ~ DSP_SIGNATURE_PROBE_WORD))
-		return (-2);
+			 dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
+			return (-2);
 	}
 
 	DBG_TRC(("DSP[%d] present", dsp))
 
-	return (0);
+		return (0);
 }
 
 
@@ -952,7 +952,7 @@ dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, i
 **  ...
 **  Bit 29 - DSP30
 */
-static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
+static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
 {
 	byte __iomem *base;
 	byte __iomem *p;
@@ -1008,8 +1008,8 @@ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
 	diva_os_wait(5);
 
 	/*
-	   Verify modules
-	 */
+	  Verify modules
+	*/
 	for (dsp_row = 0; dsp_row < 4; dsp_row++) {
 		row_state = ((ret >> (dsp_row * 7)) & 0x7F);
 		if (row_state && (row_state != 0x7F)) {
@@ -1018,35 +1018,35 @@ static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
 					DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
 						 dsp_row + 1,
 						 dsp_index + 1))
-				}
+						}
 			}
 		}
 	}
 
 	if (!(ret & 0x10000000)) {
 		DBG_ERR(("A: ON BOARD-DSP[1] failed"))
-	}
+			}
 	if (!(ret & 0x20000000)) {
 		DBG_ERR(("A: ON BOARD-DSP[2] failed"))
-	}
+			}
 
 	/*
-	   Print module population now
-	 */
-	DBG_LOG(("+-----------------------+"))
-	DBG_LOG(("| DSP MODULE POPULATION |"))
-	DBG_LOG(("+-----------------------+"))
-	DBG_LOG(("|  1  |  2  |  3  |  4  |"))
-	DBG_LOG(("+-----------------------+"))
-	DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
-		 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
-		 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
-		 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
-		 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
+	  Print module population now
+	*/
 	DBG_LOG(("+-----------------------+"))
-
-	DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
-		 ~ret & 0x3fffffff))
-
-	return (ret);
+		DBG_LOG(("| DSP MODULE POPULATION |"))
+		DBG_LOG(("+-----------------------+"))
+		DBG_LOG(("|  1  |  2  |  3  |  4  |"))
+		DBG_LOG(("+-----------------------+"))
+		DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
+			 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
+			 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
+			 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
+			 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
+		DBG_LOG(("+-----------------------+"))
+
+		DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
+			 ~ret & 0x3fffffff))
+
+		return (ret);
 }
diff --git a/drivers/isdn/hardware/eicon/os_pri.h b/drivers/isdn/hardware/eicon/os_pri.h
index a7c42f9..537c74d 100644
--- a/drivers/isdn/hardware/eicon/os_pri.h
+++ b/drivers/isdn/hardware/eicon/os_pri.h
@@ -3,6 +3,6 @@
 #ifndef __DIVA_OS_PRI_REV_1_H__
 #define __DIVA_OS_PRI_REV_1_H__
 
-int diva_pri_init_card(diva_os_xdi_adapter_t * a);
+int diva_pri_init_card(diva_os_xdi_adapter_t *a);
 
 #endif
diff --git a/drivers/isdn/hardware/eicon/pc.h b/drivers/isdn/hardware/eicon/pc.h
index bf6b018..889dc98 100644
--- a/drivers/isdn/hardware/eicon/pc.h
+++ b/drivers/isdn/hardware/eicon/pc.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 PC_H_INCLUDED  /* { */
@@ -29,42 +29,42 @@
 /* buffer definition                                                */
 /*------------------------------------------------------------------*/
 typedef struct {
-  word length;          /* length of data/parameter field           */
-  byte P[270];          /* data/parameter field                     */
+	word length;          /* length of data/parameter field           */
+	byte P[270];          /* data/parameter field                     */
 } PBUFFER;
 /*------------------------------------------------------------------*/
 /* dual port ram structure                                          */
 /*------------------------------------------------------------------*/
 struct dual
 {
-  byte Req;             /* request register                         */
-  byte ReqId;           /* request task/entity identification       */
-  byte Rc;              /* return code register                     */
-  byte RcId;            /* return code task/entity identification   */
-  byte Ind;             /* Indication register                      */
-  byte IndId;           /* Indication task/entity identification    */
-  byte IMask;           /* Interrupt Mask Flag                      */
-  byte RNR;             /* Receiver Not Ready (set by PC)           */
-  byte XLock;           /* XBuffer locked Flag                      */
-  byte Int;             /* ISDN-S interrupt                         */
-  byte ReqCh;           /* Channel field for layer-3 Requests       */
-  byte RcCh;            /* Channel field for layer-3 Returncodes    */
-  byte IndCh;           /* Channel field for layer-3 Indications    */
-  byte MInd;            /* more data indication field               */
-  word MLength;         /* more data total packet length            */
-  byte ReadyInt;        /* request field for ready interrupt        */
-  byte SWReg;           /* Software register for special purposes   */
-  byte Reserved[11];    /* reserved space                           */
-  byte InterfaceType;   /* interface type 1=16K interface           */
-  word Signature;       /* ISDN-S adapter Signature (GD)            */
-  PBUFFER XBuffer;      /* Transmit Buffer                          */
-  PBUFFER RBuffer;      /* Receive Buffer                           */
+	byte Req;             /* request register                         */
+	byte ReqId;           /* request task/entity identification       */
+	byte Rc;              /* return code register                     */
+	byte RcId;            /* return code task/entity identification   */
+	byte Ind;             /* Indication register                      */
+	byte IndId;           /* Indication task/entity identification    */
+	byte IMask;           /* Interrupt Mask Flag                      */
+	byte RNR;             /* Receiver Not Ready (set by PC)           */
+	byte XLock;           /* XBuffer locked Flag                      */
+	byte Int;             /* ISDN-S interrupt                         */
+	byte ReqCh;           /* Channel field for layer-3 Requests       */
+	byte RcCh;            /* Channel field for layer-3 Returncodes    */
+	byte IndCh;           /* Channel field for layer-3 Indications    */
+	byte MInd;            /* more data indication field               */
+	word MLength;         /* more data total packet length            */
+	byte ReadyInt;        /* request field for ready interrupt        */
+	byte SWReg;           /* Software register for special purposes   */
+	byte Reserved[11];    /* reserved space                           */
+	byte InterfaceType;   /* interface type 1=16K interface           */
+	word Signature;       /* ISDN-S adapter Signature (GD)            */
+	PBUFFER XBuffer;      /* Transmit Buffer                          */
+	PBUFFER RBuffer;      /* Receive Buffer                           */
 };
 /*------------------------------------------------------------------*/
 /* SWReg Values (0 means no command)                                */
 /*------------------------------------------------------------------*/
 #define SWREG_DIE_WITH_LEDON  0x01
-#define SWREG_HALT_CPU        0x02 /* Push CPU into a while(1) loop */
+#define SWREG_HALT_CPU        0x02 /* Push CPU into a while (1) loop */
 /*------------------------------------------------------------------*/
 /* Id Fields Coding                                                 */
 /*------------------------------------------------------------------*/
@@ -273,7 +273,7 @@ struct dual
 #define MORE 0xa0               /* more data                        */
 #define SDNCMPL 0xa1            /* sending complete                 */
 #define CL 0xb0                 /* congestion level                 */
-        /* codeset 0                                                */
+/* codeset 0                                                */
 #define SMSG 0x00               /* segmented message                */
 #define BC  0x04                /* Bearer Capability                */
 #define CAU 0x08                /* cause                            */
@@ -307,7 +307,7 @@ struct dual
 #define NLC 0x21                /* network layer configuration      */
 #define REDIRECT_IE     0x22    /* redirection request/indication data */
 #define REDIRECT_NET_IE 0x23    /* redirection network override data   */
-        /* codeset 6                                                */
+/* codeset 6                                                */
 #define SIN 0x01                /* service indicator                */
 #define CIF 0x02                /* charging information             */
 #define DATE 0x03               /* date                             */
@@ -387,13 +387,13 @@ struct dual
 #define SMASK_CCNR                 0x00000200
 #define SMASK_CONF                 0x00000400
 /* ----------------------------------------------
-    Types of transfers used to transfer the
-    information in the 'struct RC->Reserved2[8]'
-    The information is transferred as 2 dwords
-    (2 4Byte unsigned values)
-    First of them is the transfer type.
-    2^32-1 possible messages are possible in this way.
-    The context of the second one had no meaning
+   Types of transfers used to transfer the
+   information in the 'struct RC->Reserved2[8]'
+   The information is transferred as 2 dwords
+   (2 4Byte unsigned values)
+   First of them is the transfer type.
+   2^32-1 possible messages are possible in this way.
+   The context of the second one had no meaning
    ---------------------------------------------- */
 #define DIVA_RC_TYPE_NONE              0x00000000
 #define DIVA_RC_TYPE_REMOVE_COMPLETE   0x00000008
@@ -402,14 +402,14 @@ struct dual
 #define DIVA_RC_TYPE_OK_FC             0x0000000b
 #define DIVA_RC_TYPE_RX_DMA            0x0000000c
 /* ------------------------------------------------------
-      IO Control codes for IN BAND SIGNALING
+   IO Control codes for IN BAND SIGNALING
    ------------------------------------------------------ */
 #define CTRL_L1_SET_SIG_ID        5
 #define CTRL_L1_SET_DAD           6
 #define CTRL_L1_RESOURCES         7
 /* ------------------------------------------------------ */
 /* ------------------------------------------------------
-      Layer 2 types
+   Layer 2 types
    ------------------------------------------------------ */
 #define X75T            1       /* x.75 for ttx                     */
 #define TRF             2       /* transparent with hdlc framing    */
@@ -439,31 +439,31 @@ struct dual
 #define PIAFS_UDATA_ABILITY_DCDON 0x01
 #define PIAFS_UDATA_ABILITY_DDI   0x80
 /*
-DLC of PIAFS :
-Byte | 8 7 6 5 4 3 2 1
------+--------------------------------------------------------
-   0 | 0 0 1 0 0 0 0 0  Data Link Configuration
-   1 | X X X X X X X X  Length of IE (at least 15 Bytes)
-   2 | 0 0 0 0 0 0 0 0  max. information field, LOW  byte (not used, fix 73 Bytes)
-   3 | 0 0 0 0 0 0 0 0  max. information field, HIGH byte (not used, fix 73 Bytes)
-   4 | 0 0 0 0 0 0 0 0  address A (not used)
-   5 | 0 0 0 0 0 0 0 0  address B (not used)
-   6 | 0 0 0 0 0 0 0 0  Mode (not used, fix 128)
-   7 | 0 0 0 0 0 0 0 0  Window Size (not used, fix 127)
-   8 | X X X X X X X X  XID Length, Low Byte (at least 7 Bytes)
-   9 | X X X X X X X X  XID Length, High Byte
+  DLC of PIAFS :
+  Byte | 8 7 6 5 4 3 2 1
+  -----+--------------------------------------------------------
+  0 | 0 0 1 0 0 0 0 0  Data Link Configuration
+  1 | X X X X X X X X  Length of IE (at least 15 Bytes)
+  2 | 0 0 0 0 0 0 0 0  max. information field, LOW  byte (not used, fix 73 Bytes)
+  3 | 0 0 0 0 0 0 0 0  max. information field, HIGH byte (not used, fix 73 Bytes)
+  4 | 0 0 0 0 0 0 0 0  address A (not used)
+  5 | 0 0 0 0 0 0 0 0  address B (not used)
+  6 | 0 0 0 0 0 0 0 0  Mode (not used, fix 128)
+  7 | 0 0 0 0 0 0 0 0  Window Size (not used, fix 127)
+  8 | X X X X X X X X  XID Length, Low Byte (at least 7 Bytes)
+  9 | X X X X X X X X  XID Length, High Byte
   10 | 0 0 0 0 0 C V S  PIAFS Protocol Speed configuration -> Note(1)
-     |                  S = 0 -> Protocol Speed is 32K
-     |                  S = 1 -> Protocol Speed is 64K
-     |                  V = 0 -> Protocol Speed is fixed
-     |                  V = 1 -> Protocol Speed is variable
-     |                  C = 0 -> speed setting according to standard
-     |                  C = 1 -> speed setting for chinese implementation
+  |                  S = 0 -> Protocol Speed is 32K
+  |                  S = 1 -> Protocol Speed is 64K
+  |                  V = 0 -> Protocol Speed is fixed
+  |                  V = 1 -> Protocol Speed is variable
+  |                  C = 0 -> speed setting according to standard
+  |                  C = 1 -> speed setting for chinese implementation
   11 | 0 0 0 0 0 0 R T  P0 - V42bis Compression enable/disable, Low Byte
-     |                  T = 0 -> Transmit Direction enable
-     |                  T = 1 -> Transmit Direction disable
-     |                  R = 0 -> Receive  Direction enable
-     |                  R = 1 -> Receive  Direction disable
+  |                  T = 0 -> Transmit Direction enable
+  |                  T = 1 -> Transmit Direction disable
+  |                  R = 0 -> Receive  Direction enable
+  |                  R = 1 -> Receive  Direction disable
   13 | 0 0 0 0 0 0 0 0  P0 - V42bis Compression enable/disable, High Byte
   14 | X X X X X X X X  P1 - V42bis Dictionary Size, Low Byte
   15 | X X X X X X X X  P1 - V42bis Dictionary Size, High Byte
@@ -472,61 +472,61 @@ Byte | 8 7 6 5 4 3 2 1
   18 | X X X X X X X X  PIAFS extension length
   19 | 1 0 0 0 0 0 0 0  PIAFS extension Id (0x80) - UDATA abilities
   20 | U 0 0 0 0 0 0 D  UDATA abilities -> Note (2)
-     |                  up to now the following Bits are defined:
-     |                  D - signal DCD ON
-     |                  U - use extensive UDATA control communication
-     |                      for DDI test application
-+ Note (1): ----------+------+-----------------------------------------+
-| PIAFS Protocol      | Bit  |                                         |
-| Speed configuration |    S | Bit 1 - Protocol Speed                  |
-|                     |      |         0 - 32K                         |
-|                     |      |         1 - 64K (default)               |
-|                     |    V | Bit 2 - Variable Protocol Speed         |
-|                     |      |         0 - Speed is fix                |
-|                     |      |         1 - Speed is variable (default) |
-|                     |      |             OVERWRITES 32k Bit 1        |
-|                     |    C | Bit 3   0 - Speed Settings according to |
-|                     |      |             PIAFS specification         |
-|                     |      |         1 - Speed setting for chinese   |
-|                     |      |             PIAFS implementation        |
-|                     |      | Explanation for chinese speed settings: |
-|                     |      |         if Bit 3 is set the following   |
-|                     |      |         rules apply:                    |
-|                     |      |         Bit1=0 Bit2=0: 32k fix          |
-|                     |      |         Bit1=1 Bit2=0: 64k fix          |
-|                     |      |         Bit1=0 Bit2=1: PIAFS is trying  |
-|                     |      |             to negotiate 32k is that is |
-|                     |      |             not possible it tries to    |
-|                     |      |             negotiate 64k               |
-|                     |      |         Bit1=1 Bit2=1: PIAFS is trying  |
-|                     |      |             to negotiate 64k is that is |
-|                     |      |             not possible it tries to    |
-|                     |      |             negotiate 32k               |
-+ Note (2): ----------+------+-----------------------------------------+
-| PIAFS               | Bit  | this byte defines the usage of UDATA    |
-| Implementation      |      | control communication                   |
-| UDATA usage         |    D | Bit 1 - DCD-ON signalling               |
-|                     |      |         0 - no DCD-ON is signalled      |
-|                     |      |             (default)                   |
-|                     |      |         1 - DCD-ON will be signalled    |
-|                     |    U | Bit 8 - DDI test application UDATA      |
-|                     |      |         control communication           |
-|                     |      |         0 - no UDATA control            |
-|                     |      |             communication (default)     |
-|                     |      |             sets as well the DCD-ON     |
-|                     |      |             signalling                  |
-|                     |      |         1 - UDATA control communication |
-|                     |      |             ATTENTION: Do not use these |
-|                     |      |                        setting if you   |
-|                     |      |                        are not really   |
-|                     |      |                        that you need it |
-|                     |      |                        and you know     |
-|                     |      |                        exactly what you |
-|                     |      |                        are doing.       |
-|                     |      |                        You can easily   |
-|                     |      |                        disable any      |
-|                     |      |                        data transfer.   |
-+---------------------+------+-----------------------------------------+
+  |                  up to now the following Bits are defined:
+  |                  D - signal DCD ON
+  |                  U - use extensive UDATA control communication
+  |                      for DDI test application
+  + Note (1): ----------+------+-----------------------------------------+
+  | PIAFS Protocol      | Bit  |                                         |
+  | Speed configuration |    S | Bit 1 - Protocol Speed                  |
+  |                     |      |         0 - 32K                         |
+  |                     |      |         1 - 64K (default)               |
+  |                     |    V | Bit 2 - Variable Protocol Speed         |
+  |                     |      |         0 - Speed is fix                |
+  |                     |      |         1 - Speed is variable (default) |
+  |                     |      |             OVERWRITES 32k Bit 1        |
+  |                     |    C | Bit 3   0 - Speed Settings according to |
+  |                     |      |             PIAFS specification         |
+  |                     |      |         1 - Speed setting for chinese   |
+  |                     |      |             PIAFS implementation        |
+  |                     |      | Explanation for chinese speed settings: |
+  |                     |      |         if Bit 3 is set the following   |
+  |                     |      |         rules apply:                    |
+  |                     |      |         Bit1=0 Bit2=0: 32k fix          |
+  |                     |      |         Bit1=1 Bit2=0: 64k fix          |
+  |                     |      |         Bit1=0 Bit2=1: PIAFS is trying  |
+  |                     |      |             to negotiate 32k is that is |
+  |                     |      |             not possible it tries to    |
+  |                     |      |             negotiate 64k               |
+  |                     |      |         Bit1=1 Bit2=1: PIAFS is trying  |
+  |                     |      |             to negotiate 64k is that is |
+  |                     |      |             not possible it tries to    |
+  |                     |      |             negotiate 32k               |
+  + Note (2): ----------+------+-----------------------------------------+
+  | PIAFS               | Bit  | this byte defines the usage of UDATA    |
+  | Implementation      |      | control communication                   |
+  | UDATA usage         |    D | Bit 1 - DCD-ON signalling               |
+  |                     |      |         0 - no DCD-ON is signalled      |
+  |                     |      |             (default)                   |
+  |                     |      |         1 - DCD-ON will be signalled    |
+  |                     |    U | Bit 8 - DDI test application UDATA      |
+  |                     |      |         control communication           |
+  |                     |      |         0 - no UDATA control            |
+  |                     |      |             communication (default)     |
+  |                     |      |             sets as well the DCD-ON     |
+  |                     |      |             signalling                  |
+  |                     |      |         1 - UDATA control communication |
+  |                     |      |             ATTENTION: Do not use these |
+  |                     |      |                        setting if you   |
+  |                     |      |                        are not really   |
+  |                     |      |                        that you need it |
+  |                     |      |                        and you know     |
+  |                     |      |                        exactly what you |
+  |                     |      |                        are doing.       |
+  |                     |      |                        You can easily   |
+  |                     |      |                        disable any      |
+  |                     |      |                        data transfer.   |
+  +---------------------+------+-----------------------------------------+
 */
 /* ------------------------------------------------------
    LISTENER DLC DEFINITIONS
@@ -712,11 +712,11 @@ Byte | 8 7 6 5 4 3 2 1
 /*#define RESERVED85                0x85*/
 #define ADVICE_OF_CHARGE          0x86
 /*1111 0001
-to
-1111 1111
-F1H - Reserved for network operator use
-to
-FFH*/
+  to
+  1111 1111
+  F1H - Reserved for network operator use
+  to
+  FFH*/
 /* Parameter Types */
 #define DATE_AND_TIME                                           1
 #define CLI_PARAMETER_TYPE                                      2
diff --git a/drivers/isdn/hardware/eicon/pc_init.h b/drivers/isdn/hardware/eicon/pc_init.h
index a616fc9..d1d0086 100644
--- a/drivers/isdn/hardware/eicon/pc_init.h
+++ b/drivers/isdn/hardware/eicon/pc_init.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 PC_INIT_H_
@@ -57,15 +57,15 @@
   0x0060          length (8)
   0x0061          RBS Answer Delay
   0x0062          RBS Config Bit 3, 4:
-                             0  0 -> Wink Start
-                             1  0 -> Loop Start
-                             0  1 -> Ground Start
-                             1  1 -> reserved
-                             Bit 5, 6:
-                             0  0 -> Pulse Dial -> Rotary
-                             1  0 -> DTMF
-                             0  1 -> MF
-                             1  1 -> reserved
+  0  0 -> Wink Start
+  1  0 -> Loop Start
+  0  1 -> Ground Start
+  1  1 -> reserved
+  Bit 5, 6:
+  0  0 -> Pulse Dial -> Rotary
+  1  0 -> DTMF
+  0  1 -> MF
+  1  1 -> reserved
   0x0063          RBS RX Digit Timeout
   0x0064          RBS Bearer Capability
   0x0065-0x0069   RBS Debug Mask
diff --git a/drivers/isdn/hardware/eicon/pc_maint.h b/drivers/isdn/hardware/eicon/pc_maint.h
index 352ab8d..496f018 100644
--- a/drivers/isdn/hardware/eicon/pc_maint.h
+++ b/drivers/isdn/hardware/eicon/pc_maint.h
@@ -1,31 +1,31 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 #ifdef PLATFORM_GT_32BIT
 /* #define POINTER_32BIT byte * __ptr32 */
-#define POINTER_32BIT dword 
+#define POINTER_32BIT dword
 #else
 #define POINTER_32BIT byte *
 #endif
@@ -70,91 +70,91 @@
 #define NO_EVENT 1
 struct DSigStruc
 {
-  byte Id;
-  byte u;
-  byte listen;
-  byte active;
-  byte sin[3];
-  byte bc[6];
-  byte llc[6];
-  byte hlc[6];
-  byte oad[20];
+	byte Id;
+	byte u;
+	byte listen;
+	byte active;
+	byte sin[3];
+	byte bc[6];
+	byte llc[6];
+	byte hlc[6];
+	byte oad[20];
 };
 struct BL1Struc {
-  dword cx_b1;
-  dword cx_b2;
-  dword cr_b1;
-  dword cr_b2;
-  dword px_b1;
-  dword px_b2;
-  dword pr_b1;
-  dword pr_b2;
-  word er_b1;
-  word er_b2;
+	dword cx_b1;
+	dword cx_b2;
+	dword cr_b1;
+	dword cr_b2;
+	dword px_b1;
+	dword px_b2;
+	dword pr_b1;
+	dword pr_b2;
+	word er_b1;
+	word er_b2;
 };
 struct L2Struc {
-  dword XTotal;
-  dword RTotal;
-  word XError;
-  word RError;
+	dword XTotal;
+	dword RTotal;
+	word XError;
+	word RError;
 };
 struct OSStruc {
-  dword free_n;
+	dword free_n;
 };
 typedef union
 {
-  struct DSigStruc DSigStats;
-  struct BL1Struc BL1Stats;
-  struct L2Struc L2Stats;
-  struct OSStruc OSStats;
-  byte   b[BUFFER_SZ];
-  word   w[BUFFER_SZ>>1];
-  word   l[BUFFER_SZ>>2]; /* word is wrong, do not use! Use 'd' instead. */
-  dword  d[BUFFER_SZ>>2];
+	struct DSigStruc DSigStats;
+	struct BL1Struc BL1Stats;
+	struct L2Struc L2Stats;
+	struct OSStruc OSStats;
+	byte   b[BUFFER_SZ];
+	word   w[BUFFER_SZ >> 1];
+	word   l[BUFFER_SZ >> 2]; /* word is wrong, do not use! Use 'd' instead. */
+	dword  d[BUFFER_SZ >> 2];
 } BUFFER;
 typedef union
 {
-  struct DSigStruc DSigStats;
-  struct BL1Struc BL1Stats;
-  struct L2Struc L2Stats;
-  struct OSStruc OSStats;
-  byte   b[MIPS_BUFFER_SZ];
-  word   w[MIPS_BUFFER_SZ>>1];
-  word   l[BUFFER_SZ>>2]; /* word is wrong, do not use! Use 'd' instead. */
-  dword  d[MIPS_BUFFER_SZ>>2];
+	struct DSigStruc DSigStats;
+	struct BL1Struc BL1Stats;
+	struct L2Struc L2Stats;
+	struct OSStruc OSStats;
+	byte   b[MIPS_BUFFER_SZ];
+	word   w[MIPS_BUFFER_SZ >> 1];
+	word   l[BUFFER_SZ >> 2]; /* word is wrong, do not use! Use 'd' instead. */
+	dword  d[MIPS_BUFFER_SZ >> 2];
 } MIPS_BUFFER;
 #if !defined(MIPS_SCOM)
 struct pc_maint
 {
-  byte req;
-  byte rc;
-  POINTER_32BIT mem;
-  short length;
-  word port;
-  byte fill[6];
-  BUFFER data;
+	byte req;
+	byte rc;
+	POINTER_32BIT mem;
+	short length;
+	word port;
+	byte fill[6];
+	BUFFER data;
 };
 #else
 struct pc_maint
 {
-  byte req;
-  byte rc;
-  byte reserved[2];     /* R3000 alignment ... */
-  POINTER_32BIT mem;
-  short length;
-  word port;
-  byte fill[4];         /* data at offset 16   */
-  BUFFER data;
+	byte req;
+	byte rc;
+	byte reserved[2];     /* R3000 alignment ... */
+	POINTER_32BIT mem;
+	short length;
+	word port;
+	byte fill[4];         /* data at offset 16   */
+	BUFFER data;
 };
 #endif
 struct mi_pc_maint
 {
-  byte req;
-  byte rc;
-  byte reserved[2];     /* R3000 alignment ... */
-  POINTER_32BIT mem;
-  short length;
-  word port;
-  byte fill[4];         /* data at offset 16   */
-  MIPS_BUFFER data;
+	byte req;
+	byte rc;
+	byte reserved[2];     /* R3000 alignment ... */
+	POINTER_32BIT mem;
+	short length;
+	word port;
+	byte fill[4];         /* data at offset 16   */
+	MIPS_BUFFER data;
 };
diff --git a/drivers/isdn/hardware/eicon/pkmaint.h b/drivers/isdn/hardware/eicon/pkmaint.h
index 722f85f..cf3fb14 100644
--- a/drivers/isdn/hardware/eicon/pkmaint.h
+++ b/drivers/isdn/hardware/eicon/pkmaint.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_XDI_OS_DEPENDENT_PACK_MAIN_ON_BYTE_INC__
@@ -28,17 +28,16 @@
 
 
 /*
-	Only one purpose of this compiler dependent file to pack
-	structures, described in pc_maint.h so that no padding
-	will be included.
+  Only one purpose of this compiler dependent file to pack
+  structures, described in pc_maint.h so that no padding
+  will be included.
 
-	With microsoft compile it is done by "pshpack1.h" and
-	after is restored by "poppack.h"
-	*/
+  With microsoft compile it is done by "pshpack1.h" and
+  after is restored by "poppack.h"
+*/
 
 
 #include "pc_maint.h"
 
 
 #endif
-
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index 15d4942..7331c3b 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -1,10 +1,10 @@
 /* $Id: platform.h,v 1.37.4.6 2005/01/31 12:22:20 armin Exp $
  *
  * platform.h
- * 
+ *
  *
  * Copyright 2000-2003  by Armin Schindler (mac@melware.de)
- * Copyright 2000  Eicon Networks 
+ * Copyright 2000  Eicon Networks
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -112,40 +112,40 @@
 #define DIVA_OS_MEM_ATTACH_CONFIG(a)	((a)->Config)
 #define DIVA_OS_MEM_ATTACH_CONTROL(a)	((a)->Control)
 
-#define DIVA_OS_MEM_DETACH_RAM(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_PORT(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_PROM(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_CTLREG(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_RESET(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_CFG(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_ADDRESS(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_CONFIG(a, x)	do { } while(0)
-#define DIVA_OS_MEM_DETACH_CONTROL(a, x)	do { } while(0)
+#define DIVA_OS_MEM_DETACH_RAM(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_PORT(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_PROM(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_CTLREG(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_RESET(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_CFG(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_ADDRESS(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_CONFIG(a, x)	do { } while (0)
+#define DIVA_OS_MEM_DETACH_CONTROL(a, x)	do { } while (0)
 
 #define DIVA_INVALID_FILE_HANDLE  ((dword)(-1))
 
-#define DIVAS_CONTAINING_RECORD(address, type, field) \
-        ((type *)((char*)(address) - (char*)(&((type *)0)->field)))
+#define DIVAS_CONTAINING_RECORD(address, type, field)			\
+	((type *)((char *)(address) - (char *)(&((type *)0)->field)))
 
-extern int sprintf(char *, const char*, ...);
+extern int sprintf(char *, const char *, ...);
 
-typedef void* LIST_ENTRY;
+typedef void *LIST_ENTRY;
 
-typedef char    DEVICE_NAME[64];
-typedef struct _ISDN_ADAPTER   ISDN_ADAPTER;
-typedef struct _ISDN_ADAPTER* PISDN_ADAPTER;
+typedef char DEVICE_NAME[64];
+typedef struct _ISDN_ADAPTER ISDN_ADAPTER;
+typedef struct _ISDN_ADAPTER *PISDN_ADAPTER;
 
-typedef void (* DIVA_DI_PRINTF) (unsigned char *, ...);
+typedef void (*DIVA_DI_PRINTF)(unsigned char *, ...);
 #include "debuglib.h"
 
 #define dtrc(p) DBG_PRV0(p)
-#define dbug(a,p) DBG_PRV1(p)
+#define dbug(a, p) DBG_PRV1(p)
 
 
-typedef struct e_info_s E_INFO ;
+typedef struct e_info_s E_INFO;
 
 typedef char diva_os_dependent_devica_name_t[64];
-typedef void* PDEVICE_OBJECT;
+typedef void *PDEVICE_OBJECT;
 
 struct _diva_os_soft_isr;
 struct _diva_os_timer;
@@ -156,13 +156,13 @@ void diva_log_info(unsigned char *, ...);
 /*
 **  XDI DIDD Interface
 */
-void diva_xdi_didd_register_adapter (int card);
-void diva_xdi_didd_remove_adapter (int card);
+void diva_xdi_didd_register_adapter(int card);
+void diva_xdi_didd_remove_adapter(int card);
 
 /*
 ** memory allocation
 */
-static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size)
+static __inline__ void *diva_os_malloc(unsigned long flags, unsigned long size)
 {
 	void *ret = NULL;
 
@@ -171,7 +171,7 @@ static __inline__ void* diva_os_malloc (unsigned long flags, unsigned long size)
 	}
 	return (ret);
 }
-static __inline__ void  diva_os_free   (unsigned long flags, void* ptr)
+static __inline__ void diva_os_free(unsigned long flags, void *ptr)
 {
 	vfree(ptr);
 }
@@ -200,34 +200,34 @@ static __inline__ void diva_os_wait(dword mSec)
 /*
 **  PCI Configuration space access
 */
-void PCIwrite (byte bus, byte func, int offset, void* data, int length, void* pci_dev_handle);
-void PCIread (byte bus, byte func, int offset, void* data, int length, void* pci_dev_handle);
+void PCIwrite(byte bus, byte func, int offset, void *data, int length, void *pci_dev_handle);
+void PCIread(byte bus, byte func, int offset, void *data, int length, void *pci_dev_handle);
 
 /*
 **  I/O Port utilities
 */
-int diva_os_register_io_port (void *adapter, int register, unsigned long port,
-				unsigned long length, const char* name, int id);
+int diva_os_register_io_port(void *adapter, int register, unsigned long port,
+			     unsigned long length, const char *name, int id);
 /*
 **  I/O port access abstraction
 */
-byte inpp (void __iomem *);
-word inppw (void __iomem *);
-void inppw_buffer (void __iomem *, void*, int);
-void outppw (void __iomem *, word);
-void outppw_buffer (void __iomem * , void*, int);
-void outpp (void __iomem *, word);
+byte inpp(void __iomem *);
+word inppw(void __iomem *);
+void inppw_buffer(void __iomem *, void *, int);
+void outppw(void __iomem *, word);
+void outppw_buffer(void __iomem * , void*, int);
+void outpp(void __iomem *, word);
 
 /*
-**  IRQ 
+**  IRQ
 */
 typedef struct _diva_os_adapter_irq_info {
-        byte irq_nr;
-        int  registered;
-        char irq_name[24];
+	byte irq_nr;
+	int  registered;
+	char irq_name[24];
 } diva_os_adapter_irq_info_t;
-int diva_os_register_irq (void* context, byte irq, const char* name);
-void diva_os_remove_irq (void* context, byte irq);
+int diva_os_register_irq(void *context, byte irq, const char *name);
+void diva_os_remove_irq(void *context, byte irq);
 
 #define diva_os_in_irq() in_irq()
 
@@ -236,58 +236,58 @@ void diva_os_remove_irq (void* context, byte irq);
 */
 typedef long diva_os_spin_lock_magic_t;
 typedef spinlock_t diva_os_spin_lock_t;
-static __inline__ int diva_os_initialize_spin_lock (spinlock_t *lock, void * unused) { \
-  spin_lock_init (lock); return(0); }
-static __inline__ void diva_os_enter_spin_lock (diva_os_spin_lock_t* a, \
-                              diva_os_spin_lock_magic_t* old_irql, \
-                              void* dbg) { spin_lock_bh(a); }
-static __inline__ void diva_os_leave_spin_lock (diva_os_spin_lock_t* a, \
-                              diva_os_spin_lock_magic_t* old_irql, \
-                              void* dbg) { spin_unlock_bh(a); }
+static __inline__ int diva_os_initialize_spin_lock(spinlock_t *lock, void *unused) { \
+	spin_lock_init(lock); return (0); }
+static __inline__ void diva_os_enter_spin_lock(diva_os_spin_lock_t *a, \
+					       diva_os_spin_lock_magic_t *old_irql, \
+					       void *dbg) { spin_lock_bh(a); }
+static __inline__ void diva_os_leave_spin_lock(diva_os_spin_lock_t *a, \
+					       diva_os_spin_lock_magic_t *old_irql, \
+					       void *dbg) { spin_unlock_bh(a); }
 
-#define diva_os_destroy_spin_lock(a,b) do { } while(0)
+#define diva_os_destroy_spin_lock(a, b) do { } while (0)
 
 /*
 **  Deffered processing framework
 */
-typedef int (*diva_os_isr_callback_t)(struct _ISDN_ADAPTER*);
-typedef void (*diva_os_soft_isr_callback_t)(struct _diva_os_soft_isr* psoft_isr, void* context);
+typedef int (*diva_os_isr_callback_t)(struct _ISDN_ADAPTER *);
+typedef void (*diva_os_soft_isr_callback_t)(struct _diva_os_soft_isr *psoft_isr, void *context);
 
 typedef struct _diva_os_soft_isr {
-  void* object;
-  diva_os_soft_isr_callback_t callback;
-  void* callback_context;
-  char dpc_thread_name[24];
+	void *object;
+	diva_os_soft_isr_callback_t callback;
+	void *callback_context;
+	char dpc_thread_name[24];
 } diva_os_soft_isr_t;
 
-int diva_os_initialize_soft_isr (diva_os_soft_isr_t* psoft_isr, diva_os_soft_isr_callback_t callback, void*   callback_context);
-int diva_os_schedule_soft_isr (diva_os_soft_isr_t* psoft_isr);
-int diva_os_cancel_soft_isr (diva_os_soft_isr_t* psoft_isr);
-void diva_os_remove_soft_isr (diva_os_soft_isr_t* psoft_isr);
+int diva_os_initialize_soft_isr(diva_os_soft_isr_t *psoft_isr, diva_os_soft_isr_callback_t callback, void *callback_context);
+int diva_os_schedule_soft_isr(diva_os_soft_isr_t *psoft_isr);
+int diva_os_cancel_soft_isr(diva_os_soft_isr_t *psoft_isr);
+void diva_os_remove_soft_isr(diva_os_soft_isr_t *psoft_isr);
 
 /*
   Get time service
-  */
-void diva_os_get_time (dword* sec, dword* usec);
+*/
+void diva_os_get_time(dword *sec, dword *usec);
 
 /*
 **  atomic operation, fake because we use threads
 */
 typedef int diva_os_atomic_t;
 static diva_os_atomic_t __inline__
-diva_os_atomic_increment(diva_os_atomic_t* pv)
+diva_os_atomic_increment(diva_os_atomic_t *pv)
 {
-  *pv += 1;
-  return (*pv);
+	*pv += 1;
+	return (*pv);
 }
 static diva_os_atomic_t __inline__
-diva_os_atomic_decrement(diva_os_atomic_t* pv)
+diva_os_atomic_decrement(diva_os_atomic_t *pv)
 {
-  *pv -= 1;
-  return (*pv);
+	*pv -= 1;
+	return (*pv);
 }
 
-/* 
+/*
 **  CAPI SECTION
 */
 #define NO_CORNETN
@@ -319,9 +319,9 @@ diva_os_atomic_decrement(diva_os_atomic_t* pv)
 #define READ_WORD(addr)   readw(addr)
 #define READ_DWORD(addr)  readl(addr)
 
-#define WRITE_BYTE(addr,v)  writeb(v,addr)
-#define WRITE_WORD(addr,v)  writew(v,addr)
-#define WRITE_DWORD(addr,v) writel(v,addr)
+#define WRITE_BYTE(addr, v)  writeb(v, addr)
+#define WRITE_WORD(addr, v)  writew(v, addr)
+#define WRITE_DWORD(addr, v) writel(v, addr)
 
 static inline __u16 GET_WORD(void *addr)
 {
@@ -344,10 +344,10 @@ static inline void PUT_DWORD(void *addr, __u32 v)
 ** 32/64 bit macors
 */
 #ifdef BITS_PER_LONG
- #if BITS_PER_LONG > 32 
-  #define PLATFORM_GT_32BIT
-  #define ULongToPtr(x) (void *)(unsigned long)(x)
- #endif
+#if BITS_PER_LONG > 32
+#define PLATFORM_GT_32BIT
+#define ULongToPtr(x) (void *)(unsigned long)(x)
+#endif
 #endif
 
 /*
@@ -362,7 +362,7 @@ static inline void PUT_DWORD(void *addr, __u32 v)
 */
 #define diva_os_dump_file_t char
 #define diva_os_board_trace_t char
-#define diva_os_dump_file(__x__) do { } while(0)
+#define diva_os_dump_file(__x__) do { } while (0)
 
 /*
 ** size of internal arrays
diff --git a/drivers/isdn/hardware/eicon/pr_pc.h b/drivers/isdn/hardware/eicon/pr_pc.h
index bf49a5a..a08d6d5 100644
--- a/drivers/isdn/hardware/eicon/pr_pc.h
+++ b/drivers/isdn/hardware/eicon/pr_pc.h
@@ -1,76 +1,76 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
 struct pr_ram {
-  word NextReq;         /* pointer to next Req Buffer               */
-  word NextRc;          /* pointer to next Rc Buffer                */
-  word NextInd;         /* pointer to next Ind Buffer               */
-  byte ReqInput;        /* number of Req Buffers sent               */
-  byte ReqOutput;       /* number of Req Buffers returned           */
-  byte ReqReserved;     /* number of Req Buffers reserved           */
-  byte Int;             /* ISDN-P interrupt                         */
-  byte XLock;           /* Lock field for arbitration               */
-  byte RcOutput;        /* number of Rc buffers received            */
-  byte IndOutput;       /* number of Ind buffers received           */
-  byte IMask;           /* Interrupt Mask Flag                      */
-  byte Reserved1[2];    /* reserved field, do not use               */
-  byte ReadyInt;        /* request field for ready interrupt        */
-  byte Reserved2[12];   /* reserved field, do not use               */
-  byte InterfaceType;   /* interface type 1=16K interface           */
-  word Signature;       /* ISDN-P initialized indication            */
-  byte B[1];            /* buffer space for Req,Ind and Rc          */
+	word NextReq;         /* pointer to next Req Buffer               */
+	word NextRc;          /* pointer to next Rc Buffer                */
+	word NextInd;         /* pointer to next Ind Buffer               */
+	byte ReqInput;        /* number of Req Buffers sent               */
+	byte ReqOutput;       /* number of Req Buffers returned           */
+	byte ReqReserved;     /* number of Req Buffers reserved           */
+	byte Int;             /* ISDN-P interrupt                         */
+	byte XLock;           /* Lock field for arbitration               */
+	byte RcOutput;        /* number of Rc buffers received            */
+	byte IndOutput;       /* number of Ind buffers received           */
+	byte IMask;           /* Interrupt Mask Flag                      */
+	byte Reserved1[2];    /* reserved field, do not use               */
+	byte ReadyInt;        /* request field for ready interrupt        */
+	byte Reserved2[12];   /* reserved field, do not use               */
+	byte InterfaceType;   /* interface type 1=16K interface           */
+	word Signature;       /* ISDN-P initialized indication            */
+	byte B[1];            /* buffer space for Req,Ind and Rc          */
 };
 typedef struct {
-  word next;
-  byte Req;
-  byte ReqId;
-  byte ReqCh;
-  byte Reserved1;
-  word Reference;
-  byte Reserved[8];
-  PBUFFER XBuffer;
+	word next;
+	byte Req;
+	byte ReqId;
+	byte ReqCh;
+	byte Reserved1;
+	word Reference;
+	byte Reserved[8];
+	PBUFFER XBuffer;
 } REQ;
 typedef struct {
-  word next;
-  byte Rc;
-  byte RcId;
-  byte RcCh;
-  byte Reserved1;
-  word Reference;
-  byte Reserved2[8];
+	word next;
+	byte Rc;
+	byte RcId;
+	byte RcCh;
+	byte Reserved1;
+	word Reference;
+	byte Reserved2[8];
 } RC;
 typedef struct {
-  word next;
-  byte Ind;
-  byte IndId;
-  byte IndCh;
-  byte MInd;
-  word MLength;
-  word Reference;
-  byte RNR;
-  byte Reserved;
-  dword Ack;
-  PBUFFER RBuffer;
+	word next;
+	byte Ind;
+	byte IndId;
+	byte IndCh;
+	byte MInd;
+	word MLength;
+	word Reference;
+	byte RNR;
+	byte Reserved;
+	dword Ack;
+	PBUFFER RBuffer;
 } IND;
diff --git a/drivers/isdn/hardware/eicon/s_4bri.c b/drivers/isdn/hardware/eicon/s_4bri.c
index 25c5d7f..ec12165 100644
--- a/drivers/isdn/hardware/eicon/s_4bri.c
+++ b/drivers/isdn/hardware/eicon/s_4bri.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -42,13 +42,13 @@
 #define	MAX_XLOG_SIZE	(64 * 1024)
 
 /* --------------------------------------------------------------------------
-		Recovery XLOG from QBRI Card
-	 -------------------------------------------------------------------------- */
-static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
-	byte  __iomem *base ;
-	word *Xlog ;
-	dword   regs[4], TrapID, offset, size ;
-	Xdesc   xlogDesc ;
+   Recovery XLOG from QBRI Card
+   -------------------------------------------------------------------------- */
+static void qBri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
+	byte  __iomem *base;
+	word *Xlog;
+	dword   regs[4], TrapID, offset, size;
+	Xdesc   xlogDesc;
 	int factor = (IoAdapter->tasks == 1) ? 1 : 2;
 
 /*
@@ -56,211 +56,211 @@ static void qBri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
  */
 
 	base = DIVA_OS_MEM_ATTACH_CONTROL(IoAdapter);
-	offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor) ;
+	offset = IoAdapter->ControllerNumber * (IoAdapter->MemorySize >> factor);
 
-	TrapID = READ_DWORD(&base[0x80]) ;
+	TrapID = READ_DWORD(&base[0x80]);
 
-	if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
+	if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
 	{
-		dump_trap_frame (IoAdapter, &base[0x90]) ;
-		IoAdapter->trapped = 1 ;
+		dump_trap_frame(IoAdapter, &base[0x90]);
+		IoAdapter->trapped = 1;
 	}
 
 	regs[0] = READ_DWORD((base + offset) + 0x70);
 	regs[1] = READ_DWORD((base + offset) + 0x74);
 	regs[2] = READ_DWORD((base + offset) + 0x78);
 	regs[3] = READ_DWORD((base + offset) + 0x7c);
-	regs[0] &= IoAdapter->MemorySize - 1 ;
+	regs[0] &= IoAdapter->MemorySize - 1;
 
-	if ( (regs[0] >= offset)
-	  && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1) )
+	if ((regs[0] >= offset)
+	    && (regs[0] < offset + (IoAdapter->MemorySize >> factor) - 1))
 	{
-		if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
+		if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
 			DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
-			return ;
+			return;
 		}
 
-		size = offset + (IoAdapter->MemorySize >> factor) - regs[0] ;
-		if ( size > MAX_XLOG_SIZE )
-			size = MAX_XLOG_SIZE ;
-		memcpy_fromio (Xlog, &base[regs[0]], size) ;
-		xlogDesc.buf = Xlog ;
-		xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ;
-		xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ;
-		dump_xlog_buffer (IoAdapter, &xlogDesc) ;
-		diva_os_free (0, Xlog) ;
-		IoAdapter->trapped = 2 ;
+		size = offset + (IoAdapter->MemorySize >> factor) - regs[0];
+		if (size > MAX_XLOG_SIZE)
+			size = MAX_XLOG_SIZE;
+		memcpy_fromio(Xlog, &base[regs[0]], size);
+		xlogDesc.buf = Xlog;
+		xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
+		xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
+		dump_xlog_buffer(IoAdapter, &xlogDesc);
+		diva_os_free(0, Xlog);
+		IoAdapter->trapped = 2;
 	}
 	DIVA_OS_MEM_DETACH_CONTROL(IoAdapter, base);
 }
 
 /* --------------------------------------------------------------------------
-		Reset QBRI Hardware
-	 -------------------------------------------------------------------------- */
-static void reset_qBri_hardware (PISDN_ADAPTER IoAdapter) {
-	word volatile __iomem *qBriReset ;
-	byte  volatile __iomem *qBriCntrl ;
-	byte  volatile __iomem *p ;
+   Reset QBRI Hardware
+   -------------------------------------------------------------------------- */
+static void reset_qBri_hardware(PISDN_ADAPTER IoAdapter) {
+	word volatile __iomem *qBriReset;
+	byte  volatile __iomem *qBriCntrl;
+	byte  volatile __iomem *p;
 
 	qBriReset = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
-	WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET) ;
-	diva_os_wait (1) ;
-	WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET) ;
-	diva_os_wait (1);
-	WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_RELOAD_EEPROM) ;
-	diva_os_wait (1) ;
-	WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM) ;
-	diva_os_wait (1);
+	WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_SOFT_RESET);
+	diva_os_wait(1);
+	WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_SOFT_RESET);
+	diva_os_wait(1);
+	WRITE_WORD(qBriReset, READ_WORD(qBriReset) | PLX9054_RELOAD_EEPROM);
+	diva_os_wait(1);
+	WRITE_WORD(qBriReset, READ_WORD(qBriReset) & ~PLX9054_RELOAD_EEPROM);
+	diva_os_wait(1);
 	DIVA_OS_MEM_DETACH_PROM(IoAdapter, qBriReset);
 
 	qBriCntrl = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	p = &qBriCntrl[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
-	WRITE_DWORD(p, 0) ;
+	WRITE_DWORD(p, 0);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, qBriCntrl);
 
 	DBG_TRC(("resetted board @ reset addr 0x%08lx", qBriReset))
-	DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
-}
+		DBG_TRC(("resetted board @ cntrl addr 0x%08lx", p))
+		}
 
 /* --------------------------------------------------------------------------
-		Start Card CPU
-	 -------------------------------------------------------------------------- */
-void start_qBri_hardware (PISDN_ADAPTER IoAdapter) {
-	byte volatile __iomem *qBriReset ;
-	byte volatile __iomem *p ;
+   Start Card CPU
+   -------------------------------------------------------------------------- */
+void start_qBri_hardware(PISDN_ADAPTER IoAdapter) {
+	byte volatile __iomem *qBriReset;
+	byte volatile __iomem *p;
 
 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	qBriReset = &p[(DIVA_4BRI_REVISION(IoAdapter)) ? (MQ2_BREG_RISC) : (MQ_BREG_RISC)];
-	WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK) ;
-	diva_os_wait (2) ;
-	WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK) ;
-	diva_os_wait (10) ;
+	WRITE_DWORD(qBriReset, MQ_RISC_COLD_RESET_MASK);
+	diva_os_wait(2);
+	WRITE_DWORD(qBriReset, MQ_RISC_WARM_RESET_MASK | MQ_RISC_COLD_RESET_MASK);
+	diva_os_wait(10);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 
 	DBG_TRC(("started processor @ addr 0x%08lx", qBriReset))
-}
+		}
 
 /* --------------------------------------------------------------------------
-		Stop Card CPU
-	 -------------------------------------------------------------------------- */
-static void stop_qBri_hardware (PISDN_ADAPTER IoAdapter) {
-	byte volatile __iomem *p ;
-	dword volatile __iomem *qBriReset ;
-	dword volatile __iomem *qBriIrq ;
-	dword volatile __iomem *qBriIsacDspReset ;
+   Stop Card CPU
+   -------------------------------------------------------------------------- */
+static void stop_qBri_hardware(PISDN_ADAPTER IoAdapter) {
+	byte volatile __iomem *p;
+	dword volatile __iomem *qBriReset;
+	dword volatile __iomem *qBriIrq;
+	dword volatile __iomem *qBriIsacDspReset;
 	int rev2 = DIVA_4BRI_REVISION(IoAdapter);
 	int reset_offset = rev2 ? (MQ2_BREG_RISC)      : (MQ_BREG_RISC);
 	int irq_offset   = rev2 ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST);
 	int hw_offset    = rev2 ? (MQ2_ISAC_DSP_RESET) : (MQ_ISAC_DSP_RESET);
 
-	if ( IoAdapter->ControllerNumber > 0 )
-		return ;
+	if (IoAdapter->ControllerNumber > 0)
+		return;
 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	qBriReset = (dword volatile __iomem *)&p[reset_offset];
 	qBriIsacDspReset = (dword volatile __iomem *)&p[hw_offset];
 /*
  *	clear interrupt line (reset Local Interrupt Test Register)
  */
-	WRITE_DWORD(qBriReset, 0) ;
- 	WRITE_DWORD(qBriIsacDspReset, 0) ;
+	WRITE_DWORD(qBriReset, 0);
+	WRITE_DWORD(qBriIsacDspReset, 0);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
-	
+
 	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
 	WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);	/* disable PCI interrupts */
 	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
-	
+
 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	qBriIrq   = (dword volatile __iomem *)&p[irq_offset];
-	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
+	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 
 	DBG_TRC(("stopped processor @ addr 0x%08lx", qBriReset))
 
-}
+		}
 
 /* --------------------------------------------------------------------------
-		FPGA download
-	 -------------------------------------------------------------------------- */
+   FPGA download
+   -------------------------------------------------------------------------- */
 #define FPGA_NAME_OFFSET         0x10
 
-static byte * qBri_check_FPGAsrc (PISDN_ADAPTER IoAdapter, char *FileName,
-                                  dword *Length, dword *code) {
-	byte *File ;
-	char  *fpgaFile, *fpgaType, *fpgaDate, *fpgaTime ;
-	dword  fpgaFlen,  fpgaTlen,  fpgaDlen, cnt, year, i ;
+static byte *qBri_check_FPGAsrc(PISDN_ADAPTER IoAdapter, char *FileName,
+				dword *Length, dword *code) {
+	byte *File;
+	char *fpgaFile, *fpgaType, *fpgaDate, *fpgaTime;
+	dword fpgaFlen, fpgaTlen, fpgaDlen, cnt, year, i;
 
-	if (!(File = (byte *)xdiLoadFile (FileName, Length, 0))) {
-		return (NULL) ;
+	if (!(File = (byte *)xdiLoadFile(FileName, Length, 0))) {
+		return (NULL);
 	}
 /*
  *	 scan file until FF and put id string into buffer
  */
-	for ( i = 0 ; File[i] != 0xff ; )
+	for (i = 0; File[i] != 0xff;)
 	{
-		if ( ++i >= *Length )
+		if (++i >= *Length)
 		{
 			DBG_FTL(("FPGA download: start of data header not found"))
-			xdiFreeFile (File) ;
-			return (NULL) ;
+				xdiFreeFile(File);
+			return (NULL);
 		}
 	}
-	*code = i++ ;
+	*code = i++;
 
-	if ( (File[i] & 0xF0) != 0x20 )
+	if ((File[i] & 0xF0) != 0x20)
 	{
 		DBG_FTL(("FPGA download: data header corrupted"))
-		xdiFreeFile (File) ;
-		return (NULL) ;
+			xdiFreeFile(File);
+		return (NULL);
 	}
-	fpgaFlen = (dword)  File[FPGA_NAME_OFFSET - 1] ;
-	if ( fpgaFlen == 0 )
-		fpgaFlen = 12 ;
-	fpgaFile = (char *)&File[FPGA_NAME_OFFSET] ;
-	fpgaTlen = (dword)  fpgaFile[fpgaFlen + 2] ;
-	if ( fpgaTlen == 0 )
-		fpgaTlen = 10 ;
-	fpgaType = (char *)&fpgaFile[fpgaFlen + 3] ;
-	fpgaDlen = (dword)  fpgaType[fpgaTlen + 2] ;
-	if ( fpgaDlen == 0 )
-		fpgaDlen = 11 ;
-	fpgaDate = (char *)&fpgaType[fpgaTlen + 3] ;
-	fpgaTime = (char *)&fpgaDate[fpgaDlen + 3] ;
-	cnt = (dword)(((File[  i  ] & 0x0F) << 20) + (File[i + 1] << 12)
-	             + (File[i + 2]         <<  4) + (File[i + 3] >>  4)) ;
-
-	if ( (dword)(i + (cnt / 8)) > *Length )
+	fpgaFlen = (dword)File[FPGA_NAME_OFFSET - 1];
+	if (fpgaFlen == 0)
+		fpgaFlen = 12;
+	fpgaFile = (char *)&File[FPGA_NAME_OFFSET];
+	fpgaTlen = (dword)fpgaFile[fpgaFlen + 2];
+	if (fpgaTlen == 0)
+		fpgaTlen = 10;
+	fpgaType = (char *)&fpgaFile[fpgaFlen + 3];
+	fpgaDlen = (dword)  fpgaType[fpgaTlen + 2];
+	if (fpgaDlen == 0)
+		fpgaDlen = 11;
+	fpgaDate = (char *)&fpgaType[fpgaTlen + 3];
+	fpgaTime = (char *)&fpgaDate[fpgaDlen + 3];
+	cnt = (dword)(((File[i] & 0x0F) << 20) + (File[i + 1] << 12)
+		      + (File[i + 2] << 4) + (File[i + 3] >> 4));
+
+	if ((dword)(i + (cnt / 8)) > *Length)
 	{
 		DBG_FTL(("FPGA download: '%s' file too small (%ld < %ld)",
-		         FileName, *Length, code + ((cnt + 7) / 8) ))
-		xdiFreeFile (File) ;
-		return (NULL) ;
+			 FileName, *Length, code + ((cnt + 7) / 8)))
+			xdiFreeFile(File);
+		return (NULL);
 	}
-	i = 0 ;
+	i = 0;
 	do
 	{
-		while ( (fpgaDate[i] != '\0')
-		     && ((fpgaDate[i] < '0') || (fpgaDate[i] > '9')) )
+		while ((fpgaDate[i] != '\0')
+		       && ((fpgaDate[i] < '0') || (fpgaDate[i] > '9')))
 		{
 			i++;
 		}
-		year = 0 ;
-		while ( (fpgaDate[i] >= '0') && (fpgaDate[i] <= '9') )
-			year = year * 10 + (fpgaDate[i++] - '0') ;
-	} while ( (year < 2000) && (fpgaDate[i] != '\0') );
+		year = 0;
+		while ((fpgaDate[i] >= '0') && (fpgaDate[i] <= '9'))
+			year = year * 10 + (fpgaDate[i++] - '0');
+	} while ((year < 2000) && (fpgaDate[i] != '\0'));
 
 	switch (IoAdapter->cardType) {
-		case CARDTYPE_DIVASRV_B_2F_PCI:
-			break;
+	case CARDTYPE_DIVASRV_B_2F_PCI:
+		break;
 
-		default:
-	    if ( year >= 2001 ) {
-				IoAdapter->fpga_features |= PCINIT_FPGA_PLX_ACCESS_SUPPORTED ;
-			}
+	default:
+		if (year >= 2001) {
+			IoAdapter->fpga_features |= PCINIT_FPGA_PLX_ACCESS_SUPPORTED;
+		}
 	}
 
 	DBG_LOG(("FPGA[%s] file %s (%s %s) len %d",
-	         fpgaType, fpgaFile, fpgaDate, fpgaTime, cnt))
-	return (File) ;
+		 fpgaType, fpgaFile, fpgaDate, fpgaTime, cnt))
+		return (File);
 }
 
 /******************************************************************************/
@@ -272,114 +272,114 @@ static byte * qBri_check_FPGAsrc (PISDN_ADAPTER IoAdapter, char *FileName,
 #define FPGA_DOUT   0x0400
 #define FPGA_DIN    FPGA_DOUT   /* bidirectional I/O */
 
-int qBri_FPGA_download (PISDN_ADAPTER IoAdapter) {
-	int            bit ;
-	byte           *File ;
-	dword          code, FileLength ;
+int qBri_FPGA_download(PISDN_ADAPTER IoAdapter) {
+	int            bit;
+	byte           *File;
+	dword          code, FileLength;
 	word volatile __iomem *addr = (word volatile __iomem *)DIVA_OS_MEM_ATTACH_PROM(IoAdapter);
-	word           val, baseval = FPGA_CS | FPGA_PROG ;
+	word           val, baseval = FPGA_CS | FPGA_PROG;
 
 
 
 	if (DIVA_4BRI_REVISION(IoAdapter))
 	{
-		char* name;
+		char *name;
 
 		switch (IoAdapter->cardType) {
-			case CARDTYPE_DIVASRV_B_2F_PCI:
-				name = "dsbri2f.bit";
-				break;
+		case CARDTYPE_DIVASRV_B_2F_PCI:
+			name = "dsbri2f.bit";
+			break;
 
-			case CARDTYPE_DIVASRV_B_2M_V2_PCI:
-			case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
-				name = "dsbri2m.bit";
-				break;
+		case CARDTYPE_DIVASRV_B_2M_V2_PCI:
+		case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
+			name = "dsbri2m.bit";
+			break;
 
-			default:
-				name = "ds4bri2.bit";
+		default:
+			name = "ds4bri2.bit";
 		}
 
-		File = qBri_check_FPGAsrc (IoAdapter, name,
-	                           		&FileLength, &code);
+		File = qBri_check_FPGAsrc(IoAdapter, name,
+					  &FileLength, &code);
 	}
 	else
 	{
-		File = qBri_check_FPGAsrc (IoAdapter, "ds4bri.bit",
-		                           &FileLength, &code) ;
+		File = qBri_check_FPGAsrc(IoAdapter, "ds4bri.bit",
+					  &FileLength, &code);
 	}
-	if ( !File ) {
+	if (!File) {
 		DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
-		return (0) ;
+		return (0);
 	}
 /*
  *	prepare download, pulse PROGRAM pin down.
  */
-	WRITE_WORD(addr, baseval & ~FPGA_PROG) ; /* PROGRAM low pulse */
-	WRITE_WORD(addr, baseval) ;              /* release */
-	diva_os_wait (50) ;  /* wait until FPGA finished internal memory clear */
+	WRITE_WORD(addr, baseval & ~FPGA_PROG); /* PROGRAM low pulse */
+	WRITE_WORD(addr, baseval);              /* release */
+	diva_os_wait(50);  /* wait until FPGA finished internal memory clear */
 /*
  *	check done pin, must be low
  */
-	if ( READ_WORD(addr) & FPGA_BUSY )
+	if (READ_WORD(addr) & FPGA_BUSY)
 	{
 		DBG_FTL(("FPGA download: acknowledge for FPGA memory clear missing"))
-		xdiFreeFile (File) ;
+			xdiFreeFile(File);
 		DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
-		return (0) ;
+		return (0);
 	}
 /*
  *	put data onto the FPGA
  */
-	while ( code < FileLength )
+	while (code < FileLength)
 	{
-		val = ((word)File[code++]) << 3 ;
+		val = ((word)File[code++]) << 3;
 
-		for ( bit = 8 ; bit-- > 0 ; val <<= 1 ) /* put byte onto FPGA */
+		for (bit = 8; bit-- > 0; val <<= 1) /* put byte onto FPGA */
 		{
-			baseval &= ~FPGA_DOUT ;             /* clr  data bit */
-			baseval |= (val & FPGA_DOUT) ;      /* copy data bit */
-			WRITE_WORD(addr, baseval) ;
-			WRITE_WORD(addr, baseval | FPGA_CCLK) ;     /* set CCLK hi */
-			WRITE_WORD(addr, baseval | FPGA_CCLK) ;     /* set CCLK hi */
-			WRITE_WORD(addr, baseval) ;                 /* set CCLK lo */
+			baseval &= ~FPGA_DOUT;             /* clr  data bit */
+			baseval |= (val & FPGA_DOUT);      /* copy data bit */
+			WRITE_WORD(addr, baseval);
+			WRITE_WORD(addr, baseval | FPGA_CCLK);     /* set CCLK hi */
+			WRITE_WORD(addr, baseval | FPGA_CCLK);     /* set CCLK hi */
+			WRITE_WORD(addr, baseval);                 /* set CCLK lo */
 		}
 	}
-	xdiFreeFile (File) ;
-	diva_os_wait (100) ;
-	val = READ_WORD(addr) ;
+	xdiFreeFile(File);
+	diva_os_wait(100);
+	val = READ_WORD(addr);
 
 	DIVA_OS_MEM_DETACH_PROM(IoAdapter, addr);
 
-	if ( !(val & FPGA_BUSY) )
+	if (!(val & FPGA_BUSY))
 	{
 		DBG_FTL(("FPGA download: chip remains in busy state (0x%04x)", val))
-		return (0) ;
+			return (0);
 	}
 
-	return (1) ;
+	return (1);
 }
 
-static int load_qBri_hardware (PISDN_ADAPTER IoAdapter) {
+static int load_qBri_hardware(PISDN_ADAPTER IoAdapter) {
 	return (0);
 }
 
 /* --------------------------------------------------------------------------
-		Card ISR
-	 -------------------------------------------------------------------------- */
-static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
-	dword volatile     __iomem *qBriIrq ;
+   Card ISR
+   -------------------------------------------------------------------------- */
+static int qBri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
+	dword volatile     __iomem *qBriIrq;
 
-	PADAPTER_LIST_ENTRY QuadroList = IoAdapter->QuadroList ;
+	PADAPTER_LIST_ENTRY QuadroList = IoAdapter->QuadroList;
 
-	word              	i ;
-	int             	serviced = 0 ;
+	word			i;
+	int			serviced = 0;
 	byte __iomem *p;
 
 	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
 
-	if ( !(READ_BYTE(&p[PLX9054_INTCSR]) & 0x80) ) {
+	if (!(READ_BYTE(&p[PLX9054_INTCSR]) & 0x80)) {
 		DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
-		return (0) ;
+		return (0);
 	}
 	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
 
@@ -388,34 +388,34 @@ static int qBri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
  */
 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
-	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
+	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 
-	for ( i = 0 ; i < IoAdapter->tasks; ++i )
+	for (i = 0; i < IoAdapter->tasks; ++i)
 	{
-		IoAdapter = QuadroList->QuadroAdapter[i] ;
+		IoAdapter = QuadroList->QuadroAdapter[i];
 
-		if ( IoAdapter && IoAdapter->Initialized
-		  && IoAdapter->tst_irq (&IoAdapter->a) )
+		if (IoAdapter && IoAdapter->Initialized
+		    && IoAdapter->tst_irq(&IoAdapter->a))
 		{
-			IoAdapter->IrqCount++ ;
-			serviced = 1 ;
-			diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
+			IoAdapter->IrqCount++;
+			serviced = 1;
+			diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
 		}
 	}
 
-	return (serviced) ;
+	return (serviced);
 }
 
 /* --------------------------------------------------------------------------
-		Does disable the interrupt on the card
-	 -------------------------------------------------------------------------- */
-static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) {
-	dword volatile __iomem *qBriIrq ;
+   Does disable the interrupt on the card
+   -------------------------------------------------------------------------- */
+static void disable_qBri_interrupt(PISDN_ADAPTER IoAdapter) {
+	dword volatile __iomem *qBriIrq;
 	byte __iomem *p;
 
-	if ( IoAdapter->ControllerNumber > 0 )
-		return ;
+	if (IoAdapter->ControllerNumber > 0)
+		return;
 /*
  *	clear interrupt line (reset Local Interrupt Test Register)
  */
@@ -425,84 +425,84 @@ static void disable_qBri_interrupt (PISDN_ADAPTER IoAdapter) {
 
 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 	qBriIrq = (dword volatile __iomem *)(&p[DIVA_4BRI_REVISION(IoAdapter) ? (MQ2_BREG_IRQ_TEST)  : (MQ_BREG_IRQ_TEST)]);
-	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF) ;
+	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 }
 
 /* --------------------------------------------------------------------------
-		Install Adapter Entry Points
-	 -------------------------------------------------------------------------- */
-static void set_common_qBri_functions (PISDN_ADAPTER IoAdapter) {
+   Install Adapter Entry Points
+   -------------------------------------------------------------------------- */
+static void set_common_qBri_functions(PISDN_ADAPTER IoAdapter) {
 	ADAPTER *a;
 
-	a = &IoAdapter->a ;
+	a = &IoAdapter->a;
 
-	a->ram_in           = mem_in ;
-	a->ram_inw          = mem_inw ;
-	a->ram_in_buffer    = mem_in_buffer ;
-	a->ram_look_ahead   = mem_look_ahead ;
-	a->ram_out          = mem_out ;
-	a->ram_outw         = mem_outw ;
-	a->ram_out_buffer   = mem_out_buffer ;
-	a->ram_inc          = mem_inc ;
+	a->ram_in           = mem_in;
+	a->ram_inw          = mem_inw;
+	a->ram_in_buffer    = mem_in_buffer;
+	a->ram_look_ahead   = mem_look_ahead;
+	a->ram_out          = mem_out;
+	a->ram_outw         = mem_outw;
+	a->ram_out_buffer   = mem_out_buffer;
+	a->ram_inc          = mem_inc;
 
-	IoAdapter->out      = pr_out ;
-	IoAdapter->dpc      = pr_dpc ;
-	IoAdapter->tst_irq  = scom_test_int ;
-	IoAdapter->clr_irq  = scom_clear_int ;
-	IoAdapter->pcm      = (struct pc_maint *)MIPS_MAINT_OFFS ;
+	IoAdapter->out = pr_out;
+	IoAdapter->dpc = pr_dpc;
+	IoAdapter->tst_irq = scom_test_int;
+	IoAdapter->clr_irq  = scom_clear_int;
+	IoAdapter->pcm  = (struct pc_maint *)MIPS_MAINT_OFFS;
 
-	IoAdapter->load     = load_qBri_hardware ;
+	IoAdapter->load = load_qBri_hardware;
 
-	IoAdapter->disIrq   = disable_qBri_interrupt ;
-	IoAdapter->rstFnc   = reset_qBri_hardware ;
-	IoAdapter->stop     = stop_qBri_hardware ;
-	IoAdapter->trapFnc  = qBri_cpu_trapped ;
+	IoAdapter->disIrq = disable_qBri_interrupt;
+	IoAdapter->rstFnc = reset_qBri_hardware;
+	IoAdapter->stop = stop_qBri_hardware;
+	IoAdapter->trapFnc = qBri_cpu_trapped;
 
 	IoAdapter->diva_isr_handler = qBri_ISR;
 
-	IoAdapter->a.io       = (void*)IoAdapter ;
+	IoAdapter->a.io = (void *)IoAdapter;
 }
 
-static void set_qBri_functions (PISDN_ADAPTER IoAdapter) {
+static void set_qBri_functions(PISDN_ADAPTER IoAdapter) {
 	if (!IoAdapter->tasks) {
 		IoAdapter->tasks = MQ_INSTANCE_COUNT;
 	}
-	IoAdapter->MemorySize = MQ_MEMORY_SIZE ;
-	set_common_qBri_functions (IoAdapter) ;
-	diva_os_set_qBri_functions (IoAdapter) ;
+	IoAdapter->MemorySize = MQ_MEMORY_SIZE;
+	set_common_qBri_functions(IoAdapter);
+	diva_os_set_qBri_functions(IoAdapter);
 }
 
-static void set_qBri2_functions (PISDN_ADAPTER IoAdapter) {
+static void set_qBri2_functions(PISDN_ADAPTER IoAdapter) {
 	if (!IoAdapter->tasks) {
 		IoAdapter->tasks = MQ_INSTANCE_COUNT;
 	}
 	IoAdapter->MemorySize = (IoAdapter->tasks == 1) ? BRI2_MEMORY_SIZE : MQ2_MEMORY_SIZE;
-	set_common_qBri_functions (IoAdapter) ;
-	diva_os_set_qBri2_functions (IoAdapter) ;
+	set_common_qBri_functions(IoAdapter);
+	diva_os_set_qBri2_functions(IoAdapter);
 }
 
 /******************************************************************************/
 
-void prepare_qBri_functions (PISDN_ADAPTER IoAdapter) {
+void prepare_qBri_functions(PISDN_ADAPTER IoAdapter) {
 
-	set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[0]) ;
-	set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[1]) ;
-	set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[2]) ;
-	set_qBri_functions (IoAdapter->QuadroList->QuadroAdapter[3]) ;
+	set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[0]);
+	set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[1]);
+	set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[2]);
+	set_qBri_functions(IoAdapter->QuadroList->QuadroAdapter[3]);
 
 }
 
-void prepare_qBri2_functions (PISDN_ADAPTER IoAdapter) {
+void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter) {
 	if (!IoAdapter->tasks) {
 		IoAdapter->tasks = MQ_INSTANCE_COUNT;
 	}
 
-	set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[0]) ;
+	set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[0]);
 	if (IoAdapter->tasks > 1) {
-		set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[1]) ;
-		set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[2]) ;
-		set_qBri2_functions (IoAdapter->QuadroList->QuadroAdapter[3]) ;
+		set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[1]);
+		set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[2]);
+		set_qBri2_functions(IoAdapter->QuadroList->QuadroAdapter[3]);
 	}
 
 }
diff --git a/drivers/isdn/hardware/eicon/s_bri.c b/drivers/isdn/hardware/eicon/s_bri.c
index 5c87552..6a5bb74 100644
--- a/drivers/isdn/hardware/eicon/s_bri.c
+++ b/drivers/isdn/hardware/eicon/s_bri.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -38,154 +38,154 @@
 /*****************************************************************************/
 #define MAX_XLOG_SIZE (64 * 1024)
 /* --------------------------------------------------------------------------
-  Investigate card state, recovery trace buffer
-  -------------------------------------------------------------------------- */
-static void bri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
- byte  __iomem *addrHi, *addrLo, *ioaddr ;
- word *Xlog ;
- dword   regs[4], i, size ;
- Xdesc   xlogDesc ;
- byte __iomem *Port;
+   Investigate card state, recovery trace buffer
+   -------------------------------------------------------------------------- */
+static void bri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
+	byte  __iomem *addrHi, *addrLo, *ioaddr;
+	word *Xlog;
+	dword   regs[4], i, size;
+	Xdesc   xlogDesc;
+	byte __iomem *Port;
 /*
  * first read pointers and trap frame
  */
- if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) )
-  return ;
- Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
- addrHi =   Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH) ;
- addrLo = Port + ADDR ;
- ioaddr = Port + DATA ;
- outpp (addrHi,  0) ;
- outppw (addrLo, 0) ;
- for ( i = 0 ; i < 0x100 ; Xlog[i++] = inppw(ioaddr) ) ;
+	if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE)))
+		return;
+	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
+	addrHi = Port + ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
+	addrLo = Port + ADDR;
+	ioaddr = Port + DATA;
+	outpp(addrHi,  0);
+	outppw(addrLo, 0);
+	for (i = 0; i < 0x100; Xlog[i++] = inppw(ioaddr));
 /*
  * check for trapped MIPS 3xxx CPU, dump only exception frame
  */
- if ( GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999 )
- {
-  dump_trap_frame (IoAdapter, &((byte *)Xlog)[0x90]) ;
-  IoAdapter->trapped = 1 ;
- }
- regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]);
- regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]);
- regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]);
- regs[3] = GET_DWORD(&((byte *)Xlog)[0x7c]);
- outpp (addrHi, (regs[1] >> 16) & 0x7F) ;
- outppw (addrLo, regs[1] & 0xFFFF) ;
- xlogDesc.cnt = inppw(ioaddr) ;
- outpp (addrHi, (regs[2] >> 16) & 0x7F) ;
- outppw (addrLo, regs[2] & 0xFFFF) ;
- xlogDesc.out = inppw(ioaddr) ;
- xlogDesc.buf = Xlog ;
- regs[0] &= IoAdapter->MemorySize - 1 ;
- if ( (regs[0] < IoAdapter->MemorySize - 1) )
- {
-  size = IoAdapter->MemorySize - regs[0] ;
-  if ( size > MAX_XLOG_SIZE )
-   size = MAX_XLOG_SIZE ;
-  for ( i = 0 ; i < (size / sizeof(*Xlog)) ; regs[0] += 2 )
-  {
-   outpp (addrHi, (regs[0] >> 16) & 0x7F) ;
-   outppw (addrLo, regs[0] & 0xFFFF) ;
-   Xlog[i++] = inppw(ioaddr) ;
-  }
-  dump_xlog_buffer (IoAdapter, &xlogDesc) ;
-  diva_os_free (0, Xlog) ;
-  IoAdapter->trapped = 2 ;
- }
- outpp  (addrHi, (byte)((BRI_UNCACHED_ADDR (IoAdapter->MemoryBase + IoAdapter->MemorySize -
-                                            BRI_SHARED_RAM_SIZE)) >> 16)) ;
- outppw (addrLo, 0x00) ;
- DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
+	if (GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999)
+	{
+		dump_trap_frame(IoAdapter, &((byte *)Xlog)[0x90]);
+		IoAdapter->trapped = 1;
+	}
+	regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]);
+	regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]);
+	regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]);
+	regs[3] = GET_DWORD(&((byte *)Xlog)[0x7c]);
+	outpp(addrHi, (regs[1] >> 16) & 0x7F);
+	outppw(addrLo, regs[1] & 0xFFFF);
+	xlogDesc.cnt = inppw(ioaddr);
+	outpp(addrHi, (regs[2] >> 16) & 0x7F);
+	outppw(addrLo, regs[2] & 0xFFFF);
+	xlogDesc.out = inppw(ioaddr);
+	xlogDesc.buf = Xlog;
+	regs[0] &= IoAdapter->MemorySize - 1;
+	if ((regs[0] < IoAdapter->MemorySize - 1))
+	{
+		size = IoAdapter->MemorySize - regs[0];
+		if (size > MAX_XLOG_SIZE)
+			size = MAX_XLOG_SIZE;
+		for (i = 0; i < (size / sizeof(*Xlog)); regs[0] += 2)
+		{
+			outpp(addrHi, (regs[0] >> 16) & 0x7F);
+			outppw(addrLo, regs[0] & 0xFFFF);
+			Xlog[i++] = inppw(ioaddr);
+		}
+		dump_xlog_buffer(IoAdapter, &xlogDesc);
+		diva_os_free(0, Xlog);
+		IoAdapter->trapped = 2;
+	}
+	outpp(addrHi, (byte)((BRI_UNCACHED_ADDR(IoAdapter->MemoryBase + IoAdapter->MemorySize -
+						BRI_SHARED_RAM_SIZE)) >> 16));
+	outppw(addrLo, 0x00);
+	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
 }
 /* ---------------------------------------------------------------------
    Reset hardware
-  --------------------------------------------------------------------- */
-static void reset_bri_hardware (PISDN_ADAPTER IoAdapter) {
- byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
- outpp (p, 0x00) ;
- DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+   --------------------------------------------------------------------- */
+static void reset_bri_hardware(PISDN_ADAPTER IoAdapter) {
+	byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+	outpp(p, 0x00);
+	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 }
 /* ---------------------------------------------------------------------
    Halt system
-  --------------------------------------------------------------------- */
-static void stop_bri_hardware (PISDN_ADAPTER IoAdapter) {
- byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
- if (p) {
-  outpp (p, 0x00) ; /* disable interrupts ! */
- }
- DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
- p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
- outpp (p, 0x00) ;    /* clear int, halt cpu */
- DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+   --------------------------------------------------------------------- */
+static void stop_bri_hardware(PISDN_ADAPTER IoAdapter) {
+	byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+	if (p) {
+		outpp(p, 0x00); /* disable interrupts ! */
+	}
+	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+	outpp(p, 0x00);    /* clear int, halt cpu */
+	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 }
-static int load_bri_hardware (PISDN_ADAPTER IoAdapter) {
- return (0);
+static int load_bri_hardware(PISDN_ADAPTER IoAdapter) {
+	return (0);
 }
 /******************************************************************************/
-static int bri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
- byte __iomem *p;
+static int bri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
+	byte __iomem *p;
 
- p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
- if ( !(inpp (p) & 0x01) ) {
-  DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
-  return (0) ;
- }
- /*
-  clear interrupt line
-  */
- outpp (p, 0x08) ;
- DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
- IoAdapter->IrqCount++ ;
- if ( IoAdapter->Initialized ) {
-  diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
- }
- return (1) ;
+	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+	if (!(inpp(p) & 0x01)) {
+		DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+		return (0);
+	}
+	/*
+	  clear interrupt line
+	*/
+	outpp(p, 0x08);
+	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+	IoAdapter->IrqCount++;
+	if (IoAdapter->Initialized) {
+		diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
+	}
+	return (1);
 }
 /* --------------------------------------------------------------------------
-  Disable IRQ in the card hardware
-  -------------------------------------------------------------------------- */
-static void disable_bri_interrupt (PISDN_ADAPTER IoAdapter) {
- byte __iomem *p;
- p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
- if ( p )
- {
-  outpp (p, 0x00) ; /* disable interrupts ! */
- }
- DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
- p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
- outpp (p, 0x00) ; /* clear int, halt cpu */
- DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
+   Disable IRQ in the card hardware
+   -------------------------------------------------------------------------- */
+static void disable_bri_interrupt(PISDN_ADAPTER IoAdapter) {
+	byte __iomem *p;
+	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+	if (p)
+	{
+		outpp(p, 0x00); /* disable interrupts ! */
+	}
+	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
+	outpp(p, 0x00); /* clear int, halt cpu */
+	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 }
 /* -------------------------------------------------------------------------
-  Fill card entry points
-  ------------------------------------------------------------------------- */
-void prepare_maestra_functions (PISDN_ADAPTER IoAdapter) {
- ADAPTER *a = &IoAdapter->a ;
- a->ram_in             = io_in ;
- a->ram_inw            = io_inw ;
- a->ram_in_buffer      = io_in_buffer ;
- a->ram_look_ahead     = io_look_ahead ;
- a->ram_out            = io_out ;
- a->ram_outw           = io_outw ;
- a->ram_out_buffer     = io_out_buffer ;
- a->ram_inc            = io_inc ;
- IoAdapter->MemoryBase = BRI_MEMORY_BASE ;
- IoAdapter->MemorySize = BRI_MEMORY_SIZE ;
- IoAdapter->out        = pr_out ;
- IoAdapter->dpc        = pr_dpc ;
- IoAdapter->tst_irq    = scom_test_int ;
- IoAdapter->clr_irq    = scom_clear_int ;
- IoAdapter->pcm        = (struct pc_maint *)MIPS_MAINT_OFFS ;
- IoAdapter->load       = load_bri_hardware ;
- IoAdapter->disIrq     = disable_bri_interrupt ;
- IoAdapter->rstFnc     = reset_bri_hardware ;
- IoAdapter->stop       = stop_bri_hardware ;
- IoAdapter->trapFnc    = bri_cpu_trapped ;
- IoAdapter->diva_isr_handler = bri_ISR;
- /*
-  Prepare OS dependent functions
-  */
- diva_os_prepare_maestra_functions (IoAdapter);
+   Fill card entry points
+   ------------------------------------------------------------------------- */
+void prepare_maestra_functions(PISDN_ADAPTER IoAdapter) {
+	ADAPTER *a = &IoAdapter->a;
+	a->ram_in             = io_in;
+	a->ram_inw            = io_inw;
+	a->ram_in_buffer      = io_in_buffer;
+	a->ram_look_ahead     = io_look_ahead;
+	a->ram_out            = io_out;
+	a->ram_outw           = io_outw;
+	a->ram_out_buffer     = io_out_buffer;
+	a->ram_inc            = io_inc;
+	IoAdapter->MemoryBase = BRI_MEMORY_BASE;
+	IoAdapter->MemorySize = BRI_MEMORY_SIZE;
+	IoAdapter->out        = pr_out;
+	IoAdapter->dpc        = pr_dpc;
+	IoAdapter->tst_irq    = scom_test_int;
+	IoAdapter->clr_irq    = scom_clear_int;
+	IoAdapter->pcm        = (struct pc_maint *)MIPS_MAINT_OFFS;
+	IoAdapter->load       = load_bri_hardware;
+	IoAdapter->disIrq     = disable_bri_interrupt;
+	IoAdapter->rstFnc     = reset_bri_hardware;
+	IoAdapter->stop       = stop_bri_hardware;
+	IoAdapter->trapFnc    = bri_cpu_trapped;
+	IoAdapter->diva_isr_handler = bri_ISR;
+	/*
+	  Prepare OS dependent functions
+	*/
+	diva_os_prepare_maestra_functions(IoAdapter);
 }
 /* -------------------------------------------------------------------------- */
diff --git a/drivers/isdn/hardware/eicon/s_pri.c b/drivers/isdn/hardware/eicon/s_pri.c
index 18f2878..ddd0e0e 100644
--- a/drivers/isdn/hardware/eicon/s_pri.c
+++ b/drivers/isdn/hardware/eicon/s_pri.c
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 "platform.h"
@@ -38,168 +38,168 @@
 /*****************************************************************************/
 #define MAX_XLOG_SIZE  (64 * 1024)
 /* -------------------------------------------------------------------------
-  Does return offset between ADAPTER->ram and real begin of memory
-  ------------------------------------------------------------------------- */
-static dword pri_ram_offset (ADAPTER* a) {
- return ((dword)MP_SHARED_RAM_OFFSET);
+   Does return offset between ADAPTER->ram and real begin of memory
+   ------------------------------------------------------------------------- */
+static dword pri_ram_offset(ADAPTER *a) {
+	return ((dword)MP_SHARED_RAM_OFFSET);
 }
 /* -------------------------------------------------------------------------
-  Recovery XLOG buffer from the card
-  ------------------------------------------------------------------------- */
-static void pri_cpu_trapped (PISDN_ADAPTER IoAdapter) {
- byte  __iomem *base ;
- word *Xlog ;
- dword   regs[4], TrapID, size ;
- Xdesc   xlogDesc ;
+   Recovery XLOG buffer from the card
+   ------------------------------------------------------------------------- */
+static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
+	byte  __iomem *base;
+	word *Xlog;
+	dword   regs[4], TrapID, size;
+	Xdesc   xlogDesc;
 /*
  * check for trapped MIPS 46xx CPU, dump exception frame
  */
- base   = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
- TrapID = READ_DWORD(&base[0x80]) ;
- if ( (TrapID == 0x99999999) || (TrapID == 0x99999901) )
- {
-  dump_trap_frame (IoAdapter, &base[0x90]) ;
-  IoAdapter->trapped = 1 ;
- }
- regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
- regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
- regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
- regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
- regs[0] &= IoAdapter->MemorySize - 1 ;
- if ( (regs[0] < IoAdapter->MemorySize - 1) )
- {
-  if ( !(Xlog = (word *)diva_os_malloc (0, MAX_XLOG_SIZE)) ) {
-   DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
-   return ;
-  }
-  size = IoAdapter->MemorySize - regs[0] ;
-  if ( size > MAX_XLOG_SIZE )
-   size = MAX_XLOG_SIZE ;
-  memcpy_fromio(Xlog, &base[regs[0]], size) ;
-  xlogDesc.buf = Xlog ;
-  xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]) ;
-  xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]) ;
-  dump_xlog_buffer (IoAdapter, &xlogDesc) ;
-  diva_os_free (0, Xlog) ;
-  IoAdapter->trapped = 2 ;
- }
- DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
+	base   = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
+	TrapID = READ_DWORD(&base[0x80]);
+	if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
+	{
+		dump_trap_frame(IoAdapter, &base[0x90]);
+		IoAdapter->trapped = 1;
+	}
+	regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
+	regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
+	regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
+	regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
+	regs[0] &= IoAdapter->MemorySize - 1;
+	if ((regs[0] < IoAdapter->MemorySize - 1))
+	{
+		if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
+			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
+			return;
+		}
+		size = IoAdapter->MemorySize - regs[0];
+		if (size > MAX_XLOG_SIZE)
+			size = MAX_XLOG_SIZE;
+		memcpy_fromio(Xlog, &base[regs[0]], size);
+		xlogDesc.buf = Xlog;
+		xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
+		xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
+		dump_xlog_buffer(IoAdapter, &xlogDesc);
+		diva_os_free(0, Xlog);
+		IoAdapter->trapped = 2;
+	}
+	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
 }
 /* -------------------------------------------------------------------------
-  Hardware reset of PRI card
-  ------------------------------------------------------------------------- */
-static void reset_pri_hardware (PISDN_ADAPTER IoAdapter) {
- byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
- WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
- diva_os_wait (50) ;
- WRITE_BYTE(p, 0x00);
- diva_os_wait (50) ;
- DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+   Hardware reset of PRI card
+   ------------------------------------------------------------------------- */
+static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) {
+	byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+	WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
+	diva_os_wait(50);
+	WRITE_BYTE(p, 0x00);
+	diva_os_wait(50);
+	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
 }
 /* -------------------------------------------------------------------------
-  Stop Card Hardware
-  ------------------------------------------------------------------------- */
-static void stop_pri_hardware (PISDN_ADAPTER IoAdapter) {
- dword i;
- byte __iomem *p;
- dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
- WRITE_DWORD(&cfgReg[3], 0);
- WRITE_DWORD(&cfgReg[1], 0);
- DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
- IoAdapter->a.ram_out (&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU) ;
- i = 0 ;
- while ( (i < 100) && (IoAdapter->a.ram_in (&IoAdapter->a, &RAM->SWReg) != 0) )
- {
-  diva_os_wait (1) ;
-  i++ ;
- }
- DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
- cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
- WRITE_DWORD(&cfgReg[0],((dword)(~0x03E00000)));
- DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
- diva_os_wait (1) ;
- p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
- WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
- DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
+   Stop Card Hardware
+   ------------------------------------------------------------------------- */
+static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) {
+	dword i;
+	byte __iomem *p;
+	dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+	WRITE_DWORD(&cfgReg[3], 0);
+	WRITE_DWORD(&cfgReg[1], 0);
+	DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+	IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU);
+	i = 0;
+	while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0))
+	{
+		diva_os_wait(1);
+		i++;
+	}
+	DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
+		cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+	WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000)));
+	DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+	diva_os_wait(1);
+	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
+	WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
+	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
 }
-static int load_pri_hardware (PISDN_ADAPTER IoAdapter) {
- return (0);
+static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
+	return (0);
 }
 /* --------------------------------------------------------------------------
-  PRI Adapter interrupt Service Routine
+   PRI Adapter interrupt Service Routine
    -------------------------------------------------------------------------- */
-static int pri_ISR (struct _ISDN_ADAPTER* IoAdapter) {
- byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
- if ( !(READ_DWORD(cfg) & 0x80000000) ) {
-  DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
-  return (0) ;
- }
- /*
-  clear interrupt line
-  */
- WRITE_DWORD(cfg, (dword)~0x03E00000) ;
- DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
- IoAdapter->IrqCount++ ;
- if ( IoAdapter->Initialized )
- {
-  diva_os_schedule_soft_isr (&IoAdapter->isr_soft_isr);
- }
- return (1) ;
+static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
+	byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+	if (!(READ_DWORD(cfg) & 0x80000000)) {
+		DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
+		return (0);
+	}
+	/*
+	  clear interrupt line
+	*/
+	WRITE_DWORD(cfg, (dword)~0x03E00000);
+	DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
+	IoAdapter->IrqCount++;
+	if (IoAdapter->Initialized)
+	{
+		diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
+	}
+	return (1);
 }
 /* -------------------------------------------------------------------------
-  Disable interrupt in the card hardware
-  ------------------------------------------------------------------------- */
-static void disable_pri_interrupt (PISDN_ADAPTER IoAdapter) {
- dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter) ;
- WRITE_DWORD(&cfgReg[3], 0);
- WRITE_DWORD(&cfgReg[1], 0);
- WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)) ;
- DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
+   Disable interrupt in the card hardware
+   ------------------------------------------------------------------------- */
+static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) {
+	dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
+	WRITE_DWORD(&cfgReg[3], 0);
+	WRITE_DWORD(&cfgReg[1], 0);
+	WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000));
+	DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
 }
 /* -------------------------------------------------------------------------
-  Install entry points for PRI Adapter
-  ------------------------------------------------------------------------- */
-static void prepare_common_pri_functions (PISDN_ADAPTER IoAdapter) {
- ADAPTER *a = &IoAdapter->a ;
- a->ram_in           = mem_in ;
- a->ram_inw          = mem_inw ;
- a->ram_in_buffer    = mem_in_buffer ;
- a->ram_look_ahead   = mem_look_ahead ;
- a->ram_out          = mem_out ;
- a->ram_outw         = mem_outw ;
- a->ram_out_buffer   = mem_out_buffer ;
- a->ram_inc          = mem_inc ;
- a->ram_offset       = pri_ram_offset ;
- a->ram_out_dw    = mem_out_dw;
- a->ram_in_dw    = mem_in_dw;
-  a->istream_wakeup   = pr_stream;
- IoAdapter->out      = pr_out ;
- IoAdapter->dpc      = pr_dpc ;
- IoAdapter->tst_irq  = scom_test_int ;
- IoAdapter->clr_irq  = scom_clear_int ;
- IoAdapter->pcm      = (struct pc_maint *)(MIPS_MAINT_OFFS
-                                        - MP_SHARED_RAM_OFFSET) ;
- IoAdapter->load     = load_pri_hardware ;
- IoAdapter->disIrq   = disable_pri_interrupt ;
- IoAdapter->rstFnc   = reset_pri_hardware ;
- IoAdapter->stop     = stop_pri_hardware ;
- IoAdapter->trapFnc  = pri_cpu_trapped ;
- IoAdapter->diva_isr_handler = pri_ISR;
+   Install entry points for PRI Adapter
+   ------------------------------------------------------------------------- */
+static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) {
+	ADAPTER *a = &IoAdapter->a;
+	a->ram_in           = mem_in;
+	a->ram_inw          = mem_inw;
+	a->ram_in_buffer    = mem_in_buffer;
+	a->ram_look_ahead   = mem_look_ahead;
+	a->ram_out          = mem_out;
+	a->ram_outw         = mem_outw;
+	a->ram_out_buffer   = mem_out_buffer;
+	a->ram_inc          = mem_inc;
+	a->ram_offset       = pri_ram_offset;
+	a->ram_out_dw    = mem_out_dw;
+	a->ram_in_dw    = mem_in_dw;
+	a->istream_wakeup   = pr_stream;
+	IoAdapter->out      = pr_out;
+	IoAdapter->dpc      = pr_dpc;
+	IoAdapter->tst_irq  = scom_test_int;
+	IoAdapter->clr_irq  = scom_clear_int;
+	IoAdapter->pcm      = (struct pc_maint *)(MIPS_MAINT_OFFS
+						  - MP_SHARED_RAM_OFFSET);
+	IoAdapter->load     = load_pri_hardware;
+	IoAdapter->disIrq   = disable_pri_interrupt;
+	IoAdapter->rstFnc   = reset_pri_hardware;
+	IoAdapter->stop     = stop_pri_hardware;
+	IoAdapter->trapFnc  = pri_cpu_trapped;
+	IoAdapter->diva_isr_handler = pri_ISR;
 }
 /* -------------------------------------------------------------------------
-  Install entry points for PRI Adapter
-  ------------------------------------------------------------------------- */
-void prepare_pri_functions (PISDN_ADAPTER IoAdapter) {
- IoAdapter->MemorySize = MP_MEMORY_SIZE ;
- prepare_common_pri_functions (IoAdapter) ;
- diva_os_prepare_pri_functions (IoAdapter);
+   Install entry points for PRI Adapter
+   ------------------------------------------------------------------------- */
+void prepare_pri_functions(PISDN_ADAPTER IoAdapter) {
+	IoAdapter->MemorySize = MP_MEMORY_SIZE;
+	prepare_common_pri_functions(IoAdapter);
+	diva_os_prepare_pri_functions(IoAdapter);
 }
 /* -------------------------------------------------------------------------
-  Install entry points for PRI Rev.2 Adapter
-  ------------------------------------------------------------------------- */
-void prepare_pri2_functions (PISDN_ADAPTER IoAdapter) {
- IoAdapter->MemorySize = MP2_MEMORY_SIZE ;
- prepare_common_pri_functions (IoAdapter) ;
- diva_os_prepare_pri2_functions (IoAdapter);
+   Install entry points for PRI Rev.2 Adapter
+   ------------------------------------------------------------------------- */
+void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) {
+	IoAdapter->MemorySize = MP2_MEMORY_SIZE;
+	prepare_common_pri_functions(IoAdapter);
+	diva_os_prepare_pri2_functions(IoAdapter);
 }
 /* ------------------------------------------------------------------------- */
diff --git a/drivers/isdn/hardware/eicon/sdp_hdr.h b/drivers/isdn/hardware/eicon/sdp_hdr.h
index 8f61c69..5e20f8d 100644
--- a/drivers/isdn/hardware/eicon/sdp_hdr.h
+++ b/drivers/isdn/hardware/eicon/sdp_hdr.h
@@ -1,48 +1,48 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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 __DIVA_SOFT_DSP_TASK_ENTRY_H__
 #define __DIVA_SOFT_DSP_TASK_ENTRY_H__
 /*
- The soft DSP image is described by binary header contained on begin of this
- image:
-OFFSET FROM IMAGE START |  VARIABLE
-------------------------------------------------------------------------
- DIVA_MIPS_TASK_IMAGE_LINK_OFFS   |  link to the next image
+  The soft DSP image is described by binary header contained on begin of this
+  image:
+  OFFSET FROM IMAGE START |  VARIABLE
+  ------------------------------------------------------------------------
+  DIVA_MIPS_TASK_IMAGE_LINK_OFFS   |  link to the next image
   ----------------------------------------------------------------------
- DIVA_MIPS_TASK_IMAGE_GP_OFFS    |  image gp register value, void*
+  DIVA_MIPS_TASK_IMAGE_GP_OFFS    |  image gp register value, void*
   ----------------------------------------------------------------------
- DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS   |  diva_mips_sdp_task_entry_t*
+  DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS   |  diva_mips_sdp_task_entry_t*
   ----------------------------------------------------------------------
- DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS |  image image start address (void*)
+  DIVA_MIPS_TASK_IMAGE_LOAD_ADDR_OFFS |  image image start address (void*)
   ----------------------------------------------------------------------
- DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS |  image image end address   (void*)
+  DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS |  image image end address   (void*)
   ----------------------------------------------------------------------
- DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS |  image id string char[...];
+  DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS |  image id string char[...];
   ----------------------------------------------------------------------
- */
+*/
 #define DIVA_MIPS_TASK_IMAGE_LINK_OFFS   0x6C
 #define DIVA_MIPS_TASK_IMAGE_GP_OFFS    0x70
 #define DIVA_MIPS_TASK_IMAGE_ENTRY_OFFS   0x74
@@ -50,63 +50,63 @@ OFFSET FROM IMAGE START |  VARIABLE
 #define DIVA_MIPS_TASK_IMAGE_END_ADDR_OFFS 0x7c
 #define DIVA_MIPS_TASK_IMAGE_ID_STRING_OFFS 0x80
 /*
- This function is called in order to set GP register of this task
- This function should be always called before any function of the
- task is called
- */
-typedef void (*diva_task_set_prog_gp_proc_t)(void* new_gp);
+  This function is called in order to set GP register of this task
+  This function should be always called before any function of the
+  task is called
+*/
+typedef void (*diva_task_set_prog_gp_proc_t)(void *new_gp);
 /*
- This function is called to clear .bss at task initialization step
- */
-typedef void  (*diva_task_sys_reset_proc_t)(void);
+  This function is called to clear .bss at task initialization step
+*/
+typedef void (*diva_task_sys_reset_proc_t)(void);
 /*
- This function is called in order to provide GP of master call to
- task, that will be used by calls from the task to the master
- */
-typedef void (*diva_task_set_main_gp_proc_t)(void* main_gp);
+  This function is called in order to provide GP of master call to
+  task, that will be used by calls from the task to the master
+*/
+typedef void (*diva_task_set_main_gp_proc_t)(void *main_gp);
 /*
- This function is called to provide address of 'dprintf' function
- to the task
- */
+  This function is called to provide address of 'dprintf' function
+  to the task
+*/
 typedef word (*diva_prt_proc_t)(char *, ...);
 typedef void (*diva_task_set_prt_proc_t)(diva_prt_proc_t fn);
 /*
- This function is called to set task PID
- */
+  This function is called to set task PID
+*/
 typedef void (*diva_task_set_pid_proc_t)(dword id);
 /*
- This function is called for run-time task init
- */
+  This function is called for run-time task init
+*/
 typedef int (*diva_task_run_time_init_proc_t)(void*, dword);
 /*
- This function is called from system scheduler or from timer
- */
+  This function is called from system scheduler or from timer
+*/
 typedef void (*diva_task_callback_proc_t)(void);
 /*
- This callback is used by task to get current time im mS
-  */
+  This callback is used by task to get current time im mS
+*/
 typedef dword (*diva_task_get_tick_count_proc_t)(void);
 typedef void (*diva_task_set_get_time_proc_t)(\
-                diva_task_get_tick_count_proc_t fn);
+	diva_task_get_tick_count_proc_t fn);
 typedef struct _diva_mips_sdp_task_entry {
- diva_task_set_prog_gp_proc_t  set_gp_proc;
- diva_task_sys_reset_proc_t   sys_reset_proc;
- diva_task_set_main_gp_proc_t  set_main_gp_proc;
- diva_task_set_prt_proc_t    set_dprintf_proc;
- diva_task_set_pid_proc_t    set_pid_proc;
- diva_task_run_time_init_proc_t run_time_init_proc;
- diva_task_callback_proc_t    task_callback_proc;
- diva_task_callback_proc_t    timer_callback_proc;
- diva_task_set_get_time_proc_t  set_get_time_proc;
- void*              last_entry_proc;
+	diva_task_set_prog_gp_proc_t  set_gp_proc;
+	diva_task_sys_reset_proc_t   sys_reset_proc;
+	diva_task_set_main_gp_proc_t  set_main_gp_proc;
+	diva_task_set_prt_proc_t    set_dprintf_proc;
+	diva_task_set_pid_proc_t    set_pid_proc;
+	diva_task_run_time_init_proc_t run_time_init_proc;
+	diva_task_callback_proc_t    task_callback_proc;
+	diva_task_callback_proc_t    timer_callback_proc;
+	diva_task_set_get_time_proc_t  set_get_time_proc;
+	void *last_entry_proc;
 } diva_mips_sdp_task_entry_t;
 /*
- 'last_entry_proc' should be set to zero and is used for future extensuios
- */
+  'last_entry_proc' should be set to zero and is used for future extensuios
+*/
 typedef struct _diva_mips_sw_task {
-  diva_mips_sdp_task_entry_t  sdp_entry;
-  void*                       sdp_gp_reg;
-  void*                       own_gp_reg;
+	diva_mips_sdp_task_entry_t  sdp_entry;
+	void *sdp_gp_reg;
+	void *own_gp_reg;
 } diva_mips_sw_task_t;
 #if !defined(DIVA_BRI2F_SDP_1_NAME)
 #define DIVA_BRI2F_SDP_1_NAME "sdp0.2q0"
diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c
index ac0bdd1..7cab5c3 100644
--- a/drivers/isdn/hardware/eicon/um_idi.c
+++ b/drivers/isdn/hardware/eicon/um_idi.c
@@ -14,30 +14,30 @@
 #define DIVAS_MAX_XDI_ADAPTERS	64
 
 /* --------------------------------------------------------------------------
-		IMPORTS
+   IMPORTS
    -------------------------------------------------------------------------- */
 extern void diva_os_wakeup_read(void *os_context);
 extern void diva_os_wakeup_close(void *os_context);
 /* --------------------------------------------------------------------------
-		LOCALS
+   LOCALS
    -------------------------------------------------------------------------- */
 static LIST_HEAD(adapter_q);
 static diva_os_spin_lock_t adapter_lock;
 
 static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr);
-static void cleanup_adapter(diva_um_idi_adapter_t * a);
-static void cleanup_entity(divas_um_idi_entity_t * e);
-static int diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a,
+static void cleanup_adapter(diva_um_idi_adapter_t *a);
+static void cleanup_entity(divas_um_idi_entity_t *e);
+static int diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t *a,
 					       diva_um_idi_adapter_features_t
-					       * features);
-static int process_idi_request(divas_um_idi_entity_t * e,
-			       const diva_um_idi_req_hdr_t * req);
-static int process_idi_rc(divas_um_idi_entity_t * e, byte rc);
-static int process_idi_ind(divas_um_idi_entity_t * e, byte ind);
-static int write_return_code(divas_um_idi_entity_t * e, byte rc);
+					       *features);
+static int process_idi_request(divas_um_idi_entity_t *e,
+			       const diva_um_idi_req_hdr_t *req);
+static int process_idi_rc(divas_um_idi_entity_t *e, byte rc);
+static int process_idi_ind(divas_um_idi_entity_t *e, byte ind);
+static int write_return_code(divas_um_idi_entity_t *e, byte rc);
 
 /* --------------------------------------------------------------------------
-		MAIN
+   MAIN
    -------------------------------------------------------------------------- */
 int diva_user_mode_idi_init(void)
 {
@@ -46,10 +46,10 @@ int diva_user_mode_idi_init(void)
 }
 
 /* --------------------------------------------------------------------------
-		Copy adapter features to user supplied buffer
+   Copy adapter features to user supplied buffer
    -------------------------------------------------------------------------- */
 static int
-diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a,
+diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t *a,
 				    diva_um_idi_adapter_features_t *
 				    features)
 {
@@ -63,14 +63,14 @@ diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a,
 
 		sync_req.GetName.Req = 0;
 		sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME;
-		(*(a->d.request)) ((ENTITY *) & sync_req);
+		(*(a->d.request)) ((ENTITY *)&sync_req);
 		strlcpy(features->name, sync_req.GetName.name,
 			sizeof(features->name));
 
 		sync_req.GetSerial.Req = 0;
 		sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
 		sync_req.GetSerial.serial = 0;
-		(*(a->d.request)) ((ENTITY *) & sync_req);
+		(*(a->d.request))((ENTITY *)&sync_req);
 		features->serial_number = sync_req.GetSerial.serial;
 	}
 
@@ -78,7 +78,7 @@ diva_user_mode_idi_adapter_features(diva_um_idi_adapter_t * a,
 }
 
 /* --------------------------------------------------------------------------
-		REMOVE ADAPTER
+   REMOVE ADAPTER
    -------------------------------------------------------------------------- */
 void diva_user_mode_idi_remove_adapter(int adapter_nr)
 {
@@ -98,7 +98,7 @@ void diva_user_mode_idi_remove_adapter(int adapter_nr)
 }
 
 /* --------------------------------------------------------------------------
-		CALLED ON DRIVER EXIT (UNLOAD)
+   CALLED ON DRIVER EXIT (UNLOAD)
    -------------------------------------------------------------------------- */
 void diva_user_mode_idi_finit(void)
 {
@@ -116,15 +116,15 @@ void diva_user_mode_idi_finit(void)
 }
 
 /* -------------------------------------------------------------------------
-		CREATE AND INIT IDI ADAPTER
-	 ------------------------------------------------------------------------- */
-int diva_user_mode_idi_create_adapter(const DESCRIPTOR * d, int adapter_nr)
+   CREATE AND INIT IDI ADAPTER
+   ------------------------------------------------------------------------- */
+int diva_user_mode_idi_create_adapter(const DESCRIPTOR *d, int adapter_nr)
 {
 	diva_os_spin_lock_magic_t old_irql;
 	diva_um_idi_adapter_t *a =
-	    (diva_um_idi_adapter_t *) diva_os_malloc(0,
-						     sizeof
-						     (diva_um_idi_adapter_t));
+		(diva_um_idi_adapter_t *) diva_os_malloc(0,
+							 sizeof
+							 (diva_um_idi_adapter_t));
 
 	if (!a) {
 		return (-1);
@@ -145,7 +145,7 @@ int diva_user_mode_idi_create_adapter(const DESCRIPTOR * d, int adapter_nr)
 }
 
 /* ------------------------------------------------------------------------
-			Find adapter by Adapter number
+   Find adapter by Adapter number
    ------------------------------------------------------------------------ */
 static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr)
 {
@@ -159,14 +159,14 @@ static diva_um_idi_adapter_t *diva_um_idi_find_adapter(dword nr)
 			break;
 		a = NULL;
 	}
-	return(a);
+	return (a);
 }
 
 /* ------------------------------------------------------------------------
-		Cleanup this adapter and cleanup/delete all entities assigned
-		to this adapter
+   Cleanup this adapter and cleanup/delete all entities assigned
+   to this adapter
    ------------------------------------------------------------------------ */
-static void cleanup_adapter(diva_um_idi_adapter_t * a)
+static void cleanup_adapter(diva_um_idi_adapter_t *a)
 {
 	struct list_head *tmp, *safe;
 	divas_um_idi_entity_t *e;
@@ -184,9 +184,9 @@ static void cleanup_adapter(diva_um_idi_adapter_t * a)
 }
 
 /* ------------------------------------------------------------------------
-		Cleanup, but NOT delete this entity
+   Cleanup, but NOT delete this entity
    ------------------------------------------------------------------------ */
-static void cleanup_entity(divas_um_idi_entity_t * e)
+static void cleanup_entity(divas_um_idi_entity_t *e)
 {
 	e->os_ref = NULL;
 	e->status = 0;
@@ -203,7 +203,7 @@ static void cleanup_entity(divas_um_idi_entity_t * e)
 
 
 /* ------------------------------------------------------------------------
-		Create ENTITY, link it to the adapter and remove pointer to entity
+   Create ENTITY, link it to the adapter and remove pointer to entity
    ------------------------------------------------------------------------ */
 void *divas_um_idi_create_entity(dword adapter_nr, void *file)
 {
@@ -236,12 +236,12 @@ void *divas_um_idi_create_entity(dword adapter_nr, void *file)
 
 		diva_os_enter_spin_lock(&adapter_lock, &old_irql, "create_entity");
 		/*
-		   Look for Adapter requested
-		 */
+		  Look for Adapter requested
+		*/
 		if (!(a = diva_um_idi_find_adapter(adapter_nr))) {
 			/*
-			   No adapter was found, or this adapter was removed
-			 */
+			  No adapter was found, or this adapter was removed
+			*/
 			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "create_entity");
 
 			DBG_LOG(("A: no adapter(%ld)", adapter_nr));
@@ -267,7 +267,7 @@ void *divas_um_idi_create_entity(dword adapter_nr, void *file)
 }
 
 /* ------------------------------------------------------------------------
-		Unlink entity and free memory 
+   Unlink entity and free memory
    ------------------------------------------------------------------------ */
 int divas_um_idi_delete_entity(int adapter_nr, void *entity)
 {
@@ -296,8 +296,8 @@ int divas_um_idi_delete_entity(int adapter_nr, void *entity)
 }
 
 /* --------------------------------------------------------------------------
-		Called by application to read data from IDI
-	 -------------------------------------------------------------------------- */
+   Called by application to read data from IDI
+   -------------------------------------------------------------------------- */
 int diva_um_idi_read(void *entity,
 		     void *os_handle,
 		     void *dst,
@@ -319,20 +319,20 @@ int diva_um_idi_read(void *entity,
 	    (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "read");
 		DBG_ERR(("E(%08x) read failed - adapter removed", e))
-		return (-1);
+			return (-1);
 	}
 
 	DBG_TRC(("A(%d) E(%08x) read(%d)", a->adapter_nr, e, max_length));
 
 	/*
-	   Try to read return code first
-	 */
+	  Try to read return code first
+	*/
 	data = diva_data_q_get_segment4read(&e->rc);
 	q = &e->rc;
 
 	/*
-	   No return codes available, read indications now
-	 */
+	  No return codes available, read indications now
+	*/
 	if (!data) {
 		if (!(e->status & DIVA_UM_IDI_RC_PENDING)) {
 			DBG_TRC(("A(%d) E(%08x) read data", a->adapter_nr, e));
@@ -348,8 +348,8 @@ int diva_um_idi_read(void *entity,
 		if ((length = diva_data_q_get_segment_length(q)) >
 		    max_length) {
 			/*
-			   Not enough space to read message
-			 */
+			  Not enough space to read message
+			*/
 			DBG_ERR(("A: A(%d) E(%08x) read small buffer",
 				 a->adapter_nr, e, ret));
 			diva_os_leave_spin_lock(&adapter_lock, &old_irql,
@@ -357,14 +357,14 @@ int diva_um_idi_read(void *entity,
 			return (-2);
 		}
 		/*
-		   Copy it to user, this function does access ONLY locked an verified
-		   memory, also we can access it witch spin lock held
-		 */
+		  Copy it to user, this function does access ONLY locked an verified
+		  memory, also we can access it witch spin lock held
+		*/
 
 		if ((ret = (*cp_fn) (os_handle, dst, data, length)) >= 0) {
 			/*
-			   Acknowledge only if read was successful
-			 */
+			  Acknowledge only if read was successful
+			*/
 			diva_data_q_ack_segment4read(q);
 		}
 	}
@@ -399,7 +399,7 @@ int diva_um_idi_write(void *entity,
 	    (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
 		DBG_ERR(("E(%08x) write failed - adapter removed", e))
-		return (-1);
+			return (-1);
 	}
 
 	DBG_TRC(("A(%d) E(%08x) write(%d)", a->adapter_nr, e, length));
@@ -416,9 +416,9 @@ int diva_um_idi_write(void *entity,
 	}
 
 	/*
-	   Copy function does access only locked verified memory,
-	   also it can be called with spin lock held
-	 */
+	  Copy function does access only locked verified memory,
+	  also it can be called with spin lock held
+	*/
 	if ((ret = (*cp_fn) (os_handle, e->buffer, src, length)) < 0) {
 		DBG_TRC(("A: A(%d) E(%08x) write error=%d", a->adapter_nr,
 			 e, ret));
@@ -426,32 +426,32 @@ int diva_um_idi_write(void *entity,
 		return (ret);
 	}
 
-	req = (diva_um_idi_req_hdr_t *) & e->buffer[0];
+	req = (diva_um_idi_req_hdr_t *)&e->buffer[0];
 
 	switch (req->type) {
 	case DIVA_UM_IDI_GET_FEATURES:{
-			DBG_LOG(("A(%d) get_features", a->adapter_nr));
-			if (!(data =
-			     diva_data_q_get_segment4write(&e->data))) {
-				DBG_ERR(("A(%d) get_features, no free buffer",
-					 a->adapter_nr));
-				diva_os_leave_spin_lock(&adapter_lock,
-							&old_irql,
-							"write");
-				return (0);
-			}
-			diva_user_mode_idi_adapter_features(a, &(((diva_um_idi_ind_hdr_t
-								*) data)->hdr.features));
-			((diva_um_idi_ind_hdr_t *) data)->type =
-			    DIVA_UM_IDI_IND_FEATURES;
-			((diva_um_idi_ind_hdr_t *) data)->data_length = 0;
-			diva_data_q_ack_segment4write(&e->data,
-						      sizeof(diva_um_idi_ind_hdr_t));
+		DBG_LOG(("A(%d) get_features", a->adapter_nr));
+		if (!(data =
+		      diva_data_q_get_segment4write(&e->data))) {
+			DBG_ERR(("A(%d) get_features, no free buffer",
+				 a->adapter_nr));
+			diva_os_leave_spin_lock(&adapter_lock,
+						&old_irql,
+						"write");
+			return (0);
+		}
+		diva_user_mode_idi_adapter_features(a, &(((diva_um_idi_ind_hdr_t
+							   *) data)->hdr.features));
+		((diva_um_idi_ind_hdr_t *) data)->type =
+			DIVA_UM_IDI_IND_FEATURES;
+		((diva_um_idi_ind_hdr_t *) data)->data_length = 0;
+		diva_data_q_ack_segment4write(&e->data,
+					      sizeof(diva_um_idi_ind_hdr_t));
 
-			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
+		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");
 
-			diva_os_wakeup_read(e->os_context);
-		}
+		diva_os_wakeup_read(e->os_context);
+	}
 		break;
 
 	case DIVA_UM_IDI_REQ:
@@ -486,9 +486,9 @@ int diva_um_idi_write(void *entity,
 }
 
 /* --------------------------------------------------------------------------
-			CALLBACK FROM XDI
-	 -------------------------------------------------------------------------- */
-static void diva_um_idi_xdi_callback(ENTITY * entity)
+   CALLBACK FROM XDI
+   -------------------------------------------------------------------------- */
+static void diva_um_idi_xdi_callback(ENTITY *entity)
 {
 	divas_um_idi_entity_t *e = DIVAS_CONTAINING_RECORD(entity,
 							   divas_um_idi_entity_t,
@@ -529,8 +529,8 @@ static void diva_um_idi_xdi_callback(ENTITY * entity)
 	}
 }
 
-static int process_idi_request(divas_um_idi_entity_t * e,
-			       const diva_um_idi_req_hdr_t * req)
+static int process_idi_request(divas_um_idi_entity_t *e,
+			       const diva_um_idi_req_hdr_t *req)
 {
 	int assign = 0;
 	byte Req = (byte) req->Req;
@@ -579,7 +579,7 @@ static int process_idi_request(divas_um_idi_entity_t * e,
 	e->e.Req = Req;
 	e->e.ReqCh = (byte) req->ReqCh;
 	e->e.X->PLength = (word) req->data_length;
-	e->e.X->P = (byte *) & req[1];	/* Our buffer is safe */
+	e->e.X->P = (byte *)&req[1];	/* Our buffer is safe */
 
 	DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",
 		 e->adapter->adapter_nr, e, e->e.Id, e->e.Req,
@@ -595,9 +595,9 @@ static int process_idi_request(divas_um_idi_entity_t * e,
 	if (assign) {
 		if (e->e.Rc == OUT_OF_RESOURCES) {
 			/*
-			   XDI has no entities more, call was not forwarded to the card,
-			   no callback will be scheduled
-			 */
+			  XDI has no entities more, call was not forwarded to the card,
+			  no callback will be scheduled
+			*/
 			DBG_ERR(("A: A(%d) E(%08x) XDI out of entities",
 				 e->adapter->adapter_nr, e));
 
@@ -621,7 +621,7 @@ static int process_idi_request(divas_um_idi_entity_t * e,
 	return (0);
 }
 
-static int process_idi_rc(divas_um_idi_entity_t * e, byte rc)
+static int process_idi_rc(divas_um_idi_entity_t *e, byte rc)
 {
 	DBG_TRC(("A(%d) E(%08x) rc(%02x-%02x-%02x)",
 		 e->adapter->adapter_nr, e, e->e.Id, rc, e->e.RcCh));
@@ -674,20 +674,20 @@ static int process_idi_rc(divas_um_idi_entity_t * e, byte rc)
 	return (1);
 }
 
-static int process_idi_ind(divas_um_idi_entity_t * e, byte ind)
+static int process_idi_ind(divas_um_idi_entity_t *e, byte ind)
 {
 	int do_wakeup = 0;
 
 	if (e->e.complete != 0x02) {
 		diva_um_idi_ind_hdr_t *pind =
-		    (diva_um_idi_ind_hdr_t *)
-		    diva_data_q_get_segment4write(&e->data);
+			(diva_um_idi_ind_hdr_t *)
+			diva_data_q_get_segment4write(&e->data);
 		if (pind) {
 			e->e.RNum = 1;
-			e->e.R->P = (byte *) & pind[1];
+			e->e.R->P = (byte *)&pind[1];
 			e->e.R->PLength =
-			    (word) (diva_data_q_get_max_length(&e->data) -
-				    sizeof(*pind));
+				(word) (diva_data_q_get_max_length(&e->data) -
+					sizeof(*pind));
 			DBG_TRC(("A(%d) E(%08x) ind_1(%02x-%02x-%02x)-[%d-%d]",
 				 e->adapter->adapter_nr, e, e->e.Id, ind,
 				 e->e.IndCh, e->e.RLength,
@@ -703,7 +703,7 @@ static int process_idi_ind(divas_um_idi_entity_t * e, byte ind)
 		}
 	} else {
 		diva_um_idi_ind_hdr_t *pind =
-		    (diva_um_idi_ind_hdr_t *) (e->e.R->P);
+			(diva_um_idi_ind_hdr_t *) (e->e.R->P);
 
 		DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-[%d]",
 			 e->adapter->adapter_nr, e, e->e.Id, ind,
@@ -728,14 +728,14 @@ static int process_idi_ind(divas_um_idi_entity_t * e, byte ind)
 }
 
 /* --------------------------------------------------------------------------
-		Write return code to the return code queue of entity
-	 -------------------------------------------------------------------------- */
-static int write_return_code(divas_um_idi_entity_t * e, byte rc)
+   Write return code to the return code queue of entity
+   -------------------------------------------------------------------------- */
+static int write_return_code(divas_um_idi_entity_t *e, byte rc)
 {
 	diva_um_idi_ind_hdr_t *prc;
 
 	if (!(prc =
-	     (diva_um_idi_ind_hdr_t *) diva_data_q_get_segment4write(&e->rc)))
+	      (diva_um_idi_ind_hdr_t *) diva_data_q_get_segment4write(&e->rc)))
 	{
 		DBG_ERR(("A: A(%d) E(%08x) rc(%02x) lost",
 			 e->adapter->adapter_nr, e, rc));
@@ -753,9 +753,9 @@ static int write_return_code(divas_um_idi_entity_t * e, byte rc)
 }
 
 /* --------------------------------------------------------------------------
-		Return amount of entries that can be bead from this entity or
-		-1 if adapter was removed
-	 -------------------------------------------------------------------------- */
+   Return amount of entries that can be bead from this entity or
+   -1 if adapter was removed
+   -------------------------------------------------------------------------- */
 int diva_user_mode_idi_ind_ready(void *entity, void *os_handle)
 {
 	divas_um_idi_entity_t *e;
@@ -771,16 +771,16 @@ int diva_user_mode_idi_ind_ready(void *entity, void *os_handle)
 
 	if ((!a) || (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {
 		/*
-		   Adapter was unloaded
-		 */
+		  Adapter was unloaded
+		*/
 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");
 		return (-1);	/* adapter was removed */
 	}
 	if (e->status & DIVA_UM_IDI_REMOVED) {
 		/*
-		   entity was removed as result of adapter removal
-		   user should assign this entity again
-		 */
+		  entity was removed as result of adapter removal
+		  user should assign this entity again
+		*/
 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");
 		return (-1);
 	}
@@ -827,7 +827,7 @@ int divas_um_idi_entity_assigned(void *entity)
 	DBG_TRC(("Id:%02x, rc_count:%d, status:%08x", e->e.Id, e->rc_count,
 		 e->status))
 
-	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?");
+		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?");
 
 	return (ret);
 }
@@ -850,23 +850,23 @@ int divas_um_idi_entity_start_remove(void *entity)
 
 	if (e->rc_count) {
 		/*
-		   Entity BUSY
-		 */
+		  Entity BUSY
+		*/
 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");
 		return (1);
 	}
 
 	if (!e->e.Id) {
 		/*
-		   Remove request was already pending, and arrived now
-		 */
+		  Remove request was already pending, and arrived now
+		*/
 		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");
 		return (0);	/* REMOVE was pending */
 	}
 
 	/*
-	   Now send remove request
-	 */
+	  Now send remove request
+	*/
 	e->e.Req = REMOVE;
 	e->e.ReqCh = 0;
 
diff --git a/drivers/isdn/hardware/eicon/um_idi.h b/drivers/isdn/hardware/eicon/um_idi.h
index 141072f..ffb88f7 100644
--- a/drivers/isdn/hardware/eicon/um_idi.h
+++ b/drivers/isdn/hardware/eicon/um_idi.h
@@ -6,7 +6,7 @@
 
 /*
   interface between UM IDI core and OS dependent part
-  */
+*/
 int diva_user_mode_idi_init(void);
 void diva_user_mode_idi_finit(void);
 void *divas_um_idi_create_entity(dword adapter_nr, void *file);
diff --git a/drivers/isdn/hardware/eicon/xdi_adapter.h b/drivers/isdn/hardware/eicon/xdi_adapter.h
index a3bd163..d303e65 100644
--- a/drivers/isdn/hardware/eicon/xdi_adapter.h
+++ b/drivers/isdn/hardware/eicon/xdi_adapter.h
@@ -24,12 +24,12 @@ typedef union _divas_card_resources {
 } divas_card_resources_t;
 
 struct _diva_os_xdi_adapter;
-typedef int (*diva_init_card_proc_t) (struct _diva_os_xdi_adapter * a);
-typedef int (*diva_cmd_card_proc_t) (struct _diva_os_xdi_adapter * a,
-				     diva_xdi_um_cfg_cmd_t * data,
-				     int length);
-typedef void (*diva_xdi_clear_interrupts_proc_t) (struct
-						  _diva_os_xdi_adapter *);
+typedef int (*diva_init_card_proc_t)(struct _diva_os_xdi_adapter *a);
+typedef int (*diva_cmd_card_proc_t)(struct _diva_os_xdi_adapter *a,
+				    diva_xdi_um_cfg_cmd_t *data,
+				    int length);
+typedef void (*diva_xdi_clear_interrupts_proc_t)(struct
+						 _diva_os_xdi_adapter *);
 
 #define DIVA_XDI_MBOX_BUSY			1
 #define DIVA_XDI_MBOX_WAIT_XLOG	2
diff --git a/drivers/isdn/hardware/eicon/xdi_msg.h b/drivers/isdn/hardware/eicon/xdi_msg.h
index 3ade28f..58368f7 100644
--- a/drivers/isdn/hardware/eicon/xdi_msg.h
+++ b/drivers/isdn/hardware/eicon/xdi_msg.h
@@ -80,7 +80,7 @@
 
 /*
   Set untranslated protocol code features
-  */
+*/
 #define DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES	11
 
 typedef struct _diva_xdi_um_cfg_cmd_data_set_features {
diff --git a/drivers/isdn/hardware/eicon/xdi_vers.h b/drivers/isdn/hardware/eicon/xdi_vers.h
index cf34941..b3479e5 100644
--- a/drivers/isdn/hardware/eicon/xdi_vers.h
+++ b/drivers/isdn/hardware/eicon/xdi_vers.h
@@ -1,26 +1,26 @@
 
 /*
  *
-  Copyright (c) Eicon Networks, 2002.
+ Copyright (c) Eicon Networks, 2002.
  *
-  This source file is supplied for the use with
-  Eicon Networks range of DIVA Server Adapters.
+ This source file is supplied for the use with
+ Eicon Networks range of DIVA Server Adapters.
  *
-  Eicon File Revision :    2.1
+ Eicon File Revision :    2.1
  *
-  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, or (at your option)
-  any later version.
+ 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, or (at your option)
+ any later version.
  *
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
-  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-  See the GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
+ 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.
+ 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.
  *
  */
-static char diva_xdi_common_code_build[] = "102-52"; 
+static char diva_xdi_common_code_build[] = "102-52";
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
index 861b651..05ed4d0c 100644
--- a/drivers/isdn/hardware/mISDN/avmfritz.c
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -257,10 +257,10 @@ static struct bchannel *
 Sel_BCS(struct fritzcard *fc, u32 channel)
 {
 	if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) &&
-		(fc->bch[0].nr & channel))
+	    (fc->bch[0].nr & channel))
 		return &fc->bch[0];
 	else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) &&
-		(fc->bch[1].nr & channel))
+		 (fc->bch[1].nr & channel))
 		return &fc->bch[1];
 	else
 		return NULL;
@@ -277,7 +277,7 @@ __write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
 static inline void
 __write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
 	outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
-		AVM_HDLC_STATUS_1));
+					  AVM_HDLC_STATUS_1));
 }
 
 void
@@ -287,7 +287,7 @@ write_ctrl(struct bchannel *bch, int which) {
 
 	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
 	pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr,
-		which, hdlc->ctrl.ctrl);
+		 which, hdlc->ctrl.ctrl);
 	switch (fc->type) {
 	case AVM_FRITZ_PCIV2:
 		__write_ctrl_pciv2(fc, hdlc, bch->nr);
@@ -310,7 +310,7 @@ static inline u32
 __read_status_pciv2(u_long addr, u32 channel)
 {
 	return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
-		AVM_HDLC_STATUS_1));
+			   AVM_HDLC_STATUS_1));
 }
 
 
@@ -349,7 +349,7 @@ modehdlc(struct bchannel *bch, int protocol)
 
 	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
 	pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name,
-		'@' + bch->nr, bch->state, protocol, bch->nr);
+		 '@' + bch->nr, bch->state, protocol, bch->nr);
 	hdlc->ctrl.ctrl = 0;
 	switch (protocol) {
 	case -1: /* used for init */
@@ -411,14 +411,14 @@ hdlc_empty_fifo(struct bchannel *bch, int count)
 	}
 	if ((bch->rx_skb->len + count) > bch->maxlen) {
 		pr_debug("%s: overrun %d\n", fc->name,
-			bch->rx_skb->len + count);
+			 bch->rx_skb->len + count);
 		return;
 	}
 	p = skb_put(bch->rx_skb, count);
 	ptr = (u32 *)p;
 	if (AVM_FRITZ_PCIV2 == fc->type)
 		addr = fc->addr + (bch->nr == 2 ?
-			AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
+				   AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
 	else {
 		addr = fc->addr + CHIP_WINDOW;
 		outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr);
@@ -431,7 +431,7 @@ hdlc_empty_fifo(struct bchannel *bch, int count)
 	}
 	if (debug & DEBUG_HW_BFIFO) {
 		snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
-			bch->nr, fc->name, count);
+			 bch->nr, fc->name, count);
 		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
 	}
 }
@@ -460,14 +460,14 @@ hdlc_fill_fifo(struct bchannel *bch)
 			hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
 	}
 	pr_debug("%s: %s %d/%d/%d", fc->name, __func__, count,
-		bch->tx_idx, bch->tx_skb->len);
+		 bch->tx_idx, bch->tx_skb->len);
 	ptr = (u32 *)p;
 	bch->tx_idx += count;
 	hdlc->ctrl.sr.xml = ((count == HDLC_FIFO_SIZE) ? 0 : count);
 	if (AVM_FRITZ_PCIV2 == fc->type) {
 		__write_ctrl_pciv2(fc, hdlc, bch->nr);
 		addr = fc->addr + (bch->nr == 2 ?
-			AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
+				   AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
 	} else {
 		__write_ctrl_pci(fc, hdlc, bch->nr);
 		addr = fc->addr + CHIP_WINDOW;
@@ -480,7 +480,7 @@ hdlc_fill_fifo(struct bchannel *bch)
 	}
 	if (debug & DEBUG_HW_BFIFO) {
 		snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
-			bch->nr, fc->name, count);
+			 bch->nr, fc->name, count);
 		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
 	}
 }
@@ -528,14 +528,14 @@ HDLC_irq(struct bchannel *bch, u32 stat)
 			if (!bch->rx_skb)
 				goto handle_tx;
 			if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT,
-			    &bch->Flags)) {
+							       &bch->Flags)) {
 				if (((stat & HDLC_STAT_CRCVFRRAB) ==
-				    HDLC_STAT_CRCVFR) ||
+				     HDLC_STAT_CRCVFR) ||
 				    test_bit(FLG_TRANSPARENT, &bch->Flags)) {
 					recv_Bchannel(bch, 0);
 				} else {
 					pr_debug("%s: got invalid frame\n",
-						fc->name);
+						 fc->name);
 					skb_trim(bch->rx_skb, 0);
 				}
 			}
@@ -549,11 +549,11 @@ handle_tx:
 		 */
 		if (bch->tx_skb)
 			pr_debug("%s: ch%d XDU len(%d) idx(%d) Flags(%lx)\n",
-				fc->name, bch->nr, bch->tx_skb->len,
-				bch->tx_idx, bch->Flags);
+				 fc->name, bch->nr, bch->tx_skb->len,
+				 bch->tx_idx, bch->Flags);
 		else
 			pr_debug("%s: ch%d XDU no tx_skb Flags(%lx)\n",
-				fc->name, bch->nr, bch->Flags);
+				 fc->name, bch->nr, bch->Flags);
 		if (bch->tx_skb && bch->tx_skb->len) {
 			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
 				bch->tx_idx = 0;
@@ -685,7 +685,7 @@ avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(&fc->lock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				NULL, GFP_KERNEL);
+				    NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		spin_lock_irqsave(&fc->lock, flags);
@@ -693,7 +693,7 @@ avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		modehdlc(bch, ISDN_P_NONE);
 		spin_unlock_irqrestore(&fc->lock, flags);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	}
@@ -749,7 +749,7 @@ reset_avm(struct fritzcard *fc)
 	mdelay(1);
 	if (debug & DEBUG_HW)
 		pr_notice("%s: S0/S1 %x/%x\n", fc->name,
-			inb(fc->addr + 2), inb(fc->addr + 3));
+			  inb(fc->addr + 2), inb(fc->addr + 3));
 }
 
 static int
@@ -761,10 +761,10 @@ init_card(struct fritzcard *fc)
 	reset_avm(fc); /* disable IRQ */
 	if (fc->type == AVM_FRITZ_PCIV2)
 		ret = request_irq(fc->irq, avm_fritzv2_interrupt,
-			IRQF_SHARED, fc->name, fc);
+				  IRQF_SHARED, fc->name, fc);
 	else
 		ret = request_irq(fc->irq, avm_fritz_interrupt,
-			IRQF_SHARED, fc->name, fc);
+				  IRQF_SHARED, fc->name, fc);
 	if (ret) {
 		pr_info("%s: couldn't get interrupt %d\n",
 			fc->name, fc->irq);
@@ -795,7 +795,7 @@ init_card(struct fritzcard *fc)
 		msleep_interruptible(10);
 		if (debug & DEBUG_HW)
 			pr_notice("%s: IRQ %d count %d\n", fc->name,
-				fc->irq, fc->irqcnt);
+				  fc->irq, fc->irqcnt);
 		if (!fc->irqcnt) {
 			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
 				fc->name, fc->irq, 3 - cnt);
@@ -817,7 +817,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_GETOP:
 		cq->op = 0;
 		break;
-	/* Nothing implemented yet */
+		/* Nothing implemented yet */
 	case MISDN_CTRL_FILL_EMPTY:
 	default:
 		pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
@@ -931,7 +931,7 @@ avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	case CLOSE_CHANNEL:
 		pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id,
-			__builtin_return_address(0));
+			 __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -939,7 +939,7 @@ avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	default:
 		pr_debug("%s: %s unknown command %x\n",
-			fc->name, __func__, cmd);
+			 fc->name, __func__, cmd);
 		return -EINVAL;
 	}
 	return err;
@@ -963,7 +963,7 @@ setup_fritz(struct fritzcard *fc)
 		if (debug & DEBUG_HW) {
 			pr_notice("%s: PCI stat %#x\n", fc->name, val);
 			pr_notice("%s: PCI Class %X Rev %d\n", fc->name,
-				val & 0xff, (val >> 8) & 0xff);
+				  val & 0xff, (val >> 8) & 0xff);
 			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
 		}
 		ASSIGN_FUNC(V1, ISAC, fc->isac);
@@ -975,7 +975,7 @@ setup_fritz(struct fritzcard *fc)
 		if (debug & DEBUG_HW) {
 			pr_notice("%s: PCI V2 stat %#x\n", fc->name, val);
 			pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name,
-				val & 0xff, (val>>8) & 0xff);
+				  val & 0xff, (val >> 8) & 0xff);
 			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
 		}
 		ASSIGN_FUNC(V2, ISAC, fc->isac);
@@ -987,8 +987,8 @@ setup_fritz(struct fritzcard *fc)
 		return -ENODEV;
 	}
 	pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name,
-		(fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
-		"AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
+		  (fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
+		  "AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
 	return 0;
 }
 
@@ -1035,7 +1035,7 @@ setup_instance(struct fritzcard *card)
 	mISDNisac_init(&card->isac, card);
 
 	card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	card->isac.dch.dev.D.ctrl = avm_dctrl;
 	for (i = 0; i < 2; i++) {
 		card->bch[i].nr = i + 1;
@@ -1051,7 +1051,7 @@ setup_instance(struct fritzcard *card)
 	if (err)
 		goto error;
 	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
-		card->name);
+				    card->name);
 	if (err)
 		goto error_reg;
 	err = init_card(card);
@@ -1097,7 +1097,7 @@ fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	pr_notice("mISDN: found adapter %s at %s\n",
-	       (char *) ent->driver_data, pci_name(pdev));
+		  (char *) ent->driver_data, pci_name(pdev));
 
 	card->addr = pci_resource_start(pdev, 1);
 	card->irq = pdev->irq;
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index 0c77386..b0588ac 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -33,13 +33,13 @@
  */
 
 /*
-#define MAX_FRAME_SIZE	2048
+  #define MAX_FRAME_SIZE	2048
 */
 
 struct hfc_chan {
 	struct dchannel	*dch;	/* link if channel is a D-channel */
 	struct bchannel	*bch;	/* link if channel is a B-channel */
-	int		port; 	/* the interface port this */
+	int		port;	/* the interface port this */
 				/* channel is associated with */
 	int		nt_timer; /* -1 if off, 0 if elapsed, >0 if running */
 	int		los, ais, slip_tx, slip_rx, rdi; /* current alarms */
@@ -89,7 +89,7 @@ struct hfcm_hw {
 #define	HFC_CFG_REPORT_RDI	8 /* the card should report remote alarm */
 #define	HFC_CFG_DTMF		9 /* enable DTMF-detection */
 #define	HFC_CFG_CRC4		10 /* disable CRC-4 Multiframe mode, */
-					/* use double frame instead. */
+/* use double frame instead. */
 
 #define HFC_TYPE_E1		1 /* controller is HFC-E1 */
 #define HFC_TYPE_4S		4 /* controller is HFC-4S */
@@ -109,9 +109,9 @@ struct hfcm_hw {
 #define	HFC_CHIP_E1CLOCK_GET	10 /* always get clock from E1 interface */
 #define	HFC_CHIP_E1CLOCK_PUT	11 /* always put clock from E1 interface */
 #define	HFC_CHIP_WATCHDOG	12 /* whether we should send signals */
-					/* to the watchdog */
+/* to the watchdog */
 #define	HFC_CHIP_B410P		13 /* whether we have a b410p with echocan in */
-					/* hw */
+/* hw */
 #define	HFC_CHIP_PLXSD		14 /* whether we have a Speech-Design PLX */
 #define	HFC_CHIP_EMBSD          15 /* whether we have a SD Embedded board */
 
@@ -148,26 +148,26 @@ struct hfc_multi {
 	int		io_mode; /* selects mode */
 #ifdef HFC_REGISTER_DEBUG
 	void		(*HFC_outb)(struct hfc_multi *hc, u_char reg,
-				u_char val, const char *function, int line);
+				    u_char val, const char *function, int line);
 	void		(*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg,
-				u_char val, const char *function, int line);
+					    u_char val, const char *function, int line);
 	u_char		(*HFC_inb)(struct hfc_multi *hc, u_char reg,
-				const char *function, int line);
+				   const char *function, int line);
 	u_char		(*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg,
-				const char *function, int line);
+					   const char *function, int line);
 	u_short		(*HFC_inw)(struct hfc_multi *hc, u_char reg,
-				const char *function, int line);
+				   const char *function, int line);
 	u_short		(*HFC_inw_nodebug)(struct hfc_multi *hc, u_char reg,
-				const char *function, int line);
+					   const char *function, int line);
 	void		(*HFC_wait)(struct hfc_multi *hc,
-				const char *function, int line);
+				    const char *function, int line);
 	void		(*HFC_wait_nodebug)(struct hfc_multi *hc,
-				const char *function, int line);
+					    const char *function, int line);
 #else
 	void		(*HFC_outb)(struct hfc_multi *hc, u_char reg,
-				u_char val);
+				    u_char val);
 	void		(*HFC_outb_nodebug)(struct hfc_multi *hc, u_char reg,
-				u_char val);
+					    u_char val);
 	u_char		(*HFC_inb)(struct hfc_multi *hc, u_char reg);
 	u_char		(*HFC_inb_nodebug)(struct hfc_multi *hc, u_char reg);
 	u_short		(*HFC_inw)(struct hfc_multi *hc, u_char reg);
@@ -176,9 +176,9 @@ struct hfc_multi {
 	void		(*HFC_wait_nodebug)(struct hfc_multi *hc);
 #endif
 	void		(*read_fifo)(struct hfc_multi *hc, u_char *data,
-				int len);
+				     int len);
 	void		(*write_fifo)(struct hfc_multi *hc, u_char *data,
-				int len);
+				      int len);
 	u_long		pci_origmembase, plx_origmembase;
 	void __iomem	*pci_membase; /* PCI memory */
 	void __iomem	*plx_membase; /* PLX memory */
@@ -211,10 +211,10 @@ struct hfc_multi {
 					/* an optical Interface */
 	int		dslot;	/* channel # of d-channel (E1) default 16 */
 
-	u_long		wdcount; 	/* every 500 ms we need to */
+	u_long		wdcount;	/* every 500 ms we need to */
 					/* send the watchdog a signal */
 	u_char		wdbyte; /* watchdog toggle byte */
-	u_int		activity[8]; 	/* if there is any action on this */
+	u_int		activity[8];	/* if there is any action on this */
 					/* port (will be cleared after */
 					/* showing led-states) */
 	int		e1_state; /* keep track of last state */
@@ -268,7 +268,7 @@ struct hfc_multi {
 #define PLX_DSP_RES_N		PLX_GPIO8
 /* GPIO4..8 Enable & Set to OUT, SLAVE_EN_N = 1 */
 #define PLX_GPIOC_INIT		(PLX_GPIO4_DIR | PLX_GPIO5_DIR | PLX_GPIO6_DIR \
-			| PLX_GPIO7_DIR | PLX_GPIO8_DIR | PLX_SLAVE_EN_N)
+				 | PLX_GPIO7_DIR | PLX_GPIO8_DIR | PLX_SLAVE_EN_N)
 
 /* PLX Interrupt Control/STATUS */
 #define PLX_INTCSR_LINTI1_ENABLE 0x01
@@ -290,7 +290,7 @@ struct hfc_multi {
 /* write only registers */
 #define R_CIRM			0x00
 #define R_CTRL			0x01
-#define R_BRG_PCM_CFG 		0x02
+#define R_BRG_PCM_CFG		0x02
 #define R_RAM_ADDR0		0x08
 #define R_RAM_ADDR1		0x09
 #define R_RAM_ADDR2		0x0A
@@ -687,8 +687,8 @@ struct hfc_multi {
 #define V_NEG_CLK		0x08
 #define V_HCLK			0x10
 /*
-#define V_JATT_AUTO_DEL		0x20
-#define V_JATT_AUTO		0x40
+  #define V_JATT_AUTO_DEL		0x20
+  #define V_JATT_AUTO		0x40
 */
 #define V_JATT_OFF		0x80
 /* R_STATE */
@@ -1230,4 +1230,3 @@ struct hfc_register_names {
 	{"R_IRQ_FIFO_BL7",	0xCF},
 };
 #endif /* HFC_REGISTER_DEBUG */
-
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
index 45ddced..0eafe9f 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
@@ -16,9 +16,9 @@
 static void
 #ifdef HFC_REGISTER_DEBUG
 HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val,
-		const char *function, int line)
+	       const char *function, int line)
 #else
-HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
+	HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
 #endif
 {
 	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
@@ -30,7 +30,7 @@ static u_char
 #ifdef HFC_REGISTER_DEBUG
 HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
 #else
-HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
+	HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
 #endif
 {
 	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
@@ -42,7 +42,7 @@ static u_short
 #ifdef HFC_REGISTER_DEBUG
 HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
 #else
-HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
+	HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
 #endif
 {
 	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
@@ -54,7 +54,7 @@ static void
 #ifdef HFC_REGISTER_DEBUG
 HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line)
 #else
-HFC_wait_embsd(struct hfc_multi *hc)
+	HFC_wait_embsd(struct hfc_multi *hc)
 #endif
 {
 	hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
@@ -96,8 +96,8 @@ static int
 setup_embedded(struct hfc_multi *hc, struct hm_map *m)
 {
 	printk(KERN_INFO
-	    "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
-	    m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
+	       "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
+	       m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
 
 	hc->pci_dev = NULL;
 	if (m->clock2)
@@ -129,20 +129,20 @@ setup_embedded(struct hfc_multi *hc, struct hm_map *m)
 		hc->write_fifo = write_fifo_embsd;
 		hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id;
 		hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase,
-				XHFC_MEMSIZE);
+						     XHFC_MEMSIZE);
 		if (!hc->xhfc_membase) {
 			printk(KERN_WARNING
-			    "HFC-multi: failed to remap xhfc address space. "
-			    "(internal error)\n");
+			       "HFC-multi: failed to remap xhfc address space. "
+			       "(internal error)\n");
 			return -EIO;
 		}
 		hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4);
 		hc->xhfc_memdata = (u_long *)(hc->xhfc_membase);
 		printk(KERN_INFO
-		    "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
-		    "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
-		    (u_long)hc->xhfc_membase, hc->xhfc_origmembase,
-		    (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
+		       "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
+		       "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
+		       (u_long)hc->xhfc_membase, hc->xhfc_origmembase,
+		       (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
 		break;
 	default:
 		printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h
index 3132ddc..411cd10 100644
--- a/drivers/isdn/hardware/mISDN/hfc_pci.h
+++ b/drivers/isdn/hardware/mISDN/hfc_pci.h
@@ -58,7 +58,7 @@
 /* GCI/IOM bus configuration registers */
 #define HFCPCI_MST_EMOD		0xB4
 #define HFCPCI_MST_MODE		0xB8
-#define HFCPCI_CONNECT 		0xBC
+#define HFCPCI_CONNECT		0xBC
 
 
 /* Interrupt and status registers */
@@ -189,18 +189,18 @@ struct zt {
 
 struct dfifo {
 	u_char data[D_FIFO_SIZE]; /* FIFO data space */
-	u_char fill1[0x20A0-D_FIFO_SIZE]; /* reserved, do not use */
+	u_char fill1[0x20A0 - D_FIFO_SIZE]; /* reserved, do not use */
 	u_char f1, f2; /* f pointers */
-	u_char fill2[0x20C0-0x20A2]; /* reserved, do not use */
+	u_char fill2[0x20C0 - 0x20A2]; /* reserved, do not use */
 	/* mask index with D_FREG_MASK for access */
-	struct zt za[MAX_D_FRAMES+1];
-	u_char fill3[0x4000-0x2100]; /* align 16K */
+	struct zt za[MAX_D_FRAMES + 1];
+	u_char fill3[0x4000 - 0x2100]; /* align 16K */
 };
 
 struct bzfifo {
-	struct zt	za[MAX_B_FRAMES+1]; /* only range 0x0..0x1F allowed */
+	struct zt	za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */
 	u_char		f1, f2; /* f pointers */
-	u_char		fill[0x2100-0x2082]; /* alignment */
+	u_char		fill[0x2100 - 0x2082]; /* alignment */
 };
 
 
@@ -224,5 +224,5 @@ union fifo_area {
 	u_char fill[32768];
 };
 
-#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io)+b))
-#define Read_hfc(a, b) (readb((a->hw.pci_io)+b))
+#define Write_hfc(a, b, c) (writeb(c, (a->hw.pci_io) + b))
+#define Read_hfc(a, b) (readb((a->hw.pci_io) + b))
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index a440d7f..0332231 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -142,7 +142,7 @@
  *
  * hwid:
  *	NOTE: only one hwid value must be given once
- * 	Enable special embedded devices with XHFC controllers.
+ *	Enable special embedded devices with XHFC controllers.
  */
 
 /*
@@ -161,8 +161,8 @@
 #include <linux/mISDNdsp.h>
 
 /*
-#define IRQCOUNT_DEBUG
-#define IRQ_DEBUG
+  #define IRQCOUNT_DEBUG
+  #define IRQ_DEBUG
 */
 
 #include "hfc_multi.h"
@@ -237,21 +237,21 @@ module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
 module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
 
 #ifdef HFC_REGISTER_DEBUG
-#define HFC_outb(hc, reg, val) \
+#define HFC_outb(hc, reg, val)					\
 	(hc->HFC_outb(hc, reg, val, __func__, __LINE__))
-#define HFC_outb_nodebug(hc, reg, val) \
+#define HFC_outb_nodebug(hc, reg, val)					\
 	(hc->HFC_outb_nodebug(hc, reg, val, __func__, __LINE__))
-#define HFC_inb(hc, reg) \
+#define HFC_inb(hc, reg)				\
 	(hc->HFC_inb(hc, reg, __func__, __LINE__))
-#define HFC_inb_nodebug(hc, reg) \
+#define HFC_inb_nodebug(hc, reg)				\
 	(hc->HFC_inb_nodebug(hc, reg, __func__, __LINE__))
-#define HFC_inw(hc, reg) \
+#define HFC_inw(hc, reg)				\
 	(hc->HFC_inw(hc, reg, __func__, __LINE__))
-#define HFC_inw_nodebug(hc, reg) \
+#define HFC_inw_nodebug(hc, reg)				\
 	(hc->HFC_inw_nodebug(hc, reg, __func__, __LINE__))
-#define HFC_wait(hc) \
+#define HFC_wait(hc)				\
 	(hc->HFC_wait(hc, __func__, __LINE__))
-#define HFC_wait_nodebug(hc) \
+#define HFC_wait_nodebug(hc)				\
 	(hc->HFC_wait_nodebug(hc, __func__, __LINE__))
 #else
 #define HFC_outb(hc, reg, val)		(hc->HFC_outb(hc, reg, val))
@@ -274,7 +274,7 @@ static void
 HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,
 		const char *function, int line)
 #else
-HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
+	HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
 #endif
 {
 	writeb(val, hc->pci_membase + reg);
@@ -283,7 +283,7 @@ static u_char
 #ifdef HFC_REGISTER_DEBUG
 HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
 #else
-HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
+	HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
 #endif
 {
 	return readb(hc->pci_membase + reg);
@@ -292,7 +292,7 @@ static u_short
 #ifdef HFC_REGISTER_DEBUG
 HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
 #else
-HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
+	HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
 #endif
 {
 	return readw(hc->pci_membase + reg);
@@ -301,7 +301,7 @@ static void
 #ifdef HFC_REGISTER_DEBUG
 HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)
 #else
-HFC_wait_pcimem(struct hfc_multi *hc)
+	HFC_wait_pcimem(struct hfc_multi *hc)
 #endif
 {
 	while (readb(hc->pci_membase + R_STATUS) & V_BUSY)
@@ -312,9 +312,9 @@ HFC_wait_pcimem(struct hfc_multi *hc)
 static void
 #ifdef HFC_REGISTER_DEBUG
 HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,
-	const char *function, int line)
+	       const char *function, int line)
 #else
-HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
+	HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
 #endif
 {
 	outb(reg, hc->pci_iobase + 4);
@@ -324,7 +324,7 @@ static u_char
 #ifdef HFC_REGISTER_DEBUG
 HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
 #else
-HFC_inb_regio(struct hfc_multi *hc, u_char reg)
+	HFC_inb_regio(struct hfc_multi *hc, u_char reg)
 #endif
 {
 	outb(reg, hc->pci_iobase + 4);
@@ -334,7 +334,7 @@ static u_short
 #ifdef HFC_REGISTER_DEBUG
 HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
 #else
-HFC_inw_regio(struct hfc_multi *hc, u_char reg)
+	HFC_inw_regio(struct hfc_multi *hc, u_char reg)
 #endif
 {
 	outb(reg, hc->pci_iobase + 4);
@@ -344,7 +344,7 @@ static void
 #ifdef HFC_REGISTER_DEBUG
 HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)
 #else
-HFC_wait_regio(struct hfc_multi *hc)
+	HFC_wait_regio(struct hfc_multi *hc)
 #endif
 {
 	outb(R_STATUS, hc->pci_iobase + 4);
@@ -355,7 +355,7 @@ HFC_wait_regio(struct hfc_multi *hc)
 #ifdef HFC_REGISTER_DEBUG
 static void
 HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
-		const char *function, int line)
+	       const char *function, int line)
 {
 	char regname[256] = "", bits[9] = "xxxxxxxx";
 	int i;
@@ -377,8 +377,8 @@ HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
 	bits[1] = '0' + (!!(val & 64));
 	bits[0] = '0' + (!!(val & 128));
 	printk(KERN_DEBUG
-	    "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
-	    hc->id, reg, regname, val, bits, function, line);
+	       "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
+	       hc->id, reg, regname, val, bits, function, line);
 	HFC_outb_nodebug(hc, reg, val);
 }
 static u_char
@@ -407,8 +407,8 @@ HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
 	bits[1] = '0' + (!!(val & 64));
 	bits[0] = '0' + (!!(val & 128));
 	printk(KERN_DEBUG
-	    "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
-	    hc->id, reg, regname, val, bits, function, line);
+	       "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
+	       hc->id, reg, regname, val, bits, function, line);
 	return val;
 }
 static u_short
@@ -429,15 +429,15 @@ HFC_inw_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
 		strcpy(regname, "register");
 
 	printk(KERN_DEBUG
-	    "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
-	    hc->id, reg, regname, val, function, line);
+	       "HFC_inw(chip %d, %02x=%s) = 0x%04x; in %s() line %d\n",
+	       hc->id, reg, regname, val, function, line);
 	return val;
 }
 static void
 HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
 {
 	printk(KERN_DEBUG "HFC_wait(chip %d); in %s() line %d\n",
-	    hc->id, function, line);
+	       hc->id, function, line);
 	HFC_wait_nodebug(hc);
 }
 #endif
@@ -446,13 +446,13 @@ HFC_wait_debug(struct hfc_multi *hc, const char *function, int line)
 static void
 write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
 {
-	outb(A_FIFO_DATA0, (hc->pci_iobase)+4);
-	while (len>>2) {
+	outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
+	while (len >> 2) {
 		outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase);
 		data += 4;
 		len -= 4;
 	}
-	while (len>>1) {
+	while (len >> 1) {
 		outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase);
 		data += 2;
 		len -= 2;
@@ -467,15 +467,15 @@ write_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
 static void
 write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
 {
-	while (len>>2) {
+	while (len >> 2) {
 		writel(cpu_to_le32(*(u32 *)data),
-			hc->pci_membase + A_FIFO_DATA0);
+		       hc->pci_membase + A_FIFO_DATA0);
 		data += 4;
 		len -= 4;
 	}
-	while (len>>1) {
+	while (len >> 1) {
 		writew(cpu_to_le16(*(u16 *)data),
-			hc->pci_membase + A_FIFO_DATA0);
+		       hc->pci_membase + A_FIFO_DATA0);
 		data += 2;
 		len -= 2;
 	}
@@ -490,13 +490,13 @@ write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
 static void
 read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
 {
-	outb(A_FIFO_DATA0, (hc->pci_iobase)+4);
-	while (len>>2) {
+	outb(A_FIFO_DATA0, (hc->pci_iobase) + 4);
+	while (len >> 2) {
 		*(u32 *)data = le32_to_cpu(inl(hc->pci_iobase));
 		data += 4;
 		len -= 4;
 	}
-	while (len>>1) {
+	while (len >> 1) {
 		*(u16 *)data = le16_to_cpu(inw(hc->pci_iobase));
 		data += 2;
 		len -= 2;
@@ -512,13 +512,13 @@ read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
 static void
 read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
 {
-	while (len>>2) {
+	while (len >> 2) {
 		*(u32 *)data =
 			le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0));
 		data += 4;
 		len -= 4;
 	}
-	while (len>>1) {
+	while (len >> 1) {
 		*(u16 *)data =
 			le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0));
 		data += 2;
@@ -607,7 +607,7 @@ writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data)
 	outw(cipv, hc->pci_iobase + 4);
 	/* define a 32 bit dword with 4 identical bytes for write sequence */
 	datav = data | ((__u32) data << 8) | ((__u32) data << 16) |
-	    ((__u32) data << 24);
+		((__u32) data << 24);
 
 	/*
 	 * write this 32 bit dword to the bridge data port
@@ -699,7 +699,7 @@ vpm_in(struct hfc_multi *c, int which, unsigned short addr)
 
 inline void
 vpm_out(struct hfc_multi *c, int which, unsigned short addr,
-    unsigned char data)
+	unsigned char data)
 {
 	vpm_write_address(c, addr);
 
@@ -717,11 +717,11 @@ vpm_out(struct hfc_multi *c, int which, unsigned short addr,
 	disablepcibridge(c);
 
 	{
-	unsigned char regin;
-	regin = vpm_in(c, which, addr);
-	if (regin != data)
-		printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
-			"0x%x\n", data, addr, regin);
+		unsigned char regin;
+		regin = vpm_in(c, which, addr);
+		if (regin != data)
+			printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back "
+			       "0x%x\n", data, addr, regin);
 	}
 
 }
@@ -853,16 +853,16 @@ vpm_echocan_on(struct hfc_multi *hc, int ch, int taps)
 
 #ifdef TXADJ
 	skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
-		sizeof(int), &txadj, GFP_ATOMIC);
+			       sizeof(int), &txadj, GFP_ATOMIC);
 	if (skb)
 		recv_Bchannel_skb(bch, skb);
 #endif
 
-	timeslot = ((ch/4)*8) + ((ch%4)*4) + 1;
+	timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
 	unit = ch % 4;
 
 	printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n",
-	    taps, timeslot);
+	       taps, timeslot);
 
 	vpm_out(hc, unit, timeslot, 0x7e);
 }
@@ -886,16 +886,16 @@ vpm_echocan_off(struct hfc_multi *hc, int ch)
 
 #ifdef TXADJ
 	skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX,
-		sizeof(int), &txadj, GFP_ATOMIC);
+			       sizeof(int), &txadj, GFP_ATOMIC);
 	if (skb)
 		recv_Bchannel_skb(bch, skb);
 #endif
 
-	timeslot = ((ch/4)*8) + ((ch%4)*4) + 1;
+	timeslot = ((ch / 4) * 8) + ((ch % 4) * 4) + 1;
 	unit = ch % 4;
 
 	printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n",
-	    timeslot);
+	       timeslot);
 	/* FILLME */
 	vpm_out(hc, unit, timeslot, 0x01);
 }
@@ -920,7 +920,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
 
 	if (debug & DEBUG_HFCMULTI_PLXSD)
 		printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n",
-			__func__, syncmaster);
+		       __func__, syncmaster);
 
 	/* select new master */
 	if (newmaster) {
@@ -949,7 +949,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
 				if (hc->ctype == HFC_TYPE_E1) {
 					if (debug & DEBUG_HFCMULTI_PLXSD)
 						printk(KERN_DEBUG
-							"Schedule SYNC_I\n");
+						       "Schedule SYNC_I\n");
 					hc->e1_resync |= 1; /* get SYNC_I */
 				}
 			}
@@ -960,7 +960,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
 		hc = newmaster;
 		if (debug & DEBUG_HFCMULTI_PLXSD)
 			printk(KERN_DEBUG "id=%d (0x%p) = syncronized with "
-				"interface.\n", hc->id, hc);
+			       "interface.\n", hc->id, hc);
 		/* Enable new sync master */
 		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
 		pv = readl(plx_acc_32);
@@ -968,7 +968,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
 		writel(pv, plx_acc_32);
 		/* switch to jatt PLL, if not disabled by RX_SYNC */
 		if (hc->ctype == HFC_TYPE_E1
-				&& !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
+		    && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
 			if (debug & DEBUG_HFCMULTI_PLXSD)
 				printk(KERN_DEBUG "Schedule jatt PLL\n");
 			hc->e1_resync |= 2; /* switch to jatt */
@@ -978,20 +978,20 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
 			hc = pcmmaster;
 			if (debug & DEBUG_HFCMULTI_PLXSD)
 				printk(KERN_DEBUG
-					"id=%d (0x%p) = PCM master syncronized "
-					"with QUARTZ\n", hc->id, hc);
+				       "id=%d (0x%p) = PCM master syncronized "
+				       "with QUARTZ\n", hc->id, hc);
 			if (hc->ctype == HFC_TYPE_E1) {
 				/* Use the crystal clock for the PCM
 				   master card */
 				if (debug & DEBUG_HFCMULTI_PLXSD)
 					printk(KERN_DEBUG
-					    "Schedule QUARTZ for HFC-E1\n");
+					       "Schedule QUARTZ for HFC-E1\n");
 				hc->e1_resync |= 4; /* switch quartz */
 			} else {
 				if (debug & DEBUG_HFCMULTI_PLXSD)
 					printk(KERN_DEBUG
-					    "QUARTZ is automatically "
-					    "enabled by HFC-%dS\n", hc->ctype);
+					       "QUARTZ is automatically "
+					       "enabled by HFC-%dS\n", hc->ctype);
 			}
 			plx_acc_32 = hc->plx_membase + PLX_GPIOC;
 			pv = readl(plx_acc_32);
@@ -1000,7 +1000,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
 		} else
 			if (!rm)
 				printk(KERN_ERR "%s no pcm master, this MUST "
-					"not happen!\n", __func__);
+				       "not happen!\n", __func__);
 	}
 	syncmaster = newmaster;
 
@@ -1016,16 +1016,16 @@ plxsd_checksync(struct hfc_multi *hc, int rm)
 		if (syncmaster == NULL) {
 			if (debug & DEBUG_HFCMULTI_PLXSD)
 				printk(KERN_DEBUG "%s: GOT sync on card %d"
-					" (id=%d)\n", __func__, hc->id + 1,
-					hc->id);
+				       " (id=%d)\n", __func__, hc->id + 1,
+				       hc->id);
 			hfcmulti_resync(hc, hc, rm);
 		}
 	} else {
 		if (syncmaster == hc) {
 			if (debug & DEBUG_HFCMULTI_PLXSD)
 				printk(KERN_DEBUG "%s: LOST sync on card %d"
-					" (id=%d)\n", __func__, hc->id + 1,
-					hc->id);
+				       " (id=%d)\n", __func__, hc->id + 1,
+				       hc->id);
 			hfcmulti_resync(hc, NULL, rm);
 		}
 	}
@@ -1057,7 +1057,7 @@ release_io_hfcmulti(struct hfc_multi *hc)
 	if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) {
 		if (debug & DEBUG_HFCMULTI_PLXSD)
 			printk(KERN_DEBUG "%s: release PLXSD card %d\n",
-			    __func__, hc->id + 1);
+			       __func__, hc->id + 1);
 		spin_lock_irqsave(&plx_lock, plx_flags);
 		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
 		writel(PLX_GPIOC_INIT, plx_acc_32);
@@ -1073,7 +1073,7 @@ release_io_hfcmulti(struct hfc_multi *hc)
 		writel(pv, plx_acc_32);
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",
-				__func__, pv);
+			       __func__, pv);
 		spin_unlock_irqrestore(&plx_lock, plx_flags);
 	}
 
@@ -1131,22 +1131,22 @@ init_chip(struct hfc_multi *hc)
 	}
 	rev = HFC_inb(hc, R_CHIP_RV);
 	printk(KERN_INFO
-	    "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
-	    val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
-		" (old FIFO handling)" : "");
+	       "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
+	       val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
+	       " (old FIFO handling)" : "");
 	if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {
 		test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);
 		printk(KERN_WARNING
-		    "HFC_multi: NOTE: Your chip is revision 0, "
-		    "ask Cologne Chip for update. Newer chips "
-		    "have a better FIFO handling. Old chips "
-		    "still work but may have slightly lower "
-		    "HDLC transmit performance.\n");
+		       "HFC_multi: NOTE: Your chip is revision 0, "
+		       "ask Cologne Chip for update. Newer chips "
+		       "have a better FIFO handling. Old chips "
+		       "still work but may have slightly lower "
+		       "HDLC transmit performance.\n");
 	}
 	if (rev > 1) {
 		printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't "
-		    "consider chip revision = %ld. The chip / "
-		    "bridge may not work.\n", rev);
+		       "consider chip revision = %ld. The chip / "
+		       "bridge may not work.\n", rev);
 	}
 
 	/* set s-ram size */
@@ -1157,7 +1157,7 @@ init_chip(struct hfc_multi *hc)
 	if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n",
-			    __func__);
+			       __func__);
 		hc->hw.r_ctrl |= V_EXT_RAM;
 		hc->hw.r_ram_sz = 1;
 		hc->Flen = 0x20;
@@ -1168,7 +1168,7 @@ init_chip(struct hfc_multi *hc)
 	if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n",
-			    __func__);
+			       __func__);
 		hc->hw.r_ctrl |= V_EXT_RAM;
 		hc->hw.r_ram_sz = 2;
 		hc->Flen = 0x20;
@@ -1190,7 +1190,7 @@ init_chip(struct hfc_multi *hc)
 	if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
 		if (debug & DEBUG_HFCMULTI_PLXSD)
 			printk(KERN_DEBUG "%s: initializing PLXSD card %d\n",
-			    __func__, hc->id + 1);
+			       __func__, hc->id + 1);
 		spin_lock_irqsave(&plx_lock, plx_flags);
 		plx_acc_32 = hc->plx_membase + PLX_GPIOC;
 		writel(PLX_GPIOC_INIT, plx_acc_32);
@@ -1207,7 +1207,7 @@ init_chip(struct hfc_multi *hc)
 		spin_unlock_irqrestore(&plx_lock, plx_flags);
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",
-				__func__, pv);
+			       __func__, pv);
 		/*
 		 * If we are the 3rd PLXSD card or higher, we must turn
 		 * termination of last PLXSD card off.
@@ -1225,8 +1225,8 @@ init_chip(struct hfc_multi *hc)
 		if (plx_count >= 3) {
 			if (debug & DEBUG_HFCMULTI_PLXSD)
 				printk(KERN_DEBUG "%s: card %d is between, so "
-					"we disable termination\n",
-				    __func__, plx_last_hc->id + 1);
+				       "we disable termination\n",
+				       __func__, plx_last_hc->id + 1);
 			spin_lock_irqsave(&plx_lock, plx_flags);
 			plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC;
 			pv = readl(plx_acc_32);
@@ -1235,8 +1235,8 @@ init_chip(struct hfc_multi *hc)
 			spin_unlock_irqrestore(&plx_lock, plx_flags);
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: term off: PLX_GPIO=%x\n",
-				    __func__, pv);
+				       "%s: term off: PLX_GPIO=%x\n",
+				       __func__, pv);
 		}
 		spin_unlock_irqrestore(&HFClock, hfc_flags);
 		hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
@@ -1253,24 +1253,24 @@ init_chip(struct hfc_multi *hc)
 	if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: setting PCM into slave mode\n",
-			    __func__);
+			       __func__);
 	} else
-	if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: setting PCM into master mode\n",
-			    __func__);
-		hc->hw.r_pcm_md0 |= V_PCM_MD;
-	} else {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: performing PCM auto detect\n",
-			    __func__);
-	}
+		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) {
+			if (debug & DEBUG_HFCMULTI_INIT)
+				printk(KERN_DEBUG "%s: setting PCM into master mode\n",
+				       __func__);
+			hc->hw.r_pcm_md0 |= V_PCM_MD;
+		} else {
+			if (debug & DEBUG_HFCMULTI_INIT)
+				printk(KERN_DEBUG "%s: performing PCM auto detect\n",
+				       __func__);
+		}
 
 	/* soft reset */
 	HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);
 	if (hc->ctype == HFC_TYPE_XHFC)
 		HFC_outb(hc, 0x0C /* R_FIFO_THRES */,
-				0x11 /* 16 Bytes TX/RX */);
+			 0x11 /* 16 Bytes TX/RX */);
 	else
 		HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
 	HFC_outb(hc, R_FIFO_MD, 0);
@@ -1298,13 +1298,13 @@ init_chip(struct hfc_multi *hc)
 			pv |= PLX_SYNC_O_EN;
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",
-					__func__, pv);
+				       __func__, pv);
 		} else {
 			pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);
 			pv &= ~PLX_SYNC_O_EN;
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",
-					__func__, pv);
+				       __func__, pv);
 		}
 		writel(pv, plx_acc_32);
 		spin_unlock_irqrestore(&plx_lock, plx_flags);
@@ -1338,7 +1338,7 @@ init_chip(struct hfc_multi *hc)
 	if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: setting double clock\n", __func__);
+			       "%s: setting double clock\n", __func__);
 		HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
 	}
 
@@ -1360,48 +1360,48 @@ init_chip(struct hfc_multi *hc)
 	val += HFC_inb(hc, R_F0_CNTH) << 8;
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG
-		    "HFC_multi F0_CNT %ld after reset\n", val);
+		       "HFC_multi F0_CNT %ld after reset\n", val);
 	spin_unlock_irqrestore(&hc->lock, flags);
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout((HZ/100)?:1); /* Timeout minimum 10ms */
+	schedule_timeout((HZ / 100) ? : 1); /* Timeout minimum 10ms */
 	spin_lock_irqsave(&hc->lock, flags);
 	val2 = HFC_inb(hc, R_F0_CNTL);
 	val2 += HFC_inb(hc, R_F0_CNTH) << 8;
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG
-			"HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
-		    val2);
-	if (val2 >= val+8) { /* 1 ms */
+		       "HFC_multi F0_CNT %ld after 10 ms (1st try)\n",
+		       val2);
+	if (val2 >= val + 8) { /* 1 ms */
 		/* it counts, so we keep the pcm mode */
 		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip))
 			printk(KERN_INFO "controller is PCM bus MASTER\n");
 		else
-		if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
-			printk(KERN_INFO "controller is PCM bus SLAVE\n");
-		else {
-			test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
-			printk(KERN_INFO "controller is PCM bus SLAVE "
-				"(auto detected)\n");
-		}
+			if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip))
+				printk(KERN_INFO "controller is PCM bus SLAVE\n");
+			else {
+				test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
+				printk(KERN_INFO "controller is PCM bus SLAVE "
+				       "(auto detected)\n");
+			}
 	} else {
 		/* does not count */
 		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
-controller_fail:
+		controller_fail:
 			printk(KERN_ERR "HFC_multi ERROR, getting no 125us "
-			    "pulse. Seems that controller fails.\n");
+			       "pulse. Seems that controller fails.\n");
 			err = -EIO;
 			goto out;
 		}
 		if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) {
 			printk(KERN_INFO "controller is PCM bus SLAVE "
-				"(ignoring missing PCM clock)\n");
+			       "(ignoring missing PCM clock)\n");
 		} else {
 			/* only one pcm master */
 			if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
-				&& plxsd_master) {
+			    && plxsd_master) {
 				printk(KERN_ERR "HFC_multi ERROR, no clock "
-				    "on another Speech Design card found. "
-				    "Please be sure to connect PCM cable.\n");
+				       "on another Speech Design card found. "
+				       "Please be sure to connect PCM cable.\n");
 				err = -EIO;
 				goto out;
 			}
@@ -1416,24 +1416,24 @@ controller_fail:
 				spin_unlock_irqrestore(&plx_lock, plx_flags);
 				if (debug & DEBUG_HFCMULTI_INIT)
 					printk(KERN_DEBUG "%s: master: "
-					    "PLX_GPIO=%x\n", __func__, pv);
+					       "PLX_GPIO=%x\n", __func__, pv);
 			}
 			hc->hw.r_pcm_md0 |= V_PCM_MD;
 			HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
 			spin_unlock_irqrestore(&hc->lock, flags);
 			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout((HZ/100)?:1); /* Timeout min. 10ms */
+			schedule_timeout((HZ / 100) ?: 1); /* Timeout min. 10ms */
 			spin_lock_irqsave(&hc->lock, flags);
 			val2 = HFC_inb(hc, R_F0_CNTL);
 			val2 += HFC_inb(hc, R_F0_CNTH) << 8;
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG "HFC_multi F0_CNT %ld after "
-					"10 ms (2nd try)\n", val2);
-			if (val2 >= val+8) { /* 1 ms */
+				       "10 ms (2nd try)\n", val2);
+			if (val2 >= val + 8) { /* 1 ms */
 				test_and_set_bit(HFC_CHIP_PCM_MASTER,
-					&hc->chip);
+						 &hc->chip);
 				printk(KERN_INFO "controller is PCM bus MASTER "
-					"(auto detected)\n");
+				       "(auto detected)\n");
 			} else
 				goto controller_fail;
 		}
@@ -1451,21 +1451,21 @@ controller_fail:
 		spin_unlock_irqrestore(&plx_lock, plx_flags);
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",
-				__func__, pv);
+			       __func__, pv);
 	}
 
 	/* pcm id */
 	if (hc->pcm)
 		printk(KERN_INFO "controller has given PCM BUS ID %d\n",
-			hc->pcm);
+		       hc->pcm);
 	else {
 		if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)
-		 || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
+		    || test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
 			PCM_cnt++; /* SD has proprietary bridging */
 		}
 		hc->pcm = PCM_cnt;
 		printk(KERN_INFO "controller has PCM BUS ID %d "
-			"(auto selected)\n", hc->pcm);
+		       "(auto selected)\n", hc->pcm);
 	}
 
 	/* set up timer */
@@ -1480,7 +1480,7 @@ controller_fail:
 	if (test_bit(HFC_CHIP_DTMF, &hc->chip)) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: enabling DTMF detection "
-			    "for all B-channel\n", __func__);
+			       "for all B-channel\n", __func__);
 		hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP;
 		if (test_bit(HFC_CHIP_ULAW, &hc->chip))
 			hc->hw.r_dtmf |= V_ULAW_SEL;
@@ -1527,8 +1527,8 @@ controller_fail:
 	if (hc->masterclk >= 0) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: setting ST master clock "
-			    "to port %d (0..%d)\n",
-			    __func__, hc->masterclk, hc->ports-1);
+			       "to port %d (0..%d)\n",
+			       __func__, hc->masterclk, hc->ports - 1);
 		hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);
 		HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
 	}
@@ -1539,7 +1539,7 @@ controller_fail:
 	HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n",
-		    hc->hw.r_irqmsk_misc);
+		       hc->hw.r_irqmsk_misc);
 
 	/* RAM access test */
 	HFC_outb(hc, R_RAM_ADDR0, 0);
@@ -1547,7 +1547,7 @@ controller_fail:
 	HFC_outb(hc, R_RAM_ADDR2, 0);
 	for (i = 0; i < 256; i++) {
 		HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
-		HFC_outb_nodebug(hc, R_RAM_DATA, ((i*3)&0xff));
+		HFC_outb_nodebug(hc, R_RAM_DATA, ((i * 3) & 0xff));
 	}
 	for (i = 0; i < 256; i++) {
 		HFC_outb_nodebug(hc, R_RAM_ADDR0, i);
@@ -1555,8 +1555,8 @@ controller_fail:
 		rval = HFC_inb_nodebug(hc, R_INT_DATA);
 		if (rval != ((i * 3) & 0xff)) {
 			printk(KERN_DEBUG
-			    "addr:%x val:%x should:%x\n", i, rval,
-			    (i * 3) & 0xff);
+			       "addr:%x val:%x should:%x\n", i, rval,
+			       (i * 3) & 0xff);
 			err++;
 		}
 	}
@@ -1585,9 +1585,9 @@ hfcmulti_watchdog(struct hfc_multi *hc)
 	if (hc->wdcount > 10) {
 		hc->wdcount = 0;
 		hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ?
-		    V_GPIO_OUT3 : V_GPIO_OUT2;
+			V_GPIO_OUT3 : V_GPIO_OUT2;
 
-	/* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
+		/* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */
 		HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3);
 		HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte);
 	}
@@ -1623,10 +1623,10 @@ hfcmulti_leds(struct hfc_multi *hc)
 		 */
 		if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
 			if (hc->chan[hc->dslot].dch->dev.D.protocol
-				!= ISDN_P_NT_E1) {
+			    != ISDN_P_NT_E1) {
 				led[0] = 1;
 				led[1] = 1;
-			} else if (hc->ledcount>>11) {
+			} else if (hc->ledcount >> 11) {
 				led[0] = 1;
 				led[1] = 1;
 			} else {
@@ -1643,7 +1643,7 @@ hfcmulti_leds(struct hfc_multi *hc)
 			led[3] = 1;
 		}
 		leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF;
-			/* leds are inverted */
+		/* leds are inverted */
 		if (leds != (int)hc->ledstate) {
 			HFC_outb_nodebug(hc, R_GPIO_OUT1, leds);
 			hc->ledstate = leds;
@@ -1674,7 +1674,7 @@ hfcmulti_leds(struct hfc_multi *hc)
 						/* TE mode: led red */
 						led[i] = 2;
 					else
-						if (hc->ledcount>>11)
+						if (hc->ledcount >> 11)
 							/* led red */
 							led[i] = 2;
 						else
@@ -1700,9 +1700,9 @@ hfcmulti_leds(struct hfc_multi *hc)
 			}
 		} else {
 			leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) |
-			    ((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
-			    ((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
-			    ((led[0] & 1) << 6) | ((led[2] & 1) << 7);
+				((led[0] > 0) << 2) | ((led[2] > 0) << 3) |
+				((led[3] & 1) << 4) | ((led[1] & 1) << 5) |
+				((led[0] & 1) << 6) | ((led[2] & 1) << 7);
 			if (leds != (int)hc->ledstate) {
 				HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F);
 				HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4);
@@ -1746,13 +1746,13 @@ hfcmulti_leds(struct hfc_multi *hc)
 		}
 
 
-		leds = (led[0] > 0) | ((led[1] > 0)<<1) | ((led[0]&1)<<2)
-			| ((led[1]&1)<<3);
+		leds = (led[0] > 0) | ((led[1] > 0) << 1) | ((led[0]&1) << 2)
+			| ((led[1]&1) << 3);
 		if (leds != (int)hc->ledstate) {
 			HFC_outb_nodebug(hc, R_GPIO_EN1,
-			    ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
+					 ((led[0] > 0) << 2) | ((led[1] > 0) << 3));
 			HFC_outb_nodebug(hc, R_GPIO_OUT1,
-			    ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
+					 ((led[0] & 1) << 2) | ((led[1] & 1) << 3));
 			hc->ledstate = leds;
 		}
 		break;
@@ -1784,7 +1784,7 @@ hfcmulti_leds(struct hfc_multi *hc)
 		leddw = lled << 24 | lled << 16 | lled << 8 | lled;
 		if (leddw != hc->ledstate) {
 			/* HFC_outb(hc, R_BRG_PCM_CFG, 1);
-			HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
+			   HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */
 			/* was _io before */
 			HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK);
 			outw(0x4000, hc->pci_iobase + 4);
@@ -1826,16 +1826,16 @@ hfcmulti_dtmf(struct hfc_multi *hc)
 			continue;
 		if (debug & DEBUG_HFCMULTI_DTMF)
 			printk(KERN_DEBUG "%s: dtmf channel %d:",
-				__func__, ch);
+			       __func__, ch);
 		coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]);
 		dtmf = 1;
 		for (co = 0; co < 8; co++) {
 			/* read W(n-1) coefficient */
-			addr = hc->DTMFbase + ((co<<7) | (ch<<2));
+			addr = hc->DTMFbase + ((co << 7) | (ch << 2));
 			HFC_outb_nodebug(hc, R_RAM_ADDR0, addr);
-			HFC_outb_nodebug(hc, R_RAM_ADDR1, addr>>8);
-			HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr>>16)
-				| V_ADDR_INC);
+			HFC_outb_nodebug(hc, R_RAM_ADDR1, addr >> 8);
+			HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr >> 16)
+					 | V_ADDR_INC);
 			w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
 			w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8);
 			if (debug & DEBUG_HFCMULTI_DTMF)
@@ -1845,14 +1845,14 @@ hfcmulti_dtmf(struct hfc_multi *hc)
 			mantissa = w_float & 0x0fff;
 			if (w_float & 0x8000)
 				mantissa |= 0xfffff000;
-			exponent = (w_float>>12) & 0x7;
+			exponent = (w_float >> 12) & 0x7;
 			if (exponent) {
 				mantissa ^= 0x1000;
-				mantissa <<= (exponent-1);
+				mantissa <<= (exponent - 1);
 			}
 
 			/* store coefficient */
-			coeff[co<<1] = mantissa;
+			coeff[co << 1] = mantissa;
 
 			/* read W(n) coefficient */
 			w_float = HFC_inb_nodebug(hc, R_RAM_DATA);
@@ -1864,27 +1864,27 @@ hfcmulti_dtmf(struct hfc_multi *hc)
 			mantissa = w_float & 0x0fff;
 			if (w_float & 0x8000)
 				mantissa |= 0xfffff000;
-			exponent = (w_float>>12) & 0x7;
+			exponent = (w_float >> 12) & 0x7;
 			if (exponent) {
 				mantissa ^= 0x1000;
-				mantissa <<= (exponent-1);
+				mantissa <<= (exponent - 1);
 			}
 
 			/* store coefficient */
-			coeff[(co<<1)|1] = mantissa;
+			coeff[(co << 1) | 1] = mantissa;
 		}
 		if (debug & DEBUG_HFCMULTI_DTMF)
 			printk(" DTMF ready %08x %08x %08x %08x "
-			    "%08x %08x %08x %08x\n",
-			    coeff[0], coeff[1], coeff[2], coeff[3],
-			    coeff[4], coeff[5], coeff[6], coeff[7]);
+			       "%08x %08x %08x %08x\n",
+			       coeff[0], coeff[1], coeff[2], coeff[3],
+			       coeff[4], coeff[5], coeff[6], coeff[7]);
 		hc->chan[ch].coeff_count++;
 		if (hc->chan[ch].coeff_count == 8) {
 			hc->chan[ch].coeff_count = 0;
 			skb = mI_alloc_skb(512, GFP_ATOMIC);
 			if (!skb) {
 				printk(KERN_DEBUG "%s: No memory for skb\n",
-				    __func__);
+				       __func__);
 				continue;
 			}
 			hh = mISDN_HEAD_P(skb);
@@ -1966,8 +1966,8 @@ next_frame:
 		while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) {
 			if (debug & DEBUG_HFCMULTI_FIFO)
 				printk(KERN_DEBUG
-				    "%s(card %d): reread f2 because %d!=%d\n",
-				    __func__, hc->id + 1, temp, f2);
+				       "%s(card %d): reread f2 because %d!=%d\n",
+				       __func__, hc->id + 1, temp, f2);
 			f2 = temp; /* repeat until F2 is equal */
 		}
 		Fspace = f2 - f1 - 1;
@@ -1999,7 +1999,7 @@ next_frame:
 	while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) {
 		if (debug & DEBUG_HFCMULTI_FIFO)
 			printk(KERN_DEBUG "%s(card %d): reread z2 because "
-				"%d!=%d\n", __func__, hc->id + 1, temp, z2);
+			       "%d!=%d\n", __func__, hc->id + 1, temp, z2);
 		z2 = temp; /* repeat unti Z2 is equal */
 	}
 	hc->chan[ch].Zfill = z1 - z2;
@@ -2023,28 +2023,28 @@ next_frame:
 			    *txpending && slot_tx >= 0) {
 				if (debug & DEBUG_HFCMULTI_MODE)
 					printk(KERN_DEBUG
-					    "%s: reconnecting PCM due to no "
-					    "more FIFO data: channel %d "
-					    "slot_tx %d\n",
-					    __func__, ch, slot_tx);
+					       "%s: reconnecting PCM due to no "
+					       "more FIFO data: channel %d "
+					       "slot_tx %d\n",
+					       __func__, ch, slot_tx);
 				/* connect slot */
 				if (hc->ctype == HFC_TYPE_XHFC)
 					HFC_outb(hc, A_CON_HDLC, 0xc0
-					    | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-						/* Enable FIFO, no interrupt */
+						 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+				/* Enable FIFO, no interrupt */
 				else
 					HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
-					    V_HDLC_TRP | V_IFF);
-				HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);
+						 V_HDLC_TRP | V_IFF);
+				HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
 				HFC_wait_nodebug(hc);
 				if (hc->ctype == HFC_TYPE_XHFC)
 					HFC_outb(hc, A_CON_HDLC, 0xc0
-					    | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-						/* Enable FIFO, no interrupt */
+						 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+				/* Enable FIFO, no interrupt */
 				else
 					HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
-					    V_HDLC_TRP | V_IFF);
-				HFC_outb_nodebug(hc, R_FIFO, ch<<1);
+						 V_HDLC_TRP | V_IFF);
+				HFC_outb_nodebug(hc, R_FIFO, ch << 1);
 				HFC_wait_nodebug(hc);
 			}
 			*txpending = 0;
@@ -2054,10 +2054,10 @@ next_frame:
 
 	/* "fill fifo if empty" feature */
 	if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
-		&& !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
+	    && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
 		if (debug & DEBUG_HFCMULTI_FILL)
 			printk(KERN_DEBUG "%s: buffer empty, so we have "
-				"underrun\n", __func__);
+			       "underrun\n", __func__);
 		/* fill buffer, to prevent future underrun */
 		hc->write_fifo(hc, hc->silence_data, poll >> 1);
 		Zspace -= (poll >> 1);
@@ -2065,29 +2065,29 @@ next_frame:
 
 	/* if audio data and connected slot */
 	if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
-		&& slot_tx >= 0) {
+	    && slot_tx >= 0) {
 		if (debug & DEBUG_HFCMULTI_MODE)
 			printk(KERN_DEBUG "%s: disconnecting PCM due to "
-			    "FIFO data: channel %d slot_tx %d\n",
-			    __func__, ch, slot_tx);
+			       "FIFO data: channel %d slot_tx %d\n",
+			       __func__, ch, slot_tx);
 		/* disconnect slot */
 		if (hc->ctype == HFC_TYPE_XHFC)
 			HFC_outb(hc, A_CON_HDLC, 0x80
-			    | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-				/* Enable FIFO, no interrupt */
+				 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+		/* Enable FIFO, no interrupt */
 		else
 			HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
-			    V_HDLC_TRP | V_IFF);
-		HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);
+				 V_HDLC_TRP | V_IFF);
+		HFC_outb_nodebug(hc, R_FIFO, ch << 1 | 1);
 		HFC_wait_nodebug(hc);
 		if (hc->ctype == HFC_TYPE_XHFC)
 			HFC_outb(hc, A_CON_HDLC, 0x80
-			    | 0x07 << 2 | V_HDLC_TRP | V_IFF);
-				/* Enable FIFO, no interrupt */
+				 | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+		/* Enable FIFO, no interrupt */
 		else
 			HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
-			    V_HDLC_TRP | V_IFF);
-		HFC_outb_nodebug(hc, R_FIFO, ch<<1);
+				 V_HDLC_TRP | V_IFF);
+		HFC_outb_nodebug(hc, R_FIFO, ch << 1);
 		HFC_wait_nodebug(hc);
 	}
 	*txpending = 1;
@@ -2107,9 +2107,9 @@ next_frame:
 		ii = Zspace + i;
 	if (debug & DEBUG_HFCMULTI_FIFO)
 		printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "
-		    "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
-			__func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
-			temp ? "HDLC" : "TRANS");
+		       "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
+		       __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
+		       temp ? "HDLC" : "TRANS");
 
 	/* Have to prep the audio data */
 	hc->write_fifo(hc, d, ii - i);
@@ -2189,9 +2189,9 @@ next_frame:
 	    (hc->chan[ch].protocol == ISDN_P_B_RAW) &&
 	    (hc->chan[ch].slot_rx < 0) &&
 	    (hc->chan[ch].slot_tx < 0))
-		HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch<<1) | 1);
+		HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1) | 1);
 	else
-		HFC_outb_nodebug(hc, R_FIFO, (ch<<1)|1);
+		HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1);
 	HFC_wait_nodebug(hc);
 
 	/* ignore if rx is off BUT change fifo (above) to start pending TX */
@@ -2203,8 +2203,8 @@ next_frame:
 		while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) {
 			if (debug & DEBUG_HFCMULTI_FIFO)
 				printk(KERN_DEBUG
-				    "%s(card %d): reread f1 because %d!=%d\n",
-				    __func__, hc->id + 1, temp, f1);
+				       "%s(card %d): reread f1 because %d!=%d\n",
+				       __func__, hc->id + 1, temp, f1);
 			f1 = temp; /* repeat until F1 is equal */
 		}
 		f2 = HFC_inb_nodebug(hc, A_F2);
@@ -2213,7 +2213,7 @@ next_frame:
 	while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) {
 		if (debug & DEBUG_HFCMULTI_FIFO)
 			printk(KERN_DEBUG "%s(card %d): reread z2 because "
-				"%d!=%d\n", __func__, hc->id + 1, temp, z2);
+			       "%d!=%d\n", __func__, hc->id + 1, temp, z2);
 		z1 = temp; /* repeat until Z1 is equal */
 	}
 	z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin;
@@ -2231,7 +2231,7 @@ next_frame:
 		*sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC);
 		if (*sp == NULL) {
 			printk(KERN_DEBUG "%s: No mem for rx_skb\n",
-			    __func__);
+			       __func__);
 			return;
 		}
 	}
@@ -2242,16 +2242,16 @@ next_frame:
 	if (dch || test_bit(FLG_HDLC, &bch->Flags)) {
 		if (debug & DEBUG_HFCMULTI_FIFO)
 			printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d "
-			    "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
-			    "got=%d (again %d)\n", __func__, hc->id + 1, ch,
-			    Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
-			    f1, f2, Zsize + (*sp)->len, again);
+			       "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) "
+			       "got=%d (again %d)\n", __func__, hc->id + 1, ch,
+			       Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE",
+			       f1, f2, Zsize + (*sp)->len, again);
 		/* HDLC */
 		if ((Zsize + (*sp)->len) > (maxlen + 3)) {
 			if (debug & DEBUG_HFCMULTI_FIFO)
 				printk(KERN_DEBUG
-				    "%s(card %d): hdlc-frame too large.\n",
-				    __func__, hc->id + 1);
+				       "%s(card %d): hdlc-frame too large.\n",
+				       __func__, hc->id + 1);
 			skb_trim(*sp, 0);
 			HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F);
 			HFC_wait_nodebug(hc);
@@ -2268,8 +2268,8 @@ next_frame:
 			if ((*sp)->len < 4) {
 				if (debug & DEBUG_HFCMULTI_FIFO)
 					printk(KERN_DEBUG
-					    "%s(card %d): Frame below minimum "
-					    "size\n", __func__, hc->id + 1);
+					       "%s(card %d): Frame below minimum "
+					       "size\n", __func__, hc->id + 1);
 				skb_trim(*sp, 0);
 				goto next_frame;
 			}
@@ -2277,7 +2277,7 @@ next_frame:
 			if ((*sp)->data[(*sp)->len - 1]) {
 				if (debug & DEBUG_HFCMULTI_CRC)
 					printk(KERN_DEBUG
-					    "%s: CRC-error\n", __func__);
+					       "%s: CRC-error\n", __func__);
 				skb_trim(*sp, 0);
 				goto next_frame;
 			}
@@ -2287,11 +2287,11 @@ next_frame:
 				*sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
 				if (*sp) {
 					memcpy(skb_put(*sp, skb->len),
-					    skb->data, skb->len);
+					       skb->data, skb->len);
 					skb_trim(skb, 0);
 				} else {
 					printk(KERN_DEBUG "%s: No mem\n",
-					    __func__);
+					       __func__);
 					*sp = skb;
 					skb = NULL;
 				}
@@ -2300,7 +2300,7 @@ next_frame:
 			}
 			if (debug & DEBUG_HFCMULTI_FIFO) {
 				printk(KERN_DEBUG "%s(card %d):",
-					__func__, hc->id + 1);
+				       __func__, hc->id + 1);
 				temp = 0;
 				while (temp < (*sp)->len)
 					printk(" %02x", (*sp)->data[temp++]);
@@ -2325,7 +2325,7 @@ next_frame:
 			*sp = mI_alloc_skb(skb->len, GFP_ATOMIC);
 			if (*sp) {
 				memcpy(skb_put(*sp, skb->len),
-				    skb->data, skb->len);
+				       skb->data, skb->len);
 				skb_trim(skb, 0);
 			} else {
 				printk(KERN_DEBUG "%s: No mem\n", __func__);
@@ -2337,9 +2337,9 @@ next_frame:
 		}
 		if (debug & DEBUG_HFCMULTI_FIFO)
 			printk(KERN_DEBUG
-			    "%s(card %d): fifo(%d) reading %d bytes "
-			    "(z1=%04x, z2=%04x) TRANS\n",
-				__func__, hc->id + 1, ch, Zsize, z1, z2);
+			       "%s(card %d): fifo(%d) reading %d bytes "
+			       "(z1=%04x, z2=%04x) TRANS\n",
+			       __func__, hc->id + 1, ch, Zsize, z1, z2);
 		/* only bch is transparent */
 		recv_Bchannel(bch, hc->chan[ch].Zfill);
 		*sp = skb;
@@ -2362,7 +2362,7 @@ signal_state_up(struct dchannel *dch, int info, char *msg)
 	id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */
 
 	skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data,
-		GFP_ATOMIC);
+			       GFP_ATOMIC);
 	if (!skb)
 		return;
 	recv_Dchannel_skb(dch, skb);
@@ -2395,10 +2395,10 @@ handle_timer_irq(struct hfc_multi *hc)
 		if (hc->e1_resync & 4) {
 			if (debug & DEBUG_HFCMULTI_PLXSD)
 				printk(KERN_DEBUG
-				    "Enable QUARTZ for HFC-E1\n");
+				       "Enable QUARTZ for HFC-E1\n");
 			/* set jatt to quartz */
 			HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC
-				| V_JATT_OFF);
+				 | V_JATT_OFF);
 			/* switch to JATT, in case it is not already */
 			HFC_outb(hc, R_SYNC_OUT, 0);
 		}
@@ -2417,14 +2417,14 @@ handle_timer_irq(struct hfc_multi *hc)
 					dch = hc->chan[ch].dch;
 					if (!(--hc->chan[ch].nt_timer)) {
 						schedule_event(dch,
-						    FLG_PHCHANGE);
+							       FLG_PHCHANGE);
 						if (debug &
 						    DEBUG_HFCMULTI_STATE)
 							printk(KERN_DEBUG
-							    "%s: nt_timer at "
-							    "state %x\n",
-							    __func__,
-							    dch->state);
+							       "%s: nt_timer at "
+							       "state %x\n",
+							       __func__,
+							       dch->state);
 					}
 				}
 			}
@@ -2436,10 +2436,10 @@ handle_timer_irq(struct hfc_multi *hc)
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
 			if (!temp && hc->chan[hc->dslot].los)
 				signal_state_up(dch, L1_SIGNAL_LOS_ON,
-				    "LOS detected");
+						"LOS detected");
 			if (temp && !hc->chan[hc->dslot].los)
 				signal_state_up(dch, L1_SIGNAL_LOS_OFF,
-				    "LOS gone");
+						"LOS gone");
 			hc->chan[hc->dslot].los = temp;
 		}
 		if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
@@ -2447,10 +2447,10 @@ handle_timer_irq(struct hfc_multi *hc)
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
 			if (!temp && hc->chan[hc->dslot].ais)
 				signal_state_up(dch, L1_SIGNAL_AIS_ON,
-				    "AIS detected");
+						"AIS detected");
 			if (temp && !hc->chan[hc->dslot].ais)
 				signal_state_up(dch, L1_SIGNAL_AIS_OFF,
-				    "AIS gone");
+						"AIS gone");
 			hc->chan[hc->dslot].ais = temp;
 		}
 		if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
@@ -2458,12 +2458,12 @@ handle_timer_irq(struct hfc_multi *hc)
 			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
 			if (!temp && hc->chan[hc->dslot].slip_rx)
 				signal_state_up(dch, L1_SIGNAL_SLIP_RX,
-				    " bit SLIP detected RX");
+						" bit SLIP detected RX");
 			hc->chan[hc->dslot].slip_rx = temp;
 			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
 			if (!temp && hc->chan[hc->dslot].slip_tx)
 				signal_state_up(dch, L1_SIGNAL_SLIP_TX,
-				    " bit SLIP detected TX");
+						" bit SLIP detected TX");
 			hc->chan[hc->dslot].slip_tx = temp;
 		}
 		if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
@@ -2471,10 +2471,10 @@ handle_timer_irq(struct hfc_multi *hc)
 			temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
 			if (!temp && hc->chan[hc->dslot].rdi)
 				signal_state_up(dch, L1_SIGNAL_RDI_ON,
-				    "RDI detected");
+						"RDI detected");
 			if (temp && !hc->chan[hc->dslot].rdi)
 				signal_state_up(dch, L1_SIGNAL_RDI_OFF,
-				    "RDI gone");
+						"RDI gone");
 			hc->chan[hc->dslot].rdi = temp;
 		}
 		temp = HFC_inb_nodebug(hc, R_JATT_DIR);
@@ -2483,13 +2483,13 @@ handle_timer_irq(struct hfc_multi *hc)
 			if ((temp & 0x60) == 0x60) {
 				if (debug & DEBUG_HFCMULTI_SYNC)
 					printk(KERN_DEBUG
-					    "%s: (id=%d) E1 now "
-					    "in clock sync\n",
-					    __func__, hc->id);
+					       "%s: (id=%d) E1 now "
+					       "in clock sync\n",
+					       __func__, hc->id);
 				HFC_outb(hc, R_RX_OFF,
-				    hc->chan[hc->dslot].jitter | V_RX_INIT);
+					 hc->chan[hc->dslot].jitter | V_RX_INIT);
 				HFC_outb(hc, R_TX_OFF,
-				    hc->chan[hc->dslot].jitter | V_RX_INIT);
+					 hc->chan[hc->dslot].jitter | V_RX_INIT);
 				hc->chan[hc->dslot].sync = 1;
 				goto check_framesync;
 			}
@@ -2498,20 +2498,20 @@ handle_timer_irq(struct hfc_multi *hc)
 			if ((temp & 0x60) != 0x60) {
 				if (debug & DEBUG_HFCMULTI_SYNC)
 					printk(KERN_DEBUG
-					    "%s: (id=%d) E1 "
-					    "lost clock sync\n",
-					    __func__, hc->id);
+					       "%s: (id=%d) E1 "
+					       "lost clock sync\n",
+					       __func__, hc->id);
 				hc->chan[hc->dslot].sync = 0;
 				break;
 			}
-check_framesync:
+		check_framesync:
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA);
 			if (temp == 0x27) {
 				if (debug & DEBUG_HFCMULTI_SYNC)
 					printk(KERN_DEBUG
-					    "%s: (id=%d) E1 "
-					    "now in frame sync\n",
-					    __func__, hc->id);
+					       "%s: (id=%d) E1 "
+					       "now in frame sync\n",
+					       __func__, hc->id);
 				hc->chan[hc->dslot].sync = 2;
 			}
 			break;
@@ -2519,9 +2519,9 @@ check_framesync:
 			if ((temp & 0x60) != 0x60) {
 				if (debug & DEBUG_HFCMULTI_SYNC)
 					printk(KERN_DEBUG
-					    "%s: (id=%d) E1 lost "
-					    "clock & frame sync\n",
-					    __func__, hc->id);
+					       "%s: (id=%d) E1 lost "
+					       "clock & frame sync\n",
+					       __func__, hc->id);
 				hc->chan[hc->dslot].sync = 0;
 				break;
 			}
@@ -2529,9 +2529,9 @@ check_framesync:
 			if (temp != 0x27) {
 				if (debug & DEBUG_HFCMULTI_SYNC)
 					printk(KERN_DEBUG
-					    "%s: (id=%d) E1 "
-					    "lost frame sync\n",
-					    __func__, hc->id);
+					       "%s: (id=%d) E1 "
+					       "lost frame sync\n",
+					       __func__, hc->id);
 				hc->chan[hc->dslot].sync = 1;
 			}
 			break;
@@ -2559,30 +2559,30 @@ ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
 			dch = hc->chan[ch].dch;
 			if (r_irq_statech & 1) {
 				HFC_outb_nodebug(hc, R_ST_SEL,
-					hc->chan[ch].port);
+						 hc->chan[ch].port);
 				/* undocumented: delay after R_ST_SEL */
 				udelay(1);
 				/* undocumented: status changes during read */
 				st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE);
 				while (st_status != (temp =
-					HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
+						     HFC_inb_nodebug(hc, A_ST_RD_STATE))) {
 					if (debug & DEBUG_HFCMULTI_STATE)
 						printk(KERN_DEBUG "%s: reread "
-						    "STATE because %d!=%d\n",
-						    __func__, temp,
-						    st_status);
+						       "STATE because %d!=%d\n",
+						       __func__, temp,
+						       st_status);
 					st_status = temp; /* repeat */
 				}
 
 				/* Speech Design TE-sync indication */
 				if (test_bit(HFC_CHIP_PLXSD, &hc->chip) &&
-					dch->dev.D.protocol == ISDN_P_TE_S0) {
+				    dch->dev.D.protocol == ISDN_P_TE_S0) {
 					if (st_status & V_FR_SYNC_ST)
 						hc->syncronized |=
-						    (1 << hc->chan[ch].port);
+							(1 << hc->chan[ch].port);
 					else
 						hc->syncronized &=
-						   ~(1 << hc->chan[ch].port);
+							~(1 << hc->chan[ch].port);
 				}
 				dch->state = st_status & 0x0f;
 				if (dch->dev.D.protocol == ISDN_P_NT_S0)
@@ -2591,19 +2591,19 @@ ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech)
 					active = 7;
 				if (dch->state == active) {
 					HFC_outb_nodebug(hc, R_FIFO,
-						(ch << 1) | 1);
+							 (ch << 1) | 1);
 					HFC_wait_nodebug(hc);
 					HFC_outb_nodebug(hc,
-						R_INC_RES_FIFO, V_RES_F);
+							 R_INC_RES_FIFO, V_RES_F);
 					HFC_wait_nodebug(hc);
 					dch->tx_idx = 0;
 				}
 				schedule_event(dch, FLG_PHCHANGE);
 				if (debug & DEBUG_HFCMULTI_STATE)
 					printk(KERN_DEBUG
-					    "%s: S/T newstate %x port %d\n",
-					    __func__, dch->state,
-					    hc->chan[ch].port);
+					       "%s: S/T newstate %x port %d\n",
+					       __func__, dch->state,
+					       hc->chan[ch].port);
 			}
 			r_irq_statech >>= 1;
 		}
@@ -2665,7 +2665,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
 {
 #ifdef IRQCOUNT_DEBUG
 	static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0,
-	    iq5 = 0, iq6 = 0, iqcnt = 0;
+		iq5 = 0, iq6 = 0, iqcnt = 0;
 #endif
 	struct hfc_multi	*hc = dev_id;
 	struct dchannel		*dch;
@@ -2686,7 +2686,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
 #ifdef IRQ_DEBUG
 	if (irqsem)
 		printk(KERN_ERR "irq for card %d during irq from "
-		"card %d, this is no bug.\n", hc->id + 1, irqsem);
+		       "card %d, this is no bug.\n", hc->id + 1, irqsem);
 	irqsem = hc->id + 1;
 #endif
 #ifdef CONFIG_MISDN_HFCMULTI_8xx
@@ -2719,14 +2719,14 @@ hfcmulti_interrupt(int intno, void *dev_id)
 		iq6++;
 	if (iqcnt++ > 5000) {
 		printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n",
-		    iq1, iq2, iq3, iq4, iq5, iq6);
+		       iq1, iq2, iq3, iq4, iq5, iq6);
 		iqcnt = 0;
 	}
 #endif
 
 	if (!r_irq_statech &&
 	    !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA |
-	    V_MISC_IRQSTA | V_FR_IRQSTA))) {
+			V_MISC_IRQSTA | V_FR_IRQSTA))) {
 		/* irq is not for us */
 		goto irq_notforus;
 	}
@@ -2751,7 +2751,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
 				dch = hc->chan[hc->dslot].dch;
 				e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
 				if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
-				 && hc->e1_getclock) {
+				    && hc->e1_getclock) {
 					if (e1_syncsta & V_FR_SYNC_E1)
 						hc->syncronized = 1;
 					else
@@ -2760,12 +2760,12 @@ hfcmulti_interrupt(int intno, void *dev_id)
 				/* undocumented: status changes during read */
 				dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA);
 				while (dch->state != (temp =
-					HFC_inb_nodebug(hc, R_E1_RD_STA))) {
+						      HFC_inb_nodebug(hc, R_E1_RD_STA))) {
 					if (debug & DEBUG_HFCMULTI_STATE)
 						printk(KERN_DEBUG "%s: reread "
-						    "STATE because %d!=%d\n",
-						    __func__, temp,
-						    dch->state);
+						       "STATE because %d!=%d\n",
+						       __func__, temp,
+						       dch->state);
 					dch->state = temp; /* repeat */
 				}
 				dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
@@ -2773,8 +2773,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
 				schedule_event(dch, FLG_PHCHANGE);
 				if (debug & DEBUG_HFCMULTI_STATE)
 					printk(KERN_DEBUG
-					    "%s: E1 (id=%d) newstate %x\n",
-					    __func__, hc->id, dch->state);
+					       "%s: E1 (id=%d) newstate %x\n",
+					       __func__, hc->id, dch->state);
 				if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
 					plxsd_checksync(hc, 0);
 			}
@@ -2792,7 +2792,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
 			static int irq_proc_cnt;
 			if (!irq_proc_cnt++)
 				printk(KERN_DEBUG "%s: got V_IRQ_PROC -"
-				    " this should not happen\n", __func__);
+				       " this should not happen\n", __func__);
 		}
 
 	}
@@ -2841,7 +2841,7 @@ hfcmulti_dbusy_timer(struct hfc_multi *hc)
  */
 static int
 mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
-    int bank_tx, int slot_rx, int bank_rx)
+	      int bank_tx, int slot_rx, int bank_rx)
 {
 	int flow_tx = 0, flow_rx = 0, routing = 0;
 	int oslot_tx, oslot_rx;
@@ -2855,28 +2855,28 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 
 	if (debug & DEBUG_HFCMULTI_MODE)
 		printk(KERN_DEBUG
-		    "%s: card %d channel %d protocol %x slot old=%d new=%d "
-		    "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
-		    __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
-		    bank_tx, oslot_rx, slot_rx, bank_rx);
+		       "%s: card %d channel %d protocol %x slot old=%d new=%d "
+		       "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n",
+		       __func__, hc->id, ch, protocol, oslot_tx, slot_tx,
+		       bank_tx, oslot_rx, slot_rx, bank_rx);
 
 	if (oslot_tx >= 0 && slot_tx != oslot_tx) {
 		/* remove from slot */
 		if (debug & DEBUG_HFCMULTI_MODE)
 			printk(KERN_DEBUG "%s: remove from slot %d (TX)\n",
-			    __func__, oslot_tx);
-		if (hc->slot_owner[oslot_tx<<1] == ch) {
+			       __func__, oslot_tx);
+		if (hc->slot_owner[oslot_tx << 1] == ch) {
 			HFC_outb(hc, R_SLOT, oslot_tx << 1);
 			HFC_outb(hc, A_SL_CFG, 0);
 			if (hc->ctype != HFC_TYPE_XHFC)
 				HFC_outb(hc, A_CONF, 0);
-			hc->slot_owner[oslot_tx<<1] = -1;
+			hc->slot_owner[oslot_tx << 1] = -1;
 		} else {
 			if (debug & DEBUG_HFCMULTI_MODE)
 				printk(KERN_DEBUG
-				    "%s: we are not owner of this tx slot "
-				    "anymore, channel %d is.\n",
-				    __func__, hc->slot_owner[oslot_tx<<1]);
+				       "%s: we are not owner of this tx slot "
+				       "anymore, channel %d is.\n",
+				       __func__, hc->slot_owner[oslot_tx << 1]);
 		}
 	}
 
@@ -2884,8 +2884,8 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		/* remove from slot */
 		if (debug & DEBUG_HFCMULTI_MODE)
 			printk(KERN_DEBUG
-			    "%s: remove from slot %d (RX)\n",
-			    __func__, oslot_rx);
+			       "%s: remove from slot %d (RX)\n",
+			       __func__, oslot_rx);
 		if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) {
 			HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR);
 			HFC_outb(hc, A_SL_CFG, 0);
@@ -2893,10 +2893,10 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		} else {
 			if (debug & DEBUG_HFCMULTI_MODE)
 				printk(KERN_DEBUG
-				    "%s: we are not owner of this rx slot "
-				    "anymore, channel %d is.\n",
-				    __func__,
-				    hc->slot_owner[(oslot_rx << 1) | 1]);
+				       "%s: we are not owner of this rx slot "
+				       "anymore, channel %d is.\n",
+				       __func__,
+				       hc->slot_owner[(oslot_rx << 1) | 1]);
 		}
 	}
 
@@ -2917,14 +2917,14 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			routing = 0x40; /* loop */
 		if (debug & DEBUG_HFCMULTI_MODE)
 			printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
-			    " %d flow %02x routing %02x conf %d (TX)\n",
-			    __func__, ch, slot_tx, bank_tx,
-			    flow_tx, routing, conf);
+			       " %d flow %02x routing %02x conf %d (TX)\n",
+			       __func__, ch, slot_tx, bank_tx,
+			       flow_tx, routing, conf);
 		HFC_outb(hc, R_SLOT, slot_tx << 1);
-		HFC_outb(hc, A_SL_CFG, (ch<<1) | routing);
+		HFC_outb(hc, A_SL_CFG, (ch << 1) | routing);
 		if (hc->ctype != HFC_TYPE_XHFC)
 			HFC_outb(hc, A_CONF,
-				(conf < 0) ? 0 : (conf | V_CONF_SL));
+				 (conf < 0) ? 0 : (conf | V_CONF_SL));
 		hc->slot_owner[slot_tx << 1] = ch;
 		hc->chan[ch].slot_tx = slot_tx;
 		hc->chan[ch].bank_tx = bank_tx;
@@ -2946,12 +2946,12 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			routing = 0x40; /* loop */
 		if (debug & DEBUG_HFCMULTI_MODE)
 			printk(KERN_DEBUG "%s: put channel %d to slot %d bank"
-			    " %d flow %02x routing %02x conf %d (RX)\n",
-			    __func__, ch, slot_rx, bank_rx,
-			    flow_rx, routing, conf);
-		HFC_outb(hc, R_SLOT, (slot_rx<<1) | V_SL_DIR);
-		HFC_outb(hc, A_SL_CFG, (ch<<1) | V_CH_DIR | routing);
-		hc->slot_owner[(slot_rx<<1)|1] = ch;
+			       " %d flow %02x routing %02x conf %d (RX)\n",
+			       __func__, ch, slot_rx, bank_rx,
+			       flow_rx, routing, conf);
+		HFC_outb(hc, R_SLOT, (slot_rx << 1) | V_SL_DIR);
+		HFC_outb(hc, A_SL_CFG, (ch << 1) | V_CH_DIR | routing);
+		hc->slot_owner[(slot_rx << 1) | 1] = ch;
 		hc->chan[ch].slot_rx = slot_rx;
 		hc->chan[ch].bank_rx = bank_rx;
 	}
@@ -2967,7 +2967,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
 		HFC_wait(hc);
 		/* disable RX fifo */
-		HFC_outb(hc, R_FIFO, (ch<<1)|1);
+		HFC_outb(hc, R_FIFO, (ch << 1) | 1);
 		HFC_wait(hc);
 		HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00);
 		HFC_outb(hc, A_SUBCH_CFG, 0);
@@ -2976,17 +2976,17 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		HFC_wait(hc);
 		if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {
 			hc->hw.a_st_ctrl0[hc->chan[ch].port] &=
-			    ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
+				((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
 			HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
 			/* undocumented: delay after R_ST_SEL */
 			udelay(1);
 			HFC_outb(hc, A_ST_CTRL0,
-			    hc->hw.a_st_ctrl0[hc->chan[ch].port]);
+				 hc->hw.a_st_ctrl0[hc->chan[ch].port]);
 		}
 		if (hc->chan[ch].bch) {
 			test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
 			test_and_clear_bit(FLG_TRANSPARENT,
-			    &hc->chan[ch].bch->Flags);
+					   &hc->chan[ch].bch->Flags);
 		}
 		break;
 	case (ISDN_P_B_RAW): /* B-channel */
@@ -2996,20 +2996,20 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		    (hc->chan[ch].slot_tx < 0)) {
 
 			printk(KERN_DEBUG
-			    "Setting B-channel %d to echo cancelable "
-			    "state on PCM slot %d\n", ch,
-			    ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
+			       "Setting B-channel %d to echo cancelable "
+			       "state on PCM slot %d\n", ch,
+			       ((ch / 4) * 8) + ((ch % 4) * 4) + 1);
 			printk(KERN_DEBUG
-			    "Enabling pass through for channel\n");
+			       "Enabling pass through for channel\n");
 			vpm_out(hc, ch, ((ch / 4) * 8) +
-			    ((ch % 4) * 4) + 1, 0x01);
+				((ch % 4) * 4) + 1, 0x01);
 			/* rx path */
 			/* S/T -> PCM */
 			HFC_outb(hc, R_FIFO, (ch << 1));
 			HFC_wait(hc);
 			HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
 			HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
-			    ((ch % 4) * 4) + 1) << 1);
+					      ((ch % 4) * 4) + 1) << 1);
 			HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1));
 
 			/* PCM -> FIFO */
@@ -3021,7 +3021,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
 			HFC_wait(hc);
 			HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
-			    ((ch % 4) * 4) + 1) << 1) | 1);
+					       ((ch % 4) * 4) + 1) << 1) | 1);
 			HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1);
 
 			/* tx path */
@@ -3030,7 +3030,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			HFC_wait(hc);
 			HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF);
 			HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) +
-			    ((ch % 4) * 4)) << 1) | 1);
+					       ((ch % 4) * 4)) << 1) | 1);
 			HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1);
 
 			/* FIFO -> PCM */
@@ -3044,7 +3044,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			/* tx silence */
 			HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
 			HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
-			    ((ch % 4) * 4)) << 1);
+					      ((ch % 4) * 4)) << 1);
 			HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
 		} else {
 			/* enable TX fifo */
@@ -3052,11 +3052,11 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			HFC_wait(hc);
 			if (hc->ctype == HFC_TYPE_XHFC)
 				HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |
-					V_HDLC_TRP | V_IFF);
-					/* Enable FIFO, no interrupt */
+					 V_HDLC_TRP | V_IFF);
+			/* Enable FIFO, no interrupt */
 			else
 				HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
-					V_HDLC_TRP | V_IFF);
+					 V_HDLC_TRP | V_IFF);
 			HFC_outb(hc, A_SUBCH_CFG, 0);
 			HFC_outb(hc, A_IRQ_MSK, 0);
 			HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
@@ -3064,15 +3064,15 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			/* tx silence */
 			HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
 			/* enable RX fifo */
-			HFC_outb(hc, R_FIFO, (ch<<1)|1);
+			HFC_outb(hc, R_FIFO, (ch << 1) | 1);
 			HFC_wait(hc);
 			if (hc->ctype == HFC_TYPE_XHFC)
 				HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |
-					V_HDLC_TRP);
-					/* Enable FIFO, no interrupt*/
+					 V_HDLC_TRP);
+			/* Enable FIFO, no interrupt*/
 			else
 				HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |
-						V_HDLC_TRP);
+					 V_HDLC_TRP);
 			HFC_outb(hc, A_SUBCH_CFG, 0);
 			HFC_outb(hc, A_IRQ_MSK, 0);
 			HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
@@ -3080,16 +3080,16 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		}
 		if (hc->ctype != HFC_TYPE_E1) {
 			hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
-			    ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
+				((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
 			HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
 			/* undocumented: delay after R_ST_SEL */
 			udelay(1);
 			HFC_outb(hc, A_ST_CTRL0,
-			    hc->hw.a_st_ctrl0[hc->chan[ch].port]);
+				 hc->hw.a_st_ctrl0[hc->chan[ch].port]);
 		}
 		if (hc->chan[ch].bch)
 			test_and_set_bit(FLG_TRANSPARENT,
-			    &hc->chan[ch].bch->Flags);
+					 &hc->chan[ch].bch->Flags);
 		break;
 	case (ISDN_P_B_HDLC): /* B-channel */
 	case (ISDN_P_TE_S0): /* D-channel */
@@ -3097,7 +3097,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 	case (ISDN_P_TE_E1):
 	case (ISDN_P_NT_E1):
 		/* enable TX fifo */
-		HFC_outb(hc, R_FIFO, ch<<1);
+		HFC_outb(hc, R_FIFO, ch << 1);
 		HFC_wait(hc);
 		if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {
 			/* E1 or B-channel */
@@ -3112,7 +3112,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 		HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
 		HFC_wait(hc);
 		/* enable RX fifo */
-		HFC_outb(hc, R_FIFO, (ch<<1)|1);
+		HFC_outb(hc, R_FIFO, (ch << 1) | 1);
 		HFC_wait(hc);
 		HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);
 		if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)
@@ -3126,18 +3126,18 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 			test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
 			if (hc->ctype != HFC_TYPE_E1) {
 				hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
-				  ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN;
+					((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
 				HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
 				/* undocumented: delay after R_ST_SEL */
 				udelay(1);
 				HFC_outb(hc, A_ST_CTRL0,
-				  hc->hw.a_st_ctrl0[hc->chan[ch].port]);
+					 hc->hw.a_st_ctrl0[hc->chan[ch].port]);
 			}
 		}
 		break;
 	default:
 		printk(KERN_DEBUG "%s: protocol not known %x\n",
-		    __func__, protocol);
+		       __func__, protocol);
 		hc->chan[ch].protocol = ISDN_P_NONE;
 		return -ENOPROTOOPT;
 	}
@@ -3152,7 +3152,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
 
 static void
 hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
-    int slot_rx, int bank_rx)
+	     int slot_rx, int bank_rx)
 {
 	if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
 		/* disable PCM */
@@ -3162,7 +3162,7 @@ hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
 
 	/* enable pcm */
 	mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx,
-		slot_rx, bank_rx);
+		      slot_rx, bank_rx);
 }
 
 /*
@@ -3177,8 +3177,8 @@ hfcmulti_conf(struct hfc_multi *hc, int ch, int num)
 	else
 		hc->chan[ch].conf = -1;
 	mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx,
-	    hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
-	    hc->chan[ch].bank_rx);
+		      hc->chan[ch].bank_tx, hc->chan[ch].slot_rx,
+		      hc->chan[ch].bank_rx);
 }
 
 
@@ -3207,8 +3207,8 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
 		if (hc->ctype == HFC_TYPE_E1) {
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG
-				    "%s: HW_RESET_REQ no BRI\n",
-				    __func__);
+				       "%s: HW_RESET_REQ no BRI\n",
+				       __func__);
 		} else {
 			HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
 			/* undocumented: delay after R_ST_SEL */
@@ -3216,8 +3216,8 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
 			HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */
 			udelay(6); /* wait at least 5,21us */
 			HFC_outb(hc, A_ST_WR_STATE, 3);
-			HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT*3));
-				/* activate */
+			HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT * 3));
+			/* activate */
 		}
 		spin_unlock_irqrestore(&hc->lock, flags);
 		l1_event(dch->l1, HW_POWERUP_IND);
@@ -3228,17 +3228,17 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
 		if (hc->ctype == HFC_TYPE_E1) {
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG
-				    "%s: HW_DEACT_REQ no BRI\n",
-				    __func__);
+				       "%s: HW_DEACT_REQ no BRI\n",
+				       __func__);
 		} else {
 			HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
 			/* undocumented: delay after R_ST_SEL */
 			udelay(1);
-			HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT*2);
-				/* deactivate */
+			HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
+			/* deactivate */
 			if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
 				hc->syncronized &=
-				   ~(1 << hc->chan[dch->slot].port);
+					~(1 << hc->chan[dch->slot].port);
 				plxsd_checksync(hc, 0);
 			}
 		}
@@ -3262,8 +3262,8 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
 		if (hc->ctype == HFC_TYPE_E1) {
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG
-				    "%s: HW_POWERUP_REQ no BRI\n",
-				    __func__);
+				       "%s: HW_POWERUP_REQ no BRI\n",
+				       __func__);
 		} else {
 			HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port);
 			/* undocumented: delay after R_ST_SEL */
@@ -3277,17 +3277,17 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
 	case PH_ACTIVATE_IND:
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	case PH_DEACTIVATE_IND:
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: unknown command %x\n",
-			    __func__, cmd);
+			       __func__, cmd);
 		return -1;
 	}
 	return 0;
@@ -3332,27 +3332,27 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 			ret = 0;
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG
-				    "%s: PH_ACTIVATE port %d (0..%d)\n",
-				    __func__, hc->chan[dch->slot].port,
-				    hc->ports-1);
+				       "%s: PH_ACTIVATE port %d (0..%d)\n",
+				       __func__, hc->chan[dch->slot].port,
+				       hc->ports - 1);
 			/* start activation */
 			if (hc->ctype == HFC_TYPE_E1) {
 				ph_state_change(dch);
 				if (debug & DEBUG_HFCMULTI_STATE)
 					printk(KERN_DEBUG
-					    "%s: E1 report state %x \n",
-					    __func__, dch->state);
+					       "%s: E1 report state %x \n",
+					       __func__, dch->state);
 			} else {
 				HFC_outb(hc, R_ST_SEL,
-				    hc->chan[dch->slot].port);
+					 hc->chan[dch->slot].port);
 				/* undocumented: delay after R_ST_SEL */
 				udelay(1);
 				HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1);
-				    /* G1 */
+				/* G1 */
 				udelay(6); /* wait at least 5,21us */
 				HFC_outb(hc, A_ST_WR_STATE, 1);
 				HFC_outb(hc, A_ST_WR_STATE, 1 |
-				    (V_ST_ACT*3)); /* activate */
+					 (V_ST_ACT * 3)); /* activate */
 				dch->state = 1;
 			}
 			spin_unlock_irqrestore(&hc->lock, flags);
@@ -3365,22 +3365,22 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 			spin_lock_irqsave(&hc->lock, flags);
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG
-				    "%s: PH_DEACTIVATE port %d (0..%d)\n",
-				    __func__, hc->chan[dch->slot].port,
-				    hc->ports-1);
+				       "%s: PH_DEACTIVATE port %d (0..%d)\n",
+				       __func__, hc->chan[dch->slot].port,
+				       hc->ports - 1);
 			/* start deactivation */
 			if (hc->ctype == HFC_TYPE_E1) {
 				if (debug & DEBUG_HFCMULTI_MSG)
 					printk(KERN_DEBUG
-					    "%s: PH_DEACTIVATE no BRI\n",
-					    __func__);
+					       "%s: PH_DEACTIVATE no BRI\n",
+					       __func__);
 			} else {
 				HFC_outb(hc, R_ST_SEL,
-				    hc->chan[dch->slot].port);
+					 hc->chan[dch->slot].port);
 				/* undocumented: delay after R_ST_SEL */
 				udelay(1);
 				HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2);
-				    /* deactivate */
+				/* deactivate */
 				dch->state = 1;
 			}
 			skb_queue_purge(&dch->squeue);
@@ -3460,28 +3460,28 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 	case PH_ACTIVATE_REQ:
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n",
-				__func__, bch->slot);
+			       __func__, bch->slot);
 		spin_lock_irqsave(&hc->lock, flags);
 		/* activate B-channel if not already activated */
 		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
 			hc->chan[bch->slot].txpending = 0;
 			ret = mode_hfcmulti(hc, bch->slot,
-				ch->protocol,
-				hc->chan[bch->slot].slot_tx,
-				hc->chan[bch->slot].bank_tx,
-				hc->chan[bch->slot].slot_rx,
-				hc->chan[bch->slot].bank_rx);
+					    ch->protocol,
+					    hc->chan[bch->slot].slot_tx,
+					    hc->chan[bch->slot].bank_tx,
+					    hc->chan[bch->slot].slot_rx,
+					    hc->chan[bch->slot].bank_rx);
 			if (!ret) {
 				if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf
-					&& test_bit(HFC_CHIP_DTMF, &hc->chip)) {
+				    && test_bit(HFC_CHIP_DTMF, &hc->chip)) {
 					/* start decoder */
 					hc->dtmf = 1;
 					if (debug & DEBUG_HFCMULTI_DTMF)
 						printk(KERN_DEBUG
-						    "%s: start dtmf decoder\n",
-							__func__);
+						       "%s: start dtmf decoder\n",
+						       __func__);
 					HFC_outb(hc, R_DTMF, hc->hw.r_dtmf |
-					    V_RST_DTMF);
+						 V_RST_DTMF);
 				}
 			}
 		} else
@@ -3489,7 +3489,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(&hc->lock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
-				GFP_KERNEL);
+				    GFP_KERNEL);
 		break;
 	case PH_CONTROL_REQ:
 		spin_lock_irqsave(&hc->lock, flags);
@@ -3497,20 +3497,20 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 		case HFC_SPL_LOOP_ON: /* set sample loop */
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG
-				    "%s: HFC_SPL_LOOP_ON (len = %d)\n",
-				    __func__, skb->len);
+				       "%s: HFC_SPL_LOOP_ON (len = %d)\n",
+				       __func__, skb->len);
 			ret = 0;
 			break;
 		case HFC_SPL_LOOP_OFF: /* set silence */
 			if (debug & DEBUG_HFCMULTI_MSG)
 				printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n",
-				    __func__);
+				       __func__);
 			ret = 0;
 			break;
 		default:
 			printk(KERN_ERR
-			     "%s: unknown PH_CONTROL_REQ info %x\n",
-			     __func__, hh->id);
+			       "%s: unknown PH_CONTROL_REQ info %x\n",
+			       __func__, hh->id);
 			ret = -EINVAL;
 		}
 		spin_unlock_irqrestore(&hc->lock, flags);
@@ -3518,7 +3518,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 	case PH_DEACTIVATE_REQ:
 		deactivate_bchannel(bch); /* locked there */
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL,
-			GFP_KERNEL);
+			    GFP_KERNEL);
 		ret = 0;
 		break;
 	}
@@ -3559,18 +3559,18 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 		}
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
-			    __func__, bch->nr, hc->chan[bch->slot].rx_off);
+			       __func__, bch->nr, hc->chan[bch->slot].rx_off);
 		break;
 	case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
 		test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
-				"off=%d)\n", __func__, bch->nr, !!cq->p1);
+			       "off=%d)\n", __func__, bch->nr, !!cq->p1);
 		break;
 	case MISDN_CTRL_HW_FEATURES: /* fill features structure */
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: HW_FEATURE request\n",
-			    __func__);
+			       __func__);
 		/* create confirm */
 		features->hfc_id = hc->id;
 		if (test_bit(HFC_CHIP_DTMF, &hc->chip))
@@ -3593,40 +3593,40 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 		bank_rx = cq->p2 >> 8;
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG
-			    "%s: HFC_PCM_CONN slot %d bank %d (TX) "
-			    "slot %d bank %d (RX)\n",
-			    __func__, slot_tx, bank_tx,
-			    slot_rx, bank_rx);
+			       "%s: HFC_PCM_CONN slot %d bank %d (TX) "
+			       "slot %d bank %d (RX)\n",
+			       __func__, slot_tx, bank_tx,
+			       slot_rx, bank_rx);
 		if (slot_tx < hc->slots && bank_tx <= 2 &&
 		    slot_rx < hc->slots && bank_rx <= 2)
 			hfcmulti_pcm(hc, bch->slot,
-			    slot_tx, bank_tx, slot_rx, bank_rx);
+				     slot_tx, bank_tx, slot_rx, bank_rx);
 		else {
 			printk(KERN_WARNING
-			    "%s: HFC_PCM_CONN slot %d bank %d (TX) "
-			    "slot %d bank %d (RX) out of range\n",
-			    __func__, slot_tx, bank_tx,
-			    slot_rx, bank_rx);
+			       "%s: HFC_PCM_CONN slot %d bank %d (TX) "
+			       "slot %d bank %d (RX) out of range\n",
+			       __func__, slot_tx, bank_tx,
+			       slot_rx, bank_rx);
 			ret = -EINVAL;
 		}
 		break;
 	case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: HFC_PCM_DISC\n",
-			    __func__);
+			       __func__);
 		hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0);
 		break;
 	case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */
 		num = cq->p1 & 0xff;
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n",
-			    __func__, num);
+			       __func__, num);
 		if (num <= 7)
 			hfcmulti_conf(hc, bch->slot, num);
 		else {
 			printk(KERN_WARNING
-			    "%s: HW_CONF_JOIN conf %d out of range\n",
-			    __func__, num);
+			       "%s: HW_CONF_JOIN conf %d out of range\n",
+			       __func__, num);
 			ret = -EINVAL;
 		}
 		break;
@@ -3647,7 +3647,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_HFC_ECHOCAN_OFF:
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n",
-				__func__);
+			       __func__);
 		if (test_bit(HFC_CHIP_B410P, &hc->chip))
 			vpm_echocan_off(hc, bch->slot);
 		else
@@ -3655,7 +3655,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n",
-		    __func__, cq->op);
+		       __func__, cq->op);
 		ret = -EINVAL;
 		break;
 	}
@@ -3672,7 +3672,7 @@ hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 	if (bch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		    __func__, cmd, arg);
+		       __func__, cmd, arg);
 	switch (cmd) {
 	case CLOSE_CHANNEL:
 		test_and_clear_bit(FLG_OPEN, &bch->Flags);
@@ -3690,7 +3690,7 @@ hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-			__func__, cmd);
+		       __func__, cmd);
 	}
 	return err;
 }
@@ -3717,13 +3717,13 @@ ph_state_change(struct dchannel *dch)
 		if (dch->dev.D.protocol == ISDN_P_TE_E1) {
 			if (debug & DEBUG_HFCMULTI_STATE)
 				printk(KERN_DEBUG
-				    "%s: E1 TE (id=%d) newstate %x\n",
-				    __func__, hc->id, dch->state);
+				       "%s: E1 TE (id=%d) newstate %x\n",
+				       __func__, hc->id, dch->state);
 		} else {
 			if (debug & DEBUG_HFCMULTI_STATE)
 				printk(KERN_DEBUG
-				    "%s: E1 NT (id=%d) newstate %x\n",
-				    __func__, hc->id, dch->state);
+				       "%s: E1 NT (id=%d) newstate %x\n",
+				       __func__, hc->id, dch->state);
 		}
 		switch (dch->state) {
 		case (1):
@@ -3731,16 +3731,16 @@ ph_state_change(struct dchannel *dch)
 				for (i = 1; i <= 31; i++) {
 					/* reset fifos on e1 activation */
 					HFC_outb_nodebug(hc, R_FIFO,
-						(i << 1) | 1);
+							 (i << 1) | 1);
 					HFC_wait_nodebug(hc);
 					HFC_outb_nodebug(hc, R_INC_RES_FIFO,
-						V_RES_F);
+							 V_RES_F);
 					HFC_wait_nodebug(hc);
 				}
 			}
 			test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 			_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 			break;
 
 		default:
@@ -3748,15 +3748,15 @@ ph_state_change(struct dchannel *dch)
 				return;
 			test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 			_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
-			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 		}
 		hc->e1_state = dch->state;
 	} else {
 		if (dch->dev.D.protocol == ISDN_P_TE_S0) {
 			if (debug & DEBUG_HFCMULTI_STATE)
 				printk(KERN_DEBUG
-				    "%s: S/T TE newstate %x\n",
-				    __func__, dch->state);
+				       "%s: S/T TE newstate %x\n",
+				       __func__, dch->state);
 			switch (dch->state) {
 			case (0):
 				l1_event(dch->l1, HW_RESET_IND);
@@ -3778,38 +3778,38 @@ ph_state_change(struct dchannel *dch)
 		} else {
 			if (debug & DEBUG_HFCMULTI_STATE)
 				printk(KERN_DEBUG "%s: S/T NT newstate %x\n",
-				    __func__, dch->state);
+				       __func__, dch->state);
 			switch (dch->state) {
 			case (2):
 				if (hc->chan[ch].nt_timer == 0) {
 					hc->chan[ch].nt_timer = -1;
 					HFC_outb(hc, R_ST_SEL,
-					    hc->chan[ch].port);
+						 hc->chan[ch].port);
 					/* undocumented: delay after R_ST_SEL */
 					udelay(1);
 					HFC_outb(hc, A_ST_WR_STATE, 4 |
-					    V_ST_LD_STA); /* G4 */
+						 V_ST_LD_STA); /* G4 */
 					udelay(6); /* wait at least 5,21us */
 					HFC_outb(hc, A_ST_WR_STATE, 4);
 					dch->state = 4;
 				} else {
 					/* one extra count for the next event */
 					hc->chan[ch].nt_timer =
-					    nt_t1_count[poll_timer] + 1;
+						nt_t1_count[poll_timer] + 1;
 					HFC_outb(hc, R_ST_SEL,
-					    hc->chan[ch].port);
+						 hc->chan[ch].port);
 					/* undocumented: delay after R_ST_SEL */
 					udelay(1);
 					/* allow G2 -> G3 transition */
 					HFC_outb(hc, A_ST_WR_STATE, 2 |
-					    V_SET_G2_G3);
+						 V_SET_G2_G3);
 				}
 				break;
 			case (1):
 				hc->chan[ch].nt_timer = -1;
 				test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 				_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+					    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 				break;
 			case (4):
 				hc->chan[ch].nt_timer = -1;
@@ -3818,7 +3818,7 @@ ph_state_change(struct dchannel *dch)
 				hc->chan[ch].nt_timer = -1;
 				test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 				_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+					    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 				break;
 			}
 		}
@@ -3845,7 +3845,7 @@ hfcmulti_initmode(struct dchannel *dch)
 		hc->chan[hc->dslot].conf = -1;
 		if (hc->dslot) {
 			mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
-				-1, 0, -1, 0);
+				      -1, 0, -1, 0);
 			dch->timer.function = (void *) hfcmulti_dbusy_timer;
 			dch->timer.data = (long) dch;
 			init_timer(&dch->timer);
@@ -3887,13 +3887,13 @@ hfcmulti_initmode(struct dchannel *dch)
 		if (dch->dev.D.protocol == ISDN_P_NT_E1) {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG "%s: E1 port is NT-mode\n",
-				    __func__);
+				       __func__);
 			r_e1_wr_sta = 0; /* G0 */
 			hc->e1_getclock = 0;
 		} else {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG "%s: E1 port is TE-mode\n",
-				    __func__);
+				       __func__);
 			r_e1_wr_sta = 0; /* F0 */
 			hc->e1_getclock = 1;
 		}
@@ -3909,26 +3909,26 @@ hfcmulti_initmode(struct dchannel *dch)
 			/* SLAVE (clock master) */
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: E1 port is clock master "
-				    "(clock from PCM)\n", __func__);
+				       "%s: E1 port is clock master "
+				       "(clock from PCM)\n", __func__);
 			HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC);
 		} else {
 			if (hc->e1_getclock) {
 				/* MASTER (clock slave) */
 				if (debug & DEBUG_HFCMULTI_INIT)
 					printk(KERN_DEBUG
-					    "%s: E1 port is clock slave "
-					    "(clock to PCM)\n", __func__);
+					       "%s: E1 port is clock slave "
+					       "(clock to PCM)\n", __func__);
 				HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS);
 			} else {
 				/* MASTER (clock master) */
 				if (debug & DEBUG_HFCMULTI_INIT)
 					printk(KERN_DEBUG "%s: E1 port is "
-					    "clock master "
-					    "(clock from QUARTZ)\n",
-					    __func__);
+					       "clock master "
+					       "(clock from QUARTZ)\n",
+					       __func__);
 				HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC |
-				    V_PCM_SYNC | V_JATT_OFF);
+					 V_PCM_SYNC | V_JATT_OFF);
 				HFC_outb(hc, R_SYNC_OUT, 0);
 			}
 		}
@@ -3970,8 +3970,8 @@ hfcmulti_initmode(struct dchannel *dch)
 		if (dch->dev.D.protocol == ISDN_P_NT_S0) {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: ST port %d is NT-mode\n",
-				    __func__, pt);
+				       "%s: ST port %d is NT-mode\n",
+				       __func__, pt);
 			/* clock delay */
 			HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt);
 			a_st_wr_state = 1; /* G1 */
@@ -3979,8 +3979,8 @@ hfcmulti_initmode(struct dchannel *dch)
 		} else {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: ST port %d is TE-mode\n",
-				    __func__, pt);
+				       "%s: ST port %d is TE-mode\n",
+				       __func__, pt);
 			/* clock delay */
 			HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te);
 			a_st_wr_state = 2; /* F2 */
@@ -3991,7 +3991,7 @@ hfcmulti_initmode(struct dchannel *dch)
 		if (hc->ctype == HFC_TYPE_XHFC) {
 			hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;
 			HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,
-				0x7c << 1 /* V_ST_PULSE */);
+				 0x7c << 1 /* V_ST_PULSE */);
 		}
 		/* line setup */
 		HFC_outb(hc, A_ST_CTRL0,  hc->hw.a_st_ctrl0[pt]);
@@ -4013,7 +4013,7 @@ hfcmulti_initmode(struct dchannel *dch)
 		/* unset sync on port */
 		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
 			hc->syncronized &=
-			   ~(1 << hc->chan[dch->slot].port);
+				~(1 << hc->chan[dch->slot].port);
 			plxsd_checksync(hc, 0);
 		}
 	}
@@ -4024,21 +4024,21 @@ hfcmulti_initmode(struct dchannel *dch)
 
 static int
 open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
-    struct channel_req *rq)
+	      struct channel_req *rq)
 {
 	int	err = 0;
 	u_long	flags;
 
 	if (debug & DEBUG_HW_OPEN)
 		printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
-		    dch->dev.id, __builtin_return_address(0));
+		       dch->dev.id, __builtin_return_address(0));
 	if (rq->protocol == ISDN_P_NONE)
 		return -EINVAL;
 	if ((dch->dev.D.protocol != ISDN_P_NONE) &&
 	    (dch->dev.D.protocol != rq->protocol)) {
 		if (debug & DEBUG_HFCMULTI_MODE)
 			printk(KERN_DEBUG "%s: change protocol %x to %x\n",
-			    __func__, dch->dev.D.protocol, rq->protocol);
+			       __func__, dch->dev.D.protocol, rq->protocol);
 	}
 	if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&
 	    (rq->protocol != ISDN_P_TE_S0))
@@ -4060,7 +4060,7 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
 	    ((rq->protocol == ISDN_P_NT_E1) && (dch->state == 1)) ||
 	    ((rq->protocol == ISDN_P_TE_E1) && (dch->state == 1))) {
 		_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
-		    0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 	}
 	rq->ch = &dch->dev.D;
 	if (!try_module_get(THIS_MODULE))
@@ -4070,7 +4070,7 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
 
 static int
 open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
-    struct channel_req *rq)
+	      struct channel_req *rq)
 {
 	struct bchannel	*bch;
 	int		ch;
@@ -4086,7 +4086,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
 	bch = hc->chan[ch].bch;
 	if (!bch) {
 		printk(KERN_ERR "%s:internal error ch %d has no bch\n",
-		    __func__, ch);
+		       __func__, ch);
 		return -EINVAL;
 	}
 	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
@@ -4119,8 +4119,8 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
 		wd_mode = !!(cq->p1 >> 4);
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"
-			    ", counter 0x%x\n", __func__,
-			    wd_mode ? "AUTO" : "MANUAL", wd_cnt);
+			       ", counter 0x%x\n", __func__,
+			       wd_mode ? "AUTO" : "MANUAL", wd_cnt);
 		/* set the watchdog timer */
 		HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
 		hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
@@ -4139,12 +4139,12 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
 		if (debug & DEBUG_HFCMULTI_MSG)
 			printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
-			    __func__);
+			       __func__);
 		HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n",
-		    __func__, cq->op);
+		       __func__, cq->op);
 		ret = -EINVAL;
 		break;
 	}
@@ -4163,7 +4163,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 	if (dch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		    __func__, cmd, arg);
+		       __func__, cmd, arg);
 	switch (cmd) {
 	case OPEN_CHANNEL:
 		rq = arg;
@@ -4193,8 +4193,8 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	case CLOSE_CHANNEL:
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
-			    __func__, dch->dev.id,
-			    __builtin_return_address(0));
+			       __func__, dch->dev.id,
+			       __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -4205,7 +4205,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: unknown command %x\n",
-			    __func__, cmd);
+			       __func__, cmd);
 		err = -EINVAL;
 	}
 	return err;
@@ -4246,9 +4246,9 @@ init_card(struct hfc_multi *hc)
 	spin_unlock_irqrestore(&hc->lock, flags);
 
 	if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,
-	    "HFC-multi", hc)) {
+			"HFC-multi", hc)) {
 		printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",
-		    hc->irq);
+		       hc->irq);
 		hc->irq = 0;
 		return -EIO;
 	}
@@ -4257,13 +4257,13 @@ init_card(struct hfc_multi *hc)
 		spin_lock_irqsave(&plx_lock, plx_flags);
 		plx_acc = hc->plx_membase + PLX_INTCSR;
 		writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE),
-			plx_acc); /* enable PCI & LINT1 irq */
+		       plx_acc); /* enable PCI & LINT1 irq */
 		spin_unlock_irqrestore(&plx_lock, plx_flags);
 	}
 
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: IRQ %d count %d\n",
-		    __func__, hc->irq, hc->irqcnt);
+		       __func__, hc->irq, hc->irqcnt);
 	err = init_chip(hc);
 	if (err)
 		goto error;
@@ -4277,14 +4277,14 @@ init_card(struct hfc_multi *hc)
 	spin_unlock_irqrestore(&hc->lock, flags);
 	/* printk(KERN_DEBUG "no master irq set!!!\n"); */
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout((100*HZ)/1000); /* Timeout 100ms */
+	schedule_timeout((100 * HZ) / 1000); /* Timeout 100ms */
 	/* turn IRQ off until chip is completely initialized */
 	spin_lock_irqsave(&hc->lock, flags);
 	disable_hwirq(hc);
 	spin_unlock_irqrestore(&hc->lock, flags);
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: IRQ %d count %d\n",
-		    __func__, hc->irq, hc->irqcnt);
+		       __func__, hc->irq, hc->irqcnt);
 	if (hc->irqcnt) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: done\n", __func__);
@@ -4297,7 +4297,7 @@ init_card(struct hfc_multi *hc)
 	}
 
 	printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n",
-		hc->irq);
+	       hc->irq);
 
 	err = -EIO;
 
@@ -4327,13 +4327,13 @@ error:
 
 static int
 setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
-		const struct pci_device_id *ent)
+	  const struct pci_device_id *ent)
 {
 	struct hm_map	*m = (struct hm_map *)ent->driver_data;
 
 	printk(KERN_INFO
-	    "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
-	    m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
+	       "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
+	       m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
 
 	hc->pci_dev = pdev;
 	if (m->clock2)
@@ -4380,7 +4380,7 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
 
 		if (!hc->plx_origmembase) {
 			printk(KERN_WARNING
-			  "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
+			       "HFC-multi: No IO-Memory for PCI PLX bridge found\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
@@ -4388,20 +4388,20 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
 		hc->plx_membase = ioremap(hc->plx_origmembase, 0x80);
 		if (!hc->plx_membase) {
 			printk(KERN_WARNING
-			    "HFC-multi: failed to remap plx address space. "
-			    "(internal error)\n");
+			       "HFC-multi: failed to remap plx address space. "
+			       "(internal error)\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
 		printk(KERN_INFO
-		    "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
-		    (u_long)hc->plx_membase, hc->plx_origmembase);
+		       "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n",
+		       (u_long)hc->plx_membase, hc->plx_origmembase);
 
 		hc->pci_origmembase =  hc->pci_dev->resource[2].start;
-		    /* MEMBASE 1 is PLX PCI Bridge */
+		/* MEMBASE 1 is PLX PCI Bridge */
 		if (!hc->pci_origmembase) {
 			printk(KERN_WARNING
-			    "HFC-multi: No IO-Memory for PCI card found\n");
+			       "HFC-multi: No IO-Memory for PCI card found\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
@@ -4409,16 +4409,16 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
 		hc->pci_membase = ioremap(hc->pci_origmembase, 0x400);
 		if (!hc->pci_membase) {
 			printk(KERN_WARNING "HFC-multi: failed to remap io "
-			    "address space. (internal error)\n");
+			       "address space. (internal error)\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
 
 		printk(KERN_INFO
-		    "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
-		    "leds-type %d\n",
-		    hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
-		    hc->pci_dev->irq, HZ, hc->leds);
+		       "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d "
+		       "leds-type %d\n",
+		       hc->id, (u_long)hc->pci_membase, hc->pci_origmembase,
+		       hc->pci_dev->irq, HZ, hc->leds);
 		pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
 		break;
 	case HFC_IO_MODE_PCIMEM:
@@ -4431,7 +4431,7 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
 		hc->pci_origmembase = hc->pci_dev->resource[1].start;
 		if (!hc->pci_origmembase) {
 			printk(KERN_WARNING
-			    "HFC-multi: No IO-Memory for PCI card found\n");
+			       "HFC-multi: No IO-Memory for PCI card found\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
@@ -4439,14 +4439,14 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
 		hc->pci_membase = ioremap(hc->pci_origmembase, 256);
 		if (!hc->pci_membase) {
 			printk(KERN_WARNING
-			    "HFC-multi: failed to remap io address space. "
-			    "(internal error)\n");
+			       "HFC-multi: failed to remap io address space. "
+			       "(internal error)\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
 		printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "
-		    "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
-		    hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
+		       "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
+		       hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
 		pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
 		break;
 	case HFC_IO_MODE_REGIO:
@@ -4459,23 +4459,23 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
 		hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;
 		if (!hc->pci_iobase) {
 			printk(KERN_WARNING
-				"HFC-multi: No IO for PCI card found\n");
+			       "HFC-multi: No IO for PCI card found\n");
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
 
 		if (!request_region(hc->pci_iobase, 8, "hfcmulti")) {
 			printk(KERN_WARNING "HFC-multi: failed to request "
-			    "address space at 0x%08lx (internal error)\n",
-			    hc->pci_iobase);
+			       "address space at 0x%08lx (internal error)\n",
+			       hc->pci_iobase);
 			pci_disable_device(hc->pci_dev);
 			return -EIO;
 		}
 
 		printk(KERN_INFO
-		    "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
-		    m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
-		    hc->pci_dev->irq, HZ, hc->leds);
+		       "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n",
+		       m->vendor_name, m->card_name, (u_int) hc->pci_iobase,
+		       hc->pci_dev->irq, HZ, hc->leds);
 		pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO);
 		break;
 	default:
@@ -4508,17 +4508,17 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
 
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: entered for port %d\n",
-			__func__, pt + 1);
+		       __func__, pt + 1);
 
 	if (pt >= hc->ports) {
 		printk(KERN_WARNING "%s: ERROR port out of range (%d).\n",
-		     __func__, pt + 1);
+		       __func__, pt + 1);
 		return;
 	}
 
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: releasing port=%d\n",
-		    __func__, pt + 1);
+		       __func__, pt + 1);
 
 	if (dch->dev.D.protocol == ISDN_P_TE_S0)
 		l1_event(dch->l1, CLOSE_CHANNEL);
@@ -4548,8 +4548,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
 			if (hc->chan[i].bch) {
 				if (debug & DEBUG_HFCMULTI_INIT)
 					printk(KERN_DEBUG
-					    "%s: free port %d channel %d\n",
-					    __func__, hc->chan[i].port+1, i);
+					       "%s: free port %d channel %d\n",
+					       __func__, hc->chan[i].port + 1, i);
 				pb = hc->chan[i].bch;
 				hc->chan[i].bch = NULL;
 				spin_unlock_irqrestore(&hc->lock, flags);
@@ -4563,16 +4563,16 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
 		/* remove sync */
 		if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
 			hc->syncronized &=
-			   ~(1 << hc->chan[ci].port);
+				~(1 << hc->chan[ci].port);
 			plxsd_checksync(hc, 1);
 		}
 		/* free channels */
 		if (hc->chan[ci - 2].bch) {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: free port %d channel %d\n",
-				    __func__, hc->chan[ci - 2].port+1,
-				    ci - 2);
+				       "%s: free port %d channel %d\n",
+				       __func__, hc->chan[ci - 2].port + 1,
+				       ci - 2);
 			pb = hc->chan[ci - 2].bch;
 			hc->chan[ci - 2].bch = NULL;
 			spin_unlock_irqrestore(&hc->lock, flags);
@@ -4584,9 +4584,9 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
 		if (hc->chan[ci - 1].bch) {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: free port %d channel %d\n",
-				    __func__, hc->chan[ci - 1].port+1,
-				    ci - 1);
+				       "%s: free port %d channel %d\n",
+				       __func__, hc->chan[ci - 1].port + 1,
+				       ci - 1);
 			pb = hc->chan[ci - 1].bch;
 			hc->chan[ci - 1].bch = NULL;
 			spin_unlock_irqrestore(&hc->lock, flags);
@@ -4616,7 +4616,7 @@ release_card(struct hfc_multi *hc)
 
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: release card (%d) entered\n",
-		    __func__, hc->id);
+		       __func__, hc->id);
 
 	/* unregister clock source */
 	if (hc->iclock)
@@ -4635,7 +4635,7 @@ release_card(struct hfc_multi *hc)
 	/* disable D-channels & B-channels */
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: disable all channels (d and b)\n",
-		    __func__);
+		       __func__);
 	for (ch = 0; ch <= 31; ch++) {
 		if (hc->chan[ch].dch)
 			release_port(hc, hc->chan[ch].dch);
@@ -4645,7 +4645,7 @@ release_card(struct hfc_multi *hc)
 	if (hc->irq) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: free irq %d\n",
-			    __func__, hc->irq);
+			       __func__, hc->irq);
 		free_irq(hc->irq, hc);
 		hc->irq = 0;
 
@@ -4654,7 +4654,7 @@ release_card(struct hfc_multi *hc)
 
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: remove instance from list\n",
-		     __func__);
+		       __func__);
 	list_del(&hc->list);
 
 	if (debug & DEBUG_HFCMULTI_INIT)
@@ -4664,7 +4664,7 @@ release_card(struct hfc_multi *hc)
 	kfree(hc);
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: card successfully removed\n",
-		    __func__);
+		       __func__);
 }
 
 static int
@@ -4683,7 +4683,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 	dch->hw = hc;
 	dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
 	dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	dch->dev.D.send = handle_dmsg;
 	dch->dev.D.ctrl = hfcm_dctrl;
 	dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
@@ -4697,14 +4697,14 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 		bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
 		if (!bch) {
 			printk(KERN_ERR "%s: no memory for bchannel\n",
-			    __func__);
+			       __func__);
 			ret = -ENOMEM;
 			goto free_chan;
 		}
 		hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
 		if (!hc->chan[ch].coeff) {
 			printk(KERN_ERR "%s: no memory for coeffs\n",
-			    __func__);
+			       __func__);
 			ret = -ENOMEM;
 			kfree(bch);
 			goto free_chan;
@@ -4726,93 +4726,93 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 	if (port[Port_cnt] & 0x001) {
 		if (!m->opticalsupport)  {
 			printk(KERN_INFO
-			    "This board has no optical "
-			    "support\n");
+			       "This board has no optical "
+			       "support\n");
 		} else {
 			if (debug & DEBUG_HFCMULTI_INIT)
 				printk(KERN_DEBUG
-				    "%s: PORT set optical "
-				    "interfacs: card(%d) "
-				    "port(%d)\n",
-				    __func__,
-				    HFC_cnt + 1, 1);
+				       "%s: PORT set optical "
+				       "interfacs: card(%d) "
+				       "port(%d)\n",
+				       __func__,
+				       HFC_cnt + 1, 1);
 			test_and_set_bit(HFC_CFG_OPTICAL,
-			    &hc->chan[hc->dslot].cfg);
+					 &hc->chan[hc->dslot].cfg);
 		}
 	}
 	/* set LOS report */
 	if (port[Port_cnt] & 0x004) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT set "
-			    "LOS report: card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, 1);
+			       "LOS report: card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_LOS,
-		    &hc->chan[hc->dslot].cfg);
+				 &hc->chan[hc->dslot].cfg);
 	}
 	/* set AIS report */
 	if (port[Port_cnt] & 0x008) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT set "
-			    "AIS report: card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, 1);
+			       "AIS report: card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_AIS,
-		    &hc->chan[hc->dslot].cfg);
+				 &hc->chan[hc->dslot].cfg);
 	}
 	/* set SLIP report */
 	if (port[Port_cnt] & 0x010) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: PORT set SLIP report: "
-			    "card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, 1);
+			       "%s: PORT set SLIP report: "
+			       "card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_SLIP,
-		    &hc->chan[hc->dslot].cfg);
+				 &hc->chan[hc->dslot].cfg);
 	}
 	/* set RDI report */
 	if (port[Port_cnt] & 0x020) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: PORT set RDI report: "
-			    "card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, 1);
+			       "%s: PORT set RDI report: "
+			       "card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_RDI,
-		    &hc->chan[hc->dslot].cfg);
+				 &hc->chan[hc->dslot].cfg);
 	}
 	/* set CRC-4 Mode */
 	if (!(port[Port_cnt] & 0x100)) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT turn on CRC4 report:"
-				" card(%d) port(%d)\n",
-				__func__, HFC_cnt + 1, 1);
+			       " card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_CRC4,
-		    &hc->chan[hc->dslot].cfg);
+				 &hc->chan[hc->dslot].cfg);
 	} else {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT turn off CRC4"
-				" report: card(%d) port(%d)\n",
-				__func__, HFC_cnt + 1, 1);
+			       " report: card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 	}
 	/* set forced clock */
 	if (port[Port_cnt] & 0x0200) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT force getting clock from "
-				"E1: card(%d) port(%d)\n",
-				__func__, HFC_cnt + 1, 1);
+			       "E1: card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip);
 	} else
-	if (port[Port_cnt] & 0x0400) {
-		if (debug & DEBUG_HFCMULTI_INIT)
-			printk(KERN_DEBUG "%s: PORT force putting clock to "
-				"E1: card(%d) port(%d)\n",
-				__func__, HFC_cnt + 1, 1);
-		test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
-	}
+		if (port[Port_cnt] & 0x0400) {
+			if (debug & DEBUG_HFCMULTI_INIT)
+				printk(KERN_DEBUG "%s: PORT force putting clock to "
+				       "E1: card(%d) port(%d)\n",
+				       __func__, HFC_cnt + 1, 1);
+			test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip);
+		}
 	/* set JATT PLL */
 	if (port[Port_cnt] & 0x0800) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT disable JATT PLL on "
-				"E1: card(%d) port(%d)\n",
-				__func__, HFC_cnt + 1, 1);
+			       "E1: card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip);
 	}
 	/* set elastic jitter buffer */
@@ -4820,10 +4820,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 		hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: PORT set elastic "
-			    "buffer to %d: card(%d) port(%d)\n",
-			    __func__, hc->chan[hc->dslot].jitter,
-			    HFC_cnt + 1, 1);
+			       "%s: PORT set elastic "
+			       "buffer to %d: card(%d) port(%d)\n",
+			       __func__, hc->chan[hc->dslot].jitter,
+			       HFC_cnt + 1, 1);
 	} else
 		hc->chan[hc->dslot].jitter = 2; /* default */
 	snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
@@ -4853,7 +4853,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
 	dch->hw = hc;
 	dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
 	dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	dch->dev.D.send = handle_dmsg;
 	dch->dev.D.ctrl = hfcm_dctrl;
 	dch->dev.nrbchan = 2;
@@ -4866,14 +4866,14 @@ init_multi_port(struct hfc_multi *hc, int pt)
 		bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
 		if (!bch) {
 			printk(KERN_ERR "%s: no memory for bchannel\n",
-			    __func__);
+			       __func__);
 			ret = -ENOMEM;
 			goto free_chan;
 		}
 		hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL);
 		if (!hc->chan[i + ch].coeff) {
 			printk(KERN_ERR "%s: no memory for coeffs\n",
-			    __func__);
+			       __func__);
 			ret = -ENOMEM;
 			kfree(bch);
 			goto free_chan;
@@ -4895,22 +4895,22 @@ init_multi_port(struct hfc_multi *hc, int pt)
 	if (port[Port_cnt] & 0x001) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: PROTOCOL set master clock: "
-			    "card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, pt + 1);
+			       "%s: PROTOCOL set master clock: "
+			       "card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, pt + 1);
 		if (dch->dev.D.protocol != ISDN_P_TE_S0) {
 			printk(KERN_ERR "Error: Master clock "
-			    "for port(%d) of card(%d) is only"
-			    " possible with TE-mode\n",
-			    pt + 1, HFC_cnt + 1);
+			       "for port(%d) of card(%d) is only"
+			       " possible with TE-mode\n",
+			       pt + 1, HFC_cnt + 1);
 			ret = -EINVAL;
 			goto free_chan;
 		}
 		if (hc->masterclk >= 0) {
 			printk(KERN_ERR "Error: Master clock "
-			    "for port(%d) of card(%d) already "
-			    "defined for port(%d)\n",
-			    pt + 1, HFC_cnt + 1, hc->masterclk+1);
+			       "for port(%d) of card(%d) already "
+			       "defined for port(%d)\n",
+			       pt + 1, HFC_cnt + 1, hc->masterclk + 1);
 			ret = -EINVAL;
 			goto free_chan;
 		}
@@ -4920,29 +4920,29 @@ init_multi_port(struct hfc_multi *hc, int pt)
 	if (port[Port_cnt] & 0x002) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: PROTOCOL set non capacitive "
-			    "transmitter: card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, pt + 1);
+			       "%s: PROTOCOL set non capacitive "
+			       "transmitter: card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, pt + 1);
 		test_and_set_bit(HFC_CFG_NONCAP_TX,
-		    &hc->chan[i + 2].cfg);
+				 &hc->chan[i + 2].cfg);
 	}
 	/* disable E-channel */
 	if (port[Port_cnt] & 0x004) {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: PROTOCOL disable E-channel: "
-			    "card(%d) port(%d)\n",
-			    __func__, HFC_cnt + 1, pt + 1);
+			       "%s: PROTOCOL disable E-channel: "
+			       "card(%d) port(%d)\n",
+			       __func__, HFC_cnt + 1, pt + 1);
 		test_and_set_bit(HFC_CFG_DIS_ECHANNEL,
-		    &hc->chan[i + 2].cfg);
+				 &hc->chan[i + 2].cfg);
 	}
 	if (hc->ctype == HFC_TYPE_XHFC) {
 		snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",
-			HFC_cnt + 1, pt + 1);
+			 HFC_cnt + 1, pt + 1);
 		ret = mISDN_register_device(&dch->dev, NULL, name);
 	} else {
 		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
-			hc->ctype, HFC_cnt + 1, pt + 1);
+			 hc->ctype, HFC_cnt + 1, pt + 1);
 		ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
 	}
 	if (ret)
@@ -4956,7 +4956,7 @@ free_chan:
 
 static int
 hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
-    const struct pci_device_id *ent)
+	      const struct pci_device_id *ent)
 {
 	int		ret_err = 0;
 	int		pt;
@@ -4967,22 +4967,22 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 
 	if (HFC_cnt >= MAX_CARDS) {
 		printk(KERN_ERR "too many cards (max=%d).\n",
-			MAX_CARDS);
+		       MAX_CARDS);
 		return -EINVAL;
 	}
 	if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) {
 		printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but "
-		    "type[%d] %d was supplied as module parameter\n",
-		    m->vendor_name, m->card_name, m->type, HFC_cnt,
-		    type[HFC_cnt] & 0xff);
+		       "type[%d] %d was supplied as module parameter\n",
+		       m->vendor_name, m->card_name, m->type, HFC_cnt,
+		       type[HFC_cnt] & 0xff);
 		printk(KERN_WARNING "HFC-MULTI: Load module without parameters "
-			"first, to see cards and their types.");
+		       "first, to see cards and their types.");
 		return -EINVAL;
 	}
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n",
-		    __func__, m->vendor_name, m->card_name, m->type,
-		    type[HFC_cnt]);
+		       __func__, m->vendor_name, m->card_name, m->type,
+		       type[HFC_cnt]);
 
 	/* allocate card+fifo structure */
 	hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL);
@@ -5000,13 +5000,13 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 	if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
 		hc->dslot = 0;
 		printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
-			"31 B-channels\n");
+		       "31 B-channels\n");
 	}
 	if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
 	    && hc->ctype == HFC_TYPE_E1) {
 		hc->dslot = dslot[HFC_cnt];
 		printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
-			"time slot %d\n", dslot[HFC_cnt]);
+		       "time slot %d\n", dslot[HFC_cnt]);
 	} else
 		hc->dslot = 16;
 
@@ -5019,7 +5019,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 		hc->silence = 0x2a; /* alaw silence */
 	if ((poll >> 1) > sizeof(hc->silence_data)) {
 		printk(KERN_ERR "HFCMULTI error: silence_data too small, "
-			"please fix\n");
+		       "please fix\n");
 		return -EINVAL;
 	}
 	for (i = 0; i < (poll >> 1); i++)
@@ -5086,7 +5086,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 	for (pt = 0; pt < hc->ports; pt++) {
 		if (Port_cnt >= MAX_PORTS) {
 			printk(KERN_ERR "too many ports (max=%d).\n",
-				MAX_PORTS);
+			       MAX_PORTS);
 			ret_err = -EINVAL;
 			goto free_card;
 		}
@@ -5096,9 +5096,9 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 			ret_err = init_multi_port(hc, pt);
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
-			    "%s: Registering D-channel, card(%d) port(%d)"
-			    "result %d\n",
-			    __func__, HFC_cnt + 1, pt, ret_err);
+			       "%s: Registering D-channel, card(%d) port(%d)"
+			       "result %d\n",
+			       __func__, HFC_cnt + 1, pt, ret_err);
 
 		if (ret_err) {
 			while (pt) { /* release already registered ports */
@@ -5129,7 +5129,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 			pmj = ~pmj & 0xf;
 
 		printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n",
-			m->vendor_name, m->card_name, dips, pmj);
+		       m->vendor_name, m->card_name, dips, pmj);
 		break;
 	case DIP_8S:
 		/*
@@ -5151,16 +5151,16 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 		/* disable PCI auxbridge function */
 		HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
 		printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
-		    m->vendor_name, m->card_name, dips);
+		       m->vendor_name, m->card_name, dips);
 		break;
 	case DIP_E1:
 		/*
 		 * get DIP Setting for beroNet E1 cards
 		 * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0)
 		 */
-		dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0)>>4;
+		dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0) >> 4;
 		printk(KERN_INFO "%s: %s DIPs(0x%x)\n",
-		    m->vendor_name, m->card_name, dips);
+		       m->vendor_name, m->card_name, dips);
 		break;
 	}
 
@@ -5203,9 +5203,9 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
 
 	if (debug)
 		printk(KERN_INFO "removing hfc_multi card vendor:%x "
-		    "device:%x subvendor:%x subdevice:%x\n",
-		    pdev->vendor, pdev->device,
-		    pdev->subsystem_vendor, pdev->subsystem_device);
+		       "device:%x subvendor:%x subdevice:%x\n",
+		       pdev->vendor, pdev->device,
+		       pdev->subsystem_vendor, pdev->subsystem_device);
 
 	if (card) {
 		spin_lock_irqsave(&HFClock, flags);
@@ -5214,7 +5214,7 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
 	}  else {
 		if (debug)
 			printk(KERN_DEBUG "%s: drvdata already removed\n",
-			    __func__);
+			       __func__);
 	}
 }
 
@@ -5225,50 +5225,50 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
 #define VENDOR_PRIM	"PrimuX"
 
 static const struct hm_map hfcm_map[] = {
-/*0*/	{VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
-/*1*/	{VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
-/*2*/	{VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
-/*3*/	{VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
-/*4*/	{VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
-/*5*/	{VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
-/*6*/	{VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
-/*7*/	{VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
-/*8*/	{VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
-/*9*/	{VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
-/*10*/	{VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
-/*11*/	{VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
-
-/*12*/	{VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
-/*13*/	{VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
-		HFC_IO_MODE_REGIO, 0},
-/*14*/	{VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
-/*15*/	{VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
-
-/*16*/	{VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
-/*17*/	{VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
-/*18*/	{VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
-
-/*19*/	{VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
-/*20*/	{VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
-/*21*/	{VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
-/*22*/	{VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
-
-/*23*/	{VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
-/*24*/	{VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
-/*25*/	{VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
-
-/*26*/	{VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
-		HFC_IO_MODE_PLXSD, 0},
-/*27*/	{VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
-		HFC_IO_MODE_PLXSD, 0},
-/*28*/	{VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
-/*29*/	{VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
-/*30*/	{VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
-/*31*/	{VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
-		HFC_IO_MODE_EMBSD, XHFC_IRQ},
-/*32*/	{VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
-/*33*/	{VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
-/*34*/	{VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+	/*0*/	{VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
+	/*1*/	{VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+	/*2*/	{VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+	/*3*/	{VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+	/*4*/	{VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
+	/*5*/	{VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
+	/*6*/	{VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+	/*7*/	{VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
+	/*8*/	{VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
+	/*9*/	{VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
+	/*10*/	{VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
+	/*11*/	{VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
+
+	/*12*/	{VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
+	/*13*/	{VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
+		 HFC_IO_MODE_REGIO, 0},
+	/*14*/	{VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
+	/*15*/	{VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
+
+	/*16*/	{VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
+	/*17*/	{VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
+	/*18*/	{VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
+
+	/*19*/	{VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+	/*20*/	{VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
+	/*21*/	{VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+	/*22*/	{VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+
+	/*23*/	{VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
+	/*24*/	{VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
+	/*25*/	{VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
+
+	/*26*/	{VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
+		 HFC_IO_MODE_PLXSD, 0},
+	/*27*/	{VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
+		 HFC_IO_MODE_PLXSD, 0},
+	/*28*/	{VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
+	/*29*/	{VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
+	/*30*/	{VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
+	/*31*/	{VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
+		 HFC_IO_MODE_EMBSD, XHFC_IRQ},
+	/*32*/	{VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
+	/*33*/	{VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+	/*34*/	{VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
 };
 
 #undef H
@@ -5277,83 +5277,83 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
 
 	/* Cards with HFC-4S Chip */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
+	  PCI_SUBDEVICE_ID_CCD_BN1SM, 0, 0, H(0)}, /* BN1S mini PCI */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
+	  PCI_SUBDEVICE_ID_CCD_BN2S, 0, 0, H(1)}, /* BN2S */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
+	  PCI_SUBDEVICE_ID_CCD_BN2SM, 0, 0, H(2)}, /* BN2S mini PCI */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
+	  PCI_SUBDEVICE_ID_CCD_BN4S, 0, 0, H(3)}, /* BN4S */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
+	  PCI_SUBDEVICE_ID_CCD_BN4SM, 0, 0, H(4)}, /* BN4S mini PCI */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
+	  PCI_DEVICE_ID_CCD_HFC4S, 0, 0, H(5)}, /* Old Eval */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
+	  PCI_SUBDEVICE_ID_CCD_IOB4ST, 0, 0, H(6)}, /* IOB4ST */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
+	  PCI_SUBDEVICE_ID_CCD_HFC4S, 0, 0, H(7)}, /* 4S */
 	{ PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S,
-		PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
+	  PCI_VENDOR_ID_DIGIUM, PCI_DEVICE_ID_DIGIUM_HFC4S, 0, 0, H(8)},
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
+	  PCI_SUBDEVICE_ID_CCD_SWYX4S, 0, 0, H(9)}, /* 4S Swyx */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
+	  PCI_SUBDEVICE_ID_CCD_JH4S20, 0, 0, H(10)},
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
+	  PCI_SUBDEVICE_ID_CCD_PMX2S, 0, 0, H(11)}, /* Primux */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
+	  PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
+	  PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		0xb761, 0, 0, H(33)}, /* BN2S PCIe */
+	  0xb761, 0, 0, H(33)}, /* BN2S PCIe */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
-		0xb762, 0, 0, H(34)}, /* BN4S PCIe */
+	  0xb762, 0, 0, H(34)}, /* BN4S PCIe */
 
 	/* Cards with HFC-8S Chip */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
+	  PCI_SUBDEVICE_ID_CCD_BN8S, 0, 0, H(12)}, /* BN8S */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
+	  PCI_SUBDEVICE_ID_CCD_BN8SP, 0, 0, H(13)}, /* BN8S+ */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
+	  PCI_DEVICE_ID_CCD_HFC8S, 0, 0, H(14)}, /* old Eval */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-	PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
+	  PCI_SUBDEVICE_ID_CCD_IOB8STR, 0, 0, H(15)}, /* IOB8ST Recording */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST  */
+	  PCI_SUBDEVICE_ID_CCD_IOB8ST, 0, 0, H(16)}, /* IOB8ST  */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST  */
+	  PCI_SUBDEVICE_ID_CCD_IOB8ST_1, 0, 0, H(17)}, /* IOB8ST  */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
+	  PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
+	  PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S  */
+	  PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S  */
 
 
 	/* Cards with HFC-E1 Chip */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
+	  PCI_SUBDEVICE_ID_CCD_BNE1, 0, 0, H(19)}, /* BNE1 */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
+	  PCI_SUBDEVICE_ID_CCD_BNE1M, 0, 0, H(20)}, /* BNE1 mini PCI */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
+	  PCI_SUBDEVICE_ID_CCD_BNE1DP, 0, 0, H(21)}, /* BNE1 + (Dual) */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
+	  PCI_SUBDEVICE_ID_CCD_BNE1D, 0, 0, H(22)}, /* BNE1 (Dual) */
 
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
+	  PCI_DEVICE_ID_CCD_HFCE1, 0, 0, H(23)}, /* Old Eval */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
+	  PCI_SUBDEVICE_ID_CCD_IOB1E1, 0, 0, H(24)}, /* IOB1E1 */
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
+	  PCI_SUBDEVICE_ID_CCD_HFCE1, 0, 0, H(25)}, /* E1 */
 
 	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
+	  PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
 	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
+	  PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
 
 	{ PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
-		PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
+	  PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
 
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC4S), 0 },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_HFC8S), 0 },
@@ -5371,16 +5371,16 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	int		ret;
 
 	if (m == NULL && ent->vendor == PCI_VENDOR_ID_CCD && (
-	    ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
-	    ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
-	    ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
+		    ent->device == PCI_DEVICE_ID_CCD_HFC4S ||
+		    ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
+		    ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
 		printk(KERN_ERR
-		    "Unknown HFC multiport controller (vendor:%04x device:%04x "
-		    "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
-		    pdev->device, pdev->subsystem_vendor,
-		    pdev->subsystem_device);
+		       "Unknown HFC multiport controller (vendor:%04x device:%04x "
+		       "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
+		       pdev->device, pdev->subsystem_vendor,
+		       pdev->subsystem_device);
 		printk(KERN_ERR
-		    "Please contact the driver maintainer for support.\n");
+		       "Please contact the driver maintainer for support.\n");
 		return -ENODEV;
 	}
 	ret = hfcmulti_init(m, pdev, ent);
@@ -5453,7 +5453,7 @@ HFCmulti_init(void)
 		break;
 	default:
 		printk(KERN_ERR
-		    "%s: Wrong poll value (%d).\n", __func__, poll);
+		       "%s: Wrong poll value (%d).\n", __func__, poll);
 		err = -EINVAL;
 		return err;
 
@@ -5485,7 +5485,7 @@ HFCmulti_init(void)
 		err = hfcmulti_init(&m, NULL, NULL);
 		if (err) {
 			printk(KERN_ERR "error registering embedded driver: "
-				"%x\n", err);
+			       "%x\n", err);
 			return err;
 		}
 		HFC_cnt++;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 3261de1..d055ae7 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -109,11 +109,11 @@ struct hfcPCI_hw {
 	unsigned char		bswapped;
 	unsigned char		protocol;
 	int			nt_timer;
-	unsigned char __iomem 	*pci_io; /* start of PCI IO memory */
+	unsigned char __iomem	*pci_io; /* start of PCI IO memory */
 	dma_addr_t		dmahandle;
 	void			*fifos; /* FIFO memory */
 	int			last_bfifo_cnt[2];
-	    /* marker saving last b-fifo frame count */
+	/* marker saving last b-fifo frame count */
 	struct timer_list	timer;
 };
 
@@ -216,7 +216,7 @@ reset_hfcpci(struct hfc_pci *hc)
 	disable_hwirq(hc);
 	/* enable memory ports + busmaster */
 	pci_write_config_word(hc->pdev, PCI_COMMAND,
-	    PCI_ENA_MEMIO + PCI_ENA_MASTER);
+			      PCI_ENA_MEMIO + PCI_ENA_MASTER);
 	val = Read_hfc(hc, HFCPCI_STATUS);
 	printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val);
 	hc->hw.cirm = HFCPCI_RESET;	/* Reset On */
@@ -255,7 +255,7 @@ reset_hfcpci(struct hfc_pci *hc)
 	Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt);
 
 	hc->hw.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC |
-	    HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
+		HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
 	Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
 
 	/* Clear already pending ints */
@@ -319,10 +319,10 @@ static struct bchannel *
 Sel_BCS(struct hfc_pci *hc, int channel)
 {
 	if (test_bit(FLG_ACTIVE, &hc->bch[0].Flags) &&
-		(hc->bch[0].nr & channel))
+	    (hc->bch[0].nr & channel))
 		return &hc->bch[0];
 	else if (test_bit(FLG_ACTIVE, &hc->bch[1].Flags) &&
-		(hc->bch[1].nr & channel))
+		 (hc->bch[1].nr & channel))
 		return &hc->bch[1];
 	else
 		return NULL;
@@ -352,7 +352,7 @@ hfcpci_clear_fifo_rx(struct hfc_pci *hc, int fifo)
 	bzr->f2 = bzr->f1;	/* init F pointers to remain constant */
 	bzr->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
 	bzr->za[MAX_B_FRAMES].z2 = cpu_to_le16(
-	    le16_to_cpu(bzr->za[MAX_B_FRAMES].z1));
+		le16_to_cpu(bzr->za[MAX_B_FRAMES].z1));
 	if (fifo_state)
 		hc->hw.fifo_en |= fifo_state;
 	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
@@ -378,11 +378,11 @@ static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
 	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
 	if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
 		printk(KERN_DEBUG "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) "
-		    "z1(%x) z2(%x) state(%x)\n",
-		    fifo, bzt->f1, bzt->f2,
-		    le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
-		    le16_to_cpu(bzt->za[MAX_B_FRAMES].z2),
-		    fifo_state);
+		       "z1(%x) z2(%x) state(%x)\n",
+		       fifo, bzt->f1, bzt->f2,
+		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
+		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z2),
+		       fifo_state);
 	bzt->f2 = MAX_B_FRAMES;
 	bzt->f1 = bzt->f2;	/* init F pointers to remain constant */
 	bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
@@ -392,10 +392,10 @@ static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
 	Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
 	if (hc->bch[fifo].debug & DEBUG_HW_BCHANNEL)
 		printk(KERN_DEBUG
-		    "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n",
-		    fifo, bzt->f1, bzt->f2,
-		    le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
-		    le16_to_cpu(bzt->za[MAX_B_FRAMES].z2));
+		       "hfcpci_clear_fifo_tx%d f1(%x) f2(%x) z1(%x) z2(%x)\n",
+		       fifo, bzt->f1, bzt->f2,
+		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z1),
+		       le16_to_cpu(bzt->za[MAX_B_FRAMES].z2));
 }
 
 /*
@@ -403,7 +403,7 @@ static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
  */
 static void
 hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
-    u_char *bdata, int count)
+		   u_char *bdata, int count)
 {
 	u_char		*ptr, *ptr1, new_f2;
 	int		maxlen, new_z2;
@@ -420,7 +420,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
 	    (*(bdata + (le16_to_cpu(zp->z1) - B_SUB_VAL)))) {
 		if (bch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "hfcpci_empty_fifo: incoming packet "
-			    "invalid length %d or crc\n", count);
+			       "invalid length %d or crc\n", count);
 #ifdef ERROR_STATISTIC
 		bch->err_inv++;
 #endif
@@ -439,10 +439,10 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
 			maxlen = count;		/* complete transfer */
 		else
 			maxlen = B_FIFO_SIZE + B_SUB_VAL -
-			    le16_to_cpu(zp->z2);	/* maximum */
+				le16_to_cpu(zp->z2);	/* maximum */
 
 		ptr1 = bdata + (le16_to_cpu(zp->z2) - B_SUB_VAL);
-		    /* start of data */
+		/* start of data */
 		memcpy(ptr, ptr1, maxlen);	/* copy data */
 		count -= maxlen;
 
@@ -480,33 +480,33 @@ receive_dmsg(struct hfc_pci *hc)
 		rcnt++;
 		if (dch->debug & DEBUG_HW_DCHANNEL)
 			printk(KERN_DEBUG
-			    "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n",
-				df->f1, df->f2,
-				le16_to_cpu(zp->z1),
-				le16_to_cpu(zp->z2),
-				rcnt);
+			       "hfcpci recd f1(%d) f2(%d) z1(%x) z2(%x) cnt(%d)\n",
+			       df->f1, df->f2,
+			       le16_to_cpu(zp->z1),
+			       le16_to_cpu(zp->z2),
+			       rcnt);
 
 		if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) ||
 		    (df->data[le16_to_cpu(zp->z1)])) {
 			if (dch->debug & DEBUG_HW)
 				printk(KERN_DEBUG
-				    "empty_fifo hfcpci paket inv. len "
-				    "%d or crc %d\n",
-				    rcnt,
-				    df->data[le16_to_cpu(zp->z1)]);
+				       "empty_fifo hfcpci paket inv. len "
+				       "%d or crc %d\n",
+				       rcnt,
+				       df->data[le16_to_cpu(zp->z1)]);
 #ifdef ERROR_STATISTIC
 			cs->err_rx++;
 #endif
 			df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
-			    (MAX_D_FRAMES + 1);	/* next buffer */
+				(MAX_D_FRAMES + 1);	/* next buffer */
 			df->za[df->f2 & D_FREG_MASK].z2 =
-			    cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
-			    (D_FIFO_SIZE - 1));
+				cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
+					    (D_FIFO_SIZE - 1));
 		} else {
 			dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
 			if (!dch->rx_skb) {
 				printk(KERN_WARNING
-				    "HFC-PCI: D receive out of memory\n");
+				       "HFC-PCI: D receive out of memory\n");
 				break;
 			}
 			total = rcnt;
@@ -517,10 +517,10 @@ receive_dmsg(struct hfc_pci *hc)
 				maxlen = rcnt;	/* complete transfer */
 			else
 				maxlen = D_FIFO_SIZE - le16_to_cpu(zp->z2);
-				    /* maximum */
+			/* maximum */
 
 			ptr1 = df->data + le16_to_cpu(zp->z2);
-			    /* start of data */
+			/* start of data */
 			memcpy(ptr, ptr1, maxlen);	/* copy data */
 			rcnt -= maxlen;
 
@@ -530,9 +530,9 @@ receive_dmsg(struct hfc_pci *hc)
 				memcpy(ptr, ptr1, rcnt);	/* rest */
 			}
 			df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
-			    (MAX_D_FRAMES + 1);	/* next buffer */
+				(MAX_D_FRAMES + 1);	/* next buffer */
 			df->za[df->f2 & D_FREG_MASK].z2 = cpu_to_le16((
-			    le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1));
+									      le16_to_cpu(zp->z2) + total) & (D_FIFO_SIZE - 1));
 			recv_Dchannel(dch);
 		}
 	}
@@ -544,9 +544,9 @@ receive_dmsg(struct hfc_pci *hc)
  */
 static void
 hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
-	struct bzfifo *txbz, u_char *bdata)
+			struct bzfifo *txbz, u_char *bdata)
 {
-	 __le16	*z1r, *z2r, *z1t, *z2t;
+	__le16	*z1r, *z2r, *z1t, *z2t;
 	int	new_z2, fcnt_rx, fcnt_tx, maxlen;
 	u_char	*ptr, *ptr1;
 
@@ -573,9 +573,9 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
 	fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
 	if (fcnt_tx <= 0)
 		fcnt_tx += B_FIFO_SIZE;
-		    /* fcnt_tx contains available bytes in tx-fifo */
+	/* fcnt_tx contains available bytes in tx-fifo */
 	fcnt_tx = B_FIFO_SIZE - fcnt_tx;
-		    /* remaining bytes to send (bytes in tx-fifo) */
+	/* remaining bytes to send (bytes in tx-fifo) */
 
 	bch->rx_skb = mI_alloc_skb(fcnt_rx, GFP_ATOMIC);
 	if (bch->rx_skb) {
@@ -584,10 +584,10 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
 			maxlen = fcnt_rx;	/* complete transfer */
 		else
 			maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
-			    /* maximum */
+		/* maximum */
 
 		ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
-		    /* start of data */
+		/* start of data */
 		memcpy(ptr, ptr1, maxlen);	/* copy data */
 		fcnt_rx -= maxlen;
 
@@ -632,7 +632,7 @@ Begin:
 	if (rxbz->f1 != rxbz->f2) {
 		if (bch->debug & DEBUG_HW_BCHANNEL)
 			printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
-			    bch->nr, rxbz->f1, rxbz->f2);
+			       bch->nr, rxbz->f1, rxbz->f2);
 		zp = &rxbz->za[rxbz->f2];
 
 		rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
@@ -641,9 +641,9 @@ Begin:
 		rcnt++;
 		if (bch->debug & DEBUG_HW_BCHANNEL)
 			printk(KERN_DEBUG
-			    "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
-			    bch->nr, le16_to_cpu(zp->z1),
-			    le16_to_cpu(zp->z2), rcnt);
+			       "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
+			       bch->nr, le16_to_cpu(zp->z1),
+			       le16_to_cpu(zp->z2), rcnt);
 		hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt);
 		rcnt = rxbz->f1 - rxbz->f2;
 		if (rcnt < 0)
@@ -691,15 +691,15 @@ hfcpci_fill_dfifo(struct hfc_pci *hc)
 
 	if (dch->debug & DEBUG_HW_DFIFO)
 		printk(KERN_DEBUG "%s:f1(%d) f2(%d) z1(f1)(%x)\n", __func__,
-		    df->f1, df->f2,
-		    le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1));
+		       df->f1, df->f2,
+		       le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1));
 	fcnt = df->f1 - df->f2;	/* frame count actually buffered */
 	if (fcnt < 0)
 		fcnt += (MAX_D_FRAMES + 1);	/* if wrap around */
 	if (fcnt > (MAX_D_FRAMES - 1)) {
 		if (dch->debug & DEBUG_HW_DCHANNEL)
 			printk(KERN_DEBUG
-			    "hfcpci_fill_Dfifo more as 14 frames\n");
+			       "hfcpci_fill_Dfifo more as 14 frames\n");
 #ifdef ERROR_STATISTIC
 		cs->err_tx++;
 #endif
@@ -707,25 +707,25 @@ hfcpci_fill_dfifo(struct hfc_pci *hc)
 	}
 	/* now determine free bytes in FIFO buffer */
 	maxlen = le16_to_cpu(df->za[df->f2 & D_FREG_MASK].z2) -
-	    le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1;
+		le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) - 1;
 	if (maxlen <= 0)
 		maxlen += D_FIFO_SIZE;	/* count now contains available bytes */
 
 	if (dch->debug & DEBUG_HW_DCHANNEL)
 		printk(KERN_DEBUG "hfcpci_fill_Dfifo count(%d/%d)\n",
-			count, maxlen);
+		       count, maxlen);
 	if (count > maxlen) {
 		if (dch->debug & DEBUG_HW_DCHANNEL)
 			printk(KERN_DEBUG "hfcpci_fill_Dfifo no fifo mem\n");
 		return;
 	}
 	new_z1 = (le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1) + count) &
-	    (D_FIFO_SIZE - 1);
+		(D_FIFO_SIZE - 1);
 	new_f1 = ((df->f1 + 1) & D_FREG_MASK) | (D_FREG_MASK + 1);
 	src = dch->tx_skb->data + dch->tx_idx;	/* source pointer */
 	dst = df->data + le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
 	maxlen = D_FIFO_SIZE - le16_to_cpu(df->za[df->f1 & D_FREG_MASK].z1);
-	    /* end fifo */
+	/* end fifo */
 	if (maxlen > count)
 		maxlen = count;	/* limit size */
 	memcpy(dst, src, maxlen);	/* first copy */
@@ -737,9 +737,9 @@ hfcpci_fill_dfifo(struct hfc_pci *hc)
 		memcpy(dst, src, count);
 	}
 	df->za[new_f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
-	    /* for next buffer */
+	/* for next buffer */
 	df->za[df->f1 & D_FREG_MASK].z1 = cpu_to_le16(new_z1);
-	    /* new pos actual buffer */
+	/* new pos actual buffer */
 	df->f1 = new_f1;	/* next frame */
 	dch->tx_idx = dch->tx_skb->len;
 }
@@ -750,7 +750,7 @@ hfcpci_fill_dfifo(struct hfc_pci *hc)
 static void
 hfcpci_fill_fifo(struct bchannel *bch)
 {
-	struct hfc_pci 	*hc = bch->hw;
+	struct hfc_pci	*hc = bch->hw;
 	int		maxlen, fcnt;
 	int		count, new_z1;
 	struct bzfifo	*bz;
@@ -776,35 +776,35 @@ hfcpci_fill_fifo(struct bchannel *bch)
 		z2t = z1t + 1;
 		if (bch->debug & DEBUG_HW_BCHANNEL)
 			printk(KERN_DEBUG "hfcpci_fill_fifo_trans ch(%x) "
-			    "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count,
-			    le16_to_cpu(*z1t), le16_to_cpu(*z2t));
+			       "cnt(%d) z1(%x) z2(%x)\n", bch->nr, count,
+			       le16_to_cpu(*z1t), le16_to_cpu(*z2t));
 		fcnt = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
 		if (fcnt <= 0)
 			fcnt += B_FIFO_SIZE;
-			    /* fcnt contains available bytes in fifo */
+		/* fcnt contains available bytes in fifo */
 		fcnt = B_FIFO_SIZE - fcnt;
-		    /* remaining bytes to send (bytes in fifo) */
+		/* remaining bytes to send (bytes in fifo) */
 
 		/* "fill fifo if empty" feature */
 		if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) {
 			/* printk(KERN_DEBUG "%s: buffer empty, so we have "
-				"underrun\n", __func__); */
+			   "underrun\n", __func__); */
 			/* fill buffer, to prevent future underrun */
 			count = HFCPCI_FILLEMPTY;
 			new_z1 = le16_to_cpu(*z1t) + count;
-			   /* new buffer Position */
+			/* new buffer Position */
 			if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
 				new_z1 -= B_FIFO_SIZE;	/* buffer wrap */
 			dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
 			maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
-			    /* end of fifo */
+			/* end of fifo */
 			if (bch->debug & DEBUG_HW_BFIFO)
 				printk(KERN_DEBUG "hfcpci_FFt fillempty "
-				    "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
-				    fcnt, maxlen, new_z1, dst);
+				       "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
+				       fcnt, maxlen, new_z1, dst);
 			fcnt += count;
 			if (maxlen > count)
-				maxlen = count; 	/* limit size */
+				maxlen = count;		/* limit size */
 			memset(dst, 0x2a, maxlen);	/* first copy */
 			count -= maxlen;		/* remaining bytes */
 			if (count) {
@@ -814,7 +814,7 @@ hfcpci_fill_fifo(struct bchannel *bch)
 			*z1t = cpu_to_le16(new_z1);	/* now send data */
 		}
 
-next_t_frame:
+	next_t_frame:
 		count = bch->tx_skb->len - bch->tx_idx;
 		/* maximum fill shall be poll*2 */
 		if (count > (poll << 1) - fcnt)
@@ -823,18 +823,18 @@ next_t_frame:
 			return;
 		/* data is suitable for fifo */
 		new_z1 = le16_to_cpu(*z1t) + count;
-		    /* new buffer Position */
+		/* new buffer Position */
 		if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
 			new_z1 -= B_FIFO_SIZE;	/* buffer wrap */
 		src = bch->tx_skb->data + bch->tx_idx;
-		    /* source pointer */
+		/* source pointer */
 		dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
 		maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
-		    /* end of fifo */
+		/* end of fifo */
 		if (bch->debug & DEBUG_HW_BFIFO)
 			printk(KERN_DEBUG "hfcpci_FFt fcnt(%d) "
-			    "maxl(%d) nz1(%x) dst(%p)\n",
-			    fcnt, maxlen, new_z1, dst);
+			       "maxl(%d) nz1(%x) dst(%p)\n",
+			       fcnt, maxlen, new_z1, dst);
 		fcnt += count;
 		bch->tx_idx += count;
 		if (maxlen > count)
@@ -859,27 +859,27 @@ next_t_frame:
 	}
 	if (bch->debug & DEBUG_HW_BCHANNEL)
 		printk(KERN_DEBUG
-		    "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n",
-		    __func__, bch->nr, bz->f1, bz->f2,
-		    bz->za[bz->f1].z1);
+		       "%s: ch(%x) f1(%d) f2(%d) z1(f1)(%x)\n",
+		       __func__, bch->nr, bz->f1, bz->f2,
+		       bz->za[bz->f1].z1);
 	fcnt = bz->f1 - bz->f2;	/* frame count actually buffered */
 	if (fcnt < 0)
 		fcnt += (MAX_B_FRAMES + 1);	/* if wrap around */
 	if (fcnt > (MAX_B_FRAMES - 1)) {
 		if (bch->debug & DEBUG_HW_BCHANNEL)
 			printk(KERN_DEBUG
-			    "hfcpci_fill_Bfifo more as 14 frames\n");
+			       "hfcpci_fill_Bfifo more as 14 frames\n");
 		return;
 	}
 	/* now determine free bytes in FIFO buffer */
 	maxlen = le16_to_cpu(bz->za[bz->f2].z2) -
-	    le16_to_cpu(bz->za[bz->f1].z1) - 1;
+		le16_to_cpu(bz->za[bz->f1].z1) - 1;
 	if (maxlen <= 0)
 		maxlen += B_FIFO_SIZE;	/* count now contains available bytes */
 
 	if (bch->debug & DEBUG_HW_BCHANNEL)
 		printk(KERN_DEBUG "hfcpci_fill_fifo ch(%x) count(%d/%d)\n",
-			bch->nr, count, maxlen);
+		       bch->nr, count, maxlen);
 
 	if (maxlen < count) {
 		if (bch->debug & DEBUG_HW_BCHANNEL)
@@ -887,7 +887,7 @@ next_t_frame:
 		return;
 	}
 	new_z1 = le16_to_cpu(bz->za[bz->f1].z1) + count;
-	    /* new buffer Position */
+	/* new buffer Position */
 	if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
 		new_z1 -= B_FIFO_SIZE;	/* buffer wrap */
 
@@ -895,7 +895,7 @@ next_t_frame:
 	src = bch->tx_skb->data + bch->tx_idx;	/* source pointer */
 	dst = bdata + (le16_to_cpu(bz->za[bz->f1].z1) - B_SUB_VAL);
 	maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(bz->za[bz->f1].z1);
-	    /* end fifo */
+	/* end fifo */
 	if (maxlen > count)
 		maxlen = count;	/* limit size */
 	memcpy(dst, src, maxlen);	/* first copy */
@@ -923,7 +923,7 @@ ph_state_te(struct dchannel *dch)
 {
 	if (dch->debug)
 		printk(KERN_DEBUG "%s: TE newstate %x\n",
-			__func__, dch->state);
+		       __func__, dch->state);
 	switch (dch->state) {
 	case 0:
 		l1_event(dch->l1, HW_RESET_IND);
@@ -961,7 +961,7 @@ handle_nt_timer3(struct dchannel *dch) {
 		hc->hw.mst_m |= HFCPCI_MASTER;
 	Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
 	_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-	    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+		    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 }
 
 static void
@@ -971,7 +971,7 @@ ph_state_nt(struct dchannel *dch)
 
 	if (dch->debug)
 		printk(KERN_DEBUG "%s: NT newstate %x\n",
-			__func__, dch->state);
+		       __func__, dch->state);
 	switch (dch->state) {
 	case 2:
 		if (hc->hw.nt_timer < 0) {
@@ -993,7 +993,7 @@ ph_state_nt(struct dchannel *dch)
 			hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
 			hc->hw.ctmt |= HFCPCI_TIM3_125;
 			Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
-				HFCPCI_CLTIMER);
+				  HFCPCI_CLTIMER);
 			test_and_clear_bit(FLG_HFC_TIMER_T3, &dch->Flags);
 			test_and_set_bit(FLG_HFC_TIMER_T1, &dch->Flags);
 			/* allow G2 -> G3 transition */
@@ -1013,7 +1013,7 @@ ph_state_nt(struct dchannel *dch)
 		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
 		_queue_data(&dch->dev.D, PH_DEACTIVATE_IND,
-		    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 		break;
 	case 4:
 		hc->hw.nt_timer = 0;
@@ -1025,7 +1025,7 @@ ph_state_nt(struct dchannel *dch)
 	case 3:
 		if (!test_and_set_bit(FLG_HFC_TIMER_T3, &dch->Flags)) {
 			if (!test_and_clear_bit(FLG_L2_ACTIVATED,
-			    &dch->Flags)) {
+						&dch->Flags)) {
 				handle_nt_timer3(dch);
 				break;
 			}
@@ -1036,7 +1036,7 @@ ph_state_nt(struct dchannel *dch)
 			hc->hw.ctmt &= ~HFCPCI_AUTO_TIMER;
 			hc->hw.ctmt |= HFCPCI_TIM3_125;
 			Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt |
-				HFCPCI_CLTIMER);
+				  HFCPCI_CLTIMER);
 		}
 		break;
 	}
@@ -1081,7 +1081,7 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
 			hc->hw.mst_m |= HFCPCI_MASTER;
 		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
 		Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
-		   HFCPCI_DO_ACTION);
+			  HFCPCI_DO_ACTION);
 		l1_event(dch->l1, HW_POWERUP_IND);
 		break;
 	case HW_DEACT_REQ:
@@ -1107,17 +1107,17 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
 	case PH_ACTIVATE_IND:
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	case PH_DEACTIVATE_IND:
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: unknown command %x\n",
-			    __func__, cmd);
+			       __func__, cmd);
 		return -1;
 	}
 	return 0;
@@ -1170,7 +1170,7 @@ hfcpci_int(int intno, void *dev_id)
 		val = Read_hfc(hc, HFCPCI_INT_S1);
 		if (hc->dch.debug & DEBUG_HW_DCHANNEL)
 			printk(KERN_DEBUG
-			    "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val);
+			       "HFC-PCI: stat(%02x) s1(%02x)\n", stat, val);
 	} else {
 		/* shared */
 		spin_unlock(&hc->lock);
@@ -1185,7 +1185,7 @@ hfcpci_int(int intno, void *dev_id)
 		exval = Read_hfc(hc, HFCPCI_STATES) & 0xf;
 		if (hc->dch.debug & DEBUG_HW_DCHANNEL)
 			printk(KERN_DEBUG "ph_state chg %d->%d\n",
-				hc->dch.state, exval);
+			       hc->dch.state, exval);
 		hc->dch.state = exval;
 		schedule_event(&hc->dch, FLG_PHCHANGE);
 		val &= ~0x40;
@@ -1198,7 +1198,7 @@ hfcpci_int(int intno, void *dev_id)
 		val &= ~0x80;
 		Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER);
 	}
-	if (val & 0x08) { 	/* B1 rx */
+	if (val & 0x08) {	/* B1 rx */
 		bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
 		if (bch)
 			main_rec_hfcpci(bch);
@@ -1257,22 +1257,22 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
 
 	if (bch->debug & DEBUG_HW_BCHANNEL)
 		printk(KERN_DEBUG
-		    "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n",
-		    bch->state, protocol, bch->nr, bc);
+		       "HFCPCI bchannel protocol %x-->%x ch %x-->%x\n",
+		       bch->state, protocol, bch->nr, bc);
 
 	fifo2 = bc;
-	pcm_mode = (bc>>24) & 0xff;
+	pcm_mode = (bc >> 24) & 0xff;
 	if (pcm_mode) { /* PCM SLOT USE */
 		if (!test_bit(HFC_CFG_PCM, &hc->cfg))
 			printk(KERN_WARNING
-			    "%s: pcm channel id without HFC_CFG_PCM\n",
-			    __func__);
-		rx_slot = (bc>>8) & 0xff;
-		tx_slot = (bc>>16) & 0xff;
+			       "%s: pcm channel id without HFC_CFG_PCM\n",
+			       __func__);
+		rx_slot = (bc >> 8) & 0xff;
+		tx_slot = (bc >> 16) & 0xff;
 		bc = bc & 0xff;
 	} else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE))
 		printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
-		    __func__);
+		       __func__);
 	if (hc->chanlimit > 1) {
 		hc->hw.bswapped = 0;	/* B1 and B2 normal mode */
 		hc->hw.sctrl_e &= ~0x80;
@@ -1308,11 +1308,11 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
 		if (fifo2 & 2) {
 			hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2;
 			hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS +
-				HFCPCI_INTS_B2REC);
+					   HFCPCI_INTS_B2REC);
 		} else {
 			hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1;
 			hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS +
-				HFCPCI_INTS_B1REC);
+					   HFCPCI_INTS_B1REC);
 		}
 #ifdef REVERSE_BITORDER
 		if (bch->nr & 2)
@@ -1347,14 +1347,14 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
 			hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
 			if (!tics)
 				hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS +
-				    HFCPCI_INTS_B2REC);
+						  HFCPCI_INTS_B2REC);
 			hc->hw.ctmt |= 2;
 			hc->hw.conn &= ~0x18;
 		} else {
 			hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
 			if (!tics)
 				hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS +
-				    HFCPCI_INTS_B1REC);
+						  HFCPCI_INTS_B1REC);
 			hc->hw.ctmt |= 1;
 			hc->hw.conn &= ~0x03;
 		}
@@ -1376,14 +1376,14 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
 			hc->hw.last_bfifo_cnt[1] = 0;
 			hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
 			hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS +
-			    HFCPCI_INTS_B2REC);
+					  HFCPCI_INTS_B2REC);
 			hc->hw.ctmt &= ~2;
 			hc->hw.conn &= ~0x18;
 		} else {
 			hc->hw.last_bfifo_cnt[0] = 0;
 			hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
 			hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS +
-			    HFCPCI_INTS_B1REC);
+					  HFCPCI_INTS_B1REC);
 			hc->hw.ctmt &= ~1;
 			hc->hw.conn &= ~0x03;
 		}
@@ -1395,7 +1395,7 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
 	}
 	if (test_bit(HFC_CFG_PCM, &hc->cfg)) {
 		if ((protocol == ISDN_P_NONE) ||
-			(protocol == -1)) {	/* init case */
+		    (protocol == -1)) {	/* init case */
 			rx_slot = 0;
 			tx_slot = 0;
 		} else {
@@ -1411,18 +1411,18 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
 			hc->hw.conn &= 0xc7;
 			hc->hw.conn |= 0x08;
 			printk(KERN_DEBUG "%s: Write_hfc: B2_SSL 0x%x\n",
-				__func__, tx_slot);
+			       __func__, tx_slot);
 			printk(KERN_DEBUG "%s: Write_hfc: B2_RSL 0x%x\n",
-				__func__, rx_slot);
+			       __func__, rx_slot);
 			Write_hfc(hc, HFCPCI_B2_SSL, tx_slot);
 			Write_hfc(hc, HFCPCI_B2_RSL, rx_slot);
 		} else {
 			hc->hw.conn &= 0xf8;
 			hc->hw.conn |= 0x01;
 			printk(KERN_DEBUG "%s: Write_hfc: B1_SSL 0x%x\n",
-				__func__, tx_slot);
+			       __func__, tx_slot);
 			printk(KERN_DEBUG "%s: Write_hfc: B1_RSL 0x%x\n",
-				__func__, rx_slot);
+			       __func__, rx_slot);
 			Write_hfc(hc, HFCPCI_B1_SSL, tx_slot);
 			Write_hfc(hc, HFCPCI_B1_RSL, rx_slot);
 		}
@@ -1447,12 +1447,12 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
 
 	if (bch->debug & DEBUG_HW_BCHANNEL)
 		printk(KERN_DEBUG
-		    "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n",
-		    bch->state, protocol, bch->nr, chan);
+		       "HFCPCI bchannel test rx protocol %x-->%x ch %x-->%x\n",
+		       bch->state, protocol, bch->nr, chan);
 	if (bch->nr != chan) {
 		printk(KERN_DEBUG
-		    "HFCPCI rxtest wrong channel parameter %x/%x\n",
-		    bch->nr, chan);
+		       "HFCPCI rxtest wrong channel parameter %x/%x\n",
+		       bch->nr, chan);
 		return -EINVAL;
 	}
 	switch (protocol) {
@@ -1543,7 +1543,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 		test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
-				"off=%d)\n", __func__, bch->nr, !!cq->p1);
+			       "off=%d)\n", __func__, bch->nr, !!cq->p1);
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);
@@ -1593,7 +1593,7 @@ hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-			__func__, cmd);
+		       __func__, cmd);
 	}
 	return ret;
 }
@@ -1635,12 +1635,12 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
 			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
 				spin_unlock_irqrestore(&hc->lock, flags);
 				_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+					    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 				break;
 			}
 			test_and_set_bit(FLG_L2_ACTIVATED, &dch->Flags);
 			Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE |
-			    HFCPCI_DO_ACTION | 1);
+				  HFCPCI_DO_ACTION | 1);
 		} else
 			ret = l1_event(dch->l1, hh->prim);
 		spin_unlock_irqrestore(&hc->lock, flags);
@@ -1718,12 +1718,12 @@ hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(&hc->lock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				NULL, GFP_KERNEL);
+				    NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		deactivate_bchannel(bch);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	}
@@ -1763,7 +1763,7 @@ init_card(struct hfc_pci *hc)
 	spin_unlock_irqrestore(&hc->lock, flags);
 	if (request_irq(hc->irq, hfcpci_int, IRQF_SHARED, "HFC PCI", hc)) {
 		printk(KERN_WARNING
-		    "mISDN: couldn't get interrupt %d\n", hc->irq);
+		       "mISDN: couldn't get interrupt %d\n", hc->irq);
 		return -EIO;
 	}
 	spin_lock_irqsave(&hc->lock, flags);
@@ -1779,9 +1779,9 @@ init_card(struct hfc_pci *hc)
 		spin_unlock_irqrestore(&hc->lock, flags);
 		/* Timeout 80ms */
 		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout((80*HZ)/1000);
+		schedule_timeout((80 * HZ) / 1000);
 		printk(KERN_INFO "HFC PCI: IRQ %d count %d\n",
-			hc->irq, hc->irqcnt);
+		       hc->irq, hc->irqcnt);
 		/* now switch timer interrupt off */
 		spin_lock_irqsave(&hc->lock, flags);
 		hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
@@ -1790,8 +1790,8 @@ init_card(struct hfc_pci *hc)
 		Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
 		if (!hc->irqcnt) {
 			printk(KERN_WARNING
-			    "HFC PCI: IRQ(%d) getting no interrupts "
-			    "during init %d\n", hc->irq, 4 - cnt);
+			       "HFC PCI: IRQ(%d) getting no interrupts "
+			       "during init %d\n", hc->irq, 4 - cnt);
 			if (cnt == 1)
 				break;
 			else {
@@ -1819,7 +1819,7 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 	switch (cq->op) {
 	case MISDN_CTRL_GETOP:
 		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
-		    MISDN_CTRL_DISCONNECT;
+			MISDN_CTRL_DISCONNECT;
 		break;
 	case MISDN_CTRL_LOOP:
 		/* channel 0 disabled loop */
@@ -1833,7 +1833,7 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 			else
 				slot = 0x80;
 			printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
-			    __func__, slot);
+			       __func__, slot);
 			Write_hfc(hc, HFCPCI_B1_SSL, slot);
 			Write_hfc(hc, HFCPCI_B1_RSL, slot);
 			hc->hw.conn = (hc->hw.conn & ~7) | 6;
@@ -1845,7 +1845,7 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 			else
 				slot = 0x81;
 			printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
-			    __func__, slot);
+			       __func__, slot);
 			Write_hfc(hc, HFCPCI_B2_SSL, slot);
 			Write_hfc(hc, HFCPCI_B2_RSL, slot);
 			hc->hw.conn = (hc->hw.conn & ~0x38) | 0x30;
@@ -1875,7 +1875,7 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 		else
 			slot = 0x80;
 		printk(KERN_DEBUG "%s: Write_hfc: B1_SSL/RSL 0x%x\n",
-		    __func__, slot);
+		       __func__, slot);
 		Write_hfc(hc, HFCPCI_B1_SSL, slot);
 		Write_hfc(hc, HFCPCI_B2_RSL, slot);
 		if (test_bit(HFC_CFG_SW_DD_DU, &hc->cfg))
@@ -1883,7 +1883,7 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 		else
 			slot = 0x81;
 		printk(KERN_DEBUG "%s: Write_hfc: B2_SSL/RSL 0x%x\n",
-		    __func__, slot);
+		       __func__, slot);
 		Write_hfc(hc, HFCPCI_B2_SSL, slot);
 		Write_hfc(hc, HFCPCI_B1_RSL, slot);
 		hc->hw.conn = (hc->hw.conn & ~0x3f) | 0x36;
@@ -1898,7 +1898,7 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n",
-		    __func__, cq->op);
+		       __func__, cq->op);
 		ret = -EINVAL;
 		break;
 	}
@@ -1907,13 +1907,13 @@ channel_ctrl(struct hfc_pci *hc, struct mISDN_ctrl_req *cq)
 
 static int
 open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch,
-    struct channel_req *rq)
+	      struct channel_req *rq)
 {
 	int err = 0;
 
 	if (debug & DEBUG_HW_OPEN)
 		printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
-		    hc->dch.dev.id, __builtin_return_address(0));
+		       hc->dch.dev.id, __builtin_return_address(0));
 	if (rq->protocol == ISDN_P_NONE)
 		return -EINVAL;
 	if (rq->adr.channel == 1) {
@@ -1949,7 +1949,7 @@ open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch,
 	if (((ch->protocol == ISDN_P_NT_S0) && (hc->dch.state == 3)) ||
 	    ((ch->protocol == ISDN_P_TE_S0) && (hc->dch.state == 7))) {
 		_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-		    0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 	}
 	rq->ch = ch;
 	if (!try_module_get(THIS_MODULE))
@@ -1991,7 +1991,7 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 	if (dch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		    __func__, cmd, arg);
+		       __func__, cmd, arg);
 	switch (cmd) {
 	case OPEN_CHANNEL:
 		rq = arg;
@@ -2004,8 +2004,8 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	case CLOSE_CHANNEL:
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
-			    __func__, hc->dch.dev.id,
-			    __builtin_return_address(0));
+			       __func__, hc->dch.dev.id,
+			       __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -2014,7 +2014,7 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: unknown command %x\n",
-			    __func__, cmd);
+			       __func__, cmd);
 		return -EINVAL;
 	}
 	return err;
@@ -2047,16 +2047,16 @@ setup_hw(struct hfc_pci *hc)
 	/* We silently assume the address is okay if nonzero */
 	if (!buffer) {
 		printk(KERN_WARNING
-		    "HFC-PCI: Error allocating memory for FIFO!\n");
+		       "HFC-PCI: Error allocating memory for FIFO!\n");
 		return 1;
 	}
 	hc->hw.fifos = buffer;
 	pci_write_config_dword(hc->pdev, 0x80, hc->hw.dmahandle);
 	hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256);
 	printk(KERN_INFO
-		"HFC-PCI: defined at mem %#lx fifo %#lx(%#lx) IRQ %d HZ %d\n",
-		(u_long) hc->hw.pci_io, (u_long) hc->hw.fifos,
-		(u_long) hc->hw.dmahandle, hc->irq, HZ);
+	       "HFC-PCI: defined at mem %#lx fifo %#lx(%#lx) IRQ %d HZ %d\n",
+	       (u_long) hc->hw.pci_io, (u_long) hc->hw.fifos,
+	       (u_long) hc->hw.dmahandle, hc->irq, HZ);
 	/* enable memory mapped ports, disable busmaster */
 	pci_write_config_word(hc->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
 	hc->hw.int_m2 = 0;
@@ -2113,7 +2113,7 @@ setup_card(struct hfc_pci *card)
 	card->dch.hw = card;
 	card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
 	card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	card->dch.dev.D.send = hfcpci_l2l1D;
 	card->dch.dev.D.ctrl = hfc_dctrl;
 	card->dch.dev.nrbchan = 2;
@@ -2174,13 +2174,13 @@ static const struct _hfc_map hfc_map[] =
 	{HFC_ANIGMA_MC145575, 0, "Motorola MC145575"},
 	{HFC_ZOLTRIX_2BD0, 0, "Zoltrix 2BD0"},
 	{HFC_DIGI_DF_M_IOM2_E, 0,
-	    "Digi International DataFire Micro V IOM2 (Europe)"},
+	 "Digi International DataFire Micro V IOM2 (Europe)"},
 	{HFC_DIGI_DF_M_E, 0,
-	    "Digi International DataFire Micro V (Europe)"},
+	 "Digi International DataFire Micro V (Europe)"},
 	{HFC_DIGI_DF_M_IOM2_A, 0,
-	    "Digi International DataFire Micro V IOM2 (North America)"},
+	 "Digi International DataFire Micro V IOM2 (North America)"},
 	{HFC_DIGI_DF_M_A, 0,
-	    "Digi International DataFire Micro V (North America)"},
+	 "Digi International DataFire Micro V (North America)"},
 	{HFC_SITECOM_DC105V2, 0, "Sitecom Connectivity DC-105 ISDN TA"},
 	{},
 };
@@ -2188,51 +2188,51 @@ static const struct _hfc_map hfc_map[] =
 static struct pci_device_id hfc_ids[] =
 {
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_2BD0),
-		(unsigned long) &hfc_map[0] },
+	  (unsigned long) &hfc_map[0] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B000),
-		(unsigned long) &hfc_map[1] },
+	  (unsigned long) &hfc_map[1] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B006),
-		(unsigned long) &hfc_map[2] },
+	  (unsigned long) &hfc_map[2] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B007),
-		(unsigned long) &hfc_map[3] },
+	  (unsigned long) &hfc_map[3] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B008),
-		(unsigned long) &hfc_map[4] },
+	  (unsigned long) &hfc_map[4] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B009),
-		(unsigned long) &hfc_map[5] },
+	  (unsigned long) &hfc_map[5] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00A),
-		(unsigned long) &hfc_map[6] },
+	  (unsigned long) &hfc_map[6] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00B),
-		(unsigned long) &hfc_map[7] },
+	  (unsigned long) &hfc_map[7] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B00C),
-		(unsigned long) &hfc_map[8] },
+	  (unsigned long) &hfc_map[8] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B100),
-		(unsigned long) &hfc_map[9] },
+	  (unsigned long) &hfc_map[9] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B700),
-		(unsigned long) &hfc_map[10] },
+	  (unsigned long) &hfc_map[10] },
 	{ PCI_VDEVICE(CCD, PCI_DEVICE_ID_CCD_B701),
-		(unsigned long) &hfc_map[11] },
+	  (unsigned long) &hfc_map[11] },
 	{ PCI_VDEVICE(ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1),
-		(unsigned long) &hfc_map[12] },
+	  (unsigned long) &hfc_map[12] },
 	{ PCI_VDEVICE(ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675),
-		(unsigned long) &hfc_map[13] },
+	  (unsigned long) &hfc_map[13] },
 	{ PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT),
-		(unsigned long) &hfc_map[14] },
+	  (unsigned long) &hfc_map[14] },
 	{ PCI_VDEVICE(BERKOM, PCI_DEVICE_ID_BERKOM_A1T),
-		(unsigned long) &hfc_map[15] },
+	  (unsigned long) &hfc_map[15] },
 	{ PCI_VDEVICE(ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575),
-		(unsigned long) &hfc_map[16] },
+	  (unsigned long) &hfc_map[16] },
 	{ PCI_VDEVICE(ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0),
-		(unsigned long) &hfc_map[17] },
+	  (unsigned long) &hfc_map[17] },
 	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E),
-		(unsigned long) &hfc_map[18] },
+	  (unsigned long) &hfc_map[18] },
 	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_E),
-		(unsigned long) &hfc_map[19] },
+	  (unsigned long) &hfc_map[19] },
 	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A),
-		(unsigned long) &hfc_map[20] },
+	  (unsigned long) &hfc_map[20] },
 	{ PCI_VDEVICE(DIGI, PCI_DEVICE_ID_DIGI_DF_M_A),
-		(unsigned long) &hfc_map[21] },
+	  (unsigned long) &hfc_map[21] },
 	{ PCI_VDEVICE(SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2),
-		(unsigned long) &hfc_map[22] },
+	  (unsigned long) &hfc_map[22] },
 	{},
 };
 
@@ -2277,7 +2277,7 @@ hfc_remove_pci(struct pci_dev *pdev)
 	else
 		if (debug)
 			printk(KERN_DEBUG "%s: drvdata already removed\n",
-			    __func__);
+			       __func__);
 }
 
 
@@ -2317,7 +2317,7 @@ static void
 hfcpci_softirq(void *arg)
 {
 	(void) driver_for_each_device(&hfc_driver.driver, NULL, arg,
-					_hfcpci_softirq);
+				      _hfcpci_softirq);
 
 	/* if next event would be in the past ... */
 	if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
@@ -2343,14 +2343,14 @@ HFC_init(void)
 		poll = (tics * 8000) / HZ;
 		if (poll > 256 || poll < 8) {
 			printk(KERN_ERR "%s: Wrong poll value %d not in range "
-				"of 8..256.\n", __func__, poll);
+			       "of 8..256.\n", __func__, poll);
 			err = -EINVAL;
 			return err;
 		}
 	}
 	if (poll != HFCPCI_BTRANS_THRESHOLD) {
 		printk(KERN_INFO "%s: Using alternative poll value of %d\n",
-			__func__, poll);
+		       __func__, poll);
 		hfc_tl.function = (void *)hfcpci_softirq;
 		hfc_tl.data = 0;
 		init_timer(&hfc_tl);
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 0e1f4d5..6023387 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -27,6 +27,7 @@
  *   poll=<n>, default 128
  *     n : burst size of PH_DATA_IND at transparent rx data
  *
+ * Revision: 0.3.3 (socket), 2008-11-05
  */
 
 #include <linux/module.h>
@@ -36,8 +37,6 @@
 #include <linux/slab.h>
 #include "hfcsusb.h"
 
-static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
-
 static unsigned int debug;
 static int poll = DEFAULT_TRANSP_BURST_SZ;
 
@@ -76,9 +75,9 @@ ctrl_start_transfer(struct hfcsusb *hw)
 		hw->ctrl_urb->transfer_buffer = NULL;
 		hw->ctrl_urb->transfer_buffer_length = 0;
 		hw->ctrl_write.wIndex =
-		    cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg);
+			cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].hfcs_reg);
 		hw->ctrl_write.wValue =
-		    cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val);
+			cpu_to_le16(hw->ctrl_buff[hw->ctrl_out_idx].reg_val);
 
 		usb_submit_urb(hw->ctrl_urb, GFP_ATOMIC);
 	}
@@ -94,7 +93,7 @@ static int write_reg(struct hfcsusb *hw, __u8 reg, __u8 val)
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		printk(KERN_DEBUG "%s: %s reg(0x%02x) val(0x%02x)\n",
-			hw->name, __func__, reg, val);
+		       hw->name, __func__, reg, val);
 
 	spin_lock(&hw->ctrl_lock);
 	if (hw->ctrl_cnt >= HFC_CTRL_BUFSIZE) {
@@ -197,8 +196,8 @@ handle_led(struct hfcsusb *hw, int event)
 	if (hw->led_state != tmpled) {
 		if (debug & DBG_HFC_CALL_TRACE)
 			printk(KERN_DEBUG "%s: %s reg(0x%02x) val(x%02x)\n",
-			    hw->name, __func__,
-			    HFCUSB_P_DATA, hw->led_state);
+			       hw->name, __func__,
+			       HFCUSB_P_DATA, hw->led_state);
 
 		write_reg(hw, HFCUSB_P_DATA, hw->led_state);
 	}
@@ -226,7 +225,7 @@ hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(&hw->lock, flags);
 		if (debug & DBG_HFC_CALL_TRACE)
 			printk(KERN_DEBUG "%s: %s PH_DATA_REQ ret(%i)\n",
-				hw->name, __func__, ret);
+			       hw->name, __func__, ret);
 		if (ret > 0) {
 			/*
 			 * other l1 drivers don't send early confirms on
@@ -245,12 +244,12 @@ hfcusb_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 			ret = 0;
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-				0, NULL, GFP_KERNEL);
+				    0, NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		deactivate_bchannel(bch);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY,
-			0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	}
@@ -271,7 +270,7 @@ hfcsusb_ph_info(struct hfcsusb *hw)
 	int i;
 
 	phi = kzalloc(sizeof(struct ph_info) +
-		dch->dev.nrbchan * sizeof(struct ph_info_ch), GFP_ATOMIC);
+		      dch->dev.nrbchan * sizeof(struct ph_info_ch), GFP_ATOMIC);
 	phi->dch.ch.protocol = hw->protocol;
 	phi->dch.ch.Flags = dch->Flags;
 	phi->dch.state = dch->state;
@@ -281,8 +280,8 @@ hfcsusb_ph_info(struct hfcsusb *hw)
 		phi->bch[i].Flags = hw->bch[i].Flags;
 	}
 	_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
-		sizeof(struct ph_info_dch) + dch->dev.nrbchan *
-		sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
+		    sizeof(struct ph_info_dch) + dch->dev.nrbchan *
+		    sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
 	kfree(phi);
 }
 
@@ -303,7 +302,7 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
 	case PH_DATA_REQ:
 		if (debug & DBG_HFC_CALL_TRACE)
 			printk(KERN_DEBUG "%s: %s: PH_DATA_REQ\n",
-				hw->name, __func__);
+			       hw->name, __func__);
 
 		spin_lock_irqsave(&hw->lock, flags);
 		ret = dchannel_senddata(dch, skb);
@@ -317,20 +316,20 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
 	case PH_ACTIVATE_REQ:
 		if (debug & DBG_HFC_CALL_TRACE)
 			printk(KERN_DEBUG "%s: %s: PH_ACTIVATE_REQ %s\n",
-				hw->name, __func__,
-				(hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");
+			       hw->name, __func__,
+			       (hw->protocol == ISDN_P_NT_S0) ? "NT" : "TE");
 
 		if (hw->protocol == ISDN_P_NT_S0) {
 			ret = 0;
 			if (test_bit(FLG_ACTIVE, &dch->Flags)) {
 				_queue_data(&dch->dev.D,
-					PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-					NULL, GFP_ATOMIC);
+					    PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
+					    NULL, GFP_ATOMIC);
 			} else {
 				hfcsusb_ph_command(hw,
-					HFC_L1_ACTIVATE_NT);
+						   HFC_L1_ACTIVATE_NT);
 				test_and_set_bit(FLG_L2_ACTIVATED,
-					&dch->Flags);
+						 &dch->Flags);
 			}
 		} else {
 			hfcsusb_ph_command(hw, HFC_L1_ACTIVATE_TE);
@@ -341,7 +340,7 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
 	case PH_DEACTIVATE_REQ:
 		if (debug & DBG_HFC_CALL_TRACE)
 			printk(KERN_DEBUG "%s: %s: PH_DEACTIVATE_REQ\n",
-				hw->name, __func__);
+			       hw->name, __func__);
 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
 
 		if (hw->protocol == ISDN_P_NT_S0) {
@@ -386,7 +385,7 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		printk(KERN_DEBUG "%s: %s cmd 0x%x\n",
-			hw->name, __func__, cmd);
+		       hw->name, __func__, cmd);
 
 	switch (cmd) {
 	case INFO3_P8:
@@ -411,17 +410,17 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
 	case PH_ACTIVATE_IND:
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	case PH_DEACTIVATE_IND:
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: %s: unknown cmd %x\n",
-			hw->name, __func__, cmd);
+			       hw->name, __func__, cmd);
 		return -1;
 	}
 	hfcsusb_ph_info(hw);
@@ -430,14 +429,14 @@ hfc_l1callback(struct dchannel *dch, u_int cmd)
 
 static int
 open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
-    struct channel_req *rq)
+	      struct channel_req *rq)
 {
 	int err = 0;
 
 	if (debug & DEBUG_HW_OPEN)
 		printk(KERN_DEBUG "%s: %s: dev(%d) open addr(%i) from %p\n",
-		    hw->name, __func__, hw->dch.dev.id, rq->adr.channel,
-		    __builtin_return_address(0));
+		       hw->name, __func__, hw->dch.dev.id, rq->adr.channel,
+		       __builtin_return_address(0));
 	if (rq->protocol == ISDN_P_NONE)
 		return -EINVAL;
 
@@ -451,7 +450,7 @@ open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
 			hfcsusb_start_endpoint(hw, HFC_CHAN_E);
 			set_bit(FLG_ACTIVE, &hw->ech.Flags);
 			_queue_data(&hw->ech.dev.D, PH_ACTIVATE_IND,
-				     MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 		} else
 			return -EINVAL;
 	}
@@ -474,11 +473,11 @@ open_dchannel(struct hfcsusb *hw, struct mISDNchannel *ch,
 	if (((ch->protocol == ISDN_P_NT_S0) && (hw->dch.state == 3)) ||
 	    ((ch->protocol == ISDN_P_TE_S0) && (hw->dch.state == 7)))
 		_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-		    0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 	rq->ch = ch;
 	if (!try_module_get(THIS_MODULE))
 		printk(KERN_WARNING "%s: %s: cannot get module\n",
-		    hw->name, __func__);
+		       hw->name, __func__);
 	return 0;
 }
 
@@ -494,7 +493,7 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		printk(KERN_DEBUG "%s: %s B%i\n",
-			hw->name, __func__, rq->adr.channel);
+		       hw->name, __func__, rq->adr.channel);
 
 	bch = &hw->bch[rq->adr.channel - 1];
 	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
@@ -511,7 +510,7 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq)
 
 	if (!try_module_get(THIS_MODULE))
 		printk(KERN_WARNING "%s: %s:cannot get module\n",
-		    hw->name, __func__);
+		       hw->name, __func__);
 	return 0;
 }
 
@@ -522,16 +521,16 @@ channel_ctrl(struct hfcsusb *hw, struct mISDN_ctrl_req *cq)
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		printk(KERN_DEBUG "%s: %s op(0x%x) channel(0x%x)\n",
-		    hw->name, __func__, (cq->op), (cq->channel));
+		       hw->name, __func__, (cq->op), (cq->channel));
 
 	switch (cq->op) {
 	case MISDN_CTRL_GETOP:
 		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_CONNECT |
-			 MISDN_CTRL_DISCONNECT;
+			MISDN_CTRL_DISCONNECT;
 		break;
 	default:
 		printk(KERN_WARNING "%s: %s: unknown Op %x\n",
-			hw->name, __func__, cq->op);
+		       hw->name, __func__, cq->op);
 		ret = -EINVAL;
 		break;
 	}
@@ -552,7 +551,7 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 	if (dch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: %s: cmd:%x %p\n",
-		    hw->name, __func__, cmd, arg);
+		       hw->name, __func__, cmd, arg);
 	switch (cmd) {
 	case OPEN_CHANNEL:
 		rq = arg;
@@ -568,9 +567,9 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 		hw->open--;
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_DEBUG
-				"%s: %s: dev(%d) close from %p (open %d)\n",
-				hw->name, __func__, hw->dch.dev.id,
-				__builtin_return_address(0), hw->open);
+			       "%s: %s: dev(%d) close from %p (open %d)\n",
+			       hw->name, __func__, hw->dch.dev.id,
+			       __builtin_return_address(0), hw->open);
 		if (!hw->open) {
 			hfcsusb_stop_endpoint(hw, HFC_CHAN_D);
 			if (hw->fifos[HFCUSB_PCM_RX].pipe)
@@ -585,7 +584,7 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: %s: unknown command %x\n",
-				hw->name, __func__, cmd);
+			       hw->name, __func__, cmd);
 		return -EINVAL;
 	}
 	return err;
@@ -602,10 +601,10 @@ ph_state_te(struct dchannel *dch)
 	if (debug & DEBUG_HW) {
 		if (dch->state <= HFC_MAX_TE_LAYER1_STATE)
 			printk(KERN_DEBUG "%s: %s: %s\n", hw->name, __func__,
-			    HFC_TE_LAYER1_STATES[dch->state]);
+			       HFC_TE_LAYER1_STATES[dch->state]);
 		else
 			printk(KERN_DEBUG "%s: %s: TE F%d\n",
-			    hw->name, __func__, dch->state);
+			       hw->name, __func__, dch->state);
 	}
 
 	switch (dch->state) {
@@ -643,12 +642,12 @@ ph_state_nt(struct dchannel *dch)
 	if (debug & DEBUG_HW) {
 		if (dch->state <= HFC_MAX_NT_LAYER1_STATE)
 			printk(KERN_DEBUG "%s: %s: %s\n",
-			    hw->name, __func__,
-			    HFC_NT_LAYER1_STATES[dch->state]);
+			       hw->name, __func__,
+			       HFC_NT_LAYER1_STATES[dch->state]);
 
 		else
 			printk(KERN_INFO DRIVER_NAME "%s: %s: NT G%d\n",
-			    hw->name, __func__, dch->state);
+			       hw->name, __func__, dch->state);
 	}
 
 	switch (dch->state) {
@@ -677,7 +676,7 @@ ph_state_nt(struct dchannel *dch)
 		hw->timers &= ~NT_ACTIVATION_TIMER;
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, PH_ACTIVATE_IND,
-			MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+			    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 		handle_led(hw, LED_S0_ON);
 		break;
 	case (4):
@@ -712,8 +711,8 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol)
 
 	if (debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: %s: protocol %x-->%x B%d\n",
-		    hw->name, __func__, bch->state, protocol,
-		    bch->nr);
+		       hw->name, __func__, bch->state, protocol,
+		       bch->nr);
 
 	/* setup val for CON_HDLC */
 	conhdlc = 0;
@@ -743,7 +742,7 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol)
 	default:
 		if (debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: %s: prot not known %x\n",
-				hw->name, __func__, protocol);
+			       hw->name, __func__, protocol);
 		return -ENOPROTOOPT;
 	}
 
@@ -772,7 +771,7 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol)
 			handle_led(hw, (bch->nr == 1) ? LED_B1_ON : LED_B2_ON);
 		else
 			handle_led(hw, (bch->nr == 1) ? LED_B1_OFF :
-				LED_B2_OFF);
+				   LED_B2_OFF);
 	}
 	hfcsusb_ph_info(hw);
 	return 0;
@@ -783,7 +782,7 @@ hfcsusb_ph_command(struct hfcsusb *hw, u_char command)
 {
 	if (debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: %s: %x\n",
-		   hw->name, __func__, command);
+		       hw->name, __func__, command);
 
 	switch (command) {
 	case HFC_L1_ACTIVATE_TE:
@@ -801,15 +800,15 @@ hfcsusb_ph_command(struct hfcsusb *hw, u_char command)
 	case HFC_L1_ACTIVATE_NT:
 		if (hw->dch.state == 3)
 			_queue_data(&hw->dch.dev.D, PH_ACTIVATE_IND,
-				MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
+				    MISDN_ID_ANY, 0, NULL, GFP_ATOMIC);
 		else
 			write_reg(hw, HFCUSB_STATES, HFCUSB_ACTIVATE |
-				HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3);
+				  HFCUSB_DO_ACTION | HFCUSB_NT_G2_G3);
 		break;
 
 	case HFC_L1_DEACTIVATE_NT:
 		write_reg(hw, HFCUSB_STATES,
-			HFCUSB_DO_ACTION);
+			  HFCUSB_DO_ACTION);
 		break;
 	}
 }
@@ -830,7 +829,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 		test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
-				"off=%d)\n", __func__, bch->nr, !!cq->p1);
+			       "off=%d)\n", __func__, bch->nr, !!cq->p1);
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);
@@ -843,7 +842,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 /* collect data from incoming interrupt or isochron USB data */
 static void
 hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
-	int finish)
+		 int finish)
 {
 	struct hfcsusb	*hw = fifo->hw;
 	struct sk_buff	*rx_skb = NULL;
@@ -854,9 +853,9 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "
-		    "dch(%p) bch(%p) ech(%p)\n",
-		    hw->name, __func__, fifon, len,
-		    fifo->dch, fifo->bch, fifo->ech);
+		       "dch(%p) bch(%p) ech(%p)\n",
+		       hw->name, __func__, fifon, len,
+		       fifo->dch, fifo->bch, fifo->ech);
 
 	if (!len)
 		return;
@@ -896,7 +895,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 			skb_trim(rx_skb, 0);
 		} else {
 			printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
-			    hw->name, __func__);
+			       hw->name, __func__);
 			spin_unlock(&hw->lock);
 			return;
 		}
@@ -906,8 +905,8 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 		/* D/E-Channel SKB range check */
 		if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) {
 			printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
-			    "for fifo(%d) HFCUSB_D_RX\n",
-			    hw->name, __func__, fifon);
+			       "for fifo(%d) HFCUSB_D_RX\n",
+			       hw->name, __func__, fifon);
 			skb_trim(rx_skb, 0);
 			spin_unlock(&hw->lock);
 			return;
@@ -916,8 +915,8 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 		/* B-Channel SKB range check */
 		if ((rx_skb->len + len) >= (MAX_BCH_SIZE + 3)) {
 			printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
-			    "for fifo(%d) HFCUSB_B_RX\n",
-			    hw->name, __func__, fifon);
+			       "for fifo(%d) HFCUSB_B_RX\n",
+			       hw->name, __func__, fifon);
 			skb_trim(rx_skb, 0);
 			spin_unlock(&hw->lock);
 			return;
@@ -930,16 +929,16 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 		/* we have a complete hdlc packet */
 		if (finish) {
 			if ((rx_skb->len > 3) &&
-			   (!(rx_skb->data[rx_skb->len - 1]))) {
+			    (!(rx_skb->data[rx_skb->len - 1]))) {
 				if (debug & DBG_HFC_FIFO_VERBOSE) {
 					printk(KERN_DEBUG "%s: %s: fifon(%i)"
-					    " new RX len(%i): ",
-					    hw->name, __func__, fifon,
-					    rx_skb->len);
+					       " new RX len(%i): ",
+					       hw->name, __func__, fifon,
+					       rx_skb->len);
 					i = 0;
 					while (i < rx_skb->len)
 						printk("%02x ",
-						    rx_skb->data[i++]);
+						       rx_skb->data[i++]);
 					printk("\n");
 				}
 
@@ -952,17 +951,17 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
 					recv_Bchannel(fifo->bch, MISDN_ID_ANY);
 				if (fifo->ech)
 					recv_Echannel(fifo->ech,
-						     &hw->dch);
+						      &hw->dch);
 			} else {
 				if (debug & DBG_HFC_FIFO_VERBOSE) {
 					printk(KERN_DEBUG
-					    "%s: CRC or minlen ERROR fifon(%i) "
-					    "RX len(%i): ",
-					    hw->name, fifon, rx_skb->len);
+					       "%s: CRC or minlen ERROR fifon(%i) "
+					       "RX len(%i): ",
+					       hw->name, fifon, rx_skb->len);
 					i = 0;
 					while (i < rx_skb->len)
 						printk("%02x ",
-						    rx_skb->data[i++]);
+						       rx_skb->data[i++]);
 					printk("\n");
 				}
 				skb_trim(rx_skb, 0);
@@ -984,7 +983,7 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
 	int k;
 
 	usb_fill_bulk_urb(urb, dev, pipe, buf, packet_size * num_packets,
-	    complete, context);
+			  complete, context);
 
 	urb->number_of_packets = num_packets;
 	urb->transfer_flags = URB_ISO_ASAP;
@@ -1006,7 +1005,7 @@ rx_iso_complete(struct urb *urb)
 	struct usb_fifo *fifo = context_iso_urb->owner_fifo;
 	struct hfcsusb *hw = fifo->hw;
 	int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
-	    status, iso_status, i;
+		status, iso_status, i;
 	__u8 *buf;
 	static __u8 eof[8];
 	__u8 s0_state;
@@ -1030,8 +1029,8 @@ rx_iso_complete(struct urb *urb)
 	if (status == -EXDEV) {
 		if (debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: %s: with -EXDEV "
-			    "urb->status %d, fifonum %d\n",
-			    hw->name, __func__,  status, fifon);
+			       "urb->status %d, fifonum %d\n",
+			       hw->name, __func__,  status, fifon);
 
 		/* clear status, so go on with ISO transfers */
 		status = 0;
@@ -1050,18 +1049,18 @@ rx_iso_complete(struct urb *urb)
 
 			if (iso_status && (debug & DBG_HFC_FIFO_VERBOSE)) {
 				printk(KERN_DEBUG "%s: %s: "
-				    "ISO packet %i, status: %i\n",
-				    hw->name, __func__, k, iso_status);
+				       "ISO packet %i, status: %i\n",
+				       hw->name, __func__, k, iso_status);
 			}
 
 			/* USB data log for every D ISO in */
 			if ((fifon == HFCUSB_D_RX) &&
 			    (debug & DBG_HFC_USB_VERBOSE)) {
 				printk(KERN_DEBUG
-				    "%s: %s: %d (%d/%d) len(%d) ",
-				    hw->name, __func__, urb->start_frame,
-				    k, num_isoc_packets-1,
-				    len);
+				       "%s: %s: %d (%d/%d) len(%d) ",
+				       hw->name, __func__, urb->start_frame,
+				       k, num_isoc_packets - 1,
+				       len);
 				for (i = 0; i < len; i++)
 					printk("%x ", buf[i]);
 				printk("\n");
@@ -1082,12 +1081,12 @@ rx_iso_complete(struct urb *urb)
 					eof[fifon] = buf[0] & 1;
 					if (len > 2)
 						hfcsusb_rx_frame(fifo, buf + 2,
-							len - 2, (len < maxlen)
-							? eof[fifon] : 0);
+								 len - 2, (len < maxlen)
+								 ? eof[fifon] : 0);
 				} else
 					hfcsusb_rx_frame(fifo, buf, len,
-						(len < maxlen) ?
-						eof[fifon] : 0);
+							 (len < maxlen) ?
+							 eof[fifon] : 0);
 				fifo->last_urblen = len;
 			}
 		}
@@ -1107,14 +1106,14 @@ rx_iso_complete(struct urb *urb)
 		if (errcode < 0) {
 			if (debug & DEBUG_HW)
 				printk(KERN_DEBUG "%s: %s: error submitting "
-				    "ISO URB: %d\n",
-				    hw->name, __func__, errcode);
+				       "ISO URB: %d\n",
+				       hw->name, __func__, errcode);
 		}
 	} else {
 		if (status && (debug & DBG_HFC_URB_INFO))
 			printk(KERN_DEBUG "%s: %s: rx_iso_complete : "
-			    "urb->status %d, fifonum %d\n",
-			    hw->name, __func__, status, fifon);
+			       "urb->status %d, fifonum %d\n",
+			       hw->name, __func__, status, fifon);
 	}
 }
 
@@ -1141,8 +1140,8 @@ rx_int_complete(struct urb *urb)
 	if ((!fifo->active) || (urb->status)) {
 		if (debug & DBG_HFC_URB_ERROR)
 			printk(KERN_DEBUG
-			    "%s: %s: RX-Fifo %i is going down (%i)\n",
-			    hw->name, __func__, fifon, urb->status);
+			       "%s: %s: RX-Fifo %i is going down (%i)\n",
+			       hw->name, __func__, fifon, urb->status);
 
 		fifo->urb->interval = 0; /* cancel automatic rescheduling */
 		return;
@@ -1154,7 +1153,7 @@ rx_int_complete(struct urb *urb)
 	/* USB data log for every D INT in */
 	if ((fifon == HFCUSB_D_RX) && (debug & DBG_HFC_USB_VERBOSE)) {
 		printk(KERN_DEBUG "%s: %s: D RX INT len(%d) ",
-		    hw->name, __func__, len);
+		       hw->name, __func__, len);
 		for (i = 0; i < len; i++)
 			printk("%02x ", buf[i]);
 		printk("\n");
@@ -1174,8 +1173,8 @@ rx_int_complete(struct urb *urb)
 		/* if we have more than the 2 status bytes -> collect data */
 		if (len > 2)
 			hfcsusb_rx_frame(fifo, buf + 2,
-			   urb->actual_length - 2,
-			   (len < maxlen) ? eof[fifon] : 0);
+					 urb->actual_length - 2,
+					 (len < maxlen) ? eof[fifon] : 0);
 	} else {
 		hfcsusb_rx_frame(fifo, buf, urb->actual_length,
 				 (len < maxlen) ? eof[fifon] : 0);
@@ -1186,7 +1185,7 @@ rx_int_complete(struct urb *urb)
 	if (status) {
 		if (debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: %s: error resubmitting USB\n",
-			    hw->name, __func__);
+			       hw->name, __func__);
 	}
 }
 
@@ -1199,7 +1198,7 @@ tx_iso_complete(struct urb *urb)
 	struct hfcsusb *hw = fifo->hw;
 	struct sk_buff *tx_skb;
 	int k, tx_offset, num_isoc_packets, sink, remain, current_len,
-	    errcode, hdlc, i;
+		errcode, hdlc, i;
 	int *tx_idx;
 	int frame_complete, fifon, status;
 	__u8 threshbit;
@@ -1222,7 +1221,7 @@ tx_iso_complete(struct urb *urb)
 		hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
 	} else {
 		printk(KERN_DEBUG "%s: %s: neither BCH nor DCH\n",
-		    hw->name, __func__);
+		       hw->name, __func__);
 		spin_unlock(&hw->lock);
 		return;
 	}
@@ -1239,8 +1238,8 @@ tx_iso_complete(struct urb *urb)
 	if (status == -EXDEV) {
 		if (debug & DBG_HFC_URB_ERROR)
 			printk(KERN_DEBUG "%s: %s: "
-			    "-EXDEV (%i) fifon (%d)\n",
-			    hw->name, __func__, status, fifon);
+			       "-EXDEV (%i) fifon (%d)\n",
+			       hw->name, __func__, status, fifon);
 
 		/* clear status, so go on with ISO transfers */
 		status = 0;
@@ -1270,8 +1269,8 @@ tx_iso_complete(struct urb *urb)
 				errcode = urb->iso_frame_desc[k].status;
 				if (errcode) {
 					printk(KERN_DEBUG "%s: %s: "
-					    "ISO packet %i, status: %i\n",
-					     hw->name, __func__, k, errcode);
+					       "ISO packet %i, status: %i\n",
+					       hw->name, __func__, k, errcode);
 				}
 			}
 
@@ -1299,7 +1298,7 @@ tx_iso_complete(struct urb *urb)
 					if (hdlc) {
 						/* signal frame completion */
 						context_iso_urb->
-						    buffer[tx_offset] = 1;
+							buffer[tx_offset] = 1;
 						/* add 2 byte flags and 16bit
 						 * CRC at end of ISDN frame */
 						fifo->bit_line += 32;
@@ -1319,21 +1318,21 @@ tx_iso_complete(struct urb *urb)
 				if ((fifon == HFCUSB_D_RX) &&
 				    (debug & DBG_HFC_USB_VERBOSE)) {
 					printk(KERN_DEBUG
-					    "%s: %s (%d/%d) offs(%d) len(%d) ",
-					    hw->name, __func__,
-					    k, num_isoc_packets-1,
-					    urb->iso_frame_desc[k].offset,
-					    urb->iso_frame_desc[k].length);
+					       "%s: %s (%d/%d) offs(%d) len(%d) ",
+					       hw->name, __func__,
+					       k, num_isoc_packets - 1,
+					       urb->iso_frame_desc[k].offset,
+					       urb->iso_frame_desc[k].length);
 
 					for (i = urb->iso_frame_desc[k].offset;
 					     i < (urb->iso_frame_desc[k].offset
-					     + urb->iso_frame_desc[k].length);
+						  + urb->iso_frame_desc[k].length);
 					     i++)
 						printk("%x ",
-						    context_iso_urb->buffer[i]);
+						       context_iso_urb->buffer[i]);
 
 					printk(" skb->len(%i) tx-idx(%d)\n",
-					    tx_skb->len, *tx_idx);
+					       tx_skb->len, *tx_idx);
 				}
 
 				tx_offset += (current_len + 1);
@@ -1351,13 +1350,13 @@ tx_iso_complete(struct urb *urb)
 
 				if (debug & DBG_HFC_FIFO_VERBOSE) {
 					printk(KERN_DEBUG  "%s: %s: "
-					    "fifon(%i) new TX len(%i): ",
-					    hw->name, __func__,
-					    fifon, tx_skb->len);
+					       "fifon(%i) new TX len(%i): ",
+					       hw->name, __func__,
+					       fifon, tx_skb->len);
 					i = 0;
 					while (i < tx_skb->len)
 						printk("%02x ",
-						    tx_skb->data[i++]);
+						       tx_skb->data[i++]);
 					printk("\n");
 				}
 
@@ -1366,9 +1365,9 @@ tx_iso_complete(struct urb *urb)
 				if (fifo->dch && get_next_dframe(fifo->dch))
 					tx_skb = fifo->dch->tx_skb;
 				else if (fifo->bch &&
-				    get_next_bframe(fifo->bch)) {
+					 get_next_bframe(fifo->bch)) {
 					if (test_bit(FLG_TRANSPARENT,
-					    &fifo->bch->Flags))
+						     &fifo->bch->Flags))
 						confirm_Bsend(fifo->bch);
 					tx_skb = fifo->bch->tx_skb;
 				}
@@ -1378,8 +1377,8 @@ tx_iso_complete(struct urb *urb)
 		if (errcode < 0) {
 			if (debug & DEBUG_HW)
 				printk(KERN_DEBUG
-				    "%s: %s: error submitting ISO URB: %d \n",
-				    hw->name, __func__, errcode);
+				       "%s: %s: error submitting ISO URB: %d \n",
+				       hw->name, __func__, errcode);
 		}
 
 		/*
@@ -1396,9 +1395,9 @@ tx_iso_complete(struct urb *urb)
 	} else {
 		if (status && (debug & DBG_HFC_URB_ERROR))
 			printk(KERN_DEBUG  "%s: %s: urb->status %s (%i)"
-			    "fifonum=%d\n",
-			    hw->name, __func__,
-			    symbolic(urb_errlist, status), status, fifon);
+			       "fifonum=%d\n",
+			       hw->name, __func__,
+			       symbolic(urb_errlist, status), status, fifon);
 	}
 	spin_unlock(&hw->lock);
 }
@@ -1416,17 +1415,17 @@ start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,
 
 	if (debug)
 		printk(KERN_DEBUG "%s: %s: fifo %i\n",
-		    hw->name, __func__, fifo->fifonum);
+		       hw->name, __func__, fifo->fifonum);
 
 	/* allocate Memory for Iso out Urbs */
 	for (i = 0; i < 2; i++) {
 		if (!(fifo->iso[i].urb)) {
 			fifo->iso[i].urb =
-			    usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
+				usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
 			if (!(fifo->iso[i].urb)) {
 				printk(KERN_DEBUG
-				    "%s: %s: alloc urb for fifo %i failed",
-				    hw->name, __func__, fifo->fifonum);
+				       "%s: %s: alloc urb for fifo %i failed",
+				       hw->name, __func__, fifo->fifonum);
 			}
 			fifo->iso[i].owner_fifo = (struct usb_fifo *) fifo;
 			fifo->iso[i].indx = i;
@@ -1436,27 +1435,27 @@ start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,
 			    (fifo->usb_packet_maxlen *
 			     num_packets_per_urb)) {
 				fill_isoc_urb(fifo->iso[i].urb,
-				    fifo->hw->dev, fifo->pipe,
-				    fifo->iso[i].buffer,
-				    num_packets_per_urb,
-				    fifo->usb_packet_maxlen,
-				    fifo->intervall, complete,
-				    &fifo->iso[i]);
+					      fifo->hw->dev, fifo->pipe,
+					      fifo->iso[i].buffer,
+					      num_packets_per_urb,
+					      fifo->usb_packet_maxlen,
+					      fifo->intervall, complete,
+					      &fifo->iso[i]);
 				memset(fifo->iso[i].buffer, 0,
 				       sizeof(fifo->iso[i].buffer));
 
 				for (k = 0; k < num_packets_per_urb; k++) {
 					fifo->iso[i].urb->
-					    iso_frame_desc[k].offset =
-					    k * packet_size;
+						iso_frame_desc[k].offset =
+						k * packet_size;
 					fifo->iso[i].urb->
-					    iso_frame_desc[k].length =
-					    packet_size;
+						iso_frame_desc[k].length =
+						packet_size;
 				}
 			} else {
 				printk(KERN_DEBUG
-				    "%s: %s: ISO Buffer size to small!\n",
-				    hw->name, __func__);
+				       "%s: %s: ISO Buffer size to small!\n",
+				       hw->name, __func__);
 			}
 		}
 		fifo->bit_line = BITLINE_INF;
@@ -1466,8 +1465,8 @@ start_isoc_chain(struct usb_fifo *fifo, int num_packets_per_urb,
 		fifo->stop_gracefull = 0;
 		if (errcode < 0) {
 			printk(KERN_DEBUG "%s: %s: %s URB nr:%d\n",
-			    hw->name, __func__,
-			    symbolic(urb_errlist, errcode), i);
+			       hw->name, __func__,
+			       symbolic(urb_errlist, errcode), i);
 		}
 	}
 	return fifo->active;
@@ -1492,10 +1491,10 @@ stop_iso_gracefull(struct usb_fifo *fifo)
 	for (i = 0; i < 2; i++) {
 		timeout = 3;
 		while (fifo->stop_gracefull && timeout--)
-			schedule_timeout_interruptible((HZ/1000)*16);
+			schedule_timeout_interruptible((HZ / 1000) * 16);
 		if (debug && fifo->stop_gracefull)
 			printk(KERN_DEBUG "%s: ERROR %s for fifo %i.%i\n",
-				hw->name, __func__, fifo->fifonum, i);
+			       hw->name, __func__, fifo->fifonum, i);
 	}
 }
 
@@ -1515,7 +1514,7 @@ stop_int_gracefull(struct usb_fifo *fifo)
 
 	timeout = 3;
 	while (fifo->stop_gracefull && timeout--)
-		schedule_timeout_interruptible((HZ/1000)*3);
+		schedule_timeout_interruptible((HZ / 1000) * 3);
 	if (debug && fifo->stop_gracefull)
 		printk(KERN_DEBUG "%s: ERROR %s for fifo %i\n",
 		       hw->name, __func__, fifo->fifonum);
@@ -1530,7 +1529,7 @@ start_int_fifo(struct usb_fifo *fifo)
 
 	if (debug)
 		printk(KERN_DEBUG "%s: %s: INT IN fifo:%d\n",
-		    hw->name, __func__, fifo->fifonum);
+		       hw->name, __func__, fifo->fifonum);
 
 	if (!fifo->urb) {
 		fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -1538,14 +1537,14 @@ start_int_fifo(struct usb_fifo *fifo)
 			return;
 	}
 	usb_fill_int_urb(fifo->urb, fifo->hw->dev, fifo->pipe,
-	    fifo->buffer, fifo->usb_packet_maxlen,
-	    (usb_complete_t)rx_int_complete, fifo, fifo->intervall);
+			 fifo->buffer, fifo->usb_packet_maxlen,
+			 (usb_complete_t)rx_int_complete, fifo, fifo->intervall);
 	fifo->active = 1;
 	fifo->stop_gracefull = 0;
 	errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
 	if (errcode) {
 		printk(KERN_DEBUG "%s: %s: submit URB: status:%i\n",
-		    hw->name, __func__, errcode);
+		       hw->name, __func__, errcode);
 		fifo->active = 0;
 	}
 }
@@ -1555,7 +1554,7 @@ setPortMode(struct hfcsusb *hw)
 {
 	if (debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: %s %s\n", hw->name, __func__,
-		   (hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT");
+		       (hw->protocol == ISDN_P_TE_S0) ? "TE" : "NT");
 
 	if (hw->protocol == ISDN_P_TE_S0) {
 		write_reg(hw, HFCUSB_SCTRL, 0x40);
@@ -1589,7 +1588,7 @@ reset_hfcsusb(struct hfcsusb *hw)
 
 	/* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */
 	write_reg(hw, HFCUSB_USB_SIZE, (hw->packet_size / 8) |
-	    ((hw->packet_size / 8) << 4));
+		  ((hw->packet_size / 8) << 4));
 
 	/* set USB_SIZE_I to match the the wMaxPacketSize for ISO transfers */
 	write_reg(hw, HFCUSB_USB_SIZE_I, hw->iso_packet_size);
@@ -1600,13 +1599,13 @@ reset_hfcsusb(struct hfcsusb *hw)
 
 	/* init the fifos */
 	write_reg(hw, HFCUSB_F_THRES,
-	    (HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));
+		  (HFCUSB_TX_THRESHOLD / 8) | ((HFCUSB_RX_THRESHOLD / 8) << 4));
 
 	fifo = hw->fifos;
 	for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
 		write_reg(hw, HFCUSB_FIFO, i);	/* select the desired fifo */
 		fifo[i].max_size =
-		    (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
+			(i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
 		fifo[i].last_urblen = 0;
 
 		/* set 2 bit for D- & E-channel */
@@ -1615,7 +1614,7 @@ reset_hfcsusb(struct hfcsusb *hw)
 		/* enable all fifos */
 		if (i == HFCUSB_D_TX)
 			write_reg(hw, HFCUSB_CON_HDLC,
-			    (hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09);
+				  (hw->protocol == ISDN_P_NT_S0) ? 0x08 : 0x09);
 		else
 			write_reg(hw, HFCUSB_CON_HDLC, 0x08);
 		write_reg(hw, HFCUSB_INC_RES_F, 2); /* reset the fifo */
@@ -1641,34 +1640,34 @@ hfcsusb_start_endpoint(struct hfcsusb *hw, int channel)
 
 	/* start rx endpoints using USB INT IN method */
 	if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
-		start_int_fifo(hw->fifos + channel*2 + 1);
+		start_int_fifo(hw->fifos + channel * 2 + 1);
 
 	/* start rx endpoints using USB ISO IN method */
 	if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO) {
 		switch (channel) {
 		case HFC_CHAN_D:
 			start_isoc_chain(hw->fifos + HFCUSB_D_RX,
-				ISOC_PACKETS_D,
-				(usb_complete_t)rx_iso_complete,
-				16);
+					 ISOC_PACKETS_D,
+					 (usb_complete_t)rx_iso_complete,
+					 16);
 			break;
 		case HFC_CHAN_E:
 			start_isoc_chain(hw->fifos + HFCUSB_PCM_RX,
-				ISOC_PACKETS_D,
-				(usb_complete_t)rx_iso_complete,
-				16);
+					 ISOC_PACKETS_D,
+					 (usb_complete_t)rx_iso_complete,
+					 16);
 			break;
 		case HFC_CHAN_B1:
 			start_isoc_chain(hw->fifos + HFCUSB_B1_RX,
-				ISOC_PACKETS_B,
-				(usb_complete_t)rx_iso_complete,
-				16);
+					 ISOC_PACKETS_B,
+					 (usb_complete_t)rx_iso_complete,
+					 16);
 			break;
 		case HFC_CHAN_B2:
 			start_isoc_chain(hw->fifos + HFCUSB_B2_RX,
-				ISOC_PACKETS_B,
-				(usb_complete_t)rx_iso_complete,
-				16);
+					 ISOC_PACKETS_B,
+					 (usb_complete_t)rx_iso_complete,
+					 16);
 			break;
 		}
 	}
@@ -1677,18 +1676,18 @@ hfcsusb_start_endpoint(struct hfcsusb *hw, int channel)
 	switch (channel) {
 	case HFC_CHAN_D:
 		start_isoc_chain(hw->fifos + HFCUSB_D_TX,
-			ISOC_PACKETS_B,
-			(usb_complete_t)tx_iso_complete, 1);
+				 ISOC_PACKETS_B,
+				 (usb_complete_t)tx_iso_complete, 1);
 		break;
 	case HFC_CHAN_B1:
 		start_isoc_chain(hw->fifos + HFCUSB_B1_TX,
-			ISOC_PACKETS_D,
-			(usb_complete_t)tx_iso_complete, 1);
+				 ISOC_PACKETS_D,
+				 (usb_complete_t)tx_iso_complete, 1);
 		break;
 	case HFC_CHAN_B2:
 		start_isoc_chain(hw->fifos + HFCUSB_B2_TX,
-			ISOC_PACKETS_B,
-			(usb_complete_t)tx_iso_complete, 1);
+				 ISOC_PACKETS_B,
+				 (usb_complete_t)tx_iso_complete, 1);
 		break;
 	}
 }
@@ -1709,15 +1708,15 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
 
 	/* rx endpoints using USB INT IN method */
 	if (hw->cfg_used == CNF_3INT3ISO || hw->cfg_used == CNF_4INT3ISO)
-		stop_int_gracefull(hw->fifos + channel*2 + 1);
+		stop_int_gracefull(hw->fifos + channel * 2 + 1);
 
 	/* rx endpoints using USB ISO IN method */
 	if (hw->cfg_used == CNF_3ISO3ISO || hw->cfg_used == CNF_4ISO3ISO)
-		stop_iso_gracefull(hw->fifos + channel*2 + 1);
+		stop_iso_gracefull(hw->fifos + channel * 2 + 1);
 
 	/* tx endpoints using USB ISO OUT method */
 	if (channel != HFC_CHAN_E)
-		stop_iso_gracefull(hw->fifos + channel*2);
+		stop_iso_gracefull(hw->fifos + channel * 2);
 }
 
 
@@ -1733,12 +1732,12 @@ setup_hfcsusb(struct hfcsusb *hw)
 	/* check the chip id */
 	if (read_reg_atomic(hw, HFCUSB_CHIP_ID, &b) != 1) {
 		printk(KERN_DEBUG "%s: %s: cannot read chip id\n",
-		    hw->name, __func__);
+		       hw->name, __func__);
 		return 1;
 	}
 	if (b != HFCUSB_CHIPID) {
 		printk(KERN_DEBUG "%s: %s: Invalid chip id 0x%02x\n",
-		    hw->name, __func__, b);
+		       hw->name, __func__, b);
 		return 1;
 	}
 
@@ -1755,8 +1754,8 @@ setup_hfcsusb(struct hfcsusb *hw)
 	hw->ctrl_write.bRequest = 0;
 	hw->ctrl_write.wLength = 0;
 	usb_fill_control_urb(hw->ctrl_urb, hw->dev, hw->ctrl_out_pipe,
-	    (u_char *)&hw->ctrl_write, NULL, 0,
-	    (usb_complete_t)ctrl_complete, hw);
+			     (u_char *)&hw->ctrl_write, NULL, 0,
+			     (usb_complete_t)ctrl_complete, hw);
 
 	reset_hfcsusb(hw);
 	return 0;
@@ -1807,7 +1806,7 @@ deactivate_bchannel(struct bchannel *bch)
 
 	if (bch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: %s: bch->nr(%i)\n",
-		    hw->name, __func__, bch->nr);
+		       hw->name, __func__, bch->nr);
 
 	spin_lock_irqsave(&hw->lock, flags);
 	mISDN_clear_bchannel(bch);
@@ -1849,7 +1848,7 @@ hfc_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-			__func__, cmd);
+		       __func__, cmd);
 	}
 	return ret;
 }
@@ -1878,7 +1877,7 @@ setup_instance(struct hfcsusb *hw, struct device *parent)
 		mISDN_initdchannel(&hw->ech, MAX_DFRAME_LEN_L1, NULL);
 
 	hw->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	hw->dch.dev.nrbchan = 2;
 	for (i = 0; i < 2; i++) {
 		hw->bch[i].nr = i + 1;
@@ -1906,9 +1905,9 @@ setup_instance(struct hfcsusb *hw, struct device *parent)
 		goto out;
 
 	snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s.%d", DRIVER_NAME,
-	    hfcsusb_cnt + 1);
+		 hfcsusb_cnt + 1);
 	printk(KERN_INFO "%s: registered as '%s'\n",
-	    DRIVER_NAME, hw->name);
+	       DRIVER_NAME, hw->name);
 
 	err = mISDN_register_device(&hw->dch.dev, parent, hw->name);
 	if (err)
@@ -1938,30 +1937,30 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	struct usb_host_endpoint	*ep;
 	struct hfcsusb_vdata		*driver_info;
 	int ifnum = iface->desc.bInterfaceNumber, i, idx, alt_idx,
-	    probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found,
-	    ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size,
-	    alt_used = 0;
+		probe_alt_setting, vend_idx, cfg_used, *vcf, attr, cfg_found,
+		ep_addr, cmptbl[16], small_match, iso_packet_size, packet_size,
+		alt_used = 0;
 
 	vend_idx = 0xffff;
 	for (i = 0; hfcsusb_idtab[i].idVendor; i++) {
 		if ((le16_to_cpu(dev->descriptor.idVendor)
-		       == hfcsusb_idtab[i].idVendor) &&
+		     == hfcsusb_idtab[i].idVendor) &&
 		    (le16_to_cpu(dev->descriptor.idProduct)
-		       == hfcsusb_idtab[i].idProduct)) {
+		     == hfcsusb_idtab[i].idProduct)) {
 			vend_idx = i;
 			continue;
 		}
 	}
 
 	printk(KERN_DEBUG
-	    "%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n",
-	    __func__, ifnum, iface->desc.bAlternateSetting,
-	    intf->minor, vend_idx);
+	       "%s: interface(%d) actalt(%d) minor(%d) vend_idx(%d)\n",
+	       __func__, ifnum, iface->desc.bAlternateSetting,
+	       intf->minor, vend_idx);
 
 	if (vend_idx == 0xffff) {
 		printk(KERN_WARNING
-		    "%s: no valid vendor found in USB descriptor\n",
-		    __func__);
+		       "%s: no valid vendor found in USB descriptor\n",
+		       __func__);
 		return -EIO;
 	}
 	/* if vendor and product ID is OK, start probing alternate settings */
@@ -1997,17 +1996,17 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 					if (cmptbl[idx] == EP_NUL)
 						cfg_found = 0;
 					if (attr == USB_ENDPOINT_XFER_INT
-						&& cmptbl[idx] == EP_INT)
+					    && cmptbl[idx] == EP_INT)
 						cmptbl[idx] = EP_NUL;
 					if (attr == USB_ENDPOINT_XFER_BULK
-						&& cmptbl[idx] == EP_BLK)
+					    && cmptbl[idx] == EP_BLK)
 						cmptbl[idx] = EP_NUL;
 					if (attr == USB_ENDPOINT_XFER_ISOC
-						&& cmptbl[idx] == EP_ISO)
+					    && cmptbl[idx] == EP_ISO)
 						cmptbl[idx] = EP_NUL;
 
 					if (attr == USB_ENDPOINT_XFER_INT &&
-						ep->desc.bInterval < vcf[17]) {
+					    ep->desc.bInterval < vcf[17]) {
 						cfg_found = 0;
 					}
 				}
@@ -2061,27 +2060,27 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 		switch (ep->desc.bmAttributes) {
 		case USB_ENDPOINT_XFER_INT:
 			f->pipe = usb_rcvintpipe(dev,
-				ep->desc.bEndpointAddress);
+						 ep->desc.bEndpointAddress);
 			f->usb_transfer_mode = USB_INT;
 			packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
 			break;
 		case USB_ENDPOINT_XFER_BULK:
 			if (ep_addr & 0x80)
 				f->pipe = usb_rcvbulkpipe(dev,
-					ep->desc.bEndpointAddress);
+							  ep->desc.bEndpointAddress);
 			else
 				f->pipe = usb_sndbulkpipe(dev,
-					ep->desc.bEndpointAddress);
+							  ep->desc.bEndpointAddress);
 			f->usb_transfer_mode = USB_BULK;
 			packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
 			break;
 		case USB_ENDPOINT_XFER_ISOC:
 			if (ep_addr & 0x80)
 				f->pipe = usb_rcvisocpipe(dev,
-					ep->desc.bEndpointAddress);
+							  ep->desc.bEndpointAddress);
 			else
 				f->pipe = usb_sndisocpipe(dev,
-					ep->desc.bEndpointAddress);
+							  ep->desc.bEndpointAddress);
 			f->usb_transfer_mode = USB_ISOC;
 			iso_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
 			break;
@@ -2093,7 +2092,7 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 			f->fifonum = idx & 7;
 			f->hw = hw;
 			f->usb_packet_maxlen =
-			    le16_to_cpu(ep->desc.wMaxPacketSize);
+				le16_to_cpu(ep->desc.wMaxPacketSize);
 			f->intervall = ep->desc.bInterval;
 		}
 		ep++;
@@ -2115,8 +2114,8 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	driver_info =
 		(struct hfcsusb_vdata *)hfcsusb_idtab[vend_idx].driver_info;
 	printk(KERN_DEBUG "%s: %s: detected \"%s\" (%s, if=%d alt=%d)\n",
-	    hw->name, __func__, driver_info->vend_name,
-	    conf_str[small_match], ifnum, alt_used);
+	       hw->name, __func__, driver_info->vend_name,
+	       conf_str[small_match], ifnum, alt_used);
 
 	if (setup_instance(hw, dev->dev.parent))
 		return -EIO;
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
index 369196a..cb1231b 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.h
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.h
@@ -36,10 +36,10 @@
 #define NT_ACTIVATION_TIMER	0x01	/* enables NT mode activation Timer */
 #define NT_T1_COUNT		10
 
-#define MAX_BCH_SIZE 		2048	/* allowed B-channel packet size */
+#define MAX_BCH_SIZE		2048	/* allowed B-channel packet size */
 
-#define HFCUSB_RX_THRESHOLD 	64	/* threshold for fifo report bit rx */
-#define HFCUSB_TX_THRESHOLD 	96	/* threshold for fifo report bit tx */
+#define HFCUSB_RX_THRESHOLD	64	/* threshold for fifo report bit rx */
+#define HFCUSB_TX_THRESHOLD	96	/* threshold for fifo report bit tx */
 
 #define HFCUSB_CHIP_ID		0x16	/* Chip ID register index */
 #define HFCUSB_CIRM		0x00	/* cirm register index */
@@ -90,8 +90,8 @@
 
 /* defines how much ISO packets are handled in one URB */
 static int iso_packets[8] =
-    { ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
-	ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
+{ ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
+  ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
 };
 
 
@@ -100,15 +100,15 @@ static int iso_packets[8] =
 #define SINK_MIN	48
 #define SINK_DMIN	12
 #define SINK_DMAX	18
-#define BITLINE_INF	(-96*8)
+#define BITLINE_INF	(-96 * 8)
 
 /* HFC-S USB register access by Control-URSs */
-#define write_reg_atomic(a, b, c) \
+#define write_reg_atomic(a, b, c)					\
 	usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), \
-		0, 0, HFC_CTRL_TIMEOUT)
-#define read_reg_atomic(a, b, c) \
+			0, 0, HFC_CTRL_TIMEOUT)
+#define read_reg_atomic(a, b, c)					\
 	usb_control_msg((a)->dev, (a)->ctrl_in_pipe, 1, 0xC0, 0, (b), (c), \
-		1, HFC_CTRL_TIMEOUT)
+			1, HFC_CTRL_TIMEOUT)
 #define HFC_CTRL_BUFSIZE 64
 
 struct ctrl_buf {
@@ -222,7 +222,7 @@ static char *conf_str[] = {
 #define LED_B2_DATA	10
 
 #define LED_NORMAL	0	/* LEDs are normal */
-#define LED_INVERTED 	1	/* LEDs are inverted */
+#define LED_INVERTED	1	/* LEDs are inverted */
 
 /* time in ms to perform a Flashing LED when B-Channel has traffic */
 #define LED_TIME      250
@@ -258,7 +258,7 @@ struct usb_fifo {
 
 	__u8 usb_transfer_mode; /* switched between ISO and INT */
 	struct iso_urb	iso[2]; /* two urbs to have one always
-					 one pending */
+				   one pending */
 
 	struct dchannel *dch;	/* link to hfcsusb_t->dch */
 	struct bchannel *bch;	/* link to hfcsusb_t->bch */
@@ -339,76 +339,76 @@ static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
 /* supported devices */
 static struct usb_device_id hfcsusb_idtab[] = {
 	{
-	 USB_DEVICE(0x0959, 0x2bd0),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_OFF, {4, 0, 2, 1},
-			   "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
+		USB_DEVICE(0x0959, 0x2bd0),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_OFF, {4, 0, 2, 1},
+					"ISDN USB TA (Cologne Chip HFC-S USB based)"}),
 	},
 	{
-	 USB_DEVICE(0x0675, 0x1688),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {1, 2, 0, 0},
-			   "DrayTek miniVigor 128 USB ISDN TA"}),
+		USB_DEVICE(0x0675, 0x1688),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {1, 2, 0, 0},
+					"DrayTek miniVigor 128 USB ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x07b0, 0x0007),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Billion tiny USB ISDN TA 128"}),
+		USB_DEVICE(0x07b0, 0x0007),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Billion tiny USB ISDN TA 128"}),
 	},
 	{
-	 USB_DEVICE(0x0742, 0x2008),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {4, 0, 2, 1},
-			   "Stollmann USB TA"}),
+		USB_DEVICE(0x0742, 0x2008),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {4, 0, 2, 1},
+					"Stollmann USB TA"}),
 	},
 	{
-	 USB_DEVICE(0x0742, 0x2009),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {4, 0, 2, 1},
-			   "Aceex USB ISDN TA"}),
+		USB_DEVICE(0x0742, 0x2009),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {4, 0, 2, 1},
+					"Aceex USB ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x0742, 0x200A),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {4, 0, 2, 1},
-			   "OEM USB ISDN TA"}),
+		USB_DEVICE(0x0742, 0x200A),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {4, 0, 2, 1},
+					"OEM USB ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x08e3, 0x0301),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {2, 0, 1, 4},
-			   "Olitec USB RNIS"}),
+		USB_DEVICE(0x08e3, 0x0301),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {2, 0, 1, 4},
+					"Olitec USB RNIS"}),
 	},
 	{
-	 USB_DEVICE(0x07fa, 0x0846),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Bewan Modem RNIS USB"}),
+		USB_DEVICE(0x07fa, 0x0846),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Bewan Modem RNIS USB"}),
 	},
 	{
-	 USB_DEVICE(0x07fa, 0x0847),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Djinn Numeris USB"}),
+		USB_DEVICE(0x07fa, 0x0847),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Djinn Numeris USB"}),
 	},
 	{
-	 USB_DEVICE(0x07b0, 0x0006),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Twister ISDN TA"}),
+		USB_DEVICE(0x07b0, 0x0006),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Twister ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x071d, 0x1005),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {0x02, 0, 0x01, 0x04},
-			   "Eicon DIVA USB 4.0"}),
+		USB_DEVICE(0x071d, 0x1005),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {0x02, 0, 0x01, 0x04},
+					"Eicon DIVA USB 4.0"}),
 	},
 	{
-	 USB_DEVICE(0x0586, 0x0102),
-	 .driver_info = (unsigned long) &((struct hfcsusb_vdata)
-			  {LED_SCHEME1, {0x88, -64, -32, -16},
-			   "ZyXEL OMNI.NET USB II"}),
+		USB_DEVICE(0x0586, 0x0102),
+		.driver_info = (unsigned long) &((struct hfcsusb_vdata)
+			{LED_SCHEME1, {0x88, -64, -32, -16},
+					"ZyXEL OMNI.NET USB II"}),
 	},
 	{ }
 };
diff --git a/drivers/isdn/hardware/mISDN/iohelper.h b/drivers/isdn/hardware/mISDN/iohelper.h
index b438981..c3e7bb1 100644
--- a/drivers/isdn/hardware/mISDN/iohelper.h
+++ b/drivers/isdn/hardware/mISDN/iohelper.h
@@ -27,83 +27,83 @@
 #define _IOHELPER_H
 
 typedef	u8	(read_reg_func)(void *hwp, u8 offset);
-typedef	void	(write_reg_func)(void *hwp, u8 offset, u8 value);
-typedef	void	(fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
+			       typedef	void	(write_reg_func)(void *hwp, u8 offset, u8 value);
+			       typedef	void	(fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
 
-struct _ioport {
-	u32	port;
-	u32	ale;
-};
+			       struct _ioport {
+				       u32	port;
+				       u32	ale;
+			       };
 
-#define IOFUNC_IO(name, hws, ap) \
-	static u8 Read##name##_IO(void *p, u8 off) {\
-		struct hws *hw = p;\
-		return inb(hw->ap.port + off);\
-	} \
-	static void Write##name##_IO(void *p, u8 off, u8 val) {\
-		struct hws *hw = p;\
-		outb(val, hw->ap.port + off);\
-	} \
-	static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) {\
-		struct hws *hw = p;\
-		insb(hw->ap.port + off, dp, size);\
-	} \
-	static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) {\
-		struct hws *hw = p;\
-		outsb(hw->ap.port + off, dp, size);\
+#define IOFUNC_IO(name, hws, ap)					\
+	static u8 Read##name##_IO(void *p, u8 off) {			\
+		struct hws *hw = p;					\
+		return inb(hw->ap.port + off);				\
+	}								\
+	static void Write##name##_IO(void *p, u8 off, u8 val) {		\
+		struct hws *hw = p;					\
+		outb(val, hw->ap.port + off);				\
+	}								\
+	static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
+		struct hws *hw = p;					\
+		insb(hw->ap.port + off, dp, size);			\
+	}								\
+	static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \
+		struct hws *hw = p;					\
+		outsb(hw->ap.port + off, dp, size);			\
 	}
 
-#define IOFUNC_IND(name, hws, ap) \
-	static u8 Read##name##_IND(void *p, u8 off) {\
-		struct hws *hw = p;\
-		outb(off, hw->ap.ale);\
-		return inb(hw->ap.port);\
-	} \
-	static void Write##name##_IND(void *p, u8 off, u8 val) {\
-		struct hws *hw = p;\
-		outb(off, hw->ap.ale);\
-		outb(val, hw->ap.port);\
-	} \
-	static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) {\
-		struct hws *hw = p;\
-		outb(off, hw->ap.ale);\
-		insb(hw->ap.port, dp, size);\
-	} \
-	static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) {\
-		struct hws *hw = p;\
-		outb(off, hw->ap.ale);\
-		outsb(hw->ap.port, dp, size);\
+#define IOFUNC_IND(name, hws, ap)					\
+	static u8 Read##name##_IND(void *p, u8 off) {			\
+		struct hws *hw = p;					\
+		outb(off, hw->ap.ale);					\
+		return inb(hw->ap.port);				\
+	}								\
+	static void Write##name##_IND(void *p, u8 off, u8 val) {	\
+		struct hws *hw = p;					\
+		outb(off, hw->ap.ale);					\
+		outb(val, hw->ap.port);					\
+	}								\
+	static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
+		struct hws *hw = p;					\
+		outb(off, hw->ap.ale);					\
+		insb(hw->ap.port, dp, size);				\
+	}								\
+	static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \
+		struct hws *hw = p;					\
+		outb(off, hw->ap.ale);					\
+		outsb(hw->ap.port, dp, size);				\
 	}
 
-#define IOFUNC_MEMIO(name, hws, typ, adr) \
-	static u8 Read##name##_MIO(void *p, u8 off) {\
-		struct hws *hw = p;\
-		return readb(((typ *)hw->adr) + off);\
-	} \
-	static void Write##name##_MIO(void *p, u8 off, u8 val) {\
-		struct hws *hw = p;\
-		writeb(val, ((typ *)hw->adr) + off);\
-	} \
-	static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) {\
-		struct hws *hw = p;\
-		while (size--)\
-			*dp++ = readb(((typ *)hw->adr) + off);\
-	} \
-	static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) {\
-		struct hws *hw = p;\
-		while (size--)\
-			writeb(*dp++, ((typ *)hw->adr) + off);\
+#define IOFUNC_MEMIO(name, hws, typ, adr)				\
+	static u8 Read##name##_MIO(void *p, u8 off) {			\
+		struct hws *hw = p;					\
+		return readb(((typ *)hw->adr) + off);			\
+	}								\
+	static void Write##name##_MIO(void *p, u8 off, u8 val) {	\
+		struct hws *hw = p;					\
+		writeb(val, ((typ *)hw->adr) + off);			\
+	}								\
+	static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
+		struct hws *hw = p;					\
+		while (size--)						\
+			*dp++ = readb(((typ *)hw->adr) + off);		\
+	}								\
+	static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \
+		struct hws *hw = p;					\
+		while (size--)						\
+			writeb(*dp++, ((typ *)hw->adr) + off);		\
 	}
 
-#define ASSIGN_FUNC(typ, name, dest)	do {\
-	dest.read_reg = &Read##name##_##typ;\
-	dest.write_reg = &Write##name##_##typ;\
-	dest.read_fifo = &ReadFiFo##name##_##typ;\
-	dest.write_fifo = &WriteFiFo##name##_##typ;\
+#define ASSIGN_FUNC(typ, name, dest)	do {			\
+		dest.read_reg = &Read##name##_##typ;		\
+		dest.write_reg = &Write##name##_##typ;		\
+		dest.read_fifo = &ReadFiFo##name##_##typ;	\
+		dest.write_fifo = &WriteFiFo##name##_##typ;	\
 	} while (0)
-#define ASSIGN_FUNC_IPAC(typ, target)	do {\
-	ASSIGN_FUNC(typ, ISAC, target.isac);\
-	ASSIGN_FUNC(typ, IPAC, target);\
+#define ASSIGN_FUNC_IPAC(typ, target)	do {		\
+		ASSIGN_FUNC(typ, ISAC, target.isac);	\
+		ASSIGN_FUNC(typ, IPAC, target);		\
 	} while (0)
 
 #endif
diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h
index 9962bdf..cadfc49 100644
--- a/drivers/isdn/hardware/mISDN/isar.h
+++ b/drivers/isdn/hardware/mISDN/isar.h
@@ -97,7 +97,7 @@ struct isar_hw {
 #define ISAR_HIS_SDATA		0x20
 #define ISAR_HIS_DPS1		0x40
 #define ISAR_HIS_DPS2		0x80
-#define SET_DPS(x)		((x<<6) & 0xc0)
+#define SET_DPS(x)		((x << 6) & 0xc0)
 
 #define ISAR_IIS_MSCMSD		0x3f
 #define ISAR_IIS_VNR		0x15
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
index 6218775..631eb3f 100644
--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -431,11 +431,11 @@ enable_hwirq(struct inf_hw *hw)
 		break;
 	case INF_GAZEL_R685:
 		outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
-			(u32)hw->cfg.start + GAZEL_INCSR);
+		     (u32)hw->cfg.start + GAZEL_INCSR);
 		break;
 	case INF_GAZEL_R753:
 		outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
-			(u32)hw->cfg.start + GAZEL_INCSR);
+		     (u32)hw->cfg.start + GAZEL_INCSR);
 		break;
 	default:
 		break;
@@ -511,21 +511,21 @@ reset_inf(struct inf_hw *hw)
 		/* Workaround PCI9060 */
 		outb(9, (u32)hw->cfg.start + 0x69);
 		outb(DIVA_RESET_BIT | DIVA_LED_A,
-			(u32)hw->cfg.start + DIVA_PCI_CTRL);
+		     (u32)hw->cfg.start + DIVA_PCI_CTRL);
 		break;
 	case INF_DIVA201:
 		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
-			hw->cfg.p + PITA_MISC_REG);
+		       hw->cfg.p + PITA_MISC_REG);
 		mdelay(1);
 		writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
 		mdelay(10);
 		break;
 	case INF_DIVA202:
 		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
-			hw->cfg.p + PITA_MISC_REG);
+		       hw->cfg.p + PITA_MISC_REG);
 		mdelay(1);
 		writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
-			hw->cfg.p + PITA_MISC_REG);
+		       hw->cfg.p + PITA_MISC_REG);
 		mdelay(10);
 		break;
 	case INF_SPEEDWIN:
@@ -630,7 +630,7 @@ init_irq(struct inf_hw *hw)
 		msleep_interruptible(10);
 		if (debug & DEBUG_HW)
 			pr_notice("%s: IRQ %d count %d\n", hw->name,
-				hw->irq, hw->irqcnt);
+				  hw->irq, hw->irqcnt);
 		if (!hw->irqcnt) {
 			pr_info("%s: IRQ(%d) got no requests during init %d\n",
 				hw->name, hw->irq, 3 - cnt);
@@ -672,11 +672,11 @@ setup_io(struct inf_hw *hw)
 		hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
 		if (hw->ci->cfg_mode == AM_MEMIO) {
 			if (!request_mem_region(hw->cfg.start, hw->cfg.size,
-			    hw->name))
+						hw->name))
 				err = -EBUSY;
 		} else {
 			if (!request_region(hw->cfg.start, hw->cfg.size,
-			    hw->name))
+					    hw->name))
 				err = -EBUSY;
 		}
 		if (err) {
@@ -690,8 +690,8 @@ setup_io(struct inf_hw *hw)
 		hw->cfg.mode = hw->ci->cfg_mode;
 		if (debug & DEBUG_HW)
 			pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
-				hw->name, (ulong)hw->cfg.start,
-				(ulong)hw->cfg.size, hw->ci->cfg_mode);
+				  hw->name, (ulong)hw->cfg.start,
+				  (ulong)hw->cfg.size, hw->ci->cfg_mode);
 
 	}
 	if (hw->ci->addr_mode) {
@@ -699,11 +699,11 @@ setup_io(struct inf_hw *hw)
 		hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
 		if (hw->ci->addr_mode == AM_MEMIO) {
 			if (!request_mem_region(hw->addr.start, hw->addr.size,
-			    hw->name))
+						hw->name))
 				err = -EBUSY;
 		} else {
 			if (!request_region(hw->addr.start, hw->addr.size,
-			    hw->name))
+					    hw->name))
 				err = -EBUSY;
 		}
 		if (err) {
@@ -717,8 +717,8 @@ setup_io(struct inf_hw *hw)
 		hw->addr.mode = hw->ci->addr_mode;
 		if (debug & DEBUG_HW)
 			pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
-				hw->name, (ulong)hw->addr.start,
-				(ulong)hw->addr.size, hw->ci->addr_mode);
+				  hw->name, (ulong)hw->addr.start,
+				  (ulong)hw->addr.size, hw->ci->addr_mode);
 
 	}
 
@@ -903,7 +903,7 @@ setup_instance(struct inf_hw *card)
 	ulong flags;
 
 	snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
-		inf_cnt + 1);
+		 inf_cnt + 1);
 	write_lock_irqsave(&card_lock, flags);
 	list_add_tail(&card->list, &Cards);
 	write_unlock_irqrestore(&card_lock, flags);
@@ -928,7 +928,7 @@ setup_instance(struct inf_hw *card)
 		goto error_setup;
 
 	err = mISDN_register_device(&card->ipac.isac.dch.dev,
-		&card->pdev->dev, card->name);
+				    &card->pdev->dev, card->name);
 	if (err)
 		goto error;
 
@@ -1099,7 +1099,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return -EINVAL;
 	} else
 		pr_notice("mISDN: found adapter %s at %s\n",
-			card->ci->full, pci_name(pdev));
+			  card->ci->full, pci_name(pdev));
 
 	card->irq = pdev->irq;
 	pci_set_drvdata(pdev, card);
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
index d2ffb1d..b47e9be 100644
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -129,7 +129,7 @@ isac_empty_fifo(struct isac_hw *isac, int count)
 	}
 	if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
 		pr_debug("%s: %s overrun %d\n", isac->name, __func__,
-			    isac->dch.rx_skb->len + count);
+			 isac->dch.rx_skb->len + count);
 		WriteISAC(isac, ISAC_CMDR, 0x80);
 		return;
 	}
@@ -140,7 +140,7 @@ isac_empty_fifo(struct isac_hw *isac, int count)
 		char	pfx[MISDN_MAX_IDLEN + 16];
 
 		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
-			isac->name, count);
+			 isac->name, count);
 		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
 	}
 }
@@ -178,7 +178,7 @@ isac_fill_fifo(struct isac_hw *isac)
 		char	pfx[MISDN_MAX_IDLEN + 16];
 
 		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
-			isac->name, count);
+			 isac->name, count);
 		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
 	}
 }
@@ -283,7 +283,7 @@ isac_mos_irq(struct isac_hw *isac)
 		}
 		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
 		pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
-			isac->mon_rx[isac->mon_rxp - 1]);
+			 isac->mon_rx[isac->mon_rxp - 1]);
 		if (isac->mon_rxp == 1) {
 			isac->mocr |= 0x04;
 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
@@ -313,7 +313,7 @@ afterMONR0:
 		}
 		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
 		pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
-			isac->mon_rx[isac->mon_rxp - 1]);
+			 isac->mon_rx[isac->mon_rxp - 1]);
 		isac->mocr |= 0x40;
 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
 	}
@@ -325,7 +325,7 @@ afterMONR1:
 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
 		if (isac->monitor) {
 			ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
-				isac->mon_rx, isac->mon_rxp);
+					    isac->mon_rx, isac->mon_rxp);
 			if (ret)
 				kfree(isac->mon_rx);
 		} else {
@@ -343,7 +343,7 @@ afterMONR1:
 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
 		if (isac->monitor) {
 			ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
-				isac->mon_rx, isac->mon_rxp);
+					    isac->mon_rx, isac->mon_rxp);
 			if (ret)
 				kfree(isac->mon_rx);
 		} else {
@@ -356,7 +356,7 @@ afterMONR1:
 	}
 	if (val & 0x02) {
 		if ((!isac->mon_tx) || (isac->mon_txc &&
-			(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
+					(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
 			isac->mocr &= 0xf0;
 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
 			isac->mocr |= 0x0a;
@@ -364,7 +364,7 @@ afterMONR1:
 			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 				if (isac->monitor)
 					ret = isac->monitor(isac->dch.hw,
-						MONITOR_TX_0, NULL, 0);
+							    MONITOR_TX_0, NULL, 0);
 			}
 			kfree(isac->mon_tx);
 			isac->mon_tx = NULL;
@@ -375,7 +375,7 @@ afterMONR1:
 		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 			if (isac->monitor)
 				ret = isac->monitor(isac->dch.hw,
-					MONITOR_TX_0, NULL, 0);
+						    MONITOR_TX_0, NULL, 0);
 			kfree(isac->mon_tx);
 			isac->mon_tx = NULL;
 			isac->mon_txc = 0;
@@ -384,12 +384,12 @@ afterMONR1:
 		}
 		WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
 		pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
-			isac->mon_tx[isac->mon_txp - 1]);
+			 isac->mon_tx[isac->mon_txp - 1]);
 	}
 AfterMOX0:
 	if (val & 0x20) {
 		if ((!isac->mon_tx) || (isac->mon_txc &&
-			(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
+					(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
 			isac->mocr &= 0x0f;
 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
 			isac->mocr |= 0xa0;
@@ -397,7 +397,7 @@ AfterMOX0:
 			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 				if (isac->monitor)
 					ret = isac->monitor(isac->dch.hw,
-						MONITOR_TX_1, NULL, 0);
+							    MONITOR_TX_1, NULL, 0);
 			}
 			kfree(isac->mon_tx);
 			isac->mon_tx = NULL;
@@ -408,7 +408,7 @@ AfterMOX0:
 		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
 			if (isac->monitor)
 				ret = isac->monitor(isac->dch.hw,
-					MONITOR_TX_1, NULL, 0);
+						    MONITOR_TX_1, NULL, 0);
 			kfree(isac->mon_tx);
 			isac->mon_tx = NULL;
 			isac->mon_txc = 0;
@@ -417,7 +417,7 @@ AfterMOX0:
 		}
 		WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
 		pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
-			isac->mon_tx[isac->mon_txp - 1]);
+			 isac->mon_tx[isac->mon_txp - 1]);
 	}
 AfterMOX1:
 	val = 0; /* dummy to avoid warning */
@@ -432,7 +432,7 @@ isac_cisq_irq(struct isac_hw *isac) {
 	pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
 	if (val & 2) {
 		pr_debug("%s: ph_state change %x->%x\n", isac->name,
-			isac->state, (val >> 2) & 0xf);
+			 isac->state, (val >> 2) & 0xf);
 		isac->state = (val >> 2) & 0xf;
 		isac_ph_state_change(isac);
 	}
@@ -451,7 +451,7 @@ isacsx_cic_irq(struct isac_hw *isac)
 	pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
 	if (val & ISACX_CIR0_CIC0) {
 		pr_debug("%s: ph_state change %x->%x\n", isac->name,
-			isac->state, val >> 4);
+			 isac->state, val >> 4);
 		isac->state = val >> 4;
 		isac_ph_state_change(isac);
 	}
@@ -488,7 +488,7 @@ isacsx_rme_irq(struct isac_hw *isac)
 		if (isac->dch.rx_skb) {
 			skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
 			pr_debug("%s: dchannel received %d\n", isac->name,
-				isac->dch.rx_skb->len);
+				 isac->dch.rx_skb->len);
 			recv_Dchannel(&isac->dch);
 		}
 	}
@@ -628,7 +628,7 @@ isac_ctrl(struct isac_hw *isac, u32 cmd, u_long para)
 		break;
 	default:
 		pr_debug("%s: %s unknown command %x %lx\n", isac->name,
-			__func__, cmd, para);
+			 __func__, cmd, para);
 		return -1;
 	}
 	return 0;
@@ -685,16 +685,16 @@ isac_l1cmd(struct dchannel *dch, u32 cmd)
 	case PH_ACTIVATE_IND:
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	case PH_DEACTIVATE_IND:
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	default:
 		pr_debug("%s: %s unknown command %x\n", isac->name,
-			__func__, cmd);
+			 __func__, cmd);
 		return -1;
 	}
 	return 0;
@@ -731,7 +731,7 @@ dbusy_timer_handler(struct isac_hw *isac)
 		rbch = ReadISAC(isac, ISAC_RBCH);
 		star = ReadISAC(isac, ISAC_STAR);
 		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
-			isac->name, rbch, star);
+			 isac->name, rbch, star);
 		if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
 			test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
 		else {
@@ -753,7 +753,7 @@ static int
 open_dchannel(struct isac_hw *isac, struct channel_req *rq)
 {
 	pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
-		isac->dch.dev.id, __builtin_return_address(1));
+		 isac->dch.dev.id, __builtin_return_address(1));
 	if (rq->protocol != ISDN_P_TE_S0)
 		return -EINVAL;
 	if (rq->adr.channel == 1)
@@ -763,7 +763,7 @@ open_dchannel(struct isac_hw *isac, struct channel_req *rq)
 	rq->ch->protocol = rq->protocol;
 	if (isac->dch.state == 7)
 		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-		    0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 	return 0;
 }
 
@@ -807,7 +807,7 @@ isac_init(struct isac_hw *isac)
 		val = ReadISAC(isac, ISACX_ID);
 		if (isac->dch.debug & DEBUG_HW)
 			pr_notice("%s: ISACX Design ID %x\n",
-				isac->name, val & 0x3f);
+				  isac->name, val & 0x3f);
 		val = ReadISAC(isac, ISACX_CIR0);
 		pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
 		isac->state = val >> 4;
@@ -832,7 +832,7 @@ isac_init(struct isac_hw *isac)
 		val = ReadISAC(isac, ISAC_RBCH);
 		if (isac->dch.debug & DEBUG_HW)
 			pr_notice("%s: ISAC version (%x): %s\n", isac->name,
-				val, ISACVer[(val >> 5) & 3]);
+				  val, ISACVer[(val >> 5) & 3]);
 		isac->type |= ((val >> 5) & 3);
 		if (!isac->adf2)
 			isac->adf2 = 0x80;
@@ -889,7 +889,7 @@ waitforCEC(struct hscx_hw *hx)
 	}
 	if (to < 50)
 		pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
-			50 - to);
+			 50 - to);
 	if (!to)
 		pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
 }
@@ -909,7 +909,7 @@ waitforXFW(struct hscx_hw *hx)
 	}
 	if (to < 50)
 		pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
-			50 - to);
+			 50 - to);
 	if (!to)
 		pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
 }
@@ -942,7 +942,7 @@ hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
 	}
 	if ((hscx->bch.rx_skb->len + count) > hscx->bch.maxlen) {
 		pr_debug("%s: overrun %d\n", hscx->ip->name,
-			hscx->bch.rx_skb->len + count);
+			 hscx->bch.rx_skb->len + count);
 		skb_trim(hscx->bch.rx_skb, 0);
 		hscx_cmdr(hscx, 0x80); /* RMC */
 		return;
@@ -951,16 +951,16 @@ hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
 
 	if (hscx->ip->type & IPAC_TYPE_IPACX)
 		hscx->ip->read_fifo(hscx->ip->hw,
-			hscx->off + IPACX_RFIFOB, p, count);
+				    hscx->off + IPACX_RFIFOB, p, count);
 	else
 		hscx->ip->read_fifo(hscx->ip->hw,
-			hscx->off, p, count);
+				    hscx->off, p, count);
 
 	hscx_cmdr(hscx, 0x80); /* RMC */
 
 	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
 		snprintf(hscx->log, 64, "B%1d-recv %s %d ",
-			hscx->bch.nr, hscx->ip->name, count);
+			 hscx->bch.nr, hscx->ip->name, count);
 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
 	}
 }
@@ -984,22 +984,22 @@ hscx_fill_fifo(struct hscx_hw *hscx)
 		more = 1;
 	}
 	pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count,
-		hscx->bch.tx_idx, hscx->bch.tx_skb->len);
+		 hscx->bch.tx_idx, hscx->bch.tx_skb->len);
 	hscx->bch.tx_idx += count;
 
 	if (hscx->ip->type & IPAC_TYPE_IPACX)
 		hscx->ip->write_fifo(hscx->ip->hw,
-			hscx->off + IPACX_XFIFOB, p, count);
+				     hscx->off + IPACX_XFIFOB, p, count);
 	else {
 		waitforXFW(hscx);
 		hscx->ip->write_fifo(hscx->ip->hw,
-			hscx->off, p, count);
+				     hscx->off, p, count);
 	}
 	hscx_cmdr(hscx, more ? 0x08 : 0x0a);
 
 	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
 		snprintf(hscx->log, 64, "B%1d-send %s %d ",
-			hscx->bch.nr, hscx->ip->name, count);
+			 hscx->bch.nr, hscx->ip->name, count);
 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
 	}
 }
@@ -1037,18 +1037,18 @@ ipac_rme(struct hscx_hw *hx)
 		if (!(rstab & 0x80)) {
 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
 				pr_notice("%s: B%1d invalid frame\n",
-					hx->ip->name, hx->bch.nr);
+					  hx->ip->name, hx->bch.nr);
 		}
 		if (rstab & 0x40) {
 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
 				pr_notice("%s: B%1d RDO proto=%x\n",
-					hx->ip->name, hx->bch.nr,
-					hx->bch.state);
+					  hx->ip->name, hx->bch.nr,
+					  hx->bch.state);
 		}
 		if (!(rstab & 0x20)) {
 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
 				pr_notice("%s: B%1d CRC error\n",
-					hx->ip->name, hx->bch.nr);
+					  hx->ip->name, hx->bch.nr);
 		}
 		hscx_cmdr(hx, 0x80); /* Do RMC */
 		return;
@@ -1065,7 +1065,7 @@ ipac_rme(struct hscx_hw *hx)
 		return;
 	if (hx->bch.rx_skb->len < 2) {
 		pr_debug("%s: B%1d frame to short %d\n",
-			hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
+			 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
 		skb_trim(hx->bch.rx_skb, 0);
 	} else {
 		skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
@@ -1086,7 +1086,7 @@ ipac_irq(struct hscx_hw *hx, u8 ista)
 		if (m & ista) {
 			exirb = ReadHSCX(hx, IPAC_EXIRB);
 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
-				hx->bch.nr, exirb);
+				 hx->bch.nr, exirb);
 		}
 	} else if (hx->bch.nr & 2) { /* HSCX B */
 		if (ista & (HSCX__EXA | HSCX__ICA))
@@ -1094,7 +1094,7 @@ ipac_irq(struct hscx_hw *hx, u8 ista)
 		if (ista & HSCX__EXB) {
 			exirb = ReadHSCX(hx, IPAC_EXIRB);
 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
-				hx->bch.nr, exirb);
+				 hx->bch.nr, exirb);
 		}
 		istab = ista & 0xF8;
 	} else { /* HSCX A */
@@ -1102,7 +1102,7 @@ ipac_irq(struct hscx_hw *hx, u8 ista)
 		if (ista & HSCX__EXA) {
 			exirb = ReadHSCX(hx, IPAC_EXIRB);
 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
-				hx->bch.nr, exirb);
+				 hx->bch.nr, exirb);
 		}
 		istab = istab & 0xF8;
 	}
@@ -1141,7 +1141,7 @@ ipac_irq(struct hscx_hw *hx, u8 ista)
 			return;
 		}
 		pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
-			hx->bch.nr, hx->bch.tx_idx);
+			 hx->bch.nr, hx->bch.tx_idx);
 		hx->bch.tx_idx = 0;
 		hscx_cmdr(hx, 0x01);	/* XRES */
 	}
@@ -1204,10 +1204,10 @@ mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
 		return IRQ_NONE;
 	if (cnt < maxloop)
 		pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
-			maxloop - cnt, smp_processor_id());
+			 maxloop - cnt, smp_processor_id());
 	if (maxloop && !cnt)
 		pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
-			maxloop, smp_processor_id());
+			  maxloop, smp_processor_id());
 	return IRQ_HANDLED;
 }
 EXPORT_SYMBOL(mISDNipac_irq);
@@ -1216,7 +1216,7 @@ static int
 hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
 {
 	pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
-		'@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
+		 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
 	if (hscx->ip->type & IPAC_TYPE_IPACX) {
 		if (hscx->bch.nr & 1) { /* B1 and ICA */
 			WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
@@ -1364,7 +1364,7 @@ hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				NULL, GFP_KERNEL);
+				    NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		spin_lock_irqsave(hx->ip->hwlock, flags);
@@ -1372,7 +1372,7 @@ hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
 		hscx_mode(hx, ISDN_P_NONE);
 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	default:
@@ -1394,7 +1394,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_GETOP:
 		cq->op = 0;
 		break;
-	/* Nothing implemented yet */
+		/* Nothing implemented yet */
 	case MISDN_CTRL_FILL_EMPTY:
 	default:
 		pr_info("%s: unknown Op %x\n", __func__, cq->op);
@@ -1467,7 +1467,7 @@ hscx_init(struct hscx_hw *hx)
 		pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
 		if (hx->bch.debug & DEBUG_HW)
 			pr_notice("%s: HSCX version %s\n", hx->ip->name,
-				HSCXVer[val & 0x0f]);
+				  HSCXVer[val & 0x0f]);
 	} else
 		WriteHSCX(hx, IPAC_CCR1, 0x82);
 	WriteHSCX(hx, IPAC_CCR2, 0x30);
@@ -1491,7 +1491,7 @@ ipac_init(struct ipac_hw *ipac)
 		val = ReadIPAC(ipac, IPAC_CONF);
 		/* conf is default 0, but can be overwritten by card setup */
 		pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
-			val, ipac->conf);
+			 val, ipac->conf);
 		WriteIPAC(ipac, IPAC_CONF, ipac->conf);
 		val = ReadIPAC(ipac, IPAC_ID);
 		if (ipac->hscx[0].bch.debug & DEBUG_HW)
@@ -1569,7 +1569,7 @@ ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	case CLOSE_CHANNEL:
 		pr_debug("%s: dev(%d) close from %p\n", ipac->name,
-			dch->dev.id, __builtin_return_address(0));
+			 dch->dev.id, __builtin_return_address(0));
 		module_put(ipac->owner);
 		break;
 	case CONTROL_CHANNEL:
@@ -1620,7 +1620,7 @@ mISDNipac_init(struct ipac_hw *ipac, void *hw)
 		ipac->hscx[i].bch.nr = i + 1;
 		set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
 		list_add(&ipac->hscx[i].bch.ch.list,
-			&ipac->isac.dch.dev.bchannels);
+			 &ipac->isac.dch.dev.bchannels);
 		mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM);
 		ipac->hscx[i].bch.ch.nr = i + 1;
 		ipac->hscx[i].bch.ch.send = &hscx_l2l1;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index 7034af2..10446ab 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -42,7 +42,7 @@ MODULE_VERSION(ISAR_REV);
 
 static const u8 faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146";
 static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121,
-					122, 145, 146};
+				   122, 145, 146};
 #define FAXMODCNT 13
 
 static void isar_setup(struct isar_hw *);
@@ -84,9 +84,9 @@ send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg)
 
 			while (l < (int)len) {
 				hex_dump_to_buffer(msg + l, len - l, 32, 1,
-					isar->log, 256, 1);
+						   isar->log, 256, 1);
 				pr_debug("%s: %s %02x: %s\n", isar->name,
-					__func__, l, isar->log);
+					 __func__, l, isar->log);
 				l += 32;
 			}
 		}
@@ -113,9 +113,9 @@ rcv_mbox(struct isar_hw *isar, u8 *msg)
 
 			while (l < (int)isar->clsb) {
 				hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
-					1, isar->log, 256, 1);
+						   1, isar->log, 256, 1);
 				pr_debug("%s: %s %02x: %s\n", isar->name,
-					__func__, l, isar->log);
+					 __func__, l, isar->log);
 				l += 32;
 			}
 		}
@@ -130,7 +130,7 @@ get_irq_infos(struct isar_hw *isar)
 	isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H);
 	isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L);
 	pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name,
-		isar->iis, isar->cmsb, isar->clsb);
+		 isar->iis, isar->cmsb, isar->clsb);
 }
 
 /*
@@ -154,7 +154,7 @@ poll_mbox(struct isar_hw *isar, int maxdelay)
 		rcv_mbox(isar, NULL);
 	}
 	pr_debug("%s: pulled %d bytes after %d us\n",
-		isar->name, isar->clsb, maxdelay - t);
+		 isar->name, isar->clsb, maxdelay - t);
 	return t;
 }
 
@@ -200,13 +200,13 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 
 	if (1 != isar->version) {
 		pr_err("%s: ISAR wrong version %d firmware download aborted\n",
-			isar->name, isar->version);
+		       isar->name, isar->version);
 		return -EINVAL;
 	}
 	if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO))
 		isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO;
 	pr_debug("%s: load firmware %d words (%d bytes)\n",
-		isar->name, size/2, size);
+		 isar->name, size / 2, size);
 	cnt = 0;
 	size /= 2;
 	/* disable ISAR IRQ */
@@ -219,7 +219,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 		blk_head.d_key = le16_to_cpu(*sp++);
 		cnt += 3;
 		pr_debug("ISAR firmware block (%#x,%d,%#x)\n",
-			blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
+			 blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
 		left = blk_head.len;
 		if (cnt + left > size) {
 			pr_info("%s: firmware error have %d need %d words\n",
@@ -229,7 +229,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 		}
 		spin_lock_irqsave(isar->hwlock, flags);
 		if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff,
-		    0, NULL)) {
+			       0, NULL)) {
 			pr_info("ISAR send_mbox dkey failed\n");
 			ret = -ETIME;
 			goto reterror;
@@ -260,7 +260,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 			cnt += noc;
 			*mp++ = noc;
 			pr_debug("%s: load %3d words at %04x\n", isar->name,
-				noc, blk_head.sadr);
+				 noc, blk_head.sadr);
 			blk_head.sadr += noc;
 			while (noc) {
 				val = le16_to_cpu(*sp++);
@@ -289,7 +289,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 			}
 		}
 		pr_debug("%s: ISAR firmware block %d words loaded\n",
-			isar->name, blk_head.len);
+			 isar->name, blk_head.len);
 	}
 	isar->ch[0].bch.debug = saved_debug;
 	/* 10ms delay */
@@ -333,7 +333,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 		goto reterrflg;
 	} else
 		pr_debug("%s: ISAR general status event %x\n",
-			isar->name, isar->bstat);
+			 isar->name, isar->bstat);
 	/* 10ms delay */
 	cnt = 10;
 	while (cnt--)
@@ -387,7 +387,7 @@ load_firmware(struct isar_hw *isar, const u8 *buf, int size)
 	} else {
 		if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) {
 			pr_notice("%s: ISAR software version %#x\n",
-				isar->name, isar->buf[0]);
+				  isar->name, isar->buf[0]);
 		} else {
 			pr_info("%s: ISAR wrong swver response (%x,%x)"
 				" cnt(%d)\n", isar->name, isar->cmsb,
@@ -431,7 +431,7 @@ isar_rcv_frame(struct isar_ch *ch)
 	switch (ch->bch.state) {
 	case ISDN_P_NONE:
 		pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n",
-			ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
+			 ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
 		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
 		break;
 	case ISDN_P_B_RAW:
@@ -439,7 +439,7 @@ isar_rcv_frame(struct isar_ch *ch)
 	case ISDN_P_B_MODEM_ASYNC:
 		if (!ch->bch.rx_skb) {
 			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
-						GFP_ATOMIC);
+						      GFP_ATOMIC);
 			if (unlikely(!ch->bch.rx_skb)) {
 				pr_info("%s: B receive out of memory\n",
 					ch->is->name);
@@ -453,7 +453,7 @@ isar_rcv_frame(struct isar_ch *ch)
 	case ISDN_P_B_HDLC:
 		if (!ch->bch.rx_skb) {
 			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
-						GFP_ATOMIC);
+						      GFP_ATOMIC);
 			if (unlikely(!ch->bch.rx_skb)) {
 				pr_info("%s: B receive out of memory\n",
 					ch->is->name);
@@ -464,14 +464,14 @@ isar_rcv_frame(struct isar_ch *ch)
 		if ((ch->bch.rx_skb->len + ch->is->clsb) >
 		    (ch->bch.maxlen + 2)) {
 			pr_debug("%s: incoming packet too large\n",
-				ch->is->name);
+				 ch->is->name);
 			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
 			skb_trim(ch->bch.rx_skb, 0);
 			break;
 		}
 		if (ch->is->cmsb & HDLC_ERROR) {
 			pr_debug("%s: ISAR frame error %x len %d\n",
-				ch->is->name, ch->is->cmsb, ch->is->clsb);
+				 ch->is->name, ch->is->cmsb, ch->is->clsb);
 #ifdef ERROR_STATISTIC
 			if (ch->is->cmsb & HDLC_ERR_RER)
 				ch->bch.err_inv++;
@@ -489,7 +489,7 @@ isar_rcv_frame(struct isar_ch *ch)
 		if (ch->is->cmsb & HDLC_FED) {
 			if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
 				pr_debug("%s: ISAR frame to short %d\n",
-					ch->is->name, ch->bch.rx_skb->len);
+					 ch->is->name, ch->bch.rx_skb->len);
 				skb_trim(ch->bch.rx_skb, 0);
 				break;
 			}
@@ -500,7 +500,7 @@ isar_rcv_frame(struct isar_ch *ch)
 	case ISDN_P_B_T30_FAX:
 		if (ch->state != STFAX_ACTIV) {
 			pr_debug("%s: isar_rcv_frame: not ACTIV\n",
-				ch->is->name);
+				 ch->is->name);
 			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
 			if (ch->bch.rx_skb)
 				skb_trim(ch->bch.rx_skb, 0);
@@ -508,7 +508,7 @@ isar_rcv_frame(struct isar_ch *ch)
 		}
 		if (!ch->bch.rx_skb) {
 			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
-						GFP_ATOMIC);
+						      GFP_ATOMIC);
 			if (unlikely(!ch->bch.rx_skb)) {
 				pr_info("%s: B receive out of memory\n",
 					__func__);
@@ -519,14 +519,14 @@ isar_rcv_frame(struct isar_ch *ch)
 		if (ch->cmd == PCTRL_CMD_FRM) {
 			rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
 			pr_debug("%s: isar_rcv_frame: %d\n",
-				ch->is->name, ch->bch.rx_skb->len);
+				 ch->is->name, ch->bch.rx_skb->len);
 			if (ch->is->cmsb & SART_NMD) { /* ABORT */
 				pr_debug("%s: isar_rcv_frame: no more data\n",
-					ch->is->name);
+					 ch->is->name);
 				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
 				send_mbox(ch->is, SET_DPS(ch->dpath) |
-					ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
-					0, NULL);
+					  ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
+					  0, NULL);
 				ch->state = STFAX_ESCAPE;
 				/* set_skb_flag(skb, DF_NOMOREDATA); */
 			}
@@ -537,7 +537,7 @@ isar_rcv_frame(struct isar_ch *ch)
 		}
 		if (ch->cmd != PCTRL_CMD_FRH) {
 			pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n",
-				ch->is->name, ch->cmd);
+				 ch->is->name, ch->cmd);
 			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
 			if (ch->bch.rx_skb)
 				skb_trim(ch->bch.rx_skb, 0);
@@ -574,12 +574,12 @@ isar_rcv_frame(struct isar_ch *ch)
 		}
 		if (ch->is->cmsb & SART_NMD) { /* ABORT */
 			pr_debug("%s: isar_rcv_frame: no more data\n",
-				ch->is->name);
+				 ch->is->name);
 			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
 			if (ch->bch.rx_skb)
 				skb_trim(ch->bch.rx_skb, 0);
 			send_mbox(ch->is, SET_DPS(ch->dpath) |
-				ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
+				  ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
 			ch->state = STFAX_ESCAPE;
 			deliver_status(ch, HW_MOD_NOCARR);
 		}
@@ -599,14 +599,14 @@ isar_fill_fifo(struct isar_ch *ch)
 	u8 *ptr;
 
 	pr_debug("%s: ch%d  tx_skb %p tx_idx %d\n",
-		ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx);
+		 ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx);
 	if (!ch->bch.tx_skb)
 		return;
 	count = ch->bch.tx_skb->len - ch->bch.tx_idx;
 	if (count <= 0)
 		return;
 	if (!(ch->is->bstat &
-		(ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
+	      (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
 		return;
 	if (count > ch->mml) {
 		msb = 0;
@@ -618,17 +618,17 @@ isar_fill_fifo(struct isar_ch *ch)
 	if (!ch->bch.tx_idx) {
 		pr_debug("%s: frame start\n", ch->is->name);
 		if ((ch->bch.state == ISDN_P_B_T30_FAX) &&
-			(ch->cmd == PCTRL_CMD_FTH)) {
+		    (ch->cmd == PCTRL_CMD_FTH)) {
 			if (count > 1) {
 				if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) {
 					/* last frame */
 					test_and_set_bit(FLG_LASTDATA,
-						&ch->bch.Flags);
+							 &ch->bch.Flags);
 					pr_debug("%s: set LASTDATA\n",
-						ch->is->name);
+						 ch->is->name);
 					if (msb == HDLC_FED)
 						test_and_set_bit(FLG_DLEETX,
-							&ch->bch.Flags);
+								 &ch->bch.Flags);
 				}
 			}
 		}
@@ -643,21 +643,21 @@ isar_fill_fifo(struct isar_ch *ch)
 	case ISDN_P_B_L2DTMF:
 	case ISDN_P_B_MODEM_ASYNC:
 		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-			0, count, ptr);
+			  0, count, ptr);
 		break;
 	case ISDN_P_B_HDLC:
 		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-			msb, count, ptr);
+			  msb, count, ptr);
 		break;
 	case ISDN_P_B_T30_FAX:
 		if (ch->state != STFAX_ACTIV)
 			pr_debug("%s: not ACTIV\n", ch->is->name);
 		else if (ch->cmd == PCTRL_CMD_FTH)
 			send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-				msb, count, ptr);
+				  msb, count, ptr);
 		else if (ch->cmd == PCTRL_CMD_FTM)
 			send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
-				0, count, ptr);
+				  0, count, ptr);
 		else
 			pr_debug("%s: not FTH/FTM\n", ch->is->name);
 		break;
@@ -687,8 +687,8 @@ static void
 send_next(struct isar_ch *ch)
 {
 	pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n",
-		ch->is->name, __func__, ch->bch.nr,
-		ch->bch.tx_skb, ch->bch.tx_idx);
+		 ch->is->name, __func__, ch->bch.nr,
+		 ch->bch.tx_skb, ch->bch.tx_idx);
 	if (ch->bch.state == ISDN_P_B_T30_FAX) {
 		if (ch->cmd == PCTRL_CMD_FTH) {
 			if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
@@ -713,12 +713,12 @@ send_next(struct isar_ch *ch)
 	else {
 		if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
 			if (test_and_clear_bit(FLG_LASTDATA,
-			    &ch->bch.Flags)) {
+					       &ch->bch.Flags)) {
 				if (test_and_clear_bit(FLG_NMD_DATA,
-				    &ch->bch.Flags)) {
+						       &ch->bch.Flags)) {
 					u8 zd = 0;
 					send_mbox(ch->is, SET_DPS(ch->dpath) |
-						ISAR_HIS_SDATA, 0x01, 1, &zd);
+						  ISAR_HIS_SDATA, 0x01, 1, &zd);
 				}
 				test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
 			} else {
@@ -738,7 +738,7 @@ check_send(struct isar_hw *isar, u8 rdm)
 		ch = sel_bch_isar(isar, 1);
 		if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
 			if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
-			    ch->bch.tx_idx))
+					       ch->bch.tx_idx))
 				isar_fill_fifo(ch);
 			else
 				send_next(ch);
@@ -748,7 +748,7 @@ check_send(struct isar_hw *isar, u8 rdm)
 		ch = sel_bch_isar(isar, 2);
 		if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
 			if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
-			    ch->bch.tx_idx))
+					       ch->bch.tx_idx))
 				isar_fill_fifo(ch);
 			else
 				send_next(ch);
@@ -757,10 +757,10 @@ check_send(struct isar_hw *isar, u8 rdm)
 }
 
 const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
-			"300", "600", "1200", "2400", "4800", "7200",
-			"9600nt", "9600t", "12000", "14400", "WRONG"};
+		       "300", "600", "1200", "2400", "4800", "7200",
+		       "9600nt", "9600t", "12000", "14400", "WRONG"};
 const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
-			"Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
+		       "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
 
 static void
 isar_pump_status_rsp(struct isar_ch *ch) {
@@ -892,10 +892,10 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 			pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name);
 			ch->state = STFAX_CONT;
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				PCTRL_CMD_CONT, 0, NULL);
+				  PCTRL_CMD_CONT, 0, NULL);
 		} else {
 			pr_debug("%s: pump stev LINE_TX_H wrong st %x\n",
-				ch->is->name, ch->state);
+				 ch->is->name, ch->state);
 		}
 		break;
 	case PSEV_LINE_RX_H:
@@ -903,10 +903,10 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 			pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name);
 			ch->state = STFAX_CONT;
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				PCTRL_CMD_CONT, 0, NULL);
+				  PCTRL_CMD_CONT, 0, NULL);
 		} else {
 			pr_debug("%s: pump stev LINE_RX_H wrong st %x\n",
-				ch->is->name, ch->state);
+				 ch->is->name, ch->state);
 		}
 		break;
 	case PSEV_LINE_TX_B:
@@ -914,10 +914,10 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 			pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name);
 			ch->state = STFAX_CONT;
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				PCTRL_CMD_CONT, 0, NULL);
+				  PCTRL_CMD_CONT, 0, NULL);
 		} else {
 			pr_debug("%s: pump stev LINE_TX_B wrong st %x\n",
-				ch->is->name, ch->state);
+				 ch->is->name, ch->state);
 		}
 		break;
 	case PSEV_LINE_RX_B:
@@ -925,10 +925,10 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 			pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name);
 			ch->state = STFAX_CONT;
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				PCTRL_CMD_CONT, 0, NULL);
+				  PCTRL_CMD_CONT, 0, NULL);
 		} else {
 			pr_debug("%s: pump stev LINE_RX_B wrong st %x\n",
-				ch->is->name, ch->state);
+				 ch->is->name, ch->state);
 		}
 		break;
 	case PSEV_RSP_CONN:
@@ -941,19 +941,19 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 				int delay = (ch->mod == 3) ? 1000 : 200;
 				/* 1s (200 ms) Flags before data */
 				if (test_and_set_bit(FLG_FTI_RUN,
-				    &ch->bch.Flags))
+						     &ch->bch.Flags))
 					del_timer(&ch->ftimer);
 				ch->ftimer.expires =
-					jiffies + ((delay * HZ)/1000);
+					jiffies + ((delay * HZ) / 1000);
 				test_and_set_bit(FLG_LL_CONN,
-					&ch->bch.Flags);
+						 &ch->bch.Flags);
 				add_timer(&ch->ftimer);
 			} else {
 				deliver_status(ch, HW_MOD_CONNECT);
 			}
 		} else {
 			pr_debug("%s: pump stev RSP_CONN wrong st %x\n",
-				ch->is->name, ch->state);
+				 ch->is->name, ch->state);
 		}
 		break;
 	case PSEV_FLAGS_DET:
@@ -961,7 +961,7 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 		break;
 	case PSEV_RSP_DISC:
 		pr_debug("%s: pump stev RSP_DISC state(%d)\n",
-			ch->is->name, ch->state);
+			 ch->is->name, ch->state);
 		if (ch->state == STFAX_ESCAPE) {
 			p1 = 5;
 			switch (ch->newcmd) {
@@ -972,7 +972,7 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 				p1 = 2;
 			case PCTRL_CMD_FTH:
 				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-					PCTRL_CMD_SILON, 1, &p1);
+					  PCTRL_CMD_SILON, 1, &p1);
 				ch->state = STFAX_SILDET;
 				break;
 			case PCTRL_CMD_FRH:
@@ -983,13 +983,13 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 				ch->cmd = ch->newcmd;
 				ch->newcmd = 0;
 				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-					ch->cmd, 1, &p1);
+					  ch->cmd, 1, &p1);
 				ch->state = STFAX_LINE;
 				ch->try_mod = 3;
 				break;
 			default:
 				pr_debug("%s: RSP_DISC unknown newcmd %x\n",
-					ch->is->name, ch->newcmd);
+					 ch->is->name, ch->newcmd);
 				break;
 			}
 		} else if (ch->state == STFAX_ACTIV) {
@@ -1015,7 +1015,7 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 			ch->cmd = ch->newcmd;
 			ch->newcmd = 0;
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-				ch->cmd, 1, &p1);
+				  ch->cmd, 1, &p1);
 			ch->state = STFAX_LINE;
 			ch->try_mod = 3;
 		}
@@ -1026,17 +1026,17 @@ isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
 	case PSEV_RSP_FCERR:
 		if (ch->state == STFAX_LINE) {
 			pr_debug("%s: pump stev RSP_FCERR try %d\n",
-				ch->is->name, ch->try_mod);
+				 ch->is->name, ch->try_mod);
 			if (ch->try_mod--) {
 				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
-					ch->cmd, 1, &ch->mod);
+					  ch->cmd, 1, &ch->mod);
 				break;
 			}
 		}
 		pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name);
 		ch->state = STFAX_ESCAPE;
 		send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
-			0, NULL);
+			  0, NULL);
 		deliver_status(ch, HW_MOD_FCERROR);
 		break;
 	default:
@@ -1057,8 +1057,8 @@ mISDNisar_irq(struct isar_hw *isar)
 			isar_rcv_frame(ch);
 		else {
 			pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n",
-				isar->name, isar->iis, isar->cmsb,
-				isar->clsb);
+				 isar->name, isar->iis, isar->cmsb,
+				 isar->clsb);
 			isar->write_reg(isar->hw, ISAR_IIA, 0);
 		}
 		break;
@@ -1078,7 +1078,7 @@ mISDNisar_irq(struct isar_hw *isar)
 		}
 #endif
 		pr_debug("%s: Buffer STEV dpath%d msb(%x)\n",
-			isar->name, isar->iis>>6, isar->cmsb);
+			 isar->name, isar->iis >> 6, isar->cmsb);
 		isar->write_reg(isar->hw, ISAR_IIA, 0);
 		break;
 	case ISAR_IIS_PSTEV:
@@ -1100,16 +1100,16 @@ mISDNisar_irq(struct isar_hw *isar)
 					tt += 7;
 				tt |= DTMF_TONE_VAL;
 				_queue_data(&ch->bch.ch, PH_CONTROL_IND,
-					MISDN_ID_ANY, sizeof(tt), &tt,
-					GFP_ATOMIC);
+					    MISDN_ID_ANY, sizeof(tt), &tt,
+					    GFP_ATOMIC);
 			} else
 				pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n",
-					isar->name, ch->bch.state,
-					isar->cmsb);
+					 isar->name, ch->bch.state,
+					 isar->cmsb);
 		} else {
 			pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n",
-				isar->name, isar->iis, isar->cmsb,
-				isar->clsb);
+				 isar->name, isar->iis, isar->cmsb,
+				 isar->clsb);
 			isar->write_reg(isar->hw, ISAR_IIA, 0);
 		}
 		break;
@@ -1120,8 +1120,8 @@ mISDNisar_irq(struct isar_hw *isar)
 			isar_pump_status_rsp(ch);
 		} else {
 			pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n",
-				isar->name, isar->iis, isar->cmsb,
-				isar->clsb);
+				 isar->name, isar->iis, isar->cmsb,
+				 isar->clsb);
 			isar->write_reg(isar->hw, ISAR_IIA, 0);
 		}
 		break;
@@ -1137,7 +1137,7 @@ mISDNisar_irq(struct isar_hw *isar)
 	default:
 		rcv_mbox(isar, NULL);
 		pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n",
-			isar->name, isar->iis, isar->cmsb, isar->clsb);
+			 isar->name, isar->iis, isar->cmsb, isar->clsb);
 		break;
 	}
 }
@@ -1169,11 +1169,11 @@ setup_pump(struct isar_ch *ch) {
 		if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) {
 			param[0] = 5; /* TOA 5 db */
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
-				PMOD_DTMF_TRANS, 1, param);
+				  PMOD_DTMF_TRANS, 1, param);
 		} else {
 			param[0] = 40; /* REL -46 dbm */
 			send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
-				PMOD_DTMF, 1, param);
+				  PMOD_DTMF, 1, param);
 		}
 	case ISDN_P_B_MODEM_ASYNC:
 		ctrl = PMOD_DATAMODEM;
@@ -1220,17 +1220,17 @@ setup_sart(struct isar_ch *ch) {
 	switch (ch->bch.state) {
 	case ISDN_P_NONE:
 		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE,
-			0, NULL);
+			  0, NULL);
 		break;
 	case ISDN_P_B_RAW:
 	case ISDN_P_B_L2DTMF:
 		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY,
-			2, param);
+			  2, param);
 		break;
 	case ISDN_P_B_HDLC:
 	case ISDN_P_B_T30_FAX:
 		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC,
-			1, param);
+			  1, param);
 		break;
 	case ISDN_P_B_MODEM_ASYNC:
 		ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
@@ -1297,7 +1297,7 @@ modeisar(struct isar_ch *ch, u32 bprotocol)
 			if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags))
 				ch->dpath = 2;
 			else if (!test_and_set_bit(ISAR_DP1_USE,
-			    &ch->is->Flags))
+						   &ch->is->Flags))
 				ch->dpath = 1;
 			else {
 				pr_info("modeisar both pathes in use\n");
@@ -1307,7 +1307,7 @@ modeisar(struct isar_ch *ch, u32 bprotocol)
 				test_and_set_bit(FLG_HDLC, &ch->bch.Flags);
 			else
 				test_and_set_bit(FLG_TRANSPARENT,
-					&ch->bch.Flags);
+						 &ch->bch.Flags);
 			break;
 		case ISDN_P_B_MODEM_ASYNC:
 		case ISDN_P_B_T30_FAX:
@@ -1328,7 +1328,7 @@ modeisar(struct isar_ch *ch, u32 bprotocol)
 		}
 	}
 	pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name,
-		ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
+		 ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
 	ch->bch.state = bprotocol;
 	setup_pump(ch);
 	setup_iom2(ch);
@@ -1353,7 +1353,7 @@ isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
 	u8 ctrl = 0, nom = 0, p1 = 0;
 
 	pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n",
-		ch->is->name, cmd, para, ch->bch.state);
+		 ch->is->name, cmd, para, ch->bch.state);
 	switch (cmd) {
 	case HW_MOD_FTM:
 		if (ch->state == STFAX_READY) {
@@ -1367,7 +1367,7 @@ isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
 			ch->newcmd = 0;
 			ch->try_mod = 3;
 		} else if ((ch->state == STFAX_ACTIV) &&
-		    (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
+			   (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
 			deliver_status(ch, HW_MOD_CONNECT);
 		else {
 			ch->newmod = para;
@@ -1389,8 +1389,8 @@ isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
 			ch->newcmd = 0;
 			ch->try_mod = 3;
 		} else if ((ch->state == STFAX_ACTIV) &&
-		    (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
-				deliver_status(ch, HW_MOD_CONNECT);
+			   (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
+			deliver_status(ch, HW_MOD_CONNECT);
 		else {
 			ch->newmod = para;
 			ch->newcmd = PCTRL_CMD_FTH;
@@ -1411,7 +1411,7 @@ isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
 			ch->newcmd = 0;
 			ch->try_mod = 3;
 		} else if ((ch->state == STFAX_ACTIV) &&
-		    (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
+			   (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
 			deliver_status(ch, HW_MOD_CONNECT);
 		else {
 			ch->newmod = para;
@@ -1433,7 +1433,7 @@ isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
 			ch->newcmd = 0;
 			ch->try_mod = 3;
 		} else if ((ch->state == STFAX_ACTIV) &&
-		    (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
+			   (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
 			deliver_status(ch, HW_MOD_CONNECT);
 		else {
 			ch->newmod = para;
@@ -1464,7 +1464,7 @@ isar_setup(struct isar_hw *isar)
 	for (i = 0; i < 2; i++) {
 		/* Buffer Config */
 		send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
-			ISAR_HIS_P12CFG, 4, 1, &msg);
+			  ISAR_HIS_P12CFG, 4, 1, &msg);
 		isar->ch[i].mml = msg;
 		isar->ch[i].bch.state = 0;
 		isar->ch[i].dpath = i + 1;
@@ -1505,7 +1505,7 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(ich->is->hwlock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				NULL, GFP_KERNEL);
+				    NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		spin_lock_irqsave(ich->is->hwlock, flags);
@@ -1513,15 +1513,15 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
 		modeisar(ich, ISDN_P_NONE);
 		spin_unlock_irqrestore(ich->is->hwlock, flags);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	case PH_CONTROL_REQ:
 		val = (u32 *)skb->data;
 		pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
-			hh->id, *val);
+			 hh->id, *val);
 		if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
-		    DTMF_TONE_VAL)) {
+				      DTMF_TONE_VAL)) {
 			if (bch->state == ISDN_P_B_L2DTMF) {
 				char tt = *val & DTMF_TONE_MASK;
 
@@ -1541,7 +1541,7 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
 				return -EINVAL;
 			}
 		} else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
-		    (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
+			   (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
 			for (id = 0; id < FAXMODCNT; id++)
 				if (faxmodulation[id] == *val)
 					break;
@@ -1581,7 +1581,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_GETOP:
 		cq->op = 0;
 		break;
-	/* Nothing implemented yet */
+		/* Nothing implemented yet */
 	case MISDN_CTRL_FILL_EMPTY:
 	default:
 		pr_info("%s: unknown Op %x\n", __func__, cq->op);
@@ -1647,7 +1647,7 @@ init_isar(struct isar_hw *isar)
 		isar->version = ISARVersion(isar);
 		if (isar->ch[0].bch.debug & DEBUG_HW)
 			pr_notice("%s: Testing version %d (%d time)\n",
-				isar->name, isar->version, 3 - cnt);
+				  isar->name, isar->version, 3 - cnt);
 		if (isar->version == 1)
 			break;
 		isar->ctrl(isar->hw, HW_RESET_REQ, 0);
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index 5ef9f11..dd6de9f 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -191,7 +191,7 @@ fill_mem(struct tiger_ch *bc, u32 idx, u32 cnt, u32 fill)
 	u32 mask = 0xff, val;
 
 	pr_debug("%s: B%1d fill %02x len %d idx %d/%d\n", card->name,
-		bc->bch.nr, fill, cnt, idx, card->send.idx);
+		 bc->bch.nr, fill, cnt, idx, card->send.idx);
 	if (bc->bch.nr & 2) {
 		fill  <<= 8;
 		mask <<= 8;
@@ -213,7 +213,7 @@ mode_tiger(struct tiger_ch *bc, u32 protocol)
 	struct tiger_hw *card = bc->bch.hw;
 
 	pr_debug("%s: B%1d protocol %x-->%x\n", card->name,
-		bc->bch.nr, bc->bch.state, protocol);
+		 bc->bch.nr, bc->bch.state, protocol);
 	switch (protocol) {
 	case ISDN_P_NONE:
 		if (bc->bch.state == ISDN_P_NONE)
@@ -237,7 +237,7 @@ mode_tiger(struct tiger_ch *bc, u32 protocol)
 		test_and_set_bit(FLG_TRANSPARENT, &bc->bch.Flags);
 		bc->bch.state = protocol;
 		bc->idx = 0;
-		bc->free = card->send.size/2;
+		bc->free = card->send.size / 2;
 		bc->rxstate = 0;
 		bc->txstate = TX_INIT | TX_IDLE;
 		bc->lastrx = -1;
@@ -251,7 +251,7 @@ mode_tiger(struct tiger_ch *bc, u32 protocol)
 		test_and_set_bit(FLG_HDLC, &bc->bch.Flags);
 		bc->bch.state = protocol;
 		bc->idx = 0;
-		bc->free = card->send.size/2;
+		bc->free = card->send.size / 2;
 		bc->rxstate = 0;
 		bc->txstate = TX_INIT | TX_IDLE;
 		isdnhdlc_rcv_init(&bc->hrecv, 0);
@@ -273,12 +273,12 @@ mode_tiger(struct tiger_ch *bc, u32 protocol)
 	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
 	card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
 	pr_debug("%s: %s ctrl %x irq  %02x/%02x idx %d/%d\n",
-		card->name, __func__,
-		inb(card->base + NJ_DMACTRL),
-		inb(card->base + NJ_IRQMASK0),
-		inb(card->base + NJ_IRQSTAT0),
-		card->send.idx,
-		card->recv.idx);
+		 card->name, __func__,
+		 inb(card->base + NJ_DMACTRL),
+		 inb(card->base + NJ_IRQMASK0),
+		 inb(card->base + NJ_IRQSTAT0),
+		 card->send.idx,
+		 card->recv.idx);
 	return 0;
 }
 
@@ -311,7 +311,7 @@ inittiger(struct tiger_hw *card)
 	int i;
 
 	card->dma_p = pci_alloc_consistent(card->pdev, NJ_DMA_SIZE,
-			&card->dma);
+					   &card->dma);
 	if (!card->dma_p) {
 		pr_info("%s: No DMA memory\n", card->name);
 		return -ENOMEM;
@@ -344,9 +344,9 @@ inittiger(struct tiger_hw *card)
 
 	if (debug & DEBUG_HW)
 		pr_notice("%s: send buffer phy %#x - %#x - %#x  virt %p"
-			" size %zu u32\n", card->name,
-			card->send.dmastart, card->send.dmairq,
-			card->send.dmaend, card->send.start, card->send.size);
+			  " size %zu u32\n", card->name,
+			  card->send.dmastart, card->send.dmairq,
+			  card->send.dmaend, card->send.start, card->send.size);
 
 	outl(card->send.dmastart, card->base + NJ_DMA_READ_START);
 	outl(card->send.dmairq, card->base + NJ_DMA_READ_IRQ);
@@ -362,9 +362,9 @@ inittiger(struct tiger_hw *card)
 
 	if (debug & DEBUG_HW)
 		pr_notice("%s: recv buffer phy %#x - %#x - %#x  virt %p"
-			" size %zu u32\n", card->name,
-			card->recv.dmastart, card->recv.dmairq,
-			card->recv.dmaend, card->recv.start, card->recv.size);
+			  " size %zu u32\n", card->name,
+			  card->recv.dmastart, card->recv.dmairq,
+			  card->recv.dmaend, card->recv.start, card->recv.size);
 
 	outl(card->recv.dmastart, card->base + NJ_DMA_WRITE_START);
 	outl(card->recv.dmairq, card->base + NJ_DMA_WRITE_IRQ);
@@ -398,7 +398,7 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
 	if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
 		if ((bc->bch.rx_skb->len + cnt) > bc->bch.maxlen) {
 			pr_debug("%s: B%1d overrun %d\n", card->name,
-				bc->bch.nr, bc->bch.rx_skb->len + cnt);
+				 bc->bch.nr, bc->bch.rx_skb->len + cnt);
 			skb_trim(bc->bch.rx_skb, 0);
 			return;
 		}
@@ -418,8 +418,8 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
 next_frame:
 	if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
 		stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i,
-			bc->bch.rx_skb->data, bc->bch.maxlen);
-		if (stat > 0) /* valid frame received */ 
+				       bc->bch.rx_skb->data, bc->bch.maxlen);
+		if (stat > 0) /* valid frame received */
 			p = skb_put(bc->bch.rx_skb, stat);
 		else if (stat == -HDLC_CRC_ERROR)
 			pr_info("%s: B%1d receive frame CRC error\n",
@@ -431,14 +431,14 @@ next_frame:
 			pr_info("%s: B%1d receive frame too long (> %d)\n",
 				card->name, bc->bch.nr, bc->bch.maxlen);
 	} else
-		stat = cnt;	
+		stat = cnt;
 
 	if (stat > 0) {
 		if (debug & DEBUG_HW_BFIFO) {
 			snprintf(card->log, LOG_SIZE, "B%1d-recv %s %d ",
-				bc->bch.nr, card->name, stat);
+				 bc->bch.nr, card->name, stat);
 			print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET,
-				p, stat);
+					     p, stat);
 		}
 		recv_Bchannel(&bc->bch, 0);
 	}
@@ -447,7 +447,7 @@ next_frame:
 		cnt -= i;
 		if (!bc->bch.rx_skb) {
 			bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen,
-				GFP_ATOMIC);
+						      GFP_ATOMIC);
 			if (!bc->bch.rx_skb) {
 				pr_info("%s: B%1d receive out of memory\n",
 					card->name, bc->bch.nr);
@@ -498,7 +498,7 @@ resync(struct tiger_ch *bc, struct tiger_hw *card)
 		bc->idx = card->recv.size - 1;
 	bc->txstate = TX_RUN;
 	pr_debug("%s: %s B%1d free %d idx %d/%d\n", card->name,
-		__func__, bc->bch.nr, bc->free, bc->idx, card->send.idx);
+		 __func__, bc->bch.nr, bc->free, bc->idx, card->send.idx);
 }
 
 static int bc_next_frame(struct tiger_ch *);
@@ -514,14 +514,14 @@ fill_hdlc_flag(struct tiger_ch *bc)
 	if (bc->free == 0)
 		return;
 	pr_debug("%s: %s B%1d %d state %x idx %d/%d\n", card->name,
-		__func__, bc->bch.nr, bc->free, bc->txstate,
-		bc->idx, card->send.idx);
+		 __func__, bc->bch.nr, bc->free, bc->txstate,
+		 bc->idx, card->send.idx);
 	if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
 		resync(bc, card);
 	count = isdnhdlc_encode(&bc->hsend, NULL, 0, &i,
-			bc->hsbuf, bc->free);
+				bc->hsbuf, bc->free);
 	pr_debug("%s: B%1d hdlc encoded %d flags\n", card->name,
-			bc->bch.nr, count);
+		 bc->bch.nr, count);
 	bc->free -= count;
 	p = bc->hsbuf;
 	m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
@@ -535,7 +535,7 @@ fill_hdlc_flag(struct tiger_ch *bc)
 	}
 	if (debug & DEBUG_HW_BFIFO) {
 		snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
-			bc->bch.nr, card->name, count);
+			 bc->bch.nr, card->name, count);
 		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
 	}
 }
@@ -554,16 +554,16 @@ fill_dma(struct tiger_ch *bc)
 	if (count <= 0)
 		return;
 	pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", card->name,
-		__func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx,
-		bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx);
+		 __func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx,
+		 bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx);
 	if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
 		resync(bc, card);
 	p = bc->bch.tx_skb->data + bc->bch.tx_idx;
 	if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
 		count = isdnhdlc_encode(&bc->hsend, p, count, &i,
-			bc->hsbuf, bc->free);
+					bc->hsbuf, bc->free);
 		pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name,
-			bc->bch.nr, i, count);
+			 bc->bch.nr, i, count);
 		bc->bch.tx_idx += i;
 		bc->free -= count;
 		p = bc->hsbuf;
@@ -584,7 +584,7 @@ fill_dma(struct tiger_ch *bc)
 	}
 	if (debug & DEBUG_HW_BFIFO) {
 		snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
-			bc->bch.nr, card->name, count);
+			 bc->bch.nr, card->name, count);
 		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
 	}
 	if (bc->free)
@@ -633,7 +633,7 @@ send_tiger_bc(struct tiger_hw *card, struct tiger_ch *bc)
 			return;
 		}
 		pr_debug("%s: B%1d TX no data free %d idx %d/%d\n", card->name,
-			bc->bch.nr, bc->free, bc->idx, card->send.idx);
+			 bc->bch.nr, bc->free, bc->idx, card->send.idx);
 		if (!(bc->txstate & (TX_IDLE | TX_INIT))) {
 			fill_mem(bc, bc->idx, bc->free, 0xff);
 			if (bc->free == card->send.size)
@@ -706,8 +706,8 @@ nj_irq(int intno, void *dev_id)
 		s0val |= 0x01;	/* the 1st read area is free */
 
 	pr_debug("%s: DMA Status %02x/%02x/%02x %d/%d\n", card->name,
-		s1val, s0val, card->last_is0,
-		card->recv.idx, card->send.idx);
+		 s1val, s0val, card->last_is0,
+		 card->recv.idx, card->send.idx);
 	/* test if we have a DMA interrupt */
 	if (s0val != card->last_is0) {
 		if ((s0val & NJ_IRQM0_RD_MASK) !=
@@ -758,7 +758,7 @@ nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(&card->lock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				NULL, GFP_KERNEL);
+				    NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		spin_lock_irqsave(&card->lock, flags);
@@ -766,7 +766,7 @@ nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		mode_tiger(bc, ISDN_P_NONE);
 		spin_unlock_irqrestore(&card->lock, flags);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	}
@@ -785,7 +785,7 @@ channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_GETOP:
 		cq->op = 0;
 		break;
-	/* Nothing implemented yet */
+		/* Nothing implemented yet */
 	case MISDN_CTRL_FILL_EMPTY:
 	default:
 		pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
@@ -900,7 +900,7 @@ nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	case CLOSE_CHANNEL:
 		pr_debug("%s: dev(%d) close from %p\n", card->name, dch->dev.id,
-			__builtin_return_address(0));
+			 __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -908,7 +908,7 @@ nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	default:
 		pr_debug("%s: %s unknown command %x\n",
-			card->name, __func__, cmd);
+			 card->name, __func__, cmd);
 		return -EINVAL;
 	}
 	return err;
@@ -968,7 +968,7 @@ nj_release(struct tiger_hw *card)
 		free_irq(card->irq, card);
 	if (card->isac.dch.dev.dev.class)
 		mISDN_unregister_device(&card->isac.dch.dev);
-	
+
 	for (i = 0; i < 2; i++) {
 		mISDN_freebchannel(&card->bc[i].bch);
 		kfree(card->bc[i].hsbuf);
@@ -976,7 +976,7 @@ nj_release(struct tiger_hw *card)
 	}
 	if (card->dma_p)
 		pci_free_consistent(card->pdev, NJ_DMA_SIZE,
-			card->dma_p, card->dma);
+				    card->dma_p, card->dma);
 	write_lock_irqsave(&card_lock, flags);
 	list_del(&card->list);
 	write_unlock_irqrestore(&card_lock, flags);
@@ -1033,14 +1033,14 @@ setup_instance(struct tiger_hw *card)
 		card->bc[i].bch.ch.ctrl = nj_bctrl;
 		card->bc[i].bch.ch.nr = i + 1;
 		list_add(&card->bc[i].bch.ch.list,
-			&card->isac.dch.dev.bchannels);
+			 &card->isac.dch.dev.bchannels);
 		card->bc[i].bch.hw = card;
 	}
 	err = nj_setup(card);
 	if (err)
 		goto error;
 	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
-		card->name);
+				    card->name);
 	if (err)
 		goto error;
 	err = nj_init_card(card);
@@ -1074,7 +1074,7 @@ nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	if (pdev->subsystem_vendor == 0xb100 &&
-	    pdev->subsystem_device == 0x0003 ) {
+	    pdev->subsystem_device == 0x0003) {
 		pr_notice("Netjet: Digium TDM400P not handled yet\n");
 		return -ENODEV;
 	}
@@ -1094,7 +1094,7 @@ nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	printk(KERN_INFO "nj_probe(mISDN): found adapter at %s\n",
-		pci_name(pdev));
+	       pci_name(pdev));
 
 	pci_set_master(pdev);
 
diff --git a/drivers/isdn/hardware/mISDN/netjet.h b/drivers/isdn/hardware/mISDN/netjet.h
index d061ff9..ddd41ef 100644
--- a/drivers/isdn/hardware/mISDN/netjet.h
+++ b/drivers/isdn/hardware/mISDN/netjet.h
@@ -55,4 +55,3 @@
 /* 2 * 64 byte is a compromise between IRQ count and latency */
 #define NJ_DMA_RXSIZE		128  /* 2 * 64 */
 #define NJ_DMA_TXSIZE		128  /* 2 * 64 */
-
diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
index 4d0d41e..0468993 100644
--- a/drivers/isdn/hardware/mISDN/speedfax.c
+++ b/drivers/isdn/hardware/mISDN/speedfax.c
@@ -147,10 +147,10 @@ Start_ISAR:
 		goto Start_ISAR;
 	if (cnt < irqloops)
 		pr_debug("%s: %d irqloops cpu%d\n", sf->name,
-			irqloops - cnt, smp_processor_id());
+			 irqloops - cnt, smp_processor_id());
 	if (irqloops && !cnt)
 		pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
-			irqloops, smp_processor_id());
+			  irqloops, smp_processor_id());
 	spin_unlock(&sf->lock);
 	return IRQ_HANDLED;
 }
@@ -266,7 +266,7 @@ sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	case CLOSE_CHANNEL:
 		pr_debug("%s: dev(%d) close from %p\n", sf->name,
-			dch->dev.id, __builtin_return_address(0));
+			 dch->dev.id, __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -306,10 +306,10 @@ init_card(struct sfax_hw *sf)
 		msleep_interruptible(10);
 		if (debug & DEBUG_HW)
 			pr_notice("%s: IRQ %d count %d\n", sf->name,
-				sf->irq, sf->irqcnt);
+				  sf->irq, sf->irqcnt);
 		if (!sf->irqcnt) {
 			pr_info("%s: IRQ(%d) got no requests during init %d\n",
-			       sf->name, sf->irq, 3 - cnt);
+				sf->name, sf->irq, 3 - cnt);
 		} else
 			return 0;
 	}
@@ -325,7 +325,7 @@ setup_speedfax(struct sfax_hw *sf)
 
 	if (!request_region(sf->cfg, 256, sf->name)) {
 		pr_info("mISDN: %s config port %x-%x already in use\n",
-		       sf->name, sf->cfg, sf->cfg + 255);
+			sf->name, sf->cfg, sf->cfg + 255);
 		return -EIO;
 	}
 	outb(0xff, sf->cfg);
@@ -396,7 +396,7 @@ setup_instance(struct sfax_hw *card)
 	}
 	if (debug & DEBUG_HW)
 		pr_notice("%s: got firmware %zu bytes\n",
-			card->name, firmware->size);
+			  card->name, firmware->size);
 
 	mISDNisac_init(&card->isac, card);
 
@@ -406,7 +406,7 @@ setup_instance(struct sfax_hw *card)
 	for (i = 0; i < 2; i++) {
 		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
 		list_add(&card->isar.ch[i].bch.ch.list,
-			&card->isac.dch.dev.bchannels);
+			 &card->isac.dch.dev.bchannels);
 	}
 
 	err = setup_speedfax(card);
@@ -416,7 +416,7 @@ setup_instance(struct sfax_hw *card)
 	if (err)
 		goto error;
 	err = mISDN_register_device(&card->isac.dch.dev,
-		&card->pdev->dev, card->name);
+				    &card->pdev->dev, card->name);
 	if (err)
 		goto error;
 	err = init_card(card);
@@ -466,7 +466,7 @@ sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	pr_notice("mISDN: Speedfax found adapter %s at %s\n",
-		(char *)ent->driver_data, pci_name(pdev));
+		  (char *)ent->driver_data, pci_name(pdev));
 
 	card->cfg = pci_resource_start(pdev, 0);
 	card->irq = pdev->irq;
@@ -514,7 +514,7 @@ Speedfax_init(void)
 	int err;
 
 	pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
-		SPEEDFAX_REV);
+		  SPEEDFAX_REV);
 	err = pci_register_driver(&sfaxpci_driver);
 	return err;
 }
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index e10e028..7f1e7ba 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -171,7 +171,7 @@ W6692Version(struct w6692_hw *card)
 
 	val = ReadW6692(card, W_D_RBCH);
 	pr_notice("%s: Winbond W6692 version: %s\n", card->name,
-		W6692Ver[(val >> 6) & 3]);
+		  W6692Ver[(val >> 6) & 3]);
 }
 
 static void
@@ -248,7 +248,7 @@ W6692_ph_bh(struct dchannel *dch)
 		break;
 	default:
 		pr_debug("%s: TE unknown state %02x dch state %02x\n",
-			card->name, card->state, dch->state);
+			 card->name, card->state, dch->state);
 		break;
 	}
 	pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
@@ -271,7 +271,7 @@ W6692_empty_Dfifo(struct w6692_hw *card, int count)
 	}
 	if ((dch->rx_skb->len + count) >= dch->maxlen) {
 		pr_debug("%s: empty_Dfifo overrun %d\n", card->name,
-			dch->rx_skb->len + count);
+			 dch->rx_skb->len + count);
 		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
 		return;
 	}
@@ -280,7 +280,7 @@ W6692_empty_Dfifo(struct w6692_hw *card, int count)
 	WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
 	if (debug & DEBUG_HW_DFIFO) {
 		snprintf(card->log, 63, "D-recv %s %d ",
-			card->name, count);
+			 card->name, count);
 		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 	}
 }
@@ -312,11 +312,11 @@ W6692_fill_Dfifo(struct w6692_hw *card)
 		del_timer(&dch->timer);
 	}
 	init_timer(&dch->timer);
-	dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
+	dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000);
 	add_timer(&dch->timer);
 	if (debug & DEBUG_HW_DFIFO) {
 		snprintf(card->log, 63, "D-send %s %d ",
-			card->name, count);
+			 card->name, count);
 		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 	}
 }
@@ -426,7 +426,7 @@ handle_statusD(struct w6692_hw *card)
 	if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
 		v1 = ReadW6692(card, W_MOSR);
 		pr_debug("%s: spurious MOC interrupt MOSR %02x\n",
-			card->name, v1);
+			 card->name, v1);
 	}
 	if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
 		cir = ReadW6692(card, W_CIR);
@@ -434,7 +434,7 @@ handle_statusD(struct w6692_hw *card)
 		if (cir & W_CIR_ICC) {
 			v1 = cir & W_CIR_COD_MASK;
 			pr_debug("%s: ph_state_change %x -> %x\n", card->name,
-				dch->state, v1);
+				 dch->state, v1);
 			card->state = v1;
 			if (card->fmask & led) {
 				switch (v1) {
@@ -479,13 +479,13 @@ W6692_empty_Bfifo(struct w6692_ch *wch, int count)
 		if (unlikely(!wch->bch.rx_skb)) {
 			pr_info("%s: B receive out of memory\n", card->name);
 			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				W_B_CMDR_RACT);
+				    W_B_CMDR_RACT);
 			return;
 		}
 	}
 	if (wch->bch.rx_skb->len + count > wch->bch.maxlen) {
 		pr_debug("%s: empty_Bfifo incoming packet too large\n",
-			card->name);
+			 card->name);
 		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
 		skb_trim(wch->bch.rx_skb, 0);
 		return;
@@ -495,7 +495,7 @@ W6692_empty_Bfifo(struct w6692_ch *wch, int count)
 	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
 	if (debug & DEBUG_HW_DFIFO) {
 		snprintf(card->log, 63, "B%1d-recv %s %d ",
-			wch->bch.nr, card->name, count);
+			 wch->bch.nr, card->name, count);
 		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 	}
 }
@@ -520,13 +520,13 @@ W6692_fill_Bfifo(struct w6692_ch *wch)
 		cmd |= W_B_CMDR_XME;
 
 	pr_debug("%s: fill Bfifo%d/%d\n", card->name,
-			count, wch->bch.tx_idx);
+		 count, wch->bch.tx_idx);
 	wch->bch.tx_idx += count;
 	outsb(wch->addr + W_B_XFIFO, ptr, count);
 	WriteW6692B(wch, W_B_CMDR, cmd);
 	if (debug & DEBUG_HW_DFIFO) {
 		snprintf(card->log, 63, "B%1d-send %s %d ",
-			wch->bch.nr, card->name, count);
+			 wch->bch.nr, card->name, count);
 		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
 	}
 }
@@ -586,7 +586,7 @@ disable_pots(struct w6692_ch *wch)
 	wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0);
 	WriteW6692B(wch, W_B_MODE, wch->b_mode);
 	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
-		W_B_CMDR_XRST);
+		    W_B_CMDR_XRST);
 	return 0;
 }
 
@@ -597,7 +597,7 @@ w6692_mode(struct w6692_ch *wch, u32 pr)
 
 	card = wch->bch.hw;
 	pr_debug("%s: B%d protocol %x-->%x\n", card->name,
-		wch->bch.nr, wch->bch.state, pr);
+		 wch->bch.nr, wch->bch.state, pr);
 	switch (pr) {
 	case ISDN_P_NONE:
 		if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM))
@@ -614,7 +614,7 @@ w6692_mode(struct w6692_ch *wch, u32 pr)
 		WriteW6692B(wch, W_B_MODE, wch->b_mode);
 		WriteW6692B(wch, W_B_EXIM, 0);
 		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
-			W_B_CMDR_XRST);
+			    W_B_CMDR_XRST);
 		test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags);
 		break;
 	case ISDN_P_B_HDLC:
@@ -624,7 +624,7 @@ w6692_mode(struct w6692_ch *wch, u32 pr)
 		WriteW6692B(wch, W_B_ADM2, 0xff);
 		WriteW6692B(wch, W_B_EXIM, 0);
 		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
-			W_B_CMDR_XRST);
+			    W_B_CMDR_XRST);
 		test_and_set_bit(FLG_HDLC, &wch->bch.Flags);
 		break;
 	default:
@@ -667,7 +667,7 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
 			if ((star & W_B_STAR_RDOV) &&
 			    test_bit(FLG_ACTIVE, &wch->bch.Flags)) {
 				pr_debug("%s: B%d RDOV proto=%x\n", card->name,
-					wch->bch.nr, wch->bch.state);
+					 wch->bch.nr, wch->bch.state);
 #ifdef ERROR_STATISTIC
 				wch->bch.err_rdo++;
 #endif
@@ -675,21 +675,21 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
 			if (test_bit(FLG_HDLC, &wch->bch.Flags)) {
 				if (star & W_B_STAR_CRCE) {
 					pr_debug("%s: B%d CRC error\n",
-						card->name, wch->bch.nr);
+						 card->name, wch->bch.nr);
 #ifdef ERROR_STATISTIC
 					wch->bch.err_crc++;
 #endif
 				}
 				if (star & W_B_STAR_RMB) {
 					pr_debug("%s: B%d message abort\n",
-						card->name, wch->bch.nr);
+						 card->name, wch->bch.nr);
 #ifdef ERROR_STATISTIC
 					wch->bch.err_inv++;
 #endif
 				}
 			}
 			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				W_B_CMDR_RRST | W_B_CMDR_RACT);
+				    W_B_CMDR_RRST | W_B_CMDR_RACT);
 			if (wch->bch.rx_skb)
 				skb_trim(wch->bch.rx_skb, 0);
 		} else {
@@ -706,12 +706,12 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
 			star = ReadW6692B(wch, W_B_STAR);
 		if (star & W_B_STAR_RDOV) {
 			pr_debug("%s: B%d RDOV proto=%x\n", card->name,
-				wch->bch.nr, wch->bch.state);
+				 wch->bch.nr, wch->bch.state);
 #ifdef ERROR_STATISTIC
 			wch->bch.err_rdo++;
 #endif
 			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				W_B_CMDR_RRST | W_B_CMDR_RACT);
+				    W_B_CMDR_RRST | W_B_CMDR_RACT);
 		} else {
 			W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
 			if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags) &&
@@ -723,28 +723,28 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
 		/* only if it is not handled yet */
 		if (!(star & W_B_STAR_RDOV)) {
 			pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name,
-				wch->bch.nr, wch->bch.state);
+				 wch->bch.nr, wch->bch.state);
 #ifdef ERROR_STATISTIC
 			wch->bch.err_rdo++;
 #endif
 			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
-				W_B_CMDR_RRST | W_B_CMDR_RACT);
+				    W_B_CMDR_RRST | W_B_CMDR_RACT);
 		}
 	}
 	if (stat & W_B_EXI_XFR) {
 		if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) {
 			star = ReadW6692B(wch, W_B_STAR);
 			pr_debug("%s: B%d star %02x\n", card->name,
-				wch->bch.nr, star);
+				 wch->bch.nr, star);
 		}
 		if (star & W_B_STAR_XDOW) {
 			pr_debug("%s: B%d XDOW proto=%x\n", card->name,
-				wch->bch.nr, wch->bch.state);
+				 wch->bch.nr, wch->bch.state);
 #ifdef ERROR_STATISTIC
 			wch->bch.err_xdu++;
 #endif
 			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST |
-				W_B_CMDR_RACT);
+				    W_B_CMDR_RACT);
 			/* resend */
 			if (wch->bch.tx_skb) {
 				if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
@@ -757,7 +757,7 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
 	}
 	if (stat & W_B_EXI_XDUN) {
 		pr_debug("%s: B%d XDUN proto=%x\n", card->name,
-			wch->bch.nr, wch->bch.state);
+			 wch->bch.nr, wch->bch.state);
 #ifdef ERROR_STATISTIC
 		wch->bch.err_xdu++;
 #endif
@@ -818,7 +818,7 @@ dbusy_timer_handler(struct dchannel *dch)
 		rbch = ReadW6692(card, W_D_RBCH);
 		star = ReadW6692(card, W_D_STAR);
 		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
-			card->name, rbch, star);
+			 card->name, rbch, star);
 		if (star & W_D_STAR_XBZ)	/* D-Channel Busy */
 			test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
 		else {
@@ -888,7 +888,7 @@ void initW6692(struct w6692_hw *card)
 			val = ReadW6692(card, W_XADDR);
 			if (debug & DEBUG_HW)
 				pr_notice("%s: W_XADDR=%02x\n",
-					card->name, val);
+					  card->name, val);
 		}
 	}
 }
@@ -924,7 +924,7 @@ init_card(struct w6692_hw *card)
 		msleep_interruptible(10);
 		if (debug & DEBUG_HW)
 			pr_notice("%s: IRQ %d count %d\n", card->name,
-				card->irq, card->irqcnt);
+				  card->irq, card->irqcnt);
 		if (!card->irqcnt) {
 			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
 				card->name, card->irq, 3 - cnt);
@@ -970,7 +970,7 @@ w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		spin_unlock_irqrestore(&card->lock, flags);
 		if (!ret)
 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-				NULL, GFP_KERNEL);
+				    NULL, GFP_KERNEL);
 		break;
 	case PH_DEACTIVATE_REQ:
 		spin_lock_irqsave(&card->lock, flags);
@@ -978,7 +978,7 @@ w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
 		w6692_mode(bc, ISDN_P_NONE);
 		spin_unlock_irqrestore(&card->lock, flags);
 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 		ret = 0;
 		break;
 	default:
@@ -1000,7 +1000,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_GETOP:
 		cq->op = 0;
 		break;
-	/* Nothing implemented yet */
+		/* Nothing implemented yet */
 	case MISDN_CTRL_FILL_EMPTY:
 	default:
 		pr_info("%s: unknown Op %x\n", __func__, cq->op);
@@ -1168,16 +1168,16 @@ w6692_l1callback(struct dchannel *dch, u32 cmd)
 	case PH_ACTIVATE_IND:
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	case PH_DEACTIVATE_IND:
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
-			GFP_ATOMIC);
+			    GFP_ATOMIC);
 		break;
 	default:
 		pr_debug("%s: %s unknown command %x\n", card->name,
-			__func__, cmd);
+			 __func__, cmd);
 		return -1;
 	}
 	return 0;
@@ -1187,7 +1187,7 @@ static int
 open_dchannel(struct w6692_hw *card, struct channel_req *rq)
 {
 	pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
-		card->dch.dev.id, __builtin_return_address(1));
+		 card->dch.dev.id, __builtin_return_address(1));
 	if (rq->protocol != ISDN_P_TE_S0)
 		return -EINVAL;
 	if (rq->adr.channel == 1)
@@ -1197,7 +1197,7 @@ open_dchannel(struct w6692_hw *card, struct channel_req *rq)
 	rq->ch->protocol = rq->protocol;
 	if (card->dch.state == 7)
 		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
-		    0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 	return 0;
 }
 
@@ -1225,7 +1225,7 @@ w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
 		break;
 	case CLOSE_CHANNEL:
 		pr_debug("%s: dev(%d) close from %p\n", card->name,
-			dch->dev.id, __builtin_return_address(0));
+			 dch->dev.id, __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -1245,7 +1245,7 @@ setup_w6692(struct w6692_hw *card)
 
 	if (!request_region(card->addr, 256, card->name)) {
 		pr_info("%s: config port %x-%x already in use\n", card->name,
-		       card->addr, card->addr + 255);
+			card->addr, card->addr + 255);
 		return -EIO;
 	}
 	W6692Version(card);
@@ -1333,7 +1333,7 @@ setup_instance(struct w6692_hw *card)
 	if (err)
 		goto error_setup;
 	err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
-		card->name);
+				    card->name);
 	if (err)
 		goto error_reg;
 	err = init_card(card);
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 5d72783..89342f7 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -101,26 +101,26 @@ static WORD initAMD[] = {
 static void /* macro wWordAMD */
 WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
 {
-        wByteAMD(cs, 0x00, reg);
-        wByteAMD(cs, 0x01, LOBYTE(val));
-        wByteAMD(cs, 0x01, HIBYTE(val));
+	wByteAMD(cs, 0x00, reg);
+	wByteAMD(cs, 0x01, LOBYTE(val));
+	wByteAMD(cs, 0x01, HIBYTE(val));
 }
 
 static WORD /* macro rWordAMD */
 ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
 {
-        WORD res;
-        /* direct access register */
-        if(reg < 8) {
-        	res = rByteAMD(cs, reg);
-                res += 256*rByteAMD(cs, reg);
-        }
-        /* indirect access register */
-        else {
-                wByteAMD(cs, 0x00, reg);
-	        res = rByteAMD(cs, 0x01);
-                res += 256*rByteAMD(cs, 0x01);
-        }
+	WORD res;
+	/* direct access register */
+	if (reg < 8) {
+		res = rByteAMD(cs, reg);
+		res += 256 * rByteAMD(cs, reg);
+	}
+	/* indirect access register */
+	else {
+		wByteAMD(cs, 0x00, reg);
+		res = rByteAMD(cs, 0x01);
+		res += 256 * rByteAMD(cs, 0x01);
+	}
 	return (res);
 }
 
@@ -131,23 +131,23 @@ Amd7930_ph_command(struct IsdnCardState *cs, u_char command, char *s)
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "AMD7930: %s: ph_command 0x%02X", s, command);
 
-        cs->dc.amd7930.lmr1 = command;
-        wByteAMD(cs, 0xA3, command);
+	cs->dc.amd7930.lmr1 = command;
+	wByteAMD(cs, 0xA3, command);
 }
 
 
 
 static BYTE i430States[] = {
 // to   reset  F3    F4    F5    F6    F7    F8    AR     from
-        0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // init
-        0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // reset
-        0x01, 0x02, 0x00, 0x00, 0x00, 0x09, 0x05, 0x04,   // F3
-        0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,   // F4
-        0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,   // F5
-        0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00,   // F6
-        0x11, 0x13, 0x00, 0x00, 0x1B, 0x00, 0x15, 0x00,   // F7
-        0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,   // F8
-        0x01, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0A};  // AR
+	0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // init
+	0x01, 0x02, 0x00, 0x00, 0x00, 0x07, 0x05, 0x00,   // reset
+	0x01, 0x02, 0x00, 0x00, 0x00, 0x09, 0x05, 0x04,   // F3
+	0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,   // F4
+	0x01, 0x02, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,   // F5
+	0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x05, 0x00,   // F6
+	0x11, 0x13, 0x00, 0x00, 0x1B, 0x00, 0x15, 0x00,   // F7
+	0x01, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,   // F8
+	0x01, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0x0A};  // AR
 
 
 /*                    Row     init    -   reset  F3    F4    F5    F6    F7    F8    AR */
@@ -158,9 +158,9 @@ static BYTE stateHelper[] = { 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x
 
 static void
 Amd7930_get_state(struct IsdnCardState *cs) {
-        BYTE lsr = rByteAMD(cs, 0xA1);
-        cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
-        Amd7930_new_ph(cs);
+	BYTE lsr = rByteAMD(cs, 0xA1);
+	cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
+	Amd7930_new_ph(cs);
 }
 
 
@@ -168,65 +168,65 @@ Amd7930_get_state(struct IsdnCardState *cs) {
 static void
 Amd7930_new_ph(struct IsdnCardState *cs)
 {
-        u_char index = stateHelper[cs->dc.amd7930.old_state]*8 + stateHelper[cs->dc.amd7930.ph_state]-1;
-        u_char message = i430States[index];
+	u_char index = stateHelper[cs->dc.amd7930.old_state] * 8 + stateHelper[cs->dc.amd7930.ph_state] - 1;
+	u_char message = i430States[index];
 
-        if (cs->debug & L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "AMD7930: new_ph %d, old_ph %d, message %d, index %d",
-                        cs->dc.amd7930.ph_state, cs->dc.amd7930.old_state, message & 0x0f, index);
+			cs->dc.amd7930.ph_state, cs->dc.amd7930.old_state, message & 0x0f, index);
 
-        cs->dc.amd7930.old_state = cs->dc.amd7930.ph_state;
+	cs->dc.amd7930.old_state = cs->dc.amd7930.ph_state;
 
-        /* abort transmit if nessesary */
-        if ((message & 0xf0) && (cs->tx_skb)) {
-                wByteAMD(cs, 0x21, 0xC2);
-                wByteAMD(cs, 0x21, 0x02);
-        }
+	/* abort transmit if nessesary */
+	if ((message & 0xf0) && (cs->tx_skb)) {
+		wByteAMD(cs, 0x21, 0xC2);
+		wByteAMD(cs, 0x21, 0x02);
+	}
 
 	switch (message & 0x0f) {
 
-                case (1):
-                        l1_msg(cs, HW_RESET | INDICATION, NULL);
-                        Amd7930_get_state(cs);
-                        break;
-                case (2): /* init, Card starts in F3 */
-                        l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
-                        break;
-                case (3):
-                        l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-                        break;
-                case (4):
-                        l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-                        Amd7930_ph_command(cs, 0x50, "HW_ENABLE REQUEST");
-                        break;
-                case (5):
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-                        break;
-                case (6):
-			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-                        break;
-                case (7): /* init, Card starts in F7 */
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-                        break;
-                case (8):
-                        l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-                        /* fall through */
-                case (9):
-                        Amd7930_ph_command(cs, 0x40, "HW_ENABLE REQ cleared if set");
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-                        break;
-                case (10):
-                        Amd7930_ph_command(cs, 0x40, "T3 expired, HW_ENABLE REQ cleared");
-                        cs->dc.amd7930.old_state = 3;
-                        break;
-                case (11):
-			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-                        break;
-		default:
-			break;
+	case (1):
+		l1_msg(cs, HW_RESET | INDICATION, NULL);
+		Amd7930_get_state(cs);
+		break;
+	case (2): /* init, Card starts in F3 */
+		l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
+		break;
+	case (3):
+		l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+		break;
+	case (4):
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		Amd7930_ph_command(cs, 0x50, "HW_ENABLE REQUEST");
+		break;
+	case (5):
+		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+		break;
+	case (6):
+		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+		break;
+	case (7): /* init, Card starts in F7 */
+		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+		break;
+	case (8):
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		/* fall through */
+	case (9):
+		Amd7930_ph_command(cs, 0x40, "HW_ENABLE REQ cleared if set");
+		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+		break;
+	case (10):
+		Amd7930_ph_command(cs, 0x40, "T3 expired, HW_ENABLE REQ cleared");
+		cs->dc.amd7930.old_state = 3;
+		break;
+	case (11):
+		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -237,10 +237,10 @@ Amd7930_bh(struct work_struct *work)
 {
 	struct IsdnCardState *cs =
 		container_of(work, struct IsdnCardState, tqueue);
-        struct PStack *stptr;
+	struct PStack *stptr;
 
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
-                if (cs->debug)
+		if (cs->debug)
 			debugl1(cs, "Amd7930: bh, D-Channel Busy cleared");
 		stptr = cs->stlist;
 		while (stptr != NULL) {
@@ -249,29 +249,29 @@ Amd7930_bh(struct work_struct *work)
 		}
 	}
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
-	        if (cs->debug & L1_DEB_ISAC)
-		        debugl1(cs, "AMD7930: bh, D_L1STATECHANGE");
-                Amd7930_new_ph(cs);
-        }
-
-        if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
-	        if (cs->debug & L1_DEB_ISAC)
-		        debugl1(cs, "AMD7930: bh, D_RCVBUFREADY");
-                DChannel_proc_rcv(cs);
-        }
-
-        if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
-	        if (cs->debug & L1_DEB_ISAC)
-		        debugl1(cs, "AMD7930: bh, D_XMTBUFREADY");
-                DChannel_proc_xmt(cs);
-        }
+		if (cs->debug & L1_DEB_ISAC)
+			debugl1(cs, "AMD7930: bh, D_L1STATECHANGE");
+		Amd7930_new_ph(cs);
+	}
+
+	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
+		if (cs->debug & L1_DEB_ISAC)
+			debugl1(cs, "AMD7930: bh, D_RCVBUFREADY");
+		DChannel_proc_rcv(cs);
+	}
+
+	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
+		if (cs->debug & L1_DEB_ISAC)
+			debugl1(cs, "AMD7930: bh, D_XMTBUFREADY");
+		DChannel_proc_xmt(cs);
+	}
 }
 
 static void
 Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag)
 {
 
-        BYTE stat, der;
+	BYTE stat, der;
 	BYTE *ptr;
 	struct sk_buff *skb;
 
@@ -288,54 +288,54 @@ Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag)
 	/* read D-Channel-Fifo*/
 	stat = rByteAMD(cs, 0x07); // DSR2
 
-		/* while Data in Fifo ... */
-		while ( (stat & 2) && ((ptr-cs->rcvbuf) < MAX_DFRAME_LEN_L1) ) {
-			*ptr = rByteAMD(cs, 0x04); // DCRB
-			ptr++;
-	                stat = rByteAMD(cs, 0x07); // DSR2
-			cs->rcvidx = ptr - cs->rcvbuf;
-
-                        /* Paket ready? */
-			if (stat & 1) {
-
-                                der = rWordAMD(cs, 0x03);
-
-                                /* no errors, packet ok */
-                                if(!der && !flag) {
-					rWordAMD(cs, 0x89); // clear DRCR
-
-                                        if ((cs->rcvidx) > 0) {
-                                                if (!(skb = alloc_skb(cs->rcvidx, GFP_ATOMIC)))
-							printk(KERN_WARNING "HiSax: Amd7930: empty_Dfifo, D receive out of memory!\n");
-						else {
-                                                        /* Debugging */
-                                                        if (cs->debug & L1_DEB_ISAC_FIFO) {
-								char *t = cs->dlog;
-
-								t += sprintf(t, "Amd7930: empty_Dfifo cnt: %d |", cs->rcvidx);
-								QuickHex(t, cs->rcvbuf, cs->rcvidx);
-								debugl1(cs, cs->dlog);
-							}
-                                                        /* moves received data in sk-buffer */
-							memcpy(skb_put(skb, cs->rcvidx), cs->rcvbuf, cs->rcvidx);
-							skb_queue_tail(&cs->rq, skb);
+	/* while Data in Fifo ... */
+	while ((stat & 2) && ((ptr-cs->rcvbuf) < MAX_DFRAME_LEN_L1)) {
+		*ptr = rByteAMD(cs, 0x04); // DCRB
+		ptr++;
+		stat = rByteAMD(cs, 0x07); // DSR2
+		cs->rcvidx = ptr - cs->rcvbuf;
+
+		/* Paket ready? */
+		if (stat & 1) {
+
+			der = rWordAMD(cs, 0x03);
+
+			/* no errors, packet ok */
+			if (!der && !flag) {
+				rWordAMD(cs, 0x89); // clear DRCR
+
+				if ((cs->rcvidx) > 0) {
+					if (!(skb = alloc_skb(cs->rcvidx, GFP_ATOMIC)))
+						printk(KERN_WARNING "HiSax: Amd7930: empty_Dfifo, D receive out of memory!\n");
+					else {
+						/* Debugging */
+						if (cs->debug & L1_DEB_ISAC_FIFO) {
+							char *t = cs->dlog;
+
+							t += sprintf(t, "Amd7930: empty_Dfifo cnt: %d |", cs->rcvidx);
+							QuickHex(t, cs->rcvbuf, cs->rcvidx);
+							debugl1(cs, cs->dlog);
 						}
+						/* moves received data in sk-buffer */
+						memcpy(skb_put(skb, cs->rcvidx), cs->rcvbuf, cs->rcvidx);
+						skb_queue_tail(&cs->rq, skb);
 					}
-
 				}
-                                /* throw damaged packets away, reset receive-buffer, indicate RX */
-				ptr = cs->rcvbuf;
-				cs->rcvidx = 0;
-				schedule_event(cs, D_RCVBUFREADY);
+
 			}
-                }
-		/* Packet to long, overflow */
-		if(cs->rcvidx >= MAX_DFRAME_LEN_L1) {
-			if (cs->debug & L1_DEB_WARN)
-			        debugl1(cs, "AMD7930: empty_Dfifo L2-Framelength overrun");
+			/* throw damaged packets away, reset receive-buffer, indicate RX */
+			ptr = cs->rcvbuf;
 			cs->rcvidx = 0;
-			return;
+			schedule_event(cs, D_RCVBUFREADY);
 		}
+	}
+	/* Packet to long, overflow */
+	if (cs->rcvidx >= MAX_DFRAME_LEN_L1) {
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "AMD7930: empty_Dfifo L2-Framelength overrun");
+		cs->rcvidx = 0;
+		return;
+	}
 	/* AMD interrupts on */
 	AmdIrqOn(cs);
 }
@@ -345,9 +345,9 @@ static void
 Amd7930_fill_Dfifo(struct IsdnCardState *cs)
 {
 
-        WORD dtcrr, dtcrw, len, count;
-        BYTE txstat, dmr3;
-        BYTE *ptr, *deb_ptr;
+	WORD dtcrr, dtcrw, len, count;
+	BYTE txstat, dmr3;
+	BYTE *ptr, *deb_ptr;
 
 	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
 		debugl1(cs, "Amd7930: fill_Dfifo");
@@ -355,43 +355,43 @@ Amd7930_fill_Dfifo(struct IsdnCardState *cs)
 	if ((!cs->tx_skb) || (cs->tx_skb->len <= 0))
 		return;
 
-        dtcrw = 0;
-        if(!cs->dc.amd7930.tx_xmtlen)
-                /* new Frame */
-                len = dtcrw = cs->tx_skb->len;
-        /* continue frame */
-        else len = cs->dc.amd7930.tx_xmtlen;
+	dtcrw = 0;
+	if (!cs->dc.amd7930.tx_xmtlen)
+		/* new Frame */
+		len = dtcrw = cs->tx_skb->len;
+	/* continue frame */
+	else len = cs->dc.amd7930.tx_xmtlen;
 
 
 	/* AMD interrupts off */
 	AmdIrqOff(cs);
 
-        deb_ptr = ptr = cs->tx_skb->data;
-
-        /* while free place in tx-fifo available and data in sk-buffer */
-        txstat = 0x10;
-        while((txstat & 0x10) && (cs->tx_cnt < len)) {
-                wByteAMD(cs, 0x04, *ptr);
-                ptr++;
-                cs->tx_cnt++;
-                txstat= rByteAMD(cs, 0x07);
-        }
-        count = ptr - cs->tx_skb->data;
+	deb_ptr = ptr = cs->tx_skb->data;
+
+	/* while free place in tx-fifo available and data in sk-buffer */
+	txstat = 0x10;
+	while ((txstat & 0x10) && (cs->tx_cnt < len)) {
+		wByteAMD(cs, 0x04, *ptr);
+		ptr++;
+		cs->tx_cnt++;
+		txstat = rByteAMD(cs, 0x07);
+	}
+	count = ptr - cs->tx_skb->data;
 	skb_pull(cs->tx_skb, count);
 
 
-        dtcrr = rWordAMD(cs, 0x85); // DTCR
-        dmr3  = rByteAMD(cs, 0x8E);
+	dtcrr = rWordAMD(cs, 0x85); // DTCR
+	dmr3  = rByteAMD(cs, 0x8E);
 
 	if (cs->debug & L1_DEB_ISAC) {
 		debugl1(cs, "Amd7930: fill_Dfifo, DMR3: 0x%02X, DTCR read: 0x%04X write: 0x%02X 0x%02X", dmr3, dtcrr, LOBYTE(dtcrw), HIBYTE(dtcrw));
-        }
+	}
 
-        /* writeing of dtcrw starts transmit */
-        if(!cs->dc.amd7930.tx_xmtlen) {
-                wWordAMD(cs, 0x85, dtcrw);
-                cs->dc.amd7930.tx_xmtlen = dtcrw;
-        }
+	/* writeing of dtcrw starts transmit */
+	if (!cs->dc.amd7930.tx_xmtlen) {
+		wWordAMD(cs, 0x85, dtcrw);
+		cs->dc.amd7930.tx_xmtlen = dtcrw;
+	}
 
 	if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
 		debugl1(cs, "Amd7930: fill_Dfifo dbusytimer running");
@@ -409,260 +409,260 @@ Amd7930_fill_Dfifo(struct IsdnCardState *cs)
 		debugl1(cs, cs->dlog);
 	}
 	/* AMD interrupts on */
-        AmdIrqOn(cs);
+	AmdIrqOn(cs);
 }
 
 
 void Amd7930_interrupt(struct IsdnCardState *cs, BYTE irflags)
 {
 	BYTE dsr1, dsr2, lsr;
-        WORD der;
+	WORD der;
 
- while (irflags)
- {
+	while (irflags)
+	{
 
-        dsr1 = rByteAMD(cs, 0x02);
-        der  = rWordAMD(cs, 0x03);
-        dsr2 = rByteAMD(cs, 0x07);
-        lsr  = rByteAMD(cs, 0xA1);
+		dsr1 = rByteAMD(cs, 0x02);
+		der  = rWordAMD(cs, 0x03);
+		dsr2 = rByteAMD(cs, 0x07);
+		lsr  = rByteAMD(cs, 0xA1);
 
-	if (cs->debug & L1_DEB_ISAC)
-		debugl1(cs, "Amd7930: interrupt: flags: 0x%02X, DSR1: 0x%02X, DSR2: 0x%02X, LSR: 0x%02X, DER=0x%04X", irflags, dsr1, dsr2, lsr, der);
+		if (cs->debug & L1_DEB_ISAC)
+			debugl1(cs, "Amd7930: interrupt: flags: 0x%02X, DSR1: 0x%02X, DSR2: 0x%02X, LSR: 0x%02X, DER=0x%04X", irflags, dsr1, dsr2, lsr, der);
 
-        /* D error -> read DER and DSR2 bit 2 */
-	if (der || (dsr2 & 4)) {
+		/* D error -> read DER and DSR2 bit 2 */
+		if (der || (dsr2 & 4)) {
 
-                if (cs->debug & L1_DEB_WARN)
-			debugl1(cs, "Amd7930: interrupt: D error DER=0x%04X", der);
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "Amd7930: interrupt: D error DER=0x%04X", der);
+
+			/* RX, TX abort if collision detected */
+			if (der & 2) {
+				wByteAMD(cs, 0x21, 0xC2);
+				wByteAMD(cs, 0x21, 0x02);
+				if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+					del_timer(&cs->dbusytimer);
+				if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+					schedule_event(cs, D_CLEARBUSY);
+				/* restart frame */
+				if (cs->tx_skb) {
+					skb_push(cs->tx_skb, cs->tx_cnt);
+					cs->tx_cnt = 0;
+					cs->dc.amd7930.tx_xmtlen = 0;
+					Amd7930_fill_Dfifo(cs);
+				} else {
+					printk(KERN_WARNING "HiSax: Amd7930 D-Collision, no skb\n");
+					debugl1(cs, "Amd7930: interrupt: D-Collision, no skb");
+				}
+			}
+			/* remove damaged data from fifo */
+			Amd7930_empty_Dfifo(cs, 1);
 
-                /* RX, TX abort if collision detected */
-                if (der & 2) {
-                        wByteAMD(cs, 0x21, 0xC2);
-                        wByteAMD(cs, 0x21, 0x02);
 			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
 				del_timer(&cs->dbusytimer);
 			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
 				schedule_event(cs, D_CLEARBUSY);
-                        /* restart frame */
-                        if (cs->tx_skb) {
+			/* restart TX-Frame */
+			if (cs->tx_skb) {
 				skb_push(cs->tx_skb, cs->tx_cnt);
 				cs->tx_cnt = 0;
-                                cs->dc.amd7930.tx_xmtlen = 0;
+				cs->dc.amd7930.tx_xmtlen = 0;
 				Amd7930_fill_Dfifo(cs);
-			} else {
-				printk(KERN_WARNING "HiSax: Amd7930 D-Collision, no skb\n");
-				debugl1(cs, "Amd7930: interrupt: D-Collision, no skb");
 			}
-                }
-                /* remove damaged data from fifo */
-		Amd7930_empty_Dfifo(cs, 1);
-
-		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-			del_timer(&cs->dbusytimer);
-		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-			schedule_event(cs, D_CLEARBUSY);
-                /* restart TX-Frame */
-                if (cs->tx_skb) {
-			skb_push(cs->tx_skb, cs->tx_cnt);
-			cs->tx_cnt = 0;
-                        cs->dc.amd7930.tx_xmtlen = 0;
-			Amd7930_fill_Dfifo(cs);
 		}
-	}
 
-        /* D TX FIFO empty -> fill */
-	if (irflags & 1) {
-		if (cs->debug & L1_DEB_ISAC)
-			debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data");
+		/* D TX FIFO empty -> fill */
+		if (irflags & 1) {
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "Amd7930: interrupt: clear Timer and fill D-TX-FIFO if data");
 
-		/* AMD interrupts off */
-                AmdIrqOff(cs);
+			/* AMD interrupts off */
+			AmdIrqOff(cs);
 
-                if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-			del_timer(&cs->dbusytimer);
-		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-			schedule_event(cs, D_CLEARBUSY);
-		if (cs->tx_skb) {
-			if (cs->tx_skb->len)
-				Amd7930_fill_Dfifo(cs);
+			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+				del_timer(&cs->dbusytimer);
+			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+				schedule_event(cs, D_CLEARBUSY);
+			if (cs->tx_skb) {
+				if (cs->tx_skb->len)
+					Amd7930_fill_Dfifo(cs);
+			}
+			/* AMD interrupts on */
+			AmdIrqOn(cs);
 		}
-		/* AMD interrupts on */
-                AmdIrqOn(cs);
-	}
 
 
-        /* D RX FIFO full or tiny packet in Fifo -> empty */
-	if ((irflags & 2) || (dsr1 & 2)) {
-                if (cs->debug & L1_DEB_ISAC)
-			debugl1(cs, "Amd7930: interrupt: empty D-FIFO");
-                Amd7930_empty_Dfifo(cs, 0);
-	}
+		/* D RX FIFO full or tiny packet in Fifo -> empty */
+		if ((irflags & 2) || (dsr1 & 2)) {
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "Amd7930: interrupt: empty D-FIFO");
+			Amd7930_empty_Dfifo(cs, 0);
+		}
 
 
-        /* D-Frame transmit complete */
-	if (dsr1 & 64) {
-		if (cs->debug & L1_DEB_ISAC) {
-			debugl1(cs, "Amd7930: interrupt: transmit packet ready");
-        	}
-		/* AMD interrupts off */
-                AmdIrqOff(cs);
+		/* D-Frame transmit complete */
+		if (dsr1 & 64) {
+			if (cs->debug & L1_DEB_ISAC) {
+				debugl1(cs, "Amd7930: interrupt: transmit packet ready");
+			}
+			/* AMD interrupts off */
+			AmdIrqOff(cs);
 
-                if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-			del_timer(&cs->dbusytimer);
-		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-			schedule_event(cs, D_CLEARBUSY);
+			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+				del_timer(&cs->dbusytimer);
+			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+				schedule_event(cs, D_CLEARBUSY);
 
-                if (cs->tx_skb) {
-        		if (cs->debug & L1_DEB_ISAC)
-	        		debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb");
-                        dev_kfree_skb_irq(cs->tx_skb);
-			cs->tx_cnt = 0;
-                        cs->dc.amd7930.tx_xmtlen=0;
-			cs->tx_skb = NULL;
-                }
-                if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
-        		if (cs->debug & L1_DEB_ISAC)
-	        		debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued");
-	        	cs->tx_cnt = 0;
-                        cs->dc.amd7930.tx_xmtlen=0;
-			Amd7930_fill_Dfifo(cs);
+			if (cs->tx_skb) {
+				if (cs->debug & L1_DEB_ISAC)
+					debugl1(cs, "Amd7930: interrupt: TX-Packet ready, freeing skb");
+				dev_kfree_skb_irq(cs->tx_skb);
+				cs->tx_cnt = 0;
+				cs->dc.amd7930.tx_xmtlen = 0;
+				cs->tx_skb = NULL;
+			}
+			if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
+				if (cs->debug & L1_DEB_ISAC)
+					debugl1(cs, "Amd7930: interrupt: TX-Packet ready, next packet dequeued");
+				cs->tx_cnt = 0;
+				cs->dc.amd7930.tx_xmtlen = 0;
+				Amd7930_fill_Dfifo(cs);
+			}
+			else
+				schedule_event(cs, D_XMTBUFREADY);
+			/* AMD interrupts on */
+			AmdIrqOn(cs);
 		}
-                else
-			schedule_event(cs, D_XMTBUFREADY);
-		/* AMD interrupts on */
-                AmdIrqOn(cs);
-        }
 
-	/* LIU status interrupt -> read LSR, check statechanges */
-	if (lsr & 0x38) {
-                /* AMD interrupts off */
-                AmdIrqOff(cs);
+		/* LIU status interrupt -> read LSR, check statechanges */
+		if (lsr & 0x38) {
+			/* AMD interrupts off */
+			AmdIrqOff(cs);
 
-		if (cs->debug & L1_DEB_ISAC)
-			debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) +2));
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "Amd: interrupt: LSR=0x%02X, LIU is in state %d", lsr, ((lsr & 0x7) + 2));
 
-		cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
+			cs->dc.amd7930.ph_state = (lsr & 0x7) + 2;
 
-		schedule_event(cs, D_L1STATECHANGE);
-		/* AMD interrupts on */
-                AmdIrqOn(cs);
-	}
+			schedule_event(cs, D_L1STATECHANGE);
+			/* AMD interrupts on */
+			AmdIrqOn(cs);
+		}
 
-        /* reads Interrupt-Register again. If there is a new interrupt-flag: restart handler */
-        irflags = rByteAMD(cs, 0x00);
- }
+		/* reads Interrupt-Register again. If there is a new interrupt-flag: restart handler */
+		irflags = rByteAMD(cs, 0x00);
+	}
 
 }
 
 static void
 Amd7930_l1hw(struct PStack *st, int pr, void *arg)
 {
-        struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
+	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 	struct sk_buff *skb = arg;
 	u_long flags;
 
-        if (cs->debug & L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: l1hw called, pr: 0x%04X", pr);
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-                        if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
-#ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
-                                cs->dc.amd7930.tx_xmtlen=0;
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA Queued", 0);
 #endif
-				Amd7930_fill_Dfifo(cs);
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
-                        cs->dc.amd7930.tx_xmtlen=0;
+			cs->dc.amd7930.tx_xmtlen = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
 			if (cs->debug & L1_DEB_LAPD)
-				Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0);
+				Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA", 0);
 #endif
 			Amd7930_fill_Dfifo(cs);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "Amd7930: l1hw: l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			break;
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
+		cs->dc.amd7930.tx_xmtlen = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb)? "yes":"no");
+		if (cs->debug & L1_DEB_LAPD)
+			Logl2Frame(cs, skb, "Amd7930: l1hw: PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			if ((cs->dc.amd7930.ph_state == 8)) {
-				/* b-channels off, PH-AR cleared
-				 * change to F3 */
-				Amd7930_ph_command(cs, 0x20, "HW_RESET REQEST"); //LMR1 bit 5
-				spin_unlock_irqrestore(&cs->lock, flags);
-			} else {
-				Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST");
-				cs->dc.amd7930.ph_state = 2;
-				spin_unlock_irqrestore(&cs->lock, flags);
-				Amd7930_new_ph(cs);
-			}
-			break;
-		case (HW_ENABLE | REQUEST):
-                        cs->dc.amd7930.ph_state = 9;
-                        Amd7930_new_ph(cs);
-			break;
-		case (HW_INFO3 | REQUEST):
-			// automatic
-			break;
-		case (HW_TESTLOOP | REQUEST):
-			/* not implemented yet */
-			break;
-		case (HW_DEACTIVATE | RESPONSE):
-                        skb_queue_purge(&cs->rq);
-			skb_queue_purge(&cs->sq);
-			if (cs->tx_skb) {
-				dev_kfree_skb(cs->tx_skb);
-				cs->tx_skb = NULL;
-			}
-			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-				del_timer(&cs->dbusytimer);
-			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-				schedule_event(cs, D_CLEARBUSY);
-			break;
-		default:
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "Amd7930: l1hw: unknown %04x", pr);
-			break;
+		Amd7930_fill_Dfifo(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG		/* psa */
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "Amd7930: l1hw: -> PH_REQUEST_PULL, skb: %s", (cs->tx_skb) ? "yes" : "no");
+#endif
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		if ((cs->dc.amd7930.ph_state == 8)) {
+			/* b-channels off, PH-AR cleared
+			 * change to F3 */
+			Amd7930_ph_command(cs, 0x20, "HW_RESET REQEST"); //LMR1 bit 5
+			spin_unlock_irqrestore(&cs->lock, flags);
+		} else {
+			Amd7930_ph_command(cs, 0x40, "HW_RESET REQUEST");
+			cs->dc.amd7930.ph_state = 2;
+			spin_unlock_irqrestore(&cs->lock, flags);
+			Amd7930_new_ph(cs);
+		}
+		break;
+	case (HW_ENABLE | REQUEST):
+		cs->dc.amd7930.ph_state = 9;
+		Amd7930_new_ph(cs);
+		break;
+	case (HW_INFO3 | REQUEST):
+		// automatic
+		break;
+	case (HW_TESTLOOP | REQUEST):
+		/* not implemented yet */
+		break;
+	case (HW_DEACTIVATE | RESPONSE):
+		skb_queue_purge(&cs->rq);
+		skb_queue_purge(&cs->sq);
+		if (cs->tx_skb) {
+			dev_kfree_skb(cs->tx_skb);
+			cs->tx_skb = NULL;
+		}
+		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+			del_timer(&cs->dbusytimer);
+		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+			schedule_event(cs, D_CLEARBUSY);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "Amd7930: l1hw: unknown %04x", pr);
+		break;
 	}
 }
 
@@ -670,16 +670,16 @@ static void
 setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
 {
 
-        if (cs->debug & L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: setstack called");
 
-        st->l1.l1hw = Amd7930_l1hw;
+	st->l1.l1hw = Amd7930_l1hw;
 }
 
 
 static void
 DC_Close_Amd7930(struct IsdnCardState *cs) {
-        if (cs->debug & L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: DC_Close called");
 }
 
@@ -689,23 +689,23 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 {
 	u_long flags;
 	struct PStack *stptr;
-        WORD dtcr, der;
-        BYTE dsr1, dsr2;
+	WORD dtcr, der;
+	BYTE dsr1, dsr2;
 
 
-        if (cs->debug & L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: dbusy_timer expired!");
 
 	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
 		spin_lock_irqsave(&cs->lock, flags);
-                /* D Transmit Byte Count Register:
-                 * Counts down packet's number of Bytes, 0 if packet ready */
-                dtcr = rWordAMD(cs, 0x85);
-                dsr1 = rByteAMD(cs, 0x02);
-                dsr2 = rByteAMD(cs, 0x07);
-                der  = rWordAMD(cs, 0x03);
-
-	        if (cs->debug & L1_DEB_ISAC)
+		/* D Transmit Byte Count Register:
+		 * Counts down packet's number of Bytes, 0 if packet ready */
+		dtcr = rWordAMD(cs, 0x85);
+		dsr1 = rByteAMD(cs, 0x02);
+		dsr2 = rByteAMD(cs, 0x07);
+		der  = rWordAMD(cs, 0x03);
+
+		if (cs->debug & L1_DEB_ISAC)
 			debugl1(cs, "Amd7930: dbusy_timer_handler: DSR1=0x%02X, DSR2=0x%02X, DER=0x%04X, cs->tx_skb->len=%u, tx_stat=%u, dtcr=%u, cs->tx_cnt=%u", dsr1, dsr2, der, cs->tx_skb->len, cs->dc.amd7930.tx_xmtlen, dtcr, cs->tx_cnt);
 
 		if ((cs->dc.amd7930.tx_xmtlen - dtcr) < cs->tx_cnt) {	/* D-Channel Busy */
@@ -724,7 +724,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 				dev_kfree_skb_any(cs->tx_skb);
 				cs->tx_cnt = 0;
 				cs->tx_skb = NULL;
-                                cs->dc.amd7930.tx_xmtlen = 0;
+				cs->dc.amd7930.tx_xmtlen = 0;
 			} else {
 				printk(KERN_WARNING "HiSax: Amd7930: D-Channel Busy no skb\n");
 				debugl1(cs, "Amd7930: D-Channel Busy no skb");
@@ -736,7 +736,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 			spin_unlock_irqrestore(&cs->lock, flags);
 			cs->irq_func(cs->irq, cs);
 
-                        if (cs->debug & L1_DEB_ISAC)
+			if (cs->debug & L1_DEB_ISAC)
 				debugl1(cs, "Amd7930: dbusy_timer_handler: Transmitter reset");
 		}
 	}
@@ -746,16 +746,16 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 
 void Amd7930_init(struct IsdnCardState *cs)
 {
-    WORD *ptr;
-    BYTE cmd, cnt;
+	WORD *ptr;
+	BYTE cmd, cnt;
 
-        if (cs->debug & L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: initamd called");
 
-        cs->dc.amd7930.tx_xmtlen = 0;
-        cs->dc.amd7930.old_state = 0;
-        cs->dc.amd7930.lmr1 = 0x40;
-        cs->dc.amd7930.ph_command = Amd7930_ph_command;
+	cs->dc.amd7930.tx_xmtlen = 0;
+	cs->dc.amd7930.old_state = 0;
+	cs->dc.amd7930.lmr1 = 0x40;
+	cs->dc.amd7930.ph_command = Amd7930_ph_command;
 	cs->setstack_d = setstack_Amd7930;
 	cs->DC_Close = DC_Close_Amd7930;
 
@@ -763,19 +763,19 @@ void Amd7930_init(struct IsdnCardState *cs)
 	for (ptr = initAMD; *ptr != 0xFFFF; ) {
 		cmd = LOBYTE(*ptr);
 
-                /* read */
-                if (*ptr++ >= 0x100) {
+		/* read */
+		if (*ptr++ >= 0x100) {
 			if (cmd < 8)
-                                /* reset register */
-                                rByteAMD(cs, cmd);
+				/* reset register */
+				rByteAMD(cs, cmd);
 			else {
 				wByteAMD(cs, 0x00, cmd);
 				for (cnt = *ptr++; cnt > 0; cnt--)
 					rByteAMD(cs, 0x01);
 			}
 		}
-                /* write */
-                else if (cmd < 8)
+		/* write */
+		else if (cmd < 8)
 			wByteAMD(cs, cmd, LOBYTE(*ptr++));
 
 		else {
@@ -789,7 +789,7 @@ void Amd7930_init(struct IsdnCardState *cs)
 void __devinit
 setup_Amd7930(struct IsdnCardState *cs)
 {
-        INIT_WORK(&cs->tqueue, Amd7930_bh);
+	INIT_WORK(&cs->tqueue, Amd7930_bh);
 	cs->dbusytimer.function = (void *) dbusy_timer_handler;
 	cs->dbusytimer.data = (long) cs;
 	init_timer(&cs->dbusytimer);
diff --git a/drivers/isdn/hisax/arcofi.c b/drivers/isdn/hisax/arcofi.c
index 21cbbe1..29ec2df 100644
--- a/drivers/isdn/hisax/arcofi.c
+++ b/drivers/isdn/hisax/arcofi.c
@@ -9,7 +9,7 @@
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
- 
+
 #include <linux/sched.h>
 #include "hisax.h"
 #include "isdnl1.h"
@@ -22,9 +22,9 @@ static void
 add_arcofi_timer(struct IsdnCardState *cs) {
 	if (test_and_set_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
 		del_timer(&cs->dc.isac.arcofitimer);
-	}	
+	}
 	init_timer(&cs->dc.isac.arcofitimer);
-	cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ)/1000);
+	cs->dc.isac.arcofitimer.expires = jiffies + ((ARCOFI_TIMER_VALUE * HZ) / 1000);
 	add_timer(&cs->dc.isac.arcofitimer);
 }
 
@@ -34,11 +34,11 @@ send_arcofi(struct IsdnCardState *cs) {
 	cs->dc.isac.mon_txp = 0;
 	cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len;
 	memcpy(cs->dc.isac.mon_tx, cs->dc.isac.arcofi_list->msg, cs->dc.isac.mon_txc);
-	switch(cs->dc.isac.arcofi_bc) {
-		case 0: break;
-		case 1: cs->dc.isac.mon_tx[1] |= 0x40;
-			break;
-		default: break;
+	switch (cs->dc.isac.arcofi_bc) {
+	case 0: break;
+	case 1: cs->dc.isac.mon_tx[1] |= 0x40;
+		break;
+	default: break;
 	}
 	cs->dc.isac.mocr &= 0x0f;
 	cs->dc.isac.mocr |= 0xa0;
@@ -58,42 +58,25 @@ arcofi_fsm(struct IsdnCardState *cs, int event, void *data) {
 		cs->dc.isac.arcofi_state = ARCOFI_NOP;
 		test_and_set_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags);
 		wake_up(&cs->dc.isac.arcofi_wait);
- 		return(1);
+		return (1);
 	}
 	switch (cs->dc.isac.arcofi_state) {
-		case ARCOFI_NOP:
-			if (event == ARCOFI_START) {
-				cs->dc.isac.arcofi_list = data;
-				cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
-				send_arcofi(cs);
-			}
-			break;
-		case ARCOFI_TRANSMIT:
-			if (event == ARCOFI_TX_END) {
-				if (cs->dc.isac.arcofi_list->receive) {
-					add_arcofi_timer(cs);
-					cs->dc.isac.arcofi_state = ARCOFI_RECEIVE;
-				} else {
-					if (cs->dc.isac.arcofi_list->next) {
-						cs->dc.isac.arcofi_list =
-							cs->dc.isac.arcofi_list->next;
-						send_arcofi(cs);
-					} else {
-						if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
-							del_timer(&cs->dc.isac.arcofitimer);
-						}
-						cs->dc.isac.arcofi_state = ARCOFI_NOP;
-						wake_up(&cs->dc.isac.arcofi_wait);
-					}
-				}
-			}
-			break;
-		case ARCOFI_RECEIVE:
-			if (event == ARCOFI_RX_END) {
+	case ARCOFI_NOP:
+		if (event == ARCOFI_START) {
+			cs->dc.isac.arcofi_list = data;
+			cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
+			send_arcofi(cs);
+		}
+		break;
+	case ARCOFI_TRANSMIT:
+		if (event == ARCOFI_TX_END) {
+			if (cs->dc.isac.arcofi_list->receive) {
+				add_arcofi_timer(cs);
+				cs->dc.isac.arcofi_state = ARCOFI_RECEIVE;
+			} else {
 				if (cs->dc.isac.arcofi_list->next) {
 					cs->dc.isac.arcofi_list =
 						cs->dc.isac.arcofi_list->next;
-					cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
 					send_arcofi(cs);
 				} else {
 					if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
@@ -103,12 +86,29 @@ arcofi_fsm(struct IsdnCardState *cs, int event, void *data) {
 					wake_up(&cs->dc.isac.arcofi_wait);
 				}
 			}
-			break;
-		default:
-			debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state);
-			return(2);
+		}
+		break;
+	case ARCOFI_RECEIVE:
+		if (event == ARCOFI_RX_END) {
+			if (cs->dc.isac.arcofi_list->next) {
+				cs->dc.isac.arcofi_list =
+					cs->dc.isac.arcofi_list->next;
+				cs->dc.isac.arcofi_state = ARCOFI_TRANSMIT;
+				send_arcofi(cs);
+			} else {
+				if (test_and_clear_bit(FLG_ARCOFI_TIMER, &cs->HW_Flags)) {
+					del_timer(&cs->dc.isac.arcofitimer);
+				}
+				cs->dc.isac.arcofi_state = ARCOFI_NOP;
+				wake_up(&cs->dc.isac.arcofi_wait);
+			}
+		}
+		break;
+	default:
+		debugl1(cs, "Arcofi unknown state %x", cs->dc.isac.arcofi_state);
+		return (2);
 	}
-	return(0);
+	return (0);
 }
 
 static void
diff --git a/drivers/isdn/hisax/arcofi.h b/drivers/isdn/hisax/arcofi.h
index 00c44d3..b9c7752 100644
--- a/drivers/isdn/hisax/arcofi.h
+++ b/drivers/isdn/hisax/arcofi.h
@@ -9,7 +9,7 @@
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
- 
+
 #define ARCOFI_USE	1
 
 /* states */
diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c
index 1f879b5..2b74a40 100644
--- a/drivers/isdn/hisax/asuscom.c
+++ b/drivers/isdn/hisax/asuscom.c
@@ -22,7 +22,7 @@
 
 static const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define ASUS_ISAC	0
@@ -51,7 +51,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -66,7 +66,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -87,13 +87,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size);
 }
@@ -101,23 +101,23 @@ WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 static u_char
 ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
 {
-	return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset|0x80));
+	return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset | 0x80));
 }
 
 static void
 WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
-	writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset|0x80, value);
+	writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset | 0x80, value);
 }
 
 static void
-ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0x80, data, size);
 }
 
 static void
-WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0x80, data, size);
 }
@@ -140,16 +140,16 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  * fast interrupt HSCX stuff goes here
  */
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.asus.adr, \
-		cs->hw.asus.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.asus.adr, \
-		cs->hw.asus.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.asus.adr,			\
+				      cs->hw.asus.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.asus.adr,		\
+					      cs->hw.asus.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.asus.adr, \
-		cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.asus.adr,	\
+						cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.asus.adr, \
-		cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.asus.adr,	\
+						  cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -162,11 +162,11 @@ asuscom_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
@@ -274,39 +274,39 @@ Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_asuscom(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_asuscom(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->debug |= L1_DEB_IPAC;
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_asuscom(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_asuscom(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->debug |= L1_DEB_IPAC;
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 #ifdef __ISAPNP__
 static struct isapnp_device_id asus_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
-	  ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), 
+	  ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
 	  (unsigned long) "Asus1688 PnP" },
 	{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690),
-	  ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690), 
+	  ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690),
 	  (unsigned long) "Asus1690 PnP" },
 	{ ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020),
-	  ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020), 
+	  ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020),
 	  (unsigned long) "Isurf2 PnP" },
 	{ ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000),
-	  ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000), 
+	  ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000),
 	  (unsigned long) "Iscas TE320" },
 	{ 0, }
 };
@@ -330,30 +330,30 @@ setup_asuscom(struct IsdnCard *card)
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d;
-		while(ipid->card_vendor) {
+		while (ipid->card_vendor) {
 			if ((pnp_c = pnp_find_card(ipid->card_vendor,
-				ipid->card_device, pnp_c))) {
+						   ipid->card_device, pnp_c))) {
 				pnp_d = NULL;
 				if ((pnp_d = pnp_find_dev(pnp_c,
-					ipid->vendor, ipid->function, pnp_d))) {
+							  ipid->vendor, ipid->function, pnp_d))) {
 					int err;
 
 					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)ipid->driver_data);
+					       (char *)ipid->driver_data);
 					pnp_disable_dev(pnp_d);
 					err = pnp_activate_dev(pnp_d);
-					if (err<0) {
+					if (err < 0) {
 						printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-							__func__, err);
-						return(0);
+						       __func__, err);
+						return (0);
 					}
 					card->para[1] = pnp_port_start(pnp_d, 0);
 					card->para[0] = pnp_irq(pnp_d, 0);
 					if (!card->para[0] || !card->para[1]) {
 						printk(KERN_ERR "AsusPnP:some resources are missing %ld/%lx\n",
-							card->para[0], card->para[1]);
+						       card->para[0], card->para[1]);
 						pnp_disable_dev(pnp_d);
-						return(0);
+						return (0);
 					}
 					break;
 				} else {
@@ -362,10 +362,10 @@ setup_asuscom(struct IsdnCard *card)
 			}
 			ipid++;
 			pnp_c = NULL;
-		} 
+		}
 		if (!ipid->card_vendor) {
 			printk(KERN_INFO "AsusPnP: no ISAPnP card found\n");
-			return(0);
+			return (0);
 		}
 	}
 #endif
@@ -380,14 +380,14 @@ setup_asuscom(struct IsdnCard *card)
 		return (0);
 	}
 	printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
-		cs->hw.asus.cfg_reg, cs->irq);
+	       cs->hw.asus.cfg_reg, cs->irq);
 	setup_isac(cs);
 	cs->BC_Read_Reg = &ReadHSCX;
 	cs->BC_Write_Reg = &WriteHSCX;
 	cs->BC_Send_Data = &hscx_fill_fifo;
 	cs->cardmsg = &Asus_card_msg;
-	val = readreg(cs->hw.asus.cfg_reg + ASUS_IPAC_ALE, 
-		cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
+	val = readreg(cs->hw.asus.cfg_reg + ASUS_IPAC_ALE,
+		      cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID);
 	if ((val == 1) || (val == 2)) {
 		cs->subtyp = ASUS_IPAC;
 		cs->hw.asus.adr  = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE;
@@ -415,7 +415,7 @@ setup_asuscom(struct IsdnCard *card)
 		ISACVersion(cs, "ISDNLink:");
 		if (HscxVersion(cs, "ISDNLink:")) {
 			printk(KERN_WARNING
-		     	"ISDNLink: wrong HSCX versions check IO address\n");
+			       "ISDNLink: wrong HSCX versions check IO address\n");
 			release_io_asuscom(cs);
 			return (0);
 		}
diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c
index eb6b432..402d489 100644
--- a/drivers/isdn/hisax/avm_a1.c
+++ b/drivers/isdn/hisax/avm_a1.c
@@ -22,7 +22,7 @@ static const char *avm_revision = "$Revision: 2.15.2.4 $";
 #define	 AVM_A1_STAT_HSCX	0x02
 #define	 AVM_A1_STAT_TIMER	0x04
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static inline u_char
@@ -39,13 +39,13 @@ writereg(unsigned int adr, u_char off, u_char data)
 
 
 static inline void
-read_fifo(unsigned int adr, u_char * data, int size)
+read_fifo(unsigned int adr, u_char *data, int size)
 {
 	insb(adr, data, size);
 }
 
 static void
-write_fifo(unsigned int adr, u_char * data, int size)
+write_fifo(unsigned int adr, u_char *data, int size)
 {
 	outsb(adr, data, size);
 }
@@ -65,13 +65,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	read_fifo(cs->hw.avm.isacfifo, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	write_fifo(cs->hw.avm.isacfifo, data, size);
 }
@@ -158,23 +158,23 @@ AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			return(0);
-		case CARD_RELEASE:
-			release_ioregs(cs, 0x3f);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 1);
-			byteout(cs->hw.avm.cfg_reg, 0x16);
-			byteout(cs->hw.avm.cfg_reg, 0x1E);
-			inithscxisac(cs, 2);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		return (0);
+	case CARD_RELEASE:
+		release_ioregs(cs, 0x3f);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 1);
+		byteout(cs->hw.avm.cfg_reg, 0x16);
+		byteout(cs->hw.avm.cfg_reg, 0x1E);
+		inithscxisac(cs, 2);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 int __devinit
diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c
index 3039c6d..3934719 100644
--- a/drivers/isdn/hisax/avm_a1p.c
+++ b/drivers/isdn/hisax/avm_a1p.c
@@ -39,7 +39,7 @@
 #define	 ASL0_R_ISAC		0x20 /* active low */
 #define	 ASL0_R_HSCX		0x40 /* active low */
 #define	 ASL0_R_TESTBIT		0x80
-#define  ASL0_R_IRQPENDING	(ASL0_R_ISAC|ASL0_R_HSCX|ASL0_R_TIMER)
+#define  ASL0_R_IRQPENDING	(ASL0_R_ISAC | ASL0_R_HSCX | ASL0_R_TIMER)
 
 /* write bits ASL0 */
 #define	 ASL0_W_RESET		0x01
@@ -52,8 +52,8 @@
 #define	 ASL1_W_LED0		0x10
 #define	 ASL1_W_LED1		0x20
 #define	 ASL1_W_ENABLE_S0	0xC0
- 
-#define byteout(addr,val) outb(val,addr)
+
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static const char *avm_revision = "$Revision: 2.9.2.5 $";
@@ -61,34 +61,34 @@ static const char *avm_revision = "$Revision: 2.9.2.5 $";
 static inline u_char
 ReadISAC(struct IsdnCardState *cs, u_char offset)
 {
-        u_char ret;
+	u_char ret;
 
-        offset -= 0x20;
-        byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset);
-	ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET);
+	offset -= 0x20;
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_REG_OFFSET + offset);
+	ret = bytein(cs->hw.avm.cfg_reg + DATAREG_OFFSET);
 	return ret;
 }
 
 static inline void
 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
-        offset -= 0x20;
-        byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset);
-	byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value);
+	offset -= 0x20;
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_REG_OFFSET + offset);
+	byteout(cs->hw.avm.cfg_reg + DATAREG_OFFSET, value);
 }
 
 static inline void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
-	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
-	insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_FIFO_OFFSET);
+	insb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size);
 }
 
 static inline void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
-	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
-	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET, ISAC_FIFO_OFFSET);
+	outsb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size);
 }
 
 static inline u_char
@@ -96,36 +96,36 @@ ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
 	u_char ret;
 
-        offset -= 0x20;
-	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
-			HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset);
-	ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET);
+	offset -= 0x20;
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET,
+		HSCX_REG_OFFSET + hscx * HSCX_CH_DIFF + offset);
+	ret = bytein(cs->hw.avm.cfg_reg + DATAREG_OFFSET);
 	return ret;
 }
 
 static inline void
 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 {
-        offset -= 0x20;
-	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
-			HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset);
-	byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value);
+	offset -= 0x20;
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET,
+		HSCX_REG_OFFSET + hscx * HSCX_CH_DIFF + offset);
+	byteout(cs->hw.avm.cfg_reg + DATAREG_OFFSET, value);
 }
 
 static inline void
-ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
+ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size)
 {
-	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
-			HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
-	insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET,
+		HSCX_FIFO_OFFSET + hscx * HSCX_CH_DIFF);
+	insb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size);
 }
 
 static inline void
-WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
+WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size)
 {
-	byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
-			HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
-	outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+	byteout(cs->hw.avm.cfg_reg + ADDRREG_OFFSET,
+		HSCX_FIFO_OFFSET + hscx * HSCX_CH_DIFF);
+	outsb(cs->hw.avm.cfg_reg + DATAREG_OFFSET, data, size);
 }
 
 /*
@@ -134,7 +134,7 @@ WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
 
 #define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg)
 #define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data)
-#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt) 
+#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt)
 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt)
 
 #include "hscx_irq.c"
@@ -147,11 +147,11 @@ avm_a1p_interrupt(int intno, void *dev_id)
 	u_long flags;
 
 	spin_lock_irqsave(&cs->lock, flags);
-	while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) {
+	while ((sval = (~bytein(cs->hw.avm.cfg_reg + ASL0_OFFSET) & ASL0_R_IRQPENDING))) {
 		if (cs->debug & L1_DEB_INTSTAT)
 			debugl1(cs, "avm IntStatus %x", sval);
 		if (sval & ASL0_R_HSCX) {
-                        val = ReadHSCX(cs, 1, HSCX_ISTA);
+			val = ReadHSCX(cs, 1, HSCX_ISTA);
 			if (val)
 				hscx_int_main(cs, val);
 		}
@@ -177,38 +177,38 @@ AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
-			HZDELAY(HZ / 5 + 1);
-			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
-			HZDELAY(HZ / 5 + 1);
-			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return 0;
-
-		case CARD_RELEASE:
-			/* free_irq is done in HiSax_closecard(). */
-		        /* free_irq(cs->irq, cs); */
-			return 0;
-
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE);
-			clear_pending_isac_ints(cs);
-			clear_pending_hscx_ints(cs);
-			inithscxisac(cs, 1);
-			inithscxisac(cs, 2);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return 0;
-
-		case CARD_TEST:
-			/* we really don't need it for the PCMCIA Version */
-			return 0;
-
-		default:
-			/* all card drivers ignore others, so we do the same */
-			return 0;
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00);
+		HZDELAY(HZ / 5 + 1);
+		byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_RESET);
+		HZDELAY(HZ / 5 + 1);
+		byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return 0;
+
+	case CARD_RELEASE:
+		/* free_irq is done in HiSax_closecard(). */
+		/* free_irq(cs->irq, cs); */
+		return 0;
+
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_TDISABLE | ASL0_W_TRESET | ASL0_W_IRQENABLE);
+		clear_pending_isac_ints(cs);
+		clear_pending_hscx_ints(cs);
+		inithscxisac(cs, 1);
+		inithscxisac(cs, 2);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return 0;
+
+	case CARD_TEST:
+		/* we really don't need it for the PCMCIA Version */
+		return 0;
+
+	default:
+		/* all card drivers ignore others, so we do the same */
+		return 0;
 	}
 	return 0;
 }
@@ -222,7 +222,7 @@ int __devinit setup_avm_a1_pcmcia(struct IsdnCard *card)
 
 	strcpy(tmp, avm_revision);
 	printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n",
-						 HiSax_getrev(tmp));
+	       HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_A1_PCMCIA)
 		return (0);
 
@@ -230,20 +230,20 @@ int __devinit setup_avm_a1_pcmcia(struct IsdnCard *card)
 	cs->irq = card->para[0];
 
 
-	byteout(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
-	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
+	byteout(cs->hw.avm.cfg_reg + ASL1_OFFSET, ASL1_W_ENABLE_S0);
+	byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00);
 	HZDELAY(HZ / 5 + 1);
-	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
+	byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_RESET);
 	HZDELAY(HZ / 5 + 1);
-	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
+	byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, 0x00);
 
-	byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET, ASL0_W_TDISABLE|ASL0_W_TRESET);
+	byteout(cs->hw.avm.cfg_reg + ASL0_OFFSET, ASL0_W_TDISABLE | ASL0_W_TRESET);
 
-	model = bytein(cs->hw.avm.cfg_reg+MODREG_OFFSET);
-	vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET);
+	model = bytein(cs->hw.avm.cfg_reg + MODREG_OFFSET);
+	vers = bytein(cs->hw.avm.cfg_reg + VERREG_OFFSET);
 
 	printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n",
-				cs->hw.avm.cfg_reg, cs->irq, model, vers);
+	       cs->hw.avm.cfg_reg, cs->irq, model, vers);
 
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 0e66af1..979492d 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -95,14 +95,14 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
 	insb(cs->hw.avm.isac, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	outb(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
 	outsb(cs->hw.avm.isac, data, size);
@@ -151,7 +151,7 @@ WriteHDLCPnP(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
 static u_char
 ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset)
 {
-	return(0xff & ReadHDLCPCI(cs, chan, offset));
+	return (0xff & ReadHDLCPCI(cs, chan, offset));
 }
 
 static void
@@ -164,11 +164,11 @@ static inline
 struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
 {
 	if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
-		return(&cs->bcs[0]);
+		return (&cs->bcs[0]);
 	else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
-		return(&cs->bcs[1]);
+		return (&cs->bcs[1]);
 	else
-		return(NULL);
+		return (NULL);
 }
 
 static void
@@ -182,13 +182,13 @@ write_ctrl(struct BCState *bcs, int which) {
 	} else {
 		if (which & 4)
 			WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 2,
-				bcs->hw.hdlc.ctrl.sr.mode);
+				     bcs->hw.hdlc.ctrl.sr.mode);
 		if (which & 2)
 			WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS + 1,
-				bcs->hw.hdlc.ctrl.sr.xml);
+				     bcs->hw.hdlc.ctrl.sr.xml);
 		if (which & 1)
 			WriteHDLCPnP(bcs->cs, bcs->channel, HDLC_STATUS,
-				bcs->hw.hdlc.ctrl.sr.cmd);
+				     bcs->hw.hdlc.ctrl.sr.cmd);
 	}
 }
 
@@ -203,41 +203,41 @@ modehdlc(struct BCState *bcs, int mode, int bc)
 			'A' + hdlc, bcs->mode, mode, hdlc, bc);
 	bcs->hw.hdlc.ctrl.ctrl = 0;
 	switch (mode) {
-		case (-1): /* used for init */
-			bcs->mode = 1;
-			bcs->channel = bc;
-			bc = 0;
-		case (L1_MODE_NULL):
-			if (bcs->mode == L1_MODE_NULL)
-				return;
-			bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
-			bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
-			write_ctrl(bcs, 5);
-			bcs->mode = L1_MODE_NULL;
-			bcs->channel = bc;
-			break;
-		case (L1_MODE_TRANS):
-			bcs->mode = mode;
-			bcs->channel = bc;
-			bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
-			bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
-			write_ctrl(bcs, 5);
-			bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
-			write_ctrl(bcs, 1);
-			bcs->hw.hdlc.ctrl.sr.cmd = 0;
-			schedule_event(bcs, B_XMTBUFREADY);
-			break;
-		case (L1_MODE_HDLC):
-			bcs->mode = mode;
-			bcs->channel = bc;
-			bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
-			bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
-			write_ctrl(bcs, 5);
-			bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
-			write_ctrl(bcs, 1);
-			bcs->hw.hdlc.ctrl.sr.cmd = 0;
-			schedule_event(bcs, B_XMTBUFREADY);
-			break;
+	case (-1): /* used for init */
+		bcs->mode = 1;
+		bcs->channel = bc;
+		bc = 0;
+	case (L1_MODE_NULL):
+		if (bcs->mode == L1_MODE_NULL)
+			return;
+		bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
+		bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
+		write_ctrl(bcs, 5);
+		bcs->mode = L1_MODE_NULL;
+		bcs->channel = bc;
+		break;
+	case (L1_MODE_TRANS):
+		bcs->mode = mode;
+		bcs->channel = bc;
+		bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
+		bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_TRANS;
+		write_ctrl(bcs, 5);
+		bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
+		write_ctrl(bcs, 1);
+		bcs->hw.hdlc.ctrl.sr.cmd = 0;
+		schedule_event(bcs, B_XMTBUFREADY);
+		break;
+	case (L1_MODE_HDLC):
+		bcs->mode = mode;
+		bcs->channel = bc;
+		bcs->hw.hdlc.ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
+		bcs->hw.hdlc.ctrl.sr.mode = HDLC_MODE_ITF_FLG;
+		write_ctrl(bcs, 5);
+		bcs->hw.hdlc.ctrl.sr.cmd = HDLC_CMD_XRS;
+		write_ctrl(bcs, 1);
+		bcs->hw.hdlc.ctrl.sr.cmd = 0;
+		schedule_event(bcs, B_XMTBUFREADY);
+		break;
 	}
 }
 
@@ -247,7 +247,7 @@ hdlc_empty_fifo(struct BCState *bcs, int count)
 	register u_int *ptr;
 	u_char *p;
 	u_char idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
-	int cnt=0;
+	int cnt = 0;
 	struct IsdnCardState *cs = bcs->cs;
 
 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
@@ -264,7 +264,7 @@ hdlc_empty_fifo(struct BCState *bcs, int count)
 		outl(idx, cs->hw.avm.cfg_reg + 4);
 		while (cnt < count) {
 #ifdef __powerpc__
-			*ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE));
+			*ptr++ = in_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE));
 #else
 			*ptr++ = inl(cs->hw.avm.isac);
 #endif /* __powerpc__ */
@@ -293,7 +293,7 @@ static inline void
 hdlc_fill_fifo(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	int count, cnt =0;
+	int count, cnt = 0;
 	int fifo_size = 32;
 	u_char *p;
 	u_int *ptr;
@@ -323,16 +323,16 @@ hdlc_fill_fifo(struct BCState *bcs)
 	bcs->hw.hdlc.ctrl.sr.xml = ((count == fifo_size) ? 0 : count);
 	write_ctrl(bcs, 3);  /* sets the correct index too */
 	if (cs->subtyp == AVM_FRITZ_PCI) {
-		while (cnt<count) {
+		while (cnt < count) {
 #ifdef __powerpc__
-			out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++);
+			out_be32((unsigned *)(cs->hw.avm.isac + _IO_BASE), *ptr++);
 #else
 			outl(*ptr++, cs->hw.avm.isac);
 #endif /* __powerpc__ */
 			cnt += 4;
 		}
 	} else {
-		while (cnt<count) {
+		while (cnt < count) {
 			outb(*p++, cs->hw.avm.isac);
 			cnt++;
 		}
@@ -369,17 +369,17 @@ HDLC_irq(struct BCState *bcs, u_int stat) {
 			write_ctrl(bcs, 1);
 			bcs->hw.hdlc.rcvidx = 0;
 		} else {
-			if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
+			if (!(len = (stat & HDLC_STAT_RML_MASK) >> 8))
 				len = 32;
 			hdlc_empty_fifo(bcs, len);
 			if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
-				if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
-					(bcs->mode == L1_MODE_TRANS)) {
+				if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) ||
+				    (bcs->mode == L1_MODE_TRANS)) {
 					if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
 						printk(KERN_WARNING "HDLC: receive out of memory\n");
 					else {
 						memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
-							bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
+						       bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
 						skb_queue_tail(&bcs->rqueue, skb);
 					}
 					bcs->hw.hdlc.rcvidx = 0;
@@ -418,9 +418,9 @@ HDLC_irq(struct BCState *bcs, u_int stat) {
 				hdlc_fill_fifo(bcs);
 				return;
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
-					u_long	flags;
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+					u_long flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->hw.hdlc.count;
 					spin_unlock_irqrestore(&bcs->aclock, flags);
@@ -453,7 +453,7 @@ HDLC_irq_main(struct IsdnCardState *cs)
 	} else {
 		stat = ReadHDLCPnP(cs, 0, HDLC_STATUS);
 		if (stat & HDLC_INT_RPR)
-			stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS+1))<<8;
+			stat |= (ReadHDLCPnP(cs, 0, HDLC_STATUS + 1)) << 8;
 	}
 	if (stat & HDLC_INT_MASK) {
 		if (!(bcs = Sel_BCS(cs, 0))) {
@@ -467,7 +467,7 @@ HDLC_irq_main(struct IsdnCardState *cs)
 	} else {
 		stat = ReadHDLCPnP(cs, 1, HDLC_STATUS);
 		if (stat & HDLC_INT_RPR)
-			stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS+1))<<8;
+			stat |= (ReadHDLCPnP(cs, 1, HDLC_STATUS + 1)) << 8;
 	}
 	if (stat & HDLC_INT_MASK) {
 		if (!(bcs = Sel_BCS(cs, 1))) {
@@ -486,55 +486,55 @@ hdlc_l2l1(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->hw.hdlc.count = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n");
-			} else {
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->tx_skb = skb;
-				bcs->hw.hdlc.count = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			modehdlc(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			modehdlc(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->hw.hdlc.count = 0;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n");
+		} else {
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->tx_skb = skb;
+			bcs->hw.hdlc.count = 0;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		modehdlc(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		modehdlc(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -568,7 +568,7 @@ open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
 		}
 		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
 			printk(KERN_WARNING
-				"HiSax: No memory for bcs->blog\n");
+			       "HiSax: No memory for bcs->blog\n");
 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
 			kfree(bcs->hw.hdlc.rcvbuf);
 			bcs->hw.hdlc.rcvbuf = NULL;
@@ -688,34 +688,34 @@ AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_avmpcipnp(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			outb(0, cs->hw.avm.cfg_reg + 2);
-			release_region(cs->hw.avm.cfg_reg, 32);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_avmpcipnp(cs);
-			clear_pending_isac_ints(cs);
-			initisac(cs);
-			inithdlc(cs);
-			outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
-				cs->hw.avm.cfg_reg + 2);
-			WriteISAC(cs, ISAC_MASK, 0);
-			outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
-				AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
-			/* RESET Receiver and Transmitter */
-			WriteISAC(cs, ISAC_CMDR, 0x41);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_avmpcipnp(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		outb(0, cs->hw.avm.cfg_reg + 2);
+		release_region(cs->hw.avm.cfg_reg, 32);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_avmpcipnp(cs);
+		clear_pending_isac_ints(cs);
+		initisac(cs);
+		inithdlc(cs);
+		outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
+		     cs->hw.avm.cfg_reg + 2);
+		WriteISAC(cs, ISAC_MASK, 0);
+		outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
+		     AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
+		/* RESET Receiver and Transmitter */
+		WriteISAC(cs, ISAC_CMDR, 0x41);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 static int __devinit avm_setup_rest(struct IsdnCardState *cs)
@@ -724,7 +724,7 @@ static int __devinit avm_setup_rest(struct IsdnCardState *cs)
 
 	cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
 	if (!request_region(cs->hw.avm.cfg_reg, 32,
-		(cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) {
+			    (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) {
 		printk(KERN_WARNING
 		       "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n",
 		       cs->hw.avm.cfg_reg,
@@ -732,28 +732,28 @@ static int __devinit avm_setup_rest(struct IsdnCardState *cs)
 		return (0);
 	}
 	switch (cs->subtyp) {
-	  case AVM_FRITZ_PCI:
+	case AVM_FRITZ_PCI:
 		val = inl(cs->hw.avm.cfg_reg);
 		printk(KERN_INFO "AVM PCI: stat %#x\n", val);
 		printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
-			val & 0xff, (val>>8) & 0xff);
+		       val & 0xff, (val >> 8) & 0xff);
 		cs->BC_Read_Reg = &ReadHDLC_s;
 		cs->BC_Write_Reg = &WriteHDLC_s;
 		break;
-	  case AVM_FRITZ_PNP:
+	case AVM_FRITZ_PNP:
 		val = inb(cs->hw.avm.cfg_reg);
 		ver = inb(cs->hw.avm.cfg_reg + 1);
 		printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver);
 		cs->BC_Read_Reg = &ReadHDLCPnP;
 		cs->BC_Write_Reg = &WriteHDLCPnP;
 		break;
-	  default:
-	  	printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp);
-	  	return(0);
+	default:
+		printk(KERN_WARNING "AVM unknown subtype %d\n", cs->subtyp);
+		return (0);
 	}
 	printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n",
-		(cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
-		cs->irq, cs->hw.avm.cfg_reg);
+	       (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP",
+	       cs->irq, cs->hw.avm.cfg_reg);
 
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
@@ -772,7 +772,7 @@ static int __devinit avm_setup_rest(struct IsdnCardState *cs)
 
 static int __devinit avm_pnp_setup(struct IsdnCardState *cs)
 {
-	return(1);	/* no-op: success */
+	return (1);	/* no-op: success */
 }
 
 #else
@@ -784,33 +784,33 @@ static int __devinit avm_pnp_setup(struct IsdnCardState *cs)
 	struct pnp_dev *pnp_avm_d = NULL;
 
 	if (!isapnp_present())
-		return(1);	/* no-op: success */
+		return (1);	/* no-op: success */
 
 	if ((pnp_avm_c = pnp_find_card(
-		ISAPNP_VENDOR('A', 'V', 'M'),
-		ISAPNP_FUNCTION(0x0900), pnp_avm_c))) {
+		     ISAPNP_VENDOR('A', 'V', 'M'),
+		     ISAPNP_FUNCTION(0x0900), pnp_avm_c))) {
 		if ((pnp_avm_d = pnp_find_dev(pnp_avm_c,
-			ISAPNP_VENDOR('A', 'V', 'M'),
-			ISAPNP_FUNCTION(0x0900), pnp_avm_d))) {
+					      ISAPNP_VENDOR('A', 'V', 'M'),
+					      ISAPNP_FUNCTION(0x0900), pnp_avm_d))) {
 			int err;
 
 			pnp_disable_dev(pnp_avm_d);
 			err = pnp_activate_dev(pnp_avm_d);
-			if (err<0) {
+			if (err < 0) {
 				printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-					__func__, err);
-				return(0);
+				       __func__, err);
+				return (0);
 			}
 			cs->hw.avm.cfg_reg =
 				pnp_port_start(pnp_avm_d, 0);
 			cs->irq = pnp_irq(pnp_avm_d, 0);
 			if (!cs->irq) {
 				printk(KERN_ERR "FritzPnP:No IRQ\n");
-				return(0);
+				return (0);
 			}
 			if (!cs->hw.avm.cfg_reg) {
 				printk(KERN_ERR "FritzPnP:No IO address\n");
-				return(0);
+				return (0);
 			}
 			cs->subtyp = AVM_FRITZ_PNP;
 
@@ -827,7 +827,7 @@ static int __devinit avm_pnp_setup(struct IsdnCardState *cs)
 
 static int __devinit avm_pci_setup(struct IsdnCardState *cs)
 {
-	return(1);	/* no-op: success */
+	return (1);	/* no-op: success */
 }
 
 #else
@@ -837,27 +837,27 @@ static struct pci_dev *dev_avm __devinitdata = NULL;
 static int __devinit avm_pci_setup(struct IsdnCardState *cs)
 {
 	if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM,
-		PCI_DEVICE_ID_AVM_A1, dev_avm))) {
+					     PCI_DEVICE_ID_AVM_A1, dev_avm))) {
 
 		if (pci_enable_device(dev_avm))
-			return(0);
+			return (0);
 
 		cs->irq = dev_avm->irq;
 		if (!cs->irq) {
 			printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n");
-			return(0);
+			return (0);
 		}
 
 		cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
 		if (!cs->hw.avm.cfg_reg) {
 			printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
-			return(0);
+			return (0);
 		}
 
 		cs->subtyp = AVM_FRITZ_PCI;
 	} else {
 		printk(KERN_WARNING "FritzPCI: No PCI card found\n");
-		return(0);
+		return (0);
 	}
 
 	cs->irq_flags |= IRQF_SHARED;
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 8f0ad2a..33e3c94 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -3,7 +3,7 @@
  *
  * Author       Carsten Paeth
  * Copyright    1998-2001 by Carsten Paeth <calle@calle.in-berlin.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -39,20 +39,20 @@ module_param(isdnprot, int, 0);
 
 /*====================================================================*/
 
-static int avma1cs_config(struct pcmcia_device *link) __devinit ;
+static int avma1cs_config(struct pcmcia_device *link) __devinit;
 static void avma1cs_release(struct pcmcia_device *link);
-static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
+static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit;
 
 static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
 {
-    dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
+	dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
 
-    /* General socket configuration */
-    p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-    p_dev->config_index = 1;
-    p_dev->config_regs = PRESENT_OPTION;
+	/* General socket configuration */
+	p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+	p_dev->config_index = 1;
+	p_dev->config_regs = PRESENT_OPTION;
 
-    return avma1cs_config(p_dev);
+	return avma1cs_config(p_dev);
 } /* avma1cs_attach */
 
 static void __devexit avma1cs_detach(struct pcmcia_device *link)
@@ -75,63 +75,63 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
 
 static int __devinit avma1cs_config(struct pcmcia_device *link)
 {
-    int i = -1;
-    char devname[128];
-    IsdnCard_t	icard;
-    int busy = 0;
-
-    dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
-
-    devname[0] = 0;
-    if (link->prod_id[1])
-	    strlcpy(devname, link->prod_id[1], sizeof(devname));
-
-    if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
-	    return -ENODEV;
-
-    do {
-	/*
-	 * allocate an interrupt line
-	 */
-	if (!link->irq) {
-	    /* undo */
-	    pcmcia_disable_device(link);
-	    break;
-	}
-
-	/*
-	 * configure the PCMCIA socket
-	 */
-	i = pcmcia_enable_device(link);
+	int i = -1;
+	char devname[128];
+	IsdnCard_t	icard;
+	int busy = 0;
+
+	dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
+
+	devname[0] = 0;
+	if (link->prod_id[1])
+		strlcpy(devname, link->prod_id[1], sizeof(devname));
+
+	if (pcmcia_loop_config(link, avma1cs_configcheck, NULL))
+		return -ENODEV;
+
+	do {
+		/*
+		 * allocate an interrupt line
+		 */
+		if (!link->irq) {
+			/* undo */
+			pcmcia_disable_device(link);
+			break;
+		}
+
+		/*
+		 * configure the PCMCIA socket
+		 */
+		i = pcmcia_enable_device(link);
+		if (i != 0) {
+			pcmcia_disable_device(link);
+			break;
+		}
+
+	} while (0);
+
+	/* If any step failed, release any partially configured state */
 	if (i != 0) {
-	    pcmcia_disable_device(link);
-	    break;
+		avma1cs_release(link);
+		return -ENODEV;
 	}
 
-    } while (0);
-
-    /* If any step failed, release any partially configured state */
-    if (i != 0) {
-	avma1cs_release(link);
-	return -ENODEV;
-    }
-
-    icard.para[0] = link->irq;
-    icard.para[1] = link->resource[0]->start;
-    icard.protocol = isdnprot;
-    icard.typ = ISDN_CTYPE_A1_PCMCIA;
-    
-    i = hisax_init_pcmcia(link, &busy, &icard);
-    if (i < 0) {
-	printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 "
-			"PCMCIA %d at i/o %#x\n", i,
-			(unsigned int) link->resource[0]->start);
-	avma1cs_release(link);
-	return -ENODEV;
-    }
-    link->priv = (void *) (unsigned long) i;
+	icard.para[0] = link->irq;
+	icard.para[1] = link->resource[0]->start;
+	icard.protocol = isdnprot;
+	icard.typ = ISDN_CTYPE_A1_PCMCIA;
+
+	i = hisax_init_pcmcia(link, &busy, &icard);
+	if (i < 0) {
+		printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 "
+		       "PCMCIA %d at i/o %#x\n", i,
+		       (unsigned int) link->resource[0]->start);
+		avma1cs_release(link);
+		return -ENODEV;
+	}
+	link->priv = (void *) (unsigned long) i;
 
-    return 0;
+	return 0;
 } /* avma1cs_config */
 
 static void avma1cs_release(struct pcmcia_device *link)
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c
index 9f2009c..f6bf9c6 100644
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -4,7 +4,7 @@
  *
  * Author       Roland Klabunde
  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -39,7 +39,7 @@ readreg(unsigned int ale, unsigned long adr, u_char off)
 
 
 static inline void
-readfifo(unsigned int ale, unsigned long adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned long adr, u_char off, u_char *data, int size)
 {
 	int i;
 	for (i = 0; i < size; i++)
@@ -59,7 +59,7 @@ writereg(unsigned int ale, unsigned long adr, u_char off, u_char data)
 
 
 static inline void
-writefifo(unsigned int ale, unsigned long adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned long adr, u_char off, u_char *data, int size)
 {
 	int i;
 
@@ -83,13 +83,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.ax.isac_ale, cs->hw.ax.isac_adr, 0, data, size);
 }
@@ -110,15 +110,15 @@ WriteJADE(struct IsdnCardState *cs, int jade, u_char offset, u_char value)
  * fast interrupt JADE stuff goes here
  */
 
-#define READJADE(cs, nr, reg) readreg(cs->hw.ax.jade_ale,\
- 		cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)))
-#define WRITEJADE(cs, nr, reg, data) writereg(cs->hw.ax.jade_ale,\
- 		cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), data)
+#define READJADE(cs, nr, reg) readreg(cs->hw.ax.jade_ale,		\
+				      cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)))
+#define WRITEJADE(cs, nr, reg, data) writereg(cs->hw.ax.jade_ale,	\
+					      cs->hw.ax.jade_adr, reg + (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), data)
 
-#define READJADEFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.jade_ale,\
-		cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt)
-#define WRITEJADEFIFO(cs, nr, ptr, cnt) writefifo( cs->hw.ax.jade_ale,\
-		cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt)
+#define READJADEFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.jade_ale,	\
+						cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt)
+#define WRITEJADEFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ax.jade_ale,	\
+						  cs->hw.ax.jade_adr, (nr == -1 ? 0 : (nr ? 0xC0 : 0x80)), ptr, cnt)
 
 #include "jade_irq.c"
 
@@ -201,11 +201,11 @@ reset_bkm(struct IsdnCardState *cs)
 		pI20_Regs->i20SysControl = sysRESET | sysCFG;
 		/* Issue ISDN reset     */
 		pI20_Regs->i20GuestControl = guestWAIT_CFG |
-		    g_A4T_JADE_RES |
-		    g_A4T_ISAR_RES |
-		    g_A4T_ISAC_RES |
-		    g_A4T_JADE_BOOTR |
-		    g_A4T_ISAR_BOOTR;
+			g_A4T_JADE_RES |
+			g_A4T_ISAR_RES |
+			g_A4T_ISAC_RES |
+			g_A4T_JADE_BOOTR |
+			g_A4T_ISAR_BOOTR;
 		mdelay(10);
 
 		/* Remove RESET state from ISDN */
@@ -222,33 +222,33 @@ BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			/* Disable ints */
-			spin_lock_irqsave(&cs->lock, flags);
-			enable_bkm_int(cs, 0);
-			reset_bkm(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_RELEASE:
-			/* Sanity */
-			spin_lock_irqsave(&cs->lock, flags);
-			enable_bkm_int(cs, 0);
-			reset_bkm(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			release_io_bkm(cs);
-			return (0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			clear_pending_isac_ints(cs);
-			clear_pending_jade_ints(cs);
-			initisac(cs);
-			initjade(cs);
-			/* Enable ints */
-			enable_bkm_int(cs, 1);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_TEST:
-			return (0);
+	case CARD_RESET:
+		/* Disable ints */
+		spin_lock_irqsave(&cs->lock, flags);
+		enable_bkm_int(cs, 0);
+		reset_bkm(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		/* Sanity */
+		spin_lock_irqsave(&cs->lock, flags);
+		enable_bkm_int(cs, 0);
+		reset_bkm(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		release_io_bkm(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		clear_pending_isac_ints(cs);
+		clear_pending_jade_ints(cs);
+		initisac(cs);
+		initjade(cs);
+		/* Enable ints */
+		enable_bkm_int(cs, 1);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
 	return (0);
 }
@@ -341,7 +341,7 @@ setup_bkm_a4t(struct IsdnCard *card)
 		return (0);
 
 	while ((dev_a4t = hisax_find_pci_device(PCI_VENDOR_ID_ZORAN,
-		PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) {
+						PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) {
 		ret = a4t_pci_probe(dev_a4t, cs, &found, &pci_memaddr);
 		if (!ret)
 			return (0);
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c
index e775706..c9c98f0 100644
--- a/drivers/isdn/hisax/bkm_a8.c
+++ b/drivers/isdn/hisax/bkm_a8.c
@@ -4,7 +4,7 @@
  *
  * Author       Roland Klabunde
  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -34,7 +34,7 @@ static const char *sct_quadro_subtypes[] =
 };
 
 
-#define wordout(addr,val) outw(val,addr)
+#define wordout(addr, val) outw(val, addr)
 #define wordin(addr) inw(addr)
 
 static inline u_char
@@ -47,7 +47,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	int i;
 	wordout(ale, off);
@@ -64,7 +64,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	int i;
 	wordout(ale, off);
@@ -87,13 +87,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.ax.base, cs->hw.ax.data_adr, 0x80, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.ax.base, cs->hw.ax.data_adr, 0x80, data, size);
 }
@@ -117,21 +117,21 @@ set_ipac_active(struct IsdnCardState *cs, u_int active)
 {
 	/* set irq mask */
 	writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK,
-		active ? 0xc0 : 0xff);
+		 active ? 0xc0 : 0xff);
 }
 
 /*
  * fast interrupt HSCX stuff goes here
  */
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.ax.base, \
-	cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ax.base, \
-	cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0), data)
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.base, \
-	cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt)
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ax.base, \
-	cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.ax.base,			\
+				      cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ax.base,		\
+					      cs->hw.ax.data_adr, reg + (nr ? 0x40 : 0), data)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ax.base,		\
+						cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ax.base,	\
+						  cs->hw.ax.data_adr, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -148,7 +148,7 @@ bkm_interrupt_ipac(int intno, void *dev_id)
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return IRQ_NONE;
 	}
-      Start_IPAC:
+Start_IPAC:
 	if (cs->debug & L1_DEB_IPAC)
 		debugl1(cs, "IPAC ISTA %02X", ista);
 	if (ista & 0x0f) {
@@ -224,33 +224,33 @@ BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			/* Disable ints */
-			set_ipac_active(cs, 0);
-			enable_bkm_int(cs, 0);
-			reset_bkm(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_RELEASE:
-			/* Sanity */
-			spin_lock_irqsave(&cs->lock, flags);
-			set_ipac_active(cs, 0);
-			enable_bkm_int(cs, 0);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			release_io_sct_quadro(cs);
-			return (0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->debug |= L1_DEB_IPAC;
-			set_ipac_active(cs, 1);
-			inithscxisac(cs, 3);
-			/* Enable ints */
-			enable_bkm_int(cs, 1);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_TEST:
-			return (0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		/* Disable ints */
+		set_ipac_active(cs, 0);
+		enable_bkm_int(cs, 0);
+		reset_bkm(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		/* Sanity */
+		spin_lock_irqsave(&cs->lock, flags);
+		set_ipac_active(cs, 0);
+		enable_bkm_int(cs, 0);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		release_io_sct_quadro(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->debug |= L1_DEB_IPAC;
+		set_ipac_active(cs, 1);
+		inithscxisac(cs, 3);
+		/* Enable ints */
+		enable_bkm_int(cs, 1);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
 	return (0);
 }
@@ -260,11 +260,11 @@ sct_alloc_io(u_int adr, u_int len)
 {
 	if (!request_region(adr, len, "scitel")) {
 		printk(KERN_WARNING
-			"HiSax: Scitel port %#x-%#x already in use\n",
-			adr, adr + len);
+		       "HiSax: Scitel port %#x-%#x already in use\n",
+		       adr, adr + len);
 		return (1);
 	}
-	return(0);
+	return (0);
 }
 
 static struct pci_dev *dev_a8 __devinitdata = NULL;
@@ -298,18 +298,18 @@ setup_sct_quadro(struct IsdnCard *card)
 		return (0);
 	}
 	if ((cs->subtyp != SCT_1) && ((sub_sys_id != PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) ||
-		(sub_vendor_id != PCI_VENDOR_ID_BERKOM)))
+				      (sub_vendor_id != PCI_VENDOR_ID_BERKOM)))
 		return (0);
 	if (cs->subtyp == SCT_1) {
 		while ((dev_a8 = hisax_find_pci_device(PCI_VENDOR_ID_PLX,
-			PCI_DEVICE_ID_PLX_9050, dev_a8))) {
-			
+						       PCI_DEVICE_ID_PLX_9050, dev_a8))) {
+
 			sub_vendor_id = dev_a8->subsystem_vendor;
 			sub_sys_id = dev_a8->subsystem_device;
 			if ((sub_sys_id == PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) &&
-				(sub_vendor_id == PCI_VENDOR_ID_BERKOM)) {
+			    (sub_vendor_id == PCI_VENDOR_ID_BERKOM)) {
 				if (pci_enable_device(dev_a8))
-					return(0);
+					return (0);
 				pci_ioaddr1 = pci_resource_start(dev_a8, 1);
 				pci_irq = dev_a8->irq;
 				pci_bus = dev_a8->bus->number;
@@ -320,23 +320,23 @@ setup_sct_quadro(struct IsdnCard *card)
 		}
 		if (!found) {
 			printk(KERN_WARNING "HiSax: Scitel Quadro (%s): "
-				"Card not found\n",
-				sct_quadro_subtypes[cs->subtyp]);
+			       "Card not found\n",
+			       sct_quadro_subtypes[cs->subtyp]);
 			return (0);
 		}
 #ifdef ATTEMPT_PCI_REMAPPING
 /* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */
 		if ((pci_ioaddr1 & 0x80) && (dev_a8->revision == 1)) {
 			printk(KERN_WARNING "HiSax: Scitel Quadro (%s): "
-				"PLX rev 1, remapping required!\n",
-				sct_quadro_subtypes[cs->subtyp]);
+			       "PLX rev 1, remapping required!\n",
+			       sct_quadro_subtypes[cs->subtyp]);
 			/* Restart PCI negotiation */
-			pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int) - 1);
+			pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int)-1);
 			/* Move up by 0x80 byte */
 			pci_ioaddr1 += 0x80;
 			pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK;
 			pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, pci_ioaddr1);
-			dev_a8->resource[ 1].start = pci_ioaddr1;
+			dev_a8->resource[1].start = pci_ioaddr1;
 		}
 #endif /* End HACK */
 	}
@@ -371,39 +371,39 @@ setup_sct_quadro(struct IsdnCard *card)
 	/* pci_ioaddr5 is for the first subdevice only */
 	cs->hw.ax.plx_adr = pci_ioaddr1;
 	/* Enter all ipac_base addresses */
-	switch(cs->subtyp) {
-		case 1:
-			cs->hw.ax.base = pci_ioaddr5 + 0x00;
-			if (sct_alloc_io(pci_ioaddr1, 128))
-				return(0);
-			if (sct_alloc_io(pci_ioaddr5, 64))
-				return(0);
-			/* disable all IPAC */
-			writereg(pci_ioaddr5, pci_ioaddr5 + 4,
-				IPAC_MASK, 0xFF);
-			writereg(pci_ioaddr4 + 0x08, pci_ioaddr4 + 0x0c,
-				IPAC_MASK, 0xFF);
-			writereg(pci_ioaddr3 + 0x10, pci_ioaddr3 + 0x14,
-				IPAC_MASK, 0xFF);
-			writereg(pci_ioaddr2 + 0x20, pci_ioaddr2 + 0x24,
-				IPAC_MASK, 0xFF);
-			break;
-		case 2:
-			cs->hw.ax.base = pci_ioaddr4 + 0x08;
-			if (sct_alloc_io(pci_ioaddr4, 64))
-				return(0);
-			break;
-		case 3:
-			cs->hw.ax.base = pci_ioaddr3 + 0x10;
-			if (sct_alloc_io(pci_ioaddr3, 64))
-				return(0);
-			break;
-		case 4:
-			cs->hw.ax.base = pci_ioaddr2 + 0x20;
-			if (sct_alloc_io(pci_ioaddr2, 64))
-				return(0);
-			break;
-	}	
+	switch (cs->subtyp) {
+	case 1:
+		cs->hw.ax.base = pci_ioaddr5 + 0x00;
+		if (sct_alloc_io(pci_ioaddr1, 128))
+			return (0);
+		if (sct_alloc_io(pci_ioaddr5, 64))
+			return (0);
+		/* disable all IPAC */
+		writereg(pci_ioaddr5, pci_ioaddr5 + 4,
+			 IPAC_MASK, 0xFF);
+		writereg(pci_ioaddr4 + 0x08, pci_ioaddr4 + 0x0c,
+			 IPAC_MASK, 0xFF);
+		writereg(pci_ioaddr3 + 0x10, pci_ioaddr3 + 0x14,
+			 IPAC_MASK, 0xFF);
+		writereg(pci_ioaddr2 + 0x20, pci_ioaddr2 + 0x24,
+			 IPAC_MASK, 0xFF);
+		break;
+	case 2:
+		cs->hw.ax.base = pci_ioaddr4 + 0x08;
+		if (sct_alloc_io(pci_ioaddr4, 64))
+			return (0);
+		break;
+	case 3:
+		cs->hw.ax.base = pci_ioaddr3 + 0x10;
+		if (sct_alloc_io(pci_ioaddr3, 64))
+			return (0);
+		break;
+	case 4:
+		cs->hw.ax.base = pci_ioaddr2 + 0x20;
+		if (sct_alloc_io(pci_ioaddr2, 64))
+			return (0);
+		break;
+	}
 	/* For isac and hscx data path */
 	cs->hw.ax.data_adr = cs->hw.ax.base + 4;
 
@@ -429,7 +429,7 @@ setup_sct_quadro(struct IsdnCard *card)
 	cs->irq_func = &bkm_interrupt_ipac;
 
 	printk(KERN_INFO "HiSax: Scitel Quadro (%s): IPAC Version %d\n",
-		sct_quadro_subtypes[cs->subtyp],
-		readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID));
+	       sct_quadro_subtypes[cs->subtyp],
+	       readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID));
 	return (1);
 }
diff --git a/drivers/isdn/hisax/bkm_ax.h b/drivers/isdn/hisax/bkm_ax.h
index 029e0a2..27ff8a8 100644
--- a/drivers/isdn/hisax/bkm_ax.h
+++ b/drivers/isdn/hisax/bkm_ax.h
@@ -4,7 +4,7 @@
  *
  * Author       Roland Klabunde
  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -32,36 +32,36 @@
 
 /* Application specific registers I20 (Siemens SZB6120H) */
 typedef	struct {
-		/* Video front end horizontal configuration register */
+	/* Video front end horizontal configuration register */
 	volatile u_int	i20VFEHorzCfg;	/* Offset 00 */
-		/* Video front end vertical configuration register */
-	volatile u_int	i20VFEVertCfg;	/* Offset 04 */	
-		/* Video front end scaler and pixel format register */
-	volatile u_int	i20VFEScaler;	/* Offset 08 */	
-		/* Video display top register */
-	volatile u_int	i20VDispTop;   	/* Offset 0C */	
-		/* Video display bottom register */
-	volatile u_int	i20VDispBottom;	/* Offset 10 */	
-		/* Video stride, status and frame grab register */
-	volatile u_int	i20VidFrameGrab;/* Offset 14 */	
-		/* Video display configuration register */
-	volatile u_int	i20VDispCfg;	/* Offset 18 */	
-		/* Video masking map top */
-	volatile u_int	i20VMaskTop;	/* Offset 1C */	
-		/* Video masking map bottom */
-	volatile u_int	i20VMaskBottom;	/* Offset 20 */	
-		/* Overlay control register */
-	volatile u_int 	i20OvlyControl;	/* Offset 24 */	
-		/* System, PCI and general purpose pins control register */
- 	volatile u_int	i20SysControl; 	/* Offset 28 */	
+	/* Video front end vertical configuration register */
+	volatile u_int	i20VFEVertCfg;	/* Offset 04 */
+	/* Video front end scaler and pixel format register */
+	volatile u_int	i20VFEScaler;	/* Offset 08 */
+	/* Video display top register */
+	volatile u_int	i20VDispTop;	/* Offset 0C */
+	/* Video display bottom register */
+	volatile u_int	i20VDispBottom;	/* Offset 10 */
+	/* Video stride, status and frame grab register */
+	volatile u_int	i20VidFrameGrab;/* Offset 14 */
+	/* Video display configuration register */
+	volatile u_int	i20VDispCfg;	/* Offset 18 */
+	/* Video masking map top */
+	volatile u_int	i20VMaskTop;	/* Offset 1C */
+	/* Video masking map bottom */
+	volatile u_int	i20VMaskBottom;	/* Offset 20 */
+	/* Overlay control register */
+	volatile u_int	i20OvlyControl;	/* Offset 24 */
+	/* System, PCI and general purpose pins control register */
+	volatile u_int	i20SysControl;	/* Offset 28 */
 #define	sysRESET		0x01000000	/* bit 24:Softreset (Low)		*/
-			/* GPIO 4...0: Output fixed for our cfg! */
+	/* GPIO 4...0: Output fixed for our cfg! */
 #define	sysCFG			0x000000E0	/* GPIO 7,6,5: Input */
 	/* General purpose pins and guest bus control register */
- 	volatile u_int	i20GuestControl;/* Offset 2C */	
+	volatile u_int	i20GuestControl;/* Offset 2C */
 #define	guestWAIT_CFG	0x00005555	/* 4 PCI waits for all */
 #define	guestISDN_INT_E	0x01000000	/* ISDN Int en (low) */
-#define	guestVID_INT_E 	0x02000000	/* Video interrupt en (low) */
+#define	guestVID_INT_E	0x02000000	/* Video interrupt en (low) */
 #define	guestADI1_INT_R	0x04000000	/* ADI #1 int req (low) */
 #define	guestADI2_INT_R	0x08000000	/* ADI #2 int req (low) */
 #define	guestISDN_RES	0x10000000	/* ISDN reset bit (high) */
@@ -78,18 +78,18 @@ typedef	struct {
 #define	g_A4T_ISAR_INT_S 0x40000000	/* ISAR interrupt pnd (Low) */
 #define	g_A4T_ISAC_INT_S 0x80000000	/* ISAC interrupt pnd (Low) */
 
- 	volatile u_int	i20CodeSource;	/* Offset 30 */	
- 	volatile u_int	i20CodeXferCtrl;/* Offset 34 */	
- 	volatile u_int	i20CodeMemPtr;	/* Offset 38 */	
+	volatile u_int	i20CodeSource;	/* Offset 30 */
+	volatile u_int	i20CodeXferCtrl;/* Offset 34 */
+	volatile u_int	i20CodeMemPtr;	/* Offset 38 */
 
-  	volatile u_int	i20IntStatus;	/* Offset 3C */	
- 	volatile u_int	i20IntCtrl;	/* Offset 40 */	
+	volatile u_int	i20IntStatus;	/* Offset 3C */
+	volatile u_int	i20IntCtrl;	/* Offset 40 */
 #define	intISDN		0x40000000	/* GIRQ1En (ISAC/ADI) (High) */
 #define	intVID		0x20000000	/* GIRQ0En (VSYNC)    (High) */
 #define	intCOD		0x10000000	/* CodRepIrqEn        (High) */
-#define	intPCI 		0x01000000	/* PCI IntA enable    (High) */
+#define	intPCI		0x01000000	/* PCI IntA enable    (High) */
 
- 	volatile u_int	i20I2CCtrl;	/* Offset 44					*/	
+	volatile u_int	i20I2CCtrl;	/* Offset 44					*/
 } I20_REGISTER_FILE, *PI20_REGISTER_FILE;
 
 /*
@@ -98,7 +98,7 @@ typedef	struct {
  */
 #define	PO_OFFSET	0x00000200	/* Postoffice offset from base */
 
-#define	GCS_0		0x00000000 	/* Guest bus chip selects */
+#define	GCS_0		0x00000000	/* Guest bus chip selects */
 #define	GCS_1		0x00100000
 #define	GCS_2		0x00200000
 #define	GCS_3		0x00300000
@@ -108,12 +108,12 @@ typedef	struct {
 
 #define	PO_PEND		0x02000000
 
-#define POSTOFFICE(postoffice) *(volatile unsigned int*)(postoffice)
+#define POSTOFFICE(postoffice) *(volatile unsigned int *)(postoffice)
 
-/* Wait unlimited (don't worry)										*/ 
-#define	__WAITI20__(postoffice)										\
-do {		   	 		   											\
-  	while ((POSTOFFICE(postoffice) & PO_PEND)) ;					\
-} while (0)
+/* Wait unlimited (don't worry)										*/
+#define	__WAITI20__(postoffice)					\
+	do {							\
+		while ((POSTOFFICE(postoffice) & PO_PEND)) ;	\
+	} while (0)
 
 #endif	/* __BKM_AX_H__ */
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index c4897e1..a47637b 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -2,7 +2,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -66,7 +66,7 @@ hisax_findcard(int driverid)
 }
 
 static __printf(3, 4) void
-link_debug(struct Channel *chanp, int direction, char *fmt, ...)
+	link_debug(struct Channel *chanp, int direction, char *fmt, ...)
 {
 	va_list args;
 	char tmp[16];
@@ -91,9 +91,9 @@ enum {
 	ST_WAIT_DCOMMAND,	/*  9 call clear. (receiver), awaiting DCHANNEL message */
 	ST_WAIT_DRELEASE,	/* 10 DISCONNECT sent, awaiting RELEASE */
 	ST_WAIT_D_REL_CNF,	/* 11 RELEASE sent, awaiting RELEASE confirm */
-	ST_IN_PROCEED_SEND,	/* 12 incoming call, proceeding send */ 
+	ST_IN_PROCEED_SEND,	/* 12 incoming call, proceeding send */
 };
-  
+
 
 #define STATE_COUNT (ST_IN_PROCEED_SEND + 1)
 
@@ -119,7 +119,7 @@ enum {
 	EV_SETUP_CNF,		/*  1 */
 	EV_ACCEPTB,		/*  2 */
 	EV_DISCONNECT_IND,	/*  3 */
-	EV_RELEASE, 		/*  4 */
+	EV_RELEASE,		/*  4 */
 	EV_LEASED,		/*  5 */
 	EV_LEASED_REL,		/*  6 */
 	EV_SETUP_IND,		/*  7 */
@@ -136,8 +136,8 @@ enum {
 	EV_SETUP_ERR,		/* 18 */
 	EV_CONNECT_ERR,		/* 19 */
 	EV_PROCEED,		/* 20 */
-	EV_ALERT,		/* 21 */ 
-	EV_REDIR,		/* 22 */ 
+	EV_ALERT,		/* 21 */
+	EV_REDIR,		/* 22 */
 };
 
 #define EVENT_COUNT (EV_REDIR + 1)
@@ -232,8 +232,8 @@ lli_leased_in(struct FsmInst *fi, int event, void *arg)
 	ic.parm.setup.si2 = 0;
 	ic.parm.setup.plan = 0;
 	ic.parm.setup.screen = 0;
-	sprintf(ic.parm.setup.eazmsn,"%d", chanp->chan + 1);
-	sprintf(ic.parm.setup.phone,"LEASED%d", chanp->cs->myid);
+	sprintf(ic.parm.setup.eazmsn, "%d", chanp->chan + 1);
+	sprintf(ic.parm.setup.phone, "LEASED%d", chanp->cs->myid);
 	ret = chanp->cs->iif.statcallb(&ic);
 	if (chanp->debug & 1)
 		link_debug(chanp, 1, "statcallb ret=%d", ret);
@@ -356,33 +356,33 @@ lli_deliver_call(struct FsmInst *fi, int event, void *arg)
 			link_debug(chanp, 1, "statcallb ret=%d", ret);
 
 		switch (ret) {
-			case 1:	/* OK, someone likes this call */
-				FsmDelTimer(&chanp->drel_timer, 61);
-				FsmChangeState(fi, ST_IN_ALERT_SENT);
-				chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
-				break;
-			case 5: /* direct redirect */
-			case 4: /* Proceeding desired */
-				FsmDelTimer(&chanp->drel_timer, 61);
-				FsmChangeState(fi, ST_IN_PROCEED_SEND);
-				chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc);
-				if (ret == 5) {
-					memcpy(&chanp->setup, &ic.parm.setup, sizeof(setup_parm));
-					chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);
-				}
-				break;
-			case 2:	/* Rejecting Call */
-				break;
-			case 3:	/* incomplete number */
-				FsmDelTimer(&chanp->drel_timer, 61);
-				chanp->d_st->lli.l4l3(chanp->d_st, CC_MORE_INFO | REQUEST, chanp->proc);
-				break;
-			case 0:	/* OK, nobody likes this call */
-			default:	/* statcallb problems */
-				chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
-				chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
-				FsmChangeState(fi, ST_NULL);
-				break;
+		case 1:	/* OK, someone likes this call */
+			FsmDelTimer(&chanp->drel_timer, 61);
+			FsmChangeState(fi, ST_IN_ALERT_SENT);
+			chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
+			break;
+		case 5: /* direct redirect */
+		case 4: /* Proceeding desired */
+			FsmDelTimer(&chanp->drel_timer, 61);
+			FsmChangeState(fi, ST_IN_PROCEED_SEND);
+			chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc);
+			if (ret == 5) {
+				memcpy(&chanp->setup, &ic.parm.setup, sizeof(setup_parm));
+				chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);
+			}
+			break;
+		case 2:	/* Rejecting Call */
+			break;
+		case 3:	/* incomplete number */
+			FsmDelTimer(&chanp->drel_timer, 61);
+			chanp->d_st->lli.l4l3(chanp->d_st, CC_MORE_INFO | REQUEST, chanp->proc);
+			break;
+		case 0:	/* OK, nobody likes this call */
+		default:	/* statcallb problems */
+			chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
+			chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
+			FsmChangeState(fi, ST_NULL);
+			break;
 		}
 	} else {
 		chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
@@ -487,7 +487,7 @@ lli_disconnect_req(struct FsmInst *fi, int event, void *arg)
 		if (chanp->proc)
 			chanp->proc->para.cause = 0x10;	/* Normal Call Clearing */
 		chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST,
-			chanp->proc);
+				      chanp->proc);
 	}
 }
 
@@ -503,7 +503,7 @@ lli_disconnect_reject(struct FsmInst *fi, int event, void *arg)
 		if (chanp->proc)
 			chanp->proc->para.cause = 0x15;	/* Call Rejected */
 		chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST,
-			chanp->proc);
+				      chanp->proc);
 	}
 }
 
@@ -579,7 +579,7 @@ static void
 lli_bhup_disc(struct FsmInst *fi, int event, void *arg)
 {
 	struct Channel *chanp = fi->userdata;
- 
+
 	if (chanp->debug & 1)
 		link_debug(chanp, 0, "STAT_BHUP");
 	HL_LL(chanp, ISDN_STAT_BHUP);
@@ -639,7 +639,7 @@ lli_abort(struct FsmInst *fi, int event, void *arg)
 	chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
 	lli_bhup_dhup(fi, event, arg);
 }
- 
+
 static void
 lli_release_req(struct FsmInst *fi, int event, void *arg)
 {
@@ -650,7 +650,7 @@ lli_release_req(struct FsmInst *fi, int event, void *arg)
 	} else {
 		FsmChangeState(fi, ST_WAIT_D_REL_CNF);
 		chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST,
-			chanp->proc);
+				      chanp->proc);
 	}
 }
 
@@ -667,7 +667,7 @@ static void
 lli_bhup_release_req(struct FsmInst *fi, int event, void *arg)
 {
 	struct Channel *chanp = fi->userdata;
- 
+
 	if (chanp->debug & 1)
 		link_debug(chanp, 0, "STAT_BHUP");
 	HL_LL(chanp, ISDN_STAT_BHUP);
@@ -698,7 +698,7 @@ lli_dchan_not_ready(struct FsmInst *fi, int event, void *arg)
 
 	if (chanp->debug & 1)
 		link_debug(chanp, 0, "STAT_DHUP");
-	HL_LL(chanp, ISDN_STAT_DHUP); 
+	HL_LL(chanp, ISDN_STAT_DHUP);
 }
 
 static void
@@ -709,7 +709,7 @@ lli_no_setup_rsp(struct FsmInst *fi, int event, void *arg)
 	if (chanp->debug & 1)
 		link_debug(chanp, 0, "STAT_DHUP");
 	HL_LL(chanp, ISDN_STAT_DHUP);
-	lli_close(fi); 
+	lli_close(fi);
 }
 
 static void
@@ -768,69 +768,69 @@ lli_failure_a(struct FsmInst *fi, int event, void *arg)
 /* *INDENT-OFF* */
 static struct FsmNode fnlist[] __initdata =
 {
-        {ST_NULL,               EV_DIAL,                lli_prep_dialout},
-        {ST_NULL,               EV_RESUME,              lli_resume},
-        {ST_NULL,               EV_SETUP_IND,           lli_deliver_call},
-        {ST_NULL,               EV_LEASED,              lli_leased_in},
-        {ST_OUT_DIAL,           EV_SETUP_CNF,           lli_init_bchan_out},
-        {ST_OUT_DIAL,           EV_HANGUP,              lli_disconnect_req},
-        {ST_OUT_DIAL,           EV_DISCONNECT_IND,      lli_release_req},
-        {ST_OUT_DIAL,           EV_RELEASE,             lli_dhup_close},
-        {ST_OUT_DIAL,           EV_NOSETUP_RSP,         lli_no_setup_rsp},
-        {ST_OUT_DIAL,           EV_SETUP_ERR,           lli_error},
-        {ST_IN_WAIT_LL,         EV_LEASED_REL,          lli_failure_l},
-        {ST_IN_WAIT_LL,         EV_ACCEPTD,             lli_setup_rsp},
-        {ST_IN_WAIT_LL,         EV_HANGUP,              lli_reject_req},
-        {ST_IN_WAIT_LL,         EV_DISCONNECT_IND,      lli_release_req},
-        {ST_IN_WAIT_LL,         EV_RELEASE,             lli_dhup_close},
-        {ST_IN_WAIT_LL,         EV_SETUP_IND,           lli_deliver_call},
-        {ST_IN_WAIT_LL,         EV_SETUP_ERR,           lli_error},
-        {ST_IN_ALERT_SENT,      EV_SETUP_CMPL_IND,      lli_init_bchan_in},
-        {ST_IN_ALERT_SENT,      EV_ACCEPTD,             lli_send_dconnect},
-        {ST_IN_ALERT_SENT,      EV_HANGUP,              lli_disconnect_reject},
-        {ST_IN_ALERT_SENT,      EV_DISCONNECT_IND,      lli_release_req},
-        {ST_IN_ALERT_SENT,      EV_RELEASE,             lli_dhup_close},
+	{ST_NULL,               EV_DIAL,                lli_prep_dialout},
+	{ST_NULL,               EV_RESUME,              lli_resume},
+	{ST_NULL,               EV_SETUP_IND,           lli_deliver_call},
+	{ST_NULL,               EV_LEASED,              lli_leased_in},
+	{ST_OUT_DIAL,           EV_SETUP_CNF,           lli_init_bchan_out},
+	{ST_OUT_DIAL,           EV_HANGUP,              lli_disconnect_req},
+	{ST_OUT_DIAL,           EV_DISCONNECT_IND,      lli_release_req},
+	{ST_OUT_DIAL,           EV_RELEASE,             lli_dhup_close},
+	{ST_OUT_DIAL,           EV_NOSETUP_RSP,         lli_no_setup_rsp},
+	{ST_OUT_DIAL,           EV_SETUP_ERR,           lli_error},
+	{ST_IN_WAIT_LL,         EV_LEASED_REL,          lli_failure_l},
+	{ST_IN_WAIT_LL,         EV_ACCEPTD,             lli_setup_rsp},
+	{ST_IN_WAIT_LL,         EV_HANGUP,              lli_reject_req},
+	{ST_IN_WAIT_LL,         EV_DISCONNECT_IND,      lli_release_req},
+	{ST_IN_WAIT_LL,         EV_RELEASE,             lli_dhup_close},
+	{ST_IN_WAIT_LL,         EV_SETUP_IND,           lli_deliver_call},
+	{ST_IN_WAIT_LL,         EV_SETUP_ERR,           lli_error},
+	{ST_IN_ALERT_SENT,      EV_SETUP_CMPL_IND,      lli_init_bchan_in},
+	{ST_IN_ALERT_SENT,      EV_ACCEPTD,             lli_send_dconnect},
+	{ST_IN_ALERT_SENT,      EV_HANGUP,              lli_disconnect_reject},
+	{ST_IN_ALERT_SENT,      EV_DISCONNECT_IND,      lli_release_req},
+	{ST_IN_ALERT_SENT,      EV_RELEASE,             lli_dhup_close},
 	{ST_IN_ALERT_SENT,	EV_REDIR,		lli_send_redir},
 	{ST_IN_PROCEED_SEND,	EV_REDIR,		lli_send_redir},
 	{ST_IN_PROCEED_SEND,	EV_ALERT,		lli_send_alert},
 	{ST_IN_PROCEED_SEND,	EV_ACCEPTD,		lli_send_dconnect},
 	{ST_IN_PROCEED_SEND,	EV_HANGUP,		lli_disconnect_reject},
 	{ST_IN_PROCEED_SEND,	EV_DISCONNECT_IND,	lli_dhup_close},
-        {ST_IN_ALERT_SENT,      EV_RELEASE,             lli_dhup_close},
-        {ST_IN_WAIT_CONN_ACK,   EV_SETUP_CMPL_IND,      lli_init_bchan_in},
-        {ST_IN_WAIT_CONN_ACK,   EV_HANGUP,              lli_disconnect_req},
-        {ST_IN_WAIT_CONN_ACK,   EV_DISCONNECT_IND,      lli_release_req},
-        {ST_IN_WAIT_CONN_ACK,   EV_RELEASE,             lli_dhup_close},
-        {ST_IN_WAIT_CONN_ACK,   EV_CONNECT_ERR,         lli_error},
-        {ST_WAIT_BCONN,         EV_BC_EST,              lli_go_active},
-        {ST_WAIT_BCONN,         EV_BC_REL,              lli_rel_b_disc},
-        {ST_WAIT_BCONN,         EV_HANGUP,              lli_rel_b_disc},
-        {ST_WAIT_BCONN,         EV_DISCONNECT_IND,      lli_rel_b_release_req},
-        {ST_WAIT_BCONN,         EV_RELEASE,             lli_rel_b_dhup},
-        {ST_WAIT_BCONN,         EV_LEASED_REL,          lli_rel_b_fail},
-        {ST_WAIT_BCONN,         EV_CINF,                lli_charge_info},
-        {ST_ACTIVE,             EV_CINF,                lli_charge_info},
-        {ST_ACTIVE,             EV_BC_REL,              lli_bhup_rel_b},
-        {ST_ACTIVE,             EV_SUSPEND,             lli_suspend},
-        {ST_ACTIVE,             EV_HANGUP,              lli_disconn_bchan},
-        {ST_ACTIVE,             EV_DISCONNECT_IND,      lli_release_bchan},
-        {ST_ACTIVE,             EV_RELEASE,             lli_abort},
-        {ST_ACTIVE,             EV_LEASED_REL,          lli_failure_a},
-        {ST_WAIT_BRELEASE,      EV_BC_REL,              lli_bhup_disc},
-        {ST_WAIT_BRELEASE,      EV_DISCONNECT_IND,      lli_bhup_release_req},
-        {ST_WAIT_BRELEASE,      EV_RELEASE,             lli_bhup_dhup},
-        {ST_WAIT_BRELEASE,      EV_LEASED_REL,          lli_bhup_fail},
-        {ST_WAIT_BREL_DISC,     EV_BC_REL,              lli_bhup_release_req},
-        {ST_WAIT_BREL_DISC,     EV_RELEASE,             lli_bhup_dhup},
-        {ST_WAIT_DCOMMAND,      EV_HANGUP,              lli_start_disc},
-        {ST_WAIT_DCOMMAND,      EV_DISCONNECT_IND,      lli_release_req},
-        {ST_WAIT_DCOMMAND,      EV_RELEASE,             lli_dhup_close},
-        {ST_WAIT_DCOMMAND,      EV_LEASED_REL,          lli_failure_l},
-        {ST_WAIT_DRELEASE,      EV_RELEASE,             lli_dhup_close},
-        {ST_WAIT_DRELEASE,      EV_DIAL,                lli_dchan_not_ready},
-  /* ETS 300-104 16.1 */
-        {ST_WAIT_D_REL_CNF,     EV_RELEASE,             lli_dhup_close},
-        {ST_WAIT_D_REL_CNF,     EV_DIAL,                lli_dchan_not_ready},
+	{ST_IN_ALERT_SENT,      EV_RELEASE,             lli_dhup_close},
+	{ST_IN_WAIT_CONN_ACK,   EV_SETUP_CMPL_IND,      lli_init_bchan_in},
+	{ST_IN_WAIT_CONN_ACK,   EV_HANGUP,              lli_disconnect_req},
+	{ST_IN_WAIT_CONN_ACK,   EV_DISCONNECT_IND,      lli_release_req},
+	{ST_IN_WAIT_CONN_ACK,   EV_RELEASE,             lli_dhup_close},
+	{ST_IN_WAIT_CONN_ACK,   EV_CONNECT_ERR,         lli_error},
+	{ST_WAIT_BCONN,         EV_BC_EST,              lli_go_active},
+	{ST_WAIT_BCONN,         EV_BC_REL,              lli_rel_b_disc},
+	{ST_WAIT_BCONN,         EV_HANGUP,              lli_rel_b_disc},
+	{ST_WAIT_BCONN,         EV_DISCONNECT_IND,      lli_rel_b_release_req},
+	{ST_WAIT_BCONN,         EV_RELEASE,             lli_rel_b_dhup},
+	{ST_WAIT_BCONN,         EV_LEASED_REL,          lli_rel_b_fail},
+	{ST_WAIT_BCONN,         EV_CINF,                lli_charge_info},
+	{ST_ACTIVE,             EV_CINF,                lli_charge_info},
+	{ST_ACTIVE,             EV_BC_REL,              lli_bhup_rel_b},
+	{ST_ACTIVE,             EV_SUSPEND,             lli_suspend},
+	{ST_ACTIVE,             EV_HANGUP,              lli_disconn_bchan},
+	{ST_ACTIVE,             EV_DISCONNECT_IND,      lli_release_bchan},
+	{ST_ACTIVE,             EV_RELEASE,             lli_abort},
+	{ST_ACTIVE,             EV_LEASED_REL,          lli_failure_a},
+	{ST_WAIT_BRELEASE,      EV_BC_REL,              lli_bhup_disc},
+	{ST_WAIT_BRELEASE,      EV_DISCONNECT_IND,      lli_bhup_release_req},
+	{ST_WAIT_BRELEASE,      EV_RELEASE,             lli_bhup_dhup},
+	{ST_WAIT_BRELEASE,      EV_LEASED_REL,          lli_bhup_fail},
+	{ST_WAIT_BREL_DISC,     EV_BC_REL,              lli_bhup_release_req},
+	{ST_WAIT_BREL_DISC,     EV_RELEASE,             lli_bhup_dhup},
+	{ST_WAIT_DCOMMAND,      EV_HANGUP,              lli_start_disc},
+	{ST_WAIT_DCOMMAND,      EV_DISCONNECT_IND,      lli_release_req},
+	{ST_WAIT_DCOMMAND,      EV_RELEASE,             lli_dhup_close},
+	{ST_WAIT_DCOMMAND,      EV_LEASED_REL,          lli_failure_l},
+	{ST_WAIT_DRELEASE,      EV_RELEASE,             lli_dhup_close},
+	{ST_WAIT_DRELEASE,      EV_DIAL,                lli_dchan_not_ready},
+	/* ETS 300-104 16.1 */
+	{ST_WAIT_D_REL_CNF,     EV_RELEASE,             lli_dhup_close},
+	{ST_WAIT_D_REL_CNF,     EV_DIAL,                lli_dchan_not_ready},
 };
 /* *INDENT-ON* */
 
@@ -855,21 +855,21 @@ release_b_st(struct Channel *chanp)
 {
 	struct PStack *st = chanp->b_st;
 
-	if(test_and_clear_bit(FLG_START_B, &chanp->Flags)) {
+	if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) {
 		chanp->bcs->BC_Close(chanp->bcs);
 		switch (chanp->l2_active_protocol) {
-			case (ISDN_PROTO_L2_X75I):
-				releasestack_isdnl2(st);
-				break;
-			case (ISDN_PROTO_L2_HDLC):
-			case (ISDN_PROTO_L2_HDLC_56K):
-			case (ISDN_PROTO_L2_TRANS):
-			case (ISDN_PROTO_L2_MODEM):
-			case (ISDN_PROTO_L2_FAX):
-				releasestack_transl2(st);
-				break;
+		case (ISDN_PROTO_L2_X75I):
+			releasestack_isdnl2(st);
+			break;
+		case (ISDN_PROTO_L2_HDLC):
+		case (ISDN_PROTO_L2_HDLC_56K):
+		case (ISDN_PROTO_L2_TRANS):
+		case (ISDN_PROTO_L2_MODEM):
+		case (ISDN_PROTO_L2_FAX):
+			releasestack_transl2(st);
+			break;
 		}
-	} 
+	}
 }
 
 static struct Channel
@@ -880,9 +880,9 @@ static struct Channel
 	int i;
 
 	if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags))
-		i=1;
+		i = 1;
 	else
-		i=0;
+		i = 0;
 
 	if (!bch) {
 		i = 2; /* virtual channel */
@@ -912,10 +912,10 @@ static struct Channel
 
 static void stat_redir_result(struct IsdnCardState *cs, int chan, ulong result)
 {	isdn_ctrl ic;
-  
+
 	ic.driver = cs->myid;
 	ic.command = ISDN_STAT_REDIR;
-	ic.arg = chan; 
+	ic.arg = chan;
 	ic.parm.num[0] = result;
 	cs->iif.statcallb(&ic);
 } /* stat_redir_result */
@@ -927,7 +927,7 @@ dchan_l3l4(struct PStack *st, int pr, void *arg)
 	struct IsdnCardState *cs = st->l1.hardware;
 	struct Channel *chanp;
 
-	if(!pc)
+	if (!pc)
 		return;
 
 	if (pr == (CC_SETUP | INDICATION)) {
@@ -945,63 +945,63 @@ dchan_l3l4(struct PStack *st, int pr, void *arg)
 		return;
 
 	switch (pr) {
-		case (CC_MORE_INFO | INDICATION):
-			FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
-			break;
-		case (CC_DISCONNECT | INDICATION):
-			FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
-			break;
-		case (CC_RELEASE | CONFIRM):
-			FsmEvent(&chanp->fi, EV_RELEASE, NULL);
-			break;
-		case (CC_SUSPEND | CONFIRM):
-			FsmEvent(&chanp->fi, EV_RELEASE, NULL);
-			break;
-		case (CC_RESUME | CONFIRM):
-			FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
-			break;
-		case (CC_RESUME_ERR):
-			FsmEvent(&chanp->fi, EV_RELEASE, NULL);
-			break;
-		case (CC_RELEASE | INDICATION):
-			FsmEvent(&chanp->fi, EV_RELEASE, NULL);
-			break;
-		case (CC_SETUP_COMPL | INDICATION):
-			FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL);
-			break;
-		case (CC_SETUP | CONFIRM):
-			FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
-			break;
-		case (CC_CHARGE | INDICATION):
-			FsmEvent(&chanp->fi, EV_CINF, NULL);
-			break;
-		case (CC_NOSETUP_RSP):
-			FsmEvent(&chanp->fi, EV_NOSETUP_RSP, NULL);
-			break;
-		case (CC_SETUP_ERR):
-			FsmEvent(&chanp->fi, EV_SETUP_ERR, NULL);
-			break;
-		case (CC_CONNECT_ERR):
-			FsmEvent(&chanp->fi, EV_CONNECT_ERR, NULL);
-			break;
-		case (CC_RELEASE_ERR):
-			FsmEvent(&chanp->fi, EV_RELEASE, NULL);
-			break;
-		case (CC_PROCEED_SEND | INDICATION):
-		case (CC_PROCEEDING | INDICATION):
-		case (CC_ALERTING | INDICATION):
-		case (CC_PROGRESS | INDICATION):
-		case (CC_NOTIFY | INDICATION):
-			break;
-		case (CC_REDIR | INDICATION):
-			stat_redir_result(cs, chanp->chan, pc->redir_result); 
-			break;
-			default:
-			if (chanp->debug & 0x800) {
-				HiSax_putstatus(chanp->cs, "Ch",
+	case (CC_MORE_INFO | INDICATION):
+		FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
+		break;
+	case (CC_DISCONNECT | INDICATION):
+		FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
+		break;
+	case (CC_RELEASE | CONFIRM):
+		FsmEvent(&chanp->fi, EV_RELEASE, NULL);
+		break;
+	case (CC_SUSPEND | CONFIRM):
+		FsmEvent(&chanp->fi, EV_RELEASE, NULL);
+		break;
+	case (CC_RESUME | CONFIRM):
+		FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
+		break;
+	case (CC_RESUME_ERR):
+		FsmEvent(&chanp->fi, EV_RELEASE, NULL);
+		break;
+	case (CC_RELEASE | INDICATION):
+		FsmEvent(&chanp->fi, EV_RELEASE, NULL);
+		break;
+	case (CC_SETUP_COMPL | INDICATION):
+		FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL);
+		break;
+	case (CC_SETUP | CONFIRM):
+		FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
+		break;
+	case (CC_CHARGE | INDICATION):
+		FsmEvent(&chanp->fi, EV_CINF, NULL);
+		break;
+	case (CC_NOSETUP_RSP):
+		FsmEvent(&chanp->fi, EV_NOSETUP_RSP, NULL);
+		break;
+	case (CC_SETUP_ERR):
+		FsmEvent(&chanp->fi, EV_SETUP_ERR, NULL);
+		break;
+	case (CC_CONNECT_ERR):
+		FsmEvent(&chanp->fi, EV_CONNECT_ERR, NULL);
+		break;
+	case (CC_RELEASE_ERR):
+		FsmEvent(&chanp->fi, EV_RELEASE, NULL);
+		break;
+	case (CC_PROCEED_SEND | INDICATION):
+	case (CC_PROCEEDING | INDICATION):
+	case (CC_ALERTING | INDICATION):
+	case (CC_PROGRESS | INDICATION):
+	case (CC_NOTIFY | INDICATION):
+		break;
+	case (CC_REDIR | INDICATION):
+		stat_redir_result(cs, chanp->chan, pc->redir_result);
+		break;
+	default:
+		if (chanp->debug & 0x800) {
+			HiSax_putstatus(chanp->cs, "Ch",
 					"%d L3->L4 unknown primitiv %#x",
 					chanp->chan, pr);
-			}
+		}
 	}
 }
 
@@ -1069,7 +1069,7 @@ init_d_st(struct Channel *chanp)
 }
 
 static __printf(2, 3) void
-callc_debug(struct FsmInst *fi, char *fmt, ...)
+	callc_debug(struct FsmInst *fi, char *fmt, ...)
 {
 	va_list args;
 	struct Channel *chanp = fi->userdata;
@@ -1129,8 +1129,8 @@ CallcNewChan(struct IsdnCardState *csta) {
 		return err;
 	printk(KERN_INFO "HiSax: 2 channels added\n");
 
-	for (i = 0; i < MAX_WAITING_CALLS; i++) { 
-		err = init_chan(i+2,csta);
+	for (i = 0; i < MAX_WAITING_CALLS; i++) {
+		err = init_chan(i + 2, csta);
 		if (err)
 			return err;
 	}
@@ -1138,7 +1138,7 @@ CallcNewChan(struct IsdnCardState *csta) {
 	if (test_bit(FLG_PTP, &csta->channel->d_st->l2.flag)) {
 		printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
 		csta->channel->d_st->lli.l4l3(csta->channel->d_st,
-			DL_ESTABLISH | REQUEST, NULL);
+					      DL_ESTABLISH | REQUEST, NULL);
 	}
 	return (0);
 }
@@ -1187,28 +1187,28 @@ lldata_handler(struct PStack *st, int pr, void *arg)
 	struct sk_buff *skb = arg;
 
 	switch (pr) {
-		case (DL_DATA  | INDICATION):
-			if (chanp->data_open) {
-				if (chanp->debug & 0x800)
-					link_debug(chanp, 0, "lldata: %d", skb->len);
-				chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb);
-			} else {
-				link_debug(chanp, 0, "lldata: channel not open");
-				dev_kfree_skb(skb);
-			}
-			break;
-		case (DL_ESTABLISH | INDICATION):
-		case (DL_ESTABLISH | CONFIRM):
-			FsmEvent(&chanp->fi, EV_BC_EST, NULL);
-			break;
-		case (DL_RELEASE | INDICATION):
-		case (DL_RELEASE | CONFIRM):
-			FsmEvent(&chanp->fi, EV_BC_REL, NULL);
-			break;
-		default:
-			printk(KERN_WARNING "lldata_handler unknown primitive %#x\n",
-				pr);
-			break;
+	case (DL_DATA  | INDICATION):
+		if (chanp->data_open) {
+			if (chanp->debug & 0x800)
+				link_debug(chanp, 0, "lldata: %d", skb->len);
+			chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb);
+		} else {
+			link_debug(chanp, 0, "lldata: channel not open");
+			dev_kfree_skb(skb);
+		}
+		break;
+	case (DL_ESTABLISH | INDICATION):
+	case (DL_ESTABLISH | CONFIRM):
+		FsmEvent(&chanp->fi, EV_BC_EST, NULL);
+		break;
+	case (DL_RELEASE | INDICATION):
+	case (DL_RELEASE | CONFIRM):
+		FsmEvent(&chanp->fi, EV_BC_REL, NULL);
+		break;
+	default:
+		printk(KERN_WARNING "lldata_handler unknown primitive %#x\n",
+		       pr);
+		break;
 	}
 }
 
@@ -1219,28 +1219,28 @@ lltrans_handler(struct PStack *st, int pr, void *arg)
 	struct sk_buff *skb = arg;
 
 	switch (pr) {
-		case (PH_DATA | INDICATION):
-			if (chanp->data_open) {
-				if (chanp->debug & 0x800)
-					link_debug(chanp, 0, "lltrans: %d", skb->len);
-				chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb);
-			} else {
-				link_debug(chanp, 0, "lltrans: channel not open");
-				dev_kfree_skb(skb);
-			}
-			break;
-		case (PH_ACTIVATE | INDICATION):
-		case (PH_ACTIVATE | CONFIRM):
-			FsmEvent(&chanp->fi, EV_BC_EST, NULL);
-			break;
-		case (PH_DEACTIVATE | INDICATION):
-		case (PH_DEACTIVATE | CONFIRM):
-			FsmEvent(&chanp->fi, EV_BC_REL, NULL);
-			break;
-		default:
-			printk(KERN_WARNING "lltrans_handler unknown primitive %#x\n",
-				pr);
-			break;
+	case (PH_DATA | INDICATION):
+		if (chanp->data_open) {
+			if (chanp->debug & 0x800)
+				link_debug(chanp, 0, "lltrans: %d", skb->len);
+			chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb);
+		} else {
+			link_debug(chanp, 0, "lltrans: channel not open");
+			dev_kfree_skb(skb);
+		}
+		break;
+	case (PH_ACTIVATE | INDICATION):
+	case (PH_ACTIVATE | CONFIRM):
+		FsmEvent(&chanp->fi, EV_BC_EST, NULL);
+		break;
+	case (PH_DEACTIVATE | INDICATION):
+	case (PH_DEACTIVATE | CONFIRM):
+		FsmEvent(&chanp->fi, EV_BC_REL, NULL);
+		break;
+	default:
+		printk(KERN_WARNING "lltrans_handler unknown primitive %#x\n",
+		       pr);
+		break;
 	}
 }
 
@@ -1272,22 +1272,22 @@ init_b_st(struct Channel *chanp, int incoming)
 	else
 		st->l1.bc = chanp->proc->para.bchannel - 1;
 	switch (chanp->l2_active_protocol) {
-		case (ISDN_PROTO_L2_X75I):
-		case (ISDN_PROTO_L2_HDLC):
-			st->l1.mode = L1_MODE_HDLC;
-			break;
-		case (ISDN_PROTO_L2_HDLC_56K):
-			st->l1.mode = L1_MODE_HDLC_56K;
-			break;
-		case (ISDN_PROTO_L2_TRANS):
-			st->l1.mode = L1_MODE_TRANS;
-			break;
-		case (ISDN_PROTO_L2_MODEM):
-			st->l1.mode = L1_MODE_V32;
-			break;
-		case (ISDN_PROTO_L2_FAX):
-			st->l1.mode = L1_MODE_FAX;
-			break;
+	case (ISDN_PROTO_L2_X75I):
+	case (ISDN_PROTO_L2_HDLC):
+		st->l1.mode = L1_MODE_HDLC;
+		break;
+	case (ISDN_PROTO_L2_HDLC_56K):
+		st->l1.mode = L1_MODE_HDLC_56K;
+		break;
+	case (ISDN_PROTO_L2_TRANS):
+		st->l1.mode = L1_MODE_TRANS;
+		break;
+	case (ISDN_PROTO_L2_MODEM):
+		st->l1.mode = L1_MODE_V32;
+		break;
+	case (ISDN_PROTO_L2_FAX):
+		st->l1.mode = L1_MODE_FAX;
+		break;
 	}
 	chanp->bcs->conmsg = NULL;
 	if (chanp->bcs->BC_SetStack(st, chanp->bcs))
@@ -1303,29 +1303,29 @@ init_b_st(struct Channel *chanp, int incoming)
 	st->l2.T203 = 5000;	/* 5000 milliseconds */
 	st->l3.debug = 0;
 	switch (chanp->l2_active_protocol) {
-		case (ISDN_PROTO_L2_X75I):
-			sprintf(tmp, "Ch%d X.75", chanp->chan);
-			setstack_isdnl2(st, tmp);
-			setstack_l3bc(st, chanp);
-			st->l2.l2l3 = lldata_handler;
-			st->lli.userdata = chanp;
-			test_and_clear_bit(FLG_LLI_L1WAKEUP, &st->lli.flag);
-			test_and_set_bit(FLG_LLI_L2WAKEUP, &st->lli.flag);
-			st->l2.l2m.debug = chanp->debug & 16;
-			st->l2.debug = chanp->debug & 64;
-			break;
-		case (ISDN_PROTO_L2_HDLC):
-		case (ISDN_PROTO_L2_HDLC_56K):
-		case (ISDN_PROTO_L2_TRANS):
-		case (ISDN_PROTO_L2_MODEM):
-		case (ISDN_PROTO_L2_FAX):
-			st->l1.l1l2 = lltrans_handler;
-			st->lli.userdata = chanp;
-			test_and_set_bit(FLG_LLI_L1WAKEUP, &st->lli.flag);
-			test_and_clear_bit(FLG_LLI_L2WAKEUP, &st->lli.flag);
-			setstack_transl2(st);
-			setstack_l3bc(st, chanp);
-			break;
+	case (ISDN_PROTO_L2_X75I):
+		sprintf(tmp, "Ch%d X.75", chanp->chan);
+		setstack_isdnl2(st, tmp);
+		setstack_l3bc(st, chanp);
+		st->l2.l2l3 = lldata_handler;
+		st->lli.userdata = chanp;
+		test_and_clear_bit(FLG_LLI_L1WAKEUP, &st->lli.flag);
+		test_and_set_bit(FLG_LLI_L2WAKEUP, &st->lli.flag);
+		st->l2.l2m.debug = chanp->debug & 16;
+		st->l2.debug = chanp->debug & 64;
+		break;
+	case (ISDN_PROTO_L2_HDLC):
+	case (ISDN_PROTO_L2_HDLC_56K):
+	case (ISDN_PROTO_L2_TRANS):
+	case (ISDN_PROTO_L2_MODEM):
+	case (ISDN_PROTO_L2_FAX):
+		st->l1.l1l2 = lltrans_handler;
+		st->lli.userdata = chanp;
+		test_and_set_bit(FLG_LLI_L1WAKEUP, &st->lli.flag);
+		test_and_clear_bit(FLG_LLI_L2WAKEUP, &st->lli.flag);
+		setstack_transl2(st);
+		setstack_l3bc(st, chanp);
+		break;
 	}
 	test_and_set_bit(FLG_START_B, &chanp->Flags);
 	return (0);
@@ -1338,19 +1338,19 @@ leased_l4l3(struct PStack *st, int pr, void *arg)
 	struct sk_buff *skb = arg;
 
 	switch (pr) {
-		case (DL_DATA | REQUEST):
-			link_debug(chanp, 0, "leased line d-channel DATA");
-			dev_kfree_skb(skb);
-			break;
-		case (DL_ESTABLISH | REQUEST):
-			st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);
-			break;
-		case (DL_RELEASE | REQUEST):
-			break;
-		default:
-			printk(KERN_WARNING "transd_l4l3 unknown primitive %#x\n",
-				pr);
-			break;
+	case (DL_DATA | REQUEST):
+		link_debug(chanp, 0, "leased line d-channel DATA");
+		dev_kfree_skb(skb);
+		break;
+	case (DL_ESTABLISH | REQUEST):
+		st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);
+		break;
+	case (DL_RELEASE | REQUEST):
+		break;
+	default:
+		printk(KERN_WARNING "transd_l4l3 unknown primitive %#x\n",
+		       pr);
+		break;
 	}
 }
 
@@ -1359,32 +1359,32 @@ leased_l1l2(struct PStack *st, int pr, void *arg)
 {
 	struct Channel *chanp = (struct Channel *) st->lli.userdata;
 	struct sk_buff *skb = arg;
-	int i,event = EV_LEASED_REL;
+	int i, event = EV_LEASED_REL;
 
 	switch (pr) {
-		case (PH_DATA | INDICATION):
-			link_debug(chanp, 0, "leased line d-channel DATA");
-			dev_kfree_skb(skb);
-			break;
-		case (PH_ACTIVATE | INDICATION):
-		case (PH_ACTIVATE | CONFIRM):
-			event = EV_LEASED;
-		case (PH_DEACTIVATE | INDICATION):
-		case (PH_DEACTIVATE | CONFIRM):
-			if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags))
-				i = 1;
-			else
-				i = 0;
-			while (i < 2) {
-				FsmEvent(&chanp->fi, event, NULL);
-				chanp++;
-				i++;
-			}
-			break;
-		default:
-			printk(KERN_WARNING
-				"transd_l1l2 unknown primitive %#x\n", pr);
-			break;
+	case (PH_DATA | INDICATION):
+		link_debug(chanp, 0, "leased line d-channel DATA");
+		dev_kfree_skb(skb);
+		break;
+	case (PH_ACTIVATE | INDICATION):
+	case (PH_ACTIVATE | CONFIRM):
+		event = EV_LEASED;
+	case (PH_DEACTIVATE | INDICATION):
+	case (PH_DEACTIVATE | CONFIRM):
+		if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags))
+			i = 1;
+		else
+			i = 0;
+		while (i < 2) {
+			FsmEvent(&chanp->fi, event, NULL);
+			chanp++;
+			i++;
+		}
+		break;
+	default:
+		printk(KERN_WARNING
+		       "transd_l1l2 unknown primitive %#x\n", pr);
+		break;
 	}
 }
 
@@ -1394,7 +1394,7 @@ distr_debug(struct IsdnCardState *csta, int debugflags)
 	int i;
 	struct Channel *chanp = csta->channel;
 
-	for (i = 0; i < (2 + MAX_WAITING_CALLS) ; i++) {
+	for (i = 0; i < (2 + MAX_WAITING_CALLS); i++) {
 		chanp[i].debug = debugflags;
 		chanp[i].fi.debug = debugflags & 2;
 		chanp[i].d_st->l2.l2m.debug = debugflags & 8;
@@ -1421,9 +1421,9 @@ capi_debug(struct Channel *chanp, capi_msg *cm)
 {
 	char *t = tmpbuf;
 
-	t += QuickHex(t, (u_char *)cm, (cm->Length>50)? 50: cm->Length);
+	t += QuickHex(t, (u_char *)cm, (cm->Length > 50) ? 50 : cm->Length);
 	t--;
-	*t= 0;
+	*t = 0;
 	HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);
 }
 
@@ -1431,31 +1431,31 @@ static void
 lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
 	if ((cm->para[0] != 3) || (cm->para[1] != 0))
 		return;
-	if (cm->para[2]<3)
+	if (cm->para[2] < 3)
 		return;
 	if (cm->para[4] != 0)
 		return;
-	switch(cm->para[3]) {
-		case 4: /* Suspend */
-			strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);
-			FsmEvent(&chanp->fi, EV_SUSPEND, cm);
-			break;
-		case 5: /* Resume */
-			strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);
-			if (chanp->fi.state == ST_NULL) {
-				FsmEvent(&chanp->fi, EV_RESUME, cm);
-			} else {
-				FsmDelTimer(&chanp->dial_timer, 72);
-				FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73);
-			}
-			break;
+	switch (cm->para[3]) {
+	case 4: /* Suspend */
+		strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] + 1);
+		FsmEvent(&chanp->fi, EV_SUSPEND, cm);
+		break;
+	case 5: /* Resume */
+		strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] + 1);
+		if (chanp->fi.state == ST_NULL) {
+			FsmEvent(&chanp->fi, EV_RESUME, cm);
+		} else {
+			FsmDelTimer(&chanp->dial_timer, 72);
+			FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73);
+		}
+		break;
 	}
 }
 
 static void
 lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
 	if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||
-		(cs->typ == ISDN_CTYPE_ELSA_PCI)) {
+	    (cs->typ == ISDN_CTYPE_ELSA_PCI)) {
 		if (cs->hw.elsa.MFlag) {
 			cs->cardmsg(cs, CARD_AUX_IND, cm->para);
 		}
@@ -1466,14 +1466,14 @@ lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *
 /***************************************************************/
 /* Limit the available number of channels for the current card */
 /***************************************************************/
-static int 
+static int
 set_channel_limit(struct IsdnCardState *cs, int chanmax)
 {
 	isdn_ctrl ic;
 	int i, ii;
 
 	if ((chanmax < 0) || (chanmax > 2))
-		return(-EINVAL);
+		return (-EINVAL);
 	cs->chanlimit = 0;
 	for (ii = 0; ii < 2; ii++) {
 		ic.driver = cs->myid;
@@ -1483,16 +1483,16 @@ set_channel_limit(struct IsdnCardState *cs, int chanmax)
 			ic.parm.num[0] = 0; /* disabled */
 		else
 			ic.parm.num[0] = 1; /* enabled */
-		i = cs->iif.statcallb(&ic); 
-		if (i) return(-EINVAL);
-		if (ii < chanmax) 
+		i = cs->iif.statcallb(&ic);
+		if (i) return (-EINVAL);
+		if (ii < chanmax)
 			cs->chanlimit++;
 	}
-	return(0);
+	return (0);
 } /* set_channel_limit */
 
 int
-HiSax_command(isdn_ctrl * ic)
+HiSax_command(isdn_ctrl *ic)
 {
 	struct IsdnCardState *csta = hisax_findcard(ic->driver);
 	struct PStack *st;
@@ -1502,236 +1502,236 @@ HiSax_command(isdn_ctrl * ic)
 
 	if (!csta) {
 		printk(KERN_ERR
-		"HiSax: if_command %d called with invalid driverId %d!\n",
-			ic->command, ic->driver);
+		       "HiSax: if_command %d called with invalid driverId %d!\n",
+		       ic->command, ic->driver);
 		return -ENODEV;
 	}
 	switch (ic->command) {
-		case (ISDN_CMD_SETEAZ):
-			chanp = csta->channel + ic->arg;
+	case (ISDN_CMD_SETEAZ):
+		chanp = csta->channel + ic->arg;
+		break;
+	case (ISDN_CMD_SETL2):
+		chanp = csta->channel + (ic->arg & 0xff);
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "SETL2 card %d %ld",
+				   csta->cardnr + 1, ic->arg >> 8);
+		chanp->l2_protocol = ic->arg >> 8;
+		break;
+	case (ISDN_CMD_SETL3):
+		chanp = csta->channel + (ic->arg & 0xff);
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "SETL3 card %d %ld",
+				   csta->cardnr + 1, ic->arg >> 8);
+		chanp->l3_protocol = ic->arg >> 8;
+		break;
+	case (ISDN_CMD_DIAL):
+		chanp = csta->channel + (ic->arg & 0xff);
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "DIAL %s -> %s (%d,%d)",
+				   ic->parm.setup.eazmsn, ic->parm.setup.phone,
+				   ic->parm.setup.si1, ic->parm.setup.si2);
+		memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
+		if (!strcmp(chanp->setup.eazmsn, "0"))
+			chanp->setup.eazmsn[0] = '\0';
+		/* this solution is dirty and may be change, if
+		 * we make a callreference based callmanager */
+		if (chanp->fi.state == ST_NULL) {
+			FsmEvent(&chanp->fi, EV_DIAL, NULL);
+		} else {
+			FsmDelTimer(&chanp->dial_timer, 70);
+			FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71);
+		}
+		break;
+	case (ISDN_CMD_ACCEPTB):
+		chanp = csta->channel + ic->arg;
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "ACCEPTB");
+		FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);
+		break;
+	case (ISDN_CMD_ACCEPTD):
+		chanp = csta->channel + ic->arg;
+		memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "ACCEPTD");
+		FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);
+		break;
+	case (ISDN_CMD_HANGUP):
+		chanp = csta->channel + ic->arg;
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "HANGUP");
+		FsmEvent(&chanp->fi, EV_HANGUP, NULL);
+		break;
+	case (CAPI_PUT_MESSAGE):
+		chanp = csta->channel + ic->arg;
+		if (chanp->debug & 1)
+			capi_debug(chanp, &ic->parm.cmsg);
+		if (ic->parm.cmsg.Length < 8)
 			break;
-		case (ISDN_CMD_SETL2):
-			chanp = csta->channel + (ic->arg & 0xff);
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "SETL2 card %d %ld",
-					csta->cardnr + 1, ic->arg >> 8);
-			chanp->l2_protocol = ic->arg >> 8;
+		switch (ic->parm.cmsg.Command) {
+		case CAPI_FACILITY:
+			if (ic->parm.cmsg.Subcommand == CAPI_REQ)
+				lli_got_fac_req(chanp, &ic->parm.cmsg);
 			break;
-		case (ISDN_CMD_SETL3):
-			chanp = csta->channel + (ic->arg & 0xff);
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "SETL3 card %d %ld",
-					csta->cardnr + 1, ic->arg >> 8);
-			chanp->l3_protocol = ic->arg >> 8;
+		case CAPI_MANUFACTURER:
+			if (ic->parm.cmsg.Subcommand == CAPI_REQ)
+				lli_got_manufacturer(chanp, csta, &ic->parm.cmsg);
 			break;
-		case (ISDN_CMD_DIAL):
-			chanp = csta->channel + (ic->arg & 0xff);
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "DIAL %s -> %s (%d,%d)",
-					ic->parm.setup.eazmsn, ic->parm.setup.phone,
-					ic->parm.setup.si1, ic->parm.setup.si2);
-			memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
-			if (!strcmp(chanp->setup.eazmsn, "0"))
-				chanp->setup.eazmsn[0] = '\0';
-			/* this solution is dirty and may be change, if
-			 * we make a callreference based callmanager */
-			if (chanp->fi.state == ST_NULL) {
-				FsmEvent(&chanp->fi, EV_DIAL, NULL);
-			} else {
-				FsmDelTimer(&chanp->dial_timer, 70);
-				FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71);
-			}
+		default:
 			break;
-		case (ISDN_CMD_ACCEPTB):
-			chanp = csta->channel + ic->arg;
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "ACCEPTB");
-			FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);
+		}
+		break;
+	case (ISDN_CMD_IOCTL):
+		switch (ic->arg) {
+		case (0):
+			num = *(unsigned int *) ic->parm.num;
+			HiSax_reportcard(csta->cardnr, num);
 			break;
-		case (ISDN_CMD_ACCEPTD):
-			chanp = csta->channel + ic->arg;
-			memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "ACCEPTD");
-			FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);
+		case (1):
+			num = *(unsigned int *) ic->parm.num;
+			distr_debug(csta, num);
+			printk(KERN_DEBUG "HiSax: debugging flags card %d set to %x\n",
+			       csta->cardnr + 1, num);
+			HiSax_putstatus(csta, "debugging flags ",
+					"card %d set to %x", csta->cardnr + 1, num);
 			break;
-		case (ISDN_CMD_HANGUP):
-			chanp = csta->channel + ic->arg;
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "HANGUP");
-			FsmEvent(&chanp->fi, EV_HANGUP, NULL);
+		case (2):
+			num = *(unsigned int *) ic->parm.num;
+			csta->channel[0].b_st->l1.delay = num;
+			csta->channel[1].b_st->l1.delay = num;
+			HiSax_putstatus(csta, "delay ", "card %d set to %d ms",
+					csta->cardnr + 1, num);
+			printk(KERN_DEBUG "HiSax: delay card %d set to %d ms\n",
+			       csta->cardnr + 1, num);
 			break;
-		case (CAPI_PUT_MESSAGE):
-			chanp = csta->channel + ic->arg;
-			if (chanp->debug & 1)
-				capi_debug(chanp, &ic->parm.cmsg);
-			if (ic->parm.cmsg.Length < 8)
-				break;
-			switch(ic->parm.cmsg.Command) {
-				case CAPI_FACILITY:
-					if (ic->parm.cmsg.Subcommand == CAPI_REQ)
-						lli_got_fac_req(chanp, &ic->parm.cmsg);
-					break;
-				case CAPI_MANUFACTURER:
-					if (ic->parm.cmsg.Subcommand == CAPI_REQ)
-						lli_got_manufacturer(chanp, csta, &ic->parm.cmsg);
-					break;
-				default:
-					break;
+		case (5):	/* set card in leased mode */
+			num = *(unsigned int *) ic->parm.num;
+			if ((num < 1) || (num > 2)) {
+				HiSax_putstatus(csta, "Set LEASED ",
+						"wrong channel %d", num);
+				printk(KERN_WARNING "HiSax: Set LEASED wrong channel %d\n",
+				       num);
+			} else {
+				num--;
+				chanp = csta->channel + num;
+				chanp->leased = 1;
+				HiSax_putstatus(csta, "Card",
+						"%d channel %d set leased mode\n",
+						csta->cardnr + 1, num + 1);
+				chanp->d_st->l1.l1l2 = leased_l1l2;
+				chanp->d_st->lli.l4l3 = leased_l4l3;
+				chanp->d_st->lli.l4l3(chanp->d_st,
+						      DL_ESTABLISH | REQUEST, NULL);
 			}
 			break;
-		case (ISDN_CMD_IOCTL):
-			switch (ic->arg) {
-				case (0):
-					num = *(unsigned int *) ic->parm.num;
-					HiSax_reportcard(csta->cardnr, num);
-					break;
-				case (1):
-					num = *(unsigned int *) ic->parm.num;
-					distr_debug(csta, num);
-					printk(KERN_DEBUG "HiSax: debugging flags card %d set to %x\n",
-						csta->cardnr + 1, num);
-					HiSax_putstatus(csta, "debugging flags ",
-						"card %d set to %x", csta->cardnr + 1, num);
-					break;
-				case (2):
-					num = *(unsigned int *) ic->parm.num;
-					csta->channel[0].b_st->l1.delay = num;
-					csta->channel[1].b_st->l1.delay = num;
-					HiSax_putstatus(csta, "delay ", "card %d set to %d ms",
-						csta->cardnr + 1, num);
-					printk(KERN_DEBUG "HiSax: delay card %d set to %d ms\n",
-						csta->cardnr + 1, num);
-					break;
-				case (5):	/* set card in leased mode */
-					num = *(unsigned int *) ic->parm.num;
-					if ((num <1) || (num > 2)) {
-						HiSax_putstatus(csta, "Set LEASED ",
-							"wrong channel %d", num);
-						printk(KERN_WARNING "HiSax: Set LEASED wrong channel %d\n",
-							num);
-					} else {
-						num--;
-						chanp = csta->channel +num;
-						chanp->leased = 1;
-						HiSax_putstatus(csta, "Card",
-							"%d channel %d set leased mode\n",
-							csta->cardnr + 1, num + 1);
-						chanp->d_st->l1.l1l2 = leased_l1l2;
-						chanp->d_st->lli.l4l3 = leased_l4l3;
-						chanp->d_st->lli.l4l3(chanp->d_st,
-							DL_ESTABLISH | REQUEST, NULL);
-					}
-					break;
-				case (6):	/* set B-channel test loop */
-					num = *(unsigned int *) ic->parm.num;
-					if (csta->stlist)
-						csta->stlist->l2.l2l1(csta->stlist,
-							PH_TESTLOOP | REQUEST, (void *) (long)num);
-					break;
-				case (7):	/* set card in PTP mode */
-					num = *(unsigned int *) ic->parm.num;
-					if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {
-						printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n");
-					} else if (num) {
-						test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
-						test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
-						csta->channel[0].d_st->l2.tei = 0;
-						HiSax_putstatus(csta, "set card ", "in PTP mode");
-						printk(KERN_DEBUG "HiSax: set card in PTP mode\n");
-						printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
-						csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st,
-							DL_ESTABLISH | REQUEST, NULL);
-					} else {
-						test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
-						test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
-						HiSax_putstatus(csta, "set card ", "in PTMP mode");
-						printk(KERN_DEBUG "HiSax: set card in PTMP mode\n");
-					}
-					break;
-				case (8):	/* set card in FIXED TEI mode */
-					num = *(unsigned int *) ic->parm.num;
-					chanp = csta->channel + (num & 1);
-					num = num >>1;
-					if (num == 127) {
-						test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
-						chanp->d_st->l2.tei = -1;
-						HiSax_putstatus(csta, "set card ", "in VAR TEI mode");
-						printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n");
-					} else {
-						test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
-						chanp->d_st->l2.tei = num;
-						HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num);
-						printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n",
-							num);
-					}
-					chanp->d_st->lli.l4l3(chanp->d_st,
-						DL_ESTABLISH | REQUEST, NULL);
-					break;
-				case (11):
-					num = csta->debug & DEB_DLOG_HEX;
-					csta->debug = *(unsigned int *) ic->parm.num;
-					csta->debug |= num;
-					HiSax_putstatus(cards[0].cs, "l1 debugging ",
-						"flags card %d set to %x",
-						csta->cardnr + 1, csta->debug);
-					printk(KERN_DEBUG "HiSax: l1 debugging flags card %d set to %x\n",
-						csta->cardnr + 1, csta->debug);
-					break;
-				case (13):
-					csta->channel[0].d_st->l3.debug = *(unsigned int *) ic->parm.num;
-					csta->channel[1].d_st->l3.debug = *(unsigned int *) ic->parm.num;
-					HiSax_putstatus(cards[0].cs, "l3 debugging ",
-						"flags card %d set to %x\n", csta->cardnr + 1,
-						*(unsigned int *) ic->parm.num);
-					printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n",
-						csta->cardnr + 1, *(unsigned int *) ic->parm.num);
-					break;
-				case (10):
-					i = *(unsigned int *) ic->parm.num;
-					return(set_channel_limit(csta, i));
-				default:
-					if (csta->auxcmd)
-						return(csta->auxcmd(csta, ic));
-					printk(KERN_DEBUG "HiSax: invalid ioclt %d\n",
-						(int) ic->arg);
-					return (-EINVAL);
-			}
+		case (6):	/* set B-channel test loop */
+			num = *(unsigned int *) ic->parm.num;
+			if (csta->stlist)
+				csta->stlist->l2.l2l1(csta->stlist,
+						      PH_TESTLOOP | REQUEST, (void *) (long)num);
 			break;
-		
-		case (ISDN_CMD_PROCEED):
-			chanp = csta->channel + ic->arg;
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "PROCEED");
-			FsmEvent(&chanp->fi, EV_PROCEED, NULL);
+		case (7):	/* set card in PTP mode */
+			num = *(unsigned int *) ic->parm.num;
+			if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {
+				printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n");
+			} else if (num) {
+				test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
+				test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
+				csta->channel[0].d_st->l2.tei = 0;
+				HiSax_putstatus(csta, "set card ", "in PTP mode");
+				printk(KERN_DEBUG "HiSax: set card in PTP mode\n");
+				printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
+				csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st,
+								DL_ESTABLISH | REQUEST, NULL);
+			} else {
+				test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
+				test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
+				HiSax_putstatus(csta, "set card ", "in PTMP mode");
+				printk(KERN_DEBUG "HiSax: set card in PTMP mode\n");
+			}
 			break;
-
-		case (ISDN_CMD_ALERT):
-			chanp = csta->channel + ic->arg;
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "ALERT");
-			FsmEvent(&chanp->fi, EV_ALERT, NULL);
+		case (8):	/* set card in FIXED TEI mode */
+			num = *(unsigned int *)ic->parm.num;
+			chanp = csta->channel + (num & 1);
+			num = num >> 1;
+			if (num == 127) {
+				test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
+				chanp->d_st->l2.tei = -1;
+				HiSax_putstatus(csta, "set card ", "in VAR TEI mode");
+				printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n");
+			} else {
+				test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
+				chanp->d_st->l2.tei = num;
+				HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num);
+				printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n",
+				       num);
+			}
+			chanp->d_st->lli.l4l3(chanp->d_st,
+					      DL_ESTABLISH | REQUEST, NULL);
 			break;
-
-		case (ISDN_CMD_REDIR):
-			chanp = csta->channel + ic->arg;
-			if (chanp->debug & 1)
-				link_debug(chanp, 1, "REDIR");
-			memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
-			FsmEvent(&chanp->fi, EV_REDIR, NULL);
+		case (11):
+			num = csta->debug & DEB_DLOG_HEX;
+			csta->debug = *(unsigned int *) ic->parm.num;
+			csta->debug |= num;
+			HiSax_putstatus(cards[0].cs, "l1 debugging ",
+					"flags card %d set to %x",
+					csta->cardnr + 1, csta->debug);
+			printk(KERN_DEBUG "HiSax: l1 debugging flags card %d set to %x\n",
+			       csta->cardnr + 1, csta->debug);
 			break;
-
-		/* protocol specific io commands */
-		case (ISDN_CMD_PROT_IO):
-			for (st = csta->stlist; st; st = st->next)
-				if (st->protocol == (ic->arg & 0xFF))
-					return(st->lli.l4l3_proto(st, ic));
-			return(-EINVAL);
+		case (13):
+			csta->channel[0].d_st->l3.debug = *(unsigned int *) ic->parm.num;
+			csta->channel[1].d_st->l3.debug = *(unsigned int *) ic->parm.num;
+			HiSax_putstatus(cards[0].cs, "l3 debugging ",
+					"flags card %d set to %x\n", csta->cardnr + 1,
+					*(unsigned int *) ic->parm.num);
+			printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n",
+			       csta->cardnr + 1, *(unsigned int *) ic->parm.num);
 			break;
+		case (10):
+			i = *(unsigned int *) ic->parm.num;
+			return (set_channel_limit(csta, i));
 		default:
 			if (csta->auxcmd)
-				return(csta->auxcmd(csta, ic));
-			return(-EINVAL);
+				return (csta->auxcmd(csta, ic));
+			printk(KERN_DEBUG "HiSax: invalid ioctl %d\n",
+			       (int) ic->arg);
+			return (-EINVAL);
+		}
+		break;
+
+	case (ISDN_CMD_PROCEED):
+		chanp = csta->channel + ic->arg;
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "PROCEED");
+		FsmEvent(&chanp->fi, EV_PROCEED, NULL);
+		break;
+
+	case (ISDN_CMD_ALERT):
+		chanp = csta->channel + ic->arg;
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "ALERT");
+		FsmEvent(&chanp->fi, EV_ALERT, NULL);
+		break;
+
+	case (ISDN_CMD_REDIR):
+		chanp = csta->channel + ic->arg;
+		if (chanp->debug & 1)
+			link_debug(chanp, 1, "REDIR");
+		memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
+		FsmEvent(&chanp->fi, EV_REDIR, NULL);
+		break;
+
+		/* protocol specific io commands */
+	case (ISDN_CMD_PROT_IO):
+		for (st = csta->stlist; st; st = st->next)
+			if (st->protocol == (ic->arg & 0xFF))
+				return (st->lli.l4l3_proto(st, ic));
+		return (-EINVAL);
+		break;
+	default:
+		if (csta->auxcmd)
+			return (csta->auxcmd(csta, ic));
+		return (-EINVAL);
 	}
 	return (0);
 }
@@ -1747,7 +1747,7 @@ HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb)
 
 	if (!csta) {
 		printk(KERN_ERR
-			"HiSax: if_sendbuf called with invalid driverId!\n");
+		       "HiSax: if_sendbuf called with invalid driverId!\n");
 		return -ENODEV;
 	}
 	chanp = csta->channel + chan;
@@ -1759,7 +1759,7 @@ HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb)
 	if (len > MAX_DATA_SIZE) {
 		link_debug(chanp, 1, "writebuf: packet too large (%d bytes)", len);
 		printk(KERN_WARNING "HiSax_writebuf: packet too large (%d bytes) !\n",
-			len);
+		       len);
 		return -EINVAL;
 	}
 	if (len) {
@@ -1771,7 +1771,7 @@ HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb)
 				link_debug(chanp, 1, "writebuf: no buffers for %d bytes", len);
 			return 0;
 		} else if (chanp->debug & 0x800)
-			link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt,MAX_DATA_MEM);
+			link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt, MAX_DATA_MEM);
 		nskb = skb_clone(skb, GFP_ATOMIC);
 		if (nskb) {
 			nskb->truesize = nskb->len;
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index c110f86..b5edc0e 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -3,7 +3,7 @@
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *              by Kai Germaschewski <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -61,8 +61,8 @@
  *   24 Dr Neuhaus Niccy PnP/PCI card p0=irq p1=IO0 p2=IO1 (PnP only)
  *   25 Teles S0Box             p0=irq p1=iobase (from isapnp setup)
  *   26 AVM A1 PCMCIA (Fritz)   p0=irq p1=iobase
- *   27 AVM PnP/PCI 		p0=irq p1=iobase (PCI no parameter)
- *   28 Sedlbauer Speed Fax+ 	p0=irq p1=iobase (from isapnp setup)
+ *   27 AVM PnP/PCI		p0=irq p1=iobase (PCI no parameter)
+ *   28 Sedlbauer Speed Fax+	p0=irq p1=iobase (from isapnp setup)
  *   29 Siemens I-Surf          p0=irq p1=iobase p2=memory (from isapnp setup)
  *   30 ACER P10                p0=irq p1=iobase (from isapnp setup)
  *   31 HST Saphir              p0=irq  p1=iobase
@@ -88,200 +88,200 @@ const char *CardType[] = {
 	"Teles PCMCIA",	"ITK ix1-micro Rev.2", "Elsa PCMCIA",
 	"Eicon.Diehl Diva", "ISDNLink",	"TeleInt", "Teles 16.3c",
 	"Sedlbauer Speed Card", "USR Sportster", "ith mic Linux",
-	"Elsa PCI", "Compaq ISA", "NETjet-S", "Teles PCI", 
+	"Elsa PCI", "Compaq ISA", "NETjet-S", "Teles PCI",
 	"Sedlbauer Speed Star (PCMCIA)", "AMD 7930", "NICCY", "S0Box",
 	"AVM A1 (PCMCIA)", "AVM Fritz PnP/PCI", "Sedlbauer Speed Fax +",
 	"Siemens I-Surf", "Acer P10", "HST Saphir", "Telekom A4T",
 	"Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", "Winbond 6692",
 	"HFC 2BDS0 SX", "NETspider-U", "HFC-2BDS0-SP PCMCIA",
-	"Hotplug", "Formula-n enter:now PCI a/b", 
+	"Hotplug", "Formula-n enter:now PCI a/b",
 };
 
 #ifdef CONFIG_HISAX_ELSA
 #define DEFAULT_CARD ISDN_CTYPE_ELSA
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_AVM_A1
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_A1
-#define DEFAULT_CFG {10,0x340,0,0}
+#define DEFAULT_CFG {10, 0x340, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_AVM_A1_PCMCIA
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_A1_PCMCIA
-#define DEFAULT_CFG {11,0x170,0,0}
+#define DEFAULT_CFG {11, 0x170, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_FRITZPCI
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_FRITZPCI
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_16_3
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_16_3
-#define DEFAULT_CFG {15,0x180,0,0}
+#define DEFAULT_CFG {15, 0x180, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_S0BOX
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_S0BOX
-#define DEFAULT_CFG {7,0x378,0,0}
+#define DEFAULT_CFG {7, 0x378, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_16_0
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_16_0
-#define DEFAULT_CFG {15,0xd0000,0xd80,0}
+#define DEFAULT_CFG {15, 0xd0000, 0xd80, 0}
 #endif
 
 #ifdef CONFIG_HISAX_TELESPCI
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_TELESPCI
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_IX1MICROR2
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_IX1MICROR2
-#define DEFAULT_CFG {5,0x390,0,0}
+#define DEFAULT_CFG {5, 0x390, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_DIEHLDIVA
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_DIEHLDIVA
-#define DEFAULT_CFG {0,0x0,0,0}
+#define DEFAULT_CFG {0, 0x0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_ASUSCOM
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_ASUSCOM
-#define DEFAULT_CFG {5,0x200,0,0}
+#define DEFAULT_CFG {5, 0x200, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_TELEINT
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_TELEINT
-#define DEFAULT_CFG {5,0x300,0,0}
+#define DEFAULT_CFG {5, 0x300, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_SEDLBAUER
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER
-#define DEFAULT_CFG {11,0x270,0,0}
+#define DEFAULT_CFG {11, 0x270, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_SPORTSTER
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_SPORTSTER
-#define DEFAULT_CFG {7,0x268,0,0}
+#define DEFAULT_CFG {7, 0x268, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_MIC
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_MIC
-#define DEFAULT_CFG {12,0x3e0,0,0}
+#define DEFAULT_CFG {12, 0x3e0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_NETJET
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_NETJET_S
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_HFCS
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_TELES3C
-#define DEFAULT_CFG {5,0x500,0,0}
+#define DEFAULT_CFG {5, 0x500, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_HFC_PCI
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_HFC_PCI
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_HFC_SX
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_HFC_SX
-#define DEFAULT_CFG {5,0x2E0,0,0}
+#define DEFAULT_CFG {5, 0x2E0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_NICCY
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_NICCY
-#define DEFAULT_CFG {0,0x0,0,0}
+#define DEFAULT_CFG {0, 0x0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_ISURF
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_ISURF
-#define DEFAULT_CFG {5,0x100,0xc8000,0}
+#define DEFAULT_CFG {5, 0x100, 0xc8000, 0}
 #endif
 
 #ifdef CONFIG_HISAX_HSTSAPHIR
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_HSTSAPHIR
-#define DEFAULT_CFG {5,0x250,0,0}
+#define DEFAULT_CFG {5, 0x250, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_BKM_A4T
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_BKM_A4T
-#define DEFAULT_CFG {0,0x0,0,0}
+#define DEFAULT_CFG {0, 0x0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_SCT_QUADRO
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_SCT_QUADRO
-#define DEFAULT_CFG {1,0x0,0,0}
+#define DEFAULT_CFG {1, 0x0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_GAZEL
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_GAZEL
-#define DEFAULT_CFG {15,0x180,0,0}
+#define DEFAULT_CFG {15, 0x180, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_W6692
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_W6692
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_NETJET_U
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_NETJET_U
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
 #ifdef CONFIG_HISAX_1TR6
@@ -306,21 +306,21 @@ const char *CardType[] = {
 #endif
 #ifndef DEFAULT_CARD
 #define DEFAULT_CARD 0
-#define DEFAULT_CFG {0,0,0,0}
+#define DEFAULT_CFG {0, 0, 0, 0}
 #endif
 
-#define FIRST_CARD { \
-	DEFAULT_CARD, \
-	DEFAULT_PROTO, \
-	DEFAULT_CFG, \
-	NULL, \
-}
+#define FIRST_CARD {				\
+		DEFAULT_CARD,			\
+			DEFAULT_PROTO,		\
+			DEFAULT_CFG,		\
+			NULL,			\
+			}
 
 struct IsdnCard cards[HISAX_MAX_CARDS] = {
 	FIRST_CARD,
 };
 
-#define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
+#define HISAX_IDSIZE (HISAX_MAX_CARDS * 8)
 static char HiSaxID[HISAX_IDSIZE] = { 0, };
 
 static char *HiSax_id = HiSaxID;
@@ -400,7 +400,7 @@ static void __init HiSaxVersion(void)
 }
 
 #ifndef MODULE
-#define MAX_ARG	(HISAX_MAX_CARDS*5)
+#define MAX_ARG	(HISAX_MAX_CARDS * 5)
 static int __init HiSax_setup(char *line)
 {
 	int i, j, argc;
@@ -441,7 +441,7 @@ static int __init HiSax_setup(char *line)
 		}
 		i++;
 	}
-  	if (str && *str) {
+	if (str && *str) {
 		if (strlen(str) < HISAX_IDSIZE)
 			strcpy(HiSaxID, str);
 		else
@@ -813,11 +813,11 @@ static irqreturn_t card_irq(int intno, void *dev_id)
 
 static int init_card(struct IsdnCardState *cs)
 {
-	int 	irq_cnt, cnt = 3, ret;
+	int	irq_cnt, cnt = 3, ret;
 
 	if (!cs->irq) {
 		ret = cs->cardmsg(cs, CARD_INIT, NULL);
-		return(ret);
+		return (ret);
 	}
 	irq_cnt = cs->irq_cnt = 0;
 	printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
@@ -1142,12 +1142,12 @@ static int hisax_cs_setup(int cardnr, struct IsdnCard *card,
 	/* init_card only handles interrupts which are not */
 	/* used here for the loadable driver */
 	switch (card->typ) {
-		case ISDN_CTYPE_DYNAMIC:
-			ret = 0;
-			break;
-		default:
-			ret = init_card(cs);
-			break;
+	case ISDN_CTYPE_DYNAMIC:
+		ret = 0;
+		break;
+	default:
+		ret = init_card(cs);
+		break;
 	}
 	if (ret) {
 		closecard(cardnr);
@@ -1203,10 +1203,10 @@ static int __ref checkcard(int cardnr, char *id, int *busy_flag,
 	ret = hisax_cs_setup(cardnr, card, cs);
 	goto out;
 
- outf_cs:
+outf_cs:
 	kfree(cs);
 	card->cs = NULL;
- out:
+out:
 	return ret;
 }
 
@@ -1256,8 +1256,8 @@ static int __init HiSax_inithardware(int *busy_flag)
 			/* make sure we don't oops the module */
 			if (cards[i].typ > 0 && cards[i].typ <= ISDN_CTYPE_COUNT) {
 				printk(KERN_WARNING
-			       		"HiSax: Card %s not installed !\n",
-			       		CardType[cards[i].typ]);
+				       "HiSax: Card %s not installed !\n",
+				       CardType[cards[i].typ]);
 			}
 			HiSax_shiftcards(i);
 			nrcards--;
@@ -1521,15 +1521,15 @@ static int __init HiSax_init(void)
 		return -ENODEV;
 	return 0;
 
- out_tei:
+out_tei:
 	TeiFree();
- out_isdnl2:
+out_isdnl2:
 	Isdnl2Free();
- out_isdnl3:
+out_isdnl3:
 	Isdnl3Free();
- out_callc:
+out_callc:
 	CallcFree();
- out:
+out:
 	return retval;
 }
 
@@ -1614,7 +1614,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
 	sprintf(id, "%s%d", name, i);
 	nrcards++;
 	retval = checkcard(i, id, NULL, hisax_d_if->owner,
-				hisax_setup_card_dynamic);
+			   hisax_setup_card_dynamic);
 	if (retval == 0) { // yuck
 		cards[i].typ = 0;
 		nrcards--;
@@ -1637,7 +1637,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
 	hisax_d_if->ifc.l1l2 = hisax_d_l1l2;
 	skb_queue_head_init(&hisax_d_if->erq);
 	clear_bit(0, &hisax_d_if->ph_state);
-	
+
 	return 0;
 }
 
@@ -1674,7 +1674,7 @@ static void hisax_bh(struct work_struct *work)
 			pr = PH_DEACTIVATE | INDICATION;
 		for (st = cs->stlist; st; st = st->next)
 			st->l1.l1l2(st, pr, NULL);
-		
+
 	}
 }
 
@@ -1764,7 +1764,7 @@ static void hisax_b_l1l2(struct hisax_if *ifc, int pr, void *arg)
 		break;
 	case PH_DATA | CONFIRM:
 		bcs->tx_cnt -= (long)arg;
-		if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag)) {
+		if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag)) {
 			u_long	flags;
 			spin_lock_irqsave(&bcs->aclock, flags);
 			bcs->ackcnt += (long)arg;
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 780da9b..62a2945 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -27,7 +27,7 @@
 
 static const char *Diva_revision = "$Revision: 1.33.2.6 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define DIVA_HSCX_DATA		0
@@ -89,7 +89,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -113,15 +113,15 @@ writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size
 static inline u_char
 memreadreg(unsigned long adr, u_char off)
 {
-	return(*((unsigned char *)
-		(((unsigned int *)adr) + off)));
+	return (*((unsigned char *)
+		 (((unsigned int *)adr) + off)));
 }
 
 static inline void
 memwritereg(unsigned long adr, u_char off, u_char data)
 {
 	register u_char *p;
-	
+
 	p = (unsigned char *)(((unsigned int *)adr) + off);
 	*p = data;
 }
@@ -131,7 +131,7 @@ memwritereg(unsigned long adr, u_char off, u_char data)
 static u_char
 ReadISAC(struct IsdnCardState *cs, u_char offset)
 {
-	return(readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset));
+	return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset));
 }
 
 static void
@@ -155,23 +155,23 @@ WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 static u_char
 ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
 {
-	return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset+0x80));
+	return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset + 0x80));
 }
 
 static void
 WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
-	writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset|0x80, value);
+	writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset | 0x80, value);
 }
 
 static void
-ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
 }
 
 static void
-WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size);
 }
@@ -179,47 +179,47 @@ WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
 static u_char
 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
-	return(readreg(cs->hw.diva.hscx_adr,
-		cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0)));
+	return (readreg(cs->hw.diva.hscx_adr,
+		       cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0)));
 }
 
 static void
 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 {
 	writereg(cs->hw.diva.hscx_adr,
-		cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value);
+		 cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value);
 }
 
 static u_char
 MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
 {
-	return (memreadreg(cs->hw.diva.cfg_reg, offset+0x80));
+	return (memreadreg(cs->hw.diva.cfg_reg, offset + 0x80));
 }
 
 static void
 MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
-	memwritereg(cs->hw.diva.cfg_reg, offset|0x80, value);
+	memwritereg(cs->hw.diva.cfg_reg, offset | 0x80, value);
 }
 
 static void
-MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
-	while(size--)
+	while (size--)
 		*data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80);
 }
 
 static void
-MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
-	while(size--)
+	while (size--)
 		memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++);
 }
 
 static u_char
 MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
-	return(memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0)));
+	return (memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0)));
 }
 
 static void
@@ -242,47 +242,47 @@ MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
+MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size)
 {
-	while(size--)
+	while (size--)
 		*data++ = memreadreg(cs->hw.diva.cfg_reg, 0);
 }
 
 static void
-MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
+MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size)
 {
-	while(size--)
+	while (size--)
 		memwritereg(cs->hw.diva.cfg_reg, 0, *data++);
 }
 
 static u_char
 MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
-	return(memreadreg(cs->hw.diva.cfg_reg, offset + 
-                    (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1)));
+	return (memreadreg(cs->hw.diva.cfg_reg, offset +
+			  (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1)));
 }
 
 static void
 MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 {
-	memwritereg(cs->hw.diva.cfg_reg, offset + 
-              (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value);
+	memwritereg(cs->hw.diva.cfg_reg, offset +
+		    (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value);
 }
 
 /*
  * fast interrupt HSCX stuff goes here
  */
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \
-		cs->hw.diva.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \
-                cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr,		\
+				      cs->hw.diva.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr,	\
+					      cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \
-		cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr,	\
+						cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \
-		cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
+						  cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -292,7 +292,7 @@ diva_interrupt(int intno, void *dev_id)
 	struct IsdnCardState *cs = dev_id;
 	u_char val, sval;
 	u_long flags;
-	int cnt=5;
+	int cnt = 5;
 
 	spin_lock_irqsave(&cs->lock, flags);
 	while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) {
@@ -320,9 +320,9 @@ static irqreturn_t
 diva_irq_ipac_isa(int intno, void *dev_id)
 {
 	struct IsdnCardState *cs = dev_id;
-	u_char ista,val;
+	u_char ista, val;
 	u_long flags;
-	int icnt=5;
+	int icnt = 5;
 
 	spin_lock_irqsave(&cs->lock, flags);
 	ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA);
@@ -436,8 +436,8 @@ Memhscx_fill_fifo(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
 	int more, count, cnt;
-	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
-	u_char *ptr,*p;
+	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32;
+	u_char *ptr, *p;
 
 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
 		debugl1(cs, "hscx_fill_fifo");
@@ -459,9 +459,9 @@ Memhscx_fill_fifo(struct BCState *bcs)
 	skb_pull(bcs->tx_skb, count);
 	bcs->tx_cnt -= count;
 	bcs->hw.hscx.count += count;
-	while(cnt--)
+	while (cnt--)
 		memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0,
-			*p++);
+			    *p++);
 	MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa);
 	if (cs->debug & L1_DEB_HSCX_FIFO) {
 		char *t = bcs->blog;
@@ -479,7 +479,7 @@ Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 	u_char r;
 	struct BCState *bcs = cs->bcs + hscx;
 	struct sk_buff *skb;
-	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
+	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32;
 	int count;
 
 	if (!test_bit(BC_FLG_INIT, &bcs->Flag))
@@ -501,7 +501,7 @@ Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 			MemWriteHSCXCMDR(cs, hscx, 0x80);
 		} else {
 			count = MemReadHSCX(cs, hscx, HSCX_RBCL) & (
-				test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
+				test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f);
 			if (count == 0)
 				count = fifo_size;
 			Memhscx_empty_fifo(bcs, count);
@@ -539,8 +539,8 @@ Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 				Memhscx_fill_fifo(bcs);
 				return;
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 					u_long	flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->hw.hscx.count;
@@ -548,7 +548,7 @@ Memhscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 					schedule_event(bcs, B_ACKPENDING);
 				}
 				dev_kfree_skb_irq(bcs->tx_skb);
-				bcs->hw.hscx.count = 0; 
+				bcs->hw.hscx.count = 0;
 				bcs->tx_skb = NULL;
 			}
 		}
@@ -578,7 +578,7 @@ Memhscx_int_main(struct IsdnCardState *cs, u_char val)
 				Memhscx_fill_fifo(bcs);
 			else {
 				/* Here we lost an TX interrupt, so
-				   * restart transmitting the whole frame.
+				 * restart transmitting the whole frame.
 				 */
 				if (bcs->tx_skb) {
 					skb_push(bcs->tx_skb, bcs->hw.hscx.count);
@@ -605,7 +605,7 @@ Memhscx_int_main(struct IsdnCardState *cs, u_char val)
 				Memhscx_fill_fifo(bcs);
 			else {
 				/* Here we lost an TX interrupt, so
-				   * restart transmitting the whole frame.
+				 * restart transmitting the whole frame.
 				 */
 				if (bcs->tx_skb) {
 					skb_push(bcs->tx_skb, bcs->hw.hscx.count);
@@ -631,8 +631,8 @@ static irqreturn_t
 diva_irq_ipac_pci(int intno, void *dev_id)
 {
 	struct IsdnCardState *cs = dev_id;
-	u_char ista,val;
-	int icnt=5;
+	u_char ista, val;
+	int icnt = 5;
 	u_char *cfg;
 	u_long flags;
 
@@ -693,11 +693,11 @@ diva_irq_ipacx_pci(int intno, void *dev_id)
 	spin_lock_irqsave(&cs->lock, flags);
 	cfg = (u_char *) cs->hw.diva.pci_cfg;
 	val = *cfg;
-	if (!(val &PITA_INT0_STATUS)) {
+	if (!(val & PITA_INT0_STATUS)) {
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return IRQ_NONE; // other shared IRQ
 	}
- 	interrupt_ipacx(cs);      // handler for chip
+	interrupt_ipacx(cs);      // handler for chip
 	*cfg = PITA_INT0_STATUS;  // Reset PLX interrupt
 	spin_unlock_irqrestore(&cs->lock, flags);
 	return IRQ_HANDLED;
@@ -708,11 +708,11 @@ release_io_diva(struct IsdnCardState *cs)
 {
 	int bytecnt;
 
-	if ((cs->subtyp == DIVA_IPAC_PCI) || 
-	    (cs->subtyp == DIVA_IPACX_PCI)   ) {
+	if ((cs->subtyp == DIVA_IPAC_PCI) ||
+	    (cs->subtyp == DIVA_IPACX_PCI)) {
 		u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg;
 
-		*cfg = 0; /* disable INT0/1 */ 
+		*cfg = 0; /* disable INT0/1 */
 		*cfg = 2; /* reset pending INT0 */
 		if (cs->hw.diva.cfg_reg)
 			iounmap((void *)cs->hw.diva.cfg_reg);
@@ -761,7 +761,7 @@ reset_diva(struct IsdnCardState *cs)
 		writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0);
 	} else if (cs->subtyp == DIVA_IPAC_PCI) {
 		unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
-					PITA_MISC_REG);
+						      PITA_MISC_REG);
 		*ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
 		mdelay(10);
 		*ireg = PITA_PARA_MPX_MODE;
@@ -769,7 +769,7 @@ reset_diva(struct IsdnCardState *cs)
 		memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0);
 	} else if (cs->subtyp == DIVA_IPACX_PCI) {
 		unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
-					PITA_MISC_REG);
+						      PITA_MISC_REG);
 		*ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
 		mdelay(10);
 		*ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET;
@@ -802,7 +802,7 @@ diva_led_handler(struct IsdnCardState *cs)
 
 	if ((cs->subtyp == DIVA_IPAC_ISA) ||
 	    (cs->subtyp == DIVA_IPAC_PCI) ||
-	    (cs->subtyp == DIVA_IPACX_PCI)   )
+	    (cs->subtyp == DIVA_IPACX_PCI))
 		return;
 	del_timer(&cs->hw.diva.tl);
 	if (cs->hw.diva.status & DIVA_ASSIGN)
@@ -822,7 +822,7 @@ diva_led_handler(struct IsdnCardState *cs)
 		blink = 500;
 	} else
 		cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ?
-			DIVA_ISA_LED_B : DIVA_PCI_LED_B);
+					  DIVA_ISA_LED_B : DIVA_PCI_LED_B);
 
 	byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
 	if (blink) {
@@ -839,69 +839,69 @@ Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_diva(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_diva(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_diva(cs);
-			if (cs->subtyp == DIVA_IPACX_PCI) {
-				ireg = (unsigned int *)cs->hw.diva.pci_cfg;
-				*ireg = PITA_INT0_ENABLE;
-				init_ipacx(cs, 3); // init chip and enable interrupts
-				spin_unlock_irqrestore(&cs->lock, flags);
-				return (0);
-			}
-			if (cs->subtyp == DIVA_IPAC_PCI) {
-				ireg = (unsigned int *)cs->hw.diva.pci_cfg;
-				*ireg = PITA_INT0_ENABLE;
-			}
-			inithscxisac(cs, 3);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_diva(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_diva(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_diva(cs);
+		if (cs->subtyp == DIVA_IPACX_PCI) {
+			ireg = (unsigned int *)cs->hw.diva.pci_cfg;
+			*ireg = PITA_INT0_ENABLE;
+			init_ipacx(cs, 3); // init chip and enable interrupts
 			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
-		case (MDL_REMOVE | REQUEST):
-			cs->hw.diva.status = 0;
-			break;
-		case (MDL_ASSIGN | REQUEST):
-			cs->hw.diva.status |= DIVA_ASSIGN;
-			break;
-		case MDL_INFO_SETUP:
-			if ((long)arg)
-				cs->hw.diva.status |=  0x0200;
-			else
-				cs->hw.diva.status |=  0x0100;
-			break;
-		case MDL_INFO_CONN:
-			if ((long)arg)
-				cs->hw.diva.status |=  0x2000;
-			else
-				cs->hw.diva.status |=  0x1000;
-			break;
-		case MDL_INFO_REL:
-			if ((long)arg) {
-				cs->hw.diva.status &=  ~0x2000;
-				cs->hw.diva.status &=  ~0x0200;
-			} else {
-				cs->hw.diva.status &=  ~0x1000;
-				cs->hw.diva.status &=  ~0x0100;
-			}
-			break;
+			return (0);
+		}
+		if (cs->subtyp == DIVA_IPAC_PCI) {
+			ireg = (unsigned int *)cs->hw.diva.pci_cfg;
+			*ireg = PITA_INT0_ENABLE;
+		}
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
+	case (MDL_REMOVE | REQUEST):
+		cs->hw.diva.status = 0;
+		break;
+	case (MDL_ASSIGN | REQUEST):
+		cs->hw.diva.status |= DIVA_ASSIGN;
+		break;
+	case MDL_INFO_SETUP:
+		if ((long)arg)
+			cs->hw.diva.status |=  0x0200;
+		else
+			cs->hw.diva.status |=  0x0100;
+		break;
+	case MDL_INFO_CONN:
+		if ((long)arg)
+			cs->hw.diva.status |=  0x2000;
+		else
+			cs->hw.diva.status |=  0x1000;
+		break;
+	case MDL_INFO_REL:
+		if ((long)arg) {
+			cs->hw.diva.status &=  ~0x2000;
+			cs->hw.diva.status &=  ~0x0200;
+		} else {
+			cs->hw.diva.status &=  ~0x1000;
+			cs->hw.diva.status &=  ~0x0100;
+		}
+		break;
 	}
-	if ((cs->subtyp != DIVA_IPAC_ISA) && 
+	if ((cs->subtyp != DIVA_IPAC_ISA) &&
 	    (cs->subtyp != DIVA_IPAC_PCI) &&
 	    (cs->subtyp != DIVA_IPACX_PCI)) {
-	    	spin_lock_irqsave(&cs->lock, flags);
+		spin_lock_irqsave(&cs->lock, flags);
 		diva_led_handler(cs);
 		spin_unlock_irqrestore(&cs->lock, flags);
 	}
-	return(0);
+	return (0);
 }
 
 static int __devinit setup_diva_common(struct IsdnCardState *cs)
@@ -915,21 +915,21 @@ static int __devinit setup_diva_common(struct IsdnCardState *cs)
 		bytecnt = 32;
 
 	printk(KERN_INFO
-		"Diva: %s card configured at %#lx IRQ %d\n",
-		(cs->subtyp == DIVA_PCI) ? "PCI" :
-		(cs->subtyp == DIVA_ISA) ? "ISA" : 
-		(cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
-		(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
-		cs->hw.diva.cfg_reg, cs->irq);
-	if ((cs->subtyp == DIVA_IPAC_PCI)  || 
-	    (cs->subtyp == DIVA_IPACX_PCI) || 
-	    (cs->subtyp == DIVA_PCI)         )
+	       "Diva: %s card configured at %#lx IRQ %d\n",
+	       (cs->subtyp == DIVA_PCI) ? "PCI" :
+	       (cs->subtyp == DIVA_ISA) ? "ISA" :
+	       (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
+	       (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
+	       cs->hw.diva.cfg_reg, cs->irq);
+	if ((cs->subtyp == DIVA_IPAC_PCI)  ||
+	    (cs->subtyp == DIVA_IPACX_PCI) ||
+	    (cs->subtyp == DIVA_PCI))
 		printk(KERN_INFO "Diva: %s space at %#lx\n",
-			(cs->subtyp == DIVA_PCI) ? "PCI" :
-			(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
-			cs->hw.diva.pci_cfg);
+		       (cs->subtyp == DIVA_PCI) ? "PCI" :
+		       (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
+		       cs->hw.diva.pci_cfg);
 	if ((cs->subtyp != DIVA_IPAC_PCI) &&
-	    (cs->subtyp != DIVA_IPACX_PCI)   ) {
+	    (cs->subtyp != DIVA_IPACX_PCI)) {
 		if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) {
 			printk(KERN_WARNING
 			       "HiSax: %s config port %lx-%lx already in use\n",
@@ -973,8 +973,8 @@ static int __devinit setup_diva_common(struct IsdnCardState *cs)
 		cs->BC_Write_Reg = &MemWriteHSCX_IPACX;
 		cs->BC_Send_Data = NULL; // function located in ipacx module
 		cs->irq_func = &diva_irq_ipacx_pci;
-		printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 
-			MemReadISAC_IPACX(cs, IPACX_ID) &0x3F);
+		printk(KERN_INFO "Diva: IPACX Design Id: %x\n",
+		       MemReadISAC_IPACX(cs, IPACX_ID) & 0x3F);
 	} else { /* DIVA 2.0 */
 		cs->hw.diva.tl.function = (void *) diva_led_handler;
 		cs->hw.diva.tl.data = (long) cs;
@@ -987,7 +987,7 @@ static int __devinit setup_diva_common(struct IsdnCardState *cs)
 		ISACVersion(cs, "Diva:");
 		if (HscxVersion(cs, "Diva:")) {
 			printk(KERN_WARNING
-		       "Diva: wrong HSCX versions check IO address\n");
+			       "Diva: wrong HSCX versions check IO address\n");
 			release_io_diva(cs);
 			return (0);
 		}
@@ -1008,9 +1008,9 @@ static int __devinit setup_diva_isa(struct IsdnCard *card)
 	cs->hw.diva.ctrl_reg = 0;
 	cs->hw.diva.cfg_reg = card->para[1];
 	val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR,
-		cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
+		      cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID);
 	printk(KERN_INFO "Diva: IPAC version %x\n", val);
-	if ((val == 1) || (val==2)) {
+	if ((val == 1) || (val == 2)) {
 		cs->subtyp = DIVA_IPAC_ISA;
 		cs->hw.diva.ctrl = 0;
 		cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA;
@@ -1043,22 +1043,22 @@ static int __devinit setup_diva_isa(struct IsdnCard *card)
 #ifdef __ISAPNP__
 static struct isapnp_device_id diva_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
-	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 
+	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
 	  (unsigned long) "Diva picola" },
 	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
-	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 
+	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51),
 	  (unsigned long) "Diva picola" },
 	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
-	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 
+	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
 	  (unsigned long) "Diva 2.0" },
 	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
-	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 
+	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71),
 	  (unsigned long) "Diva 2.0" },
 	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
-	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 
+	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
 	  (unsigned long) "Diva 2.01" },
 	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
-	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 
+	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1),
 	  (unsigned long) "Diva 2.01" },
 	{ 0, }
 };
@@ -1074,30 +1074,30 @@ static int __devinit setup_diva_isapnp(struct IsdnCard *card)
 	if (!isapnp_present())
 		return (-1);	/* card not found; continue search */
 
-	while(ipid->card_vendor) {
+	while (ipid->card_vendor) {
 		if ((pnp_c = pnp_find_card(ipid->card_vendor,
-			ipid->card_device, pnp_c))) {
+					   ipid->card_device, pnp_c))) {
 			pnp_d = NULL;
 			if ((pnp_d = pnp_find_dev(pnp_c,
-				ipid->vendor, ipid->function, pnp_d))) {
+						  ipid->vendor, ipid->function, pnp_d))) {
 				int err;
 
 				printk(KERN_INFO "HiSax: %s detected\n",
-					(char *)ipid->driver_data);
+				       (char *)ipid->driver_data);
 				pnp_disable_dev(pnp_d);
 				err = pnp_activate_dev(pnp_d);
-				if (err<0) {
+				if (err < 0) {
 					printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-						__func__, err);
-					return(0);
+					       __func__, err);
+					return (0);
 				}
 				card->para[1] = pnp_port_start(pnp_d, 0);
 				card->para[0] = pnp_irq(pnp_d, 0);
 				if (!card->para[0] || !card->para[1]) {
 					printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
-						card->para[0], card->para[1]);
-					pnp_disable_dev(pnp_d); 
-					return(0);
+					       card->para[0], card->para[1]);
+					pnp_disable_dev(pnp_d);
+					return (0);
 				}
 				cs->hw.diva.cfg_reg  = card->para[1];
 				cs->irq = card->para[0];
@@ -1129,12 +1129,12 @@ static int __devinit setup_diva_isapnp(struct IsdnCard *card)
 				return (1);		/* card found */
 			} else {
 				printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
-				return(0);
+				return (0);
 			}
 		}
 		ipid++;
-		pnp_c=NULL;
-	} 
+		pnp_c = NULL;
+	}
 
 	return (-1);	/* card not found; continue search */
 }
@@ -1160,23 +1160,23 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
 
 	cs->subtyp = 0;
 	if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
-		PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
+					      PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
 		if (pci_enable_device(dev_diva))
-			return(0);
+			return (0);
 		cs->subtyp = DIVA_PCI;
 		cs->irq = dev_diva->irq;
 		cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
 	} else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
-		PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
+						       PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
 		if (pci_enable_device(dev_diva_u))
-			return(0);
+			return (0);
 		cs->subtyp = DIVA_PCI;
 		cs->irq = dev_diva_u->irq;
 		cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
 	} else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
-		PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
+							PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
 		if (pci_enable_device(dev_diva201))
-			return(0);
+			return (0);
 		cs->subtyp = DIVA_IPAC_PCI;
 		cs->irq = dev_diva201->irq;
 		cs->hw.diva.pci_cfg =
@@ -1184,9 +1184,9 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
 		cs->hw.diva.cfg_reg =
 			(ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
 	} else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
-		PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
+							PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
 		if (pci_enable_device(dev_diva202))
-			return(0);
+			return (0);
 		cs->subtyp = DIVA_IPACX_PCI;
 		cs->irq = dev_diva202->irq;
 		cs->hw.diva.pci_cfg =
@@ -1200,18 +1200,18 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
 	if (!cs->irq) {
 		printk(KERN_WARNING "Diva: No IRQ for PCI card found\n");
 		iounmap_diva(cs);
-		return(0);
+		return (0);
 	}
 
 	if (!cs->hw.diva.cfg_reg) {
 		printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n");
 		iounmap_diva(cs);
-		return(0);
+		return (0);
 	}
 	cs->irq_flags |= IRQF_SHARED;
 
 	if ((cs->subtyp == DIVA_IPAC_PCI) ||
-	    (cs->subtyp == DIVA_IPACX_PCI)   ) {
+	    (cs->subtyp == DIVA_IPACX_PCI)) {
 		cs->hw.diva.ctrl = 0;
 		cs->hw.diva.isac = 0;
 		cs->hw.diva.hscx = 0;
@@ -1248,7 +1248,7 @@ setup_diva(struct IsdnCard *card)
 	strcpy(tmp, Diva_revision);
 	printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_DIEHLDIVA)
-		return(0);
+		return (0);
 	cs->hw.diva.status = 0;
 
 	rc = setup_diva_isa(card);
@@ -1276,7 +1276,7 @@ setup_diva(struct IsdnCard *card)
 ready:
 	if (!have_card) {
 		printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n");
-		return(0);
+		return (0);
 	}
 
 	return setup_diva_common(card->cs);
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 5d9d338..64ba26a 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -34,14 +34,14 @@
 static const char *Elsa_revision = "$Revision: 2.32.2.4 $";
 static const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
- "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
+ "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI",
  "PCMCIA-IPAC" };
 
 static const char *ITACVer[] =
 {"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2",
  "B1", "A1"};
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define ELSA_ISAC	0
@@ -113,25 +113,25 @@ static const char *ITACVer[] =
 
 #if ARCOFI_USE
 static struct arcofi_msg ARCOFI_XOP_F =
-	{NULL,0,2,{0xa1,0x3f,0,0,0,0,0,0,0,0}}; /* Normal OP */
+{NULL,0,2,{0xa1,0x3f,0,0,0,0,0,0,0,0}}; /* Normal OP */
 static struct arcofi_msg ARCOFI_XOP_1 =
-	{&ARCOFI_XOP_F,0,2,{0xa1,0x31,0,0,0,0,0,0,0,0}}; /* PWR UP */
-static struct arcofi_msg ARCOFI_SOP_F = 
-	{&ARCOFI_XOP_1,0,10,{0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}};
+{&ARCOFI_XOP_F,0,2,{0xa1,0x31,0,0,0,0,0,0,0,0}}; /* PWR UP */
+static struct arcofi_msg ARCOFI_SOP_F =
+{&ARCOFI_XOP_1,0,10,{0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}};
 static struct arcofi_msg ARCOFI_COP_9 =
-	{&ARCOFI_SOP_F,0,10,{0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}}; /* RX */
+{&ARCOFI_SOP_F,0,10,{0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}}; /* RX */
 static struct arcofi_msg ARCOFI_COP_8 =
-	{&ARCOFI_COP_9,0,10,{0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}}; /* TX */
+{&ARCOFI_COP_9,0,10,{0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}}; /* TX */
 static struct arcofi_msg ARCOFI_COP_7 =
-	{&ARCOFI_COP_8,0,4,{0xa1,0x27,0x80,0x80,0,0,0,0,0,0}}; /* GZ */
+{&ARCOFI_COP_8,0,4,{0xa1,0x27,0x80,0x80,0,0,0,0,0,0}}; /* GZ */
 static struct arcofi_msg ARCOFI_COP_6 =
-	{&ARCOFI_COP_7,0,6,{0xa1,0x26,0,0,0x82,0x7c,0,0,0,0}}; /* GRL GRH */
+{&ARCOFI_COP_7,0,6,{0xa1,0x26,0,0,0x82,0x7c,0,0,0,0}}; /* GRL GRH */
 static struct arcofi_msg ARCOFI_COP_5 =
-	{&ARCOFI_COP_6,0,4,{0xa1,0x25,0xbb,0x4a,0,0,0,0,0,0}}; /* GTX */
+{&ARCOFI_COP_6,0,4,{0xa1,0x25,0xbb,0x4a,0,0,0,0,0,0}}; /* GTX */
 static struct arcofi_msg ARCOFI_VERSION =
-	{NULL,1,2,{0xa0,0,0,0,0,0,0,0,0,0}};
+{NULL,1,2,{0xa0,0,0,0,0,0,0,0,0,0}};
 static struct arcofi_msg ARCOFI_XOP_0 =
-	{NULL,0,2,{0xa1,0x30,0,0,0,0,0,0,0,0}}; /* PWR Down */
+{NULL,0,2,{0xa1,0x30,0,0,0,0,0,0,0,0}}; /* PWR Down */
 
 static void set_arcofi(struct IsdnCardState *cs, int bc);
 
@@ -149,7 +149,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -164,7 +164,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -185,13 +185,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0, data, size);
 }
@@ -199,23 +199,23 @@ WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 static u_char
 ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
 {
-	return (readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset+0x80));
+	return (readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset + 0x80));
 }
 
 static void
 WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
-	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset|0x80, value);
+	writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset | 0x80, value);
 }
 
 static void
-ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0x80, data, size);
 }
 
 static void
-WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0x80, data, size);
 }
@@ -267,16 +267,16 @@ TimerRun(struct IsdnCardState *cs)
  * fast interrupt HSCX stuff goes here
  */
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.elsa.ale, \
-		cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.elsa.ale, \
-		cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.elsa.ale,			\
+				      cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.elsa.ale,		\
+					      cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.elsa.ale, \
-		cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.elsa.ale,	\
+						cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.elsa.ale, \
-		cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.elsa.ale,	\
+						  cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -286,11 +286,11 @@ elsa_interrupt(int intno, void *dev_id)
 	struct IsdnCardState *cs = dev_id;
 	u_long flags;
 	u_char val;
-	int icnt=5;
+	int icnt = 5;
 
 	if ((cs->typ == ISDN_CTYPE_ELSA_PCMCIA) && (*cs->busy_flag == 1)) {
-	/* The card tends to generate interrupts while being removed
-	   causing us to just crash the kernel. bad. */
+		/* The card tends to generate interrupts while being removed
+		   causing us to just crash the kernel. bad. */
 		printk(KERN_WARNING "Elsa: card not available!\n");
 		return IRQ_NONE;
 	}
@@ -299,18 +299,18 @@ elsa_interrupt(int intno, void *dev_id)
 	if (cs->hw.elsa.MFlag) {
 		val = serial_inp(cs, UART_IIR);
 		if (!(val & UART_IIR_NO_INT)) {
-			debugl1(cs,"IIR %02x", val);
+			debugl1(cs, "IIR %02x", val);
 			rs_interrupt_elsa(cs);
 		}
 	}
 #endif
 	val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+Start_HSCX:
 	if (val) {
 		hscx_int_main(cs, val);
 	}
 	val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val) {
 		isac_interrupt(cs, val);
 	}
@@ -364,8 +364,8 @@ elsa_interrupt_ipac(int intno, void *dev_id)
 {
 	struct IsdnCardState *cs = dev_id;
 	u_long flags;
-	u_char ista,val;
-	int icnt=5;
+	u_char ista, val;
+	int icnt = 5;
 
 	spin_lock_irqsave(&cs->lock, flags);
 	if (cs->subtyp == ELSA_QS1000PCI || cs->subtyp == ELSA_QS3000PCI) {
@@ -379,7 +379,7 @@ elsa_interrupt_ipac(int intno, void *dev_id)
 	if (cs->hw.elsa.MFlag) {
 		val = serial_inp(cs, UART_IIR);
 		if (!(val & UART_IIR_NO_INT)) {
-			debugl1(cs,"IIR %02x", val);
+			debugl1(cs, "IIR %02x", val);
 			rs_interrupt_elsa(cs);
 		}
 	}
@@ -444,13 +444,13 @@ release_io_elsa(struct IsdnCardState *cs)
 		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);
 		release_region(cs->hw.elsa.cfg, 0x80);
 	}
- 	if (cs->subtyp == ELSA_PCMCIA_IPAC) {
+	if (cs->subtyp == ELSA_PCMCIA_IPAC) {
 		writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);
- 	}
+	}
 	if ((cs->subtyp == ELSA_PCFPRO) ||
-		(cs->subtyp == ELSA_QS3000) ||
-		(cs->subtyp == ELSA_PCF) ||
-		(cs->subtyp == ELSA_QS3000PCI)) {
+	    (cs->subtyp == ELSA_QS3000) ||
+	    (cs->subtyp == ELSA_PCF) ||
+	    (cs->subtyp == ELSA_QS3000PCI)) {
 		bytecnt = 16;
 #if ARCOFI_USE
 		release_modem(cs);
@@ -521,84 +521,84 @@ check_arcofi(struct IsdnCardState *cs)
 	u_char *p;
 
 	if (!cs->dc.isac.mon_tx)
-		if (!(cs->dc.isac.mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
+		if (!(cs->dc.isac.mon_tx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
 			if (cs->debug & L1_DEB_WARN)
 				debugl1(cs, "ISAC MON TX out of buffers!");
-			return(0);
+			return (0);
 		}
 	cs->dc.isac.arcofi_bc = 0;
 	arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION);
 	interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
 	if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) {
-			debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
-			p = cs->dc.isac.mon_rx;
-			t = tmp;
-			t += sprintf(tmp, "Arcofi data");
-			QuickHex(t, p, cs->dc.isac.mon_rxp);
-			debugl1(cs, tmp);
-			if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) {
-				switch(cs->dc.isac.mon_rx[1]) {
-					case 0x80:
-						debugl1(cs, "Arcofi 2160 detected");
-						arcofi_present = 1;
-						break;
-					case 0x82:
-						debugl1(cs, "Arcofi 2165 detected");
-						arcofi_present = 2;
-						break;
-					case 0x84:
-						debugl1(cs, "Arcofi 2163 detected");
-						arcofi_present = 3;
-						break;
-					default:
-						debugl1(cs, "unknown Arcofi response");
-						break;
-				}
-			} else
-				debugl1(cs, "undefined Monitor response");
-			cs->dc.isac.mon_rxp = 0;
+		debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
+		p = cs->dc.isac.mon_rx;
+		t = tmp;
+		t += sprintf(tmp, "Arcofi data");
+		QuickHex(t, p, cs->dc.isac.mon_rxp);
+		debugl1(cs, tmp);
+		if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) {
+			switch (cs->dc.isac.mon_rx[1]) {
+			case 0x80:
+				debugl1(cs, "Arcofi 2160 detected");
+				arcofi_present = 1;
+				break;
+			case 0x82:
+				debugl1(cs, "Arcofi 2165 detected");
+				arcofi_present = 2;
+				break;
+			case 0x84:
+				debugl1(cs, "Arcofi 2163 detected");
+				arcofi_present = 3;
+				break;
+			default:
+				debugl1(cs, "unknown Arcofi response");
+				break;
+			}
+		} else
+			debugl1(cs, "undefined Monitor response");
+		cs->dc.isac.mon_rxp = 0;
 	} else if (cs->dc.isac.mon_tx) {
 		debugl1(cs, "Arcofi not detected");
 	}
 	if (arcofi_present) {
-		if (cs->subtyp==ELSA_QS1000) {
+		if (cs->subtyp == ELSA_QS1000) {
 			cs->subtyp = ELSA_QS3000;
 			printk(KERN_INFO
-				"Elsa: %s detected modem at 0x%lx\n",
-				Elsa_Types[cs->subtyp],
-				cs->hw.elsa.base+8);
+			       "Elsa: %s detected modem at 0x%lx\n",
+			       Elsa_Types[cs->subtyp],
+			       cs->hw.elsa.base + 8);
 			release_region(cs->hw.elsa.base, 8);
 			if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) {
 				printk(KERN_WARNING
-					"HiSax: %s config port %lx-%lx already in use\n",
-					Elsa_Types[cs->subtyp],
-					cs->hw.elsa.base + 8,
-					cs->hw.elsa.base + 16);
+				       "HiSax: %s config port %lx-%lx already in use\n",
+				       Elsa_Types[cs->subtyp],
+				       cs->hw.elsa.base + 8,
+				       cs->hw.elsa.base + 16);
 			}
-		} else if (cs->subtyp==ELSA_PCC16) {
+		} else if (cs->subtyp == ELSA_PCC16) {
 			cs->subtyp = ELSA_PCF;
 			printk(KERN_INFO
-				"Elsa: %s detected modem at 0x%lx\n",
-				Elsa_Types[cs->subtyp],
-				cs->hw.elsa.base+8);
+			       "Elsa: %s detected modem at 0x%lx\n",
+			       Elsa_Types[cs->subtyp],
+			       cs->hw.elsa.base + 8);
 			release_region(cs->hw.elsa.base, 8);
 			if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) {
 				printk(KERN_WARNING
-					"HiSax: %s config port %lx-%lx already in use\n",
-					Elsa_Types[cs->subtyp],
-					cs->hw.elsa.base + 8,
-					cs->hw.elsa.base + 16);
+				       "HiSax: %s config port %lx-%lx already in use\n",
+				       Elsa_Types[cs->subtyp],
+				       cs->hw.elsa.base + 8,
+				       cs->hw.elsa.base + 16);
 			}
 		} else
 			printk(KERN_INFO
-				"Elsa: %s detected modem at 0x%lx\n",
-				Elsa_Types[cs->subtyp],
-				cs->hw.elsa.base+8);
+			       "Elsa: %s detected modem at 0x%lx\n",
+			       Elsa_Types[cs->subtyp],
+			       cs->hw.elsa.base + 8);
 		arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0);
 		interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
-		return(1);
+		return (1);
 	}
-	return(0);
+	return (0);
 }
 #endif /* ARCOFI_USE */
 
@@ -627,7 +627,7 @@ elsa_led_handler(struct IsdnCardState *cs)
 		cs->hw.elsa.ctrl_reg &= ~ELSA_LINE_LED;
 
 	if ((cs->subtyp == ELSA_QS1000PCI) ||
-		(cs->subtyp == ELSA_QS3000PCI)) {
+	    (cs->subtyp == ELSA_QS3000PCI)) {
 		u_char led = 0xff;
 		if (cs->hw.elsa.ctrl_reg & ELSA_LINE_LED)
 			led ^= ELSA_IPAC_LINE_LED;
@@ -650,111 +650,111 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_elsa(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_elsa(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->debug |= L1_DEB_IPAC;
+		reset_elsa(cs);
+		inithscxisac(cs, 1);
+		if ((cs->subtyp == ELSA_QS1000) ||
+		    (cs->subtyp == ELSA_QS3000))
+		{
+			byteout(cs->hw.elsa.timer, 0);
+		}
+		if (cs->hw.elsa.trig)
+			byteout(cs->hw.elsa.trig, 0xff);
+		inithscxisac(cs, 2);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		if ((cs->subtyp == ELSA_PCMCIA) ||
+		    (cs->subtyp == ELSA_PCMCIA_IPAC) ||
+		    (cs->subtyp == ELSA_QS1000PCI)) {
+			return (0);
+		} else if (cs->subtyp == ELSA_QS3000PCI) {
+			ret = 0;
+		} else {
 			spin_lock_irqsave(&cs->lock, flags);
-			reset_elsa(cs);
+			cs->hw.elsa.counter = 0;
+			cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT;
+			cs->hw.elsa.status |= ELIRQF_TIMER_AKTIV;
+			byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
+			byteout(cs->hw.elsa.timer, 0);
 			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_elsa(cs);
-			return(0);
-		case CARD_INIT:
+			msleep(110);
 			spin_lock_irqsave(&cs->lock, flags);
-			cs->debug |= L1_DEB_IPAC;
-			reset_elsa(cs);
-			inithscxisac(cs, 1);
-			if ((cs->subtyp == ELSA_QS1000) ||
-			    (cs->subtyp == ELSA_QS3000))
-			{
-				byteout(cs->hw.elsa.timer, 0);
-			}
-			if (cs->hw.elsa.trig)
-				byteout(cs->hw.elsa.trig, 0xff);
-			inithscxisac(cs, 2);
+			cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT;
+			byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
+			cs->hw.elsa.status &= ~ELIRQF_TIMER_AKTIV;
 			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			if ((cs->subtyp == ELSA_PCMCIA) ||
-				(cs->subtyp == ELSA_PCMCIA_IPAC) ||
-				(cs->subtyp == ELSA_QS1000PCI)) {
-				return(0);
-			} else if (cs->subtyp == ELSA_QS3000PCI) {
+			printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",
+			       cs->hw.elsa.counter);
+			if ((cs->hw.elsa.counter > 10) &&
+			    (cs->hw.elsa.counter < 16)) {
+				printk(KERN_INFO "Elsa: timer and irq OK\n");
 				ret = 0;
 			} else {
-				spin_lock_irqsave(&cs->lock, flags);
-				cs->hw.elsa.counter = 0;
-				cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT;
-				cs->hw.elsa.status |= ELIRQF_TIMER_AKTIV;
-				byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
-				byteout(cs->hw.elsa.timer, 0);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				msleep(110);
-				spin_lock_irqsave(&cs->lock, flags);
-				cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT;
-				byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
-				cs->hw.elsa.status &= ~ELIRQF_TIMER_AKTIV;
-				spin_unlock_irqrestore(&cs->lock, flags);
-				printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",
-				       cs->hw.elsa.counter);
-				if ((cs->hw.elsa.counter > 10) &&
-					(cs->hw.elsa.counter < 16)) {
-					printk(KERN_INFO "Elsa: timer and irq OK\n");
-					ret = 0;
-				} else {
-					printk(KERN_WARNING
-					       "Elsa: timer tic problem (%d/12) maybe an IRQ(%d) conflict\n",
-					       cs->hw.elsa.counter, cs->irq);
-					ret = 1;
-				}
+				printk(KERN_WARNING
+				       "Elsa: timer tic problem (%d/12) maybe an IRQ(%d) conflict\n",
+				       cs->hw.elsa.counter, cs->irq);
+				ret = 1;
 			}
+		}
 #if ARCOFI_USE
-			if (check_arcofi(cs)) {
-				init_modem(cs);
-			}
+		if (check_arcofi(cs)) {
+			init_modem(cs);
+		}
 #endif
-			elsa_led_handler(cs);
-			return(ret);
-		case (MDL_REMOVE | REQUEST):
-			cs->hw.elsa.status &= 0;
-			break;
-		case (MDL_ASSIGN | REQUEST):
-			cs->hw.elsa.status |= ELSA_ASSIGN;
-			break;
-		case MDL_INFO_SETUP:
-			if ((long) arg)
-				cs->hw.elsa.status |= 0x0200;
-			else
-				cs->hw.elsa.status |= 0x0100;
-			break;
-		case MDL_INFO_CONN:
-			if ((long) arg)
-				cs->hw.elsa.status |= 0x2000;
-			else
-				cs->hw.elsa.status |= 0x1000;
-			break;
-		case MDL_INFO_REL:
-			if ((long) arg) {
-				cs->hw.elsa.status &= ~0x2000;
-				cs->hw.elsa.status &= ~0x0200;
-			} else {
-				cs->hw.elsa.status &= ~0x1000;
-				cs->hw.elsa.status &= ~0x0100;
-			}
-			break;
+		elsa_led_handler(cs);
+		return (ret);
+	case (MDL_REMOVE | REQUEST):
+		cs->hw.elsa.status &= 0;
+		break;
+	case (MDL_ASSIGN | REQUEST):
+		cs->hw.elsa.status |= ELSA_ASSIGN;
+		break;
+	case MDL_INFO_SETUP:
+		if ((long) arg)
+			cs->hw.elsa.status |= 0x0200;
+		else
+			cs->hw.elsa.status |= 0x0100;
+		break;
+	case MDL_INFO_CONN:
+		if ((long) arg)
+			cs->hw.elsa.status |= 0x2000;
+		else
+			cs->hw.elsa.status |= 0x1000;
+		break;
+	case MDL_INFO_REL:
+		if ((long) arg) {
+			cs->hw.elsa.status &= ~0x2000;
+			cs->hw.elsa.status &= ~0x0200;
+		} else {
+			cs->hw.elsa.status &= ~0x1000;
+			cs->hw.elsa.status &= ~0x0100;
+		}
+		break;
 #if ARCOFI_USE
-		case CARD_AUX_IND:
-			if (cs->hw.elsa.MFlag) {
-				int len;
-				u_char *msg;
-
-				if (!arg)
-					return(0);
-				msg = arg;
-				len = *msg;
-				msg++;
-				modem_write_cmd(cs, msg, len);
-			}
-			break;
+	case CARD_AUX_IND:
+		if (cs->hw.elsa.MFlag) {
+			int len;
+			u_char *msg;
+
+			if (!arg)
+				return (0);
+			msg = arg;
+			len = *msg;
+			msg++;
+			modem_write_cmd(cs, msg, len);
+		}
+		break;
 #endif
 	}
 	if (cs->typ == ISDN_CTYPE_ELSA) {
@@ -765,14 +765,14 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 			cs->hw.elsa.status &= ~ELSA_BAD_PWR;
 	}
 	elsa_led_handler(cs);
-	return(ret);
+	return (ret);
 }
 
 static unsigned char
 probe_elsa_adr(unsigned int adr, int typ)
 {
 	int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0,
-	 pc_2 = 0, pfp_1 = 0, pfp_2 = 0;
+		pc_2 = 0, pfp_1 = 0, pfp_2 = 0;
 
 	/* In case of the elsa pcmcia card, this region is in use,
 	   reserved for us by the card manager. So we do not check it
@@ -822,7 +822,7 @@ probe_elsa(struct IsdnCardState *cs)
 {
 	int i;
 	unsigned int CARD_portlist[] =
-	{0x160, 0x170, 0x260, 0x360, 0};
+		{0x160, 0x170, 0x260, 0x360, 0};
 
 	for (i = 0; CARD_portlist[i]; i++) {
 		if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ)))
@@ -867,15 +867,15 @@ setup_elsa_isa(struct IsdnCard *card)
 	val = bytein(cs->hw.elsa.cfg);
 	if (cs->subtyp == ELSA_PC) {
 		const u_char CARD_IrqTab[8] =
-		{7, 3, 5, 9, 0, 0, 0, 0};
+			{7, 3, 5, 9, 0, 0, 0, 0};
 		cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];
 	} else if (cs->subtyp == ELSA_PCC8) {
 		const u_char CARD_IrqTab[8] =
-		{7, 3, 5, 9, 0, 0, 0, 0};
+			{7, 3, 5, 9, 0, 0, 0, 0};
 		cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];
 	} else {
 		const u_char CARD_IrqTab[8] =
-		{15, 10, 15, 3, 11, 5, 11, 9};
+			{15, 10, 15, 3, 11, 5, 11, 9};
 		cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];
 	}
 	val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;
@@ -894,7 +894,7 @@ setup_elsa_isa(struct IsdnCard *card)
 	val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;
 	if (val) {
 		printk(KERN_WARNING
-		   "Elsa: Microlink S0 bus power bad\n");
+		       "Elsa: Microlink S0 bus power bad\n");
 		cs->hw.elsa.status |= ELSA_BAD_PWR;
 	}
 
@@ -904,10 +904,10 @@ setup_elsa_isa(struct IsdnCard *card)
 #ifdef __ISAPNP__
 static struct isapnp_device_id elsa_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
-	  ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133), 
+	  ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
 	  (unsigned long) "Elsa QS1000" },
 	{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
-	  ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134), 
+	  ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
 	  (unsigned long) "Elsa QS3000" },
 	{ 0, }
 };
@@ -924,31 +924,31 @@ setup_elsa_isapnp(struct IsdnCard *card)
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d;
-		while(ipid->card_vendor) {
+		while (ipid->card_vendor) {
 			if ((pnp_c = pnp_find_card(ipid->card_vendor,
-				ipid->card_device, pnp_c))) {
+						   ipid->card_device, pnp_c))) {
 				pnp_d = NULL;
 				if ((pnp_d = pnp_find_dev(pnp_c,
-					ipid->vendor, ipid->function, pnp_d))) {
+							  ipid->vendor, ipid->function, pnp_d))) {
 					int err;
 
 					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)ipid->driver_data);
+					       (char *)ipid->driver_data);
 					pnp_disable_dev(pnp_d);
 					err = pnp_activate_dev(pnp_d);
-					if (err<0) {
+					if (err < 0) {
 						printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-							__func__, err);
-						return(0);
+						       __func__, err);
+						return (0);
 					}
 					card->para[1] = pnp_port_start(pnp_d, 0);
 					card->para[0] = pnp_irq(pnp_d, 0);
 
 					if (!card->para[0] || !card->para[1]) {
 						printk(KERN_ERR "Elsa PnP:some resources are missing %ld/%lx\n",
-							card->para[0], card->para[1]);
+						       card->para[0], card->para[1]);
 						pnp_disable_dev(pnp_d);
-						return(0);
+						return (0);
 					}
 					if (ipid->function == ISAPNP_FUNCTION(0x133))
 						cs->subtyp = ELSA_QS1000;
@@ -957,20 +957,20 @@ setup_elsa_isapnp(struct IsdnCard *card)
 					break;
 				} else {
 					printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n");
-					return(0);
+					return (0);
 				}
 			}
 			ipid++;
-			pnp_c=NULL;
-		} 
+			pnp_c = NULL;
+		}
 		if (!ipid->card_vendor) {
 			printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n");
-			return(0);
+			return (0);
 		}
 	}
 #endif	/* __ISAPNP__ */
 
-	if (card->para[1] && card->para[0]) { 
+	if (card->para[1] && card->para[0]) {
 		cs->hw.elsa.base = card->para[1];
 		cs->irq = card->para[0];
 		if (!cs->subtyp)
@@ -1027,8 +1027,8 @@ setup_elsa_pcmcia(struct IsdnCard *card)
 }
 
 #ifdef CONFIG_PCI
-static 	struct pci_dev *dev_qs1000 __devinitdata = NULL;
-static 	struct pci_dev *dev_qs3000 __devinitdata = NULL;
+static	struct pci_dev *dev_qs1000 __devinitdata = NULL;
+static	struct pci_dev *dev_qs3000 __devinitdata = NULL;
 
 static int __devinit
 setup_elsa_pci(struct IsdnCard *card)
@@ -1037,33 +1037,33 @@ setup_elsa_pci(struct IsdnCard *card)
 
 	cs->subtyp = 0;
 	if ((dev_qs1000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
-		PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
+						PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
 		if (pci_enable_device(dev_qs1000))
-			return(0);
+			return (0);
 		cs->subtyp = ELSA_QS1000PCI;
 		cs->irq = dev_qs1000->irq;
 		cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
 		cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
 	} else if ((dev_qs3000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
-		PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
+						       PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
 		if (pci_enable_device(dev_qs3000))
-			return(0);
+			return (0);
 		cs->subtyp = ELSA_QS3000PCI;
 		cs->irq = dev_qs3000->irq;
 		cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
 		cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
 	} else {
 		printk(KERN_WARNING "Elsa: No PCI card found\n");
-		return(0);
+		return (0);
 	}
 	if (!cs->irq) {
 		printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");
-		return(0);
+		return (0);
 	}
 
 	if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) {
 		printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n");
-		return(0);
+		return (0);
 	}
 	if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) {
 		printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n");
@@ -1071,8 +1071,8 @@ setup_elsa_pci(struct IsdnCard *card)
 		printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n");
 	}
 	cs->hw.elsa.ale  = cs->hw.elsa.base;
-	cs->hw.elsa.isac = cs->hw.elsa.base +1;
-	cs->hw.elsa.hscx = cs->hw.elsa.base +1; 
+	cs->hw.elsa.isac = cs->hw.elsa.base + 1;
+	cs->hw.elsa.hscx = cs->hw.elsa.base + 1;
 	test_and_set_bit(HW_IPAC, &cs->HW_Flags);
 	cs->hw.elsa.timer = 0;
 	cs->hw.elsa.trig  = 0;
@@ -1104,27 +1104,27 @@ setup_elsa_common(struct IsdnCard *card)
 	int bytecnt;
 
 	switch (cs->subtyp) {
-		case ELSA_PC:
-		case ELSA_PCC8:
-		case ELSA_PCC16:
-		case ELSA_QS1000:
-		case ELSA_PCMCIA:
-		case ELSA_PCMCIA_IPAC:
-			bytecnt = 8;
-			break;
-		case ELSA_PCFPRO:
-		case ELSA_PCF:
-		case ELSA_QS3000:
-		case ELSA_QS3000PCI:
-			bytecnt = 16;
-			break;
-		case ELSA_QS1000PCI:
-			bytecnt = 2;
-			break;
-		default:
-			printk(KERN_WARNING
-			       "Unknown ELSA subtype %d\n", cs->subtyp);
-			return (0);
+	case ELSA_PC:
+	case ELSA_PCC8:
+	case ELSA_PCC16:
+	case ELSA_QS1000:
+	case ELSA_PCMCIA:
+	case ELSA_PCMCIA_IPAC:
+		bytecnt = 8;
+		break;
+	case ELSA_PCFPRO:
+	case ELSA_PCF:
+	case ELSA_QS3000:
+	case ELSA_QS3000PCI:
+		bytecnt = 16;
+		break;
+	case ELSA_QS1000PCI:
+		bytecnt = 2;
+		break;
+	default:
+		printk(KERN_WARNING
+		       "Unknown ELSA subtype %d\n", cs->subtyp);
+		return (0);
 	}
 	/* In case of the elsa pcmcia card, this region is in use,
 	   reserved for us by the card manager. So we do not check it
@@ -1140,8 +1140,8 @@ setup_elsa_common(struct IsdnCard *card)
 		if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) {
 			printk(KERN_WARNING
 			       "HiSax: ELSA pci port %x-%x already in use\n",
-				cs->hw.elsa.cfg,
-				cs->hw.elsa.cfg + 0x80);
+			       cs->hw.elsa.cfg,
+			       cs->hw.elsa.cfg + 0x80);
 			release_region(cs->hw.elsa.base, bytecnt);
 			return (0);
 		}
@@ -1166,7 +1166,7 @@ setup_elsa_common(struct IsdnCard *card)
 				return (0);
 			}
 		}
-		HZDELAY((HZ/100) + 1);	/* wait >=10 ms */
+		HZDELAY((HZ / 100) + 1);	/* wait >=10 ms */
 		if (TimerRun(cs)) {
 			printk(KERN_WARNING "Elsa: timer do not run down\n");
 			release_io_elsa(cs);
@@ -1195,7 +1195,7 @@ setup_elsa_common(struct IsdnCard *card)
 		ISACVersion(cs, "Elsa:");
 		if (HscxVersion(cs, "Elsa:")) {
 			printk(KERN_WARNING
-				"Elsa: wrong HSCX versions check IO address\n");
+			       "Elsa: wrong HSCX versions check IO address\n");
 			release_io_elsa(cs);
 			return (0);
 		}
@@ -1244,7 +1244,7 @@ setup_elsa(struct IsdnCard *card)
 		if (!rc)
 			return (0);
 
-	} else 
+	} else
 		return (0);
 
 	return setup_elsa_common(card);
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index f0b6c0e..fe254e7 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -1,39 +1,39 @@
 /*======================================================================
 
-    An elsa_cs PCMCIA client driver
+  An elsa_cs PCMCIA client driver
 
-    This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink
+  This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink
 
 
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
+  The contents of this file are subject to the Mozilla Public
+  License Version 1.1 (the "License"); you may not use this file
+  except in compliance with the License. You may obtain a copy of
+  the License at http://www.mozilla.org/MPL/
 
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
+  Software distributed under the License is distributed on an "AS
+  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+  implied. See the License for the specific language governing
+  rights and limitations under the License.
 
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+  The initial developer of the original code is David A. Hinds
+  <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 
-    Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus
-    Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved.
+  Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus
+  Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved.
 
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
+  Alternatively, the contents of this file may be used under the
+  terms of the GNU General Public License version 2 (the "GPL"), in
+  which case the provisions of the GPL are applicable instead of the
+  above.  If you wish to allow the use of your version of this file
+  only under the terms of the GPL and not to allow others to use
+  your version of this file under the MPL, indicate your decision
+  by deleting the provisions above and replace them with the notice
+  and other provisions required by the GPL.  If you do not delete
+  the provisions above, a recipient may use your version of this
+  file under either the MPL or the GPL.
 
-======================================================================*/
+  ======================================================================*/
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -63,32 +63,32 @@ MODULE_LICENSE("Dual MPL/GPL");
 static int protocol = 2;        /* EURO-ISDN Default */
 module_param(protocol, int, 0);
 
-static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
+static int elsa_cs_config(struct pcmcia_device *link) __devinit;
 static void elsa_cs_release(struct pcmcia_device *link);
 static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
 
 typedef struct local_info_t {
 	struct pcmcia_device	*p_dev;
-    int                 busy;
-    int			cardnr;
+	int                 busy;
+	int			cardnr;
 } local_info_t;
 
 static int __devinit elsa_cs_probe(struct pcmcia_device *link)
 {
-    local_info_t *local;
+	local_info_t *local;
 
-    dev_dbg(&link->dev, "elsa_cs_attach()\n");
+	dev_dbg(&link->dev, "elsa_cs_attach()\n");
 
-    /* Allocate space for private device-specific data */
-    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return -ENOMEM;
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (!local) return -ENOMEM;
 
-    local->p_dev = link;
-    link->priv = local;
+	local->p_dev = link;
+	link->priv = local;
 
-    local->cardnr = -1;
+	local->cardnr = -1;
 
-    return elsa_cs_config(link);
+	return elsa_cs_config(link);
 } /* elsa_cs_attach */
 
 static void __devexit elsa_cs_detach(struct pcmcia_device *link)
@@ -129,64 +129,64 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
 
 static int __devinit elsa_cs_config(struct pcmcia_device *link)
 {
-    int i;
-    IsdnCard_t icard;
-
-    dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
-
-    link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
-
-    i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
-    if (i != 0)
-	goto failed;
-
-    if (!link->irq)
-	goto failed;
-
-    i = pcmcia_enable_device(link);
-    if (i != 0)
-	goto failed;
-
-    icard.para[0] = link->irq;
-    icard.para[1] = link->resource[0]->start;
-    icard.protocol = protocol;
-    icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
-    
-    i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard);
-    if (i < 0) {
-	printk(KERN_ERR "elsa_cs: failed to initialize Elsa "
-		"PCMCIA %d with %pR\n", i, link->resource[0]);
-    	elsa_cs_release(link);
-    } else
-    	((local_info_t*)link->priv)->cardnr = i;
-
-    return 0;
+	int i;
+	IsdnCard_t icard;
+
+	dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
+
+	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+
+	i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
+	if (i != 0)
+		goto failed;
+
+	if (!link->irq)
+		goto failed;
+
+	i = pcmcia_enable_device(link);
+	if (i != 0)
+		goto failed;
+
+	icard.para[0] = link->irq;
+	icard.para[1] = link->resource[0]->start;
+	icard.protocol = protocol;
+	icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
+
+	i = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->busy), &icard);
+	if (i < 0) {
+		printk(KERN_ERR "elsa_cs: failed to initialize Elsa "
+		       "PCMCIA %d with %pR\n", i, link->resource[0]);
+		elsa_cs_release(link);
+	} else
+		((local_info_t *)link->priv)->cardnr = i;
+
+	return 0;
 failed:
-    elsa_cs_release(link);
-    return -ENODEV;
+	elsa_cs_release(link);
+	return -ENODEV;
 } /* elsa_cs_config */
 
 static void elsa_cs_release(struct pcmcia_device *link)
 {
-    local_info_t *local = link->priv;
+	local_info_t *local = link->priv;
 
-    dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
 
-    if (local) {
-    	if (local->cardnr >= 0) {
-    	    /* no unregister function with hisax */
-	    HiSax_closecard(local->cardnr);
+	if (local) {
+		if (local->cardnr >= 0) {
+			/* no unregister function with hisax */
+			HiSax_closecard(local->cardnr);
+		}
 	}
-    }
 
-    pcmcia_disable_device(link);
+	pcmcia_disable_device(link);
 } /* elsa_cs_release */
 
 static int elsa_suspend(struct pcmcia_device *link)
 {
 	local_info_t *dev = link->priv;
 
-        dev->busy = 1;
+	dev->busy = 1;
 
 	return 0;
 }
@@ -195,7 +195,7 @@ static int elsa_resume(struct pcmcia_device *link)
 {
 	local_info_t *dev = link->priv;
 
-        dev->busy = 0;
+	dev->busy = 0;
 
 	return 0;
 }
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index 3fa9f61..d4c98d3 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -12,9 +12,9 @@
 #include <linux/slab.h>
 
 #define MAX_MODEM_BUF	256
-#define WAKEUP_CHARS	(MAX_MODEM_BUF/2)
+#define WAKEUP_CHARS	(MAX_MODEM_BUF / 2)
 #define RS_ISR_PASS_LIMIT 256
-#define BASE_BAUD ( 1843200 / 16 )
+#define BASE_BAUD (1843200 / 16)
 
 //#define SERIAL_DEBUG_OPEN 1
 //#define SERIAL_DEBUG_INTR 1
@@ -27,8 +27,8 @@
 
 #ifdef SERIAL_DEBUG_REG
 static u_char deb[32];
-const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
-const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
+const char *ModemIn[] = {"RBR", "IER", "IIR", "LCR", "MCR", "LSR", "MSR", "SCR"};
+const char *ModemOut[] = {"THR", "IER", "FCR", "LCR", "MCR", "LSR", "MSR", "SCR"};
 #endif
 
 static char *MInit_1 = "AT&F&C1E0&D2\r\0";
@@ -49,8 +49,8 @@ static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
 {
 #ifdef SERIAL_DEBUG_REG
 	u_int val = inb(cs->hw.elsa.base + 8 + offset);
-	debugl1(cs,"in   %s %02x",ModemIn[offset], val);
-	return(val);
+	debugl1(cs, "in   %s %02x", ModemIn[offset], val);
+	return (val);
 #else
 	return inb(cs->hw.elsa.base + 8 + offset);
 #endif
@@ -61,12 +61,12 @@ static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
 #ifdef SERIAL_DEBUG_REG
 #ifdef ELSA_SERIAL_NOPAUSE_IO
 	u_int val = inb(cs->hw.elsa.base + 8 + offset);
-	debugl1(cs,"inp  %s %02x",ModemIn[offset], val);
+	debugl1(cs, "inp  %s %02x", ModemIn[offset], val);
 #else
 	u_int val = inb_p(cs->hw.elsa.base + 8 + offset);
-	debugl1(cs,"inP  %s %02x",ModemIn[offset], val);
+	debugl1(cs, "inP  %s %02x", ModemIn[offset], val);
 #endif
-	return(val);
+	return (val);
 #else
 #ifdef ELSA_SERIAL_NOPAUSE_IO
 	return inb(cs->hw.elsa.base + 8 + offset);
@@ -79,7 +79,7 @@ static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
 static inline void serial_out(struct IsdnCardState *cs, int offset, int value)
 {
 #ifdef SERIAL_DEBUG_REG
-	debugl1(cs,"out  %s %02x",ModemOut[offset], value);
+	debugl1(cs, "out  %s %02x", ModemOut[offset], value);
 #endif
 	outb(value, cs->hw.elsa.base + 8 + offset);
 }
@@ -89,15 +89,15 @@ static inline void serial_outp(struct IsdnCardState *cs, int offset,
 {
 #ifdef SERIAL_DEBUG_REG
 #ifdef ELSA_SERIAL_NOPAUSE_IO
-	debugl1(cs,"outp %s %02x",ModemOut[offset], value);
+	debugl1(cs, "outp %s %02x", ModemOut[offset], value);
 #else
-	debugl1(cs,"outP %s %02x",ModemOut[offset], value);
+	debugl1(cs, "outP %s %02x", ModemOut[offset], value);
 #endif
 #endif
 #ifdef ELSA_SERIAL_NOPAUSE_IO
 	outb(value, cs->hw.elsa.base + 8 + offset);
 #else
-    	outb_p(value, cs->hw.elsa.base + 8 + offset);
+	outb_p(value, cs->hw.elsa.base + 8 + offset);
 #endif
 }
 
@@ -131,7 +131,7 @@ static void change_speed(struct IsdnCardState *cs, int baud)
 	cs->hw.elsa.IER |= UART_IER_MSI;
 	serial_outp(cs, UART_IER, cs->hw.elsa.IER);
 
-	debugl1(cs,"modem quot=0x%x", quot);
+	debugl1(cs, "modem quot=0x%x", quot);
 	serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
 	serial_outp(cs, UART_DLL, quot & 0xff);		/* LS of divisor */
 	serial_outp(cs, UART_DLM, quot >> 8);		/* MS of divisor */
@@ -141,7 +141,7 @@ static void change_speed(struct IsdnCardState *cs, int baud)
 
 static int mstartup(struct IsdnCardState *cs)
 {
-	int	retval=0;
+	int retval = 0;
 
 	/*
 	 * Clear the FIFO buffers and disable them
@@ -158,7 +158,7 @@ static int mstartup(struct IsdnCardState *cs)
 		retval = -ENODEV;
 		goto errout;
 	}
-	
+
 	/*
 	 * Clear the interrupt registers.
 	 */
@@ -167,20 +167,20 @@ static int mstartup(struct IsdnCardState *cs)
 	(void) serial_inp(cs, UART_MSR);
 
 	/*
-	 * Now, initialize the UART 
+	 * Now, initialize the UART
 	 */
 	serial_outp(cs, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
 
 	cs->hw.elsa.MCR = 0;
 	cs->hw.elsa.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
 	serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
-	
+
 	/*
 	 * Finally, enable interrupts
 	 */
 	cs->hw.elsa.IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
 	serial_outp(cs, UART_IER, cs->hw.elsa.IER);	/* enable interrupts */
-	
+
 	/*
 	 * And clear the interrupt registers again for luck.
 	 */
@@ -190,7 +190,7 @@ static int mstartup(struct IsdnCardState *cs)
 	(void)serial_inp(cs, UART_MSR);
 
 	cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0;
-	cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp =0;
+	cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp = 0;
 
 	/*
 	 * and set the speed of the serial port
@@ -211,7 +211,7 @@ static void mshutdown(struct IsdnCardState *cs)
 #ifdef SERIAL_DEBUG_OPEN
 	printk(KERN_DEBUG"Shutting down serial ....");
 #endif
-	
+
 	/*
 	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
 	 * here so the queue might never be waken up
@@ -220,17 +220,17 @@ static void mshutdown(struct IsdnCardState *cs)
 	cs->hw.elsa.IER = 0;
 	serial_outp(cs, UART_IER, 0x00);	/* disable all intrs */
 	cs->hw.elsa.MCR &= ~UART_MCR_OUT2;
-	
+
 	/* disable break condition */
 	serial_outp(cs, UART_LCR, serial_inp(cs, UART_LCR) & ~UART_LCR_SBC);
-	
-	cs->hw.elsa.MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+
+	cs->hw.elsa.MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
 	serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
 
-	/* disable FIFO's */	
+	/* disable FIFO's */
 	serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
 	serial_inp(cs, UART_RX);    /* read data port to reset things */
-	
+
 #ifdef SERIAL_DEBUG_OPEN
 	printk(" done\n");
 #endif
@@ -238,10 +238,10 @@ static void mshutdown(struct IsdnCardState *cs)
 
 static inline int
 write_modem(struct BCState *bcs) {
-	int ret=0;
+	int ret = 0;
 	struct IsdnCardState *cs = bcs->cs;
 	int count, len, fp;
-	
+
 	if (!bcs->tx_skb)
 		return 0;
 	if (bcs->tx_skb->len <= 0)
@@ -250,7 +250,7 @@ write_modem(struct BCState *bcs) {
 	if (len > MAX_MODEM_BUF - cs->hw.elsa.transcnt)
 		len = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
 	fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
-	fp &= (MAX_MODEM_BUF -1);
+	fp &= (MAX_MODEM_BUF - 1);
 	count = len;
 	if (count > MAX_MODEM_BUF - fp) {
 		count = MAX_MODEM_BUF - fp;
@@ -267,25 +267,25 @@ write_modem(struct BCState *bcs) {
 	skb_pull(bcs->tx_skb, count);
 	cs->hw.elsa.transcnt += count;
 	ret += count;
-	
-	if (cs->hw.elsa.transcnt && 
+
+	if (cs->hw.elsa.transcnt &&
 	    !(cs->hw.elsa.IER & UART_IER_THRI)) {
-			cs->hw.elsa.IER |= UART_IER_THRI;
+		cs->hw.elsa.IER |= UART_IER_THRI;
 		serial_outp(cs, UART_IER, cs->hw.elsa.IER);
 	}
-	return(ret);
+	return (ret);
 }
 
 static inline void
 modem_fill(struct BCState *bcs) {
-		
+
 	if (bcs->tx_skb) {
 		if (bcs->tx_skb->len) {
 			write_modem(bcs);
 			return;
 		} else {
-			if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-				(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+			if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+			    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 				u_long	flags;
 				spin_lock_irqsave(&bcs->aclock, flags);
 				bcs->ackcnt += bcs->hw.hscx.count;
@@ -322,7 +322,7 @@ static inline void receive_chars(struct IsdnCardState *cs,
 #endif
 		if (*status & (UART_LSR_BI | UART_LSR_PE |
 			       UART_LSR_FE | UART_LSR_OE)) {
-					
+
 #ifdef SERIAL_DEBUG_INTR
 			printk("handling exept....");
 #endif
@@ -333,9 +333,9 @@ static inline void receive_chars(struct IsdnCardState *cs,
 		if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
 			printk(KERN_WARNING "ElsaSER: receive out of memory\n");
 		else {
-			memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf, 
-				cs->hw.elsa.rcvcnt);
-			skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
+			memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf,
+			       cs->hw.elsa.rcvcnt);
+			skb_queue_tail(&cs->hw.elsa.bcs->rqueue, skb);
 		}
 		schedule_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
 	} else {
@@ -352,10 +352,10 @@ static inline void receive_chars(struct IsdnCardState *cs,
 static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
 {
 	int count;
-	
-	debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp, 
+
+	debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
 		cs->hw.elsa.transcnt);
-	
+
 	if (cs->hw.elsa.transcnt <= 0) {
 		cs->hw.elsa.IER &= ~UART_IER_THRI;
 		serial_out(cs, UART_IER, cs->hw.elsa.IER);
@@ -365,11 +365,11 @@ static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
 	do {
 		serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
 		if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
-			cs->hw.elsa.transp=0;
+			cs->hw.elsa.transp = 0;
 		if (--cs->hw.elsa.transcnt <= 0)
 			break;
 	} while (--count > 0);
-	if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
+	if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag == 2))
 		modem_fill(cs->hw.elsa.bcs);
 
 #ifdef SERIAL_DEBUG_INTR
@@ -388,14 +388,14 @@ static void rs_interrupt_elsa(struct IsdnCardState *cs)
 {
 	int status, iir, msr;
 	int pass_counter = 0;
-	
+
 #ifdef SERIAL_DEBUG_INTR
 	printk(KERN_DEBUG "rs_interrupt_single(%d)...", cs->irq);
 #endif
 
 	do {
 		status = serial_inp(cs, UART_LSR);
-		debugl1(cs,"rs LSR %02x", status);
+		debugl1(cs, "rs LSR %02x", status);
 #ifdef SERIAL_DEBUG_INTR
 		printk("status = %x...", status);
 #endif
@@ -408,10 +408,10 @@ static void rs_interrupt_elsa(struct IsdnCardState *cs)
 			break;
 		}
 		iir = serial_inp(cs, UART_IIR);
-		debugl1(cs,"rs IIR %02x", iir);
+		debugl1(cs, "rs IIR %02x", iir);
 		if ((iir & 0xf) == 0) {
 			msr = serial_inp(cs, UART_MSR);
-			debugl1(cs,"rs MSR %02x", msr);
+			debugl1(cs, "rs MSR %02x", msr);
 		}
 	} while (!(iir & UART_IIR_NO_INT));
 #ifdef SERIAL_DEBUG_INTR
@@ -447,14 +447,14 @@ static void
 modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
 	int count, fp;
 	u_char *msg = buf;
-	
+
 	if (!len)
 		return;
 	if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
 		return;
 	}
 	fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
-	fp &= (MAX_MODEM_BUF -1);
+	fp &= (MAX_MODEM_BUF - 1);
 	count = len;
 	if (count > MAX_MODEM_BUF - fp) {
 		count = MAX_MODEM_BUF - fp;
@@ -466,7 +466,7 @@ modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
 	}
 	memcpy(cs->hw.elsa.transbuf + fp, msg, count);
 	cs->hw.elsa.transcnt += count;
-	if (cs->hw.elsa.transcnt && 
+	if (cs->hw.elsa.transcnt &&
 	    !(cs->hw.elsa.IER & UART_IER_THRI)) {
 		cs->hw.elsa.IER |= UART_IER_THRI;
 		serial_outp(cs, UART_IER, cs->hw.elsa.IER);
@@ -480,43 +480,43 @@ modem_set_init(struct IsdnCardState *cs) {
 #define RCV_DELAY 20
 	modem_write_cmd(cs, MInit_1, strlen(MInit_1));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
 	modem_write_cmd(cs, MInit_2, strlen(MInit_2));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
 	modem_write_cmd(cs, MInit_3, strlen(MInit_3));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
 	modem_write_cmd(cs, MInit_4, strlen(MInit_4));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
 	modem_write_cmd(cs, MInit_5, strlen(MInit_5));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
 	modem_write_cmd(cs, MInit_6, strlen(MInit_6));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
 	modem_write_cmd(cs, MInit_7, strlen(MInit_7));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
@@ -529,7 +529,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) {
 
 	modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
@@ -538,7 +538,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) {
 	else
 		modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
 	timeout = 1000;
-	while(timeout-- && cs->hw.elsa.transcnt)
+	while (timeout-- && cs->hw.elsa.transcnt)
 		udelay(1000);
 	debugl1(cs, "msi tout=%d", timeout);
 	mdelay(RCV_DELAY);
@@ -568,15 +568,15 @@ modem_l2l1(struct PStack *st, int pr, void *arg)
 		set_arcofi(bcs->cs, st->l1.bc);
 		mstartup(bcs->cs);
 		modem_set_dial(bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
-		bcs->cs->hw.elsa.MFlag=2;
+		bcs->cs->hw.elsa.MFlag = 2;
 	} else if (pr == (PH_DEACTIVATE | REQUEST)) {
 		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
 		bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
 		arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
 		interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait);
-		bcs->cs->hw.elsa.MFlag=1;
+		bcs->cs->hw.elsa.MFlag = 1;
 	} else {
-		printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
+		printk(KERN_WARNING "ElsaSer: unknown pr %x\n", pr);
 	}
 }
 
@@ -586,27 +586,27 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
 
 	bcs->channel = st->l1.bc;
 	switch (st->l1.mode) {
-		case L1_MODE_HDLC:
-		case L1_MODE_TRANS:
-			if (open_hscxstate(st->l1.hardware, bcs))
-				return (-1);
-			st->l2.l2l1 = hscx_l2l1;
-			break;
-		case L1_MODE_MODEM:
-			bcs->mode = L1_MODE_MODEM;
-			if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
-				bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
-				skb_queue_head_init(&bcs->rqueue);
-				skb_queue_head_init(&bcs->squeue);
-			}
-			bcs->tx_skb = NULL;
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			bcs->event = 0;
-			bcs->hw.hscx.rcvidx = 0;
-			bcs->tx_cnt = 0;
-			bcs->cs->hw.elsa.bcs = bcs;
-			st->l2.l2l1 = modem_l2l1;
-			break;
+	case L1_MODE_HDLC:
+	case L1_MODE_TRANS:
+		if (open_hscxstate(st->l1.hardware, bcs))
+			return (-1);
+		st->l2.l2l1 = hscx_l2l1;
+		break;
+	case L1_MODE_MODEM:
+		bcs->mode = L1_MODE_MODEM;
+		if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
+			bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
+			skb_queue_head_init(&bcs->rqueue);
+			skb_queue_head_init(&bcs->squeue);
+		}
+		bcs->tx_skb = NULL;
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		bcs->event = 0;
+		bcs->hw.hscx.rcvidx = 0;
+		bcs->tx_cnt = 0;
+		bcs->cs->hw.elsa.bcs = bcs;
+		st->l2.l2l1 = modem_l2l1;
+		break;
 	}
 	st->l1.bcs = bcs;
 	setstack_manager(st);
@@ -623,15 +623,15 @@ init_modem(struct IsdnCardState *cs) {
 	cs->bcs[0].BC_Close = close_elsastate;
 	cs->bcs[1].BC_Close = close_elsastate;
 	if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
-		GFP_ATOMIC))) {
+					   GFP_ATOMIC))) {
 		printk(KERN_WARNING
-			"Elsa: No modem mem hw.elsa.rcvbuf\n");
+		       "Elsa: No modem mem hw.elsa.rcvbuf\n");
 		return;
 	}
 	if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
-		GFP_ATOMIC))) {
+					     GFP_ATOMIC))) {
 		printk(KERN_WARNING
-			"Elsa: No modem mem hw.elsa.transbuf\n");
+		       "Elsa: No modem mem hw.elsa.transbuf\n");
 		kfree(cs->hw.elsa.rcvbuf);
 		cs->hw.elsa.rcvbuf = NULL;
 		return;
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
index f55d29d..b1e38b5 100644
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -97,13 +97,13 @@ static unsigned char
 ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
 {
 	/* direct register */
-	if(offset < 8)
-		return (inb(cs->hw.njet.isac + 4*offset));
+	if (offset < 8)
+		return (inb(cs->hw.njet.isac + 4 * offset));
 
 	/* indirect register */
 	else {
-		outb(offset, cs->hw.njet.isac + 4*AMD_CR);
-		return(inb(cs->hw.njet.isac + 4*AMD_DR));
+		outb(offset, cs->hw.njet.isac + 4 * AMD_CR);
+		return (inb(cs->hw.njet.isac + 4 * AMD_DR));
 	}
 }
 
@@ -112,29 +112,29 @@ static void
 WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
 {
 	/* direct register */
-	if(offset < 8)
-		outb(value, cs->hw.njet.isac + 4*offset);
+	if (offset < 8)
+		outb(value, cs->hw.njet.isac + 4 * offset);
 
 	/* indirect register */
 	else {
-		outb(offset, cs->hw.njet.isac + 4*AMD_CR);
-		outb(value, cs->hw.njet.isac + 4*AMD_DR);
+		outb(offset, cs->hw.njet.isac + 4 * AMD_CR);
+		outb(value, cs->hw.njet.isac + 4 * AMD_DR);
 	}
 }
 
 
 static void
 enpci_setIrqMask(struct IsdnCardState *cs, unsigned char val) {
-        if (!val)
-	        outb(0x00, cs->hw.njet.base+NETJET_IRQMASK1);
-        else
-	        outb(TJ_AMD_IRQ, cs->hw.njet.base+NETJET_IRQMASK1);
+	if (!val)
+		outb(0x00, cs->hw.njet.base + NETJET_IRQMASK1);
+	else
+		outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
 }
 
 
 static unsigned char dummyrr(struct IsdnCardState *cs, int chan, unsigned char off)
 {
-        return(5);
+	return (5);
 }
 
 static void dummywr(struct IsdnCardState *cs, int chan, unsigned char off, unsigned char value)
@@ -173,70 +173,70 @@ static int
 enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
 	u_long flags;
-        unsigned char *chan;
+	unsigned char *chan;
 
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt);
 
-        switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_enpci(cs);
-                        Amd7930_init(cs);
-                        spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case CARD_RELEASE:
-			release_io_netjet(cs);
-			break;
-		case CARD_INIT:
-			reset_enpci(cs);
-			inittiger(cs);
-			/* irq must be on here */
-			Amd7930_init(cs);
-			break;
-		case CARD_TEST:
-			break;
-                case MDL_ASSIGN:
-                        /* TEI assigned, LED1 on */
-                        cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
-                        outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
-                        break;
-                case MDL_REMOVE:
-                        /* TEI removed, LEDs off */
-	                cs->hw.njet.auxd = 0;
-                        outb(0x00, cs->hw.njet.base + NETJET_AUXDATA);
-                        break;
-                case MDL_BC_ASSIGN:
-                        /* activate B-channel */
-                        chan = (unsigned char *)arg;
-
-                        if (cs->debug & L1_DEB_ISAC)
-		                debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan);
-
-                        cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN");
-                        /* at least one b-channel in use, LED 2 on */
-                        cs->hw.njet.auxd |= TJ_AMD_IRQ << 2;
-                        outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
-                        break;
-                case MDL_BC_RELEASE:
-                        /* deactivate B-channel */
-                        chan = (unsigned char *)arg;
-
-                        if (cs->debug & L1_DEB_ISAC)
-		                debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan);
-
-                        cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 & ~(*chan + 1)), "MDL_BC_RELEASE");
-                        /* no b-channel active -> LED2 off */
-                        if (!(cs->dc.amd7930.lmr1 & 3)) {
-                                cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2);
-                                outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
-                        }
-                        break;
-                default:
-                        break;
+	switch (mt) {
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_enpci(cs);
+		Amd7930_init(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case CARD_RELEASE:
+		release_io_netjet(cs);
+		break;
+	case CARD_INIT:
+		reset_enpci(cs);
+		inittiger(cs);
+		/* irq must be on here */
+		Amd7930_init(cs);
+		break;
+	case CARD_TEST:
+		break;
+	case MDL_ASSIGN:
+		/* TEI assigned, LED1 on */
+		cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
+		outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
+		break;
+	case MDL_REMOVE:
+		/* TEI removed, LEDs off */
+		cs->hw.njet.auxd = 0;
+		outb(0x00, cs->hw.njet.base + NETJET_AUXDATA);
+		break;
+	case MDL_BC_ASSIGN:
+		/* activate B-channel */
+		chan = (unsigned char *)arg;
+
+		if (cs->debug & L1_DEB_ISAC)
+			debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan);
+
+		cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN");
+		/* at least one b-channel in use, LED 2 on */
+		cs->hw.njet.auxd |= TJ_AMD_IRQ << 2;
+		outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
+		break;
+	case MDL_BC_RELEASE:
+		/* deactivate B-channel */
+		chan = (unsigned char *)arg;
+
+		if (cs->debug & L1_DEB_ISAC)
+			debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan);
+
+		cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 & ~(*chan + 1)), "MDL_BC_RELEASE");
+		/* no b-channel active -> LED2 off */
+		if (!(cs->dc.amd7930.lmr1 & 3)) {
+			cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2);
+			outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
+		}
+		break;
+	default:
+		break;
 
 	}
-	return(0);
+	return (0);
 }
 
 static irqreturn_t
@@ -249,32 +249,32 @@ enpci_interrupt(int intno, void *dev_id)
 	spin_lock_irqsave(&cs->lock, flags);
 	s1val = inb(cs->hw.njet.base + NETJET_IRQSTAT1);
 
-        /* AMD threw an interrupt */
+	/* AMD threw an interrupt */
 	if (!(s1val & TJ_AMD_IRQ)) {
-                /* read and clear interrupt-register */
+		/* read and clear interrupt-register */
 		ir = ReadByteAmd7930(cs, 0x00);
 		Amd7930_interrupt(cs, ir);
 		s1val = 1;
 	} else
 		s1val = 0;
 	s0val = inb(cs->hw.njet.base + NETJET_IRQSTAT0);
-	if ((s0val | s1val)==0) { // shared IRQ
+	if ((s0val | s1val) == 0) { // shared IRQ
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return IRQ_NONE;
-	} 
+	}
 	if (s0val)
 		outb(s0val, cs->hw.njet.base + NETJET_IRQSTAT0);
 
 	/* DMA-Interrupt: B-channel-stuff */
 	/* set bits in sval to indicate which page is free */
 	if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
-		inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
+	    inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
 		/* the 2nd write page is free */
 		s0val = 0x08;
 	else	/* the 1st write page is free */
 		s0val = 0x04;
 	if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
-		inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
+	    inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
 		/* the 2nd read page is free */
 		s0val = s0val | 0x02;
 	else	/* the 1st read page is free */
@@ -287,11 +287,11 @@ enpci_interrupt(int intno, void *dev_id)
 		}
 		cs->hw.njet.irqstat0 = s0val;
 		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) !=
-			(cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
+		    (cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
 			/* we have a read dma int */
 			read_tiger(cs);
 		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
-			(cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
+		    (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
 			/* we have a write dma int */
 			write_tiger(cs);
 		test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -304,26 +304,26 @@ static int __devinit en_pci_probe(struct pci_dev *dev_netjet,
 				  struct IsdnCardState *cs)
 {
 	if (pci_enable_device(dev_netjet))
-		return(0);
+		return (0);
 	cs->irq = dev_netjet->irq;
 	if (!cs->irq) {
 		printk(KERN_WARNING "enter:now PCI: No IRQ for PCI card found\n");
-		return(0);
+		return (0);
 	}
 	cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
 	if (!cs->hw.njet.base) {
 		printk(KERN_WARNING "enter:now PCI: No IO-Adr for PCI card found\n");
-		return(0);
+		return (0);
 	}
 	/* checks Sub-Vendor ID because system crashes with Traverse-Card */
 	if ((dev_netjet->subsystem_vendor != 0x55) ||
 	    (dev_netjet->subsystem_device != 0x02)) {
 		printk(KERN_WARNING "enter:now: You tried to load this driver with an incompatible TigerJet-card\n");
 		printk(KERN_WARNING "Use type=20 for Traverse NetJet PCI Card.\n");
-		return(0);
+		return (0);
 	}
 
-	return(1);
+	return (1);
 }
 
 static void __devinit en_cs_init(struct IsdnCard *card,
@@ -356,8 +356,8 @@ static int __devinit en_cs_init_rest(struct IsdnCard *card,
 	const int bytecnt = 256;
 
 	printk(KERN_INFO
-		"enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
-		cs->hw.njet.base, cs->irq);
+	       "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
+	       cs->hw.njet.base, cs->irq);
 	if (!request_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) {
 		printk(KERN_WARNING
 		       "HiSax: enter:now config port %lx-%lx already in use\n",
@@ -368,13 +368,13 @@ static int __devinit en_cs_init_rest(struct IsdnCard *card,
 
 	setup_Amd7930(cs);
 	cs->hw.njet.last_is0 = 0;
-        /* macro rByteAMD */
-        cs->readisac = &ReadByteAmd7930;
-        /* macro wByteAMD */
-        cs->writeisac = &WriteByteAmd7930;
-        cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;
+	/* macro rByteAMD */
+	cs->readisac = &ReadByteAmd7930;
+	/* macro wByteAMD */
+	cs->writeisac = &WriteByteAmd7930;
+	cs->dc.amd7930.setIrqMask = &enpci_setIrqMask;
 
-        cs->BC_Read_Reg  = &dummyrr;
+	cs->BC_Read_Reg  = &dummyrr;
 	cs->BC_Write_Reg = &dummywr;
 	cs->BC_Send_Data = &netjet_fill_dma;
 	cs->cardmsg = &enpci_card_msg;
@@ -398,27 +398,27 @@ setup_enternow_pci(struct IsdnCard *card)
 #error "not running on big endian machines now"
 #endif
 
-        strcpy(tmp, enternow_pci_rev);
+	strcpy(tmp, enternow_pci_rev);
 	printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_ENTERNOW)
-		return(0);
+		return (0);
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 
-	for ( ;; )
+	for (;;)
 	{
 		if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
-			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
+							PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			ret = en_pci_probe(dev_netjet, cs);
 			if (!ret)
-				return(0);
+				return (0);
 		} else {
-                        printk(KERN_WARNING "enter:now PCI: No PCI card found\n");
-			return(0);
+			printk(KERN_WARNING "enter:now PCI: No PCI card found\n");
+			return (0);
 		}
 
 		en_cs_init(card, cs);
 		break;
 	}
 
-        return en_cs_init_rest(card, cs);
+	return en_cs_init_rest(card, cs);
 }
diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c
index 732ea63..1bb2910 100644
--- a/drivers/isdn/hisax/fsm.c
+++ b/drivers/isdn/hisax/fsm.c
@@ -5,7 +5,7 @@
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *              by Kai Germaschewski <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -27,18 +27,18 @@ FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
 	int i;
 
 	fsm->jumpmatrix = (FSMFNPTR *)
-		kzalloc(sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL);
+		kzalloc(sizeof(FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL);
 	if (!fsm->jumpmatrix)
 		return -ENOMEM;
 
-	for (i = 0; i < fncount; i++) 
-		if ((fnlist[i].state>=fsm->state_count) || (fnlist[i].event>=fsm->event_count)) {
+	for (i = 0; i < fncount; i++)
+		if ((fnlist[i].state >= fsm->state_count) || (fnlist[i].event >= fsm->event_count)) {
 			printk(KERN_ERR "FsmNew Error line %d st(%ld/%ld) ev(%ld/%ld)\n",
-				i,(long)fnlist[i].state,(long)fsm->state_count,
-				(long)fnlist[i].event,(long)fsm->event_count);
-		} else		
+			       i, (long)fnlist[i].state, (long)fsm->state_count,
+			       (long)fnlist[i].event, (long)fsm->event_count);
+		} else
 			fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
-				fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
+					fnlist[i].state] = (FSMFNPTR)fnlist[i].routine;
 	return 0;
 }
 
@@ -53,24 +53,24 @@ FsmEvent(struct FsmInst *fi, int event, void *arg)
 {
 	FSMFNPTR r;
 
-	if ((fi->state>=fi->fsm->state_count) || (event >= fi->fsm->event_count)) {
+	if ((fi->state >= fi->fsm->state_count) || (event >= fi->fsm->event_count)) {
 		printk(KERN_ERR "FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
-			(long)fi->state,(long)fi->fsm->state_count,event,(long)fi->fsm->event_count);
-		return(1);
+		       (long)fi->state, (long)fi->fsm->state_count, event, (long)fi->fsm->event_count);
+		return (1);
 	}
 	r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state];
 	if (r) {
 		if (fi->debug)
 			fi->printdebug(fi, "State %s Event %s",
-				fi->fsm->strState[fi->state],
-				fi->fsm->strEvent[event]);
+				       fi->fsm->strState[fi->state],
+				       fi->fsm->strEvent[event]);
 		r(fi, event, arg);
 		return (0);
 	} else {
 		if (fi->debug)
 			fi->printdebug(fi, "State %s Event %s no routine",
-				fi->fsm->strState[fi->state],
-				fi->fsm->strEvent[event]);
+				       fi->fsm->strState[fi->state],
+				       fi->fsm->strEvent[event]);
 		return (!0);
 	}
 }
@@ -81,7 +81,7 @@ FsmChangeState(struct FsmInst *fi, int newstate)
 	fi->state = newstate;
 	if (fi->debug)
 		fi->printdebug(fi, "ChangeState %s",
-			fi->fsm->strState[newstate]);
+			       fi->fsm->strState[newstate]);
 }
 
 static void
@@ -125,7 +125,7 @@ FsmAddTimer(struct FsmTimer *ft,
 #if FSM_TIMER_DEBUG
 	if (ft->fi->debug)
 		ft->fi->printdebug(ft->fi, "FsmAddTimer %lx %d %d",
-			(long) ft, millisec, where);
+				   (long) ft, millisec, where);
 #endif
 
 	if (timer_pending(&ft->tl)) {
@@ -143,13 +143,13 @@ FsmAddTimer(struct FsmTimer *ft,
 
 void
 FsmRestartTimer(struct FsmTimer *ft,
-	    int millisec, int event, void *arg, int where)
+		int millisec, int event, void *arg, int where)
 {
 
 #if FSM_TIMER_DEBUG
 	if (ft->fi->debug)
 		ft->fi->printdebug(ft->fi, "FsmRestartTimer %lx %d %d",
-			(long) ft, millisec, where);
+				   (long) ft, millisec, where);
 #endif
 
 	if (timer_pending(&ft->tl))
diff --git a/drivers/isdn/hisax/fsm.h b/drivers/isdn/hisax/fsm.h
index f02f7da..8c73856 100644
--- a/drivers/isdn/hisax/fsm.h
+++ b/drivers/isdn/hisax/fsm.h
@@ -5,7 +5,7 @@
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *              by Kai Germaschewski <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -18,7 +18,7 @@
 
 struct FsmInst;
 
-typedef void (* FSMFNPTR)(struct FsmInst *, int, void *);
+typedef void (*FSMFNPTR)(struct FsmInst *, int, void *);
 
 struct Fsm {
 	FSMFNPTR *jumpmatrix;
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c
index 353982f..4fef775 100644
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -5,7 +5,7 @@
  * Author       BeWan Systems
  *              based on source code from Karsten Keil
  * Copyright    by BeWan Systems
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -38,7 +38,7 @@ static const char *gazel_revision = "$Revision: 2.19.2.4 $";
 #define INT_IPAC_EN  0x3	/* enable IT ipac */
 
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static inline u_char
@@ -55,13 +55,13 @@ writereg(unsigned int adr, u_short off, u_char data)
 
 
 static inline void
-read_fifo(unsigned int adr, u_char * data, int size)
+read_fifo(unsigned int adr, u_char *data, int size)
 {
 	insb(adr, data, size);
 }
 
 static void
-write_fifo(unsigned int adr, u_char * data, int size)
+write_fifo(unsigned int adr, u_char *data, int size)
 {
 	outsb(adr, data, size);
 }
@@ -85,14 +85,14 @@ writereg_ipac(unsigned int adr, u_short off, u_char data)
 
 
 static inline void
-read_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size)
+read_fifo_ipac(unsigned int adr, u_short off, u_char *data, int size)
 {
 	byteout(adr, off);
 	insb(adr + 4, data, size);
 }
 
 static void
-write_fifo_ipac(unsigned int adr, u_short off, u_char * data, int size)
+write_fifo_ipac(unsigned int adr, u_short off, u_char *data, int size)
 {
 	byteout(adr, off);
 	outsb(adr + 4, data, size);
@@ -106,13 +106,13 @@ ReadISAC(struct IsdnCardState *cs, u_char offset)
 	u_short off2 = offset;
 
 	switch (cs->subtyp) {
-		case R647:
-			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
-		case R685:
-			return (readreg(cs->hw.gazel.isac, off2));
-		case R753:
-		case R742:
-			return (readreg_ipac(cs->hw.gazel.ipac, 0x80 + off2));
+	case R647:
+		off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
+	case R685:
+		return (readreg(cs->hw.gazel.isac, off2));
+	case R753:
+	case R742:
+		return (readreg_ipac(cs->hw.gazel.ipac, 0x80 + off2));
 	}
 	return 0;
 }
@@ -123,75 +123,75 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 	u_short off2 = offset;
 
 	switch (cs->subtyp) {
-		case R647:
-			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
-		case R685:
-			writereg(cs->hw.gazel.isac, off2, value);
-			break;
-		case R753:
-		case R742:
-			writereg_ipac(cs->hw.gazel.ipac, 0x80 + off2, value);
-			break;
+	case R647:
+		off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
+	case R685:
+		writereg(cs->hw.gazel.isac, off2, value);
+		break;
+	case R753:
+	case R742:
+		writereg_ipac(cs->hw.gazel.ipac, 0x80 + off2, value);
+		break;
 	}
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	switch (cs->subtyp) {
-		case R647:
-		case R685:
-			read_fifo(cs->hw.gazel.isacfifo, data, size);
-			break;
-		case R753:
-		case R742:
-			read_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);
-			break;
+	case R647:
+	case R685:
+		read_fifo(cs->hw.gazel.isacfifo, data, size);
+		break;
+	case R753:
+	case R742:
+		read_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);
+		break;
 	}
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	switch (cs->subtyp) {
-		case R647:
-		case R685:
-			write_fifo(cs->hw.gazel.isacfifo, data, size);
-			break;
-		case R753:
-		case R742:
-			write_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);
-			break;
+	case R647:
+	case R685:
+		write_fifo(cs->hw.gazel.isacfifo, data, size);
+		break;
+	case R753:
+	case R742:
+		write_fifo_ipac(cs->hw.gazel.ipac, 0x80, data, size);
+		break;
 	}
 }
 
 static void
-ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
+ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size)
 {
 	switch (cs->subtyp) {
-		case R647:
-		case R685:
-			read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
-			break;
-		case R753:
-		case R742:
-			read_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);
-			break;
+	case R647:
+	case R685:
+		read_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
+		break;
+	case R753:
+	case R742:
+		read_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);
+		break;
 	}
 }
 
 static void
-WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
+WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char *data, int size)
 {
 	switch (cs->subtyp) {
-		case R647:
-		case R685:
-			write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
-			break;
-		case R753:
-		case R742:
-			write_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);
-			break;
+	case R647:
+	case R685:
+		write_fifo(cs->hw.gazel.hscxfifo[hscx], data, size);
+		break;
+	case R753:
+	case R742:
+		write_fifo_ipac(cs->hw.gazel.ipac, hscx * 0x40, data, size);
+		break;
 	}
 }
 
@@ -201,13 +201,13 @@ ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 	u_short off2 = offset;
 
 	switch (cs->subtyp) {
-		case R647:
-			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
-		case R685:
-			return (readreg(cs->hw.gazel.hscx[hscx], off2));
-		case R753:
-		case R742:
-			return (readreg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2));
+	case R647:
+		off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
+	case R685:
+		return (readreg(cs->hw.gazel.hscx[hscx], off2));
+	case R753:
+	case R742:
+		return (readreg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2));
 	}
 	return 0;
 }
@@ -218,15 +218,15 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 	u_short off2 = offset;
 
 	switch (cs->subtyp) {
-		case R647:
-			off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
-		case R685:
-			writereg(cs->hw.gazel.hscx[hscx], off2, value);
-			break;
-		case R753:
-		case R742:
-			writereg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2, value);
-			break;
+	case R647:
+		off2 = ((off2 << 8 & 0xf000) | (off2 & 0xf));
+	case R685:
+		writereg(cs->hw.gazel.hscx[hscx], off2, value);
+		break;
+	case R753:
+	case R742:
+		writereg_ipac(cs->hw.gazel.ipac, hscx * 0x40 + off2, value);
+		break;
 	}
 }
 
@@ -279,7 +279,7 @@ gazel_interrupt_ipac(int intno, void *dev_id)
 	u_char ista, val;
 	int count = 0;
 	u_long flags;
-	
+
 	spin_lock_irqsave(&cs->lock, flags);
 	ista = ReadISAC(cs, IPAC_ISTA - 0x80);
 	do {
@@ -322,25 +322,25 @@ release_io_gazel(struct IsdnCardState *cs)
 	unsigned int i;
 
 	switch (cs->subtyp) {
-		case R647:
-			for (i = 0x0000; i < 0xC000; i += 0x1000)
-				release_region(i + cs->hw.gazel.hscx[0], 16);
-			release_region(0xC000 + cs->hw.gazel.hscx[0], 1);
-			break;
-
-		case R685:
-			release_region(cs->hw.gazel.hscx[0], 0x100);
-			release_region(cs->hw.gazel.cfg_reg, 0x80);
-			break;
-
-		case R753:
-			release_region(cs->hw.gazel.ipac, 0x8);
-			release_region(cs->hw.gazel.cfg_reg, 0x80);
-			break;
-
-		case R742:
-			release_region(cs->hw.gazel.ipac, 8);
-			break;
+	case R647:
+		for (i = 0x0000; i < 0xC000; i += 0x1000)
+			release_region(i + cs->hw.gazel.hscx[0], 16);
+		release_region(0xC000 + cs->hw.gazel.hscx[0], 1);
+		break;
+
+	case R685:
+		release_region(cs->hw.gazel.hscx[0], 0x100);
+		release_region(cs->hw.gazel.cfg_reg, 0x80);
+		break;
+
+	case R753:
+		release_region(cs->hw.gazel.ipac, 0x8);
+		release_region(cs->hw.gazel.cfg_reg, 0x80);
+		break;
+
+	case R742:
+		release_region(cs->hw.gazel.ipac, 8);
+		break;
 	}
 }
 
@@ -350,49 +350,49 @@ reset_gazel(struct IsdnCardState *cs)
 	unsigned long plxcntrl, addr = cs->hw.gazel.cfg_reg;
 
 	switch (cs->subtyp) {
-		case R647:
-			writereg(addr, 0, 0);
-			HZDELAY(10);
-			writereg(addr, 0, 1);
-			HZDELAY(2);
-			break;
-		case R685:
-			plxcntrl = inl(addr + PLX_CNTRL);
-			plxcntrl |= (RESET_9050 + RESET_GAZEL);
-			outl(plxcntrl, addr + PLX_CNTRL);
-			plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
-			HZDELAY(4);
-			outl(plxcntrl, addr + PLX_CNTRL);
-			HZDELAY(10);
-			outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR);
-			break;
-		case R753:
-			plxcntrl = inl(addr + PLX_CNTRL);
-			plxcntrl |= (RESET_9050 + RESET_GAZEL);
-			outl(plxcntrl, addr + PLX_CNTRL);
-			plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
-			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
-			HZDELAY(4);
-			outl(plxcntrl, addr + PLX_CNTRL);
-			HZDELAY(10);
-			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
-			WriteISAC(cs, IPAC_ACFG - 0x80, 0xff);
-			WriteISAC(cs, IPAC_AOE - 0x80, 0x0);
-			WriteISAC(cs, IPAC_MASK - 0x80, 0xff);
-			WriteISAC(cs, IPAC_CONF - 0x80, 0x1);
-			outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR);
-			WriteISAC(cs, IPAC_MASK - 0x80, 0xc0);
-			break;
-		case R742:
-			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
-			HZDELAY(4);
-			WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
-			WriteISAC(cs, IPAC_ACFG - 0x80, 0xff);
-			WriteISAC(cs, IPAC_AOE - 0x80, 0x0);
-			WriteISAC(cs, IPAC_MASK - 0x80, 0xff);
-			WriteISAC(cs, IPAC_CONF - 0x80, 0x1);
-			WriteISAC(cs, IPAC_MASK - 0x80, 0xc0);
-			break;
+	case R647:
+		writereg(addr, 0, 0);
+		HZDELAY(10);
+		writereg(addr, 0, 1);
+		HZDELAY(2);
+		break;
+	case R685:
+		plxcntrl = inl(addr + PLX_CNTRL);
+		plxcntrl |= (RESET_9050 + RESET_GAZEL);
+		outl(plxcntrl, addr + PLX_CNTRL);
+		plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
+		HZDELAY(4);
+		outl(plxcntrl, addr + PLX_CNTRL);
+		HZDELAY(10);
+		outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR);
+		break;
+	case R753:
+		plxcntrl = inl(addr + PLX_CNTRL);
+		plxcntrl |= (RESET_9050 + RESET_GAZEL);
+		outl(plxcntrl, addr + PLX_CNTRL);
+		plxcntrl &= ~(RESET_9050 + RESET_GAZEL);
+		WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
+		HZDELAY(4);
+		outl(plxcntrl, addr + PLX_CNTRL);
+		HZDELAY(10);
+		WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
+		WriteISAC(cs, IPAC_ACFG - 0x80, 0xff);
+		WriteISAC(cs, IPAC_AOE - 0x80, 0x0);
+		WriteISAC(cs, IPAC_MASK - 0x80, 0xff);
+		WriteISAC(cs, IPAC_CONF - 0x80, 0x1);
+		outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR);
+		WriteISAC(cs, IPAC_MASK - 0x80, 0xc0);
+		break;
+	case R742:
+		WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20);
+		HZDELAY(4);
+		WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00);
+		WriteISAC(cs, IPAC_ACFG - 0x80, 0xff);
+		WriteISAC(cs, IPAC_AOE - 0x80, 0x0);
+		WriteISAC(cs, IPAC_MASK - 0x80, 0xff);
+		WriteISAC(cs, IPAC_CONF - 0x80, 0x1);
+		WriteISAC(cs, IPAC_MASK - 0x80, 0xc0);
+		break;
 	}
 	return (0);
 }
@@ -403,28 +403,28 @@ Gazel_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_gazel(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_RELEASE:
-			release_io_gazel(cs);
-			return (0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 1);
-			if ((cs->subtyp==R647)||(cs->subtyp==R685)) {
-				int i;
-				for (i=0;i<(2+MAX_WAITING_CALLS);i++) {
-					cs->bcs[i].hw.hscx.tsaxr0 = 0x1f;
-					cs->bcs[i].hw.hscx.tsaxr1 = 0x23;
-				}
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_gazel(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_gazel(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 1);
+		if ((cs->subtyp == R647) || (cs->subtyp == R685)) {
+			int i;
+			for (i = 0; i < (2 + MAX_WAITING_CALLS); i++) {
+				cs->bcs[i].hw.hscx.tsaxr0 = 0x1f;
+				cs->bcs[i].hw.hscx.tsaxr1 = 0x23;
 			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_TEST:
-			return (0);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
 	return (0);
 }
@@ -435,49 +435,49 @@ reserve_regions(struct IsdnCard *card, struct IsdnCardState *cs)
 	unsigned int i, j, base = 0, adr = 0, len = 0;
 
 	switch (cs->subtyp) {
-		case R647:
-			base = cs->hw.gazel.hscx[0];
-			if (!request_region(adr = (0xC000 + base), len = 1, "gazel"))
-				goto error;
-			for (i = 0x0000; i < 0xC000; i += 0x1000) {
-				if (!request_region(adr = (i + base), len = 16, "gazel"))
-					goto error;
-			}
-			if (i != 0xC000) {
-				for (j = 0; j < i; j+= 0x1000)
-					release_region(j + base, 16);
-				release_region(0xC000 + base, 1);
+	case R647:
+		base = cs->hw.gazel.hscx[0];
+		if (!request_region(adr = (0xC000 + base), len = 1, "gazel"))
+			goto error;
+		for (i = 0x0000; i < 0xC000; i += 0x1000) {
+			if (!request_region(adr = (i + base), len = 16, "gazel"))
 				goto error;
-			}
-			break;
+		}
+		if (i != 0xC000) {
+			for (j = 0; j < i; j += 0x1000)
+				release_region(j + base, 16);
+			release_region(0xC000 + base, 1);
+			goto error;
+		}
+		break;
 
-		case R685:
-			if (!request_region(adr = cs->hw.gazel.hscx[0], len = 0x100, "gazel"))
-				goto error;
-			if (!request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80, "gazel")) {
-				release_region(cs->hw.gazel.hscx[0],0x100);
-				goto error;
-			}
-			break;
+	case R685:
+		if (!request_region(adr = cs->hw.gazel.hscx[0], len = 0x100, "gazel"))
+			goto error;
+		if (!request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80, "gazel")) {
+			release_region(cs->hw.gazel.hscx[0], 0x100);
+			goto error;
+		}
+		break;
 
-		case R753:
-			if (!request_region(adr = cs->hw.gazel.ipac, len = 0x8, "gazel"))
-				goto error;
-			if (!request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80, "gazel")) {
-				release_region(cs->hw.gazel.ipac, 8);
-				goto error;
-			}
-			break;
+	case R753:
+		if (!request_region(adr = cs->hw.gazel.ipac, len = 0x8, "gazel"))
+			goto error;
+		if (!request_region(adr = cs->hw.gazel.cfg_reg, len = 0x80, "gazel")) {
+			release_region(cs->hw.gazel.ipac, 8);
+			goto error;
+		}
+		break;
 
-		case R742:
-			if (!request_region(adr = cs->hw.gazel.ipac, len = 0x8, "gazel"))
-				goto error;
-			break;
+	case R742:
+		if (!request_region(adr = cs->hw.gazel.ipac, len = 0x8, "gazel"))
+			goto error;
+		break;
 	}
 
 	return 0;
 
-      error:
+error:
 	printk(KERN_WARNING "Gazel: io ports 0x%x-0x%x already in use\n",
 	       adr, adr + len);
 	return 1;
@@ -508,24 +508,24 @@ setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
 	cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
 
 	switch (cs->subtyp) {
-		case R647:
-			printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n");
-			cs->dc.isac.adf2 = 0x87;
-			printk(KERN_INFO
-				"Gazel: config irq:%d isac:0x%X  cfg:0x%X\n",
-				cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
-			printk(KERN_INFO
-				"Gazel: hscx A:0x%X  hscx B:0x%X\n",
-				cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
-
-			break;
-		case R742:
-			printk(KERN_INFO "Gazel: Card ISA R742 found\n");
-			test_and_set_bit(HW_IPAC, &cs->HW_Flags);
-			printk(KERN_INFO
-			       "Gazel: config irq:%d ipac:0x%X\n",
-			       cs->irq, cs->hw.gazel.ipac);
-			break;
+	case R647:
+		printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n");
+		cs->dc.isac.adf2 = 0x87;
+		printk(KERN_INFO
+		       "Gazel: config irq:%d isac:0x%X  cfg:0x%X\n",
+		       cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
+		printk(KERN_INFO
+		       "Gazel: hscx A:0x%X  hscx B:0x%X\n",
+		       cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
+
+		break;
+	case R742:
+		printk(KERN_INFO "Gazel: Card ISA R742 found\n");
+		test_and_set_bit(HW_IPAC, &cs->HW_Flags);
+		printk(KERN_INFO
+		       "Gazel: config irq:%d ipac:0x%X\n",
+		       cs->irq, cs->hw.gazel.ipac);
+		break;
 	}
 
 	return (0);
@@ -547,7 +547,7 @@ setup_gazelpci(struct IsdnCardState *cs)
 	seekcard = PCI_DEVICE_ID_PLX_R685;
 	for (nbseek = 0; nbseek < 4; nbseek++) {
 		if ((dev_tel = hisax_find_pci_device(PCI_VENDOR_ID_PLX,
-					seekcard, dev_tel))) {
+						     seekcard, dev_tel))) {
 			if (pci_enable_device(dev_tel))
 				return 1;
 			pci_irq = dev_tel->irq;
@@ -559,15 +559,15 @@ setup_gazelpci(struct IsdnCardState *cs)
 			break;
 		else {
 			switch (seekcard) {
-				case PCI_DEVICE_ID_PLX_R685:
-					seekcard = PCI_DEVICE_ID_PLX_R753;
-					break;
-				case PCI_DEVICE_ID_PLX_R753:
-					seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO;
-					break;
-				case PCI_DEVICE_ID_PLX_DJINN_ITOO:
-					seekcard = PCI_DEVICE_ID_PLX_OLITEC;
-					break;
+			case PCI_DEVICE_ID_PLX_R685:
+				seekcard = PCI_DEVICE_ID_PLX_R753;
+				break;
+			case PCI_DEVICE_ID_PLX_R753:
+				seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO;
+				break;
+			case PCI_DEVICE_ID_PLX_DJINN_ITOO:
+				seekcard = PCI_DEVICE_ID_PLX_OLITEC;
+				break;
 			}
 		}
 	}
@@ -595,27 +595,27 @@ setup_gazelpci(struct IsdnCardState *cs)
 	cs->irq_flags |= IRQF_SHARED;
 
 	switch (seekcard) {
-		case PCI_DEVICE_ID_PLX_R685:
-			printk(KERN_INFO "Gazel: Card PCI R685 found\n");
-			cs->subtyp = R685;
-			cs->dc.isac.adf2 = 0x87;
-			printk(KERN_INFO
-			    "Gazel: config irq:%d isac:0x%X  cfg:0x%X\n",
-			cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
-			printk(KERN_INFO
-			       "Gazel: hscx A:0x%X  hscx B:0x%X\n",
-			     cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
-			break;
-		case PCI_DEVICE_ID_PLX_R753:
-		case PCI_DEVICE_ID_PLX_DJINN_ITOO:
-		case PCI_DEVICE_ID_PLX_OLITEC:
-			printk(KERN_INFO "Gazel: Card PCI R753 found\n");
-			cs->subtyp = R753;
-			test_and_set_bit(HW_IPAC, &cs->HW_Flags);
-			printk(KERN_INFO
-			    "Gazel: config irq:%d ipac:0x%X  cfg:0x%X\n",
-			cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
-			break;
+	case PCI_DEVICE_ID_PLX_R685:
+		printk(KERN_INFO "Gazel: Card PCI R685 found\n");
+		cs->subtyp = R685;
+		cs->dc.isac.adf2 = 0x87;
+		printk(KERN_INFO
+		       "Gazel: config irq:%d isac:0x%X  cfg:0x%X\n",
+		       cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
+		printk(KERN_INFO
+		       "Gazel: hscx A:0x%X  hscx B:0x%X\n",
+		       cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
+		break;
+	case PCI_DEVICE_ID_PLX_R753:
+	case PCI_DEVICE_ID_PLX_DJINN_ITOO:
+	case PCI_DEVICE_ID_PLX_OLITEC:
+		printk(KERN_INFO "Gazel: Card PCI R753 found\n");
+		cs->subtyp = R753;
+		test_and_set_bit(HW_IPAC, &cs->HW_Flags);
+		printk(KERN_INFO
+		       "Gazel: config irq:%d ipac:0x%X  cfg:0x%X\n",
+		       cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
+		break;
 	}
 
 	return (0);
@@ -667,23 +667,23 @@ setup_gazel(struct IsdnCard *card)
 	cs->cardmsg = &Gazel_card_msg;
 
 	switch (cs->subtyp) {
-		case R647:
-		case R685:
-			cs->irq_func = &gazel_interrupt;
-			ISACVersion(cs, "Gazel:");
-			if (HscxVersion(cs, "Gazel:")) {
-				printk(KERN_WARNING
-				       "Gazel: wrong HSCX versions check IO address\n");
-				release_io_gazel(cs);
-				return (0);
-			}
-			break;
-		case R742:
-		case R753:
-			cs->irq_func = &gazel_interrupt_ipac;
-			val = ReadISAC(cs, IPAC_ID - 0x80);
-			printk(KERN_INFO "Gazel: IPAC version %x\n", val);
-			break;
+	case R647:
+	case R685:
+		cs->irq_func = &gazel_interrupt;
+		ISACVersion(cs, "Gazel:");
+		if (HscxVersion(cs, "Gazel:")) {
+			printk(KERN_WARNING
+			       "Gazel: wrong HSCX versions check IO address\n");
+			release_io_gazel(cs);
+			return (0);
+		}
+		break;
+	case R742:
+	case R753:
+		cs->irq_func = &gazel_interrupt_ipac;
+		val = ReadISAC(cs, IPAC_ID - 0x80);
+		printk(KERN_INFO "Gazel: IPAC version %x\n", val);
+		break;
 	}
 
 	return (1);
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 384d511..dea04de 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -93,32 +93,32 @@ static struct pci_device_id hfc4s8s_ids[] = {
 	 .subdevice = 0x08b4,
 	 .driver_data =
 	 (unsigned long) &((hfc4s8s_param) {CHIP_ID_4S, CLOCKMODE_0, 4,
-					    "HFC-4S Evaluation Board"}),
-	 },
+				 "HFC-4S Evaluation Board"}),
+	},
 	{.vendor = PCI_VENDOR_ID_CCD,
 	 .device = PCI_DEVICE_ID_8S,
 	 .subvendor = 0x1397,
 	 .subdevice = 0x16b8,
 	 .driver_data =
 	 (unsigned long) &((hfc4s8s_param) {CHIP_ID_8S, CLOCKMODE_0, 8,
-					    "HFC-8S Evaluation Board"}),
-	 },
+				 "HFC-8S Evaluation Board"}),
+	},
 	{.vendor = PCI_VENDOR_ID_CCD,
 	 .device = PCI_DEVICE_ID_4S,
 	 .subvendor = 0x1397,
 	 .subdevice = 0xb520,
 	 .driver_data =
 	 (unsigned long) &((hfc4s8s_param) {CHIP_ID_4S, CLOCKMODE_1, 4,
-					    "IOB4ST"}),
-	 },
+				 "IOB4ST"}),
+	},
 	{.vendor = PCI_VENDOR_ID_CCD,
 	 .device = PCI_DEVICE_ID_8S,
 	 .subvendor = 0x1397,
 	 .subdevice = 0xb522,
 	 .driver_data =
 	 (unsigned long) &((hfc4s8s_param) {CHIP_ID_8S, CLOCKMODE_1, 8,
-					    "IOB8ST"}),
-	 },
+				 "IOB8ST"}),
+	},
 	{}
 };
 
@@ -203,14 +203,14 @@ typedef struct _hfc4s8s_hw {
 #ifdef HISAX_HFC4S8S_PCIMEM	/* inline functions memory mapped */
 
 /* memory write and dummy IO read to avoid PCI byte merge problems */
-#define Write_hfc8(a,b,c) {(*((volatile u_char *)(a->membase+b)) = c); inb(a->iobase+4);}
+#define Write_hfc8(a, b, c) {(*((volatile u_char *)(a->membase + b)) = c); inb(a->iobase + 4);}
 /* memory write without dummy IO access for fifo data access */
-#define fWrite_hfc8(a,b,c) (*((volatile u_char *)(a->membase+b)) = c)
-#define Read_hfc8(a,b) (*((volatile u_char *)(a->membase+b)))
-#define Write_hfc16(a,b,c) (*((volatile unsigned short *)(a->membase+b)) = c)
-#define Read_hfc16(a,b) (*((volatile unsigned short *)(a->membase+b)))
-#define Write_hfc32(a,b,c) (*((volatile unsigned long *)(a->membase+b)) = c)
-#define Read_hfc32(a,b) (*((volatile unsigned long *)(a->membase+b)))
+#define fWrite_hfc8(a, b, c) (*((volatile u_char *)(a->membase + b)) = c)
+#define Read_hfc8(a, b) (*((volatile u_char *)(a->membase + b)))
+#define Write_hfc16(a, b, c) (*((volatile unsigned short *)(a->membase + b)) = c)
+#define Read_hfc16(a, b) (*((volatile unsigned short *)(a->membase + b)))
+#define Write_hfc32(a, b, c) (*((volatile unsigned long *)(a->membase + b)) = c)
+#define Read_hfc32(a, b) (*((volatile unsigned long *)(a->membase + b)))
 #define wait_busy(a) {while ((Read_hfc8(a, R_STATUS) & M_BUSY));}
 #define PCI_ENA_MEMIO	0x03
 
@@ -218,87 +218,87 @@ typedef struct _hfc4s8s_hw {
 
 /* inline functions io mapped */
 static inline void
-SetRegAddr(hfc4s8s_hw * a, u_char b)
+SetRegAddr(hfc4s8s_hw *a, u_char b)
 {
 	outb(b, (a->iobase) + 4);
 }
 
 static inline u_char
-GetRegAddr(hfc4s8s_hw * a)
+GetRegAddr(hfc4s8s_hw *a)
 {
 	return (inb((volatile u_int) (a->iobase + 4)));
 }
 
 
 static inline void
-Write_hfc8(hfc4s8s_hw * a, u_char b, u_char c)
+Write_hfc8(hfc4s8s_hw *a, u_char b, u_char c)
 {
 	SetRegAddr(a, b);
 	outb(c, a->iobase);
 }
 
 static inline void
-fWrite_hfc8(hfc4s8s_hw * a, u_char c)
+fWrite_hfc8(hfc4s8s_hw *a, u_char c)
 {
 	outb(c, a->iobase);
 }
 
 static inline void
-Write_hfc16(hfc4s8s_hw * a, u_char b, u_short c)
+Write_hfc16(hfc4s8s_hw *a, u_char b, u_short c)
 {
 	SetRegAddr(a, b);
 	outw(c, a->iobase);
 }
 
 static inline void
-Write_hfc32(hfc4s8s_hw * a, u_char b, u_long c)
+Write_hfc32(hfc4s8s_hw *a, u_char b, u_long c)
 {
 	SetRegAddr(a, b);
 	outl(c, a->iobase);
 }
 
 static inline void
-fWrite_hfc32(hfc4s8s_hw * a, u_long c)
+fWrite_hfc32(hfc4s8s_hw *a, u_long c)
 {
 	outl(c, a->iobase);
 }
 
 static inline u_char
-Read_hfc8(hfc4s8s_hw * a, u_char b)
+Read_hfc8(hfc4s8s_hw *a, u_char b)
 {
 	SetRegAddr(a, b);
 	return (inb((volatile u_int) a->iobase));
 }
 
 static inline u_char
-fRead_hfc8(hfc4s8s_hw * a)
+fRead_hfc8(hfc4s8s_hw *a)
 {
 	return (inb((volatile u_int) a->iobase));
 }
 
 
 static inline u_short
-Read_hfc16(hfc4s8s_hw * a, u_char b)
+Read_hfc16(hfc4s8s_hw *a, u_char b)
 {
 	SetRegAddr(a, b);
 	return (inw((volatile u_int) a->iobase));
 }
 
 static inline u_long
-Read_hfc32(hfc4s8s_hw * a, u_char b)
+Read_hfc32(hfc4s8s_hw *a, u_char b)
 {
 	SetRegAddr(a, b);
 	return (inl((volatile u_int) a->iobase));
 }
 
 static inline u_long
-fRead_hfc32(hfc4s8s_hw * a)
+fRead_hfc32(hfc4s8s_hw *a)
 {
 	return (inl((volatile u_int) a->iobase));
 }
 
 static inline void
-wait_busy(hfc4s8s_hw * a)
+wait_busy(hfc4s8s_hw *a)
 {
 	SetRegAddr(a, R_STATUS);
 	while (inb((volatile u_int) a->iobase) & M_BUSY);
@@ -313,7 +313,7 @@ wait_busy(hfc4s8s_hw * a)
 /* may be updated by the chip during read             */
 /******************************************************/
 static u_char
-Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
+Read_hfc8_stable(hfc4s8s_hw *hw, int reg)
 {
 	u_char ref8;
 	u_char in8;
@@ -325,7 +325,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
 }
 
 static int
-Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
+Read_hfc16_stable(hfc4s8s_hw *hw, int reg)
 {
 	int ref16;
 	int in16;
@@ -349,67 +349,67 @@ dch_l2l1(struct hisax_d_if *iface, int pr, void *arg)
 
 	switch (pr) {
 
-		case (PH_DATA | REQUEST):
-			if (!l1->enabled) {
-				dev_kfree_skb(skb);
-				break;
-			}
-			spin_lock_irqsave(&l1->lock, flags);
-			skb_queue_tail(&l1->d_tx_queue, skb);
-			if ((skb_queue_len(&l1->d_tx_queue) == 1) &&
-			    (l1->tx_cnt <= 0)) {
-				l1->hw->mr.r_irq_fifo_blx[l1->st_num] |=
-				    0x10;
-				spin_unlock_irqrestore(&l1->lock, flags);
-				schedule_work(&l1->hw->tqueue);
-			} else
-				spin_unlock_irqrestore(&l1->lock, flags);
+	case (PH_DATA | REQUEST):
+		if (!l1->enabled) {
+			dev_kfree_skb(skb);
 			break;
+		}
+		spin_lock_irqsave(&l1->lock, flags);
+		skb_queue_tail(&l1->d_tx_queue, skb);
+		if ((skb_queue_len(&l1->d_tx_queue) == 1) &&
+		    (l1->tx_cnt <= 0)) {
+			l1->hw->mr.r_irq_fifo_blx[l1->st_num] |=
+				0x10;
+			spin_unlock_irqrestore(&l1->lock, flags);
+			schedule_work(&l1->hw->tqueue);
+		} else
+			spin_unlock_irqrestore(&l1->lock, flags);
+		break;
 
-		case (PH_ACTIVATE | REQUEST):
-			if (!l1->enabled)
-				break;
-			if (!l1->nt_mode) {
-				if (l1->l1_state < 6) {
-					spin_lock_irqsave(&l1->lock,
-							  flags);
-
-					Write_hfc8(l1->hw, R_ST_SEL,
-						   l1->st_num);
-					Write_hfc8(l1->hw, A_ST_WR_STA,
-						   0x60);
-					mod_timer(&l1->l1_timer,
-						  jiffies + L1_TIMER_T3);
-					spin_unlock_irqrestore(&l1->lock,
-							       flags);
-				} else if (l1->l1_state == 7)
-					l1->d_if.ifc.l1l2(&l1->d_if.ifc,
-							  PH_ACTIVATE |
-							  INDICATION,
-							  NULL);
-			} else {
-				if (l1->l1_state != 3) {
-					spin_lock_irqsave(&l1->lock,
-							  flags);
-					Write_hfc8(l1->hw, R_ST_SEL,
-						   l1->st_num);
-					Write_hfc8(l1->hw, A_ST_WR_STA,
-						   0x60);
-					spin_unlock_irqrestore(&l1->lock,
-							       flags);
-				} else if (l1->l1_state == 3)
-					l1->d_if.ifc.l1l2(&l1->d_if.ifc,
-							  PH_ACTIVATE |
-							  INDICATION,
-							  NULL);
-			}
+	case (PH_ACTIVATE | REQUEST):
+		if (!l1->enabled)
 			break;
+		if (!l1->nt_mode) {
+			if (l1->l1_state < 6) {
+				spin_lock_irqsave(&l1->lock,
+						  flags);
+
+				Write_hfc8(l1->hw, R_ST_SEL,
+					   l1->st_num);
+				Write_hfc8(l1->hw, A_ST_WR_STA,
+					   0x60);
+				mod_timer(&l1->l1_timer,
+					  jiffies + L1_TIMER_T3);
+				spin_unlock_irqrestore(&l1->lock,
+						       flags);
+			} else if (l1->l1_state == 7)
+				l1->d_if.ifc.l1l2(&l1->d_if.ifc,
+						  PH_ACTIVATE |
+						  INDICATION,
+						  NULL);
+		} else {
+			if (l1->l1_state != 3) {
+				spin_lock_irqsave(&l1->lock,
+						  flags);
+				Write_hfc8(l1->hw, R_ST_SEL,
+					   l1->st_num);
+				Write_hfc8(l1->hw, A_ST_WR_STA,
+					   0x60);
+				spin_unlock_irqrestore(&l1->lock,
+						       flags);
+			} else if (l1->l1_state == 3)
+				l1->d_if.ifc.l1l2(&l1->d_if.ifc,
+						  PH_ACTIVATE |
+						  INDICATION,
+						  NULL);
+		}
+		break;
 
-		default:
-			printk(KERN_INFO
-			       "HFC-4S/8S: Unknown D-chan cmd 0x%x received, ignored\n",
-			       pr);
-			break;
+	default:
+		printk(KERN_INFO
+		       "HFC-4S/8S: Unknown D-chan cmd 0x%x received, ignored\n",
+		       pr);
+		break;
 	}
 	if (!l1->enabled)
 		l1->d_if.ifc.l1l2(&l1->d_if.ifc,
@@ -430,199 +430,199 @@ bch_l2l1(struct hisax_if *ifc, int pr, void *arg)
 
 	switch (pr) {
 
-		case (PH_DATA | REQUEST):
-			if (!l1->enabled || (bch->mode == L1_MODE_NULL)) {
-				dev_kfree_skb(skb);
-				break;
-			}
-			spin_lock_irqsave(&l1->lock, flags);
-			skb_queue_tail(&bch->tx_queue, skb);
-			if (!bch->tx_skb && (bch->tx_cnt <= 0)) {
-				l1->hw->mr.r_irq_fifo_blx[l1->st_num] |=
-				    ((bch->bchan == 1) ? 1 : 4);
-				spin_unlock_irqrestore(&l1->lock, flags);
-				schedule_work(&l1->hw->tqueue);
-			} else
-				spin_unlock_irqrestore(&l1->lock, flags);
+	case (PH_DATA | REQUEST):
+		if (!l1->enabled || (bch->mode == L1_MODE_NULL)) {
+			dev_kfree_skb(skb);
 			break;
+		}
+		spin_lock_irqsave(&l1->lock, flags);
+		skb_queue_tail(&bch->tx_queue, skb);
+		if (!bch->tx_skb && (bch->tx_cnt <= 0)) {
+			l1->hw->mr.r_irq_fifo_blx[l1->st_num] |=
+				((bch->bchan == 1) ? 1 : 4);
+			spin_unlock_irqrestore(&l1->lock, flags);
+			schedule_work(&l1->hw->tqueue);
+		} else
+			spin_unlock_irqrestore(&l1->lock, flags);
+		break;
 
-		case (PH_ACTIVATE | REQUEST):
-		case (PH_DEACTIVATE | REQUEST):
-			if (!l1->enabled)
-				break;
-			if (pr == (PH_DEACTIVATE | REQUEST))
-				mode = L1_MODE_NULL;
-
-			switch (mode) {
-				case L1_MODE_HDLC:
-					spin_lock_irqsave(&l1->lock,
-							  flags);
-					l1->hw->mr.timer_usg_cnt++;
-					l1->hw->mr.
-					    fifo_slow_timer_service[l1->
-								    st_num]
-					    |=
-					    ((bch->bchan ==
-					      1) ? 0x2 : 0x8);
-					Write_hfc8(l1->hw, R_FIFO,
-						   (l1->st_num * 8 +
-						    ((bch->bchan ==
-						      1) ? 0 : 2)));
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, A_CON_HDLC, 0xc);	/* HDLC mode, flag fill, connect ST */
-					Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
-					Write_hfc8(l1->hw, A_IRQ_MSK, 1);	/* enable TX interrupts for hdlc */
-					Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
-					wait_busy(l1->hw);
-
-					Write_hfc8(l1->hw, R_FIFO,
-						   (l1->st_num * 8 +
-						    ((bch->bchan ==
-						      1) ? 1 : 3)));
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, A_CON_HDLC, 0xc);	/* HDLC mode, flag fill, connect ST */
-					Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
-					Write_hfc8(l1->hw, A_IRQ_MSK, 1);	/* enable RX interrupts for hdlc */
-					Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
-
-					Write_hfc8(l1->hw, R_ST_SEL,
-						   l1->st_num);
-					l1->hw->mr.r_ctrl0 |=
-					    (bch->bchan & 3);
-					Write_hfc8(l1->hw, A_ST_CTRL0,
-						   l1->hw->mr.r_ctrl0);
-					bch->mode = L1_MODE_HDLC;
-					spin_unlock_irqrestore(&l1->lock,
-							       flags);
-
-					bch->b_if.ifc.l1l2(&bch->b_if.ifc,
-							   PH_ACTIVATE |
-							   INDICATION,
-							   NULL);
-					break;
-
-				case L1_MODE_TRANS:
-					spin_lock_irqsave(&l1->lock,
-							  flags);
-					l1->hw->mr.
-					    fifo_rx_trans_enables[l1->
-								  st_num]
-					    |=
-					    ((bch->bchan ==
-					      1) ? 0x2 : 0x8);
-					l1->hw->mr.timer_usg_cnt++;
-					Write_hfc8(l1->hw, R_FIFO,
-						   (l1->st_num * 8 +
-						    ((bch->bchan ==
-						      1) ? 0 : 2)));
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, A_CON_HDLC, 0xf);	/* Transparent mode, 1 fill, connect ST */
-					Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
-					Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable TX interrupts */
-					Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
-					wait_busy(l1->hw);
-
-					Write_hfc8(l1->hw, R_FIFO,
-						   (l1->st_num * 8 +
-						    ((bch->bchan ==
-						      1) ? 1 : 3)));
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, A_CON_HDLC, 0xf);	/* Transparent mode, 1 fill, connect ST */
-					Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
-					Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable RX interrupts */
-					Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
-
-					Write_hfc8(l1->hw, R_ST_SEL,
-						   l1->st_num);
-					l1->hw->mr.r_ctrl0 |=
-					    (bch->bchan & 3);
-					Write_hfc8(l1->hw, A_ST_CTRL0,
-						   l1->hw->mr.r_ctrl0);
-					bch->mode = L1_MODE_TRANS;
-					spin_unlock_irqrestore(&l1->lock,
-							       flags);
-
-					bch->b_if.ifc.l1l2(&bch->b_if.ifc,
-							   PH_ACTIVATE |
-							   INDICATION,
-							   NULL);
-					break;
-
-				default:
-					if (bch->mode == L1_MODE_NULL)
-						break;
-					spin_lock_irqsave(&l1->lock,
-							  flags);
-					l1->hw->mr.
-					    fifo_slow_timer_service[l1->
-								    st_num]
-					    &=
-					    ~((bch->bchan ==
-					       1) ? 0x3 : 0xc);
-					l1->hw->mr.
-					    fifo_rx_trans_enables[l1->
-								  st_num]
-					    &=
-					    ~((bch->bchan ==
-					       1) ? 0x3 : 0xc);
-					l1->hw->mr.timer_usg_cnt--;
-					Write_hfc8(l1->hw, R_FIFO,
-						   (l1->st_num * 8 +
-						    ((bch->bchan ==
-						      1) ? 0 : 2)));
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable TX interrupts */
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, R_FIFO,
-						   (l1->st_num * 8 +
-						    ((bch->bchan ==
-						      1) ? 1 : 3)));
-					wait_busy(l1->hw);
-					Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable RX interrupts */
-					Write_hfc8(l1->hw, R_ST_SEL,
-						   l1->st_num);
-					l1->hw->mr.r_ctrl0 &=
-					    ~(bch->bchan & 3);
-					Write_hfc8(l1->hw, A_ST_CTRL0,
-						   l1->hw->mr.r_ctrl0);
-					spin_unlock_irqrestore(&l1->lock,
-							       flags);
-
-					bch->mode = L1_MODE_NULL;
-					bch->b_if.ifc.l1l2(&bch->b_if.ifc,
-							   PH_DEACTIVATE |
-							   INDICATION,
-							   NULL);
-					if (bch->tx_skb) {
-						dev_kfree_skb(bch->tx_skb);
-						bch->tx_skb = NULL;
-					}
-					if (bch->rx_skb) {
-						dev_kfree_skb(bch->rx_skb);
-						bch->rx_skb = NULL;
-					}
-					skb_queue_purge(&bch->tx_queue);
-					bch->tx_cnt = 0;
-					bch->rx_ptr = NULL;
-					break;
-			}
+	case (PH_ACTIVATE | REQUEST):
+	case (PH_DEACTIVATE | REQUEST):
+		if (!l1->enabled)
+			break;
+		if (pr == (PH_DEACTIVATE | REQUEST))
+			mode = L1_MODE_NULL;
+
+		switch (mode) {
+		case L1_MODE_HDLC:
+			spin_lock_irqsave(&l1->lock,
+					  flags);
+			l1->hw->mr.timer_usg_cnt++;
+			l1->hw->mr.
+				fifo_slow_timer_service[l1->
+							st_num]
+				|=
+				((bch->bchan ==
+				  1) ? 0x2 : 0x8);
+			Write_hfc8(l1->hw, R_FIFO,
+				   (l1->st_num * 8 +
+				    ((bch->bchan ==
+				      1) ? 0 : 2)));
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, A_CON_HDLC, 0xc);	/* HDLC mode, flag fill, connect ST */
+			Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
+			Write_hfc8(l1->hw, A_IRQ_MSK, 1);	/* enable TX interrupts for hdlc */
+			Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
+			wait_busy(l1->hw);
 
-			/* timer is only used when at least one b channel */
-			/* is set up to transparent mode */
-			if (l1->hw->mr.timer_usg_cnt) {
-				Write_hfc8(l1->hw, R_IRQMSK_MISC,
-					   M_TI_IRQMSK);
-			} else {
-				Write_hfc8(l1->hw, R_IRQMSK_MISC, 0);
-			}
+			Write_hfc8(l1->hw, R_FIFO,
+				   (l1->st_num * 8 +
+				    ((bch->bchan ==
+				      1) ? 1 : 3)));
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, A_CON_HDLC, 0xc);	/* HDLC mode, flag fill, connect ST */
+			Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
+			Write_hfc8(l1->hw, A_IRQ_MSK, 1);	/* enable RX interrupts for hdlc */
+			Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
+
+			Write_hfc8(l1->hw, R_ST_SEL,
+				   l1->st_num);
+			l1->hw->mr.r_ctrl0 |=
+				(bch->bchan & 3);
+			Write_hfc8(l1->hw, A_ST_CTRL0,
+				   l1->hw->mr.r_ctrl0);
+			bch->mode = L1_MODE_HDLC;
+			spin_unlock_irqrestore(&l1->lock,
+					       flags);
+
+			bch->b_if.ifc.l1l2(&bch->b_if.ifc,
+					   PH_ACTIVATE |
+					   INDICATION,
+					   NULL);
+			break;
 
+		case L1_MODE_TRANS:
+			spin_lock_irqsave(&l1->lock,
+					  flags);
+			l1->hw->mr.
+				fifo_rx_trans_enables[l1->
+						      st_num]
+				|=
+				((bch->bchan ==
+				  1) ? 0x2 : 0x8);
+			l1->hw->mr.timer_usg_cnt++;
+			Write_hfc8(l1->hw, R_FIFO,
+				   (l1->st_num * 8 +
+				    ((bch->bchan ==
+				      1) ? 0 : 2)));
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, A_CON_HDLC, 0xf);	/* Transparent mode, 1 fill, connect ST */
+			Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
+			Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable TX interrupts */
+			Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
+			wait_busy(l1->hw);
+
+			Write_hfc8(l1->hw, R_FIFO,
+				   (l1->st_num * 8 +
+				    ((bch->bchan ==
+				      1) ? 1 : 3)));
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, A_CON_HDLC, 0xf);	/* Transparent mode, 1 fill, connect ST */
+			Write_hfc8(l1->hw, A_SUBCH_CFG, 0);	/* 8 bits */
+			Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable RX interrupts */
+			Write_hfc8(l1->hw, A_INC_RES_FIFO, 2);	/* reset fifo */
+
+			Write_hfc8(l1->hw, R_ST_SEL,
+				   l1->st_num);
+			l1->hw->mr.r_ctrl0 |=
+				(bch->bchan & 3);
+			Write_hfc8(l1->hw, A_ST_CTRL0,
+				   l1->hw->mr.r_ctrl0);
+			bch->mode = L1_MODE_TRANS;
+			spin_unlock_irqrestore(&l1->lock,
+					       flags);
+
+			bch->b_if.ifc.l1l2(&bch->b_if.ifc,
+					   PH_ACTIVATE |
+					   INDICATION,
+					   NULL);
 			break;
 
 		default:
-			printk(KERN_INFO
-			       "HFC-4S/8S: Unknown B-chan cmd 0x%x received, ignored\n",
-			       pr);
+			if (bch->mode == L1_MODE_NULL)
+				break;
+			spin_lock_irqsave(&l1->lock,
+					  flags);
+			l1->hw->mr.
+				fifo_slow_timer_service[l1->
+							st_num]
+				&=
+				~((bch->bchan ==
+				   1) ? 0x3 : 0xc);
+			l1->hw->mr.
+				fifo_rx_trans_enables[l1->
+						      st_num]
+				&=
+				~((bch->bchan ==
+				   1) ? 0x3 : 0xc);
+			l1->hw->mr.timer_usg_cnt--;
+			Write_hfc8(l1->hw, R_FIFO,
+				   (l1->st_num * 8 +
+				    ((bch->bchan ==
+				      1) ? 0 : 2)));
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable TX interrupts */
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, R_FIFO,
+				   (l1->st_num * 8 +
+				    ((bch->bchan ==
+				      1) ? 1 : 3)));
+			wait_busy(l1->hw);
+			Write_hfc8(l1->hw, A_IRQ_MSK, 0);	/* disable RX interrupts */
+			Write_hfc8(l1->hw, R_ST_SEL,
+				   l1->st_num);
+			l1->hw->mr.r_ctrl0 &=
+				~(bch->bchan & 3);
+			Write_hfc8(l1->hw, A_ST_CTRL0,
+				   l1->hw->mr.r_ctrl0);
+			spin_unlock_irqrestore(&l1->lock,
+					       flags);
+
+			bch->mode = L1_MODE_NULL;
+			bch->b_if.ifc.l1l2(&bch->b_if.ifc,
+					   PH_DEACTIVATE |
+					   INDICATION,
+					   NULL);
+			if (bch->tx_skb) {
+				dev_kfree_skb(bch->tx_skb);
+				bch->tx_skb = NULL;
+			}
+			if (bch->rx_skb) {
+				dev_kfree_skb(bch->rx_skb);
+				bch->rx_skb = NULL;
+			}
+			skb_queue_purge(&bch->tx_queue);
+			bch->tx_cnt = 0;
+			bch->rx_ptr = NULL;
 			break;
+		}
+
+		/* timer is only used when at least one b channel */
+		/* is set up to transparent mode */
+		if (l1->hw->mr.timer_usg_cnt) {
+			Write_hfc8(l1->hw, R_IRQMSK_MISC,
+				   M_TI_IRQMSK);
+		} else {
+			Write_hfc8(l1->hw, R_IRQMSK_MISC, 0);
+		}
+
+		break;
+
+	default:
+		printk(KERN_INFO
+		       "HFC-4S/8S: Unknown B-chan cmd 0x%x received, ignored\n",
+		       pr);
+		break;
 	}
 	if (!l1->enabled)
 		bch->b_if.ifc.l1l2(&bch->b_if.ifc,
@@ -742,7 +742,7 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
 #ifdef HISAX_HFC4S8S_PCIMEM
 					Read_hfc8(l1p->hw, A_FIFO_DATA0);
 #else
-					fRead_hfc8(l1p->hw);
+				fRead_hfc8(l1p->hw);
 #endif
 
 				Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1);
@@ -760,7 +760,7 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
 		while (z1 >= 4) {
 #ifdef HISAX_HFC4S8S_PCIMEM
 			*((unsigned long *) cp) =
-			    Read_hfc32(l1p->hw, A_FIFO_DATA0);
+				Read_hfc32(l1p->hw, A_FIFO_DATA0);
 #else
 			*((unsigned long *) cp) = fRead_hfc32(l1p->hw);
 #endif
@@ -772,7 +772,7 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
 #ifdef HISAX_HFC4S8S_PCIMEM
 			*cp++ = Read_hfc8(l1p->hw, A_FIFO_DATA0);
 #else
-			*cp++ = fRead_hfc8(l1p->hw);
+		*cp++ = fRead_hfc8(l1p->hw);
 #endif
 
 		Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1);	/* increment f counter */
@@ -866,10 +866,10 @@ rx_b_frame(struct hfc4s8s_btype *bch)
 		while (z1 >= 4) {
 #ifdef HISAX_HFC4S8S_PCIMEM
 			*((unsigned long *) bch->rx_ptr) =
-			    Read_hfc32(l1->hw, A_FIFO_DATA0);
+				Read_hfc32(l1->hw, A_FIFO_DATA0);
 #else
 			*((unsigned long *) bch->rx_ptr) =
-			    fRead_hfc32(l1->hw);
+				fRead_hfc32(l1->hw);
 #endif
 			bch->rx_ptr += 4;
 			z1 -= 4;
@@ -879,7 +879,7 @@ rx_b_frame(struct hfc4s8s_btype *bch)
 #ifdef HISAX_HFC4S8S_PCIMEM
 			*(bch->rx_ptr++) = Read_hfc8(l1->hw, A_FIFO_DATA0);
 #else
-			*(bch->rx_ptr++) = fRead_hfc8(l1->hw);
+		*(bch->rx_ptr++) = fRead_hfc8(l1->hw);
 #endif
 
 		if (hdlc_complete) {
@@ -996,7 +996,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
 		if (bch->mode == L1_MODE_HDLC) {
 			hdlc_num = Read_hfc8(l1->hw, A_F1) & MAX_F_CNT;
 			hdlc_num -=
-			    (Read_hfc8_stable(l1->hw, A_F2) & MAX_F_CNT);
+				(Read_hfc8_stable(l1->hw, A_F2) & MAX_F_CNT);
 			if (hdlc_num < 0)
 				hdlc_num += 16;
 			if (hdlc_num >= 15)
@@ -1008,7 +1008,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
 			if (!(skb = skb_dequeue(&bch->tx_queue))) {
 				l1->hw->mr.fifo_slow_timer_service[l1->
 								   st_num]
-				    &= ~((bch->bchan == 1) ? 1 : 4);
+					&= ~((bch->bchan == 1) ? 1 : 4);
 				break;	/* list empty */
 			}
 			bch->tx_skb = skb;
@@ -1017,10 +1017,10 @@ tx_b_frame(struct hfc4s8s_btype *bch)
 
 		if (!hdlc_num)
 			l1->hw->mr.fifo_slow_timer_service[l1->st_num] |=
-			    ((bch->bchan == 1) ? 1 : 4);
+				((bch->bchan == 1) ? 1 : 4);
 		else
 			l1->hw->mr.fifo_slow_timer_service[l1->st_num] &=
-			    ~((bch->bchan == 1) ? 1 : 4);
+				~((bch->bchan == 1) ? 1 : 4);
 
 		max = Read_hfc16_stable(l1->hw, A_Z2);
 		max -= Read_hfc16(l1->hw, A_Z1);
@@ -1055,7 +1055,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
 #ifdef HISAX_HFC4S8S_PCIMEM
 			fWrite_hfc8(l1->hw, A_FIFO_DATA0, *cp++);
 #else
-			fWrite_hfc8(l1->hw, *cp++);
+		fWrite_hfc8(l1->hw, *cp++);
 #endif
 
 		if (bch->tx_cnt >= skb->len) {
@@ -1106,8 +1106,8 @@ hfc4s8s_bh(struct work_struct *work)
 					Write_hfc8(l1p->hw, R_ST_SEL,
 						   l1p->st_num);
 					l1p->l1_state =
-					    Read_hfc8(l1p->hw,
-						      A_ST_RD_STA) & 0xf;
+						Read_hfc8(l1p->hw,
+							  A_ST_RD_STA) & 0xf;
 
 					if ((oldstate == 3)
 					    && (l1p->l1_state != 3))
@@ -1123,12 +1123,12 @@ hfc4s8s_bh(struct work_struct *work)
 						del_timer(&l1p->l1_timer);
 						if (l1p->l1_state == 3) {
 							l1p->d_if.ifc.
-							    l1l2(&l1p->
-								 d_if.ifc,
-								 PH_ACTIVATE
-								 |
-								 INDICATION,
-								 NULL);
+								l1l2(&l1p->
+								     d_if.ifc,
+								     PH_ACTIVATE
+								     |
+								     INDICATION,
+								     NULL);
 						}
 					} else {
 						/* allow transition */
@@ -1148,8 +1148,8 @@ hfc4s8s_bh(struct work_struct *work)
 					Write_hfc8(l1p->hw, R_ST_SEL,
 						   l1p->st_num);
 					l1p->l1_state =
-					    Read_hfc8(l1p->hw,
-						      A_ST_RD_STA) & 0xf;
+						Read_hfc8(l1p->hw,
+							  A_ST_RD_STA) & 0xf;
 
 					if (((l1p->l1_state == 3) &&
 					     ((oldstate == 7) ||
@@ -1165,26 +1165,26 @@ hfc4s8s_bh(struct work_struct *work)
 							del_timer(&l1p->
 								  l1_timer);
 							l1p->d_if.ifc.
-							    l1l2(&l1p->
-								 d_if.ifc,
-								 PH_ACTIVATE
-								 |
-								 INDICATION,
-								 NULL);
+								l1l2(&l1p->
+								     d_if.ifc,
+								     PH_ACTIVATE
+								     |
+								     INDICATION,
+								     NULL);
 							tx_d_frame(l1p);
 						}
 						if (l1p->l1_state == 3) {
 							if (oldstate != 3)
 								l1p->d_if.
-								    ifc.
-								    l1l2
-								    (&l1p->
-								     d_if.
-								     ifc,
-								     PH_DEACTIVATE
-								     |
-								     INDICATION,
-								     NULL);
+									ifc.
+									l1l2
+									(&l1p->
+									 d_if.
+									 ifc,
+									 PH_DEACTIVATE
+									 |
+									 INDICATION,
+									 NULL);
 						}
 					}
 					printk(KERN_INFO
@@ -1209,8 +1209,8 @@ hfc4s8s_bh(struct work_struct *work)
 			*fifo_stat |= hw->mr.fifo_rx_trans_enables[idx];
 			if (hw->fifo_sched_cnt <= 0) {
 				*fifo_stat |=
-				    hw->mr.fifo_slow_timer_service[l1p->
-								   st_num];
+					hw->mr.fifo_slow_timer_service[l1p->
+								       st_num];
 			}
 		}
 		/* ignore fifo 6 (TX E fifo) */
@@ -1288,10 +1288,10 @@ hfc4s8s_interrupt(int intno, void *dev_id)
 
 	/* Layer 1 State change */
 	hw->mr.r_irq_statech |=
-	    (Read_hfc8(hw, R_SCI) & hw->mr.r_irqmsk_statchg);
+		(Read_hfc8(hw, R_SCI) & hw->mr.r_irqmsk_statchg);
 	if (!
 	    (b = (Read_hfc8(hw, R_STATUS) & (M_MISC_IRQSTA | M_FR_IRQSTA)))
-&& !hw->mr.r_irq_statech) {
+	    && !hw->mr.r_irq_statech) {
 #ifndef	HISAX_HFC4S8S_PCIMEM
 		SetRegAddr(hw, old_ioreg);
 #endif
@@ -1332,7 +1332,7 @@ hfc4s8s_interrupt(int intno, void *dev_id)
 /* reset the complete chip, don't release the chips irq but disable it */
 /***********************************************************************/
 static void
-chipreset(hfc4s8s_hw * hw)
+chipreset(hfc4s8s_hw *hw)
 {
 	u_long flags;
 
@@ -1361,7 +1361,7 @@ chipreset(hfc4s8s_hw * hw)
 /* disable/enable hardware in nt or te mode */
 /********************************************/
 static void
-hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
+hfc_hardware_enable(hfc4s8s_hw *hw, int enable, int nt_mode)
 {
 	u_long flags;
 	char if_name[40];
@@ -1468,7 +1468,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
 /* disable memory mapped ports / io ports */
 /******************************************/
 static void
-release_pci_ports(hfc4s8s_hw * hw)
+release_pci_ports(hfc4s8s_hw *hw)
 {
 	pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
 #ifdef HISAX_HFC4S8S_PCIMEM
@@ -1484,7 +1484,7 @@ release_pci_ports(hfc4s8s_hw * hw)
 /* enable memory mapped ports / io ports */
 /*****************************************/
 static void
-enable_pci_ports(hfc4s8s_hw * hw)
+enable_pci_ports(hfc4s8s_hw *hw)
 {
 #ifdef HISAX_HFC4S8S_PCIMEM
 	pci_write_config_word(hw->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
@@ -1498,7 +1498,7 @@ enable_pci_ports(hfc4s8s_hw * hw)
 /* return 0 on success.              */
 /*************************************/
 static int __devinit
-setup_instance(hfc4s8s_hw * hw)
+setup_instance(hfc4s8s_hw *hw)
 {
 	int err = -EIO;
 	int i;
@@ -1575,7 +1575,7 @@ setup_instance(hfc4s8s_hw * hw)
 
 	return (0);
 
-      out:
+out:
 	hw->irq = 0;
 	release_pci_ports(hw);
 	kfree(hw);
@@ -1632,7 +1632,7 @@ hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		card_cnt++;
 	return (err);
 
-      out:
+out:
 	kfree(hw);
 	return (err);
 }
@@ -1660,10 +1660,10 @@ hfc4s8s_remove(struct pci_dev *pdev)
 }
 
 static struct pci_driver hfc4s8s_driver = {
-      .name	= "hfc4s8s_l1",
-      .probe	= hfc4s8s_probe,
-      .remove	= __devexit_p(hfc4s8s_remove),
-      .id_table	= hfc4s8s_ids,
+	.name	= "hfc4s8s_l1",
+	.probe	= hfc4s8s_probe,
+	.remove	= __devexit_p(hfc4s8s_remove),
+	.id_table	= hfc4s8s_ids,
 };
 
 /**********************/
@@ -1697,7 +1697,7 @@ hfc4s8s_module_init(void)
 #endif
 
 	return 0;
-      out:
+out:
 	return (err);
 }				/* hfc4s8s_init_hw */
 
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.h b/drivers/isdn/hisax/hfc4s8s_l1.h
index 9d5d2a5..6a8f891 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.h
+++ b/drivers/isdn/hisax/hfc4s8s_l1.h
@@ -15,10 +15,10 @@
 
 
 /*
-*  include Genero generated HFC-4S/8S header file hfc48scu.h
-*  for complete register description. This will define _HFC48SCU_H_
-*  to prevent redefinitions
-*/
+ *  include Genero generated HFC-4S/8S header file hfc48scu.h
+ *  for complete register description. This will define _HFC48SCU_H_
+ *  to prevent redefinitions
+ */
 
 // #include "hfc48scu.h"
 
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index a16459a..a756e5c 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -18,15 +18,15 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 /*
-#define KDEBUG_DEF
-#include "kdebug.h"
+  #define KDEBUG_DEF
+  #include "kdebug.h"
 */
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static void
-dummyf(struct IsdnCardState *cs, u_char * data, int size)
+dummyf(struct IsdnCardState *cs, u_char *data, int size)
 {
 	printk(KERN_WARNING "HiSax: hfcd dummy fifo called\n");
 }
@@ -37,7 +37,7 @@ ReadReg(struct IsdnCardState *cs, int data, u_char reg)
 	register u_char ret;
 
 	if (data) {
-		if (cs->hw.hfcD.cip != reg) { 
+		if (cs->hw.hfcD.cip != reg) {
 			cs->hw.hfcD.cip = reg;
 			byteout(cs->hw.hfcD.addr | 1, reg);
 		}
@@ -54,7 +54,7 @@ ReadReg(struct IsdnCardState *cs, int data, u_char reg)
 static inline void
 WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value)
 {
-	if (cs->hw.hfcD.cip != reg) { 
+	if (cs->hw.hfcD.cip != reg) {
 		cs->hw.hfcD.cip = reg;
 		byteout(cs->hw.hfcD.addr | 1, reg);
 	}
@@ -71,7 +71,7 @@ WriteReg(struct IsdnCardState *cs, int data, u_char reg, u_char value)
 static u_char
 readreghfcd(struct IsdnCardState *cs, u_char offset)
 {
-	return(ReadReg(cs, HFCD_DATA, offset));
+	return (ReadReg(cs, HFCD_DATA, offset));
 }
 
 static void
@@ -103,7 +103,7 @@ WaitNoBusy(struct IsdnCardState *cs)
 		udelay(1);
 		to--;
 	}
-	if (!to) 
+	if (!to)
 		printk(KERN_WARNING "HiSax: WaitNoBusy timeout\n");
 	return (to);
 }
@@ -114,29 +114,29 @@ SelFiFo(struct IsdnCardState *cs, u_char FiFo)
 	u_char cip;
 
 	if (cs->hw.hfcD.fifo == FiFo)
-		return(1);
-	switch(FiFo) {
-		case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1;
-			break;
-		case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1;
-			break;
-		case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2;
-			break;
-		case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2;
-			break;
-		case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND;
-			break;
-		case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC;
-			break;
-		default:
-			debugl1(cs, "SelFiFo Error");
-			return(0);
+		return (1);
+	switch (FiFo) {
+	case 0: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B1;
+		break;
+	case 1: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B1;
+		break;
+	case 2: cip = HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_B2;
+		break;
+	case 3: cip = HFCB_FIFO | HFCB_Z1 | HFCB_REC | HFCB_B2;
+		break;
+	case 4: cip = HFCD_FIFO | HFCD_Z1 | HFCD_SEND;
+		break;
+	case 5: cip = HFCD_FIFO | HFCD_Z1 | HFCD_REC;
+		break;
+	default:
+		debugl1(cs, "SelFiFo Error");
+		return (0);
 	}
 	cs->hw.hfcD.fifo = FiFo;
 	WaitNoBusy(cs);
 	cs->BC_Write_Reg(cs, HFCD_DATA, cip, 0);
 	WaitForBusy(cs);
-	return(2);
+	return (2);
 }
 
 static int
@@ -188,7 +188,7 @@ static struct sk_buff
 	int idx;
 	int chksum;
 	u_char stat, cip;
-	
+
 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
 		debugl1(cs, "hfc_empty_fifo");
 	idx = 0;
@@ -252,7 +252,7 @@ static struct sk_buff
 	WaitForBusy(cs);
 	WaitNoBusy(cs);
 	stat = ReadReg(cs, HFCD_DATA, HFCB_FIFO | HFCB_F2_INC |
-		HFCB_REC | HFCB_CHANNEL(bcs->channel));
+		       HFCB_REC | HFCB_CHANNEL(bcs->channel));
 	WaitForBusy(cs);
 	return (skb);
 }
@@ -269,7 +269,7 @@ hfc_fill_fifo(struct BCState *bcs)
 		return;
 	if (bcs->tx_skb->len <= 0)
 		return;
-	SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel)); 
+	SelFiFo(cs, HFCB_SEND | HFCB_CHANNEL(bcs->channel));
 	cip = HFCB_FIFO | HFCB_F1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel);
 	WaitNoBusy(cs);
 	bcs->hw.hfc.f1 = ReadReg(cs, HFCD_DATA, cip);
@@ -278,7 +278,7 @@ hfc_fill_fifo(struct BCState *bcs)
 	WaitNoBusy(cs);
 	bcs->hw.hfc.f2 = ReadReg(cs, HFCD_DATA, cip);
 	bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(cs, HFCB_FIFO | HFCB_Z1 | HFCB_SEND | HFCB_CHANNEL(bcs->channel));
- 	if (cs->debug & L1_DEB_HSCX)
+	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
 			bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
 			bcs->hw.hfc.send[bcs->hw.hfc.f1]);
@@ -316,8 +316,8 @@ hfc_fill_fifo(struct BCState *bcs)
 		printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
 	} else {
 		bcs->tx_cnt -= bcs->tx_skb->len;
-		if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-			(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+		if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+		    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 			u_long	flags;
 			spin_lock_irqsave(&bcs->aclock, flags);
 			bcs->ackcnt += bcs->tx_skb->len;
@@ -339,12 +339,12 @@ static void
 hfc_send_data(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
-	
+
 	if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 		hfc_fill_fifo(bcs);
 		test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 	} else
-		debugl1(cs,"send_data %d blocked", bcs->channel);
+		debugl1(cs, "send_data %d blocked", bcs->channel);
 }
 
 static void
@@ -356,10 +356,10 @@ main_rec_2bds0(struct BCState *bcs)
 	int receive, count = 5;
 	struct sk_buff *skb;
 
-    Begin:
+Begin:
 	count--;
 	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
-		debugl1(cs,"rec_data %d blocked", bcs->channel);
+		debugl1(cs, "rec_data %d blocked", bcs->channel);
 		return;
 	}
 	SelFiFo(cs, HFCB_REC | HFCB_CHANNEL(bcs->channel));
@@ -386,10 +386,10 @@ main_rec_2bds0(struct BCState *bcs)
 			skb_queue_tail(&bcs->rqueue, skb);
 			schedule_event(bcs, B_RCVBUFREADY);
 		}
-		rcnt = f1 -f2;
-		if (rcnt<0)
+		rcnt = f1 - f2;
+		if (rcnt < 0)
 			rcnt += 32;
-		if (rcnt>1)
+		if (rcnt > 1)
 			receive = 1;
 		else
 			receive = 0;
@@ -397,7 +397,7 @@ main_rec_2bds0(struct BCState *bcs)
 		receive = 0;
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 	if (count && receive)
-		goto Begin;	
+		goto Begin;
 	return;
 }
 
@@ -412,37 +412,37 @@ mode_2bs0(struct BCState *bcs, int mode, int bc)
 	bcs->mode = mode;
 	bcs->channel = bc;
 	switch (mode) {
-		case (L1_MODE_NULL):
-			if (bc) {
-				cs->hw.hfcD.conn |= 0x18;
-				cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcD.conn |= 0x3;
-				cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA;
-			}
-			break;
-		case (L1_MODE_TRANS):
-			if (bc) {
-				cs->hw.hfcD.ctmt |= 2;
-				cs->hw.hfcD.conn &= ~0x18;
-				cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcD.ctmt |= 1;
-				cs->hw.hfcD.conn &= ~0x3;
-				cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
-			}
-			break;
-		case (L1_MODE_HDLC):
-			if (bc) {
-				cs->hw.hfcD.ctmt &= ~2;
-				cs->hw.hfcD.conn &= ~0x18;
-				cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcD.ctmt &= ~1;
-				cs->hw.hfcD.conn &= ~0x3;
-				cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
-			}
-			break;
+	case (L1_MODE_NULL):
+		if (bc) {
+			cs->hw.hfcD.conn |= 0x18;
+			cs->hw.hfcD.sctrl &= ~SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcD.conn |= 0x3;
+			cs->hw.hfcD.sctrl &= ~SCTRL_B1_ENA;
+		}
+		break;
+	case (L1_MODE_TRANS):
+		if (bc) {
+			cs->hw.hfcD.ctmt |= 2;
+			cs->hw.hfcD.conn &= ~0x18;
+			cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcD.ctmt |= 1;
+			cs->hw.hfcD.conn &= ~0x3;
+			cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
+		}
+		break;
+	case (L1_MODE_HDLC):
+		if (bc) {
+			cs->hw.hfcD.ctmt &= ~2;
+			cs->hw.hfcD.conn &= ~0x18;
+			cs->hw.hfcD.sctrl |= SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcD.ctmt &= ~1;
+			cs->hw.hfcD.conn &= ~0x3;
+			cs->hw.hfcD.sctrl |= SCTRL_B1_ENA;
+		}
+		break;
 	}
 	WriteReg(cs, HFCD_DATA, HFCD_SCTRL, cs->hw.hfcD.sctrl);
 	WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
@@ -457,53 +457,53 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
 //				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
-			} else {
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
+		} else {
 //				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->tx_skb = skb;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			mode_2bs0(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			mode_2bs0(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+			bcs->tx_skb = skb;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		mode_2bs0(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		mode_2bs0(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -558,23 +558,23 @@ hfcd_bh(struct work_struct *work)
 
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		switch (cs->dc.hfcd.ph_state) {
-			case (0):
-				l1_msg(cs, HW_RESET | INDICATION, NULL);
-				break;
-			case (3):
-				l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-				break;
-			case (8):
-				l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-				break;
-			case (6):
-				l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-				break;
-			case (7):
-				l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-				break;
-			default:
-				break;
+		case (0):
+			l1_msg(cs, HW_RESET | INDICATION, NULL);
+			break;
+		case (3):
+			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+			break;
+		case (8):
+			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+			break;
+		case (6):
+			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+			break;
+		case (7):
+			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+			break;
+		default:
+			break;
 		}
 	}
 	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
@@ -591,12 +591,12 @@ int receive_dmsg(struct IsdnCardState *cs)
 	int rcnt, z1, z2;
 	u_char stat, cip, f1, f2;
 	int chksum;
-	int count=5;
+	int count = 5;
 	u_char *ptr;
 
 	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 		debugl1(cs, "rec_dmsg blocked");
-		return(1);
+		return (1);
 	}
 	SelFiFo(cs, 4 | HFCD_REC);
 	cip = HFCD_FIFO | HFCD_F1 | HFCD_REC;
@@ -682,8 +682,8 @@ int receive_dmsg(struct IsdnCardState *cs)
 		f2 = cs->readisac(cs, cip) & 0xf;
 	}
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
-	return(1);
-} 
+	return (1);
+}
 
 static void
 hfc_fill_dfifo(struct IsdnCardState *cs)
@@ -750,23 +750,23 @@ hfc_fill_dfifo(struct IsdnCardState *cs)
 	return;
 }
 
-static 
+static
 struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
 {
 	if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
-		return(&cs->bcs[0]);
+		return (&cs->bcs[0]);
 	else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
-		return(&cs->bcs[1]);
+		return (&cs->bcs[1]);
 	else
-		return(NULL);
+		return (NULL);
 }
 
 void
 hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 {
-       	u_char exval;
-       	struct BCState *bcs;
-	int count=15;
+	u_char exval;
+	struct BCState *bcs;
+	int count = 15;
 
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "HFCD irq %x %s", val,
@@ -789,25 +789,25 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 		}
 		if (cs->hw.hfcD.int_s1 & 0x18) {
 			exval = val;
-			val =  cs->hw.hfcD.int_s1;
+			val = cs->hw.hfcD.int_s1;
 			cs->hw.hfcD.int_s1 = exval;
-		}	
+		}
 		if (val & 0x08) {
-			if (!(bcs=Sel_BCS(cs, 0))) {
+			if (!(bcs = Sel_BCS(cs, 0))) {
 				if (cs->debug)
 					debugl1(cs, "hfcd spurious 0x08 IRQ");
-			} else 
+			} else
 				main_rec_2bds0(bcs);
 		}
 		if (val & 0x10) {
-			if (!(bcs=Sel_BCS(cs, 1))) {
+			if (!(bcs = Sel_BCS(cs, 1))) {
 				if (cs->debug)
 					debugl1(cs, "hfcd spurious 0x10 IRQ");
-			} else 
+			} else
 				main_rec_2bds0(bcs);
 		}
 		if (val & 0x01) {
-			if (!(bcs=Sel_BCS(cs, 0))) {
+			if (!(bcs = Sel_BCS(cs, 0))) {
 				if (cs->debug)
 					debugl1(cs, "hfcd spurious 0x01 IRQ");
 			} else {
@@ -816,14 +816,14 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 						hfc_fill_fifo(bcs);
 						test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 					} else
-						debugl1(cs,"fill_data %d blocked", bcs->channel);
+						debugl1(cs, "fill_data %d blocked", bcs->channel);
 				} else {
 					if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 						if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 							hfc_fill_fifo(bcs);
 							test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 						} else
-							debugl1(cs,"fill_data %d blocked", bcs->channel);
+							debugl1(cs, "fill_data %d blocked", bcs->channel);
 					} else {
 						schedule_event(bcs, B_XMTBUFREADY);
 					}
@@ -831,7 +831,7 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 			}
 		}
 		if (val & 0x02) {
-			if (!(bcs=Sel_BCS(cs, 1))) {
+			if (!(bcs = Sel_BCS(cs, 1))) {
 				if (cs->debug)
 					debugl1(cs, "hfcd spurious 0x02 IRQ");
 			} else {
@@ -840,14 +840,14 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 						hfc_fill_fifo(bcs);
 						test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 					} else
-						debugl1(cs,"fill_data %d blocked", bcs->channel);
+						debugl1(cs, "fill_data %d blocked", bcs->channel);
 				} else {
 					if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 						if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 							hfc_fill_fifo(bcs);
 							test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 						} else
-							debugl1(cs,"fill_data %d blocked", bcs->channel);
+							debugl1(cs, "fill_data %d blocked", bcs->channel);
 					} else {
 						schedule_event(bcs, B_XMTBUFREADY);
 					}
@@ -888,7 +888,7 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
 			} else
 				schedule_event(cs, D_XMTBUFREADY);
 		}
-      afterXPR:
+	afterXPR:
 		if (cs->hw.hfcD.int_s1 && count--) {
 			val = cs->hw.hfcD.int_s1;
 			cs->hw.hfcD.int_s1 = 0;
@@ -905,105 +905,105 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg)
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 	struct sk_buff *skb = arg;
 	u_long flags;
-	
+
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
-#ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-				if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
-					hfc_fill_dfifo(cs);
-					test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
-				} else
-					debugl1(cs, "hfc_fill_dfifo blocked");
-
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
 			if (cs->debug & L1_DEB_LAPD)
-				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+				Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
 			if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 				hfc_fill_dfifo(cs);
 				test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 			} else
 				debugl1(cs, "hfc_fill_dfifo blocked");
+
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			break;
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD)
+			Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */
-			udelay(6);
-			cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */
-			cs->hw.hfcD.mst_m |= HFCD_MASTER;
-			cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
-			cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-		case (HW_ENABLE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_DEACTIVATE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcD.mst_m &= ~HFCD_MASTER;
-			cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO3 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcD.mst_m |= HFCD_MASTER;
-			cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		default:
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
-			break;
+		if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
+			hfc_fill_dfifo(cs);
+			test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
+		} else
+			debugl1(cs, "hfc_fill_dfifo blocked");
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG		/* psa */
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->writeisac(cs, HFCD_STATES, HFCD_LOAD_STATE | 3); /* HFC ST 3 */
+		udelay(6);
+		cs->writeisac(cs, HFCD_STATES, 3); /* HFC ST 2 */
+		cs->hw.hfcD.mst_m |= HFCD_MASTER;
+		cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
+		cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		break;
+	case (HW_ENABLE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->writeisac(cs, HFCD_STATES, HFCD_ACTIVATE | HFCD_DO_ACTION);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_DEACTIVATE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcD.mst_m &= ~HFCD_MASTER;
+		cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO3 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcD.mst_m |= HFCD_MASTER;
+		cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
+		break;
 	}
 }
 
@@ -1027,11 +1027,11 @@ static unsigned int
 	if (!(send = kmalloc(cnt * sizeof(unsigned int), GFP_ATOMIC))) {
 		printk(KERN_WARNING
 		       "HiSax: No memory for hfcd.send\n");
-		return(NULL);
+		return (NULL);
 	}
 	for (i = 0; i < cnt; i++)
 		send[i] = 0x1fff;
-	return(send);
+	return (send);
 }
 
 void
diff --git a/drivers/isdn/hisax/hfc_2bds0.h b/drivers/isdn/hisax/hfc_2bds0.h
index 30f1924..8c7582a 100644
--- a/drivers/isdn/hisax/hfc_2bds0.h
+++ b/drivers/isdn/hisax/hfc_2bds0.h
@@ -4,26 +4,26 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-#define HFCD_CIRM  	0x18
+#define HFCD_CIRM	0x18
 #define HFCD_CTMT	0x19
-#define HFCD_INT_M1  	0x1A
-#define HFCD_INT_M2  	0x1B
-#define HFCD_INT_S1  	0x1E
-#define HFCD_STAT  	0x1C
-#define HFCD_STAT_DISB  0x1D
-#define HFCD_STATES  	0x30
-#define HFCD_SCTRL  	0x31
-#define HFCD_TEST  	0x32
-#define HFCD_SQ  	0x34
-#define HFCD_CLKDEL  	0x37
+#define HFCD_INT_M1	0x1A
+#define HFCD_INT_M2	0x1B
+#define HFCD_INT_S1	0x1E
+#define HFCD_STAT	0x1C
+#define HFCD_STAT_DISB	0x1D
+#define HFCD_STATES	0x30
+#define HFCD_SCTRL	0x31
+#define HFCD_TEST	0x32
+#define HFCD_SQ		0x34
+#define HFCD_CLKDEL	0x37
 #define HFCD_MST_MODE	0x2E
-#define HFCD_CONN  	0x2F
+#define HFCD_CONN	0x2F
 
 #define HFCD_FIFO	0x80
 #define HFCD_Z1		0x10
@@ -79,7 +79,7 @@
 #define HFCD_TRANSB1 0x01
 
 /* CIRM (Write) */
-#define HFCD_RESET  	0x08
+#define HFCD_RESET	0x08
 #define HFCD_MEM8K	0x10
 #define HFCD_INTA	0x01
 #define HFCD_INTB	0x02
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index 626f85d..838531b 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -181,9 +181,9 @@ hfc_empty_fifo(struct BCState *bcs, int count)
 		return (NULL);
 	}
 	if (bcs->mode == L1_MODE_TRANS)
-	  count -= 1;
+		count -= 1;
 	else
-	  count -= 3;
+		count -= 3;
 	if (!(skb = dev_alloc_skb(count)))
 		printk(KERN_WARNING "HFC: receive out of memory\n");
 	else {
@@ -199,35 +199,35 @@ hfc_empty_fifo(struct BCState *bcs, int count)
 			printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel);
 			dev_kfree_skb_any(skb);
 			if (bcs->mode != L1_MODE_TRANS) {
-			  WaitNoBusy(cs);
-			  stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
-						 HFC_CHANNEL(bcs->channel));
-			  WaitForBusy(cs);
+				WaitNoBusy(cs);
+				stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
+						       HFC_CHANNEL(bcs->channel));
+				WaitForBusy(cs);
 			}
 			return (NULL);
 		}
 		if (bcs->mode != L1_MODE_TRANS) {
-		  WaitNoBusy(cs);
-		  chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8);
-		  WaitNoBusy(cs);
-		  chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip);
-		  WaitNoBusy(cs);
-		  stat = cs->BC_Read_Reg(cs, HFC_DATA, cip);
-		  if (cs->debug & L1_DEB_HSCX)
-		    debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
-			    bcs->channel, chksum, stat);
-		  if (stat) {
-		    debugl1(cs, "FIFO CRC error");
-		    dev_kfree_skb_any(skb);
-		    skb = NULL;
+			WaitNoBusy(cs);
+			chksum = (cs->BC_Read_Reg(cs, HFC_DATA, cip) << 8);
+			WaitNoBusy(cs);
+			chksum += cs->BC_Read_Reg(cs, HFC_DATA, cip);
+			WaitNoBusy(cs);
+			stat = cs->BC_Read_Reg(cs, HFC_DATA, cip);
+			if (cs->debug & L1_DEB_HSCX)
+				debugl1(cs, "hfc_empty_fifo %d chksum %x stat %x",
+					bcs->channel, chksum, stat);
+			if (stat) {
+				debugl1(cs, "FIFO CRC error");
+				dev_kfree_skb_any(skb);
+				skb = NULL;
 #ifdef ERROR_STATISTIC
-		    bcs->err_crc++;
+				bcs->err_crc++;
 #endif
-		  }
-		  WaitNoBusy(cs);
-		  stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
-					 HFC_CHANNEL(bcs->channel));
-		  WaitForBusy(cs);
+			}
+			WaitNoBusy(cs);
+			stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC |
+					       HFC_CHANNEL(bcs->channel));
+			WaitForBusy(cs);
 		}
 	}
 	return (skb);
@@ -249,37 +249,37 @@ hfc_fill_fifo(struct BCState *bcs)
 
 	cip = HFC_CIP | HFC_F1 | HFC_SEND | HFC_CHANNEL(bcs->channel);
 	if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
-	  cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
-	  WaitForBusy(cs);
+		cs->BC_Write_Reg(cs, HFC_STATUS, cip, cip);
+		WaitForBusy(cs);
 	}
 	WaitNoBusy(cs);
 	if (bcs->mode != L1_MODE_TRANS) {
-	  bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
-	  cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel);
-	  WaitNoBusy(cs);
-	  bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
-	  bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel));
-	  if (cs->debug & L1_DEB_HSCX)
-	    debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
-		    bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
-		    bcs->hw.hfc.send[bcs->hw.hfc.f1]);
-	  fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
-	  if (fcnt < 0)
-	    fcnt += 32;
-	  if (fcnt > 30) {
-	    if (cs->debug & L1_DEB_HSCX)
-	      debugl1(cs, "hfc_fill_fifo more as 30 frames");
-	    return;
-	  }
-	  count = GetFreeFifoBytes(bcs);
-	} 
+		bcs->hw.hfc.f1 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
+		cip = HFC_CIP | HFC_F2 | HFC_SEND | HFC_CHANNEL(bcs->channel);
+		WaitNoBusy(cs);
+		bcs->hw.hfc.f2 = cs->BC_Read_Reg(cs, HFC_DATA, cip);
+		bcs->hw.hfc.send[bcs->hw.hfc.f1] = ReadZReg(bcs, HFC_Z1 | HFC_SEND | HFC_CHANNEL(bcs->channel));
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "hfc_fill_fifo %d f1(%d) f2(%d) z1(%x)",
+				bcs->channel, bcs->hw.hfc.f1, bcs->hw.hfc.f2,
+				bcs->hw.hfc.send[bcs->hw.hfc.f1]);
+		fcnt = bcs->hw.hfc.f1 - bcs->hw.hfc.f2;
+		if (fcnt < 0)
+			fcnt += 32;
+		if (fcnt > 30) {
+			if (cs->debug & L1_DEB_HSCX)
+				debugl1(cs, "hfc_fill_fifo more as 30 frames");
+			return;
+		}
+		count = GetFreeFifoBytes(bcs);
+	}
 	else {
-	  WaitForBusy(cs);
-	  z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
-	  z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
-	  count = z1 - z2;
-	  if (count < 0)
-	    count += cs->hw.hfc.fifosize; 
+		WaitForBusy(cs);
+		z1 = ReadZReg(bcs, HFC_Z1 | HFC_REC | HFC_CHANNEL(bcs->channel));
+		z2 = ReadZReg(bcs, HFC_Z2 | HFC_REC | HFC_CHANNEL(bcs->channel));
+		count = z1 - z2;
+		if (count < 0)
+			count += cs->hw.hfc.fifosize;
 	} /* L1_MODE_TRANS */
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "hfc_fill_fifo %d count(%u/%d)",
@@ -305,12 +305,12 @@ hfc_fill_fifo(struct BCState *bcs)
 		dev_kfree_skb_any(bcs->tx_skb);
 		bcs->tx_skb = NULL;
 		if (bcs->mode != L1_MODE_TRANS) {
-		  WaitForBusy(cs);
-		  WaitNoBusy(cs);
-		  cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
+			WaitForBusy(cs);
+			WaitNoBusy(cs);
+			cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
 		}
-		if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-			(count >= 0)) {
+		if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+		    (count >= 0)) {
 			u_long	flags;
 			spin_lock_irqsave(&bcs->aclock, flags);
 			bcs->ackcnt += count;
@@ -331,7 +331,7 @@ main_irq_hfc(struct BCState *bcs)
 	int receive, transmit, count = 5;
 	struct sk_buff *skb;
 
-      Begin:
+Begin:
 	count--;
 	cip = HFC_CIP | HFC_F1 | HFC_REC | HFC_CHANNEL(bcs->channel);
 	if ((cip & 0xc3) != (cs->hw.hfc.cip & 0xc3)) {
@@ -349,7 +349,7 @@ main_irq_hfc(struct BCState *bcs)
 			if (cs->debug & L1_DEB_HSCX)
 				debugl1(cs, "hfc rec %d f1(%d) f2(%d)",
 					bcs->channel, f1, f2);
-			receive = 1; 
+			receive = 1;
 		}
 	}
 	if (receive || (bcs->mode == L1_MODE_TRANS)) {
@@ -407,41 +407,41 @@ mode_hfc(struct BCState *bcs, int mode, int bc)
 	bcs->channel = bc;
 
 	switch (mode) {
-		case (L1_MODE_NULL):
-		        if (bc) {
-				cs->hw.hfc.ctmt &= ~1;
-				cs->hw.hfc.isac_spcr &= ~0x03;
-			}
-			else {
-				cs->hw.hfc.ctmt &= ~2;
-				cs->hw.hfc.isac_spcr &= ~0x0c;
-			}
-			break;
-		case (L1_MODE_TRANS):
-		        cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */ 
-			cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
-			hfc_clear_fifo(bcs); /* complete fifo clear */ 
-			if (bc) {
-				cs->hw.hfc.ctmt |= 1;
-				cs->hw.hfc.isac_spcr &= ~0x03;
-				cs->hw.hfc.isac_spcr |= 0x02;
-			} else {
-				cs->hw.hfc.ctmt |= 2;
-				cs->hw.hfc.isac_spcr &= ~0x0c;
-				cs->hw.hfc.isac_spcr |= 0x08;
-			}
-			break;
-		case (L1_MODE_HDLC):
-			if (bc) {
-				cs->hw.hfc.ctmt &= ~1;
-				cs->hw.hfc.isac_spcr &= ~0x03;
-				cs->hw.hfc.isac_spcr |= 0x02;
-			} else {
-				cs->hw.hfc.ctmt &= ~2;
-				cs->hw.hfc.isac_spcr &= ~0x0c;
-				cs->hw.hfc.isac_spcr |= 0x08;
-			}
-			break;
+	case (L1_MODE_NULL):
+		if (bc) {
+			cs->hw.hfc.ctmt &= ~1;
+			cs->hw.hfc.isac_spcr &= ~0x03;
+		}
+		else {
+			cs->hw.hfc.ctmt &= ~2;
+			cs->hw.hfc.isac_spcr &= ~0x0c;
+		}
+		break;
+	case (L1_MODE_TRANS):
+		cs->hw.hfc.ctmt &= ~(1 << bc); /* set HDLC mode */
+		cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
+		hfc_clear_fifo(bcs); /* complete fifo clear */
+		if (bc) {
+			cs->hw.hfc.ctmt |= 1;
+			cs->hw.hfc.isac_spcr &= ~0x03;
+			cs->hw.hfc.isac_spcr |= 0x02;
+		} else {
+			cs->hw.hfc.ctmt |= 2;
+			cs->hw.hfc.isac_spcr &= ~0x0c;
+			cs->hw.hfc.isac_spcr |= 0x08;
+		}
+		break;
+	case (L1_MODE_HDLC):
+		if (bc) {
+			cs->hw.hfc.ctmt &= ~1;
+			cs->hw.hfc.isac_spcr &= ~0x03;
+			cs->hw.hfc.isac_spcr |= 0x02;
+		} else {
+			cs->hw.hfc.ctmt &= ~2;
+			cs->hw.hfc.isac_spcr &= ~0x0c;
+			cs->hw.hfc.isac_spcr |= 0x08;
+		}
+		break;
 	}
 	cs->BC_Write_Reg(cs, HFC_STATUS, cs->hw.hfc.ctmt, cs->hw.hfc.ctmt);
 	cs->writeisac(cs, ISAC_SPCR, cs->hw.hfc.isac_spcr);
@@ -457,53 +457,53 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
 	u_long		flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
-			} else {
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->tx_skb = skb;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			mode_hfc(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			mode_hfc(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
+		} else {
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->tx_skb = skb;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		mode_hfc(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		mode_hfc(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
diff --git a/drivers/isdn/hisax/hfc_2bs0.h b/drivers/isdn/hisax/hfc_2bs0.h
index 1a50d4a..1510096 100644
--- a/drivers/isdn/hisax/hfc_2bs0.h
+++ b/drivers/isdn/hisax/hfc_2bs0.h
@@ -4,14 +4,14 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
 #define HFC_CTMT	0xe0
-#define HFC_CIRM  	0xc0
+#define HFC_CIRM	0xc0
 #define HFC_CIP		0x80
 #define HFC_Z1		0x00
 #define HFC_Z2		0x08
@@ -46,7 +46,7 @@
 #define HFC_TRANSB1 0x01
 
 /* CIRM (Write) */
-#define HFC_RESET  	0x08
+#define HFC_RESET	0x08
 #define HFC_MEM8K	0x10
 #define HFC_INTA	0x01
 #define HFC_INTB	0x02
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 0cb0546..334fa90 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -57,10 +57,10 @@ static const PCI_ENTRY id_list[] =
 	{PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"},
 	{PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"},
 	{PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"},
-	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,"Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
-	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
-	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
-	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
+	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E, "Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
+	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E, "Digi International", "Digi DataFire Micro V (Europe)"},
+	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A, "Digi International", "Digi DataFire Micro V IOM2 (North America)"},
+	{PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A, "Digi International", "Digi DataFire Micro V (North America)"},
 	{PCI_VENDOR_ID_SITECOM, PCI_DEVICE_ID_SITECOM_DC105V2, "Sitecom Europe", "DC-105 ISDN PCI"},
 	{0, 0, NULL, NULL},
 };
@@ -73,7 +73,7 @@ static void
 release_io_hfcpci(struct IsdnCardState *cs)
 {
 	printk(KERN_INFO "HiSax: release hfcpci at %p\n",
-		cs->hw.hfcpci.pci_io);
+	       cs->hw.hfcpci.pci_io);
 	cs->hw.hfcpci.int_m2 = 0;					/* interrupt output off ! */
 	Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
 	Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET);			/* Reset On */
@@ -84,7 +84,7 @@ release_io_hfcpci(struct IsdnCardState *cs)
 	pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0);	/* disable memory mapped ports + busmaster */
 	del_timer(&cs->hw.hfcpci.timer);
 	pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
-		cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
+			    cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
 	cs->hw.hfcpci.fifos = NULL;
 	iounmap((void *)cs->hw.hfcpci.pci_io);
 }
@@ -124,7 +124,7 @@ reset_hfcpci(struct IsdnCardState *cs)
 	Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt);
 
 	cs->hw.hfcpci.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC |
-	    HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
+		HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER;
 	Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
 
 	/* Clear already pending ints */
@@ -170,8 +170,8 @@ hfcpci_Timer(struct IsdnCardState *cs)
 	cs->hw.hfcpci.timer.expires = jiffies + 75;
 	/* WD RESET */
 /*      WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcpci.ctmt | 0x80);
-   add_timer(&cs->hw.hfcpci.timer);
- */
+	add_timer(&cs->hw.hfcpci.timer);
+*/
 }
 
 
@@ -215,17 +215,17 @@ Sel_BCS(struct IsdnCardState *cs, int channel)
 /***************************************/
 static void hfcpci_clear_fifo_rx(struct IsdnCardState *cs, int fifo)
 {       u_char fifo_state;
-        bzfifo_type *bzr;
+	bzfifo_type *bzr;
 
 	if (fifo) {
-	        bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;
+		bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;
 		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2RX;
 	} else {
-	        bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1;
+		bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1;
 		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1RX;
 	}
 	if (fifo_state)
-	        cs->hw.hfcpci.fifo_en ^= fifo_state;
+		cs->hw.hfcpci.fifo_en ^= fifo_state;
 	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
 	cs->hw.hfcpci.last_bfifo_cnt[fifo] = 0;
 	bzr->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1;
@@ -233,7 +233,7 @@ static void hfcpci_clear_fifo_rx(struct IsdnCardState *cs, int fifo)
 	bzr->f1 = MAX_B_FRAMES;
 	bzr->f2 = bzr->f1;	/* init F pointers to remain constant */
 	if (fifo_state)
-	        cs->hw.hfcpci.fifo_en |= fifo_state;
+		cs->hw.hfcpci.fifo_en |= fifo_state;
 	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
 }
 
@@ -242,24 +242,24 @@ static void hfcpci_clear_fifo_rx(struct IsdnCardState *cs, int fifo)
 /***************************************/
 static void hfcpci_clear_fifo_tx(struct IsdnCardState *cs, int fifo)
 {       u_char fifo_state;
-        bzfifo_type *bzt;
+	bzfifo_type *bzt;
 
 	if (fifo) {
-	        bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2;
+		bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2;
 		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B2TX;
 	} else {
-	        bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1;
+		bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1;
 		fifo_state = cs->hw.hfcpci.fifo_en & HFCPCI_FIFOEN_B1TX;
 	}
 	if (fifo_state)
-	        cs->hw.hfcpci.fifo_en ^= fifo_state;
+		cs->hw.hfcpci.fifo_en ^= fifo_state;
 	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
 	bzt->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1;
 	bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1;
 	bzt->f1 = MAX_B_FRAMES;
 	bzt->f2 = bzt->f1;	/* init F pointers to remain constant */
 	if (fifo_state)
-	        cs->hw.hfcpci.fifo_en |= fifo_state;
+		cs->hw.hfcpci.fifo_en |= fifo_state;
 	Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en);
 }
 
@@ -268,7 +268,7 @@ static void hfcpci_clear_fifo_tx(struct IsdnCardState *cs, int fifo)
 /*********************************************/
 static struct sk_buff
 *
-hfcpci_empty_fifo(struct BCState *bcs, bzfifo_type * bz, u_char * bdata, int count)
+hfcpci_empty_fifo(struct BCState *bcs, bzfifo_type *bz, u_char *bdata, int count)
 {
 	u_char *ptr, *ptr1, new_f2;
 	struct sk_buff *skb;
@@ -395,7 +395,7 @@ receive_dmsg(struct IsdnCardState *cs)
 /* check for transparent receive data and read max one threshold size if avail */
 /*******************************************************************************/
 static int
-hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata)
+hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type *bz, u_char *bdata)
 {
 	unsigned short *z1r, *z2r;
 	int new_z2, fcnt, maxlen;
@@ -467,7 +467,7 @@ main_rec_hfcpci(struct BCState *bcs)
 		bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b1;
 		real_fifo = 0;
 	}
-      Begin:
+Begin:
 	count--;
 	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 		debugl1(cs, "rec_data %d blocked", bcs->channel);
@@ -494,7 +494,7 @@ main_rec_hfcpci(struct BCState *bcs)
 		if (rcnt < 0)
 			rcnt += MAX_B_FRAMES + 1;
 		if (cs->hw.hfcpci.last_bfifo_cnt[real_fifo] > rcnt + 1) {
-		        rcnt = 0;
+			rcnt = 0;
 			hfcpci_clear_fifo_rx(cs, real_fifo);
 		}
 		cs->hw.hfcpci.last_bfifo_cnt[real_fifo] = rcnt;
@@ -647,8 +647,8 @@ hfcpci_fill_fifo(struct BCState *bcs)
 				debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded",
 					bcs->channel, bcs->tx_skb->len);
 
-			if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-				(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+			if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+			    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 				u_long	flags;
 				spin_lock_irqsave(&bcs->aclock, flags);
 				bcs->ackcnt += bcs->tx_skb->len;
@@ -710,8 +710,8 @@ hfcpci_fill_fifo(struct BCState *bcs)
 		memcpy(dst, src, count);
 	}
 	bcs->tx_cnt -= bcs->tx_skb->len;
-	if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-		(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+	if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+	    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 		u_long	flags;
 		spin_lock_irqsave(&bcs->aclock, flags);
 		bcs->ackcnt += bcs->tx_skb->len;
@@ -736,27 +736,27 @@ dch_nt_l2l1(struct PStack *st, int pr, void *arg)
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-		case (PH_PULL | REQUEST):
-		case (PH_PULL | INDICATION):
-			st->l1.l1hw(st, pr, arg);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
-			break;
-		case (PH_TESTLOOP | REQUEST):
-			if (1 & (long) arg)
-				debugl1(cs, "PH_TEST_LOOP B1");
-			if (2 & (long) arg)
-				debugl1(cs, "PH_TEST_LOOP B2");
-			if (!(3 & (long) arg))
-				debugl1(cs, "PH_TEST_LOOP DISABLED");
-			st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
-			break;
-		default:
-			if (cs->debug)
-				debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);
-			break;
+	case (PH_DATA | REQUEST):
+	case (PH_PULL | REQUEST):
+	case (PH_PULL | INDICATION):
+		st->l1.l1hw(st, pr, arg);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+		break;
+	case (PH_TESTLOOP | REQUEST):
+		if (1 & (long) arg)
+			debugl1(cs, "PH_TEST_LOOP B1");
+		if (2 & (long) arg)
+			debugl1(cs, "PH_TEST_LOOP B2");
+		if (!(3 & (long) arg))
+			debugl1(cs, "PH_TEST_LOOP DISABLED");
+		st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
+		break;
+	default:
+		if (cs->debug)
+			debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);
+		break;
 	}
 }
 
@@ -766,14 +766,14 @@ dch_nt_l2l1(struct PStack *st, int pr, void *arg)
 /* set/reset echo mode */
 /***********************/
 static int
-hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic)
+hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic)
 {
 	u_long	flags;
 	int	i = *(unsigned int *) ic->parm.num;
 
 	if ((ic->arg == 98) &&
 	    (!(cs->hw.hfcpci.int_m1 & (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC + HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC)))) {
-	    	spin_lock_irqsave(&cs->lock, flags);
+		spin_lock_irqsave(&cs->lock, flags);
 		Write_hfc(cs, HFCPCI_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */
 		Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 0);	/* HFC ST G0 */
 		udelay(10);
@@ -839,7 +839,7 @@ receive_emsg(struct IsdnCardState *cs)
 
 	bz = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2;
 	bdata = ((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxdat_b2;
-      Begin:
+Begin:
 	count--;
 	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 		debugl1(cs, "echo_rec_data blocked");
@@ -1078,7 +1078,7 @@ hfcpci_interrupt(int intno, void *dev_id)
 			} else
 				sched_event_D_pci(cs, D_XMTBUFREADY);
 		}
-	      afterXPR:
+	afterXPR:
 		if (cs->hw.hfcpci.int_s1 && count--) {
 			val = cs->hw.hfcpci.int_s1;
 			cs->hw.hfcpci.int_s1 = 0;
@@ -1110,130 +1110,130 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
 	struct sk_buff *skb = arg;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
-#ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-				if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
-					hfcpci_fill_dfifo(cs);
-					test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
-				} else
-					debugl1(cs, "hfcpci_fill_dfifo blocked");
-
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
 			if (cs->debug & L1_DEB_LAPD)
-				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+				Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
 			if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 				hfcpci_fill_dfifo(cs);
 				test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 			} else
 				debugl1(cs, "hfcpci_fill_dfifo blocked");
+
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			break;
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD)
+			Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3);	/* HFC ST 3 */
-			udelay(6);
-			Write_hfc(cs, HFCPCI_STATES, 3);	/* HFC ST 2 */
-			cs->hw.hfcpci.mst_m |= HFCPCI_MASTER;
-			Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
-			Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-		case (HW_ENABLE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			Write_hfc(cs, HFCPCI_STATES, HFCPCI_DO_ACTION);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_DEACTIVATE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER;
-			Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO3 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcpci.mst_m |= HFCPCI_MASTER;
-			Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
+		if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
+			hfcpci_fill_dfifo(cs);
+			test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
+		} else
+			debugl1(cs, "hfcpci_fill_dfifo blocked");
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG		/* psa */
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3);	/* HFC ST 3 */
+		udelay(6);
+		Write_hfc(cs, HFCPCI_STATES, 3);	/* HFC ST 2 */
+		cs->hw.hfcpci.mst_m |= HFCPCI_MASTER;
+		Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
+		Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		break;
+	case (HW_ENABLE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		Write_hfc(cs, HFCPCI_STATES, HFCPCI_DO_ACTION);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_DEACTIVATE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER;
+		Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO3 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcpci.mst_m |= HFCPCI_MASTER;
+		Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_TESTLOOP | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		switch ((long) arg) {
+		case (1):
+			Write_hfc(cs, HFCPCI_B1_SSL, 0x80);	/* tx slot */
+			Write_hfc(cs, HFCPCI_B1_RSL, 0x80);	/* rx slot */
+			cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~7) | 1;
+			Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn);
 			break;
-		case (HW_TESTLOOP | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			switch ((long) arg) {
-				case (1):
-					Write_hfc(cs, HFCPCI_B1_SSL, 0x80);	/* tx slot */
-					Write_hfc(cs, HFCPCI_B1_RSL, 0x80);	/* rx slot */
-					cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~7) | 1;
-					Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn);
-					break;
-
-				case (2):
-					Write_hfc(cs, HFCPCI_B2_SSL, 0x81);	/* tx slot */
-					Write_hfc(cs, HFCPCI_B2_RSL, 0x81);	/* rx slot */
-					cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~0x38) | 0x08;
-					Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn);
-					break;
-
-				default:
-					spin_unlock_irqrestore(&cs->lock, flags);
-					if (cs->debug & L1_DEB_WARN)
-						debugl1(cs, "hfcpci_l1hw loop invalid %4lx", (long) arg);
-					return;
-			}
-			cs->hw.hfcpci.trm |= 0x80;	/* enable IOM-loop */
-			Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm);
-			spin_unlock_irqrestore(&cs->lock, flags);
+
+		case (2):
+			Write_hfc(cs, HFCPCI_B2_SSL, 0x81);	/* tx slot */
+			Write_hfc(cs, HFCPCI_B2_RSL, 0x81);	/* rx slot */
+			cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~0x38) | 0x08;
+			Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn);
 			break;
+
 		default:
+			spin_unlock_irqrestore(&cs->lock, flags);
 			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "hfcpci_l1hw unknown pr %4x", pr);
-			break;
+				debugl1(cs, "hfcpci_l1hw loop invalid %4lx", (long) arg);
+			return;
+		}
+		cs->hw.hfcpci.trm |= 0x80;	/* enable IOM-loop */
+		Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "hfcpci_l1hw unknown pr %4x", pr);
+		break;
 	}
 }
 
@@ -1295,83 +1295,83 @@ mode_hfcpci(struct BCState *bcs, int mode, int bc)
 		}
 	}
 	switch (mode) {
-		case (L1_MODE_NULL):
-			if (bc) {
-				cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA;
-				cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcpci.sctrl &= ~SCTRL_B1_ENA;
-				cs->hw.hfcpci.sctrl_r &= ~SCTRL_B1_ENA;
-			}
-			if (fifo2) {
-				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2;
-				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
-			} else {
-				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1;
-				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
-			}
-			break;
-		case (L1_MODE_TRANS):
-		        hfcpci_clear_fifo_rx(cs, fifo2);
-		        hfcpci_clear_fifo_tx(cs, fifo2);
-			if (bc) {
-				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
-				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;
-				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
-			}
-			if (fifo2) {
-				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;
-				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
-				cs->hw.hfcpci.ctmt |= 2;
-				cs->hw.hfcpci.conn &= ~0x18;
-			} else {
-				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;
-				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
-				cs->hw.hfcpci.ctmt |= 1;
-				cs->hw.hfcpci.conn &= ~0x03;
-			}
-			break;
-		case (L1_MODE_HDLC):
-		        hfcpci_clear_fifo_rx(cs, fifo2);
-		        hfcpci_clear_fifo_tx(cs, fifo2);
-			if (bc) {
-				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
-				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;
-				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
-			}
-			if (fifo2) {
-			        cs->hw.hfcpci.last_bfifo_cnt[1] = 0;
-				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;
-				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
-				cs->hw.hfcpci.ctmt &= ~2;
-				cs->hw.hfcpci.conn &= ~0x18;
-			} else {
-			        cs->hw.hfcpci.last_bfifo_cnt[0] = 0;
-				cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;
-				cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
-				cs->hw.hfcpci.ctmt &= ~1;
-				cs->hw.hfcpci.conn &= ~0x03;
-			}
-			break;
-		case (L1_MODE_EXTRN):
-			if (bc) {
-				cs->hw.hfcpci.conn |= 0x10;
-				cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
-				cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
-				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2;
-				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
-			} else {
-				cs->hw.hfcpci.conn |= 0x02;
-				cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;
-				cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
-				cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1;
-				cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
-			}
-			break;
+	case (L1_MODE_NULL):
+		if (bc) {
+			cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA;
+			cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcpci.sctrl &= ~SCTRL_B1_ENA;
+			cs->hw.hfcpci.sctrl_r &= ~SCTRL_B1_ENA;
+		}
+		if (fifo2) {
+			cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2;
+			cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
+		} else {
+			cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1;
+			cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
+		}
+		break;
+	case (L1_MODE_TRANS):
+		hfcpci_clear_fifo_rx(cs, fifo2);
+		hfcpci_clear_fifo_tx(cs, fifo2);
+		if (bc) {
+			cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
+			cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;
+			cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
+		}
+		if (fifo2) {
+			cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;
+			cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
+			cs->hw.hfcpci.ctmt |= 2;
+			cs->hw.hfcpci.conn &= ~0x18;
+		} else {
+			cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;
+			cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
+			cs->hw.hfcpci.ctmt |= 1;
+			cs->hw.hfcpci.conn &= ~0x03;
+		}
+		break;
+	case (L1_MODE_HDLC):
+		hfcpci_clear_fifo_rx(cs, fifo2);
+		hfcpci_clear_fifo_tx(cs, fifo2);
+		if (bc) {
+			cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
+			cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;
+			cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
+		}
+		if (fifo2) {
+			cs->hw.hfcpci.last_bfifo_cnt[1] = 0;
+			cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2;
+			cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
+			cs->hw.hfcpci.ctmt &= ~2;
+			cs->hw.hfcpci.conn &= ~0x18;
+		} else {
+			cs->hw.hfcpci.last_bfifo_cnt[0] = 0;
+			cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1;
+			cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
+			cs->hw.hfcpci.ctmt &= ~1;
+			cs->hw.hfcpci.conn &= ~0x03;
+		}
+		break;
+	case (L1_MODE_EXTRN):
+		if (bc) {
+			cs->hw.hfcpci.conn |= 0x10;
+			cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA;
+			cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA;
+			cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2;
+			cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC);
+		} else {
+			cs->hw.hfcpci.conn |= 0x02;
+			cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA;
+			cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA;
+			cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1;
+			cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC);
+		}
+		break;
 	}
 	Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e);
 	Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
@@ -1393,54 +1393,54 @@ hfcpci_l2l1(struct PStack *st, int pr, void *arg)
 	struct sk_buff	*skb = arg;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-//				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
- 				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				spin_unlock_irqrestore(&bcs->cs->lock, flags);
-				printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
-				break;
-			}
-//			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
 			bcs->tx_skb = skb;
+//				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
 			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
+			printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
 			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			mode_hfcpci(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			mode_hfcpci(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+		}
+//			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+		bcs->tx_skb = skb;
+		bcs->cs->BC_Send_Data(bcs);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		mode_hfcpci(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		mode_hfcpci(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -1510,57 +1510,57 @@ hfcpci_bh(struct work_struct *work)
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		if (!cs->hw.hfcpci.nt_mode)
 			switch (cs->dc.hfcpci.ph_state) {
-				case (0):
-					l1_msg(cs, HW_RESET | INDICATION, NULL);
-					break;
-				case (3):
-					l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-					break;
-				case (8):
-					l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-					break;
-				case (6):
-					l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-					break;
-				case (7):
-					l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-					break;
-				default:
-					break;
-		} else {
+			case (0):
+				l1_msg(cs, HW_RESET | INDICATION, NULL);
+				break;
+			case (3):
+				l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+				break;
+			case (8):
+				l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+				break;
+			case (6):
+				l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+				break;
+			case (7):
+				l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+				break;
+			default:
+				break;
+			} else {
 			spin_lock_irqsave(&cs->lock, flags);
 			switch (cs->dc.hfcpci.ph_state) {
-				case (2):
-					if (cs->hw.hfcpci.nt_timer < 0) {
-						cs->hw.hfcpci.nt_timer = 0;
-						cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
-						Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
-						/* Clear already pending ints */
-						if (Read_hfc(cs, HFCPCI_INT_S1));
-						Write_hfc(cs, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
-						udelay(10);
-						Write_hfc(cs, HFCPCI_STATES, 4);
-						cs->dc.hfcpci.ph_state = 4;
-					} else {
-						cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_TIMER;
-						Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
-						cs->hw.hfcpci.ctmt &= ~HFCPCI_AUTO_TIMER;
-						cs->hw.hfcpci.ctmt |= HFCPCI_TIM3_125;
-						Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER);
-						Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER);
-						cs->hw.hfcpci.nt_timer = NT_T1_COUNT;
-						Write_hfc(cs, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);	/* allow G2 -> G3 transition */
-					}
-					break;
-				case (1):
-				case (3):
-				case (4):
+			case (2):
+				if (cs->hw.hfcpci.nt_timer < 0) {
 					cs->hw.hfcpci.nt_timer = 0;
 					cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
 					Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
-					break;
-				default:
-					break;
+					/* Clear already pending ints */
+					if (Read_hfc(cs, HFCPCI_INT_S1));
+					Write_hfc(cs, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
+					udelay(10);
+					Write_hfc(cs, HFCPCI_STATES, 4);
+					cs->dc.hfcpci.ph_state = 4;
+				} else {
+					cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_TIMER;
+					Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
+					cs->hw.hfcpci.ctmt &= ~HFCPCI_AUTO_TIMER;
+					cs->hw.hfcpci.ctmt |= HFCPCI_TIM3_125;
+					Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER);
+					Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER);
+					cs->hw.hfcpci.nt_timer = NT_T1_COUNT;
+					Write_hfc(cs, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3);	/* allow G2 -> G3 transition */
+				}
+				break;
+			case (1):
+			case (3):
+			case (4):
+				cs->hw.hfcpci.nt_timer = 0;
+				cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
+				Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
+				break;
+			default:
+				break;
 			}
 			spin_unlock_irqrestore(&cs->lock, flags);
 		}
@@ -1602,30 +1602,30 @@ hfcpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "HFCPCI: card_msg %x", mt);
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_hfcpci(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_RELEASE:
-			release_io_hfcpci(cs);
-			return (0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithfcpci(cs);
-			reset_hfcpci(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			msleep(80);				/* Timeout 80ms */
-			/* now switch timer interrupt off */
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
-			Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
-			/* reinit mode reg */
-			Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_TEST:
-			return (0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_hfcpci(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_hfcpci(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithfcpci(cs);
+		reset_hfcpci(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		msleep(80);				/* Timeout 80ms */
+		/* now switch timer interrupt off */
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER;
+		Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
+		/* reinit mode reg */
+		Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
 	return (0);
 }
@@ -1654,13 +1654,13 @@ setup_hfcpci(struct IsdnCard *card)
 	cs->dc.hfcpci.ph_state = 0;
 	cs->hw.hfcpci.fifo = 255;
 	if (cs->typ != ISDN_CTYPE_HFC_PCI)
-		return(0);
+		return (0);
 
 	i = 0;
 	while (id_list[i].vendor_id) {
 		tmp_hfcpci = hisax_find_pci_device(id_list[i].vendor_id,
-					     id_list[i].device_id,
-					     dev_hfcpci);
+						   id_list[i].device_id,
+						   dev_hfcpci);
 		i++;
 		if (tmp_hfcpci) {
 			dma_addr_t	dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL;
@@ -1668,16 +1668,16 @@ setup_hfcpci(struct IsdnCard *card)
 				continue;
 			if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) {
 				printk(KERN_WARNING
-					"HiSax hfc_pci: No suitable DMA available.\n");
+				       "HiSax hfc_pci: No suitable DMA available.\n");
 				continue;
 			}
 			if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) {
 				printk(KERN_WARNING
-					"HiSax hfc_pci: No suitable consistent DMA available.\n");
+				       "HiSax hfc_pci: No suitable consistent DMA available.\n");
 				continue;
 			}
 			pci_set_master(tmp_hfcpci);
-			if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
+			if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[0].start & PCI_BASE_ADDRESS_IO_MASK)))
 				continue;
 			else
 				break;
@@ -1707,17 +1707,17 @@ setup_hfcpci(struct IsdnCard *card)
 
 	/* Allocate memory for FIFOS */
 	cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev,
-					0x8000, &cs->hw.hfcpci.dma);
+						   0x8000, &cs->hw.hfcpci.dma);
 	if (!cs->hw.hfcpci.fifos) {
 		printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n");
 		return 0;
 	}
 	if (cs->hw.hfcpci.dma & 0x7fff) {
 		printk(KERN_WARNING
-		    "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n",
-		    (u_long)cs->hw.hfcpci.dma);
+		       "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n",
+		       (u_long)cs->hw.hfcpci.dma);
 		pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
-			cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
+				    cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
 		return 0;
 	}
 	pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma);
diff --git a/drivers/isdn/hisax/hfc_pci.h b/drivers/isdn/hisax/hfc_pci.h
index 9ef2981..4e58700 100644
--- a/drivers/isdn/hisax/hfc_pci.h
+++ b/drivers/isdn/hisax/hfc_pci.h
@@ -4,7 +4,7 @@
  *
  * Author       Werner Cornelius
  * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -55,7 +55,7 @@
 
 #define HFCPCI_MST_EMOD  0xB4
 #define HFCPCI_MST_MODE	 0xB8
-#define HFCPCI_CONNECT 	 0xBC
+#define HFCPCI_CONNECT	 0xBC
 
 
 /* Interrupt and status registers */
@@ -64,22 +64,22 @@
 #define HFCPCI_TRM       0x48
 #define HFCPCI_B_MODE    0x4C
 #define HFCPCI_CHIP_ID   0x58
-#define HFCPCI_CIRM  	 0x60
+#define HFCPCI_CIRM	 0x60
 #define HFCPCI_CTMT	 0x64
-#define HFCPCI_INT_M1  	 0x68
-#define HFCPCI_INT_M2  	 0x6C
-#define HFCPCI_INT_S1  	 0x78
-#define HFCPCI_INT_S2  	 0x7C
-#define HFCPCI_STATUS  	 0x70
+#define HFCPCI_INT_M1	 0x68
+#define HFCPCI_INT_M2	 0x6C
+#define HFCPCI_INT_S1	 0x78
+#define HFCPCI_INT_S2	 0x7C
+#define HFCPCI_STATUS	 0x70
 
 /* S/T section registers */
 
-#define HFCPCI_STATES  	 0xC0
-#define HFCPCI_SCTRL  	 0xC4
+#define HFCPCI_STATES	 0xC0
+#define HFCPCI_SCTRL	 0xC4
 #define HFCPCI_SCTRL_E   0xC8
 #define HFCPCI_SCTRL_R   0xCC
-#define HFCPCI_SQ  	 0xD0
-#define HFCPCI_CLKDEL  	 0xDC
+#define HFCPCI_SQ	 0xD0
+#define HFCPCI_CLKDEL	 0xDC
 #define HFCPCI_B1_REC    0xF0
 #define HFCPCI_B1_SEND   0xF0
 #define HFCPCI_B2_REC    0xF4
@@ -91,7 +91,7 @@
 
 /* bits in status register (READ) */
 #define HFCPCI_PCI_PROC   0x02
-#define HFCPCI_NBUSY	  0x04 
+#define HFCPCI_NBUSY	  0x04
 #define HFCPCI_TIMER_ELAP 0x10
 #define HFCPCI_STATINT	  0x20
 #define HFCPCI_FRAMEINT	  0x40
@@ -110,7 +110,7 @@
 
 /* bits in CIRM (Write) */
 #define HFCPCI_AUX_MSK    0x07
-#define HFCPCI_RESET  	  0x08
+#define HFCPCI_RESET	  0x08
 #define HFCPCI_B1_REV     0x40
 #define HFCPCI_B2_REV     0x80
 
@@ -183,53 +183,53 @@
 #define D_FREG_MASK  0xF
 
 typedef struct {
-    unsigned short z1;  /* Z1 pointer 16 Bit */
-    unsigned short z2;  /* Z2 pointer 16 Bit */
-  } z_type;
+	unsigned short z1;  /* Z1 pointer 16 Bit */
+	unsigned short z2;  /* Z2 pointer 16 Bit */
+} z_type;
 
 typedef struct {
-    u_char data[D_FIFO_SIZE]; /* FIFO data space */
-    u_char fill1[0x20A0-D_FIFO_SIZE]; /* reserved, do not use */
-    u_char f1,f2; /* f pointers */
-    u_char fill2[0x20C0-0x20A2]; /* reserved, do not use */
-    z_type za[MAX_D_FRAMES+1]; /* mask index with D_FREG_MASK for access */
-    u_char fill3[0x4000-0x2100]; /* align 16K */  
-  } dfifo_type;
+	u_char data[D_FIFO_SIZE]; /* FIFO data space */
+	u_char fill1[0x20A0 - D_FIFO_SIZE]; /* reserved, do not use */
+	u_char f1, f2; /* f pointers */
+	u_char fill2[0x20C0 - 0x20A2]; /* reserved, do not use */
+	z_type za[MAX_D_FRAMES + 1]; /* mask index with D_FREG_MASK for access */
+	u_char fill3[0x4000 - 0x2100]; /* align 16K */
+} dfifo_type;
 
 typedef struct {
-    z_type za[MAX_B_FRAMES+1]; /* only range 0x0..0x1F allowed */ 
-    u_char f1,f2; /* f pointers */
-    u_char fill[0x2100-0x2082]; /* alignment */
-  } bzfifo_type;
+	z_type za[MAX_B_FRAMES + 1]; /* only range 0x0..0x1F allowed */
+	u_char f1, f2; /* f pointers */
+	u_char fill[0x2100 - 0x2082]; /* alignment */
+} bzfifo_type;
 
 
 typedef union {
-    struct { 
-      dfifo_type d_tx; /* D-send channel */
-      dfifo_type d_rx; /* D-receive channel */
-    } d_chan; 
-    struct {
-      u_char fill1[0x200];
-      u_char txdat_b1[B_FIFO_SIZE];
-      bzfifo_type txbz_b1;
+	struct {
+		dfifo_type d_tx; /* D-send channel */
+		dfifo_type d_rx; /* D-receive channel */
+	} d_chan;
+	struct {
+		u_char fill1[0x200];
+		u_char txdat_b1[B_FIFO_SIZE];
+		bzfifo_type txbz_b1;
 
-      bzfifo_type txbz_b2;
-      u_char txdat_b2[B_FIFO_SIZE];
+		bzfifo_type txbz_b2;
+		u_char txdat_b2[B_FIFO_SIZE];
 
-      u_char fill2[D_FIFO_SIZE];
+		u_char fill2[D_FIFO_SIZE];
 
-      u_char rxdat_b1[B_FIFO_SIZE];
-      bzfifo_type rxbz_b1;
+		u_char rxdat_b1[B_FIFO_SIZE];
+		bzfifo_type rxbz_b1;
 
-      bzfifo_type rxbz_b2;
-      u_char rxdat_b2[B_FIFO_SIZE];
-    } b_chans;  
-    u_char fill[32768]; 
-  } fifo_area;
+		bzfifo_type rxbz_b2;
+		u_char rxdat_b2[B_FIFO_SIZE];
+	} b_chans;
+	u_char fill[32768];
+} fifo_area;
 
 
-#define Write_hfc(a,b,c) (*(((u_char *)a->hw.hfcpci.pci_io)+b) = c) 
-#define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b))
+#define Write_hfc(a, b, c) (*(((u_char *)a->hw.hfcpci.pci_io) + b) = c)
+#define Read_hfc(a, b) (*(((u_char *)a->hw.hfcpci.pci_io) + b))
 
 extern void main_irq_hcpci(struct BCState *bcs);
 extern void releasehfcpci(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index 156d7c6..4db846b 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -5,7 +5,7 @@
  * Author       Werner Cornelius
  *              based on existing driver for CCD HFC PCI cards
  * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -43,16 +43,16 @@ static const char *hfcsx_revision = "$Revision: 1.12.2.5 $";
 #undef CCD_DEMO_BOARD
 #ifdef CCD_DEMO_BOARD
 static u_char ccd_sp_irqtab[16] = {
-  0,0,0,0,0,2,1,0,0,0,3,4,5,0,0,6
+	0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 3, 4, 5, 0, 0, 6
 };
 #else /* Teles 16.3c */
 static u_char ccd_sp_irqtab[16] = {
-  0,0,0,7,0,1,0,0,0,2,3,4,5,0,0,6
+	0, 0, 0, 7, 0, 1, 0, 0, 0, 2, 3, 4, 5, 0, 0, 6
 };
 #endif
 #define NT_T1_COUNT 20		/* number of 3.125ms interrupts for G2 timeout */
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 /******************************/
@@ -61,19 +61,19 @@ static u_char ccd_sp_irqtab[16] = {
 static inline void
 Write_hfc(struct IsdnCardState *cs, u_char regnum, u_char val)
 {
-        byteout(cs->hw.hfcsx.base+1, regnum);
+	byteout(cs->hw.hfcsx.base + 1, regnum);
 	byteout(cs->hw.hfcsx.base, val);
-} 
+}
 
 static inline u_char
 Read_hfc(struct IsdnCardState *cs, u_char regnum)
 {
-        u_char ret; 
+	u_char ret;
 
-        byteout(cs->hw.hfcsx.base+1, regnum);
+	byteout(cs->hw.hfcsx.base + 1, regnum);
 	ret = bytein(cs->hw.hfcsx.base);
-	return(ret);
-} 
+	return (ret);
+}
 
 
 /**************************************************/
@@ -82,15 +82,15 @@ Read_hfc(struct IsdnCardState *cs, u_char regnum)
 static void
 fifo_select(struct IsdnCardState *cs, u_char fifo)
 {
-        if (fifo == cs->hw.hfcsx.last_fifo) 
-	  return; /* still valid */
+	if (fifo == cs->hw.hfcsx.last_fifo)
+		return; /* still valid */
 
-        byteout(cs->hw.hfcsx.base+1, HFCSX_FIF_SEL);
+	byteout(cs->hw.hfcsx.base + 1, HFCSX_FIF_SEL);
 	byteout(cs->hw.hfcsx.base, fifo);
-	while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
+	while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */
 	udelay(4);
 	byteout(cs->hw.hfcsx.base, fifo);
-	while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
+	while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */
 }
 
 /******************************************/
@@ -101,11 +101,11 @@ static void
 reset_fifo(struct IsdnCardState *cs, u_char fifo)
 {
 	fifo_select(cs, fifo); /* first select the fifo */
-	byteout(cs->hw.hfcsx.base+1, HFCSX_CIRM);
+	byteout(cs->hw.hfcsx.base + 1, HFCSX_CIRM);
 	byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.cirm | 0x80); /* reset cmd */
 	udelay(1);
-	while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
-} 
+	while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */
+}
 
 
 /*************************************************************/
@@ -116,56 +116,56 @@ reset_fifo(struct IsdnCardState *cs, u_char fifo)
 static int
 write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans_max)
 {
-       unsigned short *msp;
-        int fifo_size, count, z1, z2;
+	unsigned short *msp;
+	int fifo_size, count, z1, z2;
 	u_char f_msk, f1, f2, *src;
 
-	if (skb->len <= 0) return(0);
-        if (fifo & 1) return(0); /* no write fifo */
+	if (skb->len <= 0) return (0);
+	if (fifo & 1) return (0); /* no write fifo */
 
 	fifo_select(cs, fifo);
 	if (fifo & 4) {
-	  fifo_size = D_FIFO_SIZE; /* D-channel */
-	  f_msk = MAX_D_FRAMES;
-	  if (trans_max) return(0); /* only HDLC */
+		fifo_size = D_FIFO_SIZE; /* D-channel */
+		f_msk = MAX_D_FRAMES;
+		if (trans_max) return (0); /* only HDLC */
 	}
 	else {
-	  fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
-	  f_msk = MAX_B_FRAMES;
+		fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
+		f_msk = MAX_B_FRAMES;
 	}
 
-        z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
+	z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
 	z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
 
 	/* Check for transparent mode */
 	if (trans_max) {
-	  z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
-	  z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
-	  count = z2 - z1;
-	  if (count <= 0)
-	    count += fifo_size; /* free bytes */
-	  if (count < skb->len+1) return(0); /* no room */
-	  count = fifo_size - count; /* bytes still not send */
-	  if (count > 2 * trans_max) return(0); /* delay to long */
-	  count = skb->len;
-	  src = skb->data;
-	  while (count--)
-	    Write_hfc(cs, HFCSX_FIF_DWR, *src++);
-	  return(1); /* success */
+		z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
+		z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
+		count = z2 - z1;
+		if (count <= 0)
+			count += fifo_size; /* free bytes */
+		if (count < skb->len + 1) return (0); /* no room */
+		count = fifo_size - count; /* bytes still not send */
+		if (count > 2 * trans_max) return (0); /* delay to long */
+		count = skb->len;
+		src = skb->data;
+		while (count--)
+			Write_hfc(cs, HFCSX_FIF_DWR, *src++);
+		return (1); /* success */
 	}
 
-        msp = ((struct hfcsx_extra *)(cs->hw.hfcsx.extra))->marker;
-	msp += (((fifo >> 1) & 3) * (MAX_B_FRAMES+1));
+	msp = ((struct hfcsx_extra *)(cs->hw.hfcsx.extra))->marker;
+	msp += (((fifo >> 1) & 3) * (MAX_B_FRAMES + 1));
 	f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
 	f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
 
 	count = f1 - f2; /* frame count actually buffered */
 	if (count < 0)
 		count += (f_msk + 1);	/* if wrap around */
-	if (count > f_msk-1) {
-	  if (cs->debug & L1_DEB_ISAC_FIFO)
-	    debugl1(cs, "hfcsx_write_fifo %d more as %d frames",fifo,f_msk-1);
-	  return(0);
+	if (count > f_msk - 1) {
+		if (cs->debug & L1_DEB_ISAC_FIFO)
+			debugl1(cs, "hfcsx_write_fifo %d more as %d frames", fifo, f_msk - 1);
+		return (0);
 	}
 
 	*(msp + f1) = z1; /* remember marker */
@@ -176,134 +176,134 @@ write_fifo(struct IsdnCardState *cs, struct sk_buff *skb, u_char fifo, int trans
 	/* now determine free bytes in FIFO buffer */
 	count = *(msp + f2) - z1;
 	if (count <= 0)
-	  count += fifo_size;	/* count now contains available bytes */
+		count += fifo_size;	/* count now contains available bytes */
 
 	if (cs->debug & L1_DEB_ISAC_FIFO)
-	  debugl1(cs, "hfcsx_write_fifo %d count(%u/%d)",
-		  fifo, skb->len, count);
+		debugl1(cs, "hfcsx_write_fifo %d count(%u/%d)",
+			fifo, skb->len, count);
 	if (count < skb->len) {
-	  if (cs->debug & L1_DEB_ISAC_FIFO)
-	    debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo);
-	  return(0);
+		if (cs->debug & L1_DEB_ISAC_FIFO)
+			debugl1(cs, "hfcsx_write_fifo %d no fifo mem", fifo);
+		return (0);
 	}
-	
+
 	count = skb->len; /* get frame len */
 	src = skb->data;	/* source pointer */
 	while (count--)
-	  Write_hfc(cs, HFCSX_FIF_DWR, *src++);
-	
+		Write_hfc(cs, HFCSX_FIF_DWR, *src++);
+
 	Read_hfc(cs, HFCSX_FIF_INCF1); /* increment F1 */
 	udelay(1);
-	while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
-	return(1);
-} 
+	while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */
+	return (1);
+}
 
 /***************************************************************/
 /* read_fifo reads data to an skb from the desired fifo        */
 /* if no data is available or an error occurs NULL is returned */
 /* the skb is not released in any way.                         */
 /***************************************************************/
-static struct sk_buff * 
+static struct sk_buff *
 read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
 {       int fifo_size, count, z1, z2;
 	u_char f_msk, f1, f2, *dst;
 	struct sk_buff *skb;
 
-        if (!(fifo & 1)) return(NULL); /* no read fifo */
+	if (!(fifo & 1)) return (NULL); /* no read fifo */
 	fifo_select(cs, fifo);
 	if (fifo & 4) {
-	  fifo_size = D_FIFO_SIZE; /* D-channel */
-	  f_msk = MAX_D_FRAMES;
-	  if (trans_max) return(NULL); /* only hdlc */
+		fifo_size = D_FIFO_SIZE; /* D-channel */
+		f_msk = MAX_D_FRAMES;
+		if (trans_max) return (NULL); /* only hdlc */
 	}
 	else {
-	  fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
-	  f_msk = MAX_B_FRAMES;
+		fifo_size = cs->hw.hfcsx.b_fifo_size; /* B-channel */
+		f_msk = MAX_B_FRAMES;
 	}
 
 	/* transparent mode */
 	if (trans_max) {
-	  z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
-	  z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
-	  z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
-	  z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
-	  /* now determine bytes in actual FIFO buffer */
-	  count = z1 - z2;
-	  if (count <= 0)
-	    count += fifo_size;	/* count now contains buffered bytes */
-	  count++;
-	  if (count > trans_max) 
-	    count = trans_max; /* limit length */
-	  skb = dev_alloc_skb(count);
-	  if (skb) {
-	    dst = skb_put(skb, count);
-	    while (count--)
-		*dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
-	    return skb;
-	  } else
-		return NULL; /* no memory */
+		z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
+		z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
+		z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
+		z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
+		/* now determine bytes in actual FIFO buffer */
+		count = z1 - z2;
+		if (count <= 0)
+			count += fifo_size;	/* count now contains buffered bytes */
+		count++;
+		if (count > trans_max)
+			count = trans_max; /* limit length */
+		skb = dev_alloc_skb(count);
+		if (skb) {
+			dst = skb_put(skb, count);
+			while (count--)
+				*dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
+			return skb;
+		} else
+			return NULL; /* no memory */
 	}
 
 	do {
-	  f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
-	  f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
-
-	  if (f1 == f2) return(NULL); /* no frame available */
-
-	  z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
-	  z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
-	  z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
-	  z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
-
-	  if (cs->debug & L1_DEB_ISAC_FIFO)
-	    debugl1(cs, "hfcsx_read_fifo %d f1(%x) f2(%x) z1(f2)(%x) z2(f2)(%x)",
-			fifo, f1, f2, z1, z2);
-	  /* now determine bytes in actual FIFO buffer */
-	  count = z1 - z2;
-	  if (count <= 0)
-	    count += fifo_size;	/* count now contains buffered bytes */
-	  count++;
-
-	  if (cs->debug & L1_DEB_ISAC_FIFO)
-	    debugl1(cs, "hfcsx_read_fifo %d count %u)",
-		    fifo, count);
-
-	  if ((count > fifo_size) || (count < 4)) {
-	    if (cs->debug & L1_DEB_WARN)
-	      debugl1(cs, "hfcsx_read_fifo %d paket inv. len %d ", fifo , count);
-	    while (count) {
-	      count--; /* empty fifo */
-	      Read_hfc(cs, HFCSX_FIF_DRD);
-	    }
-	    skb = NULL;
-	  } else 
-	    if ((skb = dev_alloc_skb(count - 3))) {
-	      count -= 3;
-	      dst = skb_put(skb, count);
-
-	      while (count--) 
-		*dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
-		    
-	      Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 1 */
-	      Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 2 */
-	      if (Read_hfc(cs, HFCSX_FIF_DRD)) {
-		dev_kfree_skb_irq(skb);
+		f1 = Read_hfc(cs, HFCSX_FIF_F1) & f_msk;
+		f2 = Read_hfc(cs, HFCSX_FIF_F2) & f_msk;
+
+		if (f1 == f2) return (NULL); /* no frame available */
+
+		z1 = Read_hfc(cs, HFCSX_FIF_Z1H);
+		z1 = ((z1 << 8) | Read_hfc(cs, HFCSX_FIF_Z1L));
+		z2 = Read_hfc(cs, HFCSX_FIF_Z2H);
+		z2 = ((z2 << 8) | Read_hfc(cs, HFCSX_FIF_Z2L));
+
 		if (cs->debug & L1_DEB_ISAC_FIFO)
-		  debugl1(cs, "hfcsx_read_fifo %d crc error", fifo);
-		skb = NULL;
-	      }
-	    } else {
-	      printk(KERN_WARNING "HFC-SX: receive out of memory\n");
-	      return(NULL);
-	    }
-
-	  Read_hfc(cs, HFCSX_FIF_INCF2); /* increment F2 */
-	  udelay(1);
-	  while (bytein(cs->hw.hfcsx.base+1) & 1); /* wait for busy */
-	  udelay(1);
+			debugl1(cs, "hfcsx_read_fifo %d f1(%x) f2(%x) z1(f2)(%x) z2(f2)(%x)",
+				fifo, f1, f2, z1, z2);
+		/* now determine bytes in actual FIFO buffer */
+		count = z1 - z2;
+		if (count <= 0)
+			count += fifo_size;	/* count now contains buffered bytes */
+		count++;
+
+		if (cs->debug & L1_DEB_ISAC_FIFO)
+			debugl1(cs, "hfcsx_read_fifo %d count %u)",
+				fifo, count);
+
+		if ((count > fifo_size) || (count < 4)) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "hfcsx_read_fifo %d paket inv. len %d ", fifo , count);
+			while (count) {
+				count--; /* empty fifo */
+				Read_hfc(cs, HFCSX_FIF_DRD);
+			}
+			skb = NULL;
+		} else
+			if ((skb = dev_alloc_skb(count - 3))) {
+				count -= 3;
+				dst = skb_put(skb, count);
+
+				while (count--)
+					*dst++ = Read_hfc(cs, HFCSX_FIF_DRD);
+
+				Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 1 */
+				Read_hfc(cs, HFCSX_FIF_DRD); /* CRC 2 */
+				if (Read_hfc(cs, HFCSX_FIF_DRD)) {
+					dev_kfree_skb_irq(skb);
+					if (cs->debug & L1_DEB_ISAC_FIFO)
+						debugl1(cs, "hfcsx_read_fifo %d crc error", fifo);
+					skb = NULL;
+				}
+			} else {
+				printk(KERN_WARNING "HFC-SX: receive out of memory\n");
+				return (NULL);
+			}
+
+		Read_hfc(cs, HFCSX_FIF_INCF2); /* increment F2 */
+		udelay(1);
+		while (bytein(cs->hw.hfcsx.base + 1) & 1); /* wait for busy */
+		udelay(1);
 	} while (!skb); /* retry in case of crc error */
-	return(skb);
-} 
+	return (skb);
+}
 
 /******************************************/
 /* free hardware resources used by driver */
@@ -328,17 +328,17 @@ release_io_hfcsx(struct IsdnCardState *cs)
 /**********************************************************/
 static int set_fifo_size(struct IsdnCardState *cs)
 {
-        
-        if (cs->hw.hfcsx.b_fifo_size) return(1); /* already determined */
+
+	if (cs->hw.hfcsx.b_fifo_size) return (1); /* already determined */
 
 	if ((cs->hw.hfcsx.chip >> 4) == 9) {
-	  cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_32K;
-	  return(1);
+		cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_32K;
+		return (1);
 	}
 
-	  cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_8K;
-	  cs->hw.hfcsx.cirm |= 0x10; /* only 8K of ram */
-	  return(0);
+	cs->hw.hfcsx.b_fifo_size = B_FIFO_SIZE_8K;
+	cs->hw.hfcsx.cirm |= 0x10; /* only 8K of ram */
+	return (0);
 
 }
 
@@ -354,15 +354,15 @@ reset_hfcsx(struct IsdnCardState *cs)
 
 	printk(KERN_INFO "HFC_SX: resetting card\n");
 	while (1) {
-	  Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET | cs->hw.hfcsx.cirm ); /* Reset */
-	  mdelay(30);
-	  Write_hfc(cs, HFCSX_CIRM, cs->hw.hfcsx.cirm); /* Reset Off */
-	  mdelay(20);
-	  if (Read_hfc(cs, HFCSX_STATUS) & 2)
-	    printk(KERN_WARNING "HFC-SX init bit busy\n");
-	  cs->hw.hfcsx.last_fifo = 0xff; /* invalidate */
-	  if (!set_fifo_size(cs)) continue;
-	  break;
+		Write_hfc(cs, HFCSX_CIRM, HFCSX_RESET | cs->hw.hfcsx.cirm); /* Reset */
+		mdelay(30);
+		Write_hfc(cs, HFCSX_CIRM, cs->hw.hfcsx.cirm); /* Reset Off */
+		mdelay(20);
+		if (Read_hfc(cs, HFCSX_STATUS) & 2)
+			printk(KERN_WARNING "HFC-SX init bit busy\n");
+		cs->hw.hfcsx.last_fifo = 0xff; /* invalidate */
+		if (!set_fifo_size(cs)) continue;
+		break;
 	}
 
 	cs->hw.hfcsx.trm = 0 + HFCSX_BTRANS_THRESMASK;	/* no echo connect , threshold */
@@ -376,8 +376,8 @@ reset_hfcsx(struct IsdnCardState *cs)
 	cs->hw.hfcsx.ctmt = HFCSX_TIM3_125 | HFCSX_AUTO_TIMER;
 	Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
 
-	cs->hw.hfcsx.int_m1 = HFCSX_INTS_DTRANS | HFCSX_INTS_DREC | 
-	    HFCSX_INTS_L1STATE | HFCSX_INTS_TIMER;
+	cs->hw.hfcsx.int_m1 = HFCSX_INTS_DTRANS | HFCSX_INTS_DREC |
+		HFCSX_INTS_L1STATE | HFCSX_INTS_TIMER;
 	Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
 
 	/* Clear already pending ints */
@@ -423,8 +423,8 @@ hfcsx_Timer(struct IsdnCardState *cs)
 	cs->hw.hfcsx.timer.expires = jiffies + 75;
 	/* WD RESET */
 /*      WriteReg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcsx.ctmt | 0x80);
-   add_timer(&cs->hw.hfcsx.timer);
- */
+	add_timer(&cs->hw.hfcsx.timer);
+*/
 }
 
 /************************************************/
@@ -458,11 +458,11 @@ receive_dmsg(struct IsdnCardState *cs)
 	}
 
 	do {
-	  skb = read_fifo(cs, HFCSX_SEL_D_RX, 0);
-	  if (skb) {
-	    skb_queue_tail(&cs->rq, skb);
-	    schedule_event(cs, D_RCVBUFREADY);
-	  }
+		skb = read_fifo(cs, HFCSX_SEL_D_RX, 0);
+		if (skb) {
+			skb_queue_tail(&cs->rq, skb);
+			schedule_event(cs, D_RCVBUFREADY);
+		}
 	} while (--count && skb);
 
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -479,20 +479,20 @@ main_rec_hfcsx(struct BCState *bcs)
 	int count = 5;
 	struct sk_buff *skb;
 
-      Begin:
+Begin:
 	count--;
 	if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 		debugl1(cs, "rec_data %d blocked", bcs->channel);
 		return;
 	}
-	skb = read_fifo(cs, ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ? 
+	skb = read_fifo(cs, ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ?
 			HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX,
-			(bcs->mode == L1_MODE_TRANS) ? 
+			(bcs->mode == L1_MODE_TRANS) ?
 			HFCSX_BTRANS_THRESHOLD : 0);
 
 	if (skb) {
-	  skb_queue_tail(&bcs->rqueue, skb);
-	  schedule_event(bcs, B_RCVBUFREADY);
+		skb_queue_tail(&bcs->rqueue, skb);
+		schedule_event(bcs, B_RCVBUFREADY);
 	}
 
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -513,8 +513,8 @@ hfcsx_fill_dfifo(struct IsdnCardState *cs)
 		return;
 
 	if (write_fifo(cs, cs->tx_skb, HFCSX_SEL_D_TX, 0)) {
-	  dev_kfree_skb_any(cs->tx_skb);
-	  cs->tx_skb = NULL;
+		dev_kfree_skb_any(cs->tx_skb);
+		cs->tx_skb = NULL;
 	}
 	return;
 }
@@ -532,24 +532,24 @@ hfcsx_fill_fifo(struct BCState *bcs)
 	if (bcs->tx_skb->len <= 0)
 		return;
 
-	if (write_fifo(cs, bcs->tx_skb, 
-		       ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ? 
+	if (write_fifo(cs, bcs->tx_skb,
+		       ((bcs->channel) && (!cs->hw.hfcsx.bswapped)) ?
 		       HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX,
-		       (bcs->mode == L1_MODE_TRANS) ? 
+		       (bcs->mode == L1_MODE_TRANS) ?
 		       HFCSX_BTRANS_THRESHOLD : 0)) {
 
-	  bcs->tx_cnt -= bcs->tx_skb->len;
-	  if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-		(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
-		u_long	flags;
-		spin_lock_irqsave(&bcs->aclock, flags);
-		bcs->ackcnt += bcs->tx_skb->len;
-		spin_unlock_irqrestore(&bcs->aclock, flags);
-		schedule_event(bcs, B_ACKPENDING);
-	  }
-	  dev_kfree_skb_any(bcs->tx_skb);
-	  bcs->tx_skb = NULL;
-	  test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		bcs->tx_cnt -= bcs->tx_skb->len;
+		if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+		    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+			u_long	flags;
+			spin_lock_irqsave(&bcs->aclock, flags);
+			bcs->ackcnt += bcs->tx_skb->len;
+			spin_unlock_irqrestore(&bcs->aclock, flags);
+			schedule_event(bcs, B_ACKPENDING);
+		}
+		dev_kfree_skb_any(bcs->tx_skb);
+		bcs->tx_skb = NULL;
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 	}
 }
 
@@ -562,27 +562,27 @@ dch_nt_l2l1(struct PStack *st, int pr, void *arg)
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-		case (PH_PULL | REQUEST):
-		case (PH_PULL | INDICATION):
-			st->l1.l1hw(st, pr, arg);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
-			break;
-		case (PH_TESTLOOP | REQUEST):
-			if (1 & (long) arg)
-				debugl1(cs, "PH_TEST_LOOP B1");
-			if (2 & (long) arg)
-				debugl1(cs, "PH_TEST_LOOP B2");
-			if (!(3 & (long) arg))
-				debugl1(cs, "PH_TEST_LOOP DISABLED");
-			st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
-			break;
-		default:
-			if (cs->debug)
-				debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);
-			break;
+	case (PH_DATA | REQUEST):
+	case (PH_PULL | REQUEST):
+	case (PH_PULL | INDICATION):
+		st->l1.l1hw(st, pr, arg);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+		break;
+	case (PH_TESTLOOP | REQUEST):
+		if (1 & (long) arg)
+			debugl1(cs, "PH_TEST_LOOP B1");
+		if (2 & (long) arg)
+			debugl1(cs, "PH_TEST_LOOP B2");
+		if (!(3 & (long) arg))
+			debugl1(cs, "PH_TEST_LOOP DISABLED");
+		st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
+		break;
+	default:
+		if (cs->debug)
+			debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr);
+		break;
 	}
 }
 
@@ -592,14 +592,14 @@ dch_nt_l2l1(struct PStack *st, int pr, void *arg)
 /* set/reset echo mode */
 /***********************/
 static int
-hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic)
+hfcsx_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic)
 {
 	unsigned long flags;
 	int i = *(unsigned int *) ic->parm.num;
 
 	if ((ic->arg == 98) &&
 	    (!(cs->hw.hfcsx.int_m1 & (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC + HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC)))) {
-	    	spin_lock_irqsave(&cs->lock, flags);
+		spin_lock_irqsave(&cs->lock, flags);
 		Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 0);	/* HFC ST G0 */
 		udelay(10);
 		cs->hw.hfcsx.sctrl |= SCTRL_MODE_NT;
@@ -660,26 +660,26 @@ receive_emsg(struct IsdnCardState *cs)
 		return;
 	}
 	do {
-	  skb = read_fifo(cs, HFCSX_SEL_B2_RX, 0);
-	  if (skb) {
-	    if (cs->debug & DEB_DLOG_HEX) {
-	      ptr = cs->dlog;
-	      if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
-		*ptr++ = 'E';
-		*ptr++ = 'C';
-		*ptr++ = 'H';
-		*ptr++ = 'O';
-		*ptr++ = ':';
-		ptr += QuickHex(ptr, skb->data, skb->len);
-		ptr--;
-		*ptr++ = '\n';
-		*ptr = 0;
-		HiSax_putstatus(cs, NULL, cs->dlog);
-	      } else
-		HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len);
-	    }
-	    dev_kfree_skb_any(skb);
-	  }
+		skb = read_fifo(cs, HFCSX_SEL_B2_RX, 0);
+		if (skb) {
+			if (cs->debug & DEB_DLOG_HEX) {
+				ptr = cs->dlog;
+				if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
+					*ptr++ = 'E';
+					*ptr++ = 'C';
+					*ptr++ = 'H';
+					*ptr++ = 'O';
+					*ptr++ = ':';
+					ptr += QuickHex(ptr, skb->data, skb->len);
+					ptr--;
+					*ptr++ = '\n';
+					*ptr = 0;
+					HiSax_putstatus(cs, NULL, cs->dlog);
+				} else
+					HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len);
+			}
+			dev_kfree_skb_any(skb);
+		}
 	} while (--count && skb);
 
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -843,7 +843,7 @@ hfcsx_interrupt(int intno, void *dev_id)
 			} else
 				schedule_event(cs, D_XMTBUFREADY);
 		}
-	      afterXPR:
+	afterXPR:
 		if (cs->hw.hfcsx.int_s1 && count--) {
 			val = cs->hw.hfcsx.int_s1;
 			cs->hw.hfcsx.int_s1 = 0;
@@ -875,128 +875,128 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
-#ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-				if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
-				        hfcsx_fill_dfifo(cs); 
-					test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
-				} else
-					debugl1(cs, "hfcsx_fill_dfifo blocked");
-
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
 			if (cs->debug & L1_DEB_LAPD)
-				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+				Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
 			if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
-				hfcsx_fill_dfifo(cs); 
+				hfcsx_fill_dfifo(cs);
 				test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 			} else
 				debugl1(cs, "hfcsx_fill_dfifo blocked");
+
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			break;
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD)
+			Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 3);	/* HFC ST 3 */
-			udelay(6);
-			Write_hfc(cs, HFCSX_STATES, 3);	/* HFC ST 2 */
-			cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
-			Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
-			Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-		case (HW_ENABLE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_DEACTIVATE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcsx.mst_m &= ~HFCSX_MASTER;
-			Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO3 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
-			Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
+		if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
+			hfcsx_fill_dfifo(cs);
+			test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
+		} else
+			debugl1(cs, "hfcsx_fill_dfifo blocked");
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG		/* psa */
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		Write_hfc(cs, HFCSX_STATES, HFCSX_LOAD_STATE | 3);	/* HFC ST 3 */
+		udelay(6);
+		Write_hfc(cs, HFCSX_STATES, 3);	/* HFC ST 2 */
+		cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
+		Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
+		Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		break;
+	case (HW_ENABLE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		Write_hfc(cs, HFCSX_STATES, HFCSX_ACTIVATE | HFCSX_DO_ACTION);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_DEACTIVATE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcsx.mst_m &= ~HFCSX_MASTER;
+		Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO3 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcsx.mst_m |= HFCSX_MASTER;
+		Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_TESTLOOP | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		switch ((long) arg) {
+		case (1):
+			Write_hfc(cs, HFCSX_B1_SSL, 0x80);	/* tx slot */
+			Write_hfc(cs, HFCSX_B1_RSL, 0x80);	/* rx slot */
+			cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~7) | 1;
+			Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 			break;
-		case (HW_TESTLOOP | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			switch ((long) arg) {
-				case (1):
-					Write_hfc(cs, HFCSX_B1_SSL, 0x80);	/* tx slot */
-					Write_hfc(cs, HFCSX_B1_RSL, 0x80);	/* rx slot */
-					cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~7) | 1;
-					Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
-					break;
-				case (2):
-					Write_hfc(cs, HFCSX_B2_SSL, 0x81);	/* tx slot */
-					Write_hfc(cs, HFCSX_B2_RSL, 0x81);	/* rx slot */
-					cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~0x38) | 0x08;
-					Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
-					break;
-				default:
-					spin_unlock_irqrestore(&cs->lock, flags);
-					if (cs->debug & L1_DEB_WARN)
-						debugl1(cs, "hfcsx_l1hw loop invalid %4lx", (unsigned long)arg);
-					return;
-			}
-			cs->hw.hfcsx.trm |= 0x80;	/* enable IOM-loop */
-			Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
-			spin_unlock_irqrestore(&cs->lock, flags);
+		case (2):
+			Write_hfc(cs, HFCSX_B2_SSL, 0x81);	/* tx slot */
+			Write_hfc(cs, HFCSX_B2_RSL, 0x81);	/* rx slot */
+			cs->hw.hfcsx.conn = (cs->hw.hfcsx.conn & ~0x38) | 0x08;
+			Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 			break;
 		default:
+			spin_unlock_irqrestore(&cs->lock, flags);
 			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "hfcsx_l1hw unknown pr %4x", pr);
-			break;
+				debugl1(cs, "hfcsx_l1hw loop invalid %4lx", (unsigned long)arg);
+			return;
+		}
+		cs->hw.hfcsx.trm |= 0x80;	/* enable IOM-loop */
+		Write_hfc(cs, HFCSX_TRM, cs->hw.hfcsx.trm);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "hfcsx_l1hw unknown pr %4x", pr);
+		break;
 	}
 }
 
@@ -1018,7 +1018,7 @@ hfcsx_send_data(struct BCState *bcs)
 	struct IsdnCardState *cs = bcs->cs;
 
 	if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
-	  hfcsx_fill_fifo(bcs);
+		hfcsx_fill_fifo(bcs);
 		test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 	} else
 		debugl1(cs, "send_data %d blocked", bcs->channel);
@@ -1058,69 +1058,69 @@ mode_hfcsx(struct BCState *bcs, int mode, int bc)
 		}
 	}
 	switch (mode) {
-		case (L1_MODE_NULL):
-			if (bc) {
-				cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA;
-				cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcsx.sctrl &= ~SCTRL_B1_ENA;
-				cs->hw.hfcsx.sctrl_r &= ~SCTRL_B1_ENA;
-			}
-			if (fifo2) {
-				cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
-			} else {
-				cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
-			}
-			break;
-		case (L1_MODE_TRANS):
-			if (bc) {
-				cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
-				cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
-				cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
-			}
-			if (fifo2) {
-				cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
-				cs->hw.hfcsx.ctmt |= 2;
-				cs->hw.hfcsx.conn &= ~0x18;
-			} else {
-				cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
-				cs->hw.hfcsx.ctmt |= 1;
-				cs->hw.hfcsx.conn &= ~0x03;
-			}
-			break;
-		case (L1_MODE_HDLC):
-			if (bc) {
-				cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
-				cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
-			} else {
-				cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
-				cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
-			}
-			if (fifo2) {
-				cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
-				cs->hw.hfcsx.ctmt &= ~2;
-				cs->hw.hfcsx.conn &= ~0x18;
-			} else {
-				cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
-				cs->hw.hfcsx.ctmt &= ~1;
-				cs->hw.hfcsx.conn &= ~0x03;
-			}
-			break;
-		case (L1_MODE_EXTRN):
-			if (bc) {
-				cs->hw.hfcsx.conn |= 0x10;
-				cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
-				cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
-				cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
-			} else {
-				cs->hw.hfcsx.conn |= 0x02;
-				cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
-				cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
-				cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
-			}
-			break;
+	case (L1_MODE_NULL):
+		if (bc) {
+			cs->hw.hfcsx.sctrl &= ~SCTRL_B2_ENA;
+			cs->hw.hfcsx.sctrl_r &= ~SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcsx.sctrl &= ~SCTRL_B1_ENA;
+			cs->hw.hfcsx.sctrl_r &= ~SCTRL_B1_ENA;
+		}
+		if (fifo2) {
+			cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
+		} else {
+			cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
+		}
+		break;
+	case (L1_MODE_TRANS):
+		if (bc) {
+			cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
+			cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
+			cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
+		}
+		if (fifo2) {
+			cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
+			cs->hw.hfcsx.ctmt |= 2;
+			cs->hw.hfcsx.conn &= ~0x18;
+		} else {
+			cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
+			cs->hw.hfcsx.ctmt |= 1;
+			cs->hw.hfcsx.conn &= ~0x03;
+		}
+		break;
+	case (L1_MODE_HDLC):
+		if (bc) {
+			cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
+			cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
+		} else {
+			cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
+			cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
+		}
+		if (fifo2) {
+			cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
+			cs->hw.hfcsx.ctmt &= ~2;
+			cs->hw.hfcsx.conn &= ~0x18;
+		} else {
+			cs->hw.hfcsx.int_m1 |= (HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
+			cs->hw.hfcsx.ctmt &= ~1;
+			cs->hw.hfcsx.conn &= ~0x03;
+		}
+		break;
+	case (L1_MODE_EXTRN):
+		if (bc) {
+			cs->hw.hfcsx.conn |= 0x10;
+			cs->hw.hfcsx.sctrl |= SCTRL_B2_ENA;
+			cs->hw.hfcsx.sctrl_r |= SCTRL_B2_ENA;
+			cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B2TRANS + HFCSX_INTS_B2REC);
+		} else {
+			cs->hw.hfcsx.conn |= 0x02;
+			cs->hw.hfcsx.sctrl |= SCTRL_B1_ENA;
+			cs->hw.hfcsx.sctrl_r |= SCTRL_B1_ENA;
+			cs->hw.hfcsx.int_m1 &= ~(HFCSX_INTS_B1TRANS + HFCSX_INTS_B1REC);
+		}
+		break;
 	}
 	Write_hfc(cs, HFCSX_SCTRL_E, cs->hw.hfcsx.sctrl_e);
 	Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
@@ -1129,8 +1129,8 @@ mode_hfcsx(struct BCState *bcs, int mode, int bc)
 	Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt);
 	Write_hfc(cs, HFCSX_CONNECT, cs->hw.hfcsx.conn);
 	if (mode != L1_MODE_EXTRN) {
-	  reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX);
-	  reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX);
+		reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_RX : HFCSX_SEL_B1_RX);
+		reset_fifo(cs, fifo2 ? HFCSX_SEL_B2_TX : HFCSX_SEL_B1_TX);
 	}
 }
 
@@ -1145,53 +1145,53 @@ hfcsx_l2l1(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
 //                              test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
-			} else {
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
+		} else {
 //				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->tx_skb = skb;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			mode_hfcsx(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			mode_hfcsx(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+			bcs->tx_skb = skb;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		mode_hfcsx(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		mode_hfcsx(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -1260,61 +1260,61 @@ hfcsx_bh(struct work_struct *work)
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		if (!cs->hw.hfcsx.nt_mode)
 			switch (cs->dc.hfcsx.ph_state) {
-				case (0):
-					l1_msg(cs, HW_RESET | INDICATION, NULL);
-					break;
-				case (3):
-					l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-					break;
-				case (8):
-					l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-					break;
-				case (6):
-					l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-					break;
-				case (7):
-					l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-					break;
-				default:
-					break;
-		} else {
+			case (0):
+				l1_msg(cs, HW_RESET | INDICATION, NULL);
+				break;
+			case (3):
+				l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+				break;
+			case (8):
+				l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+				break;
+			case (6):
+				l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+				break;
+			case (7):
+				l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+				break;
+			default:
+				break;
+			} else {
 			switch (cs->dc.hfcsx.ph_state) {
-				case (2):
-					spin_lock_irqsave(&cs->lock, flags);
-					if (cs->hw.hfcsx.nt_timer < 0) {
-						cs->hw.hfcsx.nt_timer = 0;
-						cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
-						Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
-						/* Clear already pending ints */
-						if (Read_hfc(cs, HFCSX_INT_S1));
-
-						Write_hfc(cs, HFCSX_STATES, 4 | HFCSX_LOAD_STATE);
-						udelay(10);
-						Write_hfc(cs, HFCSX_STATES, 4);
-						cs->dc.hfcsx.ph_state = 4;
-					} else {
-						cs->hw.hfcsx.int_m1 |= HFCSX_INTS_TIMER;
-						Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
-						cs->hw.hfcsx.ctmt &= ~HFCSX_AUTO_TIMER;
-						cs->hw.hfcsx.ctmt |= HFCSX_TIM3_125;
-						Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
-						Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
-						cs->hw.hfcsx.nt_timer = NT_T1_COUNT;
-						Write_hfc(cs, HFCSX_STATES, 2 | HFCSX_NT_G2_G3);	/* allow G2 -> G3 transition */
-					}
-					spin_unlock_irqrestore(&cs->lock, flags);
-					break;
-				case (1):
-				case (3):
-				case (4):
-					spin_lock_irqsave(&cs->lock, flags);
+			case (2):
+				spin_lock_irqsave(&cs->lock, flags);
+				if (cs->hw.hfcsx.nt_timer < 0) {
 					cs->hw.hfcsx.nt_timer = 0;
 					cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
 					Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
-					spin_unlock_irqrestore(&cs->lock, flags);
-					break;
-				default:
-					break;
+					/* Clear already pending ints */
+					if (Read_hfc(cs, HFCSX_INT_S1));
+
+					Write_hfc(cs, HFCSX_STATES, 4 | HFCSX_LOAD_STATE);
+					udelay(10);
+					Write_hfc(cs, HFCSX_STATES, 4);
+					cs->dc.hfcsx.ph_state = 4;
+				} else {
+					cs->hw.hfcsx.int_m1 |= HFCSX_INTS_TIMER;
+					Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
+					cs->hw.hfcsx.ctmt &= ~HFCSX_AUTO_TIMER;
+					cs->hw.hfcsx.ctmt |= HFCSX_TIM3_125;
+					Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
+					Write_hfc(cs, HFCSX_CTMT, cs->hw.hfcsx.ctmt | HFCSX_CLTIMER);
+					cs->hw.hfcsx.nt_timer = NT_T1_COUNT;
+					Write_hfc(cs, HFCSX_STATES, 2 | HFCSX_NT_G2_G3);	/* allow G2 -> G3 transition */
+				}
+				spin_unlock_irqrestore(&cs->lock, flags);
+				break;
+			case (1):
+			case (3):
+			case (4):
+				spin_lock_irqsave(&cs->lock, flags);
+				cs->hw.hfcsx.nt_timer = 0;
+				cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
+				Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
+				spin_unlock_irqrestore(&cs->lock, flags);
+				break;
+			default:
+				break;
 			}
 		}
 	}
@@ -1353,29 +1353,29 @@ hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "HFCSX: card_msg %x", mt);
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_hfcsx(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_RELEASE:
-			release_io_hfcsx(cs);
-			return (0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithfcsx(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			msleep(80);				/* Timeout 80ms */
-			/* now switch timer interrupt off */
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
-			Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
-			/* reinit mode reg */
-			Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return (0);
-		case CARD_TEST:
-			return (0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_hfcsx(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_hfcsx(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithfcsx(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		msleep(80);				/* Timeout 80ms */
+		/* now switch timer interrupt off */
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcsx.int_m1 &= ~HFCSX_INTS_TIMER;
+		Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
+		/* reinit mode reg */
+		Write_hfc(cs, HFCSX_MST_MODE, cs->hw.hfcsx.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
 	return (0);
 }
@@ -1383,7 +1383,7 @@ hfcsx_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 #ifdef __ISAPNP__
 static struct isapnp_device_id hfc_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), 
+	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
 	  (unsigned long) "Teles 16.3c2" },
 	{ 0, }
 };
@@ -1403,30 +1403,30 @@ setup_hfcsx(struct IsdnCard *card)
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d;
-		while(ipid->card_vendor) {
+		while (ipid->card_vendor) {
 			if ((pnp_c = pnp_find_card(ipid->card_vendor,
-				ipid->card_device, pnp_c))) {
+						   ipid->card_device, pnp_c))) {
 				pnp_d = NULL;
 				if ((pnp_d = pnp_find_dev(pnp_c,
-					ipid->vendor, ipid->function, pnp_d))) {
+							  ipid->vendor, ipid->function, pnp_d))) {
 					int err;
 
 					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)ipid->driver_data);
+					       (char *)ipid->driver_data);
 					pnp_disable_dev(pnp_d);
 					err = pnp_activate_dev(pnp_d);
-					if (err<0) {
+					if (err < 0) {
 						printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-							__func__, err);
-						return(0);
+						       __func__, err);
+						return (0);
 					}
 					card->para[1] = pnp_port_start(pnp_d, 0);
 					card->para[0] = pnp_irq(pnp_d, 0);
 					if (!card->para[0] || !card->para[1]) {
 						printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n",
-							card->para[0], card->para[1]);
+						       card->para[0], card->para[1]);
 						pnp_disable_dev(pnp_d);
-						return(0);
+						return (0);
 					}
 					break;
 				} else {
@@ -1435,10 +1435,10 @@ setup_hfcsx(struct IsdnCard *card)
 			}
 			ipid++;
 			pnp_c = NULL;
-		} 
+		}
 		if (!ipid->card_vendor) {
 			printk(KERN_INFO "HFC PnP: no ISAPnP card found\n");
-			return(0);
+			return (0);
 		}
 	}
 #endif
@@ -1447,47 +1447,47 @@ setup_hfcsx(struct IsdnCard *card)
 	cs->hw.hfcsx.int_s1 = 0;
 	cs->dc.hfcsx.ph_state = 0;
 	cs->hw.hfcsx.fifo = 255;
-	if ((cs->typ == ISDN_CTYPE_HFC_SX) || 
+	if ((cs->typ == ISDN_CTYPE_HFC_SX) ||
 	    (cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) {
-	        if ((!cs->hw.hfcsx.base) || !request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn")) {
-		  printk(KERN_WARNING
-			 "HiSax: HFC-SX io-base %#lx already in use\n",
-		          cs->hw.hfcsx.base);
-		  return(0);
+		if ((!cs->hw.hfcsx.base) || !request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn")) {
+			printk(KERN_WARNING
+			       "HiSax: HFC-SX io-base %#lx already in use\n",
+			       cs->hw.hfcsx.base);
+			return (0);
 		}
 		byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
 		byteout(cs->hw.hfcsx.base + 1,
 			((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
 		udelay(10);
-	        cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID);
-                switch (cs->hw.hfcsx.chip >> 4) {
-		  case 1: 
-		    tmp[0] ='+';
-		    break;
-		  case 9: 
-		    tmp[0] ='P';
-		    break;
-		  default:
-		    printk(KERN_WARNING
-			   "HFC-SX: invalid chip id 0x%x\n",
-			   cs->hw.hfcsx.chip >> 4);
-		    release_region(cs->hw.hfcsx.base, 2);
-		    return(0);
-		}  
+		cs->hw.hfcsx.chip = Read_hfc(cs, HFCSX_CHIP_ID);
+		switch (cs->hw.hfcsx.chip >> 4) {
+		case 1:
+			tmp[0] = '+';
+			break;
+		case 9:
+			tmp[0] = 'P';
+			break;
+		default:
+			printk(KERN_WARNING
+			       "HFC-SX: invalid chip id 0x%x\n",
+			       cs->hw.hfcsx.chip >> 4);
+			release_region(cs->hw.hfcsx.base, 2);
+			return (0);
+		}
 		if (!ccd_sp_irqtab[cs->irq & 0xF]) {
-		  printk(KERN_WARNING 
-			 "HFC_SX: invalid irq %d specified\n",cs->irq & 0xF);
-		  release_region(cs->hw.hfcsx.base, 2);
-		  return(0);
-		}  
+			printk(KERN_WARNING
+			       "HFC_SX: invalid irq %d specified\n", cs->irq & 0xF);
+			release_region(cs->hw.hfcsx.base, 2);
+			return (0);
+		}
 		if (!(cs->hw.hfcsx.extra = (void *)
 		      kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) {
-		  release_region(cs->hw.hfcsx.base, 2);
-		  printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
-		  return(0);
+			release_region(cs->hw.hfcsx.base, 2);
+			printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
+			return (0);
 		}
 		printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n",
-			tmp[0], (u_int) cs->hw.hfcsx.base, cs->irq, HZ);
+		       tmp[0], (u_int) cs->hw.hfcsx.base, cs->irq, HZ);
 		cs->hw.hfcsx.int_m2 = 0;	/* disable alle interrupts */
 		cs->hw.hfcsx.int_m1 = 0;
 		Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1);
diff --git a/drivers/isdn/hisax/hfc_sx.h b/drivers/isdn/hisax/hfc_sx.h
index 6792f13..eee85db 100644
--- a/drivers/isdn/hisax/hfc_sx.h
+++ b/drivers/isdn/hisax/hfc_sx.h
@@ -5,7 +5,7 @@
  * Author       Werner Cornelius
  *              based on existing driver for CCD HFC PCI cards
  * Copyright    by Werner Cornelius  <werner@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -48,7 +48,7 @@
 
 #define HFCSX_MST_EMOD  0x2D
 #define HFCSX_MST_MODE	0x2E
-#define HFCSX_CONNECT 	0x2F
+#define HFCSX_CONNECT	0x2F
 
 
 /* Interrupt and status registers */
@@ -56,22 +56,22 @@
 #define HFCSX_TRM       0x12
 #define HFCSX_B_MODE    0x13
 #define HFCSX_CHIP_ID   0x16
-#define HFCSX_CIRM  	0x18
+#define HFCSX_CIRM	0x18
 #define HFCSX_CTMT	0x19
-#define HFCSX_INT_M1  	0x1A
-#define HFCSX_INT_M2  	0x1B
-#define HFCSX_INT_S1  	0x1E
-#define HFCSX_INT_S2  	0x1F
-#define HFCSX_STATUS  	0x1C
+#define HFCSX_INT_M1	0x1A
+#define HFCSX_INT_M2	0x1B
+#define HFCSX_INT_S1	0x1E
+#define HFCSX_INT_S2	0x1F
+#define HFCSX_STATUS	0x1C
 
 /* S/T section registers */
 
-#define HFCSX_STATES  	0x30
-#define HFCSX_SCTRL  	0x31
+#define HFCSX_STATES	0x30
+#define HFCSX_SCTRL	0x31
 #define HFCSX_SCTRL_E   0x32
 #define HFCSX_SCTRL_R   0x33
-#define HFCSX_SQ  	0x34
-#define HFCSX_CLKDEL  	0x37
+#define HFCSX_SQ	0x34
+#define HFCSX_CLKDEL	0x37
 #define HFCSX_B1_REC    0x3C
 #define HFCSX_B1_SEND   0x3C
 #define HFCSX_B2_REC    0x3D
@@ -97,7 +97,7 @@
 
 /* bits in status register (READ) */
 #define HFCSX_SX_PROC    0x02
-#define HFCSX_NBUSY	 0x04 
+#define HFCSX_NBUSY	 0x04
 #define HFCSX_TIMER_ELAP 0x10
 #define HFCSX_STATINT	 0x20
 #define HFCSX_FRAMEINT	 0x40
@@ -117,7 +117,7 @@
 /* bits in CIRM (Write) */
 #define HFCSX_IRQ_SELMSK 0x07
 #define HFCSX_IRQ_SELDIS 0x00
-#define HFCSX_RESET  	 0x08
+#define HFCSX_RESET	 0x08
 #define HFCSX_FIFO_RESET 0x80
 
 
@@ -189,7 +189,7 @@
 /* structure holding additional dynamic data -> send marker */
 /************************************************************/
 struct hfcsx_extra {
-  unsigned short marker[2*(MAX_B_FRAMES+1) + (MAX_D_FRAMES+1)];
+	unsigned short marker[2 * (MAX_B_FRAMES + 1) + (MAX_D_FRAMES + 1)];
 };
 
 extern void main_irq_hfcsx(struct BCState *bcs);
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index f407de0..62c65bd 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -27,7 +27,7 @@
  *
  * See Version Histroy at the bottom of this file
  *
-*/
+ */
 
 #include <linux/types.h>
 #include <linux/stddef.h>
@@ -45,11 +45,11 @@
 #include "hfc_usb.h"
 
 static const char *hfcusb_revision =
-    "$Revision: 2.3.2.24 $ $Date: 2007/10/14 08:40:29 $ ";
+	"$Revision: 2.3.2.24 $ $Date: 2007/10/14 08:40:29 $ ";
 
 /* Hisax debug support
-*  debug flags defined in hfc_usb.h as HFCUSB_DBG_[*]
-*/
+ *  debug flags defined in hfc_usb.h as HFCUSB_DBG_[*]
+ */
 #define __debug_variable hfc_debug
 #include "hisax_debug.h"
 static u_int debug;
@@ -67,70 +67,70 @@ typedef struct {
 /* VID/PID device list */
 static struct usb_device_id hfcusb_idtab[] = {
 	{
-	 USB_DEVICE(0x0959, 0x2bd0),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_OFF, {4, 0, 2, 1},
-			   "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
+		USB_DEVICE(0x0959, 0x2bd0),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_OFF, {4, 0, 2, 1},
+					"ISDN USB TA (Cologne Chip HFC-S USB based)"}),
 	},
 	{
-	 USB_DEVICE(0x0675, 0x1688),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {1, 2, 0, 0},
-			   "DrayTek miniVigor 128 USB ISDN TA"}),
+		USB_DEVICE(0x0675, 0x1688),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {1, 2, 0, 0},
+					"DrayTek miniVigor 128 USB ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x07b0, 0x0007),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Billion tiny USB ISDN TA 128"}),
+		USB_DEVICE(0x07b0, 0x0007),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Billion tiny USB ISDN TA 128"}),
 	},
 	{
-	 USB_DEVICE(0x0742, 0x2008),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {4, 0, 2, 1},
-			   "Stollmann USB TA"}),
+		USB_DEVICE(0x0742, 0x2008),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {4, 0, 2, 1},
+					"Stollmann USB TA"}),
 	},
 	{
-	 USB_DEVICE(0x0742, 0x2009),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {4, 0, 2, 1},
-			   "Aceex USB ISDN TA"}),
+		USB_DEVICE(0x0742, 0x2009),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {4, 0, 2, 1},
+					"Aceex USB ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x0742, 0x200A),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {4, 0, 2, 1},
-			   "OEM USB ISDN TA"}),
+		USB_DEVICE(0x0742, 0x200A),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {4, 0, 2, 1},
+					"OEM USB ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x08e3, 0x0301),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {2, 0, 1, 4},
-			   "Olitec USB RNIS"}),
+		USB_DEVICE(0x08e3, 0x0301),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {2, 0, 1, 4},
+					"Olitec USB RNIS"}),
 	},
 	{
-	 USB_DEVICE(0x07fa, 0x0846),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Bewan Modem RNIS USB"}),
+		USB_DEVICE(0x07fa, 0x0846),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Bewan Modem RNIS USB"}),
 	},
 	{
-	 USB_DEVICE(0x07fa, 0x0847),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Djinn Numeris USB"}),
+		USB_DEVICE(0x07fa, 0x0847),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Djinn Numeris USB"}),
 	},
 	{
-	 USB_DEVICE(0x07b0, 0x0006),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {0x80, -64, -32, -16},
-			   "Twister ISDN TA"}),
+		USB_DEVICE(0x07b0, 0x0006),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {0x80, -64, -32, -16},
+					"Twister ISDN TA"}),
 	},
 	{
-	 USB_DEVICE(0x071d, 0x1005),
-	 .driver_info = (unsigned long) &((hfcsusb_vdata)
-			  {LED_SCHEME1, {0x02, 0, 0x01, 0x04},
-			   "Eicon DIVA USB 4.0"}),
+		USB_DEVICE(0x071d, 0x1005),
+		.driver_info = (unsigned long) &((hfcsusb_vdata)
+			{LED_SCHEME1, {0x02, 0, 0x01, 0x04},
+					"Eicon DIVA USB 4.0"}),
 	},
 	{ }
 };
@@ -177,7 +177,7 @@ typedef struct hfcusb_data {
 	int alt_used;		/* used alternate config */
 	int ctrl_paksize;	/* control pipe packet size */
 	int ctrl_in_pipe,	/* handles for control pipe */
-	    ctrl_out_pipe;
+		ctrl_out_pipe;
 	int cfg_used;		/* configuration index used */
 	int vend_idx;		/* vendor found */
 	int b_mode[2];		/* B-channel mode */
@@ -206,7 +206,7 @@ typedef struct hfcusb_data {
 } hfcusb_data;
 
 
-static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len,
+static void collect_rx_frame(usb_fifo *fifo, __u8 *data, int len,
 			     int finish);
 
 static inline const char *
@@ -220,24 +220,24 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
 }
 
 static void
-ctrl_start_transfer(hfcusb_data * hfc)
+ctrl_start_transfer(hfcusb_data *hfc)
 {
 	if (hfc->ctrl_cnt) {
 		hfc->ctrl_urb->pipe = hfc->ctrl_out_pipe;
-		hfc->ctrl_urb->setup_packet = (u_char *) & hfc->ctrl_write;
+		hfc->ctrl_urb->setup_packet = (u_char *)&hfc->ctrl_write;
 		hfc->ctrl_urb->transfer_buffer = NULL;
 		hfc->ctrl_urb->transfer_buffer_length = 0;
 		hfc->ctrl_write.wIndex =
-		    cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg);
+			cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg);
 		hfc->ctrl_write.wValue =
-		    cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val);
+			cpu_to_le16(hfc->ctrl_buff[hfc->ctrl_out_idx].reg_val);
 
 		usb_submit_urb(hfc->ctrl_urb, GFP_ATOMIC);	/* start transfer */
 	}
 }				/* ctrl_start_transfer */
 
 static int
-queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action)
+queue_control_request(hfcusb_data *hfc, __u8 reg, __u8 val, int action)
 {
 	ctrl_buft *buf;
 
@@ -271,7 +271,7 @@ ctrl_complete(struct urb *urb)
 
 /* write led data to auxport & invert if necessary */
 static void
-write_led(hfcusb_data * hfc, __u8 led_state)
+write_led(hfcusb_data *hfc, __u8 led_state)
 {
 	if (led_state != hfc->old_led_state) {
 		hfc->old_led_state = led_state;
@@ -280,7 +280,7 @@ write_led(hfcusb_data * hfc, __u8 led_state)
 }
 
 static void
-set_led_bit(hfcusb_data * hfc, signed short led_bits, int on)
+set_led_bit(hfcusb_data *hfc, signed short led_bits, int on)
 {
 	if (on) {
 		if (led_bits < 0)
@@ -297,53 +297,53 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int on)
 
 /* handle LED requests */
 static void
-handle_led(hfcusb_data * hfc, int event)
+handle_led(hfcusb_data *hfc, int event)
 {
 	hfcsusb_vdata *driver_info =
-	    (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
+		(hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
 
 	/* if no scheme -> no LED action */
 	if (driver_info->led_scheme == LED_OFF)
 		return;
 
 	switch (event) {
-		case LED_POWER_ON:
-			set_led_bit(hfc, driver_info->led_bits[0], 1);
-			set_led_bit(hfc, driver_info->led_bits[1], 0);
-			set_led_bit(hfc, driver_info->led_bits[2], 0);
-			set_led_bit(hfc, driver_info->led_bits[3], 0);
-			break;
-		case LED_POWER_OFF:
-			set_led_bit(hfc, driver_info->led_bits[0], 0);
-			set_led_bit(hfc, driver_info->led_bits[1], 0);
-			set_led_bit(hfc, driver_info->led_bits[2], 0);
-			set_led_bit(hfc, driver_info->led_bits[3], 0);
-			break;
-		case LED_S0_ON:
-			set_led_bit(hfc, driver_info->led_bits[1], 1);
-			break;
-		case LED_S0_OFF:
-			set_led_bit(hfc, driver_info->led_bits[1], 0);
-			break;
-		case LED_B1_ON:
-			set_led_bit(hfc, driver_info->led_bits[2], 1);
-			break;
-		case LED_B1_OFF:
-			set_led_bit(hfc, driver_info->led_bits[2], 0);
-			break;
-		case LED_B2_ON:
-			set_led_bit(hfc, driver_info->led_bits[3], 1);
-			break;
-		case LED_B2_OFF:
-			set_led_bit(hfc, driver_info->led_bits[3], 0);
-			break;
+	case LED_POWER_ON:
+		set_led_bit(hfc, driver_info->led_bits[0], 1);
+		set_led_bit(hfc, driver_info->led_bits[1], 0);
+		set_led_bit(hfc, driver_info->led_bits[2], 0);
+		set_led_bit(hfc, driver_info->led_bits[3], 0);
+		break;
+	case LED_POWER_OFF:
+		set_led_bit(hfc, driver_info->led_bits[0], 0);
+		set_led_bit(hfc, driver_info->led_bits[1], 0);
+		set_led_bit(hfc, driver_info->led_bits[2], 0);
+		set_led_bit(hfc, driver_info->led_bits[3], 0);
+		break;
+	case LED_S0_ON:
+		set_led_bit(hfc, driver_info->led_bits[1], 1);
+		break;
+	case LED_S0_OFF:
+		set_led_bit(hfc, driver_info->led_bits[1], 0);
+		break;
+	case LED_B1_ON:
+		set_led_bit(hfc, driver_info->led_bits[2], 1);
+		break;
+	case LED_B1_OFF:
+		set_led_bit(hfc, driver_info->led_bits[2], 0);
+		break;
+	case LED_B2_ON:
+		set_led_bit(hfc, driver_info->led_bits[3], 1);
+		break;
+	case LED_B2_OFF:
+		set_led_bit(hfc, driver_info->led_bits[3], 0);
+		break;
 	}
 	write_led(hfc, hfc->led_state);
 }
 
 /* ISDN l1 timer T3 expires */
 static void
-l1_timer_expire_t3(hfcusb_data * hfc)
+l1_timer_expire_t3(hfcusb_data *hfc)
 {
 	hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
 			   NULL);
@@ -360,7 +360,7 @@ l1_timer_expire_t3(hfcusb_data * hfc)
 
 /* ISDN l1 timer T4 expires */
 static void
-l1_timer_expire_t4(hfcusb_data * hfc)
+l1_timer_expire_t4(hfcusb_data *hfc)
 {
 	hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
 			   NULL);
@@ -374,7 +374,7 @@ l1_timer_expire_t4(hfcusb_data * hfc)
 
 /* S0 state changed */
 static void
-s0_state_handler(hfcusb_data * hfc, __u8 state)
+s0_state_handler(hfcusb_data *hfc, __u8 state)
 {
 	__u8 old_state;
 
@@ -402,12 +402,12 @@ s0_state_handler(hfcusb_data * hfc, __u8 state)
 		DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
 		hfc->l1_activated = 1;
 		handle_led(hfc, LED_S0_ON);
-	} else if (state <= 3 /* && activated */ ) {
+	} else if (state <= 3 /* && activated */) {
 		if (old_state == 7 || old_state == 8) {
 			DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated");
 			if (!timer_pending(&hfc->t4_timer)) {
 				hfc->t4_timer.expires =
-				    jiffies + (HFC_TIMER_T4 * HZ) / 1000;
+					jiffies + (HFC_TIMER_T4 * HZ) / 1000;
 				add_timer(&hfc->t4_timer);
 			}
 		} else {
@@ -451,7 +451,7 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
  * gaps in the transfer chain
  */
 static int
-start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
+start_isoc_chain(usb_fifo *fifo, int num_packets_per_urb,
 		 usb_complete_t complete, int packet_size)
 {
 	int i, k, errcode;
@@ -463,7 +463,7 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
 	for (i = 0; i < 2; i++) {
 		if (!(fifo->iso[i].purb)) {
 			fifo->iso[i].purb =
-			    usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
+				usb_alloc_urb(num_packets_per_urb, GFP_KERNEL);
 			if (!(fifo->iso[i].purb)) {
 				printk(KERN_INFO
 				       "alloc urb for fifo %i failed!!!",
@@ -487,11 +487,11 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
 				/* defining packet delimeters in fifo->buffer */
 				for (k = 0; k < num_packets_per_urb; k++) {
 					fifo->iso[i].purb->
-					    iso_frame_desc[k].offset =
-					    k * packet_size;
+						iso_frame_desc[k].offset =
+						k * packet_size;
 					fifo->iso[i].purb->
-					    iso_frame_desc[k].length =
-					    packet_size;
+						iso_frame_desc[k].length =
+						packet_size;
 				}
 			} else {
 				printk(KERN_INFO
@@ -511,7 +511,7 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
 
 /* stops running iso chain and frees their pending urbs */
 static void
-stop_isoc_chain(usb_fifo * fifo)
+stop_isoc_chain(usb_fifo *fifo)
 {
 	int i;
 
@@ -534,8 +534,8 @@ stop_isoc_chain(usb_fifo * fifo)
 
 /* defines how much ISO packets are handled in one URB */
 static int iso_packets[8] =
-    { ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
-	ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
+{ ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B, ISOC_PACKETS_B,
+  ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
 };
 
 static void
@@ -545,7 +545,7 @@ tx_iso_complete(struct urb *urb)
 	usb_fifo *fifo = context_iso_urb->owner_fifo;
 	hfcusb_data *hfc = fifo->hfc;
 	int k, tx_offset, num_isoc_packets, sink, len, current_len,
-	    errcode;
+		errcode;
 	int frame_complete, transp_mode, fifon, status;
 	__u8 threshbit;
 
@@ -565,8 +565,8 @@ tx_iso_complete(struct urb *urb)
 			errcode = urb->iso_frame_desc[k].status;
 			if (errcode)
 				DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete "
-				       "packet %i, status: %i\n",
-				       k, errcode);
+				    "packet %i, status: %i\n",
+				    k, errcode);
 		}
 
 		// clear status, so go on with ISO transfers
@@ -607,8 +607,8 @@ tx_iso_complete(struct urb *urb)
 				if (current_len > 14)
 					current_len = 14;
 				current_len =
-				    (len <=
-				     current_len) ? len : current_len;
+					(len <=
+					 current_len) ? len : current_len;
 				/* how much bit do we put on the line? */
 				fifo->bit_line += current_len * 8;
 
@@ -617,7 +617,7 @@ tx_iso_complete(struct urb *urb)
 					if (!transp_mode) {
 						/* here frame completion */
 						context_iso_urb->
-						    buffer[tx_offset] = 1;
+							buffer[tx_offset] = 1;
 						/* add 2 byte flags and 16bit CRC at end of ISDN frame */
 						fifo->bit_line += 32;
 					}
@@ -632,12 +632,12 @@ tx_iso_complete(struct urb *urb)
 				/* define packet delimeters within the URB buffer */
 				urb->iso_frame_desc[k].offset = tx_offset;
 				urb->iso_frame_desc[k].length =
-				    current_len + 1;
+					current_len + 1;
 
 				tx_offset += (current_len + 1);
 			} else {
 				urb->iso_frame_desc[k].offset =
-				    tx_offset++;
+					tx_offset++;
 
 				urb->iso_frame_desc[k].length = 1;
 				fifo->bit_line -= sink;	/* we lower data margin every msec */
@@ -683,7 +683,7 @@ rx_iso_complete(struct urb *urb)
 	usb_fifo *fifo = context_iso_urb->owner_fifo;
 	hfcusb_data *hfc = fifo->hfc;
 	int k, len, errcode, offset, num_isoc_packets, fifon, maxlen,
-	    status;
+		status;
 	unsigned int iso_status;
 	__u8 *buf;
 	static __u8 eof[8];
@@ -723,10 +723,10 @@ rx_iso_complete(struct urb *urb)
 
 			if (fifon == HFCUSB_D_RX) {
 				DBG(HFCUSB_DBG_VERBOSE_USB,
-				       "HFC-S USB: ISO-D-RX lst_urblen:%2d "
-				       "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
-				       fifo->last_urblen, len, maxlen,
-				       eof[5]);
+				    "HFC-S USB: ISO-D-RX lst_urblen:%2d "
+				    "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
+				    fifo->last_urblen, len, maxlen,
+				    eof[5]);
 
 				DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
 			}
@@ -778,7 +778,7 @@ rx_iso_complete(struct urb *urb)
 
 /* collect rx data from INT- and ISO-URBs  */
 static void
-collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
+collect_rx_frame(usb_fifo *fifo, __u8 *data, int len, int finish)
 {
 	hfcusb_data *hfc = fifo->hfc;
 	int transp_mode, fifon;
@@ -802,8 +802,8 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
 			memcpy(skb_put(fifo->skbuff, len), data, len);
 		} else {
 			DBG(HFCUSB_DBG_FIFO_ERR,
-			       "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)",
-			       fifo->max_size, fifon);
+			    "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)",
+			    fifo->max_size, fifon);
 			DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
 			skb_trim(fifo->skbuff, 0);
 		}
@@ -817,7 +817,7 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
 	/* we have a complete hdlc packet */
 	if (finish) {
 		if (fifo->skbuff->len > 3 &&
-				!fifo->skbuff->data[fifo->skbuff->len - 1]) {
+		    !fifo->skbuff->data[fifo->skbuff->len - 1]) {
 
 			if (fifon == HFCUSB_D_RX) {
 				DBG(HFCUSB_DBG_DCHANNEL,
@@ -876,10 +876,10 @@ rx_int_complete(struct urb *urb)
 
 	if (fifon == HFCUSB_D_RX) {
 		DBG(HFCUSB_DBG_VERBOSE_USB,
-		       "HFC-S USB: INT-D-RX lst_urblen:%2d "
-		       "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
-		       fifo->last_urblen, len, maxlen,
-		       eof[5]);
+		    "HFC-S USB: INT-D-RX lst_urblen:%2d "
+		    "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
+		    fifo->last_urblen, len, maxlen,
+		    eof[5]);
 		DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
 	}
 
@@ -909,7 +909,7 @@ rx_int_complete(struct urb *urb)
 
 /* start initial INT-URB for certain fifo */
 static void
-start_int_fifo(usb_fifo * fifo)
+start_int_fifo(usb_fifo *fifo)
 {
 	int errcode;
 
@@ -936,7 +936,7 @@ start_int_fifo(usb_fifo * fifo)
 }
 
 static void
-setup_bchannel(hfcusb_data * hfc, int channel, int mode)
+setup_bchannel(hfcusb_data *hfc, int channel, int mode)
 {
 	__u8 val, idx_table[2] = { 0, 2 };
 
@@ -999,100 +999,100 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
 	hfcusb_data *hfc = fifo->hfc;
 
 	switch (pr) {
-		case PH_ACTIVATE | REQUEST:
-			if (fifo->fifonum == HFCUSB_D_TX) {
+	case PH_ACTIVATE | REQUEST:
+		if (fifo->fifonum == HFCUSB_D_TX) {
+			DBG(HFCUSB_DBG_STATES,
+			    "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST");
+
+			if (hfc->l1_state != 3
+			    && hfc->l1_state != 7) {
+				hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
+						   PH_DEACTIVATE |
+						   INDICATION,
+						   NULL);
 				DBG(HFCUSB_DBG_STATES,
-				    "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST");
-
-				if (hfc->l1_state != 3
-				    && hfc->l1_state != 7) {
-					hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
-							   PH_DEACTIVATE |
+				    "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)");
+			} else {
+				if (hfc->l1_state == 7) {	/* l1 already active */
+					hfc->d_if.ifc.l1l2(&hfc->
+							   d_if.
+							   ifc,
+							   PH_ACTIVATE
+							   |
 							   INDICATION,
 							   NULL);
 					DBG(HFCUSB_DBG_STATES,
-					    "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)");
+					    "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)");
 				} else {
-					if (hfc->l1_state == 7) {	/* l1 already active */
-						hfc->d_if.ifc.l1l2(&hfc->
-								   d_if.
-								   ifc,
-								   PH_ACTIVATE
-								   |
-								   INDICATION,
-								   NULL);
-						DBG(HFCUSB_DBG_STATES,
-						    "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)");
-					} else {
-						/* force sending sending INFO1 */
-						queue_control_request(hfc,
-								      HFCUSB_STATES,
-								      0x14,
-								      1);
-						mdelay(1);
-						/* start l1 activation */
-						queue_control_request(hfc,
-								      HFCUSB_STATES,
-								      0x04,
-								      1);
-						if (!timer_pending
-						    (&hfc->t3_timer)) {
-							hfc->t3_timer.
-							    expires =
-							    jiffies +
-							    (HFC_TIMER_T3 *
-							     HZ) / 1000;
-							add_timer(&hfc->
-								  t3_timer);
-						}
+					/* force sending sending INFO1 */
+					queue_control_request(hfc,
+							      HFCUSB_STATES,
+							      0x14,
+							      1);
+					mdelay(1);
+					/* start l1 activation */
+					queue_control_request(hfc,
+							      HFCUSB_STATES,
+							      0x04,
+							      1);
+					if (!timer_pending
+					    (&hfc->t3_timer)) {
+						hfc->t3_timer.
+							expires =
+							jiffies +
+							(HFC_TIMER_T3 *
+							 HZ) / 1000;
+						add_timer(&hfc->
+							  t3_timer);
 					}
 				}
-			} else {
-				DBG(HFCUSB_DBG_STATES,
-				    "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST");
-				setup_bchannel(hfc,
-					    (fifo->fifonum ==
-					     HFCUSB_B1_TX) ? 0 : 1,
-					    (long) arg);
-				fifo->hif->l1l2(fifo->hif,
-						PH_ACTIVATE | INDICATION,
-						NULL);
-			}
-			break;
-		case PH_DEACTIVATE | REQUEST:
-			if (fifo->fifonum == HFCUSB_D_TX) {
-				DBG(HFCUSB_DBG_STATES,
-				    "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST");
-			} else {
-				DBG(HFCUSB_DBG_STATES,
-				    "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST");
-				setup_bchannel(hfc,
-					    (fifo->fifonum ==
-					     HFCUSB_B1_TX) ? 0 : 1,
-					    (int) L1_MODE_NULL);
-				fifo->hif->l1l2(fifo->hif,
-						PH_DEACTIVATE | INDICATION,
-						NULL);
-			}
-			break;
-		case PH_DATA | REQUEST:
-			if (fifo->skbuff && fifo->delete_flg) {
-				dev_kfree_skb_any(fifo->skbuff);
-				fifo->skbuff = NULL;
-				fifo->delete_flg = 0;
 			}
-			fifo->skbuff = arg;	/* we have a new buffer */
-			break;
-		default:
+		} else {
+			DBG(HFCUSB_DBG_STATES,
+			    "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST");
+			setup_bchannel(hfc,
+				       (fifo->fifonum ==
+					HFCUSB_B1_TX) ? 0 : 1,
+				       (long) arg);
+			fifo->hif->l1l2(fifo->hif,
+					PH_ACTIVATE | INDICATION,
+					NULL);
+		}
+		break;
+	case PH_DEACTIVATE | REQUEST:
+		if (fifo->fifonum == HFCUSB_D_TX) {
+			DBG(HFCUSB_DBG_STATES,
+			    "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST");
+		} else {
 			DBG(HFCUSB_DBG_STATES,
-			       "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr);
-			break;
+			    "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST");
+			setup_bchannel(hfc,
+				       (fifo->fifonum ==
+					HFCUSB_B1_TX) ? 0 : 1,
+				       (int) L1_MODE_NULL);
+			fifo->hif->l1l2(fifo->hif,
+					PH_DEACTIVATE | INDICATION,
+					NULL);
+		}
+		break;
+	case PH_DATA | REQUEST:
+		if (fifo->skbuff && fifo->delete_flg) {
+			dev_kfree_skb_any(fifo->skbuff);
+			fifo->skbuff = NULL;
+			fifo->delete_flg = 0;
+		}
+		fifo->skbuff = arg;	/* we have a new buffer */
+		break;
+	default:
+		DBG(HFCUSB_DBG_STATES,
+		    "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr);
+		break;
 	}
 }
 
 /* initial init HFC-S USB chip registers, HiSax interface, USB URBs */
 static int
-hfc_usb_init(hfcusb_data * hfc)
+hfc_usb_init(hfcusb_data *hfc)
 {
 	usb_fifo *fifo;
 	int i;
@@ -1138,7 +1138,7 @@ hfc_usb_init(hfcusb_data * hfc)
 		write_usb(hfc, HFCUSB_FIFO, i);	/* select the desired fifo */
 		fifo[i].skbuff = NULL;	/* init buffer pointer */
 		fifo[i].max_size =
-		    (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
+			(i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
 		fifo[i].last_urblen = 0;
 		/* set 2 bit for D- & E-channel */
 		write_usb(hfc, HFCUSB_HDLC_PAR,
@@ -1185,7 +1185,7 @@ hfc_usb_init(hfcusb_data * hfc)
 	usb_fill_control_urb(hfc->ctrl_urb,
 			     hfc->dev,
 			     hfc->ctrl_out_pipe,
-			     (u_char *) & hfc->ctrl_write,
+			     (u_char *)&hfc->ctrl_write,
 			     NULL, 0, ctrl_complete, hfc);
 	/* Init All Fifos */
 	for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
@@ -1264,9 +1264,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	struct usb_host_endpoint *ep;
 	int ifnum = iface->desc.bInterfaceNumber;
 	int i, idx, alt_idx, probe_alt_setting, vend_idx, cfg_used, *vcf,
-	    attr, cfg_found, cidx, ep_addr;
+		attr, cfg_found, cidx, ep_addr;
 	int cmptbl[16], small_match, iso_packet_size, packet_size,
-	    alt_used = 0;
+		alt_used = 0;
 	hfcsusb_vdata *driver_info;
 
 	vend_idx = 0xffff;
@@ -1309,7 +1309,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 				for (i = 0; i < iface->desc.bNumEndpoints;
 				     i++) {
 					ep_addr =
-					    ep->desc.bEndpointAddress;
+						ep->desc.bEndpointAddress;
 					/* get endpoint base */
 					idx = ((ep_addr & 0x7f) - 1) * 2;
 					if (ep_addr & 0x80)
@@ -1345,7 +1345,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 					if (cfg_used < small_match) {
 						small_match = cfg_used;
 						alt_used =
-						    probe_alt_setting;
+							probe_alt_setting;
 						iface_used = iface;
 					}
 				}
@@ -1376,95 +1376,95 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 				if (vcf[idx] != EP_NOP
 				    && vcf[idx] != EP_NUL) {
 					switch (attr) {
-						case USB_ENDPOINT_XFER_INT:
-							context->
-							    fifos[cidx].
-							    pipe =
-							    usb_rcvintpipe
-							    (dev,
-							     ep->desc.
-							     bEndpointAddress);
+					case USB_ENDPOINT_XFER_INT:
+						context->
+							fifos[cidx].
+							pipe =
+							usb_rcvintpipe
+							(dev,
+							 ep->desc.
+							 bEndpointAddress);
+						context->
+							fifos[cidx].
+							usb_transfer_mode
+							= USB_INT;
+						packet_size =
+							le16_to_cpu(ep->desc.wMaxPacketSize);
+						break;
+					case USB_ENDPOINT_XFER_BULK:
+						if (ep_addr & 0x80)
 							context->
-							    fifos[cidx].
-							    usb_transfer_mode
-							    = USB_INT;
-							packet_size =
-							    le16_to_cpu(ep->desc.wMaxPacketSize);
-							break;
-						case USB_ENDPOINT_XFER_BULK:
-							if (ep_addr & 0x80)
-								context->
-								    fifos
-								    [cidx].
-								    pipe =
-								    usb_rcvbulkpipe
-								    (dev,
-								     ep->
-								     desc.
-								     bEndpointAddress);
-							else
-								context->
-								    fifos
-								    [cidx].
-								    pipe =
-								    usb_sndbulkpipe
-								    (dev,
-								     ep->
-								     desc.
-								     bEndpointAddress);
+								fifos
+								[cidx].
+								pipe =
+								usb_rcvbulkpipe
+								(dev,
+								 ep->
+								 desc.
+								 bEndpointAddress);
+						else
 							context->
-							    fifos[cidx].
-							    usb_transfer_mode
-							    = USB_BULK;
-							packet_size =
-							    le16_to_cpu(ep->desc.wMaxPacketSize);
-							break;
-						case USB_ENDPOINT_XFER_ISOC:
-							if (ep_addr & 0x80)
-								context->
-								    fifos
-								    [cidx].
-								    pipe =
-								    usb_rcvisocpipe
-								    (dev,
-								     ep->
-								     desc.
-								     bEndpointAddress);
-							else
-								context->
-								    fifos
-								    [cidx].
-								    pipe =
-								    usb_sndisocpipe
-								    (dev,
-								     ep->
-								     desc.
-								     bEndpointAddress);
+								fifos
+								[cidx].
+								pipe =
+								usb_sndbulkpipe
+								(dev,
+								 ep->
+								 desc.
+								 bEndpointAddress);
+						context->
+							fifos[cidx].
+							usb_transfer_mode
+							= USB_BULK;
+						packet_size =
+							le16_to_cpu(ep->desc.wMaxPacketSize);
+						break;
+					case USB_ENDPOINT_XFER_ISOC:
+						if (ep_addr & 0x80)
 							context->
-							    fifos[cidx].
-							    usb_transfer_mode
-							    = USB_ISOC;
-							iso_packet_size =
-							    le16_to_cpu(ep->desc.wMaxPacketSize);
-							break;
-						default:
+								fifos
+								[cidx].
+								pipe =
+								usb_rcvisocpipe
+								(dev,
+								 ep->
+								 desc.
+								 bEndpointAddress);
+						else
 							context->
-							    fifos[cidx].
-							    pipe = 0;
+								fifos
+								[cidx].
+								pipe =
+								usb_sndisocpipe
+								(dev,
+								 ep->
+								 desc.
+								 bEndpointAddress);
+						context->
+							fifos[cidx].
+							usb_transfer_mode
+							= USB_ISOC;
+						iso_packet_size =
+							le16_to_cpu(ep->desc.wMaxPacketSize);
+						break;
+					default:
+						context->
+							fifos[cidx].
+							pipe = 0;
 					}	/* switch attribute */
 
 					if (context->fifos[cidx].pipe) {
 						context->fifos[cidx].
-						    fifonum = cidx;
+							fifonum = cidx;
 						context->fifos[cidx].hfc =
-						    context;
+							context;
 						context->fifos[cidx].usb_packet_maxlen =
-						    le16_to_cpu(ep->desc.wMaxPacketSize);
+							le16_to_cpu(ep->desc.wMaxPacketSize);
 						context->fifos[cidx].
-						    intervall =
-						    ep->desc.bInterval;
+							intervall =
+							ep->desc.bInterval;
 						context->fifos[cidx].
-						    skbuff = NULL;
+							skbuff = NULL;
 					}
 				}
 				ep++;
@@ -1480,14 +1480,14 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 			/* create the control pipes needed for register access */
 			context->ctrl_in_pipe =
-			    usb_rcvctrlpipe(context->dev, 0);
+				usb_rcvctrlpipe(context->dev, 0);
 			context->ctrl_out_pipe =
-			    usb_sndctrlpipe(context->dev, 0);
+				usb_sndctrlpipe(context->dev, 0);
 			context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
 
 			driver_info =
-			    (hfcsusb_vdata *) hfcusb_idtab[vend_idx].
-			    driver_info;
+				(hfcsusb_vdata *) hfcusb_idtab[vend_idx].
+				driver_info;
 			printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
 			       driver_info->vend_name);
 
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index 2f581c0..f987bf8 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -76,11 +76,11 @@
 #define SINK_MIN	48
 #define SINK_DMIN	12
 #define SINK_DMAX	18
-#define BITLINE_INF	(-64*8)
+#define BITLINE_INF	(-64 * 8)
 
 /* HFC-S USB register access by Control-URSs */
-#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT)
-#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
+#define write_usb(a, b, c) usb_control_msg((a)->dev, (a)->ctrl_out_pipe, 0, 0x40, (c), (b), NULL, 0, HFC_CTRL_TIMEOUT)
+#define read_usb(a, b, c) usb_control_msg((a)->dev, (a)->ctrl_in_pipe, 1, 0xC0, 0, (b), (c), 1, HFC_CTRL_TIMEOUT)
 #define HFC_CTRL_BUFSIZE 32
 
 /* entry and size of output/input control buffer */
@@ -200,8 +200,8 @@ typedef struct {
 #define LED_B2_OFF	9
 #define LED_B2_DATA	10
 
-#define LED_NORMAL   	0	// LEDs are normal
-#define LED_INVERTED 	1	// LEDs are inverted
+#define LED_NORMAL	0	// LEDs are normal
+#define LED_INVERTED	1	// LEDs are inverted
 
 
 #endif	// __HFC_USB_H__
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
index 20d7688..a5f048b 100644
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -26,8 +26,8 @@ hfcs_interrupt(int intno, void *dev_id)
 	u_long flags;
 
 	spin_lock_irqsave(&cs->lock, flags);
-	if ((HFCD_ANYINT | HFCD_BUSY_NBUSY) & 
-		(stat = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_STAT))) {
+	if ((HFCD_ANYINT | HFCD_BUSY_NBUSY) &
+	    (stat = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_STAT))) {
 		val = cs->BC_Read_Reg(cs, HFCD_DATA, HFCD_INT_S1);
 		if (cs->debug & L1_DEB_ISAC)
 			debugl1(cs, "HFCS: stat(%02x) s1(%02x)", stat, val);
@@ -106,57 +106,57 @@ hfcs_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "HFCS: card_msg %x", mt);
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_hfcs(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_hfcs(cs);
-			return(0);
-		case CARD_INIT:
-			delay = (75*HZ)/100 +1;
-			mod_timer(&cs->hw.hfcD.timer, jiffies + delay);
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_hfcs(cs);
-			init2bds0(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			delay = (80*HZ)/1000 +1;
-			msleep(80);
-			spin_lock_irqsave(&cs->lock, flags);
-			cs->hw.hfcD.ctmt |= HFCD_TIM800;
-			cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); 
-			cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_hfcs(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_hfcs(cs);
+		return (0);
+	case CARD_INIT:
+		delay = (75 * HZ) / 100 + 1;
+		mod_timer(&cs->hw.hfcD.timer, jiffies + delay);
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_hfcs(cs);
+		init2bds0(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		delay = (80 * HZ) / 1000 + 1;
+		msleep(80);
+		spin_lock_irqsave(&cs->lock, flags);
+		cs->hw.hfcD.ctmt |= HFCD_TIM800;
+		cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt);
+		cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 #ifdef __ISAPNP__
 static struct isapnp_device_id hfc_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
-	  ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), 
+	  ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
 	  (unsigned long) "Acer P10" },
 	{ ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002),
-	  ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002), 
+	  ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002),
 	  (unsigned long) "Billion 2" },
 	{ ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001),
-	  ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001), 
+	  ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001),
 	  (unsigned long) "Billion 1" },
 	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410), 
+	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410),
 	  (unsigned long) "IStar PnP" },
 	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610), 
+	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610),
 	  (unsigned long) "Teles 16.3c" },
 	{ ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001),
-	  ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001), 
+	  ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001),
 	  (unsigned long) "Tornado Tipa C" },
 	{ ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001),
-	  ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001), 
+	  ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001),
 	  (unsigned long) "Genius Speed Surfer" },
 	{ 0, }
 };
@@ -177,30 +177,30 @@ setup_hfcs(struct IsdnCard *card)
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d;
-		while(ipid->card_vendor) {
+		while (ipid->card_vendor) {
 			if ((pnp_c = pnp_find_card(ipid->card_vendor,
-				ipid->card_device, pnp_c))) {
+						   ipid->card_device, pnp_c))) {
 				pnp_d = NULL;
 				if ((pnp_d = pnp_find_dev(pnp_c,
-					ipid->vendor, ipid->function, pnp_d))) {
+							  ipid->vendor, ipid->function, pnp_d))) {
 					int err;
 
 					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)ipid->driver_data);
+					       (char *)ipid->driver_data);
 					pnp_disable_dev(pnp_d);
 					err = pnp_activate_dev(pnp_d);
-					if (err<0) {
+					if (err < 0) {
 						printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-							__func__, err);
-						return(0);
+						       __func__, err);
+						return (0);
 					}
 					card->para[1] = pnp_port_start(pnp_d, 0);
 					card->para[0] = pnp_irq(pnp_d, 0);
 					if (!card->para[0] || !card->para[1]) {
 						printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n",
-							card->para[0], card->para[1]);
+						       card->para[0], card->para[1]);
 						pnp_disable_dev(pnp_d);
-						return(0);
+						return (0);
 					}
 					break;
 				} else {
@@ -209,10 +209,10 @@ setup_hfcs(struct IsdnCard *card)
 			}
 			ipid++;
 			pnp_c = NULL;
-		} 
+		}
 		if (!ipid->card_vendor) {
 			printk(KERN_INFO "HFC PnP: no ISAPnP card found\n");
-			return(0);
+			return (0);
 		}
 	}
 #endif
@@ -229,7 +229,7 @@ setup_hfcs(struct IsdnCard *card)
 	if (cs->typ == ISDN_CTYPE_TELES3C) {
 		cs->hw.hfcD.bfifosize = 1024 + 512;
 	} else if (cs->typ == ISDN_CTYPE_ACERP10) {
-		cs->hw.hfcD.bfifosize = 7*1024 + 512;
+		cs->hw.hfcD.bfifosize = 7 * 1024 + 512;
 	} else
 		return (0);
 	if (!request_region(cs->hw.hfcD.addr, 2, "HFCS isdn")) {
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index aff45a1..6ead6314 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -133,15 +133,15 @@ extern const char *tei_revision;
 
 /* include l3dss1 & ni1 specific process structures, but no other defines */
 #ifdef CONFIG_HISAX_EURO
-  #define l3dss1_process
-  #include "l3dss1.h" 
-  #undef  l3dss1_process
+#define l3dss1_process
+#include "l3dss1.h"
+#undef  l3dss1_process
 #endif /* CONFIG_HISAX_EURO */
 
 #ifdef CONFIG_HISAX_NI1
-  #define l3ni1_process
-  #include "l3ni1.h" 
-  #undef  l3ni1_process
+#define l3ni1_process
+#include "l3ni1.h"
+#undef  l3ni1_process
 #endif /* CONFIG_HISAX_NI1 */
 
 #define MAX_DFRAME_LEN	260
@@ -149,7 +149,7 @@ extern const char *tei_revision;
 #define HSCX_BUFMAX	4096
 #define MAX_DATA_SIZE	(HSCX_BUFMAX - 4)
 #define MAX_DATA_MEM	(HSCX_BUFMAX + 64)
-#define RAW_BUFMAX	(((HSCX_BUFMAX*6)/5) + 5)
+#define RAW_BUFMAX	(((HSCX_BUFMAX * 6) / 5) + 5)
 #define MAX_HEADER_LEN	4
 #define MAX_WINDOW	8
 #define MAX_MON_FRAME	32
@@ -165,7 +165,7 @@ extern const char *tei_revision;
 
 struct FsmInst;
 
-typedef void (* FSMFNPTR)(struct FsmInst *, int, void *);
+typedef void (*FSMFNPTR)(struct FsmInst *, int, void *);
 
 struct Fsm {
 	FSMFNPTR *jumpmatrix;
@@ -272,10 +272,10 @@ struct Layer2 {
 
 struct Layer3 {
 	void (*l3l4) (struct PStack *, int, void *);
-        void (*l3ml3) (struct PStack *, int, void *);
+	void (*l3ml3) (struct PStack *, int, void *);
 	void (*l3l2) (struct PStack *, int, void *);
 	struct FsmInst l3m;
-        struct FsmTimer l3m_timer;
+	struct FsmTimer l3m_timer;
 	struct sk_buff_head squeue;
 	struct l3_process *proc;
 	struct l3_process *global;
@@ -286,7 +286,7 @@ struct Layer3 {
 
 struct LLInterface {
 	void (*l4l3) (struct PStack *, int, void *);
-        int  (*l4l3_proto) (struct PStack *, isdn_ctrl *);
+	int  (*l4l3_proto) (struct PStack *, isdn_ctrl *);
 	void *userdata;
 	u_long flag;
 };
@@ -325,16 +325,16 @@ struct PStack {
 	struct Management ma;
 	int protocol;		/* EDSS1, 1TR6 or NI1 */
 
-        /* protocol specific data fields */
-        union
-	 { u_char uuuu; /* only as dummy */
+	/* protocol specific data fields */
+	union
+	{ u_char uuuu; /* only as dummy */
 #ifdef CONFIG_HISAX_EURO
-           dss1_stk_priv dss1; /* private dss1 data */
-#endif /* CONFIG_HISAX_EURO */              
+		dss1_stk_priv dss1; /* private dss1 data */
+#endif /* CONFIG_HISAX_EURO */
 #ifdef CONFIG_HISAX_NI1
-           ni1_stk_priv ni1; /* private ni1 data */
-#endif /* CONFIG_HISAX_NI1 */             
-	 } prot;
+		ni1_stk_priv ni1; /* private ni1 data */
+#endif /* CONFIG_HISAX_NI1 */
+	} prot;
 };
 
 struct l3_process {
@@ -347,18 +347,18 @@ struct l3_process {
 	struct Channel *chan;
 	struct PStack *st;
 	struct l3_process *next;
-        ulong redir_result;
-
-        /* protocol specific data fields */
-        union 
-	 { u_char uuuu; /* only when euro not defined, avoiding empty union */
-#ifdef CONFIG_HISAX_EURO 
-           dss1_proc_priv dss1; /* private dss1 data */
-#endif /* CONFIG_HISAX_EURO */            
+	ulong redir_result;
+
+	/* protocol specific data fields */
+	union
+	{ u_char uuuu; /* only when euro not defined, avoiding empty union */
+#ifdef CONFIG_HISAX_EURO
+		dss1_proc_priv dss1; /* private dss1 data */
+#endif /* CONFIG_HISAX_EURO */
 #ifdef CONFIG_HISAX_NI1
-           ni1_proc_priv ni1; /* private ni1 data */
-#endif /* CONFIG_HISAX_NI1 */             
-	 } prot;
+		ni1_proc_priv ni1; /* private ni1 data */
+#endif /* CONFIG_HISAX_NI1 */
+	} prot;
 };
 
 struct hscx_hw {
@@ -642,7 +642,7 @@ struct hfc_hw {
 	unsigned char cip;
 	u_char isac_spcr;
 	struct timer_list timer;
-};	
+};
 
 struct sedl_hw {
 	unsigned int cfg_reg;
@@ -693,25 +693,25 @@ struct hfcPCI_hw {
 	unsigned char int_m2;
 	unsigned char int_s1;
 	unsigned char sctrl;
-        unsigned char sctrl_r;
-        unsigned char sctrl_e;
-        unsigned char trm;
+	unsigned char sctrl_r;
+	unsigned char sctrl_e;
+	unsigned char trm;
 	unsigned char stat;
 	unsigned char fifo;
-        unsigned char fifo_en;
-        unsigned char bswapped;
-        unsigned char nt_mode;
-        int nt_timer;
-        struct pci_dev *dev;
-        unsigned char *pci_io; /* start of PCI IO memory */
+	unsigned char fifo_en;
+	unsigned char bswapped;
+	unsigned char nt_mode;
+	int nt_timer;
+	struct pci_dev *dev;
+	unsigned char *pci_io; /* start of PCI IO memory */
 	dma_addr_t dma; /* dma handle for Fifos */
-        void *fifos; /* FIFO memory */ 
-        int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
+	void *fifos; /* FIFO memory */
+	int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
 	struct timer_list timer;
 };
 
 struct hfcSX_hw {
-        unsigned long base;
+	unsigned long base;
 	unsigned char cirm;
 	unsigned char ctmt;
 	unsigned char conn;
@@ -720,18 +720,18 @@ struct hfcSX_hw {
 	unsigned char int_m2;
 	unsigned char int_s1;
 	unsigned char sctrl;
-        unsigned char sctrl_r;
-        unsigned char sctrl_e;
-        unsigned char trm;
+	unsigned char sctrl_r;
+	unsigned char sctrl_e;
+	unsigned char trm;
 	unsigned char stat;
 	unsigned char fifo;
-        unsigned char bswapped;
-        unsigned char nt_mode;
-        unsigned char chip;
-        int b_fifo_size;
-        unsigned char last_fifo;
-        void *extra;
-        int nt_timer;
+	unsigned char bswapped;
+	unsigned char nt_mode;
+	unsigned char chip;
+	int b_fifo_size;
+	unsigned char last_fifo;
+	void *extra;
+	int nt_timer;
 	struct timer_list timer;
 };
 
@@ -784,13 +784,13 @@ struct bkm_hw {
 	/* Scitel Quadro stuff */
 	unsigned long plx_adr;
 	unsigned long data_adr;
-};	
+};
 
 struct gazel_hw {
 	struct pci_dev *dev;
 	unsigned int cfg_reg;
 	unsigned int pciaddr[2];
-        signed   int ipac;
+	signed   int ipac;
 	signed   int isac;
 	signed   int hscx[2];
 	signed   int isacfifo;
@@ -877,8 +877,8 @@ struct icc_chip {
 #define HW_ARCOFI		3
 #define FLG_TWO_DCHAN		4
 #define FLG_L1_DBUSY		5
-#define FLG_DBUSY_TIMER 	6
-#define FLG_LOCK_ATOMIC 	7
+#define FLG_DBUSY_TIMER		6
+#define FLG_LOCK_ATOMIC		7
 #define FLG_ARCOFI_TIMER	8
 #define FLG_ARCOFI_ERROR	9
 #define FLG_HW_L1_UINT		10
@@ -892,8 +892,8 @@ struct IsdnCardState {
 	u_long		irq_flags;
 	u_long		HW_Flags;
 	int		*busy_flag;
-        int		chanlimit; /* limited number of B-chans to use */
-        int		logecho; /* log echo if supported by card */
+	int		chanlimit; /* limited number of B-chans to use */
+	int		logecho; /* log echo if supported by card */
 	union {
 		struct elsa_hw elsa;
 		struct teles0_hw teles0;
@@ -937,8 +937,8 @@ struct IsdnCardState {
 	void		(*DC_Close) (struct IsdnCardState *);
 	irq_handler_t	irq_func;
 	int		(*auxcmd) (struct IsdnCardState *, isdn_ctrl *);
-	struct Channel	channel[2+MAX_WAITING_CALLS];
-	struct BCState	bcs[2+MAX_WAITING_CALLS];
+	struct Channel	channel[2 + MAX_WAITING_CALLS];
+	struct BCState	bcs[2 + MAX_WAITING_CALLS];
 	struct PStack	*stlist;
 	struct sk_buff_head rq, sq; /* D-channel queues */
 	int		cardnr;
@@ -969,7 +969,7 @@ struct IsdnCardState {
 };
 
 
-#define  schedule_event(s, ev)	do {test_and_set_bit(ev, &s->event);schedule_work(&s->tqueue); } while(0)
+#define schedule_event(s, ev)	do { test_and_set_bit(ev, &s->event); schedule_work(&s->tqueue); } while (0)
 
 #define  MON0_RX	1
 #define  MON1_RX	2
@@ -1053,7 +1053,7 @@ struct IsdnCardState {
 #define CARD_IX1MICROR2 0
 #endif
 
-#ifdef  CONFIG_HISAX_DIEHLDIVA
+#ifdef CONFIG_HISAX_DIEHLDIVA
 #define CARD_DIEHLDIVA 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1062,7 +1062,7 @@ struct IsdnCardState {
 #define CARD_DIEHLDIVA 0
 #endif
 
-#ifdef  CONFIG_HISAX_ASUSCOM
+#ifdef CONFIG_HISAX_ASUSCOM
 #define CARD_ASUSCOM 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1071,7 +1071,7 @@ struct IsdnCardState {
 #define CARD_ASUSCOM 0
 #endif
 
-#ifdef  CONFIG_HISAX_TELEINT
+#ifdef CONFIG_HISAX_TELEINT
 #define CARD_TELEINT 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1080,7 +1080,7 @@ struct IsdnCardState {
 #define CARD_TELEINT 0
 #endif
 
-#ifdef  CONFIG_HISAX_SEDLBAUER
+#ifdef CONFIG_HISAX_SEDLBAUER
 #define CARD_SEDLBAUER 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1089,7 +1089,7 @@ struct IsdnCardState {
 #define CARD_SEDLBAUER 0
 #endif
 
-#ifdef  CONFIG_HISAX_SPORTSTER
+#ifdef CONFIG_HISAX_SPORTSTER
 #define CARD_SPORTSTER 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1098,7 +1098,7 @@ struct IsdnCardState {
 #define CARD_SPORTSTER 0
 #endif
 
-#ifdef  CONFIG_HISAX_MIC
+#ifdef CONFIG_HISAX_MIC
 #define CARD_MIC 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1107,7 +1107,7 @@ struct IsdnCardState {
 #define CARD_MIC 0
 #endif
 
-#ifdef  CONFIG_HISAX_NETJET
+#ifdef CONFIG_HISAX_NETJET
 #define CARD_NETJET_S 1
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
@@ -1206,7 +1206,7 @@ struct IsdnCardState {
 #define	CARD_W6692	0
 #endif
 
-#ifdef  CONFIG_HISAX_NETJET_U
+#ifdef CONFIG_HISAX_NETJET_U
 #define CARD_NETJET_U 1
 #ifndef ISDN_CHIP_ICC
 #define ISDN_CHIP_ICC 1
@@ -1269,8 +1269,8 @@ void setstack_l3dc(struct PStack *st, struct Channel *chanp);
 void setstack_l3bc(struct PStack *st, struct Channel *chanp);
 void releasestack_isdnl3(struct PStack *st);
 
-u_char *findie(u_char * p, int size, u_char ie, int wanted_set);
-int getcallref(u_char * p);
+u_char *findie(u_char *p, int size, u_char ie, int wanted_set);
+int getcallref(u_char *p);
 int newcallref(void);
 
 int FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount);
@@ -1279,36 +1279,36 @@ int FsmEvent(struct FsmInst *fi, int event, void *arg);
 void FsmChangeState(struct FsmInst *fi, int newstate);
 void FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft);
 int FsmAddTimer(struct FsmTimer *ft, int millisec, int event,
-	void *arg, int where);
+		void *arg, int where);
 void FsmRestartTimer(struct FsmTimer *ft, int millisec, int event,
-	void *arg, int where);
+		     void *arg, int where);
 void FsmDelTimer(struct FsmTimer *ft, int where);
 int jiftime(char *s, long mark);
 
-int HiSax_command(isdn_ctrl * ic);
+int HiSax_command(isdn_ctrl *ic);
 int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
 __printf(3, 4)
 void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
 __printf(3, 0)
 void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args);
 void HiSax_reportcard(int cardnr, int sel);
-int QuickHex(char *txt, u_char * p, int cnt);
-void LogFrame(struct IsdnCardState *cs, u_char * p, int size);
+int QuickHex(char *txt, u_char *p, int cnt);
+void LogFrame(struct IsdnCardState *cs, u_char *p, int size);
 void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
-void iecpy(u_char * dest, u_char * iestart, int ieoffset);
+void iecpy(u_char *dest, u_char *iestart, int ieoffset);
 #endif	/* __KERNEL__ */
 
 /*
  * Busywait delay for `jiffs' jiffies
  */
-#define HZDELAY(jiffs) do {					\
-		int tout = jiffs;				\
-								\
-		while (tout--) {				\
-			int loops = USEC_PER_SEC / HZ;		\
-			while (loops--)				\
-				udelay(1);			\
-		}						\
+#define HZDELAY(jiffs) do {				\
+		int tout = jiffs;			\
+							\
+		while (tout--) {			\
+			int loops = USEC_PER_SEC / HZ;	\
+			while (loops--)			\
+				udelay(1);		\
+		}					\
 	} while (0)
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
diff --git a/drivers/isdn/hisax/hisax_cfg.h b/drivers/isdn/hisax/hisax_cfg.h
index 17a2fea..487dcfe 100644
--- a/drivers/isdn/hisax/hisax_cfg.h
+++ b/drivers/isdn/hisax/hisax_cfg.h
@@ -54,9 +54,9 @@ typedef struct IsdnCardState	IsdnCardState_t;
 typedef struct IsdnCard		IsdnCard_t;
 
 struct IsdnCard {
-	int		typ;
-	int 		protocol;	/* EDSS1, 1TR6 or NI1 */
-	unsigned long	para[4];
+	int typ;
+	int protocol;	/* EDSS1, 1TR6 or NI1 */
+	unsigned long para[4];
 	IsdnCardState_t	*cs;
 };
 
diff --git a/drivers/isdn/hisax/hisax_debug.h b/drivers/isdn/hisax/hisax_debug.h
index 5ed3b1c..7b3093d 100644
--- a/drivers/isdn/hisax/hisax_debug.h
+++ b/drivers/isdn/hisax/hisax_debug.h
@@ -4,12 +4,12 @@
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
  *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
  * How to use:
- * 
+ *
  * Before including this file, you need to
  *   #define __debug_variable my_debug
  * where my_debug is a variable in your code which
@@ -25,45 +25,45 @@
 
 #ifdef CONFIG_HISAX_DEBUG
 
-#define DBG(level, format, arg...) do { \
-if (level & __debug_variable) \
-printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
-} while (0)
+#define DBG(level, format, arg...) do {					\
+		if (level & __debug_variable)				\
+			printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
+	} while (0)
 
-#define DBG_PACKET(level,data,count) \
-  if (level & __debug_variable) dump_packet(__func__,data,count)
+#define DBG_PACKET(level, data, count)					\
+	if (level & __debug_variable) dump_packet(__func__, data, count)
 
-#define DBG_SKB(level,skb) \
-  if ((level & __debug_variable) && skb) dump_packet(__func__,skb->data,skb->len)
+#define DBG_SKB(level, skb)						\
+	if ((level & __debug_variable) && skb) dump_packet(__func__, skb->data, skb->len)
 
 
 static void __attribute__((unused))
-dump_packet(const char *name,const u_char *data,int pkt_len)
+dump_packet(const char *name, const u_char *data, int pkt_len)
 {
 #define DUMP_HDR_SIZE 20
 #define DUMP_TLR_SIZE 8
 	if (pkt_len) {
-		int i,len1,len2;
+		int i, len1, len2;
 
-		printk(KERN_DEBUG "%s: length=%d,data=",name,pkt_len);
+		printk(KERN_DEBUG "%s: length=%d,data=", name, pkt_len);
 
-		if (pkt_len >  DUMP_HDR_SIZE+ DUMP_TLR_SIZE) {
+		if (pkt_len > DUMP_HDR_SIZE + DUMP_TLR_SIZE) {
 			len1 = DUMP_HDR_SIZE;
 			len2 = DUMP_TLR_SIZE;
 		} else {
 			len1 = pkt_len > DUMP_HDR_SIZE ? DUMP_HDR_SIZE : pkt_len;
-			len2 = 0;			
+			len2 = 0;
 		}
 		for (i = 0; i < len1; ++i) {
-		 	printk ("%.2x", data[i]);
+			printk("%.2x", data[i]);
 		}
 		if (len2) {
-		 	printk ("..");
+			printk("..");
 			for (i = pkt_len-DUMP_TLR_SIZE; i < pkt_len; ++i) {
-				printk ("%.2x", data[i]);
+				printk("%.2x", data[i]);
 			}
 		}
-		printk ("\n");
+		printk("\n");
 	}
 #undef DUMP_HDR_SIZE
 #undef DUMP_TLR_SIZE
@@ -72,8 +72,8 @@ dump_packet(const char *name,const u_char *data,int pkt_len)
 #else
 
 #define DBG(level, format, arg...) do {} while (0)
-#define DBG_PACKET(level,data,count) do {} while (0)
-#define DBG_SKB(level,skb) do {} while (0)
+#define DBG_PACKET(level, data, count) do {} while (0)
+#define DBG_SKB(level, skb) do {} while (0)
 
 #endif
 
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 478ebab..e4f47fe 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -4,7 +4,7 @@
  * Author       Kai Germaschewski
  * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
  *              2001 by Karsten Keil       <keil@isdn4linux.de>
- * 
+ *
  * based upon Karsten Keil's original avm_pci.c driver
  *
  * This software may be used and distributed according to the terms
@@ -71,7 +71,7 @@ MODULE_DEVICE_TABLE(pci, fcpci_ids);
 
 #ifdef CONFIG_PNP
 static struct pnp_device_id fcpnp_ids[] __devinitdata = {
-	{ 
+	{
 		.id		= "AVM0900",
 		.driver_data	= (unsigned long) "Fritz!Card PnP",
 	},
@@ -153,7 +153,7 @@ MODULE_LICENSE("GPL");
 static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
 {
 	struct fritz_adapter *adapter = isac->priv;
-	unsigned char idx = (offset > 0x2f) ? 
+	unsigned char idx = (offset > 0x2f) ?
 		AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
 	unsigned char val;
 	unsigned long flags;
@@ -161,7 +161,7 @@ static unsigned char fcpci_read_isac(struct isac *isac, unsigned char offset)
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outb(idx, adapter->io + AVM_INDEX);
 	val = inb(adapter->io + AVM_DATA + (offset & 0xf));
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 	DBG(0x1000, " port %#x, value %#x",
 	    offset, val);
 	return val;
@@ -171,7 +171,7 @@ static void fcpci_write_isac(struct isac *isac, unsigned char offset,
 			     unsigned char value)
 {
 	struct fritz_adapter *adapter = isac->priv;
-	unsigned char idx = (offset > 0x2f) ? 
+	unsigned char idx = (offset > 0x2f) ?
 		AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
 	unsigned long flags;
 
@@ -180,10 +180,10 @@ static void fcpci_write_isac(struct isac *isac, unsigned char offset,
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outb(idx, adapter->io + AVM_INDEX);
 	outb(value, adapter->io + AVM_DATA + (offset & 0xf));
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 }
 
-static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data, 
+static void fcpci_read_isac_fifo(struct isac *isac, unsigned char *data,
 				 int size)
 {
 	struct fritz_adapter *adapter = isac->priv;
@@ -192,10 +192,10 @@ static void fcpci_read_isac_fifo(struct isac *isac, unsigned char * data,
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
 	insb(adapter->io + AVM_DATA, data, size);
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 }
 
-static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data, 
+static void fcpci_write_isac_fifo(struct isac *isac, unsigned char *data,
 				  int size)
 {
 	struct fritz_adapter *adapter = isac->priv;
@@ -204,7 +204,7 @@ static void fcpci_write_isac_fifo(struct isac *isac, unsigned char * data,
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outb(AVM_IDX_ISAC_FIFO, adapter->io + AVM_INDEX);
 	outsb(adapter->io + AVM_DATA, data, size);
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 }
 
 static u32 fcpci_read_hdlc_status(struct fritz_adapter *adapter, int nr)
@@ -254,14 +254,14 @@ static unsigned char fcpci2_read_isac(struct isac *isac, unsigned char offset)
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outl(offset, adapter->io + AVM_ISACSX_INDEX);
 	val = inl(adapter->io + AVM_ISACSX_DATA);
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 	DBG(0x1000, " port %#x, value %#x",
 	    offset, val);
 
 	return val;
 }
 
-static void fcpci2_write_isac(struct isac *isac, unsigned char offset, 
+static void fcpci2_write_isac(struct isac *isac, unsigned char offset,
 			      unsigned char value)
 {
 	struct fritz_adapter *adapter = isac->priv;
@@ -272,10 +272,10 @@ static void fcpci2_write_isac(struct isac *isac, unsigned char offset,
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outl(offset, adapter->io + AVM_ISACSX_INDEX);
 	outl(value, adapter->io + AVM_ISACSX_DATA);
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 }
 
-static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data, 
+static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char *data,
 				  int size)
 {
 	struct fritz_adapter *adapter = isac->priv;
@@ -286,10 +286,10 @@ static void fcpci2_read_isac_fifo(struct isac *isac, unsigned char * data,
 	outl(0, adapter->io + AVM_ISACSX_INDEX);
 	for (i = 0; i < size; i++)
 		data[i] = inl(adapter->io + AVM_ISACSX_DATA);
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 }
 
-static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data, 
+static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char *data,
 				   int size)
 {
 	struct fritz_adapter *adapter = isac->priv;
@@ -300,7 +300,7 @@ static void fcpci2_write_isac_fifo(struct isac *isac, unsigned char * data,
 	outl(0, adapter->io + AVM_ISACSX_INDEX);
 	for (i = 0; i < size; i++)
 		outl(data[i], adapter->io + AVM_ISACSX_DATA);
- 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
+	spin_unlock_irqrestore(&adapter->hw_lock, flags);
 }
 
 static u32 fcpci2_read_hdlc_status(struct fritz_adapter *adapter, int nr)
@@ -349,10 +349,10 @@ static void __fcpnp_write_ctrl(struct fritz_bcs *bcs, int which)
 
 	outb(idx, adapter->io + AVM_INDEX);
 	if (which & 4)
-		outb(bcs->ctrl.sr.mode, 
+		outb(bcs->ctrl.sr.mode,
 		     adapter->io + AVM_DATA + HDLC_STATUS + 2);
 	if (which & 2)
-		outb(bcs->ctrl.sr.xml, 
+		outb(bcs->ctrl.sr.xml,
 		     adapter->io + AVM_DATA + HDLC_STATUS + 1);
 	if (which & 1)
 		outb(bcs->ctrl.sr.cmd,
@@ -416,7 +416,7 @@ static void hdlc_fill_fifo(struct fritz_bcs *bcs)
 		break;
 	case AVM_FRITZ_PCIV2:
 		fcpci2_write_ctrl(bcs, 3);
-		outsl(adapter->io + 
+		outsl(adapter->io +
 		      (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
 		      p, (count + 3) / 4);
 		break;
@@ -447,12 +447,12 @@ static inline void hdlc_empty_fifo(struct fritz_bcs *bcs, int count)
 	case AVM_FRITZ_PCI:
 		spin_lock(&adapter->hw_lock);
 		outl(idx, adapter->io + AVM_INDEX);
-		insl(adapter->io + AVM_DATA + HDLC_FIFO, 
+		insl(adapter->io + AVM_DATA + HDLC_FIFO,
 		     p, (count + 3) / 4);
 		spin_unlock(&adapter->hw_lock);
 		break;
 	case AVM_FRITZ_PCIV2:
-		insl(adapter->io + 
+		insl(adapter->io +
 		     (bcs->channel ? AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1),
 		     p, (count + 3) / 4);
 		break;
@@ -489,7 +489,7 @@ static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
 	hdlc_empty_fifo(bcs, len);
 
 	if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
-		if (((stat & HDLC_STAT_CRCVFRRAB)== HDLC_STAT_CRCVFR) ||
+		if (((stat & HDLC_STAT_CRCVFRRAB) == HDLC_STAT_CRCVFR) ||
 		    (bcs->mode == L1_MODE_TRANS)) {
 			skb = dev_alloc_skb(bcs->rcvidx);
 			if (!skb) {
@@ -512,7 +512,7 @@ static inline void hdlc_rpr_irq(struct fritz_bcs *bcs, u32 stat)
 static inline void hdlc_xdu_irq(struct fritz_bcs *bcs)
 {
 	struct fritz_adapter *adapter = bcs->adapter;
-	
+
 
 	/* Here we lost an TX interrupt, so
 	 * restart transmitting the whole frame.
@@ -587,7 +587,7 @@ static inline void hdlc_irq(struct fritz_adapter *adapter)
 static void modehdlc(struct fritz_bcs *bcs, int mode)
 {
 	struct fritz_adapter *adapter = bcs->adapter;
-	
+
 	DBG(0x40, "hdlc %c mode %d --> %d",
 	    'A' + bcs->channel, bcs->mode, mode);
 
@@ -638,12 +638,12 @@ static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
 		break;
 	case PH_ACTIVATE | REQUEST:
 		mode = (long) arg;
-		DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
+		DBG(4, "B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);
 		modehdlc(bcs, mode);
 		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
 		break;
 	case PH_DEACTIVATE | REQUEST:
-		DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
+		DBG(4, "B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
 		modehdlc(bcs, L1_MODE_NULL);
 		B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
 		break;
@@ -702,10 +702,10 @@ static inline void fcpci2_init(struct fritz_adapter *adapter)
 
 static inline void fcpci_init(struct fritz_adapter *adapter)
 {
-	outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 
+	outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER |
 	     AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
 
-	outb(AVM_STATUS1_ENA_IOM | adapter->irq, 
+	outb(AVM_STATUS1_ENA_IOM | adapter->irq,
 	     adapter->io + AVM_STATUS1);
 	mdelay(10);
 }
@@ -717,7 +717,7 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
 	u32 val = 0;
 	int retval;
 
-	DBG(1,"");
+	DBG(1, "");
 
 	isac_init(&adapter->isac); // FIXME is this okay now
 
@@ -737,7 +737,7 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
 	}
 
 	DBG(1, "stat %#x Class %X Rev %d",
-	    val, val & 0xff, (val>>8) & 0xff);
+	    val, val & 0xff, (val >> 8) & 0xff);
 
 	spin_lock_init(&adapter->hw_lock);
 	adapter->isac.priv = adapter;
@@ -819,15 +819,15 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
 
 	return 0;
 
- err_region:
+err_region:
 	release_region(adapter->io, 32);
- err:
+err:
 	return retval;
 }
 
 static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
 {
-	DBG(1,"");
+	DBG(1, "");
 
 	outb(0, adapter->io + AVM_STATUS0);
 	free_irq(adapter->irq, adapter);
@@ -836,7 +836,7 @@ static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
 
 // ----------------------------------------------------------------------
 
-static struct fritz_adapter * __devinit 
+static struct fritz_adapter * __devinit
 new_adapter(void)
 {
 	struct fritz_adapter *adapter;
@@ -850,7 +850,7 @@ new_adapter(void)
 	adapter->isac.hisax_d_if.owner = THIS_MODULE;
 	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
 	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
-	
+
 	for (i = 0; i < 2; i++) {
 		adapter->bcs[i].adapter = adapter;
 		adapter->bcs[i].channel = i;
@@ -862,7 +862,7 @@ new_adapter(void)
 		b_if[i] = &adapter->bcs[i].b_if;
 
 	if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp",
-			protocol) != 0) {
+			   protocol) != 0) {
 		kfree(adapter);
 		adapter = NULL;
 	}
@@ -889,7 +889,7 @@ static int __devinit fcpci_probe(struct pci_dev *pdev,
 
 	pci_set_drvdata(pdev, adapter);
 
-	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) 
+	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
 		adapter->type = AVM_FRITZ_PCIV2;
 	else
 		adapter->type = AVM_FRITZ_PCI;
@@ -909,10 +909,10 @@ static int __devinit fcpci_probe(struct pci_dev *pdev,
 		goto err_free;
 
 	return 0;
-	
- err_free:
+
+err_free:
 	delete_adapter(adapter);
- err:
+err:
 	return retval;
 }
 
@@ -923,7 +923,7 @@ static int __devinit fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_i
 	int retval;
 
 	if (!pdev)
-		return(-ENODEV);
+		return (-ENODEV);
 
 	retval = -ENOMEM;
 	adapter = new_adapter();
@@ -938,7 +938,7 @@ static int __devinit fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_i
 	retval = pnp_activate_dev(pdev);
 	if (retval < 0) {
 		printk(KERN_WARNING "%s: pnp_activate_dev(%s) ret(%d)\n", __func__,
-			(char *)dev_id->driver_data, retval);
+		       (char *)dev_id->driver_data, retval);
 		goto err_free;
 	}
 	adapter->io = pnp_port_start(pdev, 0);
@@ -952,10 +952,10 @@ static int __devinit fcpnp_probe(struct pnp_dev *pdev, const struct pnp_device_i
 		goto err_free;
 
 	return 0;
-	
- err_free:
+
+err_free:
 	delete_adapter(adapter);
- err:
+err:
 	return retval;
 }
 
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.h b/drivers/isdn/hisax/hisax_fcpcipnp.h
index 21fbced..aedef97 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.h
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.h
@@ -38,7 +38,7 @@ struct fritz_bcs {
 	int rcvidx;
 	int fifo_size;
 	u_char rcvbuf[HSCX_BUFMAX]; /* B-Channel receive Buffer */
-	
+
 	int tx_cnt;		    /* B-Channel transmit counter */
 	struct sk_buff *tx_skb;     /* B-Channel transmit Buffer */
 };
@@ -55,4 +55,3 @@ struct fritz_adapter {
 	u32  (*read_hdlc_status) (struct fritz_adapter *adapter, int nr);
 	void (*write_ctrl) (struct fritz_bcs *bcs, int which);
 };
-
diff --git a/drivers/isdn/hisax/hisax_if.h b/drivers/isdn/hisax/hisax_if.h
index aa7c940..7098d6b 100644
--- a/drivers/isdn/hisax/hisax_if.h
+++ b/drivers/isdn/hisax/hisax_if.h
@@ -1,10 +1,10 @@
 /*
- * Interface between low level (hardware) drivers and 
+ * Interface between low level (hardware) drivers and
  * HiSax protocol stack
  *
  * Author       Kai Germaschewski
  * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c
index a8447fa..5154c252 100644
--- a/drivers/isdn/hisax/hisax_isac.c
+++ b/drivers/isdn/hisax/hisax_isac.c
@@ -1,11 +1,11 @@
 /*
- * Driver for ISAC-S and ISAC-SX 
+ * Driver for ISAC-S and ISAC-SX
  * ISDN Subscriber Access Controller for Terminals
  *
  * Author       Kai Germaschewski
  * Copyright    2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
  *              2001 by Karsten Keil       <keil@isdn4linux.de>
- * 
+ *
  * based upon Karsten Keil's original isac.c driver
  *
  * This software may be used and distributed according to the terms
@@ -36,10 +36,10 @@ static int debug = 1;
 module_param(debug, int, 0);
 
 static char *ISACVer[] = {
-  "2086/2186 V1.1", 
-  "2085 B1", 
-  "2085 B2",
-  "2085 V2.3"
+	"2086/2186 V1.1",
+	"2085 B1",
+	"2085 B2",
+	"2085 V2.3"
 };
 #endif
 
@@ -178,7 +178,7 @@ enum {
 	ST_L1_F8,
 };
 
-#define L1_STATE_COUNT (ST_L1_F8+1)
+#define L1_STATE_COUNT (ST_L1_F8 + 1)
 
 static char *strL1State[] =
 {
@@ -382,7 +382,7 @@ static struct FsmNode L1FnList[] __initdata =
 	{ST_L1_F3_PDOWN,      EV_PH_AI8,            l1_go_f7_act_ind},
 	{ST_L1_F3_PDOWN,      EV_PH_ACTIVATE_REQ,   l1_ar8},
 	{ST_L1_F3_PDOWN,      EV_TIMER3,            l1_timer3},
-	
+
 	{ST_L1_F3_PEND_DEACT, EV_PH_RES,            l1_di},
 	{ST_L1_F3_PEND_DEACT, EV_PH_EI,             l1_di},
 	{ST_L1_F3_PEND_DEACT, EV_PH_DC,             l1_go_f3pdown},
@@ -432,7 +432,7 @@ static void l1m_debug(struct FsmInst *fi, char *fmt, ...)
 {
 	va_list args;
 	char buf[256];
-	
+
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	DBG(DBG_L1M, "%s", buf);
@@ -522,7 +522,7 @@ static inline void isac_cisq_interrupt(struct isac *isac)
 	}
 	if (val & ISAC_CIR0_CIC1) {
 		val = isac->read_isac(isac, ISAC_CIR1);
-		DBG(DBG_WARN, "ISAC CIR1 %#x", val );
+		DBG(DBG_WARN, "ISAC CIR1 %#x", val);
 	}
 }
 
@@ -531,10 +531,10 @@ static inline void isac_rme_interrupt(struct isac *isac)
 	unsigned char val;
 	int count;
 	struct sk_buff *skb;
-	
+
 	val = isac->read_isac(isac, ISAC_RSTA);
-	if ((val & (ISAC_RSTA_RDO | ISAC_RSTA_CRC | ISAC_RSTA_RAB) )
-	     != ISAC_RSTA_CRC) {
+	if ((val & (ISAC_RSTA_RDO | ISAC_RSTA_CRC | ISAC_RSTA_RAB))
+	    != ISAC_RSTA_CRC) {
 		DBG(DBG_WARN, "RSTA %#x, dropped", val);
 		isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC);
 		goto out;
@@ -560,7 +560,7 @@ static inline void isac_rme_interrupt(struct isac *isac)
 	memcpy(skb_put(skb, count), isac->rcvbuf, count);
 	DBG_SKB(DBG_RPACKET, skb);
 	D_L1L2(isac, PH_DATA | INDICATION, skb);
- out:
+out:
 	isac->rcvidx = 0;
 }
 
@@ -659,10 +659,10 @@ static inline void isacsx_rme_interrupt(struct isac *isac)
 	unsigned char val;
 
 	val = isac->read_isac(isac, ISACSX_RSTAD);
-	if ((val & (ISACSX_RSTAD_VFR | 
-		    ISACSX_RSTAD_RDO | 
-		    ISACSX_RSTAD_CRC | 
-		    ISACSX_RSTAD_RAB)) 
+	if ((val & (ISACSX_RSTAD_VFR |
+		    ISACSX_RSTAD_RDO |
+		    ISACSX_RSTAD_CRC |
+		    ISACSX_RSTAD_RAB))
 	    != (ISACSX_RSTAD_VFR | ISACSX_RSTAD_CRC)) {
 		DBG(DBG_WARN, "RSTAD %#x, dropped", val);
 		isac->write_isac(isac, ISACSX_CMDRD, ISACSX_CMDRD_RMC);
@@ -690,7 +690,7 @@ static inline void isacsx_rme_interrupt(struct isac *isac)
 	memcpy(skb_put(skb, count), isac->rcvbuf, count);
 	DBG_SKB(DBG_RPACKET, skb);
 	D_L1L2(isac, PH_DATA | INDICATION, skb);
- out:
+out:
 	isac->rcvidx = 0;
 }
 
@@ -778,8 +778,8 @@ void isac_setup(struct isac *isac)
 
 	ph_command(isac, ISAC_CMD_RES);
 
-  	isac->write_isac(isac, ISAC_MASK, 0xff);
-  	isac->mocr = 0xaa;
+	isac->write_isac(isac, ISAC_MASK, 0xff);
+	isac->mocr = 0xaa;
 	if (test_bit(ISAC_IOM1, &isac->flags)) {
 		/* IOM 1 Mode */
 		isac->write_isac(isac, ISAC_ADF2, 0x0);
@@ -832,7 +832,7 @@ void isacsx_setup(struct isac *isac)
 	// all HDLC IRQ unmasked
 	isac->write_isac(isac, ISACSX_MASKD,    0x03);
 	// unmask ICD, CID IRQs
-	isac->write_isac(isac, ISACSX_MASK,            
+	isac->write_isac(isac, ISACSX_MASK,
 			 ~(ISACSX_ISTA_ICD | ISACSX_ISTA_CIC));
 }
 
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index 904b910..3e305fe 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -54,7 +54,7 @@ modehscx(struct BCState *bcs, int mode, int bc)
 	cs->BC_Write_Reg(cs, hscx, HSCX_XBCH, 0x0);
 	cs->BC_Write_Reg(cs, hscx, HSCX_RLCR, 0x0);
 	cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
-		test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85);
+			 test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85);
 	cs->BC_Write_Reg(cs, hscx, HSCX_CCR2, 0x30);
 	cs->BC_Write_Reg(cs, hscx, HSCX_XCCR, 7);
 	cs->BC_Write_Reg(cs, hscx, HSCX_RCCR, 7);
@@ -65,27 +65,27 @@ modehscx(struct BCState *bcs, int mode, int bc)
 
 	if (bc == 0) {
 		cs->BC_Write_Reg(cs, hscx, HSCX_TSAX,
-			      test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0);
+				 test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0);
 		cs->BC_Write_Reg(cs, hscx, HSCX_TSAR,
-			      test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0);
+				 test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : bcs->hw.hscx.tsaxr0);
 	} else {
 		cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, bcs->hw.hscx.tsaxr1);
 		cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, bcs->hw.hscx.tsaxr1);
 	}
 	switch (mode) {
-		case (L1_MODE_NULL):
-			cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x1f);
-			cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x1f);
-			cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x84);
-			break;
-		case (L1_MODE_TRANS):
-			cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0xe4);
-			break;
-		case (L1_MODE_HDLC):
-			cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
-				test_bit(HW_IPAC, &cs->HW_Flags) ? 0x8a : 0x8d);
-			cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x8c);
-			break;
+	case (L1_MODE_NULL):
+		cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x1f);
+		cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x1f);
+		cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x84);
+		break;
+	case (L1_MODE_TRANS):
+		cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0xe4);
+		break;
+	case (L1_MODE_HDLC):
+		cs->BC_Write_Reg(cs, hscx, HSCX_CCR1,
+				 test_bit(HW_IPAC, &cs->HW_Flags) ? 0x8a : 0x8d);
+		cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x8c);
+		break;
 	}
 	if (mode)
 		cs->BC_Write_Reg(cs, hscx, HSCX_CMDR, 0x41);
@@ -100,55 +100,55 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
 	struct sk_buff *skb = arg;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->hw.hscx.count = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
-			} else {
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->tx_skb = skb;
-				bcs->hw.hscx.count = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			modehscx(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			modehscx(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->hw.hscx.count = 0;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
+		} else {
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->tx_skb = skb;
+			bcs->hw.hscx.count = 0;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		modehscx(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		modehscx(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -177,13 +177,13 @@ open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
 	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
 		if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
 			printk(KERN_WARNING
-				"HiSax: No memory for hscx.rcvbuf\n");
+			       "HiSax: No memory for hscx.rcvbuf\n");
 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
 			return (1);
 		}
 		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
 			printk(KERN_WARNING
-				"HiSax: No memory for bcs->blog\n");
+			       "HiSax: No memory for bcs->blog\n");
 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
 			kfree(bcs->hw.hscx.rcvbuf);
 			bcs->hw.hscx.rcvbuf = NULL;
diff --git a/drivers/isdn/hisax/hscx.h b/drivers/isdn/hisax/hscx.h
index 268bfd3..1148b4b 100644
--- a/drivers/isdn/hisax/hscx.h
+++ b/drivers/isdn/hisax/hscx.h
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c
index 2387d76..f398d48 100644
--- a/drivers/isdn/hisax/hscx_irq.c
+++ b/drivers/isdn/hisax/hscx_irq.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -84,7 +84,7 @@ hscx_fill_fifo(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
 	int more, count;
-	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
+	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32;
 	u_char *ptr;
 
 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
@@ -125,7 +125,7 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 	u_char r;
 	struct BCState *bcs = cs->bcs + hscx;
 	struct sk_buff *skb;
-	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
+	int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32;
 	int count;
 
 	if (!test_bit(BC_FLG_INIT, &bcs->Flag))
@@ -159,7 +159,7 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 			WriteHSCXCMDR(cs, hscx, 0x80);
 		} else {
 			count = READHSCX(cs, hscx, HSCX_RBCL) & (
-				test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
+				test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f);
 			if (count == 0)
 				count = fifo_size;
 			hscx_empty_fifo(bcs, count);
@@ -197,8 +197,8 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 				hscx_fill_fifo(bcs);
 				return;
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 					u_long	flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->hw.hscx.count;
@@ -206,7 +206,7 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
 					schedule_event(bcs, B_ACKPENDING);
 				}
 				dev_kfree_skb_irq(bcs->tx_skb);
-				bcs->hw.hscx.count = 0; 
+				bcs->hw.hscx.count = 0;
 				bcs->tx_skb = NULL;
 			}
 		}
@@ -239,7 +239,7 @@ hscx_int_main(struct IsdnCardState *cs, u_char val)
 				bcs->err_tx++;
 #endif
 				/* Here we lost an TX interrupt, so
-				   * restart transmitting the whole frame.
+				 * restart transmitting the whole frame.
 				 */
 				if (bcs->tx_skb) {
 					skb_push(bcs->tx_skb, bcs->hw.hscx.count);
@@ -266,7 +266,7 @@ hscx_int_main(struct IsdnCardState *cs, u_char val)
 				hscx_fill_fifo(bcs);
 			else {
 				/* Here we lost an TX interrupt, so
-				   * restart transmitting the whole frame.
+				 * restart transmitting the whole frame.
 				 */
 #ifdef ERROR_STATISTIC
 				bcs->err_tx++;
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 6305726..7be762b 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -4,7 +4,7 @@
  *
  * Author       Matt Henderson & Guy Ellis
  * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -50,30 +50,30 @@ static void
 icc_new_ph(struct IsdnCardState *cs)
 {
 	switch (cs->dc.icc.ph_state) {
-		case (ICC_IND_EI1):
-			ph_command(cs, ICC_CMD_DI);
-			l1_msg(cs, HW_RESET | INDICATION, NULL);
-			break;
-		case (ICC_IND_DC):
-			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
-			break;
-		case (ICC_IND_DR):
-			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-			break;
-		case (ICC_IND_PU):
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-		case (ICC_IND_FJ):
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-			break;
-		case (ICC_IND_AR):
-			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-			break;
-		case (ICC_IND_AI):
-			l1_msg(cs, HW_INFO4 | INDICATION, NULL);
-			break;
-		default:
-			break;
+	case (ICC_IND_EI1):
+		ph_command(cs, ICC_CMD_DI);
+		l1_msg(cs, HW_RESET | INDICATION, NULL);
+		break;
+	case (ICC_IND_DC):
+		l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
+		break;
+	case (ICC_IND_DR):
+		l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+		break;
+	case (ICC_IND_PU):
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		break;
+	case (ICC_IND_FJ):
+		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+		break;
+	case (ICC_IND_AR):
+		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+		break;
+	case (ICC_IND_AI):
+		l1_msg(cs, HW_INFO4 | INDICATION, NULL);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -83,7 +83,7 @@ icc_bh(struct work_struct *work)
 	struct IsdnCardState *cs =
 		container_of(work, struct IsdnCardState, tqueue);
 	struct PStack *stptr;
-	
+
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
 		if (cs->debug)
 			debugl1(cs, "D-Channel Busy cleared");
@@ -94,7 +94,7 @@ icc_bh(struct work_struct *work)
 		}
 	}
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event))
-		icc_new_ph(cs);		
+		icc_new_ph(cs);
 	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
 		DChannel_proc_rcv(cs);
 	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
@@ -254,11 +254,11 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 		} else
 			schedule_event(cs, D_XMTBUFREADY);
 	}
-      afterXPR:
+afterXPR:
 	if (val & 0x04) {	/* CISQ */
 		exval = cs->readisac(cs, ICC_CIR0);
 		if (cs->debug & L1_DEB_ISAC)
-			debugl1(cs, "ICC CIR0 %02X", exval );
+			debugl1(cs, "ICC CIR0 %02X", exval);
 		if (exval & 2) {
 			cs->dc.icc.ph_state = (exval >> 2) & 0xf;
 			if (cs->debug & L1_DEB_ISAC)
@@ -268,7 +268,7 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 		if (exval & 1) {
 			exval = cs->readisac(cs, ICC_CIR1);
 			if (cs->debug & L1_DEB_ISAC)
-				debugl1(cs, "ICC CIR1 %02X", exval );
+				debugl1(cs, "ICC CIR1 %02X", exval);
 		}
 	}
 	if (val & 0x02) {	/* SIN */
@@ -331,13 +331,13 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 				}
 				cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp++] = cs->readisac(cs, ICC_MOR0);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ICC MOR0 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp -1]);
+					debugl1(cs, "ICC MOR0 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp - 1]);
 				if (cs->dc.icc.mon_rxp == 1) {
 					cs->dc.icc.mocr |= 0x04;
 					cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
 				}
 			}
-		      afterMONR0:
+		afterMONR0:
 			if (v1 & 0x80) {
 				if (!cs->dc.icc.mon_rx) {
 					if (!(cs->dc.icc.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
@@ -361,11 +361,11 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 				}
 				cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp++] = cs->readisac(cs, ICC_MOR1);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ICC MOR1 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp -1]);
+					debugl1(cs, "ICC MOR1 %02x", cs->dc.icc.mon_rx[cs->dc.icc.mon_rxp - 1]);
 				cs->dc.icc.mocr |= 0x40;
 				cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
 			}
-		      afterMONR1:
+		afterMONR1:
 			if (v1 & 0x04) {
 				cs->dc.icc.mocr &= 0xf0;
 				cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
@@ -381,15 +381,15 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 				schedule_event(cs, D_RX_MON1);
 			}
 			if (v1 & 0x02) {
-				if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc && 
-					(cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) && 
-					!(v1 & 0x08))) {
+				if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc &&
+							     (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) &&
+							     !(v1 & 0x08))) {
 					cs->dc.icc.mocr &= 0xf0;
 					cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
 					cs->dc.icc.mocr |= 0x0a;
 					cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
 					if (cs->dc.icc.mon_txc &&
-						(cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc))
+					    (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc))
 						schedule_event(cs, D_TX_MON0);
 					goto AfterMOX0;
 				}
@@ -398,21 +398,21 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 					goto AfterMOX0;
 				}
 				cs->writeisac(cs, ICC_MOX0,
-					cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]);
+					      cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ICC %02x -> MOX0", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp -1]);
+					debugl1(cs, "ICC %02x -> MOX0", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]);
 			}
-		      AfterMOX0:
+		AfterMOX0:
 			if (v1 & 0x20) {
-				if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc && 
-					(cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) && 
-					!(v1 & 0x80))) {
+				if ((!cs->dc.icc.mon_tx) || (cs->dc.icc.mon_txc &&
+							     (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc) &&
+							     !(v1 & 0x80))) {
 					cs->dc.icc.mocr &= 0x0f;
 					cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
 					cs->dc.icc.mocr |= 0xa0;
 					cs->writeisac(cs, ICC_MOCR, cs->dc.icc.mocr);
 					if (cs->dc.icc.mon_txc &&
-						(cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc))
+					    (cs->dc.icc.mon_txp >= cs->dc.icc.mon_txc))
 						schedule_event(cs, D_TX_MON1);
 					goto AfterMOX1;
 				}
@@ -421,11 +421,11 @@ icc_interrupt(struct IsdnCardState *cs, u_char val)
 					goto AfterMOX1;
 				}
 				cs->writeisac(cs, ICC_MOX1,
-					cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]);
+					      cs->dc.icc.mon_tx[cs->dc.icc.mon_txp++]);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp -1]);
+					debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]);
 			}
-		      AfterMOX1:
+		AfterMOX1:
 #endif
 		}
 	}
@@ -440,128 +440,128 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
 	int  val;
 
 	switch (pr) {
-		case (PH_DATA |REQUEST):
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
-#ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-				icc_fill_fifo(cs);
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL |INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
 			if (cs->debug & L1_DEB_LAPD)
-				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+				Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
 			icc_fill_fifo(cs);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			break;
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD)
+			Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			if ((cs->dc.icc.ph_state == ICC_IND_EI1) ||
-				(cs->dc.icc.ph_state == ICC_IND_DR))
-			        ph_command(cs, ICC_CMD_DI);
-			else
-				ph_command(cs, ICC_CMD_RES);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_ENABLE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
+		icc_fill_fifo(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG		/* psa */
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		if ((cs->dc.icc.ph_state == ICC_IND_EI1) ||
+		    (cs->dc.icc.ph_state == ICC_IND_DR))
 			ph_command(cs, ICC_CMD_DI);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO1 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			ph_command(cs, ICC_CMD_AR);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO3 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			ph_command(cs, ICC_CMD_AI);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_TESTLOOP | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			val = 0;
-			if (1 & (long) arg)
-				val |= 0x0c;
-			if (2 & (long) arg)
-				val |= 0x3;
-			if (test_bit(HW_IOM1, &cs->HW_Flags)) {
-				/* IOM 1 Mode */
-				if (!val) {
-					cs->writeisac(cs, ICC_SPCR, 0xa);
-					cs->writeisac(cs, ICC_ADF1, 0x2);
-				} else {
-					cs->writeisac(cs, ICC_SPCR, val);
-					cs->writeisac(cs, ICC_ADF1, 0xa);
-				}
+		else
+			ph_command(cs, ICC_CMD_RES);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_ENABLE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, ICC_CMD_DI);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO1 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, ICC_CMD_AR);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO3 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, ICC_CMD_AI);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_TESTLOOP | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		val = 0;
+		if (1 & (long) arg)
+			val |= 0x0c;
+		if (2 & (long) arg)
+			val |= 0x3;
+		if (test_bit(HW_IOM1, &cs->HW_Flags)) {
+			/* IOM 1 Mode */
+			if (!val) {
+				cs->writeisac(cs, ICC_SPCR, 0xa);
+				cs->writeisac(cs, ICC_ADF1, 0x2);
 			} else {
-				/* IOM 2 Mode */
 				cs->writeisac(cs, ICC_SPCR, val);
-				if (val)
-					cs->writeisac(cs, ICC_ADF1, 0x8);
-				else
-					cs->writeisac(cs, ICC_ADF1, 0x0);
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_DEACTIVATE | RESPONSE):
-			skb_queue_purge(&cs->rq);
-			skb_queue_purge(&cs->sq);
-			if (cs->tx_skb) {
-				dev_kfree_skb_any(cs->tx_skb);
-				cs->tx_skb = NULL;
+				cs->writeisac(cs, ICC_ADF1, 0xa);
 			}
-			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-				del_timer(&cs->dbusytimer);
-			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-				schedule_event(cs, D_CLEARBUSY);
-			break;
-		default:
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "icc_l1hw unknown %04x", pr);
-			break;
+		} else {
+			/* IOM 2 Mode */
+			cs->writeisac(cs, ICC_SPCR, val);
+			if (val)
+				cs->writeisac(cs, ICC_ADF1, 0x8);
+			else
+				cs->writeisac(cs, ICC_ADF1, 0x0);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_DEACTIVATE | RESPONSE):
+		skb_queue_purge(&cs->rq);
+		skb_queue_purge(&cs->sq);
+		if (cs->tx_skb) {
+			dev_kfree_skb_any(cs->tx_skb);
+			cs->tx_skb = NULL;
+		}
+		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+			del_timer(&cs->dbusytimer);
+		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+			schedule_event(cs, D_CLEARBUSY);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "icc_l1hw unknown %04x", pr);
+		break;
 	}
 }
 
@@ -588,7 +588,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
 		rbch = cs->readisac(cs, ICC_RBCH);
 		star = cs->readisac(cs, ICC_STAR);
-		if (cs->debug) 
+		if (cs->debug)
 			debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x",
 				rbch, star);
 		if (rbch & ICC_RBCH_XAC) { /* D-Channel Busy */
@@ -622,8 +622,8 @@ initicc(struct IsdnCardState *cs)
 	cs->DC_Close = DC_Close_icc;
 	cs->dc.icc.mon_tx = NULL;
 	cs->dc.icc.mon_rx = NULL;
-  	cs->writeisac(cs, ICC_MASK, 0xff);
-  	cs->dc.icc.mocr = 0xaa;
+	cs->writeisac(cs, ICC_MASK, 0xff);
+	cs->dc.icc.mocr = 0xaa;
 	if (test_bit(HW_IOM1, &cs->HW_Flags)) {
 		/* IOM 1 Mode */
 		cs->writeisac(cs, ICC_ADF2, 0x0);
diff --git a/drivers/isdn/hisax/icc.h b/drivers/isdn/hisax/icc.h
index e7f5939..f367df5 100644
--- a/drivers/isdn/hisax/icc.h
+++ b/drivers/isdn/hisax/icc.h
@@ -4,12 +4,12 @@
  *
  * Author       Matt Henderson & Guy Ellis
  * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * 1999.7.14 Initial implementation of routines for Siemens ISDN 
- * Communication Controller PEB 2070 based on the ISAC routines 
+ * 1999.7.14 Initial implementation of routines for Siemens ISDN
+ * Communication Controller PEB 2070 based on the ISAC routines
  * written by Karsten Keil.
  */
 
diff --git a/drivers/isdn/hisax/ipac.h b/drivers/isdn/hisax/ipac.h
index f92a04a..4f937f0 100644
--- a/drivers/isdn/hisax/ipac.h
+++ b/drivers/isdn/hisax/ipac.h
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index 6908404..74feb5c 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -1,10 +1,10 @@
-/* 
+/*
  *
  * IPACX specific routines
  *
  * Author       Joerg Petersohn
  * Derived from hisax_isac.c, isac.c, hscx.c and others
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -24,7 +24,7 @@
 #define D_FIFO_SIZE       32
 
 
-// ipacx interrupt mask values    
+// ipacx interrupt mask values
 #define _MASK_IMASK     0x2E  // global mask
 #define _MASKB_IMASK    0x0B
 #define _MASKD_IMASK    0x03  // all on
@@ -55,33 +55,33 @@ static void clear_pending_ints(struct IsdnCardState *cs);
 //----------------------------------------------------------
 // Issue Layer 1 command to chip
 //----------------------------------------------------------
-static void 
+static void
 ph_command(struct IsdnCardState *cs, unsigned int command)
 {
-	if (cs->debug &L1_DEB_ISAC)
+	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "ph_command (%#x) in (%#x)", command,
 			cs->dc.isac.ph_state);
-//###################################  
+//###################################
 //	printk(KERN_INFO "ph_command (%#x)\n", command);
-//###################################  
+//###################################
 	cs->writeisac(cs, IPACX_CIX0, (command << 4) | 0x0E);
 }
 
 //----------------------------------------------------------
 // Transceiver interrupt handler
 //----------------------------------------------------------
-static inline void 
+static inline void
 cic_int(struct IsdnCardState *cs)
 {
 	u_char event;
 
 	event = cs->readisac(cs, IPACX_CIR0) >> 4;
-	if (cs->debug &L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event);
-//#########################################  
+	if (cs->debug & L1_DEB_ISAC) debugl1(cs, "cic_int(event=%#x)", event);
+//#########################################
 //	printk(KERN_INFO "cic_int(%x)\n", event);
-//#########################################  
-  cs->dc.isac.ph_state = event;
-  schedule_event(cs, D_L1STATECHANGE);
+//#########################################
+	cs->dc.isac.ph_state = event;
+	schedule_event(cs, D_L1STATECHANGE);
 }
 
 //==========================================================
@@ -99,99 +99,99 @@ dch_l2l1(struct PStack *st, int pr, void *arg)
 	u_char cda1_cr;
 
 	switch (pr) {
-		case (PH_DATA |REQUEST):
-			if (cs->debug &DEB_DLOG_HEX)     LogFrame(cs, skb->data, skb->len);
-			if (cs->debug &DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
-#ifdef L2FRAME_DEBUG
-				if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX) LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG
-				if (cs->debug &L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-				dch_fill_fifo(cs);
-			}
-			break;
-      
-		case (PH_PULL |INDICATION):
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)     LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG
-			if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+			if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
 			dch_fill_fifo(cs);
+		}
+		break;
+
+	case (PH_PULL | INDICATION):
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			break;
-      
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)     LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE) dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG
-			if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD) Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-
-		case (HW_RESET | REQUEST):
-		case (HW_ENABLE | REQUEST):
-			if ((cs->dc.isac.ph_state == IPACX_IND_RES) ||
-				(cs->dc.isac.ph_state == IPACX_IND_DR) ||
-				(cs->dc.isac.ph_state == IPACX_IND_DC))
-			        ph_command(cs, IPACX_CMD_TIM);
-			else
-				ph_command(cs, IPACX_CMD_RES);
-			break;
-
-		case (HW_INFO3 | REQUEST):
-			ph_command(cs, IPACX_CMD_AR8);
-			break;
-
-		case (HW_TESTLOOP | REQUEST):
-      cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
-      cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
-      cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
-      (void) cs->readisac(cs, IPACX_CDA2_CR);
-			if ((long)arg &1) { // loop B1
-        cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a); 
-      }
-      else {  // B1 off
-        cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x0a); 
-      }
-			if ((long)arg &2) { // loop B2
-        cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x14); 
-      }
-      else {  // B2 off
-        cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr &~0x14); 
-      }
-			break;
+		dch_fill_fifo(cs);
+		break;
 
-		case (HW_DEACTIVATE | RESPONSE):
-			skb_queue_purge(&cs->rq);
-			skb_queue_purge(&cs->sq);
-			if (cs->tx_skb) {
-				dev_kfree_skb_any(cs->tx_skb);
-				cs->tx_skb = NULL;
-			}
-			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-				del_timer(&cs->dbusytimer);
-			break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG
+		if (cs->debug & L1_DEB_LAPD) debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+		if (!cs->tx_skb) {
+			clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+
+	case (HW_RESET | REQUEST):
+	case (HW_ENABLE | REQUEST):
+		if ((cs->dc.isac.ph_state == IPACX_IND_RES) ||
+		    (cs->dc.isac.ph_state == IPACX_IND_DR) ||
+		    (cs->dc.isac.ph_state == IPACX_IND_DC))
+			ph_command(cs, IPACX_CMD_TIM);
+		else
+			ph_command(cs, IPACX_CMD_RES);
+		break;
+
+	case (HW_INFO3 | REQUEST):
+		ph_command(cs, IPACX_CMD_AR8);
+		break;
+
+	case (HW_TESTLOOP | REQUEST):
+		cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
+		cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
+		cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
+		(void) cs->readisac(cs, IPACX_CDA2_CR);
+		if ((long)arg & 1) { // loop B1
+			cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr | 0x0a);
+		}
+		else {  // B1 off
+			cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr & ~0x0a);
+		}
+		if ((long)arg & 2) { // loop B2
+			cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr | 0x14);
+		}
+		else {  // B2 off
+			cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr & ~0x14);
+		}
+		break;
+
+	case (HW_DEACTIVATE | RESPONSE):
+		skb_queue_purge(&cs->rq);
+		skb_queue_purge(&cs->sq);
+		if (cs->tx_skb) {
+			dev_kfree_skb_any(cs->tx_skb);
+			cs->tx_skb = NULL;
+		}
+		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+			del_timer(&cs->dbusytimer);
+		break;
 
-		default:
-			if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr);
-			break;
+	default:
+		if (cs->debug & L1_DEB_WARN) debugl1(cs, "dch_l2l1 unknown %04x", pr);
+		break;
 	}
 }
 
@@ -206,11 +206,11 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
 		rbchd = cs->readisac(cs, IPACX_RBCHD);
 		stard = cs->readisac(cs, IPACX_STARD);
-		if (cs->debug) 
-      debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard);
-		if (!(stard &0x40)) { // D-Channel Busy
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy RBCHD %02x STARD %02x", rbchd, stard);
+		if (!(stard & 0x40)) { // D-Channel Busy
 			set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
-      for (st = cs->stlist; st; st = st->next) {
+			for (st = cs->stlist; st; st = st->next) {
 				st->l1.l1l2(st, PH_PAUSE | INDICATION, NULL); // flow control on
 			}
 		} else {
@@ -232,30 +232,30 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 //----------------------------------------------------------
 // Fill buffer from receive FIFO
 //----------------------------------------------------------
-static void 
+static void
 dch_empty_fifo(struct IsdnCardState *cs, int count)
 {
 	u_char *ptr;
 
-	if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
+	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
 		debugl1(cs, "dch_empty_fifo()");
 
-  // message too large, remove
+	// message too large, remove
 	if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
-		if (cs->debug &L1_DEB_WARN)
+		if (cs->debug & L1_DEB_WARN)
 			debugl1(cs, "dch_empty_fifo() incoming message too large");
-	  cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
+		cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
 		cs->rcvidx = 0;
 		return;
 	}
-  
+
 	ptr = cs->rcvbuf + cs->rcvidx;
 	cs->rcvidx += count;
-  
+
 	cs->readisacfifo(cs, ptr, count);
 	cs->writeisac(cs, IPACX_CMDRD, 0x80); // RMC
-  
-	if (cs->debug &L1_DEB_ISAC_FIFO) {
+
+	if (cs->debug & L1_DEB_ISAC_FIFO) {
 		char *t = cs->dlog;
 
 		t += sprintf(t, "dch_empty_fifo() cnt %d", count);
@@ -267,15 +267,15 @@ dch_empty_fifo(struct IsdnCardState *cs, int count)
 //----------------------------------------------------------
 // Fill transmit FIFO
 //----------------------------------------------------------
-static void 
+static void
 dch_fill_fifo(struct IsdnCardState *cs)
 {
 	int count;
 	u_char cmd, *ptr;
 
-	if ((cs->debug &L1_DEB_ISAC) && !(cs->debug &L1_DEB_ISAC_FIFO))
+	if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
 		debugl1(cs, "dch_fill_fifo()");
-    
+
 	if (!cs->tx_skb) return;
 	count = cs->tx_skb->len;
 	if (count <= 0) return;
@@ -286,14 +286,14 @@ dch_fill_fifo(struct IsdnCardState *cs)
 	} else {
 		cmd   = 0x0A; // XTF | XME
 	}
-  
+
 	ptr = cs->tx_skb->data;
 	skb_pull(cs->tx_skb, count);
 	cs->tx_cnt += count;
 	cs->writeisacfifo(cs, ptr, count);
 	cs->writeisac(cs, IPACX_CMDRD, cmd);
-  
-  // set timeout for transmission contol
+
+	// set timeout for transmission contol
 	if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
 		debugl1(cs, "dch_fill_fifo dbusytimer running");
 		del_timer(&cs->dbusytimer);
@@ -301,8 +301,8 @@ dch_fill_fifo(struct IsdnCardState *cs)
 	init_timer(&cs->dbusytimer);
 	cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
 	add_timer(&cs->dbusytimer);
-  
-	if (cs->debug &L1_DEB_ISAC_FIFO) {
+
+	if (cs->debug & L1_DEB_ISAC_FIFO) {
 		char *t = cs->dlog;
 
 		t += sprintf(t, "dch_fill_fifo() cnt %d", count);
@@ -314,7 +314,7 @@ dch_fill_fifo(struct IsdnCardState *cs)
 //----------------------------------------------------------
 // D channel interrupt handler
 //----------------------------------------------------------
-static inline void 
+static inline void
 dch_int(struct IsdnCardState *cs)
 {
 	struct sk_buff *skb;
@@ -322,31 +322,31 @@ dch_int(struct IsdnCardState *cs)
 	int count;
 
 	istad = cs->readisac(cs, IPACX_ISTAD);
-//##############################################  
+//##############################################
 //	printk(KERN_WARNING "dch_int(istad=%02x)\n", istad);
-//##############################################  
-  
-	if (istad &0x80) {  // RME
-	  rstad = cs->readisac(cs, IPACX_RSTAD);
-		if ((rstad &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
-			if (!(rstad &0x80))
-				if (cs->debug &L1_DEB_WARN) 
-          debugl1(cs, "dch_int(): invalid frame");
-			if ((rstad &0x40))
-				if (cs->debug &L1_DEB_WARN) 
-          debugl1(cs, "dch_int(): RDO");
-			if (!(rstad &0x20))
-				if (cs->debug &L1_DEB_WARN) 
-          debugl1(cs, "dch_int(): CRC error");
-	    cs->writeisac(cs, IPACX_CMDRD, 0x80);  // RMC
+//##############################################
+
+	if (istad & 0x80) {  // RME
+		rstad = cs->readisac(cs, IPACX_RSTAD);
+		if ((rstad & 0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
+			if (!(rstad & 0x80))
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "dch_int(): invalid frame");
+			if ((rstad & 0x40))
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "dch_int(): RDO");
+			if (!(rstad & 0x20))
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "dch_int(): CRC error");
+			cs->writeisac(cs, IPACX_CMDRD, 0x80);  // RMC
 		} else {  // received frame ok
 			count = cs->readisac(cs, IPACX_RBCLD);
-      if (count) count--; // RSTAB is last byte
-			count &= D_FIFO_SIZE-1;
+			if (count) count--; // RSTAB is last byte
+			count &= D_FIFO_SIZE - 1;
 			if (count == 0) count = D_FIFO_SIZE;
 			dch_empty_fifo(cs, count);
 			if ((count = cs->rcvidx) > 0) {
-	      cs->rcvidx = 0;
+				cs->rcvidx = 0;
 				if (!(skb = dev_alloc_skb(count)))
 					printk(KERN_WARNING "HiSax dch_int(): receive out of memory\n");
 				else {
@@ -354,57 +354,57 @@ dch_int(struct IsdnCardState *cs)
 					skb_queue_tail(&cs->rq, skb);
 				}
 			}
-    }
-	  cs->rcvidx = 0;
+		}
+		cs->rcvidx = 0;
 		schedule_event(cs, D_RCVBUFREADY);
 	}
 
-	if (istad &0x40) {  // RPF
+	if (istad & 0x40) {  // RPF
 		dch_empty_fifo(cs, D_FIFO_SIZE);
 	}
 
-	if (istad &0x20) {  // RFO
-		if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): RFO");
-	  cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES
+	if (istad & 0x20) {  // RFO
+		if (cs->debug & L1_DEB_WARN) debugl1(cs, "dch_int(): RFO");
+		cs->writeisac(cs, IPACX_CMDRD, 0x40); //RRES
 	}
-  
-  if (istad &0x10) {  // XPR
+
+	if (istad & 0x10) {  // XPR
 		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
 			del_timer(&cs->dbusytimer);
 		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
 			schedule_event(cs, D_CLEARBUSY);
-    if (cs->tx_skb) {
-      if (cs->tx_skb->len) {
-        dch_fill_fifo(cs);
-        goto afterXPR;
-      }
-      else {
-        dev_kfree_skb_irq(cs->tx_skb);
-        cs->tx_skb = NULL;
-        cs->tx_cnt = 0;
-      }
-    }
-    if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
-      cs->tx_cnt = 0;
-      dch_fill_fifo(cs);
-    } 
-    else {
-      schedule_event(cs, D_XMTBUFREADY);
-    }  
-  }  
-  afterXPR:
-
-	if (istad &0x0C) {  // XDU or XMR
-		if (cs->debug &L1_DEB_WARN) debugl1(cs, "dch_int(): XDU");
-	  if (cs->tx_skb) {
-	    skb_push(cs->tx_skb, cs->tx_cnt); // retransmit
-	    cs->tx_cnt = 0;
+		if (cs->tx_skb) {
+			if (cs->tx_skb->len) {
+				dch_fill_fifo(cs);
+				goto afterXPR;
+			}
+			else {
+				dev_kfree_skb_irq(cs->tx_skb);
+				cs->tx_skb = NULL;
+				cs->tx_cnt = 0;
+			}
+		}
+		if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
+			cs->tx_cnt = 0;
+			dch_fill_fifo(cs);
+		}
+		else {
+			schedule_event(cs, D_XMTBUFREADY);
+		}
+	}
+afterXPR:
+
+	if (istad & 0x0C) {  // XDU or XMR
+		if (cs->debug & L1_DEB_WARN) debugl1(cs, "dch_int(): XDU");
+		if (cs->tx_skb) {
+			skb_push(cs->tx_skb, cs->tx_cnt); // retransmit
+			cs->tx_cnt = 0;
 			dch_fill_fifo(cs);
 		} else {
 			printk(KERN_WARNING "HiSax: ISAC XDU no skb\n");
 			debugl1(cs, "ISAC XDU no skb");
 		}
-  }
+	}
 }
 
 //----------------------------------------------------------
@@ -423,15 +423,15 @@ dch_init(struct IsdnCardState *cs)
 	printk(KERN_INFO "HiSax: IPACX ISDN driver v0.1.0\n");
 
 	cs->setstack_d      = dch_setstack;
-  
+
 	cs->dbusytimer.function = (void *) dbusy_timer_handler;
 	cs->dbusytimer.data = (long) cs;
 	init_timer(&cs->dbusytimer);
 
-  cs->writeisac(cs, IPACX_TR_CONF0, 0x00);  // clear LDD
-  cs->writeisac(cs, IPACX_TR_CONF2, 0x00);  // enable transmitter
-  cs->writeisac(cs, IPACX_MODED,    0xC9);  // transparent mode 0, RAC, stop/go
-  cs->writeisac(cs, IPACX_MON_CR,   0x00);  // disable monitor channel
+	cs->writeisac(cs, IPACX_TR_CONF0, 0x00);  // clear LDD
+	cs->writeisac(cs, IPACX_TR_CONF2, 0x00);  // enable transmitter
+	cs->writeisac(cs, IPACX_MODED,    0xC9);  // transparent mode 0, RAC, stop/go
+	cs->writeisac(cs, IPACX_MON_CR,   0x00);  // disable monitor channel
 }
 
 
@@ -450,55 +450,55 @@ bch_l2l1(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->hw.hscx.count = 0;
-				bch_fill_fifo(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happen\n");
-			} else {
-				set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->tx_skb = skb;
-				bcs->hw.hscx.count = 0;
-				bch_fill_fifo(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			bch_mode(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			bch_mode(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
+			set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->hw.hscx.count = 0;
+			bch_fill_fifo(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "HiSax bch_l2l1(): this shouldn't happen\n");
+		} else {
+			set_bit(BC_FLG_BUSY, &bcs->Flag);
+			bcs->tx_skb = skb;
+			bcs->hw.hscx.count = 0;
+			bch_fill_fifo(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		bch_mode(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		bch_mode(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -513,28 +513,28 @@ bch_empty_fifo(struct BCState *bcs, int count)
 	int cnt;
 
 	cs = bcs->cs;
-  hscx = bcs->hw.hscx.hscx;
-	if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
+	hscx = bcs->hw.hscx.hscx;
+	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
 		debugl1(cs, "bch_empty_fifo()");
 
-  // message too large, remove
+	// message too large, remove
 	if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
-		if (cs->debug &L1_DEB_WARN)
+		if (cs->debug & L1_DEB_WARN)
 			debugl1(cs, "bch_empty_fifo() incoming packet too large");
-	  cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
+		cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
 		bcs->hw.hscx.rcvidx = 0;
 		return;
 	}
-  
+
 	ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
 	cnt = count;
-	while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB); 
+	while (cnt--) *ptr++ = cs->BC_Read_Reg(cs, hscx, IPACX_RFIFOB);
 	cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
-  
+
 	ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx;
 	bcs->hw.hscx.rcvidx += count;
-  
-	if (cs->debug &L1_DEB_HSCX_FIFO) {
+
+	if (cs->debug & L1_DEB_HSCX_FIFO) {
 		char *t = bcs->blog;
 
 		t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count);
@@ -554,7 +554,7 @@ bch_fill_fifo(struct BCState *bcs)
 	u_char *ptr, *p, hscx;
 
 	cs = bcs->cs;
-	if ((cs->debug &L1_DEB_HSCX) && !(cs->debug &L1_DEB_HSCX_FIFO))
+	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
 		debugl1(cs, "bch_fill_fifo()");
 
 	if (!bcs->tx_skb)           return;
@@ -567,17 +567,17 @@ bch_fill_fifo(struct BCState *bcs)
 		count = B_FIFO_SIZE;
 	} else {
 		count = bcs->tx_skb->len;
-	}  
+	}
 	cnt = count;
-    
+
 	p = ptr = bcs->tx_skb->data;
 	skb_pull(bcs->tx_skb, count);
 	bcs->tx_cnt -= count;
 	bcs->hw.hscx.count += count;
-	while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++); 
+	while (cnt--) cs->BC_Write_Reg(cs, hscx, IPACX_XFIFOB, *p++);
 	cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, (more ? 0x08 : 0x0a));
-  
-	if (cs->debug &L1_DEB_HSCX_FIFO) {
+
+	if (cs->debug & L1_DEB_HSCX_FIFO) {
 		char *t = bcs->blog;
 
 		t += sprintf(t, "chb_fill_fifo() B-%d cnt %d", hscx, count);
@@ -600,31 +600,31 @@ bch_int(struct IsdnCardState *cs, u_char hscx)
 
 	bcs = cs->bcs + hscx;
 	istab = cs->BC_Read_Reg(cs, hscx, IPACX_ISTAB);
-//##############################################  
+//##############################################
 //	printk(KERN_WARNING "bch_int(istab=%02x)\n", istab);
-//##############################################  
+//##############################################
 	if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return;
 
-	if (istab &0x80) {	// RME
+	if (istab & 0x80) {	// RME
 		rstab = cs->BC_Read_Reg(cs, hscx, IPACX_RSTAB);
-		if ((rstab &0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
-			if (!(rstab &0x80))
-				if (cs->debug &L1_DEB_WARN) 
-          debugl1(cs, "bch_int() B-%d: invalid frame", hscx);
-			if ((rstab &0x40) && (bcs->mode != L1_MODE_NULL))
-				if (cs->debug &L1_DEB_WARN) 
-          debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode);
-			if (!(rstab &0x20))
-				if (cs->debug &L1_DEB_WARN) 
-          debugl1(cs, "bch_int() B-%d: CRC error", hscx);
-	    cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
-		} 
-    else {  // received frame ok
-			count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) &(B_FIFO_SIZE-1);
+		if ((rstab & 0xf0) != 0xa0) { // !(VFR && !RDO && CRC && !RAB)
+			if (!(rstab & 0x80))
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "bch_int() B-%d: invalid frame", hscx);
+			if ((rstab & 0x40) && (bcs->mode != L1_MODE_NULL))
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "bch_int() B-%d: RDO mode=%d", hscx, bcs->mode);
+			if (!(rstab & 0x20))
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "bch_int() B-%d: CRC error", hscx);
+			cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x80);  // RMC
+		}
+		else {  // received frame ok
+			count = cs->BC_Read_Reg(cs, hscx, IPACX_RBCLB) & (B_FIFO_SIZE - 1);
 			if (count == 0) count = B_FIFO_SIZE;
 			bch_empty_fifo(bcs, count);
 			if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
-				if (cs->debug &L1_DEB_HSCX_FIFO)
+				if (cs->debug & L1_DEB_HSCX_FIFO)
 					debugl1(cs, "bch_int Frame %d", count);
 				if (!(skb = dev_alloc_skb(count)))
 					printk(KERN_WARNING "HiSax bch_int(): receive frame out of memory\n");
@@ -637,8 +637,8 @@ bch_int(struct IsdnCardState *cs, u_char hscx)
 		bcs->hw.hscx.rcvidx = 0;
 		schedule_event(bcs, B_RCVBUFREADY);
 	}
-  
-	if (istab &0x40) {	// RPF
+
+	if (istab & 0x40) {	// RPF
 		bch_empty_fifo(bcs, B_FIFO_SIZE);
 
 		if (bcs->mode == L1_MODE_TRANS) { // queue every chunk
@@ -653,21 +653,21 @@ bch_int(struct IsdnCardState *cs, u_char hscx)
 			schedule_event(bcs, B_RCVBUFREADY);
 		}
 	}
-  
-	if (istab &0x20) {	// RFO
-		if (cs->debug &L1_DEB_WARN) 
+
+	if (istab & 0x20) {	// RFO
+		if (cs->debug & L1_DEB_WARN)
 			debugl1(cs, "bch_int() B-%d: RFO error", hscx);
 		cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x40);  // RRES
 	}
 
-	if (istab &0x10) {	// XPR
+	if (istab & 0x10) {	// XPR
 		if (bcs->tx_skb) {
 			if (bcs->tx_skb->len) {
 				bch_fill_fifo(bcs);
 				goto afterXPR;
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 					u_long	flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->hw.hscx.count;
@@ -678,7 +678,7 @@ bch_int(struct IsdnCardState *cs, u_char hscx)
 			dev_kfree_skb_irq(bcs->tx_skb);
 			bcs->hw.hscx.count = 0;
 			bcs->tx_skb = NULL;
-    		}
+		}
 		if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
 			bcs->hw.hscx.count = 0;
 			set_bit(BC_FLG_BUSY, &bcs->Flag);
@@ -688,22 +688,22 @@ bch_int(struct IsdnCardState *cs, u_char hscx)
 			schedule_event(bcs, B_XMTBUFREADY);
 		}
 	}
-  afterXPR:
+afterXPR:
 
-	if (istab &0x04) {	// XDU
-    if (bcs->mode == L1_MODE_TRANS) {
+	if (istab & 0x04) {	// XDU
+		if (bcs->mode == L1_MODE_TRANS) {
 			bch_fill_fifo(bcs);
-    }  
-    else {
-      if (bcs->tx_skb) {  // restart transmitting the whole frame
-        skb_push(bcs->tx_skb, bcs->hw.hscx.count);
-        bcs->tx_cnt += bcs->hw.hscx.count;
-        bcs->hw.hscx.count = 0;
-      }
-	    cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01);  // XRES
-      if (cs->debug &L1_DEB_WARN)
-        debugl1(cs, "bch_int() B-%d XDU error", hscx);
-    }
+		}
+		else {
+			if (bcs->tx_skb) {  // restart transmitting the whole frame
+				skb_push(bcs->tx_skb, bcs->hw.hscx.count);
+				bcs->tx_cnt += bcs->hw.hscx.count;
+				bcs->hw.hscx.count = 0;
+			}
+			cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x01);  // XRES
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "bch_int() B-%d XDU error", hscx);
+		}
 	}
 }
 
@@ -715,43 +715,43 @@ bch_mode(struct BCState *bcs, int mode, int bc)
 	struct IsdnCardState *cs = bcs->cs;
 	int hscx = bcs->hw.hscx.hscx;
 
-        bc = bc ? 1 : 0;  // in case bc is greater than 1
+	bc = bc ? 1 : 0;  // in case bc is greater than 1
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "mode_bch() switch B-%d mode %d chan %d", hscx, mode, bc);
 	bcs->mode = mode;
 	bcs->channel = bc;
-  
-  // map controller to according timeslot
-  if (!hscx)
-  {
-    cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc);
-    cs->writeisac(cs, IPACX_BCHA_CR,       0x88); 
-  }
-  else
-  {
-    cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc);
-    cs->writeisac(cs, IPACX_BCHB_CR,       0x88); 
-  }
+
+	// map controller to according timeslot
+	if (!hscx)
+	{
+		cs->writeisac(cs, IPACX_BCHA_TSDP_BC1, 0x80 | bc);
+		cs->writeisac(cs, IPACX_BCHA_CR,       0x88);
+	}
+	else
+	{
+		cs->writeisac(cs, IPACX_BCHB_TSDP_BC1, 0x80 | bc);
+		cs->writeisac(cs, IPACX_BCHB_CR,       0x88);
+	}
 
 	switch (mode) {
-		case (L1_MODE_NULL):
-		    cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0);  // rec off
-		    cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x30);  // std adj.
-		    cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF);  // ints off
-		    cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
-		    break;
-		case (L1_MODE_TRANS):
-		    cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88);  // ext transp mode
-		    cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x00);  // xxx00000
-		    cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
-		    cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
-		    break;
-		case (L1_MODE_HDLC):
-		    cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8);  // transp mode 0
-		    cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x01);  // idle=hdlc flags crc enabled
-		    cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
-		    cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
-		    break;
+	case (L1_MODE_NULL):
+		cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC0);  // rec off
+		cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x30);  // std adj.
+		cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, 0xFF);  // ints off
+		cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
+		break;
+	case (L1_MODE_TRANS):
+		cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0x88);  // ext transp mode
+		cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x00);  // xxx00000
+		cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
+		cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
+		break;
+	case (L1_MODE_HDLC):
+		cs->BC_Write_Reg(cs, hscx, IPACX_MODEB, 0xC8);  // transp mode 0
+		cs->BC_Write_Reg(cs, hscx, IPACX_EXMB,  0x01);  // idle=hdlc flags crc enabled
+		cs->BC_Write_Reg(cs, hscx, IPACX_CMDRB, 0x41);  // validate adjustments
+		cs->BC_Write_Reg(cs, hscx, IPACX_MASKB, _MASKB_IMASK);
+		break;
 	}
 }
 
@@ -784,13 +784,13 @@ bch_open_state(struct IsdnCardState *cs, struct BCState *bcs)
 	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
 		if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
 			printk(KERN_WARNING
-				"HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
+			       "HiSax open_bchstate(): No memory for hscx.rcvbuf\n");
 			clear_bit(BC_FLG_INIT, &bcs->Flag);
 			return (1);
 		}
 		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
 			printk(KERN_WARNING
-				"HiSax open_bchstate: No memory for bcs->blog\n");
+			       "HiSax open_bchstate: No memory for bcs->blog\n");
 			clear_bit(BC_FLG_INIT, &bcs->Flag);
 			kfree(bcs->hw.hscx.rcvbuf);
 			bcs->hw.hscx.rcvbuf = NULL;
@@ -842,21 +842,21 @@ bch_init(struct IsdnCardState *cs, int hscx)
 //----------------------------------------------------------
 // Main interrupt handler
 //----------------------------------------------------------
-void 
+void
 interrupt_ipacx(struct IsdnCardState *cs)
 {
 	u_char ista;
-  
+
 	while ((ista = cs->readisac(cs, IPACX_ISTA))) {
-//#################################################  
+//#################################################
 //		printk(KERN_WARNING "interrupt_ipacx(ista=%02x)\n", ista);
-//#################################################  
-    if (ista &0x80) bch_int(cs, 0); // B channel interrupts
-    if (ista &0x40) bch_int(cs, 1);
-    
-    if (ista &0x01) dch_int(cs);    // D channel
-    if (ista &0x10) cic_int(cs);    // Layer 1 state
-  }  
+//#################################################
+		if (ista & 0x80) bch_int(cs, 0); // B channel interrupts
+		if (ista & 0x40) bch_int(cs, 1);
+
+		if (ista & 0x01) dch_int(cs);    // D channel
+		if (ista & 0x10) cic_int(cs);    // Layer 1 state
+	}
 }
 
 //----------------------------------------------------------
@@ -867,17 +867,17 @@ clear_pending_ints(struct IsdnCardState *cs)
 {
 	int ista;
 
-  // all interrupts off
-  cs->writeisac(cs, IPACX_MASK, 0xff);
+	// all interrupts off
+	cs->writeisac(cs, IPACX_MASK, 0xff);
 	cs->writeisac(cs, IPACX_MASKD, 0xff);
 	cs->BC_Write_Reg(cs, 0, IPACX_MASKB, 0xff);
 	cs->BC_Write_Reg(cs, 1, IPACX_MASKB, 0xff);
-  
-  ista = cs->readisac(cs, IPACX_ISTA); 
-  if (ista &0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB);
-  if (ista &0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB);
-  if (ista &0x10) cs->readisac(cs, IPACX_CIR0);
-  if (ista &0x01) cs->readisac(cs, IPACX_ISTAD); 
+
+	ista = cs->readisac(cs, IPACX_ISTA);
+	if (ista & 0x80) cs->BC_Read_Reg(cs, 0, IPACX_ISTAB);
+	if (ista & 0x40) cs->BC_Read_Reg(cs, 1, IPACX_ISTAB);
+	if (ista & 0x10) cs->readisac(cs, IPACX_CIR0);
+	if (ista & 0x01) cs->readisac(cs, IPACX_ISTAD);
 }
 
 //----------------------------------------------------------
@@ -887,23 +887,23 @@ clear_pending_ints(struct IsdnCardState *cs)
 void
 init_ipacx(struct IsdnCardState *cs, int part)
 {
-	if (part &1) {  // initialise chip
-//##################################################  
+	if (part & 1) {  // initialise chip
+//##################################################
 //	printk(KERN_INFO "init_ipacx(%x)\n", part);
-//##################################################  
+//##################################################
 		clear_pending_ints(cs);
 		bch_init(cs, 0);
 		bch_init(cs, 1);
 		dch_init(cs);
 	}
-	if (part &2) {  // reenable all interrupts and start chip
+	if (part & 2) {  // reenable all interrupts and start chip
 		cs->BC_Write_Reg(cs, 0, IPACX_MASKB, _MASKB_IMASK);
 		cs->BC_Write_Reg(cs, 1, IPACX_MASKB, _MASKB_IMASK);
 		cs->writeisac(cs, IPACX_MASKD, _MASKD_IMASK);
 		cs->writeisac(cs, IPACX_MASK, _MASK_IMASK); // global mask register
 
 		// reset HDLC Transmitters/receivers
-		cs->writeisac(cs, IPACX_CMDRD, 0x41); 
+		cs->writeisac(cs, IPACX_CMDRD, 0x41);
 		cs->BC_Write_Reg(cs, 0, IPACX_CMDRB, 0x41);
 		cs->BC_Write_Reg(cs, 1, IPACX_CMDRB, 0x41);
 		ph_command(cs, IPACX_CMD_RES);
@@ -911,4 +911,3 @@ init_ipacx(struct IsdnCardState *cs, int part)
 }
 
 //----------------- end of file -----------------------
-
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 2b66728..bcd70a3 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -49,34 +49,34 @@ static void
 isac_new_ph(struct IsdnCardState *cs)
 {
 	switch (cs->dc.isac.ph_state) {
-		case (ISAC_IND_RS):
-		case (ISAC_IND_EI):
-			ph_command(cs, ISAC_CMD_DUI);
-			l1_msg(cs, HW_RESET | INDICATION, NULL);
-			break;
-		case (ISAC_IND_DID):
-			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
-			break;
-		case (ISAC_IND_DR):
-			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-			break;
-		case (ISAC_IND_PU):
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-		case (ISAC_IND_RSY):
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-			break;
-		case (ISAC_IND_ARD):
-			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-			break;
-		case (ISAC_IND_AI8):
-			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-			break;
-		case (ISAC_IND_AI10):
-			l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
-			break;
-		default:
-			break;
+	case (ISAC_IND_RS):
+	case (ISAC_IND_EI):
+		ph_command(cs, ISAC_CMD_DUI);
+		l1_msg(cs, HW_RESET | INDICATION, NULL);
+		break;
+	case (ISAC_IND_DID):
+		l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
+		break;
+	case (ISAC_IND_DR):
+		l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+		break;
+	case (ISAC_IND_PU):
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		break;
+	case (ISAC_IND_RSY):
+		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+		break;
+	case (ISAC_IND_ARD):
+		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+		break;
+	case (ISAC_IND_AI8):
+		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+		break;
+	case (ISAC_IND_AI10):
+		l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -86,7 +86,7 @@ isac_bh(struct work_struct *work)
 	struct IsdnCardState *cs =
 		container_of(work, struct IsdnCardState, tqueue);
 	struct PStack *stptr;
-	
+
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
 		if (cs->debug)
 			debugl1(cs, "D-Channel Busy cleared");
@@ -97,7 +97,7 @@ isac_bh(struct work_struct *work)
 		}
 	}
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event))
-		isac_new_ph(cs);		
+		isac_new_ph(cs);
 	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event))
 		DChannel_proc_rcv(cs);
 	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
@@ -257,11 +257,11 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 		} else
 			schedule_event(cs, D_XMTBUFREADY);
 	}
-      afterXPR:
+afterXPR:
 	if (val & 0x04) {	/* CISQ */
 		exval = cs->readisac(cs, ISAC_CIR0);
 		if (cs->debug & L1_DEB_ISAC)
-			debugl1(cs, "ISAC CIR0 %02X", exval );
+			debugl1(cs, "ISAC CIR0 %02X", exval);
 		if (exval & 2) {
 			cs->dc.isac.ph_state = (exval >> 2) & 0xf;
 			if (cs->debug & L1_DEB_ISAC)
@@ -271,7 +271,7 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 		if (exval & 1) {
 			exval = cs->readisac(cs, ISAC_CIR1);
 			if (cs->debug & L1_DEB_ISAC)
-				debugl1(cs, "ISAC CIR1 %02X", exval );
+				debugl1(cs, "ISAC CIR1 %02X", exval);
 		}
 	}
 	if (val & 0x02) {	/* SIN */
@@ -334,13 +334,13 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 				}
 				cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR0);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ISAC MOR0 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp -1]);
+					debugl1(cs, "ISAC MOR0 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp - 1]);
 				if (cs->dc.isac.mon_rxp == 1) {
 					cs->dc.isac.mocr |= 0x04;
 					cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
 				}
 			}
-		      afterMONR0:
+		afterMONR0:
 			if (v1 & 0x80) {
 				if (!cs->dc.isac.mon_rx) {
 					if (!(cs->dc.isac.mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
@@ -364,11 +364,11 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 				}
 				cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp++] = cs->readisac(cs, ISAC_MOR1);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ISAC MOR1 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp -1]);
+					debugl1(cs, "ISAC MOR1 %02x", cs->dc.isac.mon_rx[cs->dc.isac.mon_rxp - 1]);
 				cs->dc.isac.mocr |= 0x40;
 				cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
 			}
-		      afterMONR1:
+		afterMONR1:
 			if (v1 & 0x04) {
 				cs->dc.isac.mocr &= 0xf0;
 				cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
@@ -384,15 +384,15 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 				schedule_event(cs, D_RX_MON1);
 			}
 			if (v1 & 0x02) {
-				if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc && 
-					(cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) && 
-					!(v1 & 0x08))) {
+				if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc &&
+							      (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) &&
+							      !(v1 & 0x08))) {
 					cs->dc.isac.mocr &= 0xf0;
 					cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
 					cs->dc.isac.mocr |= 0x0a;
 					cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
 					if (cs->dc.isac.mon_txc &&
-						(cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc))
+					    (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc))
 						schedule_event(cs, D_TX_MON0);
 					goto AfterMOX0;
 				}
@@ -401,21 +401,21 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 					goto AfterMOX0;
 				}
 				cs->writeisac(cs, ISAC_MOX0,
-					cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
+					      cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ISAC %02x -> MOX0", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp -1]);
+					debugl1(cs, "ISAC %02x -> MOX0", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp - 1]);
 			}
-		      AfterMOX0:
+		AfterMOX0:
 			if (v1 & 0x20) {
-				if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc && 
-					(cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) && 
-					!(v1 & 0x80))) {
+				if ((!cs->dc.isac.mon_tx) || (cs->dc.isac.mon_txc &&
+							      (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc) &&
+							      !(v1 & 0x80))) {
 					cs->dc.isac.mocr &= 0x0f;
 					cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
 					cs->dc.isac.mocr |= 0xa0;
 					cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
 					if (cs->dc.isac.mon_txc &&
-						(cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc))
+					    (cs->dc.isac.mon_txp >= cs->dc.isac.mon_txc))
 						schedule_event(cs, D_TX_MON1);
 					goto AfterMOX1;
 				}
@@ -424,11 +424,11 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
 					goto AfterMOX1;
 				}
 				cs->writeisac(cs, ISAC_MOX1,
-					cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
+					      cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
 				if (cs->debug & L1_DEB_MONITOR)
-					debugl1(cs, "ISAC %02x -> MOX1", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp -1]);
+					debugl1(cs, "ISAC %02x -> MOX1", cs->dc.isac.mon_tx[cs->dc.isac.mon_txp - 1]);
 			}
-		      AfterMOX1:;
+		AfterMOX1:;
 #endif
 		}
 	}
@@ -443,123 +443,123 @@ ISAC_l1hw(struct PStack *st, int pr, void *arg)
 	int  val;
 
 	switch (pr) {
-		case (PH_DATA |REQUEST):
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+		} else {
+			cs->tx_skb = skb;
+			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
-				isac_fill_fifo(cs);
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL |INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-			} else {
-				if (cs->debug & DEB_DLOG_HEX)
-					LogFrame(cs, skb->data, skb->len);
-				if (cs->debug & DEB_DLOG_VERBOSE)
-					dlogframe(cs, skb, 0);
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+			isac_fill_fifo(cs);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
+		} else {
+			if (cs->debug & DEB_DLOG_HEX)
+				LogFrame(cs, skb->data, skb->len);
+			if (cs->debug & DEB_DLOG_VERBOSE)
+				dlogframe(cs, skb, 0);
+			cs->tx_skb = skb;
+			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-				isac_fill_fifo(cs);
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
+			isac_fill_fifo(cs);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "-> PH_REQUEST_PULL");
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			if ((cs->dc.isac.ph_state == ISAC_IND_EI) ||
-				(cs->dc.isac.ph_state == ISAC_IND_DR) ||
-				(cs->dc.isac.ph_state == ISAC_IND_RS))
-			        ph_command(cs, ISAC_CMD_TIM);
-			else
-				ph_command(cs, ISAC_CMD_RS);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_ENABLE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		if ((cs->dc.isac.ph_state == ISAC_IND_EI) ||
+		    (cs->dc.isac.ph_state == ISAC_IND_DR) ||
+		    (cs->dc.isac.ph_state == ISAC_IND_RS))
 			ph_command(cs, ISAC_CMD_TIM);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO3 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			ph_command(cs, ISAC_CMD_AR8);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_TESTLOOP | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			val = 0;
-			if (1 & (long) arg)
-				val |= 0x0c;
-			if (2 & (long) arg)
-				val |= 0x3;
-			if (test_bit(HW_IOM1, &cs->HW_Flags)) {
-				/* IOM 1 Mode */
-				if (!val) {
-					cs->writeisac(cs, ISAC_SPCR, 0xa);
-					cs->writeisac(cs, ISAC_ADF1, 0x2);
-				} else {
-					cs->writeisac(cs, ISAC_SPCR, val);
-					cs->writeisac(cs, ISAC_ADF1, 0xa);
-				}
+		else
+			ph_command(cs, ISAC_CMD_RS);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_ENABLE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, ISAC_CMD_TIM);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO3 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, ISAC_CMD_AR8);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_TESTLOOP | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		val = 0;
+		if (1 & (long) arg)
+			val |= 0x0c;
+		if (2 & (long) arg)
+			val |= 0x3;
+		if (test_bit(HW_IOM1, &cs->HW_Flags)) {
+			/* IOM 1 Mode */
+			if (!val) {
+				cs->writeisac(cs, ISAC_SPCR, 0xa);
+				cs->writeisac(cs, ISAC_ADF1, 0x2);
 			} else {
-				/* IOM 2 Mode */
 				cs->writeisac(cs, ISAC_SPCR, val);
-				if (val)
-					cs->writeisac(cs, ISAC_ADF1, 0x8);
-				else
-					cs->writeisac(cs, ISAC_ADF1, 0x0);
+				cs->writeisac(cs, ISAC_ADF1, 0xa);
 			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_DEACTIVATE | RESPONSE):
-			skb_queue_purge(&cs->rq);
-			skb_queue_purge(&cs->sq);
-			if (cs->tx_skb) {
-				dev_kfree_skb_any(cs->tx_skb);
-				cs->tx_skb = NULL;
-			}
-			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-				del_timer(&cs->dbusytimer);
-			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-				schedule_event(cs, D_CLEARBUSY);
-			break;
-		default:
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "isac_l1hw unknown %04x", pr);
-			break;
+		} else {
+			/* IOM 2 Mode */
+			cs->writeisac(cs, ISAC_SPCR, val);
+			if (val)
+				cs->writeisac(cs, ISAC_ADF1, 0x8);
+			else
+				cs->writeisac(cs, ISAC_ADF1, 0x0);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_DEACTIVATE | RESPONSE):
+		skb_queue_purge(&cs->rq);
+		skb_queue_purge(&cs->sq);
+		if (cs->tx_skb) {
+			dev_kfree_skb_any(cs->tx_skb);
+			cs->tx_skb = NULL;
+		}
+		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+			del_timer(&cs->dbusytimer);
+		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+			schedule_event(cs, D_CLEARBUSY);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "isac_l1hw unknown %04x", pr);
+		break;
 	}
 }
 
@@ -587,7 +587,7 @@ dbusy_timer_handler(struct IsdnCardState *cs)
 	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
 		rbch = cs->readisac(cs, ISAC_RBCH);
 		star = cs->readisac(cs, ISAC_STAR);
-		if (cs->debug) 
+		if (cs->debug)
 			debugl1(cs, "D-Channel Busy RBCH %02x STAR %02x",
 				rbch, star);
 		if (rbch & ISAC_RBCH_XAC) { /* D-Channel Busy */
@@ -620,8 +620,8 @@ void initisac(struct IsdnCardState *cs)
 	cs->DC_Close = DC_Close_isac;
 	cs->dc.isac.mon_tx = NULL;
 	cs->dc.isac.mon_rx = NULL;
-  	cs->writeisac(cs, ISAC_MASK, 0xff);
-  	cs->dc.isac.mocr = 0xaa;
+	cs->writeisac(cs, ISAC_MASK, 0xff);
+	cs->dc.isac.mocr = 0xaa;
 	if (test_bit(HW_IOM1, &cs->HW_Flags)) {
 		/* IOM 1 Mode */
 		cs->writeisac(cs, ISAC_ADF2, 0x0);
diff --git a/drivers/isdn/hisax/isac.h b/drivers/isdn/hisax/isac.h
index 8f8331e4..04f16b9 100644
--- a/drivers/isdn/hisax/isac.h
+++ b/drivers/isdn/hisax/isac.h
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index d4cce33..ff5e139 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -22,11 +22,11 @@
 #define ETX	0x03
 
 #define FAXMODCNT	13
-static const	u_char	faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
-static	u_int	modmask = 0x1fff;
-static	int	frm_extra_delay = 2;
-static	int	para_TOA = 6;
-static const   u_char  *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
+static const u_char faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121, 122, 145, 146};
+static u_int modmask = 0x1fff;
+static int frm_extra_delay = 2;
+static int para_TOA = 6;
+static const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL"};
 
 static void isar_setup(struct IsdnCardState *cs);
 static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para);
@@ -42,7 +42,7 @@ waitforHIA(struct IsdnCardState *cs, int timeout)
 	}
 	if (!timeout)
 		printk(KERN_WARNING "HiSax: ISAR waitforHIA timeout\n");
-	return(timeout);
+	return (timeout);
 }
 
 
@@ -51,9 +51,9 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
 	u_char *msg)
 {
 	int i;
-	
+
 	if (!waitforHIA(cs, 4000))
-		return(0);
+		return (0);
 #if DUMP_MBOXFRAME
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "sendmsg(%02x,%02x,%d)", his, creg, len);
@@ -63,17 +63,17 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
 	cs->BC_Write_Reg(cs, 0, ISAR_WADR, 0);
 	if (msg && len) {
 		cs->BC_Write_Reg(cs, 1, ISAR_MBOX, msg[0]);
-		for (i=1; i<len; i++)
+		for (i = 1; i < len; i++)
 			cs->BC_Write_Reg(cs, 2, ISAR_MBOX, msg[i]);
-#if DUMP_MBOXFRAME>1
+#if DUMP_MBOXFRAME > 1
 		if (cs->debug & L1_DEB_HSCX_FIFO) {
 			char tmp[256], *t;
-			
+
 			i = len;
-			while (i>0) {
+			while (i > 0) {
 				t = tmp;
 				t += sprintf(t, "sendmbox cnt %d", len);
-				QuickHex(t, &msg[len-i], (i>64) ? 64:i);
+				QuickHex(t, &msg[len-i], (i > 64) ? 64 : i);
 				debugl1(cs, tmp);
 				i -= 64;
 			}
@@ -82,7 +82,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
 	}
 	cs->BC_Write_Reg(cs, 1, ISAR_HIS, his);
 	waitforHIA(cs, 10000);
-	return(1);
+	return (1);
 }
 
 /* Call only with IRQ disabled !!! */
@@ -94,17 +94,17 @@ rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
 	cs->BC_Write_Reg(cs, 1, ISAR_RADR, 0);
 	if (msg && ireg->clsb) {
 		msg[0] = cs->BC_Read_Reg(cs, 1, ISAR_MBOX);
-		for (i=1; i < ireg->clsb; i++)
-			 msg[i] = cs->BC_Read_Reg(cs, 2, ISAR_MBOX);
-#if DUMP_MBOXFRAME>1
+		for (i = 1; i < ireg->clsb; i++)
+			msg[i] = cs->BC_Read_Reg(cs, 2, ISAR_MBOX);
+#if DUMP_MBOXFRAME > 1
 		if (cs->debug & L1_DEB_HSCX_FIFO) {
 			char tmp[256], *t;
-			
+
 			i = ireg->clsb;
-			while (i>0) {
+			while (i > 0) {
 				t = tmp;
 				t += sprintf(t, "rcv_mbox cnt %d", ireg->clsb);
-				QuickHex(t, &msg[ireg->clsb-i], (i>64) ? 64:i);
+				QuickHex(t, &msg[ireg->clsb - i], (i > 64) ? 64 : i);
 				debugl1(cs, tmp);
 				i -= 64;
 			}
@@ -130,23 +130,23 @@ get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
 
 static int
 waitrecmsg(struct IsdnCardState *cs, u_char *len,
-	u_char *msg, int maxdelay)
+	   u_char *msg, int maxdelay)
 {
 	int timeout = 0;
 	struct isar_reg *ir = cs->bcs[0].hw.isar.reg;
-	
-	
-	while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
-		(timeout++ < maxdelay))
+
+
+	while ((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
+	      (timeout++ < maxdelay))
 		udelay(1);
 	if (timeout > maxdelay) {
 		printk(KERN_WARNING"isar recmsg IRQSTA timeout\n");
-		return(0);
+		return (0);
 	}
 	get_irq_infos(cs, ir);
 	rcv_mbox(cs, ir, msg);
 	*len = ir->clsb;
-	return(1);
+	return (1);
 }
 
 int
@@ -167,11 +167,11 @@ ISARVersion(struct IsdnCardState *cs, char *s)
 	cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
 	if (!sendmsg(cs, ISAR_HIS_VNR, 0, 3, msg)) {
 		spin_unlock_irqrestore(&cs->lock, flags);
-		return(-1);
+		return (-1);
 	}
 	if (!waitrecmsg(cs, &len, tmp, 100000)) {
 		spin_unlock_irqrestore(&cs->lock, flags);
-		return(-2);
+		return (-2);
 	}
 	cs->debug = debug;
 	if (cs->bcs[0].hw.isar.reg->iis == ISAR_IIS_VNR) {
@@ -183,7 +183,7 @@ ISARVersion(struct IsdnCardState *cs, char *s)
 	} else
 		ver = -4;
 	spin_unlock_irqrestore(&cs->lock, flags);
-	return(ver);
+	return (ver);
 }
 
 static int
@@ -196,25 +196,25 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 	u_char *msg, *tmpmsg, *mp, tmp[64];
 	u_long flags;
 	struct isar_reg *ireg = cs->bcs[0].hw.isar.reg;
-	
+
 	struct {u_short sadr;
 		u_short len;
 		u_short d_key;
 	} blk_head;
-		
+
 #define	BLK_HEAD_SIZE 6
 	if (1 != (ret = ISARVersion(cs, "Testing"))) {
 		printk(KERN_ERR"isar_load_firmware wrong isar version %d\n", ret);
-		return(1);
+		return (1);
 	}
 	debug = cs->debug;
-#if DBG_LOADFIRM<2
+#if DBG_LOADFIRM < 2
 	cs->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
 #endif
-	
+
 	cfu_ret = copy_from_user(&size, p, sizeof(int));
 	if (cfu_ret) {
-		printk(KERN_ERR"isar_load_firmware copy_from_user ret %d\n", cfu_ret);
+		printk(KERN_ERR "isar_load_firmware copy_from_user ret %d\n", cfu_ret);
 		return -EFAULT;
 	}
 	p += sizeof(int);
@@ -241,40 +241,40 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 			goto reterror;
 		}
 #ifdef __BIG_ENDIAN
-		sadr = (blk_head.sadr & 0xff)*256 + blk_head.sadr/256;
+		sadr = (blk_head.sadr & 0xff) * 256 + blk_head.sadr / 256;
 		blk_head.sadr = sadr;
-		sadr = (blk_head.len & 0xff)*256 + blk_head.len/256;
+		sadr = (blk_head.len & 0xff) * 256 + blk_head.len / 256;
 		blk_head.len = sadr;
-		sadr = (blk_head.d_key & 0xff)*256 + blk_head.d_key/256;
+		sadr = (blk_head.d_key & 0xff) * 256 + blk_head.d_key / 256;
 		blk_head.d_key = sadr;
 #endif /* __BIG_ENDIAN */
 		cnt += BLK_HEAD_SIZE;
 		p += BLK_HEAD_SIZE;
 		printk(KERN_DEBUG"isar firmware block (%#x,%5d,%#x)\n",
-			blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
+		       blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
 		sadr = blk_head.sadr;
 		left = blk_head.len;
 		spin_lock_irqsave(&cs->lock, flags);
 		if (!sendmsg(cs, ISAR_HIS_DKEY, blk_head.d_key & 0xff, 0, NULL)) {
 			printk(KERN_ERR"isar sendmsg dkey failed\n");
-			ret = 1;goto reterr_unlock;
+			ret = 1; goto reterr_unlock;
 		}
 		if (!waitrecmsg(cs, &len, tmp, 100000)) {
 			printk(KERN_ERR"isar waitrecmsg dkey failed\n");
-			ret = 1;goto reterr_unlock;
+			ret = 1; goto reterr_unlock;
 		}
 		if ((ireg->iis != ISAR_IIS_DKEY) || ireg->cmsb || len) {
 			printk(KERN_ERR"isar wrong dkey response (%x,%x,%x)\n",
-				ireg->iis, ireg->cmsb, len);
-			ret = 1;goto reterr_unlock;
+			       ireg->iis, ireg->cmsb, len);
+			ret = 1; goto reterr_unlock;
 		}
 		spin_unlock_irqrestore(&cs->lock, flags);
-		while (left>0) {
+		while (left > 0) {
 			if (left > 126)
 				noc = 126;
 			else
 				noc = left;
-			nom = 2*noc;
+			nom = 2 * noc;
 			mp  = msg;
 			*mp++ = sadr / 256;
 			*mp++ = sadr % 256;
@@ -290,10 +290,10 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 			sp = (u_short *)tmpmsg;
 #if DBG_LOADFIRM
 			printk(KERN_DEBUG"isar: load %3d words at %04x left %d\n",
-				 noc, sadr, left);
+			       noc, sadr, left);
 #endif
 			sadr += noc;
-			while(noc) {
+			while (noc) {
 #ifdef __BIG_ENDIAN
 				*mp++ = *sp % 256;
 				*mp++ = *sp / 256;
@@ -307,21 +307,21 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 			spin_lock_irqsave(&cs->lock, flags);
 			if (!sendmsg(cs, ISAR_HIS_FIRM, 0, nom, msg)) {
 				printk(KERN_ERR"isar sendmsg prog failed\n");
-				ret = 1;goto reterr_unlock;
+				ret = 1; goto reterr_unlock;
 			}
 			if (!waitrecmsg(cs, &len, tmp, 100000)) {
 				printk(KERN_ERR"isar waitrecmsg prog failed\n");
-				ret = 1;goto reterr_unlock;
+				ret = 1; goto reterr_unlock;
 			}
 			if ((ireg->iis != ISAR_IIS_FIRM) || ireg->cmsb || len) {
 				printk(KERN_ERR"isar wrong prog response (%x,%x,%x)\n",
-					ireg->iis, ireg->cmsb, len);
-				ret = 1;goto reterr_unlock;
+				       ireg->iis, ireg->cmsb, len);
+				ret = 1; goto reterr_unlock;
 			}
 			spin_unlock_irqrestore(&cs->lock, flags);
 		}
 		printk(KERN_DEBUG"isar firmware block %5d words loaded\n",
-			blk_head.len);
+		       blk_head.len);
 	}
 	/* 10ms delay */
 	cnt = 10;
@@ -333,16 +333,16 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 	spin_lock_irqsave(&cs->lock, flags);
 	if (!sendmsg(cs, ISAR_HIS_STDSP, 0, 2, msg)) {
 		printk(KERN_ERR"isar sendmsg start dsp failed\n");
-		ret = 1;goto reterr_unlock;
+		ret = 1; goto reterr_unlock;
 	}
 	if (!waitrecmsg(cs, &len, tmp, 100000)) {
 		printk(KERN_ERR"isar waitrecmsg start dsp failed\n");
-		ret = 1;goto reterr_unlock;
+		ret = 1; goto reterr_unlock;
 	}
 	if ((ireg->iis != ISAR_IIS_STDSP) || ireg->cmsb || len) {
 		printk(KERN_ERR"isar wrong start dsp response (%x,%x,%x)\n",
-			ireg->iis, ireg->cmsb, len);
-		ret = 1;goto reterr_unlock;
+		       ireg->iis, ireg->cmsb, len);
+		ret = 1; goto reterr_unlock;
 	} else
 		printk(KERN_DEBUG"isar start dsp success\n");
 	/* NORMAL mode entered */
@@ -356,10 +356,10 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 	}
 	if (!cnt) {
 		printk(KERN_ERR"isar no general status event received\n");
-		ret = 1;goto reterror;
+		ret = 1; goto reterror;
 	} else {
 		printk(KERN_DEBUG"isar general status event %x\n",
-			ireg->bstat);
+		       ireg->bstat);
 	}
 	/* 10ms delay */
 	cnt = 10;
@@ -369,7 +369,7 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 	ireg->iis = 0;
 	if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
 		printk(KERN_ERR"isar sendmsg self tst failed\n");
-		ret = 1;goto reterr_unlock;
+		ret = 1; goto reterr_unlock;
 	}
 	cnt = 10000; /* max 100 ms */
 	spin_unlock_irqrestore(&cs->lock, flags);
@@ -380,21 +380,21 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 	udelay(1000);
 	if (!cnt) {
 		printk(KERN_ERR"isar no self tst response\n");
-		ret = 1;goto reterror;
+		ret = 1; goto reterror;
 	}
 	if ((ireg->cmsb == ISAR_CTRL_STST) && (ireg->clsb == 1)
-		&& (ireg->par[0] == 0)) {
+	    && (ireg->par[0] == 0)) {
 		printk(KERN_DEBUG"isar selftest OK\n");
 	} else {
 		printk(KERN_DEBUG"isar selftest not OK %x/%x/%x\n",
-			ireg->cmsb, ireg->clsb, ireg->par[0]);
-		ret = 1;goto reterror;
+		       ireg->cmsb, ireg->clsb, ireg->par[0]);
+		ret = 1; goto reterror;
 	}
 	spin_lock_irqsave(&cs->lock, flags);
 	ireg->iis = 0;
 	if (!sendmsg(cs, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
 		printk(KERN_ERR"isar RQST SVN failed\n");
-		ret = 1;goto reterr_unlock;
+		ret = 1; goto reterr_unlock;
 	}
 	spin_unlock_irqrestore(&cs->lock, flags);
 	cnt = 30000; /* max 300 ms */
@@ -405,15 +405,15 @@ isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 	udelay(1000);
 	if (!cnt) {
 		printk(KERN_ERR"isar no SVN response\n");
-		ret = 1;goto reterror;
+		ret = 1; goto reterror;
 	} else {
 		if ((ireg->cmsb == ISAR_CTRL_SWVER) && (ireg->clsb == 1))
 			printk(KERN_DEBUG"isar software version %#x\n",
-				ireg->par[0]);
+			       ireg->par[0]);
 		else {
 			printk(KERN_ERR"isar wrong swver response (%x,%x) cnt(%d)\n",
-				ireg->cmsb, ireg->clsb, cnt);
-			ret = 1;goto reterror;
+			       ireg->cmsb, ireg->clsb, cnt);
+			ret = 1; goto reterror;
 		}
 	}
 	spin_lock_irqsave(&cs->lock, flags);
@@ -430,7 +430,7 @@ reterror:
 		cs->BC_Write_Reg(cs, 0, ISAR_IRQBIT, 0);
 	kfree(msg);
 	kfree(tmpmsg);
-	return(ret);
+	return (ret);
 }
 
 #define B_LL_NOCARRIER	8
@@ -454,9 +454,9 @@ isar_bh(struct work_struct *work)
 static void
 send_DLE_ETX(struct BCState *bcs)
 {
-	u_char dleetx[2] = {DLE,ETX};
+	u_char dleetx[2] = {DLE, ETX};
 	struct sk_buff *skb;
-	
+
 	if ((skb = dev_alloc_skb(2))) {
 		memcpy(skb_put(skb, 2), dleetx, 2);
 		skb_queue_tail(&bcs->rqueue, skb);
@@ -486,14 +486,14 @@ insert_dle(unsigned char *dest, unsigned char *src, int count) {
 			*dest++ = DLE;
 	}
 }
- 
+
 static void
 isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
 {
 	u_char *ptr;
 	struct sk_buff *skb;
 	struct isar_reg *ireg = bcs->hw.isar.reg;
-	
+
 	if (!ireg->clsb) {
 		debugl1(cs, "isar zero len frame");
 		cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
@@ -504,7 +504,7 @@ isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
 		debugl1(cs, "isar mode 0 spurious IIS_RDATA %x/%x/%x",
 			ireg->iis, ireg->cmsb, ireg->clsb);
 		printk(KERN_WARNING"isar mode 0 spurious IIS_RDATA %x/%x/%x\n",
-			ireg->iis, ireg->cmsb, ireg->clsb);
+		       ireg->iis, ireg->cmsb, ireg->clsb);
 		cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
 		break;
 	case L1_MODE_TRANS:
@@ -547,11 +547,11 @@ isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
 					if (cs->debug & L1_DEB_WARN)
 						debugl1(cs, "isar frame to short %d",
 							bcs->hw.isar.rcvidx);
-				} else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx-2))) {
+				} else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx - 2))) {
 					printk(KERN_WARNING "ISAR: receive out of memory\n");
 				} else {
-					memcpy(skb_put(skb, bcs->hw.isar.rcvidx-2),
-						bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2);
+					memcpy(skb_put(skb, bcs->hw.isar.rcvidx - 2),
+					       bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx - 2);
 					skb_queue_tail(&bcs->rqueue, skb);
 					schedule_event(bcs, B_RCVBUFREADY);
 				}
@@ -576,7 +576,7 @@ isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
 					ireg->clsb, bcs->hw.isar.rcvidx);
 			if ((skb = dev_alloc_skb(bcs->hw.isar.rcvidx))) {
 				insert_dle((u_char *)skb_put(skb, bcs->hw.isar.rcvidx),
-					bcs->hw.isar.rcvbuf, ireg->clsb);
+					   bcs->hw.isar.rcvbuf, ireg->clsb);
 				skb_queue_tail(&bcs->rqueue, skb);
 				schedule_event(bcs, B_RCVBUFREADY);
 				if (ireg->cmsb & SART_NMD) { /* ABORT */
@@ -630,13 +630,13 @@ isar_rcv_frame(struct IsdnCardState *cs, struct BCState *bcs)
 						debugl1(cs, "isar frame to short %d",
 							bcs->hw.isar.rcvidx);
 					printk(KERN_WARNING "ISAR: frame to short %d\n",
-						bcs->hw.isar.rcvidx);
+					       bcs->hw.isar.rcvidx);
 				} else if (!(skb = dev_alloc_skb(len))) {
 					printk(KERN_WARNING "ISAR: receive out of memory\n");
 				} else {
 					insert_dle((u_char *)skb_put(skb, len),
-						bcs->hw.isar.rcvbuf,
-						bcs->hw.isar.rcvidx);
+						   bcs->hw.isar.rcvbuf,
+						   bcs->hw.isar.rcvidx);
 					skb_queue_tail(&bcs->rqueue, skb);
 					schedule_event(bcs, B_RCVBUFREADY);
 					send_DLE_ETX(bcs);
@@ -680,8 +680,8 @@ isar_fill_fifo(struct BCState *bcs)
 		return;
 	if (bcs->tx_skb->len <= 0)
 		return;
-	if (!(bcs->hw.isar.reg->bstat & 
-		(bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
+	if (!(bcs->hw.isar.reg->bstat &
+	      (bcs->hw.isar.dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
 		return;
 	if (bcs->tx_skb->len > bcs->hw.isar.mml) {
 		msb = 0;
@@ -694,51 +694,51 @@ isar_fill_fifo(struct BCState *bcs)
 	if (!bcs->hw.isar.txcnt) {
 		msb |= HDLC_FST;
 		if ((bcs->mode == L1_MODE_FAX) &&
-			(bcs->hw.isar.cmd == PCTRL_CMD_FTH)) {
+		    (bcs->hw.isar.cmd == PCTRL_CMD_FTH)) {
 			if (bcs->tx_skb->len > 1) {
-				if ((ptr[0]== 0xff) && (ptr[1] == 0x13))
+				if ((ptr[0] == 0xff) && (ptr[1] == 0x13))
 					/* last frame */
 					test_and_set_bit(BC_FLG_LASTDATA,
-						&bcs->Flag);
-			}  
+							 &bcs->Flag);
+			}
 		}
 	}
 	skb_pull(bcs->tx_skb, count);
 	bcs->tx_cnt -= count;
 	bcs->hw.isar.txcnt += count;
 	switch (bcs->mode) {
-		case L1_MODE_NULL:
-			printk(KERN_ERR"isar_fill_fifo wrong mode 0\n");
-			break;
-		case L1_MODE_TRANS:
-		case L1_MODE_V32:
-			sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
-				0, count, ptr);
-			break;
-		case L1_MODE_HDLC:
+	case L1_MODE_NULL:
+		printk(KERN_ERR"isar_fill_fifo wrong mode 0\n");
+		break;
+	case L1_MODE_TRANS:
+	case L1_MODE_V32:
+		sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
+			0, count, ptr);
+		break;
+	case L1_MODE_HDLC:
+		sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
+			msb, count, ptr);
+		break;
+	case L1_MODE_FAX:
+		if (bcs->hw.isar.state != STFAX_ACTIV) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "isar_fill_fifo: not ACTIV");
+		} else if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) {
 			sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
 				msb, count, ptr);
-			break;
-		case L1_MODE_FAX:
-			if (bcs->hw.isar.state != STFAX_ACTIV) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "isar_fill_fifo: not ACTIV");
-			} else if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) { 
-				sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
-					msb, count, ptr);
-			} else if (bcs->hw.isar.cmd == PCTRL_CMD_FTM) {
-				sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
-					0, count, ptr);
-			} else {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "isar_fill_fifo: not FTH/FTM");
-			}
-			break;
-		default:
-			if (cs->debug)
-				debugl1(cs, "isar_fill_fifo mode(%x) error", bcs->mode);
-			printk(KERN_ERR"isar_fill_fifo mode(%x) error\n", bcs->mode);
-			break;
+		} else if (bcs->hw.isar.cmd == PCTRL_CMD_FTM) {
+			sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) | ISAR_HIS_SDATA,
+				0, count, ptr);
+		} else {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "isar_fill_fifo: not FTH/FTM");
+		}
+		break;
+	default:
+		if (cs->debug)
+			debugl1(cs, "isar_fill_fifo mode(%x) error", bcs->mode);
+		printk(KERN_ERR"isar_fill_fifo mode(%x) error\n", bcs->mode);
+		break;
 	}
 }
 
@@ -746,12 +746,12 @@ static inline
 struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
 {
 	if ((!dpath) || (dpath == 3))
-		return(NULL);
+		return (NULL);
 	if (cs->bcs[0].hw.isar.dpath == dpath)
-		return(&cs->bcs[0]);
+		return (&cs->bcs[0]);
 	if (cs->bcs[1].hw.isar.dpath == dpath)
-		return(&cs->bcs[1]);
-	return(NULL);
+		return (&cs->bcs[1]);
+	return (NULL);
 }
 
 static void
@@ -762,8 +762,8 @@ send_frames(struct BCState *bcs)
 			isar_fill_fifo(bcs);
 			return;
 		} else {
-			if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-				(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+			if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+			    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 				u_long	flags;
 				spin_lock_irqsave(&bcs->aclock, flags);
 				bcs->ackcnt += bcs->hw.isar.txcnt;
@@ -783,7 +783,7 @@ send_frames(struct BCState *bcs)
 				}
 			}
 			dev_kfree_skb_any(bcs->tx_skb);
-			bcs->hw.isar.txcnt = 0; 
+			bcs->hw.isar.txcnt = 0;
 			bcs->tx_skb = NULL;
 		}
 	}
@@ -813,7 +813,7 @@ static inline void
 check_send(struct IsdnCardState *cs, u_char rdm)
 {
 	struct BCState *bcs;
-	
+
 	if (rdm & BSTAT_RDM1) {
 		if ((bcs = sel_bcs_isar(cs, 1))) {
 			if (bcs->mode) {
@@ -828,16 +828,16 @@ check_send(struct IsdnCardState *cs, u_char rdm)
 			}
 		}
 	}
-	
+
 }
 
 static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200",
-				"NODEF4", "300", "600", "1200", "2400",
-				"4800", "7200", "9600nt", "9600t", "12000",
-				"14400", "WRONG"};
+			      "NODEF4", "300", "600", "1200", "2400",
+			      "4800", "7200", "9600nt", "9600t", "12000",
+			      "14400", "WRONG"};
 static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
-				"Bell103", "V23", "Bell202", "V17", "V29",
-				"V27ter"};
+			      "Bell103", "V23", "Bell202", "V17", "V29",
+			      "V27ter"};
 
 static void
 isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) {
@@ -846,48 +846,48 @@ isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) {
 	u_char rim;
 
 	if (!test_and_clear_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags))
-		return; 
+		return;
 	if (ril > 14) {
 		if (cs->debug & L1_DEB_WARN)
-			debugl1(cs, "wrong pstrsp ril=%d",ril);
+			debugl1(cs, "wrong pstrsp ril=%d", ril);
 		ril = 15;
 	}
-	switch(ireg->par[1]) {
-		case 0:
-			rim = 0;
-			break;
-		case 0x20:
-			rim = 2;
-			break;
-		case 0x40:
-			rim = 3;
-			break;
-		case 0x41:
-			rim = 4;
-			break;
-		case 0x51:
-			rim = 5;
-			break;
-		case 0x61:
-			rim = 6;
-			break;
-		case 0x71:
-			rim = 7;
-			break;
-		case 0x82:
-			rim = 8;
-			break;
-		case 0x92:
-			rim = 9;
-			break;
-		case 0xa2:
-			rim = 10;
-			break;
-		default:
-			rim = 1;
-			break;
+	switch (ireg->par[1]) {
+	case 0:
+		rim = 0;
+		break;
+	case 0x20:
+		rim = 2;
+		break;
+	case 0x40:
+		rim = 3;
+		break;
+	case 0x41:
+		rim = 4;
+		break;
+	case 0x51:
+		rim = 5;
+		break;
+	case 0x61:
+		rim = 6;
+		break;
+	case 0x71:
+		rim = 7;
+		break;
+	case 0x82:
+		rim = 8;
+		break;
+	case 0x92:
+		rim = 9;
+		break;
+	case 0xa2:
+		rim = 10;
+		break;
+	default:
+		rim = 1;
+		break;
 	}
-	sprintf(bcs->hw.isar.conmsg,"%s %s", dmril[ril], dmrim[rim]);
+	sprintf(bcs->hw.isar.conmsg, "%s %s", dmril[ril], dmrim[rim]);
 	bcs->conmsg = bcs->hw.isar.conmsg;
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "pump strsp %s", bcs->conmsg);
@@ -898,77 +898,77 @@ isar_pump_statev_modem(struct BCState *bcs, u_char devt) {
 	struct IsdnCardState *cs = bcs->cs;
 	u_char dps = SET_DPS(bcs->hw.isar.dpath);
 
-	switch(devt) {
-		case PSEV_10MS_TIMER:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev TIMER");
-			break;
-		case PSEV_CON_ON:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev CONNECT");
-			l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL);
-			break;
-		case PSEV_CON_OFF:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev NO CONNECT");
-			sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-			l1_msg_b(bcs->st, PH_DEACTIVATE | REQUEST, NULL);
-			break;
-		case PSEV_V24_OFF:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev V24 OFF");
-			break;
-		case PSEV_CTS_ON:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev CTS ON");
-			break;
-		case PSEV_CTS_OFF:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev CTS OFF");
-			break;
-		case PSEV_DCD_ON:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev CARRIER ON");
-			test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags); 
-			sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-			break;
-		case PSEV_DCD_OFF:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev CARRIER OFF");
-			break;
-		case PSEV_DSR_ON:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev DSR ON");
-			break;
-		case PSEV_DSR_OFF:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev DSR_OFF");
-			break;
-		case PSEV_REM_RET:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev REMOTE RETRAIN");
-			break;
-		case PSEV_REM_REN:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev REMOTE RENEGOTIATE");
-			break;
-		case PSEV_GSTN_CLR:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev GSTN CLEAR");
-			break;
-		default:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "unknown pump stev %x", devt);
-			break;
+	switch (devt) {
+	case PSEV_10MS_TIMER:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev TIMER");
+		break;
+	case PSEV_CON_ON:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev CONNECT");
+		l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL);
+		break;
+	case PSEV_CON_OFF:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev NO CONNECT");
+		sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+		l1_msg_b(bcs->st, PH_DEACTIVATE | REQUEST, NULL);
+		break;
+	case PSEV_V24_OFF:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev V24 OFF");
+		break;
+	case PSEV_CTS_ON:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev CTS ON");
+		break;
+	case PSEV_CTS_OFF:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev CTS OFF");
+		break;
+	case PSEV_DCD_ON:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev CARRIER ON");
+		test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags);
+		sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+		break;
+	case PSEV_DCD_OFF:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev CARRIER OFF");
+		break;
+	case PSEV_DSR_ON:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev DSR ON");
+		break;
+	case PSEV_DSR_OFF:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev DSR_OFF");
+		break;
+	case PSEV_REM_RET:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev REMOTE RETRAIN");
+		break;
+	case PSEV_REM_REN:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev REMOTE RENEGOTIATE");
+		break;
+	case PSEV_GSTN_CLR:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev GSTN CLEAR");
+		break;
+	default:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "unknown pump stev %x", devt);
+		break;
 	}
 }
 
 static void
 ll_deliver_faxstat(struct BCState *bcs, u_char status)
 {
-        isdn_ctrl ic;
+	isdn_ctrl ic;
 	struct Channel *chanp = (struct Channel *) bcs->st->lli.userdata;
- 
+
 	if (bcs->cs->debug & L1_DEB_HSCX)
 		debugl1(bcs->cs, "HL->LL FAXIND %x", status);
 	ic.driver = bcs->cs->myid;
@@ -984,153 +984,120 @@ isar_pump_statev_fax(struct BCState *bcs, u_char devt) {
 	u_char dps = SET_DPS(bcs->hw.isar.dpath);
 	u_char p1;
 
-	switch(devt) {
-		case PSEV_10MS_TIMER:
+	switch (devt) {
+	case PSEV_10MS_TIMER:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev TIMER");
+		break;
+	case PSEV_RSP_READY:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev RSP_READY");
+		bcs->hw.isar.state = STFAX_READY;
+		l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL);
+		if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
+			isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FRH, 3);
+		} else {
+			isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FTH, 3);
+		}
+		break;
+	case PSEV_LINE_TX_H:
+		if (bcs->hw.isar.state == STFAX_LINE) {
 			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev TIMER");
-			break;
-		case PSEV_RSP_READY:
+				debugl1(cs, "pump stev LINE_TX_H");
+			bcs->hw.isar.state = STFAX_CONT;
+			sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "pump stev LINE_TX_H wrong st %x",
+					bcs->hw.isar.state);
+		}
+		break;
+	case PSEV_LINE_RX_H:
+		if (bcs->hw.isar.state == STFAX_LINE) {
 			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev RSP_READY");
-			bcs->hw.isar.state = STFAX_READY;
-			l1_msg_b(bcs->st, PH_ACTIVATE | REQUEST, NULL);
-			if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
-				isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FRH, 3);
-			} else {
-				isar_pump_cmd(bcs, ISDN_FAX_CLASS1_FTH, 3);
-			}
-			break;
-		case PSEV_LINE_TX_H:
-			if (bcs->hw.isar.state == STFAX_LINE) {
-				if (cs->debug & L1_DEB_HSCX)
-					debugl1(cs, "pump stev LINE_TX_H");
-				bcs->hw.isar.state = STFAX_CONT;
-				sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
-			} else {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "pump stev LINE_TX_H wrong st %x",
-						bcs->hw.isar.state);
-			}
-			break;
-		case PSEV_LINE_RX_H:
-			if (bcs->hw.isar.state == STFAX_LINE) {
-				if (cs->debug & L1_DEB_HSCX)
-					debugl1(cs, "pump stev LINE_RX_H");
-				bcs->hw.isar.state = STFAX_CONT;
-				sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
-			} else {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "pump stev LINE_RX_H wrong st %x",
-						bcs->hw.isar.state);
-			}
-			break;
-		case PSEV_LINE_TX_B:
-			if (bcs->hw.isar.state == STFAX_LINE) {
-				if (cs->debug & L1_DEB_HSCX)
-					debugl1(cs, "pump stev LINE_TX_B");
-				bcs->hw.isar.state = STFAX_CONT;
-				sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
-			} else {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "pump stev LINE_TX_B wrong st %x",
-						bcs->hw.isar.state);
-			}
-			break;
-		case PSEV_LINE_RX_B:
-			if (bcs->hw.isar.state == STFAX_LINE) {
-				if (cs->debug & L1_DEB_HSCX)
-					debugl1(cs, "pump stev LINE_RX_B");
-				bcs->hw.isar.state = STFAX_CONT;
-				sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
-			} else {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "pump stev LINE_RX_B wrong st %x",
-						bcs->hw.isar.state);
-			}
-			break;
-		case PSEV_RSP_CONN:
-			if (bcs->hw.isar.state == STFAX_CONT) {
-				if (cs->debug & L1_DEB_HSCX)
-					debugl1(cs, "pump stev RSP_CONN");
-				bcs->hw.isar.state = STFAX_ACTIV;
-				test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags);
-				sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
-				if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) {
-					/* 1s Flags before data */
-					if (test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag))
-						del_timer(&bcs->hw.isar.ftimer);
-					/* 1000 ms */
-					bcs->hw.isar.ftimer.expires =
-						jiffies + ((1000 * HZ)/1000);
-					test_and_set_bit(BC_FLG_LL_CONN,
-						&bcs->Flag);
-					add_timer(&bcs->hw.isar.ftimer);
-				} else {
-					schedule_event(bcs, B_LL_CONNECT);
-				}
-			} else {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "pump stev RSP_CONN wrong st %x",
-						bcs->hw.isar.state);
-			}
-			break;
-		case PSEV_FLAGS_DET:
+				debugl1(cs, "pump stev LINE_RX_H");
+			bcs->hw.isar.state = STFAX_CONT;
+			sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "pump stev LINE_RX_H wrong st %x",
+					bcs->hw.isar.state);
+		}
+		break;
+	case PSEV_LINE_TX_B:
+		if (bcs->hw.isar.state == STFAX_LINE) {
 			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev FLAGS_DET");
-			break;
-		case PSEV_RSP_DISC:
+				debugl1(cs, "pump stev LINE_TX_B");
+			bcs->hw.isar.state = STFAX_CONT;
+			sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "pump stev LINE_TX_B wrong st %x",
+					bcs->hw.isar.state);
+		}
+		break;
+	case PSEV_LINE_RX_B:
+		if (bcs->hw.isar.state == STFAX_LINE) {
 			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev RSP_DISC");
-			if (bcs->hw.isar.state == STFAX_ESCAPE) {
-				p1 = 5;
-				switch(bcs->hw.isar.newcmd) {
-					case 0:
-						bcs->hw.isar.state = STFAX_READY;
-						break;
-					case PCTRL_CMD_FTM:
-						p1 = 2;
-					case PCTRL_CMD_FTH:
-						sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
-							PCTRL_CMD_SILON, 1, &p1);
-						bcs->hw.isar.state = STFAX_SILDET;
-						break;
-					case PCTRL_CMD_FRM:
-						if (frm_extra_delay)
-							mdelay(frm_extra_delay);
-					case PCTRL_CMD_FRH:
-						p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod;
-						bcs->hw.isar.newmod = 0;
-						bcs->hw.isar.cmd = bcs->hw.isar.newcmd;
-						bcs->hw.isar.newcmd = 0;
-						sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
-							bcs->hw.isar.cmd, 1, &p1);
-						bcs->hw.isar.state = STFAX_LINE;
-						bcs->hw.isar.try_mod = 3;
-						break;
-					default:
-						if (cs->debug & L1_DEB_HSCX)
-							debugl1(cs, "RSP_DISC unknown newcmd %x", bcs->hw.isar.newcmd);
-						break;
-				}
-			} else if (bcs->hw.isar.state == STFAX_ACTIV) {
-				if (test_and_clear_bit(BC_FLG_LL_OK, &bcs->Flag)) {
-					schedule_event(bcs, B_LL_OK);
-				} else if (bcs->hw.isar.cmd == PCTRL_CMD_FRM) {
-					send_DLE_ETX(bcs);
-					schedule_event(bcs, B_LL_NOCARRIER);
-				} else {
-					ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR);
-				}
-				bcs->hw.isar.state = STFAX_READY;
+				debugl1(cs, "pump stev LINE_RX_B");
+			bcs->hw.isar.state = STFAX_CONT;
+			sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "pump stev LINE_RX_B wrong st %x",
+					bcs->hw.isar.state);
+		}
+		break;
+	case PSEV_RSP_CONN:
+		if (bcs->hw.isar.state == STFAX_CONT) {
+			if (cs->debug & L1_DEB_HSCX)
+				debugl1(cs, "pump stev RSP_CONN");
+			bcs->hw.isar.state = STFAX_ACTIV;
+			test_and_set_bit(ISAR_RATE_REQ, &bcs->hw.isar.reg->Flags);
+			sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+			if (bcs->hw.isar.cmd == PCTRL_CMD_FTH) {
+				/* 1s Flags before data */
+				if (test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag))
+					del_timer(&bcs->hw.isar.ftimer);
+				/* 1000 ms */
+				bcs->hw.isar.ftimer.expires =
+					jiffies + ((1000 * HZ) / 1000);
+				test_and_set_bit(BC_FLG_LL_CONN,
+						 &bcs->Flag);
+				add_timer(&bcs->hw.isar.ftimer);
 			} else {
-				bcs->hw.isar.state = STFAX_READY;
-				ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR);
+				schedule_event(bcs, B_LL_CONNECT);
 			}
-			break;
-		case PSEV_RSP_SILDET:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev RSP_SILDET");
-			if (bcs->hw.isar.state == STFAX_SILDET) {
+		} else {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, "pump stev RSP_CONN wrong st %x",
+					bcs->hw.isar.state);
+		}
+		break;
+	case PSEV_FLAGS_DET:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev FLAGS_DET");
+		break;
+	case PSEV_RSP_DISC:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev RSP_DISC");
+		if (bcs->hw.isar.state == STFAX_ESCAPE) {
+			p1 = 5;
+			switch (bcs->hw.isar.newcmd) {
+			case 0:
+				bcs->hw.isar.state = STFAX_READY;
+				break;
+			case PCTRL_CMD_FTM:
+				p1 = 2;
+			case PCTRL_CMD_FTH:
+				sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
+					PCTRL_CMD_SILON, 1, &p1);
+				bcs->hw.isar.state = STFAX_SILDET;
+				break;
+			case PCTRL_CMD_FRM:
+				if (frm_extra_delay)
+					mdelay(frm_extra_delay);
+			case PCTRL_CMD_FRH:
 				p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod;
 				bcs->hw.isar.newmod = 0;
 				bcs->hw.isar.cmd = bcs->hw.isar.newcmd;
@@ -1139,32 +1106,65 @@ isar_pump_statev_fax(struct BCState *bcs, u_char devt) {
 					bcs->hw.isar.cmd, 1, &p1);
 				bcs->hw.isar.state = STFAX_LINE;
 				bcs->hw.isar.try_mod = 3;
-			}
-			break;
-		case PSEV_RSP_SILOFF:
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev RSP_SILOFF");
-			break;
-		case PSEV_RSP_FCERR:
-			if (bcs->hw.isar.state == STFAX_LINE) {
+				break;
+			default:
 				if (cs->debug & L1_DEB_HSCX)
-					debugl1(cs, "pump stev RSP_FCERR try %d",
-						bcs->hw.isar.try_mod);
-				if (bcs->hw.isar.try_mod--) {
-					sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
-						bcs->hw.isar.cmd, 1,
-						&bcs->hw.isar.mod);
-					break;
-				}
+					debugl1(cs, "RSP_DISC unknown newcmd %x", bcs->hw.isar.newcmd);
+				break;
 			}
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "pump stev RSP_FCERR");
-			bcs->hw.isar.state = STFAX_ESCAPE;
-			sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
+		} else if (bcs->hw.isar.state == STFAX_ACTIV) {
+			if (test_and_clear_bit(BC_FLG_LL_OK, &bcs->Flag)) {
+				schedule_event(bcs, B_LL_OK);
+			} else if (bcs->hw.isar.cmd == PCTRL_CMD_FRM) {
+				send_DLE_ETX(bcs);
+				schedule_event(bcs, B_LL_NOCARRIER);
+			} else {
+				ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR);
+			}
+			bcs->hw.isar.state = STFAX_READY;
+		} else {
+			bcs->hw.isar.state = STFAX_READY;
 			ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR);
-			break;
-		default:
-			break;
+		}
+		break;
+	case PSEV_RSP_SILDET:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev RSP_SILDET");
+		if (bcs->hw.isar.state == STFAX_SILDET) {
+			p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod;
+			bcs->hw.isar.newmod = 0;
+			bcs->hw.isar.cmd = bcs->hw.isar.newcmd;
+			bcs->hw.isar.newcmd = 0;
+			sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
+				bcs->hw.isar.cmd, 1, &p1);
+			bcs->hw.isar.state = STFAX_LINE;
+			bcs->hw.isar.try_mod = 3;
+		}
+		break;
+	case PSEV_RSP_SILOFF:
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev RSP_SILOFF");
+		break;
+	case PSEV_RSP_FCERR:
+		if (bcs->hw.isar.state == STFAX_LINE) {
+			if (cs->debug & L1_DEB_HSCX)
+				debugl1(cs, "pump stev RSP_FCERR try %d",
+					bcs->hw.isar.try_mod);
+			if (bcs->hw.isar.try_mod--) {
+				sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
+					bcs->hw.isar.cmd, 1,
+					&bcs->hw.isar.mod);
+				break;
+			}
+		}
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "pump stev RSP_FCERR");
+		bcs->hw.isar.state = STFAX_ESCAPE;
+		sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
+		ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_FCERROR);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -1178,91 +1178,91 @@ isar_int_main(struct IsdnCardState *cs)
 
 	get_irq_infos(cs, ireg);
 	switch (ireg->iis & ISAR_IIS_MSCMSD) {
-		case ISAR_IIS_RDATA:
-			if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
-				isar_rcv_frame(cs, bcs);
-			} else {
-				debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x",
-					ireg->iis, ireg->cmsb, ireg->clsb);
-				cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
-			}
-			break;
-		case ISAR_IIS_GSTEV:
+	case ISAR_IIS_RDATA:
+		if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
+			isar_rcv_frame(cs, bcs);
+		} else {
+			debugl1(cs, "isar spurious IIS_RDATA %x/%x/%x",
+				ireg->iis, ireg->cmsb, ireg->clsb);
 			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
-			ireg->bstat |= ireg->cmsb;
-			check_send(cs, ireg->cmsb);
-			break;
-		case ISAR_IIS_BSTEV:
+		}
+		break;
+	case ISAR_IIS_GSTEV:
+		cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+		ireg->bstat |= ireg->cmsb;
+		check_send(cs, ireg->cmsb);
+		break;
+	case ISAR_IIS_BSTEV:
 #ifdef ERROR_STATISTIC
-			if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
-				if (ireg->cmsb == BSTEV_TBO)
-					bcs->err_tx++;
-				if (ireg->cmsb == BSTEV_RBO)
-					bcs->err_rdo++;
-			}
+		if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
+			if (ireg->cmsb == BSTEV_TBO)
+				bcs->err_tx++;
+			if (ireg->cmsb == BSTEV_RBO)
+				bcs->err_rdo++;
+		}
 #endif
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "Buffer STEV dpath%d msb(%x)",
-					ireg->iis>>6, ireg->cmsb);
-			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
-			break;
-		case ISAR_IIS_PSTEV:
-			if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
-				rcv_mbox(cs, ireg, (u_char *)ireg->par);
-				if (bcs->mode == L1_MODE_V32) {
-					isar_pump_statev_modem(bcs, ireg->cmsb);
-				} else if (bcs->mode == L1_MODE_FAX) {
-					isar_pump_statev_fax(bcs, ireg->cmsb);
-				} else if (ireg->cmsb == PSEV_10MS_TIMER) {
-					if (cs->debug & L1_DEB_HSCX)
-						debugl1(cs, "pump stev TIMER");
-				} else {
-					if (cs->debug & L1_DEB_WARN)
-						debugl1(cs, "isar IIS_PSTEV pmode %d stat %x",
-							bcs->mode, ireg->cmsb);
-				}
-			} else {
-				debugl1(cs, "isar spurious IIS_PSTEV %x/%x/%x",
-					ireg->iis, ireg->cmsb, ireg->clsb);
-				cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
-			}
-			break;
-		case ISAR_IIS_PSTRSP:
-			if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
-				rcv_mbox(cs, ireg, (u_char *)ireg->par);
-				isar_pump_status_rsp(bcs, ireg);
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "Buffer STEV dpath%d msb(%x)",
+				ireg->iis >> 6, ireg->cmsb);
+		cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+		break;
+	case ISAR_IIS_PSTEV:
+		if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
+			rcv_mbox(cs, ireg, (u_char *)ireg->par);
+			if (bcs->mode == L1_MODE_V32) {
+				isar_pump_statev_modem(bcs, ireg->cmsb);
+			} else if (bcs->mode == L1_MODE_FAX) {
+				isar_pump_statev_fax(bcs, ireg->cmsb);
+			} else if (ireg->cmsb == PSEV_10MS_TIMER) {
+				if (cs->debug & L1_DEB_HSCX)
+					debugl1(cs, "pump stev TIMER");
 			} else {
-				debugl1(cs, "isar spurious IIS_PSTRSP %x/%x/%x",
-					ireg->iis, ireg->cmsb, ireg->clsb);
-				cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, "isar IIS_PSTEV pmode %d stat %x",
+						bcs->mode, ireg->cmsb);
 			}
-			break;
-		case ISAR_IIS_DIAG:
-		case ISAR_IIS_BSTRSP:
-		case ISAR_IIS_IOM2RSP:
+		} else {
+			debugl1(cs, "isar spurious IIS_PSTEV %x/%x/%x",
+				ireg->iis, ireg->cmsb, ireg->clsb);
+			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+		}
+		break;
+	case ISAR_IIS_PSTRSP:
+		if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) {
 			rcv_mbox(cs, ireg, (u_char *)ireg->par);
-			if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO))
-				== L1_DEB_HSCX) {
-				u_char *tp=debbuf;
-
-				tp += sprintf(debbuf, "msg iis(%x) msb(%x)",
-					ireg->iis, ireg->cmsb);
-				QuickHex(tp, (u_char *)ireg->par, ireg->clsb);
-				debugl1(cs, debbuf);
-			}
-			break;
-		case ISAR_IIS_INVMSG:
-			rcv_mbox(cs, ireg, debbuf);
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "invalid msg his:%x",
-					ireg->cmsb);
-			break;
-		default:
-			rcv_mbox(cs, ireg, debbuf);
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)",
-					ireg->iis, ireg->cmsb, ireg->clsb);
-			break;
+			isar_pump_status_rsp(bcs, ireg);
+		} else {
+			debugl1(cs, "isar spurious IIS_PSTRSP %x/%x/%x",
+				ireg->iis, ireg->cmsb, ireg->clsb);
+			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
+		}
+		break;
+	case ISAR_IIS_DIAG:
+	case ISAR_IIS_BSTRSP:
+	case ISAR_IIS_IOM2RSP:
+		rcv_mbox(cs, ireg, (u_char *)ireg->par);
+		if ((cs->debug & (L1_DEB_HSCX | L1_DEB_HSCX_FIFO))
+		    == L1_DEB_HSCX) {
+			u_char *tp = debbuf;
+
+			tp += sprintf(debbuf, "msg iis(%x) msb(%x)",
+				      ireg->iis, ireg->cmsb);
+			QuickHex(tp, (u_char *)ireg->par, ireg->clsb);
+			debugl1(cs, debbuf);
+		}
+		break;
+	case ISAR_IIS_INVMSG:
+		rcv_mbox(cs, ireg, debbuf);
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "invalid msg his:%x",
+				ireg->cmsb);
+		break;
+	default:
+		rcv_mbox(cs, ireg, debbuf);
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "unhandled msg iis(%x) ctrl(%x/%x)",
+				ireg->iis, ireg->cmsb, ireg->clsb);
+		break;
 	}
 }
 
@@ -1287,42 +1287,42 @@ setup_pump(struct BCState *bcs) {
 	u_char ctrl, param[6];
 
 	switch (bcs->mode) {
-		case L1_MODE_NULL:
-		case L1_MODE_TRANS:
-		case L1_MODE_HDLC:
-			sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
-			break;
-		case L1_MODE_V32:
-			ctrl = PMOD_DATAMODEM;
-			if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
-				ctrl |= PCTRL_ORIG;
-				param[5] = PV32P6_CTN;
-			} else {
-				param[5] = PV32P6_ATN;
-			}
-			param[0] = para_TOA; /* 6 db */
-			param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
-				   PV32P2_V22C | PV32P2_V21 | PV32P2_BEL; 
-			param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
-			param[3] = PV32P4_UT144;
-			param[4] = PV32P5_UT144;
-			sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
-			break;
-		case L1_MODE_FAX:
-			ctrl = PMOD_FAX;
-			if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
-				ctrl |= PCTRL_ORIG;
-				param[1] = PFAXP2_CTN;
-			} else {
-				param[1] = PFAXP2_ATN;
-			}
-			param[0] = para_TOA; /* 6 db */
-			sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
-			bcs->hw.isar.state = STFAX_NULL;
-			bcs->hw.isar.newcmd = 0;
-			bcs->hw.isar.newmod = 0;
-			test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag);
-			break;
+	case L1_MODE_NULL:
+	case L1_MODE_TRANS:
+	case L1_MODE_HDLC:
+		sendmsg(cs, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
+		break;
+	case L1_MODE_V32:
+		ctrl = PMOD_DATAMODEM;
+		if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
+			ctrl |= PCTRL_ORIG;
+			param[5] = PV32P6_CTN;
+		} else {
+			param[5] = PV32P6_ATN;
+		}
+		param[0] = para_TOA; /* 6 db */
+		param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
+			PV32P2_V22C | PV32P2_V21 | PV32P2_BEL;
+		param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
+		param[3] = PV32P4_UT144;
+		param[4] = PV32P5_UT144;
+		sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
+		break;
+	case L1_MODE_FAX:
+		ctrl = PMOD_FAX;
+		if (test_bit(BC_FLG_ORIG, &bcs->Flag)) {
+			ctrl |= PCTRL_ORIG;
+			param[1] = PFAXP2_CTN;
+		} else {
+			param[1] = PFAXP2_ATN;
+		}
+		param[0] = para_TOA; /* 6 db */
+		sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
+		bcs->hw.isar.state = STFAX_NULL;
+		bcs->hw.isar.newcmd = 0;
+		bcs->hw.isar.newmod = 0;
+		test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag);
+		break;
 	}
 	udelay(1000);
 	sendmsg(cs, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
@@ -1334,31 +1334,31 @@ setup_sart(struct BCState *bcs) {
 	struct IsdnCardState *cs = bcs->cs;
 	u_char dps = SET_DPS(bcs->hw.isar.dpath);
 	u_char ctrl, param[2];
-	
+
 	switch (bcs->mode) {
-		case L1_MODE_NULL:
-			sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0,
-				NULL);
-			break;
-		case L1_MODE_TRANS:
-			sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2,
-				"\0\0");
-			break;
-		case L1_MODE_HDLC:
-			param[0] = 0;
-			sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1,
-				param);
-			break;
-		case L1_MODE_V32:
-			ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
-			param[0] = S_P1_CHS_8;
-			param[1] = S_P2_BFT_DEF;
-			sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2,
-				param);
-			break;
-		case L1_MODE_FAX:
-			/* SART must not configured with FAX */
-			break;
+	case L1_MODE_NULL:
+		sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE, 0,
+			NULL);
+		break;
+	case L1_MODE_TRANS:
+		sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_BINARY, 2,
+			"\0\0");
+		break;
+	case L1_MODE_HDLC:
+		param[0] = 0;
+		sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1,
+			param);
+		break;
+	case L1_MODE_V32:
+		ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
+		param[0] = S_P1_CHS_8;
+		param[1] = S_P2_BFT_DEF;
+		sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2,
+			param);
+		break;
+	case L1_MODE_FAX:
+		/* SART must not configured with FAX */
+		break;
 	}
 	udelay(1000);
 	sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
@@ -1369,23 +1369,23 @@ static void
 setup_iom2(struct BCState *bcs) {
 	struct IsdnCardState *cs = bcs->cs;
 	u_char dps = SET_DPS(bcs->hw.isar.dpath);
-	u_char cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD,0,0,0,0};
-	
+	u_char cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0};
+
 	if (bcs->channel)
 		msg[1] = msg[3] = 1;
 	switch (bcs->mode) {
-		case L1_MODE_NULL:
-			cmsb = 0;
-			/* dummy slot */
-			msg[1] = msg[3] = bcs->hw.isar.dpath + 2;
-			break;
-		case L1_MODE_TRANS:
-		case L1_MODE_HDLC:
-			break;
-		case L1_MODE_V32:
-		case L1_MODE_FAX:
-			cmsb |= IOM_CTRL_ALAW | IOM_CTRL_RCV;
-			break;
+	case L1_MODE_NULL:
+		cmsb = 0;
+		/* dummy slot */
+		msg[1] = msg[3] = bcs->hw.isar.dpath + 2;
+		break;
+	case L1_MODE_TRANS:
+	case L1_MODE_HDLC:
+		break;
+	case L1_MODE_V32:
+	case L1_MODE_FAX:
+		cmsb |= IOM_CTRL_ALAW | IOM_CTRL_RCV;
+		break;
 	}
 	sendmsg(cs, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg);
 	udelay(1000);
@@ -1399,40 +1399,40 @@ modeisar(struct BCState *bcs, int mode, int bc)
 	struct IsdnCardState *cs = bcs->cs;
 
 	/* Here we are selecting the best datapath for requested mode */
-	if(bcs->mode == L1_MODE_NULL) { /* New Setup */
+	if (bcs->mode == L1_MODE_NULL) { /* New Setup */
 		bcs->channel = bc;
 		switch (mode) {
-			case L1_MODE_NULL: /* init */
-				if (!bcs->hw.isar.dpath)
-					/* no init for dpath 0 */
-					return(0);
-				break;
-			case L1_MODE_TRANS:
-			case L1_MODE_HDLC:
-				/* best is datapath 2 */
-				if (!test_and_set_bit(ISAR_DP2_USE, 
-					&bcs->hw.isar.reg->Flags))
-					bcs->hw.isar.dpath = 2;
-				else if (!test_and_set_bit(ISAR_DP1_USE,
-					&bcs->hw.isar.reg->Flags))
-					bcs->hw.isar.dpath = 1;
-				else {
-					printk(KERN_WARNING"isar modeisar both pathes in use\n");
-					return(1);
-				}
-				break;
-			case L1_MODE_V32:
-			case L1_MODE_FAX:
-				/* only datapath 1 */
-				if (!test_and_set_bit(ISAR_DP1_USE, 
-					&bcs->hw.isar.reg->Flags))
-					bcs->hw.isar.dpath = 1;
-				else {
-					printk(KERN_WARNING"isar modeisar analog functions only with DP1\n");
-					debugl1(cs, "isar modeisar analog functions only with DP1");
-					return(1);
-				}
-				break;
+		case L1_MODE_NULL: /* init */
+			if (!bcs->hw.isar.dpath)
+				/* no init for dpath 0 */
+				return (0);
+			break;
+		case L1_MODE_TRANS:
+		case L1_MODE_HDLC:
+			/* best is datapath 2 */
+			if (!test_and_set_bit(ISAR_DP2_USE,
+					      &bcs->hw.isar.reg->Flags))
+				bcs->hw.isar.dpath = 2;
+			else if (!test_and_set_bit(ISAR_DP1_USE,
+						   &bcs->hw.isar.reg->Flags))
+				bcs->hw.isar.dpath = 1;
+			else {
+				printk(KERN_WARNING"isar modeisar both pathes in use\n");
+				return (1);
+			}
+			break;
+		case L1_MODE_V32:
+		case L1_MODE_FAX:
+			/* only datapath 1 */
+			if (!test_and_set_bit(ISAR_DP1_USE,
+					      &bcs->hw.isar.reg->Flags))
+				bcs->hw.isar.dpath = 1;
+			else {
+				printk(KERN_WARNING"isar modeisar analog functions only with DP1\n");
+				debugl1(cs, "isar modeisar analog functions only with DP1");
+				return (1);
+			}
+			break;
 		}
 	}
 	if (cs->debug & L1_DEB_HSCX)
@@ -1450,118 +1450,118 @@ modeisar(struct BCState *bcs, int mode, int bc)
 			test_and_clear_bit(ISAR_DP2_USE, &bcs->hw.isar.reg->Flags);
 		bcs->hw.isar.dpath = 0;
 	}
-	return(0);
+	return (0);
 }
 
 static void
-isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para) 
+isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para)
 {
 	struct IsdnCardState *cs = bcs->cs;
 	u_char dps = SET_DPS(bcs->hw.isar.dpath);
 	u_char ctrl = 0, nom = 0, p1 = 0;
 
-	switch(cmd) {
-		case ISDN_FAX_CLASS1_FTM:
-			test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
-			if (bcs->hw.isar.state == STFAX_READY) {
-				p1 = para;
-				ctrl = PCTRL_CMD_FTM;
-				nom = 1;
-				bcs->hw.isar.state = STFAX_LINE;
-				bcs->hw.isar.cmd = ctrl;
-				bcs->hw.isar.mod = para;
-				bcs->hw.isar.newmod = 0;
-				bcs->hw.isar.newcmd = 0;
-				bcs->hw.isar.try_mod = 3; 
-			} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
-				(bcs->hw.isar.cmd == PCTRL_CMD_FTM) &&
-				(bcs->hw.isar.mod == para)) {
-				ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
-			} else {
-				bcs->hw.isar.newmod = para;
-				bcs->hw.isar.newcmd = PCTRL_CMD_FTM;
-				nom = 0;
-				ctrl = PCTRL_CMD_ESC;
-				bcs->hw.isar.state = STFAX_ESCAPE; 
-			}
-			break;
-		case ISDN_FAX_CLASS1_FTH:
-			test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
-			if (bcs->hw.isar.state == STFAX_READY) {
-				p1 = para;
-				ctrl = PCTRL_CMD_FTH;
-				nom = 1;
-				bcs->hw.isar.state = STFAX_LINE;
-				bcs->hw.isar.cmd = ctrl;
-				bcs->hw.isar.mod = para;
-				bcs->hw.isar.newmod = 0;
-				bcs->hw.isar.newcmd = 0;
-				bcs->hw.isar.try_mod = 3; 
-			} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
-				(bcs->hw.isar.cmd == PCTRL_CMD_FTH) &&
-				(bcs->hw.isar.mod == para)) {
-				ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
-			} else {
-				bcs->hw.isar.newmod = para;
-				bcs->hw.isar.newcmd = PCTRL_CMD_FTH;
-				nom = 0;
-				ctrl = PCTRL_CMD_ESC;
-				bcs->hw.isar.state = STFAX_ESCAPE; 
-			}
-			break;
-		case ISDN_FAX_CLASS1_FRM:
-			test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
-			if (bcs->hw.isar.state == STFAX_READY) {
-				p1 = para;
-				ctrl = PCTRL_CMD_FRM;
-				nom = 1;
-				bcs->hw.isar.state = STFAX_LINE;
-				bcs->hw.isar.cmd = ctrl;
-				bcs->hw.isar.mod = para;
-				bcs->hw.isar.newmod = 0;
-				bcs->hw.isar.newcmd = 0;
-				bcs->hw.isar.try_mod = 3; 
-			} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
-				(bcs->hw.isar.cmd == PCTRL_CMD_FRM) &&
-				(bcs->hw.isar.mod == para)) {
-				ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
-			} else {
-				bcs->hw.isar.newmod = para;
-				bcs->hw.isar.newcmd = PCTRL_CMD_FRM;
-				nom = 0;
-				ctrl = PCTRL_CMD_ESC;
-				bcs->hw.isar.state = STFAX_ESCAPE; 
-			}
-			break;
-		case ISDN_FAX_CLASS1_FRH:
-			test_and_set_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
-			if (bcs->hw.isar.state == STFAX_READY) {
-				p1 = para;
-				ctrl = PCTRL_CMD_FRH;
-				nom = 1;
-				bcs->hw.isar.state = STFAX_LINE;
-				bcs->hw.isar.cmd = ctrl;
-				bcs->hw.isar.mod = para;
-				bcs->hw.isar.newmod = 0;
-				bcs->hw.isar.newcmd = 0;
-				bcs->hw.isar.try_mod = 3; 
-			} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
-				(bcs->hw.isar.cmd == PCTRL_CMD_FRH) &&
-				(bcs->hw.isar.mod == para)) {
-				ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
-			} else {
-				bcs->hw.isar.newmod = para;
-				bcs->hw.isar.newcmd = PCTRL_CMD_FRH;
-				nom = 0;
-				ctrl = PCTRL_CMD_ESC;
-				bcs->hw.isar.state = STFAX_ESCAPE; 
-			}
-			break;
-		case ISDN_FAXPUMP_HALT:
-			bcs->hw.isar.state = STFAX_NULL;
+	switch (cmd) {
+	case ISDN_FAX_CLASS1_FTM:
+		test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
+		if (bcs->hw.isar.state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FTM;
+			nom = 1;
+			bcs->hw.isar.state = STFAX_LINE;
+			bcs->hw.isar.cmd = ctrl;
+			bcs->hw.isar.mod = para;
+			bcs->hw.isar.newmod = 0;
+			bcs->hw.isar.newcmd = 0;
+			bcs->hw.isar.try_mod = 3;
+		} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
+			   (bcs->hw.isar.cmd == PCTRL_CMD_FTM) &&
+			   (bcs->hw.isar.mod == para)) {
+			ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
+		} else {
+			bcs->hw.isar.newmod = para;
+			bcs->hw.isar.newcmd = PCTRL_CMD_FTM;
 			nom = 0;
-			ctrl = PCTRL_CMD_HALT;
-			break;
+			ctrl = PCTRL_CMD_ESC;
+			bcs->hw.isar.state = STFAX_ESCAPE;
+		}
+		break;
+	case ISDN_FAX_CLASS1_FTH:
+		test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
+		if (bcs->hw.isar.state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FTH;
+			nom = 1;
+			bcs->hw.isar.state = STFAX_LINE;
+			bcs->hw.isar.cmd = ctrl;
+			bcs->hw.isar.mod = para;
+			bcs->hw.isar.newmod = 0;
+			bcs->hw.isar.newcmd = 0;
+			bcs->hw.isar.try_mod = 3;
+		} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
+			   (bcs->hw.isar.cmd == PCTRL_CMD_FTH) &&
+			   (bcs->hw.isar.mod == para)) {
+			ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
+		} else {
+			bcs->hw.isar.newmod = para;
+			bcs->hw.isar.newcmd = PCTRL_CMD_FTH;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			bcs->hw.isar.state = STFAX_ESCAPE;
+		}
+		break;
+	case ISDN_FAX_CLASS1_FRM:
+		test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
+		if (bcs->hw.isar.state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FRM;
+			nom = 1;
+			bcs->hw.isar.state = STFAX_LINE;
+			bcs->hw.isar.cmd = ctrl;
+			bcs->hw.isar.mod = para;
+			bcs->hw.isar.newmod = 0;
+			bcs->hw.isar.newcmd = 0;
+			bcs->hw.isar.try_mod = 3;
+		} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
+			   (bcs->hw.isar.cmd == PCTRL_CMD_FRM) &&
+			   (bcs->hw.isar.mod == para)) {
+			ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
+		} else {
+			bcs->hw.isar.newmod = para;
+			bcs->hw.isar.newcmd = PCTRL_CMD_FRM;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			bcs->hw.isar.state = STFAX_ESCAPE;
+		}
+		break;
+	case ISDN_FAX_CLASS1_FRH:
+		test_and_set_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
+		if (bcs->hw.isar.state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FRH;
+			nom = 1;
+			bcs->hw.isar.state = STFAX_LINE;
+			bcs->hw.isar.cmd = ctrl;
+			bcs->hw.isar.mod = para;
+			bcs->hw.isar.newmod = 0;
+			bcs->hw.isar.newcmd = 0;
+			bcs->hw.isar.try_mod = 3;
+		} else if ((bcs->hw.isar.state == STFAX_ACTIV) &&
+			   (bcs->hw.isar.cmd == PCTRL_CMD_FRH) &&
+			   (bcs->hw.isar.mod == para)) {
+			ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_CONNECT);
+		} else {
+			bcs->hw.isar.newmod = para;
+			bcs->hw.isar.newcmd = PCTRL_CMD_FRH;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			bcs->hw.isar.state = STFAX_ESCAPE;
+		}
+		break;
+	case ISDN_FAXPUMP_HALT:
+		bcs->hw.isar.state = STFAX_NULL;
+		nom = 0;
+		ctrl = PCTRL_CMD_HALT;
+		break;
 	}
 	if (ctrl)
 		sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
@@ -1572,10 +1572,10 @@ isar_setup(struct IsdnCardState *cs)
 {
 	u_char msg;
 	int i;
-	
+
 	/* Dpath 1, 2 */
 	msg = 61;
-	for (i=0; i<2; i++) {
+	for (i = 0; i < 2; i++) {
 		/* Buffer Config */
 		sendmsg(cs, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
 			ISAR_HIS_P12CFG, 4, 1, &msg);
@@ -1596,93 +1596,93 @@ isar_l2l1(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				if (bcs->cs->debug & L1_DEB_HSCX)
-					debugl1(bcs->cs, "DRQ set BC_FLG_BUSY");
-				bcs->hw.isar.txcnt = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			if (bcs->cs->debug & L1_DEB_HSCX)
+				debugl1(bcs->cs, "DRQ set BC_FLG_BUSY");
+			bcs->hw.isar.txcnt = 0;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "isar_l2l1: this shouldn't happen\n");
+		} else {
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+			if (bcs->cs->debug & L1_DEB_HSCX)
+				debugl1(bcs->cs, "PUI set BC_FLG_BUSY");
+			bcs->tx_skb = skb;
+			bcs->hw.isar.txcnt = 0;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		bcs->hw.isar.conmsg[0] = 0;
+		if (test_bit(FLG_ORIG, &st->l2.flag))
+			test_and_set_bit(BC_FLG_ORIG, &bcs->Flag);
+		else
+			test_and_clear_bit(BC_FLG_ORIG, &bcs->Flag);
+		switch (st->l1.mode) {
+		case L1_MODE_TRANS:
+		case L1_MODE_HDLC:
+			ret = modeisar(bcs, st->l1.mode, st->l1.bc);
 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
+			if (ret)
+				l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg);
+			else
+				l1_msg_b(st, PH_ACTIVATE | REQUEST, arg);
 			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "isar_l2l1: this shouldn't happen\n");
-			} else {
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				if (bcs->cs->debug & L1_DEB_HSCX)
-					debugl1(bcs->cs, "PUI set BC_FLG_BUSY");
-				bcs->tx_skb = skb;
-				bcs->hw.isar.txcnt = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
+		case L1_MODE_V32:
+		case L1_MODE_FAX:
+			ret = modeisar(bcs, st->l1.mode, st->l1.bc);
 			spin_unlock_irqrestore(&bcs->cs->lock, flags);
+			if (ret)
+				l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg);
 			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			bcs->hw.isar.conmsg[0] = 0;
-			if (test_bit(FLG_ORIG, &st->l2.flag))
-				test_and_set_bit(BC_FLG_ORIG, &bcs->Flag);
-			else
-				test_and_clear_bit(BC_FLG_ORIG, &bcs->Flag);
-			switch(st->l1.mode) {
-				case L1_MODE_TRANS:
-				case L1_MODE_HDLC:
-					ret = modeisar(bcs, st->l1.mode, st->l1.bc);
-					spin_unlock_irqrestore(&bcs->cs->lock, flags);
-					if (ret)
-						l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg);
-					else
-						l1_msg_b(st, PH_ACTIVATE | REQUEST, arg);
-					break;
-				case L1_MODE_V32:
-				case L1_MODE_FAX:
-					ret = modeisar(bcs, st->l1.mode, st->l1.bc);
-					spin_unlock_irqrestore(&bcs->cs->lock, flags);
-					if (ret)
-						l1_msg_b(st, PH_DEACTIVATE | REQUEST, arg);
-					break;
-				default:
-					spin_unlock_irqrestore(&bcs->cs->lock, flags);
-					break;
-			}
+		default:
+			spin_unlock_irqrestore(&bcs->cs->lock, flags);
 			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
+		}
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		switch (st->l1.mode) {
+		case L1_MODE_TRANS:
+		case L1_MODE_HDLC:
+		case L1_MODE_V32:
 			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			switch(st->l1.mode) {
-				case L1_MODE_TRANS:
-				case L1_MODE_HDLC:
-				case L1_MODE_V32:
-					break;
-				case L1_MODE_FAX:
-					isar_pump_cmd(bcs, ISDN_FAXPUMP_HALT, 0);
-					break;
-			}
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			if (bcs->cs->debug & L1_DEB_HSCX)
-				debugl1(bcs->cs, "PDAC clear BC_FLG_BUSY");
-			modeisar(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		case L1_MODE_FAX:
+			isar_pump_cmd(bcs, ISDN_FAXPUMP_HALT, 0);
 			break;
+		}
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		if (bcs->cs->debug & L1_DEB_HSCX)
+			debugl1(bcs->cs, "PDAC clear BC_FLG_BUSY");
+		modeisar(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -1751,149 +1751,149 @@ isar_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "isar_auxcmd cmd/ch %x/%ld", ic->command, ic->arg);
 	switch (ic->command) {
-		case (ISDN_CMD_FAXCMD):
-			bcs = cs->channel[ic->arg].bcs;
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "isar_auxcmd cmd/subcmd %d/%d",
-					ic->parm.aux.cmd, ic->parm.aux.subcmd);
-			switch(ic->parm.aux.cmd) {
-				case ISDN_FAX_CLASS1_CTRL:
-					if (ic->parm.aux.subcmd == ETX)
-						test_and_set_bit(BC_FLG_DLEETX,
-							&bcs->Flag);
-					break;
-				case ISDN_FAX_CLASS1_FTS:
-					if (ic->parm.aux.subcmd == AT_QUERY) {
+	case (ISDN_CMD_FAXCMD):
+		bcs = cs->channel[ic->arg].bcs;
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "isar_auxcmd cmd/subcmd %d/%d",
+				ic->parm.aux.cmd, ic->parm.aux.subcmd);
+		switch (ic->parm.aux.cmd) {
+		case ISDN_FAX_CLASS1_CTRL:
+			if (ic->parm.aux.subcmd == ETX)
+				test_and_set_bit(BC_FLG_DLEETX,
+						 &bcs->Flag);
+			break;
+		case ISDN_FAX_CLASS1_FTS:
+			if (ic->parm.aux.subcmd == AT_QUERY) {
+				ic->command = ISDN_STAT_FAXIND;
+				ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
+				cs->iif.statcallb(ic);
+				return (0);
+			} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
+				strcpy(ic->parm.aux.para, "0-255");
+				ic->command = ISDN_STAT_FAXIND;
+				ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
+				cs->iif.statcallb(ic);
+				return (0);
+			} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
+				if (cs->debug & L1_DEB_HSCX)
+					debugl1(cs, "isar_auxcmd %s=%d",
+						FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
+				if (bcs->hw.isar.state == STFAX_READY) {
+					if (!ic->parm.aux.para[0]) {
 						ic->command = ISDN_STAT_FAXIND;
 						ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
 						cs->iif.statcallb(ic);
-						return(0);
-					} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
-						strcpy(ic->parm.aux.para, "0-255");
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
-						cs->iif.statcallb(ic);
-						return(0);
-					} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
-						if (cs->debug & L1_DEB_HSCX)
-							debugl1(cs, "isar_auxcmd %s=%d",
-								FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
-						if (bcs->hw.isar.state == STFAX_READY) {
-							if (! ic->parm.aux.para[0]) {
-								ic->command = ISDN_STAT_FAXIND;
-								ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
-								cs->iif.statcallb(ic);
-								return(0);
-							}
-							if (! test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) {
-								/* n*10 ms */
-								bcs->hw.isar.ftimer.expires =
-									jiffies + ((ic->parm.aux.para[0] * 10 * HZ)/1000);
-								test_and_set_bit(BC_FLG_FTI_FTS, &bcs->Flag);
-								add_timer(&bcs->hw.isar.ftimer);
-								return(0);
-							} else {
-								if (cs->debug)
-									debugl1(cs, "isar FTS=%d and FTI busy",
-										ic->parm.aux.para[0]);
-							}
-						} else {
-							if (cs->debug)
-								debugl1(cs, "isar FTS=%d and isar.state not ready(%x)",
-									ic->parm.aux.para[0],bcs->hw.isar.state);
-						}
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR;
-						cs->iif.statcallb(ic);
+						return (0);
 					}
-					break;
-				case ISDN_FAX_CLASS1_FRM:
-				case ISDN_FAX_CLASS1_FRH:
-				case ISDN_FAX_CLASS1_FTM:
-				case ISDN_FAX_CLASS1_FTH:
-					if (ic->parm.aux.subcmd == AT_QUERY) {
-						sprintf(ic->parm.aux.para,
-							"%d", bcs->hw.isar.mod);
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
-						cs->iif.statcallb(ic);
-						return(0);
-					} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
-						char *p = ic->parm.aux.para;
-						for(i=0;i<FAXMODCNT;i++)
-							if ((1<<i) & modmask)
-								p += sprintf(p, "%d,", faxmodulation[i]);
-						p--;
-						*p=0;
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
-						cs->iif.statcallb(ic);
-						return(0);
-					} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
-						if (cs->debug & L1_DEB_HSCX)
-							debugl1(cs, "isar_auxcmd %s=%d",
-								FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
-						for(i=0;i<FAXMODCNT;i++)
-							if (faxmodulation[i]==ic->parm.aux.para[0])
-								break;
-						if ((i < FAXMODCNT) && ((1<<i) & modmask) && 
-							test_bit(BC_FLG_INIT, &bcs->Flag)) {
-							isar_pump_cmd(bcs,
-								ic->parm.aux.cmd,
+					if (!test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) {
+						/* n*10 ms */
+						bcs->hw.isar.ftimer.expires =
+							jiffies + ((ic->parm.aux.para[0] * 10 * HZ) / 1000);
+						test_and_set_bit(BC_FLG_FTI_FTS, &bcs->Flag);
+						add_timer(&bcs->hw.isar.ftimer);
+						return (0);
+					} else {
+						if (cs->debug)
+							debugl1(cs, "isar FTS=%d and FTI busy",
 								ic->parm.aux.para[0]);
-							return(0);
-						}
 					}
-					/* wrong modulation or not activ */
-					/* fall through */
-				default:
-					ic->command = ISDN_STAT_FAXIND;
-					ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR;
-					cs->iif.statcallb(ic);
+				} else {
+					if (cs->debug)
+						debugl1(cs, "isar FTS=%d and isar.state not ready(%x)",
+							ic->parm.aux.para[0], bcs->hw.isar.state);
+				}
+				ic->command = ISDN_STAT_FAXIND;
+				ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR;
+				cs->iif.statcallb(ic);
 			}
 			break;
-		case (ISDN_CMD_IOCTL):
-			switch (ic->arg) {
-				case 9: /* load firmware */
-					features = ISDN_FEATURE_L2_MODEM |
-						ISDN_FEATURE_L2_FAX |
-						ISDN_FEATURE_L3_FCLASS1;
-					memcpy(&adr, ic->parm.num, sizeof(ulong));
-					if (isar_load_firmware(cs, (u_char __user *)adr))
-						return(1);
-					else 
-						ll_run(cs, features);
-					break;
-				case 20:
-					features = *(unsigned int *) ic->parm.num;
-					printk(KERN_DEBUG "HiSax: max modulation old(%04x) new(%04x)\n",
-						modmask, features);
-					modmask = features;
-					break;
-				case 21:
-					features = *(unsigned int *) ic->parm.num;
-					printk(KERN_DEBUG "HiSax: FRM extra delay old(%d) new(%d) ms\n",
-						frm_extra_delay, features);
-					if (features >= 0)
-						frm_extra_delay = features;
-					break;
-				case 22:
-					features = *(unsigned int *) ic->parm.num;
-					printk(KERN_DEBUG "HiSax: TOA old(%d) new(%d) db\n",
-						para_TOA, features);
-					if (features >= 0 && features < 32)
-						para_TOA = features;
-					break;
-				default:
-					printk(KERN_DEBUG "HiSax: invalid ioctl %d\n",
-					       (int) ic->arg);
-					return(-EINVAL);
+		case ISDN_FAX_CLASS1_FRM:
+		case ISDN_FAX_CLASS1_FRH:
+		case ISDN_FAX_CLASS1_FTM:
+		case ISDN_FAX_CLASS1_FTH:
+			if (ic->parm.aux.subcmd == AT_QUERY) {
+				sprintf(ic->parm.aux.para,
+					"%d", bcs->hw.isar.mod);
+				ic->command = ISDN_STAT_FAXIND;
+				ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
+				cs->iif.statcallb(ic);
+				return (0);
+			} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
+				char *p = ic->parm.aux.para;
+				for (i = 0; i < FAXMODCNT; i++)
+					if ((1 << i) & modmask)
+						p += sprintf(p, "%d,", faxmodulation[i]);
+				p--;
+				*p = 0;
+				ic->command = ISDN_STAT_FAXIND;
+				ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
+				cs->iif.statcallb(ic);
+				return (0);
+			} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
+				if (cs->debug & L1_DEB_HSCX)
+					debugl1(cs, "isar_auxcmd %s=%d",
+						FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
+				for (i = 0; i < FAXMODCNT; i++)
+					if (faxmodulation[i] == ic->parm.aux.para[0])
+						break;
+				if ((i < FAXMODCNT) && ((1 << i) & modmask) &&
+				    test_bit(BC_FLG_INIT, &bcs->Flag)) {
+					isar_pump_cmd(bcs,
+						      ic->parm.aux.cmd,
+						      ic->parm.aux.para[0]);
+					return (0);
+				}
 			}
+			/* wrong modulation or not activ */
+			/* fall through */
+		default:
+			ic->command = ISDN_STAT_FAXIND;
+			ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR;
+			cs->iif.statcallb(ic);
+		}
+		break;
+	case (ISDN_CMD_IOCTL):
+		switch (ic->arg) {
+		case 9: /* load firmware */
+			features = ISDN_FEATURE_L2_MODEM |
+				ISDN_FEATURE_L2_FAX |
+				ISDN_FEATURE_L3_FCLASS1;
+			memcpy(&adr, ic->parm.num, sizeof(ulong));
+			if (isar_load_firmware(cs, (u_char __user *)adr))
+				return (1);
+			else
+				ll_run(cs, features);
+			break;
+		case 20:
+			features = *(unsigned int *) ic->parm.num;
+			printk(KERN_DEBUG "HiSax: max modulation old(%04x) new(%04x)\n",
+			       modmask, features);
+			modmask = features;
+			break;
+		case 21:
+			features = *(unsigned int *) ic->parm.num;
+			printk(KERN_DEBUG "HiSax: FRM extra delay old(%d) new(%d) ms\n",
+			       frm_extra_delay, features);
+			if (features >= 0)
+				frm_extra_delay = features;
+			break;
+		case 22:
+			features = *(unsigned int *) ic->parm.num;
+			printk(KERN_DEBUG "HiSax: TOA old(%d) new(%d) db\n",
+			       para_TOA, features);
+			if (features >= 0 && features < 32)
+				para_TOA = features;
 			break;
 		default:
-			return(-EINVAL);
+			printk(KERN_DEBUG "HiSax: invalid ioctl %d\n",
+			       (int) ic->arg);
+			return (-EINVAL);
+		}
+		break;
+	default:
+		return (-EINVAL);
 	}
-	return(0);
+	return (0);
 }
 
 void initisar(struct IsdnCardState *cs)
diff --git a/drivers/isdn/hisax/isar.h b/drivers/isdn/hisax/isar.h
index bf76765..0f4d101 100644
--- a/drivers/isdn/hisax/isar.h
+++ b/drivers/isdn/hisax/isar.h
@@ -4,12 +4,12 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
- 
+
 #define ISAR_IRQMSK	0x04
 #define ISAR_IRQSTA	0x04
 #define ISAR_IRQBIT	0x75
@@ -21,7 +21,7 @@
 #define ISAR_HIA	0x50
 #define ISAR_MBOX	0x4c
 #define ISAR_WADR	0x4a
-#define ISAR_RADR	0x48 
+#define ISAR_RADR	0x48
 
 #define ISAR_HIS_VNR		0x14
 #define ISAR_HIS_DKEY		0x02
@@ -32,9 +32,9 @@
 #define ISAR_HIS_TIMERIRQ	0x25
 #define ISAR_HIS_P0CFG		0x3c
 #define ISAR_HIS_P12CFG		0x24
-#define ISAR_HIS_SARTCFG	0x25	
-#define ISAR_HIS_PUMPCFG	0x26	
-#define ISAR_HIS_PUMPCTRL	0x2a	
+#define ISAR_HIS_SARTCFG	0x25
+#define ISAR_HIS_PUMPCFG	0x26
+#define ISAR_HIS_PUMPCTRL	0x2a
 #define ISAR_HIS_IOM2CFG	0x27
 #define ISAR_HIS_IOM2REQ	0x07
 #define ISAR_HIS_IOM2CTRL	0x2b
@@ -43,7 +43,7 @@
 #define ISAR_HIS_SDATA		0x20
 #define ISAR_HIS_DPS1		0x40
 #define ISAR_HIS_DPS2		0x80
-#define SET_DPS(x)		((x<<6) & 0xc0)
+#define SET_DPS(x)		((x << 6) & 0xc0)
 
 #define ISAR_CMD_TIMERIRQ_OFF	0x20
 #define ISAR_CMD_TIMERIRQ_ON	0x21
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index d5eeacf..8000957 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -5,7 +5,7 @@
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -40,7 +40,7 @@ enum {
 	ST_L1_F8,
 };
 
-#define L1S_STATE_COUNT (ST_L1_F8+1)
+#define L1S_STATE_COUNT (ST_L1_F8 + 1)
 
 static char *strL1SState[] =
 {
@@ -65,7 +65,7 @@ enum {
 	ST_L1_TRANS,
 };
 
-#define L1U_STATE_COUNT (ST_L1_TRANS+1)
+#define L1U_STATE_COUNT (ST_L1_TRANS + 1)
 
 static char *strL1UState[] =
 {
@@ -83,7 +83,7 @@ enum {
 	ST_L1_ACTIV,
 };
 
-#define L1B_STATE_COUNT (ST_L1_ACTIV+1)
+#define L1B_STATE_COUNT (ST_L1_ACTIV + 1)
 
 static char *strL1BState[] =
 {
@@ -100,7 +100,7 @@ enum {
 	EV_DEACT_CNF,
 	EV_DEACT_IND,
 	EV_POWER_UP,
-	EV_RSYNC_IND, 
+	EV_RSYNC_IND,
 	EV_INFO2_IND,
 	EV_INFO4_IND,
 	EV_TIMER_DEACT,
@@ -118,7 +118,7 @@ static char *strL1Event[] =
 	"EV_DEACT_CNF",
 	"EV_DEACT_IND",
 	"EV_POWER_UP",
-	"EV_RSYNC_IND", 
+	"EV_RSYNC_IND",
 	"EV_INFO2_IND",
 	"EV_INFO4_IND",
 	"EV_TIMER_DEACT",
@@ -131,7 +131,7 @@ debugl1(struct IsdnCardState *cs, char *fmt, ...)
 {
 	va_list args;
 	char tmp[8];
-	
+
 	va_start(args, fmt);
 	sprintf(tmp, "Card%d ", cs->cardnr + 1);
 	VHiSax_putstatus(cs, tmp, fmt, args);
@@ -145,7 +145,7 @@ l1m_debug(struct FsmInst *fi, char *fmt, ...)
 	struct PStack *st = fi->userdata;
 	struct IsdnCardState *cs = st->l1.hardware;
 	char tmp[8];
-	
+
 	va_start(args, fmt);
 	sprintf(tmp, "Card%d ", cs->cardnr + 1);
 	VHiSax_putstatus(cs, tmp, fmt, args);
@@ -209,19 +209,19 @@ DChannel_proc_rcv(struct IsdnCardState *cs)
 
 	if (stptr)
 		if (test_bit(FLG_L1_ACTTIMER, &stptr->l1.Flags))
-			FsmEvent(&stptr->l1.l1m, EV_TIMER_ACT, NULL);	
+			FsmEvent(&stptr->l1.l1m, EV_TIMER_ACT, NULL);
 	while ((skb = skb_dequeue(&cs->rq))) {
 #ifdef L2FRAME_DEBUG		/* psa */
 		if (cs->debug & L1_DEB_LAPD)
 			Logl2Frame(cs, skb, "PH_DATA", 1);
 #endif
 		stptr = cs->stlist;
-		if (skb->len<3) {
-			debugl1(cs, "D-channel frame too short(%d)",skb->len);
+		if (skb->len < 3) {
+			debugl1(cs, "D-channel frame too short(%d)", skb->len);
 			dev_kfree_skb(skb);
 			return;
 		}
-		if ((skb->data[0] & 1) || !(skb->data[1] &1)) {
+		if ((skb->data[0] & 1) || !(skb->data[1] & 1)) {
 			debugl1(cs, "D-channel frame wrong EA0/EA1");
 			dev_kfree_skb(skb);
 			return;
@@ -378,60 +378,60 @@ static char *
 l2cmd(u_char cmd)
 {
 	switch (cmd & ~0x10) {
-		case 1:
-			return "RR";
-		case 5:
-			return "RNR";
-		case 9:
-			return "REJ";
-		case 0x6f:
-			return "SABME";
-		case 0x0f:
-			return "DM";
-		case 3:
-			return "UI";
-		case 0x43:
-			return "DISC";
-		case 0x63:
-			return "UA";
-		case 0x87:
-			return "FRMR";
-		case 0xaf:
-			return "XID";
-		default:
-			if (!(cmd & 1))
-				return "I";
-			else
-				return "invalid command";
+	case 1:
+		return "RR";
+	case 5:
+		return "RNR";
+	case 9:
+		return "REJ";
+	case 0x6f:
+		return "SABME";
+	case 0x0f:
+		return "DM";
+	case 3:
+		return "UI";
+	case 0x43:
+		return "DISC";
+	case 0x63:
+		return "UA";
+	case 0x87:
+		return "FRMR";
+	case 0xaf:
+		return "XID";
+	default:
+		if (!(cmd & 1))
+			return "I";
+		else
+			return "invalid command";
 	}
 }
 
 static char tmpdeb[32];
 
 static char *
-l2frames(u_char * ptr)
+l2frames(u_char *ptr)
 {
 	switch (ptr[2] & ~0x10) {
-		case 1:
-		case 5:
-		case 9:
-			sprintf(tmpdeb, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1);
-			break;
-		case 0x6f:
-		case 0x0f:
-		case 3:
-		case 0x43:
-		case 0x63:
-		case 0x87:
-		case 0xaf:
-			sprintf(tmpdeb, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4);
+	case 1:
+	case 5:
+	case 9:
+		sprintf(tmpdeb, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1);
+		break;
+	case 0x6f:
+	case 0x0f:
+	case 3:
+	case 0x43:
+	case 0x63:
+	case 0x87:
+	case 0xaf:
+		sprintf(tmpdeb, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4);
+		break;
+	default:
+		if (!(ptr[2] & 1)) {
+			sprintf(tmpdeb, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1);
 			break;
-		default:
-			if (!(ptr[2] & 1)) {
-				sprintf(tmpdeb, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1);
-				break;
-			} else
-				return "invalid command";
+		} else
+			return "invalid command";
 	}
 
 
@@ -547,24 +547,24 @@ l1_timer3(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
-	test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags);	
+	test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags);
 	if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
 		L1deactivated(st->l1.hardware);
 
 #ifdef HISAX_UINTERFACE
 	if (!test_bit(FLG_L1_UINT, &st->l1.Flags))
 #endif
-	if (st->l1.l1m.state != ST_L1_F6) {
-		FsmChangeState(fi, ST_L1_F3);
-		st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
-	}
+		if (st->l1.l1m.state != ST_L1_F6) {
+			FsmChangeState(fi, ST_L1_F3);
+			st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
+		}
 }
 
 static void
 l1_timer_act(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
-	
+
 	test_and_clear_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
 	test_and_set_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
 	L1activated(st->l1.hardware);
@@ -574,7 +574,7 @@ static void
 l1_timer_deact(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
-	
+
 	test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
 	test_and_clear_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
 	L1deactivated(st->l1.hardware);
@@ -585,7 +585,7 @@ static void
 l1_activate_s(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
-                
+
 	st->l1.l1hw(st, HW_RESET | REQUEST, NULL);
 }
 
@@ -679,7 +679,7 @@ static void
 l1_activate_u(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
-                
+
 	st->l1.l1hw(st, HW_INFO1 | REQUEST, NULL);
 }
 
@@ -751,7 +751,7 @@ static struct FsmNode L1BFnList[] __initdata =
 	{ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact},
 };
 
-int __init 
+int __init
 Isdnl1New(void)
 {
 	int retval;
@@ -803,35 +803,35 @@ dch_l2l1(struct PStack *st, int pr, void *arg)
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-		case (PH_PULL | REQUEST):
-		case (PH_PULL |INDICATION):
-			st->l1.l1hw(st, pr, arg);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			if (cs->debug)
-				debugl1(cs, "PH_ACTIVATE_REQ %s",
-					st->l1.l1m.fsm->strState[st->l1.l1m.state]);
-			if (test_bit(FLG_L1_ACTIVATED, &st->l1.Flags))
-				st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
-			else {
-				test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
-				FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg);
-			}
-			break;
-		case (PH_TESTLOOP | REQUEST):
-			if (1 & (long) arg)
-				debugl1(cs, "PH_TEST_LOOP B1");
-			if (2 & (long) arg)
-				debugl1(cs, "PH_TEST_LOOP B2");
-			if (!(3 & (long) arg))
-				debugl1(cs, "PH_TEST_LOOP DISABLED");
-			st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
-			break;
-		default:
-			if (cs->debug)
-				debugl1(cs, "dch_l2l1 msg %04X unhandled", pr);
-			break;
+	case (PH_DATA | REQUEST):
+	case (PH_PULL | REQUEST):
+	case (PH_PULL | INDICATION):
+		st->l1.l1hw(st, pr, arg);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		if (cs->debug)
+			debugl1(cs, "PH_ACTIVATE_REQ %s",
+				st->l1.l1m.fsm->strState[st->l1.l1m.state]);
+		if (test_bit(FLG_L1_ACTIVATED, &st->l1.Flags))
+			st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+		else {
+			test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
+			FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg);
+		}
+		break;
+	case (PH_TESTLOOP | REQUEST):
+		if (1 & (long) arg)
+			debugl1(cs, "PH_TEST_LOOP B1");
+		if (2 & (long) arg)
+			debugl1(cs, "PH_TEST_LOOP B2");
+		if (!(3 & (long) arg))
+			debugl1(cs, "PH_TEST_LOOP DISABLED");
+		st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
+		break;
+	default:
+		if (cs->debug)
+			debugl1(cs, "dch_l2l1 msg %04X unhandled", pr);
+		break;
 	}
 }
 
@@ -840,35 +840,35 @@ l1_msg(struct IsdnCardState *cs, int pr, void *arg) {
 	struct PStack *st;
 
 	st = cs->stlist;
-	
+
 	while (st) {
-		switch(pr) {
-			case (HW_RESET | INDICATION):
-				FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
-				break;
-			case (HW_DEACTIVATE | CONFIRM):
-				FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
-				break;
-			case (HW_DEACTIVATE | INDICATION):
-				FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
-				break;
-			case (HW_POWERUP | CONFIRM):
-				FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
-				break;
-			case (HW_RSYNC | INDICATION):
-				FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
-				break;
-			case (HW_INFO2 | INDICATION):
-				FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
-				break;
-			case (HW_INFO4_P8 | INDICATION):
-			case (HW_INFO4_P10 | INDICATION):
-				FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
-				break;
-			default:
-				if (cs->debug)
-					debugl1(cs, "l1msg %04X unhandled", pr);
-				break;
+		switch (pr) {
+		case (HW_RESET | INDICATION):
+			FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
+			break;
+		case (HW_DEACTIVATE | CONFIRM):
+			FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
+			break;
+		case (HW_DEACTIVATE | INDICATION):
+			FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
+			break;
+		case (HW_POWERUP | CONFIRM):
+			FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
+			break;
+		case (HW_RSYNC | INDICATION):
+			FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
+			break;
+		case (HW_INFO2 | INDICATION):
+			FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
+			break;
+		case (HW_INFO4_P8 | INDICATION):
+		case (HW_INFO4_P10 | INDICATION):
+			FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
+			break;
+		default:
+			if (cs->debug)
+				debugl1(cs, "l1msg %04X unhandled", pr);
+			break;
 		}
 		st = st->next;
 	}
@@ -876,13 +876,13 @@ l1_msg(struct IsdnCardState *cs, int pr, void *arg) {
 
 void
 l1_msg_b(struct PStack *st, int pr, void *arg) {
-	switch(pr) {
-		case (PH_ACTIVATE | REQUEST):
-			FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, NULL);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			FsmEvent(&st->l1.l1m, EV_PH_DEACTIVATE, NULL);
-			break;
+	switch (pr) {
+	case (PH_ACTIVATE | REQUEST):
+		FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, NULL);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		FsmEvent(&st->l1.l1m, EV_PH_DEACTIVATE, NULL);
+		break;
 	}
 }
 
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index cfff0c4..18accb0 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -3,7 +3,7 @@
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -37,7 +37,7 @@ enum {
 	ST_L2_8,
 };
 
-#define L2_STATE_COUNT (ST_L2_8+1)
+#define L2_STATE_COUNT (ST_L2_8 + 1)
 
 static char *strL2State[] =
 {
@@ -76,7 +76,7 @@ enum {
 	EV_L2_FRAME_ERROR,
 };
 
-#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR+1)
+#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1)
 
 static char *strL2Event[] =
 {
@@ -155,7 +155,7 @@ ReleaseWin(struct Layer2 *l2)
 {
 	int cnt;
 
-	if((cnt = freewin1(l2)))
+	if ((cnt = freewin1(l2)))
 		printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt);
 }
 
@@ -164,7 +164,7 @@ cansend(struct PStack *st)
 {
 	unsigned int p1;
 
-	if(test_bit(FLG_MOD128, &st->l2.flag))
+	if (test_bit(FLG_MOD128, &st->l2.flag))
 		p1 = (st->l2.vs - st->l2.va) % 128;
 	else
 		p1 = (st->l2.vs - st->l2.va) % 8;
@@ -194,7 +194,7 @@ l2addrsize(struct Layer2 *l2)
 }
 
 static int
-sethdraddr(struct Layer2 *l2, u_char * header, int rsp)
+sethdraddr(struct Layer2 *l2, u_char *header, int rsp)
 {
 	u_char *ptr = header;
 	int crbit = rsp;
@@ -226,41 +226,41 @@ enqueue_super(struct PStack *st,
 #define enqueue_ui(a, b) enqueue_super(a, b)
 
 static inline int
-IsUI(u_char * data)
+IsUI(u_char *data)
 {
 	return ((data[0] & 0xef) == UI);
 }
 
 static inline int
-IsUA(u_char * data)
+IsUA(u_char *data)
 {
 	return ((data[0] & 0xef) == UA);
 }
 
 static inline int
-IsDM(u_char * data)
+IsDM(u_char *data)
 {
 	return ((data[0] & 0xef) == DM);
 }
 
 static inline int
-IsDISC(u_char * data)
+IsDISC(u_char *data)
 {
 	return ((data[0] & 0xef) == DISC);
 }
 
 static inline int
-IsSFrame(u_char * data, struct PStack *st)
+IsSFrame(u_char *data, struct PStack *st)
 {
 	register u_char d = *data;
-	
+
 	if (!test_bit(FLG_MOD128, &st->l2.flag))
 		d &= 0xf;
-	return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
+	return (((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
 }
 
 static inline int
-IsSABME(u_char * data, struct PStack *st)
+IsSABME(u_char *data, struct PStack *st)
 {
 	u_char d = data[0] & ~0x10;
 
@@ -268,19 +268,19 @@ IsSABME(u_char * data, struct PStack *st)
 }
 
 static inline int
-IsREJ(u_char * data, struct PStack *st)
+IsREJ(u_char *data, struct PStack *st)
 {
 	return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ);
 }
 
 static inline int
-IsFRMR(u_char * data)
+IsFRMR(u_char *data)
 {
 	return ((data[0] & 0xef) == FRMR);
 }
 
 static inline int
-IsRNR(u_char * data, struct PStack *st)
+IsRNR(u_char *data, struct PStack *st)
 {
 	return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR);
 }
@@ -368,14 +368,14 @@ FRMR_error(struct PStack *st, struct sk_buff *skb)
 			return 'N';
 		else
 			l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x",
-				datap[0], datap[1], datap[2],
-				datap[3], datap[4]);
+				  datap[0], datap[1], datap[2],
+				  datap[3], datap[4]);
 	} else {
 		if (skb->len < headers + 3)
 			return 'N';
 		else
 			l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x",
-				datap[0], datap[1], datap[2]);
+				  datap[0], datap[1], datap[2]);
 	}
 
 	return 0;
@@ -384,9 +384,9 @@ FRMR_error(struct PStack *st, struct sk_buff *skb)
 static unsigned int
 legalnr(struct PStack *st, unsigned int nr)
 {
-        struct Layer2 *l2 = &st->l2;
+	struct Layer2 *l2 = &st->l2;
 
-	if(test_bit(FLG_MOD128, &l2->flag))
+	if (test_bit(FLG_MOD128, &l2->flag))
 		return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128);
 	else
 		return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8);
@@ -402,7 +402,7 @@ setva(struct PStack *st, unsigned int nr)
 	spin_lock_irqsave(&l2->lock, flags);
 	while (l2->va != nr) {
 		(l2->va)++;
-		if(test_bit(FLG_MOD128, &l2->flag))
+		if (test_bit(FLG_MOD128, &l2->flag))
 			l2->va %= 128;
 		else
 			l2->va %= 8;
@@ -413,7 +413,7 @@ setva(struct PStack *st, unsigned int nr)
 		l2->windowar[l2->sow] = NULL;
 		l2->sow = (l2->sow + 1) % l2->window;
 		spin_unlock_irqrestore(&l2->lock, flags);
-		if (test_bit(FLG_LLI_L2WAKEUP, &st->lli.flag) && (len >=0))
+		if (test_bit(FLG_LLI_L2WAKEUP, &st->lli.flag) && (len >= 0))
 			lli_writewakeup(st, len);
 		spin_lock_irqsave(&l2->lock, flags);
 	}
@@ -438,7 +438,7 @@ send_uframe(struct PStack *st, u_char cmd, u_char cr)
 }
 
 static inline u_char
-get_PollFlag(struct PStack * st, struct sk_buff * skb)
+get_PollFlag(struct PStack *st, struct sk_buff *skb)
 {
 	return (skb->data[l2addrsize(&(st->l2))] & 0x10);
 }
@@ -470,29 +470,29 @@ restart_t200(struct PStack *st, int i)
 static inline void
 stop_t200(struct PStack *st, int i)
 {
-	if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
+	if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
 		FsmDelTimer(&st->l2.t200, i);
 }
 
 static inline void
 st5_dl_release_l2l3(struct PStack *st)
 {
-		int pr;
+	int pr;
 
-		if(test_and_clear_bit(FLG_PEND_REL, &st->l2.flag))
-			pr = DL_RELEASE | CONFIRM;
-		else
-			pr = DL_RELEASE | INDICATION;
+	if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag))
+		pr = DL_RELEASE | CONFIRM;
+	else
+		pr = DL_RELEASE | INDICATION;
 
-		st->l2.l2l3(st, pr, NULL);
+	st->l2.l2l3(st, pr, NULL);
 }
 
 static inline void
 lapb_dl_release_l2l3(struct PStack *st, int f)
 {
-		if (test_bit(FLG_LAPB, &st->l2.flag))
-			st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
-		st->l2.l2l3(st, DL_RELEASE | f, NULL);
+	if (test_bit(FLG_LAPB, &st->l2.flag))
+		st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
+	st->l2.l2l3(st, DL_RELEASE | f, NULL);
 }
 
 static void
@@ -557,7 +557,7 @@ l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
 static void
 l2_go_st3(struct FsmInst *fi, int event, void *arg)
 {
-	FsmChangeState(fi, ST_L2_3); 
+	FsmChangeState(fi, ST_L2_3);
 }
 
 static void
@@ -565,7 +565,7 @@ l2_mdl_assign(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
-	FsmChangeState(fi, ST_L2_3); 
+	FsmChangeState(fi, ST_L2_3);
 	st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL);
 }
 
@@ -755,7 +755,7 @@ l2_restart_multi(struct FsmInst *fi, int event, void *arg)
 	if (est)
 		st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL);
 
-	if ((ST_L2_7==state) || (ST_L2_8 == state))
+	if ((ST_L2_7 == state) || (ST_L2_8 == state))
 		if (!skb_queue_empty(&st->l2.i_queue) && cansend(st))
 			st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 }
@@ -782,7 +782,7 @@ l2_connected(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 	struct sk_buff *skb = arg;
-	int pr=-1;
+	int pr = -1;
 
 	if (!get_PollFlag(st, skb)) {
 		l2_mdl_error_ua(fi, event, arg);
@@ -853,7 +853,7 @@ l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
 
 	if (get_PollFlagFree(st, skb)) {
 		stop_t200(st, 7);
-	 	if (!test_bit(FLG_L3_INIT, &st->l2.flag))
+		if (!test_bit(FLG_L3_INIT, &st->l2.flag))
 			skb_queue_purge(&st->l2.i_queue);
 		if (test_bit(FLG_LAPB, &st->l2.flag))
 			st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
@@ -941,7 +941,7 @@ invoke_retransmission(struct PStack *st, unsigned int nr)
 	if (l2->vs != nr) {
 		while (l2->vs != nr) {
 			(l2->vs)--;
-			if(test_bit(FLG_MOD128, &l2->flag)) {
+			if (test_bit(FLG_MOD128, &l2->flag)) {
 				l2->vs %= 128;
 				p1 = (l2->vs - l2->va) % 128;
 			} else {
@@ -1013,7 +1013,7 @@ l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
 					EV_L2_T203, NULL, 7);
 		} else if ((l2->va != nr) || (typ == RNR)) {
 			setva(st, nr);
-			if(typ != RR) FsmDelTimer(&st->l2.t203, 9);
+			if (typ != RR) FsmDelTimer(&st->l2.t203, 9);
 			restart_t200(st, 12);
 		}
 		if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR))
@@ -1080,10 +1080,10 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
 	}
 	if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
 		dev_kfree_skb(skb);
-		if(PollFlag) enquiry_response(st);
+		if (PollFlag) enquiry_response(st);
 	} else if (l2->vr == ns) {
 		(l2->vr)++;
-		if(test_bit(FLG_MOD128, &l2->flag))
+		if (test_bit(FLG_MOD128, &l2->flag))
 			l2->vr %= 128;
 		else
 			l2->vr %= 8;
@@ -1150,7 +1150,7 @@ l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct PStack *st = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &st->l2.flag) &&
-		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
 		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9);
 	} else if (st->l2.rc == st->l2.N200) {
 		FsmChangeState(fi, ST_L2_4);
@@ -1174,7 +1174,7 @@ l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct PStack *st = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &st->l2.flag) &&
-		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
 		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9);
 	} else if (st->l2.rc == st->l2.N200) {
 		FsmChangeState(fi, ST_L2_4);
@@ -1195,7 +1195,7 @@ l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct PStack *st = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &st->l2.flag) &&
-		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
 		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9);
 		return;
 	}
@@ -1213,7 +1213,7 @@ l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct PStack *st = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &st->l2.flag) &&
-		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
 		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9);
 		return;
 	}
@@ -1234,7 +1234,7 @@ l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
 	struct PStack *st = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &st->l2.flag) &&
-		test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) {
 		FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 9);
 		return;
 	}
@@ -1272,7 +1272,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
 		}
 	}
 	spin_lock_irqsave(&l2->lock, flags);
-	if(test_bit(FLG_MOD128, &l2->flag))
+	if (test_bit(FLG_MOD128, &l2->flag))
 		p1 = (l2->vs - l2->va) % 128;
 	else
 		p1 = (l2->vs - l2->va) % 8;
@@ -1445,7 +1445,7 @@ static void
 l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
-	
+
 	skb_queue_purge(&st->l2.i_queue);
 	skb_queue_purge(&st->l2.ui_queue);
 	if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))
@@ -1495,7 +1495,7 @@ l2_set_own_busy(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
-	if(!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) {
+	if (!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) {
 		enquiry_cr(st, RNR, RSP, 0);
 		test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
 	}
@@ -1506,7 +1506,7 @@ l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
 
-	if(!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) {
+	if (!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) {
 		enquiry_cr(st, RR, RSP, 0);
 		test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
 	}
@@ -1631,76 +1631,76 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
 	int c = 0;
 
 	switch (pr) {
-		case (PH_DATA | INDICATION):
-			datap = skb->data;
-			len = l2addrsize(&st->l2);
-			if (skb->len > len)
-				datap += len;
-			else {
-				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N');
-				dev_kfree_skb(skb);
-				return;
-			}
-			if (!(*datap & 1)) {	/* I-Frame */
-				if(!(c = iframe_error(st, skb)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb);
-			} else if (IsSFrame(datap, st)) {	/* S-Frame */
-				if(!(c = super_error(st, skb)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb);
-			} else if (IsUI(datap)) {
-				if(!(c = UI_error(st, skb)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb);
-			} else if (IsSABME(datap, st)) {
-				if(!(c = unnum_error(st, skb, CMD)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb);
-			} else if (IsUA(datap)) {
-				if(!(c = unnum_error(st, skb, RSP)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb);
-			} else if (IsDISC(datap)) {
-				if(!(c = unnum_error(st, skb, CMD)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb);
-			} else if (IsDM(datap)) {
-				if(!(c = unnum_error(st, skb, RSP)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb);
-			} else if (IsFRMR(datap)) {
-				if(!(c = FRMR_error(st,skb)))
-					ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);
-			} else {
-				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L');
-				dev_kfree_skb(skb);
-				ret = 0;
-			}
-			if(c) {
-				dev_kfree_skb(skb);
-				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
-				ret = 0;
-			}
-			if (ret)
-				dev_kfree_skb(skb);
-			break;
-		case (PH_PULL | CONFIRM):
-			FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
-			break;
-		case (PH_PAUSE | INDICATION):
-			test_and_set_bit(FLG_DCHAN_BUSY, &st->l2.flag);
-			break;
-		case (PH_PAUSE | CONFIRM):
-			test_and_clear_bit(FLG_DCHAN_BUSY, &st->l2.flag);
-			break;
-		case (PH_ACTIVATE | CONFIRM):
-		case (PH_ACTIVATE | INDICATION):
-			test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag);
-			if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))
-				FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg);
-			break;
-		case (PH_DEACTIVATE | INDICATION):
-		case (PH_DEACTIVATE | CONFIRM):
-			test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag);
-			FsmEvent(&st->l2.l2m, EV_L1_DEACTIVATE, arg);
-			break;
-		default:
-			l2m_debug(&st->l2.l2m, "l2 unknown pr %04x", pr);
-			break;
+	case (PH_DATA | INDICATION):
+		datap = skb->data;
+		len = l2addrsize(&st->l2);
+		if (skb->len > len)
+			datap += len;
+		else {
+			FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N');
+			dev_kfree_skb(skb);
+			return;
+		}
+		if (!(*datap & 1)) {	/* I-Frame */
+			if (!(c = iframe_error(st, skb)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb);
+		} else if (IsSFrame(datap, st)) {	/* S-Frame */
+			if (!(c = super_error(st, skb)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb);
+		} else if (IsUI(datap)) {
+			if (!(c = UI_error(st, skb)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb);
+		} else if (IsSABME(datap, st)) {
+			if (!(c = unnum_error(st, skb, CMD)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb);
+		} else if (IsUA(datap)) {
+			if (!(c = unnum_error(st, skb, RSP)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb);
+		} else if (IsDISC(datap)) {
+			if (!(c = unnum_error(st, skb, CMD)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb);
+		} else if (IsDM(datap)) {
+			if (!(c = unnum_error(st, skb, RSP)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb);
+		} else if (IsFRMR(datap)) {
+			if (!(c = FRMR_error(st, skb)))
+				ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);
+		} else {
+			FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L');
+			dev_kfree_skb(skb);
+			ret = 0;
+		}
+		if (c) {
+			dev_kfree_skb(skb);
+			FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
+			ret = 0;
+		}
+		if (ret)
+			dev_kfree_skb(skb);
+		break;
+	case (PH_PULL | CONFIRM):
+		FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
+		break;
+	case (PH_PAUSE | INDICATION):
+		test_and_set_bit(FLG_DCHAN_BUSY, &st->l2.flag);
+		break;
+	case (PH_PAUSE | CONFIRM):
+		test_and_clear_bit(FLG_DCHAN_BUSY, &st->l2.flag);
+		break;
+	case (PH_ACTIVATE | CONFIRM):
+	case (PH_ACTIVATE | INDICATION):
+		test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag);
+		if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag))
+			FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg);
+		break;
+	case (PH_DEACTIVATE | INDICATION):
+	case (PH_DEACTIVATE | CONFIRM):
+		test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag);
+		FsmEvent(&st->l2.l2m, EV_L1_DEACTIVATE, arg);
+		break;
+	default:
+		l2m_debug(&st->l2.l2m, "l2 unknown pr %04x", pr);
+		break;
 	}
 }
 
@@ -1708,45 +1708,45 @@ static void
 isdnl2_l3l2(struct PStack *st, int pr, void *arg)
 {
 	switch (pr) {
-		case (DL_DATA | REQUEST):
-			if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) {
-				dev_kfree_skb((struct sk_buff *) arg);
-			}
-			break;
-		case (DL_UNIT_DATA | REQUEST):
-			if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) {
-				dev_kfree_skb((struct sk_buff *) arg);
-			}
-			break;
-		case (DL_ESTABLISH | REQUEST):
-			if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) {
-				if (test_bit(FLG_LAPD, &st->l2.flag) ||
-					test_bit(FLG_ORIG, &st->l2.flag)) {
-					FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg);
-				}
-			} else {
-				if (test_bit(FLG_LAPD, &st->l2.flag) ||
-					test_bit(FLG_ORIG, &st->l2.flag)) {
-					test_and_set_bit(FLG_ESTAB_PEND, &st->l2.flag);
-				}
-				st->l2.l2l1(st, PH_ACTIVATE, NULL);
+	case (DL_DATA | REQUEST):
+		if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) {
+			dev_kfree_skb((struct sk_buff *) arg);
+		}
+		break;
+	case (DL_UNIT_DATA | REQUEST):
+		if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) {
+			dev_kfree_skb((struct sk_buff *) arg);
+		}
+		break;
+	case (DL_ESTABLISH | REQUEST):
+		if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) {
+			if (test_bit(FLG_LAPD, &st->l2.flag) ||
+			    test_bit(FLG_ORIG, &st->l2.flag)) {
+				FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg);
 			}
-			break;
-		case (DL_RELEASE | REQUEST):
-			if (test_bit(FLG_LAPB, &st->l2.flag)) {
-				st->l2.l2l1(st, PH_DEACTIVATE, NULL);
+		} else {
+			if (test_bit(FLG_LAPD, &st->l2.flag) ||
+			    test_bit(FLG_ORIG, &st->l2.flag)) {
+				test_and_set_bit(FLG_ESTAB_PEND, &st->l2.flag);
 			}
-			FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE_REQ, arg);
-			break;
-		case (MDL_ASSIGN | REQUEST):
-			FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg);
-			break;
-		case (MDL_REMOVE | REQUEST):
-			FsmEvent(&st->l2.l2m, EV_L2_MDL_REMOVE, arg);
-			break;
-		case (MDL_ERROR | RESPONSE):
-			FsmEvent(&st->l2.l2m, EV_L2_MDL_ERROR, arg);
-			break;
+			st->l2.l2l1(st, PH_ACTIVATE, NULL);
+		}
+		break;
+	case (DL_RELEASE | REQUEST):
+		if (test_bit(FLG_LAPB, &st->l2.flag)) {
+			st->l2.l2l1(st, PH_DEACTIVATE, NULL);
+		}
+		FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE_REQ, arg);
+		break;
+	case (MDL_ASSIGN | REQUEST):
+		FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg);
+		break;
+	case (MDL_REMOVE | REQUEST):
+		FsmEvent(&st->l2.l2m, EV_L2_MDL_REMOVE, arg);
+		break;
+	case (MDL_ERROR | RESPONSE):
+		FsmEvent(&st->l2.l2m, EV_L2_MDL_ERROR, arg);
+		break;
 	}
 }
 
@@ -1787,7 +1787,7 @@ setstack_isdnl2(struct PStack *st, char *debug_id)
 	if (test_bit(FLG_LAPB, &st->l2.flag))
 		st->l2.l2m.state = ST_L2_4;
 	else
-	st->l2.l2m.state = ST_L2_1;
+		st->l2.l2m.state = ST_L2_1;
 	st->l2.l2m.debug = 0;
 	st->l2.l2m.userdata = st;
 	st->l2.l2m.userint = 0;
@@ -1802,16 +1802,16 @@ static void
 transl2_l3l2(struct PStack *st, int pr, void *arg)
 {
 	switch (pr) {
-		case (DL_DATA | REQUEST):
-		case (DL_UNIT_DATA | REQUEST):
-			st->l2.l2l1(st, PH_DATA | REQUEST, arg);
-			break;
-		case (DL_ESTABLISH | REQUEST):
-			st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);
-			break;
-		case (DL_RELEASE | REQUEST):
-			st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
-			break;
+	case (DL_DATA | REQUEST):
+	case (DL_UNIT_DATA | REQUEST):
+		st->l2.l2l1(st, PH_DATA | REQUEST, arg);
+		break;
+	case (DL_ESTABLISH | REQUEST):
+		st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);
+		break;
+	case (DL_RELEASE | REQUEST):
+		st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
+		break;
 	}
 }
 
diff --git a/drivers/isdn/hisax/isdnl2.h b/drivers/isdn/hisax/isdnl2.h
index 0cdab1b..7e447fb 100644
--- a/drivers/isdn/hisax/isdnl2.h
+++ b/drivers/isdn/hisax/isdnl2.h
@@ -23,4 +23,3 @@
 #define RSP    1
 
 #define LC_FLUSH_WAIT 1
-
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index 1c24e44..45b0384 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -3,7 +3,7 @@
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -27,12 +27,12 @@ static struct Fsm l3fsm;
 enum {
 	ST_L3_LC_REL,
 	ST_L3_LC_ESTAB_WAIT,
-	ST_L3_LC_REL_DELAY, 
+	ST_L3_LC_REL_DELAY,
 	ST_L3_LC_REL_WAIT,
 	ST_L3_LC_ESTAB,
 };
 
-#define L3_STATE_COUNT (ST_L3_LC_ESTAB+1)
+#define L3_STATE_COUNT (ST_L3_LC_ESTAB + 1)
 
 static char *strL3State[] =
 {
@@ -53,7 +53,7 @@ enum {
 	EV_TIMEOUT,
 };
 
-#define L3_EVENT_COUNT (EV_TIMEOUT+1)
+#define L3_EVENT_COUNT (EV_TIMEOUT + 1)
 
 static char *strL3Event[] =
 {
@@ -67,7 +67,7 @@ static char *strL3Event[] =
 };
 
 static __printf(2, 3) void
-l3m_debug(struct FsmInst *fi, char *fmt, ...)
+	l3m_debug(struct FsmInst *fi, char *fmt, ...)
 {
 	va_list args;
 	struct PStack *st = fi->userdata;
@@ -78,7 +78,7 @@ l3m_debug(struct FsmInst *fi, char *fmt, ...)
 }
 
 u_char *
-findie(u_char * p, int size, u_char ie, int wanted_set)
+findie(u_char *p, int size, u_char ie, int wanted_set)
 {
 	int l, codeset, maincodeset;
 	u_char *pend = p + size;
@@ -102,14 +102,14 @@ findie(u_char * p, int size, u_char ie, int wanted_set)
 		else {
 			if (codeset == wanted_set) {
 				if (*p == ie)
-                                  { /* improved length check (Werner Cornelius) */
-                                    if ((pend - p) < 2) 
-                                      return(NULL); 
-                                    if (*(p+1) > (pend - (p+2))) 
-                                      return(NULL); 
-                                    return (p);
-                                  }           
-                                  
+				{ /* improved length check (Werner Cornelius) */
+					if ((pend - p) < 2)
+						return (NULL);
+					if (*(p + 1) > (pend - (p + 2)))
+						return (NULL);
+					return (p);
+				}
+
 				if (*p > ie)
 					return (NULL);
 			}
@@ -123,16 +123,16 @@ findie(u_char * p, int size, u_char ie, int wanted_set)
 }
 
 int
-getcallref(u_char * p)
+getcallref(u_char *p)
 {
 	int l, cr = 0;
 
 	p++;			/* prot discr */
 	if (*p & 0xfe)		/* wrong callref BRI only 1 octet*/
-		return(-2);
+		return (-2);
 	l = 0xf & *p++;		/* callref length */
 	if (!l)			/* dummy CallRef */
-		return(-1);
+		return (-1);
 	cr = *p++;
 	return (cr);
 }
@@ -153,7 +153,7 @@ void
 newl3state(struct l3_process *pc, int state)
 {
 	if (pc->debug & L3_DEB_STATE)
-		l3_debug(pc->st, "newstate cr %d %d --> %d", 
+		l3_debug(pc->st, "newstate cr %d %d --> %d",
 			 pc->callref & 0x7F,
 			 pc->state, state);
 	pc->state = state;
@@ -228,8 +228,8 @@ no_l3_proto(struct PStack *st, int pr, void *arg)
 static int
 no_l3_proto_spec(struct PStack *st, isdn_ctrl *ic)
 {
-	printk(KERN_WARNING "HiSax: no specific protocol handler for proto %lu\n",ic->arg & 0xFF);
-	return(-1);
+	printk(KERN_WARNING "HiSax: no specific protocol handler for proto %lu\n", ic->arg & 0xFF);
+	return (-1);
 }
 
 struct l3_process
@@ -287,7 +287,7 @@ release_l3_process(struct l3_process *p)
 			if (pp)
 				pp->next = np->next;
 			else if (!(p->st->l3.proc = np->next) &&
-				!test_bit(FLG_PTP, &p->st->l2.flag)) {
+				 !test_bit(FLG_PTP, &p->st->l2.flag)) {
 				if (p->debug)
 					l3_debug(p->st, "release_l3_process: last process");
 				if (skb_queue_empty(&p->st->l3.squeue)) {
@@ -301,7 +301,7 @@ release_l3_process(struct l3_process *p)
 					if (p->debug)
 						l3_debug(p->st, "release_l3_process: not release link");
 				}
-			} 
+			}
 			kfree(p);
 			return;
 		}
@@ -340,42 +340,42 @@ setstack_l3dc(struct PStack *st, struct Channel *chanp)
 	st->l3.l3m.userdata = st;
 	st->l3.l3m.userint = 0;
 	st->l3.l3m.printdebug = l3m_debug;
-        FsmInitTimer(&st->l3.l3m, &st->l3.l3m_timer);
+	FsmInitTimer(&st->l3.l3m, &st->l3.l3m_timer);
 	strcpy(st->l3.debug_id, "L3DC ");
 	st->lli.l4l3_proto = no_l3_proto_spec;
 
-#ifdef	CONFIG_HISAX_EURO
+#ifdef CONFIG_HISAX_EURO
 	if (st->protocol == ISDN_PTYPE_EURO) {
 		setstack_dss1(st);
 	} else
 #endif
-#ifdef  CONFIG_HISAX_NI1
-	if (st->protocol == ISDN_PTYPE_NI1) {
-		setstack_ni1(st);
-	} else
+#ifdef CONFIG_HISAX_NI1
+		if (st->protocol == ISDN_PTYPE_NI1) {
+			setstack_ni1(st);
+		} else
 #endif
-#ifdef	CONFIG_HISAX_1TR6
-	if (st->protocol == ISDN_PTYPE_1TR6) {
-		setstack_1tr6(st);
-	} else
+#ifdef CONFIG_HISAX_1TR6
+			if (st->protocol == ISDN_PTYPE_1TR6) {
+				setstack_1tr6(st);
+			} else
 #endif
-	if (st->protocol == ISDN_PTYPE_LEASED) {
-		st->lli.l4l3 = no_l3_proto;
-		st->l2.l2l3 = no_l3_proto;
-                st->l3.l3ml3 = no_l3_proto;
-		printk(KERN_INFO "HiSax: Leased line mode\n");
-	} else {
-		st->lli.l4l3 = no_l3_proto;
-		st->l2.l2l3 = no_l3_proto;
-                st->l3.l3ml3 = no_l3_proto;
-		sprintf(tmp, "protocol %s not supported",
-			(st->protocol == ISDN_PTYPE_1TR6) ? "1tr6" :
-			(st->protocol == ISDN_PTYPE_EURO) ? "euro" :
-			(st->protocol == ISDN_PTYPE_NI1) ? "ni1" :
-			"unknown");
-		printk(KERN_WARNING "HiSax: %s\n", tmp);
-		st->protocol = -1;
-	}
+				if (st->protocol == ISDN_PTYPE_LEASED) {
+					st->lli.l4l3 = no_l3_proto;
+					st->l2.l2l3 = no_l3_proto;
+					st->l3.l3ml3 = no_l3_proto;
+					printk(KERN_INFO "HiSax: Leased line mode\n");
+				} else {
+					st->lli.l4l3 = no_l3_proto;
+					st->l2.l2l3 = no_l3_proto;
+					st->l3.l3ml3 = no_l3_proto;
+					sprintf(tmp, "protocol %s not supported",
+						(st->protocol == ISDN_PTYPE_1TR6) ? "1tr6" :
+						(st->protocol == ISDN_PTYPE_EURO) ? "euro" :
+						(st->protocol == ISDN_PTYPE_NI1) ? "ni1" :
+						"unknown");
+					printk(KERN_WARNING "HiSax: %s\n", tmp);
+					st->protocol = -1;
+				}
 }
 
 static void
@@ -469,22 +469,22 @@ lc_connected(struct FsmInst *fi, int event, void *arg)
 static void
 lc_start_delay(struct FsmInst *fi, int event, void *arg)
 {
-       struct PStack *st = fi->userdata;
+	struct PStack *st = fi->userdata;
 
-       FsmChangeState(fi, ST_L3_LC_REL_DELAY);
-       FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
+	FsmChangeState(fi, ST_L3_LC_REL_DELAY);
+	FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
 }
 
 static void
 lc_start_delay_check(struct FsmInst *fi, int event, void *arg)
 /* 20/09/00 - GE timer not user for NI-1 as layer 2 should stay up */
 {
-       struct PStack *st = fi->userdata;
+	struct PStack *st = fi->userdata;
 
-       FsmChangeState(fi, ST_L3_LC_REL_DELAY);
-       /* 19/09/00 - GE timer not user for NI-1 */
-       if (st->protocol != ISDN_PTYPE_NI1) 
-       		FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
+	FsmChangeState(fi, ST_L3_LC_REL_DELAY);
+	/* 19/09/00 - GE timer not user for NI-1 */
+	if (st->protocol != ISDN_PTYPE_NI1)
+		FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
 }
 
 static void
@@ -536,9 +536,9 @@ static struct FsmNode L3FnList[] __initdata =
 	{ST_L3_LC_ESTAB_WAIT,	EV_RELEASE_IND,		lc_release_ind},
 	{ST_L3_LC_ESTAB,	EV_RELEASE_IND,		lc_release_ind},
 	{ST_L3_LC_ESTAB,	EV_RELEASE_REQ,		lc_start_delay_check},
-        {ST_L3_LC_REL_DELAY,    EV_RELEASE_IND,         lc_release_ind},
-        {ST_L3_LC_REL_DELAY,    EV_ESTABLISH_REQ,       lc_connected},
-        {ST_L3_LC_REL_DELAY,    EV_TIMEOUT,             lc_release_req},
+	{ST_L3_LC_REL_DELAY,    EV_RELEASE_IND,         lc_release_ind},
+	{ST_L3_LC_REL_DELAY,    EV_ESTABLISH_REQ,       lc_connected},
+	{ST_L3_LC_REL_DELAY,    EV_TIMEOUT,             lc_release_req},
 	{ST_L3_LC_REL_WAIT,	EV_RELEASE_CNF,		lc_release_cnf},
 	{ST_L3_LC_REL_WAIT,	EV_ESTABLISH_REQ,	lc_activate},
 };
@@ -548,34 +548,34 @@ void
 l3_msg(struct PStack *st, int pr, void *arg)
 {
 	switch (pr) {
-		case (DL_DATA | REQUEST):
-			if (st->l3.l3m.state == ST_L3_LC_ESTAB) {
-				st->l3.l3l2(st, pr, arg);
-			} else {
-				struct sk_buff *skb = arg;
-
-				skb_queue_tail(&st->l3.squeue, skb);
-				FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL); 
-			}
-			break;
-		case (DL_ESTABLISH | REQUEST):
+	case (DL_DATA | REQUEST):
+		if (st->l3.l3m.state == ST_L3_LC_ESTAB) {
+			st->l3.l3l2(st, pr, arg);
+		} else {
+			struct sk_buff *skb = arg;
+
+			skb_queue_tail(&st->l3.squeue, skb);
 			FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL);
-			break;
-		case (DL_ESTABLISH | CONFIRM):
-			FsmEvent(&st->l3.l3m, EV_ESTABLISH_CNF, NULL);
-			break;
-		case (DL_ESTABLISH | INDICATION):
-			FsmEvent(&st->l3.l3m, EV_ESTABLISH_IND, NULL);
-			break;
-		case (DL_RELEASE | INDICATION):
-			FsmEvent(&st->l3.l3m, EV_RELEASE_IND, NULL);
-			break;
-		case (DL_RELEASE | CONFIRM):
-			FsmEvent(&st->l3.l3m, EV_RELEASE_CNF, NULL);
-			break;
-		case (DL_RELEASE | REQUEST):
-			FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL);
-			break;
+		}
+		break;
+	case (DL_ESTABLISH | REQUEST):
+		FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL);
+		break;
+	case (DL_ESTABLISH | CONFIRM):
+		FsmEvent(&st->l3.l3m, EV_ESTABLISH_CNF, NULL);
+		break;
+	case (DL_ESTABLISH | INDICATION):
+		FsmEvent(&st->l3.l3m, EV_ESTABLISH_IND, NULL);
+		break;
+	case (DL_RELEASE | INDICATION):
+		FsmEvent(&st->l3.l3m, EV_RELEASE_IND, NULL);
+		break;
+	case (DL_RELEASE | CONFIRM):
+		FsmEvent(&st->l3.l3m, EV_RELEASE_CNF, NULL);
+		break;
+	case (DL_RELEASE | REQUEST):
+		FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL);
+		break;
 	}
 }
 
diff --git a/drivers/isdn/hisax/isdnl3.h b/drivers/isdn/hisax/isdnl3.h
index 749498f..0edc99d 100644
--- a/drivers/isdn/hisax/isdnl3.h
+++ b/drivers/isdn/hisax/isdnl3.h
@@ -5,7 +5,7 @@
  *
  */
 
-#define SBIT(state) (1<<state)
+#define SBIT(state) (1 << state)
 #define ALL_STATES  0x03ffffff
 
 #define PROTO_DIS_EURO	0x08
@@ -40,4 +40,3 @@ void l3_msg(struct PStack *st, int pr, void *arg);
 void setstack_dss1(struct PStack *st);
 void setstack_ni1(struct PStack *st);
 void setstack_1tr6(struct PStack *st);
-
diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c
index ca41617..ea27172 100644
--- a/drivers/isdn/hisax/isurf.c
+++ b/drivers/isdn/hisax/isurf.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -19,7 +19,7 @@
 
 static const char *ISurf_revision = "$Revision: 1.12.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define ISURF_ISAR_RESET	1
@@ -46,7 +46,7 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	register int i;
 	for (i = 0; i < size; i++)
@@ -54,11 +54,11 @@ ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	register int i;
-	for (i = 0; i < size; i++){
-		writeb(data[i], cs->hw.isurf.isac);mb();
+	for (i = 0; i < size; i++) {
+		writeb(data[i], cs->hw.isurf.isac); mb();
 	}
 }
 
@@ -67,17 +67,17 @@ WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
  * mode = 1 access with IRQ off
  * mode = 2 access with IRQ off and using last offset
  */
-  
+
 static u_char
 ReadISAR(struct IsdnCardState *cs, int mode, u_char offset)
-{	
-	return(readb(cs->hw.isurf.isar + offset));
+{
+	return (readb(cs->hw.isurf.isar + offset));
 }
 
 static void
 WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
 {
-	writeb(value, cs->hw.isurf.isar + offset);mb();
+	writeb(value, cs->hw.isurf.isar + offset); mb();
 }
 
 static irqreturn_t
@@ -90,11 +90,11 @@ isurf_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readb(cs->hw.isurf.isar + ISAR_IRQBIT);
-      Start_ISAR:
+Start_ISAR:
 	if (val & ISAR_IRQSTA)
 		isar_int_main(cs);
 	val = readb(cs->hw.isurf.isac + ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readb(cs->hw.isurf.isar + ISAR_IRQBIT);
@@ -113,8 +113,8 @@ isurf_interrupt(int intno, void *dev_id)
 		printk(KERN_WARNING "ISurf IRQ LOOP\n");
 
 	writeb(0, cs->hw.isurf.isar + ISAR_IRQBIT); mb();
-	writeb(0xFF, cs->hw.isurf.isac + ISAC_MASK);mb();
-	writeb(0, cs->hw.isurf.isac + ISAC_MASK);mb();
+	writeb(0xFF, cs->hw.isurf.isac + ISAC_MASK); mb();
+	writeb(0, cs->hw.isurf.isac + ISAC_MASK); mb();
 	writeb(ISAR_IRQMSK, cs->hw.isurf.isar + ISAR_IRQBIT); mb();
 	spin_unlock_irqrestore(&cs->lock, flags);
 	return IRQ_HANDLED;
@@ -145,31 +145,31 @@ ISurf_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_isurf(cs, ISURF_RESET);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_isurf(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_isurf(cs, ISURF_RESET);
-			clear_pending_isac_ints(cs);
-			writeb(0, cs->hw.isurf.isar+ISAR_IRQBIT);mb();
-			initisac(cs);
-			initisar(cs);
-			/* Reenable ISAC IRQ */
-			cs->writeisac(cs, ISAC_MASK, 0);
-			/* RESET Receiver and Transmitter */
-			cs->writeisac(cs, ISAC_CMDR, 0x41);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_isurf(cs, ISURF_RESET);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_isurf(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_isurf(cs, ISURF_RESET);
+		clear_pending_isac_ints(cs);
+		writeb(0, cs->hw.isurf.isar + ISAR_IRQBIT); mb();
+		initisac(cs);
+		initisar(cs);
+		/* Reenable ISAC IRQ */
+		cs->writeisac(cs, ISAC_MASK, 0);
+		/* RESET Receiver and Transmitter */
+		cs->writeisac(cs, ISAC_CMDR, 0x41);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 static int
@@ -182,15 +182,15 @@ isurf_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) {
 		spin_lock_irqsave(&cs->lock, flags);
 		if (!ret) {
 			reset_isurf(cs, ISURF_ISAR_EA | ISURF_ISAC_RESET |
-				ISURF_ARCOFI_RESET);
+				    ISURF_ARCOFI_RESET);
 			initisac(cs);
 			cs->writeisac(cs, ISAC_MASK, 0);
 			cs->writeisac(cs, ISAC_CMDR, 0x41);
 		}
 		spin_unlock_irqrestore(&cs->lock, flags);
-		return(ret);
+		return (ret);
 	}
-	return(isar_auxcmd(cs, ic));
+	return (isar_auxcmd(cs, ic));
 }
 
 #ifdef __ISAPNP__
@@ -206,9 +206,9 @@ setup_isurf(struct IsdnCard *card)
 
 	strcpy(tmp, ISurf_revision);
 	printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp));
-	
- 	if (cs->typ != ISDN_CTYPE_ISURF)
- 		return(0);
+
+	if (cs->typ != ISDN_CTYPE_ISURF)
+		return (0);
 	if (card->para[1] && card->para[2]) {
 		cs->hw.isurf.reset = card->para[1];
 		cs->hw.isurf.phymem = card->para[2];
@@ -221,11 +221,11 @@ setup_isurf(struct IsdnCard *card)
 
 			cs->subtyp = 0;
 			if ((pnp_c = pnp_find_card(
-				ISAPNP_VENDOR('S', 'I', 'E'),
-				ISAPNP_FUNCTION(0x0010), pnp_c))) {
+				     ISAPNP_VENDOR('S', 'I', 'E'),
+				     ISAPNP_FUNCTION(0x0010), pnp_c))) {
 				if (!(pnp_d = pnp_find_dev(pnp_c,
-					ISAPNP_VENDOR('S', 'I', 'E'),
-					ISAPNP_FUNCTION(0x0010), pnp_d))) {
+							   ISAPNP_VENDOR('S', 'I', 'E'),
+							   ISAPNP_FUNCTION(0x0010), pnp_d))) {
 					printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n");
 					return (0);
 				}
@@ -236,17 +236,17 @@ setup_isurf(struct IsdnCard *card)
 				cs->irq = pnp_irq(pnp_d, 0);
 				if (!cs->irq || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) {
 					printk(KERN_ERR "ISurfPnP:some resources are missing %d/%x/%lx\n",
-						cs->irq, cs->hw.isurf.reset, cs->hw.isurf.phymem);
+					       cs->irq, cs->hw.isurf.reset, cs->hw.isurf.phymem);
 					pnp_disable_dev(pnp_d);
-					return(0);
+					return (0);
 				}
 			} else {
 				printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n");
-				return(0);
+				return (0);
 			}
 		} else {
 			printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n");
-			return(0);
+			return (0);
 		}
 #else
 		printk(KERN_WARNING "HiSax: Siemens I-Surf port/mem not set\n");
@@ -255,15 +255,15 @@ setup_isurf(struct IsdnCard *card)
 	}
 	if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) {
 		printk(KERN_WARNING
-			"HiSax: Siemens I-Surf config port %x already in use\n",
-			cs->hw.isurf.reset);
-			return (0);
+		       "HiSax: Siemens I-Surf config port %x already in use\n",
+		       cs->hw.isurf.reset);
+		return (0);
 	}
 	if (!request_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE, "isurf iomem")) {
 		printk(KERN_WARNING "HiSax: Siemens I-Surf memory region "
-			"%lx-%lx already in use\n",
-			cs->hw.isurf.phymem,
-			cs->hw.isurf.phymem + ISURF_IOMEM_SIZE);
+		       "%lx-%lx already in use\n",
+		       cs->hw.isurf.phymem,
+		       cs->hw.isurf.phymem + ISURF_IOMEM_SIZE);
 		release_region(cs->hw.isurf.reset, 1);
 		return (0);
 	}
@@ -293,7 +293,7 @@ setup_isurf(struct IsdnCard *card)
 	ver = ISARVersion(cs, "ISurf:");
 	if (ver < 0) {
 		printk(KERN_WARNING
-			"ISurf: wrong ISAR version (ret = %d)\n", ver);
+		       "ISurf: wrong ISAR version (ret = %d)\n", ver);
 		release_io_isurf(cs);
 		return (0);
 	}
diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c
index a92bf0d..5f299f8 100644
--- a/drivers/isdn/hisax/ix1_micro.c
+++ b/drivers/isdn/hisax/ix1_micro.c
@@ -7,7 +7,7 @@
  * Copyright    by Klaus-Peter Nischke, ITK AG
  *                                   <klaus@nischke.do.eunet.de>
  *              by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -26,7 +26,7 @@
 
 static const char *ix1_revision = "$Revision: 2.12.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define SPECIAL_PORT_OFFSET 3
@@ -49,7 +49,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -64,7 +64,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -85,13 +85,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, 0, data, size);
 }
@@ -110,16 +110,16 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 		 cs->hw.ix1.hscx, offset + (hscx ? 0x40 : 0), value);
 }
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.ix1.hscx_ale, \
-		cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ix1.hscx_ale, \
-		cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.ix1.hscx_ale,		\
+				      cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.ix1.hscx_ale,	\
+					      cs->hw.ix1.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ix1.hscx_ale, \
-		cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.ix1.hscx_ale,	\
+						cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ix1.hscx_ale, \
-		cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.ix1.hscx_ale,	\
+						  cs->hw.ix1.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -132,11 +132,11 @@ ix1micro_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.ix1.isac_ale, cs->hw.ix1.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.ix1.hscx_ale, cs->hw.ix1.hscx, HSCX_ISTA + 0x40);
@@ -188,33 +188,33 @@ ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			ix1_reset(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_ix1micro(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			ix1_reset(cs);
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		ix1_reset(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_ix1micro(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		ix1_reset(cs);
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 #ifdef __ISAPNP__
 static struct isapnp_device_id itk_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
-	  ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), 
+	  ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
 	  (unsigned long) "ITK micro 2" },
 	{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
-	  ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29), 
+	  ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
 	  (unsigned long) "ITK micro 2." },
 	{ 0, }
 };
@@ -238,30 +238,30 @@ setup_ix1micro(struct IsdnCard *card)
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d;
-		while(ipid->card_vendor) {
+		while (ipid->card_vendor) {
 			if ((pnp_c = pnp_find_card(ipid->card_vendor,
-				ipid->card_device, pnp_c))) {
+						   ipid->card_device, pnp_c))) {
 				pnp_d = NULL;
 				if ((pnp_d = pnp_find_dev(pnp_c,
-					ipid->vendor, ipid->function, pnp_d))) {
+							  ipid->vendor, ipid->function, pnp_d))) {
 					int err;
 
 					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)ipid->driver_data);
+					       (char *)ipid->driver_data);
 					pnp_disable_dev(pnp_d);
 					err = pnp_activate_dev(pnp_d);
-					if (err<0) {
+					if (err < 0) {
 						printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-							__func__, err);
-						return(0);
+						       __func__, err);
+						return (0);
 					}
 					card->para[1] = pnp_port_start(pnp_d, 0);
 					card->para[0] = pnp_irq(pnp_d, 0);
 					if (!card->para[0] || !card->para[1]) {
 						printk(KERN_ERR "ITK PnP:some resources are missing %ld/%lx\n",
-							card->para[0], card->para[1]);
+						       card->para[0], card->para[1]);
 						pnp_disable_dev(pnp_d);
-						return(0);
+						return (0);
 					}
 					break;
 				} else {
@@ -270,10 +270,10 @@ setup_ix1micro(struct IsdnCard *card)
 			}
 			ipid++;
 			pnp_c = NULL;
-		} 
+		}
 		if (!ipid->card_vendor) {
 			printk(KERN_INFO "ITK PnP: no ISAPnP card found\n");
-			return(0);
+			return (0);
 		}
 	}
 #endif
@@ -287,15 +287,15 @@ setup_ix1micro(struct IsdnCard *card)
 	if (cs->hw.ix1.cfg_reg) {
 		if (!request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg")) {
 			printk(KERN_WARNING
-			  "HiSax: ITK ix1-micro Rev.2 config port "
-			  "%x-%x already in use\n",
+			       "HiSax: ITK ix1-micro Rev.2 config port "
+			       "%x-%x already in use\n",
 			       cs->hw.ix1.cfg_reg,
 			       cs->hw.ix1.cfg_reg + 4);
 			return (0);
 		}
 	}
 	printk(KERN_INFO "HiSax: ITK ix1-micro Rev.2 config irq:%d io:0x%X\n",
-		cs->irq, cs->hw.ix1.cfg_reg);
+	       cs->irq, cs->hw.ix1.cfg_reg);
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
 	cs->writeisac = &WriteISAC;
@@ -309,7 +309,7 @@ setup_ix1micro(struct IsdnCard *card)
 	ISACVersion(cs, "ix1-Micro:");
 	if (HscxVersion(cs, "ix1-Micro:")) {
 		printk(KERN_WARNING
-		    "ix1-Micro: wrong HSCX versions check IO address\n");
+		       "ix1-Micro: wrong HSCX versions check IO address\n");
 		release_io_ix1micro(cs);
 		return (0);
 	}
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index a06cea0..f946c58 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -4,7 +4,7 @@
  *
  * Author       Roland Klabunde
  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -23,53 +23,53 @@
 int
 JadeVersion(struct IsdnCardState *cs, char *s)
 {
-    int ver;
-    int to = 50;
-    cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
-    while (to) {
-    	udelay(1);
+	int ver;
+	int to = 50;
+	cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
+	while (to) {
+		udelay(1);
+		ver = cs->BC_Read_Reg(cs, -1, 0x60);
+		to--;
+		if (ver)
+			break;
+		if (!to) {
+			printk(KERN_INFO "%s JADE version not obtainable\n", s);
+			return (0);
+		}
+	}
+	/* Wait for the JADE */
+	udelay(10);
+	/* Read version */
 	ver = cs->BC_Read_Reg(cs, -1, 0x60);
-	to--;
-	if (ver)
-    	    break;
-	if (!to) {
-	    printk(KERN_INFO "%s JADE version not obtainable\n", s);
-    	    return (0);
-        }
-    }
-    /* Wait for the JADE */
-    udelay(10);
-    /* Read version */
-    ver = cs->BC_Read_Reg(cs, -1, 0x60);
-    printk(KERN_INFO "%s JADE version: %d\n", s, ver);
-    return (1);
+	printk(KERN_INFO "%s JADE version: %d\n", s, ver);
+	return (1);
 }
 
 /* Write to indirect accessible jade register set */
 static void
 jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
 {
-    int to = 50;
-    u_char ret;
+	int to = 50;
+	u_char ret;
 
-    /* Write the data */
-    cs->BC_Write_Reg(cs, -1, COMM_JADE+1, value);
-    /* Say JADE we wanna write indirect reg 'reg' */
-    cs->BC_Write_Reg(cs, -1, COMM_JADE, reg);
-    to = 50;
-    /* Wait for RDY goes high */
-    while (to) {
-    	udelay(1);
-	ret = cs->BC_Read_Reg(cs, -1, COMM_JADE);
-	to--;
-	if (ret & 1)
-	    /* Got acknowledge */
-	    break;
-	if (!to) {
-    	    printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value);
-	    return;
+	/* Write the data */
+	cs->BC_Write_Reg(cs, -1, COMM_JADE + 1, value);
+	/* Say JADE we wanna write indirect reg 'reg' */
+	cs->BC_Write_Reg(cs, -1, COMM_JADE, reg);
+	to = 50;
+	/* Wait for RDY goes high */
+	while (to) {
+		udelay(1);
+		ret = cs->BC_Read_Reg(cs, -1, COMM_JADE);
+		to--;
+		if (ret & 1)
+			/* Got acknowledge */
+			break;
+		if (!to) {
+			printk(KERN_INFO "Can not see ready bit from JADE DSP (reg=0x%X, value=0x%X)\n", reg, value);
+			return;
+		}
 	}
-    }
 }
 
 
@@ -77,67 +77,67 @@ jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
 static void
 modejade(struct BCState *bcs, int mode, int bc)
 {
-    struct IsdnCardState *cs = bcs->cs;
-    int jade = bcs->hw.hscx.hscx;
+	struct IsdnCardState *cs = bcs->cs;
+	int jade = bcs->hw.hscx.hscx;
 
-    if (cs->debug & L1_DEB_HSCX) {
-	char tmp[40];
-	sprintf(tmp, "jade %c mode %d ichan %d",
-		'A' + jade, mode, bc);
-	debugl1(cs, tmp);
-    }
-    bcs->mode = mode;
-    bcs->channel = bc;
-	
-    cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO:0x00));
-    cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU|jadeCCR0_ITF));
-    cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
+	if (cs->debug & L1_DEB_HSCX) {
+		char tmp[40];
+		sprintf(tmp, "jade %c mode %d ichan %d",
+			'A' + jade, mode, bc);
+		debugl1(cs, tmp);
+	}
+	bcs->mode = mode;
+	bcs->channel = bc;
 
-    jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
-    jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
-    jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
-    jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
+	cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (mode == L1_MODE_TRANS ? jadeMODE_TMO : 0x00));
+	cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR0, (jadeCCR0_PU | jadeCCR0_ITF));
+	cs->BC_Write_Reg(cs, jade, jade_HDLC_CCR1, 0x00);
 
-    cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
-    cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
+	jade_write_indirect(cs, jade_HDLC1SERRXPATH, 0x08);
+	jade_write_indirect(cs, jade_HDLC2SERRXPATH, 0x08);
+	jade_write_indirect(cs, jade_HDLC1SERTXPATH, 0x00);
+	jade_write_indirect(cs, jade_HDLC2SERTXPATH, 0x00);
 
-    if (bc == 0) {
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
-    } else {
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
-    }
-    switch (mode) {
+	cs->BC_Write_Reg(cs, jade, jade_HDLC_XCCR, 0x07);
+	cs->BC_Write_Reg(cs, jade, jade_HDLC_RCCR, 0x07);
+
+	if (bc == 0) {
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x00);
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x00);
+	} else {
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAX, 0x04);
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_TSAR, 0x04);
+	}
+	switch (mode) {
 	case (L1_MODE_NULL):
 		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, jadeMODE_TMO);
 		break;
 	case (L1_MODE_TRANS):
-		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO|jadeMODE_RAC|jadeMODE_XAC));
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_TMO | jadeMODE_RAC | jadeMODE_XAC));
 		break;
 	case (L1_MODE_HDLC):
-		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC|jadeMODE_XAC));
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_MODE, (jadeMODE_RAC | jadeMODE_XAC));
 		break;
-    }
-    if (mode) {
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES|jadeRCMD_RMC));
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
-	/* Unmask ints */
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
-    }
-    else
-	/* Mask ints */
-	cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
+	}
+	if (mode) {
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_RCMD, (jadeRCMD_RRES | jadeRCMD_RMC));
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_XCMD, jadeXCMD_XRES);
+		/* Unmask ints */
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0xF8);
+	}
+	else
+		/* Mask ints */
+		cs->BC_Write_Reg(cs, jade, jade_HDLC_IMR, 0x00);
 }
 
 static void
 jade_l2l1(struct PStack *st, int pr, void *arg)
 {
-    struct BCState *bcs = st->l1.bcs;
-    struct sk_buff *skb = arg;
-    u_long flags;
+	struct BCState *bcs = st->l1.bcs;
+	struct sk_buff *skb = arg;
+	u_long flags;
 
-    switch (pr) {
+	switch (pr) {
 	case (PH_DATA | REQUEST):
 		spin_lock_irqsave(&bcs->cs->lock, flags);
 		if (bcs->tx_skb) {
@@ -164,10 +164,10 @@ jade_l2l1(struct PStack *st, int pr, void *arg)
 		break;
 	case (PH_PULL | REQUEST):
 		if (!bcs->tx_skb) {
-		    test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-		    st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
 		} else
-		    test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
 		break;
 	case (PH_ACTIVATE | REQUEST):
 		spin_lock_irqsave(&bcs->cs->lock, flags);
@@ -187,26 +187,26 @@ jade_l2l1(struct PStack *st, int pr, void *arg)
 		spin_unlock_irqrestore(&bcs->cs->lock, flags);
 		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
 		break;
-    }
+	}
 }
 
 static void
 close_jadestate(struct BCState *bcs)
 {
-    modejade(bcs, 0, bcs->channel);
-    if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-	kfree(bcs->hw.hscx.rcvbuf);
-	bcs->hw.hscx.rcvbuf = NULL;
-	kfree(bcs->blog);
-	bcs->blog = NULL;
-	skb_queue_purge(&bcs->rqueue);
-	skb_queue_purge(&bcs->squeue);
-	if (bcs->tx_skb) {
-		dev_kfree_skb_any(bcs->tx_skb);
-		bcs->tx_skb = NULL;
-		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+	modejade(bcs, 0, bcs->channel);
+	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
+		kfree(bcs->hw.hscx.rcvbuf);
+		bcs->hw.hscx.rcvbuf = NULL;
+		kfree(bcs->blog);
+		bcs->blog = NULL;
+		skb_queue_purge(&bcs->rqueue);
+		skb_queue_purge(&bcs->squeue);
+		if (bcs->tx_skb) {
+			dev_kfree_skb_any(bcs->tx_skb);
+			bcs->tx_skb = NULL;
+			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		}
 	}
-    }
 }
 
 static int
@@ -221,7 +221,7 @@ open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
 		}
 		if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
 			printk(KERN_WARNING
-				"HiSax: No memory for bcs->blog\n");
+			       "HiSax: No memory for bcs->blog\n");
 			test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
 			kfree(bcs->hw.hscx.rcvbuf);
 			bcs->hw.hscx.rcvbuf = NULL;
@@ -303,12 +303,11 @@ initjade(struct IsdnCardState *cs)
 	cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR,  0x00);
 	cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR,  0x00);
 	/* Setup host access to hdlc controller */
-	jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
+	jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1 | jadeINDIRECT_HAH2));
 	/* Unmask HDLC int (don't forget DSP int later on)*/
-	cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
+	cs->BC_Write_Reg(cs, -1, jade_INT, (jadeINT_HDLC1 | jadeINT_HDLC2));
 
-	/* once again TRANSPARENT */	
+	/* once again TRANSPARENT */
 	modejade(cs->bcs, 0, 0);
 	modejade(cs->bcs + 1, 0, 0);
 }
-
diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h
index 29055e1..4b98096 100644
--- a/drivers/isdn/hisax/jade.h
+++ b/drivers/isdn/hisax/jade.h
@@ -4,7 +4,7 @@
  *
  * Author       Roland Klabunde
  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -16,111 +16,111 @@
 
 /* Special registers for access to indirect accessible JADE regs */
 #define	DIRECT_IO_JADE	0x0000	/* Jade direct io access area */
-#define	COMM_JADE	0x0040	/* Jade communication area */	   	
+#define	COMM_JADE	0x0040	/* Jade communication area */
 
 /********************************************************************/
-/* JADE-HDLC registers         									    */
+/* JADE-HDLC registers										    */
 /********************************************************************/
-#define jade_HDLC_RFIFO	   				0x00				   /* R */
-#define jade_HDLC_XFIFO	   				0x00				   /* W */
-
-#define	jade_HDLC_STAR	   				0x20				   /* R */
-	#define	jadeSTAR_XDOV				0x80
-	#define	jadeSTAR_XFW 				0x40 /* Does not work*/
-	#define	jadeSTAR_XCEC 				0x20
-	#define	jadeSTAR_RCEC				0x10
-	#define	jadeSTAR_BSY 				0x08
-	#define	jadeSTAR_RNA 				0x04
-	#define	jadeSTAR_STR 				0x02
-	#define	jadeSTAR_STX				0x01
-
-#define	jade_HDLC_XCMD	   				0x20				   /* W */
-	#define	jadeXCMD_XF				0x80
-	#define	jadeXCMD_XME				0x40
-	#define	jadeXCMD_XRES				0x20
-	#define	jadeXCMD_STX				0x01
-
-#define	jade_HDLC_RSTA	   				0x21				   /* R */
-    #define	jadeRSTA_VFR				0x80
-    #define	jadeRSTA_RDO				0x40
-    #define	jadeRSTA_CRC				0x20
-    #define	jadeRSTA_RAB				0x10
-    #define	jadeRSTA_MASK			   	0xF0
+#define jade_HDLC_RFIFO					0x00				   /* R */
+#define jade_HDLC_XFIFO					0x00				   /* W */
+
+#define	jade_HDLC_STAR					0x20				   /* R */
+#define	jadeSTAR_XDOV				0x80
+#define	jadeSTAR_XFW				0x40 /* Does not work*/
+#define	jadeSTAR_XCEC				0x20
+#define	jadeSTAR_RCEC				0x10
+#define	jadeSTAR_BSY				0x08
+#define	jadeSTAR_RNA				0x04
+#define	jadeSTAR_STR				0x02
+#define	jadeSTAR_STX				0x01
+
+#define	jade_HDLC_XCMD					0x20				   /* W */
+#define	jadeXCMD_XF				0x80
+#define	jadeXCMD_XME				0x40
+#define	jadeXCMD_XRES				0x20
+#define	jadeXCMD_STX				0x01
+
+#define	jade_HDLC_RSTA					0x21				   /* R */
+#define	jadeRSTA_VFR				0x80
+#define	jadeRSTA_RDO				0x40
+#define	jadeRSTA_CRC				0x20
+#define	jadeRSTA_RAB				0x10
+#define	jadeRSTA_MASK				0xF0
 
 #define	jade_HDLC_MODE					0x22				   /* RW*/
-    #define	jadeMODE_TMO				0x80
-    #define	jadeMODE_RAC				0x40
-    #define	jadeMODE_XAC				0x20
-    #define	jadeMODE_TLP				0x10
-    #define	jadeMODE_ERFS				0x02
-    #define	jadeMODE_ETFS				0x01
+#define	jadeMODE_TMO				0x80
+#define	jadeMODE_RAC				0x40
+#define	jadeMODE_XAC				0x20
+#define	jadeMODE_TLP				0x10
+#define	jadeMODE_ERFS				0x02
+#define	jadeMODE_ETFS				0x01
 
 #define	jade_HDLC_RBCH					0x24				   /* R */
 
-#define	jade_HDLC_RBCL	 				0x25				   /* R */
-#define	jade_HDLC_RCMD	 				0x25				   /* W */
-	#define	jadeRCMD_RMC 				0x80
-	#define	jadeRCMD_RRES				0x40
-	#define	jadeRCMD_RMD				0x20
-	#define	jadeRCMD_STR				0x02
+#define	jade_HDLC_RBCL					0x25				   /* R */
+#define	jade_HDLC_RCMD					0x25				   /* W */
+#define	jadeRCMD_RMC				0x80
+#define	jadeRCMD_RRES				0x40
+#define	jadeRCMD_RMD				0x20
+#define	jadeRCMD_STR				0x02
 
 #define	jade_HDLC_CCR0					0x26				   /* RW*/
-	#define	jadeCCR0_PU  				0x80
-	#define	jadeCCR0_ITF				0x40
-	#define	jadeCCR0_C32				0x20
-	#define	jadeCCR0_CRL				0x10
-	#define	jadeCCR0_RCRC				0x08
-	#define	jadeCCR0_XCRC				0x04
-	#define	jadeCCR0_RMSB				0x02
-	#define	jadeCCR0_XMSB				0x01
+#define	jadeCCR0_PU				0x80
+#define	jadeCCR0_ITF				0x40
+#define	jadeCCR0_C32				0x20
+#define	jadeCCR0_CRL				0x10
+#define	jadeCCR0_RCRC				0x08
+#define	jadeCCR0_XCRC				0x04
+#define	jadeCCR0_RMSB				0x02
+#define	jadeCCR0_XMSB				0x01
 
 #define	jade_HDLC_CCR1					0x27				   /* RW*/
-    #define	jadeCCR1_RCS0				0x80
-    #define	jadeCCR1_RCONT				0x40
-    #define	jadeCCR1_RFDIS				0x20
-    #define	jadeCCR1_XCS0				0x10
-    #define	jadeCCR1_XCONT				0x08
-    #define	jadeCCR1_XFDIS				0x04
+#define	jadeCCR1_RCS0				0x80
+#define	jadeCCR1_RCONT				0x40
+#define	jadeCCR1_RFDIS				0x20
+#define	jadeCCR1_XCS0				0x10
+#define	jadeCCR1_XCONT				0x08
+#define	jadeCCR1_XFDIS				0x04
 
 #define	jade_HDLC_TSAR					0x28				   /* RW*/
 #define	jade_HDLC_TSAX					0x29				   /* RW*/
 #define	jade_HDLC_RCCR					0x2A				   /* RW*/
 #define	jade_HDLC_XCCR					0x2B				   /* RW*/
 
-#define	jade_HDLC_ISR 					0x2C				   /* R */
-#define	jade_HDLC_IMR 					0x2C				   /* W */
-	#define	jadeISR_RME					0x80
-	#define	jadeISR_RPF					0x40
-	#define	jadeISR_RFO					0x20
-	#define	jadeISR_XPR					0x10
-	#define	jadeISR_XDU					0x08
-	#define	jadeISR_ALLS				0x04
-
-#define jade_INT            			0x75
-    #define jadeINT_HDLC1   			0x02
-    #define jadeINT_HDLC2   			0x01
-    #define jadeINT_DSP				0x04
-#define jade_INTR            			0x70
+#define	jade_HDLC_ISR					0x2C				   /* R */
+#define	jade_HDLC_IMR					0x2C				   /* W */
+#define	jadeISR_RME					0x80
+#define	jadeISR_RPF					0x40
+#define	jadeISR_RFO					0x20
+#define	jadeISR_XPR					0x10
+#define	jadeISR_XDU					0x08
+#define	jadeISR_ALLS				0x04
+
+#define jade_INT				0x75
+#define jadeINT_HDLC1				0x02
+#define jadeINT_HDLC2				0x01
+#define jadeINT_DSP				0x04
+#define jade_INTR				0x70
 
 /********************************************************************/
-/* Indirect accessible JADE registers of common interest		   	*/
+/* Indirect accessible JADE registers of common interest			*/
 /********************************************************************/
 #define	jade_CHIPVERSIONNR				0x00 /* Does not work*/
 
-#define	jade_HDLCCNTRACCESS				0x10		
-	#define	jadeINDIRECT_HAH1			0x02
-	#define	jadeINDIRECT_HAH2			0x01
+#define	jade_HDLCCNTRACCESS				0x10
+#define	jadeINDIRECT_HAH1			0x02
+#define	jadeINDIRECT_HAH2			0x01
 
 #define	jade_HDLC1SERRXPATH				0x1D
 #define	jade_HDLC1SERTXPATH				0x1E
 #define	jade_HDLC2SERRXPATH				0x1F
 #define	jade_HDLC2SERTXPATH				0x20
-	#define	jadeINDIRECT_SLIN1			0x10
-	#define	jadeINDIRECT_SLIN0			0x08
-	#define	jadeINDIRECT_LMOD1			0x04
-	#define	jadeINDIRECT_LMOD0			0x02
-	#define	jadeINDIRECT_HHR			0x01
-	#define	jadeINDIRECT_HHX			0x01
+#define	jadeINDIRECT_SLIN1			0x10
+#define	jadeINDIRECT_SLIN0			0x08
+#define	jadeINDIRECT_LMOD1			0x04
+#define	jadeINDIRECT_LMOD0			0x02
+#define	jadeINDIRECT_HHR			0x01
+#define	jadeINDIRECT_HHX			0x01
 
 #define	jade_RXAUDIOCH1CFG				0x11
 #define	jade_RXAUDIOCH2CFG				0x14
diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c
index 1f201af..f521fc8 100644
--- a/drivers/isdn/hisax/jade_irq.c
+++ b/drivers/isdn/hisax/jade_irq.c
@@ -4,7 +4,7 @@
  *
  * Author       Roland Klabunde
  * Copyright    by Roland Klabunde   <R.Klabunde@Berkom.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -13,21 +13,21 @@
 static inline void
 waitforCEC(struct IsdnCardState *cs, int jade, int reg)
 {
-  	int to = 50;
-  	int mask = (reg == jade_HDLC_XCMD ? jadeSTAR_XCEC : jadeSTAR_RCEC);
-  	while ((READJADE(cs, jade, jade_HDLC_STAR) & mask) && to) {
-  		udelay(1);
-  		to--;
-  	}
-  	if (!to)
-  		printk(KERN_WARNING "HiSax: waitforCEC (jade) timeout\n");
+	int to = 50;
+	int mask = (reg == jade_HDLC_XCMD ? jadeSTAR_XCEC : jadeSTAR_RCEC);
+	while ((READJADE(cs, jade, jade_HDLC_STAR) & mask) && to) {
+		udelay(1);
+		to--;
+	}
+	if (!to)
+		printk(KERN_WARNING "HiSax: waitforCEC (jade) timeout\n");
 }
 
 
 static inline void
 waitforXFW(struct IsdnCardState *cs, int jade)
 {
-  	/* Does not work on older jade versions, don't care */
+	/* Does not work on older jade versions, don't care */
 }
 
 static inline void
@@ -98,7 +98,7 @@ jade_fill_fifo(struct BCState *bcs)
 	bcs->tx_cnt -= count;
 	bcs->hw.hscx.count += count;
 	WRITEJADEFIFO(cs, bcs->hw.hscx.hscx, ptr, count);
-	WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, more ? jadeXCMD_XF : (jadeXCMD_XF|jadeXCMD_XME));
+	WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, more ? jadeXCMD_XF : (jadeXCMD_XF | jadeXCMD_XME));
 	if (cs->debug & L1_DEB_HSCX_FIFO) {
 		char *t = bcs->blog;
 
@@ -119,7 +119,7 @@ jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade)
 	int fifo_size = 32;
 	int count;
 	int i_jade = (int) jade; /* To satisfy the compiler */
-	
+
 	if (!test_bit(BC_FLG_INIT, &bcs->Flag))
 		return;
 
@@ -128,13 +128,13 @@ jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade)
 		if ((r & 0xf0) != 0xa0) {
 			if (!(r & 0x80))
 				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "JADE %s invalid frame", (jade ? "B":"A"));
+					debugl1(cs, "JADE %s invalid frame", (jade ? "B" : "A"));
 			if ((r & 0x40) && bcs->mode)
 				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "JADE %c RDO mode=%d", 'A'+jade, bcs->mode);
+					debugl1(cs, "JADE %c RDO mode=%d", 'A' + jade, bcs->mode);
 			if (!(r & 0x20))
 				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, "JADE %c CRC error", 'A'+jade);
+					debugl1(cs, "JADE %c CRC error", 'A' + jade);
 			WriteJADECMDR(cs, jade, jade_HDLC_RCMD, jadeRCMD_RMC);
 		} else {
 			count = READJADE(cs, i_jade, jade_HDLC_RBCL) & 0x1F;
@@ -145,7 +145,7 @@ jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade)
 				if (cs->debug & L1_DEB_HSCX_FIFO)
 					debugl1(cs, "HX Frame %d", count);
 				if (!(skb = dev_alloc_skb(count)))
-					printk(KERN_WARNING "JADE %s receive out of memory\n", (jade ? "B":"A"));
+					printk(KERN_WARNING "JADE %s receive out of memory\n", (jade ? "B" : "A"));
 				else {
 					memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
 					skb_queue_tail(&bcs->rqueue, skb);
@@ -175,8 +175,8 @@ jade_interrupt(struct IsdnCardState *cs, u_char val, u_char jade)
 				jade_fill_fifo(bcs);
 				return;
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 					u_long	flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->hw.hscx.count;
@@ -204,7 +204,7 @@ jade_int_main(struct IsdnCardState *cs, u_char val, int jade)
 {
 	struct BCState *bcs;
 	bcs = cs->bcs + jade;
-	
+
 	if (val & jadeISR_RFO) {
 		/* handled with RDO */
 		val &= ~jadeISR_RFO;
@@ -216,21 +216,21 @@ jade_int_main(struct IsdnCardState *cs, u_char val, int jade)
 			jade_fill_fifo(bcs);
 		else {
 			/* Here we lost an TX interrupt, so
-			   * restart transmitting the whole frame.
+			 * restart transmitting the whole frame.
 			 */
 			if (bcs->tx_skb) {
-			   	skb_push(bcs->tx_skb, bcs->hw.hscx.count);
+				skb_push(bcs->tx_skb, bcs->hw.hscx.count);
 				bcs->tx_cnt += bcs->hw.hscx.count;
 				bcs->hw.hscx.count = 0;
 			}
 			WriteJADECMDR(cs, bcs->hw.hscx.hscx, jade_HDLC_XCMD, jadeXCMD_XRES);
 			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "JADE %c EXIR %x Lost TX", 'A'+jade, val);
+				debugl1(cs, "JADE %c EXIR %x Lost TX", 'A' + jade, val);
 		}
 	}
-	if (val & (jadeISR_RME|jadeISR_RPF|jadeISR_XPR)) {
+	if (val & (jadeISR_RME | jadeISR_RPF | jadeISR_XPR)) {
 		if (cs->debug & L1_DEB_HSCX)
-			debugl1(cs, "JADE %c interrupt %x", 'A'+jade, val);
+			debugl1(cs, "JADE %c interrupt %x", 'A' + jade, val);
 		jade_interrupt(cs, val, jade);
 	}
 }
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
index ee4dae1..4c1bca5 100644
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -21,10 +21,10 @@
 extern char *HiSax_getrev(const char *revision);
 static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
 
-#define MsgHead(ptr, cref, mty, dis) \
-	*ptr++ = dis; \
-	*ptr++ = 0x1; \
-	*ptr++ = cref ^ 0x80; \
+#define MsgHead(ptr, cref, mty, dis)		\
+	*ptr++ = dis;				\
+	*ptr++ = 0x1;				\
+	*ptr++ = cref ^ 0x80;			\
 	*ptr++ = mty
 
 static void
@@ -83,23 +83,23 @@ l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
 	pc->para.spv = 0;
 	if (!isdigit(*teln)) {
 		switch (0x5f & *teln) {
-			case 'S':
-				pc->para.spv = 1;
-				break;
-			case 'C':
-				channel = 0x08;
-			case 'P':
-				channel |= 0x80;
-				teln++;
-				if (*teln == '1')
-					channel |= 0x01;
-				else
-					channel |= 0x02;
-				break;
-			default:
-				if (pc->st->l3.debug & L3_DEB_WARN)
-					l3_debug(pc->st, "Wrong MSN Code");
-				break;
+		case 'S':
+			pc->para.spv = 1;
+			break;
+		case 'C':
+			channel = 0x08;
+		case 'P':
+			channel |= 0x80;
+			teln++;
+			if (*teln == '1')
+				channel |= 0x01;
+			else
+				channel |= 0x02;
+			break;
+		default:
+			if (pc->st->l3.debug & L3_DEB_WARN)
+				l3_debug(pc->st, "Wrong MSN Code");
+			break;
 		}
 		teln++;
 	}
@@ -176,7 +176,7 @@ l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg)
 			return;
 		}
 		if ((pc->para.bchannel = p[2] & 0x3))
-				bcfound++;
+			bcfound++;
 	} else {
 		l3_1tr6_error(pc, "missing setup chanID", skb);
 		return;
@@ -525,15 +525,15 @@ l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
 		cause = pc->para.cause;
 	/* Map DSS1 causes */
 	switch (cause & 0x7f) {
-		case 0x10:
-			clen = 0;
-			break;
-                case 0x11:
-                        cause = CAUSE_UserBusy;
-                        break;
-		case 0x15:
-			cause = CAUSE_CallRejected;
-			break;
+	case 0x10:
+		clen = 0;
+		break;
+	case 0x11:
+		cause = CAUSE_UserBusy;
+		break;
+	case 0x15:
+		cause = CAUSE_CallRejected;
+		break;
 	}
 	StopAllL3Timer(pc);
 	MsgHead(p, pc->callref, MT_N1_DISC, PROTO_DIS_N1);
@@ -588,12 +588,12 @@ l3_1tr6_t305(struct l3_process *pc, u_char pr, void *arg)
 		cause = pc->para.cause;
 	/* Map DSS1 causes */
 	switch (cause & 0x7f) {
-		case 0x10:
-			clen = 0;
-			break;
-		case 0x15:
-			cause = CAUSE_CallRejected;
-			break;
+	case 0x10:
+		clen = 0;
+		break;
+	case 0x15:
+		cause = CAUSE_CallRejected;
+		break;
 	}
 	MsgHead(p, pc->callref, MT_N1_REL, PROTO_DIS_N1);
 	*p++ = WE0_cause;
@@ -647,19 +647,19 @@ l3_1tr6_t308_2(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3_1tr6_dl_reset(struct l3_process *pc, u_char pr, void *arg)
 {
-        pc->para.cause = CAUSE_LocalProcErr;
-        l3_1tr6_disconnect_req(pc, pr, NULL);
-        pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
+	pc->para.cause = CAUSE_LocalProcErr;
+	l3_1tr6_disconnect_req(pc, pr, NULL);
+	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
 }
 
 static void
 l3_1tr6_dl_release(struct l3_process *pc, u_char pr, void *arg)
 {
-        newl3state(pc, 0);
-        pc->para.cause = 0x1b;          /* Destination out of order */
-        pc->para.loc = 0;
-        pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
-        release_l3_process(pc);
+	newl3state(pc, 0);
+	pc->para.cause = 0x1b;          /* Destination out of order */
+	pc->para.loc = 0;
+	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
+	release_l3_process(pc);
 }
 
 /* *INDENT-OFF* */
@@ -667,9 +667,9 @@ static struct stateentry downstl[] =
 {
 	{SBIT(0),
 	 CC_SETUP | REQUEST, l3_1tr6_setup_req},
-   	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
-    	 SBIT(10),
-    	 CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req},
+	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) |
+	 SBIT(10),
+	 CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req},
 	{SBIT(12),
 	 CC_RELEASE | REQUEST, l3_1tr6_release_req},
 	{SBIT(6),
@@ -732,12 +732,12 @@ static struct stateentry datastln1[] =
 
 static struct stateentry manstatelist[] =
 {
-        {SBIT(2),
-         DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset},
-        {ALL_STATES,
-         DL_RELEASE | INDICATION, l3_1tr6_dl_release},
+	{SBIT(2),
+	 DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset},
+	{ALL_STATES,
+	 DL_RELEASE | INDICATION, l3_1tr6_dl_release},
 };
- 
+
 /* *INDENT-ON* */
 
 static void
@@ -749,16 +749,16 @@ up1tr6(struct PStack *st, int pr, void *arg)
 	char tmp[80];
 
 	switch (pr) {
-		case (DL_DATA | INDICATION):
-		case (DL_UNIT_DATA | INDICATION):
-			break;
-		case (DL_ESTABLISH | CONFIRM):
-		case (DL_ESTABLISH | INDICATION):
-		case (DL_RELEASE | INDICATION):
-		case (DL_RELEASE | CONFIRM):
-			l3_msg(st, pr, arg);
-			return;
-			break;
+	case (DL_DATA | INDICATION):
+	case (DL_UNIT_DATA | INDICATION):
+		break;
+	case (DL_ESTABLISH | CONFIRM):
+	case (DL_ESTABLISH | INDICATION):
+	case (DL_RELEASE | INDICATION):
+	case (DL_RELEASE | CONFIRM):
+		l3_msg(st, pr, arg);
+		return;
+		break;
 	}
 	if (skb->len < 4) {
 		if (st->l3.debug & L3_DEB_PROTERR) {
@@ -792,12 +792,12 @@ up1tr6(struct PStack *st, int pr, void *arg)
 		dev_kfree_skb(skb);
 		if (st->l3.debug & L3_DEB_STATE) {
 			sprintf(tmp, "up1tr6%s N0 mt %x unhandled",
-			     (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt);
+				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt);
 			l3_debug(st, tmp);
 		}
 	} else if (skb->data[0] == PROTO_DIS_N1) {
 		if (!(proc = getl3proc(st, cr))) {
-			if (mt == MT_N1_SETUP) { 
+			if (mt == MT_N1_SETUP) {
 				if (cr < 128) {
 					if (!(proc = new_l3_process(st, cr))) {
 						if (st->l3.debug & L3_DEB_PROTERR) {
@@ -812,10 +812,10 @@ up1tr6(struct PStack *st, int pr, void *arg)
 					return;
 				}
 			} else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) ||
-				(mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) ||
-				(mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
-				(mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
-				(mt == MT_N1_INFO)) {
+				   (mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) ||
+				   (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
+				   (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
+				   (mt == MT_N1_INFO)) {
 				dev_kfree_skb(skb);
 				return;
 			} else {
@@ -838,7 +838,7 @@ up1tr6(struct PStack *st, int pr, void *arg)
 			dev_kfree_skb(skb);
 			if (st->l3.debug & L3_DEB_STATE) {
 				sprintf(tmp, "up1tr6%sstate %d mt %x unhandled",
-				  (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+					(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
 					proc->state, mt);
 				l3_debug(st, tmp);
 			}
@@ -846,7 +846,7 @@ up1tr6(struct PStack *st, int pr, void *arg)
 		} else {
 			if (st->l3.debug & L3_DEB_STATE) {
 				sprintf(tmp, "up1tr6%sstate %d mt %x",
-				  (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+					(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
 					proc->state, mt);
 				l3_debug(st, tmp);
 			}
@@ -863,7 +863,7 @@ down1tr6(struct PStack *st, int pr, void *arg)
 	struct Channel *chan;
 	char tmp[80];
 
-	if ((DL_ESTABLISH | REQUEST)== pr) {
+	if ((DL_ESTABLISH | REQUEST) == pr) {
 		l3_msg(st, pr, NULL);
 		return;
 	} else if ((CC_SETUP | REQUEST) == pr) {
@@ -905,31 +905,31 @@ down1tr6(struct PStack *st, int pr, void *arg)
 static void
 man1tr6(struct PStack *st, int pr, void *arg)
 {
-        int i;
-        struct l3_process *proc = arg;
- 
-        if (!proc) {
-                printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr);
-                return;
-        }
-        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
-                if ((pr == manstatelist[i].primitive) &&
-                    ((1 << proc->state) & manstatelist[i].state))
-                        break;
-        if (i == ARRAY_SIZE(manstatelist)) {
-                if (st->l3.debug & L3_DEB_STATE) {
-                        l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
-                                proc->callref & 0x7f, proc->state, pr);
-                }
-        } else {
-                if (st->l3.debug & L3_DEB_STATE) {
-                        l3_debug(st, "cr %d man1tr6 state %d prim %d",
-                                proc->callref & 0x7f, proc->state, pr);
-                }
-                manstatelist[i].rout(proc, pr, arg);
-        }
-}
- 
+	int i;
+	struct l3_process *proc = arg;
+
+	if (!proc) {
+		printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr);
+		return;
+	}
+	for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
+		if ((pr == manstatelist[i].primitive) &&
+		    ((1 << proc->state) & manstatelist[i].state))
+			break;
+	if (i == ARRAY_SIZE(manstatelist)) {
+		if (st->l3.debug & L3_DEB_STATE) {
+			l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
+				 proc->callref & 0x7f, proc->state, pr);
+		}
+	} else {
+		if (st->l3.debug & L3_DEB_STATE) {
+			l3_debug(st, "cr %d man1tr6 state %d prim %d",
+				 proc->callref & 0x7f, proc->state, pr);
+		}
+		manstatelist[i].rout(proc, pr, arg);
+	}
+}
+
 void
 setstack_1tr6(struct PStack *st)
 {
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index 6a8acf6..cda7006 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -7,7 +7,7 @@
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -30,14 +30,14 @@ static const char *dss1_revision = "$Revision: 2.32.2.3 $";
 
 #define EXT_BEARER_CAPS 1
 
-#define	MsgHead(ptr, cref, mty) \
-	*ptr++ = 0x8; \
-	if (cref == -1) { \
-		*ptr++ = 0x0; \
-	} else { \
-		*ptr++ = 0x1; \
-		*ptr++ = cref^0x80; \
-	} \
+#define	MsgHead(ptr, cref, mty)			\
+	*ptr++ = 0x8;				\
+	if (cref == -1) {			\
+		*ptr++ = 0x0;			\
+	} else {				\
+		*ptr++ = 0x1;			\
+		*ptr++ = cref^0x80;		\
+	}					\
 	*ptr++ = mty
 
 
@@ -49,22 +49,22 @@ static unsigned char new_invoke_id(struct PStack *p)
 {
 	unsigned char retval;
 	int i;
-  
+
 	i = 32; /* maximum search depth */
 
 	retval = p->prot.dss1.last_invoke_id + 1; /* try new id */
 	while ((i) && (p->prot.dss1.invoke_used[retval >> 3] == 0xFF)) {
 		p->prot.dss1.last_invoke_id = (retval & 0xF8) + 8;
 		i--;
-	}  
+	}
 	if (i) {
 		while (p->prot.dss1.invoke_used[retval >> 3] & (1 << (retval & 7)))
-		retval++; 
+			retval++;
 	} else
 		retval = 0;
 	p->prot.dss1.last_invoke_id = retval;
 	p->prot.dss1.invoke_used[retval >> 3] |= (1 << (retval & 7));
-	return(retval);  
+	return (retval);
 } /* new_invoke_id */
 
 /*************************/
@@ -73,10 +73,10 @@ static unsigned char new_invoke_id(struct PStack *p)
 static void free_invoke_id(struct PStack *p, unsigned char id)
 {
 
-  if (!id) return; /* 0 = invalid value */
+	if (!id) return; /* 0 = invalid value */
 
-  p->prot.dss1.invoke_used[id >> 3] &= ~(1 << (id & 7));
-} /* free_invoke_id */  
+	p->prot.dss1.invoke_used[id >> 3] &= ~(1 << (id & 7));
+} /* free_invoke_id */
 
 
 /**********************************************************/
@@ -86,26 +86,26 @@ static struct l3_process
 *dss1_new_l3_process(struct PStack *st, int cr)
 {  struct l3_process *proc;
 
-   if (!(proc = new_l3_process(st, cr))) 
-     return(NULL);
+	if (!(proc = new_l3_process(st, cr)))
+		return (NULL);
 
-   proc->prot.dss1.invoke_id = 0;
-   proc->prot.dss1.remote_operation = 0;
-   proc->prot.dss1.uus1_data[0] = '\0';
-   
-   return(proc);
+	proc->prot.dss1.invoke_id = 0;
+	proc->prot.dss1.remote_operation = 0;
+	proc->prot.dss1.uus1_data[0] = '\0';
+
+	return (proc);
 } /* dss1_new_l3_process */
 
 /************************************************/
 /* free a l3 process and all dss1 specific data */
-/************************************************/ 
+/************************************************/
 static void
 dss1_release_l3_process(struct l3_process *p)
 {
-   free_invoke_id(p->st,p->prot.dss1.invoke_id);
-   release_l3_process(p);
+	free_invoke_id(p->st, p->prot.dss1.invoke_id);
+	release_l3_process(p);
 } /* dss1_release_l3_process */
- 
+
 /********************************************************/
 /* search a process with invoke id id and dummy callref */
 /********************************************************/
@@ -113,120 +113,120 @@ static struct l3_process *
 l3dss1_search_dummy_proc(struct PStack *st, int id)
 { struct l3_process *pc = st->l3.proc; /* start of processes */
 
-  if (!id) return(NULL);
+	if (!id) return (NULL);
 
-  while (pc)
-   { if ((pc->callref == -1) && (pc->prot.dss1.invoke_id == id))
-       return(pc);
-     pc = pc->next;
-   } 
-  return(NULL);
+	while (pc)
+	{ if ((pc->callref == -1) && (pc->prot.dss1.invoke_id == id))
+			return (pc);
+		pc = pc->next;
+	}
+	return (NULL);
 } /* l3dss1_search_dummy_proc */
 
 /*******************************************************************/
 /* called when a facility message with a dummy callref is received */
 /* and a return result is delivered. id specifies the invoke id.   */
-/*******************************************************************/ 
-static void 
+/*******************************************************************/
+static void
 l3dss1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs;
-  struct l3_process *pc = NULL; 
-
-  if ((pc = l3dss1_search_dummy_proc(st, id)))
-   { L3DelTimer(&pc->timer); /* remove timer */
-
-     cs = pc->st->l1.hardware;
-     ic.driver = cs->myid;
-     ic.command = ISDN_STAT_PROT;
-     ic.arg = DSS1_STAT_INVOKE_RES;
-     ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
-     ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
-     ic.parm.dss1_io.proc = pc->prot.dss1.proc;
-     ic.parm.dss1_io.timeout= 0;
-     ic.parm.dss1_io.datalen = nlen;
-     ic.parm.dss1_io.data = p;
-     free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
-     pc->prot.dss1.invoke_id = 0; /* reset id */
-
-     cs->iif.statcallb(&ic);
-     dss1_release_l3_process(pc); 
-   }
-  else
-   l3_debug(st, "dummy return result id=0x%x result len=%d",id,nlen);
+	struct IsdnCardState *cs;
+	struct l3_process *pc = NULL;
+
+	if ((pc = l3dss1_search_dummy_proc(st, id)))
+	{ L3DelTimer(&pc->timer); /* remove timer */
+
+		cs = pc->st->l1.hardware;
+		ic.driver = cs->myid;
+		ic.command = ISDN_STAT_PROT;
+		ic.arg = DSS1_STAT_INVOKE_RES;
+		ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
+		ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
+		ic.parm.dss1_io.proc = pc->prot.dss1.proc;
+		ic.parm.dss1_io.timeout = 0;
+		ic.parm.dss1_io.datalen = nlen;
+		ic.parm.dss1_io.data = p;
+		free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
+		pc->prot.dss1.invoke_id = 0; /* reset id */
+
+		cs->iif.statcallb(&ic);
+		dss1_release_l3_process(pc);
+	}
+	else
+		l3_debug(st, "dummy return result id=0x%x result len=%d", id, nlen);
 } /* l3dss1_dummy_return_result */
 
 /*******************************************************************/
 /* called when a facility message with a dummy callref is received */
 /* and a return error is delivered. id specifies the invoke id.    */
-/*******************************************************************/ 
-static void 
+/*******************************************************************/
+static void
 l3dss1_dummy_error_return(struct PStack *st, int id, ulong error)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs;
-  struct l3_process *pc = NULL; 
-
-  if ((pc = l3dss1_search_dummy_proc(st, id)))
-   { L3DelTimer(&pc->timer); /* remove timer */
-
-     cs = pc->st->l1.hardware;
-     ic.driver = cs->myid;
-     ic.command = ISDN_STAT_PROT;
-     ic.arg = DSS1_STAT_INVOKE_ERR;
-     ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
-     ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
-     ic.parm.dss1_io.proc = pc->prot.dss1.proc;
-     ic.parm.dss1_io.timeout= error;
-     ic.parm.dss1_io.datalen = 0;
-     ic.parm.dss1_io.data = NULL;
-     free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
-     pc->prot.dss1.invoke_id = 0; /* reset id */
-
-     cs->iif.statcallb(&ic);
-     dss1_release_l3_process(pc); 
-   }
-  else
-   l3_debug(st, "dummy return error id=0x%x error=0x%lx",id,error);
+	struct IsdnCardState *cs;
+	struct l3_process *pc = NULL;
+
+	if ((pc = l3dss1_search_dummy_proc(st, id)))
+	{ L3DelTimer(&pc->timer); /* remove timer */
+
+		cs = pc->st->l1.hardware;
+		ic.driver = cs->myid;
+		ic.command = ISDN_STAT_PROT;
+		ic.arg = DSS1_STAT_INVOKE_ERR;
+		ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
+		ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
+		ic.parm.dss1_io.proc = pc->prot.dss1.proc;
+		ic.parm.dss1_io.timeout = error;
+		ic.parm.dss1_io.datalen = 0;
+		ic.parm.dss1_io.data = NULL;
+		free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
+		pc->prot.dss1.invoke_id = 0; /* reset id */
+
+		cs->iif.statcallb(&ic);
+		dss1_release_l3_process(pc);
+	}
+	else
+		l3_debug(st, "dummy return error id=0x%x error=0x%lx", id, error);
 } /* l3dss1_error_return */
 
 /*******************************************************************/
 /* called when a facility message with a dummy callref is received */
 /* and a invoke is delivered. id specifies the invoke id.          */
-/*******************************************************************/ 
-static void 
-l3dss1_dummy_invoke(struct PStack *st, int cr, int id, 
-                    int ident, u_char *p, u_char nlen)
+/*******************************************************************/
+static void
+l3dss1_dummy_invoke(struct PStack *st, int cr, int id,
+		    int ident, u_char *p, u_char nlen)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs;
-  
-  l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d",
-               (cr == -1) ? "local" : "broadcast",id,ident,nlen);
-  if (cr >= -1) return; /* ignore local data */
-
-  cs = st->l1.hardware;
-  ic.driver = cs->myid;
-  ic.command = ISDN_STAT_PROT;
-  ic.arg = DSS1_STAT_INVOKE_BRD;
-  ic.parm.dss1_io.hl_id = id;
-  ic.parm.dss1_io.ll_id = 0;
-  ic.parm.dss1_io.proc = ident;
-  ic.parm.dss1_io.timeout= 0;
-  ic.parm.dss1_io.datalen = nlen;
-  ic.parm.dss1_io.data = p;
-
-  cs->iif.statcallb(&ic);
+	struct IsdnCardState *cs;
+
+	l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d",
+		 (cr == -1) ? "local" : "broadcast", id, ident, nlen);
+	if (cr >= -1) return; /* ignore local data */
+
+	cs = st->l1.hardware;
+	ic.driver = cs->myid;
+	ic.command = ISDN_STAT_PROT;
+	ic.arg = DSS1_STAT_INVOKE_BRD;
+	ic.parm.dss1_io.hl_id = id;
+	ic.parm.dss1_io.ll_id = 0;
+	ic.parm.dss1_io.proc = ident;
+	ic.parm.dss1_io.timeout = 0;
+	ic.parm.dss1_io.datalen = nlen;
+	ic.parm.dss1_io.data = p;
+
+	cs->iif.statcallb(&ic);
 } /* l3dss1_dummy_invoke */
 
 static void
 l3dss1_parse_facility(struct PStack *st, struct l3_process *pc,
-                      int cr, u_char * p)
+		      int cr, u_char *p)
 {
 	int qd_len = 0;
 	unsigned char nlen = 0, ilen, cp_tag;
 	int ident, id;
 	ulong err_ret;
 
-	if (pc) 
+	if (pc)
 		st = pc->st; /* valid Stack */
 	else
 		if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */
@@ -255,243 +255,243 @@ l3dss1_parse_facility(struct PStack *st, struct l3_process *pc,
 		l3_debug(st, "class and form != 0xA0");
 		return;
 	}
-       
-        cp_tag = *p & 0x1F; /* remember tag value */
 
-        p++;
+	cp_tag = *p & 0x1F; /* remember tag value */
+
+	p++;
 	qd_len--;
-	if (qd_len < 1) 
-          { l3_debug(st, "qd_len < 1");
-	    return;
-	  }
-	if (*p & 0x80) 
-          { /* length format indefinite or limited */
-	    nlen = *p++ & 0x7F; /* number of len bytes or indefinite */
-            if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
-                (nlen > 1))   
-	     { l3_debug(st, "length format error or not implemented");
-	       return;
-             }
-            if (nlen == 1)
-	     { nlen = *p++; /* complete length */
-               qd_len--;
-             } 
-            else
-	     { qd_len -= 2; /* trailing null bytes */
-               if ((*(p+qd_len)) || (*(p+qd_len+1)))
-		{ l3_debug(st,"length format indefinite error");
-                  return;
-                }
-               nlen = qd_len;
-             }
-	  }
-        else
-	  { nlen = *p++;
-	    qd_len--;
-          } 
-	if (qd_len < nlen) 
-          { l3_debug(st, "qd_len < nlen");
-	    return;
-	  }
+	if (qd_len < 1)
+	{ l3_debug(st, "qd_len < 1");
+		return;
+	}
+	if (*p & 0x80)
+	{ /* length format indefinite or limited */
+		nlen = *p++ & 0x7F; /* number of len bytes or indefinite */
+		if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
+		    (nlen > 1))
+		{ l3_debug(st, "length format error or not implemented");
+			return;
+		}
+		if (nlen == 1)
+		{ nlen = *p++; /* complete length */
+			qd_len--;
+		}
+		else
+		{ qd_len -= 2; /* trailing null bytes */
+			if ((*(p + qd_len)) || (*(p + qd_len + 1)))
+			{ l3_debug(st, "length format indefinite error");
+				return;
+			}
+			nlen = qd_len;
+		}
+	}
+	else
+	{ nlen = *p++;
+		qd_len--;
+	}
+	if (qd_len < nlen)
+	{ l3_debug(st, "qd_len < nlen");
+		return;
+	}
 	qd_len -= nlen;
 
-	if (nlen < 2) 
-          { l3_debug(st, "nlen < 2");
-	    return;
-	  }
-        if (*p != 0x02) 
-          {  /* invoke identifier tag */
-	     l3_debug(st, "invoke identifier tag !=0x02");
-	     return;
-	  }
+	if (nlen < 2)
+	{ l3_debug(st, "nlen < 2");
+		return;
+	}
+	if (*p != 0x02)
+	{  /* invoke identifier tag */
+		l3_debug(st, "invoke identifier tag !=0x02");
+		return;
+	}
 	p++;
 	nlen--;
-	if (*p & 0x80) 
-          { /* length format */
-	    l3_debug(st, "invoke id length format 2");
-	    return;
-	  }
+	if (*p & 0x80)
+	{ /* length format */
+		l3_debug(st, "invoke id length format 2");
+		return;
+	}
 	ilen = *p++;
 	nlen--;
-	if (ilen > nlen || ilen == 0) 
-          { l3_debug(st, "ilen > nlen || ilen == 0");
-	    return;
-	  }
+	if (ilen > nlen || ilen == 0)
+	{ l3_debug(st, "ilen > nlen || ilen == 0");
+		return;
+	}
 	nlen -= ilen;
 	id = 0;
-	while (ilen > 0) 
-          { id = (id << 8) | (*p++ & 0xFF);	/* invoke identifier */
-	    ilen--;
-	  }
+	while (ilen > 0)
+	{ id = (id << 8) | (*p++ & 0xFF);	/* invoke identifier */
+		ilen--;
+	}
 
 	switch (cp_tag) {	/* component tag */
-		case 1:	/* invoke */
-				if (nlen < 2) {
-					l3_debug(st, "nlen < 2 22");
-					return;
-				}
-				if (*p != 0x02) {	/* operation value */
-					l3_debug(st, "operation value !=0x02");
-					return;
-				}
-				p++;
-				nlen--;
-				ilen = *p++;
-				nlen--;
-				if (ilen > nlen || ilen == 0) {
-					l3_debug(st, "ilen > nlen || ilen == 0 22");
-					return;
-				}
-				nlen -= ilen;
-				ident = 0;
-				while (ilen > 0) {
-					ident = (ident << 8) | (*p++ & 0xFF);
-					ilen--;
-				}
+	case 1:	/* invoke */
+		if (nlen < 2) {
+			l3_debug(st, "nlen < 2 22");
+			return;
+		}
+		if (*p != 0x02) {	/* operation value */
+			l3_debug(st, "operation value !=0x02");
+			return;
+		}
+		p++;
+		nlen--;
+		ilen = *p++;
+		nlen--;
+		if (ilen > nlen || ilen == 0) {
+			l3_debug(st, "ilen > nlen || ilen == 0 22");
+			return;
+		}
+		nlen -= ilen;
+		ident = 0;
+		while (ilen > 0) {
+			ident = (ident << 8) | (*p++ & 0xFF);
+			ilen--;
+		}
 
-                                if (!pc) 
-			         { l3dss1_dummy_invoke(st, cr, id, ident, p, nlen);
-                                   return;
-                                 } 
+		if (!pc)
+		{ l3dss1_dummy_invoke(st, cr, id, ident, p, nlen);
+			return;
+		}
 #ifdef CONFIG_DE_AOC
-			{
-
-#define FOO1(s,a,b) \
-	    while(nlen > 1) {		\
-		    int ilen = p[1];	\
-		    if(nlen < ilen+2) {	\
-			    l3_debug(st, "FOO1  nlen < ilen+2"); \
-			    return;		\
-		    }			\
-		    nlen -= ilen+2;		\
-		    if((*p & 0xFF) == (a)) {	\
-			    int nlen = ilen;	\
-			    p += 2;		\
-			    b;		\
-		    } else {		\
-			    p += ilen+2;	\
-		    }			\
-	    }
-
-				switch (ident) {
-					case 0x22:	/* during */
-						FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( {
-							       ident = 0;
-							nlen = (nlen)?nlen:0; /* Make gcc happy */
-							while (ilen > 0) {
-														     ident = (ident << 8) | *p++;
-								  ilen--;
-									}
-														     if (ident > pc->para.chargeinfo) {
-														     pc->para.chargeinfo = ident;
-														     st->l3.l3l4(st, CC_CHARGE | INDICATION, pc);
-									}
-														     if (st->l3.debug & L3_DEB_CHARGE) {
-														     if (*(p + 2) == 0) {
-														     l3_debug(st, "charging info during %d", pc->para.chargeinfo);
-									}
-								   else {
-														     l3_debug(st, "charging info final %d", pc->para.chargeinfo);
-									}
-									}
-									}
-								    )))))
-							break;
-					case 0x24:	/* final */
-						FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( {
-							       ident = 0;
-							nlen = (nlen)?nlen:0; /* Make gcc happy */
-							while (ilen > 0) {
-																      ident = (ident << 8) | *p++;
-								  ilen--;
-									}
-																      if (ident > pc->para.chargeinfo) {
-																      pc->para.chargeinfo = ident;
-																      st->l3.l3l4(st, CC_CHARGE | INDICATION, pc);
-									}
-																      if (st->l3.debug & L3_DEB_CHARGE) {
-																      l3_debug(st, "charging info final %d", pc->para.chargeinfo);
-									}
+		{
+
+#define FOO1(s, a, b)							\
+			while (nlen > 1) {				\
+				int ilen = p[1];			\
+				if (nlen < ilen + 2) {			\
+					l3_debug(st, "FOO1  nlen < ilen+2"); \
+					return;				\
+				}					\
+				nlen -= ilen + 2;			\
+				if ((*p & 0xFF) == (a)) {		\
+					int nlen = ilen;		\
+					p += 2;				\
+					b;				\
+				} else {				\
+					p += ilen + 2;			\
+				}					\
+			}
+
+			switch (ident) {
+			case 0x22:	/* during */
+				FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( {
+										ident = 0;
+										nlen = (nlen) ? nlen : 0; /* Make gcc happy */
+										while (ilen > 0) {
+											ident = (ident << 8) | *p++;
+											ilen--;
+										}
+										if (ident > pc->para.chargeinfo) {
+											pc->para.chargeinfo = ident;
+											st->l3.l3l4(st, CC_CHARGE | INDICATION, pc);
+										}
+										if (st->l3.debug & L3_DEB_CHARGE) {
+											if (*(p + 2) == 0) {
+												l3_debug(st, "charging info during %d", pc->para.chargeinfo);
+											}
+											else {
+												l3_debug(st, "charging info final %d", pc->para.chargeinfo);
+											}
+										}
 									}
-								   ))))))
-							break;
-					default:
-                                                       l3_debug(st, "invoke break invalid ident %02x",ident);
-						break;
-				}
+									)))))
+					break;
+			case 0x24:	/* final */
+				FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( {
+											ident = 0;
+											nlen = (nlen) ? nlen : 0; /* Make gcc happy */
+											while (ilen > 0) {
+												ident = (ident << 8) | *p++;
+												ilen--;
+											}
+											if (ident > pc->para.chargeinfo) {
+												pc->para.chargeinfo = ident;
+												st->l3.l3l4(st, CC_CHARGE | INDICATION, pc);
+											}
+											if (st->l3.debug & L3_DEB_CHARGE) {
+												l3_debug(st, "charging info final %d", pc->para.chargeinfo);
+											}
+										}
+										))))))
+					break;
+			default:
+				l3_debug(st, "invoke break invalid ident %02x", ident);
+				break;
+			}
 #undef FOO1
 
-			}
+		}
 #else  /* not CONFIG_DE_AOC */
-                        l3_debug(st, "invoke break");
+		l3_debug(st, "invoke break");
 #endif /* not CONFIG_DE_AOC */
-			break;
-		case 2:	/* return result */
-			 /* if no process available handle separately */ 
-                        if (!pc)
-			 { if (cr == -1) 
-                             l3dss1_dummy_return_result(st, id, p, nlen);
-                           return; 
-                         }   
-                        if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id))
-                          { /* Diversion successful */
-                            free_invoke_id(st,pc->prot.dss1.invoke_id);
-                            pc->prot.dss1.remote_result = 0; /* success */     
-                            pc->prot.dss1.invoke_id = 0;
-                            pc->redir_result = pc->prot.dss1.remote_result; 
-                            st->l3.l3l4(st, CC_REDIR | INDICATION, pc);                                  } /* Diversion successful */
-                        else
-                          l3_debug(st,"return error unknown identifier");
-			break;
-		case 3:	/* return error */
-                            err_ret = 0;
-	                    if (nlen < 2) 
-                              { l3_debug(st, "return error nlen < 2");
-	                        return;
-	                      }
-                            if (*p != 0x02) 
-                              { /* result tag */
-	                        l3_debug(st, "invoke error tag !=0x02");
-	                        return;
-	                      }
-	                    p++;
-	                    nlen--;
-	                    if (*p > 4) 
-                              { /* length format */
-	                        l3_debug(st, "invoke return errlen > 4 ");
-	                        return;
-	                      }
-	                    ilen = *p++;
-	                    nlen--;
-	                    if (ilen > nlen || ilen == 0) 
-                              { l3_debug(st, "error return ilen > nlen || ilen == 0");
-	                        return;
-	                       }
-	                    nlen -= ilen;
-	                    while (ilen > 0) 
-                             { err_ret = (err_ret << 8) | (*p++ & 0xFF);	/* error value */
-	                       ilen--;
-	                     }
-			 /* if no process available handle separately */ 
-                        if (!pc)
-			 { if (cr == -1)
-                             l3dss1_dummy_error_return(st, id, err_ret);
-                           return; 
-                         }   
-                        if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id))
-                          { /* Deflection error */
-                            free_invoke_id(st,pc->prot.dss1.invoke_id);
-                            pc->prot.dss1.remote_result = err_ret; /* result */
-                            pc->prot.dss1.invoke_id = 0; 
-                            pc->redir_result = pc->prot.dss1.remote_result; 
-                            st->l3.l3l4(st, CC_REDIR | INDICATION, pc);  
-                          } /* Deflection error */
-                        else
-                          l3_debug(st,"return result unknown identifier");
-			break;
-		default:
-			l3_debug(st, "facility default break tag=0x%02x",cp_tag);
-			break;
+		break;
+	case 2:	/* return result */
+		/* if no process available handle separately */
+		if (!pc)
+		{ if (cr == -1)
+				l3dss1_dummy_return_result(st, id, p, nlen);
+			return;
+		}
+		if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id))
+		{ /* Diversion successful */
+			free_invoke_id(st, pc->prot.dss1.invoke_id);
+			pc->prot.dss1.remote_result = 0; /* success */
+			pc->prot.dss1.invoke_id = 0;
+			pc->redir_result = pc->prot.dss1.remote_result;
+			st->l3.l3l4(st, CC_REDIR | INDICATION, pc);                                  } /* Diversion successful */
+		else
+			l3_debug(st, "return error unknown identifier");
+		break;
+	case 3:	/* return error */
+		err_ret = 0;
+		if (nlen < 2)
+		{ l3_debug(st, "return error nlen < 2");
+			return;
+		}
+		if (*p != 0x02)
+		{ /* result tag */
+			l3_debug(st, "invoke error tag !=0x02");
+			return;
+		}
+		p++;
+		nlen--;
+		if (*p > 4)
+		{ /* length format */
+			l3_debug(st, "invoke return errlen > 4 ");
+			return;
+		}
+		ilen = *p++;
+		nlen--;
+		if (ilen > nlen || ilen == 0)
+		{ l3_debug(st, "error return ilen > nlen || ilen == 0");
+			return;
+		}
+		nlen -= ilen;
+		while (ilen > 0)
+		{ err_ret = (err_ret << 8) | (*p++ & 0xFF);	/* error value */
+			ilen--;
+		}
+		/* if no process available handle separately */
+		if (!pc)
+		{ if (cr == -1)
+				l3dss1_dummy_error_return(st, id, err_ret);
+			return;
+		}
+		if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id))
+		{ /* Deflection error */
+			free_invoke_id(st, pc->prot.dss1.invoke_id);
+			pc->prot.dss1.remote_result = err_ret; /* result */
+			pc->prot.dss1.invoke_id = 0;
+			pc->redir_result = pc->prot.dss1.remote_result;
+			st->l3.l3l4(st, CC_REDIR | INDICATION, pc);
+		} /* Deflection error */
+		else
+			l3_debug(st, "return result unknown identifier");
+		break;
+	default:
+		l3_debug(st, "facility default break tag=0x%02x", cp_tag);
+		break;
 	}
 }
 
@@ -568,21 +568,21 @@ l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
 	struct sk_buff *skb;
 
 	switch (pc->para.cause) {
-		case 81:	/* invalid callreference */
-		case 88:	/* incomp destination */
-		case 96:	/* mandory IE missing */
-		case 100:       /* invalid IE contents */
-		case 101:	/* incompatible Callstate */
-			MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
-			*p++ = IE_CAUSE;
-			*p++ = 0x2;
-			*p++ = 0x80;
-			*p++ = pc->para.cause | 0x80;
-			break;
-		default:
-			printk(KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n",
-				pc->para.cause);
-			return;
+	case 81:	/* invalid callreference */
+	case 88:	/* incomp destination */
+	case 96:	/* mandory IE missing */
+	case 100:       /* invalid IE contents */
+	case 101:	/* incompatible Callstate */
+		MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
+		*p++ = IE_CAUSE;
+		*p++ = 0x2;
+		*p++ = 0x80;
+		*p++ = pc->para.cause | 0x80;
+		break;
+	default:
+		printk(KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n",
+		       pc->para.cause);
+		return;
 	}
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
@@ -593,42 +593,42 @@ l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
 }
 
 static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
-		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,
-		IE_USER_USER, -1};
+			    IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,
+			    IE_USER_USER, -1};
 static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
-		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
-static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, 
-		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
-		IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
+				   IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
+static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
+			   IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
+			   IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
 static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1};
 static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY,
-		IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
+			      IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
 static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL,
-		IE_CALLED_PN, -1};
+			       IE_CALLED_PN, -1};
 static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1};
 static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS |
-		IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
+			    IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
 static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY,
-		IE_SIGNAL, IE_USER_USER, -1};
-/* a RELEASE_COMPLETE with errors don't require special actions 
-static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
+			   IE_SIGNAL, IE_USER_USER, -1};
+/* a RELEASE_COMPLETE with errors don't require special actions
+   static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
 */
-static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY,
-		IE_DISPLAY, -1};
+static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
+				      IE_DISPLAY, -1};
 static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
 static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER  | IE_MANDATORY,
-		IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY, IE_PROGRESS,
-		IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,
-		IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,
-		IE_LLC, IE_HLC, IE_USER_USER, -1};
+			 IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, IE_PROGRESS,
+			 IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,
+			 IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,
+			 IE_LLC, IE_HLC, IE_USER_USER, -1};
 static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
-		IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};
+				     IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};
 static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE |
-		IE_MANDATORY, IE_DISPLAY, -1};
+			  IE_MANDATORY, IE_DISPLAY, -1};
 static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1};
 static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1};
 static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
-/* not used 
+/* not used
  * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY,
  *		IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
  * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1};
@@ -636,8 +636,8 @@ static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
  *		IE_MANDATORY, -1};
  */
 static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1};
-static int comp_required[] = {1,2,3,5,6,7,9,10,11,14,15,-1};
-static int l3_valid_states[] = {0,1,2,3,4,6,7,8,9,10,11,12,15,17,19,25,-1};
+static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1};
+static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1};
 
 struct ie_len {
 	int ie;
@@ -678,7 +678,7 @@ struct ie_len max_ie_len[] = {
 	{IE_LLC, 18},
 	{IE_HLC, 5},
 	{IE_USER_USER, 131},
-	{-1,0},
+	{-1, 0},
 };
 
 static int
@@ -686,10 +686,10 @@ getmax_ie_len(u_char ie) {
 	int i = 0;
 	while (max_ie_len[i].ie != -1) {
 		if (max_ie_len[i].ie == ie)
-			return(max_ie_len[i].len);
+			return (max_ie_len[i].len);
 		i++;
 	}
-	return(255);
+	return (255);
 }
 
 static int
@@ -699,14 +699,14 @@ ie_in_set(struct l3_process *pc, u_char ie, int *checklist) {
 	while (*checklist != -1) {
 		if ((*checklist & 0xff) == ie) {
 			if (ie & 0x80)
-				return(-ret);
+				return (-ret);
 			else
-				return(ret);
+				return (ret);
 		}
 		ret++;
 		checklist++;
 	}
-	return(0);
+	return (0);
 }
 
 static int
@@ -720,7 +720,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 	u_char codeset = 0;
 	u_char old_codeset = 0;
 	u_char codelock = 1;
-	
+
 	p = skb->data;
 	/* skip cr */
 	p++;
@@ -738,7 +738,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 				codelock = 1;
 			if (pc->debug & L3_DEB_CHECK)
 				l3_debug(pc->st, "check IE shift%scodeset %d->%d",
-					codelock ? " locking ": " ", old_codeset, codeset);
+					 codelock ? " locking " : " ", old_codeset, codeset);
 			p++;
 			continue;
 		}
@@ -770,7 +770,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 		if (!codelock) {
 			if (pc->debug & L3_DEB_CHECK)
 				l3_debug(pc->st, "check IE shift back codeset %d->%d",
-					codeset, old_codeset);
+					 codeset, old_codeset);
 			codeset = old_codeset;
 			codelock = 1;
 		}
@@ -778,17 +778,17 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 	if (err_compr | err_ureg | err_len | err_seq) {
 		if (pc->debug & L3_DEB_CHECK)
 			l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d",
-				mt, err_compr, err_ureg, err_len, err_seq);
+				 mt, err_compr, err_ureg, err_len, err_seq);
 		if (err_compr)
-			return(ERR_IE_COMPREHENSION);
+			return (ERR_IE_COMPREHENSION);
 		if (err_ureg)
-			return(ERR_IE_UNRECOGNIZED);
+			return (ERR_IE_UNRECOGNIZED);
 		if (err_len)
-			return(ERR_IE_LENGTH);
+			return (ERR_IE_LENGTH);
 		if (err_seq)
-			return(ERR_IE_SEQUENCE);
-	} 
-	return(0);
+			return (ERR_IE_SEQUENCE);
+	}
+	return (0);
 }
 
 /* verify if a message type exists and contain no IE error */
@@ -796,42 +796,42 @@ static int
 l3dss1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg)
 {
 	switch (mt) {
-		case MT_ALERTING:
-		case MT_CALL_PROCEEDING:
-		case MT_CONNECT:
-		case MT_CONNECT_ACKNOWLEDGE:
-		case MT_DISCONNECT:
-		case MT_INFORMATION:
-		case MT_FACILITY:
-		case MT_NOTIFY:
-		case MT_PROGRESS:
-		case MT_RELEASE:
-		case MT_RELEASE_COMPLETE:
-		case MT_SETUP:
-		case MT_SETUP_ACKNOWLEDGE:
-		case MT_RESUME_ACKNOWLEDGE:
-		case MT_RESUME_REJECT:
-		case MT_SUSPEND_ACKNOWLEDGE:
-		case MT_SUSPEND_REJECT:
-		case MT_USER_INFORMATION:
-		case MT_RESTART:
-		case MT_RESTART_ACKNOWLEDGE:
-		case MT_CONGESTION_CONTROL:
-		case MT_STATUS:
-		case MT_STATUS_ENQUIRY:
-			if (pc->debug & L3_DEB_CHECK)
-				l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) OK", mt);
-			break;
-		case MT_RESUME: /* RESUME only in user->net */
-		case MT_SUSPEND: /* SUSPEND only in user->net */
-		default:
-			if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))
-				l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) fail", mt);
-			pc->para.cause = 97;
-			l3dss1_status_send(pc, 0, NULL);
-			return(1);
+	case MT_ALERTING:
+	case MT_CALL_PROCEEDING:
+	case MT_CONNECT:
+	case MT_CONNECT_ACKNOWLEDGE:
+	case MT_DISCONNECT:
+	case MT_INFORMATION:
+	case MT_FACILITY:
+	case MT_NOTIFY:
+	case MT_PROGRESS:
+	case MT_RELEASE:
+	case MT_RELEASE_COMPLETE:
+	case MT_SETUP:
+	case MT_SETUP_ACKNOWLEDGE:
+	case MT_RESUME_ACKNOWLEDGE:
+	case MT_RESUME_REJECT:
+	case MT_SUSPEND_ACKNOWLEDGE:
+	case MT_SUSPEND_REJECT:
+	case MT_USER_INFORMATION:
+	case MT_RESTART:
+	case MT_RESTART_ACKNOWLEDGE:
+	case MT_CONGESTION_CONTROL:
+	case MT_STATUS:
+	case MT_STATUS_ENQUIRY:
+		if (pc->debug & L3_DEB_CHECK)
+			l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) OK", mt);
+		break;
+	case MT_RESUME: /* RESUME only in user->net */
+	case MT_SUSPEND: /* SUSPEND only in user->net */
+	default:
+		if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))
+			l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) fail", mt);
+		pc->para.cause = 97;
+		l3dss1_status_send(pc, 0, NULL);
+		return (1);
 	}
-	return(0);
+	return (0);
 }
 
 static void
@@ -839,24 +839,24 @@ l3dss1_std_ie_err(struct l3_process *pc, int ret) {
 
 	if (pc->debug & L3_DEB_CHECK)
 		l3_debug(pc->st, "check_infoelements ret %d", ret);
-	switch(ret) {
-		case 0: 
-			break;
-		case ERR_IE_COMPREHENSION:
-			pc->para.cause = 96;
-			l3dss1_status_send(pc, 0, NULL);
-			break;
-		case ERR_IE_UNRECOGNIZED:
-			pc->para.cause = 99;
-			l3dss1_status_send(pc, 0, NULL);
-			break;
-		case ERR_IE_LENGTH:
-			pc->para.cause = 100;
-			l3dss1_status_send(pc, 0, NULL);
-			break;
-		case ERR_IE_SEQUENCE:
-		default:
-			break;
+	switch (ret) {
+	case 0:
+		break;
+	case ERR_IE_COMPREHENSION:
+		pc->para.cause = 96;
+		l3dss1_status_send(pc, 0, NULL);
+		break;
+	case ERR_IE_UNRECOGNIZED:
+		pc->para.cause = 99;
+		l3dss1_status_send(pc, 0, NULL);
+		break;
+	case ERR_IE_LENGTH:
+		pc->para.cause = 100;
+		l3dss1_status_send(pc, 0, NULL);
+		break;
+	case ERR_IE_SEQUENCE:
+	default:
+		break;
 	}
 }
 
@@ -878,14 +878,14 @@ l3dss1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) {
 				l3_debug(pc->st, "wrong chid %x", *p);
 			return (-3);
 		}
-		return(*p & 0x3);
+		return (*p & 0x3);
 	} else
-		return(-1);
+		return (-1);
 }
 
 static int
 l3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
-	u_char l, i=0;
+	u_char l, i = 0;
 	u_char *p;
 
 	p = skb->data;
@@ -894,13 +894,13 @@ l3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
 	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
 		p++;
 		l = *p++;
-		if (l>30)
-			return(1);
+		if (l > 30)
+			return (1);
 		if (l) {
 			pc->para.loc = *p++;
 			l--;
 		} else {
-			return(2);
+			return (2);
 		}
 		if (l && !(pc->para.loc & 0x80)) {
 			l--;
@@ -910,36 +910,36 @@ l3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
 			pc->para.cause = *p++;
 			l--;
 			if (!(pc->para.cause & 0x80))
-				return(3);
+				return (3);
 		} else
-			return(4);
-		while (l && (i<6)) {
+			return (4);
+		while (l && (i < 6)) {
 			pc->para.diag[i++] = *p++;
 			l--;
 		}
 	} else
-		return(-1);
-	return(0);
+		return (-1);
+	return (0);
 }
 
 static void
 l3dss1_msg_with_uus(struct l3_process *pc, u_char cmd)
 {
 	struct sk_buff *skb;
-	u_char tmp[16+40];
+	u_char tmp[16 + 40];
 	u_char *p = tmp;
 	int l;
 
 	MsgHead(p, pc->callref, cmd);
 
-        if (pc->prot.dss1.uus1_data[0])
-	 { *p++ = IE_USER_USER; /* UUS info element */
-           *p++ = strlen(pc->prot.dss1.uus1_data) + 1;
-           *p++ = 0x04; /* IA5 chars */
-           strcpy(p,pc->prot.dss1.uus1_data);
-           p += strlen(pc->prot.dss1.uus1_data);
-           pc->prot.dss1.uus1_data[0] = '\0';   
-         } 
+	if (pc->prot.dss1.uus1_data[0])
+	{ *p++ = IE_USER_USER; /* UUS info element */
+		*p++ = strlen(pc->prot.dss1.uus1_data) + 1;
+		*p++ = 0x04; /* IA5 chars */
+		strcpy(p, pc->prot.dss1.uus1_data);
+		p += strlen(pc->prot.dss1.uus1_data);
+		pc->prot.dss1.uus1_data[0] = '\0';
+	}
 
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
@@ -953,7 +953,7 @@ l3dss1_release_req(struct l3_process *pc, u_char pr, void *arg)
 {
 	StopAllL3Timer(pc);
 	newl3state(pc, 19);
-	if (!pc->prot.dss1.uus1_data[0]) 
+	if (!pc->prot.dss1.uus1_data[0])
 		l3dss1_message(pc, MT_RELEASE);
 	else
 		l3dss1_msg_with_uus(pc, MT_RELEASE);
@@ -966,9 +966,9 @@ l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
 	struct sk_buff *skb = arg;
 	int ret;
 
-	if ((ret = l3dss1_get_cause(pc, skb))>0) {
+	if ((ret = l3dss1_get_cause(pc, skb)) > 0) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "RELCMPL get_cause ret(%d)",ret);
+			l3_debug(pc->st, "RELCMPL get_cause ret(%d)", ret);
 	} else if (ret < 0)
 		pc->para.cause = NO_CAUSE;
 	StopAllL3Timer(pc);
@@ -980,7 +980,7 @@ l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
 #ifdef EXT_BEARER_CAPS
 
 static u_char *
-EncodeASyncParams(u_char * p, u_char si2)
+EncodeASyncParams(u_char *p, u_char si2)
 {				// 7c 06 88  90 21 42 00 bb
 
 	p[0] = 0;
@@ -1008,38 +1008,38 @@ EncodeASyncParams(u_char * p, u_char si2)
 		p[2] += 3;
 
 	switch (si2 & 0x07) {
-		case 0:
-			p[0] = 66;	// 1200 bit/s
+	case 0:
+		p[0] = 66;	// 1200 bit/s
 
-			break;
-		case 1:
-			p[0] = 88;	// 1200/75 bit/s
+		break;
+	case 1:
+		p[0] = 88;	// 1200/75 bit/s
 
-			break;
-		case 2:
-			p[0] = 87;	// 75/1200 bit/s
+		break;
+	case 2:
+		p[0] = 87;	// 75/1200 bit/s
 
-			break;
-		case 3:
-			p[0] = 67;	// 2400 bit/s
+		break;
+	case 3:
+		p[0] = 67;	// 2400 bit/s
 
-			break;
-		case 4:
-			p[0] = 69;	// 4800 bit/s
+		break;
+	case 4:
+		p[0] = 69;	// 4800 bit/s
 
-			break;
-		case 5:
-			p[0] = 72;	// 9600 bit/s
+		break;
+	case 5:
+		p[0] = 72;	// 9600 bit/s
 
-			break;
-		case 6:
-			p[0] = 73;	// 14400 bit/s
+		break;
+	case 6:
+		p[0] = 73;	// 14400 bit/s
 
-			break;
-		case 7:
-			p[0] = 75;	// 19200 bit/s
+		break;
+	case 7:
+		p[0] = 75;	// 19200 bit/s
 
-			break;
+		break;
 	}
 	return p + 3;
 }
@@ -1049,84 +1049,84 @@ EncodeSyncParams(u_char si2, u_char ai)
 {
 
 	switch (si2) {
-		case 0:
-			return ai + 2;	// 1200 bit/s
+	case 0:
+		return ai + 2;	// 1200 bit/s
 
-		case 1:
-			return ai + 24;		// 1200/75 bit/s
+	case 1:
+		return ai + 24;		// 1200/75 bit/s
 
-		case 2:
-			return ai + 23;		// 75/1200 bit/s
+	case 2:
+		return ai + 23;		// 75/1200 bit/s
 
-		case 3:
-			return ai + 3;	// 2400 bit/s
+	case 3:
+		return ai + 3;	// 2400 bit/s
 
-		case 4:
-			return ai + 5;	// 4800 bit/s
+	case 4:
+		return ai + 5;	// 4800 bit/s
 
-		case 5:
-			return ai + 8;	// 9600 bit/s
+	case 5:
+		return ai + 8;	// 9600 bit/s
 
-		case 6:
-			return ai + 9;	// 14400 bit/s
+	case 6:
+		return ai + 9;	// 14400 bit/s
 
-		case 7:
-			return ai + 11;		// 19200 bit/s
+	case 7:
+		return ai + 11;		// 19200 bit/s
 
-		case 8:
-			return ai + 14;		// 48000 bit/s
+	case 8:
+		return ai + 14;		// 48000 bit/s
 
-		case 9:
-			return ai + 15;		// 56000 bit/s
+	case 9:
+		return ai + 15;		// 56000 bit/s
 
-		case 15:
-			return ai + 40;		// negotiate bit/s
+	case 15:
+		return ai + 40;		// negotiate bit/s
 
-		default:
-			break;
+	default:
+		break;
 	}
 	return ai;
 }
 
 
 static u_char
-DecodeASyncParams(u_char si2, u_char * p)
+DecodeASyncParams(u_char si2, u_char *p)
 {
 	u_char info;
 
 	switch (p[5]) {
-		case 66:	// 1200 bit/s
+	case 66:	// 1200 bit/s
 
-			break;	// si2 don't change
+		break;	// si2 don't change
 
-		case 88:	// 1200/75 bit/s
+	case 88:	// 1200/75 bit/s
 
-			si2 += 1;
-			break;
-		case 87:	// 75/1200 bit/s
+		si2 += 1;
+		break;
+	case 87:	// 75/1200 bit/s
 
-			si2 += 2;
-			break;
-		case 67:	// 2400 bit/s
+		si2 += 2;
+		break;
+	case 67:	// 2400 bit/s
 
-			si2 += 3;
-			break;
-		case 69:	// 4800 bit/s
+		si2 += 3;
+		break;
+	case 69:	// 4800 bit/s
 
-			si2 += 4;
-			break;
-		case 72:	// 9600 bit/s
+		si2 += 4;
+		break;
+	case 72:	// 9600 bit/s
 
-			si2 += 5;
-			break;
-		case 73:	// 14400 bit/s
+		si2 += 5;
+		break;
+	case 73:	// 14400 bit/s
 
-			si2 += 6;
-			break;
-		case 75:	// 19200 bit/s
+		si2 += 6;
+		break;
+	case 75:	// 19200 bit/s
 
-			si2 += 7;
-			break;
+		si2 += 7;
+		break;
 	}
 
 	info = p[7] & 0x7f;
@@ -1151,39 +1151,39 @@ DecodeSyncParams(u_char si2, u_char info)
 {
 	info &= 0x7f;
 	switch (info) {
-		case 40:	// bit/s negotiation failed  ai := 165 not 175!
+	case 40:	// bit/s negotiation failed  ai := 165 not 175!
 
-			return si2 + 15;
-		case 15:	// 56000 bit/s failed, ai := 0 not 169 !
+		return si2 + 15;
+	case 15:	// 56000 bit/s failed, ai := 0 not 169 !
 
-			return si2 + 9;
-		case 14:	// 48000 bit/s
+		return si2 + 9;
+	case 14:	// 48000 bit/s
 
-			return si2 + 8;
-		case 11:	// 19200 bit/s
+		return si2 + 8;
+	case 11:	// 19200 bit/s
 
-			return si2 + 7;
-		case 9:	// 14400 bit/s
+		return si2 + 7;
+	case 9:	// 14400 bit/s
 
-			return si2 + 6;
-		case 8:	// 9600  bit/s
+		return si2 + 6;
+	case 8:	// 9600  bit/s
 
-			return si2 + 5;
-		case 5:	// 4800  bit/s
+		return si2 + 5;
+	case 5:	// 4800  bit/s
 
-			return si2 + 4;
-		case 3:	// 2400  bit/s
+		return si2 + 4;
+	case 3:	// 2400  bit/s
 
-			return si2 + 3;
-		case 23:	// 75/1200 bit/s
+		return si2 + 3;
+	case 23:	// 75/1200 bit/s
 
-			return si2 + 2;
-		case 24:	// 1200/75 bit/s
+		return si2 + 2;
+	case 24:	// 1200/75 bit/s
 
-			return si2 + 1;
-		default:	// 1200 bit/s
+		return si2 + 1;
+	default:	// 1200 bit/s
 
-			return si2;
+		return si2;
 	}
 }
 
@@ -1194,20 +1194,20 @@ DecodeSI2(struct sk_buff *skb)
 
 	if ((p = findie(skb->data, skb->len, 0x7c, 0))) {
 		switch (p[4] & 0x0f) {
-			case 0x01:
-				if (p[1] == 0x04)	// sync. Bitratenadaption
+		case 0x01:
+			if (p[1] == 0x04)	// sync. Bitratenadaption
 
-					return DecodeSyncParams(160, p[5]);	// V.110/X.30
+				return DecodeSyncParams(160, p[5]);	// V.110/X.30
 
-				else if (p[1] == 0x06)	// async. Bitratenadaption
+			else if (p[1] == 0x06)	// async. Bitratenadaption
 
-					return DecodeASyncParams(192, p);	// V.110/X.30
+				return DecodeASyncParams(192, p);	// V.110/X.30
 
-				break;
-			case 0x08:	// if (p[5] == 0x02) // sync. Bitratenadaption
-				if (p[1] > 3) 
-					return DecodeSyncParams(176, p[5]);	// V.120
-				break;
+			break;
+		case 0x08:	// if (p[5] == 0x02) // sync. Bitratenadaption
+			if (p[1] > 3)
+				return DecodeSyncParams(176, p[5]);	// V.120
+			break;
 		}
 	}
 	return 0;
@@ -1225,7 +1225,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 	u_char *p = tmp;
 	u_char channel = 0;
 
-        u_char send_keypad;
+	u_char send_keypad;
 	u_char screen = 0x80;
 	u_char *teln;
 	u_char *msn;
@@ -1237,7 +1237,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 
 	teln = pc->para.setup.phone;
 #ifndef CONFIG_HISAX_NO_KEYPAD
-        send_keypad = (strchr(teln,'*') || strchr(teln,'#')) ? 1 : 0; 
+	send_keypad = (strchr(teln, '*') || strchr(teln, '#')) ? 1 : 0;
 #else
 	send_keypad = 0;
 #endif
@@ -1272,7 +1272,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 		while (*teln)
 			*p++ = (*teln++) & 0x7F;
 	}
-	  
+
 	/*
 	 * What about info2? Mapping to High-Layer-Compatibility?
 	 */
@@ -1280,27 +1280,27 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 		/* parse number for special things */
 		if (!isdigit(*teln)) {
 			switch (0x5f & *teln) {
-				case 'C':
-					channel = 0x08;
-				case 'P':
-					channel |= 0x80;
-					teln++;
-					if (*teln == '1')
-						channel |= 0x01;
-					else
-						channel |= 0x02;
-					break;
-				case 'R':
-					screen = 0xA0;
-					break;
-				case 'D':
-					screen = 0x80;
-					break;
-				
-			        default:
-					if (pc->debug & L3_DEB_WARN)
-						l3_debug(pc->st, "Wrong MSN Code");
-					break;
+			case 'C':
+				channel = 0x08;
+			case 'P':
+				channel |= 0x80;
+				teln++;
+				if (*teln == '1')
+					channel |= 0x01;
+				else
+					channel |= 0x02;
+				break;
+			case 'R':
+				screen = 0xA0;
+				break;
+			case 'D':
+				screen = 0x80;
+				break;
+
+			default:
+				if (pc->debug & L3_DEB_WARN)
+					l3_debug(pc->st, "Wrong MSN Code");
+				break;
 			}
 			teln++;
 		}
@@ -1350,15 +1350,15 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 		} else
 			sp++;
 	}
-	
-        if (!send_keypad) {      
+
+	if (!send_keypad) {
 		*p++ = IE_CALLED_PN;
 		*p++ = strlen(teln) + 1;
 		/* Classify as AnyPref. */
 		*p++ = 0x81;		/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
 		while (*teln)
 			*p++ = *teln++ & 0x7f;
-		
+
 		if (sub) {
 			*sub++ = '.';
 			*p++ = IE_CALLED_SUB;
@@ -1368,7 +1368,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 			while (*sub)
 				*p++ = *sub++ & 0x7f;
 		}
-        }
+	}
 #ifdef EXT_BEARER_CAPS
 	if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {	// sync. Bitratenadaption, V.110/X.30
 
@@ -1397,7 +1397,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 		p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
 #ifndef CONFIG_HISAX_NO_LLC
 	} else {
-	  switch (pc->para.setup.si1) {
+		switch (pc->para.setup.si1) {
 		case 1:	                /* Telephony                                */
 			*p++ = IE_LLC;
 			*p++ = 0x3;	/* Length                                   */
@@ -1413,7 +1413,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 			*p++ = 0x88;	/* Coding Std. CCITT, unrestr. dig. Inform. */
 			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */
 			break;
-	  }
+		}
 #endif
 	}
 #endif
@@ -1521,7 +1521,7 @@ l3dss1_disconnect(struct l3_process *pc, u_char pr, void *arg)
 			cause = 96;
 		else if (ret > 0)
 			cause = 100;
-	} 
+	}
 	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
 		l3dss1_parse_facility(pc->st, pc, pc->callref, p);
 	ret = check_infoelements(pc, skb, ie_DISCONNECT);
@@ -1533,10 +1533,10 @@ l3dss1_disconnect(struct l3_process *pc, u_char pr, void *arg)
 	newl3state(pc, 12);
 	if (cause)
 		newl3state(pc, 19);
-       	if (11 != ret)
+	if (11 != ret)
 		pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
-       	else if (!cause)
-		   l3dss1_release_req(pc, pr, NULL);
+	else if (!cause)
+		l3dss1_release_req(pc, pr, NULL);
 	if (cause) {
 		l3dss1_message_cause(pc, MT_RELEASE, cause);
 		L3AddTimer(&pc->timer, T308, CC_T308_1);
@@ -1602,56 +1602,56 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
 		else {
 			pc->para.setup.si2 = 0;
 			switch (p[2] & 0x7f) {
-				case 0x00: /* Speech */
-				case 0x10: /* 3.1 Khz audio */
-					pc->para.setup.si1 = 1;
-					break;
-				case 0x08: /* Unrestricted digital information */
-					pc->para.setup.si1 = 7;
+			case 0x00: /* Speech */
+			case 0x10: /* 3.1 Khz audio */
+				pc->para.setup.si1 = 1;
+				break;
+			case 0x08: /* Unrestricted digital information */
+				pc->para.setup.si1 = 7;
 /* JIM, 05.11.97 I wanna set service indicator 2 */
 #ifdef EXT_BEARER_CAPS
-					pc->para.setup.si2 = DecodeSI2(skb);
+				pc->para.setup.si2 = DecodeSI2(skb);
 #endif
-					break;
-				case 0x09: /* Restricted digital information */
-					pc->para.setup.si1 = 2;
-					break;
-				case 0x11:
-					/* Unrestr. digital information  with 
-					 * tones/announcements ( or 7 kHz audio
-					 */
-					pc->para.setup.si1 = 3;
-					break;
-				case 0x18: /* Video */
-					pc->para.setup.si1 = 4;
-					break;
-				default:
-					err = 2;
-					break;
+				break;
+			case 0x09: /* Restricted digital information */
+				pc->para.setup.si1 = 2;
+				break;
+			case 0x11:
+				/* Unrestr. digital information  with
+				 * tones/announcements ( or 7 kHz audio
+				 */
+				pc->para.setup.si1 = 3;
+				break;
+			case 0x18: /* Video */
+				pc->para.setup.si1 = 4;
+				break;
+			default:
+				err = 2;
+				break;
 			}
 			switch (p[3] & 0x7f) {
-				case 0x40: /* packed mode */
-					pc->para.setup.si1 = 8;
-					break;
-				case 0x10: /* 64 kbit */
-				case 0x11: /* 2*64 kbit */
-				case 0x13: /* 384 kbit */
-				case 0x15: /* 1536 kbit */
-				case 0x17: /* 1920 kbit */
-					pc->para.moderate = p[3] & 0x7f;
-					break;
-				default:
-					err = 3;
-					break;
+			case 0x40: /* packed mode */
+				pc->para.setup.si1 = 8;
+				break;
+			case 0x10: /* 64 kbit */
+			case 0x11: /* 2*64 kbit */
+			case 0x13: /* 384 kbit */
+			case 0x15: /* 1536 kbit */
+			case 0x17: /* 1920 kbit */
+				pc->para.moderate = p[3] & 0x7f;
+				break;
+			default:
+				err = 3;
+				break;
 			}
 		}
 		if (pc->debug & L3_DEB_SI)
 			l3_debug(pc->st, "SI=%d, AI=%d",
-				pc->para.setup.si1, pc->para.setup.si2);
+				 pc->para.setup.si1, pc->para.setup.si2);
 		if (err) {
 			if (pc->debug & L3_DEB_WARN)
 				l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)",
-					p[1], p[2], p[3]);
+					 p[1], p[2], p[3]);
 			pc->para.cause = 100;
 			l3dss1_msg_without_setup(pc, pr, NULL);
 			return;
@@ -1672,17 +1672,17 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
 			if ((3 == id) && (0x10 == pc->para.moderate)) {
 				if (pc->debug & L3_DEB_WARN)
 					l3_debug(pc->st, "setup with wrong chid %x",
-						id);
+						 id);
 				pc->para.cause = 100;
 				l3dss1_msg_without_setup(pc, pr, NULL);
 				return;
 			}
 			bcfound++;
-		} else 
-                   { if (pc->debug & L3_DEB_WARN)
-			 l3_debug(pc->st, "setup without bchannel, call waiting");
-                     bcfound++;
-                   } 
+		} else
+		{ if (pc->debug & L3_DEB_WARN)
+				l3_debug(pc->st, "setup without bchannel, call waiting");
+			bcfound++;
+		}
 	} else {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "setup with wrong chid ret %d", id);
@@ -1757,7 +1757,7 @@ static void
 l3dss1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb;
-	u_char tmp[16+40];
+	u_char tmp[16 + 40];
 	u_char *p = tmp;
 	int l;
 	u_char cause = 16;
@@ -1774,14 +1774,14 @@ l3dss1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
 	*p++ = 0x80;
 	*p++ = cause | 0x80;
 
-        if (pc->prot.dss1.uus1_data[0])
-	 { *p++ = IE_USER_USER; /* UUS info element */
-           *p++ = strlen(pc->prot.dss1.uus1_data) + 1;
-           *p++ = 0x04; /* IA5 chars */
-           strcpy(p,pc->prot.dss1.uus1_data);
-           p += strlen(pc->prot.dss1.uus1_data);
-           pc->prot.dss1.uus1_data[0] = '\0';   
-         } 
+	if (pc->prot.dss1.uus1_data[0])
+	{ *p++ = IE_USER_USER; /* UUS info element */
+		*p++ = strlen(pc->prot.dss1.uus1_data) + 1;
+		*p++ = 0x04; /* IA5 chars */
+		strcpy(p, pc->prot.dss1.uus1_data);
+		p += strlen(pc->prot.dss1.uus1_data);
+		pc->prot.dss1.uus1_data[0] = '\0';
+	}
 
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
@@ -1796,12 +1796,12 @@ static void
 l3dss1_setup_rsp(struct l3_process *pc, u_char pr,
 		 void *arg)
 {
-        if (!pc->para.bchannel) 
-	 { if (pc->debug & L3_DEB_WARN)
-	       l3_debug(pc->st, "D-chan connect for waiting call");
-           l3dss1_disconnect_req(pc, pr, arg);
-           return;
-         }
+	if (!pc->para.bchannel)
+	{ if (pc->debug & L3_DEB_WARN)
+			l3_debug(pc->st, "D-chan connect for waiting call");
+		l3dss1_disconnect_req(pc, pr, arg);
+		return;
+	}
 	newl3state(pc, 8);
 	l3dss1_message(pc, MT_CONNECT);
 	L3DelTimer(&pc->timer);
@@ -1860,26 +1860,26 @@ l3dss1_release(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb = arg;
 	u_char *p;
-	int ret, cause=0;
+	int ret, cause = 0;
 
 	StopAllL3Timer(pc);
-	if ((ret = l3dss1_get_cause(pc, skb))>0) {
+	if ((ret = l3dss1_get_cause(pc, skb)) > 0) {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "REL get_cause ret(%d)", ret);
-	} else if (ret<0)
+	} else if (ret < 0)
 		pc->para.cause = NO_CAUSE;
 	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
 		l3dss1_parse_facility(pc->st, pc, pc->callref, p);
 	}
-	if ((ret<0) && (pc->state != 11))
+	if ((ret < 0) && (pc->state != 11))
 		cause = 96;
-	else if (ret>0)
+	else if (ret > 0)
 		cause = 100;
 	ret = check_infoelements(pc, skb, ie_RELEASE);
 	if (ERR_IE_COMPREHENSION == ret)
 		cause = 96;
 	else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause))
-		cause = 99;  
+		cause = 99;
 	if (cause)
 		l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, cause);
 	else
@@ -1894,10 +1894,10 @@ l3dss1_alert_req(struct l3_process *pc, u_char pr,
 		 void *arg)
 {
 	newl3state(pc, 7);
-	if (!pc->prot.dss1.uus1_data[0]) 
+	if (!pc->prot.dss1.uus1_data[0])
 		l3dss1_message(pc, MT_ALERTING);
 	else
-		l3dss1_msg_with_uus(pc, MT_ALERTING); 
+		l3dss1_msg_with_uus(pc, MT_ALERTING);
 }
 
 static void
@@ -1906,12 +1906,12 @@ l3dss1_proceed_req(struct l3_process *pc, u_char pr,
 {
 	newl3state(pc, 9);
 	l3dss1_message(pc, MT_CALL_PROCEEDING);
-	pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc); 
+	pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc);
 }
 
 static void
 l3dss1_setup_ack_req(struct l3_process *pc, u_char pr,
-		   void *arg)
+		     void *arg)
 {
 	newl3state(pc, 25);
 	L3DelTimer(&pc->timer);
@@ -1925,22 +1925,22 @@ l3dss1_setup_ack_req(struct l3_process *pc, u_char pr,
 static void
 l3dss1_deliver_display(struct l3_process *pc, int pr, u_char *infp)
 {       u_char len;
-        isdn_ctrl ic; 
+	isdn_ctrl ic;
 	struct IsdnCardState *cs;
-        char *p; 
+	char *p;
 
-        if (*infp++ != IE_DISPLAY) return;
-        if ((len = *infp++) > 80) return; /* total length <= 82 */
+	if (*infp++ != IE_DISPLAY) return;
+	if ((len = *infp++) > 80) return; /* total length <= 82 */
 	if (!pc->chan) return;
 
-	p = ic.parm.display; 
-        while (len--)
-	  *p++ = *infp++;
+	p = ic.parm.display;
+	while (len--)
+		*p++ = *infp++;
 	*p = '\0';
 	ic.command = ISDN_STAT_DISPLAY;
 	cs = pc->st->l1.hardware;
 	ic.driver = cs->myid;
-	ic.arg = pc->chan->chan; 
+	ic.arg = pc->chan->chan;
 	cs->iif.statcallb(&ic);
 } /* l3dss1_deliver_display */
 
@@ -1958,37 +1958,37 @@ l3dss1_progress(struct l3_process *pc, u_char pr, void *arg)
 			pc->para.cause = 100;
 		} else if (!(p[2] & 0x70)) {
 			switch (p[2]) {
-				case 0x80:
+			case 0x80:
+			case 0x81:
+			case 0x82:
+			case 0x84:
+			case 0x85:
+			case 0x87:
+			case 0x8a:
+				switch (p[3]) {
 				case 0x81:
 				case 0x82:
+				case 0x83:
 				case 0x84:
-				case 0x85:
-				case 0x87:
-				case 0x8a:
-					switch (p[3]) {
-						case 0x81:
-						case 0x82:
-						case 0x83:
-						case 0x84:
-						case 0x88:
-							break;
-						default:
-							err = 2;
-							pc->para.cause = 100;
-							break;
-					}
+				case 0x88:
 					break;
 				default:
-					err = 3;
+					err = 2;
 					pc->para.cause = 100;
 					break;
+				}
+				break;
+			default:
+				err = 3;
+				pc->para.cause = 100;
+				break;
 			}
 		}
 	} else {
 		pc->para.cause = 96;
 		err = 4;
 	}
-	if (err) {	
+	if (err) {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "progress error %d", err);
 		l3dss1_status_send(pc, pr, NULL);
@@ -2015,21 +2015,21 @@ l3dss1_notify(struct l3_process *pc, u_char pr, void *arg)
 			pc->para.cause = 100;
 		} else {
 			switch (p[2]) {
-				case 0x80:
-				case 0x81:
-				case 0x82:
-					break;
-				default:
-					pc->para.cause = 100;
-					err = 2;
-					break;
+			case 0x80:
+			case 0x81:
+			case 0x82:
+				break;
+			default:
+				pc->para.cause = 100;
+				err = 2;
+				break;
 			}
 		}
 	} else {
 		pc->para.cause = 96;
 		err = 3;
 	}
-	if (err) {	
+	if (err) {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "notify error %d", err);
 		l3dss1_status_send(pc, pr, NULL);
@@ -2052,7 +2052,7 @@ l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg)
 	ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);
 	l3dss1_std_ie_err(pc, ret);
 	pc->para.cause = 30; /* response to STATUS_ENQUIRY */
-        l3dss1_status_send(pc, pr, NULL);
+	l3dss1_status_send(pc, pr, NULL);
 }
 
 static void
@@ -2086,68 +2086,68 @@ static void l3dss1_redir_req(struct l3_process *pc, u_char pr, void *arg)
 	struct sk_buff *skb;
 	u_char tmp[128];
 	u_char *p = tmp;
-        u_char *subp;
-        u_char len_phone = 0;
-        u_char len_sub = 0;
-	int l; 
-
-
-        strcpy(pc->prot.dss1.uus1_data,pc->chan->setup.eazmsn); /* copy uus element if available */
-        if (!pc->chan->setup.phone[0])
-          { pc->para.cause = -1;
-            l3dss1_disconnect_req(pc,pr,arg); /* disconnect immediately */
-            return;
-          } /* only uus */
- 
-        if (pc->prot.dss1.invoke_id) 
-          free_invoke_id(pc->st,pc->prot.dss1.invoke_id);
- 
-        if (!(pc->prot.dss1.invoke_id = new_invoke_id(pc->st))) 
-          return;
-
-        MsgHead(p, pc->callref, MT_FACILITY);
-
-        for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */
-        if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */ 
+	u_char *subp;
+	u_char len_phone = 0;
+	u_char len_sub = 0;
+	int l;
+
+
+	strcpy(pc->prot.dss1.uus1_data, pc->chan->setup.eazmsn); /* copy uus element if available */
+	if (!pc->chan->setup.phone[0])
+	{ pc->para.cause = -1;
+		l3dss1_disconnect_req(pc, pr, arg); /* disconnect immediately */
+		return;
+	} /* only uus */
+
+	if (pc->prot.dss1.invoke_id)
+		free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
+
+	if (!(pc->prot.dss1.invoke_id = new_invoke_id(pc->st)))
+		return;
+
+	MsgHead(p, pc->callref, MT_FACILITY);
+
+	for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */
+	if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */
 
 	*p++ = 0x1c;   /* Facility info element */
-        *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */
-        *p++ = 0x91;  /* remote operations protocol */
-        *p++ = 0xa1;  /* invoke component */
-	  
-        *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */
-        *p++ = 0x02;  /* invoke id tag, integer */
+	*p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */
+	*p++ = 0x91;  /* remote operations protocol */
+	*p++ = 0xa1;  /* invoke component */
+
+	*p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */
+	*p++ = 0x02;  /* invoke id tag, integer */
 	*p++ = 0x01;  /* length */
-        *p++ = pc->prot.dss1.invoke_id;  /* invoke id */ 
-        *p++ = 0x02;  /* operation value tag, integer */
+	*p++ = pc->prot.dss1.invoke_id;  /* invoke id */
+	*p++ = 0x02;  /* operation value tag, integer */
 	*p++ = 0x01;  /* length */
-        *p++ = 0x0D;  /* Call Deflect */
-	  
-        *p++ = 0x30;  /* sequence phone number */
-        *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */
-	  
-        *p++ = 0x30;  /* Deflected to UserNumber */
-        *p++ = len_phone+2+len_sub; /* length */
-        *p++ = 0x80; /* NumberDigits */
+	*p++ = 0x0D;  /* Call Deflect */
+
+	*p++ = 0x30;  /* sequence phone number */
+	*p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */
+
+	*p++ = 0x30;  /* Deflected to UserNumber */
+	*p++ = len_phone + 2 + len_sub; /* length */
+	*p++ = 0x80; /* NumberDigits */
 	*p++ = len_phone; /* length */
-        for (l = 0; l < len_phone; l++)
-	 *p++ = pc->chan->setup.phone[l];
+	for (l = 0; l < len_phone; l++)
+		*p++ = pc->chan->setup.phone[l];
 
-        if (len_sub)
-	  { *p++ = 0x04; /* called party subaddress */
-            *p++ = len_sub - 2;
-            while (*subp) *p++ = *subp++;
-          }
+	if (len_sub)
+	{ *p++ = 0x04; /* called party subaddress */
+		*p++ = len_sub - 2;
+		while (*subp) *p++ = *subp++;
+	}
 
-        *p++ = 0x01; /* screening identifier */
-        *p++ = 0x01;
-        *p++ = pc->chan->setup.screen;
+	*p++ = 0x01; /* screening identifier */
+	*p++ = 0x01;
+	*p++ = pc->chan->setup.screen;
 
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l))) return;
 	memcpy(skb_put(skb, l), tmp, l);
 
-        l3_msg(pc->st, DL_DATA | REQUEST, skb);
+	l3_msg(pc->st, DL_DATA | REQUEST, skb);
 } /* l3dss1_redir_req */
 
 /********************************************/
@@ -2155,8 +2155,8 @@ static void l3dss1_redir_req(struct l3_process *pc, u_char pr, void *arg)
 /********************************************/
 static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg)
 {
-  l3dss1_proceed_req(pc,pr,arg);
-  l3dss1_redir_req(pc,pr,arg);
+	l3dss1_proceed_req(pc, pr, arg);
+	l3dss1_redir_req(pc, pr, arg);
 } /* l3dss1_redir_req_early */
 
 /***********************************************/
@@ -2166,108 +2166,108 @@ static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg)
 /***********************************************/
 static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic)
 { u_char id;
-  u_char temp[265];
-  u_char *p = temp;
-  int i, l, proc_len; 
-  struct sk_buff *skb;
-  struct l3_process *pc = NULL;
-
-  switch (ic->arg)
-   { case DSS1_CMD_INVOKE:
-       if (ic->parm.dss1_io.datalen < 0) return(-2); /* invalid parameter */ 
-
-       for (proc_len = 1, i = ic->parm.dss1_io.proc >> 8; i; i++) 
-         i = i >> 8; /* add one byte */    
-       l = ic->parm.dss1_io.datalen + proc_len + 8; /* length excluding ie header */
-       if (l > 255) 
-         return(-2); /* too long */
-
-       if (!(id = new_invoke_id(st))) 
-         return(0); /* first get a invoke id -> return if no available */
-       
-       i = -1; 
-       MsgHead(p, i, MT_FACILITY); /* build message head */
-       *p++ = 0x1C; /* Facility IE */
-       *p++ = l; /* length of ie */
-       *p++ = 0x91; /* remote operations */
-       *p++ = 0xA1; /* invoke */
-       *p++ = l - 3; /* length of invoke */
-       *p++ = 0x02; /* invoke id tag */
-       *p++ = 0x01; /* length is 1 */
-       *p++ = id; /* invoke id */
-       *p++ = 0x02; /* operation */
-       *p++ = proc_len; /* length of operation */
-       
-       for (i = proc_len; i; i--)
-         *p++ = (ic->parm.dss1_io.proc >> (i-1)) & 0xFF;
-       memcpy(p, ic->parm.dss1_io.data, ic->parm.dss1_io.datalen); /* copy data */
-       l = (p - temp) + ic->parm.dss1_io.datalen; /* total length */         
-
-       if (ic->parm.dss1_io.timeout > 0)
-        if (!(pc = dss1_new_l3_process(st, -1)))
-          { free_invoke_id(st, id);
-            return(-2);
-          } 
-       pc->prot.dss1.ll_id = ic->parm.dss1_io.ll_id; /* remember id */ 
-       pc->prot.dss1.proc = ic->parm.dss1_io.proc; /* and procedure */
-
-       if (!(skb = l3_alloc_skb(l))) 
-         { free_invoke_id(st, id);
-           if (pc) dss1_release_l3_process(pc);
-           return(-2);
-         }
-       memcpy(skb_put(skb, l), temp, l);
-       
-       if (pc)
-        { pc->prot.dss1.invoke_id = id; /* remember id */
-          L3AddTimer(&pc->timer, ic->parm.dss1_io.timeout, CC_TDSS1_IO | REQUEST);
-        }
-       
-       l3_msg(st, DL_DATA | REQUEST, skb);
-       ic->parm.dss1_io.hl_id = id; /* return id */
-       return(0);
-
-     case DSS1_CMD_INVOKE_ABORT:
-       if ((pc = l3dss1_search_dummy_proc(st, ic->parm.dss1_io.hl_id)))
-	{ L3DelTimer(&pc->timer); /* remove timer */
-          dss1_release_l3_process(pc);
-          return(0); 
-        } 
-       else
-	{ l3_debug(st, "l3dss1_cmd_global abort unknown id");
-          return(-2);
-        } 
-       break;
-    
-     default: 
-       l3_debug(st, "l3dss1_cmd_global unknown cmd 0x%lx", ic->arg);
-       return(-1);  
-   } /* switch ic-> arg */
-  return(-1);
+	u_char temp[265];
+	u_char *p = temp;
+	int i, l, proc_len;
+	struct sk_buff *skb;
+	struct l3_process *pc = NULL;
+
+	switch (ic->arg)
+	{ case DSS1_CMD_INVOKE:
+			if (ic->parm.dss1_io.datalen < 0) return (-2); /* invalid parameter */
+
+			for (proc_len = 1, i = ic->parm.dss1_io.proc >> 8; i; i++)
+				i = i >> 8; /* add one byte */
+			l = ic->parm.dss1_io.datalen + proc_len + 8; /* length excluding ie header */
+			if (l > 255)
+				return (-2); /* too long */
+
+			if (!(id = new_invoke_id(st)))
+				return (0); /* first get a invoke id -> return if no available */
+
+			i = -1;
+			MsgHead(p, i, MT_FACILITY); /* build message head */
+			*p++ = 0x1C; /* Facility IE */
+			*p++ = l; /* length of ie */
+			*p++ = 0x91; /* remote operations */
+			*p++ = 0xA1; /* invoke */
+			*p++ = l - 3; /* length of invoke */
+			*p++ = 0x02; /* invoke id tag */
+			*p++ = 0x01; /* length is 1 */
+			*p++ = id; /* invoke id */
+			*p++ = 0x02; /* operation */
+			*p++ = proc_len; /* length of operation */
+
+			for (i = proc_len; i; i--)
+				*p++ = (ic->parm.dss1_io.proc >> (i - 1)) & 0xFF;
+			memcpy(p, ic->parm.dss1_io.data, ic->parm.dss1_io.datalen); /* copy data */
+			l = (p - temp) + ic->parm.dss1_io.datalen; /* total length */
+
+			if (ic->parm.dss1_io.timeout > 0)
+				if (!(pc = dss1_new_l3_process(st, -1)))
+				{ free_invoke_id(st, id);
+					return (-2);
+				}
+			pc->prot.dss1.ll_id = ic->parm.dss1_io.ll_id; /* remember id */
+			pc->prot.dss1.proc = ic->parm.dss1_io.proc; /* and procedure */
+
+			if (!(skb = l3_alloc_skb(l)))
+			{ free_invoke_id(st, id);
+				if (pc) dss1_release_l3_process(pc);
+				return (-2);
+			}
+			memcpy(skb_put(skb, l), temp, l);
+
+			if (pc)
+			{ pc->prot.dss1.invoke_id = id; /* remember id */
+				L3AddTimer(&pc->timer, ic->parm.dss1_io.timeout, CC_TDSS1_IO | REQUEST);
+			}
+
+			l3_msg(st, DL_DATA | REQUEST, skb);
+			ic->parm.dss1_io.hl_id = id; /* return id */
+			return (0);
+
+	case DSS1_CMD_INVOKE_ABORT:
+		if ((pc = l3dss1_search_dummy_proc(st, ic->parm.dss1_io.hl_id)))
+		{ L3DelTimer(&pc->timer); /* remove timer */
+			dss1_release_l3_process(pc);
+			return (0);
+		}
+		else
+		{ l3_debug(st, "l3dss1_cmd_global abort unknown id");
+			return (-2);
+		}
+		break;
+
+	default:
+		l3_debug(st, "l3dss1_cmd_global unknown cmd 0x%lx", ic->arg);
+		return (-1);
+	} /* switch ic-> arg */
+	return (-1);
 } /* l3dss1_cmd_global */
 
-static void 
+static void
 l3dss1_io_timer(struct l3_process *pc)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs = pc->st->l1.hardware;
+	struct IsdnCardState *cs = pc->st->l1.hardware;
 
-  L3DelTimer(&pc->timer); /* remove timer */
+	L3DelTimer(&pc->timer); /* remove timer */
 
-  ic.driver = cs->myid;
-  ic.command = ISDN_STAT_PROT;
-  ic.arg = DSS1_STAT_INVOKE_ERR;
-  ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
-  ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
-  ic.parm.dss1_io.proc = pc->prot.dss1.proc;
-  ic.parm.dss1_io.timeout= -1;
-  ic.parm.dss1_io.datalen = 0;
-  ic.parm.dss1_io.data = NULL;
-  free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
-  pc->prot.dss1.invoke_id = 0; /* reset id */
+	ic.driver = cs->myid;
+	ic.command = ISDN_STAT_PROT;
+	ic.arg = DSS1_STAT_INVOKE_ERR;
+	ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
+	ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
+	ic.parm.dss1_io.proc = pc->prot.dss1.proc;
+	ic.parm.dss1_io.timeout = -1;
+	ic.parm.dss1_io.datalen = 0;
+	ic.parm.dss1_io.data = NULL;
+	free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
+	pc->prot.dss1.invoke_id = 0; /* reset id */
 
-  cs->iif.statcallb(&ic);
+	cs->iif.statcallb(&ic);
 
-  dss1_release_l3_process(pc); 
+	dss1_release_l3_process(pc);
 } /* l3dss1_io_timer */
 
 static void
@@ -2437,12 +2437,12 @@ l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
 {
 	u_char *p;
 	struct sk_buff *skb = arg;
-	int ret; 
+	int ret;
 	u_char cause = 0, callState = 0;
-	
+
 	if ((ret = l3dss1_get_cause(pc, skb))) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "STATUS get_cause ret(%d)",ret);
+			l3_debug(pc->st, "STATUS get_cause ret(%d)", ret);
 		if (ret < 0)
 			cause = 96;
 		else if (ret > 0)
@@ -2467,9 +2467,9 @@ l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
 	}
 	if (cause) {
 		u_char tmp;
-		
+
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "STATUS error(%d/%d)",ret,cause);
+			l3_debug(pc->st, "STATUS error(%d/%d)", ret, cause);
 		tmp = pc->para.cause;
 		pc->para.cause = cause;
 		l3dss1_status_send(pc, 0, NULL);
@@ -2495,10 +2495,10 @@ l3dss1_facility(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb = arg;
 	int ret;
-	
+
 	ret = check_infoelements(pc, skb, ie_FACILITY);
 	l3dss1_std_ie_err(pc, ret);
- 	  {
+	{
 		u_char *p;
 		if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
 			l3dss1_parse_facility(pc->st, pc, pc->callref, p);
@@ -2547,7 +2547,7 @@ l3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg)
 	/* We don't handle suspend_ack for IE errors now */
 	if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "SUSPACK check ie(%d)",ret);
+			l3_debug(pc->st, "SUSPACK check ie(%d)", ret);
 	dss1_release_l3_process(pc);
 }
 
@@ -2559,8 +2559,8 @@ l3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg)
 
 	if ((ret = l3dss1_get_cause(pc, skb))) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)",ret);
-		if (ret < 0) 
+			l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)", ret);
+		if (ret < 0)
 			pc->para.cause = 96;
 		else
 			pc->para.cause = 100;
@@ -2651,8 +2651,8 @@ l3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg)
 
 	if ((ret = l3dss1_get_cause(pc, skb))) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "RES_REJ get_cause ret(%d)",ret);
-		if (ret < 0) 
+			l3_debug(pc->st, "RES_REJ get_cause ret(%d)", ret);
+		if (ret < 0)
 			pc->para.cause = 96;
 		else
 			pc->para.cause = 100;
@@ -2729,36 +2729,36 @@ l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3dss1_dl_reset(struct l3_process *pc, u_char pr, void *arg)
 {
-        pc->para.cause = 0x29;          /* Temporary failure */
-        pc->para.loc = 0;
-        l3dss1_disconnect_req(pc, pr, NULL);
-        pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
+	pc->para.cause = 0x29;          /* Temporary failure */
+	pc->para.loc = 0;
+	l3dss1_disconnect_req(pc, pr, NULL);
+	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
 }
 
 static void
 l3dss1_dl_release(struct l3_process *pc, u_char pr, void *arg)
 {
-        newl3state(pc, 0);
-        pc->para.cause = 0x1b;          /* Destination out of order */
-        pc->para.loc = 0;
-        pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
-        release_l3_process(pc);
+	newl3state(pc, 0);
+	pc->para.cause = 0x1b;          /* Destination out of order */
+	pc->para.loc = 0;
+	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
+	release_l3_process(pc);
 }
 
 static void
 l3dss1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg)
 {
-        L3DelTimer(&pc->timer);
-        L3AddTimer(&pc->timer, T309, CC_T309);
-        l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL);
+	L3DelTimer(&pc->timer);
+	L3AddTimer(&pc->timer, T309, CC_T309);
+	l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL);
 }
- 
+
 static void
 l3dss1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg)
 {
 	L3DelTimer(&pc->timer);
- 
- 	pc->para.cause = 0x1F; /* normal, unspecified */
+
+	pc->para.cause = 0x1F; /* normal, unspecified */
 	l3dss1_status_send(pc, 0, NULL);
 }
 
@@ -2791,12 +2791,12 @@ static struct stateentry downstatelist[] =
 	 CC_SETUP | RESPONSE, l3dss1_setup_rsp},
 	{SBIT(10),
 	 CC_SUSPEND | REQUEST, l3dss1_suspend_req},
-        {SBIT(7) | SBIT(9) | SBIT(25),
-         CC_REDIR | REQUEST, l3dss1_redir_req},
-        {SBIT(6),
-         CC_REDIR | REQUEST, l3dss1_redir_req_early},
-        {SBIT(9) | SBIT(25),
-         CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
+	{SBIT(7) | SBIT(9) | SBIT(25),
+	 CC_REDIR | REQUEST, l3dss1_redir_req},
+	{SBIT(6),
+	 CC_REDIR | REQUEST, l3dss1_redir_req_early},
+	{SBIT(9) | SBIT(25),
+	 CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
 	{SBIT(25),
 	 CC_T302, l3dss1_t302},
 	{SBIT(1),
@@ -2880,20 +2880,20 @@ static struct stateentry globalmes_list[] =
 	{SBIT(0),
 	 MT_RESTART, l3dss1_global_restart},
 /*	{SBIT(1),
-	 MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
+	MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
 */
 };
 
 static struct stateentry manstatelist[] =
 {
-        {SBIT(2),
-         DL_ESTABLISH | INDICATION, l3dss1_dl_reset},
-        {SBIT(10),
-         DL_ESTABLISH | CONFIRM, l3dss1_dl_reest_status},
-        {SBIT(10),
-         DL_RELEASE | INDICATION, l3dss1_dl_reestablish},
-        {ALL_STATES,
-         DL_RELEASE | INDICATION, l3dss1_dl_release},
+	{SBIT(2),
+	 DL_ESTABLISH | INDICATION, l3dss1_dl_reset},
+	{SBIT(10),
+	 DL_ESTABLISH | CONFIRM, l3dss1_dl_reest_status},
+	{SBIT(10),
+	 DL_RELEASE | INDICATION, l3dss1_dl_reestablish},
+	{ALL_STATES,
+	 DL_RELEASE | INDICATION, l3dss1_dl_release},
 };
 
 /* *INDENT-ON* */
@@ -2916,13 +2916,13 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 	if (i == ARRAY_SIZE(globalmes_list)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1 global state %d mt %x unhandled",
-				proc->state, mt);
+				 proc->state, mt);
 		}
 		MsgHead(p, proc->callref, MT_STATUS);
 		*p++ = IE_CAUSE;
 		*p++ = 0x2;
 		*p++ = 0x80;
-		*p++ = 81 |0x80;	/* invalid cr */
+		*p++ = 81 | 0x80;	/* invalid cr */
 		*p++ = 0x14;		/* CallState */
 		*p++ = 0x1;
 		*p++ = proc->state & 0x3f;
@@ -2934,7 +2934,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 	} else {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1 global %d mt %x",
-				proc->state, mt);
+				 proc->state, mt);
 		}
 		globalmes_list[i].rout(proc, mt, skb);
 	}
@@ -2950,19 +2950,19 @@ dss1up(struct PStack *st, int pr, void *arg)
 	struct l3_process *proc;
 
 	switch (pr) {
-		case (DL_DATA | INDICATION):
-		case (DL_UNIT_DATA | INDICATION):
-			break;
-		case (DL_ESTABLISH | CONFIRM):
-		case (DL_ESTABLISH | INDICATION):
-		case (DL_RELEASE | INDICATION):
-		case (DL_RELEASE | CONFIRM):
-			l3_msg(st, pr, arg);
-			return;
-			break;
-                default:
-                        printk(KERN_ERR "HiSax dss1up unknown pr=%04x\n", pr);
-                        return;
+	case (DL_DATA | INDICATION):
+	case (DL_UNIT_DATA | INDICATION):
+		break;
+	case (DL_ESTABLISH | CONFIRM):
+	case (DL_ESTABLISH | INDICATION):
+	case (DL_RELEASE | INDICATION):
+	case (DL_RELEASE | CONFIRM):
+		l3_msg(st, pr, arg);
+		return;
+		break;
+	default:
+		printk(KERN_ERR "HiSax dss1up unknown pr=%04x\n", pr);
+		return;
 	}
 	if (skb->len < 3) {
 		l3_debug(st, "dss1up frame too short(%d)", skb->len);
@@ -2996,17 +2996,17 @@ dss1up(struct PStack *st, int pr, void *arg)
 	} else if (cr == -1) {	/* Dummy Callref */
 		if (mt == MT_FACILITY)
 			if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
-				l3dss1_parse_facility(st, NULL, 
-					(pr == (DL_DATA | INDICATION)) ? -1 : -2, p); 
+				l3dss1_parse_facility(st, NULL,
+						      (pr == (DL_DATA | INDICATION)) ? -1 : -2, p);
 				dev_kfree_skb(skb);
-				return;  
+				return;
 			}
 		if (st->l3.debug & L3_DEB_WARN)
 			l3_debug(st, "dss1up dummy Callref (no facility msg or ie)");
 		dev_kfree_skb(skb);
 		return;
-	} else if ((((skb->data[1] & 0x0f) == 1) && (0==(cr & 0x7f))) ||
-		(((skb->data[1] & 0x0f) == 2) && (0==(cr & 0x7fff)))) {	/* Global CallRef */
+	} else if ((((skb->data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) ||
+		   (((skb->data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) {	/* Global CallRef */
 		if (st->l3.debug & L3_DEB_STATE)
 			l3_debug(st, "dss1up Global CallRef");
 		global_handler(st, mt, skb);
@@ -3084,8 +3084,8 @@ dss1up(struct PStack *st, int pr, void *arg)
 		dev_kfree_skb(skb);
 		return;
 	}
-	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) 
-	  l3dss1_deliver_display(proc, pr, p); /* Display IE included */
+	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
+		l3dss1_deliver_display(proc, pr, p); /* Display IE included */
 	for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
 		if ((mt == datastatelist[i].primitive) &&
 		    ((1 << proc->state) & datastatelist[i].state))
@@ -3093,8 +3093,8 @@ dss1up(struct PStack *st, int pr, void *arg)
 	if (i == ARRAY_SIZE(datastatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1up%sstate %d mt %#x unhandled",
-				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
-				proc->state, mt);
+				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+				 proc->state, mt);
 		}
 		if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) {
 			proc->para.cause = 101;
@@ -3103,8 +3103,8 @@ dss1up(struct PStack *st, int pr, void *arg)
 	} else {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1up%sstate %d mt %x",
-				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
-				proc->state, mt);
+				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+				 proc->state, mt);
 		}
 		datastatelist[i].rout(proc, pr, skb);
 	}
@@ -3140,10 +3140,10 @@ dss1down(struct PStack *st, int pr, void *arg)
 		return;
 	}
 
-	if ( pr == (CC_TDSS1_IO | REQUEST)) {
-		l3dss1_io_timer(proc); /* timer expires */ 
+	if (pr == (CC_TDSS1_IO | REQUEST)) {
+		l3dss1_io_timer(proc); /* timer expires */
 		return;
-	}  
+	}
 
 	for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
 		if ((pr == downstatelist[i].primitive) &&
@@ -3152,12 +3152,12 @@ dss1down(struct PStack *st, int pr, void *arg)
 	if (i == ARRAY_SIZE(downstatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1down state %d prim %#x unhandled",
-				proc->state, pr);
+				 proc->state, pr);
 		}
 	} else {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1down state %d prim %#x",
-				proc->state, pr);
+				 proc->state, pr);
 		}
 		downstatelist[i].rout(proc, pr, arg);
 	}
@@ -3166,31 +3166,31 @@ dss1down(struct PStack *st, int pr, void *arg)
 static void
 dss1man(struct PStack *st, int pr, void *arg)
 {
-        int i;
-        struct l3_process *proc = arg;
- 
-        if (!proc) {
-                printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
-                return;
-        }
-        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
-                if ((pr == manstatelist[i].primitive) &&
-                    ((1 << proc->state) & manstatelist[i].state))
-                        break;
-        if (i == ARRAY_SIZE(manstatelist)) {
-                if (st->l3.debug & L3_DEB_STATE) {
-                        l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
-                                proc->callref & 0x7f, proc->state, pr);
-                }
-        } else {
-                if (st->l3.debug & L3_DEB_STATE) {
-                        l3_debug(st, "cr %d dss1man state %d prim %#x",
-                                proc->callref & 0x7f, proc->state, pr);
-                }
-                manstatelist[i].rout(proc, pr, arg);
-        }
-}
- 
+	int i;
+	struct l3_process *proc = arg;
+
+	if (!proc) {
+		printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
+		return;
+	}
+	for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
+		if ((pr == manstatelist[i].primitive) &&
+		    ((1 << proc->state) & manstatelist[i].state))
+			break;
+	if (i == ARRAY_SIZE(manstatelist)) {
+		if (st->l3.debug & L3_DEB_STATE) {
+			l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
+				 proc->callref & 0x7f, proc->state, pr);
+		}
+	} else {
+		if (st->l3.debug & L3_DEB_STATE) {
+			l3_debug(st, "cr %d dss1man state %d prim %#x",
+				 proc->callref & 0x7f, proc->state, pr);
+		}
+		manstatelist[i].rout(proc, pr, arg);
+	}
+}
+
 void
 setstack_dss1(struct PStack *st)
 {
@@ -3205,8 +3205,8 @@ setstack_dss1(struct PStack *st)
 	st->prot.dss1.last_invoke_id = 0;
 	st->prot.dss1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */
 	i = 1;
-	while (i < 32) 
-		st->prot.dss1.invoke_used[i++] = 0;   
+	while (i < 32)
+		st->prot.dss1.invoke_used[i++] = 0;
 
 	if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
 		printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");
@@ -3217,7 +3217,7 @@ setstack_dss1(struct PStack *st)
 		st->l3.global->debug = L3_DEB_WARN;
 		st->l3.global->st = st;
 		st->l3.global->N303 = 1;
-		st->l3.global->prot.dss1.invoke_id = 0; 
+		st->l3.global->prot.dss1.invoke_id = 0;
 
 		L3InitTimer(st->l3.global, &st->l3.global->timer);
 	}
diff --git a/drivers/isdn/hisax/l3dss1.h b/drivers/isdn/hisax/l3dss1.h
index 6da47f0..a7807e8 100644
--- a/drivers/isdn/hisax/l3dss1.h
+++ b/drivers/isdn/hisax/l3dss1.h
@@ -107,18 +107,18 @@
 
 /* l3dss1 specific data in l3 process */
 typedef struct
-  { unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */
-    ulong ll_id; /* remebered ll id */
-    u8 remote_operation; /* handled remote operation, 0 = not active */ 
-    int proc; /* rememered procedure */  
-    ulong remote_result; /* result of remote operation for statcallb */
-    char uus1_data[35]; /* data send during alerting or disconnect */
-  } dss1_proc_priv;
+{ unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */
+	ulong ll_id; /* remebered ll id */
+	u8 remote_operation; /* handled remote operation, 0 = not active */
+	int proc; /* rememered procedure */
+	ulong remote_result; /* result of remote operation for statcallb */
+	char uus1_data[35]; /* data send during alerting or disconnect */
+} dss1_proc_priv;
 
 /* l3dss1 specific data in protocol stack */
 typedef struct
-  { unsigned char last_invoke_id; /* last used value for invoking */
-    unsigned char invoke_used[32]; /* 256 bits for 256 values */
-  } dss1_stk_priv;        
+{ unsigned char last_invoke_id; /* last used value for invoking */
+	unsigned char invoke_used[32]; /* 256 bits for 256 values */
+} dss1_stk_priv;
 
 #endif /* only l3dss1_process */
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 092dcbb..0df6691 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -4,14 +4,14 @@
  *
  * Author       Matt Henderson & Guy Ellis
  * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * 2000.6.6 Initial implementation of routines for US NI1 
- * Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
- * driver written by Karsten Keil et al.  
- * NI-1 Hall of Fame - Thanks to.... 
+ * 2000.6.6 Initial implementation of routines for US NI1
+ * Layer 3 protocol based on the EURO/DSS1 D-channel protocol
+ * driver written by Karsten Keil et al.
+ * NI-1 Hall of Fame - Thanks to....
  * Ragnar Paulson - for some handy code fragments
  * Will Scales - beta tester extraordinaire
  * Brett Whittacre - beta tester and remote devel system in Vegas
@@ -29,14 +29,14 @@ static const char *ni1_revision = "$Revision: 2.8.2.3 $";
 
 #define EXT_BEARER_CAPS 1
 
-#define	MsgHead(ptr, cref, mty) \
-	*ptr++ = 0x8; \
-	if (cref == -1) { \
-		*ptr++ = 0x0; \
-	} else { \
-		*ptr++ = 0x1; \
-		*ptr++ = cref^0x80; \
-	} \
+#define	MsgHead(ptr, cref, mty)			\
+	*ptr++ = 0x8;				\
+	if (cref == -1) {			\
+		*ptr++ = 0x0;			\
+	} else {				\
+		*ptr++ = 0x1;			\
+		*ptr++ = cref^0x80;		\
+	}					\
 	*ptr++ = mty
 
 
@@ -48,22 +48,22 @@ static unsigned char new_invoke_id(struct PStack *p)
 {
 	unsigned char retval;
 	int i;
-  
+
 	i = 32; /* maximum search depth */
 
 	retval = p->prot.ni1.last_invoke_id + 1; /* try new id */
 	while ((i) && (p->prot.ni1.invoke_used[retval >> 3] == 0xFF)) {
 		p->prot.ni1.last_invoke_id = (retval & 0xF8) + 8;
 		i--;
-	}  
+	}
 	if (i) {
 		while (p->prot.ni1.invoke_used[retval >> 3] & (1 << (retval & 7)))
-		retval++; 
+			retval++;
 	} else
 		retval = 0;
 	p->prot.ni1.last_invoke_id = retval;
 	p->prot.ni1.invoke_used[retval >> 3] |= (1 << (retval & 7));
-	return(retval);  
+	return (retval);
 } /* new_invoke_id */
 
 /*************************/
@@ -72,10 +72,10 @@ static unsigned char new_invoke_id(struct PStack *p)
 static void free_invoke_id(struct PStack *p, unsigned char id)
 {
 
-  if (!id) return; /* 0 = invalid value */
+	if (!id) return; /* 0 = invalid value */
 
-  p->prot.ni1.invoke_used[id >> 3] &= ~(1 << (id & 7));
-} /* free_invoke_id */  
+	p->prot.ni1.invoke_used[id >> 3] &= ~(1 << (id & 7));
+} /* free_invoke_id */
 
 
 /**********************************************************/
@@ -85,26 +85,26 @@ static struct l3_process
 *ni1_new_l3_process(struct PStack *st, int cr)
 {  struct l3_process *proc;
 
-   if (!(proc = new_l3_process(st, cr))) 
-     return(NULL);
+	if (!(proc = new_l3_process(st, cr)))
+		return (NULL);
 
-   proc->prot.ni1.invoke_id = 0;
-   proc->prot.ni1.remote_operation = 0;
-   proc->prot.ni1.uus1_data[0] = '\0';
-   
-   return(proc);
+	proc->prot.ni1.invoke_id = 0;
+	proc->prot.ni1.remote_operation = 0;
+	proc->prot.ni1.uus1_data[0] = '\0';
+
+	return (proc);
 } /* ni1_new_l3_process */
 
 /************************************************/
 /* free a l3 process and all ni1 specific data */
-/************************************************/ 
+/************************************************/
 static void
 ni1_release_l3_process(struct l3_process *p)
 {
-   free_invoke_id(p->st,p->prot.ni1.invoke_id);
-   release_l3_process(p);
+	free_invoke_id(p->st, p->prot.ni1.invoke_id);
+	release_l3_process(p);
 } /* ni1_release_l3_process */
- 
+
 /********************************************************/
 /* search a process with invoke id id and dummy callref */
 /********************************************************/
@@ -112,120 +112,120 @@ static struct l3_process *
 l3ni1_search_dummy_proc(struct PStack *st, int id)
 { struct l3_process *pc = st->l3.proc; /* start of processes */
 
-  if (!id) return(NULL);
+	if (!id) return (NULL);
 
-  while (pc)
-   { if ((pc->callref == -1) && (pc->prot.ni1.invoke_id == id))
-       return(pc);
-     pc = pc->next;
-   } 
-  return(NULL);
+	while (pc)
+	{ if ((pc->callref == -1) && (pc->prot.ni1.invoke_id == id))
+			return (pc);
+		pc = pc->next;
+	}
+	return (NULL);
 } /* l3ni1_search_dummy_proc */
 
 /*******************************************************************/
 /* called when a facility message with a dummy callref is received */
 /* and a return result is delivered. id specifies the invoke id.   */
-/*******************************************************************/ 
-static void 
+/*******************************************************************/
+static void
 l3ni1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs;
-  struct l3_process *pc = NULL; 
-
-  if ((pc = l3ni1_search_dummy_proc(st, id)))
-   { L3DelTimer(&pc->timer); /* remove timer */
-
-     cs = pc->st->l1.hardware;
-     ic.driver = cs->myid;
-     ic.command = ISDN_STAT_PROT;
-     ic.arg = NI1_STAT_INVOKE_RES;
-     ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
-     ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
-     ic.parm.ni1_io.proc = pc->prot.ni1.proc;
-     ic.parm.ni1_io.timeout= 0;
-     ic.parm.ni1_io.datalen = nlen;
-     ic.parm.ni1_io.data = p;
-     free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
-     pc->prot.ni1.invoke_id = 0; /* reset id */
-
-     cs->iif.statcallb(&ic);
-     ni1_release_l3_process(pc); 
-   }
-  else
-   l3_debug(st, "dummy return result id=0x%x result len=%d",id,nlen);
+	struct IsdnCardState *cs;
+	struct l3_process *pc = NULL;
+
+	if ((pc = l3ni1_search_dummy_proc(st, id)))
+	{ L3DelTimer(&pc->timer); /* remove timer */
+
+		cs = pc->st->l1.hardware;
+		ic.driver = cs->myid;
+		ic.command = ISDN_STAT_PROT;
+		ic.arg = NI1_STAT_INVOKE_RES;
+		ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
+		ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
+		ic.parm.ni1_io.proc = pc->prot.ni1.proc;
+		ic.parm.ni1_io.timeout = 0;
+		ic.parm.ni1_io.datalen = nlen;
+		ic.parm.ni1_io.data = p;
+		free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
+		pc->prot.ni1.invoke_id = 0; /* reset id */
+
+		cs->iif.statcallb(&ic);
+		ni1_release_l3_process(pc);
+	}
+	else
+		l3_debug(st, "dummy return result id=0x%x result len=%d", id, nlen);
 } /* l3ni1_dummy_return_result */
 
 /*******************************************************************/
 /* called when a facility message with a dummy callref is received */
 /* and a return error is delivered. id specifies the invoke id.    */
-/*******************************************************************/ 
-static void 
+/*******************************************************************/
+static void
 l3ni1_dummy_error_return(struct PStack *st, int id, ulong error)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs;
-  struct l3_process *pc = NULL; 
-
-  if ((pc = l3ni1_search_dummy_proc(st, id)))
-   { L3DelTimer(&pc->timer); /* remove timer */
-
-     cs = pc->st->l1.hardware;
-     ic.driver = cs->myid;
-     ic.command = ISDN_STAT_PROT;
-     ic.arg = NI1_STAT_INVOKE_ERR;
-     ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
-     ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
-     ic.parm.ni1_io.proc = pc->prot.ni1.proc;
-     ic.parm.ni1_io.timeout= error;
-     ic.parm.ni1_io.datalen = 0;
-     ic.parm.ni1_io.data = NULL;
-     free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
-     pc->prot.ni1.invoke_id = 0; /* reset id */
-
-     cs->iif.statcallb(&ic);
-     ni1_release_l3_process(pc); 
-   }
-  else
-   l3_debug(st, "dummy return error id=0x%x error=0x%lx",id,error);
+	struct IsdnCardState *cs;
+	struct l3_process *pc = NULL;
+
+	if ((pc = l3ni1_search_dummy_proc(st, id)))
+	{ L3DelTimer(&pc->timer); /* remove timer */
+
+		cs = pc->st->l1.hardware;
+		ic.driver = cs->myid;
+		ic.command = ISDN_STAT_PROT;
+		ic.arg = NI1_STAT_INVOKE_ERR;
+		ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
+		ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
+		ic.parm.ni1_io.proc = pc->prot.ni1.proc;
+		ic.parm.ni1_io.timeout = error;
+		ic.parm.ni1_io.datalen = 0;
+		ic.parm.ni1_io.data = NULL;
+		free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
+		pc->prot.ni1.invoke_id = 0; /* reset id */
+
+		cs->iif.statcallb(&ic);
+		ni1_release_l3_process(pc);
+	}
+	else
+		l3_debug(st, "dummy return error id=0x%x error=0x%lx", id, error);
 } /* l3ni1_error_return */
 
 /*******************************************************************/
 /* called when a facility message with a dummy callref is received */
 /* and a invoke is delivered. id specifies the invoke id.          */
-/*******************************************************************/ 
-static void 
-l3ni1_dummy_invoke(struct PStack *st, int cr, int id, 
-                    int ident, u_char *p, u_char nlen)
+/*******************************************************************/
+static void
+l3ni1_dummy_invoke(struct PStack *st, int cr, int id,
+		   int ident, u_char *p, u_char nlen)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs;
-
-  l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d",
-               (cr == -1) ? "local" : "broadcast",id,ident,nlen);
-  if (cr >= -1) return; /* ignore local data */
-
-  cs = st->l1.hardware;
-  ic.driver = cs->myid;
-  ic.command = ISDN_STAT_PROT;
-  ic.arg = NI1_STAT_INVOKE_BRD;
-  ic.parm.ni1_io.hl_id = id;
-  ic.parm.ni1_io.ll_id = 0;
-  ic.parm.ni1_io.proc = ident;
-  ic.parm.ni1_io.timeout= 0;
-  ic.parm.ni1_io.datalen = nlen;
-  ic.parm.ni1_io.data = p;
-
-  cs->iif.statcallb(&ic);
+	struct IsdnCardState *cs;
+
+	l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d",
+		 (cr == -1) ? "local" : "broadcast", id, ident, nlen);
+	if (cr >= -1) return; /* ignore local data */
+
+	cs = st->l1.hardware;
+	ic.driver = cs->myid;
+	ic.command = ISDN_STAT_PROT;
+	ic.arg = NI1_STAT_INVOKE_BRD;
+	ic.parm.ni1_io.hl_id = id;
+	ic.parm.ni1_io.ll_id = 0;
+	ic.parm.ni1_io.proc = ident;
+	ic.parm.ni1_io.timeout = 0;
+	ic.parm.ni1_io.datalen = nlen;
+	ic.parm.ni1_io.data = p;
+
+	cs->iif.statcallb(&ic);
 } /* l3ni1_dummy_invoke */
 
 static void
 l3ni1_parse_facility(struct PStack *st, struct l3_process *pc,
-                      int cr, u_char * p)
+		     int cr, u_char *p)
 {
 	int qd_len = 0;
 	unsigned char nlen = 0, ilen, cp_tag;
 	int ident, id;
 	ulong err_ret;
 
-	if (pc) 
+	if (pc)
 		st = pc->st; /* valid Stack */
 	else
 		if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */
@@ -254,173 +254,173 @@ l3ni1_parse_facility(struct PStack *st, struct l3_process *pc,
 		l3_debug(st, "class and form != 0xA0");
 		return;
 	}
-       
-        cp_tag = *p & 0x1F; /* remember tag value */
 
-        p++;
+	cp_tag = *p & 0x1F; /* remember tag value */
+
+	p++;
 	qd_len--;
-	if (qd_len < 1) 
-          { l3_debug(st, "qd_len < 1");
-	    return;
-	  }
-	if (*p & 0x80) 
-          { /* length format indefinite or limited */
-	    nlen = *p++ & 0x7F; /* number of len bytes or indefinite */
-            if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
-                (nlen > 1))   
-	     { l3_debug(st, "length format error or not implemented");
-	       return;
-             }
-            if (nlen == 1)
-	     { nlen = *p++; /* complete length */
-               qd_len--;
-             } 
-            else
-	     { qd_len -= 2; /* trailing null bytes */
-               if ((*(p+qd_len)) || (*(p+qd_len+1)))
-		{ l3_debug(st,"length format indefinite error");
-                  return;
-                }
-               nlen = qd_len;
-             }
-	  }
-        else
-	  { nlen = *p++;
-	    qd_len--;
-          } 
-	if (qd_len < nlen) 
-          { l3_debug(st, "qd_len < nlen");
-	    return;
-	  }
+	if (qd_len < 1)
+	{ l3_debug(st, "qd_len < 1");
+		return;
+	}
+	if (*p & 0x80)
+	{ /* length format indefinite or limited */
+		nlen = *p++ & 0x7F; /* number of len bytes or indefinite */
+		if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
+		    (nlen > 1))
+		{ l3_debug(st, "length format error or not implemented");
+			return;
+		}
+		if (nlen == 1)
+		{ nlen = *p++; /* complete length */
+			qd_len--;
+		}
+		else
+		{ qd_len -= 2; /* trailing null bytes */
+			if ((*(p + qd_len)) || (*(p + qd_len + 1)))
+			{ l3_debug(st, "length format indefinite error");
+				return;
+			}
+			nlen = qd_len;
+		}
+	}
+	else
+	{ nlen = *p++;
+		qd_len--;
+	}
+	if (qd_len < nlen)
+	{ l3_debug(st, "qd_len < nlen");
+		return;
+	}
 	qd_len -= nlen;
 
-	if (nlen < 2) 
-          { l3_debug(st, "nlen < 2");
-	    return;
-	  }
-        if (*p != 0x02) 
-          {  /* invoke identifier tag */
-	     l3_debug(st, "invoke identifier tag !=0x02");
-	     return;
-	  }
+	if (nlen < 2)
+	{ l3_debug(st, "nlen < 2");
+		return;
+	}
+	if (*p != 0x02)
+	{  /* invoke identifier tag */
+		l3_debug(st, "invoke identifier tag !=0x02");
+		return;
+	}
 	p++;
 	nlen--;
-	if (*p & 0x80) 
-          { /* length format */
-	    l3_debug(st, "invoke id length format 2");
-	    return;
-	  }
+	if (*p & 0x80)
+	{ /* length format */
+		l3_debug(st, "invoke id length format 2");
+		return;
+	}
 	ilen = *p++;
 	nlen--;
-	if (ilen > nlen || ilen == 0) 
-          { l3_debug(st, "ilen > nlen || ilen == 0");
-	    return;
-	  }
+	if (ilen > nlen || ilen == 0)
+	{ l3_debug(st, "ilen > nlen || ilen == 0");
+		return;
+	}
 	nlen -= ilen;
 	id = 0;
-	while (ilen > 0) 
-          { id = (id << 8) | (*p++ & 0xFF);	/* invoke identifier */
-	    ilen--;
-	  }
+	while (ilen > 0)
+	{ id = (id << 8) | (*p++ & 0xFF);	/* invoke identifier */
+		ilen--;
+	}
 
 	switch (cp_tag) {	/* component tag */
-		case 1:	/* invoke */
-				if (nlen < 2) {
-					l3_debug(st, "nlen < 2 22");
-					return;
-				}
-				if (*p != 0x02) {	/* operation value */
-					l3_debug(st, "operation value !=0x02");
-					return;
-				}
-				p++;
-				nlen--;
-				ilen = *p++;
-				nlen--;
-				if (ilen > nlen || ilen == 0) {
-					l3_debug(st, "ilen > nlen || ilen == 0 22");
-					return;
-				}
-				nlen -= ilen;
-				ident = 0;
-				while (ilen > 0) {
-					ident = (ident << 8) | (*p++ & 0xFF);
-					ilen--;
-				}
+	case 1:	/* invoke */
+		if (nlen < 2) {
+			l3_debug(st, "nlen < 2 22");
+			return;
+		}
+		if (*p != 0x02) {	/* operation value */
+			l3_debug(st, "operation value !=0x02");
+			return;
+		}
+		p++;
+		nlen--;
+		ilen = *p++;
+		nlen--;
+		if (ilen > nlen || ilen == 0) {
+			l3_debug(st, "ilen > nlen || ilen == 0 22");
+			return;
+		}
+		nlen -= ilen;
+		ident = 0;
+		while (ilen > 0) {
+			ident = (ident << 8) | (*p++ & 0xFF);
+			ilen--;
+		}
 
-				if (!pc) 
-				{
-					l3ni1_dummy_invoke(st, cr, id, ident, p, nlen);
-					return;
-				} 
-				l3_debug(st, "invoke break");
-				break;
-		case 2:	/* return result */
-			 /* if no process available handle separately */ 
-                        if (!pc)
-			 { if (cr == -1) 
-                             l3ni1_dummy_return_result(st, id, p, nlen);
-                           return; 
-                         }   
-                        if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id))
-                          { /* Diversion successful */
-                            free_invoke_id(st,pc->prot.ni1.invoke_id);
-                            pc->prot.ni1.remote_result = 0; /* success */     
-                            pc->prot.ni1.invoke_id = 0;
-                            pc->redir_result = pc->prot.ni1.remote_result; 
-                            st->l3.l3l4(st, CC_REDIR | INDICATION, pc);                                  } /* Diversion successful */
-                        else
-                          l3_debug(st,"return error unknown identifier");
-			break;
-		case 3:	/* return error */
-                            err_ret = 0;
-	                    if (nlen < 2) 
-                              { l3_debug(st, "return error nlen < 2");
-	                        return;
-	                      }
-                            if (*p != 0x02) 
-                              { /* result tag */
-	                        l3_debug(st, "invoke error tag !=0x02");
-	                        return;
-	                      }
-	                    p++;
-	                    nlen--;
-	                    if (*p > 4) 
-                              { /* length format */
-	                        l3_debug(st, "invoke return errlen > 4 ");
-	                        return;
-	                      }
-	                    ilen = *p++;
-	                    nlen--;
-	                    if (ilen > nlen || ilen == 0) 
-                              { l3_debug(st, "error return ilen > nlen || ilen == 0");
-	                        return;
-	                       }
-	                    nlen -= ilen;
-	                    while (ilen > 0) 
-                             { err_ret = (err_ret << 8) | (*p++ & 0xFF);	/* error value */
-	                       ilen--;
-	                     }
-			 /* if no process available handle separately */ 
-                        if (!pc)
-			 { if (cr == -1)
-                             l3ni1_dummy_error_return(st, id, err_ret);
-                           return; 
-                         }   
-                        if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id))
-                          { /* Deflection error */
-                            free_invoke_id(st,pc->prot.ni1.invoke_id);
-                            pc->prot.ni1.remote_result = err_ret; /* result */
-                            pc->prot.ni1.invoke_id = 0; 
-                            pc->redir_result = pc->prot.ni1.remote_result; 
-                            st->l3.l3l4(st, CC_REDIR | INDICATION, pc);  
-                          } /* Deflection error */
-                        else
-                          l3_debug(st,"return result unknown identifier");
-			break;
-		default:
-			l3_debug(st, "facility default break tag=0x%02x",cp_tag);
-			break;
+		if (!pc)
+		{
+			l3ni1_dummy_invoke(st, cr, id, ident, p, nlen);
+			return;
+		}
+		l3_debug(st, "invoke break");
+		break;
+	case 2:	/* return result */
+		/* if no process available handle separately */
+		if (!pc)
+		{ if (cr == -1)
+				l3ni1_dummy_return_result(st, id, p, nlen);
+			return;
+		}
+		if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id))
+		{ /* Diversion successful */
+			free_invoke_id(st, pc->prot.ni1.invoke_id);
+			pc->prot.ni1.remote_result = 0; /* success */
+			pc->prot.ni1.invoke_id = 0;
+			pc->redir_result = pc->prot.ni1.remote_result;
+			st->l3.l3l4(st, CC_REDIR | INDICATION, pc); } /* Diversion successful */
+		else
+			l3_debug(st, "return error unknown identifier");
+		break;
+	case 3:	/* return error */
+		err_ret = 0;
+		if (nlen < 2)
+		{ l3_debug(st, "return error nlen < 2");
+			return;
+		}
+		if (*p != 0x02)
+		{ /* result tag */
+			l3_debug(st, "invoke error tag !=0x02");
+			return;
+		}
+		p++;
+		nlen--;
+		if (*p > 4)
+		{ /* length format */
+			l3_debug(st, "invoke return errlen > 4 ");
+			return;
+		}
+		ilen = *p++;
+		nlen--;
+		if (ilen > nlen || ilen == 0)
+		{ l3_debug(st, "error return ilen > nlen || ilen == 0");
+			return;
+		}
+		nlen -= ilen;
+		while (ilen > 0)
+		{ err_ret = (err_ret << 8) | (*p++ & 0xFF);	/* error value */
+			ilen--;
+		}
+		/* if no process available handle separately */
+		if (!pc)
+		{ if (cr == -1)
+				l3ni1_dummy_error_return(st, id, err_ret);
+			return;
+		}
+		if ((pc->prot.ni1.invoke_id) && (pc->prot.ni1.invoke_id == id))
+		{ /* Deflection error */
+			free_invoke_id(st, pc->prot.ni1.invoke_id);
+			pc->prot.ni1.remote_result = err_ret; /* result */
+			pc->prot.ni1.invoke_id = 0;
+			pc->redir_result = pc->prot.ni1.remote_result;
+			st->l3.l3l4(st, CC_REDIR | INDICATION, pc);
+		} /* Deflection error */
+		else
+			l3_debug(st, "return result unknown identifier");
+		break;
+	default:
+		l3_debug(st, "facility default break tag=0x%02x", cp_tag);
+		break;
 	}
 }
 
@@ -518,21 +518,21 @@ l3ni1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
 	struct sk_buff *skb;
 
 	switch (pc->para.cause) {
-		case 81:	/* invalid callreference */
-		case 88:	/* incomp destination */
-		case 96:	/* mandory IE missing */
-		case 100:       /* invalid IE contents */
-		case 101:	/* incompatible Callstate */
-			MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
-			*p++ = IE_CAUSE;
-			*p++ = 0x2;
-			*p++ = 0x80;
-			*p++ = pc->para.cause | 0x80;
-			break;
-		default:
-			printk(KERN_ERR "HiSax l3ni1_msg_without_setup wrong cause %d\n",
-				pc->para.cause);
-			return;
+	case 81:	/* invalid callreference */
+	case 88:	/* incomp destination */
+	case 96:	/* mandory IE missing */
+	case 100:       /* invalid IE contents */
+	case 101:	/* incompatible Callstate */
+		MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
+		*p++ = IE_CAUSE;
+		*p++ = 0x2;
+		*p++ = 0x80;
+		*p++ = pc->para.cause | 0x80;
+		break;
+	default:
+		printk(KERN_ERR "HiSax l3ni1_msg_without_setup wrong cause %d\n",
+		       pc->para.cause);
+		return;
 	}
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
@@ -543,42 +543,42 @@ l3ni1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
 }
 
 static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
-		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,
-		IE_USER_USER, -1};
+			    IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,
+			    IE_USER_USER, -1};
 static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
-		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
-static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1, 
-		IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
-		IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
+				   IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
+static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
+			   IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
+			   IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
 static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1};
 static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY,
-		IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
+			      IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
 static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL,
-		IE_CALLED_PN, -1};
+			       IE_CALLED_PN, -1};
 static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1};
 static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS |
-		IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
+			    IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
 static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY,
-		IE_SIGNAL, IE_USER_USER, -1};
-/* a RELEASE_COMPLETE with errors don't require special actions 
-static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
+			   IE_SIGNAL, IE_USER_USER, -1};
+/* a RELEASE_COMPLETE with errors don't require special actions
+   static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
 */
-static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY,
-		IE_DISPLAY, -1};
+static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
+				      IE_DISPLAY, -1};
 static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
 static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER  | IE_MANDATORY,
-		IE_CHANNEL_ID| IE_MANDATORY, IE_FACILITY, IE_PROGRESS,
-		IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,
-		IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,
-		IE_LLC, IE_HLC, IE_USER_USER, -1};
+			 IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, IE_PROGRESS,
+			 IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,
+			 IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,
+			 IE_LLC, IE_HLC, IE_USER_USER, -1};
 static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
-		IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};
+				     IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};
 static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE |
-		IE_MANDATORY, IE_DISPLAY, -1};
+			  IE_MANDATORY, IE_DISPLAY, -1};
 static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1};
 static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1};
 static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
-/* not used 
+/* not used
  * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY,
  *		IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
  * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1};
@@ -586,8 +586,8 @@ static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
  *		IE_MANDATORY, -1};
  */
 static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1};
-static int comp_required[] = {1,2,3,5,6,7,9,10,11,14,15,-1};
-static int l3_valid_states[] = {0,1,2,3,4,6,7,8,9,10,11,12,15,17,19,25,-1};
+static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1};
+static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1};
 
 struct ie_len {
 	int ie;
@@ -628,7 +628,7 @@ struct ie_len max_ie_len[] = {
 	{IE_LLC, 18},
 	{IE_HLC, 5},
 	{IE_USER_USER, 131},
-	{-1,0},
+	{-1, 0},
 };
 
 static int
@@ -636,10 +636,10 @@ getmax_ie_len(u_char ie) {
 	int i = 0;
 	while (max_ie_len[i].ie != -1) {
 		if (max_ie_len[i].ie == ie)
-			return(max_ie_len[i].len);
+			return (max_ie_len[i].len);
 		i++;
 	}
-	return(255);
+	return (255);
 }
 
 static int
@@ -649,14 +649,14 @@ ie_in_set(struct l3_process *pc, u_char ie, int *checklist) {
 	while (*checklist != -1) {
 		if ((*checklist & 0xff) == ie) {
 			if (ie & 0x80)
-				return(-ret);
+				return (-ret);
 			else
-				return(ret);
+				return (ret);
 		}
 		ret++;
 		checklist++;
 	}
-	return(0);
+	return (0);
 }
 
 static int
@@ -670,7 +670,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 	u_char codeset = 0;
 	u_char old_codeset = 0;
 	u_char codelock = 1;
-	
+
 	p = skb->data;
 	/* skip cr */
 	p++;
@@ -688,7 +688,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 				codelock = 1;
 			if (pc->debug & L3_DEB_CHECK)
 				l3_debug(pc->st, "check IE shift%scodeset %d->%d",
-					codelock ? " locking ": " ", old_codeset, codeset);
+					 codelock ? " locking " : " ", old_codeset, codeset);
 			p++;
 			continue;
 		}
@@ -720,7 +720,7 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 		if (!codelock) {
 			if (pc->debug & L3_DEB_CHECK)
 				l3_debug(pc->st, "check IE shift back codeset %d->%d",
-					codeset, old_codeset);
+					 codeset, old_codeset);
 			codeset = old_codeset;
 			codelock = 1;
 		}
@@ -728,17 +728,17 @@ check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
 	if (err_compr | err_ureg | err_len | err_seq) {
 		if (pc->debug & L3_DEB_CHECK)
 			l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d",
-				mt, err_compr, err_ureg, err_len, err_seq);
+				 mt, err_compr, err_ureg, err_len, err_seq);
 		if (err_compr)
-			return(ERR_IE_COMPREHENSION);
+			return (ERR_IE_COMPREHENSION);
 		if (err_ureg)
-			return(ERR_IE_UNRECOGNIZED);
+			return (ERR_IE_UNRECOGNIZED);
 		if (err_len)
-			return(ERR_IE_LENGTH);
+			return (ERR_IE_LENGTH);
 		if (err_seq)
-			return(ERR_IE_SEQUENCE);
-	} 
-	return(0);
+			return (ERR_IE_SEQUENCE);
+	}
+	return (0);
 }
 
 /* verify if a message type exists and contain no IE error */
@@ -746,42 +746,42 @@ static int
 l3ni1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg)
 {
 	switch (mt) {
-		case MT_ALERTING:
-		case MT_CALL_PROCEEDING:
-		case MT_CONNECT:
-		case MT_CONNECT_ACKNOWLEDGE:
-		case MT_DISCONNECT:
-		case MT_INFORMATION:
-		case MT_FACILITY:
-		case MT_NOTIFY:
-		case MT_PROGRESS:
-		case MT_RELEASE:
-		case MT_RELEASE_COMPLETE:
-		case MT_SETUP:
-		case MT_SETUP_ACKNOWLEDGE:
-		case MT_RESUME_ACKNOWLEDGE:
-		case MT_RESUME_REJECT:
-		case MT_SUSPEND_ACKNOWLEDGE:
-		case MT_SUSPEND_REJECT:
-		case MT_USER_INFORMATION:
-		case MT_RESTART:
-		case MT_RESTART_ACKNOWLEDGE:
-		case MT_CONGESTION_CONTROL:
-		case MT_STATUS:
-		case MT_STATUS_ENQUIRY:
-			if (pc->debug & L3_DEB_CHECK)
-				l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) OK", mt);
-			break;
-		case MT_RESUME: /* RESUME only in user->net */
-		case MT_SUSPEND: /* SUSPEND only in user->net */
-		default:
-			if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))
-				l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) fail", mt);
-			pc->para.cause = 97;
-			l3ni1_status_send(pc, 0, NULL);
-			return(1);
+	case MT_ALERTING:
+	case MT_CALL_PROCEEDING:
+	case MT_CONNECT:
+	case MT_CONNECT_ACKNOWLEDGE:
+	case MT_DISCONNECT:
+	case MT_INFORMATION:
+	case MT_FACILITY:
+	case MT_NOTIFY:
+	case MT_PROGRESS:
+	case MT_RELEASE:
+	case MT_RELEASE_COMPLETE:
+	case MT_SETUP:
+	case MT_SETUP_ACKNOWLEDGE:
+	case MT_RESUME_ACKNOWLEDGE:
+	case MT_RESUME_REJECT:
+	case MT_SUSPEND_ACKNOWLEDGE:
+	case MT_SUSPEND_REJECT:
+	case MT_USER_INFORMATION:
+	case MT_RESTART:
+	case MT_RESTART_ACKNOWLEDGE:
+	case MT_CONGESTION_CONTROL:
+	case MT_STATUS:
+	case MT_STATUS_ENQUIRY:
+		if (pc->debug & L3_DEB_CHECK)
+			l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) OK", mt);
+		break;
+	case MT_RESUME: /* RESUME only in user->net */
+	case MT_SUSPEND: /* SUSPEND only in user->net */
+	default:
+		if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))
+			l3_debug(pc->st, "l3ni1_check_messagetype_validity mt(%x) fail", mt);
+		pc->para.cause = 97;
+		l3ni1_status_send(pc, 0, NULL);
+		return (1);
 	}
-	return(0);
+	return (0);
 }
 
 static void
@@ -789,24 +789,24 @@ l3ni1_std_ie_err(struct l3_process *pc, int ret) {
 
 	if (pc->debug & L3_DEB_CHECK)
 		l3_debug(pc->st, "check_infoelements ret %d", ret);
-	switch(ret) {
-		case 0: 
-			break;
-		case ERR_IE_COMPREHENSION:
-			pc->para.cause = 96;
-			l3ni1_status_send(pc, 0, NULL);
-			break;
-		case ERR_IE_UNRECOGNIZED:
-			pc->para.cause = 99;
-			l3ni1_status_send(pc, 0, NULL);
-			break;
-		case ERR_IE_LENGTH:
-			pc->para.cause = 100;
-			l3ni1_status_send(pc, 0, NULL);
-			break;
-		case ERR_IE_SEQUENCE:
-		default:
-			break;
+	switch (ret) {
+	case 0:
+		break;
+	case ERR_IE_COMPREHENSION:
+		pc->para.cause = 96;
+		l3ni1_status_send(pc, 0, NULL);
+		break;
+	case ERR_IE_UNRECOGNIZED:
+		pc->para.cause = 99;
+		l3ni1_status_send(pc, 0, NULL);
+		break;
+	case ERR_IE_LENGTH:
+		pc->para.cause = 100;
+		l3ni1_status_send(pc, 0, NULL);
+		break;
+	case ERR_IE_SEQUENCE:
+	default:
+		break;
 	}
 }
 
@@ -828,14 +828,14 @@ l3ni1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) {
 				l3_debug(pc->st, "wrong chid %x", *p);
 			return (-3);
 		}
-		return(*p & 0x3);
+		return (*p & 0x3);
 	} else
-		return(-1);
+		return (-1);
 }
 
 static int
 l3ni1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
-	u_char l, i=0;
+	u_char l, i = 0;
 	u_char *p;
 
 	p = skb->data;
@@ -844,13 +844,13 @@ l3ni1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
 	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
 		p++;
 		l = *p++;
-		if (l>30)
-			return(1);
+		if (l > 30)
+			return (1);
 		if (l) {
 			pc->para.loc = *p++;
 			l--;
 		} else {
-			return(2);
+			return (2);
 		}
 		if (l && !(pc->para.loc & 0x80)) {
 			l--;
@@ -860,36 +860,36 @@ l3ni1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
 			pc->para.cause = *p++;
 			l--;
 			if (!(pc->para.cause & 0x80))
-				return(3);
+				return (3);
 		} else
-			return(4);
-		while (l && (i<6)) {
+			return (4);
+		while (l && (i < 6)) {
 			pc->para.diag[i++] = *p++;
 			l--;
 		}
 	} else
-		return(-1);
-	return(0);
+		return (-1);
+	return (0);
 }
 
 static void
 l3ni1_msg_with_uus(struct l3_process *pc, u_char cmd)
 {
 	struct sk_buff *skb;
-	u_char tmp[16+40];
+	u_char tmp[16 + 40];
 	u_char *p = tmp;
 	int l;
 
 	MsgHead(p, pc->callref, cmd);
 
-        if (pc->prot.ni1.uus1_data[0])
-	 { *p++ = IE_USER_USER; /* UUS info element */
-           *p++ = strlen(pc->prot.ni1.uus1_data) + 1;
-           *p++ = 0x04; /* IA5 chars */
-           strcpy(p,pc->prot.ni1.uus1_data);
-           p += strlen(pc->prot.ni1.uus1_data);
-           pc->prot.ni1.uus1_data[0] = '\0';   
-         } 
+	if (pc->prot.ni1.uus1_data[0])
+	{ *p++ = IE_USER_USER; /* UUS info element */
+		*p++ = strlen(pc->prot.ni1.uus1_data) + 1;
+		*p++ = 0x04; /* IA5 chars */
+		strcpy(p, pc->prot.ni1.uus1_data);
+		p += strlen(pc->prot.ni1.uus1_data);
+		pc->prot.ni1.uus1_data[0] = '\0';
+	}
 
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
@@ -903,7 +903,7 @@ l3ni1_release_req(struct l3_process *pc, u_char pr, void *arg)
 {
 	StopAllL3Timer(pc);
 	newl3state(pc, 19);
-	if (!pc->prot.ni1.uus1_data[0]) 
+	if (!pc->prot.ni1.uus1_data[0])
 		l3ni1_message(pc, MT_RELEASE);
 	else
 		l3ni1_msg_with_uus(pc, MT_RELEASE);
@@ -916,9 +916,9 @@ l3ni1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
 	struct sk_buff *skb = arg;
 	int ret;
 
-	if ((ret = l3ni1_get_cause(pc, skb))>0) {
+	if ((ret = l3ni1_get_cause(pc, skb)) > 0) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "RELCMPL get_cause ret(%d)",ret);
+			l3_debug(pc->st, "RELCMPL get_cause ret(%d)", ret);
 	} else if (ret < 0)
 		pc->para.cause = NO_CAUSE;
 	StopAllL3Timer(pc);
@@ -930,7 +930,7 @@ l3ni1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
 #if EXT_BEARER_CAPS
 
 static u_char *
-EncodeASyncParams(u_char * p, u_char si2)
+EncodeASyncParams(u_char *p, u_char si2)
 {				// 7c 06 88  90 21 42 00 bb
 
 	p[0] = 0;
@@ -958,38 +958,38 @@ EncodeASyncParams(u_char * p, u_char si2)
 		p[2] += 3;
 
 	switch (si2 & 0x07) {
-		case 0:
-			p[0] = 66;	// 1200 bit/s
+	case 0:
+		p[0] = 66;	// 1200 bit/s
 
-			break;
-		case 1:
-			p[0] = 88;	// 1200/75 bit/s
+		break;
+	case 1:
+		p[0] = 88;	// 1200/75 bit/s
 
-			break;
-		case 2:
-			p[0] = 87;	// 75/1200 bit/s
+		break;
+	case 2:
+		p[0] = 87;	// 75/1200 bit/s
 
-			break;
-		case 3:
-			p[0] = 67;	// 2400 bit/s
+		break;
+	case 3:
+		p[0] = 67;	// 2400 bit/s
 
-			break;
-		case 4:
-			p[0] = 69;	// 4800 bit/s
+		break;
+	case 4:
+		p[0] = 69;	// 4800 bit/s
 
-			break;
-		case 5:
-			p[0] = 72;	// 9600 bit/s
+		break;
+	case 5:
+		p[0] = 72;	// 9600 bit/s
 
-			break;
-		case 6:
-			p[0] = 73;	// 14400 bit/s
+		break;
+	case 6:
+		p[0] = 73;	// 14400 bit/s
 
-			break;
-		case 7:
-			p[0] = 75;	// 19200 bit/s
+		break;
+	case 7:
+		p[0] = 75;	// 19200 bit/s
 
-			break;
+		break;
 	}
 	return p + 3;
 }
@@ -999,84 +999,84 @@ EncodeSyncParams(u_char si2, u_char ai)
 {
 
 	switch (si2) {
-		case 0:
-			return ai + 2;	// 1200 bit/s
+	case 0:
+		return ai + 2;	// 1200 bit/s
 
-		case 1:
-			return ai + 24;		// 1200/75 bit/s
+	case 1:
+		return ai + 24;		// 1200/75 bit/s
 
-		case 2:
-			return ai + 23;		// 75/1200 bit/s
+	case 2:
+		return ai + 23;		// 75/1200 bit/s
 
-		case 3:
-			return ai + 3;	// 2400 bit/s
+	case 3:
+		return ai + 3;	// 2400 bit/s
 
-		case 4:
-			return ai + 5;	// 4800 bit/s
+	case 4:
+		return ai + 5;	// 4800 bit/s
 
-		case 5:
-			return ai + 8;	// 9600 bit/s
+	case 5:
+		return ai + 8;	// 9600 bit/s
 
-		case 6:
-			return ai + 9;	// 14400 bit/s
+	case 6:
+		return ai + 9;	// 14400 bit/s
 
-		case 7:
-			return ai + 11;		// 19200 bit/s
+	case 7:
+		return ai + 11;		// 19200 bit/s
 
-		case 8:
-			return ai + 14;		// 48000 bit/s
+	case 8:
+		return ai + 14;		// 48000 bit/s
 
-		case 9:
-			return ai + 15;		// 56000 bit/s
+	case 9:
+		return ai + 15;		// 56000 bit/s
 
-		case 15:
-			return ai + 40;		// negotiate bit/s
+	case 15:
+		return ai + 40;		// negotiate bit/s
 
-		default:
-			break;
+	default:
+		break;
 	}
 	return ai;
 }
 
 
 static u_char
-DecodeASyncParams(u_char si2, u_char * p)
+DecodeASyncParams(u_char si2, u_char *p)
 {
 	u_char info;
 
 	switch (p[5]) {
-		case 66:	// 1200 bit/s
+	case 66:	// 1200 bit/s
 
-			break;	// si2 don't change
+		break;	// si2 don't change
 
-		case 88:	// 1200/75 bit/s
+	case 88:	// 1200/75 bit/s
 
-			si2 += 1;
-			break;
-		case 87:	// 75/1200 bit/s
+		si2 += 1;
+		break;
+	case 87:	// 75/1200 bit/s
 
-			si2 += 2;
-			break;
-		case 67:	// 2400 bit/s
+		si2 += 2;
+		break;
+	case 67:	// 2400 bit/s
 
-			si2 += 3;
-			break;
-		case 69:	// 4800 bit/s
+		si2 += 3;
+		break;
+	case 69:	// 4800 bit/s
 
-			si2 += 4;
-			break;
-		case 72:	// 9600 bit/s
+		si2 += 4;
+		break;
+	case 72:	// 9600 bit/s
 
-			si2 += 5;
-			break;
-		case 73:	// 14400 bit/s
+		si2 += 5;
+		break;
+	case 73:	// 14400 bit/s
 
-			si2 += 6;
-			break;
-		case 75:	// 19200 bit/s
+		si2 += 6;
+		break;
+	case 75:	// 19200 bit/s
 
-			si2 += 7;
-			break;
+		si2 += 7;
+		break;
 	}
 
 	info = p[7] & 0x7f;
@@ -1101,39 +1101,39 @@ DecodeSyncParams(u_char si2, u_char info)
 {
 	info &= 0x7f;
 	switch (info) {
-		case 40:	// bit/s negotiation failed  ai := 165 not 175!
+	case 40:	// bit/s negotiation failed  ai := 165 not 175!
 
-			return si2 + 15;
-		case 15:	// 56000 bit/s failed, ai := 0 not 169 !
+		return si2 + 15;
+	case 15:	// 56000 bit/s failed, ai := 0 not 169 !
 
-			return si2 + 9;
-		case 14:	// 48000 bit/s
+		return si2 + 9;
+	case 14:	// 48000 bit/s
 
-			return si2 + 8;
-		case 11:	// 19200 bit/s
+		return si2 + 8;
+	case 11:	// 19200 bit/s
 
-			return si2 + 7;
-		case 9:	// 14400 bit/s
+		return si2 + 7;
+	case 9:	// 14400 bit/s
 
-			return si2 + 6;
-		case 8:	// 9600  bit/s
+		return si2 + 6;
+	case 8:	// 9600  bit/s
 
-			return si2 + 5;
-		case 5:	// 4800  bit/s
+		return si2 + 5;
+	case 5:	// 4800  bit/s
 
-			return si2 + 4;
-		case 3:	// 2400  bit/s
+		return si2 + 4;
+	case 3:	// 2400  bit/s
 
-			return si2 + 3;
-		case 23:	// 75/1200 bit/s
+		return si2 + 3;
+	case 23:	// 75/1200 bit/s
 
-			return si2 + 2;
-		case 24:	// 1200/75 bit/s
+		return si2 + 2;
+	case 24:	// 1200/75 bit/s
 
-			return si2 + 1;
-		default:	// 1200 bit/s
+		return si2 + 1;
+	default:	// 1200 bit/s
 
-			return si2;
+		return si2;
 	}
 }
 
@@ -1144,20 +1144,20 @@ DecodeSI2(struct sk_buff *skb)
 
 	if ((p = findie(skb->data, skb->len, 0x7c, 0))) {
 		switch (p[4] & 0x0f) {
-			case 0x01:
-				if (p[1] == 0x04)	// sync. Bitratenadaption
+		case 0x01:
+			if (p[1] == 0x04)	// sync. Bitratenadaption
 
-					return DecodeSyncParams(160, p[5]);	// V.110/X.30
+				return DecodeSyncParams(160, p[5]);	// V.110/X.30
 
-				else if (p[1] == 0x06)	// async. Bitratenadaption
+			else if (p[1] == 0x06)	// async. Bitratenadaption
 
-					return DecodeASyncParams(192, p);	// V.110/X.30
+				return DecodeASyncParams(192, p);	// V.110/X.30
 
-				break;
-			case 0x08:	// if (p[5] == 0x02) // sync. Bitratenadaption
-				if (p[1] > 3) 
-					return DecodeSyncParams(176, p[5]);	// V.120
-				break;
+			break;
+		case 0x08:	// if (p[5] == 0x02) // sync. Bitratenadaption
+			if (p[1] > 3)
+				return DecodeSyncParams(176, p[5]);	// V.120
+			break;
 		}
 	}
 	return 0;
@@ -1168,7 +1168,7 @@ DecodeSI2(struct sk_buff *skb)
 
 static void
 l3ni1_setup_req(struct l3_process *pc, u_char pr,
-		 void *arg)
+		void *arg)
 {
 	struct sk_buff *skb;
 	u_char tmp[128];
@@ -1191,7 +1191,7 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
 	case 1:	                  /* Telephony                                */
 		*p++ = IE_BEARER;
 		*p++ = 0x3;	  /* Length                                   */
-		*p++ = 0x90;	  /* 3.1khz Audio      			      */
+		*p++ = 0x90;	  /* 3.1khz Audio			      */
 		*p++ = 0x90;	  /* Circuit-Mode 64kbps                      */
 		*p++ = 0xa2;	  /* u-Law Audio                              */
 		break;
@@ -1214,7 +1214,7 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
 		} else
 			sp++;
 	}
-	
+
 	*p++ = IE_KEYPAD;
 	*p++ = strlen(teln);
 	while (*teln)
@@ -1222,7 +1222,7 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
 
 	if (sub)
 		*sub++ = '.';
-	
+
 #if EXT_BEARER_CAPS
 	if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {	// sync. Bitratenadaption, V.110/X.30
 
@@ -1250,7 +1250,7 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
 		*p++ = 0x21;
 		p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
 	} else {
-	  switch (pc->para.setup.si1) {
+		switch (pc->para.setup.si1) {
 		case 1:	                /* Telephony                                */
 			*p++ = IE_LLC;
 			*p++ = 0x3;	/* Length                                   */
@@ -1266,14 +1266,14 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
 			*p++ = 0x88;	/* Coding Std. CCITT, unrestr. dig. Inform. */
 			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */
 			break;
-	  }
+		}
 	}
 #endif
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
-{
+	{
 		return;
-}
+	}
 	memcpy(skb_put(skb, l), tmp, l);
 	L3DelTimer(&pc->timer);
 	L3AddTimer(&pc->timer, T303, CC_T303);
@@ -1375,7 +1375,7 @@ l3ni1_disconnect(struct l3_process *pc, u_char pr, void *arg)
 			cause = 96;
 		else if (ret > 0)
 			cause = 100;
-	} 
+	}
 	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
 		l3ni1_parse_facility(pc->st, pc, pc->callref, p);
 	ret = check_infoelements(pc, skb, ie_DISCONNECT);
@@ -1387,10 +1387,10 @@ l3ni1_disconnect(struct l3_process *pc, u_char pr, void *arg)
 	newl3state(pc, 12);
 	if (cause)
 		newl3state(pc, 19);
-       	if (11 != ret)
+	if (11 != ret)
 		pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
-       	else if (!cause)
-		   l3ni1_release_req(pc, pr, NULL);
+	else if (!cause)
+		l3ni1_release_req(pc, pr, NULL);
 	if (cause) {
 		l3ni1_message_cause(pc, MT_RELEASE, cause);
 		L3AddTimer(&pc->timer, T308, CC_T308_1);
@@ -1456,56 +1456,56 @@ l3ni1_setup(struct l3_process *pc, u_char pr, void *arg)
 		else {
 			pc->para.setup.si2 = 0;
 			switch (p[2] & 0x7f) {
-				case 0x00: /* Speech */
-				case 0x10: /* 3.1 Khz audio */
-					pc->para.setup.si1 = 1;
-					break;
-				case 0x08: /* Unrestricted digital information */
-					pc->para.setup.si1 = 7;
+			case 0x00: /* Speech */
+			case 0x10: /* 3.1 Khz audio */
+				pc->para.setup.si1 = 1;
+				break;
+			case 0x08: /* Unrestricted digital information */
+				pc->para.setup.si1 = 7;
 /* JIM, 05.11.97 I wanna set service indicator 2 */
 #if EXT_BEARER_CAPS
-					pc->para.setup.si2 = DecodeSI2(skb);
+				pc->para.setup.si2 = DecodeSI2(skb);
 #endif
-					break;
-				case 0x09: /* Restricted digital information */
-					pc->para.setup.si1 = 2;
-					break;
-				case 0x11:
-					/* Unrestr. digital information  with 
-					 * tones/announcements ( or 7 kHz audio
-					 */
-					pc->para.setup.si1 = 3;
-					break;
-				case 0x18: /* Video */
-					pc->para.setup.si1 = 4;
-					break;
-				default:
-					err = 2;
-					break;
+				break;
+			case 0x09: /* Restricted digital information */
+				pc->para.setup.si1 = 2;
+				break;
+			case 0x11:
+				/* Unrestr. digital information  with
+				 * tones/announcements ( or 7 kHz audio
+				 */
+				pc->para.setup.si1 = 3;
+				break;
+			case 0x18: /* Video */
+				pc->para.setup.si1 = 4;
+				break;
+			default:
+				err = 2;
+				break;
 			}
 			switch (p[3] & 0x7f) {
-				case 0x40: /* packed mode */
-					pc->para.setup.si1 = 8;
-					break;
-				case 0x10: /* 64 kbit */
-				case 0x11: /* 2*64 kbit */
-				case 0x13: /* 384 kbit */
-				case 0x15: /* 1536 kbit */
-				case 0x17: /* 1920 kbit */
-					pc->para.moderate = p[3] & 0x7f;
-					break;
-				default:
-					err = 3;
-					break;
+			case 0x40: /* packed mode */
+				pc->para.setup.si1 = 8;
+				break;
+			case 0x10: /* 64 kbit */
+			case 0x11: /* 2*64 kbit */
+			case 0x13: /* 384 kbit */
+			case 0x15: /* 1536 kbit */
+			case 0x17: /* 1920 kbit */
+				pc->para.moderate = p[3] & 0x7f;
+				break;
+			default:
+				err = 3;
+				break;
 			}
 		}
 		if (pc->debug & L3_DEB_SI)
 			l3_debug(pc->st, "SI=%d, AI=%d",
-				pc->para.setup.si1, pc->para.setup.si2);
+				 pc->para.setup.si1, pc->para.setup.si2);
 		if (err) {
 			if (pc->debug & L3_DEB_WARN)
 				l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)",
-					p[1], p[2], p[3]);
+					 p[1], p[2], p[3]);
 			pc->para.cause = 100;
 			l3ni1_msg_without_setup(pc, pr, NULL);
 			return;
@@ -1526,17 +1526,17 @@ l3ni1_setup(struct l3_process *pc, u_char pr, void *arg)
 			if ((3 == id) && (0x10 == pc->para.moderate)) {
 				if (pc->debug & L3_DEB_WARN)
 					l3_debug(pc->st, "setup with wrong chid %x",
-						id);
+						 id);
 				pc->para.cause = 100;
 				l3ni1_msg_without_setup(pc, pr, NULL);
 				return;
 			}
 			bcfound++;
-		} else 
-                   { if (pc->debug & L3_DEB_WARN)
-			 l3_debug(pc->st, "setup without bchannel, call waiting");
-                     bcfound++;
-                   } 
+		} else
+		{ if (pc->debug & L3_DEB_WARN)
+				l3_debug(pc->st, "setup without bchannel, call waiting");
+			bcfound++;
+		}
 	} else {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "setup with wrong chid ret %d", id);
@@ -1611,7 +1611,7 @@ static void
 l3ni1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb;
-	u_char tmp[16+40];
+	u_char tmp[16 + 40];
 	u_char *p = tmp;
 	int l;
 	u_char cause = 16;
@@ -1628,14 +1628,14 @@ l3ni1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
 	*p++ = 0x80;
 	*p++ = cause | 0x80;
 
-        if (pc->prot.ni1.uus1_data[0])
-	 { *p++ = IE_USER_USER; /* UUS info element */
-           *p++ = strlen(pc->prot.ni1.uus1_data) + 1;
-           *p++ = 0x04; /* IA5 chars */
-           strcpy(p,pc->prot.ni1.uus1_data);
-           p += strlen(pc->prot.ni1.uus1_data);
-           pc->prot.ni1.uus1_data[0] = '\0';   
-         } 
+	if (pc->prot.ni1.uus1_data[0])
+	{ *p++ = IE_USER_USER; /* UUS info element */
+		*p++ = strlen(pc->prot.ni1.uus1_data) + 1;
+		*p++ = 0x04; /* IA5 chars */
+		strcpy(p, pc->prot.ni1.uus1_data);
+		p += strlen(pc->prot.ni1.uus1_data);
+		pc->prot.ni1.uus1_data[0] = '\0';
+	}
 
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l)))
@@ -1648,18 +1648,18 @@ l3ni1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
 
 static void
 l3ni1_setup_rsp(struct l3_process *pc, u_char pr,
-		 void *arg)
-{
-        if (!pc->para.bchannel) 
-	 { if (pc->debug & L3_DEB_WARN)
-	       l3_debug(pc->st, "D-chan connect for waiting call");
-           l3ni1_disconnect_req(pc, pr, arg);
-           return;
-         }
+		void *arg)
+{
+	if (!pc->para.bchannel)
+	{ if (pc->debug & L3_DEB_WARN)
+			l3_debug(pc->st, "D-chan connect for waiting call");
+		l3ni1_disconnect_req(pc, pr, arg);
+		return;
+	}
 	newl3state(pc, 8);
 	if (pc->debug & L3_DEB_WARN)
 		l3_debug(pc->st, "D-chan connect for waiting call");
-	l3ni1_message_plus_chid(pc, MT_CONNECT); /* GE 05/09/00 */ 
+	l3ni1_message_plus_chid(pc, MT_CONNECT); /* GE 05/09/00 */
 	L3DelTimer(&pc->timer);
 	L3AddTimer(&pc->timer, T313, CC_T313);
 }
@@ -1716,26 +1716,26 @@ l3ni1_release(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb = arg;
 	u_char *p;
-	int ret, cause=0;
+	int ret, cause = 0;
 
 	StopAllL3Timer(pc);
-	if ((ret = l3ni1_get_cause(pc, skb))>0) {
+	if ((ret = l3ni1_get_cause(pc, skb)) > 0) {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "REL get_cause ret(%d)", ret);
-	} else if (ret<0)
+	} else if (ret < 0)
 		pc->para.cause = NO_CAUSE;
 	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
 		l3ni1_parse_facility(pc->st, pc, pc->callref, p);
 	}
-	if ((ret<0) && (pc->state != 11))
+	if ((ret < 0) && (pc->state != 11))
 		cause = 96;
-	else if (ret>0)
+	else if (ret > 0)
 		cause = 100;
 	ret = check_infoelements(pc, skb, ie_RELEASE);
 	if (ERR_IE_COMPREHENSION == ret)
 		cause = 96;
 	else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause))
-		cause = 99;  
+		cause = 99;
 	if (cause)
 		l3ni1_message_cause(pc, MT_RELEASE_COMPLETE, cause);
 	else
@@ -1747,27 +1747,27 @@ l3ni1_release(struct l3_process *pc, u_char pr, void *arg)
 
 static void
 l3ni1_alert_req(struct l3_process *pc, u_char pr,
-		 void *arg)
+		void *arg)
 {
 	newl3state(pc, 7);
-	if (!pc->prot.ni1.uus1_data[0]) 
+	if (!pc->prot.ni1.uus1_data[0])
 		l3ni1_message(pc, MT_ALERTING);
 	else
-		l3ni1_msg_with_uus(pc, MT_ALERTING); 
+		l3ni1_msg_with_uus(pc, MT_ALERTING);
 }
 
 static void
 l3ni1_proceed_req(struct l3_process *pc, u_char pr,
-		   void *arg)
+		  void *arg)
 {
 	newl3state(pc, 9);
 	l3ni1_message(pc, MT_CALL_PROCEEDING);
-	pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc); 
+	pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc);
 }
 
 static void
 l3ni1_setup_ack_req(struct l3_process *pc, u_char pr,
-		   void *arg)
+		    void *arg)
 {
 	newl3state(pc, 25);
 	L3DelTimer(&pc->timer);
@@ -1781,22 +1781,22 @@ l3ni1_setup_ack_req(struct l3_process *pc, u_char pr,
 static void
 l3ni1_deliver_display(struct l3_process *pc, int pr, u_char *infp)
 {       u_char len;
-        isdn_ctrl ic; 
+	isdn_ctrl ic;
 	struct IsdnCardState *cs;
-        char *p; 
+	char *p;
 
-        if (*infp++ != IE_DISPLAY) return;
-        if ((len = *infp++) > 80) return; /* total length <= 82 */
+	if (*infp++ != IE_DISPLAY) return;
+	if ((len = *infp++) > 80) return; /* total length <= 82 */
 	if (!pc->chan) return;
 
-	p = ic.parm.display; 
-        while (len--)
-	  *p++ = *infp++;
+	p = ic.parm.display;
+	while (len--)
+		*p++ = *infp++;
 	*p = '\0';
 	ic.command = ISDN_STAT_DISPLAY;
 	cs = pc->st->l1.hardware;
 	ic.driver = cs->myid;
-	ic.arg = pc->chan->chan; 
+	ic.arg = pc->chan->chan;
 	cs->iif.statcallb(&ic);
 } /* l3ni1_deliver_display */
 
@@ -1814,37 +1814,37 @@ l3ni1_progress(struct l3_process *pc, u_char pr, void *arg)
 			pc->para.cause = 100;
 		} else if (!(p[2] & 0x70)) {
 			switch (p[2]) {
-				case 0x80:
+			case 0x80:
+			case 0x81:
+			case 0x82:
+			case 0x84:
+			case 0x85:
+			case 0x87:
+			case 0x8a:
+				switch (p[3]) {
 				case 0x81:
 				case 0x82:
+				case 0x83:
 				case 0x84:
-				case 0x85:
-				case 0x87:
-				case 0x8a:
-					switch (p[3]) {
-						case 0x81:
-						case 0x82:
-						case 0x83:
-						case 0x84:
-						case 0x88:
-							break;
-						default:
-							err = 2;
-							pc->para.cause = 100;
-							break;
-					}
+				case 0x88:
 					break;
 				default:
-					err = 3;
+					err = 2;
 					pc->para.cause = 100;
 					break;
+				}
+				break;
+			default:
+				err = 3;
+				pc->para.cause = 100;
+				break;
 			}
 		}
 	} else {
 		pc->para.cause = 96;
 		err = 4;
 	}
-	if (err) {	
+	if (err) {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "progress error %d", err);
 		l3ni1_status_send(pc, pr, NULL);
@@ -1871,21 +1871,21 @@ l3ni1_notify(struct l3_process *pc, u_char pr, void *arg)
 			pc->para.cause = 100;
 		} else {
 			switch (p[2]) {
-				case 0x80:
-				case 0x81:
-				case 0x82:
-					break;
-				default:
-					pc->para.cause = 100;
-					err = 2;
-					break;
+			case 0x80:
+			case 0x81:
+			case 0x82:
+				break;
+			default:
+				pc->para.cause = 100;
+				err = 2;
+				break;
 			}
 		}
 	} else {
 		pc->para.cause = 96;
 		err = 3;
 	}
-	if (err) {	
+	if (err) {
 		if (pc->debug & L3_DEB_WARN)
 			l3_debug(pc->st, "notify error %d", err);
 		l3ni1_status_send(pc, pr, NULL);
@@ -1908,7 +1908,7 @@ l3ni1_status_enq(struct l3_process *pc, u_char pr, void *arg)
 	ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);
 	l3ni1_std_ie_err(pc, ret);
 	pc->para.cause = 30; /* response to STATUS_ENQUIRY */
-        l3ni1_status_send(pc, pr, NULL);
+	l3ni1_status_send(pc, pr, NULL);
 }
 
 static void
@@ -1942,68 +1942,68 @@ static void l3ni1_redir_req(struct l3_process *pc, u_char pr, void *arg)
 	struct sk_buff *skb;
 	u_char tmp[128];
 	u_char *p = tmp;
-        u_char *subp;
-        u_char len_phone = 0;
-        u_char len_sub = 0;
-	int l; 
-
-
-        strcpy(pc->prot.ni1.uus1_data,pc->chan->setup.eazmsn); /* copy uus element if available */
-        if (!pc->chan->setup.phone[0])
-          { pc->para.cause = -1;
-            l3ni1_disconnect_req(pc,pr,arg); /* disconnect immediately */
-            return;
-          } /* only uus */
- 
-        if (pc->prot.ni1.invoke_id) 
-          free_invoke_id(pc->st,pc->prot.ni1.invoke_id);
- 
-        if (!(pc->prot.ni1.invoke_id = new_invoke_id(pc->st))) 
-          return;
-
-        MsgHead(p, pc->callref, MT_FACILITY);
-
-        for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */
-        if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */ 
+	u_char *subp;
+	u_char len_phone = 0;
+	u_char len_sub = 0;
+	int l;
+
+
+	strcpy(pc->prot.ni1.uus1_data, pc->chan->setup.eazmsn); /* copy uus element if available */
+	if (!pc->chan->setup.phone[0])
+	{ pc->para.cause = -1;
+		l3ni1_disconnect_req(pc, pr, arg); /* disconnect immediately */
+		return;
+	} /* only uus */
+
+	if (pc->prot.ni1.invoke_id)
+		free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
+
+	if (!(pc->prot.ni1.invoke_id = new_invoke_id(pc->st)))
+		return;
+
+	MsgHead(p, pc->callref, MT_FACILITY);
+
+	for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */
+	if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */
 
 	*p++ = 0x1c;   /* Facility info element */
-        *p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */
-        *p++ = 0x91;  /* remote operations protocol */
-        *p++ = 0xa1;  /* invoke component */
-	  
-        *p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */
-        *p++ = 0x02;  /* invoke id tag, integer */
+	*p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */
+	*p++ = 0x91;  /* remote operations protocol */
+	*p++ = 0xa1;  /* invoke component */
+
+	*p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */
+	*p++ = 0x02;  /* invoke id tag, integer */
 	*p++ = 0x01;  /* length */
-        *p++ = pc->prot.ni1.invoke_id;  /* invoke id */ 
-        *p++ = 0x02;  /* operation value tag, integer */
+	*p++ = pc->prot.ni1.invoke_id;  /* invoke id */
+	*p++ = 0x02;  /* operation value tag, integer */
 	*p++ = 0x01;  /* length */
-        *p++ = 0x0D;  /* Call Deflect */
-	  
-        *p++ = 0x30;  /* sequence phone number */
-        *p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */
-	  
-        *p++ = 0x30;  /* Deflected to UserNumber */
-        *p++ = len_phone+2+len_sub; /* length */
-        *p++ = 0x80; /* NumberDigits */
+	*p++ = 0x0D;  /* Call Deflect */
+
+	*p++ = 0x30;  /* sequence phone number */
+	*p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */
+
+	*p++ = 0x30;  /* Deflected to UserNumber */
+	*p++ = len_phone + 2 + len_sub; /* length */
+	*p++ = 0x80; /* NumberDigits */
 	*p++ = len_phone; /* length */
-        for (l = 0; l < len_phone; l++)
-	 *p++ = pc->chan->setup.phone[l];
+	for (l = 0; l < len_phone; l++)
+		*p++ = pc->chan->setup.phone[l];
 
-        if (len_sub)
-	  { *p++ = 0x04; /* called party subaddress */
-            *p++ = len_sub - 2;
-            while (*subp) *p++ = *subp++;
-          }
+	if (len_sub)
+	{ *p++ = 0x04; /* called party subaddress */
+		*p++ = len_sub - 2;
+		while (*subp) *p++ = *subp++;
+	}
 
-        *p++ = 0x01; /* screening identifier */
-        *p++ = 0x01;
-        *p++ = pc->chan->setup.screen;
+	*p++ = 0x01; /* screening identifier */
+	*p++ = 0x01;
+	*p++ = pc->chan->setup.screen;
 
 	l = p - tmp;
 	if (!(skb = l3_alloc_skb(l))) return;
 	memcpy(skb_put(skb, l), tmp, l);
 
-        l3_msg(pc->st, DL_DATA | REQUEST, skb);
+	l3_msg(pc->st, DL_DATA | REQUEST, skb);
 } /* l3ni1_redir_req */
 
 /********************************************/
@@ -2011,8 +2011,8 @@ static void l3ni1_redir_req(struct l3_process *pc, u_char pr, void *arg)
 /********************************************/
 static void l3ni1_redir_req_early(struct l3_process *pc, u_char pr, void *arg)
 {
-  l3ni1_proceed_req(pc,pr,arg);
-  l3ni1_redir_req(pc,pr,arg);
+	l3ni1_proceed_req(pc, pr, arg);
+	l3ni1_redir_req(pc, pr, arg);
 } /* l3ni1_redir_req_early */
 
 /***********************************************/
@@ -2022,108 +2022,108 @@ static void l3ni1_redir_req_early(struct l3_process *pc, u_char pr, void *arg)
 /***********************************************/
 static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic)
 { u_char id;
-  u_char temp[265];
-  u_char *p = temp;
-  int i, l, proc_len; 
-  struct sk_buff *skb;
-  struct l3_process *pc = NULL;
-
-  switch (ic->arg)
-   { case NI1_CMD_INVOKE:
-       if (ic->parm.ni1_io.datalen < 0) return(-2); /* invalid parameter */ 
-
-       for (proc_len = 1, i = ic->parm.ni1_io.proc >> 8; i; i++) 
-         i = i >> 8; /* add one byte */    
-       l = ic->parm.ni1_io.datalen + proc_len + 8; /* length excluding ie header */
-       if (l > 255) 
-         return(-2); /* too long */
-
-       if (!(id = new_invoke_id(st))) 
-         return(0); /* first get a invoke id -> return if no available */
-       
-       i = -1; 
-       MsgHead(p, i, MT_FACILITY); /* build message head */
-       *p++ = 0x1C; /* Facility IE */
-       *p++ = l; /* length of ie */
-       *p++ = 0x91; /* remote operations */
-       *p++ = 0xA1; /* invoke */
-       *p++ = l - 3; /* length of invoke */
-       *p++ = 0x02; /* invoke id tag */
-       *p++ = 0x01; /* length is 1 */
-       *p++ = id; /* invoke id */
-       *p++ = 0x02; /* operation */
-       *p++ = proc_len; /* length of operation */
-       
-       for (i = proc_len; i; i--)
-         *p++ = (ic->parm.ni1_io.proc >> (i-1)) & 0xFF;
-       memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */
-       l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */         
-
-       if (ic->parm.ni1_io.timeout > 0)
-        if (!(pc = ni1_new_l3_process(st, -1)))
-          { free_invoke_id(st, id);
-            return(-2);
-          } 
-       pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; /* remember id */ 
-       pc->prot.ni1.proc = ic->parm.ni1_io.proc; /* and procedure */
-
-       if (!(skb = l3_alloc_skb(l))) 
-         { free_invoke_id(st, id);
-           if (pc) ni1_release_l3_process(pc);
-           return(-2);
-         }
-       memcpy(skb_put(skb, l), temp, l);
-       
-       if (pc)
-        { pc->prot.ni1.invoke_id = id; /* remember id */
-          L3AddTimer(&pc->timer, ic->parm.ni1_io.timeout, CC_TNI1_IO | REQUEST);
-        }
-       
-       l3_msg(st, DL_DATA | REQUEST, skb);
-       ic->parm.ni1_io.hl_id = id; /* return id */
-       return(0);
-
-     case NI1_CMD_INVOKE_ABORT:
-       if ((pc = l3ni1_search_dummy_proc(st, ic->parm.ni1_io.hl_id)))
-	{ L3DelTimer(&pc->timer); /* remove timer */
-          ni1_release_l3_process(pc);
-          return(0); 
-        } 
-       else
-	{ l3_debug(st, "l3ni1_cmd_global abort unknown id");
-          return(-2);
-        } 
-       break;
-    
-     default: 
-       l3_debug(st, "l3ni1_cmd_global unknown cmd 0x%lx", ic->arg);
-       return(-1);  
-   } /* switch ic-> arg */
-  return(-1);
+	u_char temp[265];
+	u_char *p = temp;
+	int i, l, proc_len;
+	struct sk_buff *skb;
+	struct l3_process *pc = NULL;
+
+	switch (ic->arg)
+	{ case NI1_CMD_INVOKE:
+			if (ic->parm.ni1_io.datalen < 0) return (-2); /* invalid parameter */
+
+			for (proc_len = 1, i = ic->parm.ni1_io.proc >> 8; i; i++)
+				i = i >> 8; /* add one byte */
+			l = ic->parm.ni1_io.datalen + proc_len + 8; /* length excluding ie header */
+			if (l > 255)
+				return (-2); /* too long */
+
+			if (!(id = new_invoke_id(st)))
+				return (0); /* first get a invoke id -> return if no available */
+
+			i = -1;
+			MsgHead(p, i, MT_FACILITY); /* build message head */
+			*p++ = 0x1C; /* Facility IE */
+			*p++ = l; /* length of ie */
+			*p++ = 0x91; /* remote operations */
+			*p++ = 0xA1; /* invoke */
+			*p++ = l - 3; /* length of invoke */
+			*p++ = 0x02; /* invoke id tag */
+			*p++ = 0x01; /* length is 1 */
+			*p++ = id; /* invoke id */
+			*p++ = 0x02; /* operation */
+			*p++ = proc_len; /* length of operation */
+
+			for (i = proc_len; i; i--)
+				*p++ = (ic->parm.ni1_io.proc >> (i - 1)) & 0xFF;
+			memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */
+			l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */
+
+			if (ic->parm.ni1_io.timeout > 0)
+				if (!(pc = ni1_new_l3_process(st, -1)))
+				{ free_invoke_id(st, id);
+					return (-2);
+				}
+			pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; /* remember id */
+			pc->prot.ni1.proc = ic->parm.ni1_io.proc; /* and procedure */
+
+			if (!(skb = l3_alloc_skb(l)))
+			{ free_invoke_id(st, id);
+				if (pc) ni1_release_l3_process(pc);
+				return (-2);
+			}
+			memcpy(skb_put(skb, l), temp, l);
+
+			if (pc)
+			{ pc->prot.ni1.invoke_id = id; /* remember id */
+				L3AddTimer(&pc->timer, ic->parm.ni1_io.timeout, CC_TNI1_IO | REQUEST);
+			}
+
+			l3_msg(st, DL_DATA | REQUEST, skb);
+			ic->parm.ni1_io.hl_id = id; /* return id */
+			return (0);
+
+	case NI1_CMD_INVOKE_ABORT:
+		if ((pc = l3ni1_search_dummy_proc(st, ic->parm.ni1_io.hl_id)))
+		{ L3DelTimer(&pc->timer); /* remove timer */
+			ni1_release_l3_process(pc);
+			return (0);
+		}
+		else
+		{ l3_debug(st, "l3ni1_cmd_global abort unknown id");
+			return (-2);
+		}
+		break;
+
+	default:
+		l3_debug(st, "l3ni1_cmd_global unknown cmd 0x%lx", ic->arg);
+		return (-1);
+	} /* switch ic-> arg */
+	return (-1);
 } /* l3ni1_cmd_global */
 
-static void 
+static void
 l3ni1_io_timer(struct l3_process *pc)
 { isdn_ctrl ic;
-  struct IsdnCardState *cs = pc->st->l1.hardware;
+	struct IsdnCardState *cs = pc->st->l1.hardware;
 
-  L3DelTimer(&pc->timer); /* remove timer */
+	L3DelTimer(&pc->timer); /* remove timer */
 
-  ic.driver = cs->myid;
-  ic.command = ISDN_STAT_PROT;
-  ic.arg = NI1_STAT_INVOKE_ERR;
-  ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
-  ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
-  ic.parm.ni1_io.proc = pc->prot.ni1.proc;
-  ic.parm.ni1_io.timeout= -1;
-  ic.parm.ni1_io.datalen = 0;
-  ic.parm.ni1_io.data = NULL;
-  free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
-  pc->prot.ni1.invoke_id = 0; /* reset id */
+	ic.driver = cs->myid;
+	ic.command = ISDN_STAT_PROT;
+	ic.arg = NI1_STAT_INVOKE_ERR;
+	ic.parm.ni1_io.hl_id = pc->prot.ni1.invoke_id;
+	ic.parm.ni1_io.ll_id = pc->prot.ni1.ll_id;
+	ic.parm.ni1_io.proc = pc->prot.ni1.proc;
+	ic.parm.ni1_io.timeout = -1;
+	ic.parm.ni1_io.datalen = 0;
+	ic.parm.ni1_io.data = NULL;
+	free_invoke_id(pc->st, pc->prot.ni1.invoke_id);
+	pc->prot.ni1.invoke_id = 0; /* reset id */
 
-  cs->iif.statcallb(&ic);
+	cs->iif.statcallb(&ic);
 
-  ni1_release_l3_process(pc); 
+	ni1_release_l3_process(pc);
 } /* l3ni1_io_timer */
 
 static void
@@ -2293,12 +2293,12 @@ l3ni1_status(struct l3_process *pc, u_char pr, void *arg)
 {
 	u_char *p;
 	struct sk_buff *skb = arg;
-	int ret; 
+	int ret;
 	u_char cause = 0, callState = 0;
-	
+
 	if ((ret = l3ni1_get_cause(pc, skb))) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "STATUS get_cause ret(%d)",ret);
+			l3_debug(pc->st, "STATUS get_cause ret(%d)", ret);
 		if (ret < 0)
 			cause = 96;
 		else if (ret > 0)
@@ -2323,9 +2323,9 @@ l3ni1_status(struct l3_process *pc, u_char pr, void *arg)
 	}
 	if (cause) {
 		u_char tmp;
-		
+
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "STATUS error(%d/%d)",ret,cause);
+			l3_debug(pc->st, "STATUS error(%d/%d)", ret, cause);
 		tmp = pc->para.cause;
 		pc->para.cause = cause;
 		l3ni1_status_send(pc, 0, NULL);
@@ -2351,10 +2351,10 @@ l3ni1_facility(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb = arg;
 	int ret;
-	
+
 	ret = check_infoelements(pc, skb, ie_FACILITY);
 	l3ni1_std_ie_err(pc, ret);
- 	  {
+	{
 		u_char *p;
 		if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
 			l3ni1_parse_facility(pc->st, pc, pc->callref, p);
@@ -2403,7 +2403,7 @@ l3ni1_suspend_ack(struct l3_process *pc, u_char pr, void *arg)
 	/* We don't handle suspend_ack for IE errors now */
 	if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "SUSPACK check ie(%d)",ret);
+			l3_debug(pc->st, "SUSPACK check ie(%d)", ret);
 	ni1_release_l3_process(pc);
 }
 
@@ -2415,8 +2415,8 @@ l3ni1_suspend_rej(struct l3_process *pc, u_char pr, void *arg)
 
 	if ((ret = l3ni1_get_cause(pc, skb))) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)",ret);
-		if (ret < 0) 
+			l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)", ret);
+		if (ret < 0)
 			pc->para.cause = 96;
 		else
 			pc->para.cause = 100;
@@ -2507,8 +2507,8 @@ l3ni1_resume_rej(struct l3_process *pc, u_char pr, void *arg)
 
 	if ((ret = l3ni1_get_cause(pc, skb))) {
 		if (pc->debug & L3_DEB_WARN)
-			l3_debug(pc->st, "RES_REJ get_cause ret(%d)",ret);
-		if (ret < 0) 
+			l3_debug(pc->st, "RES_REJ get_cause ret(%d)", ret);
+		if (ret < 0)
 			pc->para.cause = 96;
 		else
 			pc->para.cause = 100;
@@ -2562,7 +2562,7 @@ l3ni1_global_restart(struct l3_process *pc, u_char pr, void *arg)
 			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
 		else if (up->para.bchannel == chan)
 			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
-		
+
 		up = up->next;
 	}
 	p = tmp;
@@ -2586,112 +2586,112 @@ l3ni1_global_restart(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3ni1_dl_reset(struct l3_process *pc, u_char pr, void *arg)
 {
-        pc->para.cause = 0x29;          /* Temporary failure */
-        pc->para.loc = 0;
-        l3ni1_disconnect_req(pc, pr, NULL);
-        pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
+	pc->para.cause = 0x29;          /* Temporary failure */
+	pc->para.loc = 0;
+	l3ni1_disconnect_req(pc, pr, NULL);
+	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
 }
 
 static void
 l3ni1_dl_release(struct l3_process *pc, u_char pr, void *arg)
 {
-        newl3state(pc, 0);
-        pc->para.cause = 0x1b;          /* Destination out of order */
-        pc->para.loc = 0;
-        pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
-        release_l3_process(pc);
+	newl3state(pc, 0);
+	pc->para.cause = 0x1b;          /* Destination out of order */
+	pc->para.loc = 0;
+	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
+	release_l3_process(pc);
 }
 
 static void
 l3ni1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg)
 {
-        L3DelTimer(&pc->timer);
-        L3AddTimer(&pc->timer, T309, CC_T309);
-        l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL);
+	L3DelTimer(&pc->timer);
+	L3AddTimer(&pc->timer, T309, CC_T309);
+	l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL);
 }
- 
+
 static void
 l3ni1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg)
 {
 	L3DelTimer(&pc->timer);
- 
- 	pc->para.cause = 0x1F; /* normal, unspecified */
+
+	pc->para.cause = 0x1F; /* normal, unspecified */
 	l3ni1_status_send(pc, 0, NULL);
 }
 
-static void l3ni1_SendSpid( struct l3_process *pc, u_char pr, struct sk_buff *skb, int iNewState )
+static void l3ni1_SendSpid(struct l3_process *pc, u_char pr, struct sk_buff *skb, int iNewState)
 {
-	u_char         * p;
-	char           * pSPID;
-	struct Channel * pChan = pc->st->lli.userdata;
-	int              l;
+	u_char *p;
+	char *pSPID;
+	struct Channel *pChan = pc->st->lli.userdata;
+	int l;
 
-	if ( skb )
-		dev_kfree_skb( skb);
+	if (skb)
+		dev_kfree_skb(skb);
 
-	if ( !( pSPID = strchr( pChan->setup.eazmsn, ':' ) ) )
+	if (!(pSPID = strchr(pChan->setup.eazmsn, ':')))
 	{
-		printk( KERN_ERR "SPID not supplied in EAZMSN %s\n", pChan->setup.eazmsn );
-		newl3state( pc, 0 );
-		pc->st->l3.l3l2( pc->st, DL_RELEASE | REQUEST, NULL );
+		printk(KERN_ERR "SPID not supplied in EAZMSN %s\n", pChan->setup.eazmsn);
+		newl3state(pc, 0);
+		pc->st->l3.l3l2(pc->st, DL_RELEASE | REQUEST, NULL);
 		return;
 	}
 
-	l = strlen( ++pSPID );
-	if ( !( skb = l3_alloc_skb( 5+l ) ) )
+	l = strlen(++pSPID);
+	if (!(skb = l3_alloc_skb(5 + l)))
 	{
-		printk( KERN_ERR "HiSax can't get memory to send SPID\n" );
+		printk(KERN_ERR "HiSax can't get memory to send SPID\n");
 		return;
 	}
 
-	p = skb_put( skb, 5 );
+	p = skb_put(skb, 5);
 	*p++ = PROTO_DIS_EURO;
 	*p++ = 0;
 	*p++ = MT_INFORMATION;
 	*p++ = IE_SPID;
 	*p++ = l;
 
-	memcpy( skb_put( skb, l ), pSPID, l );
+	memcpy(skb_put(skb, l), pSPID, l);
 
-	newl3state( pc, iNewState );
+	newl3state(pc, iNewState);
 
-	L3DelTimer( &pc->timer );
-	L3AddTimer( &pc->timer, TSPID, CC_TSPID );
+	L3DelTimer(&pc->timer);
+	L3AddTimer(&pc->timer, TSPID, CC_TSPID);
 
-	pc->st->l3.l3l2( pc->st, DL_DATA | REQUEST, skb );
+	pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
 }
 
-static void l3ni1_spid_send( struct l3_process *pc, u_char pr, void *arg )
+static void l3ni1_spid_send(struct l3_process *pc, u_char pr, void *arg)
 {
-	l3ni1_SendSpid( pc, pr, arg, 20 );
+	l3ni1_SendSpid(pc, pr, arg, 20);
 }
 
-static void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
+static void l3ni1_spid_epid(struct l3_process *pc, u_char pr, void *arg)
 {
 	struct sk_buff *skb = arg;
 
-	if ( skb->data[ 1 ] == 0 )
-		if ( skb->data[ 3 ] == IE_ENDPOINT_ID )
+	if (skb->data[1] == 0)
+		if (skb->data[3] == IE_ENDPOINT_ID)
 		{
-			L3DelTimer( &pc->timer );
-			newl3state( pc, 0 );
-			l3_msg( pc->st, DL_ESTABLISH | CONFIRM, NULL );
+			L3DelTimer(&pc->timer);
+			newl3state(pc, 0);
+			l3_msg(pc->st, DL_ESTABLISH | CONFIRM, NULL);
 		}
-	dev_kfree_skb( skb);
+	dev_kfree_skb(skb);
 }
 
-static void l3ni1_spid_tout( struct l3_process *pc, u_char pr, void *arg )
+static void l3ni1_spid_tout(struct l3_process *pc, u_char pr, void *arg)
 {
-	if ( pc->state < 22 )
-		l3ni1_SendSpid( pc, pr, arg, pc->state+1 );
+	if (pc->state < 22)
+		l3ni1_SendSpid(pc, pr, arg, pc->state + 1);
 	else
 	{
-		L3DelTimer( &pc->timer );
-		dev_kfree_skb( arg);
+		L3DelTimer(&pc->timer);
+		dev_kfree_skb(arg);
 
-		printk( KERN_ERR "SPID not accepted\n" );
-		newl3state( pc, 0 );
-		pc->st->l3.l3l2( pc->st, DL_RELEASE | REQUEST, NULL );
+		printk(KERN_ERR "SPID not accepted\n");
+		newl3state(pc, 0);
+		pc->st->l3.l3l2(pc->st, DL_RELEASE | REQUEST, NULL);
 	}
 }
 
@@ -2724,12 +2724,12 @@ static struct stateentry downstatelist[] =
 	 CC_SETUP | RESPONSE, l3ni1_setup_rsp},
 	{SBIT(10),
 	 CC_SUSPEND | REQUEST, l3ni1_suspend_req},
-        {SBIT(7) | SBIT(9) | SBIT(25),
-         CC_REDIR | REQUEST, l3ni1_redir_req},
-        {SBIT(6),
-         CC_REDIR | REQUEST, l3ni1_redir_req_early},
-        {SBIT(9) | SBIT(25),
-         CC_DISCONNECT | REQUEST, l3ni1_disconnect_req},
+	{SBIT(7) | SBIT(9) | SBIT(25),
+	 CC_REDIR | REQUEST, l3ni1_redir_req},
+	{SBIT(6),
+	 CC_REDIR | REQUEST, l3ni1_redir_req_early},
+	{SBIT(9) | SBIT(25),
+	 CC_DISCONNECT | REQUEST, l3ni1_disconnect_req},
 	{SBIT(25),
 	 CC_T302, l3ni1_t302},
 	{SBIT(1),
@@ -2752,8 +2752,8 @@ static struct stateentry downstatelist[] =
 	 CC_T308_2, l3ni1_t308_2},
 	{SBIT(10),
 	 CC_T309, l3ni1_dl_release},
-	{ SBIT( 20 ) | SBIT( 21 ) | SBIT( 22 ),
-	 CC_TSPID, l3ni1_spid_tout },
+	{ SBIT(20) | SBIT(21) | SBIT(22),
+	  CC_TSPID, l3ni1_spid_tout },
 };
 
 static struct stateentry datastatelist[] =
@@ -2815,22 +2815,22 @@ static struct stateentry globalmes_list[] =
 	{SBIT(0),
 	 MT_RESTART, l3ni1_global_restart},
 /*	{SBIT(1),
-	 MT_RESTART_ACKNOWLEDGE, l3ni1_restart_ack},
+	MT_RESTART_ACKNOWLEDGE, l3ni1_restart_ack},
 */
-	{ SBIT( 0 ), MT_DL_ESTABLISHED, l3ni1_spid_send },
-	{ SBIT( 20 ) | SBIT( 21 ) | SBIT( 22 ), MT_INFORMATION, l3ni1_spid_epid },
+	{ SBIT(0), MT_DL_ESTABLISHED, l3ni1_spid_send },
+	{ SBIT(20) | SBIT(21) | SBIT(22), MT_INFORMATION, l3ni1_spid_epid },
 };
 
 static struct stateentry manstatelist[] =
 {
-        {SBIT(2),
-         DL_ESTABLISH | INDICATION, l3ni1_dl_reset},
-        {SBIT(10),
-         DL_ESTABLISH | CONFIRM, l3ni1_dl_reest_status},
-        {SBIT(10),
-         DL_RELEASE | INDICATION, l3ni1_dl_reestablish},
-        {ALL_STATES,
-         DL_RELEASE | INDICATION, l3ni1_dl_release},
+	{SBIT(2),
+	 DL_ESTABLISH | INDICATION, l3ni1_dl_reset},
+	{SBIT(10),
+	 DL_ESTABLISH | CONFIRM, l3ni1_dl_reest_status},
+	{SBIT(10),
+	 DL_RELEASE | INDICATION, l3ni1_dl_reestablish},
+	{ALL_STATES,
+	 DL_RELEASE | INDICATION, l3ni1_dl_release},
 };
 
 /* *INDENT-ON* */
@@ -2845,7 +2845,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 	int i;
 	struct l3_process *proc = st->l3.global;
 
-	if ( skb )	
+	if (skb)
 		proc->callref = skb->data[2]; /* cr flag */
 	else
 		proc->callref = 0;
@@ -2856,13 +2856,13 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 	if (i == ARRAY_SIZE(globalmes_list)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1 global state %d mt %x unhandled",
-				proc->state, mt);
+				 proc->state, mt);
 		}
 		MsgHead(p, proc->callref, MT_STATUS);
 		*p++ = IE_CAUSE;
 		*p++ = 0x2;
 		*p++ = 0x80;
-		*p++ = 81 |0x80;	/* invalid cr */
+		*p++ = 81 | 0x80;	/* invalid cr */
 		*p++ = 0x14;		/* CallState */
 		*p++ = 0x1;
 		*p++ = proc->state & 0x3f;
@@ -2874,7 +2874,7 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 	} else {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1 global %d mt %x",
-				proc->state, mt);
+				 proc->state, mt);
 		}
 		globalmes_list[i].rout(proc, mt, skb);
 	}
@@ -2890,23 +2890,23 @@ ni1up(struct PStack *st, int pr, void *arg)
 	struct l3_process *proc;
 
 	switch (pr) {
-		case (DL_DATA | INDICATION):
-		case (DL_UNIT_DATA | INDICATION):
-			break;
-		case (DL_ESTABLISH | INDICATION):
-		case (DL_RELEASE | INDICATION):
-		case (DL_RELEASE | CONFIRM):
-			l3_msg(st, pr, arg);
-			return;
-			break;
+	case (DL_DATA | INDICATION):
+	case (DL_UNIT_DATA | INDICATION):
+		break;
+	case (DL_ESTABLISH | INDICATION):
+	case (DL_RELEASE | INDICATION):
+	case (DL_RELEASE | CONFIRM):
+		l3_msg(st, pr, arg);
+		return;
+		break;
 
-		case (DL_ESTABLISH | CONFIRM):
-			global_handler( st, MT_DL_ESTABLISHED, NULL );
-			return;
+	case (DL_ESTABLISH | CONFIRM):
+		global_handler(st, MT_DL_ESTABLISHED, NULL);
+		return;
 
-		default:
-			printk(KERN_ERR "HiSax ni1up unknown pr=%04x\n", pr);
-			return;
+	default:
+		printk(KERN_ERR "HiSax ni1up unknown pr=%04x\n", pr);
+		return;
 	}
 	if (skb->len < 3) {
 		l3_debug(st, "ni1up frame too short(%d)", skb->len);
@@ -2941,10 +2941,10 @@ ni1up(struct PStack *st, int pr, void *arg)
 		if (mt == MT_FACILITY)
 		{
 			if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
-				l3ni1_parse_facility(st, NULL, 
-					(pr == (DL_DATA | INDICATION)) ? -1 : -2, p); 
+				l3ni1_parse_facility(st, NULL,
+						     (pr == (DL_DATA | INDICATION)) ? -1 : -2, p);
 				dev_kfree_skb(skb);
-				return;  
+				return;
 			}
 		}
 		else
@@ -2952,13 +2952,13 @@ ni1up(struct PStack *st, int pr, void *arg)
 			global_handler(st, mt, skb);
 			return;
 		}
-				
+
 		if (st->l3.debug & L3_DEB_WARN)
 			l3_debug(st, "ni1up dummy Callref (no facility msg or ie)");
 		dev_kfree_skb(skb);
 		return;
-	} else if ((((skb->data[1] & 0x0f) == 1) && (0==(cr & 0x7f))) ||
-		(((skb->data[1] & 0x0f) == 2) && (0==(cr & 0x7fff)))) {	/* Global CallRef */
+	} else if ((((skb->data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) ||
+		   (((skb->data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) {	/* Global CallRef */
 		if (st->l3.debug & L3_DEB_STATE)
 			l3_debug(st, "ni1up Global CallRef");
 		global_handler(st, mt, skb);
@@ -3036,8 +3036,8 @@ ni1up(struct PStack *st, int pr, void *arg)
 		dev_kfree_skb(skb);
 		return;
 	}
-	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) 
-	  l3ni1_deliver_display(proc, pr, p); /* Display IE included */
+	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
+		l3ni1_deliver_display(proc, pr, p); /* Display IE included */
 	for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
 		if ((mt == datastatelist[i].primitive) &&
 		    ((1 << proc->state) & datastatelist[i].state))
@@ -3045,8 +3045,8 @@ ni1up(struct PStack *st, int pr, void *arg)
 	if (i == ARRAY_SIZE(datastatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1up%sstate %d mt %#x unhandled",
-				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
-				proc->state, mt);
+				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+				 proc->state, mt);
 		}
 		if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) {
 			proc->para.cause = 101;
@@ -3055,8 +3055,8 @@ ni1up(struct PStack *st, int pr, void *arg)
 	} else {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1up%sstate %d mt %x",
-				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
-				proc->state, mt);
+				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+				 proc->state, mt);
 		}
 		datastatelist[i].rout(proc, pr, skb);
 	}
@@ -3092,10 +3092,10 @@ ni1down(struct PStack *st, int pr, void *arg)
 		return;
 	}
 
-	if ( pr == (CC_TNI1_IO | REQUEST)) {
-		l3ni1_io_timer(proc); /* timer expires */ 
+	if (pr == (CC_TNI1_IO | REQUEST)) {
+		l3ni1_io_timer(proc); /* timer expires */
 		return;
-	}  
+	}
 
 	for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
 		if ((pr == downstatelist[i].primitive) &&
@@ -3104,12 +3104,12 @@ ni1down(struct PStack *st, int pr, void *arg)
 	if (i == ARRAY_SIZE(downstatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1down state %d prim %#x unhandled",
-				proc->state, pr);
+				 proc->state, pr);
 		}
 	} else {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1down state %d prim %#x",
-				proc->state, pr);
+				 proc->state, pr);
 		}
 		downstatelist[i].rout(proc, pr, arg);
 	}
@@ -3118,31 +3118,31 @@ ni1down(struct PStack *st, int pr, void *arg)
 static void
 ni1man(struct PStack *st, int pr, void *arg)
 {
-        int i;
-        struct l3_process *proc = arg;
-
-        if (!proc) {
-                printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr);
-                return;
-        }
-        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
-                if ((pr == manstatelist[i].primitive) &&
-                    ((1 << proc->state) & manstatelist[i].state))
-                        break;
-        if (i == ARRAY_SIZE(manstatelist)) {
-                if (st->l3.debug & L3_DEB_STATE) {
-                        l3_debug(st, "cr %d ni1man state %d prim %#x unhandled",
-                                proc->callref & 0x7f, proc->state, pr);
-                }
-        } else {
-                if (st->l3.debug & L3_DEB_STATE) {
-                        l3_debug(st, "cr %d ni1man state %d prim %#x",
-                                proc->callref & 0x7f, proc->state, pr);
-                }
-                manstatelist[i].rout(proc, pr, arg);
-        }
-}
- 
+	int i;
+	struct l3_process *proc = arg;
+
+	if (!proc) {
+		printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr);
+		return;
+	}
+	for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
+		if ((pr == manstatelist[i].primitive) &&
+		    ((1 << proc->state) & manstatelist[i].state))
+			break;
+	if (i == ARRAY_SIZE(manstatelist)) {
+		if (st->l3.debug & L3_DEB_STATE) {
+			l3_debug(st, "cr %d ni1man state %d prim %#x unhandled",
+				 proc->callref & 0x7f, proc->state, pr);
+		}
+	} else {
+		if (st->l3.debug & L3_DEB_STATE) {
+			l3_debug(st, "cr %d ni1man state %d prim %#x",
+				 proc->callref & 0x7f, proc->state, pr);
+		}
+		manstatelist[i].rout(proc, pr, arg);
+	}
+}
+
 void
 setstack_ni1(struct PStack *st)
 {
@@ -3157,8 +3157,8 @@ setstack_ni1(struct PStack *st)
 	st->prot.ni1.last_invoke_id = 0;
 	st->prot.ni1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */
 	i = 1;
-	while (i < 32) 
-		st->prot.ni1.invoke_used[i++] = 0;   
+	while (i < 32)
+		st->prot.ni1.invoke_used[i++] = 0;
 
 	if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
 		printk(KERN_ERR "HiSax can't get memory for ni1 global CR\n");
@@ -3169,7 +3169,7 @@ setstack_ni1(struct PStack *st)
 		st->l3.global->debug = L3_DEB_WARN;
 		st->l3.global->st = st;
 		st->l3.global->N303 = 1;
-		st->l3.global->prot.ni1.invoke_id = 0; 
+		st->l3.global->prot.ni1.invoke_id = 0;
 
 		L3InitTimer(st->l3.global, &st->l3.global->timer);
 	}
diff --git a/drivers/isdn/hisax/l3ni1.h b/drivers/isdn/hisax/l3ni1.h
index 4066da2..99d37d2 100644
--- a/drivers/isdn/hisax/l3ni1.h
+++ b/drivers/isdn/hisax/l3ni1.h
@@ -4,13 +4,13 @@
  *
  * Author       Matt Henderson & Guy Ellis
  * Copyright    by Traverse Technologies Pty Ltd, www.travers.com.au
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * 2000.6.6 Initial implementation of routines for US NI1 
- * Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
- * driver written by Karsten Keil et al.  Thanks also for the 
+ * 2000.6.6 Initial implementation of routines for US NI1
+ * Layer 3 protocol based on the EURO/DSS1 D-channel protocol
+ * driver written by Karsten Keil et al.  Thanks also for the
  * code provided by Ragnar Paulson.
  *
  */
@@ -119,18 +119,18 @@
 
 /* l3ni1 specific data in l3 process */
 typedef struct
-  { unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */
-    ulong ll_id; /* remebered ll id */
-    u8 remote_operation; /* handled remote operation, 0 = not active */ 
-    int proc; /* rememered procedure */  
-    ulong remote_result; /* result of remote operation for statcallb */
-    char uus1_data[35]; /* data send during alerting or disconnect */
-  } ni1_proc_priv;
+{ unsigned char invoke_id; /* used invoke id in remote ops, 0 = not active */
+	ulong ll_id; /* remebered ll id */
+	u8 remote_operation; /* handled remote operation, 0 = not active */
+	int proc; /* rememered procedure */
+	ulong remote_result; /* result of remote operation for statcallb */
+	char uus1_data[35]; /* data send during alerting or disconnect */
+} ni1_proc_priv;
 
 /* l3dni1 specific data in protocol stack */
 typedef struct
-  { unsigned char last_invoke_id; /* last used value for invoking */
-    unsigned char invoke_used[32]; /* 256 bits for 256 values */
-  } ni1_stk_priv;        
+{ unsigned char last_invoke_id; /* last used value for invoking */
+	unsigned char invoke_used[32]; /* 256 bits for 256 values */
+} ni1_stk_priv;
 
 #endif /* only l3dni1_process */
diff --git a/drivers/isdn/hisax/lmgr.c b/drivers/isdn/hisax/lmgr.c
index d4f86d6..5b63eb6 100644
--- a/drivers/isdn/hisax/lmgr.c
+++ b/drivers/isdn/hisax/lmgr.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -16,12 +16,12 @@ static void
 error_handling_dchan(struct PStack *st, int Error)
 {
 	switch (Error) {
-		case 'C':
-		case 'D':
-		case 'G':
-		case 'H':
-			st->l2.l2tei(st, MDL_ERROR | REQUEST, NULL);
-			break;
+	case 'C':
+	case 'D':
+	case 'G':
+	case 'H':
+		st->l2.l2tei(st, MDL_ERROR | REQUEST, NULL);
+		break;
 	}
 }
 
@@ -31,15 +31,15 @@ hisax_manager(struct PStack *st, int pr, void *arg)
 	long Code;
 
 	switch (pr) {
-		case (MDL_ERROR | INDICATION):
-			Code = (long) arg;
-			HiSax_putstatus(st->l1.hardware, "manager: MDL_ERROR",
-				" %c %s", (char)Code, 
+	case (MDL_ERROR | INDICATION):
+		Code = (long) arg;
+		HiSax_putstatus(st->l1.hardware, "manager: MDL_ERROR",
+				" %c %s", (char)Code,
 				test_bit(FLG_LAPD, &st->l2.flag) ?
 				"D-channel" : "B-channel");
-			if (test_bit(FLG_LAPD, &st->l2.flag))
-				error_handling_dchan(st, Code);
-			break;
+		if (test_bit(FLG_LAPD, &st->l2.flag))
+			error_handling_dchan(st, Code);
+		break;
 	}
 }
 
diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c
index 2539430..08a6b7f 100644
--- a/drivers/isdn/hisax/mic.c
+++ b/drivers/isdn/hisax/mic.c
@@ -4,7 +4,7 @@
  *
  * Author       Stephan von Krawczynski
  * Copyright    by Stephan von Krawczynski <skraw@ithnet.com>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -18,7 +18,7 @@
 
 static const char *mic_revision = "$Revision: 1.12.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define MIC_ISAC	2
@@ -39,7 +39,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -54,7 +54,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -75,13 +75,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.mic.adr, cs->hw.mic.isac, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.mic.adr, cs->hw.mic.isac, 0, data, size);
 }
@@ -104,16 +104,16 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
  * fast interrupt HSCX stuff goes here
  */
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.mic.adr, \
-		cs->hw.mic.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.mic.adr, \
-		cs->hw.mic.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.mic.adr,			\
+				      cs->hw.mic.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.mic.adr,		\
+					      cs->hw.mic.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.mic.adr, \
-		cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.mic.adr,		\
+						cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.mic.adr, \
-		cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.mic.adr,	\
+						  cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -126,11 +126,11 @@ mic_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.mic.adr, cs->hw.mic.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.mic.adr, cs->hw.mic.hscx, HSCX_ISTA + 0x40);
@@ -170,21 +170,21 @@ mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			return(0);
-		case CARD_RELEASE:
-			release_io_mic(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscx(cs); /* /RTSA := ISAC RST */
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		return (0);
+	case CARD_RELEASE:
+		release_io_mic(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscx(cs); /* /RTSA := ISAC RST */
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 int __devinit
@@ -214,7 +214,7 @@ setup_mic(struct IsdnCard *card)
 		return (0);
 	}
 	printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n",
-		cs->hw.mic.cfg_reg, cs->irq);
+	       cs->hw.mic.cfg_reg, cs->irq);
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
 	cs->writeisac = &WriteISAC;
@@ -228,7 +228,7 @@ setup_mic(struct IsdnCard *card)
 	ISACVersion(cs, "mic:");
 	if (HscxVersion(cs, "mic:")) {
 		printk(KERN_WARNING
-		    "mic: wrong HSCX versions check IO address\n");
+		       "mic: wrong HSCX versions check IO address\n");
 		release_io_mic(cs);
 		return (0);
 	}
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 644891e..b646eed 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -31,21 +31,21 @@ u_char
 NETjet_ReadIC(struct IsdnCardState *cs, u_char offset)
 {
 	u_char ret;
-	
+
 	cs->hw.njet.auxd &= 0xfc;
-	cs->hw.njet.auxd |= (offset>>4) & 3;
+	cs->hw.njet.auxd |= (offset >> 4) & 3;
 	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
-	ret = bytein(cs->hw.njet.isac + ((offset & 0xf)<<2));
-	return(ret);
+	ret = bytein(cs->hw.njet.isac + ((offset & 0xf) << 2));
+	return (ret);
 }
 
 void
 NETjet_WriteIC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
 	cs->hw.njet.auxd &= 0xfc;
-	cs->hw.njet.auxd |= (offset>>4) & 3;
+	cs->hw.njet.auxd |= (offset >> 4) & 3;
 	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
-	byteout(cs->hw.njet.isac + ((offset & 0xf)<<2), value);
+	byteout(cs->hw.njet.isac + ((offset & 0xf) << 2), value);
 }
 
 void
@@ -56,7 +56,7 @@ NETjet_ReadICfifo(struct IsdnCardState *cs, u_char *data, int size)
 	insb(cs->hw.njet.isac, data, size);
 }
 
-void 
+void
 NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	cs->hw.njet.auxd &= 0xfc;
@@ -66,17 +66,17 @@ NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
 
 static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
 {
-	u_int mask=0x000000ff, val = 0, *p=pos;
+	u_int mask = 0x000000ff, val = 0, *p = pos;
 	u_int i;
-	
+
 	val |= fill;
 	if (chan) {
 		val  <<= 8;
 		mask <<= 8;
 	}
 	mask ^= 0xffffffff;
-	for (i=0; i<cnt; i++) {
-		*p   &= mask;
+	for (i = 0; i < cnt; i++) {
+		*p &= mask;
 		*p++ |= val;
 		if (p > bcs->hw.tiger.s_end)
 			p = bcs->hw.tiger.send;
@@ -87,7 +87,7 @@ static void
 mode_tiger(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
-        u_char led;
+	u_char led;
 
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "Tiger mode %d bchan %d/%d",
@@ -95,63 +95,63 @@ mode_tiger(struct BCState *bcs, int mode, int bc)
 	bcs->mode = mode;
 	bcs->channel = bc;
 	switch (mode) {
-		case (L1_MODE_NULL):
-			fill_mem(bcs, bcs->hw.tiger.send,
-				NETJET_DMA_TXSIZE, bc, 0xff);
-			if (cs->debug & L1_DEB_HSCX)
-				debugl1(cs, "Tiger stat rec %d/%d send %d",
-					bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
-					bcs->hw.tiger.s_tot); 
-			if ((cs->bcs[0].mode == L1_MODE_NULL) &&
-				(cs->bcs[1].mode == L1_MODE_NULL)) {
-				cs->hw.njet.dmactrl = 0;
-				byteout(cs->hw.njet.base + NETJET_DMACTRL,
-					cs->hw.njet.dmactrl);
-				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
-			}
-                        if (cs->typ == ISDN_CTYPE_NETJET_S)
-                        {
-                                // led off
-                                led = bc & 0x01;
-                                led = 0x01 << (6 + led); // convert to mask
-                                led = ~led;
-                                cs->hw.njet.auxd &= led;
-                                byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
-                        }
-			break;
-		case (L1_MODE_TRANS):
-			break;
-		case (L1_MODE_HDLC_56K):
-		case (L1_MODE_HDLC):
+	case (L1_MODE_NULL):
+		fill_mem(bcs, bcs->hw.tiger.send,
+			 NETJET_DMA_TXSIZE, bc, 0xff);
+		if (cs->debug & L1_DEB_HSCX)
+			debugl1(cs, "Tiger stat rec %d/%d send %d",
+				bcs->hw.tiger.r_tot, bcs->hw.tiger.r_err,
+				bcs->hw.tiger.s_tot);
+		if ((cs->bcs[0].mode == L1_MODE_NULL) &&
+		    (cs->bcs[1].mode == L1_MODE_NULL)) {
+			cs->hw.njet.dmactrl = 0;
+			byteout(cs->hw.njet.base + NETJET_DMACTRL,
+				cs->hw.njet.dmactrl);
+			byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
+		}
+		if (cs->typ == ISDN_CTYPE_NETJET_S)
+		{
+			// led off
+			led = bc & 0x01;
+			led = 0x01 << (6 + led); // convert to mask
+			led = ~led;
+			cs->hw.njet.auxd &= led;
+			byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
+		}
+		break;
+	case (L1_MODE_TRANS):
+		break;
+	case (L1_MODE_HDLC_56K):
+	case (L1_MODE_HDLC):
+		fill_mem(bcs, bcs->hw.tiger.send,
+			 NETJET_DMA_TXSIZE, bc, 0xff);
+		bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
+		bcs->hw.tiger.r_tot = 0;
+		bcs->hw.tiger.r_bitcnt = 0;
+		bcs->hw.tiger.r_one = 0;
+		bcs->hw.tiger.r_err = 0;
+		bcs->hw.tiger.s_tot = 0;
+		if (!cs->hw.njet.dmactrl) {
 			fill_mem(bcs, bcs->hw.tiger.send,
-				NETJET_DMA_TXSIZE, bc, 0xff);
-			bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
-			bcs->hw.tiger.r_tot = 0;
-			bcs->hw.tiger.r_bitcnt = 0;
-			bcs->hw.tiger.r_one = 0;
-			bcs->hw.tiger.r_err = 0;
-			bcs->hw.tiger.s_tot = 0;
-			if (! cs->hw.njet.dmactrl) {
-				fill_mem(bcs, bcs->hw.tiger.send,
-					NETJET_DMA_TXSIZE, !bc, 0xff);
-				cs->hw.njet.dmactrl = 1;
-				byteout(cs->hw.njet.base + NETJET_DMACTRL,
-					cs->hw.njet.dmactrl);
-				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f);
+				 NETJET_DMA_TXSIZE, !bc, 0xff);
+			cs->hw.njet.dmactrl = 1;
+			byteout(cs->hw.njet.base + NETJET_DMACTRL,
+				cs->hw.njet.dmactrl);
+			byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f);
 			/* was 0x3f now 0x0f for TJ300 and TJ320  GE 13/07/00 */
-			}
-			bcs->hw.tiger.sendp = bcs->hw.tiger.send;
-			bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
-			test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
-                        if (cs->typ == ISDN_CTYPE_NETJET_S)
-                        {
-                                // led on
-                                led = bc & 0x01;
-                                led = 0x01 << (6 + led); // convert to mask
-                                cs->hw.njet.auxd |= led;
-                                byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
-                        }
-			break;
+		}
+		bcs->hw.tiger.sendp = bcs->hw.tiger.send;
+		bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
+		test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
+		if (cs->typ == ISDN_CTYPE_NETJET_S)
+		{
+			// led on
+			led = bc & 0x01;
+			led = 0x01 << (6 + led); // convert to mask
+			cs->hw.njet.auxd |= led;
+			byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
+		}
+		break;
 	}
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "tiger: set %x %x %x  %x/%x  pulse=%d",
@@ -166,15 +166,15 @@ mode_tiger(struct BCState *bcs, int mode, int bc)
 static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s) {
 	char tmp[128];
 	char *t = tmp;
-	int i=count,j;
+	int i = count, j;
 	u_char *p = buf;
 
 	t += sprintf(t, "tiger %s(%4d)", s, count);
-	while (i>0) {
-		if (i>16)
-			j=16;
+	while (i > 0) {
+		if (i > 16)
+			j = 16;
 		else
-			j=i;
+			j = i;
 		QuickHex(t, p, j);
 		debugl1(cs, tmp);
 		p += j;
@@ -186,78 +186,78 @@ static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s
 
 // macro for 64k
 
-#define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
-			bitcnt++;\
-			s_val >>= 1;\
-			if (val & 1) {\
-				s_one++;\
-				s_val |= 0x80;\
-			} else {\
-				s_one = 0;\
-				s_val &= 0x7f;\
-			}\
-			if (bitcnt==8) {\
-				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
-				bitcnt = 0;\
-			}\
-			if (s_one == 5) {\
-				s_val >>= 1;\
-				s_val &= 0x7f;\
-				bitcnt++;\
-				s_one = 0;\
-			}\
-			if (bitcnt==8) {\
-				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
-				bitcnt = 0;\
-			}\
-			val >>= 1;\
-		}
+#define MAKE_RAW_BYTE for (j = 0; j < 8; j++) {			\
+		bitcnt++;					\
+		s_val >>= 1;					\
+		if (val & 1) {					\
+			s_one++;				\
+			s_val |= 0x80;				\
+		} else {					\
+			s_one = 0;				\
+			s_val &= 0x7f;				\
+		}						\
+		if (bitcnt == 8) {				\
+			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;	\
+			bitcnt = 0;				\
+		}						\
+		if (s_one == 5) {				\
+			s_val >>= 1;				\
+			s_val &= 0x7f;				\
+			bitcnt++;				\
+			s_one = 0;				\
+		}						\
+		if (bitcnt == 8) {				\
+			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;	\
+			bitcnt = 0;				\
+		}						\
+		val >>= 1;					\
+	}
 
 static int make_raw_data(struct BCState *bcs) {
 // this make_raw is for 64k
-	register u_int i,s_cnt=0;
+	register u_int i, s_cnt = 0;
 	register u_char j;
 	register u_char val;
 	register u_char s_one = 0;
 	register u_char s_val = 0;
 	register u_char bitcnt = 0;
 	u_int fcs;
-	
+
 	if (!bcs->tx_skb) {
 		debugl1(bcs->cs, "tiger make_raw: NULL skb");
-		return(1);
+		return (1);
 	}
 	bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
 	fcs = PPP_INITFCS;
-	for (i=0; i<bcs->tx_skb->len; i++) {
+	for (i = 0; i < bcs->tx_skb->len; i++) {
 		val = bcs->tx_skb->data[i];
-		fcs = PPP_FCS (fcs, val);
+		fcs = PPP_FCS(fcs, val);
 		MAKE_RAW_BYTE;
 	}
 	fcs ^= 0xffff;
 	val = fcs & 0xff;
 	MAKE_RAW_BYTE;
-	val = (fcs>>8) & 0xff;
+	val = (fcs >> 8) & 0xff;
 	MAKE_RAW_BYTE;
 	val = HDLC_FLAG_VALUE;
-	for (j=0; j<8; j++) { 
+	for (j = 0; j < 8; j++) {
 		bitcnt++;
 		s_val >>= 1;
 		if (val & 1)
 			s_val |= 0x80;
 		else
 			s_val &= 0x7f;
-		if (bitcnt==8) {
+		if (bitcnt == 8) {
 			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
 			bitcnt = 0;
 		}
 		val >>= 1;
 	}
 	if (bcs->cs->debug & L1_DEB_HSCX)
-		debugl1(bcs->cs,"tiger make_raw: in %u out %d.%d",
+		debugl1(bcs->cs, "tiger make_raw: in %u out %d.%d",
 			bcs->tx_skb->len, s_cnt, bitcnt);
 	if (bitcnt) {
-		while (8>bitcnt++) {
+		while (8 > bitcnt++) {
 			s_val >>= 1;
 			s_val |= 0x80;
 		}
@@ -267,65 +267,65 @@ static int make_raw_data(struct BCState *bcs) {
 	bcs->hw.tiger.sendcnt = s_cnt;
 	bcs->tx_cnt -= bcs->tx_skb->len;
 	bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
-	return(0);
+	return (0);
 }
 
 // macro for 56k
 
-#define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { \
-			bitcnt++;\
-			s_val >>= 1;\
-			if (val & 1) {\
-				s_one++;\
-				s_val |= 0x80;\
-			} else {\
-				s_one = 0;\
-				s_val &= 0x7f;\
-			}\
-			if (bitcnt==7) {\
-				s_val >>= 1;\
-				s_val |= 0x80;\
-				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
-				bitcnt = 0;\
-			}\
-			if (s_one == 5) {\
-				s_val >>= 1;\
-				s_val &= 0x7f;\
-				bitcnt++;\
-				s_one = 0;\
-			}\
-			if (bitcnt==7) {\
-				s_val >>= 1;\
-				s_val |= 0x80;\
-				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
-				bitcnt = 0;\
-			}\
-			val >>= 1;\
-		}
+#define MAKE_RAW_BYTE_56K for (j = 0; j < 8; j++) {			\
+		bitcnt++;					\
+		s_val >>= 1;					\
+		if (val & 1) {					\
+			s_one++;				\
+			s_val |= 0x80;				\
+		} else {					\
+			s_one = 0;				\
+			s_val &= 0x7f;				\
+		}						\
+		if (bitcnt == 7) {				\
+			s_val >>= 1;				\
+			s_val |= 0x80;				\
+			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;	\
+			bitcnt = 0;				\
+		}						\
+		if (s_one == 5) {				\
+			s_val >>= 1;				\
+			s_val &= 0x7f;				\
+			bitcnt++;				\
+			s_one = 0;				\
+		}						\
+		if (bitcnt == 7) {				\
+			s_val >>= 1;				\
+			s_val |= 0x80;				\
+			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;	\
+			bitcnt = 0;				\
+		}						\
+		val >>= 1;					\
+	}
 
 static int make_raw_data_56k(struct BCState *bcs) {
 // this make_raw is for 56k
-	register u_int i,s_cnt=0;
+	register u_int i, s_cnt = 0;
 	register u_char j;
 	register u_char val;
 	register u_char s_one = 0;
 	register u_char s_val = 0;
 	register u_char bitcnt = 0;
 	u_int fcs;
-	
+
 	if (!bcs->tx_skb) {
 		debugl1(bcs->cs, "tiger make_raw_56k: NULL skb");
-		return(1);
+		return (1);
 	}
 	val = HDLC_FLAG_VALUE;
-	for (j=0; j<8; j++) { 
+	for (j = 0; j < 8; j++) {
 		bitcnt++;
 		s_val >>= 1;
 		if (val & 1)
 			s_val |= 0x80;
 		else
 			s_val &= 0x7f;
-		if (bitcnt==7) {
+		if (bitcnt == 7) {
 			s_val >>= 1;
 			s_val |= 0x80;
 			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
@@ -334,25 +334,25 @@ static int make_raw_data_56k(struct BCState *bcs) {
 		val >>= 1;
 	};
 	fcs = PPP_INITFCS;
-	for (i=0; i<bcs->tx_skb->len; i++) {
+	for (i = 0; i < bcs->tx_skb->len; i++) {
 		val = bcs->tx_skb->data[i];
-		fcs = PPP_FCS (fcs, val);
+		fcs = PPP_FCS(fcs, val);
 		MAKE_RAW_BYTE_56K;
 	}
 	fcs ^= 0xffff;
 	val = fcs & 0xff;
 	MAKE_RAW_BYTE_56K;
-	val = (fcs>>8) & 0xff;
+	val = (fcs >> 8) & 0xff;
 	MAKE_RAW_BYTE_56K;
 	val = HDLC_FLAG_VALUE;
-	for (j=0; j<8; j++) { 
+	for (j = 0; j < 8; j++) {
 		bitcnt++;
 		s_val >>= 1;
 		if (val & 1)
 			s_val |= 0x80;
 		else
 			s_val &= 0x7f;
-		if (bitcnt==7) {
+		if (bitcnt == 7) {
 			s_val >>= 1;
 			s_val |= 0x80;
 			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
@@ -361,10 +361,10 @@ static int make_raw_data_56k(struct BCState *bcs) {
 		val >>= 1;
 	}
 	if (bcs->cs->debug & L1_DEB_HSCX)
-		debugl1(bcs->cs,"tiger make_raw_56k: in %u out %d.%d",
+		debugl1(bcs->cs, "tiger make_raw_56k: in %u out %d.%d",
 			bcs->tx_skb->len, s_cnt, bitcnt);
 	if (bitcnt) {
-		while (8>bitcnt++) {
+		while (8 > bitcnt++) {
 			s_val >>= 1;
 			s_val |= 0x80;
 		}
@@ -374,12 +374,12 @@ static int make_raw_data_56k(struct BCState *bcs) {
 	bcs->hw.tiger.sendcnt = s_cnt;
 	bcs->tx_cnt -= bcs->tx_skb->len;
 	bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
-	return(0);
+	return (0);
 }
 
 static void got_frame(struct BCState *bcs, int count) {
 	struct sk_buff *skb;
-		
+
 	if (!(skb = dev_alloc_skb(count)))
 		printk(KERN_WARNING "TIGER: receive out of memory\n");
 	else {
@@ -388,18 +388,18 @@ static void got_frame(struct BCState *bcs, int count) {
 	}
 	test_and_set_bit(B_RCVBUFREADY, &bcs->event);
 	schedule_work(&bcs->tqueue);
-	
+
 	if (bcs->cs->debug & L1_DEB_RECEIVE_FRAME)
 		printframe(bcs->cs, bcs->hw.tiger.rcvbuf, count, "rec");
 }
 
 
 
-static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
+static void read_raw(struct BCState *bcs, u_int *buf, int cnt) {
 	int i;
 	register u_char j;
 	register u_char val;
-	u_int  *pend = bcs->hw.tiger.rec +NETJET_DMA_RXSIZE -1;
+	u_int *pend = bcs->hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
 	register u_char state = bcs->hw.tiger.r_state;
 	register u_char r_one = bcs->hw.tiger.r_one;
 	register u_char r_val = bcs->hw.tiger.r_val;
@@ -408,7 +408,7 @@ static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
 	int bits;
 	u_char mask;
 
-        if (bcs->mode == L1_MODE_HDLC) { // it's 64k
+	if (bcs->mode == L1_MODE_HDLC) { // it's 64k
 		mask = 0xff;
 		bits = 8;
 	}
@@ -416,8 +416,8 @@ static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
 		mask = 0x7f;
 		bits = 7;
 	};
-	for (i=0;i<cnt;i++) {
-		val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
+	for (i = 0; i < cnt; i++) {
+		val = bcs->channel ? ((*p >> 8) & 0xff) : (*p & 0xff);
 		p++;
 		if (p > pend)
 			p = bcs->hw.tiger.rec;
@@ -428,137 +428,137 @@ static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
 			r_one = 0;
 			continue;
 		}
-		for (j=0;j<bits;j++) {
+		for (j = 0; j < bits; j++) {
 			if (state == HDLC_ZERO_SEARCH) {
 				if (val & 1) {
 					r_one++;
 				} else {
-					r_one=0;
-					state= HDLC_FLAG_SEARCH;
+					r_one = 0;
+					state = HDLC_FLAG_SEARCH;
 					if (bcs->cs->debug & L1_DEB_HSCX)
-						debugl1(bcs->cs,"tiger read_raw: zBit(%d,%d,%d) %x",
-							bcs->hw.tiger.r_tot,i,j,val);
+						debugl1(bcs->cs, "tiger read_raw: zBit(%d,%d,%d) %x",
+							bcs->hw.tiger.r_tot, i, j, val);
 				}
-			} else if (state == HDLC_FLAG_SEARCH) { 
+			} else if (state == HDLC_FLAG_SEARCH) {
 				if (val & 1) {
 					r_one++;
-					if (r_one>6) {
-						state=HDLC_ZERO_SEARCH;
+					if (r_one > 6) {
+						state = HDLC_ZERO_SEARCH;
 					}
 				} else {
-					if (r_one==6) {
-						bitcnt=0;
-						r_val=0;
-						state=HDLC_FLAG_FOUND;
+					if (r_one == 6) {
+						bitcnt = 0;
+						r_val = 0;
+						state = HDLC_FLAG_FOUND;
 						if (bcs->cs->debug & L1_DEB_HSCX)
-							debugl1(bcs->cs,"tiger read_raw: flag(%d,%d,%d) %x",
-								bcs->hw.tiger.r_tot,i,j,val);
+							debugl1(bcs->cs, "tiger read_raw: flag(%d,%d,%d) %x",
+								bcs->hw.tiger.r_tot, i, j, val);
 					}
-					r_one=0;
+					r_one = 0;
 				}
-			} else if (state ==  HDLC_FLAG_FOUND) {
+			} else if (state == HDLC_FLAG_FOUND) {
 				if (val & 1) {
 					r_one++;
-					if (r_one>6) {
-						state=HDLC_ZERO_SEARCH;
+					if (r_one > 6) {
+						state = HDLC_ZERO_SEARCH;
 					} else {
 						r_val >>= 1;
 						r_val |= 0x80;
 						bitcnt++;
 					}
 				} else {
-					if (r_one==6) {
-						bitcnt=0;
-						r_val=0;
-						r_one=0;
+					if (r_one == 6) {
+						bitcnt = 0;
+						r_val = 0;
+						r_one = 0;
 						val >>= 1;
 						continue;
-					} else if (r_one!=5) {
+					} else if (r_one != 5) {
 						r_val >>= 1;
 						r_val &= 0x7f;
 						bitcnt++;
 					}
-					r_one=0;	
+					r_one = 0;
 				}
 				if ((state != HDLC_ZERO_SEARCH) &&
-					!(bitcnt & 7)) {
-					state=HDLC_FRAME_FOUND;
+				    !(bitcnt & 7)) {
+					state = HDLC_FRAME_FOUND;
 					bcs->hw.tiger.r_fcs = PPP_INITFCS;
 					bcs->hw.tiger.rcvbuf[0] = r_val;
-					bcs->hw.tiger.r_fcs = PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
+					bcs->hw.tiger.r_fcs = PPP_FCS(bcs->hw.tiger.r_fcs, r_val);
 					if (bcs->cs->debug & L1_DEB_HSCX)
-						debugl1(bcs->cs,"tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
-							bcs->hw.tiger.r_tot,i,j,r_val,val,
+						debugl1(bcs->cs, "tiger read_raw: byte1(%d,%d,%d) rval %x val %x i %x",
+							bcs->hw.tiger.r_tot, i, j, r_val, val,
 							bcs->cs->hw.njet.irqstat0);
 				}
 			} else if (state ==  HDLC_FRAME_FOUND) {
 				if (val & 1) {
 					r_one++;
-					if (r_one>6) {
-						state=HDLC_ZERO_SEARCH;
-						bitcnt=0;
+					if (r_one > 6) {
+						state = HDLC_ZERO_SEARCH;
+						bitcnt = 0;
 					} else {
 						r_val >>= 1;
 						r_val |= 0x80;
 						bitcnt++;
 					}
 				} else {
-					if (r_one==6) {
-						r_val=0; 
-						r_one=0;
+					if (r_one == 6) {
+						r_val = 0;
+						r_one = 0;
 						bitcnt++;
 						if (bitcnt & 7) {
 							debugl1(bcs->cs, "tiger: frame not byte aligned");
-							state=HDLC_FLAG_SEARCH;
+							state = HDLC_FLAG_SEARCH;
 							bcs->hw.tiger.r_err++;
 #ifdef ERROR_STATISTIC
 							bcs->err_inv++;
 #endif
 						} else {
 							if (bcs->cs->debug & L1_DEB_HSCX)
-								debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x",
-									i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);
+								debugl1(bcs->cs, "tiger frame end(%d,%d): fcs(%x) i %x",
+									i, j, bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0);
 							if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) {
-								got_frame(bcs, (bitcnt>>3)-3);
+								got_frame(bcs, (bitcnt >> 3) - 3);
 							} else {
 								if (bcs->cs->debug) {
 									debugl1(bcs->cs, "tiger FCS error");
 									printframe(bcs->cs, bcs->hw.tiger.rcvbuf,
-										(bitcnt>>3)-1, "rec");
+										   (bitcnt >> 3) - 1, "rec");
 									bcs->hw.tiger.r_err++;
 								}
 #ifdef ERROR_STATISTIC
-							bcs->err_crc++;
+								bcs->err_crc++;
 #endif
 							}
-							state=HDLC_FLAG_FOUND;
+							state = HDLC_FLAG_FOUND;
 						}
-						bitcnt=0;
-					} else if (r_one==5) {
+						bitcnt = 0;
+					} else if (r_one == 5) {
 						val >>= 1;
-						r_one=0;
+						r_one = 0;
 						continue;
 					} else {
 						r_val >>= 1;
 						r_val &= 0x7f;
 						bitcnt++;
 					}
-					r_one=0;	
+					r_one = 0;
 				}
 				if ((state == HDLC_FRAME_FOUND) &&
-					!(bitcnt & 7)) {
-					if ((bitcnt>>3)>=HSCX_BUFMAX) {
+				    !(bitcnt & 7)) {
+					if ((bitcnt >> 3) >= HSCX_BUFMAX) {
 						debugl1(bcs->cs, "tiger: frame too big");
-						r_val=0; 
-						state=HDLC_FLAG_SEARCH;
+						r_val = 0;
+						state = HDLC_FLAG_SEARCH;
 						bcs->hw.tiger.r_err++;
 #ifdef ERROR_STATISTIC
 						bcs->err_inv++;
 #endif
 					} else {
-						bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val;
-						bcs->hw.tiger.r_fcs = 
-							PPP_FCS (bcs->hw.tiger.r_fcs, r_val);
+						bcs->hw.tiger.rcvbuf[(bitcnt >> 3) - 1] = r_val;
+						bcs->hw.tiger.r_fcs =
+							PPP_FCS(bcs->hw.tiger.r_fcs, r_val);
 					}
 				}
 			}
@@ -574,10 +574,10 @@ static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
 
 void read_tiger(struct IsdnCardState *cs) {
 	u_int *p;
-	int cnt = NETJET_DMA_RXSIZE/2;
-	
+	int cnt = NETJET_DMA_RXSIZE / 2;
+
 	if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) {
-		debugl1(cs,"tiger warn read double dma %x/%x",
+		debugl1(cs, "tiger warn read double dma %x/%x",
 			cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
 #ifdef ERROR_STATISTIC
 		if (cs->bcs[0].mode)
@@ -589,7 +589,7 @@ void read_tiger(struct IsdnCardState *cs) {
 	} else {
 		cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ;
 		cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ);
-	}	
+	}
 	if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ_1)
 		p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
 	else
@@ -612,20 +612,20 @@ void netjet_fill_dma(struct BCState *bcs)
 	if (!bcs->tx_skb)
 		return;
 	if (bcs->cs->debug & L1_DEB_HSCX)
-		debugl1(bcs->cs,"tiger fill_dma1: c%d %4lx", bcs->channel,
+		debugl1(bcs->cs, "tiger fill_dma1: c%d %4lx", bcs->channel,
 			bcs->Flag);
 	if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
 		return;
 	if (bcs->mode == L1_MODE_HDLC) { // it's 64k
 		if (make_raw_data(bcs))
-			return;		
+			return;
 	}
 	else { // it's 56k
 		if (make_raw_data_56k(bcs))
-			return;		
+			return;
 	};
 	if (bcs->cs->debug & L1_DEB_HSCX)
-		debugl1(bcs->cs,"tiger fill_dma2: c%d %4lx", bcs->channel,
+		debugl1(bcs->cs, "tiger fill_dma2: c%d %4lx", bcs->channel,
 			bcs->Flag);
 	if (test_and_clear_bit(BC_FLG_NOFRAME, &bcs->Flag)) {
 		write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
@@ -633,11 +633,11 @@ void netjet_fill_dma(struct BCState *bcs)
 		p = bus_to_virt(inl(bcs->cs->hw.njet.base + NETJET_DMA_READ_ADR));
 		sp = bcs->hw.tiger.sendp;
 		if (p == bcs->hw.tiger.s_end)
-			p = bcs->hw.tiger.send -1;
+			p = bcs->hw.tiger.send - 1;
 		if (sp == bcs->hw.tiger.s_end)
-			sp = bcs->hw.tiger.send -1;
+			sp = bcs->hw.tiger.send - 1;
 		cnt = p - sp;
-		if (cnt <0) {
+		if (cnt < 0) {
 			write_raw(bcs, bcs->hw.tiger.sendp, bcs->hw.tiger.free);
 		} else {
 			p++;
@@ -655,30 +655,30 @@ void netjet_fill_dma(struct BCState *bcs)
 		cnt = bcs->hw.tiger.s_end - p;
 		if (cnt < 2) {
 			p = bcs->hw.tiger.send + 1;
-			cnt = NETJET_DMA_TXSIZE/2 - 2;
+			cnt = NETJET_DMA_TXSIZE / 2 - 2;
 		} else {
 			p++;
 			p++;
-			if (cnt <= (NETJET_DMA_TXSIZE/2))
-				cnt += NETJET_DMA_TXSIZE/2;
+			if (cnt <= (NETJET_DMA_TXSIZE / 2))
+				cnt += NETJET_DMA_TXSIZE / 2;
 			cnt--;
 			cnt--;
 		}
 		write_raw(bcs, p, cnt);
 	}
 	if (bcs->cs->debug & L1_DEB_HSCX)
-		debugl1(bcs->cs,"tiger fill_dma3: c%d %4lx", bcs->channel,
+		debugl1(bcs->cs, "tiger fill_dma3: c%d %4lx", bcs->channel,
 			bcs->Flag);
 }
 
 static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
-	u_int mask, val, *p=buf;
+	u_int mask, val, *p = buf;
 	u_int i, s_cnt;
-        
-        if (cnt <= 0)
-        	return;
+
+	if (cnt <= 0)
+		return;
 	if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
-		if (bcs->hw.tiger.sendcnt> cnt) {
+		if (bcs->hw.tiger.sendcnt > cnt) {
 			s_cnt = cnt;
 			bcs->hw.tiger.sendcnt -= cnt;
 		} else {
@@ -689,17 +689,17 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
 			mask = 0xffff00ff;
 		else
 			mask = 0xffffff00;
-		for (i=0; i<s_cnt; i++) {
-			val = bcs->channel ? ((bcs->hw.tiger.sp[i] <<8) & 0xff00) :
+		for (i = 0; i < s_cnt; i++) {
+			val = bcs->channel ? ((bcs->hw.tiger.sp[i] << 8) & 0xff00) :
 				(bcs->hw.tiger.sp[i]);
-			*p   &= mask;
+			*p &= mask;
 			*p++ |= val;
-			if (p>bcs->hw.tiger.s_end)
+			if (p > bcs->hw.tiger.s_end)
 				p = bcs->hw.tiger.send;
 		}
 		bcs->hw.tiger.s_tot += s_cnt;
 		if (bcs->cs->debug & L1_DEB_HSCX)
-			debugl1(bcs->cs,"tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel,
+			debugl1(bcs->cs, "tiger write_raw: c%d %p-%p %d/%d %d %x", bcs->channel,
 				buf, p, s_cnt, cnt,
 				bcs->hw.tiger.sendcnt, bcs->cs->hw.njet.irqstat0);
 		if (bcs->cs->debug & L1_DEB_HSCX_FIFO)
@@ -708,10 +708,10 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
 		bcs->hw.tiger.sendp = p;
 		if (!bcs->hw.tiger.sendcnt) {
 			if (!bcs->tx_skb) {
-				debugl1(bcs->cs,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
+				debugl1(bcs->cs, "tiger write_raw: NULL skb s_cnt %d", s_cnt);
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
 					u_long	flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->tx_skb->len;
@@ -723,7 +723,7 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
 			}
 			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
 			bcs->hw.tiger.free = cnt - s_cnt;
-			if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE/2))
+			if (bcs->hw.tiger.free > (NETJET_DMA_TXSIZE / 2))
 				test_and_set_bit(BC_FLG_HALF, &bcs->Flag);
 			else {
 				test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
@@ -734,9 +734,9 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
 			} else {
 				mask ^= 0xffffffff;
 				if (s_cnt < cnt) {
-					for (i=s_cnt; i<cnt;i++) {
+					for (i = s_cnt; i < cnt; i++) {
 						*p++ |= mask;
-						if (p>bcs->hw.tiger.s_end)
+						if (p > bcs->hw.tiger.s_end)
 							p = bcs->hw.tiger.send;
 					}
 					if (bcs->cs->debug & L1_DEB_HSCX)
@@ -752,20 +752,20 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
 		fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
 		bcs->hw.tiger.free += cnt;
 		if (bcs->cs->debug & L1_DEB_HSCX)
-			debugl1(bcs->cs,"tiger write_raw: fill half");
+			debugl1(bcs->cs, "tiger write_raw: fill half");
 	} else if (test_and_clear_bit(BC_FLG_HALF, &bcs->Flag)) {
 		test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
 		fill_mem(bcs, buf, cnt, bcs->channel, 0xff);
 		if (bcs->cs->debug & L1_DEB_HSCX)
-			debugl1(bcs->cs,"tiger write_raw: fill full");
+			debugl1(bcs->cs, "tiger write_raw: fill full");
 	}
 }
 
 void write_tiger(struct IsdnCardState *cs) {
-	u_int *p, cnt = NETJET_DMA_TXSIZE/2;
-	
+	u_int *p, cnt = NETJET_DMA_TXSIZE / 2;
+
 	if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) {
-		debugl1(cs,"tiger warn write double dma %x/%x",
+		debugl1(cs, "tiger warn write double dma %x/%x",
 			cs->hw.njet.irqstat0, cs->hw.njet.last_is0);
 #ifdef ERROR_STATISTIC
 		if (cs->bcs[0].mode)
@@ -777,7 +777,7 @@ void write_tiger(struct IsdnCardState *cs) {
 	} else {
 		cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE;
 		cs->hw.njet.last_is0 |= (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE);
-	}	
+	}
 	if (cs->hw.njet.irqstat0  & NETJET_IRQM0_WRITE_1)
 		p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
 	else
@@ -797,55 +797,55 @@ tiger_l2l1(struct PStack *st, int pr, void *arg)
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
-			} else {
-				bcs->tx_skb = skb;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			mode_tiger(bcs, st->l1.mode, st->l1.bc);
-			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
-			bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			mode_tiger(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
-			break;
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
+			bcs->tx_skb = skb;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
+		} else {
+			bcs->tx_skb = skb;
+			bcs->cs->BC_Send_Data(bcs);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		mode_tiger(bcs, st->l1.mode, st->l1.bc);
+		/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		bcs->cs->cardmsg(bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
+		bcs->cs->cardmsg(bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		mode_tiger(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -908,33 +908,33 @@ setstack_tiger(struct PStack *st, struct BCState *bcs)
 	return (0);
 }
 
- 
+
 void
 inittiger(struct IsdnCardState *cs)
 {
 	if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int),
-		GFP_KERNEL | GFP_DMA))) {
+						 GFP_KERNEL | GFP_DMA))) {
 		printk(KERN_WARNING
 		       "HiSax: No memory for tiger.send\n");
 		return;
 	}
-	cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE/2 - 1;
+	cs->bcs[0].hw.tiger.s_irq = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE / 2 - 1;
 	cs->bcs[0].hw.tiger.s_end = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
 	cs->bcs[1].hw.tiger.send = cs->bcs[0].hw.tiger.send;
 	cs->bcs[1].hw.tiger.s_irq = cs->bcs[0].hw.tiger.s_irq;
 	cs->bcs[1].hw.tiger.s_end = cs->bcs[0].hw.tiger.s_end;
-	
+
 	memset(cs->bcs[0].hw.tiger.send, 0xff, NETJET_DMA_TXSIZE * sizeof(unsigned int));
 	debugl1(cs, "tiger: send buf %p - %p", cs->bcs[0].hw.tiger.send,
 		cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1);
 	outl(virt_to_bus(cs->bcs[0].hw.tiger.send),
-		cs->hw.njet.base + NETJET_DMA_READ_START);
+	     cs->hw.njet.base + NETJET_DMA_READ_START);
 	outl(virt_to_bus(cs->bcs[0].hw.tiger.s_irq),
-		cs->hw.njet.base + NETJET_DMA_READ_IRQ);
+	     cs->hw.njet.base + NETJET_DMA_READ_IRQ);
 	outl(virt_to_bus(cs->bcs[0].hw.tiger.s_end),
-		cs->hw.njet.base + NETJET_DMA_READ_END);
+	     cs->hw.njet.base + NETJET_DMA_READ_END);
 	if (!(cs->bcs[0].hw.tiger.rec = kmalloc(NETJET_DMA_RXSIZE * sizeof(unsigned int),
-		GFP_KERNEL | GFP_DMA))) {
+						GFP_KERNEL | GFP_DMA))) {
 		printk(KERN_WARNING
 		       "HiSax: No memory for tiger.rec\n");
 		return;
@@ -944,11 +944,11 @@ inittiger(struct IsdnCardState *cs)
 	cs->bcs[1].hw.tiger.rec = cs->bcs[0].hw.tiger.rec;
 	memset(cs->bcs[0].hw.tiger.rec, 0xff, NETJET_DMA_RXSIZE * sizeof(unsigned int));
 	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec),
-		cs->hw.njet.base + NETJET_DMA_WRITE_START);
-	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE/2 - 1),
-		cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
+	     cs->hw.njet.base + NETJET_DMA_WRITE_START);
+	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE / 2 - 1),
+	     cs->hw.njet.base + NETJET_DMA_WRITE_IRQ);
 	outl(virt_to_bus(cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1),
-		cs->hw.njet.base + NETJET_DMA_WRITE_END);
+	     cs->hw.njet.base + NETJET_DMA_WRITE_END);
 	debugl1(cs, "tiger: dmacfg  %x/%x  pulse=%d",
 		inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
 		inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
@@ -979,4 +979,3 @@ release_io_netjet(struct IsdnCardState *cs)
 	releasetiger(cs);
 	release_region(cs->hw.njet.base, 256);
 }
-
diff --git a/drivers/isdn/hisax/netjet.h b/drivers/isdn/hisax/netjet.h
index 68e504d..70590d5 100644
--- a/drivers/isdn/hisax/netjet.h
+++ b/drivers/isdn/hisax/netjet.h
@@ -6,13 +6,13 @@
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
  *              by Matt Henderson,
  *                 Traverse Technologies P/L www.traverse.com.au
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define NETJET_CTRL	0x00
@@ -67,4 +67,3 @@ void netjet_fill_dma(struct BCState *bcs);
 void netjet_interrupt(int intno, void *dev_id);
 void inittiger(struct IsdnCardState *cs);
 void release_io_netjet(struct IsdnCardState *cs);
-
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
index ccaa6e1..6569e03 100644
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -5,10 +5,10 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
- * 
+ *
  * Thanks to Dr. Neuhaus and SAGEM for information
  *
  */
@@ -23,7 +23,7 @@
 
 static const char *niccy_revision = "$Revision: 1.21.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define ISAC_PCI_DATA	0
@@ -53,21 +53,21 @@ static inline u_char readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void readfifo(unsigned int ale, unsigned int adr, u_char off,
-		u_char *data, int size)
+			    u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
 }
 
 static inline void writereg(unsigned int ale, unsigned int adr, u_char off,
-		u_char data)
+			    u_char data)
 {
 	byteout(ale, off);
 	byteout(adr, data);
 }
 
 static inline void writefifo(unsigned int ale, unsigned int adr, u_char off,
-		u_char *data, int size)
+			     u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -85,12 +85,12 @@ static void WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 	writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, offset, value);
 }
 
-static void ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+static void ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
 }
 
-static void WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+static void WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, 0, data, size);
 }
@@ -98,26 +98,26 @@ static void WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 static u_char ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
 	return readreg(cs->hw.niccy.hscx_ale,
-			cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0));
+		       cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0));
 }
 
 static void WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset,
-		u_char value)
+		      u_char value)
 {
 	writereg(cs->hw.niccy.hscx_ale,
 		 cs->hw.niccy.hscx, offset + (hscx ? 0x40 : 0), value);
 }
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.niccy.hscx_ale, \
-		cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.niccy.hscx_ale, \
-		cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.niccy.hscx_ale,		\
+				      cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.niccy.hscx_ale,	\
+					      cs->hw.niccy.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.niccy.hscx_ale, \
-		cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.niccy.hscx_ale,	\
+						cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.niccy.hscx_ale, \
-		cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt)
+						  cs->hw.niccy.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -138,7 +138,7 @@ static irqreturn_t niccy_interrupt(int intno, void *dev_id)
 		outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
 	}
 	val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx,
-			HSCX_ISTA + 0x40);
+		      HSCX_ISTA + 0x40);
 Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
@@ -147,7 +147,7 @@ Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx,
-			HSCX_ISTA + 0x40);
+		      HSCX_ISTA + 0x40);
 	if (val) {
 		if (cs->debug & L1_DEB_HSCX)
 			debugl1(cs, "HSCX IntStat after IntRoutine");
@@ -165,7 +165,7 @@ Start_ISAC:
 	writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0xFF);
 	writereg(cs->hw.niccy.isac_ale, cs->hw.niccy.isac, ISAC_MASK, 0);
 	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK, 0);
-	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40,0);
+	writereg(cs->hw.niccy.hscx_ale, cs->hw.niccy.hscx, HSCX_MASK + 0x40, 0);
 	spin_unlock_irqrestore(&cs->lock, flags);
 	return IRQ_HANDLED;
 }
@@ -241,32 +241,32 @@ int __devinit setup_niccy(struct IsdnCard *card)
 		int err;
 
 		pnp_c = pnp_find_card(ISAPNP_VENDOR('S', 'D', 'A'),
-				ISAPNP_FUNCTION(0x0150), pnp_c);
+				      ISAPNP_FUNCTION(0x0150), pnp_c);
 		if (pnp_c) {
 			pnp_d = pnp_find_dev(pnp_c,
-					ISAPNP_VENDOR('S', 'D', 'A'),
-					ISAPNP_FUNCTION(0x0150), pnp_d);
+					     ISAPNP_VENDOR('S', 'D', 'A'),
+					     ISAPNP_FUNCTION(0x0150), pnp_d);
 			if (!pnp_d) {
 				printk(KERN_ERR "NiccyPnP: PnP error card "
-					"found, no device\n");
+				       "found, no device\n");
 				return 0;
 			}
 			pnp_disable_dev(pnp_d);
 			err = pnp_activate_dev(pnp_d);
 			if (err < 0) {
 				printk(KERN_WARNING "%s: pnp_activate_dev "
-					"ret(%d)\n", __func__, err);
+				       "ret(%d)\n", __func__, err);
 				return 0;
 			}
 			card->para[1] = pnp_port_start(pnp_d, 0);
 			card->para[2] = pnp_port_start(pnp_d, 1);
 			card->para[0] = pnp_irq(pnp_d, 0);
 			if (!card->para[0] || !card->para[1] ||
-					!card->para[2]) {
+			    !card->para[2]) {
 				printk(KERN_ERR "NiccyPnP:some resources are "
-					"missing %ld/%lx/%lx\n",
-					card->para[0], card->para[1],
-					card->para[2]);
+				       "missing %ld/%lx/%lx\n",
+				       card->para[0], card->para[1],
+				       card->para[2]);
 				pnp_disable_dev(pnp_d);
 				return 0;
 			}
@@ -284,15 +284,15 @@ int __devinit setup_niccy(struct IsdnCard *card)
 		cs->irq = card->para[0];
 		if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) {
 			printk(KERN_WARNING "HiSax: NICCY data port %x-%x "
-				"already in use\n",
-				cs->hw.niccy.isac, cs->hw.niccy.isac + 1);
+			       "already in use\n",
+			       cs->hw.niccy.isac, cs->hw.niccy.isac + 1);
 			return 0;
 		}
 		if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) {
 			printk(KERN_WARNING "HiSax: NICCY address port %x-%x "
-				"already in use\n",
-				cs->hw.niccy.isac_ale,
-				cs->hw.niccy.isac_ale + 1);
+			       "already in use\n",
+			       cs->hw.niccy.isac_ale,
+			       cs->hw.niccy.isac_ale + 1);
 			release_region(cs->hw.niccy.isac, 2);
 			return 0;
 		}
@@ -303,8 +303,8 @@ int __devinit setup_niccy(struct IsdnCard *card)
 		u_int pci_ioaddr;
 		cs->subtyp = 0;
 		if ((niccy_dev = hisax_find_pci_device(PCI_VENDOR_ID_SATSAGEM,
-						 PCI_DEVICE_ID_SATSAGEM_NICCY,
-						 niccy_dev))) {
+						       PCI_DEVICE_ID_SATSAGEM_NICCY,
+						       niccy_dev))) {
 			if (pci_enable_device(niccy_dev))
 				return 0;
 			/* get IRQ */
@@ -357,8 +357,8 @@ int __devinit setup_niccy(struct IsdnCard *card)
 #endif				/* CONFIG_PCI */
 	}
 	printk(KERN_INFO "HiSax: NICCY %s config irq:%d data:0x%X ale:0x%X\n",
-		(cs->subtyp == 1) ? "PnP" : "PCI",
-		cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
+	       (cs->subtyp == 1) ? "PnP" : "PCI",
+	       cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale);
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
 	cs->writeisac = &WriteISAC;
@@ -372,7 +372,7 @@ int __devinit setup_niccy(struct IsdnCard *card)
 	ISACVersion(cs, "Niccy:");
 	if (HscxVersion(cs, "Niccy:")) {
 		printk(KERN_WARNING "Niccy: wrong HSCX versions check IO "
-			"address\n");
+		       "address\n");
 		release_io_niccy(cs);
 		return 0;
 	}
diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c
index a1b8952..f36ff69 100644
--- a/drivers/isdn/hisax/nj_s.c
+++ b/drivers/isdn/hisax/nj_s.c
@@ -18,7 +18,7 @@ static const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
-	return(5);
+	return (5);
 }
 
 static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value)
@@ -46,48 +46,48 @@ netjet_s_interrupt(int intno, void *dev_id)
 		s1val = 1;
 	} else
 		s1val = 0;
-	/* 
+	/*
 	 * read/write stat0 is better, because lower IRQ rate
 	 * Note the IRQ is on for 125 us if a condition match
 	 * thats long on modern CPU and so the IRQ is reentered
 	 * all the time.
 	 */
 	s0val = bytein(cs->hw.njet.base + NETJET_IRQSTAT0);
-	if ((s0val | s1val)==0) { // shared IRQ
+	if ((s0val | s1val) == 0) { // shared IRQ
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return IRQ_NONE;
-	} 
+	}
 	if (s0val)
 		byteout(cs->hw.njet.base + NETJET_IRQSTAT0, s0val);
 	/* start new code 13/07/00 GE */
 	/* set bits in sval to indicate which page is free */
 	if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
-		inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
+	    inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
 		/* the 2nd write page is free */
 		s0val = 0x08;
 	else	/* the 1st write page is free */
-		s0val = 0x04;	
+		s0val = 0x04;
 	if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
-		inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
+	    inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
 		/* the 2nd read page is free */
 		s0val |= 0x02;
 	else	/* the 1st read page is free */
-		s0val |= 0x01;	
+		s0val |= 0x01;
 	if (s0val != cs->hw.njet.last_is0) /* we have a DMA interrupt */
 	{
 		if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 			printk(KERN_WARNING "nj LOCK_ATOMIC s0val %x->%x\n",
-				cs->hw.njet.last_is0, s0val);
+			       cs->hw.njet.last_is0, s0val);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			return IRQ_HANDLED;
 		}
 		cs->hw.njet.irqstat0 = s0val;
-		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != 
-			(cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
+		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) !=
+		    (cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
 			/* we have a read dma int */
 			read_tiger(cs);
 		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
-			(cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
+		    (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
 			/* we have a write dma int */
 			write_tiger(cs);
 		/* end new code 13/07/00 GE */
@@ -124,28 +124,28 @@ NETjet_S_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_netjet_s(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_netjet(cs);
-			return(0);
-		case CARD_INIT:
-			reset_netjet_s(cs);
-			inittiger(cs);
-			spin_lock_irqsave(&cs->lock, flags);
-			clear_pending_isac_ints(cs);
-			initisac(cs);
-			/* Reenable all IRQ */
-			cs->writeisac(cs, ISAC_MASK, 0);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_netjet_s(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_netjet(cs);
+		return (0);
+	case CARD_INIT:
+		reset_netjet_s(cs);
+		inittiger(cs);
+		spin_lock_irqsave(&cs->lock, flags);
+		clear_pending_isac_ints(cs);
+		initisac(cs);
+		/* Reenable all IRQ */
+		cs->writeisac(cs, ISAC_MASK, 0);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 static int __devinit njs_pci_probe(struct pci_dev *dev_netjet,
@@ -154,17 +154,17 @@ static int __devinit njs_pci_probe(struct pci_dev *dev_netjet,
 	u32 cfg;
 
 	if (pci_enable_device(dev_netjet))
-		return(0);
+		return (0);
 	pci_set_master(dev_netjet);
 	cs->irq = dev_netjet->irq;
 	if (!cs->irq) {
 		printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n");
-		return(0);
+		return (0);
 	}
 	cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
 	if (!cs->hw.njet.base) {
 		printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n");
-		return(0);
+		return (0);
 	}
 	/* the TJ300 and TJ320 must be detected, the IRQ handling is different
 	 * unfortunately the chips use the same device ID, but the TJ320 has
@@ -177,14 +177,14 @@ static int __devinit njs_pci_probe(struct pci_dev *dev_netjet,
 		cs->subtyp = 0; /* TJ300 */
 	/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */
 	if ((dev_netjet->subsystem_vendor == 0x55) &&
-		(dev_netjet->subsystem_device == 0x02)) {
+	    (dev_netjet->subsystem_device == 0x02)) {
 		printk(KERN_WARNING "Netjet: You tried to load this driver with an incompatible TigerJet-card\n");
 		printk(KERN_WARNING "Use type=41 for Formula-n enter:now ISDN PCI and compatible\n");
-		return(0);
+		return (0);
 	}
 	/* end new code */
 
-	return(1);
+	return (1);
 }
 
 static int __devinit njs_cs_init(struct IsdnCard *card,
@@ -209,18 +209,18 @@ static int __devinit njs_cs_init(struct IsdnCard *card,
 	byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
 	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
 
-	switch ( ( ( NETjet_ReadIC( cs, ISAC_RBCH ) >> 5 ) & 3 ) )
+	switch (((NETjet_ReadIC(cs, ISAC_RBCH) >> 5) & 3))
 	{
-		case 0 :
-			return 1;	/* end loop */
+	case 0:
+		return 1;	/* end loop */
 
-		case 3 :
-			printk( KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" );
-			return -1;	/* continue looping */
+	case 3:
+		printk(KERN_WARNING "NETjet-S: NETspider-U PCI card found\n");
+		return -1;	/* continue looping */
 
-		default :
-			printk( KERN_WARNING "NETjet-S: No PCI card found\n" );
-			return 0;	/* end loop & function */
+	default:
+		printk(KERN_WARNING "NETjet-S: No PCI card found\n");
+		return 0;	/* end loop & function */
 	}
 	return 1;			/* end loop */
 }
@@ -231,8 +231,8 @@ static int __devinit njs_cs_init_rest(struct IsdnCard *card,
 	const int bytecnt = 256;
 
 	printk(KERN_INFO
-		"NETjet-S: %s card configured at %#lx IRQ %d\n",
-		cs->subtyp ? "TJ320" : "TJ300", cs->hw.njet.base, cs->irq);
+	       "NETjet-S: %s card configured at %#lx IRQ %d\n",
+	       cs->subtyp ? "TJ320" : "TJ300", cs->hw.njet.base, cs->irq);
 	if (!request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn")) {
 		printk(KERN_WARNING
 		       "HiSax: NETjet-S config port %#lx-%#lx already in use\n",
@@ -271,24 +271,24 @@ setup_netjet_s(struct IsdnCard *card)
 	strcpy(tmp, NETjet_S_revision);
 	printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_NETJET_S)
-		return(0);
+		return (0);
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 
-	for ( ;; )
+	for (;;)
 	{
 		if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
-			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
+							PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			ret = njs_pci_probe(dev_netjet, cs);
 			if (!ret)
-				return(0);
+				return (0);
 		} else {
 			printk(KERN_WARNING "NETjet-S: No PCI card found\n");
-			return(0);
+			return (0);
 		}
 
 		ret = njs_cs_init(card, cs);
 		if (!ret)
-			return(0);
+			return (0);
 		if (ret > 0)
 			break;
 		/* otherwise, ret < 0, continue looping */
diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c
index 095e974..333484a 100644
--- a/drivers/isdn/hisax/nj_u.c
+++ b/drivers/isdn/hisax/nj_u.c
@@ -1,4 +1,4 @@
-/* $Id: nj_u.c,v 2.14.2.3 2004/01/13 14:31:26 keil Exp $ 
+/* $Id: nj_u.c,v 2.14.2.3 2004/01/13 14:31:26 keil Exp $
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -18,7 +18,7 @@ static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
-	return(5);
+	return (5);
 }
 
 static void dummywr(struct IsdnCardState *cs, int chan, u_char off, u_char value)
@@ -34,7 +34,7 @@ netjet_u_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	if (!((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT1)) &
-		NETJET_ISACIRQ)) {
+	      NETJET_ISACIRQ)) {
 		val = NETjet_ReadIC(cs, ICC_ISTA);
 		if (cs->debug & L1_DEB_ISAC)
 			debugl1(cs, "tiger: i1 %x %x", sval, val);
@@ -47,17 +47,17 @@ netjet_u_interrupt(int intno, void *dev_id)
 	/* start new code 13/07/00 GE */
 	/* set bits in sval to indicate which page is free */
 	if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
-		inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
+	    inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
 		/* the 2nd write page is free */
 		sval = 0x08;
 	else	/* the 1st write page is free */
-		sval = 0x04;	
+		sval = 0x04;
 	if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
-		inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
+	    inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
 		/* the 2nd read page is free */
 		sval = sval | 0x02;
 	else	/* the 1st read page is free */
-		sval = sval | 0x01;	
+		sval = sval | 0x01;
 	if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */
 	{
 		if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
@@ -65,12 +65,12 @@ netjet_u_interrupt(int intno, void *dev_id)
 			return IRQ_HANDLED;
 		}
 		cs->hw.njet.irqstat0 = sval;
-		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != 
-			(cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
+		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) !=
+		    (cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
 			/* we have a read dma int */
 			read_tiger(cs);
 		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
-			(cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
+		    (cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
 			/* we have a write dma int */
 			write_tiger(cs);
 		/* end new code 13/07/00 GE */
@@ -104,45 +104,45 @@ NETjet_U_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_netjet_u(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_netjet(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inittiger(cs);
-			reset_netjet_u(cs);
-			clear_pending_icc_ints(cs);
-			initicc(cs);
-			/* Reenable all IRQ */
-			cs->writeisac(cs, ICC_MASK, 0);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_netjet_u(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_netjet(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inittiger(cs);
+		reset_netjet_u(cs);
+		clear_pending_icc_ints(cs);
+		initicc(cs);
+		/* Reenable all IRQ */
+		cs->writeisac(cs, ICC_MASK, 0);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 static int __devinit nju_pci_probe(struct pci_dev *dev_netjet,
 				   struct IsdnCardState *cs)
 {
 	if (pci_enable_device(dev_netjet))
-		return(0);
+		return (0);
 	pci_set_master(dev_netjet);
 	cs->irq = dev_netjet->irq;
 	if (!cs->irq) {
 		printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
-		return(0);
+		return (0);
 	}
 	cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
 	if (!cs->hw.njet.base) {
 		printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n");
-		return(0);
+		return (0);
 	}
 
 	return (1);
@@ -171,18 +171,18 @@ static int __devinit nju_cs_init(struct IsdnCard *card,
 	byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
 	byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
 
-	switch ( ( ( NETjet_ReadIC( cs, ICC_RBCH ) >> 5 ) & 3 ) )
+	switch (((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3))
 	{
-		case 3 :
-			return 1;	/* end loop */
+	case 3:
+		return 1;	/* end loop */
 
-		case 0 :
-			printk( KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" );
-			return -1;	/* continue looping */
+	case 0:
+		printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n");
+		return -1;	/* continue looping */
 
-		default :
-			printk( KERN_WARNING "NETspider-U: No PCI card found\n" );
-			return 0;	/* end loop & function */
+	default:
+		printk(KERN_WARNING "NETspider-U: No PCI card found\n");
+		return 0;	/* end loop & function */
 	}
 	return 1;			/* end loop */
 }
@@ -193,8 +193,8 @@ static int __devinit nju_cs_init_rest(struct IsdnCard *card,
 	const int bytecnt = 256;
 
 	printk(KERN_INFO
-		"NETspider-U: PCI card configured at %#lx IRQ %d\n",
-		cs->hw.njet.base, cs->irq);
+	       "NETspider-U: PCI card configured at %#lx IRQ %d\n",
+	       cs->hw.njet.base, cs->irq);
 	if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) {
 		printk(KERN_WARNING
 		       "HiSax: NETspider-U config port %#lx-%#lx "
@@ -235,19 +235,19 @@ setup_netjet_u(struct IsdnCard *card)
 	strcpy(tmp, NETjet_U_revision);
 	printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_NETJET_U)
-		return(0);
+		return (0);
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 
-	for ( ;; )
+	for (;;)
 	{
 		if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
-			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
+							PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			ret = nju_pci_probe(dev_netjet, cs);
 			if (!ret)
-				return(0);
+				return (0);
 		} else {
 			printk(KERN_WARNING "NETspider-U: No PCI card found\n");
-			return(0);
+			return (0);
 		}
 
 		ret = nju_cs_init(card, cs);
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c
index c0771f9..041bf52 100644
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -21,7 +21,7 @@
 #include "l3_1tr6.h"
 
 void
-iecpy(u_char * dest, u_char * iestart, int ieoffset)
+iecpy(u_char *dest, u_char *iestart, int ieoffset)
 {
 	u_char *p;
 	int l;
@@ -215,7 +215,7 @@ prbits(char *dest, u_char b, int start, int len)
 
 static
 u_char *
-skipext(u_char * p)
+skipext(u_char *p)
 {
 	while (!(*p++ & 0x80));
 	return (p);
@@ -442,7 +442,7 @@ struct CauseValue {
 
 static
 int
-prcause(char *dest, u_char * p)
+prcause(char *dest, u_char *p)
 {
 	u_char *end;
 	char *dp = dest;
@@ -519,7 +519,7 @@ struct MessageType cause_1tr6[] =
 static int cause_1tr6_len = ARRAY_SIZE(cause_1tr6);
 
 static int
-prcause_1tr6(char *dest, u_char * p)
+prcause_1tr6(char *dest, u_char *p)
 {
 	char *dp = dest;
 	int i, cause;
@@ -554,7 +554,7 @@ prcause_1tr6(char *dest, u_char * p)
 }
 
 static int
-prchident(char *dest, u_char * p)
+prchident(char *dest, u_char *p)
 {
 	char *dp = dest;
 
@@ -566,7 +566,7 @@ prchident(char *dest, u_char * p)
 }
 
 static int
-prcalled(char *dest, u_char * p)
+prcalled(char *dest, u_char *p)
 {
 	int l;
 	char *dp = dest;
@@ -583,7 +583,7 @@ prcalled(char *dest, u_char * p)
 	return (dp - dest);
 }
 static int
-prcalling(char *dest, u_char * p)
+prcalling(char *dest, u_char *p)
 {
 	int l;
 	char *dp = dest;
@@ -610,7 +610,7 @@ prcalling(char *dest, u_char * p)
 
 static
 int
-prbearer(char *dest, u_char * p)
+prbearer(char *dest, u_char *p)
 {
 	char *dp = dest, ch;
 
@@ -658,7 +658,7 @@ prbearer(char *dest, u_char * p)
 
 static
 int
-prbearer_ni1(char *dest, u_char * p)
+prbearer_ni1(char *dest, u_char *p)
 {
 	char *dp = dest;
 	u_char len;
@@ -668,46 +668,46 @@ prbearer_ni1(char *dest, u_char * p)
 	dp += sprintf(dp, "    octet 3  ");
 	dp += prbits(dp, *p, 8, 8);
 	switch (*p++) {
-		case 0x80:
-			dp += sprintf(dp, " Speech");
-			break;
-		case 0x88:
-			dp += sprintf(dp, " Unrestricted digital information");
-			break;
-		case 0x90:
-			dp += sprintf(dp, " 3.1 kHz audio");
-			break;
-		default:
-			dp += sprintf(dp, " Unknown information-transfer capability");
+	case 0x80:
+		dp += sprintf(dp, " Speech");
+		break;
+	case 0x88:
+		dp += sprintf(dp, " Unrestricted digital information");
+		break;
+	case 0x90:
+		dp += sprintf(dp, " 3.1 kHz audio");
+		break;
+	default:
+		dp += sprintf(dp, " Unknown information-transfer capability");
 	}
 	*dp++ = '\n';
 	dp += sprintf(dp, "    octet 4  ");
 	dp += prbits(dp, *p, 8, 8);
 	switch (*p++) {
-		case 0x90:
-			dp += sprintf(dp, " 64 kbps, circuit mode");
-			break;
-		case 0xc0:
-			dp += sprintf(dp, " Packet mode");
-			break;
-		default:
-			dp += sprintf(dp, " Unknown transfer mode");
+	case 0x90:
+		dp += sprintf(dp, " 64 kbps, circuit mode");
+		break;
+	case 0xc0:
+		dp += sprintf(dp, " Packet mode");
+		break;
+	default:
+		dp += sprintf(dp, " Unknown transfer mode");
 	}
 	*dp++ = '\n';
 	if (len > 2) {
 		dp += sprintf(dp, "    octet 5  ");
 		dp += prbits(dp, *p, 8, 8);
 		switch (*p++) {
-			case 0x21:
-				dp += sprintf(dp, " Rate adaption\n");
-				dp += sprintf(dp, "    octet 5a ");
-				dp += prbits(dp, *p, 8, 8);
-				break;
-			case 0xa2:
-				dp += sprintf(dp, " u-law");
-				break;
-			default:
-				dp += sprintf(dp, " Unknown UI layer 1 protocol");
+		case 0x21:
+			dp += sprintf(dp, " Rate adaption\n");
+			dp += sprintf(dp, "    octet 5a ");
+			dp += prbits(dp, *p, 8, 8);
+			break;
+		case 0xa2:
+			dp += sprintf(dp, " u-law");
+			break;
+		default:
+			dp += sprintf(dp, " Unknown UI layer 1 protocol");
 		}
 		*dp++ = '\n';
 	}
@@ -715,7 +715,7 @@ prbearer_ni1(char *dest, u_char * p)
 }
 
 static int
-general(char *dest, u_char * p)
+general(char *dest, u_char *p)
 {
 	char *dp = dest;
 	char ch = ' ';
@@ -742,7 +742,7 @@ general(char *dest, u_char * p)
 }
 
 static int
-general_ni1(char *dest, u_char * p)
+general_ni1(char *dest, u_char *p)
 {
 	char *dp = dest;
 	char ch = ' ';
@@ -769,7 +769,7 @@ general_ni1(char *dest, u_char * p)
 }
 
 static int
-prcharge(char *dest, u_char * p)
+prcharge(char *dest, u_char *p)
 {
 	char *dp = dest;
 	int l;
@@ -786,7 +786,7 @@ prcharge(char *dest, u_char * p)
 	return (dp - dest);
 }
 static int
-prtext(char *dest, u_char * p)
+prtext(char *dest, u_char *p)
 {
 	char *dp = dest;
 	int l;
@@ -802,7 +802,7 @@ prtext(char *dest, u_char * p)
 }
 
 static int
-prfeatureind(char *dest, u_char * p)
+prfeatureind(char *dest, u_char *p)
 {
 	char *dp = dest;
 
@@ -817,21 +817,21 @@ prfeatureind(char *dest, u_char * p)
 	}
 	dp += sprintf(dp, "    Status:  ");
 	switch (*p) {
-		case 0:
-			dp += sprintf(dp, "Idle");
-			break;
-		case 1:
-			dp += sprintf(dp, "Active");
-			break;
-		case 2:
-			dp += sprintf(dp, "Prompt");
-			break;
-		case 3:
-			dp += sprintf(dp, "Pending");
-			break;
-		default:
-			dp += sprintf(dp, "(Reserved)");
-			break;
+	case 0:
+		dp += sprintf(dp, "Idle");
+		break;
+	case 1:
+		dp += sprintf(dp, "Active");
+		break;
+	case 2:
+		dp += sprintf(dp, "Prompt");
+		break;
+	case 3:
+		dp += sprintf(dp, "Pending");
+		break;
+	default:
+		dp += sprintf(dp, "(Reserved)");
+		break;
 	}
 	*dp++ = '\n';
 	return (dp - dest);
@@ -868,7 +868,7 @@ struct DTag { /* Display tags */
 #define DTAGSIZE ARRAY_SIZE(dtaglist)
 
 static int
-disptext_ni1(char *dest, u_char * p)
+disptext_ni1(char *dest, u_char *p)
 {
 	char *dp = dest;
 	int l, tag, len, i;
@@ -902,12 +902,12 @@ disptext_ni1(char *dest, u_char * p)
 					*dp++ = *p++;
 			}
 			dp += sprintf(dp, "\n");
-                }
+		}
 	}
 	return (dp - dest);
 }
 static int
-display(char *dest, u_char * p)
+display(char *dest, u_char *p)
 {
 	char *dp = dest;
 	char ch = ' ';
@@ -936,7 +936,7 @@ display(char *dest, u_char * p)
 }
 
 static int
-prfacility(char *dest, u_char * p)
+prfacility(char *dest, u_char *p)
 {
 	char *dp = dest;
 	int l, l2;
@@ -1148,7 +1148,7 @@ static struct InformationElement we_6[] =
 #define WE_6_LEN ARRAY_SIZE(we_6)
 
 int
-QuickHex(char *txt, u_char * p, int cnt)
+QuickHex(char *txt, u_char *p, int cnt)
 {
 	register int i;
 	register char *t = txt;
@@ -1163,7 +1163,7 @@ QuickHex(char *txt, u_char * p, int cnt)
 }
 
 void
-LogFrame(struct IsdnCardState *cs, u_char * buf, int size)
+LogFrame(struct IsdnCardState *cs, u_char *buf, int size)
 {
 	char *dp;
 
@@ -1206,7 +1206,7 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
 	buf = skb->data;
 	dp += sprintf(dp, "frame %s ", dir ? "network->user" : "user->network");
 	size = skb->len;
-	
+
 	if (tei == GROUP_TEI) {
 		if (sapi == CTRL_SAPI) { /* sapi 0 */
 			if (ftyp == 3) {
@@ -1291,28 +1291,28 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
 			/* Is it a single octet information element? */
 			if (*buf & 0x80) {
 				switch ((*buf >> 4) & 7) {
-					case 1:
-						dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
-						cs_old = cset;
-						cset = *buf & 7;
-						cs_fest = *buf & 8;
-						break;
-					case 3:
-						dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
-						break;
-					case 2:
-						if (*buf == 0xa0) {
-							dp += sprintf(dp, "  More data\n");
-							break;
-						}
-						if (*buf == 0xa1) {
-							dp += sprintf(dp, "  Sending complete\n");
-						}
-						break;
-						/* fall through */
-					default:
-						dp += sprintf(dp, "  Reserved %x\n", *buf);
+				case 1:
+					dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
+					cs_old = cset;
+					cset = *buf & 7;
+					cs_fest = *buf & 8;
+					break;
+				case 3:
+					dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
+					break;
+				case 2:
+					if (*buf == 0xa0) {
+						dp += sprintf(dp, "  More data\n");
 						break;
+					}
+					if (*buf == 0xa1) {
+						dp += sprintf(dp, "  Sending complete\n");
+					}
+					break;
+					/* fall through */
+				default:
+					dp += sprintf(dp, "  Reserved %x\n", *buf);
+					break;
 				}
 				buf++;
 				continue;
@@ -1366,11 +1366,11 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
 		/* display message type if it exists */
 		if (i == MTSIZE)
 			dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n",
-			    cr & 0x7f, (cr & 0x80) ? "called" : "caller",
+				      cr & 0x7f, (cr & 0x80) ? "called" : "caller",
 				      size, mt);
 		else
 			dp += sprintf(dp, "callref %d %s size %d message type %s\n",
-			    cr & 0x7f, (cr & 0x80) ? "called" : "caller",
+				      cr & 0x7f, (cr & 0x80) ? "called" : "caller",
 				      size, mtlist[i].descr);
 
 		/* display each information element */
@@ -1378,15 +1378,15 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
 			/* Is it a single octet information element? */
 			if (*buf & 0x80) {
 				switch ((*buf >> 4) & 7) {
-					case 1:
-						dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
-						cs_old = cset;
-						cset = *buf & 7;
-						cs_fest = *buf & 8;
-						break;
-					default:
-						dp += sprintf(dp, "  Unknown single-octet IE %x\n", *buf);
-						break;
+				case 1:
+					dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
+					cs_old = cset;
+					cset = *buf & 7;
+					cs_fest = *buf & 8;
+					break;
+				default:
+					dp += sprintf(dp, "  Unknown single-octet IE %x\n", *buf);
+					break;
 				}
 				buf++;
 				continue;
@@ -1452,11 +1452,11 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
 		/* display message type if it exists */
 		if (i == MTSIZE)
 			dp += sprintf(dp, "callref %d %s size %d unknown message type %x!\n",
-			    cr & 0x7f, (cr & 0x80) ? "called" : "caller",
+				      cr & 0x7f, (cr & 0x80) ? "called" : "caller",
 				      size, mt);
 		else
 			dp += sprintf(dp, "callref %d %s size %d message type %s\n",
-			    cr & 0x7f, (cr & 0x80) ? "called" : "caller",
+				      cr & 0x7f, (cr & 0x80) ? "called" : "caller",
 				      size, mtlist[i].descr);
 
 		/* display each information element */
@@ -1464,28 +1464,28 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir)
 			/* Is it a single octet information element? */
 			if (*buf & 0x80) {
 				switch ((*buf >> 4) & 7) {
-					case 1:
-						dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
-						break;
-					case 3:
-						dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
-						break;
-					case 5:
-						dp += sprintf(dp, "  Repeat indicator %x\n", *buf & 0xf);
-						break;
-					case 2:
-						if (*buf == 0xa0) {
-							dp += sprintf(dp, "  More data\n");
-							break;
-						}
-						if (*buf == 0xa1) {
-							dp += sprintf(dp, "  Sending complete\n");
-						}
-						break;
-						/* fall through */
-					default:
-						dp += sprintf(dp, "  Reserved %x\n", *buf);
+				case 1:
+					dp += sprintf(dp, "  Shift %x\n", *buf & 0xf);
+					break;
+				case 3:
+					dp += sprintf(dp, "  Congestion level %x\n", *buf & 0xf);
+					break;
+				case 5:
+					dp += sprintf(dp, "  Repeat indicator %x\n", *buf & 0xf);
+					break;
+				case 2:
+					if (*buf == 0xa0) {
+						dp += sprintf(dp, "  More data\n");
 						break;
+					}
+					if (*buf == 0xa1) {
+						dp += sprintf(dp, "  Sending complete\n");
+					}
+					break;
+					/* fall through */
+				default:
+					dp += sprintf(dp, "  Reserved %x\n", *buf);
+					break;
 				}
 				buf++;
 				continue;
diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c
index 16d00b5..383c4e7 100644
--- a/drivers/isdn/hisax/s0box.c
+++ b/drivers/isdn/hisax/s0box.c
@@ -20,73 +20,73 @@ static const char *s0box_revision = "$Revision: 2.6.2.4 $";
 
 static inline void
 writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
-	outb_p(0x1c,padr+2);
-	outb_p(0x14,padr+2);
-	outb_p((addr+off)&0x7f,padr);
-	outb_p(0x16,padr+2);
-	outb_p(val,padr);
-	outb_p(0x17,padr+2);
-	outb_p(0x14,padr+2);
-	outb_p(0x1c,padr+2);
+	outb_p(0x1c, padr + 2);
+	outb_p(0x14, padr + 2);
+	outb_p((addr + off) & 0x7f, padr);
+	outb_p(0x16, padr + 2);
+	outb_p(val, padr);
+	outb_p(0x17, padr + 2);
+	outb_p(0x14, padr + 2);
+	outb_p(0x1c, padr + 2);
 }
 
 static u_char nibtab[] = { 1, 9, 5, 0xd, 3, 0xb, 7, 0xf,
-			 0, 0, 0, 0, 0, 0, 0, 0,
-			 0, 8, 4, 0xc, 2, 0xa, 6, 0xe } ;
+			   0, 0, 0, 0, 0, 0, 0, 0,
+			   0, 8, 4, 0xc, 2, 0xa, 6, 0xe };
 
 static inline u_char
 readreg(unsigned int padr, signed int addr, u_char off) {
 	register u_char n1, n2;
 
-	outb_p(0x1c,padr+2);
-	outb_p(0x14,padr+2);
-	outb_p((addr+off)|0x80,padr);
-	outb_p(0x16,padr+2);
-	outb_p(0x17,padr+2);
-	n1 = (inb_p(padr+1) >> 3) & 0x17;
-	outb_p(0x16,padr+2);
-	n2 = (inb_p(padr+1) >> 3) & 0x17;
-	outb_p(0x14,padr+2);
-	outb_p(0x1c,padr+2);
+	outb_p(0x1c, padr + 2);
+	outb_p(0x14, padr + 2);
+	outb_p((addr + off) | 0x80, padr);
+	outb_p(0x16, padr + 2);
+	outb_p(0x17, padr + 2);
+	n1 = (inb_p(padr + 1) >> 3) & 0x17;
+	outb_p(0x16, padr + 2);
+	n2 = (inb_p(padr + 1) >> 3) & 0x17;
+	outb_p(0x14, padr + 2);
+	outb_p(0x1c, padr + 2);
 	return nibtab[n1] | (nibtab[n2] << 4);
 }
 
 static inline void
-read_fifo(unsigned int padr, signed int adr, u_char * data, int size)
+read_fifo(unsigned int padr, signed int adr, u_char *data, int size)
 {
 	int i;
 	register u_char n1, n2;
-	
-	outb_p(0x1c, padr+2);
-	outb_p(0x14, padr+2);
-	outb_p(adr|0x80, padr);
-	outb_p(0x16, padr+2);
-	for (i=0; i<size; i++) {
-		outb_p(0x17, padr+2);
-		n1 = (inb_p(padr+1) >> 3) & 0x17;
-		outb_p(0x16,padr+2);
-		n2 = (inb_p(padr+1) >> 3) & 0x17;
-		*(data++)=nibtab[n1] | (nibtab[n2] << 4);
+
+	outb_p(0x1c, padr + 2);
+	outb_p(0x14, padr + 2);
+	outb_p(adr | 0x80, padr);
+	outb_p(0x16, padr + 2);
+	for (i = 0; i < size; i++) {
+		outb_p(0x17, padr + 2);
+		n1 = (inb_p(padr + 1) >> 3) & 0x17;
+		outb_p(0x16, padr + 2);
+		n2 = (inb_p(padr + 1) >> 3) & 0x17;
+		*(data++) = nibtab[n1] | (nibtab[n2] << 4);
 	}
-	outb_p(0x14,padr+2);
-	outb_p(0x1c,padr+2);
+	outb_p(0x14, padr + 2);
+	outb_p(0x1c, padr + 2);
 	return;
 }
 
 static inline void
-write_fifo(unsigned int padr, signed int adr, u_char * data, int size)
+write_fifo(unsigned int padr, signed int adr, u_char *data, int size)
 {
 	int i;
-	outb_p(0x1c, padr+2);
-	outb_p(0x14, padr+2);
-	outb_p(adr&0x7f, padr);
-	for (i=0; i<size; i++) {
-		outb_p(0x16, padr+2);
+	outb_p(0x1c, padr + 2);
+	outb_p(0x14, padr + 2);
+	outb_p(adr & 0x7f, padr);
+	for (i = 0; i < size; i++) {
+		outb_p(0x16, padr + 2);
 		outb_p(*(data++), padr);
-		outb_p(0x17, padr+2);
+		outb_p(0x17, padr + 2);
 	}
-	outb_p(0x14,padr+2);
-	outb_p(0x1c,padr+2);
+	outb_p(0x14, padr + 2);
+	outb_p(0x1c, padr + 2);
 	return;
 }
 
@@ -105,13 +105,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	read_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	write_fifo(cs->hw.teles3.cfg_reg, cs->hw.teles3.isacfifo, data, size);
 }
@@ -150,11 +150,11 @@ s0box_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.hscx[1], HSCX_ISTA);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.teles3.cfg_reg, cs->hw.teles3.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	count++;
@@ -194,20 +194,20 @@ S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			break;
-		case CARD_RELEASE:
-			release_io_s0box(cs);
-			break;
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case CARD_TEST:
-			break;
+	case CARD_RESET:
+		break;
+	case CARD_RELEASE:
+		release_io_s0box(cs);
+		break;
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case CARD_TEST:
+		break;
 	}
-	return(0);
+	return (0);
 }
 
 int __devinit
@@ -229,17 +229,17 @@ setup_s0box(struct IsdnCard *card)
 	cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
 	cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
 	cs->irq = card->para[0];
-	if (!request_region(cs->hw.teles3.cfg_reg,8, "S0Box parallel I/O")) {
+	if (!request_region(cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O")) {
 		printk(KERN_WARNING "HiSax: S0Box ports %x-%x already in use\n",
-                       cs->hw.teles3.cfg_reg,
-                       cs->hw.teles3.cfg_reg + 7);
+		       cs->hw.teles3.cfg_reg,
+		       cs->hw.teles3.cfg_reg + 7);
 		return 0;
 	}
 	printk(KERN_INFO "HiSax: S0Box config irq:%d isac:0x%x  cfg:0x%x\n",
-		cs->irq,
-		cs->hw.teles3.isac, cs->hw.teles3.cfg_reg);
+	       cs->irq,
+	       cs->hw.teles3.isac, cs->hw.teles3.cfg_reg);
 	printk(KERN_INFO "HiSax: hscx A:0x%x  hscx B:0x%x\n",
-		cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]);
+	       cs->hw.teles3.hscx[0], cs->hw.teles3.hscx[1]);
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
 	cs->writeisac = &WriteISAC;
diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c
index b34a81d..75dcae6 100644
--- a/drivers/isdn/hisax/saphir.c
+++ b/drivers/isdn/hisax/saphir.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -20,7 +20,7 @@
 
 static char *saphir_rev = "$Revision: 1.10.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define ISAC_DATA	0
@@ -41,7 +41,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -56,7 +56,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -77,13 +77,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
 }
@@ -92,26 +92,26 @@ static u_char
 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
 	return (readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
-		offset + (hscx ? 0x40 : 0)));
+			offset + (hscx ? 0x40 : 0)));
 }
 
 static void
 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 {
 	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
-		offset + (hscx ? 0x40 : 0), value);
+		 offset + (hscx ? 0x40 : 0), value);
 }
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, \
-		cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, \
-		cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale,		\
+				      cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale,	\
+					      cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, \
-		cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale,	\
+						cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, \
-		cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale,	\
+						  cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -124,11 +124,11 @@ saphir_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
@@ -144,8 +144,8 @@ saphir_interrupt(int intno, void *dev_id)
 		goto Start_ISAC;
 	}
 	/* Watchdog */
-	if (cs->hw.saphir.timer.function) 
-		mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
+	if (cs->hw.saphir.timer.function)
+		mod_timer(&cs->hw.saphir.timer, jiffies + 1 * HZ);
 	else
 		printk(KERN_WARNING "saphir: Spurious timer!\n");
 	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0xFF);
@@ -164,10 +164,10 @@ SaphirWatchDog(struct IsdnCardState *cs)
 	u_long flags;
 
 	spin_lock_irqsave(&cs->lock, flags);
-        /* 5 sec WatchDog, so read at least every 4 sec */
+	/* 5 sec WatchDog, so read at least every 4 sec */
 	cs->readisac(cs, ISAC_RBCH);
 	spin_unlock_irqrestore(&cs->lock, flags);
-	mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
+	mod_timer(&cs->hw.saphir.timer, jiffies + 1 * HZ);
 }
 
 static void
@@ -185,24 +185,24 @@ saphir_reset(struct IsdnCardState *cs)
 {
 	u_char irq_val;
 
-	switch(cs->irq) {
-		case 5: irq_val = 0;
-			break;
-		case 3: irq_val = 1;
-			break;
-		case 11:
-			irq_val = 2;
-			break;
-		case 12:
-			irq_val = 3;
-			break;
-		case 15:
-			irq_val = 4;
-			break;
-		default:
-			printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n",
-				cs->irq);
-			return (1);
+	switch (cs->irq) {
+	case 5: irq_val = 0;
+		break;
+	case 3: irq_val = 1;
+		break;
+	case 11:
+		irq_val = 2;
+		break;
+	case 12:
+		irq_val = 3;
+		break;
+	case 15:
+		irq_val = 4;
+		break;
+	default:
+		printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n",
+		       cs->irq);
+		return (1);
 	}
 	byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
 	byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1);
@@ -220,23 +220,23 @@ saphir_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			saphir_reset(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_saphir(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		saphir_reset(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_saphir(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 
@@ -259,9 +259,9 @@ setup_saphir(struct IsdnCard *card)
 	cs->irq = card->para[0];
 	if (!request_region(cs->hw.saphir.cfg_reg, 6, "saphir")) {
 		printk(KERN_WARNING
-			"HiSax: HST Saphir config port %x-%x already in use\n",
-			cs->hw.saphir.cfg_reg,
-			cs->hw.saphir.cfg_reg + 5);
+		       "HiSax: HST Saphir config port %x-%x already in use\n",
+		       cs->hw.saphir.cfg_reg,
+		       cs->hw.saphir.cfg_reg + 5);
 		return (0);
 	}
 
@@ -272,7 +272,7 @@ setup_saphir(struct IsdnCard *card)
 	cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
 	cs->hw.saphir.timer.data = (long) cs;
 	init_timer(&cs->hw.saphir.timer);
-	cs->hw.saphir.timer.expires = jiffies + 4*HZ;
+	cs->hw.saphir.timer.expires = jiffies + 4 * HZ;
 	add_timer(&cs->hw.saphir.timer);
 	if (saphir_reset(cs)) {
 		release_io_saphir(cs);
@@ -290,7 +290,7 @@ setup_saphir(struct IsdnCard *card)
 	ISACVersion(cs, "saphir:");
 	if (HscxVersion(cs, "saphir:")) {
 		printk(KERN_WARNING
-		    "saphir: wrong HSCX versions check IO address\n");
+		       "saphir: wrong HSCX versions check IO address\n");
 		release_io_saphir(cs);
 		return (0);
 	}
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index 69dfc8d..1ee531b 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -9,7 +9,7 @@
  *
  * Author       Marcus Niemann
  * Copyright    by Marcus Niemann    <niemann@www-bib.fh-bielefeld.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -30,13 +30,13 @@
  * ISDN PC/104	IPAC		DIP-SWITCH
  * Speed Star2	IPAC		CARDMGR
  * Speed PCI	IPAC		PCI PNP
- * Speed Fax+ 	ISAC_ISAR	PCI PNP		Full analog support
+ * Speed Fax+	ISAC_ISAR	PCI PNP		Full analog support
  *
  * Important:
  * For the sedlbauer speed fax+ to work properly you have to download
  * the firmware onto the card.
  * For example: hisaxctrl <DriverID> 9 ISAR.BIN
-*/
+ */
 
 #include <linux/init.h>
 #include "hisax.h"
@@ -51,9 +51,9 @@
 static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
 
 static const char *Sedlbauer_Types[] =
-	{"None", "speed card/win", "speed star", "speed fax+",
-	"speed win II / ISDN PC/104", "speed star II", "speed pci",
-	"speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
+{"None", "speed card/win", "speed star", "speed fax+",
+ "speed win II / ISDN PC/104", "speed star II", "speed pci",
+ "speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
 
 #define PCI_SUBVENDOR_SPEEDFAX_PYRAMID	0x51
 #define PCI_SUBVENDOR_HST_SAPHIR3	0x52
@@ -62,11 +62,11 @@ static const char *Sedlbauer_Types[] =
 #define PCI_SUB_ID_SEDLBAUER		0x01
 
 #define SEDL_SPEED_CARD_WIN	1
-#define SEDL_SPEED_STAR 	2
+#define SEDL_SPEED_STAR		2
 #define SEDL_SPEED_FAX		3
-#define SEDL_SPEED_WIN2_PC104 	4
-#define SEDL_SPEED_STAR2 	5
-#define SEDL_SPEED_PCI   	6
+#define SEDL_SPEED_WIN2_PC104	4
+#define SEDL_SPEED_STAR2	5
+#define SEDL_SPEED_PCI		6
 #define SEDL_SPEEDFAX_PYRAMID	7
 #define SEDL_SPEEDFAX_PCI	8
 #define HST_SAPHIR3		9
@@ -80,7 +80,7 @@ static const char *Sedlbauer_Types[] =
 #define SEDL_BUS_PCI		2
 #define	SEDL_BUS_PCMCIA		3
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define SEDL_HSCX_ISA_RESET_ON	0
@@ -127,7 +127,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	insb(adr, data, size);
@@ -142,7 +142,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	byteout(ale, off);
 	outsb(adr, data, size);
@@ -163,13 +163,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
 }
@@ -177,23 +177,23 @@ WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
 static u_char
 ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
 {
-	return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80));
+	return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset | 0x80));
 }
 
 static void
 WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
 {
-	writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80, value);
+	writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset | 0x80, value);
 }
 
 static void
-ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
 }
 
 static void
-WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
 {
 	writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
 }
@@ -220,12 +220,12 @@ WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
 
 static u_char
 ReadISAR(struct IsdnCardState *cs, int mode, u_char offset)
-{	
+{
 	if (mode == 0)
 		return (readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, offset));
 	else if (mode == 1)
 		byteout(cs->hw.sedl.adr, offset);
-	return(bytein(cs->hw.sedl.hscx));
+	return (bytein(cs->hw.sedl.hscx));
 }
 
 static void
@@ -244,16 +244,16 @@ WriteISAR(struct IsdnCardState *cs, int mode, u_char offset, u_char value)
  * fast interrupt HSCX stuff goes here
  */
 
-#define READHSCX(cs, nr, reg) readreg(cs->hw.sedl.adr, \
-		cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.sedl.adr, \
-		cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.sedl.adr,			\
+				      cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.sedl.adr,		\
+					      cs->hw.sedl.hscx, reg + (nr ? 0x40 : 0), data)
 
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.sedl.adr, \
-		cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.sedl.adr,	\
+						cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.sedl.adr, \
-		cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.sedl.adr,	\
+						  cs->hw.sedl.hscx, (nr ? 0x40 : 0), ptr, cnt)
 
 #include "hscx_irq.c"
 
@@ -274,11 +274,11 @@ sedlbauer_interrupt(int intno, void *dev_id)
 	}
 
 	val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
@@ -360,11 +360,11 @@ sedlbauer_interrupt_isar(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
-      Start_ISAR:
+Start_ISAR:
 	if (val & ISAR_IRQSTA)
 		isar_int_main(cs);
 	val = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, ISAR_IRQBIT);
@@ -411,7 +411,7 @@ reset_sedlbauer(struct IsdnCardState *cs)
 	printk(KERN_INFO "Sedlbauer: resetting card\n");
 
 	if (!((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) &&
-	   (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) {
+	      (cs->hw.sedl.chip == SEDL_CHIP_ISAC_HSCX))) {
 		if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
 			writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20);
 			mdelay(2);
@@ -423,12 +423,12 @@ reset_sedlbauer(struct IsdnCardState *cs)
 			writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0);
 			writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12);
 		} else if ((cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) &&
-			(cs->hw.sedl.bus == SEDL_BUS_PCI)) {
-			byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
+			   (cs->hw.sedl.bus == SEDL_BUS_PCI)) {
+			byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_on);
 			mdelay(2);
-			byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
+			byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off);
 			mdelay(10);
-		} else {		
+		} else {
 			byteout(cs->hw.sedl.reset_on, SEDL_RESET);	/* Reset On */
 			mdelay(2);
 			byteout(cs->hw.sedl.reset_off, 0);	/* Reset Off */
@@ -443,86 +443,86 @@ Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_sedlbauer(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			if (cs->hw.sedl.bus == SEDL_BUS_PCI)
-				/* disable all IRQ */
-				byteout(cs->hw.sedl.cfg_reg+ 5, 0);
-			if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
-				spin_lock_irqsave(&cs->lock, flags);
-				writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
-					ISAR_IRQBIT, 0);
-				writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
-					ISAC_MASK, 0xFF);
-				reset_sedlbauer(cs);
-				writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
-					ISAR_IRQBIT, 0);
-				writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
-					ISAC_MASK, 0xFF);
-				spin_unlock_irqrestore(&cs->lock, flags);
-			}
-			release_io_sedlbauer(cs);
-			return(0);
-		case CARD_INIT:
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_sedlbauer(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		if (cs->hw.sedl.bus == SEDL_BUS_PCI)
+			/* disable all IRQ */
+			byteout(cs->hw.sedl.cfg_reg + 5, 0);
+		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
 			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->hw.sedl.bus == SEDL_BUS_PCI)
-				/* enable all IRQ */
-				byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
+			writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
+				 ISAR_IRQBIT, 0);
+			writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
+				 ISAC_MASK, 0xFF);
 			reset_sedlbauer(cs);
-			if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
-				clear_pending_isac_ints(cs);
-				writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
-					ISAR_IRQBIT, 0);
-				initisac(cs);
-				initisar(cs);
-				/* Reenable all IRQ */
-				cs->writeisac(cs, ISAC_MASK, 0);
-				/* RESET Receiver and Transmitter */
-				cs->writeisac(cs, ISAC_CMDR, 0x41);
-			} else {
-				inithscxisac(cs, 3);
-			}
+			writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
+				 ISAR_IRQBIT, 0);
+			writereg(cs->hw.sedl.adr, cs->hw.sedl.isac,
+				 ISAC_MASK, 0xFF);
 			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
-		case MDL_INFO_CONN:
-			if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
-				return(0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if ((long) arg)
-				cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2;
-			else
-				cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1;
-			byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case MDL_INFO_REL:
-			if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
-				return(0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if ((long) arg)
-				cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2;
-			else
-				cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1;
-			byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
+		}
+		release_io_sedlbauer(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->hw.sedl.bus == SEDL_BUS_PCI)
+			/* enable all IRQ */
+			byteout(cs->hw.sedl.cfg_reg + 5, 0x02);
+		reset_sedlbauer(cs);
+		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
+			clear_pending_isac_ints(cs);
+			writereg(cs->hw.sedl.adr, cs->hw.sedl.hscx,
+				 ISAR_IRQBIT, 0);
+			initisac(cs);
+			initisar(cs);
+			/* Reenable all IRQ */
+			cs->writeisac(cs, ISAC_MASK, 0);
+			/* RESET Receiver and Transmitter */
+			cs->writeisac(cs, ISAC_CMDR, 0x41);
+		} else {
+			inithscxisac(cs, 3);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
+	case MDL_INFO_CONN:
+		if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
+			return (0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if ((long) arg)
+			cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED2;
+		else
+			cs->hw.sedl.reset_off &= ~SEDL_ISAR_PCI_LED1;
+		byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case MDL_INFO_REL:
+		if (cs->subtyp != SEDL_SPEEDFAX_PYRAMID)
+			return (0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if ((long) arg)
+			cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED2;
+		else
+			cs->hw.sedl.reset_off |= SEDL_ISAR_PCI_LED1;
+		byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
 	}
-	return(0);
+	return (0);
 }
 
 #ifdef __ISAPNP__
 static struct isapnp_device_id sedl_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
-	  ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01), 
+	  ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
 	  (unsigned long) "Speed win" },
 	{ ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
-	  ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02), 
+	  ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
 	  (unsigned long) "Speed Fax+" },
 	{ 0, }
 };
@@ -539,31 +539,31 @@ setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt)
 	if (!isapnp_present())
 		return -1;
 
-	while(ipid->card_vendor) {
+	while (ipid->card_vendor) {
 		if ((pnp_c = pnp_find_card(ipid->card_vendor,
-			ipid->card_device, pnp_c))) {
+					   ipid->card_device, pnp_c))) {
 			pnp_d = NULL;
 			if ((pnp_d = pnp_find_dev(pnp_c,
-				ipid->vendor, ipid->function, pnp_d))) {
+						  ipid->vendor, ipid->function, pnp_d))) {
 				int err;
 
 				printk(KERN_INFO "HiSax: %s detected\n",
-					(char *)ipid->driver_data);
+				       (char *)ipid->driver_data);
 				pnp_disable_dev(pnp_d);
 				err = pnp_activate_dev(pnp_d);
-				if (err<0) {
+				if (err < 0) {
 					printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-						__func__, err);
-					return(0);
+					       __func__, err);
+					return (0);
 				}
 				card->para[1] = pnp_port_start(pnp_d, 0);
 				card->para[0] = pnp_irq(pnp_d, 0);
 
 				if (!card->para[0] || !card->para[1]) {
 					printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
-						card->para[0], card->para[1]);
+					       card->para[0], card->para[1]);
 					pnp_disable_dev(pnp_d);
-					return(0);
+					return (0);
 				}
 				cs->hw.sedl.cfg_reg = card->para[1];
 				cs->irq = card->para[0];
@@ -579,12 +579,12 @@ setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt)
 				return (1);
 			} else {
 				printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
-				return(0);
+				return (0);
 			}
 		}
 		ipid++;
 		pnp_c = NULL;
-	} 
+	}
 
 	printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n");
 	return -1;
@@ -608,30 +608,30 @@ setup_sedlbauer_pci(struct IsdnCard *card)
 	u16 sub_vendor_id, sub_id;
 
 	if ((dev_sedl = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
-			PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
+					      PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
 		if (pci_enable_device(dev_sedl))
-			return(0);
+			return (0);
 		cs->irq = dev_sedl->irq;
 		if (!cs->irq) {
 			printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
-			return(0);
+			return (0);
 		}
 		cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
 	} else {
 		printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
-		return(0);
+		return (0);
 	}
 	cs->irq_flags |= IRQF_SHARED;
 	cs->hw.sedl.bus = SEDL_BUS_PCI;
 	sub_vendor_id = dev_sedl->subsystem_vendor;
 	sub_id = dev_sedl->subsystem_device;
 	printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
-		sub_vendor_id, sub_id);
+	       sub_vendor_id, sub_id);
 	printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
-		cs->hw.sedl.cfg_reg);
+	       cs->hw.sedl.cfg_reg);
 	if (sub_id != PCI_SUB_ID_SEDLBAUER) {
 		printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
-		return(0);
+		return (0);
 	}
 	if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
 		cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
@@ -647,19 +647,19 @@ setup_sedlbauer_pci(struct IsdnCard *card)
 		cs->subtyp = SEDL_SPEED_PCI;
 	} else {
 		printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
-			sub_vendor_id);
-		return(0);
+		       sub_vendor_id);
+		return (0);
 	}
 
 	cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
 	cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
 	byteout(cs->hw.sedl.cfg_reg, 0xff);
 	byteout(cs->hw.sedl.cfg_reg, 0x00);
-	byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
-	byteout(cs->hw.sedl.cfg_reg+ 5, 0); /* disable all IRQ */
-	byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
+	byteout(cs->hw.sedl.cfg_reg + 2, 0xdd);
+	byteout(cs->hw.sedl.cfg_reg + 5, 0); /* disable all IRQ */
+	byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_on);
 	mdelay(2);
-	byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
+	byteout(cs->hw.sedl.cfg_reg + 3, cs->hw.sedl.reset_off);
 	mdelay(10);
 
 	return (1);
@@ -684,20 +684,20 @@ setup_sedlbauer(struct IsdnCard *card)
 
 	strcpy(tmp, Sedlbauer_revision);
 	printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
-	
- 	if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
- 		cs->subtyp = SEDL_SPEED_CARD_WIN;
+
+	if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
+		cs->subtyp = SEDL_SPEED_CARD_WIN;
 		cs->hw.sedl.bus = SEDL_BUS_ISA;
 		cs->hw.sedl.chip = SEDL_CHIP_TEST;
- 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {	
- 		cs->subtyp = SEDL_SPEED_STAR;
+	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
+		cs->subtyp = SEDL_SPEED_STAR;
 		cs->hw.sedl.bus = SEDL_BUS_PCMCIA;
 		cs->hw.sedl.chip = SEDL_CHIP_TEST;
- 	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {	
- 		cs->subtyp = SEDL_SPEED_FAX;
+	} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
+		cs->subtyp = SEDL_SPEED_FAX;
 		cs->hw.sedl.bus = SEDL_BUS_ISA;
 		cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
- 	} else
+	} else
 		return (0);
 
 	bytecnt = 8;
@@ -720,22 +720,22 @@ setup_sedlbauer(struct IsdnCard *card)
 			return (0);
 
 		bytecnt = 256;
-	}	
+	}
 
-ready:	
+ready:
 
 	/* In case of the sedlbauer pcmcia card, this region is in use,
 	 * reserved for us by the card manager. So we do not check it
 	 * here, it would fail.
 	 */
 	if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
-		!request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) {
+	    !request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) {
 		printk(KERN_WARNING
-			"HiSax: %s config port %x-%x already in use\n",
-			CardType[card->typ],
-			cs->hw.sedl.cfg_reg,
-			cs->hw.sedl.cfg_reg + bytecnt);
-			return (0);
+		       "HiSax: %s config port %x-%x already in use\n",
+		       CardType[card->typ],
+		       cs->hw.sedl.cfg_reg,
+		       cs->hw.sedl.cfg_reg + bytecnt);
+		return (0);
 	}
 
 	printk(KERN_INFO
@@ -753,12 +753,12 @@ ready:
  * testing ISA and PCMCIA Cards for IPAC, default is ISAC
  * do not test for PCI card, because ports are different
  * and PCI card uses only IPAC (for the moment)
- */	
+ */
 	if (cs->hw.sedl.bus != SEDL_BUS_PCI) {
 		val = readreg(cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR,
-			cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
+			      cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID);
 		printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val);
-	        if ((val == 1) || (val == 2)) {
+		if ((val == 1) || (val == 2)) {
 			/* IPAC */
 			cs->subtyp = SEDL_SPEED_WIN2_PC104;
 			if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
@@ -777,16 +777,16 @@ ready:
  * hw.sedl.chip is now properly set
  */
 	printk(KERN_INFO "Sedlbauer: %s detected\n",
-		Sedlbauer_Types[cs->subtyp]);
+	       Sedlbauer_Types[cs->subtyp]);
 
 	setup_isac(cs);
 	if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) {
 		if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
-	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
+			cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR;
 			cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
 			cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC;
 		} else {
-	                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
+			cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR;
 			cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
 			cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC;
 		}
@@ -807,22 +807,22 @@ ready:
 		if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
 			if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
 				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_PCI_ADR;
+					SEDL_ISAR_PCI_ADR;
 				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_PCI_ISAC;
+					SEDL_ISAR_PCI_ISAC;
 				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_PCI_ISAR;
+					SEDL_ISAR_PCI_ISAR;
 			} else {
 				cs->hw.sedl.adr = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_ISA_ADR;
+					SEDL_ISAR_ISA_ADR;
 				cs->hw.sedl.isac = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_ISA_ISAC;
+					SEDL_ISAR_ISA_ISAC;
 				cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_ISA_ISAR;
+					SEDL_ISAR_ISA_ISAR;
 				cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_ISA_ISAR_RESET_ON;
+					SEDL_ISAR_ISA_ISAR_RESET_ON;
 				cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
-							SEDL_ISAR_ISA_ISAR_RESET_OFF;
+					SEDL_ISAR_ISA_ISAR_RESET_OFF;
 			}
 			cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar;
 			cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar;
@@ -838,7 +838,7 @@ ready:
 				ver = ISARVersion(cs, "Sedlbauer:");
 				if (ver < 0)
 					printk(KERN_WARNING
-						"Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
+					       "Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
 				else
 					break;
 				reset_sedlbauer(cs);
@@ -865,10 +865,10 @@ ready:
 			}
 			cs->irq_func = &sedlbauer_interrupt;
 			ISACVersion(cs, "Sedlbauer:");
-		
+
 			if (HscxVersion(cs, "Sedlbauer:")) {
 				printk(KERN_WARNING
-					"Sedlbauer: wrong HSCX versions check IO address\n");
+				       "Sedlbauer: wrong HSCX versions check IO address\n");
 				release_io_sedlbauer(cs);
 				return (0);
 			}
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 06473f8..68f5049 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -1,39 +1,39 @@
 /*======================================================================
 
-    A Sedlbauer PCMCIA client driver
-
-    This driver is for the Sedlbauer Speed Star and Speed Star II, 
-    which are ISDN PCMCIA Cards.
-    
-    The contents of this file are subject to the Mozilla Public
-    License Version 1.1 (the "License"); you may not use this file
-    except in compliance with the License. You may obtain a copy of
-    the License at http://www.mozilla.org/MPL/
-
-    Software distributed under the License is distributed on an "AS
-    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-    implied. See the License for the specific language governing
-    rights and limitations under the License.
-
-    The initial developer of the original code is David A. Hinds
-    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
-    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
-
-    Modifications from dummy_cs.c are Copyright (C) 1999-2001 Marcus Niemann
-    <maniemann@users.sourceforge.net>. All Rights Reserved.
-
-    Alternatively, the contents of this file may be used under the
-    terms of the GNU General Public License version 2 (the "GPL"), in
-    which case the provisions of the GPL are applicable instead of the
-    above.  If you wish to allow the use of your version of this file
-    only under the terms of the GPL and not to allow others to use
-    your version of this file under the MPL, indicate your decision
-    by deleting the provisions above and replace them with the notice
-    and other provisions required by the GPL.  If you do not delete
-    the provisions above, a recipient may use your version of this
-    file under either the MPL or the GPL.
-    
-======================================================================*/
+  A Sedlbauer PCMCIA client driver
+
+  This driver is for the Sedlbauer Speed Star and Speed Star II,
+  which are ISDN PCMCIA Cards.
+
+  The contents of this file are subject to the Mozilla Public
+  License Version 1.1 (the "License"); you may not use this file
+  except in compliance with the License. You may obtain a copy of
+  the License at http://www.mozilla.org/MPL/
+
+  Software distributed under the License is distributed on an "AS
+  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+  implied. See the License for the specific language governing
+  rights and limitations under the License.
+
+  The initial developer of the original code is David A. Hinds
+  <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+  are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+
+  Modifications from dummy_cs.c are Copyright (C) 1999-2001 Marcus Niemann
+  <maniemann@users.sourceforge.net>. All Rights Reserved.
+
+  Alternatively, the contents of this file may be used under the
+  terms of the GNU General Public License version 2 (the "GPL"), in
+  which case the provisions of the GPL are applicable instead of the
+  above.  If you wish to allow the use of your version of this file
+  only under the terms of the GPL and not to allow others to use
+  your version of this file under the MPL, indicate your decision
+  by deleting the provisions above and replace them with the notice
+  and other provisions required by the GPL.  If you do not delete
+  the provisions above, a recipient may use your version of this
+  file under either the MPL or the GPL.
+
+  ======================================================================*/
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -63,32 +63,32 @@ MODULE_LICENSE("Dual MPL/GPL");
 static int protocol = 2;        /* EURO-ISDN Default */
 module_param(protocol, int, 0);
 
-static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
+static int sedlbauer_config(struct pcmcia_device *link) __devinit;
 static void sedlbauer_release(struct pcmcia_device *link);
 
 static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
 
 typedef struct local_info_t {
 	struct pcmcia_device	*p_dev;
-    int			stop;
-    int			cardnr;
+	int			stop;
+	int			cardnr;
 } local_info_t;
 
 static int __devinit sedlbauer_probe(struct pcmcia_device *link)
 {
-    local_info_t *local;
+	local_info_t *local;
 
-    dev_dbg(&link->dev, "sedlbauer_attach()\n");
+	dev_dbg(&link->dev, "sedlbauer_attach()\n");
 
-    /* Allocate space for private device-specific data */
-    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return -ENOMEM;
-    local->cardnr = -1;
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (!local) return -ENOMEM;
+	local->cardnr = -1;
 
-    local->p_dev = link;
-    link->priv = local;
+	local->p_dev = link;
+	link->priv = local;
 
-    return sedlbauer_config(link);
+	return sedlbauer_config(link);
 } /* sedlbauer_attach */
 
 static void __devexit sedlbauer_detach(struct pcmcia_device *link)
@@ -113,58 +113,58 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev, void *priv_data)
 
 static int __devinit sedlbauer_config(struct pcmcia_device *link)
 {
-    int ret;
-    IsdnCard_t  icard;
-
-    dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
-
-    link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
-	    CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
-
-    ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL);
-    if (ret)
-	    goto failed;
-
-    ret = pcmcia_enable_device(link);
-    if (ret)
-	    goto failed;
-
-    icard.para[0] = link->irq;
-    icard.para[1] = link->resource[0]->start;
-    icard.protocol = protocol;
-    icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
-    
-    ret = hisax_init_pcmcia(link, 
-			    &(((local_info_t *)link->priv)->stop), &icard);
-    if (ret < 0) {
-	printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n",
-		ret, link->resource[0]);
-    	sedlbauer_release(link);
-	return -ENODEV;
-    } else
-	((local_info_t *)link->priv)->cardnr = ret;
+	int ret;
+	IsdnCard_t  icard;
+
+	dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
 
-    return 0;
+	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
+		CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
+
+	ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL);
+	if (ret)
+		goto failed;
+
+	ret = pcmcia_enable_device(link);
+	if (ret)
+		goto failed;
+
+	icard.para[0] = link->irq;
+	icard.para[1] = link->resource[0]->start;
+	icard.protocol = protocol;
+	icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
+
+	ret = hisax_init_pcmcia(link,
+				&(((local_info_t *)link->priv)->stop), &icard);
+	if (ret < 0) {
+		printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n",
+		       ret, link->resource[0]);
+		sedlbauer_release(link);
+		return -ENODEV;
+	} else
+		((local_info_t *)link->priv)->cardnr = ret;
+
+	return 0;
 
 failed:
-    sedlbauer_release(link);
-    return -ENODEV;
+	sedlbauer_release(link);
+	return -ENODEV;
 
 } /* sedlbauer_config */
 
 static void sedlbauer_release(struct pcmcia_device *link)
 {
-    local_info_t *local = link->priv;
-    dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
-
-    if (local) {
-    	if (local->cardnr >= 0) {
-    	    /* no unregister function with hisax */
-	    HiSax_closecard(local->cardnr);
+	local_info_t *local = link->priv;
+	dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
+
+	if (local) {
+		if (local->cardnr >= 0) {
+			/* no unregister function with hisax */
+			HiSax_closecard(local->cardnr);
+		}
 	}
-    }
 
-    pcmcia_disable_device(link);
+	pcmcia_disable_device(link);
 } /* sedlbauer_release */
 
 static int sedlbauer_suspend(struct pcmcia_device *link)
diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c
index 0a53759..1267298 100644
--- a/drivers/isdn/hisax/sportster.c
+++ b/drivers/isdn/hisax/sportster.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -20,7 +20,7 @@
 
 static const char *sportster_revision = "$Revision: 1.16.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 #define	 SPORTSTER_ISAC		0xC000
@@ -33,17 +33,17 @@ static const char *sportster_revision = "$Revision: 1.16.2.4 $";
 static inline int
 calc_off(unsigned int base, unsigned int off)
 {
-	return(base + ((off & 0xfc)<<8) + ((off & 3)<<1));
+	return (base + ((off & 0xfc) << 8) + ((off & 3) << 1));
 }
 
 static inline void
-read_fifo(unsigned int adr, u_char * data, int size)
+read_fifo(unsigned int adr, u_char *data, int size)
 {
 	insb(adr, data, size);
 }
 
 static void
-write_fifo(unsigned int adr, u_char * data, int size)
+write_fifo(unsigned int adr, u_char *data, int size)
 {
 	outsb(adr, data, size);
 }
@@ -63,13 +63,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	read_fifo(cs->hw.spt.isac, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	write_fifo(cs->hw.spt.isac, data, size);
 }
@@ -106,11 +106,11 @@ sportster_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = READHSCX(cs, 1, HSCX_ISTA);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = ReadISAC(cs, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = READHSCX(cs, 1, HSCX_ISTA);
@@ -126,7 +126,7 @@ sportster_interrupt(int intno, void *dev_id)
 		goto Start_ISAC;
 	}
 	/* get a new irq impulse if there any pending */
-	bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ +1);
+	bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ + 1);
 	spin_unlock_irqrestore(&cs->lock, flags);
 	return IRQ_HANDLED;
 }
@@ -137,8 +137,8 @@ release_io_sportster(struct IsdnCardState *cs)
 	int i, adr;
 
 	byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, 0);
-	for (i=0; i<64; i++) {
-		adr = cs->hw.spt.cfg_reg + i *1024;
+	for (i = 0; i < 64; i++) {
+		adr = cs->hw.spt.cfg_reg + i * 1024;
 		release_region(adr, 8);
 	}
 }
@@ -160,51 +160,51 @@ Sportster_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_sportster(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_sportster(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_sportster(cs);
-			inithscxisac(cs, 1);
-			cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */
-			byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
-			inithscxisac(cs, 2);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_sportster(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_sportster(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_sportster(cs);
+		inithscxisac(cs, 1);
+		cs->hw.spt.res_irq |= SPORTSTER_INTE; /* IRQ On */
+		byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq);
+		inithscxisac(cs, 2);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 static int __devinit
 get_io_range(struct IsdnCardState *cs)
 {
 	int i, j, adr;
-	
-	for (i=0;i<64;i++) {
-		adr = cs->hw.spt.cfg_reg + i *1024;
+
+	for (i = 0; i < 64; i++) {
+		adr = cs->hw.spt.cfg_reg + i * 1024;
 		if (!request_region(adr, 8, "sportster")) {
 			printk(KERN_WARNING "HiSax: USR Sportster config port "
-				"%x-%x already in use\n",
-				adr, adr + 8);
+			       "%x-%x already in use\n",
+			       adr, adr + 8);
 			break;
-		} 
+		}
 	}
-	if (i==64)
-		return(1);
+	if (i == 64)
+		return (1);
 	else {
-		for (j=0; j<i; j++) {
-			adr = cs->hw.spt.cfg_reg + j *1024;
+		for (j = 0; j < i; j++) {
+			adr = cs->hw.spt.cfg_reg + j * 1024;
 			release_region(adr, 8);
 		}
-		return(0);
+		return (0);
 	}
 }
 
@@ -226,28 +226,28 @@ setup_sportster(struct IsdnCard *card)
 	cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC;
 	cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA;
 	cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB;
-	
-	switch(cs->irq) {
-		case 5:	cs->hw.spt.res_irq = 1;
-			break;
-		case 7:	cs->hw.spt.res_irq = 2;
-			break;
-		case 10:cs->hw.spt.res_irq = 3;
-			break;
-		case 11:cs->hw.spt.res_irq = 4;
-			break;
-		case 12:cs->hw.spt.res_irq = 5;
-			break;
-		case 14:cs->hw.spt.res_irq = 6;
-			break;
-		case 15:cs->hw.spt.res_irq = 7;
-			break;
-		default:release_io_sportster(cs);
-			printk(KERN_WARNING "Sportster: wrong IRQ\n");
-			return(0);
+
+	switch (cs->irq) {
+	case 5:	cs->hw.spt.res_irq = 1;
+		break;
+	case 7:	cs->hw.spt.res_irq = 2;
+		break;
+	case 10:cs->hw.spt.res_irq = 3;
+		break;
+	case 11:cs->hw.spt.res_irq = 4;
+		break;
+	case 12:cs->hw.spt.res_irq = 5;
+		break;
+	case 14:cs->hw.spt.res_irq = 6;
+		break;
+	case 15:cs->hw.spt.res_irq = 7;
+		break;
+	default:release_io_sportster(cs);
+		printk(KERN_WARNING "Sportster: wrong IRQ\n");
+		return (0);
 	}
 	printk(KERN_INFO "HiSax: USR Sportster config irq:%d cfg:0x%X\n",
-		cs->irq, cs->hw.spt.cfg_reg);
+	       cs->irq, cs->hw.spt.cfg_reg);
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
 	cs->writeisac = &WriteISAC;
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
index b9054cb..8cd2d82 100644
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -4,7 +4,7 @@
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
  *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -31,7 +31,7 @@
 #define EP_B2_IN  0x05U /* B2 channel in */
 #define EP_D_OUT  0x06U /* D channel out */
 #define EP_D_IN   0x07U /* D channel in */
-  
+
 // Number of isochronous packets. With 20 packets we get
 // 50 interrupts/sec for each endpoint.
 
@@ -51,7 +51,7 @@
 #define B_FLOW_ADJUST 2
 
 // Registers that are written using vendor specific device request
-// on endpoint 0. 
+// on endpoint 0.
 
 #define LBA			0x02 /* S loopback */
 #define SET_DEFAULT		0x06 /* Soft reset */
@@ -84,7 +84,7 @@
 #define	FFMSK_B2		0x50 /* B2 fifo interrupt MASK register */
 #define GPIO_DIR		0x52 /* GPIO pins direction registers */
 #define GPIO_OUT		0x53 /* GPIO pins output register */
-#define GPIO_IN			0x54 /* GPIO pins input register */ 
+#define GPIO_IN			0x54 /* GPIO pins input register */
 #define TXCI			0x56 /* CI command to be transmitted */
 
 
@@ -124,8 +124,8 @@
 #define IN_COUNTER_ZEROED	0x02 /* In down-counter reached 0 */
 #define OUT_COUNTER_ZEROED	0x01 /* Out down-counter reached 0 */
 
-#define ANY_REC_INT	(IN_OVERRUN+IN_UP+IN_DOWN+IN_COUNTER_ZEROED)
-#define ANY_XMIT_INT	(OUT_UNDERRUN+OUT_UP+OUT_DOWN+OUT_COUNTER_ZEROED)
+#define ANY_REC_INT	(IN_OVERRUN + IN_UP + IN_DOWN + IN_COUNTER_ZEROED)
+#define ANY_XMIT_INT	(OUT_UNDERRUN + OUT_UP + OUT_DOWN + OUT_COUNTER_ZEROED)
 
 
 // Level 1 commands that are sent using the TXCI device request
@@ -158,7 +158,7 @@ enum {
 	ST_DOUT_NORMAL,
 
 	ST_DOUT_WAIT_FOR_UNDERRUN,
-        ST_DOUT_WAIT_FOR_NOT_BUSY,
+	ST_DOUT_WAIT_FOR_NOT_BUSY,
 	ST_DOUT_WAIT_FOR_STOP,
 	ST_DOUT_WAIT_FOR_RESET,
 };
@@ -188,9 +188,9 @@ enum {
 	ST_L1_F8,
 };
 
-#define L1_STATE_COUNT (ST_L1_F8+1)
+#define L1_STATE_COUNT (ST_L1_F8 + 1)
 
-// The first 16 entries match the Level 1 indications that 
+// The first 16 entries match the Level 1 indications that
 // are found at offset 4 (CCIST) in the interrupt packet
 
 enum {
@@ -217,14 +217,14 @@ enum {
 
 #define L1_EVENT_COUNT (EV_TIMER3 + 1)
 
-#define ERR(format, arg...) \
-printk(KERN_ERR "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
+#define ERR(format, arg...)						\
+	printk(KERN_ERR "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
 
-#define WARNING(format, arg...) \
-printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
+#define WARNING(format, arg...)						\
+	printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
 
-#define INFO(format, arg...) \
-printk(KERN_INFO "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
+#define INFO(format, arg...)						\
+	printk(KERN_INFO "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
 
 #include <linux/isdn/hdlc.h>
 #include "fsm.h"
@@ -237,7 +237,7 @@ printk(KERN_INFO "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
 
 /* Generic FIFO structure */
 struct fifo {
-	u_char r,w,count,size;
+	u_char r, w, count, size;
 	spinlock_t lock;
 };
 
@@ -269,7 +269,7 @@ static inline int fifo_add(struct fifo *fifo)
 		index = -1;
 	} else {
 		// Return index where to get the next data to add to the FIFO
-		index = fifo->w++ & (fifo->size-1);
+		index = fifo->w++ & (fifo->size - 1);
 		fifo->count++;
 	}
 	spin_unlock_irqrestore(&fifo->lock, flags);
@@ -294,7 +294,7 @@ static inline int fifo_remove(struct fifo *fifo)
 		index = -1;
 	} else {
 		// Return index where to get the next data from the FIFO
-		index = fifo->r++ & (fifo->size-1);
+		index = fifo->r++ & (fifo->size - 1);
 		fifo->count--;
 	}
 	spin_unlock_irqrestore(&fifo->lock, flags);
@@ -311,14 +311,14 @@ typedef struct ctrl_msg {
 	struct usb_ctrlrequest dr;
 	ctrl_complete_t complete;
 	void *context;
-} ctrl_msg; 
+} ctrl_msg;
 
 /* FIFO of ctrl messages waiting to be sent */
 #define MAX_EP0_MSG 16
 struct ctrl_msg_fifo {
 	struct fifo f;
 	struct ctrl_msg data[MAX_EP0_MSG];
-};	
+};
 
 #define MAX_DFRAME_LEN_L1	300
 #define HSCX_BUFMAX	4096
@@ -330,7 +330,7 @@ struct st5481_ctrl {
 };
 
 struct st5481_intr {
-  //	struct evt_fifo evt_fifo;
+	//	struct evt_fifo evt_fifo;
 	struct urb *urb;
 };
 
@@ -407,21 +407,21 @@ struct st5481_adapter {
  * Submit an URB with error reporting. This is a macro so
  * the __func__ returns the caller function name.
  */
-#define SUBMIT_URB(urb, mem_flags) \
-({ \
-	int status; \
-	if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \
-		WARNING("usb_submit_urb failed,status=%d", status); \
-	} \
-        status; \
-})
+#define SUBMIT_URB(urb, mem_flags)					\
+	({								\
+		int status;						\
+		if ((status = usb_submit_urb(urb, mem_flags)) < 0) {	\
+			WARNING("usb_submit_urb failed,status=%d", status); \
+		}							\
+		status;							\
+	})
 
 /*
  * USB double buffering, return the URB index (0 or 1).
  */
 static inline int get_buf_nr(struct urb *urbs[], struct urb *urb)
 {
-        return (urbs[0]==urb ? 0 : 1); 
+	return (urbs[0] == urb ? 0 : 1);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -442,17 +442,17 @@ void st5481_d_exit(void);
 
 /* USB */
 void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command);
-int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, 
+int st5481_setup_isocpipes(struct urb *urb[2], struct usb_device *dev,
 			   unsigned int pipe, int num_packets,
 			   int packet_size, int buf_size,
 			   usb_complete_t complete, void *context);
-void st5481_release_isocpipes(struct urb* urb[2]);
+void st5481_release_isocpipes(struct urb *urb[2]);
 
 void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
-		    u_char pipe, ctrl_complete_t complete, void *context);
+			   u_char pipe, ctrl_complete_t complete, void *context);
 void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
-			 u8 request, u16 value,
-			 ctrl_complete_t complete, void *context);
+				u8 request, u16 value,
+				ctrl_complete_t complete, void *context);
 int  st5481_setup_usb(struct st5481_adapter *adapter);
 void st5481_release_usb(struct st5481_adapter *adapter);
 void st5481_start(struct st5481_adapter *adapter);
@@ -468,18 +468,18 @@ extern int st5481_debug;
 
 #ifdef CONFIG_HISAX_DEBUG
 
-#define DBG_ISO_PACKET(level,urb) \
-  if (level & __debug_variable) dump_iso_packet(__func__,urb)
+#define DBG_ISO_PACKET(level, urb)					\
+	if (level & __debug_variable) dump_iso_packet(__func__, urb)
 
 static void __attribute__((unused))
 dump_iso_packet(const char *name, struct urb *urb)
 {
-	int i,j;
-	int len,ofs;
+	int i, j;
+	int len, ofs;
 	u_char *data;
 
 	printk(KERN_DEBUG "%s: packets=%d,errors=%d\n",
-	       name,urb->number_of_packets,urb->error_count);
+	       name, urb->number_of_packets, urb->error_count);
 	for (i = 0; i  < urb->number_of_packets; ++i) {
 		if (urb->pipe & USB_DIR_IN) {
 			len = urb->iso_frame_desc[i].actual_length;
@@ -487,11 +487,11 @@ dump_iso_packet(const char *name, struct urb *urb)
 			len = urb->iso_frame_desc[i].length;
 		}
 		ofs = urb->iso_frame_desc[i].offset;
-		printk(KERN_DEBUG "len=%.2d,ofs=%.3d ",len,ofs);
+		printk(KERN_DEBUG "len=%.2d,ofs=%.3d ", len, ofs);
 		if (len) {
-			data = urb->transfer_buffer+ofs;
-			for (j=0; j < len; j++) {
-				printk ("%.2x", data[j]);
+			data = urb->transfer_buffer + ofs;
+			for (j = 0; j < len; j++) {
+				printk("%.2x", data[j]);
 			}
 		}
 		printk("\n");
@@ -513,17 +513,17 @@ static inline const char *ST5481_CMD_string(int evt)
 	case ST5481_CMD_ARL: return "ARL";
 	case ST5481_CMD_PDN: return "PDN";
 	};
-	
-	sprintf(s,"0x%x",evt);
+
+	sprintf(s, "0x%x", evt);
 	return s;
-}	
+}
 
 #else
 
-#define DBG_ISO_PACKET(level,urb) do {} while (0)
+#define DBG_ISO_PACKET(level, urb) do {} while (0)
 
 #endif
 
 
 
-#endif 
+#endif
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index ed4bc56..4098491 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -4,7 +4,7 @@
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
  *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -27,33 +27,33 @@ static inline void B_L1L2(struct st5481_bcs *bcs, int pr, void *arg)
 /*
  * Encode and transmit next frame.
  */
-static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
+static void usb_b_out(struct st5481_bcs *bcs, int buf_nr)
 {
 	struct st5481_b_out *b_out = &bcs->b_out;
 	struct st5481_adapter *adapter = bcs->adapter;
 	struct urb *urb;
-	unsigned int packet_size,offset;
-	int len,buf_size,bytes_sent;
+	unsigned int packet_size, offset;
+	int len, buf_size, bytes_sent;
 	int i;
 	struct sk_buff *skb;
-	
+
 	if (test_and_set_bit(buf_nr, &b_out->busy)) {
-		DBG(4,"ep %d urb %d busy",(bcs->channel+1)*2,buf_nr);
+		DBG(4, "ep %d urb %d busy", (bcs->channel + 1) * 2, buf_nr);
 		return;
 	}
 	urb = b_out->urb[buf_nr];
 
 	// Adjust isoc buffer size according to flow state
-	if(b_out->flow_event & (OUT_DOWN | OUT_UNDERRUN)) {
-		buf_size = NUM_ISO_PACKETS_B*SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
+	if (b_out->flow_event & (OUT_DOWN | OUT_UNDERRUN)) {
+		buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
 		packet_size = SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST;
-		DBG(4,"B%d,adjust flow,add %d bytes",bcs->channel+1,B_FLOW_ADJUST);
-	} else if(b_out->flow_event & OUT_UP){
-		buf_size = NUM_ISO_PACKETS_B*SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
+		DBG(4, "B%d,adjust flow,add %d bytes", bcs->channel + 1, B_FLOW_ADJUST);
+	} else if (b_out->flow_event & OUT_UP) {
+		buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
 		packet_size = SIZE_ISO_PACKETS_B_OUT - B_FLOW_ADJUST;
-		DBG(4,"B%d,adjust flow,remove %d bytes",bcs->channel+1,B_FLOW_ADJUST);
+		DBG(4, "B%d,adjust flow,remove %d bytes", bcs->channel + 1, B_FLOW_ADJUST);
 	} else {
-		buf_size = NUM_ISO_PACKETS_B*SIZE_ISO_PACKETS_B_OUT;
+		buf_size = NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT;
 		packet_size = 8;
 	}
 	b_out->flow_event = 0;
@@ -62,15 +62,15 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
 	while (len < buf_size) {
 		if ((skb = b_out->tx_skb)) {
 			DBG_SKB(0x100, skb);
-			DBG(4,"B%d,len=%d",bcs->channel+1,skb->len);
-			
-			if (bcs->mode == L1_MODE_TRANS) {	
+			DBG(4, "B%d,len=%d", bcs->channel + 1, skb->len);
+
+			if (bcs->mode == L1_MODE_TRANS) {
 				bytes_sent = buf_size - len;
 				if (skb->len < bytes_sent)
 					bytes_sent = skb->len;
 				{	/* swap tx bytes to get hearable audio data */
 					register unsigned char *src  = skb->data;
-					register unsigned char *dest = urb->transfer_buffer+len;
+					register unsigned char *dest = urb->transfer_buffer + len;
 					register unsigned int count;
 					for (count = 0; count < bytes_sent; count++)
 						*dest++ = bitrev8(*src++);
@@ -79,7 +79,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
 			} else {
 				len += isdnhdlc_encode(&b_out->hdlc_state,
 						       skb->data, skb->len, &bytes_sent,
-						       urb->transfer_buffer+len, buf_size-len);
+						       urb->transfer_buffer + len, buf_size-len);
 			}
 
 			skb_pull(skb, bytes_sent);
@@ -90,21 +90,21 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
 				B_L1L2(bcs, PH_DATA | CONFIRM, (void *)(unsigned long) skb->truesize);
 				dev_kfree_skb_any(skb);
 
-/* 				if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
-/* 					st5481B_sched_event(bcs, B_XMTBUFREADY); */
-/* 				} */
+/*				if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
+/*					st5481B_sched_event(bcs, B_XMTBUFREADY); */
+/*				} */
 			}
 		} else {
 			if (bcs->mode == L1_MODE_TRANS) {
-				memset(urb->transfer_buffer+len, 0xff, buf_size-len);
+				memset(urb->transfer_buffer + len, 0xff, buf_size-len);
 				len = buf_size;
 			} else {
 				// Send flags
 				len += isdnhdlc_encode(&b_out->hdlc_state,
 						       NULL, 0, &bytes_sent,
-						       urb->transfer_buffer+len, buf_size-len);
+						       urb->transfer_buffer + len, buf_size-len);
 			}
-		}	
+		}
 	}
 
 	// Prepare the URB
@@ -118,7 +118,7 @@ static void usb_b_out(struct st5481_bcs *bcs,int buf_nr)
 	urb->number_of_packets = i;
 	urb->dev = adapter->usb_dev;
 
-	DBG_ISO_PACKET(0x200,urb);
+	DBG_ISO_PACKET(0x200, urb);
 
 	SUBMIT_URB(urb, GFP_NOIO);
 }
@@ -131,12 +131,12 @@ static void st5481B_start_xfer(void *context)
 {
 	struct st5481_bcs *bcs = context;
 
-	DBG(4,"B%d",bcs->channel+1);
+	DBG(4, "B%d", bcs->channel + 1);
 
 	// Start transmitting (flags or data) on B channel
 
-	usb_b_out(bcs,0);
-	usb_b_out(bcs,1);
+	usb_b_out(bcs, 0);
+	usb_b_out(bcs, 1);
 }
 
 /*
@@ -158,7 +158,7 @@ static void led_blink(struct st5481_adapter *adapter)
 	} else {
 		leds &= ~GREEN_LED;
 	}
-	
+
 	st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, leds, NULL, NULL);
 }
 
@@ -168,27 +168,27 @@ static void usb_b_out_complete(struct urb *urb)
 	struct st5481_b_out *b_out = &bcs->b_out;
 	struct st5481_adapter *adapter = bcs->adapter;
 	int buf_nr;
-	
+
 	buf_nr = get_buf_nr(b_out->urb, urb);
 	test_and_clear_bit(buf_nr, &b_out->busy);
 
 	if (unlikely(urb->status < 0)) {
 		switch (urb->status) {
-			case -ENOENT:
-			case -ESHUTDOWN:
-			case -ECONNRESET:
-				DBG(4,"urb killed status %d", urb->status);
-				return; // Give up
-			default: 
-				WARNING("urb status %d",urb->status);
-				if (b_out->busy == 0) {
-					st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2 | USB_DIR_OUT, NULL, NULL);
-				}
-				break;
+		case -ENOENT:
+		case -ESHUTDOWN:
+		case -ECONNRESET:
+			DBG(4, "urb killed status %d", urb->status);
+			return; // Give up
+		default:
+			WARNING("urb status %d", urb->status);
+			if (b_out->busy == 0) {
+				st5481_usb_pipe_reset(adapter, (bcs->channel + 1) * 2 | USB_DIR_OUT, NULL, NULL);
+			}
+			break;
 		}
 	}
 
-	usb_b_out(bcs,buf_nr);
+	usb_b_out(bcs, buf_nr);
 
 	if (adapter->number_of_leds == 2)
 		led_blink(adapter);
@@ -202,7 +202,7 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
 	struct st5481_b_out *b_out = &bcs->b_out;
 	struct st5481_adapter *adapter = bcs->adapter;
 
-	DBG(4,"B%d,mode=%d", bcs->channel + 1, mode);
+	DBG(4, "B%d,mode=%d", bcs->channel + 1, mode);
 
 	if (bcs->mode == mode)
 		return;
@@ -223,14 +223,14 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
 				features |= HDLC_56KBIT;
 			isdnhdlc_out_init(&b_out->hdlc_state, features);
 		}
-		st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL);
-	
+		st5481_usb_pipe_reset(adapter, (bcs->channel + 1) * 2, NULL, NULL);
+
 		// Enable B channel interrupts
-		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel*2), 
-				    OUT_UP+OUT_DOWN+OUT_UNDERRUN, NULL, NULL);
+		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1 + (bcs->channel * 2),
+					   OUT_UP + OUT_DOWN + OUT_UNDERRUN, NULL, NULL);
 
 		// Enable B channel FIFOs
-		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel*2), 32, st5481B_start_xfer, bcs);
+		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel * 2), 32, st5481B_start_xfer, bcs);
 		if (adapter->number_of_leds == 4) {
 			if (bcs->channel == 0) {
 				adapter->leds |= B1_LED;
@@ -240,10 +240,10 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
 		}
 	} else {
 		// Disble B channel interrupts
-		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel*2), 0, NULL, NULL);
+		st5481_usb_device_ctrl_msg(adapter, FFMSK_B1+(bcs->channel * 2), 0, NULL, NULL);
 
 		// Disable B channel FIFOs
-		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel*2), 0, NULL, NULL);
+		st5481_usb_device_ctrl_msg(adapter, OUT_B1_COUNTER+(bcs->channel * 2), 0, NULL, NULL);
 
 		if (adapter->number_of_leds == 4) {
 			if (bcs->channel == 0) {
@@ -258,7 +258,7 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
 			dev_kfree_skb_any(b_out->tx_skb);
 			b_out->tx_skb = NULL;
 		}
-		
+
 	}
 }
 
@@ -268,9 +268,9 @@ static int st5481_setup_b_out(struct st5481_bcs *bcs)
 	struct usb_interface *intf;
 	struct usb_host_interface *altsetting = NULL;
 	struct usb_host_endpoint *endpoint;
-  	struct st5481_b_out *b_out = &bcs->b_out;
+	struct st5481_b_out *b_out = &bcs->b_out;
 
-	DBG(4,"");
+	DBG(4, "");
 
 	intf = usb_ifnum_to_if(dev, 0);
 	if (intf)
@@ -281,11 +281,11 @@ static int st5481_setup_b_out(struct st5481_bcs *bcs)
 	// Allocate URBs and buffers for the B channel out
 	endpoint = &altsetting->endpoint[EP_B1_OUT - 1 + bcs->channel * 2];
 
-	DBG(4,"endpoint address=%02x,packet size=%d",
+	DBG(4, "endpoint address=%02x,packet size=%d",
 	    endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
 
 	// Allocate memory for 8000bytes/sec + extra bytes if underrun
-	return st5481_setup_isocpipes(b_out->urb, dev, 
+	return st5481_setup_isocpipes(b_out->urb, dev,
 				      usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress),
 				      NUM_ISO_PACKETS_B, SIZE_ISO_PACKETS_B_OUT,
 				      NUM_ISO_PACKETS_B * SIZE_ISO_PACKETS_B_OUT + B_FLOW_ADJUST,
@@ -296,7 +296,7 @@ static void st5481_release_b_out(struct st5481_bcs *bcs)
 {
 	struct st5481_b_out *b_out = &bcs->b_out;
 
-	DBG(4,"");
+	DBG(4, "");
 
 	st5481_release_isocpipes(b_out->urb);
 }
@@ -305,7 +305,7 @@ int st5481_setup_b(struct st5481_bcs *bcs)
 {
 	int retval;
 
-	DBG(4,"");
+	DBG(4, "");
 
 	retval = st5481_setup_b_out(bcs);
 	if (retval)
@@ -324,9 +324,9 @@ int st5481_setup_b(struct st5481_bcs *bcs)
 
 	return 0;
 
- err_b_out:
+err_b_out:
 	st5481_release_b_out(bcs);
- err:
+err:
 	return retval;
 }
 
@@ -335,7 +335,7 @@ int st5481_setup_b(struct st5481_bcs *bcs)
  */
 void st5481_release_b(struct st5481_bcs *bcs)
 {
-	DBG(4,"");
+	DBG(4, "");
 
 	st5481_release_in(&bcs->b_in);
 	st5481_release_b_out(bcs);
@@ -365,12 +365,12 @@ void st5481_b_l2l1(struct hisax_if *ifc, int pr, void *arg)
 		break;
 	case PH_ACTIVATE | REQUEST:
 		mode = (long) arg;
-		DBG(4,"B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode);
+		DBG(4, "B%d,PH_ACTIVATE_REQUEST %ld", bcs->channel + 1, mode);
 		st5481B_mode(bcs, mode);
 		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);
 		break;
 	case PH_DEACTIVATE | REQUEST:
-		DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
+		DBG(4, "B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);
 		st5481B_mode(bcs, L1_MODE_NULL);
 		B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);
 		break;
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index db247b7..e88c5c7 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -4,7 +4,7 @@
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
  *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -32,22 +32,22 @@ static char *strL1State[] =
 
 static char *strL1Event[] =
 {
-	"EV_IND_DP",  
-	"EV_IND_1",   
-	"EV_IND_2",   
-	"EV_IND_3",   
-	"EV_IND_RSY", 
-	"EV_IND_5",   
-	"EV_IND_6",   
-	"EV_IND_7",   
-	"EV_IND_AP",  
-	"EV_IND_9",   
-	"EV_IND_10",  
-	"EV_IND_11",  
+	"EV_IND_DP",
+	"EV_IND_1",
+	"EV_IND_2",
+	"EV_IND_3",
+	"EV_IND_RSY",
+	"EV_IND_5",
+	"EV_IND_6",
+	"EV_IND_7",
+	"EV_IND_AP",
+	"EV_IND_9",
+	"EV_IND_10",
+	"EV_IND_11",
 	"EV_IND_AI8",
 	"EV_IND_AI10",
 	"EV_IND_AIL",
-	"EV_IND_DI",  
+	"EV_IND_DI",
 	"EV_PH_ACTIVATE_REQ",
 	"EV_PH_DEACTIVATE_REQ",
 	"EV_TIMER3",
@@ -67,7 +67,7 @@ l1_go_f3(struct FsmInst *fi, int event, void *arg)
 
 	if (fi->state == ST_L1_F7)
 		ph_disconnect(adapter);
-	
+
 	FsmChangeState(fi, ST_L1_F3);
 	D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL);
 }
@@ -168,11 +168,11 @@ static struct FsmNode L1FnList[] __initdata =
 };
 
 static __printf(2, 3)
-void l1m_debug(struct FsmInst *fi, char *fmt, ...)
+	void l1m_debug(struct FsmInst *fi, char *fmt, ...)
 {
 	va_list args;
 	char buf[256];
-	
+
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	DBG(8, "%s", buf);
@@ -191,54 +191,54 @@ void l1m_debug(struct FsmInst *fi, char *fmt, ...)
 
   L1 FRAME    D_OUT_STATE           USB                  D CHANNEL
   --------    -----------           ---                  ---------
- 
-              FIXME
-
- -> [xx..xx]  SHORT_INIT            -> [7Exx..xxC1C27EFF]
-              SHORT_WAIT_DEN        <> OUT_D_COUNTER=16 
-                                                 
-              END_OF_SHORT          <- DEN_EVENT         -> 7Exx
-                                                          xxxx 
-                                                          xxxx
-							  xxxx 
-							  xxxx
-							  xxxx
-							  C1C1 
-							  7EFF 
-              WAIT_FOR_RESET_IDLE   <- D_UNDERRUN        <- (8ms)                        
-              IDLE                  <> Reset pipe
-
-              
+
+  FIXME
+
+  -> [xx..xx]  SHORT_INIT            -> [7Exx..xxC1C27EFF]
+  SHORT_WAIT_DEN        <> OUT_D_COUNTER=16
+
+  END_OF_SHORT          <- DEN_EVENT         -> 7Exx
+  xxxx
+  xxxx
+  xxxx
+  xxxx
+  xxxx
+  C1C1
+  7EFF
+  WAIT_FOR_RESET_IDLE   <- D_UNDERRUN        <- (8ms)
+  IDLE                  <> Reset pipe
+
+
 
   Transmit long frame (>= 16 bytes of encoded data):
 
   L1 FRAME    D_OUT_STATE           USB                  D CHANNEL
   --------    -----------           ---                  ---------
 
- -> [xx...xx] IDLE
-              WAIT_FOR_STOP         <> OUT_D_COUNTER=0
-              WAIT_FOR_RESET        <> Reset pipe
-	      STOP
-	      INIT_LONG_FRAME       -> [7Exx..xx]
-              WAIT_DEN              <> OUT_D_COUNTER=16 
-              OUT_NORMAL            <- DEN_EVENT       -> 7Exx
-              END_OF_FRAME_BUSY     -> [xxxx]             xxxx 
-              END_OF_FRAME_NOT_BUSY -> [xxxx]             xxxx
-				    -> [xxxx]		  xxxx 
-				    -> [C1C2]		  xxxx
-				    -> [7EFF]		  xxxx
-							  xxxx 
-							  xxxx 
-                                                          ....
-							  xxxx
-							  C1C2
-							  7EFF
-	                 	    <- D_UNDERRUN      <- (> 8ms)                        
-              WAIT_FOR_STOP         <> OUT_D_COUNTER=0
-              WAIT_FOR_RESET        <> Reset pipe
-	      STOP
-
-*/          
+  -> [xx...xx] IDLE
+  WAIT_FOR_STOP         <> OUT_D_COUNTER=0
+  WAIT_FOR_RESET        <> Reset pipe
+  STOP
+  INIT_LONG_FRAME       -> [7Exx..xx]
+  WAIT_DEN              <> OUT_D_COUNTER=16
+  OUT_NORMAL            <- DEN_EVENT       -> 7Exx
+  END_OF_FRAME_BUSY     -> [xxxx]             xxxx
+  END_OF_FRAME_NOT_BUSY -> [xxxx]             xxxx
+  -> [xxxx]		  xxxx
+  -> [C1C2]		  xxxx
+  -> [7EFF]		  xxxx
+  xxxx
+  xxxx
+  ....
+  xxxx
+  C1C2
+  7EFF
+  <- D_UNDERRUN      <- (> 8ms)
+  WAIT_FOR_STOP         <> OUT_D_COUNTER=0
+  WAIT_FOR_RESET        <> Reset pipe
+  STOP
+
+*/
 
 static struct Fsm dout_fsm;
 
@@ -254,7 +254,7 @@ static char *strDoutState[] =
 	"ST_DOUT_NORMAL",
 
 	"ST_DOUT_WAIT_FOR_UNDERRUN",
-        "ST_DOUT_WAIT_FOR_NOT_BUSY",
+	"ST_DOUT_WAIT_FOR_NOT_BUSY",
 	"ST_DOUT_WAIT_FOR_STOP",
 	"ST_DOUT_WAIT_FOR_RESET",
 };
@@ -271,11 +271,11 @@ static char *strDoutEvent[] =
 };
 
 static __printf(2, 3)
-void dout_debug(struct FsmInst *fi, char *fmt, ...)
+	void dout_debug(struct FsmInst *fi, char *fmt, ...)
 {
 	va_list args;
 	char buf[256];
-	
+
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	DBG(0x2, "%s", buf);
@@ -313,19 +313,19 @@ static void usb_d_out(struct st5481_adapter *adapter, int buf_nr)
 	skb = d_out->tx_skb;
 
 	buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT;
-	
+
 	if (skb) {
 		len = isdnhdlc_encode(&d_out->hdlc_state,
 				      skb->data, skb->len, &bytes_sent,
 				      urb->transfer_buffer, buf_size);
-		skb_pull(skb,bytes_sent);
+		skb_pull(skb, bytes_sent);
 	} else {
 		// Send flags or idle
 		len = isdnhdlc_encode(&d_out->hdlc_state,
 				      NULL, 0, &bytes_sent,
 				      urb->transfer_buffer, buf_size);
 	}
-	
+
 	if (len < buf_size) {
 		FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);
 	}
@@ -354,15 +354,15 @@ static void usb_d_out(struct st5481_adapter *adapter, int buf_nr)
 	urb->dev = adapter->usb_dev;
 	// Need to transmit the next buffer 2ms after the DEN_EVENT
 	urb->transfer_flags = 0;
-	urb->start_frame = usb_get_current_frame_number(adapter->usb_dev)+2;
+	urb->start_frame = usb_get_current_frame_number(adapter->usb_dev) + 2;
 
-	DBG_ISO_PACKET(0x20,urb);
+	DBG_ISO_PACKET(0x20, urb);
 
 	if (usb_submit_urb(urb, GFP_KERNEL) < 0) {
 		// There is another URB queued up
 		urb->transfer_flags = URB_ISO_ASAP;
 		SUBMIT_URB(urb, GFP_KERNEL);
-	}	
+	}
 }
 
 static void fifo_reseted(void *context)
@@ -377,7 +377,7 @@ static void usb_d_out_complete(struct urb *urb)
 	struct st5481_adapter *adapter = urb->context;
 	struct st5481_d_out *d_out = &adapter->d_out;
 	long buf_nr;
-	
+
 	DBG(2, "");
 
 	buf_nr = get_buf_nr(d_out->urb, urb);
@@ -385,17 +385,17 @@ static void usb_d_out_complete(struct urb *urb)
 
 	if (unlikely(urb->status < 0)) {
 		switch (urb->status) {
-			case -ENOENT:
-			case -ESHUTDOWN:
-			case -ECONNRESET:
-				DBG(1,"urb killed status %d", urb->status);
-				break;
-			default: 
-				WARNING("urb status %d",urb->status);
-				if (d_out->busy == 0) {
-					st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
-				}
-				break;
+		case -ENOENT:
+		case -ESHUTDOWN:
+		case -ECONNRESET:
+			DBG(1, "urb killed status %d", urb->status);
+			break;
+		default:
+			WARNING("urb status %d", urb->status);
+			if (d_out->busy == 0) {
+				st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
+			}
+			break;
 		}
 		return; // Give up
 	}
@@ -417,7 +417,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
 
 	skb = d_out->tx_skb;
 
-	DBG(2,"len=%d",skb->len);
+	DBG(2, "len=%d", skb->len);
 
 	isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE);
 
@@ -433,7 +433,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
 			      urb->transfer_buffer, 16);
 	skb_pull(skb, bytes_sent);
 
-	if(len < 16)
+	if (len < 16)
 		FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT);
 	else
 		FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT);
@@ -455,7 +455,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
 	urb->dev = adapter->usb_dev;
 	urb->transfer_flags = URB_ISO_ASAP;
 
-	DBG_ISO_PACKET(0x20,urb);
+	DBG_ISO_PACKET(0x20, urb);
 	SUBMIT_URB(urb, GFP_KERNEL);
 }
 
@@ -480,7 +480,7 @@ static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg)
 {
 	struct st5481_adapter *adapter = fsm->userdata;
 	struct st5481_d_out *d_out = &adapter->d_out;
-    
+
 	st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL);
 	FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN);
 }
@@ -619,8 +619,8 @@ static void ph_connect(struct st5481_adapter *adapter)
 	struct st5481_d_out *d_out = &adapter->d_out;
 	struct st5481_in *d_in = &adapter->d_in;
 
-	DBG(8,"");
-		
+	DBG(8, "");
+
 	FsmChangeState(&d_out->fsm, ST_DOUT_NONE);
 
 	//	st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL);
@@ -644,7 +644,7 @@ static void ph_connect(struct st5481_adapter *adapter)
  */
 static void ph_disconnect(struct st5481_adapter *adapter)
 {
-	DBG(8,"");
+	DBG(8, "");
 
 	st5481_in_mode(&adapter->d_in, L1_MODE_NULL);
 
@@ -661,7 +661,7 @@ static int st5481_setup_d_out(struct st5481_adapter *adapter)
 	struct usb_host_endpoint *endpoint;
 	struct st5481_d_out *d_out = &adapter->d_out;
 
-	DBG(2,"");
+	DBG(2, "");
 
 	intf = usb_ifnum_to_if(dev, 0);
 	if (intf)
@@ -672,10 +672,10 @@ static int st5481_setup_d_out(struct st5481_adapter *adapter)
 	// Allocate URBs and buffers for the D channel out
 	endpoint = &altsetting->endpoint[EP_D_OUT-1];
 
-	DBG(2,"endpoint address=%02x,packet size=%d",
+	DBG(2, "endpoint address=%02x,packet size=%d",
 	    endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
 
-	return st5481_setup_isocpipes(d_out->urb, dev, 
+	return st5481_setup_isocpipes(d_out->urb, dev,
 				      usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress),
 				      NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT,
 				      NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT,
@@ -686,7 +686,7 @@ static void st5481_release_d_out(struct st5481_adapter *adapter)
 {
 	struct st5481_d_out *d_out = &adapter->d_out;
 
-	DBG(2,"");
+	DBG(2, "");
 
 	st5481_release_isocpipes(d_out->urb);
 }
@@ -695,7 +695,7 @@ int st5481_setup_d(struct st5481_adapter *adapter)
 {
 	int retval;
 
-	DBG(2,"");
+	DBG(2, "");
 
 	retval = st5481_setup_d_out(adapter);
 	if (retval)
@@ -726,15 +726,15 @@ int st5481_setup_d(struct st5481_adapter *adapter)
 
 	return 0;
 
- err_d_out:
+err_d_out:
 	st5481_release_d_out(adapter);
- err:
+err:
 	return retval;
 }
 
 void st5481_release_d(struct st5481_adapter *adapter)
 {
-	DBG(2,"");
+	DBG(2, "");
 
 	st5481_release_in(&adapter->d_in);
 	st5481_release_d_out(adapter);
@@ -766,9 +766,9 @@ int __init st5481_d_init(void)
 
 	return 0;
 
- err_l1:
+err_l1:
 	FsmFree(&l1fsm);
- err:
+err:
 	return retval;
 }
 
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 9f7fd18..100296e 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -4,13 +4,13 @@
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
  *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
  */
 
-/* 
+/*
  * TODO:
  *
  * b layer1 delay?
@@ -63,9 +63,9 @@ static int probe_st5481(struct usb_interface *intf,
 	int retval, i;
 
 	printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
-	     le16_to_cpu(dev->descriptor.idVendor),
-	     le16_to_cpu(dev->descriptor.idProduct),
-	     number_of_leds);
+	       le16_to_cpu(dev->descriptor.idVendor),
+	       le16_to_cpu(dev->descriptor.idProduct),
+	       number_of_leds);
 
 	adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
 	if (!adapter)
@@ -105,7 +105,7 @@ static int probe_st5481(struct usb_interface *intf,
 		b_if[i] = &adapter->bcs[i].b_if;
 
 	if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
-			protocol) != 0)
+			   protocol) != 0)
 		goto err_b1;
 
 	st5481_start(adapter);
@@ -113,15 +113,15 @@ static int probe_st5481(struct usb_interface *intf,
 	usb_set_intfdata(intf, adapter);
 	return 0;
 
- err_b1:
+err_b1:
 	st5481_release_b(&adapter->bcs[1]);
- err_b:
+err_b:
 	st5481_release_b(&adapter->bcs[0]);
- err_d:
+err_d:
 	st5481_release_d(adapter);
- err_usb:
+err_usb:
 	st5481_release_usb(adapter);
- err:
+err:
 	kfree(adapter);
 	return -EIO;
 }
@@ -134,12 +134,12 @@ static void disconnect_st5481(struct usb_interface *intf)
 {
 	struct st5481_adapter *adapter = usb_get_intfdata(intf);
 
-	DBG(1,"");
+	DBG(1, "");
 
 	usb_set_intfdata(intf, NULL);
 	if (!adapter)
 		return;
-	
+
 	st5481_stop(adapter);
 	st5481_release_b(&adapter->bcs[1]);
 	st5481_release_b(&adapter->bcs[0]);
@@ -157,25 +157,25 @@ static void disconnect_st5481(struct usb_interface *intf)
  * The last 4 bits in the Product Id is set with 4 pins on the chip.
  */
 static struct usb_device_id st5481_ids[] = {
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x0) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x1) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x2) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x3) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x4) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x5) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x6) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x7) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x8) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x9) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xA) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xB) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xC) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xD) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xE) },
-	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xF) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x0) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x1) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x2) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x3) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x4) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x5) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x6) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x7) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x8) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0x9) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xA) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xB) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xC) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xD) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xE) },
+	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID + 0xF) },
 	{ }
 };
-MODULE_DEVICE_TABLE (usb, st5481_ids);
+MODULE_DEVICE_TABLE(usb, st5481_ids);
 
 static struct usb_driver st5481_usb_driver = {
 	.name =		"st5481_usb",
@@ -204,9 +204,9 @@ static int __init st5481_usb_init(void)
 
 	return 0;
 
- out_d_exit:
+out_d_exit:
 	st5481_d_exit();
- out:
+out:
 	return retval;
 }
 
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 159e8fa..017c67e 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -4,7 +4,7 @@
  * Author       Frode Isaksen
  * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
  *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -36,13 +36,13 @@ static void usb_next_ctrl_msg(struct urb *urb,
 	}
 
 	if ((r_index = fifo_remove(&ctrl->msg_fifo.f)) < 0) {
-		test_and_clear_bit(0,&ctrl->busy);
+		test_and_clear_bit(0, &ctrl->busy);
 		return;
-	} 
-	urb->setup_packet = 
+	}
+	urb->setup_packet =
 		(unsigned char *)&ctrl->msg_fifo.data[r_index];
-	
-	DBG(1,"request=0x%02x,value=0x%04x,index=%x",
+
+	DBG(1, "request=0x%02x,value=0x%04x,index=%x",
 	    ((struct ctrl_msg *)urb->setup_packet)->dr.bRequest,
 	    ((struct ctrl_msg *)urb->setup_packet)->dr.wValue,
 	    ((struct ctrl_msg *)urb->setup_packet)->dr.wIndex);
@@ -64,13 +64,13 @@ static void usb_ctrl_msg(struct st5481_adapter *adapter,
 	struct st5481_ctrl *ctrl = &adapter->ctrl;
 	int w_index;
 	struct ctrl_msg *ctrl_msg;
-	
+
 	if ((w_index = fifo_add(&ctrl->msg_fifo.f)) < 0) {
 		WARNING("control msg FIFO full");
 		return;
 	}
-	ctrl_msg = &ctrl->msg_fifo.data[w_index]; 
-   
+	ctrl_msg = &ctrl->msg_fifo.data[w_index];
+
 	ctrl_msg->dr.bRequestType = requesttype;
 	ctrl_msg->dr.bRequest = request;
 	ctrl_msg->dr.wValue = cpu_to_le16p(&value);
@@ -86,11 +86,11 @@ static void usb_ctrl_msg(struct st5481_adapter *adapter,
  * Asynchronous endpoint 0 device request.
  */
 void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
-			 u8 request, u16 value,
-			 ctrl_complete_t complete, void *context)
+				u8 request, u16 value,
+				ctrl_complete_t complete, void *context)
 {
-	usb_ctrl_msg(adapter, request, 
-		     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 
+	usb_ctrl_msg(adapter, request,
+		     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 		     value, 0, complete, context);
 }
 
@@ -98,10 +98,10 @@ void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
  * Asynchronous pipe reset (async version of usb_clear_halt).
  */
 void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
-		    u_char pipe,
-		    ctrl_complete_t complete, void *context)
+			   u_char pipe,
+			   ctrl_complete_t complete, void *context)
 {
-	DBG(1,"pipe=%02x",pipe);
+	DBG(1, "pipe=%02x", pipe);
 
 	usb_ctrl_msg(adapter,
 		     USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RECIP_ENDPOINT,
@@ -115,7 +115,7 @@ void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
 
 void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command)
 {
-	DBG(8,"command=%s", ST5481_CMD_string(command));
+	DBG(8, "command=%s", ST5481_CMD_string(command));
 
 	st5481_usb_device_ctrl_msg(adapter, TXCI, command, NULL, NULL);
 }
@@ -130,33 +130,33 @@ static void usb_ctrl_complete(struct urb *urb)
 	struct st5481_adapter *adapter = urb->context;
 	struct st5481_ctrl *ctrl = &adapter->ctrl;
 	struct ctrl_msg *ctrl_msg;
-	
+
 	if (unlikely(urb->status < 0)) {
 		switch (urb->status) {
-			case -ENOENT:
-			case -ESHUTDOWN:
-			case -ECONNRESET:
-				DBG(1,"urb killed status %d", urb->status);
-				return; // Give up
-			default: 
-				WARNING("urb status %d",urb->status);
-				break;
+		case -ENOENT:
+		case -ESHUTDOWN:
+		case -ECONNRESET:
+			DBG(1, "urb killed status %d", urb->status);
+			return; // Give up
+		default:
+			WARNING("urb status %d", urb->status);
+			break;
 		}
 	}
 
 	ctrl_msg = (struct ctrl_msg *)urb->setup_packet;
-	
+
 	if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) {
-	        /* Special case handling for pipe reset */
+		/* Special case handling for pipe reset */
 		le16_to_cpus(&ctrl_msg->dr.wIndex);
 		usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex);
 	}
-	
+
 	if (ctrl_msg->complete)
 		ctrl_msg->complete(ctrl_msg->context);
 
 	clear_bit(0, &ctrl->busy);
-	
+
 	// Try to send next control message
 	usb_next_ctrl_msg(urb, adapter);
 	return;
@@ -181,23 +181,23 @@ static void usb_int_complete(struct urb *urb)
 	int status;
 
 	switch (urb->status) {
-		case 0:
-			/* success */
-			break;
-		case -ECONNRESET:
-		case -ENOENT:
-		case -ESHUTDOWN:
-			/* this urb is terminated, clean up */
-			DBG(2, "urb shutting down with status: %d", urb->status);
-			return;
-		default:
-			WARNING("nonzero urb status received: %d", urb->status);
-			goto exit;
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		DBG(2, "urb shutting down with status: %d", urb->status);
+		return;
+	default:
+		WARNING("nonzero urb status received: %d", urb->status);
+		goto exit;
 	}
 
-	
+
 	DBG_PACKET(2, data, INT_PKT_SIZE);
-		
+
 	if (urb->actual_length == 0) {
 		goto exit;
 	}
@@ -214,7 +214,7 @@ static void usb_int_complete(struct urb *urb)
 		FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL);
 
 	if (irqbyte & OUT_DOWN)
-;//		printk("OUT_DOWN\n");
+		;//		printk("OUT_DOWN\n");
 
 	irqbyte = data[MPINT];
 	if (irqbyte & RXCI_INT)
@@ -226,7 +226,7 @@ static void usb_int_complete(struct urb *urb)
 	urb->actual_length = 0;
 
 exit:
-	status = usb_submit_urb (urb, GFP_ATOMIC);
+	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status)
 		WARNING("usb_submit_urb failed with result %d", status);
 }
@@ -246,11 +246,11 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
 	int status;
 	struct urb *urb;
 	u8 *buf;
-	
-	DBG(2,"");
-	
-	if ((status = usb_reset_configuration (dev)) < 0) {
-		WARNING("reset_configuration failed,status=%d",status);
+
+	DBG(2, "");
+
+	if ((status = usb_reset_configuration(dev)) < 0) {
+		WARNING("reset_configuration failed,status=%d", status);
 		return status;
 	}
 
@@ -261,7 +261,7 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
 		return -ENXIO;
 
 	// Check if the config is sane
-	if ( altsetting->desc.bNumEndpoints != 7 ) {
+	if (altsetting->desc.bNumEndpoints != 7) {
 		WARNING("expecting 7 got %d endpoints!", altsetting->desc.bNumEndpoints);
 		return -EINVAL;
 	}
@@ -271,8 +271,8 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
 	altsetting->endpoint[4].desc.wMaxPacketSize = __constant_cpu_to_le16(32);
 
 	// Use alternative setting 3 on interface 0 to have 2B+D
-	if ((status = usb_set_interface (dev, 0, 3)) < 0) {
-		WARNING("usb_set_interface failed,status=%d",status);
+	if ((status = usb_set_interface(dev, 0, 3)) < 0) {
+		WARNING("usb_set_interface failed,status=%d", status);
 		return status;
 	}
 
@@ -282,36 +282,36 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
 		return -ENOMEM;
 	}
 	ctrl->urb = urb;
-	
+
 	// Fill the control URB
-	usb_fill_control_urb (urb, dev, 
-			  usb_sndctrlpipe(dev, 0),
-			  NULL, NULL, 0, usb_ctrl_complete, adapter);
+	usb_fill_control_urb(urb, dev,
+			     usb_sndctrlpipe(dev, 0),
+			     NULL, NULL, 0, usb_ctrl_complete, adapter);
+
 
-		
 	fifo_init(&ctrl->msg_fifo.f, ARRAY_SIZE(ctrl->msg_fifo.data));
 
 	// Allocate URBs and buffers for interrupt endpoint
 	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!urb) { 
+	if (!urb) {
 		return -ENOMEM;
 	}
 	intr->urb = urb;
-	
+
 	buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL);
 	if (!buf) {
 		return -ENOMEM;
 	}
 
 	endpoint = &altsetting->endpoint[EP_INT-1];
-				
+
 	// Fill the interrupt URB
 	usb_fill_int_urb(urb, dev,
-		     usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress),
-		     buf, INT_PKT_SIZE,
-		     usb_int_complete, adapter,
-		     endpoint->desc.bInterval);
-		
+			 usb_rcvintpipe(dev, endpoint->desc.bEndpointAddress),
+			 buf, INT_PKT_SIZE,
+			 usb_int_complete, adapter,
+			 endpoint->desc.bInterval);
+
 	return 0;
 }
 
@@ -324,7 +324,7 @@ void st5481_release_usb(struct st5481_adapter *adapter)
 	struct st5481_intr *intr = &adapter->intr;
 	struct st5481_ctrl *ctrl = &adapter->ctrl;
 
-	DBG(1,"");
+	DBG(1, "");
 
 	// Stop and free Control and Interrupt URBs
 	usb_kill_urb(ctrl->urb);
@@ -343,33 +343,33 @@ void st5481_release_usb(struct st5481_adapter *adapter)
  */
 void st5481_start(struct st5481_adapter *adapter)
 {
-	static const u8 init_cmd_table[]={
-		SET_DEFAULT,0,
-		STT,0,
-		SDA_MIN,0x0d,
-		SDA_MAX,0x29,
-		SDELAY_VALUE,0x14,
-		GPIO_DIR,0x01,		
-		GPIO_OUT,RED_LED,
+	static const u8 init_cmd_table[] = {
+		SET_DEFAULT, 0,
+		STT, 0,
+		SDA_MIN, 0x0d,
+		SDA_MAX, 0x29,
+		SDELAY_VALUE, 0x14,
+		GPIO_DIR, 0x01,
+		GPIO_OUT, RED_LED,
 //		FFCTRL_OUT_D,4,
 //		FFCTRH_OUT_D,12,
-		FFCTRL_OUT_B1,6,
-		FFCTRH_OUT_B1,20,
-		FFCTRL_OUT_B2,6,
-		FFCTRH_OUT_B2,20,
-		MPMSK,RXCI_INT+DEN_INT+DCOLL_INT,
+		FFCTRL_OUT_B1, 6,
+		FFCTRH_OUT_B1, 20,
+		FFCTRL_OUT_B2, 6,
+		FFCTRH_OUT_B2, 20,
+		MPMSK, RXCI_INT + DEN_INT + DCOLL_INT,
 		0
-	};	
+	};
 	struct st5481_intr *intr = &adapter->intr;
 	int i = 0;
-	u8 request,value;
+	u8 request, value;
 
-	DBG(8,"");
+	DBG(8, "");
 
-	adapter->leds = RED_LED; 
+	adapter->leds = RED_LED;
 
 	// Start receiving on the interrupt endpoint
-	SUBMIT_URB(intr->urb, GFP_KERNEL); 
+	SUBMIT_URB(intr->urb, GFP_KERNEL);
 
 	while ((request = init_cmd_table[i++])) {
 		value = init_cmd_table[i++];
@@ -383,7 +383,7 @@ void st5481_start(struct st5481_adapter *adapter)
  */
 void st5481_stop(struct st5481_adapter *adapter)
 {
-	DBG(8,"");
+	DBG(8, "");
 
 	st5481_usb_device_ctrl_msg(adapter, SET_DEFAULT, 0, NULL, NULL);
 }
@@ -394,22 +394,22 @@ void st5481_stop(struct st5481_adapter *adapter)
 
 static void
 fill_isoc_urb(struct urb *urb, struct usb_device *dev,
-	      unsigned int pipe, void *buf, int num_packets, 
+	      unsigned int pipe, void *buf, int num_packets,
 	      int packet_size, usb_complete_t complete,
-	      void *context) 
+	      void *context)
 {
 	int k;
 
-	urb->dev=dev;
-	urb->pipe=pipe;
+	urb->dev = dev;
+	urb->pipe = pipe;
 	urb->interval = 1;
-	urb->transfer_buffer=buf;
+	urb->transfer_buffer = buf;
 	urb->number_of_packets = num_packets;
-	urb->transfer_buffer_length=num_packets*packet_size;
+	urb->transfer_buffer_length = num_packets * packet_size;
 	urb->actual_length = 0;
-	urb->complete=complete;
-	urb->context=context;
-	urb->transfer_flags=URB_ISO_ASAP;
+	urb->complete = complete;
+	urb->context = context;
+	urb->transfer_flags = URB_ISO_ASAP;
 	for (k = 0; k < num_packets; k++) {
 		urb->iso_frame_desc[k].offset = packet_size * k;
 		urb->iso_frame_desc[k].length = packet_size;
@@ -418,10 +418,10 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev,
 }
 
 int
-st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, 
-			   unsigned int pipe, int num_packets,
-			   int packet_size, int buf_size,
-			   usb_complete_t complete, void *context)
+st5481_setup_isocpipes(struct urb *urb[2], struct usb_device *dev,
+		       unsigned int pipe, int num_packets,
+		       int packet_size, int buf_size,
+		       usb_complete_t complete, void *context)
 {
 	int j, retval;
 	unsigned char *buf;
@@ -436,15 +436,15 @@ st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
 		buf = kmalloc(buf_size, GFP_KERNEL);
 		if (!buf)
 			goto err;
-			
+
 		// Fill the isochronous URB
-		fill_isoc_urb(urb[j], dev, pipe, buf, 
+		fill_isoc_urb(urb[j], dev, pipe, buf,
 			      num_packets, packet_size, complete,
 			      context);
 	}
 	return 0;
 
- err:
+err:
 	for (j = 0; j < 2; j++) {
 		if (urb[j]) {
 			kfree(urb[j]->transfer_buffer);
@@ -456,7 +456,7 @@ st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
 	return retval;
 }
 
-void st5481_release_isocpipes(struct urb* urb[2])
+void st5481_release_isocpipes(struct urb *urb[2])
 {
 	int j;
 
@@ -471,8 +471,8 @@ void st5481_release_isocpipes(struct urb* urb[2])
 /*
  * Decode frames received on the B/D channel.
  * Note that this function will be called continuously
- * with 64Kbit/s / 16Kbit/s of data and hence it will be 
- * called 50 times per second with 20 ISOC descriptors. 
+ * with 64Kbit/s / 16Kbit/s of data and hence it will be
+ * called 50 times per second with 20 ISOC descriptors.
  * Called at interrupt.
  */
 static void usb_in_complete(struct urb *urb)
@@ -484,18 +484,18 @@ static void usb_in_complete(struct urb *urb)
 
 	if (unlikely(urb->status < 0)) {
 		switch (urb->status) {
-			case -ENOENT:
-			case -ESHUTDOWN:
-			case -ECONNRESET:
-				DBG(1,"urb killed status %d", urb->status);
-				return; // Give up
-			default: 
-				WARNING("urb status %d",urb->status);
-				break;
+		case -ENOENT:
+		case -ESHUTDOWN:
+		case -ECONNRESET:
+			DBG(1, "urb killed status %d", urb->status);
+			return; // Give up
+		default:
+			WARNING("urb status %d", urb->status);
+			break;
 		}
 	}
 
-	DBG_ISO_PACKET(0x80,urb);
+	DBG_ISO_PACKET(0x80, urb);
 
 	len = st5481_isoc_flatten(urb);
 	ptr = urb->transfer_buffer;
@@ -506,14 +506,14 @@ static void usb_in_complete(struct urb *urb)
 			len = 0;
 		} else {
 			status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count,
-				in->rcvbuf, in->bufsize);
+						 in->rcvbuf, in->bufsize);
 			ptr += count;
 			len -= count;
 		}
-		
+
 		if (status > 0) {
 			// Good frame received
-			DBG(4,"count=%d",status);
+			DBG(4, "count=%d", status);
 			DBG_PACKET(0x400, in->rcvbuf, status);
 			if (!(skb = dev_alloc_skb(status))) {
 				WARNING("receive out of memory\n");
@@ -542,14 +542,14 @@ int st5481_setup_in(struct st5481_in *in)
 	struct usb_device *dev = in->adapter->usb_dev;
 	int retval;
 
-	DBG(4,"");
+	DBG(4, "");
 
 	in->rcvbuf = kmalloc(in->bufsize, GFP_KERNEL);
 	retval = -ENOMEM;
 	if (!in->rcvbuf)
 		goto err;
 
-	retval = st5481_setup_isocpipes(in->urb, dev, 
+	retval = st5481_setup_isocpipes(in->urb, dev,
 					usb_rcvisocpipe(dev, in->ep),
 					in->num_packets,  in->packet_size,
 					in->num_packets * in->packet_size,
@@ -558,51 +558,51 @@ int st5481_setup_in(struct st5481_in *in)
 		goto err_free;
 	return 0;
 
- err_free:
+err_free:
 	kfree(in->rcvbuf);
- err:
+err:
 	return retval;
 }
 
 void st5481_release_in(struct st5481_in *in)
 {
-	DBG(2,"");
+	DBG(2, "");
 
 	st5481_release_isocpipes(in->urb);
 }
 
 /*
  * Make the transfer_buffer contiguous by
- * copying from the iso descriptors if necessary. 
+ * copying from the iso descriptors if necessary.
  */
 static int st5481_isoc_flatten(struct urb *urb)
 {
-	struct usb_iso_packet_descriptor *pipd,*pend;
-	unsigned char *src,*dst;
+	struct usb_iso_packet_descriptor *pipd, *pend;
+	unsigned char *src, *dst;
 	unsigned int len;
-	
+
 	if (urb->status < 0) {
 		return urb->status;
 	}
 	for (pipd = &urb->iso_frame_desc[0],
 		     pend = &urb->iso_frame_desc[urb->number_of_packets],
-		     dst = urb->transfer_buffer; 
-	     pipd < pend; 
+		     dst = urb->transfer_buffer;
+	     pipd < pend;
 	     pipd++) {
-		
+
 		if (pipd->status < 0) {
 			return (pipd->status);
 		}
-	
+
 		len = pipd->actual_length;
 		pipd->actual_length = 0;
-		src = urb->transfer_buffer+pipd->offset;
+		src = urb->transfer_buffer + pipd->offset;
 
 		if (src != dst) {
 			// Need to copy since isoc buffers not full
 			while (len--) {
 				*dst++ = *src++;
-			}			
+			}
 		} else {
 			// No need to copy, just update destination buffer
 			dst += len;
@@ -617,7 +617,7 @@ static void st5481_start_rcv(void *context)
 	struct st5481_in *in = context;
 	struct st5481_adapter *adapter = in->adapter;
 
-	DBG(4,"");
+	DBG(4, "");
 
 	in->urb[0]->dev = adapter->usb_dev;
 	SUBMIT_URB(in->urb[0], GFP_KERNEL);
@@ -654,4 +654,3 @@ void st5481_in_mode(struct st5481_in *in, int mode)
 					   0, NULL, NULL);
 	}
 }
-
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
index 842f9c9..9195f9f 100644
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -3,7 +3,7 @@
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -43,7 +43,7 @@ enum {
 	ST_TEI_IDVERIFY,
 };
 
-#define TEI_STATE_COUNT (ST_TEI_IDVERIFY+1)
+#define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)
 
 static char *strTeiState[] =
 {
@@ -62,7 +62,7 @@ enum {
 	EV_T202,
 };
 
-#define TEI_EVENT_COUNT (EV_T202+1)
+#define TEI_EVENT_COUNT (EV_T202 + 1)
 
 static char *strTeiEvent[] =
 {
@@ -130,14 +130,14 @@ tei_id_request(struct FsmInst *fi, int event, void *arg)
 
 	if (st->l2.tei != -1) {
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"assign request for already asigned tei %d",
-			st->l2.tei);
+					"assign request for already assigned tei %d",
+					st->l2.tei);
 		return;
 	}
 	st->ma.ri = random_ri();
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"assign request ri %d", st->ma.ri);
+					"assign request ri %d", st->ma.ri);
 	put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
 	FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ);
 	FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1);
@@ -156,11 +156,11 @@ tei_id_assign(struct FsmInst *fi, int event, void *arg)
 	tei = skb->data[4] >> 1;
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"identity assign ri %d tei %d", ri, tei);
+					"identity assign ri %d tei %d", ri, tei);
 	if ((ost = findtei(st, tei))) {	/* same tei is in use */
 		if (ri != ost->ma.ri) {
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"possible duplicate assignment tei %d", tei);
+						"possible duplicate assignment tei %d", tei);
 			ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL);
 		}
 	} else if (ri == st->ma.ri) {
@@ -183,14 +183,14 @@ tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
 	tei = skb->data[4] >> 1;
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"foreign identity assign ri %d tei %d", ri, tei);
+					"foreign identity assign ri %d tei %d", ri, tei);
 	if ((ost = findtei(st, tei))) {	/* same tei is in use */
 		if (ri != ost->ma.ri) {	/* and it wasn't our request */
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"possible duplicate assignment tei %d", tei);
+						"possible duplicate assignment tei %d", tei);
 			FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL);
 		}
-	} 
+	}
 }
 
 static void
@@ -204,7 +204,7 @@ tei_id_denied(struct FsmInst *fi, int event, void *arg)
 	tei = skb->data[4] >> 1;
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"identity denied ri %d tei %d", ri, tei);
+					"identity denied ri %d tei %d", ri, tei);
 }
 
 static void
@@ -217,7 +217,7 @@ tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
 	tei = skb->data[4] >> 1;
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"identity check req tei %d", tei);
+					"identity check req tei %d", tei);
 	if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
 		FsmDelTimer(&st->ma.t202, 4);
 		FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
@@ -236,7 +236,7 @@ tei_id_remove(struct FsmInst *fi, int event, void *arg)
 	tei = skb->data[4] >> 1;
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"identity remove tei %d", tei);
+					"identity remove tei %d", tei);
 	if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
 		FsmDelTimer(&st->ma.t202, 5);
 		FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
@@ -253,7 +253,7 @@ tei_id_verify(struct FsmInst *fi, int event, void *arg)
 
 	if (st->ma.debug)
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"id verify request for tei %d", st->l2.tei);
+					"id verify request for tei %d", st->l2.tei);
 	put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
 	FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY);
 	FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2);
@@ -270,8 +270,8 @@ tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
 		st->ma.ri = random_ri();
 		if (st->ma.debug)
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"assign req(%d) ri %d", 4 - st->ma.N202,
-				st->ma.ri);
+						"assign req(%d) ri %d", 4 - st->ma.N202,
+						st->ma.ri);
 		put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
 		FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3);
 	} else {
@@ -292,13 +292,13 @@ tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
 	if (--st->ma.N202) {
 		if (st->ma.debug)
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"id verify req(%d) for tei %d",
-				3 - st->ma.N202, st->l2.tei);
+						"id verify req(%d) for tei %d",
+						3 - st->ma.N202, st->l2.tei);
 		put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
 		FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4);
 	} else {
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"verify req for tei %d failed", st->l2.tei);
+					"verify req for tei %d failed", st->l2.tei);
 		st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
 		cs = (struct IsdnCardState *) st->l1.hardware;
 		cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
@@ -320,25 +320,25 @@ tei_l1l2(struct PStack *st, int pr, void *arg)
 	if (pr == (PH_DATA | INDICATION)) {
 		if (skb->len < 3) {
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"short mgr frame %ld/3", skb->len);
+						"short mgr frame %ld/3", skb->len);
 		} else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) ||
 			   (skb->data[1] != ((GROUP_TEI << 1) | 1))) {
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"wrong mgr sapi/tei %x/%x",
-				skb->data[0], skb->data[1]);
+						"wrong mgr sapi/tei %x/%x",
+						skb->data[0], skb->data[1]);
 		} else if ((skb->data[2] & 0xef) != UI) {
 			st->ma.tei_m.printdebug(&st->ma.tei_m,
-				"mgr frame is not ui %x", skb->data[2]);
+						"mgr frame is not ui %x", skb->data[2]);
 		} else {
 			skb_pull(skb, 3);
 			if (skb->len < 5) {
 				st->ma.tei_m.printdebug(&st->ma.tei_m,
-					"short mgr frame %ld/5", skb->len);
+							"short mgr frame %ld/5", skb->len);
 			} else if (skb->data[0] != TEI_ENTITY_ID) {
 				/* wrong management entity identifier, ignore */
 				st->ma.tei_m.printdebug(&st->ma.tei_m,
-					"tei handler wrong entity id %x",
-					skb->data[0]);
+							"tei handler wrong entity id %x",
+							skb->data[0]);
 			} else {
 				mt = skb->data[3];
 				if (mt == ID_ASSIGNED)
@@ -351,13 +351,13 @@ tei_l1l2(struct PStack *st, int pr, void *arg)
 					FsmEvent(&st->ma.tei_m, EV_REMOVE, skb);
 				else {
 					st->ma.tei_m.printdebug(&st->ma.tei_m,
-						"tei handler wrong mt %x\n", mt);
+								"tei handler wrong mt %x\n", mt);
 				}
 			}
 		}
 	} else {
 		st->ma.tei_m.printdebug(&st->ma.tei_m,
-			"tei handler wrong pr %x\n", pr);
+					"tei handler wrong pr %x\n", pr);
 	}
 	dev_kfree_skb(skb);
 }
@@ -371,7 +371,7 @@ tei_l2tei(struct PStack *st, int pr, void *arg)
 		if (pr == (MDL_ASSIGN | INDICATION)) {
 			if (st->ma.debug)
 				st->ma.tei_m.printdebug(&st->ma.tei_m,
-					"fixed assign tei %d", st->l2.tei);
+							"fixed assign tei %d", st->l2.tei);
 			st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei);
 			cs = (struct IsdnCardState *) st->l1.hardware;
 			cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
@@ -379,14 +379,14 @@ tei_l2tei(struct PStack *st, int pr, void *arg)
 		return;
 	}
 	switch (pr) {
-		case (MDL_ASSIGN | INDICATION):
-			FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
-			break;
-		case (MDL_ERROR | REQUEST):
-			FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
-			break;
-		default:
-			break;
+	case (MDL_ASSIGN | INDICATION):
+		FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
+		break;
+	case (MDL_ERROR | REQUEST):
+		FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
+		break;
+	default:
+		break;
 	}
 }
 
diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c
index b0ce4ae..fa329e2 100644
--- a/drivers/isdn/hisax/teleint.c
+++ b/drivers/isdn/hisax/teleint.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -18,7 +18,7 @@
 
 static const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static inline u_char
@@ -40,14 +40,14 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
 }
 
 static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	register u_char ret;
 	register int max_delay = 20000;
 	register int i;
-	
+
 	byteout(ale, off);
-	for (i = 0; i<size; i++) {
+	for (i = 0; i < size; i++) {
 		ret = HFC_BUSY & bytein(ale);
 		while (ret && --max_delay)
 			ret = HFC_BUSY & bytein(ale);
@@ -78,14 +78,14 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
 }
 
 static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
 {
 	register u_char ret;
 	register int max_delay = 20000;
 	register int i;
-	
+
 	byteout(ale, off);
-	for (i = 0; i<size; i++) {
+	for (i = 0; i < size; i++) {
 		ret = HFC_BUSY & bytein(ale);
 		while (ret && --max_delay)
 			ret = HFC_BUSY & bytein(ale);
@@ -114,14 +114,14 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	cs->hw.hfc.cip = 0;
 	readfifo(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, 0, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	cs->hw.hfc.cip = 0;
 	writefifo(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, 0, data, size);
@@ -163,7 +163,7 @@ TeleInt_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	val = readreg(cs->hw.hfc.addr | 1, cs->hw.hfc.addr, ISAC_ISTA);
@@ -183,7 +183,7 @@ TeleInt_Timer(struct IsdnCardState *cs)
 {
 	int stat = 0;
 	u_long flags;
-	
+
 	spin_lock_irqsave(&cs->lock, flags);
 	if (cs->bcs[0].mode) {
 		stat |= 1;
@@ -194,7 +194,7 @@ TeleInt_Timer(struct IsdnCardState *cs)
 		main_irq_hfc(&cs->bcs[1]);
 	}
 	spin_unlock_irqrestore(&cs->lock, flags);
-	stat = HZ/100;
+	stat = HZ / 100;
 	if (!stat)
 		stat = 1;
 	cs->hw.hfc.timer.expires = jiffies + stat;
@@ -229,34 +229,34 @@ TeleInt_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	int delay;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_TeleInt(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_TeleInt(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_TeleInt(cs);
-			inithfc(cs);
-			clear_pending_isac_ints(cs);
-			initisac(cs);
-			/* Reenable all IRQ */
-			cs->writeisac(cs, ISAC_MASK, 0);
-			cs->writeisac(cs, ISAC_CMDR, 0x41);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			delay = HZ/100;
-			if (!delay)
-				delay = 1;
-			cs->hw.hfc.timer.expires = jiffies + delay;
-			add_timer(&cs->hw.hfc.timer);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_TeleInt(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_TeleInt(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_TeleInt(cs);
+		inithfc(cs);
+		clear_pending_isac_ints(cs);
+		initisac(cs);
+		/* Reenable all IRQ */
+		cs->writeisac(cs, ISAC_MASK, 0);
+		cs->writeisac(cs, ISAC_CMDR, 0x41);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		delay = HZ / 100;
+		if (!delay)
+			delay = 1;
+		cs->hw.hfc.timer.expires = jiffies + delay;
+		add_timer(&cs->hw.hfc.timer);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 int __devinit
@@ -293,34 +293,34 @@ setup_TeleInt(struct IsdnCard *card)
 	byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff);
 	byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54);
 	switch (cs->irq) {
-		case 3:
-			cs->hw.hfc.cirm |= HFC_INTA;
-			break;
-		case 4:
-			cs->hw.hfc.cirm |= HFC_INTB;
-			break;
-		case 5:
-			cs->hw.hfc.cirm |= HFC_INTC;
-			break;
-		case 7:
-			cs->hw.hfc.cirm |= HFC_INTD;
-			break;
-		case 10:
-			cs->hw.hfc.cirm |= HFC_INTE;
-			break;
-		case 11:
-			cs->hw.hfc.cirm |= HFC_INTF;
-			break;
-		default:
-			printk(KERN_WARNING "TeleInt: wrong IRQ\n");
-			release_io_TeleInt(cs);
-			return (0);
+	case 3:
+		cs->hw.hfc.cirm |= HFC_INTA;
+		break;
+	case 4:
+		cs->hw.hfc.cirm |= HFC_INTB;
+		break;
+	case 5:
+		cs->hw.hfc.cirm |= HFC_INTC;
+		break;
+	case 7:
+		cs->hw.hfc.cirm |= HFC_INTD;
+		break;
+	case 10:
+		cs->hw.hfc.cirm |= HFC_INTE;
+		break;
+	case 11:
+		cs->hw.hfc.cirm |= HFC_INTF;
+		break;
+	default:
+		printk(KERN_WARNING "TeleInt: wrong IRQ\n");
+		release_io_TeleInt(cs);
+		return (0);
 	}
 	byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);
 	byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt);
 
 	printk(KERN_INFO "TeleInt: defined at 0x%x IRQ %d\n",
-		cs->hw.hfc.addr, cs->irq);
+	       cs->hw.hfc.addr, cs->irq);
 
 	setup_isac(cs);
 	cs->readisac = &ReadISAC;
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c
index 3ca0bed..49b4a26 100644
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -5,7 +5,7 @@
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -24,7 +24,7 @@
 static const char *teles0_revision = "$Revision: 2.15.2.4 $";
 
 #define TELES_IOMEM_SIZE	0x400
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static inline u_char
@@ -55,7 +55,7 @@ writehscx(void __iomem *adr, int hscx, u_char off, u_char data)
 }
 
 static inline void
-read_fifo_isac(void __iomem *adr, u_char * data, int size)
+read_fifo_isac(void __iomem *adr, u_char *data, int size)
 {
 	register int i;
 	register u_char __iomem *ad = adr + 0x100;
@@ -64,7 +64,7 @@ read_fifo_isac(void __iomem *adr, u_char * data, int size)
 }
 
 static inline void
-write_fifo_isac(void __iomem *adr, u_char * data, int size)
+write_fifo_isac(void __iomem *adr, u_char *data, int size)
 {
 	register int i;
 	register u_char __iomem *ad = adr + 0x100;
@@ -74,7 +74,7 @@ write_fifo_isac(void __iomem *adr, u_char * data, int size)
 }
 
 static inline void
-read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
+read_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size)
 {
 	register int i;
 	register u_char __iomem *ad = adr + (hscx ? 0x1c0 : 0x180);
@@ -83,7 +83,7 @@ read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
 }
 
 static inline void
-write_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
+write_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size)
 {
 	int i;
 	register u_char __iomem *ad = adr + (hscx ? 0x1c0 : 0x180);
@@ -107,13 +107,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	read_fifo_isac(cs->hw.teles0.membase, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	write_fifo_isac(cs->hw.teles0.membase, data, size);
 }
@@ -151,11 +151,11 @@ teles0_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readisac(cs->hw.teles0.membase, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	count++;
@@ -197,33 +197,33 @@ reset_teles0(struct IsdnCardState *cs)
 
 	if (cs->hw.teles0.cfg_reg) {
 		switch (cs->irq) {
-			case 2:
-			case 9:
-				cfval = 0x00;
-				break;
-			case 3:
-				cfval = 0x02;
-				break;
-			case 4:
-				cfval = 0x04;
-				break;
-			case 5:
-				cfval = 0x06;
-				break;
-			case 10:
-				cfval = 0x08;
-				break;
-			case 11:
-				cfval = 0x0A;
-				break;
-			case 12:
-				cfval = 0x0C;
-				break;
-			case 15:
-				cfval = 0x0E;
-				break;
-			default:
-				return(1);
+		case 2:
+		case 9:
+			cfval = 0x00;
+			break;
+		case 3:
+			cfval = 0x02;
+			break;
+		case 4:
+			cfval = 0x04;
+			break;
+		case 5:
+			cfval = 0x06;
+			break;
+		case 10:
+			cfval = 0x08;
+			break;
+		case 11:
+			cfval = 0x0A;
+			break;
+		case 12:
+			cfval = 0x0C;
+			break;
+		case 15:
+			cfval = 0x0E;
+			break;
+		default:
+			return (1);
 		}
 		cfval |= ((cs->hw.teles0.phymem >> 9) & 0xF0);
 		byteout(cs->hw.teles0.cfg_reg + 4, cfval);
@@ -235,7 +235,7 @@ reset_teles0(struct IsdnCardState *cs)
 	HZDELAY(HZ / 5 + 1);
 	writeb(1, cs->hw.teles0.membase + 0x80); mb();
 	HZDELAY(HZ / 5 + 1);
-	return(0);
+	return (0);
 }
 
 static int
@@ -244,23 +244,23 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_teles0(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_teles0(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_teles0(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_teles0(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 int __devinit
@@ -283,14 +283,14 @@ setup_teles0(struct IsdnCard *card)
 	if (card->para[1] < 0x10000) {
 		card->para[1] <<= 4;
 		printk(KERN_INFO
-		   "Teles0: membase configured DOSish, assuming 0x%lx\n",
+		       "Teles0: membase configured DOSish, assuming 0x%lx\n",
 		       (unsigned long) card->para[1]);
 	}
 	cs->irq = card->para[0];
 	if (cs->hw.teles0.cfg_reg) {
 		if (!request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg")) {
 			printk(KERN_WARNING
-			  "HiSax: %s config port %x-%x already in use\n",
+			       "HiSax: %s config port %x-%x already in use\n",
 			       CardType[card->typ],
 			       cs->hw.teles0.cfg_reg,
 			       cs->hw.teles0.cfg_reg + 8);
@@ -311,8 +311,8 @@ setup_teles0(struct IsdnCard *card)
 			return (0);
 		}
 		val = bytein(cs->hw.teles0.cfg_reg + 2);	/* 0x1e=without AB
-								   * 0x1f=with AB
-								   * 0x1c 16.3 ???
+								 * 0x1f=with AB
+								 * 0x1c 16.3 ???
 								 */
 		if (val != 0x1e && val != 0x1f) {
 			printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
@@ -326,10 +326,10 @@ setup_teles0(struct IsdnCard *card)
 	cs->hw.teles0.phymem = card->para[1];
 	if (!request_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem")) {
 		printk(KERN_WARNING
-			"HiSax: %s memory region %lx-%lx already in use\n",
-			CardType[card->typ],
-			cs->hw.teles0.phymem,
-			cs->hw.teles0.phymem + TELES_IOMEM_SIZE);
+		       "HiSax: %s memory region %lx-%lx already in use\n",
+		       CardType[card->typ],
+		       cs->hw.teles0.phymem,
+		       cs->hw.teles0.phymem + TELES_IOMEM_SIZE);
 		if (cs->hw.teles0.cfg_reg)
 			release_region(cs->hw.teles0.cfg_reg, 8);
 		return (0);
@@ -357,7 +357,7 @@ setup_teles0(struct IsdnCard *card)
 	ISACVersion(cs, "Teles0:");
 	if (HscxVersion(cs, "Teles0:")) {
 		printk(KERN_WARNING
-		 "Teles0: wrong HSCX versions check IO/MEM addresses\n");
+		       "Teles0: wrong HSCX versions check IO/MEM addresses\n");
 		release_io_teles0(cs);
 		return (0);
 	}
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c
index e9f5bb4..220b919 100644
--- a/drivers/isdn/hisax/teles3.c
+++ b/drivers/isdn/hisax/teles3.c
@@ -4,7 +4,7 @@
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -22,7 +22,7 @@
 
 static const char *teles3_revision = "$Revision: 2.19.2.4 $";
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 static inline u_char
@@ -39,13 +39,13 @@ writereg(unsigned int adr, u_char off, u_char data)
 
 
 static inline void
-read_fifo(unsigned int adr, u_char * data, int size)
+read_fifo(unsigned int adr, u_char *data, int size)
 {
 	insb(adr, data, size);
 }
 
 static void
-write_fifo(unsigned int adr, u_char * data, int size)
+write_fifo(unsigned int adr, u_char *data, int size)
 {
 	outsb(adr, data, size);
 }
@@ -65,13 +65,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	read_fifo(cs->hw.teles3.isacfifo, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	write_fifo(cs->hw.teles3.isacfifo, data, size);
 }
@@ -110,11 +110,11 @@ teles3_interrupt(int intno, void *dev_id)
 
 	spin_lock_irqsave(&cs->lock, flags);
 	val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA);
-      Start_HSCX:
+Start_HSCX:
 	if (val)
 		hscx_int_main(cs, val);
 	val = readreg(cs->hw.teles3.isac, ISAC_ISTA);
-      Start_ISAC:
+Start_ISAC:
 	if (val)
 		isac_interrupt(cs, val);
 	count++;
@@ -178,33 +178,33 @@ reset_teles3(struct IsdnCardState *cs)
 	if (cs->typ != ISDN_CTYPE_TELESPCMCIA) {
 		if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) {
 			switch (cs->irq) {
-				case 2:
-				case 9:
-					irqcfg = 0x00;
-					break;
-				case 3:
-					irqcfg = 0x02;
-					break;
-				case 4:
-					irqcfg = 0x04;
-					break;
-				case 5:
-					irqcfg = 0x06;
-					break;
-				case 10:
-					irqcfg = 0x08;
-					break;
-				case 11:
-					irqcfg = 0x0A;
-					break;
-				case 12:
-					irqcfg = 0x0C;
-					break;
-				case 15:
-					irqcfg = 0x0E;
-					break;
-				default:
-					return(1);
+			case 2:
+			case 9:
+				irqcfg = 0x00;
+				break;
+			case 3:
+				irqcfg = 0x02;
+				break;
+			case 4:
+				irqcfg = 0x04;
+				break;
+			case 5:
+				irqcfg = 0x06;
+				break;
+			case 10:
+				irqcfg = 0x08;
+				break;
+			case 11:
+				irqcfg = 0x0A;
+				break;
+			case 12:
+				irqcfg = 0x0C;
+				break;
+			case 15:
+				irqcfg = 0x0E;
+				break;
+			default:
+				return (1);
 			}
 			byteout(cs->hw.teles3.cfg_reg + 4, irqcfg);
 			HZDELAY(HZ / 10 + 1);
@@ -223,7 +223,7 @@ reset_teles3(struct IsdnCardState *cs)
 			HZDELAY(2);
 		}
 	}
-	return(0);
+	return (0);
 }
 
 static int
@@ -232,36 +232,36 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			spin_lock_irqsave(&cs->lock, flags);
-			reset_teles3(cs);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_RELEASE:
-			release_io_teles3(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		spin_lock_irqsave(&cs->lock, flags);
+		reset_teles3(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_RELEASE:
+		release_io_teles3(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 #ifdef __ISAPNP__
 
 static struct isapnp_device_id teles_ids[] __devinitdata = {
 	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), 
+	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110),
 	  (unsigned long) "Teles 16.3 PnP" },
 	{ ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0),
-	  ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0), 
+	  ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0),
 	  (unsigned long) "Creatix 16.3 PnP" },
 	{ ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002),
-	  ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002), 
+	  ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002),
 	  (unsigned long) "Compaq ISDN S0" },
 	{ 0, }
 };
@@ -286,22 +286,22 @@ setup_teles3(struct IsdnCard *card)
 #ifdef __ISAPNP__
 	if (!card->para[1] && isapnp_present()) {
 		struct pnp_dev *pnp_d;
-		while(ipid->card_vendor) {
+		while (ipid->card_vendor) {
 			if ((pnp_c = pnp_find_card(ipid->card_vendor,
-				ipid->card_device, pnp_c))) {
+						   ipid->card_device, pnp_c))) {
 				pnp_d = NULL;
 				if ((pnp_d = pnp_find_dev(pnp_c,
-					ipid->vendor, ipid->function, pnp_d))) {
+							  ipid->vendor, ipid->function, pnp_d))) {
 					int err;
 
 					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)ipid->driver_data);
+					       (char *)ipid->driver_data);
 					pnp_disable_dev(pnp_d);
 					err = pnp_activate_dev(pnp_d);
-					if (err<0) {
+					if (err < 0) {
 						printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n",
-							__func__, err);
-						return(0);
+						       __func__, err);
+						return (0);
 					}
 					card->para[3] = pnp_port_start(pnp_d, 2);
 					card->para[2] = pnp_port_start(pnp_d, 1);
@@ -309,9 +309,9 @@ setup_teles3(struct IsdnCard *card)
 					card->para[0] = pnp_irq(pnp_d, 0);
 					if (!card->para[0] || !card->para[1] || !card->para[2]) {
 						printk(KERN_ERR "Teles PnP:some resources are missing %ld/%lx/%lx\n",
-							card->para[0], card->para[1], card->para[2]);
+						       card->para[0], card->para[1], card->para[2]);
 						pnp_disable_dev(pnp_d);
-						return(0);
+						return (0);
 					}
 					break;
 				} else {
@@ -320,21 +320,21 @@ setup_teles3(struct IsdnCard *card)
 			}
 			ipid++;
 			pnp_c = NULL;
-		} 
+		}
 		if (!ipid->card_vendor) {
 			printk(KERN_INFO "Teles PnP: no ISAPnP card found\n");
-			return(0);
+			return (0);
 		}
 	}
 #endif
 	if (cs->typ == ISDN_CTYPE_16_3) {
 		cs->hw.teles3.cfg_reg = card->para[1];
 		switch (cs->hw.teles3.cfg_reg) {
-			case 0x180:
-			case 0x280:
-			case 0x380:
-				cs->hw.teles3.cfg_reg |= 0xc00;
-				break;
+		case 0x180:
+		case 0x280:
+		case 0x380:
+			cs->hw.teles3.cfg_reg |= 0xc00;
+			break;
 		}
 		cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420;
 		cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20;
@@ -374,9 +374,9 @@ setup_teles3(struct IsdnCard *card)
 			if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
 				if (!request_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) {
 					printk(KERN_WARNING
-						"HiSax: %s config port %x already in use\n",
-						CardType[card->typ],
-						cs->hw.teles3.cfg_reg);
+					       "HiSax: %s config port %x already in use\n",
+					       CardType[card->typ],
+					       cs->hw.teles3.cfg_reg);
 					return (0);
 				}
 			} else {
@@ -385,14 +385,14 @@ setup_teles3(struct IsdnCard *card)
 					       "HiSax: %s config port %x-%x already in use\n",
 					       CardType[card->typ],
 					       cs->hw.teles3.cfg_reg,
-						cs->hw.teles3.cfg_reg + 8);
+					       cs->hw.teles3.cfg_reg + 8);
 					return (0);
 				}
 			}
 		}
 		if (!request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac")) {
 			printk(KERN_WARNING
-			   "HiSax: %s isac ports %x-%x already in use\n",
+			       "HiSax: %s isac ports %x-%x already in use\n",
 			       CardType[cs->typ],
 			       cs->hw.teles3.isac + 32,
 			       cs->hw.teles3.isac + 64);
@@ -407,7 +407,7 @@ setup_teles3(struct IsdnCard *card)
 		}
 		if (!request_region(cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) {
 			printk(KERN_WARNING
-			 "HiSax: %s hscx A ports %x-%x already in use\n",
+			       "HiSax: %s hscx A ports %x-%x already in use\n",
 			       CardType[cs->typ],
 			       cs->hw.teles3.hscx[0] + 32,
 			       cs->hw.teles3.hscx[0] + 64);
@@ -423,7 +423,7 @@ setup_teles3(struct IsdnCard *card)
 		}
 		if (!request_region(cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) {
 			printk(KERN_WARNING
-			 "HiSax: %s hscx B ports %x-%x already in use\n",
+			       "HiSax: %s hscx B ports %x-%x already in use\n",
 			       CardType[cs->typ],
 			       cs->hw.teles3.hscx[1] + 32,
 			       cs->hw.teles3.hscx[1] + 64);
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 161a193..bfe9428 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -1,20 +1,20 @@
 /* $Id: teles_cs.c,v 1.1.2.2 2004/01/25 15:07:06 keil Exp $ */
 /*======================================================================
 
-    A teles S0 PCMCIA client driver
+  A teles S0 PCMCIA client driver
 
-    Based on skeleton by David Hinds, dhinds@allegro.stanford.edu
-    Written by Christof Petig, christof.petig@wtal.de
-    
-    Also inspired by ELSA PCMCIA driver 
-    by Klaus Lichtenwalder <Lichtenwalder@ACM.org>
-    
-    Extensions to new hisax_pcmcia by Karsten Keil
+  Based on skeleton by David Hinds, dhinds@allegro.stanford.edu
+  Written by Christof Petig, christof.petig@wtal.de
 
-    minor changes to be compatible with kernel 2.4.x
-    by Jan.Schubert@GMX.li
+  Also inspired by ELSA PCMCIA driver
+  by Klaus Lichtenwalder <Lichtenwalder@ACM.org>
 
-======================================================================*/
+  Extensions to new hisax_pcmcia by Karsten Keil
+
+  minor changes to be compatible with kernel 2.4.x
+  by Jan.Schubert@GMX.li
+
+  ======================================================================*/
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -44,33 +44,33 @@ MODULE_LICENSE("GPL");
 static int protocol = 2;        /* EURO-ISDN Default */
 module_param(protocol, int, 0);
 
-static int teles_cs_config(struct pcmcia_device *link) __devinit ;
+static int teles_cs_config(struct pcmcia_device *link) __devinit;
 static void teles_cs_release(struct pcmcia_device *link);
-static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
+static void teles_detach(struct pcmcia_device *p_dev) __devexit;
 
 typedef struct local_info_t {
 	struct pcmcia_device	*p_dev;
-    int                 busy;
-    int			cardnr;
+	int                 busy;
+	int			cardnr;
 } local_info_t;
 
 static int __devinit teles_probe(struct pcmcia_device *link)
 {
-    local_info_t *local;
+	local_info_t *local;
 
-    dev_dbg(&link->dev, "teles_attach()\n");
+	dev_dbg(&link->dev, "teles_attach()\n");
 
-    /* Allocate space for private device-specific data */
-    local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return -ENOMEM;
-    local->cardnr = -1;
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (!local) return -ENOMEM;
+	local->cardnr = -1;
 
-    local->p_dev = link;
-    link->priv = local;
+	local->p_dev = link;
+	link->priv = local;
 
-    link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
+	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
 
-    return teles_cs_config(link);
+	return teles_cs_config(link);
 } /* teles_attach */
 
 static void __devexit teles_detach(struct pcmcia_device *link)
@@ -111,64 +111,64 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
 
 static int __devinit teles_cs_config(struct pcmcia_device *link)
 {
-    int i;
-    IsdnCard_t icard;
-
-    dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
-
-    i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
-    if (i != 0)
-	goto cs_failed;
-
-    if (!link->irq)
-        goto cs_failed;
-
-    i = pcmcia_enable_device(link);
-    if (i != 0)
-      goto cs_failed;
-
-    icard.para[0] = link->irq;
-    icard.para[1] = link->resource[0]->start;
-    icard.protocol = protocol;
-    icard.typ = ISDN_CTYPE_TELESPCMCIA;
-    
-    i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard);
-    if (i < 0) {
-    	printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
-			i, (unsigned int) link->resource[0]->start);
-    	teles_cs_release(link);
-	return -ENODEV;
-    }
+	int i;
+	IsdnCard_t icard;
+
+	dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
+
+	i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
+	if (i != 0)
+		goto cs_failed;
+
+	if (!link->irq)
+		goto cs_failed;
+
+	i = pcmcia_enable_device(link);
+	if (i != 0)
+		goto cs_failed;
 
-    ((local_info_t*)link->priv)->cardnr = i;
-    return 0;
+	icard.para[0] = link->irq;
+	icard.para[1] = link->resource[0]->start;
+	icard.protocol = protocol;
+	icard.typ = ISDN_CTYPE_TELESPCMCIA;
+
+	i = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->busy), &icard);
+	if (i < 0) {
+		printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
+		       i, (unsigned int) link->resource[0]->start);
+		teles_cs_release(link);
+		return -ENODEV;
+	}
+
+	((local_info_t *)link->priv)->cardnr = i;
+	return 0;
 
 cs_failed:
-    teles_cs_release(link);
-    return -ENODEV;
+	teles_cs_release(link);
+	return -ENODEV;
 } /* teles_cs_config */
 
 static void teles_cs_release(struct pcmcia_device *link)
 {
-    local_info_t *local = link->priv;
+	local_info_t *local = link->priv;
 
-    dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
+	dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
 
-    if (local) {
-    	if (local->cardnr >= 0) {
-    	    /* no unregister function with hisax */
-	    HiSax_closecard(local->cardnr);
+	if (local) {
+		if (local->cardnr >= 0) {
+			/* no unregister function with hisax */
+			HiSax_closecard(local->cardnr);
+		}
 	}
-    }
 
-    pcmcia_disable_device(link);
+	pcmcia_disable_device(link);
 } /* teles_cs_release */
 
 static int teles_suspend(struct pcmcia_device *link)
 {
 	local_info_t *dev = link->priv;
 
-        dev->busy = 1;
+	dev->busy = 1;
 
 	return 0;
 }
@@ -177,7 +177,7 @@ static int teles_resume(struct pcmcia_device *link)
 {
 	local_info_t *dev = link->priv;
 
-        dev->busy = 0;
+	dev->busy = 0;
 
 	return 0;
 }
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c
index b85ceb3..9c002c9 100644
--- a/drivers/isdn/hisax/telespci.c
+++ b/drivers/isdn/hisax/telespci.c
@@ -6,7 +6,7 @@
  *              Karsten Keil
  * Copyright    by Ton van Rosmalen
  *              by Karsten Keil      <keil@isdn4linux.de>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -36,9 +36,9 @@ static const char *telespci_revision = "$Revision: 2.23.2.3 $";
 #define READ_DATA_HSCX	(ZORAN_PO_GID1 | ZORAN_PO_GREG1)
 #define WRITE_DATA_HSCX	(ZORAN_PO_WR | ZORAN_PO_GID1 | ZORAN_PO_GREG1)
 
-#define ZORAN_WAIT_NOBUSY	do { \
-					portdata = readl(adr + 0x200); \
-				} while (portdata & ZORAN_PO_RQ_PEN)
+#define ZORAN_WAIT_NOBUSY	do {		\
+		portdata = readl(adr + 0x200);	\
+	} while (portdata & ZORAN_PO_RQ_PEN)
 
 static inline u_char
 readisac(void __iomem *adr, u_char off)
@@ -46,15 +46,15 @@ readisac(void __iomem *adr, u_char off)
 	register unsigned int portdata;
 
 	ZORAN_WAIT_NOBUSY;
-	
+
 	/* set address for ISAC */
 	writel(WRITE_ADDR_ISAC | off, adr + 0x200);
 	ZORAN_WAIT_NOBUSY;
-	
+
 	/* read data from ISAC */
 	writel(READ_DATA_ISAC, adr + 0x200);
 	ZORAN_WAIT_NOBUSY;
-	return((u_char)(portdata & ZORAN_PO_DMASK));
+	return ((u_char)(portdata & ZORAN_PO_DMASK));
 }
 
 static inline void
@@ -63,7 +63,7 @@ writeisac(void __iomem *adr, u_char off, u_char data)
 	register unsigned int portdata;
 
 	ZORAN_WAIT_NOBUSY;
-	
+
 	/* set address for ISAC */
 	writel(WRITE_ADDR_ISAC | off, adr + 0x200);
 	ZORAN_WAIT_NOBUSY;
@@ -80,9 +80,9 @@ readhscx(void __iomem *adr, int hscx, u_char off)
 
 	ZORAN_WAIT_NOBUSY;
 	/* set address for HSCX */
-	writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
+	writel(WRITE_ADDR_HSCX | ((hscx ? 0x40 : 0) + off), adr + 0x200);
 	ZORAN_WAIT_NOBUSY;
-	
+
 	/* read data from HSCX */
 	writel(READ_DATA_HSCX, adr + 0x200);
 	ZORAN_WAIT_NOBUSY;
@@ -96,7 +96,7 @@ writehscx(void __iomem *adr, int hscx, u_char off, u_char data)
 
 	ZORAN_WAIT_NOBUSY;
 	/* set address for HSCX */
-	writel(WRITE_ADDR_HSCX | ((hscx ? 0x40:0) + off), adr + 0x200);
+	writel(WRITE_ADDR_HSCX | ((hscx ? 0x40 : 0) + off), adr + 0x200);
 	ZORAN_WAIT_NOBUSY;
 
 	/* write data to HSCX */
@@ -105,7 +105,7 @@ writehscx(void __iomem *adr, int hscx, u_char off, u_char data)
 }
 
 static inline void
-read_fifo_isac(void __iomem *adr, u_char * data, int size)
+read_fifo_isac(void __iomem *adr, u_char *data, int size)
 {
 	register unsigned int portdata;
 	register int i;
@@ -123,7 +123,7 @@ read_fifo_isac(void __iomem *adr, u_char * data, int size)
 }
 
 static void
-write_fifo_isac(void __iomem *adr, u_char * data, int size)
+write_fifo_isac(void __iomem *adr, u_char *data, int size)
 {
 	register unsigned int portdata;
 	register int i;
@@ -140,7 +140,7 @@ write_fifo_isac(void __iomem *adr, u_char * data, int size)
 }
 
 static inline void
-read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
+read_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size)
 {
 	register unsigned int portdata;
 	register int i;
@@ -149,7 +149,7 @@ read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
 	/* read data from HSCX */
 	for (i = 0; i < size; i++) {
 		/* set address for HSCX fifo */
-		writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
+		writel(WRITE_ADDR_HSCX | (hscx ? 0x5F : 0x1F), adr + 0x200);
 		ZORAN_WAIT_NOBUSY;
 		writel(READ_DATA_HSCX, adr + 0x200);
 		ZORAN_WAIT_NOBUSY;
@@ -158,7 +158,7 @@ read_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
 }
 
 static inline void
-write_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
+write_fifo_hscx(void __iomem *adr, int hscx, u_char *data, int size)
 {
 	unsigned int portdata;
 	register int i;
@@ -167,7 +167,7 @@ write_fifo_hscx(void __iomem *adr, int hscx, u_char * data, int size)
 	/* write data to HSCX */
 	for (i = 0; i < size; i++) {
 		/* set address for HSCX fifo */
-		writel(WRITE_ADDR_HSCX |(hscx ? 0x5F:0x1F), adr + 0x200);
+		writel(WRITE_ADDR_HSCX | (hscx ? 0x5F : 0x1F), adr + 0x200);
 		ZORAN_WAIT_NOBUSY;
 		writel(WRITE_DATA_HSCX | data[i], adr + 0x200);
 		ZORAN_WAIT_NOBUSY;
@@ -190,13 +190,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	read_fifo_isac(cs->hw.teles0.membase, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	write_fifo_isac(cs->hw.teles0.membase, data, size);
 }
@@ -267,20 +267,20 @@ TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 	u_long flags;
 
 	switch (mt) {
-		case CARD_RESET:
-			return(0);
-		case CARD_RELEASE:
-			release_io_telespci(cs);
-			return(0);
-		case CARD_INIT:
-			spin_lock_irqsave(&cs->lock, flags);
-			inithscxisac(cs, 3);
-			spin_unlock_irqrestore(&cs->lock, flags);
-			return(0);
-		case CARD_TEST:
-			return(0);
+	case CARD_RESET:
+		return (0);
+	case CARD_RELEASE:
+		release_io_telespci(cs);
+		return (0);
+	case CARD_INIT:
+		spin_lock_irqsave(&cs->lock, flags);
+		inithscxisac(cs, 3);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
-	return(0);
+	return (0);
 }
 
 static struct pci_dev *dev_tel __devinitdata = NULL;
@@ -300,22 +300,22 @@ setup_telespci(struct IsdnCard *card)
 	if (cs->typ != ISDN_CTYPE_TELESPCI)
 		return (0);
 
-	if ((dev_tel = hisax_find_pci_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
+	if ((dev_tel = hisax_find_pci_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
 		if (pci_enable_device(dev_tel))
-			return(0);
+			return (0);
 		cs->irq = dev_tel->irq;
 		if (!cs->irq) {
 			printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
-			return(0);
+			return (0);
 		}
 		cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0),
-			PAGE_SIZE);
+						PAGE_SIZE);
 		printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n",
-			(unsigned long long)pci_resource_start(dev_tel, 0),
-			dev_tel->irq);
+		       (unsigned long long)pci_resource_start(dev_tel, 0),
+		       dev_tel->irq);
 	} else {
 		printk(KERN_WARNING "TelesPCI: No PCI card found\n");
-		return(0);
+		return (0);
 	}
 
 	/* Initialize Zoran PCI controller */
@@ -346,7 +346,7 @@ setup_telespci(struct IsdnCard *card)
 	ISACVersion(cs, "TelesPCI:");
 	if (HscxVersion(cs, "TelesPCI:")) {
 		printk(KERN_WARNING
-		 "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
+		       "TelesPCI: wrong HSCX versions check IO/MEM addresses\n");
 		release_io_telespci(cs);
 		return (0);
 	}
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index e2cfb6f..0f0d094 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -4,7 +4,7 @@
  *
  * Author       Petr Novak
  * Copyright    by Petr Novak        <petr.novak@i.cz>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -69,33 +69,33 @@ static void
 W6692_new_ph(struct IsdnCardState *cs)
 {
 	switch (cs->dc.w6692.ph_state) {
-		case (W_L1CMD_RST):
-			ph_command(cs, W_L1CMD_DRC);
-			l1_msg(cs, HW_RESET | INDICATION, NULL);
-			/* fallthru */
-		case (W_L1IND_CD):
-			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
-			break;
-		case (W_L1IND_DRD):
-			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-			break;
-		case (W_L1IND_CE):
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-		case (W_L1IND_LD):
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-			break;
-		case (W_L1IND_ARD):
-			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-			break;
-		case (W_L1IND_AI8):
-			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-			break;
-		case (W_L1IND_AI10):
-			l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
-			break;
-		default:
-			break;
+	case (W_L1CMD_RST):
+		ph_command(cs, W_L1CMD_DRC);
+		l1_msg(cs, HW_RESET | INDICATION, NULL);
+		/* fallthru */
+	case (W_L1IND_CD):
+		l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
+		break;
+	case (W_L1IND_DRD):
+		l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
+		break;
+	case (W_L1IND_CE):
+		l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
+		break;
+	case (W_L1IND_LD):
+		l1_msg(cs, HW_RSYNC | INDICATION, NULL);
+		break;
+	case (W_L1IND_ARD):
+		l1_msg(cs, HW_INFO2 | INDICATION, NULL);
+		break;
+	case (W_L1IND_AI8):
+		l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
+		break;
+	case (W_L1IND_AI10):
+		l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
+		break;
+	default:
+		break;
 	}
 }
 
@@ -122,11 +122,11 @@ W6692_bh(struct work_struct *work)
 	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event))
 		DChannel_proc_xmt(cs);
 /*
-   if (test_and_clear_bit(D_RX_MON1, &cs->event))
-   arcofi_fsm(cs, ARCOFI_RX_END, NULL);
-   if (test_and_clear_bit(D_TX_MON1, &cs->event))
-   arcofi_fsm(cs, ARCOFI_TX_END, NULL);
- */
+  if (test_and_clear_bit(D_RX_MON1, &cs->event))
+  arcofi_fsm(cs, ARCOFI_RX_END, NULL);
+  if (test_and_clear_bit(D_TX_MON1, &cs->event))
+  arcofi_fsm(cs, ARCOFI_TX_END, NULL);
+*/
 }
 
 static void
@@ -250,7 +250,7 @@ W6692B_fill_fifo(struct BCState *bcs)
 		count = bcs->tx_skb->len;
 
 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
-		debugl1(cs, "W6692B_fill_fifo%s%d", (more ? " ": " last "), count);
+		debugl1(cs, "W6692B_fill_fifo%s%d", (more ? " " : " last "), count);
 
 	ptr = bcs->tx_skb->data;
 	skb_pull(bcs->tx_skb, count);
@@ -277,7 +277,7 @@ W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
 	struct sk_buff *skb;
 	int count;
 
-	bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs+1);
+	bcs = (cs->bcs->channel == bchan) ? cs->bcs : (cs->bcs + 1);
 	val = cs->BC_Read_Reg(cs, bchan, W_B_EXIR);
 	debugl1(cs, "W6692B chan %d B_EXIR 0x%02X", bchan, val);
 
@@ -322,7 +322,7 @@ W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
 		r = cs->BC_Read_Reg(cs, bchan, W_B_STAR);
 		if (r & W_B_STAR_RDOV) {
 			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "W6692 B RDOV(RMR) mode=%d",bcs->mode);
+				debugl1(cs, "W6692 B RDOV(RMR) mode=%d", bcs->mode);
 			cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT);
 			if (bcs->mode != L1_MODE_TRANS)
 				bcs->hw.w6692.rcvidx = 0;
@@ -347,7 +347,7 @@ W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
 			W6692B_fill_fifo(bcs);
 		else {
 			/* Here we lost an TX interrupt, so
-			   * restart transmitting the whole frame.
+			 * restart transmitting the whole frame.
 			 */
 			if (bcs->tx_skb) {
 				skb_push(bcs->tx_skb, bcs->hw.w6692.count);
@@ -374,9 +374,9 @@ W6692B_interrupt(struct IsdnCardState *cs, u_char bchan)
 				W6692B_fill_fifo(bcs);
 				return;
 			} else {
-				if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
-					(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
-					u_long	flags;
+				if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
+				    (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
+					u_long flags;
 					spin_lock_irqsave(&bcs->aclock, flags);
 					bcs->ackcnt += bcs->hw.w6692.count;
 					spin_unlock_irqrestore(&bcs->aclock, flags);
@@ -414,7 +414,7 @@ W6692_interrupt(int intno, void *dev_id)
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return IRQ_NONE;
 	}
-      StartW6692:
+StartW6692:
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "W6692 ISTA %x", val);
 
@@ -473,7 +473,7 @@ W6692_interrupt(int intno, void *dev_id)
 		} else
 			schedule_event(cs, D_XMTBUFREADY);
 	}
-      afterXFR:
+afterXFR:
 	if (val & (W_INT_XINT0 | W_INT_XINT1)) {	/* XINT0/1 - never */
 		if (cs->debug & L1_DEB_ISAC)
 			debugl1(cs, "W6692 spurious XINT!");
@@ -564,108 +564,108 @@ W6692_l1hw(struct PStack *st, int pr, void *arg)
 	int val;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				skb_queue_tail(&cs->sq, skb);
-#ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
-#endif
-			} else {
-				cs->tx_skb = skb;
-				cs->tx_cnt = 0;
+	case (PH_DATA | REQUEST):
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			skb_queue_tail(&cs->sq, skb);
 #ifdef L2FRAME_DEBUG		/* psa */
-				if (cs->debug & L1_DEB_LAPD)
-					Logl2Frame(cs, skb, "PH_DATA", 0);
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA Queued", 0);
 #endif
-				W6692_fill_fifo(cs);
-			}
-			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			spin_lock_irqsave(&cs->lock, flags);
-			if (cs->tx_skb) {
-				if (cs->debug & L1_DEB_WARN)
-					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
-				skb_queue_tail(&cs->sq, skb);
-				spin_unlock_irqrestore(&cs->lock, flags);
-				break;
-			}
-			if (cs->debug & DEB_DLOG_HEX)
-				LogFrame(cs, skb->data, skb->len);
-			if (cs->debug & DEB_DLOG_VERBOSE)
-				dlogframe(cs, skb, 0);
+		} else {
 			cs->tx_skb = skb;
 			cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
 			if (cs->debug & L1_DEB_LAPD)
-				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+				Logl2Frame(cs, skb, "PH_DATA", 0);
 #endif
 			W6692_fill_fifo(cs);
+		}
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		spin_lock_irqsave(&cs->lock, flags);
+		if (cs->tx_skb) {
+			if (cs->debug & L1_DEB_WARN)
+				debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+			skb_queue_tail(&cs->sq, skb);
 			spin_unlock_irqrestore(&cs->lock, flags);
 			break;
-		case (PH_PULL | REQUEST):
+		}
+		if (cs->debug & DEB_DLOG_HEX)
+			LogFrame(cs, skb->data, skb->len);
+		if (cs->debug & DEB_DLOG_VERBOSE)
+			dlogframe(cs, skb, 0);
+		cs->tx_skb = skb;
+		cs->tx_cnt = 0;
 #ifdef L2FRAME_DEBUG		/* psa */
-			if (cs->debug & L1_DEB_LAPD)
-				debugl1(cs, "-> PH_REQUEST_PULL");
+		if (cs->debug & L1_DEB_LAPD)
+			Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
 #endif
-			if (!cs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (HW_RESET | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) {
-				ph_command(cs, W_L1CMD_ECK);
-				spin_unlock_irqrestore(&cs->lock, flags);
-			} else {
-				ph_command(cs, W_L1CMD_RST);
-				cs->dc.w6692.ph_state = W_L1CMD_RST;
-				spin_unlock_irqrestore(&cs->lock, flags);
-				W6692_new_ph(cs);
-			}
-			break;
-		case (HW_ENABLE | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
+		W6692_fill_fifo(cs);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+#ifdef L2FRAME_DEBUG		/* psa */
+		if (cs->debug & L1_DEB_LAPD)
+			debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+		if (!cs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (HW_RESET | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) {
 			ph_command(cs, W_L1CMD_ECK);
 			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_INFO3 | REQUEST):
-			spin_lock_irqsave(&cs->lock, flags);
-			ph_command(cs, W_L1CMD_AR8);
+		} else {
+			ph_command(cs, W_L1CMD_RST);
+			cs->dc.w6692.ph_state = W_L1CMD_RST;
 			spin_unlock_irqrestore(&cs->lock, flags);
-			break;
-		case (HW_TESTLOOP | REQUEST):
-			val = 0;
-			if (1 & (long) arg)
-				val |= 0x0c;
-			if (2 & (long) arg)
-				val |= 0x3;
-			/* !!! not implemented yet */
-			break;
-		case (HW_DEACTIVATE | RESPONSE):
-			skb_queue_purge(&cs->rq);
-			skb_queue_purge(&cs->sq);
-			if (cs->tx_skb) {
-				dev_kfree_skb_any(cs->tx_skb);
-				cs->tx_skb = NULL;
-			}
-			if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
-				del_timer(&cs->dbusytimer);
-			if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
-				schedule_event(cs, D_CLEARBUSY);
-			break;
-		default:
-			if (cs->debug & L1_DEB_WARN)
-				debugl1(cs, "W6692_l1hw unknown %04x", pr);
-			break;
+			W6692_new_ph(cs);
+		}
+		break;
+	case (HW_ENABLE | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, W_L1CMD_ECK);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_INFO3 | REQUEST):
+		spin_lock_irqsave(&cs->lock, flags);
+		ph_command(cs, W_L1CMD_AR8);
+		spin_unlock_irqrestore(&cs->lock, flags);
+		break;
+	case (HW_TESTLOOP | REQUEST):
+		val = 0;
+		if (1 & (long) arg)
+			val |= 0x0c;
+		if (2 & (long) arg)
+			val |= 0x3;
+		/* !!! not implemented yet */
+		break;
+	case (HW_DEACTIVATE | RESPONSE):
+		skb_queue_purge(&cs->rq);
+		skb_queue_purge(&cs->sq);
+		if (cs->tx_skb) {
+			dev_kfree_skb_any(cs->tx_skb);
+			cs->tx_skb = NULL;
+		}
+		if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
+			del_timer(&cs->dbusytimer);
+		if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+			schedule_event(cs, D_CLEARBUSY);
+		break;
+	default:
+		if (cs->debug & L1_DEB_WARN)
+			debugl1(cs, "W6692_l1hw unknown %04x", pr);
+		break;
 	}
 }
 
@@ -734,17 +734,17 @@ W6692Bmode(struct BCState *bcs, int mode, int bchan)
 	bcs->hw.w6692.bchan = bchan;
 
 	switch (mode) {
-		case (L1_MODE_NULL):
-			cs->BC_Write_Reg(cs, bchan, W_B_MODE, 0);
-			break;
-		case (L1_MODE_TRANS):
-			cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_MMS);
-			break;
-		case (L1_MODE_HDLC):
-			cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_ITF);
-			cs->BC_Write_Reg(cs, bchan, W_B_ADM1, 0xff);
-			cs->BC_Write_Reg(cs, bchan, W_B_ADM2, 0xff);
-			break;
+	case (L1_MODE_NULL):
+		cs->BC_Write_Reg(cs, bchan, W_B_MODE, 0);
+		break;
+	case (L1_MODE_TRANS):
+		cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_MMS);
+		break;
+	case (L1_MODE_HDLC):
+		cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_ITF);
+		cs->BC_Write_Reg(cs, bchan, W_B_ADM1, 0xff);
+		cs->BC_Write_Reg(cs, bchan, W_B_ADM2, 0xff);
+		break;
 	}
 	if (mode)
 		cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RRST |
@@ -756,59 +756,59 @@ static void
 W6692_l2l1(struct PStack *st, int pr, void *arg)
 {
 	struct sk_buff *skb = arg;
-	struct BCState *bcs = st->l1.bcs; 
+	struct BCState *bcs = st->l1.bcs;
 	u_long flags;
 
 	switch (pr) {
-		case (PH_DATA | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			if (bcs->tx_skb) {
-				skb_queue_tail(&bcs->squeue, skb);
-			} else {
-				bcs->tx_skb = skb;
-				test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
-				bcs->hw.w6692.count = 0;
-				bcs->cs->BC_Send_Data(bcs);
-			}
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | INDICATION):
-			if (bcs->tx_skb) {
-				printk(KERN_WARNING "W6692_l2l1: this shouldn't happen\n");
-				break;
-			}
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+	case (PH_DATA | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		if (bcs->tx_skb) {
+			skb_queue_tail(&bcs->squeue, skb);
+		} else {
 			bcs->tx_skb = skb;
+			test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
 			bcs->hw.w6692.count = 0;
 			bcs->cs->BC_Send_Data(bcs);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			break;
-		case (PH_PULL | REQUEST):
-			if (!bcs->tx_skb) {
-				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
-			} else
-				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
-			break;
-		case (PH_ACTIVATE | REQUEST):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
-			W6692Bmode(bcs, st->l1.mode, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | REQUEST):
-			l1_msg_b(st, pr, arg);
-			break;
-		case (PH_DEACTIVATE | CONFIRM):
-			spin_lock_irqsave(&bcs->cs->lock, flags);
-			test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
-			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
-			W6692Bmode(bcs, 0, st->l1.bc);
-			spin_unlock_irqrestore(&bcs->cs->lock, flags);
-			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		}
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | INDICATION):
+		if (bcs->tx_skb) {
+			printk(KERN_WARNING "W6692_l2l1: this shouldn't happen\n");
 			break;
+		}
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+		bcs->tx_skb = skb;
+		bcs->hw.w6692.count = 0;
+		bcs->cs->BC_Send_Data(bcs);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		break;
+	case (PH_PULL | REQUEST):
+		if (!bcs->tx_skb) {
+			test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+		} else
+			test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+		break;
+	case (PH_ACTIVATE | REQUEST):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
+		W6692Bmode(bcs, st->l1.mode, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | REQUEST):
+		l1_msg_b(st, pr, arg);
+		break;
+	case (PH_DEACTIVATE | CONFIRM):
+		spin_lock_irqsave(&bcs->cs->lock, flags);
+		test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
+		test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		W6692Bmode(bcs, 0, st->l1.bc);
+		spin_unlock_irqrestore(&bcs->cs->lock, flags);
+		st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+		break;
 	}
 }
 
@@ -943,13 +943,13 @@ WriteW6692(struct IsdnCardState *cs, u_char offset, u_char value)
 }
 
 static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size);
 }
 
 static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
 {
 	outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size);
 }
@@ -970,26 +970,26 @@ static int
 w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
 	switch (mt) {
-		case CARD_RESET:
-			resetW6692(cs);
-			return (0);
-		case CARD_RELEASE:
-			cs->writeW6692(cs, W_IMASK, 0xff);
-			release_region(cs->hw.w6692.iobase, 256);
-			if (cs->subtyp == W6692_USR) {
-				cs->writeW6692(cs, W_XDATA, 0x04);
-			}
-			return (0);
-		case CARD_INIT:
-			initW6692(cs, 3);
-			return (0);
-		case CARD_TEST:
-			return (0);
+	case CARD_RESET:
+		resetW6692(cs);
+		return (0);
+	case CARD_RELEASE:
+		cs->writeW6692(cs, W_IMASK, 0xff);
+		release_region(cs->hw.w6692.iobase, 256);
+		if (cs->subtyp == W6692_USR) {
+			cs->writeW6692(cs, W_XDATA, 0x04);
+		}
+		return (0);
+	case CARD_INIT:
+		initW6692(cs, 3);
+		return (0);
+	case CARD_TEST:
+		return (0);
 	}
 	return (0);
 }
 
-static int id_idx ;
+static int id_idx;
 
 static struct pci_dev *dev_w6692 __devinitdata = NULL;
 
@@ -1009,8 +1009,8 @@ setup_w6692(struct IsdnCard *card)
 
 	while (id_list[id_idx].vendor_id) {
 		dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id,
-					    id_list[id_idx].device_id,
-					    dev_w6692);
+						  id_list[id_idx].device_id,
+						  dev_w6692);
 		if (dev_w6692) {
 			if (pci_enable_device(dev_w6692))
 				continue;
diff --git a/drivers/isdn/hisax/w6692.h b/drivers/isdn/hisax/w6692.h
index c79c81e..024b04d 100644
--- a/drivers/isdn/hisax/w6692.h
+++ b/drivers/isdn/hisax/w6692.h
@@ -4,7 +4,7 @@
  *
  * Author       Petr Novak
  * Copyright    by Petr Novak        <petr.novak@i.cz>
- * 
+ *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
@@ -18,11 +18,11 @@
 
 /* B-channel FIFO read/write routines */
 
-#define READW6692BFIFO(cs,bchan,ptr,count) \
-	insb(cs->hw.w6692.iobase+W_B_RFIFO+(bchan?0x40:0),ptr,count)
+#define READW6692BFIFO(cs, bchan, ptr, count)				\
+	insb(cs->hw.w6692.iobase + W_B_RFIFO + (bchan ? 0x40 : 0), ptr, count)
 
-#define WRITEW6692BFIFO(cs,bchan,ptr,count) \
-	outsb(cs->hw.w6692.iobase+W_B_XFIFO+(bchan?0x40:0),ptr,count)
+#define WRITEW6692BFIFO(cs, bchan, ptr, count)				\
+	outsb(cs->hw.w6692.iobase + W_B_XFIFO + (bchan ? 0x40 : 0), ptr, count)
 
 /* Specifications of W6692 registers */
 
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
index 3eb096f..2aa2a0e 100644
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -25,7 +25,7 @@
 #include "hysdn_defs.h"
 #include "boardergo.h"
 
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
 #define bytein(addr) inb(addr)
 
 /***************************************************/
@@ -73,7 +73,7 @@ ergo_interrupt(int intno, void *dev_id)
 static void
 ergo_irq_bh(struct work_struct *ugli_api)
 {
-	hysdn_card * card = container_of(ugli_api, hysdn_card, irq_queue);
+	hysdn_card *card = container_of(ugli_api, hysdn_card, irq_queue);
 	tErgDpram *dpr;
 	int again;
 	unsigned long flags;
@@ -125,7 +125,7 @@ ergo_irq_bh(struct work_struct *ugli_api)
 /* stop the card (hardware reset) and disable interrupts */
 /*********************************************************/
 static void
-ergo_stopcard(hysdn_card * card)
+ergo_stopcard(hysdn_card *card)
 {
 	unsigned long flags;
 	unsigned char val;
@@ -150,7 +150,7 @@ ergo_stopcard(hysdn_card * card)
 /* enable or disable the cards error log. The event is queued if possible */
 /**************************************************************************/
 static void
-ergo_set_errlog_state(hysdn_card * card, int on)
+ergo_set_errlog_state(hysdn_card *card, int on)
 {
 	unsigned long flags;
 
@@ -180,7 +180,7 @@ ergo_set_errlog_state(hysdn_card * card, int on)
 static const char TestText[36] = "This Message is filler, why read it";
 
 static int
-ergo_testram(hysdn_card * card)
+ergo_testram(hysdn_card *card)
 {
 	tErgDpram *dpr = card->dpram;
 
@@ -212,12 +212,12 @@ ergo_testram(hysdn_card * card)
 /*****************************************************************************/
 static int
 ergo_writebootimg(struct HYSDN_CARD *card, unsigned char *buf,
-			unsigned long offs)
+		  unsigned long offs)
 {
 	unsigned char *dst;
 	tErgDpram *dpram;
 	int cnt = (BOOT_IMG_SIZE >> 2);		/* number of words to move and swap (byte order!) */
-	
+
 	if (card->debug_flags & LOG_POF_CARD)
 		hysdn_addlog(card, "ERGO: write bootldr offs=0x%lx ", offs);
 
@@ -355,7 +355,7 @@ ergo_waitpofready(struct HYSDN_CARD *card)
 			/* enable the cards interrupt */
 			byteout(card->iobase + PCI9050_INTR_REG,
 				bytein(card->iobase + PCI9050_INTR_REG) |
-			(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1));
+				(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1));
 			card->irq_enabled = 1;	/* we are ready to receive interrupts */
 
 			dpr->ToPcFlag = 0;	/* reset data indicator */
@@ -363,15 +363,15 @@ ergo_waitpofready(struct HYSDN_CARD *card)
 			dpr->ToPcInt = 1;	/* interrupt to E1 for all cards */
 
 			spin_unlock_irqrestore(&card->hysdn_lock, flags);
-			if ((hynet_enable & (1 << card->myid)) 
-			    && (i = hysdn_net_create(card))) 
+			if ((hynet_enable & (1 << card->myid))
+			    && (i = hysdn_net_create(card)))
 			{
 				ergo_stopcard(card);
 				card->state = CARD_STATE_BOOTERR;
 				return (i);
 			}
 #ifdef CONFIG_HYSDN_CAPI
-			if((i = hycapi_capi_create(card))) {
+			if ((i = hycapi_capi_create(card))) {
 				printk(KERN_WARNING "HYSDN: failed to create capi-interface.\n");
 			}
 #endif /* CONFIG_HYSDN_CAPI */
@@ -393,7 +393,7 @@ ergo_waitpofready(struct HYSDN_CARD *card)
 /* Use only during module release.                                                  */
 /************************************************************************************/
 static void
-ergo_releasehardware(hysdn_card * card)
+ergo_releasehardware(hysdn_card *card)
 {
 	ergo_stopcard(card);	/* first stop the card if not already done */
 	free_irq(card->irq, card);	/* release interrupt */
@@ -410,9 +410,9 @@ ergo_releasehardware(hysdn_card * card)
 /* Use only during module init.                                                  */
 /*********************************************************************************/
 int
-ergo_inithardware(hysdn_card * card)
+ergo_inithardware(hysdn_card *card)
 {
-	if (!request_region(card->iobase + PCI9050_INTR_REG, 1, "HYSDN")) 
+	if (!request_region(card->iobase + PCI9050_INTR_REG, 1, "HYSDN"))
 		return (-1);
 	if (!request_region(card->iobase + PCI9050_USER_IO, 1, "HYSDN")) {
 		release_region(card->iobase + PCI9050_INTR_REG, 1);
diff --git a/drivers/isdn/hysdn/boardergo.h b/drivers/isdn/hysdn/boardergo.h
index c59422a..e99bd81 100644
--- a/drivers/isdn/hysdn/boardergo.h
+++ b/drivers/isdn/hysdn/boardergo.h
@@ -23,8 +23,8 @@
 
 /* following DPRAM layout copied from OS2-driver boarderg.h */
 typedef struct ErgDpram_tag {
-/*0000 */ unsigned char ToHyBuf[ERG_TO_HY_BUF_SIZE];
-/*0E00 */ unsigned char ToPcBuf[ERG_TO_PC_BUF_SIZE];
+	/*0000 */ unsigned char ToHyBuf[ERG_TO_HY_BUF_SIZE];
+	/*0E00 */ unsigned char ToPcBuf[ERG_TO_PC_BUF_SIZE];
 
 	/*1C00 */ unsigned char bSoftUart[SIZE_RSV_SOFT_UART];
 	/* size 0x1B0 */
@@ -37,22 +37,22 @@ typedef struct ErgDpram_tag {
 	/*1DB9  unsigned long ucText[ERRLOG_TEXT_SIZE]; *//* ASCIIZ of len ucTextSize-1 */
 	/*1DF0 */
 
-/*1DF0 */ unsigned short volatile ToHyChannel;
-/*1DF2 */ unsigned short volatile ToHySize;
+	/*1DF0 */ unsigned short volatile ToHyChannel;
+	/*1DF2 */ unsigned short volatile ToHySize;
 	/*1DF4 */ unsigned char volatile ToHyFlag;
 	/* !=0: msg for Hy waiting */
 	/*1DF5 */ unsigned char volatile ToPcFlag;
 	/* !=0: msg for PC waiting */
-/*1DF6 */ unsigned short volatile ToPcChannel;
-/*1DF8 */ unsigned short volatile ToPcSize;
+	/*1DF6 */ unsigned short volatile ToPcChannel;
+	/*1DF8 */ unsigned short volatile ToPcSize;
 	/*1DFA */ unsigned char bRes1DBA[0x1E00 - 0x1DFA];
 	/* 6 bytes */
 
-/*1E00 */ unsigned char bRestOfEntryTbl[0x1F00 - 0x1E00];
-/*1F00 */ unsigned long TrapTable[62];
+	/*1E00 */ unsigned char bRestOfEntryTbl[0x1F00 - 0x1E00];
+	/*1F00 */ unsigned long TrapTable[62];
 	/*1FF8 */ unsigned char bRes1FF8[0x1FFB - 0x1FF8];
 	/* low part of reset vetor */
-/*1FFB */ unsigned char ToPcIntMetro;
+	/*1FFB */ unsigned char ToPcIntMetro;
 	/* notes:
 	 * - metro has 32-bit boot ram - accessing
 	 *   ToPcInt and ToHyInt would be the same;
@@ -65,13 +65,13 @@ typedef struct ErgDpram_tag {
 	 *   so E1 side should NOT change this byte
 	 *   when writing!
 	 */
-/*1FFC */ unsigned char volatile ToHyNoDpramErrLog;
+	/*1FFC */ unsigned char volatile ToHyNoDpramErrLog;
 	/* note: ToHyNoDpramErrLog is used to inform
 	 *       boot loader, not to use DPRAM based
 	 *       ErrLog; when DOS driver is rewritten
 	 *       this becomes obsolete
 	 */
-/*1FFD */ unsigned char bRes1FFD;
+	/*1FFD */ unsigned char bRes1FFD;
 	/*1FFE */ unsigned char ToPcInt;
 	/* E1_intclear; on CHAMP2: E1_intset   */
 	/*1FFF */ unsigned char ToHyInt;
@@ -85,16 +85,16 @@ typedef struct ErgDpram_tag {
 #define PCI9050_INTR_REG    0x4C	/* Interrupt register */
 #define PCI9050_USER_IO     0x51	/* User I/O  register */
 
-				    /* bitmask for PCI9050_INTR_REG: */
+/* bitmask for PCI9050_INTR_REG: */
 #define PCI9050_INTR_REG_EN1    0x01	/* 1= enable (def.), 0= disable */
 #define PCI9050_INTR_REG_POL1   0x02	/* 1= active high (def.), 0= active low */
 #define PCI9050_INTR_REG_STAT1  0x04	/* 1= intr. active, 0= intr. not active (def.) */
 #define PCI9050_INTR_REG_ENPCI  0x40	/* 1= PCI interrupts enable (def.) */
 
-				    /* bitmask for PCI9050_USER_IO: */
+/* bitmask for PCI9050_USER_IO: */
 #define PCI9050_USER_IO_EN3     0x02	/* 1= disable      , 0= enable (def.) */
 #define PCI9050_USER_IO_DIR3    0x04	/* 1= output (def.), 0= input         */
 #define PCI9050_USER_IO_DAT3    0x08	/* 1= high (def.)  , 0= low           */
 
-#define PCI9050_E1_RESET    (                     PCI9050_USER_IO_DIR3)		/* 0x04 */
-#define PCI9050_E1_RUN      (PCI9050_USER_IO_DAT3|PCI9050_USER_IO_DIR3)		/* 0x0C */
+#define PCI9050_E1_RESET    (PCI9050_USER_IO_DIR3)		/* 0x04 */
+#define PCI9050_E1_RUN      (PCI9050_USER_IO_DAT3 | PCI9050_USER_IO_DIR3)		/* 0x0C */
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 6299b06..931f916 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -31,9 +31,9 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.8.6.4 $";
+static char hycapi_revision[] = "$Revision: 1.8.6.4 $";
 
-unsigned int hycapi_enable = 0xffffffff; 
+unsigned int hycapi_enable = 0xffffffff;
 module_param(hycapi_enable, uint, 0);
 
 typedef struct _hycapi_appl {
@@ -48,18 +48,18 @@ static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
 
 static inline int _hycapi_appCheck(int app_id, int ctrl_no)
 {
-	if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
+	if ((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
 	   (app_id > CAPI_MAXAPPL))
 	{
 		printk(KERN_ERR "HYCAPI: Invalid request app_id %d for controller %d", app_id, ctrl_no);
 		return -1;
 	}
-	return ((hycapi_applications[app_id-1].ctrl_mask & (1 << (ctrl_no-1))) != 0);
+	return ((hycapi_applications[app_id - 1].ctrl_mask & (1 << (ctrl_no-1))) != 0);
 }
 
 /******************************
 Kernel-Capi callback reset_ctr
-******************************/     
+******************************/
 
 static void
 hycapi_reset_ctr(struct capi_ctr *ctrl)
@@ -75,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
 
 /******************************
 Kernel-Capi callback remove_ctr
-******************************/     
+******************************/
 
 static void
 hycapi_remove_ctr(struct capi_ctr *ctrl)
@@ -85,25 +85,25 @@ hycapi_remove_ctr(struct capi_ctr *ctrl)
 	hysdn_card *card = NULL;
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_NOTICE "HYCAPI hycapi_remove_ctr\n");
-#endif 
+#endif
 	cinfo = (hycapictrl_info *)(ctrl->driverdata);
-	if(!cinfo) {
+	if (!cinfo) {
 		printk(KERN_ERR "No hycapictrl_info set!");
 		return;
-	}    
+	}
 	card = cinfo->card;
 	capi_ctr_suspend_output(ctrl);
-	for(i=0; i<CAPI_MAXAPPL;i++) {
-		if(hycapi_applications[i].listen_req[ctrl->cnr-1]) {
-			kfree_skb(hycapi_applications[i].listen_req[ctrl->cnr-1]);
-			hycapi_applications[i].listen_req[ctrl->cnr-1] = NULL;
+	for (i = 0; i < CAPI_MAXAPPL; i++) {
+		if (hycapi_applications[i].listen_req[ctrl->cnr - 1]) {
+			kfree_skb(hycapi_applications[i].listen_req[ctrl->cnr - 1]);
+			hycapi_applications[i].listen_req[ctrl->cnr - 1] = NULL;
 		}
 	}
 	detach_capi_ctr(ctrl);
 	ctrl->driverdata = NULL;
 	kfree(card->hyctrlinfo);
 
-		
+
 	card->hyctrlinfo = NULL;
 }
 
@@ -121,7 +121,7 @@ hycapi_sendmsg_internal(struct capi_ctr *ctrl, struct sk_buff *skb)
 
 	spin_lock_irq(&cinfo->lock);
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_send_message\n");    
+	printk(KERN_NOTICE "hycapi_send_message\n");
 #endif
 	cinfo->skbs[cinfo->in_idx++] = skb;	/* add to buffer list */
 	if (cinfo->in_idx >= HYSDN_MAX_CAPI_SKB)
@@ -130,7 +130,7 @@ hycapi_sendmsg_internal(struct capi_ctr *ctrl, struct sk_buff *skb)
 	if (cinfo->sk_count >= HYSDN_MAX_CAPI_SKB) {
 		/* inform upper layers we're full */
 		printk(KERN_ERR "HYSDN Card%d: CAPI-buffer overrun!\n",
-		       card->myid);	
+		       card->myid);
 		capi_ctr_suspend_output(ctrl);
 	}
 	cinfo->tx_skb = skb;
@@ -147,7 +147,7 @@ re-register any applications in the private list.
 
 ************************************************************/
 
-static void 
+static void
 hycapi_register_internal(struct capi_ctr *ctrl, __u16 appl,
 			 capi_register_params *rp)
 {
@@ -161,9 +161,9 @@ hycapi_register_internal(struct capi_ctr *ctrl, __u16 appl,
 	__u16 MessageBufferSize = 0;
 	int slen = strlen(ExtFeatureDefaults);
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_register_appl\n"); 
+	printk(KERN_NOTICE "hycapi_register_appl\n");
 #endif
-	MessageBufferSize = rp->level3cnt * rp->datablkcnt * rp->datablklen; 
+	MessageBufferSize = rp->level3cnt * rp->datablkcnt * rp->datablklen;
 
 	len = CAPI_MSG_BASELEN + 8 + slen + 1;
 	if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
@@ -171,18 +171,18 @@ hycapi_register_internal(struct capi_ctr *ctrl, __u16 appl,
 		       card->myid);
 		return;
 	}
-	memcpy(skb_put(skb,sizeof(__u16)), &len, sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u16)), &appl, sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u8)), &_command, sizeof(_command));
-	memcpy(skb_put(skb,sizeof(__u8)), &_subcommand, sizeof(_subcommand));
-	memcpy(skb_put(skb,sizeof(__u16)), &MessageNumber, sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u16)), &MessageBufferSize, sizeof(__u16)); 
-	memcpy(skb_put(skb,sizeof(__u16)), &(rp->level3cnt), sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u16)), &(rp->datablkcnt), sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u16)), &(rp->datablklen), sizeof(__u16));
-	memcpy(skb_put(skb,slen), ExtFeatureDefaults, slen);
-	hycapi_applications[appl-1].ctrl_mask |= (1 << (ctrl->cnr-1));    
-	hycapi_send_message(ctrl, skb);    
+	memcpy(skb_put(skb, sizeof(__u16)), &len, sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u16)), &appl, sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u8)), &_command, sizeof(_command));
+	memcpy(skb_put(skb, sizeof(__u8)), &_subcommand, sizeof(_subcommand));
+	memcpy(skb_put(skb, sizeof(__u16)), &MessageNumber, sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u16)), &MessageBufferSize, sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u16)), &(rp->level3cnt), sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u16)), &(rp->datablkcnt), sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u16)), &(rp->datablklen), sizeof(__u16));
+	memcpy(skb_put(skb, slen), ExtFeatureDefaults, slen);
+	hycapi_applications[appl - 1].ctrl_mask |= (1 << (ctrl->cnr - 1));
+	hycapi_send_message(ctrl, skb);
 }
 
 /************************************************************
@@ -200,12 +200,12 @@ static void hycapi_restart_internal(struct capi_ctr *ctrl)
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_WARNING "HYSDN: hycapi_restart_internal");
 #endif
-	for(i=0; i<CAPI_MAXAPPL; i++) {
-		if(_hycapi_appCheck(i+1, ctrl->cnr) == 1) {
-			hycapi_register_internal(ctrl, i+1, 
+	for (i = 0; i < CAPI_MAXAPPL; i++) {
+		if (_hycapi_appCheck(i + 1, ctrl->cnr) == 1) {
+			hycapi_register_internal(ctrl, i + 1,
 						 &hycapi_applications[i].rp);
-			if(hycapi_applications[i].listen_req[ctrl->cnr-1]) {
-				skb = skb_copy(hycapi_applications[i].listen_req[ctrl->cnr-1], GFP_ATOMIC);
+			if (hycapi_applications[i].listen_req[ctrl->cnr - 1]) {
+				skb = skb_copy(hycapi_applications[i].listen_req[ctrl->cnr - 1], GFP_ATOMIC);
 				hycapi_sendmsg_internal(ctrl, skb);
 			}
 		}
@@ -220,35 +220,35 @@ The application is recorded in the internal list.
 *************************************************************/
 
 static void
-hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, 
+hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl,
 		     capi_register_params *rp)
 {
 	int MaxLogicalConnections = 0, MaxBDataBlocks = 0, MaxBDataLen = 0;
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 	hysdn_card *card = cinfo->card;
 	int chk = _hycapi_appCheck(appl, ctrl->cnr);
-	if(chk < 0) {
+	if (chk < 0) {
 		return;
 	}
-	if(chk == 1) {
+	if (chk == 1) {
 		printk(KERN_INFO "HYSDN: apl %d already registered\n", appl);
 		return;
 	}
 	MaxBDataBlocks = rp->datablkcnt > CAPI_MAXDATAWINDOW ? CAPI_MAXDATAWINDOW : rp->datablkcnt;
 	rp->datablkcnt = MaxBDataBlocks;
-	MaxBDataLen = rp->datablklen < 1024 ? 1024 : rp->datablklen ;
+	MaxBDataLen = rp->datablklen < 1024 ? 1024 : rp->datablklen;
 	rp->datablklen = MaxBDataLen;
-	
+
 	MaxLogicalConnections = rp->level3cnt;
 	if (MaxLogicalConnections < 0) {
-		MaxLogicalConnections = card->bchans * -MaxLogicalConnections; 
+		MaxLogicalConnections = card->bchans * -MaxLogicalConnections;
 	}
 	if (MaxLogicalConnections == 0) {
 		MaxLogicalConnections = card->bchans;
 	}
-	
+
 	rp->level3cnt = MaxLogicalConnections;
-	memcpy(&hycapi_applications[appl-1].rp, 
+	memcpy(&hycapi_applications[appl - 1].rp,
 	       rp, sizeof(capi_register_params));
 }
 
@@ -279,19 +279,19 @@ static void hycapi_release_internal(struct capi_ctr *ctrl, __u16 appl)
 		       card->myid);
 		return;
 	}
-	memcpy(skb_put(skb,sizeof(__u16)), &len, sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u16)), &appl, sizeof(__u16));
-	memcpy(skb_put(skb,sizeof(__u8)), &_command, sizeof(_command));
-	memcpy(skb_put(skb,sizeof(__u8)), &_subcommand, sizeof(_subcommand));
-	memcpy(skb_put(skb,sizeof(__u16)), &MessageNumber, sizeof(__u16));    
-	hycapi_send_message(ctrl, skb);    
-	hycapi_applications[appl-1].ctrl_mask &= ~(1 << (ctrl->cnr-1));    
+	memcpy(skb_put(skb, sizeof(__u16)), &len, sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u16)), &appl, sizeof(__u16));
+	memcpy(skb_put(skb, sizeof(__u8)), &_command, sizeof(_command));
+	memcpy(skb_put(skb, sizeof(__u8)), &_subcommand, sizeof(_subcommand));
+	memcpy(skb_put(skb, sizeof(__u16)), &MessageNumber, sizeof(__u16));
+	hycapi_send_message(ctrl, skb);
+	hycapi_applications[appl - 1].ctrl_mask &= ~(1 << (ctrl->cnr - 1));
 }
 
 /******************************************************************
 hycapi_release_appl
 
-Release the application from the internal list an remove it's 
+Release the application from the internal list an remove it's
 registration at controller-level
 ******************************************************************/
 
@@ -301,15 +301,15 @@ hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
 	int chk;
 
 	chk = _hycapi_appCheck(appl, ctrl->cnr);
-	if(chk<0) {
+	if (chk < 0) {
 		printk(KERN_ERR "HYCAPI: Releasing invalid appl %d on controller %d\n", appl, ctrl->cnr);
 		return;
 	}
-	if(hycapi_applications[appl-1].listen_req[ctrl->cnr-1]) {
-		kfree_skb(hycapi_applications[appl-1].listen_req[ctrl->cnr-1]);
-		hycapi_applications[appl-1].listen_req[ctrl->cnr-1] = NULL;
+	if (hycapi_applications[appl - 1].listen_req[ctrl->cnr - 1]) {
+		kfree_skb(hycapi_applications[appl - 1].listen_req[ctrl->cnr - 1]);
+		hycapi_applications[appl - 1].listen_req[ctrl->cnr - 1] = NULL;
 	}
-	if(chk == 1)
+	if (chk == 1)
 	{
 		hycapi_release_internal(ctrl, appl);
 	}
@@ -327,7 +327,7 @@ int hycapi_capi_release(hysdn_card *card)
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_NOTICE "hycapi_capi_release\n");
 #endif
-	if(cinfo) {
+	if (cinfo) {
 		ctrl = &cinfo->capi_ctrl;
 		hycapi_remove_ctr(ctrl);
 	}
@@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card)
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_NOTICE "hycapi_capi_stop\n");
 #endif
-	if(cinfo) {
+	if (cinfo) {
 		ctrl = &cinfo->capi_ctrl;
 /*		ctrl->suspend_output(ctrl); */
 		capi_ctr_down(ctrl);
@@ -377,59 +377,59 @@ static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
 	u16 retval = CAPI_NOERROR;
 
 	appl_id = CAPIMSG_APPID(skb->data);
-	switch(_hycapi_appCheck(appl_id, ctrl->cnr))
+	switch (_hycapi_appCheck(appl_id, ctrl->cnr))
 	{
-		case 0:
+	case 0:
 /*			printk(KERN_INFO "Need to register\n"); */
-			hycapi_register_internal(ctrl, 
-						 appl_id,
-						 &(hycapi_applications[appl_id-1].rp));
-			break;
-		case 1:
-			break;
-		default:
-			printk(KERN_ERR "HYCAPI: Controller mixup!\n");
-			retval = CAPI_ILLAPPNR;
-			goto out;
+		hycapi_register_internal(ctrl,
+					 appl_id,
+					 &(hycapi_applications[appl_id - 1].rp));
+		break;
+	case 1:
+		break;
+	default:
+		printk(KERN_ERR "HYCAPI: Controller mixup!\n");
+		retval = CAPI_ILLAPPNR;
+		goto out;
 	}
-	switch(CAPIMSG_CMD(skb->data)) {		
-		case CAPI_DISCONNECT_B3_RESP:
-			capilib_free_ncci(&cinfo->ncci_head, appl_id, 
-					  CAPIMSG_NCCI(skb->data));
-			break;
-		case CAPI_DATA_B3_REQ:
-			_len = CAPIMSG_LEN(skb->data);
-			if (_len > 22) {
-				_len2 = _len - 22;
-				skb_copy_from_linear_data(skb, msghead, 22);
-				skb_copy_to_linear_data_offset(skb, _len2,
-							       msghead, 22);
-				skb_pull(skb, _len2);
-				CAPIMSG_SETLEN(skb->data, 22);
-				retval = capilib_data_b3_req(&cinfo->ncci_head,
-							     CAPIMSG_APPID(skb->data),
-							     CAPIMSG_NCCI(skb->data),
-							     CAPIMSG_MSGID(skb->data));
-			}
-			break;
-		case CAPI_LISTEN_REQ:
-			if(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1])
-			{
-				kfree_skb(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1]);
-				hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = NULL;
-			}
-			if (!(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = skb_copy(skb, GFP_ATOMIC))) 
-			{
-				printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n");
-			} 
-			break;
-		default:
-			break;
+	switch (CAPIMSG_CMD(skb->data)) {
+	case CAPI_DISCONNECT_B3_RESP:
+		capilib_free_ncci(&cinfo->ncci_head, appl_id,
+				  CAPIMSG_NCCI(skb->data));
+		break;
+	case CAPI_DATA_B3_REQ:
+		_len = CAPIMSG_LEN(skb->data);
+		if (_len > 22) {
+			_len2 = _len - 22;
+			skb_copy_from_linear_data(skb, msghead, 22);
+			skb_copy_to_linear_data_offset(skb, _len2,
+						       msghead, 22);
+			skb_pull(skb, _len2);
+			CAPIMSG_SETLEN(skb->data, 22);
+			retval = capilib_data_b3_req(&cinfo->ncci_head,
+						     CAPIMSG_APPID(skb->data),
+						     CAPIMSG_NCCI(skb->data),
+						     CAPIMSG_MSGID(skb->data));
+		}
+		break;
+	case CAPI_LISTEN_REQ:
+		if (hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1])
+		{
+			kfree_skb(hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1]);
+			hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1] = NULL;
+		}
+		if (!(hycapi_applications[appl_id  -1].listen_req[ctrl->cnr - 1] = skb_copy(skb, GFP_ATOMIC)))
+		{
+			printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n");
+		}
+		break;
+	default:
+		break;
 	}
- out:
+out:
 	if (retval == CAPI_NOERROR)
 		hycapi_sendmsg_internal(ctrl, skb);
-	else 
+	else
 		dev_kfree_skb_any(skb);
 
 	return retval;
@@ -445,14 +445,14 @@ static int hycapi_proc_show(struct seq_file *m, void *v)
 	seq_printf(m, "%-16s %s\n", "name", cinfo->cardname);
 	seq_printf(m, "%-16s 0x%x\n", "io", card->iobase);
 	seq_printf(m, "%-16s %d\n", "irq", card->irq);
-    
+
 	switch (card->brdtype) {
-		case BD_PCCARD:  s = "HYSDN Hycard"; break;
-		case BD_ERGO: s = "HYSDN Ergo2"; break;
-		case BD_METRO: s = "HYSDN Metro4"; break;
-		case BD_CHAMP2: s = "HYSDN Champ2";	break;
-		case BD_PLEXUS: s = "HYSDN Plexus30"; break;
-		default: s = "???"; break;
+	case BD_PCCARD:  s = "HYSDN Hycard"; break;
+	case BD_ERGO: s = "HYSDN Ergo2"; break;
+	case BD_METRO: s = "HYSDN Metro4"; break;
+	case BD_CHAMP2: s = "HYSDN Champ2";	break;
+	case BD_PLEXUS: s = "HYSDN Plexus30"; break;
+	default: s = "???"; break;
 	}
 	seq_printf(m, "%-16s %s\n", "type", s);
 	if ((s = cinfo->version[VER_DRIVER]) != NULL)
@@ -461,9 +461,9 @@ static int hycapi_proc_show(struct seq_file *m, void *v)
 		seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
 	if ((s = cinfo->version[VER_SERIAL]) != NULL)
 		seq_printf(m, "%-16s %s\n", "ver_serial", s);
-    
+
 	seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
-    
+
 	return 0;
 }
 
@@ -491,7 +491,7 @@ on capi-interface registration.
 static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 {
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_load_firmware\n");    
+	printk(KERN_NOTICE "hycapi_load_firmware\n");
 #endif
 	return 0;
 }
@@ -501,7 +501,7 @@ static char *hycapi_procinfo(struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_proc_info\n");    
+	printk(KERN_NOTICE "hycapi_proc_info\n");
 #endif
 	if (!cinfo)
 		return "";
@@ -525,7 +525,7 @@ New nccis are created if necessary.
 *******************************************************************/
 
 void
-hycapi_rx_capipkt(hysdn_card * card, unsigned char *buf, unsigned short len)
+hycapi_rx_capipkt(hysdn_card *card, unsigned char *buf, unsigned short len)
 {
 	struct sk_buff *skb;
 	hycapictrl_info *cinfo = card->hyctrlinfo;
@@ -533,24 +533,24 @@ hycapi_rx_capipkt(hysdn_card * card, unsigned char *buf, unsigned short len)
 	__u16 ApplId;
 	__u16 MsgLen, info;
 	__u16 len2, CapiCmd;
-	__u32 CP64[2] = {0,0};
+	__u32 CP64[2] = {0, 0};
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_rx_capipkt\n");    
+	printk(KERN_NOTICE "hycapi_rx_capipkt\n");
 #endif
-	if(!cinfo) {
+	if (!cinfo) {
 		return;
 	}
 	ctrl = &cinfo->capi_ctrl;
-	if(len < CAPI_MSG_BASELEN) {
+	if (len < CAPI_MSG_BASELEN) {
 		printk(KERN_ERR "HYSDN Card%d: invalid CAPI-message, length %d!\n",
 		       card->myid, len);
 		return;
-	}	
+	}
 	MsgLen = CAPIMSG_LEN(buf);
 	ApplId = CAPIMSG_APPID(buf);
 	CapiCmd = CAPIMSG_CMD(buf);
-	
-	if((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) {
+
+	if ((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) {
 		len2 = len + (30 - MsgLen);
 		if (!(skb = alloc_skb(len2, GFP_ATOMIC))) {
 			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
@@ -558,7 +558,7 @@ hycapi_rx_capipkt(hysdn_card * card, unsigned char *buf, unsigned short len)
 			return;
 		}
 		memcpy(skb_put(skb, MsgLen), buf, MsgLen);
-		memcpy(skb_put(skb, 2*sizeof(__u32)), CP64, 2* sizeof(__u32));
+		memcpy(skb_put(skb, 2 * sizeof(__u32)), CP64, 2 * sizeof(__u32));
 		memcpy(skb_put(skb, len - MsgLen), buf + MsgLen,
 		       len - MsgLen);
 		CAPIMSG_SETLEN(skb->data, 30);
@@ -570,54 +570,54 @@ hycapi_rx_capipkt(hysdn_card * card, unsigned char *buf, unsigned short len)
 		}
 		memcpy(skb_put(skb, len), buf, len);
 	}
-	switch(CAPIMSG_CMD(skb->data)) 
+	switch (CAPIMSG_CMD(skb->data))
 	{
-		case CAPI_CONNECT_B3_CONF:
+	case CAPI_CONNECT_B3_CONF:
 /* Check info-field for error-indication: */
-			info = CAPIMSG_U16(skb->data, 12);
-			switch(info)
-			{
-				case 0:
-					capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), 
-							 hycapi_applications[ApplId-1].rp.datablkcnt); 
-					
-					break;
-				case 0x0001:
-					printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current "
-					       "protocol. NCPI ignored.\n", card->myid);
-					break;
-				case 0x2001:
-					printk(KERN_ERR "HYSDN Card%d: Message not supported in"
-					       " current state\n", card->myid);
-					break;
-				case 0x2002:
-					printk(KERN_ERR "HYSDN Card%d: invalid PLCI\n", card->myid);
-					break;		
-				case 0x2004:
-					printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid);
-					break;				
-				case 0x3008:
-					printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n", 
-					       card->myid);
-					break;	
-				default:
-					printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n", 
-					       card->myid, info);
-					break;			
-			}
+		info = CAPIMSG_U16(skb->data, 12);
+		switch (info)
+		{
+		case 0:
+			capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data),
+					 hycapi_applications[ApplId - 1].rp.datablkcnt);
+
+			break;
+		case 0x0001:
+			printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current "
+			       "protocol. NCPI ignored.\n", card->myid);
 			break;
-		case CAPI_CONNECT_B3_IND:
-			capilib_new_ncci(&cinfo->ncci_head, ApplId, 
-					 CAPIMSG_NCCI(skb->data), 
-					 hycapi_applications[ApplId-1].rp.datablkcnt);
+		case 0x2001:
+			printk(KERN_ERR "HYSDN Card%d: Message not supported in"
+			       " current state\n", card->myid);
 			break;
-	        case CAPI_DATA_B3_CONF:
-			capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
-					     CAPIMSG_NCCI(skb->data),
-					     CAPIMSG_MSGID(skb->data));
+		case 0x2002:
+			printk(KERN_ERR "HYSDN Card%d: invalid PLCI\n", card->myid);
+			break;
+		case 0x2004:
+			printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid);
+			break;
+		case 0x3008:
+			printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n",
+			       card->myid);
 			break;
 		default:
+			printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n",
+			       card->myid, info);
 			break;
+		}
+		break;
+	case CAPI_CONNECT_B3_IND:
+		capilib_new_ncci(&cinfo->ncci_head, ApplId,
+				 CAPIMSG_NCCI(skb->data),
+				 hycapi_applications[ApplId - 1].rp.datablkcnt);
+		break;
+	case CAPI_DATA_B3_CONF:
+		capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
+				     CAPIMSG_NCCI(skb->data),
+				     CAPIMSG_MSGID(skb->data));
+		break;
+	default:
+		break;
 	}
 	capi_ctr_handle_message(ctrl, ApplId, skb);
 }
@@ -630,13 +630,13 @@ internal queue.
 
 *******************************************************************/
 
-void hycapi_tx_capiack(hysdn_card * card)
+void hycapi_tx_capiack(hysdn_card *card)
 {
 	hycapictrl_info *cinfo = card->hyctrlinfo;
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_tx_capiack\n");    
+	printk(KERN_NOTICE "hycapi_tx_capiack\n");
 #endif
-	if(!cinfo) {
+	if (!cinfo) {
 		return;
 	}
 	spin_lock_irq(&cinfo->lock);
@@ -661,7 +661,7 @@ struct sk_buff *
 hycapi_tx_capiget(hysdn_card *card)
 {
 	hycapictrl_info *cinfo = card->hyctrlinfo;
-	if(!cinfo) {
+	if (!cinfo) {
 		return (struct sk_buff *)NULL;
 	}
 	if (!cinfo->sk_count)
@@ -681,10 +681,10 @@ attach the capi-driver to the kernel-capi.
 int hycapi_init(void)
 {
 	int i;
-	for(i=0;i<CAPI_MAXAPPL;i++) {
+	for (i = 0; i < CAPI_MAXAPPL; i++) {
 		memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl));
 	}
-	return(0);
+	return (0);
 }
 
 /**************************************************************
@@ -694,7 +694,7 @@ detach the capi-driver to the kernel-capi. Actually this should
 free some more ressources. Do that later.
 **************************************************************/
 
-void 
+void
 hycapi_cleanup(void)
 {
 }
@@ -710,9 +710,9 @@ static void hycapi_fill_profile(hysdn_card *card)
 	hycapictrl_info *cinfo = NULL;
 	struct capi_ctr *ctrl = NULL;
 	cinfo = card->hyctrlinfo;
-	if(!cinfo) return;
+	if (!cinfo) return;
 	ctrl = &cinfo->capi_ctrl;
-	strcpy(ctrl->manu, "Hypercope");	
+	strcpy(ctrl->manu, "Hypercope");
 	ctrl->version.majorversion = 2;
 	ctrl->version.minorversion = 0;
 	ctrl->version.majormanuversion = 3;
@@ -732,18 +732,18 @@ static void hycapi_fill_profile(hysdn_card *card)
 		(card->faxchans ? B3_PROT_T30 : 0) |
 		(card->faxchans ? B3_PROT_T30EXT : 0) |
 		B3_PROT_ISO8208;
-}	
+}
 
-int 
+int
 hycapi_capi_create(hysdn_card *card)
 {
 	hycapictrl_info *cinfo = NULL;
 	struct capi_ctr *ctrl = NULL;
 	int retval;
 #ifdef HYCAPI_PRINTFNAMES
-	printk(KERN_NOTICE "hycapi_capi_create\n");        
+	printk(KERN_NOTICE "hycapi_capi_create\n");
 #endif
-	if((hycapi_enable & (1 << card->myid)) == 0) {
+	if ((hycapi_enable & (1 << card->myid)) == 0) {
 		return 1;
 	}
 	if (!card->hyctrlinfo) {
@@ -758,12 +758,12 @@ hycapi_capi_create(hysdn_card *card)
 		INIT_LIST_HEAD(&cinfo->ncci_head);
 
 		switch (card->brdtype) {
-			case BD_PCCARD:  strcpy(cinfo->cardname,"HYSDN Hycard"); break;
-			case BD_ERGO: strcpy(cinfo->cardname,"HYSDN Ergo2"); break;
-			case BD_METRO: strcpy(cinfo->cardname,"HYSDN Metro4"); break;
-			case BD_CHAMP2: strcpy(cinfo->cardname,"HYSDN Champ2"); break;
-			case BD_PLEXUS: strcpy(cinfo->cardname,"HYSDN Plexus30"); break;
-			default: strcpy(cinfo->cardname,"HYSDN ???"); break;
+		case BD_PCCARD:  strcpy(cinfo->cardname, "HYSDN Hycard"); break;
+		case BD_ERGO: strcpy(cinfo->cardname, "HYSDN Ergo2"); break;
+		case BD_METRO: strcpy(cinfo->cardname, "HYSDN Metro4"); break;
+		case BD_CHAMP2: strcpy(cinfo->cardname, "HYSDN Champ2"); break;
+		case BD_PLEXUS: strcpy(cinfo->cardname, "HYSDN Plexus30"); break;
+		default: strcpy(cinfo->cardname, "HYSDN ???"); break;
 		}
 
 		ctrl = &cinfo->capi_ctrl;
@@ -792,7 +792,7 @@ hycapi_capi_create(hysdn_card *card)
 		ctrl = &card->hyctrlinfo->capi_ctrl;
 		hycapi_fill_profile(card);
 		capi_ctr_ready(ctrl);
-		hycapi_restart_internal(ctrl); 
+		hycapi_restart_internal(ctrl);
 /*		ctrl->resume_output(ctrl); */
 	}
 	return 0;
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
index 4f541ef..eda4741 100644
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -82,7 +82,7 @@ DecryptBuf(struct boot_data *boot, int cnt)
 /* id. If successful 0 is returned, a negative value shows an error.           */
 /********************************************************************************/
 static int
-pof_handle_data(hysdn_card * card, int datlen)
+pof_handle_data(hysdn_card *card, int datlen)
 {
 	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
 	long l;
@@ -92,71 +92,71 @@ pof_handle_data(hysdn_card * card, int datlen)
 	/* handle the different record types */
 	switch (boot->pof_recid) {
 
-		case TAG_TIMESTMP:
-			if (card->debug_flags & LOG_POF_RECORD)
-				hysdn_addlog(card, "POF created %s", boot->buf.PofTime.DateTimeText);
-			break;
+	case TAG_TIMESTMP:
+		if (card->debug_flags & LOG_POF_RECORD)
+			hysdn_addlog(card, "POF created %s", boot->buf.PofTime.DateTimeText);
+		break;
+
+	case TAG_CBOOTDTA:
+		DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
+	case TAG_BOOTDTA:
+		if (card->debug_flags & LOG_POF_RECORD)
+			hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
+				     (boot->pof_recid == TAG_CBOOTDTA) ? "CBOOTDATA" : "BOOTDTA",
+				     datlen, boot->pof_recoffset);
+
+		if (boot->pof_reclen != POF_BOOT_LOADER_TOTAL_SIZE) {
+			boot->last_error = EPOF_BAD_IMG_SIZE;	/* invalid length */
+			return (boot->last_error);
+		}
+		imgp = boot->buf.BootBuf;	/* start of buffer */
+		img_len = datlen;	/* maximum length to transfer */
+
+		l = POF_BOOT_LOADER_OFF_IN_PAGE -
+			(boot->pof_recoffset & (POF_BOOT_LOADER_PAGE_SIZE - 1));
+		if (l > 0) {
+			/* buffer needs to be truncated */
+			imgp += l;	/* advance pointer */
+			img_len -= l;	/* adjust len */
+		}
+		/* at this point no special handling for data wrapping over buffer */
+		/* is necessary, because the boot image always will be adjusted to */
+		/* match a page boundary inside the buffer.                        */
+		/* The buffer for the boot image on the card is filled in 2 cycles */
+		/* first the 1024 hi-words are put in the buffer, then the low 1024 */
+		/* word are handled in the same way with different offset.         */
+
+		if (img_len > 0) {
+			/* data available for copy */
+			if ((boot->last_error =
+			     card->writebootimg(card, imgp,
+						(boot->pof_recoffset > POF_BOOT_LOADER_PAGE_SIZE) ? 2 : 0)) < 0)
+				return (boot->last_error);
+		}
+		break;	/* end of case boot image hi/lo */
 
-		case TAG_CBOOTDTA:
-			DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
-		case TAG_BOOTDTA:
-			if (card->debug_flags & LOG_POF_RECORD)
-				hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
-					     (boot->pof_recid == TAG_CBOOTDTA) ? "CBOOTDATA" : "BOOTDTA",
-					     datlen, boot->pof_recoffset);
+	case TAG_CABSDATA:
+		DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
+	case TAG_ABSDATA:
+		if (card->debug_flags & LOG_POF_RECORD)
+			hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
+				     (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
+				     datlen, boot->pof_recoffset);
 
-			if (boot->pof_reclen != POF_BOOT_LOADER_TOTAL_SIZE) {
-				boot->last_error = EPOF_BAD_IMG_SIZE;	/* invalid length */
-				return (boot->last_error);
-			}
-			imgp = boot->buf.BootBuf;	/* start of buffer */
-			img_len = datlen;	/* maximum length to transfer */
-
-			l = POF_BOOT_LOADER_OFF_IN_PAGE -
-			    (boot->pof_recoffset & (POF_BOOT_LOADER_PAGE_SIZE - 1));
-			if (l > 0) {
-				/* buffer needs to be truncated */
-				imgp += l;	/* advance pointer */
-				img_len -= l;	/* adjust len */
-			}
-			/* at this point no special handling for data wrapping over buffer */
-			/* is necessary, because the boot image always will be adjusted to */
-			/* match a page boundary inside the buffer.                        */
-			/* The buffer for the boot image on the card is filled in 2 cycles */
-			/* first the 1024 hi-words are put in the buffer, then the low 1024 */
-			/* word are handled in the same way with different offset.         */
-
-			if (img_len > 0) {
-				/* data available for copy */
-				if ((boot->last_error =
-				     card->writebootimg(card, imgp,
-							(boot->pof_recoffset > POF_BOOT_LOADER_PAGE_SIZE) ? 2 : 0)) < 0)
-					return (boot->last_error);
-			}
-			break;	/* end of case boot image hi/lo */
-
-		case TAG_CABSDATA:
-			DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
-		case TAG_ABSDATA:
-			if (card->debug_flags & LOG_POF_RECORD)
-				hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
-					     (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
-					     datlen, boot->pof_recoffset);
-
-			if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
-				return (boot->last_error);	/* error writing data */
-
-			if (boot->pof_recoffset + datlen >= boot->pof_reclen)
-				return (card->waitpofready(card));	/* data completely spooled, wait for ready */
-
-			break;	/* end of case boot seq data */
+		if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
+			return (boot->last_error);	/* error writing data */
 
-		default:
-			if (card->debug_flags & LOG_POF_RECORD)
-				hysdn_addlog(card, "POF got data(id=0x%lx) len=%d offs=0x%lx", boot->pof_recid,
-					     datlen, boot->pof_recoffset);
+		if (boot->pof_recoffset + datlen >= boot->pof_reclen)
+			return (card->waitpofready(card));	/* data completely spooled, wait for ready */
+
+		break;	/* end of case boot seq data */
+
+	default:
+		if (card->debug_flags & LOG_POF_RECORD)
+			hysdn_addlog(card, "POF got data(id=0x%lx) len=%d offs=0x%lx", boot->pof_recid,
+				     datlen, boot->pof_recoffset);
 
-			break;	/* simply skip record */
+		break;	/* simply skip record */
 	}			/* switch boot->pof_recid */
 
 	return (0);
@@ -171,7 +171,7 @@ pof_handle_data(hysdn_card * card, int datlen)
 /* occurred and booting must be aborted.                                       */
 /******************************************************************************/
 int
-pof_write_buffer(hysdn_card * card, int datlen)
+pof_write_buffer(hysdn_card *card, int datlen)
 {
 	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
 
@@ -184,77 +184,77 @@ pof_write_buffer(hysdn_card * card, int datlen)
 		hysdn_addlog(card, "POF write: got %d bytes ", datlen);
 
 	switch (boot->pof_state) {
-		case POF_READ_FILE_HEAD:
-			if (card->debug_flags & LOG_POF_WRITE)
-				hysdn_addlog(card, "POF write: checking file header");
-
-			if (datlen != sizeof(tPofFileHdr)) {
-				boot->last_error = -EPOF_INTERNAL;
-				break;
-			}
-			if (boot->buf.PofFileHdr.Magic != TAGFILEMAGIC) {
-				boot->last_error = -EPOF_BAD_MAGIC;
-				break;
-			}
-			/* Setup the new state and vars */
-			boot->Nrecs = (unsigned short)(boot->buf.PofFileHdr.N_PofRecs);	/* limited to 65535 */
-			boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
-			boot->last_error = sizeof(tPofRecHdr);	/* new length */
+	case POF_READ_FILE_HEAD:
+		if (card->debug_flags & LOG_POF_WRITE)
+			hysdn_addlog(card, "POF write: checking file header");
+
+		if (datlen != sizeof(tPofFileHdr)) {
+			boot->last_error = -EPOF_INTERNAL;
+			break;
+		}
+		if (boot->buf.PofFileHdr.Magic != TAGFILEMAGIC) {
+			boot->last_error = -EPOF_BAD_MAGIC;
+			break;
+		}
+		/* Setup the new state and vars */
+		boot->Nrecs = (unsigned short)(boot->buf.PofFileHdr.N_PofRecs);	/* limited to 65535 */
+		boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
+		boot->last_error = sizeof(tPofRecHdr);	/* new length */
+		break;
+
+	case POF_READ_TAG_HEAD:
+		if (card->debug_flags & LOG_POF_WRITE)
+			hysdn_addlog(card, "POF write: checking tag header");
+
+		if (datlen != sizeof(tPofRecHdr)) {
+			boot->last_error = -EPOF_INTERNAL;
 			break;
+		}
+		boot->pof_recid = boot->buf.PofRecHdr.PofRecId;		/* actual pof recid */
+		boot->pof_reclen = boot->buf.PofRecHdr.PofRecDataLen;	/* total length */
+		boot->pof_recoffset = 0;	/* no starting offset */
 
-		case POF_READ_TAG_HEAD:
-			if (card->debug_flags & LOG_POF_WRITE)
-				hysdn_addlog(card, "POF write: checking tag header");
-
-			if (datlen != sizeof(tPofRecHdr)) {
-				boot->last_error = -EPOF_INTERNAL;
-				break;
-			}
-			boot->pof_recid = boot->buf.PofRecHdr.PofRecId;		/* actual pof recid */
-			boot->pof_reclen = boot->buf.PofRecHdr.PofRecDataLen;	/* total length */
-			boot->pof_recoffset = 0;	/* no starting offset */
-
-			if (card->debug_flags & LOG_POF_RECORD)
-				hysdn_addlog(card, "POF: got record id=0x%lx length=%ld ",
-				      boot->pof_recid, boot->pof_reclen);
-
-			boot->pof_state = POF_READ_TAG_DATA;	/* now start with tag data */
-			if (boot->pof_reclen < BOOT_BUF_SIZE)
-				boot->last_error = boot->pof_reclen;	/* limit size */
-			else
-				boot->last_error = BOOT_BUF_SIZE;	/* maximum */
+		if (card->debug_flags & LOG_POF_RECORD)
+			hysdn_addlog(card, "POF: got record id=0x%lx length=%ld ",
+				     boot->pof_recid, boot->pof_reclen);
 
-			if (!boot->last_error) {	/* no data inside record */
-				boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
-				boot->last_error = sizeof(tPofRecHdr);	/* new length */
-			}
-			break;
+		boot->pof_state = POF_READ_TAG_DATA;	/* now start with tag data */
+		if (boot->pof_reclen < BOOT_BUF_SIZE)
+			boot->last_error = boot->pof_reclen;	/* limit size */
+		else
+			boot->last_error = BOOT_BUF_SIZE;	/* maximum */
 
-		case POF_READ_TAG_DATA:
-			if (card->debug_flags & LOG_POF_WRITE)
-				hysdn_addlog(card, "POF write: getting tag data");
-
-			if (datlen != boot->last_error) {
-				boot->last_error = -EPOF_INTERNAL;
-				break;
-			}
-			if ((boot->last_error = pof_handle_data(card, datlen)) < 0)
-				return (boot->last_error);	/* an error occurred */
-			boot->pof_recoffset += datlen;
-			if (boot->pof_recoffset >= boot->pof_reclen) {
-				boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
-				boot->last_error = sizeof(tPofRecHdr);	/* new length */
-			} else {
-				if (boot->pof_reclen - boot->pof_recoffset < BOOT_BUF_SIZE)
-					boot->last_error = boot->pof_reclen - boot->pof_recoffset;	/* limit size */
-				else
-					boot->last_error = BOOT_BUF_SIZE;	/* maximum */
-			}
-			break;
+		if (!boot->last_error) {	/* no data inside record */
+			boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
+			boot->last_error = sizeof(tPofRecHdr);	/* new length */
+		}
+		break;
 
-		default:
-			boot->last_error = -EPOF_INTERNAL;	/* unknown state */
+	case POF_READ_TAG_DATA:
+		if (card->debug_flags & LOG_POF_WRITE)
+			hysdn_addlog(card, "POF write: getting tag data");
+
+		if (datlen != boot->last_error) {
+			boot->last_error = -EPOF_INTERNAL;
 			break;
+		}
+		if ((boot->last_error = pof_handle_data(card, datlen)) < 0)
+			return (boot->last_error);	/* an error occurred */
+		boot->pof_recoffset += datlen;
+		if (boot->pof_recoffset >= boot->pof_reclen) {
+			boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
+			boot->last_error = sizeof(tPofRecHdr);	/* new length */
+		} else {
+			if (boot->pof_reclen - boot->pof_recoffset < BOOT_BUF_SIZE)
+				boot->last_error = boot->pof_reclen - boot->pof_recoffset;	/* limit size */
+			else
+				boot->last_error = BOOT_BUF_SIZE;	/* maximum */
+		}
+		break;
+
+	default:
+		boot->last_error = -EPOF_INTERNAL;	/* unknown state */
+		break;
 	}			/* switch (boot->pof_state) */
 
 	return (boot->last_error);
@@ -268,7 +268,7 @@ pof_write_buffer(hysdn_card * card, int datlen)
 /* occurred. Additionally the pointer to the buffer data area is set on success */
 /*******************************************************************************/
 int
-pof_write_open(hysdn_card * card, unsigned char **bufp)
+pof_write_open(hysdn_card *card, unsigned char **bufp)
 {
 	struct boot_data *boot;	/* pointer to boot specific data */
 
@@ -310,7 +310,7 @@ pof_write_open(hysdn_card * card, unsigned char **bufp)
 /* The return value must be 0 if everything has happened as desired.            */
 /********************************************************************************/
 int
-pof_write_close(hysdn_card * card)
+pof_write_close(hysdn_card *card)
 {
 	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
 
@@ -367,27 +367,27 @@ EvalSysrTokData(hysdn_card *card, unsigned char *cp, int len)
 			return (1);
 		}
 		switch (*cp) {
-			case SYSR_TOK_B_CHAN:	/* 1 */
-				if (*(cp + 1) != 1)
-					return (1);	/* length invalid */
-				card->bchans = *(cp + 2);
-				break;
-
-			case SYSR_TOK_FAX_CHAN:	/* 2 */
-				if (*(cp + 1) != 1)
-					return (1);	/* length invalid */
-				card->faxchans = *(cp + 2);
-				break;
-
-			case SYSR_TOK_MAC_ADDR:	/* 3 */
-				if (*(cp + 1) != 6)
-					return (1);	/* length invalid */
-				memcpy(card->mac_addr, cp + 2, 6);
-				break;
-
-			default:
-				hysdn_addlog(card, "unknown token 0x%02x length %d", *cp, *(cp + 1));
-				break;
+		case SYSR_TOK_B_CHAN:	/* 1 */
+			if (*(cp + 1) != 1)
+				return (1);	/* length invalid */
+			card->bchans = *(cp + 2);
+			break;
+
+		case SYSR_TOK_FAX_CHAN:	/* 2 */
+			if (*(cp + 1) != 1)
+				return (1);	/* length invalid */
+			card->faxchans = *(cp + 2);
+			break;
+
+		case SYSR_TOK_MAC_ADDR:	/* 3 */
+			if (*(cp + 1) != 6)
+				return (1);	/* length invalid */
+			memcpy(card->mac_addr, cp + 2, 6);
+			break;
+
+		default:
+			hysdn_addlog(card, "unknown token 0x%02x length %d", *cp, *(cp + 1));
+			break;
 		}
 		len -= (*(cp + 1) + 2);		/* adjust len */
 		cp += (*(cp + 1) + 2);	/* and pointer */
diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h
index 18b801a..cdac46a 100644
--- a/drivers/isdn/hysdn/hysdn_defs.h
+++ b/drivers/isdn/hysdn/hysdn_defs.h
@@ -41,7 +41,7 @@
 
 #define B1_PROT_64KBIT_HDLC        0x0001
 #define B1_PROT_64KBIT_TRANSPARENT 0x0002
-#define B1_PROT_V110_ASYNCH        0x0004 
+#define B1_PROT_V110_ASYNCH        0x0004
 #define B1_PROT_V110_SYNCH         0x0008
 #define B1_PROT_T30                0x0010
 #define B1_PROT_64KBIT_INV_HDLC    0x0020
@@ -199,14 +199,14 @@ typedef struct HYSDN_CARD {
 		char *version[HYSDN_MAXVERSION];
 
 		char infobuf[128];	/* for function procinfo */
-		
+
 		struct HYSDN_CARD  *card;
 		struct capi_ctr capi_ctrl;
 		struct sk_buff *skbs[HYSDN_MAX_CAPI_SKB];
 		int in_idx, out_idx;	/* indexes to buffer ring */
 		int sk_count;		/* number of buffers currently in ring */
 		struct sk_buff *tx_skb;	/* buffer for tx operation */
-	  
+
 		struct list_head ncci_head;
 	} *hyctrlinfo;
 #endif /* CONFIG_HYSDN_CAPI */
@@ -235,11 +235,11 @@ extern void hysdn_procconf_release(void);	/* deinit proc config filesys */
 /* hysdn_proclog.c */
 extern int hysdn_proclog_init(hysdn_card *);	/* init proc log entry */
 extern void hysdn_proclog_release(hysdn_card *);	/* deinit proc log entry */
-extern void hysdn_addlog(hysdn_card *, char *,...);	/* output data to log */
+extern void hysdn_addlog(hysdn_card *, char *, ...);	/* output data to log */
 extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int);	/* output card log */
 
 /* boardergo.c */
-extern int ergo_inithardware(hysdn_card * card);	/* get hardware -> module init */
+extern int ergo_inithardware(hysdn_card *card);	/* get hardware -> module init */
 
 /* hysdn_boot.c */
 extern int pof_write_close(hysdn_card *);	/* close proc file after writing pof */
@@ -249,31 +249,31 @@ extern int EvalSysrTokData(hysdn_card *, unsigned char *, int);		/* Check Sysrea
 
 /* hysdn_sched.c */
 extern int hysdn_sched_tx(hysdn_card *, unsigned char *,
-			unsigned short volatile *, unsigned short volatile *,
-			unsigned short);
+			  unsigned short volatile *, unsigned short volatile *,
+			  unsigned short);
 extern int hysdn_sched_rx(hysdn_card *, unsigned char *, unsigned short,
-			unsigned short);
+			  unsigned short);
 extern int hysdn_tx_cfgline(hysdn_card *, unsigned char *,
-			unsigned short);	/* send one cfg line */
+			    unsigned short);	/* send one cfg line */
 
 /* hysdn_net.c */
-extern unsigned int hynet_enable; 
+extern unsigned int hynet_enable;
 extern int hysdn_net_create(hysdn_card *);	/* create a new net device */
 extern int hysdn_net_release(hysdn_card *);	/* delete the device */
 extern char *hysdn_net_getname(hysdn_card *);	/* get name of net interface */
 extern void hysdn_tx_netack(hysdn_card *);	/* acknowledge a packet tx */
 extern struct sk_buff *hysdn_tx_netget(hysdn_card *);	/* get next network packet */
 extern void hysdn_rx_netpkt(hysdn_card *, unsigned char *,
-			unsigned short);	/* rxed packet from network */
+			    unsigned short);	/* rxed packet from network */
 
 #ifdef CONFIG_HYSDN_CAPI
-extern unsigned int hycapi_enable; 
+extern unsigned int hycapi_enable;
 extern int hycapi_capi_create(hysdn_card *);	/* create a new capi device */
 extern int hycapi_capi_release(hysdn_card *);	/* delete the device */
 extern int hycapi_capi_stop(hysdn_card *card);   /* suspend */
-extern void hycapi_rx_capipkt(hysdn_card * card, unsigned char * buf,
-				unsigned short len);
-extern void hycapi_tx_capiack(hysdn_card * card);
+extern void hycapi_rx_capipkt(hysdn_card *card, unsigned char *buf,
+			      unsigned short len);
+extern void hycapi_tx_capiack(hysdn_card *card);
 extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
 extern int hycapi_init(void);
 extern void hycapi_cleanup(void);
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 0ab42ac..b61bbb4 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -169,8 +169,8 @@ hysdn_init(void)
 		hysdn_have_procfs = 1;
 
 #ifdef CONFIG_HYSDN_CAPI
-	if(cardmax > 0) {
-		if(hycapi_init()) {
+	if (cardmax > 0) {
+		if (hycapi_init()) {
 			printk(KERN_ERR "HYCAPI: init failed\n");
 
 			if (hysdn_have_procfs)
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index 11f2cce..a0efb4c 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -23,7 +23,7 @@
 
 #include "hysdn_defs.h"
 
-unsigned int hynet_enable = 0xffffffff; 
+unsigned int hynet_enable = 0xffffffff;
 module_param(hynet_enable, uint, 0);
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
@@ -155,7 +155,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
 /* completion                                                          */
 /***********************************************************************/
 void
-hysdn_tx_netack(hysdn_card * card)
+hysdn_tx_netack(hysdn_card *card)
 {
 	struct net_local *lp = card->netif;
 
@@ -181,7 +181,7 @@ hysdn_tx_netack(hysdn_card * card)
 /* we got a packet from the network, go and queue it */
 /*****************************************************/
 void
-hysdn_rx_netpkt(hysdn_card * card, unsigned char *buf, unsigned short len)
+hysdn_rx_netpkt(hysdn_card *card, unsigned char *buf, unsigned short len)
 {
 	struct net_local *lp = card->netif;
 	struct net_device *dev;
@@ -215,7 +215,7 @@ hysdn_rx_netpkt(hysdn_card * card, unsigned char *buf, unsigned short len)
 /* return the pointer to a network packet to be send */
 /*****************************************************/
 struct sk_buff *
-hysdn_tx_netget(hysdn_card * card)
+hysdn_tx_netget(hysdn_card *card)
 {
 	struct net_local *lp = card->netif;
 
@@ -229,11 +229,11 @@ hysdn_tx_netget(hysdn_card * card)
 }				/* hysdn_tx_netget */
 
 static const struct net_device_ops hysdn_netdev_ops = {
-	.ndo_open 		= net_open,
+	.ndo_open		= net_open,
 	.ndo_stop		= net_close,
 	.ndo_start_xmit		= net_send_packet,
 	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
@@ -244,13 +244,13 @@ static const struct net_device_ops hysdn_netdev_ops = {
 /* 0 announces success, else a negative error code will be returned.         */
 /*****************************************************************************/
 int
-hysdn_net_create(hysdn_card * card)
+hysdn_net_create(hysdn_card *card)
 {
 	struct net_device *dev;
 	int i;
 	struct net_local *lp;
 
-	if(!card) {
+	if (!card) {
 		printk(KERN_WARNING "No card-pt in hysdn_net_create!\n");
 		return (-ENOMEM);
 	}
@@ -291,7 +291,7 @@ hysdn_net_create(hysdn_card * card)
 /* value 0 announces success, else a negative error code will be returned. */
 /***************************************************************************/
 int
-hysdn_net_release(hysdn_card * card)
+hysdn_net_release(hysdn_card *card)
 {
 	struct net_device *dev = card->netif;
 
@@ -316,7 +316,7 @@ hysdn_net_release(hysdn_card * card)
 /* if the interface is not existing, a "-" is returned.                      */
 /*****************************************************************************/
 char *
-hysdn_net_getname(hysdn_card * card)
+hysdn_net_getname(hysdn_card *card)
 {
 	struct net_device *dev = card->netif;
 
diff --git a/drivers/isdn/hysdn/hysdn_pof.h b/drivers/isdn/hysdn/hysdn_pof.h
index 3a72b90..f63f5fa 100644
--- a/drivers/isdn/hysdn/hysdn_pof.h
+++ b/drivers/isdn/hysdn/hysdn_pof.h
@@ -16,9 +16,9 @@
 #define BOOT_BUF_SIZE   0x1000	/* =4096, maybe moved to other h file */
 #define CRYPT_FEEDTERM  0x8142
 #define CRYPT_STARTTERM 0x81a5
-				    /*  max. timeout time in seconds
-				     *  from end of booting to POF is ready
-				     */
+/*  max. timeout time in seconds
+ *  from end of booting to POF is ready
+ */
 #define POF_READY_TIME_OUT_SEC  10
 
 /**********************************/
@@ -36,38 +36,38 @@
  */
 
 #define POF_BOOT_LOADER_PAGE_SIZE   0x4000	/* =16384U */
-#define POF_BOOT_LOADER_TOTAL_SIZE  (2U*POF_BOOT_LOADER_PAGE_SIZE)
+#define POF_BOOT_LOADER_TOTAL_SIZE  (2U * POF_BOOT_LOADER_PAGE_SIZE)
 
 #define POF_BOOT_LOADER_CODE_SIZE   0x0800	/* =2KB =2048U */
 
-		    /* offset in boot page, where loader code may start */
-					    /* =0x3800= 14336U */
+/* offset in boot page, where loader code may start */
+/* =0x3800= 14336U */
 #define POF_BOOT_LOADER_OFF_IN_PAGE (POF_BOOT_LOADER_PAGE_SIZE-POF_BOOT_LOADER_CODE_SIZE)
 
 
 /*--------------------------------------POF file record structs------------*/
 typedef struct PofFileHdr_tag {	/* Pof file header */
-/*00 */ unsigned long Magic __attribute__((packed));
-/*04 */ unsigned long N_PofRecs __attribute__((packed));
+	/*00 */ unsigned long Magic __attribute__((packed));
+	/*04 */ unsigned long N_PofRecs __attribute__((packed));
 /*08 */
 } tPofFileHdr;
 
 typedef struct PofRecHdr_tag {	/* Pof record header */
-/*00 */ unsigned short PofRecId __attribute__((packed));
-/*02 */ unsigned long PofRecDataLen __attribute__((packed));
+	/*00 */ unsigned short PofRecId __attribute__((packed));
+	/*02 */ unsigned long PofRecDataLen __attribute__((packed));
 /*06 */
 } tPofRecHdr;
 
 typedef struct PofTimeStamp_tag {
-/*00 */ unsigned long UnixTime __attribute__((packed));
+	/*00 */ unsigned long UnixTime __attribute__((packed));
 	/*04 */ unsigned char DateTimeText[0x28];
 	/* =40 */
 /*2C */
 } tPofTimeStamp;
 
-				    /* tPofFileHdr.Magic value: */
+/* tPofFileHdr.Magic value: */
 #define TAGFILEMAGIC 0x464F501AUL
-				    /* tPofRecHdr.PofRecId values: */
+/* tPofRecHdr.PofRecId values: */
 #define TAG_ABSDATA  0x1000	/* abs. data */
 #define TAG_BOOTDTA  0x1001	/* boot data */
 #define TAG_COMMENT  0x0020
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 5fe83bd..8023d25 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -91,7 +91,7 @@ process_line(struct conf_writedata *cnf)
 /* write conf file -> boot or send cfg line to card */
 /****************************************************/
 static ssize_t
-hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
+hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
 {
 	struct conf_writedata *cnf;
 	int i;
@@ -366,7 +366,7 @@ static const struct file_operations conf_fops =
 	.read           = hysdn_conf_read,
 	.write          = hysdn_conf_write,
 	.open           = hysdn_conf_open,
-	.release        = hysdn_conf_close,                                       
+	.release        = hysdn_conf_close,
 };
 
 /*****************************/
@@ -395,9 +395,9 @@ hysdn_procconf_init(void)
 
 		sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
 		if ((card->procconf = (void *) proc_create(conf_name,
-						S_IFREG | S_IRUGO | S_IWUSR,
-						hysdn_proc_entry,
-						&conf_fops)) != NULL) {
+							   S_IFREG | S_IRUGO | S_IWUSR,
+							   hysdn_proc_entry,
+							   &conf_fops)) != NULL) {
 			hysdn_proclog_init(card);	/* init the log file entry */
 		}
 		card = card->next;	/* next entry */
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 236cc7d..ba91333 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -24,7 +24,7 @@
 extern struct proc_dir_entry *hysdn_proc_entry;
 
 static DEFINE_MUTEX(hysdn_log_mutex);
-static void put_log_buffer(hysdn_card * card, char *cp);
+static void put_log_buffer(hysdn_card *card, char *cp);
 
 /*************************************************/
 /* structure keeping ascii log for device output */
@@ -54,7 +54,7 @@ struct procdata {
 /* log function for cards error log interface */
 /**********************************************/
 void
-hysdn_card_errlog(hysdn_card * card, tErrLogEntry * logp, int maxsize)
+hysdn_card_errlog(hysdn_card *card, tErrLogEntry *logp, int maxsize)
 {
 	char buf[ERRLOG_TEXT_SIZE + 40];
 
@@ -66,7 +66,7 @@ hysdn_card_errlog(hysdn_card * card, tErrLogEntry * logp, int maxsize)
 /* Log function using format specifiers for output */
 /***************************************************/
 void
-hysdn_addlog(hysdn_card * card, char *fmt,...)
+hysdn_addlog(hysdn_card *card, char *fmt, ...)
 {
 	struct procdata *pd = card->proclog;
 	char *cp;
@@ -98,7 +98,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...)
 /* Flushes buffers not longer in use.       */
 /********************************************/
 static void
-put_log_buffer(hysdn_card * card, char *cp)
+put_log_buffer(hysdn_card *card, char *cp)
 {
 	struct log_data *ib;
 	struct procdata *pd = card->proclog;
@@ -115,7 +115,7 @@ put_log_buffer(hysdn_card * card, char *cp)
 		return;		/* no open file for read */
 
 	if (!(ib = kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
-		 return;	/* no memory */
+		return;	/* no memory */
 	strcpy(ib->log_start, cp);	/* set output string */
 	ib->next = NULL;
 	ib->proc_ctrl = pd;	/* point to own control structure */
@@ -153,7 +153,7 @@ put_log_buffer(hysdn_card * card, char *cp)
 /* write log file -> set log level bits */
 /****************************************/
 static ssize_t
-hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
+hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
 {
 	int rc;
 	unsigned char valbuf[128];
@@ -177,7 +177,7 @@ hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t
 /* read log file */
 /******************/
 static ssize_t
-hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t * off)
+hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
 	struct log_data *inf;
 	int len;
@@ -324,7 +324,7 @@ hysdn_log_close(struct inode *ino, struct file *filep)
 /* select/poll routine to be able using select() */
 /*************************************************/
 static unsigned int
-hysdn_log_poll(struct file *file, poll_table * wait)
+hysdn_log_poll(struct file *file, poll_table *wait)
 {
 	unsigned int mask = 0;
 	struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
@@ -364,7 +364,7 @@ static const struct file_operations log_fops =
 	.write          = hysdn_log_write,
 	.poll           = hysdn_log_poll,
 	.open           = hysdn_log_open,
-	.release        = hysdn_log_close,                                        
+	.release        = hysdn_log_close,
 };
 
 
@@ -373,7 +373,7 @@ static const struct file_operations log_fops =
 /* conf files.                                                                     */
 /***********************************************************************************/
 int
-hysdn_proclog_init(hysdn_card * card)
+hysdn_proclog_init(hysdn_card *card)
 {
 	struct procdata *pd;
 
@@ -382,8 +382,8 @@ hysdn_proclog_init(hysdn_card * card)
 	if ((pd = kzalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
 		sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
 		pd->log = proc_create(pd->log_name,
-				S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry,
-				&log_fops);
+				      S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry,
+				      &log_fops);
 
 		init_waitqueue_head(&(pd->rd_queue));
 
@@ -398,7 +398,7 @@ hysdn_proclog_init(hysdn_card * card)
 /* The module counter is assumed to be 0 !                                          */
 /************************************************************************************/
 void
-hysdn_proclog_release(hysdn_card * card)
+hysdn_proclog_release(hysdn_card *card)
 {
 	struct procdata *pd;
 
diff --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c
index 3674d30..31d7c14 100644
--- a/drivers/isdn/hysdn/hysdn_sched.c
+++ b/drivers/isdn/hysdn/hysdn_sched.c
@@ -29,33 +29,33 @@
 /*****************************************************************************/
 int
 hysdn_sched_rx(hysdn_card *card, unsigned char *buf, unsigned short len,
-			unsigned short chan)
+	       unsigned short chan)
 {
 
 	switch (chan) {
-		case CHAN_NDIS_DATA:
-			if (hynet_enable & (1 << card->myid)) {
-                          /* give packet to network handler */
-				hysdn_rx_netpkt(card, buf, len);
-			}
-			break;
-
-		case CHAN_ERRLOG:
-			hysdn_card_errlog(card, (tErrLogEntry *) buf, len);
-			if (card->err_log_state == ERRLOG_STATE_ON)
-				card->err_log_state = ERRLOG_STATE_START;	/* start new fetch */
-			break;
+	case CHAN_NDIS_DATA:
+		if (hynet_enable & (1 << card->myid)) {
+			/* give packet to network handler */
+			hysdn_rx_netpkt(card, buf, len);
+		}
+		break;
+
+	case CHAN_ERRLOG:
+		hysdn_card_errlog(card, (tErrLogEntry *) buf, len);
+		if (card->err_log_state == ERRLOG_STATE_ON)
+			card->err_log_state = ERRLOG_STATE_START;	/* start new fetch */
+		break;
 #ifdef CONFIG_HYSDN_CAPI
-         	case CHAN_CAPI:
+	case CHAN_CAPI:
 /* give packet to CAPI handler */
-			if (hycapi_enable & (1 << card->myid)) {
-				hycapi_rx_capipkt(card, buf, len);
-			}
-			break;
+		if (hycapi_enable & (1 << card->myid)) {
+			hycapi_rx_capipkt(card, buf, len);
+		}
+		break;
 #endif /* CONFIG_HYSDN_CAPI */
-		default:
-			printk(KERN_INFO "irq message channel %d len %d unhandled \n", chan, len);
-			break;
+	default:
+		printk(KERN_INFO "irq message channel %d len %d unhandled \n", chan, len);
+		break;
 
 	}			/* switch rx channel */
 
@@ -72,8 +72,8 @@ hysdn_sched_rx(hysdn_card *card, unsigned char *buf, unsigned short len,
 /*****************************************************************************/
 int
 hysdn_sched_tx(hysdn_card *card, unsigned char *buf,
-		unsigned short volatile *len, unsigned short volatile *chan,
-		unsigned short maxlen)
+	       unsigned short volatile *len, unsigned short volatile *chan,
+	       unsigned short maxlen)
 {
 	struct sk_buff *skb;
 
@@ -109,8 +109,8 @@ hysdn_sched_tx(hysdn_card *card, unsigned char *buf,
 		return (1);	/* tell that data should be send */
 	}			/* error log start and able to send */
 	/* now handle network interface packets */
-	if ((hynet_enable & (1 << card->myid)) && 
-	    (skb = hysdn_tx_netget(card)) != NULL) 
+	if ((hynet_enable & (1 << card->myid)) &&
+	    (skb = hysdn_tx_netget(card)) != NULL)
 	{
 		if (skb->len <= maxlen) {
 			/* copy the packet to the buffer */
@@ -123,8 +123,8 @@ hysdn_sched_tx(hysdn_card *card, unsigned char *buf,
 			hysdn_tx_netack(card);	/* aknowledge packet -> throw away */
 	}			/* send a network packet if available */
 #ifdef CONFIG_HYSDN_CAPI
-	if( ((hycapi_enable & (1 << card->myid))) && 
-	    ((skb = hycapi_tx_capiget(card)) != NULL) )
+	if (((hycapi_enable & (1 << card->myid))) &&
+	    ((skb = hycapi_tx_capiget(card)) != NULL))
 	{
 		if (skb->len <= maxlen) {
 			skb_copy_from_linear_data(skb, buf, skb->len);
diff --git a/drivers/isdn/hysdn/ince1pc.h b/drivers/isdn/hysdn/ince1pc.h
index 7a36694..cab6836 100644
--- a/drivers/isdn/hysdn/ince1pc.h
+++ b/drivers/isdn/hysdn/ince1pc.h
@@ -17,30 +17,30 @@
 
 /*  basic scalar definitions have same meanning,
  *  but their declaration location depends on environment
- */ 
+ */
 
-/*--------------------------------------channel numbers---------------------*/ 
+/*--------------------------------------channel numbers---------------------*/
 #define CHAN_SYSTEM     0x0001      /* system channel (spooler to spooler) */
 #define CHAN_ERRLOG     0x0005      /* error logger */
 #define CHAN_CAPI       0x0064      /* CAPI interface */
 #define CHAN_NDIS_DATA  0x1001      /* NDIS data transfer */
 
-/*--------------------------------------POF ready msg-----------------------*/ 
-	    /* NOTE: after booting POF sends system ready message to PC: */ 
+/*--------------------------------------POF ready msg-----------------------*/
+/* NOTE: after booting POF sends system ready message to PC: */
 #define RDY_MAGIC       0x52535953UL    /* 'SYSR' reversed */
 #define RDY_MAGIC_SIZE  4               /* size in bytes */
 
 #define MAX_N_TOK_BYTES 255
 
 #define MIN_RDY_MSG_SIZE    RDY_MAGIC_SIZE
-#define MAX_RDY_MSG_SIZE    (RDY_MAGIC_SIZE+MAX_N_TOK_BYTES)
+#define MAX_RDY_MSG_SIZE    (RDY_MAGIC_SIZE + MAX_N_TOK_BYTES)
 
 #define SYSR_TOK_END            0
 #define SYSR_TOK_B_CHAN         1   /* nr. of B-Channels;   DataLen=1; def: 2 */
 #define SYSR_TOK_FAX_CHAN       2   /* nr. of FAX Channels; DataLen=1; def: 0 */
 #define SYSR_TOK_MAC_ADDR       3   /* MAC-Address; DataLen=6; def: auto */
 #define SYSR_TOK_ESC            255 /* undefined data size yet */
-			    /* default values, if not corrected by token: */ 
+/* default values, if not corrected by token: */
 #define SYSR_TOK_B_CHAN_DEF     2   /* assume 2 B-Channels */
 #define SYSR_TOK_FAX_CHAN_DEF   1   /* assume 1 FAX Channel */
 
@@ -70,31 +70,31 @@
  *
  *  note:
  *  - for 16-bit FIFO add padding 0 byte to achieve even token data bytes!
- */ 
+ */
 
-/*--------------------------------------error logger------------------------*/ 
-					    /* note: pof needs final 0 ! */ 
+/*--------------------------------------error logger------------------------*/
+/* note: pof needs final 0 ! */
 #define ERRLOG_CMD_REQ          "ERRLOG ON"
 #define ERRLOG_CMD_REQ_SIZE     10              /* with final 0 byte ! */
 #define ERRLOG_CMD_STOP         "ERRLOG OFF"
 #define ERRLOG_CMD_STOP_SIZE    11              /* with final 0 byte ! */
 
 #define ERRLOG_ENTRY_SIZE       64      /* sizeof(tErrLogEntry) */
-					/* remaining text size = 55 */ 
-#define ERRLOG_TEXT_SIZE    (ERRLOG_ENTRY_SIZE-2*4-1)
+					/* remaining text size = 55 */
+#define ERRLOG_TEXT_SIZE    (ERRLOG_ENTRY_SIZE - 2 * 4 - 1)
 
 typedef struct ErrLogEntry_tag {
-	
-/*00 */ unsigned long ulErrType;
-	
-/*04 */ unsigned long ulErrSubtype;
-	
-/*08 */ unsigned char ucTextSize;
-	
+
+	/*00 */ unsigned long ulErrType;
+
+	/*04 */ unsigned long ulErrSubtype;
+
+	/*08 */ unsigned char ucTextSize;
+
 	/*09 */ unsigned char ucText[ERRLOG_TEXT_SIZE];
 	/* ASCIIZ of len ucTextSize-1 */
-	
-/*40 */ 
+
+/*40 */
 } tErrLogEntry;
 
 
@@ -104,30 +104,30 @@ typedef struct ErrLogEntry_tag {
 #endif				/*  */
 #endif				/*  */
 
-/*--------------------------------------DPRAM boot spooler------------------*/ 
-				/*  this is the struture used between pc and
-				 *  hyperstone to exchange boot data
-				 */ 
+/*--------------------------------------DPRAM boot spooler------------------*/
+/*  this is the struture used between pc and
+ *  hyperstone to exchange boot data
+ */
 #define DPRAM_SPOOLER_DATA_SIZE 0x20
 typedef struct DpramBootSpooler_tag {
-	
-/*00 */ unsigned char Len;
-	
-/*01 */ volatile unsigned char RdPtr;
-	
-/*02 */ unsigned char WrPtr;
-	
-/*03 */ unsigned char Data[DPRAM_SPOOLER_DATA_SIZE];
-	
-/*23 */ 
+
+	/*00 */ unsigned char Len;
+
+	/*01 */ volatile unsigned char RdPtr;
+
+	/*02 */ unsigned char WrPtr;
+
+	/*03 */ unsigned char Data[DPRAM_SPOOLER_DATA_SIZE];
+
+/*23 */
 } tDpramBootSpooler;
 
 
 #define DPRAM_SPOOLER_MIN_SIZE  5       /* Len+RdPtr+Wrptr+2*data */
 #define DPRAM_SPOOLER_DEF_SIZE  0x23    /* current default size   */
 
-/*--------------------------------------HYCARD/ERGO DPRAM SoftUart----------*/ 
-				    /* at DPRAM offset 0x1C00: */ 
+/*--------------------------------------HYCARD/ERGO DPRAM SoftUart----------*/
+/* at DPRAM offset 0x1C00: */
 #define SIZE_RSV_SOFT_UART  0x1B0   /* 432 bytes reserved for SoftUart */
 
 
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
index d501393..78ce422 100644
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -204,9 +204,9 @@ isdn_audio_tlookup(const u_char *table, u_char *buff, unsigned long n)
 		"xlatb\n\t"
 		"stosb\n\t"
 		"loop 1b\n\t"
-	:	"=&b"(d0), "=&c"(d1), "=&D"(d2), "=&S"(d3)
-	:	"0"((long) table), "1"(n), "2"((long) buff), "3"((long) buff)
-	:	"memory", "ax");
+		:	"=&b"(d0), "=&c"(d1), "=&D"(d2), "=&S"(d3)
+		:	"0"((long) table), "1"(n), "2"((long) buff), "3"((long) buff)
+		:	"memory", "ax");
 #else
 	while (n--)
 		*buff = table[*(unsigned char *)buff], buff++;
@@ -242,27 +242,27 @@ static unsigned char
 isdn_audio_linear2ulaw(int sample)
 {
 	static int exp_lut[256] =
-	{
-		0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
-		4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-		5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-		7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-	};
+		{
+			0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+			4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+			5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+			5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+			6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+			6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+			6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+			6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+			7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+		};
 	int sign,
-	 exponent,
-	 mantissa;
+		exponent,
+		mantissa;
 	unsigned char ulawbyte;
 
 	/* Get the sample into sign-magnitude. */
@@ -299,7 +299,7 @@ static int bitmask[9] =
 };
 
 static int
-isdn_audio_get_bits(adpcm_state * s, unsigned char **in, int *len)
+isdn_audio_get_bits(adpcm_state *s, unsigned char **in, int *len)
 {
 	while (s->nleft < s->nbits) {
 		int d = *((*in)++);
@@ -312,7 +312,7 @@ isdn_audio_get_bits(adpcm_state * s, unsigned char **in, int *len)
 }
 
 static void
-isdn_audio_put_bits(int data, int nbits, adpcm_state * s,
+isdn_audio_put_bits(int data, int nbits, adpcm_state *s,
 		    unsigned char **out, int *len)
 {
 	s->word = (s->word << nbits) | (data & bitmask[nbits]);
@@ -326,7 +326,7 @@ isdn_audio_put_bits(int data, int nbits, adpcm_state * s,
 }
 
 adpcm_state *
-isdn_audio_adpcm_init(adpcm_state * s, int nbits)
+isdn_audio_adpcm_init(adpcm_state *s, int nbits)
 {
 	if (!s)
 		s = kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
@@ -341,7 +341,7 @@ isdn_audio_adpcm_init(adpcm_state * s, int nbits)
 }
 
 dtmf_state *
-isdn_audio_dtmf_init(dtmf_state * s)
+isdn_audio_dtmf_init(dtmf_state *s)
 {
 	if (!s)
 		s = kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
@@ -358,7 +358,7 @@ isdn_audio_dtmf_init(dtmf_state * s)
  */
 
 int
-isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
+isdn_audio_adpcm2xlaw(adpcm_state *s, int fmt, unsigned char *in,
 		      unsigned char *out, int len)
 {
 	int a = s->a;
@@ -379,7 +379,7 @@ isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
 			a++;
 		if (fmt)
 			*out++ = isdn_audio_ulaw_to_alaw[
-					 isdn_audio_linear2ulaw(a << 2)];
+				isdn_audio_linear2ulaw(a << 2)];
 		else
 			*out++ = isdn_audio_linear2ulaw(a << 2);
 		olen++;
@@ -393,7 +393,7 @@ isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
 }
 
 int
-isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
+isdn_audio_xlaw2adpcm(adpcm_state *s, int fmt, unsigned char *in,
 		      unsigned char *out, int len)
 {
 	int a = s->a;
@@ -403,9 +403,9 @@ isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
 
 	while (len--) {
 		int e = 0,
-		 nmax = 1 << (nbits - 1);
+			nmax = 1 << (nbits - 1);
 		int sign,
-		 delta;
+			delta;
 
 		if (fmt)
 			delta = (isdn_audio_alaw_to_s16[*in++] >> 2) - a;
@@ -439,26 +439,26 @@ isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
 
 /*
  * Goertzel algorithm.
- * See http://ptolemy.eecs.berkeley.edu/papers/96/dtmf_ict/ 
+ * See http://ptolemy.eecs.berkeley.edu/papers/96/dtmf_ict/
  * for more info.
  * Result is stored into an sk_buff and queued up for later
  * evaluation.
  */
 static void
-isdn_audio_goertzel(int *sample, modem_info * info)
+isdn_audio_goertzel(int *sample, modem_info *info)
 {
 	int sk,
-	 sk1,
-	 sk2;
+		sk1,
+		sk2;
 	int k,
-	 n;
+		n;
 	struct sk_buff *skb;
 	int *result;
 
 	skb = dev_alloc_skb(sizeof(int) * NCOEFF);
 	if (!skb) {
 		printk(KERN_WARNING
-		  "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
+		       "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
 		       info->line);
 		return;
 	}
@@ -483,16 +483,16 @@ isdn_audio_goertzel(int *sample, modem_info * info)
 			printk(KERN_DEBUG
 			       "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
 		result[k] =
-		    ((sk * sk) >> AMP_BITS) -
-		    ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
-		    ((sk2 * sk2) >> AMP_BITS);
+			((sk * sk) >> AMP_BITS) -
+			((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
+			((sk2 * sk2) >> AMP_BITS);
 	}
 	skb_queue_tail(&info->dtmf_queue, skb);
 	isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
 }
 
 void
-isdn_audio_eval_dtmf(modem_info * info)
+isdn_audio_eval_dtmf(modem_info *info)
 {
 	struct sk_buff *skb;
 	int *result;
@@ -590,7 +590,7 @@ isdn_audio_eval_dtmf(modem_info * info)
  *   fmt  = audio data format (0 = ulaw, 1 = alaw)
  */
 void
-isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
+isdn_audio_calc_dtmf(modem_info *info, unsigned char *buf, int len, int fmt)
 {
 	dtmf_state *s = info->dtmf_state;
 	int i;
@@ -605,10 +605,10 @@ isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
 		for (i = 0; i < c; i++) {
 			if (fmt)
 				s->buf[s->idx++] =
-				    isdn_audio_alaw_to_s16[*buf++] >> (15 - AMP_BITS);
+					isdn_audio_alaw_to_s16[*buf++] >> (15 - AMP_BITS);
 			else
 				s->buf[s->idx++] =
-				    isdn_audio_ulaw_to_s16[*buf++] >> (15 - AMP_BITS);
+					isdn_audio_ulaw_to_s16[*buf++] >> (15 - AMP_BITS);
 		}
 		if (s->idx == DTMF_NPOINTS) {
 			isdn_audio_goertzel(s->buf, info);
@@ -619,7 +619,7 @@ isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
 }
 
 silence_state *
-isdn_audio_silence_init(silence_state * s)
+isdn_audio_silence_init(silence_state *s)
 {
 	if (!s)
 		s = kmalloc(sizeof(silence_state), GFP_ATOMIC);
@@ -631,7 +631,7 @@ isdn_audio_silence_init(silence_state * s)
 }
 
 void
-isdn_audio_calc_silence(modem_info * info, unsigned char *buf, int len, int fmt)
+isdn_audio_calc_silence(modem_info *info, unsigned char *buf, int len, int fmt)
 {
 	silence_state *s = info->silence_state;
 	int i;
@@ -641,24 +641,24 @@ isdn_audio_calc_silence(modem_info * info, unsigned char *buf, int len, int fmt)
 
 	for (i = 0; i < len; i++) {
 		if (fmt)
-		    c = isdn_audio_alaw_to_ulaw[*buf++];
-			else
-		    c = *buf++;
+			c = isdn_audio_alaw_to_ulaw[*buf++];
+		else
+			c = *buf++;
 
 		if (c > 0) c -= 128;
 		c = abs(c);
 
-		if (c > (info->emu.vpar[1] * 4)) { 
+		if (c > (info->emu.vpar[1] * 4)) {
 			s->idx = 0;
-			s->state = 1; 
+			s->state = 1;
 		} else {
-			if (s->idx < 210000) s->idx++; 
+			if (s->idx < 210000) s->idx++;
 		}
 	}
 }
 
 void
-isdn_audio_put_dle_code(modem_info * info, u_char code)
+isdn_audio_put_dle_code(modem_info *info, u_char code)
 {
 	struct sk_buff *skb;
 	int di;
@@ -668,7 +668,7 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
 	skb = dev_alloc_skb(2);
 	if (!skb) {
 		printk(KERN_WARNING
-		  "isdn_audio: Could not alloc skb for ttyI%d\n",
+		       "isdn_audio: Could not alloc skb for ttyI%d\n",
 		       info->line);
 		return;
 	}
@@ -688,24 +688,24 @@ isdn_audio_put_dle_code(modem_info * info, u_char code)
 }
 
 void
-isdn_audio_eval_silence(modem_info * info)
+isdn_audio_eval_silence(modem_info *info)
 {
 	silence_state *s = info->silence_state;
 	char what;
 
 	what = ' ';
 
-	if (s->idx > (info->emu.vpar[2] * 800)) { 
+	if (s->idx > (info->emu.vpar[2] * 800)) {
 		s->idx = 0;
-		if (!s->state) {	/* silence from beginning of rec */ 
+		if (!s->state) {	/* silence from beginning of rec */
 			what = 's';
 		} else {
 			what = 'q';
 		}
 	}
-		if ((what == 's') || (what == 'q')) {
-			printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
-				(what=='s') ? "silence":"quiet");
-			isdn_audio_put_dle_code(info, what);
-		} 
+	if ((what == 's') || (what == 'q')) {
+		printk(KERN_DEBUG "ttyI%d: %s\n", info->line,
+		       (what == 's') ? "silence" : "quiet");
+		isdn_audio_put_dle_code(info, what);
+	}
 }
diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c
index aa0b6a6..7f3c54d 100644
--- a/drivers/isdn/i4l/isdn_bsdcomp.c
+++ b/drivers/isdn/i4l/isdn_bsdcomp.c
@@ -7,7 +7,7 @@
  */
 
 /*
- * Update: The Berkeley copyright was changed, and the change 
+ * Update: The Berkeley copyright was changed, and the change
  * is retroactive to all "true" BSD software (ie everything
  * from UCB as opposed to other peoples code that just carried
  * the same license). The new copyright doesn't clash with the
@@ -121,7 +121,7 @@ struct bsd_db {
 	unsigned char  maxbits;		/* maximum bits/code */
 	unsigned char  debug;		/* non-zero if debug desired */
 	unsigned char  unit;		/* ppp unit number */
-	u16 seqno;          		/* sequence # of next packet */
+	u16 seqno;			/* sequence # of next packet */
 	unsigned int   mru;		/* size of receive (decompress) bufr */
 	unsigned int   maxmaxcode;	/* largest valid code */
 	unsigned int   max_ent;		/* largest code in use */
@@ -157,16 +157,16 @@ struct bsd_db {
 #define MAXCODE(b)	((1 << (b)) - 1)
 #define BADCODEM1	MAXCODE(MAX_BSD_BITS)
 
-#define BSD_HASH(prefix,suffix,hshift) ((((unsigned long)(suffix))<<(hshift)) \
-					 ^ (unsigned long)(prefix))
-#define BSD_KEY(prefix,suffix)		((((unsigned long)(suffix)) << 16) \
+#define BSD_HASH(prefix, suffix, hshift) ((((unsigned long)(suffix)) << (hshift)) \
+					  ^ (unsigned long)(prefix))
+#define BSD_KEY(prefix, suffix)		((((unsigned long)(suffix)) << 16) \
 					 + (unsigned long)(prefix))
 
 #define CHECK_GAP	10000		/* Ratio check interval */
 
 #define RATIO_SCALE_LOG	8
-#define RATIO_SCALE	(1<<RATIO_SCALE_LOG)
-#define RATIO_MAX	(0x7fffffff>>RATIO_SCALE_LOG)
+#define RATIO_SCALE	(1 << RATIO_SCALE_LOG)
+#define RATIO_MAX	(0x7fffffff >> RATIO_SCALE_LOG)
 
 /*
  * clear the dictionary
@@ -175,7 +175,7 @@ struct bsd_db {
 static void bsd_clear(struct bsd_db *db)
 {
 	db->clear_count++;
-	db->max_ent      = FIRST-1;
+	db->max_ent      = FIRST - 1;
 	db->n_bits       = BSD_INIT_BITS;
 	db->bytes_out    = 0;
 	db->in_count     = 0;
@@ -197,56 +197,56 @@ static void bsd_clear(struct bsd_db *db)
  * the absence of CLEAR codes (while packets are incompressible), they
  * must compute the same ratio.
  */
-static int bsd_check (struct bsd_db *db)	/* 1=output CLEAR */
+static int bsd_check(struct bsd_db *db)	/* 1=output CLEAR */
 {
-    unsigned int new_ratio;
-
-    if (db->in_count >= db->checkpoint)
-      {
-	/* age the ratio by limiting the size of the counts */
-	if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
-	  {
-	    db->in_count  -= (db->in_count  >> 2);
-	    db->bytes_out -= (db->bytes_out >> 2);
-	  }
-	
-	db->checkpoint = db->in_count + CHECK_GAP;
-	
-	if (db->max_ent >= db->maxmaxcode)
-	  {
-	    /* Reset the dictionary only if the ratio is worse,
-	     * or if it looks as if it has been poisoned
-	     * by incompressible data.
-	     *
-	     * This does not overflow, because
-	     *	db->in_count <= RATIO_MAX.
-	     */
-
-	    new_ratio = db->in_count << RATIO_SCALE_LOG;
-	    if (db->bytes_out != 0)
-	      {
-		new_ratio /= db->bytes_out;
-	      }
-	    
-	    if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
-	      {
-		bsd_clear (db);
-		return 1;
-	      }
-	    db->ratio = new_ratio;
-	  }
-      }
-    return 0;
+	unsigned int new_ratio;
+
+	if (db->in_count >= db->checkpoint)
+	{
+		/* age the ratio by limiting the size of the counts */
+		if (db->in_count >= RATIO_MAX || db->bytes_out >= RATIO_MAX)
+		{
+			db->in_count  -= (db->in_count  >> 2);
+			db->bytes_out -= (db->bytes_out >> 2);
+		}
+
+		db->checkpoint = db->in_count + CHECK_GAP;
+
+		if (db->max_ent >= db->maxmaxcode)
+		{
+			/* Reset the dictionary only if the ratio is worse,
+			 * or if it looks as if it has been poisoned
+			 * by incompressible data.
+			 *
+			 * This does not overflow, because
+			 *	db->in_count <= RATIO_MAX.
+			 */
+
+			new_ratio = db->in_count << RATIO_SCALE_LOG;
+			if (db->bytes_out != 0)
+			{
+				new_ratio /= db->bytes_out;
+			}
+
+			if (new_ratio < db->ratio || new_ratio < 1 * RATIO_SCALE)
+			{
+				bsd_clear(db);
+				return 1;
+			}
+			db->ratio = new_ratio;
+		}
+	}
+	return 0;
 }
 
 /*
  * Return statistics.
  */
 
-static void bsd_stats (void *state, struct compstat *stats)
+static void bsd_stats(void *state, struct compstat *stats)
 {
 	struct bsd_db *db = (struct bsd_db *) state;
-    
+
 	stats->unc_bytes    = db->uncomp_bytes;
 	stats->unc_packets  = db->uncomp_count;
 	stats->comp_bytes   = db->comp_bytes;
@@ -260,9 +260,9 @@ static void bsd_stats (void *state, struct compstat *stats)
 /*
  * Reset state, as on a CCP ResetReq.
  */
-static void bsd_reset (void *state,unsigned char code, unsigned char id,
-			unsigned char *data, unsigned len,
-			struct isdn_ppp_resetparams *rsparm)
+static void bsd_reset(void *state, unsigned char code, unsigned char id,
+		      unsigned char *data, unsigned len,
+		      struct isdn_ppp_resetparams *rsparm)
 {
 	struct bsd_db *db = (struct bsd_db *) state;
 
@@ -274,7 +274,7 @@ static void bsd_reset (void *state,unsigned char code, unsigned char id,
 /*
  * Release the compression structure
  */
-static void bsd_free (void *state)
+static void bsd_free(void *state)
 {
 	struct bsd_db *db = (struct bsd_db *) state;
 
@@ -302,7 +302,7 @@ static void bsd_free (void *state)
 /*
  * Allocate space for a (de) compressor.
  */
-static void *bsd_alloc (struct isdn_ppp_comp_data *data)
+static void *bsd_alloc(struct isdn_ppp_comp_data *data)
 {
 	int bits;
 	unsigned int hsize, hshift, maxmaxcode;
@@ -310,27 +310,27 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data)
 	int decomp;
 
 	static unsigned int htab[][2] = {
-		{ 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } , 
-		{ 9001 , 5 } , { 18013 , 6 } , { 35023 , 7 } , { 69001 , 8 } 
+		{ 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } , { 5003 , 4 } ,
+		{ 9001 , 5 } , { 18013 , 6 } , { 35023 , 7 } , { 69001 , 8 }
 	};
-		
+
 	if (data->optlen != 1 || data->num != CI_BSD_COMPRESS
-		|| BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
+	    || BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
 		return NULL;
 
 	bits = BSD_NBITS(data->options[0]);
 
-	if(bits < 9 || bits > 15)
+	if (bits < 9 || bits > 15)
 		return NULL;
 
-	hsize = htab[bits-9][0];
-	hshift = htab[bits-9][1];
-	
+	hsize = htab[bits - 9][0];
+	hshift = htab[bits - 9][1];
+
 	/*
 	 * Allocate the main control structure for this instance.
 	 */
 	maxmaxcode = MAXCODE(bits);
-	db = kzalloc (sizeof (struct bsd_db),GFP_KERNEL);
+	db = kzalloc(sizeof(struct bsd_db), GFP_KERNEL);
 	if (!db)
 		return NULL;
 
@@ -343,7 +343,7 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data)
 	 */
 	db->dict = vmalloc(hsize * sizeof(struct bsd_dict));
 	if (!db->dict) {
-		bsd_free (db);
+		bsd_free(db);
 		return NULL;
 	}
 
@@ -356,7 +356,7 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data)
 	else {
 		db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0]));
 		if (!db->lens) {
-			bsd_free (db);
+			bsd_free(db);
 			return (NULL);
 		}
 	}
@@ -364,41 +364,41 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data)
 	/*
 	 * Initialize the data information for the compression code
 	 */
-	db->totlen     = sizeof (struct bsd_db) + (sizeof (struct bsd_dict) * hsize);
-	db->hsize      = hsize;
-	db->hshift     = hshift;
+	db->totlen = sizeof(struct bsd_db) + (sizeof(struct bsd_dict) * hsize);
+	db->hsize = hsize;
+	db->hshift = hshift;
 	db->maxmaxcode = maxmaxcode;
-	db->maxbits    = bits;
+	db->maxbits = bits;
 
-	return (void *) db;
+	return (void *)db;
 }
 
 /*
  * Initialize the database.
  */
-static int bsd_init (void *state, struct isdn_ppp_comp_data *data, int unit, int debug)
+static int bsd_init(void *state, struct isdn_ppp_comp_data *data, int unit, int debug)
 {
 	struct bsd_db *db = state;
 	int indx;
 	int decomp;
 
-	if(!state || !data) {
-		printk(KERN_ERR "isdn_bsd_init: [%d] ERR, state %lx data %lx\n",unit,(long)state,(long)data);
+	if (!state || !data) {
+		printk(KERN_ERR "isdn_bsd_init: [%d] ERR, state %lx data %lx\n", unit, (long)state, (long)data);
 		return 0;
 	}
 
 	decomp = db->xmit ? 0 : 1;
-    
+
 	if (data->optlen != 1 || data->num != CI_BSD_COMPRESS
-		|| (BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
-		|| (BSD_NBITS(data->options[0]) != db->maxbits)
-		|| (decomp && db->lens == NULL)) {
-		printk(KERN_ERR "isdn_bsd: %d %d %d %d %lx\n",data->optlen,data->num,data->options[0],decomp,(unsigned long)db->lens);
+	    || (BSD_VERSION(data->options[0]) != BSD_CURRENT_VERSION)
+	    || (BSD_NBITS(data->options[0]) != db->maxbits)
+	    || (decomp && db->lens == NULL)) {
+		printk(KERN_ERR "isdn_bsd: %d %d %d %d %lx\n", data->optlen, data->num, data->options[0], decomp, (unsigned long)db->lens);
 		return 0;
 	}
 
 	if (decomp)
-		for(indx=LAST;indx>=0;indx--)
+		for (indx = LAST; indx >= 0; indx--)
 			db->lens[indx] = 1;
 
 	indx = db->hsize;
@@ -411,9 +411,9 @@ static int bsd_init (void *state, struct isdn_ppp_comp_data *data, int unit, int
 	db->mru  = 0;
 
 	db->debug = 1;
-    
-	bsd_reset(db,0,0,NULL,0,NULL);
-    
+
+	bsd_reset(db, 0, 0, NULL, 0, NULL);
+
 	return 1;
 }
 
@@ -421,37 +421,37 @@ static int bsd_init (void *state, struct isdn_ppp_comp_data *data, int unit, int
  * Obtain pointers to the various structures in the compression tables
  */
 
-#define dict_ptrx(p,idx) &(p->dict[idx])
-#define lens_ptrx(p,idx) &(p->lens[idx])
+#define dict_ptrx(p, idx) &(p->dict[idx])
+#define lens_ptrx(p, idx) &(p->lens[idx])
 
 #ifdef DEBUG
 static unsigned short *lens_ptr(struct bsd_db *db, int idx)
 {
 	if ((unsigned int) idx > (unsigned int) db->maxmaxcode) {
-		printk (KERN_DEBUG "<9>ppp: lens_ptr(%d) > max\n", idx);
+		printk(KERN_DEBUG "<9>ppp: lens_ptr(%d) > max\n", idx);
 		idx = 0;
 	}
-	return lens_ptrx (db, idx);
+	return lens_ptrx(db, idx);
 }
 
 static struct bsd_dict *dict_ptr(struct bsd_db *db, int idx)
 {
 	if ((unsigned int) idx >= (unsigned int) db->hsize) {
-		printk (KERN_DEBUG "<9>ppp: dict_ptr(%d) > max\n", idx);
+		printk(KERN_DEBUG "<9>ppp: dict_ptr(%d) > max\n", idx);
 		idx = 0;
 	}
-	return dict_ptrx (db, idx);
+	return dict_ptrx(db, idx);
 }
 
 #else
-#define lens_ptr(db,idx) lens_ptrx(db,idx)
-#define dict_ptr(db,idx) dict_ptrx(db,idx)
+#define lens_ptr(db, idx) lens_ptrx(db, idx)
+#define dict_ptr(db, idx) dict_ptrx(db, idx)
 #endif
 
 /*
  * compress a packet
  */
-static int bsd_compress (void *state, struct sk_buff *skb_in, struct sk_buff *skb_out,int proto)
+static int bsd_compress(void *state, struct sk_buff *skb_in, struct sk_buff *skb_out, int proto)
 {
 	struct bsd_db *db;
 	int hshift;
@@ -463,31 +463,31 @@ static int bsd_compress (void *state, struct sk_buff *skb_in, struct sk_buff *sk
 	unsigned long fcode;
 	struct bsd_dict *dictp;
 	unsigned char c;
-	int hval,disp,ilen,mxcode;
+	int hval, disp, ilen, mxcode;
 	unsigned char *rptr = skb_in->data;
 	int isize = skb_in->len;
 
-#define OUTPUT(ent)			\
-  {					\
-    bitno -= n_bits;			\
-    accm |= ((ent) << bitno);		\
-    do	{				\
-        if(skb_out && skb_tailroom(skb_out) > 0) 	\
-      		*(skb_put(skb_out,1)) = (unsigned char) (accm>>24); \
-	accm <<= 8;			\
-	bitno += 8;			\
-    } while (bitno <= 24);		\
-  }
+#define OUTPUT(ent)							\
+	{								\
+		bitno -= n_bits;					\
+		accm |= ((ent) << bitno);				\
+		do	{						\
+			if (skb_out && skb_tailroom(skb_out) > 0)	\
+				*(skb_put(skb_out, 1)) = (unsigned char)(accm >> 24); \
+			accm <<= 8;					\
+			bitno += 8;					\
+		} while (bitno <= 24);					\
+	}
 
 	/*
 	 * If the protocol is not in the range we're interested in,
 	 * just return without compressing the packet.  If it is,
 	 * the protocol becomes the first byte to compress.
 	 */
-	printk(KERN_DEBUG "bsd_compress called with %x\n",proto);
-	
+	printk(KERN_DEBUG "bsd_compress called with %x\n", proto);
+
 	ent = proto;
-	if (proto < 0x21 || proto > 0xf9 || !(proto & 0x1) )
+	if (proto < 0x21 || proto > 0xf9 || !(proto & 0x1))
 		return 0;
 
 	db      = (struct bsd_db *) state;
@@ -496,25 +496,25 @@ static int bsd_compress (void *state, struct sk_buff *skb_in, struct sk_buff *sk
 	n_bits  = db->n_bits;
 	bitno   = 32;
 	accm    = 0;
-	mxcode  = MAXCODE (n_bits);
-	
+	mxcode  = MAXCODE(n_bits);
+
 	/* This is the PPP header information */
-	if(skb_out && skb_tailroom(skb_out) >= 2) {
-		char *v = skb_put(skb_out,2);
+	if (skb_out && skb_tailroom(skb_out) >= 2) {
+		char *v = skb_put(skb_out, 2);
 		/* we only push our own data on the header,
-		  AC,PC and protos is pushed by caller  */
+		   AC,PC and protos is pushed by caller  */
 		v[0] = db->seqno >> 8;
 		v[1] = db->seqno;
 	}
 
-	ilen   = ++isize; /* This is off by one, but that is what is in draft! */
+	ilen = ++isize; /* This is off by one, but that is what is in draft! */
 
 	while (--ilen > 0) {
-		c     = *rptr++;
-		fcode = BSD_KEY  (ent, c);
-		hval  = BSD_HASH (ent, c, hshift);
-		dictp = dict_ptr (db, hval);
-	
+		c = *rptr++;
+		fcode = BSD_KEY(ent, c);
+		hval = BSD_HASH(ent, c, hshift);
+		dictp = dict_ptr(db, hval);
+
 		/* Validate and then check the entry. */
 		if (dictp->codem1 >= max_ent)
 			goto nomatch;
@@ -523,7 +523,7 @@ static int bsd_compress (void *state, struct sk_buff *skb_in, struct sk_buff *sk
 			ent = dictp->codem1 + 1;
 			continue;	/* found (prefix,suffix) */
 		}
-	
+
 		/* continue probing until a match or invalid entry */
 		disp = (hval == 0) ? 1 : hval;
 
@@ -531,17 +531,17 @@ static int bsd_compress (void *state, struct sk_buff *skb_in, struct sk_buff *sk
 			hval += disp;
 			if (hval >= db->hsize)
 				hval -= db->hsize;
-			dictp = dict_ptr (db, hval);
+			dictp = dict_ptr(db, hval);
 			if (dictp->codem1 >= max_ent)
 				goto nomatch;
 		} while (dictp->fcode != fcode);
 
 		ent = dictp->codem1 + 1;	/* finally found (prefix,suffix) */
 		continue;
-	
-nomatch:
+
+	nomatch:
 		OUTPUT(ent);		/* output the prefix */
-	
+
 		/* code -> hashtable */
 		if (max_ent < db->maxmaxcode) {
 			struct bsd_dict *dictp2;
@@ -551,16 +551,16 @@ nomatch:
 			/* expand code size if needed */
 			if (max_ent >= mxcode) {
 				db->n_bits = ++n_bits;
-				mxcode = MAXCODE (n_bits);
+				mxcode = MAXCODE(n_bits);
 			}
-	    
-			/* 
+
+			/*
 			 * Invalidate old hash table entry using
 			 * this code, and then take it over.
 			 */
-			dictp2 = dict_ptr (db, max_ent + 1);
+			dictp2 = dict_ptr(db, max_ent + 1);
 			indx   = dictp2->cptr;
-			dictp3 = dict_ptr (db, indx);
+			dictp3 = dict_ptr(db, indx);
 
 			if (dictp3->codem1 == max_ent)
 				dictp3->codem1 = BADCODEM1;
@@ -571,17 +571,17 @@ nomatch:
 			db->max_ent    = ++max_ent;
 
 			if (db->lens) {
-				unsigned short *len1 = lens_ptr (db, max_ent);
-				unsigned short *len2 = lens_ptr (db, ent);
+				unsigned short *len1 = lens_ptr(db, max_ent);
+				unsigned short *len2 = lens_ptr(db, ent);
 				*len1 = *len2 + 1;
 			}
 		}
 		ent = c;
 	}
-    
+
 	OUTPUT(ent);		/* output the last code */
 
-	if(skb_out)
+	if (skb_out)
 		db->bytes_out    += skb_out->len; /* Do not count bytes from here */
 	db->uncomp_bytes += isize;
 	db->in_count     += isize;
@@ -596,15 +596,15 @@ nomatch:
 	 */
 
 	if (bsd_check(db))
-		OUTPUT (CLEAR);
+		OUTPUT(CLEAR);
 
 	/*
 	 * Pad dribble bits of last code with ones.
 	 * Do not emit a completely useless byte of ones.
 	 */
-	if (bitno < 32 && skb_out && skb_tailroom(skb_out) > 0) 
-		*(skb_put(skb_out,1)) = (unsigned char) ((accm | (0xff << (bitno-8))) >> 24);
-    
+	if (bitno < 32 && skb_out && skb_tailroom(skb_out) > 0)
+		*(skb_put(skb_out, 1)) = (unsigned char)((accm | (0xff << (bitno - 8))) >> 24);
+
 	/*
 	 * Increase code size if we would have without the packet
 	 * boundary because the decompressor will do so.
@@ -613,7 +613,7 @@ nomatch:
 		db->n_bits++;
 
 	/* If output length is too large then this is an incompressible frame. */
-	if (!skb_out || (skb_out && skb_out->len >= skb_in->len) ) {
+	if (!skb_out || (skb_out && skb_out->len >= skb_in->len)) {
 		++db->incomp_count;
 		db->incomp_bytes += isize;
 		return 0;
@@ -631,16 +631,16 @@ nomatch:
  * Update the "BSD Compress" dictionary on the receiver for
  * incompressible data by pretending to compress the incoming data.
  */
-static void bsd_incomp (void *state, struct sk_buff *skb_in,int proto)
+static void bsd_incomp(void *state, struct sk_buff *skb_in, int proto)
 {
-	bsd_compress (state, skb_in, NULL, proto);
+	bsd_compress(state, skb_in, NULL, proto);
 }
 
 /*
  * Decompress "BSD Compress".
  */
-static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *skb_out,
-			   struct isdn_ppp_resetparams *rsparm)
+static int bsd_decompress(void *state, struct sk_buff *skb_in, struct sk_buff *skb_out,
+			  struct isdn_ppp_resetparams *rsparm)
 {
 	struct bsd_db *db;
 	unsigned int max_ent;
@@ -653,7 +653,7 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 	unsigned int incode;
 	unsigned int oldcode;
 	unsigned int finchar;
-	unsigned char *p,*ibuf;
+	unsigned char *p, *ibuf;
 	int ilen;
 	int codelen;
 	int extra;
@@ -667,20 +667,20 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 
 	printk(KERN_DEBUG "bsd_decompress called\n");
 
-	if(!skb_in || !skb_out) {
+	if (!skb_in || !skb_out) {
 		printk(KERN_ERR "bsd_decompress called with NULL parameter\n");
 		return DECOMP_ERROR;
 	}
-    
+
 	/*
 	 * Get the sequence number.
 	 */
-	if( (p = skb_pull(skb_in,2)) == NULL) {
+	if ((p = skb_pull(skb_in, 2)) == NULL) {
 		return DECOMP_ERROR;
 	}
-	p-=2;
-	seq   = (p[0] << 8) + p[1];
-	ilen  = skb_in->len;
+	p -= 2;
+	seq = (p[0] << 8) + p[1];
+	ilen = skb_in->len;
 	ibuf = skb_in->data;
 
 	/*
@@ -690,7 +690,7 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 	if (seq != db->seqno) {
 		if (db->debug) {
 			printk(KERN_DEBUG "bsd_decomp%d: bad sequence # %d, expected %d\n",
-				db->unit, seq, db->seqno - 1);
+			       db->unit, seq, db->seqno - 1);
 		}
 		return DECOMP_ERROR;
 	}
@@ -698,11 +698,11 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 	++db->seqno;
 	db->bytes_out += ilen;
 
-	if(skb_tailroom(skb_out) > 0)
-		*(skb_put(skb_out,1)) = 0;
+	if (skb_tailroom(skb_out) > 0)
+		*(skb_put(skb_out, 1)) = 0;
 	else
 		return DECOMP_ERR_NOMEM;
-    
+
 	oldcode = CLEAR;
 
 	/*
@@ -734,7 +734,7 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 		/*
 		 * The dictionary must only be cleared at the end of a packet.
 		 */
-	
+
 		if (incode == CLEAR) {
 			if (ilen > 0) {
 				if (db->debug)
@@ -746,16 +746,16 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 		}
 
 		if ((incode > max_ent + 2) || (incode > db->maxmaxcode)
-			|| (incode > max_ent && oldcode == CLEAR)) {
+		    || (incode > max_ent && oldcode == CLEAR)) {
 			if (db->debug) {
 				printk(KERN_DEBUG "bsd_decomp%d: bad code 0x%x oldcode=0x%x ",
-					db->unit, incode, oldcode);
+				       db->unit, incode, oldcode);
 				printk(KERN_DEBUG "max_ent=0x%x skb->Len=%d seqno=%d\n",
-					max_ent, skb_out->len, db->seqno);
+				       max_ent, skb_out->len, db->seqno);
 			}
 			return DECOMP_FATALERROR;	/* probably a bug */
 		}
-	
+
 		/* Special case for KwKwK string. */
 		if (incode > max_ent) {
 			finchar = oldcode;
@@ -765,13 +765,13 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 			extra   = 0;
 		}
 
-		codelen = *(lens_ptr (db, finchar));
-		if( skb_tailroom(skb_out) < codelen + extra) {
+		codelen = *(lens_ptr(db, finchar));
+		if (skb_tailroom(skb_out) < codelen + extra) {
 			if (db->debug) {
 				printk(KERN_DEBUG "bsd_decomp%d: ran out of mru\n", db->unit);
 #ifdef DEBUG
 				printk(KERN_DEBUG "  len=%d, finchar=0x%x, codelen=%d,skblen=%d\n",
-					ilen, finchar, codelen, skb_out->len);
+				       ilen, finchar, codelen, skb_out->len);
 #endif
 			}
 			return DECOMP_FATALERROR;
@@ -781,21 +781,21 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 		 * Decode this code and install it in the decompressed buffer.
 		 */
 
-		p     = skb_put(skb_out,codelen);
+		p = skb_put(skb_out, codelen);
 		p += codelen;
 		while (finchar > LAST) {
-			struct bsd_dict *dictp2 = dict_ptr (db, finchar);
-	    
-			dictp = dict_ptr (db, dictp2->cptr);
+			struct bsd_dict *dictp2 = dict_ptr(db, finchar);
+
+			dictp = dict_ptr(db, dictp2->cptr);
 
 #ifdef DEBUG
-			if (--codelen <= 0 || dictp->codem1 != finchar-1) {
+			if (--codelen <= 0 || dictp->codem1 != finchar - 1) {
 				if (codelen <= 0) {
 					printk(KERN_ERR "bsd_decomp%d: fell off end of chain ", db->unit);
 					printk(KERN_ERR "0x%x at 0x%x by 0x%x, max_ent=0x%x\n", incode, finchar, dictp2->cptr, max_ent);
 				} else {
-					if (dictp->codem1 != finchar-1) {
-						printk(KERN_ERR "bsd_decomp%d: bad code chain 0x%x finchar=0x%x ",db->unit, incode, finchar);
+					if (dictp->codem1 != finchar - 1) {
+						printk(KERN_ERR "bsd_decomp%d: bad code chain 0x%x finchar=0x%x ", db->unit, incode, finchar);
 						printk(KERN_ERR "oldcode=0x%x cptr=0x%x codem1=0x%x\n", oldcode, dictp2->cptr, dictp->codem1);
 					}
 				}
@@ -810,15 +810,15 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 			}
 		}
 		*--p = finchar;
-	
+
 #ifdef DEBUG
 		if (--codelen != 0)
 			printk(KERN_ERR "bsd_decomp%d: short by %d after code 0x%x, max_ent=0x%x\n", db->unit, codelen, incode, max_ent);
 #endif
-	
+
 		if (extra)		/* the KwKwK case again */
-			*(skb_put(skb_out,1)) = finchar;
-	
+			*(skb_put(skb_out, 1)) = finchar;
+
 		/*
 		 * If not first code in a packet, and
 		 * if not out of code space, then allocate a new code.
@@ -828,14 +828,14 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 		 */
 		if (oldcode != CLEAR && max_ent < db->maxmaxcode) {
 			struct bsd_dict *dictp2, *dictp3;
-			u16  *lens1,  *lens2;
+			u16 *lens1, *lens2;
 			unsigned long fcode;
 			int hval, disp, indx;
-	    
-			fcode = BSD_KEY(oldcode,finchar);
-			hval  = BSD_HASH(oldcode,finchar,db->hshift);
-			dictp = dict_ptr (db, hval);
-	    
+
+			fcode = BSD_KEY(oldcode, finchar);
+			hval  = BSD_HASH(oldcode, finchar, db->hshift);
+			dictp = dict_ptr(db, hval);
+
 			/* look for a free hash table entry */
 			if (dictp->codem1 < max_ent) {
 				disp = (hval == 0) ? 1 : hval;
@@ -843,18 +843,18 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 					hval += disp;
 					if (hval >= db->hsize)
 						hval -= db->hsize;
-					dictp = dict_ptr (db, hval);
+					dictp = dict_ptr(db, hval);
 				} while (dictp->codem1 < max_ent);
 			}
-	    
+
 			/*
 			 * Invalidate previous hash table entry
 			 * assigned this code, and then take it over
 			 */
 
-			dictp2 = dict_ptr (db, max_ent + 1);
+			dictp2 = dict_ptr(db, max_ent + 1);
 			indx   = dictp2->cptr;
-			dictp3 = dict_ptr (db, indx);
+			dictp3 = dict_ptr(db, indx);
 
 			if (dictp3->codem1 == max_ent)
 				dictp3->codem1 = BADCODEM1;
@@ -865,10 +865,10 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 			db->max_ent    = ++max_ent;
 
 			/* Update the length of this string. */
-			lens1  = lens_ptr (db, max_ent);
-			lens2  = lens_ptr (db, oldcode);
+			lens1  = lens_ptr(db, max_ent);
+			lens2  = lens_ptr(db, oldcode);
 			*lens1 = *lens2 + 1;
-	    
+
 			/* Expand code size if needed. */
 			if (max_ent >= MAXCODE(n_bits) && max_ent < db->maxmaxcode) {
 				db->n_bits = ++n_bits;
@@ -886,7 +886,7 @@ static int bsd_decompress (void *state, struct sk_buff *skb_in, struct sk_buff *
 	if (bsd_check(db)) {
 		if (db->debug)
 			printk(KERN_DEBUG "bsd_decomp%d: peer should have cleared dictionary on %d\n",
-				db->unit, db->seqno - 1);
+			       db->unit, db->seqno - 1);
 	}
 	return skb_out->len;
 }
@@ -914,15 +914,15 @@ static struct isdn_ppp_compressor ippp_bsd_compress = {
 
 static int __init isdn_bsdcomp_init(void)
 {
-	int answer = isdn_ppp_register_compressor (&ippp_bsd_compress);
+	int answer = isdn_ppp_register_compressor(&ippp_bsd_compress);
 	if (answer == 0)
-		printk (KERN_INFO "PPP BSD Compression module registered\n");
+		printk(KERN_INFO "PPP BSD Compression module registered\n");
 	return answer;
 }
 
 static void __exit isdn_bsdcomp_exit(void)
 {
-	isdn_ppp_unregister_compressor (&ippp_bsd_compress);
+	isdn_ppp_unregister_compressor(&ippp_bsd_compress);
 }
 
 module_init(isdn_bsdcomp_init);
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 6ddb795e..d9f5524 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -111,7 +111,7 @@ isdn_unlock_drivers(void)
 
 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
 void
-isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
+isdn_dumppkt(char *s, u_char *p, int len, int dumplen)
 {
 	int dumpc;
 
@@ -163,58 +163,58 @@ isdn_wildmat(char *s, char *p)
 	register int nostar = 1;
 
 	if (!(*s) && !(*p))
-		return(1);
+		return (1);
 	for (; *p; s++, p++)
 		switch (*p) {
-			case '\\':
-				/*
-				 * Literal match with following character,
-				 * fall through.
-				 */
+		case '\\':
+			/*
+			 * Literal match with following character,
+			 * fall through.
+			 */
+			p++;
+		default:
+			if (*s != *p)
+				return (*s == '\0') ? 2 : 1;
+					continue;
+		case '?':
+			/* Match anything. */
+			if (*s == '\0')
+				return (2);
+			continue;
+		case '*':
+			nostar = 0;
+			/* Trailing star matches everything. */
+			return (*++p ? isdn_star(s, p) : 0);
+		case '[':
+			/* [^....] means inverse character class. */
+			if ((reverse = (p[1] == '^')))
 				p++;
-			default:
-				if (*s != *p)
-					return (*s == '\0')?2:1;
-				continue;
-			case '?':
-				/* Match anything. */
-				if (*s == '\0')
-					return (2);
-				continue;
-			case '*':
-				nostar = 0;	
-				/* Trailing star matches everything. */
-				return (*++p ? isdn_star(s, p) : 0);
-			case '[':
-				/* [^....] means inverse character class. */
-				if ((reverse = (p[1] == '^')))
-					p++;
-				for (last = 0, matched = 0; *++p && (*p != ']'); last = *p)
-					/* This next line requires a good C compiler. */
-					if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
-						matched = 1;
-				if (matched == reverse)
-					return (1);
-				continue;
+			for (last = 0, matched = 0; *++p && (*p != ']'); last = *p)
+				/* This next line requires a good C compiler. */
+				if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
+					matched = 1;
+			if (matched == reverse)
+				return (1);
+			continue;
 		}
-	return (*s == '\0')?0:nostar;
+	return (*s == '\0') ? 0 : nostar;
 }
 
-int isdn_msncmp( const char * msn1, const char * msn2 )
+int isdn_msncmp(const char *msn1, const char *msn2)
 {
-	char TmpMsn1[ ISDN_MSNLEN ];
-	char TmpMsn2[ ISDN_MSNLEN ];
+	char TmpMsn1[ISDN_MSNLEN];
+	char TmpMsn2[ISDN_MSNLEN];
 	char *p;
 
-	for ( p = TmpMsn1; *msn1 && *msn1 != ':'; )  // Strip off a SPID
+	for (p = TmpMsn1; *msn1 && *msn1 != ':';)  // Strip off a SPID
 		*p++ = *msn1++;
 	*p = '\0';
 
-	for ( p = TmpMsn2; *msn2 && *msn2 != ':'; )  // Strip off a SPID
+	for (p = TmpMsn2; *msn2 && *msn2 != ':';)  // Strip off a SPID
 		*p++ = *msn2++;
 	*p = '\0';
 
-	return isdn_wildmat( TmpMsn1, TmpMsn2 );
+	return isdn_wildmat(TmpMsn1, TmpMsn2);
 }
 
 int
@@ -262,8 +262,8 @@ isdn_timer_funct(ulong dummy)
 				isdn_tty_carrier_timeout();
 		}
 	}
-	if (tf) 
-		mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES);
+	if (tf)
+		mod_timer(&dev->timer, jiffies + ISDN_TIMER_RES);
 }
 
 void
@@ -284,7 +284,7 @@ isdn_timer_ctrl(int tf, int onoff)
 	else
 		dev->tflags &= ~tf;
 	if (dev->tflags && !old_tflags)
-		mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES);
+		mod_timer(&dev->timer, jiffies + ISDN_TIMER_RES);
 	spin_unlock_irqrestore(&dev->timerlock, flags);
 }
 
@@ -302,7 +302,7 @@ isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb)
 	}
 	/* Update statistics */
 	dev->ibytes[i] += skb->len;
-	
+
 	/* First, try to deliver data to network-device */
 	if (isdn_net_rcv_skb(i, skb))
 		return;
@@ -339,40 +339,40 @@ isdn_command(isdn_ctrl *cmd)
 {
 	if (cmd->driver == -1) {
 		printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command);
-		return(1);
+		return (1);
 	}
 	if (!dev->drv[cmd->driver]) {
 		printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d] NULL\n",
-			cmd->command, cmd->driver);
-		return(1);
+		       cmd->command, cmd->driver);
+		return (1);
 	}
 	if (!dev->drv[cmd->driver]->interface) {
 		printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d]->interface NULL\n",
-			cmd->command, cmd->driver);
-		return(1);
+		       cmd->command, cmd->driver);
+		return (1);
 	}
 	if (cmd->command == ISDN_CMD_SETL2) {
 		int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
 		unsigned long l2prot = (cmd->arg >> 8) & 255;
 		unsigned long features = (dev->drv[cmd->driver]->interface->features
-						>> ISDN_FEATURE_L2_SHIFT) &
-						ISDN_FEATURE_L2_MASK;
+					  >> ISDN_FEATURE_L2_SHIFT) &
+			ISDN_FEATURE_L2_MASK;
 		unsigned long l2_feature = (1 << l2prot);
 
 		switch (l2prot) {
-			case ISDN_PROTO_L2_V11096:
-			case ISDN_PROTO_L2_V11019:
-			case ISDN_PROTO_L2_V11038:
+		case ISDN_PROTO_L2_V11096:
+		case ISDN_PROTO_L2_V11019:
+		case ISDN_PROTO_L2_V11038:
 			/* If V.110 requested, but not supported by
 			 * HL-driver, set emulator-flag and change
 			 * Layer-2 to transparent
 			 */
-				if (!(features & l2_feature)) {
-					dev->v110emu[idx] = l2prot;
-					cmd->arg = (cmd->arg & 255) |
-						(ISDN_PROTO_L2_TRANS << 8);
-				} else
-					dev->v110emu[idx] = 0;
+			if (!(features & l2_feature)) {
+				dev->v110emu[idx] = l2prot;
+				cmd->arg = (cmd->arg & 255) |
+					(ISDN_PROTO_L2_TRANS << 8);
+			} else
+				dev->v110emu[idx] = 0;
 		}
 	}
 	return dev->drv[cmd->driver]->interface->command(cmd);
@@ -393,7 +393,7 @@ isdn_all_eaz(int di, int ch)
 }
 
 /*
- * Begin of a CAPI like LL<->HL interface, currently used only for 
+ * Begin of a CAPI like LL<->HL interface, currently used only for
  * supplementary service (CAPI 2.0 part III)
  */
 #include <linux/isdn/capicmd.h>
@@ -401,17 +401,17 @@ isdn_all_eaz(int di, int ch)
 static int
 isdn_capi_rec_hl_msg(capi_msg *cm)
 {
-	switch(cm->Command) {
-		case CAPI_FACILITY:
-			/* in the moment only handled in tty */
-			return(isdn_tty_capi_facility(cm));
-		default:
-			return(-1);
+	switch (cm->Command) {
+	case CAPI_FACILITY:
+		/* in the moment only handled in tty */
+		return (isdn_tty_capi_facility(cm));
+	default:
+		return (-1);
 	}
 }
 
 static int
-isdn_status_callback(isdn_ctrl * c)
+isdn_status_callback(isdn_ctrl *c)
 {
 	int di;
 	u_long flags;
@@ -424,314 +424,314 @@ isdn_status_callback(isdn_ctrl * c)
 	di = c->driver;
 	i = isdn_dc2minor(di, c->arg);
 	switch (c->command) {
-		case ISDN_STAT_BSENT:
-			if (i < 0)
-				return -1;
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			if (isdn_net_stat_callback(i, c))
-				return 0;
-			if (isdn_v110_stat_callback(i, c))
-				return 0;
-			if (isdn_tty_stat_callback(i, c))
-				return 0;
-			wake_up_interruptible(&dev->drv[di]->snd_waitq[c->arg]);
-			break;
-		case ISDN_STAT_STAVAIL:
-			dev->drv[di]->stavail += c->arg;
-			wake_up_interruptible(&dev->drv[di]->st_waitq);
-			break;
-		case ISDN_STAT_RUN:
-			dev->drv[di]->flags |= DRV_FLAG_RUNNING;
-			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-				if (dev->drvmap[i] == di)
-					isdn_all_eaz(di, dev->chanmap[i]);
-			set_global_features();
-			break;
-		case ISDN_STAT_STOP:
-			dev->drv[di]->flags &= ~DRV_FLAG_RUNNING;
-			break;
-		case ISDN_STAT_ICALL:
-			if (i < 0)
-				return -1;
+	case ISDN_STAT_BSENT:
+		if (i < 0)
+			return -1;
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		if (isdn_net_stat_callback(i, c))
+			return 0;
+		if (isdn_v110_stat_callback(i, c))
+			return 0;
+		if (isdn_tty_stat_callback(i, c))
+			return 0;
+		wake_up_interruptible(&dev->drv[di]->snd_waitq[c->arg]);
+		break;
+	case ISDN_STAT_STAVAIL:
+		dev->drv[di]->stavail += c->arg;
+		wake_up_interruptible(&dev->drv[di]->st_waitq);
+		break;
+	case ISDN_STAT_RUN:
+		dev->drv[di]->flags |= DRV_FLAG_RUNNING;
+		for (i = 0; i < ISDN_MAX_CHANNELS; i++)
+			if (dev->drvmap[i] == di)
+				isdn_all_eaz(di, dev->chanmap[i]);
+		set_global_features();
+		break;
+	case ISDN_STAT_STOP:
+		dev->drv[di]->flags &= ~DRV_FLAG_RUNNING;
+		break;
+	case ISDN_STAT_ICALL:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "ICALL (net): %d %ld %s\n", di, c->arg, c->parm.num);
+		printk(KERN_DEBUG "ICALL (net): %d %ld %s\n", di, c->arg, c->parm.num);
 #endif
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
+			cmd.driver = di;
+			cmd.arg = c->arg;
+			cmd.command = ISDN_CMD_HANGUP;
+			isdn_command(&cmd);
+			return 0;
+		}
+		/* Try to find a network-interface which will accept incoming call */
+		r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, &c->parm.setup));
+		switch (r) {
+		case 0:
+			/* No network-device replies.
+			 * Try ttyI's.
+			 * These return 0 on no match, 1 on match and
+			 * 3 on eventually match, if CID is longer.
+			 */
+			if (c->command == ISDN_STAT_ICALL)
+				if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return (retval);
+#ifdef CONFIG_ISDN_DIVERSION
+			if (divert_if)
+				if ((retval = divert_if->stat_callback(c)))
+					return (retval); /* processed */
+#endif /* CONFIG_ISDN_DIVERSION */
+			if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) {
+				/* No tty responding */
 				cmd.driver = di;
 				cmd.arg = c->arg;
 				cmd.command = ISDN_CMD_HANGUP;
 				isdn_command(&cmd);
-				return 0;
+				retval = 2;
 			}
-			/* Try to find a network-interface which will accept incoming call */
-			r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, &c->parm.setup));
-			switch (r) {
-				case 0:
-					/* No network-device replies.
-					 * Try ttyI's.
-					 * These return 0 on no match, 1 on match and
-					 * 3 on eventually match, if CID is longer.
-					 */
-                                        if (c->command == ISDN_STAT_ICALL)
-					  if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval);
-#ifdef CONFIG_ISDN_DIVERSION 
-                                         if (divert_if)
-                 	                  if ((retval = divert_if->stat_callback(c))) 
-					    return(retval); /* processed */
-#endif /* CONFIG_ISDN_DIVERSION */                       
-					if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) {
-						/* No tty responding */
-						cmd.driver = di;
-						cmd.arg = c->arg;
-						cmd.command = ISDN_CMD_HANGUP;
-						isdn_command(&cmd);
-						retval = 2;
-					}
-					break;
-				case 1:
-					/* Schedule connection-setup */
-					isdn_net_dial();
-					cmd.driver = di;
-					cmd.arg = c->arg;
-					cmd.command = ISDN_CMD_ACCEPTD;
-					for ( p = dev->netdev; p; p = p->next )
-						if ( p->local->isdn_channel == cmd.arg )
-						{
-							strcpy( cmd.parm.setup.eazmsn, p->local->msn );
-							isdn_command(&cmd);
-							retval = 1;
-							break;
-						}
-					break;
-
-				case 2:	/* For calling back, first reject incoming call ... */
-				case 3:	/* Interface found, but down, reject call actively  */
-					retval = 2;
-					printk(KERN_INFO "isdn: Rejecting Call\n");
-					cmd.driver = di;
-					cmd.arg = c->arg;
-					cmd.command = ISDN_CMD_HANGUP;
+			break;
+		case 1:
+			/* Schedule connection-setup */
+			isdn_net_dial();
+			cmd.driver = di;
+			cmd.arg = c->arg;
+			cmd.command = ISDN_CMD_ACCEPTD;
+			for (p = dev->netdev; p; p = p->next)
+				if (p->local->isdn_channel == cmd.arg)
+				{
+					strcpy(cmd.parm.setup.eazmsn, p->local->msn);
 					isdn_command(&cmd);
-					if (r == 3)
-						break;
-					/* Fall through */
-				case 4:
-					/* ... then start callback. */
-					isdn_net_dial();
-					break;
-				case 5:
-					/* Number would eventually match, if longer */
-					retval = 3;
+					retval = 1;
 					break;
-			}
+				}
+			break;
+
+		case 2:	/* For calling back, first reject incoming call ... */
+		case 3:	/* Interface found, but down, reject call actively  */
+			retval = 2;
+			printk(KERN_INFO "isdn: Rejecting Call\n");
+			cmd.driver = di;
+			cmd.arg = c->arg;
+			cmd.command = ISDN_CMD_HANGUP;
+			isdn_command(&cmd);
+			if (r == 3)
+				break;
+			/* Fall through */
+		case 4:
+			/* ... then start callback. */
+			isdn_net_dial();
+			break;
+		case 5:
+			/* Number would eventually match, if longer */
+			retval = 3;
+			break;
+		}
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "ICALL: ret=%d\n", retval);
+		printk(KERN_DEBUG "ICALL: ret=%d\n", retval);
 #endif
-			return retval;
-			break;
-		case ISDN_STAT_CINF:
-			if (i < 0)
-				return -1;
+		return retval;
+		break;
+	case ISDN_STAT_CINF:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "CINF: %ld %s\n", c->arg, c->parm.num);
+		printk(KERN_DEBUG "CINF: %ld %s\n", c->arg, c->parm.num);
 #endif
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			if (strcmp(c->parm.num, "0"))
-				isdn_net_stat_callback(i, c);
-			isdn_tty_stat_callback(i, c);
-			break;
-		case ISDN_STAT_CAUSE:
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		if (strcmp(c->parm.num, "0"))
+			isdn_net_stat_callback(i, c);
+		isdn_tty_stat_callback(i, c);
+		break;
+	case ISDN_STAT_CAUSE:
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "CAUSE: %ld %s\n", c->arg, c->parm.num);
+		printk(KERN_DEBUG "CAUSE: %ld %s\n", c->arg, c->parm.num);
 #endif
-			printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n",
-			       dev->drvid[di], c->arg, c->parm.num);
-			isdn_tty_stat_callback(i, c);
+		printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n",
+		       dev->drvid[di], c->arg, c->parm.num);
+		isdn_tty_stat_callback(i, c);
 #ifdef CONFIG_ISDN_DIVERSION
-                        if (divert_if)
-                         divert_if->stat_callback(c); 
+		if (divert_if)
+			divert_if->stat_callback(c);
 #endif /* CONFIG_ISDN_DIVERSION */
-			break;
-		case ISDN_STAT_DISPLAY:
+		break;
+	case ISDN_STAT_DISPLAY:
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "DISPLAY: %ld %s\n", c->arg, c->parm.display);
+		printk(KERN_DEBUG "DISPLAY: %ld %s\n", c->arg, c->parm.display);
 #endif
-			isdn_tty_stat_callback(i, c);
+		isdn_tty_stat_callback(i, c);
 #ifdef CONFIG_ISDN_DIVERSION
-                        if (divert_if)
-                         divert_if->stat_callback(c); 
+		if (divert_if)
+			divert_if->stat_callback(c);
 #endif /* CONFIG_ISDN_DIVERSION */
-			break;
-		case ISDN_STAT_DCONN:
-			if (i < 0)
-				return -1;
+		break;
+	case ISDN_STAT_DCONN:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "DCONN: %ld\n", c->arg);
+		printk(KERN_DEBUG "DCONN: %ld\n", c->arg);
 #endif
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			/* Find any net-device, waiting for D-channel setup */
-			if (isdn_net_stat_callback(i, c))
-				break;
-			isdn_v110_stat_callback(i, c);
-			/* Find any ttyI, waiting for D-channel setup */
-			if (isdn_tty_stat_callback(i, c)) {
-				cmd.driver = di;
-				cmd.arg = c->arg;
-				cmd.command = ISDN_CMD_ACCEPTB;
-				isdn_command(&cmd);
-				break;
-			}
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		/* Find any net-device, waiting for D-channel setup */
+		if (isdn_net_stat_callback(i, c))
 			break;
-		case ISDN_STAT_DHUP:
-			if (i < 0)
-				return -1;
+		isdn_v110_stat_callback(i, c);
+		/* Find any ttyI, waiting for D-channel setup */
+		if (isdn_tty_stat_callback(i, c)) {
+			cmd.driver = di;
+			cmd.arg = c->arg;
+			cmd.command = ISDN_CMD_ACCEPTB;
+			isdn_command(&cmd);
+			break;
+		}
+		break;
+	case ISDN_STAT_DHUP:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "DHUP: %ld\n", c->arg);
+		printk(KERN_DEBUG "DHUP: %ld\n", c->arg);
 #endif
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			dev->drv[di]->online &= ~(1 << (c->arg));
-			isdn_info_update();
-			/* Signal hangup to network-devices */
-			if (isdn_net_stat_callback(i, c))
-				break;
-			isdn_v110_stat_callback(i, c);
-			if (isdn_tty_stat_callback(i, c))
-				break;
-#ifdef CONFIG_ISDN_DIVERSION
-                        if (divert_if)
-                         divert_if->stat_callback(c); 
-#endif /* CONFIG_ISDN_DIVERSION */
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		dev->drv[di]->online &= ~(1 << (c->arg));
+		isdn_info_update();
+		/* Signal hangup to network-devices */
+		if (isdn_net_stat_callback(i, c))
 			break;
+		isdn_v110_stat_callback(i, c);
+		if (isdn_tty_stat_callback(i, c))
 			break;
-		case ISDN_STAT_BCONN:
-			if (i < 0)
-				return -1;
+#ifdef CONFIG_ISDN_DIVERSION
+		if (divert_if)
+			divert_if->stat_callback(c);
+#endif /* CONFIG_ISDN_DIVERSION */
+		break;
+		break;
+	case ISDN_STAT_BCONN:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "BCONN: %ld\n", c->arg);
+		printk(KERN_DEBUG "BCONN: %ld\n", c->arg);
 #endif
-			/* Signal B-channel-connect to network-devices */
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			dev->drv[di]->online |= (1 << (c->arg));
-			isdn_info_update();
-			if (isdn_net_stat_callback(i, c))
-				break;
-			isdn_v110_stat_callback(i, c);
-			if (isdn_tty_stat_callback(i, c))
-				break;
+		/* Signal B-channel-connect to network-devices */
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		dev->drv[di]->online |= (1 << (c->arg));
+		isdn_info_update();
+		if (isdn_net_stat_callback(i, c))
+			break;
+		isdn_v110_stat_callback(i, c);
+		if (isdn_tty_stat_callback(i, c))
 			break;
-		case ISDN_STAT_BHUP:
-			if (i < 0)
-				return -1;
+		break;
+	case ISDN_STAT_BHUP:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "BHUP: %ld\n", c->arg);
+		printk(KERN_DEBUG "BHUP: %ld\n", c->arg);
 #endif
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			dev->drv[di]->online &= ~(1 << (c->arg));
-			isdn_info_update();
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		dev->drv[di]->online &= ~(1 << (c->arg));
+		isdn_info_update();
 #ifdef CONFIG_ISDN_X25
-			/* Signal hangup to network-devices */
-			if (isdn_net_stat_callback(i, c))
-				break;
+		/* Signal hangup to network-devices */
+		if (isdn_net_stat_callback(i, c))
+			break;
 #endif
-			isdn_v110_stat_callback(i, c);
-			if (isdn_tty_stat_callback(i, c))
-				break;
+		isdn_v110_stat_callback(i, c);
+		if (isdn_tty_stat_callback(i, c))
 			break;
-		case ISDN_STAT_NODCH:
-			if (i < 0)
-				return -1;
+		break;
+	case ISDN_STAT_NODCH:
+		if (i < 0)
+			return -1;
 #ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "NODCH: %ld\n", c->arg);
+		printk(KERN_DEBUG "NODCH: %ld\n", c->arg);
 #endif
-			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-				return 0;
-			if (isdn_net_stat_callback(i, c))
-				break;
-			if (isdn_tty_stat_callback(i, c))
-				break;
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			return 0;
+		if (isdn_net_stat_callback(i, c))
 			break;
-		case ISDN_STAT_ADDCH:
-			spin_lock_irqsave(&dev->lock, flags);
-			if (isdn_add_channels(dev->drv[di], di, c->arg, 1)) {
-				spin_unlock_irqrestore(&dev->lock, flags);
-				return -1;
-			}
-			spin_unlock_irqrestore(&dev->lock, flags);
-			isdn_info_update();
+		if (isdn_tty_stat_callback(i, c))
 			break;
-		case ISDN_STAT_DISCH:
-			spin_lock_irqsave(&dev->lock, flags);
-			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-				if ((dev->drvmap[i] == di) &&
-				    (dev->chanmap[i] == c->arg)) {
-				    if (c->parm.num[0])
-				      dev->usage[i] &= ~ISDN_USAGE_DISABLED;
-				    else
-				      if (USG_NONE(dev->usage[i])) {
-					dev->usage[i] |= ISDN_USAGE_DISABLED;
-				      }
-				      else 
-					retval = -1;
-				    break;
-				}
+		break;
+	case ISDN_STAT_ADDCH:
+		spin_lock_irqsave(&dev->lock, flags);
+		if (isdn_add_channels(dev->drv[di], di, c->arg, 1)) {
 			spin_unlock_irqrestore(&dev->lock, flags);
-			isdn_info_update();
-			break;
-		case ISDN_STAT_UNLOAD:
-			while (dev->drv[di]->locks > 0) {
-				isdn_unlock_driver(dev->drv[di]);
-			}
-			spin_lock_irqsave(&dev->lock, flags);
-			isdn_tty_stat_callback(i, c);
-			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-				if (dev->drvmap[i] == di) {
-					dev->drvmap[i] = -1;
-					dev->chanmap[i] = -1;
+			return -1;
+		}
+		spin_unlock_irqrestore(&dev->lock, flags);
+		isdn_info_update();
+		break;
+	case ISDN_STAT_DISCH:
+		spin_lock_irqsave(&dev->lock, flags);
+		for (i = 0; i < ISDN_MAX_CHANNELS; i++)
+			if ((dev->drvmap[i] == di) &&
+			    (dev->chanmap[i] == c->arg)) {
+				if (c->parm.num[0])
 					dev->usage[i] &= ~ISDN_USAGE_DISABLED;
-				}
-			dev->drivers--;
-			dev->channels -= dev->drv[di]->channels;
-			kfree(dev->drv[di]->rcverr);
-			kfree(dev->drv[di]->rcvcount);
-			for (i = 0; i < dev->drv[di]->channels; i++)
-				skb_queue_purge(&dev->drv[di]->rpqueue[i]);
-			kfree(dev->drv[di]->rpqueue);
-			kfree(dev->drv[di]->rcv_waitq);
-			kfree(dev->drv[di]);
-			dev->drv[di] = NULL;
-			dev->drvid[di][0] = '\0';
-			isdn_info_update();
-			set_global_features();
-			spin_unlock_irqrestore(&dev->lock, flags);
-			return 0;
-		case ISDN_STAT_L1ERR:
-			break;
-		case CAPI_PUT_MESSAGE:
-			return(isdn_capi_rec_hl_msg(&c->parm.cmsg));
+				else
+					if (USG_NONE(dev->usage[i])) {
+						dev->usage[i] |= ISDN_USAGE_DISABLED;
+					}
+					else
+						retval = -1;
+				break;
+			}
+		spin_unlock_irqrestore(&dev->lock, flags);
+		isdn_info_update();
+		break;
+	case ISDN_STAT_UNLOAD:
+		while (dev->drv[di]->locks > 0) {
+			isdn_unlock_driver(dev->drv[di]);
+		}
+		spin_lock_irqsave(&dev->lock, flags);
+		isdn_tty_stat_callback(i, c);
+		for (i = 0; i < ISDN_MAX_CHANNELS; i++)
+			if (dev->drvmap[i] == di) {
+				dev->drvmap[i] = -1;
+				dev->chanmap[i] = -1;
+				dev->usage[i] &= ~ISDN_USAGE_DISABLED;
+			}
+		dev->drivers--;
+		dev->channels -= dev->drv[di]->channels;
+		kfree(dev->drv[di]->rcverr);
+		kfree(dev->drv[di]->rcvcount);
+		for (i = 0; i < dev->drv[di]->channels; i++)
+			skb_queue_purge(&dev->drv[di]->rpqueue[i]);
+		kfree(dev->drv[di]->rpqueue);
+		kfree(dev->drv[di]->rcv_waitq);
+		kfree(dev->drv[di]);
+		dev->drv[di] = NULL;
+		dev->drvid[di][0] = '\0';
+		isdn_info_update();
+		set_global_features();
+		spin_unlock_irqrestore(&dev->lock, flags);
+		return 0;
+	case ISDN_STAT_L1ERR:
+		break;
+	case CAPI_PUT_MESSAGE:
+		return (isdn_capi_rec_hl_msg(&c->parm.cmsg));
 #ifdef CONFIG_ISDN_TTY_FAX
-		case ISDN_STAT_FAXIND:
-			isdn_tty_stat_callback(i, c);
-			break;
+	case ISDN_STAT_FAXIND:
+		isdn_tty_stat_callback(i, c);
+		break;
 #endif
 #ifdef CONFIG_ISDN_AUDIO
-		case ISDN_STAT_AUDIO:
-			isdn_tty_stat_callback(i, c);
-			break;
+	case ISDN_STAT_AUDIO:
+		isdn_tty_stat_callback(i, c);
+		break;
 #endif
 #ifdef CONFIG_ISDN_DIVERSION
-	        case ISDN_STAT_PROT:
-	        case ISDN_STAT_REDIR:
-                        if (divert_if)
-                          return(divert_if->stat_callback(c));
+	case ISDN_STAT_PROT:
+	case ISDN_STAT_REDIR:
+		if (divert_if)
+			return (divert_if->stat_callback(c));
 #endif /* CONFIG_ISDN_DIVERSION */
-		default:
-			return -1;
+	default:
+		return -1;
 	}
 	return 0;
 }
@@ -755,17 +755,17 @@ isdn_getnum(char **p)
  * isdn_readbchan() tries to get data from the read-queue.
  * It MUST be called with interrupts off.
  *
- * Be aware that this is not an atomic operation when sleep != 0, even though 
+ * Be aware that this is not an atomic operation when sleep != 0, even though
  * interrupts are turned off! Well, like that we are currently only called
  * on behalf of a read system call on raw device files (which are documented
  * to be dangerous and for debugging purpose only). The inode semaphore
  * takes care that this is not called for the same minor device number while
  * we are sleeping, but access is not serialized against simultaneous read()
  * from the corresponding ttyI device. Can other ugly events, like changes
- * of the mapping (di,ch)<->minor, happen during the sleep? --he 
+ * of the mapping (di,ch)<->minor, happen during the sleep? --he
  */
 int
-isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep)
+isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue_head_t *sleep)
 {
 	int count;
 	int count_pull;
@@ -890,10 +890,10 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
 	if (!dev->drv[di])
 		return 0;
 	if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
-			return 0;
+		return 0;
 
 	len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]);
-	if(len == 0)
+	if (len == 0)
 		return len;
 
 	count = 0;
@@ -912,7 +912,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
 			count_pull = count_put = 0;
 			while ((count_pull < skb->len) && (len > 0)) {
 				/* push every character but the last to the tty buffer directly */
-				if ( count_put )
+				if (count_put)
 					tty_insert_flip_char(tty, last, TTY_NORMAL);
 				len--;
 				if (dev->drv[di]->DLEflag & DLEmask) {
@@ -940,7 +940,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
 				dflag = 0;
 			}
 			count_put = count_pull;
-			if(count_put > 1)
+			if (count_put > 1)
 				tty_insert_flip_string(tty, skb->data, count_put - 1);
 			last = skb->data[count_put - 1];
 			len -= count_put;
@@ -952,7 +952,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
 			/* We got all the data in this buff.
 			 * Now we can dequeue it.
 			 */
-			if(cisco_hack)
+			if (cisco_hack)
 				tty_insert_flip_char(tty, last, 0xFF);
 			else
 				tty_insert_flip_char(tty, last, TTY_NORMAL);
@@ -1057,7 +1057,7 @@ isdn_info_update(void)
 }
 
 static ssize_t
-isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
+isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off)
 {
 	uint minor = iminor(file->f_path.dentry->d_inode);
 	int len = 0;
@@ -1112,7 +1112,7 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 		len = isdn_readbchan(drvidx, chidx, p, NULL, count,
 				     &dev->drv[drvidx]->rcv_waitq[chidx]);
 		*off += len;
-		if (copy_to_user(buf,p,len)) 
+		if (copy_to_user(buf, p, len))
 			len = -EFAULT;
 		kfree(p);
 		retval = len;
@@ -1135,7 +1135,7 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 			if (count > dev->drv[drvidx]->stavail)
 				count = dev->drv[drvidx]->stavail;
 			len = dev->drv[drvidx]->interface->readstat(buf, count,
-				drvidx, isdn_minor2chan(minor - ISDN_MINOR_CTRL));
+								    drvidx, isdn_minor2chan(minor - ISDN_MINOR_CTRL));
 			if (len < 0) {
 				retval = len;
 				goto out;
@@ -1158,13 +1158,13 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 	}
 #endif
 	retval = -ENODEV;
- out:
+out:
 	mutex_unlock(&isdn_mutex);
 	return retval;
 }
 
 static ssize_t
-isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
+isdn_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
 {
 	uint minor = iminor(file->f_path.dentry->d_inode);
 	int drvidx;
@@ -1204,11 +1204,11 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off
 		 *
 		 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
 		 return -ENODEV;
-		 */
+		*/
 		if (dev->drv[drvidx]->interface->writecmd)
 			retval = dev->drv[drvidx]->interface->
 				writecmd(buf, count, drvidx,
-				isdn_minor2chan(minor - ISDN_MINOR_CTRL));
+					 isdn_minor2chan(minor - ISDN_MINOR_CTRL));
 		else
 			retval = count;
 		goto out;
@@ -1220,13 +1220,13 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off
 	}
 #endif
 	retval = -ENODEV;
- out:
+out:
 	mutex_unlock(&isdn_mutex);
 	return retval;
 }
 
 static unsigned int
-isdn_poll(struct file *file, poll_table * wait)
+isdn_poll(struct file *file, poll_table *wait)
 {
 	unsigned int mask = 0;
 	unsigned int minor = iminor(file->f_path.dentry->d_inode);
@@ -1261,7 +1261,7 @@ isdn_poll(struct file *file, poll_table * wait)
 	}
 #endif
 	mask = POLLERR;
- out:
+out:
 	mutex_unlock(&isdn_mutex);
 	return mask;
 }
@@ -1294,38 +1294,38 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
 
 	if (minor == ISDN_MINOR_STATUS) {
 		switch (cmd) {
-			case IIOCGETDVR:
-				return (TTY_DV +
-					(NET_DV << 8) +
-					(INF_DV << 16));
-			case IIOCGETCPS:
-				if (arg) {
-					ulong __user *p = argp;
-					int i;
-					if (!access_ok(VERIFY_WRITE, p,
-							sizeof(ulong) * ISDN_MAX_CHANNELS * 2))
-						return -EFAULT;
-					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-						put_user(dev->ibytes[i], p++);
-						put_user(dev->obytes[i], p++);
-					}
-					return 0;
-				} else
-					return -EINVAL;
-				break;
+		case IIOCGETDVR:
+			return (TTY_DV +
+				(NET_DV << 8) +
+				(INF_DV << 16));
+		case IIOCGETCPS:
+			if (arg) {
+				ulong __user *p = argp;
+				int i;
+				if (!access_ok(VERIFY_WRITE, p,
+					       sizeof(ulong) * ISDN_MAX_CHANNELS * 2))
+					return -EFAULT;
+				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+					put_user(dev->ibytes[i], p++);
+					put_user(dev->obytes[i], p++);
+				}
+				return 0;
+			} else
+				return -EINVAL;
+			break;
 #ifdef CONFIG_NETDEVICES
-			case IIOCNETGPN:
-				/* Get peer phone number of a connected 
-				 * isdn network interface */
-				if (arg) {
-					if (copy_from_user(&phone, argp, sizeof(phone)))
-						return -EFAULT;
-					return isdn_net_getpeer(&phone, argp);
-				} else
-					return -EINVAL;
-#endif
-			default:
+		case IIOCNETGPN:
+			/* Get peer phone number of a connected
+			 * isdn network interface */
+			if (arg) {
+				if (copy_from_user(&phone, argp, sizeof(phone)))
+					return -EFAULT;
+				return isdn_net_getpeer(&phone, argp);
+			} else
 				return -EINVAL;
+#endif
+		default:
+			return -EINVAL;
 		}
 	}
 	if (!dev->drivers)
@@ -1347,360 +1347,360 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
  * are serialized by means of a semaphore.
  */
 		switch (cmd) {
-			case IIOCNETDWRSET:
-				printk(KERN_INFO "INFO: ISDN_DW_ABC_EXTENSION not enabled\n");
-				return(-EINVAL);
-			case IIOCNETLCR:
-				printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
-				return -ENODEV;
+		case IIOCNETDWRSET:
+			printk(KERN_INFO "INFO: ISDN_DW_ABC_EXTENSION not enabled\n");
+			return (-EINVAL);
+		case IIOCNETLCR:
+			printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
+			return -ENODEV;
 #ifdef CONFIG_NETDEVICES
-			case IIOCNETAIF:
-				/* Add a network-interface */
-				if (arg) {
-					if (copy_from_user(name, argp, sizeof(name)))
-						return -EFAULT;
-					s = name;
+		case IIOCNETAIF:
+			/* Add a network-interface */
+			if (arg) {
+				if (copy_from_user(name, argp, sizeof(name)))
+					return -EFAULT;
+				s = name;
+			} else {
+				s = NULL;
+			}
+			ret = mutex_lock_interruptible(&dev->mtx);
+			if (ret) return ret;
+			if ((s = isdn_net_new(s, NULL))) {
+				if (copy_to_user(argp, s, strlen(s) + 1)) {
+					ret = -EFAULT;
+				} else {
+					ret = 0;
+				}
+			} else
+				ret = -ENODEV;
+			mutex_unlock(&dev->mtx);
+			return ret;
+		case IIOCNETASL:
+			/* Add a slave to a network-interface */
+			if (arg) {
+				if (copy_from_user(bname, argp, sizeof(bname) - 1))
+					return -EFAULT;
+			} else
+				return -EINVAL;
+			ret = mutex_lock_interruptible(&dev->mtx);
+			if (ret) return ret;
+			if ((s = isdn_net_newslave(bname))) {
+				if (copy_to_user(argp, s, strlen(s) + 1)) {
+					ret = -EFAULT;
 				} else {
-					s = NULL;
+					ret = 0;
 				}
+			} else
+				ret = -ENODEV;
+			mutex_unlock(&dev->mtx);
+			return ret;
+		case IIOCNETDIF:
+			/* Delete a network-interface */
+			if (arg) {
+				if (copy_from_user(name, argp, sizeof(name)))
+					return -EFAULT;
 				ret = mutex_lock_interruptible(&dev->mtx);
-				if( ret ) return ret;
-				if ((s = isdn_net_new(s, NULL))) {
-					if (copy_to_user(argp, s, strlen(s) + 1)){
-						ret = -EFAULT;
-					} else {
-						ret = 0;
-					}
-				} else
-					ret = -ENODEV;
+				if (ret) return ret;
+				ret = isdn_net_rm(name);
 				mutex_unlock(&dev->mtx);
 				return ret;
-			case IIOCNETASL:
-				/* Add a slave to a network-interface */
-				if (arg) {
-					if (copy_from_user(bname, argp, sizeof(bname) - 1))
+			} else
+				return -EINVAL;
+		case IIOCNETSCF:
+			/* Set configurable parameters of a network-interface */
+			if (arg) {
+				if (copy_from_user(&cfg, argp, sizeof(cfg)))
+					return -EFAULT;
+				return isdn_net_setcfg(&cfg);
+			} else
+				return -EINVAL;
+		case IIOCNETGCF:
+			/* Get configurable parameters of a network-interface */
+			if (arg) {
+				if (copy_from_user(&cfg, argp, sizeof(cfg)))
+					return -EFAULT;
+				if (!(ret = isdn_net_getcfg(&cfg))) {
+					if (copy_to_user(argp, &cfg, sizeof(cfg)))
 						return -EFAULT;
-				} else
-					return -EINVAL;
+				}
+				return ret;
+			} else
+				return -EINVAL;
+		case IIOCNETANM:
+			/* Add a phone-number to a network-interface */
+			if (arg) {
+				if (copy_from_user(&phone, argp, sizeof(phone)))
+					return -EFAULT;
 				ret = mutex_lock_interruptible(&dev->mtx);
-				if( ret ) return ret;
-				if ((s = isdn_net_newslave(bname))) {
-					if (copy_to_user(argp, s, strlen(s) + 1)){
-						ret = -EFAULT;
-					} else {
-						ret = 0;
-					}
-				} else
-					ret = -ENODEV;
+				if (ret) return ret;
+				ret = isdn_net_addphone(&phone);
 				mutex_unlock(&dev->mtx);
 				return ret;
-			case IIOCNETDIF:
-				/* Delete a network-interface */
-				if (arg) {
-					if (copy_from_user(name, argp, sizeof(name)))
-						return -EFAULT;
-					ret = mutex_lock_interruptible(&dev->mtx);
-					if( ret ) return ret;
-					ret = isdn_net_rm(name);
-					mutex_unlock(&dev->mtx);
-					return ret;
-				} else
-					return -EINVAL;
-			case IIOCNETSCF:
-				/* Set configurable parameters of a network-interface */
-				if (arg) {
-					if (copy_from_user(&cfg, argp, sizeof(cfg)))
-						return -EFAULT;
-					return isdn_net_setcfg(&cfg);
-				} else
-					return -EINVAL;
-			case IIOCNETGCF:
-				/* Get configurable parameters of a network-interface */
-				if (arg) {
-					if (copy_from_user(&cfg, argp, sizeof(cfg)))
-						return -EFAULT;
-					if (!(ret = isdn_net_getcfg(&cfg))) {
-						if (copy_to_user(argp, &cfg, sizeof(cfg)))
-							return -EFAULT;
-					}
-					return ret;
-				} else
-					return -EINVAL;
-			case IIOCNETANM:
-				/* Add a phone-number to a network-interface */
-				if (arg) {
-					if (copy_from_user(&phone, argp, sizeof(phone)))
-						return -EFAULT;
-					ret = mutex_lock_interruptible(&dev->mtx);
-					if( ret ) return ret;
-					ret = isdn_net_addphone(&phone);
-					mutex_unlock(&dev->mtx);
-					return ret;
-				} else
-					return -EINVAL;
-			case IIOCNETGNM:
-				/* Get list of phone-numbers of a network-interface */
-				if (arg) {
-					if (copy_from_user(&phone, argp, sizeof(phone)))
-						return -EFAULT;
-					ret = mutex_lock_interruptible(&dev->mtx);
-					if( ret ) return ret;
-					ret = isdn_net_getphones(&phone, argp);
-					mutex_unlock(&dev->mtx);
-					return ret;
-				} else
-					return -EINVAL;
-			case IIOCNETDNM:
-				/* Delete a phone-number of a network-interface */
-				if (arg) {
-					if (copy_from_user(&phone, argp, sizeof(phone)))
-						return -EFAULT;
-					ret = mutex_lock_interruptible(&dev->mtx);
-					if( ret ) return ret;
-					ret = isdn_net_delphone(&phone);
-					mutex_unlock(&dev->mtx);
-					return ret;
-				} else
-					return -EINVAL;
-			case IIOCNETDIL:
-				/* Force dialing of a network-interface */
-				if (arg) {
-					if (copy_from_user(name, argp, sizeof(name)))
-						return -EFAULT;
-					return isdn_net_force_dial(name);
-				} else
-					return -EINVAL;
-#ifdef CONFIG_ISDN_PPP
-			case IIOCNETALN:
-				if (!arg)
-					return -EINVAL;
-				if (copy_from_user(name, argp, sizeof(name)))
+			} else
+				return -EINVAL;
+		case IIOCNETGNM:
+			/* Get list of phone-numbers of a network-interface */
+			if (arg) {
+				if (copy_from_user(&phone, argp, sizeof(phone)))
 					return -EFAULT;
-				return isdn_ppp_dial_slave(name);
-			case IIOCNETDLN:
-				if (!arg)
-					return -EINVAL;
-				if (copy_from_user(name, argp, sizeof(name)))
+				ret = mutex_lock_interruptible(&dev->mtx);
+				if (ret) return ret;
+				ret = isdn_net_getphones(&phone, argp);
+				mutex_unlock(&dev->mtx);
+				return ret;
+			} else
+				return -EINVAL;
+		case IIOCNETDNM:
+			/* Delete a phone-number of a network-interface */
+			if (arg) {
+				if (copy_from_user(&phone, argp, sizeof(phone)))
 					return -EFAULT;
-				return isdn_ppp_hangup_slave(name);
-#endif
-			case IIOCNETHUP:
-				/* Force hangup of a network-interface */
-				if (!arg)
-					return -EINVAL;
+				ret = mutex_lock_interruptible(&dev->mtx);
+				if (ret) return ret;
+				ret = isdn_net_delphone(&phone);
+				mutex_unlock(&dev->mtx);
+				return ret;
+			} else
+				return -EINVAL;
+		case IIOCNETDIL:
+			/* Force dialing of a network-interface */
+			if (arg) {
 				if (copy_from_user(name, argp, sizeof(name)))
 					return -EFAULT;
-				return isdn_net_force_hangup(name);
-				break;
+				return isdn_net_force_dial(name);
+			} else
+				return -EINVAL;
+#ifdef CONFIG_ISDN_PPP
+		case IIOCNETALN:
+			if (!arg)
+				return -EINVAL;
+			if (copy_from_user(name, argp, sizeof(name)))
+				return -EFAULT;
+			return isdn_ppp_dial_slave(name);
+		case IIOCNETDLN:
+			if (!arg)
+				return -EINVAL;
+			if (copy_from_user(name, argp, sizeof(name)))
+				return -EFAULT;
+			return isdn_ppp_hangup_slave(name);
+#endif
+		case IIOCNETHUP:
+			/* Force hangup of a network-interface */
+			if (!arg)
+				return -EINVAL;
+			if (copy_from_user(name, argp, sizeof(name)))
+				return -EFAULT;
+			return isdn_net_force_hangup(name);
+			break;
 #endif                          /* CONFIG_NETDEVICES */
-			case IIOCSETVER:
-				dev->net_verbose = arg;
-				printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
-				return 0;
-			case IIOCSETGST:
-				if (arg)
-					dev->global_flags |= ISDN_GLOBAL_STOPPED;
-				else
-					dev->global_flags &= ~ISDN_GLOBAL_STOPPED;
-				printk(KERN_INFO "isdn: Global Mode %s\n",
-				       (dev->global_flags & ISDN_GLOBAL_STOPPED) ? "stopped" : "running");
-				return 0;
-			case IIOCSETBRJ:
-				drvidx = -1;
-				if (arg) {
-					int i;
-					char *p;
-					if (copy_from_user(&iocts, argp,
-					     sizeof(isdn_ioctl_struct)))
-						return -EFAULT;
-					iocts.drvid[sizeof(iocts.drvid)-1] = 0;
-					if (strlen(iocts.drvid)) {
-						if ((p = strchr(iocts.drvid, ',')))
-							*p = 0;
-						drvidx = -1;
-						for (i = 0; i < ISDN_MAX_DRIVERS; i++)
-							if (!(strcmp(dev->drvid[i], iocts.drvid))) {
-								drvidx = i;
-								break;
-							}
-					}
+		case IIOCSETVER:
+			dev->net_verbose = arg;
+			printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
+			return 0;
+		case IIOCSETGST:
+			if (arg)
+				dev->global_flags |= ISDN_GLOBAL_STOPPED;
+			else
+				dev->global_flags &= ~ISDN_GLOBAL_STOPPED;
+			printk(KERN_INFO "isdn: Global Mode %s\n",
+			       (dev->global_flags & ISDN_GLOBAL_STOPPED) ? "stopped" : "running");
+			return 0;
+		case IIOCSETBRJ:
+			drvidx = -1;
+			if (arg) {
+				int i;
+				char *p;
+				if (copy_from_user(&iocts, argp,
+						   sizeof(isdn_ioctl_struct)))
+					return -EFAULT;
+				iocts.drvid[sizeof(iocts.drvid) - 1] = 0;
+				if (strlen(iocts.drvid)) {
+					if ((p = strchr(iocts.drvid, ',')))
+						*p = 0;
+					drvidx = -1;
+					for (i = 0; i < ISDN_MAX_DRIVERS; i++)
+						if (!(strcmp(dev->drvid[i], iocts.drvid))) {
+							drvidx = i;
+							break;
+						}
 				}
-				if (drvidx == -1)
-					return -ENODEV;
-				if (iocts.arg)
-					dev->drv[drvidx]->flags |= DRV_FLAG_REJBUS;
-				else
-					dev->drv[drvidx]->flags &= ~DRV_FLAG_REJBUS;
-				return 0;
-			case IIOCSIGPRF:
-				dev->profd = current;
-				return 0;
-				break;
-			case IIOCGETPRF:
-				/* Get all Modem-Profiles */
-				if (arg) {
-					char __user *p = argp;
-					int i;
-
-					if (!access_ok(VERIFY_WRITE, argp,
-					(ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
-						   * ISDN_MAX_CHANNELS))
+			}
+			if (drvidx == -1)
+				return -ENODEV;
+			if (iocts.arg)
+				dev->drv[drvidx]->flags |= DRV_FLAG_REJBUS;
+			else
+				dev->drv[drvidx]->flags &= ~DRV_FLAG_REJBUS;
+			return 0;
+		case IIOCSIGPRF:
+			dev->profd = current;
+			return 0;
+			break;
+		case IIOCGETPRF:
+			/* Get all Modem-Profiles */
+			if (arg) {
+				char __user *p = argp;
+				int i;
+
+				if (!access_ok(VERIFY_WRITE, argp,
+					       (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
+					       * ISDN_MAX_CHANNELS))
+					return -EFAULT;
+
+				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+					if (copy_to_user(p, dev->mdm.info[i].emu.profile,
+							 ISDN_MODEM_NUMREG))
+						return -EFAULT;
+					p += ISDN_MODEM_NUMREG;
+					if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN))
 						return -EFAULT;
+					p += ISDN_MSNLEN;
+					if (copy_to_user(p, dev->mdm.info[i].emu.plmsn, ISDN_LMSNLEN))
+						return -EFAULT;
+					p += ISDN_LMSNLEN;
+				}
+				return (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
+			} else
+				return -EINVAL;
+			break;
+		case IIOCSETPRF:
+			/* Set all Modem-Profiles */
+			if (arg) {
+				char __user *p = argp;
+				int i;
+
+				if (!access_ok(VERIFY_READ, argp,
+					       (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
+					       * ISDN_MAX_CHANNELS))
+					return -EFAULT;
 
-					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-						if (copy_to_user(p, dev->mdm.info[i].emu.profile,
-						      ISDN_MODEM_NUMREG))
-							return -EFAULT;
-						p += ISDN_MODEM_NUMREG;
-						if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN))
-							return -EFAULT;
-						p += ISDN_MSNLEN;
-						if (copy_to_user(p, dev->mdm.info[i].emu.plmsn, ISDN_LMSNLEN))
-							return -EFAULT;
-						p += ISDN_LMSNLEN;
-					}
-					return (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
-				} else
-					return -EINVAL;
-				break;
-			case IIOCSETPRF:
-				/* Set all Modem-Profiles */
-				if (arg) {
-					char __user *p = argp;
-					int i;
-
-					if (!access_ok(VERIFY_READ, argp,
-					(ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
-						   * ISDN_MAX_CHANNELS))
+				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+					if (copy_from_user(dev->mdm.info[i].emu.profile, p,
+							   ISDN_MODEM_NUMREG))
+						return -EFAULT;
+					p += ISDN_MODEM_NUMREG;
+					if (copy_from_user(dev->mdm.info[i].emu.plmsn, p, ISDN_LMSNLEN))
 						return -EFAULT;
+					p += ISDN_LMSNLEN;
+					if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN))
+						return -EFAULT;
+					p += ISDN_MSNLEN;
+				}
+				return 0;
+			} else
+				return -EINVAL;
+			break;
+		case IIOCSETMAP:
+		case IIOCGETMAP:
+			/* Set/Get MSN->EAZ-Mapping for a driver */
+			if (arg) {
 
-					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-						if (copy_from_user(dev->mdm.info[i].emu.profile, p,
-						     ISDN_MODEM_NUMREG))
-							return -EFAULT;
-						p += ISDN_MODEM_NUMREG;
-						if (copy_from_user(dev->mdm.info[i].emu.plmsn, p, ISDN_LMSNLEN))
-							return -EFAULT;
-						p += ISDN_LMSNLEN;
-						if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN))
-							return -EFAULT;
-						p += ISDN_MSNLEN;
-					}
-					return 0;
+				if (copy_from_user(&iocts, argp,
+						   sizeof(isdn_ioctl_struct)))
+					return -EFAULT;
+				iocts.drvid[sizeof(iocts.drvid) - 1] = 0;
+				if (strlen(iocts.drvid)) {
+					drvidx = -1;
+					for (i = 0; i < ISDN_MAX_DRIVERS; i++)
+						if (!(strcmp(dev->drvid[i], iocts.drvid))) {
+							drvidx = i;
+							break;
+						}
 				} else
-					return -EINVAL;
-				break;
-			case IIOCSETMAP:
-			case IIOCGETMAP:
-				/* Set/Get MSN->EAZ-Mapping for a driver */
-				if (arg) {
+					drvidx = 0;
+				if (drvidx == -1)
+					return -ENODEV;
+				if (cmd == IIOCSETMAP) {
+					int loop = 1;
 
-					if (copy_from_user(&iocts, argp,
-					     sizeof(isdn_ioctl_struct)))
-						return -EFAULT;
-					iocts.drvid[sizeof(iocts.drvid)-1] = 0;
-					if (strlen(iocts.drvid)) {
-						drvidx = -1;
-						for (i = 0; i < ISDN_MAX_DRIVERS; i++)
-							if (!(strcmp(dev->drvid[i], iocts.drvid))) {
-								drvidx = i;
+					p = (char __user *) iocts.arg;
+					i = 0;
+					while (loop) {
+						int j = 0;
+
+						while (1) {
+							if (!access_ok(VERIFY_READ, p, 1))
+								return -EFAULT;
+							get_user(bname[j], p++);
+							switch (bname[j]) {
+							case '\0':
+								loop = 0;
+								/* Fall through */
+							case ',':
+								bname[j] = '\0';
+								strcpy(dev->drv[drvidx]->msn2eaz[i], bname);
+								j = ISDN_MSNLEN;
 								break;
+							default:
+								j++;
 							}
-					} else
-						drvidx = 0;
-					if (drvidx == -1)
-						return -ENODEV;
-					if (cmd == IIOCSETMAP) {
-						int loop = 1;
-
-						p = (char __user *) iocts.arg;
-						i = 0;
-						while (loop) {
-							int j = 0;
-
-							while (1) {
-								if (!access_ok(VERIFY_READ, p, 1))
-									return -EFAULT;
-								get_user(bname[j], p++);
-								switch (bname[j]) {
-									case '\0':
-										loop = 0;
-										/* Fall through */
-									case ',':
-										bname[j] = '\0';
-										strcpy(dev->drv[drvidx]->msn2eaz[i], bname);
-										j = ISDN_MSNLEN;
-										break;
-									default:
-										j++;
-								}
-								if (j >= ISDN_MSNLEN)
-									break;
-							}
-							if (++i > 9)
+							if (j >= ISDN_MSNLEN)
 								break;
 						}
-					} else {
-						p = (char __user *) iocts.arg;
-						for (i = 0; i < 10; i++) {
-							snprintf(bname, sizeof(bname), "%s%s",
-								strlen(dev->drv[drvidx]->msn2eaz[i]) ?
-								dev->drv[drvidx]->msn2eaz[i] : "_",
-								(i < 9) ? "," : "\0");
-							if (copy_to_user(p, bname, strlen(bname) + 1))
-								return -EFAULT;
-							p += strlen(bname);
-						}
+						if (++i > 9)
+							break;
 					}
-					return 0;
-				} else
-					return -EINVAL;
-			case IIOCDBGVAR:
-				if (arg) {
-					if (copy_to_user(argp, &dev, sizeof(ulong)))
-						return -EFAULT;
-					return 0;
-				} else
-					return -EINVAL;
-				break;
-			default:
-				if ((cmd & IIOCDRVCTL) == IIOCDRVCTL)
-					cmd = ((cmd >> _IOC_NRSHIFT) & _IOC_NRMASK) & ISDN_DRVIOCTL_MASK;
-				else
-					return -EINVAL;
-				if (arg) {
-					int i;
-					char *p;
-					if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct)))
-						return -EFAULT;
-					iocts.drvid[sizeof(iocts.drvid)-1] = 0;
-					if (strlen(iocts.drvid)) {
-						if ((p = strchr(iocts.drvid, ',')))
-							*p = 0;
-						drvidx = -1;
-						for (i = 0; i < ISDN_MAX_DRIVERS; i++)
-							if (!(strcmp(dev->drvid[i], iocts.drvid))) {
-								drvidx = i;
-								break;
-							}
-					} else
-						drvidx = 0;
-					if (drvidx == -1)
-						return -ENODEV;
-					if (!access_ok(VERIFY_WRITE, argp,
-					     sizeof(isdn_ioctl_struct)))
-						return -EFAULT;
-					c.driver = drvidx;
-					c.command = ISDN_CMD_IOCTL;
-					c.arg = cmd;
-					memcpy(c.parm.num, &iocts.arg, sizeof(ulong));
-					ret = isdn_command(&c);
-					memcpy(&iocts.arg, c.parm.num, sizeof(ulong));
-					if (copy_to_user(argp, &iocts, sizeof(isdn_ioctl_struct)))
-						return -EFAULT;
-					return ret;
+				} else {
+					p = (char __user *) iocts.arg;
+					for (i = 0; i < 10; i++) {
+						snprintf(bname, sizeof(bname), "%s%s",
+							 strlen(dev->drv[drvidx]->msn2eaz[i]) ?
+							 dev->drv[drvidx]->msn2eaz[i] : "_",
+							 (i < 9) ? "," : "\0");
+						if (copy_to_user(p, bname, strlen(bname) + 1))
+							return -EFAULT;
+						p += strlen(bname);
+					}
+				}
+				return 0;
+			} else
+				return -EINVAL;
+		case IIOCDBGVAR:
+			if (arg) {
+				if (copy_to_user(argp, &dev, sizeof(ulong)))
+					return -EFAULT;
+				return 0;
+			} else
+				return -EINVAL;
+			break;
+		default:
+			if ((cmd & IIOCDRVCTL) == IIOCDRVCTL)
+				cmd = ((cmd >> _IOC_NRSHIFT) & _IOC_NRMASK) & ISDN_DRVIOCTL_MASK;
+			else
+				return -EINVAL;
+			if (arg) {
+				int i;
+				char *p;
+				if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct)))
+					return -EFAULT;
+				iocts.drvid[sizeof(iocts.drvid) - 1] = 0;
+				if (strlen(iocts.drvid)) {
+					if ((p = strchr(iocts.drvid, ',')))
+						*p = 0;
+					drvidx = -1;
+					for (i = 0; i < ISDN_MAX_DRIVERS; i++)
+						if (!(strcmp(dev->drvid[i], iocts.drvid))) {
+							drvidx = i;
+							break;
+						}
 				} else
-					return -EINVAL;
+					drvidx = 0;
+				if (drvidx == -1)
+					return -ENODEV;
+				if (!access_ok(VERIFY_WRITE, argp,
+					       sizeof(isdn_ioctl_struct)))
+					return -EFAULT;
+				c.driver = drvidx;
+				c.command = ISDN_CMD_IOCTL;
+				c.arg = cmd;
+				memcpy(c.parm.num, &iocts.arg, sizeof(ulong));
+				ret = isdn_command(&c);
+				memcpy(&iocts.arg, c.parm.num, sizeof(ulong));
+				if (copy_to_user(argp, &iocts, sizeof(isdn_ioctl_struct)))
+					return -EFAULT;
+				return ret;
+			} else
+				return -EINVAL;
 		}
 	}
 #ifdef CONFIG_ISDN_PPP
@@ -1788,7 +1788,7 @@ isdn_open(struct inode *ino, struct file *filep)
 		goto out;
 	}
 #endif
- out:
+out:
 	nonseekable_open(ino, filep);
 	mutex_unlock(&isdn_mutex);
 	return retval;
@@ -1832,7 +1832,7 @@ isdn_close(struct inode *ino, struct file *filep)
 		isdn_ppp_release(minor - ISDN_MINOR_PPP, filep);
 #endif
 
- out:
+out:
 	mutex_unlock(&isdn_mutex);
 	return 0;
 }
@@ -1868,14 +1868,14 @@ isdn_map_eaz2msn(char *msn, int di)
  * Find an unused ISDN-channel, whose feature-flags match the
  * given L2- and L3-protocols.
  */
-#define L2V (~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038))
+#define L2V (~(ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038))
 
 /*
  * This function must be called with holding the dev->lock.
  */
 int
 isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
-		      ,int pre_chan, char *msn)
+		      , int pre_chan, char *msn)
 {
 	int i;
 	ulong features;
@@ -1883,7 +1883,7 @@ isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
 
 	features = ((1 << l2_proto) | (0x10000 << l3_proto));
 	vfeatures = (((1 << l2_proto) | (0x10000 << l3_proto)) &
-		     ~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038));
+		     ~(ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038));
 	/* If Layer-2 protocol is V.110, accept drivers with
 	 * transparent feature even if these don't support V.110
 	 * because we can emulate this in linklevel.
@@ -1893,12 +1893,12 @@ isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
 		    (dev->drvmap[i] != -1)) {
 			int d = dev->drvmap[i];
 			if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) &&
-			((pre_dev != d) || (pre_chan != dev->chanmap[i])))
+			    ((pre_dev != d) || (pre_chan != dev->chanmap[i])))
 				continue;
 			if (!strcmp(isdn_map_eaz2msn(msn, d), "-"))
 				continue;
 			if (dev->usage[i] & ISDN_USAGE_DISABLED)
-			        continue; /* usage not allowed */
+				continue; /* usage not allowed */
 			if (dev->drv[d]->flags & DRV_FLAG_RUNNING) {
 				if (((dev->drv[d]->interface->features & features) == features) ||
 				    (((dev->drv[d]->interface->features & vfeatures) == vfeatures) &&
@@ -1932,7 +1932,7 @@ isdn_free_channel(int di, int ch, int usage)
 
 	if ((di < 0) || (ch < 0)) {
 		printk(KERN_WARNING "%s: called with invalid drv(%d) or channel(%d)\n",
-			__func__, di, ch);
+		       __func__, di, ch);
 		return;
 	}
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
@@ -1976,7 +1976,7 @@ isdn_unexclusive_channel(int di, int ch)
  *  writebuf replacement for SKB_ABLE drivers
  */
 static int
-isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len)
+isdn_writebuf_stub(int drvidx, int chan, const u_char __user *buf, int len)
 {
 	int ret;
 	int hl = dev->drv[drvidx]->interface->hl_hdrlen;
@@ -2026,8 +2026,8 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
 	} else {
 		int hl = dev->drv[drvidx]->interface->hl_hdrlen;
 
-		if( skb_headroom(skb) < hl ){
-			/* 
+		if (skb_headroom(skb) < hl) {
+			/*
 			 * This should only occur when new HL driver with
 			 * increased hl_hdrlen was loaded after netdevice
 			 * was created and connected to the new driver.
@@ -2035,13 +2035,13 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
 			 * The V.110 branch (re-allocates on its own) does
 			 * not need this
 			 */
-			struct sk_buff * skb_tmp;
+			struct sk_buff *skb_tmp;
 
 			skb_tmp = skb_realloc_headroom(skb, hl);
 			printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed");
 			if (!skb_tmp) return -ENOMEM; /* 0 better? */
 			ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb_tmp);
-			if( ret > 0 ){
+			if (ret > 0) {
 				dev_kfree_skb(skb);
 			} else {
 				dev_kfree_skb(skb_tmp);
@@ -2059,7 +2059,7 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
 			/* For V.110 return unencoded data length */
 			ret = v110_ret;
 			/* if the complete frame was send we free the skb;
-			   if not upper function will requeue the skb */ 
+			   if not upper function will requeue the skb */
 			if (ret == skb->len)
 				dev_kfree_skb(skb);
 		}
@@ -2077,7 +2077,7 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
 	init_waitqueue_head(&d->st_waitq);
 	if (d->flags & DRV_FLAG_RUNNING)
 		return -1;
-       	if (n < 1) return 0;
+	if (n < 1) return 0;
 
 	m = (adding) ? d->channels + n : n;
 
@@ -2114,7 +2114,7 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
 			kfree(d->rcvcount);
 			kfree(d->rcverr);
 		}
-		return -1; 
+		return -1;
 	}
 	for (j = 0; j < m; j++) {
 		skb_queue_head_init(&d->rpqueue[j]);
@@ -2172,45 +2172,45 @@ set_global_features(void)
 
 static char *map_drvname(int di)
 {
-  if ((di < 0) || (di >= ISDN_MAX_DRIVERS)) 
-    return(NULL);
-  return(dev->drvid[di]); /* driver name */
+	if ((di < 0) || (di >= ISDN_MAX_DRIVERS))
+		return (NULL);
+	return (dev->drvid[di]); /* driver name */
 } /* map_drvname */
 
 static int map_namedrv(char *id)
 {  int i;
 
-   for (i = 0; i < ISDN_MAX_DRIVERS; i++)
-    { if (!strcmp(dev->drvid[i],id)) 
-        return(i);
-    }
-   return(-1);
+	for (i = 0; i < ISDN_MAX_DRIVERS; i++)
+	{ if (!strcmp(dev->drvid[i], id))
+			return (i);
+	}
+	return (-1);
 } /* map_namedrv */
 
 int DIVERT_REG_NAME(isdn_divert_if *i_div)
 {
-  if (i_div->if_magic != DIVERT_IF_MAGIC) 
-    return(DIVERT_VER_ERR);
-  switch (i_div->cmd)
-    {
-      case DIVERT_CMD_REL:
-        if (divert_if != i_div) 
-          return(DIVERT_REL_ERR);
-        divert_if = NULL; /* free interface */
-        return(DIVERT_NO_ERR);
-
-      case DIVERT_CMD_REG:
-        if (divert_if) 
-          return(DIVERT_REG_ERR);
-        i_div->ll_cmd = isdn_command; /* set command function */
-        i_div->drv_to_name = map_drvname; 
-        i_div->name_to_drv = map_namedrv; 
-        divert_if = i_div; /* remember interface */
-        return(DIVERT_NO_ERR);
-
-      default:
-        return(DIVERT_CMD_ERR);   
-    }
+	if (i_div->if_magic != DIVERT_IF_MAGIC)
+		return (DIVERT_VER_ERR);
+	switch (i_div->cmd)
+	{
+	case DIVERT_CMD_REL:
+		if (divert_if != i_div)
+			return (DIVERT_REL_ERR);
+		divert_if = NULL; /* free interface */
+		return (DIVERT_NO_ERR);
+
+	case DIVERT_CMD_REG:
+		if (divert_if)
+			return (DIVERT_REG_ERR);
+		i_div->ll_cmd = isdn_command; /* set command function */
+		i_div->drv_to_name = map_drvname;
+		i_div->name_to_drv = map_namedrv;
+		divert_if = i_div; /* remember interface */
+		return (DIVERT_NO_ERR);
+
+	default:
+		return (DIVERT_CMD_ERR);
+	}
 } /* DIVERT_REG_NAME */
 
 EXPORT_SYMBOL(DIVERT_REG_NAME);
@@ -2225,7 +2225,7 @@ EXPORT_SYMBOL(isdn_ppp_unregister_compressor);
 #endif
 
 int
-register_isdn(isdn_if * i)
+register_isdn(isdn_if *i)
 {
 	isdn_driver_t *d;
 	int j;
@@ -2280,10 +2280,10 @@ register_isdn(isdn_if * i)
 }
 
 /*
- *****************************************************************************
- * And now the modules code.
- *****************************************************************************
- */
+*****************************************************************************
+* And now the modules code.
+*****************************************************************************
+*/
 
 static char *
 isdn_getrev(const char *revision)
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h
index 082735d..9a471f6 100644
--- a/drivers/isdn/i4l/isdn_common.h
+++ b/drivers/isdn/i4l/isdn_common.h
@@ -29,19 +29,19 @@ extern void isdn_lock_drivers(void);
 extern void isdn_unlock_drivers(void);
 extern void isdn_free_channel(int di, int ch, int usage);
 extern void isdn_all_eaz(int di, int ch);
-extern int  isdn_command(isdn_ctrl *);
-extern int  isdn_dc2minor(int di, int ch);
+extern int isdn_command(isdn_ctrl *);
+extern int isdn_dc2minor(int di, int ch);
 extern void isdn_info_update(void);
 extern char *isdn_map_eaz2msn(char *msn, int di);
 extern void isdn_timer_ctrl(int tf, int onoff);
 extern void isdn_unexclusive_channel(int di, int ch);
-extern int  isdn_getnum(char **);
-extern int  isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *);
-extern int  isdn_readbchan_tty(int, int, struct tty_struct *, int);
-extern int  isdn_get_free_channel(int, int, int, int, int, char *);
-extern int  isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
-extern int  register_isdn(isdn_if * i);
-extern int  isdn_msncmp( const char *,  const char *);
+extern int isdn_getnum(char **);
+extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *);
+extern int isdn_readbchan_tty(int, int, struct tty_struct *, int);
+extern int isdn_get_free_channel(int, int, int, int, int, char *);
+extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
+extern int register_isdn(isdn_if *i);
+extern int isdn_msncmp(const char *,  const char *);
 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
 extern void isdn_dumppkt(char *, u_char *, int, int);
 #endif
diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c
index d568689..91d5730 100644
--- a/drivers/isdn/i4l/isdn_concap.c
+++ b/drivers/isdn/i4l/isdn_concap.c
@@ -1,5 +1,5 @@
 /* $Id: isdn_concap.c,v 1.1.2.2 2004/01/12 22:37:19 keil Exp $
- * 
+ *
  * Linux ISDN subsystem, protocol encapsulation
  *
  * This software may be used and distributed according to the terms
@@ -25,57 +25,57 @@
    protocols that require for reliable datalink semantics. That means:
 
    - before any data is to be submitted the connection must explicitly
-     be set up.
+   be set up.
    - after the successful set up of the connection is signalled the
-     connection is considered to be reliably up.
+   connection is considered to be reliably up.
 
-   Auto-dialing ist not compatible with this requirements. Thus, auto-dialing 
+   Auto-dialing ist not compatible with this requirements. Thus, auto-dialing
    is completely bypassed.
 
    It might be possible to implement a (non standardized) datalink protocol
    that provides a reliable data link service while using some auto dialing
    mechanism. Such a protocol would need an auxiliary channel (i.e. user-user-
    signaling on the D-channel) while the B-channel is down.
-   */
+*/
 
 
 static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
 {
-	struct net_device *ndev = concap -> net_dev;
+	struct net_device *ndev = concap->net_dev;
 	isdn_net_dev *nd = ((isdn_net_local *) netdev_priv(ndev))->netdev;
 	isdn_net_local *lp = isdn_net_get_locked_lp(nd);
 
-	IX25DEBUG( "isdn_concap_dl_data_req: %s \n", concap->net_dev->name);
+	IX25DEBUG("isdn_concap_dl_data_req: %s \n", concap->net_dev->name);
 	if (!lp) {
-		IX25DEBUG( "isdn_concap_dl_data_req: %s : isdn_net_send_skb returned %d\n", concap -> net_dev -> name, 1);
+		IX25DEBUG("isdn_concap_dl_data_req: %s : isdn_net_send_skb returned %d\n", concap->net_dev->name, 1);
 		return 1;
 	}
 	lp->huptimer = 0;
 	isdn_net_writebuf_skb(lp, skb);
 	spin_unlock_bh(&lp->xmit_lock);
-	IX25DEBUG( "isdn_concap_dl_data_req: %s : isdn_net_send_skb returned %d\n", concap -> net_dev -> name, 0);
+	IX25DEBUG("isdn_concap_dl_data_req: %s : isdn_net_send_skb returned %d\n", concap->net_dev->name, 0);
 	return 0;
 }
 
 
 static int isdn_concap_dl_connect_req(struct concap_proto *concap)
 {
-	struct net_device *ndev = concap -> net_dev;
+	struct net_device *ndev = concap->net_dev;
 	isdn_net_local *lp = netdev_priv(ndev);
 	int ret;
-	IX25DEBUG( "isdn_concap_dl_connect_req: %s \n", ndev -> name);
+	IX25DEBUG("isdn_concap_dl_connect_req: %s \n", ndev->name);
 
 	/* dial ... */
-	ret = isdn_net_dial_req( lp );
-	if ( ret ) IX25DEBUG("dialing failed\n");
+	ret = isdn_net_dial_req(lp);
+	if (ret) IX25DEBUG("dialing failed\n");
 	return ret;
 }
 
 static int isdn_concap_dl_disconn_req(struct concap_proto *concap)
 {
-	IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name);
+	IX25DEBUG("isdn_concap_dl_disconn_req: %s \n", concap->net_dev->name);
 
-	isdn_net_hangup( concap -> net_dev );
+	isdn_net_hangup(concap->net_dev);
 	return 0;
 }
 
@@ -88,10 +88,10 @@ struct concap_device_ops isdn_concap_reliable_dl_dops = {
 /* The following should better go into a dedicated source file such that
    this sourcefile does not need to include any protocol specific header
    files. For now:
-   */
-struct concap_proto * isdn_concap_new( int encap )
+*/
+struct concap_proto *isdn_concap_new(int encap)
 {
-	switch ( encap ) {
+	switch (encap) {
 	case ISDN_NET_ENCAP_X25IFACE:
 		return isdn_x25iface_proto_new();
 	}
diff --git a/drivers/isdn/i4l/isdn_concap.h b/drivers/isdn/i4l/isdn_concap.h
index 6ac7e04..cd7e3ba 100644
--- a/drivers/isdn/i4l/isdn_concap.h
+++ b/drivers/isdn/i4l/isdn_concap.h
@@ -8,6 +8,4 @@
  */
 
 extern struct concap_device_ops isdn_concap_reliable_dl_dops;
-extern struct concap_proto * isdn_concap_new( int );
-
-
+extern struct concap_proto *isdn_concap_new(int);
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 802ab87..babc621 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -9,7 +9,7 @@
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02 
+ * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02
  *                                       guy@traverse.com.au
  * Outgoing calls - looks for a 'V' in first char of dialed number
  * Incoming calls - checks first character of eaz as follows:
@@ -18,7 +18,7 @@
  *   'B'     - accept BOTH DATA and DOV types
  *
  * Jan 2001: fix CISCO HDLC      Bjoern A. Zeeb <i4l@zabbadoz.net>
- *           for info on the protocol, see 
+ *           for info on the protocol, see
  *           http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt
  */
 
@@ -40,7 +40,7 @@
 
 
 /*
- * Outline of new tbusy handling: 
+ * Outline of new tbusy handling:
  *
  * Old method, roughly spoken, consisted of setting tbusy when entering
  * isdn_net_start_xmit() and at several other locations and clearing
@@ -59,14 +59,14 @@
  * Most of the changes were pretty obvious and basically done by HE already.
  *
  * One problem of the isdn net device code is that is uses struct net_device
- * for masters and slaves. However, only master interface are registered to 
- * the network layer, and therefore, it only makes sense to call netif_* 
+ * for masters and slaves. However, only master interface are registered to
+ * the network layer, and therefore, it only makes sense to call netif_*
  * functions on them.
  *
  * --KG
  */
 
-/* 
+/*
  * Find out if the netdevice has been ifup-ed yet.
  * For slaves, look at the corresponding master.
  */
@@ -74,8 +74,8 @@ static __inline__ int isdn_net_device_started(isdn_net_dev *n)
 {
 	isdn_net_local *lp = n->local;
 	struct net_device *dev;
-	
-	if (lp->master) 
+
+	if (lp->master)
 		dev = lp->master;
 	else
 		dev = n->dev;
@@ -88,7 +88,7 @@ static __inline__ int isdn_net_device_started(isdn_net_dev *n)
  */
 static __inline__ void isdn_net_device_wake_queue(isdn_net_local *lp)
 {
-	if (lp->master) 
+	if (lp->master)
 		netif_wake_queue(lp->master);
 	else
 		netif_wake_queue(lp->netdev->dev);
@@ -108,7 +108,7 @@ static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp)
 
 /*
  * find out if the net_device which this lp belongs to (lp can be
- * master or slave) is busy. It's busy iff all (master and slave) 
+ * master or slave) is busy. It's busy iff all (master and slave)
  * queues are busy
  */
 static __inline__ int isdn_net_device_busy(isdn_net_local *lp)
@@ -124,7 +124,7 @@ static __inline__ int isdn_net_device_busy(isdn_net_local *lp)
 		nd = ISDN_MASTER_PRIV(lp)->netdev;
 	else
 		nd = lp->netdev;
-	
+
 	spin_lock_irqsave(&nd->queue_lock, flags);
 	nlp = lp->next;
 	while (nlp != lp) {
@@ -155,7 +155,7 @@ static __inline__ void isdn_net_dec_frame_cnt(isdn_net_local *lp)
 		} else {
 			isdn_net_device_wake_queue(lp);
 		}
-       }                                                                      
+	}
 }
 
 static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
@@ -163,36 +163,36 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
 	atomic_set(&lp->frame_cnt, 0);
 }
 
-/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just 
+/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just
  * to be safe.
  * For 2.3.x we push it up to 20 secs, because call establishment
- * (in particular callback) may take such a long time, and we 
+ * (in particular callback) may take such a long time, and we
  * don't want confusing messages in the log. However, there is a slight
  * possibility that this large timeout will break other things like MPPP,
  * which might rely on the tx timeout. If so, we'll find out this way...
  */
 
-#define ISDN_NET_TX_TIMEOUT (20*HZ) 
+#define ISDN_NET_TX_TIMEOUT (20 * HZ)
 
 /* Prototypes */
 
 static int isdn_net_force_dial_lp(isdn_net_local *);
 static netdev_tx_t isdn_net_start_xmit(struct sk_buff *,
-					     struct net_device *);
+				       struct net_device *);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
 char *isdn_net_revision = "$Revision: 1.1.2.2 $";
 
- /*
-  * Code for raw-networking over ISDN
-  */
+/*
+ * Code for raw-networking over ISDN
+ */
 
 static void
 isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
 {
-	if(skb) {
+	if (skb) {
 
 		u_short proto = ntohs(skb->protocol);
 
@@ -200,13 +200,13 @@ isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
 		       dev->name,
 		       (reason != NULL) ? reason : "unknown",
 		       (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "");
-		
+
 		dst_link_failure(skb);
 	}
 	else {  /* dial not triggered by rawIP packet */
 		printk(KERN_DEBUG "isdn_net: %s: %s\n",
-			   dev->name,
-			   (reason != NULL) ? reason : "reason unknown");
+		       dev->name,
+		       (reason != NULL) ? reason : "reason unknown");
 	}
 }
 
@@ -214,14 +214,14 @@ static void
 isdn_net_reset(struct net_device *dev)
 {
 #ifdef CONFIG_ISDN_X25
-	struct concap_device_ops * dops =
-		((isdn_net_local *) netdev_priv(dev))->dops;
-	struct concap_proto * cprot =
-		((isdn_net_local *) netdev_priv(dev))->netdev->cprot;
+	struct concap_device_ops *dops =
+		((isdn_net_local *)netdev_priv(dev))->dops;
+	struct concap_proto *cprot =
+		((isdn_net_local *)netdev_priv(dev))->netdev->cprot;
 #endif
 #ifdef CONFIG_ISDN_X25
-	if( cprot && cprot -> pops && dops )
-		cprot -> pops -> restart ( cprot, dev, dops );
+	if (cprot && cprot->pops && dops)
+		cprot->pops->restart(cprot, dev, dops);
 #endif
 }
 
@@ -248,7 +248,7 @@ isdn_net_open(struct net_device *dev)
 		 */
 		struct in_ifaddr *ifa = in_dev->ifa_list;
 		if (ifa != NULL)
-			memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
+			memcpy(dev->dev_addr + 2, &ifa->ifa_local, 4);
 	}
 
 	/* If this interface has slaves, start them also */
@@ -267,7 +267,7 @@ isdn_net_open(struct net_device *dev)
  * Assign an ISDN-channel to a net-interface
  */
 static void
-isdn_net_bind_channel(isdn_net_local * lp, int idx)
+isdn_net_bind_channel(isdn_net_local *lp, int idx)
 {
 	lp->flags |= ISDN_NET_CONNECTED;
 	lp->isdn_device = dev->drvmap[idx];
@@ -280,7 +280,7 @@ isdn_net_bind_channel(isdn_net_local * lp, int idx)
  * unbind a net-interface (resets interface after an error)
  */
 static void
-isdn_net_unbind_channel(isdn_net_local * lp)
+isdn_net_unbind_channel(isdn_net_local *lp)
 {
 	skb_queue_purge(&lp->super_tx_queue);
 
@@ -288,7 +288,7 @@ isdn_net_unbind_channel(isdn_net_local * lp)
 		/* Moral equivalent of dev_purge_queues():
 		   BEWARE! This chunk of code cannot be called from hardware
 		   interrupt handler. I hope it is true. --ANK
-		 */
+		*/
 		qdisc_reset_all_tx(lp->netdev->dev);
 	}
 	lp->dialstate = 0;
@@ -368,7 +368,7 @@ isdn_net_autohup(void)
 					isdn_net_hangup(p->dev);
 			}
 
-			if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) {
+			if (dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) {
 				isdn_net_hangup(p->dev);
 				break;
 			}
@@ -403,143 +403,143 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
 		struct concap_proto_ops *pops = cprot ? cprot->pops : NULL;
 #endif
 		switch (cmd) {
-			case ISDN_STAT_BSENT:
-				/* A packet has successfully been sent out */
-				if ((lp->flags & ISDN_NET_CONNECTED) &&
-				    (!lp->dialstate)) {
-					isdn_net_dec_frame_cnt(lp);
-					lp->stats.tx_packets++;
-					lp->stats.tx_bytes += c->parm.length;
-				}
+		case ISDN_STAT_BSENT:
+			/* A packet has successfully been sent out */
+			if ((lp->flags & ISDN_NET_CONNECTED) &&
+			    (!lp->dialstate)) {
+				isdn_net_dec_frame_cnt(lp);
+				lp->stats.tx_packets++;
+				lp->stats.tx_bytes += c->parm.length;
+			}
+			return 1;
+		case ISDN_STAT_DCONN:
+			/* D-Channel is up */
+			switch (lp->dialstate) {
+			case 4:
+			case 7:
+			case 8:
+				lp->dialstate++;
 				return 1;
-			case ISDN_STAT_DCONN:
-				/* D-Channel is up */
-				switch (lp->dialstate) {
-					case 4:
-					case 7:
-					case 8:
-						lp->dialstate++;
-						return 1;
-					case 12:
-						lp->dialstate = 5;
-						return 1;
-				}
-				break;
-			case ISDN_STAT_DHUP:
-				/* Either D-Channel-hangup or error during dialout */
+			case 12:
+				lp->dialstate = 5;
+				return 1;
+			}
+			break;
+		case ISDN_STAT_DHUP:
+			/* Either D-Channel-hangup or error during dialout */
 #ifdef CONFIG_ISDN_X25
-				/* If we are not connencted then dialing had
-				   failed. If there are generic encap protocol
-				   receiver routines signal the closure of
-				   the link*/
-
-				if( !(lp->flags & ISDN_NET_CONNECTED)
-				    && pops && pops -> disconn_ind )
-					pops -> disconn_ind(cprot);
+			/* If we are not connencted then dialing had
+			   failed. If there are generic encap protocol
+			   receiver routines signal the closure of
+			   the link*/
+
+			if (!(lp->flags & ISDN_NET_CONNECTED)
+			    && pops && pops->disconn_ind)
+				pops->disconn_ind(cprot);
 #endif /* CONFIG_ISDN_X25 */
-				if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
-					if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
-						isdn_net_ciscohdlck_disconnected(lp);
+			if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
+				if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
+					isdn_net_ciscohdlck_disconnected(lp);
 #ifdef CONFIG_ISDN_PPP
-					if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-						isdn_ppp_free(lp);
+				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+					isdn_ppp_free(lp);
 #endif
-					isdn_net_lp_disconnected(lp);
-					isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
-					printk(KERN_INFO "%s: remote hangup\n", p->dev->name);
-					printk(KERN_INFO "%s: Chargesum is %d\n", p->dev->name,
-					       lp->charge);
-					isdn_net_unbind_channel(lp);
-					return 1;
-				}
-				break;
+				isdn_net_lp_disconnected(lp);
+				isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
+				printk(KERN_INFO "%s: remote hangup\n", p->dev->name);
+				printk(KERN_INFO "%s: Chargesum is %d\n", p->dev->name,
+				       lp->charge);
+				isdn_net_unbind_channel(lp);
+				return 1;
+			}
+			break;
 #ifdef CONFIG_ISDN_X25
-			case ISDN_STAT_BHUP:
-				/* B-Channel-hangup */
-				/* try if there are generic encap protocol
-				   receiver routines and signal the closure of
-				   the link */
-				if( pops  &&  pops -> disconn_ind ){
-						pops -> disconn_ind(cprot);
-						return 1;
-					}
-				break;
+		case ISDN_STAT_BHUP:
+			/* B-Channel-hangup */
+			/* try if there are generic encap protocol
+			   receiver routines and signal the closure of
+			   the link */
+			if (pops && pops->disconn_ind) {
+				pops->disconn_ind(cprot);
+				return 1;
+			}
+			break;
 #endif /* CONFIG_ISDN_X25 */
-			case ISDN_STAT_BCONN:
-				/* B-Channel is up */
-				isdn_net_zero_frame_cnt(lp);
-				switch (lp->dialstate) {
-					case 5:
-					case 6:
-					case 7:
-					case 8:
-					case 9:
-					case 10:
-					case 12:
-						if (lp->dialstate <= 6) {
-							dev->usage[idx] |= ISDN_USAGE_OUTGOING;
-							isdn_info_update();
-						} else
-							dev->rx_netdev[idx] = p;
-						lp->dialstate = 0;
-						isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
-						if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
-							isdn_net_ciscohdlck_connected(lp);
-						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
-							if (lp->master) { /* is lp a slave? */
-								isdn_net_dev *nd = ISDN_MASTER_PRIV(lp)->netdev;
-								isdn_net_add_to_bundle(nd, lp);
-							}
-						}
-						printk(KERN_INFO "isdn_net: %s connected\n", p->dev->name);
-						/* If first Chargeinfo comes before B-Channel connect,
-						 * we correct the timestamp here.
-						 */
-						lp->chargetime = jiffies;
+		case ISDN_STAT_BCONN:
+			/* B-Channel is up */
+			isdn_net_zero_frame_cnt(lp);
+			switch (lp->dialstate) {
+			case 5:
+			case 6:
+			case 7:
+			case 8:
+			case 9:
+			case 10:
+			case 12:
+				if (lp->dialstate <= 6) {
+					dev->usage[idx] |= ISDN_USAGE_OUTGOING;
+					isdn_info_update();
+				} else
+					dev->rx_netdev[idx] = p;
+				lp->dialstate = 0;
+				isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
+				if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
+					isdn_net_ciscohdlck_connected(lp);
+				if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
+					if (lp->master) { /* is lp a slave? */
+						isdn_net_dev *nd = ISDN_MASTER_PRIV(lp)->netdev;
+						isdn_net_add_to_bundle(nd, lp);
+					}
+				}
+				printk(KERN_INFO "isdn_net: %s connected\n", p->dev->name);
+				/* If first Chargeinfo comes before B-Channel connect,
+				 * we correct the timestamp here.
+				 */
+				lp->chargetime = jiffies;
 
-						/* reset dial-timeout */
-						lp->dialstarted = 0;
-						lp->dialwait_timer = 0;
+				/* reset dial-timeout */
+				lp->dialstarted = 0;
+				lp->dialwait_timer = 0;
 
 #ifdef CONFIG_ISDN_PPP
-						if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-							isdn_ppp_wakeup_daemon(lp);
+				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+					isdn_ppp_wakeup_daemon(lp);
 #endif
 #ifdef CONFIG_ISDN_X25
-						/* try if there are generic concap receiver routines */
-						if( pops )
-							if( pops->connect_ind)
-								pops->connect_ind(cprot);
+				/* try if there are generic concap receiver routines */
+				if (pops)
+					if (pops->connect_ind)
+						pops->connect_ind(cprot);
 #endif /* CONFIG_ISDN_X25 */
-						/* ppp needs to do negotiations first */
-						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
-							isdn_net_device_wake_queue(lp);
-						return 1;
-				}
-				break;
-			case ISDN_STAT_NODCH:
-				/* No D-Channel avail. */
-				if (lp->dialstate == 4) {
-					lp->dialstate--;
-					return 1;
-				}
-				break;
-			case ISDN_STAT_CINF:
-				/* Charge-info from TelCo. Calculate interval between
-				 * charge-infos and set timestamp for last info for
-				 * usage by isdn_net_autohup()
-				 */
-				lp->charge++;
-				if (lp->hupflags & ISDN_HAVECHARGE) {
-					lp->hupflags &= ~ISDN_WAITCHARGE;
-					lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
-				}
-				if (lp->hupflags & ISDN_WAITCHARGE)
-					lp->hupflags |= ISDN_HAVECHARGE;
-				lp->chargetime = jiffies;
-				printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
-				       p->dev->name, lp->chargetime);
+				/* ppp needs to do negotiations first */
+				if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
+					isdn_net_device_wake_queue(lp);
 				return 1;
+			}
+			break;
+		case ISDN_STAT_NODCH:
+			/* No D-Channel avail. */
+			if (lp->dialstate == 4) {
+				lp->dialstate--;
+				return 1;
+			}
+			break;
+		case ISDN_STAT_CINF:
+			/* Charge-info from TelCo. Calculate interval between
+			 * charge-infos and set timestamp for last info for
+			 * usage by isdn_net_autohup()
+			 */
+			lp->charge++;
+			if (lp->hupflags & ISDN_HAVECHARGE) {
+				lp->hupflags &= ~ISDN_WAITCHARGE;
+				lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
+			}
+			if (lp->hupflags & ISDN_WAITCHARGE)
+				lp->hupflags |= ISDN_HAVECHARGE;
+			lp->chargetime = jiffies;
+			printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
+			       p->dev->name, lp->chargetime);
+			return 1;
 		}
 	}
 	return 0;
@@ -562,7 +562,7 @@ isdn_net_dial(void)
 	int anymore = 0;
 	int i;
 	isdn_ctrl cmd;
-        u_char *phone_number;
+	u_char *phone_number;
 
 	while (p) {
 		isdn_net_local *lp = p->local;
@@ -572,249 +572,249 @@ isdn_net_dial(void)
 			printk(KERN_DEBUG "%s: dialstate=%d\n", p->dev->name, lp->dialstate);
 #endif
 		switch (lp->dialstate) {
-			case 0:
-				/* Nothing to do for this interface */
+		case 0:
+			/* Nothing to do for this interface */
+			break;
+		case 1:
+			/* Initiate dialout. Set phone-number-pointer to first number
+			 * of interface.
+			 */
+			lp->dial = lp->phone[1];
+			if (!lp->dial) {
+				printk(KERN_WARNING "%s: phone number deleted?\n",
+				       p->dev->name);
+				isdn_net_hangup(p->dev);
 				break;
-			case 1:
-				/* Initiate dialout. Set phone-number-pointer to first number
-				 * of interface.
-				 */
-				lp->dial = lp->phone[1];
-				if (!lp->dial) {
-					printk(KERN_WARNING "%s: phone number deleted?\n",
-					       p->dev->name);
-					isdn_net_hangup(p->dev);
-					break;
+			}
+			anymore = 1;
+
+			if (lp->dialtimeout > 0)
+				if (lp->dialstarted == 0 || time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
+					lp->dialstarted = jiffies;
+					lp->dialwait_timer = 0;
 				}
-				anymore = 1;
 
-				if(lp->dialtimeout > 0)
-					if(lp->dialstarted == 0 || time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
-						lp->dialstarted = jiffies;
-						lp->dialwait_timer = 0;
+			lp->dialstate++;
+			/* Fall through */
+		case 2:
+			/* Prepare dialing. Clear EAZ, then set EAZ. */
+			cmd.driver = lp->isdn_device;
+			cmd.arg = lp->isdn_channel;
+			cmd.command = ISDN_CMD_CLREAZ;
+			isdn_command(&cmd);
+			sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));
+			cmd.command = ISDN_CMD_SETEAZ;
+			isdn_command(&cmd);
+			lp->dialretry = 0;
+			anymore = 1;
+			lp->dialstate++;
+			/* Fall through */
+		case 3:
+			/* Setup interface, dial current phone-number, switch to next number.
+			 * If list of phone-numbers is exhausted, increment
+			 * retry-counter.
+			 */
+			if (dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
+				char *s;
+				if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+					s = "dial suppressed: isdn system stopped";
+				else
+					s = "dial suppressed: dialmode `off'";
+				isdn_net_unreachable(p->dev, NULL, s);
+				isdn_net_hangup(p->dev);
+				break;
+			}
+			cmd.driver = lp->isdn_device;
+			cmd.command = ISDN_CMD_SETL2;
+			cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
+			isdn_command(&cmd);
+			cmd.driver = lp->isdn_device;
+			cmd.command = ISDN_CMD_SETL3;
+			cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
+			isdn_command(&cmd);
+			cmd.driver = lp->isdn_device;
+			cmd.arg = lp->isdn_channel;
+			if (!lp->dial) {
+				printk(KERN_WARNING "%s: phone number deleted?\n",
+				       p->dev->name);
+				isdn_net_hangup(p->dev);
+				break;
+			}
+			if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
+				lp->dialstate = 4;
+				printk(KERN_INFO "%s: Open leased line ...\n", p->dev->name);
+			} else {
+				if (lp->dialtimeout > 0)
+					if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
+						lp->dialwait_timer = jiffies + lp->dialwait;
+						lp->dialstarted = 0;
+						isdn_net_unreachable(p->dev, NULL, "dial: timed out");
+						isdn_net_hangup(p->dev);
+						break;
 					}
 
-				lp->dialstate++;
-				/* Fall through */
-			case 2:
-				/* Prepare dialing. Clear EAZ, then set EAZ. */
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				cmd.command = ISDN_CMD_CLREAZ;
-				isdn_command(&cmd);
-				sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));
-				cmd.command = ISDN_CMD_SETEAZ;
-				isdn_command(&cmd);
-				lp->dialretry = 0;
-				anymore = 1;
-				lp->dialstate++;
-				/* Fall through */
-			case 3:
-				/* Setup interface, dial current phone-number, switch to next number.
-				 * If list of phone-numbers is exhausted, increment
-				 * retry-counter.
-				 */
-				if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
-					char *s;
-					if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-						s = "dial suppressed: isdn system stopped";
-					else
-						s = "dial suppressed: dialmode `off'";
-					isdn_net_unreachable(p->dev, NULL, s);
-					isdn_net_hangup(p->dev);
-					break;
-				}
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL2;
-				cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
-				isdn_command(&cmd);
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL3;
-				cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
-				isdn_command(&cmd);
 				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				if (!lp->dial) {
-					printk(KERN_WARNING "%s: phone number deleted?\n",
-					       p->dev->name);
-					isdn_net_hangup(p->dev);
-					break;
+				cmd.command = ISDN_CMD_DIAL;
+				cmd.parm.setup.si2 = 0;
+
+				/* check for DOV */
+				phone_number = lp->dial->num;
+				if ((*phone_number == 'v') ||
+				    (*phone_number == 'V')) { /* DOV call */
+					cmd.parm.setup.si1 = 1;
+				} else { /* DATA call */
+					cmd.parm.setup.si1 = 7;
 				}
-				if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
-					lp->dialstate = 4;
-					printk(KERN_INFO "%s: Open leased line ...\n", p->dev->name);
-				} else {
-					if(lp->dialtimeout > 0)
-						if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
-							lp->dialwait_timer = jiffies + lp->dialwait;
-							lp->dialstarted = 0;
-							isdn_net_unreachable(p->dev, NULL, "dial: timed out");
-							isdn_net_hangup(p->dev);
-							break;
-						}
 
-					cmd.driver = lp->isdn_device;
-					cmd.command = ISDN_CMD_DIAL;
-					cmd.parm.setup.si2 = 0;
-
-                                        /* check for DOV */
-                                        phone_number = lp->dial->num;
-                                        if ((*phone_number == 'v') ||
-					    (*phone_number == 'V')) { /* DOV call */
-                                                cmd.parm.setup.si1 = 1;
-                                        } else { /* DATA call */
-                                                cmd.parm.setup.si1 = 7;
-					}
+				strcpy(cmd.parm.setup.phone, phone_number);
+				/*
+				 * Switch to next number or back to start if at end of list.
+				 */
+				if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
+					lp->dial = lp->phone[1];
+					lp->dialretry++;
 
-					strcpy(cmd.parm.setup.phone, phone_number);
-					/*
-					 * Switch to next number or back to start if at end of list.
-					 */
-					if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
-						lp->dial = lp->phone[1];
-						lp->dialretry++;
-
-						if (lp->dialretry > lp->dialmax) {
-							if (lp->dialtimeout == 0) {
-								lp->dialwait_timer = jiffies + lp->dialwait;
-								lp->dialstarted = 0;
-								isdn_net_unreachable(p->dev, NULL, "dial: tried all numbers dialmax times");
-							}
-							isdn_net_hangup(p->dev);
-							break;
+					if (lp->dialretry > lp->dialmax) {
+						if (lp->dialtimeout == 0) {
+							lp->dialwait_timer = jiffies + lp->dialwait;
+							lp->dialstarted = 0;
+							isdn_net_unreachable(p->dev, NULL, "dial: tried all numbers dialmax times");
 						}
+						isdn_net_hangup(p->dev);
+						break;
 					}
-					sprintf(cmd.parm.setup.eazmsn, "%s",
-						isdn_map_eaz2msn(lp->msn, cmd.driver));
-					i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);
-					if (i >= 0) {
-						strcpy(dev->num[i], cmd.parm.setup.phone);
-						dev->usage[i] |= ISDN_USAGE_OUTGOING;
-						isdn_info_update();
-					}
-					printk(KERN_INFO "%s: dialing %d %s... %s\n", p->dev->name,
-					       lp->dialretry, cmd.parm.setup.phone,
-					       (cmd.parm.setup.si1 == 1) ? "DOV" : "");
-					lp->dtimer = 0;
-#ifdef ISDN_DEBUG_NET_DIAL
-					printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
-					       lp->isdn_channel);
-#endif
-					isdn_command(&cmd);
 				}
-				lp->huptimer = 0;
-				lp->outgoing = 1;
-				if (lp->chargeint) {
-					lp->hupflags |= ISDN_HAVECHARGE;
-					lp->hupflags &= ~ISDN_WAITCHARGE;
-				} else {
-					lp->hupflags |= ISDN_WAITCHARGE;
-					lp->hupflags &= ~ISDN_HAVECHARGE;
+				sprintf(cmd.parm.setup.eazmsn, "%s",
+					isdn_map_eaz2msn(lp->msn, cmd.driver));
+				i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);
+				if (i >= 0) {
+					strcpy(dev->num[i], cmd.parm.setup.phone);
+					dev->usage[i] |= ISDN_USAGE_OUTGOING;
+					isdn_info_update();
 				}
-				anymore = 1;
-				lp->dialstate =
-				    (lp->cbdelay &&
-				     (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;
-				break;
-			case 4:
-				/* Wait for D-Channel-connect.
-				 * If timeout, switch back to state 3.
-				 * Dialmax-handling moved to state 3.
-				 */
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
-					lp->dialstate = 3;
-				anymore = 1;
-				break;
-			case 5:
-				/* Got D-Channel-Connect, send B-Channel-request */
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				cmd.command = ISDN_CMD_ACCEPTB;
-				anymore = 1;
+				printk(KERN_INFO "%s: dialing %d %s... %s\n", p->dev->name,
+				       lp->dialretry, cmd.parm.setup.phone,
+				       (cmd.parm.setup.si1 == 1) ? "DOV" : "");
 				lp->dtimer = 0;
-				lp->dialstate++;
+#ifdef ISDN_DEBUG_NET_DIAL
+				printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
+				       lp->isdn_channel);
+#endif
 				isdn_command(&cmd);
-				break;
-			case 6:
-				/* Wait for B- or D-Channel-connect. If timeout,
-				 * switch back to state 3.
-				 */
+			}
+			lp->huptimer = 0;
+			lp->outgoing = 1;
+			if (lp->chargeint) {
+				lp->hupflags |= ISDN_HAVECHARGE;
+				lp->hupflags &= ~ISDN_WAITCHARGE;
+			} else {
+				lp->hupflags |= ISDN_WAITCHARGE;
+				lp->hupflags &= ~ISDN_HAVECHARGE;
+			}
+			anymore = 1;
+			lp->dialstate =
+				(lp->cbdelay &&
+				 (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;
+			break;
+		case 4:
+			/* Wait for D-Channel-connect.
+			 * If timeout, switch back to state 3.
+			 * Dialmax-handling moved to state 3.
+			 */
+			if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
+				lp->dialstate = 3;
+			anymore = 1;
+			break;
+		case 5:
+			/* Got D-Channel-Connect, send B-Channel-request */
+			cmd.driver = lp->isdn_device;
+			cmd.arg = lp->isdn_channel;
+			cmd.command = ISDN_CMD_ACCEPTB;
+			anymore = 1;
+			lp->dtimer = 0;
+			lp->dialstate++;
+			isdn_command(&cmd);
+			break;
+		case 6:
+			/* Wait for B- or D-Channel-connect. If timeout,
+			 * switch back to state 3.
+			 */
 #ifdef ISDN_DEBUG_NET_DIAL
-				printk(KERN_DEBUG "dialtimer2: %d\n", lp->dtimer);
+			printk(KERN_DEBUG "dialtimer2: %d\n", lp->dtimer);
 #endif
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
-					lp->dialstate = 3;
-				anymore = 1;
-				break;
-			case 7:
-				/* Got incoming Call, setup L2 and L3 protocols,
-				 * then wait for D-Channel-connect
-				 */
+			if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
+				lp->dialstate = 3;
+			anymore = 1;
+			break;
+		case 7:
+			/* Got incoming Call, setup L2 and L3 protocols,
+			 * then wait for D-Channel-connect
+			 */
 #ifdef ISDN_DEBUG_NET_DIAL
-				printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
+			printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
 #endif
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL2;
-				cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
-				isdn_command(&cmd);
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL3;
-				cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
-				isdn_command(&cmd);
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15)
-					isdn_net_hangup(p->dev);
-				else {
-					anymore = 1;
-					lp->dialstate++;
-				}
-				break;
-			case 9:
-				/* Got incoming D-Channel-Connect, send B-Channel-request */
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				cmd.command = ISDN_CMD_ACCEPTB;
-				isdn_command(&cmd);
+			cmd.driver = lp->isdn_device;
+			cmd.command = ISDN_CMD_SETL2;
+			cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
+			isdn_command(&cmd);
+			cmd.driver = lp->isdn_device;
+			cmd.command = ISDN_CMD_SETL3;
+			cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
+			isdn_command(&cmd);
+			if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15)
+				isdn_net_hangup(p->dev);
+			else {
 				anymore = 1;
-				lp->dtimer = 0;
 				lp->dialstate++;
-				break;
-			case 8:
-			case 10:
-				/*  Wait for B- or D-channel-connect */
+			}
+			break;
+		case 9:
+			/* Got incoming D-Channel-Connect, send B-Channel-request */
+			cmd.driver = lp->isdn_device;
+			cmd.arg = lp->isdn_channel;
+			cmd.command = ISDN_CMD_ACCEPTB;
+			isdn_command(&cmd);
+			anymore = 1;
+			lp->dtimer = 0;
+			lp->dialstate++;
+			break;
+		case 8:
+		case 10:
+			/*  Wait for B- or D-channel-connect */
 #ifdef ISDN_DEBUG_NET_DIAL
-				printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
+			printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
 #endif
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
-					isdn_net_hangup(p->dev);
-				else
-					anymore = 1;
-				break;
-			case 11:
-				/* Callback Delay */
-				if (lp->dtimer++ > lp->cbdelay)
-					lp->dialstate = 1;
-				anymore = 1;
-				break;
-			case 12:
-				/* Remote does callback. Hangup after cbdelay, then wait for incoming
-				 * call (in state 4).
-				 */
-				if (lp->dtimer++ > lp->cbdelay)
-				{
-					printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->dev->name);
-					lp->dtimer = 0;
-					lp->dialstate = 4;
-					cmd.driver = lp->isdn_device;
-					cmd.command = ISDN_CMD_HANGUP;
-					cmd.arg = lp->isdn_channel;
-					isdn_command(&cmd);
-					isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
-				}
+			if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
+				isdn_net_hangup(p->dev);
+			else
 				anymore = 1;
-				break;
-			default:
-				printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
-				       lp->dialstate, p->dev->name);
+			break;
+		case 11:
+			/* Callback Delay */
+			if (lp->dtimer++ > lp->cbdelay)
+				lp->dialstate = 1;
+			anymore = 1;
+			break;
+		case 12:
+			/* Remote does callback. Hangup after cbdelay, then wait for incoming
+			 * call (in state 4).
+			 */
+			if (lp->dtimer++ > lp->cbdelay)
+			{
+				printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->dev->name);
+				lp->dtimer = 0;
+				lp->dialstate = 4;
+				cmd.driver = lp->isdn_device;
+				cmd.command = ISDN_CMD_HANGUP;
+				cmd.arg = lp->isdn_channel;
+				isdn_command(&cmd);
+				isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
+			}
+			anymore = 1;
+			break;
+		default:
+			printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
+			       lp->dialstate, p->dev->name);
 		}
 		p = (isdn_net_dev *) p->next;
 	}
@@ -839,8 +839,8 @@ isdn_net_hangup(struct net_device *d)
 			isdn_net_local *slp = ISDN_SLAVE_PRIV(lp);
 			if (slp->flags & ISDN_NET_CONNECTED) {
 				printk(KERN_INFO
-					"isdn_net: hang up slave %s before %s\n",
-					lp->slave->name, d->name);
+				       "isdn_net: hang up slave %s before %s\n",
+				       lp->slave->name, d->name);
 				isdn_net_hangup(lp->slave);
 			}
 		}
@@ -854,8 +854,8 @@ isdn_net_hangup(struct net_device *d)
 		/* try if there are generic encap protocol
 		   receiver routines and signal the closure of
 		   the link */
-		if( pops && pops -> disconn_ind )
-		  pops -> disconn_ind(cprot);
+		if (pops && pops->disconn_ind)
+			pops->disconn_ind(cprot);
 #endif /* CONFIG_ISDN_X25 */
 
 		cmd.driver = lp->isdn_device;
@@ -874,7 +874,7 @@ typedef struct {
 } ip_ports;
 
 static void
-isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
+isdn_net_log_skb(struct sk_buff *skb, isdn_net_local *lp)
 {
 	/* hopefully, this was set correctly */
 	const u_char *p = skb_network_header(skb);
@@ -887,72 +887,72 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
 	/* This check stolen from 2.1.72 dev_queue_xmit_nit() */
 	if (p < skb->data || skb->network_header >= skb->tail) {
 		/* fall back to old isdn_net_log_packet method() */
-		char * buf = skb->data;
+		char *buf = skb->data;
 
 		printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->netdev->dev->name);
 		p = buf;
 		proto = ETH_P_IP;
 		switch (lp->p_encap) {
-			case ISDN_NET_ENCAP_IPTYP:
-				proto = ntohs(*(__be16 *)&buf[0]);
-				p = &buf[2];
-				break;
-			case ISDN_NET_ENCAP_ETHER:
-				proto = ntohs(*(__be16 *)&buf[12]);
-				p = &buf[14];
-				break;
-			case ISDN_NET_ENCAP_CISCOHDLC:
-				proto = ntohs(*(__be16 *)&buf[2]);
-				p = &buf[4];
-				break;
+		case ISDN_NET_ENCAP_IPTYP:
+			proto = ntohs(*(__be16 *)&buf[0]);
+			p = &buf[2];
+			break;
+		case ISDN_NET_ENCAP_ETHER:
+			proto = ntohs(*(__be16 *)&buf[12]);
+			p = &buf[14];
+			break;
+		case ISDN_NET_ENCAP_CISCOHDLC:
+			proto = ntohs(*(__be16 *)&buf[2]);
+			p = &buf[4];
+			break;
 #ifdef CONFIG_ISDN_PPP
-			case ISDN_NET_ENCAP_SYNCPPP:
-				proto = ntohs(skb->protocol);
-				p = &buf[IPPP_MAX_HEADER];
-				break;
+		case ISDN_NET_ENCAP_SYNCPPP:
+			proto = ntohs(skb->protocol);
+			p = &buf[IPPP_MAX_HEADER];
+			break;
 #endif
 		}
 	}
 	data_ofs = ((p[0] & 15) * 4);
 	switch (proto) {
-		case ETH_P_IP:
-			switch (p[9]) {
-				case 1:
-					strcpy(addinfo, " ICMP");
-					break;
-				case 2:
-					strcpy(addinfo, " IGMP");
-					break;
-				case 4:
-					strcpy(addinfo, " IPIP");
-					break;
-				case 6:
-					ipp = (ip_ports *) (&p[data_ofs]);
-					sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),
-						ntohs(ipp->dest));
-					break;
-				case 8:
-					strcpy(addinfo, " EGP");
-					break;
-				case 12:
-					strcpy(addinfo, " PUP");
-					break;
-				case 17:
-					ipp = (ip_ports *) (&p[data_ofs]);
-					sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),
-						ntohs(ipp->dest));
-					break;
-				case 22:
-					strcpy(addinfo, " IDP");
-					break;
-			}
-			printk(KERN_INFO "OPEN: %pI4 -> %pI4%s\n",
-			       p + 12, p + 16, addinfo);
+	case ETH_P_IP:
+		switch (p[9]) {
+		case 1:
+			strcpy(addinfo, " ICMP");
+			break;
+		case 2:
+			strcpy(addinfo, " IGMP");
+			break;
+		case 4:
+			strcpy(addinfo, " IPIP");
+			break;
+		case 6:
+			ipp = (ip_ports *) (&p[data_ofs]);
+			sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),
+				ntohs(ipp->dest));
+			break;
+		case 8:
+			strcpy(addinfo, " EGP");
+			break;
+		case 12:
+			strcpy(addinfo, " PUP");
+			break;
+		case 17:
+			ipp = (ip_ports *) (&p[data_ofs]);
+			sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),
+				ntohs(ipp->dest));
 			break;
-		case ETH_P_ARP:
-			printk(KERN_INFO "OPEN: ARP %pI4 -> *.*.*.* ?%pI4\n",
-			       p + 14, p + 24);
+		case 22:
+			strcpy(addinfo, " IDP");
 			break;
+		}
+		printk(KERN_INFO "OPEN: %pI4 -> %pI4%s\n",
+		       p + 12, p + 16, addinfo);
+		break;
+	case ETH_P_ARP:
+		printk(KERN_INFO "OPEN: ARP %pI4 -> *.*.*.* ?%pI4\n",
+		       p + 14, p + 24);
+		break;
 	}
 }
 
@@ -964,7 +964,7 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
 void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
 {
 	if (in_irq()) {
-		// we can't grab the lock from irq context, 
+		// we can't grab the lock from irq context,
 		// so we just queue the packet
 		skb_queue_tail(&lp->super_tx_queue, skb);
 		schedule_work(&lp->tqueue);
@@ -993,12 +993,12 @@ static void isdn_net_softint(struct work_struct *work)
 		skb = skb_dequeue(&lp->super_tx_queue);
 		if (!skb)
 			break;
-		isdn_net_writebuf_skb(lp, skb);                                
+		isdn_net_writebuf_skb(lp, skb);
 	}
 	spin_unlock_bh(&lp->xmit_lock);
 }
 
-/* 
+/*
  * all frames sent from the (net) LL to a HL driver should go via this function
  * it's serialized by the caller holding the lp->xmit_lock spinlock
  */
@@ -1024,12 +1024,12 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
 		printk(KERN_WARNING "%s: HL driver queue full\n", lp->netdev->dev->name);
 		goto error;
 	}
-	
+
 	lp->transcount += len;
 	isdn_net_inc_frame_cnt(lp);
 	return;
 
- error:
+error:
 	dev_kfree_skb(skb);
 	lp->stats.tx_errors++;
 
@@ -1129,14 +1129,14 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
 }
 
 
-static void isdn_net_tx_timeout(struct net_device * ndev)
+static void isdn_net_tx_timeout(struct net_device *ndev)
 {
 	isdn_net_local *lp = netdev_priv(ndev);
 
 	printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate);
-	if (!lp->dialstate){
+	if (!lp->dialstate) {
 		lp->stats.tx_errors++;
-                /*
+		/*
 		 * There is a certain probability that this currently
 		 * works at all because if we always wake up the interface,
 		 * then upper layer will try to send the next packet
@@ -1149,7 +1149,7 @@ static void isdn_net_tx_timeout(struct net_device * ndev)
 		 *
 		 * actually, this may not matter at all, because ISDN hardware
 		 * should not see transmitter hangs at all IMO
-		 * changed KERN_DEBUG to KERN_WARNING to find out if this is 
+		 * changed KERN_DEBUG to KERN_WARNING to find out if this is
 		 * ever called   --KG
 		 */
 	}
@@ -1167,27 +1167,27 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
 	isdn_net_local *lp = netdev_priv(ndev);
 #ifdef CONFIG_ISDN_X25
-	struct concap_proto * cprot = lp -> netdev -> cprot;
+	struct concap_proto *cprot = lp->netdev->cprot;
 /* At this point hard_start_xmit() passes control to the encapsulation
    protocol (if present).
    For X.25 auto-dialing is completly bypassed because:
    - It does not conform with the semantics of a reliable datalink
-     service as needed by X.25 PLP.
+   service as needed by X.25 PLP.
    - I don't want that the interface starts dialing when the network layer
-     sends a message which requests to disconnect the lapb link (or if it
-     sends any other message not resulting in data transmission).
+   sends a message which requests to disconnect the lapb link (or if it
+   sends any other message not resulting in data transmission).
    Instead, dialing will be initiated by the encapsulation protocol entity
    when a dl_establish request is received from the upper layer.
 */
-	if (cprot && cprot -> pops) {
-		int ret = cprot -> pops -> encap_and_xmit ( cprot , skb);
+	if (cprot && cprot->pops) {
+		int ret = cprot->pops->encap_and_xmit(cprot, skb);
 
 		if (ret)
 			netif_stop_queue(ndev);
 		return ret;
 	} else
 #endif
-	/* auto-dialing xmit function */
+		/* auto-dialing xmit function */
 	{
 #ifdef ISDN_DEBUG_NET_DUMP
 		u_char *buf;
@@ -1209,12 +1209,12 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 			if (lp->phone[1]) {
 				ulong flags;
 
-				if(lp->dialwait_timer <= 0)
-					if(lp->dialstarted > 0 && lp->dialtimeout > 0 && time_before(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))
+				if (lp->dialwait_timer <= 0)
+					if (lp->dialstarted > 0 && lp->dialtimeout > 0 && time_before(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))
 						lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
 
-				if(lp->dialwait_timer > 0) {
-					if(time_before(jiffies, lp->dialwait_timer)) {
+				if (lp->dialwait_timer > 0) {
+					if (time_before(jiffies, lp->dialwait_timer)) {
 						isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
 						dev_kfree_skb(skb);
 						return NETDEV_TX_OK;
@@ -1224,26 +1224,26 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 				/* Grab a free ISDN-Channel */
 				spin_lock_irqsave(&dev->lock, flags);
 				if (((chi =
-				     isdn_get_free_channel(
-					 		ISDN_USAGE_NET,
-							lp->l2_proto,
-							lp->l3_proto,
-							lp->pre_device,
-						 	lp->pre_channel,
-							lp->msn)
-							) < 0) &&
-					((chi =
-				     isdn_get_free_channel(
-					 		ISDN_USAGE_NET,
-							lp->l2_proto,
-							lp->l3_proto,
-							lp->pre_device,
-							lp->pre_channel^1,
-							lp->msn)
-							) < 0)) {
+				      isdn_get_free_channel(
+					      ISDN_USAGE_NET,
+					      lp->l2_proto,
+					      lp->l3_proto,
+					      lp->pre_device,
+					      lp->pre_channel,
+					      lp->msn)
+					     ) < 0) &&
+				    ((chi =
+				      isdn_get_free_channel(
+					      ISDN_USAGE_NET,
+					      lp->l2_proto,
+					      lp->l3_proto,
+					      lp->pre_device,
+					      lp->pre_channel^1,
+					      lp->msn)
+					    ) < 0)) {
 					spin_unlock_irqrestore(&dev->lock, flags);
 					isdn_net_unreachable(ndev, skb,
-							   "No channel");
+							     "No channel");
 					dev_kfree_skb(skb);
 					return NETDEV_TX_OK;
 				}
@@ -1290,13 +1290,13 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 				return NETDEV_TX_OK;
 			}
 		} else {
-			/* Device is connected to an ISDN channel */ 
+			/* Device is connected to an ISDN channel */
 			ndev->trans_start = jiffies;
 			if (!lp->dialstate) {
 				/* ISDN connection is established, try sending */
 				int ret;
 				ret = (isdn_net_xmit(ndev, skb));
-				if(ret) netif_stop_queue(ndev);
+				if (ret) netif_stop_queue(ndev);
 				return ret;
 			} else
 				netif_stop_queue(ndev);
@@ -1313,13 +1313,13 @@ isdn_net_close(struct net_device *dev)
 {
 	struct net_device *p;
 #ifdef CONFIG_ISDN_X25
-	struct concap_proto * cprot =
-		((isdn_net_local *) netdev_priv(dev))->netdev->cprot;
-	/* printk(KERN_DEBUG "isdn_net_close %s\n" , dev-> name ); */
+	struct concap_proto *cprot =
+		((isdn_net_local *)netdev_priv(dev))->netdev->cprot;
+	/* printk(KERN_DEBUG "isdn_net_close %s\n" , dev-> name); */
 #endif
 
 #ifdef CONFIG_ISDN_X25
-	if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
+	if (cprot && cprot->pops) cprot->pops->close(cprot);
 #endif
 	netif_stop_queue(dev);
 	p = MASTER_TO_SLAVE(dev);
@@ -1327,10 +1327,10 @@ isdn_net_close(struct net_device *dev)
 		/* If this interface has slaves, stop them also */
 		while (p) {
 #ifdef CONFIG_ISDN_X25
-			cprot = ((isdn_net_local *) netdev_priv(p))
-				-> netdev -> cprot;
-			if( cprot && cprot -> pops )
-				cprot -> pops -> close( cprot );
+			cprot = ((isdn_net_local *)netdev_priv(p))
+				->netdev->cprot;
+			if (cprot && cprot->pops)
+				cprot->pops->close(cprot);
 #endif
 			isdn_net_hangup(p);
 			p = MASTER_TO_SLAVE(p);
@@ -1405,7 +1405,7 @@ isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev)
 }
 
 
-/* 
+/*
  * CISCO HDLC keepalive specific stuff
  */
 static struct sk_buff*
@@ -1417,7 +1417,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
 	skb = alloc_skb(hl + len, GFP_ATOMIC);
 	if (skb)
 		skb_reserve(skb, hl);
-	else 
+	else
 		printk("isdn out of mem at %s:%d!\n", __FILE__, __LINE__);
 	return skb;
 }
@@ -1439,52 +1439,52 @@ isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 	switch (cmd) {
 		/* get/set keepalive period */
-		case SIOCGKEEPPERIOD:
-			len = (unsigned long)sizeof(lp->cisco_keepalive_period);
-			if (copy_to_user(ifr->ifr_data,
-				&lp->cisco_keepalive_period, len))
-				rc = -EFAULT;
-			break;
-		case SIOCSKEEPPERIOD:
-			tmp = lp->cisco_keepalive_period;
-			len = (unsigned long)sizeof(lp->cisco_keepalive_period);
-			if (copy_from_user(&period, ifr->ifr_data, len))
-				rc = -EFAULT;
-			if ((period > 0) && (period <= 32767))
-				lp->cisco_keepalive_period = period;
-			else
-				rc = -EINVAL;
-			if (!rc && (tmp != lp->cisco_keepalive_period)) {
-				expires = (unsigned long)(jiffies +
-					lp->cisco_keepalive_period * HZ);
-				mod_timer(&lp->cisco_timer, expires);
-				printk(KERN_INFO "%s: Keepalive period set "
-					"to %d seconds.\n",
-					dev->name, lp->cisco_keepalive_period);
-			}
-			break;
+	case SIOCGKEEPPERIOD:
+		len = (unsigned long)sizeof(lp->cisco_keepalive_period);
+		if (copy_to_user(ifr->ifr_data,
+				 &lp->cisco_keepalive_period, len))
+			rc = -EFAULT;
+		break;
+	case SIOCSKEEPPERIOD:
+		tmp = lp->cisco_keepalive_period;
+		len = (unsigned long)sizeof(lp->cisco_keepalive_period);
+		if (copy_from_user(&period, ifr->ifr_data, len))
+			rc = -EFAULT;
+		if ((period > 0) && (period <= 32767))
+			lp->cisco_keepalive_period = period;
+		else
+			rc = -EINVAL;
+		if (!rc && (tmp != lp->cisco_keepalive_period)) {
+			expires = (unsigned long)(jiffies +
+						  lp->cisco_keepalive_period * HZ);
+			mod_timer(&lp->cisco_timer, expires);
+			printk(KERN_INFO "%s: Keepalive period set "
+			       "to %d seconds.\n",
+			       dev->name, lp->cisco_keepalive_period);
+		}
+		break;
 
 		/* get/set debugging */
-		case SIOCGDEBSERINT:
-			len = (unsigned long)sizeof(lp->cisco_debserint);
-			if (copy_to_user(ifr->ifr_data,
-				&lp->cisco_debserint, len))
-				rc = -EFAULT;
-			break;
-		case SIOCSDEBSERINT:
-			len = (unsigned long)sizeof(lp->cisco_debserint);
-			if (copy_from_user(&debserint,
-				ifr->ifr_data, len))
-				rc = -EFAULT;
-			if ((debserint >= 0) && (debserint <= 64))
-				lp->cisco_debserint = debserint;
-			else
-				rc = -EINVAL;
-			break;
-
-		default:
+	case SIOCGDEBSERINT:
+		len = (unsigned long)sizeof(lp->cisco_debserint);
+		if (copy_to_user(ifr->ifr_data,
+				 &lp->cisco_debserint, len))
+			rc = -EFAULT;
+		break;
+	case SIOCSDEBSERINT:
+		len = (unsigned long)sizeof(lp->cisco_debserint);
+		if (copy_from_user(&debserint,
+				   ifr->ifr_data, len))
+			rc = -EFAULT;
+		if ((debserint >= 0) && (debserint <= 64))
+			lp->cisco_debserint = debserint;
+		else
 			rc = -EINVAL;
-			break;
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
 	}
 	return (rc);
 }
@@ -1524,30 +1524,30 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
 	lp->cisco_myseq++;
 
 	myseq_diff = (lp->cisco_myseq - lp->cisco_mineseen);
-	if ((lp->cisco_line_state) && ((myseq_diff >= 3)||(myseq_diff <= -3))) {
+	if ((lp->cisco_line_state) && ((myseq_diff >= 3) || (myseq_diff <= -3))) {
 		/* line up -> down */
 		lp->cisco_line_state = 0;
-		printk (KERN_WARNING
-				"UPDOWN: Line protocol on Interface %s,"
-				" changed state to down\n", lp->netdev->dev->name);
+		printk(KERN_WARNING
+		       "UPDOWN: Line protocol on Interface %s,"
+		       " changed state to down\n", lp->netdev->dev->name);
 		/* should stop routing higher-level data across */
 	} else if ((!lp->cisco_line_state) &&
-		(myseq_diff >= 0) && (myseq_diff <= 2)) {
+		   (myseq_diff >= 0) && (myseq_diff <= 2)) {
 		/* line down -> up */
 		lp->cisco_line_state = 1;
-		printk (KERN_WARNING
-				"UPDOWN: Line protocol on Interface %s,"
-				" changed state to up\n", lp->netdev->dev->name);
+		printk(KERN_WARNING
+		       "UPDOWN: Line protocol on Interface %s,"
+		       " changed state to up\n", lp->netdev->dev->name);
 		/* restart routing higher-level data across */
 	}
 
 	if (lp->cisco_debserint)
-		printk (KERN_DEBUG "%s: HDLC "
-			"myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
-			lp->netdev->dev->name, last_cisco_myseq, lp->cisco_mineseen,
-			((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
-			lp->cisco_yourseq,
-			((lp->cisco_line_state) ? "line up" : "line down"));
+		printk(KERN_DEBUG "%s: HDLC "
+		       "myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
+		       lp->netdev->dev->name, last_cisco_myseq, lp->cisco_mineseen,
+		       ((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
+		       lp->cisco_yourseq,
+		       ((lp->cisco_line_state) ? "line up" : "line down"));
 
 	skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
 	if (!skb)
@@ -1570,7 +1570,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
 	isdn_net_write_super(lp, skb);
 
 	lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
-	
+
 	add_timer(&lp->cisco_timer);
 }
 
@@ -1601,7 +1601,7 @@ isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
 	isdn_net_write_super(lp, skb);
 }
 
-static void 
+static void
 isdn_net_ciscohdlck_connected(isdn_net_local *lp)
 {
 	lp->cisco_myseq = 0;
@@ -1622,7 +1622,7 @@ isdn_net_ciscohdlck_connected(isdn_net_local *lp)
 	add_timer(&lp->cisco_timer);
 }
 
-static void 
+static void
 isdn_net_ciscohdlck_disconnected(isdn_net_local *lp)
 {
 	del_timer(&lp->cisco_timer);
@@ -1703,20 +1703,20 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
 		printk(KERN_INFO "%s: got slarp reply: remote ip: %pI4, local ip: %pI4 mask: %pI4\n",
 		       lp->netdev->dev->name, addr, &local, mask);
 		break;
-  slarp_reply_out:
+	slarp_reply_out:
 		printk(KERN_INFO "%s: got invalid slarp reply (%pI4/%pI4) - ignored\n",
 		       lp->netdev->dev->name, addr, mask);
 		break;
 	case CISCO_SLARP_KEEPALIVE:
 		period = (int)((jiffies - lp->cisco_last_slarp_in
-				+ HZ/2 - 1) / HZ);
+				+ HZ / 2 - 1) / HZ);
 		if (lp->cisco_debserint &&
-				(period != lp->cisco_keepalive_period) &&
-				lp->cisco_last_slarp_in) {
+		    (period != lp->cisco_keepalive_period) &&
+		    lp->cisco_last_slarp_in) {
 			printk(KERN_DEBUG "%s: Keepalive period mismatch - "
-				"is %d but should be %d.\n",
-				lp->netdev->dev->name, period,
-				lp->cisco_keepalive_period);
+			       "is %d but should be %d.\n",
+			       lp->netdev->dev->name, period,
+			       lp->cisco_keepalive_period);
 		}
 		lp->cisco_last_slarp_in = jiffies;
 		my_seq = be32_to_cpup((__be32 *)(p + 0));
@@ -1732,10 +1732,10 @@ static void
 isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
 {
 	unsigned char *p;
- 	u8 addr;
- 	u8 ctrl;
- 	u16 type;
-	
+	u8 addr;
+	u8 ctrl;
+	u16 type;
+
 	if (skb->len < 4)
 		goto out_free;
 
@@ -1745,7 +1745,7 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
 	type = be16_to_cpup((__be16 *)(p + 2));
 	p += 4;
 	skb_pull(skb, 4);
-	
+
 	if (addr != CISCO_ADDR_UNICAST && addr != CISCO_ADDR_BROADCAST) {
 		printk(KERN_WARNING "%s: Unknown Cisco addr 0x%02x\n",
 		       lp->netdev->dev->name, addr);
@@ -1764,8 +1764,8 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
 	case CISCO_TYPE_CDP:
 		if (lp->cisco_debserint)
 			printk(KERN_DEBUG "%s: Received CDP packet. use "
-				"\"no cdp enable\" on cisco.\n",
-				lp->netdev->dev->name);
+			       "\"no cdp enable\" on cisco.\n",
+			       lp->netdev->dev->name);
 		goto out_free;
 	default:
 		/* no special cisco protocol */
@@ -1774,7 +1774,7 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
 		return;
 	}
 
- out_free:
+out_free:
 	kfree_skb(skb);
 }
 
@@ -1787,7 +1787,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
 	isdn_net_local *lp = netdev_priv(ndev);
 	isdn_net_local *olp = lp;	/* original 'lp' */
 #ifdef CONFIG_ISDN_X25
-	struct concap_proto *cprot = lp -> netdev -> cprot;
+	struct concap_proto *cprot = lp->netdev->cprot;
 #endif
 	lp->transcount += skb->len;
 
@@ -1809,60 +1809,60 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
 	isdn_dumppkt("R:", skb->data, skb->len, 40);
 #endif
 	switch (lp->p_encap) {
-		case ISDN_NET_ENCAP_ETHER:
-			/* Ethernet over ISDN */
-			olp->huptimer = 0;
-			lp->huptimer = 0;
-			skb->protocol = isdn_net_type_trans(skb, ndev);
-			break;
-		case ISDN_NET_ENCAP_UIHDLC:
-			/* HDLC with UI-frame (for ispa with -h1 option) */
-			olp->huptimer = 0;
-			lp->huptimer = 0;
-			skb_pull(skb, 2);
-			/* Fall through */
-		case ISDN_NET_ENCAP_RAWIP:
-			/* RAW-IP without MAC-Header */
-			olp->huptimer = 0;
-			lp->huptimer = 0;
-			skb->protocol = htons(ETH_P_IP);
-			break;
-		case ISDN_NET_ENCAP_CISCOHDLCK:
-			isdn_net_ciscohdlck_receive(lp, skb);
-			return;
-		case ISDN_NET_ENCAP_CISCOHDLC:
-			/* CISCO-HDLC IP with type field and  fake I-frame-header */
-			skb_pull(skb, 2);
-			/* Fall through */
-		case ISDN_NET_ENCAP_IPTYP:
-			/* IP with type field */
-			olp->huptimer = 0;
-			lp->huptimer = 0;
-			skb->protocol = *(__be16 *)&(skb->data[0]);
-			skb_pull(skb, 2);
-			if (*(unsigned short *) skb->data == 0xFFFF)
-				skb->protocol = htons(ETH_P_802_3);
-			break;
+	case ISDN_NET_ENCAP_ETHER:
+		/* Ethernet over ISDN */
+		olp->huptimer = 0;
+		lp->huptimer = 0;
+		skb->protocol = isdn_net_type_trans(skb, ndev);
+		break;
+	case ISDN_NET_ENCAP_UIHDLC:
+		/* HDLC with UI-frame (for ispa with -h1 option) */
+		olp->huptimer = 0;
+		lp->huptimer = 0;
+		skb_pull(skb, 2);
+		/* Fall through */
+	case ISDN_NET_ENCAP_RAWIP:
+		/* RAW-IP without MAC-Header */
+		olp->huptimer = 0;
+		lp->huptimer = 0;
+		skb->protocol = htons(ETH_P_IP);
+		break;
+	case ISDN_NET_ENCAP_CISCOHDLCK:
+		isdn_net_ciscohdlck_receive(lp, skb);
+		return;
+	case ISDN_NET_ENCAP_CISCOHDLC:
+		/* CISCO-HDLC IP with type field and  fake I-frame-header */
+		skb_pull(skb, 2);
+		/* Fall through */
+	case ISDN_NET_ENCAP_IPTYP:
+		/* IP with type field */
+		olp->huptimer = 0;
+		lp->huptimer = 0;
+		skb->protocol = *(__be16 *)&(skb->data[0]);
+		skb_pull(skb, 2);
+		if (*(unsigned short *) skb->data == 0xFFFF)
+			skb->protocol = htons(ETH_P_802_3);
+		break;
 #ifdef CONFIG_ISDN_PPP
-		case ISDN_NET_ENCAP_SYNCPPP:
-			/* huptimer is done in isdn_ppp_push_higher */
-			isdn_ppp_receive(lp->netdev, olp, skb);
-			return;
+	case ISDN_NET_ENCAP_SYNCPPP:
+		/* huptimer is done in isdn_ppp_push_higher */
+		isdn_ppp_receive(lp->netdev, olp, skb);
+		return;
 #endif
 
-		default:
+	default:
 #ifdef CONFIG_ISDN_X25
-		  /* try if there are generic sync_device receiver routines */
-			if(cprot) if(cprot -> pops)
-				if( cprot -> pops -> data_ind){
-					cprot -> pops -> data_ind(cprot,skb);
-					return;
-				};
+		/* try if there are generic sync_device receiver routines */
+		if (cprot) if (cprot->pops)
+				   if (cprot->pops->data_ind) {
+					   cprot->pops->data_ind(cprot, skb);
+					   return;
+				   };
 #endif /* CONFIG_ISDN_X25 */
-			printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
-			       lp->netdev->dev->name);
-			kfree_skb(skb);
-			return;
+		printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
+		       lp->netdev->dev->name);
+		kfree_skb(skb);
+		return;
 	}
 
 	netif_rx(skb);
@@ -1904,48 +1904,48 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
 	int len = 0;
 
 	switch (lp->p_encap) {
-		case ISDN_NET_ENCAP_ETHER:
-			len = eth_header(skb, dev, type, daddr, saddr, plen);
-			break;
+	case ISDN_NET_ENCAP_ETHER:
+		len = eth_header(skb, dev, type, daddr, saddr, plen);
+		break;
 #ifdef CONFIG_ISDN_PPP
-		case ISDN_NET_ENCAP_SYNCPPP:
-			/* stick on a fake header to keep fragmentation code happy. */
-			len = IPPP_MAX_HEADER;
-			skb_push(skb,len);
-			break;
+	case ISDN_NET_ENCAP_SYNCPPP:
+		/* stick on a fake header to keep fragmentation code happy. */
+		len = IPPP_MAX_HEADER;
+		skb_push(skb, len);
+		break;
 #endif
-		case ISDN_NET_ENCAP_RAWIP:
-			printk(KERN_WARNING "isdn_net_header called with RAW_IP!\n");
-			len = 0;
-			break;
-		case ISDN_NET_ENCAP_IPTYP:
-			/* ethernet type field */
-			*((__be16 *)skb_push(skb, 2)) = htons(type);
-			len = 2;
-			break;
-		case ISDN_NET_ENCAP_UIHDLC:
-			/* HDLC with UI-Frames (for ispa with -h1 option) */
-			*((__be16 *)skb_push(skb, 2)) = htons(0x0103);
-			len = 2;
-			break;
-		case ISDN_NET_ENCAP_CISCOHDLC:
-		case ISDN_NET_ENCAP_CISCOHDLCK:
-			p = skb_push(skb, 4);
-			*(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
-			*(u8 *)(p + 1) = CISCO_CTRL;
-			*(__be16 *)(p + 2) = cpu_to_be16(type);
-			p += 4;
-			len = 4;
-			break;
+	case ISDN_NET_ENCAP_RAWIP:
+		printk(KERN_WARNING "isdn_net_header called with RAW_IP!\n");
+		len = 0;
+		break;
+	case ISDN_NET_ENCAP_IPTYP:
+		/* ethernet type field */
+		*((__be16 *)skb_push(skb, 2)) = htons(type);
+		len = 2;
+		break;
+	case ISDN_NET_ENCAP_UIHDLC:
+		/* HDLC with UI-Frames (for ispa with -h1 option) */
+		*((__be16 *)skb_push(skb, 2)) = htons(0x0103);
+		len = 2;
+		break;
+	case ISDN_NET_ENCAP_CISCOHDLC:
+	case ISDN_NET_ENCAP_CISCOHDLCK:
+		p = skb_push(skb, 4);
+		*(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
+		*(u8 *)(p + 1) = CISCO_CTRL;
+		*(__be16 *)(p + 2) = cpu_to_be16(type);
+		p += 4;
+		len = 4;
+		break;
 #ifdef CONFIG_ISDN_X25
-		default:
-		  /* try if there are generic concap protocol routines */
-			if( lp-> netdev -> cprot ){
-				printk(KERN_WARNING "isdn_net_header called with concap_proto!\n");
-				len = 0;
-				break;
-			}
+	default:
+		/* try if there are generic concap protocol routines */
+		if (lp->netdev->cprot) {
+			printk(KERN_WARNING "isdn_net_header called with concap_proto!\n");
+			len = 0;
 			break;
+		}
+		break;
 #endif /* CONFIG_ISDN_X25 */
 	}
 	return len;
@@ -2045,12 +2045,12 @@ isdn_net_swapbind(int drvidx)
 	while (p) {
 		if (p->local->pre_device == drvidx)
 			switch (p->local->pre_channel) {
-				case 0:
-					p->local->pre_channel = 1;
-					break;
-				case 1:
-					p->local->pre_channel = 0;
-					break;
+			case 0:
+				p->local->pre_channel = 1;
+				break;
+			case 1:
+				p->local->pre_channel = 0;
+				break;
 			}
 		p = (isdn_net_dev *) p->next;
 	}
@@ -2134,7 +2134,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 	ematch = wret = swapped = 0;
 #ifdef ISDN_DEBUG_NET_ICALL
 	printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
-		dev->usage[idx]);
+	       dev->usage[idx]);
 #endif
 	while (p) {
 		int matchret;
@@ -2142,32 +2142,32 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 
 		/* If last check has triggered as binding-swap, revert it */
 		switch (swapped) {
-			case 2:
-				isdn_net_swap_usage(idx, sidx);
-				/* fall through */
-			case 1:
-				isdn_net_swapbind(di);
-				break;
+		case 2:
+			isdn_net_swap_usage(idx, sidx);
+			/* fall through */
+		case 1:
+			isdn_net_swapbind(di);
+			break;
 		}
 		swapped = 0;
-                /* check acceptable call types for DOV */
-                my_eaz = isdn_map_eaz2msn(lp->msn, di);
-                if (si1 == 1) { /* it's a DOV call, check if we allow it */
-                        if (*my_eaz == 'v' || *my_eaz == 'V' ||
+		/* check acceptable call types for DOV */
+		my_eaz = isdn_map_eaz2msn(lp->msn, di);
+		if (si1 == 1) { /* it's a DOV call, check if we allow it */
+			if (*my_eaz == 'v' || *my_eaz == 'V' ||
 			    *my_eaz == 'b' || *my_eaz == 'B')
-                                my_eaz++; /* skip to allow a match */
-                        else
-                                my_eaz = NULL; /* force non match */
-                } else { /* it's a DATA call, check if we allow it */
-                        if (*my_eaz == 'b' || *my_eaz == 'B')
-                                my_eaz++; /* skip to allow a match */
-                }
-                if (my_eaz)
-                        matchret = isdn_msncmp(eaz, my_eaz);
-                else
-                        matchret = 1;
-                if (!matchret)
-                        ematch = 1;
+				my_eaz++; /* skip to allow a match */
+			else
+				my_eaz = NULL; /* force non match */
+		} else { /* it's a DATA call, check if we allow it */
+			if (*my_eaz == 'b' || *my_eaz == 'B')
+				my_eaz++; /* skip to allow a match */
+		}
+		if (my_eaz)
+			matchret = isdn_msncmp(eaz, my_eaz);
+		else
+			matchret = 1;
+		if (!matchret)
+			ematch = 1;
 
 		/* Remember if more numbers eventually can match */
 		if (matchret > wret)
@@ -2181,8 +2181,8 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 		      (USG_NONE(dev->usage[idx]))) ||                     /* and ch. unused or */
 		     ((((lp->dialstate == 4) || (lp->dialstate == 12)) && /* if dialing        */
 		       (!(lp->flags & ISDN_NET_CALLBACK)))                /* but no callback   */
-		     )))
-			 {
+			     )))
+		{
 #ifdef ISDN_DEBUG_NET_ICALL
 			printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
 			       lp->pre_device, lp->pre_channel);
@@ -2312,7 +2312,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 						p = (isdn_net_dev *) p->next;
 						continue;
 					}
-				} 
+				}
 				if (lp->flags & ISDN_NET_CALLBACK) {
 					int chi;
 					/*
@@ -2330,18 +2330,18 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 					if (lp->phone[1]) {
 						/* Grab a free ISDN-Channel */
 						spin_lock_irqsave(&dev->lock, flags);
-						if ((chi = 
-							isdn_get_free_channel(
-								ISDN_USAGE_NET,
-								lp->l2_proto,
-								lp->l3_proto,
-							  	lp->pre_device,
-						 		lp->pre_channel,
-						 		lp->msn)
-								) < 0) {
+						if ((chi =
+						     isdn_get_free_channel(
+							     ISDN_USAGE_NET,
+							     lp->l2_proto,
+							     lp->l3_proto,
+							     lp->pre_device,
+							     lp->pre_channel,
+							     lp->msn)
+							    ) < 0) {
 
 							printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n",
-								p->dev->name);
+							       p->dev->name);
 							spin_unlock_irqrestore(&dev->lock, flags);
 							return 0;
 						}
@@ -2363,11 +2363,11 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 						return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
 					} else
 						printk(KERN_WARNING "isdn_net: %s: No phone number\n",
-							p->dev->name);
+						       p->dev->name);
 					return 0;
 				} else {
 					printk(KERN_DEBUG "%s: call from %s -> %s accepted\n",
-						p->dev->name, nr, eaz);
+					       p->dev->name, nr, eaz);
 					/* if this interface is dialing, it does it probably on a different
 					   device, so free this device */
 					if ((lp->dialstate == 4) || (lp->dialstate == 12)) {
@@ -2377,7 +2377,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 #endif
 						isdn_net_lp_disconnected(lp);
 						isdn_free_channel(lp->isdn_device, lp->isdn_channel,
-							 ISDN_USAGE_NET);
+								  ISDN_USAGE_NET);
 					}
 					spin_lock_irqsave(&dev->lock, flags);
 					dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
@@ -2414,7 +2414,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
 	/* If none of configured EAZ/MSN matched and not verbose, be silent */
 	if (!ematch || dev->net_verbose)
 		printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, di, eaz);
-	return (wret == 2)?5:0;
+	return (wret == 2) ? 5 : 0;
 }
 
 /*
@@ -2439,7 +2439,7 @@ isdn_net_findif(char *name)
  * from isdn_net_start_xmit().
  */
 static int
-isdn_net_force_dial_lp(isdn_net_local * lp)
+isdn_net_force_dial_lp(isdn_net_local *lp)
 {
 	if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
 		int chi;
@@ -2449,14 +2449,14 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
 			/* Grab a free ISDN-Channel */
 			spin_lock_irqsave(&dev->lock, flags);
 			if ((chi = isdn_get_free_channel(
-					ISDN_USAGE_NET,
-					lp->l2_proto,
-					lp->l3_proto,
-					lp->pre_device,
-					lp->pre_channel,
-					lp->msn)) < 0) {
+				     ISDN_USAGE_NET,
+				     lp->l2_proto,
+				     lp->l3_proto,
+				     lp->pre_device,
+				     lp->pre_channel,
+				     lp->msn)) < 0) {
 				printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n",
-					lp->netdev->dev->name);
+				       lp->netdev->dev->name);
 				spin_unlock_irqrestore(&dev->lock, flags);
 				return -EAGAIN;
 			}
@@ -2487,7 +2487,7 @@ isdn_net_force_dial_lp(isdn_net_local * lp)
  * themselves.
  */
 int
-isdn_net_dial_req(isdn_net_local * lp)
+isdn_net_dial_req(isdn_net_local *lp)
 {
 	/* is there a better error code? */
 	if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) return -EBUSY;
@@ -2531,7 +2531,7 @@ static void _isdn_setup(struct net_device *dev)
 	ether_setup(dev);
 
 	/* Setup the generic properties */
-	dev->flags = IFF_NOARP|IFF_POINTOPOINT;
+	dev->flags = IFF_NOARP | IFF_POINTOPOINT;
 
 	/* isdn prepends a header in the tx path, can't share skbs */
 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
@@ -2655,7 +2655,7 @@ isdn_net_newslave(char *parm)
 		if (n->local->master)
 			return NULL;
 		/* Master must not be started yet */
-		if (isdn_net_device_started(n)) 
+		if (isdn_net_device_started(n))
 			return NULL;
 		return (isdn_net_new(newname, n->dev));
 	}
@@ -2669,7 +2669,7 @@ isdn_net_newslave(char *parm)
  * setup first, if only selected parameters are to be changed.
  */
 int
-isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
+isdn_net_setcfg(isdn_net_ioctl_cfg *cfg)
 {
 	isdn_net_dev *p = isdn_net_findif(cfg->name);
 	ulong features;
@@ -2692,9 +2692,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 			printk(KERN_WARNING "isdn_net: No driver with selected features\n");
 			return -ENODEV;
 		}
-		if (lp->p_encap != cfg->p_encap){
+		if (lp->p_encap != cfg->p_encap) {
 #ifdef CONFIG_ISDN_X25
-			struct concap_proto * cprot = p -> cprot;
+			struct concap_proto *cprot = p->cprot;
 #endif
 			if (isdn_net_device_started(p)) {
 				printk(KERN_WARNING "%s: cannot change encap when if is up\n",
@@ -2702,24 +2702,24 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 				return -EBUSY;
 			}
 #ifdef CONFIG_ISDN_X25
-			if( cprot && cprot -> pops )
-				cprot -> pops -> proto_del ( cprot );
-			p -> cprot = NULL;
-			lp -> dops = NULL;
+			if (cprot && cprot->pops)
+				cprot->pops->proto_del(cprot);
+			p->cprot = NULL;
+			lp->dops = NULL;
 			/* ... ,  prepare for configuration of new one ... */
-			switch ( cfg -> p_encap ){
+			switch (cfg->p_encap) {
 			case ISDN_NET_ENCAP_X25IFACE:
-				lp -> dops = &isdn_concap_reliable_dl_dops;
+				lp->dops = &isdn_concap_reliable_dl_dops;
 			}
 			/* ... and allocate new one ... */
-			p -> cprot = isdn_concap_new( cfg -> p_encap );
+			p->cprot = isdn_concap_new(cfg->p_encap);
 			/* p -> cprot == NULL now if p_encap is not supported
 			   by means of the concap_proto mechanism */
 			/* the protocol is not configured yet; this will
 			   happen later when isdn_net_reset() is called */
 #endif
 		}
-		switch ( cfg->p_encap ) {
+		switch (cfg->p_encap) {
 		case ISDN_NET_ENCAP_SYNCPPP:
 #ifndef CONFIG_ISDN_PPP
 			printk(KERN_WARNING "%s: SyncPPP support not configured\n",
@@ -2743,8 +2743,8 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 		case ISDN_NET_ENCAP_CISCOHDLCK:
 			break;
 		default:
-			if( cfg->p_encap >= 0 &&
-			    cfg->p_encap <= ISDN_NET_ENCAP_MAX_ENCAP )
+			if (cfg->p_encap >= 0 &&
+			    cfg->p_encap <= ISDN_NET_ENCAP_MAX_ENCAP)
 				break;
 			printk(KERN_WARNING
 			       "%s: encapsulation protocol %d not supported\n",
@@ -2754,10 +2754,10 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 		if (strlen(cfg->drvid)) {
 			/* A bind has been requested ... */
 			char *c,
-			*e;
+				*e;
 
 			if (strnlen(cfg->drvid, sizeof(cfg->drvid)) ==
-					sizeof(cfg->drvid))
+			    sizeof(cfg->drvid))
 				return -EINVAL;
 			drvidx = -1;
 			chidx = -1;
@@ -2789,8 +2789,8 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 			/* If binding is exclusive, try to grab the channel */
 			spin_lock_irqsave(&dev->lock, flags);
 			if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
-				lp->l2_proto, lp->l3_proto, drvidx,
-				chidx, lp->msn)) < 0) {
+						       lp->l2_proto, lp->l3_proto, drvidx,
+						       chidx, lp->msn)) < 0) {
 				/* Grab failed, because desired channel is in use */
 				lp->exclusive = -1;
 				spin_unlock_irqrestore(&dev->lock, flags);
@@ -2834,23 +2834,23 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 		else
 			lp->flags &= ~ISDN_NET_CBHUP;
 		switch (cfg->callback) {
-			case 0:
-				lp->flags &= ~(ISDN_NET_CALLBACK | ISDN_NET_CBOUT);
-				break;
-			case 1:
-				lp->flags |= ISDN_NET_CALLBACK;
-				lp->flags &= ~ISDN_NET_CBOUT;
-				break;
-			case 2:
-				lp->flags |= ISDN_NET_CBOUT;
-				lp->flags &= ~ISDN_NET_CALLBACK;
-				break;
+		case 0:
+			lp->flags &= ~(ISDN_NET_CALLBACK | ISDN_NET_CBOUT);
+			break;
+		case 1:
+			lp->flags |= ISDN_NET_CALLBACK;
+			lp->flags &= ~ISDN_NET_CBOUT;
+			break;
+		case 2:
+			lp->flags |= ISDN_NET_CBOUT;
+			lp->flags &= ~ISDN_NET_CALLBACK;
+			break;
 		}
 		lp->flags &= ~ISDN_NET_DIALMODE_MASK;	/* first all bits off */
 		if (cfg->dialmode && !(cfg->dialmode & ISDN_NET_DIALMODE_MASK)) {
 			/* old isdnctrl version, where only 0 or 1 is given */
 			printk(KERN_WARNING
-			     "Old isdnctrl version detected! Please update.\n");
+			       "Old isdnctrl version detected! Please update.\n");
 			lp->flags |= ISDN_NET_DM_OFF; /* turn on `off' bit */
 		}
 		else {
@@ -2871,13 +2871,13 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 		if (cfg->p_encap != lp->p_encap) {
 			if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) {
 				p->dev->header_ops = NULL;
-				p->dev->flags = IFF_NOARP|IFF_POINTOPOINT;
+				p->dev->flags = IFF_NOARP | IFF_POINTOPOINT;
 			} else {
 				p->dev->header_ops = &isdn_header_ops;
 				if (cfg->p_encap == ISDN_NET_ENCAP_ETHER)
 					p->dev->flags = IFF_BROADCAST | IFF_MULTICAST;
 				else
-					p->dev->flags = IFF_NOARP|IFF_POINTOPOINT;
+					p->dev->flags = IFF_NOARP | IFF_POINTOPOINT;
 			}
 		}
 		lp->p_encap = cfg->p_encap;
@@ -2890,7 +2890,7 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
  * Perform get-interface-parameters.ioctl
  */
 int
-isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
+isdn_net_getcfg(isdn_net_ioctl_cfg *cfg)
 {
 	isdn_net_dev *p = isdn_net_findif(cfg->name);
 
@@ -2924,7 +2924,7 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
 		cfg->triggercps = lp->triggercps;
 		cfg->slavedelay = lp->slavedelay / HZ;
 		cfg->chargeint = (lp->hupflags & ISDN_CHARGEHUP) ?
-		    (lp->chargeint / HZ) : 0;
+			(lp->chargeint / HZ) : 0;
 		cfg->pppbind = lp->pppbind;
 		cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
 		cfg->dialwait = lp->dialwait / HZ;
@@ -2951,7 +2951,7 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
  * Add a phone-number to an interface.
  */
 int
-isdn_net_addphone(isdn_net_ioctl_phone * phone)
+isdn_net_addphone(isdn_net_ioctl_phone *phone)
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
 	isdn_net_phone *n;
@@ -2972,7 +2972,7 @@ isdn_net_addphone(isdn_net_ioctl_phone * phone)
  * This might sleep and must be called with the isdn semaphore down.
  */
 int
-isdn_net_getphones(isdn_net_ioctl_phone * phone, char __user *phones)
+isdn_net_getphones(isdn_net_ioctl_phone *phone, char __user *phones)
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
 	int inout = phone->outgoing & 1;
@@ -3015,15 +3015,15 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
 	/*
 	 * Theoretical race: while this executes, the remote number might
 	 * become invalid (hang up) or change (new connection), resulting
-         * in (partially) wrong number copied to user. This race
+	 * in (partially) wrong number copied to user. This race
 	 * currently ignored.
 	 */
 	ch = p->local->isdn_channel;
 	dv = p->local->isdn_device;
-	if(ch < 0 && dv < 0)
+	if (ch < 0 && dv < 0)
 		return -ENOTCONN;
 	idx = isdn_dc2minor(dv, ch);
-	if (idx <0 )
+	if (idx < 0)
 		return -ENODEV;
 	/* for pre-bound channels, we need this extra check */
 	if (strncmp(dev->num[idx], "???", 3) == 0)
@@ -3038,7 +3038,7 @@ isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
  * Delete a phone-number from an interface.
  */
 int
-isdn_net_delphone(isdn_net_ioctl_phone * phone)
+isdn_net_delphone(isdn_net_ioctl_phone *phone)
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
 	int inout = phone->outgoing & 1;
@@ -3071,7 +3071,7 @@ isdn_net_delphone(isdn_net_ioctl_phone * phone)
  * Delete all phone-numbers of an interface.
  */
 static int
-isdn_net_rmallphone(isdn_net_dev * p)
+isdn_net_rmallphone(isdn_net_dev *p)
 {
 	isdn_net_phone *n;
 	isdn_net_phone *m;
@@ -3118,7 +3118,7 @@ isdn_net_force_hangup(char *name)
  * Helper-function for isdn_net_rm: Do the real work.
  */
 static int
-isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
+isdn_net_realrm(isdn_net_dev *p, isdn_net_dev *q)
 {
 	u_long flags;
 
@@ -3126,8 +3126,8 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
 		return -EBUSY;
 	}
 #ifdef CONFIG_ISDN_X25
-	if( p -> cprot && p -> cprot -> pops )
-		p -> cprot -> pops -> proto_del ( p -> cprot );
+	if (p->cprot && p->cprot->pops)
+		p->cprot->pops->proto_del(p->cprot);
 #endif
 	/* Free all phone-entries */
 	isdn_net_rmallphone(p);
diff --git a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h
index 7511f08..cca6d68 100644
--- a/drivers/isdn/i4l/isdn_net.h
+++ b/drivers/isdn/i4l/isdn_net.h
@@ -11,7 +11,7 @@
  *
  */
 
-			      /* Definitions for hupflags:                */
+/* Definitions for hupflags:                */
 #define ISDN_WAITCHARGE  1      /* did not get a charge info yet            */
 #define ISDN_HAVECHARGE  2      /* We know a charge info                    */
 #define ISDN_CHARGEHUP   4      /* We want to use the charge mechanism      */
@@ -58,8 +58,8 @@ extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb);
 
 #define ISDN_MASTER_PRIV(lp) ((isdn_net_local *) netdev_priv(lp->master))
 #define ISDN_SLAVE_PRIV(lp) ((isdn_net_local *) netdev_priv(lp->slave))
-#define MASTER_TO_SLAVE(master)	\
-			(((isdn_net_local *) netdev_priv(master))->slave)
+#define MASTER_TO_SLAVE(master)					\
+	(((isdn_net_local *) netdev_priv(master))->slave)
 
 /*
  * is this particular channel busy?
@@ -68,7 +68,7 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp)
 {
 	if (atomic_read(&lp->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH)
 		return 0;
-	else 
+	else
 		return 1;
 }
 
@@ -76,7 +76,7 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp)
  * For the given net device, this will get a non-busy channel out of the
  * corresponding bundle. The returned channel is locked.
  */
-static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd)
+static __inline__ isdn_net_local *isdn_net_get_locked_lp(isdn_net_dev *nd)
 {
 	unsigned long flags;
 	isdn_net_local *lp;
@@ -149,4 +149,3 @@ static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp)
 //		__func__, master_lp->netdev->queue);
 	spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
 }
-
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 1b002b0..a1e7601 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -28,18 +28,18 @@
 /* Prototypes */
 static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
 static int isdn_ppp_closewait(int slot);
-static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp,
+static void isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp,
 				 struct sk_buff *skb, int proto);
 static int isdn_ppp_if_get_unit(char *namebuf);
-static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *);
+static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_data *);
 static struct sk_buff *isdn_ppp_decompress(struct sk_buff *,
-				struct ippp_struct *,struct ippp_struct *,int *proto);
-static void isdn_ppp_receive_ccp(isdn_net_dev * net_dev, isdn_net_local * lp,
-				struct sk_buff *skb,int proto);
-static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
-	struct ippp_struct *is,struct ippp_struct *master,int type);
+					   struct ippp_struct *, struct ippp_struct *, int *proto);
+static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
+				 struct sk_buff *skb, int proto);
+static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in, int *proto,
+					 struct ippp_struct *is, struct ippp_struct *master, int type);
 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
-	 struct sk_buff *skb);
+			      struct sk_buff *skb);
 
 /* New CCP stuff */
 static void isdn_ppp_ccp_kickup(struct ippp_struct *is);
@@ -52,7 +52,7 @@ static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
 					  unsigned char id);
 static void isdn_ppp_ccp_timer_callback(unsigned long closure);
 static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
-						      unsigned char id);
+								   unsigned char id);
 static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 				     struct isdn_ppp_resetparams *rp);
 static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
@@ -61,17 +61,17 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
 
 
 #ifdef CONFIG_ISDN_MPP
-static ippp_bundle * isdn_ppp_bundle_arr = NULL;
- 
+static ippp_bundle *isdn_ppp_bundle_arr = NULL;
+
 static int isdn_ppp_mp_bundle_array_init(void);
-static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to );
-static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, 
-							struct sk_buff *skb);
-static void isdn_ppp_mp_cleanup( isdn_net_local * lp );
+static int isdn_ppp_mp_init(isdn_net_local *lp, ippp_bundle *add_to);
+static void isdn_ppp_mp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
+				struct sk_buff *skb);
+static void isdn_ppp_mp_cleanup(isdn_net_local *lp);
 
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
-  
+
 char *isdn_ppp_revision = "$Revision: 1.1.2.3 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
@@ -82,11 +82,11 @@ static struct isdn_ppp_compressor *ipc_head = NULL;
  * frame log (debug)
  */
 static void
-isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot)
+isdn_ppp_frame_log(char *info, char *data, int len, int maxlen, int unit, int slot)
 {
 	int cnt,
-	 j,
-	 i;
+		j,
+		i;
 	char buf[80];
 
 	if (len < maxlen)
@@ -94,8 +94,8 @@ isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot
 
 	for (i = 0, cnt = 0; cnt < maxlen; i++) {
 		for (j = 0; j < 16 && cnt < maxlen; j++, cnt++)
-			sprintf(buf + j * 3, "%02x ", (unsigned char) data[cnt]);
-		printk(KERN_DEBUG "[%d/%d].%s[%d]: %s\n",unit,slot, info, i, buf);
+			sprintf(buf + j * 3, "%02x ", (unsigned char)data[cnt]);
+		printk(KERN_DEBUG "[%d/%d].%s[%d]: %s\n", unit, slot, info, i, buf);
 	}
 }
 
@@ -105,13 +105,13 @@ isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot
  *       in this case we bind another lp to the master device
  */
 int
-isdn_ppp_free(isdn_net_local * lp)
+isdn_ppp_free(isdn_net_local *lp)
 {
 	struct ippp_struct *is;
 
 	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
-			__func__, lp->ppp_slot);
+		       __func__, lp->ppp_slot);
 		return 0;
 	}
 
@@ -128,7 +128,7 @@ isdn_ppp_free(isdn_net_local * lp)
 #endif /* CONFIG_ISDN_MPP */
 	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n",
-			__func__, lp->ppp_slot);
+		       __func__, lp->ppp_slot);
 		return 0;
 	}
 	is = ippp_table[lp->ppp_slot];
@@ -153,7 +153,7 @@ isdn_ppp_free(isdn_net_local * lp)
  * no additional lock is needed
  */
 int
-isdn_ppp_bind(isdn_net_local * lp)
+isdn_ppp_bind(isdn_net_local *lp)
 {
 	int i;
 	int unit = 0;
@@ -195,11 +195,11 @@ isdn_ppp_bind(isdn_net_local * lp)
 	unit = isdn_ppp_if_get_unit(lp->netdev->dev->name);
 	if (unit < 0) {
 		printk(KERN_ERR "isdn_ppp_bind: illegal interface name %s.\n",
-			lp->netdev->dev->name);
+		       lp->netdev->dev->name);
 		retval = -1;
 		goto out;
 	}
-	
+
 	lp->ppp_slot = i;
 	is = ippp_table[i];
 	is->lp = lp;
@@ -213,7 +213,7 @@ isdn_ppp_bind(isdn_net_local * lp)
 
 	retval = lp->ppp_slot;
 
- out:
+out:
 	return retval;
 }
 
@@ -223,11 +223,11 @@ isdn_ppp_bind(isdn_net_local * lp)
  */
 
 void
-isdn_ppp_wakeup_daemon(isdn_net_local * lp)
+isdn_ppp_wakeup_daemon(isdn_net_local *lp)
 {
 	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
-			__func__, lp->ppp_slot);
+		       __func__, lp->ppp_slot);
 		return;
 	}
 	ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
@@ -246,7 +246,7 @@ isdn_ppp_closewait(int slot)
 
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: slot(%d) out of range\n",
-			__func__, slot);
+		       __func__, slot);
 		return 0;
 	}
 	is = ippp_table[slot];
@@ -289,7 +289,7 @@ isdn_ppp_open(int min, struct file *file)
 		return -EBUSY;
 	}
 	is = file->private_data = ippp_table[slot];
-	
+
 	printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n",
 	       slot, min, is->state);
 
@@ -385,21 +385,21 @@ isdn_ppp_release(int min, struct file *file)
 #endif
 
 /* TODO: if this was the previous master: link the stuff to the new master */
-	if(is->comp_stat)
+	if (is->comp_stat)
 		is->compressor->free(is->comp_stat);
-	if(is->link_comp_stat)
+	if (is->link_comp_stat)
 		is->link_compressor->free(is->link_comp_stat);
-	if(is->link_decomp_stat)
+	if (is->link_decomp_stat)
 		is->link_decompressor->free(is->link_decomp_stat);
-	if(is->decomp_stat)
+	if (is->decomp_stat)
 		is->decompressor->free(is->decomp_stat);
-        is->compressor   = is->link_compressor   = NULL;
-        is->decompressor = is->link_decompressor = NULL;
+	is->compressor   = is->link_compressor   = NULL;
+	is->decompressor = is->link_decompressor = NULL;
 	is->comp_stat    = is->link_comp_stat    = NULL;
-        is->decomp_stat  = is->link_decomp_stat  = NULL;
+	is->decomp_stat  = is->link_decomp_stat  = NULL;
 
 	/* Clean up if necessary */
-	if(is->reset)
+	if (is->reset)
 		isdn_ppp_ccp_reset_free(is);
 
 	/* this slot is ready for new connections */
@@ -423,9 +423,9 @@ get_arg(void __user *b, void *val, int len)
  * set arg .. ioctl helper
  */
 static int
-set_arg(void __user *b, void *val,int len)
+set_arg(void __user *b, void *val, int len)
 {
-	if(len <= 0)
+	if (len <= 0)
 		len = sizeof(void *);
 	if (copy_to_user(b, val, len))
 		return -EFAULT;
@@ -471,7 +471,7 @@ int
 isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	unsigned long val;
-	int r,i,j;
+	int r, i, j;
 	struct ippp_struct *is;
 	isdn_net_local *lp;
 	struct isdn_ppp_comp_data data;
@@ -487,177 +487,177 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
 		return -EINVAL;
 
 	switch (cmd) {
-		case PPPIOCBUNDLE:
+	case PPPIOCBUNDLE:
 #ifdef CONFIG_ISDN_MPP
-			if (!(is->state & IPPP_CONNECT))
-				return -EINVAL;
-			if ((r = get_arg(argp, &val, sizeof(val) )))
-				return r;
-			printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
-			       (int) min, (int) is->unit, (int) val);
-			return isdn_ppp_bundle(is, val);
+		if (!(is->state & IPPP_CONNECT))
+			return -EINVAL;
+		if ((r = get_arg(argp, &val, sizeof(val))))
+			return r;
+		printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
+		       (int) min, (int) is->unit, (int) val);
+		return isdn_ppp_bundle(is, val);
 #else
-			return -1;
+		return -1;
 #endif
-			break;
-		case PPPIOCGUNIT:	/* get ppp/isdn unit number */
-			if ((r = set_arg(argp, &is->unit, sizeof(is->unit) )))
-				return r;
-			break;
-		case PPPIOCGIFNAME:
-			if(!lp)
-				return -EINVAL;
-			if ((r = set_arg(argp, lp->netdev->dev->name,
-				strlen(lp->netdev->dev->name))))
-				return r;
-			break;
-		case PPPIOCGMPFLAGS:	/* get configuration flags */
-			if ((r = set_arg(argp, &is->mpppcfg, sizeof(is->mpppcfg) )))
-				return r;
-			break;
-		case PPPIOCSMPFLAGS:	/* set configuration flags */
-			if ((r = get_arg(argp, &val, sizeof(val) )))
-				return r;
-			is->mpppcfg = val;
-			break;
-		case PPPIOCGFLAGS:	/* get configuration flags */
-			if ((r = set_arg(argp, &is->pppcfg,sizeof(is->pppcfg) )))
-				return r;
-			break;
-		case PPPIOCSFLAGS:	/* set configuration flags */
-			if ((r = get_arg(argp, &val, sizeof(val) ))) {
-				return r;
-			}
-			if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
-				if (lp) {
-					/* OK .. we are ready to send buffers */
-					is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */
-					netif_wake_queue(lp->netdev->dev);
-					break;
-				}
-			}
-			is->pppcfg = val;
-			break;
-		case PPPIOCGIDLE:	/* get idle time information */
+		break;
+	case PPPIOCGUNIT:	/* get ppp/isdn unit number */
+		if ((r = set_arg(argp, &is->unit, sizeof(is->unit))))
+			return r;
+		break;
+	case PPPIOCGIFNAME:
+		if (!lp)
+			return -EINVAL;
+		if ((r = set_arg(argp, lp->netdev->dev->name,
+				 strlen(lp->netdev->dev->name))))
+			return r;
+		break;
+	case PPPIOCGMPFLAGS:	/* get configuration flags */
+		if ((r = set_arg(argp, &is->mpppcfg, sizeof(is->mpppcfg))))
+			return r;
+		break;
+	case PPPIOCSMPFLAGS:	/* set configuration flags */
+		if ((r = get_arg(argp, &val, sizeof(val))))
+			return r;
+		is->mpppcfg = val;
+		break;
+	case PPPIOCGFLAGS:	/* get configuration flags */
+		if ((r = set_arg(argp, &is->pppcfg, sizeof(is->pppcfg))))
+			return r;
+		break;
+	case PPPIOCSFLAGS:	/* set configuration flags */
+		if ((r = get_arg(argp, &val, sizeof(val)))) {
+			return r;
+		}
+		if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
 			if (lp) {
-				struct ppp_idle pidle;
-				pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
-				if ((r = set_arg(argp, &pidle,sizeof(struct ppp_idle))))
-					 return r;
+				/* OK .. we are ready to send buffers */
+				is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */
+				netif_wake_queue(lp->netdev->dev);
+				break;
 			}
-			break;
-		case PPPIOCSMRU:	/* set receive unit size for PPP */
-			if ((r = get_arg(argp, &val, sizeof(val) )))
-				return r;
-			is->mru = val;
-			break;
-		case PPPIOCSMPMRU:
-			break;
-		case PPPIOCSMPMTU:
-			break;
-		case PPPIOCSMAXCID:	/* set the maximum compression slot id */
-			if ((r = get_arg(argp, &val, sizeof(val) )))
+		}
+		is->pppcfg = val;
+		break;
+	case PPPIOCGIDLE:	/* get idle time information */
+		if (lp) {
+			struct ppp_idle pidle;
+			pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
+			if ((r = set_arg(argp, &pidle, sizeof(struct ppp_idle))))
 				return r;
-			val++;
-			if (is->maxcid != val) {
+		}
+		break;
+	case PPPIOCSMRU:	/* set receive unit size for PPP */
+		if ((r = get_arg(argp, &val, sizeof(val))))
+			return r;
+		is->mru = val;
+		break;
+	case PPPIOCSMPMRU:
+		break;
+	case PPPIOCSMPMTU:
+		break;
+	case PPPIOCSMAXCID:	/* set the maximum compression slot id */
+		if ((r = get_arg(argp, &val, sizeof(val))))
+			return r;
+		val++;
+		if (is->maxcid != val) {
 #ifdef CONFIG_ISDN_PPP_VJ
-				struct slcompress *sltmp;
+			struct slcompress *sltmp;
 #endif
-				if (is->debug & 0x1)
-					printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
-				is->maxcid = val;
+			if (is->debug & 0x1)
+				printk(KERN_DEBUG "ippp, ioctl: changed MAXCID to %ld\n", val);
+			is->maxcid = val;
 #ifdef CONFIG_ISDN_PPP_VJ
-				sltmp = slhc_init(16, val);
-				if (!sltmp) {
-					printk(KERN_ERR "ippp, can't realloc slhc struct\n");
-					return -ENOMEM;
-				}
-				if (is->slcomp)
-					slhc_free(is->slcomp);
-				is->slcomp = sltmp;
-#endif
-			}
-			break;
-		case PPPIOCGDEBUG:
-			if ((r = set_arg(argp, &is->debug, sizeof(is->debug) )))
-				return r;
-			break;
-		case PPPIOCSDEBUG:
-			if ((r = get_arg(argp, &val, sizeof(val) )))
-				return r;
-			is->debug = val;
-			break;
-		case PPPIOCGCOMPRESSORS:
-			{
-				unsigned long protos[8] = {0,};
-				struct isdn_ppp_compressor *ipc = ipc_head;
-				while(ipc) {
-					j = ipc->num / (sizeof(long)*8);
-					i = ipc->num % (sizeof(long)*8);
-					if(j < 8)
-						protos[j] |= (0x1<<i);
-					ipc = ipc->next;
-				}
-				if ((r = set_arg(argp,protos,8*sizeof(long) )))
-					return r;
+			sltmp = slhc_init(16, val);
+			if (!sltmp) {
+				printk(KERN_ERR "ippp, can't realloc slhc struct\n");
+				return -ENOMEM;
 			}
-			break;
-		case PPPIOCSCOMPRESSOR:
-			if ((r = get_arg(argp, &data, sizeof(struct isdn_ppp_comp_data))))
-				return r;
-			return isdn_ppp_set_compressor(is, &data);
-		case PPPIOCGCALLINFO:
-			{
-				struct pppcallinfo pci;
-				memset((char *) &pci,0,sizeof(struct pppcallinfo));
-				if(lp)
-				{
-					strncpy(pci.local_num,lp->msn,63);
-					if(lp->dial) {
-						strncpy(pci.remote_num,lp->dial->num,63);
-					}
-					pci.charge_units = lp->charge;
-					if(lp->outgoing)
-						pci.calltype = CALLTYPE_OUTGOING;
-					else
-						pci.calltype = CALLTYPE_INCOMING;
-					if(lp->flags & ISDN_NET_CALLBACK)
-						pci.calltype |= CALLTYPE_CALLBACK;
-				}
-				return set_arg(argp,&pci,sizeof(struct pppcallinfo));
+			if (is->slcomp)
+				slhc_free(is->slcomp);
+			is->slcomp = sltmp;
+#endif
+		}
+		break;
+	case PPPIOCGDEBUG:
+		if ((r = set_arg(argp, &is->debug, sizeof(is->debug))))
+			return r;
+		break;
+	case PPPIOCSDEBUG:
+		if ((r = get_arg(argp, &val, sizeof(val))))
+			return r;
+		is->debug = val;
+		break;
+	case PPPIOCGCOMPRESSORS:
+	{
+		unsigned long protos[8] = {0,};
+		struct isdn_ppp_compressor *ipc = ipc_head;
+		while (ipc) {
+			j = ipc->num / (sizeof(long) * 8);
+			i = ipc->num % (sizeof(long) * 8);
+			if (j < 8)
+				protos[j] |= (0x1 << i);
+			ipc = ipc->next;
+		}
+		if ((r = set_arg(argp, protos, 8 * sizeof(long))))
+			return r;
+	}
+	break;
+	case PPPIOCSCOMPRESSOR:
+		if ((r = get_arg(argp, &data, sizeof(struct isdn_ppp_comp_data))))
+			return r;
+		return isdn_ppp_set_compressor(is, &data);
+	case PPPIOCGCALLINFO:
+	{
+		struct pppcallinfo pci;
+		memset((char *)&pci, 0, sizeof(struct pppcallinfo));
+		if (lp)
+		{
+			strncpy(pci.local_num, lp->msn, 63);
+			if (lp->dial) {
+				strncpy(pci.remote_num, lp->dial->num, 63);
 			}
+			pci.charge_units = lp->charge;
+			if (lp->outgoing)
+				pci.calltype = CALLTYPE_OUTGOING;
+			else
+				pci.calltype = CALLTYPE_INCOMING;
+			if (lp->flags & ISDN_NET_CALLBACK)
+				pci.calltype |= CALLTYPE_CALLBACK;
+		}
+		return set_arg(argp, &pci, sizeof(struct pppcallinfo));
+	}
 #ifdef CONFIG_IPPP_FILTER
-		case PPPIOCSPASS:
-			{
-				struct sock_filter *code;
-				int len = get_filter(argp, &code);
-				if (len < 0)
-					return len;
-				kfree(is->pass_filter);
-				is->pass_filter = code;
-				is->pass_len = len;
-				break;
-			}
-		case PPPIOCSACTIVE:
-			{
-				struct sock_filter *code;
-				int len = get_filter(argp, &code);
-				if (len < 0)
-					return len;
-				kfree(is->active_filter);
-				is->active_filter = code;
-				is->active_len = len;
-				break;
-			}
+	case PPPIOCSPASS:
+	{
+		struct sock_filter *code;
+		int len = get_filter(argp, &code);
+		if (len < 0)
+			return len;
+		kfree(is->pass_filter);
+		is->pass_filter = code;
+		is->pass_len = len;
+		break;
+	}
+	case PPPIOCSACTIVE:
+	{
+		struct sock_filter *code;
+		int len = get_filter(argp, &code);
+		if (len < 0)
+			return len;
+		kfree(is->active_filter);
+		is->active_filter = code;
+		is->active_len = len;
+		break;
+	}
 #endif /* CONFIG_IPPP_FILTER */
-		default:
-			break;
+	default:
+		break;
 	}
 	return 0;
 }
 
 unsigned int
-isdn_ppp_poll(struct file *file, poll_table * wait)
+isdn_ppp_poll(struct file *file, poll_table *wait)
 {
 	u_int mask;
 	struct ippp_buf_queue *bf, *bl;
@@ -668,13 +668,13 @@ isdn_ppp_poll(struct file *file, poll_table * wait)
 
 	if (is->debug & 0x2)
 		printk(KERN_DEBUG "isdn_ppp_poll: minor: %d\n",
-				iminor(file->f_path.dentry->d_inode));
+		       iminor(file->f_path.dentry->d_inode));
 
 	/* just registers wait_queue hook. This doesn't really wait. */
 	poll_wait(file, &is->wq, wait);
 
 	if (!(is->state & IPPP_OPEN)) {
-		if(is->state == IPPP_CLOSEWAIT)
+		if (is->state == IPPP_CLOSEWAIT)
 			return POLLHUP;
 		printk(KERN_DEBUG "isdn_ppp: device not open\n");
 		return POLLERR;
@@ -827,7 +827,7 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count)
 			return 0;
 
 		if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
-			lp->dialstate == 0 &&
+		    lp->dialstate == 0 &&
 		    (lp->flags & ISDN_NET_CONNECTED)) {
 			unsigned short hl;
 			struct sk_buff *skb;
@@ -837,7 +837,7 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count)
 			 * 16 bytes, now we are looking what the driver want
 			 */
 			hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
-			skb = alloc_skb(hl+count, GFP_ATOMIC);
+			skb = alloc_skb(hl + count, GFP_ATOMIC);
 			if (!skb) {
 				printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
 				return count;
@@ -850,10 +850,10 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count)
 			}
 			if (is->debug & 0x40) {
 				printk(KERN_DEBUG "ppp xmit: len %d\n", (int) skb->len);
-				isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
+				isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
 			}
 
-			isdn_ppp_send_ccp(lp->netdev,lp,skb); /* keeps CCP/compression states in sync */
+			isdn_ppp_send_ccp(lp->netdev, lp, skb); /* keeps CCP/compression states in sync */
 
 			isdn_net_write_super(lp, skb);
 		}
@@ -869,10 +869,10 @@ int
 isdn_ppp_init(void)
 {
 	int i,
-	 j;
-	 
+		j;
+
 #ifdef CONFIG_ISDN_MPP
-	if( isdn_ppp_mp_bundle_array_init() < 0 )
+	if (isdn_ppp_mp_bundle_array_init() < 0)
 		return -ENOMEM;
 #endif /* CONFIG_ISDN_MPP */
 
@@ -891,7 +891,7 @@ isdn_ppp_init(void)
 		for (j = 0; j < NUM_RCV_BUFFS; j++) {
 			ippp_table[i]->rq[j].buf = NULL;
 			ippp_table[i]->rq[j].last = ippp_table[i]->rq +
-			    (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
+				(NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
 			ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
 		}
 	}
@@ -916,7 +916,7 @@ isdn_ppp_cleanup(void)
  * check for address/control field and skip if allowed
  * retval != 0 -> discard packet silently
  */
-static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb) 
+static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb)
 {
 	if (skb->len < 1)
 		return -1;
@@ -930,7 +930,7 @@ static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb)
 
 		// skip address/control (AC) field
 		skb_pull(skb, 2);
-	} else { 
+	} else {
 		if (is->pppcfg & SC_REJ_COMP_AC)
 			// if AC compression was not negotiated, but used, discard packet
 			return -1;
@@ -942,10 +942,10 @@ static int isdn_ppp_skip_ac(struct ippp_struct *is, struct sk_buff *skb)
  * get the PPP protocol header and pull skb
  * retval < 0 -> discard packet silently
  */
-static int isdn_ppp_strip_proto(struct sk_buff *skb) 
+static int isdn_ppp_strip_proto(struct sk_buff *skb)
 {
 	int proto;
-	
+
 	if (skb->len < 1)
 		return -1;
 
@@ -966,7 +966,7 @@ static int isdn_ppp_strip_proto(struct sk_buff *skb)
 /*
  * handler for incoming packets on a syncPPP interface
  */
-void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb)
+void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
 {
 	struct ippp_struct *is;
 	int slot;
@@ -977,7 +977,7 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot(%d)\n",
-			lp->ppp_slot);
+		       lp->ppp_slot);
 		kfree_skb(skb);
 		return;
 	}
@@ -985,35 +985,35 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf
 
 	if (is->debug & 0x4) {
 		printk(KERN_DEBUG "ippp_receive: is:%08lx lp:%08lx slot:%d unit:%d len:%d\n",
-		       (long)is,(long)lp,lp->ppp_slot,is->unit,(int) skb->len);
-		isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
-	}
-
- 	if (isdn_ppp_skip_ac(is, skb) < 0) {
- 		kfree_skb(skb);
- 		return;
- 	}
-  	proto = isdn_ppp_strip_proto(skb);
- 	if (proto < 0) {
- 		kfree_skb(skb);
- 		return;
- 	}
-  
+		       (long)is, (long)lp, lp->ppp_slot, is->unit, (int)skb->len);
+		isdn_ppp_frame_log("receive", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
+	}
+
+	if (isdn_ppp_skip_ac(is, skb) < 0) {
+		kfree_skb(skb);
+		return;
+	}
+	proto = isdn_ppp_strip_proto(skb);
+	if (proto < 0) {
+		kfree_skb(skb);
+		return;
+	}
+
 #ifdef CONFIG_ISDN_MPP
- 	if (is->compflags & SC_LINK_DECOMP_ON) {
- 		skb = isdn_ppp_decompress(skb, is, NULL, &proto);
- 		if (!skb) // decompression error
- 			return;
- 	}
-	
- 	if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP
-  		if (proto == PPP_MP) {
-  			isdn_ppp_mp_receive(net_dev, lp, skb);
- 			return;
- 		}
- 	} 
+	if (is->compflags & SC_LINK_DECOMP_ON) {
+		skb = isdn_ppp_decompress(skb, is, NULL, &proto);
+		if (!skb) // decompression error
+			return;
+	}
+
+	if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP
+		if (proto == PPP_MP) {
+			isdn_ppp_mp_receive(net_dev, lp, skb);
+			return;
+		}
+	}
 #endif
- 	isdn_ppp_push_higher(net_dev, lp, skb, proto);
+	isdn_ppp_push_higher(net_dev, lp, skb, proto);
 }
 
 /*
@@ -1022,116 +1022,116 @@ void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buf
  * note: net_dev has to be master net_dev
  */
 static void
-isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto)
+isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb, int proto)
 {
 	struct net_device *dev = net_dev->dev;
- 	struct ippp_struct *is, *mis;
+	struct ippp_struct *is, *mis;
 	isdn_net_local *mlp = NULL;
 	int slot;
 
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot(%d)\n",
-			lp->ppp_slot);
+		       lp->ppp_slot);
 		goto drop_packet;
 	}
 	is = ippp_table[slot];
- 	
- 	if (lp->master) { // FIXME?
+
+	if (lp->master) { // FIXME?
 		mlp = ISDN_MASTER_PRIV(lp);
- 		slot = mlp->ppp_slot;
- 		if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
- 			printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
- 				lp->ppp_slot);
+		slot = mlp->ppp_slot;
+		if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
+			printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
+			       lp->ppp_slot);
 			goto drop_packet;
- 		}
- 	}
- 	mis = ippp_table[slot];
+		}
+	}
+	mis = ippp_table[slot];
 
 	if (is->debug & 0x10) {
 		printk(KERN_DEBUG "push, skb %d %04x\n", (int) skb->len, proto);
-		isdn_ppp_frame_log("rpush", skb->data, skb->len, 32,is->unit,lp->ppp_slot);
+		isdn_ppp_frame_log("rpush", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
 	}
 	if (mis->compflags & SC_DECOMP_ON) {
 		skb = isdn_ppp_decompress(skb, is, mis, &proto);
 		if (!skb) // decompression error
-  			return;
-  	}
+			return;
+	}
 	switch (proto) {
-		case PPP_IPX:  /* untested */
-			if (is->debug & 0x20)
-				printk(KERN_DEBUG "isdn_ppp: IPX\n");
-			skb->protocol = htons(ETH_P_IPX);
-			break;
-		case PPP_IP:
-			if (is->debug & 0x20)
-				printk(KERN_DEBUG "isdn_ppp: IP\n");
-			skb->protocol = htons(ETH_P_IP);
-			break;
-		case PPP_COMP:
-		case PPP_COMPFRAG:
-			printk(KERN_INFO "isdn_ppp: unexpected compressed frame dropped\n");
-			goto drop_packet;
+	case PPP_IPX:  /* untested */
+		if (is->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: IPX\n");
+		skb->protocol = htons(ETH_P_IPX);
+		break;
+	case PPP_IP:
+		if (is->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: IP\n");
+		skb->protocol = htons(ETH_P_IP);
+		break;
+	case PPP_COMP:
+	case PPP_COMPFRAG:
+		printk(KERN_INFO "isdn_ppp: unexpected compressed frame dropped\n");
+		goto drop_packet;
 #ifdef CONFIG_ISDN_PPP_VJ
-		case PPP_VJC_UNCOMP:
-			if (is->debug & 0x20)
-				printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
+	case PPP_VJC_UNCOMP:
+		if (is->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
+		if (net_dev->local->ppp_slot < 0) {
+			printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
+			       __func__, net_dev->local->ppp_slot);
+			goto drop_packet;
+		}
+		if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
+			printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
+			goto drop_packet;
+		}
+		skb->protocol = htons(ETH_P_IP);
+		break;
+	case PPP_VJC_COMP:
+		if (is->debug & 0x20)
+			printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
+		{
+			struct sk_buff *skb_old = skb;
+			int pkt_len;
+			skb = dev_alloc_skb(skb_old->len + 128);
+
+			if (!skb) {
+				printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
+				skb = skb_old;
+				goto drop_packet;
+			}
+			skb_put(skb, skb_old->len + 128);
+			skb_copy_from_linear_data(skb_old, skb->data,
+						  skb_old->len);
 			if (net_dev->local->ppp_slot < 0) {
 				printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
-					__func__, net_dev->local->ppp_slot);
+				       __func__, net_dev->local->ppp_slot);
 				goto drop_packet;
 			}
-			if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
-				printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
+			pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
+						  skb->data, skb_old->len);
+			kfree_skb(skb_old);
+			if (pkt_len < 0)
 				goto drop_packet;
-			}
+
+			skb_trim(skb, pkt_len);
 			skb->protocol = htons(ETH_P_IP);
-			break;
-		case PPP_VJC_COMP:
-			if (is->debug & 0x20)
-				printk(KERN_DEBUG "isdn_ppp: VJC_COMP\n");
-			{
-				struct sk_buff *skb_old = skb;
-				int pkt_len;
-				skb = dev_alloc_skb(skb_old->len + 128);
-
-				if (!skb) {
-					printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
-					skb = skb_old;
-					goto drop_packet;
-				}
-				skb_put(skb, skb_old->len + 128);
-				skb_copy_from_linear_data(skb_old, skb->data,
-							  skb_old->len);
-				if (net_dev->local->ppp_slot < 0) {
-					printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
-						__func__, net_dev->local->ppp_slot);
-					goto drop_packet;
-				}
-				pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
-						skb->data, skb_old->len);
-				kfree_skb(skb_old);
-				if (pkt_len < 0)
-					goto drop_packet;
-
-				skb_trim(skb, pkt_len);
-				skb->protocol = htons(ETH_P_IP);
-			}
-			break;
+		}
+		break;
 #endif
-		case PPP_CCP:
-		case PPP_CCPFRAG:
-			isdn_ppp_receive_ccp(net_dev,lp,skb,proto);
-			/* Dont pop up ResetReq/Ack stuff to the daemon any
-			   longer - the job is done already */
-			if(skb->data[0] == CCP_RESETREQ ||
-			   skb->data[0] == CCP_RESETACK)
-				break;
-			/* fall through */
-		default:
-			isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot);	/* push data to pppd device */
-			kfree_skb(skb);
-			return;
+	case PPP_CCP:
+	case PPP_CCPFRAG:
+		isdn_ppp_receive_ccp(net_dev, lp, skb, proto);
+		/* Dont pop up ResetReq/Ack stuff to the daemon any
+		   longer - the job is done already */
+		if (skb->data[0] == CCP_RESETREQ ||
+		    skb->data[0] == CCP_RESETACK)
+			break;
+		/* fall through */
+	default:
+		isdn_ppp_fill_rq(skb->data, skb->len, proto, lp->ppp_slot);	/* push data to pppd device */
+		kfree_skb(skb);
+		return;
 	}
 
 #ifdef CONFIG_IPPP_FILTER
@@ -1156,7 +1156,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
 	if (!(is->active_filter
 	      && sk_run_filter(skb, is->active_filter) == 0)) {
 		if (is->debug & 0x2)
-			printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
+			printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n");
 		lp->huptimer = 0;
 		if (mlp)
 			mlp->huptimer = 0;
@@ -1173,7 +1173,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
 	/* net_dev->local->stats.rx_packets++; done in isdn_net.c */
 	return;
 
- drop_packet:
+drop_packet:
 	net_dev->local->stats.rx_dropped++;
 	kfree_skb(skb);
 }
@@ -1183,11 +1183,11 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
  * checks whether we have enough space at the beginning of the skb
  * and allocs a new SKB if necessary
  */
-static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
+static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p, int len)
 {
 	struct sk_buff *skb = *skb_p;
 
-	if(skb_headroom(skb) < len) {
+	if (skb_headroom(skb) < len) {
 		struct sk_buff *nskb = skb_realloc_headroom(skb, len);
 
 		if (!nskb) {
@@ -1195,12 +1195,12 @@ static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
 			dev_kfree_skb(skb);
 			return NULL;
 		}
-		printk(KERN_DEBUG "isdn_ppp_skb_push:under %d %d\n",skb_headroom(skb),len);
+		printk(KERN_DEBUG "isdn_ppp_skb_push:under %d %d\n", skb_headroom(skb), len);
 		dev_kfree_skb(skb);
 		*skb_p = nskb;
 		return skb_push(nskb, len);
 	}
-	return skb_push(skb,len);
+	return skb_push(skb, len);
 }
 
 /*
@@ -1214,10 +1214,10 @@ static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
 int
 isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-	isdn_net_local *lp,*mlp;
+	isdn_net_local *lp, *mlp;
 	isdn_net_dev *nd;
 	unsigned int proto = PPP_IP;     /* 0x21 */
-	struct ippp_struct *ipt,*ipts;
+	struct ippp_struct *ipt, *ipts;
 	int slot, retval = NETDEV_TX_OK;
 
 	mlp = netdev_priv(netdev);
@@ -1226,7 +1226,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	slot = mlp->ppp_slot;
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
-			mlp->ppp_slot);
+		       mlp->ppp_slot);
 		kfree_skb(skb);
 		goto out;
 	}
@@ -1240,17 +1240,17 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	switch (ntohs(skb->protocol)) {
-		case ETH_P_IP:
-			proto = PPP_IP;
-			break;
-		case ETH_P_IPX:
-			proto = PPP_IPX;	/* untested */
-			break;
-		default:
-			printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n", 
-			       skb->protocol);
-			dev_kfree_skb(skb);
-			goto out;
+	case ETH_P_IP:
+		proto = PPP_IP;
+		break;
+	case ETH_P_IPX:
+		proto = PPP_IPX;	/* untested */
+		break;
+	default:
+		printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n",
+		       skb->protocol);
+		dev_kfree_skb(skb);
+		goto out;
 	}
 
 	lp = isdn_net_get_locked_lp(nd);
@@ -1264,7 +1264,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
-			lp->ppp_slot);
+		       lp->ppp_slot);
 		kfree_skb(skb);
 		goto unlock;
 	}
@@ -1277,7 +1277,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	/* Pull off the fake header we stuck on earlier to keep
 	 * the fragmentation code happy.
 	 */
-	skb_pull(skb,IPPP_MAX_HEADER);
+	skb_pull(skb, IPPP_MAX_HEADER);
 
 #ifdef CONFIG_IPPP_FILTER
 	/* check if we should pass this packet
@@ -1302,7 +1302,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	if (!(ipt->active_filter
 	      && sk_run_filter(skb, ipt->active_filter) == 0)) {
 		if (ipt->debug & 0x4)
-			printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
+			printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n");
 		lp->huptimer = 0;
 	}
 	skb_pull(skb, 4);
@@ -1312,26 +1312,26 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	if (ipt->debug & 0x4)
 		printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
-        if (ipts->debug & 0x40)
-                isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32,ipts->unit,lp->ppp_slot);
+	if (ipts->debug & 0x40)
+		isdn_ppp_frame_log("xmit0", skb->data, skb->len, 32, ipts->unit, lp->ppp_slot);
 
 #ifdef CONFIG_ISDN_PPP_VJ
 	if (proto == PPP_IP && ipts->pppcfg & SC_COMP_TCP) {	/* ipts here? probably yes, but check this again */
 		struct sk_buff *new_skb;
-	        unsigned short hl;
+		unsigned short hl;
 		/*
 		 * we need to reserve enough space in front of
 		 * sk_buff. old call to dev_alloc_skb only reserved
 		 * 16 bytes, now we are looking what the driver want.
 		 */
 		hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen + IPPP_MAX_HEADER;
-		/* 
+		/*
 		 * Note: hl might still be insufficient because the method
 		 * above does not account for a possibible MPPP slave channel
 		 * which had larger HL header space requirements than the
 		 * master.
 		 */
-		new_skb = alloc_skb(hl+skb->len, GFP_ATOMIC);
+		new_skb = alloc_skb(hl + skb->len, GFP_ATOMIC);
 		if (new_skb) {
 			u_char *buf;
 			int pktlen;
@@ -1342,9 +1342,9 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 			buf = skb->data;
 
 			pktlen = slhc_compress(ipts->slcomp, skb->data, skb->len, new_skb->data,
-				 &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
+					       &buf, !(ipts->pppcfg & SC_NO_TCP_CCID));
 
-			if (buf != skb->data) {	
+			if (buf != skb->data) {
 				if (new_skb->data != buf)
 					printk(KERN_ERR "isdn_ppp: FATAL error after slhc_compress!!\n");
 				dev_kfree_skb(skb);
@@ -1369,11 +1369,11 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	/*
 	 * normal (single link) or bundle compression
 	 */
-	if(ipts->compflags & SC_COMP_ON) {
+	if (ipts->compflags & SC_COMP_ON) {
 		/* We send compressed only if both down- und upstream
 		   compression is negotiated, that means, CCP is up */
-		if(ipts->compflags & SC_DECOMP_ON) {
-			skb = isdn_ppp_compress(skb,&proto,ipt,ipts,0);
+		if (ipts->compflags & SC_DECOMP_ON) {
+			skb = isdn_ppp_compress(skb, &proto, ipt, ipts, 0);
 		} else {
 			printk(KERN_DEBUG "isdn_ppp: CCP not yet up - sending as-is\n");
 		}
@@ -1389,7 +1389,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 		ipts->mp_seqno++;
 		if (ipt->mpppcfg & SC_OUT_SHORT_SEQ) {
 			unsigned char *data = isdn_ppp_skb_push(&skb, 3);
-			if(!data)
+			if (!data)
 				goto unlock;
 			mp_seqno &= 0xfff;
 			data[0] = MP_BEGIN_FRAG | MP_END_FRAG | ((mp_seqno >> 8) & 0xf);	/* (B)egin & (E)ndbit .. */
@@ -1397,7 +1397,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 			data[2] = proto;	/* PID compression */
 		} else {
 			unsigned char *data = isdn_ppp_skb_push(&skb, 5);
-			if(!data)
+			if (!data)
 				goto unlock;
 			data[0] = MP_BEGIN_FRAG | MP_END_FRAG;	/* (B)egin & (E)ndbit .. */
 			data[1] = (mp_seqno >> 16) & 0xff;	/* sequence number: 24bit */
@@ -1412,25 +1412,25 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	/*
 	 * 'link in bundle' compression  ...
 	 */
-	if(ipt->compflags & SC_LINK_COMP_ON)
-		skb = isdn_ppp_compress(skb,&proto,ipt,ipts,1);
+	if (ipt->compflags & SC_LINK_COMP_ON)
+		skb = isdn_ppp_compress(skb, &proto, ipt, ipts, 1);
 
-	if( (ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff) ) {
-		unsigned char *data = isdn_ppp_skb_push(&skb,1);
-		if(!data)
+	if ((ipt->pppcfg & SC_COMP_PROT) && (proto <= 0xff)) {
+		unsigned char *data = isdn_ppp_skb_push(&skb, 1);
+		if (!data)
 			goto unlock;
 		data[0] = proto & 0xff;
 	}
 	else {
-		unsigned char *data = isdn_ppp_skb_push(&skb,2);
-		if(!data)
+		unsigned char *data = isdn_ppp_skb_push(&skb, 2);
+		if (!data)
 			goto unlock;
 		data[0] = (proto >> 8) & 0xff;
 		data[1] = proto & 0xff;
 	}
-	if(!(ipt->pppcfg & SC_COMP_AC)) {
-		unsigned char *data = isdn_ppp_skb_push(&skb,2);
-		if(!data)
+	if (!(ipt->pppcfg & SC_COMP_AC)) {
+		unsigned char *data = isdn_ppp_skb_push(&skb, 2);
+		if (!data)
 			goto unlock;
 		data[0] = 0xff;    /* All Stations */
 		data[1] = 0x03;    /* Unnumbered information */
@@ -1440,14 +1440,14 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	if (ipts->debug & 0x40) {
 		printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len);
-		isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,lp->ppp_slot);
+		isdn_ppp_frame_log("xmit", skb->data, skb->len, 32, ipt->unit, lp->ppp_slot);
 	}
-	
+
 	isdn_net_writebuf_skb(lp, skb);
 
- unlock:
+unlock:
 	spin_unlock_bh(&lp->xmit_lock);
- out:
+out:
 	return retval;
 }
 
@@ -1488,12 +1488,12 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
 		p++;
 		*p = htons(proto);
 	}
-	
+
 	drop |= is->pass_filter
-	        && sk_run_filter(skb, is->pass_filter) == 0;
+		&& sk_run_filter(skb, is->pass_filter) == 0;
 	drop |= is->active_filter
-	        && sk_run_filter(skb, is->active_filter) == 0;
-	
+		&& sk_run_filter(skb, is->active_filter) == 0;
+
 	skb_push(skb, IPPP_MAX_HEADER - 4);
 	return drop;
 }
@@ -1502,8 +1502,8 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
 
 /* this is _not_ rfc1990 header, but something we convert both short and long
  * headers to for convinience's sake:
- * 	byte 0 is flags as in rfc1990
- *	bytes 1...4 is 24-bit seqence number converted to host byte order 
+ *	byte 0 is flags as in rfc1990
+ *	bytes 1...4 is 24-bit seqence number converted to host byte order
  */
 #define MP_HEADER_LEN	5
 
@@ -1511,51 +1511,51 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
 #define MP_SHORTSEQ_MASK	0x00000fff
 #define MP_LONGSEQ_MAX		MP_LONGSEQ_MASK
 #define MP_SHORTSEQ_MAX		MP_SHORTSEQ_MASK
-#define MP_LONGSEQ_MAXBIT	((MP_LONGSEQ_MASK+1)>>1)
-#define MP_SHORTSEQ_MAXBIT	((MP_SHORTSEQ_MASK+1)>>1)
+#define MP_LONGSEQ_MAXBIT	((MP_LONGSEQ_MASK + 1) >> 1)
+#define MP_SHORTSEQ_MAXBIT	((MP_SHORTSEQ_MASK + 1) >> 1)
 
 /* sequence-wrap safe comparisons (for long sequence)*/
-#define MP_LT(a,b)	((a-b)&MP_LONGSEQ_MAXBIT)
-#define MP_LE(a,b) 	!((b-a)&MP_LONGSEQ_MAXBIT)
-#define MP_GT(a,b) 	((b-a)&MP_LONGSEQ_MAXBIT)
-#define MP_GE(a,b)	!((a-b)&MP_LONGSEQ_MAXBIT)
+#define MP_LT(a, b)	((a - b) & MP_LONGSEQ_MAXBIT)
+#define MP_LE(a, b)	!((b - a) & MP_LONGSEQ_MAXBIT)
+#define MP_GT(a, b)	((b - a) & MP_LONGSEQ_MAXBIT)
+#define MP_GE(a, b)	!((a - b) & MP_LONGSEQ_MAXBIT)
 
-#define MP_SEQ(f)	((*(u32*)(f->data+1)))
+#define MP_SEQ(f)	((*(u32 *)(f->data + 1)))
 #define MP_FLAGS(f)	(f->data[0])
 
 static int isdn_ppp_mp_bundle_array_init(void)
 {
 	int i;
-	int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
-	if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
+	int sz = ISDN_MAX_CHANNELS * sizeof(ippp_bundle);
+	if ((isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL)
 		return -ENOMEM;
-	for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
+	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
 		spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
 	return 0;
 }
 
-static ippp_bundle * isdn_ppp_mp_bundle_alloc(void)
+static ippp_bundle *isdn_ppp_mp_bundle_alloc(void)
 {
 	int i;
-	for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
+	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
 		if (isdn_ppp_bundle_arr[i].ref_ct <= 0)
 			return (isdn_ppp_bundle_arr + i);
 	return NULL;
 }
 
-static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
+static int isdn_ppp_mp_init(isdn_net_local *lp, ippp_bundle *add_to)
 {
-	struct ippp_struct * is;
+	struct ippp_struct *is;
 
 	if (lp->ppp_slot < 0) {
 		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__func__, lp->ppp_slot);
-		return(-EINVAL);
+		       __func__, lp->ppp_slot);
+		return (-EINVAL);
 	}
 
 	is = ippp_table[lp->ppp_slot];
 	if (add_to) {
-		if( lp->netdev->pb )
+		if (lp->netdev->pb)
 			lp->netdev->pb->ref_ct--;
 		lp->netdev->pb = add_to;
 	} else {		/* first link in a bundle */
@@ -1568,76 +1568,76 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
 		lp->netdev->pb->seq = UINT_MAX;
 	}
 	lp->netdev->pb->ref_ct++;
-	
+
 	is->last_link_seqno = 0;
 	return 0;
 }
 
-static u32 isdn_ppp_mp_get_seq( int short_seq, 
-					struct sk_buff * skb, u32 last_seq );
-static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
-			struct sk_buff * from, struct sk_buff * to );
-static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
-				struct sk_buff * from, struct sk_buff * to );
-static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
-static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
-
-static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, 
-							struct sk_buff *skb)
+static u32 isdn_ppp_mp_get_seq(int short_seq,
+			       struct sk_buff *skb, u32 last_seq);
+static struct sk_buff *isdn_ppp_mp_discard(ippp_bundle *mp,
+					   struct sk_buff *from, struct sk_buff *to);
+static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
+				   struct sk_buff *from, struct sk_buff *to);
+static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
+static void isdn_ppp_mp_print_recv_pkt(int slot, struct sk_buff *skb);
+
+static void isdn_ppp_mp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
+				struct sk_buff *skb)
 {
 	struct ippp_struct *is;
-	isdn_net_local * lpq;
-	ippp_bundle * mp;
-	isdn_mppp_stats * stats;
-	struct sk_buff * newfrag, * frag, * start, *nextf;
+	isdn_net_local *lpq;
+	ippp_bundle *mp;
+	isdn_mppp_stats *stats;
+	struct sk_buff *newfrag, *frag, *start, *nextf;
 	u32 newseq, minseq, thisseq;
 	unsigned long flags;
 	int slot;
 
 	spin_lock_irqsave(&net_dev->pb->lock, flags);
-    	mp = net_dev->pb;
-        stats = &mp->stats;
+	mp = net_dev->pb;
+	stats = &mp->stats;
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
-			__func__, lp->ppp_slot);
+		       __func__, lp->ppp_slot);
 		stats->frame_drops++;
 		dev_kfree_skb(skb);
 		spin_unlock_irqrestore(&mp->lock, flags);
 		return;
 	}
 	is = ippp_table[slot];
-    	if( ++mp->frames > stats->max_queue_len )
+	if (++mp->frames > stats->max_queue_len)
 		stats->max_queue_len = mp->frames;
-	
+
 	if (is->debug & 0x8)
 		isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
 
-	newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, 
-						skb, is->last_link_seqno);
+	newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
+				     skb, is->last_link_seqno);
 
 
 	/* if this packet seq # is less than last already processed one,
-	 * toss it right away, but check for sequence start case first 
+	 * toss it right away, but check for sequence start case first
 	 */
-	if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
+	if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) {
 		mp->seq = newseq;	/* the first packet: required for
 					 * rfc1990 non-compliant clients --
 					 * prevents constant packet toss */
-	} else if( MP_LT(newseq, mp->seq) ) {
+	} else if (MP_LT(newseq, mp->seq)) {
 		stats->frame_drops++;
 		isdn_ppp_mp_free_skb(mp, skb);
 		spin_unlock_irqrestore(&mp->lock, flags);
 		return;
 	}
-	
+
 	/* find the minimum received sequence number over all links */
 	is->last_link_seqno = minseq = newseq;
 	for (lpq = net_dev->queue;;) {
 		slot = lpq->ppp_slot;
 		if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 			printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n",
-				__func__, lpq->ppp_slot);
+			       __func__, lpq->ppp_slot);
 		} else {
 			u32 lls = ippp_table[slot]->last_link_seqno;
 			if (MP_LT(lls, minseq))
@@ -1651,17 +1651,17 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
 					 * packets */
 	newfrag = skb;
 
-  	/* if this new fragment is before the first one, then enqueue it now. */
-  	if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
+	/* if this new fragment is before the first one, then enqueue it now. */
+	if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
 		newfrag->next = frag;
-    		mp->frags = frag = newfrag;
-    		newfrag = NULL;
-  	}
+		mp->frags = frag = newfrag;
+		newfrag = NULL;
+	}
 
-  	start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
-				MP_SEQ(frag) == mp->seq ? frag : NULL;
+	start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
+		MP_SEQ(frag) == mp->seq ? frag : NULL;
 
-	/* 
+	/*
 	 * main fragment traversing loop
 	 *
 	 * try to accomplish several tasks:
@@ -1675,71 +1675,71 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
 	 *   come to complete such sequence and it should be discarded
 	 *
 	 * loop completes when we accomplished the following tasks:
-	 * - new fragment is inserted in the proper sequence ('newfrag' is 
+	 * - new fragment is inserted in the proper sequence ('newfrag' is
 	 *   set to NULL)
-	 * - we hit a gap in the sequence, so no reassembly/processing is 
+	 * - we hit a gap in the sequence, so no reassembly/processing is
 	 *   possible ('start' would be set to NULL)
 	 *
 	 * algorithm for this code is derived from code in the book
 	 * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
 	 */
-  	while (start != NULL || newfrag != NULL) {
-
-    		thisseq = MP_SEQ(frag);
-    		nextf = frag->next;
-
-    		/* drop any duplicate fragments */
-    		if (newfrag != NULL && thisseq == newseq) {
-      			isdn_ppp_mp_free_skb(mp, newfrag);
-      			newfrag = NULL;
-    		}
-
-    		/* insert new fragment before next element if possible. */
-    		if (newfrag != NULL && (nextf == NULL || 
-						MP_LT(newseq, MP_SEQ(nextf)))) {
-      			newfrag->next = nextf;
-      			frag->next = nextf = newfrag;
-      			newfrag = NULL;
-    		}
-
-    		if (start != NULL) {
-	    		/* check for misplaced start */
-      			if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
+	while (start != NULL || newfrag != NULL) {
+
+		thisseq = MP_SEQ(frag);
+		nextf = frag->next;
+
+		/* drop any duplicate fragments */
+		if (newfrag != NULL && thisseq == newseq) {
+			isdn_ppp_mp_free_skb(mp, newfrag);
+			newfrag = NULL;
+		}
+
+		/* insert new fragment before next element if possible. */
+		if (newfrag != NULL && (nextf == NULL ||
+					MP_LT(newseq, MP_SEQ(nextf)))) {
+			newfrag->next = nextf;
+			frag->next = nextf = newfrag;
+			newfrag = NULL;
+		}
+
+		if (start != NULL) {
+			/* check for misplaced start */
+			if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
 				printk(KERN_WARNING"isdn_mppp(seq %d): new "
-				      "BEGIN flag with no prior END", thisseq);
+				       "BEGIN flag with no prior END", thisseq);
 				stats->seqerrs++;
 				stats->frame_drops++;
-				start = isdn_ppp_mp_discard(mp, start,frag);
+				start = isdn_ppp_mp_discard(mp, start, frag);
 				nextf = frag->next;
-      			}
-    		} else if (MP_LE(thisseq, minseq)) {		
-      			if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
+			}
+		} else if (MP_LE(thisseq, minseq)) {
+			if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
 				start = frag;
-      			else {
+			else {
 				if (MP_FLAGS(frag) & MP_END_FRAG)
-	  				stats->frame_drops++;
-				if( mp->frags == frag )
-					mp->frags = nextf;	
+					stats->frame_drops++;
+				if (mp->frags == frag)
+					mp->frags = nextf;
 				isdn_ppp_mp_free_skb(mp, frag);
 				frag = nextf;
 				continue;
-      			}
+			}
 		}
-		
+
 		/* if start is non-null and we have end fragment, then
-		 * we have full reassembly sequence -- reassemble 
+		 * we have full reassembly sequence -- reassemble
 		 * and process packet now
 		 */
-    		if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
-      			minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
-      			/* Reassemble the packet then dispatch it */
+		if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
+			minseq = mp->seq = (thisseq + 1) & MP_LONGSEQ_MASK;
+			/* Reassemble the packet then dispatch it */
 			isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
-      
-      			start = NULL;
-      			frag = NULL;
 
-      			mp->frags = nextf;
-    		}
+			start = NULL;
+			frag = NULL;
+
+			mp->frags = nextf;
+		}
 
 		/* check if need to update start pointer: if we just
 		 * reassembled the packet and sequence is contiguous
@@ -1749,48 +1749,48 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
 		 * if sequence is not contiguous, either clear everything
 		 * below low watermark and set start to the next frag or
 		 * clear start ptr.
-		 */ 
-    		if (nextf != NULL && 
-		    ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
-      			/* if we just reassembled and the next one is here, 
+		 */
+		if (nextf != NULL &&
+		    ((thisseq + 1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
+			/* if we just reassembled and the next one is here,
 			 * then start another reassembly. */
 
-      			if (frag == NULL) {
+			if (frag == NULL) {
 				if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
-	  				start = nextf;
+					start = nextf;
 				else
 				{
-	  				printk(KERN_WARNING"isdn_mppp(seq %d):"
-						" END flag with no following "
-						"BEGIN", thisseq);
+					printk(KERN_WARNING"isdn_mppp(seq %d):"
+					       " END flag with no following "
+					       "BEGIN", thisseq);
 					stats->seqerrs++;
 				}
 			}
 
-    		} else {
-			if ( nextf != NULL && frag != NULL &&
-						MP_LT(thisseq, minseq)) {
+		} else {
+			if (nextf != NULL && frag != NULL &&
+			    MP_LT(thisseq, minseq)) {
 				/* we've got a break in the sequence
 				 * and we not at the end yet
 				 * and we did not just reassembled
 				 *(if we did, there wouldn't be anything before)
-				 * and we below the low watermark 
-			 	 * discard all the frames below low watermark 
+				 * and we below the low watermark
+				 * discard all the frames below low watermark
 				 * and start over */
 				stats->frame_drops++;
-				mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
+				mp->frags = isdn_ppp_mp_discard(mp, start, nextf);
 			}
 			/* break in the sequence, no reassembly */
-      			start = NULL;
-    		}
-	  			
-    		frag = nextf;
-  	}	/* while -- main loop */
-	
-  	if (mp->frags == NULL)
-    		mp->frags = frag;
-		
-	/* rather straighforward way to deal with (not very) possible 
+			start = NULL;
+		}
+
+		frag = nextf;
+	}	/* while -- main loop */
+
+	if (mp->frags == NULL)
+		mp->frags = frag;
+
+	/* rather straighforward way to deal with (not very) possible
 	 * queue overflow */
 	if (mp->frames > MP_MAX_QUEUE_LEN) {
 		stats->overflows++;
@@ -1803,11 +1803,11 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
 	spin_unlock_irqrestore(&mp->lock, flags);
 }
 
-static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
+static void isdn_ppp_mp_cleanup(isdn_net_local *lp)
 {
-	struct sk_buff * frag = lp->netdev->pb->frags;
-	struct sk_buff * nextfrag;
-    	while( frag ) {
+	struct sk_buff *frag = lp->netdev->pb->frags;
+	struct sk_buff *nextfrag;
+	while (frag) {
 		nextfrag = frag->next;
 		isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
 		frag = nextfrag;
@@ -1815,117 +1815,117 @@ static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
 	lp->netdev->pb->frags = NULL;
 }
 
-static u32 isdn_ppp_mp_get_seq( int short_seq, 
-					struct sk_buff * skb, u32 last_seq )
+static u32 isdn_ppp_mp_get_seq(int short_seq,
+			       struct sk_buff *skb, u32 last_seq)
 {
 	u32 seq;
 	int flags = skb->data[0] & (MP_BEGIN_FRAG | MP_END_FRAG);
-   
-   	if( !short_seq )
+
+	if (!short_seq)
 	{
 		seq = ntohl(*(__be32 *)skb->data) & MP_LONGSEQ_MASK;
-		skb_push(skb,1);
+		skb_push(skb, 1);
 	}
 	else
 	{
-		/* convert 12-bit short seq number to 24-bit long one 
-	 	*/
+		/* convert 12-bit short seq number to 24-bit long one
+		 */
 		seq = ntohs(*(__be16 *)skb->data) & MP_SHORTSEQ_MASK;
-	
+
 		/* check for seqence wrap */
-		if( !(seq &  MP_SHORTSEQ_MAXBIT) && 
-		     (last_seq &  MP_SHORTSEQ_MAXBIT) && 
-		     (unsigned long)last_seq <= MP_LONGSEQ_MAX )
-			seq |= (last_seq + MP_SHORTSEQ_MAX+1) & 
-					(~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
+		if (!(seq &  MP_SHORTSEQ_MAXBIT) &&
+		    (last_seq &  MP_SHORTSEQ_MAXBIT) &&
+		    (unsigned long)last_seq <= MP_LONGSEQ_MAX)
+			seq |= (last_seq + MP_SHORTSEQ_MAX + 1) &
+				(~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
 		else
 			seq |= last_seq & (~MP_SHORTSEQ_MASK & MP_LONGSEQ_MASK);
-		
+
 		skb_push(skb, 3);	/* put converted seqence back in skb */
 	}
-	*(u32*)(skb->data+1) = seq; 	/* put seqence back in _host_ byte
+	*(u32 *)(skb->data + 1) = seq;	/* put seqence back in _host_ byte
 					 * order */
 	skb->data[0] = flags;	        /* restore flags */
 	return seq;
 }
 
-struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
-			struct sk_buff * from, struct sk_buff * to )
+struct sk_buff *isdn_ppp_mp_discard(ippp_bundle *mp,
+				    struct sk_buff *from, struct sk_buff *to)
 {
-	if( from )
+	if (from)
 		while (from != to) {
-	  		struct sk_buff * next = from->next;
+			struct sk_buff *next = from->next;
 			isdn_ppp_mp_free_skb(mp, from);
-	  		from = next;
+			from = next;
 		}
 	return from;
 }
 
-void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
-				struct sk_buff * from, struct sk_buff * to )
+void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
+			    struct sk_buff *from, struct sk_buff *to)
 {
-	ippp_bundle * mp = net_dev->pb;
+	ippp_bundle *mp = net_dev->pb;
 	int proto;
-	struct sk_buff * skb;
+	struct sk_buff *skb;
 	unsigned int tot_len;
 
 	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__func__, lp->ppp_slot);
+		       __func__, lp->ppp_slot);
 		return;
 	}
-	if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
-		if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+	if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
+		if (ippp_table[lp->ppp_slot]->debug & 0x40)
 			printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
-					"len %d\n", MP_SEQ(from), from->len );
+			       "len %d\n", MP_SEQ(from), from->len);
 		skb = from;
 		skb_pull(skb, MP_HEADER_LEN);
-		mp->frames--;	
+		mp->frames--;
 	} else {
-		struct sk_buff * frag;
+		struct sk_buff *frag;
 		int n;
 
-		for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
+		for (tot_len = n = 0, frag = from; frag != to; frag = frag->next, n++)
 			tot_len += frag->len - MP_HEADER_LEN;
 
-		if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+		if (ippp_table[lp->ppp_slot]->debug & 0x40)
 			printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
-				"to %d, len %d\n", MP_SEQ(from), 
-				(MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
-		if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
+			       "to %d, len %d\n", MP_SEQ(from),
+			       (MP_SEQ(from) + n - 1) & MP_LONGSEQ_MASK, tot_len);
+		if ((skb = dev_alloc_skb(tot_len)) == NULL) {
 			printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
-					"of size %d\n", tot_len);
+			       "of size %d\n", tot_len);
 			isdn_ppp_mp_discard(mp, from, to);
 			return;
 		}
 
-		while( from != to ) {
+		while (from != to) {
 			unsigned int len = from->len - MP_HEADER_LEN;
 
 			skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
-							 skb_put(skb,len),
+							 skb_put(skb, len),
 							 len);
 			frag = from->next;
 			isdn_ppp_mp_free_skb(mp, from);
-			from = frag; 
+			from = frag;
 		}
 	}
-   	proto = isdn_ppp_strip_proto(skb);
+	proto = isdn_ppp_strip_proto(skb);
 	isdn_ppp_push_higher(net_dev, lp, skb, proto);
 }
 
-static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
+static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb)
 {
 	dev_kfree_skb(skb);
 	mp->frames--;
 }
 
-static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb )
+static void isdn_ppp_mp_print_recv_pkt(int slot, struct sk_buff *skb)
 {
-	printk(KERN_DEBUG "mp_recv: %d/%d -> %02x %02x %02x %02x %02x %02x\n", 
-		slot, (int) skb->len, 
-		(int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
-		(int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
+	printk(KERN_DEBUG "mp_recv: %d/%d -> %02x %02x %02x %02x %02x %02x\n",
+	       slot, (int) skb->len,
+	       (int) skb->data[0], (int) skb->data[1], (int) skb->data[2],
+	       (int) skb->data[3], (int) skb->data[4], (int) skb->data[5]);
 }
 
 static int
@@ -1944,18 +1944,18 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit)
 		return -EINVAL;
 	}
 
-    	spin_lock_irqsave(&p->pb->lock, flags);
+	spin_lock_irqsave(&p->pb->lock, flags);
 
 	nlp = is->lp;
 	lp = p->queue;
-	if( nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ||
-		lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS ) {
+	if (nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ||
+	    lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n",
-			nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ? 
-			nlp->ppp_slot : lp->ppp_slot );
+		       nlp->ppp_slot < 0 || nlp->ppp_slot >= ISDN_MAX_CHANNELS ?
+		       nlp->ppp_slot : lp->ppp_slot);
 		rc = -EINVAL;
 		goto out;
- 	}
+	}
 
 	isdn_net_add_to_bundle(p, nlp);
 
@@ -1971,9 +1971,9 @@ out:
 	spin_unlock_irqrestore(&p->pb->lock, flags);
 	return rc;
 }
-  
+
 #endif /* CONFIG_ISDN_MPP */
-  
+
 /*
  * network device ioctl handlers
  */
@@ -2020,7 +2020,7 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
 int
 isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	int error=0;
+	int error = 0;
 	int len;
 	isdn_net_local *lp = netdev_priv(dev);
 
@@ -2030,18 +2030,18 @@ isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 	switch (cmd) {
 #define PPP_VERSION "2.3.7"
-		case SIOCGPPPVER:
-			len = strlen(PPP_VERSION) + 1;
-			if (copy_to_user(ifr->ifr_data, PPP_VERSION, len))
-				error = -EFAULT;
-			break;
+	case SIOCGPPPVER:
+		len = strlen(PPP_VERSION) + 1;
+		if (copy_to_user(ifr->ifr_data, PPP_VERSION, len))
+			error = -EFAULT;
+		break;
 
-		case SIOCGPPPSTATS:
-			error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
-			break;
-		default:
-			error = -EINVAL;
-			break;
+	case SIOCGPPPSTATS:
+		error = isdn_ppp_dev_ioctl_stats(lp->ppp_slot, ifr, dev);
+		break;
+	default:
+		error = -EINVAL;
+		break;
 	}
 	return error;
 }
@@ -2050,9 +2050,9 @@ static int
 isdn_ppp_if_get_unit(char *name)
 {
 	int len,
-	 i,
-	 unit = 0,
-	 deci;
+		i,
+		unit = 0,
+		deci;
 
 	len = strlen(name);
 
@@ -2129,7 +2129,7 @@ isdn_ppp_hangup_slave(char *name)
 				break;
 		} else if (mlp->flags & ISDN_NET_CONNECTED)
 			break;
-		
+
 		sdev = mlp->slave;
 	}
 	if (!sdev)
@@ -2202,8 +2202,8 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
 
 	/* Alloc large enough skb */
 	hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
-	skb = alloc_skb(len + hl + 16,GFP_ATOMIC);
-	if(!skb) {
+	skb = alloc_skb(len + hl + 16, GFP_ATOMIC);
+	if (!skb) {
 		printk(KERN_WARNING
 		       "ippp: CCP cannot send reset - out of memory\n");
 		return;
@@ -2211,7 +2211,7 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
 	skb_reserve(skb, hl);
 
 	/* We may need to stuff an address and control field first */
-	if(!(is->pppcfg & SC_COMP_AC)) {
+	if (!(is->pppcfg & SC_COMP_AC)) {
 		p = skb_put(skb, 2);
 		*p++ = 0xff;
 		*p++ = 0x03;
@@ -2228,14 +2228,14 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
 	*p++ = (cnt & 0xff);
 
 	/* Now stuff remaining bytes */
-	if(len) {
+	if (len) {
 		p = skb_put(skb, len);
 		memcpy(p, data, len);
 	}
 
 	/* skb is now ready for xmit */
 	printk(KERN_DEBUG "Sending CCP Frame:\n");
-	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
+	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
 
 	isdn_net_write_super(lp, skb);
 }
@@ -2245,7 +2245,7 @@ static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is)
 {
 	struct ippp_ccp_reset *r;
 	r = kzalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL);
-	if(!r) {
+	if (!r) {
 		printk(KERN_ERR "ippp_ccp: failed to allocate reset data"
 		       " structure - no mem\n");
 		return NULL;
@@ -2262,8 +2262,8 @@ static void isdn_ppp_ccp_reset_free(struct ippp_struct *is)
 
 	printk(KERN_DEBUG "ippp_ccp: freeing reset data structure %p\n",
 	       is->reset);
-	for(id = 0; id < 256; id++) {
-		if(is->reset->rs[id]) {
+	for (id = 0; id < 256; id++) {
+		if (is->reset->rs[id]) {
 			isdn_ppp_ccp_reset_free_state(is, (unsigned char)id);
 		}
 	}
@@ -2277,11 +2277,11 @@ static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is,
 {
 	struct ippp_ccp_reset_state *rs;
 
-	if(is->reset->rs[id]) {
+	if (is->reset->rs[id]) {
 		printk(KERN_DEBUG "ippp_ccp: freeing state for id %d\n", id);
 		rs = is->reset->rs[id];
 		/* Make sure the kernel will not call back later */
-		if(rs->ta)
+		if (rs->ta)
 			del_timer(&rs->timer);
 		is->reset->rs[id] = NULL;
 		kfree(rs);
@@ -2297,13 +2297,13 @@ static void isdn_ppp_ccp_timer_callback(unsigned long closure)
 	struct ippp_ccp_reset_state *rs =
 		(struct ippp_ccp_reset_state *)closure;
 
-	if(!rs) {
+	if (!rs) {
 		printk(KERN_ERR "ippp_ccp: timer cb with zero closure.\n");
 		return;
 	}
-	if(rs->ta && rs->state == CCPResetSentReq) {
+	if (rs->ta && rs->state == CCPResetSentReq) {
 		/* We are correct here */
-		if(!rs->expra) {
+		if (!rs->expra) {
 			/* Hmm, there is no Ack really expected. We can clean
 			   up the state now, it will be reallocated if the
 			   decompressor insists on another reset */
@@ -2317,7 +2317,7 @@ static void isdn_ppp_ccp_timer_callback(unsigned long closure)
 		isdn_ppp_ccp_xmit_reset(rs->is, PPP_CCP, CCP_RESETREQ, rs->id,
 					rs->data, rs->dlen);
 		/* Restart timer */
-		rs->timer.expires = jiffies + HZ*5;
+		rs->timer.expires = jiffies + HZ * 5;
 		add_timer(&rs->timer);
 	} else {
 		printk(KERN_WARNING "ippp_ccp: timer cb in wrong state %d\n",
@@ -2327,16 +2327,16 @@ static void isdn_ppp_ccp_timer_callback(unsigned long closure)
 
 /* Allocate a new reset transaction state */
 static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_struct *is,
-						      unsigned char id)
+								   unsigned char id)
 {
 	struct ippp_ccp_reset_state *rs;
-	if(is->reset->rs[id]) {
+	if (is->reset->rs[id]) {
 		printk(KERN_WARNING "ippp_ccp: old state exists for id %d\n",
 		       id);
 		return NULL;
 	} else {
 		rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
-		if(!rs)
+		if (!rs)
 			return NULL;
 		rs->state = CCPResetIdle;
 		rs->is = is;
@@ -2357,21 +2357,21 @@ static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 {
 	struct ippp_ccp_reset_state *rs;
 
-	if(rp->valid) {
+	if (rp->valid) {
 		/* The decompressor defines parameters by itself */
-		if(rp->rsend) {
+		if (rp->rsend) {
 			/* And he wants us to send a request */
-			if(!(rp->idval)) {
+			if (!(rp->idval)) {
 				printk(KERN_ERR "ippp_ccp: decompressor must"
 				       " specify reset id\n");
 				return;
 			}
-			if(is->reset->rs[rp->id]) {
+			if (is->reset->rs[rp->id]) {
 				/* There is already a transaction in existence
 				   for this id. May be still waiting for a
 				   Ack or may be wrong. */
 				rs = is->reset->rs[rp->id];
-				if(rs->state == CCPResetSentReq && rs->ta) {
+				if (rs->state == CCPResetSentReq && rs->ta) {
 					printk(KERN_DEBUG "ippp_ccp: reset"
 					       " trans still in progress"
 					       " for id %d\n", rp->id);
@@ -2385,14 +2385,14 @@ static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 				printk(KERN_DEBUG "ippp_ccp: new trans for id"
 				       " %d to be started\n", rp->id);
 				rs = isdn_ppp_ccp_reset_alloc_state(is, rp->id);
-				if(!rs) {
+				if (!rs) {
 					printk(KERN_ERR "ippp_ccp: out of mem"
 					       " allocing ccp trans\n");
 					return;
 				}
 				rs->state = CCPResetSentReq;
 				rs->expra = rp->expra;
-				if(rp->dtval) {
+				if (rp->dtval) {
 					rs->dlen = rp->dlen;
 					memcpy(rs->data, rp->data, rp->dlen);
 				}
@@ -2401,7 +2401,7 @@ static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 							CCP_RESETREQ, rs->id,
 							rs->data, rs->dlen);
 				/* Start the timer */
-				rs->timer.expires = jiffies + 5*HZ;
+				rs->timer.expires = jiffies + 5 * HZ;
 				add_timer(&rs->timer);
 				rs->ta = 1;
 			}
@@ -2413,12 +2413,12 @@ static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 		   care about them, so we just send the minimal requests
 		   and increase ids only when an Ack is received for a
 		   given id */
-		if(is->reset->rs[is->reset->lastid]) {
+		if (is->reset->rs[is->reset->lastid]) {
 			/* There is already a transaction in existence
 			   for this id. May be still waiting for a
 			   Ack or may be wrong. */
 			rs = is->reset->rs[is->reset->lastid];
-			if(rs->state == CCPResetSentReq && rs->ta) {
+			if (rs->state == CCPResetSentReq && rs->ta) {
 				printk(KERN_DEBUG "ippp_ccp: reset"
 				       " trans still in progress"
 				       " for id %d\n", rp->id);
@@ -2432,7 +2432,7 @@ static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 			       " %d to be started\n", is->reset->lastid);
 			rs = isdn_ppp_ccp_reset_alloc_state(is,
 							    is->reset->lastid);
-			if(!rs) {
+			if (!rs) {
 				printk(KERN_ERR "ippp_ccp: out of mem"
 				       " allocing ccp trans\n");
 				return;
@@ -2446,7 +2446,7 @@ static void isdn_ppp_ccp_reset_trans(struct ippp_struct *is,
 			isdn_ppp_ccp_xmit_reset(is, PPP_CCP, CCP_RESETREQ,
 						rs->id, NULL, 0);
 			/* Start the timer */
-			rs->timer.expires = jiffies + 5*HZ;
+			rs->timer.expires = jiffies + 5 * HZ;
 			add_timer(&rs->timer);
 			rs->ta = 1;
 		}
@@ -2460,17 +2460,17 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
 {
 	struct ippp_ccp_reset_state *rs = is->reset->rs[id];
 
-	if(rs) {
-		if(rs->ta && rs->state == CCPResetSentReq) {
+	if (rs) {
+		if (rs->ta && rs->state == CCPResetSentReq) {
 			/* Great, we are correct */
-			if(!rs->expra)
+			if (!rs->expra)
 				printk(KERN_DEBUG "ippp_ccp: ResetAck received"
 				       " for id %d but not expected\n", id);
 		} else {
 			printk(KERN_INFO "ippp_ccp: ResetAck received out of"
 			       "sync for id %d\n", id);
 		}
-		if(rs->ta) {
+		if (rs->ta) {
 			rs->ta = 0;
 			del_timer(&rs->timer);
 		}
@@ -2483,7 +2483,7 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
 	is->reset->lastid++;
 }
 
-/* 
+/*
  * decompress packet
  *
  * if master = 0, we're trying to uncompress an per-link compressed packet,
@@ -2495,8 +2495,8 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
  *	   NULL if decompression error
  */
 
-static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struct *is,struct ippp_struct *master,
-	int *proto)
+static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb, struct ippp_struct *is, struct ippp_struct *master,
+					   int *proto)
 {
 	void *stat = NULL;
 	struct isdn_ppp_compressor *ipc = NULL;
@@ -2506,8 +2506,8 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc
 	struct isdn_ppp_resetparams rsparm;
 	unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
 
-	if(!master) {
-		// per-link decompression 
+	if (!master) {
+		// per-link decompression
 		stat = is->link_decomp_stat;
 		ipc = is->link_decompressor;
 		ri = is;
@@ -2524,28 +2524,28 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc
 	}
 	BUG_ON(!stat); // if we have a compressor, stat has been set as well
 
-	if((master && *proto == PPP_COMP) || (!master && *proto == PPP_COMPFRAG) ) {
+	if ((master && *proto == PPP_COMP) || (!master && *proto == PPP_COMPFRAG)) {
 		// compressed packets are compressed by their protocol type
 
 		// Set up reset params for the decompressor
-  		memset(&rsparm, 0, sizeof(rsparm));
-  		rsparm.data = rsdata;
-  		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
-  
-  		skb_out = dev_alloc_skb(is->mru + PPP_HDRLEN);
-  		if (!skb_out) {
-  			kfree_skb(skb);
-  			printk(KERN_ERR "ippp: decomp memory allocation failure\n");
+		memset(&rsparm, 0, sizeof(rsparm));
+		rsparm.data = rsdata;
+		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
+
+		skb_out = dev_alloc_skb(is->mru + PPP_HDRLEN);
+		if (!skb_out) {
+			kfree_skb(skb);
+			printk(KERN_ERR "ippp: decomp memory allocation failure\n");
 			return NULL;
-  		}
+		}
 		len = ipc->decompress(stat, skb, skb_out, &rsparm);
 		kfree_skb(skb);
 		if (len <= 0) {
-			switch(len) {
+			switch (len) {
 			case DECOMP_ERROR:
 				printk(KERN_INFO "ippp: decomp wants reset %s params\n",
 				       rsparm.valid ? "with" : "without");
-				
+
 				isdn_ppp_ccp_reset_trans(ri, &rsparm);
 				break;
 			case DECOMP_FATALERROR:
@@ -2563,7 +2563,7 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc
 			return NULL;
 		}
 		return skb_out;
-	} else { 
+	} else {
 		// uncompressed packets are fed through the decompressor to
 		// update the decompressor state
 		ipc->incomp(stat, skb, *proto);
@@ -2572,31 +2572,31 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc
 }
 
 /*
- * compress a frame 
+ * compress a frame
  *   type=0: normal/bundle compression
  *       =1: link compression
  * returns original skb if we haven't compressed the frame
  * and a new skb pointer if we've done it
  */
-static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
-	struct ippp_struct *is,struct ippp_struct *master,int type)
+static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in, int *proto,
+					 struct ippp_struct *is, struct ippp_struct *master, int type)
 {
-    int ret;
-    int new_proto;
-    struct isdn_ppp_compressor *compressor;
-    void *stat;
-    struct sk_buff *skb_out;
+	int ret;
+	int new_proto;
+	struct isdn_ppp_compressor *compressor;
+	void *stat;
+	struct sk_buff *skb_out;
 
 	/* we do not compress control protocols */
-    if(*proto < 0 || *proto > 0x3fff) {
-	    return skb_in;
-    }
+	if (*proto < 0 || *proto > 0x3fff) {
+		return skb_in;
+	}
 
-	if(type) { /* type=1 => Link compression */
+	if (type) { /* type=1 => Link compression */
 		return skb_in;
 	}
 	else {
-		if(!master) {
+		if (!master) {
 			compressor = is->compressor;
 			stat = is->comp_stat;
 		}
@@ -2607,90 +2607,90 @@ static struct sk_buff *isdn_ppp_compress(struct sk_buff *skb_in,int *proto,
 		new_proto = PPP_COMP;
 	}
 
-	if(!compressor) {
+	if (!compressor) {
 		printk(KERN_ERR "isdn_ppp: No compressor set!\n");
 		return skb_in;
 	}
-	if(!stat) {
+	if (!stat) {
 		printk(KERN_ERR "isdn_ppp: Compressor not initialized?\n");
 		return skb_in;
 	}
 
 	/* Allow for at least 150 % expansion (for now) */
-	skb_out = alloc_skb(skb_in->len + skb_in->len/2 + 32 +
-		skb_headroom(skb_in), GFP_ATOMIC);
-	if(!skb_out)
+	skb_out = alloc_skb(skb_in->len + skb_in->len / 2 + 32 +
+			    skb_headroom(skb_in), GFP_ATOMIC);
+	if (!skb_out)
 		return skb_in;
 	skb_reserve(skb_out, skb_headroom(skb_in));
 
-	ret = (compressor->compress)(stat,skb_in,skb_out,*proto);
-	if(!ret) {
+	ret = (compressor->compress)(stat, skb_in, skb_out, *proto);
+	if (!ret) {
 		dev_kfree_skb(skb_out);
 		return skb_in;
 	}
-	
+
 	dev_kfree_skb(skb_in);
 	*proto = new_proto;
 	return skb_out;
 }
 
 /*
- * we received a CCP frame .. 
+ * we received a CCP frame ..
  * not a clean solution, but we MUST handle a few cases in the kernel
  */
 static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
-	 struct sk_buff *skb,int proto)
+				 struct sk_buff *skb, int proto)
 {
 	struct ippp_struct *is;
 	struct ippp_struct *mis;
 	int len;
 	struct isdn_ppp_resetparams rsparm;
-	unsigned char rsdata[IPPP_RESET_MAXDATABYTES];	
+	unsigned char rsdata[IPPP_RESET_MAXDATABYTES];
 
 	printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n",
-		lp->ppp_slot);
+	       lp->ppp_slot);
 	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__func__, lp->ppp_slot);
+		       __func__, lp->ppp_slot);
 		return;
 	}
 	is = ippp_table[lp->ppp_slot];
-	isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
+	isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
 
-	if(lp->master) {
+	if (lp->master) {
 		int slot = ISDN_MASTER_PRIV(lp)->ppp_slot;
 		if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 			printk(KERN_ERR "%s: slot(%d) out of range\n",
-				__func__, slot);
+			       __func__, slot);
 			return;
-		}	
+		}
 		mis = ippp_table[slot];
 	} else
 		mis = is;
 
-	switch(skb->data[0]) {
+	switch (skb->data[0]) {
 	case CCP_CONFREQ:
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Disable compression here!\n");
-		if(proto == PPP_CCP)
-			mis->compflags &= ~SC_COMP_ON;		
+		if (proto == PPP_CCP)
+			mis->compflags &= ~SC_COMP_ON;
 		else
-			is->compflags &= ~SC_LINK_COMP_ON;		
+			is->compflags &= ~SC_LINK_COMP_ON;
 		break;
 	case CCP_TERMREQ:
 	case CCP_TERMACK:
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Disable (de)compression here!\n");
-		if(proto == PPP_CCP)
-			mis->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);		
+		if (proto == PPP_CCP)
+			mis->compflags &= ~(SC_DECOMP_ON | SC_COMP_ON);
 		else
-			is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);		
+			is->compflags &= ~(SC_LINK_DECOMP_ON | SC_LINK_COMP_ON);
 		break;
 	case CCP_CONFACK:
 		/* if we RECEIVE an ackowledge we enable the decompressor */
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Enable decompression here!\n");
-		if(proto == PPP_CCP) {
+		if (proto == PPP_CCP) {
 			if (!mis->decompressor)
 				break;
 			mis->compflags |= SC_DECOMP_ON;
@@ -2706,11 +2706,11 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 		len = (skb->data[2] << 8) | skb->data[3];
 		len -= 4;
 
-		if(proto == PPP_CCP) {
+		if (proto == PPP_CCP) {
 			/* If a reset Ack was outstanding for this id, then
 			   clean up the state engine */
 			isdn_ppp_ccp_reset_ack_rcvd(mis, skb->data[1]);
-			if(mis->decompressor && mis->decomp_stat)
+			if (mis->decompressor && mis->decomp_stat)
 				mis->decompressor->
 					reset(mis->decomp_stat,
 					      skb->data[0],
@@ -2722,7 +2722,7 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 		}
 		else {
 			isdn_ppp_ccp_reset_ack_rcvd(is, skb->data[1]);
-			if(is->link_decompressor && is->link_decomp_stat)
+			if (is->link_decompressor && is->link_decomp_stat)
 				is->link_decompressor->
 					reset(is->link_decomp_stat,
 					      skb->data[0],
@@ -2740,12 +2740,12 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 		/* Set up reset params for the reset entry */
 		memset(&rsparm, 0, sizeof(rsparm));
 		rsparm.data = rsdata;
-		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES; 
+		rsparm.maxdlen = IPPP_RESET_MAXDATABYTES;
 		/* Isolate data length */
 		len = (skb->data[2] << 8) | skb->data[3];
 		len -= 4;
-		if(proto == PPP_CCP) {
-			if(mis->compressor && mis->comp_stat)
+		if (proto == PPP_CCP) {
+			if (mis->compressor && mis->comp_stat)
 				mis->compressor->
 					reset(mis->comp_stat,
 					      skb->data[0],
@@ -2754,7 +2754,7 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 					      len, &rsparm);
 		}
 		else {
-			if(is->link_compressor && is->link_comp_stat)
+			if (is->link_compressor && is->link_comp_stat)
 				is->link_compressor->
 					reset(is->link_comp_stat,
 					      skb->data[0],
@@ -2763,9 +2763,9 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 					      len, &rsparm);
 		}
 		/* Ack the Req as specified by rsparm */
-		if(rsparm.valid) {
+		if (rsparm.valid) {
 			/* Compressor reset handler decided how to answer */
-			if(rsparm.rsend) {
+			if (rsparm.rsend) {
 				/* We should send a Frame */
 				isdn_ppp_ccp_xmit_reset(is, proto, CCP_RESETACK,
 							rsparm.idval ? rsparm.id
@@ -2817,69 +2817,69 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 
 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
 {
-	struct ippp_struct *mis,*is;
+	struct ippp_struct *mis, *is;
 	int proto, slot = lp->ppp_slot;
 	unsigned char *data;
 
-	if(!skb || skb->len < 3)
+	if (!skb || skb->len < 3)
 		return;
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__func__, slot);
+		       __func__, slot);
 		return;
-	}	
+	}
 	is = ippp_table[slot];
 	/* Daemon may send with or without address and control field comp */
 	data = skb->data;
-	if(!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
+	if (!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
 		data += 2;
-		if(skb->len < 5)
+		if (skb->len < 5)
 			return;
 	}
 
-	proto = ((int)data[0]<<8)+data[1];
-	if(proto != PPP_CCP && proto != PPP_CCPFRAG)
+	proto = ((int)data[0]<<8) + data[1];
+	if (proto != PPP_CCP && proto != PPP_CCPFRAG)
 		return;
 
 	printk(KERN_DEBUG "Received CCP frame from daemon:\n");
-	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
+	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit, lp->ppp_slot);
 
 	if (lp->master) {
 		slot = ISDN_MASTER_PRIV(lp)->ppp_slot;
 		if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
 			printk(KERN_ERR "%s: slot(%d) out of range\n",
-				__func__, slot);
+			       __func__, slot);
 			return;
-		}	
+		}
 		mis = ippp_table[slot];
 	} else
 		mis = is;
 	if (mis != is)
 		printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
-	
-        switch(data[2]) {
+
+	switch (data[2]) {
 	case CCP_CONFREQ:
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Disable decompression here!\n");
-		if(proto == PPP_CCP)
+		if (proto == PPP_CCP)
 			is->compflags &= ~SC_DECOMP_ON;
 		else
 			is->compflags &= ~SC_LINK_DECOMP_ON;
 		break;
 	case CCP_TERMREQ:
 	case CCP_TERMACK:
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Disable (de)compression here!\n");
-		if(proto == PPP_CCP)
-			is->compflags &= ~(SC_DECOMP_ON|SC_COMP_ON);
+		if (proto == PPP_CCP)
+			is->compflags &= ~(SC_DECOMP_ON | SC_COMP_ON);
 		else
-			is->compflags &= ~(SC_LINK_DECOMP_ON|SC_LINK_COMP_ON);
+			is->compflags &= ~(SC_LINK_DECOMP_ON | SC_LINK_COMP_ON);
 		break;
 	case CCP_CONFACK:
 		/* if we SEND an ackowledge we can/must enable the compressor */
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Enable compression here!\n");
-		if(proto == PPP_CCP) {
+		if (proto == PPP_CCP) {
 			if (!is->compressor)
 				break;
 			is->compflags |= SC_COMP_ON;
@@ -2891,21 +2891,21 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct
 		break;
 	case CCP_RESETACK:
 		/* If we send a ACK we should reset our compressor */
-		if(is->debug & 0x10)
+		if (is->debug & 0x10)
 			printk(KERN_DEBUG "Reset decompression state here!\n");
 		printk(KERN_DEBUG "ResetAck from daemon passed by\n");
-		if(proto == PPP_CCP) {
+		if (proto == PPP_CCP) {
 			/* link to master? */
-			if(is->compressor && is->comp_stat)
+			if (is->compressor && is->comp_stat)
 				is->compressor->reset(is->comp_stat, 0, 0,
 						      NULL, 0, NULL);
-			is->compflags &= ~SC_COMP_DISCARD;	
+			is->compflags &= ~SC_COMP_DISCARD;
 		}
 		else {
-			if(is->link_compressor && is->link_comp_stat)
+			if (is->link_compressor && is->link_comp_stat)
 				is->link_compressor->reset(is->link_comp_stat,
 							   0, 0, NULL, 0, NULL);
-			is->compflags &= ~SC_LINK_COMP_DISCARD;	
+			is->compflags &= ~SC_LINK_COMP_DISCARD;
 		}
 		break;
 	case CCP_RESETREQ:
@@ -2919,7 +2919,7 @@ int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
 {
 	ipc->next = ipc_head;
 	ipc->prev = NULL;
-	if(ipc_head) {
+	if (ipc_head) {
 		ipc_head->prev = ipc;
 	}
 	ipc_head = ipc;
@@ -2928,11 +2928,11 @@ int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
 
 int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
 {
-	if(ipc->prev)
+	if (ipc->prev)
 		ipc->prev->next = ipc->next;
 	else
 		ipc_head = ipc->next;
-	if(ipc->next)
+	if (ipc->next)
 		ipc->next->prev = ipc->prev;
 	ipc->prev = ipc->next = NULL;
 	return 0;
@@ -2945,26 +2945,26 @@ static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_
 	void *stat;
 	int num = data->num;
 
-	if(is->debug & 0x10)
-		printk(KERN_DEBUG "[%d] Set %s type %d\n",is->unit,
-			(data->flags&IPPP_COMP_FLAG_XMIT)?"compressor":"decompressor",num);
+	if (is->debug & 0x10)
+		printk(KERN_DEBUG "[%d] Set %s type %d\n", is->unit,
+		       (data->flags & IPPP_COMP_FLAG_XMIT) ? "compressor" : "decompressor", num);
 
 	/* If is has no valid reset state vector, we cannot allocate a
 	   decompressor. The decompressor would cause reset transactions
 	   sooner or later, and they need that vector. */
 
-	if(!(data->flags & IPPP_COMP_FLAG_XMIT) && !is->reset) {
+	if (!(data->flags & IPPP_COMP_FLAG_XMIT) && !is->reset) {
 		printk(KERN_ERR "ippp_ccp: no reset data structure - can't"
 		       " allow decompression.\n");
 		return -ENOMEM;
 	}
 
-	while(ipc) {
-		if(ipc->num == num) {
+	while (ipc) {
+		if (ipc->num == num) {
 			stat = ipc->alloc(data);
-			if(stat) {
-				ret = ipc->init(stat,data,is->unit,0);
-				if(!ret) {
+			if (stat) {
+				ret = ipc->init(stat, data, is->unit, 0);
+				if (!ret) {
 					printk(KERN_ERR "Can't init (de)compression!\n");
 					ipc->free(stat);
 					stat = NULL;
@@ -2976,32 +2976,32 @@ static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_
 				break;
 			}
 
-                        if(data->flags & IPPP_COMP_FLAG_XMIT) {
-				if(data->flags & IPPP_COMP_FLAG_LINK) {
-					if(is->link_comp_stat)
+			if (data->flags & IPPP_COMP_FLAG_XMIT) {
+				if (data->flags & IPPP_COMP_FLAG_LINK) {
+					if (is->link_comp_stat)
 						is->link_compressor->free(is->link_comp_stat);
 					is->link_comp_stat = stat;
-                                	is->link_compressor = ipc;
+					is->link_compressor = ipc;
 				}
 				else {
-					if(is->comp_stat)
+					if (is->comp_stat)
 						is->compressor->free(is->comp_stat);
 					is->comp_stat = stat;
-                                	is->compressor = ipc;
+					is->compressor = ipc;
 				}
 			}
-                        else {
-				if(data->flags & IPPP_COMP_FLAG_LINK) {
-					if(is->link_decomp_stat)
+			else {
+				if (data->flags & IPPP_COMP_FLAG_LINK) {
+					if (is->link_decomp_stat)
 						is->link_decompressor->free(is->link_decomp_stat);
 					is->link_decomp_stat = stat;
-        	                        is->link_decompressor = ipc;
+					is->link_decompressor = ipc;
 				}
 				else {
-					if(is->decomp_stat)
+					if (is->decomp_stat)
 						is->decompressor->free(is->decomp_stat);
 					is->decomp_stat = stat;
-        	                        is->decompressor = ipc;
+					is->decompressor = ipc;
 				}
 			}
 			return 0;
diff --git a/drivers/isdn/i4l/isdn_ppp.h b/drivers/isdn/i4l/isdn_ppp.h
index 8cc05c7..4e9b893 100644
--- a/drivers/isdn/i4l/isdn_ppp.h
+++ b/drivers/isdn/i4l/isdn_ppp.h
@@ -39,5 +39,3 @@ extern int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc);
 #define IPPP_ASSIGNED	0x10
 
 #define IPPP_MAX_HEADER 10
-
-
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 2c26b64..89a2887 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -61,7 +61,7 @@ char *isdn_tty_revision = "$Revision: 1.1.2.3 $";
  *      isdn_tty_readmodem().
  */
 static int
-isdn_tty_try_read(modem_info * info, struct sk_buff *skb)
+isdn_tty_try_read(modem_info *info, struct sk_buff *skb)
 {
 	int c;
 	int len;
@@ -93,7 +93,7 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb)
 						last = *dp;
 					} else {
 #endif
-						if(len > 1)
+						if (len > 1)
 							tty_insert_flip_string(tty, skb->data, len - 1);
 						last = skb->data[len - 1];
 #ifdef CONFIG_ISDN_AUDIO
@@ -179,7 +179,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
 	info = &dev->mdm.info[midx];
 #ifdef CONFIG_ISDN_AUDIO
 	ifmt = 1;
-	
+
 	if ((info->vonline) && (!info->emu.vpar[4]))
 		isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt);
 	if ((info->vonline & 1) && (info->emu.vpar[1]))
@@ -213,29 +213,29 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
 	if (info->vonline & 1) {
 		/* voice conversion/compression */
 		switch (info->emu.vpar[3]) {
-			case 2:
-			case 3:
-			case 4:
-				/* adpcm
-				 * Since compressed data takes less
-				 * space, we can overwrite the buffer.
-				 */
-				skb_trim(skb, isdn_audio_xlaw2adpcm(info->adpcmr,
-								    ifmt,
-								    skb->data,
-								    skb->data,
-								    skb->len));
-				break;
-			case 5:
-				/* a-law */
-				if (!ifmt)
-					isdn_audio_ulaw2alaw(skb->data, skb->len);
-				break;
-			case 6:
-				/* u-law */
-				if (ifmt)
-					isdn_audio_alaw2ulaw(skb->data, skb->len);
-				break;
+		case 2:
+		case 3:
+		case 4:
+			/* adpcm
+			 * Since compressed data takes less
+			 * space, we can overwrite the buffer.
+			 */
+			skb_trim(skb, isdn_audio_xlaw2adpcm(info->adpcmr,
+							    ifmt,
+							    skb->data,
+							    skb->data,
+							    skb->len));
+			break;
+		case 5:
+			/* a-law */
+			if (!ifmt)
+				isdn_audio_ulaw2alaw(skb->data, skb->len);
+			break;
+		case 6:
+			/* u-law */
+			if (ifmt)
+				isdn_audio_alaw2ulaw(skb->data, skb->len);
+			break;
 		}
 		ISDN_AUDIO_SKB_DLECOUNT(skb) =
 			isdn_tty_countDLE(skb->data, skb->len);
@@ -275,7 +275,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
 }
 
 static void
-isdn_tty_cleanup_xmit(modem_info * info)
+isdn_tty_cleanup_xmit(modem_info *info)
 {
 	skb_queue_purge(&info->xmit_queue);
 #ifdef CONFIG_ISDN_AUDIO
@@ -284,7 +284,7 @@ isdn_tty_cleanup_xmit(modem_info * info)
 }
 
 static void
-isdn_tty_tint(modem_info * info)
+isdn_tty_tint(modem_info *info)
 {
 	struct sk_buff *skb = skb_dequeue(&info->xmit_queue);
 	int len, slen;
@@ -325,7 +325,7 @@ isdn_tty_countDLE(unsigned char *buf, int len)
  * DLE-decoding when sending audio-data.
  */
 static int
-isdn_tty_handleDLEdown(modem_info * info, atemu * m, int len)
+isdn_tty_handleDLEdown(modem_info *info, atemu *m, int len)
 {
 	unsigned char *p = &info->xmit_buf[info->xmit_count];
 	int count = 0;
@@ -334,42 +334,42 @@ isdn_tty_handleDLEdown(modem_info * info, atemu * m, int len)
 		if (m->lastDLE) {
 			m->lastDLE = 0;
 			switch (*p) {
-				case DLE:
-					/* Escape code */
-					if (len > 1)
-						memmove(p, p + 1, len - 1);
-					p--;
-					count++;
-					break;
-				case ETX:
-					/* End of data */
-					info->vonline |= 4;
-					return count;
-				case DC4:
-					/* Abort RX */
-					info->vonline &= ~1;
+			case DLE:
+				/* Escape code */
+				if (len > 1)
+					memmove(p, p + 1, len - 1);
+				p--;
+				count++;
+				break;
+			case ETX:
+				/* End of data */
+				info->vonline |= 4;
+				return count;
+			case DC4:
+				/* Abort RX */
+				info->vonline &= ~1;
 #ifdef ISDN_DEBUG_MODEM_VOICE
-					printk(KERN_DEBUG
-					       "DLEdown: got DLE-DC4, send DLE-ETX on ttyI%d\n",
-					       info->line);
+				printk(KERN_DEBUG
+				       "DLEdown: got DLE-DC4, send DLE-ETX on ttyI%d\n",
+				       info->line);
 #endif
-					isdn_tty_at_cout("\020\003", info);
-					if (!info->vonline) {
+				isdn_tty_at_cout("\020\003", info);
+				if (!info->vonline) {
 #ifdef ISDN_DEBUG_MODEM_VOICE
-						printk(KERN_DEBUG
-						       "DLEdown: send VCON on ttyI%d\n",
-						       info->line);
+					printk(KERN_DEBUG
+					       "DLEdown: send VCON on ttyI%d\n",
+					       info->line);
 #endif
-						isdn_tty_at_cout("\r\nVCON\r\n", info);
-					}
-					/* Fall through */
-				case 'q':
-				case 's':
-					/* Silence */
-					if (len > 1)
-						memmove(p, p + 1, len - 1);
-					p--;
-					break;
+					isdn_tty_at_cout("\r\nVCON\r\n", info);
+				}
+				/* Fall through */
+			case 'q':
+			case 's':
+				/* Silence */
+				if (len > 1)
+					memmove(p, p + 1, len - 1);
+				p--;
+				break;
 			}
 		} else {
 			if (*p == DLE)
@@ -416,7 +416,7 @@ static int voice_cf[7] =
  * T.70 if necessary, and finally queues it up for sending via isdn_tty_tint.
  */
 static void
-isdn_tty_senddown(modem_info * info)
+isdn_tty_senddown(modem_info *info)
 {
 	int buflen;
 	int skb_res;
@@ -440,9 +440,9 @@ isdn_tty_senddown(modem_info * info)
 #endif
 	if (!(buflen = info->xmit_count))
 		return;
- 	if ((info->emu.mdmreg[REG_CTS] & BIT_CTS) != 0)
+	if ((info->emu.mdmreg[REG_CTS] & BIT_CTS) != 0)
 		info->msr &= ~UART_MSR_CTS;
-	info->lsr &= ~UART_LSR_TEMT;	
+	info->lsr &= ~UART_LSR_TEMT;
 	/* info->xmit_count is modified here and in isdn_tty_write().
 	 * So we return here if isdn_tty_write() is in the
 	 * critical section.
@@ -485,32 +485,32 @@ isdn_tty_senddown(modem_info * info)
 
 		/* voice conversion/decompression */
 		switch (info->emu.vpar[3]) {
-			case 2:
-			case 3:
-			case 4:
-				/* adpcm, compatible to ZyXel 1496 modem
-				 * with ROM revision 6.01
-				 */
-				audio_len = isdn_audio_adpcm2xlaw(info->adpcms,
-								  ifmt,
-								  skb->data,
-						    skb_put(skb, audio_len),
-								  buflen);
-				skb_pull(skb, buflen);
-				skb_trim(skb, audio_len);
-				break;
-			case 5:
-				/* a-law */
-				if (!ifmt)
-					isdn_audio_alaw2ulaw(skb->data,
-							     buflen);
-				break;
-			case 6:
-				/* u-law */
-				if (ifmt)
-					isdn_audio_ulaw2alaw(skb->data,
-							     buflen);
-				break;
+		case 2:
+		case 3:
+		case 4:
+			/* adpcm, compatible to ZyXel 1496 modem
+			 * with ROM revision 6.01
+			 */
+			audio_len = isdn_audio_adpcm2xlaw(info->adpcms,
+							  ifmt,
+							  skb->data,
+							  skb_put(skb, audio_len),
+							  buflen);
+			skb_pull(skb, buflen);
+			skb_trim(skb, audio_len);
+			break;
+		case 5:
+			/* a-law */
+			if (!ifmt)
+				isdn_audio_alaw2ulaw(skb->data,
+						     buflen);
+			break;
+		case 6:
+			/* u-law */
+			if (ifmt)
+				isdn_audio_ulaw2alaw(skb->data,
+						     buflen);
+			break;
 		}
 	}
 #endif                          /* CONFIG_ISDN_AUDIO */
@@ -550,7 +550,7 @@ isdn_tty_modem_do_ncarrier(unsigned long data)
  * low.
  */
 static void
-isdn_tty_modem_ncarrier(modem_info * info)
+isdn_tty_modem_ncarrier(modem_info *info)
 {
 	if (info->ncarrier) {
 		info->nc_timer.expires = jiffies + HZ;
@@ -568,30 +568,30 @@ isdn_calc_usage(int si, int l2)
 
 #ifdef CONFIG_ISDN_AUDIO
 	if (si == 1) {
-		switch(l2) {
-			case ISDN_PROTO_L2_MODEM: 
-				usg = ISDN_USAGE_MODEM;
-				break;
+		switch (l2) {
+		case ISDN_PROTO_L2_MODEM:
+			usg = ISDN_USAGE_MODEM;
+			break;
 #ifdef CONFIG_ISDN_TTY_FAX
-			case ISDN_PROTO_L2_FAX: 
-				usg = ISDN_USAGE_FAX;
-				break;
+		case ISDN_PROTO_L2_FAX:
+			usg = ISDN_USAGE_FAX;
+			break;
 #endif
-			case ISDN_PROTO_L2_TRANS: 
-			default:
-				usg = ISDN_USAGE_VOICE;
-				break;
+		case ISDN_PROTO_L2_TRANS:
+		default:
+			usg = ISDN_USAGE_VOICE;
+			break;
 		}
 	}
 #endif
-	return(usg);
+	return (usg);
 }
 
 /* isdn_tty_dial() performs dialing of a tty an the necessary
  * setup of the lower levels before that.
  */
 static void
-isdn_tty_dial(char *n, modem_info * info, atemu * m)
+isdn_tty_dial(char *n, modem_info *info, atemu *m)
 {
 	int usg = ISDN_USAGE_MODEM;
 	int si = 7;
@@ -608,10 +608,10 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m)
 		}
 	usg = isdn_calc_usage(si, l2);
 #ifdef CONFIG_ISDN_AUDIO
-	if ((si == 1) && 
-		(l2 != ISDN_PROTO_L2_MODEM)
+	if ((si == 1) &&
+	    (l2 != ISDN_PROTO_L2_MODEM)
 #ifdef CONFIG_ISDN_TTY_FAX
-		&& (l2 != ISDN_PROTO_L2_FAX)
+	    && (l2 != ISDN_PROTO_L2_FAX)
 #endif
 		) {
 		l2 = ISDN_PROTO_L2_TRANS;
@@ -679,7 +679,7 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m)
  * and some cleanup is done also.
  */
 void
-isdn_tty_modem_hup(modem_info * info, int local)
+isdn_tty_modem_hup(modem_info *info, int local)
 {
 	isdn_ctrl cmd;
 	int di, ch;
@@ -723,7 +723,7 @@ isdn_tty_modem_hup(modem_info * info, int local)
 	info->adpcmr = NULL;
 #endif
 	if ((info->msr & UART_MSR_RI) &&
-		(info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
+	    (info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
 		isdn_tty_modem_result(RESULT_RUNG, info);
 	info->msr &= ~(UART_MSR_DCD | UART_MSR_RI);
 	info->lsr |= UART_LSR_TEMT;
@@ -746,7 +746,7 @@ isdn_tty_modem_hup(modem_info * info, int local)
 }
 
 /*
- * Begin of a CAPI like interface, currently used only for 
+ * Begin of a CAPI like interface, currently used only for
  * supplementary service (CAPI 2.0 part III)
  */
 #include <linux/isdn/capicmd.h>
@@ -754,16 +754,16 @@ isdn_tty_modem_hup(modem_info * info, int local)
 
 int
 isdn_tty_capi_facility(capi_msg *cm) {
-	return(-1); /* dummy */
+	return (-1); /* dummy */
 }
 
 /* isdn_tty_suspend() tries to suspend the current tty connection
  */
 static void
-isdn_tty_suspend(char *id, modem_info * info, atemu * m)
+isdn_tty_suspend(char *id, modem_info *info, atemu *m)
 {
 	isdn_ctrl cmd;
-	
+
 	int l;
 
 	if (!info)
@@ -774,7 +774,7 @@ isdn_tty_suspend(char *id, modem_info * info, atemu * m)
 #endif
 	l = strlen(id);
 	if ((info->isdn_driver >= 0)) {
-		cmd.parm.cmsg.Length = l+18;
+		cmd.parm.cmsg.Length = l + 18;
 		cmd.parm.cmsg.Command = CAPI_FACILITY;
 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
 		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
@@ -800,7 +800,7 @@ isdn_tty_suspend(char *id, modem_info * info, atemu * m)
  */
 
 static void
-isdn_tty_resume(char *id, modem_info * info, atemu * m)
+isdn_tty_resume(char *id, modem_info *info, atemu *m)
 {
 	int usg = ISDN_USAGE_MODEM;
 	int si = 7;
@@ -819,10 +819,10 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m)
 		}
 	usg = isdn_calc_usage(si, l2);
 #ifdef CONFIG_ISDN_AUDIO
-	if ((si == 1) && 
-		(l2 != ISDN_PROTO_L2_MODEM)
+	if ((si == 1) &&
+	    (l2 != ISDN_PROTO_L2_MODEM)
 #ifdef CONFIG_ISDN_TTY_FAX
-		&& (l2 != ISDN_PROTO_L2_FAX)
+	    && (l2 != ISDN_PROTO_L2_FAX)
 #endif
 		) {
 		l2 = ISDN_PROTO_L2_TRANS;
@@ -864,18 +864,18 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m)
 		isdn_command(&cmd);
 		cmd.driver = info->isdn_driver;
 		cmd.arg = info->isdn_channel;
-		cmd.parm.cmsg.Length = l+18;
+		cmd.parm.cmsg.Length = l + 18;
 		cmd.parm.cmsg.Command = CAPI_FACILITY;
 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
 		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
 		cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */
 		cmd.parm.cmsg.para[1] = 0;
-		cmd.parm.cmsg.para[2] = l+3;
+		cmd.parm.cmsg.para[2] = l + 3;
 		cmd.parm.cmsg.para[3] = 5; /* 16 bit 0x0005 Resume */
 		cmd.parm.cmsg.para[4] = 0;
 		cmd.parm.cmsg.para[5] = l;
 		strncpy(&cmd.parm.cmsg.para[6], id, l);
-		cmd.command =CAPI_PUT_MESSAGE;
+		cmd.command = CAPI_PUT_MESSAGE;
 		info->dialing = 1;
 //		strcpy(dev->num[i], n);
 		isdn_info_update();
@@ -889,7 +889,7 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m)
  */
 
 static void
-isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
+isdn_tty_send_msg(modem_info *info, atemu *m, char *msg)
 {
 	int usg = ISDN_USAGE_MODEM;
 	int si = 7;
@@ -912,10 +912,10 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
 		}
 	usg = isdn_calc_usage(si, l2);
 #ifdef CONFIG_ISDN_AUDIO
-	if ((si == 1) && 
-		(l2 != ISDN_PROTO_L2_MODEM)
+	if ((si == 1) &&
+	    (l2 != ISDN_PROTO_L2_MODEM)
 #ifdef CONFIG_ISDN_TTY_FAX
-		&& (l2 != ISDN_PROTO_L2_FAX)
+	    && (l2 != ISDN_PROTO_L2_FAX)
 #endif
 		) {
 		l2 = ISDN_PROTO_L2_TRANS;
@@ -956,14 +956,14 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
 		isdn_command(&cmd);
 		cmd.driver = info->isdn_driver;
 		cmd.arg = info->isdn_channel;
-		cmd.parm.cmsg.Length = l+14;
+		cmd.parm.cmsg.Length = l + 14;
 		cmd.parm.cmsg.Command = CAPI_MANUFACTURER;
 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
 		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
-		cmd.parm.cmsg.para[0] = l+1;
+		cmd.parm.cmsg.para[0] = l + 1;
 		strncpy(&cmd.parm.cmsg.para[1], msg, l);
-		cmd.parm.cmsg.para[l+1] = 0xd;
-		cmd.command =CAPI_PUT_MESSAGE;
+		cmd.parm.cmsg.para[l + 1] = 0xd;
+		cmd.command = CAPI_PUT_MESSAGE;
 /*		info->dialing = 1;
 		strcpy(dev->num[i], n);
 		isdn_info_update();
@@ -978,7 +978,7 @@ isdn_tty_paranoia_check(modem_info *info, char *name, const char *routine)
 #ifdef MODEM_PARANOIA_CHECK
 	if (!info) {
 		printk(KERN_WARNING "isdn_tty: null info_struct for %s in %s\n",
-			name, routine);
+		       name, routine);
 		return 1;
 	}
 	if (info->magic != ISDN_ASYNC_MAGIC) {
@@ -995,11 +995,11 @@ isdn_tty_paranoia_check(modem_info *info, char *name, const char *routine)
  * the specified baud rate for a serial port.
  */
 static void
-isdn_tty_change_speed(modem_info * info)
+isdn_tty_change_speed(modem_info *info)
 {
 	uint cflag,
-	 cval,
-	 quot;
+		cval,
+		quot;
 	int i;
 
 	if (!info->tty || !info->tty->termios)
@@ -1051,7 +1051,7 @@ isdn_tty_change_speed(modem_info * info)
 }
 
 static int
-isdn_tty_startup(modem_info * info)
+isdn_tty_startup(modem_info *info)
 {
 	if (info->flags & ISDN_ASYNC_INITIALIZED)
 		return 0;
@@ -1081,7 +1081,7 @@ isdn_tty_startup(modem_info * info)
  * DTR is dropped if the hangup on close termio flag is on.
  */
 static void
-isdn_tty_shutdown(modem_info * info)
+isdn_tty_shutdown(modem_info *info)
 {
 	if (!(info->flags & ISDN_ASYNC_INITIALIZED))
 		return;
@@ -1116,7 +1116,7 @@ isdn_tty_shutdown(modem_info * info)
  *  - If dialing, abort dial.
  */
 static int
-isdn_tty_write(struct tty_struct *tty, const u_char * buf, int count)
+isdn_tty_write(struct tty_struct *tty, const u_char *buf, int count)
 {
 	int c;
 	int total = 0;
@@ -1176,27 +1176,27 @@ isdn_tty_write(struct tty_struct *tty, const u_char * buf, int count)
 					}
 				}
 			} else
-			if (TTY_IS_FCLASS1(info)) {
-				int cc = isdn_tty_handleDLEdown(info, m, c);
-				
-				if (info->vonline & 4) { /* ETX seen */
-					isdn_ctrl c;
-
-					c.command = ISDN_CMD_FAXCMD;
-					c.driver = info->isdn_driver;
-					c.arg = info->isdn_channel;
-					c.parm.aux.cmd = ISDN_FAX_CLASS1_CTRL;
-					c.parm.aux.subcmd = ETX;
-					isdn_command(&c);
-				}
-				info->vonline = 0;
+				if (TTY_IS_FCLASS1(info)) {
+					int cc = isdn_tty_handleDLEdown(info, m, c);
+
+					if (info->vonline & 4) { /* ETX seen */
+						isdn_ctrl c;
+
+						c.command = ISDN_CMD_FAXCMD;
+						c.driver = info->isdn_driver;
+						c.arg = info->isdn_channel;
+						c.parm.aux.cmd = ISDN_FAX_CLASS1_CTRL;
+						c.parm.aux.subcmd = ETX;
+						isdn_command(&c);
+					}
+					info->vonline = 0;
 #ifdef ISDN_DEBUG_MODEM_VOICE
-				printk(KERN_DEBUG "fax dle cc/c %d/%d\n", cc, c);
+					printk(KERN_DEBUG "fax dle cc/c %d/%d\n", cc, c);
 #endif
-				info->xmit_count += cc;
-			} else
+					info->xmit_count += cc;
+				} else
 #endif
-				info->xmit_count += c;
+					info->xmit_count += c;
 		} else {
 			info->msr |= UART_MSR_CTS;
 			info->lsr |= UART_LSR_TEMT;
@@ -1332,7 +1332,7 @@ isdn_tty_unthrottle(struct tty_struct *tty)
  *          allows RS485 driver to be written in user space.
  */
 static int
-isdn_tty_get_lsr_info(modem_info * info, uint __user * value)
+isdn_tty_get_lsr_info(modem_info *info, uint __user *value)
 {
 	u_char status;
 	uint result;
@@ -1363,16 +1363,16 @@ isdn_tty_tiocmget(struct tty_struct *tty)
 	status = info->msr;
 	mutex_unlock(&modem_info_mutex);
 	return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
-	    | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
-	    | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
-	    | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
-	    | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
-	    | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
+		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
+		| ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
+		| ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
+		| ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
+		| ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
 }
 
 static int
 isdn_tty_tiocmset(struct tty_struct *tty,
-		unsigned int set, unsigned int clear)
+		  unsigned int set, unsigned int clear)
 {
 	modem_info *info = (modem_info *) tty->driver_data;
 
@@ -1422,34 +1422,34 @@ isdn_tty_ioctl(struct tty_struct *tty, uint cmd, ulong arg)
 	if (tty->flags & (1 << TTY_IO_ERROR))
 		return -EIO;
 	switch (cmd) {
-		case TCSBRK:   /* SVID version: non-zero arg --> no break */
+	case TCSBRK:   /* SVID version: non-zero arg --> no break */
 #ifdef ISDN_DEBUG_MODEM_IOCTL
-			printk(KERN_DEBUG "ttyI%d ioctl TCSBRK\n", info->line);
-#endif
-			retval = tty_check_change(tty);
-			if (retval)
-				return retval;
-			tty_wait_until_sent(tty, 0);
-			return 0;
-		case TCSBRKP:  /* support for POSIX tcsendbreak() */
+		printk(KERN_DEBUG "ttyI%d ioctl TCSBRK\n", info->line);
+#endif
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		return 0;
+	case TCSBRKP:  /* support for POSIX tcsendbreak() */
 #ifdef ISDN_DEBUG_MODEM_IOCTL
-			printk(KERN_DEBUG "ttyI%d ioctl TCSBRKP\n", info->line);
-#endif
-			retval = tty_check_change(tty);
-			if (retval)
-				return retval;
-			tty_wait_until_sent(tty, 0);
-			return 0;
-		case TIOCSERGETLSR:	/* Get line status register */
+		printk(KERN_DEBUG "ttyI%d ioctl TCSBRKP\n", info->line);
+#endif
+		retval = tty_check_change(tty);
+		if (retval)
+			return retval;
+		tty_wait_until_sent(tty, 0);
+		return 0;
+	case TIOCSERGETLSR:	/* Get line status register */
 #ifdef ISDN_DEBUG_MODEM_IOCTL
-			printk(KERN_DEBUG "ttyI%d ioctl TIOCSERGETLSR\n", info->line);
+		printk(KERN_DEBUG "ttyI%d ioctl TIOCSERGETLSR\n", info->line);
 #endif
-			return isdn_tty_get_lsr_info(info, (uint __user *) arg);
-		default:
+		return isdn_tty_get_lsr_info(info, (uint __user *) arg);
+	default:
 #ifdef ISDN_DEBUG_MODEM_IOCTL
-			printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on ttyi%d\n", cmd, info->line);
+		printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on ttyi%d\n", cmd, info->line);
 #endif
-			return -ENOIOCTLCMD;
+		return -ENOIOCTLCMD;
 	}
 	return 0;
 }
@@ -1479,7 +1479,7 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
  * ------------------------------------------------------------
  */
 static int
-isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * info)
+isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *info)
 {
 	DECLARE_WAITQUEUE(wait, NULL);
 	int do_clocal = 0;
@@ -1603,7 +1603,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
 		return -ENODEV;
 	}
 #ifdef ISDN_DEBUG_MODEM_OPEN
-	printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, 
+	printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
 	       info->count);
 #endif
 	info->count++;
@@ -1703,7 +1703,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
 		timeout = jiffies + HZ;
 		while (!(info->lsr & UART_LSR_TEMT)) {
 			schedule_timeout_interruptible(20);
-			if (time_after(jiffies,timeout))
+			if (time_after(jiffies, timeout))
 				break;
 		}
 	}
@@ -1746,7 +1746,7 @@ isdn_tty_hangup(struct tty_struct *tty)
 /* This routine initializes all emulator-data.
  */
 static void
-isdn_tty_reset_profile(atemu * m)
+isdn_tty_reset_profile(atemu *m)
 {
 	m->profile[0] = 0;
 	m->profile[1] = 0;
@@ -1776,7 +1776,7 @@ isdn_tty_reset_profile(atemu * m)
 
 #ifdef CONFIG_ISDN_AUDIO
 static void
-isdn_tty_modem_reset_vpar(atemu * m)
+isdn_tty_modem_reset_vpar(atemu *m)
 {
 	m->vpar[0] = 2;         /* Voice-device            (2 = phone line) */
 	m->vpar[1] = 0;         /* Silence detection level (0 = none      ) */
@@ -1789,7 +1789,7 @@ isdn_tty_modem_reset_vpar(atemu * m)
 
 #ifdef CONFIG_ISDN_TTY_FAX
 static void
-isdn_tty_modem_reset_faxpar(modem_info * info)
+isdn_tty_modem_reset_faxpar(modem_info *info)
 {
 	T30_s *f = info->fax;
 
@@ -1822,7 +1822,7 @@ isdn_tty_modem_reset_faxpar(modem_info * info)
 #endif
 
 static void
-isdn_tty_modem_reset_regs(modem_info * info, int force)
+isdn_tty_modem_reset_regs(modem_info *info, int force)
 {
 	atemu *m = &info->emu;
 	if ((m->mdmreg[REG_DTRR] & BIT_DTRR) || force) {
@@ -1841,7 +1841,7 @@ isdn_tty_modem_reset_regs(modem_info * info, int force)
 }
 
 static void
-modem_write_profile(atemu * m)
+modem_write_profile(atemu *m)
 {
 	memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG);
 	memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
@@ -1851,7 +1851,7 @@ modem_write_profile(atemu * m)
 }
 
 static const struct tty_operations modem_ops = {
-        .open = isdn_tty_open,
+	.open = isdn_tty_open,
 	.close = isdn_tty_close,
 	.write = isdn_tty_write,
 	.flush_chars = isdn_tty_flush_chars,
@@ -1951,7 +1951,7 @@ err_unregister:
 		kfree(info->xmit_buf - 4);
 	}
 	tty_unregister_driver(m->tty_modem);
- err:
+err:
 	put_tty_driver(m->tty_modem);
 	m->tty_modem = NULL;
 	return retval;
@@ -2021,8 +2021,8 @@ isdn_tty_match_icall(char *cid, atemu *emu, int di)
 		int tmp;
 		tmp = isdn_msncmp(cid, isdn_map_eaz2msn(emu->msn, di));
 #ifdef ISDN_DEBUG_MODEM_ICALL
-			printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n",
-			       isdn_map_eaz2msn(emu->msn, di), tmp);
+		printk(KERN_DEBUG "m_fi: mmsn=%s -> tmp=%d\n",
+		       isdn_map_eaz2msn(emu->msn, di), tmp);
 #endif
 		return tmp;
 	}
@@ -2071,8 +2071,8 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		modem_info *info = &dev->mdm.info[i];
 
-                if (info->count == 0)
-                    continue;
+		if (info->count == 0)
+			continue;
 		if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) &&  /* SI1 is matching */
 		    (info->emu.mdmreg[REG_SI2] == si2))	{         /* SI2 is matching */
 			idx = isdn_dc2minor(di, ch);
@@ -2099,7 +2099,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 					info->drv_index = idx;
 					dev->m_idx[idx] = info->line;
 					dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
-					dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]); 
+					dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]);
 					strcpy(dev->num[idx], nr);
 					strcpy(info->emu.cpn, eaz);
 					info->emu.mdmreg[REG_SI1I] = si2bit[si1];
@@ -2119,11 +2119,11 @@ isdn_tty_find_icall(int di, int ch, setup_parm *setup)
 	}
 	spin_unlock_irqrestore(&dev->lock, flags);
 	printk(KERN_INFO "isdn_tty: call from %s -> %s %s\n", nr, eaz,
-	       ((dev->drv[di]->flags & DRV_FLAG_REJBUS) && (wret != 2))? "rejected" : "ignored");
-	return (wret == 2)?3:0;
+	       ((dev->drv[di]->flags & DRV_FLAG_REJBUS) && (wret != 2)) ? "rejected" : "ignored");
+	return (wret == 2) ? 3 : 0;
 }
 
-#define TTY_IS_ACTIVE(info) \
+#define TTY_IS_ACTIVE(info)						\
 	(info->flags & (ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE))
 
 int
@@ -2138,174 +2138,174 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
 	if ((mi = dev->m_idx[i]) >= 0) {
 		info = &dev->mdm.info[mi];
 		switch (c->command) {
-                        case ISDN_STAT_CINF:
-                                printk(KERN_DEBUG "CHARGEINFO on ttyI%d: %ld %s\n", info->line, c->arg, c->parm.num);
-                                info->emu.charge = (unsigned) simple_strtoul(c->parm.num, &e, 10);
-                                if (e == (char *)c->parm.num)
-					info->emu.charge = 0;
-				
-                                break;			
-			case ISDN_STAT_BSENT:
-#ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line);
-#endif
-				if ((info->isdn_driver == c->driver) &&
-				    (info->isdn_channel == c->arg)) {
-					info->msr |= UART_MSR_CTS;
-					if (info->send_outstanding)
-						if (!(--info->send_outstanding))
-							info->lsr |= UART_LSR_TEMT;
-					isdn_tty_tint(info);
-					return 1;
-				}
-				break;
-			case ISDN_STAT_CAUSE:
+		case ISDN_STAT_CINF:
+			printk(KERN_DEBUG "CHARGEINFO on ttyI%d: %ld %s\n", info->line, c->arg, c->parm.num);
+			info->emu.charge = (unsigned) simple_strtoul(c->parm.num, &e, 10);
+			if (e == (char *)c->parm.num)
+				info->emu.charge = 0;
+
+			break;
+		case ISDN_STAT_BSENT:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_CAUSE ttyI%d\n", info->line);
+			printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line);
 #endif
-				/* Signal cause to tty-device */
-				strncpy(info->last_cause, c->parm.num, 5);
+			if ((info->isdn_driver == c->driver) &&
+			    (info->isdn_channel == c->arg)) {
+				info->msr |= UART_MSR_CTS;
+				if (info->send_outstanding)
+					if (!(--info->send_outstanding))
+						info->lsr |= UART_LSR_TEMT;
+				isdn_tty_tint(info);
 				return 1;
-			case ISDN_STAT_DISPLAY:
+			}
+			break;
+		case ISDN_STAT_CAUSE:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line);
-#endif
-				/* Signal display to tty-device */
-				if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) && 
-					!(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) {
-				  isdn_tty_at_cout("\r\n", info);
-				  isdn_tty_at_cout("DISPLAY: ", info);
-				  isdn_tty_at_cout(c->parm.display, info);
-				  isdn_tty_at_cout("\r\n", info);
-				}
-				return 1;
-			case ISDN_STAT_DCONN:
+			printk(KERN_DEBUG "tty_STAT_CAUSE ttyI%d\n", info->line);
+#endif
+			/* Signal cause to tty-device */
+			strncpy(info->last_cause, c->parm.num, 5);
+			return 1;
+		case ISDN_STAT_DISPLAY:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);
+			printk(KERN_DEBUG "tty_STAT_DISPLAY ttyI%d\n", info->line);
 #endif
-				if (TTY_IS_ACTIVE(info)) {
-					if (info->dialing == 1) {
-						info->dialing = 2;
-						return 1;
-					}
+			/* Signal display to tty-device */
+			if ((info->emu.mdmreg[REG_DISPLAY] & BIT_DISPLAY) &&
+			    !(info->emu.mdmreg[REG_RESPNUM] & BIT_RESPNUM)) {
+				isdn_tty_at_cout("\r\n", info);
+				isdn_tty_at_cout("DISPLAY: ", info);
+				isdn_tty_at_cout(c->parm.display, info);
+				isdn_tty_at_cout("\r\n", info);
+			}
+			return 1;
+		case ISDN_STAT_DCONN:
+#ifdef ISDN_TTY_STAT_DEBUG
+			printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);
+#endif
+			if (TTY_IS_ACTIVE(info)) {
+				if (info->dialing == 1) {
+					info->dialing = 2;
+					return 1;
 				}
-				break;
-			case ISDN_STAT_DHUP:
+			}
+			break;
+		case ISDN_STAT_DHUP:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line);
+			printk(KERN_DEBUG "tty_STAT_DHUP ttyI%d\n", info->line);
 #endif
-				if (TTY_IS_ACTIVE(info)) {
-					if (info->dialing == 1) 
-						isdn_tty_modem_result(RESULT_BUSY, info);
-					if (info->dialing > 1) 
-						isdn_tty_modem_result(RESULT_NO_CARRIER, info);
-					info->dialing = 0;
+			if (TTY_IS_ACTIVE(info)) {
+				if (info->dialing == 1)
+					isdn_tty_modem_result(RESULT_BUSY, info);
+				if (info->dialing > 1)
+					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
+				info->dialing = 0;
 #ifdef ISDN_DEBUG_MODEM_HUP
-					printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");
+				printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");
 #endif
-					isdn_tty_modem_hup(info, 0);
-					return 1;
-				}
-				break;
-			case ISDN_STAT_BCONN:
+				isdn_tty_modem_hup(info, 0);
+				return 1;
+			}
+			break;
+		case ISDN_STAT_BCONN:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_BCONN ttyI%d\n", info->line);
-#endif
-				/* Wake up any processes waiting
-				 * for incoming call of this device when
-				 * DCD follow the state of incoming carrier
-				 */
-				if (info->blocked_open &&
-				   (info->emu.mdmreg[REG_DCD] & BIT_DCD)) {
-					wake_up_interruptible(&info->open_wait);
-				}
+			printk(KERN_DEBUG "tty_STAT_BCONN ttyI%d\n", info->line);
+#endif
+			/* Wake up any processes waiting
+			 * for incoming call of this device when
+			 * DCD follow the state of incoming carrier
+			 */
+			if (info->blocked_open &&
+			    (info->emu.mdmreg[REG_DCD] & BIT_DCD)) {
+				wake_up_interruptible(&info->open_wait);
+			}
 
-				/* Schedule CONNECT-Message to any tty
-				 * waiting for it and
-				 * set DCD-bit of its modem-status.
-				 */
-				if (TTY_IS_ACTIVE(info) ||
-				    (info->blocked_open && (info->emu.mdmreg[REG_DCD] & BIT_DCD))) {
-					info->msr |= UART_MSR_DCD;
-					info->emu.charge = 0;
-					if (info->dialing & 0xf)
-						info->last_dir = 1;
-					else
-						info->last_dir = 0;
-					info->dialing = 0;
-					info->rcvsched = 1;
-					if (USG_MODEM(dev->usage[i])) {
-						if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {
-							strcpy(info->emu.connmsg, c->parm.num);
-							isdn_tty_modem_result(RESULT_CONNECT, info);
-						} else
-							isdn_tty_modem_result(RESULT_CONNECT64000, info);
-					}
-					if (USG_VOICE(dev->usage[i]))
-						isdn_tty_modem_result(RESULT_VCON, info);
-					return 1;
+			/* Schedule CONNECT-Message to any tty
+			 * waiting for it and
+			 * set DCD-bit of its modem-status.
+			 */
+			if (TTY_IS_ACTIVE(info) ||
+			    (info->blocked_open && (info->emu.mdmreg[REG_DCD] & BIT_DCD))) {
+				info->msr |= UART_MSR_DCD;
+				info->emu.charge = 0;
+				if (info->dialing & 0xf)
+					info->last_dir = 1;
+				else
+					info->last_dir = 0;
+				info->dialing = 0;
+				info->rcvsched = 1;
+				if (USG_MODEM(dev->usage[i])) {
+					if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {
+						strcpy(info->emu.connmsg, c->parm.num);
+						isdn_tty_modem_result(RESULT_CONNECT, info);
+					} else
+						isdn_tty_modem_result(RESULT_CONNECT64000, info);
 				}
-				break;
-			case ISDN_STAT_BHUP:
+				if (USG_VOICE(dev->usage[i]))
+					isdn_tty_modem_result(RESULT_VCON, info);
+				return 1;
+			}
+			break;
+		case ISDN_STAT_BHUP:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line);
+			printk(KERN_DEBUG "tty_STAT_BHUP ttyI%d\n", info->line);
 #endif
-				if (TTY_IS_ACTIVE(info)) {
+			if (TTY_IS_ACTIVE(info)) {
 #ifdef ISDN_DEBUG_MODEM_HUP
-					printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n");
+				printk(KERN_DEBUG "Mhup in ISDN_STAT_BHUP\n");
 #endif
-					isdn_tty_modem_hup(info, 0);
-					return 1;
-				}
-				break;
-			case ISDN_STAT_NODCH:
+				isdn_tty_modem_hup(info, 0);
+				return 1;
+			}
+			break;
+		case ISDN_STAT_NODCH:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line);
-#endif
-				if (TTY_IS_ACTIVE(info)) {
-					if (info->dialing) {
-						info->dialing = 0;
-						info->last_l2 = -1;
-						info->last_si = 0;
-						sprintf(info->last_cause, "0000");
-						isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
-					}
-					isdn_tty_modem_hup(info, 0);
-					return 1;
+			printk(KERN_DEBUG "tty_STAT_NODCH ttyI%d\n", info->line);
+#endif
+			if (TTY_IS_ACTIVE(info)) {
+				if (info->dialing) {
+					info->dialing = 0;
+					info->last_l2 = -1;
+					info->last_si = 0;
+					sprintf(info->last_cause, "0000");
+					isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 				}
-				break;
-			case ISDN_STAT_UNLOAD:
+				isdn_tty_modem_hup(info, 0);
+				return 1;
+			}
+			break;
+		case ISDN_STAT_UNLOAD:
 #ifdef ISDN_TTY_STAT_DEBUG
-				printk(KERN_DEBUG "tty_STAT_UNLOAD ttyI%d\n", info->line);
+			printk(KERN_DEBUG "tty_STAT_UNLOAD ttyI%d\n", info->line);
 #endif
-				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-					info = &dev->mdm.info[i];
-					if (info->isdn_driver == c->driver) {
-						if (info->online)
-							isdn_tty_modem_hup(info, 1);
-					}
+			for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+				info = &dev->mdm.info[i];
+				if (info->isdn_driver == c->driver) {
+					if (info->online)
+						isdn_tty_modem_hup(info, 1);
 				}
-				return 1;
+			}
+			return 1;
 #ifdef CONFIG_ISDN_TTY_FAX
-			case ISDN_STAT_FAXIND:
-				if (TTY_IS_ACTIVE(info)) {
-					isdn_tty_fax_command(info, c); 
-				}
-				break;
+		case ISDN_STAT_FAXIND:
+			if (TTY_IS_ACTIVE(info)) {
+				isdn_tty_fax_command(info, c);
+			}
+			break;
 #endif
 #ifdef CONFIG_ISDN_AUDIO
-			case ISDN_STAT_AUDIO:
-				if (TTY_IS_ACTIVE(info)) {
-					switch(c->parm.num[0]) {
-						case ISDN_AUDIO_DTMF:
-							if (info->vonline) {
-								isdn_audio_put_dle_code(info,
+		case ISDN_STAT_AUDIO:
+			if (TTY_IS_ACTIVE(info)) {
+				switch (c->parm.num[0]) {
+				case ISDN_AUDIO_DTMF:
+					if (info->vonline) {
+						isdn_audio_put_dle_code(info,
 									c->parm.num[1]);
-							}
-							break;
 					}
+					break;
 				}
-				break;
+			}
+			break;
 #endif
 		}
 	}
@@ -2314,16 +2314,16 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
 
 /*********************************************************************
  Modem-Emulator-Routines
- *********************************************************************/
+*********************************************************************/
 
-#define cmdchar(c) ((c>=' ')&&(c<=0x7f))
+#define cmdchar(c) ((c >= ' ') && (c <= 0x7f))
 
 /*
  * Put a message from the AT-emulator into receive-buffer of tty,
  * convert CR, LF, and BS to values in modem-registers 3, 4 and 5.
  */
 void
-isdn_tty_at_cout(char *msg, modem_info * info)
+isdn_tty_at_cout(char *msg, modem_info *info)
 {
 	struct tty_struct *tty;
 	atemu *m = &info->emu;
@@ -2351,7 +2351,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
 	/* use queue instead of direct, if online and */
 	/* data is in queue or buffer is full */
 	if (info->online && ((tty_buffer_request_room(tty, l) < l) ||
-	    !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) {
+			     !skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel]))) {
 		skb = alloc_skb(l, GFP_ATOMIC);
 		if (!skb) {
 			spin_unlock_irqrestore(&info->readlock, flags);
@@ -2366,22 +2366,22 @@ isdn_tty_at_cout(char *msg, modem_info * info)
 
 	for (p = msg; *p; p++) {
 		switch (*p) {
-			case '\r':
-				c = m->mdmreg[REG_CR];
-				break;
-			case '\n':
-				c = m->mdmreg[REG_LF];
-				break;
-			case '\b':
-				c = m->mdmreg[REG_BS];
-				break;
-			default:
-				c = *p;
+		case '\r':
+			c = m->mdmreg[REG_CR];
+			break;
+		case '\n':
+			c = m->mdmreg[REG_LF];
+			break;
+		case '\b':
+			c = m->mdmreg[REG_BS];
+			break;
+		default:
+			c = *p;
 		}
 		if (skb) {
 			*sp++ = c;
 		} else {
-			if(tty_insert_flip_char(tty, c, TTY_NORMAL) == 0)
+			if (tty_insert_flip_char(tty, c, TTY_NORMAL) == 0)
 				break;
 		}
 	}
@@ -2403,7 +2403,7 @@ isdn_tty_at_cout(char *msg, modem_info * info)
  * Perform ATH Hangup
  */
 static void
-isdn_tty_on_hook(modem_info * info)
+isdn_tty_on_hook(modem_info *info)
 {
 	if (info->isdn_channel >= 0) {
 #ifdef ISDN_DEBUG_MODEM_HUP
@@ -2419,8 +2419,8 @@ isdn_tty_off_hook(void)
 	printk(KERN_DEBUG "isdn_tty_off_hook\n");
 }
 
-#define PLUSWAIT1 (HZ/2)        /* 0.5 sec. */
-#define PLUSWAIT2 (HZ*3/2)      /* 1.5 sec */
+#define PLUSWAIT1 (HZ / 2)      /* 0.5 sec. */
+#define PLUSWAIT2 (HZ * 3 / 2)  /* 1.5 sec */
 
 /*
  * Check Buffer for Modem-escape-sequence, activate timer-callback to
@@ -2434,7 +2434,7 @@ isdn_tty_off_hook(void)
  *   lastplus   timestamp of last character
  */
 static void
-isdn_tty_check_esc(const u_char * p, u_char plus, int count, int *pluscount,
+isdn_tty_check_esc(const u_char *p, u_char plus, int count, int *pluscount,
 		   u_long *lastplus)
 {
 	if (plus > 127)
@@ -2474,69 +2474,69 @@ isdn_tty_check_esc(const u_char * p, u_char plus, int count, int *pluscount,
  */
 
 static void
-isdn_tty_modem_result(int code, modem_info * info)
+isdn_tty_modem_result(int code, modem_info *info)
 {
 	atemu *m = &info->emu;
 	static char *msg[] =
-	{"OK", "CONNECT", "RING", "NO CARRIER", "ERROR",
-	 "CONNECT 64000", "NO DIALTONE", "BUSY", "NO ANSWER",
-	 "RINGING", "NO MSN/EAZ", "VCON", "RUNG"};
-	char s[ISDN_MSNLEN+10];
+		{"OK", "CONNECT", "RING", "NO CARRIER", "ERROR",
+		 "CONNECT 64000", "NO DIALTONE", "BUSY", "NO ANSWER",
+		 "RINGING", "NO MSN/EAZ", "VCON", "RUNG"};
+	char s[ISDN_MSNLEN + 10];
 
 	switch (code) {
-		case RESULT_RING:
-			m->mdmreg[REG_RINGCNT]++;
-			if (m->mdmreg[REG_RINGCNT] == m->mdmreg[REG_RINGATA])
-				/* Automatically accept incoming call */
-				isdn_tty_cmd_ATA(info);
-			break;
-		case RESULT_NO_CARRIER:
+	case RESULT_RING:
+		m->mdmreg[REG_RINGCNT]++;
+		if (m->mdmreg[REG_RINGCNT] == m->mdmreg[REG_RINGATA])
+			/* Automatically accept incoming call */
+			isdn_tty_cmd_ATA(info);
+		break;
+	case RESULT_NO_CARRIER:
 #ifdef ISDN_DEBUG_MODEM_HUP
-			printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
-			       (info->flags & ISDN_ASYNC_CLOSING),
-			       (!info->tty));
-#endif
-			m->mdmreg[REG_RINGCNT] = 0;
-			del_timer(&info->nc_timer);
-			info->ncarrier = 0;
-			if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
-				return;
-			}
+		printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
+		       (info->flags & ISDN_ASYNC_CLOSING),
+		       (!info->tty));
+#endif
+		m->mdmreg[REG_RINGCNT] = 0;
+		del_timer(&info->nc_timer);
+		info->ncarrier = 0;
+		if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
+			return;
+		}
 #ifdef CONFIG_ISDN_AUDIO
-			if (info->vonline & 1) {
+		if (info->vonline & 1) {
 #ifdef ISDN_DEBUG_MODEM_VOICE
-				printk(KERN_DEBUG "res3: send DLE-ETX on ttyI%d\n",
-				       info->line);
+			printk(KERN_DEBUG "res3: send DLE-ETX on ttyI%d\n",
+			       info->line);
 #endif
-				/* voice-recording, add DLE-ETX */
-				isdn_tty_at_cout("\020\003", info);
-			}
-			if (info->vonline & 2) {
+			/* voice-recording, add DLE-ETX */
+			isdn_tty_at_cout("\020\003", info);
+		}
+		if (info->vonline & 2) {
 #ifdef ISDN_DEBUG_MODEM_VOICE
-				printk(KERN_DEBUG "res3: send DLE-DC4 on ttyI%d\n",
-				       info->line);
+			printk(KERN_DEBUG "res3: send DLE-DC4 on ttyI%d\n",
+			       info->line);
 #endif
-				/* voice-playing, add DLE-DC4 */
-				isdn_tty_at_cout("\020\024", info);
-			}
+			/* voice-playing, add DLE-DC4 */
+			isdn_tty_at_cout("\020\024", info);
+		}
 #endif
-			break;
-		case RESULT_CONNECT:
-		case RESULT_CONNECT64000:
-			sprintf(info->last_cause, "0000");
-			if (!info->online)
-				info->online = 2;
-			break;
-		case RESULT_VCON:
+		break;
+	case RESULT_CONNECT:
+	case RESULT_CONNECT64000:
+		sprintf(info->last_cause, "0000");
+		if (!info->online)
+			info->online = 2;
+		break;
+	case RESULT_VCON:
 #ifdef ISDN_DEBUG_MODEM_VOICE
-			printk(KERN_DEBUG "res3: send VCON on ttyI%d\n",
-			       info->line);
+		printk(KERN_DEBUG "res3: send VCON on ttyI%d\n",
+		       info->line);
 #endif
-			sprintf(info->last_cause, "0000");
-			if (!info->online)
-				info->online = 1;
-			break;
-	} /* switch(code) */
+		sprintf(info->last_cause, "0000");
+		if (!info->online)
+			info->online = 1;
+		break;
+	} /* switch (code) */
 
 	if (m->mdmreg[REG_RESP] & BIT_RESP) {
 		/* Show results */
@@ -2546,87 +2546,87 @@ isdn_tty_modem_result(int code, modem_info * info)
 			isdn_tty_at_cout(s, info);
 		} else {
 			if (code == RESULT_RING) {
-			    /* return if "show RUNG" and ringcounter>1 */
-			    if ((m->mdmreg[REG_RUNG] & BIT_RUNG) &&
+				/* return if "show RUNG" and ringcounter>1 */
+				if ((m->mdmreg[REG_RUNG] & BIT_RUNG) &&
 				    (m->mdmreg[REG_RINGCNT] > 1))
-						return;
-			    /* print CID, _before_ _every_ ring */
-			    if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) {
-				    isdn_tty_at_cout("\r\nCALLER NUMBER: ", info);
-				    isdn_tty_at_cout(dev->num[info->drv_index], info);
-				    if (m->mdmreg[REG_CDN] & BIT_CDN) {
-					    isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
-					    isdn_tty_at_cout(info->emu.cpn, info);
-				    }
-			    }
+					return;
+				/* print CID, _before_ _every_ ring */
+				if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) {
+					isdn_tty_at_cout("\r\nCALLER NUMBER: ", info);
+					isdn_tty_at_cout(dev->num[info->drv_index], info);
+					if (m->mdmreg[REG_CDN] & BIT_CDN) {
+						isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
+						isdn_tty_at_cout(info->emu.cpn, info);
+					}
+				}
 			}
 			isdn_tty_at_cout("\r\n", info);
 			isdn_tty_at_cout(msg[code], info);
 			switch (code) {
-				case RESULT_CONNECT:
-					switch (m->mdmreg[REG_L2PROT]) {
-						case ISDN_PROTO_L2_MODEM:
-							isdn_tty_at_cout(" ", info);
-							isdn_tty_at_cout(m->connmsg, info);
-							break;
-					}
+			case RESULT_CONNECT:
+				switch (m->mdmreg[REG_L2PROT]) {
+				case ISDN_PROTO_L2_MODEM:
+					isdn_tty_at_cout(" ", info);
+					isdn_tty_at_cout(m->connmsg, info);
 					break;
-				case RESULT_RING:
-					/* Append CPN, if enabled */
-					if ((m->mdmreg[REG_CPN] & BIT_CPN)) {
-						sprintf(s, "/%s", m->cpn);
-						isdn_tty_at_cout(s, info);
-					}
-					/* Print CID only once, _after_ 1st RING */
-					if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) &&
-					    (m->mdmreg[REG_RINGCNT] == 1)) {
-						isdn_tty_at_cout("\r\n", info);
-						isdn_tty_at_cout("CALLER NUMBER: ", info);
-						isdn_tty_at_cout(dev->num[info->drv_index], info);
-						if (m->mdmreg[REG_CDN] & BIT_CDN) {
-							isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
-							isdn_tty_at_cout(info->emu.cpn, info);
-						}
+				}
+				break;
+			case RESULT_RING:
+				/* Append CPN, if enabled */
+				if ((m->mdmreg[REG_CPN] & BIT_CPN)) {
+					sprintf(s, "/%s", m->cpn);
+					isdn_tty_at_cout(s, info);
+				}
+				/* Print CID only once, _after_ 1st RING */
+				if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) &&
+				    (m->mdmreg[REG_RINGCNT] == 1)) {
+					isdn_tty_at_cout("\r\n", info);
+					isdn_tty_at_cout("CALLER NUMBER: ", info);
+					isdn_tty_at_cout(dev->num[info->drv_index], info);
+					if (m->mdmreg[REG_CDN] & BIT_CDN) {
+						isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
+						isdn_tty_at_cout(info->emu.cpn, info);
 					}
+				}
+				break;
+			case RESULT_NO_CARRIER:
+			case RESULT_NO_DIALTONE:
+			case RESULT_BUSY:
+			case RESULT_NO_ANSWER:
+				m->mdmreg[REG_RINGCNT] = 0;
+				/* Append Cause-Message if enabled */
+				if (m->mdmreg[REG_RESPXT] & BIT_RESPXT) {
+					sprintf(s, "/%s", info->last_cause);
+					isdn_tty_at_cout(s, info);
+				}
+				break;
+			case RESULT_CONNECT64000:
+				/* Append Protocol to CONNECT message */
+				switch (m->mdmreg[REG_L2PROT]) {
+				case ISDN_PROTO_L2_X75I:
+				case ISDN_PROTO_L2_X75UI:
+				case ISDN_PROTO_L2_X75BUI:
+					isdn_tty_at_cout("/X.75", info);
 					break;
-				case RESULT_NO_CARRIER:
-				case RESULT_NO_DIALTONE:
-				case RESULT_BUSY:
-				case RESULT_NO_ANSWER:
-					m->mdmreg[REG_RINGCNT] = 0;
-					/* Append Cause-Message if enabled */
-					if (m->mdmreg[REG_RESPXT] & BIT_RESPXT) {
-						sprintf(s, "/%s", info->last_cause);
-						isdn_tty_at_cout(s, info);
-					}
+				case ISDN_PROTO_L2_HDLC:
+					isdn_tty_at_cout("/HDLC", info);
 					break;
-				case RESULT_CONNECT64000:
-					/* Append Protocol to CONNECT message */
-					switch (m->mdmreg[REG_L2PROT]) {
-						case ISDN_PROTO_L2_X75I:
-						case ISDN_PROTO_L2_X75UI:
-						case ISDN_PROTO_L2_X75BUI:
-							isdn_tty_at_cout("/X.75", info);
-							break;
-						case ISDN_PROTO_L2_HDLC:
-							isdn_tty_at_cout("/HDLC", info);
-							break;
-						case ISDN_PROTO_L2_V11096:
-							isdn_tty_at_cout("/V110/9600", info);
-							break;
-						case ISDN_PROTO_L2_V11019:
-							isdn_tty_at_cout("/V110/19200", info);
-							break;
-						case ISDN_PROTO_L2_V11038:
-							isdn_tty_at_cout("/V110/38400", info);
-							break;
-					}
-					if (m->mdmreg[REG_T70] & BIT_T70) {
-						isdn_tty_at_cout("/T.70", info);
-						if (m->mdmreg[REG_T70] & BIT_T70_EXT)
-							isdn_tty_at_cout("+", info);
-					}
+				case ISDN_PROTO_L2_V11096:
+					isdn_tty_at_cout("/V110/9600", info);
+					break;
+				case ISDN_PROTO_L2_V11019:
+					isdn_tty_at_cout("/V110/19200", info);
+					break;
+				case ISDN_PROTO_L2_V11038:
+					isdn_tty_at_cout("/V110/38400", info);
 					break;
+				}
+				if (m->mdmreg[REG_T70] & BIT_T70) {
+					isdn_tty_at_cout("/T.70", info);
+					if (m->mdmreg[REG_T70] & BIT_T70_EXT)
+						isdn_tty_at_cout("+", info);
+				}
+				break;
 			}
 			isdn_tty_at_cout("\r\n", info);
 		}
@@ -2648,7 +2648,7 @@ isdn_tty_modem_result(int code, modem_info * info)
  * Display a modem-register-value.
  */
 static void
-isdn_tty_show_profile(int ridx, modem_info * info)
+isdn_tty_show_profile(int ridx, modem_info *info)
 {
 	char v[6];
 
@@ -2667,7 +2667,7 @@ isdn_tty_get_msnstr(char *n, char **p)
 	while (((*p[0] >= '0' && *p[0] <= '9') ||
 		/* Why a comma ??? */
 		(*p[0] == ',') || (*p[0] == ':')) &&
-		(limit--))
+	       (limit--))
 		*n++ = *p[0]++;
 	*n = '\0';
 }
@@ -2676,20 +2676,20 @@ isdn_tty_get_msnstr(char *n, char **p)
  * Get phone-number from modem-commandbuffer
  */
 static void
-isdn_tty_getdial(char *p, char *q,int cnt)
+isdn_tty_getdial(char *p, char *q, int cnt)
 {
 	int first = 1;
 	int limit = ISDN_MSNLEN - 1;	/* MUST match the size of interface var to avoid
-					buffer overflow */
+					   buffer overflow */
 
-	while (strchr(" 0123456789,#.*WPTSR-", *p) && *p && --cnt>0) {
+	while (strchr(" 0123456789,#.*WPTSR-", *p) && *p && --cnt > 0) {
 		if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) ||
 		    ((*p == 'R') && first) ||
 		    (*p == '*') || (*p == '#')) {
 			*q++ = *p;
 			limit--;
 		}
-		if(!limit)
+		if (!limit)
 			break;
 		p++;
 		first = 0;
@@ -2701,7 +2701,7 @@ isdn_tty_getdial(char *p, char *q,int cnt)
 #define PARSE_ERROR1 { isdn_tty_modem_result(RESULT_ERROR, info); return 1; }
 
 static void
-isdn_tty_report(modem_info * info)
+isdn_tty_report(modem_info *info)
 {
 	atemu *m = &info->emu;
 	char s[80];
@@ -2713,39 +2713,39 @@ isdn_tty_report(modem_info * info)
 	isdn_tty_at_cout(s, info);
 	isdn_tty_at_cout("    Layer-2 Protocol: ", info);
 	switch (info->last_l2) {
-		case ISDN_PROTO_L2_X75I:
-			isdn_tty_at_cout("X.75i", info);
-			break;
-		case ISDN_PROTO_L2_X75UI:
-			isdn_tty_at_cout("X.75ui", info);
-			break;
-		case ISDN_PROTO_L2_X75BUI:
-			isdn_tty_at_cout("X.75bui", info);
-			break;
-		case ISDN_PROTO_L2_HDLC:
-			isdn_tty_at_cout("HDLC", info);
-			break;
-		case ISDN_PROTO_L2_V11096:
-			isdn_tty_at_cout("V.110 9600 Baud", info);
-			break;
-		case ISDN_PROTO_L2_V11019:
-			isdn_tty_at_cout("V.110 19200 Baud", info);
-			break;
-		case ISDN_PROTO_L2_V11038:
-			isdn_tty_at_cout("V.110 38400 Baud", info);
-			break;
-		case ISDN_PROTO_L2_TRANS:
-			isdn_tty_at_cout("transparent", info);
-			break;
-		case ISDN_PROTO_L2_MODEM:
-			isdn_tty_at_cout("modem", info);
-			break;
-		case ISDN_PROTO_L2_FAX:
-			isdn_tty_at_cout("fax", info);
-			break;
-		default:
-			isdn_tty_at_cout("unknown", info);
-			break;
+	case ISDN_PROTO_L2_X75I:
+		isdn_tty_at_cout("X.75i", info);
+		break;
+	case ISDN_PROTO_L2_X75UI:
+		isdn_tty_at_cout("X.75ui", info);
+		break;
+	case ISDN_PROTO_L2_X75BUI:
+		isdn_tty_at_cout("X.75bui", info);
+		break;
+	case ISDN_PROTO_L2_HDLC:
+		isdn_tty_at_cout("HDLC", info);
+		break;
+	case ISDN_PROTO_L2_V11096:
+		isdn_tty_at_cout("V.110 9600 Baud", info);
+		break;
+	case ISDN_PROTO_L2_V11019:
+		isdn_tty_at_cout("V.110 19200 Baud", info);
+		break;
+	case ISDN_PROTO_L2_V11038:
+		isdn_tty_at_cout("V.110 38400 Baud", info);
+		break;
+	case ISDN_PROTO_L2_TRANS:
+		isdn_tty_at_cout("transparent", info);
+		break;
+	case ISDN_PROTO_L2_MODEM:
+		isdn_tty_at_cout("modem", info);
+		break;
+	case ISDN_PROTO_L2_FAX:
+		isdn_tty_at_cout("fax", info);
+		break;
+	default:
+		isdn_tty_at_cout("unknown", info);
+		break;
 	}
 	if (m->mdmreg[REG_T70] & BIT_T70) {
 		isdn_tty_at_cout("/T.70", info);
@@ -2755,19 +2755,19 @@ isdn_tty_report(modem_info * info)
 	isdn_tty_at_cout("\r\n", info);
 	isdn_tty_at_cout("    Service:          ", info);
 	switch (info->last_si) {
-		case 1:
-			isdn_tty_at_cout("audio\r\n", info);
-			break;
-		case 5:
-			isdn_tty_at_cout("btx\r\n", info);
-			break;
-		case 7:
-			isdn_tty_at_cout("data\r\n", info);
-			break;
-		default:
-			sprintf(s, "%d\r\n", info->last_si);
-			isdn_tty_at_cout(s, info);
-			break;
+	case 1:
+		isdn_tty_at_cout("audio\r\n", info);
+		break;
+	case 5:
+		isdn_tty_at_cout("btx\r\n", info);
+		break;
+	case 7:
+		isdn_tty_at_cout("data\r\n", info);
+		break;
+	default:
+		sprintf(s, "%d\r\n", info->last_si);
+		isdn_tty_at_cout(s, info);
+		break;
 	}
 	sprintf(s, "    Hangup location:  %s\r\n", info->last_lhup ? "local" : "remote");
 	isdn_tty_at_cout(s, info);
@@ -2779,7 +2779,7 @@ isdn_tty_report(modem_info * info)
  * Parse AT&.. commands.
  */
 static int
-isdn_tty_cmd_ATand(char **p, modem_info * info)
+isdn_tty_cmd_ATand(char **p, modem_info *info)
 {
 	atemu *m = &info->emu;
 	int i;
@@ -2788,224 +2788,224 @@ isdn_tty_cmd_ATand(char **p, modem_info * info)
 #define MAXRB (sizeof(rb) - 1)
 
 	switch (*p[0]) {
-		case 'B':
-			/* &B - Set Buffersize */
-			p[0]++;
-			i = isdn_getnum(p);
-			if ((i < 0) || (i > ISDN_SERIAL_XMIT_MAX))
-				PARSE_ERROR1;
+	case 'B':
+		/* &B - Set Buffersize */
+		p[0]++;
+		i = isdn_getnum(p);
+		if ((i < 0) || (i > ISDN_SERIAL_XMIT_MAX))
+			PARSE_ERROR1;
 #ifdef CONFIG_ISDN_AUDIO
-			if ((m->mdmreg[REG_SI1] & 1) && (i > VBUF))
-				PARSE_ERROR1;
+		if ((m->mdmreg[REG_SI1] & 1) && (i > VBUF))
+			PARSE_ERROR1;
 #endif
-			m->mdmreg[REG_PSIZE] = i / 16;
-			info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
-			switch (m->mdmreg[REG_L2PROT]) {
-				case ISDN_PROTO_L2_V11096:
-				case ISDN_PROTO_L2_V11019:
-				case ISDN_PROTO_L2_V11038:
-					info->xmit_size /= 10;		
-			}
-			break;
-		case 'C':
-			/* &C - DCD Status */
-			p[0]++;
-			switch (isdn_getnum(p)) {
-				case 0:
-					m->mdmreg[REG_DCD] &= ~BIT_DCD;
-					break;
-				case 1:
-					m->mdmreg[REG_DCD] |= BIT_DCD;
-					break;
-				default:
-					PARSE_ERROR1
-			}
+		m->mdmreg[REG_PSIZE] = i / 16;
+		info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
+		switch (m->mdmreg[REG_L2PROT]) {
+		case ISDN_PROTO_L2_V11096:
+		case ISDN_PROTO_L2_V11019:
+		case ISDN_PROTO_L2_V11038:
+			info->xmit_size /= 10;
+		}
+		break;
+	case 'C':
+		/* &C - DCD Status */
+		p[0]++;
+		switch (isdn_getnum(p)) {
+		case 0:
+			m->mdmreg[REG_DCD] &= ~BIT_DCD;
 			break;
-		case 'D':
-			/* &D - Set DTR-Low-behavior */
-			p[0]++;
-			switch (isdn_getnum(p)) {
-				case 0:
-					m->mdmreg[REG_DTRHUP] &= ~BIT_DTRHUP;
-					m->mdmreg[REG_DTRR] &= ~BIT_DTRR;
-					break;
-				case 2:
-					m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP;
-					m->mdmreg[REG_DTRR] &= ~BIT_DTRR;
-					break;
-				case 3:
-					m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP;
-					m->mdmreg[REG_DTRR] |= BIT_DTRR;
-					break;
-				default:
-					PARSE_ERROR1
-			}
+		case 1:
+			m->mdmreg[REG_DCD] |= BIT_DCD;
 			break;
-		case 'E':
-			/* &E -Set EAZ/MSN */
-			p[0]++;
-			isdn_tty_get_msnstr(m->msn, p);
+		default:
+			PARSE_ERROR1
+				}
+		break;
+	case 'D':
+		/* &D - Set DTR-Low-behavior */
+		p[0]++;
+		switch (isdn_getnum(p)) {
+		case 0:
+			m->mdmreg[REG_DTRHUP] &= ~BIT_DTRHUP;
+			m->mdmreg[REG_DTRR] &= ~BIT_DTRR;
 			break;
-		case 'F':
-			/* &F -Set Factory-Defaults */
-			p[0]++;
-			if (info->msr & UART_MSR_DCD)
-				PARSE_ERROR1;
-			isdn_tty_reset_profile(m);
-			isdn_tty_modem_reset_regs(info, 1);
+		case 2:
+			m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP;
+			m->mdmreg[REG_DTRR] &= ~BIT_DTRR;
+			break;
+		case 3:
+			m->mdmreg[REG_DTRHUP] |= BIT_DTRHUP;
+			m->mdmreg[REG_DTRR] |= BIT_DTRR;
 			break;
+		default:
+			PARSE_ERROR1
+				}
+		break;
+	case 'E':
+		/* &E -Set EAZ/MSN */
+		p[0]++;
+		isdn_tty_get_msnstr(m->msn, p);
+		break;
+	case 'F':
+		/* &F -Set Factory-Defaults */
+		p[0]++;
+		if (info->msr & UART_MSR_DCD)
+			PARSE_ERROR1;
+		isdn_tty_reset_profile(m);
+		isdn_tty_modem_reset_regs(info, 1);
+		break;
 #ifdef DUMMY_HAYES_AT
-		case 'K':
-			/* only for be compilant with common scripts */
-			/* &K Flowcontrol - no function */
-			p[0]++;
-			isdn_getnum(p);
+	case 'K':
+		/* only for be compilant with common scripts */
+		/* &K Flowcontrol - no function */
+		p[0]++;
+		isdn_getnum(p);
+		break;
+#endif
+	case 'L':
+		/* &L -Set Numbers to listen on */
+		p[0]++;
+		i = 0;
+		while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
+		       (i < ISDN_LMSNLEN - 1))
+			m->lmsn[i++] = *p[0]++;
+		m->lmsn[i] = '\0';
+		break;
+	case 'R':
+		/* &R - Set V.110 bitrate adaption */
+		p[0]++;
+		i = isdn_getnum(p);
+		switch (i) {
+		case 0:
+			/* Switch off V.110, back to X.75 */
+			m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+			m->mdmreg[REG_SI2] = 0;
+			info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
 			break;
-#endif
-		case 'L':
-			/* &L -Set Numbers to listen on */
-			p[0]++;
-			i = 0;
-			while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
-			       (i < ISDN_LMSNLEN - 1))
-				m->lmsn[i++] = *p[0]++;
-			m->lmsn[i] = '\0';
-			break;
-		case 'R':
-			/* &R - Set V.110 bitrate adaption */
-			p[0]++;
-			i = isdn_getnum(p);
-			switch (i) {
-				case 0:
-					/* Switch off V.110, back to X.75 */
-					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
-					m->mdmreg[REG_SI2] = 0;
-					info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
-					break;
-				case 9600:
-					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11096;
-					m->mdmreg[REG_SI2] = 197;
-					info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
-					break;
-				case 19200:
-					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11019;
-					m->mdmreg[REG_SI2] = 199;
-					info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
-					break;
-				case 38400:
-					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11038;
-					m->mdmreg[REG_SI2] = 198; /* no existing standard for this */
-					info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
-					break;
-				default:
-					PARSE_ERROR1;
-			}
-			/* Switch off T.70 */
-			m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT);
-			/* Set Service 7 */
-			m->mdmreg[REG_SI1] |= 4;
+		case 9600:
+			m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11096;
+			m->mdmreg[REG_SI2] = 197;
+			info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
 			break;
-		case 'S':
-			/* &S - Set Windowsize */
-			p[0]++;
-			i = isdn_getnum(p);
-			if ((i > 0) && (i < 9))
-				m->mdmreg[REG_WSIZE] = i;
-			else
-				PARSE_ERROR1;
+		case 19200:
+			m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11019;
+			m->mdmreg[REG_SI2] = 199;
+			info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
 			break;
-		case 'V':
-			/* &V - Show registers */
-			p[0]++;
-			isdn_tty_at_cout("\r\n", info);
-			for (i = 0; i < ISDN_MODEM_NUMREG; i++) {
-				sprintf(rb, "S%02d=%03d%s", i,
-					m->mdmreg[i], ((i + 1) % 10) ? " " : "\r\n");
-				isdn_tty_at_cout(rb, info);
-			}
-			sprintf(rb, "\r\nEAZ/MSN: %.50s\r\n",
-				strlen(m->msn) ? m->msn : "None");
-			isdn_tty_at_cout(rb, info);
-			if (strlen(m->lmsn)) {
-				isdn_tty_at_cout("\r\nListen: ", info);
-				isdn_tty_at_cout(m->lmsn, info);
-				isdn_tty_at_cout("\r\n", info);
-			}
+		case 38400:
+			m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_V11038;
+			m->mdmreg[REG_SI2] = 198; /* no existing standard for this */
+			info->xmit_size = m->mdmreg[REG_PSIZE] * 16 / 10;
 			break;
-		case 'W':
-			/* &W - Write Profile */
+		default:
+			PARSE_ERROR1;
+		}
+		/* Switch off T.70 */
+		m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT);
+		/* Set Service 7 */
+		m->mdmreg[REG_SI1] |= 4;
+		break;
+	case 'S':
+		/* &S - Set Windowsize */
+		p[0]++;
+		i = isdn_getnum(p);
+		if ((i > 0) && (i < 9))
+			m->mdmreg[REG_WSIZE] = i;
+		else
+			PARSE_ERROR1;
+		break;
+	case 'V':
+		/* &V - Show registers */
+		p[0]++;
+		isdn_tty_at_cout("\r\n", info);
+		for (i = 0; i < ISDN_MODEM_NUMREG; i++) {
+			sprintf(rb, "S%02d=%03d%s", i,
+				m->mdmreg[i], ((i + 1) % 10) ? " " : "\r\n");
+			isdn_tty_at_cout(rb, info);
+		}
+		sprintf(rb, "\r\nEAZ/MSN: %.50s\r\n",
+			strlen(m->msn) ? m->msn : "None");
+		isdn_tty_at_cout(rb, info);
+		if (strlen(m->lmsn)) {
+			isdn_tty_at_cout("\r\nListen: ", info);
+			isdn_tty_at_cout(m->lmsn, info);
+			isdn_tty_at_cout("\r\n", info);
+		}
+		break;
+	case 'W':
+		/* &W - Write Profile */
+		p[0]++;
+		switch (*p[0]) {
+		case '0':
 			p[0]++;
-			switch (*p[0]) {
-				case '0':
-					p[0]++;
-					modem_write_profile(m);
-					break;
-				default:
-					PARSE_ERROR1;
-			}
+			modem_write_profile(m);
 			break;
-		case 'X':
-			/* &X - Switch to BTX-Mode and T.70 */
-			p[0]++;
-			switch (isdn_getnum(p)) {
-				case 0:
-					m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT);
-					info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
-					break;
-				case 1:
-					m->mdmreg[REG_T70] |= BIT_T70;
-					m->mdmreg[REG_T70] &= ~BIT_T70_EXT;
-					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
-					info->xmit_size = 112;
-					m->mdmreg[REG_SI1] = 4;
-					m->mdmreg[REG_SI2] = 0;
-					break;
-				case 2:
-					m->mdmreg[REG_T70] |= (BIT_T70 | BIT_T70_EXT);
-					m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
-					info->xmit_size = 112;
-					m->mdmreg[REG_SI1] = 4;
-					m->mdmreg[REG_SI2] = 0;
-					break;
-				default:
-					PARSE_ERROR1;
-			}
+		default:
+			PARSE_ERROR1;
+		}
+		break;
+	case 'X':
+		/* &X - Switch to BTX-Mode and T.70 */
+		p[0]++;
+		switch (isdn_getnum(p)) {
+		case 0:
+			m->mdmreg[REG_T70] &= ~(BIT_T70 | BIT_T70_EXT);
+			info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
+			break;
+		case 1:
+			m->mdmreg[REG_T70] |= BIT_T70;
+			m->mdmreg[REG_T70] &= ~BIT_T70_EXT;
+			m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+			info->xmit_size = 112;
+			m->mdmreg[REG_SI1] = 4;
+			m->mdmreg[REG_SI2] = 0;
+			break;
+		case 2:
+			m->mdmreg[REG_T70] |= (BIT_T70 | BIT_T70_EXT);
+			m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+			info->xmit_size = 112;
+			m->mdmreg[REG_SI1] = 4;
+			m->mdmreg[REG_SI2] = 0;
 			break;
 		default:
 			PARSE_ERROR1;
+		}
+		break;
+	default:
+		PARSE_ERROR1;
 	}
 	return 0;
 }
 
 static int
-isdn_tty_check_ats(int mreg, int mval, modem_info * info, atemu * m)
+isdn_tty_check_ats(int mreg, int mval, modem_info *info, atemu *m)
 {
 	/* Some plausibility checks */
 	switch (mreg) {
-		case REG_L2PROT:
-			if (mval > ISDN_PROTO_L2_MAX)
-				return 1;
-			break;
-		case REG_PSIZE:
-			if ((mval * 16) > ISDN_SERIAL_XMIT_MAX)
-				return 1;
+	case REG_L2PROT:
+		if (mval > ISDN_PROTO_L2_MAX)
+			return 1;
+		break;
+	case REG_PSIZE:
+		if ((mval * 16) > ISDN_SERIAL_XMIT_MAX)
+			return 1;
 #ifdef CONFIG_ISDN_AUDIO
-			if ((m->mdmreg[REG_SI1] & 1) && (mval > VBUFX))
-				return 1;
-#endif
-			info->xmit_size = mval * 16;
-			switch (m->mdmreg[REG_L2PROT]) {
-				case ISDN_PROTO_L2_V11096:
-				case ISDN_PROTO_L2_V11019:
-				case ISDN_PROTO_L2_V11038:
-					info->xmit_size /= 10;		
-			}
-			break;
-		case REG_SI1I:
-		case REG_PLAN:
-		case REG_SCREEN:
-			/* readonly registers */
+		if ((m->mdmreg[REG_SI1] & 1) && (mval > VBUFX))
 			return 1;
+#endif
+		info->xmit_size = mval * 16;
+		switch (m->mdmreg[REG_L2PROT]) {
+		case ISDN_PROTO_L2_V11096:
+		case ISDN_PROTO_L2_V11019:
+		case ISDN_PROTO_L2_V11038:
+			info->xmit_size /= 10;
+		}
+		break;
+	case REG_SI1I:
+	case REG_PLAN:
+	case REG_SCREEN:
+		/* readonly registers */
+		return 1;
 	}
 	return 0;
 }
@@ -3014,7 +3014,7 @@ isdn_tty_check_ats(int mreg, int mval, modem_info * info, atemu * m)
  * Perform ATS command
  */
 static int
-isdn_tty_cmd_ATS(char **p, modem_info * info)
+isdn_tty_cmd_ATS(char **p, modem_info *info)
 {
 	atemu *m = &info->emu;
 	int bitpos;
@@ -3026,52 +3026,52 @@ isdn_tty_cmd_ATS(char **p, modem_info * info)
 	if (mreg < 0 || mreg >= ISDN_MODEM_NUMREG)
 		PARSE_ERROR1;
 	switch (*p[0]) {
+	case '=':
+		p[0]++;
+		mval = isdn_getnum(p);
+		if (mval < 0 || mval > 255)
+			PARSE_ERROR1;
+		if (isdn_tty_check_ats(mreg, mval, info, m))
+			PARSE_ERROR1;
+		m->mdmreg[mreg] = mval;
+		break;
+	case '.':
+		/* Set/Clear a single bit */
+		p[0]++;
+		bitpos = isdn_getnum(p);
+		if ((bitpos < 0) || (bitpos > 7))
+			PARSE_ERROR1;
+		switch (*p[0]) {
 		case '=':
 			p[0]++;
-			mval = isdn_getnum(p);
-			if (mval < 0 || mval > 255)
+			bval = isdn_getnum(p);
+			if (bval < 0 || bval > 1)
 				PARSE_ERROR1;
+			if (bval)
+				mval = m->mdmreg[mreg] | (1 << bitpos);
+			else
+				mval = m->mdmreg[mreg] & ~(1 << bitpos);
 			if (isdn_tty_check_ats(mreg, mval, info, m))
 				PARSE_ERROR1;
 			m->mdmreg[mreg] = mval;
 			break;
-		case '.':
-			/* Set/Clear a single bit */
-			p[0]++;
-			bitpos = isdn_getnum(p);
-			if ((bitpos < 0) || (bitpos > 7))
-				PARSE_ERROR1;
-			switch (*p[0]) {
-				case '=':
-					p[0]++;
-					bval = isdn_getnum(p);
-					if (bval < 0 || bval > 1)
-						PARSE_ERROR1;
-					if (bval)
-						mval = m->mdmreg[mreg] | (1 << bitpos);
-					else
-						mval = m->mdmreg[mreg] & ~(1 << bitpos);
-					if (isdn_tty_check_ats(mreg, mval, info, m))
-						PARSE_ERROR1;
-					m->mdmreg[mreg] = mval;
-					break;
-				case '?':
-					p[0]++;
-					isdn_tty_at_cout("\r\n", info);
-					isdn_tty_at_cout((m->mdmreg[mreg] & (1 << bitpos)) ? "1" : "0",
-							 info);
-					break;
-				default:
-					PARSE_ERROR1;
-			}
-			break;
 		case '?':
 			p[0]++;
-			isdn_tty_show_profile(mreg, info);
+			isdn_tty_at_cout("\r\n", info);
+			isdn_tty_at_cout((m->mdmreg[mreg] & (1 << bitpos)) ? "1" : "0",
+					 info);
 			break;
 		default:
 			PARSE_ERROR1;
-			break;
+		}
+		break;
+	case '?':
+		p[0]++;
+		isdn_tty_show_profile(mreg, info);
+		break;
+	default:
+		PARSE_ERROR1;
+		break;
 	}
 	return 0;
 }
@@ -3080,7 +3080,7 @@ isdn_tty_cmd_ATS(char **p, modem_info * info)
  * Perform ATA command
  */
 static void
-isdn_tty_cmd_ATA(modem_info * info)
+isdn_tty_cmd_ATA(modem_info *info)
 {
 	atemu *m = &info->emu;
 	isdn_ctrl cmd;
@@ -3134,7 +3134,7 @@ isdn_tty_cmd_ATA(modem_info * info)
  * Parse AT+F.. commands
  */
 static int
-isdn_tty_cmd_PLUSF(char **p, modem_info * info)
+isdn_tty_cmd_PLUSF(char **p, modem_info *info)
 {
 	atemu *m = &info->emu;
 	char rs[20];
@@ -3142,81 +3142,81 @@ isdn_tty_cmd_PLUSF(char **p, modem_info * info)
 	if (!strncmp(p[0], "CLASS", 5)) {
 		p[0] += 5;
 		switch (*p[0]) {
-			case '?':
-				p[0]++;
-				sprintf(rs, "\r\n%d",
-					(m->mdmreg[REG_SI1] & 1) ? 8 : 0);
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d",
+				(m->mdmreg[REG_SI1] & 1) ? 8 : 0);
 #ifdef CONFIG_ISDN_TTY_FAX
-				if (TTY_IS_FCLASS2(info))
-						sprintf(rs, "\r\n2");
-				else if (TTY_IS_FCLASS1(info))
-						sprintf(rs, "\r\n1");
+			if (TTY_IS_FCLASS2(info))
+				sprintf(rs, "\r\n2");
+			else if (TTY_IS_FCLASS1(info))
+				sprintf(rs, "\r\n1");
 #endif
-				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			switch (*p[0]) {
+			case '0':
 				p[0]++;
-				switch (*p[0]) {
-					case '0':
-						p[0]++;
-						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
-						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
-						m->mdmreg[REG_SI1] = 4;
-						info->xmit_size =
-						    m->mdmreg[REG_PSIZE] * 16;
-						break;
+				m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+				m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
+				m->mdmreg[REG_SI1] = 4;
+				info->xmit_size =
+					m->mdmreg[REG_PSIZE] * 16;
+				break;
 #ifdef CONFIG_ISDN_TTY_FAX
-					case '1':
-						p[0]++;
-						if (!(dev->global_features &
-							ISDN_FEATURE_L3_FCLASS1))
-							PARSE_ERROR1;
-						m->mdmreg[REG_SI1] = 1;
-						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
-						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS1;
-						info->xmit_size =
-						    m->mdmreg[REG_PSIZE] * 16;
-						break;
-					case '2':
-						p[0]++;
-						if (!(dev->global_features &
-							ISDN_FEATURE_L3_FCLASS2))
-							PARSE_ERROR1;
-						m->mdmreg[REG_SI1] = 1;
-						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
-						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS2;
-						info->xmit_size =
-						    m->mdmreg[REG_PSIZE] * 16;
-						break;
+			case '1':
+				p[0]++;
+				if (!(dev->global_features &
+				      ISDN_FEATURE_L3_FCLASS1))
+					PARSE_ERROR1;
+				m->mdmreg[REG_SI1] = 1;
+				m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
+				m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS1;
+				info->xmit_size =
+					m->mdmreg[REG_PSIZE] * 16;
+				break;
+			case '2':
+				p[0]++;
+				if (!(dev->global_features &
+				      ISDN_FEATURE_L3_FCLASS2))
+					PARSE_ERROR1;
+				m->mdmreg[REG_SI1] = 1;
+				m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_FAX;
+				m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_FCLASS2;
+				info->xmit_size =
+					m->mdmreg[REG_PSIZE] * 16;
+				break;
 #endif
-					case '8':
-						p[0]++;
-						/* L2 will change on dialout with si=1 */
-						m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
-						m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
-						m->mdmreg[REG_SI1] = 5;
-						info->xmit_size = VBUF;
-						break;
-					case '?':
-						p[0]++;
-						strcpy(rs, "\r\n0,");
+			case '8':
+				p[0]++;
+				/* L2 will change on dialout with si=1 */
+				m->mdmreg[REG_L2PROT] = ISDN_PROTO_L2_X75I;
+				m->mdmreg[REG_L3PROT] = ISDN_PROTO_L3_TRANS;
+				m->mdmreg[REG_SI1] = 5;
+				info->xmit_size = VBUF;
+				break;
+			case '?':
+				p[0]++;
+				strcpy(rs, "\r\n0,");
 #ifdef CONFIG_ISDN_TTY_FAX
-						if (dev->global_features &
-							ISDN_FEATURE_L3_FCLASS1)
-							strcat(rs, "1,");
-						if (dev->global_features &
-							ISDN_FEATURE_L3_FCLASS2)
-							strcat(rs, "2,");
-#endif
-						strcat(rs, "8");
-						isdn_tty_at_cout(rs, info);
-						break;
-					default:
-						PARSE_ERROR1;
-				}
+				if (dev->global_features &
+				    ISDN_FEATURE_L3_FCLASS1)
+					strcat(rs, "1,");
+				if (dev->global_features &
+				    ISDN_FEATURE_L3_FCLASS2)
+					strcat(rs, "2,");
+#endif
+				strcat(rs, "8");
+				isdn_tty_at_cout(rs, info);
 				break;
 			default:
 				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -3231,12 +3231,12 @@ isdn_tty_cmd_PLUSF(char **p, modem_info * info)
  * Parse AT+V.. commands
  */
 static int
-isdn_tty_cmd_PLUSV(char **p, modem_info * info)
+isdn_tty_cmd_PLUSV(char **p, modem_info *info)
 {
 	atemu *m = &info->emu;
 	isdn_ctrl cmd;
 	static char *vcmd[] =
-	{"NH", "IP", "LS", "RX", "SD", "SM", "TX", "DD", NULL};
+		{"NH", "IP", "LS", "RX", "SD", "SM", "TX", "DD", NULL};
 	int i;
 	int par1;
 	int par2;
@@ -3251,256 +3251,256 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
 		i++;
 	}
 	switch (i) {
-		case 0:
-			/* AT+VNH - Auto hangup feature */
+	case 0:
+		/* AT+VNH - Auto hangup feature */
+		switch (*p[0]) {
+		case '?':
+			p[0]++;
+			isdn_tty_at_cout("\r\n1", info);
+			break;
+		case '=':
+			p[0]++;
 			switch (*p[0]) {
-				case '?':
-					p[0]++;
-					isdn_tty_at_cout("\r\n1", info);
-					break;
-				case '=':
-					p[0]++;
-					switch (*p[0]) {
-						case '1':
-							p[0]++;
-							break;
-						case '?':
-							p[0]++;
-							isdn_tty_at_cout("\r\n1", info);
-							break;
-						default:
-							PARSE_ERROR1;
-					}
-					break;
-				default:
-					PARSE_ERROR1;
+			case '1':
+				p[0]++;
+				break;
+			case '?':
+				p[0]++;
+				isdn_tty_at_cout("\r\n1", info);
+				break;
+			default:
+				PARSE_ERROR1;
 			}
 			break;
-		case 1:
-			/* AT+VIP - Reset all voice parameters */
-			isdn_tty_modem_reset_vpar(m);
+		default:
+			PARSE_ERROR1;
+		}
+		break;
+	case 1:
+		/* AT+VIP - Reset all voice parameters */
+		isdn_tty_modem_reset_vpar(m);
+		break;
+	case 2:
+		/* AT+VLS - Select device, accept incoming call */
+		switch (*p[0]) {
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", m->vpar[0]);
+			isdn_tty_at_cout(rs, info);
 			break;
-		case 2:
-			/* AT+VLS - Select device, accept incoming call */
+		case '=':
+			p[0]++;
 			switch (*p[0]) {
-				case '?':
-					p[0]++;
-					sprintf(rs, "\r\n%d", m->vpar[0]);
-					isdn_tty_at_cout(rs, info);
-					break;
-				case '=':
-					p[0]++;
-					switch (*p[0]) {
-						case '0':
-							p[0]++;
-							m->vpar[0] = 0;
-							break;
-						case '2':
-							p[0]++;
-							m->vpar[0] = 2;
-							break;
-						case '?':
-							p[0]++;
-							isdn_tty_at_cout("\r\n0,2", info);
-							break;
-						default:
-							PARSE_ERROR1;
-					}
-					break;
-				default:
-					PARSE_ERROR1;
-			}
-			break;
-		case 3:
-			/* AT+VRX - Start recording */
-			if (!m->vpar[0])
-				PARSE_ERROR1;
-			if (info->online != 1) {
-				isdn_tty_modem_result(RESULT_NO_ANSWER, info);
-				return 1;
-			}
-			info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
-			if (!info->dtmf_state) {
-				printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
+			case '0':
+				p[0]++;
+				m->vpar[0] = 0;
+				break;
+			case '2':
+				p[0]++;
+				m->vpar[0] = 2;
+				break;
+			case '?':
+				p[0]++;
+				isdn_tty_at_cout("\r\n0,2", info);
+				break;
+			default:
 				PARSE_ERROR1;
 			}
-			info->silence_state = isdn_audio_silence_init(info->silence_state);
-			if (!info->silence_state) {
-				printk(KERN_WARNING "isdn_tty: Couldn't malloc silence state\n");
+			break;
+		default:
+			PARSE_ERROR1;
+		}
+		break;
+	case 3:
+		/* AT+VRX - Start recording */
+		if (!m->vpar[0])
+			PARSE_ERROR1;
+		if (info->online != 1) {
+			isdn_tty_modem_result(RESULT_NO_ANSWER, info);
+			return 1;
+		}
+		info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
+		if (!info->dtmf_state) {
+			printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
+			PARSE_ERROR1;
+		}
+		info->silence_state = isdn_audio_silence_init(info->silence_state);
+		if (!info->silence_state) {
+			printk(KERN_WARNING "isdn_tty: Couldn't malloc silence state\n");
+			PARSE_ERROR1;
+		}
+		if (m->vpar[3] < 5) {
+			info->adpcmr = isdn_audio_adpcm_init(info->adpcmr, m->vpar[3]);
+			if (!info->adpcmr) {
+				printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
 				PARSE_ERROR1;
 			}
-			if (m->vpar[3] < 5) {
-				info->adpcmr = isdn_audio_adpcm_init(info->adpcmr, m->vpar[3]);
-				if (!info->adpcmr) {
-					printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
-					PARSE_ERROR1;
-				}
-			}
+		}
 #ifdef ISDN_DEBUG_AT
-			printk(KERN_DEBUG "AT: +VRX\n");
+		printk(KERN_DEBUG "AT: +VRX\n");
 #endif
-			info->vonline |= 1;
-			isdn_tty_modem_result(RESULT_CONNECT, info);
-			return 0;
+		info->vonline |= 1;
+		isdn_tty_modem_result(RESULT_CONNECT, info);
+		return 0;
+		break;
+	case 4:
+		/* AT+VSD - Silence detection */
+		switch (*p[0]) {
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n<%d>,<%d>",
+				m->vpar[1],
+				m->vpar[2]);
+			isdn_tty_at_cout(rs, info);
 			break;
-		case 4:
-			/* AT+VSD - Silence detection */
-			switch (*p[0]) {
-				case '?':
-					p[0]++;
-					sprintf(rs, "\r\n<%d>,<%d>",
-						m->vpar[1],
-						m->vpar[2]);
-					isdn_tty_at_cout(rs, info);
-					break;
-				case '=':
-					p[0]++;
-					if ((*p[0]>='0') && (*p[0]<='9')) {
-						par1 = isdn_getnum(p);
-						if ((par1 < 0) || (par1 > 31))
-							PARSE_ERROR1;
-						if (*p[0] != ',')
-							PARSE_ERROR1;
-						p[0]++;
-						par2 = isdn_getnum(p);
-						if ((par2 < 0) || (par2 > 255))
-							PARSE_ERROR1;
-						m->vpar[1] = par1;
-						m->vpar[2] = par2;
-						break;
-					} else 
-					if (*p[0] == '?') {
-						p[0]++;
-						isdn_tty_at_cout("\r\n<0-31>,<0-255>",
-							   info);
-						break;
-					} else
+		case '=':
+			p[0]++;
+			if ((*p[0] >= '0') && (*p[0] <= '9')) {
+				par1 = isdn_getnum(p);
+				if ((par1 < 0) || (par1 > 31))
 					PARSE_ERROR1;
-					break;
-				default:
+				if (*p[0] != ',')
 					PARSE_ERROR1;
-			}
-			break;
-		case 5:
-			/* AT+VSM - Select compression */
-			switch (*p[0]) {
-				case '?':
-					p[0]++;
-					sprintf(rs, "\r\n<%d>,<%d><8000>",
-						m->vpar[3],
-						m->vpar[1]);
-					isdn_tty_at_cout(rs, info);
-					break;
-				case '=':
+				p[0]++;
+				par2 = isdn_getnum(p);
+				if ((par2 < 0) || (par2 > 255))
+					PARSE_ERROR1;
+				m->vpar[1] = par1;
+				m->vpar[2] = par2;
+				break;
+			} else
+				if (*p[0] == '?') {
 					p[0]++;
-					switch (*p[0]) {
-						case '2':
-						case '3':
-						case '4':
-						case '5':
-						case '6':
-							par1 = isdn_getnum(p);
-							if ((par1 < 2) || (par1 > 6))
-								PARSE_ERROR1;
-							m->vpar[3] = par1;
-							break;
-						case '?':
-							p[0]++;
-							isdn_tty_at_cout("\r\n2;ADPCM;2;0;(8000)\r\n",
-								   info);
-							isdn_tty_at_cout("3;ADPCM;3;0;(8000)\r\n",
-								   info);
-							isdn_tty_at_cout("4;ADPCM;4;0;(8000)\r\n",
-								   info);
-							isdn_tty_at_cout("5;ALAW;8;0;(8000)\r\n",
-								   info);
-							isdn_tty_at_cout("6;ULAW;8;0;(8000)\r\n",
-								   info);
-							break;
-						default:
-							PARSE_ERROR1;
-					}
+					isdn_tty_at_cout("\r\n<0-31>,<0-255>",
+							 info);
 					break;
-				default:
+				} else
 					PARSE_ERROR1;
-			}
 			break;
-		case 6:
-			/* AT+VTX - Start sending */
-			if (!m->vpar[0])
+		default:
+			PARSE_ERROR1;
+		}
+		break;
+	case 5:
+		/* AT+VSM - Select compression */
+		switch (*p[0]) {
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n<%d>,<%d><8000>",
+				m->vpar[3],
+				m->vpar[1]);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			switch (*p[0]) {
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+				par1 = isdn_getnum(p);
+				if ((par1 < 2) || (par1 > 6))
+					PARSE_ERROR1;
+				m->vpar[3] = par1;
+				break;
+			case '?':
+				p[0]++;
+				isdn_tty_at_cout("\r\n2;ADPCM;2;0;(8000)\r\n",
+						 info);
+				isdn_tty_at_cout("3;ADPCM;3;0;(8000)\r\n",
+						 info);
+				isdn_tty_at_cout("4;ADPCM;4;0;(8000)\r\n",
+						 info);
+				isdn_tty_at_cout("5;ALAW;8;0;(8000)\r\n",
+						 info);
+				isdn_tty_at_cout("6;ULAW;8;0;(8000)\r\n",
+						 info);
+				break;
+			default:
 				PARSE_ERROR1;
-			if (info->online != 1) {
-				isdn_tty_modem_result(RESULT_NO_ANSWER, info);
-				return 1;
 			}
-			info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
-			if (!info->dtmf_state) {
-				printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
+			break;
+		default:
+			PARSE_ERROR1;
+		}
+		break;
+	case 6:
+		/* AT+VTX - Start sending */
+		if (!m->vpar[0])
+			PARSE_ERROR1;
+		if (info->online != 1) {
+			isdn_tty_modem_result(RESULT_NO_ANSWER, info);
+			return 1;
+		}
+		info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
+		if (!info->dtmf_state) {
+			printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
+			PARSE_ERROR1;
+		}
+		if (m->vpar[3] < 5) {
+			info->adpcms = isdn_audio_adpcm_init(info->adpcms, m->vpar[3]);
+			if (!info->adpcms) {
+				printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
 				PARSE_ERROR1;
 			}
-			if (m->vpar[3] < 5) {
-				info->adpcms = isdn_audio_adpcm_init(info->adpcms, m->vpar[3]);
-				if (!info->adpcms) {
-					printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
-					PARSE_ERROR1;
-				}
-			}
+		}
 #ifdef ISDN_DEBUG_AT
-			printk(KERN_DEBUG "AT: +VTX\n");
+		printk(KERN_DEBUG "AT: +VTX\n");
 #endif
-			m->lastDLE = 0;
-			info->vonline |= 2;
-			isdn_tty_modem_result(RESULT_CONNECT, info);
-			return 0;
+		m->lastDLE = 0;
+		info->vonline |= 2;
+		isdn_tty_modem_result(RESULT_CONNECT, info);
+		return 0;
+		break;
+	case 7:
+		/* AT+VDD - DTMF detection */
+		switch (*p[0]) {
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n<%d>,<%d>",
+				m->vpar[4],
+				m->vpar[5]);
+			isdn_tty_at_cout(rs, info);
 			break;
-		case 7:
-			/* AT+VDD - DTMF detection */
-			switch (*p[0]) {
-				case '?':
-					p[0]++;
-					sprintf(rs, "\r\n<%d>,<%d>",
-						m->vpar[4],
-						m->vpar[5]);
-					isdn_tty_at_cout(rs, info);
-					break;
-				case '=':
-					p[0]++;
-					if ((*p[0]>='0') && (*p[0]<='9')) {
-						if (info->online != 1)
-							PARSE_ERROR1;
-						par1 = isdn_getnum(p);
-						if ((par1 < 0) || (par1 > 15))
-							PARSE_ERROR1;
-						if (*p[0] != ',')
-							PARSE_ERROR1;
-						p[0]++;
-						par2 = isdn_getnum(p);
-						if ((par2 < 0) || (par2 > 255))
-							PARSE_ERROR1;
-						m->vpar[4] = par1;
-						m->vpar[5] = par2;
-						cmd.driver = info->isdn_driver;
-						cmd.command = ISDN_CMD_AUDIO;
-						cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8);
-						cmd.parm.num[0] = par1;
-						cmd.parm.num[1] = par2;
-						isdn_command(&cmd);
-						break;
-					} else
-					if (*p[0] == '?') {
-						p[0]++;
-						isdn_tty_at_cout("\r\n<0-15>,<0-255>",
-							info);
-						break;
-					} else
+		case '=':
+			p[0]++;
+			if ((*p[0] >= '0') && (*p[0] <= '9')) {
+				if (info->online != 1)
+					PARSE_ERROR1;
+				par1 = isdn_getnum(p);
+				if ((par1 < 0) || (par1 > 15))
+					PARSE_ERROR1;
+				if (*p[0] != ',')
 					PARSE_ERROR1;
+				p[0]++;
+				par2 = isdn_getnum(p);
+				if ((par2 < 0) || (par2 > 255))
+					PARSE_ERROR1;
+				m->vpar[4] = par1;
+				m->vpar[5] = par2;
+				cmd.driver = info->isdn_driver;
+				cmd.command = ISDN_CMD_AUDIO;
+				cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8);
+				cmd.parm.num[0] = par1;
+				cmd.parm.num[1] = par2;
+				isdn_command(&cmd);
+				break;
+			} else
+				if (*p[0] == '?') {
+					p[0]++;
+					isdn_tty_at_cout("\r\n<0-15>,<0-255>",
+							 info);
 					break;
-				default:
+				} else
 					PARSE_ERROR1;
-			}
 			break;
 		default:
 			PARSE_ERROR1;
+		}
+		break;
+	default:
+		PARSE_ERROR1;
 	}
 	return 0;
 }
@@ -3510,7 +3510,7 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
  * Parse and perform an AT-command-line.
  */
 static void
-isdn_tty_parse_at(modem_info * info)
+isdn_tty_parse_at(modem_info *info)
 {
 	atemu *m = &info->emu;
 	char *p;
@@ -3521,188 +3521,188 @@ isdn_tty_parse_at(modem_info * info)
 #endif
 	for (p = &m->mdmcmd[2]; *p;) {
 		switch (*p) {
-			case ' ':
-				p++;
+		case ' ':
+			p++;
+			break;
+		case 'A':
+			/* A - Accept incoming call */
+			p++;
+			isdn_tty_cmd_ATA(info);
+			return;
+			break;
+		case 'D':
+			/* D - Dial */
+			if (info->msr & UART_MSR_DCD)
+				PARSE_ERROR;
+			if (info->msr & UART_MSR_RI) {
+				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
+				return;
+			}
+			isdn_tty_getdial(++p, ds, sizeof ds);
+			p += strlen(p);
+			if (!strlen(m->msn))
+				isdn_tty_modem_result(RESULT_NO_MSN_EAZ, info);
+			else if (strlen(ds))
+				isdn_tty_dial(ds, info, m);
+			else
+				PARSE_ERROR;
+			return;
+		case 'E':
+			/* E - Turn Echo on/off */
+			p++;
+			switch (isdn_getnum(&p)) {
+			case 0:
+				m->mdmreg[REG_ECHO] &= ~BIT_ECHO;
 				break;
-			case 'A':
-				/* A - Accept incoming call */
+			case 1:
+				m->mdmreg[REG_ECHO] |= BIT_ECHO;
+				break;
+			default:
+				PARSE_ERROR;
+			}
+			break;
+		case 'H':
+			/* H - On/Off-hook */
+			p++;
+			switch (*p) {
+			case '0':
 				p++;
-				isdn_tty_cmd_ATA(info);
-				return;
+				isdn_tty_on_hook(info);
 				break;
-			case 'D':
-				/* D - Dial */
-				if (info->msr & UART_MSR_DCD)
-					PARSE_ERROR;
-				if (info->msr & UART_MSR_RI) {
-					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
-					return;
-				}
-				isdn_tty_getdial(++p, ds, sizeof ds);
-				p += strlen(p);
-				if (!strlen(m->msn))
-					isdn_tty_modem_result(RESULT_NO_MSN_EAZ, info);
-				else if (strlen(ds))
-					isdn_tty_dial(ds, info, m);
-				else
-					PARSE_ERROR;
-				return;
-			case 'E':
-				/* E - Turn Echo on/off */
+			case '1':
 				p++;
-				switch (isdn_getnum(&p)) {
-					case 0:
-						m->mdmreg[REG_ECHO] &= ~BIT_ECHO;
-						break;
-					case 1:
-						m->mdmreg[REG_ECHO] |= BIT_ECHO;
-						break;
-					default:
-						PARSE_ERROR;
-				}
+				isdn_tty_off_hook();
 				break;
-			case 'H':
-				/* H - On/Off-hook */
+			default:
+				isdn_tty_on_hook(info);
+				break;
+			}
+			break;
+		case 'I':
+			/* I - Information */
+			p++;
+			isdn_tty_at_cout("\r\nLinux ISDN", info);
+			switch (*p) {
+			case '0':
+			case '1':
 				p++;
-				switch (*p) {
-					case '0':
-						p++;
-						isdn_tty_on_hook(info);
-						break;
-					case '1':
-						p++;
-						isdn_tty_off_hook();
-						break;
-					default:
-						isdn_tty_on_hook(info);
-						break;
-				}
 				break;
-			case 'I':
-				/* I - Information */
+			case '2':
 				p++;
-				isdn_tty_at_cout("\r\nLinux ISDN", info);
-				switch (*p) {
-					case '0':
-					case '1':
-						p++;
-						break;
-					case '2':
-						p++;
-						isdn_tty_report(info);
-						break;
-					case '3':
-                                                p++;
-                                                snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge);
-                                                isdn_tty_at_cout(ds, info);
-                                                break;
-					default:;
-				}
+				isdn_tty_report(info);
 				break;
-#ifdef DUMMY_HAYES_AT
-			case 'L':
-			case 'M':
-				/* only for be compilant with common scripts */
-				/* no function */
+			case '3':
 				p++;
-				isdn_getnum(&p);
+				snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge);
+				isdn_tty_at_cout(ds, info);
 				break;
+			default:;
+			}
+			break;
+#ifdef DUMMY_HAYES_AT
+		case 'L':
+		case 'M':
+			/* only for be compilant with common scripts */
+			/* no function */
+			p++;
+			isdn_getnum(&p);
+			break;
 #endif
-			case 'O':
-				/* O - Go online */
-				p++;
-				if (info->msr & UART_MSR_DCD)
-					/* if B-Channel is up */
-					isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT:RESULT_CONNECT64000, info);
-				else
-					isdn_tty_modem_result(RESULT_NO_CARRIER, info);
+		case 'O':
+			/* O - Go online */
+			p++;
+			if (info->msr & UART_MSR_DCD)
+				/* if B-Channel is up */
+				isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT : RESULT_CONNECT64000, info);
+			else
+				isdn_tty_modem_result(RESULT_NO_CARRIER, info);
+			return;
+		case 'Q':
+			/* Q - Turn Emulator messages on/off */
+			p++;
+			switch (isdn_getnum(&p)) {
+			case 0:
+				m->mdmreg[REG_RESP] |= BIT_RESP;
+				break;
+			case 1:
+				m->mdmreg[REG_RESP] &= ~BIT_RESP;
+				break;
+			default:
+				PARSE_ERROR;
+			}
+			break;
+		case 'S':
+			/* S - Set/Get Register */
+			p++;
+			if (isdn_tty_cmd_ATS(&p, info))
 				return;
-			case 'Q':
-				/* Q - Turn Emulator messages on/off */
-				p++;
-				switch (isdn_getnum(&p)) {
-					case 0:
-						m->mdmreg[REG_RESP] |= BIT_RESP;
-						break;
-					case 1:
-						m->mdmreg[REG_RESP] &= ~BIT_RESP;
-						break;
-					default:
-						PARSE_ERROR;
-				}
+			break;
+		case 'V':
+			/* V - Numeric or ASCII Emulator-messages */
+			p++;
+			switch (isdn_getnum(&p)) {
+			case 0:
+				m->mdmreg[REG_RESP] |= BIT_RESPNUM;
+				break;
+			case 1:
+				m->mdmreg[REG_RESP] &= ~BIT_RESPNUM;
 				break;
-			case 'S':
-				/* S - Set/Get Register */
+			default:
+				PARSE_ERROR;
+			}
+			break;
+		case 'Z':
+			/* Z - Load Registers from Profile */
+			p++;
+			if (info->msr & UART_MSR_DCD) {
+				info->online = 0;
+				isdn_tty_on_hook(info);
+			}
+			isdn_tty_modem_reset_regs(info, 1);
+			break;
+		case '+':
+			p++;
+			switch (*p) {
+#ifdef CONFIG_ISDN_AUDIO
+			case 'F':
 				p++;
-				if (isdn_tty_cmd_ATS(&p, info))
+				if (isdn_tty_cmd_PLUSF(&p, info))
 					return;
 				break;
 			case 'V':
-				/* V - Numeric or ASCII Emulator-messages */
+				if ((!(m->mdmreg[REG_SI1] & 1)) ||
+				    (m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM))
+					PARSE_ERROR;
 				p++;
-				switch (isdn_getnum(&p)) {
-					case 0:
-						m->mdmreg[REG_RESP] |= BIT_RESPNUM;
-						break;
-					case 1:
-						m->mdmreg[REG_RESP] &= ~BIT_RESPNUM;
-						break;
-					default:
-						PARSE_ERROR;
-				}
+				if (isdn_tty_cmd_PLUSV(&p, info))
+					return;
 				break;
-			case 'Z':
-				/* Z - Load Registers from Profile */
+#endif                          /* CONFIG_ISDN_AUDIO */
+			case 'S':	/* SUSPEND */
 				p++;
-				if (info->msr & UART_MSR_DCD) {
-					info->online = 0;
-					isdn_tty_on_hook(info);
-				}
-				isdn_tty_modem_reset_regs(info, 1);
+				isdn_tty_get_msnstr(ds, &p);
+				isdn_tty_suspend(ds, info, m);
 				break;
-			case '+':
+			case 'R':	/* RESUME */
 				p++;
-				switch (*p) {
-#ifdef CONFIG_ISDN_AUDIO
-					case 'F':
-						p++;
-						if (isdn_tty_cmd_PLUSF(&p, info))
-							return;
-						break;
-					case 'V':
-						if ((!(m->mdmreg[REG_SI1] & 1)) ||
-							(m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM))
-							PARSE_ERROR;
-						p++;
-						if (isdn_tty_cmd_PLUSV(&p, info))
-							return;
-						break;
-#endif                          /* CONFIG_ISDN_AUDIO */
-					case 'S':	/* SUSPEND */
-						p++;
-						isdn_tty_get_msnstr(ds, &p);
-						isdn_tty_suspend(ds, info, m);
-						break;
-					case 'R':	/* RESUME */
-						p++;
-						isdn_tty_get_msnstr(ds, &p);
-						isdn_tty_resume(ds, info, m);
-						break;
-					case 'M':	/* MESSAGE */
-						p++;
-						isdn_tty_send_msg(info, m, p);
-						break;
-					default:
-						PARSE_ERROR;
-				}
+				isdn_tty_get_msnstr(ds, &p);
+				isdn_tty_resume(ds, info, m);
 				break;
-			case '&':
+			case 'M':	/* MESSAGE */
 				p++;
-				if (isdn_tty_cmd_ATand(&p, info))
-					return;
+				isdn_tty_send_msg(info, m, p);
 				break;
 			default:
 				PARSE_ERROR;
+			}
+			break;
+		case '&':
+			p++;
+			if (isdn_tty_cmd_ATand(&p, info))
+				return;
+			break;
+		default:
+			PARSE_ERROR;
 		}
 	}
 #ifdef CONFIG_ISDN_AUDIO
@@ -3714,7 +3714,7 @@ isdn_tty_parse_at(modem_info * info)
 /* Need own toupper() because standard-toupper is not available
  * within modules.
  */
-#define my_toupper(c) (((c>='a')&&(c<='z'))?(c&0xdf):c)
+#define my_toupper(c) (((c >= 'a') && (c <= 'z')) ? (c & 0xdf) : c)
 
 /*
  * Perform line-editing of AT-commands
@@ -3725,7 +3725,7 @@ isdn_tty_parse_at(modem_info * info)
  *   channel  index to line (minor-device)
  */
 static int
-isdn_tty_edit_at(const char *p, int count, modem_info * info)
+isdn_tty_edit_at(const char *p, int count, modem_info *info)
 {
 	atemu *m = &info->emu;
 	int total = 0;
@@ -3768,23 +3768,23 @@ isdn_tty_edit_at(const char *p, int count, modem_info * info)
 			if (m->mdmcmdl < 255) {
 				c = my_toupper(c);
 				switch (m->mdmcmdl) {
-					case 1:
-						if (c == 'T') {
-							m->mdmcmd[m->mdmcmdl] = c;
-							m->mdmcmd[++m->mdmcmdl] = 0;
-							break;
-						} else
-							m->mdmcmdl = 0;
-						/* Fall through, check for 'A' */
-					case 0:
-						if (c == 'A') {
-							m->mdmcmd[m->mdmcmdl] = c;
-							m->mdmcmd[++m->mdmcmdl] = 0;
-						}
+				case 1:
+					if (c == 'T') {
+						m->mdmcmd[m->mdmcmdl] = c;
+						m->mdmcmd[++m->mdmcmdl] = 0;
 						break;
-					default:
+					} else
+						m->mdmcmdl = 0;
+					/* Fall through, check for 'A' */
+				case 0:
+					if (c == 'A') {
 						m->mdmcmd[m->mdmcmdl] = c;
 						m->mdmcmd[++m->mdmcmdl] = 0;
+					}
+					break;
+				default:
+					m->mdmcmd[m->mdmcmdl] = c;
+					m->mdmcmd[++m->mdmcmdl] = 0;
 				}
 			}
 		}
diff --git a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h
index 692c74d..a6f801d 100644
--- a/drivers/isdn/i4l/isdn_tty.h
+++ b/drivers/isdn/i4l/isdn_tty.h
@@ -93,11 +93,11 @@
 #define RESULT_VCON		11
 #define RESULT_RUNG		12
 
-#define TTY_IS_FCLASS1(info) \
-	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
+#define TTY_IS_FCLASS1(info)						\
+	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) &&		\
 	 (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS1))
-#define TTY_IS_FCLASS2(info) \
-	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
+#define TTY_IS_FCLASS2(info)						\
+	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) &&		\
 	 (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS2))
 
 extern void isdn_tty_modem_escape(void);
@@ -110,7 +110,7 @@ extern void isdn_tty_readmodem(void);
 extern int  isdn_tty_find_icall(int, int, setup_parm *);
 extern int  isdn_tty_stat_callback(int, isdn_ctrl *);
 extern int  isdn_tty_rcv_skb(int, int, int, struct sk_buff *);
-extern int  isdn_tty_capi_facility(capi_msg *cm); 
+extern int  isdn_tty_capi_facility(capi_msg *cm);
 extern void isdn_tty_at_cout(char *, modem_info *);
 extern void isdn_tty_modem_hup(modem_info *, int);
 #ifdef CONFIG_ISDN_TTY_FAX
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index 4c41f19..47aae49 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -45,7 +45,7 @@ isdn_getrev(const char *revision)
  */
 
 static void
-isdn_tty_fax_modem_result(int code, modem_info * info)
+isdn_tty_fax_modem_result(int code, modem_info *info)
 {
 	atemu *m = &info->emu;
 	T30_s *f = info->fax;
@@ -54,9 +54,9 @@ isdn_tty_fax_modem_result(int code, modem_info * info)
 	char *rp;
 	int i;
 	static char *msg[] =
-	{"OK", "ERROR", "+FCON", "+FCSI:", "+FDIS:",
-	 "+FHNG:", "+FDCS:", "CONNECT", "+FTSI:",
-	 "+FCFR", "+FPTS:", "+FET:"};
+		{"OK", "ERROR", "+FCON", "+FCSI:", "+FDIS:",
+		 "+FHNG:", "+FDCS:", "CONNECT", "+FTSI:",
+		 "+FCFR", "+FPTS:", "+FET:"};
 
 
 	isdn_tty_at_cout("\r\n", info);
@@ -64,95 +64,95 @@ isdn_tty_fax_modem_result(int code, modem_info * info)
 
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
 	printk(KERN_DEBUG "isdn_tty: Fax send %s on ttyI%d\n",
-		msg[code], info->line);
+	       msg[code], info->line);
 #endif
 	switch (code) {
-		case 0: /* OK */
-			break;
-		case 1: /* ERROR */
-			break;
-		case 2:	/* +FCON */
-			/* Append CPN, if enabled */
-			if ((m->mdmreg[REG_CPNFCON] & BIT_CPNFCON) &&
-				(!(dev->usage[info->isdn_channel] & ISDN_USAGE_OUTGOING))) {
-				sprintf(rs, "/%s", m->cpn);
-				isdn_tty_at_cout(rs, info);
-			}
-			info->online = 1;
-			f->fet = 0;
-			if (f->phase == ISDN_FAX_PHASE_A)
-				f->phase = ISDN_FAX_PHASE_B;
-			break;
-		case 3:	/* +FCSI */
-		case 8:	/* +FTSI */
-			sprintf(rs, "\"%s\"", f->r_id);
-			isdn_tty_at_cout(rs, info);
-			break;
-		case 4:	/* +FDIS */
-			rs[0] = 0;
-			rp = &f->r_resolution;
-			for (i = 0; i < 8; i++) {
-				sprintf(rss, "%c%s", rp[i] + 48,
-					(i < 7) ? "," : "");
-				strcat(rs, rss);
-			}
+	case 0: /* OK */
+		break;
+	case 1: /* ERROR */
+		break;
+	case 2:	/* +FCON */
+		/* Append CPN, if enabled */
+		if ((m->mdmreg[REG_CPNFCON] & BIT_CPNFCON) &&
+		    (!(dev->usage[info->isdn_channel] & ISDN_USAGE_OUTGOING))) {
+			sprintf(rs, "/%s", m->cpn);
 			isdn_tty_at_cout(rs, info);
+		}
+		info->online = 1;
+		f->fet = 0;
+		if (f->phase == ISDN_FAX_PHASE_A)
+			f->phase = ISDN_FAX_PHASE_B;
+		break;
+	case 3:	/* +FCSI */
+	case 8:	/* +FTSI */
+		sprintf(rs, "\"%s\"", f->r_id);
+		isdn_tty_at_cout(rs, info);
+		break;
+	case 4:	/* +FDIS */
+		rs[0] = 0;
+		rp = &f->r_resolution;
+		for (i = 0; i < 8; i++) {
+			sprintf(rss, "%c%s", rp[i] + 48,
+				(i < 7) ? "," : "");
+			strcat(rs, rss);
+		}
+		isdn_tty_at_cout(rs, info);
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
-			printk(KERN_DEBUG "isdn_tty: Fax DIS=%s on ttyI%d\n",
-			       rs, info->line);
+		printk(KERN_DEBUG "isdn_tty: Fax DIS=%s on ttyI%d\n",
+		       rs, info->line);
 #endif
-			break;
-		case 5:	/* +FHNG */
-			sprintf(rs, "%d", f->code);
-			isdn_tty_at_cout(rs, info);
-			info->faxonline = 0;
-			break;
-		case 6:	/* +FDCS */
-			rs[0] = 0;
-			rp = &f->r_resolution;
-			for (i = 0; i < 8; i++) {
-				sprintf(rss, "%c%s", rp[i] + 48,
-					(i < 7) ? "," : "");
-				strcat(rs, rss);
-			}
-			isdn_tty_at_cout(rs, info);
+		break;
+	case 5:	/* +FHNG */
+		sprintf(rs, "%d", f->code);
+		isdn_tty_at_cout(rs, info);
+		info->faxonline = 0;
+		break;
+	case 6:	/* +FDCS */
+		rs[0] = 0;
+		rp = &f->r_resolution;
+		for (i = 0; i < 8; i++) {
+			sprintf(rss, "%c%s", rp[i] + 48,
+				(i < 7) ? "," : "");
+			strcat(rs, rss);
+		}
+		isdn_tty_at_cout(rs, info);
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
-			printk(KERN_DEBUG "isdn_tty: Fax DCS=%s on ttyI%d\n",
-			       rs, info->line);
+		printk(KERN_DEBUG "isdn_tty: Fax DCS=%s on ttyI%d\n",
+		       rs, info->line);
 #endif
-			break;
-		case 7:	/* CONNECT */
-			info->faxonline |= 2;
-			break;
-		case 9:	/* FCFR */
-			break;
-		case 10:	/* FPTS */
-			isdn_tty_at_cout("1", info);
-			break;
-		case 11:	/* FET */
-			sprintf(rs, "%d", f->fet);
-			isdn_tty_at_cout(rs, info);
-			break;
+		break;
+	case 7:	/* CONNECT */
+		info->faxonline |= 2;
+		break;
+	case 9:	/* FCFR */
+		break;
+	case 10:	/* FPTS */
+		isdn_tty_at_cout("1", info);
+		break;
+	case 11:	/* FET */
+		sprintf(rs, "%d", f->fet);
+		isdn_tty_at_cout(rs, info);
+		break;
 	}
 
 	isdn_tty_at_cout("\r\n", info);
 
 	switch (code) {
-		case 7:	/* CONNECT */
-			info->online = 2;
-			if (info->faxonline & 1) {
-				sprintf(rs, "%c", XON);
-				isdn_tty_at_cout(rs, info);
-			}
-			break;
+	case 7:	/* CONNECT */
+		info->online = 2;
+		if (info->faxonline & 1) {
+			sprintf(rs, "%c", XON);
+			isdn_tty_at_cout(rs, info);
+		}
+		break;
 	}
 }
 
 static int
-isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c)
+isdn_tty_fax_command1(modem_info *info, isdn_ctrl *c)
 {
 	static char *msg[] =
-	{"OK", "CONNECT", "NO CARRIER", "ERROR", "FCERROR"};
+		{"OK", "CONNECT", "NO CARRIER", "ERROR", "FCERROR"};
 
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
 	printk(KERN_DEBUG "isdn_tty: FCLASS1 cmd(%d)\n", c->parm.aux.cmd);
@@ -165,30 +165,30 @@ isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c)
 		isdn_tty_at_cout("\r\n", info);
 	}
 	switch (c->parm.aux.cmd) {
-		case ISDN_FAX_CLASS1_CONNECT:
-			info->online = 2;
-			break;
-		case ISDN_FAX_CLASS1_OK:
-		case ISDN_FAX_CLASS1_FCERROR:
-		case ISDN_FAX_CLASS1_ERROR:
-		case ISDN_FAX_CLASS1_NOCARR:
-			break;
-		case ISDN_FAX_CLASS1_QUERY:
+	case ISDN_FAX_CLASS1_CONNECT:
+		info->online = 2;
+		break;
+	case ISDN_FAX_CLASS1_OK:
+	case ISDN_FAX_CLASS1_FCERROR:
+	case ISDN_FAX_CLASS1_ERROR:
+	case ISDN_FAX_CLASS1_NOCARR:
+		break;
+	case ISDN_FAX_CLASS1_QUERY:
+		isdn_tty_at_cout("\r\n", info);
+		if (!c->parm.aux.para[0]) {
+			isdn_tty_at_cout(msg[ISDN_FAX_CLASS1_ERROR], info);
 			isdn_tty_at_cout("\r\n", info);
-			if (!c->parm.aux.para[0]) {
-				isdn_tty_at_cout(msg[ISDN_FAX_CLASS1_ERROR], info);
-				isdn_tty_at_cout("\r\n", info);
-			} else {
-				isdn_tty_at_cout(c->parm.aux.para, info);
-				isdn_tty_at_cout("\r\nOK\r\n", info);
-			}
-			break;
+		} else {
+			isdn_tty_at_cout(c->parm.aux.para, info);
+			isdn_tty_at_cout("\r\nOK\r\n", info);
+		}
+		break;
 	}
 	return (0);
 }
 
 int
-isdn_tty_fax_command(modem_info * info, isdn_ctrl * c)
+isdn_tty_fax_command(modem_info *info, isdn_ctrl *c)
 {
 	T30_s *f = info->fax;
 	char rs[10];
@@ -201,78 +201,78 @@ isdn_tty_fax_command(modem_info * info, isdn_ctrl * c)
 	       f->r_code, info->line);
 #endif
 	switch (f->r_code) {
-		case ISDN_TTY_FAX_FCON:
-			info->faxonline = 1;
-			isdn_tty_fax_modem_result(2, info);	/* +FCON */
-			return (0);
-		case ISDN_TTY_FAX_FCON_I:
-			info->faxonline = 16;
-			isdn_tty_fax_modem_result(2, info);	/* +FCON */
-			return (0);
-		case ISDN_TTY_FAX_RID:
-			if (info->faxonline & 1)
-				isdn_tty_fax_modem_result(3, info);	/* +FCSI */
-			if (info->faxonline & 16)
-				isdn_tty_fax_modem_result(8, info);	/* +FTSI */
-			return (0);
-		case ISDN_TTY_FAX_DIS:
-			isdn_tty_fax_modem_result(4, info);	/* +FDIS */
-			return (0);
-		case ISDN_TTY_FAX_HNG:
-			if (f->phase == ISDN_FAX_PHASE_C) {
-				if (f->direction == ISDN_TTY_FAX_CONN_IN) {
-					sprintf(rs, "%c%c", DLE, ETX);
-					isdn_tty_at_cout(rs, info);
-				} else {
-					sprintf(rs, "%c", 0x18);
-					isdn_tty_at_cout(rs, info);
-				}
-				info->faxonline &= ~2;	/* leave data mode */
-				info->online = 1;
-			}
-			f->phase = ISDN_FAX_PHASE_E;
-			isdn_tty_fax_modem_result(5, info);	/* +FHNG */
-			isdn_tty_fax_modem_result(0, info);	/* OK */
-			return (0);
-		case ISDN_TTY_FAX_DCS:
-			isdn_tty_fax_modem_result(6, info);	/* +FDCS */
-			isdn_tty_fax_modem_result(7, info);	/* CONNECT */
-			f->phase = ISDN_FAX_PHASE_C;
-			return (0);
-		case ISDN_TTY_FAX_TRAIN_OK:
-			isdn_tty_fax_modem_result(6, info);	/* +FDCS */
-			isdn_tty_fax_modem_result(0, info);	/* OK */
-			return (0);
-		case ISDN_TTY_FAX_SENT:
-			isdn_tty_fax_modem_result(0, info);	/* OK */
-			return (0);
-		case ISDN_TTY_FAX_CFR:
-			isdn_tty_fax_modem_result(9, info);	/* +FCFR */
-			return (0);
-		case ISDN_TTY_FAX_ET:
-			sprintf(rs, "%c%c", DLE, ETX);
-			isdn_tty_at_cout(rs, info);
-			isdn_tty_fax_modem_result(10, info);	/* +FPTS */
-			isdn_tty_fax_modem_result(11, info);	/* +FET */
-			isdn_tty_fax_modem_result(0, info);	/* OK */
-			info->faxonline &= ~2;	/* leave data mode */
-			info->online = 1;
-			f->phase = ISDN_FAX_PHASE_D;
-			return (0);
-		case ISDN_TTY_FAX_PTS:
-			isdn_tty_fax_modem_result(10, info);	/* +FPTS */
-			if (f->direction == ISDN_TTY_FAX_CONN_OUT) {
-				if (f->fet == 1)
-					f->phase = ISDN_FAX_PHASE_B;
-				if (f->fet == 0)
-					isdn_tty_fax_modem_result(0, info);	/* OK */
+	case ISDN_TTY_FAX_FCON:
+		info->faxonline = 1;
+		isdn_tty_fax_modem_result(2, info);	/* +FCON */
+		return (0);
+	case ISDN_TTY_FAX_FCON_I:
+		info->faxonline = 16;
+		isdn_tty_fax_modem_result(2, info);	/* +FCON */
+		return (0);
+	case ISDN_TTY_FAX_RID:
+		if (info->faxonline & 1)
+			isdn_tty_fax_modem_result(3, info);	/* +FCSI */
+		if (info->faxonline & 16)
+			isdn_tty_fax_modem_result(8, info);	/* +FTSI */
+		return (0);
+	case ISDN_TTY_FAX_DIS:
+		isdn_tty_fax_modem_result(4, info);	/* +FDIS */
+		return (0);
+	case ISDN_TTY_FAX_HNG:
+		if (f->phase == ISDN_FAX_PHASE_C) {
+			if (f->direction == ISDN_TTY_FAX_CONN_IN) {
+				sprintf(rs, "%c%c", DLE, ETX);
+				isdn_tty_at_cout(rs, info);
+			} else {
+				sprintf(rs, "%c", 0x18);
+				isdn_tty_at_cout(rs, info);
 			}
-			return (0);
-		case ISDN_TTY_FAX_EOP:
 			info->faxonline &= ~2;	/* leave data mode */
 			info->online = 1;
-			f->phase = ISDN_FAX_PHASE_D;
-			return (0);
+		}
+		f->phase = ISDN_FAX_PHASE_E;
+		isdn_tty_fax_modem_result(5, info);	/* +FHNG */
+		isdn_tty_fax_modem_result(0, info);	/* OK */
+		return (0);
+	case ISDN_TTY_FAX_DCS:
+		isdn_tty_fax_modem_result(6, info);	/* +FDCS */
+		isdn_tty_fax_modem_result(7, info);	/* CONNECT */
+		f->phase = ISDN_FAX_PHASE_C;
+		return (0);
+	case ISDN_TTY_FAX_TRAIN_OK:
+		isdn_tty_fax_modem_result(6, info);	/* +FDCS */
+		isdn_tty_fax_modem_result(0, info);	/* OK */
+		return (0);
+	case ISDN_TTY_FAX_SENT:
+		isdn_tty_fax_modem_result(0, info);	/* OK */
+		return (0);
+	case ISDN_TTY_FAX_CFR:
+		isdn_tty_fax_modem_result(9, info);	/* +FCFR */
+		return (0);
+	case ISDN_TTY_FAX_ET:
+		sprintf(rs, "%c%c", DLE, ETX);
+		isdn_tty_at_cout(rs, info);
+		isdn_tty_fax_modem_result(10, info);	/* +FPTS */
+		isdn_tty_fax_modem_result(11, info);	/* +FET */
+		isdn_tty_fax_modem_result(0, info);	/* OK */
+		info->faxonline &= ~2;	/* leave data mode */
+		info->online = 1;
+		f->phase = ISDN_FAX_PHASE_D;
+		return (0);
+	case ISDN_TTY_FAX_PTS:
+		isdn_tty_fax_modem_result(10, info);	/* +FPTS */
+		if (f->direction == ISDN_TTY_FAX_CONN_OUT) {
+			if (f->fet == 1)
+				f->phase = ISDN_FAX_PHASE_B;
+			if (f->fet == 0)
+				isdn_tty_fax_modem_result(0, info);	/* OK */
+		}
+		return (0);
+	case ISDN_TTY_FAX_EOP:
+		info->faxonline &= ~2;	/* leave data mode */
+		info->online = 1;
+		f->phase = ISDN_FAX_PHASE_D;
+		return (0);
 
 	}
 	return (-1);
@@ -280,7 +280,7 @@ isdn_tty_fax_command(modem_info * info, isdn_ctrl * c)
 
 
 void
-isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb)
+isdn_tty_fax_bitorder(modem_info *info, struct sk_buff *skb)
 {
 	__u8 LeftMask;
 	__u8 RightMask;
@@ -292,10 +292,10 @@ isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb)
 		for (i = 0; i < skb->len; i++) {
 			Data = skb->data[i];
 			for (
-				    LeftMask = 0x80, RightMask = 0x01;
-				    LeftMask > RightMask;
-				    LeftMask >>= 1, RightMask <<= 1
-			    ) {
+				LeftMask = 0x80, RightMask = 0x01;
+				LeftMask > RightMask;
+				LeftMask >>= 1, RightMask <<= 1
+				) {
 				fBit = (Data & LeftMask);
 				if (Data & RightMask)
 					Data |= LeftMask;
@@ -317,10 +317,10 @@ isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb)
  */
 
 static int
-isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
+isdn_tty_cmd_FCLASS1(char **p, modem_info *info)
 {
 	static char *cmd[] =
-	{"AE", "TS", "RS", "TM", "RM", "TH", "RH"};
+		{"AE", "TS", "RS", "TM", "RM", "TH", "RH"};
 	isdn_ctrl c;
 	int par, i;
 	u_long flags;
@@ -337,28 +337,28 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
 
 	p[0] += 2;
 	switch (*p[0]) {
-		case '?':
-			p[0]++;
-			c.parm.aux.subcmd = AT_QUERY;
-			break;
-		case '=':
+	case '?':
+		p[0]++;
+		c.parm.aux.subcmd = AT_QUERY;
+		break;
+	case '=':
+		p[0]++;
+		if (*p[0] == '?') {
 			p[0]++;
-			if (*p[0] == '?') {
-				p[0]++;
-				c.parm.aux.subcmd = AT_EQ_QUERY;
-			} else {
-				par = isdn_getnum(p);
-				if ((par < 0) || (par > 255))
-					PARSE_ERROR1;
-				c.parm.aux.subcmd = AT_EQ_VALUE;
-				c.parm.aux.para[0] = par;
-			}
-			break;
-		case 0:
-			c.parm.aux.subcmd = AT_COMMAND;
-			break;
-		default:
-			PARSE_ERROR1;
+			c.parm.aux.subcmd = AT_EQ_QUERY;
+		} else {
+			par = isdn_getnum(p);
+			if ((par < 0) || (par > 255))
+				PARSE_ERROR1;
+			c.parm.aux.subcmd = AT_EQ_VALUE;
+			c.parm.aux.para[0] = par;
+		}
+		break;
+	case 0:
+		c.parm.aux.subcmd = AT_COMMAND;
+		break;
+	default:
+		PARSE_ERROR1;
 	}
 	c.command = ISDN_CMD_FAXCMD;
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
@@ -409,7 +409,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
  */
 
 static int
-isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
+isdn_tty_cmd_FCLASS2(char **p, modem_info *info)
 {
 	atemu *m = &info->emu;
 	T30_s *f = info->fax;
@@ -418,25 +418,25 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	char rs[50];
 	char rss[50];
 	int maxdccval[] =
-	{1, 5, 2, 2, 3, 2, 0, 7};
+		{1, 5, 2, 2, 3, 2, 0, 7};
 
 	/* FAA still unchanged */
 	if (!strncmp(p[0], "AA", 2)) {	/* TODO */
 		p[0] += 2;
 		switch (*p[0]) {
-			case '?':
-				p[0]++;
-				sprintf(rs, "\r\n%d", 0);
-				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				par = isdn_getnum(p);
-				if ((par < 0) || (par > 255))
-					PARSE_ERROR1;
-				break;
-			default:
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", 0);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			par = isdn_getnum(p);
+			if ((par < 0) || (par > 255))
 				PARSE_ERROR1;
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -444,29 +444,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "BADLIN", 6)) {
 		p[0] += 6;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->badlin);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->badlin);
+				sprintf(rs, "\r\n0-255");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0-255");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 255))
-						PARSE_ERROR1;
-					f->badlin = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 255))
+					PARSE_ERROR1;
+				f->badlin = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FBADLIN=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FBADLIN=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -474,29 +474,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "BADMUL", 6)) {
 		p[0] += 6;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->badmul);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->badmul);
+				sprintf(rs, "\r\n0-255");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0-255");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 255))
-						PARSE_ERROR1;
-					f->badmul = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 255))
+					PARSE_ERROR1;
+				f->badmul = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FBADMUL=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FBADMUL=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -504,29 +504,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "BOR", 3)) {
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->bor);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->bor);
+				sprintf(rs, "\r\n0,1");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0,1");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 1))
-						PARSE_ERROR1;
-					f->bor = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 1))
+					PARSE_ERROR1;
+				f->bor = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FBOR=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FBOR=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -534,29 +534,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "NBC", 3)) {
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->nbc);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->nbc);
+				sprintf(rs, "\r\n0,1");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0,1");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 1))
-						PARSE_ERROR1;
-					f->nbc = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 1))
+					PARSE_ERROR1;
+				f->nbc = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FNBC=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FNBC=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -576,36 +576,36 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 		int i, r;
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n\"%s\"", f->pollid);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n\"%s\"", f->pollid);
+				sprintf(rs, "\r\n\"STRING\"");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
+			} else {
+				if (*p[0] == '"')
 					p[0]++;
-					sprintf(rs, "\r\n\"STRING\"");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					if (*p[0] == '"')
-						p[0]++;
-					for (i = 0; (*p[0]) && i < (FAXIDLEN - 1) && (*p[0] != '"'); i++) {
-						f->pollid[i] = *p[0]++;
-					}
-					if (*p[0] == '"')
-						p[0]++;
-					for (r = i; r < FAXIDLEN; r++) {
-						f->pollid[r] = 32;
-					}
-					f->pollid[FAXIDLEN - 1] = 0;
+				for (i = 0; (*p[0]) && i < (FAXIDLEN - 1) && (*p[0] != '"'); i++) {
+					f->pollid[i] = *p[0]++;
+				}
+				if (*p[0] == '"')
+					p[0]++;
+				for (r = i; r < FAXIDLEN; r++) {
+					f->pollid[r] = 32;
+				}
+				f->pollid[FAXIDLEN - 1] = 0;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax local poll ID rx \"%s\"\n", f->pollid);
+				printk(KERN_DEBUG "isdn_tty: Fax local poll ID rx \"%s\"\n", f->pollid);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -613,29 +613,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "CQ", 2)) {
 		p[0] += 2;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->cq);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->cq);
+				sprintf(rs, "\r\n0,1,2");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0,1,2");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 2))
-						PARSE_ERROR1;
-					f->cq = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 2))
+					PARSE_ERROR1;
+				f->cq = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FCQ=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FCQ=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -643,29 +643,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "CR", 2)) {
 		p[0] += 2;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->cr);	/* read actual value from struct and print */
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->cr);	/* read actual value from struct and print */
+				sprintf(rs, "\r\n0,1");		/* display online help */
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0,1");		/* display online help */
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 1))
-						PARSE_ERROR1;
-					f->cr = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 1))
+					PARSE_ERROR1;
+				f->cr = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FCR=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FCR=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -673,29 +673,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "CTCRTY", 6)) {
 		p[0] += 6;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->ctcrty);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->ctcrty);
+				sprintf(rs, "\r\n0-255");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0-255");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 255))
-						PARSE_ERROR1;
-					f->ctcrty = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 255))
+					PARSE_ERROR1;
+				f->ctcrty = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FCTCRTY=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FCTCRTY=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -706,42 +706,42 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
-				p[0]++;
-				strcpy(rs, "\r\n");
-				for (i = 0; i < 8; i++) {
-					sprintf(rss, "%c%s", rp[i] + 48,
-						(i < 7) ? "," : "");
-					strcat(rs, rss);
-				}
-				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
+		case '?':
+			p[0]++;
+			strcpy(rs, "\r\n");
+			for (i = 0; i < 8; i++) {
+				sprintf(rss, "%c%s", rp[i] + 48,
+					(i < 7) ? "," : "");
+				strcat(rs, rss);
+			}
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
+				isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0-3),(0-2),(0),(0-7)", info);
 				p[0]++;
-				if (*p[0] == '?') {
-					isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0-3),(0-2),(0),(0-7)", info);
-					p[0]++;
-				} else {
-					for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 8); i++) {
-						if (*p[0] != ',') {
-							if ((*p[0] - 48) > maxdccval[i]) {
-								PARSE_ERROR1;
-							}
-							rp[i] = *p[0] - 48;
-							p[0]++;
-							if (*p[0] == ',')
-								p[0]++;
-						} else
+			} else {
+				for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 8); i++) {
+					if (*p[0] != ',') {
+						if ((*p[0] - 48) > maxdccval[i]) {
+							PARSE_ERROR1;
+						}
+						rp[i] = *p[0] - 48;
+						p[0]++;
+						if (*p[0] == ',')
 							p[0]++;
-					}
+					} else
+						p[0]++;
+				}
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FDCC capabilities DCE=%d,%d,%d,%d,%d,%d,%d,%d\n",
-					       rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7]);
+				printk(KERN_DEBUG "isdn_tty: Fax FDCC capabilities DCE=%d,%d,%d,%d,%d,%d,%d,%d\n",
+				       rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7]);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -752,42 +752,42 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
-				p[0]++;
-				strcpy(rs, "\r\n");
-				for (i = 0; i < 8; i++) {
-					sprintf(rss, "%c%s", rp[i] + 48,
-						(i < 7) ? "," : "");
-					strcat(rs, rss);
-				}
-				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
+		case '?':
+			p[0]++;
+			strcpy(rs, "\r\n");
+			for (i = 0; i < 8; i++) {
+				sprintf(rss, "%c%s", rp[i] + 48,
+					(i < 7) ? "," : "");
+				strcat(rs, rss);
+			}
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
+				isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0-3),(0-2),(0),(0-7)", info);
 				p[0]++;
-				if (*p[0] == '?') {
-					isdn_tty_at_cout("\r\n(0,1),(0-5),(0-2),(0-2),(0-3),(0-2),(0),(0-7)", info);
-					p[0]++;
-				} else {
-					for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 8); i++) {
-						if (*p[0] != ',') {
-							if ((*p[0] - 48) > maxdccval[i]) {
-								PARSE_ERROR1;
-							}
-							rp[i] = *p[0] - 48;
-							p[0]++;
-							if (*p[0] == ',')
-								p[0]++;
-						} else
+			} else {
+				for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 8); i++) {
+					if (*p[0] != ',') {
+						if ((*p[0] - 48) > maxdccval[i]) {
+							PARSE_ERROR1;
+						}
+						rp[i] = *p[0] - 48;
+						p[0]++;
+						if (*p[0] == ',')
 							p[0]++;
-					}
+					} else
+						p[0]++;
+				}
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FDIS session parms=%d,%d,%d,%d,%d,%d,%d,%d\n",
-					       rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7]);
+				printk(KERN_DEBUG "isdn_tty: Fax FDIS session parms=%d,%d,%d,%d,%d,%d,%d,%d\n",
+				       rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7]);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -808,18 +808,18 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 				f->phase = ISDN_FAX_PHASE_C;
 			} else if (f->phase == ISDN_FAX_PHASE_D) {
 				switch (f->fet) {
-					case 0:	/* next page will be received */
-						f->phase = ISDN_FAX_PHASE_C;
-						isdn_tty_fax_modem_result(7, info);	/* CONNECT */
-						break;
-					case 1:	/* next doc will be received */
-						f->phase = ISDN_FAX_PHASE_B;
-						break;
-					case 2:	/* fax session is terminating */
-						f->phase = ISDN_FAX_PHASE_E;
-						break;
-					default:
-						PARSE_ERROR1;
+				case 0:	/* next page will be received */
+					f->phase = ISDN_FAX_PHASE_C;
+					isdn_tty_fax_modem_result(7, info);	/* CONNECT */
+					break;
+				case 1:	/* next doc will be received */
+					f->phase = ISDN_FAX_PHASE_B;
+					break;
+				case 2:	/* fax session is terminating */
+					f->phase = ISDN_FAX_PHASE_E;
+					break;
+				default:
+					PARSE_ERROR1;
 				}
 			}
 		} else {
@@ -830,7 +830,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	/* DT=df,vr,wd,ln - TX phase C data command (release DCE to proceed with negotiation) */
 	if (!strncmp(p[0], "DT", 2)) {
 		int i, val[] =
-		{4, 0, 2, 3};
+			{4, 0, 2, 3};
 		char *rp = &f->resolution;
 
 		p[0] += 2;
@@ -872,29 +872,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "ECM", 3)) {
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->ecm);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->ecm);
+				sprintf(rs, "\r\n0,2");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0,2");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par != 0) && (par != 2))
-						PARSE_ERROR1;
-					f->ecm = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par != 0) && (par != 2))
+					PARSE_ERROR1;
+				f->ecm = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FECM=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FECM=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -938,36 +938,36 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 		int i, r;
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n\"%s\"", f->id);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n\"%s\"", f->id);
+				sprintf(rs, "\r\n\"STRING\"");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
+			} else {
+				if (*p[0] == '"')
 					p[0]++;
-					sprintf(rs, "\r\n\"STRING\"");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					if (*p[0] == '"')
-						p[0]++;
-					for (i = 0; (*p[0]) && i < (FAXIDLEN - 1) && (*p[0] != '"'); i++) {
-						f->id[i] = *p[0]++;
-					}
-					if (*p[0] == '"')
-						p[0]++;
-					for (r = i; r < FAXIDLEN; r++) {
-						f->id[r] = 32;
-					}
-					f->id[FAXIDLEN - 1] = 0;
+				for (i = 0; (*p[0]) && i < (FAXIDLEN - 1) && (*p[0] != '"'); i++) {
+					f->id[i] = *p[0]++;
+				}
+				if (*p[0] == '"')
+					p[0]++;
+				for (r = i; r < FAXIDLEN; r++) {
+					f->id[r] = 32;
+				}
+				f->id[FAXIDLEN - 1] = 0;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax local ID \"%s\"\n", f->id);
+				printk(KERN_DEBUG "isdn_tty: Fax local ID \"%s\"\n", f->id);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -994,29 +994,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "MINSP", 5)) {
 		p[0] += 5;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->minsp);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->minsp);
+				sprintf(rs, "\r\n0-5");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0-5");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 5))
-						PARSE_ERROR1;
-					f->minsp = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 5))
+					PARSE_ERROR1;
+				f->minsp = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FMINSP=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FMINSP=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -1024,29 +1024,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "PHCTO", 5)) {
 		p[0] += 5;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->phcto);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->phcto);
+				sprintf(rs, "\r\n0-255");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0-255");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 255))
-						PARSE_ERROR1;
-					f->phcto = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 255))
+					PARSE_ERROR1;
+				f->phcto = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FPHCTO=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FPHCTO=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -1055,29 +1055,29 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 	if (!strncmp(p[0], "REL", 3)) {
 		p[0] += 3;
 		switch (*p[0]) {
-			case '?':
+		case '?':
+			p[0]++;
+			sprintf(rs, "\r\n%d", f->rel);
+			isdn_tty_at_cout(rs, info);
+			break;
+		case '=':
+			p[0]++;
+			if (*p[0] == '?') {
 				p[0]++;
-				sprintf(rs, "\r\n%d", f->rel);
+				sprintf(rs, "\r\n0,1");
 				isdn_tty_at_cout(rs, info);
-				break;
-			case '=':
-				p[0]++;
-				if (*p[0] == '?') {
-					p[0]++;
-					sprintf(rs, "\r\n0,1");
-					isdn_tty_at_cout(rs, info);
-				} else {
-					par = isdn_getnum(p);
-					if ((par < 0) || (par > 1))
-						PARSE_ERROR1;
-					f->rel = par;
+			} else {
+				par = isdn_getnum(p);
+				if ((par < 0) || (par > 1))
+					PARSE_ERROR1;
+				f->rel = par;
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
-					printk(KERN_DEBUG "isdn_tty: Fax FREL=%d\n", par);
+				printk(KERN_DEBUG "isdn_tty: Fax FREL=%d\n", par);
 #endif
-				}
-				break;
-			default:
-				PARSE_ERROR1;
+			}
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -1100,11 +1100,11 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 		printk(KERN_DEBUG "isdn_tty: Fax FTBC=%c\n", *p[0]);
 #endif
 		switch (*p[0]) {
-			case '0':
-				p[0]++;
-				break;
-			default:
-				PARSE_ERROR1;
+		case '0':
+			p[0]++;
+			break;
+		default:
+			PARSE_ERROR1;
 		}
 		return 0;
 	}
@@ -1113,7 +1113,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 }
 
 int
-isdn_tty_cmd_PLUSF_FAX(char **p, modem_info * info)
+isdn_tty_cmd_PLUSF_FAX(char **p, modem_info *info)
 {
 	if (TTY_IS_FCLASS2(info))
 		return (isdn_tty_cmd_FCLASS2(p, info));
diff --git a/drivers/isdn/i4l/isdn_ttyfax.h b/drivers/isdn/i4l/isdn_ttyfax.h
index 757a890..ccda4fc 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.h
+++ b/drivers/isdn/i4l/isdn_ttyfax.h
@@ -15,4 +15,3 @@
 #define XON	0x11
 #define XOFF	0x13
 #define DC2	0x12
-
diff --git a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c
index c5d02b6..52827a8 100644
--- a/drivers/isdn/i4l/isdn_v110.c
+++ b/drivers/isdn/i4l/isdn_v110.c
@@ -26,8 +26,8 @@ char *isdn_v110_revision = "$Revision: 1.1.2.2 $";
 #define V110_19200  15
 #define V110_9600    3
 
-/* 
- * The following data are precoded matrices, online and offline matrix 
+/*
+ * The following data are precoded matrices, online and offline matrix
  * for 9600, 19200 und 38400, respectively
  */
 static unsigned char V110_OnMatrix_9600[] =
@@ -56,7 +56,7 @@ static unsigned char V110_OnMatrix_38400[] =
 static unsigned char V110_OffMatrix_38400[] =
 {0x00, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff};
 
-/* 
+/*
  * FlipBits reorders sequences of keylen bits in one byte.
  * E.g. source order 7654321 will be converted to 45670123 when keylen = 4,
  * and to 67452301 when keylen = 2. This is necessary because ordering on
@@ -103,18 +103,18 @@ isdn_v110_open(unsigned char key, int hdrlen, int maxsize)
 	v->decodelen = 0;
 
 	switch (key) {
-		case V110_38400:
-			v->OnlineFrame = V110_OnMatrix_38400;
-			v->OfflineFrame = V110_OffMatrix_38400;
-			break;
-		case V110_19200:
-			v->OnlineFrame = V110_OnMatrix_19200;
-			v->OfflineFrame = V110_OffMatrix_19200;
-			break;
-		default:
-			v->OnlineFrame = V110_OnMatrix_9600;
-			v->OfflineFrame = V110_OffMatrix_9600;
-			break;
+	case V110_38400:
+		v->OnlineFrame = V110_OnMatrix_38400;
+		v->OfflineFrame = V110_OffMatrix_38400;
+		break;
+	case V110_19200:
+		v->OnlineFrame = V110_OnMatrix_19200;
+		v->OfflineFrame = V110_OffMatrix_19200;
+		break;
+	default:
+		v->OnlineFrame = V110_OnMatrix_9600;
+		v->OfflineFrame = V110_OffMatrix_9600;
+		break;
 	}
 	v->framelen = v->nbytes * 10;
 	v->SyncInit = 5;
@@ -132,7 +132,7 @@ isdn_v110_open(unsigned char key, int hdrlen, int maxsize)
 
 /* isdn_v110_close frees private V.110 data structures */
 void
-isdn_v110_close(isdn_v110_stream * v)
+isdn_v110_close(isdn_v110_stream *v)
 {
 	if (v == NULL)
 		return;
@@ -144,11 +144,11 @@ isdn_v110_close(isdn_v110_stream * v)
 }
 
 
-/* 
- * ValidHeaderBytes return the number of valid bytes in v->decodebuf 
+/*
+ * ValidHeaderBytes return the number of valid bytes in v->decodebuf
  */
 static int
-ValidHeaderBytes(isdn_v110_stream * v)
+ValidHeaderBytes(isdn_v110_stream *v)
 {
 	int i;
 	for (i = 0; (i < v->decodelen) && (i < v->nbytes); i++)
@@ -157,11 +157,11 @@ ValidHeaderBytes(isdn_v110_stream * v)
 	return i;
 }
 
-/* 
- * SyncHeader moves the decodebuf ptr to the next valid header 
+/*
+ * SyncHeader moves the decodebuf ptr to the next valid header
  */
 static void
-SyncHeader(isdn_v110_stream * v)
+SyncHeader(isdn_v110_stream *v)
 {
 	unsigned char *rbuf = v->decodebuf;
 	int len = v->decodelen;
@@ -185,9 +185,9 @@ SyncHeader(isdn_v110_stream * v)
    only complete matices must be given.
    From these, netto data is extracted and returned in buf. The return-value
    is the bytecount of the decoded data.
- */
+*/
 static int
-DecodeMatrix(isdn_v110_stream * v, unsigned char *m, int len, unsigned char *buf)
+DecodeMatrix(isdn_v110_stream *v, unsigned char *m, int len, unsigned char *buf)
 {
 	int line = 0;
 	int buflen = 0;
@@ -203,7 +203,7 @@ DecodeMatrix(isdn_v110_stream * v, unsigned char *m, int len, unsigned char *buf
 				printk(KERN_DEBUG "isdn_v110: DecodeMatrix, V110 Bad Header\n");
 				/* returning now is not the right thing, though :-( */
 #endif
-			} 
+			}
 			line++; /* next line of matrix */
 			continue;
 		} else if ((line % 10) == 5) {	/* in line 5 there's only e-bits ! */
@@ -217,7 +217,7 @@ DecodeMatrix(isdn_v110_stream * v, unsigned char *m, int len, unsigned char *buf
 			continue;
 		} else if (!introducer) {	/* every byte starts with 10 (stopbit, startbit) */
 			introducer = (m[line] & mbit) ? 0 : 1;	/* current bit of the matrix */
-		      next_byte:
+		next_byte:
 			if (mbit > 2) {	/* was it the last bit in this line ? */
 				mbit >>= 1;	/* no -> take next */
 				continue;
@@ -246,13 +246,13 @@ DecodeMatrix(isdn_v110_stream * v, unsigned char *m, int len, unsigned char *buf
 	return buflen;          /* return number of bytes in the output buffer */
 }
 
-/* 
- * DecodeStream receives V.110 coded data from the input stream. It recovers the 
+/*
+ * DecodeStream receives V.110 coded data from the input stream. It recovers the
  * original frames.
  * The input stream doesn't need to be framed
  */
 struct sk_buff *
-isdn_v110_decode(isdn_v110_stream * v, struct sk_buff *skb)
+isdn_v110_decode(isdn_v110_stream *v, struct sk_buff *skb)
 {
 	int i;
 	int j;
@@ -283,7 +283,7 @@ isdn_v110_decode(isdn_v110_stream * v, struct sk_buff *skb)
 	/* copy new data to decode-buffer */
 	memcpy(&(v->decodebuf[v->decodelen]), rbuf, len);
 	v->decodelen += len;
-      ReSync:
+ReSync:
 	if (v->decodelen < v->nbytes) {	/* got a new header ? */
 		dev_kfree_skb(skb);
 		return NULL;    /* no, try later      */
@@ -320,7 +320,7 @@ isdn_v110_decode(isdn_v110_stream * v, struct sk_buff *skb)
 /* EncodeMatrix takes input data in buf, len is the bytecount.
    Data is encoded into v110 frames in m. Return value is the number of
    matrix-lines generated.
- */
+*/
 static int
 EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
 {
@@ -333,14 +333,14 @@ EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
 
 	while ((i < len) && (line < mlen)) {	/* while we still have input data */
 		switch (line % 10) {	/* in which line of the matrix are we? */
-			case 0:
-				m[line++] = 0x00;	/* line 0 is always 0 */
-				mbit = 128;	/* go on with the 7th bit */
-				break;
-			case 5:
-				m[line++] = 0xbf;	/* line 5 is always 10111111 */
-				mbit = 128;	/* go on with the 7th bit */
-				break;
+		case 0:
+			m[line++] = 0x00;	/* line 0 is always 0 */
+			mbit = 128;	/* go on with the 7th bit */
+			break;
+		case 5:
+			m[line++] = 0xbf;	/* line 5 is always 10111111 */
+			mbit = 128;	/* go on with the 7th bit */
+			break;
 		}
 		if (line >= mlen) {
 			printk(KERN_WARNING "isdn_v110 (EncodeMatrix): buffer full!\n");
@@ -348,16 +348,16 @@ EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
 		}
 	next_bit:
 		switch (mbit) { /* leftmost or rightmost bit ? */
-			case 1:
-				line++;	/* rightmost -> go to next line */
-				if (line >= mlen) {
-					printk(KERN_WARNING "isdn_v110 (EncodeMatrix): buffer full!\n");
-					return line;
-				}
-			case 128:
-				m[line] = 128;	/* leftmost -> set byte to 1000000 */
-				mbit = 64;	/* current bit in the matrix line */
-				continue;
+		case 1:
+			line++;	/* rightmost -> go to next line */
+			if (line >= mlen) {
+				printk(KERN_WARNING "isdn_v110 (EncodeMatrix): buffer full!\n");
+				return line;
+			}
+		case 128:
+			m[line] = 128;	/* leftmost -> set byte to 1000000 */
+			mbit = 64;	/* current bit in the matrix line */
+			continue;
 		}
 		if (introducer) {	/* set 110 sequence ? */
 			introducer--;	/* set on digit less */
@@ -384,24 +384,24 @@ EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
 	/* if necessary, generate remaining lines of the matrix... */
 	if ((line) && ((line + 10) < mlen))
 		switch (++line % 10) {
-			case 1:
-				m[line++] = 0xfe;
-			case 2:
-				m[line++] = 0xfe;
-			case 3:
-				m[line++] = 0xfe;
-			case 4:
-				m[line++] = 0xfe;
-			case 5:
-				m[line++] = 0xbf;
-			case 6:
-				m[line++] = 0xfe;
-			case 7:
-				m[line++] = 0xfe;
-			case 8:
-				m[line++] = 0xfe;
-			case 9:
-				m[line++] = 0xfe;
+		case 1:
+			m[line++] = 0xfe;
+		case 2:
+			m[line++] = 0xfe;
+		case 3:
+			m[line++] = 0xfe;
+		case 4:
+			m[line++] = 0xfe;
+		case 5:
+			m[line++] = 0xbf;
+		case 6:
+			m[line++] = 0xfe;
+		case 7:
+			m[line++] = 0xfe;
+		case 8:
+			m[line++] = 0xfe;
+		case 9:
+			m[line++] = 0xfe;
 		}
 	return line;            /* that's how many lines we have */
 }
@@ -447,7 +447,7 @@ isdn_v110_idle(isdn_v110_stream *v)
 }
 
 struct sk_buff *
-isdn_v110_encode(isdn_v110_stream * v, struct sk_buff *skb)
+isdn_v110_encode(isdn_v110_stream *v, struct sk_buff *skb)
 {
 	int i;
 	int j;
@@ -524,93 +524,93 @@ isdn_v110_stat_callback(int idx, isdn_ctrl *c)
 	if (idx < 0)
 		return 0;
 	switch (c->command) {
-		case ISDN_STAT_BSENT:
-                        /* Keep the send-queue of the driver filled
-			 * with frames:
-			 * If number of outstanding frames < 3,
-			 * send down an Idle-Frame (or an Sync-Frame, if
-			 * v->SyncInit != 0). 
-			 */
-			if (!(v = dev->v110[idx]))
-				return 0;
-			atomic_inc(&dev->v110use[idx]);
-			for (i=0; i * v->framelen < c->parm.length; i++) {
-				if (v->skbidle > 0) {
-					v->skbidle--;
-					ret = 1;
+	case ISDN_STAT_BSENT:
+		/* Keep the send-queue of the driver filled
+		 * with frames:
+		 * If number of outstanding frames < 3,
+		 * send down an Idle-Frame (or an Sync-Frame, if
+		 * v->SyncInit != 0).
+		 */
+		if (!(v = dev->v110[idx]))
+			return 0;
+		atomic_inc(&dev->v110use[idx]);
+		for (i = 0; i * v->framelen < c->parm.length; i++) {
+			if (v->skbidle > 0) {
+				v->skbidle--;
+				ret = 1;
+			} else {
+				if (v->skbuser > 0)
+					v->skbuser--;
+				ret = 0;
+			}
+		}
+		for (i = v->skbuser + v->skbidle; i < 2; i++) {
+			struct sk_buff *skb;
+			if (v->SyncInit > 0)
+				skb = isdn_v110_sync(v);
+			else
+				skb = isdn_v110_idle(v);
+			if (skb) {
+				if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {
+					dev_kfree_skb(skb);
+					break;
 				} else {
-					if (v->skbuser > 0)
-						v->skbuser--;
-					ret = 0;
+					if (v->SyncInit)
+						v->SyncInit--;
+					v->skbidle++;
 				}
+			} else
+				break;
+		}
+		atomic_dec(&dev->v110use[idx]);
+		return ret;
+	case ISDN_STAT_DHUP:
+	case ISDN_STAT_BHUP:
+		while (1) {
+			atomic_inc(&dev->v110use[idx]);
+			if (atomic_dec_and_test(&dev->v110use[idx])) {
+				isdn_v110_close(dev->v110[idx]);
+				dev->v110[idx] = NULL;
+				break;
+			}
+			mdelay(1);
+		}
+		break;
+	case ISDN_STAT_BCONN:
+		if (dev->v110emu[idx] && (dev->v110[idx] == NULL)) {
+			int hdrlen = dev->drv[c->driver]->interface->hl_hdrlen;
+			int maxsize = dev->drv[c->driver]->interface->maxbufsize;
+			atomic_inc(&dev->v110use[idx]);
+			switch (dev->v110emu[idx]) {
+			case ISDN_PROTO_L2_V11096:
+				dev->v110[idx] = isdn_v110_open(V110_9600, hdrlen, maxsize);
+				break;
+			case ISDN_PROTO_L2_V11019:
+				dev->v110[idx] = isdn_v110_open(V110_19200, hdrlen, maxsize);
+				break;
+			case ISDN_PROTO_L2_V11038:
+				dev->v110[idx] = isdn_v110_open(V110_38400, hdrlen, maxsize);
+				break;
+			default:;
 			}
-			for (i = v->skbuser + v->skbidle; i < 2; i++) {
-				struct sk_buff *skb;
-				if (v->SyncInit > 0)
-					skb = isdn_v110_sync(v);
-				else
-					skb = isdn_v110_idle(v);
-				if (skb) {
+			if ((v = dev->v110[idx])) {
+				while (v->SyncInit) {
+					struct sk_buff *skb = isdn_v110_sync(v);
 					if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {
 						dev_kfree_skb(skb);
+						/* Unable to send, try later */
 						break;
-					} else {
-						if (v->SyncInit)
-							v->SyncInit--;
-						v->skbidle++;
 					}
-				} else
-					break;
-			}
-			atomic_dec(&dev->v110use[idx]);
-			return ret;
-		case ISDN_STAT_DHUP:
-		case ISDN_STAT_BHUP:
-			while (1) {
-				atomic_inc(&dev->v110use[idx]);
-				if (atomic_dec_and_test(&dev->v110use[idx])) {
-					isdn_v110_close(dev->v110[idx]);
-					dev->v110[idx] = NULL;
-					break;
+					v->SyncInit--;
+					v->skbidle++;
 				}
-				mdelay(1);
-			}
-			break;
-		case ISDN_STAT_BCONN:
-			if (dev->v110emu[idx] && (dev->v110[idx] == NULL)) {
-				int hdrlen = dev->drv[c->driver]->interface->hl_hdrlen;
-				int maxsize = dev->drv[c->driver]->interface->maxbufsize;
-				atomic_inc(&dev->v110use[idx]);
-				switch (dev->v110emu[idx]) {
-					case ISDN_PROTO_L2_V11096:
-						dev->v110[idx] = isdn_v110_open(V110_9600, hdrlen, maxsize);
-						break;
-					case ISDN_PROTO_L2_V11019:
-						dev->v110[idx] = isdn_v110_open(V110_19200, hdrlen, maxsize);
-						break;
-					case ISDN_PROTO_L2_V11038:
-						dev->v110[idx] = isdn_v110_open(V110_38400, hdrlen, maxsize);
-						break;
-					default:;
-				}
-				if ((v = dev->v110[idx])) {
-					while (v->SyncInit) {
-						struct sk_buff *skb = isdn_v110_sync(v);
-						if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {
-							dev_kfree_skb(skb);
-							/* Unable to send, try later */
-							break;
-						}
-						v->SyncInit--;
-						v->skbidle++;
-					}
-				} else
-					printk(KERN_WARNING "isdn_v110: Couldn't open stream for chan %d\n", idx);
-				atomic_dec(&dev->v110use[idx]);
-			}
-			break;
-		default:
-			return 0;
+			} else
+				printk(KERN_WARNING "isdn_v110: Couldn't open stream for chan %d\n", idx);
+			atomic_dec(&dev->v110use[idx]);
+		}
+		break;
+	default:
+		return 0;
 	}
 	return 0;
 }
diff --git a/drivers/isdn/i4l/isdn_v110.h b/drivers/isdn/i4l/isdn_v110.h
index 08f274b..de774ab 100644
--- a/drivers/isdn/i4l/isdn_v110.h
+++ b/drivers/isdn/i4l/isdn_v110.h
@@ -12,18 +12,18 @@
 #ifndef _isdn_v110_h_
 #define _isdn_v110_h_
 
-/* 
- * isdn_v110_encode will take raw data and encode it using V.110 
+/*
+ * isdn_v110_encode will take raw data and encode it using V.110
  */
 extern struct sk_buff *isdn_v110_encode(isdn_v110_stream *, struct sk_buff *);
 
-/* 
+/*
  * isdn_v110_decode receives V.110 coded data from the stream and rebuilds
  * frames from them. The source stream doesn't need to be framed.
  */
 extern struct sk_buff *isdn_v110_decode(isdn_v110_stream *, struct sk_buff *);
 
 extern int isdn_v110_stat_callback(int, isdn_ctrl *);
-extern void isdn_v110_close(isdn_v110_stream * v);
+extern void isdn_v110_close(isdn_v110_stream *v);
 
 #endif
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
index fd10d7c..e2d4e58 100644
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -26,7 +26,7 @@
 #include "isdn_x25iface.h"
 
 /* for debugging messages not to cause an oops when device pointer is NULL*/
-#define MY_DEVNAME(dev)  ( (dev) ? (dev)->name : "DEVICE UNSPECIFIED" )
+#define MY_DEVNAME(dev)  ((dev) ? (dev)->name : "DEVICE UNSPECIFIED")
 
 
 typedef struct isdn_x25iface_proto_data {
@@ -34,22 +34,22 @@ typedef struct isdn_x25iface_proto_data {
 	enum wan_states state;
 	/* Private stuff, not to be accessed via proto_data. We provide the
 	   other storage for the concap_proto instance here as well,
-	   enabling us to allocate both with just one kmalloc(): */ 
+	   enabling us to allocate both with just one kmalloc(): */
 	struct concap_proto priv;
 } ix25_pdata_t;
 
 
 
 /* is now in header file (extern): struct concap_proto * isdn_x25iface_proto_new(void); */
-static void isdn_x25iface_proto_del( struct concap_proto * );
-static int isdn_x25iface_proto_close( struct concap_proto * );
-static int isdn_x25iface_proto_restart( struct concap_proto *,
-					struct net_device *,
-					struct concap_device_ops *);
-static int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
-static int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
-static int isdn_x25iface_connect_ind( struct concap_proto * );
-static int isdn_x25iface_disconn_ind( struct concap_proto * );
+static void isdn_x25iface_proto_del(struct concap_proto *);
+static int isdn_x25iface_proto_close(struct concap_proto *);
+static int isdn_x25iface_proto_restart(struct concap_proto *,
+				       struct net_device *,
+				       struct concap_device_ops *);
+static int isdn_x25iface_xmit(struct concap_proto *, struct sk_buff *);
+static int isdn_x25iface_receive(struct concap_proto *, struct sk_buff *);
+static int isdn_x25iface_connect_ind(struct concap_proto *);
+static int isdn_x25iface_disconn_ind(struct concap_proto *);
 
 
 static struct concap_proto_ops ix25_pops = {
@@ -64,65 +64,65 @@ static struct concap_proto_ops ix25_pops = {
 };
 
 /* error message helper function */
-static void illegal_state_warn( unsigned state, unsigned char firstbyte) 
+static void illegal_state_warn(unsigned state, unsigned char firstbyte)
 {
-	printk( KERN_WARNING "isdn_x25iface: firstbyte %x illegal in"
-		"current state %d\n",firstbyte, state );
+	printk(KERN_WARNING "isdn_x25iface: firstbyte %x illegal in"
+	       "current state %d\n", firstbyte, state);
 }
 
 /* check protocol data field for consistency */
-static int pdata_is_bad( ix25_pdata_t * pda ){
+static int pdata_is_bad(ix25_pdata_t *pda) {
 
-	if( pda  &&  pda -> magic == ISDN_X25IFACE_MAGIC ) return 0;
-	printk( KERN_WARNING
-		"isdn_x25iface_xxx: illegal pointer to proto data\n" );
+	if (pda  &&  pda->magic == ISDN_X25IFACE_MAGIC) return 0;
+	printk(KERN_WARNING
+	       "isdn_x25iface_xxx: illegal pointer to proto data\n");
 	return 1;
 }
 
 /* create a new x25 interface protocol instance
  */
-struct concap_proto * isdn_x25iface_proto_new(void)
+struct concap_proto *isdn_x25iface_proto_new(void)
 {
-	ix25_pdata_t * tmp = kmalloc(sizeof(ix25_pdata_t),GFP_KERNEL);
+	ix25_pdata_t *tmp = kmalloc(sizeof(ix25_pdata_t), GFP_KERNEL);
 	IX25DEBUG("isdn_x25iface_proto_new\n");
-	if( tmp ){
-		tmp -> magic = ISDN_X25IFACE_MAGIC;
-		tmp -> state = WAN_UNCONFIGURED;
+	if (tmp) {
+		tmp->magic = ISDN_X25IFACE_MAGIC;
+		tmp->state = WAN_UNCONFIGURED;
 		/* private data space used to hold the concap_proto data.
 		   Only to be accessed via the returned pointer */
 		spin_lock_init(&tmp->priv.lock);
-		tmp -> priv.dops       = NULL;
-		tmp -> priv.net_dev    = NULL;
-		tmp -> priv.pops       = &ix25_pops;
-		tmp -> priv.flags      = 0;
-		tmp -> priv.proto_data = tmp;
-		return( &(tmp -> priv) );
+		tmp->priv.dops       = NULL;
+		tmp->priv.net_dev    = NULL;
+		tmp->priv.pops       = &ix25_pops;
+		tmp->priv.flags      = 0;
+		tmp->priv.proto_data = tmp;
+		return (&(tmp->priv));
 	}
 	return NULL;
 };
 
-/* close the x25iface encapsulation protocol 
+/* close the x25iface encapsulation protocol
  */
-static int isdn_x25iface_proto_close(struct concap_proto *cprot){
+static int isdn_x25iface_proto_close(struct concap_proto *cprot) {
 
 	ix25_pdata_t *tmp;
-        int ret = 0;
+	int ret = 0;
 	ulong flags;
 
-	if( ! cprot ){
-		printk( KERN_ERR "isdn_x25iface_proto_close: "
-			"invalid concap_proto pointer\n" );
+	if (!cprot) {
+		printk(KERN_ERR "isdn_x25iface_proto_close: "
+		       "invalid concap_proto pointer\n");
 		return -1;
 	}
-	IX25DEBUG( "isdn_x25iface_proto_close %s \n", MY_DEVNAME(cprot -> net_dev) );
+	IX25DEBUG("isdn_x25iface_proto_close %s \n", MY_DEVNAME(cprot->net_dev));
 	spin_lock_irqsave(&cprot->lock, flags);
-	cprot -> dops    = NULL;
-	cprot -> net_dev = NULL;
-	tmp = cprot -> proto_data;
-	if( pdata_is_bad( tmp ) ){
+	cprot->dops    = NULL;
+	cprot->net_dev = NULL;
+	tmp = cprot->proto_data;
+	if (pdata_is_bad(tmp)) {
 		ret = -1;
 	} else {
-		tmp -> state = WAN_UNCONFIGURED;
+		tmp->state = WAN_UNCONFIGURED;
 	}
 	spin_unlock_irqrestore(&cprot->lock, flags);
 	return ret;
@@ -130,100 +130,100 @@ static int isdn_x25iface_proto_close(struct concap_proto *cprot){
 
 /* Delete the x25iface encapsulation protocol instance
  */
-static void isdn_x25iface_proto_del(struct concap_proto *cprot){
+static void isdn_x25iface_proto_del(struct concap_proto *cprot) {
+
+	ix25_pdata_t *tmp;
 
-	ix25_pdata_t * tmp;
- 
-	IX25DEBUG( "isdn_x25iface_proto_del \n" );
-	if( ! cprot ){
-		printk( KERN_ERR "isdn_x25iface_proto_del: "
-			"concap_proto pointer is NULL\n" );
+	IX25DEBUG("isdn_x25iface_proto_del \n");
+	if (!cprot) {
+		printk(KERN_ERR "isdn_x25iface_proto_del: "
+		       "concap_proto pointer is NULL\n");
 		return;
 	}
-	tmp = cprot -> proto_data;
-	if( tmp == NULL ){ 
-		printk( KERN_ERR "isdn_x25iface_proto_del: inconsistent "
-			"proto_data pointer (maybe already deleted?)\n"); 
+	tmp = cprot->proto_data;
+	if (tmp == NULL) {
+		printk(KERN_ERR "isdn_x25iface_proto_del: inconsistent "
+		       "proto_data pointer (maybe already deleted?)\n");
 		return;
 	}
 	/* close if the protocol is still open */
-	if( cprot -> dops ) isdn_x25iface_proto_close(cprot);
+	if (cprot->dops) isdn_x25iface_proto_close(cprot);
 	/* freeing the storage should be sufficient now. But some additional
 	   settings might help to catch wild pointer bugs */
-	tmp -> magic = 0;
-	cprot -> proto_data = NULL;
+	tmp->magic = 0;
+	cprot->proto_data = NULL;
 
-	kfree( tmp );
+	kfree(tmp);
 	return;
 }
 
 /* (re-)initialize the data structures for x25iface encapsulation
  */
 static int isdn_x25iface_proto_restart(struct concap_proto *cprot,
-					struct net_device *ndev,
-					struct concap_device_ops *dops)
+				       struct net_device *ndev,
+				       struct concap_device_ops *dops)
 {
-	ix25_pdata_t * pda = cprot -> proto_data ;
+	ix25_pdata_t *pda = cprot->proto_data;
 	ulong flags;
 
-	IX25DEBUG( "isdn_x25iface_proto_restart %s \n", MY_DEVNAME(ndev) );
+	IX25DEBUG("isdn_x25iface_proto_restart %s \n", MY_DEVNAME(ndev));
 
-	if ( pdata_is_bad( pda ) ) return -1;
+	if (pdata_is_bad(pda)) return -1;
 
-	if( !( dops  && dops -> data_req && dops -> connect_req 
-	       && dops -> disconn_req )  ){
-		printk( KERN_WARNING "isdn_x25iface_restart: required dops"
-			" missing\n" );
+	if (!(dops && dops->data_req && dops->connect_req
+	      && dops->disconn_req)) {
+		printk(KERN_WARNING "isdn_x25iface_restart: required dops"
+		       " missing\n");
 		isdn_x25iface_proto_close(cprot);
 		return -1;
 	}
 	spin_lock_irqsave(&cprot->lock, flags);
-	cprot -> net_dev = ndev;
-	cprot -> pops = &ix25_pops;
-	cprot -> dops = dops;
-	pda -> state = WAN_DISCONNECTED;
+	cprot->net_dev = ndev;
+	cprot->pops = &ix25_pops;
+	cprot->dops = dops;
+	pda->state = WAN_DISCONNECTED;
 	spin_unlock_irqrestore(&cprot->lock, flags);
 	return 0;
 }
 
-/* deliver a dl_data frame received from i4l HL driver to the network layer 
+/* deliver a dl_data frame received from i4l HL driver to the network layer
  */
 static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
 {
-  	IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) );
-	if ( ( (ix25_pdata_t*) (cprot->proto_data) ) 
-	     -> state == WAN_CONNECTED ){
-		if( skb_push(skb, 1)){
+	IX25DEBUG("isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev));
+	if (((ix25_pdata_t *)(cprot->proto_data))
+	    ->state == WAN_CONNECTED) {
+		if (skb_push(skb, 1)) {
 			skb->data[0] = X25_IFACE_DATA;
 			skb->protocol = x25_type_trans(skb, cprot->net_dev);
 			netif_rx(skb);
 			return 0;
 		}
 	}
-	printk(KERN_WARNING "isdn_x25iface_receive %s: not connected, skb dropped\n", MY_DEVNAME(cprot->net_dev) );
+	printk(KERN_WARNING "isdn_x25iface_receive %s: not connected, skb dropped\n", MY_DEVNAME(cprot->net_dev));
 	dev_kfree_skb(skb);
 	return -1;
 }
 
-/* a connection set up is indicated by lower layer 
+/* a connection set up is indicated by lower layer
  */
 static int isdn_x25iface_connect_ind(struct concap_proto *cprot)
 {
-	struct sk_buff * skb;
-	enum wan_states *state_p 
-	  = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state);
-	IX25DEBUG( "isdn_x25iface_connect_ind %s \n"
-		   , MY_DEVNAME(cprot->net_dev) );
-	if( *state_p == WAN_UNCONFIGURED ){ 
-		printk(KERN_WARNING 
+	struct sk_buff *skb;
+	enum wan_states *state_p
+		= &(((ix25_pdata_t *)(cprot->proto_data))->state);
+	IX25DEBUG("isdn_x25iface_connect_ind %s \n"
+		  , MY_DEVNAME(cprot->net_dev));
+	if (*state_p == WAN_UNCONFIGURED) {
+		printk(KERN_WARNING
 		       "isdn_x25iface_connect_ind while unconfigured %s\n"
-		       , MY_DEVNAME(cprot->net_dev) );
+		       , MY_DEVNAME(cprot->net_dev));
 		return -1;
 	}
 	*state_p = WAN_CONNECTED;
 
 	skb = dev_alloc_skb(1);
-	if( skb ){
+	if (skb) {
 		*(skb_put(skb, 1)) = X25_IFACE_CONNECT;
 		skb->protocol = x25_type_trans(skb, cprot->net_dev);
 		netif_rx(skb);
@@ -231,28 +231,28 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot)
 	} else {
 		printk(KERN_WARNING "isdn_x25iface_connect_ind: "
 		       " out of memory -- disconnecting\n");
-		cprot -> dops -> disconn_req(cprot);
+		cprot->dops->disconn_req(cprot);
 		return -1;
 	}
 }
-	
-/* a disconnect is indicated by lower layer 
+
+/* a disconnect is indicated by lower layer
  */
 static int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
 {
 	struct sk_buff *skb;
-	enum wan_states *state_p 
-	  = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state);
-	IX25DEBUG( "isdn_x25iface_disconn_ind %s \n", MY_DEVNAME(cprot -> net_dev) );
-	if( *state_p == WAN_UNCONFIGURED ){ 
-		printk(KERN_WARNING 
+	enum wan_states *state_p
+		= &(((ix25_pdata_t *)(cprot->proto_data))->state);
+	IX25DEBUG("isdn_x25iface_disconn_ind %s \n", MY_DEVNAME(cprot->net_dev));
+	if (*state_p == WAN_UNCONFIGURED) {
+		printk(KERN_WARNING
 		       "isdn_x25iface_disconn_ind while unconfigured\n");
 		return -1;
 	}
-	if(! cprot -> net_dev) return -1;
+	if (!cprot->net_dev) return -1;
 	*state_p = WAN_DISCONNECTED;
 	skb = dev_alloc_skb(1);
-	if( skb ){
+	if (skb) {
 		*(skb_put(skb, 1)) = X25_IFACE_DISCONNECT;
 		skb->protocol = x25_type_trans(skb, cprot->net_dev);
 		netif_rx(skb);
@@ -266,57 +266,57 @@ static int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
 
 /* process a frame handed over to us from linux network layer. First byte
    semantics as defined in Documentation/networking/x25-iface.txt
-   */
+*/
 static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 {
 	unsigned char firstbyte = skb->data[0];
-	enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state;
+	enum wan_states *state = &((ix25_pdata_t *)cprot->proto_data)->state;
 	int ret = 0;
 	IX25DEBUG("isdn_x25iface_xmit: %s first=%x state=%d\n",
-		MY_DEVNAME(cprot->net_dev), firstbyte, *state);
-	switch ( firstbyte ){
+		  MY_DEVNAME(cprot->net_dev), firstbyte, *state);
+	switch (firstbyte) {
 	case X25_IFACE_DATA:
-		if( *state == WAN_CONNECTED ){
+		if (*state == WAN_CONNECTED) {
 			skb_pull(skb, 1);
-			cprot -> net_dev -> trans_start = jiffies;
-			ret = ( cprot -> dops -> data_req(cprot, skb) );
+			cprot->net_dev->trans_start = jiffies;
+			ret = (cprot->dops->data_req(cprot, skb));
 			/* prepare for future retransmissions */
-			if( ret ) skb_push(skb,1);
+			if (ret) skb_push(skb, 1);
 			return ret;
 		}
-		illegal_state_warn( *state, firstbyte ); 
+		illegal_state_warn(*state, firstbyte);
 		break;
 	case X25_IFACE_CONNECT:
-		if( *state == WAN_DISCONNECTED ){
+		if (*state == WAN_DISCONNECTED) {
 			*state = WAN_CONNECTING;
-		        ret = cprot -> dops -> connect_req(cprot);
-			if(ret){
+			ret = cprot->dops->connect_req(cprot);
+			if (ret) {
 				/* reset state and notify upper layer about
 				 * immidiatly failed attempts */
 				isdn_x25iface_disconn_ind(cprot);
 			}
 		} else {
-			illegal_state_warn( *state, firstbyte );
+			illegal_state_warn(*state, firstbyte);
 		}
 		break;
 	case X25_IFACE_DISCONNECT:
-		switch ( *state ){
-		case WAN_DISCONNECTED: 
+		switch (*state) {
+		case WAN_DISCONNECTED:
 			/* Should not happen. However, give upper layer a
 			   chance to recover from inconstistency  but don't
 			   trust the lower layer sending the disconn_confirm
 			   when already disconnected */
 			printk(KERN_WARNING "isdn_x25iface_xmit: disconnect "
-			       " requested while disconnected\n" );
+			       " requested while disconnected\n");
 			isdn_x25iface_disconn_ind(cprot);
 			break; /* prevent infinite loops */
 		case WAN_CONNECTING:
 		case WAN_CONNECTED:
 			*state = WAN_DISCONNECTED;
-			cprot -> dops -> disconn_req(cprot);
+			cprot->dops->disconn_req(cprot);
 			break;
 		default:
-			illegal_state_warn( *state, firstbyte );
+			illegal_state_warn(*state, firstbyte);
 		}
 		break;
 	case X25_IFACE_PARAMS:
diff --git a/drivers/isdn/i4l/isdn_x25iface.h b/drivers/isdn/i4l/isdn_x25iface.h
index 41a3d49..0b26e3b 100644
--- a/drivers/isdn/i4l/isdn_x25iface.h
+++ b/drivers/isdn/i4l/isdn_x25iface.h
@@ -13,9 +13,9 @@
 #define ISDN_X25IFACE_MAGIC 0x1e75a2b9
 /* #define DEBUG_ISDN_X25 if you want isdn_x25 debugging messages */
 #ifdef DEBUG_ISDN_X25
-#   define IX25DEBUG(fmt,args...) printk(KERN_DEBUG fmt , ## args)
+#   define IX25DEBUG(fmt, args...) printk(KERN_DEBUG fmt, ##args)
 #else
-#   define IX25DEBUG(fmt,args...)
+#   define IX25DEBUG(fmt, args...)
 #endif
 
 #include <linux/skbuff.h>
@@ -23,17 +23,9 @@
 #include <linux/isdn.h>
 #include <linux/concap.h>
 
-extern struct concap_proto_ops * isdn_x25iface_concap_proto_ops_pt;
-extern struct concap_proto     * isdn_x25iface_proto_new(void);
+extern struct concap_proto_ops *isdn_x25iface_concap_proto_ops_pt;
+extern struct concap_proto *isdn_x25iface_proto_new(void);
 
 
 
 #endif
-
-
-
-
-
-
-
-
diff --git a/drivers/isdn/i4l/isdnhdlc.c b/drivers/isdn/i4l/isdnhdlc.c
index c989aa3..027d1c5 100644
--- a/drivers/isdn/i4l/isdnhdlc.c
+++ b/drivers/isdn/i4l/isdnhdlc.c
@@ -88,7 +88,7 @@ check_frame(struct isdnhdlc_vars *hdlc)
 {
 	int status;
 
-	if (hdlc->dstpos < 2) 	/* too small - framing error */
+	if (hdlc->dstpos < 2)	/* too small - framing error */
 		status = -HDLC_FRAMING_ERROR;
 	else if (hdlc->crc != 0xf0b8)	/* crc error */
 		status = -HDLC_CRC_ERROR;
@@ -127,9 +127,9 @@ check_frame(struct isdnhdlc_vars *hdlc)
   dsize - destination buffer size
   returns - number of decoded bytes in the destination buffer and status
   flag.
- */
+*/
 int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
-	int *count, u8 *dst, int dsize)
+		    int *count, u8 *dst, int dsize)
 {
 	int status = 0;
 
@@ -145,28 +145,28 @@ int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
 		0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
 	};
 
-#define handle_fast_flag(h) \
-	do {\
-		if (h->cbin == fast_flag[h->bit_shift]) {\
-			h->ffvalue = fast_flag_value[h->bit_shift];\
-			h->state = HDLC_FAST_FLAG;\
-			h->ffbit_shift = h->bit_shift;\
-			h->bit_shift = 1;\
-		} else {\
-			h->state = HDLC_GET_DATA;\
-			h->data_received = 0;\
-		} \
+#define handle_fast_flag(h)						\
+	do {								\
+		if (h->cbin == fast_flag[h->bit_shift]) {		\
+			h->ffvalue = fast_flag_value[h->bit_shift];	\
+			h->state = HDLC_FAST_FLAG;			\
+			h->ffbit_shift = h->bit_shift;			\
+			h->bit_shift = 1;				\
+		} else {						\
+			h->state = HDLC_GET_DATA;			\
+			h->data_received = 0;				\
+		}							\
 	} while (0)
 
-#define handle_abort(h) \
-	do {\
-		h->shift_reg = fast_abort[h->ffbit_shift - 1];\
-		h->hdlc_bits1 = h->ffbit_shift - 2;\
-		if (h->hdlc_bits1 < 0)\
-			h->hdlc_bits1 = 0;\
-		h->data_bits = h->ffbit_shift - 1;\
-		h->state = HDLC_GET_DATA;\
-		h->data_received = 0;\
+#define handle_abort(h)						\
+	do {							\
+		h->shift_reg = fast_abort[h->ffbit_shift - 1];	\
+		h->hdlc_bits1 = h->ffbit_shift - 2;		\
+		if (h->hdlc_bits1 < 0)				\
+			h->hdlc_bits1 = 0;			\
+		h->data_bits = h->ffbit_shift - 1;		\
+		h->state = HDLC_GET_DATA;			\
+		h->data_received = 0;				\
 	} while (0)
 
 	*count = slen;
@@ -204,7 +204,7 @@ int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
 				if ((!hdlc->do_adapt56) &&
 				    (++hdlc->hdlc_bits1 >= 8) &&
 				    (hdlc->bit_shift == 1))
-						hdlc->state = HDLC_FAST_IDLE;
+					hdlc->state = HDLC_FAST_IDLE;
 			}
 			hdlc->cbin <<= 1;
 			hdlc->bit_shift--;
@@ -295,7 +295,7 @@ int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
 				hdlc->data_bits = 0;
 				hdlc->data_received = 1;
 				hdlc->crc = crc_ccitt_byte(hdlc->crc,
-						hdlc->shift_reg);
+							   hdlc->shift_reg);
 
 				/* good byte received */
 				if (hdlc->dstpos < dsize)
@@ -352,7 +352,7 @@ EXPORT_SYMBOL(isdnhdlc_decode);
   returns - number of encoded bytes in the destination buffer
 */
 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
-	int *count, u8 *dst, int dsize)
+		    int *count, u8 *dst, int dsize)
 {
 	static const unsigned char xfast_flag_value[] = {
 		0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
@@ -478,7 +478,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
 			}
 			if (hdlc->bit_shift == 8)
 				hdlc->crc = crc_ccitt_byte(hdlc->crc,
-					hdlc->shift_reg);
+							   hdlc->shift_reg);
 			if (hdlc->shift_reg & 0x01) {
 				hdlc->hdlc_bits1++;
 				hdlc->cbin++;
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 1f355bb..e74df7c 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -54,7 +54,7 @@ static int icn_addcard(int, char *, char *);
  *   channel = channel number
  */
 static void
-icn_free_queue(icn_card * card, int channel)
+icn_free_queue(icn_card *card, int channel)
 {
 	struct sk_buff_head *queue = &card->spqueue[channel];
 	struct sk_buff *skb;
@@ -93,7 +93,7 @@ icn_shiftout(unsigned short port,
  * disable a cards shared memory
  */
 static inline void
-icn_disable_ram(icn_card * card)
+icn_disable_ram(icn_card *card)
 {
 	OUTB_P(0, ICN_MAPRAM);
 }
@@ -102,7 +102,7 @@ icn_disable_ram(icn_card * card)
  * enable a cards shared memory
  */
 static inline void
-icn_enable_ram(icn_card * card)
+icn_enable_ram(icn_card *card)
 {
 	OUTB_P(0xff, ICN_MAPRAM);
 }
@@ -113,7 +113,7 @@ icn_enable_ram(icn_card * card)
  * must called with holding the devlock
  */
 static inline void
-icn_map_channel(icn_card * card, int channel)
+icn_map_channel(icn_card *card, int channel)
 {
 #ifdef MAP_DEBUG
 	printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);
@@ -139,7 +139,7 @@ icn_map_channel(icn_card * card, int channel)
  * must called with holding the devlock
  */
 static inline int
-icn_lock_channel(icn_card * card, int channel)
+icn_lock_channel(icn_card *card, int channel)
 {
 	register int retval;
 
@@ -194,7 +194,7 @@ icn_release_channel(void)
  * Return 1 on success, 0 on failure.
  */
 static inline int
-icn_trymaplock_channel(icn_card * card, int channel)
+icn_trymaplock_channel(icn_card *card, int channel)
 {
 	ulong flags;
 
@@ -225,7 +225,7 @@ icn_trymaplock_channel(icn_card * card, int channel)
  * then map same or other channel without locking.
  */
 static inline void
-icn_maprelease_channel(icn_card * card, int channel)
+icn_maprelease_channel(icn_card *card, int channel)
 {
 	ulong flags;
 
@@ -246,7 +246,7 @@ icn_maprelease_channel(icn_card * card, int channel)
  */
 
 static void
-icn_pollbchan_receive(int channel, icn_card * card)
+icn_pollbchan_receive(int channel, icn_card *card)
 {
 	int mch = channel + ((card->secondhalf) ? 2 : 0);
 	int eflag;
@@ -297,7 +297,7 @@ icn_pollbchan_receive(int channel, icn_card * card)
  */
 
 static void
-icn_pollbchan_send(int channel, icn_card * card)
+icn_pollbchan_send(int channel, icn_card *card)
 {
 	int mch = channel + ((card->secondhalf) ? 2 : 0);
 	int cnt;
@@ -309,7 +309,7 @@ icn_pollbchan_send(int channel, icn_card * card)
 	      !skb_queue_empty(&card->spqueue[channel])))
 		return;
 	if (icn_trymaplock_channel(card, mch)) {
-		while (sbfree && 
+		while (sbfree &&
 		       (card->sndcount[channel] ||
 			!skb_queue_empty(&card->spqueue[channel]) ||
 			card->xskb[channel])) {
@@ -327,7 +327,7 @@ icn_pollbchan_send(int channel, icn_card * card)
 					/* Pop ACK-flag off skb.
 					 * Store length to xlen.
 					 */
-					if (*(skb_pull(skb,1)))
+					if (*(skb_pull(skb, 1)))
 						card->xlen[channel] = skb->len;
 					else
 						card->xlen[channel] = 0;
@@ -396,7 +396,7 @@ icn_pollbchan(unsigned long data)
 	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
 		/* schedule b-channel polling again */
 		spin_lock_irqsave(&card->lock, flags);
-		mod_timer(&card->rb_timer, jiffies+ICN_TIMER_BCREAD);
+		mod_timer(&card->rb_timer, jiffies + ICN_TIMER_BCREAD);
 		card->flags |= ICN_FLAGS_RBTIMER;
 		spin_unlock_irqrestore(&card->lock, flags);
 	} else
@@ -428,7 +428,7 @@ static icn_stat icn_stat_table[] =
 	{"E_L1: ACT FAIL", ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
 	{"E_L2: DATA LIN", ISDN_STAT_BHUP,  8},	/* Layer-2 data link lost     */
 	{"E_L1: ACTIVATION FAILED",
-					   ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
+	 ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
 	{NULL, 0, -1}
 };
 /* *INDENT-ON* */
@@ -445,7 +445,7 @@ static icn_stat icn_stat_table[] =
  */
 
 static void
-icn_parse_status(u_char * status, int channel, icn_card * card)
+icn_parse_status(u_char *status, int channel, icn_card *card)
 {
 	icn_stat *s = icn_stat_table;
 	int action = -1;
@@ -465,128 +465,128 @@ icn_parse_status(u_char * status, int channel, icn_card * card)
 	cmd.driver = card->myid;
 	cmd.arg = channel;
 	switch (action) {
-		case 11:
-			spin_lock_irqsave(&card->lock, flags);
-			icn_free_queue(card,channel);
-			card->rcvidx[channel] = 0;
-
-			if (card->flags & 
-			    ((channel)?ICN_FLAGS_B2ACTIVE:ICN_FLAGS_B1ACTIVE)) {
-				
-				isdn_ctrl ncmd;
-				
-				card->flags &= ~((channel)?
-						 ICN_FLAGS_B2ACTIVE:ICN_FLAGS_B1ACTIVE);
-				
-				memset(&ncmd, 0, sizeof(ncmd));
-				
-				ncmd.driver = card->myid;
-				ncmd.arg = channel;
-				ncmd.command = ISDN_STAT_BHUP;
-				spin_unlock_irqrestore(&card->lock, flags);
-				card->interface.statcallb(&cmd);
-			} else
-				spin_unlock_irqrestore(&card->lock, flags);
-			break;
-		case 1:
-			spin_lock_irqsave(&card->lock, flags);
-			icn_free_queue(card,channel);
-			card->flags |= (channel) ?
-			    ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
-			spin_unlock_irqrestore(&card->lock, flags);
-			break;
-		case 2:
-			spin_lock_irqsave(&card->lock, flags);
+	case 11:
+		spin_lock_irqsave(&card->lock, flags);
+		icn_free_queue(card, channel);
+		card->rcvidx[channel] = 0;
+
+		if (card->flags &
+		    ((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) {
+
+			isdn_ctrl ncmd;
+
 			card->flags &= ~((channel) ?
-				ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
-			icn_free_queue(card, channel);
-			card->rcvidx[channel] = 0;
-			spin_unlock_irqrestore(&card->lock, flags);
-			break;
-		case 3:
-			{
-				char *t = status + 6;
-				char *s = strchr(t, ',');
-
-				*s++ = '\0';
-				strlcpy(cmd.parm.setup.phone, t,
-					sizeof(cmd.parm.setup.phone));
-				s = strchr(t = s, ',');
-				*s++ = '\0';
-				if (!strlen(t))
-					cmd.parm.setup.si1 = 0;
-				else
-					cmd.parm.setup.si1 =
-					    simple_strtoul(t, NULL, 10);
-				s = strchr(t = s, ',');
-				*s++ = '\0';
-				if (!strlen(t))
-					cmd.parm.setup.si2 = 0;
-				else
-					cmd.parm.setup.si2 =
-					    simple_strtoul(t, NULL, 10);
-				strlcpy(cmd.parm.setup.eazmsn, s,
-					sizeof(cmd.parm.setup.eazmsn));
-			}
-			cmd.parm.setup.plan = 0;
-			cmd.parm.setup.screen = 0;
-			break;
-		case 4:
-			sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
-			sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
-			cmd.parm.setup.si1 = 7;
-			cmd.parm.setup.si2 = 0;
-			cmd.parm.setup.plan = 0;
-			cmd.parm.setup.screen = 0;
-			break;
-		case 5:
-			strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
-			break;
-		case 6:
-			snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
-			     (int) simple_strtoul(status + 7, NULL, 16));
-			break;
-		case 7:
-			status += 3;
-			if (strlen(status) == 4)
-				snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
-				     status + 2, *status, *(status + 1));
-			else
-				strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
-			break;
-		case 8:
-			spin_lock_irqsave(&card->lock, flags);
-			card->flags &= ~ICN_FLAGS_B1ACTIVE;
-			icn_free_queue(card, 0);
-			card->rcvidx[0] = 0;
+					 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
+
+			memset(&ncmd, 0, sizeof(ncmd));
+
+			ncmd.driver = card->myid;
+			ncmd.arg = channel;
+			ncmd.command = ISDN_STAT_BHUP;
 			spin_unlock_irqrestore(&card->lock, flags);
-			cmd.arg = 0;
-			cmd.driver = card->myid;
-			card->interface.statcallb(&cmd);
-			cmd.command = ISDN_STAT_DHUP;
-			cmd.arg = 0;
-			cmd.driver = card->myid;
 			card->interface.statcallb(&cmd);
-			cmd.command = ISDN_STAT_BHUP;
-			spin_lock_irqsave(&card->lock, flags);
-			card->flags &= ~ICN_FLAGS_B2ACTIVE;
-			icn_free_queue(card, 1);
-			card->rcvidx[1] = 0;
+		} else
 			spin_unlock_irqrestore(&card->lock, flags);
-			cmd.arg = 1;
-			cmd.driver = card->myid;
-			card->interface.statcallb(&cmd);
-			cmd.command = ISDN_STAT_DHUP;
-			cmd.arg = 1;
-			cmd.driver = card->myid;
-			break;
+		break;
+	case 1:
+		spin_lock_irqsave(&card->lock, flags);
+		icn_free_queue(card, channel);
+		card->flags |= (channel) ?
+			ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
+		spin_unlock_irqrestore(&card->lock, flags);
+		break;
+	case 2:
+		spin_lock_irqsave(&card->lock, flags);
+		card->flags &= ~((channel) ?
+				 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
+		icn_free_queue(card, channel);
+		card->rcvidx[channel] = 0;
+		spin_unlock_irqrestore(&card->lock, flags);
+		break;
+	case 3:
+	{
+		char *t = status + 6;
+		char *s = strchr(t, ',');
+
+		*s++ = '\0';
+		strlcpy(cmd.parm.setup.phone, t,
+			sizeof(cmd.parm.setup.phone));
+		s = strchr(t = s, ',');
+		*s++ = '\0';
+		if (!strlen(t))
+			cmd.parm.setup.si1 = 0;
+		else
+			cmd.parm.setup.si1 =
+				simple_strtoul(t, NULL, 10);
+		s = strchr(t = s, ',');
+		*s++ = '\0';
+		if (!strlen(t))
+			cmd.parm.setup.si2 = 0;
+		else
+			cmd.parm.setup.si2 =
+				simple_strtoul(t, NULL, 10);
+		strlcpy(cmd.parm.setup.eazmsn, s,
+			sizeof(cmd.parm.setup.eazmsn));
+	}
+	cmd.parm.setup.plan = 0;
+	cmd.parm.setup.screen = 0;
+	break;
+	case 4:
+		sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
+		sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
+		cmd.parm.setup.si1 = 7;
+		cmd.parm.setup.si2 = 0;
+		cmd.parm.setup.plan = 0;
+		cmd.parm.setup.screen = 0;
+		break;
+	case 5:
+		strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
+		break;
+	case 6:
+		snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
+			 (int) simple_strtoul(status + 7, NULL, 16));
+		break;
+	case 7:
+		status += 3;
+		if (strlen(status) == 4)
+			snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
+				 status + 2, *status, *(status + 1));
+		else
+			strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
+		break;
+	case 8:
+		spin_lock_irqsave(&card->lock, flags);
+		card->flags &= ~ICN_FLAGS_B1ACTIVE;
+		icn_free_queue(card, 0);
+		card->rcvidx[0] = 0;
+		spin_unlock_irqrestore(&card->lock, flags);
+		cmd.arg = 0;
+		cmd.driver = card->myid;
+		card->interface.statcallb(&cmd);
+		cmd.command = ISDN_STAT_DHUP;
+		cmd.arg = 0;
+		cmd.driver = card->myid;
+		card->interface.statcallb(&cmd);
+		cmd.command = ISDN_STAT_BHUP;
+		spin_lock_irqsave(&card->lock, flags);
+		card->flags &= ~ICN_FLAGS_B2ACTIVE;
+		icn_free_queue(card, 1);
+		card->rcvidx[1] = 0;
+		spin_unlock_irqrestore(&card->lock, flags);
+		cmd.arg = 1;
+		cmd.driver = card->myid;
+		card->interface.statcallb(&cmd);
+		cmd.command = ISDN_STAT_DHUP;
+		cmd.arg = 1;
+		cmd.driver = card->myid;
+		break;
 	}
 	card->interface.statcallb(&cmd);
 	return;
 }
 
 static void
-icn_putmsg(icn_card * card, unsigned char c)
+icn_putmsg(icn_card *card, unsigned char c)
 {
 	ulong flags;
 
@@ -688,7 +688,7 @@ icn_polldchan(unsigned long data)
 			add_timer(&card->rb_timer);
 		}
 	/* schedule again */
-	mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD);
+	mod_timer(&card->st_timer, jiffies + ICN_TIMER_DCREAD);
 	spin_unlock_irqrestore(&card->lock, flags);
 }
 
@@ -702,7 +702,7 @@ icn_polldchan(unsigned long data)
  */
 
 static int
-icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
+icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card)
 {
 	int len = skb->len;
 	unsigned long flags;
@@ -718,13 +718,13 @@ icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
 			return 0;
 		if (card->sndcount[channel] > ICN_MAX_SQUEUE)
 			return 0;
-		#warning TODO test headroom or use skb->nb to flag ACK
+#warning TODO test headroom or use skb->nb to flag ACK
 		nskb = skb_clone(skb, GFP_ATOMIC);
 		if (nskb) {
 			/* Push ACK flag as one
 			 * byte in front of data.
 			 */
-			*(skb_push(nskb, 1)) = ack?1:0;
+			*(skb_push(nskb, 1)) = ack ? 1 : 0;
 			skb_queue_tail(&card->spqueue[channel], nskb);
 			dev_kfree_skb(skb);
 		} else
@@ -785,20 +785,20 @@ icn_check_loader(int cardnumber)
  */
 
 #ifdef BOOT_DEBUG
-#define SLEEP(sec) { \
-int slsec = sec; \
-  printk(KERN_DEBUG "SLEEP(%d)\n",slsec); \
-  while (slsec) { \
-    msleep_interruptible(1000); \
-    slsec--; \
-  } \
-}
+#define SLEEP(sec) {						\
+		int slsec = sec;				\
+		printk(KERN_DEBUG "SLEEP(%d)\n", slsec);	\
+		while (slsec) {					\
+			msleep_interruptible(1000);		\
+			slsec--;				\
+		}						\
+	}
 #else
 #define SLEEP(sec)
 #endif
 
 static int
-icn_loadboot(u_char __user * buffer, icn_card * card)
+icn_loadboot(u_char __user *buffer, icn_card *card)
 {
 	int ret;
 	u_char *codebuf;
@@ -896,14 +896,14 @@ icn_loadboot(u_char __user * buffer, icn_card * card)
 	SLEEP(1);
 	ret = (icn_check_loader(1));
 
- out_kfree:
+out_kfree:
 	kfree(codebuf);
- out:
+out:
 	return ret;
 }
 
 static int
-icn_loadproto(u_char __user * buffer, icn_card * card)
+icn_loadproto(u_char __user *buffer, icn_card *card)
 {
 	register u_char __user *p = buffer;
 	u_char codebuf[256];
@@ -1004,7 +1004,7 @@ icn_loadproto(u_char __user * buffer, icn_card * card)
 
 /* Read the Status-replies from the Interface */
 static int
-icn_readstatus(u_char __user *buf, int len, icn_card * card)
+icn_readstatus(u_char __user *buf, int len, icn_card *card)
 {
 	int count;
 	u_char __user *p;
@@ -1022,7 +1022,7 @@ icn_readstatus(u_char __user *buf, int len, icn_card * card)
 
 /* Put command-strings into the command-queue of the Interface */
 static int
-icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
+icn_writecmd(const u_char *buf, int len, int user, icn_card *card)
 {
 	int mch = card->secondhalf ? 2 : 0;
 	int pp;
@@ -1057,9 +1057,9 @@ icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
 
 		icn_putmsg(card, '>');
 		for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp
-		     ++) {
+			     ++) {
 			writeb((*p == '\n') ? 0xff : *p,
-			   &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
+			       &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
 			len--;
 			xcount++;
 			icn_putmsg(card, *p);
@@ -1093,7 +1093,7 @@ icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
  * Delete card's pending timers, send STOP to linklevel
  */
 static void
-icn_stopcard(icn_card * card)
+icn_stopcard(icn_card *card)
 {
 	unsigned long flags;
 	isdn_ctrl cmd;
@@ -1150,7 +1150,7 @@ icn_disable_cards(void)
 }
 
 static int
-icn_command(isdn_ctrl * c, icn_card * card)
+icn_command(isdn_ctrl *c, icn_card *card)
 {
 	ulong a;
 	ulong flags;
@@ -1161,275 +1161,275 @@ icn_command(isdn_ctrl * c, icn_card * card)
 	char __user *arg;
 
 	switch (c->command) {
-		case ISDN_CMD_IOCTL:
-			memcpy(&a, c->parm.num, sizeof(ulong));
-			arg = (char __user *)a;
-			switch (c->arg) {
-				case ICN_IOCTL_SETMMIO:
-					if (dev.memaddr != (a & 0x0ffc000)) {
-						if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) {
-							printk(KERN_WARNING
-							       "icn: memory at 0x%08lx in use.\n",
-							       a & 0x0ffc000);
-							return -EINVAL;
-						}
-						release_mem_region(a & 0x0ffc000, 0x4000);
-						icn_stopallcards();
-						spin_lock_irqsave(&card->lock, flags);
-						if (dev.mvalid) {
-							iounmap(dev.shmem);
-							release_mem_region(dev.memaddr, 0x4000);
-						}
-						dev.mvalid = 0;
-						dev.memaddr = a & 0x0ffc000;
-						spin_unlock_irqrestore(&card->lock, flags);
-						printk(KERN_INFO
-						       "icn: (%s) mmio set to 0x%08lx\n",
-						       CID,
-						       dev.memaddr);
-					}
-					break;
-				case ICN_IOCTL_GETMMIO:
-					return (long) dev.memaddr;
-				case ICN_IOCTL_SETPORT:
-					if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
-					    || a == 0x340 || a == 0x350 || a == 0x360 ||
-					    a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
-					    || a == 0x348 || a == 0x358 || a == 0x368) {
-						if (card->port != (unsigned short) a) {
-							if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) {
-								printk(KERN_WARNING
-								       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
-								       CID, (int) a, (int) a + ICN_PORTLEN);
-								return -EINVAL;
-							}
-							release_region((unsigned short) a, ICN_PORTLEN);
-							icn_stopcard(card);
-							spin_lock_irqsave(&card->lock, flags);
-							if (card->rvalid)
-								release_region(card->port, ICN_PORTLEN);
-							card->port = (unsigned short) a;
-							card->rvalid = 0;
-							if (card->doubleS0) {
-								card->other->port = (unsigned short) a;
-								card->other->rvalid = 0;
-							}
-							spin_unlock_irqrestore(&card->lock, flags);
-							printk(KERN_INFO
-							       "icn: (%s) port set to 0x%03x\n",
-							CID, card->port);
-						}
-					} else
+	case ISDN_CMD_IOCTL:
+		memcpy(&a, c->parm.num, sizeof(ulong));
+		arg = (char __user *)a;
+		switch (c->arg) {
+		case ICN_IOCTL_SETMMIO:
+			if (dev.memaddr != (a & 0x0ffc000)) {
+				if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) {
+					printk(KERN_WARNING
+					       "icn: memory at 0x%08lx in use.\n",
+					       a & 0x0ffc000);
+					return -EINVAL;
+				}
+				release_mem_region(a & 0x0ffc000, 0x4000);
+				icn_stopallcards();
+				spin_lock_irqsave(&card->lock, flags);
+				if (dev.mvalid) {
+					iounmap(dev.shmem);
+					release_mem_region(dev.memaddr, 0x4000);
+				}
+				dev.mvalid = 0;
+				dev.memaddr = a & 0x0ffc000;
+				spin_unlock_irqrestore(&card->lock, flags);
+				printk(KERN_INFO
+				       "icn: (%s) mmio set to 0x%08lx\n",
+				       CID,
+				       dev.memaddr);
+			}
+			break;
+		case ICN_IOCTL_GETMMIO:
+			return (long) dev.memaddr;
+		case ICN_IOCTL_SETPORT:
+			if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
+			    || a == 0x340 || a == 0x350 || a == 0x360 ||
+			    a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
+			    || a == 0x348 || a == 0x358 || a == 0x368) {
+				if (card->port != (unsigned short) a) {
+					if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) {
+						printk(KERN_WARNING
+						       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
+						       CID, (int) a, (int) a + ICN_PORTLEN);
 						return -EINVAL;
-					break;
-				case ICN_IOCTL_GETPORT:
-					return (int) card->port;
-				case ICN_IOCTL_GETDOUBLE:
-					return (int) card->doubleS0;
-				case ICN_IOCTL_DEBUGVAR:
-					if (copy_to_user(arg,
-							 &card,
-							 sizeof(ulong)))
-						return -EFAULT;
-					a += sizeof(ulong);
-					{
-						ulong l = (ulong) & dev;
-						if (copy_to_user(arg,
-								 &l,
-								 sizeof(ulong)))
-							return -EFAULT;
 					}
-					return 0;
-				case ICN_IOCTL_LOADBOOT:
-					if (dev.firstload) {
-						icn_disable_cards();
-						dev.firstload = 0;
-					}
-					icn_stopcard(card);
-					return (icn_loadboot(arg, card));
-				case ICN_IOCTL_LOADPROTO:
+					release_region((unsigned short) a, ICN_PORTLEN);
 					icn_stopcard(card);
-					if ((i = (icn_loadproto(arg, card))))
-						return i;
-					if (card->doubleS0)
-						i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other);
-					return i;
-					break;
-				case ICN_IOCTL_ADDCARD:
-					if (!dev.firstload)
-						return -EBUSY;
-					if (copy_from_user(&cdef,
-							   arg,
-							   sizeof(cdef)))
-						return -EFAULT;
-					return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
-					break;
-				case ICN_IOCTL_LEASEDCFG:
-					if (a) {
-						if (!card->leased) {
-							card->leased = 1;
-							while (card->ptype == ISDN_PTYPE_UNKNOWN) {
-								msleep_interruptible(ICN_BOOT_TIMEOUT1);
-							}
-							msleep_interruptible(ICN_BOOT_TIMEOUT1);
-							sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
-								(a & 1)?'1':'C', (a & 2)?'2':'C');
-							i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
-							printk(KERN_INFO
-							       "icn: (%s) Leased-line mode enabled\n",
-							       CID);
-							cmd.command = ISDN_STAT_RUN;
-							cmd.driver = card->myid;
-							cmd.arg = 0;
-							card->interface.statcallb(&cmd);
-						}
-					} else {
-						if (card->leased) {
-							card->leased = 0;
-							sprintf(cbuf, "00;FV2OFF\n");
-							i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
-							printk(KERN_INFO
-							       "icn: (%s) Leased-line mode disabled\n",
-							       CID);
-							cmd.command = ISDN_STAT_RUN;
-							cmd.driver = card->myid;
-							cmd.arg = 0;
-							card->interface.statcallb(&cmd);
-						}
+					spin_lock_irqsave(&card->lock, flags);
+					if (card->rvalid)
+						release_region(card->port, ICN_PORTLEN);
+					card->port = (unsigned short) a;
+					card->rvalid = 0;
+					if (card->doubleS0) {
+						card->other->port = (unsigned short) a;
+						card->other->rvalid = 0;
 					}
-					return 0;
-				default:
-					return -EINVAL;
-			}
+					spin_unlock_irqrestore(&card->lock, flags);
+					printk(KERN_INFO
+					       "icn: (%s) port set to 0x%03x\n",
+					       CID, card->port);
+				}
+			} else
+				return -EINVAL;
 			break;
-		case ISDN_CMD_DIAL:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if (card->leased)
-				break;
-			if ((c->arg & 255) < ICN_BCH) {
-				char *p;
-				char dial[50];
-				char dcode[4];
-
-				a = c->arg;
-				p = c->parm.setup.phone;
-				if (*p == 's' || *p == 'S') {
-					/* Dial for SPV */
-					p++;
-					strcpy(dcode, "SCA");
-				} else
-					/* Normal Dial */
-					strcpy(dcode, "CAL");
-				strcpy(dial, p);
-				sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
-					dcode, dial, c->parm.setup.si1,
-				c->parm.setup.si2, c->parm.setup.eazmsn);
-				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		case ICN_IOCTL_GETPORT:
+			return (int) card->port;
+		case ICN_IOCTL_GETDOUBLE:
+			return (int) card->doubleS0;
+		case ICN_IOCTL_DEBUGVAR:
+			if (copy_to_user(arg,
+					 &card,
+					 sizeof(ulong)))
+				return -EFAULT;
+			a += sizeof(ulong);
+			{
+				ulong l = (ulong)&dev;
+				if (copy_to_user(arg,
+						 &l,
+						 sizeof(ulong)))
+					return -EFAULT;
 			}
+			return 0;
+		case ICN_IOCTL_LOADBOOT:
+			if (dev.firstload) {
+				icn_disable_cards();
+				dev.firstload = 0;
+			}
+			icn_stopcard(card);
+			return (icn_loadboot(arg, card));
+		case ICN_IOCTL_LOADPROTO:
+			icn_stopcard(card);
+			if ((i = (icn_loadproto(arg, card))))
+				return i;
+			if (card->doubleS0)
+				i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other);
+			return i;
+			break;
+		case ICN_IOCTL_ADDCARD:
+			if (!dev.firstload)
+				return -EBUSY;
+			if (copy_from_user(&cdef,
+					   arg,
+					   sizeof(cdef)))
+				return -EFAULT;
+			return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
 			break;
-		case ISDN_CMD_ACCEPTD:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if (c->arg < ICN_BCH) {
-				a = c->arg + 1;
-				if (card->fw_rev >= 300) {
-					switch (card->l2_proto[a - 1]) {
-						case ISDN_PROTO_L2_X75I:
-							sprintf(cbuf, "%02d;BX75\n", (int) a);
-							break;
-						case ISDN_PROTO_L2_HDLC:
-							sprintf(cbuf, "%02d;BTRA\n", (int) a);
-							break;
+		case ICN_IOCTL_LEASEDCFG:
+			if (a) {
+				if (!card->leased) {
+					card->leased = 1;
+					while (card->ptype == ISDN_PTYPE_UNKNOWN) {
+						msleep_interruptible(ICN_BOOT_TIMEOUT1);
 					}
+					msleep_interruptible(ICN_BOOT_TIMEOUT1);
+					sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
+						(a & 1) ? '1' : 'C', (a & 2) ? '2' : 'C');
 					i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+					printk(KERN_INFO
+					       "icn: (%s) Leased-line mode enabled\n",
+					       CID);
+					cmd.command = ISDN_STAT_RUN;
+					cmd.driver = card->myid;
+					cmd.arg = 0;
+					card->interface.statcallb(&cmd);
+				}
+			} else {
+				if (card->leased) {
+					card->leased = 0;
+					sprintf(cbuf, "00;FV2OFF\n");
+					i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+					printk(KERN_INFO
+					       "icn: (%s) Leased-line mode disabled\n",
+					       CID);
+					cmd.command = ISDN_STAT_RUN;
+					cmd.driver = card->myid;
+					cmd.arg = 0;
+					card->interface.statcallb(&cmd);
 				}
-				sprintf(cbuf, "%02d;DCON_R\n", (int) a);
-				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
 			}
+			return 0;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case ISDN_CMD_DIAL:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if (card->leased)
 			break;
-		case ISDN_CMD_ACCEPTB:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if (c->arg < ICN_BCH) {
-				a = c->arg + 1;
-				if (card->fw_rev >= 300)
-					switch (card->l2_proto[a - 1]) {
-						case ISDN_PROTO_L2_X75I:
-							sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
-							break;
-						case ISDN_PROTO_L2_HDLC:
-							sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
-							break;
-				} else
-					sprintf(cbuf, "%02d;BCON_R\n", (int) a);
+		if ((c->arg & 255) < ICN_BCH) {
+			char *p;
+			char dial[50];
+			char dcode[4];
+
+			a = c->arg;
+			p = c->parm.setup.phone;
+			if (*p == 's' || *p == 'S') {
+				/* Dial for SPV */
+				p++;
+				strcpy(dcode, "SCA");
+			} else
+				/* Normal Dial */
+				strcpy(dcode, "CAL");
+			strcpy(dial, p);
+			sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
+				dcode, dial, c->parm.setup.si1,
+				c->parm.setup.si2, c->parm.setup.eazmsn);
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_ACCEPTD:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if (c->arg < ICN_BCH) {
+			a = c->arg + 1;
+			if (card->fw_rev >= 300) {
+				switch (card->l2_proto[a - 1]) {
+				case ISDN_PROTO_L2_X75I:
+					sprintf(cbuf, "%02d;BX75\n", (int) a);
+					break;
+				case ISDN_PROTO_L2_HDLC:
+					sprintf(cbuf, "%02d;BTRA\n", (int) a);
+					break;
+				}
 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
 			}
+			sprintf(cbuf, "%02d;DCON_R\n", (int) a);
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_ACCEPTB:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if (c->arg < ICN_BCH) {
+			a = c->arg + 1;
+			if (card->fw_rev >= 300)
+				switch (card->l2_proto[a - 1]) {
+				case ISDN_PROTO_L2_X75I:
+					sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
+					break;
+				case ISDN_PROTO_L2_HDLC:
+					sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
+					break;
+				} else
+				sprintf(cbuf, "%02d;BCON_R\n", (int) a);
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_HANGUP:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if (c->arg < ICN_BCH) {
+			a = c->arg + 1;
+			sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_SETEAZ:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if (card->leased)
 			break;
-		case ISDN_CMD_HANGUP:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if (c->arg < ICN_BCH) {
-				a = c->arg + 1;
-				sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
-				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
-			}
+		if (c->arg < ICN_BCH) {
+			a = c->arg + 1;
+			if (card->ptype == ISDN_PTYPE_EURO) {
+				sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
+					c->parm.num[0] ? "N" : "ALL", c->parm.num);
+			} else
+				sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
+					c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_CLREAZ:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if (card->leased)
 			break;
-		case ISDN_CMD_SETEAZ:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if (card->leased)
+		if (c->arg < ICN_BCH) {
+			a = c->arg + 1;
+			if (card->ptype == ISDN_PTYPE_EURO)
+				sprintf(cbuf, "%02d;MSNC\n", (int) a);
+			else
+				sprintf(cbuf, "%02d;EAZC\n", (int) a);
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_SETL2:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		if ((c->arg & 255) < ICN_BCH) {
+			a = c->arg;
+			switch (a >> 8) {
+			case ISDN_PROTO_L2_X75I:
+				sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
 				break;
-			if (c->arg < ICN_BCH) {
-				a = c->arg + 1;
-				if (card->ptype == ISDN_PTYPE_EURO) {
-					sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
-						c->parm.num[0] ? "N" : "ALL", c->parm.num);
-				} else
-					sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
-						c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
-				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
-			}
-			break;
-		case ISDN_CMD_CLREAZ:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if (card->leased)
+			case ISDN_PROTO_L2_HDLC:
+				sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
 				break;
-			if (c->arg < ICN_BCH) {
-				a = c->arg + 1;
-				if (card->ptype == ISDN_PTYPE_EURO)
-					sprintf(cbuf, "%02d;MSNC\n", (int) a);
-				else
-					sprintf(cbuf, "%02d;EAZC\n", (int) a);
-				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
-			}
-			break;
-		case ISDN_CMD_SETL2:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			if ((c->arg & 255) < ICN_BCH) {
-				a = c->arg;
-				switch (a >> 8) {
-					case ISDN_PROTO_L2_X75I:
-						sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
-						break;
-					case ISDN_PROTO_L2_HDLC:
-						sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
-						break;
-					default:
-						return -EINVAL;
-				}
-				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
-				card->l2_proto[a & 255] = (a >> 8);
+			default:
+				return -EINVAL;
 			}
-			break;
-		case ISDN_CMD_SETL3:
-			if (!(card->flags & ICN_FLAGS_RUNNING))
-				return -ENODEV;
-			return 0;
-		default:
-			return -EINVAL;
+			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
+			card->l2_proto[a & 255] = (a >> 8);
+		}
+		break;
+	case ISDN_CMD_SETL3:
+		if (!(card->flags & ICN_FLAGS_RUNNING))
+			return -ENODEV;
+		return 0;
+	default:
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -1454,7 +1454,7 @@ icn_findcard(int driverid)
  * Wrapper functions for interface to linklevel
  */
 static int
-if_command(isdn_ctrl * c)
+if_command(isdn_ctrl *c)
 {
 	icn_card *card = icn_findcard(c->driver);
 
@@ -1537,9 +1537,9 @@ icn_initcard(int port, char *id)
 	card->interface.writecmd = if_writecmd;
 	card->interface.readstat = if_readstatus;
 	card->interface.features = ISDN_FEATURE_L2_X75I |
-	    ISDN_FEATURE_L2_HDLC |
-	    ISDN_FEATURE_L3_TRANS |
-	    ISDN_FEATURE_P_UNKNOWN;
+		ISDN_FEATURE_L2_HDLC |
+		ISDN_FEATURE_L3_TRANS |
+		ISDN_FEATURE_P_UNKNOWN;
 	card->ptype = ISDN_PTYPE_UNKNOWN;
 	strlcpy(card->interface.id, id, sizeof(card->interface.id));
 	card->msg_buf_write = card->msg_buf;
@@ -1619,7 +1619,7 @@ icn_setup(char *line)
 			icn_id2 = sid2;
 		}
 	}
-	return(1);
+	return (1);
 }
 __setup("icn=", icn_setup);
 #endif /* MODULE */
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index 7d7245f..b713466 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -54,7 +54,7 @@ typedef struct icn_cdef {
 
 /* some useful macros for debugging */
 #ifdef ICN_DEBUG_PORT
-#define OUTB_P(v,p) {printk(KERN_DEBUG "icn: outb_p(0x%02x,0x%03x)\n",v,p); outb_p(v,p);}
+#define OUTB_P(v, p) {printk(KERN_DEBUG "icn: outb_p(0x%02x,0x%03x)\n", v, p); outb_p(v, p);}
 #else
 #define OUTB_P outb
 #endif
@@ -71,8 +71,8 @@ typedef struct icn_cdef {
 
 #define ICN_BOOT_TIMEOUT1  1000 /* Delay for Boot-download (msecs)         */
 
-#define ICN_TIMER_BCREAD (HZ/100)	/* B-Channel poll-cycle                    */
-#define ICN_TIMER_DCREAD (HZ/2) /* D-Channel poll-cycle                    */
+#define ICN_TIMER_BCREAD (HZ / 100)	/* B-Channel poll-cycle                    */
+#define ICN_TIMER_DCREAD (HZ / 2) /* D-Channel poll-cycle                    */
 
 #define ICN_CODE_STAGE1 4096    /* Size of bootcode                        */
 #define ICN_CODE_STAGE2 65536   /* Size of protocol-code                   */
@@ -140,7 +140,7 @@ typedef struct icn_card {
 	int myid;               /* Driver-Nr. assigned by linklevel */
 	int rvalid;             /* IO-portregion has been requested */
 	int leased;             /* Flag: This Adapter is connected  */
-	                        /*       to a leased line           */
+				/*       to a leased line           */
 	unsigned short flags;   /* Statusflags                      */
 	int doubleS0;           /* Flag: ICN4B                      */
 	int secondhalf;         /* Flag: Second half of a doubleS0  */
@@ -197,16 +197,16 @@ static icn_dev dev;
 
 /* Macros for accessing ports */
 #define ICN_CFG    (card->port)
-#define ICN_MAPRAM (card->port+1)
-#define ICN_RUN    (card->port+2)
-#define ICN_BANK   (card->port+3)
+#define ICN_MAPRAM (card->port + 1)
+#define ICN_RUN    (card->port + 2)
+#define ICN_BANK   (card->port + 3)
 
 /* Return true, if there is a free transmit-buffer */
-#define sbfree (((readb(&dev.shmem->data_control.scns)+1) & 0xf) != \
+#define sbfree (((readb(&dev.shmem->data_control.scns) + 1) & 0xf) !=	\
 		readb(&dev.shmem->data_control.scnr))
 
 /* Switch to next transmit-buffer */
-#define sbnext (writeb((readb(&dev.shmem->data_control.scns)+1) & 0xf, \
+#define sbnext (writeb((readb(&dev.shmem->data_control.scns) + 1) & 0xf,	\
 		       &dev.shmem->data_control.scns))
 
 /* Shortcuts for transmit-buffer-access */
@@ -220,7 +220,7 @@ static icn_dev dev;
 		readb(&dev.shmem->data_control.ecns))
 
 /* Switch to next receive-buffer */
-#define rbnext (writeb((readb(&dev.shmem->data_control.ecnr)+1) & 0xf, \
+#define rbnext (writeb((readb(&dev.shmem->data_control.ecnr) + 1) & 0xf,	\
 		       &dev.shmem->data_control.ecnr))
 
 /* Shortcuts for receive-buffer-access */
@@ -234,18 +234,18 @@ static icn_dev dev;
 #define cmd_i (dev.shmem->comm_control.pcio_i)
 
 /* Return free space in command-buffer */
-#define cmd_free ((readb(&cmd_i)>=readb(&cmd_o))? \
-		  0x100-readb(&cmd_i)+readb(&cmd_o): \
-		  readb(&cmd_o)-readb(&cmd_i))
+#define cmd_free ((readb(&cmd_i) >= readb(&cmd_o)) ?		\
+		  0x100 - readb(&cmd_i) + readb(&cmd_o) :	\
+		  readb(&cmd_o) - readb(&cmd_i))
 
 /* Shortcuts for message-buffer-access */
 #define msg_o (dev.shmem->comm_control.iopc_o)
 #define msg_i (dev.shmem->comm_control.iopc_i)
 
 /* Return length of Message, if avail. */
-#define msg_avail ((readb(&msg_o)>readb(&msg_i))? \
-		   0x100-readb(&msg_o)+readb(&msg_i): \
-		   readb(&msg_i)-readb(&msg_o))
+#define msg_avail ((readb(&msg_o) > readb(&msg_i)) ?		\
+		   0x100 - readb(&msg_o) + readb(&msg_i) :	\
+		   readb(&msg_i) - readb(&msg_o))
 
 #define CID (card->interface.id)
 
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index d497db0..5405ec6 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -35,7 +35,7 @@ static int isdnloop_addcard(char *);
  *   channel = channel number
  */
 static void
-isdnloop_free_queue(isdnloop_card * card, int channel)
+isdnloop_free_queue(isdnloop_card *card, int channel)
 {
 	struct sk_buff_head *queue = &card->bqueue[channel];
 
@@ -52,7 +52,7 @@ isdnloop_free_queue(isdnloop_card * card, int channel)
  *   ch   = channel number (0-based)
  */
 static void
-isdnloop_bchan_send(isdnloop_card * card, int ch)
+isdnloop_bchan_send(isdnloop_card *card, int ch)
 {
 	isdnloop_card *rcard = card->rcard[ch];
 	int rch = card->rch[ch], len, ack;
@@ -66,7 +66,7 @@ isdnloop_bchan_send(isdnloop_card * card, int ch)
 			ack = *(skb->head); /* used as scratch area */
 			cmd.driver = card->myid;
 			cmd.arg = ch;
-			if (rcard){
+			if (rcard) {
 				rcard->interface.rcvcallb_skb(rcard->myid, rch, skb);
 			} else {
 				printk(KERN_WARNING "isdnloop: no rcard, skb dropped\n");
@@ -119,7 +119,7 @@ isdnloop_pollbchan(unsigned long data)
  *   cmd   = pointer to struct to be filled.
  */
 static void
-isdnloop_parse_setup(char *setup, isdn_ctrl * cmd)
+isdnloop_parse_setup(char *setup, isdn_ctrl *cmd)
 {
 	char *t = setup;
 	char *s = strchr(t, ',');
@@ -138,7 +138,7 @@ isdnloop_parse_setup(char *setup, isdn_ctrl * cmd)
 		cmd->parm.setup.si2 = 0;
 	else
 		cmd->parm.setup.si2 =
-		    simple_strtoul(t, NULL, 10);
+			simple_strtoul(t, NULL, 10);
 	strlcpy(cmd->parm.setup.eazmsn, s, sizeof(cmd->parm.setup.eazmsn));
 	cmd->parm.setup.plan = 0;
 	cmd->parm.setup.screen = 0;
@@ -166,7 +166,7 @@ static isdnloop_stat isdnloop_stat_table[] =
 	{"E_L1: ACT FAIL", ISDN_STAT_BHUP,  8}, /* Layer-1 activation failed  */
 	{"E_L2: DATA LIN", ISDN_STAT_BHUP,  8}, /* Layer-2 data link lost     */
 	{"E_L1: ACTIVATION FAILED",
-			   ISDN_STAT_BHUP,  8},         /* Layer-1 activation failed  */
+	 ISDN_STAT_BHUP,  8},         /* Layer-1 activation failed  */
 	{NULL, 0, -1}
 };
 /* *INDENT-ON* */
@@ -183,7 +183,7 @@ static isdnloop_stat isdnloop_stat_table[] =
  *   card    = card where message comes from.
  */
 static void
-isdnloop_parse_status(u_char * status, int channel, isdnloop_card * card)
+isdnloop_parse_status(u_char *status, int channel, isdnloop_card *card)
 {
 	isdnloop_stat *s = isdnloop_stat_table;
 	int action = -1;
@@ -202,69 +202,69 @@ isdnloop_parse_status(u_char * status, int channel, isdnloop_card * card)
 	cmd.driver = card->myid;
 	cmd.arg = channel;
 	switch (action) {
-		case 1:
-			/* BCON_x */
-			card->flags |= (channel) ?
-			    ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE;
-			break;
-		case 2:
-			/* BDIS_x */
-			card->flags &= ~((channel) ?
-					 ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE);
-			isdnloop_free_queue(card, channel);
-			break;
-		case 3:
-			/* DCAL_I and DSCA_I */
-			isdnloop_parse_setup(status + 6, &cmd);
-			break;
-		case 4:
-			/* FCALL */
-			sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
-			sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
-			cmd.parm.setup.si1 = 7;
-			cmd.parm.setup.si2 = 0;
-			cmd.parm.setup.plan = 0;
-			cmd.parm.setup.screen = 0;
-			break;
-		case 5:
-			/* CIF */
-			strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
-			break;
-		case 6:
-			/* AOC */
-			snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
-			     (int) simple_strtoul(status + 7, NULL, 16));
-			break;
-		case 7:
-			/* CAU */
-			status += 3;
-			if (strlen(status) == 4)
-				snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
-				     status + 2, *status, *(status + 1));
-			else
-				strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
-			break;
-		case 8:
-			/* Misc Errors on L1 and L2 */
-			card->flags &= ~ISDNLOOP_FLAGS_B1ACTIVE;
-			isdnloop_free_queue(card, 0);
-			cmd.arg = 0;
-			cmd.driver = card->myid;
-			card->interface.statcallb(&cmd);
-			cmd.command = ISDN_STAT_DHUP;
-			cmd.arg = 0;
-			cmd.driver = card->myid;
-			card->interface.statcallb(&cmd);
-			cmd.command = ISDN_STAT_BHUP;
-			card->flags &= ~ISDNLOOP_FLAGS_B2ACTIVE;
-			isdnloop_free_queue(card, 1);
-			cmd.arg = 1;
-			cmd.driver = card->myid;
-			card->interface.statcallb(&cmd);
-			cmd.command = ISDN_STAT_DHUP;
-			cmd.arg = 1;
-			cmd.driver = card->myid;
-			break;
+	case 1:
+		/* BCON_x */
+		card->flags |= (channel) ?
+			ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE;
+		break;
+	case 2:
+		/* BDIS_x */
+		card->flags &= ~((channel) ?
+				 ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE);
+		isdnloop_free_queue(card, channel);
+		break;
+	case 3:
+		/* DCAL_I and DSCA_I */
+		isdnloop_parse_setup(status + 6, &cmd);
+		break;
+	case 4:
+		/* FCALL */
+		sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
+		sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
+		cmd.parm.setup.si1 = 7;
+		cmd.parm.setup.si2 = 0;
+		cmd.parm.setup.plan = 0;
+		cmd.parm.setup.screen = 0;
+		break;
+	case 5:
+		/* CIF */
+		strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
+		break;
+	case 6:
+		/* AOC */
+		snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
+			 (int) simple_strtoul(status + 7, NULL, 16));
+		break;
+	case 7:
+		/* CAU */
+		status += 3;
+		if (strlen(status) == 4)
+			snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
+				 status + 2, *status, *(status + 1));
+		else
+			strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
+		break;
+	case 8:
+		/* Misc Errors on L1 and L2 */
+		card->flags &= ~ISDNLOOP_FLAGS_B1ACTIVE;
+		isdnloop_free_queue(card, 0);
+		cmd.arg = 0;
+		cmd.driver = card->myid;
+		card->interface.statcallb(&cmd);
+		cmd.command = ISDN_STAT_DHUP;
+		cmd.arg = 0;
+		cmd.driver = card->myid;
+		card->interface.statcallb(&cmd);
+		cmd.command = ISDN_STAT_BHUP;
+		card->flags &= ~ISDNLOOP_FLAGS_B2ACTIVE;
+		isdnloop_free_queue(card, 1);
+		cmd.arg = 1;
+		cmd.driver = card->myid;
+		card->interface.statcallb(&cmd);
+		cmd.command = ISDN_STAT_DHUP;
+		cmd.arg = 1;
+		cmd.driver = card->myid;
+		break;
 	}
 	card->interface.statcallb(&cmd);
 }
@@ -277,7 +277,7 @@ isdnloop_parse_status(u_char * status, int channel, isdnloop_card * card)
  *   c    = char to store.
  */
 static void
-isdnloop_putmsg(isdnloop_card * card, unsigned char c)
+isdnloop_putmsg(isdnloop_card *card, unsigned char c)
 {
 	ulong flags;
 
@@ -335,7 +335,7 @@ isdnloop_polldchan(unsigned long data)
 			card->imsg[card->iptr] = 0;
 			card->iptr = 0;
 			if (card->imsg[0] == '0' && card->imsg[1] >= '0' &&
-			  card->imsg[1] <= '2' && card->imsg[2] == ';') {
+			    card->imsg[1] <= '2' && card->imsg[2] == ';') {
 				ch = (card->imsg[1] - '0') - 1;
 				p = &card->imsg[3];
 				isdnloop_parse_status(p, ch, card);
@@ -397,7 +397,7 @@ isdnloop_polldchan(unsigned long data)
  *   Number of bytes transferred, -E??? on error
  */
 static int
-isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card)
+isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card *card)
 {
 	int len = skb->len;
 	unsigned long flags;
@@ -440,7 +440,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card * card)
  *   number of bytes actually transferred.
  */
 static int
-isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card * card)
+isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card *card)
 {
 	int count;
 	u_char __user *p;
@@ -468,7 +468,7 @@ isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card * card)
  *   0 on success, 1 on memory squeeze.
  */
 static int
-isdnloop_fake(isdnloop_card * card, char *s, int ch)
+isdnloop_fake(isdnloop_card *card, char *s, int ch)
 {
 	struct sk_buff *skb;
 	int len = strlen(s) + ((ch >= 0) ? 3 : 0);
@@ -517,7 +517,7 @@ static isdnloop_stat isdnloop_cmd_table[] =
  *   card = pointer to card struct.
  */
 static void
-isdnloop_fake_err(isdnloop_card * card)
+isdnloop_fake_err(isdnloop_card *card)
 {
 	char buf[60];
 
@@ -543,19 +543,19 @@ static u_char ctable_1t[] =
  *   Pointer to buffer containing the assembled message.
  */
 static char *
-isdnloop_unicause(isdnloop_card * card, int loc, int cau)
+isdnloop_unicause(isdnloop_card *card, int loc, int cau)
 {
 	static char buf[6];
 
 	switch (card->ptype) {
-		case ISDN_PTYPE_EURO:
-			sprintf(buf, "E%02X%02X", (loc) ? 4 : 2, ctable_eu[cau]);
-			break;
-		case ISDN_PTYPE_1TR6:
-			sprintf(buf, "%02X44", ctable_1t[cau]);
-			break;
-		default:
-			return ("0000");
+	case ISDN_PTYPE_EURO:
+		sprintf(buf, "E%02X%02X", (loc) ? 4 : 2, ctable_eu[cau]);
+		break;
+	case ISDN_PTYPE_1TR6:
+		sprintf(buf, "%02X44", ctable_1t[cau]);
+		break;
+	default:
+		return ("0000");
 	}
 	return (buf);
 }
@@ -569,7 +569,7 @@ isdnloop_unicause(isdnloop_card * card, int loc, int cau)
  *   ch   = channel (0-based)
  */
 static void
-isdnloop_atimeout(isdnloop_card * card, int ch)
+isdnloop_atimeout(isdnloop_card *card, int ch)
 {
 	unsigned long flags;
 	char buf[60];
@@ -615,7 +615,7 @@ isdnloop_atimeout1(unsigned long data)
  *   ch   = channel to watch for.
  */
 static void
-isdnloop_start_ctimer(isdnloop_card * card, int ch)
+isdnloop_start_ctimer(isdnloop_card *card, int ch)
 {
 	unsigned long flags;
 
@@ -639,7 +639,7 @@ isdnloop_start_ctimer(isdnloop_card * card, int ch)
  *   ch   = channel (0-based).
  */
 static void
-isdnloop_kill_ctimer(isdnloop_card * card, int ch)
+isdnloop_kill_ctimer(isdnloop_card *card, int ch)
 {
 	unsigned long flags;
 
@@ -668,7 +668,7 @@ static u_char bit2si[] =
  *   3 = found matching number but SI does not match.
  */
 static int
-isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
+isdnloop_try_call(isdnloop_card *card, char *p, int lch, isdn_ctrl *cmd)
 {
 	isdnloop_card *cc = cards;
 	unsigned long flags;
@@ -686,19 +686,19 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
 				continue;
 			num_match = 0;
 			switch (cc->ptype) {
-				case ISDN_PTYPE_EURO:
-					for (i = 0; i < 3; i++)
-						if (!(strcmp(cc->s0num[i], cmd->parm.setup.phone)))
-							num_match = 1;
-					break;
-				case ISDN_PTYPE_1TR6:
-					e = cc->eazlist[ch];
-					while (*e) {
-						sprintf(nbuf, "%s%c", cc->s0num[0], *e);
-						if (!(strcmp(nbuf, cmd->parm.setup.phone)))
-							num_match = 1;
-						e++;
-					}
+			case ISDN_PTYPE_EURO:
+				for (i = 0; i < 3; i++)
+					if (!(strcmp(cc->s0num[i], cmd->parm.setup.phone)))
+						num_match = 1;
+				break;
+			case ISDN_PTYPE_1TR6:
+				e = cc->eazlist[ch];
+				while (*e) {
+					sprintf(nbuf, "%s%c", cc->s0num[0], *e);
+					if (!(strcmp(nbuf, cmd->parm.setup.phone)))
+						num_match = 1;
+					e++;
+				}
 			}
 			if (num_match) {
 				spin_lock_irqsave(&card->isdnloop_lock, flags);
@@ -741,7 +741,7 @@ isdnloop_try_call(isdnloop_card * card, char *p, int lch, isdn_ctrl * cmd)
  *   pointer to new phone number.
  */
 static char *
-isdnloop_vstphone(isdnloop_card * card, char *phone, int caller)
+isdnloop_vstphone(isdnloop_card *card, char *phone, int caller)
 {
 	int i;
 	static char nphone[30];
@@ -751,22 +751,22 @@ isdnloop_vstphone(isdnloop_card * card, char *phone, int caller)
 		return "";
 	}
 	switch (card->ptype) {
-		case ISDN_PTYPE_EURO:
-			if (caller) {
-				for (i = 0; i < 2; i++)
-					if (!(strcmp(card->s0num[i], phone)))
-						return (phone);
-				return (card->s0num[0]);
-			}
-			return (phone);
-			break;
-		case ISDN_PTYPE_1TR6:
-			if (caller) {
-				sprintf(nphone, "%s%c", card->s0num[0], phone[0]);
-				return (nphone);
-			} else
-				return (&phone[strlen(phone) - 1]);
-			break;
+	case ISDN_PTYPE_EURO:
+		if (caller) {
+			for (i = 0; i < 2; i++)
+				if (!(strcmp(card->s0num[i], phone)))
+					return (phone);
+			return (card->s0num[0]);
+		}
+		return (phone);
+		break;
+	case ISDN_PTYPE_1TR6:
+		if (caller) {
+			sprintf(nphone, "%s%c", card->s0num[0], phone[0]);
+			return (nphone);
+		} else
+			return (&phone[strlen(phone) - 1]);
+		break;
 	}
 	return "";
 }
@@ -779,7 +779,7 @@ isdnloop_vstphone(isdnloop_card * card, char *phone, int caller)
  *   card = pointer to card struct.
  */
 static void
-isdnloop_parse_cmd(isdnloop_card * card)
+isdnloop_parse_cmd(isdnloop_card *card)
 {
 	char *p = card->omsg;
 	isdn_ctrl cmd;
@@ -813,141 +813,141 @@ isdnloop_parse_cmd(isdnloop_card * card)
 	if (action == -1)
 		return;
 	switch (action) {
-		case 1:
-			/* 0x;BCON_R */
-			if (card->rcard[ch - 1]) {
-				isdnloop_fake(card->rcard[ch - 1], "BCON_I",
-					      card->rch[ch - 1] + 1);
-				isdnloop_fake(card, "BCON_C", ch);
-			}
-			break;
-		case 17:
-			/* 0x;BCON_I */
-			if (card->rcard[ch - 1]) {
-				isdnloop_fake(card->rcard[ch - 1], "BCON_C",
-					      card->rch[ch - 1] + 1);
-			}
-			break;
-		case 2:
-			/* 0x;BDIS_R */
-			isdnloop_fake(card, "BDIS_C", ch);
-			if (card->rcard[ch - 1]) {
-				isdnloop_fake(card->rcard[ch - 1], "BDIS_I",
-					      card->rch[ch - 1] + 1);
-			}
-			break;
-		case 16:
-			/* 0x;DCON_R */
-			isdnloop_kill_ctimer(card, ch - 1);
-			if (card->rcard[ch - 1]) {
-				isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
-				isdnloop_fake(card->rcard[ch - 1], "DCON_C",
-					      card->rch[ch - 1] + 1);
-				isdnloop_fake(card, "DCON_C", ch);
-			}
-			break;
-		case 3:
-			/* 0x;DDIS_R */
-			isdnloop_kill_ctimer(card, ch - 1);
-			if (card->rcard[ch - 1]) {
-				isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
-				isdnloop_fake(card->rcard[ch - 1], "DDIS_I",
-					      card->rch[ch - 1] + 1);
-				card->rcard[ch - 1] = NULL;
-			}
-			isdnloop_fake(card, "DDIS_C", ch);
-			break;
-		case 4:
-			/* 0x;DSCA_Rdd,yy,zz,oo */
-			if (card->ptype != ISDN_PTYPE_1TR6) {
-				isdnloop_fake_err(card);
-				return;
-			}
+	case 1:
+		/* 0x;BCON_R */
+		if (card->rcard[ch - 1]) {
+			isdnloop_fake(card->rcard[ch - 1], "BCON_I",
+				      card->rch[ch - 1] + 1);
+			isdnloop_fake(card, "BCON_C", ch);
+		}
+		break;
+	case 17:
+		/* 0x;BCON_I */
+		if (card->rcard[ch - 1]) {
+			isdnloop_fake(card->rcard[ch - 1], "BCON_C",
+				      card->rch[ch - 1] + 1);
+		}
+		break;
+	case 2:
+		/* 0x;BDIS_R */
+		isdnloop_fake(card, "BDIS_C", ch);
+		if (card->rcard[ch - 1]) {
+			isdnloop_fake(card->rcard[ch - 1], "BDIS_I",
+				      card->rch[ch - 1] + 1);
+		}
+		break;
+	case 16:
+		/* 0x;DCON_R */
+		isdnloop_kill_ctimer(card, ch - 1);
+		if (card->rcard[ch - 1]) {
+			isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
+			isdnloop_fake(card->rcard[ch - 1], "DCON_C",
+				      card->rch[ch - 1] + 1);
+			isdnloop_fake(card, "DCON_C", ch);
+		}
+		break;
+	case 3:
+		/* 0x;DDIS_R */
+		isdnloop_kill_ctimer(card, ch - 1);
+		if (card->rcard[ch - 1]) {
+			isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
+			isdnloop_fake(card->rcard[ch - 1], "DDIS_I",
+				      card->rch[ch - 1] + 1);
+			card->rcard[ch - 1] = NULL;
+		}
+		isdnloop_fake(card, "DDIS_C", ch);
+		break;
+	case 4:
+		/* 0x;DSCA_Rdd,yy,zz,oo */
+		if (card->ptype != ISDN_PTYPE_1TR6) {
+			isdnloop_fake_err(card);
+			return;
+		}
+		/* Fall through */
+	case 5:
+		/* 0x;DCAL_Rdd,yy,zz,oo */
+		p += 6;
+		switch (isdnloop_try_call(card, p, ch - 1, &cmd)) {
+		case 0:
+			/* Alerting */
+			sprintf(buf, "D%s_I%s,%02d,%02d,%s",
+				(action == 4) ? "SCA" : "CAL",
+				isdnloop_vstphone(card, cmd.parm.setup.eazmsn, 1),
+				cmd.parm.setup.si1,
+				cmd.parm.setup.si2,
+				isdnloop_vstphone(card->rcard[ch - 1],
+						  cmd.parm.setup.phone, 0));
+			isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
 			/* Fall through */
-		case 5:
-			/* 0x;DCAL_Rdd,yy,zz,oo */
-			p += 6;
-			switch (isdnloop_try_call(card, p, ch - 1, &cmd)) {
-				case 0:
-					/* Alerting */
-					sprintf(buf, "D%s_I%s,%02d,%02d,%s",
-					   (action == 4) ? "SCA" : "CAL",
-						isdnloop_vstphone(card, cmd.parm.setup.eazmsn, 1),
-						cmd.parm.setup.si1,
-						cmd.parm.setup.si2,
-					isdnloop_vstphone(card->rcard[ch - 1],
-					       cmd.parm.setup.phone, 0));
-					isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
-					/* Fall through */
-				case 3:
-					/* si1 does not match, don't alert but start timer */
-					isdnloop_start_ctimer(card, ch - 1);
-					break;
-				case 1:
-					/* Remote busy */
-					isdnloop_fake(card, "DDIS_I", ch);
-					sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 1));
-					isdnloop_fake(card, buf, ch);
-					break;
-				case 2:
-					/* No such user */
-					isdnloop_fake(card, "DDIS_I", ch);
-					sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 2));
-					isdnloop_fake(card, buf, ch);
-					break;
-			}
-			break;
-		case 6:
-			/* 0x;EAZC */
-			card->eazlist[ch - 1][0] = '\0';
-			break;
-		case 7:
-			/* 0x;EAZ */
-			p += 3;
-			strcpy(card->eazlist[ch - 1], p);
-			break;
-		case 8:
-			/* 0x;SEEAZ */
-			sprintf(buf, "EAZ-LIST: %s", card->eazlist[ch - 1]);
-			isdnloop_fake(card, buf, ch + 1);
-			break;
-		case 9:
-			/* 0x;MSN */
-			break;
-		case 10:
-			/* 0x;MSNALL */
-			break;
-		case 11:
-			/* 0x;SETSIL */
-			p += 6;
-			i = 0;
-			while (strchr("0157", *p)) {
-				if (i)
-					card->sil[ch - 1] |= si2bit[*p - '0'];
-				i = (*p++ == '0');
-			}
-			if (*p)
-				isdnloop_fake_err(card);
-			break;
-		case 12:
-			/* 0x;SEESIL */
-			sprintf(buf, "SIN-LIST: ");
-			p = buf + 10;
-			for (i = 0; i < 3; i++)
-				if (card->sil[ch - 1] & (1 << i))
-					p += sprintf(p, "%02d", bit2si[i]);
-			isdnloop_fake(card, buf, ch + 1);
-			break;
-		case 13:
-			/* 0x;SILC */
-			card->sil[ch - 1] = 0;
+		case 3:
+			/* si1 does not match, don't alert but start timer */
+			isdnloop_start_ctimer(card, ch - 1);
 			break;
-		case 14:
-			/* 00;FV2ON */
+		case 1:
+			/* Remote busy */
+			isdnloop_fake(card, "DDIS_I", ch);
+			sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 1));
+			isdnloop_fake(card, buf, ch);
 			break;
-		case 15:
-			/* 00;FV2OFF */
+		case 2:
+			/* No such user */
+			isdnloop_fake(card, "DDIS_I", ch);
+			sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 2));
+			isdnloop_fake(card, buf, ch);
 			break;
+		}
+		break;
+	case 6:
+		/* 0x;EAZC */
+		card->eazlist[ch - 1][0] = '\0';
+		break;
+	case 7:
+		/* 0x;EAZ */
+		p += 3;
+		strcpy(card->eazlist[ch - 1], p);
+		break;
+	case 8:
+		/* 0x;SEEAZ */
+		sprintf(buf, "EAZ-LIST: %s", card->eazlist[ch - 1]);
+		isdnloop_fake(card, buf, ch + 1);
+		break;
+	case 9:
+		/* 0x;MSN */
+		break;
+	case 10:
+		/* 0x;MSNALL */
+		break;
+	case 11:
+		/* 0x;SETSIL */
+		p += 6;
+		i = 0;
+		while (strchr("0157", *p)) {
+			if (i)
+				card->sil[ch - 1] |= si2bit[*p - '0'];
+			i = (*p++ == '0');
+		}
+		if (*p)
+			isdnloop_fake_err(card);
+		break;
+	case 12:
+		/* 0x;SEESIL */
+		sprintf(buf, "SIN-LIST: ");
+		p = buf + 10;
+		for (i = 0; i < 3; i++)
+			if (card->sil[ch - 1] & (1 << i))
+				p += sprintf(p, "%02d", bit2si[i]);
+		isdnloop_fake(card, buf, ch + 1);
+		break;
+	case 13:
+		/* 0x;SILC */
+		card->sil[ch - 1] = 0;
+		break;
+	case 14:
+		/* 00;FV2ON */
+		break;
+	case 15:
+		/* 00;FV2OFF */
+		break;
 	}
 }
 
@@ -966,7 +966,7 @@ isdnloop_parse_cmd(isdnloop_card * card)
  *   number of bytes transferred (currently always equals len).
  */
 static int
-isdnloop_writecmd(const u_char * buf, int len, int user, isdnloop_card * card)
+isdnloop_writecmd(const u_char *buf, int len, int user, isdnloop_card *card)
 {
 	int xcount = 0;
 	int ocount = 1;
@@ -1016,7 +1016,7 @@ isdnloop_writecmd(const u_char * buf, int len, int user, isdnloop_card * card)
  * Delete card's pending timers, send STOP to linklevel
  */
 static void
-isdnloop_stopcard(isdnloop_card * card)
+isdnloop_stopcard(isdnloop_card *card)
 {
 	unsigned long flags;
 	isdn_ctrl cmd;
@@ -1061,7 +1061,7 @@ isdnloop_stopallcards(void)
  *   0 on success, -E??? otherwise.
  */
 static int
-isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
+isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
 {
 	unsigned long flags;
 	isdnloop_sdef sdef;
@@ -1073,40 +1073,40 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
 		return -EFAULT;
 	spin_lock_irqsave(&card->isdnloop_lock, flags);
 	switch (sdef.ptype) {
-		case ISDN_PTYPE_EURO:
-			if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96",
-					  -1)) {
-				spin_unlock_irqrestore(&card->isdnloop_lock, flags);
-				return -ENOMEM;
-			}
-			card->sil[0] = card->sil[1] = 4;
-			if (isdnloop_fake(card, "TEI OK", 0)) {
-				spin_unlock_irqrestore(&card->isdnloop_lock, flags);
-				return -ENOMEM;
-			}
-			for (i = 0; i < 3; i++)
-				strcpy(card->s0num[i], sdef.num[i]);
-			break;
-		case ISDN_PTYPE_1TR6:
-			if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
-					  -1)) {
-				spin_unlock_irqrestore(&card->isdnloop_lock, flags);
-				return -ENOMEM;
-			}
-			card->sil[0] = card->sil[1] = 4;
-			if (isdnloop_fake(card, "TEI OK", 0)) {
-				spin_unlock_irqrestore(&card->isdnloop_lock, flags);
-				return -ENOMEM;
-			}
-			strcpy(card->s0num[0], sdef.num[0]);
-			card->s0num[1][0] = '\0';
-			card->s0num[2][0] = '\0';
-			break;
-		default:
+	case ISDN_PTYPE_EURO:
+		if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96",
+				  -1)) {
 			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
-			printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n",
-			       sdef.ptype);
-			return -EINVAL;
+			return -ENOMEM;
+		}
+		card->sil[0] = card->sil[1] = 4;
+		if (isdnloop_fake(card, "TEI OK", 0)) {
+			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+			return -ENOMEM;
+		}
+		for (i = 0; i < 3; i++)
+			strcpy(card->s0num[i], sdef.num[i]);
+		break;
+	case ISDN_PTYPE_1TR6:
+		if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
+				  -1)) {
+			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+			return -ENOMEM;
+		}
+		card->sil[0] = card->sil[1] = 4;
+		if (isdnloop_fake(card, "TEI OK", 0)) {
+			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+			return -ENOMEM;
+		}
+		strcpy(card->s0num[0], sdef.num[0]);
+		card->s0num[1][0] = '\0';
+		card->s0num[2][0] = '\0';
+		break;
+	default:
+		spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+		printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n",
+		       sdef.ptype);
+		return -EINVAL;
 	}
 	init_timer(&card->st_timer);
 	card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD;
@@ -1122,7 +1122,7 @@ isdnloop_start(isdnloop_card * card, isdnloop_sdef * sdefp)
  * Main handler for commands sent by linklevel.
  */
 static int
-isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
+isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
 {
 	ulong a;
 	int i;
@@ -1131,215 +1131,215 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
 	isdnloop_cdef cdef;
 
 	switch (c->command) {
-		case ISDN_CMD_IOCTL:
-			memcpy(&a, c->parm.num, sizeof(ulong));
-			switch (c->arg) {
-				case ISDNLOOP_IOCTL_DEBUGVAR:
-					return (ulong) card;
-				case ISDNLOOP_IOCTL_STARTUP:
-					if (!access_ok(VERIFY_READ, (void *) a, sizeof(isdnloop_sdef)))
-						return -EFAULT;
-					return (isdnloop_start(card, (isdnloop_sdef *) a));
-					break;
-				case ISDNLOOP_IOCTL_ADDCARD:
-					if (copy_from_user((char *)&cdef,
-							   (char *)a,
-							   sizeof(cdef)))
-						return -EFAULT;
-					return (isdnloop_addcard(cdef.id1));
-					break;
-				case ISDNLOOP_IOCTL_LEASEDCFG:
-					if (a) {
-						if (!card->leased) {
-							card->leased = 1;
-							while (card->ptype == ISDN_PTYPE_UNKNOWN)
-								schedule_timeout_interruptible(10);
-							schedule_timeout_interruptible(10);
-							sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
-							i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-							printk(KERN_INFO
-							       "isdnloop: (%s) Leased-line mode enabled\n",
-							       CID);
-							cmd.command = ISDN_STAT_RUN;
-							cmd.driver = card->myid;
-							cmd.arg = 0;
-							card->interface.statcallb(&cmd);
-						}
-					} else {
-						if (card->leased) {
-							card->leased = 0;
-							sprintf(cbuf, "00;FV2OFF\n");
-							i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-							printk(KERN_INFO
-							       "isdnloop: (%s) Leased-line mode disabled\n",
-							       CID);
-							cmd.command = ISDN_STAT_RUN;
-							cmd.driver = card->myid;
-							cmd.arg = 0;
-							card->interface.statcallb(&cmd);
-						}
-					}
-					return 0;
-				default:
-					return -EINVAL;
+	case ISDN_CMD_IOCTL:
+		memcpy(&a, c->parm.num, sizeof(ulong));
+		switch (c->arg) {
+		case ISDNLOOP_IOCTL_DEBUGVAR:
+			return (ulong) card;
+		case ISDNLOOP_IOCTL_STARTUP:
+			if (!access_ok(VERIFY_READ, (void *) a, sizeof(isdnloop_sdef)))
+				return -EFAULT;
+			return (isdnloop_start(card, (isdnloop_sdef *) a));
+			break;
+		case ISDNLOOP_IOCTL_ADDCARD:
+			if (copy_from_user((char *)&cdef,
+					   (char *)a,
+					   sizeof(cdef)))
+				return -EFAULT;
+			return (isdnloop_addcard(cdef.id1));
+			break;
+		case ISDNLOOP_IOCTL_LEASEDCFG:
+			if (a) {
+				if (!card->leased) {
+					card->leased = 1;
+					while (card->ptype == ISDN_PTYPE_UNKNOWN)
+						schedule_timeout_interruptible(10);
+					schedule_timeout_interruptible(10);
+					sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
+					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+					printk(KERN_INFO
+					       "isdnloop: (%s) Leased-line mode enabled\n",
+					       CID);
+					cmd.command = ISDN_STAT_RUN;
+					cmd.driver = card->myid;
+					cmd.arg = 0;
+					card->interface.statcallb(&cmd);
+				}
+			} else {
+				if (card->leased) {
+					card->leased = 0;
+					sprintf(cbuf, "00;FV2OFF\n");
+					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+					printk(KERN_INFO
+					       "isdnloop: (%s) Leased-line mode disabled\n",
+					       CID);
+					cmd.command = ISDN_STAT_RUN;
+					cmd.driver = card->myid;
+					cmd.arg = 0;
+					card->interface.statcallb(&cmd);
+				}
 			}
+			return 0;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case ISDN_CMD_DIAL:
+		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+			return -ENODEV;
+		if (card->leased)
 			break;
-		case ISDN_CMD_DIAL:
-			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
-				return -ENODEV;
-			if (card->leased)
-				break;
-			if ((c->arg & 255) < ISDNLOOP_BCH) {
-				char *p;
-				char dial[50];
-				char dcode[4];
-
-				a = c->arg;
-				p = c->parm.setup.phone;
-				if (*p == 's' || *p == 'S') {
-					/* Dial for SPV */
-					p++;
-					strcpy(dcode, "SCA");
-				} else
-					/* Normal Dial */
-					strcpy(dcode, "CAL");
-				strcpy(dial, p);
-				sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
-					dcode, dial, c->parm.setup.si1,
+		if ((c->arg & 255) < ISDNLOOP_BCH) {
+			char *p;
+			char dial[50];
+			char dcode[4];
+
+			a = c->arg;
+			p = c->parm.setup.phone;
+			if (*p == 's' || *p == 'S') {
+				/* Dial for SPV */
+				p++;
+				strcpy(dcode, "SCA");
+			} else
+				/* Normal Dial */
+				strcpy(dcode, "CAL");
+			strcpy(dial, p);
+			sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
+				dcode, dial, c->parm.setup.si1,
 				c->parm.setup.si2, c->parm.setup.eazmsn);
+			i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_ACCEPTD:
+		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+			return -ENODEV;
+		if (c->arg < ISDNLOOP_BCH) {
+			a = c->arg + 1;
+			cbuf[0] = 0;
+			switch (card->l2_proto[a - 1]) {
+			case ISDN_PROTO_L2_X75I:
+				sprintf(cbuf, "%02d;BX75\n", (int) a);
+				break;
+#ifdef CONFIG_ISDN_X25
+			case ISDN_PROTO_L2_X25DTE:
+				sprintf(cbuf, "%02d;BX2T\n", (int) a);
+				break;
+			case ISDN_PROTO_L2_X25DCE:
+				sprintf(cbuf, "%02d;BX2C\n", (int) a);
+				break;
+#endif
+			case ISDN_PROTO_L2_HDLC:
+				sprintf(cbuf, "%02d;BTRA\n", (int) a);
+				break;
+			}
+			if (strlen(cbuf))
 				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+			sprintf(cbuf, "%02d;DCON_R\n", (int) a);
+			i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+		}
+		break;
+	case ISDN_CMD_ACCEPTB:
+		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+			return -ENODEV;
+		if (c->arg < ISDNLOOP_BCH) {
+			a = c->arg + 1;
+			switch (card->l2_proto[a - 1]) {
+			case ISDN_PROTO_L2_X75I:
+				sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
+				break;
+#ifdef CONFIG_ISDN_X25
+			case ISDN_PROTO_L2_X25DTE:
+				sprintf(cbuf, "%02d;BCON_R,BX2T\n", (int) a);
+				break;
+			case ISDN_PROTO_L2_X25DCE:
+				sprintf(cbuf, "%02d;BCON_R,BX2C\n", (int) a);
+				break;
+#endif
+			case ISDN_PROTO_L2_HDLC:
+				sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
+				break;
+			default:
+				sprintf(cbuf, "%02d;BCON_R\n", (int) a);
 			}
+			printk(KERN_DEBUG "isdnloop writecmd '%s'\n", cbuf);
+			i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
 			break;
-		case ISDN_CMD_ACCEPTD:
+		case ISDN_CMD_HANGUP:
 			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
 				return -ENODEV;
 			if (c->arg < ISDNLOOP_BCH) {
 				a = c->arg + 1;
-				cbuf[0] = 0;
-				switch (card->l2_proto[a - 1]) {
-					case ISDN_PROTO_L2_X75I:
-						sprintf(cbuf, "%02d;BX75\n", (int) a);
-						break;
-#ifdef CONFIG_ISDN_X25
-					case ISDN_PROTO_L2_X25DTE:
-						sprintf(cbuf, "%02d;BX2T\n", (int) a);
-						break;
-					case ISDN_PROTO_L2_X25DCE:
-						sprintf(cbuf, "%02d;BX2C\n", (int) a);
-						break;
-#endif
-					case ISDN_PROTO_L2_HDLC:
-						sprintf(cbuf, "%02d;BTRA\n", (int) a);
-						break;
-				}
-				if (strlen(cbuf))
-					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-				sprintf(cbuf, "%02d;DCON_R\n", (int) a);
+				sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
 				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
 			}
 			break;
-		case ISDN_CMD_ACCEPTB:
+		case ISDN_CMD_SETEAZ:
 			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
 				return -ENODEV;
+			if (card->leased)
+				break;
 			if (c->arg < ISDNLOOP_BCH) {
 				a = c->arg + 1;
-				switch (card->l2_proto[a - 1]) {
-					case ISDN_PROTO_L2_X75I:
-						sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
-						break;
-#ifdef CONFIG_ISDN_X25
-					case ISDN_PROTO_L2_X25DTE:
-						sprintf(cbuf, "%02d;BCON_R,BX2T\n", (int) a);
-						break;
-					case ISDN_PROTO_L2_X25DCE:
-						sprintf(cbuf, "%02d;BCON_R,BX2C\n", (int) a);
-						break;
-#endif
-					case ISDN_PROTO_L2_HDLC:
-						sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
-						break;
-					default:
-						sprintf(cbuf, "%02d;BCON_R\n", (int) a);
-				}
-				printk(KERN_DEBUG "isdnloop writecmd '%s'\n", cbuf);
+				if (card->ptype == ISDN_PTYPE_EURO) {
+					sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
+						c->parm.num[0] ? "N" : "ALL", c->parm.num);
+				} else
+					sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
+						c->parm.num[0] ? c->parm.num : (u_char *) "0123456789");
 				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-				break;
-		case ISDN_CMD_HANGUP:
-				if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
-					return -ENODEV;
-				if (c->arg < ISDNLOOP_BCH) {
-					a = c->arg + 1;
-					sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
-					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-				}
-				break;
-		case ISDN_CMD_SETEAZ:
-				if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
-					return -ENODEV;
-				if (card->leased)
-					break;
-				if (c->arg < ISDNLOOP_BCH) {
-					a = c->arg + 1;
-					if (card->ptype == ISDN_PTYPE_EURO) {
-						sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
-							c->parm.num[0] ? "N" : "ALL", c->parm.num);
-					} else
-						sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
-							c->parm.num[0] ? c->parm.num : (u_char *) "0123456789");
-					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-				}
-				break;
+			}
+			break;
 		case ISDN_CMD_CLREAZ:
-				if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
-					return -ENODEV;
-				if (card->leased)
-					break;
-				if (c->arg < ISDNLOOP_BCH) {
-					a = c->arg + 1;
-					if (card->ptype == ISDN_PTYPE_EURO)
-						sprintf(cbuf, "%02d;MSNC\n", (int) a);
-					else
-						sprintf(cbuf, "%02d;EAZC\n", (int) a);
-					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-				}
+			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+				return -ENODEV;
+			if (card->leased)
 				break;
+			if (c->arg < ISDNLOOP_BCH) {
+				a = c->arg + 1;
+				if (card->ptype == ISDN_PTYPE_EURO)
+					sprintf(cbuf, "%02d;MSNC\n", (int) a);
+				else
+					sprintf(cbuf, "%02d;EAZC\n", (int) a);
+				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+			}
+			break;
 		case ISDN_CMD_SETL2:
-				if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
-					return -ENODEV;
-				if ((c->arg & 255) < ISDNLOOP_BCH) {
-					a = c->arg;
-					switch (a >> 8) {
-						case ISDN_PROTO_L2_X75I:
-							sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
-							break;
+			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+				return -ENODEV;
+			if ((c->arg & 255) < ISDNLOOP_BCH) {
+				a = c->arg;
+				switch (a >> 8) {
+				case ISDN_PROTO_L2_X75I:
+					sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
+					break;
 #ifdef CONFIG_ISDN_X25
-						case ISDN_PROTO_L2_X25DTE:
-							sprintf(cbuf, "%02d;BX2T\n", (int) (a & 255) + 1);
-							break;
-						case ISDN_PROTO_L2_X25DCE:
-							sprintf(cbuf, "%02d;BX2C\n", (int) (a & 255) + 1);
-							break;
+				case ISDN_PROTO_L2_X25DTE:
+					sprintf(cbuf, "%02d;BX2T\n", (int) (a & 255) + 1);
+					break;
+				case ISDN_PROTO_L2_X25DCE:
+					sprintf(cbuf, "%02d;BX2C\n", (int) (a & 255) + 1);
+					break;
 #endif
-						case ISDN_PROTO_L2_HDLC:
-							sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
-							break;
-						case ISDN_PROTO_L2_TRANS:
-							sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
-							break;
-						default:
-							return -EINVAL;
-					}
-					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
-					card->l2_proto[a & 255] = (a >> 8);
+				case ISDN_PROTO_L2_HDLC:
+					sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
+					break;
+				case ISDN_PROTO_L2_TRANS:
+					sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
+					break;
+				default:
+					return -EINVAL;
 				}
-				break;
+				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
+				card->l2_proto[a & 255] = (a >> 8);
+			}
+			break;
 		case ISDN_CMD_SETL3:
-				if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
-					return -ENODEV;
-				return 0;
+			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
+				return -ENODEV;
+			return 0;
 		default:
-				return -EINVAL;
-			}
+			return -EINVAL;
+		}
 	}
 	return 0;
 }
@@ -1364,7 +1364,7 @@ isdnloop_findcard(int driverid)
  * Wrapper functions for interface to linklevel
  */
 static int
-if_command(isdn_ctrl * c)
+if_command(isdn_ctrl *c)
 {
 	isdnloop_card *card = isdnloop_findcard(c->driver);
 
@@ -1434,12 +1434,12 @@ isdnloop_initcard(char *id)
 
 	if (!(card = kzalloc(sizeof(isdnloop_card), GFP_KERNEL))) {
 		printk(KERN_WARNING
-		 "isdnloop: (%s) Could not allocate card-struct.\n", id);
+		       "isdnloop: (%s) Could not allocate card-struct.\n", id);
 		return (isdnloop_card *) 0;
 	}
 	card->interface.owner = THIS_MODULE;
 	card->interface.channels = ISDNLOOP_BCH;
-	card->interface.hl_hdrlen  = 1; /* scratch area for storing ack flag*/ 
+	card->interface.hl_hdrlen  = 1; /* scratch area for storing ack flag*/
 	card->interface.maxbufsize = 4000;
 	card->interface.command = if_command;
 	card->interface.writebuf_skb = if_sendbuf;
@@ -1447,12 +1447,12 @@ isdnloop_initcard(char *id)
 	card->interface.readstat = if_readstatus;
 	card->interface.features = ISDN_FEATURE_L2_X75I |
 #ifdef CONFIG_ISDN_X25
-	    ISDN_FEATURE_L2_X25DTE |
-	    ISDN_FEATURE_L2_X25DCE |
+		ISDN_FEATURE_L2_X25DTE |
+		ISDN_FEATURE_L2_X25DCE |
 #endif
-	    ISDN_FEATURE_L2_HDLC |
-	    ISDN_FEATURE_L3_TRANS |
-	    ISDN_FEATURE_P_UNKNOWN;
+		ISDN_FEATURE_L2_HDLC |
+		ISDN_FEATURE_L3_TRANS |
+		ISDN_FEATURE_P_UNKNOWN;
 	card->ptype = ISDN_PTYPE_UNKNOWN;
 	strlcpy(card->interface.id, id, sizeof(card->interface.id));
 	card->msg_buf_write = card->msg_buf;
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index 0d458a8..e9e0355 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -55,7 +55,7 @@ typedef struct isdnloop_sdef {
 #define ISDNLOOP_FLAGS_RBTIMER  8	/* scheduling of B-Channel-poll  */
 #define ISDNLOOP_TIMER_BCREAD 1 /* B-Channel poll-cycle          */
 #define ISDNLOOP_TIMER_DCREAD (HZ/2)	/* D-Channel poll-cycle          */
-#define ISDNLOOP_TIMER_ALERTWAIT (10*HZ)	/* Alert timeout                 */
+#define ISDNLOOP_TIMER_ALERTWAIT (10 * HZ)	/* Alert timeout                 */
 #define ISDNLOOP_MAX_SQUEUE 65536	/* Max. outstanding send-data    */
 #define ISDNLOOP_BCH 2          /* channels per card             */
 
@@ -79,7 +79,7 @@ typedef struct isdnloop_card {
 	struct timer_list st_timer;	/* Timer for Status-Polls           */
 	struct timer_list rb_timer;	/* Timer for B-Channel-Polls        */
 	struct timer_list
-	 c_timer[ISDNLOOP_BCH]; /* Timer for Alerting               */
+	c_timer[ISDNLOOP_BCH]; /* Timer for Alerting               */
 	int l2_proto[ISDNLOOP_BCH];	/* Current layer-2-protocol         */
 	isdn_if interface;      /* Interface to upper layer         */
 	int iptr;               /* Index to imsg-buffer             */
@@ -92,7 +92,7 @@ typedef struct isdnloop_card {
 	char *msg_buf_end;      /* Pointer to end of statusbuffer   */
 	int sndcount[ISDNLOOP_BCH];	/* Byte-counters for B-Ch.-send     */
 	struct sk_buff_head
-	 bqueue[ISDNLOOP_BCH];  /* B-Channel queues                 */
+	bqueue[ISDNLOOP_BCH];  /* B-Channel queues                 */
 	struct sk_buff_head dqueue;	/* D-Channel queue                  */
 	spinlock_t isdnloop_lock;
 } isdnloop_card;
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
index 7418f2d..693fb7c 100644
--- a/drivers/isdn/mISDN/clock.c
+++ b/drivers/isdn/mISDN/clock.c
@@ -13,11 +13,11 @@
  * Quick API description:
  *
  * A clock source registers using mISDN_register_clock:
- * 	name = text string to name clock source
+ *	name = text string to name clock source
  *	priority = value to priorize clock sources (0 = default)
  *	ctl = callback function to enable/disable clock source
  *	priv = private pointer of clock source
- * 	return = pointer to clock source structure;
+ *	return = pointer to clock source structure;
  *
  * Note: Callback 'ctl' can be called before mISDN_register_clock returns!
  *       Also it can be called during mISDN_unregister_clock.
@@ -74,14 +74,14 @@ select_iclock(void)
 		/* last used clock source still exists but changes, disable */
 		if (*debug & DEBUG_CLOCK)
 			printk(KERN_DEBUG "Old clock source '%s' disable.\n",
-				lastclock->name);
+			       lastclock->name);
 		lastclock->ctl(lastclock->priv, 0);
 	}
 	if (bestclock && bestclock != iclock_current) {
 		/* new clock source selected, enable */
 		if (*debug & DEBUG_CLOCK)
 			printk(KERN_DEBUG "New clock source '%s' enable.\n",
-				bestclock->name);
+			       bestclock->name);
 		bestclock->ctl(bestclock->priv, 1);
 	}
 	if (bestclock != iclock_current) {
@@ -104,7 +104,7 @@ struct mISDNclock
 		printk(KERN_ERR "%s: No memory for clock entry.\n", __func__);
 		return NULL;
 	}
-	strncpy(iclock->name, name, sizeof(iclock->name)-1);
+	strncpy(iclock->name, name, sizeof(iclock->name) - 1);
 	iclock->pri = pri;
 	iclock->priv = priv;
 	iclock->ctl = ctl;
@@ -123,13 +123,13 @@ mISDN_unregister_clock(struct mISDNclock *iclock)
 
 	if (*debug & (DEBUG_CORE | DEBUG_CLOCK))
 		printk(KERN_DEBUG "%s: %s %d\n", __func__, iclock->name,
-			iclock->pri);
+		       iclock->pri);
 	write_lock_irqsave(&iclock_lock, flags);
 	if (iclock_current == iclock) {
 		if (*debug & DEBUG_CLOCK)
 			printk(KERN_DEBUG
-				"Current clock source '%s' unregisters.\n",
-				iclock->name);
+			       "Current clock source '%s' unregisters.\n",
+			       iclock->name);
 		iclock->ctl(iclock->priv, 0);
 	}
 	list_del(&iclock->list);
@@ -149,9 +149,9 @@ mISDN_clock_update(struct mISDNclock *iclock, int samples, struct timeval *tv)
 	write_lock_irqsave(&iclock_lock, flags);
 	if (iclock_current != iclock) {
 		printk(KERN_ERR "%s: '%s' sends us clock updates, but we do "
-			"listen to '%s'. This is a bug!\n", __func__,
-			iclock->name,
-			iclock_current ? iclock_current->name : "nothing");
+		       "listen to '%s'. This is a bug!\n", __func__,
+		       iclock->name,
+		       iclock_current ? iclock_current->name : "nothing");
 		iclock->ctl(iclock->priv, 0);
 		write_unlock_irqrestore(&iclock_lock, flags);
 		return;
@@ -185,7 +185,7 @@ mISDN_clock_update(struct mISDNclock *iclock, int samples, struct timeval *tv)
 		iclock_tv_valid = 1;
 		if (*debug & DEBUG_CLOCK)
 			printk("Received first clock from source '%s'.\n",
-			    iclock_current ? iclock_current->name : "nothing");
+			       iclock_current ? iclock_current->name : "nothing");
 	}
 	write_unlock_irqrestore(&iclock_lock, flags);
 }
@@ -215,4 +215,3 @@ mISDN_clock_get(void)
 	return count;
 }
 EXPORT_SYMBOL(mISDN_clock_get);
-
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
index afeebb0..a24530f 100644
--- a/drivers/isdn/mISDN/core.c
+++ b/drivers/isdn/mISDN/core.c
@@ -38,7 +38,7 @@ static void mISDN_dev_release(struct device *dev)
 }
 
 static ssize_t _show_id(struct device *dev,
-				struct device_attribute *attr, char *buf)
+			struct device_attribute *attr, char *buf)
 {
 	struct mISDNdevice *mdev = dev_to_mISDN(dev);
 
@@ -48,7 +48,7 @@ static ssize_t _show_id(struct device *dev,
 }
 
 static ssize_t _show_nrbchan(struct device *dev,
-				struct device_attribute *attr, char *buf)
+			     struct device_attribute *attr, char *buf)
 {
 	struct mISDNdevice *mdev = dev_to_mISDN(dev);
 
@@ -58,7 +58,7 @@ static ssize_t _show_nrbchan(struct device *dev,
 }
 
 static ssize_t _show_d_protocols(struct device *dev,
-				struct device_attribute *attr, char *buf)
+				 struct device_attribute *attr, char *buf)
 {
 	struct mISDNdevice *mdev = dev_to_mISDN(dev);
 
@@ -68,7 +68,7 @@ static ssize_t _show_d_protocols(struct device *dev,
 }
 
 static ssize_t _show_b_protocols(struct device *dev,
-				struct device_attribute *attr, char *buf)
+				 struct device_attribute *attr, char *buf)
 {
 	struct mISDNdevice *mdev = dev_to_mISDN(dev);
 
@@ -78,7 +78,7 @@ static ssize_t _show_b_protocols(struct device *dev,
 }
 
 static ssize_t _show_protocol(struct device *dev,
-				struct device_attribute *attr, char *buf)
+			      struct device_attribute *attr, char *buf)
 {
 	struct mISDNdevice *mdev = dev_to_mISDN(dev);
 
@@ -88,7 +88,7 @@ static ssize_t _show_protocol(struct device *dev,
 }
 
 static ssize_t _show_name(struct device *dev,
-				struct device_attribute *attr, char *buf)
+			  struct device_attribute *attr, char *buf)
 {
 	strcpy(buf, dev_name(dev));
 	return strlen(buf);
@@ -96,7 +96,7 @@ static ssize_t _show_name(struct device *dev,
 
 #if 0 /* hangs */
 static ssize_t _set_name(struct device *dev, struct device_attribute *attr,
-				const char *buf, size_t count)
+			 const char *buf, size_t count)
 {
 	int err = 0;
 	char *out = kmalloc(count + 1, GFP_KERNEL);
@@ -136,7 +136,7 @@ static struct device_attribute mISDN_dev_attrs[] = {
 	__ATTR(channelmap,  S_IRUGO,         _show_channelmap,  NULL),
 	__ATTR(nrbchan,     S_IRUGO,         _show_nrbchan,     NULL),
 	__ATTR(name,        S_IRUGO,         _show_name,        NULL),
-/*	__ATTR(name,        S_IRUGO|S_IWUSR, _show_name,       _set_name), */
+/*	__ATTR(name,        S_IRUGO | S_IWUSR, _show_name,      _set_name), */
 	{}
 };
 
@@ -187,7 +187,7 @@ struct mISDNdevice
 *get_mdevice(u_int id)
 {
 	return dev_to_mISDN(class_find_device(&mISDN_class, NULL, &id,
-		_get_mdevice));
+					      _get_mdevice));
 }
 
 static int
@@ -221,7 +221,7 @@ get_free_devid(void)
 
 int
 mISDN_register_device(struct mISDNdevice *dev,
-			struct device *parent, char *name)
+		      struct device *parent, char *name)
 {
 	int	err;
 
@@ -237,7 +237,7 @@ mISDN_register_device(struct mISDNdevice *dev,
 		dev_set_name(&dev->dev, "mISDN%d", dev->id);
 	if (debug & DEBUG_CORE)
 		printk(KERN_DEBUG "mISDN_register %s %d\n",
-			dev_name(&dev->dev), dev->id);
+		       dev_name(&dev->dev), dev->id);
 	err = create_stack(dev);
 	if (err)
 		goto error1;
@@ -265,7 +265,7 @@ void
 mISDN_unregister_device(struct mISDNdevice *dev) {
 	if (debug & DEBUG_CORE)
 		printk(KERN_DEBUG "mISDN_unregister %s %d\n",
-			dev_name(&dev->dev), dev->id);
+		       dev_name(&dev->dev), dev->id);
 	/* sysfs_remove_link(&dev->dev.kobj, "device"); */
 	device_del(&dev->dev);
 	dev_set_drvdata(&dev->dev, NULL);
@@ -311,7 +311,7 @@ get_Bprotocol4id(u_int id)
 
 	if (id < ISDN_P_B_START || id > 63) {
 		printk(KERN_WARNING "%s id not in range  %d\n",
-		    __func__, id);
+		       __func__, id);
 		return NULL;
 	}
 	m = 1 << (id & ISDN_P_B_MASK);
@@ -326,12 +326,12 @@ mISDN_register_Bprotocol(struct Bprotocol *bp)
 
 	if (debug & DEBUG_CORE)
 		printk(KERN_DEBUG "%s: %s/%x\n", __func__,
-		    bp->name, bp->Bprotocols);
+		       bp->name, bp->Bprotocols);
 	old = get_Bprotocol4mask(bp->Bprotocols);
 	if (old) {
 		printk(KERN_WARNING
-		    "register duplicate protocol old %s/%x new %s/%x\n",
-		    old->name, old->Bprotocols, bp->name, bp->Bprotocols);
+		       "register duplicate protocol old %s/%x new %s/%x\n",
+		       old->name, old->Bprotocols, bp->name, bp->Bprotocols);
 		return -EBUSY;
 	}
 	write_lock_irqsave(&bp_lock, flags);
@@ -348,7 +348,7 @@ mISDN_unregister_Bprotocol(struct Bprotocol *bp)
 
 	if (debug & DEBUG_CORE)
 		printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name,
-			bp->Bprotocols);
+		       bp->Bprotocols);
 	write_lock_irqsave(&bp_lock, flags);
 	list_del(&bp->list);
 	write_unlock_irqrestore(&bp_lock, flags);
@@ -361,7 +361,7 @@ mISDNInit(void)
 	int	err;
 
 	printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n",
-		MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
+	       MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
 	mISDN_init_clock(&debug);
 	mISDN_initstack(&debug);
 	err = class_register(&mISDN_class);
@@ -406,4 +406,3 @@ static void mISDN_cleanup(void)
 
 module_init(mISDNInit);
 module_exit(mISDN_cleanup);
-
diff --git a/drivers/isdn/mISDN/core.h b/drivers/isdn/mISDN/core.h
index 7ac2f81..52695bb 100644
--- a/drivers/isdn/mISDN/core.h
+++ b/drivers/isdn/mISDN/core.h
@@ -45,11 +45,11 @@ extern int			get_mdevice_count(void);
 #define MGR_OPT_NETWORK		25
 
 extern int	connect_Bstack(struct mISDNdevice *, struct mISDNchannel *,
-			u_int, struct sockaddr_mISDN *);
+			       u_int, struct sockaddr_mISDN *);
 extern int	connect_layer1(struct mISDNdevice *, struct mISDNchannel *,
-			u_int, struct sockaddr_mISDN *);
+			       u_int, struct sockaddr_mISDN *);
 extern int	create_l2entity(struct mISDNdevice *, struct mISDNchannel *,
-			u_int, struct sockaddr_mISDN *);
+				u_int, struct sockaddr_mISDN *);
 
 extern int	create_stack(struct mISDNdevice *);
 extern int	create_teimanager(struct mISDNdevice *);
@@ -71,7 +71,7 @@ extern void	mISDN_timer_cleanup(void);
 
 extern int	l1_init(u_int *);
 extern void	l1_cleanup(void);
-extern int 	Isdnl2_Init(u_int *);
+extern int	Isdnl2_Init(u_int *);
 extern void	Isdnl2_cleanup(void);
 
 extern void	mISDN_init_clock(u_int *);
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
index 8549431..afe4173 100644
--- a/drivers/isdn/mISDN/dsp.h
+++ b/drivers/isdn/mISDN/dsp.h
@@ -24,8 +24,8 @@
  * bit 1 = enable hfc hardware acceleration for all channels
  *
  */
-#define DSP_OPT_ULAW		(1<<0)
-#define DSP_OPT_NOHARDWARE	(1<<1)
+#define DSP_OPT_ULAW		(1 << 0)
+#define DSP_OPT_NOHARDWARE	(1 << 1)
 
 #include <linux/timer.h>
 #include <linux/workqueue.h>
@@ -97,12 +97,12 @@ struct dsp_conf_member {
 struct dsp_conf {
 	struct list_head	list;
 	u32			id;
-				/* all cmx stacks with the same ID are
-				 connected */
+	/* all cmx stacks with the same ID are
+	   connected */
 	struct list_head	mlist;
 	int			software; /* conf is processed by software */
 	int			hardware; /* conf is processed by hardware */
-				/* note: if both unset, has only one member */
+	/* note: if both unset, has only one member */
 };
 
 
@@ -122,7 +122,7 @@ struct dsp_dtmf {
 	int		hardware; /* dtmf uses hardware decoding */
 	int		size; /* number of bytes in buffer */
 	signed short	buffer[DSP_DTMF_NPOINTS];
-		/* buffers one full dtmf frame */
+	/* buffers one full dtmf frame */
 	u8		lastwhat, lastdigit;
 	int		count;
 	u8		digits[16]; /* dtmf result */
@@ -189,7 +189,7 @@ struct dsp {
 	u32		conf_id;
 	struct dsp_conf	*conf;
 	struct dsp_conf_member
-			*member;
+	*member;
 
 	/* buffer stuff */
 	int		rx_W; /* current write pos for data without timestamp */
@@ -203,7 +203,7 @@ struct dsp {
 	u8		rx_buff[CMX_BUFF_SIZE];
 	int		last_tx; /* if set, we transmitted last poll interval */
 	int		cmx_delay; /* initial delay of buffers,
-				or 0 for dynamic jitter buffer */
+				      or 0 for dynamic jitter buffer */
 	int		tx_dejitter; /* if set, dejitter tx buffer */
 	int		tx_data; /* enables tx-data of CMX to upper layer */
 
@@ -231,7 +231,7 @@ struct dsp {
 	int		bf_sync;
 
 	struct dsp_pipeline
-			pipeline;
+	pipeline;
 };
 
 /* functions */
@@ -253,7 +253,7 @@ extern int dsp_cmx_del_conf(struct dsp_conf *conf);
 extern void dsp_dtmf_goertzel_init(struct dsp *dsp);
 extern void dsp_dtmf_hardware(struct dsp *dsp);
 extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len,
-		int fmt);
+				    int fmt);
 
 extern int dsp_tone(struct dsp *dsp, int tone);
 extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len);
@@ -270,7 +270,6 @@ extern int  dsp_pipeline_init(struct dsp_pipeline *pipeline);
 extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline);
 extern int  dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
 extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
-		int len);
+				    int len);
 extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
-		int len, unsigned int txlen);
-
+				    int len, unsigned int txlen);
diff --git a/drivers/isdn/mISDN/dsp_audio.c b/drivers/isdn/mISDN/dsp_audio.c
index b8f18bd0..0602295 100644
--- a/drivers/isdn/mISDN/dsp_audio.c
+++ b/drivers/isdn/mISDN/dsp_audio.c
@@ -61,7 +61,7 @@ static inline unsigned char linear2alaw(short int linear)
 	}
 
 	/* Convert the scaled magnitude to segment number. */
-	for (seg = 0;  seg < 8;  seg++) {
+	for (seg = 0; seg < 8; seg++) {
 		if (pcm_val <= seg_end[seg])
 			break;
 	}
@@ -263,7 +263,7 @@ dsp_audio_generate_mix_table(void)
 				sample = 32767;
 			if (sample < -32768)
 				sample = -32768;
-			dsp_audio_mix_law[(i<<8)|j] =
+			dsp_audio_mix_law[(i << 8) | j] =
 				dsp_audio_s16_to_law[sample & 0xffff];
 			j++;
 		}
@@ -431,4 +431,3 @@ dsp_change_volume(struct sk_buff *skb, int volume)
 		i++;
 	}
 }
-
diff --git a/drivers/isdn/mISDN/dsp_biquad.h b/drivers/isdn/mISDN/dsp_biquad.h
index 038191b..c0c933a 100644
--- a/drivers/isdn/mISDN/dsp_biquad.h
+++ b/drivers/isdn/mISDN/dsp_biquad.h
@@ -38,7 +38,7 @@ struct biquad2_state {
 };
 
 static inline void biquad2_init(struct biquad2_state *bq,
-    int32_t gain, int32_t a1, int32_t a2, int32_t b1, int32_t b2)
+				int32_t gain, int32_t a1, int32_t a2, int32_t b1, int32_t b2)
 {
 	bq->gain = gain;
 	bq->a1 = a1;
@@ -55,8 +55,8 @@ static inline int16_t biquad2(struct biquad2_state *bq, int16_t sample)
 	int32_t y;
 	int32_t z0;
 
-	z0 = sample*bq->gain + bq->z1*bq->a1 + bq->z2*bq->a2;
-	y = z0 + bq->z1*bq->b1 + bq->z2*bq->b2;
+	z0 = sample * bq->gain + bq->z1 * bq->a1 + bq->z2 * bq->a2;
+	y = z0 + bq->z1 * bq->b1 + bq->z2 * bq->b2;
 
 	bq->z2 = bq->z1;
 	bq->z1 = z0 >> 15;
diff --git a/drivers/isdn/mISDN/dsp_blowfish.c b/drivers/isdn/mISDN/dsp_blowfish.c
index 18e411e..0aa572f 100644
--- a/drivers/isdn/mISDN/dsp_blowfish.c
+++ b/drivers/isdn/mISDN/dsp_blowfish.c
@@ -354,8 +354,8 @@ static const u32 bf_sbox[256 * 4] = {
 #define GET32_1(x) (((x) >> (16)) & (0xff))
 #define GET32_0(x) (((x) >> (24)) & (0xff))
 
-#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
-    S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
+#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^	\
+		  S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
 
 #define EROUND(a, b, n)  do { b ^= P[n]; a ^= bf_F(b); } while (0)
 #define DROUND(a, b, n)  do { a ^= bf_F(b); b ^= P[n]; } while (0)
@@ -388,17 +388,17 @@ dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len)
 		j = 0;
 		/* transcode 9 samples xlaw to 8 bytes */
 		yl = dsp_audio_law2seven[bf_data_in[0]];
-		yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[1]];
-		yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[2]];
-		yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[3]];
+		yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[1]];
+		yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[2]];
+		yl = (yl << 7) | dsp_audio_law2seven[bf_data_in[3]];
 		nibble = dsp_audio_law2seven[bf_data_in[4]];
 		yr = nibble;
-		yl = (yl<<4) | (nibble>>3);
-		yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[5]];
-		yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[6]];
-		yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[7]];
-		yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[8]];
-		yr = (yr<<1) | (bf_data_in[0] & 1);
+		yl = (yl << 4) | (nibble >> 3);
+		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[5]];
+		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[6]];
+		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[7]];
+		yr = (yr << 7) | dsp_audio_law2seven[bf_data_in[8]];
+		yr = (yr << 1) | (bf_data_in[0] & 1);
 
 		/* fill unused bit with random noise of audio input */
 		/* encrypt */
@@ -423,24 +423,24 @@ dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len)
 		yr ^= P[17];
 
 		/* calculate 3-bit checksumme */
-		cs = yl ^ (yl>>3) ^ (yl>>6) ^ (yl>>9) ^ (yl>>12) ^ (yl>>15)
-			^ (yl>>18) ^ (yl>>21) ^ (yl>>24) ^ (yl>>27) ^ (yl>>30)
-			^ (yr<<2) ^ (yr>>1) ^ (yr>>4) ^ (yr>>7) ^ (yr>>10)
-			^ (yr>>13) ^ (yr>>16) ^ (yr>>19) ^ (yr>>22) ^ (yr>>25)
-			^ (yr>>28) ^ (yr>>31);
+		cs = yl ^ (yl >> 3) ^ (yl >> 6) ^ (yl >> 9) ^ (yl >> 12) ^ (yl >> 15)
+			^ (yl >> 18) ^ (yl >> 21) ^ (yl >> 24) ^ (yl >> 27) ^ (yl >> 30)
+			^ (yr << 2) ^ (yr >> 1) ^ (yr >> 4) ^ (yr >> 7) ^ (yr >> 10)
+			^ (yr >> 13) ^ (yr >> 16) ^ (yr >> 19) ^ (yr >> 22) ^ (yr >> 25)
+			^ (yr >> 28) ^ (yr >> 31);
 
 		/*
 		 * transcode 8 crypted bytes to 9 data bytes with sync
 		 * and checksum information
 		 */
-		bf_crypt_out[0] = (yl>>25) | 0x80;
-		bf_crypt_out[1] = (yl>>18) & 0x7f;
-		bf_crypt_out[2] = (yl>>11) & 0x7f;
-		bf_crypt_out[3] = (yl>>4) & 0x7f;
-		bf_crypt_out[4] = ((yl<<3) & 0x78) | ((yr>>29) & 0x07);
-		bf_crypt_out[5] = ((yr>>22) & 0x7f) | ((cs<<5) & 0x80);
-		bf_crypt_out[6] = ((yr>>15) & 0x7f) | ((cs<<6) & 0x80);
-		bf_crypt_out[7] = ((yr>>8) & 0x7f) | (cs<<7);
+		bf_crypt_out[0] = (yl >> 25) | 0x80;
+		bf_crypt_out[1] = (yl >> 18) & 0x7f;
+		bf_crypt_out[2] = (yl >> 11) & 0x7f;
+		bf_crypt_out[3] = (yl >> 4) & 0x7f;
+		bf_crypt_out[4] = ((yl << 3) & 0x78) | ((yr >> 29) & 0x07);
+		bf_crypt_out[5] = ((yr >> 22) & 0x7f) | ((cs << 5) & 0x80);
+		bf_crypt_out[6] = ((yr >> 15) & 0x7f) | ((cs << 6) & 0x80);
+		bf_crypt_out[7] = ((yr >> 8) & 0x7f) | (cs << 7);
 		bf_crypt_out[8] = yr;
 	}
 
@@ -474,45 +474,45 @@ dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len)
 		 * shift upper bit and rotate data to buffer ring
 		 * send current decrypted data
 		 */
-		sync = (sync<<1) | ((*data)>>7);
+		sync = (sync << 1) | ((*data) >> 7);
 		bf_crypt_inring[j++ & 15] = *data;
 		*data++ = bf_data_out[k++];
 		i++;
 		if (k == 9)
 			k = 0; /* repeat if no sync has been found */
 		/* check if not in sync */
-		if ((sync&0x1f0) != 0x100)
+		if ((sync & 0x1f0) != 0x100)
 			continue;
 		j -= 9;
 		/* transcode receive data to 64 bit block of encrypted data */
 		yl = bf_crypt_inring[j++ & 15];
-		yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
-		yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
-		yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
+		yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
+		yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
+		yl = (yl << 7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
 		nibble = bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
 		yr = nibble;
-		yl = (yl<<4) | (nibble>>3);
+		yl = (yl << 4) | (nibble >> 3);
 		cs2 = bf_crypt_inring[j++ & 15];
-		yr = (yr<<7) | (cs2 & 0x7f);
+		yr = (yr << 7) | (cs2 & 0x7f);
 		cs1 = bf_crypt_inring[j++ & 15];
-		yr = (yr<<7) | (cs1 & 0x7f);
+		yr = (yr << 7) | (cs1 & 0x7f);
 		cs0 = bf_crypt_inring[j++ & 15];
-		yr = (yr<<7) | (cs0 & 0x7f);
-		yr = (yr<<8) | bf_crypt_inring[j++ & 15];
+		yr = (yr << 7) | (cs0 & 0x7f);
+		yr = (yr << 8) | bf_crypt_inring[j++ & 15];
 
 		/* calculate 3-bit checksumme */
-		cs = yl ^ (yl>>3) ^ (yl>>6) ^ (yl>>9) ^ (yl>>12) ^ (yl>>15)
-			^ (yl>>18) ^ (yl>>21) ^ (yl>>24) ^ (yl>>27) ^ (yl>>30)
-			^ (yr<<2) ^ (yr>>1) ^ (yr>>4) ^ (yr>>7) ^ (yr>>10)
-			^ (yr>>13) ^ (yr>>16) ^ (yr>>19) ^ (yr>>22) ^ (yr>>25)
-			^ (yr>>28) ^ (yr>>31);
+		cs = yl ^ (yl >> 3) ^ (yl >> 6) ^ (yl >> 9) ^ (yl >> 12) ^ (yl >> 15)
+			^ (yl >> 18) ^ (yl >> 21) ^ (yl >> 24) ^ (yl >> 27) ^ (yl >> 30)
+			^ (yr << 2) ^ (yr >> 1) ^ (yr >> 4) ^ (yr >> 7) ^ (yr >> 10)
+			^ (yr >> 13) ^ (yr >> 16) ^ (yr >> 19) ^ (yr >> 22) ^ (yr >> 25)
+			^ (yr >> 28) ^ (yr >> 31);
 
 		/* check if frame is valid */
-		if ((cs&0x7) != (((cs2>>5)&4) | ((cs1>>6)&2) | (cs0 >> 7))) {
+		if ((cs & 0x7) != (((cs2 >> 5) & 4) | ((cs1 >> 6) & 2) | (cs0 >> 7))) {
 			if (dsp_debug & DEBUG_DSP_BLOWFISH)
 				printk(KERN_DEBUG
-				    "DSP BLOWFISH: received corrupt frame, "
-				    "checksumme is not correct\n");
+				       "DSP BLOWFISH: received corrupt frame, "
+				       "checksumme is not correct\n");
 			continue;
 		}
 
@@ -537,17 +537,17 @@ dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len)
 		DROUND(yr, yl, 0);
 
 		/* transcode 8 crypted bytes to 9 sample bytes */
-		bf_data_out[0] = dsp_audio_seven2law[(yl>>25) & 0x7f];
-		bf_data_out[1] = dsp_audio_seven2law[(yl>>18) & 0x7f];
-		bf_data_out[2] = dsp_audio_seven2law[(yl>>11) & 0x7f];
-		bf_data_out[3] = dsp_audio_seven2law[(yl>>4) & 0x7f];
-		bf_data_out[4] = dsp_audio_seven2law[((yl<<3) & 0x78) |
-		    ((yr>>29) & 0x07)];
-
-		bf_data_out[5] = dsp_audio_seven2law[(yr>>22) & 0x7f];
-		bf_data_out[6] = dsp_audio_seven2law[(yr>>15) & 0x7f];
-		bf_data_out[7] = dsp_audio_seven2law[(yr>>8) & 0x7f];
-		bf_data_out[8] = dsp_audio_seven2law[(yr>>1) & 0x7f];
+		bf_data_out[0] = dsp_audio_seven2law[(yl >> 25) & 0x7f];
+		bf_data_out[1] = dsp_audio_seven2law[(yl >> 18) & 0x7f];
+		bf_data_out[2] = dsp_audio_seven2law[(yl >> 11) & 0x7f];
+		bf_data_out[3] = dsp_audio_seven2law[(yl >> 4) & 0x7f];
+		bf_data_out[4] = dsp_audio_seven2law[((yl << 3) & 0x78) |
+						     ((yr >> 29) & 0x07)];
+
+		bf_data_out[5] = dsp_audio_seven2law[(yr >> 22) & 0x7f];
+		bf_data_out[6] = dsp_audio_seven2law[(yr >> 15) & 0x7f];
+		bf_data_out[7] = dsp_audio_seven2law[(yr >> 8) & 0x7f];
+		bf_data_out[8] = dsp_audio_seven2law[(yr >> 1) & 0x7f];
 		k = 0; /* start with new decoded frame */
 	}
 
@@ -631,9 +631,9 @@ dsp_bf_init(struct dsp *dsp, const u8 *key, uint keylen)
 	/* Actual subkey generation */
 	for (j = 0, i = 0; i < 16 + 2; i++) {
 		temp = (((u32)key[j] << 24) |
-		    ((u32)key[(j + 1) % keylen] << 16) |
-		    ((u32)key[(j + 2) % keylen] << 8) |
-		    ((u32)key[(j + 3) % keylen]));
+			((u32)key[(j + 1) % keylen] << 16) |
+			((u32)key[(j + 2) % keylen] << 8) |
+			((u32)key[(j + 3) % keylen]));
 
 		P[i] = P[i] ^ temp;
 		j = (j + 4) % keylen;
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 4d395de..334feab 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -165,8 +165,8 @@ dsp_cmx_debug(struct dsp *dsp)
 	printk(KERN_DEBUG "-----Current DSP\n");
 	list_for_each_entry(odsp, &dsp_ilist, list) {
 		printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d",
-		    odsp->name, odsp->echo.hardware, odsp->echo.software,
-		    odsp->tx_mix);
+		       odsp->name, odsp->echo.hardware, odsp->echo.software,
+		       odsp->tx_mix);
 		if (odsp->conf)
 			printk(" (Conf %d)", odsp->conf->id);
 		if (dsp == odsp)
@@ -178,14 +178,14 @@ dsp_cmx_debug(struct dsp *dsp)
 		printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf);
 		list_for_each_entry(member, &conf->mlist, list) {
 			printk(KERN_DEBUG
-			    "  - member = %s (slot_tx %d, bank_tx %d, "
-			    "slot_rx %d, bank_rx %d hfc_conf %d "
-			    "tx_data %d rx_is_off %d)%s\n",
-			    member->dsp->name, member->dsp->pcm_slot_tx,
-			    member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
-			    member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
-			    member->dsp->tx_data, member->dsp->rx_is_off,
-			    (member->dsp == dsp) ? " *this*" : "");
+			       "  - member = %s (slot_tx %d, bank_tx %d, "
+			       "slot_rx %d, bank_rx %d hfc_conf %d "
+			       "tx_data %d rx_is_off %d)%s\n",
+			       member->dsp->name, member->dsp->pcm_slot_tx,
+			       member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
+			       member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
+			       member->dsp->tx_data, member->dsp->rx_is_off,
+			       (member->dsp == dsp) ? " *this*" : "");
 		}
 	}
 	printk(KERN_DEBUG "-----end\n");
@@ -227,13 +227,13 @@ dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
 	}
 	if (dsp->member) {
 		printk(KERN_WARNING "%s: dsp is already member in a conf.\n",
-			__func__);
+		       __func__);
 		return -EINVAL;
 	}
 
 	if (dsp->conf) {
 		printk(KERN_WARNING "%s: dsp is already in a conf.\n",
-			__func__);
+		       __func__);
 		return -EINVAL;
 	}
 
@@ -268,19 +268,19 @@ dsp_cmx_del_conf_member(struct dsp *dsp)
 
 	if (!dsp) {
 		printk(KERN_WARNING "%s: dsp is 0.\n",
-			__func__);
+		       __func__);
 		return -EINVAL;
 	}
 
 	if (!dsp->conf) {
 		printk(KERN_WARNING "%s: dsp is not in a conf.\n",
-			__func__);
+		       __func__);
 		return -EINVAL;
 	}
 
 	if (list_empty(&dsp->conf->mlist)) {
 		printk(KERN_WARNING "%s: dsp has linked an empty conf.\n",
-			__func__);
+		       __func__);
 		return -EINVAL;
 	}
 
@@ -295,8 +295,8 @@ dsp_cmx_del_conf_member(struct dsp *dsp)
 		}
 	}
 	printk(KERN_WARNING
-	    "%s: dsp is not present in its own conf_meber list.\n",
-	    __func__);
+	       "%s: dsp is not present in its own conf_meber list.\n",
+	       __func__);
 
 	return -EINVAL;
 }
@@ -312,7 +312,7 @@ static struct dsp_conf
 
 	if (!id) {
 		printk(KERN_WARNING "%s: id is 0.\n",
-		    __func__);
+		       __func__);
 		return NULL;
 	}
 
@@ -338,13 +338,13 @@ dsp_cmx_del_conf(struct dsp_conf *conf)
 {
 	if (!conf) {
 		printk(KERN_WARNING "%s: conf is null.\n",
-		    __func__);
+		       __func__);
 		return -EINVAL;
 	}
 
 	if (!list_empty(&conf->mlist)) {
 		printk(KERN_WARNING "%s: conf not empty.\n",
-		    __func__);
+		       __func__);
 		return -EINVAL;
 	}
 	list_del(&conf->list);
@@ -359,7 +359,7 @@ dsp_cmx_del_conf(struct dsp_conf *conf)
  */
 static void
 dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2,
-    u32 param3, u32 param4)
+		   u32 param3, u32 param4)
 {
 	struct mISDN_ctrl_req cq;
 
@@ -389,7 +389,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
 	int		freeunits[8];
 	u_char		freeslots[256];
 	int		same_hfc = -1, same_pcm = -1, current_conf = -1,
-	    all_conf = 1, tx_data = 0;
+		all_conf = 1, tx_data = 0;
 
 	/* dsp gets updated (no conf) */
 	if (!conf) {
@@ -397,17 +397,17 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
 			return;
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG "%s checking dsp %s\n",
-			    __func__, dsp->name);
-one_member:
+			       __func__, dsp->name);
+	one_member:
 		/* remove HFC conference if enabled */
 		if (dsp->hfc_conf >= 0) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s removing %s from HFC conf %d "
-				    "because dsp is split\n", __func__,
-				    dsp->name, dsp->hfc_conf);
+				       "%s removing %s from HFC conf %d "
+				       "because dsp is split\n", __func__,
+				       dsp->name, dsp->hfc_conf);
 			dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT,
-			    0, 0, 0, 0);
+					   0, 0, 0, 0);
 			dsp->hfc_conf = -1;
 		}
 		/* process hw echo */
@@ -418,12 +418,12 @@ one_member:
 			if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG "%s removing %s from"
-					    " PCM slot %d (TX) %d (RX) because"
-					    " dsp is split (no echo)\n",
-					    __func__, dsp->name,
-					    dsp->pcm_slot_tx, dsp->pcm_slot_rx);
+					       " PCM slot %d (TX) %d (RX) because"
+					       " dsp is split (no echo)\n",
+					       __func__, dsp->name,
+					       dsp->pcm_slot_tx, dsp->pcm_slot_rx);
 				dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC,
-				    0, 0, 0, 0);
+						   0, 0, 0, 0);
 				dsp->pcm_slot_tx = -1;
 				dsp->pcm_bank_tx = -1;
 				dsp->pcm_slot_rx = -1;
@@ -447,11 +447,11 @@ one_member:
 			dsp->pcm_bank_rx = 2;
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s refresh %s for echo using slot %d\n",
-				    __func__, dsp->name,
-				    dsp->pcm_slot_tx);
+				       "%s refresh %s for echo using slot %d\n",
+				       __func__, dsp->name,
+				       dsp->pcm_slot_tx);
 			dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
-			    dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
+					   dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
 			dsp->echo.hardware = 1;
 			return;
 		}
@@ -479,8 +479,8 @@ one_member:
 		if (i == ii) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s no slot available for echo\n",
-				    __func__);
+				       "%s no slot available for echo\n",
+				       __func__);
 			/* no more slots available */
 			dsp->echo.software = 1;
 			return;
@@ -492,10 +492,10 @@ one_member:
 		dsp->pcm_bank_rx = 2;
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG
-			    "%s assign echo for %s using slot %d\n",
-			    __func__, dsp->name, dsp->pcm_slot_tx);
+			       "%s assign echo for %s using slot %d\n",
+			       __func__, dsp->name, dsp->pcm_slot_tx);
 		dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
-		    dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
+				   dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
 		dsp->echo.hardware = 1;
 		return;
 	}
@@ -503,11 +503,11 @@ one_member:
 	/* conf gets updated (all members) */
 	if (dsp_debug & DEBUG_DSP_CMX)
 		printk(KERN_DEBUG "%s checking conference %d\n",
-		    __func__, conf->id);
+		       __func__, conf->id);
 
 	if (list_empty(&conf->mlist)) {
 		printk(KERN_ERR "%s: conference whithout members\n",
-		    __func__);
+		       __func__);
 		return;
 	}
 	member = list_entry(conf->mlist.next, struct dsp_conf_member, list);
@@ -519,25 +519,25 @@ one_member:
 		if (member->dsp->tx_mix) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "tx_mix is turned on\n", __func__,
-				    member->dsp->name);
-conf_software:
+				       "%s dsp %s cannot form a conf, because "
+				       "tx_mix is turned on\n", __func__,
+				       member->dsp->name);
+		conf_software:
 			list_for_each_entry(member, &conf->mlist, list) {
 				dsp = member->dsp;
 				/* remove HFC conference if enabled */
 				if (dsp->hfc_conf >= 0) {
 					if (dsp_debug & DEBUG_DSP_CMX)
 						printk(KERN_DEBUG
-						    "%s removing %s from HFC "
-						    "conf %d because not "
-						    "possible with hardware\n",
-						    __func__,
-						    dsp->name,
-						    dsp->hfc_conf);
+						       "%s removing %s from HFC "
+						       "conf %d because not "
+						       "possible with hardware\n",
+						       __func__,
+						       dsp->name,
+						       dsp->hfc_conf);
 					dsp_cmx_hw_message(dsp,
-					    MISDN_CTRL_HFC_CONF_SPLIT,
-					    0, 0, 0, 0);
+							   MISDN_CTRL_HFC_CONF_SPLIT,
+							   0, 0, 0, 0);
 					dsp->hfc_conf = -1;
 				}
 				/* remove PCM slot if assigned */
@@ -545,16 +545,16 @@ conf_software:
 				    dsp->pcm_slot_rx >= 0) {
 					if (dsp_debug & DEBUG_DSP_CMX)
 						printk(KERN_DEBUG "%s removing "
-						    "%s from PCM slot %d (TX)"
-						    " slot %d (RX) because not"
-						    " possible with hardware\n",
-						    __func__,
-						    dsp->name,
-						    dsp->pcm_slot_tx,
-						    dsp->pcm_slot_rx);
+						       "%s from PCM slot %d (TX)"
+						       " slot %d (RX) because not"
+						       " possible with hardware\n",
+						       __func__,
+						       dsp->name,
+						       dsp->pcm_slot_tx,
+						       dsp->pcm_slot_rx);
 					dsp_cmx_hw_message(dsp,
-					    MISDN_CTRL_HFC_PCM_DISC,
-					    0, 0, 0, 0);
+							   MISDN_CTRL_HFC_PCM_DISC,
+							   0, 0, 0, 0);
 					dsp->pcm_slot_tx = -1;
 					dsp->pcm_bank_tx = -1;
 					dsp->pcm_slot_rx = -1;
@@ -569,79 +569,79 @@ conf_software:
 		if (member->dsp->echo.hardware || member->dsp->echo.software) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "echo is turned on\n", __func__,
-				    member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "echo is turned on\n", __func__,
+				       member->dsp->name);
 			goto conf_software;
 		}
 		/* check if member has tx_mix turned on */
 		if (member->dsp->tx_mix) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "tx_mix is turned on\n",
-				    __func__, member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "tx_mix is turned on\n",
+				       __func__, member->dsp->name);
 			goto conf_software;
 		}
 		/* check if member changes volume at an not suppoted level */
 		if (member->dsp->tx_volume) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "tx_volume is changed\n",
-				    __func__, member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "tx_volume is changed\n",
+				       __func__, member->dsp->name);
 			goto conf_software;
 		}
 		if (member->dsp->rx_volume) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "rx_volume is changed\n",
-				    __func__, member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "rx_volume is changed\n",
+				       __func__, member->dsp->name);
 			goto conf_software;
 		}
 		/* check if tx-data turned on */
 		if (member->dsp->tx_data) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s tx_data is turned on\n",
-				    __func__, member->dsp->name);
+				       "%s dsp %s tx_data is turned on\n",
+				       __func__, member->dsp->name);
 			tx_data = 1;
 		}
 		/* check if pipeline exists */
 		if (member->dsp->pipeline.inuse) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "pipeline exists\n", __func__,
-				    member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "pipeline exists\n", __func__,
+				       member->dsp->name);
 			goto conf_software;
 		}
 		/* check if encryption is enabled */
 		if (member->dsp->bf_enable) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG "%s dsp %s cannot form a "
-				    "conf, because encryption is enabled\n",
-				    __func__, member->dsp->name);
+				       "conf, because encryption is enabled\n",
+				       __func__, member->dsp->name);
 			goto conf_software;
 		}
 		/* check if member is on a card with PCM support */
 		if (member->dsp->features.pcm_id < 0) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "dsp has no PCM bus\n",
-				    __func__, member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "dsp has no PCM bus\n",
+				       __func__, member->dsp->name);
 			goto conf_software;
 		}
 		/* check if relations are on the same PCM bus */
 		if (member->dsp->features.pcm_id != same_pcm) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s dsp %s cannot form a conf, because "
-				    "dsp is on a different PCM bus than the "
-				    "first dsp\n",
-				    __func__, member->dsp->name);
+				       "%s dsp %s cannot form a conf, because "
+				       "dsp is on a different PCM bus than the "
+				       "first dsp\n",
+				       __func__, member->dsp->name);
 			goto conf_software;
 		}
 		/* determine if members are on the same hfc chip */
@@ -665,12 +665,12 @@ conf_software:
 	if (memb == 1) {
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG
-			    "%s conf %d cannot form a HW conference, "
-			    "because dsp is alone\n", __func__, conf->id);
+			       "%s conf %d cannot form a HW conference, "
+			       "because dsp is alone\n", __func__, conf->id);
 		conf->hardware = 0;
 		conf->software = 0;
 		member = list_entry(conf->mlist.next, struct dsp_conf_member,
-			list);
+				    list);
 		dsp = member->dsp;
 		goto one_member;
 	}
@@ -684,30 +684,30 @@ conf_software:
 	/* if we have only two members */
 	if (memb == 2) {
 		member = list_entry(conf->mlist.next, struct dsp_conf_member,
-			list);
+				    list);
 		nextm = list_entry(member->list.next, struct dsp_conf_member,
-			list);
+				   list);
 		/* remove HFC conference if enabled */
 		if (member->dsp->hfc_conf >= 0) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s removing %s from HFC conf %d because "
-				    "two parties require only a PCM slot\n",
-				    __func__, member->dsp->name,
-				    member->dsp->hfc_conf);
+				       "%s removing %s from HFC conf %d because "
+				       "two parties require only a PCM slot\n",
+				       __func__, member->dsp->name,
+				       member->dsp->hfc_conf);
 			dsp_cmx_hw_message(member->dsp,
-			    MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
+					   MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
 			member->dsp->hfc_conf = -1;
 		}
 		if (nextm->dsp->hfc_conf >= 0) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s removing %s from HFC conf %d because "
-				    "two parties require only a PCM slot\n",
-				    __func__, nextm->dsp->name,
-				    nextm->dsp->hfc_conf);
+				       "%s removing %s from HFC conf %d because "
+				       "two parties require only a PCM slot\n",
+				       __func__, nextm->dsp->name,
+				       nextm->dsp->hfc_conf);
 			dsp_cmx_hw_message(nextm->dsp,
-			    MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
+					   MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
 			nextm->dsp->hfc_conf = -1;
 		}
 		/* if members have two banks (and not on the same chip) */
@@ -733,15 +733,15 @@ conf_software:
 				/* all members have same slot */
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG
-					    "%s dsp %s & %s stay joined on "
-					    "PCM slot %d bank %d (TX) bank %d "
-					    "(RX) (on different chips)\n",
-					    __func__,
-					    member->dsp->name,
-					    nextm->dsp->name,
-					    member->dsp->pcm_slot_tx,
-					    member->dsp->pcm_bank_tx,
-					    member->dsp->pcm_bank_rx);
+					       "%s dsp %s & %s stay joined on "
+					       "PCM slot %d bank %d (TX) bank %d "
+					       "(RX) (on different chips)\n",
+					       __func__,
+					       member->dsp->name,
+					       nextm->dsp->name,
+					       member->dsp->pcm_slot_tx,
+					       member->dsp->pcm_bank_tx,
+					       member->dsp->pcm_bank_rx);
 				conf->hardware = 0;
 				conf->software = 1;
 				return;
@@ -773,10 +773,10 @@ conf_software:
 			if (i == ii) {
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG
-					    "%s no slot available for "
-					    "%s & %s\n", __func__,
-					    member->dsp->name,
-					    nextm->dsp->name);
+					       "%s no slot available for "
+					       "%s & %s\n", __func__,
+					       member->dsp->name,
+					       nextm->dsp->name);
 				/* no more slots available */
 				goto conf_software;
 			}
@@ -791,23 +791,23 @@ conf_software:
 			nextm->dsp->pcm_bank_tx = 0;
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s adding %s & %s to new PCM slot %d "
-				    "(TX and RX on different chips) because "
-				    "both members have not same slots\n",
-				    __func__,
-				    member->dsp->name,
-				    nextm->dsp->name,
-				    member->dsp->pcm_slot_tx);
+				       "%s adding %s & %s to new PCM slot %d "
+				       "(TX and RX on different chips) because "
+				       "both members have not same slots\n",
+				       __func__,
+				       member->dsp->name,
+				       nextm->dsp->name,
+				       member->dsp->pcm_slot_tx);
 			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
-			    member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
-			    member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
+					   member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
+					   member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
 			dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
-			    nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
-			    nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
+					   nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
+					   nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
 			conf->hardware = 1;
 			conf->software = tx_data;
 			return;
-		/* if members have one bank (or on the same chip) */
+			/* if members have one bank (or on the same chip) */
 		} else {
 			/* if both members have different crossed slots */
 			if (member->dsp->pcm_slot_tx >= 0 &&
@@ -827,13 +827,13 @@ conf_software:
 				/* all members have same slot */
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG
-					    "%s dsp %s & %s stay joined on PCM "
-					    "slot %d (TX) %d (RX) on same chip "
-					    "or one bank PCM)\n", __func__,
-					    member->dsp->name,
-					    nextm->dsp->name,
-					    member->dsp->pcm_slot_tx,
-					    member->dsp->pcm_slot_rx);
+					       "%s dsp %s & %s stay joined on PCM "
+					       "slot %d (TX) %d (RX) on same chip "
+					       "or one bank PCM)\n", __func__,
+					       member->dsp->name,
+					       nextm->dsp->name,
+					       member->dsp->pcm_slot_tx,
+					       member->dsp->pcm_slot_rx);
 				conf->hardware = 0;
 				conf->software = 1;
 				return;
@@ -865,14 +865,14 @@ conf_software:
 			if (i1 == ii) {
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG
-					    "%s no slot available "
-					    "for %s & %s\n", __func__,
-					    member->dsp->name,
-					    nextm->dsp->name);
+					       "%s no slot available "
+					       "for %s & %s\n", __func__,
+					       member->dsp->name,
+					       nextm->dsp->name);
 				/* no more slots available */
 				goto conf_software;
 			}
-			i2 = i1+1;
+			i2 = i1 + 1;
 			while (i2 < ii) {
 				if (freeslots[i2])
 					break;
@@ -881,11 +881,11 @@ conf_software:
 			if (i2 == ii) {
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG
-					    "%s no slot available "
-					    "for %s & %s\n",
-					    __func__,
-					    member->dsp->name,
-					    nextm->dsp->name);
+					       "%s no slot available "
+					       "for %s & %s\n",
+					       __func__,
+					       member->dsp->name,
+					       nextm->dsp->name);
 				/* no more slots available */
 				goto conf_software;
 			}
@@ -900,20 +900,20 @@ conf_software:
 			nextm->dsp->pcm_bank_tx = 0;
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s adding %s & %s to new PCM slot %d "
-				    "(TX) %d (RX) on same chip or one bank "
-				    "PCM, because both members have not "
-				    "crossed slots\n", __func__,
-				    member->dsp->name,
-				    nextm->dsp->name,
-				    member->dsp->pcm_slot_tx,
-				    member->dsp->pcm_slot_rx);
+				       "%s adding %s & %s to new PCM slot %d "
+				       "(TX) %d (RX) on same chip or one bank "
+				       "PCM, because both members have not "
+				       "crossed slots\n", __func__,
+				       member->dsp->name,
+				       nextm->dsp->name,
+				       member->dsp->pcm_slot_tx,
+				       member->dsp->pcm_slot_rx);
 			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
-			    member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
-			    member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
+					   member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
+					   member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
 			dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
-			    nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
-			    nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
+					   nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
+					   nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
 			conf->hardware = 1;
 			conf->software = tx_data;
 			return;
@@ -929,10 +929,10 @@ conf_software:
 	if (same_hfc < 0) {
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG
-			    "%s conference %d cannot be formed, because "
-			    "members are on different chips or not "
-			    "on HFC chip\n",
-			    __func__, conf->id);
+			       "%s conference %d cannot be formed, because "
+			       "members are on different chips or not "
+			       "on HFC chip\n",
+			       __func__, conf->id);
 		goto conf_software;
 	}
 
@@ -946,7 +946,7 @@ conf_software:
 	 * if there is an existing conference, but not all members have joined
 	 */
 	if (current_conf >= 0) {
-join_members:
+	join_members:
 		list_for_each_entry(member, &conf->mlist, list) {
 			/* if no conference engine on our chip, change to
 			 * software */
@@ -966,10 +966,10 @@ join_members:
 				 * slot will be overwritten.
 				 */
 				if (
-				    dsp != member->dsp &&
-				/* dsp must be on the same PCM */
-				    member->dsp->features.pcm_id ==
-				    dsp->features.pcm_id) {
+					dsp != member->dsp &&
+					/* dsp must be on the same PCM */
+					member->dsp->features.pcm_id ==
+					dsp->features.pcm_id) {
 					/* dsp must be on a slot */
 					if (dsp->pcm_slot_tx >= 0 &&
 					    dsp->pcm_slot_tx <
@@ -992,16 +992,16 @@ join_members:
 				/* no more slots available */
 				if (dsp_debug & DEBUG_DSP_CMX)
 					printk(KERN_DEBUG
-					    "%s conference %d cannot be formed,"
-					    " because no slot free\n",
-					    __func__, conf->id);
+					       "%s conference %d cannot be formed,"
+					       " because no slot free\n",
+					       __func__, conf->id);
 				goto conf_software;
 			}
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "%s changing dsp %s to HW conference "
-				    "%d slot %d\n", __func__,
-				    member->dsp->name, current_conf, i);
+				       "%s changing dsp %s to HW conference "
+				       "%d slot %d\n", __func__,
+				       member->dsp->name, current_conf, i);
 			/* assign free slot & set PCM & join conf */
 			member->dsp->pcm_slot_tx = i;
 			member->dsp->pcm_slot_rx = i;
@@ -1009,9 +1009,9 @@ join_members:
 			member->dsp->pcm_bank_rx = 2;
 			member->dsp->hfc_conf = current_conf;
 			dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
-			    i, 2, i, 2);
+					   i, 2, i, 2);
 			dsp_cmx_hw_message(member->dsp,
-			    MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
+					   MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
 		}
 		return;
 	}
@@ -1040,9 +1040,9 @@ join_members:
 		/* no more conferences available */
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG
-			    "%s conference %d cannot be formed, because "
-			    "no conference number free\n",
-			    __func__, conf->id);
+			       "%s conference %d cannot be formed, because "
+			       "no conference number free\n",
+			       __func__, conf->id);
 		goto conf_software;
 	}
 	/* join all members */
@@ -1070,7 +1070,7 @@ dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
 	if (dsp->conf_id) {
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG "removing us from conference %d\n",
-				dsp->conf->id);
+			       dsp->conf->id);
 		/* remove us from conf */
 		conf = dsp->conf;
 		err = dsp_cmx_del_conf_member(dsp);
@@ -1085,7 +1085,7 @@ dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
 		if (list_empty(&conf->mlist)) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "conference is empty, so we remove it.\n");
+				       "conference is empty, so we remove it.\n");
 			err = dsp_cmx_del_conf(conf);
 			if (err)
 				return err;
@@ -1102,29 +1102,29 @@ dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
 	/* now add us to conf */
 	if (dsp_debug & DEBUG_DSP_CMX)
 		printk(KERN_DEBUG "searching conference %d\n",
-			conf_id);
+		       conf_id);
 	conf = dsp_cmx_search_conf(conf_id);
 	if (!conf) {
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG
-			    "conference doesn't exist yet, creating.\n");
+			       "conference doesn't exist yet, creating.\n");
 		/* the conference doesn't exist, so we create */
 		conf = dsp_cmx_new_conf(conf_id);
 		if (!conf)
 			return -EINVAL;
 	} else if (!list_empty(&conf->mlist)) {
 		member = list_entry(conf->mlist.next, struct dsp_conf_member,
-			list);
+				    list);
 		if (dsp->hdlc && !member->dsp->hdlc) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "cannot join transparent conference.\n");
+				       "cannot join transparent conference.\n");
 			return -EINVAL;
 		}
 		if (!dsp->hdlc && member->dsp->hdlc) {
 			if (dsp_debug & DEBUG_DSP_CMX)
 				printk(KERN_DEBUG
-				    "cannot join hdlc conference.\n");
+				       "cannot join hdlc conference.\n");
 			return -EINVAL;
 		}
 	}
@@ -1138,7 +1138,7 @@ dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
 	if (list_empty(&conf->mlist)) {
 		if (dsp_debug & DEBUG_DSP_CMX)
 			printk(KERN_DEBUG
-			    "we are alone in this conference, so exit.\n");
+			       "we are alone in this conference, so exit.\n");
 		/* update hardware */
 		dsp_cmx_hardware(NULL, dsp);
 		return 0;
@@ -1166,7 +1166,7 @@ showdelay(struct dsp *dsp, int samples, int delay)
 	sdelay = delay * 50 / (dsp_poll << 2);
 
 	printk(KERN_DEBUG "DELAY (%s) %3d >%s\n", dsp->name, delay,
-		sdelay > 50 ? "..." : bar + 50 - sdelay);
+	       sdelay > 50 ? "..." : bar + 50 - sdelay);
 }
 #endif
 
@@ -1188,9 +1188,9 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
 	/* half of the buffer should be larger than maximum packet size */
 	if (len >= CMX_BUFF_HALF) {
 		printk(KERN_ERR
-		    "%s line %d: packet from card is too large (%d bytes). "
-		    "please make card send smaller packets OR increase "
-		    "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
+		       "%s line %d: packet from card is too large (%d bytes). "
+		       "please make card send smaller packets OR increase "
+		       "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
 		return;
 	}
 
@@ -1228,9 +1228,9 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
 	if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) {
 		if (dsp_debug & DEBUG_DSP_CLOCK)
 			printk(KERN_DEBUG
-			    "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
-			    "maximum delay), adjusting read pointer! "
-			    "(inst %s)\n", (u_long)dsp, dsp->name);
+			       "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
+			       "maximum delay), adjusting read pointer! "
+			       "(inst %s)\n", (u_long)dsp, dsp->name);
 		/* flush rx buffer and set delay to dsp_poll / 2 */
 		if (dsp->features.unordered) {
 			dsp->rx_R = (hh->id & CMX_BUFF_MASK);
@@ -1255,27 +1255,27 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
 		    (dsp->cmx_delay << 1)) {
 			if (dsp_debug & DEBUG_DSP_CLOCK)
 				printk(KERN_DEBUG
-				    "cmx_receive(dsp=%lx): OVERRUN (because "
-				    "twice the delay is reached), adjusting "
-				    "read pointer! (inst %s)\n",
-				    (u_long)dsp, dsp->name);
-		/* flush buffer */
-		if (dsp->features.unordered) {
-			dsp->rx_R = (hh->id & CMX_BUFF_MASK);
-			dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
-				& CMX_BUFF_MASK;
-		} else {
-			dsp->rx_R = 0;
-			dsp->rx_W = dsp->cmx_delay;
+				       "cmx_receive(dsp=%lx): OVERRUN (because "
+				       "twice the delay is reached), adjusting "
+				       "read pointer! (inst %s)\n",
+				       (u_long)dsp, dsp->name);
+			/* flush buffer */
+			if (dsp->features.unordered) {
+				dsp->rx_R = (hh->id & CMX_BUFF_MASK);
+				dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
+					& CMX_BUFF_MASK;
+			} else {
+				dsp->rx_R = 0;
+				dsp->rx_W = dsp->cmx_delay;
+			}
+			memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
 		}
-		memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
-	}
 
 	/* show where to write */
 #ifdef CMX_DEBUG
 	printk(KERN_DEBUG
-	    "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
-	    (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
+	       "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
+	       (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
 #endif
 
 	/* write data into rx_buffer */
@@ -1290,7 +1290,7 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
 	}
 
 	/* increase write-pointer */
-	dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK);
+	dsp->rx_W = ((dsp->rx_W + len) & CMX_BUFF_MASK);
 #ifdef CMX_DELAY_DEBUG
 	showdelay(dsp, len, (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK);
 #endif
@@ -1319,7 +1319,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 		return;
 	}
 	if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
-	    dsp->echo.hardware) && /* OR hardware echo */
+	     dsp->echo.hardware) && /* OR hardware echo */
 	    dsp->tx_R == dsp->tx_W && /* AND no tx-data */
 	    !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
 		if (!dsp->tx_data) { /* no tx_data for user space required */
@@ -1334,8 +1334,8 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 
 #ifdef CMX_DEBUG
 	printk(KERN_DEBUG
-	    "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
-	    members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
+	       "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
+	       members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
 #endif
 
 	/* preload if we have delay set */
@@ -1349,8 +1349,8 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 	nskb = mI_alloc_skb(len + preload, GFP_ATOMIC);
 	if (!nskb) {
 		printk(KERN_ERR
-		    "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
-		    len + preload);
+		       "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
+		       len + preload);
 		return;
 	}
 	hh = mISDN_HEAD_P(nskb);
@@ -1386,22 +1386,22 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 	if (!dsp->tx_mix && t != tt) {
 		/* -> send tx-data and continue when not enough */
 #ifdef CMX_TX_DEBUG
-	sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
+		sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
 #endif
 		while (r != rr && t != tt) {
 #ifdef CMX_TX_DEBUG
 			if (strlen(debugbuf) < 48)
-				sprintf(debugbuf+strlen(debugbuf), " %02x",
-				    p[t]);
+				sprintf(debugbuf + strlen(debugbuf), " %02x",
+					p[t]);
 #endif
 			*d++ = p[t]; /* write tx_buff */
-			t = (t+1) & CMX_BUFF_MASK;
-			r = (r+1) & CMX_BUFF_MASK;
+			t = (t + 1) & CMX_BUFF_MASK;
+			r = (r + 1) & CMX_BUFF_MASK;
 		}
 		if (r == rr) {
 			dsp->tx_R = t;
 #ifdef CMX_TX_DEBUG
-	printk(KERN_DEBUG "%s\n", debugbuf);
+			printk(KERN_DEBUG "%s\n", debugbuf);
 #endif
 			goto send_packet;
 		}
@@ -1417,29 +1417,29 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 			/* -> send tx-data if available or use 0-volume */
 			while (r != rr && t != tt) {
 				*d++ = p[t]; /* write tx_buff */
-				t = (t+1) & CMX_BUFF_MASK;
-				r = (r+1) & CMX_BUFF_MASK;
+				t = (t + 1) & CMX_BUFF_MASK;
+				r = (r + 1) & CMX_BUFF_MASK;
 			}
 			if (r != rr) {
 				if (dsp_debug & DEBUG_DSP_CLOCK)
 					printk(KERN_DEBUG "%s: RX empty\n",
-						__func__);
-				memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK);
+					       __func__);
+				memset(d, dsp_silence, (rr - r) & CMX_BUFF_MASK);
 			}
-		/* -> if echo is enabled */
+			/* -> if echo is enabled */
 		} else {
 			/*
 			 * -> mix tx-data with echo if available,
 			 * or use echo only
 			 */
 			while (r != rr && t != tt) {
-				*d++ = dsp_audio_mix_law[(p[t]<<8)|q[r]];
-				t = (t+1) & CMX_BUFF_MASK;
-				r = (r+1) & CMX_BUFF_MASK;
+				*d++ = dsp_audio_mix_law[(p[t] << 8) | q[r]];
+				t = (t + 1) & CMX_BUFF_MASK;
+				r = (r + 1) & CMX_BUFF_MASK;
 			}
 			while (r != rr) {
 				*d++ = q[r]; /* echo */
-				r = (r+1) & CMX_BUFF_MASK;
+				r = (r + 1) & CMX_BUFF_MASK;
 			}
 		}
 		dsp->tx_R = t;
@@ -1449,63 +1449,63 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 #ifdef CMX_CONF_DEBUG
 	if (0) {
 #else
-	if (members == 2) {
+		if (members == 2) {
 #endif
-		/* "other" becomes other party */
-		other = (list_entry(conf->mlist.next,
-		    struct dsp_conf_member, list))->dsp;
-		if (other == member)
-			other = (list_entry(conf->mlist.prev,
-			    struct dsp_conf_member, list))->dsp;
-		o_q = other->rx_buff; /* received data */
-		o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
+			/* "other" becomes other party */
+			other = (list_entry(conf->mlist.next,
+					    struct dsp_conf_member, list))->dsp;
+			if (other == member)
+				other = (list_entry(conf->mlist.prev,
+						    struct dsp_conf_member, list))->dsp;
+			o_q = other->rx_buff; /* received data */
+			o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
 			/* end of rx-pointer */
-		o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
+			o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
 			/* start rx-pointer at current read position*/
-		/* -> if echo is NOT enabled */
-		if (!dsp->echo.software) {
-			/*
-			 * -> copy other member's rx-data,
-			 * if tx-data is available, mix
-			 */
-			while (o_r != o_rr && t != tt) {
-				*d++ = dsp_audio_mix_law[(p[t]<<8)|o_q[o_r]];
-				t = (t+1) & CMX_BUFF_MASK;
-				o_r = (o_r+1) & CMX_BUFF_MASK;
-			}
-			while (o_r != o_rr) {
-				*d++ = o_q[o_r];
-				o_r = (o_r+1) & CMX_BUFF_MASK;
-			}
-		/* -> if echo is enabled */
-		} else {
-			/*
-			 * -> mix other member's rx-data with echo,
-			 * if tx-data is available, mix
-			 */
-			while (r != rr && t != tt) {
-				sample = dsp_audio_law_to_s32[p[t]] +
-				    dsp_audio_law_to_s32[q[r]] +
-				    dsp_audio_law_to_s32[o_q[o_r]];
-				if (sample < -32768)
-					sample = -32768;
-				else if (sample > 32767)
-					sample = 32767;
-				*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-				    /* tx-data + rx_data + echo */
-				t = (t+1) & CMX_BUFF_MASK;
-				r = (r+1) & CMX_BUFF_MASK;
-				o_r = (o_r+1) & CMX_BUFF_MASK;
-			}
-			while (r != rr) {
-				*d++ = dsp_audio_mix_law[(q[r]<<8)|o_q[o_r]];
-				r = (r+1) & CMX_BUFF_MASK;
-				o_r = (o_r+1) & CMX_BUFF_MASK;
+			/* -> if echo is NOT enabled */
+			if (!dsp->echo.software) {
+				/*
+				 * -> copy other member's rx-data,
+				 * if tx-data is available, mix
+				 */
+				while (o_r != o_rr && t != tt) {
+					*d++ = dsp_audio_mix_law[(p[t] << 8) | o_q[o_r]];
+					t = (t + 1) & CMX_BUFF_MASK;
+					o_r = (o_r + 1) & CMX_BUFF_MASK;
+				}
+				while (o_r != o_rr) {
+					*d++ = o_q[o_r];
+					o_r = (o_r + 1) & CMX_BUFF_MASK;
+				}
+				/* -> if echo is enabled */
+			} else {
+				/*
+				 * -> mix other member's rx-data with echo,
+				 * if tx-data is available, mix
+				 */
+				while (r != rr && t != tt) {
+					sample = dsp_audio_law_to_s32[p[t]] +
+						dsp_audio_law_to_s32[q[r]] +
+						dsp_audio_law_to_s32[o_q[o_r]];
+					if (sample < -32768)
+						sample = -32768;
+					else if (sample > 32767)
+						sample = 32767;
+					*d++ = dsp_audio_s16_to_law[sample & 0xffff];
+					/* tx-data + rx_data + echo */
+					t = (t + 1) & CMX_BUFF_MASK;
+					r = (r + 1) & CMX_BUFF_MASK;
+					o_r = (o_r + 1) & CMX_BUFF_MASK;
+				}
+				while (r != rr) {
+					*d++ = dsp_audio_mix_law[(q[r] << 8) | o_q[o_r]];
+					r = (r + 1) & CMX_BUFF_MASK;
+					o_r = (o_r + 1) & CMX_BUFF_MASK;
+				}
 			}
+			dsp->tx_R = t;
+			goto send_packet;
 		}
-		dsp->tx_R = t;
-		goto send_packet;
-	}
 #ifdef DSP_NEVER_DEFINED
 	}
 #endif
@@ -1518,15 +1518,15 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 		 */
 		while (r != rr && t != tt) {
 			sample = dsp_audio_law_to_s32[p[t]] + *c++ -
-			    dsp_audio_law_to_s32[q[r]];
+				dsp_audio_law_to_s32[q[r]];
 			if (sample < -32768)
 				sample = -32768;
 			else if (sample > 32767)
 				sample = 32767;
 			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			    /* conf-rx+tx */
-			r = (r+1) & CMX_BUFF_MASK;
-			t = (t+1) & CMX_BUFF_MASK;
+			/* conf-rx+tx */
+			r = (r + 1) & CMX_BUFF_MASK;
+			t = (t + 1) & CMX_BUFF_MASK;
 		}
 		while (r != rr) {
 			sample = *c++ - dsp_audio_law_to_s32[q[r]];
@@ -1535,10 +1535,10 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 			else if (sample > 32767)
 				sample = 32767;
 			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			    /* conf-rx */
-			r = (r+1) & CMX_BUFF_MASK;
+			/* conf-rx */
+			r = (r + 1) & CMX_BUFF_MASK;
 		}
-	/* -> if echo is enabled */
+		/* -> if echo is enabled */
 	} else {
 		/*
 		 * -> encode conf-data, if tx-data
@@ -1551,9 +1551,9 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 			else if (sample > 32767)
 				sample = 32767;
 			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			    /* conf(echo)+tx */
-			t = (t+1) & CMX_BUFF_MASK;
-			r = (r+1) & CMX_BUFF_MASK;
+			/* conf(echo)+tx */
+			t = (t + 1) & CMX_BUFF_MASK;
+			r = (r + 1) & CMX_BUFF_MASK;
 		}
 		while (r != rr) {
 			sample = *c++;
@@ -1562,8 +1562,8 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 			else if (sample > 32767)
 				sample = 32767;
 			*d++ = dsp_audio_s16_to_law[sample & 0xffff];
-			    /* conf(echo) */
-			r = (r+1) & CMX_BUFF_MASK;
+			/* conf(echo) */
+			r = (r + 1) & CMX_BUFF_MASK;
 		}
 	}
 	dsp->tx_R = t;
@@ -1587,14 +1587,14 @@ send_packet:
 			txskb = mI_alloc_skb(len, GFP_ATOMIC);
 			if (!txskb) {
 				printk(KERN_ERR
-				    "FATAL ERROR in mISDN_dsp.o: "
-				    "cannot alloc %d bytes\n", len);
+				       "FATAL ERROR in mISDN_dsp.o: "
+				       "cannot alloc %d bytes\n", len);
 			} else {
 				thh = mISDN_HEAD_P(txskb);
 				thh->prim = DL_DATA_REQ;
 				thh->id = 0;
-				memcpy(skb_put(txskb, len), nskb->data+preload,
-					len);
+				memcpy(skb_put(txskb, len), nskb->data + preload,
+				       len);
 				/* queue (trigger later) */
 				skb_queue_tail(&dsp->sendq, txskb);
 			}
@@ -1608,7 +1608,7 @@ send_packet:
 	/* pipeline */
 	if (dsp->pipeline.inuse)
 		dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
-			nskb->len);
+					nskb->len);
 	/* crypt */
 	if (dsp->bf_enable)
 		dsp_bf_encrypt(dsp, nskb->data, nskb->len);
@@ -1621,7 +1621,7 @@ static u32	jittercount; /* counter for jitter check */
 struct timer_list dsp_spl_tl;
 u32	dsp_spl_jiffies; /* calculate the next time to fire */
 static u16	dsp_count; /* last sample count */
-static int	dsp_count_valid ; /* if we have last sample count */
+static int	dsp_count_valid; /* if we have last sample count */
 
 void
 dsp_cmx_send(void *arg)
@@ -1630,7 +1630,7 @@ dsp_cmx_send(void *arg)
 	struct dsp_conf_member *member;
 	struct dsp *dsp;
 	int mustmix, members;
-	static s32 mixbuffer[MAX_POLL+100];
+	static s32 mixbuffer[MAX_POLL + 100];
 	s32 *c;
 	u8 *p, *q;
 	int r, rr;
@@ -1675,9 +1675,9 @@ dsp_cmx_send(void *arg)
 #ifdef CMX_CONF_DEBUG
 			if (conf->software && members > 1)
 #else
-			if (conf->software && members > 2)
+				if (conf->software && members > 2)
 #endif
-				mustmix = 1;
+					mustmix = 1;
 		}
 
 		/* transmission required */
@@ -1698,265 +1698,263 @@ dsp_cmx_send(void *arg)
 #ifdef CMX_CONF_DEBUG
 		if (conf->software && members > 1) {
 #else
-		if (conf->software && members > 2) {
+			if (conf->software && members > 2) {
 #endif
-			/* check for hdlc conf */
-			member = list_entry(conf->mlist.next,
-				struct dsp_conf_member, list);
-			if (member->dsp->hdlc)
-				continue;
-			/* mix all data */
-			memset(mixbuffer, 0, length*sizeof(s32));
-			list_for_each_entry(member, &conf->mlist, list) {
-				dsp = member->dsp;
-				/* get range of data to mix */
-				c = mixbuffer;
-				q = dsp->rx_buff;
-				r = dsp->rx_R;
-				rr = (r + length) & CMX_BUFF_MASK;
-				/* add member's data */
-				while (r != rr) {
-					*c++ += dsp_audio_law_to_s32[q[r]];
-					r = (r+1) & CMX_BUFF_MASK;
+				/* check for hdlc conf */
+				member = list_entry(conf->mlist.next,
+						    struct dsp_conf_member, list);
+				if (member->dsp->hdlc)
+					continue;
+				/* mix all data */
+				memset(mixbuffer, 0, length * sizeof(s32));
+				list_for_each_entry(member, &conf->mlist, list) {
+					dsp = member->dsp;
+					/* get range of data to mix */
+					c = mixbuffer;
+					q = dsp->rx_buff;
+					r = dsp->rx_R;
+					rr = (r + length) & CMX_BUFF_MASK;
+					/* add member's data */
+					while (r != rr) {
+						*c++ += dsp_audio_law_to_s32[q[r]];
+						r = (r + 1) & CMX_BUFF_MASK;
+					}
 				}
-			}
-
-			/* process each member */
-			list_for_each_entry(member, &conf->mlist, list) {
-				/* transmission */
-				dsp_cmx_send_member(member->dsp, length,
-				    mixbuffer, members);
-			}
-		}
-	}
 
-	/* delete rx-data, increment buffers, change pointers */
-	list_for_each_entry(dsp, &dsp_ilist, list) {
-		if (dsp->hdlc)
-			continue;
-		p = dsp->rx_buff;
-		q = dsp->tx_buff;
-		r = dsp->rx_R;
-		/* move receive pointer when receiving */
-		if (!dsp->rx_is_off) {
-			rr = (r + length) & CMX_BUFF_MASK;
-			/* delete rx-data */
-			while (r != rr) {
-				p[r] = dsp_silence;
-				r = (r+1) & CMX_BUFF_MASK;
+				/* process each member */
+				list_for_each_entry(member, &conf->mlist, list) {
+					/* transmission */
+					dsp_cmx_send_member(member->dsp, length,
+							    mixbuffer, members);
+				}
 			}
-			/* increment rx-buffer pointer */
-			dsp->rx_R = r; /* write incremented read pointer */
 		}
 
-		/* check current rx_delay */
-		delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
-		if (delay >= CMX_BUFF_HALF)
-			delay = 0; /* will be the delay before next write */
-		/* check for lower delay */
-		if (delay < dsp->rx_delay[0])
-			dsp->rx_delay[0] = delay;
-		/* check current tx_delay */
-		delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
-		if (delay >= CMX_BUFF_HALF)
-			delay = 0; /* will be the delay before next write */
-		/* check for lower delay */
-		if (delay < dsp->tx_delay[0])
-			dsp->tx_delay[0] = delay;
-		if (jittercheck) {
-			/* find the lowest of all rx_delays */
-			delay = dsp->rx_delay[0];
-			i = 1;
-			while (i < MAX_SECONDS_JITTER_CHECK) {
-				if (delay > dsp->rx_delay[i])
-					delay = dsp->rx_delay[i];
-				i++;
-			}
-			/*
-			 * remove rx_delay only if we have delay AND we
-			 * have not preset cmx_delay AND
-			 * the delay is greater dsp_poll
-			 */
-			if (delay > dsp_poll && !dsp->cmx_delay) {
-				if (dsp_debug & DEBUG_DSP_CLOCK)
-					printk(KERN_DEBUG
-					    "%s lowest rx_delay of %d bytes for"
-					    " dsp %s are now removed.\n",
-					    __func__, delay,
-					    dsp->name);
-				r = dsp->rx_R;
-				rr = (r + delay - (dsp_poll >> 1))
-					& CMX_BUFF_MASK;
+		/* delete rx-data, increment buffers, change pointers */
+		list_for_each_entry(dsp, &dsp_ilist, list) {
+			if (dsp->hdlc)
+				continue;
+			p = dsp->rx_buff;
+			q = dsp->tx_buff;
+			r = dsp->rx_R;
+			/* move receive pointer when receiving */
+			if (!dsp->rx_is_off) {
+				rr = (r + length) & CMX_BUFF_MASK;
 				/* delete rx-data */
 				while (r != rr) {
 					p[r] = dsp_silence;
-					r = (r+1) & CMX_BUFF_MASK;
+					r = (r + 1) & CMX_BUFF_MASK;
 				}
 				/* increment rx-buffer pointer */
-				dsp->rx_R = r;
-				    /* write incremented read pointer */
-			}
-			/* find the lowest of all tx_delays */
-			delay = dsp->tx_delay[0];
-			i = 1;
-			while (i < MAX_SECONDS_JITTER_CHECK) {
-				if (delay > dsp->tx_delay[i])
-					delay = dsp->tx_delay[i];
-				i++;
+				dsp->rx_R = r; /* write incremented read pointer */
 			}
-			/*
-			 * remove delay only if we have delay AND we
-			 * have enabled tx_dejitter
-			 */
-			if (delay > dsp_poll && dsp->tx_dejitter) {
-				if (dsp_debug & DEBUG_DSP_CLOCK)
-					printk(KERN_DEBUG
-					    "%s lowest tx_delay of %d bytes for"
-					    " dsp %s are now removed.\n",
-					    __func__, delay,
-					    dsp->name);
-				r = dsp->tx_R;
-				rr = (r + delay - (dsp_poll >> 1))
-					& CMX_BUFF_MASK;
-				/* delete tx-data */
-				while (r != rr) {
-					q[r] = dsp_silence;
-					r = (r+1) & CMX_BUFF_MASK;
+
+			/* check current rx_delay */
+			delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
+			if (delay >= CMX_BUFF_HALF)
+				delay = 0; /* will be the delay before next write */
+			/* check for lower delay */
+			if (delay < dsp->rx_delay[0])
+				dsp->rx_delay[0] = delay;
+			/* check current tx_delay */
+			delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
+			if (delay >= CMX_BUFF_HALF)
+				delay = 0; /* will be the delay before next write */
+			/* check for lower delay */
+			if (delay < dsp->tx_delay[0])
+				dsp->tx_delay[0] = delay;
+			if (jittercheck) {
+				/* find the lowest of all rx_delays */
+				delay = dsp->rx_delay[0];
+				i = 1;
+				while (i < MAX_SECONDS_JITTER_CHECK) {
+					if (delay > dsp->rx_delay[i])
+						delay = dsp->rx_delay[i];
+					i++;
 				}
-				/* increment rx-buffer pointer */
-				dsp->tx_R = r;
-				    /* write incremented read pointer */
-			}
-			/* scroll up delays */
-			i = MAX_SECONDS_JITTER_CHECK - 1;
-			while (i) {
-				dsp->rx_delay[i] = dsp->rx_delay[i-1];
-				dsp->tx_delay[i] = dsp->tx_delay[i-1];
-				i--;
+				/*
+				 * remove rx_delay only if we have delay AND we
+				 * have not preset cmx_delay AND
+				 * the delay is greater dsp_poll
+				 */
+				if (delay > dsp_poll && !dsp->cmx_delay) {
+					if (dsp_debug & DEBUG_DSP_CLOCK)
+						printk(KERN_DEBUG
+						       "%s lowest rx_delay of %d bytes for"
+						       " dsp %s are now removed.\n",
+						       __func__, delay,
+						       dsp->name);
+					r = dsp->rx_R;
+					rr = (r + delay - (dsp_poll >> 1))
+						& CMX_BUFF_MASK;
+					/* delete rx-data */
+					while (r != rr) {
+						p[r] = dsp_silence;
+						r = (r + 1) & CMX_BUFF_MASK;
+					}
+					/* increment rx-buffer pointer */
+					dsp->rx_R = r;
+					/* write incremented read pointer */
+				}
+				/* find the lowest of all tx_delays */
+				delay = dsp->tx_delay[0];
+				i = 1;
+				while (i < MAX_SECONDS_JITTER_CHECK) {
+					if (delay > dsp->tx_delay[i])
+						delay = dsp->tx_delay[i];
+					i++;
+				}
+				/*
+				 * remove delay only if we have delay AND we
+				 * have enabled tx_dejitter
+				 */
+				if (delay > dsp_poll && dsp->tx_dejitter) {
+					if (dsp_debug & DEBUG_DSP_CLOCK)
+						printk(KERN_DEBUG
+						       "%s lowest tx_delay of %d bytes for"
+						       " dsp %s are now removed.\n",
+						       __func__, delay,
+						       dsp->name);
+					r = dsp->tx_R;
+					rr = (r + delay - (dsp_poll >> 1))
+						& CMX_BUFF_MASK;
+					/* delete tx-data */
+					while (r != rr) {
+						q[r] = dsp_silence;
+						r = (r + 1) & CMX_BUFF_MASK;
+					}
+					/* increment rx-buffer pointer */
+					dsp->tx_R = r;
+					/* write incremented read pointer */
+				}
+				/* scroll up delays */
+				i = MAX_SECONDS_JITTER_CHECK - 1;
+				while (i) {
+					dsp->rx_delay[i] = dsp->rx_delay[i - 1];
+					dsp->tx_delay[i] = dsp->tx_delay[i - 1];
+					i--;
+				}
+				dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
+				dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
 			}
-			dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
-			dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
 		}
-	}
 
-	/* if next event would be in the past ... */
-	if ((s32)(dsp_spl_jiffies+dsp_tics-jiffies) <= 0)
-		dsp_spl_jiffies = jiffies + 1;
-	else
-		dsp_spl_jiffies += dsp_tics;
+		/* if next event would be in the past ... */
+		if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0)
+			dsp_spl_jiffies = jiffies + 1;
+		else
+			dsp_spl_jiffies += dsp_tics;
 
-	dsp_spl_tl.expires = dsp_spl_jiffies;
-	add_timer(&dsp_spl_tl);
+		dsp_spl_tl.expires = dsp_spl_jiffies;
+		add_timer(&dsp_spl_tl);
 
-	/* unlock */
-	spin_unlock_irqrestore(&dsp_lock, flags);
-}
+		/* unlock */
+		spin_unlock_irqrestore(&dsp_lock, flags);
+	}
 
 /*
  * audio data is transmitted from upper layer to the dsp
  */
-void
-dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
-{
-	u_int w, ww;
-	u8 *d, *p;
-	int space; /* todo: , l = skb->len; */
+	void
+		dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
+	{
+		u_int w, ww;
+		u8 *d, *p;
+		int space; /* todo: , l = skb->len; */
 #ifdef CMX_TX_DEBUG
-	char debugbuf[256] = "";
+		char debugbuf[256] = "";
 #endif
 
-	/* check if there is enough space, and then copy */
-	w = dsp->tx_W;
-	ww = dsp->tx_R;
-	p = dsp->tx_buff;
-	d = skb->data;
-	space = (ww - w - 1) & CMX_BUFF_MASK;
-	/* write-pointer should not overrun nor reach read pointer */
-	if (space < skb->len) {
-		/* write to the space we have left */
-		ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
-		if (dsp_debug & DEBUG_DSP_CLOCK)
-			printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
-			    "%d, w=0x%04x, ww=0x%04x\n", __func__, space,
-			    skb->len, w, ww);
-	} else
-		/* write until all byte are copied */
-		ww = (w + skb->len) & CMX_BUFF_MASK;
-	dsp->tx_W = ww;
-
-	/* show current buffer */
+		/* check if there is enough space, and then copy */
+		w = dsp->tx_W;
+		ww = dsp->tx_R;
+		p = dsp->tx_buff;
+		d = skb->data;
+		space = (ww - w - 1) & CMX_BUFF_MASK;
+		/* write-pointer should not overrun nor reach read pointer */
+		if (space < skb->len) {
+			/* write to the space we have left */
+			ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */
+			if (dsp_debug & DEBUG_DSP_CLOCK)
+				printk(KERN_DEBUG "%s: TX overflow space=%d skb->len="
+				       "%d, w=0x%04x, ww=0x%04x\n", __func__, space,
+				       skb->len, w, ww);
+		} else
+			/* write until all byte are copied */
+			ww = (w + skb->len) & CMX_BUFF_MASK;
+		dsp->tx_W = ww;
+
+		/* show current buffer */
 #ifdef CMX_DEBUG
-	printk(KERN_DEBUG
-	    "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
-	    (u_long)dsp, (ww-w)&CMX_BUFF_MASK, w, ww, dsp->name);
+		printk(KERN_DEBUG
+		       "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
+		       (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name);
 #endif
 
-	/* copy transmit data to tx-buffer */
+		/* copy transmit data to tx-buffer */
 #ifdef CMX_TX_DEBUG
-	sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
+		sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
 #endif
-	while (w != ww) {
+		while (w != ww) {
 #ifdef CMX_TX_DEBUG
-		if (strlen(debugbuf) < 48)
-			sprintf(debugbuf+strlen(debugbuf), " %02x", *d);
+			if (strlen(debugbuf) < 48)
+				sprintf(debugbuf + strlen(debugbuf), " %02x", *d);
 #endif
-		p[w] = *d++;
-		w = (w+1) & CMX_BUFF_MASK;
-	}
+			p[w] = *d++;
+			w = (w + 1) & CMX_BUFF_MASK;
+		}
 #ifdef CMX_TX_DEBUG
-	printk(KERN_DEBUG "%s\n", debugbuf);
+		printk(KERN_DEBUG "%s\n", debugbuf);
 #endif
 
-}
+	}
 
 /*
  * hdlc data is received from card and sent to all members.
  */
-void
-dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
-{
-	struct sk_buff *nskb = NULL;
-	struct dsp_conf_member *member;
-	struct mISDNhead *hh;
-
-	/* not if not active */
-	if (!dsp->b_active)
-		return;
+	void
+		dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
+	{
+		struct sk_buff *nskb = NULL;
+		struct dsp_conf_member *member;
+		struct mISDNhead *hh;
+
+		/* not if not active */
+		if (!dsp->b_active)
+			return;
 
-	/* check if we have sompen */
-	if (skb->len < 1)
-		return;
+		/* check if we have sompen */
+		if (skb->len < 1)
+			return;
 
-	/* no conf */
-	if (!dsp->conf) {
-		/* in case of software echo */
-		if (dsp->echo.software) {
-			nskb = skb_clone(skb, GFP_ATOMIC);
-			if (nskb) {
-				hh = mISDN_HEAD_P(nskb);
-				hh->prim = PH_DATA_REQ;
-				hh->id = 0;
-				skb_queue_tail(&dsp->sendq, nskb);
-				schedule_work(&dsp->workq);
+		/* no conf */
+		if (!dsp->conf) {
+			/* in case of software echo */
+			if (dsp->echo.software) {
+				nskb = skb_clone(skb, GFP_ATOMIC);
+				if (nskb) {
+					hh = mISDN_HEAD_P(nskb);
+					hh->prim = PH_DATA_REQ;
+					hh->id = 0;
+					skb_queue_tail(&dsp->sendq, nskb);
+					schedule_work(&dsp->workq);
+				}
 			}
+			return;
 		}
-		return;
-	}
-	/* in case of hardware conference */
-	if (dsp->conf->hardware)
-		return;
-	list_for_each_entry(member, &dsp->conf->mlist, list) {
-		if (dsp->echo.software || member->dsp != dsp) {
-			nskb = skb_clone(skb, GFP_ATOMIC);
-			if (nskb) {
-				hh = mISDN_HEAD_P(nskb);
-				hh->prim = PH_DATA_REQ;
-				hh->id = 0;
-				skb_queue_tail(&member->dsp->sendq, nskb);
-				schedule_work(&member->dsp->workq);
+		/* in case of hardware conference */
+		if (dsp->conf->hardware)
+			return;
+		list_for_each_entry(member, &dsp->conf->mlist, list) {
+			if (dsp->echo.software || member->dsp != dsp) {
+				nskb = skb_clone(skb, GFP_ATOMIC);
+				if (nskb) {
+					hh = mISDN_HEAD_P(nskb);
+					hh->prim = PH_DATA_REQ;
+					hh->id = 0;
+					skb_queue_tail(&member->dsp->sendq, nskb);
+					schedule_work(&member->dsp->workq);
+				}
 			}
 		}
 	}
-}
-
-
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 0c41553..2ac2d7a 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -218,20 +218,20 @@ dsp_rx_off_member(struct dsp *dsp)
 	if (!dsp->ch.peer) {
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: no peer, no rx_off\n",
-				__func__);
+			       __func__);
 		return;
 	}
 	cq.op = MISDN_CTRL_RX_OFF;
 	cq.p1 = rx_off;
 	if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
 		printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
-			__func__);
+		       __func__);
 		return;
 	}
 	dsp->rx_is_off = rx_off;
 	if (dsp_debug & DEBUG_DSP_CORE)
 		printk(KERN_DEBUG "%s: %s set rx_off = %d\n",
-			__func__, dsp->name, rx_off);
+		       __func__, dsp->name, rx_off);
 }
 static void
 dsp_rx_off(struct dsp *dsp)
@@ -263,19 +263,19 @@ dsp_fill_empty(struct dsp *dsp)
 	if (!dsp->ch.peer) {
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: no peer, no fill_empty\n",
-				__func__);
+			       __func__);
 		return;
 	}
 	cq.op = MISDN_CTRL_FILL_EMPTY;
 	cq.p1 = 1;
 	if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
 		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-			__func__);
+		       __func__);
 		return;
 	}
 	if (dsp_debug & DEBUG_DSP_CORE)
 		printk(KERN_DEBUG "%s: %s set fill_empty = 1\n",
-			__func__, dsp->name);
+		       __func__, dsp->name);
 }
 
 static int
@@ -304,7 +304,7 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
 		if (len == sizeof(int)) {
 			if (dsp_debug & DEBUG_DSP_CORE)
 				printk(KERN_NOTICE "changing DTMF Threshold "
-					"to %d\n", *((int *)data));
+				       "to %d\n", *((int *)data));
 			dsp->dtmf.treshold = (*(int *)data) * 10000;
 		}
 		dsp->dtmf.enable = 1;
@@ -331,19 +331,19 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
 			goto conf_split;
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: join conference %d\n",
-				__func__, *((u32 *)data));
+			       __func__, *((u32 *)data));
 		ret = dsp_cmx_conf(dsp, *((u32 *)data));
-			/* dsp_cmx_hardware will also be called here */
+		/* dsp_cmx_hardware will also be called here */
 		dsp_rx_off(dsp);
 		if (dsp_debug & DEBUG_DSP_CMX)
 			dsp_cmx_debug(dsp);
 		break;
 	case DSP_CONF_SPLIT: /* remove from conference */
-conf_split:
+	conf_split:
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: release conference\n", __func__);
 		ret = dsp_cmx_conf(dsp, 0);
-			/* dsp_cmx_hardware will also be called here */
+		/* dsp_cmx_hardware will also be called here */
 		if (dsp_debug & DEBUG_DSP_CMX)
 			dsp_cmx_debug(dsp);
 		dsp_rx_off(dsp);
@@ -359,7 +359,7 @@ conf_split:
 		}
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: turn tone 0x%x on\n",
-				__func__, *((int *)skb->data));
+			       __func__, *((int *)skb->data));
 		ret = dsp_tone(dsp, *((int *)data));
 		if (!ret) {
 			dsp_cmx_hardware(dsp->conf, dsp);
@@ -379,7 +379,7 @@ conf_split:
 		dsp_cmx_hardware(dsp->conf, dsp);
 		dsp_rx_off(dsp);
 		/* reset tx buffers (user space data) */
-tone_off:
+	tone_off:
 		dsp->rx_W = 0;
 		dsp->rx_R = 0;
 		break;
@@ -395,7 +395,7 @@ tone_off:
 		dsp->tx_volume = *((int *)data);
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: change tx vol to %d\n",
-				__func__, dsp->tx_volume);
+			       __func__, dsp->tx_volume);
 		dsp_cmx_hardware(dsp->conf, dsp);
 		dsp_dtmf_hardware(dsp);
 		dsp_rx_off(dsp);
@@ -412,7 +412,7 @@ tone_off:
 		dsp->rx_volume = *((int *)data);
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: change rx vol to %d\n",
-				__func__, dsp->tx_volume);
+			       __func__, dsp->tx_volume);
 		dsp_cmx_hardware(dsp->conf, dsp);
 		dsp_dtmf_hardware(dsp);
 		dsp_rx_off(dsp);
@@ -439,14 +439,14 @@ tone_off:
 	case DSP_RECEIVE_ON: /* enable receive to user space */
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: enable receive to user "
-				"space\n", __func__);
+			       "space\n", __func__);
 		dsp->rx_disabled = 0;
 		dsp_rx_off(dsp);
 		break;
 	case DSP_RECEIVE_OFF: /* disable receive to user space */
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: disable receive to "
-				"user space\n", __func__);
+			       "user space\n", __func__);
 		dsp->rx_disabled = 1;
 		dsp_rx_off(dsp);
 		break;
@@ -457,7 +457,7 @@ tone_off:
 		}
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: enable mixing of "
-				"tx-data with conf mebers\n", __func__);
+			       "tx-data with conf mebers\n", __func__);
 		dsp->tx_mix = 1;
 		dsp_cmx_hardware(dsp->conf, dsp);
 		dsp_rx_off(dsp);
@@ -471,7 +471,7 @@ tone_off:
 		}
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: disable mixing of "
-				"tx-data with conf mebers\n", __func__);
+			       "tx-data with conf mebers\n", __func__);
 		dsp->tx_mix = 0;
 		dsp_cmx_hardware(dsp->conf, dsp);
 		dsp_rx_off(dsp);
@@ -507,18 +507,18 @@ tone_off:
 			break;
 		}
 		dsp->cmx_delay = (*((int *)data)) << 3;
-			/* milliseconds to samples */
-		if (dsp->cmx_delay >= (CMX_BUFF_HALF>>1))
+		/* milliseconds to samples */
+		if (dsp->cmx_delay >= (CMX_BUFF_HALF >> 1))
 			/* clip to half of maximum usable buffer
-			(half of half buffer) */
-			dsp->cmx_delay = (CMX_BUFF_HALF>>1) - 1;
+			   (half of half buffer) */
+			dsp->cmx_delay = (CMX_BUFF_HALF >> 1) - 1;
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: use delay algorithm to "
-				"compensate jitter (%d samples)\n",
-				__func__, dsp->cmx_delay);
+			       "compensate jitter (%d samples)\n",
+			       __func__, dsp->cmx_delay);
 		break;
 	case DSP_JITTER: /* use dynamic jitter algorithm instead of
-		    delay algorithm */
+			    delay algorithm */
 		if (dsp->hdlc) {
 			ret = -EINVAL;
 			break;
@@ -526,7 +526,7 @@ tone_off:
 		dsp->cmx_delay = 0;
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: use jitter algorithm to "
-				"compensate jitter\n", __func__);
+			       "compensate jitter\n", __func__);
 		break;
 	case DSP_TX_DEJITTER: /* use dynamic jitter algorithm for tx-buffer */
 		if (dsp->hdlc) {
@@ -536,7 +536,7 @@ tone_off:
 		dsp->tx_dejitter = 1;
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: use dejitter on TX "
-				"buffer\n", __func__);
+			       "buffer\n", __func__);
 		break;
 	case DSP_TX_DEJ_OFF: /* use tx-buffer without dejittering*/
 		if (dsp->hdlc) {
@@ -546,7 +546,7 @@ tone_off:
 		dsp->tx_dejitter = 0;
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: use TX buffer without "
-				"dejittering\n", __func__);
+			       "dejittering\n", __func__);
 		break;
 	case DSP_PIPELINE_CFG:
 		if (dsp->hdlc) {
@@ -555,13 +555,13 @@ tone_off:
 		}
 		if (len > 0 && ((char *)data)[len - 1]) {
 			printk(KERN_DEBUG "%s: pipeline config string "
-				"is not NULL terminated!\n", __func__);
+			       "is not NULL terminated!\n", __func__);
 			ret = -EINVAL;
 		} else {
 			dsp->pipeline.inuse = 1;
 			dsp_cmx_hardware(dsp->conf, dsp);
 			ret = dsp_pipeline_build(&dsp->pipeline,
-				len > 0 ? data : NULL);
+						 len > 0 ? data : NULL);
 			dsp_cmx_hardware(dsp->conf, dsp);
 			dsp_rx_off(dsp);
 		}
@@ -577,7 +577,7 @@ tone_off:
 		}
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: turn blowfish on (key "
-				"not shown)\n", __func__);
+			       "not shown)\n", __func__);
 		ret = dsp_bf_init(dsp, (u8 *)data, len);
 		/* set new cont */
 		if (!ret)
@@ -586,7 +586,7 @@ tone_off:
 			cont = DSP_BF_REJECT;
 		/* send indication if it worked to set it */
 		nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY,
-			sizeof(int), &cont, GFP_ATOMIC);
+					sizeof(int), &cont, GFP_ATOMIC);
 		if (nskb) {
 			if (dsp->up) {
 				if (dsp->up->send(dsp->up, nskb))
@@ -615,7 +615,7 @@ tone_off:
 	default:
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: ctrl req %x unhandled\n",
-				__func__, cont);
+			       __func__, cont);
 		ret = -EINVAL;
 	}
 	return ret;
@@ -630,14 +630,14 @@ get_features(struct mISDNchannel *ch)
 	if (!ch->peer) {
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: no peer, no features\n",
-				__func__);
+			       __func__);
 		return;
 	}
 	memset(&cq, 0, sizeof(cq));
 	cq.op = MISDN_CTRL_GETOP;
 	if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) {
 		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-			__func__);
+		       __func__);
 		return;
 	}
 	if (cq.op & MISDN_CTRL_RX_OFF)
@@ -651,12 +651,12 @@ get_features(struct mISDNchannel *ch)
 		*((u_long *)&cq.p1) = (u_long)&dsp->features;
 		if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) {
 			printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
-				__func__);
+			       __func__);
 		}
 	} else
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: features not supported for %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 }
 
 static int
@@ -670,7 +670,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 
 	hh = mISDN_HEAD_P(skb);
 	switch (hh->prim) {
-	/* FROM DOWN */
+		/* FROM DOWN */
 	case (PH_DATA_CNF):
 		dsp->data_pending = 0;
 		/* trigger next hdlc frame, if any */
@@ -690,8 +690,8 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 		if (dsp->rx_is_off) {
 			if (dsp_debug & DEBUG_DSP_CORE)
 				printk(KERN_DEBUG "%s: rx-data during rx_off"
-					" for %s\n",
-				__func__, dsp->name);
+				       " for %s\n",
+				       __func__, dsp->name);
 		}
 		if (dsp->hdlc) {
 			/* hdlc */
@@ -716,14 +716,14 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 		/* pipeline */
 		if (dsp->pipeline.inuse)
 			dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
-				skb->len, hh->id);
+						skb->len, hh->id);
 		/* change volume if requested */
 		if (dsp->rx_volume)
 			dsp_change_volume(skb, dsp->rx_volume);
 		/* check if dtmf soft decoding is turned on */
 		if (dsp->dtmf.software) {
 			digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
-				skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0);
+							  skb->len, (dsp_options & DSP_OPT_ULAW) ? 1 : 0);
 		}
 		/* we need to process receive data if software */
 		if (dsp->conf && dsp->conf->software) {
@@ -740,16 +740,16 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 				struct sk_buff *nskb;
 				if (dsp_debug & DEBUG_DSP_DTMF)
 					printk(KERN_DEBUG "%s: digit"
-					    "(%c) to layer %s\n",
-					    __func__, *digits, dsp->name);
+					       "(%c) to layer %s\n",
+					       __func__, *digits, dsp->name);
 				k = *digits | DTMF_TONE_VAL;
 				nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
-					MISDN_ID_ANY, sizeof(int), &k,
-					GFP_ATOMIC);
+							MISDN_ID_ANY, sizeof(int), &k,
+							GFP_ATOMIC);
 				if (nskb) {
 					if (dsp->up) {
 						if (dsp->up->send(
-						    dsp->up, nskb))
+							    dsp->up, nskb))
 							dev_kfree_skb(nskb);
 					} else
 						dev_kfree_skb(nskb);
@@ -768,34 +768,34 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 	case (PH_CONTROL_IND):
 		if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
 			printk(KERN_DEBUG "%s: PH_CONTROL INDICATION "
-				"received: %x (len %d) %s\n", __func__,
-				hh->id, skb->len, dsp->name);
+			       "received: %x (len %d) %s\n", __func__,
+			       hh->id, skb->len, dsp->name);
 		switch (hh->id) {
 		case (DTMF_HFC_COEF): /* getting coefficients */
 			if (!dsp->dtmf.hardware) {
 				if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
 					printk(KERN_DEBUG "%s: ignoring DTMF "
-						"coefficients from HFC\n",
-						__func__);
+					       "coefficients from HFC\n",
+					       __func__);
 				break;
 			}
 			digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
-				skb->len, 2);
+							  skb->len, 2);
 			while (*digits) {
 				int k;
 				struct sk_buff *nskb;
 				if (dsp_debug & DEBUG_DSP_DTMF)
 					printk(KERN_DEBUG "%s: digit"
-					    "(%c) to layer %s\n",
-					    __func__, *digits, dsp->name);
+					       "(%c) to layer %s\n",
+					       __func__, *digits, dsp->name);
 				k = *digits | DTMF_TONE_VAL;
 				nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
-					MISDN_ID_ANY, sizeof(int), &k,
-					GFP_ATOMIC);
+							MISDN_ID_ANY, sizeof(int), &k,
+							GFP_ATOMIC);
 				if (nskb) {
 					if (dsp->up) {
 						if (dsp->up->send(
-						    dsp->up, nskb))
+							    dsp->up, nskb))
 							dev_kfree_skb(nskb);
 					} else
 						dev_kfree_skb(nskb);
@@ -812,7 +812,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 			dsp->tx_volume = *((int *)skb->data);
 			if (dsp_debug & DEBUG_DSP_CORE)
 				printk(KERN_DEBUG "%s: change tx volume to "
-					"%d\n", __func__, dsp->tx_volume);
+				       "%d\n", __func__, dsp->tx_volume);
 			dsp_cmx_hardware(dsp->conf, dsp);
 			dsp_dtmf_hardware(dsp);
 			dsp_rx_off(dsp);
@@ -821,7 +821,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 		default:
 			if (dsp_debug & DEBUG_DSP_CORE)
 				printk(KERN_DEBUG "%s: ctrl ind %x unhandled "
-					"%s\n", __func__, hh->id, dsp->name);
+				       "%s\n", __func__, hh->id, dsp->name);
 			ret = -EINVAL;
 		}
 		break;
@@ -829,13 +829,13 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 	case (PH_ACTIVATE_CNF):
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: b_channel is now active %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 		/* bchannel now active */
 		spin_lock_irqsave(&dsp_lock, flags);
 		dsp->b_active = 1;
 		dsp->data_pending = 0;
 		dsp->rx_init = 1;
-			/* rx_W and rx_R will be adjusted on first frame */
+		/* rx_W and rx_R will be adjusted on first frame */
 		dsp->rx_W = 0;
 		dsp->rx_R = 0;
 		memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff));
@@ -845,8 +845,8 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 		spin_unlock_irqrestore(&dsp_lock, flags);
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: done with activation, sending "
-				"confirm to user space. %s\n", __func__,
-				dsp->name);
+			       "confirm to user space. %s\n", __func__,
+			       dsp->name);
 		/* send activation to upper layer */
 		hh->prim = DL_ESTABLISH_CNF;
 		if (dsp->up)
@@ -856,7 +856,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 	case (PH_DEACTIVATE_CNF):
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: b_channel is now inactive %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 		/* bchannel now inactive */
 		spin_lock_irqsave(&dsp_lock, flags);
 		dsp->b_active = 0;
@@ -868,7 +868,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 		if (dsp->up)
 			return dsp->up->send(dsp->up, skb);
 		break;
-	/* FROM UP */
+		/* FROM UP */
 	case (DL_DATA_REQ):
 	case (PH_DATA_REQ):
 		if (skb->len < 1) {
@@ -904,7 +904,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 	case (PH_ACTIVATE_REQ):
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: activating b_channel %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 		if (dsp->dtmf.hardware || dsp->dtmf.software)
 			dsp_dtmf_goertzel_init(dsp);
 		get_features(ch);
@@ -920,7 +920,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 	case (PH_DEACTIVATE_REQ):
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: releasing b_channel %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 		spin_lock_irqsave(&dsp_lock, flags);
 		dsp->tone.tone = 0;
 		dsp->tone.hardware = 0;
@@ -939,7 +939,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 	default:
 		if (dsp_debug & DEBUG_DSP_CORE)
 			printk(KERN_DEBUG "%s: msg %x unhandled %s\n",
-				__func__, hh->prim, dsp->name);
+			       __func__, hh->prim, dsp->name);
 		ret = -EINVAL;
 	}
 	if (!ret)
@@ -978,7 +978,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 		skb_queue_purge(&dsp->sendq);
 		if (dsp_debug & DEBUG_DSP_CTRL)
 			printk(KERN_DEBUG "%s: releasing member %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 		dsp->b_active = 0;
 		dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be called
 					 here */
@@ -986,13 +986,13 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 		if (dsp_debug & DEBUG_DSP_CTRL)
 			printk(KERN_DEBUG "%s: remove & destroy object %s\n",
-				__func__, dsp->name);
+			       __func__, dsp->name);
 		list_del(&dsp->list);
 		spin_unlock_irqrestore(&dsp_lock, flags);
 
 		if (dsp_debug & DEBUG_DSP_CTRL)
 			printk(KERN_DEBUG "%s: dsp instance released\n",
-				__func__);
+			       __func__);
 		vfree(dsp);
 		module_put(THIS_MODULE);
 		break;
@@ -1016,7 +1016,7 @@ dsp_send_bh(struct work_struct *work)
 		if (dsp->data_pending) {
 			if (dsp_debug & DEBUG_DSP_CORE)
 				printk(KERN_DEBUG "%s: fifo full %s, this is "
-					"no bug!\n", __func__, dsp->name);
+				       "no bug!\n", __func__, dsp->name);
 			/* flush transparent data, if not acked */
 			dev_kfree_skb(skb);
 			continue;
@@ -1050,7 +1050,7 @@ dspcreate(struct channel_req *crq)
 	u_long		flags;
 
 	if (crq->protocol != ISDN_P_B_L2DSP
-	 && crq->protocol != ISDN_P_B_L2DSPHDLC)
+	    && crq->protocol != ISDN_P_B_L2DSPHDLC)
 		return -EPROTONOSUPPORT;
 	ndsp = vzalloc(sizeof(struct dsp));
 	if (!ndsp) {
@@ -1076,7 +1076,7 @@ dspcreate(struct channel_req *crq)
 	}
 	if (!try_module_get(THIS_MODULE))
 		printk(KERN_WARNING "%s:cannot get module\n",
-			__func__);
+		       __func__);
 
 	sprintf(ndsp->name, "DSP_C%x(0x%p)",
 		ndsp->up->st->dev->id + 1, ndsp);
@@ -1095,7 +1095,7 @@ dspcreate(struct channel_req *crq)
 
 	if (dtmfthreshold < 20 || dtmfthreshold > 500)
 		dtmfthreshold = 200;
-	ndsp->dtmf.treshold = dtmfthreshold*10000;
+	ndsp->dtmf.treshold = dtmfthreshold * 10000;
 
 	/* init pipeline append to list */
 	spin_lock_irqsave(&dsp_lock, flags);
@@ -1109,7 +1109,7 @@ dspcreate(struct channel_req *crq)
 
 static struct Bprotocol DSP = {
 	.Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))
-		| (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
+	| (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
 	.name = "dsp",
 	.create = dspcreate
 };
@@ -1119,7 +1119,7 @@ static int __init dsp_init(void)
 	int err;
 	int tics;
 
-	printk(KERN_INFO "DSP modul %s\n", mISDN_dsp_revision);
+	printk(KERN_INFO "DSP module %s\n", mISDN_dsp_revision);
 
 	dsp_options = options;
 	dsp_debug = debug;
@@ -1129,21 +1129,21 @@ static int __init dsp_init(void)
 	if (dsp_poll) {
 		if (dsp_poll > MAX_POLL) {
 			printk(KERN_ERR "%s: Wrong poll value (%d), use %d "
-				"maximum.\n", __func__, poll, MAX_POLL);
+			       "maximum.\n", __func__, poll, MAX_POLL);
 			err = -EINVAL;
 			return err;
 		}
 		if (dsp_poll < 8) {
 			printk(KERN_ERR "%s: Wrong poll value (%d), use 8 "
-				"minimum.\n", __func__, dsp_poll);
+			       "minimum.\n", __func__, dsp_poll);
 			err = -EINVAL;
 			return err;
 		}
 		dsp_tics = poll * HZ / 8000;
 		if (dsp_tics * 8000 != poll * HZ) {
 			printk(KERN_INFO "mISDN_dsp: Cannot clock every %d "
-				"samples (0,125 ms). It is not a multiple of "
-				"%d HZ.\n", poll, HZ);
+			       "samples (0,125 ms). It is not a multiple of "
+			       "%d HZ.\n", poll, HZ);
 			err = -EINVAL;
 			return err;
 		}
@@ -1162,14 +1162,14 @@ static int __init dsp_init(void)
 	}
 	if (dsp_poll == 0) {
 		printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel "
-			"clock that equals exactly the duration of 8-256 "
-			"samples. (Choose kernel clock speed like 100, 250, "
-			"300, 1000)\n");
+		       "clock that equals exactly the duration of 8-256 "
+		       "samples. (Choose kernel clock speed like 100, 250, "
+		       "300, 1000)\n");
 		err = -EINVAL;
 		return err;
 	}
 	printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals "
-		"%d jiffies.\n", dsp_poll, dsp_tics);
+	       "%d jiffies.\n", dsp_poll, dsp_tics);
 
 	spin_lock_init(&dsp_lock);
 	INIT_LIST_HEAD(&dsp_ilist);
@@ -1177,8 +1177,8 @@ static int __init dsp_init(void)
 
 	/* init conversion tables */
 	dsp_audio_generate_law_tables();
-	dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a;
-	dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ?
+	dsp_silence = (dsp_options & DSP_OPT_ULAW) ? 0xff : 0x2a;
+	dsp_audio_law_to_s32 = (dsp_options & DSP_OPT_ULAW) ?
 		dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
 	dsp_audio_generate_s2law_table();
 	dsp_audio_generate_seven();
@@ -1190,7 +1190,7 @@ static int __init dsp_init(void)
 	err = dsp_pipeline_module_init();
 	if (err) {
 		printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, "
-			"error(%d)\n", err);
+		       "error(%d)\n", err);
 		return err;
 	}
 
@@ -1221,11 +1221,11 @@ static void __exit dsp_cleanup(void)
 
 	if (!list_empty(&dsp_ilist)) {
 		printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
-			"empty.\n");
+		       "empty.\n");
 	}
 	if (!list_empty(&conf_ilist)) {
 		printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not "
-			"all memory freed.\n");
+		       "all memory freed.\n");
 	}
 
 	dsp_pipeline_module_exit();
@@ -1233,4 +1233,3 @@ static void __exit dsp_cleanup(void)
 
 module_init(dsp_init);
 module_exit(dsp_cleanup);
-
diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c
index 5b484c3..887860b 100644
--- a/drivers/isdn/mISDN/dsp_dtmf.c
+++ b/drivers/isdn/mISDN/dsp_dtmf.c
@@ -61,31 +61,31 @@ void dsp_dtmf_hardware(struct dsp *dsp)
 	if (dsp->tx_volume) {
 		if (dsp_debug & DEBUG_DSP_DTMF)
 			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-				"because tx_volume is changed\n",
-				__func__, dsp->name);
+			       "because tx_volume is changed\n",
+			       __func__, dsp->name);
 		hardware = 0;
 	}
 	if (dsp->rx_volume) {
 		if (dsp_debug & DEBUG_DSP_DTMF)
 			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-				"because rx_volume is changed\n",
-				__func__, dsp->name);
+			       "because rx_volume is changed\n",
+			       __func__, dsp->name);
 		hardware = 0;
 	}
 	/* check if encryption is enabled */
 	if (dsp->bf_enable) {
 		if (dsp_debug & DEBUG_DSP_DTMF)
 			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-				"because encryption is enabled\n",
-				__func__, dsp->name);
+			       "because encryption is enabled\n",
+			       __func__, dsp->name);
 		hardware = 0;
 	}
 	/* check if pipeline exists */
 	if (dsp->pipeline.inuse) {
 		if (dsp_debug & DEBUG_DSP_DTMF)
 			printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
-				"because pipeline exists.\n",
-				__func__, dsp->name);
+			       "because pipeline exists.\n",
+			       __func__, dsp->name);
 		hardware = 0;
 	}
 
@@ -150,23 +150,23 @@ again:
 		if (len < 64) {
 			if (len > 0)
 				printk(KERN_ERR "%s: coefficients have invalid "
-					"size. (is=%d < must=%d)\n",
-					__func__, len, 64);
+				       "size. (is=%d < must=%d)\n",
+				       __func__, len, 64);
 			return dsp->dtmf.digits;
 		}
 		hfccoeff = (s32 *)data;
 		for (k = 0; k < NCOEFF; k++) {
-			sk2 = (*hfccoeff++)>>4;
-			sk = (*hfccoeff++)>>4;
+			sk2 = (*hfccoeff++) >> 4;
+			sk = (*hfccoeff++) >> 4;
 			if (sk > 32767 || sk < -32767 || sk2 > 32767
 			    || sk2 < -32767)
 				printk(KERN_WARNING
-					"DTMF-Detection overflow\n");
+				       "DTMF-Detection overflow\n");
 			/* compute |X(k)|**2 */
 			result[k] =
-				 (sk * sk) -
-				 (((cos2pik[k] * sk) >> 15) * sk2) +
-				 (sk2 * sk2);
+				(sk * sk) -
+				(((cos2pik[k] * sk) >> 15) * sk2) +
+				(sk2 * sk2);
 		}
 		data += 64;
 		len -= 64;
@@ -188,7 +188,7 @@ again:
 		buf = dsp->dtmf.buffer;
 		cos2pik_ = cos2pik[k];
 		for (n = 0; n < DSP_DTMF_NPOINTS; n++) {
-			sk = ((cos2pik_*sk1)>>15) - sk2 + (*buf++);
+			sk = ((cos2pik_ * sk1) >> 15) - sk2 + (*buf++);
 			sk2 = sk1;
 			sk1 = sk;
 		}
@@ -224,14 +224,14 @@ coefficients:
 
 	if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
 		printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d"
-			" tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n",
-			result[0]/10000, result[1]/10000, result[2]/10000,
-			result[3]/10000, result[4]/10000, result[5]/10000,
-			result[6]/10000, result[7]/10000, tresh/10000,
-			result[0]/(tresh/100), result[1]/(tresh/100),
-			result[2]/(tresh/100), result[3]/(tresh/100),
-			result[4]/(tresh/100), result[5]/(tresh/100),
-			result[6]/(tresh/100), result[7]/(tresh/100));
+		       " tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n",
+		       result[0] / 10000, result[1] / 10000, result[2] / 10000,
+		       result[3] / 10000, result[4] / 10000, result[5] / 10000,
+		       result[6] / 10000, result[7] / 10000, tresh / 10000,
+		       result[0] / (tresh / 100), result[1] / (tresh / 100),
+		       result[2] / (tresh / 100), result[3] / (tresh / 100),
+		       result[4] / (tresh / 100), result[5] / (tresh / 100),
+		       result[6] / (tresh / 100), result[7] / (tresh / 100));
 
 	/* calc digit (lowgroup/highgroup) */
 	lowgroup = -1;
@@ -247,7 +247,7 @@ coefficients:
 			break;  /* noise in between */
 		}
 		/* good level found. This is allowed only one time per group */
-		if (i < NCOEFF/2) {
+		if (i < NCOEFF / 2) {
 			/* lowgroup */
 			if (lowgroup >= 0) {
 				/* Bad. Another tone found. */
@@ -262,7 +262,7 @@ coefficients:
 				highgroup = -1;
 				break;
 			} else
-				highgroup = i-(NCOEFF/2);
+				highgroup = i - (NCOEFF / 2);
 		}
 	}
 
@@ -285,13 +285,13 @@ storedigit:
 			if (what) {
 				if (dsp_debug & DEBUG_DSP_DTMF)
 					printk(KERN_DEBUG "DTMF digit: %c\n",
-						what);
-				if ((strlen(dsp->dtmf.digits)+1)
-					< sizeof(dsp->dtmf.digits)) {
+					       what);
+				if ((strlen(dsp->dtmf.digits) + 1)
+				    < sizeof(dsp->dtmf.digits)) {
 					dsp->dtmf.digits[strlen(
-						dsp->dtmf.digits)+1] = '\0';
+							dsp->dtmf.digits) + 1] = '\0';
 					dsp->dtmf.digits[strlen(
-						dsp->dtmf.digits)] = what;
+							dsp->dtmf.digits)] = what;
 				}
 			}
 		}
@@ -302,5 +302,3 @@ storedigit:
 
 	goto again;
 }
-
-
diff --git a/drivers/isdn/mISDN/dsp_ecdis.h b/drivers/isdn/mISDN/dsp_ecdis.h
index 21dbd15..fed99ac 100644
--- a/drivers/isdn/mISDN/dsp_ecdis.h
+++ b/drivers/isdn/mISDN/dsp_ecdis.h
@@ -46,15 +46,15 @@ struct ec_disable_detector_state {
 static inline void
 echo_can_disable_detector_init(struct ec_disable_detector_state *det)
 {
-    /* Elliptic notch */
-    /* This is actually centred at 2095Hz, but gets the balance we want, due
-       to the asymmetric walls of the notch */
+	/* Elliptic notch */
+	/* This is actually centred at 2095Hz, but gets the balance we want, due
+	   to the asymmetric walls of the notch */
 	biquad2_init(&det->notch,
-		(int32_t) (-0.7600000*32768.0),
-		(int32_t) (-0.1183852*32768.0),
-		(int32_t) (-0.5104039*32768.0),
-		(int32_t) (0.1567596*32768.0),
-		(int32_t) (1.0000000*32768.0));
+		     (int32_t)(-0.7600000 * 32768.0),
+		     (int32_t)(-0.1183852 * 32768.0),
+		     (int32_t)(-0.5104039 * 32768.0),
+		     (int32_t)(0.1567596 * 32768.0),
+		     (int32_t)(1.0000000 * 32768.0));
 
 	det->channel_level = 0;
 	det->notch_level = 0;
@@ -67,7 +67,7 @@ echo_can_disable_detector_init(struct ec_disable_detector_state *det)
 
 static inline int
 echo_can_disable_detector_update(struct ec_disable_detector_state *det,
-int16_t amp)
+				 int16_t amp)
 {
 	int16_t notched;
 
@@ -82,13 +82,13 @@ int16_t amp)
 	det->notch_level += ((abs(notched) - det->notch_level) >> 4);
 	if (det->channel_level > 280) {
 		/* There is adequate energy in the channel.
-		 Is it mostly at 2100Hz? */
-		if (det->notch_level*6 < det->channel_level) {
+		   Is it mostly at 2100Hz? */
+		if (det->notch_level * 6 < det->channel_level) {
 			/* The notch says yes, so we have the tone. */
 			if (!det->tone_present) {
 				/* Do we get a kick every 450+-25ms? */
-				if (det->tone_cycle_duration >= 425*8
-					&& det->tone_cycle_duration <= 475*8) {
+				if (det->tone_cycle_duration >= 425 * 8
+				    && det->tone_cycle_duration <= 475 * 8) {
 					det->good_cycles++;
 					if (det->good_cycles > 2)
 						det->hit = TRUE;
diff --git a/drivers/isdn/mISDN/dsp_hwec.c b/drivers/isdn/mISDN/dsp_hwec.c
index 806a997..a6e8707 100644
--- a/drivers/isdn/mISDN/dsp_hwec.c
+++ b/drivers/isdn/mISDN/dsp_hwec.c
@@ -56,7 +56,7 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
 
 	if (!dsp) {
 		printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n",
-			__func__);
+		       __func__);
 		return;
 	}
 
@@ -93,13 +93,13 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
 
 _do:
 	printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n",
-		__func__, deftaps);
+	       __func__, deftaps);
 	memset(&cq, 0, sizeof(cq));
 	cq.op = MISDN_CTRL_HFC_ECHOCAN_ON;
 	cq.p1 = deftaps;
 	if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
 		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-			__func__);
+		       __func__);
 		return;
 	}
 }
@@ -110,7 +110,7 @@ void dsp_hwec_disable(struct dsp *dsp)
 
 	if (!dsp) {
 		printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n",
-			__func__);
+		       __func__);
 		return;
 	}
 
@@ -119,7 +119,7 @@ void dsp_hwec_disable(struct dsp *dsp)
 	cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF;
 	if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
 		printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
-			__func__);
+		       __func__);
 		return;
 	}
 }
@@ -135,4 +135,3 @@ void dsp_hwec_exit(void)
 {
 	mISDN_dsp_element_unregister(dsp_hwec);
 }
-
diff --git a/drivers/isdn/mISDN/dsp_hwec.h b/drivers/isdn/mISDN/dsp_hwec.h
index eebe80c..bbca1eb 100644
--- a/drivers/isdn/mISDN/dsp_hwec.h
+++ b/drivers/isdn/mISDN/dsp_hwec.h
@@ -7,4 +7,3 @@ extern void dsp_hwec_enable(struct dsp *dsp, const char *arg);
 extern void dsp_hwec_disable(struct dsp *dsp);
 extern int  dsp_hwec_init(void);
 extern void dsp_hwec_exit(void);
-
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
index b6c9a58..88305c9 100644
--- a/drivers/isdn/mISDN/dsp_pipeline.c
+++ b/drivers/isdn/mISDN/dsp_pipeline.c
@@ -63,11 +63,11 @@ attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
 	*buf = 0;
 	for (i = 0; i < elem->num_args; i++)
 		p += sprintf(p, "Name:        %s\n%s%s%sDescription: %s\n\n",
-			  elem->args[i].name,
-			  elem->args[i].def ? "Default:     " : "",
-			  elem->args[i].def ? elem->args[i].def : "",
-			  elem->args[i].def ? "\n" : "",
-			  elem->args[i].desc);
+			     elem->args[i].name,
+			     elem->args[i].def ? "Default:     " : "",
+			     elem->args[i].def ? elem->args[i].def : "",
+			     elem->args[i].def ? "\n" : "",
+			     elem->args[i].desc);
 
 	return p - buf;
 }
@@ -106,17 +106,17 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
 	ret = device_register(&entry->dev);
 	if (ret) {
 		printk(KERN_ERR "%s: failed to register %s\n",
-			__func__, elem->name);
+		       __func__, elem->name);
 		goto err1;
 	}
 	list_add_tail(&entry->list, &dsp_elements);
 
 	for (i = 0; i < ARRAY_SIZE(element_attributes); ++i) {
 		ret = device_create_file(&entry->dev,
-				&element_attributes[i]);
+					 &element_attributes[i]);
 		if (ret) {
 			printk(KERN_ERR "%s: failed to create device file\n",
-				__func__);
+			       __func__);
 			goto err2;
 		}
 	}
@@ -148,7 +148,7 @@ void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem)
 			device_unregister(&entry->dev);
 #ifdef PIPELINE_DEBUG
 			printk(KERN_DEBUG "%s: %s unregistered\n",
-				__func__, elem->name);
+			       __func__, elem->name);
 #endif
 			return;
 		}
@@ -182,7 +182,7 @@ void dsp_pipeline_module_exit(void)
 	list_for_each_entry_safe(entry, n, &dsp_elements, list) {
 		list_del(&entry->list);
 		printk(KERN_WARNING "%s: element was still registered: %s\n",
-			__func__, entry->elem->name);
+		       __func__, entry->elem->name);
 		kfree(entry);
 	}
 
@@ -213,7 +213,7 @@ static inline void _dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
 		list_del(&entry->list);
 		if (entry->elem == dsp_hwec)
 			dsp_hwec_disable(container_of(pipeline, struct dsp,
-				pipeline));
+						      pipeline));
 		else
 			entry->elem->free(entry->p);
 		kfree(entry);
@@ -271,11 +271,11 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
 				elem = entry->elem;
 
 				pipeline_entry = kmalloc(sizeof(struct
-					dsp_pipeline_entry), GFP_ATOMIC);
+								dsp_pipeline_entry), GFP_ATOMIC);
 				if (!pipeline_entry) {
 					printk(KERN_ERR "%s: failed to add "
-					    "entry to pipeline: %s (out of "
-					    "memory)\n", __func__, elem->name);
+					       "entry to pipeline: %s (out of "
+					       "memory)\n", __func__, elem->name);
 					incomplete = 1;
 					goto _out;
 				}
@@ -285,26 +285,26 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
 					/* This is a hack to make the hwec
 					   available as a pipeline module */
 					dsp_hwec_enable(container_of(pipeline,
-						struct dsp, pipeline), args);
+								     struct dsp, pipeline), args);
 					list_add_tail(&pipeline_entry->list,
-						&pipeline->list);
+						      &pipeline->list);
 				} else {
 					pipeline_entry->p = elem->new(args);
 					if (pipeline_entry->p) {
 						list_add_tail(&pipeline_entry->
-							list, &pipeline->list);
+							      list, &pipeline->list);
 #ifdef PIPELINE_DEBUG
 						printk(KERN_DEBUG "%s: created "
-						    "instance of %s%s%s\n",
-						    __func__, name, args ?
-						    " with args " : "", args ?
-						    args : "");
+						       "instance of %s%s%s\n",
+						       __func__, name, args ?
+						       " with args " : "", args ?
+						       args : "");
 #endif
 					} else {
 						printk(KERN_ERR "%s: failed "
-						  "to add entry to pipeline: "
-						  "%s (new() returned NULL)\n",
-						  __func__, elem->name);
+						       "to add entry to pipeline: "
+						       "%s (new() returned NULL)\n",
+						       __func__, elem->name);
 						kfree(pipeline_entry);
 						incomplete = 1;
 					}
@@ -317,7 +317,7 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
 			found = 0;
 		else {
 			printk(KERN_ERR "%s: element not found, skipping: "
-				"%s\n", __func__, name);
+			       "%s\n", __func__, name);
 			incomplete = 1;
 		}
 	}
@@ -330,7 +330,7 @@ _out:
 
 #ifdef PIPELINE_DEBUG
 	printk(KERN_DEBUG "%s: dsp pipeline built%s: %s\n",
-		__func__, incomplete ? " incomplete" : "", cfg);
+	       __func__, incomplete ? " incomplete" : "", cfg);
 #endif
 	kfree(dup);
 	return 0;
@@ -349,7 +349,7 @@ void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
 }
 
 void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
-	unsigned int txlen)
+			     unsigned int txlen)
 {
 	struct dsp_pipeline_entry *entry;
 
@@ -360,5 +360,3 @@ void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
 		if (entry->elem->process_rx)
 			entry->elem->process_rx(entry->p, data, len, txlen);
 }
-
-
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
index 4e4440e..057e0d6 100644
--- a/drivers/isdn/mISDN/dsp_tones.c
+++ b/drivers/isdn/mISDN/dsp_tones.c
@@ -239,120 +239,120 @@ static struct pattern {
 	u32 seq[10];
 } pattern[] = {
 	{TONE_GERMAN_DIALTONE,
-	{DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GA, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_OLDDIALTONE,
-	{DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_AMERICAN_DIALTONE,
-	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_DIALPBX,
-	{DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
-		NULL},
-	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
-		NULL},
-	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
+	 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
+	  NULL},
+	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
+	  NULL},
+	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_OLDDIALPBX,
-	{DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
-		NULL},
-	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
-		NULL},
-	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
+	 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
+	  NULL},
+	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
+	  NULL},
+	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 
 	{TONE_AMERICAN_DIALPBX,
-	{DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
-		NULL},
-	{SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
-		NULL},
-	{2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
+	 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
+	  NULL},
+	 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
+	  NULL},
+	 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_RINGING,
-	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_OLDRINGING,
-	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_AMERICAN_RINGING,
-	{DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_RINGPBX,
-	{DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_OLDRINGPBX,
-	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_AMERICAN_RINGPBX,
-	{DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
+	 {DATA_RI, DATA_S, DATA_RI, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_BUSY,
-	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_OLDBUSY,
-	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_AMERICAN_BUSY,
-	{DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_BU, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_BU, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_HANGUP,
-	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_OLDHANGUP,
-	{DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_AMERICAN_HANGUP,
-	{DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_DT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_SPECIAL_INFO,
-	{DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
+	 {DATA_S1, DATA_S2, DATA_S3, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_GASSENBESETZT,
-	{DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GA, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
 
 	{TONE_GERMAN_AUFSCHALTTON,
-	{DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
-	{1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
+	 {DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
 
 	{0,
-	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 };
 
 /******************
@@ -386,7 +386,7 @@ void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
 
 	/* process pattern */
 	pat = (struct pattern *)tone->pattern;
-		/* points to the current pattern */
+	/* points to the current pattern */
 	index = tone->index; /* gives current sequence index */
 	count = tone->count; /* gives current sample */
 
@@ -404,19 +404,19 @@ void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
 				break;
 			if (dsp_debug & DEBUG_DSP_TONE)
 				printk(KERN_DEBUG "%s: reaching next sequence "
-					"(index=%d)\n", __func__, index);
+				       "(index=%d)\n", __func__, index);
 			count -= pat->seq[index];
 			index++;
 		}
 		/* calculate start and number of samples */
 		start = count % (*(pat->siz[index]));
 		num = len;
-		if (num+count > pat->seq[index])
+		if (num + count > pat->seq[index])
 			num = pat->seq[index] - count;
-		if (num+start > (*(pat->siz[index])))
+		if (num + start > (*(pat->siz[index])))
 			num = (*(pat->siz[index])) - start;
 		/* copy memory */
-		memcpy(data, pat->data[index]+start, num);
+		memcpy(data, pat->data[index] + start, num);
 		/* reduce length */
 		data += num;
 		count += num;
@@ -441,8 +441,8 @@ dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
 
 	/* unlocking is not required, because we don't expect a response */
 	nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
-		(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
-		GFP_ATOMIC);
+				(len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
+				GFP_ATOMIC);
 	if (nskb) {
 		if (dsp->ch.peer) {
 			if (dsp->ch.recv(dsp->ch.peer, nskb))
@@ -528,7 +528,7 @@ dsp_tone(struct dsp *dsp, int tone)
 	}
 	if (dsp_debug & DEBUG_DSP_TONE)
 		printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
-			__func__, tone, 0);
+		       __func__, tone, 0);
 	tonet->tone = tone;
 	tonet->pattern = pat;
 	tonet->index = 0;
@@ -550,8 +550,3 @@ dsp_tone(struct dsp *dsp, int tone)
 
 	return 0;
 }
-
-
-
-
-
diff --git a/drivers/isdn/mISDN/fsm.c b/drivers/isdn/mISDN/fsm.c
index b5d6553..26477d4 100644
--- a/drivers/isdn/mISDN/fsm.c
+++ b/drivers/isdn/mISDN/fsm.c
@@ -28,23 +28,23 @@
 
 void
 mISDN_FsmNew(struct Fsm *fsm,
-       struct FsmNode *fnlist, int fncount)
+	     struct FsmNode *fnlist, int fncount)
 {
 	int i;
 
 	fsm->jumpmatrix = kzalloc(sizeof(FSMFNPTR) * fsm->state_count *
-		fsm->event_count, GFP_KERNEL);
+				  fsm->event_count, GFP_KERNEL);
 
 	for (i = 0; i < fncount; i++)
 		if ((fnlist[i].state >= fsm->state_count) ||
 		    (fnlist[i].event >= fsm->event_count)) {
 			printk(KERN_ERR
-			    "mISDN_FsmNew Error: %d st(%ld/%ld) ev(%ld/%ld)\n",
-			    i, (long)fnlist[i].state, (long)fsm->state_count,
-			    (long)fnlist[i].event, (long)fsm->event_count);
+			       "mISDN_FsmNew Error: %d st(%ld/%ld) ev(%ld/%ld)\n",
+			       i, (long)fnlist[i].state, (long)fsm->state_count,
+			       (long)fnlist[i].event, (long)fsm->event_count);
 		} else
 			fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
-			    fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
+					fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
 }
 EXPORT_SYMBOL(mISDN_FsmNew);
 
@@ -63,24 +63,24 @@ mISDN_FsmEvent(struct FsmInst *fi, int event, void *arg)
 	if ((fi->state >= fi->fsm->state_count) ||
 	    (event >= fi->fsm->event_count)) {
 		printk(KERN_ERR
-		    "mISDN_FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
-		    (long)fi->state, (long)fi->fsm->state_count, event,
-		    (long)fi->fsm->event_count);
+		       "mISDN_FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
+		       (long)fi->state, (long)fi->fsm->state_count, event,
+		       (long)fi->fsm->event_count);
 		return 1;
 	}
 	r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state];
 	if (r) {
 		if (fi->debug)
 			fi->printdebug(fi, "State %s Event %s",
-				fi->fsm->strState[fi->state],
-				fi->fsm->strEvent[event]);
+				       fi->fsm->strState[fi->state],
+				       fi->fsm->strEvent[event]);
 		r(fi, event, arg);
 		return 0;
 	} else {
 		if (fi->debug)
 			fi->printdebug(fi, "State %s Event %s no action",
-				fi->fsm->strState[fi->state],
-				fi->fsm->strEvent[event]);
+				       fi->fsm->strState[fi->state],
+				       fi->fsm->strEvent[event]);
 		return 1;
 	}
 }
@@ -92,7 +92,7 @@ mISDN_FsmChangeState(struct FsmInst *fi, int newstate)
 	fi->state = newstate;
 	if (fi->debug)
 		fi->printdebug(fi, "ChangeState %s",
-			fi->fsm->strState[newstate]);
+			       fi->fsm->strState[newstate]);
 }
 EXPORT_SYMBOL(mISDN_FsmChangeState);
 
@@ -126,7 +126,7 @@ mISDN_FsmDelTimer(struct FsmTimer *ft, int where)
 #if FSM_TIMER_DEBUG
 	if (ft->fi->debug)
 		ft->fi->printdebug(ft->fi, "mISDN_FsmDelTimer %lx %d",
-			(long) ft, where);
+				   (long) ft, where);
 #endif
 	del_timer(&ft->tl);
 }
@@ -134,21 +134,21 @@ EXPORT_SYMBOL(mISDN_FsmDelTimer);
 
 int
 mISDN_FsmAddTimer(struct FsmTimer *ft,
-	    int millisec, int event, void *arg, int where)
+		  int millisec, int event, void *arg, int where)
 {
 
 #if FSM_TIMER_DEBUG
 	if (ft->fi->debug)
 		ft->fi->printdebug(ft->fi, "mISDN_FsmAddTimer %lx %d %d",
-			(long) ft, millisec, where);
+				   (long) ft, millisec, where);
 #endif
 
 	if (timer_pending(&ft->tl)) {
 		if (ft->fi->debug) {
 			printk(KERN_WARNING
-				"mISDN_FsmAddTimer: timer already active!\n");
+			       "mISDN_FsmAddTimer: timer already active!\n");
 			ft->fi->printdebug(ft->fi,
-				"mISDN_FsmAddTimer already active!");
+					   "mISDN_FsmAddTimer already active!");
 		}
 		return -1;
 	}
@@ -163,13 +163,13 @@ EXPORT_SYMBOL(mISDN_FsmAddTimer);
 
 void
 mISDN_FsmRestartTimer(struct FsmTimer *ft,
-	    int millisec, int event, void *arg, int where)
+		      int millisec, int event, void *arg, int where)
 {
 
 #if FSM_TIMER_DEBUG
 	if (ft->fi->debug)
 		ft->fi->printdebug(ft->fi, "mISDN_FsmRestartTimer %lx %d %d",
-			(long) ft, millisec, where);
+				   (long) ft, millisec, where);
 #endif
 
 	if (timer_pending(&ft->tl))
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index f6e108d..c74c363 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -206,7 +206,7 @@ recv_Bchannel(struct bchannel *bch, unsigned int id)
 	hh->id = id;
 	if (bch->rcount >= 64) {
 		printk(KERN_WARNING "B-channel %p receive queue overflow, "
-			"flushing!\n", bch);
+		       "flushing!\n", bch);
 		skb_queue_purge(&bch->rqueue);
 		bch->rcount = 0;
 		return;
@@ -231,7 +231,7 @@ recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb)
 {
 	if (bch->rcount >= 64) {
 		printk(KERN_WARNING "B-channel %p receive queue overflow, "
-			"flushing!\n", bch);
+		       "flushing!\n", bch);
 		skb_queue_purge(&bch->rqueue);
 		bch->rcount = 0;
 	}
@@ -247,10 +247,10 @@ confirm_Dsend(struct dchannel *dch)
 	struct sk_buff	*skb;
 
 	skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb),
-	    0, NULL, GFP_ATOMIC);
+			       0, NULL, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_ERR "%s: no skb id %x\n", __func__,
-		    mISDN_HEAD_ID(dch->tx_skb));
+		       mISDN_HEAD_ID(dch->tx_skb));
 		return;
 	}
 	skb_queue_tail(&dch->rqueue, skb);
@@ -279,15 +279,15 @@ confirm_Bsend(struct bchannel *bch)
 
 	if (bch->rcount >= 64) {
 		printk(KERN_WARNING "B-channel %p receive queue overflow, "
-			"flushing!\n", bch);
+		       "flushing!\n", bch);
 		skb_queue_purge(&bch->rqueue);
 		bch->rcount = 0;
 	}
 	skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb),
-	    0, NULL, GFP_ATOMIC);
+			       0, NULL, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_ERR "%s: no skb id %x\n", __func__,
-		    mISDN_HEAD_ID(bch->tx_skb));
+		       mISDN_HEAD_ID(bch->tx_skb));
 		return;
 	}
 	bch->rcount++;
@@ -349,7 +349,7 @@ dchannel_senddata(struct dchannel *ch, struct sk_buff *skb)
 	}
 	if (skb->len > ch->maxlen) {
 		printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
-			__func__, skb->len, ch->maxlen);
+		       __func__, skb->len, ch->maxlen);
 		return -EINVAL;
 	}
 	/* HW lock must be obtained */
@@ -376,15 +376,15 @@ bchannel_senddata(struct bchannel *ch, struct sk_buff *skb)
 	}
 	if (skb->len > ch->maxlen) {
 		printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
-			__func__, skb->len, ch->maxlen);
+		       __func__, skb->len, ch->maxlen);
 		return -EINVAL;
 	}
 	/* HW lock must be obtained */
 	/* check for pending next_skb */
 	if (ch->next_skb) {
 		printk(KERN_WARNING
-		    "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
-		    __func__, skb->len, ch->next_skb->len);
+		       "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
+		       __func__, skb->len, ch->next_skb->len);
 		return -EBUSY;
 	}
 	if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h
index bc26c89..661c060 100644
--- a/drivers/isdn/mISDN/l1oip.h
+++ b/drivers/isdn/mISDN/l1oip.h
@@ -10,7 +10,7 @@
 
 /* enable to disorder received bchannels by sequence 2143658798... */
 /*
-#define REORDER_DEBUG
+  #define REORDER_DEBUG
 */
 
 /* frames */
@@ -29,8 +29,8 @@
 
 /* channel structure */
 struct l1oip_chan {
-	struct dchannel       	*dch;
-	struct bchannel       	*bch;
+	struct dchannel		*dch;
+	struct bchannel		*bch;
 	u32			tx_counter;	/* counts xmit bytes/packets */
 	u32			rx_counter;	/* counts recv bytes/packets */
 	u32			codecstate;	/* used by codec to save data */
@@ -60,19 +60,19 @@ struct l1oip {
 	int			limit;		/* limit number of bchannels */
 
 	/* timer */
-	struct timer_list 	keep_tl;
-	struct timer_list 	timeout_tl;
+	struct timer_list	keep_tl;
+	struct timer_list	timeout_tl;
 	int			timeout_on;
 	struct work_struct	workq;
 
 	/* socket */
-	struct socket 		*socket;	/* if set, socket is created */
-	struct completion 	socket_complete;/* completion of sock thread */
+	struct socket		*socket;	/* if set, socket is created */
+	struct completion	socket_complete;/* completion of sock thread */
 	struct task_struct	*socket_thread;
-	spinlock_t 		socket_lock;	/* access sock outside thread */
+	spinlock_t		socket_lock;	/* access sock outside thread */
 	u32			remoteip;	/* if all set, ip is assigned */
-	u16	 		localport;	/* must always be set */
-	u16	 		remoteport;	/* must always be set */
+	u16			localport;	/* must always be set */
+	u16			remoteport;	/* must always be set */
 	struct sockaddr_in	sin_local;	/* local socket name */
 	struct sockaddr_in	sin_remote;	/* remote socket name */
 	struct msghdr		sendmsg;	/* ip message to send */
@@ -88,4 +88,3 @@ extern int l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result);
 extern int l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result);
 extern void l1oip_4bit_free(void);
 extern int l1oip_4bit_alloc(int ulaw);
-
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
index 5a89972..a601c84 100644
--- a/drivers/isdn/mISDN/l1oip_codec.c
+++ b/drivers/isdn/mISDN/l1oip_codec.c
@@ -27,22 +27,22 @@
 
 /*
 
-How the codec works:
---------------------
+  How the codec works:
+  --------------------
 
-The volume is increased to increase the dynamic range of the audio signal.
-Each sample is converted to a-LAW with only 16 steps of level resolution.
-A pair of two samples are stored in one byte.
+  The volume is increased to increase the dynamic range of the audio signal.
+  Each sample is converted to a-LAW with only 16 steps of level resolution.
+  A pair of two samples are stored in one byte.
 
-The first byte is stored in the upper bits, the second byte is stored in the
-lower bits.
+  The first byte is stored in the upper bits, the second byte is stored in the
+  lower bits.
 
-To speed up compression and decompression, two lookup tables are formed:
+  To speed up compression and decompression, two lookup tables are formed:
 
-- 16 bits index for two samples (law encoded) with 8 bit compressed result.
-- 8 bits index for one compressed data with 16 bits decompressed result.
+  - 16 bits index for two samples (law encoded) with 8 bit compressed result.
+  - 8 bits index for one compressed data with 16 bits decompressed result.
 
-NOTE: The bytes are handled as they are law-encoded.
+  NOTE: The bytes are handled as they are law-encoded.
 
 */
 
@@ -232,7 +232,7 @@ l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
 
 	/* send saved byte and first input byte */
 	if (*state) {
-		*result++ = table_com[(((*state)<<8)&0xff00) | (*data++)];
+		*result++ = table_com[(((*state) << 8) & 0xff00) | (*data++)];
 		len--;
 		o++;
 	}
@@ -267,7 +267,7 @@ l1oip_4bit_to_law(u8 *data, int len, u8 *result)
 
 	while (i < len) {
 		r = table_dec[*data++];
-		*result++ = r>>8;
+		*result++ = r >> 8;
 		*result++ = r;
 		i++;
 	}
@@ -345,8 +345,8 @@ l1oip_4bit_alloc(int ulaw)
 			c = alaw_to_4bit[i1];
 		i2 = 0;
 		while (i2 < 256) {
-			table_com[(i1<<8) | i2] |= (c<<4);
-			table_com[(i2<<8) | i1] |= c;
+			table_com[(i1 << 8) | i2] |= (c << 4);
+			table_com[(i2 << 8) | i1] |= c;
 			i2++;
 		}
 		i1++;
@@ -361,8 +361,8 @@ l1oip_4bit_alloc(int ulaw)
 			sample = _4bit_to_alaw[i1];
 		i2 = 0;
 		while (i2 < 16) {
-			table_dec[(i1<<4) | i2] |= (sample<<8);
-			table_dec[(i2<<4) | i1] |= sample;
+			table_dec[(i1 << 4) | i2] |= (sample << 8);
+			table_dec[(i2 << 4) | i1] |= sample;
 			i2++;
 		}
 		i1++;
@@ -370,5 +370,3 @@ l1oip_4bit_alloc(int ulaw)
 
 	return 0;
 }
-
-
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index 22f8ec8..0f88acf 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -24,63 +24,63 @@
 
 /* module parameters:
  * type:
-	Value 1	= BRI
-	Value 2	= PRI
-	Value 3 = BRI (multi channel frame, not supported yet)
-	Value 4 = PRI (multi channel frame, not supported yet)
-	A multi channel frame reduces overhead to a single frame for all
-	b-channels, but increases delay.
-	(NOTE: Multi channel frames are not implemented yet.)
+ Value 1	= BRI
+ Value 2	= PRI
+ Value 3 = BRI (multi channel frame, not supported yet)
+ Value 4 = PRI (multi channel frame, not supported yet)
+ A multi channel frame reduces overhead to a single frame for all
+ b-channels, but increases delay.
+ (NOTE: Multi channel frames are not implemented yet.)
 
  * codec:
-	Value 0 = transparent (default)
-	Value 1 = transfer ALAW
-	Value 2 = transfer ULAW
-	Value 3 = transfer generic 4 bit compression.
+ Value 0 = transparent (default)
+ Value 1 = transfer ALAW
+ Value 2 = transfer ULAW
+ Value 3 = transfer generic 4 bit compression.
 
  * ulaw:
-	0 = we use a-Law (default)
-	1 = we use u-Law
+ 0 = we use a-Law (default)
+ 1 = we use u-Law
 
  * limit:
-	limitation of B-channels to control bandwidth (1...126)
-	BRI: 1 or 2
-	PRI: 1-30, 31-126 (126, because dchannel ist not counted here)
-	Also limited ressources are used for stack, resulting in less channels.
-	It is possible to have more channels than 30 in PRI mode, this must
-	be supported by the application.
+ limitation of B-channels to control bandwidth (1...126)
+ BRI: 1 or 2
+ PRI: 1-30, 31-126 (126, because dchannel ist not counted here)
+ Also limited ressources are used for stack, resulting in less channels.
+ It is possible to have more channels than 30 in PRI mode, this must
+ be supported by the application.
 
  * ip:
-	byte representation of remote ip address (127.0.0.1 -> 127,0,0,1)
-	If not given or four 0, no remote address is set.
-	For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1)
+ byte representation of remote ip address (127.0.0.1 -> 127,0,0,1)
+ If not given or four 0, no remote address is set.
+ For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1)
 
  * port:
-	port number (local interface)
-	If not given or 0, port 931 is used for fist instance, 932 for next...
-	For multiple interfaces, different ports must be given.
+ port number (local interface)
+ If not given or 0, port 931 is used for fist instance, 932 for next...
+ For multiple interfaces, different ports must be given.
 
  * remoteport:
-	port number (remote interface)
-	If not given or 0, remote port equals local port
-	For multiple interfaces on equal sites, different ports must be given.
+ port number (remote interface)
+ If not given or 0, remote port equals local port
+ For multiple interfaces on equal sites, different ports must be given.
 
  * ondemand:
-	0 = fixed (always transmit packets, even when remote side timed out)
-	1 = on demand (only transmit packets, when remote side is detected)
-	the default is 0
-	NOTE: ID must also be set for on demand.
+ 0 = fixed (always transmit packets, even when remote side timed out)
+ 1 = on demand (only transmit packets, when remote side is detected)
+ the default is 0
+ NOTE: ID must also be set for on demand.
 
  * id:
-	optional value to identify frames. This value must be equal on both
-	peers and should be random. If omitted or 0, no ID is transmitted.
+ optional value to identify frames. This value must be equal on both
+ peers and should be random. If omitted or 0, no ID is transmitted.
 
  * debug:
-	NOTE: only one debug value must be given for all cards
-	enable debugging (see l1oip.h for debug options)
+ NOTE: only one debug value must be given for all cards
+ enable debugging (see l1oip.h for debug options)
 
 
-Special mISDN controls:
+ Special mISDN controls:
 
  op = MISDN_CTRL_SETPEER*
  p1 = bytes 0-3 : remote IP address in network order (left element first)
@@ -91,133 +91,133 @@ Special mISDN controls:
  op = MISDN_CTRL_UNSETPEER*
 
  * Use l1oipctrl for comfortable setting or removing ip address.
-   (Layer 1 Over IP CTRL)
+ (Layer 1 Over IP CTRL)
 
 
-L1oIP-Protocol
---------------
+ L1oIP-Protocol
+ --------------
 
-Frame Header:
+ Frame Header:
 
  7 6 5 4 3 2 1 0
-+---------------+
-|Ver|T|I|Coding |
-+---------------+
-|  ID byte 3 *  |
-+---------------+
-|  ID byte 2 *  |
-+---------------+
-|  ID byte 1 *  |
-+---------------+
-|  ID byte 0 *  |
-+---------------+
-|M|   Channel   |
-+---------------+
-|    Length *   |
-+---------------+
-| Time Base MSB |
-+---------------+
-| Time Base LSB |
-+---------------+
-| Data....	|
-
-...
-
-|               |
-+---------------+
-|M|   Channel   |
-+---------------+
-|    Length *   |
-+---------------+
-| Time Base MSB |
-+---------------+
-| Time Base LSB |
-+---------------+
-| Data....	|
-
-...
-
-
-* Only included in some cases.
-
-- Ver = Version
-If version is missmatch, the frame must be ignored.
-
-- T = Type of interface
-Must be 0 for S0 or 1 for E1.
-
-- I = Id present
-If bit is set, four ID bytes are included in frame.
-
-- ID = Connection ID
-Additional ID to prevent Denial of Service attacs. Also it prevents hijacking
-connections with dynamic IP. The ID should be random and must not be 0.
-
-- Coding = Type of codec
-Must be 0 for no transcoding. Also for D-channel and other HDLC frames.
+ +---------------+
+ |Ver|T|I|Coding |
+ +---------------+
+ |  ID byte 3 *  |
+ +---------------+
+ |  ID byte 2 *  |
+ +---------------+
+ |  ID byte 1 *  |
+ +---------------+
+ |  ID byte 0 *  |
+ +---------------+
+ |M|   Channel   |
+ +---------------+
+ |    Length *   |
+ +---------------+
+ | Time Base MSB |
+ +---------------+
+ | Time Base LSB |
+ +---------------+
+ | Data....	|
+
+ ...
+
+ |               |
+ +---------------+
+ |M|   Channel   |
+ +---------------+
+ |    Length *   |
+ +---------------+
+ | Time Base MSB |
+ +---------------+
+ | Time Base LSB |
+ +---------------+
+ | Data....	|
+
+ ...
+
+
+ * Only included in some cases.
+
+ - Ver = Version
+ If version is missmatch, the frame must be ignored.
+
+ - T = Type of interface
+ Must be 0 for S0 or 1 for E1.
+
+ - I = Id present
+ If bit is set, four ID bytes are included in frame.
+
+ - ID = Connection ID
+ Additional ID to prevent Denial of Service attacs. Also it prevents hijacking
+ connections with dynamic IP. The ID should be random and must not be 0.
+
+ - Coding = Type of codec
+ Must be 0 for no transcoding. Also for D-channel and other HDLC frames.
  1 and 2 are reserved for explicitly use of a-LAW or u-LAW codec.
  3 is used for generic table compressor.
 
-- M = More channels to come. If this flag is 1, the following byte contains
-the length of the channel data. After the data block, the next channel will
-be defined. The flag for the last channel block (or if only one channel is
-transmitted), must be 0 and no length is given.
+ - M = More channels to come. If this flag is 1, the following byte contains
+ the length of the channel data. After the data block, the next channel will
+ be defined. The flag for the last channel block (or if only one channel is
+ transmitted), must be 0 and no length is given.
 
-- Channel = Channel number
-0 reserved
-1-3 channel data for S0 (3 is D-channel)
-1-31 channel data for E1 (16 is D-channel)
-32-127 channel data for extended E1 (16 is D-channel)
+ - Channel = Channel number
+ 0 reserved
+ 1-3 channel data for S0 (3 is D-channel)
+ 1-31 channel data for E1 (16 is D-channel)
+ 32-127 channel data for extended E1 (16 is D-channel)
 
-- The length is used if the M-flag is 1. It is used to find the next channel
-inside frame.
-NOTE: A value of 0 equals 256 bytes of data.
+ - The length is used if the M-flag is 1. It is used to find the next channel
+ inside frame.
+ NOTE: A value of 0 equals 256 bytes of data.
  -> For larger data blocks, a single frame must be used.
  -> For larger streams, a single frame or multiple blocks with same channel ID
-   must be used.
+ must be used.
 
-- Time Base = Timestamp of first sample in frame
-The "Time Base" is used to rearange packets and to detect packet loss.
-The 16 bits are sent in network order (MSB first) and count 1/8000 th of a
-second. This causes a wrap around each 8,192 seconds. There is no requirement
-for the initial "Time Base", but 0 should be used for the first packet.
-In case of HDLC data, this timestamp counts the packet or byte number.
+ - Time Base = Timestamp of first sample in frame
+ The "Time Base" is used to rearange packets and to detect packet loss.
+ The 16 bits are sent in network order (MSB first) and count 1/8000 th of a
+ second. This causes a wrap around each 8,192 seconds. There is no requirement
+ for the initial "Time Base", but 0 should be used for the first packet.
+ In case of HDLC data, this timestamp counts the packet or byte number.
 
 
-Two Timers:
+ Two Timers:
 
-After initialisation, a timer of 15 seconds is started. Whenever a packet is
-transmitted, the timer is reset to 15 seconds again. If the timer expires, an
-empty packet is transmitted. This keep the connection alive.
+ After initialisation, a timer of 15 seconds is started. Whenever a packet is
+ transmitted, the timer is reset to 15 seconds again. If the timer expires, an
+ empty packet is transmitted. This keep the connection alive.
 
-When a valid packet is received, a timer 65 seconds is started. The interface
-become ACTIVE. If the timer expires, the interface becomes INACTIVE.
+ When a valid packet is received, a timer 65 seconds is started. The interface
+ become ACTIVE. If the timer expires, the interface becomes INACTIVE.
 
 
-Dynamic IP handling:
+ Dynamic IP handling:
 
-To allow dynamic IP, the ID must be non 0. In this case, any packet with the
-correct port number and ID will be accepted. If the remote side changes its IP
-the new IP is used for all transmitted packets until it changes again.
+ To allow dynamic IP, the ID must be non 0. In this case, any packet with the
+ correct port number and ID will be accepted. If the remote side changes its IP
+ the new IP is used for all transmitted packets until it changes again.
 
 
-On Demand:
+ On Demand:
 
-If the ondemand parameter is given, the remote IP is set to 0 on timeout.
-This will stop keepalive traffic to remote. If the remote is online again,
-traffic will continue to the remote address. This is useful for road warriors.
-This feature only works with ID set, otherwhise it is highly unsecure.
+ If the ondemand parameter is given, the remote IP is set to 0 on timeout.
+ This will stop keepalive traffic to remote. If the remote is online again,
+ traffic will continue to the remote address. This is useful for road warriors.
+ This feature only works with ID set, otherwhise it is highly unsecure.
 
 
-Socket and Thread
------------------
+ Socket and Thread
+ -----------------
 
-The complete socket opening and closing is done by a thread.
-When the thread opened a socket, the hc->socket descriptor is set. Whenever a
-packet shall be sent to the socket, the hc->socket must be checked wheter not
-NULL. To prevent change in socket descriptor, the hc->socket_lock must be used.
-To change the socket, a recall of l1oip_socket_open() will safely kill the
-socket process and create a new one.
+ The complete socket opening and closing is done by a thread.
+ When the thread opened a socket, the hc->socket descriptor is set. Whenever a
+ packet shall be sent to the socket, the hc->socket must be checked wheter not
+ NULL. To prevent change in socket descriptor, the hc->socket_lock must be used.
+ To change the socket, a recall of l1oip_socket_open() will safely kill the
+ socket process and create a new one.
 
 */
 
@@ -247,7 +247,7 @@ static struct list_head l1oip_ilist;
 #define MAX_CARDS	16
 static u_int type[MAX_CARDS];
 static u_int codec[MAX_CARDS];
-static u_int ip[MAX_CARDS*4];
+static u_int ip[MAX_CARDS * 4];
 static u_int port[MAX_CARDS];
 static u_int remoteport[MAX_CARDS];
 static u_int ondemand[MAX_CARDS];
@@ -274,26 +274,26 @@ module_param(debug, uint, S_IRUGO | S_IWUSR);
  */
 static int
 l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
-	u16 timebase, u8 *buf, int len)
+		  u16 timebase, u8 *buf, int len)
 {
 	u8 *p;
 	int multi = 0;
-	u8 frame[len+32];
+	u8 frame[len + 32];
 	struct socket *socket = NULL;
 
 	if (debug & DEBUG_L1OIP_MSG)
 		printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
-			__func__, len);
+		       __func__, len);
 
 	p = frame;
 
 	/* restart timer */
-	if ((int)(hc->keep_tl.expires-jiffies) < 5*HZ) {
+	if ((int)(hc->keep_tl.expires-jiffies) < 5 * HZ) {
 		del_timer(&hc->keep_tl);
-		hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ;
+		hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
 		add_timer(&hc->keep_tl);
 	} else
-		hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ;
+		hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
 
 	if (debug & DEBUG_L1OIP_MSG)
 		printk(KERN_DEBUG "%s: resetting timer\n", __func__);
@@ -302,25 +302,25 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
 	if (!hc->sin_remote.sin_addr.s_addr || !hc->sin_remote.sin_port) {
 		if (debug & DEBUG_L1OIP_MSG)
 			printk(KERN_DEBUG "%s: dropping frame, because remote "
-				"IP is not set.\n", __func__);
+			       "IP is not set.\n", __func__);
 		return len;
 	}
 
 	/* assemble frame */
-	*p++ = (L1OIP_VERSION<<6) /* version and coding */
-	     | (hc->pri ? 0x20 : 0x00) /* type */
-	     | (hc->id ? 0x10 : 0x00) /* id */
-	     | localcodec;
+	*p++ = (L1OIP_VERSION << 6) /* version and coding */
+		| (hc->pri ? 0x20 : 0x00) /* type */
+		| (hc->id ? 0x10 : 0x00) /* id */
+		| localcodec;
 	if (hc->id) {
-		*p++ = hc->id>>24; /* id */
-		*p++ = hc->id>>16;
-		*p++ = hc->id>>8;
+		*p++ = hc->id >> 24; /* id */
+		*p++ = hc->id >> 16;
+		*p++ = hc->id >> 8;
 		*p++ = hc->id;
 	}
 	*p++ = (multi == 1) ? 0x80 : 0x00 + channel; /* m-flag, channel */
 	if (multi == 1)
 		*p++ = len; /* length */
-	*p++ = timebase>>8; /* time base */
+	*p++ = timebase >> 8; /* time base */
 	*p++ = timebase;
 
 	if (buf && len) { /* add data to frame */
@@ -330,7 +330,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
 			l1oip_alaw_to_ulaw(buf, len, p);
 		else if (localcodec == 3)
 			len = l1oip_law_to_4bit(buf, len, p,
-				&hc->chan[channel].codecstate);
+						&hc->chan[channel].codecstate);
 		else
 			memcpy(p, buf, len);
 	}
@@ -349,7 +349,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
 	/* send packet */
 	if (debug & DEBUG_L1OIP_MSG)
 		printk(KERN_DEBUG "%s: sending packet to socket (len "
-			"= %d)\n", __func__, len);
+		       "= %d)\n", __func__, len);
 	hc->sendiov.iov_base = frame;
 	hc->sendiov.iov_len  = len;
 	len = kernel_sendmsg(socket, &hc->sendmsg, &hc->sendiov, 1, len);
@@ -365,7 +365,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
  */
 static void
 l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
-	u8 *buf, int len)
+		  u8 *buf, int len)
 {
 	struct sk_buff *nskb;
 	struct bchannel *bch;
@@ -376,34 +376,34 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
 	if (len == 0) {
 		if (debug & DEBUG_L1OIP_MSG)
 			printk(KERN_DEBUG "%s: received empty keepalive data, "
-				"ignoring\n", __func__);
+			       "ignoring\n", __func__);
 		return;
 	}
 
 	if (debug & DEBUG_L1OIP_MSG)
 		printk(KERN_DEBUG "%s: received data, sending to mISDN (%d)\n",
-			__func__, len);
+		       __func__, len);
 
 	if (channel < 1 || channel > 127) {
 		printk(KERN_WARNING "%s: packet error - channel %d out of "
-			"range\n", __func__, channel);
+		       "range\n", __func__, channel);
 		return;
 	}
 	dch = hc->chan[channel].dch;
 	bch = hc->chan[channel].bch;
 	if (!dch && !bch) {
 		printk(KERN_WARNING "%s: packet error - channel %d not in "
-			"stack\n", __func__, channel);
+		       "stack\n", __func__, channel);
 		return;
 	}
 
 	/* prepare message */
-	nskb = mI_alloc_skb((remotecodec == 3) ? (len<<1) : len, GFP_ATOMIC);
+	nskb = mI_alloc_skb((remotecodec == 3) ? (len << 1) : len, GFP_ATOMIC);
 	if (!nskb) {
 		printk(KERN_ERR "%s: No mem for skb.\n", __func__);
 		return;
 	}
-	p = skb_put(nskb, (remotecodec == 3) ? (len<<1) : len);
+	p = skb_put(nskb, (remotecodec == 3) ? (len << 1) : len);
 
 	if (remotecodec == 1 && ulaw)
 		l1oip_alaw_to_ulaw(buf, len, p);
@@ -428,7 +428,7 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
 				rx_counter =
 					(rx_counter & 0xffff0000) | timebase;
 			else
-				rx_counter = ((rx_counter & 0xffff0000)+0x10000)
+				rx_counter = ((rx_counter & 0xffff0000) + 0x10000)
 					| timebase;
 		} else {
 			/* time has changed backwards */
@@ -436,7 +436,7 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
 				rx_counter =
 					(rx_counter & 0xffff0000) | timebase;
 			else
-				rx_counter = ((rx_counter & 0xffff0000)-0x10000)
+				rx_counter = ((rx_counter & 0xffff0000) - 0x10000)
 					| timebase;
 		}
 		hc->chan[channel].rx_counter = rx_counter;
@@ -476,42 +476,42 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
 
 	if (debug & DEBUG_L1OIP_MSG)
 		printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
-			__func__, len);
+		       __func__, len);
 
 	/* check length */
-	if (len < 1+1+2) {
+	if (len < 1 + 1 + 2) {
 		printk(KERN_WARNING "%s: packet error - length %d below "
-			"4 bytes\n", __func__, len);
+		       "4 bytes\n", __func__, len);
 		return;
 	}
 
 	/* check version */
-	if (((*buf)>>6) != L1OIP_VERSION) {
+	if (((*buf) >> 6) != L1OIP_VERSION) {
 		printk(KERN_WARNING "%s: packet error - unknown version %d\n",
-			__func__, buf[0]>>6);
+		       __func__, buf[0]>>6);
 		return;
 	}
 
 	/* check type */
-	if (((*buf)&0x20) && !hc->pri) {
+	if (((*buf) & 0x20) && !hc->pri) {
 		printk(KERN_WARNING "%s: packet error - received E1 packet "
-			"on S0 interface\n", __func__);
+		       "on S0 interface\n", __func__);
 		return;
 	}
-	if (!((*buf)&0x20) && hc->pri) {
+	if (!((*buf) & 0x20) && hc->pri) {
 		printk(KERN_WARNING "%s: packet error - received S0 packet "
-			"on E1 interface\n", __func__);
+		       "on E1 interface\n", __func__);
 		return;
 	}
 
 	/* get id flag */
-	packet_id = (*buf>>4)&1;
+	packet_id = (*buf >> 4) & 1;
 
 	/* check coding */
 	remotecodec = (*buf) & 0x0f;
 	if (remotecodec > 3) {
 		printk(KERN_WARNING "%s: packet error - remotecodec %d "
-			"unsupported\n", __func__, remotecodec);
+		       "unsupported\n", __func__, remotecodec);
 		return;
 	}
 	buf++;
@@ -521,12 +521,12 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
 	if (packet_id) {
 		if (!hc->id) {
 			printk(KERN_WARNING "%s: packet error - packet has id "
-				"0x%x, but we have not\n", __func__, packet_id);
+			       "0x%x, but we have not\n", __func__, packet_id);
 			return;
 		}
 		if (len < 4) {
 			printk(KERN_WARNING "%s: packet error - packet too "
-				"short for ID value\n", __func__);
+			       "short for ID value\n", __func__);
 			return;
 		}
 		packet_id = (*buf++) << 24;
@@ -537,14 +537,14 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
 
 		if (packet_id != hc->id) {
 			printk(KERN_WARNING "%s: packet error - ID mismatch, "
-				"got 0x%x, we 0x%x\n",
-				__func__, packet_id, hc->id);
+			       "got 0x%x, we 0x%x\n",
+			       __func__, packet_id, hc->id);
 			return;
 		}
 	} else {
 		if (hc->id) {
 			printk(KERN_WARNING "%s: packet error - packet has no "
-				"ID, but we have\n", __func__);
+			       "ID, but we have\n", __func__);
 			return;
 		}
 	}
@@ -552,13 +552,13 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
 multiframe:
 	if (len < 1) {
 		printk(KERN_WARNING "%s: packet error - packet too short, "
-			"channel expected at position %d.\n",
-			__func__, len-len_start+1);
+		       "channel expected at position %d.\n",
+		       __func__, len-len_start + 1);
 		return;
 	}
 
 	/* get channel and multiframe flag */
-	channel = *buf&0x7f;
+	channel = *buf & 0x7f;
 	m = *buf >> 7;
 	buf++;
 	len--;
@@ -567,8 +567,8 @@ multiframe:
 	if (m) {
 		if (len < 1) {
 			printk(KERN_WARNING "%s: packet error - packet too "
-				"short, length expected at position %d.\n",
-				__func__, len_start-len-1);
+			       "short, length expected at position %d.\n",
+			       __func__, len_start - len - 1);
 			return;
 		}
 
@@ -576,26 +576,26 @@ multiframe:
 		len--;
 		if (mlen == 0)
 			mlen = 256;
-		if (len < mlen+3) {
+		if (len < mlen + 3) {
 			printk(KERN_WARNING "%s: packet error - length %d at "
-				"position %d exceeds total length %d.\n",
-				__func__, mlen, len_start-len-1, len_start);
+			       "position %d exceeds total length %d.\n",
+			       __func__, mlen, len_start-len - 1, len_start);
 			return;
 		}
-		if (len == mlen+3) {
+		if (len == mlen + 3) {
 			printk(KERN_WARNING "%s: packet error - length %d at "
-				"position %d will not allow additional "
-				"packet.\n",
-				__func__, mlen, len_start-len+1);
+			       "position %d will not allow additional "
+			       "packet.\n",
+			       __func__, mlen, len_start-len + 1);
 			return;
 		}
 	} else
-		mlen = len-2; /* single frame, subtract timebase */
+		mlen = len - 2; /* single frame, subtract timebase */
 
 	if (len < 2) {
 		printk(KERN_WARNING "%s: packet error - packet too short, time "
-			"base expected at position %d.\n",
-			__func__, len-len_start+1);
+		       "base expected at position %d.\n",
+		       __func__, len-len_start + 1);
 		return;
 	}
 
@@ -606,12 +606,12 @@ multiframe:
 
 	/* if inactive, we send up a PH_ACTIVATE and activate */
 	if (!test_bit(FLG_ACTIVE, &dch->Flags)) {
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: interface become active due to "
-				"received packet\n", __func__);
+			       "received packet\n", __func__);
 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_ATOMIC);
+			    NULL, GFP_ATOMIC);
 	}
 
 	/* distribute packet */
@@ -624,24 +624,24 @@ multiframe:
 		goto multiframe;
 
 	/* restart timer */
-	if ((int)(hc->timeout_tl.expires-jiffies) < 5*HZ || !hc->timeout_on) {
+	if ((int)(hc->timeout_tl.expires-jiffies) < 5 * HZ || !hc->timeout_on) {
 		hc->timeout_on = 1;
 		del_timer(&hc->timeout_tl);
-		hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ;
+		hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ;
 		add_timer(&hc->timeout_tl);
 	} else /* only adjust timer */
-		hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ;
+		hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ;
 
 	/* if ip or source port changes */
 	if ((hc->sin_remote.sin_addr.s_addr != sin->sin_addr.s_addr)
-	 || (hc->sin_remote.sin_port != sin->sin_port)) {
+	    || (hc->sin_remote.sin_port != sin->sin_port)) {
 		if (debug & DEBUG_L1OIP_SOCKET)
 			printk(KERN_DEBUG "%s: remote address changes from "
-				"0x%08x to 0x%08x (port %d to %d)\n", __func__,
-				ntohl(hc->sin_remote.sin_addr.s_addr),
-				ntohl(sin->sin_addr.s_addr),
-				ntohs(hc->sin_remote.sin_port),
-				ntohs(sin->sin_port));
+			       "0x%08x to 0x%08x (port %d to %d)\n", __func__,
+			       ntohl(hc->sin_remote.sin_addr.s_addr),
+			       ntohl(sin->sin_addr.s_addr),
+			       ntohs(hc->sin_remote.sin_port),
+			       ntohs(sin->sin_port));
 		hc->sin_remote.sin_addr.s_addr = sin->sin_addr.s_addr;
 		hc->sin_remote.sin_port = sin->sin_port;
 	}
@@ -694,9 +694,9 @@ l1oip_socket_thread(void *data)
 
 	/* bind to incomming port */
 	if (socket->ops->bind(socket, (struct sockaddr *)&hc->sin_local,
-	    sizeof(hc->sin_local))) {
+			      sizeof(hc->sin_local))) {
 		printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",
-			__func__, hc->localport);
+		       __func__, hc->localport);
 		ret = -EINVAL;
 		goto fail;
 	}
@@ -728,7 +728,7 @@ l1oip_socket_thread(void *data)
 	/* read loop */
 	if (debug & DEBUG_L1OIP_SOCKET)
 		printk(KERN_DEBUG "%s: socket created and open\n",
-			__func__);
+		       __func__);
 	while (!signal_pending(current)) {
 		struct kvec iov = {
 			.iov_base = recvbuf,
@@ -741,7 +741,7 @@ l1oip_socket_thread(void *data)
 		} else {
 			if (debug & DEBUG_L1OIP_SOCKET)
 				printk(KERN_WARNING
-				    "%s: broken pipe on socket\n", __func__);
+				       "%s: broken pipe on socket\n", __func__);
 		}
 	}
 
@@ -750,7 +750,7 @@ l1oip_socket_thread(void *data)
 	/* if hc->socket is NULL, it is in use until it is given back */
 	while (!hc->socket) {
 		spin_unlock(&hc->socket_lock);
-		schedule_timeout(HZ/10);
+		schedule_timeout(HZ / 10);
 		spin_lock(&hc->socket_lock);
 	}
 	hc->socket = NULL;
@@ -758,7 +758,7 @@ l1oip_socket_thread(void *data)
 
 	if (debug & DEBUG_L1OIP_SOCKET)
 		printk(KERN_DEBUG "%s: socket thread terminating\n",
-			__func__);
+		       __func__);
 
 fail:
 	/* free recvbuf */
@@ -774,7 +774,7 @@ fail:
 
 	if (debug & DEBUG_L1OIP_SOCKET)
 		printk(KERN_DEBUG "%s: socket thread terminated\n",
-			__func__);
+		       __func__);
 	return ret;
 }
 
@@ -787,19 +787,19 @@ l1oip_socket_close(struct l1oip *hc)
 	if (hc->socket_thread) {
 		if (debug & DEBUG_L1OIP_SOCKET)
 			printk(KERN_DEBUG "%s: socket thread exists, "
-				"killing...\n", __func__);
+			       "killing...\n", __func__);
 		send_sig(SIGTERM, hc->socket_thread, 0);
 		wait_for_completion(&hc->socket_complete);
 	}
 
 	/* if active, we send up a PH_DEACTIVATE and deactivate */
 	if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: interface become deactivated "
-				"due to timeout\n", __func__);
+			       "due to timeout\n", __func__);
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_ATOMIC);
+			    NULL, GFP_ATOMIC);
 	}
 }
 
@@ -813,11 +813,11 @@ l1oip_socket_open(struct l1oip *hc)
 
 	/* create receive process */
 	hc->socket_thread = kthread_run(l1oip_socket_thread, hc, "l1oip_%s",
-		hc->name);
+					hc->name);
 	if (IS_ERR(hc->socket_thread)) {
 		int err = PTR_ERR(hc->socket_thread);
 		printk(KERN_ERR "%s: Failed (%d) to create socket process.\n",
-			__func__, err);
+		       __func__, err);
 		hc->socket_thread = NULL;
 		sock_release(hc->socket);
 		return err;
@@ -834,9 +834,9 @@ l1oip_send_bh(struct work_struct *work)
 {
 	struct l1oip *hc = container_of(work, struct l1oip, workq);
 
-	if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+	if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 		printk(KERN_DEBUG "%s: keepalive timer expired, sending empty "
-			"frame on dchannel\n", __func__);
+		       "frame on dchannel\n", __func__);
 
 	/* send an empty l1oip frame at D-channel */
 	l1oip_socket_send(hc, 0, hc->d_idx, 0, 0, NULL, 0);
@@ -862,25 +862,25 @@ l1oip_timeout(void *data)
 
 	if (debug & DEBUG_L1OIP_MSG)
 		printk(KERN_DEBUG "%s: timeout timer expired, turn layer one "
-			"down.\n", __func__);
+		       "down.\n", __func__);
 
 	hc->timeout_on = 0; /* state that timer must be initialized next time */
 
 	/* if timeout, we send up a PH_DEACTIVATE and deactivate */
 	if (test_bit(FLG_ACTIVE, &dch->Flags)) {
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: interface become deactivated "
-				"due to timeout\n", __func__);
+			       "due to timeout\n", __func__);
 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
 		_queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
-			NULL, GFP_ATOMIC);
+			    NULL, GFP_ATOMIC);
 	}
 
 	/* if we have ondemand set, we remove ip address */
 	if (hc->ondemand) {
 		if (debug & DEBUG_L1OIP_MSG)
 			printk(KERN_DEBUG "%s: on demand causes ip address to "
-				"be removed\n", __func__);
+			       "be removed\n", __func__);
 		hc->sin_remote.sin_addr.s_addr = 0;
 	}
 }
@@ -904,12 +904,12 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 	case PH_DATA_REQ:
 		if (skb->len < 1) {
 			printk(KERN_WARNING "%s: skb too small\n",
-				__func__);
+			       __func__);
 			break;
 		}
 		if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
 			printk(KERN_WARNING "%s: skb too large\n",
-				__func__);
+			       __func__);
 			break;
 		}
 		/* send frame */
@@ -918,7 +918,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 		while (l) {
 			ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
 			l1oip_socket_send(hc, 0, dch->slot, 0,
-				hc->chan[dch->slot].tx_counter++, p, ll);
+					  hc->chan[dch->slot].tx_counter++, p, ll);
 			p += ll;
 			l -= ll;
 		}
@@ -926,9 +926,9 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 		queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
 		return 0;
 	case PH_ACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
-				, __func__, dch->slot, hc->b_num+1);
+			       , __func__, dch->slot, hc->b_num + 1);
 		skb_trim(skb, 0);
 		if (test_bit(FLG_ACTIVE, &dch->Flags))
 			queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
@@ -936,10 +936,10 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 			queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
 		return 0;
 	case PH_DEACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
-				"(1..%d)\n", __func__, dch->slot,
-				hc->b_num+1);
+			       "(1..%d)\n", __func__, dch->slot,
+			       hc->b_num + 1);
 		skb_trim(skb, 0);
 		if (test_bit(FLG_ACTIVE, &dch->Flags))
 			queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
@@ -971,26 +971,26 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
 			hc->remoteport = hc->localport;
 		if (debug & DEBUG_L1OIP_SOCKET)
 			printk(KERN_DEBUG "%s: got new ip address from user "
-				"space.\n", __func__);
+			       "space.\n", __func__);
 		l1oip_socket_open(hc);
 		break;
 	case MISDN_CTRL_UNSETPEER:
 		if (debug & DEBUG_L1OIP_SOCKET)
 			printk(KERN_DEBUG "%s: removing ip address.\n",
-				__func__);
+			       __func__);
 		hc->remoteip = 0;
 		l1oip_socket_open(hc);
 		break;
 	case MISDN_CTRL_GETPEER:
 		if (debug & DEBUG_L1OIP_SOCKET)
 			printk(KERN_DEBUG "%s: getting ip address.\n",
-				__func__);
+			       __func__);
 		cq->p1 = hc->remoteip;
 		cq->p2 = hc->remoteport | (hc->localport << 16);
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n",
-		    __func__, cq->op);
+		       __func__, cq->op);
 		ret = -EINVAL;
 		break;
 	}
@@ -1002,21 +1002,21 @@ open_dchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
 {
 	if (debug & DEBUG_HW_OPEN)
 		printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
-		    dch->dev.id, __builtin_return_address(0));
+		       dch->dev.id, __builtin_return_address(0));
 	if (rq->protocol == ISDN_P_NONE)
 		return -EINVAL;
 	if ((dch->dev.D.protocol != ISDN_P_NONE) &&
 	    (dch->dev.D.protocol != rq->protocol)) {
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_WARNING "%s: change protocol %x to %x\n",
-			__func__, dch->dev.D.protocol, rq->protocol);
+			       __func__, dch->dev.D.protocol, rq->protocol);
 	}
 	if (dch->dev.D.protocol != rq->protocol)
 		dch->dev.D.protocol = rq->protocol;
 
 	if (test_bit(FLG_ACTIVE, &dch->Flags)) {
 		_queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
-		    0, NULL, GFP_KERNEL);
+			    0, NULL, GFP_KERNEL);
 	}
 	rq->ch = &dch->dev.D;
 	if (!try_module_get(THIS_MODULE))
@@ -1038,7 +1038,7 @@ open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
 	bch = hc->chan[ch].bch;
 	if (!bch) {
 		printk(KERN_ERR "%s:internal error ch %d has no bch\n",
-		    __func__, ch);
+		       __func__, ch);
 		return -EINVAL;
 	}
 	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
@@ -1061,7 +1061,7 @@ l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 	if (dch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		    __func__, cmd, arg);
+		       __func__, cmd, arg);
 	switch (cmd) {
 	case OPEN_CHANNEL:
 		rq = arg;
@@ -1089,8 +1089,8 @@ l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	case CLOSE_CHANNEL:
 		if (debug & DEBUG_HW_OPEN)
 			printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
-			    __func__, dch->dev.id,
-			    __builtin_return_address(0));
+			       __func__, dch->dev.id,
+			       __builtin_return_address(0));
 		module_put(THIS_MODULE);
 		break;
 	case CONTROL_CHANNEL:
@@ -1099,7 +1099,7 @@ l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 	default:
 		if (dch->debug & DEBUG_HW)
 			printk(KERN_DEBUG "%s: unknown command %x\n",
-			    __func__, cmd);
+			       __func__, cmd);
 		err = -EINVAL;
 	}
 	return err;
@@ -1112,48 +1112,38 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 	struct l1oip			*hc = bch->hw;
 	int			ret = -EINVAL;
 	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
-	int			l, ll, i;
+	int			l, ll;
 	unsigned char		*p;
 
 	switch (hh->prim) {
 	case PH_DATA_REQ:
 		if (skb->len <= 0) {
 			printk(KERN_WARNING "%s: skb too small\n",
-				__func__);
+			       __func__);
 			break;
 		}
 		if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
 			printk(KERN_WARNING "%s: skb too large\n",
-				__func__);
+			       __func__);
 			break;
 		}
 		/* check for AIS / ulaw-silence */
-		p = skb->data;
 		l = skb->len;
-		for (i = 0; i < l; i++) {
-			if (*p++ != 0xff)
-				break;
-		}
-		if (i == l) {
+		if (!memchr_inv(skb->data, 0xff, l)) {
 			if (debug & DEBUG_L1OIP_MSG)
 				printk(KERN_DEBUG "%s: got AIS, not sending, "
-					"but counting\n", __func__);
+				       "but counting\n", __func__);
 			hc->chan[bch->slot].tx_counter += l;
 			skb_trim(skb, 0);
 			queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
 			return 0;
 		}
 		/* check for silence */
-		p = skb->data;
 		l = skb->len;
-		for (i = 0; i < l; i++) {
-			if (*p++ != 0x2a)
-				break;
-		}
-		if (i == l) {
+		if (!memchr_inv(skb->data, 0x2a, l)) {
 			if (debug & DEBUG_L1OIP_MSG)
 				printk(KERN_DEBUG "%s: got silence, not sending"
-					", but counting\n", __func__);
+				       ", but counting\n", __func__);
 			hc->chan[bch->slot].tx_counter += l;
 			skb_trim(skb, 0);
 			queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
@@ -1166,7 +1156,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 		while (l) {
 			ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
 			l1oip_socket_send(hc, hc->codec, bch->slot, 0,
-				hc->chan[bch->slot].tx_counter, p, ll);
+					  hc->chan[bch->slot].tx_counter, p, ll);
 			hc->chan[bch->slot].tx_counter += ll;
 			p += ll;
 			l -= ll;
@@ -1175,19 +1165,19 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
 		queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
 		return 0;
 	case PH_ACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
-				, __func__, bch->slot, hc->b_num+1);
+			       , __func__, bch->slot, hc->b_num + 1);
 		hc->chan[bch->slot].codecstate = 0;
 		test_and_set_bit(FLG_ACTIVE, &bch->Flags);
 		skb_trim(skb, 0);
 		queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
 		return 0;
 	case PH_DEACTIVATE_REQ:
-		if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
+		if (debug & (DEBUG_L1OIP_MSG | DEBUG_L1OIP_SOCKET))
 			printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
-				"(1..%d)\n", __func__, bch->slot,
-				hc->b_num+1);
+			       "(1..%d)\n", __func__, bch->slot,
+			       hc->b_num + 1);
 		test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
 		skb_trim(skb, 0);
 		queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
@@ -1212,14 +1202,14 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
 	case MISDN_CTRL_HW_FEATURES: /* fill features structure */
 		if (debug & DEBUG_L1OIP_MSG)
 			printk(KERN_DEBUG "%s: HW_FEATURE request\n",
-			    __func__);
+			       __func__);
 		/* create confirm */
 		features->unclocked = 1;
 		features->unordered = 1;
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown Op %x\n",
-		    __func__, cq->op);
+		       __func__, cq->op);
 		ret = -EINVAL;
 		break;
 	}
@@ -1234,7 +1224,7 @@ l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 	if (bch->debug & DEBUG_HW)
 		printk(KERN_DEBUG "%s: cmd:%x %p\n",
-		    __func__, cmd, arg);
+		       __func__, cmd, arg);
 	switch (cmd) {
 	case CLOSE_CHANNEL:
 		test_and_clear_bit(FLG_OPEN, &bch->Flags);
@@ -1249,7 +1239,7 @@ l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 		break;
 	default:
 		printk(KERN_WARNING "%s: unknown prim(%x)\n",
-			__func__, cmd);
+		       __func__, cmd);
 	}
 	return err;
 }
@@ -1340,18 +1330,18 @@ init_card(struct l1oip *hc, int pri, int bundle)
 		break;
 	default:
 		printk(KERN_ERR "Codec(%d) not supported.\n",
-			codec[l1oip_cnt]);
+		       codec[l1oip_cnt]);
 		return -EINVAL;
 	}
 	hc->codec = codec[l1oip_cnt];
 	if (debug & DEBUG_L1OIP_INIT)
 		printk(KERN_DEBUG "%s: using codec %d\n",
-			__func__, hc->codec);
+		       __func__, hc->codec);
 
 	if (id[l1oip_cnt] == 0) {
 		printk(KERN_WARNING "Warning: No 'id' value given or "
-			"0, this is highly unsecure. Please use 32 "
-			"bit randmom number 0x...\n");
+		       "0, this is highly unsecure. Please use 32 "
+		       "bit randmom number 0x...\n");
 	}
 	hc->id = id[l1oip_cnt];
 	if (debug & DEBUG_L1OIP_INIT)
@@ -1360,7 +1350,7 @@ init_card(struct l1oip *hc, int pri, int bundle)
 	hc->ondemand = ondemand[l1oip_cnt];
 	if (hc->ondemand && !hc->id) {
 		printk(KERN_ERR "%s: ondemand option only allowed in "
-			"conjunction with non 0 ID\n", __func__);
+		       "conjunction with non 0 ID\n", __func__);
 		return -EINVAL;
 	}
 
@@ -1368,37 +1358,37 @@ init_card(struct l1oip *hc, int pri, int bundle)
 		hc->b_num = limit[l1oip_cnt];
 	if (!pri && hc->b_num > 2) {
 		printk(KERN_ERR "Maximum limit for BRI interface is 2 "
-			"channels.\n");
+		       "channels.\n");
 		return -EINVAL;
 	}
 	if (pri && hc->b_num > 126) {
 		printk(KERN_ERR "Maximum limit for PRI interface is 126 "
-			"channels.\n");
+		       "channels.\n");
 		return -EINVAL;
 	}
 	if (pri && hc->b_num > 30) {
 		printk(KERN_WARNING "Maximum limit for BRI interface is 30 "
-			"channels.\n");
+		       "channels.\n");
 		printk(KERN_WARNING "Your selection of %d channels must be "
-			"supported by application.\n", hc->limit);
+		       "supported by application.\n", hc->limit);
 	}
 
-	hc->remoteip = ip[l1oip_cnt<<2] << 24
-		     | ip[(l1oip_cnt<<2)+1] << 16
-		     | ip[(l1oip_cnt<<2)+2] << 8
-		     | ip[(l1oip_cnt<<2)+3];
-	hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT+l1oip_cnt);
+	hc->remoteip = ip[l1oip_cnt << 2] << 24
+		| ip[(l1oip_cnt << 2) + 1] << 16
+		| ip[(l1oip_cnt << 2) + 2] << 8
+		| ip[(l1oip_cnt << 2) + 3];
+	hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT + l1oip_cnt);
 	if (remoteport[l1oip_cnt])
 		hc->remoteport = remoteport[l1oip_cnt];
 	else
 		hc->remoteport = hc->localport;
 	if (debug & DEBUG_L1OIP_INIT)
 		printk(KERN_DEBUG "%s: using local port %d remote ip "
-			"%d.%d.%d.%d port %d ondemand %d\n", __func__,
-			hc->localport, hc->remoteip >> 24,
-			(hc->remoteip >> 16) & 0xff,
-			(hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff,
-			hc->remoteport, hc->ondemand);
+		       "%d.%d.%d.%d port %d ondemand %d\n", __func__,
+		       hc->localport, hc->remoteip >> 24,
+		       (hc->remoteip >> 16) & 0xff,
+		       (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff,
+		       hc->remoteport, hc->ondemand);
 
 	dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
 	if (!dch)
@@ -1411,7 +1401,7 @@ init_card(struct l1oip *hc, int pri, int bundle)
 	else
 		dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
 	dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
-	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	dch->dev.D.send = handle_dmsg;
 	dch->dev.D.ctrl = l1oip_dctrl;
 	dch->dev.nrbchan = hc->b_num;
@@ -1424,7 +1414,7 @@ init_card(struct l1oip *hc, int pri, int bundle)
 		bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
 		if (!bch) {
 			printk(KERN_ERR "%s: no memory for bchannel\n",
-			    __func__);
+			       __func__);
 			return -ENOMEM;
 		}
 		bch->nr = i + ch;
@@ -1447,7 +1437,7 @@ init_card(struct l1oip *hc, int pri, int bundle)
 
 	if (debug & DEBUG_L1OIP_INIT)
 		printk(KERN_DEBUG "%s: Setting up network card(%d)\n",
-			__func__, l1oip_cnt + 1);
+		       __func__, l1oip_cnt + 1);
 	ret = l1oip_socket_open(hc);
 	if (ret)
 		return ret;
@@ -1455,7 +1445,7 @@ init_card(struct l1oip *hc, int pri, int bundle)
 	hc->keep_tl.function = (void *)l1oip_keepalive;
 	hc->keep_tl.data = (ulong)hc;
 	init_timer(&hc->keep_tl);
-	hc->keep_tl.expires = jiffies + 2*HZ; /* two seconds first time */
+	hc->keep_tl.expires = jiffies + 2 * HZ; /* two seconds first time */
 	add_timer(&hc->keep_tl);
 
 	hc->timeout_tl.function = (void *)l1oip_timeout;
@@ -1474,7 +1464,7 @@ l1oip_init(void)
 	int		ret;
 
 	printk(KERN_INFO "mISDN: Layer-1-over-IP driver Rev. %s\n",
-		l1oip_revision);
+	       l1oip_revision);
 
 	INIT_LIST_HEAD(&l1oip_ilist);
 	spin_lock_init(&l1oip_lock);
@@ -1503,16 +1493,16 @@ l1oip_init(void)
 			break;
 		default:
 			printk(KERN_ERR "Card type(%d) not supported.\n",
-				type[l1oip_cnt] & 0xff);
+			       type[l1oip_cnt] & 0xff);
 			l1oip_cleanup();
 			return -EINVAL;
 		}
 
 		if (debug & DEBUG_L1OIP_INIT)
 			printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
-			    __func__, l1oip_cnt, pri ? "PRI" : "BRI",
-			    bundle ? "bundled IP packet for all B-channels" :
-			    "separate IP packets for every B-channel");
+			       __func__, l1oip_cnt, pri ? "PRI" : "BRI",
+			       bundle ? "bundled IP packet for all B-channels" :
+			       "separate IP packets for every B-channel");
 
 		hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
 		if (!hc) {
@@ -1540,4 +1530,3 @@ l1oip_init(void)
 
 module_init(l1oip_init);
 module_exit(l1oip_cleanup);
-
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index 5cc7c00..0fc49b3 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -26,12 +26,12 @@
 static u_int *debug;
 
 struct layer1 {
-	u_long			Flags;
-	struct FsmInst		l1m;
-	struct FsmTimer 	timer;
-	int			delay;
-	struct dchannel		*dch;
-	dchannel_l1callback	*dcb;
+	u_long Flags;
+	struct FsmInst l1m;
+	struct FsmTimer timer;
+	int delay;
+	struct dchannel *dch;
+	dchannel_l1callback *dcb;
 };
 
 #define TIMER3_VALUE 7000
@@ -49,7 +49,7 @@ enum {
 	ST_L1_F8,
 };
 
-#define L1S_STATE_COUNT (ST_L1_F8+1)
+#define L1S_STATE_COUNT (ST_L1_F8 + 1)
 
 static char *strL1SState[] =
 {
@@ -358,7 +358,7 @@ l1_event(struct layer1 *l1, u_int event)
 	default:
 		if (*debug & DEBUG_L1)
 			printk(KERN_DEBUG "%s %x unhandled\n",
-			    __func__, event);
+			       __func__, event);
 		err = -EINVAL;
 	}
 	return err;
diff --git a/drivers/isdn/mISDN/layer1.h b/drivers/isdn/mISDN/layer1.h
index 9c8125f..d1d332c 100644
--- a/drivers/isdn/mISDN/layer1.h
+++ b/drivers/isdn/mISDN/layer1.h
@@ -23,4 +23,3 @@
 #define FLG_L1_PULL_REQ		6
 #define FLG_L1_UINT		7
 #define FLG_L1_DBLOCKED		8
-
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index 5bc0015..39d7375 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -63,7 +63,7 @@ enum {
 	EV_L2_FRAME_ERROR,
 };
 
-#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR+1)
+#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1)
 
 static char *strL2Event[] =
 {
@@ -281,9 +281,9 @@ l2mgr(struct layer2 *l2, u_int prim, void *arg) {
 	long c = (long)arg;
 
 	printk(KERN_WARNING
-	    "l2mgr: addr:%x prim %x %c\n", l2->id, prim, (char)c);
+	       "l2mgr: addr:%x prim %x %c\n", l2->id, prim, (char)c);
 	if (test_bit(FLG_LAPD, &l2->flag) &&
-		!test_bit(FLG_FIXED_TEI, &l2->flag)) {
+	    !test_bit(FLG_FIXED_TEI, &l2->flag)) {
 		switch (c) {
 		case 'C':
 		case 'D':
@@ -340,7 +340,7 @@ ReleaseWin(struct layer2 *l2)
 
 	if (cnt)
 		printk(KERN_WARNING
-		    "isdnl2 freed %d skbuffs in release\n", cnt);
+		       "isdnl2 freed %d skbuffs in release\n", cnt);
 }
 
 inline unsigned int
@@ -471,7 +471,7 @@ inline int
 IsRNR(u_char *data, struct layer2 *l2)
 {
 	return test_bit(FLG_MOD128, &l2->flag) ?
-	    data[0] == RNR : (data[0] & 0xf) == RNR;
+		data[0] == RNR : (data[0] & 0xf) == RNR;
 }
 
 static int
@@ -543,15 +543,15 @@ FRMR_error(struct layer2 *l2, struct sk_buff *skb)
 			return 'N';
 		else if (*debug & DEBUG_L2)
 			l2m_debug(&l2->l2m,
-			    "FRMR information %2x %2x %2x %2x %2x",
-			    datap[0], datap[1], datap[2], datap[3], datap[4]);
+				  "FRMR information %2x %2x %2x %2x %2x",
+				  datap[0], datap[1], datap[2], datap[3], datap[4]);
 	} else {
 		if (skb->len < headers + 3)
 			return 'N';
 		else if (*debug & DEBUG_L2)
 			l2m_debug(&l2->l2m,
-			    "FRMR information %2x %2x %2x",
-			    datap[0], datap[1], datap[2]);
+				  "FRMR information %2x %2x %2x",
+				  datap[0], datap[1], datap[2]);
 	}
 	return 0;
 }
@@ -604,7 +604,7 @@ send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
 		skb = mI_alloc_skb(i, GFP_ATOMIC);
 		if (!skb) {
 			printk(KERN_WARNING "%s: can't alloc skbuff\n",
-				__func__);
+			       __func__);
 			return;
 		}
 	}
@@ -1051,7 +1051,7 @@ l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
 			skb_queue_purge(&l2->i_queue);
 		if (test_bit(FLG_LAPB, &l2->flag))
 			l2down_create(l2, PH_DEACTIVATE_REQ,
-				l2_newid(l2), 0, NULL);
+				      l2_newid(l2), 0, NULL);
 		st5_dl_release_l2l3(l2);
 		mISDN_FsmChangeState(fi, ST_L2_4);
 		if (l2->tm)
@@ -1090,7 +1090,7 @@ enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
 	skb = mI_alloc_skb(i, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_WARNING
-		    "isdnl2 can't alloc sbbuff for enquiry_cr\n");
+		       "isdnl2 can't alloc sbbuff for enquiry_cr\n");
 		return;
 	}
 	memcpy(skb_put(skb, i), tmp, i);
@@ -1149,8 +1149,8 @@ invoke_retransmission(struct layer2 *l2, unsigned int nr)
 				skb_queue_head(&l2->i_queue, l2->windowar[p1]);
 			else
 				printk(KERN_WARNING
-				    "%s: windowar[%d] is NULL\n",
-				    __func__, p1);
+				       "%s: windowar[%d] is NULL\n",
+				       __func__, p1);
 			l2->windowar[p1] = NULL;
 		}
 		mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
@@ -1199,13 +1199,13 @@ l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
 			invoke_retransmission(l2, nr);
 			stop_t200(l2, 10);
 			if (mISDN_FsmAddTimer(&l2->t203, l2->T203,
-					EV_L2_T203, NULL, 6))
+					      EV_L2_T203, NULL, 6))
 				l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");
 		} else if ((nr == l2->vs) && (typ == RR)) {
 			setva(l2, nr);
 			stop_t200(l2, 11);
 			mISDN_FsmRestartTimer(&l2->t203, l2->T203,
-					EV_L2_T203, NULL, 7);
+					      EV_L2_T203, NULL, 7);
 		} else if ((l2->va != nr) || (typ == RNR)) {
 			setva(l2, nr);
 			if (typ != RR)
@@ -1303,7 +1303,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
 			if (nr == l2->vs) {
 				stop_t200(l2, 13);
 				mISDN_FsmRestartTimer(&l2->t203, l2->T203,
-						EV_L2_T203, NULL, 7);
+						      EV_L2_T203, NULL, 7);
 			} else if (nr != l2->va)
 				restart_t200(l2, 14);
 		}
@@ -1343,7 +1343,7 @@ l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct layer2 *l2 = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &l2->flag) &&
-		test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
 		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
 	} else if (l2->rc == l2->N200) {
 		mISDN_FsmChangeState(fi, ST_L2_4);
@@ -1352,7 +1352,7 @@ l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
 		l2mgr(l2, MDL_ERROR_IND, (void *) 'G');
 		if (test_bit(FLG_LAPB, &l2->flag))
 			l2down_create(l2, PH_DEACTIVATE_REQ,
-				l2_newid(l2), 0, NULL);
+				      l2_newid(l2), 0, NULL);
 		st5_dl_release_l2l3(l2);
 		if (l2->tm)
 			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
@@ -1360,7 +1360,7 @@ l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
 		l2->rc++;
 		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
 		send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?
-			SABME : SABM) | 0x10, CMD);
+				       SABME : SABM) | 0x10, CMD);
 	}
 }
 
@@ -1370,7 +1370,7 @@ l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct layer2 *l2 = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &l2->flag) &&
-		test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
 		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
 	} else if (l2->rc == l2->N200) {
 		mISDN_FsmChangeState(fi, ST_L2_4);
@@ -1382,7 +1382,7 @@ l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
 	} else {
 		l2->rc++;
 		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,
-			    NULL, 9);
+				  NULL, 9);
 		send_uframe(l2, NULL, DISC | 0x10, CMD);
 	}
 }
@@ -1393,7 +1393,7 @@ l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct layer2 *l2 = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &l2->flag) &&
-		test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
 		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
 		return;
 	}
@@ -1410,7 +1410,7 @@ l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
 	struct layer2 *l2 = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &l2->flag) &&
-		test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
 		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
 		return;
 	}
@@ -1431,7 +1431,7 @@ l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
 	struct layer2 *l2 = fi->userdata;
 
 	if (test_bit(FLG_LAPD, &l2->flag) &&
-		test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
+	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
 		mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);
 		return;
 	}
@@ -1462,7 +1462,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
 	p1 = (p1 + l2->sow) % l2->window;
 	if (l2->windowar[p1]) {
 		printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n",
-		    p1);
+		       p1);
 		dev_kfree_skb(l2->windowar[p1]);
 	}
 	l2->windowar[p1] = skb;
@@ -1482,7 +1482,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
 		memcpy(skb_push(nskb, i), header, i);
 	else {
 		printk(KERN_WARNING
-		    "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);
+		       "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);
 		oskb = nskb;
 		nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC);
 		if (!nskb) {
@@ -1537,7 +1537,7 @@ l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
 			} else {
 				stop_t200(l2, 16);
 				mISDN_FsmAddTimer(&l2->t203, l2->T203,
-					    EV_L2_T203, NULL, 5);
+						  EV_L2_T203, NULL, 5);
 				setva(l2, nr);
 			}
 			invoke_retransmission(l2, nr);
@@ -1858,7 +1858,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
 		ptei = *datap++;
 		if ((psapi & 1) || !(ptei & 1)) {
 			printk(KERN_WARNING
-			    "l2 D-channel frame wrong EA0/EA1\n");
+			       "l2 D-channel frame wrong EA0/EA1\n");
 			return ret;
 		}
 		psapi >>= 2;
@@ -1867,7 +1867,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
 			/* not our business */
 			if (*debug & DEBUG_L2)
 				printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
-					__func__, psapi, l2->sapi);
+				       __func__, psapi, l2->sapi);
 			dev_kfree_skb(skb);
 			return 0;
 		}
@@ -1875,7 +1875,7 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
 			/* not our business */
 			if (*debug & DEBUG_L2)
 				printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
-					__func__, ptei, l2->tei);
+				       __func__, ptei, l2->tei);
 			dev_kfree_skb(skb);
 			return 0;
 		}
@@ -1927,11 +1927,11 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
 {
 	struct layer2		*l2 = container_of(ch, struct layer2, ch);
 	struct mISDNhead	*hh =  mISDN_HEAD_P(skb);
-	int 			ret = -EINVAL;
+	int			ret = -EINVAL;
 
 	if (*debug & DEBUG_L2_RECV)
 		printk(KERN_DEBUG "%s: prim(%x) id(%x) sapi(%d) tei(%d)\n",
-		    __func__, hh->prim, hh->id, l2->sapi, l2->tei);
+		       __func__, hh->prim, hh->id, l2->sapi, l2->tei);
 	switch (hh->prim) {
 	case PH_DATA_IND:
 		ret = ph_data_indication(l2, hh, skb);
@@ -1944,7 +1944,7 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
 		l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);
 		if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
 			ret = mISDN_FsmEvent(&l2->l2m,
-				EV_L2_DL_ESTABLISH_REQ, skb);
+					     EV_L2_DL_ESTABLISH_REQ, skb);
 		break;
 	case PH_DEACTIVATE_IND:
 		test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);
@@ -1967,30 +1967,30 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
 			test_and_set_bit(FLG_ORIG, &l2->flag);
 		if (test_bit(FLG_L1_ACTIV, &l2->flag)) {
 			if (test_bit(FLG_LAPD, &l2->flag) ||
-				test_bit(FLG_ORIG, &l2->flag))
+			    test_bit(FLG_ORIG, &l2->flag))
 				ret = mISDN_FsmEvent(&l2->l2m,
-					EV_L2_DL_ESTABLISH_REQ, skb);
+						     EV_L2_DL_ESTABLISH_REQ, skb);
 		} else {
 			if (test_bit(FLG_LAPD, &l2->flag) ||
-				test_bit(FLG_ORIG, &l2->flag)) {
+			    test_bit(FLG_ORIG, &l2->flag)) {
 				test_and_set_bit(FLG_ESTAB_PEND,
-					&l2->flag);
+						 &l2->flag);
 			}
 			ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),
-			    skb);
+				     skb);
 		}
 		break;
 	case DL_RELEASE_REQ:
 		if (test_bit(FLG_LAPB, &l2->flag))
 			l2down_create(l2, PH_DEACTIVATE_REQ,
-				l2_newid(l2), 0, NULL);
+				      l2_newid(l2), 0, NULL);
 		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,
-		    skb);
+				     skb);
 		break;
 	default:
 		if (*debug & DEBUG_L2)
 			l2m_debug(&l2->l2m, "l2 unknown pr %04x",
-			    hh->prim);
+				  hh->prim);
 	}
 	if (ret) {
 		dev_kfree_skb(skb);
@@ -2038,7 +2038,7 @@ release_l2(struct layer2 *l2)
 		TEIrelease(l2);
 		if (l2->ch.st)
 			l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,
-			    CLOSE_CHANNEL, NULL);
+					       CLOSE_CHANNEL, NULL);
 	}
 	kfree(l2);
 }
@@ -2058,7 +2058,7 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 			set_channel_address(&l2->ch, l2->sapi, l2->tei);
 			info = DL_INFO_L2_CONNECT;
 			l2up_create(l2, DL_INFORMATION_IND,
-			    sizeof(info), &info);
+				    sizeof(info), &info);
 		}
 		break;
 	case CLOSE_CHANNEL:
@@ -2072,7 +2072,7 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 
 struct layer2 *
 create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
-		int sapi)
+	  int sapi)
 {
 	struct layer2		*l2;
 	struct channel_req	rq;
@@ -2151,7 +2151,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
 		break;
 	default:
 		printk(KERN_ERR "layer2 create failed prt %x\n",
-			protocol);
+		       protocol);
 		kfree(l2);
 		return NULL;
 	}
@@ -2162,8 +2162,8 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
 	InitWin(l2);
 	l2->l2m.fsm = &l2fsm;
 	if (test_bit(FLG_LAPB, &l2->flag) ||
-		test_bit(FLG_PTP, &l2->flag) ||
-		test_bit(FLG_LAPD_NET, &l2->flag))
+	    test_bit(FLG_PTP, &l2->flag) ||
+	    test_bit(FLG_LAPD_NET, &l2->flag))
 		l2->l2m.state = ST_L2_4;
 	else
 		l2->l2m.state = ST_L2_1;
@@ -2219,4 +2219,3 @@ Isdnl2_cleanup(void)
 	TEIFree();
 	mISDN_FsmFree(&l2fsm);
 }
-
diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h
index 9547fb3..fe68d94 100644
--- a/drivers/isdn/mISDN/layer2.h
+++ b/drivers/isdn/mISDN/layer2.h
@@ -87,18 +87,18 @@ enum {
 	ST_L2_8,
 };
 
-#define L2_STATE_COUNT (ST_L2_8+1)
+#define L2_STATE_COUNT (ST_L2_8 + 1)
 
 extern struct layer2	*create_l2(struct mISDNchannel *, u_int,
-				u_long, int, int);
+				   u_long, int, int);
 extern int		tei_l2(struct layer2 *, u_int, u_long arg);
 
 
 /* from tei.c */
-extern int 		l2_tei(struct layer2 *, u_int, u_long arg);
-extern void 		TEIrelease(struct layer2 *);
-extern int 		TEIInit(u_int *);
-extern void 		TEIFree(void);
+extern int		l2_tei(struct layer2 *, u_int, u_long arg);
+extern void		TEIrelease(struct layer2 *);
+extern int		TEIInit(u_int *);
+extern void		TEIFree(void);
 
 #define MAX_L2HEADER_LEN 4
 
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 738ea8d..abe2d69 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -113,7 +113,7 @@ mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
 
 static int
 mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
-    struct msghdr *msg, size_t len, int flags)
+		   struct msghdr *msg, size_t len, int flags)
 {
 	struct sk_buff		*skb;
 	struct sock		*sk = sock->sk;
@@ -123,8 +123,8 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 	if (*debug & DEBUG_SOCKET)
 		printk(KERN_DEBUG "%s: len %d, flags %x ch.nr %d, proto %x\n",
-			__func__, (int)len, flags, _pms(sk)->ch.nr,
-			sk->sk_protocol);
+		       __func__, (int)len, flags, _pms(sk)->ch.nr,
+		       sk->sk_protocol);
 	if (flags & (MSG_OOB))
 		return -EOPNOTSUPP;
 
@@ -153,7 +153,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 	} else {
 		if (msg->msg_namelen)
 			printk(KERN_WARNING "%s: too small namelen %d\n",
-			    __func__, msg->msg_namelen);
+			       __func__, msg->msg_namelen);
 		msg->msg_namelen = 0;
 	}
 
@@ -166,7 +166,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 		return -ENOSPC;
 	}
 	memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb),
-	    MISDN_HEADER_LEN);
+	       MISDN_HEADER_LEN);
 
 	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
@@ -179,7 +179,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 static int
 mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
-    struct msghdr *msg, size_t len)
+		   struct msghdr *msg, size_t len)
 {
 	struct sock		*sk = sock->sk;
 	struct sk_buff		*skb;
@@ -188,13 +188,13 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
 	if (*debug & DEBUG_SOCKET)
 		printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
-		     __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
-		     sk->sk_protocol);
+		       __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
+		       sk->sk_protocol);
 
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
 
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+	if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL | MSG_ERRQUEUE))
 		return -EINVAL;
 
 	if (len < MISDN_HEADER_LEN)
@@ -229,7 +229,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
 	if (*debug & DEBUG_SOCKET)
 		printk(KERN_DEBUG "%s: ID:%x\n",
-		     __func__, mISDN_HEAD_ID(skb));
+		       __func__, mISDN_HEAD_ID(skb));
 
 	err = -ENODEV;
 	if (!_pms(sk)->ch.peer)
@@ -312,16 +312,16 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
 		}
 		if ((sk->sk_protocol & ~ISDN_P_B_MASK) == ISDN_P_B_START) {
 			list_for_each_entry_safe(bchan, next,
-				&_pms(sk)->dev->bchannels, list) {
+						 &_pms(sk)->dev->bchannels, list) {
 				if (bchan->nr == cq.channel) {
 					err = bchan->ctrl(bchan,
-						CONTROL_CHANNEL, &cq);
+							  CONTROL_CHANNEL, &cq);
 					break;
 				}
 			}
 		} else
 			err = _pms(sk)->dev->D.ctrl(&_pms(sk)->dev->D,
-				CONTROL_CHANNEL, &cq);
+						    CONTROL_CHANNEL, &cq);
 		if (err)
 			break;
 		if (copy_to_user(p, &cq, sizeof(cq)))
@@ -338,11 +338,11 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
 			break;
 		}
 		err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
-		    CONTROL_CHANNEL, val);
+						  CONTROL_CHANNEL, val);
 		break;
 	case IMHOLD_L1:
 		if (sk->sk_protocol != ISDN_P_LAPD_NT
-		 && sk->sk_protocol != ISDN_P_LAPD_TE) {
+		    && sk->sk_protocol != ISDN_P_LAPD_TE) {
 			err = -EINVAL;
 			break;
 		}
@@ -352,7 +352,7 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
 			break;
 		}
 		err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
-		    CONTROL_CHANNEL, val);
+						  CONTROL_CHANNEL, val);
 		break;
 	default:
 		err = -EINVAL;
@@ -366,7 +366,7 @@ done:
 static int
 data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	int 			err = 0, id;
+	int			err = 0, id;
 	struct sock		*sk = sock->sk;
 	struct mISDNdevice	*dev;
 	struct mISDNversion	ver;
@@ -399,7 +399,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 			di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
 			di.protocol = dev->D.protocol;
 			memcpy(di.channelmap, dev->channelmap,
-				sizeof(di.channelmap));
+			       sizeof(di.channelmap));
 			di.nrbchan = dev->nrbchan;
 			strcpy(di.name, dev_name(&dev->dev));
 			if (copy_to_user((void __user *)arg, &di, sizeof(di)))
@@ -410,7 +410,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 	default:
 		if (sk->sk_state == MISDN_BOUND)
 			err = data_sock_ioctl_bound(sk, cmd,
-				(void __user *)arg);
+						    (void __user *)arg);
 		else
 			err = -ENOTCONN;
 	}
@@ -418,14 +418,14 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 }
 
 static int data_sock_setsockopt(struct socket *sock, int level, int optname,
-	char __user *optval, unsigned int len)
+				char __user *optval, unsigned int len)
 {
 	struct sock *sk = sock->sk;
 	int err = 0, opt = 0;
 
 	if (*debug & DEBUG_SOCKET)
 		printk(KERN_DEBUG "%s(%p, %d, %x, %p, %d)\n", __func__, sock,
-		    level, optname, optval, len);
+		       level, optname, optval, len);
 
 	lock_sock(sk);
 
@@ -450,7 +450,7 @@ static int data_sock_setsockopt(struct socket *sock, int level, int optname,
 }
 
 static int data_sock_getsockopt(struct socket *sock, int level, int optname,
-	char __user *optval, int __user *optlen)
+				char __user *optval, int __user *optlen)
 {
 	struct sock *sk = sock->sk;
 	int len, opt;
@@ -516,7 +516,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 			if (csk->sk_protocol >= ISDN_P_B_START)
 				continue;
 			if (IS_ISDN_P_TE(csk->sk_protocol)
-					== IS_ISDN_P_TE(sk->sk_protocol))
+			    == IS_ISDN_P_TE(sk->sk_protocol))
 				continue;
 			read_unlock_bh(&data_sockets.lock);
 			err = -EBUSY;
@@ -535,14 +535,14 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 	case ISDN_P_NT_E1:
 		mISDN_sock_unlink(&data_sockets, sk);
 		err = connect_layer1(_pms(sk)->dev, &_pms(sk)->ch,
-		    sk->sk_protocol, maddr);
+				     sk->sk_protocol, maddr);
 		if (err)
 			mISDN_sock_link(&data_sockets, sk);
 		break;
 	case ISDN_P_LAPD_TE:
 	case ISDN_P_LAPD_NT:
 		err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch,
-		    sk->sk_protocol, maddr);
+				      sk->sk_protocol, maddr);
 		break;
 	case ISDN_P_B_RAW:
 	case ISDN_P_B_HDLC:
@@ -551,7 +551,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 	case ISDN_P_B_L2DSP:
 	case ISDN_P_B_L2DSPHDLC:
 		err = connect_Bstack(_pms(sk)->dev, &_pms(sk)->ch,
-		    sk->sk_protocol, maddr);
+				     sk->sk_protocol, maddr);
 		break;
 	default:
 		err = -EPROTONOSUPPORT;
@@ -568,9 +568,9 @@ done:
 
 static int
 data_sock_getname(struct socket *sock, struct sockaddr *addr,
-    int *addr_len, int peer)
+		  int *addr_len, int peer)
 {
-	struct sockaddr_mISDN 	*maddr = (struct sockaddr_mISDN *) addr;
+	struct sockaddr_mISDN	*maddr = (struct sockaddr_mISDN *) addr;
 	struct sock		*sk = sock->sk;
 
 	if (!_pms(sk)->dev)
@@ -651,7 +651,7 @@ base_sock_release(struct socket *sock)
 static int
 base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	int 			err = 0, id;
+	int			err = 0, id;
 	struct mISDNdevice	*dev;
 	struct mISDNversion	ver;
 
@@ -683,7 +683,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 			di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
 			di.protocol = dev->D.protocol;
 			memcpy(di.channelmap, dev->channelmap,
-				sizeof(di.channelmap));
+			       sizeof(di.channelmap));
 			di.nrbchan = dev->nrbchan;
 			strcpy(di.name, dev_name(&dev->dev));
 			if (copy_to_user((void __user *)arg, &di, sizeof(di)))
@@ -692,20 +692,20 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 			err = -ENODEV;
 		break;
 	case IMSETDEVNAME:
-		{
-			struct mISDN_devrename dn;
-			if (copy_from_user(&dn, (void __user *)arg,
-			    sizeof(dn))) {
-				err = -EFAULT;
-				break;
-			}
-			dev = get_mdevice(dn.id);
-			if (dev)
-				err = device_rename(&dev->dev, dn.name);
-			else
-				err = -ENODEV;
+	{
+		struct mISDN_devrename dn;
+		if (copy_from_user(&dn, (void __user *)arg,
+				   sizeof(dn))) {
+			err = -EFAULT;
+			break;
 		}
-		break;
+		dev = get_mdevice(dn.id);
+		if (dev)
+			err = device_rename(&dev->dev, dn.name);
+		else
+			err = -ENODEV;
+	}
+	break;
 	default:
 		err = -EINVAL;
 	}
@@ -790,7 +790,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
 {
 	int err = -EPROTONOSUPPORT;
 
-	switch	(proto) {
+	switch (proto) {
 	case ISDN_P_BASE:
 		err = base_sock_create(net, sock, proto);
 		break;
@@ -838,4 +838,3 @@ misdn_sock_cleanup(void)
 {
 	sock_unregister(PF_ISDN);
 }
-
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index a5b632e6..1a0ae44 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -29,7 +29,7 @@ _queue_message(struct mISDNstack *st, struct sk_buff *skb)
 
 	if (*debug & DEBUG_QUEUE_FUNC)
 		printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
-		    __func__, hh->prim, hh->id, skb);
+		       __func__, hh->prim, hh->id, skb);
 	skb_queue_tail(&st->msgq, skb);
 	if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) {
 		test_and_set_bit(mISDN_STACK_WORK, &st->status);
@@ -109,15 +109,15 @@ send_layer2(struct mISDNstack *st, struct sk_buff *skb)
 				if (ret) {
 					if (*debug & DEBUG_SEND_ERR)
 						printk(KERN_DEBUG
-						    "%s ch%d prim(%x) addr(%x)"
-						    " err %d\n",
-						    __func__, ch->nr,
-						    hh->prim, ch->addr, ret);
+						       "%s ch%d prim(%x) addr(%x)"
+						       " err %d\n",
+						       __func__, ch->nr,
+						       hh->prim, ch->addr, ret);
 					dev_kfree_skb(cskb);
 				}
 			} else {
 				printk(KERN_WARNING "%s ch%d addr %x no mem\n",
-				    __func__, ch->nr, ch->addr);
+				       __func__, ch->nr, ch->addr);
 				goto out;
 			}
 		}
@@ -135,8 +135,8 @@ send_layer2(struct mISDNstack *st, struct sk_buff *skb)
 			skb = NULL;
 		else if (*debug & DEBUG_SEND_ERR)
 			printk(KERN_DEBUG
-			    "%s ch%d mgr prim(%x) addr(%x) err %d\n",
-			    __func__, ch->nr, hh->prim, ch->addr, ret);
+			       "%s ch%d mgr prim(%x) addr(%x) err %d\n",
+			       __func__, ch->nr, hh->prim, ch->addr, ret);
 	}
 out:
 	mutex_unlock(&st->lmutex);
@@ -154,7 +154,7 @@ send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
 	lm = hh->prim & MISDN_LAYERMASK;
 	if (*debug & DEBUG_QUEUE_FUNC)
 		printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
-		    __func__, hh->prim, hh->id, skb);
+		       __func__, hh->prim, hh->id, skb);
 	if (lm == 0x1) {
 		if (!hlist_empty(&st->l1sock.head)) {
 			__net_timestamp(skb);
@@ -172,9 +172,9 @@ send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
 			return ch->send(ch, skb);
 		else
 			printk(KERN_WARNING
-			    "%s: dev(%s) prim(%x) id(%x) no channel\n",
-			    __func__, dev_name(&st->dev->dev), hh->prim,
-			    hh->id);
+			       "%s: dev(%s) prim(%x) id(%x) no channel\n",
+			       __func__, dev_name(&st->dev->dev), hh->prim,
+			       hh->id);
 	} else if (lm == 0x8) {
 		WARN_ON(lm == 0x8);
 		ch = get_channel4id(st, hh->id);
@@ -182,13 +182,13 @@ send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
 			return ch->send(ch, skb);
 		else
 			printk(KERN_WARNING
-			    "%s: dev(%s) prim(%x) id(%x) no channel\n",
-			    __func__, dev_name(&st->dev->dev), hh->prim,
-			    hh->id);
+			       "%s: dev(%s) prim(%x) id(%x) no channel\n",
+			       __func__, dev_name(&st->dev->dev), hh->prim,
+			       hh->id);
 	} else {
 		/* broadcast not handled yet */
 		printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n",
-		    __func__, dev_name(&st->dev->dev), hh->prim);
+		       __func__, dev_name(&st->dev->dev), hh->prim);
 	}
 	return -ESRCH;
 }
@@ -207,7 +207,7 @@ mISDNStackd(void *data)
 	sigfillset(&current->blocked);
 	if (*debug & DEBUG_MSG_THREAD)
 		printk(KERN_DEBUG "mISDNStackd %s started\n",
-		    dev_name(&st->dev->dev));
+		       dev_name(&st->dev->dev));
 
 	if (st->notify != NULL) {
 		complete(st->notify);
@@ -226,13 +226,13 @@ mISDNStackd(void *data)
 			skb = skb_dequeue(&st->msgq);
 			if (!skb) {
 				test_and_clear_bit(mISDN_STACK_WORK,
-					&st->status);
+						   &st->status);
 				/* test if a race happens */
 				skb = skb_dequeue(&st->msgq);
 				if (!skb)
 					continue;
 				test_and_set_bit(mISDN_STACK_WORK,
-				    &st->status);
+						 &st->status);
 			}
 #ifdef MISDN_MSG_STATS
 			st->msg_cnt++;
@@ -241,20 +241,20 @@ mISDNStackd(void *data)
 			if (unlikely(err)) {
 				if (*debug & DEBUG_SEND_ERR)
 					printk(KERN_DEBUG
-					    "%s: %s prim(%x) id(%x) "
-					    "send call(%d)\n",
-					    __func__, dev_name(&st->dev->dev),
-					    mISDN_HEAD_PRIM(skb),
-					    mISDN_HEAD_ID(skb), err);
+					       "%s: %s prim(%x) id(%x) "
+					       "send call(%d)\n",
+					       __func__, dev_name(&st->dev->dev),
+					       mISDN_HEAD_PRIM(skb),
+					       mISDN_HEAD_ID(skb), err);
 				dev_kfree_skb(skb);
 				continue;
 			}
 			if (unlikely(test_bit(mISDN_STACK_STOPPED,
-			    &st->status))) {
+					      &st->status))) {
 				test_and_clear_bit(mISDN_STACK_WORK,
-				    &st->status);
+						   &st->status);
 				test_and_clear_bit(mISDN_STACK_RUNNING,
-				    &st->status);
+						   &st->status);
 				break;
 			}
 		}
@@ -270,7 +270,7 @@ mISDNStackd(void *data)
 			test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
 			if (!skb_queue_empty(&st->msgq))
 				test_and_set_bit(mISDN_STACK_WORK,
-				    &st->status);
+						 &st->status);
 		}
 		if (test_bit(mISDN_STACK_ABORT, &st->status))
 			break;
@@ -283,10 +283,10 @@ mISDNStackd(void *data)
 #endif
 		test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
 		wait_event_interruptible(st->workq, (st->status &
-		    mISDN_STACK_ACTION_MASK));
+						     mISDN_STACK_ACTION_MASK));
 		if (*debug & DEBUG_MSG_THREAD)
 			printk(KERN_DEBUG "%s: %s wake status %08lx\n",
-			    __func__, dev_name(&st->dev->dev), st->status);
+			       __func__, dev_name(&st->dev->dev), st->status);
 		test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
 
 		test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status);
@@ -300,17 +300,17 @@ mISDNStackd(void *data)
 	}
 #ifdef MISDN_MSG_STATS
 	printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d "
-	    "msg %d sleep %d stopped\n",
-	    dev_name(&st->dev->dev), st->msg_cnt, st->sleep_cnt,
-	    st->stopped_cnt);
+	       "msg %d sleep %d stopped\n",
+	       dev_name(&st->dev->dev), st->msg_cnt, st->sleep_cnt,
+	       st->stopped_cnt);
 	printk(KERN_DEBUG
-	    "mISDNStackd daemon for %s utime(%ld) stime(%ld)\n",
-	    dev_name(&st->dev->dev), st->thread->utime, st->thread->stime);
+	       "mISDNStackd daemon for %s utime(%ld) stime(%ld)\n",
+	       dev_name(&st->dev->dev), st->thread->utime, st->thread->stime);
 	printk(KERN_DEBUG
-	    "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
-	    dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
+	       "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
+	       dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
 	printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n",
-	    dev_name(&st->dev->dev));
+	       dev_name(&st->dev->dev));
 #endif
 	test_and_set_bit(mISDN_STACK_KILLED, &st->status);
 	test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
@@ -401,15 +401,15 @@ create_stack(struct mISDNdevice *dev)
 	newst->own.recv = mISDN_queue_message;
 	if (*debug & DEBUG_CORE_FUNC)
 		printk(KERN_DEBUG "%s: st(%s)\n", __func__,
-		    dev_name(&newst->dev->dev));
+		       dev_name(&newst->dev->dev));
 	newst->notify = &done;
 	newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s",
-		dev_name(&newst->dev->dev));
+				    dev_name(&newst->dev->dev));
 	if (IS_ERR(newst->thread)) {
 		err = PTR_ERR(newst->thread);
 		printk(KERN_ERR
-			"mISDN:cannot create kernel thread for %s (%d)\n",
-			dev_name(&newst->dev->dev), err);
+		       "mISDN:cannot create kernel thread for %s (%d)\n",
+		       dev_name(&newst->dev->dev), err);
 		delete_teimanager(dev->teimgr);
 		kfree(newst);
 	} else
@@ -419,7 +419,7 @@ create_stack(struct mISDNdevice *dev)
 
 int
 connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
-		u_int protocol, struct sockaddr_mISDN *adr)
+	       u_int protocol, struct sockaddr_mISDN *adr)
 {
 	struct mISDN_sock	*msk = container_of(ch, struct mISDN_sock, ch);
 	struct channel_req	rq;
@@ -428,8 +428,8 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
 
 	if (*debug &  DEBUG_CORE_FUNC)
 		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-			__func__, dev_name(&dev->dev), protocol, adr->dev,
-			adr->channel, adr->sapi, adr->tei);
+		       __func__, dev_name(&dev->dev), protocol, adr->dev,
+		       adr->channel, adr->sapi, adr->tei);
 	switch (protocol) {
 	case ISDN_P_NT_S0:
 	case ISDN_P_NT_E1:
@@ -442,7 +442,7 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
 		rq.adr.channel = adr->channel;
 		err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
 		printk(KERN_DEBUG "%s: ret %d (dev %d)\n", __func__, err,
-			dev->id);
+		       dev->id);
 		if (err)
 			return err;
 		write_lock_bh(&dev->D.st->l1sock.lock);
@@ -457,7 +457,7 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
 
 int
 connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
-    u_int protocol, struct sockaddr_mISDN *adr)
+	       u_int protocol, struct sockaddr_mISDN *adr)
 {
 	struct channel_req	rq, rq2;
 	int			pmask, err;
@@ -465,9 +465,9 @@ connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
 
 	if (*debug &  DEBUG_CORE_FUNC)
 		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-			__func__, dev_name(&dev->dev), protocol,
-			adr->dev, adr->channel, adr->sapi,
-			adr->tei);
+		       __func__, dev_name(&dev->dev), protocol,
+		       adr->dev, adr->channel, adr->sapi,
+		       adr->tei);
 	ch->st = dev->D.st;
 	pmask = 1 << (protocol & ISDN_P_B_MASK);
 	if (pmask & dev->Bprotocols) {
@@ -514,16 +514,16 @@ connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
 
 int
 create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
-    u_int protocol, struct sockaddr_mISDN *adr)
+		u_int protocol, struct sockaddr_mISDN *adr)
 {
 	struct channel_req	rq;
 	int			err;
 
 	if (*debug &  DEBUG_CORE_FUNC)
 		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-			__func__, dev_name(&dev->dev), protocol,
-			adr->dev, adr->channel, adr->sapi,
-			adr->tei);
+		       __func__, dev_name(&dev->dev), protocol,
+		       adr->dev, adr->channel, adr->sapi,
+		       adr->tei);
 	rq.protocol = ISDN_P_TE_S0;
 	if (dev->Dprotocols & (1 << ISDN_P_TE_E1))
 		rq.protocol = ISDN_P_TE_E1;
@@ -573,7 +573,7 @@ delete_channel(struct mISDNchannel *ch)
 	}
 	if (*debug & DEBUG_CORE_FUNC)
 		printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__,
-		    dev_name(&ch->st->dev->dev), ch->protocol);
+		       dev_name(&ch->st->dev->dev), ch->protocol);
 	if (ch->protocol >= ISDN_P_B_START) {
 		if (ch->peer) {
 			ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL);
@@ -602,7 +602,7 @@ delete_channel(struct mISDNchannel *ch)
 			pch->ctrl(pch, CLOSE_CHANNEL, NULL);
 		} else
 			printk(KERN_WARNING "%s: no l2 channel\n",
-			    __func__);
+			       __func__);
 		break;
 	case ISDN_P_LAPD_NT:
 		pch = ch->st->dev->teimgr;
@@ -610,7 +610,7 @@ delete_channel(struct mISDNchannel *ch)
 			pch->ctrl(pch, CLOSE_CHANNEL, NULL);
 		} else
 			printk(KERN_WARNING "%s: no l2 channel\n",
-			    __func__);
+			       __func__);
 		break;
 	default:
 		break;
@@ -626,14 +626,14 @@ delete_stack(struct mISDNdevice *dev)
 
 	if (*debug & DEBUG_CORE_FUNC)
 		printk(KERN_DEBUG "%s: st(%s)\n", __func__,
-		    dev_name(&st->dev->dev));
+		       dev_name(&st->dev->dev));
 	if (dev->teimgr)
 		delete_teimanager(dev->teimgr);
 	if (st->thread) {
 		if (st->notify) {
 			printk(KERN_WARNING "%s: notifier in use\n",
-			    __func__);
-				complete(st->notify);
+			       __func__);
+			complete(st->notify);
 		}
 		st->notify = &done;
 		test_and_set_bit(mISDN_STACK_ABORT, &st->status);
@@ -643,10 +643,10 @@ delete_stack(struct mISDNdevice *dev)
 	}
 	if (!list_empty(&st->layer2))
 		printk(KERN_WARNING "%s: layer2 list not empty\n",
-		    __func__);
+		       __func__);
 	if (!hlist_empty(&st->l1sock.head))
 		printk(KERN_WARNING "%s: layer1 list not empty\n",
-		    __func__);
+		       __func__);
 	kfree(st);
 }
 
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index 687c9b6..ba2bc0c 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -34,7 +34,7 @@
 
 #define DATIMER_VAL	10000
 
-static 	u_int	*debug;
+static	u_int	*debug;
 
 static struct Fsm deactfsm = {NULL, 0, 0, NULL, NULL};
 static struct Fsm teifsmu = {NULL, 0, 0, NULL, NULL};
@@ -45,7 +45,7 @@ enum {
 	ST_L1_DEACT_PENDING,
 	ST_L1_ACTIV,
 };
-#define DEACT_STATE_COUNT (ST_L1_ACTIV+1)
+#define DEACT_STATE_COUNT (ST_L1_ACTIV + 1)
 
 static char *strDeactState[] =
 {
@@ -63,7 +63,7 @@ enum {
 	EV_DATIMER,
 };
 
-#define DEACT_EVENT_COUNT (EV_DATIMER+1)
+#define DEACT_EVENT_COUNT (EV_DATIMER + 1)
 
 static char *strDeactEvent[] =
 {
@@ -130,7 +130,7 @@ da_deactivate(struct FsmInst *fi, int event, void *arg)
 	/* All TEI are inactiv */
 	if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
 		mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
-			NULL, 1);
+				  NULL, 1);
 		mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
 	}
 }
@@ -144,7 +144,7 @@ da_ui(struct FsmInst *fi, int event, void *arg)
 	if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
 		mISDN_FsmDelTimer(&mgr->datimer, 2);
 		mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
-			NULL, 2);
+				  NULL, 2);
 	}
 }
 
@@ -169,7 +169,7 @@ da_timer(struct FsmInst *fi, int event, void *arg)
 	/* All TEI are inactiv */
 	mISDN_FsmChangeState(fi, ST_L1_DEACT);
 	_queue_data(&mgr->ch, PH_DEACTIVATE_REQ, MISDN_ID_ANY, 0, NULL,
-	    GFP_ATOMIC);
+		    GFP_ATOMIC);
 }
 
 static struct FsmNode DeactFnList[] =
@@ -188,7 +188,7 @@ enum {
 	ST_TEI_IDVERIFY,
 };
 
-#define TEI_STATE_COUNT (ST_TEI_IDVERIFY+1)
+#define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)
 
 static char *strTeiState[] =
 {
@@ -209,7 +209,7 @@ enum {
 	EV_TIMER,
 };
 
-#define TEI_EVENT_COUNT (EV_TIMER+1)
+#define TEI_EVENT_COUNT (EV_TIMER + 1)
 
 static char *strTeiEvent[] =
 {
@@ -257,8 +257,8 @@ get_free_id(struct manager *mgr)
 	list_for_each_entry(l2, &mgr->layer2, list) {
 		if (l2->ch.nr > 63) {
 			printk(KERN_WARNING
-			    "%s: more as 63 layer2 for one device\n",
-			    __func__);
+			       "%s: more as 63 layer2 for one device\n",
+			       __func__);
 			return -EBUSY;
 		}
 		test_and_set_bit(l2->ch.nr, (u_long *)&ids);
@@ -267,7 +267,7 @@ get_free_id(struct manager *mgr)
 		if (!test_bit(i, (u_long *)&ids))
 			return i;
 	printk(KERN_WARNING "%s: more as 63 layer2 for one device\n",
-	    __func__);
+	       __func__);
 	return -EBUSY;
 }
 
@@ -294,7 +294,7 @@ get_free_tei(struct manager *mgr)
 		if (!test_bit(i, (u_long *)&ids))
 			return i + 64;
 	printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n",
-	    __func__);
+	       __func__);
 	return -1;
 }
 
@@ -385,7 +385,7 @@ mgr_send_down(struct manager *mgr, struct sk_buff *skb)
 	skb_queue_tail(&mgr->sendq, skb);
 	if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) {
 		_queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
-		    NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 	} else {
 		do_send(mgr);
 	}
@@ -398,7 +398,7 @@ dl_unit_data(struct manager *mgr, struct sk_buff *skb)
 		return -EINVAL;
 	if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
 		_queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
-		    NULL, GFP_KERNEL);
+			    NULL, GFP_KERNEL);
 	skb_push(skb, 3);
 	skb->data[0] = 0x02; /* SAPI 0 C/R = 1 */
 	skb->data[1] = 0xff; /* TEI 127 */
@@ -468,14 +468,14 @@ tei_id_request(struct FsmInst *fi, int event, void *arg)
 
 	if (tm->l2->tei != GROUP_TEI) {
 		tm->tei_m.printdebug(&tm->tei_m,
-			"assign request for already assigned tei %d",
-			tm->l2->tei);
+				     "assign request for already assigned tei %d",
+				     tm->l2->tei);
 		return;
 	}
 	tm->ri = random_ri();
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(&tm->tei_m,
-			"assign request ri %d", tm->ri);
+				     "assign request ri %d", tm->ri);
 	put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
 	mISDN_FsmChangeState(fi, ST_TEI_IDREQ);
 	mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 1);
@@ -496,12 +496,12 @@ tei_id_assign(struct FsmInst *fi, int event, void *arg)
 	tei = *dp >> 1;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "identity assign ri %d tei %d",
-			ri, tei);
+				     ri, tei);
 	l2 = findtei(tm->mgr, tei);
 	if (l2) {	/* same tei is in use */
 		if (ri != l2->tm->ri) {
 			tm->tei_m.printdebug(fi,
-				"possible duplicate assignment tei %d", tei);
+					     "possible duplicate assignment tei %d", tei);
 			tei_l2(l2, MDL_ERROR_RSP, 0);
 		}
 	} else if (ri == tm->ri) {
@@ -525,12 +525,12 @@ tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
 	tei = *dp >> 1;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d",
-			ri, tei);
+				     ri, tei);
 	l2 = findtei(tm->mgr, tei);
 	if (l2) {	/* same tei is in use */
 		if (ri != l2->tm->ri) {	/* and it wasn't our request */
 			tm->tei_m.printdebug(fi,
-				"possible duplicate assignment tei %d", tei);
+					     "possible duplicate assignment tei %d", tei);
 			mISDN_FsmEvent(&l2->tm->tei_m, EV_VERIFY, NULL);
 		}
 	}
@@ -549,7 +549,7 @@ tei_id_denied(struct FsmInst *fi, int event, void *arg)
 	tei = *dp >> 1;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "identity denied ri %d tei %d",
-			ri, tei);
+				     ri, tei);
 }
 
 static void
@@ -559,11 +559,11 @@ tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
 	u_char *dp = arg;
 	int tei;
 
-	tei = *(dp+3) >> 1;
+	tei = *(dp + 3) >> 1;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "identity check req tei %d", tei);
 	if ((tm->l2->tei != GROUP_TEI) && ((tei == GROUP_TEI) ||
-	    (tei == tm->l2->tei))) {
+					   (tei == tm->l2->tei))) {
 		mISDN_FsmDelTimer(&tm->timer, 4);
 		mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
 		put_tei_msg(tm->mgr, ID_CHK_RES, random_ri(), tm->l2->tei);
@@ -577,7 +577,7 @@ tei_id_remove(struct FsmInst *fi, int event, void *arg)
 	u_char *dp = arg;
 	int tei;
 
-	tei = *(dp+3) >> 1;
+	tei = *(dp + 3) >> 1;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "identity remove tei %d", tei);
 	if ((tm->l2->tei != GROUP_TEI) &&
@@ -595,7 +595,7 @@ tei_id_verify(struct FsmInst *fi, int event, void *arg)
 
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "id verify request for tei %d",
-			tm->l2->tei);
+				     tm->l2->tei);
 	put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
 	mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
 	mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
@@ -611,7 +611,7 @@ tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
 		tm->ri = random_ri();
 		if (*debug & DEBUG_L2_TEI)
 			tm->tei_m.printdebug(fi, "assign req(%d) ri %d",
-				4 - tm->nval, tm->ri);
+					     4 - tm->nval, tm->ri);
 		put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
 		mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 3);
 	} else {
@@ -629,13 +629,13 @@ tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
 	if (--tm->nval) {
 		if (*debug & DEBUG_L2_TEI)
 			tm->tei_m.printdebug(fi,
-				"id verify req(%d) for tei %d",
-				3 - tm->nval, tm->l2->tei);
+					     "id verify req(%d) for tei %d",
+					     3 - tm->nval, tm->l2->tei);
 		put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
 		mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
 	} else {
 		tm->tei_m.printdebug(fi, "verify req for tei %d failed",
-			tm->l2->tei);
+				     tm->l2->tei);
 		tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
 		mISDN_FsmChangeState(fi, ST_TEI_NOP);
 	}
@@ -673,14 +673,14 @@ tei_assign_req(struct FsmInst *fi, int event, void *arg)
 
 	if (tm->l2->tei == GROUP_TEI) {
 		tm->tei_m.printdebug(&tm->tei_m,
-			"net tei assign request without tei");
+				     "net tei assign request without tei");
 		return;
 	}
 	tm->ri = ((unsigned int) *dp++ << 8);
 	tm->ri += *dp++;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(&tm->tei_m,
-			"net assign request ri %d teim %d", tm->ri, *dp);
+				     "net assign request ri %d teim %d", tm->ri, *dp);
 	put_tei_msg(tm->mgr, ID_ASSIGNED, tm->ri, tm->l2->tei);
 	mISDN_FsmChangeState(fi, ST_TEI_NOP);
 }
@@ -692,7 +692,7 @@ tei_id_chk_req_net(struct FsmInst *fi, int event, void *arg)
 
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "id check request for tei %d",
-		    tm->l2->tei);
+				     tm->l2->tei);
 	tm->rcnt = 0;
 	put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
 	mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
@@ -724,7 +724,7 @@ tei_id_verify_net(struct FsmInst *fi, int event, void *arg)
 	tei = dp[3] >> 1;
 	if (*debug & DEBUG_L2_TEI)
 		tm->tei_m.printdebug(fi, "identity verify req tei %d/%d",
-		    tei, tm->l2->tei);
+				     tei, tm->l2->tei);
 	if (tei == tm->l2->tei)
 		tei_id_chk_req_net(fi, event, arg);
 }
@@ -737,7 +737,7 @@ tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
 	if (tm->rcnt == 1) {
 		if (*debug & DEBUG_L2_TEI)
 			tm->tei_m.printdebug(fi,
-			    "check req for tei %d successful\n", tm->l2->tei);
+					     "check req for tei %d successful\n", tm->l2->tei);
 		mISDN_FsmChangeState(fi, ST_TEI_NOP);
 	} else if (tm->rcnt > 1) {
 		/* duplicate assignment; remove */
@@ -745,13 +745,13 @@ tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
 	} else if (--tm->nval) {
 		if (*debug & DEBUG_L2_TEI)
 			tm->tei_m.printdebug(fi,
-				"id check req(%d) for tei %d",
-				3 - tm->nval, tm->l2->tei);
+					     "id check req(%d) for tei %d",
+					     3 - tm->nval, tm->l2->tei);
 		put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
 		mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
 	} else {
 		tm->tei_m.printdebug(fi, "check req for tei %d failed",
-			tm->l2->tei);
+				     tm->l2->tei);
 		mISDN_FsmChangeState(fi, ST_TEI_NOP);
 		tei_l2remove(tm->l2);
 	}
@@ -800,7 +800,7 @@ create_new_tei(struct manager *mgr, int tei, int sapi)
 	if ((tei >= 0) && (tei < 64))
 		test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
 	if (mgr->ch.st->dev->Dprotocols
-	  & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
+	    & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
 		test_and_set_bit(OPTION_L2_PMX, &opt);
 	l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
 	if (!l2) {
@@ -880,7 +880,7 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
 	if (skb->len < 8) {
 		if (*debug  & DEBUG_L2_TEI)
 			printk(KERN_DEBUG "%s: short mgr frame %d/8\n",
-			    __func__, skb->len);
+			       __func__, skb->len);
 		goto done;
 	}
 
@@ -979,15 +979,15 @@ static int
 create_teimgr(struct manager *mgr, struct channel_req *crq)
 {
 	struct layer2	*l2;
-	u_long 		opt = 0;
+	u_long		opt = 0;
 	u_long		flags;
 	int		id;
 
 	if (*debug & DEBUG_L2_TEI)
 		printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-			__func__, dev_name(&mgr->ch.st->dev->dev),
-			crq->protocol, crq->adr.dev, crq->adr.channel,
-			crq->adr.sapi, crq->adr.tei);
+		       __func__, dev_name(&mgr->ch.st->dev->dev),
+		       crq->protocol, crq->adr.dev, crq->adr.channel,
+		       crq->adr.sapi, crq->adr.tei);
 	if (crq->adr.tei > GROUP_TEI)
 		return -EINVAL;
 	if (crq->adr.tei < 64)
@@ -1001,8 +1001,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
 			return -EINVAL;
 		if (mgr->up) {
 			printk(KERN_WARNING
-			    "%s: only one network manager is allowed\n",
-			    __func__);
+			       "%s: only one network manager is allowed\n",
+			       __func__);
 			return -EBUSY;
 		}
 	} else if (test_bit(MGR_OPT_USER, &mgr->options)) {
@@ -1017,7 +1017,7 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
 			test_and_set_bit(MGR_OPT_USER, &mgr->options);
 	}
 	if (mgr->ch.st->dev->Dprotocols
-	  & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
+	    & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
 		test_and_set_bit(OPTION_L2_PMX, &opt);
 	if ((crq->protocol == ISDN_P_LAPD_NT) && (crq->adr.tei == 127)) {
 		mgr->up = crq->ch;
@@ -1035,7 +1035,7 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
 		return 0;
 	}
 	l2 = create_l2(crq->ch, crq->protocol, opt,
-		crq->adr.tei, crq->adr.sapi);
+		       crq->adr.tei, crq->adr.sapi);
 	if (!l2)
 		return -ENOMEM;
 	l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
@@ -1084,7 +1084,7 @@ mgr_send(struct mISDNchannel *ch, struct sk_buff *skb)
 	mgr = container_of(ch, struct manager, ch);
 	if (*debug & DEBUG_L2_RECV)
 		printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
-		    __func__, hh->prim, hh->id);
+		       __func__, hh->prim, hh->id);
 	switch (hh->prim) {
 	case PH_DATA_IND:
 		mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
@@ -1181,7 +1181,7 @@ check_data(struct manager *mgr, struct sk_buff *skb)
 
 	if (*debug & DEBUG_L2_CTRL)
 		printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
-		    __func__, hh->prim, hh->id);
+		       __func__, hh->prim, hh->id);
 	if (test_bit(MGR_OPT_USER, &mgr->options))
 		return -ENOTCONN;
 	if (hh->prim != PH_DATA_IND)
@@ -1201,12 +1201,12 @@ check_data(struct manager *mgr, struct sk_buff *skb)
 	/* We got a SABME for a fixed TEI */
 	if (*debug & DEBUG_L2_CTRL)
 		printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
-		    __func__, sapi, tei);
+		       __func__, sapi, tei);
 	l2 = create_new_tei(mgr, tei, sapi);
 	if (!l2) {
 		if (*debug & DEBUG_L2_CTRL)
 			printk(KERN_DEBUG "%s: failed to create new tei\n",
-			    __func__);
+			       __func__);
 		return -ENOMEM;
 	}
 	ret = l2->ch.send(&l2->ch, skb);
@@ -1285,15 +1285,15 @@ mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb)
 				if (ret) {
 					if (*debug & DEBUG_SEND_ERR)
 						printk(KERN_DEBUG
-						    "%s ch%d prim(%x) addr(%x)"
-						    " err %d\n",
-						    __func__, l2->ch.nr,
-						    hh->prim, l2->ch.addr, ret);
+						       "%s ch%d prim(%x) addr(%x)"
+						       " err %d\n",
+						       __func__, l2->ch.nr,
+						       hh->prim, l2->ch.addr, ret);
 				} else
 					cskb = NULL;
 			} else {
 				printk(KERN_WARNING "%s ch%d addr %x no mem\n",
-				    __func__, ch->nr, ch->addr);
+				       __func__, ch->nr, ch->addr);
 				goto out;
 			}
 		}
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index 859c81e..1094667 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -98,13 +98,13 @@ mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)
 
 	if (*debug & DEBUG_TIMER)
 		printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__,
-			filep, buf, (int)count, off);
+		       filep, buf, (int)count, off);
 
 	if (list_empty(&dev->expired) && (dev->work == 0)) {
 		if (filep->f_flags & O_NONBLOCK)
 			return -EAGAIN;
 		wait_event_interruptible(dev->wait, (dev->work ||
-		    !list_empty(&dev->expired)));
+						     !list_empty(&dev->expired)));
 		if (signal_pending(current))
 			return -ERESTARTSYS;
 	}
@@ -141,7 +141,7 @@ mISDN_poll(struct file *filep, poll_table *wait)
 			mask |= (POLLIN | POLLRDNORM);
 		if (*debug & DEBUG_TIMER)
 			printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__,
-				dev->work, list_empty(&dev->expired));
+			       dev->work, list_empty(&dev->expired));
 	}
 	return mask;
 }
@@ -161,7 +161,7 @@ dev_expire_timer(unsigned long data)
 static int
 misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
 {
-	int 			id;
+	int			id;
 	u_long			flags;
 	struct mISDNtimer	*timer;
 
@@ -224,7 +224,7 @@ mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 
 	if (*debug & DEBUG_TIMER)
 		printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__,
-		    filep, cmd, arg);
+		       filep, cmd, arg);
 	mutex_lock(&mISDN_mutex);
 	switch (cmd) {
 	case IMADDTIMER:
@@ -235,7 +235,7 @@ mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 		id = misdn_add_timer(dev, tout);
 		if (*debug & DEBUG_TIMER)
 			printk(KERN_DEBUG "%s add %d id %d\n", __func__,
-			    tout, id);
+			       tout, id);
 		if (id < 0) {
 			ret = id;
 			break;
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c
index 976143b..efb6d6a 100644
--- a/drivers/isdn/pcbit/callbacks.c
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -2,16 +2,16 @@
  * Callbacks for the FSM
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
 /*
  * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
- * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN 
+ * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN
  * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
  */
 
@@ -39,86 +39,86 @@ ushort last_ref_num = 1;
  *
  */
 
-void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
-	      struct callb_data *cbdata) 
+void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
+	      struct callb_data *cbdata)
 {
 	struct sk_buff *skb;
 	int len;
-        ushort refnum;
+	ushort refnum;
 
 
 #ifdef DEBUG
-        printk(KERN_DEBUG "Called Party Number: %s\n", 
-               cbdata->data.setup.CalledPN);
+	printk(KERN_DEBUG "Called Party Number: %s\n",
+	       cbdata->data.setup.CalledPN);
 #endif
-        /*
-         * hdr - kmalloc in capi_conn_req
-         *     - kfree   when msg has been sent
-         */
+	/*
+	 * hdr - kmalloc in capi_conn_req
+	 *     - kfree   when msg has been sent
+	 */
 
-        if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb, 
+	if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb,
 				 chan->proto)) < 0)
-        {
-                printk("capi_conn_req failed\n");
-                return;
-        }
+	{
+		printk("capi_conn_req failed\n");
+		return;
+	}
 
 
-        refnum = last_ref_num++ & 0x7fffU;
+	refnum = last_ref_num++ & 0x7fffU;
 
-        chan->callref = 0;
-        chan->layer2link = 0;
-        chan->snum = 0;
-        chan->s_refnum = refnum;
+	chan->callref = 0;
+	chan->layer2link = 0;
+	chan->snum = 0;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
 }
 
 /*
  *  rcv CONNECT
  *  will go into ACTIVE state
  *  send CONN_ACTIVE_RESP
- *  send Select protocol request 
+ *  send Select protocol request
  */
 
-void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
-	      struct callb_data *data) 
+void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
+	      struct callb_data *data)
 {
-        isdn_ctrl ictl;
- 	struct sk_buff *skb;
+	isdn_ctrl ictl;
+	struct sk_buff *skb;
 	int len;
-        ushort refnum;
+	ushort refnum;
 
-        if ((len=capi_conn_active_resp(chan, &skb)) < 0)
-        {
-                printk("capi_conn_active_req failed\n");
-                return;
-        }
+	if ((len = capi_conn_active_resp(chan, &skb)) < 0)
+	{
+		printk("capi_conn_active_req failed\n");
+		return;
+	}
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
 
 
-        ictl.command = ISDN_STAT_DCONN;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        dev->dev_if->statcallb(&ictl);
+	ictl.command = ISDN_STAT_DCONN;
+	ictl.driver = dev->id;
+	ictl.arg = chan->id;
+	dev->dev_if->statcallb(&ictl);
 
-        /* ACTIVE D-channel */
+	/* ACTIVE D-channel */
 
-        /* Select protocol  */
+	/* Select protocol  */
 
-        if ((len=capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) { 
-                printk("capi_select_proto_req failed\n");
-                return;
-        }
+	if ((len = capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) {
+		printk("capi_select_proto_req failed\n");
+		return;
+	}
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
 }
 
 
@@ -127,22 +127,22 @@ void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
  * inform user
  */
 
-void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
-	     struct callb_data *cbdata) 
+void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
+	     struct callb_data *cbdata)
 {
-        isdn_ctrl ictl;
-        unsigned short refnum;
- 	struct sk_buff *skb;
+	isdn_ctrl ictl;
+	unsigned short refnum;
+	struct sk_buff *skb;
 	int len;
 
 
-        ictl.command = ISDN_STAT_ICALL;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        
-        /*
-         *  ictl.num >= strlen() + strlen() + 5
-         */
+	ictl.command = ISDN_STAT_ICALL;
+	ictl.driver = dev->id;
+	ictl.arg = chan->id;
+
+	/*
+	 *  ictl.num >= strlen() + strlen() + 5
+	 */
 
 	if (cbdata->data.setup.CallingPN == NULL) {
 		printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
@@ -167,18 +167,18 @@ void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
 	printk(KERN_DEBUG "statstr: %s\n", ictl.num);
 #endif
 
-        dev->dev_if->statcallb(&ictl);
+	dev->dev_if->statcallb(&ictl);
+
 
-        
-        if ((len=capi_conn_resp(chan, &skb)) < 0) {
-                printk(KERN_DEBUG "capi_conn_resp failed\n");
-                return;
+	if ((len = capi_conn_resp(chan, &skb)) < 0) {
+		printk(KERN_DEBUG "capi_conn_resp failed\n");
+		return;
 	}
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
 }
 
 /*
@@ -187,24 +187,24 @@ void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
  * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
  */
 
-void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
+void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
 	     struct callb_data *data)
 {
-        unsigned short refnum;
+	unsigned short refnum;
 	struct sk_buff *skb;
-        int len;
-        
-        if ((len = capi_conn_active_req(chan, &skb)) < 0) {        
-                printk(KERN_DEBUG "capi_conn_active_req failed\n");
-                return;
-        }
+	int len;
+
+	if ((len = capi_conn_active_req(chan, &skb)) < 0) {
+		printk(KERN_DEBUG "capi_conn_active_req failed\n");
+		return;
+	}
 
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
 	printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
-        pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
 }
 
 /*
@@ -213,23 +213,23 @@ void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
  *
  */
 
-void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
 	     struct callb_data *data)
 {
-        unsigned short refnum;
- 	struct sk_buff *skb;
+	unsigned short refnum;
+	struct sk_buff *skb;
 	int len;
-        
-        if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
-        {
-                printk("capi_select_proto_req failed\n");
-                return;
-        }
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
+	{
+		printk("capi_select_proto_req failed\n");
+		return;
+	}
+
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
 
 }
 
@@ -239,52 +239,52 @@ void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
  * send disconnect resp
  * send msg to user
  */
-void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
 	       struct callb_data *data)
 {
- 	struct sk_buff *skb;
+	struct sk_buff *skb;
 	int len;
-        ushort refnum;
-        isdn_ctrl ictl;
-  
-        if ((len = capi_disc_resp(chan, &skb)) < 0) {
-                printk("capi_disc_resp failed\n");
-                return;
-        }
-
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
-
-        pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);    
-
-        ictl.command = ISDN_STAT_BHUP;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        dev->dev_if->statcallb(&ictl);
+	ushort refnum;
+	isdn_ctrl ictl;
+
+	if ((len = capi_disc_resp(chan, &skb)) < 0) {
+		printk("capi_disc_resp failed\n");
+		return;
+	}
+
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
+
+	pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);
+
+	ictl.command = ISDN_STAT_BHUP;
+	ictl.driver = dev->id;
+	ictl.arg = chan->id;
+	dev->dev_if->statcallb(&ictl);
 }
 
-        
+
 /*
  *  User HANGUP on active/call proceeding state
  *  send disc.req
  */
-void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
 	       struct callb_data *data)
 {
- 	struct sk_buff *skb;
+	struct sk_buff *skb;
 	int len;
-        ushort refnum;
+	ushort refnum;
 
-        if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
-        {
-                printk("capi_disc_req failed\n");
-                return;
-        }
+	if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
+	{
+		printk("capi_disc_req failed\n");
+		return;
+	}
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);  
+	pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
 }
 
 /*
@@ -292,18 +292,18 @@ void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
  *  Problem: when the HL driver sends the disc req itself
  *           LL receives BHUP
  */
-void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
 	       struct callb_data *data)
 {
-        isdn_ctrl ictl;
+	isdn_ctrl ictl;
 
-        ictl.command = ISDN_STAT_BHUP;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        dev->dev_if->statcallb(&ictl);
+	ictl.command = ISDN_STAT_BHUP;
+	ictl.driver = dev->id;
+	ictl.arg = chan->id;
+	dev->dev_if->statcallb(&ictl);
 }
 
-void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		struct callb_data *data)
 {
 }
@@ -311,38 +311,35 @@ void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan,
 /*
  * send activate b-chan protocol
  */
-void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
-	       struct callb_data *data) 
+void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
+	       struct callb_data *data)
 {
- 	struct sk_buff *skb;
+	struct sk_buff *skb;
 	int len;
-        ushort refnum;
+	ushort refnum;
 
-        if ((len = capi_activate_transp_req(chan, &skb)) < 0)
-        {
-                printk("capi_conn_activate_transp_req failed\n");
-                return;
-        }
+	if ((len = capi_activate_transp_req(chan, &skb)) < 0)
+	{
+		printk("capi_conn_activate_transp_req failed\n");
+		return;
+	}
 
-        refnum = last_ref_num++ & 0x7fffU;
-        chan->s_refnum = refnum;
+	refnum = last_ref_num++ & 0x7fffU;
+	chan->s_refnum = refnum;
 
-        pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
+	pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
 }
 
 /*
  *  Inform User that the B-channel is available
  */
-void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan, 
-	     struct callb_data *data) 
+void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan,
+	     struct callb_data *data)
 {
-        isdn_ctrl ictl;
+	isdn_ctrl ictl;
 
-        ictl.command = ISDN_STAT_BCONN;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        dev->dev_if->statcallb(&ictl);
+	ictl.command = ISDN_STAT_BCONN;
+	ictl.driver = dev->id;
+	ictl.arg = chan->id;
+	dev->dev_if->statcallb(&ictl);
 }
-
-
-
diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h
index 17aa0f5..a036b4a 100644
--- a/drivers/isdn/pcbit/callbacks.h
+++ b/drivers/isdn/pcbit/callbacks.h
@@ -2,10 +2,10 @@
  * Callbacks prototypes for FSM
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -13,34 +13,32 @@
 #define CALLBACKS_H
 
 
-extern void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		     struct callb_data *data);
 
-extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		     struct callb_data *data);
 
-extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		    struct callb_data *data);
-extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		    struct callb_data *data);
-extern void cb_in_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		    struct callb_data *data);
 
-extern void cb_disc_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		      struct callb_data *data);
-extern void cb_disc_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		      struct callb_data *data);
-extern void cb_disc_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		      struct callb_data *data);
 
-extern void cb_notdone(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		       struct callb_data *data);
 
-extern void cb_selp_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		      struct callb_data *data);
-extern void cb_open(struct pcbit_dev * dev, struct pcbit_chan* chan, 
+extern void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		    struct callb_data *data);
 
 #endif
-
-
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c
index ac5a91c..4e3cbf8 100644
--- a/drivers/isdn/pcbit/capi.c
+++ b/drivers/isdn/pcbit/capi.c
@@ -3,10 +3,10 @@
  * Portugal Telecom CAPI 2.0
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  *
  * Not compatible with the AVM Gmbh. CAPI 2.0
@@ -51,39 +51,39 @@
  *
  */
 
-int capi_conn_req(const char * calledPN, struct sk_buff **skb, int proto)
+int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto)
 {
-        ushort len;
-
-        /*
-         * length
-         *   AppInfoMask - 2
-         *   BC0         - 3
-         *   BC1         - 1
-         *   Chan        - 2
-         *   Keypad      - 1
-         *   CPN         - 1
-         *   CPSA        - 1
-         *   CalledPN    - 2 + strlen
-         *   CalledPSA   - 1
-         *   rest...     - 4
-         *   ----------------
-         *   Total        18 + strlen
-         */
-
-        len = 18 + strlen(calledPN);
+	ushort len;
+
+	/*
+	 * length
+	 *   AppInfoMask - 2
+	 *   BC0         - 3
+	 *   BC1         - 1
+	 *   Chan        - 2
+	 *   Keypad      - 1
+	 *   CPN         - 1
+	 *   CPSA        - 1
+	 *   CalledPN    - 2 + strlen
+	 *   CalledPSA   - 1
+	 *   rest...     - 4
+	 *   ----------------
+	 *   Total        18 + strlen
+	 */
+
+	len = 18 + strlen(calledPN);
 
 	if (proto == ISDN_PROTO_L2_TRANS)
 		len++;
 
 	if ((*skb = dev_alloc_skb(len)) == NULL) {
-    
-	        printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
+
+		printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
 		return -1;
 	}
 
-        /* InfoElmMask */
-        *((ushort*) skb_put(*skb, 2)) = AppInfoMask; 
+	/* InfoElmMask */
+	*((ushort *)skb_put(*skb, 2)) = AppInfoMask;
 
 	if (proto == ISDN_PROTO_L2_TRANS)
 	{
@@ -101,162 +101,162 @@ int capi_conn_req(const char * calledPN, struct sk_buff **skb, int proto)
 		*(skb_put(*skb, 1)) = 0x90;     /* BC0.Octect4		*/
 	}
 
-        /* Bearer Capability - Optional*/
-        *(skb_put(*skb, 1)) = 0;        /* BC1.Length = 0                    */
+	/* Bearer Capability - Optional*/
+	*(skb_put(*skb, 1)) = 0;        /* BC1.Length = 0                    */
 
-        *(skb_put(*skb, 1)) = 1;        /* ChannelID.Length = 1              */
-        *(skb_put(*skb, 1)) = 0x83;     /* Basic Interface - Any Channel     */
+	*(skb_put(*skb, 1)) = 1;        /* ChannelID.Length = 1              */
+	*(skb_put(*skb, 1)) = 0x83;     /* Basic Interface - Any Channel     */
 
-        *(skb_put(*skb, 1)) = 0;        /* Keypad.Length = 0                 */
-                  
+	*(skb_put(*skb, 1)) = 0;        /* Keypad.Length = 0                 */
 
-        *(skb_put(*skb, 1)) = 0;        /* CallingPN.Length = 0              */
-        *(skb_put(*skb, 1)) = 0;        /* CallingPSA.Length = 0             */
 
-        /* Called Party Number */
-        *(skb_put(*skb, 1)) = strlen(calledPN) + 1;
-        *(skb_put(*skb, 1)) = 0x81;
-        memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
+	*(skb_put(*skb, 1)) = 0;        /* CallingPN.Length = 0              */
+	*(skb_put(*skb, 1)) = 0;        /* CallingPSA.Length = 0             */
 
-        /* '#' */
+	/* Called Party Number */
+	*(skb_put(*skb, 1)) = strlen(calledPN) + 1;
+	*(skb_put(*skb, 1)) = 0x81;
+	memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
 
-        *(skb_put(*skb, 1)) = 0;       /* CalledPSA.Length = 0     */
+	/* '#' */
 
-        /* LLC.Length  = 0; */
-        /* HLC0.Length = 0; */
-        /* HLC1.Length = 0; */ 
-        /* UTUS.Length = 0; */
-        memset(skb_put(*skb, 4), 0, 4);
+	*(skb_put(*skb, 1)) = 0;       /* CalledPSA.Length = 0     */
 
-        return len;
+	/* LLC.Length  = 0; */
+	/* HLC0.Length = 0; */
+	/* HLC1.Length = 0; */
+	/* UTUS.Length = 0; */
+	memset(skb_put(*skb, 4), 0, 4);
+
+	return len;
 }
 
-int capi_conn_resp(struct pcbit_chan* chan, struct sk_buff **skb)
+int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb)
 {
-        
+
 	if ((*skb = dev_alloc_skb(5)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
-        *(skb_put(*skb, 1)) = 0x01;  /* ACCEPT_CALL */
-        *(skb_put(*skb, 1)) = 0;
-        *(skb_put(*skb, 1)) = 0;
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
+	*(skb_put(*skb, 1)) = 0x01;  /* ACCEPT_CALL */
+	*(skb_put(*skb, 1)) = 0;
+	*(skb_put(*skb, 1)) = 0;
 
-        return 5;
+	return 5;
 }
 
-int capi_conn_active_req(struct pcbit_chan* chan, struct sk_buff **skb)
+int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb)
 {
-        /*
-         * 8 bytes
-         */
-        
+	/*
+	 * 8 bytes
+	 */
+
 	if ((*skb = dev_alloc_skb(8)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
 
 #ifdef DEBUG
-	printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); 
+	printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
 #endif
 
-        *(skb_put(*skb, 1)) = 0;       /*  BC.Length = 0;          */
-        *(skb_put(*skb, 1)) = 0;       /*  ConnectedPN.Length = 0  */
-        *(skb_put(*skb, 1)) = 0;       /*  PSA.Length              */
-        *(skb_put(*skb, 1)) = 0;       /*  LLC.Length = 0;         */
-        *(skb_put(*skb, 1)) = 0;       /*  HLC.Length = 0;         */
-        *(skb_put(*skb, 1)) = 0;       /*  UTUS.Length = 0;        */
+	*(skb_put(*skb, 1)) = 0;       /*  BC.Length = 0;          */
+	*(skb_put(*skb, 1)) = 0;       /*  ConnectedPN.Length = 0  */
+	*(skb_put(*skb, 1)) = 0;       /*  PSA.Length              */
+	*(skb_put(*skb, 1)) = 0;       /*  LLC.Length = 0;         */
+	*(skb_put(*skb, 1)) = 0;       /*  HLC.Length = 0;         */
+	*(skb_put(*skb, 1)) = 0;       /*  UTUS.Length = 0;        */
 
 	return 8;
 }
 
-int capi_conn_active_resp(struct pcbit_chan* chan, struct sk_buff **skb)
+int capi_conn_active_resp(struct pcbit_chan *chan, struct sk_buff **skb)
 {
-        /*
-         * 2 bytes
-         */
-  
+	/*
+	 * 2 bytes
+	 */
+
 	if ((*skb = dev_alloc_skb(2)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
 
-        return 2;
+	return 2;
 }
 
 
-int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, 
-                          int outgoing)
+int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
+			  int outgoing)
 {
 
-        /*
-         * 18 bytes
-         */
+	/*
+	 * 18 bytes
+	 */
 
 	if ((*skb = dev_alloc_skb(18)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
 
-        /* Layer2 protocol */
+	/* Layer2 protocol */
 
-        switch (chan->proto) {
-        case ISDN_PROTO_L2_X75I: 
-                *(skb_put(*skb, 1)) = 0x05;            /* LAPB */
-                break;
-        case ISDN_PROTO_L2_HDLC:
-                *(skb_put(*skb, 1)) = 0x02;
-                break;
+	switch (chan->proto) {
+	case ISDN_PROTO_L2_X75I:
+		*(skb_put(*skb, 1)) = 0x05;            /* LAPB */
+		break;
+	case ISDN_PROTO_L2_HDLC:
+		*(skb_put(*skb, 1)) = 0x02;
+		break;
 	case ISDN_PROTO_L2_TRANS:
-		/* 
+		/*
 		 *	Voice (a-law)
 		 */
 		*(skb_put(*skb, 1)) = 0x06;
 		break;
-        default:
-#ifdef DEBUG 
-                printk(KERN_DEBUG "Transparent\n");
+	default:
+#ifdef DEBUG
+		printk(KERN_DEBUG "Transparent\n");
 #endif
-                *(skb_put(*skb, 1)) = 0x03;
-                break;
-        }
-
-        *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42);    /* Don't ask */
-        *(skb_put(*skb, 1)) = 0x00;
-  
-        *((ushort *) skb_put(*skb, 2)) = MRU;
-
- 
-        *(skb_put(*skb, 1)) = 0x08;           /* Modulo */
-        *(skb_put(*skb, 1)) = 0x07;           /* Max Window */
-  
-        *(skb_put(*skb, 1)) = 0x01;           /* No Layer3 Protocol */
-
-        /*
-         * 2 - layer3 MTU       [10]
-         *   - Modulo           [12]
-         *   - Window           
-         *   - layer1 proto     [14]
-         *   - bitrate
-         *   - sub-channel      [16]
-         *   - layer1dataformat [17]
-         */
-
-        memset(skb_put(*skb, 8), 0, 8);
-
-        return 18;
+		*(skb_put(*skb, 1)) = 0x03;
+		break;
+	}
+
+	*(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42);    /* Don't ask */
+	*(skb_put(*skb, 1)) = 0x00;
+
+	*((ushort *) skb_put(*skb, 2)) = MRU;
+
+
+	*(skb_put(*skb, 1)) = 0x08;           /* Modulo */
+	*(skb_put(*skb, 1)) = 0x07;           /* Max Window */
+
+	*(skb_put(*skb, 1)) = 0x01;           /* No Layer3 Protocol */
+
+	/*
+	 * 2 - layer3 MTU       [10]
+	 *   - Modulo           [12]
+	 *   - Window
+	 *   - layer1 proto     [14]
+	 *   - bitrate
+	 *   - sub-channel      [16]
+	 *   - layer1dataformat [17]
+	 */
+
+	memset(skb_put(*skb, 8), 0, 8);
+
+	return 18;
 }
 
 
@@ -264,45 +264,45 @@ int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
 {
 
 	if ((*skb = dev_alloc_skb(7)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
 
-        
-        *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
-        *(skb_put(*skb, 1)) = 0x00;             /* Transmit by default */
 
-        *((ushort *) skb_put(*skb, 2)) = MRU;
+	*(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
+	*(skb_put(*skb, 1)) = 0x00;             /* Transmit by default */
 
-        *(skb_put(*skb, 1)) = 0x01;             /* Enables reception*/
+	*((ushort *) skb_put(*skb, 2)) = MRU;
 
-        return 7;
+	*(skb_put(*skb, 1)) = 0x01;             /* Enables reception*/
+
+	return 7;
 }
 
-int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb)
+int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb)
 {
 	ushort data_len;
-	
 
-	/*  
-	 * callref      - 2  
+
+	/*
+	 * callref      - 2
 	 * layer2link   - 1
-	 * wBlockLength - 2 
+	 * wBlockLength - 2
 	 * data         - 4
 	 * sernum       - 1
 	 */
-	
+
 	data_len = skb->len;
 
-	if(skb_headroom(skb) < 10)
+	if (skb_headroom(skb) < 10)
 	{
 		printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb);
 	}
 	else
-	{	
+	{
 		skb_push(skb, 10);
 	}
 
@@ -318,58 +318,58 @@ int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb)
 	return 10;
 }
 
-int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb)
-		    
+int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb)
+
 {
 	if ((*skb = dev_alloc_skb(4)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
 
-        *(skb_put(*skb, 1)) = chan->layer2link;
-        *(skb_put(*skb, 1)) = chan->r_refnum;
+	*(skb_put(*skb, 1)) = chan->layer2link;
+	*(skb_put(*skb, 1)) = chan->r_refnum;
 
-        return (*skb)->len;
+	return (*skb)->len;
 }
 
 int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
 {
 
 	if ((*skb = dev_alloc_skb(6)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2) ) = callref;  
+	*((ushort *)skb_put(*skb, 2)) = callref;
 
-        *(skb_put(*skb, 1)) = 2;                  /* Cause.Length = 2; */
-        *(skb_put(*skb, 1)) = 0x80;
-        *(skb_put(*skb, 1)) = 0x80 | cause;           
+	*(skb_put(*skb, 1)) = 2;                  /* Cause.Length = 2; */
+	*(skb_put(*skb, 1)) = 0x80;
+	*(skb_put(*skb, 1)) = 0x80 | cause;
 
-        /* 
-         * Change it: we should send 'Sic transit gloria Mundi' here ;-) 
-         */
+	/*
+	 * Change it: we should send 'Sic transit gloria Mundi' here ;-)
+	 */
 
-        *(skb_put(*skb, 1)) = 0;                   /* UTUS.Length = 0;  */
+	*(skb_put(*skb, 1)) = 0;                   /* UTUS.Length = 0;  */
 
-        return 6;
+	return 6;
 }
 
 int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
 {
 	if ((*skb = dev_alloc_skb(2)) == NULL) {
-    
+
 		printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n");
 		return -1;
 	}
 
-        *((ushort*) skb_put(*skb, 2)) = chan->callref;  
+	*((ushort *)skb_put(*skb, 2)) = chan->callref;
 
-        return 2;
+	return 2;
 }
 
 
@@ -378,57 +378,57 @@ int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
  *
  */
 
-int capi_decode_conn_ind(struct pcbit_chan * chan, 
-                         struct sk_buff *skb,
-                         struct callb_data *info) 
+int capi_decode_conn_ind(struct pcbit_chan *chan,
+			 struct sk_buff *skb,
+			 struct callb_data *info)
 {
-        int CIlen, len;
+	int CIlen, len;
 
-        /* Call Reference [CAPI] */
-        chan->callref = *((ushort*) skb->data);
-        skb_pull(skb, 2);
+	/* Call Reference [CAPI] */
+	chan->callref = *((ushort *)skb->data);
+	skb_pull(skb, 2);
 
 #ifdef DEBUG
-	printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); 
+	printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
 #endif
 
-        /* Channel Identification */
+	/* Channel Identification */
 
-        /* Expect  
-           Len = 1 
-           Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
-           */
+	/* Expect
+	   Len = 1
+	   Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
+	*/
 
-        CIlen = skb->data[0];
+	CIlen = skb->data[0];
 #ifdef DEBUG
-        if (CIlen == 1) {
+	if (CIlen == 1) {
 
-                if ( ((skb->data[1]) & 0xFC) == 0x48 )
-                        printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
-                printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03); 
-        }
+		if (((skb->data[1]) & 0xFC) == 0x48)
+			printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
+		printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03);
+	}
 	else
 		printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen);
 #endif
-        skb_pull(skb, CIlen + 1);
+	skb_pull(skb, CIlen + 1);
 
-        /* Calling Party Number */
-        /* An "additional service" as far as Portugal Telecom is concerned */
+	/* Calling Party Number */
+	/* An "additional service" as far as Portugal Telecom is concerned */
 
-        len = skb->data[0];
+	len = skb->data[0];
 
 	if (len > 0) {
 		int count = 1;
-		
+
 #ifdef DEBUG
 		printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
 #endif
 		if ((skb->data[1] & 0x80) == 0)
 			count = 2;
-		
+
 		if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
 			return -1;
-       
+
 		skb_copy_from_linear_data_offset(skb, count + 1,
 						 info->data.setup.CallingPN,
 						 len - count);
@@ -442,22 +442,22 @@ int capi_decode_conn_ind(struct pcbit_chan * chan,
 
 	skb_pull(skb, len + 1);
 
-        /* Calling Party Subaddress */
-        skb_pull(skb, skb->data[0] + 1);
+	/* Calling Party Subaddress */
+	skb_pull(skb, skb->data[0] + 1);
 
-        /* Called Party Number */
+	/* Called Party Number */
 
-        len = skb->data[0];
+	len = skb->data[0];
 
 	if (len > 0) {
 		int count = 1;
-		
+
 		if ((skb->data[1] & 0x80) == 0)
 			count = 2;
-        
+
 		if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
 			return -1;
-        
+
 		skb_copy_from_linear_data_offset(skb, count + 1,
 						 info->data.setup.CalledPN,
 						 len - count);
@@ -471,73 +471,73 @@ int capi_decode_conn_ind(struct pcbit_chan * chan,
 
 	skb_pull(skb, len + 1);
 
-        /* Called Party Subaddress */
-        skb_pull(skb, skb->data[0] + 1);
+	/* Called Party Subaddress */
+	skb_pull(skb, skb->data[0] + 1);
 
-        /* LLC */
-        skb_pull(skb, skb->data[0] + 1);
+	/* LLC */
+	skb_pull(skb, skb->data[0] + 1);
 
-        /* HLC */
-        skb_pull(skb, skb->data[0] + 1);
+	/* HLC */
+	skb_pull(skb, skb->data[0] + 1);
 
-        /* U2U */
-        skb_pull(skb, skb->data[0] + 1);
+	/* U2U */
+	skb_pull(skb, skb->data[0] + 1);
 
-        return 0;
+	return 0;
 }
 
 /*
  *  returns errcode
  */
 
-int capi_decode_conn_conf(struct pcbit_chan * chan, struct sk_buff *skb,
-			  int *complete) 
+int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb,
+			  int *complete)
 {
-        int errcode;
-  
-        chan->callref = *((ushort *) skb->data);     /* Update CallReference */
-        skb_pull(skb, 2);
+	int errcode;
+
+	chan->callref = *((ushort *)skb->data);     /* Update CallReference */
+	skb_pull(skb, 2);
+
+	errcode = *((ushort *) skb->data);   /* read errcode */
+	skb_pull(skb, 2);
 
-        errcode = *((ushort *) skb->data);   /* read errcode */
-        skb_pull(skb, 2);
+	*complete = *(skb->data);
+	skb_pull(skb, 1);
 
-        *complete = *(skb->data);
-        skb_pull(skb, 1);
+	/* FIX ME */
+	/* This is actually a firmware bug */
+	if (!*complete)
+	{
+		printk(KERN_DEBUG "complete=%02x\n", *complete);
+		*complete = 1;
+	}
 
-        /* FIX ME */
-        /* This is actually a firmware bug */
-        if (!*complete)
-        {
-                printk(KERN_DEBUG "complete=%02x\n", *complete);
-                *complete = 1;
-        }
 
+	/* Optional Bearer Capability */
+	skb_pull(skb, *(skb->data) + 1);
 
-        /* Optional Bearer Capability */
-        skb_pull(skb, *(skb->data) + 1);
-        
-        /* Channel Identification */
-        skb_pull(skb, *(skb->data) + 1);
+	/* Channel Identification */
+	skb_pull(skb, *(skb->data) + 1);
 
-        /* High Layer Compatibility follows */
-        skb_pull(skb, *(skb->data) + 1);
+	/* High Layer Compatibility follows */
+	skb_pull(skb, *(skb->data) + 1);
 
-        return errcode;
+	return errcode;
 }
 
-int capi_decode_conn_actv_ind(struct pcbit_chan * chan, struct sk_buff *skb)
+int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb)
 {
-        ushort len;
+	ushort len;
 #ifdef DEBUG
-        char str[32];
+	char str[32];
 #endif
 
-        /* Yet Another Bearer Capability */
-        skb_pull(skb, *(skb->data) + 1);
-  
+	/* Yet Another Bearer Capability */
+	skb_pull(skb, *(skb->data) + 1);
 
-        /* Connected Party Number */
-        len=*(skb->data);
+
+	/* Connected Party Number */
+	len = *(skb->data);
 
 #ifdef DEBUG
 	if (len > 1 && len < 31) {
@@ -549,106 +549,101 @@ int capi_decode_conn_actv_ind(struct pcbit_chan * chan, struct sk_buff *skb)
 		printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
 #endif
 
-        skb_pull(skb, len + 1);
+	skb_pull(skb, len + 1);
 
-        /* Connected Subaddress */
-        skb_pull(skb, *(skb->data) + 1);
+	/* Connected Subaddress */
+	skb_pull(skb, *(skb->data) + 1);
 
-        /* Low Layer Capability */
-        skb_pull(skb, *(skb->data) + 1);
+	/* Low Layer Capability */
+	skb_pull(skb, *(skb->data) + 1);
 
-        /* High Layer Capability */
-        skb_pull(skb, *(skb->data) + 1);
+	/* High Layer Capability */
+	skb_pull(skb, *(skb->data) + 1);
 
-        return 0;
+	return 0;
 }
 
-int capi_decode_conn_actv_conf(struct pcbit_chan * chan, struct sk_buff *skb)
+int capi_decode_conn_actv_conf(struct pcbit_chan *chan, struct sk_buff *skb)
 {
-        ushort errcode;
-
-        errcode = *((ushort*) skb->data);
-        skb_pull(skb, 2);
-        
-        /* Channel Identification 
-        skb_pull(skb, skb->data[0] + 1);
-        */
-        return errcode;
+	ushort errcode;
+
+	errcode = *((ushort *)skb->data);
+	skb_pull(skb, 2);
+
+	/* Channel Identification
+	   skb_pull(skb, skb->data[0] + 1);
+	*/
+	return errcode;
 }
 
 
 int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
 {
-        ushort errcode;
-        
-        chan->layer2link = *(skb->data);
-        skb_pull(skb, 1);
+	ushort errcode;
 
-        errcode = *((ushort*) skb->data);
-        skb_pull(skb, 2);
+	chan->layer2link = *(skb->data);
+	skb_pull(skb, 1);
 
-        return errcode;
+	errcode = *((ushort *)skb->data);
+	skb_pull(skb, 2);
+
+	return errcode;
 }
 
 int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
 {
-        ushort errcode;
+	ushort errcode;
 
-        if (chan->layer2link != *(skb->data) )
-                printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");
+	if (chan->layer2link != *(skb->data))
+		printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");
 
-        skb_pull(skb, 1);
+	skb_pull(skb, 1);
 
-        errcode = *((ushort*) skb->data);
-        skb_pull(skb, 2);
+	errcode = *((ushort *)skb->data);
+	skb_pull(skb, 2);
 
-        return errcode;        
+	return errcode;
 }
 
 int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
 {
-        ushort len;
+	ushort len;
 #ifdef DEBUG
-        int i;
+	int i;
 #endif
-        /* Cause */
-        
-        len = *(skb->data);
-        skb_pull(skb, 1);
+	/* Cause */
+
+	len = *(skb->data);
+	skb_pull(skb, 1);
 
 #ifdef DEBUG
 
-        for (i=0; i<len; i++)
-                printk(KERN_DEBUG "Cause Octect %d: %02x\n", i+3, 
-                       *(skb->data + i));
+	for (i = 0; i < len; i++)
+		printk(KERN_DEBUG "Cause Octect %d: %02x\n", i + 3,
+		       *(skb->data + i));
 #endif
 
-        skb_pull(skb, len);
+	skb_pull(skb, len);
 
-        return 0;
+	return 0;
 }
 
 #ifdef DEBUG
 int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
 {
-        char str[64];
-        int len;
-        
-        len = hdr[0];
-
-        if (len < 64 && len == hdrlen - 1) {        
-                memcpy(str, hdr + 1, hdrlen - 1);
-                str[hdrlen - 1] = 0;
-                printk("%s\n", str);
-        }
-        else
-                printk("debug message incorrect\n");
-
-        return 0;
-}
-#endif
-
-
+	char str[64];
+	int len;
 
+	len = hdr[0];
 
+	if (len < 64 && len == hdrlen - 1) {
+		memcpy(str, hdr + 1, hdrlen - 1);
+		str[hdrlen - 1] = 0;
+		printk("%s\n", str);
+	}
+	else
+		printk("debug message incorrect\n");
 
+	return 0;
+}
+#endif
diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h
index df8e73c..635f634 100644
--- a/drivers/isdn/pcbit/capi.h
+++ b/drivers/isdn/pcbit/capi.h
@@ -2,10 +2,10 @@
  * CAPI encode/decode prototypes and defines
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -15,42 +15,42 @@
 
 #define REQ_CAUSE         0x01
 #define REQ_DISPLAY       0x04
-#define REQ_USER_TO_USER  0x08 
+#define REQ_USER_TO_USER  0x08
 
-#define AppInfoMask  REQ_CAUSE|REQ_DISPLAY|REQ_USER_TO_USER 
+#define AppInfoMask  REQ_CAUSE | REQ_DISPLAY | REQ_USER_TO_USER
 
 /* Connection Setup */
-extern int capi_conn_req(const char * calledPN, struct sk_buff **buf,
+extern int capi_conn_req(const char *calledPN, struct sk_buff **buf,
 			 int proto);
-extern int capi_decode_conn_conf(struct pcbit_chan * chan, struct sk_buff *skb,
-				 int *complete); 
+extern int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb,
+				 int *complete);
 
-extern int capi_decode_conn_ind(struct pcbit_chan * chan, struct sk_buff *skb,
+extern int capi_decode_conn_ind(struct pcbit_chan *chan, struct sk_buff *skb,
 				struct callb_data *info);
-extern int capi_conn_resp(struct pcbit_chan* chan, struct sk_buff **skb);
+extern int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb);
 
-extern int capi_conn_active_req(struct pcbit_chan* chan, struct sk_buff **skb);
-extern int capi_decode_conn_actv_conf(struct pcbit_chan * chan, 
+extern int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb);
+extern int capi_decode_conn_actv_conf(struct pcbit_chan *chan,
 				      struct sk_buff *skb);
 
-extern int capi_decode_conn_actv_ind(struct pcbit_chan * chan, 
+extern int capi_decode_conn_actv_ind(struct pcbit_chan *chan,
 				     struct sk_buff *skb);
-extern int capi_conn_active_resp(struct pcbit_chan* chan, 
+extern int capi_conn_active_resp(struct pcbit_chan *chan,
 				 struct sk_buff **skb);
 
 /* Data */
 extern int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
 				 int outgoing);
-extern int capi_decode_sel_proto_conf(struct pcbit_chan *chan, 
+extern int capi_decode_sel_proto_conf(struct pcbit_chan *chan,
 				      struct sk_buff *skb);
 
-extern int capi_activate_transp_req(struct pcbit_chan *chan, 
+extern int capi_activate_transp_req(struct pcbit_chan *chan,
 				    struct sk_buff **skb);
-extern int capi_decode_actv_trans_conf(struct pcbit_chan *chan, 
+extern int capi_decode_actv_trans_conf(struct pcbit_chan *chan,
 				       struct sk_buff *skb);
 
-extern int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb);
-extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb);
+extern int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb);
+extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb);
 
 /* Connection Termination */
 extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause);
@@ -62,12 +62,12 @@ extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb);
 extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen);
 #endif
 
-static inline struct pcbit_chan * 
+static inline struct pcbit_chan *
 capi_channel(struct pcbit_dev *dev, struct sk_buff *skb)
 {
 	ushort callref;
 
-	callref = *((ushort*) skb->data);
+	callref = *((ushort *)skb->data);
 	skb_pull(skb, 2);
 
 	if (dev->b1->callref == callref)
@@ -79,9 +79,3 @@ capi_channel(struct pcbit_dev *dev, struct sk_buff *skb)
 }
 
 #endif
-
-
-
-
-
-
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 1507d2e..1eaf622 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -2,10 +2,10 @@
  * PCBIT-D interface with isdn4linux
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -14,7 +14,7 @@
  *
  *	Nuno Grilo	<l38486@alfa.ist.utl.pt>
  *      fixed msn_list NULL pointer dereference.
- *		
+ *
  */
 
 #include <linux/module.h>
@@ -43,9 +43,9 @@
 
 extern ushort last_ref_num;
 
-static int pcbit_ioctl(isdn_ctrl* ctl);
+static int pcbit_ioctl(isdn_ctrl *ctl);
 
-static char* pcbit_devname[MAX_PCBIT_CARDS] = {
+static char *pcbit_devname[MAX_PCBIT_CARDS] = {
 	"pcbit0",
 	"pcbit1",
 	"pcbit2",
@@ -56,12 +56,12 @@ static char* pcbit_devname[MAX_PCBIT_CARDS] = {
  * prototypes
  */
 
-static int pcbit_command(isdn_ctrl* ctl);
-static int pcbit_stat(u_char __user * buf, int len, int, int);
+static int pcbit_command(isdn_ctrl *ctl);
+static int pcbit_stat(u_char __user *buf, int len, int, int);
 static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
 static int pcbit_writecmd(const u_char __user *, int, int, int);
 
-static int set_protocol_running(struct pcbit_dev * dev);
+static int set_protocol_running(struct pcbit_dev *dev);
 
 static void pcbit_clear_msn(struct pcbit_dev *dev);
 static void pcbit_set_msn(struct pcbit_dev *dev, char *list);
@@ -73,7 +73,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 	struct pcbit_dev *dev;
 	isdn_if *dev_if;
 
-	if ((dev=kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
+	if ((dev = kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
 	{
 		printk("pcbit_init: couldn't malloc pcbit_dev struct\n");
 		return -ENOMEM;
@@ -83,19 +83,19 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 	init_waitqueue_head(&dev->set_running_wq);
 	spin_lock_init(&dev->lock);
 
-	if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) {
+	if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF) {
 		dev->ph_mem = mem_base;
 		if (!request_mem_region(dev->ph_mem, 4096, "PCBIT mem")) {
 			printk(KERN_WARNING
-				"PCBIT: memory region %lx-%lx already in use\n",
-				dev->ph_mem, dev->ph_mem + 4096);
+			       "PCBIT: memory region %lx-%lx already in use\n",
+			       dev->ph_mem, dev->ph_mem + 4096);
 			kfree(dev);
 			dev_pcbit[board] = NULL;
 			return -EACCES;
 		}
 		dev->sh_mem = ioremap(dev->ph_mem, 4096);
 	}
-	else 
+	else
 	{
 		printk("memory address invalid");
 		kfree(dev);
@@ -111,7 +111,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 		kfree(dev);
 		return -ENOMEM;
 	}
-    
+
 	dev->b2 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
 	if (!dev->b2) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
@@ -130,7 +130,7 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 	 *  interrupts
 	 */
 
-	if (request_irq(irq, &pcbit_irq_handler, 0, pcbit_devname[board], dev) != 0) 
+	if (request_irq(irq, &pcbit_irq_handler, 0, pcbit_devname[board], dev) != 0)
 	{
 		kfree(dev->b1);
 		kfree(dev->b2);
@@ -168,16 +168,16 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 	dev_if->owner = THIS_MODULE;
 
 	dev_if->channels = 2;
-	
-	dev_if->features = (ISDN_FEATURE_P_EURO  | ISDN_FEATURE_L3_TRANS | 
-			    ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS );
+
+	dev_if->features = (ISDN_FEATURE_P_EURO  | ISDN_FEATURE_L3_TRANS |
+			    ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS);
 
 	dev_if->writebuf_skb = pcbit_xmit;
 	dev_if->hl_hdrlen = 16;
 
 	dev_if->maxbufsize = MAXBUFSIZE;
 	dev_if->command  = pcbit_command;
-	
+
 	dev_if->writecmd = pcbit_writecmd;
 	dev_if->readstat = pcbit_stat;
 
@@ -211,12 +211,12 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 #ifdef MODULE
 void pcbit_terminate(int board)
 {
-	struct pcbit_dev * dev;
+	struct pcbit_dev *dev;
 
 	dev = dev_pcbit[board];
 
 	if (dev) {
-	     /* unregister_isdn(dev->dev_if); */
+		/* unregister_isdn(dev->dev_if); */
 		free_irq(dev->irq, dev);
 		pcbit_clear_msn(dev);
 		kfree(dev->dev_if);
@@ -233,9 +233,9 @@ void pcbit_terminate(int board)
 }
 #endif
 
-static int pcbit_command(isdn_ctrl* ctl)
+static int pcbit_command(isdn_ctrl *ctl)
 {
-	struct pcbit_dev  *dev;
+	struct pcbit_dev *dev;
 	struct pcbit_chan *chan;
 	struct callb_data info;
 
@@ -250,7 +250,7 @@ static int pcbit_command(isdn_ctrl* ctl)
 	chan = (ctl->arg & 0x0F) ? dev->b2 : dev->b1;
 
 
-	switch(ctl->command) {
+	switch (ctl->command) {
 	case ISDN_CMD_IOCTL:
 		return pcbit_ioctl(ctl);
 		break;
@@ -299,10 +299,10 @@ static int pcbit_command(isdn_ctrl* ctl)
 static void pcbit_block_timer(unsigned long data)
 {
 	struct pcbit_chan *chan;
-	struct pcbit_dev * dev;
+	struct pcbit_dev *dev;
 	isdn_ctrl ictl;
 
-	chan = (struct pcbit_chan *) data;
+	chan = (struct pcbit_chan *)data;
 
 	dev = chan2dev(chan);
 
@@ -316,12 +316,12 @@ static void pcbit_block_timer(unsigned long data)
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "pcbit_block_timer\n");
-#endif	
+#endif
 	chan->queued = 0;
 	ictl.driver = dev->id;
 	ictl.command = ISDN_STAT_BSENT;
 	ictl.arg = chan->id;
-	dev->dev_if->statcallb(&ictl);     
+	dev->dev_if->statcallb(&ictl);
 }
 #endif
 
@@ -329,7 +329,7 @@ static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
 {
 	ushort hdrlen;
 	int refnum, len;
-	struct pcbit_chan * chan;
+	struct pcbit_chan *chan;
 	struct pcbit_dev *dev;
 
 	dev = finddev(driver);
@@ -345,10 +345,10 @@ static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
 	if (chan->fsm_state != ST_ACTIVE)
 		return -1;
 
-	if (chan->queued >= MAX_QUEUED )
+	if (chan->queued >= MAX_QUEUED)
 	{
 #ifdef DEBUG_QUEUE
-		printk(KERN_DEBUG 
+		printk(KERN_DEBUG
 		       "pcbit: %d packets already in queue - write fails\n",
 		       chan->queued);
 #endif
@@ -365,14 +365,14 @@ static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
 			chan->block_timer.expires = jiffies + 1 * HZ;
 			add_timer(&chan->block_timer);
 		}
-#endif		
-		return 0;	                 
+#endif
+		return 0;
 	}
 
 
 	chan->queued++;
-	
-        len = skb->len;
+
+	len = skb->len;
 
 	hdrlen = capi_tdata_req(chan, skb);
 
@@ -386,10 +386,10 @@ static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
 
 static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
 {
-	struct pcbit_dev * dev;
+	struct pcbit_dev *dev;
 	int i, j;
-	const u_char * loadbuf;
-	u_char * ptr = NULL;
+	const u_char *loadbuf;
+	u_char *ptr = NULL;
 	u_char *cbuf;
 
 	int errstat;
@@ -402,7 +402,7 @@ static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int cha
 		return -ENODEV;
 	}
 
-	switch(dev->l2_state) {
+	switch (dev->l2_state) {
 	case L2_LWMODE:
 		/* check (size <= rdp_size); write buf into board */
 		if (len < 0 || len > BANK4 + 1 || len > 1024)
@@ -422,19 +422,19 @@ static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int cha
 		/* this is the hard part */
 		/* dumb board */
 		/* get it into kernel space */
-		if ((ptr = kmalloc(len, GFP_KERNEL))==NULL)
+		if ((ptr = kmalloc(len, GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 		if (copy_from_user(ptr, buf, len)) {
 			kfree(ptr);
 			return -EFAULT;
 		}
 		loadbuf = ptr;
-    
+
 		errstat = 0;
 
-		for (i=0; i < len; i++)
+		for (i = 0; i < len; i++)
 		{
-			for(j=0; j < LOAD_RETRY; j++)
+			for (j = 0; j < LOAD_RETRY; j++)
 				if (!(readb(dev->sh_mem + dev->loadptr)))
 					break;
 
@@ -464,9 +464,9 @@ static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int cha
  *
  */
 
-void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg, 
-			     struct sk_buff * skb,
-			     ushort hdr_len, ushort refnum)
+void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg,
+		      struct sk_buff *skb,
+		      ushort hdr_len, ushort refnum)
 {
 	struct pcbit_chan *chan;
 	struct sk_buff *skb2;
@@ -475,11 +475,11 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 	int complete, err;
 	isdn_ctrl ictl;
 
-	switch(msg) {
+	switch (msg) {
 
 	case MSG_TDATA_IND:
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
@@ -488,30 +488,30 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 
 		dev->dev_if->rcvcallb_skb(dev->id, chan->id, skb);
 
-		if (capi_tdata_resp(chan, &skb2) > 0) 
-			pcbit_l2_write(dev, MSG_TDATA_RESP, refnum, 
+		if (capi_tdata_resp(chan, &skb2) > 0)
+			pcbit_l2_write(dev, MSG_TDATA_RESP, refnum,
 				       skb2, skb2->len);
 		return;
-		break;  
+		break;
 	case MSG_TDATA_CONF:
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
 
 #ifdef DEBUG
-		if ( (*((ushort *) (skb->data + 2) )) != 0) {
-                        printk(KERN_DEBUG "TDATA_CONF error\n");
+		if ((*((ushort *)(skb->data + 2))) != 0) {
+			printk(KERN_DEBUG "TDATA_CONF error\n");
 		}
 #endif
 #ifdef BLOCK_TIMER
-                if (chan->queued == MAX_QUEUED) {
-                        del_timer(&chan->block_timer);
+		if (chan->queued == MAX_QUEUED) {
+			del_timer(&chan->block_timer);
 			chan->block_timer.function = NULL;
 		}
-                
-#endif		
+
+#endif
 		chan->queued--;
 
 		ictl.driver = dev->id;
@@ -523,7 +523,7 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 	case MSG_CONN_IND:
 		/*
 		 *  channel: 1st not used will do
-		 *           if both are used we're in trouble 
+		 *           if both are used we're in trouble
 		 */
 
 		if (!dev->b1->fsm_state)
@@ -531,12 +531,12 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 		else if (!dev->b2->fsm_state)
 			chan = dev->b2;
 		else {
-			printk(KERN_INFO 
+			printk(KERN_INFO
 			       "Incoming connection: no channels available");
 
-			if ((len = capi_disc_req(*(ushort*)(skb->data), &skb2, CAUSE_NOCHAN)) > 0)
+			if ((len = capi_disc_req(*(ushort *)(skb->data), &skb2, CAUSE_NOCHAN)) > 0)
 				pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb2, len);
-			break;  
+			break;
 		}
 
 		cbdata.data.setup.CalledPN = NULL;
@@ -547,7 +547,7 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 
 		pcbit_fsm_event(dev, chan, EV_NET_SETUP, NULL);
 
-		if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN)) 
+		if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN))
 			pcbit_fsm_event(dev, chan, EV_USR_PROCED_REQ, &cbdata);
 		else
 			pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
@@ -555,26 +555,26 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 		kfree(cbdata.data.setup.CalledPN);
 		kfree(cbdata.data.setup.CallingPN);
 		break;
-    
+
 	case MSG_CONN_CONF:
-		/* 
+		/*
 		 * We should be able to find the channel by the message
 		 * reference number. The current version of the firmware
 		 * doesn't sent the ref number correctly.
 		 */
 #ifdef DEBUG
-		printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum, 
-		       dev->b1->s_refnum, 
+		printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum,
+		       dev->b1->s_refnum,
 		       dev->b2->s_refnum);
 #endif
 		/* We just try to find a channel in the right state */
 
 		if (dev->b1->fsm_state == ST_CALL_INIT)
 			chan = dev->b1;
-		else { 		   
+		else {
 			if (dev->b2->s_refnum == ST_CALL_INIT)
 				chan = dev->b2;
-			else {			
+			else {
 				chan = NULL;
 				printk(KERN_WARNING "Connection Confirm - no channel in Call Init state\n");
 				break;
@@ -589,18 +589,18 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 				pcbit_fsm_event(dev, chan, EV_NET_CALL_PROC, NULL);
 			else
 				pcbit_fsm_event(dev, chan, EV_NET_SETUP_ACK, NULL);
-		break; 
+		break;
 	case MSG_CONN_ACTV_IND:
 
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
-		
+
 		if (capi_decode_conn_actv_ind(chan, skb)) {
 			printk("error in capi_decode_conn_actv_ind\n");
-		     /* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */
+			/* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */
 			break;
 		}
 		chan->r_refnum = refnum;
@@ -609,14 +609,14 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 	case MSG_CONN_ACTV_CONF:
 
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
 
 		if (capi_decode_conn_actv_conf(chan, skb) == 0)
 			pcbit_fsm_event(dev, chan, EV_NET_CONN_ACK, NULL);
-		
+
 		else
 			printk(KERN_DEBUG "decode_conn_actv_conf failed\n");
 		break;
@@ -624,7 +624,7 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 	case  MSG_SELP_CONF:
 
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
@@ -638,7 +638,7 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 		break;
 	case MSG_ACT_TRANSP_CONF:
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
@@ -650,7 +650,7 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 	case MSG_DISC_IND:
 
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
@@ -662,7 +662,7 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
 		break;
 	case MSG_DISC_CONF:
 		if (!(chan = capi_channel(dev, skb))) {
-			printk(KERN_WARNING 
+			printk(KERN_WARNING
 			       "CAPI header: unknown channel id\n");
 			break;
 		}
@@ -711,24 +711,24 @@ static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
 		stat_count = STATBUF_LEN - stat_st + stat_end;
 
 	/* FIXME: should we sleep and wait for more cookies ? */
-	if (len > stat_count)            
+	if (len > stat_count)
 		len = stat_count;
 
 	if (stat_st < stat_end)
 	{
 		if (copy_to_user(buf, statbuf + stat_st, len))
 			return -EFAULT;
-		stat_st += len;	   
+		stat_st += len;
 	}
 	else
 	{
 		if (len > STATBUF_LEN - stat_st)
 		{
 			if (copy_to_user(buf, statbuf + stat_st,
-				       STATBUF_LEN - stat_st))
+					 STATBUF_LEN - stat_st))
 				return -EFAULT;
 			if (copy_to_user(buf, statbuf,
-				       len - (STATBUF_LEN - stat_st)))
+					 len - (STATBUF_LEN - stat_st)))
 				return -EFAULT;
 
 			stat_st = len - (STATBUF_LEN - stat_st);
@@ -739,7 +739,7 @@ static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
 				return -EFAULT;
 
 			stat_st += len;
-			
+
 			if (stat_st == STATBUF_LEN)
 				stat_st = 0;
 		}
@@ -756,27 +756,27 @@ static void pcbit_logstat(struct pcbit_dev *dev, char *str)
 	int i;
 	isdn_ctrl ictl;
 
-	for (i=stat_end; i<strlen(str); i++)
+	for (i = stat_end; i < strlen(str); i++)
 	{
-		statbuf[i]=str[i];
+		statbuf[i] = str[i];
 		stat_end = (stat_end + 1) % STATBUF_LEN;
 		if (stat_end == stat_st)
 			stat_st = (stat_st + 1) % STATBUF_LEN;
 	}
 
-	ictl.command=ISDN_STAT_STAVAIL;
-	ictl.driver=dev->id;
-	ictl.arg=strlen(str);
+	ictl.command = ISDN_STAT_STAVAIL;
+	ictl.driver = dev->id;
+	ictl.arg = strlen(str);
 	dev->dev_if->statcallb(&ictl);
 }
-	
-void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan, 
+
+void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan,
 			unsigned short i, unsigned short ev, unsigned short f)
 {
 	char buf[256];
-  
+
 	sprintf(buf, "change on device: %d channel:%d\n%s -> %s -> %s\n",
-		dev->id, chan->id, 
+		dev->id, chan->id,
 		isdn_state_table[i], strisdnevent(ev), isdn_state_table[f]
 		);
 
@@ -789,7 +789,7 @@ void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan,
 
 static void set_running_timeout(unsigned long ptr)
 {
-	struct pcbit_dev * dev;
+	struct pcbit_dev *dev;
 
 #ifdef DEBUG
 	printk(KERN_DEBUG "set_running_timeout\n");
@@ -799,7 +799,7 @@ static void set_running_timeout(unsigned long ptr)
 	wake_up_interruptible(&dev->set_running_wq);
 }
 
-static int set_protocol_running(struct pcbit_dev * dev)
+static int set_protocol_running(struct pcbit_dev *dev)
 {
 	isdn_ctrl ctl;
 
@@ -813,7 +813,7 @@ static int set_protocol_running(struct pcbit_dev * dev)
 
 	dev->l2_state = L2_STARTING;
 
-	writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)), 
+	writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
 	       dev->sh_mem + BANK4);
 
 	add_timer(&dev->set_running_timer);
@@ -830,8 +830,8 @@ static int set_protocol_running(struct pcbit_dev * dev)
 
 		dev->writeptr = dev->sh_mem;
 		dev->readptr = dev->sh_mem + BANK2;
-    
-		/* tell the good news to the upper layer */  
+
+		/* tell the good news to the upper layer */
 		ctl.driver = dev->id;
 		ctl.command = ISDN_STAT_RUN;
 
@@ -845,7 +845,7 @@ static int set_protocol_running(struct pcbit_dev * dev)
 		dev->l2_state = L2_DOWN;
 
 #ifdef DEBUG
-		printk(KERN_DEBUG "Bank3 = %02x\n", 
+		printk(KERN_DEBUG "Bank3 = %02x\n",
 		       readb(dev->sh_mem + BANK3));
 #endif
 		writeb(0x40, dev->sh_mem + BANK4);
@@ -862,13 +862,13 @@ static int set_protocol_running(struct pcbit_dev * dev)
 	return 0;
 }
 
-static int pcbit_ioctl(isdn_ctrl* ctl)
+static int pcbit_ioctl(isdn_ctrl *ctl)
 {
-	struct pcbit_dev * dev;
+	struct pcbit_dev *dev;
 	struct pcbit_ioctl *cmd;
 
 	dev = finddev(ctl->driver);
-  
+
 	if (!dev)
 	{
 		printk(KERN_DEBUG "pcbit_ioctl: unknown device\n");
@@ -877,7 +877,7 @@ static int pcbit_ioctl(isdn_ctrl* ctl)
 
 	cmd = (struct pcbit_ioctl *) ctl->parm.num;
 
-	switch(ctl->arg) {
+	switch (ctl->arg) {
 	case PCBIT_IOCTL_GETSTAT:
 		cmd->info.l2_status = dev->l2_state;
 		break;
@@ -890,7 +890,7 @@ static int pcbit_ioctl(isdn_ctrl* ctl)
 
 		dev->writeptr = dev->sh_mem;
 		dev->readptr = dev->sh_mem + BANK2;
-    
+
 		dev->l2_state = L2_LOADING;
 		break;
 
@@ -907,21 +907,21 @@ static int pcbit_ioctl(isdn_ctrl* ctl)
 		dev->loadptr = LOAD_ZONE_START;
 		dev->l2_state = L2_FWMODE;
 
-		break; 
+		break;
 	case PCBIT_IOCTL_ENDLOAD:
 		if (dev->l2_state == L2_RUNNING)
 			return -EBUSY;
 		dev->l2_state = L2_DOWN;
-		break; 
+		break;
 
-	case PCBIT_IOCTL_SETBYTE: 
+	case PCBIT_IOCTL_SETBYTE:
 		if (dev->l2_state == L2_RUNNING)
 			return -EBUSY;
 
 		/* check addr */
 		if (cmd->info.rdp_byte.addr > BANK4)
 			return -EFAULT;
-		
+
 		writeb(cmd->info.rdp_byte.value, dev->sh_mem + cmd->info.rdp_byte.addr);
 		break;
 	case PCBIT_IOCTL_GETBYTE:
@@ -935,10 +935,10 @@ static int pcbit_ioctl(isdn_ctrl* ctl)
 			printk("getbyte: invalid addr %04x\n", cmd->info.rdp_byte.addr);
 			return -EFAULT;
 		}
-		
-		cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr); 
+
+		cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr);
 		break;
-	case PCBIT_IOCTL_RUNNING: 
+	case PCBIT_IOCTL_RUNNING:
 		if (dev->l2_state == L2_RUNNING)
 			return -EBUSY;
 		return set_protocol_running(dev);
@@ -972,25 +972,25 @@ static int pcbit_ioctl(isdn_ctrl* ctl)
 	return 0;
 }
 
-/* 
+/*
  *        MSN list handling
  *
  *        if null reject all calls
- *        if first entry has null MSN accept all calls 
+ *        if first entry has null MSN accept all calls
  */
 
 static void pcbit_clear_msn(struct pcbit_dev *dev)
 {
 	struct msn_entry *ptr, *back;
 
-	for (ptr=dev->msn_list; ptr; )
+	for (ptr = dev->msn_list; ptr;)
 	{
 		back = ptr->next;
 		kfree(ptr);
 		ptr = back;
 	}
 
-	dev->msn_list = NULL; 
+	dev->msn_list = NULL;
 }
 
 static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
@@ -1016,12 +1016,12 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
 	}
 
 	if (dev->msn_list)
-		for (back=dev->msn_list; back->next; back=back->next);
-	
+		for (back = dev->msn_list; back->next; back = back->next);
+
 	sp = list;
 
 	do {
-		cp=strchr(sp, ',');
+		cp = strchr(sp, ',');
 		if (cp)
 			len = cp - sp;
 		else
@@ -1034,7 +1034,7 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
 			return;
 		}
 		ptr->next = NULL;
-		
+
 		ptr->msn = kmalloc(len, GFP_ATOMIC);
 		if (!ptr->msn) {
 			printk(KERN_WARNING "kmalloc failed\n");
@@ -1054,7 +1054,7 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
 			back->next = ptr;
 		back = ptr;
 		sp += len;
-	} while(cp);
+	} while (cp);
 }
 
 /*
@@ -1063,12 +1063,12 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
 static int pcbit_check_msn(struct pcbit_dev *dev, char *msn)
 {
 	struct msn_entry *ptr;
-	
-	for (ptr=dev->msn_list; ptr; ptr=ptr->next) {
 
-		if (ptr->msn == NULL) 
+	for (ptr = dev->msn_list; ptr; ptr = ptr->next) {
+
+		if (ptr->msn == NULL)
 			return 1;
-		
+
 		if (strcmp(ptr->msn, msn) == 0)
 			return 1;
 	}
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c
index 80c9c16..b2262ba 100644
--- a/drivers/isdn/pcbit/edss1.c
+++ b/drivers/isdn/pcbit/edss1.c
@@ -3,10 +3,10 @@
  * base: ITU-T Rec Q.931
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -34,145 +34,145 @@
 
 
 const char * const isdn_state_table[] = {
-  "Closed",
-  "Call initiated",
-  "Overlap sending",
-  "Outgoing call proceeding",
-  "NOT DEFINED",
-  "Call delivered",
-  "Call present",
-  "Call received",
-  "Connect request",
-  "Incoming call proceeding",
-  "Active",
-  "Disconnect request",
-  "Disconnect indication",
-  "NOT DEFINED",
-  "NOT DEFINED",
-  "Suspend request",
-  "NOT DEFINED",
-  "Resume request",
-  "NOT DEFINED",
-  "Release Request",
-  "NOT DEFINED",
-  "NOT DEFINED",
-  "NOT DEFINED",
-  "NOT DEFINED",
-  "NOT DEFINED",
-  "Overlap receiving",
-  "Select protocol on B-Channel",
-  "Activate B-channel protocol"
+	"Closed",
+	"Call initiated",
+	"Overlap sending",
+	"Outgoing call proceeding",
+	"NOT DEFINED",
+	"Call delivered",
+	"Call present",
+	"Call received",
+	"Connect request",
+	"Incoming call proceeding",
+	"Active",
+	"Disconnect request",
+	"Disconnect indication",
+	"NOT DEFINED",
+	"NOT DEFINED",
+	"Suspend request",
+	"NOT DEFINED",
+	"Resume request",
+	"NOT DEFINED",
+	"Release Request",
+	"NOT DEFINED",
+	"NOT DEFINED",
+	"NOT DEFINED",
+	"NOT DEFINED",
+	"NOT DEFINED",
+	"Overlap receiving",
+	"Select protocol on B-Channel",
+	"Activate B-channel protocol"
 };
 
 #ifdef DEBUG_ERRS
 static
 struct CauseValue {
-  byte nr;
-  char *descr;
-} cvlist[]={
-  {0x01,"Unallocated (unassigned) number"},
-  {0x02,"No route to specified transit network"},
-  {0x03,"No route to destination"},
-  {0x04,"Send special information tone"},
-  {0x05,"Misdialled trunk prefix"},
-  {0x06,"Channel unacceptable"},
-  {0x07,"Channel awarded and being delivered in an established channel"},
-  {0x08,"Preemption"},
-  {0x09,"Preemption - circuit reserved for reuse"},
-  {0x10,"Normal call clearing"},
-  {0x11,"User busy"},
-  {0x12,"No user responding"},
-  {0x13,"No answer from user (user alerted)"},
-  {0x14,"Subscriber absent"},
-  {0x15,"Call rejected"},
-  {0x16,"Number changed"},
-  {0x1a,"non-selected user clearing"},
-  {0x1b,"Destination out of order"},
-  {0x1c,"Invalid number format (address incomplete)"},
-  {0x1d,"Facility rejected"},
-  {0x1e,"Response to Status enquiry"},
-  {0x1f,"Normal, unspecified"},
-  {0x22,"No circuit/channel available"},
-  {0x26,"Network out of order"},
-  {0x27,"Permanent frame mode connection out-of-service"},
-  {0x28,"Permanent frame mode connection operational"},
-  {0x29,"Temporary failure"},
-  {0x2a,"Switching equipment congestion"},
-  {0x2b,"Access information discarded"},
-  {0x2c,"Requested circuit/channel not available"},
-  {0x2e,"Precedence call blocked"},
-  {0x2f,"Resource unavailable, unspecified"},
-  {0x31,"Quality of service unavailable"},
-  {0x32,"Requested facility not subscribed"},
-  {0x35,"Outgoing calls barred within CUG"},
-  {0x37,"Incoming calls barred within CUG"},
-  {0x39,"Bearer capability not authorized"},
-  {0x3a,"Bearer capability not presently available"},
-  {0x3e,"Inconsistency in designated outgoing access information and subscriber class"},
-  {0x3f,"Service or option not available, unspecified"},
-  {0x41,"Bearer capability not implemented"},
-  {0x42,"Channel type not implemented"},
-  {0x43,"Requested facility not implemented"},
-  {0x44,"Only restricted digital information bearer capability is available"},
-  {0x4f,"Service or option not implemented"},
-  {0x51,"Invalid call reference value"},
-  {0x52,"Identified channel does not exist"},
-  {0x53,"A suspended call exists, but this call identity does not"},
-  {0x54,"Call identity in use"},
-  {0x55,"No call suspended"},
-  {0x56,"Call having the requested call identity has been cleared"},
-  {0x57,"User not member of CUG"},
-  {0x58,"Incompatible destination"},
-  {0x5a,"Non-existent CUG"},
-  {0x5b,"Invalid transit network selection"},
-  {0x5f,"Invalid message, unspecified"},
-  {0x60,"Mandatory information element is missing"},
-  {0x61,"Message type non-existent or not implemented"},
-  {0x62,"Message not compatible with call state or message type non-existent or not implemented"},
-  {0x63,"Information element/parameter non-existent or not implemented"},
-  {0x64,"Invalid information element contents"},
-  {0x65,"Message not compatible with call state"},
-  {0x66,"Recovery on timer expiry"},
-  {0x67,"Parameter non-existent or not implemented - passed on"},
-  {0x6e,"Message with unrecognized parameter discarded"},
-  {0x6f,"Protocol error, unspecified"},
-  {0x7f,"Interworking, unspecified"}
+	byte nr;
+	char *descr;
+} cvlist[] = {
+	{0x01, "Unallocated (unassigned) number"},
+	{0x02, "No route to specified transit network"},
+	{0x03, "No route to destination"},
+	{0x04, "Send special information tone"},
+	{0x05, "Misdialled trunk prefix"},
+	{0x06, "Channel unacceptable"},
+	{0x07, "Channel awarded and being delivered in an established channel"},
+	{0x08, "Preemption"},
+	{0x09, "Preemption - circuit reserved for reuse"},
+	{0x10, "Normal call clearing"},
+	{0x11, "User busy"},
+	{0x12, "No user responding"},
+	{0x13, "No answer from user (user alerted)"},
+	{0x14, "Subscriber absent"},
+	{0x15, "Call rejected"},
+	{0x16, "Number changed"},
+	{0x1a, "non-selected user clearing"},
+	{0x1b, "Destination out of order"},
+	{0x1c, "Invalid number format (address incomplete)"},
+	{0x1d, "Facility rejected"},
+	{0x1e, "Response to Status enquiry"},
+	{0x1f, "Normal, unspecified"},
+	{0x22, "No circuit/channel available"},
+	{0x26, "Network out of order"},
+	{0x27, "Permanent frame mode connection out-of-service"},
+	{0x28, "Permanent frame mode connection operational"},
+	{0x29, "Temporary failure"},
+	{0x2a, "Switching equipment congestion"},
+	{0x2b, "Access information discarded"},
+	{0x2c, "Requested circuit/channel not available"},
+	{0x2e, "Precedence call blocked"},
+	{0x2f, "Resource unavailable, unspecified"},
+	{0x31, "Quality of service unavailable"},
+	{0x32, "Requested facility not subscribed"},
+	{0x35, "Outgoing calls barred within CUG"},
+	{0x37, "Incoming calls barred within CUG"},
+	{0x39, "Bearer capability not authorized"},
+	{0x3a, "Bearer capability not presently available"},
+	{0x3e, "Inconsistency in designated outgoing access information and subscriber class"},
+	{0x3f, "Service or option not available, unspecified"},
+	{0x41, "Bearer capability not implemented"},
+	{0x42, "Channel type not implemented"},
+	{0x43, "Requested facility not implemented"},
+	{0x44, "Only restricted digital information bearer capability is available"},
+	{0x4f, "Service or option not implemented"},
+	{0x51, "Invalid call reference value"},
+	{0x52, "Identified channel does not exist"},
+	{0x53, "A suspended call exists, but this call identity does not"},
+	{0x54, "Call identity in use"},
+	{0x55, "No call suspended"},
+	{0x56, "Call having the requested call identity has been cleared"},
+	{0x57, "User not member of CUG"},
+	{0x58, "Incompatible destination"},
+	{0x5a, "Non-existent CUG"},
+	{0x5b, "Invalid transit network selection"},
+	{0x5f, "Invalid message, unspecified"},
+	{0x60, "Mandatory information element is missing"},
+	{0x61, "Message type non-existent or not implemented"},
+	{0x62, "Message not compatible with call state or message type non-existent or not implemented"},
+	{0x63, "Information element/parameter non-existent or not implemented"},
+	{0x64, "Invalid information element contents"},
+	{0x65, "Message not compatible with call state"},
+	{0x66, "Recovery on timer expiry"},
+	{0x67, "Parameter non-existent or not implemented - passed on"},
+	{0x6e, "Message with unrecognized parameter discarded"},
+	{0x6f, "Protocol error, unspecified"},
+	{0x7f, "Interworking, unspecified"}
 };
 
 #endif
 
 static struct isdn_event_desc {
-  unsigned short ev;
-  char * desc;
-} isdn_event_table [] = {
-  {EV_USR_SETUP_REQ,     "CC->L3: Setup Request"},
-  {EV_USR_SETUP_RESP,    "CC->L3: Setup Response"},
-  {EV_USR_PROCED_REQ,    "CC->L3: Proceeding Request"},
-  {EV_USR_RELEASE_REQ,   "CC->L3: Release Request"},
-
-  {EV_NET_SETUP,        "NET->TE: setup "},
-  {EV_NET_CALL_PROC,    "NET->TE: call proceeding"},
-  {EV_NET_SETUP_ACK,    "NET->TE: setup acknowledge (more info needed)"},
-  {EV_NET_CONN,         "NET->TE: connect"},
-  {EV_NET_CONN_ACK,     "NET->TE: connect acknowledge"},
-  {EV_NET_DISC,         "NET->TE: disconnect indication"},
-  {EV_NET_RELEASE,      "NET->TE: release"},
-  {EV_NET_RELEASE_COMP, "NET->TE: release complete"},
-  {EV_NET_SELP_RESP,    "Board: Select B-channel protocol ack"},
-  {EV_NET_ACTV_RESP,    "Board: Activate B-channel protocol ack"},
-  {EV_TIMER,            "Timeout"},
-  {0, "NULL"}
+	unsigned short ev;
+	char *desc;
+} isdn_event_table[] = {
+	{EV_USR_SETUP_REQ,     "CC->L3: Setup Request"},
+	{EV_USR_SETUP_RESP,    "CC->L3: Setup Response"},
+	{EV_USR_PROCED_REQ,    "CC->L3: Proceeding Request"},
+	{EV_USR_RELEASE_REQ,   "CC->L3: Release Request"},
+
+	{EV_NET_SETUP,        "NET->TE: setup "},
+	{EV_NET_CALL_PROC,    "NET->TE: call proceeding"},
+	{EV_NET_SETUP_ACK,    "NET->TE: setup acknowledge (more info needed)"},
+	{EV_NET_CONN,         "NET->TE: connect"},
+	{EV_NET_CONN_ACK,     "NET->TE: connect acknowledge"},
+	{EV_NET_DISC,         "NET->TE: disconnect indication"},
+	{EV_NET_RELEASE,      "NET->TE: release"},
+	{EV_NET_RELEASE_COMP, "NET->TE: release complete"},
+	{EV_NET_SELP_RESP,    "Board: Select B-channel protocol ack"},
+	{EV_NET_ACTV_RESP,    "Board: Activate B-channel protocol ack"},
+	{EV_TIMER,            "Timeout"},
+	{0, "NULL"}
 };
 
-char * strisdnevent(ushort ev)
+char *strisdnevent(ushort ev)
 {
-  struct isdn_event_desc * entry;
- 
-  for (entry = isdn_event_table; entry->ev; entry++)
-    if (entry->ev == ev)
-      break;
+	struct isdn_event_desc *entry;
+
+	for (entry = isdn_event_table; entry->ev; entry++)
+		if (entry->ev == ev)
+			break;
 
-  return entry->desc;
+	return entry->desc;
 }
 
 /*
@@ -180,130 +180,130 @@ char * strisdnevent(ushort ev)
  */
 
 static struct fsm_timer_entry fsm_timers[] = {
-  {ST_CALL_PROC, 10},
-  {ST_DISC_REQ, 2},
-  {ST_ACTIVE_SELP, 5},
-  {ST_ACTIVE_ACTV, 5},
-  {ST_INCM_PROC, 10},
-  {ST_CONN_REQ, 2},
-  {0xff, 0}
+	{ST_CALL_PROC, 10},
+	{ST_DISC_REQ, 2},
+	{ST_ACTIVE_SELP, 5},
+	{ST_ACTIVE_ACTV, 5},
+	{ST_INCM_PROC, 10},
+	{ST_CONN_REQ, 2},
+	{0xff, 0}
 };
 
 static struct fsm_entry fsm_table[] = {
 /* Connect Phase */
-  /* Outgoing */
-  {ST_NULL, ST_CALL_INIT, EV_USR_SETUP_REQ, cb_out_1},
+	/* Outgoing */
+	{ST_NULL, ST_CALL_INIT, EV_USR_SETUP_REQ, cb_out_1},
 
-  {ST_CALL_INIT, ST_OVER_SEND, EV_NET_SETUP_ACK, cb_notdone},
-  {ST_CALL_INIT, ST_CALL_PROC, EV_NET_CALL_PROC, NULL},
-  {ST_CALL_INIT, ST_NULL, EV_NET_DISC, cb_out_2},
+	{ST_CALL_INIT, ST_OVER_SEND, EV_NET_SETUP_ACK, cb_notdone},
+	{ST_CALL_INIT, ST_CALL_PROC, EV_NET_CALL_PROC, NULL},
+	{ST_CALL_INIT, ST_NULL, EV_NET_DISC, cb_out_2},
 
-  {ST_CALL_PROC, ST_ACTIVE_SELP, EV_NET_CONN, cb_out_2},
-  {ST_CALL_PROC, ST_NULL, EV_NET_DISC, cb_disc_1},
-  {ST_CALL_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
+	{ST_CALL_PROC, ST_ACTIVE_SELP, EV_NET_CONN, cb_out_2},
+	{ST_CALL_PROC, ST_NULL, EV_NET_DISC, cb_disc_1},
+	{ST_CALL_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
 
-  /* Incoming */
-  {ST_NULL, ST_CALL_PRES, EV_NET_SETUP, NULL},
+	/* Incoming */
+	{ST_NULL, ST_CALL_PRES, EV_NET_SETUP, NULL},
 
-  {ST_CALL_PRES, ST_INCM_PROC, EV_USR_PROCED_REQ, cb_in_1},
-  {ST_CALL_PRES, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
+	{ST_CALL_PRES, ST_INCM_PROC, EV_USR_PROCED_REQ, cb_in_1},
+	{ST_CALL_PRES, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
 
-  {ST_INCM_PROC, ST_CONN_REQ, EV_USR_SETUP_RESP, cb_in_2},
-  {ST_INCM_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
+	{ST_INCM_PROC, ST_CONN_REQ, EV_USR_SETUP_RESP, cb_in_2},
+	{ST_INCM_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
 
-  {ST_CONN_REQ, ST_ACTIVE_SELP, EV_NET_CONN_ACK, cb_in_3},
+	{ST_CONN_REQ, ST_ACTIVE_SELP, EV_NET_CONN_ACK, cb_in_3},
 
-  /* Active */
-  {ST_ACTIVE, ST_NULL, EV_NET_DISC, cb_disc_1},
-  {ST_ACTIVE, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
-  {ST_ACTIVE, ST_NULL, EV_NET_RELEASE, cb_disc_3},
+	/* Active */
+	{ST_ACTIVE, ST_NULL, EV_NET_DISC, cb_disc_1},
+	{ST_ACTIVE, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
+	{ST_ACTIVE, ST_NULL, EV_NET_RELEASE, cb_disc_3},
 
-  /* Disconnect */
+	/* Disconnect */
 
-  {ST_DISC_REQ, ST_NULL, EV_NET_DISC, cb_disc_1},
-  {ST_DISC_REQ, ST_NULL, EV_NET_RELEASE, cb_disc_3},
+	{ST_DISC_REQ, ST_NULL, EV_NET_DISC, cb_disc_1},
+	{ST_DISC_REQ, ST_NULL, EV_NET_RELEASE, cb_disc_3},
 
-  /* protocol selection */
-  {ST_ACTIVE_SELP, ST_ACTIVE_ACTV, EV_NET_SELP_RESP, cb_selp_1},
-  {ST_ACTIVE_SELP, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
+	/* protocol selection */
+	{ST_ACTIVE_SELP, ST_ACTIVE_ACTV, EV_NET_SELP_RESP, cb_selp_1},
+	{ST_ACTIVE_SELP, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
 
-  {ST_ACTIVE_ACTV, ST_ACTIVE, EV_NET_ACTV_RESP, cb_open},
-  {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
+	{ST_ACTIVE_ACTV, ST_ACTIVE, EV_NET_ACTV_RESP, cb_open},
+	{ST_ACTIVE_ACTV, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
 
-  /* Timers */
-  {ST_CALL_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
-  {ST_DISC_REQ, ST_NULL, EV_TIMER, cb_disc_3},
-  {ST_ACTIVE_SELP, ST_DISC_REQ, EV_TIMER, cb_disc_2},
-  {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_TIMER, cb_disc_2},        
-  {ST_INCM_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
-  {ST_CONN_REQ, ST_CONN_REQ, EV_TIMER, cb_in_2},
-        
-  {0xff, 0, 0, NULL}
+	/* Timers */
+	{ST_CALL_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
+	{ST_DISC_REQ, ST_NULL, EV_TIMER, cb_disc_3},
+	{ST_ACTIVE_SELP, ST_DISC_REQ, EV_TIMER, cb_disc_2},
+	{ST_ACTIVE_ACTV, ST_DISC_REQ, EV_TIMER, cb_disc_2},
+	{ST_INCM_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
+	{ST_CONN_REQ, ST_CONN_REQ, EV_TIMER, cb_in_2},
+
+	{0xff, 0, 0, NULL}
 };
 
 
 static void pcbit_fsm_timer(unsigned long data)
 {
-        struct pcbit_dev *dev;
-        struct pcbit_chan *chan;
+	struct pcbit_dev *dev;
+	struct pcbit_chan *chan;
 
-        chan = (struct pcbit_chan *) data;
+	chan = (struct pcbit_chan *) data;
 
-        del_timer(&chan->fsm_timer);
-        chan->fsm_timer.function = NULL;
+	del_timer(&chan->fsm_timer);
+	chan->fsm_timer.function = NULL;
 
-        dev = chan2dev(chan);
+	dev = chan2dev(chan);
 
-        if (dev == NULL) {
-                printk(KERN_WARNING "pcbit: timer for unknown device\n");
-                return;
-        }
+	if (dev == NULL) {
+		printk(KERN_WARNING "pcbit: timer for unknown device\n");
+		return;
+	}
 
-        pcbit_fsm_event(dev, chan, EV_TIMER, NULL);
+	pcbit_fsm_event(dev, chan, EV_TIMER, NULL);
 }
 
 
 void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
-		   unsigned short event, struct callb_data *data)
+		     unsigned short event, struct callb_data *data)
 {
-	struct fsm_entry * action;	
+	struct fsm_entry *action;
 	struct fsm_timer_entry *tentry;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev->lock, flags);
 
-        for (action = fsm_table; action->init != 0xff; action++)
-                if (action->init == chan->fsm_state && action->event == event)
-                        break;
-  
+	for (action = fsm_table; action->init != 0xff; action++)
+		if (action->init == chan->fsm_state && action->event == event)
+			break;
+
 	if (action->init == 0xff) {
-		
+
 		spin_unlock_irqrestore(&dev->lock, flags);
-		printk(KERN_DEBUG "fsm error: event %x on state %x\n", 
-                       event, chan->fsm_state);
+		printk(KERN_DEBUG "fsm error: event %x on state %x\n",
+		       event, chan->fsm_state);
 		return;
 	}
 
-        if (chan->fsm_timer.function) {
-                del_timer(&chan->fsm_timer);
-                chan->fsm_timer.function = NULL;
-        }
+	if (chan->fsm_timer.function) {
+		del_timer(&chan->fsm_timer);
+		chan->fsm_timer.function = NULL;
+	}
 
 	chan->fsm_state = action->final;
-  
+
 	pcbit_state_change(dev, chan, action->init, event, action->final);
 
-        for (tentry = fsm_timers; tentry->init != 0xff; tentry++)
-                if (tentry->init == chan->fsm_state)
-                        break;
+	for (tentry = fsm_timers; tentry->init != 0xff; tentry++)
+		if (tentry->init == chan->fsm_state)
+			break;
 
-        if (tentry->init != 0xff) {
-                init_timer(&chan->fsm_timer);
-                chan->fsm_timer.function = &pcbit_fsm_timer;
-                chan->fsm_timer.data = (ulong) chan;
-                chan->fsm_timer.expires = jiffies + tentry->timeout * HZ;
-                add_timer(&chan->fsm_timer);
-        }
+	if (tentry->init != 0xff) {
+		init_timer(&chan->fsm_timer);
+		chan->fsm_timer.function = &pcbit_fsm_timer;
+		chan->fsm_timer.data = (ulong) chan;
+		chan->fsm_timer.expires = jiffies + tentry->timeout * HZ;
+		add_timer(&chan->fsm_timer);
+	}
 
 	spin_unlock_irqrestore(&dev->lock, flags);
 
@@ -311,7 +311,3 @@ void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
 		action->callb(dev, chan, data);
 
 }
-
-
-
-
diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h
index 39f8346..2f6b3a8 100644
--- a/drivers/isdn/pcbit/edss1.h
+++ b/drivers/isdn/pcbit/edss1.h
@@ -2,10 +2,10 @@
  * DSS.1 module definitions
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -62,9 +62,9 @@
 /*
  *  Cause values
  *  only the ones we use
- */ 
+ */
 
-#define CAUSE_NORMAL          0x10U 
+#define CAUSE_NORMAL          0x10U
 #define CAUSE_NOCHAN          0x22U
 
 struct callb_data {
@@ -94,9 +94,6 @@ extern const char * const isdn_state_table[];
 
 void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *,
 		     unsigned short event, struct callb_data *);
-char * strisdnevent(ushort ev);
+char *strisdnevent(ushort ev);
 
 #endif
-
-
-
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index 30f0f45..682911f 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -12,7 +12,7 @@
 /*
  * 19991203 - Fernando Carvalho - takion@superbofh.org
  * Hacked to compile with egcs and run with current version of isdn modules
-*/
+ */
 
 /*
  *        Based on documentation provided by Inesc:
@@ -77,7 +77,7 @@ pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
 	       struct sk_buff *skb, unsigned short hdr_len)
 {
 	struct frame_buf *frame,
-	*ptr;
+		*ptr;
 	unsigned long flags;
 
 	if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
@@ -85,7 +85,7 @@ pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
 		return -1;
 	}
 	if ((frame = kmalloc(sizeof(struct frame_buf),
-						  GFP_ATOMIC)) == NULL) {
+			     GFP_ATOMIC)) == NULL) {
 		printk(KERN_WARNING "pcbit_2_write: kmalloc failed\n");
 		dev_kfree_skb(skb);
 		return -1;
@@ -147,7 +147,7 @@ pcbit_transmit(struct pcbit_dev *dev)
 	int flen;               /* fragment frame length including all headers */
 	int free;
 	int count,
-	 cp_len;
+		cp_len;
 	unsigned long flags;
 	unsigned short tt;
 
@@ -177,7 +177,7 @@ pcbit_transmit(struct pcbit_dev *dev)
 
 			/* Type 0 frame */
 
-			ulong 	msg;
+			ulong	msg;
 
 			if (frame->skb)
 				flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
@@ -270,7 +270,7 @@ pcbit_transmit(struct pcbit_dev *dev)
 		spin_unlock_irqrestore(&dev->lock, flags);
 #ifdef DEBUG
 		printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
-		     unacked, dev->free, dev->write_queue ? "not empty" :
+		       unacked, dev->free, dev->write_queue ? "not empty" :
 		       "empty");
 #endif
 	}
@@ -301,8 +301,8 @@ pcbit_deliver(struct work_struct *work)
 		SET_MSG_CMD(msg, frame->skb->data[2]);
 		SET_MSG_SCMD(msg, frame->skb->data[3]);
 
-		frame->refnum = *((ushort *) frame->skb->data + 4);
-		frame->msg = *((ulong *) & msg);
+		frame->refnum = *((ushort *)frame->skb->data + 4);
+		frame->msg = *((ulong *)&msg);
 
 		skb_pull(frame->skb, 6);
 
@@ -326,7 +326,7 @@ pcbit_receive(struct pcbit_dev *dev)
 {
 	unsigned short tt;
 	u_char cpu,
-	 proc;
+		proc;
 	struct frame_buf *frame = NULL;
 	unsigned long flags;
 	u_char type1;
@@ -378,10 +378,10 @@ pcbit_receive(struct pcbit_dev *dev)
 		frame->dt_len = pcbit_readw(dev);
 
 		/*
-		   * 0 sized packet
-		   * I don't know if they are an error or not...
-		   * But they are very frequent
-		   * Not documented
+		 * 0 sized packet
+		 * I don't know if they are an error or not...
+		 * But they are very frequent
+		 * Not documented
 		 */
 
 		if (frame->hdr_len == 0) {
@@ -499,8 +499,8 @@ pcbit_irq_handler(int interrupt, void *devptr)
 {
 	struct pcbit_dev *dev;
 	u_char info,
-	 ack_seq,
-	 read_seq;
+		ack_seq,
+		read_seq;
 
 	dev = (struct pcbit_dev *) devptr;
 
@@ -666,7 +666,7 @@ static void
 pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
 {
 	int i,
-	 count;
+		count;
 	int unacked;
 
 	unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
@@ -678,13 +678,13 @@ pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
 		if (dev->send_seq > dev->unack_seq) {
 			if (ack <= dev->unack_seq || ack > dev->send_seq) {
 				printk(KERN_DEBUG
-				     "layer 2 ack unacceptable - dev %d",
+				       "layer 2 ack unacceptable - dev %d",
 				       dev->id);
 
 				pcbit_l2_error(dev);
 			} else if (ack > dev->send_seq && ack <= dev->unack_seq) {
 				printk(KERN_DEBUG
-				     "layer 2 ack unacceptable - dev %d",
+				       "layer 2 ack unacceptable - dev %d",
 				       dev->id);
 				pcbit_l2_error(dev);
 			}
diff --git a/drivers/isdn/pcbit/layer2.h b/drivers/isdn/pcbit/layer2.h
index 2ac295e..be1327b 100644
--- a/drivers/isdn/pcbit/layer2.h
+++ b/drivers/isdn/pcbit/layer2.h
@@ -2,17 +2,17 @@
  * PCBIT-D low-layer interface definitions
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
 /*
  * 19991203 - Fernando Carvalho - takion@superbofh.org
  * Hacked to compile with egcs and run with current version of isdn modules
-*/
+ */
 
 #ifndef LAYER2_H
 #define LAYER2_H
@@ -37,8 +37,8 @@
 
 /* TAM - XX - C - S  - NUM */
 #define PREHDR_LEN 8
-/* TT  - M  - I - TH - TD  */      
-#define FRAME_HDR_LEN  8   
+/* TT  - M  - I - TH - TD  */
+#define FRAME_HDR_LEN  8
 
 #define MSG_CONN_REQ		0x08000100
 #define MSG_CONN_CONF		0x00000101
@@ -84,21 +84,21 @@
 #define MSG_DEBUG_188           0x0000ff00
 
 /*
-   
-   long  4 3 2 1
-   Intel 1 2 3 4
+
+  long  4 3 2 1
+  Intel 1 2 3 4
 */
 
 #ifdef __LITTLE_ENDIAN
-#define SET_MSG_SCMD(msg, ch) 	(msg = (msg & 0xffffff00) | (((ch) & 0xff)))
-#define SET_MSG_CMD(msg, ch) 	(msg = (msg & 0xffff00ff) | (((ch) & 0xff) << 8))
-#define SET_MSG_PROC(msg, ch) 	(msg = (msg & 0xff00ffff) | (((ch) & 0xff) << 16))
-#define SET_MSG_CPU(msg, ch) 	(msg = (msg & 0x00ffffff) | (((ch) & 0xff) << 24))
+#define SET_MSG_SCMD(msg, ch)	(msg = (msg & 0xffffff00) | (((ch) & 0xff)))
+#define SET_MSG_CMD(msg, ch)	(msg = (msg & 0xffff00ff) | (((ch) & 0xff) << 8))
+#define SET_MSG_PROC(msg, ch)	(msg = (msg & 0xff00ffff) | (((ch) & 0xff) << 16))
+#define SET_MSG_CPU(msg, ch)	(msg = (msg & 0x00ffffff) | (((ch) & 0xff) << 24))
 
-#define GET_MSG_SCMD(msg) 	((msg) & 0xFF)
-#define GET_MSG_CMD(msg) 	((msg) >> 8 & 0xFF)
-#define GET_MSG_PROC(msg) 	((msg) >> 16 & 0xFF)
-#define GET_MSG_CPU(msg) 	((msg) >> 24)
+#define GET_MSG_SCMD(msg)	((msg) & 0xFF)
+#define GET_MSG_CMD(msg)	((msg) >> 8 & 0xFF)
+#define GET_MSG_PROC(msg)	((msg) >> 16 & 0xFF)
+#define GET_MSG_CPU(msg)	((msg) >> 24)
 
 #else
 #error "Non-Intel CPU"
@@ -109,60 +109,60 @@
 #define SCHED_READ    0x01
 #define SCHED_WRITE   0x02
 
-#define SET_RUN_TIMEOUT 2*HZ /* 2 seconds */
-     
+#define SET_RUN_TIMEOUT 2 * HZ /* 2 seconds */
+
 struct frame_buf {
-        ulong msg;
-        unsigned int refnum;
-        unsigned int dt_len;
-        unsigned int hdr_len;
-        struct sk_buff *skb;
+	ulong msg;
+	unsigned int refnum;
+	unsigned int dt_len;
+	unsigned int hdr_len;
+	struct sk_buff *skb;
 	unsigned int copied;
-        struct frame_buf * next;
+	struct frame_buf *next;
 };
 
-extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum, 
-                          struct sk_buff *skb, unsigned short hdr_len);
+extern int pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
+			  struct sk_buff *skb, unsigned short hdr_len);
 
 extern irqreturn_t pcbit_irq_handler(int interrupt, void *);
 
-extern struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
+extern struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS];
 
 #ifdef DEBUG
 static __inline__ void log_state(struct pcbit_dev *dev) {
-        printk(KERN_DEBUG "writeptr = %ld\n", 
+	printk(KERN_DEBUG "writeptr = %ld\n",
 	       (ulong) (dev->writeptr - dev->sh_mem));
-        printk(KERN_DEBUG "readptr  = %ld\n", 
+	printk(KERN_DEBUG "readptr  = %ld\n",
 	       (ulong) (dev->readptr - (dev->sh_mem + BANK2)));
-        printk(KERN_DEBUG "{rcv_seq=%01x, send_seq=%01x, unack_seq=%01x}\n", 
+	printk(KERN_DEBUG "{rcv_seq=%01x, send_seq=%01x, unack_seq=%01x}\n",
 	       dev->rcv_seq, dev->send_seq, dev->unack_seq);
 }
 #endif
 
-static __inline__ struct pcbit_dev * chan2dev(struct pcbit_chan * chan) 
+static __inline__ struct pcbit_dev *chan2dev(struct pcbit_chan *chan)
 {
-        struct pcbit_dev * dev;
-        int i;
+	struct pcbit_dev *dev;
+	int i;
 
 
-        for (i=0; i<MAX_PCBIT_CARDS; i++)
-                if ((dev=dev_pcbit[i]))
-                        if (dev->b1 == chan || dev->b2 == chan)
-                                return dev;
-        return NULL;
+	for (i = 0; i < MAX_PCBIT_CARDS; i++)
+		if ((dev = dev_pcbit[i]))
+			if (dev->b1 == chan || dev->b2 == chan)
+				return dev;
+	return NULL;
 
 }
 
-static __inline__ struct pcbit_dev * finddev(int id)
+static __inline__ struct pcbit_dev *finddev(int id)
 {
-  struct pcbit_dev * dev;
-  int i;
-
-  for (i=0; i<MAX_PCBIT_CARDS; i++)
-    if ((dev=dev_pcbit[i]))
-      if (dev->id == id)
-	return dev;
-  return NULL;
+	struct pcbit_dev *dev;
+	int i;
+
+	for (i = 0; i < MAX_PCBIT_CARDS; i++)
+		if ((dev = dev_pcbit[i]))
+			if (dev->id == id)
+				return dev;
+	return NULL;
 }
 
 
@@ -172,117 +172,110 @@ static __inline__ struct pcbit_dev * finddev(int id)
 
 static __inline__ void pcbit_writeb(struct pcbit_dev *dev, unsigned char dt)
 {
-  writeb(dt, dev->writeptr++);
-  if (dev->writeptr == dev->sh_mem + BANKLEN)
-    dev->writeptr = dev->sh_mem;
+	writeb(dt, dev->writeptr++);
+	if (dev->writeptr == dev->sh_mem + BANKLEN)
+		dev->writeptr = dev->sh_mem;
 }
 
 static __inline__ void pcbit_writew(struct pcbit_dev *dev, unsigned short dt)
 {
-  int dist;
-
-  dist = BANKLEN - (dev->writeptr - dev->sh_mem);
-  switch (dist) {
-  case 2:
-    writew(dt, dev->writeptr);
-    dev->writeptr = dev->sh_mem;
-    break;
-  case 1:
-    writeb((u_char) (dt & 0x00ffU), dev->writeptr);    
-    dev->writeptr = dev->sh_mem;
-    writeb((u_char) (dt >> 8), dev->writeptr++);    
-    break;
-  default:
-    writew(dt, dev->writeptr);
-    dev->writeptr += 2;
-    break;
-  };
+	int dist;
+
+	dist = BANKLEN - (dev->writeptr - dev->sh_mem);
+	switch (dist) {
+	case 2:
+		writew(dt, dev->writeptr);
+		dev->writeptr = dev->sh_mem;
+		break;
+	case 1:
+		writeb((u_char) (dt & 0x00ffU), dev->writeptr);
+		dev->writeptr = dev->sh_mem;
+		writeb((u_char) (dt >> 8), dev->writeptr++);
+		break;
+	default:
+		writew(dt, dev->writeptr);
+		dev->writeptr += 2;
+		break;
+	};
 }
 
-static __inline__ void memcpy_topcbit(struct pcbit_dev * dev, u_char * data, 
+static __inline__ void memcpy_topcbit(struct pcbit_dev *dev, u_char *data,
 				      int len)
 {
-  int diff;
-
-  diff = len - (BANKLEN - (dev->writeptr - dev->sh_mem) );
-
-  if (diff > 0)
-    {
-      memcpy_toio(dev->writeptr, data, len - diff);
-      memcpy_toio(dev->sh_mem, data + (len - diff), diff);
-      dev->writeptr = dev->sh_mem + diff;
-    }
-  else
-    {
-      memcpy_toio(dev->writeptr, data, len);
-
-      dev->writeptr += len;
-      if (diff == 0)
-	dev->writeptr = dev->sh_mem;
-    }
+	int diff;
+
+	diff = len - (BANKLEN - (dev->writeptr - dev->sh_mem));
+
+	if (diff > 0)
+	{
+		memcpy_toio(dev->writeptr, data, len - diff);
+		memcpy_toio(dev->sh_mem, data + (len - diff), diff);
+		dev->writeptr = dev->sh_mem + diff;
+	}
+	else
+	{
+		memcpy_toio(dev->writeptr, data, len);
+
+		dev->writeptr += len;
+		if (diff == 0)
+			dev->writeptr = dev->sh_mem;
+	}
 }
 
 static __inline__ unsigned char pcbit_readb(struct pcbit_dev *dev)
 {
-  unsigned char val;
+	unsigned char val;
 
-  val = readb(dev->readptr++);
-  if (dev->readptr == dev->sh_mem + BANK2 + BANKLEN)
-    dev->readptr = dev->sh_mem + BANK2;
+	val = readb(dev->readptr++);
+	if (dev->readptr == dev->sh_mem + BANK2 + BANKLEN)
+		dev->readptr = dev->sh_mem + BANK2;
 
-  return val;
+	return val;
 }
 
 static __inline__ unsigned short pcbit_readw(struct pcbit_dev *dev)
 {
-  int dist;
-  unsigned short val;
-
-  dist = BANKLEN - ( dev->readptr - (dev->sh_mem + BANK2 ) );
-  switch (dist) {
-  case 2:
-    val = readw(dev->readptr);
-    dev->readptr = dev->sh_mem + BANK2;
-    break;
-  case 1:
-    val = readb(dev->readptr);
-    dev->readptr = dev->sh_mem + BANK2;
-    val = (readb(dev->readptr++) << 8) | val;
-    break;
-  default:
-    val = readw(dev->readptr);
-    dev->readptr += 2;
-    break;
-  };
-  return val;
+	int dist;
+	unsigned short val;
+
+	dist = BANKLEN - (dev->readptr - (dev->sh_mem + BANK2));
+	switch (dist) {
+	case 2:
+		val = readw(dev->readptr);
+		dev->readptr = dev->sh_mem + BANK2;
+		break;
+	case 1:
+		val = readb(dev->readptr);
+		dev->readptr = dev->sh_mem + BANK2;
+		val = (readb(dev->readptr++) << 8) | val;
+		break;
+	default:
+		val = readw(dev->readptr);
+		dev->readptr += 2;
+		break;
+	};
+	return val;
 }
 
-static __inline__ void memcpy_frompcbit(struct pcbit_dev * dev, u_char * data, int len)
+static __inline__ void memcpy_frompcbit(struct pcbit_dev *dev, u_char *data, int len)
 {
-  int diff;
-
-  diff = len - (BANKLEN - (dev->readptr - (dev->sh_mem + BANK2) ) ); 
-  if (diff > 0)
-    {
-      memcpy_fromio(data, dev->readptr, len - diff);
-      memcpy_fromio(data + (len - diff), dev->sh_mem + BANK2 , diff);
-      dev->readptr = dev->sh_mem + BANK2 + diff;
-    }
-  else
-    {
-      memcpy_fromio(data, dev->readptr, len);
-      dev->readptr += len;
-      if (diff == 0)
-	dev->readptr = dev->sh_mem + BANK2;
-    }
+	int diff;
+
+	diff = len - (BANKLEN - (dev->readptr - (dev->sh_mem + BANK2)));
+	if (diff > 0)
+	{
+		memcpy_fromio(data, dev->readptr, len - diff);
+		memcpy_fromio(data + (len - diff), dev->sh_mem + BANK2 , diff);
+		dev->readptr = dev->sh_mem + BANK2 + diff;
+	}
+	else
+	{
+		memcpy_fromio(data, dev->readptr, len);
+		dev->readptr += len;
+		if (diff == 0)
+			dev->readptr = dev->sh_mem + BANK2;
+	}
 }
 
 
 #endif
-
-
-
-
-
-
-
diff --git a/drivers/isdn/pcbit/module.c b/drivers/isdn/pcbit/module.c
index 04ea241..0a59bd0 100644
--- a/drivers/isdn/pcbit/module.c
+++ b/drivers/isdn/pcbit/module.c
@@ -2,10 +2,10 @@
  * PCBIT-D module support
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -29,7 +29,7 @@ module_param_array(mem, int, NULL, 0);
 module_param_array(irq, int, NULL, 0);
 
 static int num_boards;
-struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
+struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS];
 
 static int __init pcbit_init(void)
 {
@@ -37,26 +37,26 @@ static int __init pcbit_init(void)
 
 	num_boards = 0;
 
-	printk(KERN_NOTICE 
+	printk(KERN_NOTICE
 	       "PCBIT-D device driver v 0.5-fjpc0 19991204 - "
 	       "Copyright (C) 1996 Universidade de Lisboa\n");
 
-	if (mem[0] || irq[0]) 
+	if (mem[0] || irq[0])
 	{
-		for (board=0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++)
+		for (board = 0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++)
 		{
 			if (!mem[board])
 				mem[board] = 0xD0000;
 			if (!irq[board])
 				irq[board] = 5;
-			
+
 			if (pcbit_init_dev(board, mem[board], irq[board]) == 0)
 				num_boards++;
-		
-			else 
+
+			else
 			{
-				printk(KERN_WARNING 
-				       "pcbit_init failed for dev %d", 
+				printk(KERN_WARNING
+				       "pcbit_init failed for dev %d",
 				       board + 1);
 				return -EIO;
 			}
@@ -67,7 +67,7 @@ static int __init pcbit_init(void)
 
 	if (!num_boards)
 	{
-		printk(KERN_INFO 
+		printk(KERN_INFO
 		       "Trying to detect board using default settings\n");
 		if (pcbit_init_dev(0, 0xD0000, 5) == 0)
 			num_boards++;
@@ -84,7 +84,7 @@ static void __exit pcbit_exit(void)
 
 	for (board = 0; board < num_boards; board++)
 		pcbit_terminate(board);
-	printk(KERN_NOTICE 
+	printk(KERN_NOTICE
 	       "PCBIT-D module unloaded\n");
 #endif
 }
@@ -95,20 +95,20 @@ static int __init pcbit_setup(char *line)
 {
 	int i, j, argc;
 	char *str;
-	int ints[MAX_PARA+1];
+	int ints[MAX_PARA + 1];
 
 	str = get_options(line, MAX_PARA, ints);
 	argc = ints[0];
 	i = 0;
 	j = 1;
 
-	while (argc && (i<MAX_PCBIT_CARDS)) {
+	while (argc && (i < MAX_PCBIT_CARDS)) {
 
 		if (argc) {
 			mem[i]	= ints[j];
 			j++; argc--;
 		}
-		
+
 		if (argc) {
 			irq[i]	= ints[j];
 			j++; argc--;
@@ -116,11 +116,10 @@ static int __init pcbit_setup(char *line)
 
 		i++;
 	}
-	return(1);
+	return (1);
 }
 __setup("pcbit=", pcbit_setup);
 #endif
 
 module_init(pcbit_init);
 module_exit(pcbit_exit);
-
diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h
index d76fffc..0a5a994 100644
--- a/drivers/isdn/pcbit/pcbit.h
+++ b/drivers/isdn/pcbit/pcbit.h
@@ -2,10 +2,10 @@
  * PCBIT-D device driver definitions
  *
  * Copyright (C) 1996 Universidade de Lisboa
- * 
+ *
  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
- * This software may be used and distributed according to the terms of 
+ * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
  */
 
@@ -32,14 +32,14 @@ struct pcbit_chan {
 	unsigned short r_refnum;
 	unsigned short fsm_state;
 	struct timer_list fsm_timer;
-#ifdef  BLOCK_TIMER
+#ifdef BLOCK_TIMER
 	struct timer_list block_timer;
 #endif
 };
 
 struct msn_entry {
 	char *msn;
-	struct msn_entry * next;
+	struct msn_entry *next;
 };
 
 struct pcbit_dev {
@@ -49,15 +49,15 @@ struct pcbit_dev {
 	unsigned long ph_mem;
 	unsigned int irq;
 	unsigned int id;
-	unsigned int interrupt;			/* set during interrupt 
+	unsigned int interrupt;			/* set during interrupt
 						   processing */
 	spinlock_t lock;
 	/* isdn4linux */
 
-	struct msn_entry * msn_list;		/* ISDN address list */
-	
-	isdn_if * dev_if;
-	
+	struct msn_entry *msn_list;		/* ISDN address list */
+
+	isdn_if *dev_if;
+
 	ushort ll_hdrlen;
 	ushort hl_hdrlen;
 
@@ -89,17 +89,17 @@ struct pcbit_dev {
 	unsigned char send_seq;
 	unsigned char rcv_seq;
 	unsigned char unack_seq;
-  
+
 	unsigned short free;
 
 	/* channels */
 
 	struct pcbit_chan *b1;
-	struct pcbit_chan *b2;  
+	struct pcbit_chan *b2;
 };
 
-#define STATS_TIMER (10*HZ)
-#define ERRTIME     (HZ/10)
+#define STATS_TIMER (10 * HZ)
+#define ERRTIME     (HZ / 10)
 
 /* MRU */
 #define MAXBUFSIZE  1534
@@ -107,7 +107,7 @@ struct pcbit_dev {
 
 #define STATBUF_LEN 2048
 /*
- * 
+ *
  */
 
 #endif /* __KERNEL__ */
@@ -169,9 +169,9 @@ struct pcbit_ioctl {
 void pcbit_deliver(struct work_struct *work);
 int pcbit_init_dev(int board, int mem_base, int irq);
 void pcbit_terminate(int board);
-void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg, struct sk_buff * skb,
+void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, struct sk_buff *skb,
 		      ushort hdr_len, ushort refnum);
-void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan,
+void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan,
 			unsigned short i, unsigned short ev, unsigned short f);
 
 #endif
diff --git a/drivers/isdn/sc/card.h b/drivers/isdn/sc/card.h
index 0120bcf..3da69ee 100644
--- a/drivers/isdn/sc/card.h
+++ b/drivers/isdn/sc/card.h
@@ -118,7 +118,7 @@ int send_and_receive(int card, unsigned int procid, unsigned char type,
 		     unsigned char class, unsigned char code,
 		     unsigned char link, unsigned char data_len,
 		     unsigned char *data,  RspMessage *mesgdata, int timeout);
-void flushreadfifo (int card);
+void flushreadfifo(int card);
 int sendmessage(int card, unsigned int procid, unsigned int type,
 		unsigned int class, unsigned int code, unsigned int link,
 		unsigned int data_len, unsigned int *data);
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index 0e4969c..4a4e661 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -69,14 +69,14 @@ int get_card_from_id(int driver)
 {
 	int i;
 
-	for(i = 0 ; i < cinst ; i++) {
-		if(sc_adapter[i]->driverId == driver)
+	for (i = 0; i < cinst; i++) {
+		if (sc_adapter[i]->driverId == driver)
 			return i;
 	}
 	return -ENODEV;
 }
 
-/* 
+/*
  * command
  */
 
@@ -85,7 +85,7 @@ int command(isdn_ctrl *cmd)
 	int card;
 
 	card = get_card_from_id(cmd->driver);
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
@@ -93,17 +93,17 @@ int command(isdn_ctrl *cmd)
 	/*
 	 * Dispatch the command
 	 */
-	switch(cmd->command) {
+	switch (cmd->command) {
 	case ISDN_CMD_IOCTL:
 	{
-		unsigned long 	cmdptr;
+		unsigned long	cmdptr;
 		scs_ioctl	ioc;
 
 		memcpy(&cmdptr, cmd->parm.num, sizeof(unsigned long));
 		if (copy_from_user(&ioc, (scs_ioctl __user *)cmdptr,
 				   sizeof(scs_ioctl))) {
 			pr_debug("%s: Failed to verify user space 0x%lx\n",
-				sc_adapter[card]->devicename, cmdptr);
+				 sc_adapter[card]->devicename, cmdptr);
 			return -EFAULT;
 		}
 		return sc_ioctl(card, &ioc);
@@ -133,76 +133,76 @@ int command(isdn_ctrl *cmd)
 /*
  * start the onboard firmware
  */
-int startproc(int card) 
+int startproc(int card)
 {
 	int status;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
 	/*
-	 * send start msg 
+	 * send start msg
 	 */
-       	status = sendmessage(card, CMPID,cmReqType2,
-			  cmReqClass0,
-			  cmReqStartProc,
-			  0,0,NULL);
+	status = sendmessage(card, CMPID, cmReqType2,
+			     cmReqClass0,
+			     cmReqStartProc,
+			     0, 0, NULL);
 	pr_debug("%s: Sent startProc\n", sc_adapter[card]->devicename);
-	
+
 	return status;
 }
 
 
 /*
- * Dials the number passed in 
+ * Dials the number passed in
  */
 static int dial(int card, unsigned long channel, setup_parm setup)
 {
 	int status;
 	char Phone[48];
-  
-	if(!IS_VALID_CARD(card)) {
+
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
-	/*extract ISDN number to dial from eaz/msn string*/ 
-	strcpy(Phone,setup.phone); 
+	/*extract ISDN number to dial from eaz/msn string*/
+	strcpy(Phone, setup.phone);
 
 	/*send the connection message*/
-	status = sendmessage(card, CEPID,ceReqTypePhy,
-				ceReqClass1,
-				ceReqPhyConnect,
-				(unsigned char) channel+1, 
-				strlen(Phone),
-				(unsigned int *) Phone);
+	status = sendmessage(card, CEPID, ceReqTypePhy,
+			     ceReqClass1,
+			     ceReqPhyConnect,
+			     (unsigned char)channel + 1,
+			     strlen(Phone),
+			     (unsigned int *)Phone);
 
 	pr_debug("%s: Dialing %s on channel %lu\n",
-		sc_adapter[card]->devicename, Phone, channel+1);
-	
+		 sc_adapter[card]->devicename, Phone, channel + 1);
+
 	return status;
 }
 
 /*
- * Answer an incoming call 
+ * Answer an incoming call
  */
 static int answer(int card, unsigned long channel)
 {
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
-	if(setup_buffers(card, channel+1)) {
-		hangup(card, channel+1);
+	if (setup_buffers(card, channel + 1)) {
+		hangup(card, channel + 1);
 		return -ENOBUFS;
 	}
 
-	indicate_status(card, ISDN_STAT_BCONN,channel,NULL);
+	indicate_status(card, ISDN_STAT_BCONN, channel, NULL);
 	pr_debug("%s: Answered incoming call on channel %lu\n",
-		sc_adapter[card]->devicename, channel+1);
+		 sc_adapter[card]->devicename, channel + 1);
 	return 0;
 }
 
@@ -213,19 +213,19 @@ static int hangup(int card, unsigned long channel)
 {
 	int status;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
 	status = sendmessage(card, CEPID, ceReqTypePhy,
-						 ceReqClass1,
-						 ceReqPhyDisconnect,
-						 (unsigned char) channel+1,
-						 0,
-						 NULL);
+			     ceReqClass1,
+			     ceReqPhyDisconnect,
+			     (unsigned char)channel + 1,
+			     0,
+			     NULL);
 	pr_debug("%s: Sent HANGUP message to channel %lu\n",
-		sc_adapter[card]->devicename, channel+1);
+		 sc_adapter[card]->devicename, channel + 1);
 	return status;
 }
 
@@ -234,10 +234,10 @@ static int hangup(int card, unsigned long channel)
  */
 static int setl2(int card, unsigned long arg)
 {
-	int status =0;
-	int protocol,channel;
+	int status = 0;
+	int protocol, channel;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
@@ -249,14 +249,14 @@ static int setl2(int card, unsigned long arg)
 	 * check that the adapter is also set to the correct protocol
 	 */
 	pr_debug("%s: Sending GetFrameFormat for channel %d\n",
-		sc_adapter[card]->devicename, channel+1);
+		 sc_adapter[card]->devicename, channel + 1);
 	status = sendmessage(card, CEPID, ceReqTypeCall,
- 				ceReqClass0,
- 				ceReqCallGetFrameFormat,
- 				(unsigned char)channel+1,
- 				1,
- 				(unsigned int *) protocol);
-	if(status) 
+			     ceReqClass0,
+			     ceReqCallGetFrameFormat,
+			     (unsigned char)channel + 1,
+			     1,
+			     (unsigned int *)protocol);
+	if (status)
 		return status;
 	return 0;
 }
@@ -268,7 +268,7 @@ static int setl3(int card, unsigned long channel)
 {
 	int protocol = channel >> 8;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
@@ -279,26 +279,26 @@ static int setl3(int card, unsigned long channel)
 
 static int acceptb(int card, unsigned long channel)
 {
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
-	if(setup_buffers(card, channel+1))
+	if (setup_buffers(card, channel + 1))
 	{
-		hangup(card, channel+1);
+		hangup(card, channel + 1);
 		return -ENOBUFS;
 	}
 
 	pr_debug("%s: B-Channel connection accepted on channel %lu\n",
-		sc_adapter[card]->devicename, channel+1);
+		 sc_adapter[card]->devicename, channel + 1);
 	indicate_status(card, ISDN_STAT_BCONN, channel, NULL);
 	return 0;
 }
 
 static int clreaz(int card, unsigned long arg)
 {
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
@@ -306,13 +306,13 @@ static int clreaz(int card, unsigned long arg)
 	strcpy(sc_adapter[card]->channel[arg].eazlist, "");
 	sc_adapter[card]->channel[arg].eazclear = 1;
 	pr_debug("%s: EAZ List cleared for channel %lu\n",
-		sc_adapter[card]->devicename, arg+1);
+		 sc_adapter[card]->devicename, arg + 1);
 	return 0;
 }
 
 static int seteaz(int card, unsigned long arg, char *num)
 {
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
@@ -320,8 +320,8 @@ static int seteaz(int card, unsigned long arg, char *num)
 	strcpy(sc_adapter[card]->channel[arg].eazlist, num);
 	sc_adapter[card]->channel[arg].eazclear = 0;
 	pr_debug("%s: EAZ list for channel %lu set to: %s\n",
-		sc_adapter[card]->devicename, arg+1,
-		sc_adapter[card]->channel[arg].eazlist);
+		 sc_adapter[card]->devicename, arg + 1,
+		 sc_adapter[card]->channel[arg].eazlist);
 	return 0;
 }
 
@@ -329,14 +329,14 @@ int reset(int card)
 {
 	unsigned long flags;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
 	indicate_status(card, ISDN_STAT_STOP, 0, NULL);
 
-	if(sc_adapter[card]->EngineUp) {
+	if (sc_adapter[card]->EngineUp) {
 		del_timer(&sc_adapter[card]->stat_timer);
 	}
 
@@ -350,14 +350,14 @@ int reset(int card)
 	add_timer(&sc_adapter[card]->reset_timer);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 
-	outb(0x1,sc_adapter[card]->ioport[SFT_RESET]);
+	outb(0x1, sc_adapter[card]->ioport[SFT_RESET]);
 
 	pr_debug("%s: Adapter Reset\n", sc_adapter[card]->devicename);
 	return 0;
 }
 
-void flushreadfifo (int card)
+void flushreadfifo(int card)
 {
-	while(inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA)
+	while (inb(sc_adapter[card]->ioport[FIFO_STATUS]) & RF_HAS_DATA)
 		inb(sc_adapter[card]->ioport[FIFO_READ]);
 }
diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c
index 498f403..717003a 100644
--- a/drivers/isdn/sc/event.c
+++ b/drivers/isdn/sc/event.c
@@ -38,26 +38,26 @@ static char *events[] = { "ISDN_STAT_STAVAIL",
 			  "ISDN_STAT_CAUSE" };
 #endif
 
-int indicate_status(int card, int event,ulong Channel,char *Data)
+int indicate_status(int card, int event, ulong Channel, char *Data)
 {
 	isdn_ctrl cmd;
 
 #ifdef DEBUG
 	pr_debug("%s: Indicating event %s on Channel %d\n",
-		sc_adapter[card]->devicename, events[event-256], Channel);
+		 sc_adapter[card]->devicename, events[event - 256], Channel);
 #endif
-	if (Data != NULL){
+	if (Data != NULL) {
 		pr_debug("%s: Event data: %s\n", sc_adapter[card]->devicename,
-			Data);
+			 Data);
 		switch (event) {
-			case ISDN_STAT_BSENT:
-				memcpy(&cmd.parm.length, Data, sizeof(cmd.parm.length));
-				break;
-			case ISDN_STAT_ICALL:
-				memcpy(&cmd.parm.setup, Data, sizeof(cmd.parm.setup));
-				break;
-			default:
-				strcpy(cmd.parm.num, Data);
+		case ISDN_STAT_BSENT:
+			memcpy(&cmd.parm.length, Data, sizeof(cmd.parm.length));
+			break;
+		case ISDN_STAT_ICALL:
+			memcpy(&cmd.parm.setup, Data, sizeof(cmd.parm.setup));
+			break;
+		default:
+			strcpy(cmd.parm.num, Data);
 		}
 	}
 
diff --git a/drivers/isdn/sc/hardware.h b/drivers/isdn/sc/hardware.h
index 6273248..81fbe78 100644
--- a/drivers/isdn/sc/hardware.h
+++ b/drivers/isdn/sc/hardware.h
@@ -105,6 +105,6 @@
  */
 
 /* Determine if a channel number is valid for the adapter */
-#define IS_VALID_CHANNEL(y,x)	((x>0) && (x <= sc_adapter[y]->channels))
+#define IS_VALID_CHANNEL(y, x)	((x > 0) && (x <= sc_adapter[y]->channels))
 
 #endif
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 023de78..6b580b2 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -27,9 +27,9 @@ static const char version[] = "2.0b1";
 static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
 
 /* insmod set parameters */
-static unsigned int io[] = {0,0,0,0};
-static unsigned char irq[] = {0,0,0,0};
-static unsigned long ram[] = {0,0,0,0};
+static unsigned int io[] = {0, 0, 0, 0};
+static unsigned char irq[] = {0, 0, 0, 0};
+static unsigned long ram[] = {0, 0, 0, 0};
 static bool do_reset = 0;
 
 module_param_array(io, int, NULL, 0);
@@ -62,7 +62,7 @@ static int __init sc_init(void)
 #endif
 	pr_info("Copyright (C) 1996 SpellCaster Telecommunications Inc.\n");
 
-	while(b++ < MAX_CARDS - 1) {
+	while (b++ < MAX_CARDS - 1) {
 		pr_debug("Probing for adapter #%d\n", b);
 		/*
 		 * Initialize reusable variables
@@ -72,17 +72,17 @@ static int __init sc_init(void)
 		channels = 0;
 		pgport = 0;
 
-		/* 
-		 * See if we should probe for IO base 
+		/*
+		 * See if we should probe for IO base
 		 */
 		pr_debug("I/O Base for board %d is 0x%x, %s probe\n", b, io[b],
-			io[b] == 0 ? "will" : "won't");
-		if(io[b]) {
+			 io[b] == 0 ? "will" : "won't");
+		if (io[b]) {
 			/*
 			 * No, I/O Base has been provided
 			 */
-			for (i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
-				if(!request_region(io[b] + i * 0x400, 1, "sc test")) {
+			for (i = 0; i < MAX_IO_REGS - 1; i++) {
+				if (!request_region(io[b] + i * 0x400, 1, "sc test")) {
 					pr_debug("request_region for 0x%x failed\n", io[b] + i * 0x400);
 					io[b] = 0;
 					break;
@@ -93,13 +93,13 @@ static int __init sc_init(void)
 			/*
 			 * Confirm the I/O Address with a test
 			 */
-			if(io[b] == 0) {
+			if (io[b] == 0) {
 				pr_debug("I/O Address invalid.\n");
 				continue;
 			}
 
 			outb(0x18, io[b] + 0x400 * EXP_PAGE0);
-			if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
+			if (inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
 				pr_debug("I/O Base 0x%x fails test\n",
 					 io[b] + 0x400 * EXP_PAGE0);
 				continue;
@@ -109,12 +109,12 @@ static int __init sc_init(void)
 			/*
 			 * Yes, probe for I/O Base
 			 */
-			if(probe_exhasted) {
+			if (probe_exhasted) {
 				pr_debug("All probe addresses exhasted, skipping\n");
 				continue;
 			}
 			pr_debug("Probing for I/O...\n");
-			for (i = last_base ; i <= IOBASE_MAX ; i += IOBASE_OFFSET) {
+			for (i = last_base; i <= IOBASE_MAX; i += IOBASE_OFFSET) {
 				int found_io = 1;
 				if (i == IOBASE_MAX) {
 					probe_exhasted = 1; /* No more addresses to probe */
@@ -122,19 +122,19 @@ static int __init sc_init(void)
 				}
 				last_base = i + IOBASE_OFFSET;
 				pr_debug("  checking 0x%x...", i);
-				for ( j = 0 ; j < MAX_IO_REGS - 1 ; j++) {
-					if(!request_region(i + j * 0x400, 1, "sc test")) {
+				for (j = 0; j < MAX_IO_REGS - 1; j++) {
+					if (!request_region(i + j * 0x400, 1, "sc test")) {
 						pr_debug("Failed\n");
 						found_io = 0;
 						break;
 					} else
 						release_region(i + j * 0x400, 1);
-				}	
+				}
 
-				if(found_io) {
+				if (found_io) {
 					io[b] = i;
 					outb(0x18, io[b] + 0x400 * EXP_PAGE0);
-					if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) { 
+					if (inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
 						pr_debug("Failed by test\n");
 						continue;
 					}
@@ -142,7 +142,7 @@ static int __init sc_init(void)
 					break;
 				}
 			}
-			if(probe_exhasted) {
+			if (probe_exhasted) {
 				continue;
 			}
 		}
@@ -150,23 +150,23 @@ static int __init sc_init(void)
 		/*
 		 * See if we should probe for shared RAM
 		 */
-		if(do_reset) {
+		if (do_reset) {
 			pr_debug("Doing a SAFE probe reset\n");
 			outb(0xFF, io[b] + RESET_OFFSET);
 			msleep_interruptible(10000);
 		}
 		pr_debug("RAM Base for board %d is 0x%lx, %s probe\n", b,
-			ram[b], ram[b] == 0 ? "will" : "won't");
+			 ram[b], ram[b] == 0 ? "will" : "won't");
 
-		if(ram[b]) {
+		if (ram[b]) {
 			/*
 			 * No, the RAM base has been provided
 			 * Just look for a signature and ID the
 			 * board model
 			 */
-			if(request_region(ram[b], SRAM_PAGESIZE, "sc test")) {
+			if (request_region(ram[b], SRAM_PAGESIZE, "sc test")) {
 				pr_debug("request_region for RAM base 0x%lx succeeded\n", ram[b]);
-			 	model = identify_board(ram[b], io[b]);
+				model = identify_board(ram[b], io[b]);
 				release_region(ram[b], SRAM_PAGESIZE);
 			}
 		}
@@ -175,15 +175,15 @@ static int __init sc_init(void)
 			 * Yes, probe for free RAM and look for
 			 * a signature and id the board model
 			 */
-			for (i = SRAM_MIN ; i < SRAM_MAX ; i += SRAM_PAGESIZE) {
+			for (i = SRAM_MIN; i < SRAM_MAX; i += SRAM_PAGESIZE) {
 				pr_debug("Checking RAM address 0x%x...\n", i);
-				if(request_region(i, SRAM_PAGESIZE, "sc test")) {
+				if (request_region(i, SRAM_PAGESIZE, "sc test")) {
 					pr_debug("  request_region succeeded\n");
 					model = identify_board(i, io[b]);
 					release_region(i, SRAM_PAGESIZE);
 					if (model >= 0) {
 						pr_debug("  Identified a %s\n",
-							boardname[model]);
+							 boardname[model]);
 						ram[b] = i;
 						break;
 					}
@@ -196,19 +196,19 @@ static int __init sc_init(void)
 		/*
 		 * See if we found free RAM and the board model
 		 */
-		if(!ram[b] || model < 0) {
+		if (!ram[b] || model < 0) {
 			/*
 			 * Nope, there was no place in RAM for the
 			 * board, or it couldn't be identified
 			 */
-			 pr_debug("Failed to find an adapter at 0x%lx\n", ram[b]);
-			 continue;
+			pr_debug("Failed to find an adapter at 0x%lx\n", ram[b]);
+			continue;
 		}
 
 		/*
 		 * Set the board's magic number, memory size and page register
 		 */
-		switch(model) {
+		switch (model) {
 		case PRI_BOARD:
 			channels = 23;
 			magic = 0x20000;
@@ -224,7 +224,7 @@ static int __init sc_init(void)
 			features = BRI_FEATURES;
 			break;
 		}
-		switch(ram[b] >> 12 & 0x0F) {
+		switch (ram[b] >> 12 & 0x0F) {
 		case 0x0:
 			pr_debug("RAM Page register set to EXP_PAGE0\n");
 			pgport = EXP_PAGE0;
@@ -250,12 +250,12 @@ static int __init sc_init(void)
 			continue;
 		}
 
-		pr_debug("current IRQ: %d  b: %d\n",irq[b],b);
+		pr_debug("current IRQ: %d  b: %d\n", irq[b], b);
 
 		/*
 		 * Make sure we got an IRQ
 		 */
-		if(!irq[b]) {
+		if (!irq[b]) {
 			/*
 			 * No interrupt could be used
 			 */
@@ -299,7 +299,7 @@ static int __init sc_init(void)
 		}
 		spin_lock_init(&sc_adapter[cinst]->lock);
 
-		if(!register_isdn(interface)) {
+		if (!register_isdn(interface)) {
 			/*
 			 * Oops, couldn't register for some reason
 			 */
@@ -344,30 +344,30 @@ static int __init sc_init(void)
 			kfree(interface);
 			kfree(sc_adapter[cinst]);
 			continue;
-			
+
 		}
 		sc_adapter[cinst]->iobase = io[b];
-		for(i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
+		for (i = 0; i < MAX_IO_REGS - 1; i++) {
 			sc_adapter[cinst]->ioport[i] = io[b] + i * 0x400;
 			request_region(sc_adapter[cinst]->ioport[i], 1,
-					interface->id);
+				       interface->id);
 			pr_debug("Requesting I/O Port %#x\n",
-				sc_adapter[cinst]->ioport[i]);
+				 sc_adapter[cinst]->ioport[i]);
 		}
 		sc_adapter[cinst]->ioport[IRQ_SELECT] = io[b] + 0x2;
 		request_region(sc_adapter[cinst]->ioport[IRQ_SELECT], 1,
-				interface->id);
+			       interface->id);
 		pr_debug("Requesting I/O Port %#x\n",
-				sc_adapter[cinst]->ioport[IRQ_SELECT]);
+			 sc_adapter[cinst]->ioport[IRQ_SELECT]);
 		sc_adapter[cinst]->rambase = ram[b];
 		request_region(sc_adapter[cinst]->rambase, SRAM_PAGESIZE,
-				interface->id);
+			       interface->id);
 
-		pr_info("  %s (%d) - %s %d channels IRQ %d, I/O Base 0x%x, RAM Base 0x%lx\n", 
+		pr_info("  %s (%d) - %s %d channels IRQ %d, I/O Base 0x%x, RAM Base 0x%lx\n",
 			sc_adapter[cinst]->devicename,
 			sc_adapter[cinst]->driverId,
 			boardname[model], channels, irq[b], io[b], ram[b]);
-		
+
 		/*
 		 * reset the adapter to put things in motion
 		 */
@@ -376,7 +376,7 @@ static int __init sc_init(void)
 		cinst++;
 		status = 0;
 	}
-	if (status) 
+	if (status)
 		pr_info("Failed to find any adapters, driver unloaded\n");
 	return status;
 }
@@ -385,7 +385,7 @@ static void __exit sc_exit(void)
 {
 	int i, j;
 
-	for(i = 0 ; i < cinst ; i++) {
+	for (i = 0; i < cinst; i++) {
 		pr_debug("Cleaning up after adapter %d\n", i);
 		/*
 		 * kill the timers
@@ -417,14 +417,14 @@ static void __exit sc_exit(void)
 		/*
 		 * Release the I/O Port regions
 		 */
-		for(j = 0 ; j < MAX_IO_REGS - 1; j++) {
+		for (j = 0; j < MAX_IO_REGS - 1; j++) {
 			release_region(sc_adapter[i]->ioport[j], 1);
 			pr_debug("Releasing I/O Port %#x\n",
-				sc_adapter[i]->ioport[j]);
+				 sc_adapter[i]->ioport[j]);
 		}
 		release_region(sc_adapter[i]->ioport[IRQ_SELECT], 1);
 		pr_debug("Releasing I/O Port %#x\n",
-			sc_adapter[i]->ioport[IRQ_SELECT]);
+			 sc_adapter[i]->ioport[IRQ_SELECT]);
 
 		/*
 		 * Release any memory we alloced
@@ -447,19 +447,19 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
 	int x;
 
 	pr_debug("Attempting to identify adapter @ 0x%lx io 0x%x\n",
-		rambase, iobase);
+		 rambase, iobase);
 
 	/*
 	 * Enable the base pointer
 	 */
 	outb(rambase >> 12, iobase + 0x2c00);
 
-	switch(rambase >> 12 & 0x0F) {
+	switch (rambase >> 12 & 0x0F) {
 	case 0x0:
 		pgport = iobase + PG0_OFFSET;
 		pr_debug("Page Register offset is 0x%x\n", PG0_OFFSET);
 		break;
-		
+
 	case 0x4:
 		pgport = iobase + PG1_OFFSET;
 		pr_debug("Page Register offset is 0x%x\n", PG1_OFFSET);
@@ -486,7 +486,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
 	msleep_interruptible(1000);
 	sig = readl(rambase + SIG_OFFSET);
 	pr_debug("Looking for a signature, got 0x%lx\n", sig);
-	if(sig == SIGNATURE)
+	if (sig == SIGNATURE)
 		return PRI_BOARD;
 
 	/*
@@ -496,7 +496,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
 	msleep_interruptible(1000);
 	sig = readl(rambase + SIG_OFFSET);
 	pr_debug("Looking for a signature, got 0x%lx\n", sig);
-	if(sig == SIGNATURE)
+	if (sig == SIGNATURE)
 		return BRI_BOARD;
 
 	return -1;
@@ -506,7 +506,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
 	 */
 	sig = readl(rambase + SIG_OFFSET);
 	pr_debug("Looking for a signature, got 0x%lx\n", sig);
-	if(sig != SIGNATURE)
+	if (sig != SIGNATURE)
 		return -1;
 
 	dpm = (DualPortMemory *) rambase;
@@ -523,11 +523,11 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
 	 * Wait for the response
 	 */
 	x = 0;
-	while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
+	while ((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
 		schedule_timeout_interruptible(1);
 		x++;
 	}
-	if(x == 100) {
+	if (x == 100) {
 		pr_debug("Timeout waiting for response\n");
 		return -1;
 	}
@@ -540,11 +540,11 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
 		 hwci.st_u_sense ? "S/T" : "U", hwci.ram_size,
 		 hwci.serial_no, hwci.part_no, hwci.rev_no);
 
-	if(!strncmp(PRI_PARTNO, hwci.part_no, 6))
+	if (!strncmp(PRI_PARTNO, hwci.part_no, 6))
 		return PRI_BOARD;
-	if(!strncmp(BRI_PARTNO, hwci.part_no, 6))
+	if (!strncmp(BRI_PARTNO, hwci.part_no, 6))
 		return BRI_BOARD;
-		
+
 	return -1;
 }
 
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c
index f0225bc..e80cc76 100644
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -22,7 +22,7 @@
 #include <linux/interrupt.h>
 
 /*
- * 
+ *
  */
 irqreturn_t interrupt_handler(int dummy, void *card_inst)
 {
@@ -31,15 +31,15 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 	int channel;
 	int card = (int)(unsigned long) card_inst;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return IRQ_NONE;
 	}
 
 	pr_debug("%s: Entered Interrupt handler\n",
-			sc_adapter[card]->devicename);
-	
- 	/*
+		 sc_adapter[card]->devicename);
+
+	/*
 	 * Pull all of the waiting messages off the response queue
 	 */
 	while (!receivemessage(card, &rcvmsg)) {
@@ -47,31 +47,31 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 		 * Push the message to the adapter structure for
 		 * send_and_receive to snoop
 		 */
-		if(sc_adapter[card]->want_async_messages)
+		if (sc_adapter[card]->want_async_messages)
 			memcpy(&(sc_adapter[card]->async_msg),
-					&rcvmsg, sizeof(RspMessage));
+			       &rcvmsg, sizeof(RspMessage));
 
 		channel = (unsigned int) rcvmsg.phy_link_no;
-		
+
 		/*
 		 * Trap Invalid request messages
 		 */
-		if(IS_CM_MESSAGE(rcvmsg, 0, 0, Invalid)) {
-			pr_debug("%s: Invalid request Message, rsp_status = %d\n", 
-				sc_adapter[card]->devicename,
-				rcvmsg.rsp_status);
-			break;	
+		if (IS_CM_MESSAGE(rcvmsg, 0, 0, Invalid)) {
+			pr_debug("%s: Invalid request Message, rsp_status = %d\n",
+				 sc_adapter[card]->devicename,
+				 rcvmsg.rsp_status);
+			break;
 		}
-		
+
 		/*
 		 * Check for a linkRead message
 		 */
 		if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Read))
 		{
 			pr_debug("%s: Received packet 0x%x bytes long at 0x%lx\n",
-						sc_adapter[card]->devicename,
-						rcvmsg.msg_data.response.msg_len,
-						rcvmsg.msg_data.response.buff_offset);
+				 sc_adapter[card]->devicename,
+				 rcvmsg.msg_data.response.msg_len,
+				 rcvmsg.msg_data.response.buff_offset);
 			rcvpkt(card, &rcvmsg);
 			continue;
 
@@ -80,49 +80,49 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 		/*
 		 * Handle a write acknoledgement
 		 */
-		if(IS_CE_MESSAGE(rcvmsg, Lnk, 1, Write)) {
+		if (IS_CE_MESSAGE(rcvmsg, Lnk, 1, Write)) {
 			pr_debug("%s: Packet Send ACK on channel %d\n",
-				sc_adapter[card]->devicename,
-				rcvmsg.phy_link_no);
-			sc_adapter[card]->channel[rcvmsg.phy_link_no-1].free_sendbufs++;
+				 sc_adapter[card]->devicename,
+				 rcvmsg.phy_link_no);
+			sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].free_sendbufs++;
 			continue;
 		}
 
 		/*
 		 * Handle a connection message
 		 */
-		if (IS_CE_MESSAGE(rcvmsg, Phy, 1, Connect)) 
+		if (IS_CE_MESSAGE(rcvmsg, Phy, 1, Connect))
 		{
 			unsigned int callid;
-			setup_parm setup;	
+			setup_parm setup;
 			pr_debug("%s: Connect message: line %d: status %d: cause 0x%x\n",
-						sc_adapter[card]->devicename,
-						rcvmsg.phy_link_no,
-						rcvmsg.rsp_status,
-						rcvmsg.msg_data.byte_array[2]);
-			
-			memcpy(&callid,rcvmsg.msg_data.byte_array,sizeof(int));
-			if(callid>=0x8000 && callid<=0xFFFF)
-			{		
+				 sc_adapter[card]->devicename,
+				 rcvmsg.phy_link_no,
+				 rcvmsg.rsp_status,
+				 rcvmsg.msg_data.byte_array[2]);
+
+			memcpy(&callid, rcvmsg.msg_data.byte_array, sizeof(int));
+			if (callid >= 0x8000 && callid <= 0xFFFF)
+			{
 				pr_debug("%s: Got Dial-Out Rsp\n",
-					sc_adapter[card]->devicename);
+					 sc_adapter[card]->devicename);
 				indicate_status(card, ISDN_STAT_DCONN,
-						(unsigned long)rcvmsg.phy_link_no-1,NULL);
-				
+						(unsigned long)rcvmsg.phy_link_no - 1, NULL);
+
 			}
-			else if(callid>=0x0000 && callid<=0x7FFF)
+			else if (callid >= 0x0000 && callid <= 0x7FFF)
 			{
 				int len;
 
 				pr_debug("%s: Got Incoming Call\n",
-						sc_adapter[card]->devicename);
+					 sc_adapter[card]->devicename);
 				len = strlcpy(setup.phone, &(rcvmsg.msg_data.byte_array[4]),
-						sizeof(setup.phone));
+					      sizeof(setup.phone));
 				if (len >= sizeof(setup.phone))
 					continue;
 				len = strlcpy(setup.eazmsn,
-						sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
-						sizeof(setup.eazmsn));
+					      sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
+					      sizeof(setup.eazmsn));
 				if (len >= sizeof(setup.eazmsn))
 					continue;
 				setup.si1 = 7;
@@ -130,8 +130,8 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 				setup.plan = 0;
 				setup.screen = 0;
 
-				indicate_status(card, ISDN_STAT_ICALL,(unsigned long)rcvmsg.phy_link_no-1,(char *)&setup);
-				indicate_status(card, ISDN_STAT_DCONN,(unsigned long)rcvmsg.phy_link_no-1,NULL);
+				indicate_status(card, ISDN_STAT_ICALL, (unsigned long)rcvmsg.phy_link_no - 1, (char *)&setup);
+				indicate_status(card, ISDN_STAT_DCONN, (unsigned long)rcvmsg.phy_link_no - 1, NULL);
 			}
 			continue;
 		}
@@ -139,16 +139,16 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 		/*
 		 * Handle a disconnection message
 		 */
-		if (IS_CE_MESSAGE(rcvmsg, Phy, 1, Disconnect)) 
+		if (IS_CE_MESSAGE(rcvmsg, Phy, 1, Disconnect))
 		{
 			pr_debug("%s: disconnect message: line %d: status %d: cause 0x%x\n",
-						sc_adapter[card]->devicename,
-						rcvmsg.phy_link_no,
-						rcvmsg.rsp_status,
-					 	rcvmsg.msg_data.byte_array[2]);
+				 sc_adapter[card]->devicename,
+				 rcvmsg.phy_link_no,
+				 rcvmsg.rsp_status,
+				 rcvmsg.msg_data.byte_array[2]);
 
-			indicate_status(card, ISDN_STAT_BHUP,(unsigned long)rcvmsg.phy_link_no-1,NULL);
-			indicate_status(card, ISDN_STAT_DHUP,(unsigned long)rcvmsg.phy_link_no-1,NULL);
+			indicate_status(card, ISDN_STAT_BHUP, (unsigned long)rcvmsg.phy_link_no - 1, NULL);
+			indicate_status(card, ISDN_STAT_DHUP, (unsigned long)rcvmsg.phy_link_no - 1, NULL);
 			continue;
 
 		}
@@ -158,10 +158,10 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 		 */
 		if (IS_CM_MESSAGE(rcvmsg, 5, 0, MiscEngineUp)) {
 			pr_debug("%s: Received EngineUp message\n",
-				sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 			sc_adapter[card]->EngineUp = 1;
-			sendmessage(card, CEPID,ceReqTypeCall,ceReqClass0,ceReqCallGetMyNumber,1,0,NULL);
-			sendmessage(card, CEPID,ceReqTypeCall,ceReqClass0,ceReqCallGetMyNumber,2,0,NULL);
+			sendmessage(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber, 1, 0, NULL);
+			sendmessage(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber, 2, 0, NULL);
 			init_timer(&sc_adapter[card]->stat_timer);
 			sc_adapter[card]->stat_timer.function = check_phystat;
 			sc_adapter[card]->stat_timer.data = card;
@@ -175,25 +175,25 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 		 */
 		if (IS_CM_MESSAGE(rcvmsg, 2, 0, StartProc)) {
 			pr_debug("%s: StartProc Response Status %d\n",
-				sc_adapter[card]->devicename,
-				rcvmsg.rsp_status);
+				 sc_adapter[card]->devicename,
+				 rcvmsg.rsp_status);
 			continue;
 		}
 
 		/*
 		 * Handle a GetMyNumber Rsp
 		 */
-		if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){
+		if (IS_CE_MESSAGE(rcvmsg, Call, 0, GetMyNumber)) {
 			strlcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn,
 				rcvmsg.msg_data.byte_array,
 				sizeof(rcvmsg.msg_data.byte_array));
 			continue;
 		}
-			
+
 		/*
 		 * PhyStatus response
 		 */
-		if(IS_CE_MESSAGE(rcvmsg, Phy, 2, Status)) {
+		if (IS_CE_MESSAGE(rcvmsg, Phy, 2, Status)) {
 			unsigned int b1stat, b2stat;
 
 			/*
@@ -204,30 +204,30 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 
 			sc_adapter[card]->nphystat = (b2stat >> 8) | b1stat; /* endian?? */
 			pr_debug("%s: PhyStat is 0x%2x\n",
-				sc_adapter[card]->devicename,
-				sc_adapter[card]->nphystat);
+				 sc_adapter[card]->devicename,
+				 sc_adapter[card]->nphystat);
 			continue;
 		}
 
 
-		/* 
+		/*
 		 * Handle a GetFramFormat
 		 */
-		if(IS_CE_MESSAGE(rcvmsg, Call, 0, GetFrameFormat)) {
-			if(rcvmsg.msg_data.byte_array[0] != HDLC_PROTO) {
+		if (IS_CE_MESSAGE(rcvmsg, Call, 0, GetFrameFormat)) {
+			if (rcvmsg.msg_data.byte_array[0] != HDLC_PROTO) {
 				unsigned int proto = HDLC_PROTO;
 				/*
 				 * Set board format to HDLC if it wasn't already
 				 */
 				pr_debug("%s: current frame format: 0x%x, will change to HDLC\n",
-						sc_adapter[card]->devicename,
-					rcvmsg.msg_data.byte_array[0]);
+					 sc_adapter[card]->devicename,
+					 rcvmsg.msg_data.byte_array[0]);
 				sendmessage(card, CEPID, ceReqTypeCall,
-						ceReqClass0,
-						ceReqCallSetFrameFormat,
-						(unsigned char) channel +1,
-						1,&proto);
-				}
+					    ceReqClass0,
+					    ceReqCallSetFrameFormat,
+					    (unsigned char)channel + 1,
+					    1, &proto);
+			}
 			continue;
 		}
 
@@ -235,13 +235,13 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst)
 		 * Hmm...
 		 */
 		pr_debug("%s: Received unhandled message (%d,%d,%d) link %d\n",
-			sc_adapter[card]->devicename,
-			rcvmsg.type, rcvmsg.class, rcvmsg.code,
-			rcvmsg.phy_link_no);
+			 sc_adapter[card]->devicename,
+			 rcvmsg.type, rcvmsg.class, rcvmsg.code,
+			 rcvmsg.phy_link_no);
 
 	}	/* while */
 
 	pr_debug("%s: Exiting Interrupt Handler\n",
-			sc_adapter[card]->devicename);
+		 sc_adapter[card]->devicename);
 	return IRQ_HANDLED;
 }
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c
index 4cfdbe0..e63983a 100644
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -30,11 +30,11 @@ int sc_ioctl(int card, scs_ioctl *data)
 	if (!rcvmsg)
 		return -ENOMEM;
 
-	switch(data->command) {
+	switch (data->command) {
 	case SCIOCRESET:	/* Perform a hard reset of the adapter */
 	{
 		pr_debug("%s: SCIOCRESET: ioctl received\n",
-			sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		sc_adapter[card]->StartOnReset = 0;
 		kfree(rcvmsg);
 		return reset(card);
@@ -50,10 +50,10 @@ int sc_ioctl(int card, scs_ioctl *data)
 			return -ENOMEM;
 		}
 		pr_debug("%s: SCIOLOAD: ioctl received\n",
-				sc_adapter[card]->devicename);
-		if(sc_adapter[card]->EngineUp) {
+			 sc_adapter[card]->devicename);
+		if (sc_adapter[card]->EngineUp) {
 			pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n",
-				sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 			kfree(rcvmsg);
 			kfree(srec);
 			return -1;
@@ -69,18 +69,18 @@ int sc_ioctl(int card, scs_ioctl *data)
 		}
 
 		status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc,
-				0, SCIOC_SRECSIZE, srec, rcvmsg, SAR_TIMEOUT);
+					  0, SCIOC_SRECSIZE, srec, rcvmsg, SAR_TIMEOUT);
 		kfree(rcvmsg);
 		kfree(srec);
 
-		if(status) {
-			pr_debug("%s: SCIOCLOAD: command failed, status = %d\n", 
-				sc_adapter[card]->devicename, status);
+		if (status) {
+			pr_debug("%s: SCIOCLOAD: command failed, status = %d\n",
+				 sc_adapter[card]->devicename, status);
 			return -1;
 		}
 		else {
 			pr_debug("%s: SCIOCLOAD: command successful\n",
-					sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 			return 0;
 		}
 	}
@@ -89,10 +89,10 @@ int sc_ioctl(int card, scs_ioctl *data)
 	{
 		kfree(rcvmsg);
 		pr_debug("%s: SCIOSTART: ioctl received\n",
-				sc_adapter[card]->devicename);
-		if(sc_adapter[card]->EngineUp) {
+			 sc_adapter[card]->devicename);
+		if (sc_adapter[card]->EngineUp) {
 			pr_debug("%s: SCIOCSTART: command failed, engine already running.\n",
-				sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 			return -1;
 		}
 
@@ -104,7 +104,7 @@ int sc_ioctl(int card, scs_ioctl *data)
 	case SCIOCSETSWITCH:
 	{
 		pr_debug("%s: SCIOSETSWITCH: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		/*
 		 * Get the switch type from user space
@@ -115,41 +115,41 @@ int sc_ioctl(int card, scs_ioctl *data)
 		}
 
 		pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n",
-			sc_adapter[card]->devicename,
-			switchtype);
+			 sc_adapter[card]->devicename,
+			 switchtype);
 		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetSwitchType,
-						0, sizeof(char),&switchtype, rcvmsg, SAR_TIMEOUT);
-		if(!status && !(rcvmsg->rsp_status)) {
+					  0, sizeof(char), &switchtype, rcvmsg, SAR_TIMEOUT);
+		if (!status && !(rcvmsg->rsp_status)) {
 			pr_debug("%s: SCIOCSETSWITCH: command successful\n",
-				sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 			kfree(rcvmsg);
 			return 0;
 		}
 		else {
 			pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(rcvmsg);
 			return status;
 		}
 	}
-		
+
 	case SCIOCGETSWITCH:
 	{
 		pr_debug("%s: SCIOGETSWITCH: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		/*
 		 * Get the switch type from the board
 		 */
-		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 
-			ceReqCallGetSwitchType, 0, 0, NULL, rcvmsg, SAR_TIMEOUT);
+		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
+					  ceReqCallGetSwitchType, 0, 0, NULL, rcvmsg, SAR_TIMEOUT);
 		if (!status && !(rcvmsg->rsp_status)) {
 			pr_debug("%s: SCIOCGETSWITCH: command successful\n",
-					sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 		}
 		else {
 			pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(rcvmsg);
 			return status;
 		}
@@ -172,7 +172,7 @@ int sc_ioctl(int card, scs_ioctl *data)
 	case SCIOCGETSPID:
 	{
 		pr_debug("%s: SCIOGETSPID: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		spid = kzalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
 		if (!spid) {
@@ -183,13 +183,13 @@ int sc_ioctl(int card, scs_ioctl *data)
 		 * Get the spid from the board
 		 */
 		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSPID,
-					data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
+					  data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
 		if (!status) {
 			pr_debug("%s: SCIOCGETSPID: command successful\n",
-					sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 		} else {
 			pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(spid);
 			kfree(rcvmsg);
 			return status;
@@ -208,12 +208,12 @@ int sc_ioctl(int card, scs_ioctl *data)
 		kfree(spid);
 		kfree(rcvmsg);
 		return 0;
-	}	
+	}
 
 	case SCIOCSETSPID:
 	{
 		pr_debug("%s: DCBIOSETSPID: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		/*
 		 * Get the spid from user space
@@ -224,21 +224,21 @@ int sc_ioctl(int card, scs_ioctl *data)
 			return PTR_ERR(spid);
 		}
 
-		pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n", 
-			sc_adapter[card]->devicename, data->channel, spid);
-		status = send_and_receive(card, CEPID, ceReqTypeCall, 
-			ceReqClass0, ceReqCallSetSPID, data->channel, 
-			strlen(spid), spid, rcvmsg, SAR_TIMEOUT);
-		if(!status && !(rcvmsg->rsp_status)) {
-			pr_debug("%s: SCIOCSETSPID: command successful\n", 
-				sc_adapter[card]->devicename);
+		pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n",
+			 sc_adapter[card]->devicename, data->channel, spid);
+		status = send_and_receive(card, CEPID, ceReqTypeCall,
+					  ceReqClass0, ceReqCallSetSPID, data->channel,
+					  strlen(spid), spid, rcvmsg, SAR_TIMEOUT);
+		if (!status && !(rcvmsg->rsp_status)) {
+			pr_debug("%s: SCIOCSETSPID: command successful\n",
+				 sc_adapter[card]->devicename);
 			kfree(rcvmsg);
 			kfree(spid);
 			return 0;
 		}
 		else {
 			pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(rcvmsg);
 			kfree(spid);
 			return status;
@@ -248,20 +248,20 @@ int sc_ioctl(int card, scs_ioctl *data)
 	case SCIOCGETDN:
 	{
 		pr_debug("%s: SCIOGETDN: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		/*
 		 * Get the dn from the board
 		 */
 		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber,
-					data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
+					  data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
 		if (!status) {
 			pr_debug("%s: SCIOCGETDN: command successful\n",
-					sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 		}
 		else {
 			pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(rcvmsg);
 			return status;
 		}
@@ -283,12 +283,12 @@ int sc_ioctl(int card, scs_ioctl *data)
 		}
 		kfree(dn);
 		return 0;
-	}	
+	}
 
 	case SCIOCSETDN:
 	{
 		pr_debug("%s: SCIOSETDN: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		/*
 		 * Get the spid from user space
@@ -299,21 +299,21 @@ int sc_ioctl(int card, scs_ioctl *data)
 			return PTR_ERR(dn);
 		}
 
-		pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n", 
-			sc_adapter[card]->devicename, data->channel, dn);
-		status = send_and_receive(card, CEPID, ceReqTypeCall, 
-			ceReqClass0, ceReqCallSetMyNumber, data->channel, 
-			strlen(dn),dn,rcvmsg, SAR_TIMEOUT);
-		if(!status && !(rcvmsg->rsp_status)) {
-			pr_debug("%s: SCIOCSETDN: command successful\n", 
-				sc_adapter[card]->devicename);
+		pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n",
+			 sc_adapter[card]->devicename, data->channel, dn);
+		status = send_and_receive(card, CEPID, ceReqTypeCall,
+					  ceReqClass0, ceReqCallSetMyNumber, data->channel,
+					  strlen(dn), dn, rcvmsg, SAR_TIMEOUT);
+		if (!status && !(rcvmsg->rsp_status)) {
+			pr_debug("%s: SCIOCSETDN: command successful\n",
+				 sc_adapter[card]->devicename);
 			kfree(rcvmsg);
 			kfree(dn);
 			return 0;
 		}
 		else {
 			pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(rcvmsg);
 			kfree(dn);
 			return status;
@@ -323,11 +323,11 @@ int sc_ioctl(int card, scs_ioctl *data)
 	case SCIOCTRACE:
 
 		pr_debug("%s: SCIOTRACE: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 /*		sc_adapter[card]->trace = !sc_adapter[card]->trace;
 		pr_debug("%s: SCIOCTRACE: tracing turned %s\n",
-				sc_adapter[card]->devicename,
-			sc_adapter[card]->trace ? "ON" : "OFF"); */
+		sc_adapter[card]->devicename,
+		sc_adapter[card]->trace ? "ON" : "OFF"); */
 		break;
 
 	case SCIOCSTAT:
@@ -335,7 +335,7 @@ int sc_ioctl(int card, scs_ioctl *data)
 		boardInfo *bi;
 
 		pr_debug("%s: SCIOSTAT: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		bi = kzalloc(sizeof(boardInfo), GFP_KERNEL);
 		if (!bi) {
@@ -358,20 +358,20 @@ int sc_ioctl(int card, scs_ioctl *data)
 	case SCIOCGETSPEED:
 	{
 		pr_debug("%s: SCIOGETSPEED: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 
 		/*
 		 * Get the speed from the board
 		 */
-		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, 
-			ceReqCallGetCallType, data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
+		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
+					  ceReqCallGetCallType, data->channel, 0, NULL, rcvmsg, SAR_TIMEOUT);
 		if (!status && !(rcvmsg->rsp_status)) {
 			pr_debug("%s: SCIOCGETSPEED: command successful\n",
-				sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 		}
 		else {
 			pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n",
-				sc_adapter[card]->devicename, status);
+				 sc_adapter[card]->devicename, status);
 			kfree(rcvmsg);
 			return status;
 		}
@@ -392,12 +392,12 @@ int sc_ioctl(int card, scs_ioctl *data)
 
 	case SCIOCSETSPEED:
 		pr_debug("%s: SCIOCSETSPEED: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		break;
 
 	case SCIOCLOOPTST:
 		pr_debug("%s: SCIOCLOOPTST: ioctl received\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		break;
 
 	default:
@@ -432,32 +432,32 @@ static int GetStatus(int card, boardInfo *bi)
 	 * Get the current PhyStats and LnkStats
 	 */
 	status = send_and_receive(card, CEPID, ceReqTypePhy, ceReqClass2,
-		ceReqPhyStatus, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
-	if(!status) {
-		if(sc_adapter[card]->model < PRI_BOARD) {
+				  ceReqPhyStatus, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+	if (!status) {
+		if (sc_adapter[card]->model < PRI_BOARD) {
 			bi->l1_status = rcvmsg.msg_data.byte_array[2];
-			for(i = 0 ; i < BRI_CHANNELS ; i++)
+			for (i = 0; i < BRI_CHANNELS; i++)
 				bi->status.bristats[i].phy_stat =
 					rcvmsg.msg_data.byte_array[i];
 		}
 		else {
 			bi->l1_status = rcvmsg.msg_data.byte_array[0];
 			bi->l2_status = rcvmsg.msg_data.byte_array[1];
-			for(i = 0 ; i < PRI_CHANNELS ; i++)
-				bi->status.pristats[i].phy_stat = 
-					rcvmsg.msg_data.byte_array[i+2];
+			for (i = 0; i < PRI_CHANNELS; i++)
+				bi->status.pristats[i].phy_stat =
+					rcvmsg.msg_data.byte_array[i + 2];
 		}
 	}
-	
+
 	/*
 	 * Get the call types for each channel
 	 */
-	for (i = 0 ; i < sc_adapter[card]->nChannels ; i++) {
+	for (i = 0; i < sc_adapter[card]->nChannels; i++) {
 		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
-			ceReqCallGetCallType, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
-		if(!status) {
+					  ceReqCallGetCallType, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+		if (!status) {
 			if (sc_adapter[card]->model == PRI_BOARD) {
-				bi->status.pristats[i].call_type = 
+				bi->status.pristats[i].call_type =
 					rcvmsg.msg_data.byte_array[0];
 			}
 			else {
@@ -466,7 +466,7 @@ static int GetStatus(int card, boardInfo *bi)
 			}
 		}
 	}
-	
+
 	/*
 	 * If PRI, get the call states and service states for each channel
 	 */
@@ -475,10 +475,10 @@ static int GetStatus(int card, boardInfo *bi)
 		 * Get the call states
 		 */
 		status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2,
-			ceReqPhyChCallState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
-		if(!status) {
-			for( i = 0 ; i < PRI_CHANNELS ; i++ )
-				bi->status.pristats[i].call_state = 
+					  ceReqPhyChCallState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+		if (!status) {
+			for (i = 0; i < PRI_CHANNELS; i++)
+				bi->status.pristats[i].call_state =
 					rcvmsg.msg_data.byte_array[i];
 		}
 
@@ -486,27 +486,27 @@ static int GetStatus(int card, boardInfo *bi)
 		 * Get the service states
 		 */
 		status = send_and_receive(card, CEPID, ceReqTypeStat, ceReqClass2,
-			ceReqPhyChServState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
-		if(!status) {
-			for( i = 0 ; i < PRI_CHANNELS ; i++ )
-				bi->status.pristats[i].serv_state = 
+					  ceReqPhyChServState, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+		if (!status) {
+			for (i = 0; i < PRI_CHANNELS; i++)
+				bi->status.pristats[i].serv_state =
 					rcvmsg.msg_data.byte_array[i];
 		}
 
 		/*
 		 * Get the link stats for the channels
 		 */
-		for (i = 1 ; i <= PRI_CHANNELS ; i++) {
+		for (i = 1; i <= PRI_CHANNELS; i++) {
 			status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,
-				ceReqLnkGetStats, i, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+						  ceReqLnkGetStats, i, 0, NULL, &rcvmsg, SAR_TIMEOUT);
 			if (!status) {
-				bi->status.pristats[i-1].link_stats.tx_good =
+				bi->status.pristats[i - 1].link_stats.tx_good =
 					(unsigned long)rcvmsg.msg_data.byte_array[0];
-				bi->status.pristats[i-1].link_stats.tx_bad =
+				bi->status.pristats[i - 1].link_stats.tx_bad =
 					(unsigned long)rcvmsg.msg_data.byte_array[4];
-				bi->status.pristats[i-1].link_stats.rx_good =
+				bi->status.pristats[i - 1].link_stats.rx_good =
 					(unsigned long)rcvmsg.msg_data.byte_array[8];
-				bi->status.pristats[i-1].link_stats.rx_bad =
+				bi->status.pristats[i - 1].link_stats.rx_bad =
 					(unsigned long)rcvmsg.msg_data.byte_array[12];
 			}
 		}
@@ -515,7 +515,7 @@ static int GetStatus(int card, boardInfo *bi)
 		 * Link stats for the D channel
 		 */
 		status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,
-			ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+					  ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
 		if (!status) {
 			bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0];
 			bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4];
@@ -534,49 +534,49 @@ static int GetStatus(int card, boardInfo *bi)
 	 * Get the link stats for the channels
 	 */
 	status = send_and_receive(card, CEPID, ceReqTypeLnk, ceReqClass0,
-		ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+				  ceReqLnkGetStats, 0, 0, NULL, &rcvmsg, SAR_TIMEOUT);
 	if (!status) {
 		bi->dch_stats.tx_good = (unsigned long)rcvmsg.msg_data.byte_array[0];
 		bi->dch_stats.tx_bad = (unsigned long)rcvmsg.msg_data.byte_array[4];
 		bi->dch_stats.rx_good = (unsigned long)rcvmsg.msg_data.byte_array[8];
 		bi->dch_stats.rx_bad = (unsigned long)rcvmsg.msg_data.byte_array[12];
-		bi->status.bristats[0].link_stats.tx_good = 
+		bi->status.bristats[0].link_stats.tx_good =
 			(unsigned long)rcvmsg.msg_data.byte_array[16];
-		bi->status.bristats[0].link_stats.tx_bad = 
+		bi->status.bristats[0].link_stats.tx_bad =
 			(unsigned long)rcvmsg.msg_data.byte_array[20];
-		bi->status.bristats[0].link_stats.rx_good = 
+		bi->status.bristats[0].link_stats.rx_good =
 			(unsigned long)rcvmsg.msg_data.byte_array[24];
-		bi->status.bristats[0].link_stats.rx_bad = 
+		bi->status.bristats[0].link_stats.rx_bad =
 			(unsigned long)rcvmsg.msg_data.byte_array[28];
-		bi->status.bristats[1].link_stats.tx_good = 
+		bi->status.bristats[1].link_stats.tx_good =
 			(unsigned long)rcvmsg.msg_data.byte_array[32];
-		bi->status.bristats[1].link_stats.tx_bad = 
+		bi->status.bristats[1].link_stats.tx_bad =
 			(unsigned long)rcvmsg.msg_data.byte_array[36];
-		bi->status.bristats[1].link_stats.rx_good = 
+		bi->status.bristats[1].link_stats.rx_good =
 			(unsigned long)rcvmsg.msg_data.byte_array[40];
-		bi->status.bristats[1].link_stats.rx_bad = 
+		bi->status.bristats[1].link_stats.rx_bad =
 			(unsigned long)rcvmsg.msg_data.byte_array[44];
 	}
 
 	/*
 	 * Get the SPIDs
 	 */
-	for (i = 0 ; i < BRI_CHANNELS ; i++) {
+	for (i = 0; i < BRI_CHANNELS; i++) {
 		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
-			ceReqCallGetSPID, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+					  ceReqCallGetSPID, i + 1, 0, NULL, &rcvmsg, SAR_TIMEOUT);
 		if (!status)
 			strcpy(bi->status.bristats[i].spid, rcvmsg.msg_data.byte_array);
 	}
-		
+
 	/*
 	 * Get the DNs
 	 */
-	for (i = 0 ; i < BRI_CHANNELS ; i++) {
+	for (i = 0; i < BRI_CHANNELS; i++) {
 		status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0,
-			ceReqCallGetMyNumber, i+1, 0, NULL, &rcvmsg, SAR_TIMEOUT);
+					  ceReqCallGetMyNumber, i + 1, 0, NULL, &rcvmsg, SAR_TIMEOUT);
 		if (!status)
 			strcpy(bi->status.bristats[i].dn, rcvmsg.msg_data.byte_array);
 	}
-		
+
 	return 0;
 }
diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c
index 0b4c4f1..9679a19 100644
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -25,7 +25,7 @@
 /*
  * receive a message from the board
  */
-int receivemessage(int card, RspMessage *rspmsg) 
+int receivemessage(int card, RspMessage *rspmsg)
 {
 	DualPortMemory *dpm;
 	unsigned long flags;
@@ -34,9 +34,9 @@ int receivemessage(int card, RspMessage *rspmsg)
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return -EINVAL;
 	}
-	
+
 	pr_debug("%s: Entered receivemessage\n",
-			sc_adapter[card]->devicename);
+		 sc_adapter[card]->devicename);
 
 	/*
 	 * See if there are messages waiting
@@ -47,47 +47,47 @@ int receivemessage(int card, RspMessage *rspmsg)
 		 */
 		spin_lock_irqsave(&sc_adapter[card]->lock, flags);
 		outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
-			sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
+		     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
 		dpm = (DualPortMemory *) sc_adapter[card]->rambase;
-		memcpy_fromio(rspmsg, &(dpm->rsp_queue[dpm->rsp_tail]), 
-			MSG_LEN);
-		dpm->rsp_tail = (dpm->rsp_tail+1) % MAX_MESSAGES;
+		memcpy_fromio(rspmsg, &(dpm->rsp_queue[dpm->rsp_tail]),
+			      MSG_LEN);
+		dpm->rsp_tail = (dpm->rsp_tail + 1) % MAX_MESSAGES;
 		inb(sc_adapter[card]->ioport[FIFO_READ]);
 		spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 		/*
 		 * Tell the board that the message is received
 		 */
 		pr_debug("%s: Received Message seq:%d pid:%d time:%d cmd:%d "
-				"cnt:%d (type,class,code):(%d,%d,%d) "
-				"link:%d stat:0x%x\n",
-					sc_adapter[card]->devicename,
-					rspmsg->sequence_no,
-					rspmsg->process_id,
-					rspmsg->time_stamp,
-					rspmsg->cmd_sequence_no,
-					rspmsg->msg_byte_cnt,
-					rspmsg->type,
-					rspmsg->class,
-					rspmsg->code,
-					rspmsg->phy_link_no, 
-					rspmsg->rsp_status);
+			 "cnt:%d (type,class,code):(%d,%d,%d) "
+			 "link:%d stat:0x%x\n",
+			 sc_adapter[card]->devicename,
+			 rspmsg->sequence_no,
+			 rspmsg->process_id,
+			 rspmsg->time_stamp,
+			 rspmsg->cmd_sequence_no,
+			 rspmsg->msg_byte_cnt,
+			 rspmsg->type,
+			 rspmsg->class,
+			 rspmsg->code,
+			 rspmsg->phy_link_no,
+			 rspmsg->rsp_status);
 
 		return 0;
 	}
 	return -ENOMSG;
 }
-	
+
 /*
  * send a message to the board
  */
 int sendmessage(int card,
 		unsigned int procid,
-		unsigned int type, 
-		unsigned int class, 
+		unsigned int type,
+		unsigned int class,
 		unsigned int code,
-		unsigned int link, 
-		unsigned int data_len, 
-		unsigned int *data) 
+		unsigned int link,
+		unsigned int data_len,
+		unsigned int *data)
 {
 	DualPortMemory *dpm;
 	ReqMessage sndmsg;
@@ -102,15 +102,15 @@ int sendmessage(int card,
 	 * Make sure we only send CEPID messages when the engine is up
 	 * and CMPID messages when it is down
 	 */
-	if(sc_adapter[card]->EngineUp && procid == CMPID) {
+	if (sc_adapter[card]->EngineUp && procid == CMPID) {
 		pr_debug("%s: Attempt to send CM message with engine up\n",
-			sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		return -ESRCH;
 	}
 
-	if(!sc_adapter[card]->EngineUp && procid == CEPID) {
+	if (!sc_adapter[card]->EngineUp && procid == CEPID) {
 		pr_debug("%s: Attempt to send CE message with engine down\n",
-			sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		return -ESRCH;
 	}
 
@@ -142,39 +142,39 @@ int sendmessage(int card,
 	 */
 	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
 	outb((sc_adapter[card]->shmem_magic >> 14) | 0x80,
-		sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
+	     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
 	dpm = (DualPortMemory *) sc_adapter[card]->rambase;	/* Fix me */
-	memcpy_toio(&(dpm->req_queue[dpm->req_head]),&sndmsg,MSG_LEN);
-	dpm->req_head = (dpm->req_head+1) % MAX_MESSAGES;
+	memcpy_toio(&(dpm->req_queue[dpm->req_head]), &sndmsg, MSG_LEN);
+	dpm->req_head = (dpm->req_head + 1) % MAX_MESSAGES;
 	outb(sndmsg.sequence_no, sc_adapter[card]->ioport[FIFO_WRITE]);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
-		
+
 	pr_debug("%s: Sent Message seq:%d pid:%d time:%d "
-			"cnt:%d (type,class,code):(%d,%d,%d) "
-			"link:%d\n ",
-				sc_adapter[card]->devicename,
-				sndmsg.sequence_no,
-				sndmsg.process_id,
-				sndmsg.time_stamp,
-				sndmsg.msg_byte_cnt,
-				sndmsg.type,
-				sndmsg.class,
-				sndmsg.code,
-				sndmsg.phy_link_no); 
-		
+		 "cnt:%d (type,class,code):(%d,%d,%d) "
+		 "link:%d\n ",
+		 sc_adapter[card]->devicename,
+		 sndmsg.sequence_no,
+		 sndmsg.process_id,
+		 sndmsg.time_stamp,
+		 sndmsg.msg_byte_cnt,
+		 sndmsg.type,
+		 sndmsg.class,
+		 sndmsg.code,
+		 sndmsg.phy_link_no);
+
 	return 0;
 }
 
 int send_and_receive(int card,
-		unsigned int procid, 
-		unsigned char type,
-		unsigned char class, 
-		unsigned char code,
-		unsigned char link,
-	 	unsigned char data_len, 
-		unsigned char *data, 
-		RspMessage *mesgdata,
-		int timeout) 
+		     unsigned int procid,
+		     unsigned char type,
+		     unsigned char class,
+		     unsigned char code,
+		     unsigned char link,
+		     unsigned char data_len,
+		     unsigned char *data,
+		     RspMessage *mesgdata,
+		     int timeout)
 {
 	int retval;
 	int tries;
@@ -185,12 +185,12 @@ int send_and_receive(int card,
 	}
 
 	sc_adapter[card]->want_async_messages = 1;
-	retval = sendmessage(card, procid, type, class, code, link, 
-			data_len, (unsigned int *) data);
-  
+	retval = sendmessage(card, procid, type, class, code, link,
+			     data_len, (unsigned int *) data);
+
 	if (retval) {
 		pr_debug("%s: SendMessage failed in SAR\n",
-			sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		sc_adapter[card]->want_async_messages = 0;
 		return -EIO;
 	}
@@ -199,7 +199,7 @@ int send_and_receive(int card,
 	/* wait for the response */
 	while (tries < timeout) {
 		schedule_timeout_interruptible(1);
-		
+
 		pr_debug("SAR waiting..\n");
 
 		/*
@@ -214,14 +214,14 @@ int send_and_receive(int card,
 			 * Got it!
 			 */
 			pr_debug("%s: Got ASYNC message\n",
-				sc_adapter[card]->devicename);
+				 sc_adapter[card]->devicename);
 			memcpy(mesgdata, &(sc_adapter[card]->async_msg),
-				sizeof(RspMessage));
+			       sizeof(RspMessage));
 			sc_adapter[card]->want_async_messages = 0;
 			return 0;
 		}
 
-   		tries++;
+		tries++;
 	}
 
 	pr_debug("%s: SAR message timeout\n", sc_adapter[card]->devicename);
diff --git a/drivers/isdn/sc/message.h b/drivers/isdn/sc/message.h
index 8eb15e7..5e6f4a5 100644
--- a/drivers/isdn/sc/message.h
+++ b/drivers/isdn/sc/message.h
@@ -21,7 +21,7 @@
 /*
  * Board message macros, defines and structures
  */
- 
+
 #ifndef MESSAGE_H
 #define MESSAGE_H
 
@@ -36,19 +36,19 @@
  * Macro to determine if a message is a loader message
  */
 #define IS_CM_MESSAGE(mesg, tx, cx, dx)		\
-		((mesg.type == cmRspType##tx)		\
-		&&(mesg.class == cmRspClass##cx)	\
-		&&(mesg.code == cmRsp##dx))
+	((mesg.type == cmRspType##tx)		\
+	 && (mesg.class == cmRspClass##cx)	\
+	 && (mesg.code == cmRsp##dx))
 
 /*
  * Macro to determine if a message is a firmware message
  */
 #define IS_CE_MESSAGE(mesg, tx, cx, dx)		\
-		((mesg.type == ceRspType##tx)		\
-		&&(mesg.class == ceRspClass##cx)	\
-		&&(mesg.code == ceRsp##tx##dx))
+	((mesg.type == ceRspType##tx)		\
+	 && (mesg.class == ceRspClass##cx)	\
+	 && (mesg.code == ceRsp##tx##dx))
 
-/* 
+/*
  * Loader Request and Response Messages
  */
 
@@ -186,7 +186,7 @@ typedef struct {
 } LLData;
 
 
-/* 
+/*
  * Message payload template for an HWConfig message
  */
 typedef struct {
diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c
index 5ff6ae8..2446957 100644
--- a/drivers/isdn/sc/packet.c
+++ b/drivers/isdn/sc/packet.c
@@ -29,27 +29,27 @@ int sndpkt(int devId, int channel, int ack, struct sk_buff *data)
 
 	card = get_card_from_id(devId);
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
 
 	pr_debug("%s: sndpkt: frst = 0x%lx nxt = %d  f = %d n = %d\n",
-		sc_adapter[card]->devicename,
-		sc_adapter[card]->channel[channel].first_sendbuf,
-		sc_adapter[card]->channel[channel].next_sendbuf,
-		sc_adapter[card]->channel[channel].free_sendbufs,
-		sc_adapter[card]->channel[channel].num_sendbufs);
+		 sc_adapter[card]->devicename,
+		 sc_adapter[card]->channel[channel].first_sendbuf,
+		 sc_adapter[card]->channel[channel].next_sendbuf,
+		 sc_adapter[card]->channel[channel].free_sendbufs,
+		 sc_adapter[card]->channel[channel].num_sendbufs);
 
-	if(!sc_adapter[card]->channel[channel].free_sendbufs) {
+	if (!sc_adapter[card]->channel[channel].free_sendbufs) {
 		pr_debug("%s: out of TX buffers\n",
-				sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		return -EINVAL;
 	}
 
-	if(data->len > BUFFER_SIZE) {
+	if (data->len > BUFFER_SIZE) {
 		pr_debug("%s: data overflows buffer size (data > buffer)\n",
-			sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		return -EINVAL;
 	}
 
@@ -57,24 +57,24 @@ int sndpkt(int devId, int channel, int ack, struct sk_buff *data)
 		BUFFER_SIZE + sc_adapter[card]->channel[channel].first_sendbuf;
 	ReqLnkWrite.msg_len = data->len; /* sk_buff size */
 	pr_debug("%s: writing %d bytes to buffer offset 0x%lx\n",
-			sc_adapter[card]->devicename,
-			ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset);
+		 sc_adapter[card]->devicename,
+		 ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset);
 	memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len);
 
 	/*
 	 * sendmessage
 	 */
 	pr_debug("%s: sndpkt size=%d, buf_offset=0x%lx buf_indx=%d\n",
-		sc_adapter[card]->devicename,
-		ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset,
-		sc_adapter[card]->channel[channel].next_sendbuf);
+		 sc_adapter[card]->devicename,
+		 ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset,
+		 sc_adapter[card]->channel[channel].next_sendbuf);
 
 	status = sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkWrite,
-				channel+1, sizeof(LLData), (unsigned int*)&ReqLnkWrite);
+			     channel + 1, sizeof(LLData), (unsigned int *)&ReqLnkWrite);
 	len = data->len;
-	if(status) {
+	if (status) {
 		pr_debug("%s: failed to send packet, status = %d\n",
-				sc_adapter[card]->devicename, status);
+			 sc_adapter[card]->devicename, status);
 		return -1;
 	}
 	else {
@@ -83,9 +83,9 @@ int sndpkt(int devId, int channel, int ack, struct sk_buff *data)
 			++sc_adapter[card]->channel[channel].next_sendbuf ==
 			sc_adapter[card]->channel[channel].num_sendbufs ? 0 :
 			sc_adapter[card]->channel[channel].next_sendbuf;
-			pr_debug("%s: packet sent successfully\n", sc_adapter[card]->devicename);
+		pr_debug("%s: packet sent successfully\n", sc_adapter[card]->devicename);
 		dev_kfree_skb(data);
-		indicate_status(card,ISDN_STAT_BSENT,channel, (char *)&len);
+		indicate_status(card, ISDN_STAT_BSENT, channel, (char *)&len);
 	}
 	return len;
 }
@@ -95,49 +95,49 @@ void rcvpkt(int card, RspMessage *rcvmsg)
 	LLData newll;
 	struct sk_buff *skb;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("invalid param: %d is not a valid card id\n", card);
 		return;
 	}
 
-	switch(rcvmsg->rsp_status){
+	switch (rcvmsg->rsp_status) {
 	case 0x01:
 	case 0x02:
 	case 0x70:
 		pr_debug("%s: error status code: 0x%x\n",
-			sc_adapter[card]->devicename, rcvmsg->rsp_status);
+			 sc_adapter[card]->devicename, rcvmsg->rsp_status);
 		return;
-	case 0x00: 
-	    if (!(skb = dev_alloc_skb(rcvmsg->msg_data.response.msg_len))) {
+	case 0x00:
+		if (!(skb = dev_alloc_skb(rcvmsg->msg_data.response.msg_len))) {
 			printk(KERN_WARNING "%s: rcvpkt out of memory, dropping packet\n",
-				sc_adapter[card]->devicename);
+			       sc_adapter[card]->devicename);
 			return;
 		}
 		skb_put(skb, rcvmsg->msg_data.response.msg_len);
 		pr_debug("%s: getting data from offset: 0x%lx\n",
-			sc_adapter[card]->devicename,
-			rcvmsg->msg_data.response.buff_offset);
+			 sc_adapter[card]->devicename,
+			 rcvmsg->msg_data.response.buff_offset);
 		memcpy_fromshmem(card,
-			skb_put(skb, rcvmsg->msg_data.response.msg_len),
-		 	(char *)rcvmsg->msg_data.response.buff_offset,
-			rcvmsg->msg_data.response.msg_len);
+				 skb_put(skb, rcvmsg->msg_data.response.msg_len),
+				 (char *)rcvmsg->msg_data.response.buff_offset,
+				 rcvmsg->msg_data.response.msg_len);
 		sc_adapter[card]->card->rcvcallb_skb(sc_adapter[card]->driverId,
-			rcvmsg->phy_link_no-1, skb);
+						     rcvmsg->phy_link_no - 1, skb);
 
 	case 0x03:
 		/*
-	 	 * Recycle the buffer
-	 	 */
+		 * Recycle the buffer
+		 */
 		pr_debug("%s: buffer size : %d\n",
-				sc_adapter[card]->devicename, BUFFER_SIZE);
+			 sc_adapter[card]->devicename, BUFFER_SIZE);
 /*		memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */
 		newll.buff_offset = rcvmsg->msg_data.response.buff_offset;
 		newll.msg_len = BUFFER_SIZE;
 		pr_debug("%s: recycled buffer at offset 0x%lx size %d\n",
-			sc_adapter[card]->devicename,
-			newll.buff_offset, newll.msg_len);
+			 sc_adapter[card]->devicename,
+			 newll.buff_offset, newll.msg_len);
 		sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
-			rcvmsg->phy_link_no, sizeof(LLData), (unsigned int *)&newll);
+			    rcvmsg->phy_link_no, sizeof(LLData), (unsigned int *)&newll);
 	}
 
 }
@@ -148,7 +148,7 @@ int setup_buffers(int card, int c)
 	unsigned int buffer_size;
 	LLData	RcvBuffOffset;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("invalid param: %d is not a valid card id\n", card);
 		return -ENODEV;
 	}
@@ -157,49 +157,48 @@ int setup_buffers(int card, int c)
 	 * Calculate the buffer offsets (send/recv/send/recv)
 	 */
 	pr_debug("%s: setting up channel buffer space in shared RAM\n",
-			sc_adapter[card]->devicename);
+		 sc_adapter[card]->devicename);
 	buffer_size = BUFFER_SIZE;
 	nBuffers = ((sc_adapter[card]->ramsize - BUFFER_BASE) / buffer_size) / 2;
 	nBuffers = nBuffers > BUFFERS_MAX ? BUFFERS_MAX : nBuffers;
 	pr_debug("%s: calculating buffer space: %d buffers, %d big\n",
-		sc_adapter[card]->devicename,
-		nBuffers, buffer_size);
-	if(nBuffers < 2) {
+		 sc_adapter[card]->devicename,
+		 nBuffers, buffer_size);
+	if (nBuffers < 2) {
 		pr_debug("%s: not enough buffer space\n",
-			sc_adapter[card]->devicename);
+			 sc_adapter[card]->devicename);
 		return -1;
 	}
 	cBase = (nBuffers * buffer_size) * (c - 1);
 	pr_debug("%s: channel buffer offset from shared RAM: 0x%x\n",
-			sc_adapter[card]->devicename, cBase);
-	sc_adapter[card]->channel[c-1].first_sendbuf = BUFFER_BASE + cBase;
-	sc_adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2;
-	sc_adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2;
-	sc_adapter[card]->channel[c-1].next_sendbuf = 0;
+		 sc_adapter[card]->devicename, cBase);
+	sc_adapter[card]->channel[c - 1].first_sendbuf = BUFFER_BASE + cBase;
+	sc_adapter[card]->channel[c - 1].num_sendbufs = nBuffers / 2;
+	sc_adapter[card]->channel[c - 1].free_sendbufs = nBuffers / 2;
+	sc_adapter[card]->channel[c - 1].next_sendbuf = 0;
 	pr_debug("%s: send buffer setup complete: first=0x%lx n=%d f=%d, nxt=%d\n",
-				sc_adapter[card]->devicename,
-				sc_adapter[card]->channel[c-1].first_sendbuf,
-				sc_adapter[card]->channel[c-1].num_sendbufs,
-				sc_adapter[card]->channel[c-1].free_sendbufs,
-				sc_adapter[card]->channel[c-1].next_sendbuf);
+		 sc_adapter[card]->devicename,
+		 sc_adapter[card]->channel[c - 1].first_sendbuf,
+		 sc_adapter[card]->channel[c - 1].num_sendbufs,
+		 sc_adapter[card]->channel[c - 1].free_sendbufs,
+		 sc_adapter[card]->channel[c - 1].next_sendbuf);
 
 	/*
 	 * Prep the receive buffers
 	 */
 	pr_debug("%s: adding %d RecvBuffers:\n",
-			sc_adapter[card]->devicename, nBuffers /2);
-	for (i = 0 ; i < nBuffers / 2; i++) {
-		RcvBuffOffset.buff_offset = 
-			((sc_adapter[card]->channel[c-1].first_sendbuf +
-			(nBuffers / 2) * buffer_size) + (buffer_size * i));
+		 sc_adapter[card]->devicename, nBuffers / 2);
+	for (i = 0; i < nBuffers / 2; i++) {
+		RcvBuffOffset.buff_offset =
+			((sc_adapter[card]->channel[c - 1].first_sendbuf +
+			  (nBuffers / 2) * buffer_size) + (buffer_size * i));
 		RcvBuffOffset.msg_len = buffer_size;
 		pr_debug("%s: adding RcvBuffer #%d offset=0x%lx sz=%d bufsz:%d\n",
-				sc_adapter[card]->devicename,
-				i + 1, RcvBuffOffset.buff_offset, 
-				RcvBuffOffset.msg_len,buffer_size);
+			 sc_adapter[card]->devicename,
+			 i + 1, RcvBuffOffset.buff_offset,
+			 RcvBuffOffset.msg_len, buffer_size);
 		sendmessage(card, CEPID, ceReqTypeLnk, ceReqClass1, ceReqLnkRead,
-				c, sizeof(LLData), (unsigned int *)&RcvBuffOffset);
-	} 
+			    c, sizeof(LLData), (unsigned int *)&RcvBuffOffset);
+	}
 	return 0;
 }
-
diff --git a/drivers/isdn/sc/scioc.h b/drivers/isdn/sc/scioc.h
index dfb107a..a50e143 100644
--- a/drivers/isdn/sc/scioc.h
+++ b/drivers/isdn/sc/scioc.h
@@ -17,9 +17,9 @@
 #define SCIOCGETSWITCH	0x06	/* Get switch type */
 #define SCIOCSETSWITCH	0x07	/* Set switch type */
 #define SCIOCGETSPID	0x08	/* Get channel SPID */
-#define SCIOCSETSPID	0x09 	/* Set channel SPID */
+#define SCIOCSETSPID	0x09	/* Set channel SPID */
 #define SCIOCGETDN	0x0A	/* Get channel DN */
-#define SCIOCSETDN	0x0B 	/* Set channel DN */
+#define SCIOCSETDN	0x0B	/* Set channel DN */
 #define SCIOCTRACE	0x0C	/* Toggle trace mode */
 #define SCIOCSTAT	0x0D	/* Get line status */
 #define SCIOCGETSPEED	0x0E	/* Set channel speed */
@@ -108,4 +108,3 @@ typedef struct {
 } boardInfo;
 
 #endif  /*  __ISDN_SC_SCIOC_H__  */
-
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
index 7f16d75..d24506c 100644
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -42,22 +42,22 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
 	 * determine the page to load from the address
 	 */
 	ch = (unsigned long) dest / SRAM_PAGESIZE;
-	pr_debug("%s: loaded page %d\n", sc_adapter[card]->devicename,ch);
+	pr_debug("%s: loaded page %d\n", sc_adapter[card]->devicename, ch);
 	/*
 	 * Block interrupts and load the page
 	 */
 	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
 
 	outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
-		sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
+	     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
 	memcpy_toio((void __iomem *)(sc_adapter[card]->rambase + dest_rem), src, n);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
-	pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
-		((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
+	pr_debug("%s: set page to %#x\n", sc_adapter[card]->devicename,
+		 ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80);
 	pr_debug("%s: copying %zu bytes from %#lx to %#lx\n",
-		sc_adapter[card]->devicename, n,
-		(unsigned long) src,
-		sc_adapter[card]->rambase + ((unsigned long) dest %0x4000));
+		 sc_adapter[card]->devicename, n,
+		 (unsigned long) src,
+		 sc_adapter[card]->rambase + ((unsigned long) dest % 0x4000));
 }
 
 /*
@@ -68,12 +68,12 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n)
 	unsigned long flags;
 	unsigned char ch;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return;
 	}
 
-	if(n > SRAM_PAGESIZE) {
+	if (n > SRAM_PAGESIZE) {
 		return;
 	}
 
@@ -81,24 +81,24 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n)
 	 * determine the page to load from the address
 	 */
 	ch = (unsigned long) src / SRAM_PAGESIZE;
-	pr_debug("%s: loaded page %d\n", sc_adapter[card]->devicename,ch);
-	
-	
+	pr_debug("%s: loaded page %d\n", sc_adapter[card]->devicename, ch);
+
+
 	/*
 	 * Block interrupts and load the page
 	 */
 	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
 
 	outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
-		sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
-	memcpy_fromio(dest,(void *)(sc_adapter[card]->rambase +
-		((unsigned long) src % 0x4000)), n);
+	     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
+	memcpy_fromio(dest, (void *)(sc_adapter[card]->rambase +
+				     ((unsigned long) src % 0x4000)), n);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
-	pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
-		((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
+	pr_debug("%s: set page to %#x\n", sc_adapter[card]->devicename,
+		 ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80);
 /*	pr_debug("%s: copying %d bytes from %#x to %#x\n",
-		sc_adapter[card]->devicename, n,
-		sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */
+	sc_adapter[card]->devicename, n,
+	sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */
 }
 
 #if 0
@@ -107,12 +107,12 @@ void memset_shmem(int card, void *dest, int c, size_t n)
 	unsigned long flags;
 	unsigned char ch;
 
-	if(!IS_VALID_CARD(card)) {
+	if (!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
 		return;
 	}
 
-	if(n > SRAM_PAGESIZE) {
+	if (n > SRAM_PAGESIZE) {
 		return;
 	}
 
@@ -120,7 +120,7 @@ void memset_shmem(int card, void *dest, int c, size_t n)
 	 * determine the page to load from the address
 	 */
 	ch = (unsigned long) dest / SRAM_PAGESIZE;
-	pr_debug("%s: loaded page %d\n",sc_adapter[card]->devicename,ch);
+	pr_debug("%s: loaded page %d\n", sc_adapter[card]->devicename, ch);
 
 	/*
 	 * Block interrupts and load the page
@@ -128,11 +128,11 @@ void memset_shmem(int card, void *dest, int c, size_t n)
 	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
 
 	outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
-		sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
+	     sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
 	memset_io(sc_adapter[card]->rambase +
-		((unsigned long) dest % 0x4000), c, n);
-	pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
-		((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
+		  ((unsigned long) dest % 0x4000), c, n);
+	pr_debug("%s: set page to %#x\n", sc_adapter[card]->devicename,
+		 ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 }
 #endif  /*  0  */
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
index 91fbe0d..6fbac22 100644
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -31,7 +31,7 @@ static void setup_ports(int card)
 
 	/* And the IRQ */
 	outb((sc_adapter[card]->interrupt | 0x80),
-		sc_adapter[card]->ioport[IRQ_SELECT]);
+	     sc_adapter[card]->ioport[IRQ_SELECT]);
 }
 
 /*
@@ -50,18 +50,18 @@ void sc_check_reset(unsigned long data)
 	int card = (unsigned int) data;
 
 	pr_debug("%s: check_timer timer called\n",
-		sc_adapter[card]->devicename);
+		 sc_adapter[card]->devicename);
 
 	/* Setup the io ports */
 	setup_ports(card);
 
 	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
 	outb(sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport],
-		(sc_adapter[card]->shmem_magic>>14) | 0x80);
+	     (sc_adapter[card]->shmem_magic >> 14) | 0x80);
 	sig = (unsigned long) *((unsigned long *)(sc_adapter[card]->rambase + SIG_OFFSET));
 
 	/* check the signature */
-	if(sig == SIGNATURE) {
+	if (sig == SIGNATURE) {
 		flushreadfifo(card);
 		spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 		/* See if we need to do a startproc */
@@ -69,8 +69,8 @@ void sc_check_reset(unsigned long data)
 			startproc(card);
 	} else  {
 		pr_debug("%s: No signature yet, waiting another %lu jiffies.\n",
-			sc_adapter[card]->devicename, CHECKRESET_TIME);
-		mod_timer(&sc_adapter[card]->reset_timer, jiffies+CHECKRESET_TIME);
+			 sc_adapter[card]->devicename, CHECKRESET_TIME);
+		mod_timer(&sc_adapter[card]->reset_timer, jiffies + CHECKRESET_TIME);
 		spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 	}
 }
@@ -91,19 +91,19 @@ void check_phystat(unsigned long data)
 	int card = (unsigned int) data;
 
 	pr_debug("%s: Checking status...\n", sc_adapter[card]->devicename);
-	/* 
+	/*
 	 * check the results of the last PhyStat and change only if
 	 * has changed drastically
 	 */
 	if (sc_adapter[card]->nphystat && !sc_adapter[card]->phystat) {   /* All is well */
 		pr_debug("PhyStat transition to RUN\n");
-		pr_info("%s: Switch contacted, transmitter enabled\n", 
+		pr_info("%s: Switch contacted, transmitter enabled\n",
 			sc_adapter[card]->devicename);
 		indicate_status(card, ISDN_STAT_RUN, 0, NULL);
 	}
 	else if (!sc_adapter[card]->nphystat && sc_adapter[card]->phystat) {   /* All is not well */
 		pr_debug("PhyStat transition to STOP\n");
-		pr_info("%s: Switch connection lost, transmitter disabled\n", 
+		pr_info("%s: Switch connection lost, transmitter disabled\n",
 			sc_adapter[card]->devicename);
 
 		indicate_status(card, ISDN_STAT_STOP, 0, NULL);
@@ -113,11 +113,10 @@ void check_phystat(unsigned long data)
 
 	/* Reinitialize the timer */
 	spin_lock_irqsave(&sc_adapter[card]->lock, flags);
-	mod_timer(&sc_adapter[card]->stat_timer, jiffies+CHECKSTAT_TIME);
+	mod_timer(&sc_adapter[card]->stat_timer, jiffies + CHECKSTAT_TIME);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 
 	/* Send a new cePhyStatus message */
-	sendmessage(card, CEPID,ceReqTypePhy,ceReqClass2,
-		ceReqPhyStatus,0,0,NULL);
+	sendmessage(card, CEPID, ceReqTypePhy, ceReqClass2,
+		    ceReqPhyStatus, 0, 0, NULL);
 }
-
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ca28fc..e2ac190 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -89,16 +89,6 @@ config LEDS_NET48XX
 	  This option enables support for the Soekris net4801 and net4826 error
 	  LED.
 
-config LEDS_NET5501
-	tristate "LED Support for Soekris net5501 series Error LED"
-	depends on LEDS_TRIGGERS
-	depends on X86 && GPIO_CS5535
-	select LEDS_TRIGGER_DEFAULT_ON
-	default n
-	help
-	  Add support for the Soekris net5501 board (detection, error led
-	  and GPIO).
-
 config LEDS_FSG
 	tristate "LED Support for the Freecom FSG-3"
 	depends on LEDS_CLASS
@@ -244,6 +234,14 @@ config LEDS_PCA955X
 	  LED driver chips accessed via the I2C bus.  Supported
 	  devices include PCA9550, PCA9551, PCA9552, and PCA9553.
 
+config LEDS_PCA9633
+	tristate "LED support for PCA9633 I2C chip"
+	depends on LEDS_CLASS
+	depends on I2C
+	help
+	  This option enables support for LEDs connected to the PCA9633
+	  LED driver chip accessed via the I2C bus.
+
 config LEDS_WM831X_STATUS
 	tristate "LED support for status LEDs on WM831x PMICs"
 	depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 1fc6875..fa0f428 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_LEDS_MIKROTIK_RB532)	+= leds-rb532.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_AMS_DELTA)		+= leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
-obj-$(CONFIG_LEDS_NET5501)		+= leds-net5501.o
 obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
 obj-$(CONFIG_LEDS_COBALT_QUBE)		+= leds-cobalt-qube.o
 obj-$(CONFIG_LEDS_COBALT_RAQ)		+= leds-cobalt-raq.o
@@ -31,6 +30,7 @@ obj-$(CONFIG_LEDS_HP6XX)		+= leds-hp6xx.o
 obj-$(CONFIG_LEDS_OT200)		+= leds-ot200.o
 obj-$(CONFIG_LEDS_FSG)			+= leds-fsg.o
 obj-$(CONFIG_LEDS_PCA955X)		+= leds-pca955x.o
+obj-$(CONFIG_LEDS_PCA9633)		+= leds-pca9633.o
 obj-$(CONFIG_LEDS_DA903X)		+= leds-da903x.o
 obj-$(CONFIG_LEDS_WM831X_STATUS)	+= leds-wm831x-status.o
 obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 7df74cb..f4c470a 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
@@ -20,8 +21,6 @@
 #include <linux/workqueue.h>
 #include <linux/module.h>
 
-#include <asm/gpio.h>
-
 struct gpio_led_data {
 	struct led_classdev cdev;
 	unsigned gpio;
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index e59c166..968fd5f 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -26,7 +26,6 @@
 #define LM3530_GEN_CONFIG		0x10
 #define LM3530_ALS_CONFIG		0x20
 #define LM3530_BRT_RAMP_RATE		0x30
-#define LM3530_ALS_ZONE_REG		0x40
 #define LM3530_ALS_IMP_SELECT		0x41
 #define LM3530_BRT_CTRL_REG		0xA0
 #define LM3530_ALS_ZB0_REG		0x60
@@ -38,7 +37,7 @@
 #define LM3530_ALS_Z2T_REG		0x72
 #define LM3530_ALS_Z3T_REG		0x73
 #define LM3530_ALS_Z4T_REG		0x74
-#define LM3530_REG_MAX			15
+#define LM3530_REG_MAX			14
 
 /* General Control Register */
 #define LM3530_EN_I2C_SHIFT		(0)
@@ -80,6 +79,9 @@
 #define LM3530_DEF_ZT_3			(0x33)
 #define LM3530_DEF_ZT_4			(0x19)
 
+/* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */
+#define MAX_BRIGHTNESS			(127)
+
 struct lm3530_mode_map {
 	const char *mode;
 	enum lm3530_mode mode_val;
@@ -115,7 +117,6 @@ static const u8 lm3530_reg[LM3530_REG_MAX] = {
 	LM3530_GEN_CONFIG,
 	LM3530_ALS_CONFIG,
 	LM3530_BRT_RAMP_RATE,
-	LM3530_ALS_ZONE_REG,
 	LM3530_ALS_IMP_SELECT,
 	LM3530_BRT_CTRL_REG,
 	LM3530_ALS_ZB0_REG,
@@ -152,27 +153,35 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
 	u8 reg_val[LM3530_REG_MAX];
 	u8 zones[LM3530_ALS_ZB_MAX];
 	u32 als_vmin, als_vmax, als_vstep;
-	struct lm3530_platform_data *pltfm = drvdata->pdata;
+	struct lm3530_platform_data *pdata = drvdata->pdata;
 	struct i2c_client *client = drvdata->client;
+	struct lm3530_pwm_data *pwm = &pdata->pwm_data;
 
-	gen_config = (pltfm->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
-			((pltfm->max_current & 7) << LM3530_MAX_CURR_SHIFT);
+	gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
+			((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT);
 
-	if (drvdata->mode == LM3530_BL_MODE_MANUAL ||
-	    drvdata->mode == LM3530_BL_MODE_ALS)
-		gen_config |= (LM3530_ENABLE_I2C);
+	switch (drvdata->mode) {
+	case LM3530_BL_MODE_MANUAL:
+	case LM3530_BL_MODE_ALS:
+		gen_config |= LM3530_ENABLE_I2C;
+		break;
+	case LM3530_BL_MODE_PWM:
+		gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE |
+			      (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT);
+		break;
+	}
 
 	if (drvdata->mode == LM3530_BL_MODE_ALS) {
-		if (pltfm->als_vmax == 0) {
-			pltfm->als_vmin = 0;
-			pltfm->als_vmax = LM3530_ALS_WINDOW_mV;
+		if (pdata->als_vmax == 0) {
+			pdata->als_vmin = 0;
+			pdata->als_vmax = LM3530_ALS_WINDOW_mV;
 		}
 
-		als_vmin = pltfm->als_vmin;
-		als_vmax = pltfm->als_vmax;
+		als_vmin = pdata->als_vmin;
+		als_vmax = pdata->als_vmax;
 
 		if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV)
-			pltfm->als_vmax = als_vmax =
+			pdata->als_vmax = als_vmax =
 				als_vmin + LM3530_ALS_WINDOW_mV;
 
 		/* n zone boundary makes n+1 zones */
@@ -184,44 +193,41 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
 					/ 1000;
 
 		als_config =
-			(pltfm->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
+			(pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
 			(LM3530_ENABLE_ALS) |
-			(pltfm->als_input_mode << LM3530_ALS_SEL_SHIFT);
+			(pdata->als_input_mode << LM3530_ALS_SEL_SHIFT);
 
 		als_imp_sel =
-			(pltfm->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
-			(pltfm->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
+			(pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
+			(pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
 
 	}
 
-	if (drvdata->mode == LM3530_BL_MODE_PWM)
-		gen_config |= (LM3530_ENABLE_PWM) |
-				(pltfm->pwm_pol_hi << LM3530_PWM_POL_SHIFT) |
-				(LM3530_ENABLE_PWM_SIMPLE);
-
-	brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
-			(pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
+	brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
+			(pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
 
 	if (drvdata->brightness)
 		brightness = drvdata->brightness;
 	else
-		brightness = drvdata->brightness = pltfm->brt_val;
+		brightness = drvdata->brightness = pdata->brt_val;
+
+	if (brightness > drvdata->led_dev.max_brightness)
+		brightness = drvdata->led_dev.max_brightness;
 
 	reg_val[0] = gen_config;	/* LM3530_GEN_CONFIG */
 	reg_val[1] = als_config;	/* LM3530_ALS_CONFIG */
 	reg_val[2] = brt_ramp;		/* LM3530_BRT_RAMP_RATE */
-	reg_val[3] = 0x00;		/* LM3530_ALS_ZONE_REG */
-	reg_val[4] = als_imp_sel;	/* LM3530_ALS_IMP_SELECT */
-	reg_val[5] = brightness;	/* LM3530_BRT_CTRL_REG */
-	reg_val[6] = zones[0];		/* LM3530_ALS_ZB0_REG */
-	reg_val[7] = zones[1];		/* LM3530_ALS_ZB1_REG */
-	reg_val[8] = zones[2];		/* LM3530_ALS_ZB2_REG */
-	reg_val[9] = zones[3];		/* LM3530_ALS_ZB3_REG */
-	reg_val[10] = LM3530_DEF_ZT_0;	/* LM3530_ALS_Z0T_REG */
-	reg_val[11] = LM3530_DEF_ZT_1;	/* LM3530_ALS_Z1T_REG */
-	reg_val[12] = LM3530_DEF_ZT_2;	/* LM3530_ALS_Z2T_REG */
-	reg_val[13] = LM3530_DEF_ZT_3;	/* LM3530_ALS_Z3T_REG */
-	reg_val[14] = LM3530_DEF_ZT_4;	/* LM3530_ALS_Z4T_REG */
+	reg_val[3] = als_imp_sel;	/* LM3530_ALS_IMP_SELECT */
+	reg_val[4] = brightness;	/* LM3530_BRT_CTRL_REG */
+	reg_val[5] = zones[0];		/* LM3530_ALS_ZB0_REG */
+	reg_val[6] = zones[1];		/* LM3530_ALS_ZB1_REG */
+	reg_val[7] = zones[2];		/* LM3530_ALS_ZB2_REG */
+	reg_val[8] = zones[3];		/* LM3530_ALS_ZB3_REG */
+	reg_val[9] = LM3530_DEF_ZT_0;	/* LM3530_ALS_Z0T_REG */
+	reg_val[10] = LM3530_DEF_ZT_1;	/* LM3530_ALS_Z1T_REG */
+	reg_val[11] = LM3530_DEF_ZT_2;	/* LM3530_ALS_Z2T_REG */
+	reg_val[12] = LM3530_DEF_ZT_3;	/* LM3530_ALS_Z3T_REG */
+	reg_val[13] = LM3530_DEF_ZT_4;	/* LM3530_ALS_Z4T_REG */
 
 	if (!drvdata->enable) {
 		ret = regulator_enable(drvdata->regulator);
@@ -234,6 +240,15 @@ static int lm3530_init_registers(struct lm3530_data *drvdata)
 	}
 
 	for (i = 0; i < LM3530_REG_MAX; i++) {
+		/* do not update brightness register when pwm mode */
+		if (lm3530_reg[i] == LM3530_BRT_CTRL_REG &&
+		    drvdata->mode == LM3530_BL_MODE_PWM) {
+			if (pwm->pwm_set_intensity)
+				pwm->pwm_set_intensity(reg_val[i],
+					drvdata->led_dev.max_brightness);
+			continue;
+		}
+
 		ret = i2c_smbus_write_byte_data(client,
 				lm3530_reg[i], reg_val[i]);
 		if (ret)
@@ -249,6 +264,9 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
 	int err;
 	struct lm3530_data *drvdata =
 	    container_of(led_cdev, struct lm3530_data, led_dev);
+	struct lm3530_platform_data *pdata = drvdata->pdata;
+	struct lm3530_pwm_data *pwm = &pdata->pwm_data;
+	u8 max_brightness = led_cdev->max_brightness;
 
 	switch (drvdata->mode) {
 	case LM3530_BL_MODE_MANUAL:
@@ -264,12 +282,12 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
 
 		/* set the brightness in brightness control register*/
 		err = i2c_smbus_write_byte_data(drvdata->client,
-				LM3530_BRT_CTRL_REG, brt_val / 2);
+				LM3530_BRT_CTRL_REG, brt_val);
 		if (err)
 			dev_err(&drvdata->client->dev,
 				"Unable to set brightness: %d\n", err);
 		else
-			drvdata->brightness = brt_val / 2;
+			drvdata->brightness = brt_val;
 
 		if (brt_val == 0) {
 			err = regulator_disable(drvdata->regulator);
@@ -282,6 +300,8 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
 	case LM3530_BL_MODE_ALS:
 		break;
 	case LM3530_BL_MODE_PWM:
+		if (pwm->pwm_set_intensity)
+			pwm->pwm_set_intensity(brt_val, max_brightness);
 		break;
 	default:
 		break;
@@ -291,11 +311,11 @@ static void lm3530_brightness_set(struct led_classdev *led_cdev,
 static ssize_t lm3530_mode_get(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
-	struct i2c_client *client = container_of(
-					dev->parent, struct i2c_client, dev);
-	struct lm3530_data *drvdata = i2c_get_clientdata(client);
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lm3530_data *drvdata;
 	int i, len = 0;
 
+	drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
 	for (i = 0; i < ARRAY_SIZE(mode_map); i++)
 		if (drvdata->mode == mode_map[i].mode_val)
 			len += sprintf(buf + len, "[%s] ", mode_map[i].mode);
@@ -310,26 +330,26 @@ static ssize_t lm3530_mode_get(struct device *dev,
 static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
 				   *attr, const char *buf, size_t size)
 {
-	int err;
-	struct i2c_client *client = container_of(
-					dev->parent, struct i2c_client, dev);
-	struct lm3530_data *drvdata = i2c_get_clientdata(client);
-	int mode;
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lm3530_data *drvdata;
+	struct lm3530_pwm_data *pwm;
+	u8 max_brightness;
+	int mode, err;
 
+	drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
+	pwm = &drvdata->pdata->pwm_data;
+	max_brightness = led_cdev->max_brightness;
 	mode = lm3530_get_mode_from_str(buf);
 	if (mode < 0) {
 		dev_err(dev, "Invalid mode\n");
 		return -EINVAL;
 	}
 
-	if (mode == LM3530_BL_MODE_MANUAL)
-		drvdata->mode = LM3530_BL_MODE_MANUAL;
-	else if (mode == LM3530_BL_MODE_ALS)
-		drvdata->mode = LM3530_BL_MODE_ALS;
-	else if (mode == LM3530_BL_MODE_PWM) {
-		dev_err(dev, "PWM mode not supported\n");
-		return -EINVAL;
-	}
+	drvdata->mode = mode;
+
+	/* set pwm to low if unnecessary */
+	if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity)
+		pwm->pwm_set_intensity(0, max_brightness);
 
 	err = lm3530_init_registers(drvdata);
 	if (err) {
@@ -380,6 +400,7 @@ static int __devinit lm3530_probe(struct i2c_client *client,
 	drvdata->enable = false;
 	drvdata->led_dev.name = LM3530_LED_DEV;
 	drvdata->led_dev.brightness_set = lm3530_brightness_set;
+	drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
 
 	i2c_set_clientdata(client, drvdata);
 
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index d62a798..de7b8fe 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -81,18 +81,10 @@
 #define LP5521_MASTER_ENABLE		0x40	/* Chip master enable */
 #define LP5521_LOGARITHMIC_PWM		0x80	/* Logarithmic PWM adjustment */
 #define LP5521_EXEC_RUN			0x2A
-
-/* Bits in CONFIG register */
-#define LP5521_PWM_HF			0x40	/* PWM: 0 = 256Hz, 1 = 558Hz */
-#define LP5521_PWRSAVE_EN		0x20	/* 1 = Power save mode */
-#define LP5521_CP_MODE_OFF		0	/* Charge pump (CP) off */
-#define LP5521_CP_MODE_BYPASS		8	/* CP forced to bypass mode */
-#define LP5521_CP_MODE_1X5		0x10	/* CP forced to 1.5x mode */
-#define LP5521_CP_MODE_AUTO		0x18	/* Automatic mode selection */
-#define LP5521_R_TO_BATT		4	/* R out: 0 = CP, 1 = Vbat */
-#define LP5521_CLK_SRC_EXT		0	/* Ext-clk source (CLK_32K) */
-#define LP5521_CLK_INT			1	/* Internal clock */
-#define LP5521_CLK_AUTO			2	/* Automatic clock selection */
+#define LP5521_ENABLE_DEFAULT	\
+	(LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)
+#define LP5521_ENABLE_RUN_PROGRAM	\
+	(LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
 
 /* Status */
 #define LP5521_EXT_CLK_USED		0x08
@@ -100,6 +92,9 @@
 /* default R channel current register value */
 #define LP5521_REG_R_CURR_DEFAULT	0xAF
 
+/* Pattern Mode */
+#define PATTERN_OFF	0
+
 struct lp5521_engine {
 	int		id;
 	u8		mode;
@@ -241,15 +236,16 @@ static int lp5521_configure(struct i2c_client *client)
 {
 	struct lp5521_chip *chip = i2c_get_clientdata(client);
 	int ret;
+	u8 cfg;
 
 	lp5521_init_engine(chip);
 
 	/* Set all PWMs to direct control mode */
-	ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
+	ret = lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
 
-	/* Enable auto-powersave, set charge pump to auto, red to battery */
-	ret |= lp5521_write(client, LP5521_REG_CONFIG,
-		LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
+	cfg = chip->pdata->update_config ?
+		: (LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO | LP5521_R_TO_BATT);
+	ret |= lp5521_write(client, LP5521_REG_CONFIG, cfg);
 
 	/* Initialize all channels PWM to zero -> leds off */
 	ret |= lp5521_write(client, LP5521_REG_R_PWM, 0);
@@ -258,8 +254,7 @@ static int lp5521_configure(struct i2c_client *client)
 
 	/* Set engines are set to run state when OP_MODE enables engines */
 	ret |= lp5521_write(client, LP5521_REG_ENABLE,
-			LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
-			LP5521_EXEC_RUN);
+			LP5521_ENABLE_RUN_PROGRAM);
 	/* enable takes 500us. 1 - 2 ms leaves some margin */
 	usleep_range(1000, 2000);
 
@@ -310,8 +305,7 @@ static int lp5521_detect(struct i2c_client *client)
 	int ret;
 	u8 buf;
 
-	ret = lp5521_write(client, LP5521_REG_ENABLE,
-			LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
+	ret = lp5521_write(client, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
 	if (ret)
 		return ret;
 	/* enable takes 500us. 1 - 2 ms leaves some margin */
@@ -319,7 +313,7 @@ static int lp5521_detect(struct i2c_client *client)
 	ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
 	if (ret)
 		return ret;
-	if (buf != (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM))
+	if (buf != LP5521_ENABLE_DEFAULT)
 		return -ENODEV;
 
 	return 0;
@@ -504,7 +498,7 @@ static ssize_t store_current(struct device *dev,
 	ssize_t ret;
 	unsigned long curr;
 
-	if (strict_strtoul(buf, 0, &curr))
+	if (kstrtoul(buf, 0, &curr))
 		return -EINVAL;
 
 	if (curr > led->max_current)
@@ -536,6 +530,97 @@ static ssize_t lp5521_selftest(struct device *dev,
 	return sprintf(buf, "%s\n", ret ? "FAIL" : "OK");
 }
 
+static void lp5521_clear_program_memory(struct i2c_client *cl)
+{
+	int i;
+	u8 rgb_mem[] = {
+		LP5521_REG_R_PROG_MEM,
+		LP5521_REG_G_PROG_MEM,
+		LP5521_REG_B_PROG_MEM,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(rgb_mem); i++) {
+		lp5521_write(cl, rgb_mem[i], 0);
+		lp5521_write(cl, rgb_mem[i] + 1, 0);
+	}
+}
+
+static void lp5521_write_program_memory(struct i2c_client *cl,
+				u8 base, u8 *rgb, int size)
+{
+	int i;
+
+	if (!rgb || size <= 0)
+		return;
+
+	for (i = 0; i < size; i++)
+		lp5521_write(cl, base + i, *(rgb + i));
+
+	lp5521_write(cl, base + i, 0);
+	lp5521_write(cl, base + i + 1, 0);
+}
+
+static inline struct lp5521_led_pattern *lp5521_get_pattern
+					(struct lp5521_chip *chip, u8 offset)
+{
+	struct lp5521_led_pattern *ptn;
+	ptn = chip->pdata->patterns + (offset - 1);
+	return ptn;
+}
+
+static void lp5521_run_led_pattern(int mode, struct lp5521_chip *chip)
+{
+	struct lp5521_led_pattern *ptn;
+	struct i2c_client *cl = chip->client;
+	int num_patterns = chip->pdata->num_patterns;
+
+	if (mode > num_patterns || !(chip->pdata->patterns))
+		return;
+
+	if (mode == PATTERN_OFF) {
+		lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_DEFAULT);
+		usleep_range(1000, 2000);
+		lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
+	} else {
+		ptn = lp5521_get_pattern(chip, mode);
+		if (!ptn)
+			return;
+
+		lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
+		usleep_range(1000, 2000);
+
+		lp5521_clear_program_memory(cl);
+
+		lp5521_write_program_memory(cl, LP5521_REG_R_PROG_MEM,
+					ptn->r, ptn->size_r);
+		lp5521_write_program_memory(cl, LP5521_REG_G_PROG_MEM,
+					ptn->g, ptn->size_g);
+		lp5521_write_program_memory(cl, LP5521_REG_B_PROG_MEM,
+					ptn->b, ptn->size_b);
+
+		lp5521_write(cl, LP5521_REG_OP_MODE, LP5521_CMD_RUN);
+		usleep_range(1000, 2000);
+		lp5521_write(cl, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM);
+	}
+}
+
+static ssize_t store_led_pattern(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t len)
+{
+	struct lp5521_chip *chip = i2c_get_clientdata(to_i2c_client(dev));
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	lp5521_run_led_pattern(val, chip);
+
+	return len;
+}
+
 /* led class device attributes */
 static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current);
 static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL);
@@ -561,6 +646,7 @@ static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load);
 static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load);
 static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load);
 static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
+static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, store_led_pattern);
 
 static struct attribute *lp5521_attributes[] = {
 	&dev_attr_engine1_mode.attr,
@@ -570,6 +656,7 @@ static struct attribute *lp5521_attributes[] = {
 	&dev_attr_engine1_load.attr,
 	&dev_attr_engine2_load.attr,
 	&dev_attr_engine3_load.attr,
+	&dev_attr_led_pattern.attr,
 	NULL
 };
 
@@ -620,10 +707,15 @@ static int __devinit lp5521_init_led(struct lp5521_led *led,
 		return -EINVAL;
 	}
 
-	snprintf(name, sizeof(name), "%s:channel%d",
-			pdata->label ?: client->name, chan);
 	led->cdev.brightness_set = lp5521_set_brightness;
-	led->cdev.name = name;
+	if (pdata->led_config[chan].name) {
+		led->cdev.name = pdata->led_config[chan].name;
+	} else {
+		snprintf(name, sizeof(name), "%s:channel%d",
+			pdata->label ?: client->name, chan);
+		led->cdev.name = name;
+	}
+
 	res = led_classdev_register(dev, &led->cdev);
 	if (res < 0) {
 		dev_err(dev, "couldn't register led on channel %d\n", chan);
@@ -694,7 +786,7 @@ static int __devinit lp5521_probe(struct i2c_client *client,
 	 */
 	lp5521_read(client, LP5521_REG_R_CURRENT, &buf);
 	if (buf != LP5521_REG_R_CURR_DEFAULT) {
-		dev_err(&client->dev, "error in reseting chip\n");
+		dev_err(&client->dev, "error in resetting chip\n");
 		goto fail2;
 	}
 	usleep_range(10000, 20000);
@@ -767,6 +859,7 @@ static int __devexit lp5521_remove(struct i2c_client *client)
 	struct lp5521_chip *chip = i2c_get_clientdata(client);
 	int i;
 
+	lp5521_run_led_pattern(PATTERN_OFF, chip);
 	lp5521_unregister_sysfs(client);
 
 	for (i = 0; i < chip->num_leds; i++) {
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 73e791a..857a3e1 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -152,7 +152,7 @@ static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
 
 static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
 static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
-static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern);
+static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern);
 
 static void lp5523_led_brightness_work(struct work_struct *work);
 
@@ -196,7 +196,7 @@ static int lp5523_configure(struct i2c_client *client)
 	u8 status;
 
 	/* one pattern per engine setting led mux start and stop addresses */
-	u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
+	static const u8 pattern[][LP5523_PROGRAM_LENGTH] =  {
 		{ 0x9c, 0x30, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
 		{ 0x9c, 0x40, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
 		{ 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
@@ -301,7 +301,7 @@ static int lp5523_load_mux(struct lp5523_engine *engine, u16 mux)
 	return ret;
 }
 
-static int lp5523_load_program(struct lp5523_engine *engine, u8 *pattern)
+static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern)
 {
 	struct lp5523_chip *chip = engine_to_lp5523(engine);
 	struct i2c_client *client = chip->client;
diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c
deleted file mode 100644
index 0555d47..0000000
--- a/drivers/leds/leds-net5501.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Soekris board support code
- *
- * Copyright (C) 2008-2009 Tower Technologies
- * Written by Alessandro Zummo <a.zummo@towertech.it>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/string.h>
-#include <linux/leds.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/module.h>
-
-#include <asm/geode.h>
-
-static const struct gpio_led net5501_leds[] = {
-	{
-		.name = "error",
-		.gpio = 6,
-		.default_trigger = "default-on",
-	},
-};
-
-static struct gpio_led_platform_data net5501_leds_data = {
-	.num_leds = ARRAY_SIZE(net5501_leds),
-	.leds = net5501_leds,
-};
-
-static struct platform_device net5501_leds_dev = {
-	.name = "leds-gpio",
-	.id = -1,
-	.dev.platform_data = &net5501_leds_data,
-};
-
-static void __init init_net5501(void)
-{
-	platform_device_register(&net5501_leds_dev);
-}
-
-struct soekris_board {
-	u16	offset;
-	char	*sig;
-	u8	len;
-	void	(*init)(void);
-};
-
-static struct soekris_board __initdata boards[] = {
-	{ 0xb7b, "net5501", 7, init_net5501 },	/* net5501 v1.33/1.33c */
-	{ 0xb1f, "net5501", 7, init_net5501 },	/* net5501 v1.32i */
-};
-
-static int __init soekris_init(void)
-{
-	int i;
-	unsigned char *rombase, *bios;
-
-	if (!is_geode())
-		return 0;
-
-	rombase = ioremap(0xffff0000, 0xffff);
-	if (!rombase) {
-		printk(KERN_INFO "Soekris net5501 LED driver failed to get rombase");
-		return 0;
-	}
-
-	bios = rombase + 0x20;	/* null terminated */
-
-	if (strncmp(bios, "comBIOS", 7))
-		goto unmap;
-
-	for (i = 0; i < ARRAY_SIZE(boards); i++) {
-		unsigned char *model = rombase + boards[i].offset;
-
-		if (strncmp(model, boards[i].sig, boards[i].len) == 0) {
-			printk(KERN_INFO "Soekris %s: %s\n", model, bios);
-
-			if (boards[i].init)
-				boards[i].init();
-			break;
-		}
-	}
-
-unmap:
-	iounmap(rombase);
-	return 0;
-}
-
-arch_initcall(soekris_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
new file mode 100644
index 0000000..02889bb
--- /dev/null
+++ b/drivers/leds/leds-pca9633.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2011 bct electronic GmbH
+ *
+ * Author: Peter Meerwald <p.meerwald@bct-electronic.com>
+ *
+ * Based on leds-pca955x.c
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+
+/* LED select registers determine the source that drives LED outputs */
+#define PCA9633_LED_OFF		0x0	/* LED driver off */
+#define PCA9633_LED_ON		0x1	/* LED driver on */
+#define PCA9633_LED_PWM		0x2	/* Controlled through PWM */
+#define PCA9633_LED_GRP_PWM	0x3	/* Controlled through PWM/GRPPWM */
+
+#define PCA9633_MODE1		0x00
+#define PCA9633_MODE2		0x01
+#define PCA9633_PWM_BASE	0x02
+#define PCA9633_LEDOUT		0x08
+
+static const struct i2c_device_id pca9633_id[] = {
+	{ "pca9633", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, pca9633_id);
+
+struct pca9633_led {
+	struct i2c_client *client;
+	struct work_struct work;
+	enum led_brightness brightness;
+	struct led_classdev led_cdev;
+	int led_num; /* 0 .. 3 potentially */
+	char name[32];
+};
+
+static void pca9633_led_work(struct work_struct *work)
+{
+	struct pca9633_led *pca9633 = container_of(work,
+		struct pca9633_led, work);
+	u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
+	int shift = 2 * pca9633->led_num;
+	u8 mask = 0x3 << shift;
+
+	switch (pca9633->brightness) {
+	case LED_FULL:
+		i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
+			(ledout & ~mask) | (PCA9633_LED_ON << shift));
+		break;
+	case LED_OFF:
+		i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
+			ledout & ~mask);
+		break;
+	default:
+		i2c_smbus_write_byte_data(pca9633->client,
+			PCA9633_PWM_BASE + pca9633->led_num,
+			pca9633->brightness);
+		i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
+			(ledout & ~mask) | (PCA9633_LED_PWM << shift));
+		break;
+	}
+}
+
+static void pca9633_led_set(struct led_classdev *led_cdev,
+	enum led_brightness value)
+{
+	struct pca9633_led *pca9633;
+
+	pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
+
+	pca9633->brightness = value;
+
+	/*
+	 * Must use workqueue for the actual I/O since I2C operations
+	 * can sleep.
+	 */
+	schedule_work(&pca9633->work);
+}
+
+static int __devinit pca9633_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct pca9633_led *pca9633;
+	struct led_platform_data *pdata;
+	int i, err;
+
+	pdata = client->dev.platform_data;
+
+	if (pdata) {
+		if (pdata->num_leds <= 0 || pdata->num_leds > 4) {
+			dev_err(&client->dev, "board info must claim at most 4 LEDs");
+			return -EINVAL;
+		}
+	}
+
+	pca9633 = kcalloc(sizeof(*pca9633), 4, GFP_KERNEL);
+	if (!pca9633)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, pca9633);
+
+	for (i = 0; i < 4; i++) {
+		pca9633[i].client = client;
+		pca9633[i].led_num = i;
+
+		/* Platform data can specify LED names and default triggers */
+		if (pdata && i < pdata->num_leds) {
+			if (pdata->leds[i].name)
+				snprintf(pca9633[i].name,
+					 sizeof(pca9633[i].name), "pca9633:%s",
+					 pdata->leds[i].name);
+			if (pdata->leds[i].default_trigger)
+				pca9633[i].led_cdev.default_trigger =
+					pdata->leds[i].default_trigger;
+		} else {
+			snprintf(pca9633[i].name, sizeof(pca9633[i].name),
+				 "pca9633:%d", i);
+		}
+
+		pca9633[i].led_cdev.name = pca9633[i].name;
+		pca9633[i].led_cdev.brightness_set = pca9633_led_set;
+
+		INIT_WORK(&pca9633[i].work, pca9633_led_work);
+
+		err = led_classdev_register(&client->dev, &pca9633[i].led_cdev);
+		if (err < 0)
+			goto exit;
+	}
+
+	/* Disable LED all-call address and set normal mode */
+	i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
+
+	/* Turn off LEDs */
+	i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
+
+	return 0;
+
+exit:
+	while (i--) {
+		led_classdev_unregister(&pca9633[i].led_cdev);
+		cancel_work_sync(&pca9633[i].work);
+	}
+
+	kfree(pca9633);
+
+	return err;
+}
+
+static int __devexit pca9633_remove(struct i2c_client *client)
+{
+	struct pca9633_led *pca9633 = i2c_get_clientdata(client);
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		led_classdev_unregister(&pca9633[i].led_cdev);
+		cancel_work_sync(&pca9633[i].work);
+	}
+
+	kfree(pca9633);
+
+	return 0;
+}
+
+static struct i2c_driver pca9633_driver = {
+	.driver = {
+		.name	= "leds-pca9633",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= pca9633_probe,
+	.remove	= __devexit_p(pca9633_remove),
+	.id_table = pca9633_id,
+};
+
+module_i2c_driver(pca9633_driver);
+
+MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
+MODULE_DESCRIPTION("PCA9633 LED driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
index 133f89f..ec06a81 100644
--- a/drivers/leds/leds-tca6507.c
+++ b/drivers/leds/leds-tca6507.c
@@ -687,10 +687,9 @@ static int __devinit tca6507_probe(struct i2c_client *client,
 			NUM_LEDS);
 		return -ENODEV;
 	}
-	err = -ENOMEM;
 	tca = kzalloc(sizeof(*tca), GFP_KERNEL);
 	if (!tca)
-		goto exit;
+		return -ENOMEM;
 
 	tca->client = client;
 	INIT_WORK(&tca->work, tca6507_work);
@@ -724,11 +723,10 @@ static int __devinit tca6507_probe(struct i2c_client *client,
 
 	return 0;
 exit:
-	while (i--)
+	while (i--) {
 		if (tca->leds[i].led_cdev.name)
 			led_classdev_unregister(&tca->leds[i].led_cdev);
-	cancel_work_sync(&tca->work);
-	i2c_set_clientdata(client, NULL);
+	}
 	kfree(tca);
 	return err;
 }
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 4daf9e5..20e5c2c 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -137,7 +137,7 @@ extern struct device_attribute macio_dev_attrs[];
 struct bus_type macio_bus_type = {
        .name	= "macio",
        .match	= macio_bus_match,
-       .uevent = of_device_uevent,
+       .uevent = of_device_uevent_modalias,
        .probe	= macio_device_probe,
        .remove	= macio_device_remove,
        .shutdown = macio_device_shutdown,
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 2fd435b..831d751 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -356,7 +356,7 @@ static void poll_media_bay(struct media_bay_info* bay)
 	static char *mb_content_types[] = {
 		"a floppy drive",
 		"a floppy drive",
-		"an unsuported audio device",
+		"an unsupported audio device",
 		"an ATA device",
 		"an unsupported PCI device",
 		"an unknown device",
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index cdf36b1..045e086 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -457,7 +457,7 @@ void bitmap_update_sb(struct bitmap *bitmap)
 		return;
 	}
 	spin_unlock_irqrestore(&bitmap->lock, flags);
-	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+	sb = kmap_atomic(bitmap->sb_page);
 	sb->events = cpu_to_le64(bitmap->mddev->events);
 	if (bitmap->mddev->events < bitmap->events_cleared)
 		/* rocking back to read-only */
@@ -467,7 +467,7 @@ void bitmap_update_sb(struct bitmap *bitmap)
 	/* Just in case these have been changed via sysfs: */
 	sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
 	sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
-	kunmap_atomic(sb, KM_USER0);
+	kunmap_atomic(sb);
 	write_page(bitmap, bitmap->sb_page, 1);
 }
 
@@ -478,7 +478,7 @@ void bitmap_print_sb(struct bitmap *bitmap)
 
 	if (!bitmap || !bitmap->sb_page)
 		return;
-	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+	sb = kmap_atomic(bitmap->sb_page);
 	printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap));
 	printk(KERN_DEBUG "         magic: %08x\n", le32_to_cpu(sb->magic));
 	printk(KERN_DEBUG "       version: %d\n", le32_to_cpu(sb->version));
@@ -497,7 +497,7 @@ void bitmap_print_sb(struct bitmap *bitmap)
 	printk(KERN_DEBUG "     sync size: %llu KB\n",
 			(unsigned long long)le64_to_cpu(sb->sync_size)/2);
 	printk(KERN_DEBUG "max write behind: %d\n", le32_to_cpu(sb->write_behind));
-	kunmap_atomic(sb, KM_USER0);
+	kunmap_atomic(sb);
 }
 
 /*
@@ -525,7 +525,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
 	}
 	bitmap->sb_page->index = 0;
 
-	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+	sb = kmap_atomic(bitmap->sb_page);
 
 	sb->magic = cpu_to_le32(BITMAP_MAGIC);
 	sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
@@ -533,7 +533,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
 	chunksize = bitmap->mddev->bitmap_info.chunksize;
 	BUG_ON(!chunksize);
 	if (!is_power_of_2(chunksize)) {
-		kunmap_atomic(sb, KM_USER0);
+		kunmap_atomic(sb);
 		printk(KERN_ERR "bitmap chunksize not a power of 2\n");
 		return -EINVAL;
 	}
@@ -571,7 +571,7 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap)
 	bitmap->flags |= BITMAP_HOSTENDIAN;
 	sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
 
-	kunmap_atomic(sb, KM_USER0);
+	kunmap_atomic(sb);
 
 	return 0;
 }
@@ -603,7 +603,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
 		return err;
 	}
 
-	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+	sb = kmap_atomic(bitmap->sb_page);
 
 	chunksize = le32_to_cpu(sb->chunksize);
 	daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;
@@ -664,7 +664,7 @@ success:
 		bitmap->events_cleared = bitmap->mddev->events;
 	err = 0;
 out:
-	kunmap_atomic(sb, KM_USER0);
+	kunmap_atomic(sb);
 	if (err)
 		bitmap_print_sb(bitmap);
 	return err;
@@ -689,7 +689,7 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
 		return 0;
 	}
 	spin_unlock_irqrestore(&bitmap->lock, flags);
-	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+	sb = kmap_atomic(bitmap->sb_page);
 	old = le32_to_cpu(sb->state) & bits;
 	switch (op) {
 	case MASK_SET:
@@ -703,7 +703,7 @@ static int bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
 	default:
 		BUG();
 	}
-	kunmap_atomic(sb, KM_USER0);
+	kunmap_atomic(sb);
 	return old;
 }
 
@@ -881,12 +881,12 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
 	bit = file_page_offset(bitmap, chunk);
 
 	/* set the bit */
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	if (bitmap->flags & BITMAP_HOSTENDIAN)
 		set_bit(bit, kaddr);
 	else
 		__set_bit_le(bit, kaddr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	pr_debug("set file bit %lu page %lu\n", bit, page->index);
 	/* record page number so it gets flushed to disk when unplug occurs */
 	set_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
@@ -1050,10 +1050,10 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 				 * if bitmap is out of date, dirty the
 				 * whole page and write it out
 				 */
-				paddr = kmap_atomic(page, KM_USER0);
+				paddr = kmap_atomic(page);
 				memset(paddr + offset, 0xff,
 				       PAGE_SIZE - offset);
-				kunmap_atomic(paddr, KM_USER0);
+				kunmap_atomic(paddr);
 				write_page(bitmap, page, 1);
 
 				ret = -EIO;
@@ -1061,12 +1061,12 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
 					goto err;
 			}
 		}
-		paddr = kmap_atomic(page, KM_USER0);
+		paddr = kmap_atomic(page);
 		if (bitmap->flags & BITMAP_HOSTENDIAN)
 			b = test_bit(bit, paddr);
 		else
 			b = test_bit_le(bit, paddr);
-		kunmap_atomic(paddr, KM_USER0);
+		kunmap_atomic(paddr);
 		if (b) {
 			/* if the disk bit is set, set the memory bit */
 			int needed = ((sector_t)(i+1) << (CHUNK_BLOCK_SHIFT(bitmap))
@@ -1209,10 +1209,10 @@ void bitmap_daemon_work(struct mddev *mddev)
 			    mddev->bitmap_info.external == 0) {
 				bitmap_super_t *sb;
 				bitmap->need_sync = 0;
-				sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+				sb = kmap_atomic(bitmap->sb_page);
 				sb->events_cleared =
 					cpu_to_le64(bitmap->events_cleared);
-				kunmap_atomic(sb, KM_USER0);
+				kunmap_atomic(sb);
 				write_page(bitmap, bitmap->sb_page, 1);
 			}
 			spin_lock_irqsave(&bitmap->lock, flags);
@@ -1235,7 +1235,7 @@ void bitmap_daemon_work(struct mddev *mddev)
 						  -1);
 
 				/* clear the bit */
-				paddr = kmap_atomic(page, KM_USER0);
+				paddr = kmap_atomic(page);
 				if (bitmap->flags & BITMAP_HOSTENDIAN)
 					clear_bit(file_page_offset(bitmap, j),
 						  paddr);
@@ -1244,7 +1244,7 @@ void bitmap_daemon_work(struct mddev *mddev)
 						file_page_offset(bitmap,
 								 j),
 						paddr);
-				kunmap_atomic(paddr, KM_USER0);
+				kunmap_atomic(paddr);
 			} else if (*bmc <= 2) {
 				*bmc = 1; /* maybe clear the bit next time */
 				set_page_attr(bitmap, page, BITMAP_PAGE_PENDING);
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 0a6806f..b6e58c7 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -12,7 +12,6 @@
 #include <linux/dm-io.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/version.h>
 #include <linux/shrinker.h>
 #include <linux/module.h>
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 8c2a000..db6b516 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -590,9 +590,9 @@ static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 *iv,
 	int r = 0;
 
 	if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) {
-		src = kmap_atomic(sg_page(&dmreq->sg_in), KM_USER0);
+		src = kmap_atomic(sg_page(&dmreq->sg_in));
 		r = crypt_iv_lmk_one(cc, iv, dmreq, src + dmreq->sg_in.offset);
-		kunmap_atomic(src, KM_USER0);
+		kunmap_atomic(src);
 	} else
 		memset(iv, 0, cc->iv_size);
 
@@ -608,14 +608,14 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv,
 	if (bio_data_dir(dmreq->ctx->bio_in) == WRITE)
 		return 0;
 
-	dst = kmap_atomic(sg_page(&dmreq->sg_out), KM_USER0);
+	dst = kmap_atomic(sg_page(&dmreq->sg_out));
 	r = crypt_iv_lmk_one(cc, iv, dmreq, dst + dmreq->sg_out.offset);
 
 	/* Tweak the first block of plaintext sector */
 	if (!r)
 		crypto_xor(dst + dmreq->sg_out.offset, iv, cc->iv_size);
 
-	kunmap_atomic(dst, KM_USER0);
+	kunmap_atomic(dst);
 	return r;
 }
 
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index ad2eba4..ea5dd28 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -296,6 +296,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
 	unsigned offset;
 	unsigned num_bvecs;
 	sector_t remaining = where->count;
+	struct request_queue *q = bdev_get_queue(where->bdev);
+	sector_t discard_sectors;
 
 	/*
 	 * where->count may be zero if rw holds a flush and we need to
@@ -305,9 +307,12 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
 		/*
 		 * Allocate a suitably sized-bio.
 		 */
-		num_bvecs = dm_sector_div_up(remaining,
-					     (PAGE_SIZE >> SECTOR_SHIFT));
-		num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs);
+		if (rw & REQ_DISCARD)
+			num_bvecs = 1;
+		else
+			num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev),
+					  dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT)));
+
 		bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios);
 		bio->bi_sector = where->sector + (where->count - remaining);
 		bio->bi_bdev = where->bdev;
@@ -315,10 +320,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
 		bio->bi_destructor = dm_bio_destructor;
 		store_io_and_region_in_bio(bio, io, region);
 
-		/*
-		 * Try and add as many pages as possible.
-		 */
-		while (remaining) {
+		if (rw & REQ_DISCARD) {
+			discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
+			bio->bi_size = discard_sectors << SECTOR_SHIFT;
+			remaining -= discard_sectors;
+		} else while (remaining) {
+			/*
+			 * Try and add as many pages as possible.
+			 */
 			dp->get_page(dp, &page, &len, &offset);
 			len = min(len, to_bytes(remaining));
 			if (!bio_add_page(bio, page, len, offset))
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 31c2dc2..1ce84ed 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1437,7 +1437,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
 
 	if (!argc) {
 		DMWARN("Empty message received.");
-		goto out;
+		goto out_argv;
 	}
 
 	table = dm_get_live_table(md);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 801d92d..31cf495 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -920,8 +920,10 @@ static int multipath_map(struct dm_target *ti, struct request *clone,
 	map_context->ptr = mpio;
 	clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
 	r = map_io(m, clone, mpio, 0);
-	if (r < 0 || r == DM_MAPIO_REQUEUE)
+	if (r < 0 || r == DM_MAPIO_REQUEUE) {
 		mempool_free(mpio, m->mpio_pool);
+		map_context->ptr = NULL;
+	}
 
 	return r;
 }
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 86cb7e5..9861c32 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -604,7 +604,9 @@ static int read_disk_sb(struct md_rdev *rdev, int size)
 		return 0;
 
 	if (!sync_page_io(rdev, 0, size, rdev->sb_page, READ, 1)) {
-		DMERR("Failed to read device superblock");
+		DMERR("Failed to read superblock of device at position %d",
+		      rdev->raid_disk);
+		set_bit(Faulty, &rdev->flags);
 		return -EINVAL;
 	}
 
@@ -668,7 +670,14 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
 		return ret;
 
 	sb = page_address(rdev->sb_page);
-	if (sb->magic != cpu_to_le32(DM_RAID_MAGIC)) {
+
+	/*
+	 * Two cases that we want to write new superblocks and rebuild:
+	 * 1) New device (no matching magic number)
+	 * 2) Device specified for rebuild (!In_sync w/ offset == 0)
+	 */
+	if ((sb->magic != cpu_to_le32(DM_RAID_MAGIC)) ||
+	    (!test_bit(In_sync, &rdev->flags) && !rdev->recovery_offset)) {
 		super_sync(rdev->mddev, rdev);
 
 		set_bit(FirstUse, &rdev->flags);
@@ -745,11 +754,8 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev)
 	 */
 	rdev_for_each(r, t, mddev) {
 		if (!test_bit(In_sync, &r->flags)) {
-			if (!test_bit(FirstUse, &r->flags))
-				DMERR("Superblock area of "
-				      "rebuild device %d should have been "
-				      "cleared.", r->raid_disk);
-			set_bit(FirstUse, &r->flags);
+			DMINFO("Device %d specified for rebuild: "
+			       "Clearing superblock", r->raid_disk);
 			rebuilds++;
 		} else if (test_bit(FirstUse, &r->flags))
 			new_devs++;
@@ -851,9 +857,25 @@ static int super_validate(struct mddev *mddev, struct md_rdev *rdev)
 static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
 {
 	int ret;
+	unsigned redundancy = 0;
+	struct raid_dev *dev;
 	struct md_rdev *rdev, *freshest, *tmp;
 	struct mddev *mddev = &rs->md;
 
+	switch (rs->raid_type->level) {
+	case 1:
+		redundancy = rs->md.raid_disks - 1;
+		break;
+	case 4:
+	case 5:
+	case 6:
+		redundancy = rs->raid_type->parity_devs;
+		break;
+	default:
+		ti->error = "Unknown RAID type";
+		return -EINVAL;
+	}
+
 	freshest = NULL;
 	rdev_for_each(rdev, tmp, mddev) {
 		if (!rdev->meta_bdev)
@@ -868,6 +890,37 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
 		case 0:
 			break;
 		default:
+			dev = container_of(rdev, struct raid_dev, rdev);
+			if (redundancy--) {
+				if (dev->meta_dev)
+					dm_put_device(ti, dev->meta_dev);
+
+				dev->meta_dev = NULL;
+				rdev->meta_bdev = NULL;
+
+				if (rdev->sb_page)
+					put_page(rdev->sb_page);
+
+				rdev->sb_page = NULL;
+
+				rdev->sb_loaded = 0;
+
+				/*
+				 * We might be able to salvage the data device
+				 * even though the meta device has failed.  For
+				 * now, we behave as though '- -' had been
+				 * set for this device in the table.
+				 */
+				if (dev->data_dev)
+					dm_put_device(ti, dev->data_dev);
+
+				dev->data_dev = NULL;
+				rdev->bdev = NULL;
+
+				list_del(&rdev->same_set);
+
+				continue;
+			}
 			ti->error = "Failed to load superblock";
 			return ret;
 		}
@@ -1209,7 +1262,7 @@ static void raid_resume(struct dm_target *ti)
 
 static struct target_type raid_target = {
 	.name = "raid",
-	.version = {1, 1, 0},
+	.version = {1, 2, 0},
 	.module = THIS_MODULE,
 	.ctr = raid_ctr,
 	.dtr = raid_dtr,
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
index 59c4f04..237571a 100644
--- a/drivers/md/dm-thin-metadata.c
+++ b/drivers/md/dm-thin-metadata.c
@@ -385,6 +385,7 @@ static int init_pmd(struct dm_pool_metadata *pmd,
 		data_sm = dm_sm_disk_create(tm, nr_blocks);
 		if (IS_ERR(data_sm)) {
 			DMERR("sm_disk_create failed");
+			dm_tm_unlock(tm, sblock);
 			r = PTR_ERR(data_sm);
 			goto bad;
 		}
@@ -789,6 +790,11 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
 	return 0;
 }
 
+/*
+ * __open_device: Returns @td corresponding to device with id @dev,
+ * creating it if @create is set and incrementing @td->open_count.
+ * On failure, @td is undefined.
+ */
 static int __open_device(struct dm_pool_metadata *pmd,
 			 dm_thin_id dev, int create,
 			 struct dm_thin_device **td)
@@ -799,10 +805,16 @@ static int __open_device(struct dm_pool_metadata *pmd,
 	struct disk_device_details details_le;
 
 	/*
-	 * Check the device isn't already open.
+	 * If the device is already open, return it.
 	 */
 	list_for_each_entry(td2, &pmd->thin_devices, list)
 		if (td2->id == dev) {
+			/*
+			 * May not create an already-open device.
+			 */
+			if (create)
+				return -EEXIST;
+
 			td2->open_count++;
 			*td = td2;
 			return 0;
@@ -817,6 +829,9 @@ static int __open_device(struct dm_pool_metadata *pmd,
 		if (r != -ENODATA || !create)
 			return r;
 
+		/*
+		 * Create new device.
+		 */
 		changed = 1;
 		details_le.mapped_blocks = 0;
 		details_le.transaction_id = cpu_to_le64(pmd->trans_id);
@@ -882,12 +897,10 @@ static int __create_thin(struct dm_pool_metadata *pmd,
 
 	r = __open_device(pmd, dev, 1, &td);
 	if (r) {
-		__close_device(td);
 		dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
 		dm_btree_del(&pmd->bl_info, dev_root);
 		return r;
 	}
-	td->changed = 1;
 	__close_device(td);
 
 	return r;
@@ -967,14 +980,14 @@ static int __create_snap(struct dm_pool_metadata *pmd,
 		goto bad;
 
 	r = __set_snapshot_details(pmd, td, origin, pmd->time);
+	__close_device(td);
+
 	if (r)
 		goto bad;
 
-	__close_device(td);
 	return 0;
 
 bad:
-	__close_device(td);
 	dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root);
 	dm_btree_remove(&pmd->details_info, pmd->details_root,
 			&key, &pmd->details_root);
@@ -1211,6 +1224,8 @@ static int __remove(struct dm_thin_device *td, dm_block_t block)
 	if (r)
 		return r;
 
+	td->mapped_blocks--;
+	td->changed = 1;
 	pmd->need_commit = 1;
 
 	return 0;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index c308757..920304e 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -23,6 +23,7 @@
 #define DEFERRED_SET_SIZE 64
 #define MAPPING_POOL_SIZE 1024
 #define PRISON_CELLS 1024
+#define COMMIT_PERIOD HZ
 
 /*
  * The block size of the device holding pool data must be
@@ -493,8 +494,10 @@ struct pool {
 
 	struct workqueue_struct *wq;
 	struct work_struct worker;
+	struct delayed_work waker;
 
 	unsigned ref_count;
+	unsigned long last_commit_jiffies;
 
 	spinlock_t lock;
 	struct bio_list deferred_bios;
@@ -1249,6 +1252,12 @@ static void process_bio(struct thin_c *tc, struct bio *bio)
 	}
 }
 
+static int need_commit_due_to_time(struct pool *pool)
+{
+	return jiffies < pool->last_commit_jiffies ||
+	       jiffies > pool->last_commit_jiffies + COMMIT_PERIOD;
+}
+
 static void process_deferred_bios(struct pool *pool)
 {
 	unsigned long flags;
@@ -1290,7 +1299,7 @@ static void process_deferred_bios(struct pool *pool)
 	bio_list_init(&pool->deferred_flush_bios);
 	spin_unlock_irqrestore(&pool->lock, flags);
 
-	if (bio_list_empty(&bios))
+	if (bio_list_empty(&bios) && !need_commit_due_to_time(pool))
 		return;
 
 	r = dm_pool_commit_metadata(pool->pmd);
@@ -1301,6 +1310,7 @@ static void process_deferred_bios(struct pool *pool)
 			bio_io_error(bio);
 		return;
 	}
+	pool->last_commit_jiffies = jiffies;
 
 	while ((bio = bio_list_pop(&bios)))
 		generic_make_request(bio);
@@ -1314,6 +1324,17 @@ static void do_worker(struct work_struct *ws)
 	process_deferred_bios(pool);
 }
 
+/*
+ * We want to commit periodically so that not too much
+ * unwritten data builds up.
+ */
+static void do_waker(struct work_struct *ws)
+{
+	struct pool *pool = container_of(to_delayed_work(ws), struct pool, waker);
+	wake_worker(pool);
+	queue_delayed_work(pool->wq, &pool->waker, COMMIT_PERIOD);
+}
+
 /*----------------------------------------------------------------*/
 
 /*
@@ -1523,6 +1544,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
 	}
 
 	INIT_WORK(&pool->worker, do_worker);
+	INIT_DELAYED_WORK(&pool->waker, do_waker);
 	spin_lock_init(&pool->lock);
 	bio_list_init(&pool->deferred_bios);
 	bio_list_init(&pool->deferred_flush_bios);
@@ -1549,6 +1571,7 @@ static struct pool *pool_create(struct mapped_device *pool_md,
 		goto bad_endio_hook_pool;
 	}
 	pool->ref_count = 1;
+	pool->last_commit_jiffies = jiffies;
 	pool->pool_md = pool_md;
 	pool->md_dev = metadata_dev;
 	__pool_table_insert(pool);
@@ -1878,7 +1901,7 @@ static void pool_resume(struct dm_target *ti)
 	__requeue_bios(pool);
 	spin_unlock_irqrestore(&pool->lock, flags);
 
-	wake_worker(pool);
+	do_waker(&pool->waker.work);
 }
 
 static void pool_postsuspend(struct dm_target *ti)
@@ -1887,6 +1910,7 @@ static void pool_postsuspend(struct dm_target *ti)
 	struct pool_c *pt = ti->private;
 	struct pool *pool = pt->pool;
 
+	cancel_delayed_work(&pool->waker);
 	flush_workqueue(pool->wq);
 
 	r = dm_pool_commit_metadata(pool->pmd);
diff --git a/drivers/md/persistent-data/dm-btree-internal.h b/drivers/md/persistent-data/dm-btree-internal.h
index d279c76..5709bfe 100644
--- a/drivers/md/persistent-data/dm-btree-internal.h
+++ b/drivers/md/persistent-data/dm-btree-internal.h
@@ -108,12 +108,9 @@ static inline void *value_base(struct node *n)
 	return &n->keys[le32_to_cpu(n->header.max_entries)];
 }
 
-/*
- * FIXME: Now that value size is stored in node we don't need the third parm.
- */
-static inline void *value_ptr(struct node *n, uint32_t index, size_t value_size)
+static inline void *value_ptr(struct node *n, uint32_t index)
 {
-	BUG_ON(value_size != le32_to_cpu(n->header.value_size));
+	uint32_t value_size = le32_to_cpu(n->header.value_size);
 	return value_base(n) + (value_size * index);
 }
 
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
index 023fbc2..8576d56 100644
--- a/drivers/md/persistent-data/dm-btree-remove.c
+++ b/drivers/md/persistent-data/dm-btree-remove.c
@@ -61,20 +61,20 @@ static void node_shift(struct node *n, int shift)
 	if (shift < 0) {
 		shift = -shift;
 		BUG_ON(shift > nr_entries);
-		BUG_ON((void *) key_ptr(n, shift) >= value_ptr(n, shift, value_size));
+		BUG_ON((void *) key_ptr(n, shift) >= value_ptr(n, shift));
 		memmove(key_ptr(n, 0),
 			key_ptr(n, shift),
 			(nr_entries - shift) * sizeof(__le64));
-		memmove(value_ptr(n, 0, value_size),
-			value_ptr(n, shift, value_size),
+		memmove(value_ptr(n, 0),
+			value_ptr(n, shift),
 			(nr_entries - shift) * value_size);
 	} else {
 		BUG_ON(nr_entries + shift > le32_to_cpu(n->header.max_entries));
 		memmove(key_ptr(n, shift),
 			key_ptr(n, 0),
 			nr_entries * sizeof(__le64));
-		memmove(value_ptr(n, shift, value_size),
-			value_ptr(n, 0, value_size),
+		memmove(value_ptr(n, shift),
+			value_ptr(n, 0),
 			nr_entries * value_size);
 	}
 }
@@ -91,16 +91,16 @@ static void node_copy(struct node *left, struct node *right, int shift)
 		memcpy(key_ptr(left, nr_left),
 		       key_ptr(right, 0),
 		       shift * sizeof(__le64));
-		memcpy(value_ptr(left, nr_left, value_size),
-		       value_ptr(right, 0, value_size),
+		memcpy(value_ptr(left, nr_left),
+		       value_ptr(right, 0),
 		       shift * value_size);
 	} else {
 		BUG_ON(shift > le32_to_cpu(right->header.max_entries));
 		memcpy(key_ptr(right, 0),
 		       key_ptr(left, nr_left - shift),
 		       shift * sizeof(__le64));
-		memcpy(value_ptr(right, 0, value_size),
-		       value_ptr(left, nr_left - shift, value_size),
+		memcpy(value_ptr(right, 0),
+		       value_ptr(left, nr_left - shift),
 		       shift * value_size);
 	}
 }
@@ -120,8 +120,8 @@ static void delete_at(struct node *n, unsigned index)
 			key_ptr(n, index + 1),
 			nr_to_copy * sizeof(__le64));
 
-		memmove(value_ptr(n, index, value_size),
-			value_ptr(n, index + 1, value_size),
+		memmove(value_ptr(n, index),
+			value_ptr(n, index + 1),
 			nr_to_copy * value_size);
 	}
 
@@ -175,7 +175,7 @@ static int init_child(struct dm_btree_info *info, struct node *parent,
 	if (inc)
 		inc_children(info->tm, result->n, &le64_type);
 
-	*((__le64 *) value_ptr(parent, index, sizeof(__le64))) =
+	*((__le64 *) value_ptr(parent, index)) =
 		cpu_to_le64(dm_block_location(result->block));
 
 	return 0;
@@ -496,7 +496,7 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info,
 		 */
 		if (shadow_has_parent(s)) {
 			__le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
-			memcpy(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(__le64)),
+			memcpy(value_ptr(dm_block_data(shadow_parent(s)), i),
 			       &location, sizeof(__le64));
 		}
 
@@ -553,7 +553,7 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root,
 
 		if (info->value_type.dec)
 			info->value_type.dec(info->value_type.context,
-					     value_ptr(n, index, info->value_type.size));
+					     value_ptr(n, index));
 
 		delete_at(n, index);
 	}
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
index bd1e7ff..d12b2cc 100644
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -74,8 +74,7 @@ void inc_children(struct dm_transaction_manager *tm, struct node *n,
 			dm_tm_inc(tm, value64(n, i));
 	else if (vt->inc)
 		for (i = 0; i < nr_entries; i++)
-			vt->inc(vt->context,
-				value_ptr(n, i, vt->size));
+			vt->inc(vt->context, value_ptr(n, i));
 }
 
 static int insert_at(size_t value_size, struct node *node, unsigned index,
@@ -281,7 +280,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
 
 				for (i = 0; i < f->nr_children; i++)
 					info->value_type.dec(info->value_type.context,
-							     value_ptr(f->n, i, info->value_type.size));
+							     value_ptr(f->n, i));
 			}
 			f->current_child = f->nr_children;
 		}
@@ -320,7 +319,7 @@ static int btree_lookup_raw(struct ro_spine *s, dm_block_t block, uint64_t key,
 	} while (!(flags & LEAF_NODE));
 
 	*result_key = le64_to_cpu(ro_node(s)->keys[i]);
-	memcpy(v, value_ptr(ro_node(s), i, value_size), value_size);
+	memcpy(v, value_ptr(ro_node(s), i), value_size);
 
 	return 0;
 }
@@ -432,7 +431,7 @@ static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
 
 	size = le32_to_cpu(ln->header.flags) & INTERNAL_NODE ?
 		sizeof(uint64_t) : s->info->value_type.size;
-	memcpy(value_ptr(rn, 0, size), value_ptr(ln, nr_left, size),
+	memcpy(value_ptr(rn, 0), value_ptr(ln, nr_left),
 	       size * nr_right);
 
 	/*
@@ -443,7 +442,7 @@ static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
 	pn = dm_block_data(parent);
 	location = cpu_to_le64(dm_block_location(left));
 	__dm_bless_for_disk(&location);
-	memcpy_disk(value_ptr(pn, parent_index, sizeof(__le64)),
+	memcpy_disk(value_ptr(pn, parent_index),
 		    &location, sizeof(__le64));
 
 	location = cpu_to_le64(dm_block_location(right));
@@ -529,8 +528,8 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
 
 	size = le32_to_cpu(pn->header.flags) & INTERNAL_NODE ?
 		sizeof(__le64) : s->info->value_type.size;
-	memcpy(value_ptr(ln, 0, size), value_ptr(pn, 0, size), nr_left * size);
-	memcpy(value_ptr(rn, 0, size), value_ptr(pn, nr_left, size),
+	memcpy(value_ptr(ln, 0), value_ptr(pn, 0), nr_left * size);
+	memcpy(value_ptr(rn, 0), value_ptr(pn, nr_left),
 	       nr_right * size);
 
 	/* new_parent should just point to l and r now */
@@ -545,12 +544,12 @@ static int btree_split_beneath(struct shadow_spine *s, uint64_t key)
 	val = cpu_to_le64(dm_block_location(left));
 	__dm_bless_for_disk(&val);
 	pn->keys[0] = ln->keys[0];
-	memcpy_disk(value_ptr(pn, 0, sizeof(__le64)), &val, sizeof(__le64));
+	memcpy_disk(value_ptr(pn, 0), &val, sizeof(__le64));
 
 	val = cpu_to_le64(dm_block_location(right));
 	__dm_bless_for_disk(&val);
 	pn->keys[1] = rn->keys[0];
-	memcpy_disk(value_ptr(pn, 1, sizeof(__le64)), &val, sizeof(__le64));
+	memcpy_disk(value_ptr(pn, 1), &val, sizeof(__le64));
 
 	/*
 	 * rejig the spine.  This is ugly, since it knows too
@@ -595,7 +594,7 @@ static int btree_insert_raw(struct shadow_spine *s, dm_block_t root,
 			__le64 location = cpu_to_le64(dm_block_location(shadow_current(s)));
 
 			__dm_bless_for_disk(&location);
-			memcpy_disk(value_ptr(dm_block_data(shadow_parent(s)), i, sizeof(uint64_t)),
+			memcpy_disk(value_ptr(dm_block_data(shadow_parent(s)), i),
 				    &location, sizeof(__le64));
 		}
 
@@ -710,12 +709,12 @@ static int insert(struct dm_btree_info *info, dm_block_t root,
 		    (!info->value_type.equal ||
 		     !info->value_type.equal(
 			     info->value_type.context,
-			     value_ptr(n, index, info->value_type.size),
+			     value_ptr(n, index),
 			     value))) {
 			info->value_type.dec(info->value_type.context,
-					     value_ptr(n, index, info->value_type.size));
+					     value_ptr(n, index));
 		}
-		memcpy_disk(value_ptr(n, index, info->value_type.size),
+		memcpy_disk(value_ptr(n, index),
 			    value, info->value_type.size);
 	}
 
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index a368db2..a0b225e 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -624,7 +624,7 @@ int md_raid1_congested(struct mddev *mddev, int bits)
 		return 1;
 
 	rcu_read_lock();
-	for (i = 0; i < conf->raid_disks; i++) {
+	for (i = 0; i < conf->raid_disks * 2; i++) {
 		struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev);
 		if (rdev && !test_bit(Faulty, &rdev->flags)) {
 			struct request_queue *q = bdev_get_queue(rdev->bdev);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 6e8aa21..bd06ea2 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -67,6 +67,7 @@ static int max_queued_requests = 1024;
 
 static void allow_barrier(struct r10conf *conf);
 static void lower_barrier(struct r10conf *conf);
+static int enough(struct r10conf *conf, int ignore);
 
 static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
 {
@@ -347,6 +348,19 @@ static void raid10_end_read_request(struct bio *bio, int error)
 		 * wait for the 'master' bio.
 		 */
 		set_bit(R10BIO_Uptodate, &r10_bio->state);
+	} else {
+		/* If all other devices that store this block have
+		 * failed, we want to return the error upwards rather
+		 * than fail the last device.  Here we redefine
+		 * "uptodate" to mean "Don't want to retry"
+		 */
+		unsigned long flags;
+		spin_lock_irqsave(&conf->device_lock, flags);
+		if (!enough(conf, rdev->raid_disk))
+			uptodate = 1;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
+	}
+	if (uptodate) {
 		raid_end_bio_io(r10_bio);
 		rdev_dec_pending(rdev, conf->mddev);
 	} else {
@@ -2052,6 +2066,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10
 		       "md/raid10:%s: %s: Failing raid device\n",
 		       mdname(mddev), b);
 		md_error(mddev, conf->mirrors[d].rdev);
+		r10_bio->devs[r10_bio->read_slot].bio = IO_BLOCKED;
 		return;
 	}
 
@@ -2105,8 +2120,11 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10
 				    rdev,
 				    r10_bio->devs[r10_bio->read_slot].addr
 				    + sect,
-				    s, 0))
+				    s, 0)) {
 				md_error(mddev, rdev);
+				r10_bio->devs[r10_bio->read_slot].bio
+					= IO_BLOCKED;
+			}
 			break;
 		}
 
@@ -2299,17 +2317,20 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio)
 	 * This is all done synchronously while the array is
 	 * frozen.
 	 */
+	bio = r10_bio->devs[slot].bio;
+	bdevname(bio->bi_bdev, b);
+	bio_put(bio);
+	r10_bio->devs[slot].bio = NULL;
+
 	if (mddev->ro == 0) {
 		freeze_array(conf);
 		fix_read_error(conf, mddev, r10_bio);
 		unfreeze_array(conf);
-	}
+	} else
+		r10_bio->devs[slot].bio = IO_BLOCKED;
+
 	rdev_dec_pending(rdev, mddev);
 
-	bio = r10_bio->devs[slot].bio;
-	bdevname(bio->bi_bdev, b);
-	r10_bio->devs[slot].bio =
-		mddev->ro ? IO_BLOCKED : NULL;
 read_more:
 	rdev = read_balance(conf, r10_bio, &max_sectors);
 	if (rdev == NULL) {
@@ -2318,13 +2339,10 @@ read_more:
 		       mdname(mddev), b,
 		       (unsigned long long)r10_bio->sector);
 		raid_end_bio_io(r10_bio);
-		bio_put(bio);
 		return;
 	}
 
 	do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
-	if (bio)
-		bio_put(bio);
 	slot = r10_bio->read_slot;
 	printk_ratelimited(
 		KERN_ERR
@@ -2360,7 +2378,6 @@ read_more:
 			mbio->bi_phys_segments++;
 		spin_unlock_irq(&conf->device_lock);
 		generic_make_request(bio);
-		bio = NULL;
 
 		r10_bio = mempool_alloc(conf->r10bio_pool,
 					GFP_NOIO);
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
index cb2c98f..ba84936 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/common/tuners/max2165.c
@@ -168,7 +168,7 @@ int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
 	int i;
 
 	if (0 == divisor)
-		return -1;
+		return -EINVAL;
 
 	q = dividend / divisor;
 	remainder = dividend - q * divisor;
@@ -194,10 +194,13 @@ static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
 	u8 tf_ntch;
 	u32 t;
 	u32 quotient, fraction;
+	int ret;
 
 	/* Set PLL divider according to RF frequency */
-	fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
-		&quotient, &fraction);
+	ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
+			 &quotient, &fraction);
+	if (ret != 0)
+		return ret;
 
 	/* 20-bit fraction */
 	fraction >>= 12;
diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c
index c89af3c..0ed9091 100644
--- a/drivers/media/common/tuners/mt2063.c
+++ b/drivers/media/common/tuners/mt2063.c
@@ -350,7 +350,7 @@ static int MT2063_Sleep(struct dvb_frontend *fe)
 	/*
 	 *  ToDo:  Add code here to implement a OS blocking
 	 */
-	msleep(10);
+	msleep(100);
 
 	return 0;
 }
@@ -2226,7 +2226,7 @@ static struct dvb_tuner_ops mt2063_ops = {
 	.info = {
 		 .name = "MT2063 Silicon Tuner",
 		 .frequency_min = 45000000,
-		 .frequency_max = 850000000,
+		 .frequency_max = 865000000,
 		 .frequency_step = 0,
 		 },
 
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index e13683b..2da4440 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1868,6 +1868,10 @@ struct tunertype tuners[] = {
 		.params = tuner_tena_tnf_5337_params,
 		.count  = ARRAY_SIZE(tuner_tena_tnf_5337_params),
 	},
+	[TUNER_XC5000C] = { /* Xceive 5000C */
+		.name   = "Xceive 5000C tuner",
+		/* see xc5000.c for details */
+	},
 };
 EXPORT_SYMBOL(tuners);
 
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 296df05..7f98984 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -49,9 +49,6 @@ static LIST_HEAD(hybrid_tuner_instance_list);
 #define dprintk(level, fmt, arg...) if (debug >= level) \
 	printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
 
-#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
-#define XC5000_DEFAULT_FIRMWARE_SIZE 12401
-
 struct xc5000_priv {
 	struct tuner_i2c_props i2c_props;
 	struct list_head hybrid_tuner_instance_list;
@@ -62,6 +59,8 @@ struct xc5000_priv {
 	u8  video_standard;
 	u8  rf_mode;
 	u8  radio_input;
+
+	int chip_id;
 };
 
 /* Misc Defines */
@@ -204,6 +203,33 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
 	{"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
 };
 
+
+struct xc5000_fw_cfg {
+	char *name;
+	u16 size;
+};
+
+static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
+	.name = "dvb-fe-xc5000-1.6.114.fw",
+	.size = 12401,
+};
+
+static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = {
+	.name = "dvb-fe-xc5000c-41.024.5-31875.fw",
+	.size = 16503,
+};
+
+static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
+{
+	switch (chip_id) {
+	default:
+	case XC5000A:
+		return &xc5000a_1_6_114;
+	case XC5000C:
+		return &xc5000c_41_024_5_31875;
+	}
+}
+
 static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
 static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
 static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
@@ -552,12 +578,14 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
 	struct xc5000_priv *priv = fe->tuner_priv;
 	const struct firmware *fw;
 	int ret;
+	const struct xc5000_fw_cfg *desired_fw =
+		xc5000_assign_firmware(priv->chip_id);
 
 	/* request the firmware, this will block and timeout */
 	printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
-		XC5000_DEFAULT_FIRMWARE);
+		desired_fw->name);
 
-	ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
+	ret = request_firmware(&fw, desired_fw->name,
 		priv->i2c_props.adap->dev.parent);
 	if (ret) {
 		printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
@@ -569,7 +597,7 @@ static int xc5000_fwupload(struct dvb_frontend *fe)
 		ret = XC_RESULT_SUCCESS;
 	}
 
-	if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
+	if (fw->size != desired_fw->size) {
 		printk(KERN_ERR "xc5000: firmware incorrect size\n");
 		ret = XC_RESULT_RESET_FAILURE;
 	} else {
@@ -1139,6 +1167,13 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
 	if (priv->radio_input == 0)
 		priv->radio_input = cfg->radio_input;
 
+	/* don't override chip id if it's already been set
+	   unless explicitly specified */
+	if ((priv->chip_id == 0) || (cfg->chip_id))
+		/* use default chip id if none specified, set to 0 so
+		   it can be overridden if this is a hybrid driver */
+		priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0;
+
 	/* Check if firmware has been loaded. It is possible that another
 	   instance of the driver has loaded the firmware.
 	 */
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index e295745..3396f8e 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -27,10 +27,15 @@
 struct dvb_frontend;
 struct i2c_adapter;
 
+#define XC5000A 1
+#define XC5000C 2
+
 struct xc5000_config {
 	u8   i2c_address;
 	u32  if_khz;
 	u8   radio_input;
+
+	int chip_id;
 };
 
 /* xc5000 callback command */
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c
index ce4f858..d88c4aa 100644
--- a/drivers/media/dvb/ddbridge/ddbridge-core.c
+++ b/drivers/media/dvb/ddbridge/ddbridge-core.c
@@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)
 	struct drxk_config config;
 
 	memset(&config, 0, sizeof(config));
+	config.microcode_name = "drxk_a3.mc";
 	config.adr = 0x29 + (input->nr & 1);
 
 	fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
diff --git a/drivers/media/dvb/ddbridge/ddbridge.h b/drivers/media/dvb/ddbridge/ddbridge.h
index 6d14893..8b1b41d 100644
--- a/drivers/media/dvb/ddbridge/ddbridge.h
+++ b/drivers/media/dvb/ddbridge/ddbridge.h
@@ -32,8 +32,6 @@
 #include <asm/dma.h>
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/ca.h>
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
 #include <linux/socket.h>
 
 #include "dmxdev.h"
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index fbbe545..4555baa 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -655,6 +655,8 @@ restart:
 					dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
 					re_tune = true;
 					fepriv->state = FESTATE_TUNED;
+				} else {
+					re_tune = false;
 				}
 
 				if (fe->ops.tune)
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 9f203c6..e894bad 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -361,6 +361,14 @@ config DVB_USB_EC168
 	help
 	  Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
 
+config DVB_USB_AZ6007
+	tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
+	depends on DVB_USB
+	select DVB_DRXK if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
+	help
+	  Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers.
+
 config DVB_USB_AZ6027
 	tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
 	depends on DVB_USB
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 26c8b9e..d9549cb 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -54,7 +54,6 @@ obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
 dvb-usb-opera-objs = opera1.o
 obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
 
-
 dvb-usb-af9005-objs = af9005.o af9005-fe.o
 obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
 
@@ -88,6 +87,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
 dvb-usb-ec168-objs = ec168.o
 obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
 
+dvb-usb-az6007-objs = az6007.o
+obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
+
 dvb-usb-az6027-objs = az6027.o
 obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
 
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index cf0c318..03c2865 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -58,7 +58,7 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
 	u8 *rbuf, u8 rlen)
 {
 	struct anysee_state *state = d->priv;
-	int act_len, ret;
+	int act_len, ret, i;
 	u8 buf[64];
 
 	memcpy(&buf[0], sbuf, slen);
@@ -73,26 +73,52 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
 	/* We need receive one message more after dvb_usb_generic_rw due
 	   to weird transaction flow, which is 1 x send + 2 x receive. */
 	ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
-	if (!ret) {
+	if (ret)
+		goto error_unlock;
+
+	/* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
+	 * (EPIPE, Broken pipe). Function supports currently msleep() as a
+	 * parameter but I would not like to use it, since according to
+	 * Documentation/timers/timers-howto.txt it should not be used such
+	 * short, under < 20ms, sleeps. Repeating failed message would be
+	 * better choice as not to add unwanted delays...
+	 * Fixing that correctly is one of those or both;
+	 * 1) use repeat if possible
+	 * 2) add suitable delay
+	 */
+
+	/* get answer, retry few times if error returned */
+	for (i = 0; i < 3; i++) {
 		/* receive 2nd answer */
 		ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
 			d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
 			&act_len, 2000);
-		if (ret)
-			err("%s: recv bulk message failed: %d", __func__, ret);
-		else {
+
+		if (ret) {
+			deb_info("%s: recv bulk message failed: %d",
+					__func__, ret);
+		} else {
 			deb_xfer("<<< ");
 			debug_dump(buf, rlen, deb_xfer);
 
 			if (buf[63] != 0x4f)
 				deb_info("%s: cmd failed\n", __func__);
+
+			break;
 		}
 	}
 
+	if (ret) {
+		/* all retries failed, it is fatal */
+		err("%s: recv bulk message failed: %d", __func__, ret);
+		goto error_unlock;
+	}
+
 	/* read request, copy returned data to return buf */
-	if (!ret && rbuf && rlen)
+	if (rbuf && rlen)
 		memcpy(rbuf, buf, rlen);
 
+error_unlock:
 	mutex_unlock(&anysee_usb_mutex);
 
 	return ret;
diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c
new file mode 100644
index 0000000..df4cbc0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/az6007.c
@@ -0,0 +1,582 @@
+/*
+ * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones
+ *
+ * Copyright (c) Henry Wang <Henry.wang@AzureWave.com>
+ *
+ * This driver was made publicly available by Terratec, at:
+ *	http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
+ * The original driver's license is GPL, as declared with MODULE_LICENSE()
+ *
+ * Copyright (c) 2010-2011 Mauro Carvalho Chehab <mchehab@redhat.com>
+ *	Driver modified by in order to work with upstream drxk driver, and
+ *	tons of bugs got fixed.
+ *
+ * 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 under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "drxk.h"
+#include "mt2063.h"
+#include "dvb_ca_en50221.h"
+
+#define DVB_USB_LOG_PREFIX "az6007"
+#include "dvb-usb.h"
+
+/* debug */
+int dvb_usb_az6007_debug;
+module_param_named(debug, dvb_usb_az6007_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))."
+		 DVB_USB_DEBUG_STATUS);
+
+#define deb_info(args...) dprintk(dvb_usb_az6007_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_az6007_debug, 0x04, args)
+#define deb_fe(args...)   dprintk(dvb_usb_az6007_debug, 0x08, args)
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/
+
+#define FX2_OED			0xb5
+#define AZ6007_READ_DATA	0xb7
+#define AZ6007_I2C_RD		0xb9
+#define AZ6007_POWER		0xbc
+#define AZ6007_I2C_WR		0xbd
+#define FX2_SCON1		0xc0
+#define AZ6007_TS_THROUGH	0xc7
+#define AZ6007_READ_IR		0xb4
+
+struct az6007_device_state {
+	struct mutex		mutex;
+	struct dvb_ca_en50221	ca;
+	unsigned		warm:1;
+	int			(*gate_ctrl) (struct dvb_frontend *, int);
+	unsigned char		data[4096];
+};
+
+static struct drxk_config terratec_h7_drxk = {
+	.adr = 0x29,
+	.parallel_ts = true,
+	.dynamic_clk = true,
+	.single_master = true,
+	.enable_merr_cfg = true,
+	.no_i2c_bridge = false,
+	.chunk_size = 64,
+	.mpeg_out_clk_strength = 0x02,
+	.microcode_name = "dvb-usb-terratec-h7-drxk.fw",
+};
+
+static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	struct dvb_usb_adapter *adap = fe->sec_priv;
+	struct az6007_device_state *st;
+	int status = 0;
+
+	deb_info("%s: %s\n", __func__, enable ? "enable" : "disable");
+
+	if (!adap)
+		return -EINVAL;
+
+	st = adap->dev->priv;
+
+	if (!st)
+		return -EINVAL;
+
+	if (enable)
+		status = st->gate_ctrl(fe, 1);
+	else
+		status = st->gate_ctrl(fe, 0);
+
+	return status;
+}
+
+static struct mt2063_config az6007_mt2063_config = {
+	.tuner_address = 0x60,
+	.refclock = 36125000,
+};
+
+static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	int ret;
+
+	ret = usb_control_msg(udev,
+			      usb_rcvctrlpipe(udev, 0),
+			      req,
+			      USB_TYPE_VENDOR | USB_DIR_IN,
+			      value, index, b, blen, 5000);
+	if (ret < 0) {
+		warn("usb read operation failed. (%d)", ret);
+		return -EIO;
+	}
+
+	deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value,
+		 index);
+	debug_dump(b, blen, deb_xfer);
+
+	return ret;
+}
+
+static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct az6007_device_state *st = d->priv;
+	int ret;
+
+	if (mutex_lock_interruptible(&st->mutex) < 0)
+		return -EAGAIN;
+
+	ret = __az6007_read(d->udev, req, value, index, b, blen);
+
+	mutex_unlock(&st->mutex);
+
+	return ret;
+}
+
+static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
+			     u16 index, u8 *b, int blen)
+{
+	int ret;
+
+	deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value,
+		 index);
+	debug_dump(b, blen, deb_xfer);
+
+	if (blen > 64) {
+		err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
+		    blen);
+		return -EOPNOTSUPP;
+	}
+
+	ret = usb_control_msg(udev,
+			      usb_sndctrlpipe(udev, 0),
+			      req,
+			      USB_TYPE_VENDOR | USB_DIR_OUT,
+			      value, index, b, blen, 5000);
+	if (ret != blen) {
+		err("usb write operation failed. (%d)", ret);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	struct az6007_device_state *st = d->priv;
+	int ret;
+
+	if (mutex_lock_interruptible(&st->mutex) < 0)
+		return -EAGAIN;
+
+	ret = __az6007_write(d->udev, req, value, index, b, blen);
+
+	mutex_unlock(&st->mutex);
+
+	return ret;
+}
+
+static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct dvb_usb_device *d = adap->dev;
+
+	deb_info("%s: %s", __func__, onoff ? "enable" : "disable");
+
+	return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
+}
+
+/* remote control stuff (does not work with my box) */
+static int az6007_rc_query(struct dvb_usb_device *d)
+{
+	struct az6007_device_state *st = d->priv;
+	unsigned code = 0;
+
+	az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
+
+	if (st->data[1] == 0x44)
+		return 0;
+
+	if ((st->data[1] ^ st->data[2]) == 0xff)
+		code = st->data[1];
+	else
+		code = st->data[1] << 8 | st->data[2];
+
+	if ((st->data[3] ^ st->data[4]) == 0xff)
+		code = code << 8 | st->data[3];
+	else
+		code = code << 16 | st->data[3] << 8 | st->data[4];
+
+	rc_keydown(d->rc_dev, code, st->data[5]);
+
+	return 0;
+}
+
+static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
+{
+	struct az6007_device_state *st = d->priv;
+	int ret;
+
+	ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
+	memcpy(mac, st->data, sizeof(mac));
+
+	if (ret > 0)
+		deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n",
+			 __func__, mac[0], mac[1], mac[2],
+			 mac[3], mac[4], mac[5]);
+
+	return ret;
+}
+
+static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	struct az6007_device_state *st = adap->dev->priv;
+
+	deb_info("attaching demod drxk");
+
+	adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk,
+					 &adap->dev->i2c_adap);
+	if (!adap->fe_adap[0].fe)
+		return -EINVAL;
+
+	adap->fe_adap[0].fe->sec_priv = adap;
+	st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl;
+	adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
+
+	return 0;
+}
+
+static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	deb_info("attaching tuner mt2063");
+
+	/* Attach mt2063 to DVB-C frontend */
+	if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
+		adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
+	if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe,
+			&az6007_mt2063_config,
+			&adap->dev->i2c_adap))
+		return -EINVAL;
+
+	if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
+		adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
+
+	return 0;
+}
+
+int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	struct az6007_device_state *st = d->priv;
+	int ret;
+
+	deb_info("%s()\n", __func__);
+
+	if (!st->warm) {
+		mutex_init(&st->mutex);
+
+		ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
+		if (ret < 0)
+			return ret;
+		msleep(60);
+		ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
+		if (ret < 0)
+			return ret;
+		msleep(100);
+		ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0);
+		if (ret < 0)
+			return ret;
+		msleep(20);
+		ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
+		if (ret < 0)
+			return ret;
+
+		msleep(400);
+		ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0);
+		if (ret < 0)
+			return ret;
+		msleep(150);
+		ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0);
+		if (ret < 0)
+			return ret;
+		msleep(430);
+		ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
+		if (ret < 0)
+			return ret;
+
+		st->warm = true;
+
+		return 0;
+	}
+
+	if (!onoff)
+		return 0;
+
+	az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
+	az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
+
+	return 0;
+}
+
+/* I2C */
+static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
+			   int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct az6007_device_state *st = d->priv;
+	int i, j, len;
+	int ret = 0;
+	u16 index;
+	u16 value;
+	int length;
+	u8 req, addr;
+
+	if (mutex_lock_interruptible(&st->mutex) < 0)
+		return -EAGAIN;
+
+	for (i = 0; i < num; i++) {
+		addr = msgs[i].addr << 1;
+		if (((i + 1) < num)
+		    && (msgs[i].len == 1)
+		    && (!msgs[i].flags & I2C_M_RD)
+		    && (msgs[i + 1].flags & I2C_M_RD)
+		    && (msgs[i].addr == msgs[i + 1].addr)) {
+			/*
+			 * A write + read xfer for the same address, where
+			 * the first xfer has just 1 byte length.
+			 * Need to join both into one operation
+			 */
+			if (dvb_usb_az6007_debug & 2)
+				printk(KERN_DEBUG
+				       "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ",
+				       addr, msgs[i].len, msgs[i + 1].len);
+			req = AZ6007_I2C_RD;
+			index = msgs[i].buf[0];
+			value = addr | (1 << 8);
+			length = 6 + msgs[i + 1].len;
+			len = msgs[i + 1].len;
+			ret = __az6007_read(d->udev, req, value, index,
+					    st->data, length);
+			if (ret >= len) {
+				for (j = 0; j < len; j++) {
+					msgs[i + 1].buf[j] = st->data[j + 5];
+					if (dvb_usb_az6007_debug & 2)
+						printk(KERN_CONT
+						       "0x%02x ",
+						       msgs[i + 1].buf[j]);
+				}
+			} else
+				ret = -EIO;
+			i++;
+		} else if (!(msgs[i].flags & I2C_M_RD)) {
+			/* write bytes */
+			if (dvb_usb_az6007_debug & 2)
+				printk(KERN_DEBUG
+				       "az6007 I2C xfer write addr=0x%x len=%d: ",
+				       addr, msgs[i].len);
+			req = AZ6007_I2C_WR;
+			index = msgs[i].buf[0];
+			value = addr | (1 << 8);
+			length = msgs[i].len - 1;
+			len = msgs[i].len - 1;
+			if (dvb_usb_az6007_debug & 2)
+				printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]);
+			for (j = 0; j < len; j++) {
+				st->data[j] = msgs[i].buf[j + 1];
+				if (dvb_usb_az6007_debug & 2)
+					printk(KERN_CONT "0x%02x ",
+					       st->data[j]);
+			}
+			ret =  __az6007_write(d->udev, req, value, index,
+					      st->data, length);
+		} else {
+			/* read bytes */
+			if (dvb_usb_az6007_debug & 2)
+				printk(KERN_DEBUG
+				       "az6007 I2C xfer read addr=0x%x len=%d: ",
+				       addr, msgs[i].len);
+			req = AZ6007_I2C_RD;
+			index = msgs[i].buf[0];
+			value = addr;
+			length = msgs[i].len + 6;
+			len = msgs[i].len;
+			ret = __az6007_read(d->udev, req, value, index,
+					    st->data, length);
+			for (j = 0; j < len; j++) {
+				msgs[i].buf[j] = st->data[j + 5];
+				if (dvb_usb_az6007_debug & 2)
+					printk(KERN_CONT
+					       "0x%02x ", st->data[j + 5]);
+			}
+		}
+		if (dvb_usb_az6007_debug & 2)
+			printk(KERN_CONT "\n");
+		if (ret < 0)
+			goto err;
+	}
+err:
+	mutex_unlock(&st->mutex);
+
+	if (ret < 0) {
+		info("%s ERROR: %i", __func__, ret);
+		return ret;
+	}
+	return num;
+}
+
+static u32 az6007_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm az6007_i2c_algo = {
+	.master_xfer = az6007_i2c_xfer,
+	.functionality = az6007_i2c_func,
+};
+
+int az6007_identify_state(struct usb_device *udev,
+			  struct dvb_usb_device_properties *props,
+			  struct dvb_usb_device_description **desc, int *cold)
+{
+	int ret;
+	u8 *mac;
+
+	mac = kmalloc(6, GFP_ATOMIC);
+	if (!mac)
+		return -ENOMEM;
+
+	/* Try to read the mac address */
+	ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6);
+	if (ret == 6)
+		*cold = 0;
+	else
+		*cold = 1;
+
+	kfree(mac);
+
+	if (*cold) {
+		__az6007_write(udev, 0x09, 1, 0, NULL, 0);
+		__az6007_write(udev, 0x00, 0, 0, NULL, 0);
+		__az6007_write(udev, 0x00, 0, 0, NULL, 0);
+	}
+
+	deb_info("Device is on %s state\n", *cold ? "warm" : "cold");
+	return 0;
+}
+
+static struct dvb_usb_device_properties az6007_properties;
+
+static int az6007_usb_probe(struct usb_interface *intf,
+			    const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf, &az6007_properties,
+				   THIS_MODULE, NULL, adapter_nr);
+}
+
+static struct usb_device_id az6007_usb_table[] = {
+	{USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)},
+	{USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)},
+	{USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2)},
+	{0},
+};
+
+MODULE_DEVICE_TABLE(usb, az6007_usb_table);
+
+static struct dvb_usb_device_properties az6007_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware            = "dvb-usb-terratec-h7-az6007.fw",
+	.no_reconnect        = 1,
+	.size_of_priv        = sizeof(struct az6007_device_state),
+	.identify_state	     = az6007_identify_state,
+	.num_adapters = 1,
+	.adapter = {
+		{
+		.num_frontends = 1,
+		.fe = {{
+			.streaming_ctrl   = az6007_streaming_ctrl,
+			.tuner_attach     = az6007_tuner_attach,
+			.frontend_attach  = az6007_frontend_attach,
+
+			/* parameter for the MPEG2-data transfer */
+			.stream = {
+				.type = USB_BULK,
+				.count = 10,
+				.endpoint = 0x02,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+					}
+				}
+			},
+		} }
+	} },
+	.power_ctrl       = az6007_power_ctrl,
+	.read_mac_address = az6007_read_mac_addr,
+
+	.rc.core = {
+		.rc_interval      = 400,
+		.rc_codes         = RC_MAP_NEC_TERRATEC_CINERGY_XS,
+		.module_name	  = "az6007",
+		.rc_query         = az6007_rc_query,
+		.allowed_protos   = RC_TYPE_NEC,
+	},
+	.i2c_algo         = &az6007_i2c_algo,
+
+	.num_device_descs = 2,
+	.devices = {
+		{ .name = "AzureWave DTV StarBox DVB-T/C USB2.0 (az6007)",
+		  .cold_ids = { &az6007_usb_table[0], NULL },
+		  .warm_ids = { NULL },
+		},
+		{ .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)",
+		  .cold_ids = { &az6007_usb_table[1], &az6007_usb_table[2], NULL },
+		  .warm_ids = { NULL },
+		},
+		{ NULL },
+	}
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver az6007_usb_driver = {
+	.name		= "dvb_usb_az6007",
+	.probe		= az6007_usb_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= az6007_usb_table,
+};
+
+/* module stuff */
+static int __init az6007_usb_module_init(void)
+{
+	int result;
+	deb_info("az6007 usb module init\n");
+
+	result = usb_register(&az6007_usb_driver);
+	if (result) {
+		err("usb_register failed. (%d)", result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit az6007_usb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	deb_info("az6007 usb module exit\n");
+	usb_deregister(&az6007_usb_driver);
+}
+
+module_init(az6007_usb_module_init);
+module_exit(az6007_usb_module_exit);
+
+MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
+MODULE_VERSION("1.1");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index d390dda..9c3dae1 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -80,6 +80,7 @@
 #define USB_PID_ANSONIC_DVBT_USB			0x6000
 #define USB_PID_ANYSEE					0x861f
 #define USB_PID_AZUREWAVE_AD_TU700			0x3237
+#define USB_PID_AZUREWAVE_6007				0x0ccd
 #define USB_PID_AVERMEDIA_DVBT_USB_COLD			0x0001
 #define USB_PID_AVERMEDIA_DVBT_USB_WARM			0x0002
 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD		0xa800
@@ -226,6 +227,8 @@
 #define USB_PID_TERRATEC_CINERGY_T_EXPRESS		0x0062
 #define USB_PID_TERRATEC_CINERGY_T_XXS			0x0078
 #define USB_PID_TERRATEC_CINERGY_T_XXS_2		0x00ab
+#define USB_PID_TERRATEC_H7				0x10b4
+#define USB_PID_TERRATEC_H7_2				0x10a3
 #define USB_PID_TERRATEC_T3				0x10a0
 #define USB_PID_TERRATEC_T5				0x10a1
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index 9f01cd7..2560652 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -388,19 +388,12 @@ static int ite_firmware_select(struct usb_device *udev,
 {
 	int sw;
 	/* auto switch */
-	if (le16_to_cpu(udev->descriptor.idProduct) ==
-			USB_PID_ITETECH_IT9135)
-		sw = IT9135_V1_FW;
-	else if (le16_to_cpu(udev->descriptor.idProduct) ==
-			USB_PID_ITETECH_IT9135_9005)
+	if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2)
+		sw = IT9137_FW;
+	else if (it913x_config.chip_ver == 1)
 		sw = IT9135_V1_FW;
-	else if (le16_to_cpu(udev->descriptor.idProduct) ==
-			USB_PID_ITETECH_IT9135_9006) {
+	else
 		sw = IT9135_V2_FW;
-		if (it913x_config.tuner_id_0 == 0)
-			it913x_config.tuner_id_0 = IT9135_60;
-	} else
-		sw = IT9137_FW;
 
 	/* force switch */
 	if (dvb_usb_it913x_firmware != IT9135_AUTO)
@@ -416,6 +409,15 @@ static int ite_firmware_select(struct usb_device *udev,
 		it913x_config.firmware_ver = 1;
 		it913x_config.adc_x2 = 1;
 		props->firmware = fw_it9135_v2;
+		switch (it913x_config.tuner_id_0) {
+		case IT9135_61:
+		case IT9135_62:
+			break;
+		default:
+			info("Unknown tuner ID applying default 0x60");
+		case IT9135_60:
+			it913x_config.tuner_id_0 = IT9135_60;
+		}
 		break;
 	case IT9137_FW:
 	default:
@@ -427,24 +429,74 @@ static int ite_firmware_select(struct usb_device *udev,
 	return 0;
 }
 
+static void it913x_select_remote(struct usb_device *udev,
+	struct dvb_usb_device_properties *props)
+{
+	switch (le16_to_cpu(udev->descriptor.idProduct)) {
+	case USB_PID_ITETECH_IT9135_9005:
+		props->rc.core.rc_codes = RC_MAP_IT913X_V2;
+		return;
+	default:
+		props->rc.core.rc_codes = RC_MAP_IT913X_V1;
+	}
+	return;
+}
+
 #define TS_MPEG_PKT_SIZE	188
 #define EP_LOW			21
 #define TS_BUFFER_SIZE_PID	(EP_LOW*TS_MPEG_PKT_SIZE)
 #define EP_HIGH			348
 #define TS_BUFFER_SIZE_MAX	(EP_HIGH*TS_MPEG_PKT_SIZE)
 
-static int it913x_identify_state(struct usb_device *udev,
-		struct dvb_usb_device_properties *props,
-		struct dvb_usb_device_description **desc,
-		int *cold)
+static int it913x_select_config(struct usb_device *udev,
+	struct dvb_usb_device_properties *props)
 {
-	int ret = 0, firm_no;
-	u8 reg, remote;
+	int ret = 0, reg;
+	bool proprietary_ir = false;
 
-	firm_no = it913x_return_status(udev);
+	if (it913x_config.chip_ver == 0x02
+			&& it913x_config.chip_type == 0x9135)
+		reg = it913x_read_reg(udev, 0x461d);
+	else
+		reg = it913x_read_reg(udev, 0x461b);
 
-	/* checnk for dual mode */
-	it913x_config.dual_mode =  it913x_read_reg(udev, 0x49c5);
+	if (reg < 0)
+		return reg;
+
+	if (reg == 0) {
+		it913x_config.dual_mode = 0;
+		it913x_config.tuner_id_0 = IT9135_38;
+		proprietary_ir = true;
+	} else {
+		/* TS mode */
+		reg =  it913x_read_reg(udev, 0x49c5);
+		if (reg < 0)
+			return reg;
+		it913x_config.dual_mode = reg;
+
+		/* IR mode type */
+		reg = it913x_read_reg(udev, 0x49ac);
+		if (reg < 0)
+			return reg;
+		if (reg == 5) {
+			info("Remote propriety (raw) mode");
+			proprietary_ir = true;
+		} else if (reg == 1) {
+			info("Remote HID mode NOT SUPPORTED");
+			proprietary_ir = false;
+			props->rc.core.rc_codes = NULL;
+		} else
+			props->rc.core.rc_codes = NULL;
+
+		/* Tuner_id */
+		reg = it913x_read_reg(udev, 0x49d0);
+		if (reg < 0)
+			return reg;
+		it913x_config.tuner_id_0 = reg;
+	}
+
+	if (proprietary_ir)
+		it913x_select_remote(udev, props);
 
 	if (udev->speed != USB_SPEED_HIGH) {
 		props->adapter[0].fe[0].pid_filter_count = 5;
@@ -459,17 +511,6 @@ static int it913x_identify_state(struct usb_device *udev,
 		if(props->adapter[0].fe[0].pid_filter_count == 5)
 			props->adapter[0].fe[0].pid_filter_count = 31;
 
-	/* TODO different remotes */
-	remote = it913x_read_reg(udev, 0x49ac); /* Remote */
-	if (remote == 0)
-		props->rc.core.rc_codes = NULL;
-
-	/* TODO at the moment tuner_id is always assigned to 0x38 */
-	it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
-
-	info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
-		, remote, it913x_config.tuner_id_0);
-
 	/* Select Stream Buffer Size and pid filter option*/
 	if (pid_filter) {
 		props->adapter[0].fe[0].stream.u.bulk.buffersize =
@@ -490,8 +531,29 @@ static int it913x_identify_state(struct usb_device *udev,
 	} else
 		props->num_adapters = 1;
 
+	info("Dual mode=%x Tuner Type=%x", it913x_config.dual_mode,
+		it913x_config.tuner_id_0);
+
 	ret = ite_firmware_select(udev, props);
 
+	return ret;
+}
+
+static int it913x_identify_state(struct usb_device *udev,
+		struct dvb_usb_device_properties *props,
+		struct dvb_usb_device_description **desc,
+		int *cold)
+{
+	int ret = 0, firm_no;
+	u8 reg;
+
+	firm_no = it913x_return_status(udev);
+
+	/* Read and select config */
+	ret = it913x_select_config(udev, props);
+	if (ret < 0)
+		return ret;
+
 	if (firm_no > 0) {
 		*cold = 0;
 		return 0;
@@ -789,7 +851,7 @@ static struct dvb_usb_device_properties it913x_properties = {
 		.rc_query	= it913x_rc_query,
 		.rc_interval	= IT913X_POLL,
 		.allowed_protos	= RC_TYPE_NEC,
-		.rc_codes	= RC_MAP_MSI_DIGIVOX_III,
+		.rc_codes	= RC_MAP_IT913X_V1,
 	},
 	.i2c_algo         = &it913x_i2c_algo,
 	.num_device_descs = 5,
@@ -823,5 +885,5 @@ module_usb_driver(it913x_driver);
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("it913x USB 2 Driver");
-MODULE_VERSION("1.22");
+MODULE_VERSION("1.25");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index b3fe05b..c33134c 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -104,8 +104,7 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
 
 static int pid_filter;
 module_param_named(pid, pid_filter, int, 0644);
-MODULE_PARM_DESC(pid, "set default 0=on 1=off");
-
+MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
@@ -653,7 +652,7 @@ static int lme2510_identify_state(struct usb_device *udev,
 		struct dvb_usb_device_description **desc,
 		int *cold)
 {
-	if (pid_filter > 0)
+	if (pid_filter != 2)
 		props->adapter[0].fe[0].caps &=
 			~DVB_USB_ADAP_NEED_PID_FILTERING;
 	*cold = 0;
@@ -1054,7 +1053,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
 	if (ret)
 		info("TUN Found %s tuner", tun_msg[ret]);
 	else {
-		info("TUN No tuner found --- reseting device");
+		info("TUN No tuner found --- resetting device");
 		lme_coldreset(adap->dev->udev);
 		return -ENODEV;
 	}
@@ -1295,5 +1294,5 @@ module_usb_driver(lme2510_driver);
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("1.91");
+MODULE_VERSION("1.96");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
index 0209818..9d64e4f 100644
--- a/drivers/media/dvb/frontends/drxk.h
+++ b/drivers/media/dvb/frontends/drxk.h
@@ -7,15 +7,19 @@
 /**
  * struct drxk_config - Configure the initial parameters for DRX-K
  *
- * adr:			I2C Address of the DRX-K
- * parallel_ts:		true means that the device uses parallel TS,
+ * @adr:		I2C Address of the DRX-K
+ * @parallel_ts:	True means that the device uses parallel TS,
  * 			Serial otherwise.
- * single_master:	Device is on the single master mode
- * no_i2c_bridge:	Don't switch the I2C bridge to talk with tuner
- * antenna_gpio:	GPIO bit used to control the antenna
- * antenna_dvbt:	GPIO bit for changing antenna to DVB-C. A value of 1
+ * @dynamic_clk:	True means that the clock will be dynamically
+ *			adjusted. Static clock otherwise.
+ * @enable_merr_cfg:	Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
+ * @single_master:	Device is on the single master mode
+ * @no_i2c_bridge:	Don't switch the I2C bridge to talk with tuner
+ * @antenna_gpio:	GPIO bit used to control the antenna
+ * @antenna_dvbt:	GPIO bit for changing antenna to DVB-C. A value of 1
  *			means that 1=DVBC, 0 = DVBT. Zero means the opposite.
- * microcode_name:	Name of the firmware file with the microcode
+ * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
+ * @microcode_name:	Name of the firmware file with the microcode
  *
  * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
  * UIO-3.
@@ -25,11 +29,14 @@ struct drxk_config {
 	bool	single_master;
 	bool	no_i2c_bridge;
 	bool	parallel_ts;
+	bool	dynamic_clk;
+	bool	enable_merr_cfg;
 
 	bool	antenna_dvbt;
 	u16	antenna_gpio;
 
-	int    chunk_size;
+	u8	mpeg_out_clk_strength;
+	int	chunk_size;
 
 	const char *microcode_name;
 };
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 6980ed7..36d1175 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -28,7 +28,6 @@
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/i2c.h>
-#include <linux/version.h>
 #include <asm/div64.h>
 
 #include "dvb_frontend.h"
@@ -91,10 +90,6 @@ bool IsA1WithRomCode(struct drxk_state *state)
 #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
 #endif
 
-#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
-#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
-#endif
-
 #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
 #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
 
@@ -650,9 +645,6 @@ static int init_state(struct drxk_state *state)
 	u32 ulQual83 = DEFAULT_MER_83;
 	u32 ulQual93 = DEFAULT_MER_93;
 
-	u32 ulDVBTStaticTSClock = 1;
-	u32 ulDVBCStaticTSClock = 1;
-
 	u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
 	u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
 
@@ -662,7 +654,6 @@ static int init_state(struct drxk_state *state)
 	u32 ulGPIOCfg = 0x0113;
 	u32 ulInvertTSClock = 0;
 	u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
-	u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
 	u32 ulDVBTBitrate = 50000000;
 	u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
 
@@ -815,8 +806,7 @@ static int init_state(struct drxk_state *state)
 	state->m_invertSTR = false;	/* If TRUE; invert STR signals */
 	state->m_invertVAL = false;	/* If TRUE; invert VAL signals */
 	state->m_invertCLK = (ulInvertTSClock != 0);	/* If TRUE; invert CLK signals */
-	state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
-	state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
+
 	/* If TRUE; static MPEG clockrate will be used;
 	   otherwise clockrate will adapt to the bitrate of the TS */
 
@@ -824,7 +814,6 @@ static int init_state(struct drxk_state *state)
 	state->m_DVBCBitrate = ulDVBCBitrate;
 
 	state->m_TSDataStrength = (ulTSDataStrength & 0x07);
-	state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
 
 	/* Maximum bitrate in b/s in case static clockrate is selected */
 	state->m_mpegTsStaticBitrate = 19392658;
@@ -1189,6 +1178,7 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
 	int status = -1;
 	u16 sioPdrMclkCfg = 0;
 	u16 sioPdrMdxCfg = 0;
+	u16 err_cfg = 0;
 
 	dprintk(1, ": mpeg %s, %s mode\n",
 		mpegEnable ? "enable" : "disable",
@@ -1254,12 +1244,17 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
 		status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
 		if (status < 0)
 			goto error;
-		status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);	/* Disable */
+
+		if (state->enable_merr_cfg)
+			err_cfg = sioPdrMdxCfg;
+
+		status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg);
 		if (status < 0)
 			goto error;
-		status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);	/* Disable */
+		status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg);
 		if (status < 0)
 			goto error;
+
 		if (state->m_enableParallel == true) {
 			/* paralel -> enable MD1 to MD7 */
 			status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
@@ -6070,9 +6065,7 @@ static int init_drxk(struct drxk_state *state)
 		if (status < 0)
 			goto error;
 
-		if (!state->microcode_name)
-			load_microcode(state, "drxk_a3.mc");
-		else
+		if (state->microcode_name)
 			load_microcode(state, state->microcode_name);
 
 		/* disable token-ring bus through OFDM block for possible ucode upload */
@@ -6323,15 +6316,12 @@ static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_t
 	switch (p->delivery_system) {
 	case SYS_DVBC_ANNEX_A:
 	case SYS_DVBC_ANNEX_C:
+	case SYS_DVBT:
 		sets->min_delay_ms = 3000;
 		sets->max_drift = 0;
 		sets->step_size = 0;
 		return 0;
 	default:
-		/*
-		 * For DVB-T, let it use the default DVB core way, that is:
-		 *	fepriv->step_size = fe->ops.info.frequency_stepsize * 2
-		 */
 		return -EINVAL;
 	}
 }
@@ -6391,6 +6381,21 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 	state->antenna_gpio = config->antenna_gpio;
 	state->antenna_dvbt = config->antenna_dvbt;
 	state->m_ChunkSize = config->chunk_size;
+	state->enable_merr_cfg = config->enable_merr_cfg;
+
+	if (config->dynamic_clk) {
+		state->m_DVBTStaticCLK = 0;
+		state->m_DVBCStaticCLK = 0;
+	} else {
+		state->m_DVBTStaticCLK = 1;
+		state->m_DVBCStaticCLK = 1;
+	}
+
+
+	if (config->mpeg_out_clk_strength)
+		state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07;
+	else
+		state->m_TSClockkStrength = 0x06;
 
 	if (config->parallel_ts)
 		state->m_enableParallel = true;
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
index 3a58b73..4bbf841 100644
--- a/drivers/media/dvb/frontends/drxk_hard.h
+++ b/drivers/media/dvb/frontends/drxk_hard.h
@@ -332,6 +332,7 @@ struct drxk_state {
 
 	u16	UIO_mask;	/* Bits used by UIO */
 
+	bool	enable_merr_cfg;
 	bool	single_master;
 	bool	no_i2c_bridge;
 	bool	antenna_dvbt;
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index ae6f22a..35d72b4 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -1272,7 +1272,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
 	/* allocate memory for the internal state */
 	state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
 	if (!state) {
-		printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
+		printk(KERN_ERR "Can't allocate memory for tda10045 state\n");
 		return NULL;
 	}
 
@@ -1342,7 +1342,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
 	/* allocate memory for the internal state */
 	state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
 	if (!state) {
-		printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
+		printk(KERN_ERR "Can't allocate memory for tda10046 state\n");
 		return NULL;
 	}
 
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c
index 672cf4d..10c68df 100644
--- a/drivers/media/dvb/mantis/mantis_hif.c
+++ b/drivers/media/dvb/mantis/mantis_hif.c
@@ -76,7 +76,7 @@ static int mantis_hif_write_wait(struct mantis_ca *ca)
 		udelay(500);
 		timeout++;
 		if (timeout > 100) {
-			dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num);
+			dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timed out!", mantis->num);
 			rc = -ETIMEDOUT;
 			break;
 		}
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 8418c02..7539a5d 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -216,6 +216,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
 	struct drxk_config config;
 
 	memset(&config, 0, sizeof(config));
+	config.microcode_name = "drxk_a3.mc";
 	config.adr = 0x29 + (chan->number ^ 2);
 
 	chan->fe = dvb_attach(drxk_attach, &config, i2c);
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index e954781..dc2cc93 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -80,6 +80,16 @@ config RADIO_SI4713
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-si4713.
 
+config USB_KEENE
+	tristate "Keene FM Transmitter USB support"
+	depends on USB && VIDEO_V4L2
+	---help---
+	  Say Y here if you want to connect this type of FM transmitter
+	  to your computer's USB port.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-keene.
+
 config RADIO_TEA5764
 	tristate "TEA5764 I2C FM radio support"
 	depends on I2C && VIDEO_V4L2
@@ -167,6 +177,10 @@ menuconfig V4L_RADIO_ISA_DRIVERS
 
 if V4L_RADIO_ISA_DRIVERS
 
+config RADIO_ISA
+	depends on ISA
+	tristate
+
 config RADIO_CADET
 	tristate "ADS Cadet AM/FM Tuner"
 	depends on ISA && VIDEO_V4L2
@@ -174,20 +188,13 @@ config RADIO_CADET
 	  Choose Y here if you have one of these AM/FM radio cards, and then
 	  fill in the port address below.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
-	  Further documentation on this driver can be found on the WWW at
-	  <http://linux.blackhawke.net/cadet/>.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-cadet.
 
 config RADIO_RTRACK
 	tristate "AIMSlab RadioTrack (aka RadioReveal) support"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
 	  Choose Y here if you have one of these FM radio cards, and then fill
 	  in the port address below.
@@ -201,11 +208,7 @@ config RADIO_RTRACK
 	  You must also pass the module a suitable io parameter, 0x248 has
 	  been reported to be used by these cards.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>. More information is
-	  contained in the file
+	  More information is contained in the file
 	  <file:Documentation/video4linux/radiotrack.txt>.
 
 	  To compile this driver as a module, choose M here: the
@@ -214,7 +217,7 @@ config RADIO_RTRACK
 config RADIO_RTRACK_PORT
 	hex "RadioTrack i/o port (0x20f or 0x30f)"
 	depends on RADIO_RTRACK=y
-	default "20f"
+	default "30f"
 	help
 	  Enter either 0x30f or 0x20f here.  The card default is 0x30f, if you
 	  haven't changed the jumper setting on the card.
@@ -222,14 +225,14 @@ config RADIO_RTRACK_PORT
 config RADIO_RTRACK2
 	tristate "AIMSlab RadioTrack II support"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
 	  Choose Y here if you have this FM radio card, and then fill in the
 	  port address below.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
+	  Note: this driver hasn't been tested since a long time due to lack
+	  of hardware. If you have this hardware, then please contact the
+	  linux-media mailinglist.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-rtrack2.
@@ -245,15 +248,11 @@ config RADIO_RTRACK2_PORT
 config RADIO_AZTECH
 	tristate "Aztech/Packard Bell Radio"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
 	  Choose Y here if you have one of these FM radio cards, and then fill
 	  in the port address below.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-aztech.
 
@@ -269,6 +268,7 @@ config RADIO_AZTECH_PORT
 config RADIO_GEMTEK
 	tristate "GemTek Radio card (or compatible) support"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
 	  Choose Y here if you have this FM radio card, and then fill in the
 	  I/O port address and settings below. The following cards either have
@@ -278,23 +278,21 @@ config RADIO_GEMTEK
 	  - Typhoon Radio card (some models)
 	  - Hama Radio card
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-gemtek.
 
 config RADIO_GEMTEK_PORT
-	hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0c24c or 0x28c)"
+	hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c)"
 	depends on RADIO_GEMTEK=y
 	default "34c"
 	help
-	  Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
-	  0x34c, if you haven't changed the jumper setting on the card. On
-	  Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
+	  Enter either 0x20c, 0x30c, 0x24c, 0x34c, 0x248 or 0x28c here. The
+	  card default is 0x34c, if you haven't changed the jumper setting
+	  on the card.
+
+	  On Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
 	  port is 0x20c, 0x248 or 0x28c.
+
 	  If automatic I/O port probing is enabled this port will be used only
 	  in case of automatic probing failure, ie. as a fallback.
 
@@ -318,11 +316,6 @@ config RADIO_MIROPCM20
 	  sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
 	  is required for the radio-miropcm20.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-miropcm20.
 
@@ -332,11 +325,6 @@ config RADIO_SF16FMI
 	---help---
 	  Choose Y here if you have one of these FM radio cards.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-sf16fmi.
 
@@ -346,50 +334,35 @@ config RADIO_SF16FMR2
 	---help---
 	  Choose Y here if you have one of these FM radio cards.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found on the WWW at
-	  <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
-
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-sf16fmr2.
 
 config RADIO_TERRATEC
 	tristate "TerraTec ActiveRadio ISA Standalone"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
-	  Choose Y here if you have this FM radio card, and then fill in the
-	  port address below. (TODO)
+	  Choose Y here if you have this FM radio card.
 
-	  Note: This driver is in its early stages.  Right now volume and
-	  frequency control and muting works at least for me, but
-	  unfortunately I have not found anybody who wants to use this card
-	  with Linux.  So if it is this what YOU are trying to do right now,
-	  PLEASE DROP ME A NOTE!!  Rolf Offermanns <rolf@offermanns.de>.
-
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
+	  Note: this driver hasn't been tested since a long time due to lack
+	  of hardware. If you have this hardware, then please contact the
+	  linux-media mailinglist.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-terratec.
 
-config RADIO_TERRATEC_PORT
-	hex "Terratec i/o port (normally 0x590)"
-	depends on RADIO_TERRATEC=y
-	default "590"
-	help
-	  Fill in the I/O port of your TerraTec FM radio card. If unsure, go
-	  with the default.
-
 config RADIO_TRUST
 	tristate "Trust FM radio card"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	help
 	  This is a driver for the Trust FM radio cards. Say Y if you have
 	  such a card and want to use it under Linux.
 
+	  Note: this driver hasn't been tested since a long time due to lack
+	  of hardware. If you have this hardware, then please contact the
+	  linux-media mailinglist.
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-trust.
 
@@ -404,14 +377,14 @@ config RADIO_TRUST_PORT
 config RADIO_TYPHOON
 	tristate "Typhoon Radio (a.k.a. EcoRadio)"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
 	  Choose Y here if you have one of these FM radio cards, and then fill
 	  in the port address and the frequency used for muting below.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
+	  Note: this driver hasn't been tested since a long time due to lack
+	  of hardware. If you have this hardware, then please contact the
+	  linux-media mailinglist.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-typhoon.
@@ -438,14 +411,14 @@ config RADIO_TYPHOON_MUTEFREQ
 config RADIO_ZOLTRIX
 	tristate "Zoltrix Radio"
 	depends on ISA && VIDEO_V4L2
+	select RADIO_ISA
 	---help---
 	  Choose Y here if you have one of these FM radio cards, and then fill
 	  in the port address below.
 
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
+	  Note: this driver hasn't been tested since a long time due to lack
+	  of hardware. If you have this hardware, then please contact the
+	  linux-media mailinglist.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-zoltrix.
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 390daf9..ca8c7d1 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the kernel character device drivers.
 #
 
+obj-$(CONFIG_RADIO_ISA) += radio-isa.o
 obj-$(CONFIG_RADIO_AZTECH) += radio-aztech.o
 obj-$(CONFIG_RADIO_RTRACK2) += radio-rtrack2.o
 obj-$(CONFIG_RADIO_SF16FMI) += radio-sf16fmi.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
 obj-$(CONFIG_USB_DSBR) += dsbr100.o
 obj-$(CONFIG_RADIO_SI470X) += si470x/
 obj-$(CONFIG_USB_MR800) += radio-mr800.o
+obj-$(CONFIG_USB_KEENE) += radio-keene.o
 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
 obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
 obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 1c3f844..862dfce 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -1,16 +1,13 @@
-/* radiotrack (radioreveal) driver for Linux radio support
- * (c) 1997 M. Kirkwood
+/*
+ * AimsLab RadioTrack (aka RadioVeveal) driver
+ *
+ * Copyright 1997 M. Kirkwood
+ *
+ * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
  * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
  * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
- * History:
- * 1999-02-24	Russell Kroll <rkroll@exploits.org>
- * 		Fine tuning/VIDEO_TUNER_LOW
- *		Frequency range expanded to start at 87 MHz
- *
- * TODO: Allow for more than one of these foolish entities :-)
- *
  * Notes on the hardware (reverse engineered from other peoples'
  * reverse engineering of AIMS' code :-)
  *
@@ -26,6 +23,7 @@
  *   wait(a_wee_while);
  *   out(port, stop_changing_the_volume);
  *
+ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
  */
 
 #include <linux/module.h>	/* Modules 			*/
@@ -36,399 +34,176 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include "radio-isa.h"
 
-MODULE_AUTHOR("M.Kirkwood");
+MODULE_AUTHOR("M. Kirkwood");
 MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
+MODULE_VERSION("1.0.0");
 
 #ifndef CONFIG_RADIO_RTRACK_PORT
 #define CONFIG_RADIO_RTRACK_PORT -1
 #endif
 
-static int io = CONFIG_RADIO_RTRACK_PORT;
-static int radio_nr = -1;
+#define RTRACK_MAX 2
 
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
-module_param(radio_nr, int, 0);
+static int io[RTRACK_MAX] = { [0] = CONFIG_RADIO_RTRACK_PORT,
+			      [1 ... (RTRACK_MAX - 1)] = -1 };
+static int radio_nr[RTRACK_MAX]	= { [0 ... (RTRACK_MAX - 1)] = -1 };
 
-struct rtrack
-{
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int port;
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)");
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
+
+struct rtrack {
+	struct radio_isa_card isa;
 	int curvol;
-	unsigned long curfreq;
-	int muted;
-	int io;
-	struct mutex lock;
 };
 
-static struct rtrack rtrack_card;
-
-/* local things */
-
-static void rt_decvol(struct rtrack *rt)
-{
-	outb(0x58, rt->io);		/* volume down + sigstr + on	*/
-	msleep(100);
-	outb(0xd8, rt->io);		/* volume steady + sigstr + on	*/
-}
-
-static void rt_incvol(struct rtrack *rt)
-{
-	outb(0x98, rt->io);		/* volume up + sigstr + on	*/
-	msleep(100);
-	outb(0xd8, rt->io);		/* volume steady + sigstr + on	*/
-}
-
-static void rt_mute(struct rtrack *rt)
-{
-	rt->muted = 1;
-	mutex_lock(&rt->lock);
-	outb(0xd0, rt->io);		/* volume steady, off		*/
-	mutex_unlock(&rt->lock);
-}
-
-static int rt_setvol(struct rtrack *rt, int vol)
+static struct radio_isa_card *rtrack_alloc(void)
 {
-	int i;
-
-	mutex_lock(&rt->lock);
-
-	if (vol == rt->curvol) {	/* requested volume = current */
-		if (rt->muted) {	/* user is unmuting the card  */
-			rt->muted = 0;
-			outb(0xd8, rt->io);	/* enable card */
-		}
-		mutex_unlock(&rt->lock);
-		return 0;
-	}
-
-	if (vol == 0) {			/* volume = 0 means mute the card */
-		outb(0x48, rt->io);	/* volume down but still "on"	*/
-		msleep(2000);	/* make sure it's totally down	*/
-		outb(0xd0, rt->io);	/* volume steady, off		*/
-		rt->curvol = 0;		/* track the volume state!	*/
-		mutex_unlock(&rt->lock);
-		return 0;
-	}
+	struct rtrack *rt = kzalloc(sizeof(struct rtrack), GFP_KERNEL);
 
-	rt->muted = 0;
-	if (vol > rt->curvol)
-		for (i = rt->curvol; i < vol; i++)
-			rt_incvol(rt);
-	else
-		for (i = rt->curvol; i > vol; i--)
-			rt_decvol(rt);
-
-	rt->curvol = vol;
-	mutex_unlock(&rt->lock);
-	return 0;
+	if (rt)
+		rt->curvol = 0xff;
+	return rt ? &rt->isa : NULL;
 }
 
-/* the 128+64 on these outb's is to keep the volume stable while tuning
- * without them, the volume _will_ creep up with each frequency change
- * and bit 4 (+16) is to keep the signal strength meter enabled
+/* The 128+64 on these outb's is to keep the volume stable while tuning.
+ * Without them, the volume _will_ creep up with each frequency change
+ * and bit 4 (+16) is to keep the signal strength meter enabled.
  */
 
-static void send_0_byte(struct rtrack *rt)
+static void send_0_byte(struct radio_isa_card *isa, int on)
 {
-	if (rt->curvol == 0 || rt->muted) {
-		outb_p(128+64+16+  1, rt->io);   /* wr-enable + data low */
-		outb_p(128+64+16+2+1, rt->io);   /* clock */
-	}
-	else {
-		outb_p(128+64+16+8+  1, rt->io);  /* on + wr-enable + data low */
-		outb_p(128+64+16+8+2+1, rt->io);  /* clock */
-	}
+	outb_p(128+64+16+on+1, isa->io);	/* wr-enable + data low */
+	outb_p(128+64+16+on+2+1, isa->io);	/* clock */
 	msleep(1);
 }
 
-static void send_1_byte(struct rtrack *rt)
+static void send_1_byte(struct radio_isa_card *isa, int on)
 {
-	if (rt->curvol == 0 || rt->muted) {
-		outb_p(128+64+16+4  +1, rt->io);   /* wr-enable+data high */
-		outb_p(128+64+16+4+2+1, rt->io);   /* clock */
-	}
-	else {
-		outb_p(128+64+16+8+4  +1, rt->io); /* on+wr-enable+data high */
-		outb_p(128+64+16+8+4+2+1, rt->io); /* clock */
-	}
-
+	outb_p(128+64+16+on+4+1, isa->io);	/* wr-enable+data high */
+	outb_p(128+64+16+on+4+2+1, isa->io);	/* clock */
 	msleep(1);
 }
 
-static int rt_setfreq(struct rtrack *rt, unsigned long freq)
+static int rtrack_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
+	int on = v4l2_ctrl_g_ctrl(isa->mute) ? 0 : 8;
 	int i;
 
-	mutex_lock(&rt->lock);			/* Stop other ops interfering */
-
-	rt->curfreq = freq;
-
-	/* now uses VIDEO_TUNER_LOW for fine tuning */
-
 	freq += 171200;			/* Add 10.7 MHz IF 		*/
 	freq /= 800;			/* Convert to 50 kHz units	*/
 
-	send_0_byte(rt);		/*  0: LSB of frequency		*/
+	send_0_byte(isa, on);		/*  0: LSB of frequency		*/
 
 	for (i = 0; i < 13; i++)	/*   : frequency bits (1-13)	*/
 		if (freq & (1 << i))
-			send_1_byte(rt);
+			send_1_byte(isa, on);
 		else
-			send_0_byte(rt);
-
-	send_0_byte(rt);		/* 14: test bit - always 0    */
-	send_0_byte(rt);		/* 15: test bit - always 0    */
-
-	send_0_byte(rt);		/* 16: band data 0 - always 0 */
-	send_0_byte(rt);		/* 17: band data 1 - always 0 */
-	send_0_byte(rt);		/* 18: band data 2 - always 0 */
-	send_0_byte(rt);		/* 19: time base - always 0   */
-
-	send_0_byte(rt);		/* 20: spacing (0 = 25 kHz)   */
-	send_1_byte(rt);		/* 21: spacing (1 = 25 kHz)   */
-	send_0_byte(rt);		/* 22: spacing (0 = 25 kHz)   */
-	send_1_byte(rt);		/* 23: AM/FM (FM = 1, always) */
-
-	if (rt->curvol == 0 || rt->muted)
-		outb(0xd0, rt->io);	/* volume steady + sigstr */
-	else
-		outb(0xd8, rt->io);	/* volume steady + sigstr + on */
-
-	mutex_unlock(&rt->lock);
-
-	return 0;
-}
-
-static int rt_getsigstr(struct rtrack *rt)
-{
-	int sig = 1;
-
-	mutex_lock(&rt->lock);
-	if (inb(rt->io) & 2)	/* bit set = no signal present	*/
-		sig = 0;
-	mutex_unlock(&rt->lock);
-	return sig;
-}
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
-	strlcpy(v->card, "RadioTrack", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	struct rtrack *rt = video_drvdata(file);
+			send_0_byte(isa, on);
 
-	if (v->index > 0)
-		return -EINVAL;
+	send_0_byte(isa, on);		/* 14: test bit - always 0    */
+	send_0_byte(isa, on);		/* 15: test bit - always 0    */
 
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = 87 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xffff * rt_getsigstr(rt);
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct rtrack *rt = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	rt_setfreq(rt, f->frequency);
-	return 0;
-}
+	send_0_byte(isa, on);		/* 16: band data 0 - always 0 */
+	send_0_byte(isa, on);		/* 17: band data 1 - always 0 */
+	send_0_byte(isa, on);		/* 18: band data 2 - always 0 */
+	send_0_byte(isa, on);		/* 19: time base - always 0   */
 
-static int vidioc_g_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct rtrack *rt = video_drvdata(file);
+	send_0_byte(isa, on);		/* 20: spacing (0 = 25 kHz)   */
+	send_1_byte(isa, on);		/* 21: spacing (1 = 25 kHz)   */
+	send_0_byte(isa, on);		/* 22: spacing (0 = 25 kHz)   */
+	send_1_byte(isa, on);		/* 23: AM/FM (FM = 1, always) */
 
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = rt->curfreq;
+	outb(0xd0 + on, isa->io);	/* volume steady + sigstr */
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
+static u32 rtrack_g_signal(struct radio_isa_card *isa)
 {
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
-	}
-	return -EINVAL;
+	/* bit set = no signal present */
+	return 0xffff * !(inb(isa->io) & 2);
 }
 
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
+static int rtrack_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
-	struct rtrack *rt = video_drvdata(file);
+	struct rtrack *rt = container_of(isa, struct rtrack, isa);
+	int curvol = rt->curvol;
 
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = rt->muted;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = rt->curvol;
+	if (mute) {
+		outb(0xd0, isa->io);	/* volume steady + sigstr + off	*/
 		return 0;
 	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct rtrack *rt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			rt_mute(rt);
-		else
-			rt_setvol(rt, rt->curvol);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		rt_setvol(rt, ctrl->value);
-		return 0;
+	if (vol == 0) {			/* volume = 0 means mute the card */
+		outb(0x48, isa->io);	/* volume down but still "on"	*/
+		msleep(curvol * 3);	/* make sure it's totally down	*/
+	} else if (curvol < vol) {
+		outb(0x98, isa->io);	/* volume up + sigstr + on	*/
+		for (; curvol < vol; curvol++)
+			udelay(3000);
+	} else if (curvol > vol) {
+		outb(0x58, isa->io);	/* volume down + sigstr + on	*/
+		for (; curvol > vol; curvol--)
+			udelay(3000);
 	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
+	outb(0xd8, isa->io);		/* volume steady + sigstr + on	*/
+	rt->curvol = vol;
 	return 0;
 }
 
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+/* Mute card - prevents noisy bootups */
+static int rtrack_initialize(struct radio_isa_card *isa)
 {
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
+	/* this ensures that the volume is all the way up  */
+	outb(0x90, isa->io);	/* volume up but still "on"	*/
+	msleep(3000);		/* make sure it's totally up	*/
+	outb(0xc0, isa->io);	/* steady volume, mute card	*/
 	return 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
-static const struct v4l2_file_operations rtrack_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops rtrack_ops = {
+	.alloc = rtrack_alloc,
+	.init = rtrack_initialize,
+	.s_mute_volume = rtrack_s_mute_volume,
+	.s_frequency = rtrack_s_frequency,
+	.g_signal = rtrack_g_signal,
 };
 
-static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+static const int rtrack_ioports[] = { 0x20f, 0x30f };
+
+static struct radio_isa_driver rtrack_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-aimslab",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = rtrack_ioports,
+	.num_of_io_ports = ARRAY_SIZE(rtrack_ioports),
+	.region_size = 2,
+	.card = "AIMSlab RadioTrack/RadioReveal",
+	.ops = &rtrack_ops,
+	.has_stereo = true,
+	.max_volume = 0xff,
 };
 
 static int __init rtrack_init(void)
 {
-	struct rtrack *rt = &rtrack_card;
-	struct v4l2_device *v4l2_dev = &rt->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name));
-	rt->io = io;
-
-	if (rt->io == -1) {
-		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n");
-		return -EINVAL;
-	}
-
-	if (!request_region(rt->io, 2, "rtrack")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(rt->io, 2);
-		v4l2_err(v4l2_dev, "could not register v4l2_device\n");
-		return res;
-	}
-
-	strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name));
-	rt->vdev.v4l2_dev = v4l2_dev;
-	rt->vdev.fops = &rtrack_fops;
-	rt->vdev.ioctl_ops = &rtrack_ioctl_ops;
-	rt->vdev.release = video_device_release_empty;
-	video_set_drvdata(&rt->vdev, rt);
-
-	/* Set up the I/O locking */
-
-	mutex_init(&rt->lock);
-
-	/* mute card - prevents noisy bootups */
-
-	/* this ensures that the volume is all the way down  */
-	outb(0x48, rt->io);		/* volume down but still "on"	*/
-	msleep(2000);	/* make sure it's totally down	*/
-	outb(0xc0, rt->io);		/* steady volume, mute card	*/
-
-	if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(&rt->v4l2_dev);
-		release_region(rt->io, 2);
-		return -EINVAL;
-	}
-	v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
-
-	return 0;
+	return isa_register_driver(&rtrack_driver.driver, RTRACK_MAX);
 }
 
 static void __exit rtrack_exit(void)
 {
-	struct rtrack *rt = &rtrack_card;
-
-	video_unregister_device(&rt->vdev);
-	v4l2_device_unregister(&rt->v4l2_dev);
-	release_region(rt->io, 2);
+	isa_unregister_driver(&rtrack_driver.driver);
 }
 
 module_init(rtrack_init);
 module_exit(rtrack_exit);
-
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index eed7b08..8117fdf 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -1,5 +1,7 @@
-/* radio-aztech.c - Aztech radio card driver for Linux 2.2
+/*
+ * radio-aztech.c - Aztech radio card driver
  *
+ * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@xs4all.nl>
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
  * Adapted to support the Video for Linux API by
  * Russell Kroll <rkroll@exploits.org>.  Based on original tuner code by:
@@ -10,19 +12,7 @@
  * Scott McGrath    (smcgrath@twilight.vtc.vsc.edu)
  * William McGrath  (wmcgrath@twilight.vtc.vsc.edu)
  *
- * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/
- * along with more information on the card itself.
- *
- * History:
- * 1999-02-24	Russell Kroll <rkroll@exploits.org>
- *		Fine tuning/VIDEO_TUNER_LOW
- * 		Range expanded to 87-108 MHz (from 87.9-107.8)
- *
- * Notable changes from the original source:
- * - includes stripped down to the essentials
- * - for loops used as delays replaced with udelay()
- * - #defines removed, changed to static values
- * - tuning structure changed - no more character arrays, other changes
+ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
 */
 
 #include <linux/module.h>	/* Modules 			*/
@@ -33,124 +23,69 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include "radio-isa.h"
 
 MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the Aztech radio card.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
+MODULE_VERSION("1.0.0");
 
 /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
-
 #ifndef CONFIG_RADIO_AZTECH_PORT
 #define CONFIG_RADIO_AZTECH_PORT -1
 #endif
 
-static int io = CONFIG_RADIO_AZTECH_PORT;
-static int radio_nr = -1;
-static int radio_wait_time = 1000;
+#define AZTECH_MAX 2
 
-module_param(io, int, 0);
-module_param(radio_nr, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
+static int io[AZTECH_MAX] = { [0] = CONFIG_RADIO_AZTECH_PORT,
+			      [1 ... (AZTECH_MAX - 1)] = -1 };
+static int radio_nr[AZTECH_MAX]	= { [0 ... (AZTECH_MAX - 1)] = -1 };
+static const int radio_wait_time = 1000;
 
-struct aztech
-{
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int io;
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "I/O addresses of the Aztech card (0x350 or 0x358)");
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
+
+struct aztech {
+	struct radio_isa_card isa;
 	int curvol;
-	unsigned long curfreq;
-	int stereo;
-	struct mutex lock;
 };
 
-static struct aztech aztech_card;
-
-static int volconvert(int level)
-{
-	level >>= 14;		/* Map 16bits down to 2 bit */
-	level &= 3;
-
-	/* convert to card-friendly values */
-	switch (level) {
-	case 0:
-		return 0;
-	case 1:
-		return 1;
-	case 2:
-		return 4;
-	case 3:
-		return 5;
-	}
-	return 0;	/* Quieten gcc */
-}
-
 static void send_0_byte(struct aztech *az)
 {
 	udelay(radio_wait_time);
-	outb_p(2 + volconvert(az->curvol), az->io);
-	outb_p(64 + 2 + volconvert(az->curvol), az->io);
+	outb_p(2 + az->curvol, az->isa.io);
+	outb_p(64 + 2 + az->curvol, az->isa.io);
 }
 
 static void send_1_byte(struct aztech *az)
 {
-	udelay (radio_wait_time);
-	outb_p(128 + 2 + volconvert(az->curvol), az->io);
-	outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io);
-}
-
-static int az_setvol(struct aztech *az, int vol)
-{
-	mutex_lock(&az->lock);
-	outb(volconvert(vol), az->io);
-	mutex_unlock(&az->lock);
-	return 0;
-}
-
-/* thanks to Michael Dwyer for giving me a dose of clues in
- * the signal strength department..
- *
- * This card has a stereo bit - bit 0 set = mono, not set = stereo
- * It also has a "signal" bit - bit 1 set = bad signal, not set = good
- *
- */
-
-static int az_getsigstr(struct aztech *az)
-{
-	int sig = 1;
-
-	mutex_lock(&az->lock);
-	if (inb(az->io) & 2)	/* bit set = no signal present */
-		sig = 0;
-	mutex_unlock(&az->lock);
-	return sig;
+	udelay(radio_wait_time);
+	outb_p(128 + 2 + az->curvol, az->isa.io);
+	outb_p(128 + 64 + 2 + az->curvol, az->isa.io);
 }
 
-static int az_getstereo(struct aztech *az)
+static struct radio_isa_card *aztech_alloc(void)
 {
-	int stereo = 1;
+	struct aztech *az = kzalloc(sizeof(*az), GFP_KERNEL);
 
-	mutex_lock(&az->lock);
-	if (inb(az->io) & 1) 	/* bit set = mono */
-		stereo = 0;
-	mutex_unlock(&az->lock);
-	return stereo;
+	return az ? &az->isa : NULL;
 }
 
-static int az_setfreq(struct aztech *az, unsigned long frequency)
+static int aztech_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
+	struct aztech *az = container_of(isa, struct aztech, isa);
 	int  i;
 
-	mutex_lock(&az->lock);
-
-	az->curfreq = frequency;
-	frequency += 171200;		/* Add 10.7 MHz IF		*/
-	frequency /= 800;		/* Convert to 50 kHz units	*/
+	freq += 171200;			/* Add 10.7 MHz IF		*/
+	freq /= 800;			/* Convert to 50 kHz units	*/
 
 	send_0_byte(az);		/*  0: LSB of frequency       */
 
 	for (i = 0; i < 13; i++)	/*   : frequency bits (1-13)  */
-		if (frequency & (1 << i))
+		if (freq & (1 << i))
 			send_1_byte(az);
 		else
 			send_0_byte(az);
@@ -158,7 +93,7 @@ static int az_setfreq(struct aztech *az, unsigned long frequency)
 	send_0_byte(az);		/* 14: test bit - always 0    */
 	send_0_byte(az);		/* 15: test bit - always 0    */
 	send_0_byte(az);		/* 16: band data 0 - always 0 */
-	if (az->stereo)		/* 17: stereo (1 to enable)   */
+	if (isa->stereo)		/* 17: stereo (1 to enable)   */
 		send_1_byte(az);
 	else
 		send_0_byte(az);
@@ -173,225 +108,77 @@ static int az_setfreq(struct aztech *az, unsigned long frequency)
 	/* latch frequency */
 
 	udelay(radio_wait_time);
-	outb_p(128 + 64 + volconvert(az->curvol), az->io);
-
-	mutex_unlock(&az->lock);
-
-	return 0;
-}
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-aztech", sizeof(v->driver));
-	strlcpy(v->card, "Aztech Radio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-				struct v4l2_tuner *v)
-{
-	struct aztech *az = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-
-	v->rangelow = 87 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	if (az_getstereo(az))
-		v->audmode = V4L2_TUNER_MODE_STEREO;
-	else
-		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF * az_getsigstr(az);
-
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-				struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
+	outb_p(128 + 64 + az->curvol, az->isa.io);
 
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
 	return 0;
 }
 
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-			   struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-			   struct v4l2_audio *a)
+/* thanks to Michael Dwyer for giving me a dose of clues in
+ * the signal strength department..
+ *
+ * This card has a stereo bit - bit 0 set = mono, not set = stereo
+ */
+static u32 aztech_g_rxsubchans(struct radio_isa_card *isa)
 {
-	return a->index ? -EINVAL : 0;
+	if (inb(isa->io) & 1)
+		return V4L2_TUNER_SUB_MONO;
+	return V4L2_TUNER_SUB_STEREO;
 }
 
-static int vidioc_s_frequency(struct file *file, void *priv,
-				struct v4l2_frequency *f)
+static int aztech_s_stereo(struct radio_isa_card *isa, bool stereo)
 {
-	struct aztech *az = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	az_setfreq(az, f->frequency);
-	return 0;
+	return aztech_s_frequency(isa, isa->freq);
 }
 
-static int vidioc_g_frequency(struct file *file, void *priv,
-				struct v4l2_frequency *f)
+static int aztech_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
-	struct aztech *az = video_drvdata(file);
+	struct aztech *az = container_of(isa, struct aztech, isa);
 
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = az->curfreq;
+	if (mute)
+		vol = 0;
+	az->curvol = (vol & 1) + ((vol & 2) << 1);
+	outb(az->curvol, isa->io);
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-			    struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-			    struct v4l2_control *ctrl)
-{
-	struct aztech *az = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (az->curvol == 0)
-			ctrl->value = 1;
-		else
-			ctrl->value = 0;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = az->curvol * 6554;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-			    struct v4l2_control *ctrl)
-{
-	struct aztech *az = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			az_setvol(az, 0);
-		else
-			az_setvol(az, az->curvol);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		az_setvol(az, ctrl->value);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static const struct v4l2_file_operations aztech_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops aztech_ops = {
+	.alloc = aztech_alloc,
+	.s_mute_volume = aztech_s_mute_volume,
+	.s_frequency = aztech_s_frequency,
+	.s_stereo = aztech_s_stereo,
+	.g_rxsubchans = aztech_g_rxsubchans,
 };
 
-static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+static const int aztech_ioports[] = { 0x350, 0x358 };
+
+static struct radio_isa_driver aztech_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-aztech",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = aztech_ioports,
+	.num_of_io_ports = ARRAY_SIZE(aztech_ioports),
+	.region_size = 2,
+	.card = "Aztech Radio",
+	.ops = &aztech_ops,
+	.has_stereo = true,
+	.max_volume = 3,
 };
 
 static int __init aztech_init(void)
 {
-	struct aztech *az = &aztech_card;
-	struct v4l2_device *v4l2_dev = &az->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name));
-	az->io = io;
-
-	if (az->io == -1) {
-		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n");
-		return -EINVAL;
-	}
-
-	if (!request_region(az->io, 2, "aztech")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(az->io, 2);
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		return res;
-	}
-
-	mutex_init(&az->lock);
-	strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name));
-	az->vdev.v4l2_dev = v4l2_dev;
-	az->vdev.fops = &aztech_fops;
-	az->vdev.ioctl_ops = &aztech_ioctl_ops;
-	az->vdev.release = video_device_release_empty;
-	video_set_drvdata(&az->vdev, az);
-	/* mute card - prevents noisy bootups */
-	outb(0, az->io);
-
-	if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(v4l2_dev);
-		release_region(az->io, 2);
-		return -EINVAL;
-	}
-
-	v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
-	return 0;
+	return isa_register_driver(&aztech_driver.driver, AZTECH_MAX);
 }
 
 static void __exit aztech_exit(void)
 {
-	struct aztech *az = &aztech_card;
-
-	video_unregister_device(&az->vdev);
-	v4l2_device_unregister(&az->v4l2_dev);
-	release_region(az->io, 2);
+	isa_unregister_driver(&aztech_driver.driver);
 }
 
 module_init(aztech_init);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 36ce061..9d7fdae 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -1,4 +1,7 @@
-/* GemTek radio card driver for Linux (C) 1998 Jonas Munsin <jmunsin@iki.fi>
+/*
+ * GemTek radio card driver
+ *
+ * Copyright 1998 Jonas Munsin <jmunsin@iki.fi>
  *
  * GemTek hasn't released any specs on the card, so the protocol had to
  * be reverse engineered with dosemu.
@@ -11,9 +14,12 @@
  *    Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
  *    Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
- * TODO: Allow for more than one of these foolish entities :-)
- *
+ * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
+ * Note: this card seems to swap the left and right audio channels!
+ *
+ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
  */
 
 #include <linux/module.h>	/* Modules 			*/
@@ -25,6 +31,7 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
+#include "radio-isa.h"
 
 /*
  * Module info.
@@ -33,7 +40,7 @@
 MODULE_AUTHOR("Jonas Munsin, Pekka Seppänen <pexu@kapsi.fi>");
 MODULE_DESCRIPTION("A driver for the GemTek Radio card.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.4");
+MODULE_VERSION("1.0.0");
 
 /*
  * Module params.
@@ -46,45 +53,29 @@ MODULE_VERSION("0.0.4");
 #define CONFIG_RADIO_GEMTEK_PROBE 1
 #endif
 
-static int io		= CONFIG_RADIO_GEMTEK_PORT;
-static bool probe	= CONFIG_RADIO_GEMTEK_PROBE;
-static bool hardmute;
-static bool shutdown	= 1;
-static bool keepmuted	= 1;
-static bool initmute	= 1;
-static int radio_nr	= -1;
+#define GEMTEK_MAX 4
 
-module_param(io, int, 0444);
-MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic "
-	 "probing is disabled or fails. The most common I/O ports are: 0x20c "
-	 "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to "
-	 "work for the combined sound/radiocard).");
+static bool probe = CONFIG_RADIO_GEMTEK_PROBE;
+static bool hardmute;
+static int io[GEMTEK_MAX] = { [0] = CONFIG_RADIO_GEMTEK_PORT,
+			      [1 ... (GEMTEK_MAX - 1)] = -1 };
+static int radio_nr[GEMTEK_MAX]	= { [0 ... (GEMTEK_MAX - 1)] = -1 };
 
 module_param(probe, bool, 0444);
-MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most "
-	"common I/O ports used by the card are probed.");
+MODULE_PARM_DESC(probe, "Enable automatic device probing.");
 
 module_param(hardmute, bool, 0644);
-MODULE_PARM_DESC(hardmute, "Enable `hard muting' by shutting down PLL, may "
+MODULE_PARM_DESC(hardmute, "Enable 'hard muting' by shutting down PLL, may "
 	 "reduce static noise.");
 
-module_param(shutdown, bool, 0644);
-MODULE_PARM_DESC(shutdown, "Enable shutting down PLL and muting line when "
-	 "module is unloaded.");
-
-module_param(keepmuted, bool, 0644);
-MODULE_PARM_DESC(keepmuted, "Keep card muted even when frequency is changed.");
-
-module_param(initmute, bool, 0444);
-MODULE_PARM_DESC(initmute, "Mute card when module is loaded.");
-
-module_param(radio_nr, int, 0444);
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "Force I/O ports for the GemTek Radio card if automatic "
+	 "probing is disabled or fails. The most common I/O ports are: 0x20c "
+	 "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to "
+	 "work for the combined sound/radiocard).");
 
-/*
- * Functions for controlling the card.
- */
-#define GEMTEK_LOWFREQ	(87*16000)
-#define GEMTEK_HIGHFREQ	(108*16000)
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
 
 /*
  * Frequency calculation constants.  Intermediate frequency 10.52 MHz (nominal
@@ -108,18 +99,11 @@ module_param(radio_nr, int, 0444);
 #define LONG_DELAY 75		/* usec */
 
 struct gemtek {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	struct mutex lock;
-	unsigned long lastfreq;
-	int muted;
-	int verified;
-	int io;
+	struct radio_isa_card isa;
+	bool muted;
 	u32 bu2614data;
 };
 
-static struct gemtek gemtek_card;
-
 #define BU2614_FREQ_BITS 	16 /* D0..D15, Frequency data		*/
 #define BU2614_PORT_BITS	3 /* P0..P2, Output port control data	*/
 #define BU2614_VOID_BITS	4 /* unused 				*/
@@ -166,31 +150,24 @@ static struct gemtek gemtek_card;
  */
 static void gemtek_bu2614_transmit(struct gemtek *gt)
 {
+	struct radio_isa_card *isa = &gt->isa;
 	int i, bit, q, mute;
 
-	mutex_lock(&gt->lock);
-
 	mute = gt->muted ? GEMTEK_MT : 0x00;
 
-	outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
-	udelay(SHORT_DELAY);
-	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
+	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, isa->io);
 	udelay(LONG_DELAY);
 
 	for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) {
 		bit = (q & 1) ? GEMTEK_DA : 0;
-		outb_p(mute | GEMTEK_CE | bit, gt->io);
+		outb_p(mute | GEMTEK_CE | bit, isa->io);
 		udelay(SHORT_DELAY);
-		outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io);
+		outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, isa->io);
 		udelay(SHORT_DELAY);
 	}
 
-	outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
+	outb_p(mute | GEMTEK_DA | GEMTEK_CK, isa->io);
 	udelay(SHORT_DELAY);
-	outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
-	udelay(LONG_DELAY);
-
-	mutex_unlock(&gt->lock);
 }
 
 /*
@@ -198,21 +175,27 @@ static void gemtek_bu2614_transmit(struct gemtek *gt)
  */
 static unsigned long gemtek_convfreq(unsigned long freq)
 {
-	return ((freq<<FSCALE) + IF_OFFSET + REF_FREQ/2) / REF_FREQ;
+	return ((freq << FSCALE) + IF_OFFSET + REF_FREQ / 2) / REF_FREQ;
+}
+
+static struct radio_isa_card *gemtek_alloc(void)
+{
+	struct gemtek *gt = kzalloc(sizeof(*gt), GFP_KERNEL);
+
+	if (gt)
+		gt->muted = true;
+	return gt ? &gt->isa : NULL;
 }
 
 /*
  * Set FM-frequency.
  */
-static void gemtek_setfreq(struct gemtek *gt, unsigned long freq)
+static int gemtek_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
-	if (keepmuted && hardmute && gt->muted)
-		return;
+	struct gemtek *gt = container_of(isa, struct gemtek, isa);
 
-	freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ);
-
-	gt->lastfreq = freq;
-	gt->muted = 0;
+	if (hardmute && gt->muted)
+		return 0;
 
 	gemtek_bu2614_set(gt, BU2614_PORT, 0);
 	gemtek_bu2614_set(gt, BU2614_FMES, 0);
@@ -220,23 +203,25 @@ static void gemtek_setfreq(struct gemtek *gt, unsigned long freq)
 	gemtek_bu2614_set(gt, BU2614_SWAL, 0);
 	gemtek_bu2614_set(gt, BU2614_FMUN, 1);	/* GT bit set	*/
 	gemtek_bu2614_set(gt, BU2614_TEST, 0);
-
 	gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
 	gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq));
-
 	gemtek_bu2614_transmit(gt);
+	return 0;
 }
 
 /*
  * Set mute flag.
  */
-static void gemtek_mute(struct gemtek *gt)
+static int gemtek_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
+	struct gemtek *gt = container_of(isa, struct gemtek, isa);
 	int i;
 
-	gt->muted = 1;
-
+	gt->muted = mute;
 	if (hardmute) {
+		if (!mute)
+			return gemtek_s_frequency(isa, isa->freq);
+
 		/* Turn off PLL, disable data output */
 		gemtek_bu2614_set(gt, BU2614_PORT, 0);
 		gemtek_bu2614_set(gt, BU2614_FMES, 0);	/* CT bit off	*/
@@ -247,367 +232,85 @@ static void gemtek_mute(struct gemtek *gt)
 		gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF);
 		gemtek_bu2614_set(gt, BU2614_FREQ, 0);
 		gemtek_bu2614_transmit(gt);
-		return;
+		return 0;
 	}
 
-	mutex_lock(&gt->lock);
-
 	/* Read bus contents (CE, CK and DA). */
-	i = inb_p(gt->io);
+	i = inb_p(isa->io);
 	/* Write it back with mute flag set. */
-	outb_p((i >> 5) | GEMTEK_MT, gt->io);
+	outb_p((i >> 5) | (mute ? GEMTEK_MT : 0), isa->io);
 	udelay(SHORT_DELAY);
-
-	mutex_unlock(&gt->lock);
-}
-
-/*
- * Unset mute flag.
- */
-static void gemtek_unmute(struct gemtek *gt)
-{
-	int i;
-
-	gt->muted = 0;
-	if (hardmute) {
-		/* Turn PLL back on. */
-		gemtek_setfreq(gt, gt->lastfreq);
-		return;
-	}
-	mutex_lock(&gt->lock);
-
-	i = inb_p(gt->io);
-	outb_p(i >> 5, gt->io);
-	udelay(SHORT_DELAY);
-
-	mutex_unlock(&gt->lock);
+	return 0;
 }
 
-/*
- * Get signal strength (= stereo status).
- */
-static inline int gemtek_getsigstr(struct gemtek *gt)
+static u32 gemtek_g_rxsubchans(struct radio_isa_card *isa)
 {
-	int sig;
-
-	mutex_lock(&gt->lock);
-	sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1;
-	mutex_unlock(&gt->lock);
-	return sig;
+	if (inb_p(isa->io) & GEMTEK_NS)
+		return V4L2_TUNER_SUB_MONO;
+	return V4L2_TUNER_SUB_STEREO;
 }
 
 /*
  * Check if requested card acts like GemTek Radio card.
  */
-static int gemtek_verify(struct gemtek *gt, int port)
+static bool gemtek_probe(struct radio_isa_card *isa, int io)
 {
 	int i, q;
 
-	if (gt->verified == port)
-		return 1;
-
-	mutex_lock(&gt->lock);
-
-	q = inb_p(port);	/* Read bus contents before probing. */
+	q = inb_p(io);	/* Read bus contents before probing. */
 	/* Try to turn on CE, CK and DA respectively and check if card responds
 	   properly. */
 	for (i = 0; i < 3; ++i) {
-		outb_p(1 << i, port);
+		outb_p(1 << i, io);
 		udelay(SHORT_DELAY);
 
-		if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) {
-			mutex_unlock(&gt->lock);
-			return 0;
-		}
+		if ((inb_p(io) & ~GEMTEK_NS) != (0x17 | (1 << (i + 5))))
+			return false;
 	}
-	outb_p(q >> 5, port);	/* Write bus contents back. */
+	outb_p(q >> 5, io);	/* Write bus contents back. */
 	udelay(SHORT_DELAY);
-
-	mutex_unlock(&gt->lock);
-	gt->verified = port;
-
-	return 1;
-}
-
-/*
- * Automatic probing for card.
- */
-static int gemtek_probe(struct gemtek *gt)
-{
-	struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
-	int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
-	int i;
-
-	if (!probe) {
-		v4l2_info(v4l2_dev, "Automatic device probing disabled.\n");
-		return -1;
-	}
-
-	v4l2_info(v4l2_dev, "Automatic device probing enabled.\n");
-
-	for (i = 0; i < ARRAY_SIZE(ioports); ++i) {
-		v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]);
-
-		if (!request_region(ioports[i], 1, "gemtek-probe")) {
-			v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n",
-			       ioports[i]);
-			continue;
-		}
-
-		if (gemtek_verify(gt, ioports[i])) {
-			v4l2_info(v4l2_dev, "Card found from I/O port "
-			       "0x%x!\n", ioports[i]);
-
-			release_region(ioports[i], 1);
-			gt->io = ioports[i];
-			return gt->io;
-		}
-
-		release_region(ioports[i], 1);
-	}
-
-	v4l2_err(v4l2_dev, "Automatic probing failed!\n");
-	return -1;
+	return true;
 }
 
-/*
- * Video 4 Linux stuff.
- */
-
-static const struct v4l2_file_operations gemtek_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops gemtek_ops = {
+	.alloc = gemtek_alloc,
+	.probe = gemtek_probe,
+	.s_mute_volume = gemtek_s_mute_volume,
+	.s_frequency = gemtek_s_frequency,
+	.g_rxsubchans = gemtek_g_rxsubchans,
 };
 
-static int vidioc_querycap(struct file *file, void *priv,
-			   struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
-	strlcpy(v->card, "GemTek", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
-{
-	struct gemtek *gt = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = GEMTEK_LOWFREQ;
-	v->rangehigh = GEMTEK_HIGHFREQ;
-	v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-	v->signal = 0xffff * gemtek_getsigstr(gt);
-	if (v->signal) {
-		v->audmode = V4L2_TUNER_MODE_STEREO;
-		v->rxsubchans = V4L2_TUNER_SUB_STEREO;
-	} else {
-		v->audmode = V4L2_TUNER_MODE_MONO;
-		v->rxsubchans = V4L2_TUNER_SUB_MONO;
-	}
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
-{
-	return (v->index != 0) ? -EINVAL : 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-			      struct v4l2_frequency *f)
-{
-	struct gemtek *gt = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = gt->lastfreq;
-	return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-			      struct v4l2_frequency *f)
-{
-	struct gemtek *gt = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	gemtek_setfreq(gt, f->frequency);
-	return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-			    struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
-	default:
-		return -EINVAL;
-	}
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-			 struct v4l2_control *ctrl)
-{
-	struct gemtek *gt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = gt->muted;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-			 struct v4l2_control *ctrl)
-{
-	struct gemtek *gt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			gemtek_mute(gt);
-		else
-			gemtek_unmute(gt);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return (i != 0) ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
-	return (a->index != 0) ? -EINVAL : 0;
-}
-
-static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
-	.vidioc_querycap	= vidioc_querycap,
-	.vidioc_g_tuner		= vidioc_g_tuner,
-	.vidioc_s_tuner		= vidioc_s_tuner,
-	.vidioc_g_audio		= vidioc_g_audio,
-	.vidioc_s_audio		= vidioc_s_audio,
-	.vidioc_g_input		= vidioc_g_input,
-	.vidioc_s_input		= vidioc_s_input,
-	.vidioc_g_frequency	= vidioc_g_frequency,
-	.vidioc_s_frequency	= vidioc_s_frequency,
-	.vidioc_queryctrl	= vidioc_queryctrl,
-	.vidioc_g_ctrl		= vidioc_g_ctrl,
-	.vidioc_s_ctrl		= vidioc_s_ctrl
+static const int gemtek_ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
+
+static struct radio_isa_driver gemtek_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-gemtek",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = gemtek_ioports,
+	.num_of_io_ports = ARRAY_SIZE(gemtek_ioports),
+	.region_size = 1,
+	.card = "GemTek Radio",
+	.ops = &gemtek_ops,
+	.has_stereo = true,
 };
 
-/*
- * Initialization / cleanup related stuff.
- */
-
 static int __init gemtek_init(void)
 {
-	struct gemtek *gt = &gemtek_card;
-	struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name));
-
-	v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n");
-
-	mutex_init(&gt->lock);
-
-	gt->verified = -1;
-	gt->io = io;
-	gemtek_probe(gt);
-	if (gt->io) {
-		if (!request_region(gt->io, 1, "gemtek")) {
-			v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io);
-			return -EBUSY;
-		}
-
-		if (!gemtek_verify(gt, gt->io))
-			v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not "
-			       "respond properly, check your "
-			       "configuration.\n", gt->io);
-		else
-			v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io);
-	} else if (probe) {
-		v4l2_err(v4l2_dev, "Automatic probing failed and no "
-		       "fixed I/O port defined.\n");
-		return -ENODEV;
-	} else {
-		v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed "
-		       "I/O port defined.");
-		return -EINVAL;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		release_region(gt->io, 1);
-		return res;
-	}
-
-	strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name));
-	gt->vdev.v4l2_dev = v4l2_dev;
-	gt->vdev.fops = &gemtek_fops;
-	gt->vdev.ioctl_ops = &gemtek_ioctl_ops;
-	gt->vdev.release = video_device_release_empty;
-	video_set_drvdata(&gt->vdev, gt);
-
-	/* Set defaults */
-	gt->lastfreq = GEMTEK_LOWFREQ;
-	gt->bu2614data = 0;
-
-	if (initmute)
-		gemtek_mute(gt);
-
-	if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(v4l2_dev);
-		release_region(gt->io, 1);
-		return -EBUSY;
-	}
-
-	return 0;
+	gemtek_driver.probe = probe;
+	return isa_register_driver(&gemtek_driver.driver, GEMTEK_MAX);
 }
 
-/*
- * Module cleanup
- */
 static void __exit gemtek_exit(void)
 {
-	struct gemtek *gt = &gemtek_card;
-	struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
-
-	if (shutdown) {
-		hardmute = 1;	/* Turn off PLL */
-		gemtek_mute(gt);
-	} else {
-		v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n");
-	}
-
-	video_unregister_device(&gt->vdev);
-	v4l2_device_unregister(&gt->v4l2_dev);
-	release_region(gt->io, 1);
+	hardmute = 1;	/* Turn off PLL */
+	isa_unregister_driver(&gemtek_driver.driver);
 }
 
 module_init(gemtek_init);
diff --git a/drivers/media/radio/radio-isa.c b/drivers/media/radio/radio-isa.c
new file mode 100644
index 0000000..02bcead
--- /dev/null
+++ b/drivers/media/radio/radio-isa.c
@@ -0,0 +1,339 @@
+/*
+ * Framework for ISA radio drivers.
+ * This takes care of all the V4L2 scaffolding, allowing the ISA drivers
+ * to concentrate on the actual hardware operation.
+ *
+ * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+
+#include "radio-isa.h"
+
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_DESCRIPTION("A framework for ISA radio drivers.");
+MODULE_LICENSE("GPL");
+
+#define FREQ_LOW  (87U * 16000U)
+#define FREQ_HIGH (108U * 16000U)
+
+static int radio_isa_querycap(struct file *file, void  *priv,
+					struct v4l2_capability *v)
+{
+	struct radio_isa_card *isa = video_drvdata(file);
+
+	strlcpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver));
+	strlcpy(v->card, isa->drv->card, sizeof(v->card));
+	snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name);
+
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	v->device_caps = v->capabilities | V4L2_CAP_DEVICE_CAPS;
+	return 0;
+}
+
+static int radio_isa_g_tuner(struct file *file, void *priv,
+				struct v4l2_tuner *v)
+{
+	struct radio_isa_card *isa = video_drvdata(file);
+	const struct radio_isa_ops *ops = isa->drv->ops;
+
+	if (v->index > 0)
+		return -EINVAL;
+
+	strlcpy(v->name, "FM", sizeof(v->name));
+	v->type = V4L2_TUNER_RADIO;
+	v->rangelow = FREQ_LOW;
+	v->rangehigh = FREQ_HIGH;
+	v->capability = V4L2_TUNER_CAP_LOW;
+	if (isa->drv->has_stereo)
+		v->capability |= V4L2_TUNER_CAP_STEREO;
+
+	if (ops->g_rxsubchans)
+		v->rxsubchans = ops->g_rxsubchans(isa);
+	else
+		v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	v->audmode = isa->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
+	if (ops->g_signal)
+		v->signal = ops->g_signal(isa);
+	else
+		v->signal = (v->rxsubchans & V4L2_TUNER_SUB_STEREO) ?
+								0xffff : 0;
+	return 0;
+}
+
+static int radio_isa_s_tuner(struct file *file, void *priv,
+				struct v4l2_tuner *v)
+{
+	struct radio_isa_card *isa = video_drvdata(file);
+	const struct radio_isa_ops *ops = isa->drv->ops;
+
+	if (v->index)
+		return -EINVAL;
+	if (ops->s_stereo) {
+		isa->stereo = (v->audmode == V4L2_TUNER_MODE_STEREO);
+		return ops->s_stereo(isa, isa->stereo);
+	}
+	return 0;
+}
+
+static int radio_isa_s_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *f)
+{
+	struct radio_isa_card *isa = video_drvdata(file);
+	int res;
+
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
+	f->frequency = clamp(f->frequency, FREQ_LOW, FREQ_HIGH);
+	res = isa->drv->ops->s_frequency(isa, f->frequency);
+	if (res == 0)
+		isa->freq = f->frequency;
+	return res;
+}
+
+static int radio_isa_g_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *f)
+{
+	struct radio_isa_card *isa = video_drvdata(file);
+
+	if (f->tuner != 0)
+		return -EINVAL;
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = isa->freq;
+	return 0;
+}
+
+static int radio_isa_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct radio_isa_card *isa =
+		container_of(ctrl->handler, struct radio_isa_card, hdl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		return isa->drv->ops->s_mute_volume(isa, ctrl->val,
+				isa->volume ? isa->volume->val : 0);
+	}
+	return -EINVAL;
+}
+
+static int radio_isa_log_status(struct file *file, void *priv)
+{
+	struct radio_isa_card *isa = video_drvdata(file);
+
+	v4l2_info(&isa->v4l2_dev, "I/O Port = 0x%03x\n", isa->io);
+	v4l2_ctrl_handler_log_status(&isa->hdl, isa->v4l2_dev.name);
+	return 0;
+}
+
+static int radio_isa_subscribe_event(struct v4l2_fh *fh,
+				struct v4l2_event_subscription *sub)
+{
+	if (sub->type == V4L2_EVENT_CTRL)
+		return v4l2_event_subscribe(fh, sub, 0);
+	return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops radio_isa_ctrl_ops = {
+	.s_ctrl = radio_isa_s_ctrl,
+};
+
+static const struct v4l2_file_operations radio_isa_fops = {
+	.owner		= THIS_MODULE,
+	.open		= v4l2_fh_open,
+	.release	= v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
+	.unlocked_ioctl	= video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops radio_isa_ioctl_ops = {
+	.vidioc_querycap    = radio_isa_querycap,
+	.vidioc_g_tuner     = radio_isa_g_tuner,
+	.vidioc_s_tuner     = radio_isa_s_tuner,
+	.vidioc_g_frequency = radio_isa_g_frequency,
+	.vidioc_s_frequency = radio_isa_s_frequency,
+	.vidioc_log_status  = radio_isa_log_status,
+	.vidioc_subscribe_event   = radio_isa_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+int radio_isa_match(struct device *pdev, unsigned int dev)
+{
+	struct radio_isa_driver *drv = pdev->platform_data;
+
+	return drv->probe || drv->io_params[dev] >= 0;
+}
+EXPORT_SYMBOL_GPL(radio_isa_match);
+
+static bool radio_isa_valid_io(const struct radio_isa_driver *drv, int io)
+{
+	int i;
+
+	for (i = 0; i < drv->num_of_io_ports; i++)
+		if (drv->io_ports[i] == io)
+			return true;
+	return false;
+}
+
+int radio_isa_probe(struct device *pdev, unsigned int dev)
+{
+	struct radio_isa_driver *drv = pdev->platform_data;
+	const struct radio_isa_ops *ops = drv->ops;
+	struct v4l2_device *v4l2_dev;
+	struct radio_isa_card *isa;
+	int res;
+
+	isa = drv->ops->alloc();
+	if (isa == NULL)
+		return -ENOMEM;
+	dev_set_drvdata(pdev, isa);
+	isa->drv = drv;
+	isa->io = drv->io_params[dev];
+	v4l2_dev = &isa->v4l2_dev;
+	strlcpy(v4l2_dev->name, dev_name(pdev), sizeof(v4l2_dev->name));
+
+	if (drv->probe && ops->probe) {
+		int i;
+
+		for (i = 0; i < drv->num_of_io_ports; ++i) {
+			int io = drv->io_ports[i];
+
+			if (request_region(io, drv->region_size, v4l2_dev->name)) {
+				bool found = ops->probe(isa, io);
+
+				release_region(io, drv->region_size);
+				if (found) {
+					isa->io = io;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!radio_isa_valid_io(drv, isa->io)) {
+		int i;
+
+		if (isa->io < 0)
+			return -ENODEV;
+		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x%03x",
+				drv->io_ports[0]);
+		for (i = 1; i < drv->num_of_io_ports; i++)
+			printk(KERN_CONT "/0x%03x", drv->io_ports[i]);
+		printk(KERN_CONT ".\n");
+		kfree(isa);
+		return -EINVAL;
+	}
+
+	if (!request_region(isa->io, drv->region_size, v4l2_dev->name)) {
+		v4l2_err(v4l2_dev, "port 0x%x already in use\n", isa->io);
+		kfree(isa);
+		return -EBUSY;
+	}
+
+	res = v4l2_device_register(pdev, v4l2_dev);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+		goto err_dev_reg;
+	}
+
+	v4l2_ctrl_handler_init(&isa->hdl, 1);
+	isa->mute = v4l2_ctrl_new_std(&isa->hdl, &radio_isa_ctrl_ops,
+				V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
+	if (drv->max_volume)
+		isa->volume = v4l2_ctrl_new_std(&isa->hdl, &radio_isa_ctrl_ops,
+			V4L2_CID_AUDIO_VOLUME, 0, drv->max_volume, 1,
+			drv->max_volume);
+	v4l2_dev->ctrl_handler = &isa->hdl;
+	if (isa->hdl.error) {
+		res = isa->hdl.error;
+		v4l2_err(v4l2_dev, "Could not register controls\n");
+		goto err_hdl;
+	}
+	if (drv->max_volume)
+		v4l2_ctrl_cluster(2, &isa->mute);
+	v4l2_dev->ctrl_handler = &isa->hdl;
+
+	mutex_init(&isa->lock);
+	isa->vdev.lock = &isa->lock;
+	strlcpy(isa->vdev.name, v4l2_dev->name, sizeof(isa->vdev.name));
+	isa->vdev.v4l2_dev = v4l2_dev;
+	isa->vdev.fops = &radio_isa_fops;
+	isa->vdev.ioctl_ops = &radio_isa_ioctl_ops;
+	isa->vdev.release = video_device_release_empty;
+	set_bit(V4L2_FL_USE_FH_PRIO, &isa->vdev.flags);
+	video_set_drvdata(&isa->vdev, isa);
+	isa->freq = FREQ_LOW;
+	isa->stereo = drv->has_stereo;
+
+	if (ops->init)
+		res = ops->init(isa);
+	if (!res)
+		res = v4l2_ctrl_handler_setup(&isa->hdl);
+	if (!res)
+		res = ops->s_frequency(isa, isa->freq);
+	if (!res && ops->s_stereo)
+		res = ops->s_stereo(isa, isa->stereo);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not setup card\n");
+		goto err_node_reg;
+	}
+	res = video_register_device(&isa->vdev, VFL_TYPE_RADIO,
+					drv->radio_nr_params[dev]);
+	if (res < 0) {
+		v4l2_err(v4l2_dev, "Could not register device node\n");
+		goto err_node_reg;
+	}
+
+	v4l2_info(v4l2_dev, "Initialized radio card %s on port 0x%03x\n",
+			drv->card, isa->io);
+	return 0;
+
+err_node_reg:
+	v4l2_ctrl_handler_free(&isa->hdl);
+err_hdl:
+	v4l2_device_unregister(&isa->v4l2_dev);
+err_dev_reg:
+	release_region(isa->io, drv->region_size);
+	kfree(isa);
+	return res;
+}
+EXPORT_SYMBOL_GPL(radio_isa_probe);
+
+int radio_isa_remove(struct device *pdev, unsigned int dev)
+{
+	struct radio_isa_card *isa = dev_get_drvdata(pdev);
+	const struct radio_isa_ops *ops = isa->drv->ops;
+
+	ops->s_mute_volume(isa, true, isa->volume ? isa->volume->cur.val : 0);
+	video_unregister_device(&isa->vdev);
+	v4l2_ctrl_handler_free(&isa->hdl);
+	v4l2_device_unregister(&isa->v4l2_dev);
+	release_region(isa->io, isa->drv->region_size);
+	v4l2_info(&isa->v4l2_dev, "Removed radio card %s\n", isa->drv->card);
+	kfree(isa);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(radio_isa_remove);
diff --git a/drivers/media/radio/radio-isa.h b/drivers/media/radio/radio-isa.h
new file mode 100644
index 0000000..8a0ea84
--- /dev/null
+++ b/drivers/media/radio/radio-isa.h
@@ -0,0 +1,105 @@
+/*
+ * Framework for ISA radio drivers.
+ * This takes care of all the V4L2 scaffolding, allowing the ISA drivers
+ * to concentrate on the actual hardware operation.
+ *
+ * Copyright (C) 2012 Hans Verkuil <hans.verkuil@cisco.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _RADIO_ISA_H_
+#define _RADIO_ISA_H_
+
+#include <linux/isa.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+
+struct radio_isa_driver;
+struct radio_isa_ops;
+
+/* Core structure for radio ISA cards */
+struct radio_isa_card {
+	const struct radio_isa_driver *drv;
+	struct v4l2_device v4l2_dev;
+	struct v4l2_ctrl_handler hdl;
+	struct video_device vdev;
+	struct mutex lock;
+	const struct radio_isa_ops *ops;
+	struct {	/* mute/volume cluster */
+		struct v4l2_ctrl *mute;
+		struct v4l2_ctrl *volume;
+	};
+	/* I/O port */
+	int io;
+
+	/* Card is in stereo audio mode */
+	bool stereo;
+	/* Current frequency */
+	u32 freq;
+};
+
+struct radio_isa_ops {
+	/* Allocate and initialize a radio_isa_card struct */
+	struct radio_isa_card *(*alloc)(void);
+	/* Probe whether a card is present at the given port */
+	bool (*probe)(struct radio_isa_card *isa, int io);
+	/* Special card initialization can be done here, this is called after
+	 * the standard controls are registered, but before they are setup,
+	 * thus allowing drivers to add their own controls here. */
+	int (*init)(struct radio_isa_card *isa);
+	/* Set mute and volume. */
+	int (*s_mute_volume)(struct radio_isa_card *isa, bool mute, int volume);
+	/* Set frequency */
+	int (*s_frequency)(struct radio_isa_card *isa, u32 freq);
+	/* Set stereo/mono audio mode */
+	int (*s_stereo)(struct radio_isa_card *isa, bool stereo);
+	/* Get rxsubchans value for VIDIOC_G_TUNER */
+	u32 (*g_rxsubchans)(struct radio_isa_card *isa);
+	/* Get the signal strength for VIDIOC_G_TUNER */
+	u32 (*g_signal)(struct radio_isa_card *isa);
+};
+
+/* Top level structure needed to instantiate the cards */
+struct radio_isa_driver {
+	struct isa_driver driver;
+	const struct radio_isa_ops *ops;
+	/* The module_param_array with the specified I/O ports */
+	int *io_params;
+	/* The module_param_array with the radio_nr values */
+	int *radio_nr_params;
+	/* Whether we should probe for possible cards */
+	bool probe;
+	/* The list of possible I/O ports */
+	const int *io_ports;
+	/* The size of that list */
+	int num_of_io_ports;
+	/* The region size to request */
+	unsigned region_size;
+	/* The name of the card */
+	const char *card;
+	/* Card can capture stereo audio */
+	bool has_stereo;
+	/* The maximum volume for the volume control. If 0, then there
+	   is no volume control possible. */
+	int max_volume;
+};
+
+int radio_isa_match(struct device *pdev, unsigned int dev);
+int radio_isa_probe(struct device *pdev, unsigned int dev);
+int radio_isa_remove(struct device *pdev, unsigned int dev);
+
+#endif
diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c
new file mode 100644
index 0000000..55bd1d2
--- /dev/null
+++ b/drivers/media/radio/radio-keene.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2012 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* kernel includes */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <linux/usb.h>
+#include <linux/version.h>
+#include <linux/mutex.h>
+
+/* driver and module definitions */
+MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
+MODULE_DESCRIPTION("Keene FM Transmitter driver");
+MODULE_LICENSE("GPL");
+
+/* Actually, it advertises itself as a Logitech */
+#define USB_KEENE_VENDOR 0x046d
+#define USB_KEENE_PRODUCT 0x0a0e
+
+/* Probably USB_TIMEOUT should be modified in module parameter */
+#define BUFFER_LENGTH 8
+#define USB_TIMEOUT 500
+
+/* Frequency limits in MHz */
+#define FREQ_MIN  76U
+#define FREQ_MAX 108U
+#define FREQ_MUL 16000U
+
+/* USB Device ID List */
+static struct usb_device_id usb_keene_device_table[] = {
+	{USB_DEVICE_AND_INTERFACE_INFO(USB_KEENE_VENDOR, USB_KEENE_PRODUCT,
+							USB_CLASS_HID, 0, 0) },
+	{ }						/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, usb_keene_device_table);
+
+struct keene_device {
+	struct usb_device *usbdev;
+	struct usb_interface *intf;
+	struct video_device vdev;
+	struct v4l2_device v4l2_dev;
+	struct v4l2_ctrl_handler hdl;
+	struct mutex lock;
+
+	u8 *buffer;
+	unsigned curfreq;
+	u8 tx;
+	u8 pa;
+	bool stereo;
+	bool muted;
+	bool preemph_75_us;
+};
+
+static inline struct keene_device *to_keene_dev(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct keene_device, v4l2_dev);
+}
+
+/* Set frequency (if non-0), PA, mute and turn on/off the FM transmitter. */
+static int keene_cmd_main(struct keene_device *radio, unsigned freq, bool play)
+{
+	unsigned short freq_send = freq ? (freq - 76 * 16000) / 800 : 0;
+	int ret;
+
+	radio->buffer[0] = 0x00;
+	radio->buffer[1] = 0x50;
+	radio->buffer[2] = (freq_send >> 8) & 0xff;
+	radio->buffer[3] = freq_send & 0xff;
+	radio->buffer[4] = radio->pa;
+	/* If bit 4 is set, then tune to the frequency.
+	   If bit 3 is set, then unmute; if bit 2 is set, then mute.
+	   If bit 1 is set, then enter idle mode; if bit 0 is set,
+	   then enter transit mode.
+	 */
+	radio->buffer[5] = (radio->muted ? 4 : 8) | (play ? 1 : 2) |
+							(freq ? 0x10 : 0);
+	radio->buffer[6] = 0x00;
+	radio->buffer[7] = 0x00;
+
+	ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
+		9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
+
+	if (ret < 0) {
+		dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret);
+		return ret;
+	}
+	if (freq)
+		radio->curfreq = freq;
+	return 0;
+}
+
+/* Set TX, stereo and preemphasis mode (50 us vs 75 us). */
+static int keene_cmd_set(struct keene_device *radio)
+{
+	int ret;
+
+	radio->buffer[0] = 0x00;
+	radio->buffer[1] = 0x51;
+	radio->buffer[2] = radio->tx;
+	/* If bit 0 is set, then transmit mono, otherwise stereo.
+	   If bit 2 is set, then enable 75 us preemphasis, otherwise
+	   it is 50 us. */
+	radio->buffer[3] = (!radio->stereo) | (radio->preemph_75_us ? 4 : 0);
+	radio->buffer[4] = 0x00;
+	radio->buffer[5] = 0x00;
+	radio->buffer[6] = 0x00;
+	radio->buffer[7] = 0x00;
+
+	ret = usb_control_msg(radio->usbdev, usb_sndctrlpipe(radio->usbdev, 0),
+		9, 0x21, 0x200, 2, radio->buffer, BUFFER_LENGTH, USB_TIMEOUT);
+
+	if (ret < 0) {
+		dev_warn(&radio->vdev.dev, "%s failed (%d)\n", __func__, ret);
+		return ret;
+	}
+	return 0;
+}
+
+/* Handle unplugging the device.
+ * We call video_unregister_device in any case.
+ * The last function called in this procedure is
+ * usb_keene_device_release.
+ */
+static void usb_keene_disconnect(struct usb_interface *intf)
+{
+	struct keene_device *radio = to_keene_dev(usb_get_intfdata(intf));
+
+	v4l2_device_get(&radio->v4l2_dev);
+	mutex_lock(&radio->lock);
+	usb_set_intfdata(intf, NULL);
+	video_unregister_device(&radio->vdev);
+	v4l2_device_disconnect(&radio->v4l2_dev);
+	mutex_unlock(&radio->lock);
+	v4l2_device_put(&radio->v4l2_dev);
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+					struct v4l2_capability *v)
+{
+	struct keene_device *radio = video_drvdata(file);
+
+	strlcpy(v->driver, "radio-keene", sizeof(v->driver));
+	strlcpy(v->card, "Keene FM Transmitter", sizeof(v->card));
+	usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
+	v->device_caps = V4L2_CAP_RADIO | V4L2_CAP_MODULATOR;
+	v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS;
+	return 0;
+}
+
+static int vidioc_g_modulator(struct file *file, void *priv,
+				struct v4l2_modulator *v)
+{
+	struct keene_device *radio = video_drvdata(file);
+
+	if (v->index > 0)
+		return -EINVAL;
+
+	strlcpy(v->name, "FM", sizeof(v->name));
+	v->rangelow = FREQ_MIN * FREQ_MUL;
+	v->rangehigh = FREQ_MAX * FREQ_MUL;
+	v->txsubchans = radio->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+	v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+	return 0;
+}
+
+static int vidioc_s_modulator(struct file *file, void *priv,
+				struct v4l2_modulator *v)
+{
+	struct keene_device *radio = video_drvdata(file);
+
+	if (v->index > 0)
+		return -EINVAL;
+
+	radio->stereo = (v->txsubchans == V4L2_TUNER_SUB_STEREO);
+	return keene_cmd_set(radio);
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *f)
+{
+	struct keene_device *radio = video_drvdata(file);
+
+	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+		return -EINVAL;
+	f->frequency = clamp(f->frequency,
+			FREQ_MIN * FREQ_MUL, FREQ_MAX * FREQ_MUL);
+	return keene_cmd_main(radio, f->frequency, true);
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+				struct v4l2_frequency *f)
+{
+	struct keene_device *radio = video_drvdata(file);
+
+	if (f->tuner != 0)
+		return -EINVAL;
+	f->type = V4L2_TUNER_RADIO;
+	f->frequency = radio->curfreq;
+	return 0;
+}
+
+static int keene_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	static const u8 db2tx[] = {
+	     /*	 -15,  -12,   -9,   -6,   -3,    0 dB */
+		0x03, 0x13, 0x02, 0x12, 0x22, 0x32,
+	     /*	   3,    6,    9,   12,   15,   18 dB */
+		0x21, 0x31, 0x20, 0x30, 0x40, 0x50
+	};
+	struct keene_device *radio =
+		container_of(ctrl->handler, struct keene_device, hdl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		radio->muted = ctrl->val;
+		return keene_cmd_main(radio, 0, true);
+
+	case V4L2_CID_TUNE_POWER_LEVEL:
+		/* To go from dBuV to the register value we apply the
+		   following formula: */
+		radio->pa = (ctrl->val - 71) * 100 / 62;
+		return keene_cmd_main(radio, 0, true);
+
+	case V4L2_CID_TUNE_PREEMPHASIS:
+		radio->preemph_75_us = ctrl->val == V4L2_PREEMPHASIS_75_uS;
+		return keene_cmd_set(radio);
+
+	case V4L2_CID_AUDIO_COMPRESSION_GAIN:
+		radio->tx = db2tx[(ctrl->val - ctrl->minimum) / ctrl->step];
+		return keene_cmd_set(radio);
+	}
+	return -EINVAL;
+}
+
+static int vidioc_subscribe_event(struct v4l2_fh *fh,
+				struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_CTRL:
+		return v4l2_event_subscribe(fh, sub, 0);
+	default:
+		return -EINVAL;
+	}
+}
+
+
+/* File system interface */
+static const struct v4l2_file_operations usb_keene_fops = {
+	.owner		= THIS_MODULE,
+	.open           = v4l2_fh_open,
+	.release        = v4l2_fh_release,
+	.poll		= v4l2_ctrl_poll,
+	.unlocked_ioctl	= video_ioctl2,
+};
+
+static const struct v4l2_ctrl_ops keene_ctrl_ops = {
+	.s_ctrl = keene_s_ctrl,
+};
+
+static const struct v4l2_ioctl_ops usb_keene_ioctl_ops = {
+	.vidioc_querycap    = vidioc_querycap,
+	.vidioc_g_modulator = vidioc_g_modulator,
+	.vidioc_s_modulator = vidioc_s_modulator,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+	.vidioc_log_status = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = vidioc_subscribe_event,
+	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+static void usb_keene_video_device_release(struct v4l2_device *v4l2_dev)
+{
+	struct keene_device *radio = to_keene_dev(v4l2_dev);
+
+	/* free rest memory */
+	v4l2_ctrl_handler_free(&radio->hdl);
+	kfree(radio->buffer);
+	kfree(radio);
+}
+
+/* check if the device is present and register with v4l and usb if it is */
+static int usb_keene_probe(struct usb_interface *intf,
+				const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct keene_device *radio;
+	struct v4l2_ctrl_handler *hdl;
+	int retval = 0;
+
+	/*
+	 * The Keene FM transmitter USB device has the same USB ID as
+	 * the Logitech AudioHub Speaker, but it should ignore the hid.
+	 * Check if the name is that of the Keene device.
+	 * If not, then someone connected the AudioHub and we shouldn't
+	 * attempt to handle this driver.
+	 * For reference: the product name of the AudioHub is
+	 * "AudioHub Speaker".
+	 */
+	if (dev->product && strcmp(dev->product, "B-LINK USB Audio  "))
+		return -ENODEV;
+
+	radio = kzalloc(sizeof(struct keene_device), GFP_KERNEL);
+	if (radio)
+		radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
+
+	if (!radio || !radio->buffer) {
+		dev_err(&intf->dev, "kmalloc for keene_device failed\n");
+		kfree(radio);
+		retval = -ENOMEM;
+		goto err;
+	}
+
+	hdl = &radio->hdl;
+	v4l2_ctrl_handler_init(hdl, 4);
+	v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_MUTE,
+			0, 1, 1, 0);
+	v4l2_ctrl_new_std_menu(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_PREEMPHASIS,
+			V4L2_PREEMPHASIS_75_uS, 1, V4L2_PREEMPHASIS_50_uS);
+	v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_TUNE_POWER_LEVEL,
+			84, 118, 1, 118);
+	v4l2_ctrl_new_std(hdl, &keene_ctrl_ops, V4L2_CID_AUDIO_COMPRESSION_GAIN,
+			-15, 18, 3, 0);
+	radio->pa = 118;
+	radio->tx = 0x32;
+	radio->stereo = true;
+	radio->curfreq = 95.16 * FREQ_MUL;
+	if (hdl->error) {
+		retval = hdl->error;
+
+		v4l2_ctrl_handler_free(hdl);
+		goto err_v4l2;
+	}
+	retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev);
+	if (retval < 0) {
+		dev_err(&intf->dev, "couldn't register v4l2_device\n");
+		goto err_v4l2;
+	}
+
+	mutex_init(&radio->lock);
+
+	radio->v4l2_dev.ctrl_handler = hdl;
+	radio->v4l2_dev.release = usb_keene_video_device_release;
+	strlcpy(radio->vdev.name, radio->v4l2_dev.name,
+		sizeof(radio->vdev.name));
+	radio->vdev.v4l2_dev = &radio->v4l2_dev;
+	radio->vdev.fops = &usb_keene_fops;
+	radio->vdev.ioctl_ops = &usb_keene_ioctl_ops;
+	radio->vdev.lock = &radio->lock;
+	radio->vdev.release = video_device_release_empty;
+
+	radio->usbdev = interface_to_usbdev(intf);
+	radio->intf = intf;
+	usb_set_intfdata(intf, &radio->v4l2_dev);
+
+	video_set_drvdata(&radio->vdev, radio);
+	set_bit(V4L2_FL_USE_FH_PRIO, &radio->vdev.flags);
+
+	retval = video_register_device(&radio->vdev, VFL_TYPE_RADIO, -1);
+	if (retval < 0) {
+		dev_err(&intf->dev, "could not register video device\n");
+		goto err_vdev;
+	}
+	v4l2_ctrl_handler_setup(hdl);
+	dev_info(&intf->dev, "V4L2 device registered as %s\n",
+			video_device_node_name(&radio->vdev));
+	return 0;
+
+err_vdev:
+	v4l2_device_unregister(&radio->v4l2_dev);
+err_v4l2:
+	kfree(radio->buffer);
+	kfree(radio);
+err:
+	return retval;
+}
+
+/* USB subsystem interface */
+static struct usb_driver usb_keene_driver = {
+	.name			= "radio-keene",
+	.probe			= usb_keene_probe,
+	.disconnect		= usb_keene_disconnect,
+	.id_table		= usb_keene_device_table,
+};
+
+static int __init keene_init(void)
+{
+	int retval = usb_register(&usb_keene_driver);
+
+	if (retval)
+		pr_err(KBUILD_MODNAME
+			": usb_register failed. Error number %d\n", retval);
+
+	return retval;
+}
+
+static void __exit keene_exit(void)
+{
+	usb_deregister(&usb_keene_driver);
+}
+
+module_init(keene_init);
+module_exit(keene_exit);
+
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 3628be6..b275c5d 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -1,11 +1,12 @@
-/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
+/*
+ * RadioTrack II driver
+ * Copyright 1998 Ben Pfaff
  *
  * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
  * Converted to new API by Alan Cox <alan@lxorguk.ukuu.org.uk>
  * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
- * TODO: Allow for more than one of these foolish entities :-)
- *
+ * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
  */
 
@@ -18,323 +19,120 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include "radio-isa.h"
 
 MODULE_AUTHOR("Ben Pfaff");
 MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
+MODULE_VERSION("0.1.99");
 
 #ifndef CONFIG_RADIO_RTRACK2_PORT
 #define CONFIG_RADIO_RTRACK2_PORT -1
 #endif
 
-static int io = CONFIG_RADIO_RTRACK2_PORT;
-static int radio_nr = -1;
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-struct rtrack2
-{
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int io;
-	unsigned long curfreq;
-	int muted;
-	struct mutex lock;
-};
+#define RTRACK2_MAX 2
 
-static struct rtrack2 rtrack2_card;
+static int io[RTRACK2_MAX] = { [0] = CONFIG_RADIO_RTRACK2_PORT,
+			      [1 ... (RTRACK2_MAX - 1)] = -1 };
+static int radio_nr[RTRACK2_MAX] = { [0 ... (RTRACK2_MAX - 1)] = -1 };
 
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "I/O addresses of the RadioTrack card (0x20f or 0x30f)");
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
 
-/* local things */
-
-static void rt_mute(struct rtrack2 *dev)
-{
-	if (dev->muted)
-		return;
-	mutex_lock(&dev->lock);
-	outb(1, dev->io);
-	mutex_unlock(&dev->lock);
-	dev->muted = 1;
-}
-
-static void rt_unmute(struct rtrack2 *dev)
+static struct radio_isa_card *rtrack2_alloc(void)
 {
-	if(dev->muted == 0)
-		return;
-	mutex_lock(&dev->lock);
-	outb(0, dev->io);
-	mutex_unlock(&dev->lock);
-	dev->muted = 0;
+	return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL);
 }
 
-static void zero(struct rtrack2 *dev)
+static void zero(struct radio_isa_card *isa)
 {
-	outb_p(1, dev->io);
-	outb_p(3, dev->io);
-	outb_p(1, dev->io);
+	outb_p(1, isa->io);
+	outb_p(3, isa->io);
+	outb_p(1, isa->io);
 }
 
-static void one(struct rtrack2 *dev)
+static void one(struct radio_isa_card *isa)
 {
-	outb_p(5, dev->io);
-	outb_p(7, dev->io);
-	outb_p(5, dev->io);
+	outb_p(5, isa->io);
+	outb_p(7, isa->io);
+	outb_p(5, isa->io);
 }
 
-static int rt_setfreq(struct rtrack2 *dev, unsigned long freq)
+static int rtrack2_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
 	int i;
 
-	mutex_lock(&dev->lock);
-	dev->curfreq = freq;
 	freq = freq / 200 + 856;
 
-	outb_p(0xc8, dev->io);
-	outb_p(0xc9, dev->io);
-	outb_p(0xc9, dev->io);
+	outb_p(0xc8, isa->io);
+	outb_p(0xc9, isa->io);
+	outb_p(0xc9, isa->io);
 
 	for (i = 0; i < 10; i++)
-		zero(dev);
+		zero(isa);
 
 	for (i = 14; i >= 0; i--)
 		if (freq & (1 << i))
-			one(dev);
+			one(isa);
 		else
-			zero(dev);
-
-	outb_p(0xc8, dev->io);
-	if (!dev->muted)
-		outb_p(0, dev->io);
-
-	mutex_unlock(&dev->lock);
-	return 0;
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
-				struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
-	strlcpy(v->card, "RadioTrack II", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
+			zero(isa);
 
-static int vidioc_s_tuner(struct file *file, void *priv,
-				struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int rt_getsigstr(struct rtrack2 *dev)
-{
-	int sig = 1;
-
-	mutex_lock(&dev->lock);
-	if (inb(dev->io) & 2)	/* bit set = no signal present	*/
-		sig = 0;
-	mutex_unlock(&dev->lock);
-	return sig;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-				struct v4l2_tuner *v)
-{
-	struct rtrack2 *rt = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = 88 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF * rt_getsigstr(rt);
+	outb_p(0xc8, isa->io);
+	if (!v4l2_ctrl_g_ctrl(isa->mute))
+		outb_p(0, isa->io);
 	return 0;
 }
 
-static int vidioc_s_frequency(struct file *file, void *priv,
-				struct v4l2_frequency *f)
+static u32 rtrack2_g_signal(struct radio_isa_card *isa)
 {
-	struct rtrack2 *rt = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	rt_setfreq(rt, f->frequency);
-	return 0;
+	/* bit set = no signal present	*/
+	return (inb(isa->io) & 2) ? 0 : 0xffff;
 }
 
-static int vidioc_g_frequency(struct file *file, void *priv,
-				struct v4l2_frequency *f)
+static int rtrack2_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
-	struct rtrack2 *rt = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = rt->curfreq;
+	outb(mute, isa->io);
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-				struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct rtrack2 *rt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = rt->muted;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (rt->muted)
-			ctrl->value = 0;
-		else
-			ctrl->value = 65535;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct rtrack2 *rt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			rt_mute(rt);
-		else
-			rt_unmute(rt);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		if (ctrl->value)
-			rt_unmute(rt);
-		else
-			rt_mute(rt);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
-static const struct v4l2_file_operations rtrack2_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops rtrack2_ops = {
+	.alloc = rtrack2_alloc,
+	.s_mute_volume = rtrack2_s_mute_volume,
+	.s_frequency = rtrack2_s_frequency,
+	.g_signal = rtrack2_g_signal,
 };
 
-static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
+static const int rtrack2_ioports[] = { 0x20f, 0x30f };
+
+static struct radio_isa_driver rtrack2_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-rtrack2",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = rtrack2_ioports,
+	.num_of_io_ports = ARRAY_SIZE(rtrack2_ioports),
+	.region_size = 4,
+	.card = "AIMSlab RadioTrack II",
+	.ops = &rtrack2_ops,
+	.has_stereo = true,
 };
 
 static int __init rtrack2_init(void)
 {
-	struct rtrack2 *dev = &rtrack2_card;
-	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name));
-	dev->io = io;
-	if (dev->io == -1) {
-		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n");
-		return -EINVAL;
-	}
-	if (!request_region(dev->io, 4, "rtrack2")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(dev->io, 4);
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		return res;
-	}
-
-	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
-	dev->vdev.v4l2_dev = v4l2_dev;
-	dev->vdev.fops = &rtrack2_fops;
-	dev->vdev.ioctl_ops = &rtrack2_ioctl_ops;
-	dev->vdev.release = video_device_release_empty;
-	video_set_drvdata(&dev->vdev, dev);
-
-	/* mute card - prevents noisy bootups */
-	outb(1, dev->io);
-	dev->muted = 1;
-
-	mutex_init(&dev->lock);
-	if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(v4l2_dev);
-		release_region(dev->io, 4);
-		return -EINVAL;
-	}
-
-	v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
-
-	return 0;
+	return isa_register_driver(&rtrack2_driver.driver, RTRACK2_MAX);
 }
 
 static void __exit rtrack2_exit(void)
 {
-	struct rtrack2 *dev = &rtrack2_card;
-
-	video_unregister_device(&dev->vdev);
-	v4l2_device_unregister(&dev->v4l2_dev);
-	release_region(dev->io, 4);
+	isa_unregister_driver(&rtrack2_driver.driver);
 }
 
 module_init(rtrack2_init);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 2dd4859..7ab9afa 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -172,7 +172,7 @@ static int fmr2_tea_ext_init(struct snd_tea575x *tea)
 		fmr2->volume = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 68, 2, 56);
 		fmr2->balance = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_BALANCE, -68, 68, 2, 0);
 		if (tea->ctrl_handler.error) {
-			printk(KERN_ERR "radio-sf16fmr2: can't initialize contrls\n");
+			printk(KERN_ERR "radio-sf16fmr2: can't initialize controls\n");
 			return tea->ctrl_handler.error;
 		}
 	}
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index f2ed9cc..2b82dd7 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -16,11 +16,7 @@
  *  Frequency control is done digitally -- ie out(port,encodefreq(95.8));
  *  Volume Control is done digitally
  *
- *  there is a I2C controlled RDS decoder (SAA6588)  onboard, which i would like to support someday
- *  (as soon i have understand how to get started :)
- *  If you can help me out with that, please contact me!!
- *
- *
+ * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
  */
 
@@ -32,41 +28,21 @@
 #include <linux/io.h>		/* outb, outb_p			*/
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include "radio-isa.h"
 
-MODULE_AUTHOR("R.OFFERMANNS & others");
+MODULE_AUTHOR("R. Offermans & others");
 MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
-
-#ifndef CONFIG_RADIO_TERRATEC_PORT
-#define CONFIG_RADIO_TERRATEC_PORT 0x590
-#endif
+MODULE_VERSION("0.1.99");
 
-static int io = CONFIG_RADIO_TERRATEC_PORT;
+/* Note: there seems to be only one possible port (0x590), but without
+   hardware this is hard to verify. For now, this is the only one we will
+   support. */
+static int io = 0x590;
 static int radio_nr = -1;
 
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
-module_param(radio_nr, int, 0);
-
-static struct v4l2_queryctrl radio_qctrl[] = {
-	{
-		.id            = V4L2_CID_AUDIO_MUTE,
-		.name          = "Mute",
-		.minimum       = 0,
-		.maximum       = 1,
-		.default_value = 1,
-		.type          = V4L2_CTRL_TYPE_BOOLEAN,
-	},{
-		.id            = V4L2_CID_AUDIO_VOLUME,
-		.name          = "Volume",
-		.minimum       = 0,
-		.maximum       = 0xff,
-		.step          = 1,
-		.default_value = 0xff,
-		.type          = V4L2_CTRL_TYPE_INTEGER,
-	}
-};
+module_param(radio_nr, int, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device number");
 
 #define WRT_DIS 	0x00
 #define CLK_OFF		0x00
@@ -76,63 +52,24 @@ static struct v4l2_queryctrl radio_qctrl[] = {
 #define CLK_ON 		0x08
 #define WRT_EN		0x10
 
-struct terratec
+static struct radio_isa_card *terratec_alloc(void)
 {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int io;
-	int curvol;
-	unsigned long curfreq;
-	int muted;
-	struct mutex lock;
-};
-
-static struct terratec terratec_card;
-
-/* local things */
+	return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL);
+}
 
-static void tt_write_vol(struct terratec *tt, int volume)
+static int terratec_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
 	int i;
 
-	volume = volume + (volume * 32); /* change both channels */
-	mutex_lock(&tt->lock);
+	if (mute)
+		vol = 0;
+	vol = vol + (vol * 32); /* change both channels */
 	for (i = 0; i < 8; i++) {
-		if (volume & (0x80 >> i))
-			outb(0x80, tt->io + 1);
+		if (vol & (0x80 >> i))
+			outb(0x80, isa->io + 1);
 		else
-			outb(0x00, tt->io + 1);
-	}
-	mutex_unlock(&tt->lock);
-}
-
-
-
-static void tt_mute(struct terratec *tt)
-{
-	tt->muted = 1;
-	tt_write_vol(tt, 0);
-}
-
-static int tt_setvol(struct terratec *tt, int vol)
-{
-	if (vol == tt->curvol) {	/* requested volume = current */
-		if (tt->muted) {	/* user is unmuting the card  */
-			tt->muted = 0;
-			tt_write_vol(tt, vol);	/* enable card */
-		}
-		return 0;
-	}
-
-	if (vol == 0) {			/* volume = 0 means mute the card */
-		tt_write_vol(tt, 0);	/* "turn off card" by setting vol to 0 */
-		tt->curvol = vol;	/* track the volume state!	*/
-		return 0;
+			outb(0x00, isa->io + 1);
 	}
-
-	tt->muted = 0;
-	tt_write_vol(tt, vol);
-	tt->curvol = vol;
 	return 0;
 }
 
@@ -140,20 +77,15 @@ static int tt_setvol(struct terratec *tt, int vol)
 /* this is the worst part in this driver */
 /* many more or less strange things are going on here, but hey, it works :) */
 
-static int tt_setfreq(struct terratec *tt, unsigned long freq1)
+static int terratec_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
-	int freq;
 	int i;
 	int p;
-	int  temp;
+	int temp;
 	long rest;
 	unsigned char buffer[25];		/* we have to bit shift 25 registers */
 
-	mutex_lock(&tt->lock);
-
-	tt->curfreq = freq1;
-
-	freq = freq1 / 160;			/* convert the freq. to a nice to handle value */
+	freq = freq / 160;			/* convert the freq. to a nice to handle value */
 	memset(buffer, 0, sizeof(buffer));
 
 	rest = freq * 10 + 10700;	/* I once had understood what is going on here */
@@ -175,239 +107,61 @@ static int tt_setfreq(struct terratec *tt, unsigned long freq1)
 
 	for (i = 24; i > -1; i--) {	/* bit shift the values to the radiocard */
 		if (buffer[i] == 1) {
-			outb(WRT_EN | DATA, tt->io);
-			outb(WRT_EN | DATA | CLK_ON, tt->io);
-			outb(WRT_EN | DATA, tt->io);
+			outb(WRT_EN | DATA, isa->io);
+			outb(WRT_EN | DATA | CLK_ON, isa->io);
+			outb(WRT_EN | DATA, isa->io);
 		} else {
-			outb(WRT_EN | 0x00, tt->io);
-			outb(WRT_EN | 0x00 | CLK_ON, tt->io);
-		}
-	}
-	outb(0x00, tt->io);
-
-	mutex_unlock(&tt->lock);
-
-	return 0;
-}
-
-static int tt_getsigstr(struct terratec *tt)
-{
-	if (inb(tt->io) & 2)	/* bit set = no signal present	*/
-		return 0;
-	return 1;		/* signal present		*/
-}
-
-static int vidioc_querycap(struct file *file, void *priv,
-					struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
-	strlcpy(v->card, "ActiveRadio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	struct terratec *tt = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = 87 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF * tt_getsigstr(tt);
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct terratec *tt = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	tt_setfreq(tt, f->frequency);
-	return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct terratec *tt = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = tt->curfreq;
-	return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
-		if (qc->id && qc->id == radio_qctrl[i].id) {
-			memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
-			return 0;
+			outb(WRT_EN | 0x00, isa->io);
+			outb(WRT_EN | 0x00 | CLK_ON, isa->io);
 		}
 	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct terratec *tt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (tt->muted)
-			ctrl->value = 1;
-		else
-			ctrl->value = 0;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = tt->curvol * 6554;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct terratec *tt = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			tt_mute(tt);
-		else
-			tt_setvol(tt,tt->curvol);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		tt_setvol(tt,ctrl->value);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
+	outb(0x00, isa->io);
 	return 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
+static u32 terratec_g_signal(struct radio_isa_card *isa)
 {
-	return a->index ? -EINVAL : 0;
+	/* bit set = no signal present	*/
+	return (inb(isa->io) & 2) ? 0 : 0xffff;
 }
 
-static const struct v4l2_file_operations terratec_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops terratec_ops = {
+	.alloc = terratec_alloc,
+	.s_mute_volume = terratec_s_mute_volume,
+	.s_frequency = terratec_s_frequency,
+	.g_signal = terratec_g_signal,
 };
 
-static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
+static const int terratec_ioports[] = { 0x590 };
+
+static struct radio_isa_driver terratec_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-terratec",
+		},
+	},
+	.io_params = &io,
+	.radio_nr_params = &radio_nr,
+	.io_ports = terratec_ioports,
+	.num_of_io_ports = ARRAY_SIZE(terratec_ioports),
+	.region_size = 2,
+	.card = "TerraTec ActiveRadio",
+	.ops = &terratec_ops,
+	.has_stereo = true,
+	.max_volume = 10,
 };
 
 static int __init terratec_init(void)
 {
-	struct terratec *tt = &terratec_card;
-	struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name));
-	tt->io = io;
-	if (tt->io == -1) {
-		v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n");
-		return -EINVAL;
-	}
-	if (!request_region(tt->io, 2, "terratec")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(tt->io, 2);
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		return res;
-	}
-
-	strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name));
-	tt->vdev.v4l2_dev = v4l2_dev;
-	tt->vdev.fops = &terratec_fops;
-	tt->vdev.ioctl_ops = &terratec_ioctl_ops;
-	tt->vdev.release = video_device_release_empty;
-	video_set_drvdata(&tt->vdev, tt);
-
-	mutex_init(&tt->lock);
-
-	/* mute card - prevents noisy bootups */
-	tt_write_vol(tt, 0);
-
-	if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(&tt->v4l2_dev);
-		release_region(tt->io, 2);
-		return -EINVAL;
-	}
-
-	v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
-	return 0;
+	return isa_register_driver(&terratec_driver.driver, 1);
 }
 
 static void __exit terratec_exit(void)
 {
-	struct terratec *tt = &terratec_card;
-	struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
-
-	video_unregister_device(&tt->vdev);
-	v4l2_device_unregister(&tt->v4l2_dev);
-	release_region(tt->io, 2);
-	v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n");
+	isa_unregister_driver(&terratec_driver.driver);
 }
 
 module_init(terratec_init);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index b3f45a0..0703a80 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -23,11 +23,12 @@
 #include <linux/io.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include "radio-isa.h"
 
 MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
+MODULE_VERSION("0.1.99");
 
 /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
 
@@ -35,39 +36,38 @@ MODULE_VERSION("0.0.3");
 #define CONFIG_RADIO_TRUST_PORT -1
 #endif
 
-static int io = CONFIG_RADIO_TRUST_PORT;
-static int radio_nr = -1;
+#define TRUST_MAX 2
 
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
-module_param(radio_nr, int, 0);
+static int io[TRUST_MAX] = { [0] = CONFIG_RADIO_TRUST_PORT,
+			      [1 ... (TRUST_MAX - 1)] = -1 };
+static int radio_nr[TRUST_MAX] = { [0 ... (TRUST_MAX - 1)] = -1 };
+
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "I/O addresses of the Trust FM Radio card (0x350 or 0x358)");
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
 
 struct trust {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int io;
+	struct radio_isa_card isa;
 	int ioval;
-	__u16 curvol;
-	__u16 curbass;
-	__u16 curtreble;
-	int muted;
-	unsigned long curfreq;
-	int curstereo;
-	int curmute;
-	struct mutex lock;
 };
 
-static struct trust trust_card;
+static struct radio_isa_card *trust_alloc(void)
+{
+	struct trust *tr = kzalloc(sizeof(*tr), GFP_KERNEL);
+
+	return tr ? &tr->isa : NULL;
+}
 
 /* i2c addresses */
 #define TDA7318_ADDR 0x88
 #define TSA6060T_ADDR 0xc4
 
-#define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0)
-#define TR_SET_SCL outb(tr->ioval |= 2, tr->io)
-#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io)
-#define TR_SET_SDA outb(tr->ioval |= 1, tr->io)
-#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io)
+#define TR_DELAY do { inb(tr->isa.io); inb(tr->isa.io); inb(tr->isa.io); } while (0)
+#define TR_SET_SCL outb(tr->ioval |= 2, tr->isa.io)
+#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->isa.io)
+#define TR_SET_SDA outb(tr->ioval |= 1, tr->isa.io)
+#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->isa.io)
 
 static void write_i2c(struct trust *tr, int n, ...)
 {
@@ -84,10 +84,10 @@ static void write_i2c(struct trust *tr, int n, ...)
 	TR_CLR_SCL;
 	TR_DELAY;
 
-	for(; n; n--) {
+	for (; n; n--) {
 		val = va_arg(args, unsigned);
-		for(mask = 0x80; mask; mask >>= 1) {
-			if(val & mask)
+		for (mask = 0x80; mask; mask >>= 1) {
+			if (val & mask)
 				TR_SET_SDA;
 			else
 				TR_CLR_SDA;
@@ -115,317 +115,128 @@ static void write_i2c(struct trust *tr, int n, ...)
 	va_end(args);
 }
 
-static void tr_setvol(struct trust *tr, __u16 vol)
+static int trust_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
-	mutex_lock(&tr->lock);
-	tr->curvol = vol / 2048;
-	write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f);
-	mutex_unlock(&tr->lock);
-}
+	struct trust *tr = container_of(isa, struct trust, isa);
 
-static int basstreble2chip[15] = {
-	0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
-};
-
-static void tr_setbass(struct trust *tr, __u16 bass)
-{
-	mutex_lock(&tr->lock);
-	tr->curbass = bass / 4370;
-	write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]);
-	mutex_unlock(&tr->lock);
-}
-
-static void tr_settreble(struct trust *tr, __u16 treble)
-{
-	mutex_lock(&tr->lock);
-	tr->curtreble = treble / 4370;
-	write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]);
-	mutex_unlock(&tr->lock);
+	tr->ioval = (tr->ioval & 0xf7) | (mute << 3);
+	outb(tr->ioval, isa->io);
+	write_i2c(tr, 2, TDA7318_ADDR, vol ^ 0x1f);
+	return 0;
 }
 
-static void tr_setstereo(struct trust *tr, int stereo)
+static int trust_s_stereo(struct radio_isa_card *isa, bool stereo)
 {
-	mutex_lock(&tr->lock);
-	tr->curstereo = !!stereo;
-	tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2);
-	outb(tr->ioval, tr->io);
-	mutex_unlock(&tr->lock);
-}
+	struct trust *tr = container_of(isa, struct trust, isa);
 
-static void tr_setmute(struct trust *tr, int mute)
-{
-	mutex_lock(&tr->lock);
-	tr->curmute = !!mute;
-	tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3);
-	outb(tr->ioval, tr->io);
-	mutex_unlock(&tr->lock);
+	tr->ioval = (tr->ioval & 0xfb) | (!stereo << 2);
+	outb(tr->ioval, isa->io);
+	return 0;
 }
 
-static int tr_getsigstr(struct trust *tr)
+static u32 trust_g_signal(struct radio_isa_card *isa)
 {
 	int i, v;
 
-	mutex_lock(&tr->lock);
 	for (i = 0, v = 0; i < 100; i++)
-		v |= inb(tr->io);
-	mutex_unlock(&tr->lock);
+		v |= inb(isa->io);
 	return (v & 1) ? 0 : 0xffff;
 }
 
-static int tr_getstereo(struct trust *tr)
-{
-	/* don't know how to determine it, just return the setting */
-	return tr->curstereo;
-}
-
-static void tr_setfreq(struct trust *tr, unsigned long f)
+static int trust_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
-	mutex_lock(&tr->lock);
-	tr->curfreq = f;
-	f /= 160;	/* Convert to 10 kHz units	*/
-	f += 1070;	/* Add 10.7 MHz IF		*/
-	write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
-	mutex_unlock(&tr->lock);
-}
+	struct trust *tr = container_of(isa, struct trust, isa);
 
-static int vidioc_querycap(struct file *file, void *priv,
-				struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-trust", sizeof(v->driver));
-	strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+	freq /= 160;	/* Convert to 10 kHz units	*/
+	freq += 1070;	/* Add 10.7 MHz IF		*/
+	write_i2c(tr, 5, TSA6060T_ADDR, (freq << 1) | 1,
+			freq >> 7, 0x60 | ((freq >> 15) & 1), 0);
 	return 0;
 }
 
-static int vidioc_g_tuner(struct file *file, void *priv,
-				struct v4l2_tuner *v)
-{
-	struct trust *tr = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = 87.5 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	if (tr_getstereo(tr))
-		v->audmode = V4L2_TUNER_MODE_STEREO;
-	else
-		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = tr_getsigstr(tr);
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-				struct v4l2_tuner *v)
-{
-	struct trust *tr = video_drvdata(file);
-
-	if (v->index)
-		return -EINVAL;
-	tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO);
-	return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-				struct v4l2_frequency *f)
-{
-	struct trust *tr = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	tr_setfreq(tr, f->frequency);
-	return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-				struct v4l2_frequency *f)
-{
-	struct trust *tr = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = tr->curfreq;
-	return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-				struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535);
-	case V4L2_CID_AUDIO_BASS:
-	case V4L2_CID_AUDIO_TREBLE:
-		return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct trust *tr = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = tr->curmute;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = tr->curvol * 2048;
-		return 0;
-	case V4L2_CID_AUDIO_BASS:
-		ctrl->value = tr->curbass * 4370;
-		return 0;
-	case V4L2_CID_AUDIO_TREBLE:
-		ctrl->value = tr->curtreble * 4370;
-		return 0;
-	}
-	return -EINVAL;
-}
+static int basstreble2chip[15] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
+};
 
-static int vidioc_s_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
+static int trust_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct trust *tr = video_drvdata(file);
+	struct radio_isa_card *isa =
+		container_of(ctrl->handler, struct radio_isa_card, hdl);
+	struct trust *tr = container_of(isa, struct trust, isa);
 
 	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		tr_setmute(tr, ctrl->value);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		tr_setvol(tr, ctrl->value);
-		return 0;
 	case V4L2_CID_AUDIO_BASS:
-		tr_setbass(tr, ctrl->value);
+		write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[ctrl->val]);
 		return 0;
 	case V4L2_CID_AUDIO_TREBLE:
-		tr_settreble(tr, ctrl->value);
+		write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[ctrl->val]);
 		return 0;
 	}
 	return -EINVAL;
 }
 
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-				struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
-static const struct v4l2_file_operations trust_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops trust_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
+static const struct v4l2_ctrl_ops trust_ctrl_ops = {
+	.s_ctrl = trust_s_ctrl,
 };
 
-static int __init trust_init(void)
+static int trust_initialize(struct radio_isa_card *isa)
 {
-	struct trust *tr = &trust_card;
-	struct v4l2_device *v4l2_dev = &tr->v4l2_dev;
-	int res;
+	struct trust *tr = container_of(isa, struct trust, isa);
 
-	strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name));
-	tr->io = io;
 	tr->ioval = 0xf;
-	mutex_init(&tr->lock);
-
-	if (tr->io == -1) {
-		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n");
-		return -EINVAL;
-	}
-	if (!request_region(tr->io, 2, "Trust FM Radio")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(tr->io, 2);
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		return res;
-	}
-
-	strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name));
-	tr->vdev.v4l2_dev = v4l2_dev;
-	tr->vdev.fops = &trust_fops;
-	tr->vdev.ioctl_ops = &trust_ioctl_ops;
-	tr->vdev.release = video_device_release_empty;
-	video_set_drvdata(&tr->vdev, tr);
-
 	write_i2c(tr, 2, TDA7318_ADDR, 0x80);	/* speaker att. LF = 0 dB */
 	write_i2c(tr, 2, TDA7318_ADDR, 0xa0);	/* speaker att. RF = 0 dB */
 	write_i2c(tr, 2, TDA7318_ADDR, 0xc0);	/* speaker att. LR = 0 dB */
 	write_i2c(tr, 2, TDA7318_ADDR, 0xe0);	/* speaker att. RR = 0 dB */
 	write_i2c(tr, 2, TDA7318_ADDR, 0x40);	/* stereo 1 input, gain = 18.75 dB */
 
-	tr_setvol(tr, 0xffff);
-	tr_setbass(tr, 0x8000);
-	tr_settreble(tr, 0x8000);
-	tr_setstereo(tr, 1);
-
-	/* mute card - prevents noisy bootups */
-	tr_setmute(tr, 1);
+	v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
+				V4L2_CID_AUDIO_BASS, 0, 15, 1, 8);
+	v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
+				V4L2_CID_AUDIO_TREBLE, 0, 15, 1, 8);
+	return isa->hdl.error;
+}
 
-	if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(v4l2_dev);
-		release_region(tr->io, 2);
-		return -EINVAL;
-	}
+static const struct radio_isa_ops trust_ops = {
+	.init = trust_initialize,
+	.alloc = trust_alloc,
+	.s_mute_volume = trust_s_mute_volume,
+	.s_frequency = trust_s_frequency,
+	.s_stereo = trust_s_stereo,
+	.g_signal = trust_g_signal,
+};
 
-	v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
+static const int trust_ioports[] = { 0x350, 0x358 };
+
+static struct radio_isa_driver trust_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-trust",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = trust_ioports,
+	.num_of_io_ports = ARRAY_SIZE(trust_ioports),
+	.region_size = 2,
+	.card = "Trust FM Radio",
+	.ops = &trust_ops,
+	.has_stereo = true,
+	.max_volume = 31,
+};
 
-	return 0;
+static int __init trust_init(void)
+{
+	return isa_register_driver(&trust_driver.driver, TRUST_MAX);
 }
 
-static void __exit cleanup_trust_module(void)
+static void __exit trust_exit(void)
 {
-	struct trust *tr = &trust_card;
-
-	video_unregister_device(&tr->vdev);
-	v4l2_device_unregister(&tr->v4l2_dev);
-	release_region(tr->io, 2);
+	isa_unregister_driver(&trust_driver.driver);
 }
 
 module_init(trust_init);
-module_exit(cleanup_trust_module);
+module_exit(trust_exit);
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 398726a..145d10c 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -35,61 +35,50 @@
 #include <linux/io.h>		/* outb, outb_p                   */
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include "radio-isa.h"
 
 #define DRIVER_VERSION "0.1.2"
 
 MODULE_AUTHOR("Dr. Henrik Seidel");
 MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
+MODULE_VERSION("0.1.99");
 
 #ifndef CONFIG_RADIO_TYPHOON_PORT
 #define CONFIG_RADIO_TYPHOON_PORT -1
 #endif
 
 #ifndef CONFIG_RADIO_TYPHOON_MUTEFREQ
-#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
+#define CONFIG_RADIO_TYPHOON_MUTEFREQ 87000
 #endif
 
-static int io = CONFIG_RADIO_TYPHOON_PORT;
-static int radio_nr = -1;
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
-
-module_param(radio_nr, int, 0);
+#define TYPHOON_MAX 2
 
+static int io[TYPHOON_MAX] = { [0] = CONFIG_RADIO_TYPHOON_PORT,
+			      [1 ... (TYPHOON_MAX - 1)] = -1 };
+static int radio_nr[TYPHOON_MAX]	= { [0 ... (TYPHOON_MAX - 1)] = -1 };
 static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ;
+
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "I/O addresses of the Typhoon card (0x316 or 0x336)");
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
 module_param(mutefreq, ulong, 0);
 MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
 
-#define BANNER "Typhoon Radio Card driver v" DRIVER_VERSION "\n"
-
 struct typhoon {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int io;
-	int curvol;
+	struct radio_isa_card isa;
 	int muted;
-	unsigned long curfreq;
-	unsigned long mutefreq;
-	struct mutex lock;
 };
 
-static struct typhoon typhoon_card;
-
-static void typhoon_setvol_generic(struct typhoon *dev, int vol)
+static struct radio_isa_card *typhoon_alloc(void)
 {
-	mutex_lock(&dev->lock);
-	vol >>= 14;				/* Map 16 bit to 2 bit */
-	vol &= 3;
-	outb_p(vol / 2, dev->io);		/* Set the volume, high bit. */
-	outb_p(vol % 2, dev->io + 2);	/* Set the volume, low bit. */
-	mutex_unlock(&dev->lock);
+	struct typhoon *ty = kzalloc(sizeof(*ty), GFP_KERNEL);
+
+	return ty ? &ty->isa : NULL;
 }
 
-static int typhoon_setfreq_generic(struct typhoon *dev,
-				   unsigned long frequency)
+static int typhoon_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
 	unsigned long outval;
 	unsigned long x;
@@ -105,302 +94,86 @@ static int typhoon_setfreq_generic(struct typhoon *dev,
 	 *
 	 */
 
-	mutex_lock(&dev->lock);
-	x = frequency / 160;
+	x = freq / 160;
 	outval = (x * x + 2500) / 5000;
 	outval = (outval * x + 5000) / 10000;
 	outval -= (10 * x * x + 10433) / 20866;
 	outval += 4 * x - 11505;
 
-	outb_p((outval >> 8) & 0x01, dev->io + 4);
-	outb_p(outval >> 9, dev->io + 6);
-	outb_p(outval & 0xff, dev->io + 8);
-	mutex_unlock(&dev->lock);
-
-	return 0;
-}
-
-static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency)
-{
-	typhoon_setfreq_generic(dev, frequency);
-	dev->curfreq = frequency;
-	return 0;
-}
-
-static void typhoon_mute(struct typhoon *dev)
-{
-	if (dev->muted == 1)
-		return;
-	typhoon_setvol_generic(dev, 0);
-	typhoon_setfreq_generic(dev, dev->mutefreq);
-	dev->muted = 1;
-}
-
-static void typhoon_unmute(struct typhoon *dev)
-{
-	if (dev->muted == 0)
-		return;
-	typhoon_setfreq_generic(dev, dev->curfreq);
-	typhoon_setvol_generic(dev, dev->curvol);
-	dev->muted = 0;
-}
-
-static int typhoon_setvol(struct typhoon *dev, int vol)
-{
-	if (dev->muted && vol != 0) {	/* user is unmuting the card */
-		dev->curvol = vol;
-		typhoon_unmute(dev);
-		return 0;
-	}
-	if (vol == dev->curvol)		/* requested volume == current */
-		return 0;
-
-	if (vol == 0) {			/* volume == 0 means mute the card */
-		typhoon_mute(dev);
-		dev->curvol = vol;
-		return 0;
-	}
-	typhoon_setvol_generic(dev, vol);
-	dev->curvol = vol;
-	return 0;
-}
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
-	strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = 87.5 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF;     /* We can't get the signal strength */
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct typhoon *dev = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = dev->curfreq;
-	return 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct typhoon *dev = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	dev->curfreq = f->frequency;
-	typhoon_setfreq(dev, dev->curfreq);
+	outb_p((outval >> 8) & 0x01, isa->io + 4);
+	outb_p(outval >> 9, isa->io + 6);
+	outb_p(outval & 0xff, isa->io + 8);
 	return 0;
 }
 
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
+static int typhoon_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535);
-	}
-	return -EINVAL;
-}
+	struct typhoon *ty = container_of(isa, struct typhoon, isa);
 
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct typhoon *dev = video_drvdata(file);
+	if (mute)
+		vol = 0;
+	vol >>= 14;			/* Map 16 bit to 2 bit */
+	vol &= 3;
+	outb_p(vol / 2, isa->io);	/* Set the volume, high bit. */
+	outb_p(vol % 2, isa->io + 2);	/* Set the volume, low bit. */
 
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = dev->muted;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = dev->curvol;
-		return 0;
+	if (vol == 0 && !ty->muted) {
+		ty->muted = true;
+		return typhoon_s_frequency(isa, mutefreq << 4);
 	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl (struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct typhoon *dev = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			typhoon_mute(dev);
-		else
-			typhoon_unmute(dev);
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		typhoon_setvol(dev, ctrl->value);
-		return 0;
+	if (vol && ty->muted) {
+		ty->muted = false;
+		return typhoon_s_frequency(isa, isa->freq);
 	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
 	return 0;
 }
 
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
-	struct typhoon *dev = video_drvdata(file);
-	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
-
-	v4l2_info(v4l2_dev, BANNER);
-#ifdef MODULE
-	v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n");
-#else
-	v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n");
-#endif
-	v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4);
-	v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol);
-	v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ?  "on" : "off");
-	v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io);
-	v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4);
-	return 0;
-}
-
-static const struct v4l2_file_operations typhoon_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops typhoon_ops = {
+	.alloc = typhoon_alloc,
+	.s_mute_volume = typhoon_s_mute_volume,
+	.s_frequency = typhoon_s_frequency,
 };
 
-static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
-	.vidioc_log_status  = vidioc_log_status,
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+static const int typhoon_ioports[] = { 0x316, 0x336 };
+
+static struct radio_isa_driver typhoon_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-typhoon",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = typhoon_ioports,
+	.num_of_io_ports = ARRAY_SIZE(typhoon_ioports),
+	.region_size = 8,
+	.card = "Typhoon Radio",
+	.ops = &typhoon_ops,
+	.has_stereo = true,
+	.max_volume = 3,
 };
 
 static int __init typhoon_init(void)
 {
-	struct typhoon *dev = &typhoon_card;
-	struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
-	dev->io = io;
-
-	if (dev->io == -1) {
-		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
-		return -EINVAL;
-	}
-
-	if (mutefreq < 87000 || mutefreq > 108500) {
-		v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
-		v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
-		return -EINVAL;
-	}
-	dev->curfreq = dev->mutefreq = mutefreq << 4;
-
-	mutex_init(&dev->lock);
-	if (!request_region(dev->io, 8, "typhoon")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n",
-		       dev->io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(dev->io, 8);
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		return res;
+	if (mutefreq < 87000 || mutefreq > 108000) {
+		printk(KERN_ERR "%s: You must set a frequency (in kHz) used when muting the card,\n",
+				typhoon_driver.driver.driver.name);
+		printk(KERN_ERR "%s: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108000)\n",
+				typhoon_driver.driver.driver.name);
+		return -ENODEV;
 	}
-	v4l2_info(v4l2_dev, BANNER);
-
-	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
-	dev->vdev.v4l2_dev = v4l2_dev;
-	dev->vdev.fops = &typhoon_fops;
-	dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
-	dev->vdev.release = video_device_release_empty;
-	video_set_drvdata(&dev->vdev, dev);
-
-	/* mute card - prevents noisy bootups */
-	typhoon_mute(dev);
-
-	if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(&dev->v4l2_dev);
-		release_region(dev->io, 8);
-		return -EINVAL;
-	}
-	v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
-	v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq);
-
-	return 0;
+	return isa_register_driver(&typhoon_driver.driver, TYPHOON_MAX);
 }
 
 static void __exit typhoon_exit(void)
 {
-	struct typhoon *dev = &typhoon_card;
-
-	video_unregister_device(&dev->vdev);
-	v4l2_device_unregister(&dev->v4l2_dev);
-	release_region(dev->io, 8);
+	isa_unregister_driver(&typhoon_driver.driver);
 }
 
+
 module_init(typhoon_init);
 module_exit(typhoon_exit);
 
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index f5613b9..33dc089 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -1,5 +1,6 @@
-/* zoltrix radio plus driver for Linux radio support
- * (c) 1998 C. van Schaik <carl@leg.uct.ac.za>
+/*
+ * Zoltrix Radio Plus driver
+ * Copyright 1998 C. van Schaik <carl@leg.uct.ac.za>
  *
  * BUGS
  *  Due to the inconsistency in reading from the signal flags
@@ -27,6 +28,14 @@
  *
  * 2006-07-24 - Converted to V4L2 API
  *		by Mauro Carvalho Chehab <mchehab@infradead.org>
+ *
+ * Converted to the radio-isa framework by Hans Verkuil <hans.verkuil@cisco.com>
+ *
+ * Note that this is the driver for the Zoltrix Radio Plus.
+ * This driver does not work for the Zoltrix Radio Plus 108 or the
+ * Zoltrix Radio Plus for Windows.
+ *
+ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
  */
 
 #include <linux/module.h>	/* Modules                        */
@@ -38,80 +47,67 @@
 #include <linux/io.h>		/* outb, outb_p                   */
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
+#include "radio-isa.h"
 
-MODULE_AUTHOR("C.van Schaik");
+MODULE_AUTHOR("C. van Schaik");
 MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0.0.3");
+MODULE_VERSION("0.1.99");
 
 #ifndef CONFIG_RADIO_ZOLTRIX_PORT
 #define CONFIG_RADIO_ZOLTRIX_PORT -1
 #endif
 
-static int io = CONFIG_RADIO_ZOLTRIX_PORT;
-static int radio_nr = -1;
+#define ZOLTRIX_MAX 2
+
+static int io[ZOLTRIX_MAX] = { [0] = CONFIG_RADIO_ZOLTRIX_PORT,
+			       [1 ... (ZOLTRIX_MAX - 1)] = -1 };
+static int radio_nr[ZOLTRIX_MAX] = { [0 ... (ZOLTRIX_MAX - 1)] = -1 };
 
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
+module_param_array(io, int, NULL, 0444);
+MODULE_PARM_DESC(io, "I/O addresses of the Zoltrix Radio Plus card (0x20c or 0x30c)");
+module_param_array(radio_nr, int, NULL, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio device numbers");
 
 struct zoltrix {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	int io;
+	struct radio_isa_card isa;
 	int curvol;
-	unsigned long curfreq;
-	int muted;
-	unsigned int stereo;
-	struct mutex lock;
+	bool muted;
 };
 
-static struct zoltrix zoltrix_card;
+static struct radio_isa_card *zoltrix_alloc(void)
+{
+	struct zoltrix *zol = kzalloc(sizeof(*zol), GFP_KERNEL);
+
+	return zol ? &zol->isa : NULL;
+}
 
-static int zol_setvol(struct zoltrix *zol, int vol)
+static int zoltrix_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
 {
-	zol->curvol = vol;
-	if (zol->muted)
-		return 0;
+	struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
 
-	mutex_lock(&zol->lock);
-	if (vol == 0) {
-		outb(0, zol->io);
-		outb(0, zol->io);
-		inb(zol->io + 3);    /* Zoltrix needs to be read to confirm */
-		mutex_unlock(&zol->lock);
+	zol->curvol = vol;
+	zol->muted = mute;
+	if (mute || vol == 0) {
+		outb(0, isa->io);
+		outb(0, isa->io);
+		inb(isa->io + 3);            /* Zoltrix needs to be read to confirm */
 		return 0;
 	}
 
-	outb(zol->curvol-1, zol->io);
+	outb(vol - 1, isa->io);
 	msleep(10);
-	inb(zol->io + 2);
-	mutex_unlock(&zol->lock);
+	inb(isa->io + 2);
 	return 0;
 }
 
-static void zol_mute(struct zoltrix *zol)
-{
-	zol->muted = 1;
-	mutex_lock(&zol->lock);
-	outb(0, zol->io);
-	outb(0, zol->io);
-	inb(zol->io + 3);            /* Zoltrix needs to be read to confirm */
-	mutex_unlock(&zol->lock);
-}
-
-static void zol_unmute(struct zoltrix *zol)
-{
-	zol->muted = 0;
-	zol_setvol(zol, zol->curvol);
-}
-
-static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
+/* tunes the radio to the desired frequency */
+static int zoltrix_s_frequency(struct radio_isa_card *isa, u32 freq)
 {
-	/* tunes the radio to the desired frequency */
-	struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
+	struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
+	struct v4l2_device *v4l2_dev = &isa->v4l2_dev;
 	unsigned long long bitmask, f, m;
-	unsigned int stereo = zol->stereo;
+	bool stereo = isa->stereo;
 	int i;
 
 	if (freq == 0) {
@@ -125,340 +121,125 @@ static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
 	bitmask = 0xc480402c10080000ull;
 	i = 45;
 
-	mutex_lock(&zol->lock);
-
-	zol->curfreq = freq;
-
-	outb(0, zol->io);
-	outb(0, zol->io);
-	inb(zol->io + 3);            /* Zoltrix needs to be read to confirm */
+	outb(0, isa->io);
+	outb(0, isa->io);
+	inb(isa->io + 3);            /* Zoltrix needs to be read to confirm */
 
-	outb(0x40, zol->io);
-	outb(0xc0, zol->io);
+	outb(0x40, isa->io);
+	outb(0xc0, isa->io);
 
 	bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31));
 	while (i--) {
 		if ((bitmask & 0x8000000000000000ull) != 0) {
-			outb(0x80, zol->io);
+			outb(0x80, isa->io);
 			udelay(50);
-			outb(0x00, zol->io);
+			outb(0x00, isa->io);
 			udelay(50);
-			outb(0x80, zol->io);
+			outb(0x80, isa->io);
 			udelay(50);
 		} else {
-			outb(0xc0, zol->io);
+			outb(0xc0, isa->io);
 			udelay(50);
-			outb(0x40, zol->io);
+			outb(0x40, isa->io);
 			udelay(50);
-			outb(0xc0, zol->io);
+			outb(0xc0, isa->io);
 			udelay(50);
 		}
 		bitmask *= 2;
 	}
 	/* termination sequence */
-	outb(0x80, zol->io);
-	outb(0xc0, zol->io);
-	outb(0x40, zol->io);
+	outb(0x80, isa->io);
+	outb(0xc0, isa->io);
+	outb(0x40, isa->io);
 	udelay(1000);
-	inb(zol->io + 2);
-
+	inb(isa->io + 2);
 	udelay(1000);
 
-	if (zol->muted) {
-		outb(0, zol->io);
-		outb(0, zol->io);
-		inb(zol->io + 3);
-		udelay(1000);
-	}
-
-	mutex_unlock(&zol->lock);
-
-	if (!zol->muted)
-		zol_setvol(zol, zol->curvol);
-	return 0;
+	return zoltrix_s_mute_volume(isa, zol->muted, zol->curvol);
 }
 
 /* Get signal strength */
-static int zol_getsigstr(struct zoltrix *zol)
+static u32 zoltrix_g_rxsubchans(struct radio_isa_card *isa)
 {
+	struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
 	int a, b;
 
-	mutex_lock(&zol->lock);
-	outb(0x00, zol->io);         /* This stuff I found to do nothing */
-	outb(zol->curvol, zol->io);
+	outb(0x00, isa->io);         /* This stuff I found to do nothing */
+	outb(zol->curvol, isa->io);
 	msleep(20);
 
-	a = inb(zol->io);
+	a = inb(isa->io);
 	msleep(10);
-	b = inb(zol->io);
+	b = inb(isa->io);
 
-	mutex_unlock(&zol->lock);
-
-	if (a != b)
-		return 0;
-
-	/* I found this out by playing with a binary scanner on the card io */
-	return a == 0xcf || a == 0xdf || a == 0xef;
+	return (a == b && a == 0xcf) ?
+		V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
 }
 
-static int zol_is_stereo(struct zoltrix *zol)
+static u32 zoltrix_g_signal(struct radio_isa_card *isa)
 {
-	int x1, x2;
-
-	mutex_lock(&zol->lock);
+	struct zoltrix *zol = container_of(isa, struct zoltrix, isa);
+	int a, b;
 
-	outb(0x00, zol->io);
-	outb(zol->curvol, zol->io);
+	outb(0x00, isa->io);         /* This stuff I found to do nothing */
+	outb(zol->curvol, isa->io);
 	msleep(20);
 
-	x1 = inb(zol->io);
+	a = inb(isa->io);
 	msleep(10);
-	x2 = inb(zol->io);
-
-	mutex_unlock(&zol->lock);
-
-	return x1 == x2 && x1 == 0xcf;
-}
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *v)
-{
-	strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
-	strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
-	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	struct zoltrix *zol = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = 88 * 16000;
-	v->rangehigh = 108 * 16000;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	if (zol_is_stereo(zol))
-		v->audmode = V4L2_TUNER_MODE_STEREO;
-	else
-		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = 0xFFFF * zol_getsigstr(zol);
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct zoltrix *zol = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	if (zol_setfreq(zol, f->frequency) != 0)
-		return -EINVAL;
-	return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct zoltrix *zol = video_drvdata(file);
+	b = inb(isa->io);
 
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	f->frequency = zol->curfreq;
-	return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	case V4L2_CID_AUDIO_VOLUME:
-		return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct zoltrix *zol = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = zol->muted;
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = zol->curvol * 4096;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-				struct v4l2_control *ctrl)
-{
-	struct zoltrix *zol = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value)
-			zol_mute(zol);
-		else {
-			zol_unmute(zol);
-			zol_setvol(zol, zol->curvol);
-		}
-		return 0;
-	case V4L2_CID_AUDIO_VOLUME:
-		zol_setvol(zol, ctrl->value / 4096);
+	if (a != b)
 		return 0;
-	}
-	zol->stereo = 1;
-	if (zol_setfreq(zol, zol->curfreq) != 0)
-		return -EINVAL;
-#if 0
-/* FIXME: Implement stereo/mono switch on V4L2 */
-	if (v->mode & VIDEO_SOUND_STEREO) {
-		zol->stereo = 1;
-		zol_setfreq(zol, zol->curfreq);
-	}
-	if (v->mode & VIDEO_SOUND_MONO) {
-		zol->stereo = 0;
-		zol_setfreq(zol, zol->curfreq);
-	}
-#endif
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
 
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
+	/* I found this out by playing with a binary scanner on the card io */
+	return (a == 0xcf || a == 0xdf || a == 0xef) ? 0xffff : 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
+static int zoltrix_s_stereo(struct radio_isa_card *isa, bool stereo)
 {
-	return a->index ? -EINVAL : 0;
+	return zoltrix_s_frequency(isa, isa->freq);
 }
 
-static const struct v4l2_file_operations zoltrix_fops =
-{
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
+static const struct radio_isa_ops zoltrix_ops = {
+	.alloc = zoltrix_alloc,
+	.s_mute_volume = zoltrix_s_mute_volume,
+	.s_frequency = zoltrix_s_frequency,
+	.s_stereo = zoltrix_s_stereo,
+	.g_rxsubchans = zoltrix_g_rxsubchans,
+	.g_signal = zoltrix_g_signal,
 };
 
-static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
+static const int zoltrix_ioports[] = { 0x20c, 0x30c };
+
+static struct radio_isa_driver zoltrix_driver = {
+	.driver = {
+		.match		= radio_isa_match,
+		.probe		= radio_isa_probe,
+		.remove		= radio_isa_remove,
+		.driver		= {
+			.name	= "radio-zoltrix",
+		},
+	},
+	.io_params = io,
+	.radio_nr_params = radio_nr,
+	.io_ports = zoltrix_ioports,
+	.num_of_io_ports = ARRAY_SIZE(zoltrix_ioports),
+	.region_size = 2,
+	.card = "Zoltrix Radio Plus",
+	.ops = &zoltrix_ops,
+	.has_stereo = true,
+	.max_volume = 15,
 };
 
 static int __init zoltrix_init(void)
 {
-	struct zoltrix *zol = &zoltrix_card;
-	struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
-	int res;
-
-	strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name));
-	zol->io = io;
-	if (zol->io == -1) {
-		v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n");
-		return -EINVAL;
-	}
-	if (zol->io != 0x20c && zol->io != 0x30c) {
-		v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n");
-		return -ENXIO;
-	}
-
-	if (!request_region(zol->io, 2, "zoltrix")) {
-		v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io);
-		return -EBUSY;
-	}
-
-	res = v4l2_device_register(NULL, v4l2_dev);
-	if (res < 0) {
-		release_region(zol->io, 2);
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		return res;
-	}
-
-	mutex_init(&zol->lock);
-
-	/* mute card - prevents noisy bootups */
-
-	/* this ensures that the volume is all the way down  */
-
-	outb(0, zol->io);
-	outb(0, zol->io);
-	msleep(20);
-	inb(zol->io + 3);
-
-	zol->curvol = 0;
-	zol->stereo = 1;
-
-	strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
-	zol->vdev.v4l2_dev = v4l2_dev;
-	zol->vdev.fops = &zoltrix_fops;
-	zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
-	zol->vdev.release = video_device_release_empty;
-	video_set_drvdata(&zol->vdev, zol);
-
-	if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		v4l2_device_unregister(v4l2_dev);
-		release_region(zol->io, 2);
-		return -EINVAL;
-	}
-	v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
-
-	return 0;
+	return isa_register_driver(&zoltrix_driver.driver, ZOLTRIX_MAX);
 }
 
 static void __exit zoltrix_exit(void)
 {
-	struct zoltrix *zol = &zoltrix_card;
-
-	video_unregister_device(&zol->vdev);
-	v4l2_device_unregister(&zol->v4l2_dev);
-	release_region(zol->io, 2);
+	isa_unregister_driver(&zoltrix_driver.driver);
 }
 
 module_init(zoltrix_init);
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
index 86b2857..ea1e654 100644
--- a/drivers/media/radio/wl128x/Kconfig
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -4,8 +4,8 @@
 menu "Texas Instruments WL128x FM driver (ST based)"
 config RADIO_WL128X
 	tristate "Texas Instruments WL128x FM Radio"
-	depends on VIDEO_V4L2 && RFKILL
-	select TI_ST if NET && GPIOLIB
+	depends on VIDEO_V4L2 && RFKILL && GPIOLIB
+	select TI_ST if NET
 	help
 	Choose Y here if you have this FM radio chip.
 
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 7f7079b..392d4be 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -117,7 +117,7 @@ static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset)
 static void cir_dump_regs(struct fintek_dev *fintek)
 {
 	fintek_config_mode_enable(fintek);
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 
 	pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
 	pr_reg(" * CR CIR BASE ADDR: 0x%x\n",
@@ -143,7 +143,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
 	u8 chip_major, chip_minor;
 	u8 vendor_major, vendor_minor;
 	u8 portsel, ir_class;
-	u16 vendor;
+	u16 vendor, chip;
 	int ret = 0;
 
 	fintek_config_mode_enable(fintek);
@@ -176,6 +176,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
 
 	chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI);
 	chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO);
+	chip  = chip_major << 8 | chip_minor;
 
 	vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI);
 	vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO);
@@ -192,6 +193,15 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
 	fintek->chip_major  = chip_major;
 	fintek->chip_minor  = chip_minor;
 	fintek->chip_vendor = vendor;
+
+	/*
+	 * Newer reviews of this chipset uses port 8 instead of 5
+	 */
+	if ((chip != 0x0408) || (chip != 0x0804))
+		fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV2;
+	else
+		fintek->logical_dev_cir = LOGICAL_DEV_CIR_REV1;
+
 	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
 
 	return ret;
@@ -200,7 +210,7 @@ static int fintek_hw_detect(struct fintek_dev *fintek)
 static void fintek_cir_ldev_init(struct fintek_dev *fintek)
 {
 	/* Select CIR logical device and enable */
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 	fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
 
 	/* Write allocated CIR address and IRQ information to hardware */
@@ -381,7 +391,7 @@ static irqreturn_t fintek_cir_isr(int irq, void *data)
 	fit_dbg_verbose("%s firing", __func__);
 
 	fintek_config_mode_enable(fintek);
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 	fintek_config_mode_disable(fintek);
 
 	/*
@@ -422,7 +432,7 @@ static void fintek_enable_cir(struct fintek_dev *fintek)
 	fintek_config_mode_enable(fintek);
 
 	/* enable the CIR logical device */
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 	fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
 
 	fintek_config_mode_disable(fintek);
@@ -439,7 +449,7 @@ static void fintek_disable_cir(struct fintek_dev *fintek)
 	fintek_config_mode_enable(fintek);
 
 	/* disable the CIR logical device */
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 	fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
 
 	fintek_config_mode_disable(fintek);
@@ -611,7 +621,7 @@ static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state)
 	fintek_config_mode_enable(fintek);
 
 	/* disable cir logical dev */
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 	fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
 
 	fintek_config_mode_disable(fintek);
@@ -634,7 +644,7 @@ static int fintek_resume(struct pnp_dev *pdev)
 
 	/* Enable CIR logical device */
 	fintek_config_mode_enable(fintek);
-	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
 	fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
 
 	fintek_config_mode_disable(fintek);
diff --git a/drivers/media/rc/fintek-cir.h b/drivers/media/rc/fintek-cir.h
index 1b10b20..82516a1 100644
--- a/drivers/media/rc/fintek-cir.h
+++ b/drivers/media/rc/fintek-cir.h
@@ -88,6 +88,7 @@ struct fintek_dev {
 	u8 chip_major;
 	u8 chip_minor;
 	u16 chip_vendor;
+	u8 logical_dev_cir;
 
 	/* hardware features */
 	bool hw_learning_capable;
@@ -172,7 +173,8 @@ struct fintek_dev {
 #define LOGICAL_DEV_ENABLE	0x01
 
 /* Logical device number of the CIR function */
-#define LOGICAL_DEV_CIR		0x05
+#define LOGICAL_DEV_CIR_REV1	0x05
+#define LOGICAL_DEV_CIR_REV2	0x08
 
 /* CIR Logical Device (LDN 0x08) config registers */
 #define CIR_CR_COMMAND_INDEX	0x04
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 3aeb29a..7f26fdf 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -47,7 +47,7 @@
 #define MOD_AUTHOR	"Jarod Wilson <jarod@wilsonet.com>"
 #define MOD_DESC	"Driver for SoundGraph iMON MultiMedia IR/Display"
 #define MOD_NAME	"imon"
-#define MOD_VERSION	"0.9.3"
+#define MOD_VERSION	"0.9.4"
 
 #define DISPLAY_MINOR_BASE	144
 #define DEVICE_NAME	"lcd%d"
@@ -1658,9 +1658,17 @@ static void usb_rx_callback_intf0(struct urb *urb)
 		return;
 
 	ictx = (struct imon_context *)urb->context;
-	if (!ictx || !ictx->dev_present_intf0)
+	if (!ictx)
 		return;
 
+	/*
+	 * if we get a callback before we're done configuring the hardware, we
+	 * can't yet process the data, as there's nowhere to send it, but we
+	 * still need to submit a new rx URB to avoid wedging the hardware
+	 */
+	if (!ictx->dev_present_intf0)
+		goto out;
+
 	switch (urb->status) {
 	case -ENOENT:		/* usbcore unlink successful! */
 		return;
@@ -1678,6 +1686,7 @@ static void usb_rx_callback_intf0(struct urb *urb)
 		break;
 	}
 
+out:
 	usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
 }
 
@@ -1690,9 +1699,17 @@ static void usb_rx_callback_intf1(struct urb *urb)
 		return;
 
 	ictx = (struct imon_context *)urb->context;
-	if (!ictx || !ictx->dev_present_intf1)
+	if (!ictx)
 		return;
 
+	/*
+	 * if we get a callback before we're done configuring the hardware, we
+	 * can't yet process the data, as there's nowhere to send it, but we
+	 * still need to submit a new rx URB to avoid wedging the hardware
+	 */
+	if (!ictx->dev_present_intf1)
+		goto out;
+
 	switch (urb->status) {
 	case -ENOENT:		/* usbcore unlink successful! */
 		return;
@@ -1710,6 +1727,7 @@ static void usb_rx_callback_intf1(struct urb *urb)
 		break;
 	}
 
+out:
 	usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
 }
 
@@ -2242,7 +2260,7 @@ find_endpoint_failed:
 	mutex_unlock(&ictx->lock);
 	usb_free_urb(rx_urb);
 rx_urb_alloc_failed:
-	dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret);
+	dev_err(ictx->dev, "unable to initialize intf1, err %d\n", ret);
 
 	return NULL;
 }
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 36e4d5e..9514d82 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -41,6 +41,8 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
 			rc-imon-mce.o \
 			rc-imon-pad.o \
 			rc-iodata-bctv7e.o \
+			rc-it913x-v1.o \
+			rc-it913x-v2.o \
 			rc-kaiomy.o \
 			rc-kworld-315u.o \
 			rc-kworld-plus-tv-analog.o \
diff --git a/drivers/media/rc/keymaps/rc-it913x-v1.c b/drivers/media/rc/keymaps/rc-it913x-v1.c
new file mode 100644
index 0000000..0ac775f
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-it913x-v1.c
@@ -0,0 +1,95 @@
+/* ITE Generic remotes Version 1
+ *
+ * Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+
+static struct rc_map_table it913x_v1_rc[] = {
+	/* Type 1 */
+	{ 0x61d601, KEY_VIDEO },           /* Source */
+	{ 0x61d602, KEY_3 },
+	{ 0x61d603, KEY_POWER },           /* ShutDown */
+	{ 0x61d604, KEY_1 },
+	{ 0x61d605, KEY_5 },
+	{ 0x61d606, KEY_6 },
+	{ 0x61d607, KEY_CHANNELDOWN },     /* CH- */
+	{ 0x61d608, KEY_2 },
+	{ 0x61d609, KEY_CHANNELUP },       /* CH+ */
+	{ 0x61d60a, KEY_9 },
+	{ 0x61d60b, KEY_ZOOM },            /* Zoom */
+	{ 0x61d60c, KEY_7 },
+	{ 0x61d60d, KEY_8 },
+	{ 0x61d60e, KEY_VOLUMEUP },        /* Vol+ */
+	{ 0x61d60f, KEY_4 },
+	{ 0x61d610, KEY_ESC },             /* [back up arrow] */
+	{ 0x61d611, KEY_0 },
+	{ 0x61d612, KEY_OK },              /* [enter arrow] */
+	{ 0x61d613, KEY_VOLUMEDOWN },      /* Vol- */
+	{ 0x61d614, KEY_RECORD },          /* Rec */
+	{ 0x61d615, KEY_STOP },            /* Stop */
+	{ 0x61d616, KEY_PLAY },            /* Play */
+	{ 0x61d617, KEY_MUTE },            /* Mute */
+	{ 0x61d618, KEY_UP },
+	{ 0x61d619, KEY_DOWN },
+	{ 0x61d61a, KEY_LEFT },
+	{ 0x61d61b, KEY_RIGHT },
+	{ 0x61d61c, KEY_RED },
+	{ 0x61d61d, KEY_GREEN },
+	{ 0x61d61e, KEY_YELLOW },
+	{ 0x61d61f, KEY_BLUE },
+	{ 0x61d643, KEY_POWER2 },          /* [red power button] */
+	/* Type 2 - 20 buttons */
+	{ 0x807f0d, KEY_0 },
+	{ 0x807f04, KEY_1 },
+	{ 0x807f05, KEY_2 },
+	{ 0x807f06, KEY_3 },
+	{ 0x807f07, KEY_4 },
+	{ 0x807f08, KEY_5 },
+	{ 0x807f09, KEY_6 },
+	{ 0x807f0a, KEY_7 },
+	{ 0x807f1b, KEY_8 },
+	{ 0x807f1f, KEY_9 },
+	{ 0x807f12, KEY_POWER },
+	{ 0x807f01, KEY_MEDIA_REPEAT}, /* Recall */
+	{ 0x807f19, KEY_PAUSE }, /* Timeshift */
+	{ 0x807f1e, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
+	{ 0x807f03, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
+	{ 0x807f1a, KEY_CHANNELUP },
+	{ 0x807f02, KEY_CHANNELDOWN },
+	{ 0x807f0c, KEY_ZOOM },
+	{ 0x807f00, KEY_RECORD },
+	{ 0x807f0e, KEY_STOP },
+};
+
+static struct rc_map_list it913x_v1_map = {
+	.map = {
+		.scan    = it913x_v1_rc,
+		.size    = ARRAY_SIZE(it913x_v1_rc),
+		.rc_type = RC_TYPE_NEC,
+		.name    = RC_MAP_IT913X_V1,
+	}
+};
+
+static int __init init_rc_it913x_v1_map(void)
+{
+	return rc_map_register(&it913x_v1_map);
+}
+
+static void __exit exit_rc_it913x_v1_map(void)
+{
+	rc_map_unregister(&it913x_v1_map);
+}
+
+module_init(init_rc_it913x_v1_map)
+module_exit(exit_rc_it913x_v1_map)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
diff --git a/drivers/media/rc/keymaps/rc-it913x-v2.c b/drivers/media/rc/keymaps/rc-it913x-v2.c
new file mode 100644
index 0000000..28e376e
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-it913x-v2.c
@@ -0,0 +1,94 @@
+/* ITE Generic remotes Version 2
+ *
+ * Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <media/rc-map.h>
+#include <linux/module.h>
+
+
+static struct rc_map_table it913x_v2_rc[] = {
+	/* Type 1 */
+	/* 9005 remote */
+	{ 0x807f12, KEY_POWER2 },	/* Power (RED POWER BUTTON)*/
+	{ 0x807f1a, KEY_VIDEO },	/* Source */
+	{ 0x807f1e, KEY_MUTE },		/* Mute */
+	{ 0x807f01, KEY_RECORD },	/* Record */
+	{ 0x807f02, KEY_CHANNELUP },	/* Channel+ */
+	{ 0x807f03, KEY_TIME },		/* TimeShift */
+	{ 0x807f04, KEY_VOLUMEUP },	/* Volume- */
+	{ 0x807f05, KEY_SCREEN },	/* FullScreen */
+	{ 0x807f06, KEY_VOLUMEDOWN },	/* Volume- */
+	{ 0x807f07, KEY_0 },		/* 0 */
+	{ 0x807f08, KEY_CHANNELDOWN },	/* Channel- */
+	{ 0x807f09, KEY_PREVIOUS },	/* Recall */
+	{ 0x807f0a, KEY_1 },		/* 1 */
+	{ 0x807f1b, KEY_2 },		/* 2 */
+	{ 0x807f1f, KEY_3 },		/* 3 */
+	{ 0x807f0c, KEY_4 },		/* 4 */
+	{ 0x807f0d, KEY_5 },		/* 5 */
+	{ 0x807f0e, KEY_6 },		/* 6 */
+	{ 0x807f00, KEY_7 },		/* 7 */
+	{ 0x807f0f, KEY_8 },		/* 8 */
+	{ 0x807f19, KEY_9 },		/* 9 */
+
+	/* Type 2 */
+	/* keys stereo, snapshot unassigned */
+	{ 0x866b00, KEY_0 },
+	{ 0x866b1b, KEY_1 },
+	{ 0x866b02, KEY_2 },
+	{ 0x866b03, KEY_3 },
+	{ 0x866b04, KEY_4 },
+	{ 0x866b05, KEY_5 },
+	{ 0x866b06, KEY_6 },
+	{ 0x866b07, KEY_7 },
+	{ 0x866b08, KEY_8 },
+	{ 0x866b09, KEY_9 },
+	{ 0x866b12, KEY_POWER },
+	{ 0x866b13, KEY_MUTE },
+	{ 0x866b0a, KEY_PREVIOUS }, /* Recall */
+	{ 0x866b1e, KEY_PAUSE },
+	{ 0x866b0c, KEY_VOLUMEUP },
+	{ 0x866b18, KEY_VOLUMEDOWN },
+	{ 0x866b0b, KEY_CHANNELUP },
+	{ 0x866b18, KEY_CHANNELDOWN },
+	{ 0x866b10, KEY_ZOOM },
+	{ 0x866b1d, KEY_RECORD },
+	{ 0x866b0e, KEY_STOP },
+	{ 0x866b11, KEY_EPG},
+	{ 0x866b1a, KEY_FASTFORWARD },
+	{ 0x866b0f, KEY_REWIND },
+	{ 0x866b1c, KEY_TV },
+	{ 0x866b1b, KEY_TEXT },
+
+};
+
+static struct rc_map_list it913x_v2_map = {
+	.map = {
+		.scan    = it913x_v2_rc,
+		.size    = ARRAY_SIZE(it913x_v2_rc),
+		.rc_type = RC_TYPE_NEC,
+		.name    = RC_MAP_IT913X_V2,
+	}
+};
+
+static int __init init_rc_it913x_v2_map(void)
+{
+	return rc_map_register(&it913x_v2_map);
+}
+
+static void __exit exit_rc_it913x_v2_map(void)
+{
+	rc_map_unregister(&it913x_v2_map);
+}
+
+module_init(init_rc_it913x_v2_map)
+module_exit(exit_rc_it913x_v2_map)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
index f3b86c8..8d4dae2 100644
--- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -18,6 +18,8 @@
  */
 
 static struct rc_map_table nec_terratec_cinergy_xs[] = {
+
+	/* Terratec Grey IR, with most keys in orange */
 	{ 0x1441, KEY_HOME},
 	{ 0x1401, KEY_POWER2},
 
@@ -78,6 +80,56 @@ static struct rc_map_table nec_terratec_cinergy_xs[] = {
 	{ 0x144e, KEY_REWIND},
 	{ 0x144f, KEY_FASTFORWARD},
 	{ 0x145c, KEY_NEXT},
+
+	/* Terratec Black IR, with most keys in black */
+	{ 0x04eb01, KEY_POWER2},
+
+	{ 0x04eb02, KEY_1},
+	{ 0x04eb03, KEY_2},
+	{ 0x04eb04, KEY_3},
+	{ 0x04eb05, KEY_4},
+	{ 0x04eb06, KEY_5},
+	{ 0x04eb07, KEY_6},
+	{ 0x04eb08, KEY_7},
+	{ 0x04eb09, KEY_8},
+	{ 0x04eb0a, KEY_9},
+	{ 0x04eb0c, KEY_0},
+
+	{ 0x04eb0b, KEY_TEXT},		/* TXT */
+	{ 0x04eb0d, KEY_REFRESH},	/* Refresh */
+
+	{ 0x04eb0e, KEY_HOME},
+	{ 0x04eb0f, KEY_EPG},
+
+	{ 0x04eb10, KEY_UP},
+	{ 0x04eb11, KEY_LEFT},
+	{ 0x04eb12, KEY_OK},
+	{ 0x04eb13, KEY_RIGHT},
+	{ 0x04eb14, KEY_DOWN},
+
+	{ 0x04eb15, KEY_BACKSPACE},
+	{ 0x04eb16, KEY_INFO},
+
+	{ 0x04eb17, KEY_RED},
+	{ 0x04eb18, KEY_GREEN},
+	{ 0x04eb19, KEY_YELLOW},
+	{ 0x04eb1a, KEY_BLUE},
+
+	{ 0x04eb1c, KEY_VOLUMEUP},
+	{ 0x04eb1e, KEY_VOLUMEDOWN},
+
+	{ 0x04eb1d, KEY_MUTE},
+
+	{ 0x04eb1b, KEY_CHANNELUP},
+	{ 0x04eb1f, KEY_CHANNELDOWN},
+
+	{ 0x04eb40, KEY_RECORD},
+	{ 0x04eb4c, KEY_PLAY},
+	{ 0x04eb58, KEY_PAUSE},
+
+	{ 0x04eb54, KEY_REWIND},
+	{ 0x04eb48, KEY_STOP},
+	{ 0x04eb5c, KEY_NEXT},
 };
 
 static struct rc_map_list nec_terratec_cinergy_xs_map = {
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 76c301f..e581b37 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2035,11 +2035,7 @@ static int bttv_log_status(struct file *file, void *f)
 	struct bttv_fh *fh  = f;
 	struct bttv *btv = fh->btv;
 
-	pr_info("%d: ========  START STATUS CARD #%d  ========\n",
-		btv->c.nr, btv->c.nr);
 	bttv_call_all(btv, core, log_status);
-	pr_info("%d: ========  END STATUS CARD   #%d  ========\n",
-		btv->c.nr, btv->c.nr);
 	return 0;
 }
 
diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c
index a1e6c2a..e118361 100644
--- a/drivers/media/video/cx18/cx18-alsa-main.c
+++ b/drivers/media/video/cx18/cx18-alsa-main.c
@@ -285,7 +285,6 @@ static void __exit cx18_alsa_exit(void)
 
 	drv = driver_find("cx18", &pci_bus_type);
 	ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback);
-	put_driver(drv);
 
 	cx18_ext_init = NULL;
 	printk(KERN_INFO "cx18-alsa: module unload complete\n");
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index b9a94fc..7a37e0e 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -44,8 +44,6 @@
 #include <linux/slab.h>
 #include <asm/byteorder.h>
 
-#include <linux/dvb/video.h>
-#include <linux/dvb/audio.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 66b1c15..be49f68 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -1085,8 +1085,6 @@ static int cx18_log_status(struct file *file, void *fh)
 	struct v4l2_audio audin;
 	int i;
 
-	CX18_INFO("=================  START STATUS CARD #%d  "
-		  "=================\n", cx->instance);
 	CX18_INFO("Version: %s  Card: %s\n", CX18_VERSION, cx->card_name);
 	if (cx->hw_flags & CX18_HW_TVEEPROM) {
 		struct tveeprom tv;
@@ -1120,8 +1118,6 @@ static int cx18_log_status(struct file *file, void *fh)
 	CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
 			(long long)cx->mpg_data_received,
 			(long long)cx->vbi_data_inserted);
-	CX18_INFO("==================  END STATUS CARD #%d  "
-		  "==================\n", cx->instance);
 	return 0;
 }
 
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index f8f0e59..d4327da 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -1686,7 +1686,6 @@ static struct v4l2_capability pvr_capability = {
 	.capabilities   = (V4L2_CAP_VIDEO_CAPTURE |
 			   V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
 			 V4L2_CAP_STREAMING | V4L2_CAP_READWRITE),
-	.reserved       = {0, 0, 0, 0}
 };
 static int vidioc_querycap(struct file *file, void  *priv,
 				struct v4l2_capability *cap)
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
index f83baf3..5b68847 100644
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -292,7 +292,7 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
 	if ((ccdcparam->med_filt_thres < 0) ||
 	   (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
 		dev_dbg(ccdc_cfg.dev,
-			"Invalid value of median filter thresold\n");
+			"Invalid value of median filter threshold\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
index 25036cb..8bcac65 100644
--- a/drivers/media/video/davinci/vpif.h
+++ b/drivers/media/video/davinci/vpif.h
@@ -18,8 +18,6 @@
 
 #include <linux/io.h>
 #include <linux/videodev2.h>
-#include <mach/hardware.h>
-#include <mach/dm646x.h>
 #include <media/davinci/vpif_types.h>
 
 /* Maximum channel allowed */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
index 286f029..7fa34b4 100644
--- a/drivers/media/video/davinci/vpif_display.c
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -39,8 +39,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-chip-ident.h>
 
-#include <mach/dm646x.h>
-
 #include "vpif_display.h"
 #include "vpif.h"
 
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index e5eb56a..6510110 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -154,10 +154,20 @@ static int device_authorization(struct hdpvr_device *dev)
 	}
 #endif
 
+	dev->fw_ver = dev->usbc_buf[1];
+
 	v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
-			  dev->usbc_buf[1], &dev->usbc_buf[2]);
+			  dev->fw_ver, &dev->usbc_buf[2]);
+
+	if (dev->fw_ver > 0x15) {
+		dev->options.brightness	= 0x80;
+		dev->options.contrast	= 0x40;
+		dev->options.hue	= 0xf;
+		dev->options.saturation	= 0x40;
+		dev->options.sharpness	= 0x80;
+	}
 
-	switch (dev->usbc_buf[1]) {
+	switch (dev->fw_ver) {
 	case HDPVR_FIRMWARE_VERSION:
 		dev->flags &= ~HDPVR_FLAG_AC3_CAP;
 		break;
@@ -169,7 +179,7 @@ static int device_authorization(struct hdpvr_device *dev)
 	default:
 		v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might"
 			  " not work.\n");
-		if (dev->usbc_buf[1] >= HDPVR_FIRMWARE_VERSION_AC3)
+		if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3)
 			dev->flags |= HDPVR_FLAG_AC3_CAP;
 		else
 			dev->flags &= ~HDPVR_FLAG_AC3_CAP;
@@ -270,6 +280,8 @@ static const struct hdpvr_options hdpvr_default_options = {
 	.bitrate_mode	= HDPVR_CONSTANT,
 	.gop_mode	= HDPVR_SIMPLE_IDR_GOP,
 	.audio_codec	= V4L2_MPEG_AUDIO_ENCODING_AAC,
+	/* original picture controls for firmware version <= 0x15 */
+	/* updated in device_authorization() for newer firmware */
 	.brightness	= 0x86,
 	.contrast	= 0x80,
 	.hue		= 0x80,
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 087f7c0..11ffe9c 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -283,12 +283,13 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
 
 		hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
 
+		dev->status = STATUS_STREAMING;
+
 		INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
 		queue_work(dev->workqueue, &dev->worker);
 
 		v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
 			 "streaming started\n");
-		dev->status = STATUS_STREAMING;
 
 		return 0;
 	}
@@ -722,21 +723,39 @@ static const s32 supported_v4l2_ctrls[] = {
 };
 
 static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
-			  int ac3)
+			  int ac3, int fw_ver)
 {
 	int err;
 
+	if (fw_ver > 0x15) {
+		switch (qc->id) {
+		case V4L2_CID_BRIGHTNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_CONTRAST:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
+		case V4L2_CID_SATURATION:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
+		case V4L2_CID_HUE:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf);
+		case V4L2_CID_SHARPNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		}
+	} else {
+		switch (qc->id) {
+		case V4L2_CID_BRIGHTNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
+		case V4L2_CID_CONTRAST:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_SATURATION:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_HUE:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		case V4L2_CID_SHARPNESS:
+			return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+		}
+	}
+
 	switch (qc->id) {
-	case V4L2_CID_BRIGHTNESS:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
-	case V4L2_CID_CONTRAST:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
-	case V4L2_CID_SATURATION:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
-	case V4L2_CID_HUE:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
-	case V4L2_CID_SHARPNESS:
-		return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
 	case V4L2_CID_MPEG_AUDIO_ENCODING:
 		return v4l2_ctrl_query_fill(
 			qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
@@ -794,7 +813,8 @@ static int vidioc_queryctrl(struct file *file, void *private_data,
 
 		if (qc->id == supported_v4l2_ctrls[i])
 			return fill_queryctrl(&dev->options, qc,
-					      dev->flags & HDPVR_FLAG_AC3_CAP);
+					      dev->flags & HDPVR_FLAG_AC3_CAP,
+					      dev->fw_ver);
 
 		if (qc->id < supported_v4l2_ctrls[i])
 			break;
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index d6439db..fea3c69 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -113,6 +113,7 @@ struct hdpvr_device {
 	/* usb control transfer buffer and lock */
 	struct mutex		usbc_mutex;
 	u8			*usbc_buf;
+	u8			fw_ver;
 };
 
 static inline struct hdpvr_device *to_hdpvr_dev(struct v4l2_device *v4l2_dev)
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index b31ee1b..e290118 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -21,6 +21,7 @@
 #include "ivtv-driver.h"
 #include "ivtv-ioctl.h"
 #include "ivtv-controls.h"
+#include "ivtv-mailbox.h"
 
 static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
 {
@@ -99,3 +100,64 @@ struct cx2341x_handler_ops ivtv_cxhdl_ops = {
 	.s_video_encoding = ivtv_s_video_encoding,
 	.s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
 };
+
+int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame)
+{
+	u32 data[CX2341X_MBOX_MAX_DATA];
+
+	if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
+		*pts = (s64)((u64)itv->last_dec_timing[2] << 32) |
+			(u64)itv->last_dec_timing[1];
+		*frame = itv->last_dec_timing[0];
+		return 0;
+	}
+	*pts = 0;
+	*frame = 0;
+	if (atomic_read(&itv->decoding)) {
+		if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
+			IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
+			return -EIO;
+		}
+		memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
+		set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
+		*pts = (s64)((u64) data[2] << 32) | (u64) data[1];
+		*frame = data[0];
+		/*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
+	}
+	return 0;
+}
+
+static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ivtv *itv = container_of(ctrl->handler, struct ivtv, hdl_out);
+
+	switch (ctrl->id) {
+	/* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
+	   control cluster */
+	case V4L2_CID_MPEG_VIDEO_DEC_PTS:
+		return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64,
+					     &itv->ctrl_frame->val64);
+	}
+	return 0;
+}
+
+static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct ivtv *itv = container_of(ctrl->handler, struct ivtv, hdl_out);
+
+	switch (ctrl->id) {
+	/* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
+	   control cluster */
+	case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
+		itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1;
+		itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1;
+		ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
+		break;
+	}
+	return 0;
+}
+
+const struct v4l2_ctrl_ops ivtv_hdl_out_ops = {
+	.s_ctrl = ivtv_s_ctrl,
+	.g_volatile_ctrl = ivtv_g_volatile_ctrl,
+};
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
index d12893d..3999e63 100644
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ b/drivers/media/video/ivtv/ivtv-controls.h
@@ -22,5 +22,7 @@
 #define IVTV_CONTROLS_H
 
 extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
+extern const struct v4l2_ctrl_ops ivtv_hdl_out_ops;
+int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame);
 
 #endif
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 3949b7d..107e9e6 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -744,8 +744,6 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
 
 	itv->cur_dma_stream = -1;
 	itv->cur_pio_stream = -1;
-	itv->audio_stereo_mode = AUDIO_STEREO;
-	itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
 
 	/* Ctrls */
 	itv->speed = 1000;
@@ -1200,6 +1198,32 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
 	itv->tuner_std = itv->std;
 
 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+		v4l2_ctrl_handler_init(&itv->hdl_out, 50);
+		itv->ctrl_pts = v4l2_ctrl_new_std(&itv->hdl_out, &ivtv_hdl_out_ops,
+				V4L2_CID_MPEG_VIDEO_DEC_PTS, 0, 0, 1, 0);
+		itv->ctrl_frame = v4l2_ctrl_new_std(&itv->hdl_out, &ivtv_hdl_out_ops,
+				V4L2_CID_MPEG_VIDEO_DEC_FRAME, 0, 0x7fffffff, 1, 0);
+		/* Note: V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO is not supported,
+		   mask that menu item. */
+		itv->ctrl_audio_playback =
+			v4l2_ctrl_new_std_menu(&itv->hdl_out, &ivtv_hdl_out_ops,
+				V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK,
+				V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
+				1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
+				V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO);
+		itv->ctrl_audio_multilingual_playback =
+			v4l2_ctrl_new_std_menu(&itv->hdl_out, &ivtv_hdl_out_ops,
+				V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK,
+				V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO,
+				1 << V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO,
+				V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT);
+		v4l2_ctrl_add_handler(&itv->hdl_out, &itv->cxhdl.hdl);
+		if (itv->hdl_out.error) {
+			retval = itv->hdl_out.error;
+			goto free_i2c;
+		}
+		v4l2_ctrl_cluster(2, &itv->ctrl_pts);
+		v4l2_ctrl_cluster(2, &itv->ctrl_audio_playback);
 		ivtv_call_all(itv, video, s_std_output, itv->std);
 		/* Turn off the output signal. The mpeg decoder is not yet
 		   active so without this you would get a green image until the
@@ -1236,6 +1260,9 @@ free_streams:
 free_irq:
 	free_irq(itv->pdev->irq, (void *)itv);
 free_i2c:
+	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+		v4l2_ctrl_handler_free(&itv->hdl_out);
+	v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
 	exit_ivtv_i2c(itv);
 free_io:
 	ivtv_iounmap(itv);
@@ -1375,7 +1402,7 @@ static void ivtv_remove(struct pci_dev *pdev)
 			else
 				type = IVTV_DEC_STREAM_TYPE_MPG;
 			ivtv_stop_v4l2_decode_stream(&itv->streams[type],
-				VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+				V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
 		}
 		ivtv_halt_firmware(itv);
 	}
@@ -1391,6 +1418,10 @@ static void ivtv_remove(struct pci_dev *pdev)
 	ivtv_streams_cleanup(itv, 1);
 	ivtv_udma_free(itv);
 
+	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+		v4l2_ctrl_handler_free(&itv->hdl_out);
+	v4l2_ctrl_handler_free(&itv->cxhdl.hdl);
+
 	exit_ivtv_i2c(itv);
 
 	free_irq(itv->pdev->irq, (void *)itv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 06f3d78..f83857a 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -331,6 +331,7 @@ struct ivtv_stream {
 	struct ivtv *itv; 		/* for ease of use */
 	const char *name;		/* name of the stream */
 	int type;			/* stream type */
+	u32 caps;			/* V4L2 capabilities */
 
 	struct v4l2_fh *fh;		/* pointer to the streaming filehandle */
 	spinlock_t qlock; 		/* locks access to the queues */
@@ -630,6 +631,17 @@ struct ivtv {
 
 	struct v4l2_device v4l2_dev;
 	struct cx2341x_handler cxhdl;
+	struct {
+		/* PTS/Frame count control cluster */
+		struct v4l2_ctrl *ctrl_pts;
+		struct v4l2_ctrl *ctrl_frame;
+	};
+	struct {
+		/* Audio Playback control cluster */
+		struct v4l2_ctrl *ctrl_audio_playback;
+		struct v4l2_ctrl *ctrl_audio_multilingual_playback;
+	};
+	struct v4l2_ctrl_handler hdl_out;
 	struct v4l2_ctrl_handler hdl_gpio;
 	struct v4l2_subdev sd_gpio;	/* GPIO sub-device */
 	u16 instance;
@@ -649,7 +661,6 @@ struct ivtv {
 	u8 audio_stereo_mode;           /* decoder setting how to handle stereo MPEG audio */
 	u8 audio_bilingual_mode;        /* decoder setting how to handle bilingual MPEG audio */
 
-
 	/* Locking */
 	spinlock_t lock;                /* lock access to this struct */
 	struct mutex serialize_lock;    /* mutex used to serialize open/close/start/stop/ioctl operations */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 2cd6c89..c9663e8 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -900,7 +900,7 @@ int ivtv_v4l2_close(struct file *filp)
 	if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
 		struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
 
-		ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+		ivtv_stop_decoding(id, V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY, 0);
 
 		/* If all output streams are closed, and if the user doesn't have
 		   IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index c4bc481..385e003 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -246,34 +246,40 @@ static int ivtv_validate_speed(int cur_speed, int new_speed)
 }
 
 static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
-		struct video_command *vc, int try)
+		struct v4l2_decoder_cmd *dc, int try)
 {
 	struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
 
 	if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
 		return -EINVAL;
 
-	switch (vc->cmd) {
-	case VIDEO_CMD_PLAY: {
-		vc->flags = 0;
-		vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
-		if (vc->play.speed < 0)
-			vc->play.format = VIDEO_PLAY_FMT_GOP;
+	switch (dc->cmd) {
+	case V4L2_DEC_CMD_START: {
+		dc->flags &= V4L2_DEC_CMD_START_MUTE_AUDIO;
+		dc->start.speed = ivtv_validate_speed(itv->speed, dc->start.speed);
+		if (dc->start.speed < 0)
+			dc->start.format = V4L2_DEC_START_FMT_GOP;
+		else
+			dc->start.format = V4L2_DEC_START_FMT_NONE;
+		if (dc->start.speed != 500 && dc->start.speed != 1500)
+			dc->flags = dc->start.speed == 1000 ? 0 :
+					V4L2_DEC_CMD_START_MUTE_AUDIO;
 		if (try) break;
 
+		itv->speed_mute_audio = dc->flags & V4L2_DEC_CMD_START_MUTE_AUDIO;
 		if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
 			return -EBUSY;
 		if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
 			/* forces ivtv_set_speed to be called */
 			itv->speed = 0;
 		}
-		return ivtv_start_decoding(id, vc->play.speed);
+		return ivtv_start_decoding(id, dc->start.speed);
 	}
 
-	case VIDEO_CMD_STOP:
-		vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
-		if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
-			vc->stop.pts = 0;
+	case V4L2_DEC_CMD_STOP:
+		dc->flags &= V4L2_DEC_CMD_STOP_IMMEDIATELY | V4L2_DEC_CMD_STOP_TO_BLACK;
+		if (dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY)
+			dc->stop.pts = 0;
 		if (try) break;
 		if (atomic_read(&itv->decoding) == 0)
 			return 0;
@@ -281,22 +287,22 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
 			return -EBUSY;
 
 		itv->output_mode = OUT_NONE;
-		return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
+		return ivtv_stop_v4l2_decode_stream(s, dc->flags, dc->stop.pts);
 
-	case VIDEO_CMD_FREEZE:
-		vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
+	case V4L2_DEC_CMD_PAUSE:
+		dc->flags &= V4L2_DEC_CMD_PAUSE_TO_BLACK;
 		if (try) break;
 		if (itv->output_mode != OUT_MPG)
 			return -EBUSY;
 		if (atomic_read(&itv->decoding) > 0) {
 			ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
-				(vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
+				(dc->flags & V4L2_DEC_CMD_PAUSE_TO_BLACK) ? 1 : 0);
 			set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
 		}
 		break;
 
-	case VIDEO_CMD_CONTINUE:
-		vc->flags = 0;
+	case V4L2_DEC_CMD_RESUME:
+		dc->flags = 0;
 		if (try) break;
 		if (itv->output_mode != OUT_MPG)
 			return -EBUSY;
@@ -754,12 +760,15 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register
 
 static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
 {
-	struct ivtv *itv = fh2id(fh)->itv;
+	struct ivtv_open_id *id = fh2id(file->private_data);
+	struct ivtv *itv = id->itv;
+	struct ivtv_stream *s = &itv->streams[id->type];
 
 	strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
 	strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
 	snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
-	vcap->capabilities = itv->v4l2_cap; 	    /* capabilities */
+	vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
+	vcap->device_caps = s->caps;
 	return 0;
 }
 
@@ -1476,8 +1485,6 @@ static int ivtv_log_status(struct file *file, void *fh)
 	struct v4l2_audio audin;
 	int i;
 
-	IVTV_INFO("=================  START STATUS CARD #%d  =================\n",
-		       itv->instance);
 	IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
 	if (itv->hw_flags & IVTV_HW_TVEEPROM) {
 		struct tveeprom tv;
@@ -1501,13 +1508,6 @@ static int ivtv_log_status(struct file *file, void *fh)
 			"YUV Frames",
 			"Passthrough",
 		};
-		static const char * const audio_modes[5] = {
-			"Stereo",
-			"Left",
-			"Right",
-			"Mono",
-			"Swapped"
-		};
 		static const char * const alpha_mode[4] = {
 			"None",
 			"Global",
@@ -1536,9 +1536,6 @@ static int ivtv_log_status(struct file *file, void *fh)
 		ivtv_get_output(itv, itv->active_output, &vidout);
 		ivtv_get_audio_output(itv, 0, &audout);
 		IVTV_INFO("Video Output: %s\n", vidout.name);
-		IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
-			audio_modes[itv->audio_stereo_mode],
-			audio_modes[itv->audio_bilingual_mode]);
 		if (mode < 0 || mode > OUT_PASSTHROUGH)
 			mode = OUT_NONE;
 		IVTV_INFO("Output Mode:  %s\n", output_modes[mode]);
@@ -1551,7 +1548,10 @@ static int ivtv_log_status(struct file *file, void *fh)
 	}
 	IVTV_INFO("Tuner:  %s\n",
 		test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
-	v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
+	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+		v4l2_ctrl_handler_log_status(&itv->hdl_out, itv->v4l2_dev.name);
+	else
+		v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
 	IVTV_INFO("Status flags:    0x%08lx\n", itv->i_flags);
 	for (i = 0; i < IVTV_MAX_STREAMS; i++) {
 		struct ivtv_stream *s = &itv->streams[i];
@@ -1566,12 +1566,27 @@ static int ivtv_log_status(struct file *file, void *fh)
 	IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n",
 			(long long)itv->mpg_data_received,
 			(long long)itv->vbi_data_inserted);
-	IVTV_INFO("==================  END STATUS CARD #%d  ==================\n",
-			itv->instance);
-
 	return 0;
 }
 
+static int ivtv_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
+{
+	struct ivtv_open_id *id = fh2id(file->private_data);
+	struct ivtv *itv = id->itv;
+
+	IVTV_DEBUG_IOCTL("VIDIOC_DECODER_CMD %d\n", dec->cmd);
+	return ivtv_video_command(itv, id, dec, false);
+}
+
+static int ivtv_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *dec)
+{
+	struct ivtv_open_id *id = fh2id(file->private_data);
+	struct ivtv *itv = id->itv;
+
+	IVTV_DEBUG_IOCTL("VIDIOC_TRY_DECODER_CMD %d\n", dec->cmd);
+	return ivtv_video_command(itv, id, dec, true);
+}
+
 static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 {
 	struct ivtv_open_id *id = fh2id(filp->private_data);
@@ -1605,9 +1620,15 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 		return ivtv_yuv_prep_frame(itv, args);
 	}
 
+	case IVTV_IOC_PASSTHROUGH_MODE:
+		IVTV_DEBUG_IOCTL("IVTV_IOC_PASSTHROUGH_MODE\n");
+		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+			return -EINVAL;
+		return ivtv_passthrough_mode(itv, *(int *)arg != 0);
+
 	case VIDEO_GET_PTS: {
-		u32 data[CX2341X_MBOX_MAX_DATA];
-		u64 *pts = arg;
+		s64 *pts = arg;
+		s64 frame;
 
 		IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
 		if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
@@ -1616,29 +1637,12 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 		}
 		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
 			return -EINVAL;
-
-		if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
-			*pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
-					(u64)itv->last_dec_timing[1];
-			break;
-		}
-		*pts = 0;
-		if (atomic_read(&itv->decoding)) {
-			if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
-				IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
-				return -EIO;
-			}
-			memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
-			set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
-			*pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
-			/*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
-		}
-		break;
+		return ivtv_g_pts_frame(itv, pts, &frame);
 	}
 
 	case VIDEO_GET_FRAME_COUNT: {
-		u32 data[CX2341X_MBOX_MAX_DATA];
-		u64 *frame = arg;
+		s64 *frame = arg;
+		s64 pts;
 
 		IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
 		if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
@@ -1647,71 +1651,58 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 		}
 		if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
 			return -EINVAL;
-
-		if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
-			*frame = itv->last_dec_timing[0];
-			break;
-		}
-		*frame = 0;
-		if (atomic_read(&itv->decoding)) {
-			if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
-				IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
-				return -EIO;
-			}
-			memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
-			set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
-			*frame = data[0];
-		}
-		break;
+		return ivtv_g_pts_frame(itv, &pts, frame);
 	}
 
 	case VIDEO_PLAY: {
-		struct video_command vc;
+		struct v4l2_decoder_cmd dc;
 
 		IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
-		memset(&vc, 0, sizeof(vc));
-		vc.cmd = VIDEO_CMD_PLAY;
-		return ivtv_video_command(itv, id, &vc, 0);
+		memset(&dc, 0, sizeof(dc));
+		dc.cmd = V4L2_DEC_CMD_START;
+		return ivtv_video_command(itv, id, &dc, 0);
 	}
 
 	case VIDEO_STOP: {
-		struct video_command vc;
+		struct v4l2_decoder_cmd dc;
 
 		IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
-		memset(&vc, 0, sizeof(vc));
-		vc.cmd = VIDEO_CMD_STOP;
-		vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
-		return ivtv_video_command(itv, id, &vc, 0);
+		memset(&dc, 0, sizeof(dc));
+		dc.cmd = V4L2_DEC_CMD_STOP;
+		dc.flags = V4L2_DEC_CMD_STOP_TO_BLACK | V4L2_DEC_CMD_STOP_IMMEDIATELY;
+		return ivtv_video_command(itv, id, &dc, 0);
 	}
 
 	case VIDEO_FREEZE: {
-		struct video_command vc;
+		struct v4l2_decoder_cmd dc;
 
 		IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
-		memset(&vc, 0, sizeof(vc));
-		vc.cmd = VIDEO_CMD_FREEZE;
-		return ivtv_video_command(itv, id, &vc, 0);
+		memset(&dc, 0, sizeof(dc));
+		dc.cmd = V4L2_DEC_CMD_PAUSE;
+		return ivtv_video_command(itv, id, &dc, 0);
 	}
 
 	case VIDEO_CONTINUE: {
-		struct video_command vc;
+		struct v4l2_decoder_cmd dc;
 
 		IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
-		memset(&vc, 0, sizeof(vc));
-		vc.cmd = VIDEO_CMD_CONTINUE;
-		return ivtv_video_command(itv, id, &vc, 0);
+		memset(&dc, 0, sizeof(dc));
+		dc.cmd = V4L2_DEC_CMD_RESUME;
+		return ivtv_video_command(itv, id, &dc, 0);
 	}
 
 	case VIDEO_COMMAND:
 	case VIDEO_TRY_COMMAND: {
-		struct video_command *vc = arg;
+		/* Note: struct v4l2_decoder_cmd has the same layout as
+		   struct video_command */
+		struct v4l2_decoder_cmd *dc = arg;
 		int try = (cmd == VIDEO_TRY_COMMAND);
 
 		if (try)
-			IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
+			IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", dc->cmd);
 		else
-			IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
-		return ivtv_video_command(itv, id, vc, try);
+			IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", dc->cmd);
+		return ivtv_video_command(itv, id, dc, try);
 	}
 
 	case VIDEO_GET_EVENT: {
@@ -1775,17 +1766,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
 		IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
 		if (iarg > AUDIO_STEREO_SWAPPED)
 			return -EINVAL;
-		itv->audio_stereo_mode = iarg;
-		ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
-		return 0;
+		return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg);
 
 	case AUDIO_BILINGUAL_CHANNEL_SELECT:
 		IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
 		if (iarg > AUDIO_STEREO_SWAPPED)
 			return -EINVAL;
-		itv->audio_bilingual_mode = iarg;
-		ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
-		return 0;
+		return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg);
 
 	default:
 		return -EINVAL;
@@ -1800,6 +1787,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
 
 	if (!valid_prio) {
 		switch (cmd) {
+		case IVTV_IOC_PASSTHROUGH_MODE:
 		case VIDEO_PLAY:
 		case VIDEO_STOP:
 		case VIDEO_FREEZE:
@@ -1825,6 +1813,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
 	}
 
 	case IVTV_IOC_DMA_FRAME:
+	case IVTV_IOC_PASSTHROUGH_MODE:
 	case VIDEO_GET_PTS:
 	case VIDEO_GET_FRAME_COUNT:
 	case VIDEO_GET_EVENT:
@@ -1889,6 +1878,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
 	.vidioc_enum_fmt_vid_cap 	    = ivtv_enum_fmt_vid_cap,
 	.vidioc_encoder_cmd  		    = ivtv_encoder_cmd,
 	.vidioc_try_encoder_cmd 	    = ivtv_try_encoder_cmd,
+	.vidioc_decoder_cmd		    = ivtv_decoder_cmd,
+	.vidioc_try_decoder_cmd		    = ivtv_try_decoder_cmd,
 	.vidioc_enum_fmt_vid_out 	    = ivtv_enum_fmt_vid_out,
 	.vidioc_g_fmt_vid_cap 		    = ivtv_g_fmt_vid_cap,
 	.vidioc_g_fmt_vbi_cap		    = ivtv_g_fmt_vbi_cap,
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index c6e28b4..9cc037c 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -78,60 +78,73 @@ static struct {
 	int num_offset;
 	int dma, pio;
 	enum v4l2_buf_type buf_type;
+	u32 v4l2_caps;
 	const struct v4l2_file_operations *fops;
 } ivtv_stream_info[] = {
 	{	/* IVTV_ENC_STREAM_TYPE_MPG */
 		"encoder MPG",
 		VFL_TYPE_GRABBER, 0,
 		PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+		V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
+			V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_enc_fops
 	},
 	{	/* IVTV_ENC_STREAM_TYPE_YUV */
 		"encoder YUV",
 		VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET,
 		PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
+		V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
+			V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_enc_fops
 	},
 	{	/* IVTV_ENC_STREAM_TYPE_VBI */
 		"encoder VBI",
 		VFL_TYPE_VBI, 0,
 		PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE,
+		V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER |
+			V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_enc_fops
 	},
 	{	/* IVTV_ENC_STREAM_TYPE_PCM */
 		"encoder PCM",
 		VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
 		PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
+		V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_enc_fops
 	},
 	{	/* IVTV_ENC_STREAM_TYPE_RAD */
 		"encoder radio",
 		VFL_TYPE_RADIO, 0,
 		PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE,
+		V4L2_CAP_RADIO | V4L2_CAP_TUNER,
 		&ivtv_v4l2_enc_fops
 	},
 	{	/* IVTV_DEC_STREAM_TYPE_MPG */
 		"decoder MPG",
 		VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
 		PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+		V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_dec_fops
 	},
 	{	/* IVTV_DEC_STREAM_TYPE_VBI */
 		"decoder VBI",
 		VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET,
 		PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE,
+		V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_enc_fops
 	},
 	{	/* IVTV_DEC_STREAM_TYPE_VOUT */
 		"decoder VOUT",
 		VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET,
 		PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT,
+		V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_dec_fops
 	},
 	{	/* IVTV_DEC_STREAM_TYPE_YUV */
 		"decoder YUV",
 		VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET,
 		PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
+		V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE,
 		&ivtv_v4l2_dec_fops
 	}
 };
@@ -149,6 +162,7 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
 	s->itv = itv;
 	s->type = type;
 	s->name = ivtv_stream_info[type].name;
+	s->caps = ivtv_stream_info[type].v4l2_caps;
 
 	if (ivtv_stream_info[type].pio)
 		s->dma = PCI_DMA_NONE;
@@ -209,7 +223,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
 
 	s->vdev->num = num;
 	s->vdev->v4l2_dev = &itv->v4l2_dev;
-	s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
+	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+		s->vdev->ctrl_handler = &itv->hdl_out;
+	else
+		s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
 	s->vdev->fops = ivtv_stream_info[type].fops;
 	s->vdev->release = video_device_release;
 	s->vdev->tvnorms = V4L2_STD_ALL;
@@ -891,7 +908,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
 	IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
 
 	/* Stop Decoder */
-	if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
+	if (!(flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) || pts) {
 		u32 tmp = 0;
 
 		/* Wait until the decoder is no longer running */
@@ -911,7 +928,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
 				break;
 		}
 	}
-	ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & VIDEO_CMD_STOP_TO_BLACK, 0, 0);
+	ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 3, flags & V4L2_DEC_CMD_STOP_TO_BLACK, 0, 0);
 
 	/* turn off notification of dual/stereo mode change */
 	ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 69cc816..7338cb2 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -57,9 +57,9 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
 			if (dma->bouncemap[map_offset] == NULL)
 				return -1;
 			local_irq_save(flags);
-			src = kmap_atomic(dma->map[map_offset], KM_BOUNCE_READ) + offset;
+			src = kmap_atomic(dma->map[map_offset]) + offset;
 			memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
-			kunmap_atomic(src, KM_BOUNCE_READ);
+			kunmap_atomic(src);
 			local_irq_restore(flags);
 			sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset);
 		}
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index d0fbfcf..e5e7fa9 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1293,7 +1293,6 @@ static int __init ivtvfb_init(void)
 
 	drv = driver_find("ivtv", &pci_bus_type);
 	err = driver_for_each_device(drv, NULL, &registered, ivtvfb_callback_init);
-	put_driver(drv);
 	if (!registered) {
 		printk(KERN_ERR "ivtvfb:  no cards found\n");
 		return -ENODEV;
@@ -1310,7 +1309,6 @@ static void ivtvfb_cleanup(void)
 
 	drv = driver_find("ivtv", &pci_bus_type);
 	err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup);
-	put_driver(drv);
 }
 
 module_init(ivtvfb_init);
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 1fb7d5b..88cf9d9 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -2268,13 +2268,12 @@ static struct platform_driver omap_vout_driver = {
 	.driver = {
 		.name = VOUT_NAME,
 	},
-	.probe = omap_vout_probe,
 	.remove = omap_vout_remove,
 };
 
 static int __init omap_vout_init(void)
 {
-	if (platform_driver_register(&omap_vout_driver) != 0) {
+	if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
 		printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
 		return -EINVAL;
 	}
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index a74a797..eaabc27 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1407,7 +1407,7 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
 {
 	struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
-	struct video_device *vdev = &ccdc->subdev.devnode;
+	struct video_device *vdev = ccdc->subdev.devnode;
 	struct v4l2_event event;
 
 	memset(&event, 0, sizeof(event));
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index 6806345..3627f32 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -649,7 +649,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
 			clkrc = CLKRC_24MHz;
 		} else {
 			dev_err(&client->dev,
-				"unspported input clock, check platform data\n");
+				"unsupported input clock, check platform data\n");
 			return -EINVAL;
 		}
 		mclk = sense->master_clock;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 6d66617..e1111d9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -96,7 +96,6 @@ static struct v4l2_capability pvr_capability ={
 	.capabilities   = (V4L2_CAP_VIDEO_CAPTURE |
 			   V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
 			   V4L2_CAP_READWRITE),
-	.reserved       = {0,0,0,0}
 };
 
 static struct v4l2_fmtdesc pvr_fmtdesc [] = {
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index f495eeb..2834e3e 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1146,14 +1146,6 @@ leave:
 	return ret;
 }
 
-static int pwc_log_status(struct file *file, void *priv)
-{
-	struct pwc_device *pdev = video_drvdata(file);
-
-	v4l2_ctrl_handler_log_status(&pdev->ctrl_handler, PWC_NAME);
-	return 0;
-}
-
 const struct v4l2_ioctl_ops pwc_ioctl_ops = {
 	.vidioc_querycap		    = pwc_querycap,
 	.vidioc_enum_input		    = pwc_enum_input,
@@ -1169,7 +1161,7 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
 	.vidioc_dqbuf			    = pwc_dqbuf,
 	.vidioc_streamon		    = pwc_streamon,
 	.vidioc_streamoff		    = pwc_streamoff,
-	.vidioc_log_status		    = pwc_log_status,
+	.vidioc_log_status		    = v4l2_ctrl_log_status,
 	.vidioc_enum_framesizes		    = pwc_enum_framesizes,
 	.vidioc_enum_frameintervals	    = pwc_enum_frameintervals,
 	.vidioc_g_parm			    = pwc_g_parm,
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
index 8ea4ee1..63eccb5 100644
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c
@@ -344,16 +344,13 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd)
 		return -ENODEV;
 	ret = driver_for_each_device(driver, NULL, fmd,
 				     fimc_register_callback);
-	put_driver(driver);
 	if (ret)
 		return ret;
 
 	driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type);
-	if (driver) {
+	if (driver)
 		ret = driver_for_each_device(driver, NULL, fmd,
 					     csis_register_callback);
-		put_driver(driver);
-	}
 	return ret;
 }
 
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
index 8b41a04..3e0dd09 100644
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ b/drivers/media/video/s5p-tv/hdmi_drv.c
@@ -962,7 +962,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
 	/* storing subdev for call that have only access to struct device */
 	dev_set_drvdata(dev, sd);
 
-	dev_info(dev, "probe sucessful\n");
+	dev_info(dev, "probe successful\n");
 
 	return 0;
 
@@ -1000,7 +1000,7 @@ static int __devexit hdmi_remove(struct platform_device *pdev)
 	iounmap(hdmi_dev->regs);
 	hdmi_resources_cleanup(hdmi_dev);
 	kfree(hdmi_dev);
-	dev_info(dev, "remove sucessful\n");
+	dev_info(dev, "remove successful\n");
 
 	return 0;
 }
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c
index 0064309..a2c0c25 100644
--- a/drivers/media/video/s5p-tv/mixer_drv.c
+++ b/drivers/media/video/s5p-tv/mixer_drv.c
@@ -444,7 +444,7 @@ static int __devexit mxr_remove(struct platform_device *pdev)
 
 	kfree(mdev);
 
-	dev_info(dev, "remove sucessful\n");
+	dev_info(dev, "remove successful\n");
 	return 0;
 }
 
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
index 7884bae..f7ca5cc 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -58,7 +58,6 @@ static struct v4l2_subdev *find_and_register_subdev(
 	}
 
 done:
-	put_driver(drv);
 	return sd;
 }
 
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index 2fd38a0..a9ed686 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -791,11 +791,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
-static int vidioc_log_status(struct file *file, void *priv)
-{
-	return 0;
-}
-
 static int fill_queryctrl(struct saa7164_encoder_params *params,
 	struct v4l2_queryctrl *c)
 {
@@ -1347,7 +1342,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
 	.vidioc_g_ext_ctrls	 = vidioc_g_ext_ctrls,
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
-	.vidioc_log_status	 = vidioc_log_status,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
 	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index e2e0341..273cf80 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -730,11 +730,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 	return 0;
 }
 
-static int vidioc_log_status(struct file *file, void *priv)
-{
-	return 0;
-}
-
 static int fill_queryctrl(struct saa7164_vbi_params *params,
 	struct v4l2_queryctrl *c)
 {
@@ -1256,7 +1251,6 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
 	.vidioc_g_ext_ctrls	 = vidioc_g_ext_ctrls,
 	.vidioc_s_ext_ctrls	 = vidioc_s_ext_ctrls,
 	.vidioc_try_ext_ctrls	 = vidioc_try_ext_ctrls,
-	.vidioc_log_status	 = vidioc_log_status,
 	.vidioc_queryctrl	 = vidioc_queryctrl,
 #if 0
 	.vidioc_g_chip_ident	 = saa7164_g_chip_ident,
diff --git a/drivers/media/video/tm6000/tm6000-input.c b/drivers/media/video/tm6000/tm6000-input.c
index 7844607..859eb90 100644
--- a/drivers/media/video/tm6000/tm6000-input.c
+++ b/drivers/media/video/tm6000/tm6000-input.c
@@ -481,8 +481,6 @@ int tm6000_ir_fini(struct tm6000_core *dev)
 
 	dprintk(2, "%s\n",__func__);
 
-	rc_unregister_device(ir->rc);
-
 	if (!ir->polling)
 		__tm6000_ir_int_stop(ir->rc);
 
@@ -492,6 +490,7 @@ int tm6000_ir_fini(struct tm6000_core *dev)
 	tm6000_flash_led(dev, 0);
 	ir->pwled = 0;
 
+	rc_unregister_device(ir->rc);
 
 	kfree(ir);
 	dev->ir = NULL;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 4059ea1..89a123d 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -380,6 +380,21 @@ static void set_type(struct i2c_client *c, unsigned int type,
 		tune_now = 0;
 		break;
 	}
+	case TUNER_XC5000C:
+	{
+		struct xc5000_config xc5000c_cfg = {
+			.i2c_address = t->i2c->addr,
+			/* if_khz will be set at dvb_attach() */
+			.if_khz	  = 0,
+			.chip_id  = XC5000C,
+		};
+
+		if (!dvb_attach(xc5000_attach,
+				&t->fe, t->i2c->adapter, &xc5000c_cfg))
+			goto attach_failed;
+		tune_now = 0;
+		break;
+	}
 	case TUNER_NXP_TDA18271:
 	{
 		struct tda18271_config cfg = {
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 6103d1b..bcde81c 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -286,7 +286,7 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,                 "MaxLinear 301"},
 	{ TUNER_ABSENT,                 "Mirics MSi001"},
 	{ TUNER_ABSENT,                 "MaxLinear MxL241SF"},
-	{ TUNER_ABSENT,                 "Xceive XC5000C"},
+	{ TUNER_XC5000C,                "Xceive XC5000C"},
 	{ TUNER_ABSENT,                 "Montage M68TS2020"},
 };
 
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index af4419e..e6f67aa 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -1005,6 +1005,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
 	case VIDIOC_G_ENC_INDEX:
 	case VIDIOC_ENCODER_CMD:
 	case VIDIOC_TRY_ENCODER_CMD:
+	case VIDIOC_DECODER_CMD:
+	case VIDIOC_TRY_DECODER_CMD:
 	case VIDIOC_DBG_S_REGISTER:
 	case VIDIOC_DBG_G_REGISTER:
 	case VIDIOC_DBG_G_CHIP_IDENT:
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index cccd42b..9091172 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -175,6 +175,15 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"16-bit CRC",
 		NULL
 	};
+	static const char * const mpeg_audio_dec_playback[] = {
+		"Auto",
+		"Stereo",
+		"Left",
+		"Right",
+		"Mono",
+		"Swapped Stereo",
+		NULL
+	};
 	static const char * const mpeg_video_encoding[] = {
 		"MPEG-1",
 		"MPEG-2",
@@ -374,6 +383,9 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return mpeg_audio_emphasis;
 	case V4L2_CID_MPEG_AUDIO_CRC:
 		return mpeg_audio_crc;
+	case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
+	case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
+		return mpeg_audio_dec_playback;
 	case V4L2_CID_MPEG_VIDEO_ENCODING:
 		return mpeg_video_encoding;
 	case V4L2_CID_MPEG_VIDEO_ASPECT:
@@ -492,6 +504,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_MPEG_AUDIO_MUTE:		return "Audio Mute";
 	case V4L2_CID_MPEG_AUDIO_AAC_BITRATE:	return "Audio AAC Bitrate";
 	case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:	return "Audio AC-3 Bitrate";
+	case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:	return "Audio Playback";
+	case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK: return "Audio Multilingual Playback";
 	case V4L2_CID_MPEG_VIDEO_ENCODING:	return "Video Encoding";
 	case V4L2_CID_MPEG_VIDEO_ASPECT:	return "Video Aspect";
 	case V4L2_CID_MPEG_VIDEO_B_FRAMES:	return "Video B Frames";
@@ -546,6 +560,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:		return "Number of MBs in a Slice";
 	case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:		return "Slice Partitioning Method";
 	case V4L2_CID_MPEG_VIDEO_VBV_SIZE:			return "VBV Buffer Size";
+	case V4L2_CID_MPEG_VIDEO_DEC_PTS:			return "Video Decoder PTS";
+	case V4L2_CID_MPEG_VIDEO_DEC_FRAME:			return "Video Decoder Frame Count";
 
 	/* CAMERA controls */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -674,6 +690,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
 	case V4L2_CID_MPEG_AUDIO_EMPHASIS:
 	case V4L2_CID_MPEG_AUDIO_CRC:
+	case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK:
+	case V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK:
 	case V4L2_CID_MPEG_VIDEO_ENCODING:
 	case V4L2_CID_MPEG_VIDEO_ASPECT:
 	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
@@ -724,6 +742,11 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 		*type = V4L2_CTRL_TYPE_INTEGER;
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
 		break;
+	case V4L2_CID_MPEG_VIDEO_DEC_FRAME:
+	case V4L2_CID_MPEG_VIDEO_DEC_PTS:
+		*type = V4L2_CTRL_TYPE_INTEGER64;
+		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE;
+		break;
 	default:
 		*type = V4L2_CTRL_TYPE_INTEGER;
 		break;
@@ -2359,3 +2382,35 @@ void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl,
 	v4l2_ctrl_unlock(ctrl);
 }
 EXPORT_SYMBOL(v4l2_ctrl_del_event);
+
+int v4l2_ctrl_log_status(struct file *file, void *fh)
+{
+	struct video_device *vfd = video_devdata(file);
+	struct v4l2_fh *vfh = file->private_data;
+
+	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)
+		v4l2_ctrl_handler_log_status(vfh->ctrl_handler,
+			vfd->v4l2_dev->name);
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_ctrl_log_status);
+
+int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
+				struct v4l2_event_subscription *sub)
+{
+	if (sub->type == V4L2_EVENT_CTRL)
+		return v4l2_event_subscribe(fh, sub, 0);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);
+
+unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct v4l2_fh *fh = file->private_data;
+
+	if (v4l2_event_pending(fh))
+		return POLLPRI;
+	poll_wait(file, &fh->wait, wait);
+	return 0;
+}
+EXPORT_SYMBOL(v4l2_ctrl_poll);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 3f62385..74cab51 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -260,6 +260,8 @@ static const char *v4l2_ioctls[] = {
 	[_IOC_NR(VIDIOC_ENCODER_CMD)] 	   = "VIDIOC_ENCODER_CMD",
 	[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)]  = "VIDIOC_TRY_ENCODER_CMD",
 
+	[_IOC_NR(VIDIOC_DECODER_CMD)]	   = "VIDIOC_DECODER_CMD",
+	[_IOC_NR(VIDIOC_TRY_DECODER_CMD)]  = "VIDIOC_TRY_DECODER_CMD",
 	[_IOC_NR(VIDIOC_DBG_S_REGISTER)]   = "VIDIOC_DBG_S_REGISTER",
 	[_IOC_NR(VIDIOC_DBG_G_REGISTER)]   = "VIDIOC_DBG_G_REGISTER",
 
@@ -540,10 +542,12 @@ static long __video_do_ioctl(struct file *file,
 		if (!ret)
 			dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
 					"version=0x%08x, "
-					"capabilities=0x%08x\n",
+					"capabilities=0x%08x, "
+					"device_caps=0x%08x\n",
 					cap->driver, cap->card, cap->bus_info,
 					cap->version,
-					cap->capabilities);
+					cap->capabilities,
+					cap->device_caps);
 		break;
 	}
 
@@ -1762,6 +1766,32 @@ static long __video_do_ioctl(struct file *file,
 			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
 		break;
 	}
+	case VIDIOC_DECODER_CMD:
+	{
+		struct v4l2_decoder_cmd *p = arg;
+
+		if (!ops->vidioc_decoder_cmd)
+			break;
+		if (ret_prio) {
+			ret = ret_prio;
+			break;
+		}
+		ret = ops->vidioc_decoder_cmd(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
+		break;
+	}
+	case VIDIOC_TRY_DECODER_CMD:
+	{
+		struct v4l2_decoder_cmd *p = arg;
+
+		if (!ops->vidioc_try_decoder_cmd)
+			break;
+		ret = ops->vidioc_try_decoder_cmd(file, fh, p);
+		if (!ret)
+			dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
+		break;
+	}
 	case VIDIOC_G_PARM:
 	{
 		struct v4l2_streamparm *p = arg;
@@ -1909,7 +1939,13 @@ static long __video_do_ioctl(struct file *file,
 	{
 		if (!ops->vidioc_log_status)
 			break;
+		if (vfd->v4l2_dev)
+			pr_info("%s: =================  START STATUS  =================\n",
+				vfd->v4l2_dev->name);
 		ret = ops->vidioc_log_status(file, fh);
+		if (vfd->v4l2_dev)
+			pr_info("%s: ==================  END STATUS  ==================\n",
+				vfd->v4l2_dev->name);
 		break;
 	}
 #ifdef CONFIG_VIDEO_ADV_DEBUG
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 41d118e..6fe88e9 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -194,8 +194,16 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	}
 #endif
 
-	case VIDIOC_LOG_STATUS:
-		return v4l2_subdev_call(sd, core, log_status);
+	case VIDIOC_LOG_STATUS: {
+		int ret;
+
+		pr_info("%s: =================  START STATUS  =================\n",
+			sd->name);
+		ret = v4l2_subdev_call(sd, core, log_status);
+		pr_info("%s: ==================  END STATUS  ==================\n",
+			sd->name);
+		return ret;
+	}
 
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	case VIDIOC_SUBDEV_G_FMT: {
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 7d754fb..5e8b071 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -819,8 +819,9 @@ static int vidioc_querycap(struct file *file, void  *priv,
 	strcpy(cap->driver, "vivi");
 	strcpy(cap->card, "vivi");
 	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
+	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
 			    V4L2_CAP_READWRITE;
+	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
 	return 0;
 }
 
@@ -958,14 +959,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 	return vb2_streamoff(&dev->vb_vidq, i);
 }
 
-static int vidioc_log_status(struct file *file, void *priv)
-{
-	struct vivi_dev *dev = video_drvdata(file);
-
-	v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name);
-	return 0;
-}
-
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
 {
 	return 0;
@@ -1008,17 +1001,6 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 	return 0;
 }
 
-static int vidioc_subscribe_event(struct v4l2_fh *fh,
-				struct v4l2_event_subscription *sub)
-{
-	switch (sub->type) {
-	case V4L2_EVENT_CTRL:
-		return v4l2_event_subscribe(fh, sub, 0);
-	default:
-		return -EINVAL;
-	}
-}
-
 /* --- controls ---------------------------------------------- */
 
 static int vivi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
@@ -1209,8 +1191,8 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
 	.vidioc_s_input       = vidioc_s_input,
 	.vidioc_streamon      = vidioc_streamon,
 	.vidioc_streamoff     = vidioc_streamoff,
-	.vidioc_log_status    = vidioc_log_status,
-	.vidioc_subscribe_event = vidioc_subscribe_event,
+	.vidioc_log_status    = v4l2_ctrl_log_status,
+	.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
 	.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 };
 
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 5319e9b..c37d375 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -325,7 +325,7 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
 			p_cnt = min(p_cnt, length);
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
+			buf = kmap_atomic(pg) + p_off;
 		} else {
 			buf = host->req->data + host->block_pos;
 			p_cnt = host->req->data_len - host->block_pos;
@@ -341,7 +341,7 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host)
 				 : jmb38x_ms_read_reg_data(host, buf, p_cnt);
 
 		if (host->req->long_data) {
-			kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
+			kunmap_atomic(buf - p_off);
 			local_irq_restore(flags);
 		}
 
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 6902b83..7bafa72 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -210,7 +210,7 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
 			p_cnt = min(p_cnt, length);
 
 			local_irq_save(flags);
-			buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off;
+			buf = kmap_atomic(pg) + p_off;
 		} else {
 			buf = host->req->data + host->block_pos;
 			p_cnt = host->req->data_len - host->block_pos;
@@ -221,7 +221,7 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
 			 : tifm_ms_read_data(host, buf, p_cnt);
 
 		if (host->req->long_data) {
-			kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ);
+			kunmap_atomic(buf - p_off);
 			local_irq_restore(flags);
 		}
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f147395..2aeb63b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -143,6 +143,21 @@ config TPS6507X
 	  This driver can also be built as a module.  If so, the module
 	  will be called tps6507x.
 
+config MFD_TPS65217
+	tristate "TPS65217 Power Management / White LED chips"
+	depends on I2C
+	select MFD_CORE
+	select REGMAP_I2C
+	help
+	  If you say yes here you get support for the TPS65217 series of
+	  Power Management / White LED chips.
+	  These include voltage regulators, lithium ion/polymer battery
+	  charger, wled and other features that are often used in portable
+	  devices.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tps65217.
+
 config MFD_TPS6586X
 	bool "TPS6586x Power Management chips"
 	depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
@@ -251,10 +266,17 @@ config TWL6030_PWM
 	  This is used to control charging LED brightness.
 
 config TWL6040_CORE
-	bool
-	depends on TWL4030_CORE && GENERIC_HARDIRQS
+	bool "Support for TWL6040 audio codec"
+	depends on I2C=y && GENERIC_HARDIRQS
 	select MFD_CORE
+	select REGMAP_I2C
 	default n
+	help
+	  Say yes here if you want support for Texas Instruments TWL6040 audio
+	  codec.
+	  This driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device (audio, vibra).
 
 config MFD_STMPE
 	bool "Support STMicroelectronics STMPE"
@@ -847,8 +869,9 @@ config MCP_SA11X0
 
 # Chip drivers
 config MCP_UCB1200
-	tristate "Support for UCB1200 / UCB1300"
-	depends on MCP
+	bool "Support for UCB1200 / UCB1300"
+	depends on MCP_SA11X0
+	select MCP
 
 config MCP_UCB1200_TS
 	tristate "Touchscreen interface support"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b953bab..27430d3 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_MFD_WM8994)	+= wm8994-core.o wm8994-irq.o wm8994-regmap.o
 obj-$(CONFIG_TPS6105X)		+= tps6105x.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
+obj-$(CONFIG_MFD_TPS65217)	+= tps65217.o
 obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o tps65910-irq.o
 tps65912-objs                   := tps65912-core.o tps65912-irq.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c
index bd56a76..54d0fe4 100644
--- a/drivers/mfd/ab5500-core.c
+++ b/drivers/mfd/ab5500-core.c
@@ -28,7 +28,6 @@
 #include <linux/bitops.h>
 #include <linux/spinlock.h>
 #include <linux/mfd/core.h>
-#include <linux/version.h>
 #include <linux/mfd/db5500-prcmu.h>
 
 #include "ab5500-core.h"
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 53e2a80..15a18fe 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -32,6 +32,7 @@
 #define AB8500_IT_SOURCE6_REG		0x05
 #define AB8500_IT_SOURCE7_REG		0x06
 #define AB8500_IT_SOURCE8_REG		0x07
+#define AB9540_IT_SOURCE13_REG		0x0C
 #define AB8500_IT_SOURCE19_REG		0x12
 #define AB8500_IT_SOURCE20_REG		0x13
 #define AB8500_IT_SOURCE21_REG		0x14
@@ -53,6 +54,7 @@
 #define AB8500_IT_LATCH9_REG		0x28
 #define AB8500_IT_LATCH10_REG		0x29
 #define AB8500_IT_LATCH12_REG		0x2B
+#define AB9540_IT_LATCH13_REG		0x2C
 #define AB8500_IT_LATCH19_REG		0x32
 #define AB8500_IT_LATCH20_REG		0x33
 #define AB8500_IT_LATCH21_REG		0x34
@@ -90,21 +92,39 @@
 #define AB8500_IT_MASK24_REG		0x57
 
 #define AB8500_REV_REG			0x80
+#define AB8500_IC_NAME_REG		0x82
 #define AB8500_SWITCH_OFF_STATUS	0x00
 
 #define AB8500_TURN_ON_STATUS		0x00
 
+#define AB9540_MODEM_CTRL2_REG			0x23
+#define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT	BIT(2)
+
 /*
  * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
- * numbers are indexed into this array with (num / 8).
+ * numbers are indexed into this array with (num / 8). The interupts are
+ * defined in linux/mfd/ab8500.h
  *
  * This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at
  * offset 0.
  */
+/* AB8500 support */
 static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
 	0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21,
 };
 
+/* AB9540 support */
+static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = {
+	0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24,
+};
+
+static const char ab8500_version_str[][7] = {
+	[AB8500_VERSION_AB8500] = "AB8500",
+	[AB8500_VERSION_AB8505] = "AB8505",
+	[AB8500_VERSION_AB9540] = "AB9540",
+	[AB8500_VERSION_AB8540] = "AB8540",
+};
+
 static int ab8500_get_chip_id(struct device *dev)
 {
 	struct ab8500 *ab8500;
@@ -248,7 +268,7 @@ static void ab8500_irq_sync_unlock(struct irq_data *data)
 	struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
 	int i;
 
-	for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
+	for (i = 0; i < ab8500->mask_size; i++) {
 		u8 old = ab8500->oldmask[i];
 		u8 new = ab8500->mask[i];
 		int reg;
@@ -256,14 +276,17 @@ static void ab8500_irq_sync_unlock(struct irq_data *data)
 		if (new == old)
 			continue;
 
-		/* Interrupt register 12 doesn't exist prior to version 2.0 */
-		if (ab8500_irq_regoffset[i] == 11 &&
-			ab8500->chip_id < AB8500_CUT2P0)
+		/*
+		 * Interrupt register 12 doesn't exist prior to AB8500 version
+		 * 2.0
+		 */
+		if (ab8500->irq_reg_offset[i] == 11 &&
+			is_ab8500_1p1_or_earlier(ab8500))
 			continue;
 
 		ab8500->oldmask[i] = new;
 
-		reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i];
+		reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i];
 		set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new);
 	}
 
@@ -306,13 +329,16 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
 
 	dev_vdbg(ab8500->dev, "interrupt\n");
 
-	for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
-		int regoffset = ab8500_irq_regoffset[i];
+	for (i = 0; i < ab8500->mask_size; i++) {
+		int regoffset = ab8500->irq_reg_offset[i];
 		int status;
 		u8 value;
 
-		/* Interrupt register 12 doesn't exist prior to version 2.0 */
-		if (regoffset == 11 && ab8500->chip_id < AB8500_CUT2P0)
+		/*
+		 * Interrupt register 12 doesn't exist prior to AB8500 version
+		 * 2.0
+		 */
+		if (regoffset == 11 && is_ab8500_1p1_or_earlier(ab8500))
 			continue;
 
 		status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
@@ -336,8 +362,14 @@ static int ab8500_irq_init(struct ab8500 *ab8500)
 {
 	int base = ab8500->irq_base;
 	int irq;
+	int num_irqs;
+
+	if (is_ab9540(ab8500))
+		num_irqs = AB9540_NR_IRQS;
+	else
+		num_irqs = AB8500_NR_IRQS;
 
-	for (irq = base; irq < base + AB8500_NR_IRQS; irq++) {
+	for (irq = base; irq < base + num_irqs; irq++) {
 		irq_set_chip_data(irq, ab8500);
 		irq_set_chip_and_handler(irq, &ab8500_irq_chip,
 					 handle_simple_irq);
@@ -356,8 +388,14 @@ static void ab8500_irq_remove(struct ab8500 *ab8500)
 {
 	int base = ab8500->irq_base;
 	int irq;
+	int num_irqs;
 
-	for (irq = base; irq < base + AB8500_NR_IRQS; irq++) {
+	if (is_ab9540(ab8500))
+		num_irqs = AB9540_NR_IRQS;
+	else
+		num_irqs = AB8500_NR_IRQS;
+
+	for (irq = base; irq < base + num_irqs; irq++) {
 #ifdef CONFIG_ARM
 		set_irq_flags(irq, 0);
 #endif
@@ -366,6 +404,7 @@ static void ab8500_irq_remove(struct ab8500 *ab8500)
 	}
 }
 
+/* AB8500 GPIO Resources */
 static struct resource __devinitdata ab8500_gpio_resources[] = {
 	{
 		.name	= "GPIO_INT6",
@@ -375,6 +414,28 @@ static struct resource __devinitdata ab8500_gpio_resources[] = {
 	}
 };
 
+/* AB9540 GPIO Resources */
+static struct resource __devinitdata ab9540_gpio_resources[] = {
+	{
+		.name	= "GPIO_INT6",
+		.start	= AB8500_INT_GPIO6R,
+		.end	= AB8500_INT_GPIO41F,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "GPIO_INT14",
+		.start	= AB9540_INT_GPIO50R,
+		.end	= AB9540_INT_GPIO54R,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "GPIO_INT15",
+		.start	= AB9540_INT_GPIO50F,
+		.end	= AB9540_INT_GPIO54F,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
 static struct resource __devinitdata ab8500_gpadc_resources[] = {
 	{
 		.name	= "HW_CONV_END",
@@ -691,7 +752,7 @@ static struct resource __devinitdata ab8500_temp_resources[] = {
 	},
 };
 
-static struct mfd_cell __devinitdata ab8500_devs[] = {
+static struct mfd_cell __devinitdata abx500_common_devs[] = {
 #ifdef CONFIG_DEBUG_FS
 	{
 		.name = "ab8500-debug",
@@ -706,11 +767,6 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
 		.name = "ab8500-regulator",
 	},
 	{
-		.name = "ab8500-gpio",
-		.num_resources = ARRAY_SIZE(ab8500_gpio_resources),
-		.resources = ab8500_gpio_resources,
-	},
-	{
 		.name = "ab8500-gpadc",
 		.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
 		.resources = ab8500_gpadc_resources,
@@ -748,11 +804,7 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
 	{
 		.name = "ab8500-codec",
 	},
-	{
-		.name = "ab8500-usb",
-		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
-		.resources = ab8500_usb_resources,
-	},
+
 	{
 		.name = "ab8500-poweron-key",
 		.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
@@ -781,6 +833,32 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
 	},
 };
 
+static struct mfd_cell __devinitdata ab8500_devs[] = {
+	{
+		.name = "ab8500-gpio",
+		.num_resources = ARRAY_SIZE(ab8500_gpio_resources),
+		.resources = ab8500_gpio_resources,
+	},
+	{
+		.name = "ab8500-usb",
+		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
+		.resources = ab8500_usb_resources,
+	},
+};
+
+static struct mfd_cell __devinitdata ab9540_devs[] = {
+	{
+		.name = "ab8500-gpio",
+		.num_resources = ARRAY_SIZE(ab9540_gpio_resources),
+		.resources = ab9540_gpio_resources,
+	},
+	{
+		.name = "ab9540-usb",
+		.num_resources = ARRAY_SIZE(ab8500_usb_resources),
+		.resources = ab8500_usb_resources,
+	},
+};
+
 static ssize_t show_chip_id(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
@@ -842,9 +920,64 @@ static ssize_t show_turn_on_status(struct device *dev,
 	return sprintf(buf, "%#x\n", value);
 }
 
+static ssize_t show_ab9540_dbbrstn(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct ab8500 *ab8500;
+	int ret;
+	u8 value;
+
+	ab8500 = dev_get_drvdata(dev);
+
+	ret = get_register_interruptible(ab8500, AB8500_REGU_CTRL2,
+		AB9540_MODEM_CTRL2_REG, &value);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n",
+			(value & AB9540_MODEM_CTRL2_SWDBBRSTN_BIT) ? 1 : 0);
+}
+
+static ssize_t store_ab9540_dbbrstn(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct ab8500 *ab8500;
+	int ret = count;
+	int err;
+	u8 bitvalues;
+
+	ab8500 = dev_get_drvdata(dev);
+
+	if (count > 0) {
+		switch (buf[0]) {
+		case '0':
+			bitvalues = 0;
+			break;
+		case '1':
+			bitvalues = AB9540_MODEM_CTRL2_SWDBBRSTN_BIT;
+			break;
+		default:
+			goto exit;
+		}
+
+		err = mask_and_set_register_interruptible(ab8500,
+			AB8500_REGU_CTRL2, AB9540_MODEM_CTRL2_REG,
+			AB9540_MODEM_CTRL2_SWDBBRSTN_BIT, bitvalues);
+		if (err)
+			dev_info(ab8500->dev,
+				"Failed to set DBBRSTN %c, err %#x\n",
+				buf[0], err);
+	}
+
+exit:
+	return ret;
+}
+
 static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
 static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
 static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL);
+static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR,
+			show_ab9540_dbbrstn, store_ab9540_dbbrstn);
 
 static struct attribute *ab8500_sysfs_entries[] = {
 	&dev_attr_chip_id.attr,
@@ -853,11 +986,23 @@ static struct attribute *ab8500_sysfs_entries[] = {
 	NULL,
 };
 
+static struct attribute *ab9540_sysfs_entries[] = {
+	&dev_attr_chip_id.attr,
+	&dev_attr_switch_off_status.attr,
+	&dev_attr_turn_on_status.attr,
+	&dev_attr_dbbrstn.attr,
+	NULL,
+};
+
 static struct attribute_group ab8500_attr_group = {
 	.attrs	= ab8500_sysfs_entries,
 };
 
-int __devinit ab8500_init(struct ab8500 *ab8500)
+static struct attribute_group ab9540_attr_group = {
+	.attrs	= ab9540_sysfs_entries,
+};
+
+int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version)
 {
 	struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev);
 	int ret;
@@ -870,25 +1015,45 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
 	mutex_init(&ab8500->lock);
 	mutex_init(&ab8500->irq_lock);
 
+	if (version != AB8500_VERSION_UNDEFINED)
+		ab8500->version = version;
+	else {
+		ret = get_register_interruptible(ab8500, AB8500_MISC,
+			AB8500_IC_NAME_REG, &value);
+		if (ret < 0)
+			return ret;
+
+		ab8500->version = value;
+	}
+
 	ret = get_register_interruptible(ab8500, AB8500_MISC,
 		AB8500_REV_REG, &value);
 	if (ret < 0)
 		return ret;
 
-	switch (value) {
-	case AB8500_CUT1P0:
-	case AB8500_CUT1P1:
-	case AB8500_CUT2P0:
-	case AB8500_CUT3P0:
-	case AB8500_CUT3P3:
-		dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
-		break;
-	default:
-		dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
-		return -EINVAL;
-	}
 	ab8500->chip_id = value;
 
+	dev_info(ab8500->dev, "detected chip, %s rev. %1x.%1x\n",
+			ab8500_version_str[ab8500->version],
+			ab8500->chip_id >> 4,
+			ab8500->chip_id & 0x0F);
+
+	/* Configure AB8500 or AB9540 IRQ */
+	if (is_ab9540(ab8500)) {
+		ab8500->mask_size = AB9540_NUM_IRQ_REGS;
+		ab8500->irq_reg_offset = ab9540_irq_regoffset;
+	} else {
+		ab8500->mask_size = AB8500_NUM_IRQ_REGS;
+		ab8500->irq_reg_offset = ab8500_irq_regoffset;
+	}
+	ab8500->mask = kzalloc(ab8500->mask_size, GFP_KERNEL);
+	if (!ab8500->mask)
+		return -ENOMEM;
+	ab8500->oldmask = kzalloc(ab8500->mask_size, GFP_KERNEL);
+	if (!ab8500->oldmask) {
+		ret = -ENOMEM;
+		goto out_freemask;
+	}
 	/*
 	 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
 	 * 0x01 Swoff bit programming
@@ -911,30 +1076,33 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
 		plat->init(ab8500);
 
 	/* Clear and mask all interrupts */
-	for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
-		/* Interrupt register 12 doesn't exist prior to version 2.0 */
-		if (ab8500_irq_regoffset[i] == 11 &&
-			ab8500->chip_id < AB8500_CUT2P0)
+	for (i = 0; i < ab8500->mask_size; i++) {
+		/*
+		 * Interrupt register 12 doesn't exist prior to AB8500 version
+		 * 2.0
+		 */
+		if (ab8500->irq_reg_offset[i] == 11 &&
+				is_ab8500_1p1_or_earlier(ab8500))
 			continue;
 
 		get_register_interruptible(ab8500, AB8500_INTERRUPT,
-			AB8500_IT_LATCH1_REG + ab8500_irq_regoffset[i],
+			AB8500_IT_LATCH1_REG + ab8500->irq_reg_offset[i],
 			&value);
 		set_register_interruptible(ab8500, AB8500_INTERRUPT,
-			AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i], 0xff);
+			AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i], 0xff);
 	}
 
 	ret = abx500_register_ops(ab8500->dev, &ab8500_ops);
 	if (ret)
-		return ret;
+		goto out_freeoldmask;
 
-	for (i = 0; i < AB8500_NUM_IRQ_REGS; i++)
+	for (i = 0; i < ab8500->mask_size; i++)
 		ab8500->mask[i] = ab8500->oldmask[i] = 0xff;
 
 	if (ab8500->irq_base) {
 		ret = ab8500_irq_init(ab8500);
 		if (ret)
-			return ret;
+			goto out_freeoldmask;
 
 		ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq,
 					   IRQF_ONESHOT | IRQF_NO_SUSPEND,
@@ -943,35 +1111,62 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
 			goto out_removeirq;
 	}
 
-	ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
-			      ARRAY_SIZE(ab8500_devs), NULL,
+	ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs,
+			      ARRAY_SIZE(abx500_common_devs), NULL,
+			      ab8500->irq_base);
+
+	if (ret)
+		goto out_freeirq;
+
+	if (is_ab9540(ab8500))
+		ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
+			      ARRAY_SIZE(ab9540_devs), NULL,
+			      ab8500->irq_base);
+	else
+		ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
+			      ARRAY_SIZE(ab9540_devs), NULL,
 			      ab8500->irq_base);
 	if (ret)
 		goto out_freeirq;
 
-	ret = sysfs_create_group(&ab8500->dev->kobj, &ab8500_attr_group);
+	if (is_ab9540(ab8500))
+		ret = sysfs_create_group(&ab8500->dev->kobj,
+					&ab9540_attr_group);
+	else
+		ret = sysfs_create_group(&ab8500->dev->kobj,
+					&ab8500_attr_group);
 	if (ret)
 		dev_err(ab8500->dev, "error creating sysfs entries\n");
-
-	return ret;
+	else
+		return ret;
 
 out_freeirq:
-	if (ab8500->irq_base) {
+	if (ab8500->irq_base)
 		free_irq(ab8500->irq, ab8500);
 out_removeirq:
+	if (ab8500->irq_base)
 		ab8500_irq_remove(ab8500);
-	}
+out_freeoldmask:
+	kfree(ab8500->oldmask);
+out_freemask:
+	kfree(ab8500->mask);
+
 	return ret;
 }
 
 int __devexit ab8500_exit(struct ab8500 *ab8500)
 {
-	sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group);
+	if (is_ab9540(ab8500))
+		sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group);
+	else
+		sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group);
 	mfd_remove_devices(ab8500->dev);
 	if (ab8500->irq_base) {
 		free_irq(ab8500->irq, ab8500);
 		ab8500_irq_remove(ab8500);
 	}
+	kfree(ab8500->oldmask);
+	kfree(ab8500->mask);
 
 	return 0;
 }
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c
index 087fecd..70a16ae 100644
--- a/drivers/mfd/ab8500-i2c.c
+++ b/drivers/mfd/ab8500-i2c.c
@@ -38,6 +38,7 @@ static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
 
 static int __devinit ab8500_i2c_probe(struct platform_device *plf)
 {
+	const struct platform_device_id *platid = platform_get_device_id(plf);
 	struct ab8500 *ab8500;
 	struct resource *resource;
 	int ret;
@@ -61,10 +62,11 @@ static int __devinit ab8500_i2c_probe(struct platform_device *plf)
 
 	platform_set_drvdata(plf, ab8500);
 
-	ret = ab8500_init(ab8500);
+	ret = ab8500_init(ab8500, platid->driver_data);
 	if (ret)
 		kfree(ab8500);
 
+
 	return ret;
 }
 
@@ -78,13 +80,22 @@ static int __devexit ab8500_i2c_remove(struct platform_device *plf)
 	return 0;
 }
 
+static const struct platform_device_id ab8500_id[] = {
+	{ "ab8500-i2c", AB8500_VERSION_AB8500 },
+	{ "ab8505-i2c", AB8500_VERSION_AB8505 },
+	{ "ab9540-i2c", AB8500_VERSION_AB9540 },
+	{ "ab8540-i2c", AB8500_VERSION_AB8540 },
+	{ }
+};
+
 static struct platform_driver ab8500_i2c_driver = {
 	.driver = {
 		.name = "ab8500-i2c",
 		.owner = THIS_MODULE,
 	},
 	.probe	= ab8500_i2c_probe,
-	.remove	= __devexit_p(ab8500_i2c_remove)
+	.remove	= __devexit_p(ab8500_i2c_remove),
+	.id_table = ab8500_id,
 };
 
 static int __init ab8500_i2c_init(void)
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index b85bbd7..1895cf9 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -525,6 +525,11 @@ static void asic3_gpio_set(struct gpio_chip *chip,
 	return;
 }
 
+static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO;
+}
+
 static __init int asic3_gpio_probe(struct platform_device *pdev,
 				   u16 *gpio_config, int num)
 {
@@ -976,6 +981,7 @@ static int __init asic3_probe(struct platform_device *pdev)
 	asic->gpio.set = asic3_gpio_set;
 	asic->gpio.direction_input = asic3_gpio_direction_input;
 	asic->gpio.direction_output = asic3_gpio_direction_output;
+	asic->gpio.to_irq = asic3_gpio_to_irq;
 
 	ret = asic3_gpio_probe(pdev,
 			       pdata->gpio_config,
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c
index 44b97c7..fdc2c6a 100644
--- a/drivers/mfd/da9052-i2c.c
+++ b/drivers/mfd/da9052-i2c.c
@@ -74,14 +74,16 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client,
 
 	ret = da9052_i2c_enable_multiwrite(da9052);
 	if (ret < 0)
-		goto err;
+		goto err_regmap;
 
 	ret = da9052_device_init(da9052, id->driver_data);
 	if (ret != 0)
-		goto err;
+		goto err_regmap;
 
 	return 0;
 
+err_regmap:
+	regmap_exit(da9052->regmap);
 err:
 	kfree(da9052);
 	return ret;
@@ -92,6 +94,7 @@ static int da9052_i2c_remove(struct i2c_client *client)
 	struct da9052 *da9052 = i2c_get_clientdata(client);
 
 	da9052_device_exit(da9052);
+	regmap_exit(da9052->regmap);
 	kfree(da9052);
 
 	return 0;
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c
index cdbc7ca..6faf149 100644
--- a/drivers/mfd/da9052-spi.c
+++ b/drivers/mfd/da9052-spi.c
@@ -21,7 +21,7 @@
 
 #include <linux/mfd/da9052/da9052.h>
 
-static int da9052_spi_probe(struct spi_device *spi)
+static int __devinit da9052_spi_probe(struct spi_device *spi)
 {
 	int ret;
 	const struct spi_device_id *id = spi_get_device_id(spi);
@@ -52,20 +52,23 @@ static int da9052_spi_probe(struct spi_device *spi)
 
 	ret = da9052_device_init(da9052, id->driver_data);
 	if (ret != 0)
-		goto err;
+		goto err_regmap;
 
 	return 0;
 
+err_regmap:
+	regmap_exit(da9052->regmap);
 err:
 	kfree(da9052);
 	return ret;
 }
 
-static int da9052_spi_remove(struct spi_device *spi)
+static int __devexit da9052_spi_remove(struct spi_device *spi)
 {
 	struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
 
 	da9052_device_exit(da9052);
+	regmap_exit(da9052->regmap);
 	kfree(da9052);
 
 	return 0;
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index af8e0ef..128b5f4 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -39,11 +39,6 @@
 /* Offset for the firmware version within the TCPM */
 #define PRCMU_FW_VERSION_OFFSET 0xA4
 
-/* PRCMU project numbers, defined by PRCMU FW */
-#define PRCMU_PROJECT_ID_8500V1_0 1
-#define PRCMU_PROJECT_ID_8500V2_0 2
-#define PRCMU_PROJECT_ID_8400V2_0 3
-
 /* Index of different voltages to be used when accessing AVSData */
 #define PRCM_AVS_BASE		0x2FC
 #define PRCM_AVS_VBB_RET	(PRCM_AVS_BASE + 0x0)
@@ -137,6 +132,8 @@
 #define PRCM_REQ_MB1_ARM_OPP			(PRCM_REQ_MB1 + 0x0)
 #define PRCM_REQ_MB1_APE_OPP			(PRCM_REQ_MB1 + 0x1)
 #define PRCM_REQ_MB1_PLL_ON_OFF			(PRCM_REQ_MB1 + 0x4)
+#define PLL_SOC0_OFF	0x1
+#define PLL_SOC0_ON	0x2
 #define PLL_SOC1_OFF	0x4
 #define PLL_SOC1_ON	0x8
 
@@ -266,6 +263,11 @@
 #define WAKEUP_BIT_GPIO7 BIT(30)
 #define WAKEUP_BIT_GPIO8 BIT(31)
 
+static struct {
+	bool valid;
+	struct prcmu_fw_version version;
+} fw_info;
+
 /*
  * This vector maps irq numbers to the bits in the bit field used in
  * communication with the PRCMU firmware.
@@ -341,11 +343,13 @@ static struct {
  * mb1_transfer - state needed for mailbox 1 communication.
  * @lock:	The transaction lock.
  * @work:	The transaction completion structure.
+ * @ape_opp:	The current APE OPP.
  * @ack:	Reply ("acknowledge") data.
  */
 static struct {
 	struct mutex lock;
 	struct completion work;
+	u8 ape_opp;
 	struct {
 		u8 header;
 		u8 arm_opp;
@@ -413,50 +417,102 @@ static struct {
 static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
 
 /* Spinlocks */
+static DEFINE_SPINLOCK(prcmu_lock);
 static DEFINE_SPINLOCK(clkout_lock);
-static DEFINE_SPINLOCK(gpiocr_lock);
 
 /* Global var to runtime determine TCDM base for v2 or v1 */
 static __iomem void *tcdm_base;
 
 struct clk_mgt {
-	unsigned int offset;
+	void __iomem *reg;
 	u32 pllsw;
+	int branch;
+	bool clk38div;
+};
+
+enum {
+	PLL_RAW,
+	PLL_FIX,
+	PLL_DIV
 };
 
 static DEFINE_SPINLOCK(clk_mgt_lock);
 
-#define CLK_MGT_ENTRY(_name)[PRCMU_##_name] = { (PRCM_##_name##_MGT_OFF), 0 }
+#define CLK_MGT_ENTRY(_name, _branch, _clk38div)[PRCMU_##_name] = \
+	{ (PRCM_##_name##_MGT), 0 , _branch, _clk38div}
 struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
-	CLK_MGT_ENTRY(SGACLK),
-	CLK_MGT_ENTRY(UARTCLK),
-	CLK_MGT_ENTRY(MSP02CLK),
-	CLK_MGT_ENTRY(MSP1CLK),
-	CLK_MGT_ENTRY(I2CCLK),
-	CLK_MGT_ENTRY(SDMMCCLK),
-	CLK_MGT_ENTRY(SLIMCLK),
-	CLK_MGT_ENTRY(PER1CLK),
-	CLK_MGT_ENTRY(PER2CLK),
-	CLK_MGT_ENTRY(PER3CLK),
-	CLK_MGT_ENTRY(PER5CLK),
-	CLK_MGT_ENTRY(PER6CLK),
-	CLK_MGT_ENTRY(PER7CLK),
-	CLK_MGT_ENTRY(LCDCLK),
-	CLK_MGT_ENTRY(BMLCLK),
-	CLK_MGT_ENTRY(HSITXCLK),
-	CLK_MGT_ENTRY(HSIRXCLK),
-	CLK_MGT_ENTRY(HDMICLK),
-	CLK_MGT_ENTRY(APEATCLK),
-	CLK_MGT_ENTRY(APETRACECLK),
-	CLK_MGT_ENTRY(MCDECLK),
-	CLK_MGT_ENTRY(IPI2CCLK),
-	CLK_MGT_ENTRY(DSIALTCLK),
-	CLK_MGT_ENTRY(DMACLK),
-	CLK_MGT_ENTRY(B2R2CLK),
-	CLK_MGT_ENTRY(TVCLK),
-	CLK_MGT_ENTRY(SSPCLK),
-	CLK_MGT_ENTRY(RNGCLK),
-	CLK_MGT_ENTRY(UICCCLK),
+	CLK_MGT_ENTRY(SGACLK, PLL_DIV, false),
+	CLK_MGT_ENTRY(UARTCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(MSP02CLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(MSP1CLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(I2CCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(SDMMCCLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(SLIMCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(PER1CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(PER2CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(PER3CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(PER5CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(HDMICLK, PLL_FIX, false),
+	CLK_MGT_ENTRY(APEATCLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(APETRACECLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(MCDECLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(IPI2CCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(DSIALTCLK, PLL_FIX, false),
+	CLK_MGT_ENTRY(DMACLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(B2R2CLK, PLL_DIV, true),
+	CLK_MGT_ENTRY(TVCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(SSPCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(RNGCLK, PLL_FIX, true),
+	CLK_MGT_ENTRY(UICCCLK, PLL_FIX, false),
+};
+
+struct dsiclk {
+	u32 divsel_mask;
+	u32 divsel_shift;
+	u32 divsel;
+};
+
+static struct dsiclk dsiclk[2] = {
+	{
+		.divsel_mask = PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK,
+		.divsel_shift = PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT,
+		.divsel = PRCM_DSI_PLLOUT_SEL_PHI,
+	},
+	{
+		.divsel_mask = PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK,
+		.divsel_shift = PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT,
+		.divsel = PRCM_DSI_PLLOUT_SEL_PHI,
+	}
+};
+
+struct dsiescclk {
+	u32 en;
+	u32 div_mask;
+	u32 div_shift;
+};
+
+static struct dsiescclk dsiescclk[3] = {
+	{
+		.en = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN,
+		.div_mask = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK,
+		.div_shift = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT,
+	},
+	{
+		.en = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN,
+		.div_mask = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK,
+		.div_shift = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT,
+	},
+	{
+		.en = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN,
+		.div_mask = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK,
+		.div_shift = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT,
+	}
 };
 
 static struct regulator *hwacc_regulator[NUM_HW_ACC];
@@ -503,9 +559,6 @@ static const char *hwacc_ret_regulator_name[NUM_HW_ACC] = {
 /* PLLDIV=12, PLLSW=4 (PLLDDR) */
 #define PRCMU_DSI_CLOCK_SETTING		0x0000008C
 
-/* PLLDIV=8, PLLSW=4 (PLLDDR) */
-#define PRCMU_DSI_CLOCK_SETTING_U8400	0x00000088
-
 /* DPI 50000000 Hz */
 #define PRCMU_DPI_CLOCK_SETTING		((1 << PRCMU_CLK_PLL_SW_SHIFT) | \
 					  (16 << PRCMU_CLK_PLL_DIV_SHIFT))
@@ -514,9 +567,6 @@ static const char *hwacc_ret_regulator_name[NUM_HW_ACC] = {
 /* D=101, N=1, R=4, SELDIV2=0 */
 #define PRCMU_PLLDSI_FREQ_SETTING	0x00040165
 
-/* D=70, N=1, R=3, SELDIV2=0 */
-#define PRCMU_PLLDSI_FREQ_SETTING_U8400	0x00030146
-
 #define PRCMU_ENABLE_PLLDSI		0x00000001
 #define PRCMU_DISABLE_PLLDSI		0x00000000
 #define PRCMU_RELEASE_RESET_DSS		0x0000400C
@@ -528,30 +578,17 @@ static const char *hwacc_ret_regulator_name[NUM_HW_ACC] = {
 
 #define PRCMU_PLLDSI_LOCKP_LOCKED	0x3
 
-static struct {
-	u8 project_number;
-	u8 api_version;
-	u8 func_version;
-	u8 errata;
-} prcmu_version;
-
-
 int db8500_prcmu_enable_dsipll(void)
 {
 	int i;
-	unsigned int plldsifreq;
 
 	/* Clear DSIPLL_RESETN */
 	writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR);
 	/* Unclamp DSIPLL in/out */
 	writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR);
 
-	if (prcmu_is_u8400())
-		plldsifreq = PRCMU_PLLDSI_FREQ_SETTING_U8400;
-	else
-		plldsifreq = PRCMU_PLLDSI_FREQ_SETTING;
 	/* Set DSI PLL FREQ */
-	writel(plldsifreq, PRCM_PLLDSI_FREQ);
+	writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ);
 	writel(PRCMU_DSI_PLLOUT_SEL_SETTING, PRCM_DSI_PLLOUT_SEL);
 	/* Enable Escape clocks */
 	writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
@@ -583,12 +620,6 @@ int db8500_prcmu_disable_dsipll(void)
 int db8500_prcmu_set_display_clocks(void)
 {
 	unsigned long flags;
-	unsigned int dsiclk;
-
-	if (prcmu_is_u8400())
-		dsiclk = PRCMU_DSI_CLOCK_SETTING_U8400;
-	else
-		dsiclk = PRCMU_DSI_CLOCK_SETTING;
 
 	spin_lock_irqsave(&clk_mgt_lock, flags);
 
@@ -596,7 +627,7 @@ int db8500_prcmu_set_display_clocks(void)
 	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
 		cpu_relax();
 
-	writel(dsiclk, PRCM_HDMICLK_MGT);
+	writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT);
 	writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT);
 	writel(PRCMU_DPI_CLOCK_SETTING, PRCM_LCDCLK_MGT);
 
@@ -608,43 +639,41 @@ int db8500_prcmu_set_display_clocks(void)
 	return 0;
 }
 
-/**
- * prcmu_enable_spi2 - Enables pin muxing for SPI2 on OtherAlternateC1.
- */
-void prcmu_enable_spi2(void)
+u32 db8500_prcmu_read(unsigned int reg)
+{
+	return readl(_PRCMU_BASE + reg);
+}
+
+void db8500_prcmu_write(unsigned int reg, u32 value)
 {
-	u32 reg;
 	unsigned long flags;
 
-	spin_lock_irqsave(&gpiocr_lock, flags);
-	reg = readl(PRCM_GPIOCR);
-	writel(reg | PRCM_GPIOCR_SPI2_SELECT, PRCM_GPIOCR);
-	spin_unlock_irqrestore(&gpiocr_lock, flags);
+	spin_lock_irqsave(&prcmu_lock, flags);
+	writel(value, (_PRCMU_BASE + reg));
+	spin_unlock_irqrestore(&prcmu_lock, flags);
 }
 
-/**
- * prcmu_disable_spi2 - Disables pin muxing for SPI2 on OtherAlternateC1.
- */
-void prcmu_disable_spi2(void)
+void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value)
 {
-	u32 reg;
+	u32 val;
 	unsigned long flags;
 
-	spin_lock_irqsave(&gpiocr_lock, flags);
-	reg = readl(PRCM_GPIOCR);
-	writel(reg & ~PRCM_GPIOCR_SPI2_SELECT, PRCM_GPIOCR);
-	spin_unlock_irqrestore(&gpiocr_lock, flags);
+	spin_lock_irqsave(&prcmu_lock, flags);
+	val = readl(_PRCMU_BASE + reg);
+	val = ((val & ~mask) | (value & mask));
+	writel(val, (_PRCMU_BASE + reg));
+	spin_unlock_irqrestore(&prcmu_lock, flags);
 }
 
-bool prcmu_has_arm_maxopp(void)
+struct prcmu_fw_version *prcmu_get_fw_version(void)
 {
-	return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) &
-		PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK;
+	return fw_info.valid ? &fw_info.version : NULL;
 }
 
-bool prcmu_is_u8400(void)
+bool prcmu_has_arm_maxopp(void)
 {
-	return prcmu_version.project_number == PRCMU_PROJECT_ID_8400V2_0;
+	return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) &
+		PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK;
 }
 
 /**
@@ -787,6 +816,11 @@ int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll)
 	return 0;
 }
 
+u8 db8500_prcmu_get_power_state_result(void)
+{
+	return readb(tcdm_base + PRCM_ACK_MB0_AP_PWRSTTR_STATUS);
+}
+
 /* This function should only be called while mb0_transfer.lock is held. */
 static void config_wakeups(void)
 {
@@ -909,23 +943,23 @@ int db8500_prcmu_get_arm_opp(void)
 }
 
 /**
- * prcmu_get_ddr_opp - get the current DDR OPP
+ * db8500_prcmu_get_ddr_opp - get the current DDR OPP
  *
  * Returns: the current DDR OPP
  */
-int prcmu_get_ddr_opp(void)
+int db8500_prcmu_get_ddr_opp(void)
 {
 	return readb(PRCM_DDR_SUBSYS_APE_MINBW);
 }
 
 /**
- * set_ddr_opp - set the appropriate DDR OPP
+ * db8500_set_ddr_opp - set the appropriate DDR OPP
  * @opp: The new DDR operating point to which transition is to be made
  * Returns: 0 on success, non-zero on failure
  *
  * This function sets the operating point of the DDR.
  */
-int prcmu_set_ddr_opp(u8 opp)
+int db8500_prcmu_set_ddr_opp(u8 opp)
 {
 	if (opp < DDR_100_OPP || opp > DDR_25_OPP)
 		return -EINVAL;
@@ -935,25 +969,82 @@ int prcmu_set_ddr_opp(u8 opp)
 
 	return 0;
 }
+
+/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */
+static void request_even_slower_clocks(bool enable)
+{
+	void __iomem *clock_reg[] = {
+		PRCM_ACLK_MGT,
+		PRCM_DMACLK_MGT
+	};
+	unsigned long flags;
+	unsigned int i;
+
+	spin_lock_irqsave(&clk_mgt_lock, flags);
+
+	/* Grab the HW semaphore. */
+	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
+		cpu_relax();
+
+	for (i = 0; i < ARRAY_SIZE(clock_reg); i++) {
+		u32 val;
+		u32 div;
+
+		val = readl(clock_reg[i]);
+		div = (val & PRCM_CLK_MGT_CLKPLLDIV_MASK);
+		if (enable) {
+			if ((div <= 1) || (div > 15)) {
+				pr_err("prcmu: Bad clock divider %d in %s\n",
+					div, __func__);
+				goto unlock_and_return;
+			}
+			div <<= 1;
+		} else {
+			if (div <= 2)
+				goto unlock_and_return;
+			div >>= 1;
+		}
+		val = ((val & ~PRCM_CLK_MGT_CLKPLLDIV_MASK) |
+			(div & PRCM_CLK_MGT_CLKPLLDIV_MASK));
+		writel(val, clock_reg[i]);
+	}
+
+unlock_and_return:
+	/* Release the HW semaphore. */
+	writel(0, PRCM_SEM);
+
+	spin_unlock_irqrestore(&clk_mgt_lock, flags);
+}
+
 /**
- * set_ape_opp - set the appropriate APE OPP
+ * db8500_set_ape_opp - set the appropriate APE OPP
  * @opp: The new APE operating point to which transition is to be made
  * Returns: 0 on success, non-zero on failure
  *
  * This function sets the operating point of the APE.
  */
-int prcmu_set_ape_opp(u8 opp)
+int db8500_prcmu_set_ape_opp(u8 opp)
 {
 	int r = 0;
 
+	if (opp == mb1_transfer.ape_opp)
+		return 0;
+
 	mutex_lock(&mb1_transfer.lock);
 
+	if (mb1_transfer.ape_opp == APE_50_PARTLY_25_OPP)
+		request_even_slower_clocks(false);
+
+	if ((opp != APE_100_OPP) && (mb1_transfer.ape_opp != APE_100_OPP))
+		goto skip_message;
+
 	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
 		cpu_relax();
 
 	writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
 	writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP));
-	writeb(opp, (tcdm_base + PRCM_REQ_MB1_APE_OPP));
+	writeb(((opp == APE_50_PARTLY_25_OPP) ? APE_50_OPP : opp),
+		(tcdm_base + PRCM_REQ_MB1_APE_OPP));
 
 	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);
 	wait_for_completion(&mb1_transfer.work);
@@ -962,17 +1053,24 @@ int prcmu_set_ape_opp(u8 opp)
 		(mb1_transfer.ack.ape_opp != opp))
 		r = -EIO;
 
+skip_message:
+	if ((!r && (opp == APE_50_PARTLY_25_OPP)) ||
+		(r && (mb1_transfer.ape_opp == APE_50_PARTLY_25_OPP)))
+		request_even_slower_clocks(true);
+	if (!r)
+		mb1_transfer.ape_opp = opp;
+
 	mutex_unlock(&mb1_transfer.lock);
 
 	return r;
 }
 
 /**
- * prcmu_get_ape_opp - get the current APE OPP
+ * db8500_prcmu_get_ape_opp - get the current APE OPP
  *
  * Returns: the current APE OPP
  */
-int prcmu_get_ape_opp(void)
+int db8500_prcmu_get_ape_opp(void)
 {
 	return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_APE_OPP);
 }
@@ -1056,7 +1154,9 @@ static int request_pll(u8 clock, bool enable)
 {
 	int r = 0;
 
-	if (clock == PRCMU_PLLSOC1)
+	if (clock == PRCMU_PLLSOC0)
+		clock = (enable ? PLL_SOC0_ON : PLL_SOC0_OFF);
+	else if (clock == PRCMU_PLLSOC1)
 		clock = (enable ? PLL_SOC1_ON : PLL_SOC1_OFF);
 	else
 		return -EINVAL;
@@ -1375,7 +1475,7 @@ static int request_timclk(bool enable)
 	return 0;
 }
 
-static int request_reg_clock(u8 clock, bool enable)
+static int request_clock(u8 clock, bool enable)
 {
 	u32 val;
 	unsigned long flags;
@@ -1386,14 +1486,14 @@ static int request_reg_clock(u8 clock, bool enable)
 	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
 		cpu_relax();
 
-	val = readl(_PRCMU_BASE + clk_mgt[clock].offset);
+	val = readl(clk_mgt[clock].reg);
 	if (enable) {
 		val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw);
 	} else {
 		clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);
 		val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK);
 	}
-	writel(val, (_PRCMU_BASE + clk_mgt[clock].offset));
+	writel(val, clk_mgt[clock].reg);
 
 	/* Release the HW semaphore. */
 	writel(0, PRCM_SEM);
@@ -1413,7 +1513,7 @@ static int request_sga_clock(u8 clock, bool enable)
 		writel(val | PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS);
 	}
 
-	ret = request_reg_clock(clock, enable);
+	ret = request_clock(clock, enable);
 
 	if (!ret && !enable) {
 		val = readl(PRCM_CGATING_BYPASS);
@@ -1423,6 +1523,78 @@ static int request_sga_clock(u8 clock, bool enable)
 	return ret;
 }
 
+static inline bool plldsi_locked(void)
+{
+	return (readl(PRCM_PLLDSI_LOCKP) &
+		(PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 |
+		 PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3)) ==
+		(PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 |
+		 PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3);
+}
+
+static int request_plldsi(bool enable)
+{
+	int r = 0;
+	u32 val;
+
+	writel((PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP |
+		PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI), (enable ?
+		PRCM_MMIP_LS_CLAMP_CLR : PRCM_MMIP_LS_CLAMP_SET));
+
+	val = readl(PRCM_PLLDSI_ENABLE);
+	if (enable)
+		val |= PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE;
+	else
+		val &= ~PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE;
+	writel(val, PRCM_PLLDSI_ENABLE);
+
+	if (enable) {
+		unsigned int i;
+		bool locked = plldsi_locked();
+
+		for (i = 10; !locked && (i > 0); --i) {
+			udelay(100);
+			locked = plldsi_locked();
+		}
+		if (locked) {
+			writel(PRCM_APE_RESETN_DSIPLL_RESETN,
+				PRCM_APE_RESETN_SET);
+		} else {
+			writel((PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP |
+				PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI),
+				PRCM_MMIP_LS_CLAMP_SET);
+			val &= ~PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE;
+			writel(val, PRCM_PLLDSI_ENABLE);
+			r = -EAGAIN;
+		}
+	} else {
+		writel(PRCM_APE_RESETN_DSIPLL_RESETN, PRCM_APE_RESETN_CLR);
+	}
+	return r;
+}
+
+static int request_dsiclk(u8 n, bool enable)
+{
+	u32 val;
+
+	val = readl(PRCM_DSI_PLLOUT_SEL);
+	val &= ~dsiclk[n].divsel_mask;
+	val |= ((enable ? dsiclk[n].divsel : PRCM_DSI_PLLOUT_SEL_OFF) <<
+		dsiclk[n].divsel_shift);
+	writel(val, PRCM_DSI_PLLOUT_SEL);
+	return 0;
+}
+
+static int request_dsiescclk(u8 n, bool enable)
+{
+	u32 val;
+
+	val = readl(PRCM_DSITVCLK_DIV);
+	enable ? (val |= dsiescclk[n].en) : (val &= ~dsiescclk[n].en);
+	writel(val, PRCM_DSITVCLK_DIV);
+	return 0;
+}
+
 /**
  * db8500_prcmu_request_clock() - Request for a clock to be enabled or disabled.
  * @clock:      The clock for which the request is made.
@@ -1433,21 +1605,435 @@ static int request_sga_clock(u8 clock, bool enable)
  */
 int db8500_prcmu_request_clock(u8 clock, bool enable)
 {
-	switch(clock) {
-	case PRCMU_SGACLK:
+	if (clock == PRCMU_SGACLK)
 		return request_sga_clock(clock, enable);
-	case PRCMU_TIMCLK:
+	else if (clock < PRCMU_NUM_REG_CLOCKS)
+		return request_clock(clock, enable);
+	else if (clock == PRCMU_TIMCLK)
 		return request_timclk(enable);
-	case PRCMU_SYSCLK:
+	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
+		return request_dsiclk((clock - PRCMU_DSI0CLK), enable);
+	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))
+		return request_dsiescclk((clock - PRCMU_DSI0ESCCLK), enable);
+	else if (clock == PRCMU_PLLDSI)
+		return request_plldsi(enable);
+	else if (clock == PRCMU_SYSCLK)
 		return request_sysclk(enable);
-	case PRCMU_PLLSOC1:
+	else if ((clock == PRCMU_PLLSOC0) || (clock == PRCMU_PLLSOC1))
 		return request_pll(clock, enable);
+	else
+		return -EINVAL;
+}
+
+static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate,
+	int branch)
+{
+	u64 rate;
+	u32 val;
+	u32 d;
+	u32 div = 1;
+
+	val = readl(reg);
+
+	rate = src_rate;
+	rate *= ((val & PRCM_PLL_FREQ_D_MASK) >> PRCM_PLL_FREQ_D_SHIFT);
+
+	d = ((val & PRCM_PLL_FREQ_N_MASK) >> PRCM_PLL_FREQ_N_SHIFT);
+	if (d > 1)
+		div *= d;
+
+	d = ((val & PRCM_PLL_FREQ_R_MASK) >> PRCM_PLL_FREQ_R_SHIFT);
+	if (d > 1)
+		div *= d;
+
+	if (val & PRCM_PLL_FREQ_SELDIV2)
+		div *= 2;
+
+	if ((branch == PLL_FIX) || ((branch == PLL_DIV) &&
+		(val & PRCM_PLL_FREQ_DIV2EN) &&
+		((reg == PRCM_PLLSOC0_FREQ) ||
+		 (reg == PRCM_PLLDDR_FREQ))))
+		div *= 2;
+
+	(void)do_div(rate, div);
+
+	return (unsigned long)rate;
+}
+
+#define ROOT_CLOCK_RATE 38400000
+
+static unsigned long clock_rate(u8 clock)
+{
+	u32 val;
+	u32 pllsw;
+	unsigned long rate = ROOT_CLOCK_RATE;
+
+	val = readl(clk_mgt[clock].reg);
+
+	if (val & PRCM_CLK_MGT_CLK38) {
+		if (clk_mgt[clock].clk38div && (val & PRCM_CLK_MGT_CLK38DIV))
+			rate /= 2;
+		return rate;
+	}
+
+	val |= clk_mgt[clock].pllsw;
+	pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);
+
+	if (pllsw == PRCM_CLK_MGT_CLKPLLSW_SOC0)
+		rate = pll_rate(PRCM_PLLSOC0_FREQ, rate, clk_mgt[clock].branch);
+	else if (pllsw == PRCM_CLK_MGT_CLKPLLSW_SOC1)
+		rate = pll_rate(PRCM_PLLSOC1_FREQ, rate, clk_mgt[clock].branch);
+	else if (pllsw == PRCM_CLK_MGT_CLKPLLSW_DDR)
+		rate = pll_rate(PRCM_PLLDDR_FREQ, rate, clk_mgt[clock].branch);
+	else
+		return 0;
+
+	if ((clock == PRCMU_SGACLK) &&
+		(val & PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN)) {
+		u64 r = (rate * 10);
+
+		(void)do_div(r, 25);
+		return (unsigned long)r;
+	}
+	val &= PRCM_CLK_MGT_CLKPLLDIV_MASK;
+	if (val)
+		return rate / val;
+	else
+		return 0;
+}
+
+static unsigned long dsiclk_rate(u8 n)
+{
+	u32 divsel;
+	u32 div = 1;
+
+	divsel = readl(PRCM_DSI_PLLOUT_SEL);
+	divsel = ((divsel & dsiclk[n].divsel_mask) >> dsiclk[n].divsel_shift);
+
+	if (divsel == PRCM_DSI_PLLOUT_SEL_OFF)
+		divsel = dsiclk[n].divsel;
+
+	switch (divsel) {
+	case PRCM_DSI_PLLOUT_SEL_PHI_4:
+		div *= 2;
+	case PRCM_DSI_PLLOUT_SEL_PHI_2:
+		div *= 2;
+	case PRCM_DSI_PLLOUT_SEL_PHI:
+		return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK),
+			PLL_RAW) / div;
 	default:
-		break;
+		return 0;
+	}
+}
+
+static unsigned long dsiescclk_rate(u8 n)
+{
+	u32 div;
+
+	div = readl(PRCM_DSITVCLK_DIV);
+	div = ((div & dsiescclk[n].div_mask) >> (dsiescclk[n].div_shift));
+	return clock_rate(PRCMU_TVCLK) / max((u32)1, div);
+}
+
+unsigned long prcmu_clock_rate(u8 clock)
+{
+	if (clock < PRCMU_NUM_REG_CLOCKS)
+		return clock_rate(clock);
+	else if (clock == PRCMU_TIMCLK)
+		return ROOT_CLOCK_RATE / 16;
+	else if (clock == PRCMU_SYSCLK)
+		return ROOT_CLOCK_RATE;
+	else if (clock == PRCMU_PLLSOC0)
+		return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
+	else if (clock == PRCMU_PLLSOC1)
+		return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
+	else if (clock == PRCMU_PLLDDR)
+		return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW);
+	else if (clock == PRCMU_PLLDSI)
+		return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK),
+			PLL_RAW);
+	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
+		return dsiclk_rate(clock - PRCMU_DSI0CLK);
+	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))
+		return dsiescclk_rate(clock - PRCMU_DSI0ESCCLK);
+	else
+		return 0;
+}
+
+static unsigned long clock_source_rate(u32 clk_mgt_val, int branch)
+{
+	if (clk_mgt_val & PRCM_CLK_MGT_CLK38)
+		return ROOT_CLOCK_RATE;
+	clk_mgt_val &= PRCM_CLK_MGT_CLKPLLSW_MASK;
+	if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_SOC0)
+		return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, branch);
+	else if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_SOC1)
+		return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, branch);
+	else if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_DDR)
+		return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, branch);
+	else
+		return 0;
+}
+
+static u32 clock_divider(unsigned long src_rate, unsigned long rate)
+{
+	u32 div;
+
+	div = (src_rate / rate);
+	if (div == 0)
+		return 1;
+	if (rate < (src_rate / div))
+		div++;
+	return div;
+}
+
+static long round_clock_rate(u8 clock, unsigned long rate)
+{
+	u32 val;
+	u32 div;
+	unsigned long src_rate;
+	long rounded_rate;
+
+	val = readl(clk_mgt[clock].reg);
+	src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),
+		clk_mgt[clock].branch);
+	div = clock_divider(src_rate, rate);
+	if (val & PRCM_CLK_MGT_CLK38) {
+		if (clk_mgt[clock].clk38div) {
+			if (div > 2)
+				div = 2;
+		} else {
+			div = 1;
+		}
+	} else if ((clock == PRCMU_SGACLK) && (div == 3)) {
+		u64 r = (src_rate * 10);
+
+		(void)do_div(r, 25);
+		if (r <= rate)
+			return (unsigned long)r;
+	}
+	rounded_rate = (src_rate / min(div, (u32)31));
+
+	return rounded_rate;
+}
+
+#define MIN_PLL_VCO_RATE 600000000ULL
+#define MAX_PLL_VCO_RATE 1680640000ULL
+
+static long round_plldsi_rate(unsigned long rate)
+{
+	long rounded_rate = 0;
+	unsigned long src_rate;
+	unsigned long rem;
+	u32 r;
+
+	src_rate = clock_rate(PRCMU_HDMICLK);
+	rem = rate;
+
+	for (r = 7; (rem > 0) && (r > 0); r--) {
+		u64 d;
+
+		d = (r * rate);
+		(void)do_div(d, src_rate);
+		if (d < 6)
+			d = 6;
+		else if (d > 255)
+			d = 255;
+		d *= src_rate;
+		if (((2 * d) < (r * MIN_PLL_VCO_RATE)) ||
+			((r * MAX_PLL_VCO_RATE) < (2 * d)))
+			continue;
+		(void)do_div(d, r);
+		if (rate < d) {
+			if (rounded_rate == 0)
+				rounded_rate = (long)d;
+			break;
+		}
+		if ((rate - d) < rem) {
+			rem = (rate - d);
+			rounded_rate = (long)d;
+		}
 	}
+	return rounded_rate;
+}
+
+static long round_dsiclk_rate(unsigned long rate)
+{
+	u32 div;
+	unsigned long src_rate;
+	long rounded_rate;
+
+	src_rate = pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK),
+		PLL_RAW);
+	div = clock_divider(src_rate, rate);
+	rounded_rate = (src_rate / ((div > 2) ? 4 : div));
+
+	return rounded_rate;
+}
+
+static long round_dsiescclk_rate(unsigned long rate)
+{
+	u32 div;
+	unsigned long src_rate;
+	long rounded_rate;
+
+	src_rate = clock_rate(PRCMU_TVCLK);
+	div = clock_divider(src_rate, rate);
+	rounded_rate = (src_rate / min(div, (u32)255));
+
+	return rounded_rate;
+}
+
+long prcmu_round_clock_rate(u8 clock, unsigned long rate)
+{
 	if (clock < PRCMU_NUM_REG_CLOCKS)
-		return request_reg_clock(clock, enable);
-	return -EINVAL;
+		return round_clock_rate(clock, rate);
+	else if (clock == PRCMU_PLLDSI)
+		return round_plldsi_rate(rate);
+	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
+		return round_dsiclk_rate(rate);
+	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))
+		return round_dsiescclk_rate(rate);
+	else
+		return (long)prcmu_clock_rate(clock);
+}
+
+static void set_clock_rate(u8 clock, unsigned long rate)
+{
+	u32 val;
+	u32 div;
+	unsigned long src_rate;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clk_mgt_lock, flags);
+
+	/* Grab the HW semaphore. */
+	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
+		cpu_relax();
+
+	val = readl(clk_mgt[clock].reg);
+	src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),
+		clk_mgt[clock].branch);
+	div = clock_divider(src_rate, rate);
+	if (val & PRCM_CLK_MGT_CLK38) {
+		if (clk_mgt[clock].clk38div) {
+			if (div > 1)
+				val |= PRCM_CLK_MGT_CLK38DIV;
+			else
+				val &= ~PRCM_CLK_MGT_CLK38DIV;
+		}
+	} else if (clock == PRCMU_SGACLK) {
+		val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK |
+			PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN);
+		if (div == 3) {
+			u64 r = (src_rate * 10);
+
+			(void)do_div(r, 25);
+			if (r <= rate) {
+				val |= PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN;
+				div = 0;
+			}
+		}
+		val |= min(div, (u32)31);
+	} else {
+		val &= ~PRCM_CLK_MGT_CLKPLLDIV_MASK;
+		val |= min(div, (u32)31);
+	}
+	writel(val, clk_mgt[clock].reg);
+
+	/* Release the HW semaphore. */
+	writel(0, PRCM_SEM);
+
+	spin_unlock_irqrestore(&clk_mgt_lock, flags);
+}
+
+static int set_plldsi_rate(unsigned long rate)
+{
+	unsigned long src_rate;
+	unsigned long rem;
+	u32 pll_freq = 0;
+	u32 r;
+
+	src_rate = clock_rate(PRCMU_HDMICLK);
+	rem = rate;
+
+	for (r = 7; (rem > 0) && (r > 0); r--) {
+		u64 d;
+		u64 hwrate;
+
+		d = (r * rate);
+		(void)do_div(d, src_rate);
+		if (d < 6)
+			d = 6;
+		else if (d > 255)
+			d = 255;
+		hwrate = (d * src_rate);
+		if (((2 * hwrate) < (r * MIN_PLL_VCO_RATE)) ||
+			((r * MAX_PLL_VCO_RATE) < (2 * hwrate)))
+			continue;
+		(void)do_div(hwrate, r);
+		if (rate < hwrate) {
+			if (pll_freq == 0)
+				pll_freq = (((u32)d << PRCM_PLL_FREQ_D_SHIFT) |
+					(r << PRCM_PLL_FREQ_R_SHIFT));
+			break;
+		}
+		if ((rate - hwrate) < rem) {
+			rem = (rate - hwrate);
+			pll_freq = (((u32)d << PRCM_PLL_FREQ_D_SHIFT) |
+				(r << PRCM_PLL_FREQ_R_SHIFT));
+		}
+	}
+	if (pll_freq == 0)
+		return -EINVAL;
+
+	pll_freq |= (1 << PRCM_PLL_FREQ_N_SHIFT);
+	writel(pll_freq, PRCM_PLLDSI_FREQ);
+
+	return 0;
+}
+
+static void set_dsiclk_rate(u8 n, unsigned long rate)
+{
+	u32 val;
+	u32 div;
+
+	div = clock_divider(pll_rate(PRCM_PLLDSI_FREQ,
+			clock_rate(PRCMU_HDMICLK), PLL_RAW), rate);
+
+	dsiclk[n].divsel = (div == 1) ? PRCM_DSI_PLLOUT_SEL_PHI :
+			   (div == 2) ? PRCM_DSI_PLLOUT_SEL_PHI_2 :
+			   /* else */	PRCM_DSI_PLLOUT_SEL_PHI_4;
+
+	val = readl(PRCM_DSI_PLLOUT_SEL);
+	val &= ~dsiclk[n].divsel_mask;
+	val |= (dsiclk[n].divsel << dsiclk[n].divsel_shift);
+	writel(val, PRCM_DSI_PLLOUT_SEL);
+}
+
+static void set_dsiescclk_rate(u8 n, unsigned long rate)
+{
+	u32 val;
+	u32 div;
+
+	div = clock_divider(clock_rate(PRCMU_TVCLK), rate);
+	val = readl(PRCM_DSITVCLK_DIV);
+	val &= ~dsiescclk[n].div_mask;
+	val |= (min(div, (u32)255) << dsiescclk[n].div_shift);
+	writel(val, PRCM_DSITVCLK_DIV);
+}
+
+int prcmu_set_clock_rate(u8 clock, unsigned long rate)
+{
+	if (clock < PRCMU_NUM_REG_CLOCKS)
+		set_clock_rate(clock, rate);
+	else if (clock == PRCMU_PLLDSI)
+		return set_plldsi_rate(rate);
+	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))
+		set_dsiclk_rate((clock - PRCMU_DSI0CLK), rate);
+	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))
+		set_dsiescclk_rate((clock - PRCMU_DSI0ESCCLK), rate);
+	return 0;
 }
 
 int db8500_prcmu_config_esram0_deep_sleep(u8 state)
@@ -1476,7 +2062,7 @@ int db8500_prcmu_config_esram0_deep_sleep(u8 state)
 	return 0;
 }
 
-int prcmu_config_hotdog(u8 threshold)
+int db8500_prcmu_config_hotdog(u8 threshold)
 {
 	mutex_lock(&mb4_transfer.lock);
 
@@ -1494,7 +2080,7 @@ int prcmu_config_hotdog(u8 threshold)
 	return 0;
 }
 
-int prcmu_config_hotmon(u8 low, u8 high)
+int db8500_prcmu_config_hotmon(u8 low, u8 high)
 {
 	mutex_lock(&mb4_transfer.lock);
 
@@ -1533,7 +2119,7 @@ static int config_hot_period(u16 val)
 	return 0;
 }
 
-int prcmu_start_temp_sense(u16 cycles32k)
+int db8500_prcmu_start_temp_sense(u16 cycles32k)
 {
 	if (cycles32k == 0xFFFF)
 		return -EINVAL;
@@ -1541,7 +2127,7 @@ int prcmu_start_temp_sense(u16 cycles32k)
 	return config_hot_period(cycles32k);
 }
 
-int prcmu_stop_temp_sense(void)
+int db8500_prcmu_stop_temp_sense(void)
 {
 	return config_hot_period(0xFFFF);
 }
@@ -1570,7 +2156,7 @@ static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)
 
 }
 
-int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
+int db8500_prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
 {
 	BUG_ON(num == 0 || num > 0xf);
 	return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0,
@@ -1578,17 +2164,17 @@ int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
 			    A9WDOG_AUTO_OFF_DIS);
 }
 
-int prcmu_enable_a9wdog(u8 id)
+int db8500_prcmu_enable_a9wdog(u8 id)
 {
 	return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0);
 }
 
-int prcmu_disable_a9wdog(u8 id)
+int db8500_prcmu_disable_a9wdog(u8 id)
 {
 	return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0);
 }
 
-int prcmu_kick_a9wdog(u8 id)
+int db8500_prcmu_kick_a9wdog(u8 id)
 {
 	return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0);
 }
@@ -1596,16 +2182,8 @@ int prcmu_kick_a9wdog(u8 id)
 /*
  * timeout is 28 bit, in ms.
  */
-#define MAX_WATCHDOG_TIMEOUT 131000
-int prcmu_load_a9wdog(u8 id, u32 timeout)
+int db8500_prcmu_load_a9wdog(u8 id, u32 timeout)
 {
-	if (timeout > MAX_WATCHDOG_TIMEOUT)
-		/*
-		 * Due to calculation bug in prcmu fw, timeouts
-		 * can't be bigger than 131 seconds.
-		 */
-		return -EINVAL;
-
 	return prcmu_a9wdog(MB4H_A9WDOG_LOAD,
 			    (id & A9WDOG_ID_MASK) |
 			    /*
@@ -1619,41 +2197,6 @@ int prcmu_load_a9wdog(u8 id, u32 timeout)
 }
 
 /**
- * prcmu_set_clock_divider() - Configure the clock divider.
- * @clock:	The clock for which the request is made.
- * @divider:	The clock divider. (< 32)
- *
- * This function should only be used by the clock implementation.
- * Do not use it from any other place!
- */
-int prcmu_set_clock_divider(u8 clock, u8 divider)
-{
-	u32 val;
-	unsigned long flags;
-
-	if ((clock >= PRCMU_NUM_REG_CLOCKS) || (divider < 1) || (31 < divider))
-		return -EINVAL;
-
-	spin_lock_irqsave(&clk_mgt_lock, flags);
-
-	/* Grab the HW semaphore. */
-	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
-		cpu_relax();
-
-	val = readl(_PRCMU_BASE + clk_mgt[clock].offset);
-	val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK);
-	val |= (u32)divider;
-	writel(val, (_PRCMU_BASE + clk_mgt[clock].offset));
-
-	/* Release the HW semaphore. */
-	writel(0, PRCM_SEM);
-
-	spin_unlock_irqrestore(&clk_mgt_lock, flags);
-
-	return 0;
-}
-
-/**
  * prcmu_abb_read() - Read register value(s) from the ABB.
  * @slave:	The I2C slave address.
  * @reg:	The (start) register address.
@@ -1850,9 +2393,9 @@ u16 db8500_prcmu_get_reset_code(void)
 }
 
 /**
- * prcmu_reset_modem - ask the PRCMU to reset modem
+ * db8500_prcmu_reset_modem - ask the PRCMU to reset modem
  */
-void prcmu_modem_reset(void)
+void db8500_prcmu_modem_reset(void)
 {
 	mutex_lock(&mb1_transfer.lock);
 
@@ -2099,6 +2642,22 @@ static struct irq_chip prcmu_irq_chip = {
 	.irq_unmask	= prcmu_irq_unmask,
 };
 
+static char *fw_project_name(u8 project)
+{
+	switch (project) {
+	case PRCMU_FW_PROJECT_U8500:
+		return "U8500";
+	case PRCMU_FW_PROJECT_U8500_C2:
+		return "U8500 C2";
+	case PRCMU_FW_PROJECT_U9500:
+		return "U9500";
+	case PRCMU_FW_PROJECT_U9500_C2:
+		return "U9500 C2";
+	default:
+		return "Unknown";
+	}
+}
+
 void __init db8500_prcmu_early_init(void)
 {
 	unsigned int i;
@@ -2108,11 +2667,13 @@ void __init db8500_prcmu_early_init(void)
 		if (tcpm_base != NULL) {
 			u32 version;
 			version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET);
-			prcmu_version.project_number = version & 0xFF;
-			prcmu_version.api_version = (version >> 8) & 0xFF;
-			prcmu_version.func_version = (version >> 16) & 0xFF;
-			prcmu_version.errata = (version >> 24) & 0xFF;
-			pr_info("PRCMU firmware version %d.%d.%d\n",
+			fw_info.version.project = version & 0xFF;
+			fw_info.version.api_version = (version >> 8) & 0xFF;
+			fw_info.version.func_version = (version >> 16) & 0xFF;
+			fw_info.version.errata = (version >> 24) & 0xFF;
+			fw_info.valid = true;
+			pr_info("PRCMU firmware: %s, version %d.%d.%d\n",
+				fw_project_name(fw_info.version.project),
 				(version >> 8) & 0xFF, (version >> 16) & 0xFF,
 				(version >> 24) & 0xFF);
 			iounmap(tcpm_base);
@@ -2130,6 +2691,7 @@ void __init db8500_prcmu_early_init(void)
 	init_completion(&mb0_transfer.ac_wake_work);
 	mutex_init(&mb1_transfer.lock);
 	init_completion(&mb1_transfer.work);
+	mb1_transfer.ape_opp = APE_NO_CHANGE;
 	mutex_init(&mb2_transfer.lock);
 	init_completion(&mb2_transfer.work);
 	spin_lock_init(&mb2_transfer.auto_pm_lock);
@@ -2154,7 +2716,7 @@ void __init db8500_prcmu_early_init(void)
 	}
 }
 
-static void __init db8500_prcmu_init_clkforce(void)
+static void __init init_prcm_registers(void)
 {
 	u32 val;
 
@@ -2186,19 +2748,17 @@ static struct regulator_consumer_supply db8500_vape_consumers[] = {
 	REGULATOR_SUPPLY("vcore", "uart1"),
 	REGULATOR_SUPPLY("vcore", "uart2"),
 	REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"),
+	REGULATOR_SUPPLY("v-hsi", "ste_hsi.0"),
 };
 
 static struct regulator_consumer_supply db8500_vsmps2_consumers[] = {
-	/* CG2900 and CW1200 power to off-chip peripherals */
-	REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"),
-	REGULATOR_SUPPLY("wlan_1v8", "cw1200.0"),
 	REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"),
 	/* AV8100 regulator */
 	REGULATOR_SUPPLY("hdmi_1v8", "0-0070"),
 };
 
 static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = {
-	REGULATOR_SUPPLY("vsupply", "b2r2.0"),
+	REGULATOR_SUPPLY("vsupply", "b2r2_bus"),
 	REGULATOR_SUPPLY("vsupply", "mcde"),
 };
 
@@ -2235,6 +2795,7 @@ static struct regulator_consumer_supply db8500_esram12_consumers[] = {
 static struct regulator_consumer_supply db8500_esram34_consumers[] = {
 	REGULATOR_SUPPLY("v-esram34", "mcde"),
 	REGULATOR_SUPPLY("esram34", "cm_control"),
+	REGULATOR_SUPPLY("lcla_esram", "dma40.0"),
 };
 
 static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
@@ -2291,7 +2852,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
 		},
 	},
 	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
-		.supply_regulator = "db8500-vape",
+		/* dependency to u8500-vape is handled outside regulator framework */
 		.constraints = {
 			.name = "db8500-sva-mmdsp",
 			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -2307,7 +2868,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
 		},
 	},
 	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
-		.supply_regulator = "db8500-vape",
+		/* dependency to u8500-vape is handled outside regulator framework */
 		.constraints = {
 			.name = "db8500-sva-pipe",
 			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -2316,7 +2877,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
 		.num_consumer_supplies = ARRAY_SIZE(db8500_svapipe_consumers),
 	},
 	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
-		.supply_regulator = "db8500-vape",
+		/* dependency to u8500-vape is handled outside regulator framework */
 		.constraints = {
 			.name = "db8500-sia-mmdsp",
 			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -2331,7 +2892,7 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
 		},
 	},
 	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
-		.supply_regulator = "db8500-vape",
+		/* dependency to u8500-vape is handled outside regulator framework */
 		.constraints = {
 			.name = "db8500-sia-pipe",
 			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -2359,7 +2920,10 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
 		.num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers),
 	},
 	[DB8500_REGULATOR_SWITCH_ESRAM12] = {
-		.supply_regulator = "db8500-vape",
+		/*
+		 * esram12 is set in retention and supplied by Vsafe when Vape is off,
+		 * no need to hold Vape
+		 */
 		.constraints = {
 			.name = "db8500-esram12",
 			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -2374,7 +2938,10 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
 		},
 	},
 	[DB8500_REGULATOR_SWITCH_ESRAM34] = {
-		.supply_regulator = "db8500-vape",
+		/*
+		 * esram34 is set in retention and supplied by Vsafe when Vape is off,
+		 * no need to hold Vape
+		 */
 		.constraints = {
 			.name = "db8500-esram34",
 			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
@@ -2412,7 +2979,7 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev)
 	if (ux500_is_svp())
 		return -ENODEV;
 
-	db8500_prcmu_init_clkforce();
+	init_prcm_registers();
 
 	/* Clean up the mailbox interrupts after pre-kernel code. */
 	writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h
index ec22e9f..b9ab4ce 100644
--- a/drivers/mfd/dbx500-prcmu-regs.h
+++ b/drivers/mfd/dbx500-prcmu-regs.h
@@ -17,41 +17,41 @@
 
 #define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
 
-#define PRCM_SVACLK_MGT_OFF		0x008
-#define PRCM_SIACLK_MGT_OFF		0x00C
-#define PRCM_SGACLK_MGT_OFF		0x014
-#define PRCM_UARTCLK_MGT_OFF		0x018
-#define PRCM_MSP02CLK_MGT_OFF		0x01C
-#define PRCM_I2CCLK_MGT_OFF		0x020
-#define PRCM_SDMMCCLK_MGT_OFF		0x024
-#define PRCM_SLIMCLK_MGT_OFF		0x028
-#define PRCM_PER1CLK_MGT_OFF		0x02C
-#define PRCM_PER2CLK_MGT_OFF		0x030
-#define PRCM_PER3CLK_MGT_OFF		0x034
-#define PRCM_PER5CLK_MGT_OFF		0x038
-#define PRCM_PER6CLK_MGT_OFF		0x03C
-#define PRCM_PER7CLK_MGT_OFF		0x040
-#define PRCM_PWMCLK_MGT_OFF		0x044 /* for DB5500 */
-#define PRCM_IRDACLK_MGT_OFF		0x048 /* for DB5500 */
-#define PRCM_IRRCCLK_MGT_OFF		0x04C /* for DB5500 */
-#define PRCM_LCDCLK_MGT_OFF		0x044
-#define PRCM_BMLCLK_MGT_OFF		0x04C
-#define PRCM_HSITXCLK_MGT_OFF		0x050
-#define PRCM_HSIRXCLK_MGT_OFF		0x054
-#define PRCM_HDMICLK_MGT_OFF		0x058
-#define PRCM_APEATCLK_MGT_OFF		0x05C
-#define PRCM_APETRACECLK_MGT_OFF	0x060
-#define PRCM_MCDECLK_MGT_OFF		0x064
-#define PRCM_IPI2CCLK_MGT_OFF		0x068
-#define PRCM_DSIALTCLK_MGT_OFF		0x06C
-#define PRCM_DMACLK_MGT_OFF		0x074
-#define PRCM_B2R2CLK_MGT_OFF		0x078
-#define PRCM_TVCLK_MGT_OFF		0x07C
-#define PRCM_UNIPROCLK_MGT_OFF		0x278
-#define PRCM_SSPCLK_MGT_OFF		0x280
-#define PRCM_RNGCLK_MGT_OFF		0x284
-#define PRCM_UICCCLK_MGT_OFF		0x27C
-#define PRCM_MSP1CLK_MGT_OFF		0x288
+#define PRCM_CLK_MGT(_offset) (void __iomem *)(IO_ADDRESS(U8500_PRCMU_BASE) \
+	+ _offset)
+#define PRCM_ACLK_MGT		PRCM_CLK_MGT(0x004)
+#define PRCM_SVACLK_MGT		PRCM_CLK_MGT(0x008)
+#define PRCM_SIACLK_MGT		PRCM_CLK_MGT(0x00C)
+#define PRCM_SGACLK_MGT		PRCM_CLK_MGT(0x014)
+#define PRCM_UARTCLK_MGT	PRCM_CLK_MGT(0x018)
+#define PRCM_MSP02CLK_MGT	PRCM_CLK_MGT(0x01C)
+#define PRCM_I2CCLK_MGT		PRCM_CLK_MGT(0x020)
+#define PRCM_SDMMCCLK_MGT	PRCM_CLK_MGT(0x024)
+#define PRCM_SLIMCLK_MGT	PRCM_CLK_MGT(0x028)
+#define PRCM_PER1CLK_MGT	PRCM_CLK_MGT(0x02C)
+#define PRCM_PER2CLK_MGT	PRCM_CLK_MGT(0x030)
+#define PRCM_PER3CLK_MGT	PRCM_CLK_MGT(0x034)
+#define PRCM_PER5CLK_MGT	PRCM_CLK_MGT(0x038)
+#define PRCM_PER6CLK_MGT	PRCM_CLK_MGT(0x03C)
+#define PRCM_PER7CLK_MGT	PRCM_CLK_MGT(0x040)
+#define PRCM_LCDCLK_MGT		PRCM_CLK_MGT(0x044)
+#define PRCM_BMLCLK_MGT		PRCM_CLK_MGT(0x04C)
+#define PRCM_HSITXCLK_MGT	PRCM_CLK_MGT(0x050)
+#define PRCM_HSIRXCLK_MGT	PRCM_CLK_MGT(0x054)
+#define PRCM_HDMICLK_MGT	PRCM_CLK_MGT(0x058)
+#define PRCM_APEATCLK_MGT	PRCM_CLK_MGT(0x05C)
+#define PRCM_APETRACECLK_MGT	PRCM_CLK_MGT(0x060)
+#define PRCM_MCDECLK_MGT	PRCM_CLK_MGT(0x064)
+#define PRCM_IPI2CCLK_MGT	PRCM_CLK_MGT(0x068)
+#define PRCM_DSIALTCLK_MGT	PRCM_CLK_MGT(0x06C)
+#define PRCM_DMACLK_MGT		PRCM_CLK_MGT(0x074)
+#define PRCM_B2R2CLK_MGT	PRCM_CLK_MGT(0x078)
+#define PRCM_TVCLK_MGT		PRCM_CLK_MGT(0x07C)
+#define PRCM_UNIPROCLK_MGT	PRCM_CLK_MGT(0x278)
+#define PRCM_SSPCLK_MGT		PRCM_CLK_MGT(0x280)
+#define PRCM_RNGCLK_MGT		PRCM_CLK_MGT(0x284)
+#define PRCM_UICCCLK_MGT	PRCM_CLK_MGT(0x27C)
+#define PRCM_MSP1CLK_MGT	PRCM_CLK_MGT(0x288)
 
 #define PRCM_ARM_PLLDIVPS	(_PRCMU_BASE + 0x118)
 #define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE		0x3f
@@ -131,20 +131,58 @@
 #define PRCM_MMIP_LS_CLAMP_SET     (_PRCMU_BASE + 0x420)
 #define PRCM_MMIP_LS_CLAMP_CLR     (_PRCMU_BASE + 0x424)
 
+#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP		BIT(11)
+#define PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI	BIT(22)
+
 /* PRCMU clock/PLL/reset registers */
+#define PRCM_PLLSOC0_FREQ	   (_PRCMU_BASE + 0x080)
+#define PRCM_PLLSOC1_FREQ	   (_PRCMU_BASE + 0x084)
+#define PRCM_PLLDDR_FREQ	   (_PRCMU_BASE + 0x08C)
+#define PRCM_PLL_FREQ_D_SHIFT	0
+#define PRCM_PLL_FREQ_D_MASK	BITS(0, 7)
+#define PRCM_PLL_FREQ_N_SHIFT	8
+#define PRCM_PLL_FREQ_N_MASK	BITS(8, 13)
+#define PRCM_PLL_FREQ_R_SHIFT	16
+#define PRCM_PLL_FREQ_R_MASK	BITS(16, 18)
+#define PRCM_PLL_FREQ_SELDIV2	BIT(24)
+#define PRCM_PLL_FREQ_DIV2EN	BIT(25)
+
 #define PRCM_PLLDSI_FREQ           (_PRCMU_BASE + 0x500)
 #define PRCM_PLLDSI_ENABLE         (_PRCMU_BASE + 0x504)
 #define PRCM_PLLDSI_LOCKP          (_PRCMU_BASE + 0x508)
-#define PRCM_LCDCLK_MGT            (_PRCMU_BASE + PRCM_LCDCLK_MGT_OFF)
-#define PRCM_MCDECLK_MGT           (_PRCMU_BASE + PRCM_MCDECLK_MGT_OFF)
-#define PRCM_HDMICLK_MGT           (_PRCMU_BASE + PRCM_HDMICLK_MGT_OFF)
-#define PRCM_TVCLK_MGT             (_PRCMU_BASE + PRCM_TVCLK_MGT_OFF)
 #define PRCM_DSI_PLLOUT_SEL        (_PRCMU_BASE + 0x530)
 #define PRCM_DSITVCLK_DIV          (_PRCMU_BASE + 0x52C)
 #define PRCM_PLLDSI_LOCKP          (_PRCMU_BASE + 0x508)
 #define PRCM_APE_RESETN_SET        (_PRCMU_BASE + 0x1E4)
 #define PRCM_APE_RESETN_CLR        (_PRCMU_BASE + 0x1E8)
 
+#define PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE BIT(0)
+
+#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10	BIT(0)
+#define PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3	BIT(1)
+
+#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT	0
+#define PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK	BITS(0, 2)
+#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT	8
+#define PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK	BITS(8, 10)
+
+#define PRCM_DSI_PLLOUT_SEL_OFF		0
+#define PRCM_DSI_PLLOUT_SEL_PHI		1
+#define PRCM_DSI_PLLOUT_SEL_PHI_2	2
+#define PRCM_DSI_PLLOUT_SEL_PHI_4	3
+
+#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT	0
+#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK		BITS(0, 7)
+#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT	8
+#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK		BITS(8, 15)
+#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT	16
+#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK		BITS(16, 23)
+#define PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN		BIT(24)
+#define PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN		BIT(25)
+#define PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN		BIT(26)
+
+#define PRCM_APE_RESETN_DSIPLL_RESETN BIT(14)
+
 #define PRCM_CLKOCR		   (_PRCMU_BASE + 0x1CC)
 #define PRCM_CLKOCR_CLKOUT0_REF_CLK	(1 << 0)
 #define PRCM_CLKOCR_CLKOUT0_MASK	BITS(0, 13)
@@ -183,9 +221,15 @@
 #define PRCM_CLKOCR_CLKOSEL1_MASK	BITS(22, 24)
 #define PRCM_CLKOCR_CLK1TYPE		BIT(28)
 
-#define PRCM_CLK_MGT_CLKPLLDIV_MASK	BITS(0, 4)
-#define PRCM_CLK_MGT_CLKPLLSW_MASK	BITS(5, 7)
-#define PRCM_CLK_MGT_CLKEN		BIT(8)
+#define PRCM_CLK_MGT_CLKPLLDIV_MASK		BITS(0, 4)
+#define PRCM_CLK_MGT_CLKPLLSW_SOC0		BIT(5)
+#define PRCM_CLK_MGT_CLKPLLSW_SOC1		BIT(6)
+#define PRCM_CLK_MGT_CLKPLLSW_DDR		BIT(7)
+#define PRCM_CLK_MGT_CLKPLLSW_MASK		BITS(5, 7)
+#define PRCM_CLK_MGT_CLKEN			BIT(8)
+#define PRCM_CLK_MGT_CLK38			BIT(9)
+#define PRCM_CLK_MGT_CLK38DIV			BIT(11)
+#define PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN	BIT(12)
 
 /* GPIOCR register */
 #define PRCM_GPIOCR_SPI2_SELECT BIT(23)
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 7122386..9fd4f63 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -560,6 +560,8 @@ EXPORT_SYMBOL(mc13xxx_get_flags);
 
 #define MC13XXX_ADC1_CHAN0_SHIFT	5
 #define MC13XXX_ADC1_CHAN1_SHIFT	8
+#define MC13783_ADC1_ATO_SHIFT		11
+#define MC13783_ADC1_ATOX		(1 << 19)
 
 struct mc13xxx_adcdone_data {
 	struct mc13xxx *mc13xxx;
@@ -580,7 +582,8 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
 #define MC13XXX_ADC_WORKING (1 << 0)
 
 int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
-		unsigned int channel, unsigned int *sample)
+		unsigned int channel, u8 ato, bool atox,
+		unsigned int *sample)
 {
 	u32 adc0, adc1, old_adc0;
 	int i, ret;
@@ -631,6 +634,9 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
 		return -EINVAL;
 	}
 
+	adc1 |= ato << MC13783_ADC1_ATO_SHIFT;
+	if (atox)
+		adc1 |= MC13783_ADC1_ATOX;
 	dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__);
 	mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
 			mc13xxx_handler_adcdone, __func__, &adcdone_data);
@@ -813,7 +819,8 @@ err_revision:
 		mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
 
 	if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
-		mc13xxx_add_subdevice(mc13xxx, "%s-ts");
+		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts",
+				&pdata->touch, sizeof(pdata->touch));
 
 	if (pdata) {
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 86cc3f7..6acf2e0 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/mfd/mcp.h>
 
-#include <mach/dma.h>
 #include <asm/system.h>
 
 
@@ -48,39 +47,11 @@ static int mcp_bus_remove(struct device *dev)
 	return 0;
 }
 
-static int mcp_bus_suspend(struct device *dev, pm_message_t state)
-{
-	struct mcp *mcp = to_mcp(dev);
-	int ret = 0;
-
-	if (dev->driver) {
-		struct mcp_driver *drv = to_mcp_driver(dev->driver);
-
-		ret = drv->suspend(mcp, state);
-	}
-	return ret;
-}
-
-static int mcp_bus_resume(struct device *dev)
-{
-	struct mcp *mcp = to_mcp(dev);
-	int ret = 0;
-
-	if (dev->driver) {
-		struct mcp_driver *drv = to_mcp_driver(dev->driver);
-
-		ret = drv->resume(mcp);
-	}
-	return ret;
-}
-
 static struct bus_type mcp_bus_type = {
 	.name		= "mcp",
 	.match		= mcp_bus_match,
 	.probe		= mcp_bus_probe,
 	.remove		= mcp_bus_remove,
-	.suspend	= mcp_bus_suspend,
-	.resume		= mcp_bus_resume,
 };
 
 /**
@@ -208,6 +179,7 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
 	mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL);
 	if (mcp) {
 		spin_lock_init(&mcp->lock);
+		device_initialize(&mcp->attached_device);
 		mcp->attached_device.parent = parent;
 		mcp->attached_device.bus = &mcp_bus_type;
 		mcp->attached_device.dma_mask = parent->dma_mask;
@@ -217,18 +189,25 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
 }
 EXPORT_SYMBOL(mcp_host_alloc);
 
-int mcp_host_register(struct mcp *mcp)
+int mcp_host_add(struct mcp *mcp, void *pdata)
 {
+	mcp->attached_device.platform_data = pdata;
 	dev_set_name(&mcp->attached_device, "mcp0");
-	return device_register(&mcp->attached_device);
+	return device_add(&mcp->attached_device);
+}
+EXPORT_SYMBOL(mcp_host_add);
+
+void mcp_host_del(struct mcp *mcp)
+{
+	device_del(&mcp->attached_device);
 }
-EXPORT_SYMBOL(mcp_host_register);
+EXPORT_SYMBOL(mcp_host_del);
 
-void mcp_host_unregister(struct mcp *mcp)
+void mcp_host_free(struct mcp *mcp)
 {
-	device_unregister(&mcp->attached_device);
+	put_device(&mcp->attached_device);
 }
-EXPORT_SYMBOL(mcp_host_unregister);
+EXPORT_SYMBOL(mcp_host_free);
 
 int mcp_driver_register(struct mcp_driver *mcpdrv)
 {
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 02c53a0..1c0ceac 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -13,51 +13,61 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/mfd/mcp.h>
 
-#include <mach/dma.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/system.h>
 #include <mach/mcp.h>
 
-#include <mach/assabet.h>
-
+#define DRIVER_NAME "sa11x0-mcp"
 
 struct mcp_sa11x0 {
-	u32	mccr0;
-	u32	mccr1;
+	void __iomem	*base0;
+	void __iomem	*base1;
+	u32		mccr0;
+	u32		mccr1;
 };
 
+/* Register offsets */
+#define MCCR0(m)	((m)->base0 + 0x00)
+#define MCDR0(m)	((m)->base0 + 0x08)
+#define MCDR1(m)	((m)->base0 + 0x0c)
+#define MCDR2(m)	((m)->base0 + 0x10)
+#define MCSR(m)		((m)->base0 + 0x18)
+#define MCCR1(m)	((m)->base1 + 0x00)
+
 #define priv(mcp)	((struct mcp_sa11x0 *)mcp_priv(mcp))
 
 static void
 mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
 {
-	unsigned int mccr0;
+	struct mcp_sa11x0 *m = priv(mcp);
 
 	divisor /= 32;
 
-	mccr0 = Ser4MCCR0 & ~0x00007f00;
-	mccr0 |= divisor << 8;
-	Ser4MCCR0 = mccr0;
+	m->mccr0 &= ~0x00007f00;
+	m->mccr0 |= divisor << 8;
+	writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 static void
 mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
 {
-	unsigned int mccr0;
+	struct mcp_sa11x0 *m = priv(mcp);
 
 	divisor /= 32;
 
-	mccr0 = Ser4MCCR0 & ~0x0000007f;
-	mccr0 |= divisor;
-	Ser4MCCR0 = mccr0;
+	m->mccr0 &= ~0x0000007f;
+	m->mccr0 |= divisor;
+	writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 /*
@@ -69,14 +79,15 @@ mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
 static void
 mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
 {
+	struct mcp_sa11x0 *m = priv(mcp);
 	int ret = -ETIME;
 	int i;
 
-	Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
+	writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m));
 
 	for (i = 0; i < 2; i++) {
 		udelay(mcp->rw_timeout);
-		if (Ser4MCSR & MCSR_CWC) {
+		if (readl_relaxed(MCSR(m)) & MCSR_CWC) {
 			ret = 0;
 			break;
 		}
@@ -95,15 +106,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
 static unsigned int
 mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
 {
+	struct mcp_sa11x0 *m = priv(mcp);
 	int ret = -ETIME;
 	int i;
 
-	Ser4MCDR2 = reg << 17 | MCDR2_Rd;
+	writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m));
 
 	for (i = 0; i < 2; i++) {
 		udelay(mcp->rw_timeout);
-		if (Ser4MCSR & MCSR_CRC) {
-			ret = Ser4MCDR2 & 0xffff;
+		if (readl_relaxed(MCSR(m)) & MCSR_CRC) {
+			ret = readl_relaxed(MCDR2(m)) & 0xffff;
 			break;
 		}
 	}
@@ -116,13 +128,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
 
 static void mcp_sa11x0_enable(struct mcp *mcp)
 {
-	Ser4MCSR = -1;
-	Ser4MCCR0 |= MCCR0_MCE;
+	struct mcp_sa11x0 *m = priv(mcp);
+
+	writel(-1, MCSR(m));
+	m->mccr0 |= MCCR0_MCE;
+	writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 static void mcp_sa11x0_disable(struct mcp *mcp)
 {
-	Ser4MCCR0 &= ~MCCR0_MCE;
+	struct mcp_sa11x0 *m = priv(mcp);
+
+	m->mccr0 &= ~MCCR0_MCE;
+	writel_relaxed(m->mccr0, MCCR0(m));
 }
 
 /*
@@ -137,55 +155,64 @@ static struct mcp_ops mcp_sa11x0 = {
 	.disable		= mcp_sa11x0_disable,
 };
 
-static int mcp_sa11x0_probe(struct platform_device *pdev)
+static int mcp_sa11x0_probe(struct platform_device *dev)
 {
-	struct mcp_plat_data *data = pdev->dev.platform_data;
+	struct mcp_plat_data *data = dev->dev.platform_data;
+	struct resource *mem0, *mem1;
+	struct mcp_sa11x0 *m;
 	struct mcp *mcp;
 	int ret;
 
 	if (!data)
 		return -ENODEV;
 
-	if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
-		return -EBUSY;
+	mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
+	if (!mem0 || !mem1)
+		return -ENXIO;
+
+	if (!request_mem_region(mem0->start, resource_size(mem0),
+				DRIVER_NAME)) {
+		ret = -EBUSY;
+		goto err_mem0;
+	}
 
-	mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0));
+	if (!request_mem_region(mem1->start, resource_size(mem1),
+				DRIVER_NAME)) {
+		ret = -EBUSY;
+		goto err_mem1;
+	}
+
+	mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0));
 	if (!mcp) {
 		ret = -ENOMEM;
-		goto release;
+		goto err_alloc;
 	}
 
 	mcp->owner		= THIS_MODULE;
 	mcp->ops		= &mcp_sa11x0;
 	mcp->sclk_rate		= data->sclk_rate;
-	mcp->dma_audio_rd	= DMA_Ser4MCP0Rd;
-	mcp->dma_audio_wr	= DMA_Ser4MCP0Wr;
-	mcp->dma_telco_rd	= DMA_Ser4MCP1Rd;
-	mcp->dma_telco_wr	= DMA_Ser4MCP1Wr;
-	mcp->gpio_base		= data->gpio_base;
 
-	platform_set_drvdata(pdev, mcp);
+	m = priv(mcp);
+	m->mccr0 = data->mccr0 | 0x7f7f;
+	m->mccr1 = data->mccr1;
 
-	if (machine_is_assabet()) {
-		ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
+	m->base0 = ioremap(mem0->start, resource_size(mem0));
+	m->base1 = ioremap(mem1->start, resource_size(mem1));
+	if (!m->base0 || !m->base1) {
+		ret = -ENOMEM;
+		goto err_ioremap;
 	}
 
-	/*
-	 * Setup the PPC unit correctly.
-	 */
-	PPDR &= ~PPC_RXD4;
-	PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-	PSDR |= PPC_RXD4;
-	PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-	PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+	platform_set_drvdata(dev, mcp);
 
 	/*
 	 * Initialise device.  Note that we initially
 	 * set the sampling rate to minimum.
 	 */
-	Ser4MCSR = -1;
-	Ser4MCCR1 = data->mccr1;
-	Ser4MCCR0 = data->mccr0 | 0x7f7f;
+	writel_relaxed(-1, MCSR(m));
+	writel_relaxed(m->mccr1, MCCR1(m));
+	writel_relaxed(m->mccr0, MCCR0(m));
 
 	/*
 	 * Calculate the read/write timeout (us) from the bit clock
@@ -195,62 +222,90 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
 	mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
 			  mcp->sclk_rate;
 
-	ret = mcp_host_register(mcp);
+	ret = mcp_host_add(mcp, data->codec_pdata);
 	if (ret == 0)
-		goto out;
+		return 0;
 
- release:
-	release_mem_region(0x80060000, 0x60);
-	platform_set_drvdata(pdev, NULL);
+	platform_set_drvdata(dev, NULL);
 
- out:
+ err_ioremap:
+	iounmap(m->base1);
+	iounmap(m->base0);
+	mcp_host_free(mcp);
+ err_alloc:
+	release_mem_region(mem1->start, resource_size(mem1));
+ err_mem1:
+	release_mem_region(mem0->start, resource_size(mem0));
+ err_mem0:
 	return ret;
 }
 
 static int mcp_sa11x0_remove(struct platform_device *dev)
 {
 	struct mcp *mcp = platform_get_drvdata(dev);
+	struct mcp_sa11x0 *m = priv(mcp);
+	struct resource *mem0, *mem1;
+
+	if (m->mccr0 & MCCR0_MCE)
+		dev_warn(&dev->dev,
+			 "device left active (missing disable call?)\n");
+
+	mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
 
 	platform_set_drvdata(dev, NULL);
-	mcp_host_unregister(mcp);
-	release_mem_region(0x80060000, 0x60);
+	mcp_host_del(mcp);
+	iounmap(m->base1);
+	iounmap(m->base0);
+	mcp_host_free(mcp);
+	release_mem_region(mem1->start, resource_size(mem1));
+	release_mem_region(mem0->start, resource_size(mem0));
 
 	return 0;
 }
 
-static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int mcp_sa11x0_suspend(struct device *dev)
 {
-	struct mcp *mcp = platform_get_drvdata(dev);
+	struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
+
+	if (m->mccr0 & MCCR0_MCE)
+		dev_warn(dev, "device left active (missing disable call?)\n");
 
-	priv(mcp)->mccr0 = Ser4MCCR0;
-	priv(mcp)->mccr1 = Ser4MCCR1;
-	Ser4MCCR0 &= ~MCCR0_MCE;
+	writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m));
 
 	return 0;
 }
 
-static int mcp_sa11x0_resume(struct platform_device *dev)
+static int mcp_sa11x0_resume(struct device *dev)
 {
-	struct mcp *mcp = platform_get_drvdata(dev);
+	struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev));
 
-	Ser4MCCR1 = priv(mcp)->mccr1;
-	Ser4MCCR0 = priv(mcp)->mccr0;
+	writel_relaxed(m->mccr1, MCCR1(m));
+	writel_relaxed(m->mccr0, MCCR0(m));
 
 	return 0;
 }
-
-/*
- * The driver for the SA11x0 MCP port.
- */
-MODULE_ALIAS("platform:sa11x0-mcp");
+#endif
+
+static const struct dev_pm_ops mcp_sa11x0_pm_ops = {
+#ifdef CONFIG_PM_SLEEP
+	.suspend = mcp_sa11x0_suspend,
+	.freeze = mcp_sa11x0_suspend,
+	.poweroff = mcp_sa11x0_suspend,
+	.resume_noirq = mcp_sa11x0_resume,
+	.thaw_noirq = mcp_sa11x0_resume,
+	.restore_noirq = mcp_sa11x0_resume,
+#endif
+};
 
 static struct platform_driver mcp_sa11x0_driver = {
 	.probe		= mcp_sa11x0_probe,
 	.remove		= mcp_sa11x0_remove,
-	.suspend	= mcp_sa11x0_suspend,
-	.resume		= mcp_sa11x0_resume,
 	.driver		= {
-		.name	= "sa11x0-mcp",
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &mcp_sa11x0_pm_ops,
 	},
 };
 
@@ -259,6 +314,7 @@ static struct platform_driver mcp_sa11x0_driver = {
  */
 module_platform_driver(mcp_sa11x0_driver);
 
+MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c
index e075c11..8b8cf85 100644
--- a/drivers/mfd/s5m-core.c
+++ b/drivers/mfd/s5m-core.c
@@ -26,7 +26,27 @@
 #include <linux/mfd/s5m87xx/s5m-rtc.h>
 #include <linux/regmap.h>
 
-static struct mfd_cell s5m87xx_devs[] = {
+static struct mfd_cell s5m8751_devs[] = {
+	{
+		.name = "s5m8751-pmic",
+	}, {
+		.name = "s5m-charger",
+	}, {
+		.name = "s5m8751-codec",
+	},
+};
+
+static struct mfd_cell s5m8763_devs[] = {
+	{
+		.name = "s5m8763-pmic",
+	}, {
+		.name = "s5m-rtc",
+	}, {
+		.name = "s5m-charger",
+	},
+};
+
+static struct mfd_cell s5m8767_devs[] = {
 	{
 		.name = "s5m8767-pmic",
 	}, {
@@ -77,7 +97,8 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
 	int ret = 0;
 	int error;
 
-	s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL);
+	s5m87xx = devm_kzalloc(&i2c->dev, sizeof(struct s5m87xx_dev),
+				GFP_KERNEL);
 	if (s5m87xx == NULL)
 		return -ENOMEM;
 
@@ -105,16 +126,30 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c,
 	s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
 	i2c_set_clientdata(s5m87xx->rtc, s5m87xx);
 
-	if (pdata->cfg_pmic_irq)
+	if (pdata && pdata->cfg_pmic_irq)
 		pdata->cfg_pmic_irq();
 
 	s5m_irq_init(s5m87xx);
 
 	pm_runtime_set_active(s5m87xx->dev);
 
-	ret = mfd_add_devices(s5m87xx->dev, -1,
-				s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs),
-				NULL, 0);
+	switch (s5m87xx->device_type) {
+	case S5M8751X:
+		ret = mfd_add_devices(s5m87xx->dev, -1, s5m8751_devs,
+					ARRAY_SIZE(s5m8751_devs), NULL, 0);
+		break;
+	case S5M8763X:
+		ret = mfd_add_devices(s5m87xx->dev, -1, s5m8763_devs,
+					ARRAY_SIZE(s5m8763_devs), NULL, 0);
+		break;
+	case S5M8767X:
+		ret = mfd_add_devices(s5m87xx->dev, -1, s5m8767_devs,
+					ARRAY_SIZE(s5m8767_devs), NULL, 0);
+		break;
+	default:
+		/* If this happens the probe function is problem */
+		BUG();
+	}
 
 	if (ret < 0)
 		goto err;
@@ -126,7 +161,6 @@ err:
 	s5m_irq_exit(s5m87xx);
 	i2c_unregister_device(s5m87xx->rtc);
 	regmap_exit(s5m87xx->regmap);
-	kfree(s5m87xx);
 	return ret;
 }
 
@@ -138,7 +172,6 @@ static int s5m87xx_i2c_remove(struct i2c_client *i2c)
 	s5m_irq_exit(s5m87xx);
 	i2c_unregister_device(s5m87xx->rtc);
 	regmap_exit(s5m87xx->regmap);
-	kfree(s5m87xx);
 	return 0;
 }
 
diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c
index de76dfb..0236676 100644
--- a/drivers/mfd/s5m-irq.c
+++ b/drivers/mfd/s5m-irq.c
@@ -342,7 +342,10 @@ int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
 			s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
 			break;
 		default:
-			break;
+			dev_err(s5m87xx->dev,
+				"Unknown device type %d\n",
+				s5m87xx->device_type);
+			return -EINVAL;
 
 		}
 	}
@@ -444,7 +447,9 @@ int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
 		}
 		break;
 	default:
-		break;
+		dev_err(s5m87xx->dev,
+			"Unknown device type %d\n", s5m87xx->device_type);
+		return -EINVAL;
 	}
 
 	if (!s5m87xx->ono)
@@ -467,12 +472,15 @@ int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
 					IRQF_ONESHOT, "s5m87xx-ono", s5m87xx);
 		break;
 	default:
+		ret = -EINVAL;
 		break;
 	}
 
-	if (ret)
+	if (ret) {
 		dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
 			s5m87xx->ono, ret);
+		return ret;
+	}
 
 	return 0;
 }
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index e07947e..2dd8d49 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -298,6 +298,11 @@ static struct mfd_cell stmpe_gpio_cell = {
 	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
 };
 
+static struct mfd_cell stmpe_gpio_cell_noirq = {
+	.name		= "stmpe-gpio",
+	/* gpio cell resources consist of an irq only so no resources here */
+};
+
 /*
  * Keypad (1601, 2401, 2403)
  */
@@ -346,6 +351,13 @@ static struct stmpe_variant_block stmpe801_blocks[] = {
 	},
 };
 
+static struct stmpe_variant_block stmpe801_blocks_noirq[] = {
+	{
+		.cell	= &stmpe_gpio_cell_noirq,
+		.block	= STMPE_BLOCK_GPIO,
+	},
+};
+
 static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
 			   bool enable)
 {
@@ -367,6 +379,17 @@ static struct stmpe_variant_info stmpe801 = {
 	.enable		= stmpe801_enable,
 };
 
+static struct stmpe_variant_info stmpe801_noirq = {
+	.name		= "stmpe801",
+	.id_val		= STMPE801_ID,
+	.id_mask	= 0xffff,
+	.num_gpios	= 8,
+	.regs		= stmpe801_regs,
+	.blocks		= stmpe801_blocks_noirq,
+	.num_blocks	= ARRAY_SIZE(stmpe801_blocks_noirq),
+	.enable		= stmpe801_enable,
+};
+
 /*
  * Touchscreen (STMPE811 or STMPE610)
  */
@@ -712,7 +735,7 @@ static struct stmpe_variant_info stmpe2403 = {
 	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
 };
 
-static struct stmpe_variant_info *stmpe_variant_info[] = {
+static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
 	[STMPE610]	= &stmpe610,
 	[STMPE801]	= &stmpe801,
 	[STMPE811]	= &stmpe811,
@@ -721,6 +744,16 @@ static struct stmpe_variant_info *stmpe_variant_info[] = {
 	[STMPE2403]	= &stmpe2403,
 };
 
+/*
+ * These devices can be connected in a 'no-irq' configuration - the irq pin
+ * is not used and the device cannot interrupt the CPU. Here we only list
+ * devices which support this configuration - the driver will fail probing
+ * for any devices not listed here which are configured in this way.
+ */
+static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
+	[STMPE801]	= &stmpe801_noirq,
+};
+
 static irqreturn_t stmpe_irq(int irq, void *data)
 {
 	struct stmpe *stmpe = data;
@@ -864,7 +897,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
 	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
 	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
 	struct stmpe_variant_info *variant = stmpe->variant;
-	u8 icr;
+	u8 icr = 0;
 	unsigned int id;
 	u8 data[2];
 	int ret;
@@ -887,31 +920,33 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
 	if (ret)
 		return ret;
 
-	if (id == STMPE801_ID)
-		icr = STMPE801_REG_SYS_CTRL_INT_EN;
-	else
-		icr = STMPE_ICR_LSB_GIM;
-
-	/* STMPE801 doesn't support Edge interrupts */
-	if (id != STMPE801_ID) {
-		if (irq_trigger == IRQF_TRIGGER_FALLING ||
-				irq_trigger == IRQF_TRIGGER_RISING)
-			icr |= STMPE_ICR_LSB_EDGE;
-	}
-
-	if (irq_trigger == IRQF_TRIGGER_RISING ||
-			irq_trigger == IRQF_TRIGGER_HIGH) {
+	if (stmpe->irq >= 0) {
 		if (id == STMPE801_ID)
-			icr |= STMPE801_REG_SYS_CTRL_INT_HI;
+			icr = STMPE801_REG_SYS_CTRL_INT_EN;
 		else
-			icr |= STMPE_ICR_LSB_HIGH;
-	}
+			icr = STMPE_ICR_LSB_GIM;
 
-	if (stmpe->pdata->irq_invert_polarity) {
-		if (id == STMPE801_ID)
-			icr ^= STMPE801_REG_SYS_CTRL_INT_HI;
-		else
-			icr ^= STMPE_ICR_LSB_HIGH;
+		/* STMPE801 doesn't support Edge interrupts */
+		if (id != STMPE801_ID) {
+			if (irq_trigger == IRQF_TRIGGER_FALLING ||
+					irq_trigger == IRQF_TRIGGER_RISING)
+				icr |= STMPE_ICR_LSB_EDGE;
+		}
+
+		if (irq_trigger == IRQF_TRIGGER_RISING ||
+				irq_trigger == IRQF_TRIGGER_HIGH) {
+			if (id == STMPE801_ID)
+				icr |= STMPE801_REG_SYS_CTRL_INT_HI;
+			else
+				icr |= STMPE_ICR_LSB_HIGH;
+		}
+
+		if (stmpe->pdata->irq_invert_polarity) {
+			if (id == STMPE801_ID)
+				icr ^= STMPE801_REG_SYS_CTRL_INT_HI;
+			else
+				icr ^= STMPE_ICR_LSB_HIGH;
+		}
 	}
 
 	if (stmpe->pdata->autosleep) {
@@ -1001,19 +1036,38 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
 		stmpe->irq = ci->irq;
 	}
 
+	if (stmpe->irq < 0) {
+		/* use alternate variant info for no-irq mode, if supported */
+		dev_info(stmpe->dev,
+			"%s configured in no-irq mode by platform data\n",
+			stmpe->variant->name);
+		if (!stmpe_noirq_variant_info[stmpe->partnum]) {
+			dev_err(stmpe->dev,
+				"%s does not support no-irq mode!\n",
+				stmpe->variant->name);
+			ret = -ENODEV;
+			goto free_gpio;
+		}
+		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
+	}
+
 	ret = stmpe_chip_init(stmpe);
 	if (ret)
 		goto free_gpio;
 
-	ret = stmpe_irq_init(stmpe);
-	if (ret)
-		goto free_gpio;
+	if (stmpe->irq >= 0) {
+		ret = stmpe_irq_init(stmpe);
+		if (ret)
+			goto free_gpio;
 
-	ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
-			pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe);
-	if (ret) {
-		dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret);
-		goto out_removeirq;
+		ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
+				pdata->irq_trigger | IRQF_ONESHOT,
+				"stmpe", stmpe);
+		if (ret) {
+			dev_err(stmpe->dev, "failed to request IRQ: %d\n",
+					ret);
+			goto out_removeirq;
+		}
 	}
 
 	ret = stmpe_devices_init(stmpe);
@@ -1026,9 +1080,11 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
 
 out_removedevs:
 	mfd_remove_devices(stmpe->dev);
-	free_irq(stmpe->irq, stmpe);
+	if (stmpe->irq >= 0)
+		free_irq(stmpe->irq, stmpe);
 out_removeirq:
-	stmpe_irq_remove(stmpe);
+	if (stmpe->irq >= 0)
+		stmpe_irq_remove(stmpe);
 free_gpio:
 	if (pdata->irq_over_gpio)
 		gpio_free(pdata->irq_gpio);
@@ -1041,8 +1097,10 @@ int stmpe_remove(struct stmpe *stmpe)
 {
 	mfd_remove_devices(stmpe->dev);
 
-	free_irq(stmpe->irq, stmpe);
-	stmpe_irq_remove(stmpe);
+	if (stmpe->irq >= 0) {
+		free_irq(stmpe->irq, stmpe);
+		stmpe_irq_remove(stmpe);
+	}
 
 	if (stmpe->pdata->irq_over_gpio)
 		gpio_free(stmpe->pdata->irq_gpio);
@@ -1057,7 +1115,7 @@ static int stmpe_suspend(struct device *dev)
 {
 	struct stmpe *stmpe = dev_get_drvdata(dev);
 
-	if (device_may_wakeup(dev))
+	if (stmpe->irq >= 0 && device_may_wakeup(dev))
 		enable_irq_wake(stmpe->irq);
 
 	return 0;
@@ -1067,7 +1125,7 @@ static int stmpe_resume(struct device *dev)
 {
 	struct stmpe *stmpe = dev_get_drvdata(dev);
 
-	if (device_may_wakeup(dev))
+	if (stmpe->irq >= 0 && device_may_wakeup(dev))
 		disable_irq_wake(stmpe->irq);
 
 	return 0;
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
new file mode 100644
index 0000000..f7d854e
--- /dev/null
+++ b/drivers/mfd/tps65217.c
@@ -0,0 +1,242 @@
+/*
+ * tps65217.c
+ *
+ * TPS65217 chip family multi-function driver
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65217.h>
+
+/**
+ * tps65217_reg_read: Read a single tps65217 register.
+ *
+ * @tps: Device to read from.
+ * @reg: Register to read.
+ * @val: Contians the value
+ */
+int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
+			unsigned int *val)
+{
+	return regmap_read(tps->regmap, reg, val);
+}
+EXPORT_SYMBOL_GPL(tps65217_reg_read);
+
+/**
+ * tps65217_reg_write: Write a single tps65217 register.
+ *
+ * @tps65217: Device to write to.
+ * @reg: Register to write to.
+ * @val: Value to write.
+ * @level: Password protected level
+ */
+int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
+			unsigned int val, unsigned int level)
+{
+	int ret;
+	unsigned int xor_reg_val;
+
+	switch (level) {
+	case TPS65217_PROTECT_NONE:
+		return regmap_write(tps->regmap, reg, val);
+	case TPS65217_PROTECT_L1:
+		xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
+		ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
+							xor_reg_val);
+		if (ret < 0)
+			return ret;
+
+		return regmap_write(tps->regmap, reg, val);
+	case TPS65217_PROTECT_L2:
+		xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
+		ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
+							xor_reg_val);
+		if (ret < 0)
+			return ret;
+		ret = regmap_write(tps->regmap, reg, val);
+		if (ret < 0)
+			return ret;
+		ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
+							xor_reg_val);
+		if (ret < 0)
+			return ret;
+		return regmap_write(tps->regmap, reg, val);
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL_GPL(tps65217_reg_write);
+
+/**
+ * tps65217_update_bits: Modify bits w.r.t mask, val and level.
+ *
+ * @tps65217: Device to write to.
+ * @reg: Register to read-write to.
+ * @mask: Mask.
+ * @val: Value to write.
+ * @level: Password protected level
+ */
+int tps65217_update_bits(struct tps65217 *tps, unsigned int reg,
+		unsigned int mask, unsigned int val, unsigned int level)
+{
+	int ret;
+	unsigned int data;
+
+	ret = tps65217_reg_read(tps, reg, &data);
+	if (ret) {
+		dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
+		return ret;
+	}
+
+	data &= ~mask;
+	data |= val & mask;
+
+	ret = tps65217_reg_write(tps, reg, data, level);
+	if (ret)
+		dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
+
+	return ret;
+}
+
+int tps65217_set_bits(struct tps65217 *tps, unsigned int reg,
+		unsigned int mask, unsigned int val, unsigned int level)
+{
+	return tps65217_update_bits(tps, reg, mask, val, level);
+}
+EXPORT_SYMBOL_GPL(tps65217_set_bits);
+
+int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
+		unsigned int mask, unsigned int level)
+{
+	return tps65217_update_bits(tps, reg, mask, 0, level);
+}
+EXPORT_SYMBOL_GPL(tps65217_clear_bits);
+
+static struct regmap_config tps65217_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int __devinit tps65217_probe(struct i2c_client *client,
+				const struct i2c_device_id *ids)
+{
+	struct tps65217 *tps;
+	struct tps65217_board *pdata = client->dev.platform_data;
+	int i, ret;
+	unsigned int version;
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps)
+		return -ENOMEM;
+
+	tps->pdata = pdata;
+	tps->regmap = regmap_init_i2c(client, &tps65217_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		ret = PTR_ERR(tps->regmap);
+		dev_err(tps->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	i2c_set_clientdata(client, tps);
+	tps->dev = &client->dev;
+
+	ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);
+	if (ret < 0) {
+		dev_err(tps->dev, "Failed to read revision"
+					" register: %d\n", ret);
+		goto err_regmap;
+	}
+
+	dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
+			(version & TPS65217_CHIPID_CHIP_MASK) >> 4,
+			version & TPS65217_CHIPID_REV_MASK);
+
+	for (i = 0; i < TPS65217_NUM_REGULATOR; i++) {
+		struct platform_device *pdev;
+
+		pdev = platform_device_alloc("tps65217-pmic", i);
+		if (!pdev) {
+			dev_err(tps->dev, "Cannot create regulator %d\n", i);
+			continue;
+		}
+
+		pdev->dev.parent = tps->dev;
+		platform_device_add_data(pdev, &pdata->tps65217_init_data[i],
+					sizeof(pdata->tps65217_init_data[i]));
+		tps->regulator_pdev[i] = pdev;
+
+		platform_device_add(pdev);
+	}
+
+	return 0;
+
+err_regmap:
+	regmap_exit(tps->regmap);
+
+	return ret;
+}
+
+static int __devexit tps65217_remove(struct i2c_client *client)
+{
+	struct tps65217 *tps = i2c_get_clientdata(client);
+	int i;
+
+	for (i = 0; i < TPS65217_NUM_REGULATOR; i++)
+		platform_device_unregister(tps->regulator_pdev[i]);
+
+	regmap_exit(tps->regmap);
+
+	return 0;
+}
+
+static const struct i2c_device_id tps65217_id_table[] = {
+	{"tps65217", 0xF0},
+	{/* end of list */}
+};
+MODULE_DEVICE_TABLE(i2c, tps65217_id_table);
+
+static struct i2c_driver tps65217_driver = {
+	.driver		= {
+		.name	= "tps65217",
+	},
+	.id_table	= tps65217_id_table,
+	.probe		= tps65217_probe,
+	.remove		= __devexit_p(tps65217_remove),
+};
+
+static int __init tps65217_init(void)
+{
+	return i2c_add_driver(&tps65217_driver);
+}
+subsys_initcall(tps65217_init);
+
+static void __exit tps65217_exit(void)
+{
+	i2c_del_driver(&tps65217_driver);
+}
+module_exit(tps65217_exit);
+
+MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
+MODULE_DESCRIPTION("TPS65217 chip family multi-function driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c
index 95c0d79..c9ed5c0 100644
--- a/drivers/mfd/tps65910-irq.c
+++ b/drivers/mfd/tps65910-irq.c
@@ -145,12 +145,23 @@ static void tps65910_irq_disable(struct irq_data *data)
 	tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq));
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int tps65910_irq_set_wake(struct irq_data *data, unsigned int enable)
+{
+	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
+	return irq_set_irq_wake(tps65910->chip_irq, enable);
+}
+#else
+#define tps65910_irq_set_wake NULL
+#endif
+
 static struct irq_chip tps65910_irq_chip = {
 	.name = "tps65910",
 	.irq_bus_lock = tps65910_irq_lock,
 	.irq_bus_sync_unlock = tps65910_irq_sync_unlock,
 	.irq_disable = tps65910_irq_disable,
 	.irq_enable = tps65910_irq_enable,
+	.irq_set_wake = tps65910_irq_set_wake,
 };
 
 int tps65910_irq_init(struct tps65910 *tps65910, int irq,
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index 01cf501..4392f6b 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -168,7 +168,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
 		goto err;
 
 	init_data->irq = pmic_plat_data->irq;
-	init_data->irq_base = pmic_plat_data->irq;
+	init_data->irq_base = pmic_plat_data->irq_base;
 
 	tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base);
 
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 8ce3959..45ab243 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -115,8 +115,8 @@
 #define twl_has_watchdog()        false
 #endif
 
-#if defined(CONFIG_MFD_TWL4030_AUDIO) || defined(CONFIG_MFD_TWL4030_AUDIO_MODULE) ||\
-	defined(CONFIG_TWL6040_CORE) || defined(CONFIG_TWL6040_CORE_MODULE)
+#if defined(CONFIG_MFD_TWL4030_AUDIO) || \
+	defined(CONFIG_MFD_TWL4030_AUDIO_MODULE)
 #define twl_has_codec()	true
 #else
 #define twl_has_codec()	false
@@ -146,10 +146,11 @@
 #define SUB_CHIP_ID1 1
 #define SUB_CHIP_ID2 2
 #define SUB_CHIP_ID3 3
+#define SUB_CHIP_ID_INVAL 0xff
 
 #define TWL_MODULE_LAST TWL4030_MODULE_LAST
 
-#define TWL4030_NR_IRQS    8
+#define TWL4030_NR_IRQS    34 /* core:8, power:8, gpio: 18 */
 #define TWL6030_NR_IRQS    20
 
 /* Base Address defns for twl4030_map[] */
@@ -263,10 +264,6 @@ struct twl_client {
 
 static struct twl_client twl_modules[TWL_NUM_SLAVES];
 
-#ifdef CONFIG_IRQ_DOMAIN
-static struct irq_domain domain;
-#endif
-
 /* mapping the module id to slave id and base address */
 struct twl_mapping {
 	unsigned char sid;	/* Slave ID */
@@ -317,7 +314,7 @@ static struct twl_mapping twl6030_map[] = {
 	 * so they continue to match the order in this table.
 	 */
 	{ SUB_CHIP_ID1, TWL6030_BASEADD_USB },
-	{ SUB_CHIP_ID3, TWL6030_BASEADD_AUDIO },
+	{ SUB_CHIP_ID_INVAL, TWL6030_BASEADD_AUDIO },
 	{ SUB_CHIP_ID2, TWL6030_BASEADD_DIEID },
 	{ SUB_CHIP_ID2, TWL6030_BASEADD_RSV },
 	{ SUB_CHIP_ID1, TWL6030_BASEADD_PIH },
@@ -379,6 +376,11 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
 		return -EPERM;
 	}
 	sid = twl_map[mod_no].sid;
+	if (unlikely(sid == SUB_CHIP_ID_INVAL)) {
+		pr_err("%s: module %d is not part of the pmic\n",
+		       DRIVER_NAME, mod_no);
+		return -EINVAL;
+	}
 	twl = &twl_modules[sid];
 
 	mutex_lock(&twl->xfer_lock);
@@ -436,6 +438,11 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
 		return -EPERM;
 	}
 	sid = twl_map[mod_no].sid;
+	if (unlikely(sid == SUB_CHIP_ID_INVAL)) {
+		pr_err("%s: module %d is not part of the pmic\n",
+		       DRIVER_NAME, mod_no);
+		return -EINVAL;
+	}
 	twl = &twl_modules[sid];
 
 	mutex_lock(&twl->xfer_lock);
@@ -621,6 +628,8 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
 		unsigned num_consumers, unsigned long features)
 {
 	unsigned sub_chip_id;
+	struct twl_regulator_driver_data drv_data;
+
 	/* regulator framework demands init_data ... */
 	if (!pdata)
 		return NULL;
@@ -630,7 +639,19 @@ add_regulator_linked(int num, struct regulator_init_data *pdata,
 		pdata->num_consumer_supplies = num_consumers;
 	}
 
-	pdata->driver_data = (void *)features;
+	if (pdata->driver_data) {
+		/* If we have existing drv_data, just add the flags */
+		struct twl_regulator_driver_data *tmp;
+		tmp = pdata->driver_data;
+		tmp->features |= features;
+	} else {
+		/* add new driver data struct, used only during init */
+		drv_data.features = features;
+		drv_data.set_voltage = NULL;
+		drv_data.get_voltage = NULL;
+		drv_data.data = NULL;
+		pdata->driver_data = &drv_data;
+	}
 
 	/* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
 	sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
@@ -753,9 +774,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 
 		/* we need to connect regulators to this transceiver */
 		if (twl_has_regulator() && child) {
-			usb1v5.dev = child;
-			usb1v8.dev = child;
-			usb3v1.dev = child;
+			usb1v5.dev_name = dev_name(child);
+			usb1v8.dev_name = dev_name(child);
+			usb3v1.dev_name = dev_name(child);
 		}
 	}
 	if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
@@ -801,7 +822,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 			return PTR_ERR(child);
 		/* we need to connect regulators to this transceiver */
 		if (twl_has_regulator() && child)
-			usb3v3.dev = child;
+			usb3v3.dev_name = dev_name(child);
 	} else if (twl_has_regulator() && twl_class_is_6030()) {
 		if (features & TWL6025_SUBCLASS)
 			child = add_regulator(TWL6025_REG_LDOUSB,
@@ -836,15 +857,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_codec() && pdata->audio && twl_class_is_6030()) {
-		sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
-		child = add_child(sub_chip_id, "twl6040",
-				pdata->audio, sizeof(*pdata->audio),
-				false, 0, 0);
-		if (IS_ERR(child))
-			return PTR_ERR(child);
-	}
-
 	/* twl4030 regulators */
 	if (twl_has_regulator() && twl_class_is_4030()) {
 		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
@@ -1165,18 +1177,21 @@ int twl6030_exit_irq(void);
 
 static int twl_remove(struct i2c_client *client)
 {
-	unsigned i;
+	unsigned i, num_slaves;
 	int status;
 
-	if (twl_class_is_4030())
+	if (twl_class_is_4030()) {
 		status = twl4030_exit_irq();
-	else
+		num_slaves = TWL_NUM_SLAVES;
+	} else {
 		status = twl6030_exit_irq();
+		num_slaves = TWL_NUM_SLAVES - 1;
+	}
 
 	if (status < 0)
 		return status;
 
-	for (i = 0; i < TWL_NUM_SLAVES; i++) {
+	for (i = 0; i < num_slaves; i++) {
 		struct twl_client	*twl = &twl_modules[i];
 
 		if (twl->client && twl->client != client)
@@ -1192,7 +1207,7 @@ static int __devinit
 twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	int				status;
-	unsigned			i;
+	unsigned			i, num_slaves;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
 	struct device_node		*node = client->dev.of_node;
 	u8 temp;
@@ -1227,14 +1242,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	pdata->irq_base = status;
 	pdata->irq_end = pdata->irq_base + nr_irqs;
-
-#ifdef CONFIG_IRQ_DOMAIN
-	domain.irq_base = pdata->irq_base;
-	domain.nr_irq = nr_irqs;
-	domain.of_node = of_node_get(node);
-	domain.ops = &irq_domain_simple_ops;
-	irq_domain_add(&domain);
-#endif
+	irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
+			      &irq_domain_simple_ops, NULL);
 
 	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
 		dev_dbg(&client->dev, "can't talk I2C?\n");
@@ -1246,7 +1255,17 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		return -EBUSY;
 	}
 
-	for (i = 0; i < TWL_NUM_SLAVES; i++) {
+	if ((id->driver_data) & TWL6030_CLASS) {
+		twl_id = TWL6030_CLASS_ID;
+		twl_map = &twl6030_map[0];
+		num_slaves = TWL_NUM_SLAVES - 1;
+	} else {
+		twl_id = TWL4030_CLASS_ID;
+		twl_map = &twl4030_map[0];
+		num_slaves = TWL_NUM_SLAVES;
+	}
+
+	for (i = 0; i < num_slaves; i++) {
 		struct twl_client	*twl = &twl_modules[i];
 
 		twl->address = client->addr + i;
@@ -1265,13 +1284,6 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		mutex_init(&twl->xfer_lock);
 	}
 	inuse = true;
-	if ((id->driver_data) & TWL6030_CLASS) {
-		twl_id = TWL6030_CLASS_ID;
-		twl_map = &twl6030_map[0];
-	} else {
-		twl_id = TWL4030_CLASS_ID;
-		twl_map = &twl4030_map[0];
-	}
 
 	/* setup clock framework */
 	clocks_init(&client->dev, pdata->clock);
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b69bb51..b31f920 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -59,7 +59,6 @@
 #define REG_PIH_ISR_P2			0x02
 #define REG_PIH_SIR			0x03	/* for testing */
 
-
 /* Linux could (eventually) use either IRQ line */
 static int irq_line;
 
@@ -111,7 +110,8 @@ static int nr_sih_modules;
 #define TWL4030_MODULE_INT_PWR		TWL4030_MODULE_INT
 
 
-/* Order in this table matches order in PIH_ISR.  That is,
+/*
+ * Order in this table matches order in PIH_ISR.  That is,
  * BIT(n) in PIH_ISR is sih_modules[n].
  */
 /* sih_modules_twl4030 is used both in twl4030 and twl5030 */
@@ -309,6 +309,7 @@ static irqreturn_t handle_twl4030_pih(int irq, void *devid)
 
 	return IRQ_HANDLED;
 }
+
 /*----------------------------------------------------------------------*/
 
 /*
@@ -337,7 +338,6 @@ static int twl4030_init_sih_modules(unsigned line)
 	memset(buf, 0xff, sizeof buf);
 	sih = sih_modules;
 	for (i = 0; i < nr_sih_modules; i++, sih++) {
-
 		/* skip USB -- it's funky */
 		if (!sih->bytes_ixr)
 			continue;
@@ -352,7 +352,8 @@ static int twl4030_init_sih_modules(unsigned line)
 			pr_err("twl4030: err %d initializing %s %s\n",
 					status, sih->name, "IMR");
 
-		/* Maybe disable "exclusive" mode; buffer second pending irq;
+		/*
+		 * Maybe disable "exclusive" mode; buffer second pending irq;
 		 * set Clear-On-Read (COR) bit.
 		 *
 		 * NOTE that sometimes COR polarity is documented as being
@@ -382,7 +383,8 @@ static int twl4030_init_sih_modules(unsigned line)
 		if (sih->irq_lines <= line)
 			continue;
 
-		/* Clear pending interrupt status.  Either the read was
+		/*
+		 * Clear pending interrupt status.  Either the read was
 		 * enough, or we need to write those bits.  Repeat, in
 		 * case an IRQ is pending (PENDDIS=0) ... that's not
 		 * uncommon with PWR_INT.PWRON.
@@ -398,7 +400,8 @@ static int twl4030_init_sih_modules(unsigned line)
 				status = twl_i2c_write(sih->module, buf,
 					sih->mask[line].isr_offset,
 					sih->bytes_ixr);
-			/* else COR=1 means read sufficed.
+			/*
+			 * else COR=1 means read sufficed.
 			 * (for most SIH modules...)
 			 */
 		}
@@ -410,7 +413,8 @@ static int twl4030_init_sih_modules(unsigned line)
 static inline void activate_irq(int irq)
 {
 #ifdef CONFIG_ARM
-	/* ARM requires an extra step to clear IRQ_NOREQUEST, which it
+	/*
+	 * ARM requires an extra step to clear IRQ_NOREQUEST, which it
 	 * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
 	 */
 	set_irq_flags(irq, IRQF_VALID);
@@ -622,9 +626,7 @@ static irqreturn_t handle_twl4030_sih(int irq, void *data)
 
 static unsigned twl4030_irq_next;
 
-/* returns the first IRQ used by this SIH bank,
- * or negative errno
- */
+/* returns the first IRQ used by this SIH bank, or negative errno */
 int twl4030_sih_setup(int module)
 {
 	int			sih_mod;
@@ -688,7 +690,6 @@ int twl4030_sih_setup(int module)
 
 /* FIXME need a call to reverse twl4030_sih_setup() ... */
 
-
 /*----------------------------------------------------------------------*/
 
 /* FIXME pass in which interrupt line we'll use ... */
@@ -711,7 +712,8 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
 
 	twl4030_irq_base = irq_base;
 
-	/* install an irq handler for each of the SIH modules;
+	/*
+	 * install an irq handler for each of the SIH modules;
 	 * clone dummy irq_chip since PIH can't *do* anything
 	 */
 	twl4030_irq_chip = dummy_irq_chip;
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index b2d8e51..58c95b4 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -27,19 +27,24 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
+#include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
-#include <linux/i2c/twl.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/twl6040.h>
+#include <linux/regulator/consumer.h>
 
 #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
+#define TWL6040_NUM_SUPPLIES	(2)
 
 int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
 {
 	int ret;
-	u8 val = 0;
+	unsigned int val;
 
 	mutex_lock(&twl6040->io_mutex);
 	/* Vibra control registers from cache */
@@ -47,7 +52,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg)
 		     reg == TWL6040_REG_VIBCTLR)) {
 		val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)];
 	} else {
-		ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
+		ret = regmap_read(twl6040->regmap, reg, &val);
 		if (ret < 0) {
 			mutex_unlock(&twl6040->io_mutex);
 			return ret;
@@ -64,7 +69,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val)
 	int ret;
 
 	mutex_lock(&twl6040->io_mutex);
-	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
+	ret = regmap_write(twl6040->regmap, reg, val);
 	/* Cache the vibra control registers */
 	if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR)
 		twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val;
@@ -77,16 +82,9 @@ EXPORT_SYMBOL(twl6040_reg_write);
 int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
 {
 	int ret;
-	u8 val;
 
 	mutex_lock(&twl6040->io_mutex);
-	ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
-	if (ret)
-		goto out;
-
-	val |= mask;
-	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+	ret = regmap_update_bits(twl6040->regmap, reg, mask, mask);
 	mutex_unlock(&twl6040->io_mutex);
 	return ret;
 }
@@ -95,16 +93,9 @@ EXPORT_SYMBOL(twl6040_set_bits);
 int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask)
 {
 	int ret;
-	u8 val;
 
 	mutex_lock(&twl6040->io_mutex);
-	ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg);
-	if (ret)
-		goto out;
-
-	val &= ~mask;
-	ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg);
-out:
+	ret = regmap_update_bits(twl6040->regmap, reg, mask, 0);
 	mutex_unlock(&twl6040->io_mutex);
 	return ret;
 }
@@ -494,32 +485,81 @@ static struct resource twl6040_codec_rsrc[] = {
 	},
 };
 
-static int __devinit twl6040_probe(struct platform_device *pdev)
+static bool twl6040_readable_reg(struct device *dev, unsigned int reg)
 {
-	struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+	/* Register 0 is not readable */
+	if (!reg)
+		return false;
+	return true;
+}
+
+static struct regmap_config twl6040_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TWL6040_REG_STATUS, /* 0x2e */
+
+	.readable_reg = twl6040_readable_reg,
+};
+
+static int __devinit twl6040_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
+{
+	struct twl6040_platform_data *pdata = client->dev.platform_data;
 	struct twl6040 *twl6040;
 	struct mfd_cell *cell = NULL;
 	int ret, children = 0;
 
 	if (!pdata) {
-		dev_err(&pdev->dev, "Platform data is missing\n");
+		dev_err(&client->dev, "Platform data is missing\n");
 		return -EINVAL;
 	}
 
 	/* In order to operate correctly we need valid interrupt config */
-	if (!pdata->naudint_irq || !pdata->irq_base) {
-		dev_err(&pdev->dev, "Invalid IRQ configuration\n");
+	if (!client->irq || !pdata->irq_base) {
+		dev_err(&client->dev, "Invalid IRQ configuration\n");
 		return -EINVAL;
 	}
 
-	twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL);
-	if (!twl6040)
-		return -ENOMEM;
+	twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040),
+			       GFP_KERNEL);
+	if (!twl6040) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	twl6040->supplies = devm_kzalloc(&client->dev,
+					 sizeof(struct regulator_bulk_data) *
+					 TWL6040_NUM_SUPPLIES, GFP_KERNEL);
+	if (!twl6040->supplies) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config);
+	if (IS_ERR(twl6040->regmap)) {
+		ret = PTR_ERR(twl6040->regmap);
+		goto err;
+	}
 
-	platform_set_drvdata(pdev, twl6040);
+	i2c_set_clientdata(client, twl6040);
 
-	twl6040->dev = &pdev->dev;
-	twl6040->irq = pdata->naudint_irq;
+	twl6040->supplies[0].supply = "vio";
+	twl6040->supplies[1].supply = "v2v1";
+	ret = regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES,
+				 twl6040->supplies);
+	if (ret != 0) {
+		dev_err(&client->dev, "Failed to get supplies: %d\n", ret);
+		goto regulator_get_err;
+	}
+
+	ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
+	if (ret != 0) {
+		dev_err(&client->dev, "Failed to enable supplies: %d\n", ret);
+		goto power_err;
+	}
+
+	twl6040->dev = &client->dev;
+	twl6040->irq = client->irq;
 	twl6040->irq_base = pdata->irq_base;
 
 	mutex_init(&twl6040->mutex);
@@ -538,13 +578,13 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
 		ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW,
 				       "audpwron");
 		if (ret)
-			goto gpio1_err;
+			goto gpio_err;
 	}
 
 	/* codec interrupt */
 	ret = twl6040_irq_init(twl6040);
 	if (ret)
-		goto gpio2_err;
+		goto irq_init_err;
 
 	ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY,
 				   NULL, twl6040_naudint_handler, 0,
@@ -588,12 +628,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
 	}
 
 	if (children) {
-		ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells,
+		ret = mfd_add_devices(&client->dev, -1, twl6040->cells,
 				      children, NULL, 0);
 		if (ret)
 			goto mfd_err;
 	} else {
-		dev_err(&pdev->dev, "No platform data found for children\n");
+		dev_err(&client->dev, "No platform data found for children\n");
 		ret = -ENODEV;
 		goto mfd_err;
 	}
@@ -604,18 +644,23 @@ mfd_err:
 	free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
 irq_err:
 	twl6040_irq_exit(twl6040);
-gpio2_err:
+irq_init_err:
 	if (gpio_is_valid(twl6040->audpwron))
 		gpio_free(twl6040->audpwron);
-gpio1_err:
-	platform_set_drvdata(pdev, NULL);
-	kfree(twl6040);
+gpio_err:
+	regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
+power_err:
+	regulator_bulk_free(TWL6040_NUM_SUPPLIES, twl6040->supplies);
+regulator_get_err:
+	i2c_set_clientdata(client, NULL);
+	regmap_exit(twl6040->regmap);
+err:
 	return ret;
 }
 
-static int __devexit twl6040_remove(struct platform_device *pdev)
+static int __devexit twl6040_remove(struct i2c_client *client)
 {
-	struct twl6040 *twl6040 = platform_get_drvdata(pdev);
+	struct twl6040 *twl6040 = i2c_get_clientdata(client);
 
 	if (twl6040->power_count)
 		twl6040_power(twl6040, 0);
@@ -626,23 +671,33 @@ static int __devexit twl6040_remove(struct platform_device *pdev)
 	free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040);
 	twl6040_irq_exit(twl6040);
 
-	mfd_remove_devices(&pdev->dev);
-	platform_set_drvdata(pdev, NULL);
-	kfree(twl6040);
+	mfd_remove_devices(&client->dev);
+	i2c_set_clientdata(client, NULL);
+	regmap_exit(twl6040->regmap);
+
+	regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies);
+	regulator_bulk_free(TWL6040_NUM_SUPPLIES, twl6040->supplies);
 
 	return 0;
 }
 
-static struct platform_driver twl6040_driver = {
+static const struct i2c_device_id twl6040_i2c_id[] = {
+	{ "twl6040", 0, },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id);
+
+static struct i2c_driver twl6040_driver = {
+	.driver = {
+		.name = "twl6040",
+		.owner = THIS_MODULE,
+	},
 	.probe		= twl6040_probe,
 	.remove		= __devexit_p(twl6040_remove),
-	.driver		= {
-		.owner	= THIS_MODULE,
-		.name	= "twl6040",
-	},
+	.id_table	= twl6040_i2c_id,
 };
 
-module_platform_driver(twl6040_driver);
+module_i2c_driver(twl6040_driver);
 
 MODULE_DESCRIPTION("TWL6040 MFD");
 MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c
index cea9da6..b63c075 100644
--- a/drivers/mfd/ucb1x00-assabet.c
+++ b/drivers/mfd/ucb1x00-assabet.c
@@ -11,14 +11,15 @@
  */
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
 #include <linux/fs.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
 #include <linux/proc_fs.h>
-#include <linux/device.h>
 #include <linux/mfd/ucb1x00.h>
 
-#include <mach/dma.h>
-
-
 #define UCB1X00_ATTR(name,input)\
 static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \
 			   char *buf)	\
@@ -38,14 +39,45 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
 
 static int ucb1x00_assabet_add(struct ucb1x00_dev *dev)
 {
-	device_create_file(&dev->ucb->dev, &dev_attr_vbatt);
-	device_create_file(&dev->ucb->dev, &dev_attr_vcharger);
-	device_create_file(&dev->ucb->dev, &dev_attr_batt_temp);
+	struct ucb1x00 *ucb = dev->ucb;
+	struct platform_device *pdev;
+	struct gpio_keys_platform_data keys;
+	static struct gpio_keys_button buttons[6];
+	unsigned i;
+
+	memset(buttons, 0, sizeof(buttons));
+	memset(&keys, 0, sizeof(keys));
+
+	for (i = 0; i < ARRAY_SIZE(buttons); i++) {
+		buttons[i].code = BTN_0 + i;
+		buttons[i].gpio = ucb->gpio.base + i;
+		buttons[i].type = EV_KEY;
+		buttons[i].can_disable = true;
+	}
+
+	keys.buttons = buttons;
+	keys.nbuttons = ARRAY_SIZE(buttons);
+	keys.poll_interval = 50;
+	keys.name = "ucb1x00";
+
+	pdev = platform_device_register_data(&ucb->dev, "gpio-keys", -1,
+		&keys, sizeof(keys));
+
+	device_create_file(&ucb->dev, &dev_attr_vbatt);
+	device_create_file(&ucb->dev, &dev_attr_vcharger);
+	device_create_file(&ucb->dev, &dev_attr_batt_temp);
+
+	dev->priv = pdev;
 	return 0;
 }
 
 static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev)
 {
+	struct platform_device *pdev = dev->priv;
+
+	if (!IS_ERR(pdev))
+		platform_device_unregister(pdev);
+
 	device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp);
 	device_remove_file(&dev->ucb->dev, &dev_attr_vcharger);
 	device_remove_file(&dev->ucb->dev, &dev_attr_vbatt);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index febc90c..70f02da 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -23,14 +23,12 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/device.h>
 #include <linux/mutex.h>
 #include <linux/mfd/ucb1x00.h>
+#include <linux/pm.h>
 #include <linux/gpio.h>
-#include <linux/semaphore.h>
-
-#include <mach/dma.h>
-#include <mach/hardware.h>
 
 static DEFINE_MUTEX(ucb1x00_mutex);
 static LIST_HEAD(ucb1x00_drivers);
@@ -102,7 +100,7 @@ void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
  *	ucb1x00_enable must have been called to enable the comms
  *	before using this function.
  *
- *	This function does not take any semaphores or spinlocks.
+ *	This function does not take any mutexes or spinlocks.
  */
 unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
 {
@@ -120,14 +118,22 @@ static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 	else
 		ucb->io_out &= ~(1 << offset);
 
+	ucb1x00_enable(ucb);
 	ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
+	ucb1x00_disable(ucb);
 	spin_unlock_irqrestore(&ucb->io_lock, flags);
 }
 
 static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
 	struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
-	return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset);
+	unsigned val;
+
+	ucb1x00_enable(ucb);
+	val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
+	ucb1x00_disable(ucb);
+
+	return val & (1 << offset);
 }
 
 static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -137,7 +143,9 @@ static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 
 	spin_lock_irqsave(&ucb->io_lock, flags);
 	ucb->io_dir &= ~(1 << offset);
+	ucb1x00_enable(ucb);
 	ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+	ucb1x00_disable(ucb);
 	spin_unlock_irqrestore(&ucb->io_lock, flags);
 
 	return 0;
@@ -157,6 +165,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
 	else
 		ucb->io_out &= ~mask;
 
+	ucb1x00_enable(ucb);
 	if (old != ucb->io_out)
 		ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
 
@@ -164,11 +173,19 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
 		ucb->io_dir |= mask;
 		ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
 	}
+	ucb1x00_disable(ucb);
 	spin_unlock_irqrestore(&ucb->io_lock, flags);
 
 	return 0;
 }
 
+static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio);
+
+	return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO;
+}
+
 /*
  * UCB1300 data sheet says we must:
  *  1. enable ADC	=> 5us (including reference startup time)
@@ -186,7 +203,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
  *	Any code wishing to use the ADC converter must call this
  *	function prior to using it.
  *
- *	This function takes the ADC semaphore to prevent two or more
+ *	This function takes the ADC mutex to prevent two or more
  *	concurrent uses, and therefore may sleep.  As a result, it
  *	can only be called from process context, not interrupt
  *	context.
@@ -196,7 +213,7 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset
  */
 void ucb1x00_adc_enable(struct ucb1x00 *ucb)
 {
-	down(&ucb->adc_sem);
+	mutex_lock(&ucb->adc_mutex);
 
 	ucb->adc_cr |= UCB_ADC_ENA;
 
@@ -218,7 +235,7 @@ void ucb1x00_adc_enable(struct ucb1x00 *ucb)
  *	complete (2 frames max without sync).
  *
  *	If called for a synchronised ADC conversion, it may sleep
- *	with the ADC semaphore held.
+ *	with the ADC mutex held.
  */
 unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
 {
@@ -246,7 +263,7 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
  *	ucb1x00_adc_disable - disable the ADC converter
  *	@ucb: UCB1x00 structure describing chip
  *
- *	Disable the ADC converter and release the ADC semaphore.
+ *	Disable the ADC converter and release the ADC mutex.
  */
 void ucb1x00_adc_disable(struct ucb1x00 *ucb)
 {
@@ -254,7 +271,7 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
 	ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
 	ucb1x00_disable(ucb);
 
-	up(&ucb->adc_sem);
+	mutex_unlock(&ucb->adc_mutex);
 }
 
 /*
@@ -265,10 +282,9 @@ void ucb1x00_adc_disable(struct ucb1x00 *ucb)
  * SIBCLK to talk to the chip.  We leave the clock running until
  * we have finished processing all interrupts from the chip.
  */
-static irqreturn_t ucb1x00_irq(int irqnr, void *devid)
+static void ucb1x00_irq(unsigned int irq, struct irq_desc *desc)
 {
-	struct ucb1x00 *ucb = devid;
-	struct ucb1x00_irq *irq;
+	struct ucb1x00 *ucb = irq_desc_get_handler_data(desc);
 	unsigned int isr, i;
 
 	ucb1x00_enable(ucb);
@@ -276,157 +292,104 @@ static irqreturn_t ucb1x00_irq(int irqnr, void *devid)
 	ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
 	ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
 
-	for (i = 0, irq = ucb->irq_handler; i < 16 && isr; i++, isr >>= 1, irq++)
-		if (isr & 1 && irq->fn)
-			irq->fn(i, irq->devid);
+	for (i = 0; i < 16 && isr; i++, isr >>= 1, irq++)
+		if (isr & 1)
+			generic_handle_irq(ucb->irq_base + i);
 	ucb1x00_disable(ucb);
-
-	return IRQ_HANDLED;
 }
 
-/**
- *	ucb1x00_hook_irq - hook a UCB1x00 interrupt
- *	@ucb:   UCB1x00 structure describing chip
- *	@idx:   interrupt index
- *	@fn:    function to call when interrupt is triggered
- *	@devid: device id to pass to interrupt handler
- *
- *	Hook the specified interrupt.  You can only register one handler
- *	for each interrupt source.  The interrupt source is not enabled
- *	by this function; use ucb1x00_enable_irq instead.
- *
- *	Interrupt handlers will be called with other interrupts enabled.
- *
- *	Returns zero on success, or one of the following errors:
- *	 -EINVAL if the interrupt index is invalid
- *	 -EBUSY if the interrupt has already been hooked
- */
-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
+static void ucb1x00_irq_update(struct ucb1x00 *ucb, unsigned mask)
 {
-	struct ucb1x00_irq *irq;
-	int ret = -EINVAL;
-
-	if (idx < 16) {
-		irq = ucb->irq_handler + idx;
-		ret = -EBUSY;
-
-		spin_lock_irq(&ucb->lock);
-		if (irq->fn == NULL) {
-			irq->devid = devid;
-			irq->fn = fn;
-			ret = 0;
-		}
-		spin_unlock_irq(&ucb->lock);
-	}
-	return ret;
+	ucb1x00_enable(ucb);
+	if (ucb->irq_ris_enbl & mask)
+		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+				  ucb->irq_mask);
+	if (ucb->irq_fal_enbl & mask)
+		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+				  ucb->irq_mask);
+	ucb1x00_disable(ucb);
 }
 
-/**
- *	ucb1x00_enable_irq - enable an UCB1x00 interrupt source
- *	@ucb: UCB1x00 structure describing chip
- *	@idx: interrupt index
- *	@edges: interrupt edges to enable
- *
- *	Enable the specified interrupt to trigger on %UCB_RISING,
- *	%UCB_FALLING or both edges.  The interrupt should have been
- *	hooked by ucb1x00_hook_irq.
- */
-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
+static void ucb1x00_irq_noop(struct irq_data *data)
 {
-	unsigned long flags;
+}
 
-	if (idx < 16) {
-		spin_lock_irqsave(&ucb->lock, flags);
+static void ucb1x00_irq_mask(struct irq_data *data)
+{
+	struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+	unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-		ucb1x00_enable(ucb);
-		if (edges & UCB_RISING) {
-			ucb->irq_ris_enbl |= 1 << idx;
-			ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-		}
-		if (edges & UCB_FALLING) {
-			ucb->irq_fal_enbl |= 1 << idx;
-			ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-		}
-		ucb1x00_disable(ucb);
-		spin_unlock_irqrestore(&ucb->lock, flags);
-	}
+	raw_spin_lock(&ucb->irq_lock);
+	ucb->irq_mask &= ~mask;
+	ucb1x00_irq_update(ucb, mask);
+	raw_spin_unlock(&ucb->irq_lock);
 }
 
-/**
- *	ucb1x00_disable_irq - disable an UCB1x00 interrupt source
- *	@ucb: UCB1x00 structure describing chip
- *	@edges: interrupt edges to disable
- *
- *	Disable the specified interrupt triggering on the specified
- *	(%UCB_RISING, %UCB_FALLING or both) edges.
- */
-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
+static void ucb1x00_irq_unmask(struct irq_data *data)
 {
-	unsigned long flags;
+	struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+	unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-	if (idx < 16) {
-		spin_lock_irqsave(&ucb->lock, flags);
-
-		ucb1x00_enable(ucb);
-		if (edges & UCB_RISING) {
-			ucb->irq_ris_enbl &= ~(1 << idx);
-			ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-		}
-		if (edges & UCB_FALLING) {
-			ucb->irq_fal_enbl &= ~(1 << idx);
-			ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-		}
-		ucb1x00_disable(ucb);
-		spin_unlock_irqrestore(&ucb->lock, flags);
-	}
+	raw_spin_lock(&ucb->irq_lock);
+	ucb->irq_mask |= mask;
+	ucb1x00_irq_update(ucb, mask);
+	raw_spin_unlock(&ucb->irq_lock);
 }
 
-/**
- *	ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
- *	@ucb: UCB1x00 structure describing chip
- *	@idx: interrupt index
- *	@devid: device id.
- *
- *	Disable the interrupt source and remove the handler.  devid must
- *	match the devid passed when hooking the interrupt.
- *
- *	Returns zero on success, or one of the following errors:
- *	 -EINVAL if the interrupt index is invalid
- *	 -ENOENT if devid does not match
- */
-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
+static int ucb1x00_irq_set_type(struct irq_data *data, unsigned int type)
 {
-	struct ucb1x00_irq *irq;
-	int ret;
+	struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+	unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-	if (idx >= 16)
-		goto bad;
+	raw_spin_lock(&ucb->irq_lock);
+	if (type & IRQ_TYPE_EDGE_RISING)
+		ucb->irq_ris_enbl |= mask;
+	else
+		ucb->irq_ris_enbl &= ~mask;
 
-	irq = ucb->irq_handler + idx;
-	ret = -ENOENT;
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		ucb->irq_fal_enbl |= mask;
+	else
+		ucb->irq_fal_enbl &= ~mask;
+	if (ucb->irq_mask & mask) {
+		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+				  ucb->irq_mask);
+		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+				  ucb->irq_mask);
+	}
+	raw_spin_unlock(&ucb->irq_lock);
 
-	spin_lock_irq(&ucb->lock);
-	if (irq->devid == devid) {
-		ucb->irq_ris_enbl &= ~(1 << idx);
-		ucb->irq_fal_enbl &= ~(1 << idx);
+	return 0;
+}
 
-		ucb1x00_enable(ucb);
-		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-		ucb1x00_disable(ucb);
+static int ucb1x00_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+	struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data);
+	struct ucb1x00_plat_data *pdata = ucb->mcp->attached_device.platform_data;
+	unsigned mask = 1 << (data->irq - ucb->irq_base);
 
-		irq->fn = NULL;
-		irq->devid = NULL;
-		ret = 0;
-	}
-	spin_unlock_irq(&ucb->lock);
-	return ret;
+	if (!pdata || !pdata->can_wakeup)
+		return -EINVAL;
 
-bad:
-	printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx);
-	return -EINVAL;
+	raw_spin_lock(&ucb->irq_lock);
+	if (on)
+		ucb->irq_wake |= mask;
+	else
+		ucb->irq_wake &= ~mask;
+	raw_spin_unlock(&ucb->irq_lock);
+
+	return 0;
 }
 
+static struct irq_chip ucb1x00_irqchip = {
+	.name = "ucb1x00",
+	.irq_ack = ucb1x00_irq_noop,
+	.irq_mask = ucb1x00_irq_mask,
+	.irq_unmask = ucb1x00_irq_unmask,
+	.irq_set_type = ucb1x00_irq_set_type,
+	.irq_set_wake = ucb1x00_irq_set_wake,
+};
+
 static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
 {
 	struct ucb1x00_dev *dev;
@@ -440,8 +403,8 @@ static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv)
 		ret = drv->add(dev);
 
 		if (ret == 0) {
-			list_add(&dev->dev_node, &ucb->devs);
-			list_add(&dev->drv_node, &drv->devs);
+			list_add_tail(&dev->dev_node, &ucb->devs);
+			list_add_tail(&dev->drv_node, &drv->devs);
 		} else {
 			kfree(dev);
 		}
@@ -533,98 +496,126 @@ static struct class ucb1x00_class = {
 
 static int ucb1x00_probe(struct mcp *mcp)
 {
-	struct ucb1x00 *ucb;
+	struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
 	struct ucb1x00_driver *drv;
-	unsigned int id;
+	struct ucb1x00 *ucb;
+	unsigned id, i, irq_base;
 	int ret = -ENODEV;
-	int temp;
+
+	/* Tell the platform to deassert the UCB1x00 reset */
+	if (pdata && pdata->reset)
+		pdata->reset(UCB_RST_PROBE);
 
 	mcp_enable(mcp);
 	id = mcp_reg_read(mcp, UCB_ID);
+	mcp_disable(mcp);
 
 	if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
 		printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
-		goto err_disable;
+		goto out;
 	}
 
 	ucb = kzalloc(sizeof(struct ucb1x00), GFP_KERNEL);
 	ret = -ENOMEM;
 	if (!ucb)
-		goto err_disable;
-
+		goto out;
 
+	device_initialize(&ucb->dev);
 	ucb->dev.class = &ucb1x00_class;
 	ucb->dev.parent = &mcp->attached_device;
 	dev_set_name(&ucb->dev, "ucb1x00");
 
-	spin_lock_init(&ucb->lock);
+	raw_spin_lock_init(&ucb->irq_lock);
 	spin_lock_init(&ucb->io_lock);
-	sema_init(&ucb->adc_sem, 1);
+	mutex_init(&ucb->adc_mutex);
 
 	ucb->id  = id;
 	ucb->mcp = mcp;
+
+	ret = device_add(&ucb->dev);
+	if (ret)
+		goto err_dev_add;
+
+	ucb1x00_enable(ucb);
 	ucb->irq = ucb1x00_detect_irq(ucb);
+	ucb1x00_disable(ucb);
 	if (ucb->irq == NO_IRQ) {
-		printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
+		dev_err(&ucb->dev, "IRQ probe failed\n");
 		ret = -ENODEV;
-		goto err_free;
+		goto err_no_irq;
 	}
 
 	ucb->gpio.base = -1;
-	if (mcp->gpio_base != 0) {
+	irq_base = pdata ? pdata->irq_base : 0;
+	ucb->irq_base = irq_alloc_descs(-1, irq_base, 16, -1);
+	if (ucb->irq_base < 0) {
+		dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n",
+			ucb->irq_base);
+		goto err_irq_alloc;
+	}
+
+	for (i = 0; i < 16; i++) {
+		unsigned irq = ucb->irq_base + i;
+
+		irq_set_chip_and_handler(irq, &ucb1x00_irqchip, handle_edge_irq);
+		irq_set_chip_data(irq, ucb);
+		set_irq_flags(irq, IRQF_VALID | IRQ_NOREQUEST);
+	}
+
+	irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING);
+	irq_set_handler_data(ucb->irq, ucb);
+	irq_set_chained_handler(ucb->irq, ucb1x00_irq);
+
+	if (pdata && pdata->gpio_base) {
 		ucb->gpio.label = dev_name(&ucb->dev);
-		ucb->gpio.base = mcp->gpio_base;
+		ucb->gpio.dev = &ucb->dev;
+		ucb->gpio.owner = THIS_MODULE;
+		ucb->gpio.base = pdata->gpio_base;
 		ucb->gpio.ngpio = 10;
 		ucb->gpio.set = ucb1x00_gpio_set;
 		ucb->gpio.get = ucb1x00_gpio_get;
 		ucb->gpio.direction_input = ucb1x00_gpio_direction_input;
 		ucb->gpio.direction_output = ucb1x00_gpio_direction_output;
+		ucb->gpio.to_irq = ucb1x00_to_irq;
 		ret = gpiochip_add(&ucb->gpio);
 		if (ret)
-			goto err_free;
+			goto err_gpio_add;
 	} else
 		dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
 
-	ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
-			  "UCB1x00", ucb);
-	if (ret) {
-		printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
-			ucb->irq, ret);
-		goto err_gpio;
-	}
-
 	mcp_set_drvdata(mcp, ucb);
 
-	ret = device_register(&ucb->dev);
-	if (ret)
-		goto err_irq;
-
+	if (pdata)
+		device_set_wakeup_capable(&ucb->dev, pdata->can_wakeup);
 
 	INIT_LIST_HEAD(&ucb->devs);
 	mutex_lock(&ucb1x00_mutex);
-	list_add(&ucb->node, &ucb1x00_devices);
+	list_add_tail(&ucb->node, &ucb1x00_devices);
 	list_for_each_entry(drv, &ucb1x00_drivers, node) {
 		ucb1x00_add_dev(ucb, drv);
 	}
 	mutex_unlock(&ucb1x00_mutex);
 
-	goto out;
+	return ret;
 
- err_irq:
-	free_irq(ucb->irq, ucb);
- err_gpio:
-	if (ucb->gpio.base != -1)
-		temp = gpiochip_remove(&ucb->gpio);
- err_free:
-	kfree(ucb);
- err_disable:
-	mcp_disable(mcp);
+ err_gpio_add:
+	irq_set_chained_handler(ucb->irq, NULL);
+ err_irq_alloc:
+	if (ucb->irq_base > 0)
+		irq_free_descs(ucb->irq_base, 16);
+ err_no_irq:
+	device_del(&ucb->dev);
+ err_dev_add:
+	put_device(&ucb->dev);
  out:
+	if (pdata && pdata->reset)
+		pdata->reset(UCB_RST_PROBE_FAIL);
 	return ret;
 }
 
 static void ucb1x00_remove(struct mcp *mcp)
 {
+	struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data;
 	struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
 	struct list_head *l, *n;
 	int ret;
@@ -643,8 +634,12 @@ static void ucb1x00_remove(struct mcp *mcp)
 			dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret);
 	}
 
-	free_irq(ucb->irq, ucb);
+	irq_set_chained_handler(ucb->irq, NULL);
+	irq_free_descs(ucb->irq_base, 16);
 	device_unregister(&ucb->dev);
+
+	if (pdata && pdata->reset)
+		pdata->reset(UCB_RST_REMOVE);
 }
 
 int ucb1x00_register_driver(struct ucb1x00_driver *drv)
@@ -653,7 +648,7 @@ int ucb1x00_register_driver(struct ucb1x00_driver *drv)
 
 	INIT_LIST_HEAD(&drv->devs);
 	mutex_lock(&ucb1x00_mutex);
-	list_add(&drv->node, &ucb1x00_drivers);
+	list_add_tail(&drv->node, &ucb1x00_drivers);
 	list_for_each_entry(ucb, &ucb1x00_devices, node) {
 		ucb1x00_add_dev(ucb, drv);
 	}
@@ -674,44 +669,86 @@ void ucb1x00_unregister_driver(struct ucb1x00_driver *drv)
 	mutex_unlock(&ucb1x00_mutex);
 }
 
-static int ucb1x00_suspend(struct mcp *mcp, pm_message_t state)
+static int ucb1x00_suspend(struct device *dev)
 {
-	struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
-	struct ucb1x00_dev *dev;
+	struct ucb1x00_plat_data *pdata = dev->platform_data;
+	struct ucb1x00 *ucb = dev_get_drvdata(dev);
+	struct ucb1x00_dev *udev;
 
 	mutex_lock(&ucb1x00_mutex);
-	list_for_each_entry(dev, &ucb->devs, dev_node) {
-		if (dev->drv->suspend)
-			dev->drv->suspend(dev, state);
+	list_for_each_entry(udev, &ucb->devs, dev_node) {
+		if (udev->drv->suspend)
+			udev->drv->suspend(udev);
 	}
 	mutex_unlock(&ucb1x00_mutex);
+
+	if (ucb->irq_wake) {
+		unsigned long flags;
+
+		raw_spin_lock_irqsave(&ucb->irq_lock, flags);
+		ucb1x00_enable(ucb);
+		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+				  ucb->irq_wake);
+		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+				  ucb->irq_wake);
+		ucb1x00_disable(ucb);
+		raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
+
+		enable_irq_wake(ucb->irq);
+	} else if (pdata && pdata->reset)
+		pdata->reset(UCB_RST_SUSPEND);
+
 	return 0;
 }
 
-static int ucb1x00_resume(struct mcp *mcp)
+static int ucb1x00_resume(struct device *dev)
 {
-	struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
-	struct ucb1x00_dev *dev;
+	struct ucb1x00_plat_data *pdata = dev->platform_data;
+	struct ucb1x00 *ucb = dev_get_drvdata(dev);
+	struct ucb1x00_dev *udev;
+
+	if (!ucb->irq_wake && pdata && pdata->reset)
+		pdata->reset(UCB_RST_RESUME);
 
+	ucb1x00_enable(ucb);
 	ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
 	ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
+
+	if (ucb->irq_wake) {
+		unsigned long flags;
+
+		raw_spin_lock_irqsave(&ucb->irq_lock, flags);
+		ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl &
+				  ucb->irq_mask);
+		ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl &
+				  ucb->irq_mask);
+		raw_spin_unlock_irqrestore(&ucb->irq_lock, flags);
+
+		disable_irq_wake(ucb->irq);
+	}
+	ucb1x00_disable(ucb);
+
 	mutex_lock(&ucb1x00_mutex);
-	list_for_each_entry(dev, &ucb->devs, dev_node) {
-		if (dev->drv->resume)
-			dev->drv->resume(dev);
+	list_for_each_entry(udev, &ucb->devs, dev_node) {
+		if (udev->drv->resume)
+			udev->drv->resume(udev);
 	}
 	mutex_unlock(&ucb1x00_mutex);
 	return 0;
 }
 
+static const struct dev_pm_ops ucb1x00_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume)
+};
+
 static struct mcp_driver ucb1x00_driver = {
 	.drv		= {
 		.name	= "ucb1x00",
+		.owner	= THIS_MODULE,
+		.pm	= &ucb1x00_pm_ops,
 	},
 	.probe		= ucb1x00_probe,
 	.remove		= ucb1x00_remove,
-	.suspend	= ucb1x00_suspend,
-	.resume		= ucb1x00_resume,
 };
 
 static int __init ucb1x00_init(void)
@@ -742,14 +779,10 @@ EXPORT_SYMBOL(ucb1x00_adc_enable);
 EXPORT_SYMBOL(ucb1x00_adc_read);
 EXPORT_SYMBOL(ucb1x00_adc_disable);
 
-EXPORT_SYMBOL(ucb1x00_hook_irq);
-EXPORT_SYMBOL(ucb1x00_free_irq);
-EXPORT_SYMBOL(ucb1x00_enable_irq);
-EXPORT_SYMBOL(ucb1x00_disable_irq);
-
 EXPORT_SYMBOL(ucb1x00_register_driver);
 EXPORT_SYMBOL(ucb1x00_unregister_driver);
 
+MODULE_ALIAS("mcp:ucb1x00");
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("UCB1x00 core driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 63a3cbd..1e0e20c 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -20,8 +20,9 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/smp.h>
+#include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/string.h>
@@ -32,7 +33,6 @@
 #include <linux/kthread.h>
 #include <linux/mfd/ucb1x00.h>
 
-#include <mach/dma.h>
 #include <mach/collie.h>
 #include <asm/mach-types.h>
 
@@ -42,6 +42,8 @@ struct ucb1x00_ts {
 	struct input_dev	*idev;
 	struct ucb1x00		*ucb;
 
+	spinlock_t		irq_lock;
+	unsigned		irq_disabled;
 	wait_queue_head_t	irq_wait;
 	struct task_struct	*rtask;
 	u16			x_res;
@@ -238,7 +240,12 @@ static int ucb1x00_thread(void *_ts)
 		if (ucb1x00_ts_pen_down(ts)) {
 			set_current_state(TASK_INTERRUPTIBLE);
 
-			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
+			spin_lock_irq(&ts->irq_lock);
+			if (ts->irq_disabled) {
+				ts->irq_disabled = 0;
+				enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX);
+			}
+			spin_unlock_irq(&ts->irq_lock);
 			ucb1x00_disable(ts->ucb);
 
 			/*
@@ -281,23 +288,37 @@ static int ucb1x00_thread(void *_ts)
  * We only detect touch screen _touches_ with this interrupt
  * handler, and even then we just schedule our task.
  */
-static void ucb1x00_ts_irq(int idx, void *id)
+static irqreturn_t ucb1x00_ts_irq(int irq, void *id)
 {
 	struct ucb1x00_ts *ts = id;
 
-	ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
+	spin_lock(&ts->irq_lock);
+	ts->irq_disabled = 1;
+	disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX);
+	spin_unlock(&ts->irq_lock);
 	wake_up(&ts->irq_wait);
+
+	return IRQ_HANDLED;
 }
 
 static int ucb1x00_ts_open(struct input_dev *idev)
 {
 	struct ucb1x00_ts *ts = input_get_drvdata(idev);
+	unsigned long flags = 0;
 	int ret = 0;
 
 	BUG_ON(ts->rtask);
 
+	if (machine_is_collie())
+		flags = IRQF_TRIGGER_RISING;
+	else
+		flags = IRQF_TRIGGER_FALLING;
+
+	ts->irq_disabled = 0;
+
 	init_waitqueue_head(&ts->irq_wait);
-	ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
+	ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq,
+			  flags, "ucb1x00-ts", ts);
 	if (ret < 0)
 		goto out;
 
@@ -314,7 +335,7 @@ static int ucb1x00_ts_open(struct input_dev *idev)
 	if (!IS_ERR(ts->rtask)) {
 		ret = 0;
 	} else {
-		ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
+		free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
 		ts->rtask = NULL;
 		ret = -EFAULT;
 	}
@@ -334,7 +355,7 @@ static void ucb1x00_ts_close(struct input_dev *idev)
 		kthread_stop(ts->rtask);
 
 	ucb1x00_enable(ts->ucb);
-	ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
+	free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts);
 	ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
 	ucb1x00_disable(ts->ucb);
 }
@@ -359,11 +380,13 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
 	ts->ucb = dev->ucb;
 	ts->idev = idev;
 	ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
+	spin_lock_init(&ts->irq_lock);
 
 	idev->name       = "Touchscreen panel";
 	idev->id.product = ts->ucb->id;
 	idev->open       = ucb1x00_ts_open;
 	idev->close      = ucb1x00_ts_close;
+	idev->dev.parent = &ts->ucb->dev;
 
 	idev->evbit[0]   = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
 	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index f5e54fa..838056c 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -1631,7 +1631,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
 	if (ret < 0) {
 		dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
-		goto err_regmap;
+		goto err;
 	}
 	switch (ret) {
 	case 0x6204:
@@ -1640,20 +1640,20 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	default:
 		dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
 		ret = -EINVAL;
-		goto err_regmap;
+		goto err;
 	}
 
 	ret = wm831x_reg_read(wm831x, WM831X_REVISION);
 	if (ret < 0) {
 		dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
-		goto err_regmap;
+		goto err;
 	}
 	rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
 
 	ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
 	if (ret < 0) {
 		dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
-		goto err_regmap;
+		goto err;
 	}
 
 	/* Some engineering samples do not have the ID set, rely on
@@ -1728,7 +1728,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	default:
 		dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
 		ret = -EINVAL;
-		goto err_regmap;
+		goto err;
 	}
 
 	/* This will need revisiting in future but is OK for all
@@ -1742,7 +1742,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 	ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
 	if (ret < 0) {
 		dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
-		goto err_regmap;
+		goto err;
 	}
 	if (ret != 0) {
 		dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
@@ -1755,7 +1755,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 		ret = pdata->pre_init(wm831x);
 		if (ret != 0) {
 			dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
-			goto err_regmap;
+			goto err;
 		}
 	}
 
@@ -1778,7 +1778,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 
 	ret = wm831x_irq_init(wm831x, irq);
 	if (ret != 0)
-		goto err_regmap;
+		goto err;
 
 	wm831x_auxadc_init(wm831x);
 
@@ -1874,9 +1874,8 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 
 err_irq:
 	wm831x_irq_exit(wm831x);
-err_regmap:
+err:
 	mfd_remove_devices(wm831x->dev);
-	regmap_exit(wm831x->regmap);
 	return ret;
 }
 
@@ -1887,7 +1886,6 @@ void wm831x_device_exit(struct wm831x *wm831x)
 	if (wm831x->irq_base)
 		free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
 	wm831x_irq_exit(wm831x);
-	regmap_exit(wm831x->regmap);
 }
 
 int wm831x_device_suspend(struct wm831x *wm831x)
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index cb15609..2b29cae 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -37,7 +37,7 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
 	i2c_set_clientdata(i2c, wm831x);
 	wm831x->dev = &i2c->dev;
 
-	wm831x->regmap = regmap_init_i2c(i2c, &wm831x_regmap_config);
+	wm831x->regmap = devm_regmap_init_i2c(i2c, &wm831x_regmap_config);
 	if (IS_ERR(wm831x->regmap)) {
 		ret = PTR_ERR(wm831x->regmap);
 		dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 62ef325..745c879 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -40,7 +40,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
 	dev_set_drvdata(&spi->dev, wm831x);
 	wm831x->dev = &spi->dev;
 
-	wm831x->regmap = regmap_init_spi(spi, &wm831x_regmap_config);
+	wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config);
 	if (IS_ERR(wm831x->regmap)) {
 		ret = PTR_ERR(wm831x->regmap);
 		dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index 8a1fafd..9fd01bf 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -496,7 +496,6 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 
 	mutex_init(&wm8350->irq_lock);
 	wm8350->chip_irq = irq;
-	wm8350->irq_base = pdata->irq_base;
 
 	if (pdata && pdata->irq_base > 0)
 		irq_base = pdata->irq_base;
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 2204893..237764a 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -350,7 +350,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
 		goto err;
 	}
 
-	wm8400->regmap = regmap_init_i2c(i2c, &wm8400_regmap_config);
+	wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config);
 	if (IS_ERR(wm8400->regmap)) {
 		ret = PTR_ERR(wm8400->regmap);
 		goto err;
@@ -361,12 +361,10 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
 
 	ret = wm8400_init(wm8400, i2c->dev.platform_data);
 	if (ret != 0)
-		goto map_err;
+		goto err;
 
 	return 0;
 
-map_err:
-	regmap_exit(wm8400->regmap);
 err:
 	return ret;
 }
@@ -376,7 +374,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
 	struct wm8400 *wm8400 = i2c_get_clientdata(i2c);
 
 	wm8400_release(wm8400);
-	regmap_exit(wm8400->regmap);
 
 	return 0;
 }
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index f117e7f..b2de65b 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -256,6 +256,20 @@ static int wm8994_suspend(struct device *dev)
 		break;
 	}
 
+	switch (wm8994->type) {
+	case WM1811:
+		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
+		if (ret < 0) {
+			dev_err(dev, "Failed to read jackdet: %d\n", ret);
+		} else if (ret & WM1811_JACKDET_MODE_MASK) {
+			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
+			return 0;
+		}
+		break;
+	default:
+		break;
+	}
+
 	/* Disable LDO pulldowns while the device is suspended if we
 	 * don't know that something will be driving them. */
 	if (!wm8994->ldo_ena_always_driven)
@@ -345,15 +359,37 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
 }
 #endif
 
+static const __devinitdata struct reg_default wm8994_revc_patch[] = {
+	{ 0x102, 0x3 },
+	{ 0x56, 0x3 },
+	{ 0x817, 0x0 },
+	{ 0x102, 0x0 },
+};
+
+static const __devinitdata struct reg_default wm8958_reva_patch[] = {
+	{ 0x102, 0x3 },
+	{ 0xcb, 0x81 },
+	{ 0x817, 0x0 },
+	{ 0x102, 0x0 },
+};
+
+static const __devinitdata struct reg_default wm1811_reva_patch[] = {
+	{ 0x102, 0x3 },
+	{ 0x5d, 0x7e },
+	{ 0x5e, 0x0 },
+	{ 0x102, 0x0 },
+};
+
 /*
  * Instantiate the generic non-control parts of the device.
  */
-static int wm8994_device_init(struct wm8994 *wm8994, int irq)
+static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq)
 {
 	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
 	struct regmap_config *regmap_config;
+	const struct reg_default *regmap_patch = NULL;
 	const char *devname;
-	int ret, i;
+	int ret, i, patch_regs;
 	int pulls = 0;
 
 	dev_set_drvdata(wm8994->dev, wm8994);
@@ -365,7 +401,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 			      NULL, 0);
 	if (ret != 0) {
 		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
-		goto err_regmap;
+		goto err;
 	}
 
 	switch (wm8994->type) {
@@ -380,7 +416,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 		break;
 	default:
 		BUG();
-		goto err_regmap;
+		goto err;
 	}
 
 	wm8994->supplies = devm_kzalloc(wm8994->dev,
@@ -388,7 +424,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 					wm8994->num_supplies, GFP_KERNEL);
 	if (!wm8994->supplies) {
 		ret = -ENOMEM;
-		goto err_regmap;
+		goto err;
 	}
 
 	switch (wm8994->type) {
@@ -406,14 +442,14 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 		break;
 	default:
 		BUG();
-		goto err_regmap;
+		goto err;
 	}
 		
 	ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
 				 wm8994->supplies);
 	if (ret != 0) {
 		dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
-		goto err_regmap;
+		goto err;
 	}
 
 	ret = regulator_bulk_enable(wm8994->num_supplies,
@@ -474,15 +510,42 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 				 "revision %c not fully supported\n",
 				 'A' + wm8994->revision);
 			break;
+		case 2:
+		case 3:
+			regmap_patch = wm8994_revc_patch;
+			patch_regs = ARRAY_SIZE(wm8994_revc_patch);
+			break;
 		default:
 			break;
 		}
 		break;
+
+	case WM8958:
+		switch (wm8994->revision) {
+		case 0:
+			regmap_patch = wm8958_reva_patch;
+			patch_regs = ARRAY_SIZE(wm8958_reva_patch);
+			break;
+		default:
+			break;
+		}
+		break;
+
 	case WM1811:
 		/* Revision C did not change the relevant layer */
 		if (wm8994->revision > 1)
 			wm8994->revision++;
+		switch (wm8994->revision) {
+		case 0:
+		case 1:
+			regmap_patch = wm1811_reva_patch;
+			patch_regs = ARRAY_SIZE(wm1811_reva_patch);
+			break;
+		default:
+			break;
+		}
 		break;
+
 	default:
 		break;
 	}
@@ -512,6 +575,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 		return ret;
 	}
 
+	if (regmap_patch) {
+		ret = regmap_register_patch(wm8994->regmap, regmap_patch,
+					    patch_regs);
+		if (ret != 0) {
+			dev_err(wm8994->dev, "Failed to register patch: %d\n",
+				ret);
+			goto err;
+		}
+	}
+
 	if (pdata) {
 		wm8994->irq_base = pdata->irq_base;
 		wm8994->gpio_base = pdata->gpio_base;
@@ -563,7 +636,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 	}
 
 	pm_runtime_enable(wm8994->dev);
-	pm_runtime_resume(wm8994->dev);
+	pm_runtime_idle(wm8994->dev);
 
 	return 0;
 
@@ -574,13 +647,12 @@ err_enable:
 			       wm8994->supplies);
 err_get:
 	regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
-err_regmap:
-	regmap_exit(wm8994->regmap);
+err:
 	mfd_remove_devices(wm8994->dev);
 	return ret;
 }
 
-static void wm8994_device_exit(struct wm8994 *wm8994)
+static __devexit void wm8994_device_exit(struct wm8994 *wm8994)
 {
 	pm_runtime_disable(wm8994->dev);
 	mfd_remove_devices(wm8994->dev);
@@ -588,7 +660,6 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
 	regulator_bulk_disable(wm8994->num_supplies,
 			       wm8994->supplies);
 	regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
-	regmap_exit(wm8994->regmap);
 }
 
 static const struct of_device_id wm8994_of_match[] = {
@@ -614,7 +685,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c,
 	wm8994->irq = i2c->irq;
 	wm8994->type = id->driver_data;
 
-	wm8994->regmap = regmap_init_i2c(i2c, &wm8994_base_regmap_config);
+	wm8994->regmap = devm_regmap_init_i2c(i2c, &wm8994_base_regmap_config);
 	if (IS_ERR(wm8994->regmap)) {
 		ret = PTR_ERR(wm8994->regmap);
 		dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index c598ae6..47743fa 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -968,6 +968,7 @@ static bool wm8994_readable_register(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM8994_DC_SERVO_READBACK:
+	case WM8994_MICBIAS:
 	case WM8994_WRITE_SEQUENCER_CTRL_1:
 	case WM8994_WRITE_SEQUENCER_CTRL_2:
 	case WM8994_AIF1_ADC2_LEFT_VOLUME:
diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c
index 83adab6..8208262 100644
--- a/drivers/misc/ad525x_dpot-i2c.c
+++ b/drivers/misc/ad525x_dpot-i2c.c
@@ -113,17 +113,7 @@ static struct i2c_driver ad_dpot_i2c_driver = {
 	.id_table	= ad_dpot_id,
 };
 
-static int __init ad_dpot_i2c_init(void)
-{
-	return i2c_add_driver(&ad_dpot_i2c_driver);
-}
-module_init(ad_dpot_i2c_init);
-
-static void __exit ad_dpot_i2c_exit(void)
-{
-	i2c_del_driver(&ad_dpot_i2c_driver);
-}
-module_exit(ad_dpot_i2c_exit);
+module_i2c_driver(ad_dpot_i2c_driver);
 
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("digital potentiometer I2C bus driver");
diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c
index 822749e..f623175 100644
--- a/drivers/misc/ad525x_dpot-spi.c
+++ b/drivers/misc/ad525x_dpot-spi.c
@@ -135,17 +135,7 @@ static struct spi_driver ad_dpot_spi_driver = {
 	.id_table	= ad_dpot_spi_id,
 };
 
-static int __init ad_dpot_spi_init(void)
-{
-	return spi_register_driver(&ad_dpot_spi_driver);
-}
-module_init(ad_dpot_spi_init);
-
-static void __exit ad_dpot_spi_exit(void)
-{
-	spi_unregister_driver(&ad_dpot_spi_driver);
-}
-module_exit(ad_dpot_spi_exit);
+module_spi_driver(ad_dpot_spi_driver);
 
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("digital potentiometer SPI bus driver");
diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c
index 81db781..0314773 100644
--- a/drivers/misc/apds9802als.c
+++ b/drivers/misc/apds9802als.c
@@ -332,17 +332,7 @@ static struct i2c_driver apds9802als_driver = {
 	.id_table = apds9802als_id,
 };
 
-static int __init sensor_apds9802als_init(void)
-{
-	return i2c_add_driver(&apds9802als_driver);
-}
-
-static void  __exit sensor_apds9802als_exit(void)
-{
-	i2c_del_driver(&apds9802als_driver);
-}
-module_init(sensor_apds9802als_init);
-module_exit(sensor_apds9802als_exit);
+module_i2c_driver(apds9802als_driver);
 
 MODULE_AUTHOR("Anantha Narayanan <Anantha.Narayanan@intel.com");
 MODULE_DESCRIPTION("Avago apds9802als ALS Driver");
diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c
index e2a52e5..ee74244 100644
--- a/drivers/misc/apds990x.c
+++ b/drivers/misc/apds990x.c
@@ -1279,19 +1279,8 @@ static struct i2c_driver apds990x_driver = {
 	.id_table = apds990x_id,
 };
 
-static int __init apds990x_init(void)
-{
-	return i2c_add_driver(&apds990x_driver);
-}
-
-static void __exit apds990x_exit(void)
-{
-	i2c_del_driver(&apds990x_driver);
-}
+module_i2c_driver(apds990x_driver);
 
 MODULE_DESCRIPTION("APDS990X combined ALS and proximity sensor");
 MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
 MODULE_LICENSE("GPL v2");
-
-module_init(apds990x_init);
-module_exit(apds990x_exit);
diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c
index d79a972..3d56ae7 100644
--- a/drivers/misc/bh1770glc.c
+++ b/drivers/misc/bh1770glc.c
@@ -1399,19 +1399,8 @@ static struct i2c_driver bh1770_driver = {
 	.id_table = bh1770_id,
 };
 
-static int __init bh1770_init(void)
-{
-	return i2c_add_driver(&bh1770_driver);
-}
-
-static void __exit bh1770_exit(void)
-{
-	i2c_del_driver(&bh1770_driver);
-}
+module_i2c_driver(bh1770_driver);
 
 MODULE_DESCRIPTION("BH1770GLC / SFH7770 combined ALS and proximity sensor");
 MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
 MODULE_LICENSE("GPL v2");
-
-module_init(bh1770_init);
-module_exit(bh1770_exit);
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
index bfeea9b..54f6f39 100644
--- a/drivers/misc/bh1780gli.c
+++ b/drivers/misc/bh1780gli.c
@@ -253,21 +253,10 @@ static struct i2c_driver bh1780_driver = {
 	.driver = {
 		.name = "bh1780",
 		.pm	= BH1780_PMOPS,
-},
+	},
 };
 
-static int __init bh1780_init(void)
-{
-	return i2c_add_driver(&bh1780_driver);
-}
-
-static void __exit bh1780_exit(void)
-{
-	i2c_del_driver(&bh1780_driver);
-}
-
-module_init(bh1780_init)
-module_exit(bh1780_exit)
+module_i2c_driver(bh1780_driver);
 
 MODULE_DESCRIPTION("BH1780GLI Ambient Light Sensor Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c
index b29a2be..3c534ab 100644
--- a/drivers/misc/bmp085.c
+++ b/drivers/misc/bmp085.c
@@ -464,20 +464,8 @@ static struct i2c_driver bmp085_driver = {
 	.address_list	= normal_i2c
 };
 
-static int __init bmp085_init(void)
-{
-	return i2c_add_driver(&bmp085_driver);
-}
-
-static void __exit bmp085_exit(void)
-{
-	i2c_del_driver(&bmp085_driver);
-}
-
+module_i2c_driver(bmp085_driver);
 
 MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
 MODULE_DESCRIPTION("BMP085 driver");
 MODULE_LICENSE("GPL");
-
-module_init(bmp085_init);
-module_exit(bmp085_exit);
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 14e974b2..366bc15 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -1410,23 +1410,8 @@ static struct platform_driver data_of_driver = {
 	},
 };
 
-/*
- * Module Init / Exit
- */
-
-static int __init data_init(void)
-{
-	return platform_driver_register(&data_of_driver);
-}
-
-static void __exit data_exit(void)
-{
-	platform_driver_unregister(&data_of_driver);
-}
+module_platform_driver(data_of_driver);
 
 MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
 MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver");
 MODULE_LICENSE("GPL");
-
-module_init(data_init);
-module_exit(data_exit);
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c
index 87a390d..f505a40 100644
--- a/drivers/misc/cs5535-mfgpt.c
+++ b/drivers/misc/cs5535-mfgpt.c
@@ -246,7 +246,7 @@ EXPORT_SYMBOL_GPL(cs5535_mfgpt_write);
  * Jordan tells me that he and Mitch once played w/ it, but it's unclear
  * what the results of that were (and they experienced some instability).
  */
-static void __init reset_all_timers(void)
+static void __devinit reset_all_timers(void)
 {
 	uint32_t val, dummy;
 
diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c
index a513f0a..154b02e 100644
--- a/drivers/misc/ds1682.c
+++ b/drivers/misc/ds1682.c
@@ -250,19 +250,8 @@ static struct i2c_driver ds1682_driver = {
 	.id_table = ds1682_id,
 };
 
-static int __init ds1682_init(void)
-{
-	return i2c_add_driver(&ds1682_driver);
-}
-
-static void __exit ds1682_exit(void)
-{
-	i2c_del_driver(&ds1682_driver);
-}
+module_i2c_driver(ds1682_driver);
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
 MODULE_LICENSE("GPL");
-
-module_init(ds1682_init);
-module_exit(ds1682_exit);
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index c627e41..01ab3c9 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -405,17 +405,7 @@ static struct spi_driver at25_driver = {
 	.remove		= __devexit_p(at25_remove),
 };
 
-static int __init at25_init(void)
-{
-	return spi_register_driver(&at25_driver);
-}
-module_init(at25_init);
-
-static void __exit at25_exit(void)
-{
-	spi_unregister_driver(&at25_driver);
-}
-module_exit(at25_exit);
+module_spi_driver(at25_driver);
 
 MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
 MODULE_AUTHOR("David Brownell");
diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c
index 45060dd..c169e07 100644
--- a/drivers/misc/eeprom/eeprom.c
+++ b/drivers/misc/eeprom/eeprom.c
@@ -229,22 +229,10 @@ static struct i2c_driver eeprom_driver = {
 	.address_list	= normal_i2c,
 };
 
-static int __init eeprom_init(void)
-{
-	return i2c_add_driver(&eeprom_driver);
-}
-
-static void __exit eeprom_exit(void)
-{
-	i2c_del_driver(&eeprom_driver);
-}
-
+module_i2c_driver(eeprom_driver);
 
 MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
 		"Philip Edelbrock <phil@netroedge.com> and "
 		"Greg Kroah-Hartman <greg@kroah.com>");
 MODULE_DESCRIPTION("I2C EEPROM driver");
 MODULE_LICENSE("GPL");
-
-module_init(eeprom_init);
-module_exit(eeprom_exit);
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c
index 0c7ebb1..ce3fe36 100644
--- a/drivers/misc/eeprom/eeprom_93xx46.c
+++ b/drivers/misc/eeprom/eeprom_93xx46.c
@@ -392,17 +392,7 @@ static struct spi_driver eeprom_93xx46_driver = {
 	.remove		= __devexit_p(eeprom_93xx46_remove),
 };
 
-static int __init eeprom_93xx46_init(void)
-{
-	return spi_register_driver(&eeprom_93xx46_driver);
-}
-module_init(eeprom_93xx46_init);
-
-static void __exit eeprom_93xx46_exit(void)
-{
-	spi_unregister_driver(&eeprom_93xx46_driver);
-}
-module_exit(eeprom_93xx46_exit);
+module_spi_driver(eeprom_93xx46_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c
index 5653a3c..e36157d 100644
--- a/drivers/misc/eeprom/max6875.c
+++ b/drivers/misc/eeprom/max6875.c
@@ -208,20 +208,8 @@ static struct i2c_driver max6875_driver = {
 	.id_table	= max6875_id,
 };
 
-static int __init max6875_init(void)
-{
-	return i2c_add_driver(&max6875_driver);
-}
-
-static void __exit max6875_exit(void)
-{
-	i2c_del_driver(&max6875_driver);
-}
-
+module_i2c_driver(max6875_driver);
 
 MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
 MODULE_DESCRIPTION("MAX6875 driver");
 MODULE_LICENSE("GPL");
-
-module_init(max6875_init);
-module_exit(max6875_exit);
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c
index f6586d5..483d6b7 100644
--- a/drivers/misc/fsa9480.c
+++ b/drivers/misc/fsa9480.c
@@ -541,17 +541,7 @@ static struct i2c_driver fsa9480_i2c_driver = {
 	.id_table = fsa9480_id,
 };
 
-static int __init fsa9480_init(void)
-{
-	return i2c_add_driver(&fsa9480_i2c_driver);
-}
-module_init(fsa9480_init);
-
-static void __exit fsa9480_exit(void)
-{
-	i2c_del_driver(&fsa9480_i2c_driver);
-}
-module_exit(fsa9480_exit);
+module_i2c_driver(fsa9480_i2c_driver);
 
 MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
 MODULE_DESCRIPTION("FSA9480 USB Switch driver");
diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c
index ca938fc..423cd40 100644
--- a/drivers/misc/hmc6352.c
+++ b/drivers/misc/hmc6352.c
@@ -148,18 +148,7 @@ static struct i2c_driver hmc6352_driver = {
 	.id_table = hmc6352_id,
 };
 
-static int __init sensor_hmc6352_init(void)
-{
-	return i2c_add_driver(&hmc6352_driver);
-}
-
-static void  __exit sensor_hmc6352_exit(void)
-{
-	i2c_del_driver(&hmc6352_driver);
-}
-
-module_init(sensor_hmc6352_init);
-module_exit(sensor_hmc6352_exit);
+module_i2c_driver(hmc6352_driver);
 
 MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
 MODULE_DESCRIPTION("hmc6352 Compass Driver");
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index 3536175..1c034b8 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -87,7 +87,7 @@
 static LIST_HEAD(service_processors);
 
 static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode);
-static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root);
+static void ibmasmfs_create_files (struct super_block *sb);
 static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
 
 
@@ -114,7 +114,6 @@ static struct file_system_type ibmasmfs_type = {
 static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
 {
 	struct inode *root;
-	struct dentry *root_dentry;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -129,14 +128,11 @@ static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
 	root->i_op = &simple_dir_inode_operations;
 	root->i_fop = ibmasmfs_dir_ops;
 
-	root_dentry = d_alloc_root(root);
-	if (!root_dentry) {
-		iput(root);
+	sb->s_root = d_make_root(root);
+	if (!sb->s_root)
 		return -ENOMEM;
-	}
-	sb->s_root = root_dentry;
 
-	ibmasmfs_create_files(sb, root_dentry);
+	ibmasmfs_create_files(sb);
 	return 0;
 }
 
@@ -612,7 +608,7 @@ static const struct file_operations remote_settings_fops = {
 };
 
 
-static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
+static void ibmasmfs_create_files (struct super_block *sb)
 {
 	struct list_head *entry;
 	struct service_processor *sp;
@@ -621,7 +617,7 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
 		struct dentry *dir;
 		struct dentry *remote_dir;
 		sp = list_entry(entry, struct service_processor, node);
-		dir = ibmasmfs_create_dir(sb, root, sp->dirname);
+		dir = ibmasmfs_create_dir(sb, sb->s_root, sp->dirname);
 		if (!dir)
 			continue;
 
diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c
index 152e9d9..0029536 100644
--- a/drivers/misc/ics932s401.c
+++ b/drivers/misc/ics932s401.c
@@ -480,23 +480,12 @@ static int ics932s401_remove(struct i2c_client *client)
 	return 0;
 }
 
-static int __init ics932s401_init(void)
-{
-	return i2c_add_driver(&ics932s401_driver);
-}
-
-static void __exit ics932s401_exit(void)
-{
-	i2c_del_driver(&ics932s401_driver);
-}
+module_i2c_driver(ics932s401_driver);
 
 MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
 MODULE_DESCRIPTION("ICS932S401 driver");
 MODULE_LICENSE("GPL");
 
-module_init(ics932s401_init);
-module_exit(ics932s401_exit);
-
 /* IBM IntelliStation Z30 */
 MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*");
 MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*");
diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c
index a71e245..eb5de2e 100644
--- a/drivers/misc/isl29003.c
+++ b/drivers/misc/isl29003.c
@@ -455,21 +455,9 @@ static struct i2c_driver isl29003_driver = {
 	.id_table = isl29003_id,
 };
 
-static int __init isl29003_init(void)
-{
-	return i2c_add_driver(&isl29003_driver);
-}
-
-static void __exit isl29003_exit(void)
-{
-	i2c_del_driver(&isl29003_driver);
-}
+module_i2c_driver(isl29003_driver);
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION(DRIVER_VERSION);
-
-module_init(isl29003_init);
-module_exit(isl29003_exit);
-
diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c
index 3d6cce6..0aa08c7 100644
--- a/drivers/misc/isl29020.c
+++ b/drivers/misc/isl29020.c
@@ -230,18 +230,7 @@ static struct i2c_driver isl29020_driver = {
 	.id_table = isl29020_id,
 };
 
-static int __init sensor_isl29020_init(void)
-{
-	return i2c_add_driver(&isl29020_driver);
-}
-
-static void  __exit sensor_isl29020_exit(void)
-{
-	i2c_del_driver(&isl29020_driver);
-}
-
-module_init(sensor_isl29020_init);
-module_exit(sensor_isl29020_exit);
+module_i2c_driver(isl29020_driver);
 
 MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>");
 MODULE_DESCRIPTION("Intersil isl29020 ALS Driver");
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
index c02fea0..e8c0019 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
@@ -256,19 +256,8 @@ static struct i2c_driver lis3lv02d_i2c_driver = {
 	.id_table = lis3lv02d_id,
 };
 
-static int __init lis3lv02d_init(void)
-{
-	return i2c_add_driver(&lis3lv02d_i2c_driver);
-}
-
-static void __exit lis3lv02d_exit(void)
-{
-	i2c_del_driver(&lis3lv02d_i2c_driver);
-}
+module_i2c_driver(lis3lv02d_i2c_driver);
 
 MODULE_AUTHOR("Nokia Corporation");
 MODULE_DESCRIPTION("lis3lv02d I2C interface");
 MODULE_LICENSE("GPL");
-
-module_init(lis3lv02d_init);
-module_exit(lis3lv02d_exit);
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c
index b2c1be1..80880e9 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c
@@ -126,18 +126,7 @@ static struct spi_driver lis302dl_spi_driver = {
 	.remove	= __devexit_p(lis302dl_spi_remove),
 };
 
-static int __init lis302dl_init(void)
-{
-	return spi_register_driver(&lis302dl_spi_driver);
-}
-
-static void __exit lis302dl_exit(void)
-{
-	spi_unregister_driver(&lis302dl_spi_driver);
-}
-
-module_init(lis302dl_init);
-module_exit(lis302dl_exit);
+module_spi_driver(lis302dl_spi_driver);
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
diff --git a/drivers/misc/max8997-muic.c b/drivers/misc/max8997-muic.c
index d74ef41..19591ea 100644
--- a/drivers/misc/max8997-muic.c
+++ b/drivers/misc/max8997-muic.c
@@ -488,17 +488,7 @@ static struct platform_driver max8997_muic_driver = {
 	.remove		= __devexit_p(max8997_muic_remove),
 };
 
-static int __init max8997_muic_init(void)
-{
-	return platform_driver_register(&max8997_muic_driver);
-}
-module_init(max8997_muic_init);
-
-static void __exit max8997_muic_exit(void)
-{
-	platform_driver_unregister(&max8997_muic_driver);
-}
-module_exit(max8997_muic_exit);
+module_platform_driver(max8997_muic_driver);
 
 MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver");
 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index 0b56e3f..471ff4c 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -481,13 +481,9 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
 	int idx = tty->index;
 	struct pti_tty *pti_tty_data;
-	int ret = tty_init_termios(tty);
+	int ret = tty_standard_install(driver, tty);
 
 	if (ret == 0) {
-		tty_driver_kref_get(driver);
-		tty->count++;
-		driver->ttys[idx] = tty;
-
 		pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL);
 		if (pti_tty_data == NULL)
 			return -ENOMEM;
diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c
index 43d073b..123ed98 100644
--- a/drivers/misc/spear13xx_pcie_gadget.c
+++ b/drivers/misc/spear13xx_pcie_gadget.c
@@ -891,17 +891,7 @@ static struct platform_driver spear_pcie_gadget_driver = {
 	},
 };
 
-static int __init spear_pcie_gadget_init(void)
-{
-	return platform_driver_register(&spear_pcie_gadget_driver);
-}
-module_init(spear_pcie_gadget_init);
-
-static void __exit spear_pcie_gadget_exit(void)
-{
-	platform_driver_unregister(&spear_pcie_gadget_driver);
-}
-module_exit(spear_pcie_gadget_exit);
+module_platform_driver(spear_pcie_gadget_driver);
 
 MODULE_ALIAS("platform:pcie-gadget-spear");
 MODULE_AUTHOR("Pratyush Anand");
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
index a7a861c..7c14f8f 100644
--- a/drivers/misc/ti-st/st_kim.c
+++ b/drivers/misc/ti-st/st_kim.c
@@ -837,19 +837,8 @@ static struct platform_driver kim_platform_driver = {
 	},
 };
 
-static int __init st_kim_init(void)
-{
-	return platform_driver_register(&kim_platform_driver);
-}
-
-static void __exit st_kim_deinit(void)
-{
-	platform_driver_unregister(&kim_platform_driver);
-}
-
+module_platform_driver(kim_platform_driver);
 
-module_init(st_kim_init);
-module_exit(st_kim_deinit);
 MODULE_AUTHOR("Pavan Savoy <pavan_savoy@ti.com>");
 MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips ");
 MODULE_LICENSE("GPL");
diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c
index d3f229a..5acbba1 100644
--- a/drivers/misc/ti_dac7512.c
+++ b/drivers/misc/ti_dac7512.c
@@ -82,20 +82,9 @@ static struct spi_driver dac7512_driver = {
 	.remove	= __devexit_p(dac7512_remove),
 };
 
-static int __init dac7512_init(void)
-{
-	return spi_register_driver(&dac7512_driver);
-}
-
-static void __exit dac7512_exit(void)
-{
-	spi_unregister_driver(&dac7512_driver);
-}
+module_spi_driver(dac7512_driver);
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("DAC7512 16-bit DAC");
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION(DRIVER_VERSION);
-
-module_init(dac7512_init);
-module_exit(dac7512_exit);
diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c
index 483ae5f..0beb298 100644
--- a/drivers/misc/tsl2550.c
+++ b/drivers/misc/tsl2550.c
@@ -454,20 +454,9 @@ static struct i2c_driver tsl2550_driver = {
 	.id_table = tsl2550_id,
 };
 
-static int __init tsl2550_init(void)
-{
-	return i2c_add_driver(&tsl2550_driver);
-}
-
-static void __exit tsl2550_exit(void)
-{
-	i2c_del_driver(&tsl2550_driver);
-}
+module_i2c_driver(tsl2550_driver);
 
 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRIVER_VERSION);
-
-module_init(tsl2550_init);
-module_exit(tsl2550_exit);
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c6a383d..a7c75d8 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1080,6 +1080,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 	struct mmc_blk_request *brq = &mqrq->brq;
 	struct request *req = mqrq->req;
 	struct mmc_blk_data *md = mq->data;
+	bool do_data_tag;
 
 	/*
 	 * Reliable writes are used to implement Forced Unit Access and
@@ -1156,6 +1157,16 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 		mmc_apply_rel_rw(brq, card, req);
 
 	/*
+	 * Data tag is used only during writing meta data to speed
+	 * up write and any subsequent read of this meta data
+	 */
+	do_data_tag = (card->ext_csd.data_tag_unit_size) &&
+		(req->cmd_flags & REQ_META) &&
+		(rq_data_dir(req) == WRITE) &&
+		((brq->data.blocks * brq->data.blksz) >=
+		 card->ext_csd.data_tag_unit_size);
+
+	/*
 	 * Pre-defined multi-block transfers are preferable to
 	 * open ended-ones (and necessary for reliable writes).
 	 * However, it is not sufficient to just send CMD23,
@@ -1173,13 +1184,13 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 	 * We'll avoid using CMD23-bounded multiblock writes for
 	 * these, while retaining features like reliable writes.
 	 */
-
-	if ((md->flags & MMC_BLK_CMD23) &&
-	    mmc_op_multi(brq->cmd.opcode) &&
-	    (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
+	if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) &&
+	    (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
+	     do_data_tag)) {
 		brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
 		brq->sbc.arg = brq->data.blocks |
-			(do_rel_wr ? (1 << 31) : 0);
+			(do_rel_wr ? (1 << 31) : 0) |
+			(do_data_tag ? (1 << 29) : 0);
 		brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
 		brq->mrq.sbc = &brq->sbc;
 	}
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 2c151e1..bd4a67c 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -750,15 +750,12 @@ static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)
 {
 	int idx = tty->index;
 	struct sdio_uart_port *port = sdio_uart_port_get(idx);
-	int ret = tty_init_termios(tty);
+	int ret = tty_standard_install(driver, tty);
 
-	if (ret == 0) {
-		tty_driver_kref_get(driver);
-		tty->count++;
+	if (ret == 0)
 		/* This is the ref sdio_uart_port get provided */
 		tty->driver_data = port;
-		driver->ttys[idx] = tty;
-	} else
+	else
 		sdio_uart_port_put(port);
 	return ret;
 }
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 690255c..0b317f0 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -188,6 +188,12 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 	struct scatterlist *sg;
 #endif
 
+	if (mrq->sbc) {
+		pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n",
+			 mmc_hostname(host), mrq->sbc->opcode,
+			 mrq->sbc->arg, mrq->sbc->flags);
+	}
+
 	pr_debug("%s: starting CMD%u arg %08x flags %08x\n",
 		 mmc_hostname(host), mrq->cmd->opcode,
 		 mrq->cmd->arg, mrq->cmd->flags);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index a480663..6b13776 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -519,6 +519,20 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
 			ext_csd[EXT_CSD_CACHE_SIZE + 1] << 8 |
 			ext_csd[EXT_CSD_CACHE_SIZE + 2] << 16 |
 			ext_csd[EXT_CSD_CACHE_SIZE + 3] << 24;
+
+		if (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 1)
+			card->ext_csd.data_sector_size = 4096;
+		else
+			card->ext_csd.data_sector_size = 512;
+
+		if ((ext_csd[EXT_CSD_DATA_TAG_SUPPORT] & 1) &&
+		    (ext_csd[EXT_CSD_TAG_UNIT_SIZE] <= 8)) {
+			card->ext_csd.data_tag_unit_size =
+			((unsigned int) 1 << ext_csd[EXT_CSD_TAG_UNIT_SIZE]) *
+			(card->ext_csd.data_sector_size);
+		} else {
+			card->ext_csd.data_tag_unit_size = 0;
+		}
 	}
 
 out:
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 00fcbed..0c9b3b1 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -533,6 +533,31 @@ config MMC_DW_IDMAC
 	  Designware Mobile Storage IP block. This disables the external DMA
 	  interface.
 
+config MMC_DW_PLTFM
+	tristate "Synopsys Designware MCI Support as platform device"
+	depends on MMC_DW
+	default y
+	help
+	  This selects the common helper functions support for Host Controller
+	  Interface based platform driver. Please select this option if the IP
+	  is present as a platform device. This is the common interface for the
+	  Synopsys Designware IP.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say Y.
+
+config MMC_DW_PCI
+	tristate "Synopsys Designware MCI support on PCI bus"
+	depends on MMC_DW && PCI
+	help
+	  This selects the PCI bus for the Synopsys Designware Mobile Storage IP.
+	  Select this option if the IP is present on PCI platform.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_SH_MMCIF
 	tristate "SuperH Internal MMCIF support"
 	depends on MMC_BLOCK && (SUPERH || ARCH_SHMOBILE)
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 745f8fc..3e7e26d 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -39,6 +39,8 @@ obj-$(CONFIG_MMC_CB710)		+= cb710-mmc.o
 obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
 obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
 obj-$(CONFIG_MMC_DW)		+= dw_mmc.o
+obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
+obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
 obj-$(CONFIG_MMC_VUB300)	+= vub300.o
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 947faa5..efdb81d 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -86,7 +86,6 @@ static inline int at91mci_is_mci1rev2xx(void)
 {
 	return (   cpu_is_at91sam9260()
 		|| cpu_is_at91sam9263()
-		|| cpu_is_at91cap9()
 		|| cpu_is_at91sam9rl()
 		|| cpu_is_at91sam9g10()
 		|| cpu_is_at91sam9g20()
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 6985cdb..390863e 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -1948,12 +1948,12 @@ static bool atmci_filter(struct dma_chan *chan, void *slave)
 	}
 }
 
-static void atmci_configure_dma(struct atmel_mci *host)
+static bool atmci_configure_dma(struct atmel_mci *host)
 {
 	struct mci_platform_data	*pdata;
 
 	if (host == NULL)
-		return;
+		return false;
 
 	pdata = host->pdev->dev.platform_data;
 
@@ -1970,12 +1970,15 @@ static void atmci_configure_dma(struct atmel_mci *host)
 		host->dma.chan =
 			dma_request_channel(mask, atmci_filter, pdata->dma_slave);
 	}
-	if (!host->dma.chan)
-		dev_notice(&host->pdev->dev, "DMA not available, using PIO\n");
-	else
+	if (!host->dma.chan) {
+		dev_warn(&host->pdev->dev, "no DMA channel available\n");
+		return false;
+	} else {
 		dev_info(&host->pdev->dev,
-					"Using %s for DMA transfers\n",
+					"using %s for DMA transfers\n",
 					dma_chan_name(host->dma.chan));
+		return true;
+	}
 }
 
 static inline unsigned int atmci_get_version(struct atmel_mci *host)
@@ -2085,8 +2088,7 @@ static int __init atmci_probe(struct platform_device *pdev)
 
 	/* Get MCI capabilities and set operations according to it */
 	atmci_get_cap(host);
-	if (host->caps.has_dma) {
-		dev_info(&pdev->dev, "using DMA\n");
+	if (host->caps.has_dma && atmci_configure_dma(host)) {
 		host->prepare_data = &atmci_prepare_data_dma;
 		host->submit_data = &atmci_submit_data_dma;
 		host->stop_transfer = &atmci_stop_transfer_dma;
@@ -2096,15 +2098,12 @@ static int __init atmci_probe(struct platform_device *pdev)
 		host->submit_data = &atmci_submit_data_pdc;
 		host->stop_transfer = &atmci_stop_transfer_pdc;
 	} else {
-		dev_info(&pdev->dev, "no DMA, no PDC\n");
+		dev_info(&pdev->dev, "using PIO\n");
 		host->prepare_data = &atmci_prepare_data;
 		host->submit_data = &atmci_submit_data;
 		host->stop_transfer = &atmci_stop_transfer;
 	}
 
-	if (host->caps.has_dma)
-		atmci_configure_dma(host);
-
 	platform_set_drvdata(pdev, host);
 
 	/* We need at least one slot to succeed */
diff --git a/drivers/mmc/host/dw_mmc-pci.c b/drivers/mmc/host/dw_mmc-pci.c
new file mode 100644
index 0000000..dc0d25a
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-pci.c
@@ -0,0 +1,158 @@
+/*
+ * Synopsys DesignWare Multimedia Card PCI Interface driver
+ *
+ * Copyright (C) 2012 Vayavya Labs Pvt. Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/dw_mmc.h>
+#include "dw_mmc.h"
+
+#define PCI_BAR_NO 2
+#define COMPLETE_BAR 0
+#define SYNOPSYS_DW_MCI_VENDOR_ID 0x700
+#define SYNOPSYS_DW_MCI_DEVICE_ID 0x1107
+/* Defining the Capabilities */
+#define DW_MCI_CAPABILITIES (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED |\
+				MMC_CAP_SD_HIGHSPEED | MMC_CAP_8_BIT_DATA |\
+				MMC_CAP_SDIO_IRQ)
+
+static struct dw_mci_board pci_board_data = {
+	.num_slots			= 1,
+	.caps				= DW_MCI_CAPABILITIES,
+	.bus_hz				= 33 * 1000 * 1000,
+	.detect_delay_ms		= 200,
+	.fifo_depth			= 32,
+};
+
+static int __devinit dw_mci_pci_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *entries)
+{
+	struct dw_mci *host;
+	int ret;
+
+	ret = pci_enable_device(pdev);
+	if (ret)
+		return ret;
+	if (pci_request_regions(pdev, "dw_mmc_pci")) {
+		ret = -ENODEV;
+		goto err_disable_dev;
+	}
+
+	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
+	if (!host) {
+		ret = -ENOMEM;
+		goto err_release;
+	}
+
+	host->irq = pdev->irq;
+	host->irq_flags = IRQF_SHARED;
+	host->dev = pdev->dev;
+	host->pdata = &pci_board_data;
+
+	host->regs = pci_iomap(pdev, PCI_BAR_NO, COMPLETE_BAR);
+	if (!host->regs) {
+		ret = -EIO;
+		goto err_unmap;
+	}
+
+	pci_set_drvdata(pdev, host);
+	ret = dw_mci_probe(host);
+	if (ret)
+		goto err_probe_failed;
+	return ret;
+
+err_probe_failed:
+	pci_iounmap(pdev, host->regs);
+err_unmap:
+	kfree(host);
+err_release:
+	pci_release_regions(pdev);
+err_disable_dev:
+	pci_disable_device(pdev);
+	return ret;
+}
+
+static void __devexit dw_mci_pci_remove(struct pci_dev *pdev)
+{
+	struct dw_mci *host = pci_get_drvdata(pdev);
+
+	dw_mci_remove(host);
+	pci_set_drvdata(pdev, NULL);
+	pci_release_regions(pdev);
+	pci_iounmap(pdev, host->regs);
+	kfree(host);
+	pci_disable_device(pdev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dw_mci_pci_suspend(struct device *dev)
+{
+	int ret;
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct dw_mci *host = pci_get_drvdata(pdev);
+
+	ret = dw_mci_suspend(host);
+	return ret;
+}
+
+static int dw_mci_pci_resume(struct device *dev)
+{
+	int ret;
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct dw_mci *host = pci_get_drvdata(pdev);
+
+	ret = dw_mci_resume(host);
+	return ret;
+}
+#else
+#define dw_mci_pci_suspend	NULL
+#define dw_mci_pci_resume	NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(dw_mci_pci_pmops, dw_mci_pci_suspend, dw_mci_pci_resume);
+
+static DEFINE_PCI_DEVICE_TABLE(dw_mci_pci_id) = {
+	{ PCI_DEVICE(SYNOPSYS_DW_MCI_VENDOR_ID, SYNOPSYS_DW_MCI_DEVICE_ID) },
+	{}
+};
+MODULE_DEVICE_TABLE(pci, dw_mci_pci_id);
+
+static struct pci_driver dw_mci_pci_driver = {
+	.name		= "dw_mmc_pci",
+	.id_table	= dw_mci_pci_id,
+	.probe		= dw_mci_pci_probe,
+	.remove		= dw_mci_pci_remove,
+	.driver		=	{
+		.pm =   &dw_mci_pci_pmops
+	},
+};
+
+static int __init dw_mci_init(void)
+{
+	return pci_register_driver(&dw_mci_pci_driver);
+}
+
+static void __exit dw_mci_exit(void)
+{
+	pci_unregister_driver(&dw_mci_pci_driver);
+}
+
+module_init(dw_mci_init);
+module_exit(dw_mci_exit);
+
+MODULE_DESCRIPTION("DW Multimedia Card PCI Interface driver");
+MODULE_AUTHOR("Shashidhar Hiremath <shashidharh@vayavyalabs.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
new file mode 100644
index 0000000..92ec3eb
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -0,0 +1,134 @@
+/*
+ * Synopsys DesignWare Multimedia Card Interface driver
+ *
+ * Copyright (C) 2009 NXP Semiconductors
+ * Copyright (C) 2009, 2010 Imagination Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/dw_mmc.h>
+#include "dw_mmc.h"
+
+static int dw_mci_pltfm_probe(struct platform_device *pdev)
+{
+	struct dw_mci *host;
+	struct resource	*regs;
+	int ret;
+
+	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
+	if (!host)
+		return -ENOMEM;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		ret = -ENXIO;
+		goto err_free;
+	}
+
+	host->irq = platform_get_irq(pdev, 0);
+	if (host->irq < 0) {
+		ret = host->irq;
+		goto err_free;
+	}
+
+	host->dev = pdev->dev;
+	host->irq_flags = 0;
+	host->pdata = pdev->dev.platform_data;
+	ret = -ENOMEM;
+	host->regs = ioremap(regs->start, resource_size(regs));
+	if (!host->regs)
+		goto err_free;
+	platform_set_drvdata(pdev, host);
+	ret = dw_mci_probe(host);
+	if (ret)
+		goto err_out;
+	return ret;
+err_out:
+	iounmap(host->regs);
+err_free:
+	kfree(host);
+	return ret;
+}
+
+static int __exit dw_mci_pltfm_remove(struct platform_device *pdev)
+{
+	struct dw_mci *host = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	dw_mci_remove(host);
+	iounmap(host->regs);
+	kfree(host);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+/*
+ * TODO: we should probably disable the clock to the card in the suspend path.
+ */
+static int dw_mci_pltfm_suspend(struct device *dev)
+{
+	int ret;
+	struct dw_mci *host = dev_get_drvdata(dev);
+
+	ret = dw_mci_suspend(host);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int dw_mci_pltfm_resume(struct device *dev)
+{
+	int ret;
+	struct dw_mci *host = dev_get_drvdata(dev);
+
+	ret = dw_mci_resume(host);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+#else
+#define dw_mci_pltfm_suspend	NULL
+#define dw_mci_pltfm_resume	NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+
+static struct platform_driver dw_mci_pltfm_driver = {
+	.remove		= __exit_p(dw_mci_pltfm_remove),
+	.driver		= {
+		.name		= "dw_mmc",
+		.pm		= &dw_mci_pltfm_pmops,
+	},
+};
+
+static int __init dw_mci_init(void)
+{
+	return platform_driver_probe(&dw_mci_pltfm_driver, dw_mci_pltfm_probe);
+}
+
+static void __exit dw_mci_exit(void)
+{
+	platform_driver_unregister(&dw_mci_pltfm_driver);
+}
+
+module_init(dw_mci_init);
+module_exit(dw_mci_exit);
+
+MODULE_DESCRIPTION("DW Multimedia Card Interface driver");
+MODULE_AUTHOR("NXP Semiconductor VietNam");
+MODULE_AUTHOR("Imagination Technologies Ltd");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 8bec1c3..bf3c9b4 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -268,7 +268,7 @@ static void dw_mci_start_command(struct dw_mci *host,
 				 struct mmc_command *cmd, u32 cmd_flags)
 {
 	host->cmd = cmd;
-	dev_vdbg(&host->pdev->dev,
+	dev_vdbg(&host->dev,
 		 "start command: ARGR=0x%08x CMDR=0x%08x\n",
 		 cmd->arg, cmd_flags);
 
@@ -295,15 +295,25 @@ static void dw_mci_stop_dma(struct dw_mci *host)
 	}
 }
 
+static int dw_mci_get_dma_dir(struct mmc_data *data)
+{
+	if (data->flags & MMC_DATA_WRITE)
+		return DMA_TO_DEVICE;
+	else
+		return DMA_FROM_DEVICE;
+}
+
 #ifdef CONFIG_MMC_DW_IDMAC
 static void dw_mci_dma_cleanup(struct dw_mci *host)
 {
 	struct mmc_data *data = host->data;
 
 	if (data)
-		dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
-			     ((data->flags & MMC_DATA_WRITE)
-			      ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+		if (!data->host_cookie)
+			dma_unmap_sg(&host->dev,
+				     data->sg,
+				     data->sg_len,
+				     dw_mci_get_dma_dir(data));
 }
 
 static void dw_mci_idmac_stop_dma(struct dw_mci *host)
@@ -326,7 +336,7 @@ static void dw_mci_idmac_complete_dma(struct dw_mci *host)
 {
 	struct mmc_data *data = host->data;
 
-	dev_vdbg(&host->pdev->dev, "DMA complete\n");
+	dev_vdbg(&host->dev, "DMA complete\n");
 
 	host->dma_ops->cleanup(host);
 
@@ -428,17 +438,15 @@ static struct dw_mci_dma_ops dw_mci_idmac_ops = {
 };
 #endif /* CONFIG_MMC_DW_IDMAC */
 
-static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
+static int dw_mci_pre_dma_transfer(struct dw_mci *host,
+				   struct mmc_data *data,
+				   bool next)
 {
 	struct scatterlist *sg;
-	unsigned int i, direction, sg_len;
-	u32 temp;
+	unsigned int i, sg_len;
 
-	host->using_dma = 0;
-
-	/* If we don't have a channel, we can't do DMA */
-	if (!host->use_dma)
-		return -ENODEV;
+	if (!next && data->host_cookie)
+		return data->host_cookie;
 
 	/*
 	 * We don't do DMA on "complex" transfers, i.e. with
@@ -447,6 +455,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
 	 */
 	if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD)
 		return -EINVAL;
+
 	if (data->blksz & 3)
 		return -EINVAL;
 
@@ -455,17 +464,74 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
 			return -EINVAL;
 	}
 
-	host->using_dma = 1;
+	sg_len = dma_map_sg(&host->dev,
+			    data->sg,
+			    data->sg_len,
+			    dw_mci_get_dma_dir(data));
+	if (sg_len == 0)
+		return -EINVAL;
 
-	if (data->flags & MMC_DATA_READ)
-		direction = DMA_FROM_DEVICE;
-	else
-		direction = DMA_TO_DEVICE;
+	if (next)
+		data->host_cookie = sg_len;
 
-	sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len,
-			    direction);
+	return sg_len;
+}
 
-	dev_vdbg(&host->pdev->dev,
+static void dw_mci_pre_req(struct mmc_host *mmc,
+			   struct mmc_request *mrq,
+			   bool is_first_req)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct mmc_data *data = mrq->data;
+
+	if (!slot->host->use_dma || !data)
+		return;
+
+	if (data->host_cookie) {
+		data->host_cookie = 0;
+		return;
+	}
+
+	if (dw_mci_pre_dma_transfer(slot->host, mrq->data, 1) < 0)
+		data->host_cookie = 0;
+}
+
+static void dw_mci_post_req(struct mmc_host *mmc,
+			    struct mmc_request *mrq,
+			    int err)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct mmc_data *data = mrq->data;
+
+	if (!slot->host->use_dma || !data)
+		return;
+
+	if (data->host_cookie)
+		dma_unmap_sg(&slot->host->dev,
+			     data->sg,
+			     data->sg_len,
+			     dw_mci_get_dma_dir(data));
+	data->host_cookie = 0;
+}
+
+static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
+{
+	int sg_len;
+	u32 temp;
+
+	host->using_dma = 0;
+
+	/* If we don't have a channel, we can't do DMA */
+	if (!host->use_dma)
+		return -ENODEV;
+
+	sg_len = dw_mci_pre_dma_transfer(host, data, 0);
+	if (sg_len < 0)
+		return sg_len;
+
+	host->using_dma = 1;
+
+	dev_vdbg(&host->dev,
 		 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
 		 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
 		 sg_len);
@@ -579,8 +645,8 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
 			     SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
 
 		/* enable clock */
-		mci_writel(host, CLKENA, SDMMC_CLKEN_ENABLE |
-			   SDMMC_CLKEN_LOW_PWR);
+		mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE |
+			   SDMMC_CLKEN_LOW_PWR) << slot->id));
 
 		/* inform CIU */
 		mci_send_cmd(slot,
@@ -800,6 +866,8 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
 
 static const struct mmc_host_ops dw_mci_ops = {
 	.request		= dw_mci_request,
+	.pre_req		= dw_mci_pre_req,
+	.post_req		= dw_mci_post_req,
 	.set_ios		= dw_mci_set_ios,
 	.get_ro			= dw_mci_get_ro,
 	.get_cd			= dw_mci_get_cd,
@@ -821,12 +889,12 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
 		slot = list_entry(host->queue.next,
 				  struct dw_mci_slot, queue_node);
 		list_del(&slot->queue_node);
-		dev_vdbg(&host->pdev->dev, "list not empty: %s is next\n",
+		dev_vdbg(&host->dev, "list not empty: %s is next\n",
 			 mmc_hostname(slot->mmc));
 		host->state = STATE_SENDING_CMD;
 		dw_mci_start_request(host, slot);
 	} else {
-		dev_vdbg(&host->pdev->dev, "list empty\n");
+		dev_vdbg(&host->dev, "list empty\n");
 		host->state = STATE_IDLE;
 	}
 
@@ -965,7 +1033,7 @@ static void dw_mci_tasklet_func(unsigned long priv)
 					data->bytes_xfered = 0;
 					data->error = -ETIMEDOUT;
 				} else {
-					dev_err(&host->pdev->dev,
+					dev_err(&host->dev,
 						"data FIFO error "
 						"(status=%08x)\n",
 						status);
@@ -1682,7 +1750,7 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 	struct mmc_host *mmc;
 	struct dw_mci_slot *slot;
 
-	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &host->pdev->dev);
+	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &host->dev);
 	if (!mmc)
 		return -ENOMEM;
 
@@ -1720,13 +1788,11 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 	if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
-#ifdef CONFIG_MMC_DW_IDMAC
-	mmc->max_segs = host->ring_size;
-	mmc->max_blk_size = 65536;
-	mmc->max_blk_count = host->ring_size;
-	mmc->max_seg_size = 0x1000;
-	mmc->max_req_size = mmc->max_seg_size * mmc->max_blk_count;
-#else
+	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
+		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
+	else
+		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
+
 	if (host->pdata->blk_settings) {
 		mmc->max_segs = host->pdata->blk_settings->max_segs;
 		mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
@@ -1735,13 +1801,20 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 		mmc->max_seg_size = host->pdata->blk_settings->max_seg_size;
 	} else {
 		/* Useful defaults if platform data is unset. */
+#ifdef CONFIG_MMC_DW_IDMAC
+		mmc->max_segs = host->ring_size;
+		mmc->max_blk_size = 65536;
+		mmc->max_blk_count = host->ring_size;
+		mmc->max_seg_size = 0x1000;
+		mmc->max_req_size = mmc->max_seg_size * mmc->max_blk_count;
+#else
 		mmc->max_segs = 64;
 		mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
 		mmc->max_blk_count = 512;
 		mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
 		mmc->max_seg_size = mmc->max_req_size;
-	}
 #endif /* CONFIG_MMC_DW_IDMAC */
+	}
 
 	host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
 	if (IS_ERR(host->vmmc)) {
@@ -1789,10 +1862,10 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
 static void dw_mci_init_dma(struct dw_mci *host)
 {
 	/* Alloc memory for sg translation */
-	host->sg_cpu = dma_alloc_coherent(&host->pdev->dev, PAGE_SIZE,
+	host->sg_cpu = dma_alloc_coherent(&host->dev, PAGE_SIZE,
 					  &host->sg_dma, GFP_KERNEL);
 	if (!host->sg_cpu) {
-		dev_err(&host->pdev->dev, "%s: could not alloc DMA memory\n",
+		dev_err(&host->dev, "%s: could not alloc DMA memory\n",
 			__func__);
 		goto no_dma;
 	}
@@ -1800,7 +1873,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
 	/* Determine which DMA interface to use */
 #ifdef CONFIG_MMC_DW_IDMAC
 	host->dma_ops = &dw_mci_idmac_ops;
-	dev_info(&host->pdev->dev, "Using internal DMA controller.\n");
+	dev_info(&host->dev, "Using internal DMA controller.\n");
 #endif
 
 	if (!host->dma_ops)
@@ -1808,12 +1881,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
 
 	if (host->dma_ops->init) {
 		if (host->dma_ops->init(host)) {
-			dev_err(&host->pdev->dev, "%s: Unable to initialize "
+			dev_err(&host->dev, "%s: Unable to initialize "
 				"DMA Controller.\n", __func__);
 			goto no_dma;
 		}
 	} else {
-		dev_err(&host->pdev->dev, "DMA initialization not found.\n");
+		dev_err(&host->dev, "DMA initialization not found.\n");
 		goto no_dma;
 	}
 
@@ -1821,7 +1894,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
 	return;
 
 no_dma:
-	dev_info(&host->pdev->dev, "Using PIO mode.\n");
+	dev_info(&host->dev, "Using PIO mode.\n");
 	host->use_dma = 0;
 	return;
 }
@@ -1847,61 +1920,37 @@ static bool mci_wait_reset(struct device *dev, struct dw_mci *host)
 	return false;
 }
 
-static int dw_mci_probe(struct platform_device *pdev)
+int dw_mci_probe(struct dw_mci *host)
 {
-	struct dw_mci *host;
-	struct resource	*regs;
-	struct dw_mci_board *pdata;
-	int irq, ret, i, width;
+	int width, i, ret = 0;
 	u32 fifo_size;
 
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs)
-		return -ENXIO;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
-	if (!host)
-		return -ENOMEM;
-
-	host->pdev = pdev;
-	host->pdata = pdata = pdev->dev.platform_data;
-	if (!pdata || !pdata->init) {
-		dev_err(&pdev->dev,
+	if (!host->pdata || !host->pdata->init) {
+		dev_err(&host->dev,
 			"Platform data must supply init function\n");
-		ret = -ENODEV;
-		goto err_freehost;
+		return -ENODEV;
 	}
 
-	if (!pdata->select_slot && pdata->num_slots > 1) {
-		dev_err(&pdev->dev,
+	if (!host->pdata->select_slot && host->pdata->num_slots > 1) {
+		dev_err(&host->dev,
 			"Platform data must supply select_slot function\n");
-		ret = -ENODEV;
-		goto err_freehost;
+		return -ENODEV;
 	}
 
-	if (!pdata->bus_hz) {
-		dev_err(&pdev->dev,
+	if (!host->pdata->bus_hz) {
+		dev_err(&host->dev,
 			"Platform data must supply bus speed\n");
-		ret = -ENODEV;
-		goto err_freehost;
+		return -ENODEV;
 	}
 
-	host->bus_hz = pdata->bus_hz;
-	host->quirks = pdata->quirks;
+	host->bus_hz = host->pdata->bus_hz;
+	host->quirks = host->pdata->quirks;
 
 	spin_lock_init(&host->lock);
 	INIT_LIST_HEAD(&host->queue);
 
-	ret = -ENOMEM;
-	host->regs = ioremap(regs->start, resource_size(regs));
-	if (!host->regs)
-		goto err_freehost;
 
-	host->dma_ops = pdata->dma_ops;
+	host->dma_ops = host->pdata->dma_ops;
 	dw_mci_init_dma(host);
 
 	/*
@@ -1931,7 +1980,7 @@ static int dw_mci_probe(struct platform_device *pdev)
 	}
 
 	/* Reset all blocks */
-	if (!mci_wait_reset(&pdev->dev, host)) {
+	if (!mci_wait_reset(&host->dev, host)) {
 		ret = -ENODEV;
 		goto err_dmaunmap;
 	}
@@ -1974,13 +2023,10 @@ static int dw_mci_probe(struct platform_device *pdev)
 	if (!dw_mci_card_workqueue)
 		goto err_dmaunmap;
 	INIT_WORK(&host->card_work, dw_mci_work_routine_card);
-
-	ret = request_irq(irq, dw_mci_interrupt, 0, "dw-mci", host);
+	ret = request_irq(host->irq, dw_mci_interrupt, host->irq_flags, "dw-mci", host);
 	if (ret)
 		goto err_workqueue;
 
-	platform_set_drvdata(pdev, host);
-
 	if (host->pdata->num_slots)
 		host->num_slots = host->pdata->num_slots;
 	else
@@ -2000,7 +2046,7 @@ static int dw_mci_probe(struct platform_device *pdev)
 	 * Need to check the version-id and set data-offset for DATA register.
 	 */
 	host->verid = SDMMC_GET_VERID(mci_readl(host, VERID));
-	dev_info(&pdev->dev, "Version ID is %04x\n", host->verid);
+	dev_info(&host->dev, "Version ID is %04x\n", host->verid);
 
 	if (host->verid < DW_MMC_240A)
 		host->data_offset = DATA_OFFSET;
@@ -2017,12 +2063,12 @@ static int dw_mci_probe(struct platform_device *pdev)
 		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
 	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
 
-	dev_info(&pdev->dev, "DW MMC controller at irq %d, "
+	dev_info(&host->dev, "DW MMC controller at irq %d, "
 		 "%d bit host data width, "
 		 "%u deep fifo\n",
-		 irq, width, fifo_size);
+		 host->irq, width, fifo_size);
 	if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
-		dev_info(&pdev->dev, "Internal DMAC interrupt fix enabled.\n");
+		dev_info(&host->dev, "Internal DMAC interrupt fix enabled.\n");
 
 	return 0;
 
@@ -2033,7 +2079,7 @@ err_init_slot:
 			dw_mci_cleanup_slot(host->slot[i], i);
 		i--;
 	}
-	free_irq(irq, host);
+	free_irq(host->irq, host);
 
 err_workqueue:
 	destroy_workqueue(dw_mci_card_workqueue);
@@ -2041,33 +2087,26 @@ err_workqueue:
 err_dmaunmap:
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
-	dma_free_coherent(&host->pdev->dev, PAGE_SIZE,
+	dma_free_coherent(&host->dev, PAGE_SIZE,
 			  host->sg_cpu, host->sg_dma);
-	iounmap(host->regs);
 
 	if (host->vmmc) {
 		regulator_disable(host->vmmc);
 		regulator_put(host->vmmc);
 	}
-
-
-err_freehost:
-	kfree(host);
 	return ret;
 }
+EXPORT_SYMBOL(dw_mci_probe);
 
-static int __exit dw_mci_remove(struct platform_device *pdev)
+void dw_mci_remove(struct dw_mci *host)
 {
-	struct dw_mci *host = platform_get_drvdata(pdev);
 	int i;
 
 	mci_writel(host, RINTSTS, 0xFFFFFFFF);
 	mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
 
-	platform_set_drvdata(pdev, NULL);
-
 	for (i = 0; i < host->num_slots; i++) {
-		dev_dbg(&pdev->dev, "remove slot %d\n", i);
+		dev_dbg(&host->dev, "remove slot %d\n", i);
 		if (host->slot[i])
 			dw_mci_cleanup_slot(host->slot[i], i);
 	}
@@ -2076,9 +2115,9 @@ static int __exit dw_mci_remove(struct platform_device *pdev)
 	mci_writel(host, CLKENA, 0);
 	mci_writel(host, CLKSRC, 0);
 
-	free_irq(platform_get_irq(pdev, 0), host);
+	free_irq(host->irq, host);
 	destroy_workqueue(dw_mci_card_workqueue);
-	dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+	dma_free_coherent(&host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
 
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
@@ -2088,20 +2127,18 @@ static int __exit dw_mci_remove(struct platform_device *pdev)
 		regulator_put(host->vmmc);
 	}
 
-	iounmap(host->regs);
-
-	kfree(host);
-	return 0;
 }
+EXPORT_SYMBOL(dw_mci_remove);
+
+
 
 #ifdef CONFIG_PM_SLEEP
 /*
  * TODO: we should probably disable the clock to the card in the suspend path.
  */
-static int dw_mci_suspend(struct device *dev)
+int dw_mci_suspend(struct dw_mci *host)
 {
-	int i, ret;
-	struct dw_mci *host = dev_get_drvdata(dev);
+	int i, ret = 0;
 
 	for (i = 0; i < host->num_slots; i++) {
 		struct dw_mci_slot *slot = host->slot[i];
@@ -2123,11 +2160,11 @@ static int dw_mci_suspend(struct device *dev)
 
 	return 0;
 }
+EXPORT_SYMBOL(dw_mci_suspend);
 
-static int dw_mci_resume(struct device *dev)
+int dw_mci_resume(struct dw_mci *host)
 {
 	int i, ret;
-	struct dw_mci *host = dev_get_drvdata(dev);
 
 	if (host->vmmc)
 		regulator_enable(host->vmmc);
@@ -2135,7 +2172,7 @@ static int dw_mci_resume(struct device *dev)
 	if (host->dma_ops->init)
 		host->dma_ops->init(host);
 
-	if (!mci_wait_reset(dev, host)) {
+	if (!mci_wait_reset(&host->dev, host)) {
 		ret = -ENODEV;
 		return ret;
 	}
@@ -2157,32 +2194,19 @@ static int dw_mci_resume(struct device *dev)
 		if (ret < 0)
 			return ret;
 	}
-
 	return 0;
 }
-#else
-#define dw_mci_suspend	NULL
-#define dw_mci_resume	NULL
+EXPORT_SYMBOL(dw_mci_resume);
 #endif /* CONFIG_PM_SLEEP */
 
-static SIMPLE_DEV_PM_OPS(dw_mci_pmops, dw_mci_suspend, dw_mci_resume);
-
-static struct platform_driver dw_mci_driver = {
-	.remove		= __exit_p(dw_mci_remove),
-	.driver		= {
-		.name		= "dw_mmc",
-		.pm		= &dw_mci_pmops,
-	},
-};
-
 static int __init dw_mci_init(void)
 {
-	return platform_driver_probe(&dw_mci_driver, dw_mci_probe);
+	printk(KERN_INFO "Synopsys Designware Multimedia Card Interface Driver");
+	return 0;
 }
 
 static void __exit dw_mci_exit(void)
 {
-	platform_driver_unregister(&dw_mci_driver);
 }
 
 module_init(dw_mci_init);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index df392a1..15c27e1 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -175,4 +175,11 @@
 	(*(volatile u64 __force *)((dev)->regs + SDMMC_##reg) = (value))
 #endif
 
+extern int dw_mci_probe(struct dw_mci *host);
+extern void dw_mci_remove(struct dw_mci *host);
+#ifdef CONFIG_PM
+extern int dw_mci_suspend(struct dw_mci *host);
+extern int dw_mci_resume(struct dw_mci *host);
+#endif
+
 #endif /* _DW_MMC_H_ */
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 0d955ff..63a6295 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -53,6 +53,8 @@ static unsigned int fmax = 515633;
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
+ * @pwrreg_powerup: power up value for MMCIPOWER register
+ * @signal_direction: input/out direction of bus signals can be indicated
  */
 struct variant_data {
 	unsigned int		clkreg;
@@ -63,18 +65,22 @@ struct variant_data {
 	bool			sdio;
 	bool			st_clkdiv;
 	bool			blksz_datactrl16;
+	u32			pwrreg_powerup;
+	bool			signal_direction;
 };
 
 static struct variant_data variant_arm = {
 	.fifosize		= 16 * 4,
 	.fifohalfsize		= 8 * 4,
 	.datalength_bits	= 16,
+	.pwrreg_powerup		= MCI_PWR_UP,
 };
 
 static struct variant_data variant_arm_extended_fifo = {
 	.fifosize		= 128 * 4,
 	.fifohalfsize		= 64 * 4,
 	.datalength_bits	= 16,
+	.pwrreg_powerup		= MCI_PWR_UP,
 };
 
 static struct variant_data variant_u300 = {
@@ -83,6 +89,8 @@ static struct variant_data variant_u300 = {
 	.clkreg_enable		= MCI_ST_U300_HWFCEN,
 	.datalength_bits	= 16,
 	.sdio			= true,
+	.pwrreg_powerup		= MCI_PWR_ON,
+	.signal_direction	= true,
 };
 
 static struct variant_data variant_ux500 = {
@@ -93,6 +101,8 @@ static struct variant_data variant_ux500 = {
 	.datalength_bits	= 24,
 	.sdio			= true,
 	.st_clkdiv		= true,
+	.pwrreg_powerup		= MCI_PWR_ON,
+	.signal_direction	= true,
 };
 
 static struct variant_data variant_ux500v2 = {
@@ -104,11 +114,35 @@ static struct variant_data variant_ux500v2 = {
 	.sdio			= true,
 	.st_clkdiv		= true,
 	.blksz_datactrl16	= true,
+	.pwrreg_powerup		= MCI_PWR_ON,
+	.signal_direction	= true,
 };
 
 /*
  * This must be called with host->lock held
  */
+static void mmci_write_clkreg(struct mmci_host *host, u32 clk)
+{
+	if (host->clk_reg != clk) {
+		host->clk_reg = clk;
+		writel(clk, host->base + MMCICLOCK);
+	}
+}
+
+/*
+ * This must be called with host->lock held
+ */
+static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr)
+{
+	if (host->pwr_reg != pwr) {
+		host->pwr_reg = pwr;
+		writel(pwr, host->base + MMCIPOWER);
+	}
+}
+
+/*
+ * This must be called with host->lock held
+ */
 static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
 {
 	struct variant_data *variant = host->variant;
@@ -153,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
 	if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
 		clk |= MCI_ST_8BIT_BUS;
 
-	writel(clk, host->base + MMCICLOCK);
+	mmci_write_clkreg(host, clk);
 }
 
 static void
@@ -166,14 +200,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 	host->mrq = NULL;
 	host->cmd = NULL;
 
-	/*
-	 * Need to drop the host lock here; mmc_request_done may call
-	 * back into the driver...
-	 */
-	spin_unlock(&host->lock);
-	pm_runtime_put(mmc_dev(host->mmc));
 	mmc_request_done(host->mmc, mrq);
-	spin_lock(&host->lock);
+
+	pm_runtime_mark_last_busy(mmc_dev(host->mmc));
+	pm_runtime_put_autosuspend(mmc_dev(host->mmc));
 }
 
 static void mmci_set_mask1(struct mmci_host *host, unsigned int mask)
@@ -607,6 +637,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
 	if (data->flags & MMC_DATA_READ)
 		datactrl |= MCI_DPSM_DIRECTION;
 
+	/* The ST Micro variants has a special bit to enable SDIO */
+	if (variant->sdio && host->mmc->card)
+		if (mmc_card_sdio(host->mmc->card))
+			datactrl |= MCI_ST_DPSM_SDIOEN;
+
 	/*
 	 * Attempt to use DMA operation mode, if this
 	 * should fail, fall back to PIO mode
@@ -635,11 +670,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
 		irqmask = MCI_TXFIFOHALFEMPTYMASK;
 	}
 
-	/* The ST Micro variants has a special bit to enable SDIO */
-	if (variant->sdio && host->mmc->card)
-		if (mmc_card_sdio(host->mmc->card))
-			datactrl |= MCI_ST_DPSM_SDIOEN;
-
 	writel(datactrl, base + MMCIDATACTRL);
 	writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0);
 	mmci_set_mask1(host, irqmask);
@@ -786,7 +816,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema
 		if (count <= 0)
 			break;
 
-		readsl(base + MMCIFIFO, ptr, count >> 2);
+		/*
+		 * SDIO especially may want to send something that is
+		 * not divisible by 4 (as opposed to card sectors
+		 * etc). Therefore make sure to always read the last bytes
+		 * while only doing full 32-bit reads towards the FIFO.
+		 */
+		if (unlikely(count & 0x3)) {
+			if (count < 4) {
+				unsigned char buf[4];
+				readsl(base + MMCIFIFO, buf, 1);
+				memcpy(ptr, buf, count);
+			} else {
+				readsl(base + MMCIFIFO, ptr, count >> 2);
+				count &= ~0x3;
+			}
+		} else {
+			readsl(base + MMCIFIFO, ptr, count >> 2);
+		}
 
 		ptr += count;
 		remain -= count;
@@ -821,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem
 		 */
 		if (variant->sdio &&
 		    mmc_card_sdio(host->mmc->card)) {
+			u32 clk;
 			if (count < 8)
-				writel(readl(host->base + MMCICLOCK) &
-					~variant->clkreg_enable,
-					host->base + MMCICLOCK);
+				clk = host->clk_reg & ~variant->clkreg_enable;
 			else
-				writel(readl(host->base + MMCICLOCK) |
-					variant->clkreg_enable,
-					host->base + MMCICLOCK);
+				clk = host->clk_reg | variant->clkreg_enable;
+
+			mmci_write_clkreg(host, clk);
 		}
 
 		/*
@@ -1015,10 +1061,17 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct mmci_host *host = mmc_priv(mmc);
+	struct variant_data *variant = host->variant;
 	u32 pwr = 0;
 	unsigned long flags;
 	int ret;
 
+	pm_runtime_get_sync(mmc_dev(mmc));
+
+	if (host->plat->ios_handler &&
+		host->plat->ios_handler(mmc_dev(mmc), ios))
+			dev_err(mmc_dev(mmc), "platform ios_handler failed\n");
+
 	switch (ios->power_mode) {
 	case MMC_POWER_OFF:
 		if (host->vcc)
@@ -1035,22 +1088,38 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 				 * power should be rare so we print an error
 				 * and return here.
 				 */
-				return;
+				goto out;
 			}
 		}
-		if (host->plat->vdd_handler)
-			pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd,
-						       ios->power_mode);
-		/* The ST version does not have this, fall through to POWER_ON */
-		if (host->hw_designer != AMBA_VENDOR_ST) {
-			pwr |= MCI_PWR_UP;
-			break;
-		}
+		/*
+		 * The ST Micro variant doesn't have the PL180s MCI_PWR_UP
+		 * and instead uses MCI_PWR_ON so apply whatever value is
+		 * configured in the variant data.
+		 */
+		pwr |= variant->pwrreg_powerup;
+
+		break;
 	case MMC_POWER_ON:
 		pwr |= MCI_PWR_ON;
 		break;
 	}
 
+	if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) {
+		/*
+		 * The ST Micro variant has some additional bits
+		 * indicating signal direction for the signals in
+		 * the SD/MMC bus and feedback-clock usage.
+		 */
+		pwr |= host->plat->sigdir;
+
+		if (ios->bus_width == MMC_BUS_WIDTH_4)
+			pwr &= ~MCI_ST_DATA74DIREN;
+		else if (ios->bus_width == MMC_BUS_WIDTH_1)
+			pwr &= (~MCI_ST_DATA74DIREN &
+				~MCI_ST_DATA31DIREN &
+				~MCI_ST_DATA2DIREN);
+	}
+
 	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
 		if (host->hw_designer != AMBA_VENDOR_ST)
 			pwr |= MCI_ROD;
@@ -1066,13 +1135,13 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	spin_lock_irqsave(&host->lock, flags);
 
 	mmci_set_clkreg(host, ios->clock);
-
-	if (host->pwr != pwr) {
-		host->pwr = pwr;
-		writel(pwr, host->base + MMCIPOWER);
-	}
+	mmci_write_pwrreg(host, pwr);
 
 	spin_unlock_irqrestore(&host->lock, flags);
+
+ out:
+	pm_runtime_mark_last_busy(mmc_dev(mmc));
+	pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 
 static int mmci_get_ro(struct mmc_host *mmc)
@@ -1325,7 +1394,7 @@ static int __devinit mmci_probe(struct amba_device *dev,
 	if (ret)
 		goto unmap;
 
-	if (dev->irq[1] == NO_IRQ)
+	if (dev->irq[1] == NO_IRQ || !dev->irq[1])
 		host->singleirq = true;
 	else {
 		ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
@@ -1345,6 +1414,8 @@ static int __devinit mmci_probe(struct amba_device *dev,
 
 	mmci_dma_setup(host);
 
+	pm_runtime_set_autosuspend_delay(&dev->dev, 50);
+	pm_runtime_use_autosuspend(&dev->dev);
 	pm_runtime_put(&dev->dev);
 
 	mmc_add_host(mmc);
@@ -1429,43 +1500,49 @@ static int __devexit mmci_remove(struct amba_device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int mmci_suspend(struct amba_device *dev, pm_message_t state)
+#ifdef CONFIG_SUSPEND
+static int mmci_suspend(struct device *dev)
 {
-	struct mmc_host *mmc = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
 	int ret = 0;
 
 	if (mmc) {
 		struct mmci_host *host = mmc_priv(mmc);
 
 		ret = mmc_suspend_host(mmc);
-		if (ret == 0)
+		if (ret == 0) {
+			pm_runtime_get_sync(dev);
 			writel(0, host->base + MMCIMASK0);
+		}
 	}
 
 	return ret;
 }
 
-static int mmci_resume(struct amba_device *dev)
+static int mmci_resume(struct device *dev)
 {
-	struct mmc_host *mmc = amba_get_drvdata(dev);
+	struct amba_device *adev = to_amba_device(dev);
+	struct mmc_host *mmc = amba_get_drvdata(adev);
 	int ret = 0;
 
 	if (mmc) {
 		struct mmci_host *host = mmc_priv(mmc);
 
 		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
+		pm_runtime_put(dev);
 
 		ret = mmc_resume_host(mmc);
 	}
 
 	return ret;
 }
-#else
-#define mmci_suspend	NULL
-#define mmci_resume	NULL
 #endif
 
+static const struct dev_pm_ops mmci_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
+};
+
 static struct amba_id mmci_ids[] = {
 	{
 		.id	= 0x00041180,
@@ -1511,11 +1588,10 @@ MODULE_DEVICE_TABLE(amba, mmci_ids);
 static struct amba_driver mmci_driver = {
 	.drv		= {
 		.name	= DRIVER_NAME,
+		.pm	= &mmci_dev_pm_ops,
 	},
 	.probe		= mmci_probe,
 	.remove		= __devexit_p(mmci_remove),
-	.suspend	= mmci_suspend,
-	.resume		= mmci_resume,
 	.id_table	= mmci_ids,
 };
 
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 79e4143..d437ccf 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -13,16 +13,6 @@
 #define MCI_PWR_ON		0x03
 #define MCI_OD			(1 << 6)
 #define MCI_ROD			(1 << 7)
-/*
- * The ST Micro version does not have ROD and reuse the voltage registers
- * for direction settings
- */
-#define MCI_ST_DATA2DIREN	(1 << 2)
-#define MCI_ST_CMDDIREN		(1 << 3)
-#define MCI_ST_DATA0DIREN	(1 << 4)
-#define MCI_ST_DATA31DIREN	(1 << 5)
-#define MCI_ST_FBCLKEN		(1 << 7)
-#define MCI_ST_DATA74DIREN	(1 << 8)
 
 #define MMCICLOCK		0x004
 #define MCI_CLK_ENABLE		(1 << 8)
@@ -160,7 +150,7 @@
 	(MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \
 	 MCI_TXFIFOHALFEMPTYMASK)
 
-#define NR_SG		16
+#define NR_SG		128
 
 struct clk;
 struct variant_data;
@@ -189,7 +179,8 @@ struct mmci_host {
 
 	unsigned int		mclk;
 	unsigned int		cclk;
-	u32			pwr;
+	u32			pwr_reg;
+	u32			clk_reg;
 	struct mmci_platform_data *plat;
 	struct variant_data	*variant;
 
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 4184b79..f35b6ba 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -267,6 +267,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
 	wmb();
 
 	dmaengine_submit(host->desc);
+	dma_async_issue_pending(host->dma);
 
 	return 0;
 }
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index fd0c661..36e7f5b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1912,8 +1912,12 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
 	if (mmc_slot(host).vcc_aux_disable_is_sleep)
 		mmc_slot(host).no_off = 1;
 
-	mmc->f_min	= OMAP_MMC_MIN_CLOCK;
-	mmc->f_max	= OMAP_MMC_MAX_CLOCK;
+	mmc->f_min = OMAP_MMC_MIN_CLOCK;
+
+	if (pdata->max_freq > 0)
+		mmc->f_max = pdata->max_freq;
+	else
+		mmc->f_max = OMAP_MMC_MAX_CLOCK;
 
 	spin_lock_init(&host->irq_lock);
 
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 1bcfd6d..c3622a6 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1606,7 +1606,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev)
 	host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!host->mem) {
 		dev_err(&pdev->dev,
-			"failed to get io memory region resouce.\n");
+			"failed to get io memory region resource.\n");
 
 		ret = -ENOENT;
 		goto probe_free_gpio;
@@ -1630,7 +1630,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev)
 
 	host->irq = platform_get_irq(pdev, 0);
 	if (host->irq == 0) {
-		dev_err(&pdev->dev, "failed to get interrupt resouce.\n");
+		dev_err(&pdev->dev, "failed to get interrupt resource.\n");
 		ret = -EINVAL;
 		goto probe_iounmap;
 	}
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index d601e41..f4e82d4 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -463,7 +463,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
 		err = PTR_ERR(clk);
 		goto err_clk_get;
 	}
-	clk_enable(clk);
+	clk_prepare_enable(clk);
 	pltfm_host->clk = clk;
 
 	if (!is_imx25_esdhc(imx_data))
@@ -558,7 +558,7 @@ no_card_detect_irq:
 		gpio_free(boarddata->wp_gpio);
 no_card_detect_pin:
 no_board_data:
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 err_clk_get:
 	kfree(imx_data);
@@ -585,7 +585,7 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
 		gpio_free(boarddata->cd_gpio);
 	}
 
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 	kfree(imx_data);
 
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 5d876ff..f8eb1fb 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -1,7 +1,7 @@
 /*
  * Freescale eSDHC controller driver.
  *
- * Copyright (c) 2007, 2010 Freescale Semiconductor, Inc.
+ * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc.
  * Copyright (c) 2009 MontaVista Software, Inc.
  *
  * Authors: Xiaobo Xie <X.Xie@freescale.com>
@@ -14,6 +14,7 @@
  */
 
 #include <linux/io.h>
+#include <linux/of.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/mmc/host.h>
@@ -114,6 +115,34 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 	return pltfm_host->clock / 256 / 16;
 }
 
+static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	/* Workaround to reduce the clock frequency for p1010 esdhc */
+	if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) {
+		if (clock > 20000000)
+			clock -= 5000000;
+		if (clock > 40000000)
+			clock -= 5000000;
+	}
+
+	/* Set the clock */
+	esdhc_set_clock(host, clock);
+}
+
+#ifdef CONFIG_PM
+static u32 esdhc_proctl;
+static void esdhc_of_suspend(struct sdhci_host *host)
+{
+	esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL);
+}
+
+static void esdhc_of_resume(struct sdhci_host *host)
+{
+	esdhc_of_enable_dma(host);
+	sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL);
+}
+#endif
+
 static struct sdhci_ops sdhci_esdhc_ops = {
 	.read_l = sdhci_be32bs_readl,
 	.read_w = esdhc_readw,
@@ -121,10 +150,14 @@ static struct sdhci_ops sdhci_esdhc_ops = {
 	.write_l = sdhci_be32bs_writel,
 	.write_w = esdhc_writew,
 	.write_b = esdhc_writeb,
-	.set_clock = esdhc_set_clock,
+	.set_clock = esdhc_of_set_clock,
 	.enable_dma = esdhc_of_enable_dma,
 	.get_max_clock = esdhc_of_get_max_clock,
 	.get_min_clock = esdhc_of_get_min_clock,
+#ifdef CONFIG_PM
+	.platform_suspend = esdhc_of_suspend,
+	.platform_resume = esdhc_of_resume,
+#endif
 };
 
 static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 1af756e..a2bfbe0 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -20,6 +20,8 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <linux/mmc/host.h>
 
@@ -29,6 +31,8 @@
 #include "sdhci.h"
 
 #define MAX_BUS_CLK	(4)
+/* Number of gpio's used is max data bus width + command and clock lines */
+#define NUM_GPIOS(x)	(x + 2)
 
 /**
  * struct sdhci_s3c - S3C SDHCI instance
@@ -37,6 +41,7 @@
  * @ioarea: The resource created when we claimed the IO area.
  * @pdata: The platform data for this controller.
  * @cur_clk: The index of the current bus clock.
+ * @gpios: List of gpio numbers parsed from device tree.
  * @clk_io: The clock for the internal bus interface.
  * @clk_bus: The clocks that are available for the SD/MMC bus clock.
  */
@@ -48,11 +53,24 @@ struct sdhci_s3c {
 	unsigned int		cur_clk;
 	int			ext_cd_irq;
 	int			ext_cd_gpio;
+	int			*gpios;
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
 };
 
+/**
+ * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data
+ * @sdhci_quirks: sdhci host specific quirks.
+ *
+ * Specifies platform specific configuration of sdhci controller.
+ * Note: A structure for driver specific platform data is used for future
+ * expansion of its usage.
+ */
+struct sdhci_s3c_drv_data {
+	unsigned int	sdhci_quirks;
+};
+
 static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
 {
 	return sdhci_priv(host);
@@ -132,10 +150,10 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost,
 		return UINT_MAX;
 
 	/*
-	 * Clock divider's step is different as 1 from that of host controller
-	 * when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL.
+	 * If controller uses a non-standard clock division, find the best clock
+	 * speed possible with selected clock source and skip the division.
 	 */
-	if (ourhost->pdata->clk_type) {
+	if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
 		rate = clk_round_rate(clksrc, wanted);
 		return wanted - rate;
 	}
@@ -272,6 +290,8 @@ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host)
 static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_s3c *ourhost = to_s3c(host);
+	unsigned long timeout;
+	u16 clk = 0;
 
 	/* don't bother if the clock is going off */
 	if (clock == 0)
@@ -282,6 +302,25 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 	clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
 
 	host->clock = clock;
+
+	clk = SDHCI_CLOCK_INT_EN;
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+	/* Wait max 20 ms */
+	timeout = 20;
+	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
+		& SDHCI_CLOCK_INT_STABLE)) {
+		if (timeout == 0) {
+			printk(KERN_ERR "%s: Internal clock never "
+				"stabilised.\n", mmc_hostname(host->mmc));
+			return;
+		}
+		timeout--;
+		mdelay(1);
+	}
+
+	clk |= SDHCI_CLOCK_CARD_EN;
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 }
 
 /**
@@ -382,16 +421,125 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc)
 	}
 }
 
+#ifdef CONFIG_OF
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+		struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+	struct device_node *node = dev->of_node;
+	struct sdhci_s3c *ourhost = to_s3c(host);
+	u32 max_width;
+	int gpio, cnt, ret;
+
+	/* if the bus-width property is not specified, assume width as 1 */
+	if (of_property_read_u32(node, "samsung,sdhci-bus-width",
+				&max_width))
+		max_width = 1;
+	pdata->max_width = max_width;
+
+	ourhost->gpios = devm_kzalloc(dev, NUM_GPIOS(pdata->max_width) *
+				sizeof(int), GFP_KERNEL);
+	if (!ourhost->gpios)
+		return -ENOMEM;
+
+	/* get the card detection method */
+	if (of_get_property(node, "samsung,sdhci-cd-internal", NULL))
+		pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
+	else if (of_get_property(node, "samsung,sdhci-cd-gpio", NULL))
+		pdata->cd_type = S3C_SDHCI_CD_GPIO;
+	else if (of_get_property(node, "samsung,sdhci-cd-none", NULL))
+		pdata->cd_type = S3C_SDHCI_CD_NONE;
+	else if (of_get_property(node, "samsung,sdhci-cd-permanent", NULL))
+		pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
+	else
+		pdata->cd_type = S3C_SDHCI_CD_NONE;
+
+	/* get the gpio used for card detection */
+	if (pdata->cd_type == S3C_SDHCI_CD_GPIO ||
+			pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		gpio = of_get_named_gpio(node, "gpio-cd", 0);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(dev, "invalid card detect gpio specified\n");
+			return -EINVAL;
+		}
+	}
+
+	if (pdata->cd_type == S3C_SDHCI_CD_GPIO) {
+		pdata->ext_cd_gpio = gpio;
+		ourhost->ext_cd_gpio = -1; /* invalid gpio number */
+		if (of_get_property(node, "samsung,cd-gpio-invert", NULL))
+			pdata->ext_cd_gpio_invert = 1;
+	} else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		ret = gpio_request(gpio, "sdhci-cd");
+		if (ret) {
+			dev_err(dev, "card detect gpio request failed\n");
+			return -EINVAL;
+		}
+		ourhost->ext_cd_gpio = gpio;
+	}
+
+	/* get the gpios for command, clock and data lines */
+	for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+		gpio = of_get_gpio(node, cnt);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(dev, "invalid gpio[%d]\n", cnt);
+			goto err_free_dt_cd_gpio;
+		}
+		ourhost->gpios[cnt] = gpio;
+	}
+
+	for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+		ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio");
+		if (ret) {
+			dev_err(dev, "gpio[%d] request failed\n", cnt);
+			goto err_free_dt_gpios;
+		}
+	}
+
+	return 0;
+
+ err_free_dt_gpios:
+	while (--cnt >= 0)
+		gpio_free(ourhost->gpios[cnt]);
+ err_free_dt_cd_gpio:
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+		gpio_free(ourhost->ext_cd_gpio);
+	return -EINVAL;
+}
+#else
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+		struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+	return -EINVAL;
+}
+#endif
+
+static const struct of_device_id sdhci_s3c_dt_match[];
+
+static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
+			struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(sdhci_s3c_dt_match, pdev->dev.of_node);
+		return (struct sdhci_s3c_drv_data *)match->data;
+	}
+#endif
+	return (struct sdhci_s3c_drv_data *)
+			platform_get_device_id(pdev)->driver_data;
+}
+
 static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 {
-	struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
+	struct s3c_sdhci_platdata *pdata;
+	struct sdhci_s3c_drv_data *drv_data;
 	struct device *dev = &pdev->dev;
 	struct sdhci_host *host;
 	struct sdhci_s3c *sc;
 	struct resource *res;
 	int ret, irq, ptr, clks;
 
-	if (!pdata) {
+	if (!pdev->dev.platform_data && !pdev->dev.of_node) {
 		dev_err(dev, "no device data specified\n");
 		return -ENOENT;
 	}
@@ -413,13 +561,28 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 		dev_err(dev, "sdhci_alloc_host() failed\n");
 		return PTR_ERR(host);
 	}
-
 	sc = sdhci_priv(host);
 
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		ret = -ENOMEM;
+		goto err_pdata;
+	}
+
+	if (pdev->dev.of_node) {
+		ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
+		if (ret)
+			goto err_pdata;
+	} else {
+		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+		sc->ext_cd_gpio = -1; /* invalid gpio number */
+	}
+
+	drv_data = sdhci_s3c_get_driver_data(pdev);
+
 	sc->host = host;
 	sc->pdev = pdev;
 	sc->pdata = pdata;
-	sc->ext_cd_gpio = -1; /* invalid gpio number */
 
 	platform_set_drvdata(pdev, host);
 
@@ -491,6 +654,8 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 	/* Setup quirks for the controller */
 	host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
+	if (drv_data)
+		host->quirks |= drv_data->sdhci_quirks;
 
 #ifndef CONFIG_MMC_SDHCI_S3C_DMA
 
@@ -518,8 +683,13 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 	if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
 		host->mmc->caps = MMC_CAP_NONREMOVABLE;
 
-	if (pdata->host_caps)
-		host->mmc->caps |= pdata->host_caps;
+	switch (pdata->max_width) {
+	case 8:
+		host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+	case 4:
+		host->mmc->caps |= MMC_CAP_4_BIT_DATA;
+		break;
+	}
 
 	if (pdata->pm_caps)
 		host->mmc->pm_caps |= pdata->pm_caps;
@@ -534,7 +704,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 	 * If controller does not have internal clock divider,
 	 * we can use overriding functions instead of default.
 	 */
-	if (pdata->clk_type) {
+	if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) {
 		sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock;
 		sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock;
 		sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock;
@@ -544,6 +714,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 	if (pdata->host_caps)
 		host->mmc->caps |= pdata->host_caps;
 
+	if (pdata->host_caps2)
+		host->mmc->caps2 |= pdata->host_caps2;
+
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_err(dev, "sdhci_add_host() failed\n");
@@ -578,6 +751,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 	clk_put(sc->clk_io);
 
  err_io_clk:
+	for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+		gpio_free(sc->gpios[ptr]);
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+		gpio_free(sc->ext_cd_gpio);
+
+ err_pdata:
 	sdhci_free_host(host);
 
 	return ret;
@@ -585,9 +764,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
 
 static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
 {
-	struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
 	struct sdhci_host *host =  platform_get_drvdata(pdev);
 	struct sdhci_s3c *sc = sdhci_priv(host);
+	struct s3c_sdhci_platdata *pdata = sc->pdata;
 	int ptr;
 
 	if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
@@ -614,6 +793,11 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
 	release_resource(sc->ioarea);
 	kfree(sc->ioarea);
 
+	if (pdev->dev.of_node) {
+		for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+			gpio_free(sc->gpios[ptr]);
+	}
+
 	sdhci_free_host(host);
 	platform_set_drvdata(pdev, NULL);
 
@@ -647,12 +831,45 @@ static const struct dev_pm_ops sdhci_s3c_pmops = {
 #define SDHCI_S3C_PMOPS NULL
 #endif
 
+#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212)
+static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = {
+	.sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK,
+};
+#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data)
+#else
+#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL)
+#endif
+
+static struct platform_device_id sdhci_s3c_driver_ids[] = {
+	{
+		.name		= "s3c-sdhci",
+		.driver_data	= (kernel_ulong_t)NULL,
+	}, {
+		.name		= "exynos4-sdhci",
+		.driver_data	= EXYNOS4_SDHCI_DRV_DATA,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
+
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_s3c_dt_match[] = {
+	{ .compatible = "samsung,s3c6410-sdhci", },
+	{ .compatible = "samsung,exynos4210-sdhci",
+		.data = &exynos4_sdhci_drv_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+#endif
+
 static struct platform_driver sdhci_s3c_driver = {
 	.probe		= sdhci_s3c_probe,
 	.remove		= __devexit_p(sdhci_s3c_remove),
+	.id_table	= sdhci_s3c_driver_ids,
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "s3c-sdhci",
+		.of_match_table = of_match_ptr(sdhci_s3c_dt_match),
 		.pm	= SDHCI_S3C_PMOPS,
 	},
 };
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 78a36eb..ccbca0b 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/mmc/card.h>
@@ -32,6 +33,19 @@
 
 #include "sdhci-pltfm.h"
 
+#define NVQUIRK_FORCE_SDHCI_SPEC_200	BIT(0)
+#define NVQUIRK_ENABLE_BLOCK_GAP_DET	BIT(1)
+
+struct sdhci_tegra_soc_data {
+	struct sdhci_pltfm_data *pdata;
+	u32 nvquirks;
+};
+
+struct sdhci_tegra {
+	const struct tegra_sdhci_platform_data *plat;
+	const struct sdhci_tegra_soc_data *soc_data;
+};
+
 static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
 {
 	u32 val;
@@ -47,7 +61,12 @@ static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
 
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
 {
-	if (unlikely(reg == SDHCI_HOST_VERSION)) {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
+	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
+
+	if (unlikely((soc_data->nvquirks & NVQUIRK_FORCE_SDHCI_SPEC_200) &&
+			(reg == SDHCI_HOST_VERSION))) {
 		/* Erratum: Version register is invalid in HW. */
 		return SDHCI_SPEC_200;
 	}
@@ -57,6 +76,10 @@ static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
 
 static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
+	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
+
 	/* Seems like we're getting spurious timeout and crc errors, so
 	 * disable signalling of them. In case of real errors software
 	 * timers should take care of eventually detecting them.
@@ -66,7 +89,8 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
 
 	writel(val, host->ioaddr + reg);
 
-	if (unlikely(reg == SDHCI_INT_ENABLE)) {
+	if (unlikely((soc_data->nvquirks & NVQUIRK_ENABLE_BLOCK_GAP_DET) &&
+			(reg == SDHCI_INT_ENABLE))) {
 		/* Erratum: Must enable block gap interrupt detection */
 		u8 gap_ctrl = readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL);
 		if (val & SDHCI_INT_CARD_INT)
@@ -77,10 +101,11 @@ static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
 	}
 }
 
-static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci)
+static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
 {
-	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
-	struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
+	const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
 
 	if (!gpio_is_valid(plat->wp_gpio))
 		return -1;
@@ -99,7 +124,8 @@ static irqreturn_t carddetect_irq(int irq, void *data)
 static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
+	const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
 	u32 ctrl;
 
 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
@@ -125,16 +151,44 @@ static struct sdhci_ops tegra_sdhci_ops = {
 	.platform_8bit_width = tegra_sdhci_8bit,
 };
 
-static struct sdhci_pltfm_data sdhci_tegra_pdata = {
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+static struct sdhci_pltfm_data sdhci_tegra20_pdata = {
+	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+		  SDHCI_QUIRK_SINGLE_POWER_WRITE |
+		  SDHCI_QUIRK_NO_HISPD_BIT |
+		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+	.ops  = &tegra_sdhci_ops,
+};
+
+static struct sdhci_tegra_soc_data soc_data_tegra20 = {
+	.pdata = &sdhci_tegra20_pdata,
+	.nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 |
+		    NVQUIRK_ENABLE_BLOCK_GAP_DET,
+};
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+static struct sdhci_pltfm_data sdhci_tegra30_pdata = {
 	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 		  SDHCI_QUIRK_SINGLE_POWER_WRITE |
 		  SDHCI_QUIRK_NO_HISPD_BIT |
 		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
 	.ops  = &tegra_sdhci_ops,
 };
 
+static struct sdhci_tegra_soc_data soc_data_tegra30 = {
+	.pdata = &sdhci_tegra30_pdata,
+};
+#endif
+
 static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
-	{ .compatible = "nvidia,tegra20-sdhci", },
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+	{ .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
+#endif
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+	{ .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
+#endif
 	{}
 };
 MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
@@ -165,13 +219,22 @@ static struct tegra_sdhci_platform_data * __devinit sdhci_tegra_dt_parse_pdata(
 
 static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *match;
+	const struct sdhci_tegra_soc_data *soc_data;
+	struct sdhci_host *host;
 	struct sdhci_pltfm_host *pltfm_host;
 	struct tegra_sdhci_platform_data *plat;
-	struct sdhci_host *host;
+	struct sdhci_tegra *tegra_host;
 	struct clk *clk;
 	int rc;
 
-	host = sdhci_pltfm_init(pdev, &sdhci_tegra_pdata);
+	match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
+	if (match)
+		soc_data = match->data;
+	else
+		soc_data = &soc_data_tegra20;
+
+	host = sdhci_pltfm_init(pdev, soc_data->pdata);
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
@@ -188,7 +251,17 @@ static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
 		goto err_no_plat;
 	}
 
-	pltfm_host->priv = plat;
+	tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL);
+	if (!tegra_host) {
+		dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n");
+		rc = -ENOMEM;
+		goto err_no_plat;
+	}
+
+	tegra_host->plat = plat;
+	tegra_host->soc_data = soc_data;
+
+	pltfm_host->priv = tegra_host;
 
 	if (gpio_is_valid(plat->power_gpio)) {
 		rc = gpio_request(plat->power_gpio, "sdhci_power");
@@ -284,7 +357,8 @@ static int __devexit sdhci_tegra_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-	struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
+	const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
 	int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
 
 	sdhci_remove_host(host, dead);
@@ -327,5 +401,5 @@ static struct platform_driver sdhci_tegra_driver = {
 module_platform_driver(sdhci_tegra_driver);
 
 MODULE_DESCRIPTION("SDHCI driver for Tegra");
-MODULE_AUTHOR(" Google, Inc.");
+MODULE_AUTHOR("Google, Inc.");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 8d66706..1f5888b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2379,6 +2379,9 @@ int sdhci_suspend_host(struct sdhci_host *host)
 	int ret;
 	bool has_tuning_timer;
 
+	if (host->ops->platform_suspend)
+		host->ops->platform_suspend(host);
+
 	sdhci_disable_card_detection(host);
 
 	/* Disable tuning since we are suspending */
@@ -2429,6 +2432,9 @@ int sdhci_resume_host(struct sdhci_host *host)
 	ret = mmc_resume_host(host->mmc);
 	sdhci_enable_card_detection(host);
 
+	if (host->ops->platform_resume)
+		host->ops->platform_resume(host);
+
 	/* Set the re-tuning expiration flag */
 	if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
 	    (host->tuning_mode == SDHCI_TUNING_MODE_1))
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index ad265b9..f761f23 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -275,6 +275,8 @@ struct sdhci_ops {
 	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
 	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
 	void	(*hw_reset)(struct sdhci_host *host);
+	void	(*platform_suspend)(struct sdhci_host *host);
+	void	(*platform_resume)(struct sdhci_host *host);
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff --git a/drivers/modem_shm/Kconfig b/drivers/modem_shm/Kconfig
new file mode 100644
index 0000000..7e18801
--- /dev/null
+++ b/drivers/modem_shm/Kconfig
@@ -0,0 +1,62 @@
+#
+# MODEM_SHM Framework
+#
+
+config MODEM_SHM
+	tristate
+	default n
+	depends on EXPERIMENTAL
+
+if MODEM_SHM && NET
+
+menu "Modem Shared Memory"
+
+config DUMMY_C2C
+	tristate "Dummy C2C GENIO driver"
+	depends on !C2C
+	default MODEM_SHM
+	---help---
+	Say "Y" or "M" if you want to compile a dummy C2C driver.
+	Use this if you want to compile without the real
+	C2C driver available.
+	If unsure say N.
+
+config MODEM_SHM_BUS
+	tristate
+	default MODEM_SHM_DEV
+
+config MODEM_SHM_BOOT
+	tristate
+	depends on MODEM_SHM_DEV
+	default MODEM_SHM_DEV
+
+config MODEM_SHM_DEV
+	tristate "SHM Channels for Modem Shared Memory"
+	depends on DUMMY_C2C || C2C
+	select MODEM_SHM_BUS
+	select MODEM_SHM_BOOT
+	default MODEM_SHM
+	---help---
+	Say "Y" to use Modem Shared Memory IPC mechanism.
+	SHM is an IPC protocol used to talk to external device such
+	as modem over a shared memory (e.g. Chip to Chip).
+	Only say "M" here if you want to test MODEM_SHM and need to load
+	and unload its module.
+	If unsure say N.
+
+config MODEM_SHM_CHR
+	tristate "Character device for Modem Shared Memory"
+	depends on MODEM_SHM_DEV
+	default MODEM_SHM_DEV
+	---help---
+	Say "Y" to use a character device for the Modem Shared
+	Memory IPC mechanism. MODEM_SHM is an IPC protocol used to
+	talk to external device such as modem over a shared memory
+	(e.g. Chip to Chip).
+	Only say "M" here if you want to test MODEM_SHM and need to load
+	and unload its module.
+	If unsure say N.
+
+endmenu
+
+endif
diff --git a/drivers/modem_shm/Makefile b/drivers/modem_shm/Makefile
new file mode 100644
index 0000000..3bd2274
--- /dev/null
+++ b/drivers/modem_shm/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_MODEM_SHM_BUS) += shm_bus.o
+obj-$(CONFIG_MODEM_SHM_BOOT) += shm_boot.o
+obj-$(CONFIG_MODEM_SHM_DEV) += shm_dev.o
+obj-$(CONFIG_MODEM_SHM_CHR) +=  shm_chr.o
+obj-$(CONFIG_DUMMY_C2C) +=  dummy_c2c_genio.o
diff --git a/drivers/modem_shm/dummy_c2c_genio.c b/drivers/modem_shm/dummy_c2c_genio.c
new file mode 100644
index 0000000..18fbb6f
--- /dev/null
+++ b/drivers/modem_shm/dummy_c2c_genio.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author:	Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+/* This is a dummy implementation of GENIO */
+
+#include <linux/module.h>
+#include <linux/c2c_genio.h>
+
+int genio_subscribe(int bit, void (*bit_set_cb)(void *data), void *data)
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_subscribe);
+
+int genio_unsubscribe(int bit)
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_unsubscribe);
+
+int genio_set_bit(int bit)
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_set_bit);
+
+int genio_reset(void)
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_reset);
+
+int genio_subscribe_caif_ready(void (*caif_ready_cb) (bool ready))
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_subscribe_caif_ready);
+
+int genio_set_shm_addr(u32 addr, void (*ipc_ready_cb) (void))
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_set_shm_addr);
+
+int genio_bit_alloc(u32 setter_mask, u32 getter_mask)
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_bit_alloc);
+
+void genio_register_errhandler(void (*errhandler)(int errno))
+{
+}
+EXPORT_SYMBOL(genio_register_errhandler);
+
+int genio_power_req(int state)
+{
+	return 0;
+}
+EXPORT_SYMBOL(genio_power_req);
+
+static int __init genio_init(void)
+{
+	return 0;
+}
+
+static void __exit genio_exit(void)
+{
+}
+module_init(genio_init);
+module_exit(genio_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/modem_shm/shm_boot.c b/drivers/modem_shm/shm_boot.c
new file mode 100644
index 0000000..87ff053
--- /dev/null
+++ b/drivers/modem_shm/shm_boot.c
@@ -0,0 +1,1208 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author:	Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/crc-ccitt.h>
+#include <linux/kdev_t.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include "shm_ipctoc.h"
+#include <linux/modem_shm/shm_dev.h>
+#include <linux/modem_shm/modem_shm_netlink.h>
+#include <linux/c2c_genio.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brændland <sjur.brandeland@stericsson.com>");
+
+#define SHM_VERSION	0x1
+#define SHM_SUBVER	0x0
+#define TOC_SZ		512
+#define IMG_MAX_SZ	65536
+#define SHM_ALIGNMT	sizeof(u32)
+#define SHM_MIN_CHSZ 3
+#define SHM_PAYL_ALIGN max(32, L1_CACHE_BYTES)
+#define STE_BOOTIMG_NAME "ste-bootimg.bin"
+
+#define GET_OFFSET(base, ptr) (((u8 *)(ptr)) - ((u8 *)(base)))
+#define OFFS2PTR(base, offs) ((void *) ((u8 *)base + offs))
+#define LEOFFS2PTR(base, offs) ((void *) ((u8 *)base + le32_to_cpu(offs)))
+
+/* Structure use in debug mode for integrity checking */
+struct ipctoc_hash {
+	u16 img_hash;
+	u16 ch_hash;
+	u16 ch_size;
+};
+struct shm_modem {
+	bool config_error;
+	bool commited;
+	bool registered;
+	bool addr_set;
+	bool fw_requested;
+	u32 modem_bootimg_size;
+	void *shm_start;
+	u32 channels;
+	struct shm_channel *channel[SHM_MAX_CHANNELS + 1];
+	struct shm_ipctoc *ipctoc;
+	bool gennetl_reg;
+};
+
+static unsigned long shm_start;
+module_param(shm_start, ulong, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(shm_start, "Address for memory shared by host/modem.");
+
+static unsigned long shm_c2c_bootaddr;
+module_param(shm_c2c_bootaddr, ulong, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(shm_c2c_bootaddr,
+			"Address given to modem (through GENI register)");
+
+static long shm_size;
+module_param(shm_size, long, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(shm_size, "Size of SHM area");
+
+#ifdef DEBUG
+
+/* In debug mode we pad around all payload area in order to detect overwrite */
+#define MAGIC_PAD_LEN 32
+#define MAGIC_PAD 0xbc
+
+/* Verify a magic-pad area */
+static inline bool padok(void *mag)
+{
+	u32 *p = mag, v = 0xbcbcbcbc;
+	int i;
+
+	for (i = 0; i < 8; i++)
+		if (*p++ != v)
+			return false;
+	return true;
+}
+
+/* Insert a magic-pad area */
+static inline void add_magic_pad(u32 *offset, void *base)
+{
+	if (*offset < shm_size)
+		memset(base + *offset, MAGIC_PAD, MAGIC_PAD_LEN);
+	*offset += MAGIC_PAD_LEN;
+}
+
+/* Abuse the pad area to create a checksum of the ipc-toc and descriptors */
+static inline void store_checksum(struct shm_modem *modem, u32 size)
+{
+	struct ipctoc_hash *hash = (void *)modem->ipctoc;
+	--hash;
+	hash->img_hash =
+		crc_ccitt(0xffff, (u8 *) modem->shm_start,
+				modem->modem_bootimg_size);
+	hash->ch_hash = crc_ccitt(0xffff, (u8 *) modem->ipctoc, size);
+	hash->ch_size = size;
+}
+
+/* Verify that shm config has not been accidently tampered. */
+static inline bool ok_checksum(struct shm_modem *modem,
+				struct shm_ipctoc *ipctoc)
+{
+	struct ipctoc_hash *hash = (void *) ipctoc;
+	u16 new_hash, new_imghash;
+	int i;
+	u8 *p;
+
+	if (!modem->commited)
+		return false;
+
+	for (i = 0; i < modem->channels; i++) {
+		struct shm_ipctoc_channel *ch;
+
+		ch = LEOFFS2PTR(modem->shm_start,
+				ipctoc->channel_offsets[i].rx);
+		p = LEOFFS2PTR(modem->shm_start, ch->ipc);
+		if (!padok(p - MAGIC_PAD_LEN))
+			return false;
+		p = LEOFFS2PTR(modem->shm_start, ch->offset);
+		if (!padok(p - MAGIC_PAD_LEN))
+			return false;
+		ch = LEOFFS2PTR(modem->shm_start,
+				ipctoc->channel_offsets[i].tx);
+		p = LEOFFS2PTR(modem->shm_start, ch->ipc);
+		if (!padok(p - MAGIC_PAD_LEN))
+			return false;
+		p = LEOFFS2PTR(modem->shm_start, ch->offset);
+		if (!padok(p - MAGIC_PAD_LEN))
+			return false;
+	}
+
+	--hash;
+	new_hash = crc_ccitt(0xffff, (u8 *) ipctoc, hash->ch_size);
+	new_imghash =
+		crc_ccitt(0xffff, (u8 *) modem->shm_start,
+				modem->modem_bootimg_size);
+	pr_debug("Hash result:size:%d chksm:%u/%u img:%u/%u\n",
+			hash->ch_size, hash->ch_hash, new_hash,
+			hash->img_hash, new_imghash);
+	return hash->ch_hash == new_hash && hash->img_hash == new_imghash;
+}
+
+static inline void init_data(void *shm_start, u32 offset,
+				int ch, u32 size)
+{
+	memset((u8 *)shm_start + offset, ch + 1, size);
+}
+#else
+#define MAGIC_PAD_LEN 0
+static inline void add_magic_pad(u32 *offset, void *base)
+{
+}
+static inline void store_checksum(struct shm_modem *modem, u32 size)
+{
+}
+static inline bool ok_checksum(struct shm_modem *modem, void *ipctoc)
+{
+	return true;
+}
+static inline void init_data(struct shm_modem *modem, u32 offs, int ch,
+				u32 size)
+{
+}
+#endif
+
+/* write_to_shm - Write SHM Channel descriptors to SHM.
+ *
+ * Based on the configuration data channel configuration
+ * is written to the shared memory area.
+ * This is the data layout:
+ *
+ * +------------+  <---- shm_start
+ * |	TOC	|
+ * +------------+
+ * | Boot IMG	|
+ * +------------+ <---- rw_start
+ * | RW Data	|
+ * +------------+
+ * | RW Buf idx |
+ * +------------+ <---- ipctoc
+ * | IPC TOC	|
+ * +------------+
+ * | RW Ch Decr |
+ * +------------+ <---- ro_start
+ * | RO Ch Decr |
+ * +------------+
+ * | RO Buf idx |
+ * +------------+
+ * | RO Data	|
+ * +------------+
+ */
+
+static int write_to_shm(struct shm_modem *modem)
+{
+	int i, pri, bitno;
+	u32 offset, ro_start, rw_start, ipctoc_offs, ipcro_offs;
+	bool found;
+	struct shm_ipctoc_channel *ch;
+	struct toc_entry *toc_entry;
+	struct shm_bufidx *bix;
+
+	/*
+	 * Find where to put IPC-TOC by adding up
+	 * the size of Payload buffers pluss buf-indices
+	 */
+	ipctoc_offs = ALIGN(modem->modem_bootimg_size, SHM_PAYL_ALIGN);
+	rw_start = ipctoc_offs;
+	for (i = 0; i < modem->channels; i++) {
+		int n = modem->channel[i]->tx.buffers;
+		ipctoc_offs += MAGIC_PAD_LEN;
+		ipctoc_offs += offsetof(struct shm_bufidx, size[n + 2]);
+		ipctoc_offs = ALIGN(ipctoc_offs, SHM_PAYL_ALIGN);
+		ipctoc_offs += MAGIC_PAD_LEN;
+		ipctoc_offs += modem->channel[i]->tx.ch_size;
+		ipctoc_offs = ALIGN(ipctoc_offs, SHM_PAYL_ALIGN);
+	}
+	add_magic_pad(&ipctoc_offs, modem->shm_start);
+	pr_debug("IPC toc @ %08x\n", ipctoc_offs);
+
+	/*
+	 * Allocate the IPC-TOC and, initiatlize it.
+	 * The IPC toc will be located after the RW Data and
+	 * buffer indices.
+	 */
+	offset = ipctoc_offs;
+	modem->ipctoc = OFFS2PTR(modem->shm_start, ipctoc_offs);
+	modem->ipctoc->magic[0] = SHM_IPCTOC_MAGIC1;
+	modem->ipctoc->magic[1] = SHM_IPCTOC_MAGIC2;
+	modem->ipctoc->version = SHM_VERSION;
+	modem->ipctoc->subver = SHM_SUBVER;
+	memset(modem->ipctoc->channel_offsets, 0,
+		sizeof(modem->ipctoc->channel_offsets));
+
+	/* Find start of first channel descriptor */
+	offset += sizeof(struct shm_ipctoc);
+
+	/*
+	 * Allocate the location for the RW Channel descriptors.
+	 * It will be located after the IPC-TOC.
+	 */
+	offset = ALIGN(offset, SHM_ALIGNMT);
+	for (i = 0; i < modem->channels; i++) {
+		pr_debug("Channel descriptor %d RW @ 0x%08x\n", i, offset);
+		modem->ipctoc->channel_offsets[i].tx = cpu_to_le32(offset);
+		offset += sizeof(struct shm_ipctoc_channel);
+		offset = ALIGN(offset, SHM_ALIGNMT);
+		if (offset > shm_size)
+			goto badsize;
+	}
+	ro_start = offset;
+
+	/*
+	 * Allocate the location for the RO Channel descriptors.
+	 * It will be located after the RW Channels.
+	 */
+	for (i = 0; i < modem->channels; i++) {
+		pr_debug("Channel descriptor %d RO @ 0x%08x\n", i, offset);
+		modem->ipctoc->channel_offsets[i].rx = cpu_to_le32(offset);
+		offset += sizeof(struct shm_ipctoc_channel);
+		offset = ALIGN(offset, SHM_ALIGNMT);
+		if (offset > shm_size)
+			goto badsize;
+	}
+
+	/*
+	 * Allocate the location for the RO Buffer Indices.
+	 * It will be located after the RO Channels.
+	 */
+	offset = ALIGN(offset, SHM_PAYL_ALIGN);
+	ipcro_offs = offset;
+	for (i = 0; i < modem->channels; i++) {
+		int n = modem->channel[i]->rx.buffers;
+		ch = LEOFFS2PTR(modem->shm_start,
+				modem->ipctoc->channel_offsets[i].rx);
+		add_magic_pad(&offset, modem->shm_start);
+		ch->ipc = cpu_to_le32(offset);
+
+		bix = OFFS2PTR(modem->shm_start, offset);
+		bix->read_index = cpu_to_le32(0);
+		bix->write_index = cpu_to_le32(0);
+		bix->state = cpu_to_le32(SHM_CLOSED);
+		bix->size[0] = cpu_to_le32(0);
+
+		pr_debug("IPC RO[%d] @: 0x%08x\n",  i, offset);
+		offset += offsetof(struct shm_bufidx, size[n + 2]);
+		offset = ALIGN(offset, SHM_PAYL_ALIGN);
+		if (offset > shm_size)
+			goto badsize;
+	}
+
+	/*
+	 * Allocate RO Data Area. This will located after
+	 * the RO Buffer Indices at the end of the Share Memory
+	 * area.
+	 */
+	offset = ALIGN(offset, SHM_PAYL_ALIGN);
+	for (i = 0; i < modem->channels; i++) {
+		u8 align;
+		u32 size;
+		ch = LEOFFS2PTR(modem->shm_start,
+				modem->ipctoc->channel_offsets[i].rx);
+		add_magic_pad(&offset, modem->shm_start);
+		ch->offset = cpu_to_le32(offset);
+
+		BUILD_BUG_ON(sizeof(ch->mode) != 1);
+		ch->mode = modem->channel[i]->mode & SHM_MODE_MASK;
+		ch->buffers = cpu_to_le32(modem->channel[i]->rx.buffers);
+		align = rounddown_pow_of_two(modem->channel[i]->rx.alignment);
+		ch->alignment = align;
+		ch->packets = modem->channel[i]->rx.packets;
+		ch->mtu = modem->channel[i]->rx.mtu;
+		size = modem->channel[i]->tx.ch_size;
+		if (modem->channel[i]->mode & SHM_PACKET_MODE) {
+			u32 buf_size;
+			buf_size = size / modem->channel[i]->tx.buffers;
+			buf_size = rounddown(buf_size, align);
+			size = buf_size * modem->channel[i]->tx.buffers;
+		}
+		pr_debug("Buffer area RO for Channel[%d] at: 0x%08x size:%d\n",
+				i, offset, size);
+		ch->size = cpu_to_le32(size);
+
+		init_data(modem->shm_start, offset, i,
+				modem->channel[i]->rx.ch_size);
+		offset += modem->channel[i]->rx.ch_size;
+		offset = ALIGN(offset, SHM_PAYL_ALIGN);
+		if (offset > shm_size)
+			goto badsize;
+	}
+
+	/*
+	 * Allocate RW Data Area. This will located in the beginning
+	 * just after the Modem Boot Image.
+	 */
+	offset = rw_start;
+	for (i = 0; i < modem->channels; i++) {
+		u8 align;
+		u32 size;
+		ch = LEOFFS2PTR(modem->shm_start,
+				modem->ipctoc->channel_offsets[i].tx);
+		add_magic_pad(&offset, modem->shm_start);
+		ch->offset = cpu_to_le32(offset);
+		init_data(modem->shm_start, offset, i,
+				modem->channel[i]->tx.ch_size);
+		ch->mode = modem->channel[i]->mode &
+				SHM_MODE_MASK;
+		ch->buffers = cpu_to_le32(modem->channel[i]->tx.buffers);
+		align = rounddown_pow_of_two(modem->channel[i]->rx.alignment);
+		ch->alignment = align;
+		ch->packets = modem->channel[i]->rx.packets;
+		ch->mtu = modem->channel[i]->rx.mtu;
+		size = modem->channel[i]->tx.ch_size;
+		if (modem->channel[i]->mode & SHM_PACKET_MODE) {
+			u32 buf_size;
+			buf_size = size / modem->channel[i]->tx.buffers;
+			buf_size = rounddown(buf_size, align);
+			size = buf_size * modem->channel[i]->tx.buffers;
+		}
+		ch->size = cpu_to_le32(size);
+		pr_debug("Buffer area RW for Channel[%d] at: 0x%08x size:%d\n",
+				i, offset, size);
+		offset += modem->channel[i]->tx.ch_size;
+		offset = ALIGN(offset, SHM_PAYL_ALIGN);
+		if (offset > ro_start)
+			goto badsize;
+	}
+
+	/*
+	 * Allocate RW IPC Area. This will located after RW data area,
+	 * just before the IPC-TOC.
+	 */
+	offset = ALIGN(offset, SHM_PAYL_ALIGN);
+	for (i = 0; i < modem->channels; i++) {
+		int n = modem->channel[i]->tx.buffers;
+		ch = LEOFFS2PTR(modem->shm_start,
+				modem->ipctoc->channel_offsets[i].tx);
+		add_magic_pad(&offset, modem->shm_start);
+		ch->ipc = cpu_to_le32(offset);
+		bix = OFFS2PTR(modem->shm_start, offset);
+		bix->read_index = cpu_to_le32(0);
+		bix->write_index = cpu_to_le32(0);
+		bix->state = cpu_to_le32(SHM_CLOSED);
+		bix->size[0] = cpu_to_le32(0);
+
+		pr_debug("IPC RW[%d] @: 0x%08x\n",  i, offset);
+		offset += offsetof(struct shm_bufidx, size[n + 2]);
+		offset = ALIGN(offset, SHM_PAYL_ALIGN);
+		if (offset > shm_size)
+			goto badsize;
+	}
+
+	/* Allocate genio bits for each channel according to priority*/
+	bitno = 0;
+	for (pri = 0; pri < 8; pri++) {
+		for (i = 0; i < modem->channels; i++) {
+			if (modem->channel[i]->priority == pri) {
+				ch = LEOFFS2PTR(modem->shm_start,
+					modem->ipctoc->channel_offsets[i].tx);
+				ch->write_bit = cpu_to_le16(bitno * 4);
+				ch->read_bit = cpu_to_le16(bitno * 4 + 2);
+				ch = LEOFFS2PTR(modem->shm_start,
+					modem->ipctoc->channel_offsets[i].rx);
+				ch->write_bit = cpu_to_le16(bitno * 4 + 1);
+				ch->read_bit = cpu_to_le16(bitno * 4 + 3);
+				bitno++;
+			}
+		}
+	}
+
+	/*
+	 * The Master TOC points out the boot images for the modem,
+	 * Use the first avilable entry in the toc to write the pointer,
+	 * to the IPC-TOC defined above.
+	 */
+	found = false;
+	for (toc_entry = modem->shm_start, i = 0; i < 16; i++, toc_entry++)
+		if (toc_entry->start == cpu_to_le32(0xffffffff)) {
+			pr_debug("IPCTOC address written into Master TOC"
+					" @ 0x%08x\n", i * 32);
+			toc_entry->start =
+				cpu_to_le32(GET_OFFSET(modem->shm_start,
+							modem->ipctoc));
+			toc_entry->size = cpu_to_le32(0);
+			toc_entry->flags = cpu_to_le32(0);
+			toc_entry->entry_point = cpu_to_le32(0);
+			toc_entry->load_addr = cpu_to_le32(0xffffffff);
+			memset(toc_entry->name, 0, sizeof(toc_entry->name));
+			sprintf(toc_entry->name, "ipc-toc");
+			found = true;
+			break;
+		}
+	if (!found) {
+		pr_debug("Cannot insert IPC-TOC in toc\n");
+		goto bad_config;
+	}
+
+	store_checksum(modem, ipcro_offs - ipctoc_offs);
+
+	return 0;
+
+badsize:
+	pr_debug("IPCTOC not enough space offset (size:0x%lx offset:0x%x\n",
+			shm_size, offset);
+	return -ENOSPC;
+
+bad_config:
+	pr_debug("IPCTOC bad configuration data\n");
+	return -EINVAL;
+}
+
+static int shm_verify_config(struct shm_modem *modem,
+				struct shm_channel *xcfg)
+{
+	int j;
+	u32 size;
+
+	if (modem->channels <= 0 || modem->channels > SHM_MAX_CHANNELS) {
+		pr_debug("Bad config: channel mode must be set\n");
+		return -EINVAL;
+	}
+
+	if ((xcfg->mode & SHM_MODE_MASK) != SHM_PACKET_MODE &&
+			(xcfg->mode & SHM_MODE_MASK) != SHM_STREAM_MODE) {
+		pr_debug("Bad config: channel mode must be set\n");
+		return -EINVAL;
+	}
+	if (xcfg->mode & SHM_PACKET_MODE && xcfg->rx.buffers < 2) {
+		pr_debug("Bad config:minimum 2 buffers "
+				"must be set for packet mode\n");
+		return -EINVAL;
+	}
+
+	if (xcfg->rx.ch_size < SHM_MIN_CHSZ) {
+		pr_debug("Bad config:"
+				"Channel size must be larger than %d\n",
+				SHM_MIN_CHSZ);
+		return -EINVAL;
+	}
+
+	if (xcfg->mode & SHM_PACKET_MODE) {
+		if (xcfg->tx.buffers < 2) {
+			pr_debug("Bad config:"
+				"buffers must be minimum 2 packet mode\n");
+			return -EINVAL;
+		}
+		if (xcfg->tx.packets < 1) {
+			pr_debug("Bad config:"
+				"packets must be set for packet mode\n");
+			return -EINVAL;
+		}
+	}
+
+	if (xcfg->tx.ch_size < SHM_MIN_CHSZ) {
+		pr_debug("Bad config:"
+				"Channel size must be larger than %d\n",
+				SHM_MIN_CHSZ);
+		return -EINVAL;
+	}
+
+	if (xcfg->name[0] == '\0') {
+		pr_debug("Channel must be named\n");
+		return -EINVAL;
+	}
+
+	size = modem->modem_bootimg_size;
+
+	for (j = 0; j < modem->channels; j++) {
+		struct shm_channel *xcfg2 = modem->channel[j];
+		size = xcfg2->tx.ch_size + xcfg2->rx.ch_size;
+		if (xcfg != xcfg2 && strcmp(xcfg->name, xcfg2->name) == 0) {
+			pr_debug("Channels has same name:%s\n",
+					 xcfg->name);
+			return -EINVAL;
+		}
+	}
+
+	if (size > shm_size) {
+		pr_debug("Channel size too big\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int verify_config(struct shm_modem *modem)
+{
+	int i;
+
+	if (modem->channels == 0) {
+		pr_debug("Bad config: minimum one channel must be defined\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < modem->channels; i++) {
+		int err = shm_verify_config(modem, modem->channel[i]);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
+/*
+ * Create Configuration data for the shm devices.
+ */
+static void create_devs(struct shm_modem *modem)
+{
+	int i;
+
+	for (i = 0; i < modem->channels; i++) {
+		struct shm_bufidx *buf_rx, *buf_tx;
+		struct shm_ipctoc_channel *ch_rx, *ch_tx;
+		struct shm_channel *xcfg = modem->channel[i];
+		ch_rx = LEOFFS2PTR(modem->shm_start,
+				modem->ipctoc->channel_offsets[i].rx);
+		buf_rx = LEOFFS2PTR(modem->shm_start, ch_rx->ipc);
+		ch_tx = LEOFFS2PTR(modem->shm_start,
+				modem->ipctoc->channel_offsets[i].tx);
+		buf_tx = LEOFFS2PTR(modem->shm_start, ch_tx->ipc);
+
+		/*
+		 * Due to restricted read-only access
+		 * we swap positions for read/write
+		 * pointers.
+		 */
+		xcfg->tx.write = &buf_tx->write_index;
+		xcfg->tx.read = &buf_rx->read_index;
+
+		xcfg->rx.write = &buf_rx->write_index;
+		xcfg->rx.read = &buf_tx->read_index;
+
+		xcfg->rx.addr = LEOFFS2PTR(modem->shm_start, ch_rx->offset);
+		xcfg->tx.addr = LEOFFS2PTR(modem->shm_start, ch_tx->offset);
+		xcfg->rx.state = &buf_rx->state;
+		xcfg->tx.state = &buf_tx->state;
+		xcfg->tx.buf_size = buf_tx->size;
+		xcfg->rx.buf_size = buf_rx->size;
+
+		xcfg->rx.xfer_bit = le16_to_cpu(ch_rx->write_bit);
+		xcfg->tx.xfer_bit = le16_to_cpu(ch_tx->write_bit);
+		xcfg->rx.xfer_done_bit = le16_to_cpu(ch_rx->read_bit);
+		xcfg->tx.xfer_done_bit = le16_to_cpu(ch_tx->read_bit);
+
+		if (xcfg->mode & SHM_PAIR_MODE) {
+			struct shm_channel *pair;
+			pr_debug("Channel[%d] is in PAIR mode\n", i);
+			if (i < 1) {
+				pr_debug("No channel to pair with\n");
+				continue;
+			}
+			/* Cross couple rx/tx on the pair */
+			pair = modem->channel[i - 1];
+
+			/* Copy everything but the kobj which is at the end */
+			memcpy(&xcfg->tx, &pair->rx,
+					offsetof(struct shm_udchannel, kobj));
+			memcpy(&xcfg->rx, &pair->tx,
+					offsetof(struct shm_udchannel, kobj));
+		} else if (xcfg->mode & SHM_LOOP_MODE) {
+			pr_debug("Channel[%d] is in LOOP mode\n", i);
+			/*
+			 * Connect rx/tx in a pair. Copy everything,
+			 * but the kobj which is at the end
+			 */
+			memcpy(&xcfg->tx, &xcfg->rx,
+					offsetof(struct shm_udchannel, kobj));
+		}
+
+		pr_devel("RX[%d] wi:%p ri:%p\n", i, xcfg->rx.read,
+				xcfg->rx.write);
+		pr_devel("TX[%d] wi:%p ri:%p\n", i, xcfg->tx.read,
+				xcfg->tx.write);
+	}
+}
+
+struct shm_modem *modem;
+
+struct shm_modem *get_modem(struct sk_buff *skb, struct genl_info *info)
+{
+	return modem;
+}
+
+static int do_commit(struct shm_modem *modem)
+{
+	int err;
+
+	if (modem->config_error) {
+		pr_devel("config error detected\n");
+		return -EINVAL;
+	}
+
+	if (modem->commited) {
+		pr_devel("already commited\n");
+		modem->config_error = true;
+		return -EINVAL;
+	}
+	err = verify_config(modem);
+	if (err) {
+		pr_devel("bad config\n");
+		modem->config_error = true;
+		return err;
+	}
+	err = write_to_shm(modem);
+	if (err) {
+		pr_devel("writei to SHM failed\n");
+		modem->config_error = true;
+		return err;
+	}
+	modem->commited = true;
+	create_devs(modem);
+	return 0;
+}
+
+static int do_register(struct shm_modem *modem)
+{
+	int err;
+
+	if (!modem->commited || modem->registered || modem->config_error) {
+		pr_devel("bad sequence of requests\n");
+		modem->config_error = true;
+		return -EINVAL;
+	}
+
+	err = verify_config(modem);
+	if (err) {
+		modem->config_error = true;
+		pr_devel("bad config\n");
+		return err;
+	}
+	modem->registered = true;
+
+	modem_shm_register_devices(modem->channel, modem->channels);
+
+	return 0;
+}
+
+static void shm_firmware(const struct firmware *fw, void *context)
+{
+	struct shm_modem *modem = context;
+	struct toc_entry *toc_entry;
+	int i;
+
+	modem->fw_requested = false;
+
+	pr_debug("recevied firmware\n");
+	if (fw == NULL) {
+		pr_warn("No boot-img provided\n");
+		goto out;
+	}
+
+	if (modem->commited) {
+		pr_warn("Received firmware too late in modem boot\n");
+		goto out;
+	}
+
+	toc_entry = (void *)fw->data;
+	if (fw->size < TOC_SZ) {
+		pr_debug("Modem image too short\n");
+		goto bad_img;
+	}
+
+	for (i = 0; i < 16; i++, toc_entry++)
+		if (toc_entry->start == cpu_to_le32(0xffffffff))
+			break;
+
+	if (i == 0) {
+		pr_debug("Empty TOC in firmware image\n");
+		goto bad_img;
+	}
+
+	if (i >= 15) {
+		pr_debug("No free slot for IPC-TOC in received image\n");
+		goto bad_img;
+	}
+
+	modem->modem_bootimg_size = fw->size;
+	memcpy(modem->shm_start, fw->data, fw->size);
+out:
+	release_firmware(fw);
+	return;
+bad_img:
+	pr_warn("Bad modem firmware received\n");
+	modem->config_error = true;
+	release_firmware(fw);
+}
+
+static void do_reset(struct shm_modem *modem)
+{
+	int i;
+
+	modem_shm_reset();
+	modem->config_error = false;
+	modem->registered = false;
+	modem->commited = false;
+	modem->addr_set = false;
+	modem->modem_bootimg_size = TOC_SZ;
+	for (i = 0; i < modem->channels; i++) {
+		kfree(modem->channel[i]);
+		modem->channel[i] = NULL;
+	}
+	modem->channels = 0;
+
+	/* Initiate the Master TOC to 0xff for the first 512 bytes */
+	memset(modem->shm_start, 0xff, TOC_SZ);
+
+	if (!modem->fw_requested)
+		modem_shm_request_firmware(modem, THIS_MODULE,
+				STE_BOOTIMG_NAME, shm_firmware);
+	modem->fw_requested = true;
+}
+
+static int do_set_addr(struct shm_modem *modem)
+{
+	int err;
+	if (!modem->commited || modem->addr_set || modem->config_error) {
+		pr_devel("bad sequence of requests\n");
+		modem->config_error = true;
+		return -EINVAL;
+	}
+	err = verify_config(modem);
+	if (err) {
+		modem->config_error = true;
+		pr_devel("bad config\n");
+		return err;
+	}
+	modem->addr_set = true;
+	return genio_set_shm_addr(shm_c2c_bootaddr, genio_ipc_ready_cb);
+}
+
+static int copy_name(const char *src, char *d, size_t count)
+{
+	const char *s, *end = src + count;
+	for (s = src; *s && s < end; s++, d++)
+		if (*s == '\0' || *s == '\n')
+			break;
+		else if (!isalnum(*s)) {
+			pr_debug("Illegal chr:'%c' in name:'%s'\n", *s, src);
+			return -EINVAL;
+		} else if (s - src >= SHM_NAMESZ - 1) {
+			pr_debug("Name '%s'too long\n", src);
+			return -EINVAL;
+		} else
+			*d = *s;
+	*d = '\0';
+
+	return count;
+}
+
+/* SHM Generic NETLINK family */
+static struct genl_family shm_gnl_family = {
+	.id = GENL_ID_GENERATE,
+	.hdrsize = 0,
+	.name = "modem_shm",
+	.version = SHM_PROTO_VERSION,
+	.maxattr = SHM_A_MAX,
+};
+
+/* SHM Netlink attribute policy */
+static const struct nla_policy shm_genl_policy[SHM_A_MAX + 1] = {
+	[SHM_A_VERSION] = { .type = NLA_U8 },
+	[SHM_A_SUB_VERSION] = { .type = NLA_U8 },
+	[__SHM_A_FLAGS] = { .type = NLA_U32 },
+	[SHM_A_NAME] = { .type = NLA_NUL_STRING, .len = SHM_NAMESZ},
+	[SHM_A_RX_CHANNEL] = { .type = NLA_NESTED },
+	[SHM_A_TX_CHANNEL] = { .type = NLA_NESTED },
+	[SHM_A_PRIORITY] = { .type = NLA_U8 },
+	[SHM_A_LATENCY] = { .type = NLA_U8 },
+};
+
+/* Policy for uni-directional attributes for stream */
+static const struct nla_policy stream_policy[SHM_A_MAX + 1] = {
+	[SHM_A_CHANNEL_SIZE] = { .type = NLA_U32 },
+};
+
+/* Policy for uni-directional attributes for packet */
+static const struct nla_policy packet_policy[SHM_A_MAX + 1] = {
+	[SHM_A_CHANNEL_SIZE] = { .type = NLA_U32 },
+	[SHM_A_CHANNEL_BUFFERS] = { .type = NLA_U32 },
+	[SHM_A_MTU] = { .type = NLA_U16 },
+	[SHM_A_ALIGNMENT] = { .type = NLA_U8 },
+	[SHM_A_PACKETS] = { .type = NLA_U8 },
+};
+
+static int shm_add_udchannel(struct shm_udchannel *chn, int attr,
+			struct genl_info *info, struct nla_policy const *policy)
+{
+	struct nlattr *nla;
+	int nla_rem;
+
+	if (!info->attrs[attr])
+		return -EINVAL;
+
+	if (nla_validate_nested(info->attrs[attr],
+					SHM_A_MAX,
+					policy) != 0) {
+		pr_info("Invalid RX channel attributes\n");
+		return -EINVAL;
+	}
+
+	nla_for_each_nested(nla, info->attrs[attr], nla_rem) {
+
+		if (nla_type(nla) == SHM_A_CHANNEL_SIZE)
+			chn->ch_size = nla_get_u32(nla);
+
+		if (nla_type(nla) == SHM_A_CHANNEL_BUFFERS)
+			chn->buffers = nla_get_u32(nla);
+
+		if (nla_type(nla) == SHM_A_MTU)
+			chn->mtu = nla_get_u16(nla);
+
+		if (nla_type(nla) == SHM_A_PACKETS)
+			chn->packets = nla_get_u8(nla);
+
+		if (nla_type(nla) == SHM_A_ALIGNMENT) {
+			chn->alignment = nla_get_u8(nla);
+			chn->alignment = rounddown_pow_of_two(chn->alignment);
+		}
+
+	}
+	return 0;
+}
+
+static int shm_add_channel(struct shm_channel *cfg, struct genl_info *info,
+			int mode)
+{
+	int len, err;
+	struct nla_policy const *policy;
+	char name[SHM_NAMESZ];
+
+	policy = (mode == SHM_PACKET_MODE) ? packet_policy : stream_policy;
+
+	if (info->attrs[SHM_A_VERSION]) {
+		u8 version;
+		u8 sub_version;
+
+		version = nla_get_u8(info->attrs[SHM_A_VERSION]);
+		if (!info->attrs[SHM_A_SUB_VERSION])
+			return -EINVAL;
+		sub_version = nla_get_u8(info->attrs[SHM_A_SUB_VERSION]);
+		if (version != 1 || sub_version != 0) {
+			pr_info("Bad version or sub_version\n");
+			return -EINVAL;
+		}
+	}
+
+	if (!info->attrs[SHM_A_NAME]) {
+		pr_debug("Name not specified\n");
+		return -EINVAL;
+	}
+
+	len = nla_strlcpy(name, info->attrs[SHM_A_NAME],
+			SHM_NAMESZ);
+
+	if (len > SHM_NAMESZ)
+		return -EINVAL;
+
+	err = copy_name(name, cfg->name, sizeof(name));
+	if (err < 0)
+		return err;
+
+	cfg->excl_group = 1;
+	if (info->attrs[SHM_A_EXCL_GROUP])
+		cfg->excl_group = nla_get_u8(info->attrs[SHM_A_EXCL_GROUP]);
+
+	err = shm_add_udchannel(&cfg->rx, SHM_A_RX_CHANNEL, info, policy);
+	if (err)
+		return err;
+
+	err = shm_add_udchannel(&cfg->tx, SHM_A_TX_CHANNEL, info, policy);
+	if (err)
+		return err;
+
+	if (cfg->tx.ch_size + cfg->rx.ch_size > shm_size) {
+		pr_debug("Channel size too big\n");
+		return -EINVAL;
+	}
+
+	if (info->attrs[SHM_A_PRIORITY]) {
+		cfg->priority = nla_get_u8(info->attrs[SHM_A_PRIORITY]);
+		/* silently fixup bad value */
+		if (cfg->priority > 7)
+			cfg->priority = 0;
+	}
+
+	if (info->attrs[SHM_A_LATENCY])
+		cfg->latency = nla_get_u8(info->attrs[SHM_A_LATENCY]);
+
+	if (info->attrs[__SHM_A_FLAGS])
+		cfg->mode |= nla_get_u32(info->attrs[__SHM_A_FLAGS]);
+
+	return 0;
+}
+
+static int do_reply(struct genl_info *info, int result)
+{
+	struct sk_buff *msg;
+	int err;
+	void *reply;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (msg == NULL)
+		return -ENOMEM;
+
+	reply = genlmsg_put_reply(msg, info, &shm_gnl_family, 0, result);
+	if (reply == NULL) {
+		kfree_skb(msg);
+		return -EMSGSIZE;
+	}
+
+	genlmsg_end(msg, reply);
+	err = genlmsg_reply(msg, info);
+	return err;
+}
+
+static int shm_add_ch(struct sk_buff *skb, struct genl_info *info, int mode)
+{
+	int err;
+	struct shm_channel *cfg;
+	struct shm_modem *modem = get_modem(skb, info);
+	if (!modem)
+		return -EINVAL;
+
+	if (modem->channels + 1 > SHM_MAX_CHANNELS) {
+		pr_debug("Too many channels added\n");
+		return -EINVAL;
+	}
+
+
+	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+	if (cfg == NULL)
+		return -ENOMEM;
+
+	cfg->mode = mode;
+	err = shm_add_channel(cfg, info, mode);
+	if (err)
+		goto error;
+
+	modem->channel[modem->channels] = cfg;
+	++modem->channels;
+
+	err = shm_verify_config(modem, cfg);
+	if (err)
+		goto error_remove;
+
+	err = do_reply(info, 0);
+	if (err)
+		goto error_remove;
+	return err;
+
+error_remove:
+	--modem->channels;
+error:
+	kfree(cfg);
+	return err;
+}
+
+static int shm_add_packet_ch(struct sk_buff *skb, struct genl_info *info)
+{
+	return shm_add_ch(skb, info, SHM_PACKET_MODE);
+}
+
+static int shm_add_stream_ch(struct sk_buff *skb, struct genl_info *info)
+{
+	return shm_add_ch(skb, info, SHM_STREAM_MODE);
+}
+
+
+static int shm_c_commit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct shm_modem *modem = get_modem(skb, info);
+	int err;
+	if (!modem)
+		return -EINVAL;
+
+	err = do_commit(modem);
+	if (!err)
+		do_reply(info, 0);
+	return err;
+}
+
+static int shm_c_register(struct sk_buff *skb, struct genl_info *info)
+{
+	int err;
+	struct shm_modem *modem = get_modem(skb, info);
+	if (!modem)
+		return -EINVAL;
+
+	err = do_register(modem);
+	if (!err)
+		do_reply(info, 0);
+	return err;
+}
+
+static int shm_c_set_addr(struct sk_buff *skb, struct genl_info *info)
+{
+	int err;
+	struct shm_modem *modem = get_modem(skb, info);
+	if (!modem)
+		return -EINVAL;
+
+	err = do_set_addr(modem);
+	if (!err)
+		do_reply(info, 0);
+	return err;
+}
+
+static int shm_c_reset(struct sk_buff *skb, struct genl_info *info)
+{
+	struct shm_modem *modem = get_modem(skb, info);
+	if (!modem)
+		return -EINVAL;
+
+	do_reset(modem);
+	do_reply(info, 0);
+	return 0;
+}
+
+static int shm_c_verify(struct sk_buff *skb, struct genl_info *info)
+{
+	int err;
+	struct shm_modem *modem = get_modem(skb, info);
+	if (!modem)
+		return -EINVAL;
+
+	err = verify_config(modem);
+	if (!err)
+		do_reply(info, 0);
+	return err;
+}
+
+static struct genl_ops shm_genl_ops[] = {
+	{
+	.cmd = SHM_C_ADD_STREAM_CHANNEL,
+	.flags = GENL_ADMIN_PERM,
+	.policy = shm_genl_policy,
+	.doit = shm_add_stream_ch,
+	.dumpit = NULL,
+	},
+	{
+	.cmd = SHM_C_ADD_PACKET_CHANNEL,
+	.flags = GENL_ADMIN_PERM,
+	.policy = shm_genl_policy,
+	.doit = shm_add_packet_ch,
+	.dumpit = NULL,
+	},
+	{
+	.cmd = SHM_C_COMMIT,
+	.flags = GENL_ADMIN_PERM,
+	.doit = shm_c_commit,
+	.dumpit = NULL,
+	},
+	{
+	.cmd = SHM_C_REGISTER,
+	.flags = GENL_ADMIN_PERM,
+	.doit = shm_c_register,
+	.dumpit = NULL,
+	},
+	{
+	.cmd = SHM_C_SET_ADDR,
+	.flags = GENL_ADMIN_PERM,
+	.doit = shm_c_set_addr,
+	.dumpit = NULL,
+	},
+	{
+	.cmd = SHM_C_RESET,
+	.flags = GENL_ADMIN_PERM,
+	.doit = shm_c_reset,
+	.dumpit = NULL,
+	},
+	{
+	.cmd = __SHM_C_VERIFY,
+	.flags = GENL_ADMIN_PERM,
+	.doit = shm_c_verify,
+	.dumpit = NULL,
+	},
+
+};
+
+/* Initialize boot handling and create sysfs entries*/
+int __init shm_boot_init(void)
+{
+	int err = -EINVAL;
+	bool shm_fake = false;
+
+	modem = kzalloc(sizeof(struct shm_modem), GFP_KERNEL);
+	if (modem == NULL)
+		return -ENOMEM;
+
+	/* Negative shm_size indicates module test without real SHM */
+	if (shm_size < 0) {
+		shm_fake = true;
+		shm_size = abs(shm_size);
+	}
+
+	if (shm_size < TOC_SZ)
+		goto bad_config;
+
+	if (shm_fake) {
+		modem->shm_start = kzalloc(shm_size, GFP_KERNEL);
+		err = -ENOMEM;
+		if (!modem->shm_start)
+			goto error;
+		shm_start = (unsigned long) modem->shm_start;
+		memset(modem->shm_start, 0xaa, shm_size);
+	} else {
+		if (shm_start == 0)
+			goto bad_config;
+		modem->shm_start = ioremap(shm_start, shm_size);
+	}
+
+	/* Initiate the Master TOC to 0xff for the first 512 bytes */
+	if (shm_size > TOC_SZ)
+		memset(modem->shm_start, 0xff, TOC_SZ);
+
+	modem->modem_bootimg_size = TOC_SZ;
+
+	pr_debug("Boot image addr: %p size:%d\n", modem->shm_start,
+			modem->modem_bootimg_size);
+
+	err = genl_register_family_with_ops(&shm_gnl_family,
+		shm_genl_ops, ARRAY_SIZE(shm_genl_ops));
+	if (err)
+		goto error;
+
+	modem->gennetl_reg = true;
+	modem->fw_requested = true;
+	err = modem_shm_request_firmware(modem, THIS_MODULE,
+			STE_BOOTIMG_NAME, shm_firmware);
+	if (err)
+		goto error;
+
+	return err;
+error:
+	pr_debug("initialization failed\n");
+
+	if (shm_fake)
+		kfree(modem->shm_start);
+	return err;
+bad_config:
+	pr_err("Bad module configuration:"
+			" shm_base_address:%lu shm_size:%lu err:%d\n",
+			shm_start, shm_size, err);
+	/* Buildin module should not return error */
+	return -EINVAL;
+}
+
+void __exit shm_boot_exit(void)
+{
+
+	if (modem->gennetl_reg)
+		genl_unregister_family(&shm_gnl_family);
+	modem->gennetl_reg = false;
+}
+module_init(shm_boot_init);
+module_exit(shm_boot_exit);
diff --git a/drivers/modem_shm/shm_bus.c b/drivers/modem_shm/shm_bus.c
new file mode 100644
index 0000000..6ca238d
--- /dev/null
+++ b/drivers/modem_shm/shm_bus.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/modem_shm/shm_dev.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brændland <sjur.brandeland@stericsson.com>");
+
+static int shm_dev_match(struct device *_dv, struct device_driver *_dr)
+{
+	struct shm_dev *dev = container_of(_dv, struct shm_dev, dev);
+	struct shm_driver *drv = container_of(_dr, struct shm_driver, driver);
+
+	return drv->mode ==  (drv->mode & dev->cfg.mode);
+}
+
+static int shm_dev_probe(struct device *_d)
+{
+	struct shm_dev *dev = container_of(_d, struct shm_dev, dev);
+	struct shm_driver *drv = container_of(dev->dev.driver,
+						 struct shm_driver, driver);
+	return drv->probe(dev);
+}
+
+static int shm_dev_remove(struct device *_d)
+{
+	struct shm_dev *dev = container_of(_d, struct shm_dev, dev);
+	struct shm_driver *drv = container_of(dev->dev.driver,
+						 struct shm_driver, driver);
+	drv->remove(dev);
+	return 0;
+}
+
+static struct bus_type shm_bus = {
+	.name  = "modem_shm",
+	.match = shm_dev_match,
+	.probe = shm_dev_probe,
+	.remove = shm_dev_remove,
+};
+
+struct shm_iter_data {
+	void *data;
+	void (*fn)(struct shm_dev *, void *);
+};
+
+int shm_iter(struct device *_dev, void *data)
+{
+	struct shm_dev *dev = container_of(_dev, struct shm_dev, dev);
+	struct shm_iter_data *iter_data = data;
+
+	iter_data->fn(dev, iter_data->data);
+	return 0;
+}
+
+void modem_shm_foreach_dev(void fn(struct shm_dev *, void *), void *data)
+{
+	struct shm_iter_data iter = {
+		.data = data,
+		.fn = fn
+	};
+
+	bus_for_each_dev(&shm_bus, NULL, &iter, shm_iter);
+}
+EXPORT_SYMBOL_GPL(modem_shm_foreach_dev);
+
+int modem_shm_register_driver(struct shm_driver *driver)
+{
+	driver->driver.bus = &shm_bus;
+	return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(modem_shm_register_driver);
+
+void modem_shm_unregister_driver(struct shm_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_GPL(modem_shm_unregister_driver);
+
+int modem_shm_register_device(struct shm_dev *dev)
+{
+	int err;
+
+	dev->dev.bus = &shm_bus;
+	err = device_register(&dev->dev);
+	return err;
+}
+EXPORT_SYMBOL_GPL(modem_shm_register_device);
+
+void modem_shm_unregister_device(struct shm_dev *dev)
+{
+	device_unregister(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(modem_shm_unregister_device);
+
+static int shm_bus_init(void)
+{
+	if (bus_register(&shm_bus) != 0)
+		panic("shm bus registration failed");
+	return 0;
+}
+
+static void __exit shm_bus_exit(void)
+{
+	bus_unregister(&shm_bus);
+}
+
+core_initcall(shm_bus_init);
+module_exit(shm_bus_exit);
diff --git a/drivers/modem_shm/shm_chr.c b/drivers/modem_shm/shm_chr.c
new file mode 100644
index 0000000..64c39a8
--- /dev/null
+++ b/drivers/modem_shm/shm_chr.c
@@ -0,0 +1,1242 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author:	Per Sigmond / Per.Sigmond@stericsson.com
+ *		Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <linux/modem_shm/shm_dev.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brændland <sjur.brandeland@stericsson.com>");
+
+static LIST_HEAD(shmchr_chrdev_list);
+static spinlock_t list_lock;
+
+#define mdev_dbg(dev, fmt, arg...) \
+		dev_dbg(dev->misc.this_device, pr_fmt(fmt), ##arg)
+
+#define mdev_vdbg(dev, fmt, arg...) \
+		dev_vdbg(dev->misc.this_device, pr_fmt(fmt), ##arg)
+
+#define OPEN_TOUT			(25 * HZ)
+#define CONN_STATE_OPEN_BIT		0
+#define CONN_STATE_PENDING_BIT		1
+#define CONN_REMOTE_TEARDOWN_BIT	2
+#define CONN_EOF_BIT			4
+
+#define STATE_IS_OPEN(dev) test_bit(CONN_STATE_OPEN_BIT, \
+					(void *) &(dev)->conn_state)
+#define STATE_IS_REMOTE_TEARDOWN(dev) test_bit(CONN_REMOTE_TEARDOWN_BIT, \
+					(void *) &(dev)->conn_state)
+#define STATE_IS_PENDING(dev) test_bit(CONN_STATE_PENDING_BIT, \
+					(void *) &(dev)->conn_state)
+#define SET_STATE_OPEN(dev) (set_bit(CONN_STATE_OPEN_BIT,	\
+			(void *) &(dev)->conn_state), \
+			pr_devel("SET_STATE_OPEN:%d\n", dev->conn_state))
+#define SET_STATE_CLOSED(dev) (clear_bit(CONN_STATE_OPEN_BIT,	\
+			(void *) &(dev)->conn_state), \
+			pr_devel("SET_STATE_CLOSED:%d\n", dev->conn_state))
+#define SET_PENDING_ON(dev) (set_bit(CONN_STATE_PENDING_BIT,	\
+			(void *) &(dev)->conn_state), \
+			pr_devel("SET_PENDING_ON:%d\n", dev->conn_state))
+#define SET_PENDING_OFF(dev) (clear_bit(CONN_STATE_PENDING_BIT, \
+			(void *) &(dev)->conn_state), \
+			pr_devel("SET_PENDING_OFF:%d\n", dev->conn_state))
+#define SET_REMOTE_TEARDOWN(dev) (set_bit(CONN_REMOTE_TEARDOWN_BIT,	\
+			(void *) &(dev)->conn_state), \
+			pr_devel("SET_REMOTE_TEARDOWN:%d\n", dev->conn_state))
+#define CLEAR_REMOTE_TEARDOWN(dev) (clear_bit(CONN_REMOTE_TEARDOWN_BIT, \
+			(void *) &(dev)->conn_state), \
+			pr_devel("CLEAR_REMOTE_TEARDOWN:%d\n", dev->conn_state))
+#define SET_EOF(dev) (set_bit(CONN_EOF_BIT,	\
+			(void *) &(dev)->conn_state), \
+			pr_devel("SET_EOF:%d\n", dev->conn_state))
+#define CLEAR_EOF(dev) (clear_bit(CONN_EOF_BIT, \
+			(void *) &(dev)->conn_state), \
+			pr_devel("CLEAR_EOF:%d\n", dev->conn_state))
+#define STATE_IS_EOF(dev) test_bit(CONN_EOF_BIT, \
+					(void *) &(dev)->conn_state)
+
+#define CHR_READ_FLAG 0x01
+#define CHR_WRITE_FLAG 0x02
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *debugfsdir;
+#include <linux/debugfs.h>
+#define	dbfs_atomic_inc(a) atomic_inc(a)
+#define	dbfs_atomic_add(v, a) atomic_add_return(v, a)
+#else
+#define	dbfs_atomic_inc(a) 0
+#define	dbfs_atomic_add(v, a) 0
+#endif
+
+struct ringbuf {
+	__le32 *ri;	/* Pointer to read-index in shared memory.*/
+	__le32 *wi;	/* Pointer to write-index in shared memory */
+	unsigned int size;/* Size of buffer */
+	void *data;	/* Buffer data in shared memory */
+};
+
+struct shmchr_char_dev {
+	struct shm_dev *shm;
+	struct kref kref;
+	struct ringbuf rx, tx;
+	u32 conn_state;
+	char name[256];
+	struct miscdevice misc;
+	int file_mode;
+
+	/* Access to this struct and below layers */
+	struct mutex mutex;
+	wait_queue_head_t mgmt_wq;
+	/* List of misc test devices */
+	struct list_head list_field;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_device_dir;
+	atomic_t num_open;
+	atomic_t num_close;
+	atomic_t num_read;
+	atomic_t num_read_block;
+	atomic_t num_read_bytes;
+
+	atomic_t num_write;
+	atomic_t num_write_block;
+	atomic_t num_write_bytes;
+
+	atomic_t num_init;
+	atomic_t num_init_resp;
+	atomic_t num_deinit;
+	atomic_t num_deinit_resp;
+	atomic_t num_remote_teardown_ind;
+
+#endif
+};
+
+static void shm_release(struct kref *kref)
+{
+	struct shmchr_char_dev *dev;
+	dev = container_of(kref, struct shmchr_char_dev, kref);
+	kfree(dev);
+}
+
+static void shmchr_get(struct shmchr_char_dev *dev)
+{
+	kref_get(&dev->kref);
+}
+
+static void shmchr_put(struct shmchr_char_dev *dev)
+{
+	kref_put(&dev->kref, shm_release);
+}
+
+static inline unsigned int ringbuf_empty(struct ringbuf *rb)
+{
+	return *rb->wi == *rb->ri;
+}
+
+static inline unsigned int ringbuf_full(struct ringbuf *rb)
+{
+	return (le32_to_cpu(*rb->wi) + 1) % rb->size == le32_to_cpu(*rb->ri);
+}
+
+static int insert_ringbuf(struct ringbuf *rb, const char __user *from,
+		u32 len)
+{
+	u32 wi = le32_to_cpu(*rb->wi);
+	u32 ri = le32_to_cpu(*rb->ri);
+	u32 cpylen, cpylen2 = 0, notcpy;
+
+	pr_devel("insert: wi:%d ri:%d len:%d\n", wi, ri, len);
+	if (wi >= ri) {
+		len = min(len, rb->size - 1 - wi + ri);
+		cpylen = min(rb->size, wi + len) - wi;
+
+		/* Write is ahead of read, copy 'cpylen' data from 'wi' */
+		notcpy = copy_from_user(rb->data + wi, from, cpylen);
+		if (cpylen > 0 && notcpy == cpylen)
+			return -EIO;
+
+		if (cpylen < len && notcpy == 0) {
+			cpylen2 = min(ri - 1 , len - cpylen);
+
+			/* We have wrapped copy 'cpylen2' from start */
+			notcpy = copy_from_user(rb->data, from + cpylen,
+					cpylen2);
+		}
+	} else {
+		cpylen = min(ri - 1 - wi , len);
+
+		/* Read is ahead of write, copy from wi to (ri - 1) */
+		notcpy = copy_from_user(rb->data + wi, from, cpylen);
+		if (cpylen > 0 && notcpy == cpylen)
+			return -EIO;
+
+	}
+	/* Do write barrier before updating index */
+	smp_wmb();
+	*rb->wi = cpu_to_le32((wi + cpylen + cpylen2 - notcpy) % rb->size);
+	pr_devel("write ringbuf: wi: %d->%d l:%d\n",
+			wi, le32_to_cpu(*rb->wi), cpylen + cpylen2);
+	return cpylen + cpylen2 - notcpy;
+}
+
+static int extract_ringbuf(struct ringbuf *rb, void __user *to, u32 len)
+{
+	u32 wi = le32_to_cpu(*rb->wi);
+	u32 ri = le32_to_cpu(*rb->ri);
+	u32 cpylen = 0, cpylen2 = 0, notcpy;
+
+	pr_devel("extract: wi:%d ri:%d len:%d\n", wi, ri, len);
+	if (ri <= wi) {
+		len = min(wi - ri, len);
+
+		/* Read is ahead of write, copy 'len' data from 'ri' */
+		notcpy = copy_to_user(to, rb->data + ri, len);
+		if (len > 0 && notcpy == len)
+			return -EIO;
+
+		/* Do write barrier before updating index */
+		smp_wmb();
+		*rb->ri = cpu_to_le32(ri + len - notcpy);
+		pr_devel("read ringbuf: ri: %d->%d len:%d\n",
+			ri, le32_to_cpu(*rb->ri), len - notcpy);
+
+		return len - notcpy;
+	} else {
+		/* wr >= ri */
+		cpylen = min(rb->size - ri, len);
+
+		/* Write is ahead, copy 'cpylen' data from ri until end */
+		notcpy = copy_to_user(to, rb->data + ri, cpylen);
+		if (cpylen > 0 && notcpy == cpylen)
+			return -EIO;
+		if (cpylen < len && notcpy == 0) {
+			cpylen2 = min(wi , len - cpylen);
+			/* we have wrapped copy from [0 .. cpylen2] */
+			notcpy = copy_to_user(to + cpylen, rb->data, cpylen2);
+		}
+		/* Do write barrier before updating index */
+		smp_wmb();
+
+		*rb->ri = cpu_to_le32((ri + cpylen + cpylen2 - notcpy)
+						% rb->size);
+		pr_devel("read ringbuf: ri: %d->%d cpylen:%d\n",
+			ri, le32_to_cpu(*rb->ri), cpylen + cpylen2 - notcpy);
+
+		return cpylen + cpylen2 - notcpy;
+	}
+}
+
+static void drain_ringbuf(struct shmchr_char_dev *dev)
+{
+	/* Empty the ringbuf. */
+	*dev->shm->cfg.rx.read = *dev->shm->cfg.rx.write;
+	*dev->shm->cfg.tx.write = *dev->shm->cfg.tx.read;
+}
+
+static int open_cb(void *drv)
+{
+	struct shmchr_char_dev *dev = drv;
+
+	dbfs_atomic_inc(&dev->num_init_resp);
+	/* Signal reader that data is available. */
+	WARN_ON(!STATE_IS_OPEN(dev));
+	SET_PENDING_OFF(dev);
+	wake_up_interruptible_all(&dev->mgmt_wq);
+	return 0;
+}
+
+static void close_cb(void *drv)
+{
+	struct shmchr_char_dev *dev = drv;
+
+	dbfs_atomic_inc(&dev->num_remote_teardown_ind);
+	if (STATE_IS_PENDING(dev) && !STATE_IS_OPEN(dev)) {
+		/* Normal close sequence */
+		SET_PENDING_OFF(dev);
+		CLEAR_REMOTE_TEARDOWN(dev);
+		SET_EOF(dev);
+		drain_ringbuf(dev);
+		dev->file_mode = 0;
+	} else {
+		/* Remote teardown, close should be called from user-space */
+		SET_REMOTE_TEARDOWN(dev);
+		SET_PENDING_OFF(dev);
+	}
+
+	wake_up_interruptible_all(&dev->mgmt_wq);
+}
+
+static int ipc_rx_cb(void *drv)
+{
+	struct shmchr_char_dev *dev = drv;
+
+	if (unlikely(*dev->shm->cfg.rx.state == cpu_to_le32(SHM_CLOSED)))
+		return -ESHUTDOWN;
+
+	/*
+	 * Performance could perhaps be improved by having a WAIT
+	 * flag, similar to SOCK_ASYNC_WAITDATA, and only do wake up
+	 * when it's actually needed.
+	 */
+	wake_up_interruptible_all(&dev->mgmt_wq);
+	return 0;
+}
+
+static int ipc_tx_release_cb(void *drv)
+{
+	struct shmchr_char_dev *dev = drv;
+
+	wake_up_interruptible_all(&dev->mgmt_wq);
+	return 0;
+}
+
+/* Device Read function called from Linux kernel */
+static ssize_t shmchr_chrread(struct file *filp, char __user *buf,
+	 size_t count, loff_t *f_pos)
+{
+	unsigned int len = 0;
+	int result;
+	struct shmchr_char_dev *dev = filp->private_data;
+	ssize_t ret = -EIO;
+
+	if (dev == NULL) {
+		mdev_dbg(dev, "private_data not set!\n");
+		return -EBADFD;
+	}
+
+	/* I want to be alone on dev (except status and queue) */
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		mdev_dbg(dev, "mutex_lock_interruptible got signalled\n");
+		return -ERESTARTSYS;
+	}
+	shmchr_get(dev);
+
+	if (!STATE_IS_OPEN(dev)) {
+		/* Device is closed or closing. */
+		if (!STATE_IS_PENDING(dev)) {
+			mdev_dbg(dev, "device is closed (by remote)\n");
+			ret = -ECONNRESET;
+		} else {
+			mdev_dbg(dev, "device is closing...\n");
+			ret = -EBADF;
+		}
+		goto read_error;
+	}
+
+	dbfs_atomic_inc(&dev->num_read);
+
+	/* Device is open or opening. */
+	if (STATE_IS_PENDING(dev)) {
+		mdev_vdbg(dev, "device is opening...\n");
+
+		dbfs_atomic_inc(&dev->num_read_block);
+		if (filp->f_flags & O_NONBLOCK) {
+			/* We can't block. */
+			mdev_dbg(dev, "exit: state pending and O_NONBLOCK\n");
+			ret = -EAGAIN;
+			goto read_error;
+		}
+
+		/*
+		 * To reach here client must do blocking open,
+		 * and start read() before open completes. This is
+		 * quite quirky, but let's handle it anyway.
+		 */
+		result =
+		    wait_event_interruptible(dev->mgmt_wq,
+					!STATE_IS_PENDING(dev) ||
+				    STATE_IS_REMOTE_TEARDOWN(dev));
+
+		if (result == -ERESTARTSYS) {
+			mdev_dbg(dev, "wait_event_interruptible"
+				 " woken by a signal (1)\n");
+			ret = -ERESTARTSYS;
+			goto read_error;
+		}
+		if (STATE_IS_REMOTE_TEARDOWN(dev)) {
+			mdev_dbg(dev,
+				"received remote_shutdown indication (1)\n");
+			ret = -ESHUTDOWN;
+			goto read_error;
+		}
+	}
+
+	/* Block if we don't have any received buffers.
+	 * The queue has its own lock.
+	 */
+	while (ringbuf_empty(&dev->rx)) {
+
+		if (filp->f_flags & O_NONBLOCK) {
+			mdev_vdbg(dev, "exit: O_NONBLOCK\n");
+			ret = -EAGAIN;
+			goto read_error;
+		}
+
+		/* Let writers in. */
+		mutex_unlock(&dev->mutex);
+
+		mdev_vdbg(dev, "wait for data\n");
+		/* Block reader until data arrives or device is closed. */
+		if (wait_event_interruptible(dev->mgmt_wq,
+				!ringbuf_empty(&dev->rx)
+				|| STATE_IS_REMOTE_TEARDOWN(dev)
+				|| !STATE_IS_OPEN(dev)) == -ERESTARTSYS) {
+			mdev_vdbg(dev, "event_interruptible woken by "
+				 "a signal, signal_pending(current) = %d\n",
+				signal_pending(current));
+			return -ERESTARTSYS;
+		}
+
+		mdev_vdbg(dev, "wakeup readq\n");
+
+		if (STATE_IS_REMOTE_TEARDOWN(dev) && ringbuf_empty(&dev->rx)) {
+			if (!STATE_IS_EOF(dev)) {
+				mdev_dbg(dev, "First EOF OK\n");
+				SET_EOF(dev);
+				ret = 0;
+				goto error_nolock;
+			}
+			mdev_dbg(dev, "2'nd EOF - remote_shutdown\n");
+			ret = -ECONNRESET;
+			goto error_nolock;
+		}
+
+		/* I want to be alone on dev (except status and queue). */
+		if (mutex_lock_interruptible(&dev->mutex)) {
+			mdev_dbg(dev, "mutex_lock_interruptible"
+					" got signalled\n");
+			return -ERESTARTSYS;
+		}
+
+		if (!STATE_IS_OPEN(dev)) {
+			/* Someone closed the link, report error. */
+			mdev_dbg(dev, "remote end shutdown!\n");
+			ret = -EBADF;
+			goto read_error;
+		}
+	}
+
+	mdev_vdbg(dev, "copy data\n");
+	len = extract_ringbuf(&dev->rx, buf, count);
+	if (len <= 0) {
+		mdev_dbg(dev, "Extracting from ringbuf failed\n");
+		ret = -EINVAL;
+		goto read_error;
+	}
+
+	/* Signal to modem that data is read from ringbuf */
+
+	dev->shm->ipc_rx_release(dev->shm, false);
+
+	dbfs_atomic_add(len, &dev->num_read_bytes);
+	/* Let the others in. */
+	mutex_unlock(&dev->mutex);
+	shmchr_put(dev);
+	return len;
+
+read_error:
+	mutex_unlock(&dev->mutex);
+error_nolock:
+	shmchr_put(dev);
+	return ret;
+}
+
+/* Device write function called from Linux kernel (misc device) */
+static ssize_t shmchr_chrwrite(struct file *filp, const char __user *buf,
+		      size_t count, loff_t *f_pos)
+{
+	struct shmchr_char_dev *dev = filp->private_data;
+	ssize_t ret = -EIO;
+	int result;
+	uint len = 0;
+
+	if (dev == NULL) {
+		mdev_dbg(dev, "private_data not set!\n");
+		ret = -EBADFD;
+		goto write_error_no_unlock;
+	}
+
+	/* I want to be alone on dev (except status and queue). */
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		mdev_dbg(dev, "mutex_lock_interruptible got signalled\n");
+		ret = -ERESTARTSYS;
+		goto write_error_no_unlock;
+	}
+	shmchr_get(dev);
+
+	dbfs_atomic_inc(&dev->num_write);
+	if (!STATE_IS_OPEN(dev)) {
+		/* Device is closed or closing. */
+		if (!STATE_IS_PENDING(dev)) {
+			mdev_dbg(dev, "device is closed (by remote)\n");
+			ret = -EPIPE;
+		} else {
+			mdev_dbg(dev, "device is closing...\n");
+			ret = -EBADF;
+		}
+		goto write_error;
+	}
+
+	/* Device is open or opening. */
+	if (STATE_IS_PENDING(dev)) {
+		mdev_dbg(dev, "device is opening...\n");
+
+		dbfs_atomic_inc(&dev->num_write_block);
+		if (filp->f_flags & O_NONBLOCK) {
+			/* We can't block */
+			mdev_dbg(dev, "exit: state pending and O_NONBLOCK\n");
+			ret = -EAGAIN;
+			goto write_error;
+		}
+
+		/* Blocking mode; state is pending and we need to wait
+		 * for its conclusion. (Shutdown_ind set pending off.)
+		 */
+		result =
+		    wait_event_interruptible(dev->mgmt_wq,
+					!STATE_IS_PENDING(dev) ||
+					STATE_IS_REMOTE_TEARDOWN(dev));
+		if (result == -ERESTARTSYS) {
+			mdev_dbg(dev, "wait_event_interruptible"
+				 " woken by a signal (1)\n");
+			ret = -ERESTARTSYS;
+			goto write_error;
+		}
+	}
+	if (STATE_IS_REMOTE_TEARDOWN(dev)) {
+		mdev_dbg(dev, "received remote_shutdown indication\n");
+		ret = -EPIPE;
+		goto write_error;
+	}
+
+	while (ringbuf_full(&dev->tx)) {
+		/* Flow is off. Check non-block flag. */
+		if (filp->f_flags & O_NONBLOCK) {
+			mdev_dbg(dev, "exit: O_NONBLOCK and tx flow off");
+			ret = -EAGAIN;
+			goto write_error;
+		}
+
+		/* Let readers in. */
+		mutex_unlock(&dev->mutex);
+
+		mdev_vdbg(dev, "wait for write space\n");
+		/* Wait until flow is on or device is closed. */
+		if (wait_event_interruptible(dev->mgmt_wq,
+					!ringbuf_full(&dev->tx)
+					|| !STATE_IS_OPEN(dev)
+					|| STATE_IS_REMOTE_TEARDOWN(dev)
+					) == -ERESTARTSYS) {
+			mdev_dbg(dev, "wait_event_interruptible"
+				 " woken by a signal (1)\n");
+			ret = -ERESTARTSYS;
+			goto write_error_no_unlock;
+		}
+
+		/* I want to be alone on dev (except status and queue). */
+		if (mutex_lock_interruptible(&dev->mutex)) {
+			mdev_dbg(dev, "mutex_lock_interruptible "
+					"got signalled\n");
+			ret = -ERESTARTSYS;
+			goto write_error_no_unlock;
+		}
+
+		mdev_vdbg(dev, "wakeup got write space\n");
+		if (!STATE_IS_OPEN(dev)) {
+			/* Someone closed the link, report error. */
+			mdev_dbg(dev, "remote end shutdown!\n");
+			ret = -EPIPE;
+			goto write_error;
+		}
+		if (STATE_IS_REMOTE_TEARDOWN(dev)) {
+			mdev_dbg(dev, "received remote_shutdown indication\n");
+			ret = -ESHUTDOWN;
+			goto write_error;
+		}
+	}
+	len = insert_ringbuf(&dev->tx, buf, count);
+	mdev_vdbg(dev, "inserted %d bytes\n", len);
+	if (len <= 0) {
+		mdev_dbg(dev, "transmit failed, error = %d\n",
+				(int) ret);
+		goto write_error;
+	}
+
+	dbfs_atomic_add(len, &dev->num_write_bytes);
+
+	/* Signal to modem that data is put in ringbuf */
+	dev->shm->ipc_tx(dev->shm);
+
+	mutex_unlock(&dev->mutex);
+	shmchr_put(dev);
+	return len;
+
+write_error:
+	mutex_unlock(&dev->mutex);
+write_error_no_unlock:
+	shmchr_put(dev);
+	return ret;
+}
+
+static unsigned int shmchr_chrpoll(struct file *filp, poll_table *waittab)
+{
+	struct shmchr_char_dev *dev = filp->private_data;
+	unsigned int mask = 0;
+
+	if (dev == NULL) {
+		mdev_dbg(dev, "private_data not set!\n");
+		return -EBADFD;
+	}
+
+	/* I want to be alone on dev (except status and queue). */
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		mdev_dbg(dev, "mutex_lock_interruptible got signalled\n");
+		mask |= POLLERR;
+		goto out_unlocked;
+	}
+	shmchr_get(dev);
+
+	if (STATE_IS_REMOTE_TEARDOWN(dev)) {
+		mdev_dbg(dev, "not open\n");
+		mask |= POLLRDHUP | POLLHUP;
+		goto out;
+	}
+
+	mdev_vdbg(dev, "poll wait\n");
+	poll_wait(filp, &dev->mgmt_wq, waittab);
+
+	if (STATE_IS_OPEN(dev) && STATE_IS_PENDING(dev))
+		goto out;
+
+	if (!ringbuf_empty(&dev->rx))
+		mask |= (POLLIN | POLLRDNORM);
+
+	if (!ringbuf_full(&dev->tx))
+		mask |= (POLLOUT | POLLWRNORM);
+
+out:
+	mutex_unlock(&dev->mutex);
+out_unlocked:
+	mdev_vdbg(dev, "poll return mask=0x%04x\n", mask);
+	shmchr_put(dev);
+	return mask;
+}
+
+/* Usage:
+ * minor >= 0 : find from minor
+ * minor < 0 and name == name : find from name
+ * minor < 0 and name == NULL : get first
+ */
+
+static struct shmchr_char_dev *find_device(int minor, char *name,
+					 int remove_from_list)
+{
+	struct list_head *list_node;
+	struct list_head *n;
+	struct shmchr_char_dev *dev = NULL;
+	struct shmchr_char_dev *tmp;
+	spin_lock(&list_lock);
+	pr_devel("start looping\n");
+	list_for_each_safe(list_node, n, &shmchr_chrdev_list) {
+		tmp = list_entry(list_node, struct shmchr_char_dev,
+				list_field);
+		if (minor >= 0) {	/* find from minor */
+			if (tmp->misc.minor == minor)
+				dev = tmp;
+
+		} else if (name) {	/* find from name */
+			if (!strncmp(tmp->name, name, sizeof(tmp->name)))
+				dev = tmp;
+		} else {	/* take first */
+			dev = tmp;
+		}
+
+		if (dev) {
+			mdev_vdbg(dev, "match %d, %s\n",
+				      minor, name);
+			if (remove_from_list)
+				list_del(list_node);
+			break;
+		}
+	}
+	spin_unlock(&list_lock);
+	return dev;
+}
+
+static int shmchr_chropen(struct inode *inode, struct file *filp)
+{
+	struct shmchr_char_dev *dev = NULL;
+	int result = -1;
+	int minor = iminor(inode);
+	int mode = 0;
+	int ret = -EIO;
+
+	dev = find_device(minor, NULL, 0);
+
+	if (dev == NULL) {
+		mdev_dbg(dev, "Could not find device\n");
+		return -EBADF;
+	}
+
+	/* I want to be alone on dev (except status and queue). */
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		mdev_dbg(dev, "mutex_lock_interruptible got signalled\n");
+		return -ERESTARTSYS;
+	}
+
+	shmchr_get(dev);
+	dbfs_atomic_inc(&dev->num_open);
+	filp->private_data = dev;
+
+	switch (filp->f_flags & O_ACCMODE) {
+	case O_RDONLY:
+		mode = CHR_READ_FLAG;
+		break;
+	case O_WRONLY:
+		mode = CHR_WRITE_FLAG;
+		break;
+	case O_RDWR:
+		mode = CHR_READ_FLAG | CHR_WRITE_FLAG;
+		break;
+	}
+
+	/* If device is not open, make sure device is in fully closed state. */
+	if (!STATE_IS_OPEN(dev)) {
+		/* Has link close response been received
+		 * (if we ever sent it)?
+		 */
+		if (STATE_IS_PENDING(dev)) {
+			/* Still waiting for close response from remote.
+			 * If opened non-blocking, report "would block".
+			 */
+			if (filp->f_flags & O_NONBLOCK) {
+				mdev_vdbg(dev,
+					"exit: O_NONBLOCK && close pending\n");
+				ret = -EAGAIN;
+				goto open_error;
+			}
+
+			mdev_vdbg(dev, "WAIT for close response from remote\n");
+
+			/*
+			 * Blocking mode; close is pending and we need to wait
+			 * for its conclusion. However modem may be dead,
+			 * or resureccted and alive waiting for
+			 * an open ack.
+			 * It's hard to get this rigth - if state is
+			 * pending. We have missed a state update,
+			 * let's just wait for ack, and then proceede
+			 * with watever state we have.
+			 */
+			result =
+			    wait_event_interruptible_timeout(dev->mgmt_wq,
+					    !STATE_IS_PENDING(dev) ||
+					    STATE_IS_REMOTE_TEARDOWN(dev),
+					    OPEN_TOUT);
+
+			if (result == -ERESTARTSYS) {
+				mdev_dbg(dev, "wait_event_interruptible"
+					" woken by a signal (1)\n");
+				ret = -ERESTARTSYS;
+				goto open_error;
+			}
+
+			if (result == 0) {
+				SET_PENDING_OFF(dev);
+				mdev_dbg(dev,
+				    "Timeout -pending close -Clear pending");
+			} else
+				mdev_dbg(dev, "wakeup (wait for close)");
+		}
+	}
+
+	/* Device is now either closed, pending open or open */
+	if (STATE_IS_OPEN(dev) && !STATE_IS_PENDING(dev)) {
+		/* Open */
+		mdev_vdbg(dev, "Device is already opened (dev=%p) check"
+				"access f_flags = 0x%x file_mode = 0x%x\n",
+				dev, mode, dev->file_mode);
+
+		if (mode & dev->file_mode) {
+			mdev_vdbg(dev, "Access mode already in use 0x%x\n",
+					mode);
+			ret = -EBUSY;
+			goto open_error;
+		}
+	} else {
+
+		/* We are closed or pending open.
+		 * If closed:	    send link setup
+		 * If pending open: link setup already sent (we could have been
+		 *		    interrupted by a signal last time)
+		 */
+		if (!STATE_IS_OPEN(dev)) {
+			/* First opening of file; do connect */
+
+			SET_STATE_OPEN(dev);
+			SET_PENDING_ON(dev);
+			CLEAR_EOF(dev);
+			/* Send "open" by resetting indexes */
+			result = dev->shm->open(dev->shm);
+
+			if (result < 0) {
+				mdev_dbg(dev, "can't open channel\n");
+				ret = -EIO;
+				SET_STATE_CLOSED(dev);
+				SET_PENDING_OFF(dev);
+				goto open_error;
+			}
+			dbfs_atomic_inc(&dev->num_init);
+		}
+
+		/* If opened non-blocking, report "success".
+		 */
+		if (filp->f_flags & O_NONBLOCK) {
+			mdev_vdbg(dev, "EXIT: O_NONBLOCK success\n");
+			ret = 0;
+			goto open_success;
+		}
+
+		mdev_vdbg(dev, "WAIT for connect response\n");
+		/*
+		 * misc_open holds a global mutex anyway so there is no
+		 * reason to release our own while waiting
+		 */
+		result =
+		    wait_event_interruptible_timeout(dev->mgmt_wq,
+				    !STATE_IS_PENDING(dev) ||
+				    STATE_IS_REMOTE_TEARDOWN(dev),
+				    OPEN_TOUT);
+		if (result == 0) {
+			mdev_dbg(dev, "wait_event_interruptible timeout (1)\n");
+			ret = -ETIMEDOUT;
+			goto open_error;
+		}
+		if (result == -ERESTARTSYS) {
+			mdev_dbg(dev, "wait_event_interruptible woken by sig");
+			ret = -ERESTARTSYS;
+			goto open_error;
+		}
+		if (STATE_IS_REMOTE_TEARDOWN(dev)) {
+			mdev_dbg(dev, "received remote_shutdown indication\n");
+			ret = -ESHUTDOWN;
+			goto open_error;
+		}
+
+		if (!STATE_IS_OPEN(dev)) {
+			/* Lower layers said "no". */
+			mdev_dbg(dev, "shmchr_chropen: Closed received\n");
+			ret = -EPIPE;
+			goto open_error;
+		}
+
+		mdev_vdbg(dev, "connect received\n");
+	}
+open_success:
+	/* Open is OK. */
+	dev->file_mode |= mode;
+
+	mdev_vdbg(dev, "file mode = %x\n", dev->file_mode);
+
+	mutex_unlock(&dev->mutex);
+	shmchr_put(dev);
+	return 0;
+
+open_error:
+	dev->shm->close(dev->shm);
+	SET_STATE_CLOSED(dev);
+	SET_PENDING_OFF(dev);
+	CLEAR_REMOTE_TEARDOWN(dev);
+	mutex_unlock(&dev->mutex);
+	shmchr_put(dev);
+	return ret;
+}
+
+static int shmchr_chrrelease(struct inode *inode, struct file *filp)
+{
+	struct shmchr_char_dev *dev = NULL;
+	int minor = iminor(inode);
+	int mode = 0;
+
+
+	dev = find_device(minor, NULL, 0);
+	if (dev == NULL) {
+		mdev_dbg(dev, "Could not find device\n");
+		return -EBADF;
+	}
+
+	/* I want to be alone on dev (except status queue). */
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		mdev_dbg(dev, "mutex_lock_interruptible got signalled\n");
+		return -ERESTARTSYS;
+	}
+
+	shmchr_get(dev);
+	dbfs_atomic_inc(&dev->num_close);
+
+	/* Is the device open? */
+	if (!STATE_IS_OPEN(dev)) {
+		mdev_vdbg(dev, "Device not open (dev=%p)\n",
+			      dev);
+		mutex_unlock(&dev->mutex);
+		shmchr_put(dev);
+		return 0;
+	}
+
+	switch (filp->f_flags & O_ACCMODE) {
+	case O_RDONLY:
+		mode = CHR_READ_FLAG;
+		break;
+	case O_WRONLY:
+		mode = CHR_WRITE_FLAG;
+		break;
+	case O_RDWR:
+		mode = CHR_READ_FLAG | CHR_WRITE_FLAG;
+		break;
+	}
+
+	dev->file_mode &= ~mode;
+	if (dev->file_mode) {
+		mdev_vdbg(dev, "Device is kept open by someone else, "
+			 " don't close. SHMCHR connection - file_mode = %x\n",
+			 dev->file_mode);
+		mutex_unlock(&dev->mutex);
+		shmchr_put(dev);
+		return 0;
+	}
+
+	/* IS_CLOSED have double meaning:
+	 * 1) Spontanous Remote Shutdown Request.
+	 * 2) Ack on a channel teardown(disconnect)
+	 * Must clear bit, in case we previously received
+	 * a remote shudown request.
+	 */
+
+	SET_STATE_CLOSED(dev);
+	SET_PENDING_ON(dev);
+	CLEAR_REMOTE_TEARDOWN(dev);
+	SET_EOF(dev);
+
+	dev->shm->close(dev->shm);
+
+	dbfs_atomic_inc(&dev->num_deinit);
+
+	/* Empty the ringbuf */
+	drain_ringbuf(dev);
+	dev->file_mode = 0;
+
+	mutex_unlock(&dev->mutex);
+	shmchr_put(dev);
+	return 0;
+}
+
+static const struct file_operations shmchr_chrfops = {
+	.owner = THIS_MODULE,
+	.read = shmchr_chrread,
+	.write = shmchr_chrwrite,
+	.open = shmchr_chropen,
+	.release = shmchr_chrrelease,
+	.poll = shmchr_chrpoll,
+};
+
+static int cfshm_probe(struct shm_dev *shm)
+
+{
+	struct shmchr_char_dev *dev = NULL;
+	int result;
+
+	pr_devel("cfshm_probe called\n");
+	if (shm == NULL)
+		return 0;
+
+	/* Allocate device */
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+
+	if (!dev) {
+		pr_err("kmalloc failed.\n");
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	kref_init(&dev->kref);
+
+	dev->shm = shm;
+	mutex_init(&dev->mutex);
+	init_waitqueue_head(&dev->mgmt_wq);
+
+	/* Fill in some information concerning the misc device. */
+	dev->misc.minor = MISC_DYNAMIC_MINOR;
+	if (strlen(shm->cfg.name) == 0) {
+		mdev_dbg(dev, "SHM device does not have a name\n");
+		return -EINVAL;
+	}
+	sprintf(dev->name, "%s", shm->cfg.name);
+	dev->misc.name = dev->name;
+	dev->misc.fops = &shmchr_chrfops;
+
+	dev->tx.ri = shm->cfg.tx.read;
+	dev->tx.wi = shm->cfg.tx.write;
+	dev->tx.data = shm->cfg.tx.addr;
+	dev->tx.size = shm->cfg.tx.ch_size - 1;
+
+	dev->rx.ri = shm->cfg.rx.read;
+	dev->rx.wi = shm->cfg.rx.write;
+	dev->rx.data = shm->cfg.rx.addr;
+	dev->rx.size = shm->cfg.rx.ch_size - 1;
+	if (dev->rx.size < 2 || dev->tx.size < 2) {
+		dev->rx.size = 0;
+		dev->tx.size = 0;
+		mdev_dbg(dev, "dev:error - channel size too small\n");
+		return -EINVAL;
+	}
+	dev->shm->ipc_rx_cb = ipc_rx_cb;
+	dev->shm->ipc_tx_release_cb = ipc_tx_release_cb;
+	dev->shm->open_cb = open_cb;
+	dev->shm->close_cb = close_cb;
+	dev->shm->driver_data = dev;
+
+	mutex_lock(&dev->mutex);
+
+	/* Register the device. */
+	dev->misc.parent = &shm->dev;
+	pr_devel("register dev:%s chr=%s(%s) dev=%p\n",
+			dev_name(&dev->shm->dev),
+			dev->name, shm->cfg.name, dev);
+	result = misc_register(&dev->misc);
+
+	/* Lock in order to try to stop someone from opening the device
+	 * too early. The misc device has its own lock. We cannot take our
+	 * lock until misc_register() is finished, because in open() the
+	 * locks are taken in this order (misc first and then dev).
+	 * So anyone managing to open the device between the misc_register
+	 * and the mutex_lock will get a "device not found" error. Don't
+	 * think it can be avoided.
+	 */
+
+	if (result < 0) {
+		pr_warn("error - %d, can't register misc\n",
+				result);
+		mutex_unlock(&dev->mutex);
+		goto err_failed;
+	}
+
+	mdev_vdbg(dev, "Registered dev with name=%s minor=%d, dev=%p\n",
+			dev->misc.name, dev->misc.minor, dev->misc.this_device);
+
+	SET_STATE_CLOSED(dev);
+	SET_PENDING_OFF(dev);
+	CLEAR_REMOTE_TEARDOWN(dev);
+	CLEAR_EOF(dev);
+
+	/* Add the device. */
+	spin_lock(&list_lock);
+	list_add(&dev->list_field, &shmchr_chrdev_list);
+	spin_unlock(&list_lock);
+
+#ifdef CONFIG_DEBUG_FS
+	if (debugfsdir != NULL) {
+		dev->debugfs_device_dir =
+		    debugfs_create_dir(dev->misc.name, debugfsdir);
+		debugfs_create_u32("conn_state", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir, &dev->conn_state);
+		debugfs_create_u32("num_open", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir,
+				   (u32 *) &dev->num_open);
+		debugfs_create_u32("num_close", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir,
+				   (u32 *) &dev->num_close);
+		debugfs_create_u32("num_init", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir,
+				   (u32 *) &dev->num_init);
+		debugfs_create_u32("num_init_resp", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir,
+				   (u32 *) &dev->num_init_resp);
+		debugfs_create_u32("num_deinit", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir,
+				   (u32 *) &dev->num_deinit);
+		debugfs_create_u32("num_deinit_resp", S_IRUSR | S_IWUSR,
+				   dev->debugfs_device_dir,
+				   (u32 *) &dev->num_deinit_resp);
+		debugfs_create_u32("num_remote_teardown_ind",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_remote_teardown_ind);
+		debugfs_create_u32("num_read",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_read);
+		debugfs_create_u32("num_read_block",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_read_block);
+		debugfs_create_u32("num_read_bytes",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_read_bytes);
+		debugfs_create_u32("num_write",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_write);
+		debugfs_create_u32("num_write_block",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_write_block);
+		debugfs_create_u32("num_write_bytes",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				   (u32 *) &dev->num_write_bytes);
+
+		debugfs_create_u32("rx_write_index",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				(u32 *) dev->shm->cfg.rx.write);
+		debugfs_create_u32("rx_read_index",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				(u32 *) dev->shm->cfg.rx.read);
+		debugfs_create_u32("rx_state",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				(u32 *) dev->shm->cfg.rx.state);
+		debugfs_create_u32("tx_write_index",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				(u32 *) dev->shm->cfg.tx.write);
+		debugfs_create_u32("tx_read_index",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				(u32 *) dev->shm->cfg.tx.read);
+		debugfs_create_u32("tx_state",
+				   S_IRUSR | S_IWUSR, dev->debugfs_device_dir,
+				(u32 *) dev->shm->cfg.tx.state);
+
+	}
+#endif
+	mutex_unlock(&dev->mutex);
+	return 0;
+err_failed:
+	shmchr_put(dev);
+	return result;
+}
+
+static int chrdev_remove(struct shmchr_char_dev *dev)
+{
+	if (!dev)
+		return -EBADF;
+
+	if (STATE_IS_OPEN(dev)) {
+		mdev_dbg(dev, "Device is opened "
+			 "(dev=%p) file_mode = 0x%x\n",
+			 dev, dev->file_mode);
+		SET_STATE_CLOSED(dev);
+		SET_PENDING_OFF(dev);
+		wake_up_interruptible_all(&dev->mgmt_wq);
+	}
+
+	if (mutex_lock_interruptible(&dev->mutex)) {
+		mdev_dbg(dev, "mutex_lock_interruptible got signalled\n");
+		shmchr_put(dev);
+		return -ERESTARTSYS;
+	}
+
+	drain_ringbuf(dev);
+
+	misc_deregister(&dev->misc);
+
+	/* Remove from list. */
+	list_del(&dev->list_field);
+
+#ifdef CONFIG_DEBUG_FS
+	if (dev->debugfs_device_dir != NULL)
+		debugfs_remove_recursive(dev->debugfs_device_dir);
+#endif
+
+	mutex_unlock(&dev->mutex);
+	shmchr_put(dev);
+	return 0;
+}
+
+static void cfshm_remove(struct shm_dev *shm)
+{
+	int err;
+
+	pr_devel("unregister pdev:%s chr=%s shm=%p\n",
+			dev_name(&shm->dev),
+			shm->cfg.name, shm);
+
+	err = chrdev_remove(shm->driver_data);
+	if (err)
+		pr_debug("removing char-dev:%s failed.%d\n",
+					shm->cfg.name, err);
+
+	shm->ipc_rx_cb = NULL;
+	shm->ipc_tx_release_cb = NULL;
+	shm->open_cb = NULL;
+	shm->close_cb = NULL;
+	shm->driver_data = NULL;
+}
+
+static struct shm_driver cfshm_drv = {
+	.mode = SHM_STREAM_MODE,
+	.probe = cfshm_probe,
+	.remove = cfshm_remove,
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+
+static int __init shmchr_chrinit_module(void)
+{
+	int err;
+	pr_devel("shm init\n");
+	spin_lock_init(&list_lock);
+
+	/* Register shm driver. */
+	err = modem_shm_register_driver(&cfshm_drv);
+	if (err) {
+		printk(KERN_ERR "Could not register SHM driver: %d.\n",
+			err);
+		goto err_dev_register;
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	debugfsdir = debugfs_create_dir("modem_shm_chr", NULL);
+#endif
+
+ err_dev_register:
+	return err;
+
+}
+
+static void __exit shmchr_chrexit_module(void)
+{
+	int result;
+	struct shmchr_char_dev *dev = NULL;
+
+	/* Unregister shm driver. */
+	modem_shm_unregister_driver(&cfshm_drv);
+
+	do {
+		/* Remove any device (the first in the list). */
+		dev = find_device(-1, NULL, 0);
+		result = chrdev_remove(dev);
+	} while (result == 0);
+
+#ifdef CONFIG_DEBUG_FS
+	if (debugfsdir != NULL)
+		debugfs_remove_recursive(debugfsdir);
+#endif
+
+}
+
+module_init(shmchr_chrinit_module);
+module_exit(shmchr_chrexit_module);
diff --git a/drivers/modem_shm/shm_dev.c b/drivers/modem_shm/shm_dev.c
new file mode 100644
index 0000000..e1a77eb
--- /dev/null
+++ b/drivers/modem_shm/shm_dev.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/firmware.h>
+#include <linux/c2c_genio.h>
+#include <linux/modem_shm/shm_dev.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sjur Brændland <sjur.brandeland@stericsson.com>");
+
+static int shm_inactivity_timeout = 1000;
+module_param(shm_inactivity_timeout, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(shm_inactivity_timeout, "Inactivity timeout, ms.");
+
+struct shm_parent {
+	struct device dev;
+	bool ready_for_ipc;
+	bool ready_for_caif;
+	spinlock_t timer_lock;
+	int inactivity_timeout;
+	struct timer_list inactivity_timer;
+	bool power_on;
+};
+
+struct shm_parent *parent_dev;
+
+#define mdev_dbg(dev, fmt, arg...) dev_dbg(&dev->dev, pr_fmt(fmt), ##arg)
+#define mdev_vdbg(dev, fmt, arg...) dev_vdbg(&dev->dev, pr_fmt(fmt), ##arg)
+
+static void inactivity_tout(unsigned long arg)
+{
+	unsigned long flags;
+	pr_devel("enter\n");
+	spin_lock_irqsave(&parent_dev->timer_lock, flags);
+	/*
+	 * This is paranoia, but if timer is reactivated
+	 * before this tout function is scheduled,
+	 * we just ignore this timeout.
+	 */
+	if (timer_pending(&parent_dev->inactivity_timer))
+		goto out;
+
+	if (parent_dev->power_on) {
+		pr_devel("genio power req(off)\n");
+		genio_power_req(false);
+		parent_dev->power_on = false;
+	}
+out:
+	spin_unlock_irqrestore(&parent_dev->timer_lock, flags);
+}
+
+static void activity(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&parent_dev->timer_lock, flags);
+	if (!parent_dev->power_on) {
+		pr_devel("genio power req(on)\n");
+		genio_power_req(true);
+		parent_dev->power_on = true;
+	}
+	mod_timer(&parent_dev->inactivity_timer,
+			jiffies + parent_dev->inactivity_timeout);
+	spin_unlock_irqrestore(&parent_dev->timer_lock, flags);
+}
+
+static void reset_activity_tout(void)
+{
+	unsigned long flags;
+	pr_devel("enter\n");
+	spin_lock_irqsave(&parent_dev->timer_lock, flags);
+	if (parent_dev->power_on) {
+		genio_power_req(false);
+		parent_dev->power_on = false;
+	}
+	del_timer_sync(&parent_dev->inactivity_timer);
+	spin_unlock_irqrestore(&parent_dev->timer_lock, flags);
+}
+
+static int shmdev_ipc_tx(struct shm_dev *dev)
+{
+	mdev_vdbg(dev, "call genio_set_bit(%d)\n", dev->cfg.tx.xfer_bit);
+	activity();
+	return genio_set_bit(dev->cfg.tx.xfer_bit);
+}
+
+static int shmdev_ipc_rx_release(struct shm_dev *dev, bool more)
+{
+	mdev_vdbg(dev, "call genio_set_bit(%d)\n", dev->cfg.tx.xfer_bit);
+	activity();
+	return genio_set_bit(dev->cfg.rx.xfer_done_bit);
+}
+
+static int do_open(struct shm_dev *dev)
+{
+	int err;
+
+	err = dev->open_cb(dev->driver_data);
+	if (err < 0) {
+		mdev_dbg(dev, "Error - open_cb failed\n");
+
+		/* Make sure ring-buffer is empty i RX and TX direction */
+		*dev->cfg.rx.read = *dev->cfg.rx.write;
+		*dev->cfg.tx.write = *dev->cfg.tx.read;
+		*dev->cfg.tx.state = cpu_to_le32(SHM_CLOSED);
+		mdev_vdbg(dev, "set state = SHM_DEV_CLOSED\n");
+		dev->state = SHM_DEV_CLOSED;
+		return err;
+	}
+
+	/* Check is we already have any data in the pipe */
+	if (*dev->cfg.rx.write != *dev->cfg.rx.read) {
+		mdev_vdbg(dev, "Received data during opening\n");
+		dev->ipc_rx_cb(dev->driver_data);
+	}
+
+	return err;
+}
+
+static void genio_rx_cb(void *data)
+{
+	struct shm_dev *dev = data;
+
+	if (likely(dev->state == SHM_DEV_OPEN)) {
+		if (unlikely(!parent_dev->ready_for_ipc)) {
+			mdev_vdbg(dev, "ready_for_ipc is not yet set\n");
+			return;
+		}
+
+		if (dev->ipc_rx_cb) {
+			int err = dev->ipc_rx_cb(dev->driver_data);
+			if (unlikely(err < 0))
+				goto remote_close;
+		}
+
+	} else if (*dev->cfg.rx.state == cpu_to_le32(SHM_OPEN)) {
+		dev->state = SHM_DEV_OPEN;
+		if (!parent_dev->ready_for_ipc) {
+			mdev_vdbg(dev, "ready_for_ipc is not yet set\n");
+			return;
+		}
+		if (do_open(dev) < 0)
+			goto open_fail;
+	}
+	return;
+open_fail:
+	/* Make sure ring-buffer is empty i RX and TX direction */
+	*dev->cfg.rx.read = *dev->cfg.rx.write;
+	*dev->cfg.tx.write = *dev->cfg.tx.read;
+remote_close:
+	*dev->cfg.tx.state = cpu_to_le32(SHM_CLOSED);
+	dev->state = SHM_DEV_CLOSED;
+	dev->close_cb(dev->driver_data);
+}
+
+static void genio_tx_release_cb(void *data)
+{
+	struct shm_dev *dev = data;
+
+	if (!parent_dev->ready_for_ipc) {
+		mdev_vdbg(dev, "not ready_for_ipc\n");
+		return;
+	}
+	if (dev->ipc_tx_release_cb)
+		dev->ipc_tx_release_cb(dev->driver_data);
+}
+
+struct shm_xgroup {
+	bool prohibit;
+	u32 group;
+};
+
+static void check_exclgroup(struct shm_dev *dev, void *data)
+{
+	struct shm_xgroup *x = data;
+	if (dev->state == SHM_DEV_OPEN &&
+		dev->cfg.excl_group != x->group) {
+		x->prohibit = true;
+		mdev_dbg(dev, "Exclusive group "
+				"prohibits device open\n");
+	}
+}
+
+static int shmdev_open(struct shm_dev *dev)
+{
+	int err = -EINVAL;
+	struct shm_xgroup x = {
+		.prohibit = false,
+		.group = dev->cfg.excl_group
+	};
+
+
+	if (WARN_ON(dev->ipc_rx_cb == NULL) ||
+			WARN_ON(dev->ipc_tx_release_cb == NULL) ||
+			WARN_ON(dev->open_cb == NULL) ||
+			WARN_ON(dev->close_cb == NULL))
+		goto err;
+
+	modem_shm_foreach_dev(check_exclgroup, &x);
+	if (x.prohibit) {
+		mdev_dbg(dev, "Exclusive group prohibits device open\n");
+		err = -EPERM;
+		goto err;
+	}
+
+	mdev_vdbg(dev, "call genio_subscribe(%d)\n", dev->cfg.rx.xfer_bit);
+	err = genio_subscribe(dev->cfg.rx.xfer_bit, genio_rx_cb, dev);
+	if (err)
+		goto err;
+
+	mdev_vdbg(dev, "call genio_subscribe(%d)\n", dev->cfg.tx.xfer_done_bit);
+	err = genio_subscribe(dev->cfg.tx.xfer_done_bit,
+			genio_tx_release_cb, dev);
+	if (err)
+		goto err;
+
+	/* Indicate that our side is open and ready for action */
+	*dev->cfg.rx.read = *dev->cfg.rx.write;
+	*dev->cfg.tx.write = *dev->cfg.tx.read;
+	*dev->cfg.tx.state = cpu_to_le32(SHM_OPEN);
+
+	if (parent_dev->ready_for_ipc)
+		err = shmdev_ipc_tx(dev);
+
+	if (err < 0) {
+		mdev_dbg(dev, "can't update geno\n");
+		goto err;
+	}
+	/* If other side is ready as well we're ready to role */
+	if (*dev->cfg.rx.state == cpu_to_le32(SHM_OPEN) &&
+			parent_dev->ready_for_ipc) {
+
+		if (do_open(dev) < 0)
+			goto err;
+		dev->state = SHM_DEV_OPEN;
+	}
+
+	return 0;
+err:
+	*dev->cfg.rx.read = *dev->cfg.rx.write;
+	*dev->cfg.tx.write = *dev->cfg.tx.read;
+	*dev->cfg.tx.state = cpu_to_le32(SHM_CLOSED);
+	return err;
+}
+
+static void shmdev_close(struct shm_dev *dev)
+{
+	dev->state = SHM_DEV_CLOSED;
+	*dev->cfg.rx.read = *dev->cfg.rx.write;
+	*dev->cfg.tx.state = cpu_to_le32(SHM_CLOSED);
+	shmdev_ipc_tx(dev);
+	if (dev->close_cb)
+		dev->close_cb(dev->driver_data);
+
+	mdev_vdbg(dev, "call genio_unsubscribe(%d)\n", dev->cfg.rx.xfer_bit);
+	genio_unsubscribe(dev->cfg.rx.xfer_bit);
+	mdev_vdbg(dev, "call genio_unsubscribe(%d)\n",
+			dev->cfg.tx.xfer_done_bit);
+	genio_unsubscribe(dev->cfg.tx.xfer_done_bit);
+}
+
+static void shmdev_release(struct device *dev)
+{
+	struct shm_dev *shm = container_of(dev, struct shm_dev, dev);
+	kfree(shm);
+}
+
+int modem_shm_register_devices(struct shm_channel *channel[], int channels)
+{
+
+	int i, err;
+	struct shm_dev *dev;
+
+	for (i = 0; i < channels; i++) {
+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+		if (dev == NULL)
+			return -ENOMEM;
+		dev_set_name(&dev->dev, "shm%u", i);
+		dev->dev.release = shmdev_release;
+
+		dev->state = SHM_DEV_CLOSED;
+		dev->open = shmdev_open;
+		dev->close = shmdev_close;
+		dev->ipc_rx_release = shmdev_ipc_rx_release;
+		dev->ipc_tx = shmdev_ipc_tx;
+		mdev_vdbg(dev, "register SHM device %s\n",
+				dev_name(&dev->dev));
+		dev->dev.parent = &parent_dev->dev;
+		dev->cfg = *channel[i];
+
+		err = modem_shm_register_device(dev);
+		if (err) {
+			mdev_dbg(dev, "registration failed (%d)\n", err);
+			return err;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(modem_shm_register_devices);
+
+/* sysfs: ipc_ready file */
+static ssize_t caif_ready_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", parent_dev->ready_for_caif);
+}
+
+static DEVICE_ATTR(caif_ready, S_IRUSR | S_IRUGO, caif_ready_show, NULL);
+
+/* sysfs: notification on change of caif_ready to user space */
+void shm_caif_ready(void)
+{
+	sysfs_notify(&parent_dev->dev.kobj, NULL,
+			dev_attr_caif_ready.attr.name);
+}
+
+/* sysfs: ipc_ready file */
+static ssize_t ipc_ready_show(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "%d\n", parent_dev->ready_for_ipc);
+}
+
+static DEVICE_ATTR(ipc_ready, S_IRUSR | S_IRUGO, ipc_ready_show, NULL);
+
+/* sysfs: notification on change of ipc_ready to user space */
+void shm_ipc_ready(void)
+{
+	sysfs_notify(&parent_dev->dev.kobj, NULL, dev_attr_ipc_ready.attr.name);
+}
+
+static void genio_caif_ready_cb(bool ready)
+{
+	pr_devel("enter\n");
+	/* Set global variable ready_for_caif true */
+	if (parent_dev->ready_for_caif != ready) {
+		parent_dev->ready_for_caif = ready;
+		shm_caif_ready();
+	}
+}
+
+static void genio_errhandler(int errno)
+{
+	/* Fake CAIF_READY low to trigger modem restart */
+	pr_warn("Driver reported error:%d\n", errno);
+	parent_dev->ready_for_caif = 0;
+	shm_caif_ready();
+}
+
+struct shm_bits {
+	u32 setter;
+	u32 getter;
+};
+
+static void collect_bits(struct shm_dev *dev, void *data)
+{
+	struct shm_bits *bits = data;
+	bits->setter |= 1 << dev->cfg.tx.xfer_bit;
+	bits->setter |= 1 << dev->cfg.rx.xfer_done_bit;
+	bits->getter |= 1 << dev->cfg.rx.xfer_bit;
+	bits->getter |= 1 << dev->cfg.tx.xfer_done_bit;
+}
+
+static void handle_open(struct shm_dev *dev, void *data)
+{
+		if (dev->cfg.rx.state != NULL && dev->cfg.tx.state != NULL &&
+				*dev->cfg.rx.state == cpu_to_le32(SHM_OPEN) &&
+				*dev->cfg.tx.state == cpu_to_le32(SHM_OPEN)) {
+			dev->state = SHM_DEV_OPEN;
+			do_open(dev);
+		}
+}
+
+void genio_ipc_ready_cb(void)
+{
+	int err;
+	struct shm_bits bits = {0, 0};
+
+	pr_devel("enter\n");
+	/* Set global variable ready_for_ipc true */
+#ifdef DEBUG
+	/*
+	 * In real life ready_for_ipc doesn't change, but it's
+	 * convenient for testing.
+	 */
+	parent_dev->ready_for_ipc = !parent_dev->ready_for_ipc;
+#else
+	parent_dev->ready_for_ipc = true;
+#endif
+
+	shm_ipc_ready();
+
+	genio_register_errhandler(genio_errhandler);
+
+	pr_devel("call genio_subscribe_caif_ready()\n");
+	err = genio_subscribe_caif_ready(genio_caif_ready_cb);
+	if (err < 0)
+		pr_debug("genio_subscribe_caif_ready failed:%d\n", err);
+
+	/* Collect the bit-mask for GENIO bits */
+	modem_shm_foreach_dev(collect_bits, &bits);
+	pr_devel("call genio_bit_alloc(%x,%x)\n", bits.setter, bits.getter);
+	err = genio_bit_alloc(bits.setter, bits.getter);
+	if (err < 0)
+		pr_debug("genio_bit_alloc failed:%d\n", err);
+	modem_shm_foreach_dev(handle_open, NULL);
+}
+EXPORT_SYMBOL(genio_ipc_ready_cb);
+
+int modem_shm_request_firmware(void *context, struct module *mod,
+		const char *img_name,
+		void (*cb)(const struct firmware *, void *))
+{
+	pr_debug("firmware request\n");
+	return request_firmware_nowait(mod,
+			FW_ACTION_NOHOTPLUG,
+			img_name,
+			&parent_dev->dev,
+			GFP_KERNEL,
+			context,
+			cb);
+}
+EXPORT_SYMBOL(modem_shm_request_firmware);
+
+static void parent_release(struct device *dev)
+{
+	struct shm_parent *parent = container_of(dev, struct shm_parent, dev);
+	WARN_ON(parent_dev != parent);
+	kfree(parent);
+	parent_dev = NULL;
+}
+
+static int __init shm_init(void)
+{
+	int err;
+
+	pr_devel("Initializing\n");
+
+	parent_dev = kzalloc(sizeof(*parent_dev), GFP_KERNEL);
+	if (parent_dev  == NULL)
+		return -ENOMEM;
+
+	dev_set_name(&parent_dev->dev, "modem_shm");
+	parent_dev->dev.release = parent_release;
+
+	/* Pre-calculate inactivity timeout. */
+	if (shm_inactivity_timeout != -1) {
+		parent_dev->inactivity_timeout =
+				shm_inactivity_timeout * HZ / 1000;
+		if (parent_dev->inactivity_timeout == 0)
+			parent_dev->inactivity_timeout = 1;
+		else if (parent_dev->inactivity_timeout > NEXT_TIMER_MAX_DELTA)
+			parent_dev->inactivity_timeout = NEXT_TIMER_MAX_DELTA;
+	} else
+		parent_dev->inactivity_timeout = NEXT_TIMER_MAX_DELTA;
+
+	spin_lock_init(&parent_dev->timer_lock);
+	init_timer(&parent_dev->inactivity_timer);
+	parent_dev->inactivity_timer.data = 0L;
+	parent_dev->inactivity_timer.function = inactivity_tout;
+
+	err = device_register(&parent_dev->dev);
+	if (err)
+		goto err;
+
+	err = device_create_file(&parent_dev->dev, &dev_attr_ipc_ready);
+	if (err)
+		goto err_unreg;
+	err = device_create_file(&parent_dev->dev, &dev_attr_caif_ready);
+	if (err)
+		goto err_unreg;
+
+	return err;
+err_unreg:
+	pr_debug("initialization failed\n");
+	device_unregister(&parent_dev->dev);
+err:
+	return err;
+}
+
+static void handle_close(struct shm_dev *dev, void *data)
+{
+	if (dev->close_cb)
+		dev->close_cb(dev->driver_data);
+}
+
+void close_devices(void)
+{
+	modem_shm_foreach_dev(handle_close, NULL);
+}
+
+static void handle_reset(struct shm_dev *dev, void *data)
+{
+	if (dev->close_cb)
+		dev->close_cb(dev->driver_data);
+	modem_shm_unregister_device(dev);
+}
+
+void modem_shm_reset(void)
+{
+	parent_dev->ready_for_ipc = false;
+	parent_dev->ready_for_caif = false;
+	modem_shm_foreach_dev(handle_reset, NULL);
+	reset_activity_tout();
+	genio_reset();
+}
+EXPORT_SYMBOL(modem_shm_reset);
+
+static void __exit shm_exit(void)
+{
+	modem_shm_reset();
+	device_unregister(&parent_dev->dev);
+	genio_unsubscribe(READY_FOR_IPC_BIT);
+	genio_unsubscribe(READY_FOR_CAIF_BIT);
+}
+
+module_init(shm_init);
+module_exit(shm_exit);
diff --git a/drivers/modem_shm/shm_ipctoc.h b/drivers/modem_shm/shm_ipctoc.h
new file mode 100644
index 0000000..1a9b072
--- /dev/null
+++ b/drivers/modem_shm/shm_ipctoc.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef SHM_TOC
+#define SHM_TOC
+
+/**
+ * DOC: SHM Shared Memory Layout
+ *
+ * SHM defines a set of structures describing the memory layout used
+ * for the Shared Memory IPC. In short &toc_entry points out &ipc_toc,
+ * which points out the &shm_ipctoc_channel. &shm_ipctoc_channel defines
+ * the channels used to communicate between host and external device (modem).
+ *
+ *  &shm_ipctoc_channel can be used in packet-mode or stream-mode,
+ *  and points out &shm_bufidx holding information about cirular
+ *  buffers, andtheir read/write indices etc.
+ */
+
+struct _shm_offsets {
+	__le32 tx;
+	__le32 rx;
+};
+
+/**
+ * struct shm_ipctoc - Table Of Content definition for IPC.
+ *
+ * @subver:	Sub version of the TOC header.
+ * @version:	Main version of the TOC header.
+ * @magic:	Magic shall always be set to Ascii coded string "TC" (2 bytes)
+ * @channel_offsets: Offset to both rx and tx direction must be set.
+ *			The array must be terminated by a zero value.
+ *
+ * This struct is stored at the start of the External Shared memory, and
+ * serves as a extended table of contents defining the channel configurations
+ * for the external shared memory protocol between a modem and host.
+ *
+ * This extended table of content (ipctoc) is written to a predefine memory
+ * location and the modem will read this ipctoc during start-up and use this
+ * for setting up the IPC channels and it's buffers.
+ *
+ */
+
+struct shm_ipctoc {
+	__u8 subver;
+	__u8 version;
+	__u8 magic[2];
+	struct _shm_offsets channel_offsets[8];
+};
+
+#define SHM_IPCTOC_MAGIC1 'T'
+#define SHM_IPCTOC_MAGIC2 'C'
+
+/**
+ * struct shm_ipctoc_channel - Channel descriptor for External Shared memory.
+ *
+ * @offset: Relative address to channel data area.
+ * @size: Total size of a SHM channel area partition.
+ * @mode: Mode of channel: Packet mode=1, Stream mode (shm_channel_mode = 2).
+ * @buffers: Number of buffers for the channel.
+ * @ipc: Offset to IPC message location (of type struct shm_bufidx).
+ * @read_bit: GENI/O bit used to indicate update of the read pointer for
+ *	this channel (at offset ipc).
+ * @write_bit: GENI/O bit used to indicate update of the write pointer for
+ *	this channel (at offset ipc).
+ * @alignment: Protocol specific options for the protocol,
+ *	e.g. packet alignment.
+ * @packets: Maximum Number of packets in a buffer (packet mode).
+ * @mtu: Maximum Transfer Unit for packets in a buffer (packet mode).
+ *
+ * This struct defines the channel configuration for a single direction.
+ *
+ * This structure is pointed out by the &shm_toc and is written by
+ * host during start-up and read by modem at firmware boot.
+ *
+ */
+
+struct shm_ipctoc_channel {
+	__le32 offset;
+	__le32 size;
+	__u8 mode;
+/* private: */
+	__u8 unused[3];
+/* public: */
+	__le32 buffers;
+	__le32 ipc;
+	__le16 read_bit;
+	__le16 write_bit;
+	__u8 alignment;
+	__u8 packets;
+	__u16 mtu;
+};
+
+/**
+ * struct shm_bufidx - Indices's for a uni-directional shm channel.
+ *
+ * @read_index: Specify the read index for a channel. This field can
+ *	have value in range of [0.. shm_ipctoc_channel.buffers -1].
+ *	In stream mode - this is the read index in the ringbuffer.
+ *	In packet mode - this index will at any time refer to the next
+ *	buffer available for read.
+ *
+ * @write_index: Specify the write index for a channel.
+ *	This field can have value in range of [0.. buffers -1].
+ *	In stream mode - this is the write index in the ringbuffer.
+ *	In packet mode - this index will at any time refer to the next
+ *	buffer available for write.
+ *
+ * @size: The actual number of bytes for a buffer at each index.
+ *	  This array has shm_ipctoc_channel.buffers slots, one for each buffer.
+ *	  The size is updated every time data is written to the buffer.
+ *
+ * @state: The state of the channel, 0 - Closed, 1 - Open
+ *
+ *
+ * This structure contains data for the ring-buffer used in packet and stream
+ * mode, for the external shared memory protocol.
+ * Note that the read_buf_index and the write_buf_index
+ * refer to two different channels. So for a ring buffer used to communicate
+ * from modem, the modem will update the write_buf_index while Linux host
+ * will update read_buf_index.
+ */
+struct shm_bufidx {
+	__le32 state;
+	__le32 read_index;
+	__le32 write_index;
+	__le32 size[0];
+};
+
+/**
+ * struct toc_entry - Points out the boot imiages
+ *
+ * @start: Offset counting from start of memory area to the image data.
+ * @size:  Size of the images in bytes.
+ * @flags: Use 0 if no flags are in use.
+ * @entry: Where to jump to start exeuting. Only applicable
+ *		when using SDRAM. Set to 0xffffffff if unused.
+ * @load_addr: Location in SDRAM to move image. Set to 0xffffffff if
+ *		not applicable.
+ * @name: Name of image.
+ */
+struct toc_entry {
+	__le32 start;
+	__le32 size;
+	__le32 flags;
+	__le32 entry_point;
+	__le32 load_addr;
+	char name[12];
+};
+
+#endif
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 1be6218..58c6020 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -304,9 +304,6 @@ config MTD_OOPS
 	  buffer in a flash partition where it can be read back at some
 	  later point.
 
-	  To use, add console=ttyMTDx to the kernel command line,
-	  where x is the MTD device number to use.
-
 config MTD_SWAP
 	tristate "Swap on MTD device support"
 	depends on MTD && SWAP
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index e1e122f..8663f50 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -87,7 +87,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private **
 
 static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
 		     size_t *retlen, void **virt, resource_size_t *phys);
-static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
+static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
 
 static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
@@ -262,9 +262,9 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd)
 static void fixup_use_point(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
-	if (!mtd->point && map_is_linear(map)) {
-		mtd->point   = cfi_intelext_point;
-		mtd->unpoint = cfi_intelext_unpoint;
+	if (!mtd->_point && map_is_linear(map)) {
+		mtd->_point   = cfi_intelext_point;
+		mtd->_unpoint = cfi_intelext_unpoint;
 	}
 }
 
@@ -274,8 +274,8 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
 	struct cfi_private *cfi = map->fldrv_priv;
 	if (cfi->cfiq->BufWriteTimeoutTyp) {
 		printk(KERN_INFO "Using buffer write method\n" );
-		mtd->write = cfi_intelext_write_buffers;
-		mtd->writev = cfi_intelext_writev;
+		mtd->_write = cfi_intelext_write_buffers;
+		mtd->_writev = cfi_intelext_writev;
 	}
 }
 
@@ -443,15 +443,15 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
 	mtd->type = MTD_NORFLASH;
 
 	/* Fill in the default mtd operations */
-	mtd->erase   = cfi_intelext_erase_varsize;
-	mtd->read    = cfi_intelext_read;
-	mtd->write   = cfi_intelext_write_words;
-	mtd->sync    = cfi_intelext_sync;
-	mtd->lock    = cfi_intelext_lock;
-	mtd->unlock  = cfi_intelext_unlock;
-	mtd->is_locked = cfi_intelext_is_locked;
-	mtd->suspend = cfi_intelext_suspend;
-	mtd->resume  = cfi_intelext_resume;
+	mtd->_erase   = cfi_intelext_erase_varsize;
+	mtd->_read    = cfi_intelext_read;
+	mtd->_write   = cfi_intelext_write_words;
+	mtd->_sync    = cfi_intelext_sync;
+	mtd->_lock    = cfi_intelext_lock;
+	mtd->_unlock  = cfi_intelext_unlock;
+	mtd->_is_locked = cfi_intelext_is_locked;
+	mtd->_suspend = cfi_intelext_suspend;
+	mtd->_resume  = cfi_intelext_resume;
 	mtd->flags   = MTD_CAP_NORFLASH;
 	mtd->name    = map->name;
 	mtd->writesize = 1;
@@ -600,12 +600,12 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
 	}
 
 #ifdef CONFIG_MTD_OTP
-	mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
-	mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
-	mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg;
-	mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
-	mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info;
-	mtd->get_user_prot_info = cfi_intelext_get_user_prot_info;
+	mtd->_read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
+	mtd->_read_user_prot_reg = cfi_intelext_read_user_prot_reg;
+	mtd->_write_user_prot_reg = cfi_intelext_write_user_prot_reg;
+	mtd->_lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
+	mtd->_get_fact_prot_info = cfi_intelext_get_fact_prot_info;
+	mtd->_get_user_prot_info = cfi_intelext_get_user_prot_info;
 #endif
 
 	/* This function has the potential to distort the reality
@@ -1324,7 +1324,7 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
 	int chipnum;
 	int ret = 0;
 
-	if (!map->virt || (from + len > mtd->size))
+	if (!map->virt)
 		return -EINVAL;
 
 	/* Now lock the chip(s) to POINT state */
@@ -1334,7 +1334,6 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
 	ofs = from - (chipnum << cfi->chipshift);
 
 	*virt = map->virt + cfi->chips[chipnum].start + ofs;
-	*retlen = 0;
 	if (phys)
 		*phys = map->phys + cfi->chips[chipnum].start + ofs;
 
@@ -1369,12 +1368,12 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
 	return 0;
 }
 
-static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long ofs;
-	int chipnum;
+	int chipnum, err = 0;
 
 	/* Now unlock the chip(s) POINT state */
 
@@ -1382,7 +1381,7 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 	chipnum = (from >> cfi->chipshift);
 	ofs = from - (chipnum <<  cfi->chipshift);
 
-	while (len) {
+	while (len && !err) {
 		unsigned long thislen;
 		struct flchip *chip;
 
@@ -1400,8 +1399,10 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 			chip->ref_point_counter--;
 			if(chip->ref_point_counter == 0)
 				chip->state = FL_READY;
-		} else
-			printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
+		} else {
+			printk(KERN_ERR "%s: Error: unpoint called on non pointed region\n", map->name);
+			err = -EINVAL;
+		}
 
 		put_chip(map, chip, chip->start);
 		mutex_unlock(&chip->mutex);
@@ -1410,6 +1411,8 @@ static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 		ofs = 0;
 		chipnum++;
 	}
+
+	return err;
 }
 
 static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
@@ -1456,8 +1459,6 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
 	chipnum = (from >> cfi->chipshift);
 	ofs = from - (chipnum <<  cfi->chipshift);
 
-	*retlen = 0;
-
 	while (len) {
 		unsigned long thislen;
 
@@ -1565,10 +1566,6 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
 	int chipnum;
 	unsigned long ofs;
 
-	*retlen = 0;
-	if (!len)
-		return 0;
-
 	chipnum = to >> cfi->chipshift;
 	ofs = to  - (chipnum << cfi->chipshift);
 
@@ -1813,7 +1810,6 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
 	for (i = 0; i < count; i++)
 		len += vecs[i].iov_len;
 
-	*retlen = 0;
 	if (!len)
 		return 0;
 
@@ -2526,12 +2522,10 @@ static void cfi_intelext_restore_locks(struct mtd_info *mtd)
 		if (!region->lockmap)
 			continue;
 
-		for (block = 0; block < region->numblocks; block++) {
+		for_each_clear_bit(block, region->lockmap, region->numblocks) {
 			len = region->erasesize;
 			adr = region->offset + block * len;
-
-			if (!test_bit(block, region->lockmap))
-				cfi_intelext_unlock(mtd, adr, len);
+			cfi_intelext_unlock(mtd, adr, len);
 		}
 	}
 }
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 8d70895..c1d4624 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -59,6 +59,9 @@ static void cfi_amdstd_resume (struct mtd_info *);
 static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
 static int cfi_amdstd_secsi_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 
+static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
+				  size_t *retlen, const u_char *buf);
+
 static void cfi_amdstd_destroy(struct mtd_info *);
 
 struct mtd_info *cfi_cmdset_0002(struct map_info *, int);
@@ -189,7 +192,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd)
 	struct cfi_private *cfi = map->fldrv_priv;
 	if (cfi->cfiq->BufWriteTimeoutTyp) {
 		pr_debug("Using buffer write method\n" );
-		mtd->write = cfi_amdstd_write_buffers;
+		mtd->_write = cfi_amdstd_write_buffers;
 	}
 }
 
@@ -228,8 +231,8 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd)
 static void fixup_use_secsi(struct mtd_info *mtd)
 {
 	/* Setup for chips with a secsi area */
-	mtd->read_user_prot_reg = cfi_amdstd_secsi_read;
-	mtd->read_fact_prot_reg = cfi_amdstd_secsi_read;
+	mtd->_read_user_prot_reg = cfi_amdstd_secsi_read;
+	mtd->_read_fact_prot_reg = cfi_amdstd_secsi_read;
 }
 
 static void fixup_use_erase_chip(struct mtd_info *mtd)
@@ -238,7 +241,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd)
 	struct cfi_private *cfi = map->fldrv_priv;
 	if ((cfi->cfiq->NumEraseRegions == 1) &&
 		((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
-		mtd->erase = cfi_amdstd_erase_chip;
+		mtd->_erase = cfi_amdstd_erase_chip;
 	}
 
 }
@@ -249,8 +252,8 @@ static void fixup_use_erase_chip(struct mtd_info *mtd)
  */
 static void fixup_use_atmel_lock(struct mtd_info *mtd)
 {
-	mtd->lock = cfi_atmel_lock;
-	mtd->unlock = cfi_atmel_unlock;
+	mtd->_lock = cfi_atmel_lock;
+	mtd->_unlock = cfi_atmel_unlock;
 	mtd->flags |= MTD_POWERUP_LOCK;
 }
 
@@ -429,12 +432,12 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 	mtd->type = MTD_NORFLASH;
 
 	/* Fill in the default mtd operations */
-	mtd->erase   = cfi_amdstd_erase_varsize;
-	mtd->write   = cfi_amdstd_write_words;
-	mtd->read    = cfi_amdstd_read;
-	mtd->sync    = cfi_amdstd_sync;
-	mtd->suspend = cfi_amdstd_suspend;
-	mtd->resume  = cfi_amdstd_resume;
+	mtd->_erase   = cfi_amdstd_erase_varsize;
+	mtd->_write   = cfi_amdstd_write_words;
+	mtd->_read    = cfi_amdstd_read;
+	mtd->_sync    = cfi_amdstd_sync;
+	mtd->_suspend = cfi_amdstd_suspend;
+	mtd->_resume  = cfi_amdstd_resume;
 	mtd->flags   = MTD_CAP_NORFLASH;
 	mtd->name    = map->name;
 	mtd->writesize = 1;
@@ -443,6 +446,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 	pr_debug("MTD %s(): write buffer size %d\n", __func__,
 			mtd->writebufsize);
 
+	mtd->_panic_write = cfi_amdstd_panic_write;
 	mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;
 
 	if (cfi->cfi_mode==CFI_MODE_CFI){
@@ -1013,13 +1017,9 @@ static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_
 	int ret = 0;
 
 	/* ofs: offset within the first chip that the first read should start */
-
 	chipnum = (from >> cfi->chipshift);
 	ofs = from - (chipnum <<  cfi->chipshift);
 
-
-	*retlen = 0;
-
 	while (len) {
 		unsigned long thislen;
 
@@ -1097,16 +1097,11 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len,
 	int chipnum;
 	int ret = 0;
 
-
 	/* ofs: offset within the first chip that the first read should start */
-
 	/* 8 secsi bytes per chip */
 	chipnum=from>>3;
 	ofs=from & 7;
 
-
-	*retlen = 0;
-
 	while (len) {
 		unsigned long thislen;
 
@@ -1251,10 +1246,6 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
 	unsigned long ofs, chipstart;
 	DECLARE_WAITQUEUE(wait, current);
 
-	*retlen = 0;
-	if (!len)
-		return 0;
-
 	chipnum = to >> cfi->chipshift;
 	ofs = to  - (chipnum << cfi->chipshift);
 	chipstart = cfi->chips[chipnum].start;
@@ -1493,10 +1484,6 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
 	int chipnum;
 	unsigned long ofs;
 
-	*retlen = 0;
-	if (!len)
-		return 0;
-
 	chipnum = to >> cfi->chipshift;
 	ofs = to  - (chipnum << cfi->chipshift);
 
@@ -1562,6 +1549,238 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
 	return 0;
 }
 
+/*
+ * Wait for the flash chip to become ready to write data
+ *
+ * This is only called during the panic_write() path. When panic_write()
+ * is called, the kernel is in the process of a panic, and will soon be
+ * dead. Therefore we don't take any locks, and attempt to get access
+ * to the chip as soon as possible.
+ */
+static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip,
+				 unsigned long adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	int retries = 10;
+	int i;
+
+	/*
+	 * If the driver thinks the chip is idle, and no toggle bits
+	 * are changing, then the chip is actually idle for sure.
+	 */
+	if (chip->state == FL_READY && chip_ready(map, adr))
+		return 0;
+
+	/*
+	 * Try several times to reset the chip and then wait for it
+	 * to become idle. The upper limit of a few milliseconds of
+	 * delay isn't a big problem: the kernel is dying anyway. It
+	 * is more important to save the messages.
+	 */
+	while (retries > 0) {
+		const unsigned long timeo = (HZ / 1000) + 1;
+
+		/* send the reset command */
+		map_write(map, CMD(0xF0), chip->start);
+
+		/* wait for the chip to become ready */
+		for (i = 0; i < jiffies_to_usecs(timeo); i++) {
+			if (chip_ready(map, adr))
+				return 0;
+
+			udelay(1);
+		}
+	}
+
+	/* the chip never became ready */
+	return -EBUSY;
+}
+
+/*
+ * Write out one word of data to a single flash chip during a kernel panic
+ *
+ * This is only called during the panic_write() path. When panic_write()
+ * is called, the kernel is in the process of a panic, and will soon be
+ * dead. Therefore we don't take any locks, and attempt to get access
+ * to the chip as soon as possible.
+ *
+ * The implementation of this routine is intentionally similar to
+ * do_write_oneword(), in order to ease code maintenance.
+ */
+static int do_panic_write_oneword(struct map_info *map, struct flchip *chip,
+				  unsigned long adr, map_word datum)
+{
+	const unsigned long uWriteTimeout = (HZ / 1000) + 1;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int retry_cnt = 0;
+	map_word oldd;
+	int ret = 0;
+	int i;
+
+	adr += chip->start;
+
+	ret = cfi_amdstd_panic_wait(map, chip, adr);
+	if (ret)
+		return ret;
+
+	pr_debug("MTD %s(): PANIC WRITE 0x%.8lx(0x%.8lx)\n",
+			__func__, adr, datum.x[0]);
+
+	/*
+	 * Check for a NOP for the case when the datum to write is already
+	 * present - it saves time and works around buggy chips that corrupt
+	 * data at other locations when 0xff is written to a location that
+	 * already contains 0xff.
+	 */
+	oldd = map_read(map, adr);
+	if (map_word_equal(map, oldd, datum)) {
+		pr_debug("MTD %s(): NOP\n", __func__);
+		goto op_done;
+	}
+
+	ENABLE_VPP(map);
+
+retry:
+	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
+	cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
+	map_write(map, datum, adr);
+
+	for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) {
+		if (chip_ready(map, adr))
+			break;
+
+		udelay(1);
+	}
+
+	if (!chip_good(map, adr, datum)) {
+		/* reset on all failures. */
+		map_write(map, CMD(0xF0), chip->start);
+		/* FIXME - should have reset delay before continuing */
+
+		if (++retry_cnt <= MAX_WORD_RETRIES)
+			goto retry;
+
+		ret = -EIO;
+	}
+
+op_done:
+	DISABLE_VPP(map);
+	return ret;
+}
+
+/*
+ * Write out some data during a kernel panic
+ *
+ * This is used by the mtdoops driver to save the dying messages from a
+ * kernel which has panic'd.
+ *
+ * This routine ignores all of the locking used throughout the rest of the
+ * driver, in order to ensure that the data gets written out no matter what
+ * state this driver (and the flash chip itself) was in when the kernel crashed.
+ *
+ * The implementation of this routine is intentionally similar to
+ * cfi_amdstd_write_words(), in order to ease code maintenance.
+ */
+static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
+				  size_t *retlen, const u_char *buf)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	unsigned long ofs, chipstart;
+	int ret = 0;
+	int chipnum;
+
+	chipnum = to >> cfi->chipshift;
+	ofs = to - (chipnum << cfi->chipshift);
+	chipstart = cfi->chips[chipnum].start;
+
+	/* If it's not bus aligned, do the first byte write */
+	if (ofs & (map_bankwidth(map) - 1)) {
+		unsigned long bus_ofs = ofs & ~(map_bankwidth(map) - 1);
+		int i = ofs - bus_ofs;
+		int n = 0;
+		map_word tmp_buf;
+
+		ret = cfi_amdstd_panic_wait(map, &cfi->chips[chipnum], bus_ofs);
+		if (ret)
+			return ret;
+
+		/* Load 'tmp_buf' with old contents of flash */
+		tmp_buf = map_read(map, bus_ofs + chipstart);
+
+		/* Number of bytes to copy from buffer */
+		n = min_t(int, len, map_bankwidth(map) - i);
+
+		tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
+
+		ret = do_panic_write_oneword(map, &cfi->chips[chipnum],
+					     bus_ofs, tmp_buf);
+		if (ret)
+			return ret;
+
+		ofs += n;
+		buf += n;
+		(*retlen) += n;
+		len -= n;
+
+		if (ofs >> cfi->chipshift) {
+			chipnum++;
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+		}
+	}
+
+	/* We are now aligned, write as much as possible */
+	while (len >= map_bankwidth(map)) {
+		map_word datum;
+
+		datum = map_word_load(map, buf);
+
+		ret = do_panic_write_oneword(map, &cfi->chips[chipnum],
+					     ofs, datum);
+		if (ret)
+			return ret;
+
+		ofs += map_bankwidth(map);
+		buf += map_bankwidth(map);
+		(*retlen) += map_bankwidth(map);
+		len -= map_bankwidth(map);
+
+		if (ofs >> cfi->chipshift) {
+			chipnum++;
+			ofs = 0;
+			if (chipnum == cfi->numchips)
+				return 0;
+
+			chipstart = cfi->chips[chipnum].start;
+		}
+	}
+
+	/* Write the trailing bytes if any */
+	if (len & (map_bankwidth(map) - 1)) {
+		map_word tmp_buf;
+
+		ret = cfi_amdstd_panic_wait(map, &cfi->chips[chipnum], ofs);
+		if (ret)
+			return ret;
+
+		tmp_buf = map_read(map, ofs + chipstart);
+
+		tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
+
+		ret = do_panic_write_oneword(map, &cfi->chips[chipnum],
+					     ofs, tmp_buf);
+		if (ret)
+			return ret;
+
+		(*retlen) += len;
+	}
+
+	return 0;
+}
+
 
 /*
  * Handle devices with one erase region, that only implement
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 85e8018..096993f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -228,15 +228,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
 		}
 
 	/* Also select the correct geometry setup too */
-	mtd->erase = cfi_staa_erase_varsize;
-	mtd->read = cfi_staa_read;
-        mtd->write = cfi_staa_write_buffers;
-	mtd->writev = cfi_staa_writev;
-	mtd->sync = cfi_staa_sync;
-	mtd->lock = cfi_staa_lock;
-	mtd->unlock = cfi_staa_unlock;
-	mtd->suspend = cfi_staa_suspend;
-	mtd->resume = cfi_staa_resume;
+	mtd->_erase = cfi_staa_erase_varsize;
+	mtd->_read = cfi_staa_read;
+	mtd->_write = cfi_staa_write_buffers;
+	mtd->_writev = cfi_staa_writev;
+	mtd->_sync = cfi_staa_sync;
+	mtd->_lock = cfi_staa_lock;
+	mtd->_unlock = cfi_staa_unlock;
+	mtd->_suspend = cfi_staa_suspend;
+	mtd->_resume = cfi_staa_resume;
 	mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE;
 	mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
 	mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
@@ -394,8 +394,6 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
 	chipnum = (from >> cfi->chipshift);
 	ofs = from - (chipnum <<  cfi->chipshift);
 
-	*retlen = 0;
-
 	while (len) {
 		unsigned long thislen;
 
@@ -617,10 +615,6 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
 	int chipnum;
 	unsigned long ofs;
 
-	*retlen = 0;
-	if (!len)
-		return 0;
-
 	chipnum = to >> cfi->chipshift;
 	ofs = to  - (chipnum << cfi->chipshift);
 
@@ -904,12 +898,6 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd,
 	int i, first;
 	struct mtd_erase_region_info *regions = mtd->eraseregions;
 
-	if (instr->addr > mtd->size)
-		return -EINVAL;
-
-	if ((instr->len + instr->addr) > mtd->size)
-		return -EINVAL;
-
 	/* Check that both start and end of the requested erase are
 	 * aligned with the erasesize at the appropriate addresses.
 	 */
@@ -1155,9 +1143,6 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	if (len & (mtd->erasesize -1))
 		return -EINVAL;
 
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
-
 	chipnum = ofs >> cfi->chipshift;
 	adr = ofs - (chipnum << cfi->chipshift);
 
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 8e46405..f992418 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -173,12 +173,6 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
 	int i, first;
 	struct mtd_erase_region_info *regions = mtd->eraseregions;
 
-	if (ofs > mtd->size)
-		return -EINVAL;
-
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
-
 	/* Check that both start and end of the requested erase are
 	 * aligned with the erasesize at the appropriate addresses.
 	 */
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index 89c6595..800b0e8 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -101,7 +101,7 @@ static void fixup_use_fwh_lock(struct mtd_info *mtd)
 {
 	printk(KERN_NOTICE "using fwh lock/unlock method\n");
 	/* Setup for the chips with the fwh lock method */
-	mtd->lock   = fwh_lock_varsize;
-	mtd->unlock = fwh_unlock_varsize;
+	mtd->_lock   = fwh_lock_varsize;
+	mtd->_unlock = fwh_unlock_varsize;
 }
 #endif /* FWH_LOCK_H */
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c
index f2b8729..f7a5bca 100644
--- a/drivers/mtd/chips/map_absent.c
+++ b/drivers/mtd/chips/map_absent.c
@@ -55,10 +55,10 @@ static struct mtd_info *map_absent_probe(struct map_info *map)
 	mtd->name 	= map->name;
 	mtd->type 	= MTD_ABSENT;
 	mtd->size 	= map->size;
-	mtd->erase 	= map_absent_erase;
-	mtd->read 	= map_absent_read;
-	mtd->write 	= map_absent_write;
-	mtd->sync 	= map_absent_sync;
+	mtd->_erase 	= map_absent_erase;
+	mtd->_read 	= map_absent_read;
+	mtd->_write 	= map_absent_write;
+	mtd->_sync 	= map_absent_sync;
 	mtd->flags 	= 0;
 	mtd->erasesize  = PAGE_SIZE;
 	mtd->writesize  = 1;
@@ -70,13 +70,11 @@ static struct mtd_info *map_absent_probe(struct map_info *map)
 
 static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 {
-	*retlen = 0;
 	return -ENODEV;
 }
 
 static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
-	*retlen = 0;
 	return -ENODEV;
 }
 
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 67640cc..991c2a1 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -64,11 +64,11 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
 	mtd->name = map->name;
 	mtd->type = MTD_RAM;
 	mtd->size = map->size;
-	mtd->erase = mapram_erase;
-	mtd->get_unmapped_area = mapram_unmapped_area;
-	mtd->read = mapram_read;
-	mtd->write = mapram_write;
-	mtd->sync = mapram_nop;
+	mtd->_erase = mapram_erase;
+	mtd->_get_unmapped_area = mapram_unmapped_area;
+	mtd->_read = mapram_read;
+	mtd->_write = mapram_write;
+	mtd->_sync = mapram_nop;
 	mtd->flags = MTD_CAP_RAM;
 	mtd->writesize = 1;
 
@@ -122,14 +122,10 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr)
 	unsigned long i;
 
 	allff = map_word_ff(map);
-
 	for (i=0; i<instr->len; i += map_bankwidth(map))
 		map_write(map, allff, instr->addr + i);
-
 	instr->state = MTD_ERASE_DONE;
-
 	mtd_erase_callback(instr);
-
 	return 0;
 }
 
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index 593f73d..47a43cf 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -41,11 +41,11 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
 	mtd->name = map->name;
 	mtd->type = MTD_ROM;
 	mtd->size = map->size;
-	mtd->get_unmapped_area = maprom_unmapped_area;
-	mtd->read = maprom_read;
-	mtd->write = maprom_write;
-	mtd->sync = maprom_nop;
-	mtd->erase = maprom_erase;
+	mtd->_get_unmapped_area = maprom_unmapped_area;
+	mtd->_read = maprom_read;
+	mtd->_write = maprom_write;
+	mtd->_sync = maprom_nop;
+	mtd->_erase = maprom_erase;
 	mtd->flags = MTD_CAP_ROM;
 	mtd->erasesize = map->size;
 	mtd->writesize = 1;
@@ -85,8 +85,7 @@ static void maprom_nop(struct mtd_info *mtd)
 
 static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 {
-	printk(KERN_NOTICE "maprom_write called\n");
-	return -EIO;
+	return -EROFS;
 }
 
 static int maprom_erase (struct mtd_info *mtd, struct erase_info *info)
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 37b05c3..98206b0 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -102,6 +102,13 @@ config M25PXX_USE_FAST_READ
 	help
 	  This option enables FAST_READ access supported by ST M25Pxx.
 
+config MTD_SPEAR_SMI
+	tristate "SPEAR MTD NOR Support through SMI controller"
+	depends on PLAT_SPEAR
+	default y
+	help
+	  This enable SNOR support on SPEAR platforms using SMI controller
+
 config MTD_SST25L
 	tristate "Support SST25L (non JEDEC) SPI Flash chips"
 	depends on SPI_MASTER
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index 56c7cd4..a4dd1d8 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MTD_LART)		+= lart.o
 obj-$(CONFIG_MTD_BLOCK2MTD)	+= block2mtd.o
 obj-$(CONFIG_MTD_DATAFLASH)	+= mtd_dataflash.o
 obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
+obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
 
 CFLAGS_docg3.o			+= -I$(src)
\ No newline at end of file
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index e7e46d1..a4a80b7 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -104,14 +104,6 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
 	int offset = from & (PAGE_SIZE-1);
 	int cpylen;
 
-	if (from > mtd->size)
-		return -EINVAL;
-	if (from + len > mtd->size)
-		len = mtd->size - from;
-
-	if (retlen)
-		*retlen = 0;
-
 	while (len) {
 		if ((offset + len) > PAGE_SIZE)
 			cpylen = PAGE_SIZE - offset;	// multiple pages
@@ -148,8 +140,6 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
 	int offset = to & ~PAGE_MASK;	// page offset
 	int cpylen;
 
-	if (retlen)
-		*retlen = 0;
 	while (len) {
 		if ((offset+len) > PAGE_SIZE)
 			cpylen = PAGE_SIZE - offset;	// multiple pages
@@ -188,13 +178,6 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
 	struct block2mtd_dev *dev = mtd->priv;
 	int err;
 
-	if (!len)
-		return 0;
-	if (to >= mtd->size)
-		return -ENOSPC;
-	if (to + len > mtd->size)
-		len = mtd->size - to;
-
 	mutex_lock(&dev->write_mutex);
 	err = _block2mtd_write(dev, buf, to, len, retlen);
 	mutex_unlock(&dev->write_mutex);
@@ -283,13 +266,14 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
 	dev->mtd.erasesize = erase_size;
 	dev->mtd.writesize = 1;
+	dev->mtd.writebufsize = PAGE_SIZE;
 	dev->mtd.type = MTD_RAM;
 	dev->mtd.flags = MTD_CAP_RAM;
-	dev->mtd.erase = block2mtd_erase;
-	dev->mtd.write = block2mtd_write;
-	dev->mtd.writev = mtd_writev;
-	dev->mtd.sync = block2mtd_sync;
-	dev->mtd.read = block2mtd_read;
+	dev->mtd._erase = block2mtd_erase;
+	dev->mtd._write = block2mtd_write;
+	dev->mtd._writev = mtd_writev;
+	dev->mtd._sync = block2mtd_sync;
+	dev->mtd._read = block2mtd_read;
 	dev->mtd.priv = dev;
 	dev->mtd.owner = THIS_MODULE;
 
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index b1cdf64..7ad7b05 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -562,14 +562,14 @@ void DoC2k_init(struct mtd_info *mtd)
 
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->writesize = 512;
+	mtd->writebufsize = mtd->writesize = 512;
 	mtd->oobsize = 16;
 	mtd->owner = THIS_MODULE;
-	mtd->erase = doc_erase;
-	mtd->read = doc_read;
-	mtd->write = doc_write;
-	mtd->read_oob = doc_read_oob;
-	mtd->write_oob = doc_write_oob;
+	mtd->_erase = doc_erase;
+	mtd->_read = doc_read;
+	mtd->_write = doc_write;
+	mtd->_read_oob = doc_read_oob;
+	mtd->_write_oob = doc_write_oob;
 	this->curfloor = -1;
 	this->curchip = -1;
 	mutex_init(&this->lock);
@@ -602,13 +602,7 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
 	int i, len256 = 0, ret=0;
 	size_t left = len;
 
-	/* Don't allow read past end of device */
-	if (from >= this->totlen)
-		return -EINVAL;
-
 	mutex_lock(&this->lock);
-
-	*retlen = 0;
 	while (left) {
 		len = left;
 
@@ -748,13 +742,7 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
 	size_t left = len;
 	int status;
 
-	/* Don't allow write past end of device */
-	if (to >= this->totlen)
-		return -EINVAL;
-
 	mutex_lock(&this->lock);
-
-	*retlen = 0;
 	while (left) {
 		len = left;
 
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 7543b98..7bff54e 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -346,14 +346,14 @@ void DoCMil_init(struct mtd_info *mtd)
 
 	/* FIXME: erase size is not always 8KiB */
 	mtd->erasesize = 0x2000;
-	mtd->writesize = 512;
+	mtd->writebufsize = mtd->writesize = 512;
 	mtd->oobsize = 16;
 	mtd->owner = THIS_MODULE;
-	mtd->erase = doc_erase;
-	mtd->read = doc_read;
-	mtd->write = doc_write;
-	mtd->read_oob = doc_read_oob;
-	mtd->write_oob = doc_write_oob;
+	mtd->_erase = doc_erase;
+	mtd->_read = doc_read;
+	mtd->_write = doc_write;
+	mtd->_read_oob = doc_read_oob;
+	mtd->_write_oob = doc_write_oob;
 	this->curfloor = -1;
 	this->curchip = -1;
 
@@ -383,10 +383,6 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
 
-	/* Don't allow read past end of device */
-	if (from >= this->totlen)
-		return -EINVAL;
-
 	/* Don't allow a single read to cross a 512-byte block boundary */
 	if (from + len > ((from | 0x1ff) + 1))
 		len = ((from | 0x1ff) + 1) - from;
@@ -494,10 +490,6 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
 	void __iomem *docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
 
-	/* Don't allow write past end of device */
-	if (to >= this->totlen)
-		return -EINVAL;
-
 #if 0
 	/* Don't allow a single write to cross a 512-byte block boundary */
 	if (to + len > ( (to | 0x1ff) + 1))
@@ -599,7 +591,6 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
 		printk("Error programming flash\n");
 		/* Error in programming
 		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
-		*retlen = 0;
 		ret = -EIO;
 	}
 	dummy = ReadDOC(docptr, LastDataRead);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 177510d..4a03d86 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -467,14 +467,14 @@ void DoCMilPlus_init(struct mtd_info *mtd)
 
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->writesize = 512;
+	mtd->writebufsize = mtd->writesize = 512;
 	mtd->oobsize = 16;
 	mtd->owner = THIS_MODULE;
-	mtd->erase = doc_erase;
-	mtd->read = doc_read;
-	mtd->write = doc_write;
-	mtd->read_oob = doc_read_oob;
-	mtd->write_oob = doc_write_oob;
+	mtd->_erase = doc_erase;
+	mtd->_read = doc_read;
+	mtd->_write = doc_write;
+	mtd->_read_oob = doc_read_oob;
+	mtd->_write_oob = doc_write_oob;
 	this->curfloor = -1;
 	this->curchip = -1;
 
@@ -581,10 +581,6 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[from >> (this->chipshift)];
 
-	/* Don't allow read past end of device */
-	if (from >= this->totlen)
-		return -EINVAL;
-
 	/* Don't allow a single read to cross a 512-byte block boundary */
 	if (from + len > ((from | 0x1ff) + 1))
 		len = ((from | 0x1ff) + 1) - from;
@@ -700,10 +696,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
 	void __iomem * docptr = this->virtadr;
 	struct Nand *mychip = &this->chips[to >> (this->chipshift)];
 
-	/* Don't allow write past end of device */
-	if (to >= this->totlen)
-		return -EINVAL;
-
 	/* Don't allow writes which aren't exactly one block (512 bytes) */
 	if ((to & 0x1ff) || (len != 0x200))
 		return -EINVAL;
@@ -800,7 +792,6 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
 		printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
 		/* Error in programming
 		   FIXME: implement Bad Block Replacement (in nftl.c ??) */
-		*retlen = 0;
 		ret = -EIO;
 	}
 	dummy = ReadDOC(docptr, Mplus_LastDataRead);
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index ad11ef0a..fc7932b 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -1817,15 +1817,15 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd)
 	mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES;
 	if (docg3->reliable == 2)
 		mtd->erasesize /= 2;
-	mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
+	mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE;
 	mtd->oobsize = DOC_LAYOUT_OOB_SIZE;
 	mtd->owner = THIS_MODULE;
-	mtd->erase = doc_erase;
-	mtd->read = doc_read;
-	mtd->write = doc_write;
-	mtd->read_oob = doc_read_oob;
-	mtd->write_oob = doc_write_oob;
-	mtd->block_isbad = doc_block_isbad;
+	mtd->_erase = doc_erase;
+	mtd->_read = doc_read;
+	mtd->_write = doc_write;
+	mtd->_read_oob = doc_read_oob;
+	mtd->_write_oob = doc_write_oob;
+	mtd->_block_isbad = doc_block_isbad;
 	mtd->ecclayout = &docg3_oobinfo;
 }
 
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index 3a11ea6..82bd00a 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -367,9 +367,6 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
    printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len);
 #endif
 
-   /* sanity checks */
-   if (instr->addr + instr->len > mtd->size) return (-EINVAL);
-
    /*
 	* check that both start and end of the requested erase are
 	* aligned with the erasesize at the appropriate addresses.
@@ -440,10 +437,6 @@ static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retle
    printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len);
 #endif
 
-   /* sanity checks */
-   if (!len) return (0);
-   if (from + len > mtd->size) return (-EINVAL);
-
    /* we always read len bytes */
    *retlen = len;
 
@@ -522,11 +515,8 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen
    printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len);
 #endif
 
-   *retlen = 0;
-
    /* sanity checks */
    if (!len) return (0);
-   if (to + len > mtd->size) return (-EINVAL);
 
    /* first, we write a 0xFF.... padded byte until we reach a dword boundary */
    if (to & (BUSWIDTH - 1))
@@ -630,14 +620,15 @@ static int __init lart_flash_init (void)
    mtd.name = module_name;
    mtd.type = MTD_NORFLASH;
    mtd.writesize = 1;
+   mtd.writebufsize = 4;
    mtd.flags = MTD_CAP_NORFLASH;
    mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
    mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
    mtd.numeraseregions = ARRAY_SIZE(erase_regions);
    mtd.eraseregions = erase_regions;
-   mtd.erase = flash_erase;
-   mtd.read = flash_read;
-   mtd.write = flash_write;
+   mtd._erase = flash_erase;
+   mtd._read = flash_read;
+   mtd._write = flash_write;
    mtd.owner = THIS_MODULE;
 
 #ifdef LART_DEBUG
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c60ddd..1924d24 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -288,9 +288,6 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
 			__func__, (long long)instr->addr,
 			(long long)instr->len);
 
-	/* sanity checks */
-	if (instr->addr + instr->len > flash->mtd.size)
-		return -EINVAL;
 	div_u64_rem(instr->len, mtd->erasesize, &rem);
 	if (rem)
 		return -EINVAL;
@@ -349,13 +346,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
 			__func__, (u32)from, len);
 
-	/* sanity checks */
-	if (!len)
-		return 0;
-
-	if (from + len > flash->mtd.size)
-		return -EINVAL;
-
 	spi_message_init(&m);
 	memset(t, 0, (sizeof t));
 
@@ -371,9 +361,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
 
-	/* Byte count starts at zero. */
-	*retlen = 0;
-
 	mutex_lock(&flash->lock);
 
 	/* Wait till previous write/erase is done. */
@@ -417,15 +404,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
 	pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
 			__func__, (u32)to, len);
 
-	*retlen = 0;
-
-	/* sanity checks */
-	if (!len)
-		return(0);
-
-	if (to + len > flash->mtd.size)
-		return -EINVAL;
-
 	spi_message_init(&m);
 	memset(t, 0, (sizeof t));
 
@@ -509,15 +487,6 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
 			__func__, (u32)to, len);
 
-	*retlen = 0;
-
-	/* sanity checks */
-	if (!len)
-		return 0;
-
-	if (to + len > flash->mtd.size)
-		return -EINVAL;
-
 	spi_message_init(&m);
 	memset(t, 0, (sizeof t));
 
@@ -908,14 +877,14 @@ static int __devinit m25p_probe(struct spi_device *spi)
 	flash->mtd.writesize = 1;
 	flash->mtd.flags = MTD_CAP_NORFLASH;
 	flash->mtd.size = info->sector_size * info->n_sectors;
-	flash->mtd.erase = m25p80_erase;
-	flash->mtd.read = m25p80_read;
+	flash->mtd._erase = m25p80_erase;
+	flash->mtd._read = m25p80_read;
 
 	/* sst flash chips use AAI word program */
 	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST)
-		flash->mtd.write = sst_write;
+		flash->mtd._write = sst_write;
 	else
-		flash->mtd.write = m25p80_write;
+		flash->mtd._write = m25p80_write;
 
 	/* prefer "small sector" erase if possible */
 	if (info->flags & SECT_4K) {
@@ -932,6 +901,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
 	ppdata.of_node = spi->dev.of_node;
 	flash->mtd.dev.parent = &spi->dev;
 	flash->page_size = info->page_size;
+	flash->mtd.writebufsize = flash->page_size;
 
 	if (info->addr_width)
 		flash->addr_width = info->addr_width;
@@ -1004,21 +974,7 @@ static struct spi_driver m25p80_driver = {
 	 */
 };
 
-
-static int __init m25p80_init(void)
-{
-	return spi_register_driver(&m25p80_driver);
-}
-
-
-static void __exit m25p80_exit(void)
-{
-	spi_unregister_driver(&m25p80_driver);
-}
-
-
-module_init(m25p80_init);
-module_exit(m25p80_exit);
+module_spi_driver(m25p80_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mike Lavender");
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 8423fb6..182849d 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -59,12 +59,8 @@ static int ms02nv_read(struct mtd_info *mtd, loff_t from,
 {
 	struct ms02nv_private *mp = mtd->priv;
 
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	memcpy(buf, mp->uaddr + from, len);
 	*retlen = len;
-
 	return 0;
 }
 
@@ -73,12 +69,8 @@ static int ms02nv_write(struct mtd_info *mtd, loff_t to,
 {
 	struct ms02nv_private *mp = mtd->priv;
 
-	if (to + len > mtd->size)
-		return -EINVAL;
-
 	memcpy(mp->uaddr + to, buf, len);
 	*retlen = len;
-
 	return 0;
 }
 
@@ -215,8 +207,8 @@ static int __init ms02nv_init_one(ulong addr)
 	mtd->size = fixsize;
 	mtd->name = (char *)ms02nv_name;
 	mtd->owner = THIS_MODULE;
-	mtd->read = ms02nv_read;
-	mtd->write = ms02nv_write;
+	mtd->_read = ms02nv_read;
+	mtd->_write = ms02nv_write;
 	mtd->writesize = 1;
 
 	ret = -EIO;
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 236057e..928fb0e 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -164,9 +164,6 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
 	      dev_name(&spi->dev), (long long)instr->addr,
 	      (long long)instr->len);
 
-	/* Sanity checks */
-	if (instr->addr + instr->len > mtd->size)
-		return -EINVAL;
 	div_u64_rem(instr->len, priv->page_size, &rem);
 	if (rem)
 		return -EINVAL;
@@ -252,14 +249,6 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
 	pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev),
 			(unsigned)from, (unsigned)(from + len));
 
-	*retlen = 0;
-
-	/* Sanity checks */
-	if (!len)
-		return 0;
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	/* Calculate flash page/byte address */
 	addr = (((unsigned)from / priv->page_size) << priv->page_offset)
 		+ ((unsigned)from % priv->page_size);
@@ -328,14 +317,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
 	pr_debug("%s: write 0x%x..0x%x\n",
 		dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len));
 
-	*retlen = 0;
-
-	/* Sanity checks */
-	if (!len)
-		return 0;
-	if ((to + len) > mtd->size)
-		return -EINVAL;
-
 	spi_message_init(&msg);
 
 	x[0].tx_buf = command = priv->command;
@@ -490,8 +471,6 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base,
 
 	if ((off + len) > 64)
 		len = 64 - off;
-	if (len == 0)
-		return len;
 
 	spi_message_init(&m);
 
@@ -611,16 +590,16 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
 
 static char *otp_setup(struct mtd_info *device, char revision)
 {
-	device->get_fact_prot_info = dataflash_get_otp_info;
-	device->read_fact_prot_reg = dataflash_read_fact_otp;
-	device->get_user_prot_info = dataflash_get_otp_info;
-	device->read_user_prot_reg = dataflash_read_user_otp;
+	device->_get_fact_prot_info = dataflash_get_otp_info;
+	device->_read_fact_prot_reg = dataflash_read_fact_otp;
+	device->_get_user_prot_info = dataflash_get_otp_info;
+	device->_read_user_prot_reg = dataflash_read_user_otp;
 
 	/* rev c parts (at45db321c and at45db1281 only!) use a
 	 * different write procedure; not (yet?) implemented.
 	 */
 	if (revision > 'c')
-		device->write_user_prot_reg = dataflash_write_user_otp;
+		device->_write_user_prot_reg = dataflash_write_user_otp;
 
 	return ", OTP";
 }
@@ -672,9 +651,9 @@ add_dataflash_otp(struct spi_device *spi, char *name,
 	device->owner = THIS_MODULE;
 	device->type = MTD_DATAFLASH;
 	device->flags = MTD_WRITEABLE;
-	device->erase = dataflash_erase;
-	device->read = dataflash_read;
-	device->write = dataflash_write;
+	device->_erase = dataflash_erase;
+	device->_read = dataflash_read;
+	device->_write = dataflash_write;
 	device->priv = priv;
 
 	device->dev.parent = &spi->dev;
@@ -946,18 +925,7 @@ static struct spi_driver dataflash_driver = {
 	/* FIXME:  investigate suspend and resume... */
 };
 
-static int __init dataflash_init(void)
-{
-	return spi_register_driver(&dataflash_driver);
-}
-module_init(dataflash_init);
-
-static void __exit dataflash_exit(void)
-{
-	spi_unregister_driver(&dataflash_driver);
-}
-module_exit(dataflash_exit);
-
+module_spi_driver(dataflash_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Andrew Victor, David Brownell");
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 2562689..ec59d65 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -34,34 +34,23 @@ static struct mtd_info *mtd_info;
 
 static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-	if (instr->addr + instr->len > mtd->size)
-		return -EINVAL;
-
 	memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
-
 	instr->state = MTD_ERASE_DONE;
 	mtd_erase_callback(instr);
-
 	return 0;
 }
 
 static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, void **virt, resource_size_t *phys)
 {
-	if (from + len > mtd->size)
-		return -EINVAL;
-
-	/* can we return a physical address with this driver? */
-	if (phys)
-		return -EINVAL;
-
 	*virt = mtd->priv + from;
 	*retlen = len;
 	return 0;
 }
 
-static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+static int ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
+	return 0;
 }
 
 /*
@@ -80,11 +69,7 @@ static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
 static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, u_char *buf)
 {
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	memcpy(buf, mtd->priv + from, len);
-
 	*retlen = len;
 	return 0;
 }
@@ -92,11 +77,7 @@ static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
 static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
-	if (to + len > mtd->size)
-		return -EINVAL;
-
 	memcpy((char *)mtd->priv + to, buf, len);
-
 	*retlen = len;
 	return 0;
 }
@@ -126,12 +107,12 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
 	mtd->priv = mapped_address;
 
 	mtd->owner = THIS_MODULE;
-	mtd->erase = ram_erase;
-	mtd->point = ram_point;
-	mtd->unpoint = ram_unpoint;
-	mtd->get_unmapped_area = ram_get_unmapped_area;
-	mtd->read = ram_read;
-	mtd->write = ram_write;
+	mtd->_erase = ram_erase;
+	mtd->_point = ram_point;
+	mtd->_unpoint = ram_unpoint;
+	mtd->_get_unmapped_area = ram_get_unmapped_area;
+	mtd->_read = ram_read;
+	mtd->_write = ram_write;
 
 	if (mtd_device_register(mtd, NULL, 0))
 		return -EIO;
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 23423bd..9d2bf17 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -33,45 +33,32 @@ struct phram_mtd_list {
 
 static LIST_HEAD(phram_list);
 
-
 static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	u_char *start = mtd->priv;
 
-	if (instr->addr + instr->len > mtd->size)
-		return -EINVAL;
-
 	memset(start + instr->addr, 0xff, instr->len);
 
 	/* This'll catch a few races. Free the thing before returning :)
 	 * I don't feel at all ashamed. This kind of thing is possible anyway
 	 * with flash, but unlikely.
 	 */
-
 	instr->state = MTD_ERASE_DONE;
-
 	mtd_erase_callback(instr);
-
 	return 0;
 }
 
 static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, void **virt, resource_size_t *phys)
 {
-	if (from + len > mtd->size)
-		return -EINVAL;
-
-	/* can we return a physical address with this driver? */
-	if (phys)
-		return -EINVAL;
-
 	*virt = mtd->priv + from;
 	*retlen = len;
 	return 0;
 }
 
-static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
+	return 0;
 }
 
 static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -79,14 +66,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
 {
 	u_char *start = mtd->priv;
 
-	if (from >= mtd->size)
-		return -EINVAL;
-
-	if (len > mtd->size - from)
-		len = mtd->size - from;
-
 	memcpy(buf, start + from, len);
-
 	*retlen = len;
 	return 0;
 }
@@ -96,20 +76,11 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
 {
 	u_char *start = mtd->priv;
 
-	if (to >= mtd->size)
-		return -EINVAL;
-
-	if (len > mtd->size - to)
-		len = mtd->size - to;
-
 	memcpy(start + to, buf, len);
-
 	*retlen = len;
 	return 0;
 }
 
-
-
 static void unregister_devices(void)
 {
 	struct phram_mtd_list *this, *safe;
@@ -142,11 +113,11 @@ static int register_device(char *name, unsigned long start, unsigned long len)
 	new->mtd.name = name;
 	new->mtd.size = len;
 	new->mtd.flags = MTD_CAP_RAM;
-        new->mtd.erase = phram_erase;
-	new->mtd.point = phram_point;
-	new->mtd.unpoint = phram_unpoint;
-	new->mtd.read = phram_read;
-	new->mtd.write = phram_write;
+	new->mtd._erase = phram_erase;
+	new->mtd._point = phram_point;
+	new->mtd._unpoint = phram_unpoint;
+	new->mtd._read = phram_read;
+	new->mtd._write = phram_write;
 	new->mtd.owner = THIS_MODULE;
 	new->mtd.type = MTD_RAM;
 	new->mtd.erasesize = PAGE_SIZE;
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index ecff765..c4368ec 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -95,12 +95,48 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/pci.h>
-
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/pmc551.h>
+
+#define PMC551_VERSION \
+	"Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
+
+#define PCI_VENDOR_ID_V3_SEMI 0x11b0
+#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200
+
+#define PMC551_PCI_MEM_MAP0 0x50
+#define PMC551_PCI_MEM_MAP1 0x54
+#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000
+#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0
+#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002
+#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001
+
+#define PMC551_SDRAM_MA  0x60
+#define PMC551_SDRAM_CMD 0x62
+#define PMC551_DRAM_CFG  0x64
+#define PMC551_SYS_CTRL_REG 0x78
+
+#define PMC551_DRAM_BLK0 0x68
+#define PMC551_DRAM_BLK1 0x6c
+#define PMC551_DRAM_BLK2 0x70
+#define PMC551_DRAM_BLK3 0x74
+#define PMC551_DRAM_BLK_GET_SIZE(x) (524288 << ((x >> 4) & 0x0f))
+#define PMC551_DRAM_BLK_SET_COL_MUX(x, v) (((x) & ~0x00007000) | (((v) & 0x7) << 12))
+#define PMC551_DRAM_BLK_SET_ROW_MUX(x, v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8))
+
+struct mypriv {
+	struct pci_dev *dev;
+	u_char *start;
+	u32 base_map0;
+	u32 curr_map0;
+	u32 asize;
+	struct mtd_info *nextpmc551;
+};
 
 static struct mtd_info *pmc551list;
 
+static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
+			size_t *retlen, void **virt, resource_size_t *phys);
+
 static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct mypriv *priv = mtd->priv;
@@ -116,16 +152,6 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
 #endif
 
 	end = instr->addr + instr->len - 1;
-
-	/* Is it past the end? */
-	if (end > mtd->size) {
-#ifdef CONFIG_MTD_PMC551_DEBUG
-		printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n",
-			(long)end, (long)mtd->size);
-#endif
-		return -EINVAL;
-	}
-
 	eoff_hi = end & ~(priv->asize - 1);
 	soff_hi = instr->addr & ~(priv->asize - 1);
 	eoff_lo = end & (priv->asize - 1);
@@ -179,18 +205,6 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
 	printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
 #endif
 
-	if (from + len > mtd->size) {
-#ifdef CONFIG_MTD_PMC551_DEBUG
-		printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n",
-			(long)from + len, (long)mtd->size);
-#endif
-		return -EINVAL;
-	}
-
-	/* can we return a physical address with this driver? */
-	if (phys)
-		return -EINVAL;
-
 	soff_hi = from & ~(priv->asize - 1);
 	soff_lo = from & (priv->asize - 1);
 
@@ -206,11 +220,12 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
 	return 0;
 }
 
-static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 #ifdef CONFIG_MTD_PMC551_DEBUG
 	printk(KERN_DEBUG "pmc551_unpoint()\n");
 #endif
+	return 0;
 }
 
 static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -229,16 +244,6 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
 #endif
 
 	end = from + len - 1;
-
-	/* Is it past the end? */
-	if (end > mtd->size) {
-#ifdef CONFIG_MTD_PMC551_DEBUG
-		printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n",
-			(long)end, (long)mtd->size);
-#endif
-		return -EINVAL;
-	}
-
 	soff_hi = from & ~(priv->asize - 1);
 	eoff_hi = end & ~(priv->asize - 1);
 	soff_lo = from & (priv->asize - 1);
@@ -296,16 +301,6 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
 #endif
 
 	end = to + len - 1;
-	/* Is it past the end?  or did the u32 wrap? */
-	if (end > mtd->size) {
-#ifdef CONFIG_MTD_PMC551_DEBUG
-		printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, "
-			"size: %ld, to: %ld)\n", (long)end, (long)mtd->size,
-			(long)to);
-#endif
-		return -EINVAL;
-	}
-
 	soff_hi = to & ~(priv->asize - 1);
 	eoff_hi = end & ~(priv->asize - 1);
 	soff_lo = to & (priv->asize - 1);
@@ -359,7 +354,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len,
  * mechanism
  * returns the size of the memory region found.
  */
-static u32 fixup_pmc551(struct pci_dev *dev)
+static int fixup_pmc551(struct pci_dev *dev)
 {
 #ifdef CONFIG_MTD_PMC551_BUGFIX
 	u32 dram_data;
@@ -669,7 +664,7 @@ static int __init init_pmc551(void)
 	struct mypriv *priv;
 	int found = 0;
 	struct mtd_info *mtd;
-	u32 length = 0;
+	int length = 0;
 
 	if (msize) {
 		msize = (1 << (ffs(msize) - 1)) << 20;
@@ -787,11 +782,11 @@ static int __init init_pmc551(void)
 
 		mtd->size = msize;
 		mtd->flags = MTD_CAP_RAM;
-		mtd->erase = pmc551_erase;
-		mtd->read = pmc551_read;
-		mtd->write = pmc551_write;
-		mtd->point = pmc551_point;
-		mtd->unpoint = pmc551_unpoint;
+		mtd->_erase = pmc551_erase;
+		mtd->_read = pmc551_read;
+		mtd->_write = pmc551_write;
+		mtd->_point = pmc551_point;
+		mtd->_unpoint = pmc551_unpoint;
 		mtd->type = MTD_RAM;
 		mtd->name = "PMC551 RAM board";
 		mtd->erasesize = 0x10000;
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index e585263..ccd39ff 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -76,7 +76,7 @@ static slram_mtd_list_t *slram_mtdlist = NULL;
 static int slram_erase(struct mtd_info *, struct erase_info *);
 static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **,
 		resource_size_t *);
-static void slram_unpoint(struct mtd_info *, loff_t, size_t);
+static int slram_unpoint(struct mtd_info *, loff_t, size_t);
 static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 
@@ -84,21 +84,13 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	slram_priv_t *priv = mtd->priv;
 
-	if (instr->addr + instr->len > mtd->size) {
-		return(-EINVAL);
-	}
-
 	memset(priv->start + instr->addr, 0xff, instr->len);
-
 	/* This'll catch a few races. Free the thing before returning :)
 	 * I don't feel at all ashamed. This kind of thing is possible anyway
 	 * with flash, but unlikely.
 	 */
-
 	instr->state = MTD_ERASE_DONE;
-
 	mtd_erase_callback(instr);
-
 	return(0);
 }
 
@@ -107,20 +99,14 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len,
 {
 	slram_priv_t *priv = mtd->priv;
 
-	/* can we return a physical address with this driver? */
-	if (phys)
-		return -EINVAL;
-
-	if (from + len > mtd->size)
-		return -EINVAL;
-
 	*virt = priv->start + from;
 	*retlen = len;
 	return(0);
 }
 
-static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+static int slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
+	return 0;
 }
 
 static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
@@ -128,14 +114,7 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
 {
 	slram_priv_t *priv = mtd->priv;
 
-	if (from > mtd->size)
-		return -EINVAL;
-
-	if (from + len > mtd->size)
-		len = mtd->size - from;
-
 	memcpy(buf, priv->start + from, len);
-
 	*retlen = len;
 	return(0);
 }
@@ -145,11 +124,7 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len,
 {
 	slram_priv_t *priv = mtd->priv;
 
-	if (to + len > mtd->size)
-		return -EINVAL;
-
 	memcpy(priv->start + to, buf, len);
-
 	*retlen = len;
 	return(0);
 }
@@ -200,11 +175,11 @@ static int register_device(char *name, unsigned long start, unsigned long length
 	(*curmtd)->mtdinfo->name = name;
 	(*curmtd)->mtdinfo->size = length;
 	(*curmtd)->mtdinfo->flags = MTD_CAP_RAM;
-        (*curmtd)->mtdinfo->erase = slram_erase;
-	(*curmtd)->mtdinfo->point = slram_point;
-	(*curmtd)->mtdinfo->unpoint = slram_unpoint;
-	(*curmtd)->mtdinfo->read = slram_read;
-	(*curmtd)->mtdinfo->write = slram_write;
+	(*curmtd)->mtdinfo->_erase = slram_erase;
+	(*curmtd)->mtdinfo->_point = slram_point;
+	(*curmtd)->mtdinfo->_unpoint = slram_unpoint;
+	(*curmtd)->mtdinfo->_read = slram_read;
+	(*curmtd)->mtdinfo->_write = slram_write;
 	(*curmtd)->mtdinfo->owner = THIS_MODULE;
 	(*curmtd)->mtdinfo->type = MTD_RAM;
 	(*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
new file mode 100644
index 0000000..4f7b682
--- /dev/null
+++ b/drivers/mtd/devices/spear_smi.c
@@ -0,0 +1,1091 @@
+/*
+ * linux/drivers/mtd/devices/spear_smi.c
+ *
+ * SMI (Serial Memory Controller) device driver for Serial NOR Flash on
+ * SPEAr platform
+ * The serial nor interface is largely based on drivers/mtd/m25p80.c,
+ * however the SPI interface has been replaced by SMI.
+ *
+ * Copyright (C) 2010 STMicroelectronics.
+ * Ashish Priyadarshi
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spear_smi.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+
+/* max possible slots for serial-nor flash chip in the SMI controller */
+#define MAX_NUM_FLASH_CHIP	4
+
+/* SMI clock rate */
+#define SMI_MAX_CLOCK_FREQ	50000000 /* 50 MHz */
+
+/* MAX time out to safely come out of a erase or write busy conditions */
+#define SMI_PROBE_TIMEOUT	(HZ / 10)
+#define SMI_MAX_TIME_OUT	(3 * HZ)
+
+/* timeout for command completion */
+#define SMI_CMD_TIMEOUT		(HZ / 10)
+
+/* registers of smi */
+#define SMI_CR1		0x0	/* SMI control register 1 */
+#define SMI_CR2		0x4	/* SMI control register 2 */
+#define SMI_SR		0x8	/* SMI status register */
+#define SMI_TR		0xC	/* SMI transmit register */
+#define SMI_RR		0x10	/* SMI receive register */
+
+/* defines for control_reg 1 */
+#define BANK_EN		(0xF << 0)	/* enables all banks */
+#define DSEL_TIME	(0x6 << 4)	/* Deselect time 6 + 1 SMI_CK periods */
+#define SW_MODE		(0x1 << 28)	/* enables SW Mode */
+#define WB_MODE		(0x1 << 29)	/* Write Burst Mode */
+#define FAST_MODE	(0x1 << 15)	/* Fast Mode */
+#define HOLD1		(0x1 << 16)	/* Clock Hold period selection */
+
+/* defines for control_reg 2 */
+#define SEND		(0x1 << 7)	/* Send data */
+#define TFIE		(0x1 << 8)	/* Transmission Flag Interrupt Enable */
+#define WCIE		(0x1 << 9)	/* Write Complete Interrupt Enable */
+#define RD_STATUS_REG	(0x1 << 10)	/* reads status reg */
+#define WE		(0x1 << 11)	/* Write Enable */
+
+#define TX_LEN_SHIFT	0
+#define RX_LEN_SHIFT	4
+#define BANK_SHIFT	12
+
+/* defines for status register */
+#define SR_WIP		0x1	/* Write in progress */
+#define SR_WEL		0x2	/* Write enable latch */
+#define SR_BP0		0x4	/* Block protect 0 */
+#define SR_BP1		0x8	/* Block protect 1 */
+#define SR_BP2		0x10	/* Block protect 2 */
+#define SR_SRWD		0x80	/* SR write protect */
+#define TFF		0x100	/* Transfer Finished Flag */
+#define WCF		0x200	/* Transfer Finished Flag */
+#define ERF1		0x400	/* Forbidden Write Request */
+#define ERF2		0x800	/* Forbidden Access */
+
+#define WM_SHIFT	12
+
+/* flash opcodes */
+#define OPCODE_RDID	0x9f	/* Read JEDEC ID */
+
+/* Flash Device Ids maintenance section */
+
+/* data structure to maintain flash ids from different vendors */
+struct flash_device {
+	char *name;
+	u8 erase_cmd;
+	u32 device_id;
+	u32 pagesize;
+	unsigned long sectorsize;
+	unsigned long size_in_bytes;
+};
+
+#define FLASH_ID(n, es, id, psize, ssize, size)	\
+{				\
+	.name = n,		\
+	.erase_cmd = es,	\
+	.device_id = id,	\
+	.pagesize = psize,	\
+	.sectorsize = ssize,	\
+	.size_in_bytes = size	\
+}
+
+static struct flash_device flash_devices[] = {
+	FLASH_ID("st m25p16"     , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000),
+	FLASH_ID("st m25p32"     , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000),
+	FLASH_ID("st m25p64"     , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000),
+	FLASH_ID("st m25p128"    , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000),
+	FLASH_ID("st m25p05"     , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000),
+	FLASH_ID("st m25p10"     , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000),
+	FLASH_ID("st m25p20"     , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000),
+	FLASH_ID("st m25p40"     , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000),
+	FLASH_ID("st m25p80"     , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000),
+	FLASH_ID("st m45pe10"    , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),
+	FLASH_ID("st m45pe20"    , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),
+	FLASH_ID("st m45pe40"    , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),
+	FLASH_ID("st m45pe80"    , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),
+	FLASH_ID("sp s25fl004"   , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000),
+	FLASH_ID("sp s25fl008"   , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000),
+	FLASH_ID("sp s25fl016"   , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000),
+	FLASH_ID("sp s25fl032"   , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000),
+	FLASH_ID("sp s25fl064"   , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000),
+	FLASH_ID("atmel 25f512"  , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000),
+	FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000),
+	FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000),
+	FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000),
+	FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000),
+	FLASH_ID("mac 25l512"    , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000),
+	FLASH_ID("mac 25l1005"   , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000),
+	FLASH_ID("mac 25l2005"   , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000),
+	FLASH_ID("mac 25l4005"   , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
+	FLASH_ID("mac 25l4005a"  , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000),
+	FLASH_ID("mac 25l8005"   , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000),
+	FLASH_ID("mac 25l1605"   , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000),
+	FLASH_ID("mac 25l1605a"  , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000),
+	FLASH_ID("mac 25l3205"   , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
+	FLASH_ID("mac 25l3205a"  , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000),
+	FLASH_ID("mac 25l6405"   , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000),
+};
+
+/* These partitions would be used if platform doesn't pass one */
+static struct mtd_partition part_info_8M[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x10000),
+	DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x40000),
+	DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x2C0000),
+	DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL),
+};
+
+static struct mtd_partition part_info_16M[] = {
+	DEFINE_PARTS("Xloader", 0x00, 0x40000),
+	DEFINE_PARTS("UBoot", MTDPART_OFS_APPEND, 0x100000),
+	DEFINE_PARTS("Kernel", MTDPART_OFS_APPEND, 0x300000),
+	DEFINE_PARTS("Root File System", MTDPART_OFS_APPEND, MTDPART_SIZ_FULL),
+};
+
+/* Define spear specific structures */
+
+struct spear_snor_flash;
+
+/**
+ * struct spear_smi - Structure for SMI Device
+ *
+ * @clk: functional clock
+ * @status: current status register of SMI.
+ * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ)
+ * @lock: lock to prevent parallel access of SMI.
+ * @io_base: base address for registers of SMI.
+ * @pdev: platform device
+ * @cmd_complete: queue to wait for command completion of NOR-flash.
+ * @num_flashes: number of flashes actually present on board.
+ * @flash: separate structure for each Serial NOR-flash attached to SMI.
+ */
+struct spear_smi {
+	struct clk *clk;
+	u32 status;
+	unsigned long clk_rate;
+	struct mutex lock;
+	void __iomem *io_base;
+	struct platform_device *pdev;
+	wait_queue_head_t cmd_complete;
+	u32 num_flashes;
+	struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP];
+};
+
+/**
+ * struct spear_snor_flash - Structure for Serial NOR Flash
+ *
+ * @bank: Bank number(0, 1, 2, 3) for each NOR-flash.
+ * @dev_id: Device ID of NOR-flash.
+ * @lock: lock to manage flash read, write and erase operations
+ * @mtd: MTD info for each NOR-flash.
+ * @num_parts: Total number of partition in each bank of NOR-flash.
+ * @parts: Partition info for each bank of NOR-flash.
+ * @page_size: Page size of NOR-flash.
+ * @base_addr: Base address of NOR-flash.
+ * @erase_cmd: erase command may vary on different flash types
+ * @fast_mode: flash supports read in fast mode
+ */
+struct spear_snor_flash {
+	u32 bank;
+	u32 dev_id;
+	struct mutex lock;
+	struct mtd_info mtd;
+	u32 num_parts;
+	struct mtd_partition *parts;
+	u32 page_size;
+	void __iomem *base_addr;
+	u8 erase_cmd;
+	u8 fast_mode;
+};
+
+static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd)
+{
+	return container_of(mtd, struct spear_snor_flash, mtd);
+}
+
+/**
+ * spear_smi_read_sr - Read status register of flash through SMI
+ * @dev: structure of SMI information.
+ * @bank: bank to which flash is connected
+ *
+ * This routine will return the status register of the flash chip present at the
+ * given bank.
+ */
+static int spear_smi_read_sr(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	mutex_lock(&dev->lock);
+	dev->status = 0; /* Will be set in interrupt handler */
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	/* program smi in hw mode */
+	writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1);
+
+	/* performing a rsr instruction in hw mode */
+	writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE,
+			dev->io_base + SMI_CR2);
+
+	/* wait for tff */
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	/* copy dev->status (lower 16 bits) in order to release lock */
+	if (ret > 0)
+		ret = dev->status & 0xffff;
+	else
+		ret = -EIO;
+
+	/* restore the ctrl regs state */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/**
+ * spear_smi_wait_till_ready - wait till flash is ready
+ * @dev: structure of SMI information.
+ * @bank: flash corresponding to this bank
+ * @timeout: timeout for busy wait condition
+ *
+ * This routine checks for WIP (write in progress) bit in Status register
+ * If successful the routine returns 0 else -EBUSY
+ */
+static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank,
+		unsigned long timeout)
+{
+	unsigned long finish;
+	int status;
+
+	finish = jiffies + timeout;
+	do {
+		status = spear_smi_read_sr(dev, bank);
+		if (status < 0)
+			continue; /* try till timeout */
+		else if (!(status & SR_WIP))
+			return 0;
+
+		cond_resched();
+	} while (!time_after_eq(jiffies, finish));
+
+	dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
+	return status;
+}
+
+/**
+ * spear_smi_int_handler - SMI Interrupt Handler.
+ * @irq: irq number
+ * @dev_id: structure of SMI device, embedded in dev_id.
+ *
+ * The handler clears all interrupt conditions and records the status in
+ * dev->status which is used by the driver later.
+ */
+static irqreturn_t spear_smi_int_handler(int irq, void *dev_id)
+{
+	u32 status = 0;
+	struct spear_smi *dev = dev_id;
+
+	status = readl(dev->io_base + SMI_SR);
+
+	if (unlikely(!status))
+		return IRQ_NONE;
+
+	/* clear all interrupt conditions */
+	writel(0, dev->io_base + SMI_SR);
+
+	/* copy the status register in dev->status */
+	dev->status |= status;
+
+	/* send the completion */
+	wake_up_interruptible(&dev->cmd_complete);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * spear_smi_hw_init - initializes the smi controller.
+ * @dev: structure of smi device
+ *
+ * this routine initializes the smi controller wit the default values
+ */
+static void spear_smi_hw_init(struct spear_smi *dev)
+{
+	unsigned long rate = 0;
+	u32 prescale = 0;
+	u32 val;
+
+	rate = clk_get_rate(dev->clk);
+
+	/* functional clock of smi */
+	prescale = DIV_ROUND_UP(rate, dev->clk_rate);
+
+	/*
+	 * setting the standard values, fast mode, prescaler for
+	 * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable
+	 */
+	val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
+
+	mutex_lock(&dev->lock);
+	writel(val, dev->io_base + SMI_CR1);
+	mutex_unlock(&dev->lock);
+}
+
+/**
+ * get_flash_index - match chip id from a flash list.
+ * @flash_id: a valid nor flash chip id obtained from board.
+ *
+ * try to validate the chip id by matching from a list, if not found then simply
+ * returns negative. In case of success returns index in to the flash devices
+ * array.
+ */
+static int get_flash_index(u32 flash_id)
+{
+	int index;
+
+	/* Matches chip-id to entire list of 'serial-nor flash' ids */
+	for (index = 0; index < ARRAY_SIZE(flash_devices); index++) {
+		if (flash_devices[index].device_id == flash_id)
+			return index;
+	}
+
+	/* Memory chip is not listed and not supported */
+	return -ENODEV;
+}
+
+/**
+ * spear_smi_write_enable - Enable the flash to do write operation
+ * @dev: structure of SMI device
+ * @bank: enable write for flash connected to this bank
+ *
+ * Set write enable latch with Write Enable command.
+ * Returns 0 on success.
+ */
+static int spear_smi_write_enable(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	mutex_lock(&dev->lock);
+	dev->status = 0; /* Will be set in interrupt handler */
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	/* program smi in h/w mode */
+	writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	/* give the flash, write enable command */
+	writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2);
+
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	/* restore the ctrl regs state */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+
+	if (ret <= 0) {
+		ret = -EIO;
+		dev_err(&dev->pdev->dev,
+			"smi controller failed on write enable\n");
+	} else {
+		/* check whether write mode status is set for required bank */
+		if (dev->status & (1 << (bank + WM_SHIFT)))
+			ret = 0;
+		else {
+			dev_err(&dev->pdev->dev, "couldn't enable write\n");
+			ret = -EIO;
+		}
+	}
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static inline u32
+get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset)
+{
+	u32 cmd;
+	u8 *x = (u8 *)&cmd;
+
+	x[0] = flash->erase_cmd;
+	x[1] = offset >> 16;
+	x[2] = offset >> 8;
+	x[3] = offset;
+
+	return cmd;
+}
+
+/**
+ * spear_smi_erase_sector - erase one sector of flash
+ * @dev: structure of SMI information
+ * @command: erase command to be send
+ * @bank: bank to which this command needs to be send
+ * @bytes: size of command
+ *
+ * Erase one sector of flash memory at offset ``offset'' which is any
+ * address within the sector which should be erased.
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int spear_smi_erase_sector(struct spear_smi *dev,
+		u32 bank, u32 command, u32 bytes)
+{
+	u32 ctrlreg1 = 0;
+	int ret;
+
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
+	if (ret)
+		return ret;
+
+	ret = spear_smi_write_enable(dev, bank);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->lock);
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1);
+
+	/* send command in sw mode */
+	writel(command, dev->io_base + SMI_TR);
+
+	writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT),
+			dev->io_base + SMI_CR2);
+
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+
+	if (ret <= 0) {
+		ret = -EIO;
+		dev_err(&dev->pdev->dev, "sector erase failed\n");
+	} else
+		ret = 0; /* success */
+
+	/* restore ctrl regs */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	writel(0, dev->io_base + SMI_CR2);
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+/**
+ * spear_mtd_erase - perform flash erase operation as requested by user
+ * @mtd: Provides the memory characteristics
+ * @e_info: Provides the erase information
+ *
+ * Erase an address range on the flash chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+ */
+static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	u32 addr, command, bank;
+	int len, ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	bank = flash->bank;
+	if (bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	addr = e_info->addr;
+	len = e_info->len;
+
+	mutex_lock(&flash->lock);
+
+	/* now erase sectors in loop */
+	while (len) {
+		command = get_sector_erase_cmd(flash, addr);
+		/* preparing the command for flash */
+		ret = spear_smi_erase_sector(dev, bank, command, 4);
+		if (ret) {
+			e_info->state = MTD_ERASE_FAILED;
+			mutex_unlock(&flash->lock);
+			return ret;
+		}
+		addr += mtd->erasesize;
+		len -= mtd->erasesize;
+	}
+
+	mutex_unlock(&flash->lock);
+	e_info->state = MTD_ERASE_DONE;
+	mtd_erase_callback(e_info);
+
+	return 0;
+}
+
+/**
+ * spear_mtd_read - performs flash read operation as requested by the user
+ * @mtd: MTD information of the memory bank
+ * @from: Address from which to start read
+ * @len: Number of bytes to be read
+ * @retlen: Fills the Number of bytes actually read
+ * @buf: Fills this after reading
+ *
+ * Read an address range from the flash chip. The address range
+ * may be any size provided it is within the physical boundaries.
+ * Returns 0 on success, non zero otherwise
+ */
+static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u8 *buf)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	void *src;
+	u32 ctrlreg1, val;
+	int ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	if (flash->bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	/* select address as per bank number */
+	src = flash->base_addr + from;
+
+	mutex_lock(&flash->lock);
+
+	/* wait till previous write/erase is done. */
+	ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT);
+	if (ret) {
+		mutex_unlock(&flash->lock);
+		return ret;
+	}
+
+	mutex_lock(&dev->lock);
+	/* put smi in hw mode not wbt mode */
+	ctrlreg1 = val = readl(dev->io_base + SMI_CR1);
+	val &= ~(SW_MODE | WB_MODE);
+	if (flash->fast_mode)
+		val |= FAST_MODE;
+
+	writel(val, dev->io_base + SMI_CR1);
+
+	memcpy_fromio(buf, (u8 *)src, len);
+
+	/* restore ctrl reg1 */
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+	mutex_unlock(&dev->lock);
+
+	*retlen = len;
+	mutex_unlock(&flash->lock);
+
+	return 0;
+}
+
+static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank,
+		void *dest, const void *src, size_t len)
+{
+	int ret;
+	u32 ctrlreg1;
+
+	/* wait until finished previous write command. */
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT);
+	if (ret)
+		return ret;
+
+	/* put smi in write enable */
+	ret = spear_smi_write_enable(dev, bank);
+	if (ret)
+		return ret;
+
+	/* put smi in hw, write burst mode */
+	mutex_lock(&dev->lock);
+
+	ctrlreg1 = readl(dev->io_base + SMI_CR1);
+	writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	memcpy_toio(dest, src, len);
+
+	writel(ctrlreg1, dev->io_base + SMI_CR1);
+
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+/**
+ * spear_mtd_write - performs write operation as requested by the user.
+ * @mtd: MTD information of the memory bank.
+ * @to:	Address to write.
+ * @len: Number of bytes to be written.
+ * @retlen: Number of bytes actually wrote.
+ * @buf: Buffer from which the data to be taken.
+ *
+ * Write an address range to the flash chip. Data must be written in
+ * flash_page_size chunks. The address range may be any size provided
+ * it is within the physical boundaries.
+ * Returns 0 on success, non zero otherwise
+ */
+static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+		size_t *retlen, const u8 *buf)
+{
+	struct spear_snor_flash *flash = get_flash_data(mtd);
+	struct spear_smi *dev = mtd->priv;
+	void *dest;
+	u32 page_offset, page_size;
+	int ret;
+
+	if (!flash || !dev)
+		return -ENODEV;
+
+	if (flash->bank > dev->num_flashes - 1) {
+		dev_err(&dev->pdev->dev, "Invalid Bank Num");
+		return -EINVAL;
+	}
+
+	/* select address as per bank number */
+	dest = flash->base_addr + to;
+	mutex_lock(&flash->lock);
+
+	page_offset = (u32)to % flash->page_size;
+
+	/* do if all the bytes fit onto one page */
+	if (page_offset + len <= flash->page_size) {
+		ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len);
+		if (!ret)
+			*retlen += len;
+	} else {
+		u32 i;
+
+		/* the size of data remaining on the first page */
+		page_size = flash->page_size - page_offset;
+
+		ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf,
+				page_size);
+		if (ret)
+			goto err_write;
+		else
+			*retlen += page_size;
+
+		/* write everything in pagesize chunks */
+		for (i = page_size; i < len; i += page_size) {
+			page_size = len - i;
+			if (page_size > flash->page_size)
+				page_size = flash->page_size;
+
+			ret = spear_smi_cpy_toio(dev, flash->bank, dest + i,
+					buf + i, page_size);
+			if (ret)
+				break;
+			else
+				*retlen += page_size;
+		}
+	}
+
+err_write:
+	mutex_unlock(&flash->lock);
+
+	return ret;
+}
+
+/**
+ * spear_smi_probe_flash - Detects the NOR Flash chip.
+ * @dev: structure of SMI information.
+ * @bank: bank on which flash must be probed
+ *
+ * This routine will check whether there exists a flash chip on a given memory
+ * bank ID.
+ * Return index of the probed flash in flash devices structure
+ */
+static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank)
+{
+	int ret;
+	u32 val = 0;
+
+	ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT);
+	if (ret)
+		return ret;
+
+	mutex_lock(&dev->lock);
+
+	dev->status = 0; /* Will be set in interrupt handler */
+	/* put smi in sw mode */
+	val = readl(dev->io_base + SMI_CR1);
+	writel(val | SW_MODE, dev->io_base + SMI_CR1);
+
+	/* send readid command in sw mode */
+	writel(OPCODE_RDID, dev->io_base + SMI_TR);
+
+	val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) |
+		(3 << RX_LEN_SHIFT) | TFIE;
+	writel(val, dev->io_base + SMI_CR2);
+
+	/* wait for TFF */
+	ret = wait_event_interruptible_timeout(dev->cmd_complete,
+			dev->status & TFF, SMI_CMD_TIMEOUT);
+	if (ret <= 0) {
+		ret = -ENODEV;
+		goto err_probe;
+	}
+
+	/* get memory chip id */
+	val = readl(dev->io_base + SMI_RR);
+	val &= 0x00ffffff;
+	ret = get_flash_index(val);
+
+err_probe:
+	/* clear sw mode */
+	val = readl(dev->io_base + SMI_CR1);
+	writel(val & ~SW_MODE, dev->io_base + SMI_CR1);
+
+	mutex_unlock(&dev->lock);
+	return ret;
+}
+
+static int spear_smi_setup_banks(struct platform_device *pdev, u32 bank)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+	struct spear_smi_flash_info *flash_info;
+	struct spear_smi_plat_data *pdata;
+	struct spear_snor_flash *flash;
+	struct mtd_partition *parts;
+	int count;
+	int flash_index;
+	int ret = 0;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (bank > pdata->num_flashes - 1)
+		return -EINVAL;
+
+	flash_info = &pdata->board_flash_info[bank];
+	if (!flash_info)
+		return -ENODEV;
+
+	flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
+	if (!flash)
+		return -ENOMEM;
+	flash->bank = bank;
+	flash->fast_mode = flash_info->fast_mode ? 1 : 0;
+	mutex_init(&flash->lock);
+
+	/* verify whether nor flash is really present on board */
+	flash_index = spear_smi_probe_flash(dev, bank);
+	if (flash_index < 0) {
+		dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
+		ret = flash_index;
+		goto err_probe;
+	}
+	/* map the memory for nor flash chip */
+	flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
+	if (!flash->base_addr) {
+		ret = -EIO;
+		goto err_probe;
+	}
+
+	dev->flash[bank] = flash;
+	flash->mtd.priv = dev;
+
+	if (flash_info->name)
+		flash->mtd.name = flash_info->name;
+	else
+		flash->mtd.name = flash_devices[flash_index].name;
+
+	flash->mtd.type = MTD_NORFLASH;
+	flash->mtd.writesize = 1;
+	flash->mtd.flags = MTD_CAP_NORFLASH;
+	flash->mtd.size = flash_info->size;
+	flash->mtd.erasesize = flash_devices[flash_index].sectorsize;
+	flash->page_size = flash_devices[flash_index].pagesize;
+	flash->mtd.writebufsize = flash->page_size;
+	flash->erase_cmd = flash_devices[flash_index].erase_cmd;
+	flash->mtd._erase = spear_mtd_erase;
+	flash->mtd._read = spear_mtd_read;
+	flash->mtd._write = spear_mtd_write;
+	flash->dev_id = flash_devices[flash_index].device_id;
+
+	dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n",
+			flash->mtd.name, flash->mtd.size,
+			flash->mtd.size / (1024 * 1024));
+
+	dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n",
+			flash->mtd.erasesize, flash->mtd.erasesize / 1024);
+
+	if (flash_info->partitions) {
+		parts = flash_info->partitions;
+		count = flash_info->nr_partitions;
+	} else {
+		/* choose from default ones */
+		switch (flash->mtd.size) {
+		case 0x800000:/* 8MB */
+			parts = part_info_8M;
+			count = ARRAY_SIZE(part_info_8M);
+			break;
+		case 0x1000000:/* 16MB */
+			parts = part_info_16M;
+			count = ARRAY_SIZE(part_info_16M);
+			break;
+		default:
+			dev_err(&pdev->dev, "undefined partition\n");
+			ret = ENODEV;
+			goto err_map;
+		}
+	}
+	ret = mtd_device_parse_register(&flash->mtd, NULL, 0, parts, count);
+	if (ret)
+		dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
+
+	return ret;
+
+err_map:
+	iounmap(flash->base_addr);
+
+err_probe:
+	kfree(flash);
+	return ret;
+}
+
+/**
+ * spear_smi_probe - Entry routine
+ * @pdev: platform device structure
+ *
+ * This is the first routine which gets invoked during booting and does all
+ * initialization/allocation work. The routine looks for available memory banks,
+ * and do proper init for any found one.
+ * Returns 0 on success, non zero otherwise
+ */
+static int __devinit spear_smi_probe(struct platform_device *pdev)
+{
+	struct spear_smi_plat_data *pdata;
+	struct spear_smi *dev;
+	struct resource *smi_base;
+	int irq, ret = 0;
+	int i;
+
+	pdata = dev_get_platdata(&pdev->dev);
+	if (pdata < 0) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "no platform data\n");
+		goto err;
+	}
+
+	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!smi_base) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "invalid smi base address\n");
+		goto err;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "invalid smi irq\n");
+		goto err;
+	}
+
+	dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
+	if (!dev) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "mem alloc fail\n");
+		goto err;
+	}
+
+	smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
+			pdev->name);
+	if (!smi_base) {
+		ret = -EBUSY;
+		dev_err(&pdev->dev, "request mem region fail\n");
+		goto err_mem;
+	}
+
+	dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
+	if (!dev->io_base) {
+		ret = -EIO;
+		dev_err(&pdev->dev, "ioremap fail\n");
+		goto err_ioremap;
+	}
+
+	dev->pdev = pdev;
+	dev->clk_rate = pdata->clk_rate;
+
+	if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
+		dev->clk_rate = SMI_MAX_CLOCK_FREQ;
+
+	dev->num_flashes = pdata->num_flashes;
+
+	if (dev->num_flashes > MAX_NUM_FLASH_CHIP) {
+		dev_err(&pdev->dev, "exceeding max number of flashes\n");
+		dev->num_flashes = MAX_NUM_FLASH_CHIP;
+	}
+
+	dev->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(dev->clk)) {
+		ret = PTR_ERR(dev->clk);
+		goto err_clk;
+	}
+
+	ret = clk_enable(dev->clk);
+	if (ret)
+		goto err_clk_enable;
+
+	ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
+		goto err_irq;
+	}
+
+	mutex_init(&dev->lock);
+	init_waitqueue_head(&dev->cmd_complete);
+	spear_smi_hw_init(dev);
+	platform_set_drvdata(pdev, dev);
+
+	/* loop for each serial nor-flash which is connected to smi */
+	for (i = 0; i < dev->num_flashes; i++) {
+		ret = spear_smi_setup_banks(pdev, i);
+		if (ret) {
+			dev_err(&dev->pdev->dev, "bank setup failed\n");
+			goto err_bank_setup;
+		}
+	}
+
+	return 0;
+
+err_bank_setup:
+	free_irq(irq, dev);
+	platform_set_drvdata(pdev, NULL);
+err_irq:
+	clk_disable(dev->clk);
+err_clk_enable:
+	clk_put(dev->clk);
+err_clk:
+	iounmap(dev->io_base);
+err_ioremap:
+	release_mem_region(smi_base->start, resource_size(smi_base));
+err_mem:
+	kfree(dev);
+err:
+	return ret;
+}
+
+/**
+ * spear_smi_remove - Exit routine
+ * @pdev: platform device structure
+ *
+ * free all allocations and delete the partitions.
+ */
+static int __devexit spear_smi_remove(struct platform_device *pdev)
+{
+	struct spear_smi *dev;
+	struct spear_snor_flash *flash;
+	struct resource *smi_base;
+	int ret;
+	int i, irq;
+
+	dev = platform_get_drvdata(pdev);
+	if (!dev) {
+		dev_err(&pdev->dev, "dev is null\n");
+		return -ENODEV;
+	}
+
+	/* clean up for all nor flash */
+	for (i = 0; i < dev->num_flashes; i++) {
+		flash = dev->flash[i];
+		if (!flash)
+			continue;
+
+		/* clean up mtd stuff */
+		ret = mtd_device_unregister(&flash->mtd);
+		if (ret)
+			dev_err(&pdev->dev, "error removing mtd\n");
+
+		iounmap(flash->base_addr);
+		kfree(flash);
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	free_irq(irq, dev);
+
+	clk_disable(dev->clk);
+	clk_put(dev->clk);
+	iounmap(dev->io_base);
+	kfree(dev);
+
+	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(smi_base->start, resource_size(smi_base));
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+
+	if (dev && dev->clk)
+		clk_disable(dev->clk);
+
+	return 0;
+}
+
+int spear_smi_resume(struct platform_device *pdev)
+{
+	struct spear_smi *dev = platform_get_drvdata(pdev);
+	int ret = -EPERM;
+
+	if (dev && dev->clk)
+		ret = clk_enable(dev->clk);
+
+	if (!ret)
+		spear_smi_hw_init(dev);
+	return ret;
+}
+
+static struct platform_driver spear_smi_driver = {
+	.driver = {
+		.name = "smi",
+		.bus = &platform_bus_type,
+		.owner = THIS_MODULE,
+	},
+	.probe = spear_smi_probe,
+	.remove = __devexit_p(spear_smi_remove),
+	.suspend = spear_smi_suspend,
+	.resume = spear_smi_resume,
+};
+
+static int spear_smi_init(void)
+{
+	return platform_driver_register(&spear_smi_driver);
+}
+module_init(spear_smi_init);
+
+static void spear_smi_exit(void)
+{
+	platform_driver_unregister(&spear_smi_driver);
+}
+module_exit(spear_smi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 5fc1983..51b2df3 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -175,9 +175,6 @@ static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr)
 	int err;
 
 	/* Sanity checks */
-	if (instr->addr + instr->len > flash->mtd.size)
-		return -EINVAL;
-
 	if ((uint32_t)instr->len % mtd->erasesize)
 		return -EINVAL;
 
@@ -223,16 +220,6 @@ static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len,
 	unsigned char command[4];
 	int ret;
 
-	/* Sanity checking */
-	if (len == 0)
-		return 0;
-
-	if (from + len > flash->mtd.size)
-		return -EINVAL;
-
-	if (retlen)
-		*retlen = 0;
-
 	spi_message_init(&message);
 	memset(&transfer, 0, sizeof(transfer));
 
@@ -274,13 +261,6 @@ static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len,
 	int i, j, ret, bytes, copied = 0;
 	unsigned char command[5];
 
-	/* Sanity checks */
-	if (!len)
-		return 0;
-
-	if (to + len > flash->mtd.size)
-		return -EINVAL;
-
 	if ((uint32_t)to % mtd->writesize)
 		return -EINVAL;
 
@@ -402,10 +382,11 @@ static int __devinit sst25l_probe(struct spi_device *spi)
 	flash->mtd.flags	= MTD_CAP_NORFLASH;
 	flash->mtd.erasesize	= flash_info->erase_size;
 	flash->mtd.writesize	= flash_info->page_size;
+	flash->mtd.writebufsize	= flash_info->page_size;
 	flash->mtd.size		= flash_info->page_size * flash_info->nr_pages;
-	flash->mtd.erase	= sst25l_erase;
-	flash->mtd.read		= sst25l_read;
-	flash->mtd.write 	= sst25l_write;
+	flash->mtd._erase	= sst25l_erase;
+	flash->mtd._read		= sst25l_read;
+	flash->mtd._write 	= sst25l_write;
 
 	dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name,
 		 (long long)flash->mtd.size >> 10);
@@ -450,18 +431,7 @@ static struct spi_driver sst25l_driver = {
 	.remove		= __devexit_p(sst25l_remove),
 };
 
-static int __init sst25l_init(void)
-{
-	return spi_register_driver(&sst25l_driver);
-}
-
-static void __exit sst25l_exit(void)
-{
-	spi_unregister_driver(&sst25l_driver);
-}
-
-module_init(sst25l_init);
-module_exit(sst25l_exit);
+module_spi_driver(sst25l_driver);
 
 MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips");
 MODULE_AUTHOR("Andre Renaud <andre@bluewatersys.com>, "
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 28646c9..3af3514 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -56,7 +56,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	if (memcmp(mtd->name, "DiskOnChip", 10))
 		return;
 
-	if (!mtd->block_isbad) {
+	if (!mtd->_block_isbad) {
 		printk(KERN_ERR
 "INFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n"
 "Please use the new diskonchip driver under the NAND subsystem.\n");
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c
index 536bbce..d3cfe26b 100644
--- a/drivers/mtd/lpddr/lpddr_cmds.c
+++ b/drivers/mtd/lpddr/lpddr_cmds.c
@@ -40,7 +40,7 @@ static int lpddr_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
 static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
 			size_t *retlen, void **mtdbuf, resource_size_t *phys);
-static void lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len);
+static int lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len);
 static int get_chip(struct map_info *map, struct flchip *chip, int mode);
 static int chip_ready(struct map_info *map, struct flchip *chip, int mode);
 static void put_chip(struct map_info *map, struct flchip *chip);
@@ -63,18 +63,18 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
 	mtd->type = MTD_NORFLASH;
 
 	/* Fill in the default mtd operations */
-	mtd->read = lpddr_read;
+	mtd->_read = lpddr_read;
 	mtd->type = MTD_NORFLASH;
 	mtd->flags = MTD_CAP_NORFLASH;
 	mtd->flags &= ~MTD_BIT_WRITEABLE;
-	mtd->erase = lpddr_erase;
-	mtd->write = lpddr_write_buffers;
-	mtd->writev = lpddr_writev;
-	mtd->lock = lpddr_lock;
-	mtd->unlock = lpddr_unlock;
+	mtd->_erase = lpddr_erase;
+	mtd->_write = lpddr_write_buffers;
+	mtd->_writev = lpddr_writev;
+	mtd->_lock = lpddr_lock;
+	mtd->_unlock = lpddr_unlock;
 	if (map_is_linear(map)) {
-		mtd->point = lpddr_point;
-		mtd->unpoint = lpddr_unpoint;
+		mtd->_point = lpddr_point;
+		mtd->_unpoint = lpddr_unpoint;
 	}
 	mtd->size = 1 << lpddr->qinfo->DevSizeShift;
 	mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift;
@@ -530,14 +530,12 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
 	struct flchip *chip = &lpddr->chips[chipnum];
 	int ret = 0;
 
-	if (!map->virt || (adr + len > mtd->size))
+	if (!map->virt)
 		return -EINVAL;
 
 	/* ofs: offset within the first chip that the first read should start */
 	ofs = adr - (chipnum << lpddr->chipshift);
-
 	*mtdbuf = (void *)map->virt + chip->start + ofs;
-	*retlen = 0;
 
 	while (len) {
 		unsigned long thislen;
@@ -575,11 +573,11 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
 	return 0;
 }
 
-static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
+static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
 {
 	struct map_info *map = mtd->priv;
 	struct lpddr_private *lpddr = map->fldrv_priv;
-	int chipnum = adr >> lpddr->chipshift;
+	int chipnum = adr >> lpddr->chipshift, err = 0;
 	unsigned long ofs;
 
 	/* ofs: offset within the first chip that the first read should start */
@@ -603,9 +601,11 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
 			chip->ref_point_counter--;
 			if (chip->ref_point_counter == 0)
 				chip->state = FL_READY;
-		} else
+		} else {
 			printk(KERN_WARNING "%s: Warning: unpoint called on non"
 					"pointed region\n", map->name);
+			err = -EINVAL;
+		}
 
 		put_chip(map, chip);
 		mutex_unlock(&chip->mutex);
@@ -614,6 +614,8 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
 		ofs = 0;
 		chipnum++;
 	}
+
+	return err;
 }
 
 static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
@@ -637,13 +639,11 @@ static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs,
 	int chipnum;
 	unsigned long ofs, vec_seek, i;
 	int wbufsize = 1 << lpddr->qinfo->BufSizeShift;
-
 	size_t len = 0;
 
 	for (i = 0; i < count; i++)
 		len += vecs[i].iov_len;
 
-	*retlen = 0;
 	if (!len)
 		return 0;
 
@@ -688,9 +688,6 @@ static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr)
 	ofs = instr->addr;
 	len = instr->len;
 
-	if (ofs > mtd->size || (len + ofs) > mtd->size)
-		return -EINVAL;
-
 	while (len > 0) {
 		ret = do_erase_oneblock(mtd, ofs);
 		if (ret)
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 8b54101..e864fc6 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -182,6 +182,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 {
 	struct flash_platform_data *plat = dev->dev.platform_data;
 	struct ixp4xx_flash_info *info;
+	struct mtd_part_parser_data ppdata = {
+		.origin = dev->resource->start,
+	};
 	int err = -1;
 
 	if (!plat)
@@ -247,7 +250,7 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
 	/* Use the fast version */
 	info->map.write = ixp4xx_write16;
 
-	err = mtd_device_parse_register(info->mtd, probes, dev->resource->start,
+	err = mtd_device_parse_register(info->mtd, probes, &ppdata,
 			plat->parts, plat->nr_parts);
 	if (err) {
 		printk(KERN_ERR "Could not parse partitions\n");
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 5028219..cbc3b78 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -23,106 +23,6 @@
 #include <asm/sizes.h>
 #include <asm/mach/flash.h>
 
-#if 0
-/*
- * This is here for documentation purposes only - until these people
- * submit their machine types.  It will be gone January 2005.
- */
-static struct mtd_partition consus_partitions[] = {
-	{
-		.name		= "Consus boot firmware",
-		.offset		= 0,
-		.size		= 0x00040000,
-		.mask_flags	= MTD_WRITABLE, /* force read-only */
-	}, {
-		.name		= "Consus kernel",
-		.offset		= 0x00040000,
-		.size		= 0x00100000,
-		.mask_flags	= 0,
-	}, {
-		.name		= "Consus disk",
-		.offset		= 0x00140000,
-		/* The rest (up to 16M) for jffs.  We could put 0 and
-		   make it find the size automatically, but right now
-		   i have 32 megs.  jffs will use all 32 megs if given
-		   the chance, and this leads to horrible problems
-		   when you try to re-flash the image because blob
-		   won't erase the whole partition. */
-		.size		= 0x01000000 - 0x00140000,
-		.mask_flags	= 0,
-	}, {
-		/* this disk is a secondary disk, which can be used as
-		   needed, for simplicity, make it the size of the other
-		   consus partition, although realistically it could be
-		   the remainder of the disk (depending on the file
-		   system used) */
-		 .name		= "Consus disk2",
-		 .offset	= 0x01000000,
-		 .size		= 0x01000000 - 0x00140000,
-		 .mask_flags	= 0,
-	}
-};
-
-/* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
-static struct mtd_partition frodo_partitions[] =
-{
-	{
-		.name		= "bootloader",
-		.size		= 0x00040000,
-		.offset		= 0x00000000,
-		.mask_flags	= MTD_WRITEABLE
-	}, {
-		.name		= "bootloader params",
-		.size		= 0x00040000,
-		.offset		= MTDPART_OFS_APPEND,
-		.mask_flags	= MTD_WRITEABLE
-	}, {
-		.name		= "kernel",
-		.size		= 0x00100000,
-		.offset		= MTDPART_OFS_APPEND,
-		.mask_flags	= MTD_WRITEABLE
-	}, {
-		.name		= "ramdisk",
-		.size		= 0x00400000,
-		.offset		= MTDPART_OFS_APPEND,
-		.mask_flags	= MTD_WRITEABLE
-	}, {
-		.name		= "file system",
-		.size		= MTDPART_SIZ_FULL,
-		.offset		= MTDPART_OFS_APPEND
-	}
-};
-
-static struct mtd_partition jornada56x_partitions[] = {
-	{
-		.name		= "bootldr",
-		.size		= 0x00040000,
-		.offset		= 0,
-		.mask_flags	= MTD_WRITEABLE,
-	}, {
-		.name		= "rootfs",
-		.size		= MTDPART_SIZ_FULL,
-		.offset		= MTDPART_OFS_APPEND,
-	}
-};
-
-static void jornada56x_set_vpp(int vpp)
-{
-	if (vpp)
-		GPSR = GPIO_GPIO26;
-	else
-		GPCR = GPIO_GPIO26;
-	GPDR |= GPIO_GPIO26;
-}
-
-/*
- * Machine        Phys          Size    set_vpp
- * Consus    : SA1100_CS0_PHYS SZ_32M
- * Frodo     : SA1100_CS0_PHYS SZ_32M
- * Jornada56x: SA1100_CS0_PHYS SZ_32M jornada56x_set_vpp
- */
-#endif
-
 struct sa_subdev_info {
 	char name[16];
 	struct map_info map;
@@ -373,21 +273,9 @@ static int __exit sa1100_mtd_remove(struct platform_device *pdev)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static void sa1100_mtd_shutdown(struct platform_device *dev)
-{
-	struct sa_info *info = platform_get_drvdata(dev);
-	if (info && mtd_suspend(info->mtd) == 0)
-		mtd_resume(info->mtd);
-}
-#else
-#define sa1100_mtd_shutdown NULL
-#endif
-
 static struct platform_driver sa1100_mtd_driver = {
 	.probe		= sa1100_mtd_probe,
 	.remove		= __exit_p(sa1100_mtd_remove),
-	.shutdown	= sa1100_mtd_shutdown,
 	.driver		= {
 		.name	= "sa1100-mtd",
 		.owner	= THIS_MODULE,
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index 6793074..cfff454 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -85,7 +85,7 @@ static int __init uclinux_mtd_init(void)
 	}
 
 	mtd->owner = THIS_MODULE;
-	mtd->point = uclinux_point;
+	mtd->_point = uclinux_point;
 	mtd->priv = mapp;
 
 	uclinux_ram_mtdinfo = mtd;
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c
index 3a04b07..2e2b094 100644
--- a/drivers/mtd/maps/vmu-flash.c
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -360,9 +360,6 @@ static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
 	int index = 0, retval, partition, leftover, numblocks;
 	unsigned char cx;
 
-	if (len < 1)
-		return -EIO;
-
 	mpart = mtd->priv;
 	mdev = mpart->mdev;
 	partition = mpart->partition;
@@ -434,11 +431,6 @@ static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
 	partition = mpart->partition;
 	card = maple_get_drvdata(mdev);
 
-	/* simple sanity checks */
-	if (len < 1) {
-		error = -EIO;
-		goto failed;
-	}
 	numblocks = card->parts[partition].numblocks;
 	if (to + len > numblocks * card->blocklen)
 		len = numblocks * card->blocklen - to;
@@ -544,9 +536,9 @@ static void vmu_queryblocks(struct mapleq *mq)
 	mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
 	mtd_cur->size = part_cur->numblocks * card->blocklen;
 	mtd_cur->erasesize = card->blocklen;
-	mtd_cur->write = vmu_flash_write;
-	mtd_cur->read = vmu_flash_read;
-	mtd_cur->sync = vmu_flash_sync;
+	mtd_cur->_write = vmu_flash_write;
+	mtd_cur->_read = vmu_flash_read;
+	mtd_cur->_sync = vmu_flash_sync;
 	mtd_cur->writesize = card->blocklen;
 
 	mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 424ca5f..f1f0671 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -233,6 +233,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
 	ret = __get_mtd_device(dev->mtd);
 	if (ret)
 		goto error_release;
+	dev->file_mode = mode;
 
 unlock:
 	dev->open++;
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index af65912..6c6d807 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -321,8 +321,12 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
 	mutex_unlock(&mtdblk->cache_mutex);
 
 	if (!--mtdblk->count) {
-		/* It was the last usage. Free the cache */
-		mtd_sync(mbd->mtd);
+		/*
+		 * It was the last usage. Free the cache, but only sync if
+		 * opened for writing.
+		 */
+		if (mbd->file_mode & FMODE_WRITE)
+			mtd_sync(mbd->mtd);
 		vfree(mtdblk->cache_data);
 	}
 
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 50c6a1e..55d8232 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -31,13 +31,13 @@
 #include <linux/compat.h>
 #include <linux/mount.h>
 #include <linux/blkpg.h>
+#include <linux/magic.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
 
 #include <asm/uaccess.h>
 
-#define MTD_INODE_FS_MAGIC 0x11307854
 static DEFINE_MUTEX(mtd_mutex);
 static struct vfsmount *mtd_inode_mnt __read_mostly;
 
@@ -405,7 +405,7 @@ static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
 	if (length > 4096)
 		return -EINVAL;
 
-	if (!mtd->write_oob)
+	if (!mtd->_write_oob)
 		ret = -EOPNOTSUPP;
 	else
 		ret = access_ok(VERIFY_READ, ptr, length) ? 0 : -EFAULT;
@@ -576,7 +576,7 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd,
 			!access_ok(VERIFY_READ, req.usr_data, req.len) ||
 			!access_ok(VERIFY_READ, req.usr_oob, req.ooblen))
 		return -EFAULT;
-	if (!mtd->write_oob)
+	if (!mtd->_write_oob)
 		return -EOPNOTSUPP;
 
 	ops.mode = req.mode;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 1ed5103..f7a31cc 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -72,8 +72,6 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
 	int ret = 0, err;
 	int i;
 
-	*retlen = 0;
-
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
 		size_t size, retsize;
@@ -126,11 +124,6 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
 	int err = -EINVAL;
 	int i;
 
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-
-	*retlen = 0;
-
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
 		size_t size, retsize;
@@ -145,11 +138,7 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
 		else
 			size = len;
 
-		if (!(subdev->flags & MTD_WRITEABLE))
-			err = -EROFS;
-		else
-			err = mtd_write(subdev, to, size, &retsize, buf);
-
+		err = mtd_write(subdev, to, size, &retsize, buf);
 		if (err)
 			break;
 
@@ -176,19 +165,10 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
 	int i;
 	int err = -EINVAL;
 
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-
-	*retlen = 0;
-
 	/* Calculate total length of data */
 	for (i = 0; i < count; i++)
 		total_len += vecs[i].iov_len;
 
-	/* Do not allow write past end of device */
-	if ((to + total_len) > mtd->size)
-		return -EINVAL;
-
 	/* Check alignment */
 	if (mtd->writesize > 1) {
 		uint64_t __to = to;
@@ -224,12 +204,8 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
 		old_iov_len = vecs_copy[entry_high].iov_len;
 		vecs_copy[entry_high].iov_len = size;
 
-		if (!(subdev->flags & MTD_WRITEABLE))
-			err = -EROFS;
-		else
-			err = mtd_writev(subdev, &vecs_copy[entry_low],
-					 entry_high - entry_low + 1, to,
-					 &retsize);
+		err = mtd_writev(subdev, &vecs_copy[entry_low],
+				 entry_high - entry_low + 1, to, &retsize);
 
 		vecs_copy[entry_high].iov_len = old_iov_len - size;
 		vecs_copy[entry_high].iov_base += size;
@@ -403,15 +379,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
 	uint64_t length, offset = 0;
 	struct erase_info *erase;
 
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-
-	if (instr->addr > concat->mtd.size)
-		return -EINVAL;
-
-	if (instr->len + instr->addr > concat->mtd.size)
-		return -EINVAL;
-
 	/*
 	 * Check for proper erase block alignment of the to-be-erased area.
 	 * It is easier to do this based on the super device's erase
@@ -499,10 +466,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
 		else
 			erase->len = length;
 
-		if (!(subdev->flags & MTD_WRITEABLE)) {
-			err = -EROFS;
-			break;
-		}
 		length -= erase->len;
 		if ((err = concat_dev_erase(subdev, erase))) {
 			/* sanity check: should never happen since
@@ -538,9 +501,6 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	struct mtd_concat *concat = CONCAT(mtd);
 	int i, err = -EINVAL;
 
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
-
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
 		uint64_t size;
@@ -575,9 +535,6 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	struct mtd_concat *concat = CONCAT(mtd);
 	int i, err = 0;
 
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
-
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
 		uint64_t size;
@@ -650,9 +607,6 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
 	if (!mtd_can_have_bb(concat->subdev[0]))
 		return res;
 
-	if (ofs > mtd->size)
-		return -EINVAL;
-
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
 
@@ -673,12 +627,6 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	struct mtd_concat *concat = CONCAT(mtd);
 	int i, err = -EINVAL;
 
-	if (!mtd_can_have_bb(concat->subdev[0]))
-		return 0;
-
-	if (ofs > mtd->size)
-		return -EINVAL;
-
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
 
@@ -716,10 +664,6 @@ static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
 			continue;
 		}
 
-		/* we've found the subdev over which the mapping will reside */
-		if (offset + len > subdev->size)
-			return (unsigned long) -EINVAL;
-
 		return mtd_get_unmapped_area(subdev, len, offset, flags);
 	}
 
@@ -777,16 +721,16 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],	/* subdevices to c
 	concat->mtd.subpage_sft = subdev[0]->subpage_sft;
 	concat->mtd.oobsize = subdev[0]->oobsize;
 	concat->mtd.oobavail = subdev[0]->oobavail;
-	if (subdev[0]->writev)
-		concat->mtd.writev = concat_writev;
-	if (subdev[0]->read_oob)
-		concat->mtd.read_oob = concat_read_oob;
-	if (subdev[0]->write_oob)
-		concat->mtd.write_oob = concat_write_oob;
-	if (subdev[0]->block_isbad)
-		concat->mtd.block_isbad = concat_block_isbad;
-	if (subdev[0]->block_markbad)
-		concat->mtd.block_markbad = concat_block_markbad;
+	if (subdev[0]->_writev)
+		concat->mtd._writev = concat_writev;
+	if (subdev[0]->_read_oob)
+		concat->mtd._read_oob = concat_read_oob;
+	if (subdev[0]->_write_oob)
+		concat->mtd._write_oob = concat_write_oob;
+	if (subdev[0]->_block_isbad)
+		concat->mtd._block_isbad = concat_block_isbad;
+	if (subdev[0]->_block_markbad)
+		concat->mtd._block_markbad = concat_block_markbad;
 
 	concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
 
@@ -833,8 +777,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],	/* subdevices to c
 		if (concat->mtd.writesize   !=  subdev[i]->writesize ||
 		    concat->mtd.subpage_sft != subdev[i]->subpage_sft ||
 		    concat->mtd.oobsize    !=  subdev[i]->oobsize ||
-		    !concat->mtd.read_oob  != !subdev[i]->read_oob ||
-		    !concat->mtd.write_oob != !subdev[i]->write_oob) {
+		    !concat->mtd._read_oob  != !subdev[i]->_read_oob ||
+		    !concat->mtd._write_oob != !subdev[i]->_write_oob) {
 			kfree(concat);
 			printk("Incompatible OOB or ECC data on \"%s\"\n",
 			       subdev[i]->name);
@@ -849,15 +793,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],	/* subdevices to c
 	concat->num_subdev = num_devs;
 	concat->mtd.name = name;
 
-	concat->mtd.erase = concat_erase;
-	concat->mtd.read = concat_read;
-	concat->mtd.write = concat_write;
-	concat->mtd.sync = concat_sync;
-	concat->mtd.lock = concat_lock;
-	concat->mtd.unlock = concat_unlock;
-	concat->mtd.suspend = concat_suspend;
-	concat->mtd.resume = concat_resume;
-	concat->mtd.get_unmapped_area = concat_get_unmapped_area;
+	concat->mtd._erase = concat_erase;
+	concat->mtd._read = concat_read;
+	concat->mtd._write = concat_write;
+	concat->mtd._sync = concat_sync;
+	concat->mtd._lock = concat_lock;
+	concat->mtd._unlock = concat_unlock;
+	concat->mtd._suspend = concat_suspend;
+	concat->mtd._resume = concat_resume;
+	concat->mtd._get_unmapped_area = concat_get_unmapped_area;
 
 	/*
 	 * Combine the erase block size info of the subdevices:
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 9a9ce71..b274fdf 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -107,7 +107,7 @@ static LIST_HEAD(mtd_notifiers);
  */
 static void mtd_release(struct device *dev)
 {
-	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct mtd_info __maybe_unused *mtd = dev_get_drvdata(dev);
 	dev_t index = MTD_DEVT(mtd->index);
 
 	/* remove /dev/mtdXro node if needed */
@@ -126,7 +126,7 @@ static int mtd_cls_resume(struct device *dev)
 {
 	struct mtd_info *mtd = dev_get_drvdata(dev);
 
-	if (mtd && mtd->resume)
+	if (mtd)
 		mtd_resume(mtd);
 	return 0;
 }
@@ -610,8 +610,8 @@ int __get_mtd_device(struct mtd_info *mtd)
 	if (!try_module_get(mtd->owner))
 		return -ENODEV;
 
-	if (mtd->get_device) {
-		err = mtd->get_device(mtd);
+	if (mtd->_get_device) {
+		err = mtd->_get_device(mtd);
 
 		if (err) {
 			module_put(mtd->owner);
@@ -675,14 +675,266 @@ void __put_mtd_device(struct mtd_info *mtd)
 	--mtd->usecount;
 	BUG_ON(mtd->usecount < 0);
 
-	if (mtd->put_device)
-		mtd->put_device(mtd);
+	if (mtd->_put_device)
+		mtd->_put_device(mtd);
 
 	module_put(mtd->owner);
 }
 EXPORT_SYMBOL_GPL(__put_mtd_device);
 
 /*
+ * Erase is an asynchronous operation.  Device drivers are supposed
+ * to call instr->callback() whenever the operation completes, even
+ * if it completes with a failure.
+ * Callers are supposed to pass a callback function and wait for it
+ * to be called before writing to the block.
+ */
+int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr)
+		return -EINVAL;
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	if (!instr->len) {
+		instr->state = MTD_ERASE_DONE;
+		mtd_erase_callback(instr);
+		return 0;
+	}
+	return mtd->_erase(mtd, instr);
+}
+EXPORT_SYMBOL_GPL(mtd_erase);
+
+/*
+ * This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
+ */
+int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+	      void **virt, resource_size_t *phys)
+{
+	*retlen = 0;
+	*virt = NULL;
+	if (phys)
+		*phys = 0;
+	if (!mtd->_point)
+		return -EOPNOTSUPP;
+	if (from < 0 || from > mtd->size || len > mtd->size - from)
+		return -EINVAL;
+	if (!len)
+		return 0;
+	return mtd->_point(mtd, from, len, retlen, virt, phys);
+}
+EXPORT_SYMBOL_GPL(mtd_point);
+
+/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
+int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+{
+	if (!mtd->_point)
+		return -EOPNOTSUPP;
+	if (from < 0 || from > mtd->size || len > mtd->size - from)
+		return -EINVAL;
+	if (!len)
+		return 0;
+	return mtd->_unpoint(mtd, from, len);
+}
+EXPORT_SYMBOL_GPL(mtd_unpoint);
+
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
+				    unsigned long offset, unsigned long flags)
+{
+	if (!mtd->_get_unmapped_area)
+		return -EOPNOTSUPP;
+	if (offset > mtd->size || len > mtd->size - offset)
+		return -EINVAL;
+	return mtd->_get_unmapped_area(mtd, len, offset, flags);
+}
+EXPORT_SYMBOL_GPL(mtd_get_unmapped_area);
+
+int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+	     u_char *buf)
+{
+	*retlen = 0;
+	if (from < 0 || from > mtd->size || len > mtd->size - from)
+		return -EINVAL;
+	if (!len)
+		return 0;
+	return mtd->_read(mtd, from, len, retlen, buf);
+}
+EXPORT_SYMBOL_GPL(mtd_read);
+
+int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+	      const u_char *buf)
+{
+	*retlen = 0;
+	if (to < 0 || to > mtd->size || len > mtd->size - to)
+		return -EINVAL;
+	if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	if (!len)
+		return 0;
+	return mtd->_write(mtd, to, len, retlen, buf);
+}
+EXPORT_SYMBOL_GPL(mtd_write);
+
+/*
+ * In blackbox flight recorder like scenarios we want to make successful writes
+ * in interrupt context. panic_write() is only intended to be called when its
+ * known the kernel is about to panic and we need the write to succeed. Since
+ * the kernel is not going to be running for much longer, this function can
+ * break locks and delay to ensure the write succeeds (but not sleep).
+ */
+int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+		    const u_char *buf)
+{
+	*retlen = 0;
+	if (!mtd->_panic_write)
+		return -EOPNOTSUPP;
+	if (to < 0 || to > mtd->size || len > mtd->size - to)
+		return -EINVAL;
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	if (!len)
+		return 0;
+	return mtd->_panic_write(mtd, to, len, retlen, buf);
+}
+EXPORT_SYMBOL_GPL(mtd_panic_write);
+
+/*
+ * Method to access the protection register area, present in some flash
+ * devices. The user data is one time programmable but the factory data is read
+ * only.
+ */
+int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+			   size_t len)
+{
+	if (!mtd->_get_fact_prot_info)
+		return -EOPNOTSUPP;
+	if (!len)
+		return 0;
+	return mtd->_get_fact_prot_info(mtd, buf, len);
+}
+EXPORT_SYMBOL_GPL(mtd_get_fact_prot_info);
+
+int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+			   size_t *retlen, u_char *buf)
+{
+	*retlen = 0;
+	if (!mtd->_read_fact_prot_reg)
+		return -EOPNOTSUPP;
+	if (!len)
+		return 0;
+	return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf);
+}
+EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
+
+int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+			   size_t len)
+{
+	if (!mtd->_get_user_prot_info)
+		return -EOPNOTSUPP;
+	if (!len)
+		return 0;
+	return mtd->_get_user_prot_info(mtd, buf, len);
+}
+EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);
+
+int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+			   size_t *retlen, u_char *buf)
+{
+	*retlen = 0;
+	if (!mtd->_read_user_prot_reg)
+		return -EOPNOTSUPP;
+	if (!len)
+		return 0;
+	return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf);
+}
+EXPORT_SYMBOL_GPL(mtd_read_user_prot_reg);
+
+int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
+			    size_t *retlen, u_char *buf)
+{
+	*retlen = 0;
+	if (!mtd->_write_user_prot_reg)
+		return -EOPNOTSUPP;
+	if (!len)
+		return 0;
+	return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
+}
+EXPORT_SYMBOL_GPL(mtd_write_user_prot_reg);
+
+int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
+{
+	if (!mtd->_lock_user_prot_reg)
+		return -EOPNOTSUPP;
+	if (!len)
+		return 0;
+	return mtd->_lock_user_prot_reg(mtd, from, len);
+}
+EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg);
+
+/* Chip-supported device locking */
+int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+	if (!mtd->_lock)
+		return -EOPNOTSUPP;
+	if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
+		return -EINVAL;
+	if (!len)
+		return 0;
+	return mtd->_lock(mtd, ofs, len);
+}
+EXPORT_SYMBOL_GPL(mtd_lock);
+
+int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+	if (!mtd->_unlock)
+		return -EOPNOTSUPP;
+	if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
+		return -EINVAL;
+	if (!len)
+		return 0;
+	return mtd->_unlock(mtd, ofs, len);
+}
+EXPORT_SYMBOL_GPL(mtd_unlock);
+
+int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+	if (!mtd->_is_locked)
+		return -EOPNOTSUPP;
+	if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
+		return -EINVAL;
+	if (!len)
+		return 0;
+	return mtd->_is_locked(mtd, ofs, len);
+}
+EXPORT_SYMBOL_GPL(mtd_is_locked);
+
+int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
+{
+	if (!mtd->_block_isbad)
+		return 0;
+	if (ofs < 0 || ofs > mtd->size)
+		return -EINVAL;
+	return mtd->_block_isbad(mtd, ofs);
+}
+EXPORT_SYMBOL_GPL(mtd_block_isbad);
+
+int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+	if (!mtd->_block_markbad)
+		return -EOPNOTSUPP;
+	if (ofs < 0 || ofs > mtd->size)
+		return -EINVAL;
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	return mtd->_block_markbad(mtd, ofs);
+}
+EXPORT_SYMBOL_GPL(mtd_block_markbad);
+
+/*
  * default_mtd_writev - the default writev method
  * @mtd: mtd device description object pointer
  * @vecs: the vectors to write
@@ -729,9 +981,11 @@ int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
 	       unsigned long count, loff_t to, size_t *retlen)
 {
 	*retlen = 0;
-	if (!mtd->writev)
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	if (!mtd->_writev)
 		return default_mtd_writev(mtd, vecs, count, to, retlen);
-	return mtd->writev(mtd, vecs, count, to, retlen);
+	return mtd->_writev(mtd, vecs, count, to, retlen);
 }
 EXPORT_SYMBOL_GPL(mtd_writev);
 
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 3ce99e0..ae36d7e 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -169,7 +169,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
 			cxt->nextpage = 0;
 	}
 
-	while (mtd_can_have_bb(mtd)) {
+	while (1) {
 		ret = mtd_block_isbad(mtd, cxt->nextpage * record_size);
 		if (!ret)
 			break;
@@ -199,9 +199,9 @@ badblock:
 		return;
 	}
 
-	if (mtd_can_have_bb(mtd) && ret == -EIO) {
+	if (ret == -EIO) {
 		ret = mtd_block_markbad(mtd, cxt->nextpage * record_size);
-		if (ret < 0) {
+		if (ret < 0 && ret != -EOPNOTSUPP) {
 			printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n");
 			return;
 		}
@@ -257,8 +257,7 @@ static void find_next_position(struct mtdoops_context *cxt)
 	size_t retlen;
 
 	for (page = 0; page < cxt->oops_pages; page++) {
-		if (mtd_can_have_bb(mtd) &&
-		    mtd_block_isbad(mtd, page * record_size))
+		if (mtd_block_isbad(mtd, page * record_size))
 			continue;
 		/* Assume the page is used */
 		mark_page_used(cxt, page);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index a3d44c3..33d32c6 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -65,11 +65,6 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
 	int res;
 
 	stats = part->master->ecc_stats;
-
-	if (from >= mtd->size)
-		len = 0;
-	else if (from + len > mtd->size)
-		len = mtd->size - from;
 	res = mtd_read(part->master, from + part->offset, len, retlen, buf);
 	if (unlikely(res)) {
 		if (mtd_is_bitflip(res))
@@ -84,19 +79,16 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len,
 		size_t *retlen, void **virt, resource_size_t *phys)
 {
 	struct mtd_part *part = PART(mtd);
-	if (from >= mtd->size)
-		len = 0;
-	else if (from + len > mtd->size)
-		len = mtd->size - from;
+
 	return mtd_point(part->master, from + part->offset, len, retlen,
 			 virt, phys);
 }
 
-static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
 {
 	struct mtd_part *part = PART(mtd);
 
-	mtd_unpoint(part->master, from + part->offset, len);
+	return mtd_unpoint(part->master, from + part->offset, len);
 }
 
 static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
@@ -180,12 +172,6 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
 	struct mtd_part *part = PART(mtd);
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-	if (to >= mtd->size)
-		len = 0;
-	else if (to + len > mtd->size)
-		len = mtd->size - to;
 	return mtd_write(part->master, to + part->offset, len, retlen, buf);
 }
 
@@ -193,12 +179,6 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 		size_t *retlen, const u_char *buf)
 {
 	struct mtd_part *part = PART(mtd);
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-	if (to >= mtd->size)
-		len = 0;
-	else if (to + len > mtd->size)
-		len = mtd->size - to;
 	return mtd_panic_write(part->master, to + part->offset, len, retlen,
 			       buf);
 }
@@ -208,9 +188,6 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
 {
 	struct mtd_part *part = PART(mtd);
 
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-
 	if (to >= mtd->size)
 		return -EINVAL;
 	if (ops->datbuf && to + ops->len > mtd->size)
@@ -236,8 +213,6 @@ static int part_writev(struct mtd_info *mtd, const struct kvec *vecs,
 		unsigned long count, loff_t to, size_t *retlen)
 {
 	struct mtd_part *part = PART(mtd);
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
 	return mtd_writev(part->master, vecs, count, to + part->offset,
 			  retlen);
 }
@@ -246,10 +221,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	struct mtd_part *part = PART(mtd);
 	int ret;
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-	if (instr->addr >= mtd->size)
-		return -EINVAL;
+
 	instr->addr += part->offset;
 	ret = mtd_erase(part->master, instr);
 	if (ret) {
@@ -262,7 +234,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 void mtd_erase_callback(struct erase_info *instr)
 {
-	if (instr->mtd->erase == part_erase) {
+	if (instr->mtd->_erase == part_erase) {
 		struct mtd_part *part = PART(instr->mtd);
 
 		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
@@ -277,24 +249,18 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
 static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
 	struct mtd_part *part = PART(mtd);
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
 	return mtd_lock(part->master, ofs + part->offset, len);
 }
 
 static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
 	struct mtd_part *part = PART(mtd);
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
 	return mtd_unlock(part->master, ofs + part->offset, len);
 }
 
 static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
 	struct mtd_part *part = PART(mtd);
-	if ((len + ofs) > mtd->size)
-		return -EINVAL;
 	return mtd_is_locked(part->master, ofs + part->offset, len);
 }
 
@@ -319,8 +285,6 @@ static void part_resume(struct mtd_info *mtd)
 static int part_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
 	struct mtd_part *part = PART(mtd);
-	if (ofs >= mtd->size)
-		return -EINVAL;
 	ofs += part->offset;
 	return mtd_block_isbad(part->master, ofs);
 }
@@ -330,10 +294,6 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	struct mtd_part *part = PART(mtd);
 	int res;
 
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-	if (ofs >= mtd->size)
-		return -EINVAL;
 	ofs += part->offset;
 	res = mtd_block_markbad(part->master, ofs);
 	if (!res)
@@ -410,54 +370,55 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
 	 */
 	slave->mtd.dev.parent = master->dev.parent;
 
-	slave->mtd.read = part_read;
-	slave->mtd.write = part_write;
+	slave->mtd._read = part_read;
+	slave->mtd._write = part_write;
 
-	if (master->panic_write)
-		slave->mtd.panic_write = part_panic_write;
+	if (master->_panic_write)
+		slave->mtd._panic_write = part_panic_write;
 
-	if (master->point && master->unpoint) {
-		slave->mtd.point = part_point;
-		slave->mtd.unpoint = part_unpoint;
+	if (master->_point && master->_unpoint) {
+		slave->mtd._point = part_point;
+		slave->mtd._unpoint = part_unpoint;
 	}
 
-	if (master->get_unmapped_area)
-		slave->mtd.get_unmapped_area = part_get_unmapped_area;
-	if (master->read_oob)
-		slave->mtd.read_oob = part_read_oob;
-	if (master->write_oob)
-		slave->mtd.write_oob = part_write_oob;
-	if (master->read_user_prot_reg)
-		slave->mtd.read_user_prot_reg = part_read_user_prot_reg;
-	if (master->read_fact_prot_reg)
-		slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
-	if (master->write_user_prot_reg)
-		slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
-	if (master->lock_user_prot_reg)
-		slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
-	if (master->get_user_prot_info)
-		slave->mtd.get_user_prot_info = part_get_user_prot_info;
-	if (master->get_fact_prot_info)
-		slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
-	if (master->sync)
-		slave->mtd.sync = part_sync;
-	if (!partno && !master->dev.class && master->suspend && master->resume) {
-			slave->mtd.suspend = part_suspend;
-			slave->mtd.resume = part_resume;
+	if (master->_get_unmapped_area)
+		slave->mtd._get_unmapped_area = part_get_unmapped_area;
+	if (master->_read_oob)
+		slave->mtd._read_oob = part_read_oob;
+	if (master->_write_oob)
+		slave->mtd._write_oob = part_write_oob;
+	if (master->_read_user_prot_reg)
+		slave->mtd._read_user_prot_reg = part_read_user_prot_reg;
+	if (master->_read_fact_prot_reg)
+		slave->mtd._read_fact_prot_reg = part_read_fact_prot_reg;
+	if (master->_write_user_prot_reg)
+		slave->mtd._write_user_prot_reg = part_write_user_prot_reg;
+	if (master->_lock_user_prot_reg)
+		slave->mtd._lock_user_prot_reg = part_lock_user_prot_reg;
+	if (master->_get_user_prot_info)
+		slave->mtd._get_user_prot_info = part_get_user_prot_info;
+	if (master->_get_fact_prot_info)
+		slave->mtd._get_fact_prot_info = part_get_fact_prot_info;
+	if (master->_sync)
+		slave->mtd._sync = part_sync;
+	if (!partno && !master->dev.class && master->_suspend &&
+	    master->_resume) {
+			slave->mtd._suspend = part_suspend;
+			slave->mtd._resume = part_resume;
 	}
-	if (master->writev)
-		slave->mtd.writev = part_writev;
-	if (master->lock)
-		slave->mtd.lock = part_lock;
-	if (master->unlock)
-		slave->mtd.unlock = part_unlock;
-	if (master->is_locked)
-		slave->mtd.is_locked = part_is_locked;
-	if (master->block_isbad)
-		slave->mtd.block_isbad = part_block_isbad;
-	if (master->block_markbad)
-		slave->mtd.block_markbad = part_block_markbad;
-	slave->mtd.erase = part_erase;
+	if (master->_writev)
+		slave->mtd._writev = part_writev;
+	if (master->_lock)
+		slave->mtd._lock = part_lock;
+	if (master->_unlock)
+		slave->mtd._unlock = part_unlock;
+	if (master->_is_locked)
+		slave->mtd._is_locked = part_is_locked;
+	if (master->_block_isbad)
+		slave->mtd._block_isbad = part_block_isbad;
+	if (master->_block_markbad)
+		slave->mtd._block_markbad = part_block_markbad;
+	slave->mtd._erase = part_erase;
 	slave->master = master;
 	slave->offset = part->offset;
 
@@ -549,7 +510,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
 	}
 
 	slave->mtd.ecclayout = master->ecclayout;
-	if (master->block_isbad) {
+	if (master->_block_isbad) {
 		uint64_t offs = 0;
 
 		while (offs < slave->mtd.size) {
@@ -761,7 +722,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
 	for ( ; ret <= 0 && *types; types++) {
 		parser = get_partition_parser(*types);
 		if (!parser && !request_module("%s", *types))
-				parser = get_partition_parser(*types);
+			parser = get_partition_parser(*types);
 		if (!parser)
 			continue;
 		ret = (*parser->parse_fn)(master, pparts, data);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 31b034b..2474733 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -313,6 +313,26 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
 	  load time (assuming you build diskonchip as a module) with the module
 	  parameter "inftl_bbt_write=1".
 
+config MTD_NAND_DOCG4
+	tristate "Support for DiskOnChip G4 (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	select BCH
+	select BITREVERSE
+	help
+	  Support for diskonchip G4 nand flash, found in various smartphones and
+	  PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba
+	  Portege G900, Asus P526, and O2 XDA Zinc.
+
+	  With this driver you will be able to use UBI and create a ubifs on the
+	  device, so you may wish to consider enabling UBI and UBIFS as well.
+
+	  These devices ship with the Mys/Sandisk SAFTL formatting, for which
+	  there is currently no mtd parser, so you may want to use command line
+	  partitioning to segregate write-protected blocks.  On the Treo680, the
+	  first five erase blocks (256K each) are write-protected, followed by
+	  the block containing the saftl partition table.  This is probably
+	  typical.
+
 config MTD_NAND_SHARPSL
 	tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
 	depends on ARCH_PXA
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 618f4ba..36c26ab 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)	+= ppchameleonevb.o
 obj-$(CONFIG_MTD_NAND_S3C2410)		+= s3c2410.o
 obj-$(CONFIG_MTD_NAND_DAVINCI)		+= davinci_nand.o
 obj-$(CONFIG_MTD_NAND_DISKONCHIP)	+= diskonchip.o
+obj-$(CONFIG_MTD_NAND_DOCG4)		+= docg4.o
 obj-$(CONFIG_MTD_NAND_FSMC)		+= fsmc_nand.o
 obj-$(CONFIG_MTD_NAND_H1900)		+= h1910.o
 obj-$(CONFIG_MTD_NAND_RTC_FROM4)	+= rtc_from4.o
diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c
index 6a5ff64..ac38f73 100644
--- a/drivers/mtd/nand/alauda.c
+++ b/drivers/mtd/nand/alauda.c
@@ -585,10 +585,10 @@ static int alauda_init_media(struct alauda *al)
 	mtd->writesize = 1<<card->pageshift;
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->read = alauda_read;
-	mtd->write = alauda_write;
-	mtd->erase = alauda_erase;
-	mtd->block_isbad = alauda_isbad;
+	mtd->_read = alauda_read;
+	mtd->_write = alauda_write;
+	mtd->_erase = alauda_erase;
+	mtd->_block_isbad = alauda_isbad;
 	mtd->priv = al;
 	mtd->owner = THIS_MODULE;
 
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
new file mode 100644
index 0000000..8a0d7f6
--- /dev/null
+++ b/drivers/mtd/nand/docg4.c
@@ -0,0 +1,1378 @@
+/*
+ * drivers/mtd/nand/docg4.c
+ *
+ *  Copyright (C) 2012 Mike Dunn <mikedunn@newsguy.com>
+ *
+ * mtd nand driver for M-Systems DiskOnChip G4
+ *
+ * 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.
+ *
+ * Tested on the Palm Treo 680.  The G4 is also present on Toshiba Portege, Asus
+ * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others.
+ * Should work on these as well.  Let me know!
+ *
+ * TODO:
+ *
+ *  Mechanism for management of password-protected areas
+ *
+ *  Hamming ecc when reading oob only
+ *
+ *  According to the M-Sys documentation, this device is also available in a
+ *  "dual-die" configuration having a 256MB capacity, but no mechanism for
+ *  detecting this variant is documented.  Currently this driver assumes 128MB
+ *  capacity.
+ *
+ *  Support for multiple cascaded devices ("floors").  Not sure which gadgets
+ *  contain multiple G4s in a cascaded configuration, if any.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/bch.h>
+#include <linux/bitrev.h>
+
+/*
+ * You'll want to ignore badblocks if you're reading a partition that contains
+ * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since
+ * it does not use mtd nand's method for marking bad blocks (using oob area).
+ * This will also skip the check of the "page written" flag.
+ */
+static bool ignore_badblocks;
+module_param(ignore_badblocks, bool, 0);
+MODULE_PARM_DESC(ignore_badblocks, "no badblock checking performed");
+
+struct docg4_priv {
+	struct mtd_info	*mtd;
+	struct device *dev;
+	void __iomem *virtadr;
+	int status;
+	struct {
+		unsigned int command;
+		int column;
+		int page;
+	} last_command;
+	uint8_t oob_buf[16];
+	uint8_t ecc_buf[7];
+	int oob_page;
+	struct bch_control *bch;
+};
+
+/*
+ * Defines prefixed with DOCG4 are unique to the diskonchip G4.  All others are
+ * shared with other diskonchip devices (P3, G3 at least).
+ *
+ * Functions with names prefixed with docg4_ are mtd / nand interface functions
+ * (though they may also be called internally).  All others are internal.
+ */
+
+#define DOC_IOSPACE_DATA		0x0800
+
+/* register offsets */
+#define DOC_CHIPID			0x1000
+#define DOC_DEVICESELECT		0x100a
+#define DOC_ASICMODE			0x100c
+#define DOC_DATAEND			0x101e
+#define DOC_NOP				0x103e
+
+#define DOC_FLASHSEQUENCE		0x1032
+#define DOC_FLASHCOMMAND		0x1034
+#define DOC_FLASHADDRESS		0x1036
+#define DOC_FLASHCONTROL		0x1038
+#define DOC_ECCCONF0			0x1040
+#define DOC_ECCCONF1			0x1042
+#define DOC_HAMMINGPARITY		0x1046
+#define DOC_BCH_SYNDROM(idx)		(0x1048 + idx)
+
+#define DOC_ASICMODECONFIRM		0x1072
+#define DOC_CHIPID_INV			0x1074
+#define DOC_POWERMODE			0x107c
+
+#define DOCG4_MYSTERY_REG		0x1050
+
+/* apparently used only to write oob bytes 6 and 7 */
+#define DOCG4_OOB_6_7			0x1052
+
+/* DOC_FLASHSEQUENCE register commands */
+#define DOC_SEQ_RESET			0x00
+#define DOCG4_SEQ_PAGE_READ		0x03
+#define DOCG4_SEQ_FLUSH			0x29
+#define DOCG4_SEQ_PAGEWRITE		0x16
+#define DOCG4_SEQ_PAGEPROG		0x1e
+#define DOCG4_SEQ_BLOCKERASE		0x24
+
+/* DOC_FLASHCOMMAND register commands */
+#define DOCG4_CMD_PAGE_READ             0x00
+#define DOC_CMD_ERASECYCLE2		0xd0
+#define DOCG4_CMD_FLUSH                 0x70
+#define DOCG4_CMD_READ2                 0x30
+#define DOC_CMD_PROG_BLOCK_ADDR		0x60
+#define DOCG4_CMD_PAGEWRITE		0x80
+#define DOC_CMD_PROG_CYCLE2		0x10
+#define DOC_CMD_RESET			0xff
+
+/* DOC_POWERMODE register bits */
+#define DOC_POWERDOWN_READY		0x80
+
+/* DOC_FLASHCONTROL register bits */
+#define DOC_CTRL_CE			0x10
+#define DOC_CTRL_UNKNOWN		0x40
+#define DOC_CTRL_FLASHREADY		0x01
+
+/* DOC_ECCCONF0 register bits */
+#define DOC_ECCCONF0_READ_MODE		0x8000
+#define DOC_ECCCONF0_UNKNOWN		0x2000
+#define DOC_ECCCONF0_ECC_ENABLE	        0x1000
+#define DOC_ECCCONF0_DATA_BYTES_MASK	0x07ff
+
+/* DOC_ECCCONF1 register bits */
+#define DOC_ECCCONF1_BCH_SYNDROM_ERR	0x80
+#define DOC_ECCCONF1_ECC_ENABLE         0x07
+#define DOC_ECCCONF1_PAGE_IS_WRITTEN	0x20
+
+/* DOC_ASICMODE register bits */
+#define DOC_ASICMODE_RESET		0x00
+#define DOC_ASICMODE_NORMAL		0x01
+#define DOC_ASICMODE_POWERDOWN		0x02
+#define DOC_ASICMODE_MDWREN		0x04
+#define DOC_ASICMODE_BDETCT_RESET	0x08
+#define DOC_ASICMODE_RSTIN_RESET	0x10
+#define DOC_ASICMODE_RAM_WE		0x20
+
+/* good status values read after read/write/erase operations */
+#define DOCG4_PROGSTATUS_GOOD          0x51
+#define DOCG4_PROGSTATUS_GOOD_2        0xe0
+
+/*
+ * On read operations (page and oob-only), the first byte read from I/O reg is a
+ * status.  On error, it reads 0x73; otherwise, it reads either 0x71 (first read
+ * after reset only) or 0x51, so bit 1 is presumed to be an error indicator.
+ */
+#define DOCG4_READ_ERROR           0x02 /* bit 1 indicates read error */
+
+/* anatomy of the device */
+#define DOCG4_CHIP_SIZE        0x8000000
+#define DOCG4_PAGE_SIZE        0x200
+#define DOCG4_PAGES_PER_BLOCK  0x200
+#define DOCG4_BLOCK_SIZE       (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE)
+#define DOCG4_NUMBLOCKS        (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE)
+#define DOCG4_OOB_SIZE         0x10
+#define DOCG4_CHIP_SHIFT       27    /* log_2(DOCG4_CHIP_SIZE) */
+#define DOCG4_PAGE_SHIFT       9     /* log_2(DOCG4_PAGE_SIZE) */
+#define DOCG4_ERASE_SHIFT      18    /* log_2(DOCG4_BLOCK_SIZE) */
+
+/* all but the last byte is included in ecc calculation */
+#define DOCG4_BCH_SIZE         (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1)
+
+#define DOCG4_USERDATA_LEN     520 /* 512 byte page plus 8 oob avail to user */
+
+/* expected values from the ID registers */
+#define DOCG4_IDREG1_VALUE     0x0400
+#define DOCG4_IDREG2_VALUE     0xfbff
+
+/* primitive polynomial used to build the Galois field used by hw ecc gen */
+#define DOCG4_PRIMITIVE_POLY   0x4443
+
+#define DOCG4_M                14  /* Galois field is of order 2^14 */
+#define DOCG4_T                4   /* BCH alg corrects up to 4 bit errors */
+
+#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */
+
+/*
+ * Oob bytes 0 - 6 are available to the user.
+ * Byte 7 is hamming ecc for first 7 bytes.  Bytes 8 - 14 are hw-generated ecc.
+ * Byte 15 (the last) is used by the driver as a "page written" flag.
+ */
+static struct nand_ecclayout docg4_oobinfo = {
+	.eccbytes = 9,
+	.eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
+	.oobavail = 7,
+	.oobfree = { {0, 7} }
+};
+
+/*
+ * The device has a nop register which M-Sys claims is for the purpose of
+ * inserting precise delays.  But beware; at least some operations fail if the
+ * nop writes are replaced with a generic delay!
+ */
+static inline void write_nop(void __iomem *docptr)
+{
+	writew(0, docptr + DOC_NOP);
+}
+
+static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *nand = mtd->priv;
+	uint16_t *p = (uint16_t *) buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		p[i] = readw(nand->IO_ADDR_R);
+}
+
+static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *nand = mtd->priv;
+	uint16_t *p = (uint16_t *) buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		writew(p[i], nand->IO_ADDR_W);
+}
+
+static int poll_status(struct docg4_priv *doc)
+{
+	/*
+	 * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
+	 * register.  Operations known to take a long time (e.g., block erase)
+	 * should sleep for a while before calling this.
+	 */
+
+	uint16_t flash_status;
+	unsigned int timeo;
+	void __iomem *docptr = doc->virtadr;
+
+	dev_dbg(doc->dev, "%s...\n", __func__);
+
+	/* hardware quirk requires reading twice initially */
+	flash_status = readw(docptr + DOC_FLASHCONTROL);
+
+	timeo = 1000;
+	do {
+		cpu_relax();
+		flash_status = readb(docptr + DOC_FLASHCONTROL);
+	} while (!(flash_status & DOC_CTRL_FLASHREADY) && --timeo);
+
+
+	if (!timeo) {
+		dev_err(doc->dev, "%s: timed out!\n", __func__);
+		return NAND_STATUS_FAIL;
+	}
+
+	if (unlikely(timeo < 50))
+		dev_warn(doc->dev, "%s: nearly timed out; %d remaining\n",
+			 __func__, timeo);
+
+	return 0;
+}
+
+
+static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand)
+{
+
+	struct docg4_priv *doc = nand->priv;
+	int status = NAND_STATUS_WP;       /* inverse logic?? */
+	dev_dbg(doc->dev, "%s...\n", __func__);
+
+	/* report any previously unreported error */
+	if (doc->status) {
+		status |= doc->status;
+		doc->status = 0;
+		return status;
+	}
+
+	status |= poll_status(doc);
+	return status;
+}
+
+static void docg4_select_chip(struct mtd_info *mtd, int chip)
+{
+	/*
+	 * Select among multiple cascaded chips ("floors").  Multiple floors are
+	 * not yet supported, so the only valid non-negative value is 0.
+	 */
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+
+	dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip);
+
+	if (chip < 0)
+		return;		/* deselected */
+
+	if (chip > 0)
+		dev_warn(doc->dev, "multiple floors currently unsupported\n");
+
+	writew(0, docptr + DOC_DEVICESELECT);
+}
+
+static void reset(struct mtd_info *mtd)
+{
+	/* full device reset */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+
+	writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN,
+	       docptr + DOC_ASICMODE);
+	writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN),
+	       docptr + DOC_ASICMODECONFIRM);
+	write_nop(docptr);
+
+	writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN,
+	       docptr + DOC_ASICMODE);
+	writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN),
+	       docptr + DOC_ASICMODECONFIRM);
+
+	writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1);
+
+	poll_status(doc);
+}
+
+static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf)
+{
+	/* read the 7 hw-generated ecc bytes */
+
+	int i;
+	for (i = 0; i < 7; i++) { /* hw quirk; read twice */
+		ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i));
+		ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i));
+	}
+}
+
+static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page)
+{
+	/*
+	 * Called after a page read when hardware reports bitflips.
+	 * Up to four bitflips can be corrected.
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	int i, numerrs, errpos[4];
+	const uint8_t blank_read_hwecc[8] = {
+		0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 };
+
+	read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */
+
+	/* check if read error is due to a blank page */
+	if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7))
+		return 0;	/* yes */
+
+	/* skip additional check of "written flag" if ignore_badblocks */
+	if (ignore_badblocks == false) {
+
+		/*
+		 * If the hw ecc bytes are not those of a blank page, there's
+		 * still a chance that the page is blank, but was read with
+		 * errors.  Check the "written flag" in last oob byte, which
+		 * is set to zero when a page is written.  If more than half
+		 * the bits are set, assume a blank page.  Unfortunately, the
+		 * bit flips(s) are not reported in stats.
+		 */
+
+		if (doc->oob_buf[15]) {
+			int bit, numsetbits = 0;
+			unsigned long written_flag = doc->oob_buf[15];
+			for_each_set_bit(bit, &written_flag, 8)
+				numsetbits++;
+			if (numsetbits > 4) { /* assume blank */
+				dev_warn(doc->dev,
+					 "error(s) in blank page "
+					 "at offset %08x\n",
+					 page * DOCG4_PAGE_SIZE);
+				return 0;
+			}
+		}
+	}
+
+	/*
+	 * The hardware ecc unit produces oob_ecc ^ calc_ecc.  The kernel's bch
+	 * algorithm is used to decode this.  However the hw operates on page
+	 * data in a bit order that is the reverse of that of the bch alg,
+	 * requiring that the bits be reversed on the result.  Thanks to Ivan
+	 * Djelic for his analysis!
+	 */
+	for (i = 0; i < 7; i++)
+		doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]);
+
+	numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL,
+			     doc->ecc_buf, NULL, errpos);
+
+	if (numerrs == -EBADMSG) {
+		dev_warn(doc->dev, "uncorrectable errors at offset %08x\n",
+			 page * DOCG4_PAGE_SIZE);
+		return -EBADMSG;
+	}
+
+	BUG_ON(numerrs < 0);	/* -EINVAL, or anything other than -EBADMSG */
+
+	/* undo last step in BCH alg (modulo mirroring not needed) */
+	for (i = 0; i < numerrs; i++)
+		errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7));
+
+	/* fix the errors */
+	for (i = 0; i < numerrs; i++) {
+
+		/* ignore if error within oob ecc bytes */
+		if (errpos[i] > DOCG4_USERDATA_LEN * 8)
+			continue;
+
+		/* if error within oob area preceeding ecc bytes... */
+		if (errpos[i] > DOCG4_PAGE_SIZE * 8)
+			change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8,
+				   (unsigned long *)doc->oob_buf);
+
+		else    /* error in page data */
+			change_bit(errpos[i], (unsigned long *)buf);
+	}
+
+	dev_notice(doc->dev, "%d error(s) corrected at offset %08x\n",
+		   numerrs, page * DOCG4_PAGE_SIZE);
+
+	return numerrs;
+}
+
+static uint8_t docg4_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+
+	dev_dbg(doc->dev, "%s\n", __func__);
+
+	if (doc->last_command.command == NAND_CMD_STATUS) {
+		int status;
+
+		/*
+		 * Previous nand command was status request, so nand
+		 * infrastructure code expects to read the status here.  If an
+		 * error occurred in a previous operation, report it.
+		 */
+		doc->last_command.command = 0;
+
+		if (doc->status) {
+			status = doc->status;
+			doc->status = 0;
+		}
+
+		/* why is NAND_STATUS_WP inverse logic?? */
+		else
+			status = NAND_STATUS_WP | NAND_STATUS_READY;
+
+		return status;
+	}
+
+	dev_warn(doc->dev, "unexpectd call to read_byte()\n");
+
+	return 0;
+}
+
+static void write_addr(struct docg4_priv *doc, uint32_t docg4_addr)
+{
+	/* write the four address bytes packed in docg4_addr to the device */
+
+	void __iomem *docptr = doc->virtadr;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+}
+
+static int read_progstatus(struct docg4_priv *doc)
+{
+	/*
+	 * This apparently checks the status of programming.  Done after an
+	 * erasure, and after page data is written.  On error, the status is
+	 * saved, to be later retrieved by the nand infrastructure code.
+	 */
+	void __iomem *docptr = doc->virtadr;
+
+	/* status is read from the I/O reg */
+	uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA);
+	uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA);
+	uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG);
+
+	dev_dbg(doc->dev, "docg4: %s: %02x %02x %02x\n",
+	      __func__, status1, status2, status3);
+
+	if (status1 != DOCG4_PROGSTATUS_GOOD
+	    || status2 != DOCG4_PROGSTATUS_GOOD_2
+	    || status3 != DOCG4_PROGSTATUS_GOOD_2) {
+		doc->status = NAND_STATUS_FAIL;
+		dev_warn(doc->dev, "read_progstatus failed: "
+			 "%02x, %02x, %02x\n", status1, status2, status3);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int pageprog(struct mtd_info *mtd)
+{
+	/*
+	 * Final step in writing a page.  Writes the contents of its
+	 * internal buffer out to the flash array, or some such.
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	int retval = 0;
+
+	dev_dbg(doc->dev, "docg4: %s\n", __func__);
+
+	writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* Just busy-wait; usleep_range() slows things down noticeably. */
+	poll_status(doc);
+
+	writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND);
+	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	retval = read_progstatus(doc);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+	poll_status(doc);
+	write_nop(docptr);
+
+	return retval;
+}
+
+static void sequence_reset(struct mtd_info *mtd)
+{
+	/* common starting sequence for all operations */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+
+	writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL);
+	writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+	poll_status(doc);
+	write_nop(docptr);
+}
+
+static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr)
+{
+	/* first step in reading a page */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+
+	dev_dbg(doc->dev,
+	      "docg4: %s: g4 page %08x\n", __func__, docg4_addr);
+
+	sequence_reset(mtd);
+
+	writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+
+	write_addr(doc, docg4_addr);
+
+	write_nop(docptr);
+	writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	poll_status(doc);
+}
+
+static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr)
+{
+	/* first step in writing a page */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+
+	dev_dbg(doc->dev,
+	      "docg4: %s: g4 addr: %x\n", __func__, docg4_addr);
+	sequence_reset(mtd);
+	writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_addr(doc, docg4_addr);
+	write_nop(docptr);
+	write_nop(docptr);
+	poll_status(doc);
+}
+
+static uint32_t mtd_to_docg4_address(int page, int column)
+{
+	/*
+	 * Convert mtd address to format used by the device, 32 bit packed.
+	 *
+	 * Some notes on G4 addressing... The M-Sys documentation on this device
+	 * claims that pages are 2K in length, and indeed, the format of the
+	 * address used by the device reflects that.  But within each page are
+	 * four 512 byte "sub-pages", each with its own oob data that is
+	 * read/written immediately after the 512 bytes of page data.  This oob
+	 * data contains the ecc bytes for the preceeding 512 bytes.
+	 *
+	 * Rather than tell the mtd nand infrastructure that page size is 2k,
+	 * with four sub-pages each, we engage in a little subterfuge and tell
+	 * the infrastructure code that pages are 512 bytes in size.  This is
+	 * done because during the course of reverse-engineering the device, I
+	 * never observed an instance where an entire 2K "page" was read or
+	 * written as a unit.  Each "sub-page" is always addressed individually,
+	 * its data read/written, and ecc handled before the next "sub-page" is
+	 * addressed.
+	 *
+	 * This requires us to convert addresses passed by the mtd nand
+	 * infrastructure code to those used by the device.
+	 *
+	 * The address that is written to the device consists of four bytes: the
+	 * first two are the 2k page number, and the second is the index into
+	 * the page.  The index is in terms of 16-bit half-words and includes
+	 * the preceeding oob data, so e.g., the index into the second
+	 * "sub-page" is 0x108, and the full device address of the start of mtd
+	 * page 0x201 is 0x00800108.
+	 */
+	int g4_page = page / 4;	                      /* device's 2K page */
+	int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */
+	return (g4_page << 16) | g4_index;	      /* pack */
+}
+
+static void docg4_command(struct mtd_info *mtd, unsigned command, int column,
+			  int page_addr)
+{
+	/* handle standard nand commands */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	uint32_t g4_addr = mtd_to_docg4_address(page_addr, column);
+
+	dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n",
+	      __func__, command, page_addr, column);
+
+	/*
+	 * Save the command and its arguments.  This enables emulation of
+	 * standard flash devices, and also some optimizations.
+	 */
+	doc->last_command.command = command;
+	doc->last_command.column = column;
+	doc->last_command.page = page_addr;
+
+	switch (command) {
+
+	case NAND_CMD_RESET:
+		reset(mtd);
+		break;
+
+	case NAND_CMD_READ0:
+		read_page_prologue(mtd, g4_addr);
+		break;
+
+	case NAND_CMD_STATUS:
+		/* next call to read_byte() will expect a status */
+		break;
+
+	case NAND_CMD_SEQIN:
+		write_page_prologue(mtd, g4_addr);
+
+		/* hack for deferred write of oob bytes */
+		if (doc->oob_page == page_addr)
+			memcpy(nand->oob_poi, doc->oob_buf, 16);
+		break;
+
+	case NAND_CMD_PAGEPROG:
+		pageprog(mtd);
+		break;
+
+	/* we don't expect these, based on review of nand_base.c */
+	case NAND_CMD_READOOB:
+	case NAND_CMD_READID:
+	case NAND_CMD_ERASE1:
+	case NAND_CMD_ERASE2:
+		dev_warn(doc->dev, "docg4_command: "
+			 "unexpected nand command 0x%x\n", command);
+		break;
+
+	}
+}
+
+static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
+		     uint8_t *buf, int page, bool use_ecc)
+{
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	uint16_t status, edc_err, *buf16;
+
+	dev_dbg(doc->dev, "%s: page %08x\n", __func__, page);
+
+	writew(DOC_ECCCONF0_READ_MODE |
+	       DOC_ECCCONF0_ECC_ENABLE |
+	       DOC_ECCCONF0_UNKNOWN |
+	       DOCG4_BCH_SIZE,
+	       docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* the 1st byte from the I/O reg is a status; the rest is page data */
+	status = readw(docptr + DOC_IOSPACE_DATA);
+	if (status & DOCG4_READ_ERROR) {
+		dev_err(doc->dev,
+			"docg4_read_page: bad status: 0x%02x\n", status);
+		writew(0, docptr + DOC_DATAEND);
+		return -EIO;
+	}
+
+	dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status);
+
+	docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */
+
+	/*
+	 * Diskonchips read oob immediately after a page read.  Mtd
+	 * infrastructure issues a separate command for reading oob after the
+	 * page is read.  So we save the oob bytes in a local buffer and just
+	 * copy it if the next command reads oob from the same page.
+	 */
+
+	/* first 14 oob bytes read from I/O reg */
+	docg4_read_buf(mtd, doc->oob_buf, 14);
+
+	/* last 2 read from another reg */
+	buf16 = (uint16_t *)(doc->oob_buf + 14);
+	*buf16 = readw(docptr + DOCG4_MYSTERY_REG);
+
+	write_nop(docptr);
+
+	if (likely(use_ecc == true)) {
+
+		/* read the register that tells us if bitflip(s) detected  */
+		edc_err = readw(docptr + DOC_ECCCONF1);
+		edc_err = readw(docptr + DOC_ECCCONF1);
+		dev_dbg(doc->dev, "%s: edc_err = 0x%02x\n", __func__, edc_err);
+
+		/* If bitflips are reported, attempt to correct with ecc */
+		if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) {
+			int bits_corrected = correct_data(mtd, buf, page);
+			if (bits_corrected == -EBADMSG)
+				mtd->ecc_stats.failed++;
+			else
+				mtd->ecc_stats.corrected += bits_corrected;
+		}
+	}
+
+	writew(0, docptr + DOC_DATAEND);
+	return 0;
+}
+
+
+static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+			       uint8_t *buf, int page)
+{
+	return read_page(mtd, nand, buf, page, false);
+}
+
+static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
+			   uint8_t *buf, int page)
+{
+	return read_page(mtd, nand, buf, page, true);
+}
+
+static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
+			  int page, int sndcmd)
+{
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	uint16_t status;
+
+	dev_dbg(doc->dev, "%s: page %x\n", __func__, page);
+
+	/*
+	 * Oob bytes are read as part of a normal page read.  If the previous
+	 * nand command was a read of the page whose oob is now being read, just
+	 * copy the oob bytes that we saved in a local buffer and avoid a
+	 * separate oob read.
+	 */
+	if (doc->last_command.command == NAND_CMD_READ0 &&
+	    doc->last_command.page == page) {
+		memcpy(nand->oob_poi, doc->oob_buf, 16);
+		return 0;
+	}
+
+	/*
+	 * Separate read of oob data only.
+	 */
+	docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page);
+
+	writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* the 1st byte from the I/O reg is a status; the rest is oob data */
+	status = readw(docptr + DOC_IOSPACE_DATA);
+	if (status & DOCG4_READ_ERROR) {
+		dev_warn(doc->dev,
+			 "docg4_read_oob failed: status = 0x%02x\n", status);
+		return -EIO;
+	}
+
+	dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status);
+
+	docg4_read_buf(mtd, nand->oob_poi, 16);
+
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+
+	return 0;
+}
+
+static void docg4_erase_block(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	uint16_t g4_page;
+
+	dev_dbg(doc->dev, "%s: page %04x\n", __func__, page);
+
+	sequence_reset(mtd);
+
+	writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+
+	/* only 2 bytes of address are written to specify erase block */
+	g4_page = (uint16_t)(page / 4);  /* to g4's 2k page addressing */
+	writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS);
+	g4_page >>= 8;
+	writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS);
+	write_nop(docptr);
+
+	/* start the erasure */
+	writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	usleep_range(500, 1000); /* erasure is long; take a snooze */
+	poll_status(doc);
+	writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND);
+	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	read_progstatus(doc);
+
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+	poll_status(doc);
+	write_nop(docptr);
+}
+
+static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+		       const uint8_t *buf, bool use_ecc)
+{
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	uint8_t ecc_buf[8];
+
+	dev_dbg(doc->dev, "%s...\n", __func__);
+
+	writew(DOC_ECCCONF0_ECC_ENABLE |
+	       DOC_ECCCONF0_UNKNOWN |
+	       DOCG4_BCH_SIZE,
+	       docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+
+	/* write the page data */
+	docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE);
+
+	/* oob bytes 0 through 5 are written to I/O reg */
+	docg4_write_buf16(mtd, nand->oob_poi, 6);
+
+	/* oob byte 6 written to a separate reg */
+	writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7);
+
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* write hw-generated ecc bytes to oob */
+	if (likely(use_ecc == true)) {
+		/* oob byte 7 is hamming code */
+		uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY);
+		hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */
+		writew(hamming, docptr + DOCG4_OOB_6_7);
+		write_nop(docptr);
+
+		/* read the 7 bch bytes from ecc regs */
+		read_hw_ecc(docptr, ecc_buf);
+		ecc_buf[7] = 0;         /* clear the "page written" flag */
+	}
+
+	/* write user-supplied bytes to oob */
+	else {
+		writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7);
+		write_nop(docptr);
+		memcpy(ecc_buf, &nand->oob_poi[8], 8);
+	}
+
+	docg4_write_buf16(mtd, ecc_buf, 8);
+	write_nop(docptr);
+	write_nop(docptr);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+}
+
+static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+				 const uint8_t *buf)
+{
+	return write_page(mtd, nand, buf, false);
+}
+
+static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+			     const uint8_t *buf)
+{
+	return write_page(mtd, nand, buf, true);
+}
+
+static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
+			   int page)
+{
+	/*
+	 * Writing oob-only is not really supported, because MLC nand must write
+	 * oob bytes at the same time as page data.  Nonetheless, we save the
+	 * oob buffer contents here, and then write it along with the page data
+	 * if the same page is subsequently written.  This allows user space
+	 * utilities that write the oob data prior to the page data to work
+	 * (e.g., nandwrite).  The disdvantage is that, if the intention was to
+	 * write oob only, the operation is quietly ignored.  Also, oob can get
+	 * corrupted if two concurrent processes are running nandwrite.
+	 */
+
+	/* note that bytes 7..14 are hw generated hamming/ecc and overwritten */
+	struct docg4_priv *doc = nand->priv;
+	doc->oob_page = page;
+	memcpy(doc->oob_buf, nand->oob_poi, 16);
+	return 0;
+}
+
+static int __init read_factory_bbt(struct mtd_info *mtd)
+{
+	/*
+	 * The device contains a read-only factory bad block table.  Read it and
+	 * update the memory-based bbt accordingly.
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);
+	uint8_t *buf;
+	int i, block, status;
+
+	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	read_page_prologue(mtd, g4_addr);
+	status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE);
+	if (status)
+		goto exit;
+
+	/*
+	 * If no memory-based bbt was created, exit.  This will happen if module
+	 * parameter ignore_badblocks is set.  Then why even call this function?
+	 * For an unknown reason, block erase always fails if it's the first
+	 * operation after device power-up.  The above read ensures it never is.
+	 * Ugly, I know.
+	 */
+	if (nand->bbt == NULL)  /* no memory-based bbt */
+		goto exit;
+
+	/*
+	 * Parse factory bbt and update memory-based bbt.  Factory bbt format is
+	 * simple: one bit per block, block numbers increase left to right (msb
+	 * to lsb).  Bit clear means bad block.
+	 */
+	for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) {
+		int bitnum;
+		unsigned long bits = ~buf[i];
+		for_each_set_bit(bitnum, &bits, 8) {
+			int badblock = block + 7 - bitnum;
+			nand->bbt[badblock / 4] |=
+				0x03 << ((badblock % 4) * 2);
+			mtd->ecc_stats.badblocks++;
+			dev_notice(doc->dev, "factory-marked bad block: %d\n",
+				   badblock);
+		}
+	}
+ exit:
+	kfree(buf);
+	return status;
+}
+
+static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+	/*
+	 * Mark a block as bad.  Bad blocks are marked in the oob area of the
+	 * first page of the block.  The default scan_bbt() in the nand
+	 * infrastructure code works fine for building the memory-based bbt
+	 * during initialization, as does the nand infrastructure function that
+	 * checks if a block is bad by reading the bbt.  This function replaces
+	 * the nand default because writes to oob-only are not supported.
+	 */
+
+	int ret, i;
+	uint8_t *buf;
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	struct nand_bbt_descr *bbtd = nand->badblock_pattern;
+	int block = (int)(ofs >> nand->bbt_erase_shift);
+	int page = (int)(ofs >> nand->page_shift);
+	uint32_t g4_addr = mtd_to_docg4_address(page, 0);
+
+	dev_dbg(doc->dev, "%s: %08llx\n", __func__, ofs);
+
+	if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1)))
+		dev_warn(doc->dev, "%s: ofs %llx not start of block!\n",
+			 __func__, ofs);
+
+	/* allocate blank buffer for page data */
+	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	/* update bbt in memory */
+	nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2);
+
+	/* write bit-wise negation of pattern to oob buffer */
+	memset(nand->oob_poi, 0xff, mtd->oobsize);
+	for (i = 0; i < bbtd->len; i++)
+		nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i];
+
+	/* write first page of block */
+	write_page_prologue(mtd, g4_addr);
+	docg4_write_page(mtd, nand, buf);
+	ret = pageprog(mtd);
+	if (!ret)
+		mtd->ecc_stats.badblocks++;
+
+	kfree(buf);
+
+	return ret;
+}
+
+static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+	/* only called when module_param ignore_badblocks is set */
+	return 0;
+}
+
+static int docg4_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	/*
+	 * Put the device into "deep power-down" mode.  Note that CE# must be
+	 * deasserted for this to take effect.  The xscale, e.g., can be
+	 * configured to float this signal when the processor enters power-down,
+	 * and a suitable pull-up ensures its deassertion.
+	 */
+
+	int i;
+	uint8_t pwr_down;
+	struct docg4_priv *doc = platform_get_drvdata(pdev);
+	void __iomem *docptr = doc->virtadr;
+
+	dev_dbg(doc->dev, "%s...\n", __func__);
+
+	/* poll the register that tells us we're ready to go to sleep */
+	for (i = 0; i < 10; i++) {
+		pwr_down = readb(docptr + DOC_POWERMODE);
+		if (pwr_down & DOC_POWERDOWN_READY)
+			break;
+		usleep_range(1000, 4000);
+	}
+
+	if (pwr_down & DOC_POWERDOWN_READY) {
+		dev_err(doc->dev, "suspend failed; "
+			"timeout polling DOC_POWERDOWN_READY\n");
+		return -EIO;
+	}
+
+	writew(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN,
+	       docptr + DOC_ASICMODE);
+	writew(~(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN),
+	       docptr + DOC_ASICMODECONFIRM);
+
+	write_nop(docptr);
+
+	return 0;
+}
+
+static int docg4_resume(struct platform_device *pdev)
+{
+
+	/*
+	 * Exit power-down.  Twelve consecutive reads of the address below
+	 * accomplishes this, assuming CE# has been asserted.
+	 */
+
+	struct docg4_priv *doc = platform_get_drvdata(pdev);
+	void __iomem *docptr = doc->virtadr;
+	int i;
+
+	dev_dbg(doc->dev, "%s...\n", __func__);
+
+	for (i = 0; i < 12; i++)
+		readb(docptr + 0x1fff);
+
+	return 0;
+}
+
+static void __init init_mtd_structs(struct mtd_info *mtd)
+{
+	/* initialize mtd and nand data structures */
+
+	/*
+	 * Note that some of the following initializations are not usually
+	 * required within a nand driver because they are performed by the nand
+	 * infrastructure code as part of nand_scan().  In this case they need
+	 * to be initialized here because we skip call to nand_scan_ident() (the
+	 * first half of nand_scan()).  The call to nand_scan_ident() is skipped
+	 * because for this device the chip id is not read in the manner of a
+	 * standard nand device.  Unfortunately, nand_scan_ident() does other
+	 * things as well, such as call nand_set_defaults().
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+
+	mtd->size = DOCG4_CHIP_SIZE;
+	mtd->name = "Msys_Diskonchip_G4";
+	mtd->writesize = DOCG4_PAGE_SIZE;
+	mtd->erasesize = DOCG4_BLOCK_SIZE;
+	mtd->oobsize = DOCG4_OOB_SIZE;
+	nand->chipsize = DOCG4_CHIP_SIZE;
+	nand->chip_shift = DOCG4_CHIP_SHIFT;
+	nand->bbt_erase_shift = nand->phys_erase_shift = DOCG4_ERASE_SHIFT;
+	nand->chip_delay = 20;
+	nand->page_shift = DOCG4_PAGE_SHIFT;
+	nand->pagemask = 0x3ffff;
+	nand->badblockpos = NAND_LARGE_BADBLOCK_POS;
+	nand->badblockbits = 8;
+	nand->ecc.layout = &docg4_oobinfo;
+	nand->ecc.mode = NAND_ECC_HW_SYNDROME;
+	nand->ecc.size = DOCG4_PAGE_SIZE;
+	nand->ecc.prepad = 8;
+	nand->ecc.bytes	= 8;
+	nand->options =
+		NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
+	nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA;
+	nand->controller = &nand->hwcontrol;
+	spin_lock_init(&nand->controller->lock);
+	init_waitqueue_head(&nand->controller->wq);
+
+	/* methods */
+	nand->cmdfunc = docg4_command;
+	nand->waitfunc = docg4_wait;
+	nand->select_chip = docg4_select_chip;
+	nand->read_byte = docg4_read_byte;
+	nand->block_markbad = docg4_block_markbad;
+	nand->read_buf = docg4_read_buf;
+	nand->write_buf = docg4_write_buf16;
+	nand->scan_bbt = nand_default_bbt;
+	nand->erase_cmd = docg4_erase_block;
+	nand->ecc.read_page = docg4_read_page;
+	nand->ecc.write_page = docg4_write_page;
+	nand->ecc.read_page_raw = docg4_read_page_raw;
+	nand->ecc.write_page_raw = docg4_write_page_raw;
+	nand->ecc.read_oob = docg4_read_oob;
+	nand->ecc.write_oob = docg4_write_oob;
+
+	/*
+	 * The way the nand infrastructure code is written, a memory-based bbt
+	 * is not created if NAND_SKIP_BBTSCAN is set.  With no memory bbt,
+	 * nand->block_bad() is used.  So when ignoring bad blocks, we skip the
+	 * scan and define a dummy block_bad() which always returns 0.
+	 */
+	if (ignore_badblocks) {
+		nand->options |= NAND_SKIP_BBTSCAN;
+		nand->block_bad	= docg4_block_neverbad;
+	}
+
+}
+
+static int __init read_id_reg(struct mtd_info *mtd)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = doc->virtadr;
+	uint16_t id1, id2;
+
+	/* check for presence of g4 chip by reading id registers */
+	id1 = readw(docptr + DOC_CHIPID);
+	id1 = readw(docptr + DOCG4_MYSTERY_REG);
+	id2 = readw(docptr + DOC_CHIPID_INV);
+	id2 = readw(docptr + DOCG4_MYSTERY_REG);
+
+	if (id1 == DOCG4_IDREG1_VALUE && id2 == DOCG4_IDREG2_VALUE) {
+		dev_info(doc->dev,
+			 "NAND device: 128MiB Diskonchip G4 detected\n");
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
+static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL };
+
+static int __init probe_docg4(struct platform_device *pdev)
+{
+	struct mtd_info *mtd;
+	struct nand_chip *nand;
+	void __iomem *virtadr;
+	struct docg4_priv *doc;
+	int len, retval;
+	struct resource *r;
+	struct device *dev = &pdev->dev;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (r == NULL) {
+		dev_err(dev, "no io memory resource defined!\n");
+		return -ENODEV;
+	}
+
+	virtadr = ioremap(r->start, resource_size(r));
+	if (!virtadr) {
+		dev_err(dev, "Diskonchip ioremap failed: %pR\n", r);
+		return -EIO;
+	}
+
+	len = sizeof(struct mtd_info) + sizeof(struct nand_chip) +
+		sizeof(struct docg4_priv);
+	mtd = kzalloc(len, GFP_KERNEL);
+	if (mtd == NULL) {
+		retval = -ENOMEM;
+		goto fail;
+	}
+	nand = (struct nand_chip *) (mtd + 1);
+	doc = (struct docg4_priv *) (nand + 1);
+	mtd->priv = nand;
+	nand->priv = doc;
+	mtd->owner = THIS_MODULE;
+	doc->virtadr = virtadr;
+	doc->dev = dev;
+
+	init_mtd_structs(mtd);
+
+	/* initialize kernel bch algorithm */
+	doc->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY);
+	if (doc->bch == NULL) {
+		retval = -EINVAL;
+		goto fail;
+	}
+
+	platform_set_drvdata(pdev, doc);
+
+	reset(mtd);
+	retval = read_id_reg(mtd);
+	if (retval == -ENODEV) {
+		dev_warn(dev, "No diskonchip G4 device found.\n");
+		goto fail;
+	}
+
+	retval = nand_scan_tail(mtd);
+	if (retval)
+		goto fail;
+
+	retval = read_factory_bbt(mtd);
+	if (retval)
+		goto fail;
+
+	retval = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0);
+	if (retval)
+		goto fail;
+
+	doc->mtd = mtd;
+	return 0;
+
+ fail:
+	iounmap(virtadr);
+	if (mtd) {
+		/* re-declarations avoid compiler warning */
+		struct nand_chip *nand = mtd->priv;
+		struct docg4_priv *doc = nand->priv;
+		nand_release(mtd); /* deletes partitions and mtd devices */
+		platform_set_drvdata(pdev, NULL);
+		free_bch(doc->bch);
+		kfree(mtd);
+	}
+
+	return retval;
+}
+
+static int __exit cleanup_docg4(struct platform_device *pdev)
+{
+	struct docg4_priv *doc = platform_get_drvdata(pdev);
+	nand_release(doc->mtd);
+	platform_set_drvdata(pdev, NULL);
+	free_bch(doc->bch);
+	kfree(doc->mtd);
+	iounmap(doc->virtadr);
+	return 0;
+}
+
+static struct platform_driver docg4_driver = {
+	.driver		= {
+		.name	= "docg4",
+		.owner	= THIS_MODULE,
+	},
+	.suspend	= docg4_suspend,
+	.resume		= docg4_resume,
+	.remove		= __exit_p(cleanup_docg4),
+};
+
+static int __init docg4_init(void)
+{
+	return platform_driver_probe(&docg4_driver, probe_docg4);
+}
+
+static void __exit docg4_exit(void)
+{
+	platform_driver_unregister(&docg4_driver);
+}
+
+module_init(docg4_init);
+module_exit(docg4_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mike Dunn");
+MODULE_DESCRIPTION("M-Systems DiskOnChip G4 device driver");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 493ec2f..f39f83e 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1124,7 +1124,7 @@ static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs)
 		chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
 	/* Do we have a flash based bad block table ? */
-	if (chip->options & NAND_BBT_USE_FLASH)
+	if (chip->bbt_options & NAND_BBT_USE_FLASH)
 		ret = nand_update_bbt(mtd, ofs);
 	else {
 		chipnr = (int)(ofs >> chip->chip_shift);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 8a393f9..5822e3a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -123,12 +123,6 @@ static int check_offs_len(struct mtd_info *mtd,
 		ret = -EINVAL;
 	}
 
-	/* Do not allow past end of device */
-	if (ofs + len > mtd->size) {
-		pr_debug("%s: past end of device\n", __func__);
-		ret = -EINVAL;
-	}
-
 	return ret;
 }
 
@@ -338,7 +332,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
  */
 static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 {
-	int page, chipnr, res = 0;
+	int page, chipnr, res = 0, i = 0;
 	struct nand_chip *chip = mtd->priv;
 	u16 bad;
 
@@ -356,23 +350,29 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 		chip->select_chip(mtd, chipnr);
 	}
 
-	if (chip->options & NAND_BUSWIDTH_16) {
-		chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE,
-			      page);
-		bad = cpu_to_le16(chip->read_word(mtd));
-		if (chip->badblockpos & 0x1)
-			bad >>= 8;
-		else
-			bad &= 0xFF;
-	} else {
-		chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page);
-		bad = chip->read_byte(mtd);
-	}
+	do {
+		if (chip->options & NAND_BUSWIDTH_16) {
+			chip->cmdfunc(mtd, NAND_CMD_READOOB,
+					chip->badblockpos & 0xFE, page);
+			bad = cpu_to_le16(chip->read_word(mtd));
+			if (chip->badblockpos & 0x1)
+				bad >>= 8;
+			else
+				bad &= 0xFF;
+		} else {
+			chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
+					page);
+			bad = chip->read_byte(mtd);
+		}
 
-	if (likely(chip->badblockbits == 8))
-		res = bad != 0xFF;
-	else
-		res = hweight8(bad) < chip->badblockbits;
+		if (likely(chip->badblockbits == 8))
+			res = bad != 0xFF;
+		else
+			res = hweight8(bad) < chip->badblockbits;
+		ofs += mtd->writesize;
+		page = (int)(ofs >> chip->page_shift) & chip->pagemask;
+		i++;
+	} while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE));
 
 	if (getchip)
 		nand_release_device(mtd);
@@ -386,51 +386,79 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
  * @ofs: offset from device start
  *
  * This is the default implementation, which can be overridden by a hardware
- * specific driver.
+ * specific driver. We try operations in the following order, according to our
+ * bbt_options (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH):
+ *  (1) erase the affected block, to allow OOB marker to be written cleanly
+ *  (2) update in-memory BBT
+ *  (3) write bad block marker to OOB area of affected block
+ *  (4) update flash-based BBT
+ * Note that we retain the first error encountered in (3) or (4), finish the
+ * procedures, and dump the error in the end.
 */
 static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
 {
 	struct nand_chip *chip = mtd->priv;
 	uint8_t buf[2] = { 0, 0 };
-	int block, ret, i = 0;
+	int block, res, ret = 0, i = 0;
+	int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM);
 
-	if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
-		ofs += mtd->erasesize - mtd->writesize;
+	if (write_oob) {
+		struct erase_info einfo;
+
+		/* Attempt erase before marking OOB */
+		memset(&einfo, 0, sizeof(einfo));
+		einfo.mtd = mtd;
+		einfo.addr = ofs;
+		einfo.len = 1 << chip->phys_erase_shift;
+		nand_erase_nand(mtd, &einfo, 0);
+	}
 
 	/* Get block number */
 	block = (int)(ofs >> chip->bbt_erase_shift);
+	/* Mark block bad in memory-based BBT */
 	if (chip->bbt)
 		chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
-	/* Do we have a flash based bad block table? */
-	if (chip->bbt_options & NAND_BBT_USE_FLASH)
-		ret = nand_update_bbt(mtd, ofs);
-	else {
+	/* Write bad block marker to OOB */
+	if (write_oob) {
 		struct mtd_oob_ops ops;
+		loff_t wr_ofs = ofs;
 
 		nand_get_device(chip, mtd, FL_WRITING);
 
-		/*
-		 * Write to first two pages if necessary. If we write to more
-		 * than one location, the first error encountered quits the
-		 * procedure. We write two bytes per location, so we dont have
-		 * to mess with 16 bit access.
-		 */
-		ops.len = ops.ooblen = 2;
 		ops.datbuf = NULL;
 		ops.oobbuf = buf;
-		ops.ooboffs = chip->badblockpos & ~0x01;
+		ops.ooboffs = chip->badblockpos;
+		if (chip->options & NAND_BUSWIDTH_16) {
+			ops.ooboffs &= ~0x01;
+			ops.len = ops.ooblen = 2;
+		} else {
+			ops.len = ops.ooblen = 1;
+		}
 		ops.mode = MTD_OPS_PLACE_OOB;
+
+		/* Write to first/last page(s) if necessary */
+		if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
+			wr_ofs += mtd->erasesize - mtd->writesize;
 		do {
-			ret = nand_do_write_oob(mtd, ofs, &ops);
+			res = nand_do_write_oob(mtd, wr_ofs, &ops);
+			if (!ret)
+				ret = res;
 
 			i++;
-			ofs += mtd->writesize;
-		} while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) &&
-				i < 2);
+			wr_ofs += mtd->writesize;
+		} while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2);
 
 		nand_release_device(mtd);
 	}
+
+	/* Update flash-based bad block table */
+	if (chip->bbt_options & NAND_BBT_USE_FLASH) {
+		res = nand_update_bbt(mtd, ofs);
+		if (!ret)
+			ret = res;
+	}
+
 	if (!ret)
 		mtd->ecc_stats.badblocks++;
 
@@ -1586,25 +1614,14 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
 	struct mtd_oob_ops ops;
 	int ret;
 
-	/* Do not allow reads past end of device */
-	if ((from + len) > mtd->size)
-		return -EINVAL;
-	if (!len)
-		return 0;
-
 	nand_get_device(chip, mtd, FL_READING);
-
 	ops.len = len;
 	ops.datbuf = buf;
 	ops.oobbuf = NULL;
 	ops.mode = 0;
-
 	ret = nand_do_read_ops(mtd, from, &ops);
-
 	*retlen = ops.retlen;
-
 	nand_release_device(mtd);
-
 	return ret;
 }
 
@@ -2293,12 +2310,6 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 	struct mtd_oob_ops ops;
 	int ret;
 
-	/* Do not allow reads past end of device */
-	if ((to + len) > mtd->size)
-		return -EINVAL;
-	if (!len)
-		return 0;
-
 	/* Wait for the device to get ready */
 	panic_nand_wait(mtd, chip, 400);
 
@@ -2333,25 +2344,14 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
 	struct mtd_oob_ops ops;
 	int ret;
 
-	/* Do not allow reads past end of device */
-	if ((to + len) > mtd->size)
-		return -EINVAL;
-	if (!len)
-		return 0;
-
 	nand_get_device(chip, mtd, FL_WRITING);
-
 	ops.len = len;
 	ops.datbuf = (uint8_t *)buf;
 	ops.oobbuf = NULL;
 	ops.mode = 0;
-
 	ret = nand_do_write_ops(mtd, to, &ops);
-
 	*retlen = ops.retlen;
-
 	nand_release_device(mtd);
-
 	return ret;
 }
 
@@ -2715,10 +2715,6 @@ static void nand_sync(struct mtd_info *mtd)
  */
 static int nand_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
-	/* Check for invalid offset */
-	if (offs > mtd->size)
-		return -EINVAL;
-
 	return nand_block_checkbad(mtd, offs, 1, 0);
 }
 
@@ -3238,6 +3234,10 @@ int nand_scan_tail(struct mtd_info *mtd)
 	int i;
 	struct nand_chip *chip = mtd->priv;
 
+	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
+	BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
+			!(chip->bbt_options & NAND_BBT_USE_FLASH));
+
 	if (!(chip->options & NAND_OWN_BUFFERS))
 		chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
 	if (!chip->buffers)
@@ -3461,21 +3461,21 @@ int nand_scan_tail(struct mtd_info *mtd)
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
 						MTD_CAP_NANDFLASH;
-	mtd->erase = nand_erase;
-	mtd->point = NULL;
-	mtd->unpoint = NULL;
-	mtd->read = nand_read;
-	mtd->write = nand_write;
-	mtd->panic_write = panic_nand_write;
-	mtd->read_oob = nand_read_oob;
-	mtd->write_oob = nand_write_oob;
-	mtd->sync = nand_sync;
-	mtd->lock = NULL;
-	mtd->unlock = NULL;
-	mtd->suspend = nand_suspend;
-	mtd->resume = nand_resume;
-	mtd->block_isbad = nand_block_isbad;
-	mtd->block_markbad = nand_block_markbad;
+	mtd->_erase = nand_erase;
+	mtd->_point = NULL;
+	mtd->_unpoint = NULL;
+	mtd->_read = nand_read;
+	mtd->_write = nand_write;
+	mtd->_panic_write = panic_nand_write;
+	mtd->_read_oob = nand_read_oob;
+	mtd->_write_oob = nand_write_oob;
+	mtd->_sync = nand_sync;
+	mtd->_lock = NULL;
+	mtd->_unlock = NULL;
+	mtd->_suspend = nand_suspend;
+	mtd->_resume = nand_resume;
+	mtd->_block_isbad = nand_block_isbad;
+	mtd->_block_markbad = nand_block_markbad;
 	mtd->writebufsize = mtd->writesize;
 
 	/* propagate ecc.layout to mtd_info */
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index a75382a..c5f4ebf 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -56,13 +56,6 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 	if (memcmp(mtd->name, "DiskOnChip", 10))
 		return;
 
-	if (!mtd_can_have_bb(mtd)) {
-		printk(KERN_ERR
-"NFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n"
-"Please use the new diskonchip driver under the NAND subsystem.\n");
-		return;
-	}
-
 	pr_debug("NFTL: add_mtd for %s\n", mtd->name);
 
 	nftl = kzalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index a061bc1..a1592cf 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1753,16 +1753,6 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
 	pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to,
 			(int)len);
 
-	/* Initialize retlen, in case of early exit */
-	*retlen = 0;
-
-	/* Do not allow writes past end of device */
-	if (unlikely((to + len) > mtd->size)) {
-		printk(KERN_ERR "%s: Attempt write to past end of device\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	/* Reject writes, which are not page aligned */
         if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
 		printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
@@ -1890,13 +1880,6 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
 	ops->retlen = 0;
 	ops->oobretlen = 0;
 
-	/* Do not allow writes past end of device */
-	if (unlikely((to + len) > mtd->size)) {
-		printk(KERN_ERR "%s: Attempt write to past end of device\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	/* Reject writes, which are not page aligned */
         if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) {
 		printk(KERN_ERR "%s: Attempt to write not page aligned data\n",
@@ -2493,12 +2476,6 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
 			(unsigned long long)instr->addr,
 			(unsigned long long)instr->len);
 
-	/* Do not allow erase past end of device */
-	if (unlikely((len + addr) > mtd->size)) {
-		printk(KERN_ERR "%s: Erase past end of device\n", __func__);
-		return -EINVAL;
-	}
-
 	if (FLEXONENAND(this)) {
 		/* Find the eraseregion of this address */
 		int i = flexonenand_region(mtd, addr);
@@ -4107,29 +4084,29 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
 	/* Fill in remaining MTD driver data */
 	mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH;
 	mtd->flags = MTD_CAP_NANDFLASH;
-	mtd->erase = onenand_erase;
-	mtd->point = NULL;
-	mtd->unpoint = NULL;
-	mtd->read = onenand_read;
-	mtd->write = onenand_write;
-	mtd->read_oob = onenand_read_oob;
-	mtd->write_oob = onenand_write_oob;
-	mtd->panic_write = onenand_panic_write;
+	mtd->_erase = onenand_erase;
+	mtd->_point = NULL;
+	mtd->_unpoint = NULL;
+	mtd->_read = onenand_read;
+	mtd->_write = onenand_write;
+	mtd->_read_oob = onenand_read_oob;
+	mtd->_write_oob = onenand_write_oob;
+	mtd->_panic_write = onenand_panic_write;
 #ifdef CONFIG_MTD_ONENAND_OTP
-	mtd->get_fact_prot_info = onenand_get_fact_prot_info;
-	mtd->read_fact_prot_reg = onenand_read_fact_prot_reg;
-	mtd->get_user_prot_info = onenand_get_user_prot_info;
-	mtd->read_user_prot_reg = onenand_read_user_prot_reg;
-	mtd->write_user_prot_reg = onenand_write_user_prot_reg;
-	mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;
+	mtd->_get_fact_prot_info = onenand_get_fact_prot_info;
+	mtd->_read_fact_prot_reg = onenand_read_fact_prot_reg;
+	mtd->_get_user_prot_info = onenand_get_user_prot_info;
+	mtd->_read_user_prot_reg = onenand_read_user_prot_reg;
+	mtd->_write_user_prot_reg = onenand_write_user_prot_reg;
+	mtd->_lock_user_prot_reg = onenand_lock_user_prot_reg;
 #endif
-	mtd->sync = onenand_sync;
-	mtd->lock = onenand_lock;
-	mtd->unlock = onenand_unlock;
-	mtd->suspend = onenand_suspend;
-	mtd->resume = onenand_resume;
-	mtd->block_isbad = onenand_block_isbad;
-	mtd->block_markbad = onenand_block_markbad;
+	mtd->_sync = onenand_sync;
+	mtd->_lock = onenand_lock;
+	mtd->_unlock = onenand_unlock;
+	mtd->_suspend = onenand_suspend;
+	mtd->_resume = onenand_resume;
+	mtd->_block_isbad = onenand_block_isbad;
+	mtd->_block_markbad = onenand_block_markbad;
 	mtd->owner = THIS_MODULE;
 	mtd->writebufsize = mtd->writesize;
 
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index fa1ee43..deaf762 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -923,7 +923,7 @@ static int s3c_onenand_probe(struct platform_device *pdev)
 		r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 		if (!r) {
 			dev_err(&pdev->dev, "no buffer memory resource defined\n");
-			return -ENOENT;
+			err = -ENOENT;
 			goto ahb_resource_failed;
 		}
 
@@ -964,7 +964,7 @@ static int s3c_onenand_probe(struct platform_device *pdev)
 		r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 		if (!r) {
 			dev_err(&pdev->dev, "no dma memory resource defined\n");
-			return -ENOENT;
+			err = -ENOENT;
 			goto dma_resource_failed;
 		}
 
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 48970c1..580035c 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -78,8 +78,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
 
 	if ( directory < 0 ) {
 		offset = master->size + directory * master->erasesize;
-		while (mtd_can_have_bb(master) &&
-		       mtd_block_isbad(master, offset)) {
+		while (mtd_block_isbad(master, offset)) {
 			if (!offset) {
 			nogood:
 				printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");
@@ -89,8 +88,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
 		}
 	} else {
 		offset = directory * master->erasesize;
-		while (mtd_can_have_bb(master) &&
-		       mtd_block_isbad(master, offset)) {
+		while (mtd_block_isbad(master, offset)) {
 			offset += master->erasesize;
 			if (offset == master->size)
 				goto nogood;
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c
index 941bc3c..90b9882 100644
--- a/drivers/mtd/ubi/gluebi.c
+++ b/drivers/mtd/ubi/gluebi.c
@@ -174,11 +174,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len,
 	int err = 0, lnum, offs, total_read;
 	struct gluebi_device *gluebi;
 
-	if (len < 0 || from < 0 || from + len > mtd->size)
-		return -EINVAL;
-
 	gluebi = container_of(mtd, struct gluebi_device, mtd);
-
 	lnum = div_u64_rem(from, mtd->erasesize, &offs);
 	total_read = len;
 	while (total_read) {
@@ -218,14 +214,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len,
 	int err = 0, lnum, offs, total_written;
 	struct gluebi_device *gluebi;
 
-	if (len < 0 || to < 0 || len + to > mtd->size)
-		return -EINVAL;
-
 	gluebi = container_of(mtd, struct gluebi_device, mtd);
-
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-
 	lnum = div_u64_rem(to, mtd->erasesize, &offs);
 
 	if (len % mtd->writesize || offs % mtd->writesize)
@@ -265,21 +254,13 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr)
 	int err, i, lnum, count;
 	struct gluebi_device *gluebi;
 
-	if (instr->addr < 0 || instr->addr > mtd->size - mtd->erasesize)
-		return -EINVAL;
-	if (instr->len < 0 || instr->addr + instr->len > mtd->size)
-		return -EINVAL;
 	if (mtd_mod_by_ws(instr->addr, mtd) || mtd_mod_by_ws(instr->len, mtd))
 		return -EINVAL;
 
 	lnum = mtd_div_by_eb(instr->addr, mtd);
 	count = mtd_div_by_eb(instr->len, mtd);
-
 	gluebi = container_of(mtd, struct gluebi_device, mtd);
 
-	if (!(mtd->flags & MTD_WRITEABLE))
-		return -EROFS;
-
 	for (i = 0; i < count - 1; i++) {
 		err = ubi_leb_unmap(gluebi->desc, lnum + i);
 		if (err)
@@ -340,11 +321,11 @@ static int gluebi_create(struct ubi_device_info *di,
 	mtd->owner      = THIS_MODULE;
 	mtd->writesize  = di->min_io_size;
 	mtd->erasesize  = vi->usable_leb_size;
-	mtd->read       = gluebi_read;
-	mtd->write      = gluebi_write;
-	mtd->erase      = gluebi_erase;
-	mtd->get_device = gluebi_get_device;
-	mtd->put_device = gluebi_put_device;
+	mtd->_read       = gluebi_read;
+	mtd->_write      = gluebi_write;
+	mtd->_erase      = gluebi_erase;
+	mtd->_get_device = gluebi_get_device;
+	mtd->_put_device = gluebi_put_device;
 
 	/*
 	 * In case of dynamic a volume, MTD device size is just volume size. In
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 0cb17d9..b99318e 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -1174,7 +1174,7 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
 
 	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
 	if (!ech)
-		goto out_slab;
+		goto out_si;
 
 	vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
 	if (!vidh)
@@ -1235,8 +1235,6 @@ out_vidh:
 	ubi_free_vid_hdr(ubi, vidh);
 out_ech:
 	kfree(ech);
-out_slab:
-	kmem_cache_destroy(si->scan_leb_slab);
 out_si:
 	ubi_scan_destroy_si(si);
 	return ERR_PTR(err);
@@ -1325,7 +1323,9 @@ void ubi_scan_destroy_si(struct ubi_scan_info *si)
 		}
 	}
 
-	kmem_cache_destroy(si->scan_leb_slab);
+	if (si->scan_leb_slab)
+		kmem_cache_destroy(si->scan_leb_slab);
+
 	kfree(si);
 }
 
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 0ae0d7c..793b001 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -660,7 +660,7 @@ static void __attach_bond_to_agg(struct port *port)
 static void __detach_bond_from_agg(struct port *port)
 {
 	port = NULL; /* just to satisfy the compiler */
-	// This function does nothing sience the parser/multiplexer of the receive
+	// This function does nothing since the parser/multiplexer of the receive
 	// and the parser/multiplexer of the aggregator are already combined
 }
 
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index f820b26..9abfde4 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -180,11 +180,9 @@ static int tlb_initialize(struct bonding *bond)
 	int i;
 
 	new_hashtbl = kzalloc(size, GFP_KERNEL);
-	if (!new_hashtbl) {
-		pr_err("%s: Error: Failed to allocate TLB hash table\n",
-		       bond->dev->name);
+	if (!new_hashtbl)
 		return -1;
-	}
+
 	_lock_tx_hashtbl_bh(bond);
 
 	bond_info->tx_hashtbl = new_hashtbl;
@@ -784,11 +782,9 @@ static int rlb_initialize(struct bonding *bond)
 	int i;
 
 	new_hashtbl = kmalloc(size, GFP_KERNEL);
-	if (!new_hashtbl) {
-		pr_err("%s: Error: Failed to allocate RLB hash table\n",
-		       bond->dev->name);
+	if (!new_hashtbl)
 		return -1;
-	}
+
 	_lock_rx_hashtbl_bh(bond);
 
 	bond_info->rx_hashtbl = new_hashtbl;
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig
index abf4d7a..5a8912b 100644
--- a/drivers/net/caif/Kconfig
+++ b/drivers/net/caif/Kconfig
@@ -32,7 +32,7 @@ config CAIF_SPI_SYNC
 	help to synchronize to the next transfer in case of over or under-runs.
 	This option also needs to be enabled on the modem.
 
-config CAIF_SHM
+config CAIF_SHM_MBX
 	tristate "CAIF shared memory protocol driver"
 	depends on CAIF && U5500_MBOX
 	default n
@@ -47,3 +47,13 @@ config CAIF_HSI
        The caif low level driver for CAIF over HSI.
        Be aware that if you enable this then you also need to
        enable a low-level HSI driver.
+
+config CAIF_SHM
+	tristate "CAIF shared memory protocol driver"
+	depends on MODEM_SHM_BUS && CAIF
+	default n
+	---help---
+	Say "Y" if you want to support CAIF over Modem Shared Memory
+	IPC mechanism (e.g. over Chip to Chip). Only say M here if you want to
+	test CAIF over SHM and need to load and unload its module.
+	If unsure say N.
diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile
index 91dff86..2837c56 100644
--- a/drivers/net/caif/Makefile
+++ b/drivers/net/caif/Makefile
@@ -8,7 +8,8 @@ cfspi_slave-objs := caif_spi.o caif_spi_slave.o
 obj-$(CONFIG_CAIF_SPI_SLAVE) += cfspi_slave.o
 
 # Shared memory
-caif_shm-objs := caif_shmcore.o caif_shm_u5500.o
+caif_shmmbx-objs := caif_shmcore.o caif_shm_u5500.o
+obj-$(CONFIG_CAIF_SHM_MBX) += caif_shmmbx.o
 obj-$(CONFIG_CAIF_SHM) += caif_shm.o
 
 # HSI interface
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 0a4fc62..c8afd62 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -426,6 +426,35 @@ static int cfhsi_rx_desc(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 	return xfer_sz;
 }
 
+static int cfhsi_rx_desc_len(struct cfhsi_desc *desc)
+{
+	int xfer_sz = 0;
+	int nfrms = 0;
+	u16 *plen;
+
+	if ((desc->header & ~CFHSI_PIGGY_DESC) ||
+			(desc->offset > CFHSI_MAX_EMB_FRM_SZ)) {
+
+		pr_err("Invalid descriptor. %x %x\n", desc->header,
+				desc->offset);
+		return -EPROTO;
+	}
+
+	/* Calculate transfer length. */
+	plen = desc->cffrm_len;
+	while (nfrms < CFHSI_MAX_PKTS && *plen) {
+		xfer_sz += *plen;
+		plen++;
+		nfrms++;
+	}
+
+	if (xfer_sz % 4) {
+		pr_err("Invalid payload len: %d, ignored.\n", xfer_sz);
+		return -EPROTO;
+	}
+	return xfer_sz;
+}
+
 static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 {
 	int rx_sz = 0;
@@ -517,8 +546,10 @@ static int cfhsi_rx_pld(struct cfhsi_desc *desc, struct cfhsi *cfhsi)
 static void cfhsi_rx_done(struct cfhsi *cfhsi)
 {
 	int res;
-	int desc_pld_len = 0;
+	int desc_pld_len = 0, rx_len, rx_state;
 	struct cfhsi_desc *desc = NULL;
+	u8 *rx_ptr, *rx_buf;
+	struct cfhsi_desc *piggy_desc = NULL;
 
 	desc = (struct cfhsi_desc *)cfhsi->rx_buf;
 
@@ -534,65 +565,71 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 	spin_unlock_bh(&cfhsi->lock);
 
 	if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
-		desc_pld_len = cfhsi_rx_desc(desc, cfhsi);
-		if (desc_pld_len == -ENOMEM)
-			goto restart;
-		if (desc_pld_len == -EPROTO)
+		desc_pld_len = cfhsi_rx_desc_len(desc);
+
+		if (desc_pld_len < 0)
 			goto out_of_sync;
+
+		rx_buf = cfhsi->rx_buf;
+		rx_len = desc_pld_len;
+		if (desc_pld_len > 0 && (desc->header & CFHSI_PIGGY_DESC))
+			rx_len += CFHSI_DESC_SZ;
+		if (desc_pld_len == 0)
+			rx_buf = cfhsi->rx_flip_buf;
 	} else {
-		int pld_len;
+		rx_buf = cfhsi->rx_flip_buf;
 
-		if (!cfhsi->rx_state.piggy_desc) {
-			pld_len = cfhsi_rx_pld(desc, cfhsi);
-			if (pld_len == -ENOMEM)
-				goto restart;
-			if (pld_len == -EPROTO)
-				goto out_of_sync;
-			cfhsi->rx_state.pld_len = pld_len;
-		} else {
-			pld_len = cfhsi->rx_state.pld_len;
-		}
+		rx_len = CFHSI_DESC_SZ;
+		if (cfhsi->rx_state.pld_len > 0 &&
+				(desc->header & CFHSI_PIGGY_DESC)) {
 
-		if ((pld_len > 0) && (desc->header & CFHSI_PIGGY_DESC)) {
-			struct cfhsi_desc *piggy_desc;
 			piggy_desc = (struct cfhsi_desc *)
 				(desc->emb_frm + CFHSI_MAX_EMB_FRM_SZ +
-						pld_len);
+						cfhsi->rx_state.pld_len);
+
 			cfhsi->rx_state.piggy_desc = true;
 
-			/* Extract piggy-backed descriptor. */
-			desc_pld_len = cfhsi_rx_desc(piggy_desc, cfhsi);
-			if (desc_pld_len == -ENOMEM)
-				goto restart;
+			/* Extract payload len from piggy-backed descriptor. */
+			desc_pld_len = cfhsi_rx_desc_len(piggy_desc);
+			if (desc_pld_len < 0)
+				goto out_of_sync;
+
+			if (desc_pld_len > 0)
+				rx_len = desc_pld_len;
+
+			if (desc_pld_len > 0 &&
+					(piggy_desc->header & CFHSI_PIGGY_DESC))
+				rx_len += CFHSI_DESC_SZ;
 
 			/*
 			 * Copy needed information from the piggy-backed
 			 * descriptor to the descriptor in the start.
 			 */
-			memcpy((u8 *)desc, (u8 *)piggy_desc,
+			memcpy(rx_buf, (u8 *)piggy_desc,
 					CFHSI_DESC_SHORT_SZ);
-
+			/* Mark no embedded frame here */
+			piggy_desc->offset = 0;
 			if (desc_pld_len == -EPROTO)
 				goto out_of_sync;
 		}
 	}
 
-	memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state));
 	if (desc_pld_len) {
-		cfhsi->rx_state.state = CFHSI_RX_STATE_PAYLOAD;
-		cfhsi->rx_ptr = cfhsi->rx_buf + CFHSI_DESC_SZ;
-		cfhsi->rx_len = desc_pld_len;
+		rx_state = CFHSI_RX_STATE_PAYLOAD;
+		rx_ptr = rx_buf + CFHSI_DESC_SZ;
 	} else {
-		cfhsi->rx_state.state = CFHSI_RX_STATE_DESC;
-		cfhsi->rx_ptr = cfhsi->rx_buf;
-		cfhsi->rx_len = CFHSI_DESC_SZ;
+		rx_state = CFHSI_RX_STATE_DESC;
+		rx_ptr = rx_buf;
+		rx_len = CFHSI_DESC_SZ;
 	}
 
+	/* Initiate next read */
 	if (test_bit(CFHSI_AWAKE, &cfhsi->bits)) {
 		/* Set up new transfer. */
 		dev_dbg(&cfhsi->ndev->dev, "%s: Start RX.\n",
-			__func__);
-		res = cfhsi->dev->cfhsi_rx(cfhsi->rx_ptr, cfhsi->rx_len,
+				__func__);
+
+		res = cfhsi->dev->cfhsi_rx(rx_ptr, rx_len,
 				cfhsi->dev);
 		if (WARN_ON(res < 0)) {
 			dev_err(&cfhsi->ndev->dev, "%s: RX error %d.\n",
@@ -601,16 +638,32 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi)
 			cfhsi->ndev->stats.rx_dropped++;
 		}
 	}
-	return;
 
-restart:
-	if (++cfhsi->rx_state.retries > CFHSI_MAX_RX_RETRIES) {
-		dev_err(&cfhsi->ndev->dev, "%s: No memory available "
-			"in %d iterations.\n",
-			__func__, CFHSI_MAX_RX_RETRIES);
-		BUG();
+	if (cfhsi->rx_state.state == CFHSI_RX_STATE_DESC) {
+		/* Extract payload from descriptor */
+		if (cfhsi_rx_desc(desc, cfhsi) < 0)
+			goto out_of_sync;
+	} else {
+		/* Extract payload */
+		if (cfhsi_rx_pld(desc, cfhsi) < 0)
+			goto out_of_sync;
+		if (piggy_desc) {
+			/* Extract any payload in piggyback descriptor. */
+			if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0)
+				goto out_of_sync;
+		}
 	}
-	mod_timer(&cfhsi->rx_slowpath_timer, jiffies + 1);
+
+	/* Update state info */
+	memset(&cfhsi->rx_state, 0, sizeof(cfhsi->rx_state));
+	cfhsi->rx_state.state = rx_state;
+	cfhsi->rx_ptr = rx_ptr;
+	cfhsi->rx_len = rx_len;
+	cfhsi->rx_state.pld_len = desc_pld_len;
+	cfhsi->rx_state.piggy_desc = desc->header & CFHSI_PIGGY_DESC;
+
+	if (rx_buf != cfhsi->rx_buf)
+		swap(cfhsi->rx_buf, cfhsi->rx_flip_buf);
 	return;
 
 out_of_sync:
@@ -1040,6 +1093,12 @@ int cfhsi_probe(struct platform_device *pdev)
 		goto err_alloc_rx;
 	}
 
+	cfhsi->rx_flip_buf = kzalloc(CFHSI_BUF_SZ_RX, GFP_KERNEL);
+	if (!cfhsi->rx_flip_buf) {
+		res = -ENODEV;
+		goto err_alloc_rx_flip;
+	}
+
 	/* Pre-calculate inactivity timeout. */
 	if (inactivity_timeout != -1) {
 		cfhsi->inactivity_timeout =
@@ -1138,6 +1197,8 @@ int cfhsi_probe(struct platform_device *pdev)
  err_activate:
 	destroy_workqueue(cfhsi->wq);
  err_create_wq:
+	kfree(cfhsi->rx_flip_buf);
+ err_alloc_rx_flip:
 	kfree(cfhsi->rx_buf);
  err_alloc_rx:
 	kfree(cfhsi->tx_buf);
diff --git a/drivers/net/caif/caif_shm.c b/drivers/net/caif/caif_shm.c
new file mode 100644
index 0000000..f6ce4867
--- /dev/null
+++ b/drivers/net/caif/caif_shm.c
@@ -0,0 +1,900 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2011
+ * Contact: Sjur Brændeland / sjur.brandeland@stericsson.com
+ * Authors: Sjur Brændeland / sjur.brandeland@stericsson.com
+ *	   Daniel Martensson / daniel.martensson@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/modem_shm/shm_dev.h>
+#include <net/rtnetlink.h>
+#include <net/caif/caif_device.h>
+#include <net/caif/caif_layer.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Martensson <daniel.martensson@stericsson.com>");
+MODULE_AUTHOR("Sjur Brændeland <sjur.brandeland@stericsson.com>");
+MODULE_DESCRIPTION("CAIF SHM driver");
+
+#define CONNECT_TIMEOUT (3 * HZ)
+#define CAIF_NEEDED_HEADROOM	32
+#define CAIF_FLOW_ON		1
+#define CAIF_FLOW_OFF		0
+
+#define LOW_XOFF_WATERMARK	50
+#define HIGH_XOFF_WATERMARK	70
+#define STUFF_MARK		30
+
+struct ringbuf {
+	__le32	*rip;
+	__le32	*wip;
+	u32	size;
+	__le32	*bufsize;
+};
+
+struct shm_pck_desc {
+	/* Offset from start of channel to CAIF frame. */
+	u32 offset;
+	u32 length;
+} __packed;
+
+struct shm_caif_frm {
+	/* Number of bytes of padding before the CAIF frame. */
+	u8 hdr_ofs;
+} __packed;
+
+#define SHM_HDR_LEN sizeof(struct shm_caif_frm)
+
+struct shmbuffer {
+/* Static part: */
+	u8 *addr;
+	u32 index;
+	u32 len;
+/* Dynamic part: */
+	u32 frames;
+	/* Offset from start of buffer to CAIF frame. */
+	u32 frm_ofs;
+};
+
+enum CFSHM_STATE {
+	CFSHM_CLOSED = 1,
+	CFSHM_OPENING,
+	CFSHM_OPEN
+};
+
+struct cfshm {
+	/* caif_dev_common must always be first in the structure*/
+	struct caif_dev_common cfdev;
+	struct shm_dev *shm;
+	struct napi_struct napi;
+	struct ringbuf tx;
+	struct sk_buff_head sk_qhead;
+	spinlock_t lock;
+	struct ringbuf rx;
+	u8 *rx_ringbuf;
+	u32 rx_frms_pr_buf;
+	u32 rx_alignment;
+	struct shmbuffer **rx_bufs;
+	struct net_device *ndev;
+
+	u32 tx_frms_pr_buf;
+	u32 tx_alignment;
+	struct shmbuffer **tx_bufs;
+	u8 *tx_ringbuf;
+	u32 tx_flow_on;
+	u32 high_xoff_water;
+	u32 low_xoff_water;
+	u32 stuff_mark;
+	atomic_t dbg_smp_rxactive;
+	enum CFSHM_STATE state;
+	wait_queue_head_t netmgmt_wq;
+};
+
+static unsigned int ringbuf_used(struct ringbuf *rb)
+{
+	if (le32_to_cpu(*rb->wip) >= le32_to_cpu(*rb->rip))
+		return le32_to_cpu(*rb->wip) - le32_to_cpu(*rb->rip);
+	else
+		return rb->size - le32_to_cpu(*rb->rip) + le32_to_cpu(*rb->wip);
+}
+
+static int ringbuf_get_writepos(struct ringbuf *rb)
+{
+	if ((le32_to_cpu(*rb->wip) + 1) % rb->size == le32_to_cpu(*rb->rip))
+		return -1;
+	else
+		return le32_to_cpu(*rb->wip);
+}
+
+static int ringbuf_get_readpos(struct ringbuf *rb)
+{
+
+	if (le32_to_cpu(*rb->wip) == le32_to_cpu(*rb->rip))
+		return -1;
+	else
+		return le32_to_cpu(*rb->rip);
+}
+
+static int ringbuf_upd_writeptr(struct ringbuf *rb)
+{
+	if (!WARN_ON((le32_to_cpu(*rb->wip) + 1) % rb->size ==
+					le32_to_cpu(*rb->rip))) {
+
+		*rb->wip = cpu_to_le32((le32_to_cpu(*rb->wip) + 1) % rb->size);
+		/* Do write barrier before updating index */
+		smp_wmb();
+	}
+	return le32_to_cpu(*rb->wip);
+}
+
+static void ringbuf_upd_readptr(struct ringbuf *rb)
+{
+	if (!WARN_ON(le32_to_cpu(*rb->wip) == le32_to_cpu(*rb->rip))) {
+		*rb->rip = cpu_to_le32((le32_to_cpu(*rb->rip) + 1) % rb->size);
+		/* Do write barrier before updating index */
+		smp_wmb();
+	}
+}
+
+
+
+static struct shmbuffer *get_rx_buf(struct cfshm *cfshm)
+{
+	struct shmbuffer *pbuf = NULL;
+	int idx = ringbuf_get_readpos(&cfshm->rx);
+
+	if (idx < 0)
+		goto out;
+	pbuf = cfshm->rx_bufs[idx];
+out:
+	return pbuf;
+}
+
+static struct shmbuffer *new_rx_buf(struct cfshm *cfshm)
+{
+	struct shmbuffer *pbuf = get_rx_buf(cfshm);
+
+	WARN_ON(!spin_is_locked(&cfshm->lock));
+	if (pbuf)
+		pbuf->frames = 0;
+
+	return pbuf;
+}
+
+static struct shmbuffer *get_tx_buf(struct cfshm *cfshm)
+{
+	int idx = ringbuf_get_writepos(&cfshm->tx);
+
+	if (idx < 0)
+		return NULL;
+	return cfshm->tx_bufs[idx];
+}
+
+inline struct shmbuffer *tx_bump_buf(struct cfshm *cfshm,
+			struct shmbuffer *pbuf)
+{
+	u32 desc_size;
+	struct shmbuffer *newpbuf = pbuf;
+
+	WARN_ON(!spin_is_locked(&cfshm->lock));
+	if (pbuf) {
+		cfshm->shm->cfg.tx.buf_size[pbuf->index] =
+			cpu_to_le32(pbuf->frm_ofs);
+		ringbuf_upd_writeptr(&cfshm->tx);
+		newpbuf = get_tx_buf(cfshm);
+		/* Reset buffer parameters. */
+		desc_size = (cfshm->tx_frms_pr_buf + 1) *
+			sizeof(struct shm_pck_desc);
+		pbuf->frm_ofs = desc_size + (desc_size % cfshm->rx_alignment);
+		pbuf->frames = 0;
+
+	}
+	return newpbuf;
+}
+
+static struct shmbuffer *shm_rx_func(struct cfshm *cfshm, int quota)
+{
+	struct shmbuffer *pbuf;
+	struct sk_buff *skb;
+	int ret;
+	unsigned long flags;
+
+	pbuf = get_rx_buf(cfshm);
+	while (pbuf) {
+		/* Retrieve pointer to start of the packet descriptor area. */
+		struct shm_pck_desc *pck_desc =
+			((struct shm_pck_desc *) pbuf->addr) + pbuf->frames;
+		u32 offset;
+
+		/* Loop until descriptor contains zero offset */
+		while ((offset = pck_desc->offset)) {
+			unsigned int caif_len;
+			struct shm_caif_frm *frm;
+			u32 length = pck_desc->length;
+			u8 hdr_ofs;
+			frm = (struct shm_caif_frm *)(pbuf->addr + offset);
+			hdr_ofs = frm->hdr_ofs;
+			caif_len =
+				length - SHM_HDR_LEN -
+				hdr_ofs;
+
+			pr_devel("copy data buf:%d frm:%d offs:%d @%x len:%d\n",
+					pbuf->index, pbuf->frames, offset,
+					(u32) (SHM_HDR_LEN + hdr_ofs + offset +
+						pbuf->addr - cfshm->rx_ringbuf),
+					length);
+
+			/* Check whether number of frames is below limit */
+			if (pbuf->frames > cfshm->rx_frms_pr_buf) {
+				pr_warn("Too many frames in buffer.\n");
+				++cfshm->ndev->stats.rx_frame_errors;
+				goto desc_err;
+			}
+
+			/* Check whether offset is below low limits */
+			if (pbuf->addr + offset
+					<= (u8 *)(pck_desc + 1)) {
+				pr_warn("Offset in desc. below buffer area.\n");
+				++cfshm->ndev->stats.rx_frame_errors;
+				goto desc_err;
+			}
+
+			/* Check whether offset above upper limit */
+			if (offset + length > pbuf->len) {
+				pr_warn("Offset outside buffer area:\n");
+				++cfshm->ndev->stats.rx_frame_errors;
+				goto desc_err;
+			}
+
+			skb = netdev_alloc_skb(cfshm->ndev,
+							caif_len + 1);
+			if (skb == NULL) {
+				pr_debug("Couldn't allocate SKB\n");
+				++cfshm->ndev->stats.rx_dropped;
+				goto out;
+			}
+
+			memcpy(skb_put(skb, caif_len),
+					SHM_HDR_LEN + hdr_ofs +
+					offset + pbuf->addr,
+					caif_len);
+
+			skb->protocol = htons(ETH_P_CAIF);
+			skb_reset_mac_header(skb);
+			skb->dev = cfshm->ndev;
+
+			/* Push received packet up the stack. */
+			ret = netif_receive_skb(skb);
+
+			if (!ret) {
+				cfshm->ndev->stats.rx_packets++;
+				cfshm->ndev->stats.rx_bytes +=
+					length;
+			} else
+				++cfshm->ndev->stats.rx_dropped;
+			/* Move to next packet descriptor. */
+			pck_desc++;
+
+			pbuf->frames++;
+			if (--quota <= 0) {
+				pr_devel("Quota exeeded (pbuf:%p)\n", pbuf);
+				goto out;
+			}
+		}
+desc_err:
+		pbuf->frames = 0;
+
+		spin_lock_irqsave(&cfshm->lock, flags);
+		ringbuf_upd_readptr(&cfshm->rx);
+		pbuf = new_rx_buf(cfshm);
+		spin_unlock_irqrestore(&cfshm->lock, flags);
+
+	}
+	cfshm->shm->ipc_rx_release(cfshm->shm, false);
+out:
+	return pbuf;
+}
+
+static int insert_skb_in_buf(struct cfshm *cfshm, struct sk_buff *skb,
+					struct shmbuffer *pbuf)
+{
+	struct shm_pck_desc *pck_desc;
+	unsigned int frmlen;
+	struct shm_caif_frm *frm;
+	u8 hdr_ofs;
+	struct caif_payload_info *info = (struct caif_payload_info *)&skb->cb;
+
+	WARN_ON(!spin_is_locked(&cfshm->lock));
+
+	if (unlikely(pbuf->frames >= cfshm->tx_frms_pr_buf)) {
+		pr_devel("-ENOSPC exeeded frames: %d >= %d\n",
+				pbuf->frames, cfshm->tx_frms_pr_buf);
+		return -ENOSPC;
+	}
+
+	/*
+	 * Align the address of the entire CAIF frame (incl padding),
+	 * so the modem can do efficient DMA of this frame
+	 * FIXME: Alignment is power of to, so it could use binary ops.
+	 */
+	pbuf->frm_ofs = roundup(pbuf->frm_ofs, cfshm->tx_alignment);
+
+
+	/* Make the payload (IP packet) inside the frame aligned */
+	hdr_ofs = (unsigned long) &pbuf->frm_ofs;
+	hdr_ofs = roundup(hdr_ofs + SHM_HDR_LEN + info->hdr_len,
+			cfshm->tx_alignment);
+
+	frm = (struct shm_caif_frm *)
+		(pbuf->addr + pbuf->frm_ofs);
+
+	frmlen = SHM_HDR_LEN + hdr_ofs + skb->len;
+
+	/*
+	 * Verify that packet, header and additional padding
+	 * can fit within the buffer frame area.
+	 */
+	if (pbuf->len < pbuf->frm_ofs + frmlen) {
+		pr_devel("-ENOSPC exeeded offset %d < %d\n",
+				pbuf->len, pbuf->frm_ofs + frmlen);
+		return -ENOSPC;
+	}
+
+	/* Copy in CAIF frame. */
+	frm->hdr_ofs = hdr_ofs;
+	skb_copy_bits(skb, 0, pbuf->addr +
+			pbuf->frm_ofs + SHM_HDR_LEN +
+			hdr_ofs, skb->len);
+
+	pr_devel("copy data buf:%d frm:%d offs:%d @%d len:%d\n",
+			pbuf->index, pbuf->frames,
+			pbuf->frm_ofs,
+			(u32) (pbuf->addr + pbuf->frm_ofs +
+				SHM_HDR_LEN + hdr_ofs - cfshm->tx_ringbuf),
+			skb->len);
+
+	cfshm->ndev->stats.tx_packets++;
+	cfshm->ndev->stats.tx_bytes += frmlen;
+	/* Fill in the shared memory packet descriptor area. */
+	pck_desc = (struct shm_pck_desc *) (pbuf->addr);
+	/* Forward to current frame. */
+	pck_desc += pbuf->frames;
+	pck_desc->offset = pbuf->frm_ofs;
+	pck_desc->length = frmlen;
+	/* Terminate packet descriptor area. */
+	pck_desc++;
+	pck_desc->offset = 0;
+	pck_desc->length = 0;
+	/* Update buffer parameters. */
+	pbuf->frames++;
+	pbuf->frm_ofs += frmlen;
+
+	return 0;
+}
+
+static struct shmbuffer *queue_to_ringbuf(struct cfshm *cfshm, int *new_bufs)
+{
+	struct shmbuffer *pbuf;
+	struct sk_buff *skb;
+	int err;
+
+	WARN_ON(!spin_is_locked(&cfshm->lock));
+
+	pbuf = get_tx_buf(cfshm);
+	while (pbuf != NULL) {
+		skb = skb_peek(&cfshm->sk_qhead);
+		if (skb == NULL)
+			break;
+		err = insert_skb_in_buf(cfshm, skb, pbuf);
+		if (unlikely(err == -ENOSPC)) {
+			pr_devel("No more space in buffer\n");
+			++(*new_bufs);
+			pbuf = tx_bump_buf(cfshm, pbuf);
+			continue;
+		}
+		skb = skb_dequeue(&cfshm->sk_qhead);
+		/* We're always in NET_*_SOFTIRQ */
+		dev_kfree_skb(skb);
+	}
+	return pbuf;
+}
+
+static int shm_netdev_open(struct net_device *netdev)
+{
+	struct cfshm *cfshm = netdev_priv(netdev);
+	int ret, err = 0;
+
+	cfshm->state = CFSHM_OPENING;
+	if (cfshm->shm != NULL && cfshm->shm->open != NULL)
+		err = cfshm->shm->open(cfshm->shm);
+	if (err)
+		goto error;
+
+	rtnl_unlock();  /* Release RTNL lock during connect wait */
+	ret = wait_event_interruptible_timeout(cfshm->netmgmt_wq,
+			cfshm->state != CFSHM_OPENING,
+			CONNECT_TIMEOUT);
+	rtnl_lock();
+
+	if (ret == 0) {
+		pr_debug("connect timeout\n");
+		err = -ETIMEDOUT;
+		goto error;
+	}
+
+	if (cfshm->state !=  CFSHM_OPEN) {
+		pr_debug("connect failed\n");
+		err = -ECONNREFUSED;
+		goto error;
+	}
+
+	napi_enable(&cfshm->napi);
+	return 0;
+error:
+	if (cfshm->shm != NULL && cfshm->shm->close != NULL)
+		cfshm->shm->close(cfshm->shm);
+	return err;
+}
+
+static int shm_netdev_close(struct net_device *netdev)
+{
+	struct cfshm *cfshm = netdev_priv(netdev);
+
+	napi_disable(&cfshm->napi);
+
+	if (cfshm->shm != NULL && cfshm->shm->close != NULL)
+		cfshm->shm->close(cfshm->shm);
+
+	return 0;
+}
+
+static int open_cb(void *drv)
+{
+	struct cfshm *cfshm = drv;
+
+	cfshm->state = CFSHM_OPEN;
+	netif_carrier_on(cfshm->ndev);
+	wake_up_interruptible(&cfshm->netmgmt_wq);
+	return 0;
+}
+
+static void close_cb(void *drv)
+{
+	struct cfshm *cfshm = drv;
+
+	cfshm->state = CFSHM_CLOSED;
+	netif_carrier_off(cfshm->ndev);
+	wake_up_interruptible(&cfshm->netmgmt_wq);
+}
+
+static int caif_shmdrv_rx_cb(void *drv)
+{
+	struct cfshm *cfshm = drv;
+
+	if (unlikely(*cfshm->shm->cfg.rx.state == cpu_to_le32(SHM_CLOSED)))
+		return -ESHUTDOWN;
+
+	napi_schedule(&cfshm->napi);
+	return 0;
+}
+
+static int send_pending_txbufs(struct cfshm *cfshm, int usedbufs)
+{
+	/* Send the started buffer if used buffers are low enough */
+	WARN_ON(!spin_is_locked(&cfshm->lock));
+	if (likely(usedbufs < cfshm->stuff_mark)) {
+		struct shmbuffer *pbuf = get_tx_buf(cfshm);
+		if (unlikely(pbuf->frames > 0)) {
+			pbuf = get_tx_buf(cfshm);
+			tx_bump_buf(cfshm, pbuf);
+			cfshm->shm->ipc_tx(cfshm->shm);
+			return 0;
+		}
+	}
+	return 0;
+}
+
+static int caif_shmdrv_tx_release_cb(void *drv)
+{
+	struct cfshm *cfshm = drv;
+	int usedbufs;
+
+	usedbufs = ringbuf_used(&cfshm->tx);
+
+	/* Send flow-on if we have sent flow-off and get below low-water */
+	if (usedbufs <= cfshm->low_xoff_water && !cfshm->tx_flow_on) {
+		pr_debug("Flow on\n");
+		cfshm->tx_flow_on = true;
+		cfshm->cfdev.flowctrl(cfshm->ndev, CAIF_FLOW_ON);
+	}
+
+	/* If ringbuf is full, schedule NAPI to start sending */
+	if (skb_peek(&cfshm->sk_qhead) != NULL) {
+		pr_debug("Schedule NAPI to empty queue\n");
+		napi_schedule(&cfshm->napi);
+	}
+
+	return 0;
+}
+
+static int shm_rx_poll(struct napi_struct *napi, int quota)
+{
+	struct cfshm *cfshm = container_of(napi, struct cfshm, napi);
+	int new_bufs;
+	struct shmbuffer *pbuf;
+	int usedbufs;
+	unsigned long flags;
+
+	/* Simply return if rx_poll is already called on other CPU */
+	if (atomic_read(&cfshm->dbg_smp_rxactive) > 0)
+		return quota;
+
+	WARN_ON(atomic_inc_return(&cfshm->dbg_smp_rxactive) > 1);
+
+	pbuf = shm_rx_func(cfshm, quota);
+
+	usedbufs = ringbuf_used(&cfshm->tx);
+
+	if (spin_trylock_irqsave(&cfshm->lock, flags)) {
+
+		/* Check if we're below "Stuff" limit, and send pending data */
+		send_pending_txbufs(cfshm, usedbufs);
+
+		/* Check if we have queued packets */
+		if (unlikely(skb_peek(&cfshm->sk_qhead) != NULL)) {
+			struct shmbuffer *txbuf;
+			WARN_ON(!spin_is_locked(&cfshm->lock));
+			pr_debug("Try to empty tx-queue\n");
+			new_bufs = 0;
+			txbuf = queue_to_ringbuf(cfshm, &new_bufs);
+
+			/* Bump out if we are configured with few buffers */
+			if (txbuf && cfshm->shm->cfg.tx.buffers < 3) {
+				tx_bump_buf(cfshm, txbuf);
+
+				spin_unlock_irqrestore(&cfshm->lock, flags);
+				cfshm->shm->ipc_tx(cfshm->shm);
+				goto txdone;
+			}
+		}
+		spin_unlock_irqrestore(&cfshm->lock, flags);
+	}
+txdone:
+
+	if (pbuf == NULL)
+		napi_complete(&cfshm->napi);
+
+	atomic_dec(&cfshm->dbg_smp_rxactive);
+	return 0;
+}
+
+static int shm_netdev_tx(struct sk_buff *skb, struct net_device *shm_netdev)
+{
+	struct shmbuffer *pbuf = NULL;
+	int usedbufs;
+	int new_bufs = 0;
+	struct cfshm *cfshm = netdev_priv(shm_netdev);
+	unsigned long flags;
+
+	/*
+	 * If we have packets in queue, keep queueing to avoid
+	 * out-of-order delivery
+	 */
+	spin_lock_irqsave(&cfshm->lock, flags);
+
+	skb_queue_tail(&cfshm->sk_qhead, skb);
+	pbuf = queue_to_ringbuf(cfshm, &new_bufs);
+
+	usedbufs = ringbuf_used(&cfshm->tx);
+
+	if (usedbufs > cfshm->high_xoff_water && cfshm->tx_flow_on) {
+		pr_debug("Flow off\n");
+		cfshm->tx_flow_on = false;
+		spin_unlock_irqrestore(&cfshm->lock, flags);
+		cfshm->cfdev.flowctrl(cfshm->ndev, CAIF_FLOW_OFF);
+		return 0;
+	}
+
+	/* Check if we should accumulate more packets */
+	if (new_bufs == 0 && usedbufs > cfshm->stuff_mark) {
+		spin_unlock_irqrestore(&cfshm->lock, flags);
+		return 0;
+	}
+	tx_bump_buf(cfshm, pbuf);
+	spin_unlock_irqrestore(&cfshm->lock, flags);
+	cfshm->shm->ipc_tx(cfshm->shm);
+	return 0;
+}
+
+static const struct net_device_ops netdev_ops = {
+	.ndo_open = shm_netdev_open,
+	.ndo_stop = shm_netdev_close,
+	.ndo_start_xmit = shm_netdev_tx,
+};
+
+static void shm_netdev_setup(struct net_device *pshm_netdev)
+{
+	struct cfshm *cfshm;
+
+	cfshm = netdev_priv(pshm_netdev);
+	pshm_netdev->netdev_ops = &netdev_ops;
+	pshm_netdev->type = ARPHRD_CAIF;
+	pshm_netdev->hard_header_len = CAIF_NEEDED_HEADROOM;
+	pshm_netdev->tx_queue_len = 0;
+	pshm_netdev->destructor = free_netdev;
+
+	/* Initialize structures in a clean state. */
+	memset(cfshm, 0, sizeof(struct cfshm));
+}
+
+static void deinit_bufs(struct cfshm *cfshm)
+{
+	int j;
+
+	if (cfshm == NULL)
+		return;
+
+	for (j = 0; j < cfshm->shm->cfg.rx.buffers; j++)
+		kfree(cfshm->rx_bufs[j]);
+	kfree(cfshm->rx_bufs);
+
+	for (j = 0; j < cfshm->shm->cfg.tx.buffers; j++)
+		kfree(cfshm->tx_bufs[j]);
+	kfree(cfshm->tx_bufs);
+}
+
+static int cfshm_probe(struct shm_dev *shm)
+{
+	int err, j;
+	struct cfshm *cfshm = NULL;
+	struct net_device *netdev;
+	u32 buf_size;
+	unsigned long flags;
+
+	if (shm == NULL)
+		return -EINVAL;
+	if (shm->cfg.tx.addr == NULL || shm->cfg.rx.addr == NULL) {
+		pr_debug("Shared Memory are not configured\n");
+		return -EINVAL;
+	}
+
+	if (shm->cfg.tx.ch_size / shm->cfg.tx.buffers <
+			shm->cfg.tx.packets * sizeof(struct shm_pck_desc) +
+				shm->cfg.tx.mtu) {
+		pr_warn("Bad packet TX-channel size");
+		return -EINVAL;
+	}
+
+	if (shm->cfg.rx.ch_size / shm->cfg.rx.buffers <
+			sizeof(struct shm_pck_desc) + shm->cfg.rx.mtu) {
+		pr_warn("Bad packet RX-channel size");
+		return -EINVAL;
+	}
+
+	if (shm->cfg.rx.buffers < 2 || shm->cfg.tx.buffers < 2) {
+		pr_warn("Too few buffers in channel");
+		return -EINVAL;
+	}
+
+	err = -ENOMEM;
+	netdev = alloc_netdev(sizeof(struct cfshm), shm->cfg.name,
+			shm_netdev_setup);
+
+	if (netdev == NULL)
+		goto error;
+
+	cfshm = netdev_priv(netdev);
+	cfshm->state = CFSHM_CLOSED;
+	init_waitqueue_head(&cfshm->netmgmt_wq);
+
+	cfshm->shm = shm;
+	shm->driver_data = cfshm;
+	cfshm->ndev = netdev;
+	netdev->mtu = shm->cfg.tx.mtu;
+	cfshm->high_xoff_water =
+		(shm->cfg.rx.buffers * HIGH_XOFF_WATERMARK) / 100;
+	cfshm->low_xoff_water =
+		(shm->cfg.rx.buffers * LOW_XOFF_WATERMARK) / 100;
+	cfshm->stuff_mark = (shm->cfg.rx.buffers * STUFF_MARK) / 100;
+
+	cfshm->tx_frms_pr_buf = shm->cfg.tx.packets;
+	cfshm->rx_frms_pr_buf = shm->cfg.rx.packets;
+	cfshm->rx_alignment = shm->cfg.rx.alignment;
+	cfshm->tx_alignment = shm->cfg.tx.alignment;
+
+	if (shm->cfg.latency)
+		cfshm->cfdev.link_select = CAIF_LINK_LOW_LATENCY;
+	else
+		cfshm->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+
+	cfshm->tx.rip = shm->cfg.tx.read;
+	cfshm->tx.wip = shm->cfg.tx.write;
+	cfshm->tx.bufsize = shm->cfg.tx.buf_size;
+	cfshm->tx.size = shm->cfg.tx.buffers;
+
+	cfshm->rx.rip = shm->cfg.rx.read;
+	cfshm->rx.wip = shm->cfg.rx.write;
+	cfshm->rx.bufsize = shm->cfg.rx.buf_size;
+	cfshm->rx.size = shm->cfg.rx.buffers;
+	pr_devel("RX ri:%d wi:%d size:%d\n",
+		le32_to_cpu(*cfshm->rx.rip),
+			le32_to_cpu(*cfshm->rx.wip), cfshm->rx.size);
+	pr_devel("TX ri:%d wi:%d size:%d\n",
+		le32_to_cpu(*cfshm->tx.rip),
+			le32_to_cpu(*cfshm->tx.wip), cfshm->rx.size);
+	pr_devel("frms_pr_buf:%d %d\n", cfshm->rx_frms_pr_buf,
+			cfshm->tx_frms_pr_buf);
+
+	spin_lock_init(&cfshm->lock);
+	netif_carrier_off(netdev);
+	skb_queue_head_init(&cfshm->sk_qhead);
+
+	pr_devel("SHM DEVICE[%p] PROBED BY DRIVER, NEW SHM DRIVER"
+			" INSTANCE AT cfshm =0x%p\n",
+			cfshm->shm, cfshm);
+
+	cfshm->tx_ringbuf = shm->cfg.tx.addr;
+	cfshm->rx_ringbuf = shm->cfg.rx.addr;
+
+	pr_devel("TX-BASE:%p RX-BASE:%p\n",
+			cfshm->tx_ringbuf,
+			cfshm->rx_ringbuf);
+
+	cfshm->tx_bufs = kzalloc(sizeof(struct shmbuffer *) *
+			shm->cfg.tx.buffers, GFP_KERNEL);
+	if (cfshm->tx_bufs == NULL)
+		goto error;
+	buf_size = shm->cfg.tx.ch_size / shm->cfg.tx.buffers;
+
+	pr_devel("TX: buffers:%d buf_size:%d frms:%d mtu:%d\n",
+			shm->cfg.tx.buffers, buf_size,
+			cfshm->tx_frms_pr_buf, netdev->mtu);
+
+	for (j = 0; j < shm->cfg.tx.buffers; j++) {
+		u32 desc_size;
+		struct shmbuffer *tx_buf =
+				kzalloc(sizeof(struct shmbuffer), GFP_KERNEL);
+
+		if (tx_buf == NULL) {
+			pr_warn("ERROR, Could not"
+					" allocate dynamic mem. for tx_buf, "
+					" Bailing out ...\n");
+			goto error;
+		}
+
+		tx_buf->index = j;
+
+		tx_buf->addr = cfshm->tx_ringbuf + (buf_size * j);
+		tx_buf->len = buf_size;
+		tx_buf->frames = 0;
+		desc_size = (cfshm->tx_frms_pr_buf + 1) *
+				sizeof(struct shm_pck_desc);
+
+		tx_buf->frm_ofs = desc_size + (desc_size % cfshm->tx_alignment);
+
+		cfshm->tx_bufs[j] = tx_buf;
+
+		pr_devel("tx_buf[%d] addr:%p len:%d\n",
+				tx_buf->index,
+				tx_buf->addr,
+				tx_buf->len);
+	}
+
+	cfshm->rx_bufs = kzalloc(sizeof(struct shmbuffer *) *
+				shm->cfg.rx.buffers, GFP_KERNEL);
+	if (cfshm->rx_bufs == NULL)
+		goto error;
+	buf_size = shm->cfg.tx.ch_size / shm->cfg.tx.buffers;
+	pr_devel("RX: buffers:%d buf_size:%d frms:%d mtu:%d\n",
+			shm->cfg.rx.buffers, buf_size,
+			cfshm->rx_frms_pr_buf, netdev->mtu);
+
+	for (j = 0; j < shm->cfg.rx.buffers; j++) {
+		struct shmbuffer *rx_buf =
+				kzalloc(sizeof(struct shmbuffer), GFP_KERNEL);
+
+		if (rx_buf == NULL) {
+			pr_warn("ERROR, Could not"
+					" allocate dynamic mem.for rx_buf, "
+					" Bailing out ...\n");
+			goto error;
+		}
+
+		rx_buf->index = j;
+
+		rx_buf->addr = cfshm->rx_ringbuf + (buf_size * j);
+		rx_buf->len = buf_size;
+		cfshm->rx_bufs[j] = rx_buf;
+		pr_devel("rx_buf[%d] addr:%p len:%d\n",
+				rx_buf->index,
+				rx_buf->addr,
+				rx_buf->len);
+	}
+
+	cfshm->tx_flow_on = 1;
+	cfshm->shm->ipc_rx_cb = caif_shmdrv_rx_cb;
+	cfshm->shm->ipc_tx_release_cb = caif_shmdrv_tx_release_cb;
+	cfshm->shm->open_cb = open_cb;
+	cfshm->shm->close_cb = close_cb;
+
+	spin_lock_irqsave(&cfshm->lock, flags);
+	get_tx_buf(cfshm);
+	new_rx_buf(cfshm);
+	spin_unlock_irqrestore(&cfshm->lock, flags);
+
+	netif_napi_add(netdev, &cfshm->napi, shm_rx_poll,
+			2 * cfshm->rx_frms_pr_buf);
+
+	netdev->dev.parent = &shm->dev;
+	err = register_netdev(netdev);
+	if (err) {
+		pr_warn("ERROR[%d], SHM could not, "
+			"register with NW FRMWK Bailing out ...\n", err);
+		goto error;
+	}
+	return err;
+error:
+	deinit_bufs(cfshm);
+	free_netdev(netdev);
+	return err;
+}
+
+static void cfshm_remove(struct shm_dev *shm)
+{
+	struct cfshm *cfshm;
+
+	if (shm == NULL || shm->driver_data == NULL)
+		return;
+
+	cfshm = shm->driver_data;
+	deinit_bufs(cfshm);
+	unregister_netdev(cfshm->ndev);
+
+	shm->ipc_rx_cb = NULL;
+	shm->ipc_tx_release_cb = NULL;
+	shm->open_cb = NULL;
+	shm->close_cb = NULL;
+	shm->driver_data = NULL;
+}
+
+static struct shm_driver cfshm_drv = {
+	.mode = SHM_PACKET_MODE,
+	.probe = cfshm_probe,
+	.remove = cfshm_remove,
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static void __exit cfshm_exit_module(void)
+{
+	modem_shm_unregister_driver(&cfshm_drv);
+}
+
+static int __init cfshm_init_module(void)
+{
+	int err;
+
+	err = modem_shm_register_driver(&cfshm_drv);
+	if (err) {
+		printk(KERN_ERR "Could not register SHM driver: %d.\n",
+			err);
+		goto err_dev_register;
+	}
+	return err;
+
+ err_dev_register:
+	return err;
+}
+
+module_init(cfshm_init_module);
+module_exit(cfshm_exit_module);
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index ab45758..bb709fd 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -103,11 +103,11 @@ config CAN_FLEXCAN
 	  Say Y here if you want to support for Freescale FlexCAN.
 
 config PCH_CAN
-	tristate "PCH CAN"
+	tristate "Intel EG20T PCH CAN controller"
 	depends on CAN_DEV && PCI
 	---help---
-	  This driver is for PCH CAN of Topcliff which is an IOH for x86
-	  embedded processor.
+	  This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which
+	  is an IOH for x86 embedded processor (Intel Atom E6xx series).
 	  This driver can access CAN bus.
 
 source "drivers/net/can/mscan/Kconfig"
diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c
index 349e0fa..3f88473 100644
--- a/drivers/net/can/bfin_can.c
+++ b/drivers/net/can/bfin_can.c
@@ -82,8 +82,7 @@ static int bfin_can_set_bittiming(struct net_device *dev)
 	bfin_write(&reg->clock, clk);
 	bfin_write(&reg->timing, timing);
 
-	dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n",
-			clk, timing);
+	netdev_info(dev, "setting CLOCK=0x%04x TIMING=0x%04x\n", clk, timing);
 
 	return 0;
 }
@@ -108,8 +107,7 @@ static void bfin_can_set_reset_mode(struct net_device *dev)
 	while (!(bfin_read(&reg->control) & CCA)) {
 		udelay(10);
 		if (--timeout == 0) {
-			dev_err(dev->dev.parent,
-					"fail to enter configuration mode\n");
+			netdev_err(dev, "fail to enter configuration mode\n");
 			BUG();
 		}
 	}
@@ -165,8 +163,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev)
 	while (bfin_read(&reg->status) & CCA) {
 		udelay(10);
 		if (--timeout == 0) {
-			dev_err(dev->dev.parent,
-					"fail to leave configuration mode\n");
+			netdev_err(dev, "fail to leave configuration mode\n");
 			BUG();
 		}
 	}
@@ -224,6 +221,20 @@ static int bfin_can_set_mode(struct net_device *dev, enum can_mode mode)
 	return 0;
 }
 
+static int bfin_can_get_berr_counter(const struct net_device *dev,
+				     struct can_berr_counter *bec)
+{
+	struct bfin_can_priv *priv = netdev_priv(dev);
+	struct bfin_can_regs __iomem *reg = priv->membase;
+
+	u16 cec = bfin_read(&reg->cec);
+
+	bec->txerr = cec >> 8;
+	bec->rxerr = cec;
+
+	return 0;
+}
+
 static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bfin_can_priv *priv = netdev_priv(dev);
@@ -331,7 +342,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status)
 
 	if (isrc & RMLIS) {
 		/* data overrun interrupt */
-		dev_dbg(dev->dev.parent, "data overrun interrupt\n");
+		netdev_dbg(dev, "data overrun interrupt\n");
 		cf->can_id |= CAN_ERR_CRTL;
 		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 		stats->rx_over_errors++;
@@ -339,7 +350,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status)
 	}
 
 	if (isrc & BOIS) {
-		dev_dbg(dev->dev.parent, "bus-off mode interrupt\n");
+		netdev_dbg(dev, "bus-off mode interrupt\n");
 		state = CAN_STATE_BUS_OFF;
 		cf->can_id |= CAN_ERR_BUSOFF;
 		can_bus_off(dev);
@@ -347,13 +358,12 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status)
 
 	if (isrc & EPIS) {
 		/* error passive interrupt */
-		dev_dbg(dev->dev.parent, "error passive interrupt\n");
+		netdev_dbg(dev, "error passive interrupt\n");
 		state = CAN_STATE_ERROR_PASSIVE;
 	}
 
 	if ((isrc & EWTIS) || (isrc & EWRIS)) {
-		dev_dbg(dev->dev.parent,
-				"Error Warning Transmit/Receive Interrupt\n");
+		netdev_dbg(dev, "Error Warning Transmit/Receive Interrupt\n");
 		state = CAN_STATE_ERROR_WARNING;
 	}
 
@@ -509,6 +519,7 @@ struct net_device *alloc_bfin_candev(void)
 	priv->can.bittiming_const = &bfin_can_bittiming_const;
 	priv->can.do_set_bittiming = bfin_can_set_bittiming;
 	priv->can.do_set_mode = bfin_can_set_mode;
+	priv->can.do_get_berr_counter = bfin_can_get_berr_counter;
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	return dev;
@@ -636,8 +647,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg)
 		while (!(bfin_read(&reg->intr) & SMACK)) {
 			udelay(10);
 			if (--timeout == 0) {
-				dev_err(dev->dev.parent,
-						"fail to enter sleep mode\n");
+				netdev_err(dev, "fail to enter sleep mode\n");
 				BUG();
 			}
 		}
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 120f1ab..c5fe3a3 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -130,13 +130,13 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
 		/* Error in one-tenth of a percent */
 		error = (best_error * 1000) / bt->bitrate;
 		if (error > CAN_CALC_MAX_ERROR) {
-			dev_err(dev->dev.parent,
-				"bitrate error %ld.%ld%% too high\n",
-				error / 10, error % 10);
+			netdev_err(dev,
+				   "bitrate error %ld.%ld%% too high\n",
+				   error / 10, error % 10);
 			return -EDOM;
 		} else {
-			dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n",
-				 error / 10, error % 10);
+			netdev_warn(dev, "bitrate error %ld.%ld%%\n",
+				    error / 10, error % 10);
 		}
 	}
 
@@ -172,7 +172,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
 #else /* !CONFIG_CAN_CALC_BITTIMING */
 static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
 {
-	dev_err(dev->dev.parent, "bit-timing calculation not available\n");
+	netdev_err(dev, "bit-timing calculation not available\n");
 	return -EINVAL;
 }
 #endif /* CONFIG_CAN_CALC_BITTIMING */
@@ -313,8 +313,7 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 		priv->echo_skb[idx] = skb;
 	} else {
 		/* locking problem with netif_stop_queue() ?? */
-		dev_err(dev->dev.parent, "%s: BUG! echo_skb is occupied!\n",
-			__func__);
+		netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__);
 		kfree_skb(skb);
 	}
 }
@@ -327,16 +326,24 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
  * is handled in the device driver. The driver must protect
  * access to priv->echo_skb, if necessary.
  */
-void can_get_echo_skb(struct net_device *dev, unsigned int idx)
+unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
 	BUG_ON(idx >= priv->echo_skb_max);
 
 	if (priv->echo_skb[idx]) {
+		struct sk_buff *skb = priv->echo_skb[idx];
+		struct can_frame *cf = (struct can_frame *)skb->data;
+		u8 dlc = cf->can_dlc;
+
 		netif_rx(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
+
+		return dlc;
 	}
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(can_get_echo_skb);
 
@@ -392,7 +399,7 @@ void can_restart(unsigned long data)
 	stats->rx_bytes += cf->can_dlc;
 
 restart:
-	dev_dbg(dev->dev.parent, "restarted\n");
+	netdev_dbg(dev, "restarted\n");
 	priv->can_stats.restarts++;
 
 	/* Now restart the device */
@@ -400,7 +407,7 @@ restart:
 
 	netif_carrier_on(dev);
 	if (err)
-		dev_err(dev->dev.parent, "Error %d during restart", err);
+		netdev_err(dev, "Error %d during restart", err);
 }
 
 int can_restart_now(struct net_device *dev)
@@ -433,7 +440,7 @@ void can_bus_off(struct net_device *dev)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	dev_dbg(dev->dev.parent, "bus-off\n");
+	netdev_dbg(dev, "bus-off\n");
 
 	netif_carrier_off(dev);
 	priv->can_stats.bus_off++;
@@ -545,7 +552,7 @@ int open_candev(struct net_device *dev)
 	struct can_priv *priv = netdev_priv(dev);
 
 	if (!priv->bittiming.tq && !priv->bittiming.bitrate) {
-		dev_err(dev->dev.parent, "bit-timing not yet defined\n");
+		netdev_err(dev, "bit-timing not yet defined\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 96d2357..1efb083 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -272,7 +272,6 @@ static int flexcan_get_berr_counter(const struct net_device *dev,
 static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	const struct flexcan_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct flexcan_regs __iomem *regs = priv->base;
 	struct can_frame *cf = (struct can_frame *)skb->data;
 	u32 can_id;
@@ -302,14 +301,11 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		flexcan_write(data, &regs->cantxfg[FLEXCAN_TX_BUF_ID].data[1]);
 	}
 
+	can_put_echo_skb(skb, dev, 0);
+
 	flexcan_write(can_id, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_id);
 	flexcan_write(ctrl, &regs->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl);
 
-	kfree_skb(skb);
-
-	/* tx_packets is incremented in flexcan_irq */
-	stats->tx_bytes += cf->can_dlc;
-
 	return NETDEV_TX_OK;
 }
 
@@ -322,34 +318,34 @@ static void do_bus_err(struct net_device *dev,
 	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 	if (reg_esr & FLEXCAN_ESR_BIT1_ERR) {
-		dev_dbg(dev->dev.parent, "BIT1_ERR irq\n");
+		netdev_dbg(dev, "BIT1_ERR irq\n");
 		cf->data[2] |= CAN_ERR_PROT_BIT1;
 		tx_errors = 1;
 	}
 	if (reg_esr & FLEXCAN_ESR_BIT0_ERR) {
-		dev_dbg(dev->dev.parent, "BIT0_ERR irq\n");
+		netdev_dbg(dev, "BIT0_ERR irq\n");
 		cf->data[2] |= CAN_ERR_PROT_BIT0;
 		tx_errors = 1;
 	}
 	if (reg_esr & FLEXCAN_ESR_ACK_ERR) {
-		dev_dbg(dev->dev.parent, "ACK_ERR irq\n");
+		netdev_dbg(dev, "ACK_ERR irq\n");
 		cf->can_id |= CAN_ERR_ACK;
 		cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
 		tx_errors = 1;
 	}
 	if (reg_esr & FLEXCAN_ESR_CRC_ERR) {
-		dev_dbg(dev->dev.parent, "CRC_ERR irq\n");
+		netdev_dbg(dev, "CRC_ERR irq\n");
 		cf->data[2] |= CAN_ERR_PROT_BIT;
 		cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
 		rx_errors = 1;
 	}
 	if (reg_esr & FLEXCAN_ESR_FRM_ERR) {
-		dev_dbg(dev->dev.parent, "FRM_ERR irq\n");
+		netdev_dbg(dev, "FRM_ERR irq\n");
 		cf->data[2] |= CAN_ERR_PROT_FORM;
 		rx_errors = 1;
 	}
 	if (reg_esr & FLEXCAN_ESR_STF_ERR) {
-		dev_dbg(dev->dev.parent, "STF_ERR irq\n");
+		netdev_dbg(dev, "STF_ERR irq\n");
 		cf->data[2] |= CAN_ERR_PROT_STUFF;
 		rx_errors = 1;
 	}
@@ -396,7 +392,7 @@ static void do_state(struct net_device *dev,
 		 */
 		if (new_state >= CAN_STATE_ERROR_WARNING &&
 		    new_state <= CAN_STATE_BUS_OFF) {
-			dev_dbg(dev->dev.parent, "Error Warning IRQ\n");
+			netdev_dbg(dev, "Error Warning IRQ\n");
 			priv->can.can_stats.error_warning++;
 
 			cf->can_id |= CAN_ERR_CRTL;
@@ -412,7 +408,7 @@ static void do_state(struct net_device *dev,
 		 */
 		if (new_state >= CAN_STATE_ERROR_PASSIVE &&
 		    new_state <= CAN_STATE_BUS_OFF) {
-			dev_dbg(dev->dev.parent, "Error Passive IRQ\n");
+			netdev_dbg(dev, "Error Passive IRQ\n");
 			priv->can.can_stats.error_passive++;
 
 			cf->can_id |= CAN_ERR_CRTL;
@@ -422,8 +418,8 @@ static void do_state(struct net_device *dev,
 		}
 		break;
 	case CAN_STATE_BUS_OFF:
-		dev_err(dev->dev.parent,
-			"BUG! hardware recovered automatically from BUS_OFF\n");
+		netdev_err(dev, "BUG! "
+			   "hardware recovered automatically from BUS_OFF\n");
 		break;
 	default:
 		break;
@@ -432,7 +428,7 @@ static void do_state(struct net_device *dev,
 	/* process state changes depending on the new state */
 	switch (new_state) {
 	case CAN_STATE_ERROR_ACTIVE:
-		dev_dbg(dev->dev.parent, "Error Active\n");
+		netdev_dbg(dev, "Error Active\n");
 		cf->can_id |= CAN_ERR_PROT;
 		cf->data[2] = CAN_ERR_PROT_ACTIVE;
 		break;
@@ -614,7 +610,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
 
 	/* transmission complete interrupt */
 	if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
-		/* tx_bytes is incremented in flexcan_start_xmit */
+		stats->tx_bytes += can_get_echo_skb(dev, 0);
 		stats->tx_packets++;
 		flexcan_write((1 << FLEXCAN_TX_BUF_ID), &regs->iflag1);
 		netif_wake_queue(dev);
@@ -653,12 +649,12 @@ static void flexcan_set_bittiming(struct net_device *dev)
 	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
 		reg |= FLEXCAN_CTRL_SMP;
 
-	dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg);
+	netdev_info(dev, "writing ctrl=0x%08x\n", reg);
 	flexcan_write(reg, &regs->ctrl);
 
 	/* print chip status */
-	dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
-		flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+	netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
+		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
 }
 
 /*
@@ -684,9 +680,8 @@ static int flexcan_chip_start(struct net_device *dev)
 
 	reg_mcr = flexcan_read(&regs->mcr);
 	if (reg_mcr & FLEXCAN_MCR_SOFTRST) {
-		dev_err(dev->dev.parent,
-			"Failed to softreset can module (mcr=0x%08x)\n",
-			reg_mcr);
+		netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n",
+			   reg_mcr);
 		err = -ENODEV;
 		goto out;
 	}
@@ -702,13 +697,14 @@ static int flexcan_chip_start(struct net_device *dev)
 	 * only supervisor access
 	 * enable warning int
 	 * choose format C
+	 * disable local echo
 	 *
 	 */
 	reg_mcr = flexcan_read(&regs->mcr);
 	reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
 		FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
-		FLEXCAN_MCR_IDAM_C;
-	dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
+		FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS;
+	netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
 	flexcan_write(reg_mcr, &regs->mcr);
 
 	/*
@@ -734,7 +730,7 @@ static int flexcan_chip_start(struct net_device *dev)
 
 	/* save for later use */
 	priv->reg_ctrl_default = reg_ctrl;
-	dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
+	netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
 	flexcan_write(reg_ctrl, &regs->ctrl);
 
 	for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) {
@@ -766,8 +762,8 @@ static int flexcan_chip_start(struct net_device *dev)
 	flexcan_write(FLEXCAN_IFLAG_DEFAULT, &regs->imask1);
 
 	/* print chip status */
-	dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n",
-		__func__, flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
+	netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
+		   flexcan_read(&regs->mcr), flexcan_read(&regs->ctrl));
 
 	return 0;
 
@@ -905,8 +901,7 @@ static int __devinit register_flexcandev(struct net_device *dev)
 	 */
 	reg = flexcan_read(&regs->mcr);
 	if (!(reg & FLEXCAN_MCR_FEN)) {
-		dev_err(dev->dev.parent,
-			"Could not enable RX FIFO, unsupported core\n");
+		netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
 		err = -ENODEV;
 		goto out;
 	}
@@ -975,7 +970,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
 		goto failed_map;
 	}
 
-	dev = alloc_candev(sizeof(struct flexcan_priv), 0);
+	dev = alloc_candev(sizeof(struct flexcan_priv), 1);
 	if (!dev) {
 		err = -ENOMEM;
 		goto failed_alloc;
@@ -983,7 +978,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
 
 	dev->netdev_ops = &flexcan_netdev_ops;
 	dev->irq = irq;
-	dev->flags |= IFF_ECHO; /* we support local echo in hardware */
+	dev->flags |= IFF_ECHO;
 
 	priv = netdev_priv(dev);
 	priv->can.clock.freq = clock_freq;
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index 330140e..346785c 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -712,8 +712,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1)
 		frame->data[1] = data1;
 		netif_rx_ni(skb);
 	} else {
-		dev_err(&net->dev,
-			"cannot allocate error skb\n");
+		netdev_err(net, "cannot allocate error skb\n");
 	}
 }
 
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 1c82dd8..41a2a2d 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -95,9 +95,9 @@ static int mscan_set_mode(struct net_device *dev, u8 mode)
 			 * any, at once.
 			 */
 			if (i >= MSCAN_SET_MODE_RETRIES)
-				dev_dbg(dev->dev.parent,
-					"device failed to enter sleep mode. "
-					"We proceed anyhow.\n");
+				netdev_dbg(dev,
+					   "device failed to enter sleep mode. "
+					   "We proceed anyhow.\n");
 			else
 				priv->can.state = CAN_STATE_SLEEPING;
 		}
@@ -213,7 +213,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	switch (hweight8(i)) {
 	case 0:
 		netif_stop_queue(dev);
-		dev_err(dev->dev.parent, "Tx Ring full when queue awake!\n");
+		netdev_err(dev, "Tx Ring full when queue awake!\n");
 		return NETDEV_TX_BUSY;
 	case 1:
 		/*
@@ -352,7 +352,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame,
 	struct net_device_stats *stats = &dev->stats;
 	enum can_state old_state;
 
-	dev_dbg(dev->dev.parent, "error interrupt (canrflg=%#x)\n", canrflg);
+	netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg);
 	frame->can_id = CAN_ERR_FLAG;
 
 	if (canrflg & MSCAN_OVRIF) {
@@ -427,7 +427,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)
 		skb = alloc_can_skb(dev, &frame);
 		if (!skb) {
 			if (printk_ratelimit())
-				dev_notice(dev->dev.parent, "packet dropped\n");
+				netdev_notice(dev, "packet dropped\n");
 			stats->rx_dropped++;
 			out_8(&regs->canrflg, canrflg);
 			continue;
@@ -551,8 +551,7 @@ static int mscan_do_set_bittiming(struct net_device *dev)
 		BTR1_SET_TSEG2(bt->phase_seg2) |
 		BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES));
 
-	dev_info(dev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n",
-		btr0, btr1);
+	netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
 
 	out_8(&regs->canbtr0, btr0);
 	out_8(&regs->canbtr1, btr1);
@@ -560,6 +559,18 @@ static int mscan_do_set_bittiming(struct net_device *dev)
 	return 0;
 }
 
+static int mscan_get_berr_counter(const struct net_device *dev,
+				  struct can_berr_counter *bec)
+{
+	struct mscan_priv *priv = netdev_priv(dev);
+	struct mscan_regs __iomem *regs = priv->reg_base;
+
+	bec->txerr = in_8(&regs->cantxerr);
+	bec->rxerr = in_8(&regs->canrxerr);
+
+	return 0;
+}
+
 static int mscan_open(struct net_device *dev)
 {
 	int ret;
@@ -575,7 +586,7 @@ static int mscan_open(struct net_device *dev)
 
 	ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev);
 	if (ret < 0) {
-		dev_err(dev->dev.parent, "failed to attach interrupt\n");
+		netdev_err(dev, "failed to attach interrupt\n");
 		goto exit_napi_disable;
 	}
 
@@ -639,8 +650,10 @@ int register_mscandev(struct net_device *dev, int mscan_clksrc)
 	else
 		ctl1 &= ~MSCAN_CLKSRC;
 
-	if (priv->type == MSCAN_TYPE_MPC5121)
+	if (priv->type == MSCAN_TYPE_MPC5121) {
+		priv->can.do_get_berr_counter = mscan_get_berr_counter;
 		ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */
+	}
 
 	ctl1 |= MSCAN_CANE;
 	out_8(&regs->canctl1, ctl1);
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 6edc25e..2bb215e 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999 - 2010 Intel Corporation.
- * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
+ * Copyright (C) 2010 LAPIS SEMICONDUCTOR CO., LTD.
  *
  * 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
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
index 36e9d59..b21523d 100644
--- a/drivers/net/can/sja1000/Kconfig
+++ b/drivers/net/can/sja1000/Kconfig
@@ -71,6 +71,7 @@ config CAN_PLX_PCI
 	   - esd CAN-PCIe/2000
 	   - Marathon CAN-bus-PCI card (http://www.marathon.ru/)
 	   - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
+	   - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
 
 config CAN_TSCAN1
 	tristate "TS-CAN1 PC104 boards"
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c
index c7f3d4e..a227586 100644
--- a/drivers/net/can/sja1000/plx_pci.c
+++ b/drivers/net/can/sja1000/plx_pci.c
@@ -43,7 +43,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, "
 			"TEWS TECHNOLOGIES TPMC810, "
 			"esd CAN-PCI/CPCI/PCI104/200, "
 			"esd CAN-PCI/PMC/266, "
-			"esd CAN-PCIe/2000")
+			"esd CAN-PCIe/2000, "
+			"IXXAT PC-I 04/PCI")
 MODULE_LICENSE("GPL v2");
 
 #define PLX_PCI_MAX_CHAN 2
@@ -121,6 +122,10 @@ struct plx_pci_card {
 #define ESD_PCI_SUB_SYS_ID_PCIE2000	0x0200
 #define ESD_PCI_SUB_SYS_ID_PCI104200	0x0501
 
+#define IXXAT_PCI_VENDOR_ID		0x10b5
+#define IXXAT_PCI_DEVICE_ID		0x9050
+#define IXXAT_PCI_SUB_SYS_ID		0x2540
+
 #define MARATHON_PCI_DEVICE_ID		0x2715
 
 #define TEWS_PCI_VENDOR_ID		0x1498
@@ -193,6 +198,14 @@ static struct plx_pci_card_info plx_pci_card_info_esd2000 __devinitdata = {
 	/* based on PEX8311 */
 };
 
+static struct plx_pci_card_info plx_pci_card_info_ixxat __devinitdata = {
+	"IXXAT PC-I 04/PCI", 2,
+	PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
+	{0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x200, 0x80} },
+	&plx_pci_reset_common
+	/* based on PLX9050 */
+};
+
 static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = {
 	"Marathon CAN-bus-PCI", 2,
 	PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR,
@@ -267,6 +280,13 @@ static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = {
 		(kernel_ulong_t)&plx_pci_card_info_esd2000
 	},
 	{
+		/* IXXAT PC-I 04/PCI card */
+		IXXAT_PCI_VENDOR_ID, IXXAT_PCI_DEVICE_ID,
+		PCI_ANY_ID, IXXAT_PCI_SUB_SYS_ID,
+		0, 0,
+		(kernel_ulong_t)&plx_pci_card_info_ixxat
+	},
+	{
 		/* Marathon CAN-bus-PCI card */
 		PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID,
 		PCI_ANY_ID, PCI_ANY_ID,
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 04a3f1b..5e10472 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -95,11 +95,16 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
 	spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
 }
 
+static int sja1000_is_absent(struct sja1000_priv *priv)
+{
+	return (priv->read_reg(priv, REG_MOD) == 0xFF);
+}
+
 static int sja1000_probe_chip(struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
 
-	if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+	if (priv->reg_base && sja1000_is_absent(priv)) {
 		printk(KERN_INFO "%s: probing @0x%lX failed\n",
 		       DRV_NAME, dev->base_addr);
 		return 0;
@@ -128,7 +133,7 @@ static void set_reset_mode(struct net_device *dev)
 		status = priv->read_reg(priv, REG_MOD);
 	}
 
-	dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n");
+	netdev_err(dev, "setting SJA1000 into reset mode failed!\n");
 }
 
 static void set_normal_mode(struct net_device *dev)
@@ -156,7 +161,7 @@ static void set_normal_mode(struct net_device *dev)
 		status = priv->read_reg(priv, REG_MOD);
 	}
 
-	dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n");
+	netdev_err(dev, "setting SJA1000 into normal mode failed!\n");
 }
 
 static void sja1000_start(struct net_device *dev)
@@ -209,8 +214,7 @@ static int sja1000_set_bittiming(struct net_device *dev)
 	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
 		btr1 |= 0x80;
 
-	dev_info(dev->dev.parent,
-		 "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+	netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
 
 	priv->write_reg(priv, REG_BTR0, btr0);
 	priv->write_reg(priv, REG_BTR1, btr1);
@@ -378,7 +382,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 
 	if (isrc & IRQ_DOI) {
 		/* data overrun interrupt */
-		dev_dbg(dev->dev.parent, "data overrun interrupt\n");
+		netdev_dbg(dev, "data overrun interrupt\n");
 		cf->can_id |= CAN_ERR_CRTL;
 		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 		stats->rx_over_errors++;
@@ -388,7 +392,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 
 	if (isrc & IRQ_EI) {
 		/* error warning interrupt */
-		dev_dbg(dev->dev.parent, "error warning interrupt\n");
+		netdev_dbg(dev, "error warning interrupt\n");
 
 		if (status & SR_BS) {
 			state = CAN_STATE_BUS_OFF;
@@ -429,7 +433,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 	}
 	if (isrc & IRQ_EPI) {
 		/* error passive interrupt */
-		dev_dbg(dev->dev.parent, "error passive interrupt\n");
+		netdev_dbg(dev, "error passive interrupt\n");
 		if (status & SR_ES)
 			state = CAN_STATE_ERROR_PASSIVE;
 		else
@@ -437,7 +441,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 	}
 	if (isrc & IRQ_ALI) {
 		/* arbitration lost interrupt */
-		dev_dbg(dev->dev.parent, "arbitration lost interrupt\n");
+		netdev_dbg(dev, "arbitration lost interrupt\n");
 		alc = priv->read_reg(priv, REG_ALC);
 		priv->can.can_stats.arbitration_lost++;
 		stats->tx_errors++;
@@ -493,9 +497,12 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 	while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
 		n++;
 		status = priv->read_reg(priv, REG_SR);
+		/* check for absent controller due to hw unplug */
+		if (status == 0xFF && sja1000_is_absent(priv))
+			return IRQ_NONE;
 
 		if (isrc & IRQ_WUI)
-			dev_warn(dev->dev.parent, "wakeup interrupt\n");
+			netdev_warn(dev, "wakeup interrupt\n");
 
 		if (isrc & IRQ_TI) {
 			/* transmission complete interrupt */
@@ -509,6 +516,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 			while (status & SR_RBS) {
 				sja1000_rx(dev);
 				status = priv->read_reg(priv, REG_SR);
+				/* check for absent controller */
+				if (status == 0xFF && sja1000_is_absent(priv))
+					return IRQ_NONE;
 			}
 		}
 		if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
@@ -522,7 +532,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 		priv->post_irq(priv);
 
 	if (n >= SJA1000_MAX_IRQ)
-		dev_dbg(dev->dev.parent, "%d messages handled in ISR", n);
+		netdev_dbg(dev, "%d messages handled in ISR", n);
 
 	return (n) ? IRQ_HANDLED : IRQ_NONE;
 }
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 3f1ebcc..98a5a7d 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -1,7 +1,7 @@
 /*
  * slcan.c - serial line CAN interface driver (using tty line discipline)
  *
- * This file is derived from linux/drivers/net/slip.c
+ * This file is derived from linux/drivers/net/slip/slip.c
  *
  * slip.c Authors  : Laurence Culhane <loz@holmes.demon.co.uk>
  *                   Fred N. van Kempen <waltje@uwalt.nl.mugnet.org>
@@ -639,10 +639,8 @@ static int __init slcan_init(void)
 	printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev);
 
 	slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
-	if (!slcan_devs) {
-		printk(KERN_ERR "slcan: can't allocate slcan device array!\n");
+	if (!slcan_devs)
 		return -ENOMEM;
-	}
 
 	/* Fill in our line protocol discipline, and register it */
 	status = tty_register_ldisc(N_SLCAN, &slc_ldisc);
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 5a2e1e3..4accd7e 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -306,7 +306,7 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv)
 		if (bit_timing->brp > 4)
 			can_btc |= HECC_CANBTC_SAM;
 		else
-			dev_warn(priv->ndev->dev.parent, "WARN: Triple" \
+			netdev_warn(priv->ndev, "WARN: Triple"
 				"sampling not set due to h/w limitations");
 	}
 	can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8;
@@ -315,7 +315,7 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv)
 	/* ERM being set to 0 by default meaning resync at falling edge */
 
 	hecc_write(priv, HECC_CANBTC, can_btc);
-	dev_info(priv->ndev->dev.parent, "setting CANBTC=%#x\n", can_btc);
+	netdev_info(priv->ndev, "setting CANBTC=%#x\n", can_btc);
 
 	return 0;
 }
@@ -332,7 +332,7 @@ static void ti_hecc_reset(struct net_device *ndev)
 	u32 cnt;
 	struct ti_hecc_priv *priv = netdev_priv(ndev);
 
-	dev_dbg(ndev->dev.parent, "resetting hecc ...\n");
+	netdev_dbg(ndev, "resetting hecc ...\n");
 	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SRES);
 
 	/* Set change control request and wait till enabled */
@@ -458,6 +458,17 @@ static int ti_hecc_do_set_mode(struct net_device *ndev, enum can_mode mode)
 	return ret;
 }
 
+static int ti_hecc_get_berr_counter(const struct net_device *ndev,
+					struct can_berr_counter *bec)
+{
+	struct ti_hecc_priv *priv = netdev_priv(ndev);
+
+	bec->txerr = hecc_read(priv, HECC_CANTEC);
+	bec->rxerr = hecc_read(priv, HECC_CANREC);
+
+	return 0;
+}
+
 /*
  * ti_hecc_xmit: HECC Transmit
  *
@@ -496,7 +507,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
 	if (unlikely(hecc_read(priv, HECC_CANME) & mbx_mask)) {
 		spin_unlock_irqrestore(&priv->mbx_lock, flags);
 		netif_stop_queue(ndev);
-		dev_err(priv->ndev->dev.parent,
+		netdev_err(priv->ndev,
 			"BUG: TX mbx not ready tx_head=%08X, tx_tail=%08X\n",
 			priv->tx_head, priv->tx_tail);
 		return NETDEV_TX_BUSY;
@@ -550,7 +561,7 @@ static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno)
 	skb = alloc_can_skb(priv->ndev, &cf);
 	if (!skb) {
 		if (printk_ratelimit())
-			dev_err(priv->ndev->dev.parent,
+			netdev_err(priv->ndev,
 				"ti_hecc_rx_pkt: alloc_can_skb() failed\n");
 		return -ENOMEM;
 	}
@@ -668,7 +679,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
 	skb = alloc_can_err_skb(ndev, &cf);
 	if (!skb) {
 		if (printk_ratelimit())
-			dev_err(priv->ndev->dev.parent,
+			netdev_err(priv->ndev,
 				"ti_hecc_error: alloc_can_err_skb() failed\n");
 		return -ENOMEM;
 	}
@@ -684,7 +695,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
 				cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
 		}
 		hecc_set_bit(priv, HECC_CANES, HECC_CANES_EW);
-		dev_dbg(priv->ndev->dev.parent, "Error Warning interrupt\n");
+		netdev_dbg(priv->ndev, "Error Warning interrupt\n");
 		hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
 	}
 
@@ -699,7 +710,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
 				cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
 		}
 		hecc_set_bit(priv, HECC_CANES, HECC_CANES_EP);
-		dev_dbg(priv->ndev->dev.parent, "Error passive interrupt\n");
+		netdev_dbg(priv->ndev, "Error passive interrupt\n");
 		hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
 	}
 
@@ -825,7 +836,7 @@ static int ti_hecc_open(struct net_device *ndev)
 	err = request_irq(ndev->irq, ti_hecc_interrupt, IRQF_SHARED,
 			ndev->name, ndev);
 	if (err) {
-		dev_err(ndev->dev.parent, "error requesting interrupt\n");
+		netdev_err(ndev, "error requesting interrupt\n");
 		return err;
 	}
 
@@ -834,7 +845,7 @@ static int ti_hecc_open(struct net_device *ndev)
 	/* Open common can device */
 	err = open_candev(ndev);
 	if (err) {
-		dev_err(ndev->dev.parent, "open_candev() failed %d\n", err);
+		netdev_err(ndev, "open_candev() failed %d\n", err);
 		ti_hecc_transceiver_switch(priv, 0);
 		free_irq(ndev->irq, ndev);
 		return err;
@@ -923,6 +934,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	priv->can.bittiming_const = &ti_hecc_bittiming_const;
 	priv->can.do_set_mode = ti_hecc_do_set_mode;
 	priv->can.do_get_state = ti_hecc_get_state;
+	priv->can.do_get_berr_counter = ti_hecc_get_berr_counter;
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
 
 	spin_lock_init(&priv->mbx_lock);
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 7dae64d..7ae65fc 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -288,8 +288,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb)
 		return;
 
 	default:
-		dev_info(netdev->dev.parent, "Rx interrupt aborted %d\n",
-			 urb->status);
+		netdev_info(netdev, "Rx interrupt aborted %d\n", urb->status);
 		break;
 	}
 
@@ -298,8 +297,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb)
 	if (err == -ENODEV)
 		netif_device_detach(netdev);
 	else if (err)
-		dev_err(netdev->dev.parent,
-			"failed resubmitting intr urb: %d\n", err);
+		netdev_err(netdev, "failed resubmitting intr urb: %d\n", err);
 }
 
 static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg)
@@ -431,8 +429,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
 		return;
 
 	default:
-		dev_info(netdev->dev.parent, "Rx URB aborted (%d)\n",
-			 urb->status);
+		netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status);
 		goto resubmit_urb;
 	}
 
@@ -477,7 +474,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb)
 			msg_count--;
 
 			if (start > urb->transfer_buffer_length) {
-				dev_err(netdev->dev.parent, "format error\n");
+				netdev_err(netdev, "format error\n");
 				break;
 			}
 		}
@@ -493,8 +490,8 @@ resubmit_urb:
 	if (retval == -ENODEV)
 		netif_device_detach(netdev);
 	else if (retval)
-		dev_err(netdev->dev.parent,
-			"failed resubmitting read bulk urb: %d\n", retval);
+		netdev_err(netdev,
+			   "failed resubmitting read bulk urb: %d\n", retval);
 }
 
 /*
@@ -521,8 +518,7 @@ static void ems_usb_write_bulk_callback(struct urb *urb)
 		return;
 
 	if (urb->status)
-		dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n",
-			 urb->status);
+		netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
 
 	netdev->trans_start = jiffies;
 
@@ -605,18 +601,18 @@ static int ems_usb_start(struct ems_usb *dev)
 		/* create a URB, and a buffer for it */
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!urb) {
-			dev_err(netdev->dev.parent,
-				"No memory left for URBs\n");
-			return -ENOMEM;
+			netdev_err(netdev, "No memory left for URBs\n");
+			err = -ENOMEM;
+			break;
 		}
 
 		buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
 					 &urb->transfer_dma);
 		if (!buf) {
-			dev_err(netdev->dev.parent,
-				"No memory left for USB buffer\n");
+			netdev_err(netdev, "No memory left for USB buffer\n");
 			usb_free_urb(urb);
-			return -ENOMEM;
+			err = -ENOMEM;
+			break;
 		}
 
 		usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
@@ -639,13 +635,13 @@ static int ems_usb_start(struct ems_usb *dev)
 
 	/* Did we submit any URBs */
 	if (i == 0) {
-		dev_warn(netdev->dev.parent, "couldn't setup read URBs\n");
+		netdev_warn(netdev, "couldn't setup read URBs\n");
 		return err;
 	}
 
 	/* Warn if we've couldn't transmit all the URBs */
 	if (i < MAX_RX_URBS)
-		dev_warn(netdev->dev.parent, "rx performance may be slow\n");
+		netdev_warn(netdev, "rx performance may be slow\n");
 
 	/* Setup and start interrupt URB */
 	usb_fill_int_urb(dev->intr_urb, dev->udev,
@@ -656,8 +652,7 @@ static int ems_usb_start(struct ems_usb *dev)
 
 	err = usb_submit_urb(dev->intr_urb, GFP_KERNEL);
 	if (err) {
-		dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n",
-			 err);
+		netdev_warn(netdev, "intr URB submit failed: %d\n", err);
 
 		return err;
 	}
@@ -686,7 +681,7 @@ static int ems_usb_start(struct ems_usb *dev)
 	return 0;
 
 failed:
-	dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err);
+	netdev_warn(netdev, "couldn't submit control: %d\n", err);
 
 	return err;
 }
@@ -726,8 +721,7 @@ static int ems_usb_open(struct net_device *netdev)
 		if (err == -ENODEV)
 			netif_device_detach(dev->netdev);
 
-		dev_warn(netdev->dev.parent, "couldn't start device: %d\n",
-			 err);
+		netdev_warn(netdev, "couldn't start device: %d\n", err);
 
 		close_candev(netdev);
 
@@ -760,13 +754,13 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
 	/* create a URB, and a buffer for it, and copy the data to the URB */
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
-		dev_err(netdev->dev.parent, "No memory left for URBs\n");
+		netdev_err(netdev, "No memory left for URBs\n");
 		goto nomem;
 	}
 
 	buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma);
 	if (!buf) {
-		dev_err(netdev->dev.parent, "No memory left for USB buffer\n");
+		netdev_err(netdev, "No memory left for USB buffer\n");
 		usb_free_urb(urb);
 		goto nomem;
 	}
@@ -809,7 +803,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
 		usb_unanchor_urb(urb);
 		usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
 
-		dev_warn(netdev->dev.parent, "couldn't find free context\n");
+		netdev_warn(netdev, "couldn't find free context\n");
 
 		return NETDEV_TX_BUSY;
 	}
@@ -840,7 +834,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
 		if (err == -ENODEV) {
 			netif_device_detach(netdev);
 		} else {
-			dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err);
+			netdev_warn(netdev, "failed tx_urb %d\n", err);
 
 			stats->tx_dropped++;
 		}
@@ -880,7 +874,7 @@ static int ems_usb_close(struct net_device *netdev)
 
 	/* Set CAN controller to reset mode */
 	if (ems_usb_write_mode(dev, SJA1000_MOD_RM))
-		dev_warn(netdev->dev.parent, "couldn't stop device");
+		netdev_warn(netdev, "couldn't stop device");
 
 	close_candev(netdev);
 
@@ -917,7 +911,7 @@ static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode)
 	switch (mode) {
 	case CAN_MODE_START:
 		if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL))
-			dev_warn(netdev->dev.parent, "couldn't start device");
+			netdev_warn(netdev, "couldn't start device");
 
 		if (netif_queue_stopped(netdev))
 			netif_wake_queue(netdev);
@@ -942,8 +936,7 @@ static int ems_usb_set_bittiming(struct net_device *netdev)
 	if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
 		btr1 |= 0x80;
 
-	dev_info(netdev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n",
-		 btr0, btr1);
+	netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
 
 	dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0;
 	dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1;
@@ -1048,15 +1041,13 @@ static int ems_usb_probe(struct usb_interface *intf,
 
 	err = ems_usb_command_msg(dev, &dev->active_params);
 	if (err) {
-		dev_err(netdev->dev.parent,
-			"couldn't initialize controller: %d\n", err);
+		netdev_err(netdev, "couldn't initialize controller: %d\n", err);
 		goto cleanup_tx_msg_buffer;
 	}
 
 	err = register_candev(netdev);
 	if (err) {
-		dev_err(netdev->dev.parent,
-			"couldn't register CAN device: %d\n", err);
+		netdev_err(netdev, "couldn't register CAN device: %d\n", err);
 		goto cleanup_tx_msg_buffer;
 	}
 
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
index 9277463..09b1da5 100644
--- a/drivers/net/can/usb/esd_usb2.c
+++ b/drivers/net/can/usb/esd_usb2.c
@@ -470,8 +470,7 @@ static void esd_usb2_write_bulk_callback(struct urb *urb)
 		return;
 
 	if (urb->status)
-		dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n",
-			 urb->status);
+		netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
 
 	netdev->trans_start = jiffies;
 }
@@ -651,7 +650,7 @@ failed:
 	if (err == -ENODEV)
 		netif_device_detach(netdev);
 
-	dev_err(netdev->dev.parent, "couldn't start device: %d\n", err);
+	netdev_err(netdev, "couldn't start device: %d\n", err);
 
 	return err;
 }
@@ -687,8 +686,7 @@ static int esd_usb2_open(struct net_device *netdev)
 	/* finally start device */
 	err = esd_usb2_start(priv);
 	if (err) {
-		dev_warn(netdev->dev.parent,
-			 "couldn't start device: %d\n", err);
+		netdev_warn(netdev, "couldn't start device: %d\n", err);
 		close_candev(netdev);
 		return err;
 	}
@@ -721,7 +719,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
 	/* create a URB, and a buffer for it, and copy the data to the URB */
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb) {
-		dev_err(netdev->dev.parent, "No memory left for URBs\n");
+		netdev_err(netdev, "No memory left for URBs\n");
 		stats->tx_dropped++;
 		dev_kfree_skb(skb);
 		goto nourbmem;
@@ -730,7 +728,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
 	buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC,
 				 &urb->transfer_dma);
 	if (!buf) {
-		dev_err(netdev->dev.parent, "No memory left for USB buffer\n");
+		netdev_err(netdev, "No memory left for USB buffer\n");
 		stats->tx_dropped++;
 		dev_kfree_skb(skb);
 		goto nobufmem;
@@ -766,7 +764,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
 	 * This may never happen.
 	 */
 	if (!context) {
-		dev_warn(netdev->dev.parent, "couldn't find free context\n");
+		netdev_warn(netdev, "couldn't find free context\n");
 		ret = NETDEV_TX_BUSY;
 		goto releasebuf;
 	}
@@ -806,7 +804,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
 		if (err == -ENODEV)
 			netif_device_detach(netdev);
 		else
-			dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err);
+			netdev_warn(netdev, "failed tx_urb %d\n", err);
 
 		goto releasebuf;
 	}
@@ -845,7 +843,7 @@ static int esd_usb2_close(struct net_device *netdev)
 	for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
 		msg.msg.filter.mask[i] = 0;
 	if (esd_usb2_send_msg(priv->usb2, &msg) < 0)
-		dev_err(netdev->dev.parent, "sending idadd message failed\n");
+		netdev_err(netdev, "sending idadd message failed\n");
 
 	/* set CAN controller to reset mode */
 	msg.msg.hdr.len = 2;
@@ -854,7 +852,7 @@ static int esd_usb2_close(struct net_device *netdev)
 	msg.msg.setbaud.rsvd = 0;
 	msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
 	if (esd_usb2_send_msg(priv->usb2, &msg) < 0)
-		dev_err(netdev->dev.parent, "sending setbaud message failed\n");
+		netdev_err(netdev, "sending setbaud message failed\n");
 
 	priv->can.state = CAN_STATE_STOPPED;
 
@@ -910,7 +908,7 @@ static int esd_usb2_set_bittiming(struct net_device *netdev)
 	msg.msg.setbaud.rsvd = 0;
 	msg.msg.setbaud.baud = cpu_to_le32(canbtr);
 
-	dev_info(netdev->dev.parent, "setting BTR=%#x\n", canbtr);
+	netdev_info(netdev, "setting BTR=%#x\n", canbtr);
 
 	return esd_usb2_send_msg(priv->usb2, &msg);
 }
@@ -988,15 +986,14 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index)
 
 	err = register_candev(netdev);
 	if (err) {
-		dev_err(&intf->dev,
-			"couldn't register CAN device: %d\n", err);
+		dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
 		free_candev(netdev);
 		err = -ENOMEM;
 		goto done;
 	}
 
 	dev->nets[index] = priv;
-	dev_info(netdev->dev.parent, "device %s registered\n", netdev->name);
+	netdev_info(netdev, "device %s registered\n", netdev->name);
 
 done:
 	return err;
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 7cb2785..c7e1df9 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -1132,7 +1132,6 @@ static irqreturn_t
 e100rxtx_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
-	struct net_local *np = netdev_priv(dev);
 	unsigned long irqbits;
 
 	/*
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 087648e..d5c6d92 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -47,6 +47,7 @@ static int dummy_set_address(struct net_device *dev, void *p)
 	if (!is_valid_ether_addr(sa->sa_data))
 		return -EADDRNOTAVAIL;
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
 	return 0;
 }
@@ -135,7 +136,7 @@ static void dummy_setup(struct net_device *dev)
 	dev->flags &= ~IFF_MULTICAST;
 	dev->features	|= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO;
 	dev->features	|= NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX;
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 }
 
 static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
diff --git a/drivers/net/ethernet/3com/3c501.c b/drivers/net/ethernet/3com/3c501.c
index 68da81d..bf73e1a 100644
--- a/drivers/net/ethernet/3com/3c501.c
+++ b/drivers/net/ethernet/3com/3c501.c
@@ -702,7 +702,7 @@ static void el_receive(struct net_device *dev)
 	 */
 
 	outb(AX_SYS, AX_CMD);
-	skb = dev_alloc_skb(pkt_len+2);
+	skb = netdev_alloc_skb(dev, pkt_len + 2);
 
 	/*
 	 *	Start of frame
diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c
index 92053e6..41719da 100644
--- a/drivers/net/ethernet/3com/3c509.c
+++ b/drivers/net/ethernet/3com/3c509.c
@@ -1066,7 +1066,7 @@ el3_rx(struct net_device *dev)
 			short pkt_len = rx_status & 0x7ff;
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len+5);
+			skb = netdev_alloc_skb(dev, pkt_len + 5);
 			if (el3_debug > 4)
 				pr_debug("Receiving packet size %d status %4.4x.\n",
 					   pkt_len, rx_status);
diff --git a/drivers/net/ethernet/3com/3c515.c b/drivers/net/ethernet/3com/3c515.c
index f67a5d3..59e1e00 100644
--- a/drivers/net/ethernet/3com/3c515.c
+++ b/drivers/net/ethernet/3com/3c515.c
@@ -826,11 +826,10 @@ static int corkscrew_open(struct net_device *dev)
 				vp->rx_ring[i].next = 0;
 			vp->rx_ring[i].status = 0;	/* Clear complete bit. */
 			vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
-			skb = dev_alloc_skb(PKT_BUF_SZ);
+			skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 			vp->rx_skbuff[i] = skb;
 			if (skb == NULL)
 				break;	/* Bad news!  */
-			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
 		}
@@ -1295,7 +1294,7 @@ static int corkscrew_rx(struct net_device *dev)
 			short pkt_len = rx_status & 0x1fff;
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len + 5 + 2);
+			skb = netdev_alloc_skb(dev, pkt_len + 5 + 2);
 			if (corkscrew_debug > 4)
 				pr_debug("Receiving packet size %d status %4.4x.\n",
 				     pkt_len, rx_status);
@@ -1368,7 +1367,7 @@ static int boomerang_rx(struct net_device *dev)
 			/* Check if the packet is long enough to just accept without
 			   copying to a properly sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 4)) != NULL) {
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				memcpy(skb_put(skb, pkt_len),
@@ -1403,10 +1402,9 @@ static int boomerang_rx(struct net_device *dev)
 		struct sk_buff *skb;
 		entry = vp->dirty_rx % RX_RING_SIZE;
 		if (vp->rx_skbuff[entry] == NULL) {
-			skb = dev_alloc_skb(PKT_BUF_SZ);
+			skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 			if (skb == NULL)
 				break;	/* Bad news!  */
-			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
 			vp->rx_skbuff[entry] = skb;
diff --git a/drivers/net/ethernet/3com/3c574_cs.c b/drivers/net/ethernet/3com/3c574_cs.c
index 9c01bc9..e61b2f8 100644
--- a/drivers/net/ethernet/3com/3c574_cs.c
+++ b/drivers/net/ethernet/3com/3c574_cs.c
@@ -1012,7 +1012,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
 			short pkt_len = rx_status & 0x7ff;
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len+5);
+			skb = netdev_alloc_skb(dev, pkt_len + 5);
 
 			pr_debug("  Receiving packet size %d status %4.4x.\n",
 				  pkt_len, rx_status);
diff --git a/drivers/net/ethernet/3com/3c589_cs.c b/drivers/net/ethernet/3com/3c589_cs.c
index da410f0..b23253b 100644
--- a/drivers/net/ethernet/3com/3c589_cs.c
+++ b/drivers/net/ethernet/3com/3c589_cs.c
@@ -819,7 +819,7 @@ static int el3_rx(struct net_device *dev)
 	    short pkt_len = rx_status & 0x7ff;
 	    struct sk_buff *skb;
 
-	    skb = dev_alloc_skb(pkt_len+5);
+	    skb = netdev_alloc_skb(dev, pkt_len + 5);
 
 	    netdev_dbg(dev, "    Receiving packet size %d status %4.4x.\n",
 		       pkt_len, rx_status);
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index f9b74c0..e463d10 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -1121,10 +1121,9 @@ static int __devinit vortex_probe1(struct device *gendev,
 
 	dev = alloc_etherdev(sizeof(*vp));
 	retval = -ENOMEM;
-	if (!dev) {
-		pr_err(PFX "unable to allocate etherdev, aborting\n");
+	if (!dev)
 		goto out;
-	}
+
 	SET_NETDEV_DEV(dev, gendev);
 	vp = netdev_priv(dev);
 
@@ -2500,7 +2499,7 @@ static int vortex_rx(struct net_device *dev)
 			int pkt_len = rx_status & 0x1fff;
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len + 5);
+			skb = netdev_alloc_skb(dev, pkt_len + 5);
 			if (vortex_debug > 4)
 				pr_debug("Receiving packet size %d status %4.4x.\n",
 					   pkt_len, rx_status);
@@ -2579,7 +2578,8 @@ boomerang_rx(struct net_device *dev)
 
 			/* Check if the packet is long enough to just accept without
 			   copying to a properly sized skbuff. */
-			if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			if (pkt_len < rx_copybreak &&
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 				pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				/* 'skb_put()' points to the start of sk_buff data area. */
diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig
index a8bb30c..bad4fa6 100644
--- a/drivers/net/ethernet/3com/Kconfig
+++ b/drivers/net/ethernet/3com/Kconfig
@@ -97,7 +97,7 @@ config VORTEX
 	  available from <http://www.tldp.org/docs.html#howto>. More
 	  specific information is in
 	  <file:Documentation/networking/vortex.txt> and in the comments at
-	  the beginning of <file:drivers/net/3c59x.c>.
+	  the beginning of <file:drivers/net/ethernet/3com/3c59x.c>.
 
 	  To compile this support as a module, choose M here.
 
diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c
index 6d6bc75..f7d622e 100644
--- a/drivers/net/ethernet/3com/typhoon.c
+++ b/drivers/net/ethernet/3com/typhoon.c
@@ -1607,7 +1607,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
 				le32_to_cpu(indexes->rxBuffCleared))
 		return -ENOMEM;
 
-	skb = dev_alloc_skb(PKT_BUF_SZ);
+	skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ);
 	if(!skb)
 		return -ENOMEM;
 
@@ -1618,7 +1618,6 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
 	skb_reserve(skb, 2);
 #endif
 
-	skb->dev = tp->dev;
 	dma_addr = pci_map_single(tp->pdev, skb->data,
 				  PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 
@@ -1673,7 +1672,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
 		pkt_len = le16_to_cpu(rx->frameLen);
 
 		if(pkt_len < rx_copybreak &&
-		   (new_skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+		   (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) {
 			skb_reserve(new_skb, 2);
 			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
 						    PKT_BUF_SZ,
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index 0f92e35..c30adcc 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -1,4 +1,4 @@
-/* drivers/net/ax88796.c
+/* drivers/net/ethernet/8390/ax88796.c
  *
  * Copyright 2005,2007 Simtec Electronics
  *	Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c
index bba51cd..c5bd8eb 100644
--- a/drivers/net/ethernet/8390/axnet_cs.c
+++ b/drivers/net/ethernet/8390/axnet_cs.c
@@ -192,7 +192,7 @@ static int get_prom(struct pcmcia_device *link)
     unsigned int ioaddr = dev->base_addr;
     int i, j;
 
-    /* This is based on drivers/net/ne.c */
+    /* This is based on drivers/net/ethernet/8390/ne.c */
     struct {
 	u_char value, offset;
     } program_seq[] = {
@@ -1408,7 +1408,7 @@ static void ei_receive(struct net_device *dev)
 		{
 			struct sk_buff *skb;
 			
-			skb = dev_alloc_skb(pkt_len+2);
+			skb = netdev_alloc_skb(dev, pkt_len + 2);
 			if (skb == NULL) 
 			{
 				if (ei_debug > 1)
diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c
index 05ae214..e77f624 100644
--- a/drivers/net/ethernet/8390/lib8390.c
+++ b/drivers/net/ethernet/8390/lib8390.c
@@ -717,7 +717,7 @@ static void ei_receive(struct net_device *dev)
 		} else if ((pkt_stat & 0x0F) == ENRSR_RXOK) {
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len+2);
+			skb = netdev_alloc_skb(dev, pkt_len + 2);
 			if (skb == NULL) {
 				if (ei_debug > 1)
 					netdev_dbg(dev, "Couldn't allocate a sk_buff of size %d\n",
diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c
index 053b255..f2a4e5d 100644
--- a/drivers/net/ethernet/8390/pcnet_cs.c
+++ b/drivers/net/ethernet/8390/pcnet_cs.c
@@ -326,7 +326,7 @@ static hw_info_t *get_prom(struct pcmcia_device *link)
     u_char prom[32];
     int i, j;
 
-    /* This is lifted straight from drivers/net/ne.c */
+    /* This is lifted straight from drivers/net/ethernet/8390/ne.c */
     struct {
 	u_char value, offset;
     } program_seq[] = {
diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c
index cb4f38a..d896816 100644
--- a/drivers/net/ethernet/adaptec/starfire.c
+++ b/drivers/net/ethernet/adaptec/starfire.c
@@ -686,10 +686,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
 	}
 
 	dev = alloc_etherdev(sizeof(*np));
-	if (!dev) {
-		printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);
+	if (!dev)
 		return -ENOMEM;
-	}
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	irq = pdev->irq;
@@ -1180,12 +1179,11 @@ static void init_ring(struct net_device *dev)
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+		struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz);
 		np->rx_info[i].skb = skb;
 		if (skb == NULL)
 			break;
 		np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-		skb->dev = dev;			/* Mark as being used by this device. */
 		/* Grrr, we cannot offset to correctly align the IP header. */
 		np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
 	}
@@ -1473,7 +1471,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
 		/* Check if the packet is long enough to accept without copying
 		   to a minimally-sized skbuff. */
 		if (pkt_len < rx_copybreak &&
-		    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+		    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 			skb_reserve(skb, 2);	/* 16 byte align the IP header */
 			pci_dma_sync_single_for_cpu(np->pci_dev,
 						    np->rx_info[entry].mapping,
@@ -1597,13 +1595,12 @@ static void refill_rx_ring(struct net_device *dev)
 	for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
 		entry = np->dirty_rx % RX_RING_SIZE;
 		if (np->rx_info[entry].skb == NULL) {
-			skb = dev_alloc_skb(np->rx_buf_sz);
+			skb = netdev_alloc_skb(dev, np->rx_buf_sz);
 			np->rx_info[entry].skb = skb;
 			if (skb == NULL)
 				break;	/* Better luck next round. */
 			np->rx_info[entry].mapping =
 				pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-			skb->dev = dev;	/* Mark as being used by this device. */
 			np->rx_ring[entry].rxaddr =
 				cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
 		}
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c
index d812a10..ab4daec 100644
--- a/drivers/net/ethernet/adi/bfin_mac.c
+++ b/drivers/net/ethernet/adi/bfin_mac.c
@@ -113,7 +113,7 @@ static void desc_list_free(void)
 	}
 }
 
-static int desc_list_init(void)
+static int desc_list_init(struct net_device *dev)
 {
 	int i;
 	struct sk_buff *new_skb;
@@ -187,7 +187,7 @@ static int desc_list_init(void)
 		struct dma_descriptor *b = &(r->desc_b);
 
 		/* allocate a new skb for next time receive */
-		new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
+		new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
 		if (!new_skb) {
 			pr_notice("init: low on mem - packet dropped\n");
 			goto init_error;
@@ -621,6 +621,7 @@ static int bfin_mac_set_mac_address(struct net_device *dev, void *p)
 	if (netif_running(dev))
 		return -EBUSY;
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	setup_mac_addr(dev->dev_addr);
 	return 0;
 }
@@ -1090,7 +1091,7 @@ static void bfin_mac_rx(struct net_device *dev)
 	/* allocate a new skb for next time receive */
 	skb = current_rx_ptr->skb;
 
-	new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
+	new_skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
 	if (!new_skb) {
 		netdev_notice(dev, "rx: low on mem - packet dropped\n");
 		dev->stats.rx_dropped++;
@@ -1397,7 +1398,7 @@ static int bfin_mac_open(struct net_device *dev)
 	}
 
 	/* initial rx and tx list */
-	ret = desc_list_init();
+	ret = desc_list_init(dev);
 	if (ret)
 		return ret;
 
@@ -1467,10 +1468,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 	int rc;
 
 	ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
-	if (!ndev) {
-		dev_err(&pdev->dev, "Cannot allocate net device!\n");
+	if (!ndev)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	platform_set_drvdata(pdev, ndev);
@@ -1496,12 +1495,14 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 	 * Grab the MAC from the board somehow
 	 * this is done in the arch/blackfin/mach-bfxxx/boards/eth_mac.c
 	 */
-	if (!is_valid_ether_addr(ndev->dev_addr))
-		bfin_get_ether_addr(ndev->dev_addr);
-
-	/* If still not valid, get a random one */
-	if (!is_valid_ether_addr(ndev->dev_addr))
-		random_ether_addr(ndev->dev_addr);
+	if (!is_valid_ether_addr(ndev->dev_addr)) {
+		if (bfin_get_ether_addr(ndev->dev_addr) ||
+		     !is_valid_ether_addr(ndev->dev_addr)) {
+			/* Still not valid, get a random one */
+			netdev_warn(ndev, "Setting Ethernet MAC to a random one\n");
+			eth_hw_addr_random(ndev);
+		}
+	}
 
 	setup_mac_addr(ndev->dev_addr);
 
diff --git a/drivers/net/ethernet/adi/bfin_mac.h b/drivers/net/ethernet/adi/bfin_mac.h
index f8559ac..960905c 100644
--- a/drivers/net/ethernet/adi/bfin_mac.h
+++ b/drivers/net/ethernet/adi/bfin_mac.h
@@ -101,6 +101,6 @@ struct bfin_mac_local {
 #endif
 };
 
-extern void bfin_get_ether_addr(char *addr);
+extern int bfin_get_ether_addr(char *addr);
 
 #endif
diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
index c885aa9..cfa1348 100644
--- a/drivers/net/ethernet/aeroflex/greth.c
+++ b/drivers/net/ethernet/aeroflex/greth.c
@@ -785,7 +785,6 @@ static int greth_rx(struct net_device *dev, int limit)
 
 			} else {
 				skb_reserve(skb, NET_IP_ALIGN);
-				skb->dev = dev;
 
 				dma_sync_single_for_cpu(greth->dev,
 							dma_addr,
@@ -1422,7 +1421,7 @@ static int __devinit greth_of_probe(struct platform_device *ofdev)
 	SET_NETDEV_DEV(dev, greth->dev);
 
 	if (netif_msg_probe(greth))
-		dev_dbg(greth->dev, "reseting controller.\n");
+		dev_dbg(greth->dev, "resetting controller.\n");
 
 	/* Reset the controller. */
 	GRETH_REGSAVE(regs->control, GRETH_RESET);
diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c
index f872748..6c3b1c0 100644
--- a/drivers/net/ethernet/alteon/acenic.c
+++ b/drivers/net/ethernet/alteon/acenic.c
@@ -463,11 +463,8 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
 	static int boards_found;
 
 	dev = alloc_etherdev(sizeof(struct ace_private));
-	if (dev == NULL) {
-		printk(KERN_ERR "acenic: Unable to allocate "
-		       "net_device structure!\n");
+	if (dev == NULL)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c
index 60b35fb..1b046f5 100644
--- a/drivers/net/ethernet/amd/7990.c
+++ b/drivers/net/ethernet/amd/7990.c
@@ -316,7 +316,7 @@ static int lance_rx (struct net_device *dev)
                         if (bits & LE_R1_EOP) dev->stats.rx_errors++;
                 } else {
 			int len = (rd->mblength & 0xfff) - 4;
-			struct sk_buff *skb = dev_alloc_skb (len+2);
+			struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
 
                         if (!skb) {
                                 printk ("%s: Memory squeeze, deferring packet.\n",
diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
index 238b537..8350f4b 100644
--- a/drivers/net/ethernet/amd/Kconfig
+++ b/drivers/net/ethernet/amd/Kconfig
@@ -113,7 +113,7 @@ config DEPCA
 	  If you have a network (Ethernet) card of this type, say Y and read
 	  the Ethernet-HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto> as well as
-	  <file:drivers/net/depca.c>.
+	  <file:drivers/net/ethernet/amd/depca.c>.
 
 	  To compile this driver as a module, choose M here. The module
 	  will be called depca.
diff --git a/drivers/net/ethernet/amd/a2065.c b/drivers/net/ethernet/amd/a2065.c
index 825e5d4..689dfca 100644
--- a/drivers/net/ethernet/amd/a2065.c
+++ b/drivers/net/ethernet/amd/a2065.c
@@ -290,7 +290,7 @@ static int lance_rx(struct net_device *dev)
 				dev->stats.rx_errors++;
 		} else {
 			int len = (rd->mblength & 0xfff) - 4;
-			struct sk_buff *skb = dev_alloc_skb(len + 2);
+			struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
 
 			if (!skb) {
 				netdev_warn(dev, "Memory squeeze, deferring packet\n");
diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c
index 7d5ded8..cc7b9e4 100644
--- a/drivers/net/ethernet/amd/am79c961a.c
+++ b/drivers/net/ethernet/amd/am79c961a.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/am79c961.c
+ *  linux/drivers/net/ethernet/amd/am79c961a.c
  *
  *  by Russell King <rmk@arm.linux.org.uk> 1995-2001.
  *
@@ -516,7 +516,7 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
 		}
 
 		len = am_readword(dev, hdraddr + 6);
-		skb = dev_alloc_skb(len + 2);
+		skb = netdev_alloc_skb(dev, len + 2);
 
 		if (skb) {
 			skb_reserve(skb, 2);
diff --git a/drivers/net/ethernet/amd/am79c961a.h b/drivers/net/ethernet/amd/am79c961a.h
index fd634d3..9f384b7 100644
--- a/drivers/net/ethernet/amd/am79c961a.h
+++ b/drivers/net/ethernet/amd/am79c961a.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/net/arm/am79c961a.h
+ * linux/drivers/net/ethernet/amd/am79c961a.h
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 33e0a8c..9f62504 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -336,7 +336,8 @@ static int amd8111e_init_ring(struct net_device *dev)
 	/* Allocating receive  skbs */
 	for (i = 0; i < NUM_RX_BUFFERS; i++) {
 
-		if (!(lp->rx_skbuff[i] = dev_alloc_skb(lp->rx_buff_len))) {
+		lp->rx_skbuff[i] = netdev_alloc_skb(dev, lp->rx_buff_len);
+		if (!lp->rx_skbuff[i]) {
 				/* Release previos allocated skbs */
 				for(--i; i >= 0 ;i--)
 					dev_kfree_skb(lp->rx_skbuff[i]);
@@ -768,7 +769,8 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
 			}
 			if(--rx_pkt_limit < 0)
 				goto rx_not_empty;
-			if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){
+			new_skb = netdev_alloc_skb(dev, lp->rx_buff_len);
+			if (!new_skb) {
 				/* if allocation fail,
 				   ignore that pkt and go to next one */
 				lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
@@ -1859,7 +1861,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
 
 	dev = alloc_etherdev(sizeof(struct amd8111e_priv));
 	if (!dev) {
-		printk(KERN_ERR "amd8111e: Etherdev alloc failed, exiting.\n");
 		err = -ENOMEM;
 		goto err_free_reg;
 	}
diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c
index eb18e1f..f4c228e 100644
--- a/drivers/net/ethernet/amd/ariadne.c
+++ b/drivers/net/ethernet/amd/ariadne.c
@@ -191,7 +191,7 @@ static int ariadne_rx(struct net_device *dev)
 			short pkt_len = swapw(priv->rx_ring[entry]->RMD3);
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len + 2);
+			skb = netdev_alloc_skb(dev, pkt_len + 2);
 			if (skb == NULL) {
 				netdev_warn(dev, "Memory squeeze, deferring packet\n");
 				for (i = 0; i < RX_RING_SIZE; i++)
diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
index 15bfa28..70ed79c 100644
--- a/drivers/net/ethernet/amd/atarilance.c
+++ b/drivers/net/ethernet/amd/atarilance.c
@@ -997,7 +997,7 @@ static int lance_rx( struct net_device *dev )
 				dev->stats.rx_errors++;
 			}
 			else {
-				skb = dev_alloc_skb( pkt_len+2 );
+				skb = netdev_alloc_skb(dev, pkt_len + 2);
 				if (skb == NULL) {
 					DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
 								  dev->name ));
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 8b95dd3..397596b 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -725,7 +725,7 @@ static int au1000_rx(struct net_device *dev)
 			/* good frame */
 			frmlen = (status & RX_FRAME_LEN_MASK);
 			frmlen -= 4; /* Remove FCS */
-			skb = dev_alloc_skb(frmlen + 2);
+			skb = netdev_alloc_skb(dev, frmlen + 2);
 			if (skb == NULL) {
 				netdev_err(dev, "Memory squeeze, dropping packet.\n");
 				dev->stats.rx_dropped++;
@@ -1077,7 +1077,6 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	dev = alloc_etherdev(sizeof(struct au1000_private));
 	if (!dev) {
-		dev_err(&pdev->dev, "alloc_etherdev failed\n");
 		err = -ENOMEM;
 		goto err_alloc;
 	}
@@ -1130,9 +1129,6 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 
 	au1000_setup_hw_rings(aup, aup->macdma);
 
-	/* set a random MAC now in case platform_data doesn't provide one */
-	random_ether_addr(dev->dev_addr);
-
 	writel(0, aup->enable);
 	aup->mac_enabled = 0;
 
@@ -1142,8 +1138,12 @@ static int __devinit au1000_probe(struct platform_device *pdev)
 					" PHY search on MAC0\n");
 		aup->phy1_search_mac0 = 1;
 	} else {
-		if (is_valid_ether_addr(pd->mac))
+		if (is_valid_ether_addr(pd->mac)) {
 			memcpy(dev->dev_addr, pd->mac, 6);
+		} else {
+			/* Set a random MAC since no valid provided by platform_data. */
+			eth_hw_addr_random(dev);
+		}
 
 		aup->phy_static_config = pd->phy_static_config;
 		aup->phy_search_highest_addr = pd->phy_search_highest_addr;
diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c
index 73f8d4f..7dc508e 100644
--- a/drivers/net/ethernet/amd/declance.c
+++ b/drivers/net/ethernet/amd/declance.c
@@ -605,7 +605,7 @@ static int lance_rx(struct net_device *dev)
 				dev->stats.rx_errors++;
 		} else {
 			len = (*rds_ptr(rd, mblength, lp->type) & 0xfff) - 4;
-			skb = dev_alloc_skb(len + 2);
+			skb = netdev_alloc_skb(dev, len + 2);
 
 			if (skb == 0) {
 				printk("%s: Memory squeeze, deferring packet.\n",
@@ -1052,8 +1052,6 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type)
 
 	dev = alloc_etherdev(sizeof(struct lance_private));
 	if (!dev) {
-		printk(KERN_ERR "%s: Unable to allocate etherdev, aborting.\n",
-			name);
 		ret = -ENOMEM;
 		goto err_out;
 	}
diff --git a/drivers/net/ethernet/amd/depca.c b/drivers/net/ethernet/amd/depca.c
index 681970c..86dd957 100644
--- a/drivers/net/ethernet/amd/depca.c
+++ b/drivers/net/ethernet/amd/depca.c
@@ -1042,7 +1042,7 @@ static int depca_rx(struct net_device *dev)
 				short len, pkt_len = readw(&lp->rx_ring[entry].msg_length) - 4;
 				struct sk_buff *skb;
 
-				skb = dev_alloc_skb(pkt_len + 2);
+				skb = netdev_alloc_skb(dev, pkt_len + 2);
 				if (skb != NULL) {
 					unsigned char *buf;
 					skb_reserve(skb, 2);	/* 16 byte align the IP header */
diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c
index 6e6aa72..013b651 100644
--- a/drivers/net/ethernet/amd/ni65.c
+++ b/drivers/net/ethernet/amd/ni65.c
@@ -621,10 +621,8 @@ static void *ni65_alloc_mem(struct net_device *dev,char *what,int size,int type)
 	}
 	else {
 		ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA);
-		if(!ret) {
-			printk(KERN_WARNING "%s: unable to allocate %s memory.\n",dev->name,what);
+		if(!ret)
 			return NULL;
-		}
 	}
 	if( (u32) virt_to_phys(ptr+size) > 0x1000000) {
 		printk(KERN_WARNING "%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what);
@@ -1091,7 +1089,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
 			if (skb)
 				skb_reserve(skb,16);
 #else
-			struct sk_buff *skb = dev_alloc_skb(len+2);
+			struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
 #endif
 			if(skb)
 			{
diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
index 6be0dd6..ebdb9e2 100644
--- a/drivers/net/ethernet/amd/nmclan_cs.c
+++ b/drivers/net/ethernet/amd/nmclan_cs.c
@@ -1104,7 +1104,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
       pr_debug("    receiving packet size 0x%X rx_status"
 	    " 0x%X.\n", pkt_len, rx_status);
 
-      skb = dev_alloc_skb(pkt_len+2);
+      skb = netdev_alloc_skb(dev, pkt_len + 2);
 
       if (skb != NULL) {
 	skb_reserve(skb, 2);
diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c
index 20e6dab..86b6d8e 100644
--- a/drivers/net/ethernet/amd/pcnet32.c
+++ b/drivers/net/ethernet/amd/pcnet32.c
@@ -588,11 +588,11 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
 	/* now allocate any new buffers needed */
 	for (; new < size; new++) {
 		struct sk_buff *rx_skbuff;
-		new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB);
+		new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB);
 		rx_skbuff = new_skb_list[new];
 		if (!rx_skbuff) {
 			/* keep the original lists and buffers */
-			netif_err(lp, drv, dev, "%s dev_alloc_skb failed\n",
+			netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n",
 				  __func__);
 			goto free_all_new;
 		}
@@ -909,7 +909,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
 	/* Initialize Transmit buffers. */
 	size = data_len + 15;
 	for (x = 0; x < numbuffs; x++) {
-		skb = dev_alloc_skb(size);
+		skb = netdev_alloc_skb(dev, size);
 		if (!skb) {
 			netif_printk(lp, hw, KERN_DEBUG, dev,
 				     "Cannot allocate skb at line: %d!\n",
@@ -1152,7 +1152,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
 	if (pkt_len > rx_copybreak) {
 		struct sk_buff *newskb;
 
-		newskb = dev_alloc_skb(PKT_BUF_SKB);
+		newskb = netdev_alloc_skb(dev, PKT_BUF_SKB);
 		if (newskb) {
 			skb_reserve(newskb, NET_IP_ALIGN);
 			skb = lp->rx_skbuff[entry];
@@ -1172,7 +1172,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
 		} else
 			skb = NULL;
 	} else
-		skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN);
+		skb = netdev_alloc_skb(dev, pkt_len + NET_IP_ALIGN);
 
 	if (skb == NULL) {
 		netif_err(lp, drv, dev, "Memory squeeze, dropping packet\n");
@@ -1649,8 +1649,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
 
 	dev = alloc_etherdev(sizeof(*lp));
 	if (!dev) {
-		if (pcnet32_debug & NETIF_MSG_PROBE)
-			pr_err("Memory allocation failed\n");
 		ret = -ENOMEM;
 		goto err_release_region;
 	}
@@ -2273,11 +2271,11 @@ static int pcnet32_init_ring(struct net_device *dev)
 	for (i = 0; i < lp->rx_ring_size; i++) {
 		struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
 		if (rx_skbuff == NULL) {
-			lp->rx_skbuff[i] = dev_alloc_skb(PKT_BUF_SKB);
+			lp->rx_skbuff[i] = netdev_alloc_skb(dev, PKT_BUF_SKB);
 			rx_skbuff = lp->rx_skbuff[i];
 			if (!rx_skbuff) {
 				/* there is not much we can do at this point */
-				netif_err(lp, drv, dev, "%s dev_alloc_skb failed\n",
+				netif_err(lp, drv, dev, "%s netdev_alloc_skb failed\n",
 					  __func__);
 				return -1;
 			}
diff --git a/drivers/net/ethernet/amd/sun3lance.c b/drivers/net/ethernet/amd/sun3lance.c
index 080b71f..74b3891 100644
--- a/drivers/net/ethernet/amd/sun3lance.c
+++ b/drivers/net/ethernet/amd/sun3lance.c
@@ -810,7 +810,7 @@ static int lance_rx( struct net_device *dev )
 				dev->stats.rx_errors++;
 			}
 			else {
-				skb = dev_alloc_skb( pkt_len+2 );
+				skb = netdev_alloc_skb(dev, pkt_len + 2);
 				if (skb == NULL) {
 					DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
 						      dev->name ));
diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c
index 7ea16d3..e3fe350 100644
--- a/drivers/net/ethernet/amd/sunlance.c
+++ b/drivers/net/ethernet/amd/sunlance.c
@@ -534,7 +534,7 @@ static void lance_rx_dvma(struct net_device *dev)
 			if (bits & LE_R1_EOP) dev->stats.rx_errors++;
 		} else {
 			len = (rd->mblength & 0xfff) - 4;
-			skb = dev_alloc_skb(len + 2);
+			skb = netdev_alloc_skb(dev, len + 2);
 
 			if (skb == NULL) {
 				printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
@@ -706,7 +706,7 @@ static void lance_rx_pio(struct net_device *dev)
 			if (bits & LE_R1_EOP) dev->stats.rx_errors++;
 		} else {
 			len = (sbus_readw(&rd->mblength) & 0xfff) - 4;
-			skb = dev_alloc_skb(len + 2);
+			skb = netdev_alloc_skb(dev, len + 2);
 
 			if (skb == NULL) {
 				printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n",
diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
index d070b22..855bdaf 100644
--- a/drivers/net/ethernet/apple/bmac.c
+++ b/drivers/net/ethernet/apple/bmac.c
@@ -607,8 +607,9 @@ bmac_init_tx_ring(struct bmac_data *bp)
 }
 
 static int
-bmac_init_rx_ring(struct bmac_data *bp)
+bmac_init_rx_ring(struct net_device *dev)
 {
+	struct bmac_data *bp = netdev_priv(dev);
 	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	int i;
 	struct sk_buff *skb;
@@ -618,7 +619,7 @@ bmac_init_rx_ring(struct bmac_data *bp)
 	       (N_RX_RING + 1) * sizeof(struct dbdma_cmd));
 	for (i = 0; i < N_RX_RING; i++) {
 		if ((skb = bp->rx_bufs[i]) == NULL) {
-			bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
+			bp->rx_bufs[i] = skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
 			if (skb != NULL)
 				skb_reserve(skb, 2);
 		}
@@ -722,7 +723,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id)
 			++dev->stats.rx_dropped;
 		}
 		if ((skb = bp->rx_bufs[i]) == NULL) {
-			bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
+			bp->rx_bufs[i] = skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
 			if (skb != NULL)
 				skb_reserve(bp->rx_bufs[i], 2);
 		}
@@ -1208,7 +1209,7 @@ static void bmac_reset_and_enable(struct net_device *dev)
 	spin_lock_irqsave(&bp->lock, flags);
 	bmac_enable_and_reset_chip(dev);
 	bmac_init_tx_ring(bp);
-	bmac_init_rx_ring(bp);
+	bmac_init_rx_ring(dev);
 	bmac_init_chip(dev);
 	bmac_start_chip(dev);
 	bmwrite(dev, INTDISABLE, EnableNormal);
@@ -1218,7 +1219,7 @@ static void bmac_reset_and_enable(struct net_device *dev)
 	 * It seems that the bmac can't receive until it's transmitted
 	 * a packet.  So we give it a dummy packet to transmit.
 	 */
-	skb = dev_alloc_skb(ETHERMINPACKET);
+	skb = netdev_alloc_skb(dev, ETHERMINPACKET);
 	if (skb != NULL) {
 		data = skb_put(skb, ETHERMINPACKET);
 		memset(data, 0, ETHERMINPACKET);
@@ -1269,10 +1270,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
 	memcpy(addr, prop_addr, sizeof(addr));
 
 	dev = alloc_etherdev(PRIV_BYTES);
-	if (!dev) {
-		printk(KERN_ERR "BMAC: alloc_etherdev failed, out of memory\n");
+	if (!dev)
 		return -ENOMEM;
-	}
 
 	bp = netdev_priv(dev);
 	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
@@ -1660,10 +1659,8 @@ static int __init bmac_init(void)
 {
 	if (bmac_emergency_rxbuf == NULL) {
 		bmac_emergency_rxbuf = kmalloc(RX_BUFLEN, GFP_KERNEL);
-		if (bmac_emergency_rxbuf == NULL) {
-			printk(KERN_ERR "BMAC: can't allocate emergency RX buffer\n");
+		if (bmac_emergency_rxbuf == NULL)
 			return -ENOMEM;
-		}
 	}
 
 	return macio_register_driver(&bmac_driver);
diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
index bec87bd..e1df4b7 100644
--- a/drivers/net/ethernet/apple/mace.c
+++ b/drivers/net/ethernet/apple/mace.c
@@ -136,10 +136,8 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
 	 */
 	if (dummy_buf == NULL) {
 		dummy_buf = kmalloc(RX_BUFLEN+2, GFP_KERNEL);
-		if (dummy_buf == NULL) {
-			printk(KERN_ERR "MACE: couldn't allocate dummy buffer\n");
+		if (dummy_buf == NULL)
 			return -ENOMEM;
-		}
 	}
 
 	if (macio_request_resources(mdev, "mace")) {
@@ -149,7 +147,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
 
 	dev = alloc_etherdev(PRIV_BYTES);
 	if (!dev) {
-		printk(KERN_ERR "MACE: can't allocate ethernet device !\n");
 		rc = -ENOMEM;
 		goto err_release;
 	}
@@ -447,7 +444,7 @@ static int mace_open(struct net_device *dev)
     memset((char *)mp->rx_cmds, 0, N_RX_RING * sizeof(struct dbdma_cmd));
     cp = mp->rx_cmds;
     for (i = 0; i < N_RX_RING - 1; ++i) {
-	skb = dev_alloc_skb(RX_BUFLEN + 2);
+	skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
 	if (!skb) {
 	    data = dummy_buf;
 	} else {
@@ -959,7 +956,7 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
 	cp = mp->rx_cmds + i;
 	skb = mp->rx_bufs[i];
 	if (!skb) {
-	    skb = dev_alloc_skb(RX_BUFLEN + 2);
+	    skb = netdev_alloc_skb(dev, RX_BUFLEN + 2);
 	    if (skb) {
 		skb_reserve(skb, 2);
 		mp->rx_bufs[i] = skb;
diff --git a/drivers/net/ethernet/apple/macmace.c b/drivers/net/ethernet/apple/macmace.c
index 7cf81bb..ab7ff86 100644
--- a/drivers/net/ethernet/apple/macmace.c
+++ b/drivers/net/ethernet/apple/macmace.c
@@ -661,7 +661,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
 	} else {
 		unsigned int frame_length = mf->rcvcnt + ((frame_status & 0x0F) << 8 );
 
-		skb = dev_alloc_skb(frame_length + 2);
+		skb = netdev_alloc_skb(dev, frame_length + 2);
 		if (!skb) {
 			dev->stats.rx_dropped++;
 			return;
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
index 23f2ab0..bd1667c 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_hw.c
@@ -224,7 +224,7 @@ int atl1c_read_mac_addr(struct atl1c_hw *hw)
 		random_ether_addr(hw->perm_mac_addr);
 
 	memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
-	return 0;
+	return err;
 }
 
 /*
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index b859124..0f21a9b 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -468,6 +468,7 @@ static int atl1c_set_mac_addr(struct net_device *netdev, void *p)
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+	netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	atl1c_hw_set_mac_addr(&adapter->hw);
 
@@ -1765,7 +1766,7 @@ static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid
 	while (next_info->flags & ATL1C_BUFFER_FREE) {
 		rfd_desc = ATL1C_RFD_DESC(rfd_ring, rfd_next_to_use);
 
-		skb = dev_alloc_skb(adapter->rx_buffer_len);
+		skb = netdev_alloc_skb(adapter->netdev, adapter->rx_buffer_len);
 		if (unlikely(!skb)) {
 			if (netif_msg_rx_err(adapter))
 				dev_warn(&pdev->dev, "alloc rx buffer failed\n");
@@ -2244,10 +2245,6 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
 			dev_info(&adapter->pdev->dev, "tx locked\n");
 		return NETDEV_TX_LOCKED;
 	}
-	if (skb->mark == 0x01)
-		type = atl1c_trans_high;
-	else
-		type = atl1c_trans_normal;
 
 	if (atl1c_tpd_avail(adapter, type) < tpd_req) {
 		/* no enough descriptor, just stop queue */
@@ -2689,7 +2686,6 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
 	netdev = alloc_etherdev(sizeof(struct atl1c_adapter));
 	if (netdev == NULL) {
 		err = -ENOMEM;
-		dev_err(&pdev->dev, "etherdev alloc failed\n");
 		goto err_alloc_etherdev;
 	}
 
@@ -2746,10 +2742,9 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
 		err = -EIO;
 		goto err_reset;
 	}
-	if (atl1c_read_mac_addr(&adapter->hw) != 0) {
-		err = -EIO;
-		dev_err(&pdev->dev, "get mac address failed\n");
-		goto err_eeprom;
+	if (atl1c_read_mac_addr(&adapter->hw)) {
+		/* got a random MAC address, set NET_ADDR_RANDOM to netdev */
+		netdev->addr_assign_type |= NET_ADDR_RANDOM;
 	}
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
 	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
@@ -2774,7 +2769,6 @@ static int __devinit atl1c_probe(struct pci_dev *pdev,
 err_reset:
 err_register:
 err_sw_init:
-err_eeprom:
 	iounmap(adapter->hw.hw_addr);
 err_init_netdev:
 err_ioremap:
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
index c915c08..93ff2b2 100644
--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -2300,7 +2300,6 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
 	netdev = alloc_etherdev(sizeof(struct atl1e_adapter));
 	if (netdev == NULL) {
 		err = -ENOMEM;
-		dev_err(&pdev->dev, "etherdev alloc failed\n");
 		goto err_alloc_etherdev;
 	}
 
diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 9bd2049..40ac414 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -534,14 +534,17 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
  */
 static s32 atl1_read_mac_addr(struct atl1_hw *hw)
 {
+	s32 ret = 0;
 	u16 i;
 
-	if (atl1_get_permanent_address(hw))
+	if (atl1_get_permanent_address(hw)) {
 		random_ether_addr(hw->perm_mac_addr);
+		ret = 1;
+	}
 
 	for (i = 0; i < ETH_ALEN; i++)
 		hw->mac_addr[i] = hw->perm_mac_addr[i];
-	return 0;
+	return ret;
 }
 
 /*
@@ -3007,7 +3010,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	}
 
 	/* copy the MAC address out of the EEPROM */
-	atl1_read_mac_addr(&adapter->hw);
+	if (atl1_read_mac_addr(&adapter->hw)) {
+		/* mark random mac */
+		netdev->addr_assign_type |= NET_ADDR_RANDOM;
+	}
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
 
 	if (!is_valid_ether_addr(netdev->dev_addr)) {
diff --git a/drivers/net/ethernet/atheros/atlx/atlx.c b/drivers/net/ethernet/atheros/atlx/atlx.c
index 8ff7411..3cd8837 100644
--- a/drivers/net/ethernet/atheros/atlx/atlx.c
+++ b/drivers/net/ethernet/atheros/atlx/atlx.c
@@ -84,6 +84,7 @@ static int atlx_set_mac(struct net_device *netdev, void *p)
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+	netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	atlx_set_mac_addr(&adapter->hw);
 	return 0;
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 3fb66d0..46b8b7d8 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2138,7 +2138,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
 
 	dev = alloc_etherdev(sizeof(*bp));
 	if (!dev) {
-		dev_err(sdev->dev, "Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto out;
 	}
@@ -2339,7 +2338,7 @@ static inline int __init b44_pci_init(void)
 	return err;
 }
 
-static inline void __exit b44_pci_exit(void)
+static inline void b44_pci_exit(void)
 {
 #ifdef CONFIG_B44_PCI
 	ssb_pcihost_unregister(&b44_pci_driver);
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 021fb81..7105989 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -2625,10 +2625,8 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp)
 	u32 val;
 
 	good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL);
-	if (good_mbuf == NULL) {
-		pr_err("Failed to allocate memory in %s\n", __func__);
+	if (good_mbuf == NULL)
 		return -ENOMEM;
-	}
 
 	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
 		BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
@@ -6248,7 +6246,16 @@ static int
 bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
 {
 	int cpus = num_online_cpus();
-	int msix_vecs = min(cpus + 1, RX_MAX_RINGS);
+	int msix_vecs;
+
+	if (!bp->num_req_rx_rings)
+		msix_vecs = max(cpus + 1, bp->num_req_tx_rings);
+	else if (!bp->num_req_tx_rings)
+		msix_vecs = max(cpus, bp->num_req_rx_rings);
+	else
+		msix_vecs = max(bp->num_req_rx_rings, bp->num_req_tx_rings);
+
+	msix_vecs = min(msix_vecs, RX_MAX_RINGS);
 
 	bp->irq_tbl[0].handler = bnx2_interrupt;
 	strcpy(bp->irq_tbl[0].name, bp->dev->name);
@@ -6272,10 +6279,18 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
 		}
 	}
 
-	bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
+	if (!bp->num_req_tx_rings)
+		bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
+	else
+		bp->num_tx_rings = min(bp->irq_nvecs, bp->num_req_tx_rings);
+
+	if (!bp->num_req_rx_rings)
+		bp->num_rx_rings = bp->irq_nvecs;
+	else
+		bp->num_rx_rings = min(bp->irq_nvecs, bp->num_req_rx_rings);
+
 	netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings);
 
-	bp->num_rx_rings = bp->irq_nvecs;
 	return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings);
 }
 
@@ -6550,6 +6565,9 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END;
 
+	/* Sync BD data before updating TX mailbox */
+	wmb();
+
 	netdev_tx_sent_queue(txq, skb->len);
 
 	prod = NEXT_TX_BD(prod);
@@ -7164,7 +7182,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 }
 
 static int
-bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
+bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx, bool reset_irq)
 {
 	if (netif_running(bp->dev)) {
 		/* Reset will erase chipset stats; save them */
@@ -7172,7 +7190,12 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
 
 		bnx2_netif_stop(bp, true);
 		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
-		__bnx2_free_irq(bp);
+		if (reset_irq) {
+			bnx2_free_irq(bp);
+			bnx2_del_napi(bp);
+		} else {
+			__bnx2_free_irq(bp);
+		}
 		bnx2_free_skbs(bp);
 		bnx2_free_mem(bp);
 	}
@@ -7181,9 +7204,16 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
 	bp->tx_ring_size = tx;
 
 	if (netif_running(bp->dev)) {
-		int rc;
+		int rc = 0;
+
+		if (reset_irq) {
+			rc = bnx2_setup_int_mode(bp, disable_msi);
+			bnx2_init_napi(bp);
+		}
+
+		if (!rc)
+			rc = bnx2_alloc_mem(bp);
 
-		rc = bnx2_alloc_mem(bp);
 		if (!rc)
 			rc = bnx2_request_irq(bp);
 
@@ -7219,7 +7249,8 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 
 		return -EINVAL;
 	}
-	rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending);
+	rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending,
+				   false);
 	return rc;
 }
 
@@ -7607,6 +7638,54 @@ bnx2_set_features(struct net_device *dev, netdev_features_t features)
 	return 0;
 }
 
+static void bnx2_get_channels(struct net_device *dev,
+			      struct ethtool_channels *channels)
+{
+	struct bnx2 *bp = netdev_priv(dev);
+	u32 max_rx_rings = 1;
+	u32 max_tx_rings = 1;
+
+	if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) {
+		max_rx_rings = RX_MAX_RINGS;
+		max_tx_rings = TX_MAX_RINGS;
+	}
+
+	channels->max_rx = max_rx_rings;
+	channels->max_tx = max_tx_rings;
+	channels->max_other = 0;
+	channels->max_combined = 0;
+	channels->rx_count = bp->num_rx_rings;
+	channels->tx_count = bp->num_tx_rings;
+	channels->other_count = 0;
+	channels->combined_count = 0;
+}
+
+static int bnx2_set_channels(struct net_device *dev,
+			      struct ethtool_channels *channels)
+{
+	struct bnx2 *bp = netdev_priv(dev);
+	u32 max_rx_rings = 1;
+	u32 max_tx_rings = 1;
+	int rc = 0;
+
+	if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) {
+		max_rx_rings = RX_MAX_RINGS;
+		max_tx_rings = TX_MAX_RINGS;
+	}
+	if (channels->rx_count > max_rx_rings ||
+	    channels->tx_count > max_tx_rings)
+		return -EINVAL;
+
+	bp->num_req_rx_rings = channels->rx_count;
+	bp->num_req_tx_rings = channels->tx_count;
+
+	if (netif_running(dev))
+		rc = bnx2_change_ring_size(bp, bp->rx_ring_size,
+					   bp->tx_ring_size, true);
+
+	return rc;
+}
+
 static const struct ethtool_ops bnx2_ethtool_ops = {
 	.get_settings		= bnx2_get_settings,
 	.set_settings		= bnx2_set_settings,
@@ -7631,6 +7710,8 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
 	.set_phys_id		= bnx2_set_phys_id,
 	.get_ethtool_stats	= bnx2_get_ethtool_stats,
 	.get_sset_count		= bnx2_get_sset_count,
+	.get_channels		= bnx2_get_channels,
+	.set_channels		= bnx2_set_channels,
 };
 
 /* Called with rtnl_lock */
@@ -7712,7 +7793,8 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu)
 		return -EINVAL;
 
 	dev->mtu = new_mtu;
-	return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size);
+	return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size,
+				     false);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h
index 1db2d51..dc06bda 100644
--- a/drivers/net/ethernet/broadcom/bnx2.h
+++ b/drivers/net/ethernet/broadcom/bnx2.h
@@ -6933,6 +6933,9 @@ struct bnx2 {
 	u8			num_tx_rings;
 	u8			num_rx_rings;
 
+	int			num_req_tx_rings;
+	int			num_req_rx_rings;
+
 	u32 			leds_save;
 	u32			idle_chk_status_idx;
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 8c73d34..c0cf313 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1,6 +1,6 @@
 /* bnx2x.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -23,8 +23,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.70.35-0"
-#define DRV_MODULE_RELDATE      "2011/11/10"
+#define DRV_MODULE_VERSION      "1.72.10-0"
+#define DRV_MODULE_RELDATE      "2012/02/20"
 #define BNX2X_BC_VER            0x040200
 
 #if defined(CONFIG_DCB)
@@ -341,6 +341,7 @@ union db_prod {
 #define SGE_PAGE_SIZE		PAGE_SIZE
 #define SGE_PAGE_SHIFT		PAGE_SHIFT
 #define SGE_PAGE_ALIGN(addr)	PAGE_ALIGN((typeof(PAGE_SIZE))(addr))
+#define SGE_PAGES		(SGE_PAGE_SIZE * PAGES_PER_SGE)
 
 /* SGE ring related macros */
 #define NUM_RX_SGE_PAGES	2
@@ -445,6 +446,8 @@ struct bnx2x_agg_info {
 	u16			vlan_tag;
 	u16			len_on_bd;
 	u32			rxhash;
+	u16			gro_size;
+	u16			full_page;
 };
 
 #define Q_STATS_OFFSET32(stat_name) \
@@ -473,6 +476,11 @@ struct bnx2x_fp_txdata {
 	int			txq_index;
 };
 
+enum bnx2x_tpa_mode_t {
+	TPA_MODE_LRO,
+	TPA_MODE_GRO
+};
+
 struct bnx2x_fastpath {
 	struct bnx2x		*bp; /* parent */
 
@@ -489,6 +497,8 @@ struct bnx2x_fastpath {
 
 	dma_addr_t		status_blk_mapping;
 
+	enum bnx2x_tpa_mode_t	mode;
+
 	u8			max_cos; /* actual number of active tx coses */
 	struct bnx2x_fp_txdata	txdata[BNX2X_MULTI_TX_COS];
 
@@ -540,6 +550,7 @@ struct bnx2x_fastpath {
 	struct ustorm_per_queue_stats old_uclient;
 	struct xstorm_per_queue_stats old_xclient;
 	struct bnx2x_eth_q_stats eth_q_stats;
+	struct bnx2x_eth_q_stats_old eth_q_stats_old;
 
 	/* The size is calculated using the following:
 	     sizeof name field from netdev structure +
@@ -1046,7 +1057,6 @@ struct bnx2x_slowpath {
 	struct nig_stats		nig_stats;
 	struct host_port_stats		port_stats;
 	struct host_func_stats		func_stats;
-	struct host_func_stats		func_stats_base;
 
 	u32				wb_comp;
 	u32				wb_data[4];
@@ -1088,7 +1098,8 @@ enum bnx2x_recovery_state {
 	BNX2X_RECOVERY_DONE,
 	BNX2X_RECOVERY_INIT,
 	BNX2X_RECOVERY_WAIT,
-	BNX2X_RECOVERY_FAILED
+	BNX2X_RECOVERY_FAILED,
+	BNX2X_RECOVERY_NIC_LOADING
 };
 
 /*
@@ -1198,6 +1209,9 @@ struct bnx2x {
 #define ETH_MIN_PACKET_SIZE		60
 #define ETH_MAX_PACKET_SIZE		1500
 #define ETH_MAX_JUMBO_PACKET_SIZE	9600
+/* TCP with Timestamp Option (32) + IPv6 (40) */
+#define ETH_MAX_TPA_HEADER_SIZE		72
+#define ETH_MIN_TPA_HEADER_SIZE		40
 
 	/* Max supported alignment is 256 (8 shift) */
 #define BNX2X_RX_ALIGN_SHIFT		min(8, L1_CACHE_SHIFT)
@@ -1268,6 +1282,7 @@ struct bnx2x {
 #define NO_MCP_FLAG			(1 << 9)
 
 #define BP_NOMCP(bp)			(bp->flags & NO_MCP_FLAG)
+#define GRO_ENABLE_FLAG			(1 << 10)
 #define MF_FUNC_DIS			(1 << 11)
 #define OWN_CNIC_IRQ			(1 << 12)
 #define NO_ISCSI_OOO_FLAG		(1 << 13)
@@ -1316,6 +1331,8 @@ struct bnx2x {
 
 	u8			wol;
 
+	bool			gro_check;
+
 	int			rx_ring_size;
 
 	u16			tx_quick_cons_trip_int;
@@ -1461,6 +1478,10 @@ struct bnx2x {
 
 	u16			stats_counter;
 	struct bnx2x_eth_stats	eth_stats;
+	struct bnx2x_eth_stats_old	eth_stats_old;
+	struct bnx2x_net_stats_old	net_stats_old;
+	struct bnx2x_fw_port_stats_old	fw_stats_old;
+	bool			stats_init;
 
 	struct z_stream_s	*strm;
 	void			*gunzip_buf;
@@ -2073,8 +2094,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 #define BNX2X_VPD_LEN			128
 #define VENDOR_ID_LEN			4
 
-int bnx2x_close(struct net_device *dev);
-
 /* Congestion management fairness mode */
 #define CMNG_FNS_NONE		0
 #define CMNG_FNS_MINMAX		1
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 7aee469..f82dfff 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1,6 +1,6 @@
 /* bnx2x_cmn.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -32,46 +32,6 @@
 
 
 /**
- * bnx2x_bz_fp - zero content of the fastpath structure.
- *
- * @bp:		driver handle
- * @index:	fastpath index to be zeroed
- *
- * Makes sure the contents of the bp->fp[index].napi is kept
- * intact.
- */
-static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
-{
-	struct bnx2x_fastpath *fp = &bp->fp[index];
-	struct napi_struct orig_napi = fp->napi;
-	/* bzero bnx2x_fastpath contents */
-	memset(fp, 0, sizeof(*fp));
-
-	/* Restore the NAPI object as it has been already initialized */
-	fp->napi = orig_napi;
-
-	fp->bp = bp;
-	fp->index = index;
-	if (IS_ETH_FP(fp))
-		fp->max_cos = bp->max_cos;
-	else
-		/* Special queues support only one CoS */
-		fp->max_cos = 1;
-
-	/*
-	 * set the tpa flag for each queue. The tpa flag determines the queue
-	 * minimal size so it must be set prior to queue memory allocation
-	 */
-	fp->disable_tpa = ((bp->flags & TPA_ENABLE_FLAG) == 0);
-
-#ifdef BCM_CNIC
-	/* We don't want TPA on an FCoE L2 ring */
-	if (IS_FCOE_FP(fp))
-		fp->disable_tpa = 1;
-#endif
-}
-
-/**
  * bnx2x_move_fp - move content of the fastpath structure.
  *
  * @bp:		driver handle
@@ -249,13 +209,11 @@ static inline void bnx2x_update_last_max_sge(struct bnx2x_fastpath *fp,
 		fp->last_max_sge = idx;
 }
 
-static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
-				  struct eth_fast_path_rx_cqe *fp_cqe)
+static inline void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
+					 u16 sge_len,
+					 struct eth_end_agg_rx_cqe *cqe)
 {
 	struct bnx2x *bp = fp->bp;
-	u16 sge_len = SGE_PAGE_ALIGN(le16_to_cpu(fp_cqe->pkt_len) -
-				     le16_to_cpu(fp_cqe->len_on_bd)) >>
-		      SGE_PAGE_SHIFT;
 	u16 last_max, last_elem, first_elem;
 	u16 delta = 0;
 	u16 i;
@@ -266,15 +224,15 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp,
 	/* First mark all used pages */
 	for (i = 0; i < sge_len; i++)
 		BIT_VEC64_CLEAR_BIT(fp->sge_mask,
-			RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i])));
+			RX_SGE(le16_to_cpu(cqe->sgl_or_raw_data.sgl[i])));
 
 	DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n",
-	   sge_len - 1, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1]));
+	   sge_len - 1, le16_to_cpu(cqe->sgl_or_raw_data.sgl[sge_len - 1]));
 
 	/* Here we assume that the last SGE index is the biggest */
 	prefetch((void *)(fp->sge_mask));
 	bnx2x_update_last_max_sge(fp,
-		le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1]));
+		le16_to_cpu(cqe->sgl_or_raw_data.sgl[sge_len - 1]));
 
 	last_max = RX_SGE(fp->last_max_sge);
 	last_elem = last_max >> BIT_VEC64_ELEM_SHIFT;
@@ -368,6 +326,22 @@ static void bnx2x_tpa_start(struct bnx2x_fastpath *fp, u16 queue,
 	tpa_info->len_on_bd = le16_to_cpu(cqe->len_on_bd);
 	tpa_info->placement_offset = cqe->placement_offset;
 	tpa_info->rxhash = bnx2x_get_rxhash(bp, cqe);
+	if (fp->mode == TPA_MODE_GRO) {
+		u16 gro_size = le16_to_cpu(cqe->pkt_len_or_gro_seg_len);
+		tpa_info->full_page =
+			SGE_PAGE_SIZE * PAGES_PER_SGE / gro_size * gro_size;
+		/*
+		 * FW 7.2.16 BUG workaround:
+		 * if SGE size is (exactly) multiple gro_size
+		 * fw will place one less frag on SGE.
+		 * the calculation is done only for potentially
+		 * dangerous MTUs.
+		 */
+		if (unlikely(bp->gro_check))
+			if (!(SGE_PAGE_SIZE * PAGES_PER_SGE % gro_size))
+				tpa_info->full_page -= gro_size;
+		tpa_info->gro_size = gro_size;
+	}
 
 #ifdef BNX2X_STOP_ON_ERROR
 	fp->tpa_queue_used |= (1 << queue);
@@ -424,25 +398,40 @@ static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
 }
 
 static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
-			       u16 queue, struct sk_buff *skb,
+			       struct bnx2x_agg_info *tpa_info,
+			       u16 pages,
+			       struct sk_buff *skb,
 			       struct eth_end_agg_rx_cqe *cqe,
 			       u16 cqe_idx)
 {
 	struct sw_rx_page *rx_pg, old_rx_pg;
-	u32 i, frag_len, frag_size, pages;
-	int err;
-	int j;
-	struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue];
+	u32 i, frag_len, frag_size;
+	int err, j, frag_id = 0;
 	u16 len_on_bd = tpa_info->len_on_bd;
+	u16 full_page = 0, gro_size = 0;
 
 	frag_size = le16_to_cpu(cqe->pkt_len) - len_on_bd;
-	pages = SGE_PAGE_ALIGN(frag_size) >> SGE_PAGE_SHIFT;
+
+	if (fp->mode == TPA_MODE_GRO) {
+		gro_size = tpa_info->gro_size;
+		full_page = tpa_info->full_page;
+	}
 
 	/* This is needed in order to enable forwarding support */
-	if (frag_size)
+	if (frag_size) {
 		skb_shinfo(skb)->gso_size = bnx2x_set_lro_mss(bp,
 					tpa_info->parsing_flags, len_on_bd);
 
+		/* set for GRO */
+		if (fp->mode == TPA_MODE_GRO)
+			skb_shinfo(skb)->gso_type =
+			    (GET_FLAG(tpa_info->parsing_flags,
+				      PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) ==
+						PRS_FLAG_OVERETH_IPV6) ?
+				SKB_GSO_TCPV6 : SKB_GSO_TCPV4;
+	}
+
+
 #ifdef BNX2X_STOP_ON_ERROR
 	if (pages > min_t(u32, 8, MAX_SKB_FRAGS)*SGE_PAGE_SIZE*PAGES_PER_SGE) {
 		BNX2X_ERR("SGL length is too long: %d. CQE index is %d\n",
@@ -459,7 +448,12 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 
 		/* FW gives the indices of the SGE as if the ring is an array
 		   (meaning that "next" element will consume 2 indices) */
-		frag_len = min(frag_size, (u32)(SGE_PAGE_SIZE*PAGES_PER_SGE));
+		if (fp->mode == TPA_MODE_GRO)
+			frag_len = min_t(u32, frag_size, (u32)full_page);
+		else /* LRO */
+			frag_len = min_t(u32, frag_size,
+					 (u32)(SGE_PAGE_SIZE * PAGES_PER_SGE));
+
 		rx_pg = &fp->rx_page_ring[sge_idx];
 		old_rx_pg = *rx_pg;
 
@@ -475,9 +469,21 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 		dma_unmap_page(&bp->pdev->dev,
 			       dma_unmap_addr(&old_rx_pg, mapping),
 			       SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE);
-
 		/* Add one frag and update the appropriate fields in the skb */
-		skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len);
+		if (fp->mode == TPA_MODE_LRO)
+			skb_fill_page_desc(skb, j, old_rx_pg.page, 0, frag_len);
+		else { /* GRO */
+			int rem;
+			int offset = 0;
+			for (rem = frag_len; rem > 0; rem -= gro_size) {
+				int len = rem > gro_size ? gro_size : rem;
+				skb_fill_page_desc(skb, frag_id++,
+						   old_rx_pg.page, offset, len);
+				if (offset)
+					get_page(old_rx_pg.page);
+				offset += len;
+			}
+		}
 
 		skb->data_len += frag_len;
 		skb->truesize += SGE_PAGE_SIZE * PAGES_PER_SGE;
@@ -489,18 +495,17 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 	return 0;
 }
 
-static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
-			   u16 queue, struct eth_end_agg_rx_cqe *cqe,
-			   u16 cqe_idx)
+static inline void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+				  struct bnx2x_agg_info *tpa_info,
+				  u16 pages,
+				  struct eth_end_agg_rx_cqe *cqe,
+				  u16 cqe_idx)
 {
-	struct bnx2x_agg_info *tpa_info = &fp->tpa_info[queue];
 	struct sw_rx_bd *rx_buf = &tpa_info->first_buf;
-	u32 pad = tpa_info->placement_offset;
+	u8 pad = tpa_info->placement_offset;
 	u16 len = tpa_info->len_on_bd;
 	struct sk_buff *skb = NULL;
-	u8 *data = rx_buf->data;
-	/* alloc new skb */
-	u8 *new_data;
+	u8 *new_data, *data = rx_buf->data;
 	u8 old_tpa_state = tpa_info->tpa_state;
 
 	tpa_info->tpa_state = BNX2X_TPA_STOP;
@@ -540,7 +545,8 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 		skb->protocol = eth_type_trans(skb, bp->dev);
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-		if (!bnx2x_fill_frag_skb(bp, fp, queue, skb, cqe, cqe_idx)) {
+		if (!bnx2x_fill_frag_skb(bp, fp, tpa_info, pages,
+					 skb, cqe, cqe_idx)) {
 			if (tpa_info->parsing_flags & PARSING_FLAGS_VLAN)
 				__vlan_hwaccel_put_tag(skb, tpa_info->vlan_tag);
 			napi_gro_receive(&fp->napi, skb);
@@ -605,7 +611,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 		struct eth_fast_path_rx_cqe *cqe_fp;
 		u8 cqe_fp_flags;
 		enum eth_rx_cqe_type cqe_fp_type;
-		u16 len, pad;
+		u16 len, pad, queue;
 		u8 *data;
 
 #ifdef BNX2X_STOP_ON_ERROR
@@ -626,17 +632,21 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 		   "  queue %x  vlan %x  len %u\n", CQE_TYPE(cqe_fp_flags),
 		   cqe_fp_flags, cqe_fp->status_flags,
 		   le32_to_cpu(cqe_fp->rss_hash_result),
-		   le16_to_cpu(cqe_fp->vlan_tag), le16_to_cpu(cqe_fp->pkt_len));
+		   le16_to_cpu(cqe_fp->vlan_tag),
+		   le16_to_cpu(cqe_fp->pkt_len_or_gro_seg_len));
 
 		/* is this a slowpath msg? */
 		if (unlikely(CQE_TYPE_SLOW(cqe_fp_type))) {
 			bnx2x_sp_event(fp, cqe);
 			goto next_cqe;
 		}
+
 		rx_buf = &fp->rx_buf_ring[bd_cons];
 		data = rx_buf->data;
 
 		if (!CQE_TYPE_FAST(cqe_fp_type)) {
+			struct bnx2x_agg_info *tpa_info;
+			u16 frag_size, pages;
 #ifdef BNX2X_STOP_ON_ERROR
 			/* sanity check */
 			if (fp->disable_tpa &&
@@ -656,28 +666,38 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 				bnx2x_tpa_start(fp, queue,
 						bd_cons, bd_prod,
 						cqe_fp);
+
 				goto next_rx;
-			} else {
-				u16 queue =
-					cqe->end_agg_cqe.queue_index;
-				DP(NETIF_MSG_RX_STATUS,
-				   "calling tpa_stop on queue %d\n",
-				   queue);
 
-				bnx2x_tpa_stop(bp, fp, queue,
-					       &cqe->end_agg_cqe,
-					       comp_ring_cons);
+			}
+			queue = cqe->end_agg_cqe.queue_index;
+			tpa_info = &fp->tpa_info[queue];
+			DP(NETIF_MSG_RX_STATUS,
+			   "calling tpa_stop on queue %d\n",
+			   queue);
+
+			frag_size = le16_to_cpu(cqe->end_agg_cqe.pkt_len) -
+				    tpa_info->len_on_bd;
+
+			if (fp->mode == TPA_MODE_GRO)
+				pages = (frag_size + tpa_info->full_page - 1) /
+					 tpa_info->full_page;
+			else
+				pages = SGE_PAGE_ALIGN(frag_size) >>
+					SGE_PAGE_SHIFT;
+
+			bnx2x_tpa_stop(bp, fp, tpa_info, pages,
+				       &cqe->end_agg_cqe, comp_ring_cons);
 #ifdef BNX2X_STOP_ON_ERROR
-				if (bp->panic)
-					return 0;
+			if (bp->panic)
+				return 0;
 #endif
 
-				bnx2x_update_sge_prod(fp, cqe_fp);
-				goto next_cqe;
-			}
+			bnx2x_update_sge_prod(fp, pages, &cqe->end_agg_cqe);
+			goto next_cqe;
 		}
 		/* non TPA */
-		len = le16_to_cpu(cqe_fp->pkt_len);
+		len = le16_to_cpu(cqe_fp->pkt_len_or_gro_seg_len);
 		pad = cqe_fp->placement_offset;
 		dma_sync_single_for_cpu(&bp->pdev->dev,
 					dma_unmap_addr(rx_buf, mapping),
@@ -1766,12 +1786,27 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 
 	bnx2x_napi_enable(bp);
 
+	/* set pf load just before approaching the MCP */
+	bnx2x_set_pf_load(bp);
+
 	/* Send LOAD_REQUEST command to MCP
 	 * Returns the type of LOAD command:
 	 * if it is the first port to be initialized
 	 * common blocks should be initialized, otherwise - not
 	 */
 	if (!BP_NOMCP(bp)) {
+		/* init fw_seq */
+		bp->fw_seq =
+			(SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
+			 DRV_MSG_SEQ_NUMBER_MASK);
+		BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
+
+		/* Get current FW pulse sequence */
+		bp->fw_drv_pulse_wr_seq =
+			(SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb) &
+			 DRV_PULSE_SEQ_MASK);
+		BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
+
 		load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0);
 		if (!load_code) {
 			BNX2X_ERR("MCP response failure, aborting\n");
@@ -1782,6 +1817,29 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 			rc = -EBUSY; /* other port in diagnostic mode */
 			LOAD_ERROR_EXIT(bp, load_error1);
 		}
+		if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP &&
+		    load_code != FW_MSG_CODE_DRV_LOAD_COMMON) {
+			/* build FW version dword */
+			u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) +
+					(BCM_5710_FW_MINOR_VERSION << 8) +
+					(BCM_5710_FW_REVISION_VERSION << 16) +
+					(BCM_5710_FW_ENGINEERING_VERSION << 24);
+
+			/* read loaded FW from chip */
+			u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM);
+
+			DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x",
+			   loaded_fw, my_fw);
+
+			/* abort nic load if version mismatch */
+			if (my_fw != loaded_fw) {
+				BNX2X_ERR("bnx2x with FW %x already loaded, "
+					  "which mismatches my %x FW. aborting",
+					  loaded_fw, my_fw);
+				rc = -EBUSY;
+				LOAD_ERROR_EXIT(bp, load_error2);
+			}
+		}
 
 	} else {
 		int path = BP_PATH(bp);
@@ -1948,7 +2006,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	if (bp->state == BNX2X_STATE_OPEN)
 		bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD);
 #endif
-	bnx2x_inc_load_cnt(bp);
 
 	/* Wait for all pending SP commands to complete */
 	if (!bnx2x_wait_sp_comp(bp, ~0x0UL)) {
@@ -1988,6 +2045,8 @@ load_error2:
 	bp->port.pmf = 0;
 load_error1:
 	bnx2x_napi_disable(bp);
+	/* clear pf_load status, as it was already set */
+	bnx2x_clear_pf_load(bp);
 load_error0:
 	bnx2x_free_mem(bp);
 
@@ -2045,6 +2104,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 	bnx2x_drv_pulse(bp);
 
 	bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+	bnx2x_save_statistics(bp);
 
 	/* Cleanup the chip if needed */
 	if (unload_mode != UNLOAD_RECOVERY)
@@ -2108,7 +2168,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 	/* The last driver must disable a "close the gate" if there is no
 	 * parity attention or "process kill" pending.
 	 */
-	if (!bnx2x_dec_load_cnt(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp)))
+	if (!bnx2x_clear_pf_load(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp)))
 		bnx2x_disable_close_the_gate(bp);
 
 	return 0;
@@ -3007,6 +3067,7 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p)
 			return rc;
 	}
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
 	if (netif_running(dev))
@@ -3122,9 +3183,16 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
 	} else
 #endif
 	if (!bp->rx_ring_size) {
+		u32 cfg = SHMEM_RD(bp,
+			     dev_info.port_hw_config[BP_PORT(bp)].default_cfg);
 
 		rx_ring_size = MAX_RX_AVAIL/BNX2X_NUM_RX_QUEUES(bp);
 
+		/* Dercease ring size for 1G functions */
+		if ((cfg & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
+		    PORT_HW_CFG_NET_SERDES_IF_SGMII)
+			rx_ring_size /= 10;
+
 		/* allocate at least number of buffers required by FW */
 		rx_ring_size = max_t(int, bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
 				     MIN_RX_SIZE_TPA, rx_ring_size);
@@ -3414,7 +3482,7 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
 	struct bnx2x *bp = netdev_priv(dev);
 
 	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-		pr_err("Handling parity error recovery. Try again later\n");
+		netdev_err(dev, "Handling parity error recovery. Try again later\n");
 		return -EAGAIN;
 	}
 
@@ -3428,17 +3496,21 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
 	 */
 	dev->mtu = new_mtu;
 
+	bp->gro_check = bnx2x_need_gro_check(new_mtu);
+
 	return bnx2x_reload_if_running(dev);
 }
 
 netdev_features_t bnx2x_fix_features(struct net_device *dev,
-	netdev_features_t features)
+				     netdev_features_t features)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
 	/* TPA requires Rx CSUM offloading */
-	if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa)
+	if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa) {
 		features &= ~NETIF_F_LRO;
+		features &= ~NETIF_F_GRO;
+	}
 
 	return features;
 }
@@ -3454,6 +3526,11 @@ int bnx2x_set_features(struct net_device *dev, netdev_features_t features)
 	else
 		flags &= ~TPA_ENABLE_FLAG;
 
+	if (features & NETIF_F_GRO)
+		flags |= GRO_ENABLE_FLAG;
+	else
+		flags &= ~GRO_ENABLE_FLAG;
+
 	if (features & NETIF_F_LOOPBACK) {
 		if (bp->link_params.loopback_mode != LOOPBACK_BMAC) {
 			bp->link_params.loopback_mode = LOOPBACK_BMAC;
@@ -3541,7 +3618,7 @@ int bnx2x_resume(struct pci_dev *pdev)
 	bp = netdev_priv(dev);
 
 	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-		pr_err("Handling parity error recovery. Try again later\n");
+		netdev_err(dev, "Handling parity error recovery. Try again later\n");
 		return -EAGAIN;
 	}
 
@@ -3557,8 +3634,6 @@ int bnx2x_resume(struct pci_dev *pdev)
 	bnx2x_set_power_state(bp, PCI_D0);
 	netif_device_attach(dev);
 
-	/* Since the chip was reset, clear the FW sequence number */
-	bp->fw_seq = 0;
 	rc = bnx2x_nic_load(bp, LOAD_OPEN);
 
 	rtnl_unlock();
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index bf27c54..33aa7de 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -1,6 +1,6 @@
 /* bnx2x_cmn.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -379,8 +379,8 @@ void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id,
 			 unsigned long ramrod_flags);
 
 /* Parity errors related */
-void bnx2x_inc_load_cnt(struct bnx2x *bp);
-u32 bnx2x_dec_load_cnt(struct bnx2x *bp);
+void bnx2x_set_pf_load(struct bnx2x *bp);
+bool bnx2x_clear_pf_load(struct bnx2x *bp);
 bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print);
 bool bnx2x_reset_is_done(struct bnx2x *bp, int engine);
 void bnx2x_set_reset_in_progress(struct bnx2x *bp);
@@ -534,8 +534,9 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
  */
 int bnx2x_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type);
 #endif
+
 netdev_features_t bnx2x_fix_features(struct net_device *dev,
-	netdev_features_t features);
+				     netdev_features_t features);
 int bnx2x_set_features(struct net_device *dev, netdev_features_t features);
 
 /**
@@ -614,8 +615,7 @@ static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func,
 	u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL;
 	u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4;
 	u32 sb_bit =  1 << (idu_sb_id%32);
-	u32 func_encode = func |
-			((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT);
+	u32 func_encode = func | (is_Pf ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT;
 	u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id;
 
 	/* Not supported in BC mode */
@@ -984,10 +984,11 @@ static inline int bnx2x_func_start(struct bnx2x *bp)
 	/* Function parameters */
 	start_params->mf_mode = bp->mf_mode;
 	start_params->sd_vlan_tag = bp->mf_ov;
-	if (CHIP_IS_E1x(bp))
-		start_params->network_cos_mode = OVERRIDE_COS;
-	else
+
+	if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp))
 		start_params->network_cos_mode = STATIC_COS;
+	else /* CHIP_IS_E1X */
+		start_params->network_cos_mode = FW_WRR;
 
 	return bnx2x_func_state_change(bp, &func_params);
 }
@@ -1491,6 +1492,105 @@ static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
 	return max_cfg;
 }
 
+/* checks if HW supports GRO for given MTU */
+static inline bool bnx2x_mtu_allows_gro(int mtu)
+{
+	/* gro frags per page */
+	int fpp = SGE_PAGE_SIZE / (mtu - ETH_MAX_TPA_HEADER_SIZE);
+
+	/*
+	 * 1. number of frags should not grow above MAX_SKB_FRAGS
+	 * 2. frag must fit the page
+	 */
+	return mtu <= SGE_PAGE_SIZE && (U_ETH_SGL_SIZE * fpp) <= MAX_SKB_FRAGS;
+}
+
+static inline bool bnx2x_need_gro_check(int mtu)
+{
+	return (SGE_PAGES / (mtu - ETH_MAX_TPA_HEADER_SIZE - 1)) !=
+		(SGE_PAGES / (mtu - ETH_MIN_TPA_HEADER_SIZE + 1));
+}
+
+/**
+ * bnx2x_bz_fp - zero content of the fastpath structure.
+ *
+ * @bp:		driver handle
+ * @index:	fastpath index to be zeroed
+ *
+ * Makes sure the contents of the bp->fp[index].napi is kept
+ * intact.
+ */
+static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
+{
+	struct bnx2x_fastpath *fp = &bp->fp[index];
+	struct napi_struct orig_napi = fp->napi;
+	/* bzero bnx2x_fastpath contents */
+	if (bp->stats_init)
+		memset(fp, 0, sizeof(*fp));
+	else {
+		/* Keep Queue statistics */
+		struct bnx2x_eth_q_stats *tmp_eth_q_stats;
+		struct bnx2x_eth_q_stats_old *tmp_eth_q_stats_old;
+
+		tmp_eth_q_stats = kzalloc(sizeof(struct bnx2x_eth_q_stats),
+					  GFP_KERNEL);
+		if (tmp_eth_q_stats)
+			memcpy(tmp_eth_q_stats, &fp->eth_q_stats,
+			       sizeof(struct bnx2x_eth_q_stats));
+
+		tmp_eth_q_stats_old =
+			kzalloc(sizeof(struct bnx2x_eth_q_stats_old),
+				GFP_KERNEL);
+		if (tmp_eth_q_stats_old)
+			memcpy(tmp_eth_q_stats_old, &fp->eth_q_stats_old,
+			       sizeof(struct bnx2x_eth_q_stats_old));
+
+		memset(fp, 0, sizeof(*fp));
+
+		if (tmp_eth_q_stats) {
+			memcpy(&fp->eth_q_stats, tmp_eth_q_stats,
+				   sizeof(struct bnx2x_eth_q_stats));
+			kfree(tmp_eth_q_stats);
+		}
+
+		if (tmp_eth_q_stats_old) {
+			memcpy(&fp->eth_q_stats_old, tmp_eth_q_stats_old,
+			       sizeof(struct bnx2x_eth_q_stats_old));
+			kfree(tmp_eth_q_stats_old);
+		}
+
+	}
+
+	/* Restore the NAPI object as it has been already initialized */
+	fp->napi = orig_napi;
+
+	fp->bp = bp;
+	fp->index = index;
+	if (IS_ETH_FP(fp))
+		fp->max_cos = bp->max_cos;
+	else
+		/* Special queues support only one CoS */
+		fp->max_cos = 1;
+
+	/*
+	 * set the tpa flag for each queue. The tpa flag determines the queue
+	 * minimal size so it must be set prior to queue memory allocation
+	 */
+	fp->disable_tpa = !(bp->flags & TPA_ENABLE_FLAG ||
+				  (bp->flags & GRO_ENABLE_FLAG &&
+				   bnx2x_mtu_allows_gro(bp->dev->mtu)));
+	if (bp->flags & TPA_ENABLE_FLAG)
+		fp->mode = TPA_MODE_LRO;
+	else if (bp->flags & GRO_ENABLE_FLAG)
+		fp->mode = TPA_MODE_GRO;
+
+#ifdef BCM_CNIC
+	/* We don't want TPA on an FCoE L2 ring */
+	if (IS_FCOE_FP(fp))
+		fp->disable_tpa = 1;
+#endif
+}
+
 /**
  * bnx2x_get_iscsi_info - update iSCSI params according to licensing info.
  *
@@ -1539,7 +1639,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)
 {
 	if (SHMEM2_HAS(bp, drv_flags)) {
 		u32 drv_flags;
-		bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS);
+		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS);
 		drv_flags = SHMEM2_RD(bp, drv_flags);
 
 		if (set)
@@ -1549,7 +1649,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set)
 
 		SHMEM2_WR(bp, drv_flags, drv_flags);
 		DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags);
-		bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS);
+		bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS);
 	}
 }
 
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
index 5051cf3..9a9bd3a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
@@ -1,6 +1,6 @@
 /* bnx2x_dcb.c: Broadcom Everest network driver.
  *
- * Copyright 2009-2011 Broadcom Corporation
+ * Copyright 2009-2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
index 2ab9254..06c7a04 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
@@ -1,6 +1,6 @@
 /* bnx2x_dcb.h: Broadcom Everest network driver.
  *
- * Copyright 2009-2011 Broadcom Corporation
+ * Copyright 2009-2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h
index b983825..3e4cff9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h
@@ -1,6 +1,6 @@
 /* bnx2x_dump.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2011 Broadcom Corporation
+ * Copyright (c) 2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 31a8b38..9c24d53 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1,6 +1,6 @@
 /* bnx2x_ethtool.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -175,7 +175,11 @@ static const struct {
 	{ STATS_OFFSET32(total_tpa_aggregated_frames_hi),
 			8, STATS_FLAGS_FUNC, "tpa_aggregated_frames"},
 	{ STATS_OFFSET32(total_tpa_bytes_hi),
-			8, STATS_FLAGS_FUNC, "tpa_bytes"}
+			8, STATS_FLAGS_FUNC, "tpa_bytes"},
+	{ STATS_OFFSET32(recoverable_error),
+			4, STATS_FLAGS_FUNC, "recoverable_errors" },
+	{ STATS_OFFSET32(unrecoverable_error),
+			4, STATS_FLAGS_FUNC, "unrecoverable_errors" },
 };
 
 #define BNX2X_NUM_STATS		ARRAY_SIZE(bnx2x_stats_arr)
@@ -242,6 +246,34 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	else
 		cmd->autoneg = AUTONEG_DISABLE;
 
+	/* Publish LP advertised speeds and FC */
+	if (bp->link_vars.link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
+		u32 status = bp->link_vars.link_status;
+
+		cmd->lp_advertising |= ADVERTISED_Autoneg;
+		if (status & LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE)
+			cmd->lp_advertising |= ADVERTISED_Pause;
+		if (status & LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
+			cmd->lp_advertising |= ADVERTISED_Asym_Pause;
+
+		if (status & LINK_STATUS_LINK_PARTNER_10THD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_10baseT_Half;
+		if (status & LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_10baseT_Full;
+		if (status & LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_100baseT_Half;
+		if (status & LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_100baseT_Full;
+		if (status & LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_1000baseT_Half;
+		if (status & LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_1000baseT_Full;
+		if (status & LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_2500baseX_Full;
+		if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE)
+			cmd->lp_advertising |= ADVERTISED_10000baseT_Full;
+	}
+
 	cmd->maxtxpkt = 0;
 	cmd->maxrxpkt = 0;
 
@@ -774,14 +806,8 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
 	strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
 
 	phy_fw_ver[0] = '\0';
-	if (bp->port.pmf) {
-		bnx2x_acquire_phy_lock(bp);
-		bnx2x_get_ext_phy_fw_version(&bp->link_params,
-					     (bp->state != BNX2X_STATE_CLOSED),
-					     phy_fw_ver, PHY_FW_VER_LEN);
-		bnx2x_release_phy_lock(bp);
-	}
-
+	bnx2x_get_ext_phy_fw_version(&bp->link_params,
+				     phy_fw_ver, PHY_FW_VER_LEN);
 	strlcpy(info->fw_version, bp->fw_ver, sizeof(info->fw_version));
 	snprintf(info->fw_version + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver),
 		 "bc %d.%d.%d%s%s",
@@ -882,11 +908,27 @@ static int bnx2x_get_eeprom_len(struct net_device *dev)
 	return bp->common.flash_size;
 }
 
+/* Per pf misc lock must be aquired before the per port mcp lock. Otherwise, had
+ * we done things the other way around, if two pfs from the same port would
+ * attempt to access nvram at the same time, we could run into a scenario such
+ * as:
+ * pf A takes the port lock.
+ * pf B succeeds in taking the same lock since they are from the same port.
+ * pf A takes the per pf misc lock. Performs eeprom access.
+ * pf A finishes. Unlocks the per pf misc lock.
+ * Pf B takes the lock and proceeds to perform it's own access.
+ * pf A unlocks the per port lock, while pf B is still working (!).
+ * mcp takes the per port lock and corrupts pf B's access (and/or has it's own
+ * acess corrupted by pf B).*
+ */
 static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
 	int count, i;
-	u32 val = 0;
+	u32 val;
+
+	/* acquire HW lock: protect against other PFs in PF Direct Assignment */
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
 
 	/* adjust timeout for emulation/FPGA */
 	count = BNX2X_NVRAM_TIMEOUT_COUNT;
@@ -917,7 +959,7 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
 	int count, i;
-	u32 val = 0;
+	u32 val;
 
 	/* adjust timeout for emulation/FPGA */
 	count = BNX2X_NVRAM_TIMEOUT_COUNT;
@@ -941,6 +983,8 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp)
 		return -EBUSY;
 	}
 
+	/* release HW lock: protect against other PFs in PF Direct Assignment */
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM);
 	return 0;
 }
 
@@ -1370,7 +1414,8 @@ static int bnx2x_set_ringparam(struct net_device *dev,
 	struct bnx2x *bp = netdev_priv(dev);
 
 	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-		pr_err("Handling parity error recovery. Try again later\n");
+		netdev_err(dev, "Handling parity error recovery. "
+				"Try again later\n");
 		return -EAGAIN;
 	}
 
@@ -1392,12 +1437,19 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+	int cfg_reg;
+
 	epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] ==
 			   BNX2X_FLOW_CTRL_AUTO);
 
-	epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
+	if (!epause->autoneg)
+		cfg_reg = bp->link_vars.flow_ctrl;
+	else
+		cfg_reg = bp->link_params.req_fc_auto_adv;
+
+	epause->rx_pause = ((cfg_reg & BNX2X_FLOW_CTRL_RX) ==
 			    BNX2X_FLOW_CTRL_RX);
-	epause->tx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX) ==
+	epause->tx_pause = ((cfg_reg & BNX2X_FLOW_CTRL_TX) ==
 			    BNX2X_FLOW_CTRL_TX);
 
 	DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
@@ -1879,7 +1931,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode)
 	if (!CQE_TYPE_FAST(cqe_fp_type) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
 		goto test_loopback_rx_exit;
 
-	len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
+	len = le16_to_cpu(cqe->fast_path_cqe.pkt_len_or_gro_seg_len);
 	if (len != pkt_size)
 		goto test_loopback_rx_exit;
 
@@ -1958,14 +2010,22 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
 		{ 0x708,  0x70 }, /* manuf_key_info */
 		{     0,     0 }
 	};
-	__be32 buf[0x350 / 4];
-	u8 *data = (u8 *)buf;
+	__be32 *buf;
+	u8 *data;
 	int i, rc;
 	u32 magic, crc;
 
 	if (BP_NOMCP(bp))
 		return 0;
 
+	buf = kmalloc(0x350, GFP_KERNEL);
+	if (!buf) {
+		DP(NETIF_MSG_PROBE, "kmalloc failed\n");
+		rc = -ENOMEM;
+		goto test_nvram_exit;
+	}
+	data = (u8 *)buf;
+
 	rc = bnx2x_nvram_read(bp, 0, data, 4);
 	if (rc) {
 		DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
@@ -1999,6 +2059,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
 	}
 
 test_nvram_exit:
+	kfree(buf);
 	return rc;
 }
 
@@ -2024,7 +2085,8 @@ static void bnx2x_self_test(struct net_device *dev,
 	struct bnx2x *bp = netdev_priv(dev);
 	u8 is_serdes;
 	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-		pr_err("Handling parity error recovery. Try again later\n");
+		netdev_err(bp->dev, "Handling parity error recovery. "
+				    "Try again later\n");
 		etest->flags |= ETH_TEST_FL_FAILED;
 		return;
 	}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
index 998652a..e5c5982 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
 /* bnx2x_fw_defs.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h
index f4a07fb..4bed52b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h
@@ -1,6 +1,6 @@
 /* bnx2x_fw_file_hdr.h: FW binary file header structure.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 3e30c86..a1413ad 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -1,6 +1,6 @@
 /* bnx2x_hsi.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -34,9 +34,10 @@ struct license_key {
 };
 
 
-#define PORT_0              0
-#define PORT_1              1
-#define PORT_MAX            2
+#define PORT_0			0
+#define PORT_1			1
+#define PORT_MAX		2
+#define NVM_PATH_MAX		2
 
 /****************************************************************************
  * Shared HW configuration                                                  *
@@ -618,12 +619,6 @@ struct port_hw_cfg {		    /* port 0: 0x12c  port 1: 0x2bc */
 	#define PORT_HW_CFG_ENABLE_CMS_DISABLED                      0x00000000
 	#define PORT_HW_CFG_ENABLE_CMS_ENABLED                       0x00200000
 
-	/*  Enable RJ45 magjack pair swapping on 10GBase-T PHY, 84833 only */
-	#define PORT_HW_CFG_RJ45_PR_SWP_MASK                0x00400000
-	#define PORT_HW_CFG_RJ45_PR_SWP_SHIFT			     22
-	#define PORT_HW_CFG_RJ45_PR_SWP_DISABLED		     0x00000000
-	#define PORT_HW_CFG_RJ45_PR_SWP_ENABLED			     0x00400000
-
 	/*  Determine the Serdes electrical interface   */
 	#define PORT_HW_CFG_NET_SERDES_IF_MASK              0x0F000000
 	#define PORT_HW_CFG_NET_SERDES_IF_SHIFT                      24
@@ -898,11 +893,6 @@ struct port_feat_cfg {		    /* port 0: 0x454  port 1: 0x4c8 */
 		#define PORT_FEAT_CFG_DCBX_DISABLED                  0x00000000
 		#define PORT_FEAT_CFG_DCBX_ENABLED                   0x00000100
 
-	#define PORT_FEAT_CFG_AUTOGREEN_MASK                0x00000200
-	#define PORT_FEAT_CFG_AUTOGREEN_SHIFT                        9
-	#define PORT_FEAT_CFG_AUTOGREEN_DISABLED                     0x00000000
-	#define PORT_FEAT_CFG_AUTOGREEN_ENABLED                      0x00000200
-
 	#define PORT_FEATURE_EN_SIZE_MASK                   0x0f000000
 	#define PORT_FEATURE_EN_SIZE_SHIFT                           24
 	#define PORT_FEATURE_WOL_ENABLED                             0x01000000
@@ -1139,9 +1129,6 @@ struct shm_dev_info {				/* size */
 
 #define FW_ACK_NUM_OF_POLL  (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
 
-/* LED Blink rate that will achieve ~15.9Hz */
-#define LED_BLINK_RATE_VAL      480
-
 /****************************************************************************
  * Driver <-> FW Mailbox                                                    *
  ****************************************************************************/
@@ -1407,7 +1394,7 @@ struct port_mf_cfg {
 	#define PORT_MF_CFG_E1HOV_TAG_SHIFT             0
 	#define PORT_MF_CFG_E1HOV_TAG_DEFAULT         PORT_MF_CFG_E1HOV_TAG_MASK
 
-	u32 reserved[3];
+	u32 reserved[1];
 
 };
 
@@ -1493,7 +1480,8 @@ struct func_ext_cfg {
 struct mf_cfg {
 
 	struct shared_mf_cfg    shared_mf_config;       /* 0x4 */
-	struct port_mf_cfg  port_mf_config[PORT_MAX];   /* 0x10 * 2 = 0x20 */
+							/* 0x8*2*2=0x20 */
+	struct port_mf_cfg  port_mf_config[NVM_PATH_MAX][PORT_MAX];
 	/* for all chips, there are 8 mf functions */
 	struct func_mf_cfg  func_mf_config[E1H_FUNC_MAX]; /* 0x18 * 8 = 0xc0 */
 	/*
@@ -2002,6 +1990,7 @@ struct shmem2_region {
 #define DRV_INFO_CONTROL_VER_SHIFT         0
 #define DRV_INFO_CONTROL_OP_CODE_MASK      0x0000ff00
 #define DRV_INFO_CONTROL_OP_CODE_SHIFT     8
+	u32 ibft_host_addr; /* initialized by option ROM */
 };
 
 
@@ -2700,8 +2689,8 @@ union drv_info_to_mcp {
 	struct iscsi_stats_info	iscsi_stat;
 };
 #define BCM_5710_FW_MAJOR_VERSION			7
-#define BCM_5710_FW_MINOR_VERSION			0
-#define BCM_5710_FW_REVISION_VERSION		29
+#define BCM_5710_FW_MINOR_VERSION			2
+#define BCM_5710_FW_REVISION_VERSION		16
 #define BCM_5710_FW_ENGINEERING_VERSION		0
 #define BCM_5710_FW_COMPILE_FLAGS			1
 
@@ -3308,8 +3297,10 @@ struct client_init_rx_data {
 #define CLIENT_INIT_RX_DATA_TPA_EN_IPV4_SHIFT 0
 #define CLIENT_INIT_RX_DATA_TPA_EN_IPV6 (0x1<<1)
 #define CLIENT_INIT_RX_DATA_TPA_EN_IPV6_SHIFT 1
-#define CLIENT_INIT_RX_DATA_RESERVED5 (0x3F<<2)
-#define CLIENT_INIT_RX_DATA_RESERVED5_SHIFT 2
+#define CLIENT_INIT_RX_DATA_TPA_MODE (0x1<<2)
+#define CLIENT_INIT_RX_DATA_TPA_MODE_SHIFT 2
+#define CLIENT_INIT_RX_DATA_RESERVED5 (0x1F<<3)
+#define CLIENT_INIT_RX_DATA_RESERVED5_SHIFT 3
 	u8 vmqueue_mode_en_flg;
 	u8 extra_data_over_sgl_en_flg;
 	u8 cache_line_alignment_log_size;
@@ -3324,7 +3315,7 @@ struct client_init_rx_data {
 	u8 outer_vlan_removal_enable_flg;
 	u8 status_block_id;
 	u8 rx_sb_index_number;
-	u8 reserved0;
+	u8 dont_verify_rings_pause_thr_flg;
 	u8 max_tpa_queues;
 	u8 silent_vlan_removal_flg;
 	__le16 max_bytes_on_bd;
@@ -3657,7 +3648,7 @@ struct eth_fast_path_rx_cqe {
 	u8 placement_offset;
 	__le32 rss_hash_result;
 	__le16 vlan_tag;
-	__le16 pkt_len;
+	__le16 pkt_len_or_gro_seg_len;
 	__le16 len_on_bd;
 	struct parsing_flags pars_flags;
 	union eth_sgl_or_raw_data sgl_or_raw_data;
@@ -4215,6 +4206,15 @@ enum set_mac_action_type {
 
 
 /*
+ * Ethernet TPA Modes
+ */
+enum tpa_mode {
+	TPA_LRO,
+	TPA_GRO,
+	MAX_TPA_MODE};
+
+
+/*
  * tpa update ramrod data
  */
 struct tpa_update_ramrod_data {
@@ -4224,7 +4224,8 @@ struct tpa_update_ramrod_data {
 	u8 max_tpa_queues;
 	u8 max_sges_for_packet;
 	u8 complete_on_both_clients;
-	__le16 reserved1;
+	u8 dont_verify_rings_pause_thr_flg;
+	u8 tpa_mode;
 	__le16 sge_buff_size;
 	__le16 max_agg_size;
 	__le32 sge_page_base_lo;
@@ -4447,13 +4448,13 @@ enum common_spqe_cmd_id {
 	RAMROD_CMD_ID_COMMON_UNUSED,
 	RAMROD_CMD_ID_COMMON_FUNCTION_START,
 	RAMROD_CMD_ID_COMMON_FUNCTION_STOP,
+	RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE,
 	RAMROD_CMD_ID_COMMON_CFC_DEL,
 	RAMROD_CMD_ID_COMMON_CFC_DEL_WB,
 	RAMROD_CMD_ID_COMMON_STAT_QUERY,
 	RAMROD_CMD_ID_COMMON_STOP_TRAFFIC,
 	RAMROD_CMD_ID_COMMON_START_TRAFFIC,
 	RAMROD_CMD_ID_COMMON_RESERVED1,
-	RAMROD_CMD_ID_COMMON_RESERVED2,
 	MAX_COMMON_SPQE_CMD_ID
 };
 
@@ -4733,8 +4734,8 @@ enum event_ring_opcode {
 	EVENT_RING_OPCODE_MALICIOUS_VF,
 	EVENT_RING_OPCODE_FORWARD_SETUP,
 	EVENT_RING_OPCODE_RSS_UPDATE_RULES,
+	EVENT_RING_OPCODE_FUNCTION_UPDATE,
 	EVENT_RING_OPCODE_RESERVED1,
-	EVENT_RING_OPCODE_RESERVED2,
 	EVENT_RING_OPCODE_SET_MAC,
 	EVENT_RING_OPCODE_CLASSIFICATION_RULES,
 	EVENT_RING_OPCODE_FILTERS_RULES,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
index 4d748e7..29f5c3c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h
@@ -1,7 +1,7 @@
 /* bnx2x_init.h: Broadcom Everest network driver.
  *               Structures and macroes needed during the initialization.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h
index 7ec1724..fe66d90 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h
@@ -2,7 +2,7 @@
  *               Static functions needed during the initialization.
  *               This file is "included" in bnx2x_main.c.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -69,12 +69,12 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len,
 {
 	if (bp->dmae_ready)
 		bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
-	else if (wb)
-		/*
-		 * Wide bus registers with no dmae need to be written
-		 * using indirect write.
-		 */
+
+	/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
+	else if (wb && CHIP_IS_E1(bp))
 		bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
+
+	/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
 	else
 		bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
 }
@@ -99,8 +99,14 @@ static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
 {
 	if (bp->dmae_ready)
 		bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
-	else
+
+	/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
+	else if (CHIP_IS_E1(bp))
 		bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
+
+	/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
+	else
+		bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
 }
 
 static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr,
@@ -177,8 +183,14 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr,
 {
 	if (bp->dmae_ready)
 		VIRT_WR_DMAE_LEN(bp, data, addr, len, 0);
-	else
+
+	/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
+	else if (CHIP_IS_E1(bp))
 		bnx2x_init_ind_wr(bp, addr, data, len);
+
+	/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
+	else
+		bnx2x_init_str_wr(bp, addr, data, len);
 }
 
 static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo,
@@ -840,25 +852,15 @@ static void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count,
 	}
 }
 
-static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count)
+static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count,
+				   u32 base_reg, u32 reg)
 {
 	int i;
-	u32 wb_data[2];
-
-	wb_data[0] = wb_data[1] = 0;
-
+	u32 wb_data[2] = {0, 0};
 	for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) {
-		REG_WR(bp, QM_REG_BASEADDR + i*4,
+		REG_WR(bp, base_reg + i*4,
 		       qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
-		bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8,
-				  wb_data, 2);
-
-		if (CHIP_IS_E1H(bp)) {
-			REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4,
-			       qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
-			bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8,
-					  wb_data, 2);
-		}
+		bnx2x_init_wr_wb(bp, reg + i*8,	 wb_data, 2);
 	}
 }
 
@@ -873,7 +875,12 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
 	case INITOP_INIT:
 		/* set in the init-value array */
 	case INITOP_SET:
-		bnx2x_qm_set_ptr_table(bp, qm_cid_count);
+		bnx2x_qm_set_ptr_table(bp, qm_cid_count,
+				       QM_REG_BASEADDR, QM_REG_PTRTBL);
+		if (CHIP_IS_E1H(bp))
+			bnx2x_qm_set_ptr_table(bp, qm_cid_count,
+					       QM_REG_BASEADDR_EXT_A,
+					       QM_REG_PTRTBL_EXT_A);
 		break;
 	case INITOP_CLEAR:
 		break;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 2091e5d..beb4cdb 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -1,4 +1,4 @@
-/* Copyright 2008-2011 Broadcom Corporation
+/* Copyright 2008-2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -1612,6 +1612,9 @@ static void bnx2x_umac_enable(struct link_params *params,
 	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
 		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
 
+	if (vars->duplex == DUPLEX_HALF)
+		val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
+
 	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
 	udelay(50);
 
@@ -3635,45 +3638,50 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
 		vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
 }
 
-static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
-				   struct link_params *params,
-				   struct link_vars *vars)
+static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
+					struct link_params *params,
+					struct link_vars *vars)
 {
-	struct bnx2x *bp = params->bp;
 	u16 ld_pause;		/* local */
 	u16 lp_pause;		/* link partner */
 	u16 pause_result;
-	u8 ret = 0;
-	/* read twice */
+	struct bnx2x *bp = params->bp;
+	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
+		bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
+		bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
+	} else {
+		bnx2x_cl45_read(bp, phy,
+				MDIO_AN_DEVAD,
+				MDIO_AN_REG_ADV_PAUSE, &ld_pause);
+		bnx2x_cl45_read(bp, phy,
+				MDIO_AN_DEVAD,
+				MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
+	}
+	pause_result = (ld_pause &
+			MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
+	pause_result |= (lp_pause &
+			 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
+	DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
+	bnx2x_pause_resolve(vars, pause_result);
 
+}
+static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
+				   struct link_params *params,
+				   struct link_vars *vars)
+{
+	u8 ret = 0;
 	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
-
-	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
+	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
+		/* Update the advertised flow-controled of LD/LP in AN */
+		if (phy->req_line_speed == SPEED_AUTO_NEG)
+			bnx2x_ext_phy_update_adv_fc(phy, params, vars);
+		/* But set the flow-control result as the requested one */
 		vars->flow_ctrl = phy->req_flow_ctrl;
-	else if (phy->req_line_speed != SPEED_AUTO_NEG)
+	} else if (phy->req_line_speed != SPEED_AUTO_NEG)
 		vars->flow_ctrl = params->req_fc_auto_adv;
 	else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
 		ret = 1;
-		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
-			bnx2x_cl22_read(bp, phy,
-					0x4, &ld_pause);
-			bnx2x_cl22_read(bp, phy,
-					0x5, &lp_pause);
-		} else {
-			bnx2x_cl45_read(bp, phy,
-					MDIO_AN_DEVAD,
-					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
-			bnx2x_cl45_read(bp, phy,
-					MDIO_AN_DEVAD,
-					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
-		}
-		pause_result = (ld_pause &
-				MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
-		pause_result |= (lp_pause &
-				 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
-		DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
-		   pause_result);
-		bnx2x_pause_resolve(vars, pause_result);
+		bnx2x_ext_phy_update_adv_fc(phy, params, vars);
 	}
 	return ret;
 }
@@ -3785,7 +3793,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
 
 	/* Enable Autoneg */
 	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
-			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
+			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
 
 }
 
@@ -5216,22 +5224,69 @@ static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
 	return 0;
 }
 
+static void bnx2x_update_adv_fc(struct bnx2x_phy *phy,
+				struct link_params *params,
+				struct link_vars *vars,
+				u32 gp_status)
+{
+	u16 ld_pause;   /* local driver */
+	u16 lp_pause;   /* link partner */
+	u16 pause_result;
+	struct bnx2x *bp = params->bp;
+	if ((gp_status &
+	     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
+	      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
+	    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
+	     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
+
+		CL22_RD_OVER_CL45(bp, phy,
+				  MDIO_REG_BANK_CL73_IEEEB1,
+				  MDIO_CL73_IEEEB1_AN_ADV1,
+				  &ld_pause);
+		CL22_RD_OVER_CL45(bp, phy,
+				  MDIO_REG_BANK_CL73_IEEEB1,
+				  MDIO_CL73_IEEEB1_AN_LP_ADV1,
+				  &lp_pause);
+		pause_result = (ld_pause &
+				MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
+		pause_result |= (lp_pause &
+				 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
+		DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result);
+	} else {
+		CL22_RD_OVER_CL45(bp, phy,
+				  MDIO_REG_BANK_COMBO_IEEE0,
+				  MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
+				  &ld_pause);
+		CL22_RD_OVER_CL45(bp, phy,
+			MDIO_REG_BANK_COMBO_IEEE0,
+			MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
+			&lp_pause);
+		pause_result = (ld_pause &
+				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
+		pause_result |= (lp_pause &
+				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
+		DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result);
+	}
+	bnx2x_pause_resolve(vars, pause_result);
+
+}
+
 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
 				    struct link_params *params,
 				    struct link_vars *vars,
 				    u32 gp_status)
 {
 	struct bnx2x *bp = params->bp;
-	u16 ld_pause;   /* local driver */
-	u16 lp_pause;   /* link partner */
-	u16 pause_result;
-
 	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
 
 	/* resolve from gp_status in case of AN complete and not sgmii */
-	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
+	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
+		/* Update the advertised flow-controled of LD/LP in AN */
+		if (phy->req_line_speed == SPEED_AUTO_NEG)
+			bnx2x_update_adv_fc(phy, params, vars, gp_status);
+		/* But set the flow-control result as the requested one */
 		vars->flow_ctrl = phy->req_flow_ctrl;
-	else if (phy->req_line_speed != SPEED_AUTO_NEG)
+	} else if (phy->req_line_speed != SPEED_AUTO_NEG)
 		vars->flow_ctrl = params->req_fc_auto_adv;
 	else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
 		 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
@@ -5239,45 +5294,7 @@ static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
 			vars->flow_ctrl = params->req_fc_auto_adv;
 			return;
 		}
-		if ((gp_status &
-		    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
-		     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
-		    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
-		     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
-
-			CL22_RD_OVER_CL45(bp, phy,
-					  MDIO_REG_BANK_CL73_IEEEB1,
-					  MDIO_CL73_IEEEB1_AN_ADV1,
-					  &ld_pause);
-			CL22_RD_OVER_CL45(bp, phy,
-					  MDIO_REG_BANK_CL73_IEEEB1,
-					  MDIO_CL73_IEEEB1_AN_LP_ADV1,
-					  &lp_pause);
-			pause_result = (ld_pause &
-					MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
-					>> 8;
-			pause_result |= (lp_pause &
-					MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
-					>> 10;
-			DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
-				 pause_result);
-		} else {
-			CL22_RD_OVER_CL45(bp, phy,
-					  MDIO_REG_BANK_COMBO_IEEE0,
-					  MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
-					  &ld_pause);
-			CL22_RD_OVER_CL45(bp, phy,
-				MDIO_REG_BANK_COMBO_IEEE0,
-				MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
-				&lp_pause);
-			pause_result = (ld_pause &
-				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
-			pause_result |= (lp_pause &
-				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
-			DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
-				 pause_result);
-		}
-		bnx2x_pause_resolve(vars, pause_result);
+		bnx2x_update_adv_fc(phy, params, vars, gp_status);
 	}
 	DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
 }
@@ -5496,6 +5513,33 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
 		}
 	}
 
+	/* Read LP advertised speeds*/
+	if (SINGLE_MEDIA_DIRECT(params) &&
+	    (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
+		u16 val;
+
+		CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1,
+				  MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
+
+		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
+			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
+
+		CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G,
+				  MDIO_OVER_1G_LP_UP1, &val);
+
+		if (val & MDIO_OVER_1G_UP1_2_5G)
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
+		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
+	}
+
 	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
 		   vars->duplex, vars->flow_ctrl, vars->link_status);
 	return rc;
@@ -5553,6 +5597,34 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
 		}
 	}
 
+	if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
+	    SINGLE_MEDIA_DIRECT(params)) {
+		u16 val;
+
+		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+				MDIO_AN_REG_LP_AUTO_NEG2, &val);
+
+		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
+			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
+
+		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
+				MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
+
+		if (val & MDIO_OVER_1G_UP1_2_5G)
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
+		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
+
+	}
+
+
 	if (lane < 2) {
 		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
 				MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
@@ -5970,8 +6042,8 @@ static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
 	return 0;
 }
 
-int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
-				 u8 *version, u16 len)
+int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 *version,
+				 u16 len)
 {
 	struct bnx2x *bp;
 	u32 spirom_ver = 0;
@@ -6418,7 +6490,9 @@ static int bnx2x_update_link_down(struct link_params *params,
 			       LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
 			       LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
 			       LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
-			       LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
+			       LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK |
+			       LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE |
+			       LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE);
 	vars->line_speed = 0;
 	bnx2x_update_mng(params, vars->link_status);
 
@@ -7367,6 +7441,19 @@ static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
 		bnx2x_8073_resolve_fc(phy, params, vars);
 		vars->duplex = DUPLEX_FULL;
 	}
+
+	if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
+		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+				MDIO_AN_REG_LP_AUTO_NEG2, &val1);
+
+		if (val1 & (1<<5))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+		if (val1 & (1<<7))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
+	}
+
 	return link_up;
 }
 
@@ -9405,13 +9492,8 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
 {
 	struct bnx2x *bp = params->bp;
 	u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val;
-	u16 tmp_req_line_speed;
 
-	tmp_req_line_speed = phy->req_line_speed;
-	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
-		if (phy->req_line_speed == SPEED_10000)
-			phy->req_line_speed = SPEED_AUTO_NEG;
-	} else {
+	if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
 		/* Save spirom version */
 		bnx2x_save_848xx_spirom_version(phy, bp, params->port);
 	}
@@ -9555,8 +9637,6 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
 				 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
 				 1);
 
-	phy->req_line_speed = tmp_req_line_speed;
-
 	return 0;
 }
 
@@ -9948,6 +10028,42 @@ static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
 		DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
 			   vars->line_speed);
 		bnx2x_ext_phy_resolve_fc(phy, params, vars);
+
+		/* Read LP advertised speeds */
+		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+				MDIO_AN_REG_CL37_FC_LP, &val);
+		if (val & (1<<5))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
+		if (val & (1<<6))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
+		if (val & (1<<7))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
+		if (val & (1<<8))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
+		if (val & (1<<9))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
+
+		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+				MDIO_AN_REG_1000T_STATUS, &val);
+
+		if (val & (1<<10))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
+		if (val & (1<<11))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+
+		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
+				MDIO_AN_REG_MASTER_STATUS, &val);
+
+		if (val & (1<<11))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
 	}
 
 	return link_up;
@@ -10571,6 +10687,35 @@ static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
 		}
 
 		bnx2x_ext_phy_resolve_fc(phy, params, vars);
+
+		if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
+			/* report LP advertised speeds */
+			bnx2x_cl22_read(bp, phy, 0x5, &val);
+
+			if (val & (1<<5))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
+			if (val & (1<<6))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
+			if (val & (1<<7))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
+			if (val & (1<<8))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
+			if (val & (1<<9))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
+
+			bnx2x_cl22_read(bp, phy, 0xa, &val);
+			if (val & (1<<10))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
+			if (val & (1<<11))
+				vars->link_status |=
+				  LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
+		}
 	}
 	return link_up;
 }
@@ -10699,6 +10844,11 @@ static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
 			   val2, (val2 & (1<<14)));
 		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
 		bnx2x_ext_phy_resolve_fc(phy, params, vars);
+
+		/* read LP advertised speeds */
+		if (val2 & (1<<11))
+			vars->link_status |=
+				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
 	}
 	return link_up;
 }
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
index e02a68a..7ba557a 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
@@ -1,4 +1,4 @@
-/* Copyright 2008-2011 Broadcom Corporation
+/* Copyright 2008-2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -337,8 +337,8 @@ int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
 void bnx2x_link_status_update(struct link_params *input,
 			    struct link_vars *output);
 /* returns string representing the fw_version of the external phy */
-int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
-				 u8 *version, u16 len);
+int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 *version,
+				 u16 len);
 
 /* Set/Unset the led
    Basically, the CLC takes care of the led for the link, but in case one needs
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 2545213..b4afef6 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -1,6 +1,6 @@
 /* bnx2x_main.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -464,7 +464,9 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp,
 	while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
 		DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
 
-		if (!cnt) {
+		if (!cnt ||
+		    (bp->recovery_state != BNX2X_RECOVERY_DONE &&
+		     bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) {
 			BNX2X_ERR("DMAE timeout!\n");
 			rc = DMAE_TIMEOUT;
 			goto unlock;
@@ -494,9 +496,13 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 	if (!bp->dmae_ready) {
 		u32 *data = bnx2x_sp(bp, wb_data[0]);
 
-		DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x  len32 %d)"
-		   "  using indirect\n", dst_addr, len32);
-		bnx2x_init_ind_wr(bp, dst_addr, data, len32);
+		DP(BNX2X_MSG_OFF,
+		   "DMAE is not ready (dst_addr %08x len32 %d) using indirect\n",
+		   dst_addr, len32);
+		if (CHIP_IS_E1(bp))
+			bnx2x_init_ind_wr(bp, dst_addr, data, len32);
+		else
+			bnx2x_init_str_wr(bp, dst_addr, data, len32);
 		return;
 	}
 
@@ -524,10 +530,16 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 		u32 *data = bnx2x_sp(bp, wb_data[0]);
 		int i;
 
-		DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x  len32 %d)"
-		   "  using indirect\n", src_addr, len32);
-		for (i = 0; i < len32; i++)
-			data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
+		if (CHIP_IS_E1(bp)) {
+			DP(BNX2X_MSG_OFF,
+			   "DMAE is not ready (src_addr %08x len32 %d) using indirect\n",
+			   src_addr, len32);
+			for (i = 0; i < len32; i++)
+				data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
+		} else
+			for (i = 0; i < len32; i++)
+				data[i] = REG_RD(bp, src_addr + i*4);
+
 		return;
 	}
 
@@ -768,6 +780,7 @@ void bnx2x_panic_dump(struct bnx2x *bp)
 #endif
 
 	bp->stats_state = STATS_STATE_DISABLED;
+	bp->eth_stats.unrecoverable_error++;
 	DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
 
 	BNX2X_ERR("begin crash dump -----------------\n");
@@ -1003,8 +1016,8 @@ void bnx2x_panic_dump(struct bnx2x *bp)
  * initialization.
  */
 #define FLR_WAIT_USEC		10000	/* 10 miliseconds */
-#define FLR_WAIT_INTERAVAL	50	/* usec */
-#define	FLR_POLL_CNT		(FLR_WAIT_USEC/FLR_WAIT_INTERAVAL) /* 200 */
+#define FLR_WAIT_INTERVAL	50	/* usec */
+#define	FLR_POLL_CNT		(FLR_WAIT_USEC/FLR_WAIT_INTERVAL) /* 200 */
 
 struct pbf_pN_buf_regs {
 	int pN;
@@ -1037,7 +1050,7 @@ static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp,
 	while ((crd != init_crd) && ((u32)SUB_S32(crd_freed, crd_freed_start) <
 	       (init_crd - crd_start))) {
 		if (cur_cnt--) {
-			udelay(FLR_WAIT_INTERAVAL);
+			udelay(FLR_WAIT_INTERVAL);
 			crd = REG_RD(bp, regs->crd);
 			crd_freed = REG_RD(bp, regs->crd_freed);
 		} else {
@@ -1051,7 +1064,7 @@ static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp,
 		}
 	}
 	DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF tx buffer[%d]\n",
-	   poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN);
+	   poll_count-cur_cnt, FLR_WAIT_INTERVAL, regs->pN);
 }
 
 static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp,
@@ -1069,7 +1082,7 @@ static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp,
 
 	while (occup && ((u32)SUB_S32(freed, freed_start) < to_free)) {
 		if (cur_cnt--) {
-			udelay(FLR_WAIT_INTERAVAL);
+			udelay(FLR_WAIT_INTERVAL);
 			occup = REG_RD(bp, regs->lines_occup);
 			freed = REG_RD(bp, regs->lines_freed);
 		} else {
@@ -1083,7 +1096,7 @@ static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp,
 		}
 	}
 	DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF cmd queue[%d]\n",
-	   poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN);
+	   poll_count-cur_cnt, FLR_WAIT_INTERVAL, regs->pN);
 }
 
 static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg,
@@ -1093,7 +1106,7 @@ static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg,
 	u32 val;
 
 	while ((val = REG_RD(bp, reg)) != expected && cur_cnt--)
-		udelay(FLR_WAIT_INTERAVAL);
+		udelay(FLR_WAIT_INTERVAL);
 
 	return val;
 }
@@ -1206,7 +1219,7 @@ static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func,
 	int ret = 0;
 
 	if (REG_RD(bp, comp_addr)) {
-		BNX2X_ERR("Cleanup complete is not 0\n");
+		BNX2X_ERR("Cleanup complete was not 0 before sending\n");
 		return 1;
 	}
 
@@ -1215,7 +1228,7 @@ static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func,
 	op_gen.command |= OP_GEN_AGG_VECT(clnup_func);
 	op_gen.command |= 1 << SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT;
 
-	DP(BNX2X_MSG_SP, "FW Final cleanup\n");
+	DP(BNX2X_MSG_SP, "sending FW Final cleanup\n");
 	REG_WR(bp, XSDM_REG_OPERATION_GEN, op_gen.command);
 
 	if (bnx2x_flr_clnup_reg_poll(bp, comp_addr, 1, poll_cnt) != 1) {
@@ -1330,6 +1343,7 @@ static int bnx2x_pf_flr_clnup(struct bnx2x *bp)
 	REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
 
 	/* Poll HW usage counters */
+	DP(BNX2X_MSG_SP, "Polling usage counters\n");
 	if (bnx2x_poll_hw_usage_counters(bp, poll_cnt))
 		return -EBUSY;
 
@@ -2688,6 +2702,8 @@ static inline unsigned long bnx2x_get_q_flags(struct bnx2x *bp,
 	if (!fp->disable_tpa) {
 		__set_bit(BNX2X_Q_FLG_TPA, &flags);
 		__set_bit(BNX2X_Q_FLG_TPA_IPV6, &flags);
+		if (fp->mode == TPA_MODE_GRO)
+			__set_bit(BNX2X_Q_FLG_TPA_GRO, &flags);
 	}
 
 	if (leading) {
@@ -3709,11 +3725,11 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
  */
 void bnx2x_set_reset_global(struct bnx2x *bp)
 {
-	u32 val	= REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
-
+	u32 val;
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT);
-	barrier();
-	mmiowb();
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
 }
 
 /*
@@ -3723,11 +3739,11 @@ void bnx2x_set_reset_global(struct bnx2x *bp)
  */
 static inline void bnx2x_clear_reset_global(struct bnx2x *bp)
 {
-	u32 val	= REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
-
+	u32 val;
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT));
-	barrier();
-	mmiowb();
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
 }
 
 /*
@@ -3750,15 +3766,17 @@ static inline bool bnx2x_reset_is_global(struct bnx2x *bp)
  */
 static inline void bnx2x_set_reset_done(struct bnx2x *bp)
 {
-	u32 val	= REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val;
 	u32 bit = BP_PATH(bp) ?
 		BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 
 	/* Clear the bit */
 	val &= ~bit;
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
-	barrier();
-	mmiowb();
+
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
 }
 
 /*
@@ -3768,15 +3786,16 @@ static inline void bnx2x_set_reset_done(struct bnx2x *bp)
  */
 void bnx2x_set_reset_in_progress(struct bnx2x *bp)
 {
-	u32 val	= REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val;
 	u32 bit = BP_PATH(bp) ?
 		BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT;
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 
 	/* Set the bit */
 	val |= bit;
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
-	barrier();
-	mmiowb();
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
 }
 
 /*
@@ -3794,25 +3813,28 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine)
 }
 
 /*
- * Increment the load counter for the current engine.
+ * set pf load for the current pf.
  *
  * should be run under rtnl lock
  */
-void bnx2x_inc_load_cnt(struct bnx2x *bp)
+void bnx2x_set_pf_load(struct bnx2x *bp)
 {
-	u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val1, val;
 	u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
 			     BNX2X_PATH0_LOAD_CNT_MASK;
 	u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT :
 			     BNX2X_PATH0_LOAD_CNT_SHIFT;
 
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+
 	DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val);
 
 	/* get the current counter value */
 	val1 = (val & mask) >> shift;
 
-	/* increment... */
-	val1++;
+	/* set bit of that PF */
+	val1 |= (1 << bp->pf_num);
 
 	/* clear the old value */
 	val &= ~mask;
@@ -3821,34 +3843,35 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp)
 	val |= ((val1 << shift) & mask);
 
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
-	barrier();
-	mmiowb();
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
 }
 
 /**
- * bnx2x_dec_load_cnt - decrement the load counter
+ * bnx2x_clear_pf_load - clear pf load mark
  *
  * @bp:		driver handle
  *
  * Should be run under rtnl lock.
  * Decrements the load counter for the current engine. Returns
- * the new counter value.
+ * whether other functions are still loaded
  */
-u32 bnx2x_dec_load_cnt(struct bnx2x *bp)
+bool bnx2x_clear_pf_load(struct bnx2x *bp)
 {
-	u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val1, val;
 	u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
 			     BNX2X_PATH0_LOAD_CNT_MASK;
 	u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT :
 			     BNX2X_PATH0_LOAD_CNT_SHIFT;
 
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 	DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val);
 
 	/* get the current counter value */
 	val1 = (val & mask) >> shift;
 
-	/* decrement... */
-	val1--;
+	/* clear bit of that PF */
+	val1 &= ~(1 << bp->pf_num);
 
 	/* clear the old value */
 	val &= ~mask;
@@ -3857,18 +3880,16 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp)
 	val |= ((val1 << shift) & mask);
 
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val);
-	barrier();
-	mmiowb();
-
-	return val1;
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	return val1 != 0;
 }
 
 /*
- * Read the load counter for the current engine.
+ * Read the load status for the current engine.
  *
  * should be run under rtnl lock
  */
-static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine)
+static inline bool bnx2x_get_load_status(struct bnx2x *bp, int engine)
 {
 	u32 mask = (engine ? BNX2X_PATH1_LOAD_CNT_MASK :
 			     BNX2X_PATH0_LOAD_CNT_MASK);
@@ -3880,23 +3901,23 @@ static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine)
 
 	val = (val & mask) >> shift;
 
-	DP(NETIF_MSG_HW, "load_cnt for engine %d = %d\n", engine, val);
+	DP(NETIF_MSG_HW, "load mask for engine %d = 0x%x\n", engine, val);
 
-	return val;
+	return val != 0;
 }
 
 /*
- * Reset the load counter for the current engine.
- *
- * should be run under rtnl lock
+ * Reset the load status for the current engine.
  */
-static inline void bnx2x_clear_load_cnt(struct bnx2x *bp)
+static inline void bnx2x_clear_load_status(struct bnx2x *bp)
 {
-	u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
+	u32 val;
 	u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK :
-			     BNX2X_PATH0_LOAD_CNT_MASK);
-
+		    BNX2X_PATH0_LOAD_CNT_MASK);
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
+	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG);
 	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask));
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG);
 }
 
 static inline void _print_next_block(int idx, const char *blk)
@@ -5410,6 +5431,7 @@ static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx)
 
 	/* init shortcut */
 	fp->ustorm_rx_prods_offset = bnx2x_rx_ustorm_prods_offset(fp);
+
 	/* Setup SB indicies */
 	fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
 
@@ -6674,13 +6696,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
 	u16 cdu_ilt_start;
 	u32 addr, val;
 	u32 main_mem_base, main_mem_size, main_mem_prty_clr;
-	int i, main_mem_width;
+	int i, main_mem_width, rc;
 
 	DP(BNX2X_MSG_MCP, "starting func init  func %d\n", func);
 
 	/* FLR cleanup - hmmm */
-	if (!CHIP_IS_E1x(bp))
-		bnx2x_pf_flr_clnup(bp);
+	if (!CHIP_IS_E1x(bp)) {
+		rc = bnx2x_pf_flr_clnup(bp);
+		if (rc)
+			return rc;
+	}
 
 	/* set MSI reconfigure capability */
 	if (bp->common.int_block == INT_BLOCK_HC) {
@@ -7089,6 +7114,11 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
 	BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
 			sizeof(struct bnx2x_slowpath));
 
+#ifdef BCM_CNIC
+	/* write address to which L5 should insert its values */
+	bp->cnic_eth_dev.addr_drv_info_to_mcp = &bp->slowpath->drv_info_to_mcp;
+#endif
+
 	/* Allocated memory for FW statistics  */
 	if (bnx2x_alloc_fw_stats_mem(bp))
 		goto alloc_mem_err;
@@ -8445,13 +8475,38 @@ int bnx2x_leader_reset(struct bnx2x *bp)
 {
 	int rc = 0;
 	bool global = bnx2x_reset_is_global(bp);
+	u32 load_code;
+
+	/* if not going to reset MCP - load "fake" driver to reset HW while
+	 * driver is owner of the HW
+	 */
+	if (!global && !BP_NOMCP(bp)) {
+		load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0);
+		if (!load_code) {
+			BNX2X_ERR("MCP response failure, aborting\n");
+			rc = -EAGAIN;
+			goto exit_leader_reset;
+		}
+		if ((load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) &&
+		    (load_code != FW_MSG_CODE_DRV_LOAD_COMMON)) {
+			BNX2X_ERR("MCP unexpected resp, aborting\n");
+			rc = -EAGAIN;
+			goto exit_leader_reset2;
+		}
+		load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0);
+		if (!load_code) {
+			BNX2X_ERR("MCP response failure, aborting\n");
+			rc = -EAGAIN;
+			goto exit_leader_reset2;
+		}
+	}
 
 	/* Try to recover after the failure */
 	if (bnx2x_process_kill(bp, global)) {
 		netdev_err(bp->dev, "Something bad had happen on engine %d! "
 				    "Aii!\n", BP_PATH(bp));
 		rc = -EAGAIN;
-		goto exit_leader_reset;
+		goto exit_leader_reset2;
 	}
 
 	/*
@@ -8462,6 +8517,12 @@ int bnx2x_leader_reset(struct bnx2x *bp)
 	if (global)
 		bnx2x_clear_reset_global(bp);
 
+exit_leader_reset2:
+	/* unload "fake driver" if it was loaded */
+	if (!global && !BP_NOMCP(bp)) {
+		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0);
+		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
+	}
 exit_leader_reset:
 	bp->is_leader = 0;
 	bnx2x_release_leader_lock(bp);
@@ -8498,13 +8559,16 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp)
 static void bnx2x_parity_recover(struct bnx2x *bp)
 {
 	bool global = false;
+	u32 error_recovered, error_unrecovered;
+	bool is_parity;
 
 	DP(NETIF_MSG_HW, "Handling parity\n");
 	while (1) {
 		switch (bp->recovery_state) {
 		case BNX2X_RECOVERY_INIT:
 			DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n");
-			bnx2x_chk_parity_attn(bp, &global, false);
+			is_parity = bnx2x_chk_parity_attn(bp, &global, false);
+			WARN_ON(!is_parity);
 
 			/* Try to get a LEADER_LOCK HW lock */
 			if (bnx2x_trylock_leader_lock(bp)) {
@@ -8528,15 +8592,6 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
 
 			bp->recovery_state = BNX2X_RECOVERY_WAIT;
 
-			/*
-			 * Reset MCP command sequence number and MCP mail box
-			 * sequence as we are going to reset the MCP.
-			 */
-			if (global) {
-				bp->fw_seq = 0;
-				bp->fw_drv_pulse_wr_seq = 0;
-			}
-
 			/* Ensure "is_leader", MCP command sequence and
 			 * "recovery_state" update values are seen on other
 			 * CPUs.
@@ -8548,10 +8603,10 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
 			DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n");
 			if (bp->is_leader) {
 				int other_engine = BP_PATH(bp) ? 0 : 1;
-				u32 other_load_counter =
-					bnx2x_get_load_cnt(bp, other_engine);
-				u32 load_counter =
-					bnx2x_get_load_cnt(bp, BP_PATH(bp));
+				bool other_load_status =
+					bnx2x_get_load_status(bp, other_engine);
+				bool load_status =
+					bnx2x_get_load_status(bp, BP_PATH(bp));
 				global = bnx2x_reset_is_global(bp);
 
 				/*
@@ -8562,8 +8617,8 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
 				 * the the gates will remain closed for that
 				 * engine.
 				 */
-				if (load_counter ||
-				    (global && other_load_counter)) {
+				if (load_status ||
+				    (global && other_load_status)) {
 					/* Wait until all other functions get
 					 * down.
 					 */
@@ -8620,13 +8675,34 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
 						return;
 					}
 
-					if (bnx2x_nic_load(bp, LOAD_NORMAL))
-						bnx2x_recovery_failed(bp);
-					else {
+					error_recovered =
+					  bp->eth_stats.recoverable_error;
+					error_unrecovered =
+					  bp->eth_stats.unrecoverable_error;
+					bp->recovery_state =
+						BNX2X_RECOVERY_NIC_LOADING;
+					if (bnx2x_nic_load(bp, LOAD_NORMAL)) {
+						error_unrecovered++;
+						netdev_err(bp->dev,
+							   "Recovery failed. "
+							   "Power cycle "
+							   "needed\n");
+						/* Disconnect this device */
+						netif_device_detach(bp->dev);
+						/* Shut down the power */
+						bnx2x_set_power_state(
+							bp, PCI_D3hot);
+						smp_mb();
+					} else {
 						bp->recovery_state =
 							BNX2X_RECOVERY_DONE;
+						error_recovered++;
 						smp_mb();
 					}
+					bp->eth_stats.recoverable_error =
+						error_recovered;
+					bp->eth_stats.unrecoverable_error =
+						error_unrecovered;
 
 					return;
 				}
@@ -8637,6 +8713,8 @@ static void bnx2x_parity_recover(struct bnx2x *bp)
 	}
 }
 
+static int bnx2x_close(struct net_device *dev);
+
 /* bnx2x_nic_unload() flushes the bnx2x_wq, thus reset task is
  * scheduled on a general queue in order to prevent a dead lock.
  */
@@ -8782,11 +8860,13 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 {
 	u32 val;
 
-	/* Check if there is any driver already loaded */
-	val = REG_RD(bp, MISC_REG_UNPREPARED);
-	if (val == 0x1) {
+	/* possibly another driver is trying to reset the chip */
+	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
+
+	/* check if doorbell queue is reset */
+	if (REG_RD(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET)
+	    & MISC_REGISTERS_RESET_REG_1_RST_DORQ) {
 
-		bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
 		/*
 		 * Check if it is the UNDI driver
 		 * UNDI driver initializes CID offset for normal bell to 0x7
@@ -8874,14 +8954,11 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
 
 			/* restore our func and fw_seq */
 			bp->pf_num = orig_pf_num;
-			bp->fw_seq =
-			      (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) &
-				DRV_MSG_SEQ_NUMBER_MASK);
 		}
-
-		/* now it's safe to release the lock */
-		bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
 	}
+
+	/* now it's safe to release the lock */
+	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET);
 }
 
 static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
@@ -9212,6 +9289,11 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
 					SPEED_AUTO_NEG;
 				bp->port.advertising[idx] |=
 					bp->port.supported[idx];
+				if (bp->link_params.phy[EXT_PHY1].type ==
+				    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
+					bp->port.advertising[idx] |=
+					(SUPPORTED_100baseT_Half |
+					 SUPPORTED_100baseT_Full);
 			} else {
 				/* force 10G, no AN */
 				bp->link_params.req_line_speed[idx] =
@@ -9592,7 +9674,7 @@ static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp)
 
 	if (BP_NOMCP(bp)) {
 		BNX2X_ERROR("warning: random MAC workaround active\n");
-		random_ether_addr(bp->dev->dev_addr);
+		eth_hw_addr_random(bp->dev);
 	} else if (IS_MF(bp)) {
 		val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper);
 		val = MF_CFG_RD(bp, func_mf_config[func].mac_lower);
@@ -9902,16 +9984,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
 
 	bnx2x_get_cnic_info(bp);
 
-	/* Get current FW pulse sequence */
-	if (!BP_NOMCP(bp)) {
-		int mb_idx = BP_FW_MB_IDX(bp);
-
-		bp->fw_drv_pulse_wr_seq =
-				(SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) &
-				 DRV_PULSE_SEQ_MASK);
-		BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
-	}
-
 	return rc;
 }
 
@@ -10080,14 +10152,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 	if (!BP_NOMCP(bp))
 		bnx2x_undi_unload(bp);
 
-	/* init fw_seq after undi_unload! */
-	if (!BP_NOMCP(bp)) {
-		bp->fw_seq =
-			(SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
-			 DRV_MSG_SEQ_NUMBER_MASK);
-		BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
-	}
-
 	if (CHIP_REV_IS_FPGA(bp))
 		dev_err(&bp->pdev->dev, "FPGA detected\n");
 
@@ -10105,10 +10169,10 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 
 	/* Set TPA flags */
 	if (bp->disable_tpa) {
-		bp->flags &= ~TPA_ENABLE_FLAG;
+		bp->flags &= ~(TPA_ENABLE_FLAG | GRO_ENABLE_FLAG);
 		bp->dev->features &= ~NETIF_F_LRO;
 	} else {
-		bp->flags |= TPA_ENABLE_FLAG;
+		bp->flags |= (TPA_ENABLE_FLAG | GRO_ENABLE_FLAG);
 		bp->dev->features |= NETIF_F_LRO;
 	}
 
@@ -10150,6 +10214,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 	if (CHIP_IS_E3B0(bp))
 		bp->max_cos = BNX2X_MULTI_TX_COS_E3B0;
 
+	bp->gro_check = bnx2x_need_gro_check(bp->dev->mtu);
+
 	return rc;
 }
 
@@ -10168,14 +10234,16 @@ static int bnx2x_open(struct net_device *dev)
 	struct bnx2x *bp = netdev_priv(dev);
 	bool global = false;
 	int other_engine = BP_PATH(bp) ? 0 : 1;
-	u32 other_load_counter, load_counter;
+	bool other_load_status, load_status;
+
+	bp->stats_init = true;
 
 	netif_carrier_off(dev);
 
 	bnx2x_set_power_state(bp, PCI_D0);
 
-	other_load_counter = bnx2x_get_load_cnt(bp, other_engine);
-	load_counter = bnx2x_get_load_cnt(bp, BP_PATH(bp));
+	other_load_status = bnx2x_get_load_status(bp, other_engine);
+	load_status = bnx2x_get_load_status(bp, BP_PATH(bp));
 
 	/*
 	 * If parity had happen during the unload, then attentions
@@ -10201,8 +10269,8 @@ static int bnx2x_open(struct net_device *dev)
 			 * global blocks only the first in the chip should try
 			 * to recover.
 			 */
-			if ((!load_counter &&
-			     (!global || !other_load_counter)) &&
+			if ((!load_status &&
+			     (!global || !other_load_status)) &&
 			    bnx2x_trylock_leader_lock(bp) &&
 			    !bnx2x_leader_reset(bp)) {
 				netdev_info(bp->dev, "Recovered in open\n");
@@ -10226,7 +10294,7 @@ static int bnx2x_open(struct net_device *dev)
 }
 
 /* called with rtnl_lock */
-int bnx2x_close(struct net_device *dev)
+static int bnx2x_close(struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
@@ -10521,6 +10589,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 {
 	struct bnx2x *bp;
 	int rc;
+	u32 pci_cfg_dword;
 	bool chip_is_e1x = (board_type == BCM57710 ||
 			    board_type == BCM57711 ||
 			    board_type == BCM57711E);
@@ -10531,7 +10600,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 	bp->dev = dev;
 	bp->pdev = pdev;
 	bp->flags = 0;
-	bp->pf_num = PCI_FUNC(pdev->devfn);
 
 	rc = pci_enable_device(pdev);
 	if (rc) {
@@ -10598,6 +10666,21 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 		goto err_out_release;
 	}
 
+	/* In E1/E1H use pci device function given by kernel.
+	 * In E2/E3 read physical function from ME register since these chips
+	 * support Physical Device Assignment where kernel BDF maybe arbitrary
+	 * (depending on hypervisor).
+	 */
+	if (chip_is_e1x)
+		bp->pf_num = PCI_FUNC(pdev->devfn);
+	else {/* chip is E2/3*/
+		pci_read_config_dword(bp->pdev,
+				      PCICFG_ME_REGISTER, &pci_cfg_dword);
+		bp->pf_num = (u8)((pci_cfg_dword & ME_REG_ABS_PF_NUM) >>
+		    ME_REG_ABS_PF_NUM_SHIFT);
+	}
+	DP(BNX2X_MSG_SP, "me reg PF num: %d\n", bp->pf_num);
+
 	bnx2x_set_power_state(bp, PCI_D0);
 
 	/* clean indirect addresses */
@@ -10627,7 +10710,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 		REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1);
 
 	/* Reset the load counter */
-	bnx2x_clear_load_cnt(bp);
+	bnx2x_clear_load_status(bp);
 
 	dev->watchdog_timeo = TX_TIMEOUT;
 
@@ -10637,8 +10720,9 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 	dev->priv_flags |= IFF_UNICAST_FLT;
 
 	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_LRO |
-		NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_HW_VLAN_TX;
+		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
+		NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO |
+		NETIF_F_RXHASH | NETIF_F_HW_VLAN_TX;
 
 	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
@@ -10814,10 +10898,8 @@ static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
 do {									\
 	u32 len = be32_to_cpu(fw_hdr->arr.len);				\
 	bp->arr = kmalloc(len, GFP_KERNEL);				\
-	if (!bp->arr) {							\
-		pr_err("Failed to allocate %d bytes for "#arr"\n", len); \
+	if (!bp->arr)							\
 		goto lbl;						\
-	}								\
 	func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset),	\
 	     (u8 *)bp->arr, len);					\
 } while (0)
@@ -11055,10 +11137,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
 
 	/* dev zeroed in init_etherdev */
 	dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count);
-	if (!dev) {
-		dev_err(&pdev->dev, "Cannot allocate net device\n");
+	if (!dev)
 		return -ENOMEM;
-	}
 
 	bp = netdev_priv(dev);
 
@@ -11264,29 +11344,11 @@ static void bnx2x_eeh_recover(struct bnx2x *bp)
 
 	mutex_init(&bp->port.phy_mutex);
 
-	bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
-	bp->link_params.shmem_base = bp->common.shmem_base;
-	BNX2X_DEV_INFO("shmem offset is 0x%x\n", bp->common.shmem_base);
-
-	if (!bp->common.shmem_base ||
-	    (bp->common.shmem_base < 0xA0000) ||
-	    (bp->common.shmem_base >= 0xC0000)) {
-		BNX2X_DEV_INFO("MCP not active\n");
-		bp->flags |= NO_MCP_FLAG;
-		return;
-	}
 
 	val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
 	if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
 		!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
 		BNX2X_ERR("BAD MCP validity signature\n");
-
-	if (!BP_NOMCP(bp)) {
-		bp->fw_seq =
-		    (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) &
-		    DRV_MSG_SEQ_NUMBER_MASK);
-		BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
-	}
 }
 
 /**
@@ -11542,6 +11604,13 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev,
 		return -EIO;
 #endif
 
+	if ((bp->recovery_state != BNX2X_RECOVERY_DONE) &&
+	    (bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) {
+		netdev_err(dev, "Handling parity error recovery. Try again "
+				"later\n");
+		return -EAGAIN;
+	}
+
 	spin_lock_bh(&bp->spq_lock);
 
 	for (i = 0; i < count; i++) {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index dddbcf6..fd7fb45 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -1,6 +1,6 @@
 /* bnx2x_reg.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -4812,6 +4812,7 @@
    The fields are: [4:0] - tail pointer; 10:5] - Link List size; 15:11] -
    header pointer. */
 #define UCM_REG_XX_TABLE					 0xe0300
+#define UMAC_COMMAND_CONFIG_REG_HD_ENA				 (0x1<<10)
 #define UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE			 (0x1<<28)
 #define UMAC_COMMAND_CONFIG_REG_LOOP_ENA			 (0x1<<15)
 #define UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK			 (0x1<<24)
@@ -5731,6 +5732,7 @@
 #define MISC_REGISTERS_GPIO_PORT_SHIFT				 4
 #define MISC_REGISTERS_GPIO_SET_POS				 8
 #define MISC_REGISTERS_RESET_REG_1_CLEAR			 0x588
+#define MISC_REGISTERS_RESET_REG_1_RST_DORQ			 (0x1<<19)
 #define MISC_REGISTERS_RESET_REG_1_RST_HC			 (0x1<<29)
 #define MISC_REGISTERS_RESET_REG_1_RST_NIG			 (0x1<<7)
 #define MISC_REGISTERS_RESET_REG_1_RST_PXP			 (0x1<<26)
@@ -5783,15 +5785,17 @@
 #define MISC_REGISTERS_SPIO_OUTPUT_HIGH 			 1
 #define MISC_REGISTERS_SPIO_OUTPUT_LOW				 0
 #define MISC_REGISTERS_SPIO_SET_POS				 8
-#define HW_LOCK_DRV_FLAGS					 10
 #define HW_LOCK_MAX_RESOURCE_VALUE				 31
+#define HW_LOCK_RESOURCE_DRV_FLAGS				 10
 #define HW_LOCK_RESOURCE_GPIO					 1
 #define HW_LOCK_RESOURCE_MDIO					 0
+#define HW_LOCK_RESOURCE_NVRAM					 12
 #define HW_LOCK_RESOURCE_PORT0_ATT_MASK				 3
 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_0			 8
 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_1			 9
-#define HW_LOCK_RESOURCE_SPIO					 2
+#define HW_LOCK_RESOURCE_RECOVERY_REG				 11
 #define HW_LOCK_RESOURCE_RESET					 5
+#define HW_LOCK_RESOURCE_SPIO					 2
 #define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT			 (0x1<<4)
 #define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR			 (0x1<<5)
 #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR			 (0x1<<18)
@@ -6023,7 +6027,8 @@
 #define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP	(0x1<<23)
 #define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE	(0x1<<24)
 #define PCICFG_GRC_ADDRESS				0x78
-#define PCICFG_GRC_DATA 				0x80
+#define PCICFG_GRC_DATA				0x80
+#define PCICFG_ME_REGISTER				0x98
 #define PCICFG_MSIX_CAP_ID_OFFSET			0xa0
 #define PCICFG_MSIX_CONTROL_TABLE_SIZE		(0x7ff<<16)
 #define PCICFG_MSIX_CONTROL_RESERVED		(0x7<<27)
@@ -6401,6 +6406,7 @@
 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_ASYMMETRIC		0x0800
 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_BOTH		0x0C00
 #define MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK		0x0C00
+#define MDIO_CL73_IEEEB1_AN_LP_ADV2			0x04
 
 #define MDIO_REG_BANK_RX0				0x80b0
 #define MDIO_RX0_RX_STATUS				0x10
@@ -6794,14 +6800,16 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_AN_REG_ADV_PAUSE_MASK		0x0C00
 #define MDIO_AN_REG_ADV 		0x0011
 #define MDIO_AN_REG_ADV2		0x0012
-#define MDIO_AN_REG_LP_AUTO_NEG 	0x0013
+#define MDIO_AN_REG_LP_AUTO_NEG		0x0013
+#define MDIO_AN_REG_LP_AUTO_NEG2	0x0014
 #define MDIO_AN_REG_MASTER_STATUS	0x0021
 /*bcm*/
 #define MDIO_AN_REG_LINK_STATUS 	0x8304
 #define MDIO_AN_REG_CL37_CL73		0x8370
 #define MDIO_AN_REG_CL37_AN		0xffe0
 #define MDIO_AN_REG_CL37_FC_LD		0xffe4
-#define MDIO_AN_REG_CL37_FC_LP		0xffe5
+#define		MDIO_AN_REG_CL37_FC_LP		0xffe5
+#define		MDIO_AN_REG_1000T_STATUS	0xffea
 
 #define MDIO_AN_REG_8073_2_5G		0x8329
 #define MDIO_AN_REG_8073_BAM		0x8350
@@ -6966,6 +6974,7 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_WC_REG_SERDESDIGITAL_MISC1			0x8308
 #define MDIO_WC_REG_SERDESDIGITAL_MISC2			0x8309
 #define MDIO_WC_REG_DIGITAL3_UP1			0x8329
+#define MDIO_WC_REG_DIGITAL3_LP_UP1			 0x832c
 #define MDIO_WC_REG_DIGITAL4_MISC3			0x833c
 #define MDIO_WC_REG_DIGITAL5_MISC6			0x8345
 #define MDIO_WC_REG_DIGITAL5_MISC7			0x8349
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index cb6339c..adfae6b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -1,6 +1,6 @@
 /* bnx2x_sp.c: Broadcom Everest network driver.
  *
- * Copyright 2011 Broadcom Corporation
+ * Copyright (c) 2011-2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -1836,6 +1836,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
 			rc = exeq->remove(bp, exeq->owner, exeq_pos);
 			if (rc) {
 				BNX2X_ERR("Failed to remove command\n");
+				spin_unlock_bh(&exeq->lock);
 				return rc;
 			}
 			list_del(&exeq_pos->link);
@@ -4430,9 +4431,10 @@ static void bnx2x_q_fill_init_rx_data(struct bnx2x_queue_sp_obj *o,
 				struct client_init_rx_data *rx_data,
 				unsigned long *flags)
 {
-		/* Rx data */
 	rx_data->tpa_en = test_bit(BNX2X_Q_FLG_TPA, flags) *
 				CLIENT_INIT_RX_DATA_TPA_EN_IPV4;
+	rx_data->tpa_en |= test_bit(BNX2X_Q_FLG_TPA_GRO, flags) *
+				CLIENT_INIT_RX_DATA_TPA_MODE;
 	rx_data->vmqueue_mode_en_flg = 0;
 
 	rx_data->cache_line_alignment_log_size =
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index 66da39f..685d42e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -1,6 +1,6 @@
 /* bnx2x_sp.h: Broadcom Everest network driver.
  *
- * Copyright 2011 Broadcom Corporation
+ * Copyright (c) 2011-2012 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -774,6 +774,7 @@ enum bnx2x_queue_cmd {
 enum {
 	BNX2X_Q_FLG_TPA,
 	BNX2X_Q_FLG_TPA_IPV6,
+	BNX2X_Q_FLG_TPA_GRO,
 	BNX2X_Q_FLG_STATS,
 	BNX2X_Q_FLG_ZERO_STATS,
 	BNX2X_Q_FLG_ACTIVE,
@@ -803,10 +804,10 @@ enum bnx2x_q_type {
 };
 
 #define BNX2X_PRIMARY_CID_INDEX			0
-#define BNX2X_MULTI_TX_COS_E1X			1
+#define BNX2X_MULTI_TX_COS_E1X			3 /* QM only */
 #define BNX2X_MULTI_TX_COS_E2_E3A0		2
 #define BNX2X_MULTI_TX_COS_E3B0			3
-#define BNX2X_MULTI_TX_COS			BNX2X_MULTI_TX_COS_E3B0
+#define BNX2X_MULTI_TX_COS			3 /* Maximum possible */
 
 
 struct bnx2x_queue_init_params {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
index 1adef26..14c961b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c
@@ -1,6 +1,6 @@
 /* bnx2x_stats.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -161,7 +161,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp)
 	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
 
 	/* sanity */
-	if (!IS_MF(bp) || !bp->port.pmf || !bp->port.port_stx) {
+	if (!bp->port.pmf || !bp->port.port_stx) {
 		BNX2X_ERR("BUG!\n");
 		return;
 	}
@@ -638,31 +638,30 @@ static void bnx2x_mstat_stats_update(struct bnx2x *bp)
 			tx_stat_dot3statsinternalmactransmiterrors);
 	ADD_STAT64(stats_tx.tx_gtufl, tx_stat_mac_ufl);
 
-	ADD_64(estats->etherstatspkts1024octetsto1522octets_hi,
-	       new->stats_tx.tx_gt1518_hi,
-	       estats->etherstatspkts1024octetsto1522octets_lo,
-	       new->stats_tx.tx_gt1518_lo);
+	estats->etherstatspkts1024octetsto1522octets_hi =
+	    pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_hi;
+	estats->etherstatspkts1024octetsto1522octets_lo =
+	    pstats->mac_stx[1].tx_stat_etherstatspkts1024octetsto1522octets_lo;
 
-	ADD_64(estats->etherstatspktsover1522octets_hi,
-	       new->stats_tx.tx_gt2047_hi,
-	       estats->etherstatspktsover1522octets_lo,
-	       new->stats_tx.tx_gt2047_lo);
+	estats->etherstatspktsover1522octets_hi =
+	    pstats->mac_stx[1].tx_stat_mac_2047_hi;
+	estats->etherstatspktsover1522octets_lo =
+	    pstats->mac_stx[1].tx_stat_mac_2047_lo;
 
 	ADD_64(estats->etherstatspktsover1522octets_hi,
-	       new->stats_tx.tx_gt4095_hi,
+	       pstats->mac_stx[1].tx_stat_mac_4095_hi,
 	       estats->etherstatspktsover1522octets_lo,
-	       new->stats_tx.tx_gt4095_lo);
+	       pstats->mac_stx[1].tx_stat_mac_4095_lo);
 
 	ADD_64(estats->etherstatspktsover1522octets_hi,
-	       new->stats_tx.tx_gt9216_hi,
+	       pstats->mac_stx[1].tx_stat_mac_9216_hi,
 	       estats->etherstatspktsover1522octets_lo,
-	       new->stats_tx.tx_gt9216_lo);
-
+	       pstats->mac_stx[1].tx_stat_mac_9216_lo);
 
 	ADD_64(estats->etherstatspktsover1522octets_hi,
-	       new->stats_tx.tx_gt16383_hi,
+	       pstats->mac_stx[1].tx_stat_mac_16383_hi,
 	       estats->etherstatspktsover1522octets_lo,
-	       new->stats_tx.tx_gt16383_lo);
+	       pstats->mac_stx[1].tx_stat_mac_16383_lo);
 
 	estats->pause_frames_received_hi =
 				pstats->mac_stx[1].rx_stat_mac_xpf_hi;
@@ -817,6 +816,7 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 				&bp->fw_stats_data->pf.tstorm_pf_statistics;
 	struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
 	struct bnx2x_eth_stats *estats = &bp->eth_stats;
+	struct bnx2x_eth_stats_old *estats_old = &bp->eth_stats_old;
 	struct stats_counter *counters = &bp->fw_stats_data->storm_counters;
 	int i;
 	u16 cur_stats_counter;
@@ -857,21 +857,8 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 		return -EAGAIN;
 	}
 
-	memcpy(&(fstats->total_bytes_received_hi),
-	       &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi),
-	       sizeof(struct host_func_stats) - 2*sizeof(u32));
 	estats->error_bytes_received_hi = 0;
 	estats->error_bytes_received_lo = 0;
-	estats->etherstatsoverrsizepkts_hi = 0;
-	estats->etherstatsoverrsizepkts_lo = 0;
-	estats->no_buff_discard_hi = 0;
-	estats->no_buff_discard_lo = 0;
-	estats->total_tpa_aggregations_hi = 0;
-	estats->total_tpa_aggregations_lo = 0;
-	estats->total_tpa_aggregated_frames_hi = 0;
-	estats->total_tpa_aggregated_frames_lo = 0;
-	estats->total_tpa_bytes_hi = 0;
-	estats->total_tpa_bytes_lo = 0;
 
 	for_each_eth_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
@@ -888,6 +875,8 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 			xstorm_queue_statistics;
 		struct xstorm_per_queue_stats *old_xclient = &fp->old_xclient;
 		struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
+		struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
+
 		u32 diff;
 
 		DP(BNX2X_MSG_STATS, "queue[%d]: ucast_sent 0x%x, "
@@ -897,20 +886,12 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 
 		DP(BNX2X_MSG_STATS, "---------------\n");
 
-		qstats->total_broadcast_bytes_received_hi =
-			le32_to_cpu(tclient->rcv_bcast_bytes.hi);
-		qstats->total_broadcast_bytes_received_lo =
-			le32_to_cpu(tclient->rcv_bcast_bytes.lo);
-
-		qstats->total_multicast_bytes_received_hi =
-			le32_to_cpu(tclient->rcv_mcast_bytes.hi);
-		qstats->total_multicast_bytes_received_lo =
-			le32_to_cpu(tclient->rcv_mcast_bytes.lo);
-
-		qstats->total_unicast_bytes_received_hi =
-			le32_to_cpu(tclient->rcv_ucast_bytes.hi);
-		qstats->total_unicast_bytes_received_lo =
-			le32_to_cpu(tclient->rcv_ucast_bytes.lo);
+		UPDATE_QSTAT(tclient->rcv_bcast_bytes,
+			     total_broadcast_bytes_received);
+		UPDATE_QSTAT(tclient->rcv_mcast_bytes,
+			     total_multicast_bytes_received);
+		UPDATE_QSTAT(tclient->rcv_ucast_bytes,
+			     total_unicast_bytes_received);
 
 		/*
 		 * sum to total_bytes_received all
@@ -943,9 +924,9 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 					total_multicast_packets_received);
 		UPDATE_EXTEND_TSTAT(rcv_bcast_pkts,
 					total_broadcast_packets_received);
-		UPDATE_EXTEND_TSTAT(pkts_too_big_discard,
-					etherstatsoverrsizepkts);
-		UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard);
+		UPDATE_EXTEND_E_TSTAT(pkts_too_big_discard,
+				      etherstatsoverrsizepkts);
+		UPDATE_EXTEND_E_TSTAT(no_buff_discard, no_buff_discard);
 
 		SUB_EXTEND_USTAT(ucast_no_buff_pkts,
 					total_unicast_packets_received);
@@ -953,24 +934,17 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 					total_multicast_packets_received);
 		SUB_EXTEND_USTAT(bcast_no_buff_pkts,
 					total_broadcast_packets_received);
-		UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard);
-		UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard);
-		UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard);
-
-		qstats->total_broadcast_bytes_transmitted_hi =
-			le32_to_cpu(xclient->bcast_bytes_sent.hi);
-		qstats->total_broadcast_bytes_transmitted_lo =
-			le32_to_cpu(xclient->bcast_bytes_sent.lo);
-
-		qstats->total_multicast_bytes_transmitted_hi =
-			le32_to_cpu(xclient->mcast_bytes_sent.hi);
-		qstats->total_multicast_bytes_transmitted_lo =
-			le32_to_cpu(xclient->mcast_bytes_sent.lo);
-
-		qstats->total_unicast_bytes_transmitted_hi =
-			le32_to_cpu(xclient->ucast_bytes_sent.hi);
-		qstats->total_unicast_bytes_transmitted_lo =
-			le32_to_cpu(xclient->ucast_bytes_sent.lo);
+		UPDATE_EXTEND_E_USTAT(ucast_no_buff_pkts, no_buff_discard);
+		UPDATE_EXTEND_E_USTAT(mcast_no_buff_pkts, no_buff_discard);
+		UPDATE_EXTEND_E_USTAT(bcast_no_buff_pkts, no_buff_discard);
+
+		UPDATE_QSTAT(xclient->bcast_bytes_sent,
+			     total_broadcast_bytes_transmitted);
+		UPDATE_QSTAT(xclient->mcast_bytes_sent,
+			     total_multicast_bytes_transmitted);
+		UPDATE_QSTAT(xclient->ucast_bytes_sent,
+			     total_unicast_bytes_transmitted);
+
 		/*
 		 * sum to total_bytes_transmitted all
 		 * unicast/multicast/broadcast
@@ -1006,110 +980,54 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 				    total_transmitted_dropped_packets_error);
 
 		/* TPA aggregations completed */
-		UPDATE_EXTEND_USTAT(coalesced_events, total_tpa_aggregations);
+		UPDATE_EXTEND_E_USTAT(coalesced_events, total_tpa_aggregations);
 		/* Number of network frames aggregated by TPA */
-		UPDATE_EXTEND_USTAT(coalesced_pkts,
-				    total_tpa_aggregated_frames);
+		UPDATE_EXTEND_E_USTAT(coalesced_pkts,
+				      total_tpa_aggregated_frames);
 		/* Total number of bytes in completed TPA aggregations */
-		qstats->total_tpa_bytes_lo =
-			le32_to_cpu(uclient->coalesced_bytes.lo);
-		qstats->total_tpa_bytes_hi =
-			le32_to_cpu(uclient->coalesced_bytes.hi);
-
-		/* TPA stats per-function */
-		ADD_64(estats->total_tpa_aggregations_hi,
-		       qstats->total_tpa_aggregations_hi,
-		       estats->total_tpa_aggregations_lo,
-		       qstats->total_tpa_aggregations_lo);
-		ADD_64(estats->total_tpa_aggregated_frames_hi,
-		       qstats->total_tpa_aggregated_frames_hi,
-		       estats->total_tpa_aggregated_frames_lo,
-		       qstats->total_tpa_aggregated_frames_lo);
-		ADD_64(estats->total_tpa_bytes_hi,
-		       qstats->total_tpa_bytes_hi,
-		       estats->total_tpa_bytes_lo,
-		       qstats->total_tpa_bytes_lo);
-
-		ADD_64(fstats->total_bytes_received_hi,
-		       qstats->total_bytes_received_hi,
-		       fstats->total_bytes_received_lo,
-		       qstats->total_bytes_received_lo);
-		ADD_64(fstats->total_bytes_transmitted_hi,
-		       qstats->total_bytes_transmitted_hi,
-		       fstats->total_bytes_transmitted_lo,
-		       qstats->total_bytes_transmitted_lo);
-		ADD_64(fstats->total_unicast_packets_received_hi,
-		       qstats->total_unicast_packets_received_hi,
-		       fstats->total_unicast_packets_received_lo,
-		       qstats->total_unicast_packets_received_lo);
-		ADD_64(fstats->total_multicast_packets_received_hi,
-		       qstats->total_multicast_packets_received_hi,
-		       fstats->total_multicast_packets_received_lo,
-		       qstats->total_multicast_packets_received_lo);
-		ADD_64(fstats->total_broadcast_packets_received_hi,
-		       qstats->total_broadcast_packets_received_hi,
-		       fstats->total_broadcast_packets_received_lo,
-		       qstats->total_broadcast_packets_received_lo);
-		ADD_64(fstats->total_unicast_packets_transmitted_hi,
-		       qstats->total_unicast_packets_transmitted_hi,
-		       fstats->total_unicast_packets_transmitted_lo,
-		       qstats->total_unicast_packets_transmitted_lo);
-		ADD_64(fstats->total_multicast_packets_transmitted_hi,
-		       qstats->total_multicast_packets_transmitted_hi,
-		       fstats->total_multicast_packets_transmitted_lo,
-		       qstats->total_multicast_packets_transmitted_lo);
-		ADD_64(fstats->total_broadcast_packets_transmitted_hi,
-		       qstats->total_broadcast_packets_transmitted_hi,
-		       fstats->total_broadcast_packets_transmitted_lo,
-		       qstats->total_broadcast_packets_transmitted_lo);
-		ADD_64(fstats->valid_bytes_received_hi,
-		       qstats->valid_bytes_received_hi,
-		       fstats->valid_bytes_received_lo,
-		       qstats->valid_bytes_received_lo);
-
-		ADD_64(estats->etherstatsoverrsizepkts_hi,
-		       qstats->etherstatsoverrsizepkts_hi,
-		       estats->etherstatsoverrsizepkts_lo,
-		       qstats->etherstatsoverrsizepkts_lo);
-		ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi,
-		       estats->no_buff_discard_lo, qstats->no_buff_discard_lo);
+		UPDATE_QSTAT(uclient->coalesced_bytes, total_tpa_bytes);
+
+		UPDATE_ESTAT_QSTAT_64(total_tpa_bytes);
+
+		UPDATE_FSTAT_QSTAT(total_bytes_received);
+		UPDATE_FSTAT_QSTAT(total_bytes_transmitted);
+		UPDATE_FSTAT_QSTAT(total_unicast_packets_received);
+		UPDATE_FSTAT_QSTAT(total_multicast_packets_received);
+		UPDATE_FSTAT_QSTAT(total_broadcast_packets_received);
+		UPDATE_FSTAT_QSTAT(total_unicast_packets_transmitted);
+		UPDATE_FSTAT_QSTAT(total_multicast_packets_transmitted);
+		UPDATE_FSTAT_QSTAT(total_broadcast_packets_transmitted);
+		UPDATE_FSTAT_QSTAT(valid_bytes_received);
 	}
 
-	ADD_64(fstats->total_bytes_received_hi,
+	ADD_64(estats->total_bytes_received_hi,
 	       estats->rx_stat_ifhcinbadoctets_hi,
-	       fstats->total_bytes_received_lo,
+	       estats->total_bytes_received_lo,
 	       estats->rx_stat_ifhcinbadoctets_lo);
 
-	ADD_64(fstats->total_bytes_received_hi,
+	ADD_64(estats->total_bytes_received_hi,
 	       le32_to_cpu(tfunc->rcv_error_bytes.hi),
-	       fstats->total_bytes_received_lo,
+	       estats->total_bytes_received_lo,
 	       le32_to_cpu(tfunc->rcv_error_bytes.lo));
 
-	memcpy(estats, &(fstats->total_bytes_received_hi),
-	       sizeof(struct host_func_stats) - 2*sizeof(u32));
-
 	ADD_64(estats->error_bytes_received_hi,
 	       le32_to_cpu(tfunc->rcv_error_bytes.hi),
 	       estats->error_bytes_received_lo,
 	       le32_to_cpu(tfunc->rcv_error_bytes.lo));
 
-	ADD_64(estats->etherstatsoverrsizepkts_hi,
-	       estats->rx_stat_dot3statsframestoolong_hi,
-	       estats->etherstatsoverrsizepkts_lo,
-	       estats->rx_stat_dot3statsframestoolong_lo);
+	UPDATE_ESTAT(etherstatsoverrsizepkts, rx_stat_dot3statsframestoolong);
+
 	ADD_64(estats->error_bytes_received_hi,
 	       estats->rx_stat_ifhcinbadoctets_hi,
 	       estats->error_bytes_received_lo,
 	       estats->rx_stat_ifhcinbadoctets_lo);
 
 	if (bp->port.pmf) {
-		estats->mac_filter_discard =
-				le32_to_cpu(tport->mac_filter_discard);
-		estats->mf_tag_discard =
-				le32_to_cpu(tport->mf_tag_discard);
-		estats->brb_truncate_discard =
-				le32_to_cpu(tport->brb_truncate_discard);
-		estats->mac_discard = le32_to_cpu(tport->mac_discard);
+		struct bnx2x_fw_port_stats_old *fwstats = &bp->fw_stats_old;
+		UPDATE_FW_STAT(mac_filter_discard);
+		UPDATE_FW_STAT(mf_tag_discard);
+		UPDATE_FW_STAT(brb_truncate_discard);
+		UPDATE_FW_STAT(mac_discard);
 	}
 
 	fstats->host_func_stats_start = ++fstats->host_func_stats_end;
@@ -1143,7 +1061,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
 	tmp = estats->mac_discard;
 	for_each_rx_queue(bp, i)
 		tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
-	nstats->rx_dropped = tmp;
+	nstats->rx_dropped = tmp + bp->net_stats_old.rx_dropped;
 
 	nstats->tx_dropped = 0;
 
@@ -1191,17 +1109,15 @@ static void bnx2x_drv_stats_update(struct bnx2x *bp)
 	struct bnx2x_eth_stats *estats = &bp->eth_stats;
 	int i;
 
-	estats->driver_xoff = 0;
-	estats->rx_err_discard_pkt = 0;
-	estats->rx_skb_alloc_failed = 0;
-	estats->hw_csum_err = 0;
 	for_each_queue(bp, i) {
 		struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
+		struct bnx2x_eth_q_stats_old *qstats_old =
+						&bp->fp[i].eth_q_stats_old;
 
-		estats->driver_xoff += qstats->driver_xoff;
-		estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt;
-		estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed;
-		estats->hw_csum_err += qstats->hw_csum_err;
+		UPDATE_ESTAT_QSTAT(driver_xoff);
+		UPDATE_ESTAT_QSTAT(rx_err_discard_pkt);
+		UPDATE_ESTAT_QSTAT(rx_skb_alloc_failed);
+		UPDATE_ESTAT_QSTAT(hw_csum_err);
 	}
 }
 
@@ -1446,33 +1362,6 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp)
 	bnx2x_stats_comp(bp);
 }
 
-static void bnx2x_func_stats_base_init(struct bnx2x *bp)
-{
-	int vn, vn_max = IS_MF(bp) ? BP_MAX_VN_NUM(bp) : E1VN_MAX;
-	u32 func_stx;
-
-	/* sanity */
-	if (!bp->port.pmf || !bp->func_stx) {
-		BNX2X_ERR("BUG!\n");
-		return;
-	}
-
-	/* save our func_stx */
-	func_stx = bp->func_stx;
-
-	for (vn = VN_0; vn < vn_max; vn++) {
-		int mb_idx = BP_FW_MB_IDX_VN(bp, vn);
-
-		bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param);
-		bnx2x_func_stats_init(bp);
-		bnx2x_hw_stats_post(bp);
-		bnx2x_stats_comp(bp);
-	}
-
-	/* restore our func_stx */
-	bp->func_stx = func_stx;
-}
-
 static void bnx2x_func_stats_base_update(struct bnx2x *bp)
 {
 	struct dmae_command *dmae = &bp->stats_dmae;
@@ -1491,8 +1380,8 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp)
 					 true, DMAE_COMP_PCI);
 	dmae->src_addr_lo = bp->func_stx >> 2;
 	dmae->src_addr_hi = 0;
-	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base));
-	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base));
+	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats));
+	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats));
 	dmae->len = sizeof(struct host_func_stats) >> 2;
 	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
 	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
@@ -1653,6 +1542,10 @@ void bnx2x_stats_init(struct bnx2x *bp)
 	DP(BNX2X_MSG_STATS, "port_stx 0x%x  func_stx 0x%x\n",
 	   bp->port.port_stx, bp->func_stx);
 
+	/* pmf should retrieve port statistics from SP on a non-init*/
+	if (!bp->stats_init && bp->port.pmf && bp->port.port_stx)
+		bnx2x_stats_handle(bp, STATS_EVENT_PMF);
+
 	port = BP_PORT(bp);
 	/* port stats */
 	memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
@@ -1674,24 +1567,83 @@ void bnx2x_stats_init(struct bnx2x *bp)
 		memset(&fp->old_tclient, 0, sizeof(fp->old_tclient));
 		memset(&fp->old_uclient, 0, sizeof(fp->old_uclient));
 		memset(&fp->old_xclient, 0, sizeof(fp->old_xclient));
-		memset(&fp->eth_q_stats, 0, sizeof(fp->eth_q_stats));
+		if (bp->stats_init) {
+			memset(&fp->eth_q_stats, 0, sizeof(fp->eth_q_stats));
+			memset(&fp->eth_q_stats_old, 0,
+			       sizeof(fp->eth_q_stats_old));
+		}
 	}
 
 	/* Prepare statistics ramrod data */
 	bnx2x_prep_fw_stats_req(bp);
 
 	memset(&bp->dev->stats, 0, sizeof(bp->dev->stats));
-	memset(&bp->eth_stats, 0, sizeof(bp->eth_stats));
+	if (bp->stats_init) {
+		memset(&bp->net_stats_old, 0, sizeof(bp->net_stats_old));
+		memset(&bp->fw_stats_old, 0, sizeof(bp->fw_stats_old));
+		memset(&bp->eth_stats_old, 0, sizeof(bp->eth_stats_old));
+		memset(&bp->eth_stats, 0, sizeof(bp->eth_stats));
 
-	bp->stats_state = STATS_STATE_DISABLED;
+		/* Clean SP from previous statistics */
+		if (bp->func_stx) {
+			memset(bnx2x_sp(bp, func_stats), 0,
+			       sizeof(struct host_func_stats));
+			bnx2x_func_stats_init(bp);
+			bnx2x_hw_stats_post(bp);
+			bnx2x_stats_comp(bp);
+		}
+	}
 
-	if (bp->port.pmf) {
-		if (bp->port.port_stx)
-			bnx2x_port_stats_base_init(bp);
+	bp->stats_state = STATS_STATE_DISABLED;
 
-		if (bp->func_stx)
-			bnx2x_func_stats_base_init(bp);
+	if (bp->port.pmf && bp->port.port_stx)
+		bnx2x_port_stats_base_init(bp);
 
-	} else if (bp->func_stx)
+	/* On a non-init, retrieve previous statistics from SP */
+	if (!bp->stats_init && bp->func_stx)
 		bnx2x_func_stats_base_update(bp);
+
+	/* mark the end of statistics initializiation */
+	bp->stats_init = false;
+}
+
+void bnx2x_save_statistics(struct bnx2x *bp)
+{
+	int i;
+	struct net_device_stats *nstats = &bp->dev->stats;
+
+	/* save queue statistics */
+	for_each_eth_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+		struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
+		struct bnx2x_eth_q_stats_old *qstats_old = &fp->eth_q_stats_old;
+
+		UPDATE_QSTAT_OLD(total_unicast_bytes_received_hi);
+		UPDATE_QSTAT_OLD(total_unicast_bytes_received_lo);
+		UPDATE_QSTAT_OLD(total_broadcast_bytes_received_hi);
+		UPDATE_QSTAT_OLD(total_broadcast_bytes_received_lo);
+		UPDATE_QSTAT_OLD(total_multicast_bytes_received_hi);
+		UPDATE_QSTAT_OLD(total_multicast_bytes_received_lo);
+		UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_hi);
+		UPDATE_QSTAT_OLD(total_unicast_bytes_transmitted_lo);
+		UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_hi);
+		UPDATE_QSTAT_OLD(total_broadcast_bytes_transmitted_lo);
+		UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_hi);
+		UPDATE_QSTAT_OLD(total_multicast_bytes_transmitted_lo);
+		UPDATE_QSTAT_OLD(total_tpa_bytes_hi);
+		UPDATE_QSTAT_OLD(total_tpa_bytes_lo);
+	}
+
+	/* save net_device_stats statistics */
+	bp->net_stats_old.rx_dropped = nstats->rx_dropped;
+
+	/* store port firmware statistics */
+	if (bp->port.pmf && IS_MF(bp)) {
+		struct bnx2x_eth_stats *estats = &bp->eth_stats;
+		struct bnx2x_fw_port_stats_old *fwstats = &bp->fw_stats_old;
+		UPDATE_FW_STAT_OLD(mac_filter_discard);
+		UPDATE_FW_STAT_OLD(mf_tag_discard);
+		UPDATE_FW_STAT_OLD(brb_truncate_discard);
+		UPDATE_FW_STAT_OLD(mac_discard);
+	}
 }
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
index 683deb0..39ffd6d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h
@@ -1,6 +1,6 @@
 /* bnx2x_stats.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2011 Broadcom Corporation
+ * Copyright (c) 2007-2012 Broadcom Corporation
  *
  * 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
@@ -199,6 +199,10 @@ struct bnx2x_eth_stats {
 	u32 pfc_frames_received_lo;
 	u32 pfc_frames_sent_hi;
 	u32 pfc_frames_sent_lo;
+
+	/* Recovery */
+	u32 recoverable_error;
+	u32 unrecoverable_error;
 };
 
 
@@ -260,6 +264,69 @@ struct bnx2x_eth_q_stats {
 	u32 total_tpa_bytes_lo;
 };
 
+struct bnx2x_eth_stats_old {
+	u32 rx_stat_dot3statsframestoolong_hi;
+	u32 rx_stat_dot3statsframestoolong_lo;
+};
+
+struct bnx2x_eth_q_stats_old {
+	/* Fields to perserve over fw reset*/
+	u32 total_unicast_bytes_received_hi;
+	u32 total_unicast_bytes_received_lo;
+	u32 total_broadcast_bytes_received_hi;
+	u32 total_broadcast_bytes_received_lo;
+	u32 total_multicast_bytes_received_hi;
+	u32 total_multicast_bytes_received_lo;
+	u32 total_unicast_bytes_transmitted_hi;
+	u32 total_unicast_bytes_transmitted_lo;
+	u32 total_broadcast_bytes_transmitted_hi;
+	u32 total_broadcast_bytes_transmitted_lo;
+	u32 total_multicast_bytes_transmitted_hi;
+	u32 total_multicast_bytes_transmitted_lo;
+	u32 total_tpa_bytes_hi;
+	u32 total_tpa_bytes_lo;
+
+	/* Fields to perserve last of */
+	u32 total_bytes_received_hi;
+	u32 total_bytes_received_lo;
+	u32 total_bytes_transmitted_hi;
+	u32 total_bytes_transmitted_lo;
+	u32 total_unicast_packets_received_hi;
+	u32 total_unicast_packets_received_lo;
+	u32 total_multicast_packets_received_hi;
+	u32 total_multicast_packets_received_lo;
+	u32 total_broadcast_packets_received_hi;
+	u32 total_broadcast_packets_received_lo;
+	u32 total_unicast_packets_transmitted_hi;
+	u32 total_unicast_packets_transmitted_lo;
+	u32 total_multicast_packets_transmitted_hi;
+	u32 total_multicast_packets_transmitted_lo;
+	u32 total_broadcast_packets_transmitted_hi;
+	u32 total_broadcast_packets_transmitted_lo;
+	u32 valid_bytes_received_hi;
+	u32 valid_bytes_received_lo;
+
+	u32 total_tpa_bytes_hi_old;
+	u32 total_tpa_bytes_lo_old;
+
+	u32 driver_xoff_old;
+	u32 rx_err_discard_pkt_old;
+	u32 rx_skb_alloc_failed_old;
+	u32 hw_csum_err_old;
+};
+
+struct bnx2x_net_stats_old {
+	 u32 rx_dropped;
+};
+
+struct bnx2x_fw_port_stats_old {
+	 u32 mac_filter_discard;
+	 u32 mf_tag_discard;
+	 u32 brb_truncate_discard;
+	 u32 mac_discard;
+};
+
+
 /****************************************************************************
 * Macros
 ****************************************************************************/
@@ -344,11 +411,28 @@ struct bnx2x_eth_q_stats {
 		ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
 	} while (0)
 
+#define UPDATE_EXTEND_E_TSTAT(s, t) \
+	do { \
+		UPDATE_EXTEND_TSTAT(s, t); \
+		ADD_EXTEND_64(estats->t##_hi, estats->t##_lo, diff); \
+	} while (0)
+
 #define UPDATE_EXTEND_USTAT(s, t) \
 	do { \
 		diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
 		old_uclient->s = uclient->s; \
-		ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+	} while (0)
+
+#define UPDATE_EXTEND_E_USTAT(s, t) \
+	do { \
+		UPDATE_EXTEND_USTAT(s, t); \
+		ADD_EXTEND_64(estats->t##_hi, estats->t##_lo, diff); \
+	} while (0)
+
+#define UPDATE_EXTEND_E_USTAT(s, t) \
+	do { \
+		UPDATE_EXTEND_USTAT(s, t); \
+		ADD_EXTEND_64(estats->t##_hi, estats->t##_lo, diff); \
 	} while (0)
 
 #define UPDATE_EXTEND_XSTAT(s, t) \
@@ -358,6 +442,66 @@ struct bnx2x_eth_q_stats {
 		ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
 	} while (0)
 
+#define UPDATE_QSTAT(s, t) \
+	do { \
+		qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \
+		qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \
+	} while (0)
+
+#define UPDATE_QSTAT_OLD(f) \
+	do { \
+		qstats_old->f = qstats->f; \
+	} while (0)
+
+#define UPDATE_ESTAT_QSTAT_64(s) \
+	do { \
+		ADD_64(estats->s##_hi, qstats->s##_hi, \
+		       estats->s##_lo, qstats->s##_lo); \
+		SUB_64(estats->s##_hi, qstats_old->s##_hi_old, \
+		       estats->s##_lo, qstats_old->s##_lo_old); \
+		qstats_old->s##_hi_old = qstats->s##_hi; \
+		qstats_old->s##_lo_old = qstats->s##_lo; \
+	} while (0)
+
+#define UPDATE_ESTAT_QSTAT(s) \
+	do { \
+		estats->s += qstats->s; \
+		estats->s -= qstats_old->s##_old; \
+		qstats_old->s##_old = qstats->s; \
+	} while (0)
+
+#define UPDATE_FSTAT_QSTAT(s) \
+	do { \
+		ADD_64(fstats->s##_hi, qstats->s##_hi, \
+		       fstats->s##_lo, qstats->s##_lo); \
+		SUB_64(fstats->s##_hi, qstats_old->s##_hi, \
+		       fstats->s##_lo, qstats_old->s##_lo); \
+		estats->s##_hi = fstats->s##_hi; \
+		estats->s##_lo = fstats->s##_lo; \
+		qstats_old->s##_hi = qstats->s##_hi; \
+		qstats_old->s##_lo = qstats->s##_lo; \
+	} while (0)
+
+#define UPDATE_FW_STAT(s) \
+	do { \
+		estats->s = le32_to_cpu(tport->s) + fwstats->s; \
+	} while (0)
+
+#define UPDATE_FW_STAT_OLD(f) \
+	do { \
+		fwstats->f = estats->f; \
+	} while (0)
+
+#define UPDATE_ESTAT(s, t) \
+	do { \
+		SUB_64(estats->s##_hi, estats_old->t##_hi, \
+		       estats->s##_lo, estats_old->t##_lo); \
+		ADD_64(estats->s##_hi, estats->t##_hi, \
+		       estats->s##_lo, estats->t##_lo); \
+		estats_old->t##_hi = estats->t##_hi; \
+		estats_old->t##_lo = estats->t##_lo; \
+	} while (0)
+
 /* minuend -= subtrahend */
 #define SUB_64(m_hi, s_hi, m_lo, s_lo) \
 	do { \
@@ -384,4 +528,10 @@ void bnx2x_stats_init(struct bnx2x *bp);
 
 void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
 
+/**
+ * bnx2x_save_statistics - save statistics when unloading.
+ *
+ * @bp:		driver handle
+ */
+void bnx2x_save_statistics(struct bnx2x *bp);
 #endif /* BNX2X_STATS_H */
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index dd3a0a2..df42995 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -1,6 +1,6 @@
 /* cnic.c: Broadcom CNIC core network driver.
  *
- * Copyright (c) 2006-2011 Broadcom Corporation
+ * Copyright (c) 2006-2012 Broadcom Corporation
  *
  * 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
@@ -380,6 +380,8 @@ static int cnic_iscsi_nl_msg_recv(struct cnic_dev *dev, u32 msg_type,
 		if (cnic_in_use(csk) &&
 		    test_bit(SK_F_CONNECT_START, &csk->flags)) {
 
+			csk->vlan_id = path_resp->vlan_id;
+
 			memcpy(csk->ha, path_resp->mac_addr, 6);
 			if (test_bit(SK_F_IPV6, &csk->flags))
 				memcpy(&csk->src_ip[0], &path_resp->src.v6_addr,
@@ -2521,12 +2523,35 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe)
 	u32 cid;
 	u32 opcode = KWQE_OPCODE(kwqe->kwqe_op_flag);
 	u32 layer_code = kwqe->kwqe_op_flag & KWQE_LAYER_MASK;
+	u32 kcqe_op;
 	int ulp_type;
 
 	cid = kwqe->kwqe_info0;
 	memset(&kcqe, 0, sizeof(kcqe));
 
-	if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_ISCSI) {
+	if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_FCOE) {
+		u32 l5_cid = 0;
+
+		ulp_type = CNIC_ULP_FCOE;
+		if (opcode == FCOE_KWQE_OPCODE_DISABLE_CONN) {
+			struct fcoe_kwqe_conn_enable_disable *req;
+
+			req = (struct fcoe_kwqe_conn_enable_disable *) kwqe;
+			kcqe_op = FCOE_KCQE_OPCODE_DISABLE_CONN;
+			cid = req->context_id;
+			l5_cid = req->conn_id;
+		} else if (opcode == FCOE_KWQE_OPCODE_DESTROY) {
+			kcqe_op = FCOE_KCQE_OPCODE_DESTROY_FUNC;
+		} else {
+			return;
+		}
+		kcqe.kcqe_op_flag = kcqe_op << KCQE_FLAGS_OPCODE_SHIFT;
+		kcqe.kcqe_op_flag |= KCQE_FLAGS_LAYER_MASK_L5_FCOE;
+		kcqe.kcqe_info1 = FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR;
+		kcqe.kcqe_info2 = cid;
+		kcqe.kcqe_info0 = l5_cid;
+
+	} else if (layer_code == KWQE_FLAGS_LAYER_MASK_L5_ISCSI) {
 		ulp_type = CNIC_ULP_ISCSI;
 		if (opcode == ISCSI_KWQE_OPCODE_UPDATE_CONN)
 			cid = kwqe->kwqe_info1;
@@ -2539,7 +2564,6 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe)
 
 	} else if (layer_code == KWQE_FLAGS_LAYER_MASK_L4) {
 		struct l4_kcq *l4kcqe = (struct l4_kcq *) &kcqe;
-		u32 kcqe_op;
 
 		ulp_type = CNIC_ULP_L4;
 		if (opcode == L4_KWQE_OPCODE_VALUE_CONNECT1)
@@ -2686,9 +2710,17 @@ static int cnic_submit_bnx2x_fcoe_kwqes(struct cnic_dev *dev,
 				   opcode);
 			break;
 		}
-		if (ret < 0)
+		if (ret < 0) {
 			netdev_err(dev->netdev, "KWQE(0x%x) failed\n",
 				   opcode);
+
+			/* Possibly bnx2x parity error, send completion
+			 * to ulp drivers with error code to speed up
+			 * cleanup and reset recovery.
+			 */
+			if (ret == -EIO || ret == -EAGAIN)
+				cnic_bnx2x_kwqe_err(dev, kwqe);
+		}
 		i += work;
 	}
 	return 0;
@@ -3897,6 +3929,8 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)
 	case L4_KCQE_OPCODE_VALUE_CONNECT_COMPLETE:
 		if (l4kcqe->status == 0)
 			set_bit(SK_F_OFFLD_COMPLETE, &csk->flags);
+		else if (l4kcqe->status == L4_KCQE_COMPLETION_STATUS_NIC_ERROR)
+			set_bit(SK_F_HW_ERR, &csk->flags);
 
 		smp_mb__before_clear_bit();
 		clear_bit(SK_F_OFFLD_SCHED, &csk->flags);
diff --git a/drivers/net/ethernet/broadcom/cnic_defs.h b/drivers/net/ethernet/broadcom/cnic_defs.h
index 86936f6..06ca002 100644
--- a/drivers/net/ethernet/broadcom/cnic_defs.h
+++ b/drivers/net/ethernet/broadcom/cnic_defs.h
@@ -1,7 +1,7 @@
 
 /* cnic.c: Broadcom CNIC core network driver.
  *
- * Copyright (c) 2006-2009 Broadcom Corporation
+ * Copyright (c) 2006-2012 Broadcom Corporation
  *
  * 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
@@ -69,6 +69,7 @@
 
 #define FCOE_KCQE_COMPLETION_STATUS_ERROR	(0x1)
 #define FCOE_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE	(0x3)
+#define FCOE_KCQE_COMPLETION_STATUS_NIC_ERROR	(0x5)
 
 /* KCQ (kernel completion queue) response op codes */
 #define L4_KCQE_OPCODE_VALUE_CLOSE_COMP             (53)
@@ -1392,9 +1393,9 @@ struct xstorm_fcoe_extra_ag_context_section {
 #define __XSTORM_FCOE_EXTRA_AG_CONTEXT_SECTION_RESERVED_DA_EXPIRATION_FLAG_SHIFT 7
 #endif
 	u32 snd_nxt;
-	u32 tx_wnd;
-	u32 __reserved55;
-	u32 local_adv_wnd;
+	u32 __xfrqe_bd_addr_lo;
+	u32 __xfrqe_bd_addr_hi;
+	u32 __xfrqe_data1;
 #if defined(__BIG_ENDIAN)
 	u8 __agg_val8_th;
 	u8 __tx_dest;
@@ -1480,13 +1481,13 @@ struct xstorm_fcoe_extra_ag_context_section {
 #endif
 	u32 __tcp_agg_vars6;
 #if defined(__BIG_ENDIAN)
-	u16 __agg_misc6;
+	u16 __xfrqe_mng;
 	u16 __tcp_agg_vars7;
 #elif defined(__LITTLE_ENDIAN)
 	u16 __tcp_agg_vars7;
-	u16 __agg_misc6;
+	u16 __xfrqe_mng;
 #endif
-	u32 __agg_val10;
+	u32 __xfrqe_data0;
 	u32 __agg_val10_th;
 #if defined(__BIG_ENDIAN)
 	u16 __reserved3;
@@ -1706,11 +1707,11 @@ struct xstorm_fcoe_ag_context {
 #define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3 (0xFF<<24)
 #define XSTORM_FCOE_AG_CONTEXT_AGG_MISC3_SHIFT 24
 #if defined(__BIG_ENDIAN)
-	u16 agg_misc0;
+	u16 __cache_wqe_db;
 	u16 sq_prod;
 #elif defined(__LITTLE_ENDIAN)
 	u16 sq_prod;
-	u16 agg_misc0;
+	u16 __cache_wqe_db;
 #endif
 #if defined(__BIG_ENDIAN)
 	u8 agg_val3;
@@ -3016,8 +3017,8 @@ struct fcoe_tce_tx_wr_rx_rd_const {
 #define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV1_SHIFT 5
 #define FCOE_TCE_TX_WR_RX_RD_CONST_TX_SEQ_INIT (0x1<<6)
 #define FCOE_TCE_TX_WR_RX_RD_CONST_TX_SEQ_INIT_SHIFT 6
-#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV2 (0x1<<7)
-#define FCOE_TCE_TX_WR_RX_RD_CONST_RSRV2_SHIFT 7
+#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_COMP_TRNS (0x1<<7)
+#define FCOE_TCE_TX_WR_RX_RD_CONST_TX_COMP_TRNS_SHIFT 7
 	__le16 rsrv3;
 	__le32 verify_tx_seq;
 };
@@ -4298,7 +4299,7 @@ struct xstorm_eth_context_section {
 #endif
 #if defined(__BIG_ENDIAN)
 	u16 reserved_vlan_type;
-	u16 params;
+	u16 vlan_params;
 #define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0)
 #define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0
 #define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12)
@@ -4306,7 +4307,7 @@ struct xstorm_eth_context_section {
 #define XSTORM_ETH_CONTEXT_SECTION_PRIORITY (0x7<<13)
 #define XSTORM_ETH_CONTEXT_SECTION_PRIORITY_SHIFT 13
 #elif defined(__LITTLE_ENDIAN)
-	u16 params;
+	u16 vlan_params;
 #define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID (0xFFF<<0)
 #define XSTORM_ETH_CONTEXT_SECTION_VLAN_ID_SHIFT 0
 #define XSTORM_ETH_CONTEXT_SECTION_CFI (0x1<<12)
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h
index 1517763..60deb84 100644
--- a/drivers/net/ethernet/broadcom/cnic_if.h
+++ b/drivers/net/ethernet/broadcom/cnic_if.h
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION	"2.5.8"
-#define CNIC_MODULE_RELDATE	"Jan 3, 2012"
+#define CNIC_MODULE_VERSION	"2.5.9"
+#define CNIC_MODULE_RELDATE	"Feb 8, 2012"
 
 #define CNIC_ULP_RDMA		0
 #define CNIC_ULP_ISCSI		1
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index 084904c..49e7a25 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -2623,8 +2623,6 @@ static int __devinit sbmac_probe(struct platform_device *pldev)
 	 */
 	dev = alloc_etherdev(sizeof(struct sbmac_softc));
 	if (!dev) {
-		printk(KERN_ERR "%s: unable to allocate etherdev\n",
-		       dev_name(&pldev->dev));
 		err = -ENOMEM;
 		goto out_unmap;
 	}
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index a1f2e0f..d604664 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
  * Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
  * Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2011 Broadcom Corporation.
+ * Copyright (C) 2005-2012 Broadcom Corporation.
  *
  * Firmware is:
  *	Derived from proprietary unpublished source code,
@@ -1453,33 +1453,23 @@ static void tg3_wait_for_event_ack(struct tg3 *tp)
 }
 
 /* tp->lock is held. */
-static void tg3_ump_link_report(struct tg3 *tp)
+static void tg3_phy_gather_ump_data(struct tg3 *tp, u32 *data)
 {
-	u32 reg;
-	u32 val;
-
-	if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF))
-		return;
-
-	tg3_wait_for_event_ack(tp);
-
-	tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
-
-	tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
+	u32 reg, val;
 
 	val = 0;
 	if (!tg3_readphy(tp, MII_BMCR, &reg))
 		val = reg << 16;
 	if (!tg3_readphy(tp, MII_BMSR, &reg))
 		val |= (reg & 0xffff);
-	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
+	*data++ = val;
 
 	val = 0;
 	if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
 		val = reg << 16;
 	if (!tg3_readphy(tp, MII_LPA, &reg))
 		val |= (reg & 0xffff);
-	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
+	*data++ = val;
 
 	val = 0;
 	if (!(tp->phy_flags & TG3_PHYFLG_MII_SERDES)) {
@@ -1488,13 +1478,33 @@ static void tg3_ump_link_report(struct tg3 *tp)
 		if (!tg3_readphy(tp, MII_STAT1000, &reg))
 			val |= (reg & 0xffff);
 	}
-	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
+	*data++ = val;
 
 	if (!tg3_readphy(tp, MII_PHYADDR, &reg))
 		val = reg << 16;
 	else
 		val = 0;
-	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
+	*data++ = val;
+}
+
+/* tp->lock is held. */
+static void tg3_ump_link_report(struct tg3 *tp)
+{
+	u32 data[4];
+
+	if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF))
+		return;
+
+	tg3_phy_gather_ump_data(tp, data);
+
+	tg3_wait_for_event_ack(tp);
+
+	tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
+	tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
+	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x0, data[0]);
+	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x4, data[1]);
+	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0x8, data[2]);
+	tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 0xc, data[3]);
 
 	tg3_generate_fw_event(tp);
 }
@@ -1809,8 +1819,8 @@ static void tg3_adjust_link(struct net_device *dev)
 		      (6 << TX_LENGTHS_IPG_SHIFT) |
 		      (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
 
-	if ((phydev->link && tp->link_config.active_speed == SPEED_INVALID) ||
-	    (!phydev->link && tp->link_config.active_speed != SPEED_INVALID) ||
+	if ((phydev->link && tp->link_config.active_speed == SPEED_UNKNOWN) ||
+	    (!phydev->link && tp->link_config.active_speed != SPEED_UNKNOWN) ||
 	    phydev->speed != tp->link_config.active_speed ||
 	    phydev->duplex != tp->link_config.active_duplex ||
 	    oldflowctrl != tp->link_config.active_flowctrl)
@@ -1884,10 +1894,10 @@ static void tg3_phy_start(struct tg3 *tp)
 
 	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
 		tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
-		phydev->speed = tp->link_config.orig_speed;
-		phydev->duplex = tp->link_config.orig_duplex;
-		phydev->autoneg = tp->link_config.orig_autoneg;
-		phydev->advertising = tp->link_config.orig_advertising;
+		phydev->speed = tp->link_config.speed;
+		phydev->duplex = tp->link_config.duplex;
+		phydev->autoneg = tp->link_config.autoneg;
+		phydev->advertising = tp->link_config.advertising;
 	}
 
 	phy_start(phydev);
@@ -2709,9 +2719,6 @@ static int tg3_5700_link_polarity(struct tg3 *tp, u32 speed)
 	return 0;
 }
 
-static int tg3_setup_phy(struct tg3 *, int);
-static int tg3_halt_cpu(struct tg3 *, u32);
-
 static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
 	u32 val;
@@ -2978,4190 +2985,4317 @@ static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
 	return res;
 }
 
-#define RX_CPU_SCRATCH_BASE	0x30000
-#define RX_CPU_SCRATCH_SIZE	0x04000
-#define TX_CPU_SCRATCH_BASE	0x34000
-#define TX_CPU_SCRATCH_SIZE	0x04000
-
-/* tp->lock is held. */
-static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
+static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
+				    u32 offset, u32 len, u8 *buf)
 {
-	int i;
+	int i, j, rc = 0;
+	u32 val;
 
-	BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS));
+	for (i = 0; i < len; i += 4) {
+		u32 addr;
+		__be32 data;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		u32 val = tr32(GRC_VCPU_EXT_CTRL);
+		addr = offset + i;
 
-		tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU);
-		return 0;
-	}
-	if (offset == RX_CPU_BASE) {
-		for (i = 0; i < 10000; i++) {
-			tw32(offset + CPU_STATE, 0xffffffff);
-			tw32(offset + CPU_MODE,  CPU_MODE_HALT);
-			if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
-				break;
-		}
+		memcpy(&data, buf + i, 4);
 
-		tw32(offset + CPU_STATE, 0xffffffff);
-		tw32_f(offset + CPU_MODE,  CPU_MODE_HALT);
-		udelay(10);
-	} else {
-		for (i = 0; i < 10000; i++) {
-			tw32(offset + CPU_STATE, 0xffffffff);
-			tw32(offset + CPU_MODE,  CPU_MODE_HALT);
-			if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
+		/*
+		 * The SEEPROM interface expects the data to always be opposite
+		 * the native endian format.  We accomplish this by reversing
+		 * all the operations that would have been performed on the
+		 * data from a call to tg3_nvram_read_be32().
+		 */
+		tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
+
+		val = tr32(GRC_EEPROM_ADDR);
+		tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
+
+		val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK |
+			EEPROM_ADDR_READ);
+		tw32(GRC_EEPROM_ADDR, val |
+			(0 << EEPROM_ADDR_DEVID_SHIFT) |
+			(addr & EEPROM_ADDR_ADDR_MASK) |
+			EEPROM_ADDR_START |
+			EEPROM_ADDR_WRITE);
+
+		for (j = 0; j < 1000; j++) {
+			val = tr32(GRC_EEPROM_ADDR);
+
+			if (val & EEPROM_ADDR_COMPLETE)
 				break;
+			msleep(1);
+		}
+		if (!(val & EEPROM_ADDR_COMPLETE)) {
+			rc = -EBUSY;
+			break;
 		}
 	}
 
-	if (i >= 10000) {
-		netdev_err(tp->dev, "%s timed out, %s CPU\n",
-			   __func__, offset == RX_CPU_BASE ? "RX" : "TX");
-		return -ENODEV;
-	}
-
-	/* Clear firmware's nvram arbitration. */
-	if (tg3_flag(tp, NVRAM))
-		tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
-	return 0;
+	return rc;
 }
 
-struct fw_info {
-	unsigned int fw_base;
-	unsigned int fw_len;
-	const __be32 *fw_data;
-};
-
-/* tp->lock is held. */
-static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base,
-				 u32 cpu_scratch_base, int cpu_scratch_size,
-				 struct fw_info *info)
+/* offset and length are dword aligned */
+static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
+		u8 *buf)
 {
-	int err, lock_err, i;
-	void (*write_op)(struct tg3 *, u32, u32);
+	int ret = 0;
+	u32 pagesize = tp->nvram_pagesize;
+	u32 pagemask = pagesize - 1;
+	u32 nvram_cmd;
+	u8 *tmp;
 
-	if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) {
-		netdev_err(tp->dev,
-			   "%s: Trying to load TX cpu firmware which is 5705\n",
-			   __func__);
-		return -EINVAL;
-	}
+	tmp = kmalloc(pagesize, GFP_KERNEL);
+	if (tmp == NULL)
+		return -ENOMEM;
 
-	if (tg3_flag(tp, 5705_PLUS))
-		write_op = tg3_write_mem;
-	else
-		write_op = tg3_write_indirect_reg32;
+	while (len) {
+		int j;
+		u32 phy_addr, page_off, size;
 
-	/* It is possible that bootcode is still loading at this point.
-	 * Get the nvram lock first before halting the cpu.
-	 */
-	lock_err = tg3_nvram_lock(tp);
-	err = tg3_halt_cpu(tp, cpu_base);
-	if (!lock_err)
-		tg3_nvram_unlock(tp);
-	if (err)
-		goto out;
+		phy_addr = offset & ~pagemask;
 
-	for (i = 0; i < cpu_scratch_size; i += sizeof(u32))
-		write_op(tp, cpu_scratch_base + i, 0);
-	tw32(cpu_base + CPU_STATE, 0xffffffff);
-	tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT);
-	for (i = 0; i < (info->fw_len / sizeof(u32)); i++)
-		write_op(tp, (cpu_scratch_base +
-			      (info->fw_base & 0xffff) +
-			      (i * sizeof(u32))),
-			      be32_to_cpu(info->fw_data[i]));
+		for (j = 0; j < pagesize; j += 4) {
+			ret = tg3_nvram_read_be32(tp, phy_addr + j,
+						  (__be32 *) (tmp + j));
+			if (ret)
+				break;
+		}
+		if (ret)
+			break;
 
-	err = 0;
+		page_off = offset & pagemask;
+		size = pagesize;
+		if (len < size)
+			size = len;
 
-out:
-	return err;
-}
+		len -= size;
 
-/* tp->lock is held. */
-static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
-{
-	struct fw_info info;
-	const __be32 *fw_data;
-	int err, i;
+		memcpy(tmp + page_off, buf, size);
 
-	fw_data = (void *)tp->fw->data;
+		offset = offset + (pagesize - page_off);
 
-	/* Firmware blob starts with version numbers, followed by
-	   start address and length. We are setting complete length.
-	   length = end_address_of_bss - start_address_of_text.
-	   Remainder is the blob to be loaded contiguously
-	   from start address. */
+		tg3_enable_nvram_access(tp);
 
-	info.fw_base = be32_to_cpu(fw_data[1]);
-	info.fw_len = tp->fw->size - 12;
-	info.fw_data = &fw_data[3];
+		/*
+		 * Before we can erase the flash page, we need
+		 * to issue a special "write enable" command.
+		 */
+		nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
 
-	err = tg3_load_firmware_cpu(tp, RX_CPU_BASE,
-				    RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE,
-				    &info);
-	if (err)
-		return err;
+		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+			break;
 
-	err = tg3_load_firmware_cpu(tp, TX_CPU_BASE,
-				    TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE,
-				    &info);
-	if (err)
-		return err;
+		/* Erase the target page */
+		tw32(NVRAM_ADDR, phy_addr);
 
-	/* Now startup only the RX cpu. */
-	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
-	tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
+		nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR |
+			NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE;
 
-	for (i = 0; i < 5; i++) {
-		if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base)
+		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
 			break;
-		tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
-		tw32(RX_CPU_BASE + CPU_MODE,  CPU_MODE_HALT);
-		tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
-		udelay(1000);
-	}
-	if (i >= 5) {
-		netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x "
-			   "should be %08x\n", __func__,
-			   tr32(RX_CPU_BASE + CPU_PC), info.fw_base);
-		return -ENODEV;
-	}
-	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
-	tw32_f(RX_CPU_BASE + CPU_MODE,  0x00000000);
 
-	return 0;
-}
+		/* Issue another write enable to start the write. */
+		nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
 
-/* tp->lock is held. */
-static int tg3_load_tso_firmware(struct tg3 *tp)
-{
-	struct fw_info info;
-	const __be32 *fw_data;
-	unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
-	int err, i;
+		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+			break;
 
-	if (tg3_flag(tp, HW_TSO_1) ||
-	    tg3_flag(tp, HW_TSO_2) ||
-	    tg3_flag(tp, HW_TSO_3))
-		return 0;
+		for (j = 0; j < pagesize; j += 4) {
+			__be32 data;
 
-	fw_data = (void *)tp->fw->data;
+			data = *((__be32 *) (tmp + j));
 
-	/* Firmware blob starts with version numbers, followed by
-	   start address and length. We are setting complete length.
-	   length = end_address_of_bss - start_address_of_text.
-	   Remainder is the blob to be loaded contiguously
-	   from start address. */
-
-	info.fw_base = be32_to_cpu(fw_data[1]);
-	cpu_scratch_size = tp->fw_len;
-	info.fw_len = tp->fw->size - 12;
-	info.fw_data = &fw_data[3];
+			tw32(NVRAM_WRDATA, be32_to_cpu(data));
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
-		cpu_base = RX_CPU_BASE;
-		cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705;
-	} else {
-		cpu_base = TX_CPU_BASE;
-		cpu_scratch_base = TX_CPU_SCRATCH_BASE;
-		cpu_scratch_size = TX_CPU_SCRATCH_SIZE;
-	}
+			tw32(NVRAM_ADDR, phy_addr + j);
 
-	err = tg3_load_firmware_cpu(tp, cpu_base,
-				    cpu_scratch_base, cpu_scratch_size,
-				    &info);
-	if (err)
-		return err;
+			nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE |
+				NVRAM_CMD_WR;
 
-	/* Now startup the cpu. */
-	tw32(cpu_base + CPU_STATE, 0xffffffff);
-	tw32_f(cpu_base + CPU_PC, info.fw_base);
+			if (j == 0)
+				nvram_cmd |= NVRAM_CMD_FIRST;
+			else if (j == (pagesize - 4))
+				nvram_cmd |= NVRAM_CMD_LAST;
 
-	for (i = 0; i < 5; i++) {
-		if (tr32(cpu_base + CPU_PC) == info.fw_base)
+			ret = tg3_nvram_exec_cmd(tp, nvram_cmd);
+			if (ret)
+				break;
+		}
+		if (ret)
 			break;
-		tw32(cpu_base + CPU_STATE, 0xffffffff);
-		tw32(cpu_base + CPU_MODE,  CPU_MODE_HALT);
-		tw32_f(cpu_base + CPU_PC, info.fw_base);
-		udelay(1000);
-	}
-	if (i >= 5) {
-		netdev_err(tp->dev,
-			   "%s fails to set CPU PC, is %08x should be %08x\n",
-			   __func__, tr32(cpu_base + CPU_PC), info.fw_base);
-		return -ENODEV;
-	}
-	tw32(cpu_base + CPU_STATE, 0xffffffff);
-	tw32_f(cpu_base + CPU_MODE,  0x00000000);
-	return 0;
-}
-
-
-/* tp->lock is held. */
-static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
-{
-	u32 addr_high, addr_low;
-	int i;
-
-	addr_high = ((tp->dev->dev_addr[0] << 8) |
-		     tp->dev->dev_addr[1]);
-	addr_low = ((tp->dev->dev_addr[2] << 24) |
-		    (tp->dev->dev_addr[3] << 16) |
-		    (tp->dev->dev_addr[4] <<  8) |
-		    (tp->dev->dev_addr[5] <<  0));
-	for (i = 0; i < 4; i++) {
-		if (i == 1 && skip_mac_1)
-			continue;
-		tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
-		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
-		for (i = 0; i < 12; i++) {
-			tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
-			tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
-		}
-	}
+	nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE;
+	tg3_nvram_exec_cmd(tp, nvram_cmd);
 
-	addr_high = (tp->dev->dev_addr[0] +
-		     tp->dev->dev_addr[1] +
-		     tp->dev->dev_addr[2] +
-		     tp->dev->dev_addr[3] +
-		     tp->dev->dev_addr[4] +
-		     tp->dev->dev_addr[5]) &
-		TX_BACKOFF_SEED_MASK;
-	tw32(MAC_TX_BACKOFF_SEED, addr_high);
-}
+	kfree(tmp);
 
-static void tg3_enable_register_access(struct tg3 *tp)
-{
-	/*
-	 * Make sure register accesses (indirect or otherwise) will function
-	 * correctly.
-	 */
-	pci_write_config_dword(tp->pdev,
-			       TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+	return ret;
 }
 
-static int tg3_power_up(struct tg3 *tp)
+/* offset and length are dword aligned */
+static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
+		u8 *buf)
 {
-	int err;
+	int i, ret = 0;
 
-	tg3_enable_register_access(tp);
+	for (i = 0; i < len; i += 4, offset += 4) {
+		u32 page_off, phy_addr, nvram_cmd;
+		__be32 data;
 
-	err = pci_set_power_state(tp->pdev, PCI_D0);
-	if (!err) {
-		/* Switch out of Vaux if it is a NIC */
-		tg3_pwrsrc_switch_to_vmain(tp);
-	} else {
-		netdev_err(tp->dev, "Transition to D0 failed\n");
-	}
+		memcpy(&data, buf + i, 4);
+		tw32(NVRAM_WRDATA, be32_to_cpu(data));
 
-	return err;
-}
+		page_off = offset % tp->nvram_pagesize;
 
-static int tg3_power_down_prepare(struct tg3 *tp)
-{
-	u32 misc_host_ctrl;
-	bool device_should_wake, do_low_power;
+		phy_addr = tg3_nvram_phys_addr(tp, offset);
 
-	tg3_enable_register_access(tp);
+		nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR;
 
-	/* Restore the CLKREQ setting. */
-	if (tg3_flag(tp, CLKREQ_BUG)) {
-		u16 lnkctl;
+		if (page_off == 0 || i == 0)
+			nvram_cmd |= NVRAM_CMD_FIRST;
+		if (page_off == (tp->nvram_pagesize - 4))
+			nvram_cmd |= NVRAM_CMD_LAST;
 
-		pci_read_config_word(tp->pdev,
-				     pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
-				     &lnkctl);
-		lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
-		pci_write_config_word(tp->pdev,
-				      pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
-				      lnkctl);
-	}
+		if (i == (len - 4))
+			nvram_cmd |= NVRAM_CMD_LAST;
 
-	misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
-	tw32(TG3PCI_MISC_HOST_CTRL,
-	     misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
+		if ((nvram_cmd & NVRAM_CMD_FIRST) ||
+		    !tg3_flag(tp, FLASH) ||
+		    !tg3_flag(tp, 57765_PLUS))
+			tw32(NVRAM_ADDR, phy_addr);
 
-	device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
-			     tg3_flag(tp, WOL_ENABLE);
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
+		    !tg3_flag(tp, 5755_PLUS) &&
+		    (tp->nvram_jedecnum == JEDEC_ST) &&
+		    (nvram_cmd & NVRAM_CMD_FIRST)) {
+			u32 cmd;
 
-	if (tg3_flag(tp, USE_PHYLIB)) {
-		do_low_power = false;
-		if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) &&
-		    !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
-			struct phy_device *phydev;
-			u32 phyid, advertising;
+			cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
+			ret = tg3_nvram_exec_cmd(tp, cmd);
+			if (ret)
+				break;
+		}
+		if (!tg3_flag(tp, FLASH)) {
+			/* We always do complete word writes to eeprom. */
+			nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
+		}
 
-			phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+		ret = tg3_nvram_exec_cmd(tp, nvram_cmd);
+		if (ret)
+			break;
+	}
+	return ret;
+}
 
-			tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
+/* offset and length are dword aligned */
+static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
+{
+	int ret;
 
-			tp->link_config.orig_speed = phydev->speed;
-			tp->link_config.orig_duplex = phydev->duplex;
-			tp->link_config.orig_autoneg = phydev->autoneg;
-			tp->link_config.orig_advertising = phydev->advertising;
+	if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
+		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
+		       ~GRC_LCLCTRL_GPIO_OUTPUT1);
+		udelay(40);
+	}
 
-			advertising = ADVERTISED_TP |
-				      ADVERTISED_Pause |
-				      ADVERTISED_Autoneg |
-				      ADVERTISED_10baseT_Half;
+	if (!tg3_flag(tp, NVRAM)) {
+		ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
+	} else {
+		u32 grc_mode;
 
-			if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) {
-				if (tg3_flag(tp, WOL_SPEED_100MB))
-					advertising |=
-						ADVERTISED_100baseT_Half |
-						ADVERTISED_100baseT_Full |
-						ADVERTISED_10baseT_Full;
-				else
-					advertising |= ADVERTISED_10baseT_Full;
-			}
+		ret = tg3_nvram_lock(tp);
+		if (ret)
+			return ret;
 
-			phydev->advertising = advertising;
+		tg3_enable_nvram_access(tp);
+		if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM))
+			tw32(NVRAM_WRITE1, 0x406);
 
-			phy_start_aneg(phydev);
+		grc_mode = tr32(GRC_MODE);
+		tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
 
-			phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
-			if (phyid != PHY_ID_BCMAC131) {
-				phyid &= PHY_BCM_OUI_MASK;
-				if (phyid == PHY_BCM_OUI_1 ||
-				    phyid == PHY_BCM_OUI_2 ||
-				    phyid == PHY_BCM_OUI_3)
-					do_low_power = true;
-			}
+		if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) {
+			ret = tg3_nvram_write_block_buffered(tp, offset, len,
+				buf);
+		} else {
+			ret = tg3_nvram_write_block_unbuffered(tp, offset, len,
+				buf);
 		}
-	} else {
-		do_low_power = true;
 
-		if (!(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
-			tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
-			tp->link_config.orig_speed = tp->link_config.speed;
-			tp->link_config.orig_duplex = tp->link_config.duplex;
-			tp->link_config.orig_autoneg = tp->link_config.autoneg;
-		}
+		grc_mode = tr32(GRC_MODE);
+		tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE);
 
-		if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES)) {
-			tp->link_config.speed = SPEED_10;
-			tp->link_config.duplex = DUPLEX_HALF;
-			tp->link_config.autoneg = AUTONEG_ENABLE;
-			tg3_setup_phy(tp, 0);
-		}
+		tg3_disable_nvram_access(tp);
+		tg3_nvram_unlock(tp);
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		u32 val;
+	if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
+		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+		udelay(40);
+	}
 
-		val = tr32(GRC_VCPU_EXT_CTRL);
-		tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL);
-	} else if (!tg3_flag(tp, ENABLE_ASF)) {
-		int i;
-		u32 val;
+	return ret;
+}
 
-		for (i = 0; i < 200; i++) {
-			tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val);
-			if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
-				break;
-			msleep(1);
-		}
-	}
-	if (tg3_flag(tp, WOL_CAP))
-		tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
-						     WOL_DRV_STATE_SHUTDOWN |
-						     WOL_DRV_WOL |
-						     WOL_SET_MAGIC_PKT);
+#define RX_CPU_SCRATCH_BASE	0x30000
+#define RX_CPU_SCRATCH_SIZE	0x04000
+#define TX_CPU_SCRATCH_BASE	0x34000
+#define TX_CPU_SCRATCH_SIZE	0x04000
 
-	if (device_should_wake) {
-		u32 mac_mode;
+/* tp->lock is held. */
+static int tg3_halt_cpu(struct tg3 *tp, u32 offset)
+{
+	int i;
 
-		if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
-			if (do_low_power &&
-			    !(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
-				tg3_phy_auxctl_write(tp,
-					       MII_TG3_AUXCTL_SHDWSEL_PWRCTL,
-					       MII_TG3_AUXCTL_PCTL_WOL_EN |
-					       MII_TG3_AUXCTL_PCTL_100TX_LPWR |
-					       MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC);
-				udelay(40);
-			}
+	BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS));
 
-			if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
-				mac_mode = MAC_MODE_PORT_MODE_GMII;
-			else
-				mac_mode = MAC_MODE_PORT_MODE_MII;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		u32 val = tr32(GRC_VCPU_EXT_CTRL);
 
-			mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY;
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
-			    ASIC_REV_5700) {
-				u32 speed = tg3_flag(tp, WOL_SPEED_100MB) ?
-					     SPEED_100 : SPEED_10;
-				if (tg3_5700_link_polarity(tp, speed))
-					mac_mode |= MAC_MODE_LINK_POLARITY;
-				else
-					mac_mode &= ~MAC_MODE_LINK_POLARITY;
-			}
-		} else {
-			mac_mode = MAC_MODE_PORT_MODE_TBI;
+		tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_HALT_CPU);
+		return 0;
+	}
+	if (offset == RX_CPU_BASE) {
+		for (i = 0; i < 10000; i++) {
+			tw32(offset + CPU_STATE, 0xffffffff);
+			tw32(offset + CPU_MODE,  CPU_MODE_HALT);
+			if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
+				break;
 		}
 
-		if (!tg3_flag(tp, 5750_PLUS))
-			tw32(MAC_LED_CTRL, tp->led_ctrl);
+		tw32(offset + CPU_STATE, 0xffffffff);
+		tw32_f(offset + CPU_MODE,  CPU_MODE_HALT);
+		udelay(10);
+	} else {
+		for (i = 0; i < 10000; i++) {
+			tw32(offset + CPU_STATE, 0xffffffff);
+			tw32(offset + CPU_MODE,  CPU_MODE_HALT);
+			if (tr32(offset + CPU_MODE) & CPU_MODE_HALT)
+				break;
+		}
+	}
 
-		mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
-		if ((tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS)) &&
-		    (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)))
-			mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
+	if (i >= 10000) {
+		netdev_err(tp->dev, "%s timed out, %s CPU\n",
+			   __func__, offset == RX_CPU_BASE ? "RX" : "TX");
+		return -ENODEV;
+	}
 
-		if (tg3_flag(tp, ENABLE_APE))
-			mac_mode |= MAC_MODE_APE_TX_EN |
-				    MAC_MODE_APE_RX_EN |
-				    MAC_MODE_TDE_ENABLE;
+	/* Clear firmware's nvram arbitration. */
+	if (tg3_flag(tp, NVRAM))
+		tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
+	return 0;
+}
 
-		tw32_f(MAC_MODE, mac_mode);
-		udelay(100);
+struct fw_info {
+	unsigned int fw_base;
+	unsigned int fw_len;
+	const __be32 *fw_data;
+};
 
-		tw32_f(MAC_RX_MODE, RX_MODE_ENABLE);
-		udelay(10);
-	}
+/* tp->lock is held. */
+static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base,
+				 u32 cpu_scratch_base, int cpu_scratch_size,
+				 struct fw_info *info)
+{
+	int err, lock_err, i;
+	void (*write_op)(struct tg3 *, u32, u32);
 
-	if (!tg3_flag(tp, WOL_SPEED_100MB) &&
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
-		u32 base_val;
+	if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) {
+		netdev_err(tp->dev,
+			   "%s: Trying to load TX cpu firmware which is 5705\n",
+			   __func__);
+		return -EINVAL;
+	}
 
-		base_val = tp->pci_clock_ctrl;
-		base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
-			     CLOCK_CTRL_TXCLK_DISABLE);
+	if (tg3_flag(tp, 5705_PLUS))
+		write_op = tg3_write_mem;
+	else
+		write_op = tg3_write_indirect_reg32;
 
-		tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
-			    CLOCK_CTRL_PWRDOWN_PLL133, 40);
-	} else if (tg3_flag(tp, 5780_CLASS) ||
-		   tg3_flag(tp, CPMU_PRESENT) ||
-		   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		/* do nothing */
-	} else if (!(tg3_flag(tp, 5750_PLUS) && tg3_flag(tp, ENABLE_ASF))) {
-		u32 newbits1, newbits2;
+	/* It is possible that bootcode is still loading at this point.
+	 * Get the nvram lock first before halting the cpu.
+	 */
+	lock_err = tg3_nvram_lock(tp);
+	err = tg3_halt_cpu(tp, cpu_base);
+	if (!lock_err)
+		tg3_nvram_unlock(tp);
+	if (err)
+		goto out;
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
-			newbits1 = (CLOCK_CTRL_RXCLK_DISABLE |
-				    CLOCK_CTRL_TXCLK_DISABLE |
-				    CLOCK_CTRL_ALTCLK);
-			newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
-		} else if (tg3_flag(tp, 5705_PLUS)) {
-			newbits1 = CLOCK_CTRL_625_CORE;
-			newbits2 = newbits1 | CLOCK_CTRL_ALTCLK;
-		} else {
-			newbits1 = CLOCK_CTRL_ALTCLK;
-			newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
-		}
+	for (i = 0; i < cpu_scratch_size; i += sizeof(u32))
+		write_op(tp, cpu_scratch_base + i, 0);
+	tw32(cpu_base + CPU_STATE, 0xffffffff);
+	tw32(cpu_base + CPU_MODE, tr32(cpu_base+CPU_MODE)|CPU_MODE_HALT);
+	for (i = 0; i < (info->fw_len / sizeof(u32)); i++)
+		write_op(tp, (cpu_scratch_base +
+			      (info->fw_base & 0xffff) +
+			      (i * sizeof(u32))),
+			      be32_to_cpu(info->fw_data[i]));
 
-		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
-			    40);
+	err = 0;
 
-		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
-			    40);
+out:
+	return err;
+}
 
-		if (!tg3_flag(tp, 5705_PLUS)) {
-			u32 newbits3;
+/* tp->lock is held. */
+static int tg3_load_5701_a0_firmware_fix(struct tg3 *tp)
+{
+	struct fw_info info;
+	const __be32 *fw_data;
+	int err, i;
 
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
-				newbits3 = (CLOCK_CTRL_RXCLK_DISABLE |
-					    CLOCK_CTRL_TXCLK_DISABLE |
-					    CLOCK_CTRL_44MHZ_CORE);
-			} else {
-				newbits3 = CLOCK_CTRL_44MHZ_CORE;
-			}
+	fw_data = (void *)tp->fw->data;
 
-			tw32_wait_f(TG3PCI_CLOCK_CTRL,
-				    tp->pci_clock_ctrl | newbits3, 40);
-		}
-	}
+	/* Firmware blob starts with version numbers, followed by
+	   start address and length. We are setting complete length.
+	   length = end_address_of_bss - start_address_of_text.
+	   Remainder is the blob to be loaded contiguously
+	   from start address. */
 
-	if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF))
-		tg3_power_down_phy(tp, do_low_power);
+	info.fw_base = be32_to_cpu(fw_data[1]);
+	info.fw_len = tp->fw->size - 12;
+	info.fw_data = &fw_data[3];
 
-	tg3_frob_aux_power(tp, true);
+	err = tg3_load_firmware_cpu(tp, RX_CPU_BASE,
+				    RX_CPU_SCRATCH_BASE, RX_CPU_SCRATCH_SIZE,
+				    &info);
+	if (err)
+		return err;
 
-	/* Workaround for unstable PLL clock */
-	if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
-	    (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) {
-		u32 val = tr32(0x7d00);
+	err = tg3_load_firmware_cpu(tp, TX_CPU_BASE,
+				    TX_CPU_SCRATCH_BASE, TX_CPU_SCRATCH_SIZE,
+				    &info);
+	if (err)
+		return err;
 
-		val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
-		tw32(0x7d00, val);
-		if (!tg3_flag(tp, ENABLE_ASF)) {
-			int err;
+	/* Now startup only the RX cpu. */
+	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
+	tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
 
-			err = tg3_nvram_lock(tp);
-			tg3_halt_cpu(tp, RX_CPU_BASE);
-			if (!err)
-				tg3_nvram_unlock(tp);
-		}
+	for (i = 0; i < 5; i++) {
+		if (tr32(RX_CPU_BASE + CPU_PC) == info.fw_base)
+			break;
+		tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
+		tw32(RX_CPU_BASE + CPU_MODE,  CPU_MODE_HALT);
+		tw32_f(RX_CPU_BASE + CPU_PC, info.fw_base);
+		udelay(1000);
 	}
-
-	tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
+	if (i >= 5) {
+		netdev_err(tp->dev, "%s fails to set RX CPU PC, is %08x "
+			   "should be %08x\n", __func__,
+			   tr32(RX_CPU_BASE + CPU_PC), info.fw_base);
+		return -ENODEV;
+	}
+	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
+	tw32_f(RX_CPU_BASE + CPU_MODE,  0x00000000);
 
 	return 0;
 }
 
-static void tg3_power_down(struct tg3 *tp)
+/* tp->lock is held. */
+static int tg3_load_tso_firmware(struct tg3 *tp)
 {
-	tg3_power_down_prepare(tp);
-
-	pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
-	pci_set_power_state(tp->pdev, PCI_D3hot);
-}
+	struct fw_info info;
+	const __be32 *fw_data;
+	unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
+	int err, i;
 
-static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
-{
-	switch (val & MII_TG3_AUX_STAT_SPDMASK) {
-	case MII_TG3_AUX_STAT_10HALF:
-		*speed = SPEED_10;
-		*duplex = DUPLEX_HALF;
-		break;
+	if (tg3_flag(tp, HW_TSO_1) ||
+	    tg3_flag(tp, HW_TSO_2) ||
+	    tg3_flag(tp, HW_TSO_3))
+		return 0;
 
-	case MII_TG3_AUX_STAT_10FULL:
-		*speed = SPEED_10;
-		*duplex = DUPLEX_FULL;
-		break;
+	fw_data = (void *)tp->fw->data;
 
-	case MII_TG3_AUX_STAT_100HALF:
-		*speed = SPEED_100;
-		*duplex = DUPLEX_HALF;
-		break;
+	/* Firmware blob starts with version numbers, followed by
+	   start address and length. We are setting complete length.
+	   length = end_address_of_bss - start_address_of_text.
+	   Remainder is the blob to be loaded contiguously
+	   from start address. */
 
-	case MII_TG3_AUX_STAT_100FULL:
-		*speed = SPEED_100;
-		*duplex = DUPLEX_FULL;
-		break;
+	info.fw_base = be32_to_cpu(fw_data[1]);
+	cpu_scratch_size = tp->fw_len;
+	info.fw_len = tp->fw->size - 12;
+	info.fw_data = &fw_data[3];
 
-	case MII_TG3_AUX_STAT_1000HALF:
-		*speed = SPEED_1000;
-		*duplex = DUPLEX_HALF;
-		break;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+		cpu_base = RX_CPU_BASE;
+		cpu_scratch_base = NIC_SRAM_MBUF_POOL_BASE5705;
+	} else {
+		cpu_base = TX_CPU_BASE;
+		cpu_scratch_base = TX_CPU_SCRATCH_BASE;
+		cpu_scratch_size = TX_CPU_SCRATCH_SIZE;
+	}
 
-	case MII_TG3_AUX_STAT_1000FULL:
-		*speed = SPEED_1000;
-		*duplex = DUPLEX_FULL;
-		break;
+	err = tg3_load_firmware_cpu(tp, cpu_base,
+				    cpu_scratch_base, cpu_scratch_size,
+				    &info);
+	if (err)
+		return err;
 
-	default:
-		if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
-			*speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
-				 SPEED_10;
-			*duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
-				  DUPLEX_HALF;
+	/* Now startup the cpu. */
+	tw32(cpu_base + CPU_STATE, 0xffffffff);
+	tw32_f(cpu_base + CPU_PC, info.fw_base);
+
+	for (i = 0; i < 5; i++) {
+		if (tr32(cpu_base + CPU_PC) == info.fw_base)
 			break;
-		}
-		*speed = SPEED_INVALID;
-		*duplex = DUPLEX_INVALID;
-		break;
+		tw32(cpu_base + CPU_STATE, 0xffffffff);
+		tw32(cpu_base + CPU_MODE,  CPU_MODE_HALT);
+		tw32_f(cpu_base + CPU_PC, info.fw_base);
+		udelay(1000);
+	}
+	if (i >= 5) {
+		netdev_err(tp->dev,
+			   "%s fails to set CPU PC, is %08x should be %08x\n",
+			   __func__, tr32(cpu_base + CPU_PC), info.fw_base);
+		return -ENODEV;
 	}
+	tw32(cpu_base + CPU_STATE, 0xffffffff);
+	tw32_f(cpu_base + CPU_MODE,  0x00000000);
+	return 0;
 }
 
-static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
-{
-	int err = 0;
-	u32 val, new_adv;
-
-	new_adv = ADVERTISE_CSMA;
-	new_adv |= ethtool_adv_to_mii_adv_t(advertise) & ADVERTISE_ALL;
-	new_adv |= mii_advertise_flowctrl(flowctrl);
-
-	err = tg3_writephy(tp, MII_ADVERTISE, new_adv);
-	if (err)
-		goto done;
-
-	if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
-		new_adv = ethtool_adv_to_mii_ctrl1000_t(advertise);
 
-		if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
-		    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
-			new_adv |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
+/* tp->lock is held. */
+static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
+{
+	u32 addr_high, addr_low;
+	int i;
 
-		err = tg3_writephy(tp, MII_CTRL1000, new_adv);
-		if (err)
-			goto done;
+	addr_high = ((tp->dev->dev_addr[0] << 8) |
+		     tp->dev->dev_addr[1]);
+	addr_low = ((tp->dev->dev_addr[2] << 24) |
+		    (tp->dev->dev_addr[3] << 16) |
+		    (tp->dev->dev_addr[4] <<  8) |
+		    (tp->dev->dev_addr[5] <<  0));
+	for (i = 0; i < 4; i++) {
+		if (i == 1 && skip_mac_1)
+			continue;
+		tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
+		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
 	}
 
-	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
-		goto done;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+		for (i = 0; i < 12; i++) {
+			tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
+			tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
+		}
+	}
 
-	tw32(TG3_CPMU_EEE_MODE,
-	     tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
+	addr_high = (tp->dev->dev_addr[0] +
+		     tp->dev->dev_addr[1] +
+		     tp->dev->dev_addr[2] +
+		     tp->dev->dev_addr[3] +
+		     tp->dev->dev_addr[4] +
+		     tp->dev->dev_addr[5]) &
+		TX_BACKOFF_SEED_MASK;
+	tw32(MAC_TX_BACKOFF_SEED, addr_high);
+}
 
-	err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
-	if (!err) {
-		u32 err2;
+static void tg3_enable_register_access(struct tg3 *tp)
+{
+	/*
+	 * Make sure register accesses (indirect or otherwise) will function
+	 * correctly.
+	 */
+	pci_write_config_dword(tp->pdev,
+			       TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+}
 
-		val = 0;
-		/* Advertise 100-BaseTX EEE ability */
-		if (advertise & ADVERTISED_100baseT_Full)
-			val |= MDIO_AN_EEE_ADV_100TX;
-		/* Advertise 1000-BaseT EEE ability */
-		if (advertise & ADVERTISED_1000baseT_Full)
-			val |= MDIO_AN_EEE_ADV_1000T;
-		err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
-		if (err)
-			val = 0;
+static int tg3_power_up(struct tg3 *tp)
+{
+	int err;
 
-		switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
-		case ASIC_REV_5717:
-		case ASIC_REV_57765:
-		case ASIC_REV_57766:
-		case ASIC_REV_5719:
-			/* If we advertised any eee advertisements above... */
-			if (val)
-				val = MII_TG3_DSP_TAP26_ALNOKO |
-				      MII_TG3_DSP_TAP26_RMRXSTO |
-				      MII_TG3_DSP_TAP26_OPCSINPT;
-			tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
-			/* Fall through */
-		case ASIC_REV_5720:
-			if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
-				tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
-						 MII_TG3_DSP_CH34TP2_HIBW01);
-		}
+	tg3_enable_register_access(tp);
 
-		err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
-		if (!err)
-			err = err2;
+	err = pci_set_power_state(tp->pdev, PCI_D0);
+	if (!err) {
+		/* Switch out of Vaux if it is a NIC */
+		tg3_pwrsrc_switch_to_vmain(tp);
+	} else {
+		netdev_err(tp->dev, "Transition to D0 failed\n");
 	}
 
-done:
 	return err;
 }
 
-static void tg3_phy_copper_begin(struct tg3 *tp)
-{
-	u32 new_adv;
-	int i;
+static int tg3_setup_phy(struct tg3 *, int);
 
-	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
-		new_adv = ADVERTISED_10baseT_Half |
-			  ADVERTISED_10baseT_Full;
-		if (tg3_flag(tp, WOL_SPEED_100MB))
-			new_adv |= ADVERTISED_100baseT_Half |
-				   ADVERTISED_100baseT_Full;
+static int tg3_power_down_prepare(struct tg3 *tp)
+{
+	u32 misc_host_ctrl;
+	bool device_should_wake, do_low_power;
 
-		tg3_phy_autoneg_cfg(tp, new_adv,
-				    FLOW_CTRL_TX | FLOW_CTRL_RX);
-	} else if (tp->link_config.speed == SPEED_INVALID) {
-		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
-			tp->link_config.advertising &=
-				~(ADVERTISED_1000baseT_Half |
-				  ADVERTISED_1000baseT_Full);
+	tg3_enable_register_access(tp);
 
-		tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
-				    tp->link_config.flowctrl);
-	} else {
-		/* Asking for a specific link mode. */
-		if (tp->link_config.speed == SPEED_1000) {
-			if (tp->link_config.duplex == DUPLEX_FULL)
-				new_adv = ADVERTISED_1000baseT_Full;
-			else
-				new_adv = ADVERTISED_1000baseT_Half;
-		} else if (tp->link_config.speed == SPEED_100) {
-			if (tp->link_config.duplex == DUPLEX_FULL)
-				new_adv = ADVERTISED_100baseT_Full;
-			else
-				new_adv = ADVERTISED_100baseT_Half;
-		} else {
-			if (tp->link_config.duplex == DUPLEX_FULL)
-				new_adv = ADVERTISED_10baseT_Full;
-			else
-				new_adv = ADVERTISED_10baseT_Half;
-		}
+	/* Restore the CLKREQ setting. */
+	if (tg3_flag(tp, CLKREQ_BUG)) {
+		u16 lnkctl;
 
-		tg3_phy_autoneg_cfg(tp, new_adv,
-				    tp->link_config.flowctrl);
+		pci_read_config_word(tp->pdev,
+				     pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
+				     &lnkctl);
+		lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
+		pci_write_config_word(tp->pdev,
+				      pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
+				      lnkctl);
 	}
 
-	if (tp->link_config.autoneg == AUTONEG_DISABLE &&
-	    tp->link_config.speed != SPEED_INVALID) {
-		u32 bmcr, orig_bmcr;
+	misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
 
-		tp->link_config.active_speed = tp->link_config.speed;
-		tp->link_config.active_duplex = tp->link_config.duplex;
+	device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
+			     tg3_flag(tp, WOL_ENABLE);
 
-		bmcr = 0;
-		switch (tp->link_config.speed) {
-		default:
-		case SPEED_10:
-			break;
+	if (tg3_flag(tp, USE_PHYLIB)) {
+		do_low_power = false;
+		if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) &&
+		    !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
+			struct phy_device *phydev;
+			u32 phyid, advertising;
 
-		case SPEED_100:
-			bmcr |= BMCR_SPEED100;
-			break;
+			phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
-		case SPEED_1000:
-			bmcr |= BMCR_SPEED1000;
-			break;
-		}
+			tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
 
-		if (tp->link_config.duplex == DUPLEX_FULL)
-			bmcr |= BMCR_FULLDPLX;
+			tp->link_config.speed = phydev->speed;
+			tp->link_config.duplex = phydev->duplex;
+			tp->link_config.autoneg = phydev->autoneg;
+			tp->link_config.advertising = phydev->advertising;
 
-		if (!tg3_readphy(tp, MII_BMCR, &orig_bmcr) &&
-		    (bmcr != orig_bmcr)) {
-			tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK);
-			for (i = 0; i < 1500; i++) {
-				u32 tmp;
+			advertising = ADVERTISED_TP |
+				      ADVERTISED_Pause |
+				      ADVERTISED_Autoneg |
+				      ADVERTISED_10baseT_Half;
 
-				udelay(10);
-				if (tg3_readphy(tp, MII_BMSR, &tmp) ||
-				    tg3_readphy(tp, MII_BMSR, &tmp))
-					continue;
-				if (!(tmp & BMSR_LSTATUS)) {
-					udelay(40);
-					break;
-				}
+			if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) {
+				if (tg3_flag(tp, WOL_SPEED_100MB))
+					advertising |=
+						ADVERTISED_100baseT_Half |
+						ADVERTISED_100baseT_Full |
+						ADVERTISED_10baseT_Full;
+				else
+					advertising |= ADVERTISED_10baseT_Full;
 			}
-			tg3_writephy(tp, MII_BMCR, bmcr);
-			udelay(40);
-		}
-	} else {
-		tg3_writephy(tp, MII_BMCR,
-			     BMCR_ANENABLE | BMCR_ANRESTART);
-	}
-}
 
-static int tg3_init_5401phy_dsp(struct tg3 *tp)
-{
-	int err;
+			phydev->advertising = advertising;
 
-	/* Turn off tap power management. */
-	/* Set Extended packet length bit */
-	err = tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20);
+			phy_start_aneg(phydev);
 
-	err |= tg3_phydsp_write(tp, 0x0012, 0x1804);
-	err |= tg3_phydsp_write(tp, 0x0013, 0x1204);
-	err |= tg3_phydsp_write(tp, 0x8006, 0x0132);
-	err |= tg3_phydsp_write(tp, 0x8006, 0x0232);
-	err |= tg3_phydsp_write(tp, 0x201f, 0x0a20);
+			phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
+			if (phyid != PHY_ID_BCMAC131) {
+				phyid &= PHY_BCM_OUI_MASK;
+				if (phyid == PHY_BCM_OUI_1 ||
+				    phyid == PHY_BCM_OUI_2 ||
+				    phyid == PHY_BCM_OUI_3)
+					do_low_power = true;
+			}
+		}
+	} else {
+		do_low_power = true;
 
-	udelay(40);
+		if (!(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER))
+			tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
 
-	return err;
-}
+		if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
+			tg3_setup_phy(tp, 0);
+	}
 
-static bool tg3_phy_copper_an_config_ok(struct tg3 *tp, u32 *lcladv)
-{
-	u32 advmsk, tgtadv, advertising;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		u32 val;
 
-	advertising = tp->link_config.advertising;
-	tgtadv = ethtool_adv_to_mii_adv_t(advertising) & ADVERTISE_ALL;
+		val = tr32(GRC_VCPU_EXT_CTRL);
+		tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL);
+	} else if (!tg3_flag(tp, ENABLE_ASF)) {
+		int i;
+		u32 val;
 
-	advmsk = ADVERTISE_ALL;
-	if (tp->link_config.active_duplex == DUPLEX_FULL) {
-		tgtadv |= mii_advertise_flowctrl(tp->link_config.flowctrl);
-		advmsk |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+		for (i = 0; i < 200; i++) {
+			tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val);
+			if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+				break;
+			msleep(1);
+		}
 	}
+	if (tg3_flag(tp, WOL_CAP))
+		tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
+						     WOL_DRV_STATE_SHUTDOWN |
+						     WOL_DRV_WOL |
+						     WOL_SET_MAGIC_PKT);
 
-	if (tg3_readphy(tp, MII_ADVERTISE, lcladv))
-		return false;
+	if (device_should_wake) {
+		u32 mac_mode;
 
-	if ((*lcladv & advmsk) != tgtadv)
-		return false;
+		if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
+			if (do_low_power &&
+			    !(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
+				tg3_phy_auxctl_write(tp,
+					       MII_TG3_AUXCTL_SHDWSEL_PWRCTL,
+					       MII_TG3_AUXCTL_PCTL_WOL_EN |
+					       MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+					       MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC);
+				udelay(40);
+			}
 
-	if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
-		u32 tg3_ctrl;
+			if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
+				mac_mode = MAC_MODE_PORT_MODE_GMII;
+			else
+				mac_mode = MAC_MODE_PORT_MODE_MII;
 
-		tgtadv = ethtool_adv_to_mii_ctrl1000_t(advertising);
+			mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY;
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5700) {
+				u32 speed = tg3_flag(tp, WOL_SPEED_100MB) ?
+					     SPEED_100 : SPEED_10;
+				if (tg3_5700_link_polarity(tp, speed))
+					mac_mode |= MAC_MODE_LINK_POLARITY;
+				else
+					mac_mode &= ~MAC_MODE_LINK_POLARITY;
+			}
+		} else {
+			mac_mode = MAC_MODE_PORT_MODE_TBI;
+		}
 
-		if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl))
-			return false;
+		if (!tg3_flag(tp, 5750_PLUS))
+			tw32(MAC_LED_CTRL, tp->led_ctrl);
 
-		tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL);
-		if (tg3_ctrl != tgtadv)
-			return false;
-	}
+		mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+		if ((tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS)) &&
+		    (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)))
+			mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
 
-	return true;
-}
+		if (tg3_flag(tp, ENABLE_APE))
+			mac_mode |= MAC_MODE_APE_TX_EN |
+				    MAC_MODE_APE_RX_EN |
+				    MAC_MODE_TDE_ENABLE;
 
-static bool tg3_phy_copper_fetch_rmtadv(struct tg3 *tp, u32 *rmtadv)
-{
-	u32 lpeth = 0;
+		tw32_f(MAC_MODE, mac_mode);
+		udelay(100);
 
-	if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
-		u32 val;
+		tw32_f(MAC_RX_MODE, RX_MODE_ENABLE);
+		udelay(10);
+	}
 
-		if (tg3_readphy(tp, MII_STAT1000, &val))
-			return false;
+	if (!tg3_flag(tp, WOL_SPEED_100MB) &&
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
+		u32 base_val;
 
-		lpeth = mii_stat1000_to_ethtool_lpa_t(val);
-	}
+		base_val = tp->pci_clock_ctrl;
+		base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
+			     CLOCK_CTRL_TXCLK_DISABLE);
 
-	if (tg3_readphy(tp, MII_LPA, rmtadv))
-		return false;
+		tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
+			    CLOCK_CTRL_PWRDOWN_PLL133, 40);
+	} else if (tg3_flag(tp, 5780_CLASS) ||
+		   tg3_flag(tp, CPMU_PRESENT) ||
+		   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		/* do nothing */
+	} else if (!(tg3_flag(tp, 5750_PLUS) && tg3_flag(tp, ENABLE_ASF))) {
+		u32 newbits1, newbits2;
 
-	lpeth |= mii_lpa_to_ethtool_lpa_t(*rmtadv);
-	tp->link_config.rmt_adv = lpeth;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
+			newbits1 = (CLOCK_CTRL_RXCLK_DISABLE |
+				    CLOCK_CTRL_TXCLK_DISABLE |
+				    CLOCK_CTRL_ALTCLK);
+			newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
+		} else if (tg3_flag(tp, 5705_PLUS)) {
+			newbits1 = CLOCK_CTRL_625_CORE;
+			newbits2 = newbits1 | CLOCK_CTRL_ALTCLK;
+		} else {
+			newbits1 = CLOCK_CTRL_ALTCLK;
+			newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
+		}
 
-	return true;
-}
+		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
+			    40);
 
-static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
-{
-	int current_link_up;
-	u32 bmsr, val;
-	u32 lcl_adv, rmt_adv;
-	u16 current_speed;
-	u8 current_duplex;
-	int i, err;
+		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
+			    40);
 
-	tw32(MAC_EVENT, 0);
+		if (!tg3_flag(tp, 5705_PLUS)) {
+			u32 newbits3;
 
-	tw32_f(MAC_STATUS,
-	     (MAC_STATUS_SYNC_CHANGED |
-	      MAC_STATUS_CFG_CHANGED |
-	      MAC_STATUS_MI_COMPLETION |
-	      MAC_STATUS_LNKSTATE_CHANGED));
-	udelay(40);
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
+				newbits3 = (CLOCK_CTRL_RXCLK_DISABLE |
+					    CLOCK_CTRL_TXCLK_DISABLE |
+					    CLOCK_CTRL_44MHZ_CORE);
+			} else {
+				newbits3 = CLOCK_CTRL_44MHZ_CORE;
+			}
 
-	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
-		tw32_f(MAC_MI_MODE,
-		     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
-		udelay(80);
+			tw32_wait_f(TG3PCI_CLOCK_CTRL,
+				    tp->pci_clock_ctrl | newbits3, 40);
+		}
 	}
 
-	tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, 0);
+	if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF))
+		tg3_power_down_phy(tp, do_low_power);
 
-	/* Some third-party PHYs need to be reset on link going
-	 * down.
-	 */
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
-	    netif_carrier_ok(tp->dev)) {
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
-		    !(bmsr & BMSR_LSTATUS))
-			force_reset = 1;
-	}
-	if (force_reset)
-		tg3_phy_reset(tp);
-
-	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if (tg3_readphy(tp, MII_BMSR, &bmsr) ||
-		    !tg3_flag(tp, INIT_COMPLETE))
-			bmsr = 0;
+	tg3_frob_aux_power(tp, true);
 
-		if (!(bmsr & BMSR_LSTATUS)) {
-			err = tg3_init_5401phy_dsp(tp);
-			if (err)
-				return err;
+	/* Workaround for unstable PLL clock */
+	if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
+	    (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) {
+		u32 val = tr32(0x7d00);
 
-			tg3_readphy(tp, MII_BMSR, &bmsr);
-			for (i = 0; i < 1000; i++) {
-				udelay(10);
-				if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
-				    (bmsr & BMSR_LSTATUS)) {
-					udelay(40);
-					break;
-				}
-			}
+		val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
+		tw32(0x7d00, val);
+		if (!tg3_flag(tp, ENABLE_ASF)) {
+			int err;
 
-			if ((tp->phy_id & TG3_PHY_ID_REV_MASK) ==
-			    TG3_PHY_REV_BCM5401_B0 &&
-			    !(bmsr & BMSR_LSTATUS) &&
-			    tp->link_config.active_speed == SPEED_1000) {
-				err = tg3_phy_reset(tp);
-				if (!err)
-					err = tg3_init_5401phy_dsp(tp);
-				if (err)
-					return err;
-			}
+			err = tg3_nvram_lock(tp);
+			tg3_halt_cpu(tp, RX_CPU_BASE);
+			if (!err)
+				tg3_nvram_unlock(tp);
 		}
-	} else if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
-		   tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
-		/* 5701 {A0,B0} CRC bug workaround */
-		tg3_writephy(tp, 0x15, 0x0a75);
-		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68);
-		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
-		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68);
 	}
 
-	/* Clear pending interrupts... */
-	tg3_readphy(tp, MII_TG3_ISTAT, &val);
-	tg3_readphy(tp, MII_TG3_ISTAT, &val);
-
-	if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT)
-		tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
-	else if (!(tp->phy_flags & TG3_PHYFLG_IS_FET))
-		tg3_writephy(tp, MII_TG3_IMASK, ~0);
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
-		if (tp->led_ctrl == LED_CTRL_MODE_PHY_1)
-			tg3_writephy(tp, MII_TG3_EXT_CTRL,
-				     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
-		else
-			tg3_writephy(tp, MII_TG3_EXT_CTRL, 0);
-	}
+	tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
 
-	current_link_up = 0;
-	current_speed = SPEED_INVALID;
-	current_duplex = DUPLEX_INVALID;
-	tp->phy_flags &= ~TG3_PHYFLG_MDIX_STATE;
-	tp->link_config.rmt_adv = 0;
+	return 0;
+}
 
-	if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
-		err = tg3_phy_auxctl_read(tp,
-					  MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
-					  &val);
-		if (!err && !(val & (1 << 10))) {
-			tg3_phy_auxctl_write(tp,
-					     MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
-					     val | (1 << 10));
-			goto relink;
-		}
-	}
+static void tg3_power_down(struct tg3 *tp)
+{
+	tg3_power_down_prepare(tp);
 
-	bmsr = 0;
-	for (i = 0; i < 100; i++) {
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
-		    (bmsr & BMSR_LSTATUS))
-			break;
-		udelay(40);
-	}
+	pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
+	pci_set_power_state(tp->pdev, PCI_D3hot);
+}
 
-	if (bmsr & BMSR_LSTATUS) {
-		u32 aux_stat, bmcr;
+static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
+{
+	switch (val & MII_TG3_AUX_STAT_SPDMASK) {
+	case MII_TG3_AUX_STAT_10HALF:
+		*speed = SPEED_10;
+		*duplex = DUPLEX_HALF;
+		break;
 
-		tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
-		for (i = 0; i < 2000; i++) {
-			udelay(10);
-			if (!tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat) &&
-			    aux_stat)
-				break;
-		}
+	case MII_TG3_AUX_STAT_10FULL:
+		*speed = SPEED_10;
+		*duplex = DUPLEX_FULL;
+		break;
 
-		tg3_aux_stat_to_speed_duplex(tp, aux_stat,
-					     &current_speed,
-					     &current_duplex);
+	case MII_TG3_AUX_STAT_100HALF:
+		*speed = SPEED_100;
+		*duplex = DUPLEX_HALF;
+		break;
 
-		bmcr = 0;
-		for (i = 0; i < 200; i++) {
-			tg3_readphy(tp, MII_BMCR, &bmcr);
-			if (tg3_readphy(tp, MII_BMCR, &bmcr))
-				continue;
-			if (bmcr && bmcr != 0x7fff)
-				break;
-			udelay(10);
-		}
+	case MII_TG3_AUX_STAT_100FULL:
+		*speed = SPEED_100;
+		*duplex = DUPLEX_FULL;
+		break;
 
-		lcl_adv = 0;
-		rmt_adv = 0;
+	case MII_TG3_AUX_STAT_1000HALF:
+		*speed = SPEED_1000;
+		*duplex = DUPLEX_HALF;
+		break;
 
-		tp->link_config.active_speed = current_speed;
-		tp->link_config.active_duplex = current_duplex;
+	case MII_TG3_AUX_STAT_1000FULL:
+		*speed = SPEED_1000;
+		*duplex = DUPLEX_FULL;
+		break;
 
-		if (tp->link_config.autoneg == AUTONEG_ENABLE) {
-			if ((bmcr & BMCR_ANENABLE) &&
-			    tg3_phy_copper_an_config_ok(tp, &lcl_adv) &&
-			    tg3_phy_copper_fetch_rmtadv(tp, &rmt_adv))
-				current_link_up = 1;
-		} else {
-			if (!(bmcr & BMCR_ANENABLE) &&
-			    tp->link_config.speed == current_speed &&
-			    tp->link_config.duplex == current_duplex &&
-			    tp->link_config.flowctrl ==
-			    tp->link_config.active_flowctrl) {
-				current_link_up = 1;
-			}
+	default:
+		if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
+			*speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
+				 SPEED_10;
+			*duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
+				  DUPLEX_HALF;
+			break;
 		}
+		*speed = SPEED_UNKNOWN;
+		*duplex = DUPLEX_UNKNOWN;
+		break;
+	}
+}
 
-		if (current_link_up == 1 &&
-		    tp->link_config.active_duplex == DUPLEX_FULL) {
-			u32 reg, bit;
+static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
+{
+	int err = 0;
+	u32 val, new_adv;
 
-			if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
-				reg = MII_TG3_FET_GEN_STAT;
-				bit = MII_TG3_FET_GEN_STAT_MDIXSTAT;
-			} else {
-				reg = MII_TG3_EXT_STAT;
-				bit = MII_TG3_EXT_STAT_MDIX;
-			}
+	new_adv = ADVERTISE_CSMA;
+	new_adv |= ethtool_adv_to_mii_adv_t(advertise) & ADVERTISE_ALL;
+	new_adv |= mii_advertise_flowctrl(flowctrl);
 
-			if (!tg3_readphy(tp, reg, &val) && (val & bit))
-				tp->phy_flags |= TG3_PHYFLG_MDIX_STATE;
+	err = tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	if (err)
+		goto done;
 
-			tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
-		}
-	}
+	if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
+		new_adv = ethtool_adv_to_mii_ctrl1000_t(advertise);
 
-relink:
-	if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
-		tg3_phy_copper_begin(tp);
+		if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+			new_adv |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
 
-		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) ||
-		    (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
-			current_link_up = 1;
+		err = tg3_writephy(tp, MII_CTRL1000, new_adv);
+		if (err)
+			goto done;
 	}
 
-	tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;
-	if (current_link_up == 1) {
-		if (tp->link_config.active_speed == SPEED_100 ||
-		    tp->link_config.active_speed == SPEED_10)
-			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
-		else
-			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
-	} else if (tp->phy_flags & TG3_PHYFLG_IS_FET)
-		tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
-	else
-		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
+		goto done;
 
-	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
-	if (tp->link_config.active_duplex == DUPLEX_HALF)
-		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
+	tw32(TG3_CPMU_EEE_MODE,
+	     tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-		if (current_link_up == 1 &&
-		    tg3_5700_link_polarity(tp, tp->link_config.active_speed))
-			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
-		else
-			tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
-	}
+	err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+	if (!err) {
+		u32 err2;
 
-	/* ??? Without this setting Netgear GA302T PHY does not
-	 * ??? send/receive packets...
-	 */
-	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5411 &&
-	    tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {
-		tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;
-		tw32_f(MAC_MI_MODE, tp->mi_mode);
-		udelay(80);
-	}
+		val = 0;
+		/* Advertise 100-BaseTX EEE ability */
+		if (advertise & ADVERTISED_100baseT_Full)
+			val |= MDIO_AN_EEE_ADV_100TX;
+		/* Advertise 1000-BaseT EEE ability */
+		if (advertise & ADVERTISED_1000baseT_Full)
+			val |= MDIO_AN_EEE_ADV_1000T;
+		err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+		if (err)
+			val = 0;
 
-	tw32_f(MAC_MODE, tp->mac_mode);
-	udelay(40);
+		switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
+		case ASIC_REV_5717:
+		case ASIC_REV_57765:
+		case ASIC_REV_57766:
+		case ASIC_REV_5719:
+			/* If we advertised any eee advertisements above... */
+			if (val)
+				val = MII_TG3_DSP_TAP26_ALNOKO |
+				      MII_TG3_DSP_TAP26_RMRXSTO |
+				      MII_TG3_DSP_TAP26_OPCSINPT;
+			tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, val);
+			/* Fall through */
+		case ASIC_REV_5720:
+			if (!tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val))
+				tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, val |
+						 MII_TG3_DSP_CH34TP2_HIBW01);
+		}
 
-	tg3_phy_eee_adjust(tp, current_link_up);
+		err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+		if (!err)
+			err = err2;
+	}
 
-	if (tg3_flag(tp, USE_LINKCHG_REG)) {
-		/* Polled via timer. */
-		tw32_f(MAC_EVENT, 0);
+done:
+	return err;
+}
+
+static void tg3_phy_copper_begin(struct tg3 *tp)
+{
+	u32 new_adv;
+	int i;
+
+	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+		new_adv = ADVERTISED_10baseT_Half |
+			  ADVERTISED_10baseT_Full;
+		if (tg3_flag(tp, WOL_SPEED_100MB))
+			new_adv |= ADVERTISED_100baseT_Half |
+				   ADVERTISED_100baseT_Full;
+
+		tg3_phy_autoneg_cfg(tp, new_adv,
+				    FLOW_CTRL_TX | FLOW_CTRL_RX);
+	} else if (tp->link_config.speed == SPEED_UNKNOWN) {
+		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+			tp->link_config.advertising &=
+				~(ADVERTISED_1000baseT_Half |
+				  ADVERTISED_1000baseT_Full);
+
+		tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
+				    tp->link_config.flowctrl);
 	} else {
-		tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
-	}
-	udelay(40);
+		/* Asking for a specific link mode. */
+		if (tp->link_config.speed == SPEED_1000) {
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = ADVERTISED_1000baseT_Full;
+			else
+				new_adv = ADVERTISED_1000baseT_Half;
+		} else if (tp->link_config.speed == SPEED_100) {
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = ADVERTISED_100baseT_Full;
+			else
+				new_adv = ADVERTISED_100baseT_Half;
+		} else {
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = ADVERTISED_10baseT_Full;
+			else
+				new_adv = ADVERTISED_10baseT_Half;
+		}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
-	    current_link_up == 1 &&
-	    tp->link_config.active_speed == SPEED_1000 &&
-	    (tg3_flag(tp, PCIX_MODE) || tg3_flag(tp, PCI_HIGH_SPEED))) {
-		udelay(120);
-		tw32_f(MAC_STATUS,
-		     (MAC_STATUS_SYNC_CHANGED |
-		      MAC_STATUS_CFG_CHANGED));
-		udelay(40);
-		tg3_write_mem(tp,
-			      NIC_SRAM_FIRMWARE_MBOX,
-			      NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
+		tg3_phy_autoneg_cfg(tp, new_adv,
+				    tp->link_config.flowctrl);
 	}
 
-	/* Prevent send BD corruption. */
-	if (tg3_flag(tp, CLKREQ_BUG)) {
-		u16 oldlnkctl, newlnkctl;
+	if (tp->link_config.autoneg == AUTONEG_DISABLE &&
+	    tp->link_config.speed != SPEED_UNKNOWN) {
+		u32 bmcr, orig_bmcr;
 
-		pci_read_config_word(tp->pdev,
-				     pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
-				     &oldlnkctl);
-		if (tp->link_config.active_speed == SPEED_100 ||
-		    tp->link_config.active_speed == SPEED_10)
-			newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN;
-		else
-			newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN;
-		if (newlnkctl != oldlnkctl)
-			pci_write_config_word(tp->pdev,
-					      pci_pcie_cap(tp->pdev) +
-					      PCI_EXP_LNKCTL, newlnkctl);
-	}
+		tp->link_config.active_speed = tp->link_config.speed;
+		tp->link_config.active_duplex = tp->link_config.duplex;
 
-	if (current_link_up != netif_carrier_ok(tp->dev)) {
-		if (current_link_up)
-			netif_carrier_on(tp->dev);
-		else
-			netif_carrier_off(tp->dev);
-		tg3_link_report(tp);
-	}
+		bmcr = 0;
+		switch (tp->link_config.speed) {
+		default:
+		case SPEED_10:
+			break;
 
-	return 0;
-}
+		case SPEED_100:
+			bmcr |= BMCR_SPEED100;
+			break;
 
-struct tg3_fiber_aneginfo {
-	int state;
-#define ANEG_STATE_UNKNOWN		0
-#define ANEG_STATE_AN_ENABLE		1
-#define ANEG_STATE_RESTART_INIT		2
-#define ANEG_STATE_RESTART		3
-#define ANEG_STATE_DISABLE_LINK_OK	4
-#define ANEG_STATE_ABILITY_DETECT_INIT	5
-#define ANEG_STATE_ABILITY_DETECT	6
-#define ANEG_STATE_ACK_DETECT_INIT	7
-#define ANEG_STATE_ACK_DETECT		8
-#define ANEG_STATE_COMPLETE_ACK_INIT	9
-#define ANEG_STATE_COMPLETE_ACK		10
-#define ANEG_STATE_IDLE_DETECT_INIT	11
-#define ANEG_STATE_IDLE_DETECT		12
-#define ANEG_STATE_LINK_OK		13
-#define ANEG_STATE_NEXT_PAGE_WAIT_INIT	14
-#define ANEG_STATE_NEXT_PAGE_WAIT	15
+		case SPEED_1000:
+			bmcr |= BMCR_SPEED1000;
+			break;
+		}
 
-	u32 flags;
-#define MR_AN_ENABLE		0x00000001
-#define MR_RESTART_AN		0x00000002
-#define MR_AN_COMPLETE		0x00000004
-#define MR_PAGE_RX		0x00000008
-#define MR_NP_LOADED		0x00000010
-#define MR_TOGGLE_TX		0x00000020
-#define MR_LP_ADV_FULL_DUPLEX	0x00000040
-#define MR_LP_ADV_HALF_DUPLEX	0x00000080
-#define MR_LP_ADV_SYM_PAUSE	0x00000100
-#define MR_LP_ADV_ASYM_PAUSE	0x00000200
-#define MR_LP_ADV_REMOTE_FAULT1	0x00000400
-#define MR_LP_ADV_REMOTE_FAULT2	0x00000800
-#define MR_LP_ADV_NEXT_PAGE	0x00001000
-#define MR_TOGGLE_RX		0x00002000
-#define MR_NP_RX		0x00004000
+		if (tp->link_config.duplex == DUPLEX_FULL)
+			bmcr |= BMCR_FULLDPLX;
 
-#define MR_LINK_OK		0x80000000
+		if (!tg3_readphy(tp, MII_BMCR, &orig_bmcr) &&
+		    (bmcr != orig_bmcr)) {
+			tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK);
+			for (i = 0; i < 1500; i++) {
+				u32 tmp;
 
-	unsigned long link_time, cur_time;
+				udelay(10);
+				if (tg3_readphy(tp, MII_BMSR, &tmp) ||
+				    tg3_readphy(tp, MII_BMSR, &tmp))
+					continue;
+				if (!(tmp & BMSR_LSTATUS)) {
+					udelay(40);
+					break;
+				}
+			}
+			tg3_writephy(tp, MII_BMCR, bmcr);
+			udelay(40);
+		}
+	} else {
+		tg3_writephy(tp, MII_BMCR,
+			     BMCR_ANENABLE | BMCR_ANRESTART);
+	}
+}
 
-	u32 ability_match_cfg;
-	int ability_match_count;
+static int tg3_init_5401phy_dsp(struct tg3 *tp)
+{
+	int err;
 
-	char ability_match, idle_match, ack_match;
+	/* Turn off tap power management. */
+	/* Set Extended packet length bit */
+	err = tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20);
 
-	u32 txconfig, rxconfig;
-#define ANEG_CFG_NP		0x00000080
-#define ANEG_CFG_ACK		0x00000040
-#define ANEG_CFG_RF2		0x00000020
-#define ANEG_CFG_RF1		0x00000010
-#define ANEG_CFG_PS2		0x00000001
-#define ANEG_CFG_PS1		0x00008000
-#define ANEG_CFG_HD		0x00004000
-#define ANEG_CFG_FD		0x00002000
-#define ANEG_CFG_INVAL		0x00001f06
+	err |= tg3_phydsp_write(tp, 0x0012, 0x1804);
+	err |= tg3_phydsp_write(tp, 0x0013, 0x1204);
+	err |= tg3_phydsp_write(tp, 0x8006, 0x0132);
+	err |= tg3_phydsp_write(tp, 0x8006, 0x0232);
+	err |= tg3_phydsp_write(tp, 0x201f, 0x0a20);
 
-};
-#define ANEG_OK		0
-#define ANEG_DONE	1
-#define ANEG_TIMER_ENAB	2
-#define ANEG_FAILED	-1
+	udelay(40);
 
-#define ANEG_STATE_SETTLE_TIME	10000
+	return err;
+}
 
-static int tg3_fiber_aneg_smachine(struct tg3 *tp,
-				   struct tg3_fiber_aneginfo *ap)
+static bool tg3_phy_copper_an_config_ok(struct tg3 *tp, u32 *lcladv)
 {
-	u16 flowctrl;
-	unsigned long delta;
-	u32 rx_cfg_reg;
-	int ret;
+	u32 advmsk, tgtadv, advertising;
 
-	if (ap->state == ANEG_STATE_UNKNOWN) {
-		ap->rxconfig = 0;
-		ap->link_time = 0;
-		ap->cur_time = 0;
-		ap->ability_match_cfg = 0;
-		ap->ability_match_count = 0;
-		ap->ability_match = 0;
-		ap->idle_match = 0;
-		ap->ack_match = 0;
+	advertising = tp->link_config.advertising;
+	tgtadv = ethtool_adv_to_mii_adv_t(advertising) & ADVERTISE_ALL;
+
+	advmsk = ADVERTISE_ALL;
+	if (tp->link_config.active_duplex == DUPLEX_FULL) {
+		tgtadv |= mii_advertise_flowctrl(tp->link_config.flowctrl);
+		advmsk |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 	}
-	ap->cur_time++;
 
-	if (tr32(MAC_STATUS) & MAC_STATUS_RCVD_CFG) {
-		rx_cfg_reg = tr32(MAC_RX_AUTO_NEG);
-
-		if (rx_cfg_reg != ap->ability_match_cfg) {
-			ap->ability_match_cfg = rx_cfg_reg;
-			ap->ability_match = 0;
-			ap->ability_match_count = 0;
-		} else {
-			if (++ap->ability_match_count > 1) {
-				ap->ability_match = 1;
-				ap->ability_match_cfg = rx_cfg_reg;
-			}
-		}
-		if (rx_cfg_reg & ANEG_CFG_ACK)
-			ap->ack_match = 1;
-		else
-			ap->ack_match = 0;
-
-		ap->idle_match = 0;
-	} else {
-		ap->idle_match = 1;
-		ap->ability_match_cfg = 0;
-		ap->ability_match_count = 0;
-		ap->ability_match = 0;
-		ap->ack_match = 0;
+	if (tg3_readphy(tp, MII_ADVERTISE, lcladv))
+		return false;
 
-		rx_cfg_reg = 0;
-	}
+	if ((*lcladv & advmsk) != tgtadv)
+		return false;
 
-	ap->rxconfig = rx_cfg_reg;
-	ret = ANEG_OK;
+	if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
+		u32 tg3_ctrl;
 
-	switch (ap->state) {
-	case ANEG_STATE_UNKNOWN:
-		if (ap->flags & (MR_AN_ENABLE | MR_RESTART_AN))
-			ap->state = ANEG_STATE_AN_ENABLE;
+		tgtadv = ethtool_adv_to_mii_ctrl1000_t(advertising);
 
-		/* fallthru */
-	case ANEG_STATE_AN_ENABLE:
-		ap->flags &= ~(MR_AN_COMPLETE | MR_PAGE_RX);
-		if (ap->flags & MR_AN_ENABLE) {
-			ap->link_time = 0;
-			ap->cur_time = 0;
-			ap->ability_match_cfg = 0;
-			ap->ability_match_count = 0;
-			ap->ability_match = 0;
-			ap->idle_match = 0;
-			ap->ack_match = 0;
+		if (tg3_readphy(tp, MII_CTRL1000, &tg3_ctrl))
+			return false;
 
-			ap->state = ANEG_STATE_RESTART_INIT;
+		if (tgtadv &&
+		    (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+		     tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)) {
+			tgtadv |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
+			tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL |
+				     CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER);
 		} else {
-			ap->state = ANEG_STATE_DISABLE_LINK_OK;
+			tg3_ctrl &= (ADVERTISE_1000HALF | ADVERTISE_1000FULL);
 		}
-		break;
 
-	case ANEG_STATE_RESTART_INIT:
-		ap->link_time = ap->cur_time;
-		ap->flags &= ~(MR_NP_LOADED);
-		ap->txconfig = 0;
-		tw32(MAC_TX_AUTO_NEG, 0);
-		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
-		tw32_f(MAC_MODE, tp->mac_mode);
-		udelay(40);
+		if (tg3_ctrl != tgtadv)
+			return false;
+	}
 
-		ret = ANEG_TIMER_ENAB;
-		ap->state = ANEG_STATE_RESTART;
+	return true;
+}
 
-		/* fallthru */
-	case ANEG_STATE_RESTART:
-		delta = ap->cur_time - ap->link_time;
-		if (delta > ANEG_STATE_SETTLE_TIME)
-			ap->state = ANEG_STATE_ABILITY_DETECT_INIT;
-		else
-			ret = ANEG_TIMER_ENAB;
-		break;
+static bool tg3_phy_copper_fetch_rmtadv(struct tg3 *tp, u32 *rmtadv)
+{
+	u32 lpeth = 0;
 
-	case ANEG_STATE_DISABLE_LINK_OK:
-		ret = ANEG_DONE;
-		break;
+	if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
+		u32 val;
 
-	case ANEG_STATE_ABILITY_DETECT_INIT:
-		ap->flags &= ~(MR_TOGGLE_TX);
-		ap->txconfig = ANEG_CFG_FD;
-		flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
-		if (flowctrl & ADVERTISE_1000XPAUSE)
-			ap->txconfig |= ANEG_CFG_PS1;
-		if (flowctrl & ADVERTISE_1000XPSE_ASYM)
-			ap->txconfig |= ANEG_CFG_PS2;
-		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
-		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
-		tw32_f(MAC_MODE, tp->mac_mode);
-		udelay(40);
+		if (tg3_readphy(tp, MII_STAT1000, &val))
+			return false;
 
-		ap->state = ANEG_STATE_ABILITY_DETECT;
-		break;
+		lpeth = mii_stat1000_to_ethtool_lpa_t(val);
+	}
 
-	case ANEG_STATE_ABILITY_DETECT:
-		if (ap->ability_match != 0 && ap->rxconfig != 0)
-			ap->state = ANEG_STATE_ACK_DETECT_INIT;
-		break;
+	if (tg3_readphy(tp, MII_LPA, rmtadv))
+		return false;
 
-	case ANEG_STATE_ACK_DETECT_INIT:
-		ap->txconfig |= ANEG_CFG_ACK;
-		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
-		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
-		tw32_f(MAC_MODE, tp->mac_mode);
-		udelay(40);
+	lpeth |= mii_lpa_to_ethtool_lpa_t(*rmtadv);
+	tp->link_config.rmt_adv = lpeth;
 
-		ap->state = ANEG_STATE_ACK_DETECT;
+	return true;
+}
 
-		/* fallthru */
-	case ANEG_STATE_ACK_DETECT:
-		if (ap->ack_match != 0) {
-			if ((ap->rxconfig & ~ANEG_CFG_ACK) ==
-			    (ap->ability_match_cfg & ~ANEG_CFG_ACK)) {
-				ap->state = ANEG_STATE_COMPLETE_ACK_INIT;
-			} else {
-				ap->state = ANEG_STATE_AN_ENABLE;
-			}
-		} else if (ap->ability_match != 0 &&
-			   ap->rxconfig == 0) {
-			ap->state = ANEG_STATE_AN_ENABLE;
-		}
-		break;
+static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
+{
+	int current_link_up;
+	u32 bmsr, val;
+	u32 lcl_adv, rmt_adv;
+	u16 current_speed;
+	u8 current_duplex;
+	int i, err;
 
-	case ANEG_STATE_COMPLETE_ACK_INIT:
-		if (ap->rxconfig & ANEG_CFG_INVAL) {
-			ret = ANEG_FAILED;
-			break;
-		}
-		ap->flags &= ~(MR_LP_ADV_FULL_DUPLEX |
-			       MR_LP_ADV_HALF_DUPLEX |
-			       MR_LP_ADV_SYM_PAUSE |
-			       MR_LP_ADV_ASYM_PAUSE |
-			       MR_LP_ADV_REMOTE_FAULT1 |
-			       MR_LP_ADV_REMOTE_FAULT2 |
-			       MR_LP_ADV_NEXT_PAGE |
-			       MR_TOGGLE_RX |
-			       MR_NP_RX);
-		if (ap->rxconfig & ANEG_CFG_FD)
-			ap->flags |= MR_LP_ADV_FULL_DUPLEX;
-		if (ap->rxconfig & ANEG_CFG_HD)
-			ap->flags |= MR_LP_ADV_HALF_DUPLEX;
-		if (ap->rxconfig & ANEG_CFG_PS1)
-			ap->flags |= MR_LP_ADV_SYM_PAUSE;
-		if (ap->rxconfig & ANEG_CFG_PS2)
-			ap->flags |= MR_LP_ADV_ASYM_PAUSE;
-		if (ap->rxconfig & ANEG_CFG_RF1)
-			ap->flags |= MR_LP_ADV_REMOTE_FAULT1;
-		if (ap->rxconfig & ANEG_CFG_RF2)
-			ap->flags |= MR_LP_ADV_REMOTE_FAULT2;
-		if (ap->rxconfig & ANEG_CFG_NP)
-			ap->flags |= MR_LP_ADV_NEXT_PAGE;
+	tw32(MAC_EVENT, 0);
 
-		ap->link_time = ap->cur_time;
+	tw32_f(MAC_STATUS,
+	     (MAC_STATUS_SYNC_CHANGED |
+	      MAC_STATUS_CFG_CHANGED |
+	      MAC_STATUS_MI_COMPLETION |
+	      MAC_STATUS_LNKSTATE_CHANGED));
+	udelay(40);
 
-		ap->flags ^= (MR_TOGGLE_TX);
-		if (ap->rxconfig & 0x0008)
-			ap->flags |= MR_TOGGLE_RX;
-		if (ap->rxconfig & ANEG_CFG_NP)
-			ap->flags |= MR_NP_RX;
-		ap->flags |= MR_PAGE_RX;
+	if ((tp->mi_mode & MAC_MI_MODE_AUTO_POLL) != 0) {
+		tw32_f(MAC_MI_MODE,
+		     (tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL));
+		udelay(80);
+	}
 
-		ap->state = ANEG_STATE_COMPLETE_ACK;
-		ret = ANEG_TIMER_ENAB;
-		break;
+	tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, 0);
 
-	case ANEG_STATE_COMPLETE_ACK:
-		if (ap->ability_match != 0 &&
-		    ap->rxconfig == 0) {
-			ap->state = ANEG_STATE_AN_ENABLE;
-			break;
-		}
-		delta = ap->cur_time - ap->link_time;
-		if (delta > ANEG_STATE_SETTLE_TIME) {
-			if (!(ap->flags & (MR_LP_ADV_NEXT_PAGE))) {
-				ap->state = ANEG_STATE_IDLE_DETECT_INIT;
-			} else {
-				if ((ap->txconfig & ANEG_CFG_NP) == 0 &&
-				    !(ap->flags & MR_NP_RX)) {
-					ap->state = ANEG_STATE_IDLE_DETECT_INIT;
-				} else {
-					ret = ANEG_FAILED;
-				}
-			}
-		}
-		break;
+	/* Some third-party PHYs need to be reset on link going
+	 * down.
+	 */
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
+	    netif_carrier_ok(tp->dev)) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+		    !(bmsr & BMSR_LSTATUS))
+			force_reset = 1;
+	}
+	if (force_reset)
+		tg3_phy_reset(tp);
 
-	case ANEG_STATE_IDLE_DETECT_INIT:
-		ap->link_time = ap->cur_time;
-		tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
-		tw32_f(MAC_MODE, tp->mac_mode);
-		udelay(40);
+	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5401) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		if (tg3_readphy(tp, MII_BMSR, &bmsr) ||
+		    !tg3_flag(tp, INIT_COMPLETE))
+			bmsr = 0;
 
-		ap->state = ANEG_STATE_IDLE_DETECT;
-		ret = ANEG_TIMER_ENAB;
-		break;
+		if (!(bmsr & BMSR_LSTATUS)) {
+			err = tg3_init_5401phy_dsp(tp);
+			if (err)
+				return err;
 
-	case ANEG_STATE_IDLE_DETECT:
-		if (ap->ability_match != 0 &&
-		    ap->rxconfig == 0) {
-			ap->state = ANEG_STATE_AN_ENABLE;
-			break;
-		}
-		delta = ap->cur_time - ap->link_time;
-		if (delta > ANEG_STATE_SETTLE_TIME) {
-			/* XXX another gem from the Broadcom driver :( */
-			ap->state = ANEG_STATE_LINK_OK;
-		}
-		break;
+			tg3_readphy(tp, MII_BMSR, &bmsr);
+			for (i = 0; i < 1000; i++) {
+				udelay(10);
+				if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+				    (bmsr & BMSR_LSTATUS)) {
+					udelay(40);
+					break;
+				}
+			}
 
-	case ANEG_STATE_LINK_OK:
-		ap->flags |= (MR_AN_COMPLETE | MR_LINK_OK);
-		ret = ANEG_DONE;
-		break;
+			if ((tp->phy_id & TG3_PHY_ID_REV_MASK) ==
+			    TG3_PHY_REV_BCM5401_B0 &&
+			    !(bmsr & BMSR_LSTATUS) &&
+			    tp->link_config.active_speed == SPEED_1000) {
+				err = tg3_phy_reset(tp);
+				if (!err)
+					err = tg3_init_5401phy_dsp(tp);
+				if (err)
+					return err;
+			}
+		}
+	} else if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+		   tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
+		/* 5701 {A0,B0} CRC bug workaround */
+		tg3_writephy(tp, 0x15, 0x0a75);
+		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68);
+		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
+		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8c68);
+	}
 
-	case ANEG_STATE_NEXT_PAGE_WAIT_INIT:
-		/* ??? unimplemented */
-		break;
+	/* Clear pending interrupts... */
+	tg3_readphy(tp, MII_TG3_ISTAT, &val);
+	tg3_readphy(tp, MII_TG3_ISTAT, &val);
 
-	case ANEG_STATE_NEXT_PAGE_WAIT:
-		/* ??? unimplemented */
-		break;
+	if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT)
+		tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
+	else if (!(tp->phy_flags & TG3_PHYFLG_IS_FET))
+		tg3_writephy(tp, MII_TG3_IMASK, ~0);
 
-	default:
-		ret = ANEG_FAILED;
-		break;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
+		if (tp->led_ctrl == LED_CTRL_MODE_PHY_1)
+			tg3_writephy(tp, MII_TG3_EXT_CTRL,
+				     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
+		else
+			tg3_writephy(tp, MII_TG3_EXT_CTRL, 0);
 	}
 
-	return ret;
-}
+	current_link_up = 0;
+	current_speed = SPEED_UNKNOWN;
+	current_duplex = DUPLEX_UNKNOWN;
+	tp->phy_flags &= ~TG3_PHYFLG_MDIX_STATE;
+	tp->link_config.rmt_adv = 0;
 
-static int fiber_autoneg(struct tg3 *tp, u32 *txflags, u32 *rxflags)
-{
-	int res = 0;
-	struct tg3_fiber_aneginfo aninfo;
-	int status = ANEG_FAILED;
-	unsigned int tick;
-	u32 tmp;
+	if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
+		err = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+					  &val);
+		if (!err && !(val & (1 << 10))) {
+			tg3_phy_auxctl_write(tp,
+					     MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+					     val | (1 << 10));
+			goto relink;
+		}
+	}
 
-	tw32_f(MAC_TX_AUTO_NEG, 0);
+	bmsr = 0;
+	for (i = 0; i < 100; i++) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
+		    (bmsr & BMSR_LSTATUS))
+			break;
+		udelay(40);
+	}
 
-	tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
-	tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
-	udelay(40);
+	if (bmsr & BMSR_LSTATUS) {
+		u32 aux_stat, bmcr;
 
-	tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
-	udelay(40);
+		tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
+		for (i = 0; i < 2000; i++) {
+			udelay(10);
+			if (!tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat) &&
+			    aux_stat)
+				break;
+		}
 
-	memset(&aninfo, 0, sizeof(aninfo));
-	aninfo.flags |= MR_AN_ENABLE;
-	aninfo.state = ANEG_STATE_UNKNOWN;
-	aninfo.cur_time = 0;
-	tick = 0;
-	while (++tick < 195000) {
-		status = tg3_fiber_aneg_smachine(tp, &aninfo);
-		if (status == ANEG_DONE || status == ANEG_FAILED)
-			break;
+		tg3_aux_stat_to_speed_duplex(tp, aux_stat,
+					     &current_speed,
+					     &current_duplex);
 
-		udelay(1);
-	}
+		bmcr = 0;
+		for (i = 0; i < 200; i++) {
+			tg3_readphy(tp, MII_BMCR, &bmcr);
+			if (tg3_readphy(tp, MII_BMCR, &bmcr))
+				continue;
+			if (bmcr && bmcr != 0x7fff)
+				break;
+			udelay(10);
+		}
 
-	tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
-	tw32_f(MAC_MODE, tp->mac_mode);
-	udelay(40);
+		lcl_adv = 0;
+		rmt_adv = 0;
 
-	*txflags = aninfo.txconfig;
-	*rxflags = aninfo.flags;
+		tp->link_config.active_speed = current_speed;
+		tp->link_config.active_duplex = current_duplex;
 
-	if (status == ANEG_DONE &&
-	    (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
-			     MR_LP_ADV_FULL_DUPLEX)))
-		res = 1;
+		if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+			if ((bmcr & BMCR_ANENABLE) &&
+			    tg3_phy_copper_an_config_ok(tp, &lcl_adv) &&
+			    tg3_phy_copper_fetch_rmtadv(tp, &rmt_adv))
+				current_link_up = 1;
+		} else {
+			if (!(bmcr & BMCR_ANENABLE) &&
+			    tp->link_config.speed == current_speed &&
+			    tp->link_config.duplex == current_duplex &&
+			    tp->link_config.flowctrl ==
+			    tp->link_config.active_flowctrl) {
+				current_link_up = 1;
+			}
+		}
 
-	return res;
-}
+		if (current_link_up == 1 &&
+		    tp->link_config.active_duplex == DUPLEX_FULL) {
+			u32 reg, bit;
 
-static void tg3_init_bcm8002(struct tg3 *tp)
-{
-	u32 mac_status = tr32(MAC_STATUS);
-	int i;
+			if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
+				reg = MII_TG3_FET_GEN_STAT;
+				bit = MII_TG3_FET_GEN_STAT_MDIXSTAT;
+			} else {
+				reg = MII_TG3_EXT_STAT;
+				bit = MII_TG3_EXT_STAT_MDIX;
+			}
 
-	/* Reset when initting first time or we have a link. */
-	if (tg3_flag(tp, INIT_COMPLETE) &&
-	    !(mac_status & MAC_STATUS_PCS_SYNCED))
-		return;
+			if (!tg3_readphy(tp, reg, &val) && (val & bit))
+				tp->phy_flags |= TG3_PHYFLG_MDIX_STATE;
 
-	/* Set PLL lock range. */
-	tg3_writephy(tp, 0x16, 0x8007);
+			tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
+		}
+	}
 
-	/* SW reset */
-	tg3_writephy(tp, MII_BMCR, BMCR_RESET);
+relink:
+	if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
+		tg3_phy_copper_begin(tp);
 
-	/* Wait for reset to complete. */
-	/* XXX schedule_timeout() ... */
-	for (i = 0; i < 500; i++)
-		udelay(10);
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) ||
+		    (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
+			current_link_up = 1;
+	}
 
-	/* Config mode; select PMA/Ch 1 regs. */
-	tg3_writephy(tp, 0x10, 0x8411);
+	tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;
+	if (current_link_up == 1) {
+		if (tp->link_config.active_speed == SPEED_100 ||
+		    tp->link_config.active_speed == SPEED_10)
+			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+		else
+			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	} else if (tp->phy_flags & TG3_PHYFLG_IS_FET)
+		tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+	else
+		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
 
-	/* Enable auto-lock and comdet, select txclk for tx. */
-	tg3_writephy(tp, 0x11, 0x0a10);
+	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+	if (tp->link_config.active_duplex == DUPLEX_HALF)
+		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
 
-	tg3_writephy(tp, 0x18, 0x00a0);
-	tg3_writephy(tp, 0x16, 0x41ff);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+		if (current_link_up == 1 &&
+		    tg3_5700_link_polarity(tp, tp->link_config.active_speed))
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+		else
+			tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
+	}
 
-	/* Assert and deassert POR. */
-	tg3_writephy(tp, 0x13, 0x0400);
-	udelay(40);
-	tg3_writephy(tp, 0x13, 0x0000);
+	/* ??? Without this setting Netgear GA302T PHY does not
+	 * ??? send/receive packets...
+	 */
+	if ((tp->phy_id & TG3_PHY_ID_MASK) == TG3_PHY_ID_BCM5411 &&
+	    tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {
+		tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;
+		tw32_f(MAC_MI_MODE, tp->mi_mode);
+		udelay(80);
+	}
 
-	tg3_writephy(tp, 0x11, 0x0a50);
+	tw32_f(MAC_MODE, tp->mac_mode);
 	udelay(40);
-	tg3_writephy(tp, 0x11, 0x0a10);
 
-	/* Wait for signal to stabilize */
-	/* XXX schedule_timeout() ... */
-	for (i = 0; i < 15000; i++)
-		udelay(10);
+	tg3_phy_eee_adjust(tp, current_link_up);
 
-	/* Deselect the channel register so we can read the PHYID
-	 * later.
-	 */
-	tg3_writephy(tp, 0x10, 0x8011);
-}
+	if (tg3_flag(tp, USE_LINKCHG_REG)) {
+		/* Polled via timer. */
+		tw32_f(MAC_EVENT, 0);
+	} else {
+		tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+	}
+	udelay(40);
 
-static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
-{
-	u16 flowctrl;
-	u32 sg_dig_ctrl, sg_dig_status;
-	u32 serdes_cfg, expected_sg_dig_ctrl;
-	int workaround, port_a;
-	int current_link_up;
-
-	serdes_cfg = 0;
-	expected_sg_dig_ctrl = 0;
-	workaround = 0;
-	port_a = 1;
-	current_link_up = 0;
-
-	if (tp->pci_chip_rev_id != CHIPREV_ID_5704_A0 &&
-	    tp->pci_chip_rev_id != CHIPREV_ID_5704_A1) {
-		workaround = 1;
-		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
-			port_a = 0;
-
-		/* preserve bits 0-11,13,14 for signal pre-emphasis */
-		/* preserve bits 20-23 for voltage regulator */
-		serdes_cfg = tr32(MAC_SERDES_CFG) & 0x00f06fff;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
+	    current_link_up == 1 &&
+	    tp->link_config.active_speed == SPEED_1000 &&
+	    (tg3_flag(tp, PCIX_MODE) || tg3_flag(tp, PCI_HIGH_SPEED))) {
+		udelay(120);
+		tw32_f(MAC_STATUS,
+		     (MAC_STATUS_SYNC_CHANGED |
+		      MAC_STATUS_CFG_CHANGED));
+		udelay(40);
+		tg3_write_mem(tp,
+			      NIC_SRAM_FIRMWARE_MBOX,
+			      NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
 	}
 
-	sg_dig_ctrl = tr32(SG_DIG_CTRL);
-
-	if (tp->link_config.autoneg != AUTONEG_ENABLE) {
-		if (sg_dig_ctrl & SG_DIG_USING_HW_AUTONEG) {
-			if (workaround) {
-				u32 val = serdes_cfg;
+	/* Prevent send BD corruption. */
+	if (tg3_flag(tp, CLKREQ_BUG)) {
+		u16 oldlnkctl, newlnkctl;
 
-				if (port_a)
-					val |= 0xc010000;
-				else
-					val |= 0x4010000;
-				tw32_f(MAC_SERDES_CFG, val);
-			}
+		pci_read_config_word(tp->pdev,
+				     pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL,
+				     &oldlnkctl);
+		if (tp->link_config.active_speed == SPEED_100 ||
+		    tp->link_config.active_speed == SPEED_10)
+			newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN;
+		else
+			newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN;
+		if (newlnkctl != oldlnkctl)
+			pci_write_config_word(tp->pdev,
+					      pci_pcie_cap(tp->pdev) +
+					      PCI_EXP_LNKCTL, newlnkctl);
+	}
 
-			tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP);
-		}
-		if (mac_status & MAC_STATUS_PCS_SYNCED) {
-			tg3_setup_flow_control(tp, 0, 0);
-			current_link_up = 1;
-		}
-		goto out;
+	if (current_link_up != netif_carrier_ok(tp->dev)) {
+		if (current_link_up)
+			netif_carrier_on(tp->dev);
+		else
+			netif_carrier_off(tp->dev);
+		tg3_link_report(tp);
 	}
 
-	/* Want auto-negotiation.  */
-	expected_sg_dig_ctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_COMMON_SETUP;
+	return 0;
+}
 
-	flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
-	if (flowctrl & ADVERTISE_1000XPAUSE)
-		expected_sg_dig_ctrl |= SG_DIG_PAUSE_CAP;
-	if (flowctrl & ADVERTISE_1000XPSE_ASYM)
-		expected_sg_dig_ctrl |= SG_DIG_ASYM_PAUSE;
+struct tg3_fiber_aneginfo {
+	int state;
+#define ANEG_STATE_UNKNOWN		0
+#define ANEG_STATE_AN_ENABLE		1
+#define ANEG_STATE_RESTART_INIT		2
+#define ANEG_STATE_RESTART		3
+#define ANEG_STATE_DISABLE_LINK_OK	4
+#define ANEG_STATE_ABILITY_DETECT_INIT	5
+#define ANEG_STATE_ABILITY_DETECT	6
+#define ANEG_STATE_ACK_DETECT_INIT	7
+#define ANEG_STATE_ACK_DETECT		8
+#define ANEG_STATE_COMPLETE_ACK_INIT	9
+#define ANEG_STATE_COMPLETE_ACK		10
+#define ANEG_STATE_IDLE_DETECT_INIT	11
+#define ANEG_STATE_IDLE_DETECT		12
+#define ANEG_STATE_LINK_OK		13
+#define ANEG_STATE_NEXT_PAGE_WAIT_INIT	14
+#define ANEG_STATE_NEXT_PAGE_WAIT	15
 
-	if (sg_dig_ctrl != expected_sg_dig_ctrl) {
-		if ((tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT) &&
-		    tp->serdes_counter &&
-		    ((mac_status & (MAC_STATUS_PCS_SYNCED |
-				    MAC_STATUS_RCVD_CFG)) ==
-		     MAC_STATUS_PCS_SYNCED)) {
-			tp->serdes_counter--;
-			current_link_up = 1;
-			goto out;
-		}
-restart_autoneg:
-		if (workaround)
-			tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000);
-		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | SG_DIG_SOFT_RESET);
-		udelay(5);
-		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
+	u32 flags;
+#define MR_AN_ENABLE		0x00000001
+#define MR_RESTART_AN		0x00000002
+#define MR_AN_COMPLETE		0x00000004
+#define MR_PAGE_RX		0x00000008
+#define MR_NP_LOADED		0x00000010
+#define MR_TOGGLE_TX		0x00000020
+#define MR_LP_ADV_FULL_DUPLEX	0x00000040
+#define MR_LP_ADV_HALF_DUPLEX	0x00000080
+#define MR_LP_ADV_SYM_PAUSE	0x00000100
+#define MR_LP_ADV_ASYM_PAUSE	0x00000200
+#define MR_LP_ADV_REMOTE_FAULT1	0x00000400
+#define MR_LP_ADV_REMOTE_FAULT2	0x00000800
+#define MR_LP_ADV_NEXT_PAGE	0x00001000
+#define MR_TOGGLE_RX		0x00002000
+#define MR_NP_RX		0x00004000
 
-		tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
-		tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
-	} else if (mac_status & (MAC_STATUS_PCS_SYNCED |
-				 MAC_STATUS_SIGNAL_DET)) {
-		sg_dig_status = tr32(SG_DIG_STATUS);
-		mac_status = tr32(MAC_STATUS);
+#define MR_LINK_OK		0x80000000
 
-		if ((sg_dig_status & SG_DIG_AUTONEG_COMPLETE) &&
-		    (mac_status & MAC_STATUS_PCS_SYNCED)) {
-			u32 local_adv = 0, remote_adv = 0;
+	unsigned long link_time, cur_time;
 
-			if (sg_dig_ctrl & SG_DIG_PAUSE_CAP)
-				local_adv |= ADVERTISE_1000XPAUSE;
-			if (sg_dig_ctrl & SG_DIG_ASYM_PAUSE)
-				local_adv |= ADVERTISE_1000XPSE_ASYM;
+	u32 ability_match_cfg;
+	int ability_match_count;
 
-			if (sg_dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE)
-				remote_adv |= LPA_1000XPAUSE;
-			if (sg_dig_status & SG_DIG_PARTNER_ASYM_PAUSE)
-				remote_adv |= LPA_1000XPAUSE_ASYM;
+	char ability_match, idle_match, ack_match;
 
-			tp->link_config.rmt_adv =
-					   mii_adv_to_ethtool_adv_x(remote_adv);
+	u32 txconfig, rxconfig;
+#define ANEG_CFG_NP		0x00000080
+#define ANEG_CFG_ACK		0x00000040
+#define ANEG_CFG_RF2		0x00000020
+#define ANEG_CFG_RF1		0x00000010
+#define ANEG_CFG_PS2		0x00000001
+#define ANEG_CFG_PS1		0x00008000
+#define ANEG_CFG_HD		0x00004000
+#define ANEG_CFG_FD		0x00002000
+#define ANEG_CFG_INVAL		0x00001f06
 
-			tg3_setup_flow_control(tp, local_adv, remote_adv);
-			current_link_up = 1;
-			tp->serdes_counter = 0;
-			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
-		} else if (!(sg_dig_status & SG_DIG_AUTONEG_COMPLETE)) {
-			if (tp->serdes_counter)
-				tp->serdes_counter--;
-			else {
-				if (workaround) {
-					u32 val = serdes_cfg;
+};
+#define ANEG_OK		0
+#define ANEG_DONE	1
+#define ANEG_TIMER_ENAB	2
+#define ANEG_FAILED	-1
 
-					if (port_a)
-						val |= 0xc010000;
-					else
-						val |= 0x4010000;
+#define ANEG_STATE_SETTLE_TIME	10000
 
-					tw32_f(MAC_SERDES_CFG, val);
-				}
+static int tg3_fiber_aneg_smachine(struct tg3 *tp,
+				   struct tg3_fiber_aneginfo *ap)
+{
+	u16 flowctrl;
+	unsigned long delta;
+	u32 rx_cfg_reg;
+	int ret;
 
-				tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP);
-				udelay(40);
+	if (ap->state == ANEG_STATE_UNKNOWN) {
+		ap->rxconfig = 0;
+		ap->link_time = 0;
+		ap->cur_time = 0;
+		ap->ability_match_cfg = 0;
+		ap->ability_match_count = 0;
+		ap->ability_match = 0;
+		ap->idle_match = 0;
+		ap->ack_match = 0;
+	}
+	ap->cur_time++;
 
-				/* Link parallel detection - link is up */
-				/* only if we have PCS_SYNC and not */
-				/* receiving config code words */
-				mac_status = tr32(MAC_STATUS);
-				if ((mac_status & MAC_STATUS_PCS_SYNCED) &&
-				    !(mac_status & MAC_STATUS_RCVD_CFG)) {
-					tg3_setup_flow_control(tp, 0, 0);
-					current_link_up = 1;
-					tp->phy_flags |=
-						TG3_PHYFLG_PARALLEL_DETECT;
-					tp->serdes_counter =
-						SERDES_PARALLEL_DET_TIMEOUT;
-				} else
-					goto restart_autoneg;
+	if (tr32(MAC_STATUS) & MAC_STATUS_RCVD_CFG) {
+		rx_cfg_reg = tr32(MAC_RX_AUTO_NEG);
+
+		if (rx_cfg_reg != ap->ability_match_cfg) {
+			ap->ability_match_cfg = rx_cfg_reg;
+			ap->ability_match = 0;
+			ap->ability_match_count = 0;
+		} else {
+			if (++ap->ability_match_count > 1) {
+				ap->ability_match = 1;
+				ap->ability_match_cfg = rx_cfg_reg;
 			}
 		}
+		if (rx_cfg_reg & ANEG_CFG_ACK)
+			ap->ack_match = 1;
+		else
+			ap->ack_match = 0;
+
+		ap->idle_match = 0;
 	} else {
-		tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
-		tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+		ap->idle_match = 1;
+		ap->ability_match_cfg = 0;
+		ap->ability_match_count = 0;
+		ap->ability_match = 0;
+		ap->ack_match = 0;
+
+		rx_cfg_reg = 0;
 	}
 
-out:
-	return current_link_up;
-}
+	ap->rxconfig = rx_cfg_reg;
+	ret = ANEG_OK;
 
-static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
-{
-	int current_link_up = 0;
-
-	if (!(mac_status & MAC_STATUS_PCS_SYNCED))
-		goto out;
-
-	if (tp->link_config.autoneg == AUTONEG_ENABLE) {
-		u32 txflags, rxflags;
-		int i;
+	switch (ap->state) {
+	case ANEG_STATE_UNKNOWN:
+		if (ap->flags & (MR_AN_ENABLE | MR_RESTART_AN))
+			ap->state = ANEG_STATE_AN_ENABLE;
 
-		if (fiber_autoneg(tp, &txflags, &rxflags)) {
-			u32 local_adv = 0, remote_adv = 0;
+		/* fallthru */
+	case ANEG_STATE_AN_ENABLE:
+		ap->flags &= ~(MR_AN_COMPLETE | MR_PAGE_RX);
+		if (ap->flags & MR_AN_ENABLE) {
+			ap->link_time = 0;
+			ap->cur_time = 0;
+			ap->ability_match_cfg = 0;
+			ap->ability_match_count = 0;
+			ap->ability_match = 0;
+			ap->idle_match = 0;
+			ap->ack_match = 0;
 
-			if (txflags & ANEG_CFG_PS1)
-				local_adv |= ADVERTISE_1000XPAUSE;
-			if (txflags & ANEG_CFG_PS2)
-				local_adv |= ADVERTISE_1000XPSE_ASYM;
+			ap->state = ANEG_STATE_RESTART_INIT;
+		} else {
+			ap->state = ANEG_STATE_DISABLE_LINK_OK;
+		}
+		break;
 
-			if (rxflags & MR_LP_ADV_SYM_PAUSE)
-				remote_adv |= LPA_1000XPAUSE;
-			if (rxflags & MR_LP_ADV_ASYM_PAUSE)
-				remote_adv |= LPA_1000XPAUSE_ASYM;
+	case ANEG_STATE_RESTART_INIT:
+		ap->link_time = ap->cur_time;
+		ap->flags &= ~(MR_NP_LOADED);
+		ap->txconfig = 0;
+		tw32(MAC_TX_AUTO_NEG, 0);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32_f(MAC_MODE, tp->mac_mode);
+		udelay(40);
 
-			tp->link_config.rmt_adv =
-					   mii_adv_to_ethtool_adv_x(remote_adv);
+		ret = ANEG_TIMER_ENAB;
+		ap->state = ANEG_STATE_RESTART;
 
-			tg3_setup_flow_control(tp, local_adv, remote_adv);
+		/* fallthru */
+	case ANEG_STATE_RESTART:
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME)
+			ap->state = ANEG_STATE_ABILITY_DETECT_INIT;
+		else
+			ret = ANEG_TIMER_ENAB;
+		break;
 
-			current_link_up = 1;
-		}
-		for (i = 0; i < 30; i++) {
-			udelay(20);
-			tw32_f(MAC_STATUS,
-			       (MAC_STATUS_SYNC_CHANGED |
-				MAC_STATUS_CFG_CHANGED));
-			udelay(40);
-			if ((tr32(MAC_STATUS) &
-			     (MAC_STATUS_SYNC_CHANGED |
-			      MAC_STATUS_CFG_CHANGED)) == 0)
-				break;
-		}
+	case ANEG_STATE_DISABLE_LINK_OK:
+		ret = ANEG_DONE;
+		break;
 
-		mac_status = tr32(MAC_STATUS);
-		if (current_link_up == 0 &&
-		    (mac_status & MAC_STATUS_PCS_SYNCED) &&
-		    !(mac_status & MAC_STATUS_RCVD_CFG))
-			current_link_up = 1;
-	} else {
-		tg3_setup_flow_control(tp, 0, 0);
+	case ANEG_STATE_ABILITY_DETECT_INIT:
+		ap->flags &= ~(MR_TOGGLE_TX);
+		ap->txconfig = ANEG_CFG_FD;
+		flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
+		if (flowctrl & ADVERTISE_1000XPAUSE)
+			ap->txconfig |= ANEG_CFG_PS1;
+		if (flowctrl & ADVERTISE_1000XPSE_ASYM)
+			ap->txconfig |= ANEG_CFG_PS2;
+		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32_f(MAC_MODE, tp->mac_mode);
+		udelay(40);
 
-		/* Forcing 1000FD link up. */
-		current_link_up = 1;
+		ap->state = ANEG_STATE_ABILITY_DETECT;
+		break;
 
-		tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS));
-		udelay(40);
+	case ANEG_STATE_ABILITY_DETECT:
+		if (ap->ability_match != 0 && ap->rxconfig != 0)
+			ap->state = ANEG_STATE_ACK_DETECT_INIT;
+		break;
 
+	case ANEG_STATE_ACK_DETECT_INIT:
+		ap->txconfig |= ANEG_CFG_ACK;
+		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
 		tw32_f(MAC_MODE, tp->mac_mode);
 		udelay(40);
-	}
-
-out:
-	return current_link_up;
-}
 
-static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
-{
-	u32 orig_pause_cfg;
-	u16 orig_active_speed;
-	u8 orig_active_duplex;
-	u32 mac_status;
-	int current_link_up;
-	int i;
-
-	orig_pause_cfg = tp->link_config.active_flowctrl;
-	orig_active_speed = tp->link_config.active_speed;
-	orig_active_duplex = tp->link_config.active_duplex;
+		ap->state = ANEG_STATE_ACK_DETECT;
 
-	if (!tg3_flag(tp, HW_AUTONEG) &&
-	    netif_carrier_ok(tp->dev) &&
-	    tg3_flag(tp, INIT_COMPLETE)) {
-		mac_status = tr32(MAC_STATUS);
-		mac_status &= (MAC_STATUS_PCS_SYNCED |
-			       MAC_STATUS_SIGNAL_DET |
-			       MAC_STATUS_CFG_CHANGED |
-			       MAC_STATUS_RCVD_CFG);
-		if (mac_status == (MAC_STATUS_PCS_SYNCED |
-				   MAC_STATUS_SIGNAL_DET)) {
-			tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED |
-					    MAC_STATUS_CFG_CHANGED));
-			return 0;
+		/* fallthru */
+	case ANEG_STATE_ACK_DETECT:
+		if (ap->ack_match != 0) {
+			if ((ap->rxconfig & ~ANEG_CFG_ACK) ==
+			    (ap->ability_match_cfg & ~ANEG_CFG_ACK)) {
+				ap->state = ANEG_STATE_COMPLETE_ACK_INIT;
+			} else {
+				ap->state = ANEG_STATE_AN_ENABLE;
+			}
+		} else if (ap->ability_match != 0 &&
+			   ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
 		}
-	}
+		break;
 
-	tw32_f(MAC_TX_AUTO_NEG, 0);
+	case ANEG_STATE_COMPLETE_ACK_INIT:
+		if (ap->rxconfig & ANEG_CFG_INVAL) {
+			ret = ANEG_FAILED;
+			break;
+		}
+		ap->flags &= ~(MR_LP_ADV_FULL_DUPLEX |
+			       MR_LP_ADV_HALF_DUPLEX |
+			       MR_LP_ADV_SYM_PAUSE |
+			       MR_LP_ADV_ASYM_PAUSE |
+			       MR_LP_ADV_REMOTE_FAULT1 |
+			       MR_LP_ADV_REMOTE_FAULT2 |
+			       MR_LP_ADV_NEXT_PAGE |
+			       MR_TOGGLE_RX |
+			       MR_NP_RX);
+		if (ap->rxconfig & ANEG_CFG_FD)
+			ap->flags |= MR_LP_ADV_FULL_DUPLEX;
+		if (ap->rxconfig & ANEG_CFG_HD)
+			ap->flags |= MR_LP_ADV_HALF_DUPLEX;
+		if (ap->rxconfig & ANEG_CFG_PS1)
+			ap->flags |= MR_LP_ADV_SYM_PAUSE;
+		if (ap->rxconfig & ANEG_CFG_PS2)
+			ap->flags |= MR_LP_ADV_ASYM_PAUSE;
+		if (ap->rxconfig & ANEG_CFG_RF1)
+			ap->flags |= MR_LP_ADV_REMOTE_FAULT1;
+		if (ap->rxconfig & ANEG_CFG_RF2)
+			ap->flags |= MR_LP_ADV_REMOTE_FAULT2;
+		if (ap->rxconfig & ANEG_CFG_NP)
+			ap->flags |= MR_LP_ADV_NEXT_PAGE;
 
-	tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
-	tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
-	tw32_f(MAC_MODE, tp->mac_mode);
-	udelay(40);
+		ap->link_time = ap->cur_time;
 
-	if (tp->phy_id == TG3_PHY_ID_BCM8002)
-		tg3_init_bcm8002(tp);
+		ap->flags ^= (MR_TOGGLE_TX);
+		if (ap->rxconfig & 0x0008)
+			ap->flags |= MR_TOGGLE_RX;
+		if (ap->rxconfig & ANEG_CFG_NP)
+			ap->flags |= MR_NP_RX;
+		ap->flags |= MR_PAGE_RX;
 
-	/* Enable link change event even when serdes polling.  */
-	tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
-	udelay(40);
+		ap->state = ANEG_STATE_COMPLETE_ACK;
+		ret = ANEG_TIMER_ENAB;
+		break;
 
-	current_link_up = 0;
-	tp->link_config.rmt_adv = 0;
-	mac_status = tr32(MAC_STATUS);
+	case ANEG_STATE_COMPLETE_ACK:
+		if (ap->ability_match != 0 &&
+		    ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+			break;
+		}
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			if (!(ap->flags & (MR_LP_ADV_NEXT_PAGE))) {
+				ap->state = ANEG_STATE_IDLE_DETECT_INIT;
+			} else {
+				if ((ap->txconfig & ANEG_CFG_NP) == 0 &&
+				    !(ap->flags & MR_NP_RX)) {
+					ap->state = ANEG_STATE_IDLE_DETECT_INIT;
+				} else {
+					ret = ANEG_FAILED;
+				}
+			}
+		}
+		break;
 
-	if (tg3_flag(tp, HW_AUTONEG))
-		current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status);
-	else
-		current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
+	case ANEG_STATE_IDLE_DETECT_INIT:
+		ap->link_time = ap->cur_time;
+		tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+		tw32_f(MAC_MODE, tp->mac_mode);
+		udelay(40);
 
-	tp->napi[0].hw_status->status =
-		(SD_STATUS_UPDATED |
-		 (tp->napi[0].hw_status->status & ~SD_STATUS_LINK_CHG));
+		ap->state = ANEG_STATE_IDLE_DETECT;
+		ret = ANEG_TIMER_ENAB;
+		break;
 
-	for (i = 0; i < 100; i++) {
-		tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED |
-				    MAC_STATUS_CFG_CHANGED));
-		udelay(5);
-		if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED |
-					 MAC_STATUS_CFG_CHANGED |
-					 MAC_STATUS_LNKSTATE_CHANGED)) == 0)
+	case ANEG_STATE_IDLE_DETECT:
+		if (ap->ability_match != 0 &&
+		    ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
 			break;
-	}
-
-	mac_status = tr32(MAC_STATUS);
-	if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) {
-		current_link_up = 0;
-		if (tp->link_config.autoneg == AUTONEG_ENABLE &&
-		    tp->serdes_counter == 0) {
-			tw32_f(MAC_MODE, (tp->mac_mode |
-					  MAC_MODE_SEND_CONFIGS));
-			udelay(1);
-			tw32_f(MAC_MODE, tp->mac_mode);
 		}
-	}
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			/* XXX another gem from the Broadcom driver :( */
+			ap->state = ANEG_STATE_LINK_OK;
+		}
+		break;
 
-	if (current_link_up == 1) {
-		tp->link_config.active_speed = SPEED_1000;
-		tp->link_config.active_duplex = DUPLEX_FULL;
-		tw32(MAC_LED_CTRL, (tp->led_ctrl |
-				    LED_CTRL_LNKLED_OVERRIDE |
-				    LED_CTRL_1000MBPS_ON));
-	} else {
-		tp->link_config.active_speed = SPEED_INVALID;
-		tp->link_config.active_duplex = DUPLEX_INVALID;
-		tw32(MAC_LED_CTRL, (tp->led_ctrl |
-				    LED_CTRL_LNKLED_OVERRIDE |
-				    LED_CTRL_TRAFFIC_OVERRIDE));
-	}
+	case ANEG_STATE_LINK_OK:
+		ap->flags |= (MR_AN_COMPLETE | MR_LINK_OK);
+		ret = ANEG_DONE;
+		break;
 
-	if (current_link_up != netif_carrier_ok(tp->dev)) {
-		if (current_link_up)
-			netif_carrier_on(tp->dev);
-		else
-			netif_carrier_off(tp->dev);
-		tg3_link_report(tp);
-	} else {
-		u32 now_pause_cfg = tp->link_config.active_flowctrl;
-		if (orig_pause_cfg != now_pause_cfg ||
-		    orig_active_speed != tp->link_config.active_speed ||
-		    orig_active_duplex != tp->link_config.active_duplex)
-			tg3_link_report(tp);
+	case ANEG_STATE_NEXT_PAGE_WAIT_INIT:
+		/* ??? unimplemented */
+		break;
+
+	case ANEG_STATE_NEXT_PAGE_WAIT:
+		/* ??? unimplemented */
+		break;
+
+	default:
+		ret = ANEG_FAILED;
+		break;
 	}
 
-	return 0;
+	return ret;
 }
 
-static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
+static int fiber_autoneg(struct tg3 *tp, u32 *txflags, u32 *rxflags)
 {
-	int current_link_up, err = 0;
-	u32 bmsr, bmcr;
-	u16 current_speed;
-	u8 current_duplex;
-	u32 local_adv, remote_adv;
-
-	tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
-	tw32_f(MAC_MODE, tp->mac_mode);
-	udelay(40);
+	int res = 0;
+	struct tg3_fiber_aneginfo aninfo;
+	int status = ANEG_FAILED;
+	unsigned int tick;
+	u32 tmp;
 
-	tw32(MAC_EVENT, 0);
+	tw32_f(MAC_TX_AUTO_NEG, 0);
 
-	tw32_f(MAC_STATUS,
-	     (MAC_STATUS_SYNC_CHANGED |
-	      MAC_STATUS_CFG_CHANGED |
-	      MAC_STATUS_MI_COMPLETION |
-	      MAC_STATUS_LNKSTATE_CHANGED));
+	tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
+	tw32_f(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
 	udelay(40);
 
-	if (force_reset)
-		tg3_phy_reset(tp);
+	tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
+	udelay(40);
 
-	current_link_up = 0;
-	current_speed = SPEED_INVALID;
-	current_duplex = DUPLEX_INVALID;
-	tp->link_config.rmt_adv = 0;
+	memset(&aninfo, 0, sizeof(aninfo));
+	aninfo.flags |= MR_AN_ENABLE;
+	aninfo.state = ANEG_STATE_UNKNOWN;
+	aninfo.cur_time = 0;
+	tick = 0;
+	while (++tick < 195000) {
+		status = tg3_fiber_aneg_smachine(tp, &aninfo);
+		if (status == ANEG_DONE || status == ANEG_FAILED)
+			break;
 
-	err |= tg3_readphy(tp, MII_BMSR, &bmsr);
-	err |= tg3_readphy(tp, MII_BMSR, &bmsr);
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
-		if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
-			bmsr |= BMSR_LSTATUS;
-		else
-			bmsr &= ~BMSR_LSTATUS;
+		udelay(1);
 	}
 
-	err |= tg3_readphy(tp, MII_BMCR, &bmcr);
-
-	if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
-	    (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
-		/* do nothing, just check for link up at the end */
-	} else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
-		u32 adv, newadv;
+	tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+	tw32_f(MAC_MODE, tp->mac_mode);
+	udelay(40);
 
-		err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
-		newadv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF |
-				 ADVERTISE_1000XPAUSE |
-				 ADVERTISE_1000XPSE_ASYM |
-				 ADVERTISE_SLCT);
+	*txflags = aninfo.txconfig;
+	*rxflags = aninfo.flags;
 
-		newadv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
-		newadv |= ethtool_adv_to_mii_adv_x(tp->link_config.advertising);
+	if (status == ANEG_DONE &&
+	    (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
+			     MR_LP_ADV_FULL_DUPLEX)))
+		res = 1;
 
-		if ((newadv != adv) || !(bmcr & BMCR_ANENABLE)) {
-			tg3_writephy(tp, MII_ADVERTISE, newadv);
-			bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
-			tg3_writephy(tp, MII_BMCR, bmcr);
+	return res;
+}
 
-			tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
-			tp->serdes_counter = SERDES_AN_TIMEOUT_5714S;
-			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+static void tg3_init_bcm8002(struct tg3 *tp)
+{
+	u32 mac_status = tr32(MAC_STATUS);
+	int i;
 
-			return err;
-		}
-	} else {
-		u32 new_bmcr;
+	/* Reset when initting first time or we have a link. */
+	if (tg3_flag(tp, INIT_COMPLETE) &&
+	    !(mac_status & MAC_STATUS_PCS_SYNCED))
+		return;
 
-		bmcr &= ~BMCR_SPEED1000;
-		new_bmcr = bmcr & ~(BMCR_ANENABLE | BMCR_FULLDPLX);
+	/* Set PLL lock range. */
+	tg3_writephy(tp, 0x16, 0x8007);
 
-		if (tp->link_config.duplex == DUPLEX_FULL)
-			new_bmcr |= BMCR_FULLDPLX;
+	/* SW reset */
+	tg3_writephy(tp, MII_BMCR, BMCR_RESET);
 
-		if (new_bmcr != bmcr) {
-			/* BMCR_SPEED1000 is a reserved bit that needs
-			 * to be set on write.
-			 */
-			new_bmcr |= BMCR_SPEED1000;
+	/* Wait for reset to complete. */
+	/* XXX schedule_timeout() ... */
+	for (i = 0; i < 500; i++)
+		udelay(10);
 
-			/* Force a linkdown */
-			if (netif_carrier_ok(tp->dev)) {
-				u32 adv;
+	/* Config mode; select PMA/Ch 1 regs. */
+	tg3_writephy(tp, 0x10, 0x8411);
 
-				err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
-				adv &= ~(ADVERTISE_1000XFULL |
-					 ADVERTISE_1000XHALF |
-					 ADVERTISE_SLCT);
-				tg3_writephy(tp, MII_ADVERTISE, adv);
-				tg3_writephy(tp, MII_BMCR, bmcr |
-							   BMCR_ANRESTART |
-							   BMCR_ANENABLE);
-				udelay(10);
-				netif_carrier_off(tp->dev);
-			}
-			tg3_writephy(tp, MII_BMCR, new_bmcr);
-			bmcr = new_bmcr;
-			err |= tg3_readphy(tp, MII_BMSR, &bmsr);
-			err |= tg3_readphy(tp, MII_BMSR, &bmsr);
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
-			    ASIC_REV_5714) {
-				if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
-					bmsr |= BMSR_LSTATUS;
-				else
-					bmsr &= ~BMSR_LSTATUS;
-			}
-			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
-		}
-	}
+	/* Enable auto-lock and comdet, select txclk for tx. */
+	tg3_writephy(tp, 0x11, 0x0a10);
 
-	if (bmsr & BMSR_LSTATUS) {
-		current_speed = SPEED_1000;
-		current_link_up = 1;
-		if (bmcr & BMCR_FULLDPLX)
-			current_duplex = DUPLEX_FULL;
-		else
-			current_duplex = DUPLEX_HALF;
+	tg3_writephy(tp, 0x18, 0x00a0);
+	tg3_writephy(tp, 0x16, 0x41ff);
 
-		local_adv = 0;
-		remote_adv = 0;
+	/* Assert and deassert POR. */
+	tg3_writephy(tp, 0x13, 0x0400);
+	udelay(40);
+	tg3_writephy(tp, 0x13, 0x0000);
 
-		if (bmcr & BMCR_ANENABLE) {
-			u32 common;
+	tg3_writephy(tp, 0x11, 0x0a50);
+	udelay(40);
+	tg3_writephy(tp, 0x11, 0x0a10);
 
-			err |= tg3_readphy(tp, MII_ADVERTISE, &local_adv);
-			err |= tg3_readphy(tp, MII_LPA, &remote_adv);
-			common = local_adv & remote_adv;
-			if (common & (ADVERTISE_1000XHALF |
-				      ADVERTISE_1000XFULL)) {
-				if (common & ADVERTISE_1000XFULL)
-					current_duplex = DUPLEX_FULL;
-				else
-					current_duplex = DUPLEX_HALF;
+	/* Wait for signal to stabilize */
+	/* XXX schedule_timeout() ... */
+	for (i = 0; i < 15000; i++)
+		udelay(10);
 
-				tp->link_config.rmt_adv =
-					   mii_adv_to_ethtool_adv_x(remote_adv);
-			} else if (!tg3_flag(tp, 5780_CLASS)) {
-				/* Link is up via parallel detect */
-			} else {
-				current_link_up = 0;
-			}
-		}
-	}
+	/* Deselect the channel register so we can read the PHYID
+	 * later.
+	 */
+	tg3_writephy(tp, 0x10, 0x8011);
+}
 
-	if (current_link_up == 1 && current_duplex == DUPLEX_FULL)
-		tg3_setup_flow_control(tp, local_adv, remote_adv);
+static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
+{
+	u16 flowctrl;
+	u32 sg_dig_ctrl, sg_dig_status;
+	u32 serdes_cfg, expected_sg_dig_ctrl;
+	int workaround, port_a;
+	int current_link_up;
 
-	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
-	if (tp->link_config.active_duplex == DUPLEX_HALF)
-		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
+	serdes_cfg = 0;
+	expected_sg_dig_ctrl = 0;
+	workaround = 0;
+	port_a = 1;
+	current_link_up = 0;
 
-	tw32_f(MAC_MODE, tp->mac_mode);
-	udelay(40);
+	if (tp->pci_chip_rev_id != CHIPREV_ID_5704_A0 &&
+	    tp->pci_chip_rev_id != CHIPREV_ID_5704_A1) {
+		workaround = 1;
+		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
+			port_a = 0;
 
-	tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+		/* preserve bits 0-11,13,14 for signal pre-emphasis */
+		/* preserve bits 20-23 for voltage regulator */
+		serdes_cfg = tr32(MAC_SERDES_CFG) & 0x00f06fff;
+	}
 
-	tp->link_config.active_speed = current_speed;
-	tp->link_config.active_duplex = current_duplex;
+	sg_dig_ctrl = tr32(SG_DIG_CTRL);
 
-	if (current_link_up != netif_carrier_ok(tp->dev)) {
-		if (current_link_up)
-			netif_carrier_on(tp->dev);
-		else {
-			netif_carrier_off(tp->dev);
-			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
-		}
-		tg3_link_report(tp);
-	}
-	return err;
-}
+	if (tp->link_config.autoneg != AUTONEG_ENABLE) {
+		if (sg_dig_ctrl & SG_DIG_USING_HW_AUTONEG) {
+			if (workaround) {
+				u32 val = serdes_cfg;
 
-static void tg3_serdes_parallel_detect(struct tg3 *tp)
-{
-	if (tp->serdes_counter) {
-		/* Give autoneg time to complete. */
-		tp->serdes_counter--;
-		return;
+				if (port_a)
+					val |= 0xc010000;
+				else
+					val |= 0x4010000;
+				tw32_f(MAC_SERDES_CFG, val);
+			}
+
+			tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP);
+		}
+		if (mac_status & MAC_STATUS_PCS_SYNCED) {
+			tg3_setup_flow_control(tp, 0, 0);
+			current_link_up = 1;
+		}
+		goto out;
 	}
 
-	if (!netif_carrier_ok(tp->dev) &&
-	    (tp->link_config.autoneg == AUTONEG_ENABLE)) {
-		u32 bmcr;
+	/* Want auto-negotiation.  */
+	expected_sg_dig_ctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_COMMON_SETUP;
 
-		tg3_readphy(tp, MII_BMCR, &bmcr);
-		if (bmcr & BMCR_ANENABLE) {
-			u32 phy1, phy2;
+	flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
+	if (flowctrl & ADVERTISE_1000XPAUSE)
+		expected_sg_dig_ctrl |= SG_DIG_PAUSE_CAP;
+	if (flowctrl & ADVERTISE_1000XPSE_ASYM)
+		expected_sg_dig_ctrl |= SG_DIG_ASYM_PAUSE;
 
-			/* Select shadow register 0x1f */
-			tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x7c00);
-			tg3_readphy(tp, MII_TG3_MISC_SHDW, &phy1);
+	if (sg_dig_ctrl != expected_sg_dig_ctrl) {
+		if ((tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT) &&
+		    tp->serdes_counter &&
+		    ((mac_status & (MAC_STATUS_PCS_SYNCED |
+				    MAC_STATUS_RCVD_CFG)) ==
+		     MAC_STATUS_PCS_SYNCED)) {
+			tp->serdes_counter--;
+			current_link_up = 1;
+			goto out;
+		}
+restart_autoneg:
+		if (workaround)
+			tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000);
+		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | SG_DIG_SOFT_RESET);
+		udelay(5);
+		tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
 
-			/* Select expansion interrupt status register */
-			tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
-					 MII_TG3_DSP_EXP1_INT_STAT);
-			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
-			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
+		tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
+		tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+	} else if (mac_status & (MAC_STATUS_PCS_SYNCED |
+				 MAC_STATUS_SIGNAL_DET)) {
+		sg_dig_status = tr32(SG_DIG_STATUS);
+		mac_status = tr32(MAC_STATUS);
 
-			if ((phy1 & 0x10) && !(phy2 & 0x20)) {
-				/* We have signal detect and not receiving
-				 * config code words, link is up by parallel
-				 * detection.
-				 */
+		if ((sg_dig_status & SG_DIG_AUTONEG_COMPLETE) &&
+		    (mac_status & MAC_STATUS_PCS_SYNCED)) {
+			u32 local_adv = 0, remote_adv = 0;
 
-				bmcr &= ~BMCR_ANENABLE;
-				bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
-				tg3_writephy(tp, MII_BMCR, bmcr);
-				tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT;
-			}
-		}
-	} else if (netif_carrier_ok(tp->dev) &&
-		   (tp->link_config.autoneg == AUTONEG_ENABLE) &&
-		   (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
-		u32 phy2;
+			if (sg_dig_ctrl & SG_DIG_PAUSE_CAP)
+				local_adv |= ADVERTISE_1000XPAUSE;
+			if (sg_dig_ctrl & SG_DIG_ASYM_PAUSE)
+				local_adv |= ADVERTISE_1000XPSE_ASYM;
 
-		/* Select expansion interrupt status register */
-		tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
-				 MII_TG3_DSP_EXP1_INT_STAT);
-		tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
-		if (phy2 & 0x20) {
-			u32 bmcr;
+			if (sg_dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE)
+				remote_adv |= LPA_1000XPAUSE;
+			if (sg_dig_status & SG_DIG_PARTNER_ASYM_PAUSE)
+				remote_adv |= LPA_1000XPAUSE_ASYM;
 
-			/* Config code words received, turn on autoneg. */
-			tg3_readphy(tp, MII_BMCR, &bmcr);
-			tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANENABLE);
+			tp->link_config.rmt_adv =
+					   mii_adv_to_ethtool_adv_x(remote_adv);
 
+			tg3_setup_flow_control(tp, local_adv, remote_adv);
+			current_link_up = 1;
+			tp->serdes_counter = 0;
 			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+		} else if (!(sg_dig_status & SG_DIG_AUTONEG_COMPLETE)) {
+			if (tp->serdes_counter)
+				tp->serdes_counter--;
+			else {
+				if (workaround) {
+					u32 val = serdes_cfg;
+
+					if (port_a)
+						val |= 0xc010000;
+					else
+						val |= 0x4010000;
 
+					tw32_f(MAC_SERDES_CFG, val);
+				}
+
+				tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP);
+				udelay(40);
+
+				/* Link parallel detection - link is up */
+				/* only if we have PCS_SYNC and not */
+				/* receiving config code words */
+				mac_status = tr32(MAC_STATUS);
+				if ((mac_status & MAC_STATUS_PCS_SYNCED) &&
+				    !(mac_status & MAC_STATUS_RCVD_CFG)) {
+					tg3_setup_flow_control(tp, 0, 0);
+					current_link_up = 1;
+					tp->phy_flags |=
+						TG3_PHYFLG_PARALLEL_DETECT;
+					tp->serdes_counter =
+						SERDES_PARALLEL_DET_TIMEOUT;
+				} else
+					goto restart_autoneg;
+			}
 		}
+	} else {
+		tp->serdes_counter = SERDES_AN_TIMEOUT_5704S;
+		tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
 	}
+
+out:
+	return current_link_up;
 }
 
-static int tg3_setup_phy(struct tg3 *tp, int force_reset)
+static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
 {
-	u32 val;
-	int err;
+	int current_link_up = 0;
 
-	if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
-		err = tg3_setup_fiber_phy(tp, force_reset);
-	else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
-		err = tg3_setup_fiber_mii_phy(tp, force_reset);
-	else
-		err = tg3_setup_copper_phy(tp, force_reset);
+	if (!(mac_status & MAC_STATUS_PCS_SYNCED))
+		goto out;
 
-	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
-		u32 scale;
+	if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+		u32 txflags, rxflags;
+		int i;
 
-		val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
-		if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5)
-			scale = 65;
-		else if (val == CPMU_CLCK_STAT_MAC_CLCK_6_25)
-			scale = 6;
-		else
-			scale = 12;
+		if (fiber_autoneg(tp, &txflags, &rxflags)) {
+			u32 local_adv = 0, remote_adv = 0;
 
-		val = tr32(GRC_MISC_CFG) & ~GRC_MISC_CFG_PRESCALAR_MASK;
-		val |= (scale << GRC_MISC_CFG_PRESCALAR_SHIFT);
-		tw32(GRC_MISC_CFG, val);
-	}
+			if (txflags & ANEG_CFG_PS1)
+				local_adv |= ADVERTISE_1000XPAUSE;
+			if (txflags & ANEG_CFG_PS2)
+				local_adv |= ADVERTISE_1000XPSE_ASYM;
 
-	val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
-	      (6 << TX_LENGTHS_IPG_SHIFT);
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
-		val |= tr32(MAC_TX_LENGTHS) &
-		       (TX_LENGTHS_JMB_FRM_LEN_MSK |
-			TX_LENGTHS_CNT_DWN_VAL_MSK);
+			if (rxflags & MR_LP_ADV_SYM_PAUSE)
+				remote_adv |= LPA_1000XPAUSE;
+			if (rxflags & MR_LP_ADV_ASYM_PAUSE)
+				remote_adv |= LPA_1000XPAUSE_ASYM;
 
-	if (tp->link_config.active_speed == SPEED_1000 &&
-	    tp->link_config.active_duplex == DUPLEX_HALF)
-		tw32(MAC_TX_LENGTHS, val |
-		     (0xff << TX_LENGTHS_SLOT_TIME_SHIFT));
-	else
-		tw32(MAC_TX_LENGTHS, val |
-		     (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
+			tp->link_config.rmt_adv =
+					   mii_adv_to_ethtool_adv_x(remote_adv);
 
-	if (!tg3_flag(tp, 5705_PLUS)) {
-		if (netif_carrier_ok(tp->dev)) {
-			tw32(HOSTCC_STAT_COAL_TICKS,
-			     tp->coal.stats_block_coalesce_usecs);
-		} else {
-			tw32(HOSTCC_STAT_COAL_TICKS, 0);
-		}
-	}
+			tg3_setup_flow_control(tp, local_adv, remote_adv);
 
-	if (tg3_flag(tp, ASPM_WORKAROUND)) {
-		val = tr32(PCIE_PWR_MGMT_THRESH);
-		if (!netif_carrier_ok(tp->dev))
-			val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) |
-			      tp->pwrmgmt_thresh;
-		else
-			val |= PCIE_PWR_MGMT_L1_THRESH_MSK;
-		tw32(PCIE_PWR_MGMT_THRESH, val);
-	}
+			current_link_up = 1;
+		}
+		for (i = 0; i < 30; i++) {
+			udelay(20);
+			tw32_f(MAC_STATUS,
+			       (MAC_STATUS_SYNC_CHANGED |
+				MAC_STATUS_CFG_CHANGED));
+			udelay(40);
+			if ((tr32(MAC_STATUS) &
+			     (MAC_STATUS_SYNC_CHANGED |
+			      MAC_STATUS_CFG_CHANGED)) == 0)
+				break;
+		}
 
-	return err;
-}
-
-static inline int tg3_irq_sync(struct tg3 *tp)
-{
-	return tp->irq_sync;
-}
-
-static inline void tg3_rd32_loop(struct tg3 *tp, u32 *dst, u32 off, u32 len)
-{
-	int i;
-
-	dst = (u32 *)((u8 *)dst + off);
-	for (i = 0; i < len; i += sizeof(u32))
-		*dst++ = tr32(off + i);
-}
-
-static void tg3_dump_legacy_regs(struct tg3 *tp, u32 *regs)
-{
-	tg3_rd32_loop(tp, regs, TG3PCI_VENDOR, 0xb0);
-	tg3_rd32_loop(tp, regs, MAILBOX_INTERRUPT_0, 0x200);
-	tg3_rd32_loop(tp, regs, MAC_MODE, 0x4f0);
-	tg3_rd32_loop(tp, regs, SNDDATAI_MODE, 0xe0);
-	tg3_rd32_loop(tp, regs, SNDDATAC_MODE, 0x04);
-	tg3_rd32_loop(tp, regs, SNDBDS_MODE, 0x80);
-	tg3_rd32_loop(tp, regs, SNDBDI_MODE, 0x48);
-	tg3_rd32_loop(tp, regs, SNDBDC_MODE, 0x04);
-	tg3_rd32_loop(tp, regs, RCVLPC_MODE, 0x20);
-	tg3_rd32_loop(tp, regs, RCVLPC_SELLST_BASE, 0x15c);
-	tg3_rd32_loop(tp, regs, RCVDBDI_MODE, 0x0c);
-	tg3_rd32_loop(tp, regs, RCVDBDI_JUMBO_BD, 0x3c);
-	tg3_rd32_loop(tp, regs, RCVDBDI_BD_PROD_IDX_0, 0x44);
-	tg3_rd32_loop(tp, regs, RCVDCC_MODE, 0x04);
-	tg3_rd32_loop(tp, regs, RCVBDI_MODE, 0x20);
-	tg3_rd32_loop(tp, regs, RCVCC_MODE, 0x14);
-	tg3_rd32_loop(tp, regs, RCVLSC_MODE, 0x08);
-	tg3_rd32_loop(tp, regs, MBFREE_MODE, 0x08);
-	tg3_rd32_loop(tp, regs, HOSTCC_MODE, 0x100);
+		mac_status = tr32(MAC_STATUS);
+		if (current_link_up == 0 &&
+		    (mac_status & MAC_STATUS_PCS_SYNCED) &&
+		    !(mac_status & MAC_STATUS_RCVD_CFG))
+			current_link_up = 1;
+	} else {
+		tg3_setup_flow_control(tp, 0, 0);
 
-	if (tg3_flag(tp, SUPPORT_MSIX))
-		tg3_rd32_loop(tp, regs, HOSTCC_RXCOL_TICKS_VEC1, 0x180);
+		/* Forcing 1000FD link up. */
+		current_link_up = 1;
 
-	tg3_rd32_loop(tp, regs, MEMARB_MODE, 0x10);
-	tg3_rd32_loop(tp, regs, BUFMGR_MODE, 0x58);
-	tg3_rd32_loop(tp, regs, RDMAC_MODE, 0x08);
-	tg3_rd32_loop(tp, regs, WDMAC_MODE, 0x08);
-	tg3_rd32_loop(tp, regs, RX_CPU_MODE, 0x04);
-	tg3_rd32_loop(tp, regs, RX_CPU_STATE, 0x04);
-	tg3_rd32_loop(tp, regs, RX_CPU_PGMCTR, 0x04);
-	tg3_rd32_loop(tp, regs, RX_CPU_HWBKPT, 0x04);
+		tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS));
+		udelay(40);
 
-	if (!tg3_flag(tp, 5705_PLUS)) {
-		tg3_rd32_loop(tp, regs, TX_CPU_MODE, 0x04);
-		tg3_rd32_loop(tp, regs, TX_CPU_STATE, 0x04);
-		tg3_rd32_loop(tp, regs, TX_CPU_PGMCTR, 0x04);
+		tw32_f(MAC_MODE, tp->mac_mode);
+		udelay(40);
 	}
 
-	tg3_rd32_loop(tp, regs, GRCMBOX_INTERRUPT_0, 0x110);
-	tg3_rd32_loop(tp, regs, FTQ_RESET, 0x120);
-	tg3_rd32_loop(tp, regs, MSGINT_MODE, 0x0c);
-	tg3_rd32_loop(tp, regs, DMAC_MODE, 0x04);
-	tg3_rd32_loop(tp, regs, GRC_MODE, 0x4c);
-
-	if (tg3_flag(tp, NVRAM))
-		tg3_rd32_loop(tp, regs, NVRAM_CMD, 0x24);
+out:
+	return current_link_up;
 }
 
-static void tg3_dump_state(struct tg3 *tp)
+static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
 {
+	u32 orig_pause_cfg;
+	u16 orig_active_speed;
+	u8 orig_active_duplex;
+	u32 mac_status;
+	int current_link_up;
 	int i;
-	u32 *regs;
 
-	regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC);
-	if (!regs) {
-		netdev_err(tp->dev, "Failed allocating register dump buffer\n");
-		return;
+	orig_pause_cfg = tp->link_config.active_flowctrl;
+	orig_active_speed = tp->link_config.active_speed;
+	orig_active_duplex = tp->link_config.active_duplex;
+
+	if (!tg3_flag(tp, HW_AUTONEG) &&
+	    netif_carrier_ok(tp->dev) &&
+	    tg3_flag(tp, INIT_COMPLETE)) {
+		mac_status = tr32(MAC_STATUS);
+		mac_status &= (MAC_STATUS_PCS_SYNCED |
+			       MAC_STATUS_SIGNAL_DET |
+			       MAC_STATUS_CFG_CHANGED |
+			       MAC_STATUS_RCVD_CFG);
+		if (mac_status == (MAC_STATUS_PCS_SYNCED |
+				   MAC_STATUS_SIGNAL_DET)) {
+			tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED |
+					    MAC_STATUS_CFG_CHANGED));
+			return 0;
+		}
 	}
 
-	if (tg3_flag(tp, PCI_EXPRESS)) {
-		/* Read up to but not including private PCI registers */
-		for (i = 0; i < TG3_PCIE_TLDLPL_PORT; i += sizeof(u32))
-			regs[i / sizeof(u32)] = tr32(i);
-	} else
-		tg3_dump_legacy_regs(tp, regs);
+	tw32_f(MAC_TX_AUTO_NEG, 0);
 
-	for (i = 0; i < TG3_REG_BLK_SIZE / sizeof(u32); i += 4) {
-		if (!regs[i + 0] && !regs[i + 1] &&
-		    !regs[i + 2] && !regs[i + 3])
-			continue;
+	tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+	tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
+	tw32_f(MAC_MODE, tp->mac_mode);
+	udelay(40);
 
-		netdev_err(tp->dev, "0x%08x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
-			   i * 4,
-			   regs[i + 0], regs[i + 1], regs[i + 2], regs[i + 3]);
-	}
+	if (tp->phy_id == TG3_PHY_ID_BCM8002)
+		tg3_init_bcm8002(tp);
 
-	kfree(regs);
+	/* Enable link change event even when serdes polling.  */
+	tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+	udelay(40);
 
-	for (i = 0; i < tp->irq_cnt; i++) {
-		struct tg3_napi *tnapi = &tp->napi[i];
+	current_link_up = 0;
+	tp->link_config.rmt_adv = 0;
+	mac_status = tr32(MAC_STATUS);
 
-		/* SW status block */
-		netdev_err(tp->dev,
-			 "%d: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
-			   i,
-			   tnapi->hw_status->status,
-			   tnapi->hw_status->status_tag,
-			   tnapi->hw_status->rx_jumbo_consumer,
-			   tnapi->hw_status->rx_consumer,
-			   tnapi->hw_status->rx_mini_consumer,
-			   tnapi->hw_status->idx[0].rx_producer,
-			   tnapi->hw_status->idx[0].tx_consumer);
+	if (tg3_flag(tp, HW_AUTONEG))
+		current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status);
+	else
+		current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
 
-		netdev_err(tp->dev,
-		"%d: NAPI info [%08x:%08x:(%04x:%04x:%04x):%04x:(%04x:%04x:%04x:%04x)]\n",
-			   i,
-			   tnapi->last_tag, tnapi->last_irq_tag,
-			   tnapi->tx_prod, tnapi->tx_cons, tnapi->tx_pending,
-			   tnapi->rx_rcb_ptr,
-			   tnapi->prodring.rx_std_prod_idx,
-			   tnapi->prodring.rx_std_cons_idx,
-			   tnapi->prodring.rx_jmb_prod_idx,
-			   tnapi->prodring.rx_jmb_cons_idx);
+	tp->napi[0].hw_status->status =
+		(SD_STATUS_UPDATED |
+		 (tp->napi[0].hw_status->status & ~SD_STATUS_LINK_CHG));
+
+	for (i = 0; i < 100; i++) {
+		tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED |
+				    MAC_STATUS_CFG_CHANGED));
+		udelay(5);
+		if ((tr32(MAC_STATUS) & (MAC_STATUS_SYNC_CHANGED |
+					 MAC_STATUS_CFG_CHANGED |
+					 MAC_STATUS_LNKSTATE_CHANGED)) == 0)
+			break;
 	}
-}
 
-/* This is called whenever we suspect that the system chipset is re-
- * ordering the sequence of MMIO to the tx send mailbox. The symptom
- * is bogus tx completions. We try to recover by setting the
- * TG3_FLAG_MBOX_WRITE_REORDER flag and resetting the chip later
- * in the workqueue.
- */
-static void tg3_tx_recover(struct tg3 *tp)
-{
-	BUG_ON(tg3_flag(tp, MBOX_WRITE_REORDER) ||
-	       tp->write32_tx_mbox == tg3_write_indirect_mbox);
+	mac_status = tr32(MAC_STATUS);
+	if ((mac_status & MAC_STATUS_PCS_SYNCED) == 0) {
+		current_link_up = 0;
+		if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+		    tp->serdes_counter == 0) {
+			tw32_f(MAC_MODE, (tp->mac_mode |
+					  MAC_MODE_SEND_CONFIGS));
+			udelay(1);
+			tw32_f(MAC_MODE, tp->mac_mode);
+		}
+	}
 
-	netdev_warn(tp->dev,
-		    "The system may be re-ordering memory-mapped I/O "
-		    "cycles to the network device, attempting to recover. "
-		    "Please report the problem to the driver maintainer "
-		    "and include system chipset information.\n");
+	if (current_link_up == 1) {
+		tp->link_config.active_speed = SPEED_1000;
+		tp->link_config.active_duplex = DUPLEX_FULL;
+		tw32(MAC_LED_CTRL, (tp->led_ctrl |
+				    LED_CTRL_LNKLED_OVERRIDE |
+				    LED_CTRL_1000MBPS_ON));
+	} else {
+		tp->link_config.active_speed = SPEED_UNKNOWN;
+		tp->link_config.active_duplex = DUPLEX_UNKNOWN;
+		tw32(MAC_LED_CTRL, (tp->led_ctrl |
+				    LED_CTRL_LNKLED_OVERRIDE |
+				    LED_CTRL_TRAFFIC_OVERRIDE));
+	}
 
-	spin_lock(&tp->lock);
-	tg3_flag_set(tp, TX_RECOVERY_PENDING);
-	spin_unlock(&tp->lock);
-}
+	if (current_link_up != netif_carrier_ok(tp->dev)) {
+		if (current_link_up)
+			netif_carrier_on(tp->dev);
+		else
+			netif_carrier_off(tp->dev);
+		tg3_link_report(tp);
+	} else {
+		u32 now_pause_cfg = tp->link_config.active_flowctrl;
+		if (orig_pause_cfg != now_pause_cfg ||
+		    orig_active_speed != tp->link_config.active_speed ||
+		    orig_active_duplex != tp->link_config.active_duplex)
+			tg3_link_report(tp);
+	}
 
-static inline u32 tg3_tx_avail(struct tg3_napi *tnapi)
-{
-	/* Tell compiler to fetch tx indices from memory. */
-	barrier();
-	return tnapi->tx_pending -
-	       ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1));
+	return 0;
 }
 
-/* Tigon3 never reports partial packet sends.  So we do not
- * need special logic to handle SKBs that have not had all
- * of their frags sent yet, like SunGEM does.
- */
-static void tg3_tx(struct tg3_napi *tnapi)
+static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
 {
-	struct tg3 *tp = tnapi->tp;
-	u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer;
-	u32 sw_idx = tnapi->tx_cons;
-	struct netdev_queue *txq;
-	int index = tnapi - tp->napi;
-	unsigned int pkts_compl = 0, bytes_compl = 0;
+	int current_link_up, err = 0;
+	u32 bmsr, bmcr;
+	u16 current_speed;
+	u8 current_duplex;
+	u32 local_adv, remote_adv;
 
-	if (tg3_flag(tp, ENABLE_TSS))
-		index--;
+	tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	tw32_f(MAC_MODE, tp->mac_mode);
+	udelay(40);
 
-	txq = netdev_get_tx_queue(tp->dev, index);
+	tw32(MAC_EVENT, 0);
 
-	while (sw_idx != hw_idx) {
-		struct tg3_tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];
-		struct sk_buff *skb = ri->skb;
-		int i, tx_bug = 0;
+	tw32_f(MAC_STATUS,
+	     (MAC_STATUS_SYNC_CHANGED |
+	      MAC_STATUS_CFG_CHANGED |
+	      MAC_STATUS_MI_COMPLETION |
+	      MAC_STATUS_LNKSTATE_CHANGED));
+	udelay(40);
 
-		if (unlikely(skb == NULL)) {
-			tg3_tx_recover(tp);
-			return;
-		}
+	if (force_reset)
+		tg3_phy_reset(tp);
 
-		pci_unmap_single(tp->pdev,
-				 dma_unmap_addr(ri, mapping),
-				 skb_headlen(skb),
-				 PCI_DMA_TODEVICE);
+	current_link_up = 0;
+	current_speed = SPEED_UNKNOWN;
+	current_duplex = DUPLEX_UNKNOWN;
+	tp->link_config.rmt_adv = 0;
 
-		ri->skb = NULL;
+	err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+	err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+		if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+			bmsr |= BMSR_LSTATUS;
+		else
+			bmsr &= ~BMSR_LSTATUS;
+	}
 
-		while (ri->fragmented) {
-			ri->fragmented = false;
-			sw_idx = NEXT_TX(sw_idx);
-			ri = &tnapi->tx_buffers[sw_idx];
+	err |= tg3_readphy(tp, MII_BMCR, &bmcr);
+
+	if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
+	    (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
+		/* do nothing, just check for link up at the end */
+	} else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+		u32 adv, newadv;
+
+		err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
+		newadv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF |
+				 ADVERTISE_1000XPAUSE |
+				 ADVERTISE_1000XPSE_ASYM |
+				 ADVERTISE_SLCT);
+
+		newadv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
+		newadv |= ethtool_adv_to_mii_adv_x(tp->link_config.advertising);
+
+		if ((newadv != adv) || !(bmcr & BMCR_ANENABLE)) {
+			tg3_writephy(tp, MII_ADVERTISE, newadv);
+			bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
+			tg3_writephy(tp, MII_BMCR, bmcr);
+
+			tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+			tp->serdes_counter = SERDES_AN_TIMEOUT_5714S;
+			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+
+			return err;
 		}
+	} else {
+		u32 new_bmcr;
 
-		sw_idx = NEXT_TX(sw_idx);
+		bmcr &= ~BMCR_SPEED1000;
+		new_bmcr = bmcr & ~(BMCR_ANENABLE | BMCR_FULLDPLX);
 
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			ri = &tnapi->tx_buffers[sw_idx];
-			if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
-				tx_bug = 1;
+		if (tp->link_config.duplex == DUPLEX_FULL)
+			new_bmcr |= BMCR_FULLDPLX;
 
-			pci_unmap_page(tp->pdev,
-				       dma_unmap_addr(ri, mapping),
-				       skb_frag_size(&skb_shinfo(skb)->frags[i]),
-				       PCI_DMA_TODEVICE);
+		if (new_bmcr != bmcr) {
+			/* BMCR_SPEED1000 is a reserved bit that needs
+			 * to be set on write.
+			 */
+			new_bmcr |= BMCR_SPEED1000;
 
-			while (ri->fragmented) {
-				ri->fragmented = false;
-				sw_idx = NEXT_TX(sw_idx);
-				ri = &tnapi->tx_buffers[sw_idx];
-			}
+			/* Force a linkdown */
+			if (netif_carrier_ok(tp->dev)) {
+				u32 adv;
 
-			sw_idx = NEXT_TX(sw_idx);
+				err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
+				adv &= ~(ADVERTISE_1000XFULL |
+					 ADVERTISE_1000XHALF |
+					 ADVERTISE_SLCT);
+				tg3_writephy(tp, MII_ADVERTISE, adv);
+				tg3_writephy(tp, MII_BMCR, bmcr |
+							   BMCR_ANRESTART |
+							   BMCR_ANENABLE);
+				udelay(10);
+				netif_carrier_off(tp->dev);
+			}
+			tg3_writephy(tp, MII_BMCR, new_bmcr);
+			bmcr = new_bmcr;
+			err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+			err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5714) {
+				if (tr32(MAC_TX_STATUS) & TX_STATUS_LINK_UP)
+					bmsr |= BMSR_LSTATUS;
+				else
+					bmsr &= ~BMSR_LSTATUS;
+			}
+			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
 		}
+	}
 
-		pkts_compl++;
-		bytes_compl += skb->len;
+	if (bmsr & BMSR_LSTATUS) {
+		current_speed = SPEED_1000;
+		current_link_up = 1;
+		if (bmcr & BMCR_FULLDPLX)
+			current_duplex = DUPLEX_FULL;
+		else
+			current_duplex = DUPLEX_HALF;
 
-		dev_kfree_skb(skb);
+		local_adv = 0;
+		remote_adv = 0;
 
-		if (unlikely(tx_bug)) {
-			tg3_tx_recover(tp);
-			return;
+		if (bmcr & BMCR_ANENABLE) {
+			u32 common;
+
+			err |= tg3_readphy(tp, MII_ADVERTISE, &local_adv);
+			err |= tg3_readphy(tp, MII_LPA, &remote_adv);
+			common = local_adv & remote_adv;
+			if (common & (ADVERTISE_1000XHALF |
+				      ADVERTISE_1000XFULL)) {
+				if (common & ADVERTISE_1000XFULL)
+					current_duplex = DUPLEX_FULL;
+				else
+					current_duplex = DUPLEX_HALF;
+
+				tp->link_config.rmt_adv =
+					   mii_adv_to_ethtool_adv_x(remote_adv);
+			} else if (!tg3_flag(tp, 5780_CLASS)) {
+				/* Link is up via parallel detect */
+			} else {
+				current_link_up = 0;
+			}
 		}
 	}
 
-	netdev_completed_queue(tp->dev, pkts_compl, bytes_compl);
+	if (current_link_up == 1 && current_duplex == DUPLEX_FULL)
+		tg3_setup_flow_control(tp, local_adv, remote_adv);
 
-	tnapi->tx_cons = sw_idx;
+	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+	if (tp->link_config.active_duplex == DUPLEX_HALF)
+		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
 
-	/* Need to make the tx_cons update visible to tg3_start_xmit()
-	 * before checking for netif_queue_stopped().  Without the
-	 * memory barrier, there is a small possibility that tg3_start_xmit()
-	 * will miss it and cause the queue to be stopped forever.
-	 */
-	smp_mb();
+	tw32_f(MAC_MODE, tp->mac_mode);
+	udelay(40);
 
-	if (unlikely(netif_tx_queue_stopped(txq) &&
-		     (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) {
-		__netif_tx_lock(txq, smp_processor_id());
-		if (netif_tx_queue_stopped(txq) &&
-		    (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
-			netif_tx_wake_queue(txq);
-		__netif_tx_unlock(txq);
+	tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+
+	tp->link_config.active_speed = current_speed;
+	tp->link_config.active_duplex = current_duplex;
+
+	if (current_link_up != netif_carrier_ok(tp->dev)) {
+		if (current_link_up)
+			netif_carrier_on(tp->dev);
+		else {
+			netif_carrier_off(tp->dev);
+			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
+		}
+		tg3_link_report(tp);
 	}
+	return err;
 }
 
-static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
+static void tg3_serdes_parallel_detect(struct tg3 *tp)
 {
-	if (!ri->data)
+	if (tp->serdes_counter) {
+		/* Give autoneg time to complete. */
+		tp->serdes_counter--;
 		return;
+	}
 
-	pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping),
-			 map_sz, PCI_DMA_FROMDEVICE);
-	kfree(ri->data);
-	ri->data = NULL;
-}
+	if (!netif_carrier_ok(tp->dev) &&
+	    (tp->link_config.autoneg == AUTONEG_ENABLE)) {
+		u32 bmcr;
 
-/* Returns size of skb allocated or < 0 on error.
- *
- * We only need to fill in the address because the other members
- * of the RX descriptor are invariant, see tg3_init_rings.
- *
- * Note the purposeful assymetry of cpu vs. chip accesses.  For
- * posting buffers we only dirty the first cache line of the RX
- * descriptor (containing the address).  Whereas for the RX status
- * buffers the cpu only reads the last cacheline of the RX descriptor
- * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
- */
-static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
-			    u32 opaque_key, u32 dest_idx_unmasked)
-{
-	struct tg3_rx_buffer_desc *desc;
-	struct ring_info *map;
-	u8 *data;
-	dma_addr_t mapping;
-	int skb_size, data_size, dest_idx;
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		if (bmcr & BMCR_ANENABLE) {
+			u32 phy1, phy2;
 
-	switch (opaque_key) {
-	case RXD_OPAQUE_RING_STD:
-		dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
-		desc = &tpr->rx_std[dest_idx];
-		map = &tpr->rx_std_buffers[dest_idx];
-		data_size = tp->rx_pkt_map_sz;
-		break;
+			/* Select shadow register 0x1f */
+			tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x7c00);
+			tg3_readphy(tp, MII_TG3_MISC_SHDW, &phy1);
 
-	case RXD_OPAQUE_RING_JUMBO:
-		dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
-		desc = &tpr->rx_jmb[dest_idx].std;
-		map = &tpr->rx_jmb_buffers[dest_idx];
-		data_size = TG3_RX_JMB_MAP_SZ;
-		break;
+			/* Select expansion interrupt status register */
+			tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+					 MII_TG3_DSP_EXP1_INT_STAT);
+			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
+			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
 
-	default:
-		return -EINVAL;
-	}
+			if ((phy1 & 0x10) && !(phy2 & 0x20)) {
+				/* We have signal detect and not receiving
+				 * config code words, link is up by parallel
+				 * detection.
+				 */
 
-	/* Do not overwrite any of the map or rp information
-	 * until we are sure we can commit to a new buffer.
-	 *
-	 * Callers depend upon this behavior and assume that
-	 * we leave everything unchanged if we fail.
-	 */
-	skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
-		   SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-	data = kmalloc(skb_size, GFP_ATOMIC);
-	if (!data)
-		return -ENOMEM;
+				bmcr &= ~BMCR_ANENABLE;
+				bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
+				tg3_writephy(tp, MII_BMCR, bmcr);
+				tp->phy_flags |= TG3_PHYFLG_PARALLEL_DETECT;
+			}
+		}
+	} else if (netif_carrier_ok(tp->dev) &&
+		   (tp->link_config.autoneg == AUTONEG_ENABLE) &&
+		   (tp->phy_flags & TG3_PHYFLG_PARALLEL_DETECT)) {
+		u32 phy2;
 
-	mapping = pci_map_single(tp->pdev,
-				 data + TG3_RX_OFFSET(tp),
-				 data_size,
-				 PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(tp->pdev, mapping)) {
-		kfree(data);
-		return -EIO;
-	}
+		/* Select expansion interrupt status register */
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+				 MII_TG3_DSP_EXP1_INT_STAT);
+		tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &phy2);
+		if (phy2 & 0x20) {
+			u32 bmcr;
 
-	map->data = data;
-	dma_unmap_addr_set(map, mapping, mapping);
+			/* Config code words received, turn on autoneg. */
+			tg3_readphy(tp, MII_BMCR, &bmcr);
+			tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANENABLE);
 
-	desc->addr_hi = ((u64)mapping >> 32);
-	desc->addr_lo = ((u64)mapping & 0xffffffff);
+			tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
 
-	return data_size;
+		}
+	}
 }
 
-/* We only need to move over in the address because the other
- * members of the RX descriptor are invariant.  See notes above
- * tg3_alloc_rx_data for full details.
- */
-static void tg3_recycle_rx(struct tg3_napi *tnapi,
-			   struct tg3_rx_prodring_set *dpr,
-			   u32 opaque_key, int src_idx,
-			   u32 dest_idx_unmasked)
+static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 {
-	struct tg3 *tp = tnapi->tp;
-	struct tg3_rx_buffer_desc *src_desc, *dest_desc;
-	struct ring_info *src_map, *dest_map;
-	struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring;
-	int dest_idx;
+	u32 val;
+	int err;
 
-	switch (opaque_key) {
-	case RXD_OPAQUE_RING_STD:
-		dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
-		dest_desc = &dpr->rx_std[dest_idx];
-		dest_map = &dpr->rx_std_buffers[dest_idx];
-		src_desc = &spr->rx_std[src_idx];
-		src_map = &spr->rx_std_buffers[src_idx];
-		break;
+	if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
+		err = tg3_setup_fiber_phy(tp, force_reset);
+	else if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
+		err = tg3_setup_fiber_mii_phy(tp, force_reset);
+	else
+		err = tg3_setup_copper_phy(tp, force_reset);
 
-	case RXD_OPAQUE_RING_JUMBO:
-		dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
-		dest_desc = &dpr->rx_jmb[dest_idx].std;
-		dest_map = &dpr->rx_jmb_buffers[dest_idx];
-		src_desc = &spr->rx_jmb[src_idx].std;
-		src_map = &spr->rx_jmb_buffers[src_idx];
-		break;
+	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
+		u32 scale;
 
-	default:
-		return;
+		val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
+		if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5)
+			scale = 65;
+		else if (val == CPMU_CLCK_STAT_MAC_CLCK_6_25)
+			scale = 6;
+		else
+			scale = 12;
+
+		val = tr32(GRC_MISC_CFG) & ~GRC_MISC_CFG_PRESCALAR_MASK;
+		val |= (scale << GRC_MISC_CFG_PRESCALAR_SHIFT);
+		tw32(GRC_MISC_CFG, val);
 	}
 
-	dest_map->data = src_map->data;
-	dma_unmap_addr_set(dest_map, mapping,
-			   dma_unmap_addr(src_map, mapping));
-	dest_desc->addr_hi = src_desc->addr_hi;
-	dest_desc->addr_lo = src_desc->addr_lo;
+	val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+	      (6 << TX_LENGTHS_IPG_SHIFT);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		val |= tr32(MAC_TX_LENGTHS) &
+		       (TX_LENGTHS_JMB_FRM_LEN_MSK |
+			TX_LENGTHS_CNT_DWN_VAL_MSK);
 
-	/* Ensure that the update to the skb happens after the physical
-	 * addresses have been transferred to the new BD location.
-	 */
-	smp_wmb();
+	if (tp->link_config.active_speed == SPEED_1000 &&
+	    tp->link_config.active_duplex == DUPLEX_HALF)
+		tw32(MAC_TX_LENGTHS, val |
+		     (0xff << TX_LENGTHS_SLOT_TIME_SHIFT));
+	else
+		tw32(MAC_TX_LENGTHS, val |
+		     (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
 
-	src_map->data = NULL;
-}
+	if (!tg3_flag(tp, 5705_PLUS)) {
+		if (netif_carrier_ok(tp->dev)) {
+			tw32(HOSTCC_STAT_COAL_TICKS,
+			     tp->coal.stats_block_coalesce_usecs);
+		} else {
+			tw32(HOSTCC_STAT_COAL_TICKS, 0);
+		}
+	}
 
-/* The RX ring scheme is composed of multiple rings which post fresh
- * buffers to the chip, and one special ring the chip uses to report
- * status back to the host.
- *
- * The special ring reports the status of received packets to the
- * host.  The chip does not write into the original descriptor the
- * RX buffer was obtained from.  The chip simply takes the original
- * descriptor as provided by the host, updates the status and length
- * field, then writes this into the next status ring entry.
- *
- * Each ring the host uses to post buffers to the chip is described
- * by a TG3_BDINFO entry in the chips SRAM area.  When a packet arrives,
- * it is first placed into the on-chip ram.  When the packet's length
- * is known, it walks down the TG3_BDINFO entries to select the ring.
- * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO
- * which is within the range of the new packet's length is chosen.
- *
- * The "separate ring for rx status" scheme may sound queer, but it makes
- * sense from a cache coherency perspective.  If only the host writes
- * to the buffer post rings, and only the chip writes to the rx status
- * rings, then cache lines never move beyond shared-modified state.
- * If both the host and chip were to write into the same ring, cache line
- * eviction could occur since both entities want it in an exclusive state.
- */
-static int tg3_rx(struct tg3_napi *tnapi, int budget)
-{
-	struct tg3 *tp = tnapi->tp;
-	u32 work_mask, rx_std_posted = 0;
-	u32 std_prod_idx, jmb_prod_idx;
-	u32 sw_idx = tnapi->rx_rcb_ptr;
-	u16 hw_idx;
-	int received;
-	struct tg3_rx_prodring_set *tpr = &tnapi->prodring;
+	if (tg3_flag(tp, ASPM_WORKAROUND)) {
+		val = tr32(PCIE_PWR_MGMT_THRESH);
+		if (!netif_carrier_ok(tp->dev))
+			val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) |
+			      tp->pwrmgmt_thresh;
+		else
+			val |= PCIE_PWR_MGMT_L1_THRESH_MSK;
+		tw32(PCIE_PWR_MGMT_THRESH, val);
+	}
 
-	hw_idx = *(tnapi->rx_rcb_prod_idx);
-	/*
-	 * We need to order the read of hw_idx and the read of
-	 * the opaque cookie.
-	 */
-	rmb();
-	work_mask = 0;
-	received = 0;
-	std_prod_idx = tpr->rx_std_prod_idx;
-	jmb_prod_idx = tpr->rx_jmb_prod_idx;
-	while (sw_idx != hw_idx && budget > 0) {
-		struct ring_info *ri;
-		struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
-		unsigned int len;
-		struct sk_buff *skb;
-		dma_addr_t dma_addr;
-		u32 opaque_key, desc_idx, *post_ptr;
-		u8 *data;
+	return err;
+}
 
-		desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
-		opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
-		if (opaque_key == RXD_OPAQUE_RING_STD) {
-			ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx];
-			dma_addr = dma_unmap_addr(ri, mapping);
-			data = ri->data;
-			post_ptr = &std_prod_idx;
-			rx_std_posted++;
-		} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
-			ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx];
-			dma_addr = dma_unmap_addr(ri, mapping);
-			data = ri->data;
-			post_ptr = &jmb_prod_idx;
-		} else
-			goto next_pkt_nopost;
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+	return tp->irq_sync;
+}
 
-		work_mask |= opaque_key;
+static inline void tg3_rd32_loop(struct tg3 *tp, u32 *dst, u32 off, u32 len)
+{
+	int i;
 
-		if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
-		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
-		drop_it:
-			tg3_recycle_rx(tnapi, tpr, opaque_key,
-				       desc_idx, *post_ptr);
-		drop_it_no_recycle:
-			/* Other statistics kept track of by card. */
-			tp->rx_dropped++;
-			goto next_pkt;
-		}
+	dst = (u32 *)((u8 *)dst + off);
+	for (i = 0; i < len; i += sizeof(u32))
+		*dst++ = tr32(off + i);
+}
 
-		prefetch(data + TG3_RX_OFFSET(tp));
-		len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -
-		      ETH_FCS_LEN;
+static void tg3_dump_legacy_regs(struct tg3 *tp, u32 *regs)
+{
+	tg3_rd32_loop(tp, regs, TG3PCI_VENDOR, 0xb0);
+	tg3_rd32_loop(tp, regs, MAILBOX_INTERRUPT_0, 0x200);
+	tg3_rd32_loop(tp, regs, MAC_MODE, 0x4f0);
+	tg3_rd32_loop(tp, regs, SNDDATAI_MODE, 0xe0);
+	tg3_rd32_loop(tp, regs, SNDDATAC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, SNDBDS_MODE, 0x80);
+	tg3_rd32_loop(tp, regs, SNDBDI_MODE, 0x48);
+	tg3_rd32_loop(tp, regs, SNDBDC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, RCVLPC_MODE, 0x20);
+	tg3_rd32_loop(tp, regs, RCVLPC_SELLST_BASE, 0x15c);
+	tg3_rd32_loop(tp, regs, RCVDBDI_MODE, 0x0c);
+	tg3_rd32_loop(tp, regs, RCVDBDI_JUMBO_BD, 0x3c);
+	tg3_rd32_loop(tp, regs, RCVDBDI_BD_PROD_IDX_0, 0x44);
+	tg3_rd32_loop(tp, regs, RCVDCC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, RCVBDI_MODE, 0x20);
+	tg3_rd32_loop(tp, regs, RCVCC_MODE, 0x14);
+	tg3_rd32_loop(tp, regs, RCVLSC_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, MBFREE_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, HOSTCC_MODE, 0x100);
 
-		if (len > TG3_RX_COPY_THRESH(tp)) {
-			int skb_size;
+	if (tg3_flag(tp, SUPPORT_MSIX))
+		tg3_rd32_loop(tp, regs, HOSTCC_RXCOL_TICKS_VEC1, 0x180);
 
-			skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key,
-						    *post_ptr);
-			if (skb_size < 0)
-				goto drop_it;
-
-			pci_unmap_single(tp->pdev, dma_addr, skb_size,
-					 PCI_DMA_FROMDEVICE);
-
-			skb = build_skb(data);
-			if (!skb) {
-				kfree(data);
-				goto drop_it_no_recycle;
-			}
-			skb_reserve(skb, TG3_RX_OFFSET(tp));
-			/* Ensure that the update to the data happens
-			 * after the usage of the old DMA mapping.
-			 */
-			smp_wmb();
-
-			ri->data = NULL;
+	tg3_rd32_loop(tp, regs, MEMARB_MODE, 0x10);
+	tg3_rd32_loop(tp, regs, BUFMGR_MODE, 0x58);
+	tg3_rd32_loop(tp, regs, RDMAC_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, WDMAC_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, RX_CPU_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, RX_CPU_STATE, 0x04);
+	tg3_rd32_loop(tp, regs, RX_CPU_PGMCTR, 0x04);
+	tg3_rd32_loop(tp, regs, RX_CPU_HWBKPT, 0x04);
 
-		} else {
-			tg3_recycle_rx(tnapi, tpr, opaque_key,
-				       desc_idx, *post_ptr);
+	if (!tg3_flag(tp, 5705_PLUS)) {
+		tg3_rd32_loop(tp, regs, TX_CPU_MODE, 0x04);
+		tg3_rd32_loop(tp, regs, TX_CPU_STATE, 0x04);
+		tg3_rd32_loop(tp, regs, TX_CPU_PGMCTR, 0x04);
+	}
 
-			skb = netdev_alloc_skb(tp->dev,
-					       len + TG3_RAW_IP_ALIGN);
-			if (skb == NULL)
-				goto drop_it_no_recycle;
+	tg3_rd32_loop(tp, regs, GRCMBOX_INTERRUPT_0, 0x110);
+	tg3_rd32_loop(tp, regs, FTQ_RESET, 0x120);
+	tg3_rd32_loop(tp, regs, MSGINT_MODE, 0x0c);
+	tg3_rd32_loop(tp, regs, DMAC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, GRC_MODE, 0x4c);
 
-			skb_reserve(skb, TG3_RAW_IP_ALIGN);
-			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
-			memcpy(skb->data,
-			       data + TG3_RX_OFFSET(tp),
-			       len);
-			pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
-		}
+	if (tg3_flag(tp, NVRAM))
+		tg3_rd32_loop(tp, regs, NVRAM_CMD, 0x24);
+}
 
-		skb_put(skb, len);
-		if ((tp->dev->features & NETIF_F_RXCSUM) &&
-		    (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
-		    (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
-		      >> RXD_TCPCSUM_SHIFT) == 0xffff))
-			skb->ip_summed = CHECKSUM_UNNECESSARY;
-		else
-			skb_checksum_none_assert(skb);
+static void tg3_dump_state(struct tg3 *tp)
+{
+	int i;
+	u32 *regs;
 
-		skb->protocol = eth_type_trans(skb, tp->dev);
+	regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC);
+	if (!regs) {
+		netdev_err(tp->dev, "Failed allocating register dump buffer\n");
+		return;
+	}
 
-		if (len > (tp->dev->mtu + ETH_HLEN) &&
-		    skb->protocol != htons(ETH_P_8021Q)) {
-			dev_kfree_skb(skb);
-			goto drop_it_no_recycle;
-		}
+	if (tg3_flag(tp, PCI_EXPRESS)) {
+		/* Read up to but not including private PCI registers */
+		for (i = 0; i < TG3_PCIE_TLDLPL_PORT; i += sizeof(u32))
+			regs[i / sizeof(u32)] = tr32(i);
+	} else
+		tg3_dump_legacy_regs(tp, regs);
 
-		if (desc->type_flags & RXD_FLAG_VLAN &&
-		    !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG))
-			__vlan_hwaccel_put_tag(skb,
-					       desc->err_vlan & RXD_VLAN_MASK);
+	for (i = 0; i < TG3_REG_BLK_SIZE / sizeof(u32); i += 4) {
+		if (!regs[i + 0] && !regs[i + 1] &&
+		    !regs[i + 2] && !regs[i + 3])
+			continue;
 
-		napi_gro_receive(&tnapi->napi, skb);
+		netdev_err(tp->dev, "0x%08x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+			   i * 4,
+			   regs[i + 0], regs[i + 1], regs[i + 2], regs[i + 3]);
+	}
 
-		received++;
-		budget--;
+	kfree(regs);
 
-next_pkt:
-		(*post_ptr)++;
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
 
-		if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
-			tpr->rx_std_prod_idx = std_prod_idx &
-					       tp->rx_std_ring_mask;
-			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
-				     tpr->rx_std_prod_idx);
-			work_mask &= ~RXD_OPAQUE_RING_STD;
-			rx_std_posted = 0;
-		}
-next_pkt_nopost:
-		sw_idx++;
-		sw_idx &= tp->rx_ret_ring_mask;
+		/* SW status block */
+		netdev_err(tp->dev,
+			 "%d: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
+			   i,
+			   tnapi->hw_status->status,
+			   tnapi->hw_status->status_tag,
+			   tnapi->hw_status->rx_jumbo_consumer,
+			   tnapi->hw_status->rx_consumer,
+			   tnapi->hw_status->rx_mini_consumer,
+			   tnapi->hw_status->idx[0].rx_producer,
+			   tnapi->hw_status->idx[0].tx_consumer);
 
-		/* Refresh hw_idx to see if there is new work */
-		if (sw_idx == hw_idx) {
-			hw_idx = *(tnapi->rx_rcb_prod_idx);
-			rmb();
-		}
+		netdev_err(tp->dev,
+		"%d: NAPI info [%08x:%08x:(%04x:%04x:%04x):%04x:(%04x:%04x:%04x:%04x)]\n",
+			   i,
+			   tnapi->last_tag, tnapi->last_irq_tag,
+			   tnapi->tx_prod, tnapi->tx_cons, tnapi->tx_pending,
+			   tnapi->rx_rcb_ptr,
+			   tnapi->prodring.rx_std_prod_idx,
+			   tnapi->prodring.rx_std_cons_idx,
+			   tnapi->prodring.rx_jmb_prod_idx,
+			   tnapi->prodring.rx_jmb_cons_idx);
 	}
+}
 
-	/* ACK the status ring. */
-	tnapi->rx_rcb_ptr = sw_idx;
-	tw32_rx_mbox(tnapi->consmbox, sw_idx);
-
-	/* Refill RX ring(s). */
-	if (!tg3_flag(tp, ENABLE_RSS)) {
-		if (work_mask & RXD_OPAQUE_RING_STD) {
-			tpr->rx_std_prod_idx = std_prod_idx &
-					       tp->rx_std_ring_mask;
-			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
-				     tpr->rx_std_prod_idx);
-		}
-		if (work_mask & RXD_OPAQUE_RING_JUMBO) {
-			tpr->rx_jmb_prod_idx = jmb_prod_idx &
-					       tp->rx_jmb_ring_mask;
-			tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
-				     tpr->rx_jmb_prod_idx);
-		}
-		mmiowb();
-	} else if (work_mask) {
-		/* rx_std_buffers[] and rx_jmb_buffers[] entries must be
-		 * updated before the producer indices can be updated.
-		 */
-		smp_wmb();
-
-		tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask;
-		tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask;
+/* This is called whenever we suspect that the system chipset is re-
+ * ordering the sequence of MMIO to the tx send mailbox. The symptom
+ * is bogus tx completions. We try to recover by setting the
+ * TG3_FLAG_MBOX_WRITE_REORDER flag and resetting the chip later
+ * in the workqueue.
+ */
+static void tg3_tx_recover(struct tg3 *tp)
+{
+	BUG_ON(tg3_flag(tp, MBOX_WRITE_REORDER) ||
+	       tp->write32_tx_mbox == tg3_write_indirect_mbox);
 
-		if (tnapi != &tp->napi[1])
-			napi_schedule(&tp->napi[1].napi);
-	}
+	netdev_warn(tp->dev,
+		    "The system may be re-ordering memory-mapped I/O "
+		    "cycles to the network device, attempting to recover. "
+		    "Please report the problem to the driver maintainer "
+		    "and include system chipset information.\n");
 
-	return received;
+	spin_lock(&tp->lock);
+	tg3_flag_set(tp, TX_RECOVERY_PENDING);
+	spin_unlock(&tp->lock);
 }
 
-static void tg3_poll_link(struct tg3 *tp)
+static inline u32 tg3_tx_avail(struct tg3_napi *tnapi)
 {
-	/* handle link change and other phy events */
-	if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
-		struct tg3_hw_status *sblk = tp->napi[0].hw_status;
-
-		if (sblk->status & SD_STATUS_LINK_CHG) {
-			sblk->status = SD_STATUS_UPDATED |
-				       (sblk->status & ~SD_STATUS_LINK_CHG);
-			spin_lock(&tp->lock);
-			if (tg3_flag(tp, USE_PHYLIB)) {
-				tw32_f(MAC_STATUS,
-				     (MAC_STATUS_SYNC_CHANGED |
-				      MAC_STATUS_CFG_CHANGED |
-				      MAC_STATUS_MI_COMPLETION |
-				      MAC_STATUS_LNKSTATE_CHANGED));
-				udelay(40);
-			} else
-				tg3_setup_phy(tp, 0);
-			spin_unlock(&tp->lock);
-		}
-	}
+	/* Tell compiler to fetch tx indices from memory. */
+	barrier();
+	return tnapi->tx_pending -
+	       ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1));
 }
 
-static int tg3_rx_prodring_xfer(struct tg3 *tp,
-				struct tg3_rx_prodring_set *dpr,
-				struct tg3_rx_prodring_set *spr)
+/* Tigon3 never reports partial packet sends.  So we do not
+ * need special logic to handle SKBs that have not had all
+ * of their frags sent yet, like SunGEM does.
+ */
+static void tg3_tx(struct tg3_napi *tnapi)
 {
-	u32 si, di, cpycnt, src_prod_idx;
-	int i, err = 0;
+	struct tg3 *tp = tnapi->tp;
+	u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer;
+	u32 sw_idx = tnapi->tx_cons;
+	struct netdev_queue *txq;
+	int index = tnapi - tp->napi;
+	unsigned int pkts_compl = 0, bytes_compl = 0;
 
-	while (1) {
-		src_prod_idx = spr->rx_std_prod_idx;
+	if (tg3_flag(tp, ENABLE_TSS))
+		index--;
 
-		/* Make sure updates to the rx_std_buffers[] entries and the
-		 * standard producer index are seen in the correct order.
-		 */
-		smp_rmb();
+	txq = netdev_get_tx_queue(tp->dev, index);
 
-		if (spr->rx_std_cons_idx == src_prod_idx)
-			break;
+	while (sw_idx != hw_idx) {
+		struct tg3_tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];
+		struct sk_buff *skb = ri->skb;
+		int i, tx_bug = 0;
 
-		if (spr->rx_std_cons_idx < src_prod_idx)
-			cpycnt = src_prod_idx - spr->rx_std_cons_idx;
-		else
-			cpycnt = tp->rx_std_ring_mask + 1 -
-				 spr->rx_std_cons_idx;
+		if (unlikely(skb == NULL)) {
+			tg3_tx_recover(tp);
+			return;
+		}
 
-		cpycnt = min(cpycnt,
-			     tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx);
-
-		si = spr->rx_std_cons_idx;
-		di = dpr->rx_std_prod_idx;
-
-		for (i = di; i < di + cpycnt; i++) {
-			if (dpr->rx_std_buffers[i].data) {
-				cpycnt = i - di;
-				err = -ENOSPC;
-				break;
-			}
-		}
-
-		if (!cpycnt)
-			break;
-
-		/* Ensure that updates to the rx_std_buffers ring and the
-		 * shadowed hardware producer ring from tg3_recycle_skb() are
-		 * ordered correctly WRT the skb check above.
-		 */
-		smp_rmb();
+		pci_unmap_single(tp->pdev,
+				 dma_unmap_addr(ri, mapping),
+				 skb_headlen(skb),
+				 PCI_DMA_TODEVICE);
 
-		memcpy(&dpr->rx_std_buffers[di],
-		       &spr->rx_std_buffers[si],
-		       cpycnt * sizeof(struct ring_info));
+		ri->skb = NULL;
 
-		for (i = 0; i < cpycnt; i++, di++, si++) {
-			struct tg3_rx_buffer_desc *sbd, *dbd;
-			sbd = &spr->rx_std[si];
-			dbd = &dpr->rx_std[di];
-			dbd->addr_hi = sbd->addr_hi;
-			dbd->addr_lo = sbd->addr_lo;
+		while (ri->fragmented) {
+			ri->fragmented = false;
+			sw_idx = NEXT_TX(sw_idx);
+			ri = &tnapi->tx_buffers[sw_idx];
 		}
 
-		spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) &
-				       tp->rx_std_ring_mask;
-		dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) &
-				       tp->rx_std_ring_mask;
-	}
+		sw_idx = NEXT_TX(sw_idx);
 
-	while (1) {
-		src_prod_idx = spr->rx_jmb_prod_idx;
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			ri = &tnapi->tx_buffers[sw_idx];
+			if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
+				tx_bug = 1;
 
-		/* Make sure updates to the rx_jmb_buffers[] entries and
-		 * the jumbo producer index are seen in the correct order.
-		 */
-		smp_rmb();
+			pci_unmap_page(tp->pdev,
+				       dma_unmap_addr(ri, mapping),
+				       skb_frag_size(&skb_shinfo(skb)->frags[i]),
+				       PCI_DMA_TODEVICE);
 
-		if (spr->rx_jmb_cons_idx == src_prod_idx)
-			break;
+			while (ri->fragmented) {
+				ri->fragmented = false;
+				sw_idx = NEXT_TX(sw_idx);
+				ri = &tnapi->tx_buffers[sw_idx];
+			}
 
-		if (spr->rx_jmb_cons_idx < src_prod_idx)
-			cpycnt = src_prod_idx - spr->rx_jmb_cons_idx;
-		else
-			cpycnt = tp->rx_jmb_ring_mask + 1 -
-				 spr->rx_jmb_cons_idx;
+			sw_idx = NEXT_TX(sw_idx);
+		}
 
-		cpycnt = min(cpycnt,
-			     tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx);
+		pkts_compl++;
+		bytes_compl += skb->len;
 
-		si = spr->rx_jmb_cons_idx;
-		di = dpr->rx_jmb_prod_idx;
+		dev_kfree_skb(skb);
 
-		for (i = di; i < di + cpycnt; i++) {
-			if (dpr->rx_jmb_buffers[i].data) {
-				cpycnt = i - di;
-				err = -ENOSPC;
-				break;
-			}
+		if (unlikely(tx_bug)) {
+			tg3_tx_recover(tp);
+			return;
 		}
+	}
 
-		if (!cpycnt)
-			break;
-
-		/* Ensure that updates to the rx_jmb_buffers ring and the
-		 * shadowed hardware producer ring from tg3_recycle_skb() are
-		 * ordered correctly WRT the skb check above.
-		 */
-		smp_rmb();
+	netdev_completed_queue(tp->dev, pkts_compl, bytes_compl);
 
-		memcpy(&dpr->rx_jmb_buffers[di],
-		       &spr->rx_jmb_buffers[si],
-		       cpycnt * sizeof(struct ring_info));
+	tnapi->tx_cons = sw_idx;
 
-		for (i = 0; i < cpycnt; i++, di++, si++) {
-			struct tg3_rx_buffer_desc *sbd, *dbd;
-			sbd = &spr->rx_jmb[si].std;
-			dbd = &dpr->rx_jmb[di].std;
-			dbd->addr_hi = sbd->addr_hi;
-			dbd->addr_lo = sbd->addr_lo;
-		}
+	/* Need to make the tx_cons update visible to tg3_start_xmit()
+	 * before checking for netif_queue_stopped().  Without the
+	 * memory barrier, there is a small possibility that tg3_start_xmit()
+	 * will miss it and cause the queue to be stopped forever.
+	 */
+	smp_mb();
 
-		spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) &
-				       tp->rx_jmb_ring_mask;
-		dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) &
-				       tp->rx_jmb_ring_mask;
+	if (unlikely(netif_tx_queue_stopped(txq) &&
+		     (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) {
+		__netif_tx_lock(txq, smp_processor_id());
+		if (netif_tx_queue_stopped(txq) &&
+		    (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
+			netif_tx_wake_queue(txq);
+		__netif_tx_unlock(txq);
 	}
-
-	return err;
 }
 
-static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
+static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
 {
-	struct tg3 *tp = tnapi->tp;
-
-	/* run TX completion thread */
-	if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
-		tg3_tx(tnapi);
-		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
-			return work_done;
-	}
-
-	/* run RX thread, within the bounds set by NAPI.
-	 * All RX "locking" is done by ensuring outside
-	 * code synchronizes with tg3->napi.poll()
-	 */
-	if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
-		work_done += tg3_rx(tnapi, budget - work_done);
+	if (!ri->data)
+		return;
 
-	if (tg3_flag(tp, ENABLE_RSS) && tnapi == &tp->napi[1]) {
-		struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
-		int i, err = 0;
-		u32 std_prod_idx = dpr->rx_std_prod_idx;
-		u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
+	pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping),
+			 map_sz, PCI_DMA_FROMDEVICE);
+	kfree(ri->data);
+	ri->data = NULL;
+}
 
-		for (i = 1; i < tp->irq_cnt; i++)
-			err |= tg3_rx_prodring_xfer(tp, dpr,
-						    &tp->napi[i].prodring);
+/* Returns size of skb allocated or < 0 on error.
+ *
+ * We only need to fill in the address because the other members
+ * of the RX descriptor are invariant, see tg3_init_rings.
+ *
+ * Note the purposeful assymetry of cpu vs. chip accesses.  For
+ * posting buffers we only dirty the first cache line of the RX
+ * descriptor (containing the address).  Whereas for the RX status
+ * buffers the cpu only reads the last cacheline of the RX descriptor
+ * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
+ */
+static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
+			    u32 opaque_key, u32 dest_idx_unmasked)
+{
+	struct tg3_rx_buffer_desc *desc;
+	struct ring_info *map;
+	u8 *data;
+	dma_addr_t mapping;
+	int skb_size, data_size, dest_idx;
 
-		wmb();
+	switch (opaque_key) {
+	case RXD_OPAQUE_RING_STD:
+		dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
+		desc = &tpr->rx_std[dest_idx];
+		map = &tpr->rx_std_buffers[dest_idx];
+		data_size = tp->rx_pkt_map_sz;
+		break;
 
-		if (std_prod_idx != dpr->rx_std_prod_idx)
-			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
-				     dpr->rx_std_prod_idx);
+	case RXD_OPAQUE_RING_JUMBO:
+		dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
+		desc = &tpr->rx_jmb[dest_idx].std;
+		map = &tpr->rx_jmb_buffers[dest_idx];
+		data_size = TG3_RX_JMB_MAP_SZ;
+		break;
 
-		if (jmb_prod_idx != dpr->rx_jmb_prod_idx)
-			tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
-				     dpr->rx_jmb_prod_idx);
+	default:
+		return -EINVAL;
+	}
 
-		mmiowb();
+	/* Do not overwrite any of the map or rp information
+	 * until we are sure we can commit to a new buffer.
+	 *
+	 * Callers depend upon this behavior and assume that
+	 * we leave everything unchanged if we fail.
+	 */
+	skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
+		   SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	data = kmalloc(skb_size, GFP_ATOMIC);
+	if (!data)
+		return -ENOMEM;
 
-		if (err)
-			tw32_f(HOSTCC_MODE, tp->coal_now);
+	mapping = pci_map_single(tp->pdev,
+				 data + TG3_RX_OFFSET(tp),
+				 data_size,
+				 PCI_DMA_FROMDEVICE);
+	if (pci_dma_mapping_error(tp->pdev, mapping)) {
+		kfree(data);
+		return -EIO;
 	}
 
-	return work_done;
-}
+	map->data = data;
+	dma_unmap_addr_set(map, mapping, mapping);
 
-static inline void tg3_reset_task_schedule(struct tg3 *tp)
-{
-	if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags))
-		schedule_work(&tp->reset_task);
-}
+	desc->addr_hi = ((u64)mapping >> 32);
+	desc->addr_lo = ((u64)mapping & 0xffffffff);
 
-static inline void tg3_reset_task_cancel(struct tg3 *tp)
-{
-	cancel_work_sync(&tp->reset_task);
-	tg3_flag_clear(tp, RESET_TASK_PENDING);
+	return data_size;
 }
 
-static int tg3_poll_msix(struct napi_struct *napi, int budget)
+/* We only need to move over in the address because the other
+ * members of the RX descriptor are invariant.  See notes above
+ * tg3_alloc_rx_data for full details.
+ */
+static void tg3_recycle_rx(struct tg3_napi *tnapi,
+			   struct tg3_rx_prodring_set *dpr,
+			   u32 opaque_key, int src_idx,
+			   u32 dest_idx_unmasked)
 {
-	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
 	struct tg3 *tp = tnapi->tp;
-	int work_done = 0;
-	struct tg3_hw_status *sblk = tnapi->hw_status;
-
-	while (1) {
-		work_done = tg3_poll_work(tnapi, work_done, budget);
-
-		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
-			goto tx_recovery;
+	struct tg3_rx_buffer_desc *src_desc, *dest_desc;
+	struct ring_info *src_map, *dest_map;
+	struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring;
+	int dest_idx;
 
-		if (unlikely(work_done >= budget))
-			break;
+	switch (opaque_key) {
+	case RXD_OPAQUE_RING_STD:
+		dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask;
+		dest_desc = &dpr->rx_std[dest_idx];
+		dest_map = &dpr->rx_std_buffers[dest_idx];
+		src_desc = &spr->rx_std[src_idx];
+		src_map = &spr->rx_std_buffers[src_idx];
+		break;
 
-		/* tp->last_tag is used in tg3_int_reenable() below
-		 * to tell the hw how much work has been processed,
-		 * so we must read it before checking for more work.
-		 */
-		tnapi->last_tag = sblk->status_tag;
-		tnapi->last_irq_tag = tnapi->last_tag;
-		rmb();
+	case RXD_OPAQUE_RING_JUMBO:
+		dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask;
+		dest_desc = &dpr->rx_jmb[dest_idx].std;
+		dest_map = &dpr->rx_jmb_buffers[dest_idx];
+		src_desc = &spr->rx_jmb[src_idx].std;
+		src_map = &spr->rx_jmb_buffers[src_idx];
+		break;
 
-		/* check for RX/TX work to do */
-		if (likely(sblk->idx[0].tx_consumer == tnapi->tx_cons &&
-			   *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr)) {
-			napi_complete(napi);
-			/* Reenable interrupts. */
-			tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
-			mmiowb();
-			break;
-		}
+	default:
+		return;
 	}
 
-	return work_done;
+	dest_map->data = src_map->data;
+	dma_unmap_addr_set(dest_map, mapping,
+			   dma_unmap_addr(src_map, mapping));
+	dest_desc->addr_hi = src_desc->addr_hi;
+	dest_desc->addr_lo = src_desc->addr_lo;
 
-tx_recovery:
-	/* work_done is guaranteed to be less than budget. */
-	napi_complete(napi);
-	tg3_reset_task_schedule(tp);
-	return work_done;
+	/* Ensure that the update to the skb happens after the physical
+	 * addresses have been transferred to the new BD location.
+	 */
+	smp_wmb();
+
+	src_map->data = NULL;
 }
 
-static void tg3_process_error(struct tg3 *tp)
+/* The RX ring scheme is composed of multiple rings which post fresh
+ * buffers to the chip, and one special ring the chip uses to report
+ * status back to the host.
+ *
+ * The special ring reports the status of received packets to the
+ * host.  The chip does not write into the original descriptor the
+ * RX buffer was obtained from.  The chip simply takes the original
+ * descriptor as provided by the host, updates the status and length
+ * field, then writes this into the next status ring entry.
+ *
+ * Each ring the host uses to post buffers to the chip is described
+ * by a TG3_BDINFO entry in the chips SRAM area.  When a packet arrives,
+ * it is first placed into the on-chip ram.  When the packet's length
+ * is known, it walks down the TG3_BDINFO entries to select the ring.
+ * Each TG3_BDINFO specifies a MAXLEN field and the first TG3_BDINFO
+ * which is within the range of the new packet's length is chosen.
+ *
+ * The "separate ring for rx status" scheme may sound queer, but it makes
+ * sense from a cache coherency perspective.  If only the host writes
+ * to the buffer post rings, and only the chip writes to the rx status
+ * rings, then cache lines never move beyond shared-modified state.
+ * If both the host and chip were to write into the same ring, cache line
+ * eviction could occur since both entities want it in an exclusive state.
+ */
+static int tg3_rx(struct tg3_napi *tnapi, int budget)
 {
-	u32 val;
-	bool real_error = false;
+	struct tg3 *tp = tnapi->tp;
+	u32 work_mask, rx_std_posted = 0;
+	u32 std_prod_idx, jmb_prod_idx;
+	u32 sw_idx = tnapi->rx_rcb_ptr;
+	u16 hw_idx;
+	int received;
+	struct tg3_rx_prodring_set *tpr = &tnapi->prodring;
 
-	if (tg3_flag(tp, ERROR_PROCESSED))
-		return;
+	hw_idx = *(tnapi->rx_rcb_prod_idx);
+	/*
+	 * We need to order the read of hw_idx and the read of
+	 * the opaque cookie.
+	 */
+	rmb();
+	work_mask = 0;
+	received = 0;
+	std_prod_idx = tpr->rx_std_prod_idx;
+	jmb_prod_idx = tpr->rx_jmb_prod_idx;
+	while (sw_idx != hw_idx && budget > 0) {
+		struct ring_info *ri;
+		struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
+		unsigned int len;
+		struct sk_buff *skb;
+		dma_addr_t dma_addr;
+		u32 opaque_key, desc_idx, *post_ptr;
+		u8 *data;
 
-	/* Check Flow Attention register */
-	val = tr32(HOSTCC_FLOW_ATTN);
-	if (val & ~HOSTCC_FLOW_ATTN_MBUF_LWM) {
-		netdev_err(tp->dev, "FLOW Attention error.  Resetting chip.\n");
-		real_error = true;
-	}
+		desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+		opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
+		if (opaque_key == RXD_OPAQUE_RING_STD) {
+			ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx];
+			dma_addr = dma_unmap_addr(ri, mapping);
+			data = ri->data;
+			post_ptr = &std_prod_idx;
+			rx_std_posted++;
+		} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
+			ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx];
+			dma_addr = dma_unmap_addr(ri, mapping);
+			data = ri->data;
+			post_ptr = &jmb_prod_idx;
+		} else
+			goto next_pkt_nopost;
 
-	if (tr32(MSGINT_STATUS) & ~MSGINT_STATUS_MSI_REQ) {
-		netdev_err(tp->dev, "MSI Status error.  Resetting chip.\n");
-		real_error = true;
-	}
+		work_mask |= opaque_key;
 
-	if (tr32(RDMAC_STATUS) || tr32(WDMAC_STATUS)) {
-		netdev_err(tp->dev, "DMA Status error.  Resetting chip.\n");
-		real_error = true;
-	}
+		if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
+		drop_it:
+			tg3_recycle_rx(tnapi, tpr, opaque_key,
+				       desc_idx, *post_ptr);
+		drop_it_no_recycle:
+			/* Other statistics kept track of by card. */
+			tp->rx_dropped++;
+			goto next_pkt;
+		}
 
-	if (!real_error)
-		return;
+		prefetch(data + TG3_RX_OFFSET(tp));
+		len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -
+		      ETH_FCS_LEN;
 
-	tg3_dump_state(tp);
+		if (len > TG3_RX_COPY_THRESH(tp)) {
+			int skb_size;
 
-	tg3_flag_set(tp, ERROR_PROCESSED);
-	tg3_reset_task_schedule(tp);
-}
+			skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key,
+						    *post_ptr);
+			if (skb_size < 0)
+				goto drop_it;
 
-static int tg3_poll(struct napi_struct *napi, int budget)
-{
-	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
-	struct tg3 *tp = tnapi->tp;
-	int work_done = 0;
-	struct tg3_hw_status *sblk = tnapi->hw_status;
+			pci_unmap_single(tp->pdev, dma_addr, skb_size,
+					 PCI_DMA_FROMDEVICE);
 
-	while (1) {
-		if (sblk->status & SD_STATUS_ERROR)
-			tg3_process_error(tp);
+			skb = build_skb(data);
+			if (!skb) {
+				kfree(data);
+				goto drop_it_no_recycle;
+			}
+			skb_reserve(skb, TG3_RX_OFFSET(tp));
+			/* Ensure that the update to the data happens
+			 * after the usage of the old DMA mapping.
+			 */
+			smp_wmb();
 
-		tg3_poll_link(tp);
+			ri->data = NULL;
 
-		work_done = tg3_poll_work(tnapi, work_done, budget);
+		} else {
+			tg3_recycle_rx(tnapi, tpr, opaque_key,
+				       desc_idx, *post_ptr);
 
-		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
-			goto tx_recovery;
+			skb = netdev_alloc_skb(tp->dev,
+					       len + TG3_RAW_IP_ALIGN);
+			if (skb == NULL)
+				goto drop_it_no_recycle;
 
-		if (unlikely(work_done >= budget))
-			break;
+			skb_reserve(skb, TG3_RAW_IP_ALIGN);
+			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
+			memcpy(skb->data,
+			       data + TG3_RX_OFFSET(tp),
+			       len);
+			pci_dma_sync_single_for_device(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
+		}
 
-		if (tg3_flag(tp, TAGGED_STATUS)) {
-			/* tp->last_tag is used in tg3_int_reenable() below
-			 * to tell the hw how much work has been processed,
-			 * so we must read it before checking for more work.
-			 */
-			tnapi->last_tag = sblk->status_tag;
-			tnapi->last_irq_tag = tnapi->last_tag;
-			rmb();
-		} else
-			sblk->status &= ~SD_STATUS_UPDATED;
+		skb_put(skb, len);
+		if ((tp->dev->features & NETIF_F_RXCSUM) &&
+		    (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
+		    (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
+		      >> RXD_TCPCSUM_SHIFT) == 0xffff))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb_checksum_none_assert(skb);
 
-		if (likely(!tg3_has_work(tnapi))) {
-			napi_complete(napi);
-			tg3_int_reenable(tnapi);
-			break;
-		}
-	}
+		skb->protocol = eth_type_trans(skb, tp->dev);
 
-	return work_done;
+		if (len > (tp->dev->mtu + ETH_HLEN) &&
+		    skb->protocol != htons(ETH_P_8021Q)) {
+			dev_kfree_skb(skb);
+			goto drop_it_no_recycle;
+		}
 
-tx_recovery:
-	/* work_done is guaranteed to be less than budget. */
-	napi_complete(napi);
-	tg3_reset_task_schedule(tp);
-	return work_done;
-}
+		if (desc->type_flags & RXD_FLAG_VLAN &&
+		    !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG))
+			__vlan_hwaccel_put_tag(skb,
+					       desc->err_vlan & RXD_VLAN_MASK);
 
-static void tg3_napi_disable(struct tg3 *tp)
-{
-	int i;
+		napi_gro_receive(&tnapi->napi, skb);
 
-	for (i = tp->irq_cnt - 1; i >= 0; i--)
-		napi_disable(&tp->napi[i].napi);
-}
+		received++;
+		budget--;
 
-static void tg3_napi_enable(struct tg3 *tp)
-{
-	int i;
+next_pkt:
+		(*post_ptr)++;
 
-	for (i = 0; i < tp->irq_cnt; i++)
-		napi_enable(&tp->napi[i].napi);
-}
+		if (unlikely(rx_std_posted >= tp->rx_std_max_post)) {
+			tpr->rx_std_prod_idx = std_prod_idx &
+					       tp->rx_std_ring_mask;
+			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+				     tpr->rx_std_prod_idx);
+			work_mask &= ~RXD_OPAQUE_RING_STD;
+			rx_std_posted = 0;
+		}
+next_pkt_nopost:
+		sw_idx++;
+		sw_idx &= tp->rx_ret_ring_mask;
 
-static void tg3_napi_init(struct tg3 *tp)
-{
-	int i;
+		/* Refresh hw_idx to see if there is new work */
+		if (sw_idx == hw_idx) {
+			hw_idx = *(tnapi->rx_rcb_prod_idx);
+			rmb();
+		}
+	}
 
-	netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64);
-	for (i = 1; i < tp->irq_cnt; i++)
-		netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64);
-}
+	/* ACK the status ring. */
+	tnapi->rx_rcb_ptr = sw_idx;
+	tw32_rx_mbox(tnapi->consmbox, sw_idx);
 
-static void tg3_napi_fini(struct tg3 *tp)
-{
-	int i;
+	/* Refill RX ring(s). */
+	if (!tg3_flag(tp, ENABLE_RSS)) {
+		if (work_mask & RXD_OPAQUE_RING_STD) {
+			tpr->rx_std_prod_idx = std_prod_idx &
+					       tp->rx_std_ring_mask;
+			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+				     tpr->rx_std_prod_idx);
+		}
+		if (work_mask & RXD_OPAQUE_RING_JUMBO) {
+			tpr->rx_jmb_prod_idx = jmb_prod_idx &
+					       tp->rx_jmb_ring_mask;
+			tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
+				     tpr->rx_jmb_prod_idx);
+		}
+		mmiowb();
+	} else if (work_mask) {
+		/* rx_std_buffers[] and rx_jmb_buffers[] entries must be
+		 * updated before the producer indices can be updated.
+		 */
+		smp_wmb();
 
-	for (i = 0; i < tp->irq_cnt; i++)
-		netif_napi_del(&tp->napi[i].napi);
-}
+		tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask;
+		tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask;
 
-static inline void tg3_netif_stop(struct tg3 *tp)
-{
-	tp->dev->trans_start = jiffies;	/* prevent tx timeout */
-	tg3_napi_disable(tp);
-	netif_tx_disable(tp->dev);
+		if (tnapi != &tp->napi[1])
+			napi_schedule(&tp->napi[1].napi);
+	}
+
+	return received;
 }
 
-static inline void tg3_netif_start(struct tg3 *tp)
+static void tg3_poll_link(struct tg3 *tp)
 {
-	/* NOTE: unconditional netif_tx_wake_all_queues is only
-	 * appropriate so long as all callers are assured to
-	 * have free tx slots (such as after tg3_init_hw)
-	 */
-	netif_tx_wake_all_queues(tp->dev);
+	/* handle link change and other phy events */
+	if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
+		struct tg3_hw_status *sblk = tp->napi[0].hw_status;
 
-	tg3_napi_enable(tp);
-	tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
-	tg3_enable_ints(tp);
+		if (sblk->status & SD_STATUS_LINK_CHG) {
+			sblk->status = SD_STATUS_UPDATED |
+				       (sblk->status & ~SD_STATUS_LINK_CHG);
+			spin_lock(&tp->lock);
+			if (tg3_flag(tp, USE_PHYLIB)) {
+				tw32_f(MAC_STATUS,
+				     (MAC_STATUS_SYNC_CHANGED |
+				      MAC_STATUS_CFG_CHANGED |
+				      MAC_STATUS_MI_COMPLETION |
+				      MAC_STATUS_LNKSTATE_CHANGED));
+				udelay(40);
+			} else
+				tg3_setup_phy(tp, 0);
+			spin_unlock(&tp->lock);
+		}
+	}
 }
 
-static void tg3_irq_quiesce(struct tg3 *tp)
+static int tg3_rx_prodring_xfer(struct tg3 *tp,
+				struct tg3_rx_prodring_set *dpr,
+				struct tg3_rx_prodring_set *spr)
 {
-	int i;
+	u32 si, di, cpycnt, src_prod_idx;
+	int i, err = 0;
 
-	BUG_ON(tp->irq_sync);
+	while (1) {
+		src_prod_idx = spr->rx_std_prod_idx;
 
-	tp->irq_sync = 1;
-	smp_mb();
+		/* Make sure updates to the rx_std_buffers[] entries and the
+		 * standard producer index are seen in the correct order.
+		 */
+		smp_rmb();
 
-	for (i = 0; i < tp->irq_cnt; i++)
-		synchronize_irq(tp->napi[i].irq_vec);
-}
+		if (spr->rx_std_cons_idx == src_prod_idx)
+			break;
 
-/* Fully shutdown all tg3 driver activity elsewhere in the system.
- * If irq_sync is non-zero, then the IRQ handler must be synchronized
- * with as well.  Most of the time, this is not necessary except when
- * shutting down the device.
- */
-static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
-{
-	spin_lock_bh(&tp->lock);
-	if (irq_sync)
-		tg3_irq_quiesce(tp);
-}
+		if (spr->rx_std_cons_idx < src_prod_idx)
+			cpycnt = src_prod_idx - spr->rx_std_cons_idx;
+		else
+			cpycnt = tp->rx_std_ring_mask + 1 -
+				 spr->rx_std_cons_idx;
 
-static inline void tg3_full_unlock(struct tg3 *tp)
-{
-	spin_unlock_bh(&tp->lock);
-}
+		cpycnt = min(cpycnt,
+			     tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx);
 
-/* One-shot MSI handler - Chip automatically disables interrupt
- * after sending MSI so driver doesn't have to do it.
- */
-static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
-{
-	struct tg3_napi *tnapi = dev_id;
-	struct tg3 *tp = tnapi->tp;
+		si = spr->rx_std_cons_idx;
+		di = dpr->rx_std_prod_idx;
 
-	prefetch(tnapi->hw_status);
-	if (tnapi->rx_rcb)
-		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+		for (i = di; i < di + cpycnt; i++) {
+			if (dpr->rx_std_buffers[i].data) {
+				cpycnt = i - di;
+				err = -ENOSPC;
+				break;
+			}
+		}
 
-	if (likely(!tg3_irq_sync(tp)))
-		napi_schedule(&tnapi->napi);
+		if (!cpycnt)
+			break;
 
-	return IRQ_HANDLED;
-}
+		/* Ensure that updates to the rx_std_buffers ring and the
+		 * shadowed hardware producer ring from tg3_recycle_skb() are
+		 * ordered correctly WRT the skb check above.
+		 */
+		smp_rmb();
 
-/* MSI ISR - No need to check for interrupt sharing and no need to
- * flush status block and interrupt mailbox. PCI ordering rules
- * guarantee that MSI will arrive after the status block.
- */
-static irqreturn_t tg3_msi(int irq, void *dev_id)
-{
-	struct tg3_napi *tnapi = dev_id;
-	struct tg3 *tp = tnapi->tp;
+		memcpy(&dpr->rx_std_buffers[di],
+		       &spr->rx_std_buffers[si],
+		       cpycnt * sizeof(struct ring_info));
 
-	prefetch(tnapi->hw_status);
-	if (tnapi->rx_rcb)
-		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
-	/*
-	 * Writing any value to intr-mbox-0 clears PCI INTA# and
-	 * chip-internal interrupt pending events.
-	 * Writing non-zero to intr-mbox-0 additional tells the
-	 * NIC to stop sending us irqs, engaging "in-intr-handler"
-	 * event coalescing.
-	 */
-	tw32_mailbox(tnapi->int_mbox, 0x00000001);
-	if (likely(!tg3_irq_sync(tp)))
-		napi_schedule(&tnapi->napi);
+		for (i = 0; i < cpycnt; i++, di++, si++) {
+			struct tg3_rx_buffer_desc *sbd, *dbd;
+			sbd = &spr->rx_std[si];
+			dbd = &dpr->rx_std[di];
+			dbd->addr_hi = sbd->addr_hi;
+			dbd->addr_lo = sbd->addr_lo;
+		}
 
-	return IRQ_RETVAL(1);
-}
+		spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) &
+				       tp->rx_std_ring_mask;
+		dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) &
+				       tp->rx_std_ring_mask;
+	}
 
-static irqreturn_t tg3_interrupt(int irq, void *dev_id)
-{
-	struct tg3_napi *tnapi = dev_id;
-	struct tg3 *tp = tnapi->tp;
-	struct tg3_hw_status *sblk = tnapi->hw_status;
-	unsigned int handled = 1;
+	while (1) {
+		src_prod_idx = spr->rx_jmb_prod_idx;
 
-	/* In INTx mode, it is possible for the interrupt to arrive at
-	 * the CPU before the status block posted prior to the interrupt.
-	 * Reading the PCI State register will confirm whether the
-	 * interrupt is ours and will flush the status block.
-	 */
-	if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
-		if (tg3_flag(tp, CHIP_RESETTING) ||
-		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
-			handled = 0;
-			goto out;
-		}
-	}
+		/* Make sure updates to the rx_jmb_buffers[] entries and
+		 * the jumbo producer index are seen in the correct order.
+		 */
+		smp_rmb();
 
-	/*
-	 * Writing any value to intr-mbox-0 clears PCI INTA# and
-	 * chip-internal interrupt pending events.
-	 * Writing non-zero to intr-mbox-0 additional tells the
-	 * NIC to stop sending us irqs, engaging "in-intr-handler"
-	 * event coalescing.
-	 *
-	 * Flush the mailbox to de-assert the IRQ immediately to prevent
-	 * spurious interrupts.  The flush impacts performance but
-	 * excessive spurious interrupts can be worse in some cases.
-	 */
-	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
-	if (tg3_irq_sync(tp))
-		goto out;
-	sblk->status &= ~SD_STATUS_UPDATED;
-	if (likely(tg3_has_work(tnapi))) {
-		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
-		napi_schedule(&tnapi->napi);
-	} else {
-		/* No work, shared interrupt perhaps?  re-enable
-		 * interrupts, and flush that PCI write
+		if (spr->rx_jmb_cons_idx == src_prod_idx)
+			break;
+
+		if (spr->rx_jmb_cons_idx < src_prod_idx)
+			cpycnt = src_prod_idx - spr->rx_jmb_cons_idx;
+		else
+			cpycnt = tp->rx_jmb_ring_mask + 1 -
+				 spr->rx_jmb_cons_idx;
+
+		cpycnt = min(cpycnt,
+			     tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx);
+
+		si = spr->rx_jmb_cons_idx;
+		di = dpr->rx_jmb_prod_idx;
+
+		for (i = di; i < di + cpycnt; i++) {
+			if (dpr->rx_jmb_buffers[i].data) {
+				cpycnt = i - di;
+				err = -ENOSPC;
+				break;
+			}
+		}
+
+		if (!cpycnt)
+			break;
+
+		/* Ensure that updates to the rx_jmb_buffers ring and the
+		 * shadowed hardware producer ring from tg3_recycle_skb() are
+		 * ordered correctly WRT the skb check above.
 		 */
-		tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-			       0x00000000);
+		smp_rmb();
+
+		memcpy(&dpr->rx_jmb_buffers[di],
+		       &spr->rx_jmb_buffers[si],
+		       cpycnt * sizeof(struct ring_info));
+
+		for (i = 0; i < cpycnt; i++, di++, si++) {
+			struct tg3_rx_buffer_desc *sbd, *dbd;
+			sbd = &spr->rx_jmb[si].std;
+			dbd = &dpr->rx_jmb[di].std;
+			dbd->addr_hi = sbd->addr_hi;
+			dbd->addr_lo = sbd->addr_lo;
+		}
+
+		spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) &
+				       tp->rx_jmb_ring_mask;
+		dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) &
+				       tp->rx_jmb_ring_mask;
 	}
-out:
-	return IRQ_RETVAL(handled);
+
+	return err;
 }
 
-static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
+static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
 {
-	struct tg3_napi *tnapi = dev_id;
 	struct tg3 *tp = tnapi->tp;
-	struct tg3_hw_status *sblk = tnapi->hw_status;
-	unsigned int handled = 1;
 
-	/* In INTx mode, it is possible for the interrupt to arrive at
-	 * the CPU before the status block posted prior to the interrupt.
-	 * Reading the PCI State register will confirm whether the
-	 * interrupt is ours and will flush the status block.
-	 */
-	if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) {
-		if (tg3_flag(tp, CHIP_RESETTING) ||
-		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
-			handled = 0;
-			goto out;
-		}
+	/* run TX completion thread */
+	if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
+		tg3_tx(tnapi);
+		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
+			return work_done;
 	}
 
-	/*
-	 * writing any value to intr-mbox-0 clears PCI INTA# and
-	 * chip-internal interrupt pending events.
-	 * writing non-zero to intr-mbox-0 additional tells the
-	 * NIC to stop sending us irqs, engaging "in-intr-handler"
-	 * event coalescing.
-	 *
-	 * Flush the mailbox to de-assert the IRQ immediately to prevent
-	 * spurious interrupts.  The flush impacts performance but
-	 * excessive spurious interrupts can be worse in some cases.
+	/* run RX thread, within the bounds set by NAPI.
+	 * All RX "locking" is done by ensuring outside
+	 * code synchronizes with tg3->napi.poll()
 	 */
-	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+	if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
+		work_done += tg3_rx(tnapi, budget - work_done);
 
-	/*
-	 * In a shared interrupt configuration, sometimes other devices'
-	 * interrupts will scream.  We record the current status tag here
-	 * so that the above check can report that the screaming interrupts
-	 * are unhandled.  Eventually they will be silenced.
-	 */
-	tnapi->last_irq_tag = sblk->status_tag;
+	if (tg3_flag(tp, ENABLE_RSS) && tnapi == &tp->napi[1]) {
+		struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
+		int i, err = 0;
+		u32 std_prod_idx = dpr->rx_std_prod_idx;
+		u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
 
-	if (tg3_irq_sync(tp))
-		goto out;
+		for (i = 1; i < tp->irq_cnt; i++)
+			err |= tg3_rx_prodring_xfer(tp, dpr,
+						    &tp->napi[i].prodring);
 
-	prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+		wmb();
 
-	napi_schedule(&tnapi->napi);
+		if (std_prod_idx != dpr->rx_std_prod_idx)
+			tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG,
+				     dpr->rx_std_prod_idx);
 
-out:
-	return IRQ_RETVAL(handled);
-}
+		if (jmb_prod_idx != dpr->rx_jmb_prod_idx)
+			tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
+				     dpr->rx_jmb_prod_idx);
 
-/* ISR for interrupt test */
-static irqreturn_t tg3_test_isr(int irq, void *dev_id)
-{
-	struct tg3_napi *tnapi = dev_id;
-	struct tg3 *tp = tnapi->tp;
-	struct tg3_hw_status *sblk = tnapi->hw_status;
+		mmiowb();
 
-	if ((sblk->status & SD_STATUS_UPDATED) ||
-	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
-		tg3_disable_ints(tp);
-		return IRQ_RETVAL(1);
+		if (err)
+			tw32_f(HOSTCC_MODE, tp->coal_now);
 	}
-	return IRQ_RETVAL(0);
-}
 
-static int tg3_init_hw(struct tg3 *, int);
-static int tg3_halt(struct tg3 *, int, int);
+	return work_done;
+}
 
-/* Restart hardware after configuration changes, self-test, etc.
- * Invoked with tp->lock held.
- */
-static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
-	__releases(tp->lock)
-	__acquires(tp->lock)
+static inline void tg3_reset_task_schedule(struct tg3 *tp)
 {
-	int err;
-
-	err = tg3_init_hw(tp, reset_phy);
-	if (err) {
-		netdev_err(tp->dev,
-			   "Failed to re-initialize device, aborting\n");
-		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-		tg3_full_unlock(tp);
-		del_timer_sync(&tp->timer);
-		tp->irq_sync = 0;
-		tg3_napi_enable(tp);
-		dev_close(tp->dev);
-		tg3_full_lock(tp, 0);
-	}
-	return err;
+	if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags))
+		schedule_work(&tp->reset_task);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void tg3_poll_controller(struct net_device *dev)
+static inline void tg3_reset_task_cancel(struct tg3 *tp)
 {
-	int i;
-	struct tg3 *tp = netdev_priv(dev);
-
-	for (i = 0; i < tp->irq_cnt; i++)
-		tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
+	cancel_work_sync(&tp->reset_task);
+	tg3_flag_clear(tp, RESET_TASK_PENDING);
 }
-#endif
 
-static void tg3_reset_task(struct work_struct *work)
+static int tg3_poll_msix(struct napi_struct *napi, int budget)
 {
-	struct tg3 *tp = container_of(work, struct tg3, reset_task);
-	int err;
-
-	tg3_full_lock(tp, 0);
-
-	if (!netif_running(tp->dev)) {
-		tg3_flag_clear(tp, RESET_TASK_PENDING);
-		tg3_full_unlock(tp);
-		return;
-	}
+	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
+	struct tg3 *tp = tnapi->tp;
+	int work_done = 0;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 
-	tg3_full_unlock(tp);
+	while (1) {
+		work_done = tg3_poll_work(tnapi, work_done, budget);
 
-	tg3_phy_stop(tp);
+		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
+			goto tx_recovery;
 
-	tg3_netif_stop(tp);
+		if (unlikely(work_done >= budget))
+			break;
 
-	tg3_full_lock(tp, 1);
+		/* tp->last_tag is used in tg3_int_reenable() below
+		 * to tell the hw how much work has been processed,
+		 * so we must read it before checking for more work.
+		 */
+		tnapi->last_tag = sblk->status_tag;
+		tnapi->last_irq_tag = tnapi->last_tag;
+		rmb();
 
-	if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
-		tp->write32_tx_mbox = tg3_write32_tx_mbox;
-		tp->write32_rx_mbox = tg3_write_flush_reg32;
-		tg3_flag_set(tp, MBOX_WRITE_REORDER);
-		tg3_flag_clear(tp, TX_RECOVERY_PENDING);
+		/* check for RX/TX work to do */
+		if (likely(sblk->idx[0].tx_consumer == tnapi->tx_cons &&
+			   *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr)) {
+			napi_complete(napi);
+			/* Reenable interrupts. */
+			tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
+			mmiowb();
+			break;
+		}
 	}
 
-	tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
-	err = tg3_init_hw(tp, 1);
-	if (err)
-		goto out;
-
-	tg3_netif_start(tp);
-
-out:
-	tg3_full_unlock(tp);
-
-	if (!err)
-		tg3_phy_start(tp);
+	return work_done;
 
-	tg3_flag_clear(tp, RESET_TASK_PENDING);
+tx_recovery:
+	/* work_done is guaranteed to be less than budget. */
+	napi_complete(napi);
+	tg3_reset_task_schedule(tp);
+	return work_done;
 }
 
-static void tg3_tx_timeout(struct net_device *dev)
+static void tg3_process_error(struct tg3 *tp)
 {
-	struct tg3 *tp = netdev_priv(dev);
+	u32 val;
+	bool real_error = false;
 
-	if (netif_msg_tx_err(tp)) {
-		netdev_err(dev, "transmit timed out, resetting\n");
-		tg3_dump_state(tp);
-	}
+	if (tg3_flag(tp, ERROR_PROCESSED))
+		return;
 
-	tg3_reset_task_schedule(tp);
-}
+	/* Check Flow Attention register */
+	val = tr32(HOSTCC_FLOW_ATTN);
+	if (val & ~HOSTCC_FLOW_ATTN_MBUF_LWM) {
+		netdev_err(tp->dev, "FLOW Attention error.  Resetting chip.\n");
+		real_error = true;
+	}
 
-/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
-static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
-{
-	u32 base = (u32) mapping & 0xffffffff;
+	if (tr32(MSGINT_STATUS) & ~MSGINT_STATUS_MSI_REQ) {
+		netdev_err(tp->dev, "MSI Status error.  Resetting chip.\n");
+		real_error = true;
+	}
 
-	return (base > 0xffffdcc0) && (base + len + 8 < base);
-}
+	if (tr32(RDMAC_STATUS) || tr32(WDMAC_STATUS)) {
+		netdev_err(tp->dev, "DMA Status error.  Resetting chip.\n");
+		real_error = true;
+	}
 
-/* Test for DMA addresses > 40-bit */
-static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
-					  int len)
-{
-#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
-	if (tg3_flag(tp, 40BIT_DMA_BUG))
-		return ((u64) mapping + len) > DMA_BIT_MASK(40);
-	return 0;
-#else
-	return 0;
-#endif
-}
+	if (!real_error)
+		return;
 
-static inline void tg3_tx_set_bd(struct tg3_tx_buffer_desc *txbd,
-				 dma_addr_t mapping, u32 len, u32 flags,
-				 u32 mss, u32 vlan)
-{
-	txbd->addr_hi = ((u64) mapping >> 32);
-	txbd->addr_lo = ((u64) mapping & 0xffffffff);
-	txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff);
-	txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT);
+	tg3_dump_state(tp);
+
+	tg3_flag_set(tp, ERROR_PROCESSED);
+	tg3_reset_task_schedule(tp);
 }
 
-static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
-			    dma_addr_t map, u32 len, u32 flags,
-			    u32 mss, u32 vlan)
+static int tg3_poll(struct napi_struct *napi, int budget)
 {
+	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
 	struct tg3 *tp = tnapi->tp;
-	bool hwbug = false;
-
-	if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8)
-		hwbug = true;
-
-	if (tg3_4g_overflow_test(map, len))
-		hwbug = true;
+	int work_done = 0;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 
-	if (tg3_40bit_overflow_test(tp, map, len))
-		hwbug = true;
+	while (1) {
+		if (sblk->status & SD_STATUS_ERROR)
+			tg3_process_error(tp);
 
-	if (tp->dma_limit) {
-		u32 prvidx = *entry;
-		u32 tmp_flag = flags & ~TXD_FLAG_END;
-		while (len > tp->dma_limit && *budget) {
-			u32 frag_len = tp->dma_limit;
-			len -= tp->dma_limit;
+		tg3_poll_link(tp);
 
-			/* Avoid the 8byte DMA problem */
-			if (len <= 8) {
-				len += tp->dma_limit / 2;
-				frag_len = tp->dma_limit / 2;
-			}
+		work_done = tg3_poll_work(tnapi, work_done, budget);
 
-			tnapi->tx_buffers[*entry].fragmented = true;
+		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
+			goto tx_recovery;
 
-			tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
-				      frag_len, tmp_flag, mss, vlan);
-			*budget -= 1;
-			prvidx = *entry;
-			*entry = NEXT_TX(*entry);
+		if (unlikely(work_done >= budget))
+			break;
 
-			map += frag_len;
-		}
+		if (tg3_flag(tp, TAGGED_STATUS)) {
+			/* tp->last_tag is used in tg3_int_reenable() below
+			 * to tell the hw how much work has been processed,
+			 * so we must read it before checking for more work.
+			 */
+			tnapi->last_tag = sblk->status_tag;
+			tnapi->last_irq_tag = tnapi->last_tag;
+			rmb();
+		} else
+			sblk->status &= ~SD_STATUS_UPDATED;
 
-		if (len) {
-			if (*budget) {
-				tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
-					      len, flags, mss, vlan);
-				*budget -= 1;
-				*entry = NEXT_TX(*entry);
-			} else {
-				hwbug = true;
-				tnapi->tx_buffers[prvidx].fragmented = false;
-			}
+		if (likely(!tg3_has_work(tnapi))) {
+			napi_complete(napi);
+			tg3_int_reenable(tnapi);
+			break;
 		}
-	} else {
-		tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
-			      len, flags, mss, vlan);
-		*entry = NEXT_TX(*entry);
 	}
 
-	return hwbug;
+	return work_done;
+
+tx_recovery:
+	/* work_done is guaranteed to be less than budget. */
+	napi_complete(napi);
+	tg3_reset_task_schedule(tp);
+	return work_done;
 }
 
-static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
+static void tg3_napi_disable(struct tg3 *tp)
 {
 	int i;
-	struct sk_buff *skb;
-	struct tg3_tx_ring_info *txb = &tnapi->tx_buffers[entry];
 
-	skb = txb->skb;
-	txb->skb = NULL;
+	for (i = tp->irq_cnt - 1; i >= 0; i--)
+		napi_disable(&tp->napi[i].napi);
+}
 
-	pci_unmap_single(tnapi->tp->pdev,
-			 dma_unmap_addr(txb, mapping),
-			 skb_headlen(skb),
-			 PCI_DMA_TODEVICE);
+static void tg3_napi_enable(struct tg3 *tp)
+{
+	int i;
 
-	while (txb->fragmented) {
-		txb->fragmented = false;
-		entry = NEXT_TX(entry);
-		txb = &tnapi->tx_buffers[entry];
-	}
+	for (i = 0; i < tp->irq_cnt; i++)
+		napi_enable(&tp->napi[i].napi);
+}
 
-	for (i = 0; i <= last; i++) {
-		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+static void tg3_napi_init(struct tg3 *tp)
+{
+	int i;
 
-		entry = NEXT_TX(entry);
-		txb = &tnapi->tx_buffers[entry];
+	netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64);
+	for (i = 1; i < tp->irq_cnt; i++)
+		netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64);
+}
 
-		pci_unmap_page(tnapi->tp->pdev,
-			       dma_unmap_addr(txb, mapping),
-			       skb_frag_size(frag), PCI_DMA_TODEVICE);
+static void tg3_napi_fini(struct tg3 *tp)
+{
+	int i;
 
-		while (txb->fragmented) {
-			txb->fragmented = false;
-			entry = NEXT_TX(entry);
-			txb = &tnapi->tx_buffers[entry];
-		}
-	}
+	for (i = 0; i < tp->irq_cnt; i++)
+		netif_napi_del(&tp->napi[i].napi);
 }
 
-/* Workaround 4GB and 40-bit hardware DMA bugs. */
-static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
-				       struct sk_buff **pskb,
-				       u32 *entry, u32 *budget,
-				       u32 base_flags, u32 mss, u32 vlan)
+static inline void tg3_netif_stop(struct tg3 *tp)
 {
-	struct tg3 *tp = tnapi->tp;
-	struct sk_buff *new_skb, *skb = *pskb;
-	dma_addr_t new_addr = 0;
-	int ret = 0;
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
-		new_skb = skb_copy(skb, GFP_ATOMIC);
-	else {
-		int more_headroom = 4 - ((unsigned long)skb->data & 3);
+	tp->dev->trans_start = jiffies;	/* prevent tx timeout */
+	tg3_napi_disable(tp);
+	netif_tx_disable(tp->dev);
+}
 
-		new_skb = skb_copy_expand(skb,
-					  skb_headroom(skb) + more_headroom,
-					  skb_tailroom(skb), GFP_ATOMIC);
-	}
+static inline void tg3_netif_start(struct tg3 *tp)
+{
+	/* NOTE: unconditional netif_tx_wake_all_queues is only
+	 * appropriate so long as all callers are assured to
+	 * have free tx slots (such as after tg3_init_hw)
+	 */
+	netif_tx_wake_all_queues(tp->dev);
 
-	if (!new_skb) {
-		ret = -1;
-	} else {
-		/* New SKB is guaranteed to be linear. */
-		new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
-					  PCI_DMA_TODEVICE);
-		/* Make sure the mapping succeeded */
-		if (pci_dma_mapping_error(tp->pdev, new_addr)) {
-			dev_kfree_skb(new_skb);
-			ret = -1;
-		} else {
-			u32 save_entry = *entry;
+	tg3_napi_enable(tp);
+	tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
+	tg3_enable_ints(tp);
+}
 
-			base_flags |= TXD_FLAG_END;
+static void tg3_irq_quiesce(struct tg3 *tp)
+{
+	int i;
 
-			tnapi->tx_buffers[*entry].skb = new_skb;
-			dma_unmap_addr_set(&tnapi->tx_buffers[*entry],
-					   mapping, new_addr);
+	BUG_ON(tp->irq_sync);
 
-			if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
-					    new_skb->len, base_flags,
-					    mss, vlan)) {
-				tg3_tx_skb_unmap(tnapi, save_entry, -1);
-				dev_kfree_skb(new_skb);
-				ret = -1;
-			}
-		}
-	}
+	tp->irq_sync = 1;
+	smp_mb();
 
-	dev_kfree_skb(skb);
-	*pskb = new_skb;
-	return ret;
+	for (i = 0; i < tp->irq_cnt; i++)
+		synchronize_irq(tp->napi[i].irq_vec);
 }
 
-static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
-
-/* Use GSO to workaround a rare TSO bug that may be triggered when the
- * TSO header is greater than 80 bytes.
+/* Fully shutdown all tg3 driver activity elsewhere in the system.
+ * If irq_sync is non-zero, then the IRQ handler must be synchronized
+ * with as well.  Most of the time, this is not necessary except when
+ * shutting down the device.
  */
-static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
 {
-	struct sk_buff *segs, *nskb;
-	u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
-
-	/* Estimate the number of fragments in the worst case */
-	if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
-		netif_stop_queue(tp->dev);
-
-		/* netif_tx_stop_queue() must be done before checking
-		 * checking tx index in tg3_tx_avail() below, because in
-		 * tg3_tx(), we update tx index before checking for
-		 * netif_tx_queue_stopped().
-		 */
-		smp_mb();
-		if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
-			return NETDEV_TX_BUSY;
+	spin_lock_bh(&tp->lock);
+	if (irq_sync)
+		tg3_irq_quiesce(tp);
+}
 
-		netif_wake_queue(tp->dev);
-	}
+static inline void tg3_full_unlock(struct tg3 *tp)
+{
+	spin_unlock_bh(&tp->lock);
+}
 
-	segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO);
-	if (IS_ERR(segs))
-		goto tg3_tso_bug_end;
+/* One-shot MSI handler - Chip automatically disables interrupt
+ * after sending MSI so driver doesn't have to do it.
+ */
+static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
+{
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
 
-	do {
-		nskb = segs;
-		segs = segs->next;
-		nskb->next = NULL;
-		tg3_start_xmit(nskb, tp->dev);
-	} while (segs);
+	prefetch(tnapi->hw_status);
+	if (tnapi->rx_rcb)
+		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
 
-tg3_tso_bug_end:
-	dev_kfree_skb(skb);
+	if (likely(!tg3_irq_sync(tp)))
+		napi_schedule(&tnapi->napi);
 
-	return NETDEV_TX_OK;
+	return IRQ_HANDLED;
 }
 
-/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
- * support TG3_FLAG_HW_TSO_1 or firmware TSO only.
+/* MSI ISR - No need to check for interrupt sharing and no need to
+ * flush status block and interrupt mailbox. PCI ordering rules
+ * guarantee that MSI will arrive after the status block.
  */
-static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static irqreturn_t tg3_msi(int irq, void *dev_id)
 {
-	struct tg3 *tp = netdev_priv(dev);
-	u32 len, entry, base_flags, mss, vlan = 0;
-	u32 budget;
-	int i = -1, would_hit_hwbug;
-	dma_addr_t mapping;
-	struct tg3_napi *tnapi;
-	struct netdev_queue *txq;
-	unsigned int last;
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
 
-	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
-	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
-	if (tg3_flag(tp, ENABLE_TSS))
-		tnapi++;
+	prefetch(tnapi->hw_status);
+	if (tnapi->rx_rcb)
+		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+	/*
+	 * Writing any value to intr-mbox-0 clears PCI INTA# and
+	 * chip-internal interrupt pending events.
+	 * Writing non-zero to intr-mbox-0 additional tells the
+	 * NIC to stop sending us irqs, engaging "in-intr-handler"
+	 * event coalescing.
+	 */
+	tw32_mailbox(tnapi->int_mbox, 0x00000001);
+	if (likely(!tg3_irq_sync(tp)))
+		napi_schedule(&tnapi->napi);
 
-	budget = tg3_tx_avail(tnapi);
+	return IRQ_RETVAL(1);
+}
 
-	/* We are running in BH disabled context with netif_tx_lock
-	 * and TX reclaim runs via tp->napi.poll inside of a software
-	 * interrupt.  Furthermore, IRQ processing runs lockless so we have
-	 * no IRQ context deadlocks to worry about either.  Rejoice!
-	 */
-	if (unlikely(budget <= (skb_shinfo(skb)->nr_frags + 1))) {
-		if (!netif_tx_queue_stopped(txq)) {
-			netif_tx_stop_queue(txq);
+static irqreturn_t tg3_interrupt(int irq, void *dev_id)
+{
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
+	unsigned int handled = 1;
 
-			/* This is a hard error, log it. */
-			netdev_err(dev,
-				   "BUG! Tx Ring full when queue awake!\n");
+	/* In INTx mode, it is possible for the interrupt to arrive at
+	 * the CPU before the status block posted prior to the interrupt.
+	 * Reading the PCI State register will confirm whether the
+	 * interrupt is ours and will flush the status block.
+	 */
+	if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
+		if (tg3_flag(tp, CHIP_RESETTING) ||
+		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+			handled = 0;
+			goto out;
 		}
-		return NETDEV_TX_BUSY;
 	}
 
-	entry = tnapi->tx_prod;
-	base_flags = 0;
-	if (skb->ip_summed == CHECKSUM_PARTIAL)
-		base_flags |= TXD_FLAG_TCPUDP_CSUM;
-
-	mss = skb_shinfo(skb)->gso_size;
-	if (mss) {
-		struct iphdr *iph;
-		u32 tcp_opt_len, hdr_len;
+	/*
+	 * Writing any value to intr-mbox-0 clears PCI INTA# and
+	 * chip-internal interrupt pending events.
+	 * Writing non-zero to intr-mbox-0 additional tells the
+	 * NIC to stop sending us irqs, engaging "in-intr-handler"
+	 * event coalescing.
+	 *
+	 * Flush the mailbox to de-assert the IRQ immediately to prevent
+	 * spurious interrupts.  The flush impacts performance but
+	 * excessive spurious interrupts can be worse in some cases.
+	 */
+	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+	if (tg3_irq_sync(tp))
+		goto out;
+	sblk->status &= ~SD_STATUS_UPDATED;
+	if (likely(tg3_has_work(tnapi))) {
+		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+		napi_schedule(&tnapi->napi);
+	} else {
+		/* No work, shared interrupt perhaps?  re-enable
+		 * interrupts, and flush that PCI write
+		 */
+		tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
+			       0x00000000);
+	}
+out:
+	return IRQ_RETVAL(handled);
+}
 
-		if (skb_header_cloned(skb) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-			goto drop;
+static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
+{
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
+	unsigned int handled = 1;
 
-		iph = ip_hdr(skb);
-		tcp_opt_len = tcp_optlen(skb);
+	/* In INTx mode, it is possible for the interrupt to arrive at
+	 * the CPU before the status block posted prior to the interrupt.
+	 * Reading the PCI State register will confirm whether the
+	 * interrupt is ours and will flush the status block.
+	 */
+	if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) {
+		if (tg3_flag(tp, CHIP_RESETTING) ||
+		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+			handled = 0;
+			goto out;
+		}
+	}
 
-		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
+	/*
+	 * writing any value to intr-mbox-0 clears PCI INTA# and
+	 * chip-internal interrupt pending events.
+	 * writing non-zero to intr-mbox-0 additional tells the
+	 * NIC to stop sending us irqs, engaging "in-intr-handler"
+	 * event coalescing.
+	 *
+	 * Flush the mailbox to de-assert the IRQ immediately to prevent
+	 * spurious interrupts.  The flush impacts performance but
+	 * excessive spurious interrupts can be worse in some cases.
+	 */
+	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
 
-		if (!skb_is_gso_v6(skb)) {
-			iph->check = 0;
-			iph->tot_len = htons(mss + hdr_len);
-		}
+	/*
+	 * In a shared interrupt configuration, sometimes other devices'
+	 * interrupts will scream.  We record the current status tag here
+	 * so that the above check can report that the screaming interrupts
+	 * are unhandled.  Eventually they will be silenced.
+	 */
+	tnapi->last_irq_tag = sblk->status_tag;
 
-		if (unlikely((ETH_HLEN + hdr_len) > 80) &&
-		    tg3_flag(tp, TSO_BUG))
-			return tg3_tso_bug(tp, skb);
+	if (tg3_irq_sync(tp))
+		goto out;
 
-		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
-			       TXD_FLAG_CPU_POST_DMA);
+	prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
 
-		if (tg3_flag(tp, HW_TSO_1) ||
-		    tg3_flag(tp, HW_TSO_2) ||
-		    tg3_flag(tp, HW_TSO_3)) {
-			tcp_hdr(skb)->check = 0;
-			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
-		} else
-			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-								 iph->daddr, 0,
-								 IPPROTO_TCP,
-								 0);
+	napi_schedule(&tnapi->napi);
 
-		if (tg3_flag(tp, HW_TSO_3)) {
-			mss |= (hdr_len & 0xc) << 12;
-			if (hdr_len & 0x10)
-				base_flags |= 0x00000010;
-			base_flags |= (hdr_len & 0x3e0) << 5;
-		} else if (tg3_flag(tp, HW_TSO_2))
-			mss |= hdr_len << 9;
-		else if (tg3_flag(tp, HW_TSO_1) ||
-			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
-			if (tcp_opt_len || iph->ihl > 5) {
-				int tsflags;
+out:
+	return IRQ_RETVAL(handled);
+}
 
-				tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2);
-				mss |= (tsflags << 11);
-			}
-		} else {
-			if (tcp_opt_len || iph->ihl > 5) {
-				int tsflags;
+/* ISR for interrupt test */
+static irqreturn_t tg3_test_isr(int irq, void *dev_id)
+{
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 
-				tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2);
-				base_flags |= tsflags << 12;
-			}
-		}
+	if ((sblk->status & SD_STATUS_UPDATED) ||
+	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
+		tg3_disable_ints(tp);
+		return IRQ_RETVAL(1);
 	}
+	return IRQ_RETVAL(0);
+}
 
-	if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
-	    !mss && skb->len > VLAN_ETH_FRAME_LEN)
-		base_flags |= TXD_FLAG_JMB_PKT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void tg3_poll_controller(struct net_device *dev)
+{
+	int i;
+	struct tg3 *tp = netdev_priv(dev);
 
-	if (vlan_tx_tag_present(skb)) {
-		base_flags |= TXD_FLAG_VLAN;
-		vlan = vlan_tx_tag_get(skb);
+	for (i = 0; i < tp->irq_cnt; i++)
+		tg3_interrupt(tp->napi[i].irq_vec, &tp->napi[i]);
+}
+#endif
+
+static void tg3_tx_timeout(struct net_device *dev)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (netif_msg_tx_err(tp)) {
+		netdev_err(dev, "transmit timed out, resetting\n");
+		tg3_dump_state(tp);
 	}
 
-	len = skb_headlen(skb);
+	tg3_reset_task_schedule(tp);
+}
 
-	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(tp->pdev, mapping))
-		goto drop;
+/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
+static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len)
+{
+	u32 base = (u32) mapping & 0xffffffff;
 
+	return (base > 0xffffdcc0) && (base + len + 8 < base);
+}
 
-	tnapi->tx_buffers[entry].skb = skb;
-	dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
+/* Test for DMA addresses > 40-bit */
+static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
+					  int len)
+{
+#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
+	if (tg3_flag(tp, 40BIT_DMA_BUG))
+		return ((u64) mapping + len) > DMA_BIT_MASK(40);
+	return 0;
+#else
+	return 0;
+#endif
+}
 
-	would_hit_hwbug = 0;
+static inline void tg3_tx_set_bd(struct tg3_tx_buffer_desc *txbd,
+				 dma_addr_t mapping, u32 len, u32 flags,
+				 u32 mss, u32 vlan)
+{
+	txbd->addr_hi = ((u64) mapping >> 32);
+	txbd->addr_lo = ((u64) mapping & 0xffffffff);
+	txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff);
+	txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT);
+}
 
-	if (tg3_flag(tp, 5701_DMA_BUG))
-		would_hit_hwbug = 1;
+static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
+			    dma_addr_t map, u32 len, u32 flags,
+			    u32 mss, u32 vlan)
+{
+	struct tg3 *tp = tnapi->tp;
+	bool hwbug = false;
 
-	if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
-			  ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
-			    mss, vlan)) {
-		would_hit_hwbug = 1;
-	/* Now loop through additional data fragments, and queue them. */
-	} else if (skb_shinfo(skb)->nr_frags > 0) {
-		u32 tmp_mss = mss;
+	if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8)
+		hwbug = true;
 
-		if (!tg3_flag(tp, HW_TSO_1) &&
-		    !tg3_flag(tp, HW_TSO_2) &&
-		    !tg3_flag(tp, HW_TSO_3))
-			tmp_mss = 0;
+	if (tg3_4g_overflow_test(map, len))
+		hwbug = true;
 
-		last = skb_shinfo(skb)->nr_frags - 1;
-		for (i = 0; i <= last; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+	if (tg3_40bit_overflow_test(tp, map, len))
+		hwbug = true;
 
-			len = skb_frag_size(frag);
-			mapping = skb_frag_dma_map(&tp->pdev->dev, frag, 0,
-						   len, DMA_TO_DEVICE);
+	if (tp->dma_limit) {
+		u32 prvidx = *entry;
+		u32 tmp_flag = flags & ~TXD_FLAG_END;
+		while (len > tp->dma_limit && *budget) {
+			u32 frag_len = tp->dma_limit;
+			len -= tp->dma_limit;
 
-			tnapi->tx_buffers[entry].skb = NULL;
-			dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
-					   mapping);
-			if (dma_mapping_error(&tp->pdev->dev, mapping))
-				goto dma_error;
+			/* Avoid the 8byte DMA problem */
+			if (len <= 8) {
+				len += tp->dma_limit / 2;
+				frag_len = tp->dma_limit / 2;
+			}
 
-			if (!budget ||
-			    tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
-					    len, base_flags |
-					    ((i == last) ? TXD_FLAG_END : 0),
-					    tmp_mss, vlan)) {
-				would_hit_hwbug = 1;
-				break;
+			tnapi->tx_buffers[*entry].fragmented = true;
+
+			tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
+				      frag_len, tmp_flag, mss, vlan);
+			*budget -= 1;
+			prvidx = *entry;
+			*entry = NEXT_TX(*entry);
+
+			map += frag_len;
+		}
+
+		if (len) {
+			if (*budget) {
+				tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
+					      len, flags, mss, vlan);
+				*budget -= 1;
+				*entry = NEXT_TX(*entry);
+			} else {
+				hwbug = true;
+				tnapi->tx_buffers[prvidx].fragmented = false;
 			}
 		}
+	} else {
+		tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
+			      len, flags, mss, vlan);
+		*entry = NEXT_TX(*entry);
 	}
 
-	if (would_hit_hwbug) {
-		tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
-
-		/* If the workaround fails due to memory/mapping
-		 * failure, silently drop this packet.
-		 */
-		entry = tnapi->tx_prod;
-		budget = tg3_tx_avail(tnapi);
-		if (tigon3_dma_hwbug_workaround(tnapi, &skb, &entry, &budget,
-						base_flags, mss, vlan))
-			goto drop_nofree;
-	}
+	return hwbug;
+}
 
-	skb_tx_timestamp(skb);
-	netdev_sent_queue(tp->dev, skb->len);
+static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
+{
+	int i;
+	struct sk_buff *skb;
+	struct tg3_tx_ring_info *txb = &tnapi->tx_buffers[entry];
 
-	/* Packets are ready, update Tx producer idx local and on card. */
-	tw32_tx_mbox(tnapi->prodmbox, entry);
+	skb = txb->skb;
+	txb->skb = NULL;
 
-	tnapi->tx_prod = entry;
-	if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
-		netif_tx_stop_queue(txq);
+	pci_unmap_single(tnapi->tp->pdev,
+			 dma_unmap_addr(txb, mapping),
+			 skb_headlen(skb),
+			 PCI_DMA_TODEVICE);
 
-		/* netif_tx_stop_queue() must be done before checking
-		 * checking tx index in tg3_tx_avail() below, because in
-		 * tg3_tx(), we update tx index before checking for
-		 * netif_tx_queue_stopped().
-		 */
-		smp_mb();
-		if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
-			netif_tx_wake_queue(txq);
+	while (txb->fragmented) {
+		txb->fragmented = false;
+		entry = NEXT_TX(entry);
+		txb = &tnapi->tx_buffers[entry];
 	}
 
-	mmiowb();
-	return NETDEV_TX_OK;
+	for (i = 0; i <= last; i++) {
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-dma_error:
-	tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
-	tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
-drop:
-	dev_kfree_skb(skb);
-drop_nofree:
-	tp->tx_dropped++;
-	return NETDEV_TX_OK;
+		entry = NEXT_TX(entry);
+		txb = &tnapi->tx_buffers[entry];
+
+		pci_unmap_page(tnapi->tp->pdev,
+			       dma_unmap_addr(txb, mapping),
+			       skb_frag_size(frag), PCI_DMA_TODEVICE);
+
+		while (txb->fragmented) {
+			txb->fragmented = false;
+			entry = NEXT_TX(entry);
+			txb = &tnapi->tx_buffers[entry];
+		}
+	}
 }
 
-static void tg3_mac_loopback(struct tg3 *tp, bool enable)
+/* Workaround 4GB and 40-bit hardware DMA bugs. */
+static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
+				       struct sk_buff **pskb,
+				       u32 *entry, u32 *budget,
+				       u32 base_flags, u32 mss, u32 vlan)
 {
-	if (enable) {
-		tp->mac_mode &= ~(MAC_MODE_HALF_DUPLEX |
-				  MAC_MODE_PORT_MODE_MASK);
+	struct tg3 *tp = tnapi->tp;
+	struct sk_buff *new_skb, *skb = *pskb;
+	dma_addr_t new_addr = 0;
+	int ret = 0;
 
-		tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
+		new_skb = skb_copy(skb, GFP_ATOMIC);
+	else {
+		int more_headroom = 4 - ((unsigned long)skb->data & 3);
 
-		if (!tg3_flag(tp, 5705_PLUS))
-			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+		new_skb = skb_copy_expand(skb,
+					  skb_headroom(skb) + more_headroom,
+					  skb_tailroom(skb), GFP_ATOMIC);
+	}
 
-		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
-			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
-		else
-			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	if (!new_skb) {
+		ret = -1;
 	} else {
-		tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
+		/* New SKB is guaranteed to be linear. */
+		new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
+					  PCI_DMA_TODEVICE);
+		/* Make sure the mapping succeeded */
+		if (pci_dma_mapping_error(tp->pdev, new_addr)) {
+			dev_kfree_skb(new_skb);
+			ret = -1;
+		} else {
+			u32 save_entry = *entry;
 
-		if (tg3_flag(tp, 5705_PLUS) ||
-		    (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) ||
-		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
-			tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
-	}
+			base_flags |= TXD_FLAG_END;
 
-	tw32(MAC_MODE, tp->mac_mode);
-	udelay(40);
-}
+			tnapi->tx_buffers[*entry].skb = new_skb;
+			dma_unmap_addr_set(&tnapi->tx_buffers[*entry],
+					   mapping, new_addr);
 
-static int tg3_phy_lpbk_set(struct tg3 *tp, u32 speed, bool extlpbk)
-{
-	u32 val, bmcr, mac_mode, ptest = 0;
-
-	tg3_phy_toggle_apd(tp, false);
-	tg3_phy_toggle_automdix(tp, 0);
-
-	if (extlpbk && tg3_phy_set_extloopbk(tp))
-		return -EIO;
-
-	bmcr = BMCR_FULLDPLX;
-	switch (speed) {
-	case SPEED_10:
-		break;
-	case SPEED_100:
-		bmcr |= BMCR_SPEED100;
-		break;
-	case SPEED_1000:
-	default:
-		if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
-			speed = SPEED_100;
-			bmcr |= BMCR_SPEED100;
-		} else {
-			speed = SPEED_1000;
-			bmcr |= BMCR_SPEED1000;
+			if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
+					    new_skb->len, base_flags,
+					    mss, vlan)) {
+				tg3_tx_skb_unmap(tnapi, save_entry, -1);
+				dev_kfree_skb(new_skb);
+				ret = -1;
+			}
 		}
 	}
 
-	if (extlpbk) {
-		if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
-			tg3_readphy(tp, MII_CTRL1000, &val);
-			val |= CTL1000_AS_MASTER |
-			       CTL1000_ENABLE_MASTER;
-			tg3_writephy(tp, MII_CTRL1000, val);
-		} else {
-			ptest = MII_TG3_FET_PTEST_TRIM_SEL |
-				MII_TG3_FET_PTEST_TRIM_2;
-			tg3_writephy(tp, MII_TG3_FET_PTEST, ptest);
-		}
-	} else
-		bmcr |= BMCR_LOOPBACK;
-
-	tg3_writephy(tp, MII_BMCR, bmcr);
+	dev_kfree_skb(skb);
+	*pskb = new_skb;
+	return ret;
+}
 
-	/* The write needs to be flushed for the FETs */
-	if (tp->phy_flags & TG3_PHYFLG_IS_FET)
-		tg3_readphy(tp, MII_BMCR, &bmcr);
+static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
 
-	udelay(40);
+/* Use GSO to workaround a rare TSO bug that may be triggered when the
+ * TSO header is greater than 80 bytes.
+ */
+static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
+{
+	struct sk_buff *segs, *nskb;
+	u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
 
-	if ((tp->phy_flags & TG3_PHYFLG_IS_FET) &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
-		tg3_writephy(tp, MII_TG3_FET_PTEST, ptest |
-			     MII_TG3_FET_PTEST_FRC_TX_LINK |
-			     MII_TG3_FET_PTEST_FRC_TX_LOCK);
+	/* Estimate the number of fragments in the worst case */
+	if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
+		netif_stop_queue(tp->dev);
 
-		/* The write needs to be flushed for the AC131 */
-		tg3_readphy(tp, MII_TG3_FET_PTEST, &val);
-	}
+		/* netif_tx_stop_queue() must be done before checking
+		 * checking tx index in tg3_tx_avail() below, because in
+		 * tg3_tx(), we update tx index before checking for
+		 * netif_tx_queue_stopped().
+		 */
+		smp_mb();
+		if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
+			return NETDEV_TX_BUSY;
 
-	/* Reset to prevent losing 1st rx packet intermittently */
-	if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
-	    tg3_flag(tp, 5780_CLASS)) {
-		tw32_f(MAC_RX_MODE, RX_MODE_RESET);
-		udelay(10);
-		tw32_f(MAC_RX_MODE, tp->rx_mode);
+		netif_wake_queue(tp->dev);
 	}
 
-	mac_mode = tp->mac_mode &
-		   ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
-	if (speed == SPEED_1000)
-		mac_mode |= MAC_MODE_PORT_MODE_GMII;
-	else
-		mac_mode |= MAC_MODE_PORT_MODE_MII;
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
-		u32 masked_phy_id = tp->phy_id & TG3_PHY_ID_MASK;
-
-		if (masked_phy_id == TG3_PHY_ID_BCM5401)
-			mac_mode &= ~MAC_MODE_LINK_POLARITY;
-		else if (masked_phy_id == TG3_PHY_ID_BCM5411)
-			mac_mode |= MAC_MODE_LINK_POLARITY;
+	segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO);
+	if (IS_ERR(segs))
+		goto tg3_tso_bug_end;
 
-		tg3_writephy(tp, MII_TG3_EXT_CTRL,
-			     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
-	}
+	do {
+		nskb = segs;
+		segs = segs->next;
+		nskb->next = NULL;
+		tg3_start_xmit(nskb, tp->dev);
+	} while (segs);
 
-	tw32(MAC_MODE, mac_mode);
-	udelay(40);
+tg3_tso_bug_end:
+	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
-static void tg3_set_loopback(struct net_device *dev, netdev_features_t features)
+/* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
+ * support TG3_FLAG_HW_TSO_1 or firmware TSO only.
+ */
+static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
+	u32 len, entry, base_flags, mss, vlan = 0;
+	u32 budget;
+	int i = -1, would_hit_hwbug;
+	dma_addr_t mapping;
+	struct tg3_napi *tnapi;
+	struct netdev_queue *txq;
+	unsigned int last;
 
-	if (features & NETIF_F_LOOPBACK) {
-		if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)
-			return;
+	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
+	if (tg3_flag(tp, ENABLE_TSS))
+		tnapi++;
 
-		spin_lock_bh(&tp->lock);
-		tg3_mac_loopback(tp, true);
-		netif_carrier_on(tp->dev);
-		spin_unlock_bh(&tp->lock);
-		netdev_info(dev, "Internal MAC loopback mode enabled.\n");
-	} else {
-		if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
-			return;
+	budget = tg3_tx_avail(tnapi);
 
-		spin_lock_bh(&tp->lock);
-		tg3_mac_loopback(tp, false);
-		/* Force link status check */
-		tg3_setup_phy(tp, 1);
-		spin_unlock_bh(&tp->lock);
-		netdev_info(dev, "Internal MAC loopback mode disabled.\n");
+	/* We are running in BH disabled context with netif_tx_lock
+	 * and TX reclaim runs via tp->napi.poll inside of a software
+	 * interrupt.  Furthermore, IRQ processing runs lockless so we have
+	 * no IRQ context deadlocks to worry about either.  Rejoice!
+	 */
+	if (unlikely(budget <= (skb_shinfo(skb)->nr_frags + 1))) {
+		if (!netif_tx_queue_stopped(txq)) {
+			netif_tx_stop_queue(txq);
+
+			/* This is a hard error, log it. */
+			netdev_err(dev,
+				   "BUG! Tx Ring full when queue awake!\n");
+		}
+		return NETDEV_TX_BUSY;
 	}
-}
 
-static netdev_features_t tg3_fix_features(struct net_device *dev,
-	netdev_features_t features)
-{
-	struct tg3 *tp = netdev_priv(dev);
+	entry = tnapi->tx_prod;
+	base_flags = 0;
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		base_flags |= TXD_FLAG_TCPUDP_CSUM;
 
-	if (dev->mtu > ETH_DATA_LEN && tg3_flag(tp, 5780_CLASS))
-		features &= ~NETIF_F_ALL_TSO;
+	mss = skb_shinfo(skb)->gso_size;
+	if (mss) {
+		struct iphdr *iph;
+		u32 tcp_opt_len, hdr_len;
 
-	return features;
-}
+		if (skb_header_cloned(skb) &&
+		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+			goto drop;
 
-static int tg3_set_features(struct net_device *dev, netdev_features_t features)
-{
-	netdev_features_t changed = dev->features ^ features;
+		iph = ip_hdr(skb);
+		tcp_opt_len = tcp_optlen(skb);
 
-	if ((changed & NETIF_F_LOOPBACK) && netif_running(dev))
-		tg3_set_loopback(dev, features);
+		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
 
-	return 0;
-}
+		if (!skb_is_gso_v6(skb)) {
+			iph->check = 0;
+			iph->tot_len = htons(mss + hdr_len);
+		}
 
-static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
-			       int new_mtu)
-{
-	dev->mtu = new_mtu;
+		if (unlikely((ETH_HLEN + hdr_len) > 80) &&
+		    tg3_flag(tp, TSO_BUG))
+			return tg3_tso_bug(tp, skb);
 
-	if (new_mtu > ETH_DATA_LEN) {
-		if (tg3_flag(tp, 5780_CLASS)) {
-			netdev_update_features(dev);
-			tg3_flag_clear(tp, TSO_CAPABLE);
+		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
+			       TXD_FLAG_CPU_POST_DMA);
+
+		if (tg3_flag(tp, HW_TSO_1) ||
+		    tg3_flag(tp, HW_TSO_2) ||
+		    tg3_flag(tp, HW_TSO_3)) {
+			tcp_hdr(skb)->check = 0;
+			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
+		} else
+			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
+								 iph->daddr, 0,
+								 IPPROTO_TCP,
+								 0);
+
+		if (tg3_flag(tp, HW_TSO_3)) {
+			mss |= (hdr_len & 0xc) << 12;
+			if (hdr_len & 0x10)
+				base_flags |= 0x00000010;
+			base_flags |= (hdr_len & 0x3e0) << 5;
+		} else if (tg3_flag(tp, HW_TSO_2))
+			mss |= hdr_len << 9;
+		else if (tg3_flag(tp, HW_TSO_1) ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+			if (tcp_opt_len || iph->ihl > 5) {
+				int tsflags;
+
+				tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2);
+				mss |= (tsflags << 11);
+			}
 		} else {
-			tg3_flag_set(tp, JUMBO_RING_ENABLE);
-		}
-	} else {
-		if (tg3_flag(tp, 5780_CLASS)) {
-			tg3_flag_set(tp, TSO_CAPABLE);
-			netdev_update_features(dev);
+			if (tcp_opt_len || iph->ihl > 5) {
+				int tsflags;
+
+				tsflags = (iph->ihl - 5) + (tcp_opt_len >> 2);
+				base_flags |= tsflags << 12;
+			}
 		}
-		tg3_flag_clear(tp, JUMBO_RING_ENABLE);
 	}
-}
 
-static int tg3_change_mtu(struct net_device *dev, int new_mtu)
-{
-	struct tg3 *tp = netdev_priv(dev);
-	int err;
-
-	if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp))
-		return -EINVAL;
+	if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
+	    !mss && skb->len > VLAN_ETH_FRAME_LEN)
+		base_flags |= TXD_FLAG_JMB_PKT;
 
-	if (!netif_running(dev)) {
-		/* We'll just catch it later when the
-		 * device is up'd.
-		 */
-		tg3_set_mtu(dev, tp, new_mtu);
-		return 0;
+	if (vlan_tx_tag_present(skb)) {
+		base_flags |= TXD_FLAG_VLAN;
+		vlan = vlan_tx_tag_get(skb);
 	}
 
-	tg3_phy_stop(tp);
-
-	tg3_netif_stop(tp);
+	len = skb_headlen(skb);
 
-	tg3_full_lock(tp, 1);
+	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(tp->pdev, mapping))
+		goto drop;
 
-	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 
-	tg3_set_mtu(dev, tp, new_mtu);
+	tnapi->tx_buffers[entry].skb = skb;
+	dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
 
-	err = tg3_restart_hw(tp, 0);
+	would_hit_hwbug = 0;
 
-	if (!err)
-		tg3_netif_start(tp);
+	if (tg3_flag(tp, 5701_DMA_BUG))
+		would_hit_hwbug = 1;
 
-	tg3_full_unlock(tp);
+	if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
+			  ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
+			    mss, vlan)) {
+		would_hit_hwbug = 1;
+	} else if (skb_shinfo(skb)->nr_frags > 0) {
+		u32 tmp_mss = mss;
 
-	if (!err)
-		tg3_phy_start(tp);
+		if (!tg3_flag(tp, HW_TSO_1) &&
+		    !tg3_flag(tp, HW_TSO_2) &&
+		    !tg3_flag(tp, HW_TSO_3))
+			tmp_mss = 0;
 
-	return err;
-}
+		/* Now loop through additional data
+		 * fragments, and queue them.
+		 */
+		last = skb_shinfo(skb)->nr_frags - 1;
+		for (i = 0; i <= last; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-static void tg3_rx_prodring_free(struct tg3 *tp,
-				 struct tg3_rx_prodring_set *tpr)
-{
-	int i;
+			len = skb_frag_size(frag);
+			mapping = skb_frag_dma_map(&tp->pdev->dev, frag, 0,
+						   len, DMA_TO_DEVICE);
 
-	if (tpr != &tp->napi[0].prodring) {
-		for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
-		     i = (i + 1) & tp->rx_std_ring_mask)
-			tg3_rx_data_free(tp, &tpr->rx_std_buffers[i],
-					tp->rx_pkt_map_sz);
+			tnapi->tx_buffers[entry].skb = NULL;
+			dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
+					   mapping);
+			if (dma_mapping_error(&tp->pdev->dev, mapping))
+				goto dma_error;
 
-		if (tg3_flag(tp, JUMBO_CAPABLE)) {
-			for (i = tpr->rx_jmb_cons_idx;
-			     i != tpr->rx_jmb_prod_idx;
-			     i = (i + 1) & tp->rx_jmb_ring_mask) {
-				tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i],
-						TG3_RX_JMB_MAP_SZ);
+			if (!budget ||
+			    tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
+					    len, base_flags |
+					    ((i == last) ? TXD_FLAG_END : 0),
+					    tmp_mss, vlan)) {
+				would_hit_hwbug = 1;
+				break;
 			}
 		}
+	}
 
-		return;
+	if (would_hit_hwbug) {
+		tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
+
+		/* If the workaround fails due to memory/mapping
+		 * failure, silently drop this packet.
+		 */
+		entry = tnapi->tx_prod;
+		budget = tg3_tx_avail(tnapi);
+		if (tigon3_dma_hwbug_workaround(tnapi, &skb, &entry, &budget,
+						base_flags, mss, vlan))
+			goto drop_nofree;
 	}
 
-	for (i = 0; i <= tp->rx_std_ring_mask; i++)
-		tg3_rx_data_free(tp, &tpr->rx_std_buffers[i],
-				tp->rx_pkt_map_sz);
+	skb_tx_timestamp(skb);
+	netdev_sent_queue(tp->dev, skb->len);
 
-	if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) {
-		for (i = 0; i <= tp->rx_jmb_ring_mask; i++)
-			tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i],
-					TG3_RX_JMB_MAP_SZ);
+	/* Packets are ready, update Tx producer idx local and on card. */
+	tw32_tx_mbox(tnapi->prodmbox, entry);
+
+	tnapi->tx_prod = entry;
+	if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
+		netif_tx_stop_queue(txq);
+
+		/* netif_tx_stop_queue() must be done before checking
+		 * checking tx index in tg3_tx_avail() below, because in
+		 * tg3_tx(), we update tx index before checking for
+		 * netif_tx_queue_stopped().
+		 */
+		smp_mb();
+		if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
+			netif_tx_wake_queue(txq);
 	}
+
+	mmiowb();
+	return NETDEV_TX_OK;
+
+dma_error:
+	tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
+	tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
+drop:
+	dev_kfree_skb(skb);
+drop_nofree:
+	tp->tx_dropped++;
+	return NETDEV_TX_OK;
 }
 
-/* Initialize rx rings for packet processing.
- *
- * The chip has been shut down and the driver detached from
- * the networking, so no interrupts or new tx packets will
- * end up in the driver.  tp->{tx,}lock are held and thus
- * we may not sleep.
- */
-static int tg3_rx_prodring_alloc(struct tg3 *tp,
-				 struct tg3_rx_prodring_set *tpr)
+static void tg3_mac_loopback(struct tg3 *tp, bool enable)
 {
-	u32 i, rx_pkt_dma_sz;
+	if (enable) {
+		tp->mac_mode &= ~(MAC_MODE_HALF_DUPLEX |
+				  MAC_MODE_PORT_MODE_MASK);
 
-	tpr->rx_std_cons_idx = 0;
-	tpr->rx_std_prod_idx = 0;
-	tpr->rx_jmb_cons_idx = 0;
-	tpr->rx_jmb_prod_idx = 0;
+		tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
 
-	if (tpr != &tp->napi[0].prodring) {
-		memset(&tpr->rx_std_buffers[0], 0,
-		       TG3_RX_STD_BUFF_RING_SIZE(tp));
-		if (tpr->rx_jmb_buffers)
-			memset(&tpr->rx_jmb_buffers[0], 0,
-			       TG3_RX_JMB_BUFF_RING_SIZE(tp));
-		goto done;
+		if (!tg3_flag(tp, 5705_PLUS))
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+
+		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+		else
+			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	} else {
+		tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
+
+		if (tg3_flag(tp, 5705_PLUS) ||
+		    (tp->phy_flags & TG3_PHYFLG_PHY_SERDES) ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+			tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
 	}
 
-	/* Zero out all descriptors. */
-	memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp));
+	tw32(MAC_MODE, tp->mac_mode);
+	udelay(40);
+}
 
-	rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
-	if (tg3_flag(tp, 5780_CLASS) &&
-	    tp->dev->mtu > ETH_DATA_LEN)
-		rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ;
-	tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz);
+static int tg3_phy_lpbk_set(struct tg3 *tp, u32 speed, bool extlpbk)
+{
+	u32 val, bmcr, mac_mode, ptest = 0;
 
-	/* Initialize invariants of the rings, we only set this
-	 * stuff once.  This works because the card does not
-	 * write into the rx buffer posting rings.
-	 */
-	for (i = 0; i <= tp->rx_std_ring_mask; i++) {
-		struct tg3_rx_buffer_desc *rxd;
+	tg3_phy_toggle_apd(tp, false);
+	tg3_phy_toggle_automdix(tp, 0);
 
-		rxd = &tpr->rx_std[i];
-		rxd->idx_len = rx_pkt_dma_sz << RXD_LEN_SHIFT;
-		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
-		rxd->opaque = (RXD_OPAQUE_RING_STD |
-			       (i << RXD_OPAQUE_INDEX_SHIFT));
-	}
+	if (extlpbk && tg3_phy_set_extloopbk(tp))
+		return -EIO;
 
-	/* Now allocate fresh SKBs for each rx ring. */
-	for (i = 0; i < tp->rx_pending; i++) {
-		if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
-			netdev_warn(tp->dev,
-				    "Using a smaller RX standard ring. Only "
-				    "%d out of %d buffers were allocated "
-				    "successfully\n", i, tp->rx_pending);
-			if (i == 0)
-				goto initfail;
-			tp->rx_pending = i;
-			break;
+	bmcr = BMCR_FULLDPLX;
+	switch (speed) {
+	case SPEED_10:
+		break;
+	case SPEED_100:
+		bmcr |= BMCR_SPEED100;
+		break;
+	case SPEED_1000:
+	default:
+		if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
+			speed = SPEED_100;
+			bmcr |= BMCR_SPEED100;
+		} else {
+			speed = SPEED_1000;
+			bmcr |= BMCR_SPEED1000;
 		}
 	}
 
-	if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS))
-		goto done;
+	if (extlpbk) {
+		if (!(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
+			tg3_readphy(tp, MII_CTRL1000, &val);
+			val |= CTL1000_AS_MASTER |
+			       CTL1000_ENABLE_MASTER;
+			tg3_writephy(tp, MII_CTRL1000, val);
+		} else {
+			ptest = MII_TG3_FET_PTEST_TRIM_SEL |
+				MII_TG3_FET_PTEST_TRIM_2;
+			tg3_writephy(tp, MII_TG3_FET_PTEST, ptest);
+		}
+	} else
+		bmcr |= BMCR_LOOPBACK;
 
-	memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp));
+	tg3_writephy(tp, MII_BMCR, bmcr);
 
-	if (!tg3_flag(tp, JUMBO_RING_ENABLE))
-		goto done;
+	/* The write needs to be flushed for the FETs */
+	if (tp->phy_flags & TG3_PHYFLG_IS_FET)
+		tg3_readphy(tp, MII_BMCR, &bmcr);
 
-	for (i = 0; i <= tp->rx_jmb_ring_mask; i++) {
-		struct tg3_rx_buffer_desc *rxd;
+	udelay(40);
 
-		rxd = &tpr->rx_jmb[i].std;
+	if ((tp->phy_flags & TG3_PHYFLG_IS_FET) &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+		tg3_writephy(tp, MII_TG3_FET_PTEST, ptest |
+			     MII_TG3_FET_PTEST_FRC_TX_LINK |
+			     MII_TG3_FET_PTEST_FRC_TX_LOCK);
+
+		/* The write needs to be flushed for the AC131 */
+		tg3_readphy(tp, MII_TG3_FET_PTEST, &val);
+	}
+
+	/* Reset to prevent losing 1st rx packet intermittently */
+	if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
+	    tg3_flag(tp, 5780_CLASS)) {
+		tw32_f(MAC_RX_MODE, RX_MODE_RESET);
+		udelay(10);
+		tw32_f(MAC_RX_MODE, tp->rx_mode);
+	}
+
+	mac_mode = tp->mac_mode &
+		   ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+	if (speed == SPEED_1000)
+		mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	else
+		mac_mode |= MAC_MODE_PORT_MODE_MII;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+		u32 masked_phy_id = tp->phy_id & TG3_PHY_ID_MASK;
+
+		if (masked_phy_id == TG3_PHY_ID_BCM5401)
+			mac_mode &= ~MAC_MODE_LINK_POLARITY;
+		else if (masked_phy_id == TG3_PHY_ID_BCM5411)
+			mac_mode |= MAC_MODE_LINK_POLARITY;
+
+		tg3_writephy(tp, MII_TG3_EXT_CTRL,
+			     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
+	}
+
+	tw32(MAC_MODE, mac_mode);
+	udelay(40);
+
+	return 0;
+}
+
+static void tg3_set_loopback(struct net_device *dev, netdev_features_t features)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (features & NETIF_F_LOOPBACK) {
+		if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)
+			return;
+
+		spin_lock_bh(&tp->lock);
+		tg3_mac_loopback(tp, true);
+		netif_carrier_on(tp->dev);
+		spin_unlock_bh(&tp->lock);
+		netdev_info(dev, "Internal MAC loopback mode enabled.\n");
+	} else {
+		if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
+			return;
+
+		spin_lock_bh(&tp->lock);
+		tg3_mac_loopback(tp, false);
+		/* Force link status check */
+		tg3_setup_phy(tp, 1);
+		spin_unlock_bh(&tp->lock);
+		netdev_info(dev, "Internal MAC loopback mode disabled.\n");
+	}
+}
+
+static netdev_features_t tg3_fix_features(struct net_device *dev,
+	netdev_features_t features)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (dev->mtu > ETH_DATA_LEN && tg3_flag(tp, 5780_CLASS))
+		features &= ~NETIF_F_ALL_TSO;
+
+	return features;
+}
+
+static int tg3_set_features(struct net_device *dev, netdev_features_t features)
+{
+	netdev_features_t changed = dev->features ^ features;
+
+	if ((changed & NETIF_F_LOOPBACK) && netif_running(dev))
+		tg3_set_loopback(dev, features);
+
+	return 0;
+}
+
+static void tg3_rx_prodring_free(struct tg3 *tp,
+				 struct tg3_rx_prodring_set *tpr)
+{
+	int i;
+
+	if (tpr != &tp->napi[0].prodring) {
+		for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx;
+		     i = (i + 1) & tp->rx_std_ring_mask)
+			tg3_rx_data_free(tp, &tpr->rx_std_buffers[i],
+					tp->rx_pkt_map_sz);
+
+		if (tg3_flag(tp, JUMBO_CAPABLE)) {
+			for (i = tpr->rx_jmb_cons_idx;
+			     i != tpr->rx_jmb_prod_idx;
+			     i = (i + 1) & tp->rx_jmb_ring_mask) {
+				tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i],
+						TG3_RX_JMB_MAP_SZ);
+			}
+		}
+
+		return;
+	}
+
+	for (i = 0; i <= tp->rx_std_ring_mask; i++)
+		tg3_rx_data_free(tp, &tpr->rx_std_buffers[i],
+				tp->rx_pkt_map_sz);
+
+	if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) {
+		for (i = 0; i <= tp->rx_jmb_ring_mask; i++)
+			tg3_rx_data_free(tp, &tpr->rx_jmb_buffers[i],
+					TG3_RX_JMB_MAP_SZ);
+	}
+}
+
+/* Initialize rx rings for packet processing.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver.  tp->{tx,}lock are held and thus
+ * we may not sleep.
+ */
+static int tg3_rx_prodring_alloc(struct tg3 *tp,
+				 struct tg3_rx_prodring_set *tpr)
+{
+	u32 i, rx_pkt_dma_sz;
+
+	tpr->rx_std_cons_idx = 0;
+	tpr->rx_std_prod_idx = 0;
+	tpr->rx_jmb_cons_idx = 0;
+	tpr->rx_jmb_prod_idx = 0;
+
+	if (tpr != &tp->napi[0].prodring) {
+		memset(&tpr->rx_std_buffers[0], 0,
+		       TG3_RX_STD_BUFF_RING_SIZE(tp));
+		if (tpr->rx_jmb_buffers)
+			memset(&tpr->rx_jmb_buffers[0], 0,
+			       TG3_RX_JMB_BUFF_RING_SIZE(tp));
+		goto done;
+	}
+
+	/* Zero out all descriptors. */
+	memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp));
+
+	rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
+	if (tg3_flag(tp, 5780_CLASS) &&
+	    tp->dev->mtu > ETH_DATA_LEN)
+		rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ;
+	tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz);
+
+	/* Initialize invariants of the rings, we only set this
+	 * stuff once.  This works because the card does not
+	 * write into the rx buffer posting rings.
+	 */
+	for (i = 0; i <= tp->rx_std_ring_mask; i++) {
+		struct tg3_rx_buffer_desc *rxd;
+
+		rxd = &tpr->rx_std[i];
+		rxd->idx_len = rx_pkt_dma_sz << RXD_LEN_SHIFT;
+		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
+		rxd->opaque = (RXD_OPAQUE_RING_STD |
+			       (i << RXD_OPAQUE_INDEX_SHIFT));
+	}
+
+	/* Now allocate fresh SKBs for each rx ring. */
+	for (i = 0; i < tp->rx_pending; i++) {
+		if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
+			netdev_warn(tp->dev,
+				    "Using a smaller RX standard ring. Only "
+				    "%d out of %d buffers were allocated "
+				    "successfully\n", i, tp->rx_pending);
+			if (i == 0)
+				goto initfail;
+			tp->rx_pending = i;
+			break;
+		}
+	}
+
+	if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS))
+		goto done;
+
+	memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp));
+
+	if (!tg3_flag(tp, JUMBO_RING_ENABLE))
+		goto done;
+
+	for (i = 0; i <= tp->rx_jmb_ring_mask; i++) {
+		struct tg3_rx_buffer_desc *rxd;
+
+		rxd = &tpr->rx_jmb[i].std;
 		rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
 		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
 				  RXD_FLAG_JUMBO;
@@ -7978,7 +8112,6 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
 			      nic_addr);
 }
 
-static void __tg3_set_rx_mode(struct net_device *);
 static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
 {
 	int i;
@@ -8215,56 +8348,143 @@ static void tg3_setup_rxbd_thresholds(struct tg3 *tp)
 		tw32(JMB_REPLENISH_LWM, bdcache_maxcnt);
 }
 
-static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp)
+static inline u32 calc_crc(unsigned char *buf, int len)
 {
-	int i;
+	u32 reg;
+	u32 tmp;
+	int j, k;
 
-	for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++)
-		tp->rss_ind_tbl[i] =
-			ethtool_rxfh_indir_default(i, tp->irq_cnt - 1);
-}
+	reg = 0xffffffff;
 
-static void tg3_rss_check_indir_tbl(struct tg3 *tp)
-{
-	int i;
+	for (j = 0; j < len; j++) {
+		reg ^= buf[j];
 
-	if (!tg3_flag(tp, SUPPORT_MSIX))
-		return;
+		for (k = 0; k < 8; k++) {
+			tmp = reg & 0x01;
 
-	if (tp->irq_cnt <= 2) {
-		memset(&tp->rss_ind_tbl[0], 0, sizeof(tp->rss_ind_tbl));
-		return;
-	}
+			reg >>= 1;
 
-	/* Validate table against current IRQ count */
-	for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
-		if (tp->rss_ind_tbl[i] >= tp->irq_cnt - 1)
-			break;
+			if (tmp)
+				reg ^= 0xedb88320;
+		}
 	}
 
-	if (i != TG3_RSS_INDIR_TBL_SIZE)
-		tg3_rss_init_dflt_indir_tbl(tp);
+	return ~reg;
 }
 
-static void tg3_rss_write_indir_tbl(struct tg3 *tp)
+static void tg3_set_multi(struct tg3 *tp, unsigned int accept_all)
 {
-	int i = 0;
-	u32 reg = MAC_RSS_INDIR_TBL_0;
-
-	while (i < TG3_RSS_INDIR_TBL_SIZE) {
-		u32 val = tp->rss_ind_tbl[i];
-		i++;
-		for (; i % 8; i++) {
-			val <<= 4;
-			val |= tp->rss_ind_tbl[i];
-		}
-		tw32(reg, val);
-		reg += 4;
-	}
+	/* accept or reject all multicast frames */
+	tw32(MAC_HASH_REG_0, accept_all ? 0xffffffff : 0);
+	tw32(MAC_HASH_REG_1, accept_all ? 0xffffffff : 0);
+	tw32(MAC_HASH_REG_2, accept_all ? 0xffffffff : 0);
+	tw32(MAC_HASH_REG_3, accept_all ? 0xffffffff : 0);
 }
 
-/* tp->lock is held. */
-static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
+static void __tg3_set_rx_mode(struct net_device *dev)
+{
+	struct tg3 *tp = netdev_priv(dev);
+	u32 rx_mode;
+
+	rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC |
+				  RX_MODE_KEEP_VLAN_TAG);
+
+#if !defined(CONFIG_VLAN_8021Q) && !defined(CONFIG_VLAN_8021Q_MODULE)
+	/* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
+	 * flag clear.
+	 */
+	if (!tg3_flag(tp, ENABLE_ASF))
+		rx_mode |= RX_MODE_KEEP_VLAN_TAG;
+#endif
+
+	if (dev->flags & IFF_PROMISC) {
+		/* Promiscuous mode. */
+		rx_mode |= RX_MODE_PROMISC;
+	} else if (dev->flags & IFF_ALLMULTI) {
+		/* Accept all multicast. */
+		tg3_set_multi(tp, 1);
+	} else if (netdev_mc_empty(dev)) {
+		/* Reject all multicast. */
+		tg3_set_multi(tp, 0);
+	} else {
+		/* Accept one or more multicast(s). */
+		struct netdev_hw_addr *ha;
+		u32 mc_filter[4] = { 0, };
+		u32 regidx;
+		u32 bit;
+		u32 crc;
+
+		netdev_for_each_mc_addr(ha, dev) {
+			crc = calc_crc(ha->addr, ETH_ALEN);
+			bit = ~crc & 0x7f;
+			regidx = (bit & 0x60) >> 5;
+			bit &= 0x1f;
+			mc_filter[regidx] |= (1 << bit);
+		}
+
+		tw32(MAC_HASH_REG_0, mc_filter[0]);
+		tw32(MAC_HASH_REG_1, mc_filter[1]);
+		tw32(MAC_HASH_REG_2, mc_filter[2]);
+		tw32(MAC_HASH_REG_3, mc_filter[3]);
+	}
+
+	if (rx_mode != tp->rx_mode) {
+		tp->rx_mode = rx_mode;
+		tw32_f(MAC_RX_MODE, rx_mode);
+		udelay(10);
+	}
+}
+
+static void tg3_rss_init_dflt_indir_tbl(struct tg3 *tp)
+{
+	int i;
+
+	for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++)
+		tp->rss_ind_tbl[i] =
+			ethtool_rxfh_indir_default(i, tp->irq_cnt - 1);
+}
+
+static void tg3_rss_check_indir_tbl(struct tg3 *tp)
+{
+	int i;
+
+	if (!tg3_flag(tp, SUPPORT_MSIX))
+		return;
+
+	if (tp->irq_cnt <= 2) {
+		memset(&tp->rss_ind_tbl[0], 0, sizeof(tp->rss_ind_tbl));
+		return;
+	}
+
+	/* Validate table against current IRQ count */
+	for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
+		if (tp->rss_ind_tbl[i] >= tp->irq_cnt - 1)
+			break;
+	}
+
+	if (i != TG3_RSS_INDIR_TBL_SIZE)
+		tg3_rss_init_dflt_indir_tbl(tp);
+}
+
+static void tg3_rss_write_indir_tbl(struct tg3 *tp)
+{
+	int i = 0;
+	u32 reg = MAC_RSS_INDIR_TBL_0;
+
+	while (i < TG3_RSS_INDIR_TBL_SIZE) {
+		u32 val = tp->rss_ind_tbl[i];
+		i++;
+		for (; i % 8; i++) {
+			val <<= 4;
+			val |= tp->rss_ind_tbl[i];
+		}
+		tw32(reg, val);
+		reg += 4;
+	}
+}
+
+/* tp->lock is held. */
+static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
 	u32 val, rdmac_mode;
 	int i, err, limit;
@@ -8690,9 +8910,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	if (tg3_flag(tp, PCI_EXPRESS))
 		rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
-		rdmac_mode |= RDMAC_MODE_JMB_2K_MMRR;
-
 	if (tg3_flag(tp, HW_TSO_1) ||
 	    tg3_flag(tp, HW_TSO_2) ||
 	    tg3_flag(tp, HW_TSO_3))
@@ -9039,12 +9256,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	}
 
 	if (!tg3_flag(tp, USE_PHYLIB)) {
-		if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+		if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
 			tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
-			tp->link_config.speed = tp->link_config.orig_speed;
-			tp->link_config.duplex = tp->link_config.orig_duplex;
-			tp->link_config.autoneg = tp->link_config.orig_autoneg;
-		}
 
 		err = tg3_setup_phy(tp, 0);
 		if (err)
@@ -9135,6 +9348,74 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
 	return tg3_reset_hw(tp, reset_phy);
 }
 
+/* Restart hardware after configuration changes, self-test, etc.
+ * Invoked with tp->lock held.
+ */
+static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
+	__releases(tp->lock)
+	__acquires(tp->lock)
+{
+	int err;
+
+	err = tg3_init_hw(tp, reset_phy);
+	if (err) {
+		netdev_err(tp->dev,
+			   "Failed to re-initialize device, aborting\n");
+		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+		tg3_full_unlock(tp);
+		del_timer_sync(&tp->timer);
+		tp->irq_sync = 0;
+		tg3_napi_enable(tp);
+		dev_close(tp->dev);
+		tg3_full_lock(tp, 0);
+	}
+	return err;
+}
+
+static void tg3_reset_task(struct work_struct *work)
+{
+	struct tg3 *tp = container_of(work, struct tg3, reset_task);
+	int err;
+
+	tg3_full_lock(tp, 0);
+
+	if (!netif_running(tp->dev)) {
+		tg3_flag_clear(tp, RESET_TASK_PENDING);
+		tg3_full_unlock(tp);
+		return;
+	}
+
+	tg3_full_unlock(tp);
+
+	tg3_phy_stop(tp);
+
+	tg3_netif_stop(tp);
+
+	tg3_full_lock(tp, 1);
+
+	if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
+		tp->write32_tx_mbox = tg3_write32_tx_mbox;
+		tp->write32_rx_mbox = tg3_write_flush_reg32;
+		tg3_flag_set(tp, MBOX_WRITE_REORDER);
+		tg3_flag_clear(tp, TX_RECOVERY_PENDING);
+	}
+
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
+	err = tg3_init_hw(tp, 1);
+	if (err)
+		goto out;
+
+	tg3_netif_start(tp);
+
+out:
+	tg3_full_unlock(tp);
+
+	if (!err)
+		tg3_phy_start(tp);
+
+	tg3_flag_clear(tp, RESET_TASK_PENDING);
+}
+
 #define TG3_STAT_ADD32(PSTAT, REG) \
 do {	u32 __val = tr32(REG); \
 	(PSTAT)->low += __val; \
@@ -9883,9 +10164,6 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp,
 	struct tg3_ethtool_stats *old_estats = &tp->estats_prev;
 	struct tg3_hw_stats *hw_stats = tp->hw_stats;
 
-	if (!hw_stats)
-		return old_estats;
-
 	ESTAT_ADD(rx_octets);
 	ESTAT_ADD(rx_fragments);
 	ESTAT_ADD(rx_ucast_packets);
@@ -10030,153 +10308,54 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev,
 	return stats;
 }
 
-static inline u32 calc_crc(unsigned char *buf, int len)
+static int tg3_get_regs_len(struct net_device *dev)
 {
-	u32 reg;
-	u32 tmp;
-	int j, k;
+	return TG3_REG_BLK_SIZE;
+}
 
-	reg = 0xffffffff;
+static void tg3_get_regs(struct net_device *dev,
+		struct ethtool_regs *regs, void *_p)
+{
+	struct tg3 *tp = netdev_priv(dev);
 
-	for (j = 0; j < len; j++) {
-		reg ^= buf[j];
+	regs->version = 0;
 
-		for (k = 0; k < 8; k++) {
-			tmp = reg & 0x01;
+	memset(_p, 0, TG3_REG_BLK_SIZE);
 
-			reg >>= 1;
+	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
+		return;
 
-			if (tmp)
-				reg ^= 0xedb88320;
-		}
-	}
+	tg3_full_lock(tp, 0);
 
-	return ~reg;
+	tg3_dump_legacy_regs(tp, (u32 *)_p);
+
+	tg3_full_unlock(tp);
 }
 
-static void tg3_set_multi(struct tg3 *tp, unsigned int accept_all)
+static int tg3_get_eeprom_len(struct net_device *dev)
 {
-	/* accept or reject all multicast frames */
-	tw32(MAC_HASH_REG_0, accept_all ? 0xffffffff : 0);
-	tw32(MAC_HASH_REG_1, accept_all ? 0xffffffff : 0);
-	tw32(MAC_HASH_REG_2, accept_all ? 0xffffffff : 0);
-	tw32(MAC_HASH_REG_3, accept_all ? 0xffffffff : 0);
+	struct tg3 *tp = netdev_priv(dev);
+
+	return tp->nvram_size;
 }
 
-static void __tg3_set_rx_mode(struct net_device *dev)
+static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
 	struct tg3 *tp = netdev_priv(dev);
-	u32 rx_mode;
+	int ret;
+	u8  *pd;
+	u32 i, offset, len, b_offset, b_count;
+	__be32 val;
 
-	rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC |
-				  RX_MODE_KEEP_VLAN_TAG);
+	if (tg3_flag(tp, NO_NVRAM))
+		return -EINVAL;
 
-#if !defined(CONFIG_VLAN_8021Q) && !defined(CONFIG_VLAN_8021Q_MODULE)
-	/* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
-	 * flag clear.
-	 */
-	if (!tg3_flag(tp, ENABLE_ASF))
-		rx_mode |= RX_MODE_KEEP_VLAN_TAG;
-#endif
+	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
+		return -EAGAIN;
 
-	if (dev->flags & IFF_PROMISC) {
-		/* Promiscuous mode. */
-		rx_mode |= RX_MODE_PROMISC;
-	} else if (dev->flags & IFF_ALLMULTI) {
-		/* Accept all multicast. */
-		tg3_set_multi(tp, 1);
-	} else if (netdev_mc_empty(dev)) {
-		/* Reject all multicast. */
-		tg3_set_multi(tp, 0);
-	} else {
-		/* Accept one or more multicast(s). */
-		struct netdev_hw_addr *ha;
-		u32 mc_filter[4] = { 0, };
-		u32 regidx;
-		u32 bit;
-		u32 crc;
-
-		netdev_for_each_mc_addr(ha, dev) {
-			crc = calc_crc(ha->addr, ETH_ALEN);
-			bit = ~crc & 0x7f;
-			regidx = (bit & 0x60) >> 5;
-			bit &= 0x1f;
-			mc_filter[regidx] |= (1 << bit);
-		}
-
-		tw32(MAC_HASH_REG_0, mc_filter[0]);
-		tw32(MAC_HASH_REG_1, mc_filter[1]);
-		tw32(MAC_HASH_REG_2, mc_filter[2]);
-		tw32(MAC_HASH_REG_3, mc_filter[3]);
-	}
-
-	if (rx_mode != tp->rx_mode) {
-		tp->rx_mode = rx_mode;
-		tw32_f(MAC_RX_MODE, rx_mode);
-		udelay(10);
-	}
-}
-
-static void tg3_set_rx_mode(struct net_device *dev)
-{
-	struct tg3 *tp = netdev_priv(dev);
-
-	if (!netif_running(dev))
-		return;
-
-	tg3_full_lock(tp, 0);
-	__tg3_set_rx_mode(dev);
-	tg3_full_unlock(tp);
-}
-
-static int tg3_get_regs_len(struct net_device *dev)
-{
-	return TG3_REG_BLK_SIZE;
-}
-
-static void tg3_get_regs(struct net_device *dev,
-		struct ethtool_regs *regs, void *_p)
-{
-	struct tg3 *tp = netdev_priv(dev);
-
-	regs->version = 0;
-
-	memset(_p, 0, TG3_REG_BLK_SIZE);
-
-	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
-		return;
-
-	tg3_full_lock(tp, 0);
-
-	tg3_dump_legacy_regs(tp, (u32 *)_p);
-
-	tg3_full_unlock(tp);
-}
-
-static int tg3_get_eeprom_len(struct net_device *dev)
-{
-	struct tg3 *tp = netdev_priv(dev);
-
-	return tp->nvram_size;
-}
-
-static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
-{
-	struct tg3 *tp = netdev_priv(dev);
-	int ret;
-	u8  *pd;
-	u32 i, offset, len, b_offset, b_count;
-	__be32 val;
-
-	if (tg3_flag(tp, NO_NVRAM))
-		return -EINVAL;
-
-	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
-		return -EAGAIN;
-
-	offset = eeprom->offset;
-	len = eeprom->len;
-	eeprom->len = 0;
+	offset = eeprom->offset;
+	len = eeprom->len;
+	eeprom->len = 0;
 
 	eeprom->magic = TG3_EEPROM_MAGIC;
 
@@ -10223,8 +10402,6 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 	return 0;
 }
 
-static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf);
-
 static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
 {
 	struct tg3 *tp = netdev_priv(dev);
@@ -10338,8 +10515,8 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 				cmd->eth_tp_mdix = ETH_TP_MDI;
 		}
 	} else {
-		ethtool_cmd_speed_set(cmd, SPEED_INVALID);
-		cmd->duplex = DUPLEX_INVALID;
+		ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
+		cmd->duplex = DUPLEX_UNKNOWN;
 		cmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
 	}
 	cmd->phy_address = tp->phy_addr;
@@ -10421,18 +10598,14 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	if (cmd->autoneg == AUTONEG_ENABLE) {
 		tp->link_config.advertising = (cmd->advertising |
 					      ADVERTISED_Autoneg);
-		tp->link_config.speed = SPEED_INVALID;
-		tp->link_config.duplex = DUPLEX_INVALID;
+		tp->link_config.speed = SPEED_UNKNOWN;
+		tp->link_config.duplex = DUPLEX_UNKNOWN;
 	} else {
 		tp->link_config.advertising = 0;
 		tp->link_config.speed = speed;
 		tp->link_config.duplex = cmd->duplex;
 	}
 
-	tp->link_config.orig_speed = tp->link_config.speed;
-	tp->link_config.orig_duplex = tp->link_config.duplex;
-	tp->link_config.orig_autoneg = tp->link_config.autoneg;
-
 	if (netif_running(dev))
 		tg3_setup_phy(tp, 1);
 
@@ -10679,10 +10852,10 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 			if (!epause->autoneg)
 				tg3_setup_flow_control(tp, 0, 0);
 		} else {
-			tp->link_config.orig_advertising &=
+			tp->link_config.advertising &=
 					~(ADVERTISED_Pause |
 					  ADVERTISED_Asym_Pause);
-			tp->link_config.orig_advertising |= newadv;
+			tp->link_config.advertising |= newadv;
 		}
 	} else {
 		int irq_sync = 0;
@@ -10859,7 +11032,10 @@ static void tg3_get_ethtool_stats(struct net_device *dev,
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	tg3_get_estats(tp, (struct tg3_ethtool_stats *)tmp_stats);
+	if (tp->hw_stats)
+		tg3_get_estats(tp, (struct tg3_ethtool_stats *)tmp_stats);
+	else
+		memset(tmp_stats, 0, sizeof(struct tg3_ethtool_stats));
 }
 
 static __be32 *tg3_vpd_readblock(struct tg3 *tp, u32 *vpdlen)
@@ -12040,943 +12216,785 @@ static const struct ethtool_ops tg3_ethtool_ops = {
 	.set_rxfh_indir		= tg3_set_rxfh_indir,
 };
 
-static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
+static void tg3_set_rx_mode(struct net_device *dev)
 {
-	u32 cursize, val, magic;
-
-	tp->nvram_size = EEPROM_CHIP_SIZE;
-
-	if (tg3_nvram_read(tp, 0, &magic) != 0)
-		return;
+	struct tg3 *tp = netdev_priv(dev);
 
-	if ((magic != TG3_EEPROM_MAGIC) &&
-	    ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) &&
-	    ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW))
+	if (!netif_running(dev))
 		return;
 
-	/*
-	 * Size the chip by reading offsets at increasing powers of two.
-	 * When we encounter our validation signature, we know the addressing
-	 * has wrapped around, and thus have our chip size.
-	 */
-	cursize = 0x10;
-
-	while (cursize < tp->nvram_size) {
-		if (tg3_nvram_read(tp, cursize, &val) != 0)
-			return;
-
-		if (val == magic)
-			break;
-
-		cursize <<= 1;
-	}
-
-	tp->nvram_size = cursize;
+	tg3_full_lock(tp, 0);
+	__tg3_set_rx_mode(dev);
+	tg3_full_unlock(tp);
 }
 
-static void __devinit tg3_get_nvram_size(struct tg3 *tp)
+static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
+			       int new_mtu)
 {
-	u32 val;
-
-	if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &val) != 0)
-		return;
-
-	/* Selfboot format */
-	if (val != TG3_EEPROM_MAGIC) {
-		tg3_get_eeprom_size(tp);
-		return;
-	}
+	dev->mtu = new_mtu;
 
-	if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
-		if (val != 0) {
-			/* This is confusing.  We want to operate on the
-			 * 16-bit value at offset 0xf2.  The tg3_nvram_read()
-			 * call will read from NVRAM and byteswap the data
-			 * according to the byteswapping settings for all
-			 * other register accesses.  This ensures the data we
-			 * want will always reside in the lower 16-bits.
-			 * However, the data in NVRAM is in LE format, which
-			 * means the data from the NVRAM read will always be
-			 * opposite the endianness of the CPU.  The 16-bit
-			 * byteswap then brings the data to CPU endianness.
-			 */
-			tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
-			return;
+	if (new_mtu > ETH_DATA_LEN) {
+		if (tg3_flag(tp, 5780_CLASS)) {
+			netdev_update_features(dev);
+			tg3_flag_clear(tp, TSO_CAPABLE);
+		} else {
+			tg3_flag_set(tp, JUMBO_RING_ENABLE);
 		}
-	}
-	tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-}
-
-static void __devinit tg3_get_nvram_info(struct tg3 *tp)
-{
-	u32 nvcfg1;
-
-	nvcfg1 = tr32(NVRAM_CFG1);
-	if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
-		tg3_flag_set(tp, FLASH);
 	} else {
-		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-		tw32(NVRAM_CFG1, nvcfg1);
-	}
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
-	    tg3_flag(tp, 5780_CLASS)) {
-		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
-		case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
-			tg3_flag_set(tp, NVRAM_BUFFERED);
-			break;
-		case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
-			break;
-		case FLASH_VENDOR_ATMEL_EEPROM:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-			tg3_flag_set(tp, NVRAM_BUFFERED);
-			break;
-		case FLASH_VENDOR_ST:
-			tp->nvram_jedecnum = JEDEC_ST;
-			tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
-			tg3_flag_set(tp, NVRAM_BUFFERED);
-			break;
-		case FLASH_VENDOR_SAIFUN:
-			tp->nvram_jedecnum = JEDEC_SAIFUN;
-			tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
-			break;
-		case FLASH_VENDOR_SST_SMALL:
-		case FLASH_VENDOR_SST_LARGE:
-			tp->nvram_jedecnum = JEDEC_SST;
-			tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
-			break;
+		if (tg3_flag(tp, 5780_CLASS)) {
+			tg3_flag_set(tp, TSO_CAPABLE);
+			netdev_update_features(dev);
 		}
-	} else {
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-	}
-}
-
-static void __devinit tg3_nvram_get_pagesize(struct tg3 *tp, u32 nvmcfg1)
-{
-	switch (nvmcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
-	case FLASH_5752PAGE_SIZE_256:
-		tp->nvram_pagesize = 256;
-		break;
-	case FLASH_5752PAGE_SIZE_512:
-		tp->nvram_pagesize = 512;
-		break;
-	case FLASH_5752PAGE_SIZE_1K:
-		tp->nvram_pagesize = 1024;
-		break;
-	case FLASH_5752PAGE_SIZE_2K:
-		tp->nvram_pagesize = 2048;
-		break;
-	case FLASH_5752PAGE_SIZE_4K:
-		tp->nvram_pagesize = 4096;
-		break;
-	case FLASH_5752PAGE_SIZE_264:
-		tp->nvram_pagesize = 264;
-		break;
-	case FLASH_5752PAGE_SIZE_528:
-		tp->nvram_pagesize = 528;
-		break;
-	}
-}
-
-static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
-{
-	u32 nvcfg1;
-
-	nvcfg1 = tr32(NVRAM_CFG1);
-
-	/* NVRAM protection for TPM */
-	if (nvcfg1 & (1 << 27))
-		tg3_flag_set(tp, PROTECTED_NVRAM);
-
-	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-	case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
-	case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		break;
-	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		break;
-	case FLASH_5752VENDOR_ST_M45PE10:
-	case FLASH_5752VENDOR_ST_M45PE20:
-	case FLASH_5752VENDOR_ST_M45PE40:
-		tp->nvram_jedecnum = JEDEC_ST;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		break;
-	}
-
-	if (tg3_flag(tp, FLASH)) {
-		tg3_nvram_get_pagesize(tp, nvcfg1);
-	} else {
-		/* For eeprom, set pagesize to maximum eeprom size */
-		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-
-		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-		tw32(NVRAM_CFG1, nvcfg1);
-	}
-}
-
-static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
-{
-	u32 nvcfg1, protect = 0;
-
-	nvcfg1 = tr32(NVRAM_CFG1);
-
-	/* NVRAM protection for TPM */
-	if (nvcfg1 & (1 << 27)) {
-		tg3_flag_set(tp, PROTECTED_NVRAM);
-		protect = 1;
-	}
-
-	nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
-	switch (nvcfg1) {
-	case FLASH_5755VENDOR_ATMEL_FLASH_1:
-	case FLASH_5755VENDOR_ATMEL_FLASH_2:
-	case FLASH_5755VENDOR_ATMEL_FLASH_3:
-	case FLASH_5755VENDOR_ATMEL_FLASH_5:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		tp->nvram_pagesize = 264;
-		if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
-		    nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
-			tp->nvram_size = (protect ? 0x3e200 :
-					  TG3_NVRAM_SIZE_512KB);
-		else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
-			tp->nvram_size = (protect ? 0x1f200 :
-					  TG3_NVRAM_SIZE_256KB);
-		else
-			tp->nvram_size = (protect ? 0x1f200 :
-					  TG3_NVRAM_SIZE_128KB);
-		break;
-	case FLASH_5752VENDOR_ST_M45PE10:
-	case FLASH_5752VENDOR_ST_M45PE20:
-	case FLASH_5752VENDOR_ST_M45PE40:
-		tp->nvram_jedecnum = JEDEC_ST;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		tp->nvram_pagesize = 256;
-		if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
-			tp->nvram_size = (protect ?
-					  TG3_NVRAM_SIZE_64KB :
-					  TG3_NVRAM_SIZE_128KB);
-		else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
-			tp->nvram_size = (protect ?
-					  TG3_NVRAM_SIZE_64KB :
-					  TG3_NVRAM_SIZE_256KB);
-		else
-			tp->nvram_size = (protect ?
-					  TG3_NVRAM_SIZE_128KB :
-					  TG3_NVRAM_SIZE_512KB);
-		break;
+		tg3_flag_clear(tp, JUMBO_RING_ENABLE);
 	}
 }
 
-static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
+static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 {
-	u32 nvcfg1;
-
-	nvcfg1 = tr32(NVRAM_CFG1);
+	struct tg3 *tp = netdev_priv(dev);
+	int err;
 
-	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-	case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
-	case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
-	case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
-	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+	if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp))
+		return -EINVAL;
 
-		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-		tw32(NVRAM_CFG1, nvcfg1);
-		break;
-	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-	case FLASH_5755VENDOR_ATMEL_FLASH_1:
-	case FLASH_5755VENDOR_ATMEL_FLASH_2:
-	case FLASH_5755VENDOR_ATMEL_FLASH_3:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		tp->nvram_pagesize = 264;
-		break;
-	case FLASH_5752VENDOR_ST_M45PE10:
-	case FLASH_5752VENDOR_ST_M45PE20:
-	case FLASH_5752VENDOR_ST_M45PE40:
-		tp->nvram_jedecnum = JEDEC_ST;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		tp->nvram_pagesize = 256;
-		break;
+	if (!netif_running(dev)) {
+		/* We'll just catch it later when the
+		 * device is up'd.
+		 */
+		tg3_set_mtu(dev, tp, new_mtu);
+		return 0;
 	}
-}
-
-static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
-{
-	u32 nvcfg1, protect = 0;
-
-	nvcfg1 = tr32(NVRAM_CFG1);
 
-	/* NVRAM protection for TPM */
-	if (nvcfg1 & (1 << 27)) {
-		tg3_flag_set(tp, PROTECTED_NVRAM);
-		protect = 1;
-	}
+	tg3_phy_stop(tp);
 
-	nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
-	switch (nvcfg1) {
-	case FLASH_5761VENDOR_ATMEL_ADB021D:
-	case FLASH_5761VENDOR_ATMEL_ADB041D:
-	case FLASH_5761VENDOR_ATMEL_ADB081D:
-	case FLASH_5761VENDOR_ATMEL_ADB161D:
-	case FLASH_5761VENDOR_ATMEL_MDB021D:
-	case FLASH_5761VENDOR_ATMEL_MDB041D:
-	case FLASH_5761VENDOR_ATMEL_MDB081D:
-	case FLASH_5761VENDOR_ATMEL_MDB161D:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
-		tp->nvram_pagesize = 256;
-		break;
-	case FLASH_5761VENDOR_ST_A_M45PE20:
-	case FLASH_5761VENDOR_ST_A_M45PE40:
-	case FLASH_5761VENDOR_ST_A_M45PE80:
-	case FLASH_5761VENDOR_ST_A_M45PE16:
-	case FLASH_5761VENDOR_ST_M_M45PE20:
-	case FLASH_5761VENDOR_ST_M_M45PE40:
-	case FLASH_5761VENDOR_ST_M_M45PE80:
-	case FLASH_5761VENDOR_ST_M_M45PE16:
-		tp->nvram_jedecnum = JEDEC_ST;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-		tp->nvram_pagesize = 256;
-		break;
-	}
+	tg3_netif_stop(tp);
 
-	if (protect) {
-		tp->nvram_size = tr32(NVRAM_ADDR_LOCKOUT);
-	} else {
-		switch (nvcfg1) {
-		case FLASH_5761VENDOR_ATMEL_ADB161D:
-		case FLASH_5761VENDOR_ATMEL_MDB161D:
-		case FLASH_5761VENDOR_ST_A_M45PE16:
-		case FLASH_5761VENDOR_ST_M_M45PE16:
-			tp->nvram_size = TG3_NVRAM_SIZE_2MB;
-			break;
-		case FLASH_5761VENDOR_ATMEL_ADB081D:
-		case FLASH_5761VENDOR_ATMEL_MDB081D:
-		case FLASH_5761VENDOR_ST_A_M45PE80:
-		case FLASH_5761VENDOR_ST_M_M45PE80:
-			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
-			break;
-		case FLASH_5761VENDOR_ATMEL_ADB041D:
-		case FLASH_5761VENDOR_ATMEL_MDB041D:
-		case FLASH_5761VENDOR_ST_A_M45PE40:
-		case FLASH_5761VENDOR_ST_M_M45PE40:
-			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-			break;
-		case FLASH_5761VENDOR_ATMEL_ADB021D:
-		case FLASH_5761VENDOR_ATMEL_MDB021D:
-		case FLASH_5761VENDOR_ST_A_M45PE20:
-		case FLASH_5761VENDOR_ST_M_M45PE20:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-			break;
-		}
-	}
-}
+	tg3_full_lock(tp, 1);
 
-static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
-{
-	tp->nvram_jedecnum = JEDEC_ATMEL;
-	tg3_flag_set(tp, NVRAM_BUFFERED);
-	tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+
+	tg3_set_mtu(dev, tp, new_mtu);
+
+	err = tg3_restart_hw(tp, 0);
+
+	if (!err)
+		tg3_netif_start(tp);
+
+	tg3_full_unlock(tp);
+
+	if (!err)
+		tg3_phy_start(tp);
+
+	return err;
 }
 
-static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
+static const struct net_device_ops tg3_netdev_ops = {
+	.ndo_open		= tg3_open,
+	.ndo_stop		= tg3_close,
+	.ndo_start_xmit		= tg3_start_xmit,
+	.ndo_get_stats64	= tg3_get_stats64,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_rx_mode	= tg3_set_rx_mode,
+	.ndo_set_mac_address	= tg3_set_mac_addr,
+	.ndo_do_ioctl		= tg3_ioctl,
+	.ndo_tx_timeout		= tg3_tx_timeout,
+	.ndo_change_mtu		= tg3_change_mtu,
+	.ndo_fix_features	= tg3_fix_features,
+	.ndo_set_features	= tg3_set_features,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= tg3_poll_controller,
+#endif
+};
+
+static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
 {
-	u32 nvcfg1;
+	u32 cursize, val, magic;
 
-	nvcfg1 = tr32(NVRAM_CFG1);
+	tp->nvram_size = EEPROM_CHIP_SIZE;
 
-	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-	case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
-	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+	if (tg3_nvram_read(tp, 0, &magic) != 0)
+		return;
 
-		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-		tw32(NVRAM_CFG1, nvcfg1);
+	if ((magic != TG3_EEPROM_MAGIC) &&
+	    ((magic & TG3_EEPROM_MAGIC_FW_MSK) != TG3_EEPROM_MAGIC_FW) &&
+	    ((magic & TG3_EEPROM_MAGIC_HW_MSK) != TG3_EEPROM_MAGIC_HW))
 		return;
-	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-	case FLASH_57780VENDOR_ATMEL_AT45DB011D:
-	case FLASH_57780VENDOR_ATMEL_AT45DB011B:
-	case FLASH_57780VENDOR_ATMEL_AT45DB021D:
-	case FLASH_57780VENDOR_ATMEL_AT45DB021B:
-	case FLASH_57780VENDOR_ATMEL_AT45DB041D:
-	case FLASH_57780VENDOR_ATMEL_AT45DB041B:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
 
-		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-		case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-		case FLASH_57780VENDOR_ATMEL_AT45DB011D:
-		case FLASH_57780VENDOR_ATMEL_AT45DB011B:
-			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
-			break;
-		case FLASH_57780VENDOR_ATMEL_AT45DB021D:
-		case FLASH_57780VENDOR_ATMEL_AT45DB021B:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-			break;
-		case FLASH_57780VENDOR_ATMEL_AT45DB041D:
-		case FLASH_57780VENDOR_ATMEL_AT45DB041B:
-			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-			break;
-		}
-		break;
-	case FLASH_5752VENDOR_ST_M45PE10:
-	case FLASH_5752VENDOR_ST_M45PE20:
-	case FLASH_5752VENDOR_ST_M45PE40:
-		tp->nvram_jedecnum = JEDEC_ST;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
+	/*
+	 * Size the chip by reading offsets at increasing powers of two.
+	 * When we encounter our validation signature, we know the addressing
+	 * has wrapped around, and thus have our chip size.
+	 */
+	cursize = 0x10;
 
-		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-		case FLASH_5752VENDOR_ST_M45PE10:
-			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
-			break;
-		case FLASH_5752VENDOR_ST_M45PE20:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-			break;
-		case FLASH_5752VENDOR_ST_M45PE40:
-			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+	while (cursize < tp->nvram_size) {
+		if (tg3_nvram_read(tp, cursize, &val) != 0)
+			return;
+
+		if (val == magic)
 			break;
-		}
-		break;
-	default:
-		tg3_flag_set(tp, NO_NVRAM);
-		return;
+
+		cursize <<= 1;
 	}
 
-	tg3_nvram_get_pagesize(tp, nvcfg1);
-	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
-		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+	tp->nvram_size = cursize;
 }
 
+static void __devinit tg3_get_nvram_size(struct tg3 *tp)
+{
+	u32 val;
 
-static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
+	if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &val) != 0)
+		return;
+
+	/* Selfboot format */
+	if (val != TG3_EEPROM_MAGIC) {
+		tg3_get_eeprom_size(tp);
+		return;
+	}
+
+	if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
+		if (val != 0) {
+			/* This is confusing.  We want to operate on the
+			 * 16-bit value at offset 0xf2.  The tg3_nvram_read()
+			 * call will read from NVRAM and byteswap the data
+			 * according to the byteswapping settings for all
+			 * other register accesses.  This ensures the data we
+			 * want will always reside in the lower 16-bits.
+			 * However, the data in NVRAM is in LE format, which
+			 * means the data from the NVRAM read will always be
+			 * opposite the endianness of the CPU.  The 16-bit
+			 * byteswap then brings the data to CPU endianness.
+			 */
+			tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
+			return;
+		}
+	}
+	tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+}
+
+static void __devinit tg3_get_nvram_info(struct tg3 *tp)
 {
 	u32 nvcfg1;
 
 	nvcfg1 = tr32(NVRAM_CFG1);
-
-	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-	case FLASH_5717VENDOR_ATMEL_EEPROM:
-	case FLASH_5717VENDOR_MICRO_EEPROM:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-
+	if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
+		tg3_flag_set(tp, FLASH);
+	} else {
 		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
 		tw32(NVRAM_CFG1, nvcfg1);
-		return;
-	case FLASH_5717VENDOR_ATMEL_MDB011D:
-	case FLASH_5717VENDOR_ATMEL_ADB011B:
-	case FLASH_5717VENDOR_ATMEL_ADB011D:
-	case FLASH_5717VENDOR_ATMEL_MDB021D:
-	case FLASH_5717VENDOR_ATMEL_ADB021B:
-	case FLASH_5717VENDOR_ATMEL_ADB021D:
-	case FLASH_5717VENDOR_ATMEL_45USPT:
-		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
+	}
 
-		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-		case FLASH_5717VENDOR_ATMEL_MDB021D:
-			/* Detect size with tg3_nvram_get_size() */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+	    tg3_flag(tp, 5780_CLASS)) {
+		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
+		case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
+			tp->nvram_jedecnum = JEDEC_ATMEL;
+			tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+			tg3_flag_set(tp, NVRAM_BUFFERED);
 			break;
-		case FLASH_5717VENDOR_ATMEL_ADB021B:
-		case FLASH_5717VENDOR_ATMEL_ADB021D:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+		case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
+			tp->nvram_jedecnum = JEDEC_ATMEL;
+			tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
 			break;
-		default:
-			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+		case FLASH_VENDOR_ATMEL_EEPROM:
+			tp->nvram_jedecnum = JEDEC_ATMEL;
+			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+			tg3_flag_set(tp, NVRAM_BUFFERED);
 			break;
-		}
-		break;
-	case FLASH_5717VENDOR_ST_M_M25PE10:
-	case FLASH_5717VENDOR_ST_A_M25PE10:
-	case FLASH_5717VENDOR_ST_M_M45PE10:
-	case FLASH_5717VENDOR_ST_A_M45PE10:
-	case FLASH_5717VENDOR_ST_M_M25PE20:
-	case FLASH_5717VENDOR_ST_A_M25PE20:
-	case FLASH_5717VENDOR_ST_M_M45PE20:
-	case FLASH_5717VENDOR_ST_A_M45PE20:
-	case FLASH_5717VENDOR_ST_25USPT:
-	case FLASH_5717VENDOR_ST_45USPT:
-		tp->nvram_jedecnum = JEDEC_ST;
-		tg3_flag_set(tp, NVRAM_BUFFERED);
-		tg3_flag_set(tp, FLASH);
-
-		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-		case FLASH_5717VENDOR_ST_M_M25PE20:
-		case FLASH_5717VENDOR_ST_M_M45PE20:
-			/* Detect size with tg3_nvram_get_size() */
+		case FLASH_VENDOR_ST:
+			tp->nvram_jedecnum = JEDEC_ST;
+			tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
+			tg3_flag_set(tp, NVRAM_BUFFERED);
 			break;
-		case FLASH_5717VENDOR_ST_A_M25PE20:
-		case FLASH_5717VENDOR_ST_A_M45PE20:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+		case FLASH_VENDOR_SAIFUN:
+			tp->nvram_jedecnum = JEDEC_SAIFUN;
+			tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
 			break;
-		default:
-			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+		case FLASH_VENDOR_SST_SMALL:
+		case FLASH_VENDOR_SST_LARGE:
+			tp->nvram_jedecnum = JEDEC_SST;
+			tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
 			break;
 		}
+	} else {
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+	}
+}
+
+static void __devinit tg3_nvram_get_pagesize(struct tg3 *tp, u32 nvmcfg1)
+{
+	switch (nvmcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
+	case FLASH_5752PAGE_SIZE_256:
+		tp->nvram_pagesize = 256;
+		break;
+	case FLASH_5752PAGE_SIZE_512:
+		tp->nvram_pagesize = 512;
+		break;
+	case FLASH_5752PAGE_SIZE_1K:
+		tp->nvram_pagesize = 1024;
+		break;
+	case FLASH_5752PAGE_SIZE_2K:
+		tp->nvram_pagesize = 2048;
+		break;
+	case FLASH_5752PAGE_SIZE_4K:
+		tp->nvram_pagesize = 4096;
+		break;
+	case FLASH_5752PAGE_SIZE_264:
+		tp->nvram_pagesize = 264;
+		break;
+	case FLASH_5752PAGE_SIZE_528:
+		tp->nvram_pagesize = 528;
 		break;
-	default:
-		tg3_flag_set(tp, NO_NVRAM);
-		return;
 	}
-
-	tg3_nvram_get_pagesize(tp, nvcfg1);
-	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
-		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
 }
 
-static void __devinit tg3_get_5720_nvram_info(struct tg3 *tp)
+static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
 {
-	u32 nvcfg1, nvmpinstrp;
+	u32 nvcfg1;
 
 	nvcfg1 = tr32(NVRAM_CFG1);
-	nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
 
-	switch (nvmpinstrp) {
-	case FLASH_5720_EEPROM_HD:
-	case FLASH_5720_EEPROM_LD:
+	/* NVRAM protection for TPM */
+	if (nvcfg1 & (1 << 27))
+		tg3_flag_set(tp, PROTECTED_NVRAM);
+
+	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+	case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
+	case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
 		tg3_flag_set(tp, NVRAM_BUFFERED);
-
-		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-		tw32(NVRAM_CFG1, nvcfg1);
-		if (nvmpinstrp == FLASH_5720_EEPROM_HD)
-			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-		else
-			tp->nvram_pagesize = ATMEL_AT24C02_CHIP_SIZE;
-		return;
-	case FLASH_5720VENDOR_M_ATMEL_DB011D:
-	case FLASH_5720VENDOR_A_ATMEL_DB011B:
-	case FLASH_5720VENDOR_A_ATMEL_DB011D:
-	case FLASH_5720VENDOR_M_ATMEL_DB021D:
-	case FLASH_5720VENDOR_A_ATMEL_DB021B:
-	case FLASH_5720VENDOR_A_ATMEL_DB021D:
-	case FLASH_5720VENDOR_M_ATMEL_DB041D:
-	case FLASH_5720VENDOR_A_ATMEL_DB041B:
-	case FLASH_5720VENDOR_A_ATMEL_DB041D:
-	case FLASH_5720VENDOR_M_ATMEL_DB081D:
-	case FLASH_5720VENDOR_A_ATMEL_DB081D:
-	case FLASH_5720VENDOR_ATMEL_45USPT:
+		break;
+	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
 		tg3_flag_set(tp, NVRAM_BUFFERED);
 		tg3_flag_set(tp, FLASH);
-
-		switch (nvmpinstrp) {
-		case FLASH_5720VENDOR_M_ATMEL_DB021D:
-		case FLASH_5720VENDOR_A_ATMEL_DB021B:
-		case FLASH_5720VENDOR_A_ATMEL_DB021D:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-			break;
-		case FLASH_5720VENDOR_M_ATMEL_DB041D:
-		case FLASH_5720VENDOR_A_ATMEL_DB041B:
-		case FLASH_5720VENDOR_A_ATMEL_DB041D:
-			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-			break;
-		case FLASH_5720VENDOR_M_ATMEL_DB081D:
-		case FLASH_5720VENDOR_A_ATMEL_DB081D:
-			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
-			break;
-		default:
-			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
-			break;
-		}
 		break;
-	case FLASH_5720VENDOR_M_ST_M25PE10:
-	case FLASH_5720VENDOR_M_ST_M45PE10:
-	case FLASH_5720VENDOR_A_ST_M25PE10:
-	case FLASH_5720VENDOR_A_ST_M45PE10:
-	case FLASH_5720VENDOR_M_ST_M25PE20:
-	case FLASH_5720VENDOR_M_ST_M45PE20:
-	case FLASH_5720VENDOR_A_ST_M25PE20:
-	case FLASH_5720VENDOR_A_ST_M45PE20:
-	case FLASH_5720VENDOR_M_ST_M25PE40:
-	case FLASH_5720VENDOR_M_ST_M45PE40:
-	case FLASH_5720VENDOR_A_ST_M25PE40:
-	case FLASH_5720VENDOR_A_ST_M45PE40:
-	case FLASH_5720VENDOR_M_ST_M25PE80:
-	case FLASH_5720VENDOR_M_ST_M45PE80:
-	case FLASH_5720VENDOR_A_ST_M25PE80:
-	case FLASH_5720VENDOR_A_ST_M45PE80:
-	case FLASH_5720VENDOR_ST_25USPT:
-	case FLASH_5720VENDOR_ST_45USPT:
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
 		tp->nvram_jedecnum = JEDEC_ST;
 		tg3_flag_set(tp, NVRAM_BUFFERED);
 		tg3_flag_set(tp, FLASH);
-
-		switch (nvmpinstrp) {
-		case FLASH_5720VENDOR_M_ST_M25PE20:
-		case FLASH_5720VENDOR_M_ST_M45PE20:
-		case FLASH_5720VENDOR_A_ST_M25PE20:
-		case FLASH_5720VENDOR_A_ST_M45PE20:
-			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-			break;
-		case FLASH_5720VENDOR_M_ST_M25PE40:
-		case FLASH_5720VENDOR_M_ST_M45PE40:
-		case FLASH_5720VENDOR_A_ST_M25PE40:
-		case FLASH_5720VENDOR_A_ST_M45PE40:
-			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-			break;
-		case FLASH_5720VENDOR_M_ST_M25PE80:
-		case FLASH_5720VENDOR_M_ST_M45PE80:
-		case FLASH_5720VENDOR_A_ST_M25PE80:
-		case FLASH_5720VENDOR_A_ST_M45PE80:
-			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
-			break;
-		default:
-			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
-			break;
-		}
 		break;
-	default:
-		tg3_flag_set(tp, NO_NVRAM);
-		return;
 	}
 
-	tg3_nvram_get_pagesize(tp, nvcfg1);
-	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
-		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+	if (tg3_flag(tp, FLASH)) {
+		tg3_nvram_get_pagesize(tp, nvcfg1);
+	} else {
+		/* For eeprom, set pagesize to maximum eeprom size */
+		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+	}
 }
 
-/* Chips other than 5700/5701 use the NVRAM for fetching info. */
-static void __devinit tg3_nvram_init(struct tg3 *tp)
+static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
 {
-	tw32_f(GRC_EEPROM_ADDR,
-	     (EEPROM_ADDR_FSM_RESET |
-	      (EEPROM_DEFAULT_CLOCK_PERIOD <<
-	       EEPROM_ADDR_CLKPERD_SHIFT)));
-
-	msleep(1);
-
-	/* Enable seeprom accesses. */
-	tw32_f(GRC_LOCAL_CTRL,
-	     tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM);
-	udelay(100);
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
-		tg3_flag_set(tp, NVRAM);
+	u32 nvcfg1, protect = 0;
 
-		if (tg3_nvram_lock(tp)) {
-			netdev_warn(tp->dev,
-				    "Cannot get nvram lock, %s failed\n",
-				    __func__);
-			return;
-		}
-		tg3_enable_nvram_access(tp);
+	nvcfg1 = tr32(NVRAM_CFG1);
 
-		tp->nvram_size = 0;
+	/* NVRAM protection for TPM */
+	if (nvcfg1 & (1 << 27)) {
+		tg3_flag_set(tp, PROTECTED_NVRAM);
+		protect = 1;
+	}
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
-			tg3_get_5752_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
-			tg3_get_5755_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
-			tg3_get_5787_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
-			tg3_get_5761_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-			tg3_get_5906_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-			 tg3_flag(tp, 57765_CLASS))
-			tg3_get_57780_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
-			tg3_get_5717_nvram_info(tp);
-		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
-			tg3_get_5720_nvram_info(tp);
+	nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
+	switch (nvcfg1) {
+	case FLASH_5755VENDOR_ATMEL_FLASH_1:
+	case FLASH_5755VENDOR_ATMEL_FLASH_2:
+	case FLASH_5755VENDOR_ATMEL_FLASH_3:
+	case FLASH_5755VENDOR_ATMEL_FLASH_5:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tp->nvram_pagesize = 264;
+		if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
+		    nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
+			tp->nvram_size = (protect ? 0x3e200 :
+					  TG3_NVRAM_SIZE_512KB);
+		else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
+			tp->nvram_size = (protect ? 0x1f200 :
+					  TG3_NVRAM_SIZE_256KB);
 		else
-			tg3_get_nvram_info(tp);
+			tp->nvram_size = (protect ? 0x1f200 :
+					  TG3_NVRAM_SIZE_128KB);
+		break;
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tp->nvram_pagesize = 256;
+		if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
+			tp->nvram_size = (protect ?
+					  TG3_NVRAM_SIZE_64KB :
+					  TG3_NVRAM_SIZE_128KB);
+		else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
+			tp->nvram_size = (protect ?
+					  TG3_NVRAM_SIZE_64KB :
+					  TG3_NVRAM_SIZE_256KB);
+		else
+			tp->nvram_size = (protect ?
+					  TG3_NVRAM_SIZE_128KB :
+					  TG3_NVRAM_SIZE_512KB);
+		break;
+	}
+}
 
-		if (tp->nvram_size == 0)
-			tg3_get_nvram_size(tp);
+static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
+{
+	u32 nvcfg1;
 
-		tg3_disable_nvram_access(tp);
-		tg3_nvram_unlock(tp);
+	nvcfg1 = tr32(NVRAM_CFG1);
 
-	} else {
-		tg3_flag_clear(tp, NVRAM);
-		tg3_flag_clear(tp, NVRAM_BUFFERED);
+	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+	case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
+	case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+	case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
+	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
-		tg3_get_eeprom_size(tp);
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		break;
+	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+	case FLASH_5755VENDOR_ATMEL_FLASH_1:
+	case FLASH_5755VENDOR_ATMEL_FLASH_2:
+	case FLASH_5755VENDOR_ATMEL_FLASH_3:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tp->nvram_pagesize = 264;
+		break;
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tp->nvram_pagesize = 256;
+		break;
 	}
 }
 
-static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
-				    u32 offset, u32 len, u8 *buf)
+static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
 {
-	int i, j, rc = 0;
-	u32 val;
-
-	for (i = 0; i < len; i += 4) {
-		u32 addr;
-		__be32 data;
-
-		addr = offset + i;
-
-		memcpy(&data, buf + i, 4);
-
-		/*
-		 * The SEEPROM interface expects the data to always be opposite
-		 * the native endian format.  We accomplish this by reversing
-		 * all the operations that would have been performed on the
-		 * data from a call to tg3_nvram_read_be32().
-		 */
-		tw32(GRC_EEPROM_DATA, swab32(be32_to_cpu(data)));
+	u32 nvcfg1, protect = 0;
 
-		val = tr32(GRC_EEPROM_ADDR);
-		tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
+	nvcfg1 = tr32(NVRAM_CFG1);
 
-		val &= ~(EEPROM_ADDR_ADDR_MASK | EEPROM_ADDR_DEVID_MASK |
-			EEPROM_ADDR_READ);
-		tw32(GRC_EEPROM_ADDR, val |
-			(0 << EEPROM_ADDR_DEVID_SHIFT) |
-			(addr & EEPROM_ADDR_ADDR_MASK) |
-			EEPROM_ADDR_START |
-			EEPROM_ADDR_WRITE);
+	/* NVRAM protection for TPM */
+	if (nvcfg1 & (1 << 27)) {
+		tg3_flag_set(tp, PROTECTED_NVRAM);
+		protect = 1;
+	}
 
-		for (j = 0; j < 1000; j++) {
-			val = tr32(GRC_EEPROM_ADDR);
+	nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
+	switch (nvcfg1) {
+	case FLASH_5761VENDOR_ATMEL_ADB021D:
+	case FLASH_5761VENDOR_ATMEL_ADB041D:
+	case FLASH_5761VENDOR_ATMEL_ADB081D:
+	case FLASH_5761VENDOR_ATMEL_ADB161D:
+	case FLASH_5761VENDOR_ATMEL_MDB021D:
+	case FLASH_5761VENDOR_ATMEL_MDB041D:
+	case FLASH_5761VENDOR_ATMEL_MDB081D:
+	case FLASH_5761VENDOR_ATMEL_MDB161D:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+		tp->nvram_pagesize = 256;
+		break;
+	case FLASH_5761VENDOR_ST_A_M45PE20:
+	case FLASH_5761VENDOR_ST_A_M45PE40:
+	case FLASH_5761VENDOR_ST_A_M45PE80:
+	case FLASH_5761VENDOR_ST_A_M45PE16:
+	case FLASH_5761VENDOR_ST_M_M45PE20:
+	case FLASH_5761VENDOR_ST_M_M45PE40:
+	case FLASH_5761VENDOR_ST_M_M45PE80:
+	case FLASH_5761VENDOR_ST_M_M45PE16:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tp->nvram_pagesize = 256;
+		break;
+	}
 
-			if (val & EEPROM_ADDR_COMPLETE)
-				break;
-			msleep(1);
-		}
-		if (!(val & EEPROM_ADDR_COMPLETE)) {
-			rc = -EBUSY;
+	if (protect) {
+		tp->nvram_size = tr32(NVRAM_ADDR_LOCKOUT);
+	} else {
+		switch (nvcfg1) {
+		case FLASH_5761VENDOR_ATMEL_ADB161D:
+		case FLASH_5761VENDOR_ATMEL_MDB161D:
+		case FLASH_5761VENDOR_ST_A_M45PE16:
+		case FLASH_5761VENDOR_ST_M_M45PE16:
+			tp->nvram_size = TG3_NVRAM_SIZE_2MB;
+			break;
+		case FLASH_5761VENDOR_ATMEL_ADB081D:
+		case FLASH_5761VENDOR_ATMEL_MDB081D:
+		case FLASH_5761VENDOR_ST_A_M45PE80:
+		case FLASH_5761VENDOR_ST_M_M45PE80:
+			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+			break;
+		case FLASH_5761VENDOR_ATMEL_ADB041D:
+		case FLASH_5761VENDOR_ATMEL_MDB041D:
+		case FLASH_5761VENDOR_ST_A_M45PE40:
+		case FLASH_5761VENDOR_ST_M_M45PE40:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		case FLASH_5761VENDOR_ATMEL_ADB021D:
+		case FLASH_5761VENDOR_ATMEL_MDB021D:
+		case FLASH_5761VENDOR_ST_A_M45PE20:
+		case FLASH_5761VENDOR_ST_M_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
 			break;
 		}
 	}
+}
 
-	return rc;
+static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
+{
+	tp->nvram_jedecnum = JEDEC_ATMEL;
+	tg3_flag_set(tp, NVRAM_BUFFERED);
+	tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 }
 
-/* offset and length are dword aligned */
-static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
-		u8 *buf)
+static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
 {
-	int ret = 0;
-	u32 pagesize = tp->nvram_pagesize;
-	u32 pagemask = pagesize - 1;
-	u32 nvram_cmd;
-	u8 *tmp;
+	u32 nvcfg1;
 
-	tmp = kmalloc(pagesize, GFP_KERNEL);
-	if (tmp == NULL)
-		return -ENOMEM;
+	nvcfg1 = tr32(NVRAM_CFG1);
 
-	while (len) {
-		int j;
-		u32 phy_addr, page_off, size;
+	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+	case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
-		phy_addr = offset & ~pagemask;
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		return;
+	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+	case FLASH_57780VENDOR_ATMEL_AT45DB011D:
+	case FLASH_57780VENDOR_ATMEL_AT45DB011B:
+	case FLASH_57780VENDOR_ATMEL_AT45DB021D:
+	case FLASH_57780VENDOR_ATMEL_AT45DB021B:
+	case FLASH_57780VENDOR_ATMEL_AT45DB041D:
+	case FLASH_57780VENDOR_ATMEL_AT45DB041B:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
-		for (j = 0; j < pagesize; j += 4) {
-			ret = tg3_nvram_read_be32(tp, phy_addr + j,
-						  (__be32 *) (tmp + j));
-			if (ret)
-				break;
-		}
-		if (ret)
+		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+		case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+		case FLASH_57780VENDOR_ATMEL_AT45DB011D:
+		case FLASH_57780VENDOR_ATMEL_AT45DB011B:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
 			break;
-
-		page_off = offset & pagemask;
-		size = pagesize;
-		if (len < size)
-			size = len;
-
-		len -= size;
-
-		memcpy(tmp + page_off, buf, size);
-
-		offset = offset + (pagesize - page_off);
-
-		tg3_enable_nvram_access(tp);
-
-		/*
-		 * Before we can erase the flash page, we need
-		 * to issue a special "write enable" command.
-		 */
-		nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
-
-		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+		case FLASH_57780VENDOR_ATMEL_AT45DB021D:
+		case FLASH_57780VENDOR_ATMEL_AT45DB021B:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
 			break;
-
-		/* Erase the target page */
-		tw32(NVRAM_ADDR, phy_addr);
-
-		nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR |
-			NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_ERASE;
-
-		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+		case FLASH_57780VENDOR_ATMEL_AT45DB041D:
+		case FLASH_57780VENDOR_ATMEL_AT45DB041B:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
 			break;
+		}
+		break;
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
-		/* Issue another write enable to start the write. */
-		nvram_cmd = NVRAM_CMD_WREN | NVRAM_CMD_GO | NVRAM_CMD_DONE;
-
-		if (tg3_nvram_exec_cmd(tp, nvram_cmd))
+		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+		case FLASH_5752VENDOR_ST_M45PE10:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
 			break;
-
-		for (j = 0; j < pagesize; j += 4) {
-			__be32 data;
-
-			data = *((__be32 *) (tmp + j));
-
-			tw32(NVRAM_WRDATA, be32_to_cpu(data));
-
-			tw32(NVRAM_ADDR, phy_addr + j);
-
-			nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE |
-				NVRAM_CMD_WR;
-
-			if (j == 0)
-				nvram_cmd |= NVRAM_CMD_FIRST;
-			else if (j == (pagesize - 4))
-				nvram_cmd |= NVRAM_CMD_LAST;
-
-			if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd)))
-				break;
-		}
-		if (ret)
+		case FLASH_5752VENDOR_ST_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
 			break;
-	}
-
-	nvram_cmd = NVRAM_CMD_WRDI | NVRAM_CMD_GO | NVRAM_CMD_DONE;
-	tg3_nvram_exec_cmd(tp, nvram_cmd);
-
-	kfree(tmp);
+		case FLASH_5752VENDOR_ST_M45PE40:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		}
+		break;
+	default:
+		tg3_flag_set(tp, NO_NVRAM);
+		return;
+	}
 
-	return ret;
+	tg3_nvram_get_pagesize(tp, nvcfg1);
+	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
 }
 
-/* offset and length are dword aligned */
-static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len,
-		u8 *buf)
+
+static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
 {
-	int i, ret = 0;
+	u32 nvcfg1;
 
-	for (i = 0; i < len; i += 4, offset += 4) {
-		u32 page_off, phy_addr, nvram_cmd;
-		__be32 data;
+	nvcfg1 = tr32(NVRAM_CFG1);
 
-		memcpy(&data, buf + i, 4);
-		tw32(NVRAM_WRDATA, be32_to_cpu(data));
+	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+	case FLASH_5717VENDOR_ATMEL_EEPROM:
+	case FLASH_5717VENDOR_MICRO_EEPROM:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
-		page_off = offset % tp->nvram_pagesize;
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		return;
+	case FLASH_5717VENDOR_ATMEL_MDB011D:
+	case FLASH_5717VENDOR_ATMEL_ADB011B:
+	case FLASH_5717VENDOR_ATMEL_ADB011D:
+	case FLASH_5717VENDOR_ATMEL_MDB021D:
+	case FLASH_5717VENDOR_ATMEL_ADB021B:
+	case FLASH_5717VENDOR_ATMEL_ADB021D:
+	case FLASH_5717VENDOR_ATMEL_45USPT:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
-		phy_addr = tg3_nvram_phys_addr(tp, offset);
+		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+		case FLASH_5717VENDOR_ATMEL_MDB021D:
+			/* Detect size with tg3_nvram_get_size() */
+			break;
+		case FLASH_5717VENDOR_ATMEL_ADB021B:
+		case FLASH_5717VENDOR_ATMEL_ADB021D:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
+		break;
+	case FLASH_5717VENDOR_ST_M_M25PE10:
+	case FLASH_5717VENDOR_ST_A_M25PE10:
+	case FLASH_5717VENDOR_ST_M_M45PE10:
+	case FLASH_5717VENDOR_ST_A_M45PE10:
+	case FLASH_5717VENDOR_ST_M_M25PE20:
+	case FLASH_5717VENDOR_ST_A_M25PE20:
+	case FLASH_5717VENDOR_ST_M_M45PE20:
+	case FLASH_5717VENDOR_ST_A_M45PE20:
+	case FLASH_5717VENDOR_ST_25USPT:
+	case FLASH_5717VENDOR_ST_45USPT:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
-		tw32(NVRAM_ADDR, phy_addr);
+		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+		case FLASH_5717VENDOR_ST_M_M25PE20:
+		case FLASH_5717VENDOR_ST_M_M45PE20:
+			/* Detect size with tg3_nvram_get_size() */
+			break;
+		case FLASH_5717VENDOR_ST_A_M25PE20:
+		case FLASH_5717VENDOR_ST_A_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
+		break;
+	default:
+		tg3_flag_set(tp, NO_NVRAM);
+		return;
+	}
 
-		nvram_cmd = NVRAM_CMD_GO | NVRAM_CMD_DONE | NVRAM_CMD_WR;
+	tg3_nvram_get_pagesize(tp, nvcfg1);
+	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+}
 
-		if (page_off == 0 || i == 0)
-			nvram_cmd |= NVRAM_CMD_FIRST;
-		if (page_off == (tp->nvram_pagesize - 4))
-			nvram_cmd |= NVRAM_CMD_LAST;
+static void __devinit tg3_get_5720_nvram_info(struct tg3 *tp)
+{
+	u32 nvcfg1, nvmpinstrp;
 
-		if (i == (len - 4))
-			nvram_cmd |= NVRAM_CMD_LAST;
+	nvcfg1 = tr32(NVRAM_CFG1);
+	nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
-		    !tg3_flag(tp, 5755_PLUS) &&
-		    (tp->nvram_jedecnum == JEDEC_ST) &&
-		    (nvram_cmd & NVRAM_CMD_FIRST)) {
+	switch (nvmpinstrp) {
+	case FLASH_5720_EEPROM_HD:
+	case FLASH_5720_EEPROM_LD:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
 
-			if ((ret = tg3_nvram_exec_cmd(tp,
-				NVRAM_CMD_WREN | NVRAM_CMD_GO |
-				NVRAM_CMD_DONE)))
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		if (nvmpinstrp == FLASH_5720_EEPROM_HD)
+			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+		else
+			tp->nvram_pagesize = ATMEL_AT24C02_CHIP_SIZE;
+		return;
+	case FLASH_5720VENDOR_M_ATMEL_DB011D:
+	case FLASH_5720VENDOR_A_ATMEL_DB011B:
+	case FLASH_5720VENDOR_A_ATMEL_DB011D:
+	case FLASH_5720VENDOR_M_ATMEL_DB021D:
+	case FLASH_5720VENDOR_A_ATMEL_DB021B:
+	case FLASH_5720VENDOR_A_ATMEL_DB021D:
+	case FLASH_5720VENDOR_M_ATMEL_DB041D:
+	case FLASH_5720VENDOR_A_ATMEL_DB041B:
+	case FLASH_5720VENDOR_A_ATMEL_DB041D:
+	case FLASH_5720VENDOR_M_ATMEL_DB081D:
+	case FLASH_5720VENDOR_A_ATMEL_DB081D:
+	case FLASH_5720VENDOR_ATMEL_45USPT:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
-				break;
-		}
-		if (!tg3_flag(tp, FLASH)) {
-			/* We always do complete word writes to eeprom. */
-			nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
+		switch (nvmpinstrp) {
+		case FLASH_5720VENDOR_M_ATMEL_DB021D:
+		case FLASH_5720VENDOR_A_ATMEL_DB021B:
+		case FLASH_5720VENDOR_A_ATMEL_DB021D:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		case FLASH_5720VENDOR_M_ATMEL_DB041D:
+		case FLASH_5720VENDOR_A_ATMEL_DB041B:
+		case FLASH_5720VENDOR_A_ATMEL_DB041D:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		case FLASH_5720VENDOR_M_ATMEL_DB081D:
+		case FLASH_5720VENDOR_A_ATMEL_DB081D:
+			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
 		}
+		break;
+	case FLASH_5720VENDOR_M_ST_M25PE10:
+	case FLASH_5720VENDOR_M_ST_M45PE10:
+	case FLASH_5720VENDOR_A_ST_M25PE10:
+	case FLASH_5720VENDOR_A_ST_M45PE10:
+	case FLASH_5720VENDOR_M_ST_M25PE20:
+	case FLASH_5720VENDOR_M_ST_M45PE20:
+	case FLASH_5720VENDOR_A_ST_M25PE20:
+	case FLASH_5720VENDOR_A_ST_M45PE20:
+	case FLASH_5720VENDOR_M_ST_M25PE40:
+	case FLASH_5720VENDOR_M_ST_M45PE40:
+	case FLASH_5720VENDOR_A_ST_M25PE40:
+	case FLASH_5720VENDOR_A_ST_M45PE40:
+	case FLASH_5720VENDOR_M_ST_M25PE80:
+	case FLASH_5720VENDOR_M_ST_M45PE80:
+	case FLASH_5720VENDOR_A_ST_M25PE80:
+	case FLASH_5720VENDOR_A_ST_M45PE80:
+	case FLASH_5720VENDOR_ST_25USPT:
+	case FLASH_5720VENDOR_ST_45USPT:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
-		if ((ret = tg3_nvram_exec_cmd(tp, nvram_cmd)))
+		switch (nvmpinstrp) {
+		case FLASH_5720VENDOR_M_ST_M25PE20:
+		case FLASH_5720VENDOR_M_ST_M45PE20:
+		case FLASH_5720VENDOR_A_ST_M25PE20:
+		case FLASH_5720VENDOR_A_ST_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		case FLASH_5720VENDOR_M_ST_M25PE40:
+		case FLASH_5720VENDOR_M_ST_M45PE40:
+		case FLASH_5720VENDOR_A_ST_M25PE40:
+		case FLASH_5720VENDOR_A_ST_M45PE40:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		case FLASH_5720VENDOR_M_ST_M25PE80:
+		case FLASH_5720VENDOR_M_ST_M45PE80:
+		case FLASH_5720VENDOR_A_ST_M25PE80:
+		case FLASH_5720VENDOR_A_ST_M45PE80:
+			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
 			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
+		break;
+	default:
+		tg3_flag_set(tp, NO_NVRAM);
+		return;
 	}
-	return ret;
+
+	tg3_nvram_get_pagesize(tp, nvcfg1);
+	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
 }
 
-/* offset and length are dword aligned */
-static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf)
+/* Chips other than 5700/5701 use the NVRAM for fetching info. */
+static void __devinit tg3_nvram_init(struct tg3 *tp)
 {
-	int ret;
-
-	if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
-		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
-		       ~GRC_LCLCTRL_GPIO_OUTPUT1);
-		udelay(40);
-	}
-
-	if (!tg3_flag(tp, NVRAM)) {
-		ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
-	} else {
-		u32 grc_mode;
+	tw32_f(GRC_EEPROM_ADDR,
+	     (EEPROM_ADDR_FSM_RESET |
+	      (EEPROM_DEFAULT_CLOCK_PERIOD <<
+	       EEPROM_ADDR_CLKPERD_SHIFT)));
 
-		ret = tg3_nvram_lock(tp);
-		if (ret)
-			return ret;
+	msleep(1);
 
-		tg3_enable_nvram_access(tp);
-		if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM))
-			tw32(NVRAM_WRITE1, 0x406);
+	/* Enable seeprom accesses. */
+	tw32_f(GRC_LOCAL_CTRL,
+	     tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM);
+	udelay(100);
 
-		grc_mode = tr32(GRC_MODE);
-		tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
+		tg3_flag_set(tp, NVRAM);
 
-		if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) {
-			ret = tg3_nvram_write_block_buffered(tp, offset, len,
-				buf);
-		} else {
-			ret = tg3_nvram_write_block_unbuffered(tp, offset, len,
-				buf);
+		if (tg3_nvram_lock(tp)) {
+			netdev_warn(tp->dev,
+				    "Cannot get nvram lock, %s failed\n",
+				    __func__);
+			return;
 		}
+		tg3_enable_nvram_access(tp);
 
-		grc_mode = tr32(GRC_MODE);
-		tw32(GRC_MODE, grc_mode & ~GRC_MODE_NVRAM_WR_ENABLE);
+		tp->nvram_size = 0;
+
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+			tg3_get_5752_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+			tg3_get_5755_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+			tg3_get_5787_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
+			tg3_get_5761_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+			tg3_get_5906_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+			 tg3_flag(tp, 57765_CLASS))
+			tg3_get_57780_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+			tg3_get_5717_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+			tg3_get_5720_nvram_info(tp);
+		else
+			tg3_get_nvram_info(tp);
+
+		if (tp->nvram_size == 0)
+			tg3_get_nvram_size(tp);
 
 		tg3_disable_nvram_access(tp);
 		tg3_nvram_unlock(tp);
-	}
 
-	if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
-		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
-		udelay(40);
-	}
+	} else {
+		tg3_flag_clear(tp, NVRAM);
+		tg3_flag_clear(tp, NVRAM_BUFFERED);
 
-	return ret;
+		tg3_get_eeprom_size(tp);
+	}
 }
 
 struct subsys_tbl_ent {
@@ -13329,14 +13347,11 @@ static void __devinit tg3_phy_init_link_config(struct tg3 *tp)
 		adv |= ADVERTISED_FIBRE;
 
 	tp->link_config.advertising = adv;
-	tp->link_config.speed = SPEED_INVALID;
-	tp->link_config.duplex = DUPLEX_INVALID;
+	tp->link_config.speed = SPEED_UNKNOWN;
+	tp->link_config.duplex = DUPLEX_UNKNOWN;
 	tp->link_config.autoneg = AUTONEG_ENABLE;
-	tp->link_config.active_speed = SPEED_INVALID;
-	tp->link_config.active_duplex = DUPLEX_INVALID;
-	tp->link_config.orig_speed = SPEED_INVALID;
-	tp->link_config.orig_duplex = DUPLEX_INVALID;
-	tp->link_config.orig_autoneg = AUTONEG_INVALID;
+	tp->link_config.active_speed = SPEED_UNKNOWN;
+	tp->link_config.active_duplex = DUPLEX_UNKNOWN;
 }
 
 static int __devinit tg3_phy_probe(struct tg3 *tp)
@@ -13833,8 +13848,6 @@ done:
 	tp->fw_ver[TG3_VER_SIZE - 1] = 0;
 }
 
-static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
-
 static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
 {
 	if (tg3_flag(tp, LRG_PROD_RING_CAP))
@@ -13852,49 +13865,50 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = {
 	{ },
 };
 
-static int __devinit tg3_get_invariants(struct tg3 *tp)
+static struct pci_dev * __devinit tg3_find_peer(struct tg3 *tp)
 {
-	u32 misc_ctrl_reg;
-	u32 pci_state_reg, grc_misc_cfg;
-	u32 val;
-	u16 pci_cmd;
-	int err;
+	struct pci_dev *peer;
+	unsigned int func, devnr = tp->pdev->devfn & ~7;
 
-	/* Force memory write invalidate off.  If we leave it on,
-	 * then on 5700_BX chips we have to enable a workaround.
-	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
-	 * to match the cacheline size.  The Broadcom driver have this
-	 * workaround but turns MWI off all the times so never uses
-	 * it.  This seems to suggest that the workaround is insufficient.
+	for (func = 0; func < 8; func++) {
+		peer = pci_get_slot(tp->pdev->bus, devnr | func);
+		if (peer && peer != tp->pdev)
+			break;
+		pci_dev_put(peer);
+	}
+	/* 5704 can be configured in single-port mode, set peer to
+	 * tp->pdev in that case.
 	 */
-	pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
-	pci_cmd &= ~PCI_COMMAND_INVALIDATE;
-	pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
+	if (!peer) {
+		peer = tp->pdev;
+		return peer;
+	}
 
-	/* Important! -- Make sure register accesses are byteswapped
-	 * correctly.  Also, for those chips that require it, make
-	 * sure that indirect register accesses are enabled before
-	 * the first operation.
+	/*
+	 * We don't need to keep the refcount elevated; there's no way
+	 * to remove one half of this device without removing the other
 	 */
-	pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
-			      &misc_ctrl_reg);
-	tp->misc_host_ctrl |= (misc_ctrl_reg &
-			       MISC_HOST_CTRL_CHIPREV);
-	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
-			       tp->misc_host_ctrl);
+	pci_dev_put(peer);
+
+	return peer;
+}
 
-	tp->pci_chip_rev_id = (misc_ctrl_reg >>
-			       MISC_HOST_CTRL_CHIPREV_SHIFT);
+static void __devinit tg3_detect_asic_rev(struct tg3 *tp, u32 misc_ctrl_reg)
+{
+	tp->pci_chip_rev_id = misc_ctrl_reg >> MISC_HOST_CTRL_CHIPREV_SHIFT;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_USE_PROD_ID_REG) {
-		u32 prod_id_asic_rev;
+		u32 reg;
+
+		/* All devices that use the alternate
+		 * ASIC REV location have a CPMU.
+		 */
+		tg3_flag_set(tp, CPMU_PRESENT);
 
 		if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720)
-			pci_read_config_dword(tp->pdev,
-					      TG3PCI_GEN2_PRODID_ASICREV,
-					      &prod_id_asic_rev);
+			reg = TG3PCI_GEN2_PRODID_ASICREV;
 		else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781 ||
 			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785 ||
 			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761 ||
@@ -13905,14 +13919,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57766 ||
 			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57782 ||
 			 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57786)
-			pci_read_config_dword(tp->pdev,
-					      TG3PCI_GEN15_PRODID_ASICREV,
-					      &prod_id_asic_rev);
+			reg = TG3PCI_GEN15_PRODID_ASICREV;
 		else
-			pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
-					      &prod_id_asic_rev);
+			reg = TG3PCI_PRODID_ASICREV;
 
-		tp->pci_chip_rev_id = prod_id_asic_rev;
+		pci_read_config_dword(tp->pdev, reg, &tp->pci_chip_rev_id);
 	}
 
 	/* Wrong chip ID in 5752 A0. This code can be removed later
@@ -13921,6 +13932,77 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
 		tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		tg3_flag_set(tp, 5717_PLUS);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
+		tg3_flag_set(tp, 57765_CLASS);
+
+	if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS))
+		tg3_flag_set(tp, 57765_PLUS);
+
+	/* Intentionally exclude ASIC_REV_5906 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+	    tg3_flag(tp, 57765_PLUS))
+		tg3_flag_set(tp, 5755_PLUS);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)
+		tg3_flag_set(tp, 5780_CLASS);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
+	    tg3_flag(tp, 5755_PLUS) ||
+	    tg3_flag(tp, 5780_CLASS))
+		tg3_flag_set(tp, 5750_PLUS);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
+	    tg3_flag(tp, 5750_PLUS))
+		tg3_flag_set(tp, 5705_PLUS);
+}
+
+static int __devinit tg3_get_invariants(struct tg3 *tp)
+{
+	u32 misc_ctrl_reg;
+	u32 pci_state_reg, grc_misc_cfg;
+	u32 val;
+	u16 pci_cmd;
+	int err;
+
+	/* Force memory write invalidate off.  If we leave it on,
+	 * then on 5700_BX chips we have to enable a workaround.
+	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary
+	 * to match the cacheline size.  The Broadcom driver have this
+	 * workaround but turns MWI off all the times so never uses
+	 * it.  This seems to suggest that the workaround is insufficient.
+	 */
+	pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
+	pci_cmd &= ~PCI_COMMAND_INVALIDATE;
+	pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
+
+	/* Important! -- Make sure register accesses are byteswapped
+	 * correctly.  Also, for those chips that require it, make
+	 * sure that indirect register accesses are enabled before
+	 * the first operation.
+	 */
+	pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+			      &misc_ctrl_reg);
+	tp->misc_host_ctrl |= (misc_ctrl_reg &
+			       MISC_HOST_CTRL_CHIPREV);
+	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
+
+	tg3_detect_asic_rev(tp, misc_ctrl_reg);
+
 	/* If we have 5702/03 A1 or A2 on certain ICH chipsets,
 	 * we need to disable memory and use config. cycles
 	 * only to access all registers. The 5702/03 chips
@@ -14017,9 +14099,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	 * Any tg3 device found behind the bridge will also need the 40-bit
 	 * DMA workaround.
 	 */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
-		tg3_flag_set(tp, 5780_CLASS);
+	if (tg3_flag(tp, 5780_CLASS)) {
 		tg3_flag_set(tp, 40BIT_DMA_BUG);
 		tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
 	} else {
@@ -14045,39 +14125,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)
 		tp->pdev_peer = tg3_find_peer(tp);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
-		tg3_flag_set(tp, 5717_PLUS);
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
-		tg3_flag_set(tp, 57765_CLASS);
-
-	if (tg3_flag(tp, 57765_CLASS) || tg3_flag(tp, 5717_PLUS))
-		tg3_flag_set(tp, 57765_PLUS);
-
-	/* Intentionally exclude ASIC_REV_5906 */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-	    tg3_flag(tp, 57765_PLUS))
-		tg3_flag_set(tp, 5755_PLUS);
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
-	    tg3_flag(tp, 5755_PLUS) ||
-	    tg3_flag(tp, 5780_CLASS))
-		tg3_flag_set(tp, 5750_PLUS);
-
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
-	    tg3_flag(tp, 5750_PLUS))
-		tg3_flag_set(tp, 5705_PLUS);
-
 	/* Determine TSO capabilities */
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5719_A0)
 		; /* Do nothing. HW bug. */
@@ -14149,8 +14196,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 		tp->dma_limit = TG3_TX_BD_DMA_MAX_4K;
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57766)
-		tp->dma_limit = TG3_TX_BD_DMA_MAX_2K;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
@@ -14409,13 +14454,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 		tg3_ape_lock_init(tp);
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-	    tg3_flag(tp, 57765_PLUS))
-		tg3_flag_set(tp, CPMU_PRESENT);
-
 	/* Set up tp->grc_local_ctrl before calling
 	 * tg3_pwrsrc_switch_to_vmain().  GPIO1 driven high
 	 * will bring 5700's external PHY out of reset.
@@ -15350,34 +15388,6 @@ static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
 	return str;
 }
 
-static struct pci_dev * __devinit tg3_find_peer(struct tg3 *tp)
-{
-	struct pci_dev *peer;
-	unsigned int func, devnr = tp->pdev->devfn & ~7;
-
-	for (func = 0; func < 8; func++) {
-		peer = pci_get_slot(tp->pdev->bus, devnr | func);
-		if (peer && peer != tp->pdev)
-			break;
-		pci_dev_put(peer);
-	}
-	/* 5704 can be configured in single-port mode, set peer to
-	 * tp->pdev in that case.
-	 */
-	if (!peer) {
-		peer = tp->pdev;
-		return peer;
-	}
-
-	/*
-	 * We don't need to keep the refcount elevated; there's no way
-	 * to remove one half of this device without removing the other
-	 */
-	pci_dev_put(peer);
-
-	return peer;
-}
-
 static void __devinit tg3_init_coal(struct tg3 *tp)
 {
 	struct ethtool_coalesce *ec = &tp->coal;
@@ -15409,24 +15419,6 @@ static void __devinit tg3_init_coal(struct tg3 *tp)
 	}
 }
 
-static const struct net_device_ops tg3_netdev_ops = {
-	.ndo_open		= tg3_open,
-	.ndo_stop		= tg3_close,
-	.ndo_start_xmit		= tg3_start_xmit,
-	.ndo_get_stats64	= tg3_get_stats64,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_rx_mode	= tg3_set_rx_mode,
-	.ndo_set_mac_address	= tg3_set_mac_addr,
-	.ndo_do_ioctl		= tg3_ioctl,
-	.ndo_tx_timeout		= tg3_tx_timeout,
-	.ndo_change_mtu		= tg3_change_mtu,
-	.ndo_fix_features	= tg3_fix_features,
-	.ndo_set_features	= tg3_set_features,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= tg3_poll_controller,
-#endif
-};
-
 static int __devinit tg3_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -15471,7 +15463,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
 	dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS);
 	if (!dev) {
-		dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_out_power_down;
 	}
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index aea8f72..22cbe74 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -4,7 +4,7 @@
  * Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
  * Copyright (C) 2001 Jeff Garzik (jgarzik@pobox.com)
  * Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2007-2011 Broadcom Corporation.
+ * Copyright (C) 2007-2012 Broadcom Corporation.
  */
 
 #ifndef _T3_H
@@ -2702,19 +2702,8 @@ struct tg3_link_config {
 	u8				active_flowctrl;
 
 	u8				active_duplex;
-#define SPEED_INVALID		0xffff
-#define DUPLEX_INVALID		0xff
-#define AUTONEG_INVALID		0xff
 	u16				active_speed;
 	u32				rmt_adv;
-
-	/* When we go in and out of low power mode we need
-	 * to swap with this state.
-	 */
-	u16				orig_speed;
-	u8				orig_duplex;
-	u8				orig_autoneg;
-	u32				orig_advertising;
 };
 
 struct tg3_bufmgr_config {
diff --git a/drivers/net/ethernet/brocade/bna/bfa_cee.c b/drivers/net/ethernet/brocade/bna/bfa_cee.c
index 29f284f..689e5e1 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_cee.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_cee.c
@@ -203,7 +203,7 @@ bfa_nw_cee_get_attr(struct bfa_cee *cee, struct bfa_cee_attr *attr,
 	if (!bfa_nw_ioc_is_operational(cee->ioc))
 		return BFA_STATUS_IOC_FAILURE;
 
-	if (cee->get_attr_pending == true)
+	if (cee->get_attr_pending)
 		return  BFA_STATUS_DEVBUSY;
 
 	cee->get_attr_pending = true;
@@ -272,7 +272,7 @@ bfa_cee_notify(void *arg, enum bfa_ioc_event event)
 	switch (event) {
 	case BFA_IOC_E_DISABLED:
 	case BFA_IOC_E_FAILED:
-		if (cee->get_attr_pending == true) {
+		if (cee->get_attr_pending) {
 			cee->get_attr_status = BFA_STATUS_FAILED;
 			cee->get_attr_pending  = false;
 			if (cee->cbfn.get_attr_cbfn) {
@@ -281,7 +281,7 @@ bfa_cee_notify(void *arg, enum bfa_ioc_event event)
 					BFA_STATUS_FAILED);
 			}
 		}
-		if (cee->get_stats_pending == true) {
+		if (cee->get_stats_pending) {
 			cee->get_stats_status = BFA_STATUS_FAILED;
 			cee->get_stats_pending  = false;
 			if (cee->cbfn.get_stats_cbfn) {
@@ -290,7 +290,7 @@ bfa_cee_notify(void *arg, enum bfa_ioc_event event)
 					BFA_STATUS_FAILED);
 			}
 		}
-		if (cee->reset_stats_pending == true) {
+		if (cee->reset_stats_pending) {
 			cee->reset_stats_status = BFA_STATUS_FAILED;
 			cee->reset_stats_pending  = false;
 			if (cee->cbfn.reset_stats_cbfn) {
diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs.h b/drivers/net/ethernet/brocade/bna/bfa_defs.h
index 871c630..48f8773 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_defs.h
+++ b/drivers/net/ethernet/brocade/bna/bfa_defs.h
@@ -297,6 +297,7 @@ enum bfa_mode {
 #define BFA_FLASH_PART_ENTRY_SIZE	32	/* partition entry size */
 #define BFA_FLASH_PART_MAX		32	/* maximal # of partitions */
 #define BFA_TOTAL_FLASH_SIZE		0x400000
+#define BFA_FLASH_PART_FWIMG		2
 #define BFA_FLASH_PART_MFG		7
 
 /*
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index abfad27..77977d7 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -692,7 +692,7 @@ static void
 bfa_iocpf_sm_mismatch_entry(struct bfa_iocpf *iocpf)
 {
 	/* Call only the first time sm enters fwmismatch state. */
-	if (iocpf->fw_mismatch_notified == false)
+	if (!iocpf->fw_mismatch_notified)
 		bfa_ioc_pf_fwmismatch(iocpf->ioc);
 
 	iocpf->fw_mismatch_notified = true;
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index be7d91e..ff78f77 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -3284,7 +3284,6 @@ bnad_pci_probe(struct pci_dev *pdev,
 	 */
 	netdev = alloc_etherdev(sizeof(struct bnad));
 	if (!netdev) {
-		dev_err(&pdev->dev, "netdev allocation failed\n");
 		err = -ENOMEM;
 		return err;
 	}
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
index 592ad39..c9fdceb 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
@@ -62,8 +62,6 @@ bnad_debugfs_open_fwtrc(struct inode *inode, struct file *file)
 	if (!fw_debug->debug_buffer) {
 		kfree(fw_debug);
 		fw_debug = NULL;
-		pr_warn("bna %s: Failed to allocate fwtrc buffer\n",
-			pci_name(bnad->pcidev));
 		return -ENOMEM;
 	}
 
@@ -105,8 +103,6 @@ bnad_debugfs_open_fwsave(struct inode *inode, struct file *file)
 	if (!fw_debug->debug_buffer) {
 		kfree(fw_debug);
 		fw_debug = NULL;
-		pr_warn("bna %s: Failed to allocate fwsave buffer\n",
-			pci_name(bnad->pcidev));
 		return -ENOMEM;
 	}
 
@@ -208,8 +204,6 @@ bnad_debugfs_open_drvinfo(struct inode *inode, struct file *file)
 	if (!drv_info->debug_buffer) {
 		kfree(drv_info);
 		drv_info = NULL;
-		pr_warn("bna %s: Failed to allocate drv info buffer\n",
-			pci_name(bnad->pcidev));
 		return -ENOMEM;
 	}
 
@@ -348,11 +342,8 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
 
 	/* Allocate memory to store the user space buf */
 	kern_buf = kzalloc(nbytes, GFP_KERNEL);
-	if (!kern_buf) {
-		pr_warn("bna %s: Failed to allocate user buffer\n",
-			pci_name(bnad->pcidev));
+	if (!kern_buf)
 		return -ENOMEM;
-	}
 
 	if (copy_from_user(kern_buf, (void  __user *)buf, nbytes)) {
 		kfree(kern_buf);
@@ -373,11 +364,8 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
 	bnad->reglen = 0;
 
 	bnad->regdata = kzalloc(len << 2, GFP_KERNEL);
-	if (!bnad->regdata) {
-		pr_warn("bna %s: Failed to allocate regrd buffer\n",
-			pci_name(bnad->pcidev));
+	if (!bnad->regdata)
 		return -ENOMEM;
-	}
 
 	bnad->reglen = len << 2;
 	rb = bfa_ioc_bar0(ioc);
@@ -421,11 +409,8 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf,
 
 	/* Allocate memory to store the user space buf */
 	kern_buf = kzalloc(nbytes, GFP_KERNEL);
-	if (!kern_buf) {
-		pr_warn("bna %s: Failed to allocate user buffer\n",
-			pci_name(bnad->pcidev));
+	if (!kern_buf)
 		return -ENOMEM;
-	}
 
 	if (copy_from_user(kern_buf, (void  __user *)buf, nbytes)) {
 		kfree(kern_buf);
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
index 803ea32..ab753d7 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c
@@ -1070,6 +1070,47 @@ done:
 	return ret;
 }
 
+static int
+bnad_flash_device(struct net_device *netdev, struct ethtool_flash *eflash)
+{
+	struct bnad *bnad = netdev_priv(netdev);
+	struct bnad_iocmd_comp fcomp;
+	const struct firmware *fw;
+	int ret = 0;
+
+	ret = request_firmware(&fw, eflash->data, &bnad->pcidev->dev);
+	if (ret) {
+		pr_err("BNA: Can't locate firmware %s\n", eflash->data);
+		goto out;
+	}
+
+	fcomp.bnad = bnad;
+	fcomp.comp_status = 0;
+
+	init_completion(&fcomp.comp);
+	spin_lock_irq(&bnad->bna_lock);
+	ret = bfa_nw_flash_update_part(&bnad->bna.flash, BFA_FLASH_PART_FWIMG,
+				bnad->id, (u8 *)fw->data, fw->size, 0,
+				bnad_cb_completion, &fcomp);
+	if (ret != BFA_STATUS_OK) {
+		pr_warn("BNA: Flash update failed with err: %d\n", ret);
+		ret = -EIO;
+		spin_unlock_irq(&bnad->bna_lock);
+		goto out;
+	}
+
+	spin_unlock_irq(&bnad->bna_lock);
+	wait_for_completion(&fcomp.comp);
+	if (fcomp.comp_status != BFA_STATUS_OK) {
+		ret = -EIO;
+		pr_warn("BNA: Firmware image update to flash failed with: %d\n",
+			fcomp.comp_status);
+	}
+out:
+	release_firmware(fw);
+	return ret;
+}
+
 static const struct ethtool_ops bnad_ethtool_ops = {
 	.get_settings = bnad_get_settings,
 	.set_settings = bnad_set_settings,
@@ -1088,6 +1129,7 @@ static const struct ethtool_ops bnad_ethtool_ops = {
 	.get_eeprom_len = bnad_get_eeprom_len,
 	.get_eeprom = bnad_get_eeprom,
 	.set_eeprom = bnad_set_eeprom,
+	.flash_device = bnad_flash_device,
 };
 
 void
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c
index 1a5b6ef..9061170 100644
--- a/drivers/net/ethernet/cadence/at91_ether.c
+++ b/drivers/net/ethernet/cadence/at91_ether.c
@@ -886,7 +886,7 @@ static void at91ether_rx(struct net_device *dev)
 	while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
 		p_recv = dlist->recv_buf[lp->rxBuffIndex];
 		pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff;	/* Length of frame including FCS */
-		skb = dev_alloc_skb(pktlen + 2);
+		skb = netdev_alloc_skb(dev, pktlen + 2);
 		if (skb != NULL) {
 			skb_reserve(skb, 2);
 			memcpy(skb_put(skb, pktlen), p_recv, pktlen);
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 2320068..c4834c2 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -87,7 +87,7 @@ static void __init macb_get_hwaddr(struct macb *bp)
 		memcpy(bp->dev->dev_addr, addr, sizeof(addr));
 	} else {
 		netdev_info(bp->dev, "invalid hw address, using random\n");
-		random_ether_addr(bp->dev->dev_addr);
+		eth_hw_addr_random(bp->dev);
 	}
 }
 
@@ -397,7 +397,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 	netdev_dbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
 		   first_frag, last_frag, len);
 
-	skb = dev_alloc_skb(len + RX_OFFSET);
+	skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET);
 	if (!skb) {
 		bp->stats.rx_dropped++;
 		for (frag = first_frag; ; frag = NEXT_RX(frag)) {
@@ -1308,10 +1308,8 @@ static int __init macb_probe(struct platform_device *pdev)
 
 	err = -ENOMEM;
 	dev = alloc_etherdev(sizeof(*bp));
-	if (!dev) {
-		dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
+	if (!dev)
 		goto err_out;
-	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 1fce186..11f667f 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -1012,7 +1012,7 @@ static int xgmac_open(struct net_device *dev)
 	 * address using the following linux command:
 	 *      ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx  */
 	if (!is_valid_ether_addr(dev->dev_addr)) {
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 		netdev_dbg(priv->dev, "generated random MAC address %pM\n",
 			dev->dev_addr);
 	}
@@ -1482,6 +1482,7 @@ static int xgmac_set_mac_address(struct net_device *dev, void *p)
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
 	xgmac_set_mac_addr(ioaddr, dev->dev_addr, 0);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/version.h b/drivers/net/ethernet/chelsio/cxgb3/version.h
index 8bda06e..165bfb9 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/version.h
+++ b/drivers/net/ethernet/chelsio/cxgb3/version.h
@@ -35,10 +35,10 @@
 #define DRV_DESC "Chelsio T3 Network Driver"
 #define DRV_NAME "cxgb3"
 /* Driver version */
-#define DRV_VERSION "1.1.4-ko"
+#define DRV_VERSION "1.1.5-ko"
 
 /* Firmware version */
 #define FW_VERSION_MAJOR 7
-#define FW_VERSION_MINOR 10
+#define FW_VERSION_MINOR 12
 #define FW_VERSION_MICRO 0
 #endif				/* __CHELSIO_VERSION_H */
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index e53365a..9045a45 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -2596,8 +2596,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
 		netdev = alloc_etherdev_mq(sizeof(struct port_info),
 					   MAX_PORT_QSETS);
 		if (netdev == NULL) {
-			dev_err(&pdev->dev, "cannot allocate netdev for"
-				" port %d\n", port_id);
 			t4vf_free_vi(adapter, viid);
 			err = -ENOMEM;
 			goto err_free_dev;
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index f328da2..d5ff936 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -911,7 +911,7 @@ dma_rx(struct net_device *dev)
 	}
 
 	/* Malloc up new buffer. */
-	skb = dev_alloc_skb(length + 2);
+	skb = netdev_alloc_skb(dev, length + 2);
 	if (skb == NULL) {
 		if (net_debug)	/* I don't think we want to do this to a stressed system */
 			printk("%s: Memory squeeze, dropping packet.\n", dev->name);
@@ -1616,7 +1616,7 @@ net_rx(struct net_device *dev)
 	}
 
 	/* Malloc up new buffer. */
-	skb = dev_alloc_skb(length + 2);
+	skb = netdev_alloc_skb(dev, length + 2);
 	if (skb == NULL) {
 #if 0		/* Again, this seems a cruel thing to do */
 		printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
diff --git a/drivers/net/ethernet/cirrus/ep93xx_eth.c b/drivers/net/ethernet/cirrus/ep93xx_eth.c
index 4317af8..78c5521 100644
--- a/drivers/net/ethernet/cirrus/ep93xx_eth.c
+++ b/drivers/net/ethernet/cirrus/ep93xx_eth.c
@@ -282,7 +282,7 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
 		if (rstat0 & RSTAT0_CRCI)
 			length -= 4;
 
-		skb = dev_alloc_skb(length + 2);
+		skb = netdev_alloc_skb(dev, length + 2);
 		if (likely(skb != NULL)) {
 			struct ep93xx_rdesc *rxd = &ep->descs->rdesc[entry];
 			skb_reserve(skb, 2);
@@ -859,7 +859,7 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
 	ep->mdc_divisor = 40;	/* Max HCLK 100 MHz, min MDIO clk 2.5 MHz.  */
 
 	if (is_zero_ether_addr(dev->dev_addr))
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 	err = register_netdev(dev);
 	if (err) {
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index ee93a20..99998c6 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -32,13 +32,13 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.31"
+#define DRV_VERSION		"2.1.1.38"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
 
 #define ENIC_WQ_MAX		1
-#define ENIC_RQ_MAX		1
+#define ENIC_RQ_MAX		8
 #define ENIC_CQ_MAX		(ENIC_WQ_MAX + ENIC_RQ_MAX)
 #define ENIC_INTR_MAX		(ENIC_CQ_MAX + 2)
 
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index ab3f67f..e27ec1d 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -865,6 +865,7 @@ static int enic_set_mac_addr(struct net_device *netdev, char *addr)
 	}
 
 	memcpy(netdev->dev_addr, addr, netdev->addr_len);
+	netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	return 0;
 }
@@ -1069,8 +1070,17 @@ static int enic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
 		return err;
 
 	if (is_valid_ether_addr(mac)) {
-		memcpy(pp->vf_mac, mac, ETH_ALEN);
-		return 0;
+		if (vf == PORT_SELF_VF) {
+			memcpy(pp->vf_mac, mac, ETH_ALEN);
+			return 0;
+		} else {
+			/*
+			 * For sriov vf's set the mac in hw
+			 */
+			ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
+				vnic_dev_set_mac_addr, mac);
+			return enic_dev_status_to_errno(err);
+		}
 	} else
 		return -EINVAL;
 }
@@ -1114,12 +1124,23 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
 	}
 
-	/* Special case handling: mac came from IFLA_VF_MAC */
-	if (!is_zero_ether_addr(prev_pp.vf_mac))
-		memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN);
+	if (vf == PORT_SELF_VF) {
+		/* Special case handling: mac came from IFLA_VF_MAC */
+		if (!is_zero_ether_addr(prev_pp.vf_mac))
+			memcpy(pp->mac_addr, prev_pp.vf_mac, ETH_ALEN);
 
-	if (vf == PORT_SELF_VF && is_zero_ether_addr(netdev->dev_addr))
-		random_ether_addr(netdev->dev_addr);
+		if (is_zero_ether_addr(netdev->dev_addr))
+			eth_hw_addr_random(netdev);
+	} else {
+		/* SR-IOV VF: get mac from adapter */
+		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic,
+			vnic_dev_get_mac_addr, pp->mac_addr);
+		if (err) {
+			netdev_err(netdev, "Error getting mac for vf %d\n", vf);
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return enic_dev_status_to_errno(err);
+		}
+	}
 
 	err = enic_process_set_pp_request(enic, vf, &prev_pp, &restore_pp);
 	if (err) {
@@ -1147,7 +1168,8 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
 		}
 	}
 
-	memset(pp->vf_mac, 0, ETH_ALEN);
+	if (vf == PORT_SELF_VF)
+		memset(pp->vf_mac, 0, ETH_ALEN);
 
 	return err;
 }
@@ -2280,10 +2302,8 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	 */
 
 	netdev = alloc_etherdev(sizeof(struct enic));
-	if (!netdev) {
-		pr_err("Etherdev alloc failed, aborting\n");
+	if (!netdev)
 		return -ENOMEM;
-	}
 
 	pci_set_drvdata(pdev, netdev);
 
@@ -2388,7 +2408,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	/* Allocate structure for port profiles */
 	enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL);
 	if (!enic->pp) {
-		pr_err("port profile alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_out_disable_sriov_pp;
 	}
@@ -2433,7 +2452,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	 * called later by an upper layer.
 	 */
 
-	if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) {
+	if (!enic_is_dynamic(enic)) {
 		err = vnic_dev_init(enic->vdev, 0);
 		if (err) {
 			dev_err(dev, "vNIC dev init failed, aborting\n");
@@ -2466,11 +2485,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	enic->port_mtu = enic->config.mtu;
 	(void)enic_change_mtu(netdev, enic->port_mtu);
 
-#ifdef CONFIG_PCI_IOV
-	if (enic_is_sriov_vf(enic) && is_zero_ether_addr(enic->mac_addr))
-		random_ether_addr(enic->mac_addr);
-#endif
-
 	err = enic_set_mac_addr(netdev, enic->mac_addr);
 	if (err) {
 		dev_err(dev, "Invalid MAC address, aborting\n");
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index 22bf03a..c758674 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -207,7 +207,7 @@ static int enic_pp_disassociate(struct enic *enic, int vf,
 	if (!is_zero_ether_addr(pp->mac_addr))
 		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
 			pp->mac_addr);
-	else if (!is_zero_ether_addr(netdev->dev_addr))
+	else if (vf == PORT_SELF_VF && !is_zero_ether_addr(netdev->dev_addr))
 		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_del_addr,
 			netdev->dev_addr);
 
@@ -294,7 +294,7 @@ static int enic_pp_associate(struct enic *enic, int vf,
 	if (!is_zero_ether_addr(pp->mac_addr))
 		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
 			pp->mac_addr);
-	else if (!is_zero_ether_addr(netdev->dev_addr))
+	else if (vf == PORT_SELF_VF && !is_zero_ether_addr(netdev->dev_addr))
 		ENIC_DEVCMD_PROXY_BY_INDEX(vf, err, enic, vnic_dev_add_addr,
 			netdev->dev_addr);
 
diff --git a/drivers/net/ethernet/cisco/enic/enic_res.c b/drivers/net/ethernet/cisco/enic/enic_res.c
index 4a35367..31d6588 100644
--- a/drivers/net/ethernet/cisco/enic/enic_res.c
+++ b/drivers/net/ethernet/cisco/enic/enic_res.c
@@ -44,7 +44,7 @@ int enic_get_vnic_config(struct enic *enic)
 	struct vnic_enet_config *c = &enic->config;
 	int err;
 
-	err = vnic_dev_mac_addr(enic->vdev, enic->mac_addr);
+	err = vnic_dev_get_mac_addr(enic->vdev, enic->mac_addr);
 	if (err) {
 		dev_err(enic_get_dev(enic),
 			"Error getting MAC addr, %d\n", err);
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c
index 31e7f9b..605b222 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c
@@ -439,11 +439,12 @@ int vnic_dev_fw_info(struct vnic_dev *vdev,
 		a1 = sizeof(struct vnic_devcmd_fw_info);
 
 		/* only get fw_info once and cache it */
-		err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait);
-		if (err == ERR_ECMDUNKNOWN) {
+		if (vnic_dev_capable(vdev, CMD_MCPU_FW_INFO))
+			err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO,
+				&a0, &a1, wait);
+		else
 			err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO_OLD,
 				&a0, &a1, wait);
-		}
 	}
 
 	*fw_info = vdev->fw_info;
@@ -504,13 +505,11 @@ int vnic_dev_enable_wait(struct vnic_dev *vdev)
 {
 	u64 a0 = 0, a1 = 0;
 	int wait = 1000;
-	int err;
 
-	err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait);
-	if (err == ERR_ECMDUNKNOWN)
+	if (vnic_dev_capable(vdev, CMD_ENABLE_WAIT))
+		return vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait);
+	else
 		return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
-
-	return err;
 }
 
 int vnic_dev_disable(struct vnic_dev *vdev)
@@ -574,16 +573,15 @@ int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg)
 	int wait = 1000;
 	int err;
 
-	err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait);
-	if (err == ERR_ECMDUNKNOWN) {
+	if (vnic_dev_capable(vdev, CMD_HANG_RESET)) {
+		return vnic_dev_cmd(vdev, CMD_HANG_RESET,
+				&a0, &a1, wait);
+	} else {
 		err = vnic_dev_soft_reset(vdev, arg);
 		if (err)
 			return err;
-
 		return vnic_dev_init(vdev, 0);
 	}
-
-	return err;
 }
 
 int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done)
@@ -594,11 +592,13 @@ int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done)
 
 	*done = 0;
 
-	err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait);
-	if (err) {
-		if (err == ERR_ECMDUNKNOWN)
-			return vnic_dev_soft_reset_done(vdev, done);
-		return err;
+	if (vnic_dev_capable(vdev, CMD_HANG_RESET_STATUS)) {
+		err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS,
+				&a0, &a1, wait);
+		if (err)
+			return err;
+	} else {
+		return vnic_dev_soft_reset_done(vdev, done);
 	}
 
 	*done = (a0 == 0);
@@ -613,7 +613,7 @@ int vnic_dev_hang_notify(struct vnic_dev *vdev)
 	return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);
 }
 
-int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
+int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
 {
 	u64 a0, a1;
 	int wait = 1000;
@@ -622,7 +622,7 @@ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
 	for (i = 0; i < ETH_ALEN; i++)
 		mac_addr[i] = 0;
 
-	err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
+	err = vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &a0, &a1, wait);
 	if (err)
 		return err;
 
@@ -691,13 +691,12 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
 {
 	u64 a0 = ig_vlan_rewrite_mode, a1 = 0;
 	int wait = 1000;
-	int err;
 
-	err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait);
-	if (err == ERR_ECMDUNKNOWN)
+	if (vnic_dev_capable(vdev, CMD_IG_VLAN_REWRITE_MODE))
+		return vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE,
+				&a0, &a1, wait);
+	else
 		return 0;
-
-	return err;
 }
 
 static int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
@@ -804,7 +803,7 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
 			/* Emulate these for old CMD_INIT_v1 which
 			 * didn't pass a0 so no CMD_INITF_*.
 			 */
-			vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
+			vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &a0, &a1, wait);
 			vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
 		}
 	}
@@ -835,7 +834,10 @@ int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev)
 
 	memset(vdev->args, 0, sizeof(vdev->args));
 
-	err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait);
+	if (vnic_dev_capable(vdev, CMD_INTR_COAL_CONVERT))
+		err = _vnic_dev_cmd(vdev, CMD_INTR_COAL_CONVERT, wait);
+	else
+		err = ERR_ECMDUNKNOWN;
 
 	/* Use defaults when firmware doesn't support the devcmd at all or
 	 * supports it for only specific hardware
@@ -848,9 +850,11 @@ int vnic_dev_intr_coal_timer_info(struct vnic_dev *vdev)
 		return 0;
 	}
 
-	vdev->intr_coal_timer_info.mul = (u32) vdev->args[0];
-	vdev->intr_coal_timer_info.div = (u32) vdev->args[1];
-	vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2];
+	if (!err) {
+		vdev->intr_coal_timer_info.mul = (u32) vdev->args[0];
+		vdev->intr_coal_timer_info.div = (u32) vdev->args[1];
+		vdev->intr_coal_timer_info.max_usec = (u32) vdev->args[2];
+	}
 
 	return err;
 }
@@ -1019,3 +1023,15 @@ int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status)
 {
 	return vnic_dev_cmd_status(vdev, CMD_DEINIT, status);
 }
+
+int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	int i;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		((u8 *)&a0)[i] = mac_addr[i];
+
+	return vnic_dev_cmd(vdev, CMD_SET_MAC_ADDR, &a0, &a1, wait);
+}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.h b/drivers/net/ethernet/cisco/enic/vnic_dev.h
index 6a138b6..f3d9b79 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_dev.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_dev.h
@@ -97,7 +97,7 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
 	int broadcast, int promisc, int allmulti);
 int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr);
 int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr);
-int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
+int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
 int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr);
 int vnic_dev_notify_unset(struct vnic_dev *vdev);
 int vnic_dev_link_status(struct vnic_dev *vdev);
@@ -131,5 +131,6 @@ int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len);
 int vnic_dev_enable2(struct vnic_dev *vdev, int active);
 int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
 int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status);
+int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
 
 #endif /* _VNIC_DEV_H_ */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
index 8025e88..23d5552 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_devcmd.h
@@ -131,7 +131,7 @@ enum vnic_devcmd_cmd {
 	CMD_HANG_NOTIFY         = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8),
 
 	/* MAC address in (u48)a0 */
-	CMD_MAC_ADDR            = _CMDC(_CMD_DIR_READ,
+	CMD_GET_MAC_ADDR        = _CMDC(_CMD_DIR_READ,
 					_CMD_VTYPE_ENET | _CMD_VTYPE_FC, 9),
 
 	/* add addr from (u48)a0 */
@@ -337,6 +337,15 @@ enum vnic_devcmd_cmd {
 	 *      (u32)a2 = maximum timer value in usec
 	 */
 	CMD_INTR_COAL_CONVERT = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 50),
+
+	/*
+	 * cmd_set_mac_addr
+	 *	set mac address
+	 * in:
+	 *   (u48)a0 = mac addr
+	 *
+	 */
+	CMD_SET_MAC_ADDR = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 55),
 };
 
 /* CMD_ENABLE2 flags */
diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c
index 34105e0..7e1488f 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_rq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c
@@ -38,10 +38,8 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
 
 	for (i = 0; i < blks; i++) {
 		rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC);
-		if (!rq->bufs[i]) {
-			pr_err("Failed to alloc rq_bufs\n");
+		if (!rq->bufs[i])
 			return -ENOMEM;
-		}
 	}
 
 	for (i = 0; i < blks; i++) {
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c
index df61bd9..5e0d7a2 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_wq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c
@@ -38,10 +38,8 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
 
 	for (i = 0; i < blks; i++) {
 		wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC);
-		if (!wq->bufs[i]) {
-			pr_err("Failed to alloc wq_bufs\n");
+		if (!wq->bufs[i])
 			return -ENOMEM;
-		}
 	}
 
 	for (i = 0; i < blks; i++) {
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index f801754..36499d5 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -1028,7 +1028,7 @@ dm9000_rx(struct net_device *dev)
 
 		/* Move data from DM9000 */
 		if (GoodPacket &&
-		    ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
+		    ((skb = netdev_alloc_skb(dev, RxLen + 4)) != NULL)) {
 			skb_reserve(skb, 2);
 			rdptr = (u8 *) skb_put(skb, RxLen - 4);
 
@@ -1373,10 +1373,8 @@ dm9000_probe(struct platform_device *pdev)
 
 	/* Init network device */
 	ndev = alloc_etherdev(sizeof(struct board_info));
-	if (!ndev) {
-		dev_err(&pdev->dev, "could not allocate device.\n");
+	if (!ndev)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
@@ -1587,7 +1585,7 @@ dm9000_probe(struct platform_device *pdev)
 		dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
 			 "set using ifconfig\n", ndev->name);
 
-		random_ether_addr(ndev->dev_addr);
+		eth_hw_addr_random(ndev);
 		mac_src = "random";
 	}
 
diff --git a/drivers/net/ethernet/dec/ewrk3.c b/drivers/net/ethernet/dec/ewrk3.c
index f9df5e4..1879f84 100644
--- a/drivers/net/ethernet/dec/ewrk3.c
+++ b/drivers/net/ethernet/dec/ewrk3.c
@@ -986,8 +986,10 @@ static int ewrk3_rx(struct net_device *dev)
 						dev->stats.rx_fifo_errors++;
 				} else {
 					struct sk_buff *skb;
+					skb = netdev_alloc_skb(dev,
+							pkt_len + 2);
 
-					if ((skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+					if (skb != NULL) {
 						unsigned char *p;
 						skb_reserve(skb, 2);	/* Align to 16 bytes */
 						p = skb_put(skb, pkt_len);
diff --git a/drivers/net/ethernet/dec/tulip/21142.c b/drivers/net/ethernet/dec/tulip/21142.c
index 25b8dee..3698582 100644
--- a/drivers/net/ethernet/dec/tulip/21142.c
+++ b/drivers/net/ethernet/dec/tulip/21142.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/21142.c
+	drivers/net/ethernet/dec/tulip/21142.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/de2104x.c b/drivers/net/ethernet/dec/tulip/de2104x.c
index 1eb46a0..68f1c39 100644
--- a/drivers/net/ethernet/dec/tulip/de2104x.c
+++ b/drivers/net/ethernet/dec/tulip/de2104x.c
@@ -439,7 +439,7 @@ static void de_rx (struct de_private *de)
 			  rx_tail, status, len, copying_skb);
 
 		buflen = copying_skb ? (len + RX_OFFSET) : de->rx_buf_sz;
-		copy_skb = dev_alloc_skb (buflen);
+		copy_skb = netdev_alloc_skb(de->dev, buflen);
 		if (unlikely(!copy_skb)) {
 			de->net_stats.rx_dropped++;
 			drop = 1;
@@ -1283,12 +1283,10 @@ static int de_refill_rx (struct de_private *de)
 	for (i = 0; i < DE_RX_RING_SIZE; i++) {
 		struct sk_buff *skb;
 
-		skb = dev_alloc_skb(de->rx_buf_sz);
+		skb = netdev_alloc_skb(de->dev, de->rx_buf_sz);
 		if (!skb)
 			goto err_out;
 
-		skb->dev = de->dev;
-
 		de->rx_skb[i].mapping = pci_map_single(de->pdev,
 			skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		de->rx_skb[i].skb = skb;
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
index 4d71f5a..9358340 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -3598,7 +3598,7 @@ de4x5_alloc_rx_buff(struct net_device *dev, int index, int len)
     struct sk_buff *ret;
     u_long i=0, tmp;
 
-    p = dev_alloc_skb(IEEE802_3_SZ + DE4X5_ALIGN + 2);
+    p = netdev_alloc_skb(dev, IEEE802_3_SZ + DE4X5_ALIGN + 2);
     if (!p) return NULL;
 
     tmp = virt_to_bus(p->data);
@@ -3618,7 +3618,7 @@ de4x5_alloc_rx_buff(struct net_device *dev, int index, int len)
 #else
     if (lp->state != OPEN) return (struct sk_buff *)1; /* Fake out the open */
 
-    p = dev_alloc_skb(len + 2);
+    p = netdev_alloc_skb(dev, len + 2);
     if (!p) return NULL;
 
     skb_reserve(p, 2);	                               /* Align */
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index 51f7542..1eccf49 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -325,8 +325,8 @@ static irqreturn_t dmfe_interrupt(int , void *);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_dmfe (struct net_device *dev);
 #endif
-static void dmfe_descriptor_init(struct dmfe_board_info *, unsigned long);
-static void allocate_rx_buffer(struct dmfe_board_info *);
+static void dmfe_descriptor_init(struct net_device *, unsigned long);
+static void allocate_rx_buffer(struct net_device *);
 static void update_cr6(u32, unsigned long);
 static void send_filter_frame(struct DEVICE *);
 static void dm9132_id_table(struct DEVICE *);
@@ -649,7 +649,7 @@ static void dmfe_init_dm910x(struct DEVICE *dev)
 		db->op_mode = db->media_mode; 	/* Force Mode */
 
 	/* Initialize Transmit/Receive decriptor and CR3/4 */
-	dmfe_descriptor_init(db, ioaddr);
+	dmfe_descriptor_init(dev, ioaddr);
 
 	/* Init CR6 to program DM910x operation */
 	update_cr6(db->cr6_data, ioaddr);
@@ -828,7 +828,7 @@ static irqreturn_t dmfe_interrupt(int irq, void *dev_id)
 
 	/* reallocate rx descriptor buffer */
 	if (db->rx_avail_cnt<RX_DESC_CNT)
-		allocate_rx_buffer(db);
+		allocate_rx_buffer(dev);
 
 	/* Free the transmitted descriptor */
 	if ( db->cr5_data & 0x01)
@@ -1008,7 +1008,7 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db)
 					/* Good packet, send to upper layer */
 					/* Shorst packet used new SKB */
 					if ((rxlen < RX_COPY_SIZE) &&
-						((newskb = dev_alloc_skb(rxlen + 2))
+						((newskb = netdev_alloc_skb(dev, rxlen + 2))
 						!= NULL)) {
 
 						skb = newskb;
@@ -1364,8 +1364,9 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb)
  *	Using Chain structure, and allocate Tx/Rx buffer
  */
 
-static void dmfe_descriptor_init(struct dmfe_board_info *db, unsigned long ioaddr)
+static void dmfe_descriptor_init(struct net_device *dev, unsigned long ioaddr)
 {
+	struct dmfe_board_info *db = netdev_priv(dev);
 	struct tx_desc *tmp_tx;
 	struct rx_desc *tmp_rx;
 	unsigned char *tmp_buf;
@@ -1421,7 +1422,7 @@ static void dmfe_descriptor_init(struct dmfe_board_info *db, unsigned long ioadd
 	tmp_rx->next_rx_desc = db->first_rx_desc;
 
 	/* pre-allocate Rx buffer */
-	allocate_rx_buffer(db);
+	allocate_rx_buffer(dev);
 }
 
 
@@ -1551,15 +1552,16 @@ static void send_filter_frame(struct DEVICE *dev)
  *	As possible as allocate maxiumn Rx buffer
  */
 
-static void allocate_rx_buffer(struct dmfe_board_info *db)
+static void allocate_rx_buffer(struct net_device *dev)
 {
+	struct dmfe_board_info *db = netdev_priv(dev);
 	struct rx_desc *rxptr;
 	struct sk_buff *skb;
 
 	rxptr = db->rx_insert_ptr;
 
 	while(db->rx_avail_cnt < RX_DESC_CNT) {
-		if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
+		if ( ( skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE) ) == NULL )
 			break;
 		rxptr->rx_skb_ptr = skb; /* FIXME (?) */
 		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data,
diff --git a/drivers/net/ethernet/dec/tulip/eeprom.c b/drivers/net/ethernet/dec/tulip/eeprom.c
index 14d5b61..ed7d1dc 100644
--- a/drivers/net/ethernet/dec/tulip/eeprom.c
+++ b/drivers/net/ethernet/dec/tulip/eeprom.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/eeprom.c
+	drivers/net/ethernet/dec/tulip/eeprom.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c
index 4fb8c8c..28a5e42 100644
--- a/drivers/net/ethernet/dec/tulip/interrupt.c
+++ b/drivers/net/ethernet/dec/tulip/interrupt.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/interrupt.c
+	drivers/net/ethernet/dec/tulip/interrupt.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
@@ -69,7 +69,8 @@ int tulip_refill_rx(struct net_device *dev)
 			struct sk_buff *skb;
 			dma_addr_t mapping;
 
-			skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ);
+			skb = tp->rx_buffers[entry].skb =
+				netdev_alloc_skb(dev, PKT_BUF_SZ);
 			if (skb == NULL)
 				break;
 
@@ -77,7 +78,6 @@ int tulip_refill_rx(struct net_device *dev)
 						 PCI_DMA_FROMDEVICE);
 			tp->rx_buffers[entry].mapping = mapping;
 
-			skb->dev = dev;			/* Mark as being used by this device. */
 			tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
 			refilled++;
 		}
@@ -202,7 +202,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
                                /* Check if the packet is long enough to accept without copying
                                   to a minimally-sized skbuff. */
                                if (pkt_len < tulip_rx_copybreak &&
-                                   (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+                                   (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
                                        skb_reserve(skb, 2);    /* 16 byte align the IP header */
                                        pci_dma_sync_single_for_cpu(tp->pdev,
 								   tp->rx_buffers[entry].mapping,
@@ -428,7 +428,7 @@ static int tulip_rx(struct net_device *dev)
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < tulip_rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(tp->pdev,
 							    tp->rx_buffers[entry].mapping,
diff --git a/drivers/net/ethernet/dec/tulip/media.c b/drivers/net/ethernet/dec/tulip/media.c
index beeb17b..ae937c6 100644
--- a/drivers/net/ethernet/dec/tulip/media.c
+++ b/drivers/net/ethernet/dec/tulip/media.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/media.c
+	drivers/net/ethernet/dec/tulip/media.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/pnic.c b/drivers/net/ethernet/dec/tulip/pnic.c
index 9c16e4a..5364563 100644
--- a/drivers/net/ethernet/dec/tulip/pnic.c
+++ b/drivers/net/ethernet/dec/tulip/pnic.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/pnic.c
+	drivers/net/ethernet/dec/tulip/pnic.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/pnic2.c b/drivers/net/ethernet/dec/tulip/pnic2.c
index 04a7e47..5895fc4 100644
--- a/drivers/net/ethernet/dec/tulip/pnic2.c
+++ b/drivers/net/ethernet/dec/tulip/pnic2.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/pnic2.c
+	drivers/net/ethernet/dec/tulip/pnic2.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/timer.c b/drivers/net/ethernet/dec/tulip/timer.c
index 19078d2..768379b 100644
--- a/drivers/net/ethernet/dec/tulip/timer.c
+++ b/drivers/net/ethernet/dec/tulip/timer.c
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/timer.c
+	drivers/net/ethernet/dec/tulip/timer.c
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/tulip.h b/drivers/net/ethernet/dec/tulip/tulip.h
index fb3887c..38431a1 100644
--- a/drivers/net/ethernet/dec/tulip/tulip.h
+++ b/drivers/net/ethernet/dec/tulip/tulip.h
@@ -1,5 +1,5 @@
 /*
-	drivers/net/tulip/tulip.h
+	drivers/net/ethernet/dec/tulip/tulip.h
 
 	Copyright 2000,2001  The Linux Kernel Team
 	Written/copyright 1994-2001 by Donald Becker.
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c
index 4eb0d76..fea3641 100644
--- a/drivers/net/ethernet/dec/tulip/tulip_core.c
+++ b/drivers/net/ethernet/dec/tulip/tulip_core.c
@@ -636,16 +636,15 @@ static void tulip_init_ring(struct net_device *dev)
 		dma_addr_t mapping;
 
 		/* Note the receive buffer must be longword aligned.
-		   dev_alloc_skb() provides 16 byte alignment.  But do *not*
+		   netdev_alloc_skb() provides 16 byte alignment.  But do *not*
 		   use skb_reserve() to align the IP header! */
-		struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
+		struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 		tp->rx_buffers[i].skb = skb;
 		if (skb == NULL)
 			break;
 		mapping = pci_map_single(tp->pdev, skb->data,
 					 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 		tp->rx_buffers[i].mapping = mapping;
-		skb->dev = dev;			/* Mark as being used by this device. */
 		tp->rx_ring[i].status = cpu_to_le32(DescOwned);	/* Owned by Tulip chip */
 		tp->rx_ring[i].buffer1 = cpu_to_le32(mapping);
 	}
@@ -1424,10 +1423,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 
 	/* alloc_etherdev ensures aligned and zeroed private structures */
 	dev = alloc_etherdev (sizeof (*tp));
-	if (!dev) {
-		pr_err("ether device alloc failed, aborting\n");
+	if (!dev)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) {
diff --git a/drivers/net/ethernet/dec/tulip/uli526x.c b/drivers/net/ethernet/dec/tulip/uli526x.c
index 48b0b65..fc4001f 100644
--- a/drivers/net/ethernet/dec/tulip/uli526x.c
+++ b/drivers/net/ethernet/dec/tulip/uli526x.c
@@ -232,8 +232,8 @@ static irqreturn_t uli526x_interrupt(int, void *);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void uli526x_poll(struct net_device *dev);
 #endif
-static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long);
-static void allocate_rx_buffer(struct uli526x_board_info *);
+static void uli526x_descriptor_init(struct net_device *, unsigned long);
+static void allocate_rx_buffer(struct net_device *);
 static void update_cr6(u32, unsigned long);
 static void send_filter_frame(struct net_device *, int);
 static u16 phy_read(unsigned long, u8, u8, u32);
@@ -549,7 +549,7 @@ static void uli526x_init(struct net_device *dev)
 		db->op_mode = db->media_mode; 	/* Force Mode */
 
 	/* Initialize Transmit/Receive decriptor and CR3/4 */
-	uli526x_descriptor_init(db, ioaddr);
+	uli526x_descriptor_init(dev, ioaddr);
 
 	/* Init CR6 to program M526X operation */
 	update_cr6(db->cr6_data, ioaddr);
@@ -711,7 +711,7 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id)
 
 	/* reallocate rx descriptor buffer */
 	if (db->rx_avail_cnt<RX_DESC_CNT)
-		allocate_rx_buffer(db);
+		allocate_rx_buffer(dev);
 
 	/* Free the transmitted descriptor */
 	if ( db->cr5_data & 0x01)
@@ -844,7 +844,7 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info
 				/* Good packet, send to upper layer */
 				/* Shorst packet used new SKB */
 				if ((rxlen < RX_COPY_SIZE) &&
-				    (((new_skb = dev_alloc_skb(rxlen + 2)) != NULL))) {
+				    (((new_skb = netdev_alloc_skb(dev, rxlen + 2)) != NULL))) {
 					skb = new_skb;
 					/* size less than COPY_SIZE, allocate a rxlen SKB */
 					skb_reserve(skb, 2); /* 16byte align */
@@ -1289,8 +1289,9 @@ static void uli526x_reuse_skb(struct uli526x_board_info *db, struct sk_buff * sk
  *	Using Chain structure, and allocate Tx/Rx buffer
  */
 
-static void uli526x_descriptor_init(struct uli526x_board_info *db, unsigned long ioaddr)
+static void uli526x_descriptor_init(struct net_device *dev, unsigned long ioaddr)
 {
+	struct uli526x_board_info *db = netdev_priv(dev);
 	struct tx_desc *tmp_tx;
 	struct rx_desc *tmp_rx;
 	unsigned char *tmp_buf;
@@ -1343,7 +1344,7 @@ static void uli526x_descriptor_init(struct uli526x_board_info *db, unsigned long
 	tmp_rx->next_rx_desc = db->first_rx_desc;
 
 	/* pre-allocate Rx buffer */
-	allocate_rx_buffer(db);
+	allocate_rx_buffer(dev);
 }
 
 
@@ -1433,15 +1434,17 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt)
  *	As possible as allocate maxiumn Rx buffer
  */
 
-static void allocate_rx_buffer(struct uli526x_board_info *db)
+static void allocate_rx_buffer(struct net_device *dev)
 {
+	struct uli526x_board_info *db = netdev_priv(dev);
 	struct rx_desc *rxptr;
 	struct sk_buff *skb;
 
 	rxptr = db->rx_insert_ptr;
 
 	while(db->rx_avail_cnt < RX_DESC_CNT) {
-		if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
+		skb = netdev_alloc_skb(dev, RX_ALLOC_SIZE);
+		if (skb == NULL)
 			break;
 		rxptr->rx_skb_ptr = skb; /* FIXME (?) */
 		rxptr->rdes2 = cpu_to_le32(pci_map_single(db->pdev,
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c
index 52da7b2..2ac6fff 100644
--- a/drivers/net/ethernet/dec/tulip/winbond-840.c
+++ b/drivers/net/ethernet/dec/tulip/winbond-840.c
@@ -815,7 +815,7 @@ static void init_rxtx_rings(struct net_device *dev)
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+		struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz);
 		np->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
@@ -1231,7 +1231,7 @@ static int netdev_rx(struct net_device *dev)
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
 							    np->rx_skbuff[entry]->len,
@@ -1270,7 +1270,7 @@ static int netdev_rx(struct net_device *dev)
 		struct sk_buff *skb;
 		entry = np->dirty_rx % RX_RING_SIZE;
 		if (np->rx_skbuff[entry] == NULL) {
-			skb = dev_alloc_skb(np->rx_buf_sz);
+			skb = netdev_alloc_skb(dev, np->rx_buf_sz);
 			np->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break;			/* Better luck next round. */
diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c
index 988b8eb..fdb329f 100644
--- a/drivers/net/ethernet/dec/tulip/xircom_cb.c
+++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c
@@ -222,10 +222,9 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
 	   is available.
 	 */
 	dev = alloc_etherdev(sizeof(struct xircom_private));
-	if (!dev) {
-		pr_err("%s: failed to allocate etherdev\n", __func__);
+	if (!dev)
 		goto device_fail;
-	}
+
 	private = netdev_priv(dev);
 
 	/* Allocate the send/receive buffers */
@@ -1085,7 +1084,7 @@ investigate_read_descriptor(struct net_device *dev, struct xircom_private *card,
 			pkt_len = 1518;
 		}
 
-		skb = dev_alloc_skb(pkt_len + 2);
+		skb = netdev_alloc_skb(dev, pkt_len + 2);
 		if (skb == NULL) {
 			dev->stats.rx_dropped++;
 			goto out;
diff --git a/drivers/net/ethernet/dlink/de600.c b/drivers/net/ethernet/dlink/de600.c
index c24fab1..682750c 100644
--- a/drivers/net/ethernet/dlink/de600.c
+++ b/drivers/net/ethernet/dlink/de600.c
@@ -335,7 +335,7 @@ static void de600_rx_intr(struct net_device *dev)
 		return;
 	}
 
-	skb = dev_alloc_skb(size+2);
+	skb = netdev_alloc_skb(dev, size + 2);
 	if (skb == NULL) {
 		printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
 		return;
diff --git a/drivers/net/ethernet/dlink/de620.c b/drivers/net/ethernet/dlink/de620.c
index 3b934ab..afc5aaa 100644
--- a/drivers/net/ethernet/dlink/de620.c
+++ b/drivers/net/ethernet/dlink/de620.c
@@ -650,7 +650,7 @@ static int de620_rx_intr(struct net_device *dev)
 		printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
 	}
 	else { /* Good packet? */
-		skb = dev_alloc_skb(size+2);
+		skb = netdev_alloc_skb(dev, size + 2);
 		if (skb == NULL) { /* Yeah, but no place to put it... */
 			printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
 			dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/dlink/sundance.c b/drivers/net/ethernet/dlink/sundance.c
index 28a3a9b..7227f29 100644
--- a/drivers/net/ethernet/dlink/sundance.c
+++ b/drivers/net/ethernet/dlink/sundance.c
@@ -1020,11 +1020,11 @@ static void init_ring(struct net_device *dev)
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 2);
+		struct sk_buff *skb =
+			netdev_alloc_skb(dev, np->rx_buf_sz + 2);
 		np->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
-		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		np->rx_ring[i].frag[0].addr = cpu_to_le32(
 			dma_map_single(&np->pci_dev->dev, skb->data,
@@ -1358,7 +1358,7 @@ static void rx_poll(unsigned long data)
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				dma_sync_single_for_cpu(&np->pci_dev->dev,
 						le32_to_cpu(desc->frag[0].addr),
@@ -1411,11 +1411,10 @@ static void refill_rx (struct net_device *dev)
 		struct sk_buff *skb;
 		entry = np->dirty_rx % RX_RING_SIZE;
 		if (np->rx_skbuff[entry] == NULL) {
-			skb = dev_alloc_skb(np->rx_buf_sz + 2);
+			skb = netdev_alloc_skb(dev, np->rx_buf_sz + 2);
 			np->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break;		/* Better luck next round. */
-			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			np->rx_ring[entry].frag[0].addr = cpu_to_le32(
 				dma_map_single(&np->pci_dev->dev, skb->data,
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
index 925c9ba..b276469 100644
--- a/drivers/net/ethernet/dnet.c
+++ b/drivers/net/ethernet/dnet.c
@@ -421,7 +421,7 @@ static int dnet_poll(struct napi_struct *napi, int budget)
 			printk(KERN_ERR "%s packet receive error %x\n",
 			       __func__, cmd_word);
 
-		skb = dev_alloc_skb(pkt_len + 5);
+		skb = netdev_alloc_skb(dev, pkt_len + 5);
 		if (skb != NULL) {
 			/* Align IP on 16 byte boundaries */
 			skb_reserve(skb, 2);
@@ -854,10 +854,8 @@ static int __devinit dnet_probe(struct platform_device *pdev)
 
 	err = -ENOMEM;
 	dev = alloc_etherdev(sizeof(*bp));
-	if (!dev) {
-		dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
+	if (!dev)
 		goto err_out_release_mem;
-	}
 
 	/* TODO: Actually, we have some interesting features... */
 	dev->features |= 0;
@@ -897,7 +895,7 @@ static int __devinit dnet_probe(struct platform_device *pdev)
 
 	if (!is_valid_ether_addr(dev->dev_addr)) {
 		/* choose a random ethernet address */
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 		__dnet_set_hwaddr(bp);
 	}
 
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index cbdec25..86f51de 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -74,11 +74,14 @@ static inline char *nic_name(struct pci_dev *pdev)
 
 /* Number of bytes of an RX frame that are copied to skb->data */
 #define BE_HDR_LEN		((u16) 64)
+/* allocate extra space to allow tunneling decapsulation without head reallocation */
+#define BE_RX_SKB_ALLOC_SIZE (BE_HDR_LEN + 64)
+
 #define BE_MAX_JUMBO_FRAME_SIZE	9018
 #define BE_MIN_MTU		256
 
 #define BE_NUM_VLANS_SUPPORTED	64
-#define BE_MAX_EQD		96
+#define BE_MAX_EQD		96u
 #define	BE_MAX_TX_FRAG_COUNT	30
 
 #define EVNT_Q_LEN		1024
@@ -89,12 +92,16 @@ static inline char *nic_name(struct pci_dev *pdev)
 #define MCC_Q_LEN		128	/* total size not to exceed 8 pages */
 #define MCC_CQ_LEN		256
 
-#define MAX_RSS_QS		4	/* BE limit is 4 queues/port */
+#define BE3_MAX_RSS_QS		8
+#define BE2_MAX_RSS_QS		4
+#define MAX_RSS_QS		BE3_MAX_RSS_QS
 #define MAX_RX_QS		(MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
+
 #define MAX_TX_QS		8
-#define BE_MAX_MSIX_VECTORS	(MAX_RX_QS + 1)/* RX + TX */
+#define MAX_MSIX_VECTORS	MAX_RSS_QS
+#define BE_TX_BUDGET		256
 #define BE_NAPI_WEIGHT		64
-#define MAX_RX_POST 		BE_NAPI_WEIGHT /* Frags posted at a time */
+#define MAX_RX_POST		BE_NAPI_WEIGHT /* Frags posted at a time */
 #define RX_FRAGS_REFILL_WM	(RX_Q_LEN - MAX_RX_POST)
 
 #define FW_VER_LEN		32
@@ -162,13 +169,16 @@ struct be_eq_obj {
 
 	/* Adaptive interrupt coalescing (AIC) info */
 	bool enable_aic;
-	u16 min_eqd;		/* in usecs */
-	u16 max_eqd;		/* in usecs */
-	u16 cur_eqd;		/* in usecs */
-	u8  eq_idx;
+	u32 min_eqd;		/* in usecs */
+	u32 max_eqd;		/* in usecs */
+	u32 eqd;		/* configured val when aic is off */
+	u32 cur_eqd;		/* in usecs */
 
+	u8 idx;			/* array index */
+	u16 tx_budget;
 	struct napi_struct napi;
-};
+	struct be_adapter *adapter;
+} ____cacheline_aligned_in_smp;
 
 struct be_mcc_obj {
 	struct be_queue_info q;
@@ -194,7 +204,7 @@ struct be_tx_obj {
 	/* Remember the skbs that were transmitted */
 	struct sk_buff *sent_skb_list[TX_Q_LEN];
 	struct be_tx_stats stats;
-};
+} ____cacheline_aligned_in_smp;
 
 /* Struct to remember the pages posted for rx frags */
 struct be_rx_page_info {
@@ -212,8 +222,6 @@ struct be_rx_stats {
 	u32 rx_drops_no_skbs;	/* skb allocation errors */
 	u32 rx_drops_no_frags;	/* HW has no fetched frags */
 	u32 rx_post_fail;	/* page post alloc failures */
-	u32 rx_polls;		/* NAPI calls */
-	u32 rx_events;
 	u32 rx_compl;
 	u32 rx_mcast_pkts;
 	u32 rx_compl_err;	/* completions with err set */
@@ -246,23 +254,19 @@ struct be_rx_obj {
 	struct be_queue_info cq;
 	struct be_rx_compl_info rxcp;
 	struct be_rx_page_info page_info_tbl[RX_Q_LEN];
-	struct be_eq_obj rx_eq;
 	struct be_rx_stats stats;
 	u8 rss_id;
 	bool rx_post_starved;	/* Zero rx frags have been posted to BE */
-	u32 cache_line_barrier[16];
-};
+} ____cacheline_aligned_in_smp;
 
 struct be_drv_stats {
 	u32 be_on_die_temperature;
-	u32 tx_events;
 	u32 eth_red_drops;
 	u32 rx_drops_no_pbuf;
 	u32 rx_drops_no_txpb;
 	u32 rx_drops_no_erx_descr;
 	u32 rx_drops_no_tpre_descr;
 	u32 rx_drops_too_many_frags;
-	u32 rx_drops_invalid_ring;
 	u32 forwarded_packets;
 	u32 rx_drops_mtu;
 	u32 rx_crc_errors;
@@ -273,7 +277,7 @@ struct be_drv_stats {
 	u32 rx_in_range_errors;
 	u32 rx_out_range_errors;
 	u32 rx_frame_too_long;
-	u32 rx_address_match_errors;
+	u32 rx_address_mismatch_drops;
 	u32 rx_dropped_too_small;
 	u32 rx_dropped_too_short;
 	u32 rx_dropped_header_too_small;
@@ -318,20 +322,19 @@ struct be_adapter {
 	spinlock_t mcc_lock;	/* For serializing mcc cmds to BE card */
 	spinlock_t mcc_cq_lock;
 
-	struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
 	u32 num_msix_vec;
+	u32 num_evt_qs;
+	struct be_eq_obj eq_obj[MAX_MSIX_VECTORS];
+	struct msix_entry msix_entries[MAX_MSIX_VECTORS];
 	bool isr_registered;
 
 	/* TX Rings */
-	struct be_eq_obj tx_eq;
+	u32 num_tx_qs;
 	struct be_tx_obj tx_obj[MAX_TX_QS];
-	u8 num_tx_qs;
-
-	u32 cache_line_break[8];
 
 	/* Rx rings */
-	struct be_rx_obj rx_obj[MAX_RX_QS];
 	u32 num_rx_qs;
+	struct be_rx_obj rx_obj[MAX_RX_QS];
 	u32 big_page_size;	/* Compounded page size shared by rx wrbs */
 
 	u8 eq_next_idx;
@@ -402,24 +405,34 @@ struct be_adapter {
 extern const struct ethtool_ops be_ethtool_ops;
 
 #define msix_enabled(adapter)		(adapter->num_msix_vec > 0)
-#define tx_stats(txo)			(&txo->stats)
-#define rx_stats(rxo)			(&rxo->stats)
+#define num_irqs(adapter)		(msix_enabled(adapter) ?	\
+						adapter->num_msix_vec : 1)
+#define tx_stats(txo)			(&(txo)->stats)
+#define rx_stats(rxo)			(&(rxo)->stats)
 
-#define BE_SET_NETDEV_OPS(netdev, ops)	(netdev->netdev_ops = ops)
+/* The default RXQ is the last RXQ */
+#define default_rxo(adpt)		(&adpt->rx_obj[adpt->num_rx_qs - 1])
 
 #define for_all_rx_queues(adapter, rxo, i)				\
 	for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs;	\
 		i++, rxo++)
 
-/* Just skip the first default non-rss queue */
+/* Skip the default non-rss queue (last one)*/
 #define for_all_rss_queues(adapter, rxo, i)				\
-	for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
+	for (i = 0, rxo = &adapter->rx_obj[i]; i < (adapter->num_rx_qs - 1);\
 		i++, rxo++)
 
 #define for_all_tx_queues(adapter, txo, i)				\
 	for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs;	\
 		i++, txo++)
 
+#define for_all_evt_queues(adapter, eqo, i)				\
+	for (i = 0, eqo = &adapter->eq_obj[i]; i < adapter->num_evt_qs; \
+		i++, eqo++)
+
+#define is_mcc_eqo(eqo)			(eqo->idx == 0)
+#define mcc_eqo(adapter)		(&adapter->eq_obj[0])
+
 #define PAGE_SHIFT_4K		12
 #define PAGE_SIZE_4K		(1 << PAGE_SHIFT_4K)
 
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 0fcb456..6432efa 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -235,10 +235,10 @@ void be_async_mcc_disable(struct be_adapter *adapter)
 	adapter->mcc_obj.rearm_cq = false;
 }
 
-int be_process_mcc(struct be_adapter *adapter, int *status)
+int be_process_mcc(struct be_adapter *adapter)
 {
 	struct be_mcc_compl *compl;
-	int num = 0;
+	int num = 0, status = 0;
 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
 
 	spin_lock_bh(&adapter->mcc_cq_lock);
@@ -252,32 +252,32 @@ int be_process_mcc(struct be_adapter *adapter, int *status)
 				be_async_grp5_evt_process(adapter,
 				compl->flags, compl);
 		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
-				*status = be_mcc_compl_process(adapter, compl);
+				status = be_mcc_compl_process(adapter, compl);
 				atomic_dec(&mcc_obj->q.used);
 		}
 		be_mcc_compl_use(compl);
 		num++;
 	}
 
+	if (num)
+		be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
+
 	spin_unlock_bh(&adapter->mcc_cq_lock);
-	return num;
+	return status;
 }
 
 /* Wait till no more pending mcc requests are present */
 static int be_mcc_wait_compl(struct be_adapter *adapter)
 {
 #define mcc_timeout		120000 /* 12s timeout */
-	int i, num, status = 0;
+	int i, status = 0;
 	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
 
 	for (i = 0; i < mcc_timeout; i++) {
 		if (be_error(adapter))
 			return -EIO;
 
-		num = be_process_mcc(adapter, &status);
-		if (num)
-			be_cq_notify(adapter, mcc_obj->cq.id,
-				mcc_obj->rearm_cq, num);
+		status = be_process_mcc(adapter);
 
 		if (atomic_read(&mcc_obj->q.used) == 0)
 			break;
@@ -726,9 +726,8 @@ err:
 }
 
 /* Uses Mbox */
-int be_cmd_cq_create(struct be_adapter *adapter,
-		struct be_queue_info *cq, struct be_queue_info *eq,
-		bool sol_evts, bool no_delay, int coalesce_wm)
+int be_cmd_cq_create(struct be_adapter *adapter, struct be_queue_info *cq,
+		struct be_queue_info *eq, bool no_delay, int coalesce_wm)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_cq_create *req;
@@ -759,7 +758,6 @@ int be_cmd_cq_create(struct be_adapter *adapter,
 								ctxt, 1);
 		AMAP_SET_BITS(struct amap_cq_context_lancer, eqid,
 								ctxt, eq->id);
-		AMAP_SET_BITS(struct amap_cq_context_lancer, armed, ctxt, 1);
 	} else {
 		AMAP_SET_BITS(struct amap_cq_context_be, coalescwm, ctxt,
 								coalesce_wm);
@@ -768,11 +766,8 @@ int be_cmd_cq_create(struct be_adapter *adapter,
 		AMAP_SET_BITS(struct amap_cq_context_be, count, ctxt,
 						__ilog2_u32(cq->len/256));
 		AMAP_SET_BITS(struct amap_cq_context_be, valid, ctxt, 1);
-		AMAP_SET_BITS(struct amap_cq_context_be, solevent,
-								ctxt, sol_evts);
 		AMAP_SET_BITS(struct amap_cq_context_be, eventable, ctxt, 1);
 		AMAP_SET_BITS(struct amap_cq_context_be, eqid, ctxt, eq->id);
-		AMAP_SET_BITS(struct amap_cq_context_be, armed, ctxt, 1);
 	}
 
 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
@@ -973,7 +968,7 @@ err:
 /* Uses MCC */
 int be_cmd_rxq_create(struct be_adapter *adapter,
 		struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
-		u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id)
+		u32 if_id, u32 rss, u8 *rss_id)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_eth_rx_create *req;
@@ -997,7 +992,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
 	req->num_pages = 2;
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 	req->interface_id = cpu_to_le32(if_id);
-	req->max_frame_size = cpu_to_le16(max_frame_size);
+	req->max_frame_size = cpu_to_le16(BE_MAX_JUMBO_FRAME_SIZE);
 	req->rss_queue = cpu_to_le32(rss);
 
 	status = be_mcc_notify_wait(adapter);
@@ -1257,11 +1252,13 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
 	}
 	req = embedded_payload(wrb);
 
+	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL);
+
 	if (adapter->generation == BE_GEN3 || lancer_chip(adapter))
 		req->hdr.version = 1;
 
-	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-		OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req), wrb, NULL);
+	req->hdr.domain = dom;
 
 	status = be_mcc_notify_wait(adapter);
 	if (!status) {
@@ -2298,52 +2295,81 @@ err:
 
 /* Uses synchronous MCCQ */
 int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
-							u32 *pmac_id)
+			bool *pmac_id_active, u32 *pmac_id, u8 *mac)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_get_mac_list *req;
 	int status;
 	int mac_count;
+	struct be_dma_mem get_mac_list_cmd;
+	int i;
+
+	memset(&get_mac_list_cmd, 0, sizeof(struct be_dma_mem));
+	get_mac_list_cmd.size = sizeof(struct be_cmd_resp_get_mac_list);
+	get_mac_list_cmd.va = pci_alloc_consistent(adapter->pdev,
+			get_mac_list_cmd.size,
+			&get_mac_list_cmd.dma);
+
+	if (!get_mac_list_cmd.va) {
+		dev_err(&adapter->pdev->dev,
+				"Memory allocation failure during GET_MAC_LIST\n");
+		return -ENOMEM;
+	}
 
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
 	if (!wrb) {
 		status = -EBUSY;
-		goto err;
+		goto out;
 	}
-	req = embedded_payload(wrb);
+
+	req = get_mac_list_cmd.va;
 
 	be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 				OPCODE_COMMON_GET_MAC_LIST, sizeof(*req),
-				wrb, NULL);
+				wrb, &get_mac_list_cmd);
 
 	req->hdr.domain = domain;
+	req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
+	req->perm_override = 1;
 
 	status = be_mcc_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_get_mac_list *resp =
-						embedded_payload(wrb);
-		int i;
-		u8 *ctxt = &resp->context[0][0];
-		status = -EIO;
-		mac_count = resp->mac_count;
-		be_dws_le_to_cpu(&resp->context, sizeof(resp->context));
+						get_mac_list_cmd.va;
+		mac_count = resp->true_mac_count + resp->pseudo_mac_count;
+		/* Mac list returned could contain one or more active mac_ids
+		 * or one or more pseudo permanant mac addresses. If an active
+		 * mac_id is present, return first active mac_id found
+		 */
 		for (i = 0; i < mac_count; i++) {
-			if (!AMAP_GET_BITS(struct amap_get_mac_list_context,
-					   act, ctxt)) {
-				*pmac_id = AMAP_GET_BITS
-					(struct amap_get_mac_list_context,
-					 macid, ctxt);
-				status = 0;
-				break;
+			struct get_list_macaddr *mac_entry;
+			u16 mac_addr_size;
+			u32 mac_id;
+
+			mac_entry = &resp->macaddr_list[i];
+			mac_addr_size = le16_to_cpu(mac_entry->mac_addr_size);
+			/* mac_id is a 32 bit value and mac_addr size
+			 * is 6 bytes
+			 */
+			if (mac_addr_size == sizeof(u32)) {
+				*pmac_id_active = true;
+				mac_id = mac_entry->mac_addr_id.s_mac_id.mac_id;
+				*pmac_id = le32_to_cpu(mac_id);
+				goto out;
 			}
-			ctxt += sizeof(struct amap_get_mac_list_context) / 8;
 		}
+		/* If no active mac_id found, return first pseudo mac addr */
+		*pmac_id_active = false;
+		memcpy(mac, resp->macaddr_list[0].mac_addr_id.macaddr,
+								ETH_ALEN);
 	}
 
-err:
+out:
 	spin_unlock_bh(&adapter->mcc_lock);
+	pci_free_consistent(adapter->pdev, get_mac_list_cmd.size,
+			get_mac_list_cmd.va, get_mac_list_cmd.dma);
 	return status;
 }
 
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index dca8924..687c420 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -592,8 +592,8 @@ struct be_port_rxf_stats_v0 {
 	u32 rx_in_range_errors;	/* dword 10*/
 	u32 rx_out_range_errors;	/* dword 11*/
 	u32 rx_frame_too_long;	/* dword 12*/
-	u32 rx_address_match_errors;	/* dword 13*/
-	u32 rx_vlan_mismatch;	/* dword 14*/
+	u32 rx_address_mismatch_drops;	/* dword 13*/
+	u32 rx_vlan_mismatch_drops;	/* dword 14*/
 	u32 rx_dropped_too_small;	/* dword 15*/
 	u32 rx_dropped_too_short;	/* dword 16*/
 	u32 rx_dropped_header_too_small;	/* dword 17*/
@@ -799,8 +799,8 @@ struct lancer_pport_stats {
 	u32 rx_control_frames_unknown_opcode_hi;
 	u32 rx_in_range_errors;
 	u32 rx_out_of_range_errors;
-	u32 rx_address_match_errors;
-	u32 rx_vlan_mismatch_errors;
+	u32 rx_address_mismatch_drops;
+	u32 rx_vlan_mismatch_drops;
 	u32 rx_dropped_too_small;
 	u32 rx_dropped_too_short;
 	u32 rx_dropped_header_too_small;
@@ -1346,22 +1346,36 @@ struct be_cmd_resp_set_func_cap {
 
 /******************** GET/SET_MACLIST  **************************/
 #define BE_MAX_MAC			64
-struct amap_get_mac_list_context {
-	u8 macid[31];
-	u8 act;
-} __packed;
-
 struct be_cmd_req_get_mac_list {
 	struct be_cmd_req_hdr hdr;
-	u32 rsvd;
+	u8 mac_type;
+	u8 perm_override;
+	u16 iface_id;
+	u32 mac_id;
+	u32 rsvd[3];
+} __packed;
+
+struct get_list_macaddr {
+	u16 mac_addr_size;
+	union {
+		u8 macaddr[6];
+		struct {
+			u8 rsvd[2];
+			u32 mac_id;
+		} __packed s_mac_id;
+	} __packed mac_addr_id;
 } __packed;
 
 struct be_cmd_resp_get_mac_list {
 	struct be_cmd_resp_hdr hdr;
-	u8 mac_count;
-	u8 rsvd1;
-	u16 rsvd2;
-	u8 context[sizeof(struct amap_get_mac_list_context) / 8][BE_MAX_MAC];
+	struct get_list_macaddr fd_macaddr; /* Factory default mac */
+	struct get_list_macaddr macid_macaddr; /* soft mac */
+	u8 true_mac_count;
+	u8 pseudo_mac_count;
+	u8 mac_list_size;
+	u8 rsvd;
+	/* perm override mac */
+	struct get_list_macaddr macaddr_list[BE_MAX_MAC];
 } __packed;
 
 struct be_cmd_req_set_mac_list {
@@ -1384,7 +1398,7 @@ struct be_port_rxf_stats_v1 {
 	u32 rx_in_range_errors;
 	u32 rx_out_range_errors;
 	u32 rx_frame_too_long;
-	u32 rx_address_match_errors;
+	u32 rx_address_mismatch_drops;
 	u32 rx_dropped_too_small;
 	u32 rx_dropped_too_short;
 	u32 rx_dropped_header_too_small;
@@ -1492,8 +1506,7 @@ extern int be_cmd_eq_create(struct be_adapter *adapter,
 			struct be_queue_info *eq, int eq_delay);
 extern int be_cmd_cq_create(struct be_adapter *adapter,
 			struct be_queue_info *cq, struct be_queue_info *eq,
-			bool sol_evts, bool no_delay,
-			int num_cqe_dma_coalesce);
+			bool no_delay, int num_cqe_dma_coalesce);
 extern int be_cmd_mccq_create(struct be_adapter *adapter,
 			struct be_queue_info *mccq,
 			struct be_queue_info *cq);
@@ -1502,8 +1515,7 @@ extern int be_cmd_txq_create(struct be_adapter *adapter,
 			struct be_queue_info *cq);
 extern int be_cmd_rxq_create(struct be_adapter *adapter,
 			struct be_queue_info *rxq, u16 cq_id,
-			u16 frag_size, u16 max_frame_size, u32 if_id,
-			u32 rss, u8 *rss_id);
+			u16 frag_size, u32 if_id, u32 rss, u8 *rss_id);
 extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 			int type);
 extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
@@ -1532,7 +1544,7 @@ extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
 extern int be_cmd_reset_function(struct be_adapter *adapter);
 extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
 			u16 table_size);
-extern int be_process_mcc(struct be_adapter *adapter, int *status);
+extern int be_process_mcc(struct be_adapter *adapter);
 extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
 			u8 port_num, u8 beacon, u8 status, u8 state);
 extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
@@ -1575,7 +1587,7 @@ extern int be_cmd_req_native_mode(struct be_adapter *adapter);
 extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
 extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
 extern int be_cmd_get_mac_from_list(struct be_adapter *adapter, u32 domain,
-							u32 *pmac_id);
+				bool *pmac_id_active, u32 *pmac_id, u8 *mac);
 extern int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
 						u8 mac_count, u32 domain);
 
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 802e5dd..30ce178 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -37,20 +37,46 @@ enum {DRVSTAT_TX, DRVSTAT_RX, DRVSTAT};
 					FIELDINFO(struct be_drv_stats, field)
 
 static const struct be_ethtool_stat et_stats[] = {
-	{DRVSTAT_INFO(tx_events)},
 	{DRVSTAT_INFO(rx_crc_errors)},
 	{DRVSTAT_INFO(rx_alignment_symbol_errors)},
 	{DRVSTAT_INFO(rx_pause_frames)},
 	{DRVSTAT_INFO(rx_control_frames)},
+	/* Received packets dropped when the Ethernet length field
+	 * is not equal to the actual Ethernet data length.
+	 */
 	{DRVSTAT_INFO(rx_in_range_errors)},
+	/* Received packets dropped when their length field is >= 1501 bytes
+	 * and <= 1535 bytes.
+	 */
 	{DRVSTAT_INFO(rx_out_range_errors)},
+	/* Received packets dropped when they are longer than 9216 bytes */
 	{DRVSTAT_INFO(rx_frame_too_long)},
-	{DRVSTAT_INFO(rx_address_match_errors)},
+	/* Received packets dropped when they don't pass the unicast or
+	 * multicast address filtering.
+	 */
+	{DRVSTAT_INFO(rx_address_mismatch_drops)},
+	/* Received packets dropped when IP packet length field is less than
+	 * the IP header length field.
+	 */
 	{DRVSTAT_INFO(rx_dropped_too_small)},
+	/* Received packets dropped when IP length field is greater than
+	 * the actual packet length.
+	 */
 	{DRVSTAT_INFO(rx_dropped_too_short)},
+	/* Received packets dropped when the IP header length field is less
+	 * than 5.
+	 */
 	{DRVSTAT_INFO(rx_dropped_header_too_small)},
+	/* Received packets dropped when the TCP header length field is less
+	 * than 5 or the TCP header length + IP header length is more
+	 * than IP packet length.
+	 */
 	{DRVSTAT_INFO(rx_dropped_tcp_length)},
 	{DRVSTAT_INFO(rx_dropped_runt)},
+	/* Number of received packets dropped when a fifo for descriptors going
+	 * into the packet demux block overflows. In normal operation, this
+	 * fifo must never overflow.
+	 */
 	{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
 	{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
 	{DRVSTAT_INFO(rx_ip_checksum_errs)},
@@ -59,16 +85,35 @@ static const struct be_ethtool_stat et_stats[] = {
 	{DRVSTAT_INFO(tx_pauseframes)},
 	{DRVSTAT_INFO(tx_controlframes)},
 	{DRVSTAT_INFO(rx_priority_pause_frames)},
+	/* Received packets dropped when an internal fifo going into
+	 * main packet buffer tank (PMEM) overflows.
+	 */
 	{DRVSTAT_INFO(pmem_fifo_overflow_drop)},
 	{DRVSTAT_INFO(jabber_events)},
+	/* Received packets dropped due to lack of available HW packet buffers
+	 * used to temporarily hold the received packets.
+	 */
 	{DRVSTAT_INFO(rx_drops_no_pbuf)},
-	{DRVSTAT_INFO(rx_drops_no_txpb)},
+	/* Received packets dropped due to input receive buffer
+	 * descriptor fifo overflowing.
+	 */
 	{DRVSTAT_INFO(rx_drops_no_erx_descr)},
+	/* Packets dropped because the internal FIFO to the offloaded TCP
+	 * receive processing block is full. This could happen only for
+	 * offloaded iSCSI or FCoE trarffic.
+	 */
 	{DRVSTAT_INFO(rx_drops_no_tpre_descr)},
+	/* Received packets dropped when they need more than 8
+	 * receive buffers. This cannot happen as the driver configures
+	 * 2048 byte receive buffers.
+	 */
 	{DRVSTAT_INFO(rx_drops_too_many_frags)},
-	{DRVSTAT_INFO(rx_drops_invalid_ring)},
 	{DRVSTAT_INFO(forwarded_packets)},
+	/* Received packets dropped when the frame length
+	 * is more than 9018 bytes
+	 */
 	{DRVSTAT_INFO(rx_drops_mtu)},
+	/* Number of packets dropped due to random early drop function */
 	{DRVSTAT_INFO(eth_red_drops)},
 	{DRVSTAT_INFO(be_on_die_temperature)}
 };
@@ -80,12 +125,17 @@ static const struct be_ethtool_stat et_stats[] = {
 static const struct be_ethtool_stat et_rx_stats[] = {
 	{DRVSTAT_RX_INFO(rx_bytes)},/* If moving this member see above note */
 	{DRVSTAT_RX_INFO(rx_pkts)}, /* If moving this member see above note */
-	{DRVSTAT_RX_INFO(rx_polls)},
-	{DRVSTAT_RX_INFO(rx_events)},
 	{DRVSTAT_RX_INFO(rx_compl)},
 	{DRVSTAT_RX_INFO(rx_mcast_pkts)},
+	/* Number of page allocation failures while posting receive buffers
+	 * to HW.
+	 */
 	{DRVSTAT_RX_INFO(rx_post_fail)},
+	/* Recevied packets dropped due to skb allocation failure */
 	{DRVSTAT_RX_INFO(rx_drops_no_skbs)},
+	/* Received packets dropped due to lack of available fetched buffers
+	 * posted by the driver.
+	 */
 	{DRVSTAT_RX_INFO(rx_drops_no_frags)}
 };
 #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
@@ -97,9 +147,13 @@ static const struct be_ethtool_stat et_tx_stats[] = {
 	{DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */
 	{DRVSTAT_TX_INFO(tx_bytes)},
 	{DRVSTAT_TX_INFO(tx_pkts)},
+	/* Number of skbs queued for trasmission by the driver */
 	{DRVSTAT_TX_INFO(tx_reqs)},
+	/* Number of TX work request blocks DMAed to HW */
 	{DRVSTAT_TX_INFO(tx_wrbs)},
-	{DRVSTAT_TX_INFO(tx_compl)},
+	/* Number of times the TX queue was stopped due to lack
+	 * of spaces in the TXQ.
+	 */
 	{DRVSTAT_TX_INFO(tx_stops)}
 };
 #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
@@ -232,86 +286,42 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
 	}
 }
 
-static int
-be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+static int be_get_coalesce(struct net_device *netdev,
+			   struct ethtool_coalesce *et)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq;
-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+	struct be_eq_obj *eqo = &adapter->eq_obj[0];
+
 
-	coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
-	coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd;
-	coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd;
+	et->rx_coalesce_usecs = eqo->cur_eqd;
+	et->rx_coalesce_usecs_high = eqo->max_eqd;
+	et->rx_coalesce_usecs_low = eqo->min_eqd;
 
-	coalesce->tx_coalesce_usecs = tx_eq->cur_eqd;
-	coalesce->tx_coalesce_usecs_high = tx_eq->max_eqd;
-	coalesce->tx_coalesce_usecs_low = tx_eq->min_eqd;
+	et->tx_coalesce_usecs = eqo->cur_eqd;
+	et->tx_coalesce_usecs_high = eqo->max_eqd;
+	et->tx_coalesce_usecs_low = eqo->min_eqd;
 
-	coalesce->use_adaptive_rx_coalesce = rx_eq->enable_aic;
-	coalesce->use_adaptive_tx_coalesce = tx_eq->enable_aic;
+	et->use_adaptive_rx_coalesce = eqo->enable_aic;
+	et->use_adaptive_tx_coalesce = eqo->enable_aic;
 
 	return 0;
 }
 
-/*
- * This routine is used to set interrup coalescing delay
+/* TX attributes are ignored. Only RX attributes are considered
+ * eqd cmd is issued in the worker thread.
  */
-static int
-be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
+static int be_set_coalesce(struct net_device *netdev,
+			   struct ethtool_coalesce *et)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_rx_obj *rxo;
-	struct be_eq_obj *rx_eq;
-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
-	u32 rx_max, rx_min, rx_cur;
-	int status = 0, i;
-	u32 tx_cur;
-
-	if (coalesce->use_adaptive_tx_coalesce == 1)
-		return -EINVAL;
-
-	for_all_rx_queues(adapter, rxo, i) {
-		rx_eq = &rxo->rx_eq;
-
-		if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce)
-			rx_eq->cur_eqd = 0;
-		rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce;
-
-		rx_max = coalesce->rx_coalesce_usecs_high;
-		rx_min = coalesce->rx_coalesce_usecs_low;
-		rx_cur = coalesce->rx_coalesce_usecs;
-
-		if (rx_eq->enable_aic) {
-			if (rx_max > BE_MAX_EQD)
-				rx_max = BE_MAX_EQD;
-			if (rx_min > rx_max)
-				rx_min = rx_max;
-			rx_eq->max_eqd = rx_max;
-			rx_eq->min_eqd = rx_min;
-			if (rx_eq->cur_eqd > rx_max)
-				rx_eq->cur_eqd = rx_max;
-			if (rx_eq->cur_eqd < rx_min)
-				rx_eq->cur_eqd = rx_min;
-		} else {
-			if (rx_cur > BE_MAX_EQD)
-				rx_cur = BE_MAX_EQD;
-			if (rx_eq->cur_eqd != rx_cur) {
-				status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
-						rx_cur);
-				if (!status)
-					rx_eq->cur_eqd = rx_cur;
-			}
-		}
-	}
-
-	tx_cur = coalesce->tx_coalesce_usecs;
-
-	if (tx_cur > BE_MAX_EQD)
-		tx_cur = BE_MAX_EQD;
-	if (tx_eq->cur_eqd != tx_cur) {
-		status = be_cmd_modify_eqd(adapter, tx_eq->q.id, tx_cur);
-		if (!status)
-			tx_eq->cur_eqd = tx_cur;
+	struct be_eq_obj *eqo;
+	int i;
+
+	for_all_evt_queues(adapter, eqo, i) {
+		eqo->enable_aic = et->use_adaptive_rx_coalesce;
+		eqo->max_eqd = min(et->rx_coalesce_usecs_high, BE_MAX_EQD);
+		eqo->min_eqd = min(et->rx_coalesce_usecs_low, eqo->max_eqd);
+		eqo->eqd = et->rx_coalesce_usecs;
 	}
 
 	return 0;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index e703d64..28f2b25 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -144,7 +144,7 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
 	mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
 				     GFP_KERNEL);
 	if (!mem->va)
-		return -1;
+		return -ENOMEM;
 	memset(mem->va, 0, mem->size);
 	return 0;
 }
@@ -286,7 +286,9 @@ static void populate_be2_stats(struct be_adapter *adapter)
 	drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow;
 	drvs->rx_dropped_header_too_small =
 		port_stats->rx_dropped_header_too_small;
-	drvs->rx_address_match_errors = port_stats->rx_address_match_errors;
+	drvs->rx_address_mismatch_drops =
+					port_stats->rx_address_mismatch_drops +
+					port_stats->rx_vlan_mismatch_drops;
 	drvs->rx_alignment_symbol_errors =
 		port_stats->rx_alignment_symbol_errors;
 
@@ -298,9 +300,7 @@ static void populate_be2_stats(struct be_adapter *adapter)
 	else
 		drvs->jabber_events = rxf_stats->port0_jabber_events;
 	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
-	drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
 	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
-	drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
 	drvs->forwarded_packets = rxf_stats->forwarded_packets;
 	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
 	drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
@@ -337,7 +337,7 @@ static void populate_be3_stats(struct be_adapter *adapter)
 		port_stats->rx_dropped_header_too_small;
 	drvs->rx_input_fifo_overflow_drop =
 		port_stats->rx_input_fifo_overflow_drop;
-	drvs->rx_address_match_errors = port_stats->rx_address_match_errors;
+	drvs->rx_address_mismatch_drops = port_stats->rx_address_mismatch_drops;
 	drvs->rx_alignment_symbol_errors =
 		port_stats->rx_alignment_symbol_errors;
 	drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop;
@@ -345,9 +345,7 @@ static void populate_be3_stats(struct be_adapter *adapter)
 	drvs->tx_controlframes = port_stats->tx_controlframes;
 	drvs->jabber_events = port_stats->jabber_events;
 	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
-	drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
 	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
-	drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
 	drvs->forwarded_packets = rxf_stats->forwarded_packets;
 	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
 	drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr;
@@ -380,13 +378,14 @@ static void populate_lancer_stats(struct be_adapter *adapter)
 	drvs->rx_dropped_header_too_small =
 				pport_stats->rx_dropped_header_too_small;
 	drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
-	drvs->rx_address_match_errors = pport_stats->rx_address_match_errors;
+	drvs->rx_address_mismatch_drops =
+					pport_stats->rx_address_mismatch_drops +
+					pport_stats->rx_vlan_mismatch_drops;
 	drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo;
 	drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
 	drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo;
 	drvs->tx_controlframes = pport_stats->tx_control_frames_lo;
 	drvs->jabber_events = pport_stats->rx_jabbers;
-	drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue;
 	drvs->forwarded_packets = pport_stats->num_forwards_lo;
 	drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo;
 	drvs->rx_drops_too_many_frags =
@@ -997,18 +996,24 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
 	return status;
 }
 
-static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
+static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
 {
-	struct be_eq_obj *rx_eq = &rxo->rx_eq;
-	struct be_rx_stats *stats = rx_stats(rxo);
+	struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
 	ulong now = jiffies;
 	ulong delta = now - stats->rx_jiffies;
 	u64 pkts;
 	unsigned int start, eqd;
 
-	if (!rx_eq->enable_aic)
+	if (!eqo->enable_aic) {
+		eqd = eqo->eqd;
+		goto modify_eqd;
+	}
+
+	if (eqo->idx >= adapter->num_rx_qs)
 		return;
 
+	stats = rx_stats(&adapter->rx_obj[eqo->idx]);
+
 	/* Wrapped around */
 	if (time_before(now, stats->rx_jiffies)) {
 		stats->rx_jiffies = now;
@@ -1027,17 +1032,16 @@ static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
 	stats->rx_pps = (unsigned long)(pkts - stats->rx_pkts_prev) / (delta / HZ);
 	stats->rx_pkts_prev = pkts;
 	stats->rx_jiffies = now;
-	eqd = stats->rx_pps / 110000;
-	eqd = eqd << 3;
-	if (eqd > rx_eq->max_eqd)
-		eqd = rx_eq->max_eqd;
-	if (eqd < rx_eq->min_eqd)
-		eqd = rx_eq->min_eqd;
+	eqd = (stats->rx_pps / 110000) << 3;
+	eqd = min(eqd, eqo->max_eqd);
+	eqd = max(eqd, eqo->min_eqd);
 	if (eqd < 10)
 		eqd = 0;
-	if (eqd != rx_eq->cur_eqd) {
-		be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd);
-		rx_eq->cur_eqd = eqd;
+
+modify_eqd:
+	if (eqd != eqo->cur_eqd) {
+		be_cmd_modify_eqd(adapter, eqo->q.id, eqd);
+		eqo->cur_eqd = eqd;
 	}
 }
 
@@ -1065,11 +1069,10 @@ static inline bool csum_passed(struct be_rx_compl_info *rxcp)
 				(rxcp->ip_csum || rxcp->ipv6);
 }
 
-static struct be_rx_page_info *
-get_rx_page_info(struct be_adapter *adapter,
-		struct be_rx_obj *rxo,
-		u16 frag_idx)
+static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo,
+						u16 frag_idx)
 {
+	struct be_adapter *adapter = rxo->adapter;
 	struct be_rx_page_info *rx_page_info;
 	struct be_queue_info *rxq = &rxo->q;
 
@@ -1088,16 +1091,15 @@ get_rx_page_info(struct be_adapter *adapter,
 }
 
 /* Throwaway the data in the Rx completion */
-static void be_rx_compl_discard(struct be_adapter *adapter,
-		struct be_rx_obj *rxo,
-		struct be_rx_compl_info *rxcp)
+static void be_rx_compl_discard(struct be_rx_obj *rxo,
+				struct be_rx_compl_info *rxcp)
 {
 	struct be_queue_info *rxq = &rxo->q;
 	struct be_rx_page_info *page_info;
 	u16 i, num_rcvd = rxcp->num_rcvd;
 
 	for (i = 0; i < num_rcvd; i++) {
-		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+		page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
 		put_page(page_info->page);
 		memset(page_info, 0, sizeof(*page_info));
 		index_inc(&rxcp->rxq_idx, rxq->len);
@@ -1108,8 +1110,8 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
  * skb_fill_rx_data forms a complete skb for an ether frame
  * indicated by rxcp.
  */
-static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
-			struct sk_buff *skb, struct be_rx_compl_info *rxcp)
+static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
+			     struct be_rx_compl_info *rxcp)
 {
 	struct be_queue_info *rxq = &rxo->q;
 	struct be_rx_page_info *page_info;
@@ -1117,7 +1119,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
 	u16 hdr_len, curr_frag_len, remaining;
 	u8 *start;
 
-	page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+	page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
 	start = page_address(page_info->page) + page_info->page_offset;
 	prefetch(start);
 
@@ -1154,7 +1156,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
 	index_inc(&rxcp->rxq_idx, rxq->len);
 	remaining = rxcp->pkt_size - curr_frag_len;
 	for (i = 1, j = 0; i < rxcp->num_rcvd; i++) {
-		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+		page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
 		curr_frag_len = min(remaining, rx_frag_size);
 
 		/* Coalesce all frags from the same physical page in one slot */
@@ -1182,21 +1184,21 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo,
 }
 
 /* Process the RX completion indicated by rxcp when GRO is disabled */
-static void be_rx_compl_process(struct be_adapter *adapter,
-			struct be_rx_obj *rxo,
-			struct be_rx_compl_info *rxcp)
+static void be_rx_compl_process(struct be_rx_obj *rxo,
+				struct be_rx_compl_info *rxcp)
 {
+	struct be_adapter *adapter = rxo->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct sk_buff *skb;
 
-	skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN);
+	skb = netdev_alloc_skb_ip_align(netdev, BE_RX_SKB_ALLOC_SIZE);
 	if (unlikely(!skb)) {
 		rx_stats(rxo)->rx_drops_no_skbs++;
-		be_rx_compl_discard(adapter, rxo, rxcp);
+		be_rx_compl_discard(rxo, rxcp);
 		return;
 	}
 
-	skb_fill_rx_data(adapter, rxo, skb, rxcp);
+	skb_fill_rx_data(rxo, skb, rxcp);
 
 	if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp)))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1204,7 +1206,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 		skb_checksum_none_assert(skb);
 
 	skb->protocol = eth_type_trans(skb, netdev);
-	if (adapter->netdev->features & NETIF_F_RXHASH)
+	if (netdev->features & NETIF_F_RXHASH)
 		skb->rxhash = rxcp->rss_hash;
 
 
@@ -1215,26 +1217,25 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 }
 
 /* Process the RX completion indicated by rxcp when GRO is enabled */
-static void be_rx_compl_process_gro(struct be_adapter *adapter,
-		struct be_rx_obj *rxo,
-		struct be_rx_compl_info *rxcp)
+void be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
+			     struct be_rx_compl_info *rxcp)
 {
+	struct be_adapter *adapter = rxo->adapter;
 	struct be_rx_page_info *page_info;
 	struct sk_buff *skb = NULL;
 	struct be_queue_info *rxq = &rxo->q;
-	struct be_eq_obj *eq_obj =  &rxo->rx_eq;
 	u16 remaining, curr_frag_len;
 	u16 i, j;
 
-	skb = napi_get_frags(&eq_obj->napi);
+	skb = napi_get_frags(napi);
 	if (!skb) {
-		be_rx_compl_discard(adapter, rxo, rxcp);
+		be_rx_compl_discard(rxo, rxcp);
 		return;
 	}
 
 	remaining = rxcp->pkt_size;
 	for (i = 0, j = -1; i < rxcp->num_rcvd; i++) {
-		page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx);
+		page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
 
 		curr_frag_len = min(remaining, rx_frag_size);
 
@@ -1267,12 +1268,11 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
 	if (rxcp->vlanf)
 		__vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
 
-	napi_gro_frags(&eq_obj->napi);
+	napi_gro_frags(napi);
 }
 
-static void be_parse_rx_compl_v1(struct be_adapter *adapter,
-				struct be_eth_rx_compl *compl,
-				struct be_rx_compl_info *rxcp)
+static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
+				 struct be_rx_compl_info *rxcp)
 {
 	rxcp->pkt_size =
 		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl);
@@ -1303,9 +1303,8 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter,
 	rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, port, compl);
 }
 
-static void be_parse_rx_compl_v0(struct be_adapter *adapter,
-				struct be_eth_rx_compl *compl,
-				struct be_rx_compl_info *rxcp)
+static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
+				 struct be_rx_compl_info *rxcp)
 {
 	rxcp->pkt_size =
 		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl);
@@ -1351,9 +1350,9 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
 	be_dws_le_to_cpu(compl, sizeof(*compl));
 
 	if (adapter->be3_native)
-		be_parse_rx_compl_v1(adapter, compl, rxcp);
+		be_parse_rx_compl_v1(compl, rxcp);
 	else
-		be_parse_rx_compl_v0(adapter, compl, rxcp);
+		be_parse_rx_compl_v0(compl, rxcp);
 
 	if (rxcp->vlanf) {
 		/* vlanf could be wrongly set in some cards.
@@ -1392,7 +1391,6 @@ static inline struct page *be_alloc_pages(u32 size, gfp_t gfp)
 static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
 {
 	struct be_adapter *adapter = rxo->adapter;
-	struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl;
 	struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL;
 	struct be_queue_info *rxq = &rxo->q;
 	struct page *pagep = NULL;
@@ -1434,7 +1432,7 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp)
 
 		prev_page_info = page_info;
 		queue_head_inc(rxq);
-		page_info = &page_info_tbl[rxq->head];
+		page_info = &rxo->page_info_tbl[rxq->head];
 	}
 	if (pagep)
 		prev_page_info->last_page_user = true;
@@ -1496,62 +1494,51 @@ static u16 be_tx_compl_process(struct be_adapter *adapter,
 	return num_wrbs;
 }
 
-static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
+/* Return the number of events in the event queue */
+static inline int events_get(struct be_eq_obj *eqo)
 {
-	struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
+	struct be_eq_entry *eqe;
+	int num = 0;
 
-	if (!eqe->evt)
-		return NULL;
+	do {
+		eqe = queue_tail_node(&eqo->q);
+		if (eqe->evt == 0)
+			break;
 
-	rmb();
-	eqe->evt = le32_to_cpu(eqe->evt);
-	queue_tail_inc(&eq_obj->q);
-	return eqe;
+		rmb();
+		eqe->evt = 0;
+		num++;
+		queue_tail_inc(&eqo->q);
+	} while (true);
+
+	return num;
 }
 
-static int event_handle(struct be_adapter *adapter,
-			struct be_eq_obj *eq_obj,
-			bool rearm)
+static int event_handle(struct be_eq_obj *eqo)
 {
-	struct be_eq_entry *eqe;
-	u16 num = 0;
+	bool rearm = false;
+	int num = events_get(eqo);
 
-	while ((eqe = event_get(eq_obj)) != NULL) {
-		eqe->evt = 0;
-		num++;
-	}
-
-	/* Deal with any spurious interrupts that come
-	 * without events
-	 */
+	/* Deal with any spurious interrupts that come without events */
 	if (!num)
 		rearm = true;
 
-	be_eq_notify(adapter, eq_obj->q.id, rearm, true, num);
+	be_eq_notify(eqo->adapter, eqo->q.id, rearm, true, num);
 	if (num)
-		napi_schedule(&eq_obj->napi);
+		napi_schedule(&eqo->napi);
 
 	return num;
 }
 
-/* Just read and notify events without processing them.
- * Used at the time of destroying event queues */
-static void be_eq_clean(struct be_adapter *adapter,
-			struct be_eq_obj *eq_obj)
+/* Leaves the EQ is disarmed state */
+static void be_eq_clean(struct be_eq_obj *eqo)
 {
-	struct be_eq_entry *eqe;
-	u16 num = 0;
+	int num = events_get(eqo);
 
-	while ((eqe = event_get(eq_obj)) != NULL) {
-		eqe->evt = 0;
-		num++;
-	}
-
-	if (num)
-		be_eq_notify(adapter, eq_obj->q.id, false, true, num);
+	be_eq_notify(eqo->adapter, eqo->q.id, false, true, num);
 }
 
-static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
+static void be_rx_cq_clean(struct be_rx_obj *rxo)
 {
 	struct be_rx_page_info *page_info;
 	struct be_queue_info *rxq = &rxo->q;
@@ -1561,14 +1548,14 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
 
 	/* First cleanup pending rx completions */
 	while ((rxcp = be_rx_compl_get(rxo)) != NULL) {
-		be_rx_compl_discard(adapter, rxo, rxcp);
-		be_cq_notify(adapter, rx_cq->id, false, 1);
+		be_rx_compl_discard(rxo, rxcp);
+		be_cq_notify(rxo->adapter, rx_cq->id, false, 1);
 	}
 
 	/* Then free posted rx buffer that were not used */
 	tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
 	for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
-		page_info = get_rx_page_info(adapter, rxo, tail);
+		page_info = get_rx_page_info(rxo, tail);
 		put_page(page_info->page);
 		memset(page_info, 0, sizeof(*page_info));
 	}
@@ -1624,6 +1611,47 @@ static void be_tx_compl_clean(struct be_adapter *adapter,
 	}
 }
 
+static void be_evt_queues_destroy(struct be_adapter *adapter)
+{
+	struct be_eq_obj *eqo;
+	int i;
+
+	for_all_evt_queues(adapter, eqo, i) {
+		be_eq_clean(eqo);
+		if (eqo->q.created)
+			be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
+		be_queue_free(adapter, &eqo->q);
+	}
+}
+
+static int be_evt_queues_create(struct be_adapter *adapter)
+{
+	struct be_queue_info *eq;
+	struct be_eq_obj *eqo;
+	int i, rc;
+
+	adapter->num_evt_qs = num_irqs(adapter);
+
+	for_all_evt_queues(adapter, eqo, i) {
+		eqo->adapter = adapter;
+		eqo->tx_budget = BE_TX_BUDGET;
+		eqo->idx = i;
+		eqo->max_eqd = BE_MAX_EQD;
+		eqo->enable_aic = true;
+
+		eq = &eqo->q;
+		rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
+					sizeof(struct be_eq_entry));
+		if (rc)
+			return rc;
+
+		rc = be_cmd_eq_create(adapter, eq, eqo->cur_eqd);
+		if (rc)
+			return rc;
+	}
+	return rc;
+}
+
 static void be_mcc_queues_destroy(struct be_adapter *adapter)
 {
 	struct be_queue_info *q;
@@ -1644,22 +1672,19 @@ static int be_mcc_queues_create(struct be_adapter *adapter)
 {
 	struct be_queue_info *q, *cq;
 
-	/* Alloc MCC compl queue */
 	cq = &adapter->mcc_obj.cq;
 	if (be_queue_alloc(adapter, cq, MCC_CQ_LEN,
 			sizeof(struct be_mcc_compl)))
 		goto err;
 
-	/* Ask BE to create MCC compl queue; share TX's eq */
-	if (be_cmd_cq_create(adapter, cq, &adapter->tx_eq.q, false, true, 0))
+	/* Use the default EQ for MCC completions */
+	if (be_cmd_cq_create(adapter, cq, &mcc_eqo(adapter)->q, true, 0))
 		goto mcc_cq_free;
 
-	/* Alloc MCC queue */
 	q = &adapter->mcc_obj.q;
 	if (be_queue_alloc(adapter, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
 		goto mcc_cq_destroy;
 
-	/* Ask BE to create MCC queue */
 	if (be_cmd_mccq_create(adapter, q, cq))
 		goto mcc_q_free;
 
@@ -1692,14 +1717,6 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
 			be_cmd_q_destroy(adapter, q, QTYPE_CQ);
 		be_queue_free(adapter, q);
 	}
-
-	/* Clear any residual events */
-	be_eq_clean(adapter, &adapter->tx_eq);
-
-	q = &adapter->tx_eq.q;
-	if (q->created)
-		be_cmd_q_destroy(adapter, q, QTYPE_EQ);
-	be_queue_free(adapter, q);
 }
 
 static int be_num_txqs_want(struct be_adapter *adapter)
@@ -1712,10 +1729,10 @@ static int be_num_txqs_want(struct be_adapter *adapter)
 		return MAX_TX_QS;
 }
 
-/* One TX event queue is shared by all TX compl qs */
-static int be_tx_queues_create(struct be_adapter *adapter)
+static int be_tx_cqs_create(struct be_adapter *adapter)
 {
-	struct be_queue_info *eq, *q, *cq;
+	struct be_queue_info *cq, *eq;
+	int status;
 	struct be_tx_obj *txo;
 	u8 i;
 
@@ -1727,192 +1744,109 @@ static int be_tx_queues_create(struct be_adapter *adapter)
 		rtnl_unlock();
 	}
 
-	adapter->tx_eq.max_eqd = 0;
-	adapter->tx_eq.min_eqd = 0;
-	adapter->tx_eq.cur_eqd = 96;
-	adapter->tx_eq.enable_aic = false;
+	for_all_tx_queues(adapter, txo, i) {
+		cq = &txo->cq;
+		status = be_queue_alloc(adapter, cq, TX_CQ_LEN,
+					sizeof(struct be_eth_tx_compl));
+		if (status)
+			return status;
 
-	eq = &adapter->tx_eq.q;
-	if (be_queue_alloc(adapter, eq, EVNT_Q_LEN,
-		sizeof(struct be_eq_entry)))
-		return -1;
+		/* If num_evt_qs is less than num_tx_qs, then more than
+		 * one txq share an eq
+		 */
+		eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
+		status = be_cmd_cq_create(adapter, cq, eq, false, 3);
+		if (status)
+			return status;
+	}
+	return 0;
+}
 
-	if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
-		goto err;
-	adapter->tx_eq.eq_idx = adapter->eq_next_idx++;
+static int be_tx_qs_create(struct be_adapter *adapter)
+{
+	struct be_tx_obj *txo;
+	int i, status;
 
 	for_all_tx_queues(adapter, txo, i) {
-		cq = &txo->cq;
-		if (be_queue_alloc(adapter, cq, TX_CQ_LEN,
-			sizeof(struct be_eth_tx_compl)))
-			goto err;
-
-		if (be_cmd_cq_create(adapter, cq, eq, false, false, 3))
-			goto err;
+		status = be_queue_alloc(adapter, &txo->q, TX_Q_LEN,
+					sizeof(struct be_eth_wrb));
+		if (status)
+			return status;
 
-		q = &txo->q;
-		if (be_queue_alloc(adapter, q, TX_Q_LEN,
-			sizeof(struct be_eth_wrb)))
-			goto err;
+		status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
+		if (status)
+			return status;
 	}
-	return 0;
 
-err:
-	be_tx_queues_destroy(adapter);
-	return -1;
+	return 0;
 }
 
-static void be_rx_queues_destroy(struct be_adapter *adapter)
+static void be_rx_cqs_destroy(struct be_adapter *adapter)
 {
 	struct be_queue_info *q;
 	struct be_rx_obj *rxo;
 	int i;
 
 	for_all_rx_queues(adapter, rxo, i) {
-		be_queue_free(adapter, &rxo->q);
-
 		q = &rxo->cq;
 		if (q->created)
 			be_cmd_q_destroy(adapter, q, QTYPE_CQ);
 		be_queue_free(adapter, q);
-
-		q = &rxo->rx_eq.q;
-		if (q->created)
-			be_cmd_q_destroy(adapter, q, QTYPE_EQ);
-		be_queue_free(adapter, q);
-	}
-}
-
-static u32 be_num_rxqs_want(struct be_adapter *adapter)
-{
-	if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
-	     !sriov_enabled(adapter) && be_physfn(adapter)) {
-		return 1 + MAX_RSS_QS; /* one default non-RSS queue */
-	} else {
-		dev_warn(&adapter->pdev->dev,
-			"No support for multiple RX queues\n");
-		return 1;
 	}
 }
 
-static int be_rx_queues_create(struct be_adapter *adapter)
+static int be_rx_cqs_create(struct be_adapter *adapter)
 {
-	struct be_queue_info *eq, *q, *cq;
+	struct be_queue_info *eq, *cq;
 	struct be_rx_obj *rxo;
 	int rc, i;
 
-	adapter->num_rx_qs = min(be_num_rxqs_want(adapter),
-				msix_enabled(adapter) ?
-					adapter->num_msix_vec - 1 : 1);
-	if (adapter->num_rx_qs != MAX_RX_QS)
-		dev_warn(&adapter->pdev->dev,
-			"Can create only %d RX queues", adapter->num_rx_qs);
+	/* We'll create as many RSS rings as there are irqs.
+	 * But when there's only one irq there's no use creating RSS rings
+	 */
+	adapter->num_rx_qs = (num_irqs(adapter) > 1) ?
+				num_irqs(adapter) + 1 : 1;
 
 	adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
 	for_all_rx_queues(adapter, rxo, i) {
 		rxo->adapter = adapter;
-		rxo->rx_eq.max_eqd = BE_MAX_EQD;
-		rxo->rx_eq.enable_aic = true;
-
-		/* EQ */
-		eq = &rxo->rx_eq.q;
-		rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN,
-					sizeof(struct be_eq_entry));
-		if (rc)
-			goto err;
-
-		rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd);
-		if (rc)
-			goto err;
-
-		rxo->rx_eq.eq_idx = adapter->eq_next_idx++;
-
-		/* CQ */
 		cq = &rxo->cq;
 		rc = be_queue_alloc(adapter, cq, RX_CQ_LEN,
 				sizeof(struct be_eth_rx_compl));
 		if (rc)
-			goto err;
-
-		rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
-		if (rc)
-			goto err;
+			return rc;
 
-		/* Rx Q - will be created in be_open() */
-		q = &rxo->q;
-		rc = be_queue_alloc(adapter, q, RX_Q_LEN,
-				sizeof(struct be_eth_rx_d));
+		eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
+		rc = be_cmd_cq_create(adapter, cq, eq, false, 3);
 		if (rc)
-			goto err;
-
+			return rc;
 	}
 
-	return 0;
-err:
-	be_rx_queues_destroy(adapter);
-	return -1;
-}
+	if (adapter->num_rx_qs != MAX_RX_QS)
+		dev_info(&adapter->pdev->dev,
+			"Created only %d receive queues", adapter->num_rx_qs);
 
-static bool event_peek(struct be_eq_obj *eq_obj)
-{
-	struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
-	if (!eqe->evt)
-		return false;
-	else
-		return true;
+	return 0;
 }
 
 static irqreturn_t be_intx(int irq, void *dev)
 {
 	struct be_adapter *adapter = dev;
-	struct be_rx_obj *rxo;
-	int isr, i, tx = 0 , rx = 0;
-
-	if (lancer_chip(adapter)) {
-		if (event_peek(&adapter->tx_eq))
-			tx = event_handle(adapter, &adapter->tx_eq, false);
-		for_all_rx_queues(adapter, rxo, i) {
-			if (event_peek(&rxo->rx_eq))
-				rx |= event_handle(adapter, &rxo->rx_eq, true);
-		}
-
-		if (!(tx || rx))
-			return IRQ_NONE;
-
-	} else {
-		isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
-			(adapter->tx_eq.q.id / 8) * CEV_ISR_SIZE);
-		if (!isr)
-			return IRQ_NONE;
-
-		if ((1 << adapter->tx_eq.eq_idx & isr))
-			event_handle(adapter, &adapter->tx_eq, false);
-
-		for_all_rx_queues(adapter, rxo, i) {
-			if ((1 << rxo->rx_eq.eq_idx & isr))
-				event_handle(adapter, &rxo->rx_eq, true);
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t be_msix_rx(int irq, void *dev)
-{
-	struct be_rx_obj *rxo = dev;
-	struct be_adapter *adapter = rxo->adapter;
+	int num_evts;
 
-	event_handle(adapter, &rxo->rx_eq, true);
-
-	return IRQ_HANDLED;
+	/* With INTx only one EQ is used */
+	num_evts = event_handle(&adapter->eq_obj[0]);
+	if (num_evts)
+		return IRQ_HANDLED;
+	else
+		return IRQ_NONE;
 }
 
-static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
+static irqreturn_t be_msix(int irq, void *dev)
 {
-	struct be_adapter *adapter = dev;
-
-	event_handle(adapter, &adapter->tx_eq, false);
+	struct be_eq_obj *eqo = dev;
 
+	event_handle(eqo);
 	return IRQ_HANDLED;
 }
 
@@ -1921,16 +1855,14 @@ static inline bool do_gro(struct be_rx_compl_info *rxcp)
 	return (rxcp->tcpf && !rxcp->err) ? true : false;
 }
 
-static int be_poll_rx(struct napi_struct *napi, int budget)
+static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi,
+			int budget)
 {
-	struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi);
-	struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq);
 	struct be_adapter *adapter = rxo->adapter;
 	struct be_queue_info *rx_cq = &rxo->cq;
 	struct be_rx_compl_info *rxcp;
 	u32 work_done;
 
-	rx_stats(rxo)->rx_polls++;
 	for (work_done = 0; work_done < budget; work_done++) {
 		rxcp = be_rx_compl_get(rxo);
 		if (!rxcp)
@@ -1942,7 +1874,7 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
 
 		/* Discard compl with partial DMA Lancer B0 */
 		if (unlikely(!rxcp->pkt_size)) {
-			be_rx_compl_discard(adapter, rxo, rxcp);
+			be_rx_compl_discard(rxo, rxcp);
 			goto loop_continue;
 		}
 
@@ -1951,94 +1883,96 @@ static int be_poll_rx(struct napi_struct *napi, int budget)
 		 */
 		if (unlikely(rxcp->port != adapter->port_num &&
 				!lancer_chip(adapter))) {
-			be_rx_compl_discard(adapter, rxo, rxcp);
+			be_rx_compl_discard(rxo, rxcp);
 			goto loop_continue;
 		}
 
 		if (do_gro(rxcp))
-			be_rx_compl_process_gro(adapter, rxo, rxcp);
+			be_rx_compl_process_gro(rxo, napi, rxcp);
 		else
-			be_rx_compl_process(adapter, rxo, rxcp);
+			be_rx_compl_process(rxo, rxcp);
 loop_continue:
 		be_rx_stats_update(rxo, rxcp);
 	}
 
-	be_cq_notify(adapter, rx_cq->id, false, work_done);
+	if (work_done) {
+		be_cq_notify(adapter, rx_cq->id, true, work_done);
 
-	/* Refill the queue */
-	if (work_done && atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
-		be_post_rx_frags(rxo, GFP_ATOMIC);
-
-	/* All consumed */
-	if (work_done < budget) {
-		napi_complete(napi);
-		/* Arm CQ */
-		be_cq_notify(adapter, rx_cq->id, true, 0);
+		if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM)
+			be_post_rx_frags(rxo, GFP_ATOMIC);
 	}
+
 	return work_done;
 }
 
-/* As TX and MCC share the same EQ check for both TX and MCC completions.
- * For TX/MCC we don't honour budget; consume everything
- */
-static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
+static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
+			  int budget, int idx)
 {
-	struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
-	struct be_adapter *adapter =
-		container_of(tx_eq, struct be_adapter, tx_eq);
-	struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
-	struct be_tx_obj *txo;
 	struct be_eth_tx_compl *txcp;
-	int tx_compl, mcc_compl, status = 0;
-	u8 i;
-	u16 num_wrbs;
+	int num_wrbs = 0, work_done;
 
-	for_all_tx_queues(adapter, txo, i) {
-		tx_compl = 0;
-		num_wrbs = 0;
-		while ((txcp = be_tx_compl_get(&txo->cq))) {
-			num_wrbs += be_tx_compl_process(adapter, txo,
+	for (work_done = 0; work_done < budget; work_done++) {
+		txcp = be_tx_compl_get(&txo->cq);
+		if (!txcp)
+			break;
+		num_wrbs += be_tx_compl_process(adapter, txo,
 				AMAP_GET_BITS(struct amap_eth_tx_compl,
 					wrb_index, txcp));
-			tx_compl++;
-		}
-		if (tx_compl) {
-			be_cq_notify(adapter, txo->cq.id, true, tx_compl);
+	}
 
-			atomic_sub(num_wrbs, &txo->q.used);
+	if (work_done) {
+		be_cq_notify(adapter, txo->cq.id, true, work_done);
+		atomic_sub(num_wrbs, &txo->q.used);
 
-			/* As Tx wrbs have been freed up, wake up netdev queue
-			 * if it was stopped due to lack of tx wrbs.  */
-			if (__netif_subqueue_stopped(adapter->netdev, i) &&
-				atomic_read(&txo->q.used) < txo->q.len / 2) {
-				netif_wake_subqueue(adapter->netdev, i);
-			}
-
-			u64_stats_update_begin(&tx_stats(txo)->sync_compl);
-			tx_stats(txo)->tx_compl += tx_compl;
-			u64_stats_update_end(&tx_stats(txo)->sync_compl);
+		/* As Tx wrbs have been freed up, wake up netdev queue
+		 * if it was stopped due to lack of tx wrbs.  */
+		if (__netif_subqueue_stopped(adapter->netdev, idx) &&
+			atomic_read(&txo->q.used) < txo->q.len / 2) {
+			netif_wake_subqueue(adapter->netdev, idx);
 		}
+
+		u64_stats_update_begin(&tx_stats(txo)->sync_compl);
+		tx_stats(txo)->tx_compl += work_done;
+		u64_stats_update_end(&tx_stats(txo)->sync_compl);
 	}
+	return (work_done < budget); /* Done */
+}
 
-	mcc_compl = be_process_mcc(adapter, &status);
+int be_poll(struct napi_struct *napi, int budget)
+{
+	struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
+	struct be_adapter *adapter = eqo->adapter;
+	int max_work = 0, work, i;
+	bool tx_done;
 
-	if (mcc_compl) {
-		be_cq_notify(adapter, mcc_obj->cq.id, true, mcc_compl);
+	/* Process all TXQs serviced by this EQ */
+	for (i = eqo->idx; i < adapter->num_tx_qs; i += adapter->num_evt_qs) {
+		tx_done = be_process_tx(adapter, &adapter->tx_obj[i],
+					eqo->tx_budget, i);
+		if (!tx_done)
+			max_work = budget;
 	}
 
-	napi_complete(napi);
+	/* This loop will iterate twice for EQ0 in which
+	 * completions of the last RXQ (default one) are also processed
+	 * For other EQs the loop iterates only once
+	 */
+	for (i = eqo->idx; i < adapter->num_rx_qs; i += adapter->num_evt_qs) {
+		work = be_process_rx(&adapter->rx_obj[i], napi, budget);
+		max_work = max(work, max_work);
+	}
 
-	/* Arm CQ again to regenerate EQEs for Lancer in INTx mode */
-	if (lancer_chip(adapter) && !msix_enabled(adapter)) {
-		for_all_tx_queues(adapter, txo, i)
-			be_cq_notify(adapter, txo->cq.id, true, 0);
+	if (is_mcc_eqo(eqo))
+		be_process_mcc(adapter);
 
-		be_cq_notify(adapter, mcc_obj->cq.id, true, 0);
+	if (max_work < budget) {
+		napi_complete(napi);
+		be_eq_notify(adapter, eqo->q.id, true, false, 0);
+	} else {
+		/* As we'll continue in polling mode, count and clear events */
+		be_eq_notify(adapter, eqo->q.id, false, false, events_get(eqo));
 	}
-
-	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
-	adapter->drv_stats.tx_events++;
-	return 1;
+	return max_work;
 }
 
 void be_detect_dump_ue(struct be_adapter *adapter)
@@ -2113,12 +2047,24 @@ static void be_msix_disable(struct be_adapter *adapter)
 	}
 }
 
+static uint be_num_rss_want(struct be_adapter *adapter)
+{
+	if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+	     adapter->num_vfs == 0 && be_physfn(adapter) &&
+	     !be_is_mc(adapter))
+		return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
+	else
+		return 0;
+}
+
 static void be_msix_enable(struct be_adapter *adapter)
 {
-#define BE_MIN_MSIX_VECTORS	(1 + 1) /* Rx + Tx */
+#define BE_MIN_MSIX_VECTORS		1
 	int i, status, num_vec;
 
-	num_vec = be_num_rxqs_want(adapter) + 1;
+	/* If RSS queues are not used, need a vec for default RX Q */
+	num_vec = min(be_num_rss_want(adapter), num_online_cpus());
+	num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
 
 	for (i = 0; i < num_vec; i++)
 		adapter->msix_entries[i].entry = i;
@@ -2186,60 +2132,31 @@ static void be_sriov_disable(struct be_adapter *adapter)
 }
 
 static inline int be_msix_vec_get(struct be_adapter *adapter,
-					struct be_eq_obj *eq_obj)
+				struct be_eq_obj *eqo)
 {
-	return adapter->msix_entries[eq_obj->eq_idx].vector;
-}
-
-static int be_request_irq(struct be_adapter *adapter,
-		struct be_eq_obj *eq_obj,
-		void *handler, char *desc, void *context)
-{
-	struct net_device *netdev = adapter->netdev;
-	int vec;
-
-	sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
-	vec = be_msix_vec_get(adapter, eq_obj);
-	return request_irq(vec, handler, 0, eq_obj->desc, context);
-}
-
-static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj,
-			void *context)
-{
-	int vec = be_msix_vec_get(adapter, eq_obj);
-	free_irq(vec, context);
+	return adapter->msix_entries[eqo->idx].vector;
 }
 
 static int be_msix_register(struct be_adapter *adapter)
 {
-	struct be_rx_obj *rxo;
-	int status, i;
-	char qname[10];
-
-	status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx",
-				adapter);
-	if (status)
-		goto err;
+	struct net_device *netdev = adapter->netdev;
+	struct be_eq_obj *eqo;
+	int status, i, vec;
 
-	for_all_rx_queues(adapter, rxo, i) {
-		sprintf(qname, "rxq%d", i);
-		status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx,
-				qname, rxo);
+	for_all_evt_queues(adapter, eqo, i) {
+		sprintf(eqo->desc, "%s-q%d", netdev->name, i);
+		vec = be_msix_vec_get(adapter, eqo);
+		status = request_irq(vec, be_msix, 0, eqo->desc, eqo);
 		if (status)
 			goto err_msix;
 	}
 
 	return 0;
-
 err_msix:
-	be_free_irq(adapter, &adapter->tx_eq, adapter);
-
-	for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--)
-		be_free_irq(adapter, &rxo->rx_eq, rxo);
-
-err:
-	dev_warn(&adapter->pdev->dev,
-		"MSIX Request IRQ failed - err %d\n", status);
+	for (i--, eqo = &adapter->eq_obj[i]; i >= 0; i--, eqo--)
+		free_irq(be_msix_vec_get(adapter, eqo), eqo);
+	dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n",
+		status);
 	be_msix_disable(adapter);
 	return status;
 }
@@ -2275,7 +2192,7 @@ done:
 static void be_irq_unregister(struct be_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct be_rx_obj *rxo;
+	struct be_eq_obj *eqo;
 	int i;
 
 	if (!adapter->isr_registered)
@@ -2288,16 +2205,14 @@ static void be_irq_unregister(struct be_adapter *adapter)
 	}
 
 	/* MSIx */
-	be_free_irq(adapter, &adapter->tx_eq, adapter);
-
-	for_all_rx_queues(adapter, rxo, i)
-		be_free_irq(adapter, &rxo->rx_eq, rxo);
+	for_all_evt_queues(adapter, eqo, i)
+		free_irq(be_msix_vec_get(adapter, eqo), eqo);
 
 done:
 	adapter->isr_registered = false;
 }
 
-static void be_rx_queues_clear(struct be_adapter *adapter)
+static void be_rx_qs_destroy(struct be_adapter *adapter)
 {
 	struct be_queue_info *q;
 	struct be_rx_obj *rxo;
@@ -2312,53 +2227,33 @@ static void be_rx_queues_clear(struct be_adapter *adapter)
 			 * arrive
 			 */
 			mdelay(1);
-			be_rx_q_clean(adapter, rxo);
+			be_rx_cq_clean(rxo);
 		}
-
-		/* Clear any residual events */
-		q = &rxo->rx_eq.q;
-		if (q->created)
-			be_eq_clean(adapter, &rxo->rx_eq);
+		be_queue_free(adapter, q);
 	}
 }
 
 static int be_close(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_rx_obj *rxo;
 	struct be_tx_obj *txo;
-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
-	int vec, i;
+	struct be_eq_obj *eqo;
+	int i;
 
 	be_async_mcc_disable(adapter);
 
 	if (!lancer_chip(adapter))
 		be_intr_set(adapter, false);
 
-	for_all_rx_queues(adapter, rxo, i)
-		napi_disable(&rxo->rx_eq.napi);
-
-	napi_disable(&tx_eq->napi);
-
-	if (lancer_chip(adapter)) {
-		be_cq_notify(adapter, adapter->mcc_obj.cq.id, false, 0);
-		for_all_rx_queues(adapter, rxo, i)
-			 be_cq_notify(adapter, rxo->cq.id, false, 0);
-		for_all_tx_queues(adapter, txo, i)
-			 be_cq_notify(adapter, txo->cq.id, false, 0);
+	for_all_evt_queues(adapter, eqo, i) {
+		napi_disable(&eqo->napi);
+		if (msix_enabled(adapter))
+			synchronize_irq(be_msix_vec_get(adapter, eqo));
+		else
+			synchronize_irq(netdev->irq);
+		be_eq_clean(eqo);
 	}
 
-	if (msix_enabled(adapter)) {
-		vec = be_msix_vec_get(adapter, tx_eq);
-		synchronize_irq(vec);
-
-		for_all_rx_queues(adapter, rxo, i) {
-			vec = be_msix_vec_get(adapter, &rxo->rx_eq);
-			synchronize_irq(vec);
-		}
-	} else {
-		synchronize_irq(netdev->irq);
-	}
 	be_irq_unregister(adapter);
 
 	/* Wait for all pending tx completions to arrive so that
@@ -2367,21 +2262,34 @@ static int be_close(struct net_device *netdev)
 	for_all_tx_queues(adapter, txo, i)
 		be_tx_compl_clean(adapter, txo);
 
-	be_rx_queues_clear(adapter);
+	be_rx_qs_destroy(adapter);
 	return 0;
 }
 
-static int be_rx_queues_setup(struct be_adapter *adapter)
+static int be_rx_qs_create(struct be_adapter *adapter)
 {
 	struct be_rx_obj *rxo;
 	int rc, i, j;
 	u8 rsstable[128];
 
 	for_all_rx_queues(adapter, rxo, i) {
+		rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN,
+				    sizeof(struct be_eth_rx_d));
+		if (rc)
+			return rc;
+	}
+
+	/* The FW would like the default RXQ to be created first */
+	rxo = default_rxo(adapter);
+	rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id, rx_frag_size,
+			       adapter->if_handle, false, &rxo->rss_id);
+	if (rc)
+		return rc;
+
+	for_all_rss_queues(adapter, rxo, i) {
 		rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id,
-			rx_frag_size, BE_MAX_JUMBO_FRAME_SIZE,
-			adapter->if_handle,
-			(i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id);
+				       rx_frag_size, adapter->if_handle,
+				       true, &rxo->rss_id);
 		if (rc)
 			return rc;
 	}
@@ -2395,48 +2303,47 @@ static int be_rx_queues_setup(struct be_adapter *adapter)
 			}
 		}
 		rc = be_cmd_rss_config(adapter, rsstable, 128);
-
 		if (rc)
 			return rc;
 	}
 
 	/* First time posting */
-	for_all_rx_queues(adapter, rxo, i) {
+	for_all_rx_queues(adapter, rxo, i)
 		be_post_rx_frags(rxo, GFP_KERNEL);
-		napi_enable(&rxo->rx_eq.napi);
-	}
 	return 0;
 }
 
 static int be_open(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
+	struct be_eq_obj *eqo;
 	struct be_rx_obj *rxo;
+	struct be_tx_obj *txo;
 	u8 link_status;
 	int status, i;
 
-	status = be_rx_queues_setup(adapter);
+	status = be_rx_qs_create(adapter);
 	if (status)
 		goto err;
 
-	napi_enable(&tx_eq->napi);
-
 	be_irq_register(adapter);
 
 	if (!lancer_chip(adapter))
 		be_intr_set(adapter, true);
 
-	/* The evt queues are created in unarmed state; arm them */
-	for_all_rx_queues(adapter, rxo, i) {
-		be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0);
+	for_all_rx_queues(adapter, rxo, i)
 		be_cq_notify(adapter, rxo->cq.id, true, 0);
-	}
-	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
 
-	/* Now that interrupts are on we can process async mcc */
+	for_all_tx_queues(adapter, txo, i)
+		be_cq_notify(adapter, txo->cq.id, true, 0);
+
 	be_async_mcc_enable(adapter);
 
+	for_all_evt_queues(adapter, eqo, i) {
+		napi_enable(&eqo->napi);
+		be_eq_notify(adapter, eqo->q.id, true, false, 0);
+	}
+
 	status = be_cmd_link_status_query(adapter, NULL, NULL,
 					  &link_status, 0);
 	if (!status)
@@ -2546,11 +2453,14 @@ static int be_clear(struct be_adapter *adapter)
 	be_cmd_if_destroy(adapter, adapter->if_handle,  0);
 
 	be_mcc_queues_destroy(adapter);
-	be_rx_queues_destroy(adapter);
+	be_rx_cqs_destroy(adapter);
 	be_tx_queues_destroy(adapter);
+	be_evt_queues_destroy(adapter);
 
 	/* tell fw we're done with firing cmds */
 	be_cmd_fw_clean(adapter);
+
+	be_msix_disable(adapter);
 	return 0;
 }
 
@@ -2609,19 +2519,28 @@ static void be_setup_init(struct be_adapter *adapter)
 	adapter->eq_next_idx = 0;
 }
 
-static int be_configure_mac_from_list(struct be_adapter *adapter, u8 *mac)
+static int be_add_mac_from_list(struct be_adapter *adapter, u8 *mac)
 {
 	u32 pmac_id;
-	int status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id);
-	if (status != 0)
-		goto do_none;
-	status = be_cmd_mac_addr_query(adapter, mac,
-			MAC_ADDRESS_TYPE_NETWORK,
-			false, adapter->if_handle, pmac_id);
+	int status;
+	bool pmac_id_active;
+
+	status = be_cmd_get_mac_from_list(adapter, 0, &pmac_id_active,
+							&pmac_id, mac);
 	if (status != 0)
 		goto do_none;
-	status = be_cmd_pmac_add(adapter, mac, adapter->if_handle,
-			&adapter->pmac_id, 0);
+
+	if (pmac_id_active) {
+		status = be_cmd_mac_addr_query(adapter, mac,
+				MAC_ADDRESS_TYPE_NETWORK,
+				false, adapter->if_handle, pmac_id);
+
+		if (!status)
+			adapter->pmac_id = pmac_id;
+	} else {
+		status = be_cmd_pmac_add(adapter, mac,
+				adapter->if_handle, &adapter->pmac_id, 0);
+	}
 do_none:
 	return status;
 }
@@ -2631,24 +2550,29 @@ static int be_setup(struct be_adapter *adapter)
 	struct net_device *netdev = adapter->netdev;
 	u32 cap_flags, en_flags;
 	u32 tx_fc, rx_fc;
-	int status, i;
+	int status;
 	u8 mac[ETH_ALEN];
-	struct be_tx_obj *txo;
 
 	be_setup_init(adapter);
 
 	be_cmd_req_native_mode(adapter);
 
-	status = be_tx_queues_create(adapter);
-	if (status != 0)
+	be_msix_enable(adapter);
+
+	status = be_evt_queues_create(adapter);
+	if (status)
 		goto err;
 
-	status = be_rx_queues_create(adapter);
-	if (status != 0)
+	status = be_tx_cqs_create(adapter);
+	if (status)
+		goto err;
+
+	status = be_rx_cqs_create(adapter);
+	if (status)
 		goto err;
 
 	status = be_mcc_queues_create(adapter);
-	if (status != 0)
+	if (status)
 		goto err;
 
 	memset(mac, 0, ETH_ALEN);
@@ -2674,19 +2598,13 @@ static int be_setup(struct be_adapter *adapter)
 	if (status != 0)
 		goto err;
 
-	 for_all_tx_queues(adapter, txo, i) {
-		status = be_cmd_txq_create(adapter, &txo->q, &txo->cq);
-		if (status)
-			goto err;
-	}
-
 	 /* The VF's permanent mac queried from card is incorrect.
 	  * For BEx: Query the mac configued by the PF using if_handle
 	  * For Lancer: Get and use mac_list to obtain mac address.
 	  */
 	if (!be_physfn(adapter)) {
 		if (lancer_chip(adapter))
-			status = be_configure_mac_from_list(adapter, mac);
+			status = be_add_mac_from_list(adapter, mac);
 		else
 			status = be_cmd_mac_addr_query(adapter, mac,
 					MAC_ADDRESS_TYPE_NETWORK, false,
@@ -2697,6 +2615,10 @@ static int be_setup(struct be_adapter *adapter)
 		}
 	}
 
+	status = be_tx_qs_create(adapter);
+	if (status)
+		goto err;
+
 	be_cmd_get_fw_ver(adapter, adapter->fw_ver, NULL);
 
 	status = be_vid_config(adapter, false, 0);
@@ -2736,12 +2658,13 @@ err:
 static void be_netpoll(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_rx_obj *rxo;
+	struct be_eq_obj *eqo;
 	int i;
 
-	event_handle(adapter, &adapter->tx_eq, false);
-	for_all_rx_queues(adapter, rxo, i)
-		event_handle(adapter, &rxo->rx_eq, true);
+	for_all_evt_queues(adapter, eqo, i)
+		event_handle(eqo);
+
+	return;
 }
 #endif
 
@@ -3102,7 +3025,7 @@ static const struct net_device_ops be_netdev_ops = {
 static void be_netdev_init(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_rx_obj *rxo;
+	struct be_eq_obj *eqo;
 	int i;
 
 	netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
@@ -3121,16 +3044,12 @@ static void be_netdev_init(struct net_device *netdev)
 
 	netif_set_gso_max_size(netdev, 65535);
 
-	BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
+	netdev->netdev_ops = &be_netdev_ops;
 
 	SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
 
-	for_all_rx_queues(adapter, rxo, i)
-		netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx,
-				BE_NAPI_WEIGHT);
-
-	netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
-		BE_NAPI_WEIGHT);
+	for_all_evt_queues(adapter, eqo, i)
+		netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
 }
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
@@ -3301,8 +3220,6 @@ static void __devexit be_remove(struct pci_dev *pdev)
 
 	be_sriov_disable(adapter);
 
-	be_msix_disable(adapter);
-
 	pci_set_drvdata(pdev, NULL);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -3469,6 +3386,7 @@ static void be_worker(struct work_struct *work)
 	struct be_adapter *adapter =
 		container_of(work, struct be_adapter, work.work);
 	struct be_rx_obj *rxo;
+	struct be_eq_obj *eqo;
 	int i;
 
 	if (lancer_chip(adapter))
@@ -3479,15 +3397,7 @@ static void be_worker(struct work_struct *work)
 	/* when interrupts are not yet enabled, just reap any pending
 	* mcc completions */
 	if (!netif_running(adapter->netdev)) {
-		int mcc_compl, status = 0;
-
-		mcc_compl = be_process_mcc(adapter, &status);
-
-		if (mcc_compl) {
-			struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
-			be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
-		}
-
+		be_process_mcc(adapter);
 		goto reschedule;
 	}
 
@@ -3500,14 +3410,15 @@ static void be_worker(struct work_struct *work)
 	}
 
 	for_all_rx_queues(adapter, rxo, i) {
-		be_rx_eqd_update(adapter, rxo);
-
 		if (rxo->rx_post_starved) {
 			rxo->rx_post_starved = false;
 			be_post_rx_frags(rxo, GFP_KERNEL);
 		}
 	}
 
+	for_all_evt_queues(adapter, eqo, i)
+		be_eqd_update(adapter, eqo);
+
 reschedule:
 	adapter->work_counter++;
 	schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
@@ -3593,6 +3504,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	if (status)
 		goto ctrl_clean;
 
+	/* The INTR bit may be set in the card when probed by a kdump kernel
+	 * after a crash.
+	 */
+	if (!lancer_chip(adapter))
+		be_intr_set(adapter, false);
+
 	status = be_stats_init(adapter);
 	if (status)
 		goto ctrl_clean;
@@ -3601,14 +3518,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	if (status)
 		goto stats_clean;
 
-	/* The INTR bit may be set in the card when probed by a kdump kernel
-	 * after a crash.
-	 */
-	if (!lancer_chip(adapter))
-		be_intr_set(adapter, false);
-
-	be_msix_enable(adapter);
-
 	INIT_DELAYED_WORK(&adapter->work, be_worker);
 	adapter->rx_fc = adapter->tx_fc = true;
 
@@ -3621,7 +3530,8 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	if (status != 0)
 		goto unsetup;
 
-	dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
+	dev_info(&pdev->dev, "%s: %s port %d\n", netdev->name, nic_name(pdev),
+		adapter->port_num);
 
 	schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
 	return 0;
@@ -3665,7 +3575,6 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
 	}
 	be_clear(adapter);
 
-	be_msix_disable(adapter);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -3687,7 +3596,6 @@ static int be_resume(struct pci_dev *pdev)
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 
-	be_msix_enable(adapter);
 	/* tell fw we're ready to fire cmds */
 	status = be_cmd_fw_init(adapter);
 	if (status)
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 60f0e78..a381678 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/net/ethoc.c
+ * linux/drivers/net/ethernet/ethoc.c
  *
  * Copyright (C) 2007-2008 Avionic Design Development GmbH
  * Copyright (C) 2008-2009 Avionic Design GmbH
@@ -776,10 +776,16 @@ static int ethoc_set_mac_address(struct net_device *dev, void *addr)
 	struct ethoc *priv = netdev_priv(dev);
 	u8 *mac = (u8 *)addr;
 
+	if (!is_valid_ether_addr(mac))
+		return -EADDRNOTAVAIL;
+
 	ethoc_write(priv, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
 				     (mac[4] <<  8) | (mac[5] <<  0));
 	ethoc_write(priv, MAC_ADDR1, (mac[0] <<  8) | (mac[1] <<  0));
 
+	memcpy(dev->dev_addr, mac, ETH_ALEN);
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
+
 	return 0;
 }
 
@@ -909,11 +915,11 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
 	unsigned int phy;
 	int num_bd;
 	int ret = 0;
+	bool random_mac = false;
 
 	/* allocate networking device */
 	netdev = alloc_etherdev(sizeof(struct ethoc));
 	if (!netdev) {
-		dev_err(&pdev->dev, "cannot allocate network device\n");
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -1050,10 +1056,19 @@ static int __devinit ethoc_probe(struct platform_device *pdev)
 
 	/* Check the MAC again for validity, if it still isn't choose and
 	 * program a random one. */
-	if (!is_valid_ether_addr(netdev->dev_addr))
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
 		random_ether_addr(netdev->dev_addr);
+		random_mac = true;
+	}
+
+	ret = ethoc_set_mac_address(netdev, netdev->dev_addr);
+	if (ret) {
+		dev_err(&netdev->dev, "failed to set MAC address\n");
+		goto error;
+	}
 
-	ethoc_set_mac_address(netdev, netdev->dev_addr);
+	if (random_mac)
+		netdev->addr_assign_type |= NET_ADDR_RANDOM;
 
 	/* register MII bus */
 	priv->mdio = mdiobus_alloc();
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index 47f85c3..16b0704 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -1289,7 +1289,7 @@ static int ftgmac100_probe(struct platform_device *pdev)
 	netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base);
 
 	if (!is_valid_ether_addr(netdev->dev_addr)) {
-		random_ether_addr(netdev->dev_addr);
+		eth_hw_addr_random(netdev);
 		netdev_info(netdev, "generated random MAC address %pM\n",
 			    netdev->dev_addr);
 	}
diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c
index bb336a0..829b109 100644
--- a/drivers/net/ethernet/faraday/ftmac100.c
+++ b/drivers/net/ethernet/faraday/ftmac100.c
@@ -1133,7 +1133,7 @@ static int ftmac100_probe(struct platform_device *pdev)
 	netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base);
 
 	if (!is_valid_ether_addr(netdev->dev_addr)) {
-		random_ether_addr(netdev->dev_addr);
+		eth_hw_addr_random(netdev);
 		netdev_info(netdev, "generated random MAC address %pM\n",
 			    netdev->dev_addr);
 	}
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
index c82d444..1637b98 100644
--- a/drivers/net/ethernet/fealnx.c
+++ b/drivers/net/ethernet/fealnx.c
@@ -1070,14 +1070,13 @@ static void allocate_rx_buffers(struct net_device *dev)
 	while (np->really_rx_count != RX_RING_SIZE) {
 		struct sk_buff *skb;
 
-		skb = dev_alloc_skb(np->rx_buf_sz);
+		skb = netdev_alloc_skb(dev, np->rx_buf_sz);
 		if (skb == NULL)
 			break;	/* Better luck next round. */
 
 		while (np->lack_rxbuf->skbuff)
 			np->lack_rxbuf = np->lack_rxbuf->next_desc_logical;
 
-		skb->dev = dev;	/* Mark as being used by this device. */
 		np->lack_rxbuf->skbuff = skb;
 		np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
@@ -1265,7 +1264,7 @@ static void init_ring(struct net_device *dev)
 
 	/* allocate skb for rx buffers */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+		struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz);
 
 		if (skb == NULL) {
 			np->lack_rxbuf = &np->rx_ring[i];
@@ -1274,7 +1273,6 @@ static void init_ring(struct net_device *dev)
 
 		++np->really_rx_count;
 		np->rx_ring[i].skbuff = skb;
-		skb->dev = dev;	/* Mark as being used by this device. */
 		np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->rx_ring[i].status = RXOWN;
@@ -1704,7 +1702,7 @@ static int netdev_rx(struct net_device *dev)
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(np->pci_dev,
 							    np->cur_rx->buffer,
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index e92ef1b..a12b3f5 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -711,7 +711,7 @@ fec_enet_rx(struct net_device *ndev)
 		 * include that when passing upstream as it messes up
 		 * bridging applications.
 		 */
-		skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
+		skb = netdev_alloc_skb(ndev, pkt_len - 4 + NET_IP_ALIGN);
 
 		if (unlikely(!skb)) {
 			printk("%s: Memory squeeze, dropping packet.\n",
@@ -1210,7 +1210,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
 
 	bdp = fep->rx_bd_base;
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
+		skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
 		if (!skb) {
 			fec_enet_free_buffers(ndev);
 			return -ENOMEM;
@@ -1739,21 +1739,6 @@ static struct platform_driver fec_driver = {
 	.remove	= __devexit_p(fec_drv_remove),
 };
 
-static int __init
-fec_enet_module_init(void)
-{
-	printk(KERN_INFO "FEC Ethernet Driver\n");
-
-	return platform_driver_register(&fec_driver);
-}
-
-static void __exit
-fec_enet_cleanup(void)
-{
-	platform_driver_unregister(&fec_driver);
-}
-
-module_exit(fec_enet_cleanup);
-module_init(fec_enet_module_init);
+module_platform_driver(fec_driver);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c
index 30745b5..7b34d8c 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
@@ -160,7 +160,7 @@ static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task
 	struct sk_buff *skb;
 
 	while (!bcom_queue_full(rxtsk)) {
-		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+		skb = netdev_alloc_skb(dev, FEC_RX_BUFFER_SIZE);
 		if (!skb)
 			return -EAGAIN;
 
@@ -416,7 +416,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
 
 		/* skbs are allocated on open, so now we allocate a new one,
 		 * and remove the old (with the packet) */
-		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+		skb = netdev_alloc_skb(dev, FEC_RX_BUFFER_SIZE);
 		if (!skb) {
 			/* Can't get a new one : reuse the same & drop pkt */
 			dev_notice(&dev->dev, "Low memory - dropped packet.\n");
diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.h b/drivers/net/ethernet/freescale/fec_mpc52xx.h
index 41d2dff..10afa54 100644
--- a/drivers/net/ethernet/freescale/fec_mpc52xx.h
+++ b/drivers/net/ethernet/freescale/fec_mpc52xx.h
@@ -1,5 +1,5 @@
 /*
- * drivers/drivers/net/fec_mpc52xx/fec.h
+ * drivers/net/ethernet/freescale/fec_mpc52xx.h
  *
  * Driver for the MPC5200 Fast Ethernet Controller
  *
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
index 910a8e1..999638a 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
@@ -154,7 +154,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 
 			if (pkt_len <= fpi->rx_copybreak) {
 				/* +2 to make IP header L1 cache aligned */
-				skbn = dev_alloc_skb(pkt_len + 2);
+				skbn = netdev_alloc_skb(dev, pkt_len + 2);
 				if (skbn != NULL) {
 					skb_reserve(skbn, 2);	/* align IP header */
 					skb_copy_from_linear_data(skb,
@@ -165,7 +165,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 					skbn = skbt;
 				}
 			} else {
-				skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+				skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
 
 				if (skbn)
 					skb_align(skbn, ENET_RX_ALIGN);
@@ -286,7 +286,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 
 			if (pkt_len <= fpi->rx_copybreak) {
 				/* +2 to make IP header L1 cache aligned */
-				skbn = dev_alloc_skb(pkt_len + 2);
+				skbn = netdev_alloc_skb(dev, pkt_len + 2);
 				if (skbn != NULL) {
 					skb_reserve(skbn, 2);	/* align IP header */
 					skb_copy_from_linear_data(skb,
@@ -297,7 +297,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 					skbn = skbt;
 				}
 			} else {
-				skbn = dev_alloc_skb(ENET_RX_FRSIZE);
+				skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
 
 				if (skbn)
 					skb_align(skbn, ENET_RX_ALIGN);
@@ -504,7 +504,7 @@ void fs_init_bds(struct net_device *dev)
 	 * Initialize the receive buffer descriptors.
 	 */
 	for (i = 0, bdp = fep->rx_bd_base; i < fep->rx_ring; i++, bdp++) {
-		skb = dev_alloc_skb(ENET_RX_FRSIZE);
+		skb = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
 		if (skb == NULL) {
 			dev_warn(fep->dev,
 				 "Memory squeeze, unable to allocate skb\n");
@@ -592,7 +592,7 @@ static struct sk_buff *tx_skb_align_workaround(struct net_device *dev,
 	struct fs_enet_private *fep = netdev_priv(dev);
 
 	/* Alloc new skb */
-	new_skb = dev_alloc_skb(skb->len + 4);
+	new_skb = netdev_alloc_skb(dev, skb->len + 4);
 	if (!new_skb) {
 		if (net_ratelimit()) {
 			dev_warn(fep->dev,
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 39d160d..adb0ae4 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/gianfar.c
+ * drivers/net/ethernet/freescale/gianfar.c
  *
  * Gianfar Ethernet Driver
  * This driver is designed for the non-CPM ethernet controllers
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 40c33a7..4fe0f34 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/gianfar.h
+ * drivers/net/ethernet/freescale/gianfar.h
  *
  * Gianfar Ethernet Driver
  * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 5a3b2e5..5a78d55 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -1,5 +1,5 @@
 /*
- *  drivers/net/gianfar_ethtool.c
+ *  drivers/net/ethernet/freescale/gianfar_ethtool.c
  *
  *  Gianfar Ethernet Driver
  *  Ethtool support for Gianfar Enet
diff --git a/drivers/net/ethernet/freescale/gianfar_sysfs.c b/drivers/net/ethernet/freescale/gianfar_sysfs.c
index 64f4094..cd14a4d 100644
--- a/drivers/net/ethernet/freescale/gianfar_sysfs.c
+++ b/drivers/net/ethernet/freescale/gianfar_sysfs.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/gianfar_sysfs.c
+ * drivers/net/ethernet/freescale/gianfar_sysfs.c
  *
  * Gianfar Ethernet Driver
  * This driver is designed for the non-CPM ethernet controllers
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index ba2dc08..ec09054 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -214,8 +214,9 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
 
 	skb = __skb_dequeue(&ugeth->rx_recycle);
 	if (!skb)
-		skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length +
-				    UCC_GETH_RX_DATA_BUF_ALIGNMENT);
+		skb = netdev_alloc_skb(ugeth->ndev,
+				      ugeth->ug_info->uf_info.max_rx_buf_length +
+				      UCC_GETH_RX_DATA_BUF_ALIGNMENT);
 	if (skb == NULL)
 		return NULL;
 
@@ -227,8 +228,6 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
 		    (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT -
 					      1)));
 
-	skb->dev = ugeth->ndev;
-
 	out_be32(&((struct qe_bd __iomem *)bd)->buf,
 		      dma_map_single(ugeth->dev,
 				     skb->data,
diff --git a/drivers/net/ethernet/fujitsu/at1700.c b/drivers/net/ethernet/fujitsu/at1700.c
index 7c6c908..586b46f 100644
--- a/drivers/net/ethernet/fujitsu/at1700.c
+++ b/drivers/net/ethernet/fujitsu/at1700.c
@@ -757,7 +757,7 @@ net_rx(struct net_device *dev)
 				dev->stats.rx_errors++;
 				break;
 			}
-			skb = dev_alloc_skb(pkt_len+3);
+			skb = netdev_alloc_skb(dev, pkt_len + 3);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet (len %d).\n",
 					   dev->name, pkt_len);
diff --git a/drivers/net/ethernet/fujitsu/eth16i.c b/drivers/net/ethernet/fujitsu/eth16i.c
index b0e2313..c3f0178 100644
--- a/drivers/net/ethernet/fujitsu/eth16i.c
+++ b/drivers/net/ethernet/fujitsu/eth16i.c
@@ -1164,7 +1164,7 @@ static void eth16i_rx(struct net_device *dev)
 		else {   /* Ok so now we should have a good packet */
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len + 3);
+			skb = netdev_alloc_skb(dev, pkt_len + 3);
 			if( skb == NULL ) {
 				printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n",
 				       dev->name, pkt_len);
diff --git a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
index ee84b47..0230319 100644
--- a/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
+++ b/drivers/net/ethernet/fujitsu/fmvj18x_cs.c
@@ -1002,7 +1002,7 @@ static void fjn_rx(struct net_device *dev)
 		dev->stats.rx_errors++;
 		break;
 	    }
-	    skb = dev_alloc_skb(pkt_len+2);
+	    skb = netdev_alloc_skb(dev, pkt_len + 2);
 	    if (skb == NULL) {
 		netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n",
 			      pkt_len);
diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c
index 6a5ee07..d496673 100644
--- a/drivers/net/ethernet/hp/hp100.c
+++ b/drivers/net/ethernet/hp/hp100.c
@@ -1274,7 +1274,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr,
 	/* Note: This depends on the alloc_skb functions allocating more
 	 * space than requested, i.e. aligning to 16bytes */
 
-	ringptr->skb = dev_alloc_skb(roundup(MAX_ETHER_SIZE + 2, 4));
+	ringptr->skb = netdev_alloc_skb(dev, roundup(MAX_ETHER_SIZE + 2, 4));
 
 	if (NULL != ringptr->skb) {
 		/*
@@ -1284,7 +1284,6 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr,
 		 */
 		skb_reserve(ringptr->skb, 2);
 
-		ringptr->skb->dev = dev;
 		ringptr->skb->data = (u_char *) skb_put(ringptr->skb, MAX_ETHER_SIZE);
 
 		/* ringptr->pdl points to the beginning of the PDL, i.e. the PDH */
@@ -1817,7 +1816,7 @@ static void hp100_rx(struct net_device *dev)
 #endif
 
 		/* Now we allocate the skb and transfer the data into it. */
-		skb = dev_alloc_skb(pkt_len+2);
+		skb = netdev_alloc_skb(dev, pkt_len + 2);
 		if (skb == NULL) {	/* Not enough memory->drop packet */
 #ifdef HP100_DEBUG
 			printk("hp100: %s: rx: couldn't allocate a sk_buff of size %d\n",
@@ -2992,7 +2991,6 @@ static int __init hp100_isa_init(void)
 	for (i = 0; i < HP100_DEVICES && hp100_port[i] != -1; ++i) {
 		dev = alloc_etherdev(sizeof(struct hp100_private));
 		if (!dev) {
-			printk(KERN_WARNING "hp100: no memory for network device\n");
 			while (cards > 0)
 				cleanup_dev(hp100_devlist[--cards]);
 
diff --git a/drivers/net/ethernet/i825xx/3c505.c b/drivers/net/ethernet/i825xx/3c505.c
index ba82a26..6a5c21b 100644
--- a/drivers/net/ethernet/i825xx/3c505.c
+++ b/drivers/net/ethernet/i825xx/3c505.c
@@ -583,7 +583,7 @@ static void receive_packet(struct net_device *dev, int len)
 	unsigned long flags;
 
 	rlen = (len + 1) & ~1;
-	skb = dev_alloc_skb(rlen + 2);
+	skb = netdev_alloc_skb(dev, rlen + 2);
 
 	if (!skb) {
 		pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
diff --git a/drivers/net/ethernet/i825xx/3c507.c b/drivers/net/ethernet/i825xx/3c507.c
index 1e94555..ed6925f 100644
--- a/drivers/net/ethernet/i825xx/3c507.c
+++ b/drivers/net/ethernet/i825xx/3c507.c
@@ -851,7 +851,7 @@ static void el16_rx(struct net_device *dev)
 			struct sk_buff *skb;
 
 			pkt_len &= 0x3fff;
-			skb = dev_alloc_skb(pkt_len+2);
+			skb = netdev_alloc_skb(dev, pkt_len + 2);
 			if (skb == NULL) {
 				pr_err("%s: Memory squeeze, dropping packet.\n",
 				       dev->name);
diff --git a/drivers/net/ethernet/i825xx/3c523.c b/drivers/net/ethernet/i825xx/3c523.c
index d70d3df..8451ecd 100644
--- a/drivers/net/ethernet/i825xx/3c523.c
+++ b/drivers/net/ethernet/i825xx/3c523.c
@@ -983,7 +983,7 @@ static void elmc_rcv_int(struct net_device *dev)
 			if ((totlen = rbd->status) & RBD_LAST) {	/* the first and the last buffer? */
 				totlen &= RBD_MASK;	/* length of this frame */
 				rbd->status = 0;
-				skb = (struct sk_buff *) dev_alloc_skb(totlen + 2);
+				skb = netdev_alloc_skb(dev, totlen + 2);
 				if (skb != NULL) {
 					skb_reserve(skb, 2);	/* 16 byte alignment */
 					skb_put(skb,totlen);
diff --git a/drivers/net/ethernet/i825xx/3c527.c b/drivers/net/ethernet/i825xx/3c527.c
index 474b5e7..ef43f3e 100644
--- a/drivers/net/ethernet/i825xx/3c527.c
+++ b/drivers/net/ethernet/i825xx/3c527.c
@@ -1169,7 +1169,7 @@ static void mc32_rx_ring(struct net_device *dev)
 			/* Try to save time by avoiding a copy on big frames */
 
 			if ((length > RX_COPYBREAK) &&
-			    ((newskb=dev_alloc_skb(1532)) != NULL))
+			    ((newskb = netdev_alloc_skb(dev, 1532)) != NULL))
 			{
 				skb=lp->rx_ring[rx_ring_tail].skb;
 				skb_put(skb, length);
@@ -1180,7 +1180,7 @@ static void mc32_rx_ring(struct net_device *dev)
 			}
 			else
 			{
-				skb=dev_alloc_skb(length+2);
+				skb = netdev_alloc_skb(dev, length + 2);
 
 				if(skb==NULL) {
 					dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/i825xx/82596.c b/drivers/net/ethernet/i825xx/82596.c
index f2408a4..6aa927a 100644
--- a/drivers/net/ethernet/i825xx/82596.c
+++ b/drivers/net/ethernet/i825xx/82596.c
@@ -549,14 +549,13 @@ static inline int init_rx_bufs(struct net_device *dev)
 	/* First build the Receive Buffer Descriptor List */
 
 	for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
-		struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
+		struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 
 		if (skb == NULL) {
 			remove_rx_bufs(dev);
 			return -ENOMEM;
 		}
 
-		skb->dev = dev;
 		rbd->v_next = rbd+1;
 		rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1));
 		rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
@@ -810,7 +809,7 @@ static inline int i596_rx(struct net_device *dev)
 				struct sk_buff *newskb;
 
 				/* Get fresh skbuff to replace filled one. */
-				newskb = dev_alloc_skb(PKT_BUF_SZ);
+				newskb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 				if (newskb == NULL) {
 					skb = NULL;	/* drop pkt */
 					goto memory_squeeze;
@@ -819,7 +818,6 @@ static inline int i596_rx(struct net_device *dev)
 				skb_put(skb, pkt_len);
 				rx_in_place = 1;
 				rbd->skb = newskb;
-				newskb->dev = dev;
 				rbd->v_data = newskb->data;
 				rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
 #ifdef __mc68000__
@@ -827,7 +825,7 @@ static inline int i596_rx(struct net_device *dev)
 #endif
 			}
 			else
-				skb = dev_alloc_skb(pkt_len + 2);
+				skb = netdev_alloc_skb(dev, pkt_len + 2);
 memory_squeeze:
 			if (skb == NULL) {
 				/* XXX tulip.c can defer packets here!! */
diff --git a/drivers/net/ethernet/i825xx/eepro.c b/drivers/net/ethernet/i825xx/eepro.c
index 114cda77..7a4ad4a 100644
--- a/drivers/net/ethernet/i825xx/eepro.c
+++ b/drivers/net/ethernet/i825xx/eepro.c
@@ -1563,7 +1563,7 @@ eepro_rx(struct net_device *dev)
 
 			dev->stats.rx_bytes+=rcv_size;
 			rcv_size &= 0x3fff;
-			skb = dev_alloc_skb(rcv_size+5);
+			skb = netdev_alloc_skb(dev, rcv_size + 5);
 			if (skb == NULL) {
 				printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 				dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/i825xx/eexpress.c b/drivers/net/ethernet/i825xx/eexpress.c
index 3a9580f..3fc649e 100644
--- a/drivers/net/ethernet/i825xx/eexpress.c
+++ b/drivers/net/ethernet/i825xx/eexpress.c
@@ -955,7 +955,7 @@ static void eexp_hw_rx_pio(struct net_device *dev)
 			{
 				struct sk_buff *skb;
 				pkt_len &= 0x3fff;
-				skb = dev_alloc_skb(pkt_len+16);
+				skb = netdev_alloc_skb(dev, pkt_len + 16);
 				if (skb == NULL)
 				{
 					printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
diff --git a/drivers/net/ethernet/i825xx/ether1.c b/drivers/net/ethernet/i825xx/ether1.c
index 42e90a9..406a12b 100644
--- a/drivers/net/ethernet/i825xx/ether1.c
+++ b/drivers/net/ethernet/i825xx/ether1.c
@@ -867,7 +867,7 @@ ether1_recv_done (struct net_device *dev)
 			struct sk_buff *skb;
 
 			length = (length + 1) & ~1;
-			skb = dev_alloc_skb (length + 2);
+			skb = netdev_alloc_skb(dev, length + 2);
 
 			if (skb) {
 				skb_reserve (skb, 2);
diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c
index 414044b..6c2952c 100644
--- a/drivers/net/ethernet/i825xx/lp486e.c
+++ b/drivers/net/ethernet/i825xx/lp486e.c
@@ -454,8 +454,6 @@ init_rx_bufs(struct net_device *dev, int num) {
 			}
 
 			rfd->rbd = rbd;
-		} else {
-			printk("Could not kmalloc rbd\n");
 		}
 	}
 	lp->rbd_tail->next = rfd->rbd;
@@ -658,7 +656,7 @@ i596_rx_one(struct net_device *dev, struct i596_private *lp,
 	if (rfd->stat & RFD_STAT_OK) {
 		/* a good frame */
 		int pkt_len = (rfd->count & 0x3fff);
-		struct sk_buff *skb = dev_alloc_skb(pkt_len);
+		struct sk_buff *skb = netdev_alloc_skb(dev, pkt_len);
 
 		(*frames)++;
 
diff --git a/drivers/net/ethernet/i825xx/ni52.c b/drivers/net/ethernet/i825xx/ni52.c
index c089371..272976e 100644
--- a/drivers/net/ethernet/i825xx/ni52.c
+++ b/drivers/net/ethernet/i825xx/ni52.c
@@ -964,7 +964,7 @@ static void ni52_rcv_int(struct net_device *dev)
 				/* the first and the last buffer? */
 				totlen &= RBD_MASK; /* length of this frame */
 				writew(0x00, &rbd->status);
-				skb = (struct sk_buff *)dev_alloc_skb(totlen+2);
+				skb = netdev_alloc_skb(dev, totlen + 2);
 				if (skb != NULL) {
 					skb_reserve(skb, 2);
 					skb_put(skb, totlen);
diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c
index 6ef5e11..cae17f4 100644
--- a/drivers/net/ethernet/i825xx/sun3_82586.c
+++ b/drivers/net/ethernet/i825xx/sun3_82586.c
@@ -28,7 +28,6 @@ static int automatic_resume = 0; /* experimental .. better should be zero */
 static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */
 static int fifo=0x8;	/* don't change */
 
-#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
@@ -779,7 +778,7 @@ static void sun3_82586_rcv_int(struct net_device *dev)
 				{
 					totlen &= RBD_MASK; /* length of this frame */
 					rbd->status = 0;
-					skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
+					skb = netdev_alloc_skb(dev, totlen + 2);
 					if(skb != NULL)
 					{
 						skb_reserve(skb,2);
@@ -1151,28 +1150,6 @@ static void set_multicast_list(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-#ifdef MODULE
-#error This code is not currently supported as a module
-static struct net_device *dev_sun3_82586;
-
-int init_module(void)
-{
-	dev_sun3_82586 = sun3_82586_probe(-1);
-	if (IS_ERR(dev_sun3_82586))
-		return PTR_ERR(dev_sun3_82586);
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	unsigned long ioaddr = dev_sun3_82586->base_addr;
-	unregister_netdev(dev_sun3_82586);
-	release_region(ioaddr, SUN3_82586_TOTAL_SIZE);
-	iounmap((void *)ioaddr);
-	free_netdev(dev_sun3_82586);
-}
-#endif /* MODULE */
-
 #if 0
 /*
  * DUMP .. we expect a not running CMD unit and enough space
@@ -1209,5 +1186,3 @@ void sun3_82586_dump(struct net_device *dev,void *ptr)
 	printk("\n");
 }
 #endif
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c
index 962b4c4..a436497 100644
--- a/drivers/net/ethernet/i825xx/znet.c
+++ b/drivers/net/ethernet/i825xx/znet.c
@@ -762,7 +762,7 @@ static void znet_rx(struct net_device *dev)
 			/* Malloc up new buffer. */
 			struct sk_buff *skb;
 
-			skb = dev_alloc_skb(pkt_len);
+			skb = netdev_alloc_skb(dev, pkt_len);
 			if (skb == NULL) {
 				if (znet_debug)
 				  printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
diff --git a/drivers/net/ethernet/ibm/ehea/ehea.h b/drivers/net/ethernet/ibm/ehea/ehea.h
index 6650068..b8e46cc 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea.h
+++ b/drivers/net/ethernet/ibm/ehea/ehea.h
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea.h
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea.h
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
index 6bdd8e3..95837b9 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_ethtool.c
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_hw.h b/drivers/net/ethernet/ibm/ehea/ehea_hw.h
index 1a2fe4d..180d412 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_hw.h
+++ b/drivers/net/ethernet/ibm/ehea/ehea_hw.h
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_hw.h
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_hw.h
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index 5d5fb26..8b73dd4 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_main.c
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_main.c
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
@@ -2980,7 +2980,6 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 	dev = alloc_etherdev_mq(sizeof(struct ehea_port), EHEA_MAX_PORT_RES);
 
 	if (!dev) {
-		pr_err("no mem for net_device\n");
 		ret = -ENOMEM;
 		goto out_err;
 	}
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
index 0506967..30f9033 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_phyp.c
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_phyp.c
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h
index 2f8174c..52c456e 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h
+++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_phyp.h
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_phyp.h
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
index c25b05b..4fb47f1 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_qmr.c
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_qmr.c
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.h b/drivers/net/ethernet/ibm/ehea/ehea_qmr.h
index 337a47e..8e4a70c 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.h
+++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.h
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/net/ehea/ehea_qmr.h
+ *  linux/drivers/net/ethernet/ibm/ehea/ehea_qmr.h
  *
  *  eHEA ethernet device driver for IBM eServer System p
  *
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 2abce96..dac7ffb 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/core.c
+ * drivers/net/ethernet/ibm/emac/core.c
  *
  * Driver for PowerPC 4xx on-chip ethernet controller.
  *
@@ -2706,11 +2706,9 @@ static int __devinit emac_probe(struct platform_device *ofdev)
 	/* Allocate our net_device structure */
 	err = -ENOMEM;
 	ndev = alloc_etherdev(sizeof(struct emac_instance));
-	if (!ndev) {
-		printk(KERN_ERR "%s: could not allocate ethernet device!\n",
-		       np->full_name);
+	if (!ndev)
 		goto err_gone;
-	}
+
 	dev = netdev_priv(ndev);
 	dev->ndev = ndev;
 	dev->ofdev = ofdev;
diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h
index fa3ec57..bade296 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/core.h
+ * drivers/net/ethernet/ibm/emac/core.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller.
  *
diff --git a/drivers/net/ethernet/ibm/emac/debug.c b/drivers/net/ethernet/ibm/emac/debug.c
index 8c6c1e2..b16b482 100644
--- a/drivers/net/ethernet/ibm/emac/debug.c
+++ b/drivers/net/ethernet/ibm/emac/debug.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/debug.c
+ * drivers/net/ethernet/ibm/emac/debug.c
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
  *
diff --git a/drivers/net/ethernet/ibm/emac/debug.h b/drivers/net/ethernet/ibm/emac/debug.h
index 90477fe..59a92d5 100644
--- a/drivers/net/ethernet/ibm/emac/debug.h
+++ b/drivers/net/ethernet/ibm/emac/debug.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/debug.h
+ * drivers/net/ethernet/ibm/emac/debug.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
  *
diff --git a/drivers/net/ethernet/ibm/emac/emac.h b/drivers/net/ethernet/ibm/emac/emac.h
index 1568278..b44bd24 100644
--- a/drivers/net/ethernet/ibm/emac/emac.h
+++ b/drivers/net/ethernet/ibm/emac/emac.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/emac.h
+ * drivers/net/ethernet/ibm/emac/emac.h
  *
  * Register definitions for PowerPC 4xx on-chip ethernet contoller
  *
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c
index f3c50b9..479e43e 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/mal.c
+ * drivers/net/ethernet/ibm/emac/mal.c
  *
  * Memory Access Layer (MAL) support
  *
diff --git a/drivers/net/ethernet/ibm/emac/mal.h b/drivers/net/ethernet/ibm/emac/mal.h
index d06f985..e431a32 100644
--- a/drivers/net/ethernet/ibm/emac/mal.h
+++ b/drivers/net/ethernet/ibm/emac/mal.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/mal.h
+ * drivers/net/ethernet/ibm/emac/mal.h
  *
  * Memory Access Layer (MAL) support
  *
diff --git a/drivers/net/ethernet/ibm/emac/phy.c b/drivers/net/ethernet/ibm/emac/phy.c
index ab4e596..d3b9d10 100644
--- a/drivers/net/ethernet/ibm/emac/phy.c
+++ b/drivers/net/ethernet/ibm/emac/phy.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/phy.c
+ * drivers/net/ethernet/ibm/emac/phy.c
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
  * Borrowed from sungem_phy.c, though I only kept the generic MII
diff --git a/drivers/net/ethernet/ibm/emac/phy.h b/drivers/net/ethernet/ibm/emac/phy.h
index 5d2bf4c..d7e41ec 100644
--- a/drivers/net/ethernet/ibm/emac/phy.h
+++ b/drivers/net/ethernet/ibm/emac/phy.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/phy.h
+ * drivers/net/ethernet/ibm/emac/phy.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, PHY support
  *
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c
index 4fa53f3..d312328 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.c
+++ b/drivers/net/ethernet/ibm/emac/rgmii.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/rgmii.c
+ * drivers/net/ethernet/ibm/emac/rgmii.c
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
  *
@@ -237,11 +237,8 @@ static int __devinit rgmii_probe(struct platform_device *ofdev)
 
 	rc = -ENOMEM;
 	dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL);
-	if (dev == NULL) {
-		printk(KERN_ERR "%s: could not allocate RGMII device!\n",
-		       np->full_name);
+	if (dev == NULL)
 		goto err_gone;
-	}
 
 	mutex_init(&dev->lock);
 	dev->ofdev = ofdev;
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.h b/drivers/net/ethernet/ibm/emac/rgmii.h
index 9296b6c..668bcee 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.h
+++ b/drivers/net/ethernet/ibm/emac/rgmii.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/rgmii.h
+ * drivers/net/ethernet/ibm/emac/rgmii.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
  *
diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c
index 5f51bf7..872912e 100644
--- a/drivers/net/ethernet/ibm/emac/tah.c
+++ b/drivers/net/ethernet/ibm/emac/tah.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/tah.c
+ * drivers/net/ethernet/ibm/emac/tah.c
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
  *
@@ -96,11 +96,8 @@ static int __devinit tah_probe(struct platform_device *ofdev)
 
 	rc = -ENOMEM;
 	dev = kzalloc(sizeof(struct tah_instance), GFP_KERNEL);
-	if (dev == NULL) {
-		printk(KERN_ERR "%s: could not allocate TAH device!\n",
-		       np->full_name);
+	if (dev == NULL)
 		goto err_gone;
-	}
 
 	mutex_init(&dev->lock);
 	dev->ofdev = ofdev;
diff --git a/drivers/net/ethernet/ibm/emac/tah.h b/drivers/net/ethernet/ibm/emac/tah.h
index 3437ab4..350b709 100644
--- a/drivers/net/ethernet/ibm/emac/tah.h
+++ b/drivers/net/ethernet/ibm/emac/tah.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/tah.h
+ * drivers/net/ethernet/ibm/emac/tah.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
  *
diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c
index 97449e7..415e9b4 100644
--- a/drivers/net/ethernet/ibm/emac/zmii.c
+++ b/drivers/net/ethernet/ibm/emac/zmii.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/zmii.c
+ * drivers/net/ethernet/ibm/emac/zmii.c
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
  *
@@ -240,11 +240,8 @@ static int __devinit zmii_probe(struct platform_device *ofdev)
 
 	rc = -ENOMEM;
 	dev = kzalloc(sizeof(struct zmii_instance), GFP_KERNEL);
-	if (dev == NULL) {
-		printk(KERN_ERR "%s: could not allocate ZMII device!\n",
-		       np->full_name);
+	if (dev == NULL)
 		goto err_gone;
-	}
 
 	mutex_init(&dev->lock);
 	dev->ofdev = ofdev;
diff --git a/drivers/net/ethernet/ibm/emac/zmii.h b/drivers/net/ethernet/ibm/emac/zmii.h
index ceaed82..455bfb0 100644
--- a/drivers/net/ethernet/ibm/emac/zmii.h
+++ b/drivers/net/ethernet/ibm/emac/zmii.h
@@ -1,5 +1,5 @@
 /*
- * drivers/net/ibm_newemac/zmii.h
+ * drivers/net/ethernet/ibm/emac/zmii.h
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
  *
diff --git a/drivers/net/ethernet/ibm/iseries_veth.c b/drivers/net/ethernet/ibm/iseries_veth.c
index acc31af..1cafa65 100644
--- a/drivers/net/ethernet/ibm/iseries_veth.c
+++ b/drivers/net/ethernet/ibm/iseries_veth.c
@@ -1032,10 +1032,8 @@ static struct net_device *veth_probe_one(int vlan,
 	}
 
 	dev = alloc_etherdev(sizeof (struct veth_port));
-	if (! dev) {
-		veth_error("Unable to allocate net_device structure!\n");
+	if (!dev)
 		return NULL;
-	}
 
 	port = netdev_priv(dev);
 
diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c
index 075451d..1b563bb 100644
--- a/drivers/net/ethernet/icplus/ipg.c
+++ b/drivers/net/ethernet/icplus/ipg.c
@@ -744,9 +744,6 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
 		return -ENOMEM;
 	}
 
-	/* Associate the receive buffer with the IPG NIC. */
-	skb->dev = dev;
-
 	/* Save the address of the sk_buff structure. */
 	sp->rx_buff[entry] = skb;
 
@@ -2233,7 +2230,6 @@ static int __devinit ipg_probe(struct pci_dev *pdev,
 	 */
 	dev = alloc_etherdev(sizeof(struct ipg_nic_private));
 	if (!dev) {
-		pr_err("%s: alloc_etherdev failed\n", pci_name(pdev));
 		rc = -ENOMEM;
 		goto err_disable_0;
 	}
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 9436397..485ab8c 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -2751,11 +2751,8 @@ static int __devinit e100_probe(struct pci_dev *pdev,
 	struct nic *nic;
 	int err;
 
-	if (!(netdev = alloc_etherdev(sizeof(struct nic)))) {
-		if (((1 << debug) - 1) & NETIF_MSG_PROBE)
-			pr_err("Etherdev alloc failed, aborting\n");
+	if (!(netdev = alloc_etherdev(sizeof(struct nic))))
 		return -ENOMEM;
-	}
 
 	netdev->netdev_ops = &e100_netdev_ops;
 	SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
diff --git a/drivers/net/ethernet/intel/e1000/e1000.h b/drivers/net/ethernet/intel/e1000/e1000.h
index 1e15969..2b6cd02 100644
--- a/drivers/net/ethernet/intel/e1000/e1000.h
+++ b/drivers/net/ethernet/intel/e1000/e1000.h
@@ -254,6 +254,7 @@ struct e1000_adapter {
 	atomic_t tx_fifo_stall;
 	bool pcix_82544;
 	bool detect_tx_hung;
+	bool dump_buffers;
 
 	/* RX */
 	bool (*clean_rx)(struct e1000_adapter *adapter,
diff --git a/drivers/net/ethernet/intel/e1000/e1000_hw.h b/drivers/net/ethernet/intel/e1000/e1000_hw.h
index f6c4d7e..11578c8 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_hw.h
+++ b/drivers/net/ethernet/intel/e1000/e1000_hw.h
@@ -895,6 +895,11 @@ struct e1000_ffvt_entry {
 #define E1000_FCRTL    0x02160	/* Flow Control Receive Threshold Low - RW */
 #define E1000_FCRTH    0x02168	/* Flow Control Receive Threshold High - RW */
 #define E1000_PSRCTL   0x02170	/* Packet Split Receive Control - RW */
+#define E1000_RDFH     0x02410  /* RX Data FIFO Head - RW */
+#define E1000_RDFT     0x02418  /* RX Data FIFO Tail - RW */
+#define E1000_RDFHS    0x02420  /* RX Data FIFO Head Saved - RW */
+#define E1000_RDFTS    0x02428  /* RX Data FIFO Tail Saved - RW */
+#define E1000_RDFPC    0x02430  /* RX Data FIFO Packet Count - RW */
 #define E1000_RDBAL    0x02800	/* RX Descriptor Base Address Low - RW */
 #define E1000_RDBAH    0x02804	/* RX Descriptor Base Address High - RW */
 #define E1000_RDLEN    0x02808	/* RX Descriptor Length - RW */
@@ -1074,6 +1079,11 @@ struct e1000_ffvt_entry {
 #define E1000_82542_IMC      E1000_IMC
 #define E1000_82542_RCTL     E1000_RCTL
 #define E1000_82542_RDTR     0x00108
+#define E1000_82542_RDFH     E1000_RDFH
+#define E1000_82542_RDFT     E1000_RDFT
+#define E1000_82542_RDFHS    E1000_RDFHS
+#define E1000_82542_RDFTS    E1000_RDFTS
+#define E1000_82542_RDFPC    E1000_RDFPC
 #define E1000_82542_RDBAL    0x00110
 #define E1000_82542_RDBAH    0x00114
 #define E1000_82542_RDLEN    0x00118
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index d94d64b..44d9789 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -730,10 +730,8 @@ static void e1000_dump_eeprom(struct e1000_adapter *adapter)
 	eeprom.offset = 0;
 
 	data = kmalloc(eeprom.len, GFP_KERNEL);
-	if (!data) {
-		pr_err("Unable to allocate memory to dump EEPROM data\n");
+	if (!data)
 		return;
-	}
 
 	ops->get_eeprom(netdev, &eeprom, data);
 
@@ -3241,6 +3239,228 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
+#define NUM_REGS 38 /* 1 based count */
+static void e1000_regdump(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 regs[NUM_REGS];
+	u32 *regs_buff = regs;
+	int i = 0;
+
+	char *reg_name[] = {
+	"CTRL",  "STATUS",
+	"RCTL", "RDLEN", "RDH", "RDT", "RDTR",
+	"TCTL", "TDBAL", "TDBAH", "TDLEN", "TDH", "TDT",
+	"TIDV", "TXDCTL", "TADV", "TARC0",
+	"TDBAL1", "TDBAH1", "TDLEN1", "TDH1", "TDT1",
+	"TXDCTL1", "TARC1",
+	"CTRL_EXT", "ERT", "RDBAL", "RDBAH",
+	"TDFH", "TDFT", "TDFHS", "TDFTS", "TDFPC",
+	"RDFH", "RDFT", "RDFHS", "RDFTS", "RDFPC"
+	};
+
+	regs_buff[0]  = er32(CTRL);
+	regs_buff[1]  = er32(STATUS);
+
+	regs_buff[2]  = er32(RCTL);
+	regs_buff[3]  = er32(RDLEN);
+	regs_buff[4]  = er32(RDH);
+	regs_buff[5]  = er32(RDT);
+	regs_buff[6]  = er32(RDTR);
+
+	regs_buff[7]  = er32(TCTL);
+	regs_buff[8]  = er32(TDBAL);
+	regs_buff[9]  = er32(TDBAH);
+	regs_buff[10] = er32(TDLEN);
+	regs_buff[11] = er32(TDH);
+	regs_buff[12] = er32(TDT);
+	regs_buff[13] = er32(TIDV);
+	regs_buff[14] = er32(TXDCTL);
+	regs_buff[15] = er32(TADV);
+	regs_buff[16] = er32(TARC0);
+
+	regs_buff[17] = er32(TDBAL1);
+	regs_buff[18] = er32(TDBAH1);
+	regs_buff[19] = er32(TDLEN1);
+	regs_buff[20] = er32(TDH1);
+	regs_buff[21] = er32(TDT1);
+	regs_buff[22] = er32(TXDCTL1);
+	regs_buff[23] = er32(TARC1);
+	regs_buff[24] = er32(CTRL_EXT);
+	regs_buff[25] = er32(ERT);
+	regs_buff[26] = er32(RDBAL0);
+	regs_buff[27] = er32(RDBAH0);
+	regs_buff[28] = er32(TDFH);
+	regs_buff[29] = er32(TDFT);
+	regs_buff[30] = er32(TDFHS);
+	regs_buff[31] = er32(TDFTS);
+	regs_buff[32] = er32(TDFPC);
+	regs_buff[33] = er32(RDFH);
+	regs_buff[34] = er32(RDFT);
+	regs_buff[35] = er32(RDFHS);
+	regs_buff[36] = er32(RDFTS);
+	regs_buff[37] = er32(RDFPC);
+
+	pr_info("Register dump\n");
+	for (i = 0; i < NUM_REGS; i++) {
+		printk(KERN_INFO "%-15s  %08x\n",
+		reg_name[i], regs_buff[i]);
+	}
+}
+
+/*
+ * e1000_dump: Print registers, tx ring and rx ring
+ */
+static void e1000_dump(struct e1000_adapter *adapter)
+{
+	/* this code doesn't handle multiple rings */
+	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+	struct e1000_rx_ring *rx_ring = adapter->rx_ring;
+	int i;
+
+	if (!netif_msg_hw(adapter))
+		return;
+
+	/* Print Registers */
+	e1000_regdump(adapter);
+
+	/*
+	 * transmit dump
+	 */
+	pr_info("TX Desc ring0 dump\n");
+
+	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
+	 *
+	 * Legacy Transmit Descriptor
+	 *   +--------------------------------------------------------------+
+	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
+	 *   +--------------------------------------------------------------+
+	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
+	 *   +--------------------------------------------------------------+
+	 *   63       48 47        36 35    32 31     24 23    16 15        0
+	 *
+	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
+	 *   63      48 47    40 39       32 31             16 15    8 7      0
+	 *   +----------------------------------------------------------------+
+	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
+	 *   +----------------------------------------------------------------+
+	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
+	 *   +----------------------------------------------------------------+
+	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
+	 *
+	 * Extended Data Descriptor (DTYP=0x1)
+	 *   +----------------------------------------------------------------+
+	 * 0 |                     Buffer Address [63:0]                      |
+	 *   +----------------------------------------------------------------+
+	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
+	 *   +----------------------------------------------------------------+
+	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
+	 */
+	printk(KERN_INFO "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ]"
+	       " leng  ntw timestmp         bi->skb\n");
+	printk(KERN_INFO "Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ]"
+	       " leng  ntw timestmp         bi->skb\n");
+
+	if (!netif_msg_tx_done(adapter))
+		goto rx_ring_summary;
+
+	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
+		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
+		struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
+		struct my_u { u64 a; u64 b; };
+		struct my_u *u = (struct my_u *)tx_desc;
+		printk(KERN_INFO "T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X "
+		       "%016llX %p",
+		       ((le64_to_cpu(u->b) & (1<<20)) ? 'd' : 'c'), i,
+		       le64_to_cpu(u->a), le64_to_cpu(u->b),
+		       (u64)buffer_info->dma, buffer_info->length,
+		       buffer_info->next_to_watch, (u64)buffer_info->time_stamp,
+		       buffer_info->skb);
+		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
+			printk(KERN_CONT" NTC/U\n");
+		else if (i == tx_ring->next_to_use)
+			printk(KERN_CONT " NTU\n");
+		else if (i == tx_ring->next_to_clean)
+			printk(KERN_CONT " NTC\n");
+		else
+			printk(KERN_CONT "\n");
+
+
+		if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
+			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
+					16, 1, phys_to_virt(buffer_info->dma),
+					buffer_info->length, true);
+	}
+
+rx_ring_summary:
+	/*
+	 * receive dump
+	 */
+	pr_info("\nRX Desc ring dump\n");
+
+	/* Legacy Receive Descriptor Format
+	 *
+	 * +-----------------------------------------------------+
+	 * |                Buffer Address [63:0]                |
+	 * +-----------------------------------------------------+
+	 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
+	 * +-----------------------------------------------------+
+	 * 63       48 47    40 39      32 31         16 15      0
+	 */
+	printk(KERN_INFO "R[desc]      [address 63:0  ] [vl er S cks ln] "
+		"[bi->dma       ] [bi->skb]\n");
+
+	if (!netif_msg_rx_status(adapter))
+		goto exit;
+
+	for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
+		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
+		struct e1000_buffer *buffer_info = &rx_ring->buffer_info[i];
+		struct my_u { u64 a; u64 b; };
+		struct my_u *u = (struct my_u *)rx_desc;
+		printk(KERN_INFO "R[0x%03X]     %016llX %016llX %016llX %p",
+			i, le64_to_cpu(u->a), le64_to_cpu(u->b),
+			(u64)buffer_info->dma, buffer_info->skb);
+		if (i == rx_ring->next_to_use)
+			printk(KERN_CONT " NTU\n");
+		else if (i == rx_ring->next_to_clean)
+			printk(KERN_CONT " NTC\n");
+		else
+			printk(KERN_CONT "\n");
+
+		if (netif_msg_pktdata(adapter))
+			print_hex_dump(KERN_INFO, "",
+				DUMP_PREFIX_ADDRESS, 16, 1,
+				phys_to_virt(buffer_info->dma),
+				buffer_info->length, true);
+
+	} /* for */
+
+	/* dump the descriptor caches */
+	/* rx */
+	printk(KERN_INFO "e1000: Rx descriptor cache in 64bit format\n");
+	for (i = 0x6000; i <= 0x63FF ; i += 0x10) {
+		printk(KERN_INFO "R%04X: %08X|%08X %08X|%08X\n",
+				i,
+				readl(adapter->hw.hw_addr + i+4),
+				readl(adapter->hw.hw_addr + i),
+				readl(adapter->hw.hw_addr + i+12),
+				readl(adapter->hw.hw_addr + i+8));
+	}
+	/* tx */
+	printk(KERN_INFO "e1000: Tx descriptor cache in 64bit format\n");
+	for (i = 0x7000; i <= 0x73FF ; i += 0x10) {
+		printk(KERN_INFO "T%04X: %08X|%08X %08X|%08X\n",
+				i,
+				readl(adapter->hw.hw_addr + i+4),
+				readl(adapter->hw.hw_addr + i),
+				readl(adapter->hw.hw_addr + i+12),
+				readl(adapter->hw.hw_addr + i+8));
+	}
+exit:
+	return;
+}
+
 /**
  * e1000_tx_timeout - Respond to a Tx Hang
  * @netdev: network interface device structure
@@ -3262,6 +3482,7 @@ static void e1000_reset_task(struct work_struct *work)
 
 	if (test_bit(__E1000_DOWN, &adapter->flags))
 		return;
+	e_err(drv, "Reset adapter\n");
 	e1000_reinit_safe(adapter);
 }
 
@@ -3679,6 +3900,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 				eop,
 				jiffies,
 				eop_desc->upper.fields.status);
+			e1000_dump(adapter);
 			netif_stop_queue(netdev);
 		}
 	}
@@ -3878,11 +4100,9 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
 				if (length <= copybreak &&
 				    skb_tailroom(skb) >= length) {
 					u8 *vaddr;
-					vaddr = kmap_atomic(buffer_info->page,
-					                    KM_SKB_DATA_SOFTIRQ);
+					vaddr = kmap_atomic(buffer_info->page);
 					memcpy(skb_tail_pointer(skb), vaddr, length);
-					kunmap_atomic(vaddr,
-					              KM_SKB_DATA_SOFTIRQ);
+					kunmap_atomic(vaddr);
 					/* re-use the page, so don't erase
 					 * buffer_info->page */
 					skb_put(skb, length);
diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c
index e1159e5..bc960fe 100644
--- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c
+++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -201,19 +201,23 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw)
  *  e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs.
  *  @hw: pointer to the HW structure
  **/
-static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
+static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
-	struct e1000_mac_operations *func = &mac->ops;
 
-	/* Set media type */
-	switch (adapter->pdev->device) {
+	/* Set media type and media-dependent function pointers */
+	switch (hw->adapter->pdev->device) {
 	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
 		hw->phy.media_type = e1000_media_type_internal_serdes;
+		mac->ops.check_for_link = e1000e_check_for_serdes_link;
+		mac->ops.setup_physical_interface =
+		    e1000e_setup_fiber_serdes_link;
 		break;
 	default:
 		hw->phy.media_type = e1000_media_type_copper;
+		mac->ops.check_for_link = e1000e_check_for_copper_link;
+		mac->ops.setup_physical_interface =
+		    e1000_setup_copper_link_80003es2lan;
 		break;
 	}
 
@@ -230,25 +234,6 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
 	/* Adaptive IFS not supported */
 	mac->adaptive_ifs = false;
 
-	/* check for link */
-	switch (hw->phy.media_type) {
-	case e1000_media_type_copper:
-		func->setup_physical_interface = e1000_setup_copper_link_80003es2lan;
-		func->check_for_link = e1000e_check_for_copper_link;
-		break;
-	case e1000_media_type_fiber:
-		func->setup_physical_interface = e1000e_setup_fiber_serdes_link;
-		func->check_for_link = e1000e_check_for_fiber_link;
-		break;
-	case e1000_media_type_internal_serdes:
-		func->setup_physical_interface = e1000e_setup_fiber_serdes_link;
-		func->check_for_link = e1000e_check_for_serdes_link;
-		break;
-	default:
-		return -E1000_ERR_CONFIG;
-		break;
-	}
-
 	/* set lan id for port to determine which phy lock to use */
 	hw->mac.ops.set_lan_id(hw);
 
@@ -260,7 +245,7 @@ static s32 e1000_get_variants_80003es2lan(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	s32 rc;
 
-	rc = e1000_init_mac_params_80003es2lan(adapter);
+	rc = e1000_init_mac_params_80003es2lan(hw);
 	if (rc)
 		return rc;
 
@@ -485,9 +470,8 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 		ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
 
 		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-			ret_val = -E1000_ERR_PHY;
 			e1000_release_phy_80003es2lan(hw);
-			return ret_val;
+			return -E1000_ERR_PHY;
 		}
 
 		udelay(200);
@@ -667,8 +651,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 	udelay(1);
 
 	if (hw->phy.autoneg_wait_to_complete) {
-		e_dbg("Waiting for forced speed/duplex link "
-			 "on GG82563 phy.\n");
+		e_dbg("Waiting for forced speed/duplex link on GG82563 phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
 						     100000, &link);
@@ -731,22 +714,19 @@ static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, GG82563_PHY_DSP_DISTANCE, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
 
-	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) {
-		ret_val = -E1000_ERR_PHY;
-		goto out;
-	}
+	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5)
+		return -E1000_ERR_PHY;
 
 	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
 	phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -820,9 +800,7 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
 	ew32(IMC, 0xffffffff);
 	er32(ICR);
 
-	ret_val = e1000_check_alt_mac_addr_generic(hw);
-
-	return ret_val;
+	return e1000_check_alt_mac_addr_generic(hw);
 }
 
 /**
@@ -1163,9 +1141,7 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	ret_val = e1000e_setup_copper_link(hw);
-
-	return 0;
+	return e1000e_setup_copper_link(hw);
 }
 
 /**
@@ -1241,9 +1217,7 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
 	else
 		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
 
-	ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
-
-	return 0;
+	return e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
 }
 
 /**
@@ -1285,9 +1259,8 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
 	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
 
 	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
-	ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
 
-	return ret_val;
+	return e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
 }
 
 /**
@@ -1372,12 +1345,9 @@ static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
 	 */
 	ret_val = e1000_check_alt_mac_addr_generic(hw);
 	if (ret_val)
-		goto out;
-
-	ret_val = e1000_read_mac_addr_generic(hw);
+		return ret_val;
 
-out:
-	return ret_val;
+	return e1000_read_mac_addr_generic(hw);
 }
 
 /**
@@ -1502,8 +1472,7 @@ const struct e1000_info e1000_es2_info = {
 				  | FLAG_RX_NEEDS_RESTART /* errata */
 				  | FLAG_TARC_SET_BIT_ZERO /* errata */
 				  | FLAG_APME_CHECK_PORT_B
-				  | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
-				  | FLAG_TIPG_MEDIUM_FOR_80003ESLAN,
+				  | FLAG_DISABLE_FC_PAUSE_TIME, /* errata */
 	.flags2			= FLAG2_DMA_BURST,
 	.pba			= 38,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c
index a3e65fd..b6b7bc4 100644
--- a/drivers/net/ethernet/intel/e1000e/82571.c
+++ b/drivers/net/ethernet/intel/e1000e/82571.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -235,30 +235,42 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
  *  e1000_init_mac_params_82571 - Init MAC func ptrs.
  *  @hw: pointer to the HW structure
  **/
-static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
+static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
-	struct e1000_mac_operations *func = &mac->ops;
 	u32 swsm = 0;
 	u32 swsm2 = 0;
 	bool force_clear_smbi = false;
 
-	/* Set media type */
-	switch (adapter->pdev->device) {
+	/* Set media type and media-dependent function pointers */
+	switch (hw->adapter->pdev->device) {
 	case E1000_DEV_ID_82571EB_FIBER:
 	case E1000_DEV_ID_82572EI_FIBER:
 	case E1000_DEV_ID_82571EB_QUAD_FIBER:
 		hw->phy.media_type = e1000_media_type_fiber;
+		mac->ops.setup_physical_interface =
+		    e1000_setup_fiber_serdes_link_82571;
+		mac->ops.check_for_link = e1000e_check_for_fiber_link;
+		mac->ops.get_link_up_info =
+		    e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
 	case E1000_DEV_ID_82571EB_SERDES:
-	case E1000_DEV_ID_82572EI_SERDES:
 	case E1000_DEV_ID_82571EB_SERDES_DUAL:
 	case E1000_DEV_ID_82571EB_SERDES_QUAD:
+	case E1000_DEV_ID_82572EI_SERDES:
 		hw->phy.media_type = e1000_media_type_internal_serdes;
+		mac->ops.setup_physical_interface =
+		    e1000_setup_fiber_serdes_link_82571;
+		mac->ops.check_for_link = e1000_check_for_serdes_link_82571;
+		mac->ops.get_link_up_info =
+		    e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
 	default:
 		hw->phy.media_type = e1000_media_type_copper;
+		mac->ops.setup_physical_interface =
+		    e1000_setup_copper_link_82571;
+		mac->ops.check_for_link = e1000e_check_for_copper_link;
+		mac->ops.get_link_up_info = e1000e_get_speed_and_duplex_copper;
 		break;
 	}
 
@@ -269,38 +281,13 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 	/* Adaptive IFS supported */
 	mac->adaptive_ifs = true;
 
-	/* check for link */
-	switch (hw->phy.media_type) {
-	case e1000_media_type_copper:
-		func->setup_physical_interface = e1000_setup_copper_link_82571;
-		func->check_for_link = e1000e_check_for_copper_link;
-		func->get_link_up_info = e1000e_get_speed_and_duplex_copper;
-		break;
-	case e1000_media_type_fiber:
-		func->setup_physical_interface =
-			e1000_setup_fiber_serdes_link_82571;
-		func->check_for_link = e1000e_check_for_fiber_link;
-		func->get_link_up_info =
-			e1000e_get_speed_and_duplex_fiber_serdes;
-		break;
-	case e1000_media_type_internal_serdes:
-		func->setup_physical_interface =
-			e1000_setup_fiber_serdes_link_82571;
-		func->check_for_link = e1000_check_for_serdes_link_82571;
-		func->get_link_up_info =
-			e1000e_get_speed_and_duplex_fiber_serdes;
-		break;
-	default:
-		return -E1000_ERR_CONFIG;
-		break;
-	}
-
+	/* MAC-specific function pointers */
 	switch (hw->mac.type) {
 	case e1000_82573:
-		func->set_lan_id = e1000_set_lan_id_single_port;
-		func->check_mng_mode = e1000e_check_mng_mode_generic;
-		func->led_on = e1000e_led_on_generic;
-		func->blink_led = e1000e_blink_led_generic;
+		mac->ops.set_lan_id = e1000_set_lan_id_single_port;
+		mac->ops.check_mng_mode = e1000e_check_mng_mode_generic;
+		mac->ops.led_on = e1000e_led_on_generic;
+		mac->ops.blink_led = e1000e_blink_led_generic;
 
 		/* FWSM register */
 		mac->has_fwsm = true;
@@ -314,14 +301,14 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 		break;
 	case e1000_82574:
 	case e1000_82583:
-		func->set_lan_id = e1000_set_lan_id_single_port;
-		func->check_mng_mode = e1000_check_mng_mode_82574;
-		func->led_on = e1000_led_on_82574;
+		mac->ops.set_lan_id = e1000_set_lan_id_single_port;
+		mac->ops.check_mng_mode = e1000_check_mng_mode_82574;
+		mac->ops.led_on = e1000_led_on_82574;
 		break;
 	default:
-		func->check_mng_mode = e1000e_check_mng_mode_generic;
-		func->led_on = e1000e_led_on_generic;
-		func->blink_led = e1000e_blink_led_generic;
+		mac->ops.check_mng_mode = e1000e_check_mng_mode_generic;
+		mac->ops.led_on = e1000e_led_on_generic;
+		mac->ops.blink_led = e1000e_blink_led_generic;
 
 		/* FWSM register */
 		mac->has_fwsm = true;
@@ -342,11 +329,11 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 
 		if (!(swsm2 & E1000_SWSM2_LOCK)) {
 			/* Only do this for the first interface on this card */
-			ew32(SWSM2,
-			    swsm2 | E1000_SWSM2_LOCK);
+			ew32(SWSM2, swsm2 | E1000_SWSM2_LOCK);
 			force_clear_smbi = true;
-		} else
+		} else {
 			force_clear_smbi = false;
+		}
 		break;
 	default:
 		force_clear_smbi = true;
@@ -383,7 +370,7 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
 	int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
 	s32 rc;
 
-	rc = e1000_init_mac_params_82571(adapter);
+	rc = e1000_init_mac_params_82571(hw);
 	if (rc)
 		return rc;
 
@@ -577,7 +564,6 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
 static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
 {
 	u32 extcnf_ctrl;
-	s32 ret_val = 0;
 	s32 i = 0;
 
 	extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -599,12 +585,10 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
 		/* Release semaphores */
 		e1000_put_hw_semaphore_82573(hw);
 		e_dbg("Driver can't access the PHY\n");
-		ret_val = -E1000_ERR_PHY;
-		goto out;
+		return -E1000_ERR_PHY;
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -809,7 +793,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
 	 * otherwise, commit the checksum to the flash NVM.
 	 */
 	if (hw->nvm.type != e1000_nvm_flash_hw)
-		return ret_val;
+		return 0;
 
 	/* Check for pending operations. */
 	for (i = 0; i < E1000_FLASH_UPDATES; i++) {
@@ -1227,6 +1211,10 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
 	case e1000_82572:
 		reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26);
 		break;
+	case e1000_82574:
+	case e1000_82583:
+		reg |= (1 << 26);
+		break;
 	default:
 		break;
 	}
@@ -1418,7 +1406,6 @@ bool e1000_check_phy_82574(struct e1000_hw *hw)
 {
 	u16 status_1kbt = 0;
 	u16 receive_errors = 0;
-	bool phy_hung = false;
 	s32 ret_val = 0;
 
 	/*
@@ -1426,19 +1413,18 @@ bool e1000_check_phy_82574(struct e1000_hw *hw)
 	 * read the Base1000T status register If both are max then PHY is hung.
 	 */
 	ret_val = e1e_rphy(hw, E1000_RECEIVE_ERROR_COUNTER, &receive_errors);
-
 	if (ret_val)
-		goto out;
+		return false;
 	if (receive_errors == E1000_RECEIVE_ERROR_MAX)  {
 		ret_val = e1e_rphy(hw, E1000_BASE1000T_STATUS, &status_1kbt);
 		if (ret_val)
-			goto out;
+			return false;
 		if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) ==
 		    E1000_IDLE_ERROR_COUNT_MASK)
-			phy_hung = true;
+			return true;
 	}
-out:
-	return phy_hung;
+
+	return false;
 }
 
 /**
@@ -1506,9 +1492,7 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	ret_val = e1000e_setup_copper_link(hw);
-
-	return ret_val;
+	return e1000e_setup_copper_link(hw);
 }
 
 /**
@@ -1842,9 +1826,9 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
  **/
 static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
 {
-	s32 ret_val = 0;
-
 	if (hw->mac.type == e1000_82571) {
+		s32 ret_val = 0;
+
 		/*
 		 * If there's an alternate MAC address place it in RAR0
 		 * so that it will override the Si installed default perm
@@ -1852,13 +1836,10 @@ static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
 		 */
 		ret_val = e1000_check_alt_mac_addr_generic(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
-	ret_val = e1000_read_mac_addr_generic(hw);
-
-out:
-	return ret_val;
+	return e1000_read_mac_addr_generic(hw);
 }
 
 /**
@@ -1873,7 +1854,7 @@ static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw)
 	struct e1000_phy_info *phy = &hw->phy;
 	struct e1000_mac_info *mac = &hw->mac;
 
-	if (!(phy->ops.check_reset_block))
+	if (!phy->ops.check_reset_block)
 		return;
 
 	/* If the management interface is not enabled, then power down */
diff --git a/drivers/net/ethernet/intel/e1000e/Makefile b/drivers/net/ethernet/intel/e1000e/Makefile
index 948c05d..591b713 100644
--- a/drivers/net/ethernet/intel/e1000e/Makefile
+++ b/drivers/net/ethernet/intel/e1000e/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel PRO/1000 Linux driver
-# Copyright(c) 1999 - 2011 Intel Corporation.
+# Copyright(c) 1999 - 2012 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
@@ -33,5 +33,6 @@
 obj-$(CONFIG_E1000E) += e1000e.o
 
 e1000e-objs := 82571.o ich8lan.o 80003es2lan.o \
-	       lib.o phy.o param.o ethtool.o netdev.o
+	       mac.o manage.o nvm.o phy.o \
+	       param.o ethtool.o netdev.o
 
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h
index c516a74..1af30b9 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -126,6 +126,13 @@
     E1000_RXDEXT_STATERR_CXE |            \
     E1000_RXDEXT_STATERR_RXE)
 
+#define E1000_MRQC_RSS_FIELD_MASK              0xFFFF0000
+#define E1000_MRQC_RSS_FIELD_IPV4_TCP          0x00010000
+#define E1000_MRQC_RSS_FIELD_IPV4              0x00020000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX       0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6              0x00100000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP          0x00200000
+
 #define E1000_RXDPS_HDRSTAT_HDRSP              0x00008000
 
 /* Management Control */
@@ -326,6 +333,7 @@
 /* Receive Checksum Control */
 #define E1000_RXCSUM_TUOFL     0x00000200   /* TCP / UDP checksum offload */
 #define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
+#define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
 
 /* Header split receive */
 #define E1000_RFCTL_NFSW_DIS            0x00000040
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index f478a22..45e5ae8 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -234,6 +234,7 @@ struct e1000_buffer {
 };
 
 struct e1000_ring {
+	struct e1000_adapter *adapter;	/* back pointer to adapter */
 	void *desc;			/* pointer to ring memory  */
 	dma_addr_t dma;			/* phys address of ring    */
 	unsigned int size;		/* length of ring in bytes */
@@ -242,8 +243,8 @@ struct e1000_ring {
 	u16 next_to_use;
 	u16 next_to_clean;
 
-	u16 head;
-	u16 tail;
+	void __iomem *head;
+	void __iomem *tail;
 
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
@@ -251,7 +252,7 @@ struct e1000_ring {
 	char name[IFNAMSIZ + 5];
 	u32 ims_val;
 	u32 itr_val;
-	u16 itr_register;
+	void __iomem *itr_register;
 	int set_itr;
 
 	struct sk_buff *rx_skb_top;
@@ -334,11 +335,10 @@ struct e1000_adapter {
 	/*
 	 * Rx
 	 */
-	bool (*clean_rx) (struct e1000_adapter *adapter,
-			  int *work_done, int work_to_do)
-						____cacheline_aligned_in_smp;
-	void (*alloc_rx_buf) (struct e1000_adapter *adapter,
-			      int cleaned_count, gfp_t gfp);
+	bool (*clean_rx) (struct e1000_ring *ring, int *work_done,
+			  int work_to_do) ____cacheline_aligned_in_smp;
+	void (*alloc_rx_buf) (struct e1000_ring *ring, int cleaned_count,
+			      gfp_t gfp);
 	struct e1000_ring *rx_ring;
 
 	u32 rx_int_delay;
@@ -398,6 +398,9 @@ struct e1000_adapter {
 
 	bool idle_check;
 	int phy_hang_count;
+
+	u16 tx_ring_count;
+	u16 rx_ring_count;
 };
 
 struct e1000_info {
@@ -417,7 +420,7 @@ struct e1000_info {
 #define FLAG_HAS_FLASH                    (1 << 1)
 #define FLAG_HAS_HW_VLAN_FILTER           (1 << 2)
 #define FLAG_HAS_WOL                      (1 << 3)
-#define FLAG_HAS_ERT                      (1 << 4)
+/* reserved bit4 */
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
@@ -427,7 +430,7 @@ struct e1000_info {
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
 #define FLAG_IS_QUAD_PORT_A               (1 << 12)
 #define FLAG_IS_QUAD_PORT                 (1 << 13)
-#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN   (1 << 14)
+/* reserved bit14 */
 #define FLAG_APME_IN_WUC                  (1 << 15)
 #define FLAG_APME_IN_CTRL3                (1 << 16)
 #define FLAG_APME_CHECK_PORT_B            (1 << 17)
@@ -492,10 +495,10 @@ extern void e1000e_down(struct e1000_adapter *adapter);
 extern void e1000e_reinit_locked(struct e1000_adapter *adapter);
 extern void e1000e_reset(struct e1000_adapter *adapter);
 extern void e1000e_power_up_phy(struct e1000_adapter *adapter);
-extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
+extern int e1000e_setup_rx_resources(struct e1000_ring *ring);
+extern int e1000e_setup_tx_resources(struct e1000_ring *ring);
+extern void e1000e_free_rx_resources(struct e1000_ring *ring);
+extern void e1000e_free_tx_resources(struct e1000_ring *ring);
 extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
                                                     struct rtnl_link_stats64
                                                     *stats);
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index fb2c28e..b1f5d74 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -34,6 +34,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/vmalloc.h>
 
 #include "e1000.h"
 
@@ -536,7 +537,7 @@ static int e1000_set_eeprom(struct net_device *netdev,
 		ret_val = e1000_read_nvm(hw, first_word, 1, &eeprom_buff[0]);
 		ptr++;
 	}
-	if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0))
+	if (((eeprom->offset + eeprom->len) & 1) && (!ret_val))
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
 		ret_val = e1000_read_nvm(hw, last_word, 1,
@@ -552,7 +553,7 @@ static int e1000_set_eeprom(struct net_device *netdev,
 	memcpy(ptr, bytes, eeprom->len);
 
 	for (i = 0; i < last_word - first_word + 1; i++)
-		eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
+		cpu_to_le16s(&eeprom_buff[i]);
 
 	ret_val = e1000_write_nvm(hw, first_word,
 				  last_word - first_word + 1, eeprom_buff);
@@ -605,94 +606,112 @@ static void e1000_get_ringparam(struct net_device *netdev,
 				struct ethtool_ringparam *ring)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	struct e1000_ring *tx_ring = adapter->tx_ring;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 
 	ring->rx_max_pending = E1000_MAX_RXD;
 	ring->tx_max_pending = E1000_MAX_TXD;
-	ring->rx_pending = rx_ring->count;
-	ring->tx_pending = tx_ring->count;
+	ring->rx_pending = adapter->rx_ring_count;
+	ring->tx_pending = adapter->tx_ring_count;
 }
 
 static int e1000_set_ringparam(struct net_device *netdev,
 			       struct ethtool_ringparam *ring)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
-	struct e1000_ring *tx_ring, *tx_old;
-	struct e1000_ring *rx_ring, *rx_old;
-	int err;
+	struct e1000_ring *temp_tx = NULL, *temp_rx = NULL;
+	int err = 0, size = sizeof(struct e1000_ring);
+	bool set_tx = false, set_rx = false;
+	u16 new_rx_count, new_tx_count;
 
 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
 
-	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
-		usleep_range(1000, 2000);
+	new_rx_count = clamp_t(u32, ring->rx_pending, E1000_MIN_RXD,
+			       E1000_MAX_RXD);
+	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
 
-	if (netif_running(adapter->netdev))
-		e1000e_down(adapter);
+	new_tx_count = clamp_t(u32, ring->tx_pending, E1000_MIN_TXD,
+			       E1000_MAX_TXD);
+	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
 
-	tx_old = adapter->tx_ring;
-	rx_old = adapter->rx_ring;
+	if ((new_tx_count == adapter->tx_ring_count) &&
+	    (new_rx_count == adapter->rx_ring_count))
+		/* nothing to do */
+		return 0;
 
-	err = -ENOMEM;
-	tx_ring = kmemdup(tx_old, sizeof(struct e1000_ring), GFP_KERNEL);
-	if (!tx_ring)
-		goto err_alloc_tx;
+	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
+		usleep_range(1000, 2000);
 
-	rx_ring = kmemdup(rx_old, sizeof(struct e1000_ring), GFP_KERNEL);
-	if (!rx_ring)
-		goto err_alloc_rx;
+	if (!netif_running(adapter->netdev)) {
+		/* Set counts now and allocate resources during open() */
+		adapter->tx_ring->count = new_tx_count;
+		adapter->rx_ring->count = new_rx_count;
+		adapter->tx_ring_count = new_tx_count;
+		adapter->rx_ring_count = new_rx_count;
+		goto clear_reset;
+	}
 
-	adapter->tx_ring = tx_ring;
-	adapter->rx_ring = rx_ring;
+	set_tx = (new_tx_count != adapter->tx_ring_count);
+	set_rx = (new_rx_count != adapter->rx_ring_count);
 
-	rx_ring->count = max(ring->rx_pending, (u32)E1000_MIN_RXD);
-	rx_ring->count = min(rx_ring->count, (u32)(E1000_MAX_RXD));
-	rx_ring->count = ALIGN(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);
+	/* Allocate temporary storage for ring updates */
+	if (set_tx) {
+		temp_tx = vmalloc(size);
+		if (!temp_tx) {
+			err = -ENOMEM;
+			goto free_temp;
+		}
+	}
+	if (set_rx) {
+		temp_rx = vmalloc(size);
+		if (!temp_rx) {
+			err = -ENOMEM;
+			goto free_temp;
+		}
+	}
 
-	tx_ring->count = max(ring->tx_pending, (u32)E1000_MIN_TXD);
-	tx_ring->count = min(tx_ring->count, (u32)(E1000_MAX_TXD));
-	tx_ring->count = ALIGN(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+	e1000e_down(adapter);
 
-	if (netif_running(adapter->netdev)) {
-		/* Try to get new resources before deleting old */
-		err = e1000e_setup_rx_resources(adapter);
+	/*
+	 * We can't just free everything and then setup again, because the
+	 * ISRs in MSI-X mode get passed pointers to the Tx and Rx ring
+	 * structs.  First, attempt to allocate new resources...
+	 */
+	if (set_tx) {
+		memcpy(temp_tx, adapter->tx_ring, size);
+		temp_tx->count = new_tx_count;
+		err = e1000e_setup_tx_resources(temp_tx);
 		if (err)
-			goto err_setup_rx;
-		err = e1000e_setup_tx_resources(adapter);
+			goto err_setup;
+	}
+	if (set_rx) {
+		memcpy(temp_rx, adapter->rx_ring, size);
+		temp_rx->count = new_rx_count;
+		err = e1000e_setup_rx_resources(temp_rx);
 		if (err)
-			goto err_setup_tx;
+			goto err_setup_rx;
+	}
 
-		/*
-		 * restore the old in order to free it,
-		 * then add in the new
-		 */
-		adapter->rx_ring = rx_old;
-		adapter->tx_ring = tx_old;
-		e1000e_free_rx_resources(adapter);
-		e1000e_free_tx_resources(adapter);
-		kfree(tx_old);
-		kfree(rx_old);
-		adapter->rx_ring = rx_ring;
-		adapter->tx_ring = tx_ring;
-		err = e1000e_up(adapter);
-		if (err)
-			goto err_setup;
+	/* ...then free the old resources and copy back any new ring data */
+	if (set_tx) {
+		e1000e_free_tx_resources(adapter->tx_ring);
+		memcpy(adapter->tx_ring, temp_tx, size);
+		adapter->tx_ring_count = new_tx_count;
+	}
+	if (set_rx) {
+		e1000e_free_rx_resources(adapter->rx_ring);
+		memcpy(adapter->rx_ring, temp_rx, size);
+		adapter->rx_ring_count = new_rx_count;
 	}
 
-	clear_bit(__E1000_RESETTING, &adapter->state);
-	return 0;
-err_setup_tx:
-	e1000e_free_rx_resources(adapter);
 err_setup_rx:
-	adapter->rx_ring = rx_old;
-	adapter->tx_ring = tx_old;
-	kfree(rx_ring);
-err_alloc_rx:
-	kfree(tx_ring);
-err_alloc_tx:
-	e1000e_up(adapter);
+	if (err && set_tx)
+		e1000e_free_tx_resources(temp_tx);
 err_setup:
+	e1000e_up(adapter);
+free_temp:
+	vfree(temp_tx);
+	vfree(temp_rx);
+clear_reset:
 	clear_bit(__E1000_RESETTING, &adapter->state);
 	return err;
 }
@@ -1069,7 +1088,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 	tx_ring->buffer_info = kcalloc(tx_ring->count,
 				       sizeof(struct e1000_buffer),
 				       GFP_KERNEL);
-	if (!(tx_ring->buffer_info)) {
+	if (!tx_ring->buffer_info) {
 		ret_val = 1;
 		goto err_nomem;
 	}
@@ -1131,7 +1150,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 	rx_ring->buffer_info = kcalloc(rx_ring->count,
 				       sizeof(struct e1000_buffer),
 				       GFP_KERNEL);
-	if (!(rx_ring->buffer_info)) {
+	if (!rx_ring->buffer_info) {
 		ret_val = 5;
 		goto err_nomem;
 	}
@@ -1837,11 +1856,11 @@ static int e1000_set_phys_id(struct net_device *netdev,
 		break;
 
 	case ETHTOOL_ID_ON:
-		adapter->hw.mac.ops.led_on(&adapter->hw);
+		hw->mac.ops.led_on(hw);
 		break;
 
 	case ETHTOOL_ID_OFF:
-		adapter->hw.mac.ops.led_off(&adapter->hw);
+		hw->mac.ops.led_off(hw);
 		break;
 	}
 	return 0;
@@ -1955,6 +1974,53 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
 	}
 }
 
+static int e1000_get_rxnfc(struct net_device *netdev,
+			   struct ethtool_rxnfc *info, u32 *rule_locs)
+{
+	info->data = 0;
+
+	switch (info->cmd) {
+	case ETHTOOL_GRXFH: {
+		struct e1000_adapter *adapter = netdev_priv(netdev);
+		struct e1000_hw *hw = &adapter->hw;
+		u32 mrqc = er32(MRQC);
+
+		if (!(mrqc & E1000_MRQC_RSS_FIELD_MASK))
+			return 0;
+
+		switch (info->flow_type) {
+		case TCP_V4_FLOW:
+			if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP)
+				info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+			/* fall through */
+		case UDP_V4_FLOW:
+		case SCTP_V4_FLOW:
+		case AH_ESP_V4_FLOW:
+		case IPV4_FLOW:
+			if (mrqc & E1000_MRQC_RSS_FIELD_IPV4)
+				info->data |= RXH_IP_SRC | RXH_IP_DST;
+			break;
+		case TCP_V6_FLOW:
+			if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP)
+				info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+			/* fall through */
+		case UDP_V6_FLOW:
+		case SCTP_V6_FLOW:
+		case AH_ESP_V6_FLOW:
+		case IPV6_FLOW:
+			if (mrqc & E1000_MRQC_RSS_FIELD_IPV6)
+				info->data |= RXH_IP_SRC | RXH_IP_DST;
+			break;
+		default:
+			break;
+		}
+		return 0;
+	}
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static const struct ethtool_ops e1000_ethtool_ops = {
 	.get_settings		= e1000_get_settings,
 	.set_settings		= e1000_set_settings,
@@ -1981,6 +2047,7 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.get_sset_count		= e1000e_get_sset_count,
 	.get_coalesce		= e1000_get_coalesce,
 	.set_coalesce		= e1000_set_coalesce,
+	.get_rxnfc		= e1000_get_rxnfc,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
index 2967039..197059b 100644
--- a/drivers/net/ethernet/intel/e1000e/hw.h
+++ b/drivers/net/ethernet/intel/e1000e/hw.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -204,6 +204,7 @@ enum e1e_registers {
 	E1000_WUC      = 0x05800, /* Wakeup Control - RW */
 	E1000_WUFC     = 0x05808, /* Wakeup Filter Control - RW */
 	E1000_WUS      = 0x05810, /* Wakeup Status - RO */
+	E1000_MRQC     = 0x05818, /* Multiple Receive Control - RW */
 	E1000_MANC     = 0x05820, /* Management Control - RW */
 	E1000_FFLT     = 0x05F00, /* Flexible Filter Length Table - RW Array */
 	E1000_HOST_IF  = 0x08800, /* Host Interface */
@@ -219,6 +220,10 @@ enum e1e_registers {
 	E1000_SWSM      = 0x05B50, /* SW Semaphore */
 	E1000_FWSM      = 0x05B54, /* FW Semaphore */
 	E1000_SWSM2     = 0x05B58, /* Driver-only SW semaphore */
+	E1000_RETA_BASE = 0x05C00, /* Redirection Table - RW */
+#define E1000_RETA(_n)	(E1000_RETA_BASE + ((_n) * 4))
+	E1000_RSSRK_BASE = 0x05C80, /* RSS Random Key - RW */
+#define E1000_RSSRK(_n)	(E1000_RSSRK_BASE + ((_n) * 4))
 	E1000_FFLT_DBG  = 0x05F04, /* Debug Register */
 	E1000_PCH_RAICC_BASE = 0x05F50, /* Receive Address Initial CRC */
 #define E1000_PCH_RAICC(_n)	(E1000_PCH_RAICC_BASE + ((_n) * 4))
@@ -964,8 +969,8 @@ struct e1000_dev_spec_ich8lan {
 struct e1000_hw {
 	struct e1000_adapter *adapter;
 
-	u8 __iomem *hw_addr;
-	u8 __iomem *flash_address;
+	void __iomem *hw_addr;
+	void __iomem *flash_address;
 
 	struct e1000_mac_info  mac;
 	struct e1000_fc_info   fc;
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index e2a80a2..f3282dc 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -145,6 +145,8 @@
 #define I82579_EMI_ADDR         0x10
 #define I82579_EMI_DATA         0x11
 #define I82579_LPI_UPDATE_TIMER 0x4805	/* in 40ns units + 40 ns base value */
+#define I82579_MSE_THRESHOLD    0x084F	/* Mean Square Error Threshold */
+#define I82579_MSE_LINK_DOWN    0x2411	/* MSE count before dropping link */
 
 /* Strapping Option Register - RO */
 #define E1000_STRAP                     0x0000C
@@ -278,8 +280,8 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
 
 #define er16flash(reg)		__er16flash(hw, (reg))
 #define er32flash(reg)		__er32flash(hw, (reg))
-#define ew16flash(reg,val)	__ew16flash(hw, (reg), (val))
-#define ew32flash(reg,val)	__ew32flash(hw, (reg), (val))
+#define ew16flash(reg, val)	__ew16flash(hw, (reg), (val))
+#define ew32flash(reg, val)	__ew32flash(hw, (reg), (val))
 
 static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw)
 {
@@ -304,7 +306,6 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw)
 static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	u32 fwsm;
 	s32 ret_val = 0;
 
 	phy->addr                     = 1;
@@ -323,14 +324,14 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 	phy->ops.power_down           = e1000_power_down_phy_copper_ich8lan;
 	phy->autoneg_mask             = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
-	/*
-	 * The MAC-PHY interconnect may still be in SMBus mode
-	 * after Sx->S0.  If the manageability engine (ME) is
-	 * disabled, then toggle the LANPHYPC Value bit to force
-	 * the interconnect to PCIe mode.
-	 */
-	fwsm = er32(FWSM);
-	if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) {
+	if (!e1000_check_reset_block(hw)) {
+		u32 fwsm = er32(FWSM);
+
+		/*
+		 * The MAC-PHY interconnect may still be in SMBus mode after
+		 * Sx->S0.  If resetting the PHY is not blocked, toggle the
+		 * LANPHYPC Value bit to force the interconnect to PCIe mode.
+		 */
 		e1000_toggle_lanphypc_value_ich8lan(hw);
 		msleep(50);
 
@@ -338,25 +339,26 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 		 * Gate automatic PHY configuration by hardware on
 		 * non-managed 82579
 		 */
-		if (hw->mac.type == e1000_pch2lan)
+		if ((hw->mac.type == e1000_pch2lan) &&
+		    !(fwsm & E1000_ICH_FWSM_FW_VALID))
 			e1000_gate_hw_phy_config_ich8lan(hw, true);
-	}
 
-	/*
-	 * Reset the PHY before any access to it.  Doing so, ensures that
-	 * the PHY is in a known good state before we read/write PHY registers.
-	 * The generic reset is sufficient here, because we haven't determined
-	 * the PHY type yet.
-	 */
-	ret_val = e1000e_phy_hw_reset_generic(hw);
-	if (ret_val)
-		goto out;
+		/*
+		 * Reset the PHY before any access to it.  Doing so, ensures
+		 * that the PHY is in a known good state before we read/write
+		 * PHY registers.  The generic reset is sufficient here,
+		 * because we haven't determined the PHY type yet.
+		 */
+		ret_val = e1000e_phy_hw_reset_generic(hw);
+		if (ret_val)
+			return ret_val;
 
-	/* Ungate automatic PHY configuration on non-managed 82579 */
-	if ((hw->mac.type == e1000_pch2lan) &&
-	    !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
-		usleep_range(10000, 20000);
-		e1000_gate_hw_phy_config_ich8lan(hw, false);
+		/* Ungate automatic PHY configuration on non-managed 82579 */
+		if ((hw->mac.type == e1000_pch2lan) &&
+		    !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
+			usleep_range(10000, 20000);
+			e1000_gate_hw_phy_config_ich8lan(hw, false);
+		}
 	}
 
 	phy->id = e1000_phy_unknown;
@@ -364,7 +366,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 	default:
 		ret_val = e1000e_get_phy_id(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK))
 			break;
 		/* fall-through */
@@ -375,10 +377,10 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 		 */
 		ret_val = e1000_set_mdio_slow_mode_hv(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1000e_get_phy_id(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		break;
 	}
 	phy->type = e1000e_get_phy_type_from_id(phy->id);
@@ -404,7 +406,6 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 		break;
 	}
 
-out:
 	return ret_val;
 }
 
@@ -551,9 +552,8 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
  *  Initialize family-specific MAC parameters and function
  *  pointers.
  **/
-static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
+static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
 
 	/* Set media type function pointer */
@@ -634,20 +634,18 @@ static s32 e1000_set_eee_pchlan(struct e1000_hw *hw)
 	u16 phy_reg;
 
 	if (hw->phy.type != e1000_phy_82579)
-		goto out;
+		return 0;
 
 	ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (hw->dev_spec.ich8lan.eee_disable)
 		phy_reg &= ~I82579_LPI_CTRL_ENABLE_MASK;
 	else
 		phy_reg |= I82579_LPI_CTRL_ENABLE_MASK;
 
-	ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
-out:
-	return ret_val;
+	return e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
 }
 
 /**
@@ -671,10 +669,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	 * get_link_status flag is set upon receiving a Link Status
 	 * Change or Rx Sequence Error interrupt.
 	 */
-	if (!mac->get_link_status) {
-		ret_val = 0;
-		goto out;
-	}
+	if (!mac->get_link_status)
+		return 0;
 
 	/*
 	 * First we want to see if the MII Status Register reports
@@ -683,16 +679,16 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	 */
 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (hw->mac.type == e1000_pchlan) {
 		ret_val = e1000_k1_gig_workaround_hv(hw, link);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	if (!link)
-		goto out; /* No link detected */
+		return 0; /* No link detected */
 
 	mac->get_link_status = false;
 
@@ -700,13 +696,13 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	case e1000_pch2lan:
 		ret_val = e1000_k1_workaround_lv(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		/* fall-thru */
 	case e1000_pchlan:
 		if (hw->phy.type == e1000_phy_82578) {
 			ret_val = e1000_link_stall_workaround_hv(hw);
 			if (ret_val)
-				goto out;
+				return ret_val;
 		}
 
 		/*
@@ -736,16 +732,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	/* Enable/Disable EEE after link up */
 	ret_val = e1000_set_eee_pchlan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/*
 	 * If we are forcing speed/duplex, then we simply return since
 	 * we have already determined whether we have link or not.
 	 */
-	if (!mac->autoneg) {
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
-	}
+	if (!mac->autoneg)
+		return -E1000_ERR_CONFIG;
 
 	/*
 	 * Auto-Neg is enabled.  Auto Speed Detection takes care
@@ -764,7 +758,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 	if (ret_val)
 		e_dbg("Error configuring flow control\n");
 
-out:
 	return ret_val;
 }
 
@@ -773,7 +766,7 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	s32 rc;
 
-	rc = e1000_init_mac_params_ich8lan(adapter);
+	rc = e1000_init_mac_params_ich8lan(hw);
 	if (rc)
 		return rc;
 
@@ -900,8 +893,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 	}
 
 	if (!timeout) {
-		e_dbg("Failed to acquire the semaphore, FW or HW has it: "
-		      "FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n",
+		e_dbg("Failed to acquire the semaphore, FW or HW has it: FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n",
 		      er32(FWSM), extcnf_ctrl);
 		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
 		ew32(EXTCNF_CTRL, extcnf_ctrl);
@@ -1008,15 +1000,13 @@ static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
 
 	ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy_data &= ~HV_SMB_ADDR_MASK;
 	phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
 	phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
-	ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
 
-out:
-	return ret_val;
+	return e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
 }
 
 /**
@@ -1065,7 +1055,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 
 	data = er32(FEXTNVM);
 	if (!(data & sw_cfg_mask))
-		goto out;
+		goto release;
 
 	/*
 	 * Make sure HW does not configure LCD from PHY
@@ -1074,14 +1064,14 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 	data = er32(EXTCNF_CTRL);
 	if (!(hw->mac.type == e1000_pch2lan)) {
 		if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
-			goto out;
+			goto release;
 	}
 
 	cnf_size = er32(EXTCNF_SIZE);
 	cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
 	cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
 	if (!cnf_size)
-		goto out;
+		goto release;
 
 	cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
 	cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
@@ -1097,13 +1087,13 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 		 */
 		ret_val = e1000_write_smbus_addr(hw);
 		if (ret_val)
-			goto out;
+			goto release;
 
 		data = er32(LEDCTL);
 		ret_val = e1000_write_phy_reg_hv_locked(hw, HV_LED_CONFIG,
 							(u16)data);
 		if (ret_val)
-			goto out;
+			goto release;
 	}
 
 	/* Configure LCD from extended configuration region. */
@@ -1115,12 +1105,12 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 		ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1,
 					 &reg_data);
 		if (ret_val)
-			goto out;
+			goto release;
 
 		ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1),
 					 1, &reg_addr);
 		if (ret_val)
-			goto out;
+			goto release;
 
 		/* Save off the PHY page for future writes. */
 		if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
@@ -1134,10 +1124,10 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 		ret_val = phy->ops.write_reg_locked(hw, (u32)reg_addr,
 						    reg_data);
 		if (ret_val)
-			goto out;
+			goto release;
 	}
 
-out:
+release:
 	hw->phy.ops.release(hw);
 	return ret_val;
 }
@@ -1159,12 +1149,12 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
 	bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled;
 
 	if (hw->mac.type != e1000_pchlan)
-		goto out;
+		return 0;
 
 	/* Wrap the whole flow with the sw flag */
 	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
 	if (link) {
@@ -1218,7 +1208,7 @@ static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
 
 release:
 	hw->phy.ops.release(hw);
-out:
+
 	return ret_val;
 }
 
@@ -1244,7 +1234,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
 	                                     E1000_KMRNCTRLSTA_K1_CONFIG,
 	                                     &kmrn_reg);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (k1_enable)
 		kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE;
@@ -1255,7 +1245,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
 	                                      E1000_KMRNCTRLSTA_K1_CONFIG,
 	                                      kmrn_reg);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	udelay(20);
 	ctrl_ext = er32(CTRL_EXT);
@@ -1273,8 +1263,7 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
 	e1e_flush();
 	udelay(20);
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -1302,18 +1291,18 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
 	if (!(hw->mac.type == e1000_pch2lan)) {
 		mac_reg = er32(EXTCNF_CTRL);
 		if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
-			goto out;
+			goto release;
 	}
 
 	mac_reg = er32(FEXTNVM);
 	if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M))
-		goto out;
+		goto release;
 
 	mac_reg = er32(PHY_CTRL);
 
 	ret_val = hw->phy.ops.read_reg_locked(hw, HV_OEM_BITS, &oem_reg);
 	if (ret_val)
-		goto out;
+		goto release;
 
 	oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU);
 
@@ -1339,7 +1328,7 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
 
 	ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg);
 
-out:
+release:
 	hw->phy.ops.release(hw);
 
 	return ret_val;
@@ -1376,13 +1365,13 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 	u16 phy_data;
 
 	if (hw->mac.type != e1000_pchlan)
-		return ret_val;
+		return 0;
 
 	/* Set MDIO slow mode before any other MDIO access */
 	if (hw->phy.type == e1000_phy_82577) {
 		ret_val = e1000_set_mdio_slow_mode_hv(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	if (((hw->phy.type == e1000_phy_82577) &&
@@ -1419,7 +1408,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
 	hw->phy.ops.release(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/*
 	 * Configure the K1 Si workaround during phy reset assuming there is
@@ -1427,12 +1416,12 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 	 */
 	ret_val = e1000_k1_gig_workaround_hv(hw, true);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Workaround for link disconnects on a busy hub in half duplex */
 	ret_val = hw->phy.ops.acquire(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 	ret_val = hw->phy.ops.read_reg_locked(hw, BM_PORT_GEN_CFG, &phy_data);
 	if (ret_val)
 		goto release;
@@ -1440,7 +1429,7 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 					       phy_data & 0x00FF);
 release:
 	hw->phy.ops.release(hw);
-out:
+
 	return ret_val;
 }
 
@@ -1497,13 +1486,13 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 	u16 i;
 
 	if (hw->mac.type != e1000_pch2lan)
-		goto out;
+		return 0;
 
 	/* disable Rx path while enabling/disabling workaround */
 	e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
 	ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg | (1 << 14));
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (enable) {
 		/*
@@ -1545,24 +1534,24 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 						E1000_KMRNCTRLSTA_CTRL_OFFSET,
 						&data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1000e_write_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_CTRL_OFFSET,
 						data | (1 << 0));
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1000e_read_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_HD_CTRL,
 						&data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		data &= ~(0xF << 8);
 		data |= (0xB << 8);
 		ret_val = e1000e_write_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_HD_CTRL,
 						data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		/* Enable jumbo frame workaround in the PHY */
 		e1e_rphy(hw, PHY_REG(769, 23), &data);
@@ -1570,25 +1559,25 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 		data |= (0x37 << 5);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		e1e_rphy(hw, PHY_REG(769, 16), &data);
 		data &= ~(1 << 13);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		e1e_rphy(hw, PHY_REG(776, 20), &data);
 		data &= ~(0x3FF << 2);
 		data |= (0x1A << 2);
 		ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0xF100);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		e1e_rphy(hw, HV_PM_CTRL, &data);
 		ret_val = e1e_wphy(hw, HV_PM_CTRL, data | (1 << 10));
 		if (ret_val)
-			goto out;
+			return ret_val;
 	} else {
 		/* Write MAC register values back to h/w defaults */
 		mac_reg = er32(FFLT_DBG);
@@ -1603,56 +1592,53 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 						E1000_KMRNCTRLSTA_CTRL_OFFSET,
 						&data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1000e_write_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_CTRL_OFFSET,
 						data & ~(1 << 0));
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1000e_read_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_HD_CTRL,
 						&data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		data &= ~(0xF << 8);
 		data |= (0xB << 8);
 		ret_val = e1000e_write_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_HD_CTRL,
 						data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		/* Write PHY register values back to h/w defaults */
 		e1e_rphy(hw, PHY_REG(769, 23), &data);
 		data &= ~(0x7F << 5);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		e1e_rphy(hw, PHY_REG(769, 16), &data);
 		data |= (1 << 13);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		e1e_rphy(hw, PHY_REG(776, 20), &data);
 		data &= ~(0x3FF << 2);
 		data |= (0x8 << 2);
 		ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0x7E00);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		e1e_rphy(hw, HV_PM_CTRL, &data);
 		ret_val = e1e_wphy(hw, HV_PM_CTRL, data & ~(1 << 10));
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	/* re-enable Rx path after enabling/disabling workaround */
-	ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14));
-
-out:
-	return ret_val;
+	return e1e_wphy(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14));
 }
 
 /**
@@ -1664,12 +1650,31 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw)
 	s32 ret_val = 0;
 
 	if (hw->mac.type != e1000_pch2lan)
-		goto out;
+		return 0;
 
 	/* Set MDIO slow mode before any other MDIO access */
 	ret_val = e1000_set_mdio_slow_mode_hv(hw);
 
-out:
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val)
+		return ret_val;
+	ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR,
+					       I82579_MSE_THRESHOLD);
+	if (ret_val)
+		goto release;
+	/* set MSE higher to enable link to stay up when noise is high */
+	ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0034);
+	if (ret_val)
+		goto release;
+	ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR,
+					       I82579_MSE_LINK_DOWN);
+	if (ret_val)
+		goto release;
+	/* drop link after 5 times MSE threshold was reached */
+	ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0005);
+release:
+	hw->phy.ops.release(hw);
+
 	return ret_val;
 }
 
@@ -1687,12 +1692,12 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
 	u16 phy_reg;
 
 	if (hw->mac.type != e1000_pch2lan)
-		goto out;
+		return 0;
 
 	/* Set K1 beacon duration based on 1Gbps speed or otherwise */
 	ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
 	    == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
@@ -1701,7 +1706,7 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
 
 		ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		if (status_reg & HV_M_STATUS_SPEED_1000) {
 			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
@@ -1714,7 +1719,6 @@ static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
 		ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg);
 	}
 
-out:
 	return ret_val;
 }
 
@@ -1741,7 +1745,6 @@ static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
 		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG;
 
 	ew32(EXTCNF_CTRL, extcnf_ctrl);
-	return;
 }
 
 /**
@@ -1786,7 +1789,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
 	u16 reg;
 
 	if (e1000_check_reset_block(hw))
-		goto out;
+		return 0;
 
 	/* Allow time for h/w to get to quiescent state after reset */
 	usleep_range(10000, 20000);
@@ -1796,12 +1799,12 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
 	case e1000_pchlan:
 		ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		break;
 	case e1000_pch2lan:
 		ret_val = e1000_lv_phy_workarounds_ich8lan(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		break;
 	default:
 		break;
@@ -1817,7 +1820,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
 	/* Configure the LCD with the extended configuration region in NVM */
 	ret_val = e1000_sw_lcd_config_ich8lan(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Configure the LCD with the OEM bits in NVM */
 	ret_val = e1000_oem_bits_config_ich8lan(hw, true);
@@ -1832,18 +1835,16 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
 		/* Set EEE LPI Update Timer to 200usec */
 		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 		ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR,
 						       I82579_LPI_UPDATE_TIMER);
-		if (ret_val)
-			goto release;
-		ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA,
-						       0x1387);
-release:
+		if (!ret_val)
+			ret_val = hw->phy.ops.write_reg_locked(hw,
+							       I82579_EMI_DATA,
+							       0x1387);
 		hw->phy.ops.release(hw);
 	}
 
-out:
 	return ret_val;
 }
 
@@ -1866,12 +1867,9 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 
 	ret_val = e1000e_phy_hw_reset_generic(hw);
 	if (ret_val)
-		goto out;
-
-	ret_val = e1000_post_phy_reset_ich8lan(hw);
+		return ret_val;
 
-out:
-	return ret_val;
+	return e1000_post_phy_reset_ich8lan(hw);
 }
 
 /**
@@ -1892,18 +1890,17 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active)
 
 	ret_val = e1e_rphy(hw, HV_OEM_BITS, &oem_reg);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (active)
 		oem_reg |= HV_OEM_BITS_LPLU;
 	else
 		oem_reg &= ~HV_OEM_BITS_LPLU;
 
-	oem_reg |= HV_OEM_BITS_RESTART_AN;
-	ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg);
+	if (!e1000_check_reset_block(hw))
+		oem_reg |= HV_OEM_BITS_RESTART_AN;
 
-out:
-	return ret_val;
+	return e1e_wphy(hw, HV_OEM_BITS, oem_reg);
 }
 
 /**
@@ -1927,7 +1924,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 	u16 data;
 
 	if (phy->type == e1000_phy_ife)
-		return ret_val;
+		return 0;
 
 	phy_ctrl = er32(PHY_CTRL);
 
@@ -2009,7 +2006,7 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	u32 phy_ctrl;
-	s32 ret_val;
+	s32 ret_val = 0;
 	u16 data;
 
 	phy_ctrl = er32(PHY_CTRL);
@@ -2075,7 +2072,7 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
 	}
 
-	return 0;
+	return ret_val;
 }
 
 /**
@@ -2093,7 +2090,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
 	u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
 	u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
 	u8 sig_byte = 0;
-	s32 ret_val = 0;
+	s32 ret_val;
 
 	switch (hw->mac.type) {
 	case e1000_ich8lan:
@@ -2108,8 +2105,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
 
 			return 0;
 		}
-		e_dbg("Unable to determine valid NVM bank via EEC - "
-		       "reading flash signature\n");
+		e_dbg("Unable to determine valid NVM bank via EEC - reading flash signature\n");
 		/* fall-thru */
 	default:
 		/* set bank to 0 in case flash read fails */
@@ -2141,8 +2137,6 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
 		e_dbg("ERROR: No valid NVM bank present\n");
 		return -E1000_ERR_NVM;
 	}
-
-	return 0;
 }
 
 /**
@@ -2221,8 +2215,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 
 	/* Check if the flash descriptor is valid */
 	if (hsfsts.hsf_status.fldesvalid == 0) {
-		e_dbg("Flash descriptor invalid.  "
-			 "SW Sequencing must be used.\n");
+		e_dbg("Flash descriptor invalid.  SW Sequencing must be used.\n");
 		return -E1000_ERR_NVM;
 	}
 
@@ -2251,21 +2244,21 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 		ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 		ret_val = 0;
 	} else {
-		s32 i = 0;
+		s32 i;
 
 		/*
 		 * Otherwise poll for sometime so the current
 		 * cycle has a chance to end before giving up.
 		 */
 		for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
-			hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS);
+			hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
 			if (hsfsts.hsf_status.flcinprog == 0) {
 				ret_val = 0;
 				break;
 			}
 			udelay(1);
 		}
-		if (ret_val == 0) {
+		if (!ret_val) {
 			/*
 			 * Successful in waiting for previous cycle to timeout,
 			 * now set the Flash Cycle Done.
@@ -2291,7 +2284,6 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
 {
 	union ich8_hws_flash_ctrl hsflctl;
 	union ich8_hws_flash_status hsfsts;
-	s32 ret_val = -E1000_ERR_NVM;
 	u32 i = 0;
 
 	/* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
@@ -2310,7 +2302,7 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout)
 	if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0)
 		return 0;
 
-	return ret_val;
+	return -E1000_ERR_NVM;
 }
 
 /**
@@ -2383,7 +2375,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 		udelay(1);
 		/* Steps */
 		ret_val = e1000_flash_cycle_init_ich8lan(hw);
-		if (ret_val != 0)
+		if (ret_val)
 			break;
 
 		hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
@@ -2403,7 +2395,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 		 * read in (shift in) the Flash Data0, the order is
 		 * least significant byte first msb to lsb
 		 */
-		if (ret_val == 0) {
+		if (!ret_val) {
 			flash_data = er32flash(ICH_FLASH_FDATA0);
 			if (size == 1)
 				*data = (u8)(flash_data & 0x000000FF);
@@ -2422,8 +2414,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 				/* Repeat for some time before giving up. */
 				continue;
 			} else if (hsfsts.hsf_status.flcdone == 0) {
-				e_dbg("Timeout error - flash cycle "
-					 "did not complete.\n");
+				e_dbg("Timeout error - flash cycle did not complete.\n");
 				break;
 			}
 		}
@@ -2774,8 +2765,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 			/* Repeat for some time before giving up. */
 			continue;
 		if (hsfsts.hsf_status.flcdone == 0) {
-			e_dbg("Timeout error - flash cycle "
-				 "did not complete.");
+			e_dbg("Timeout error - flash cycle did not complete.\n");
 			break;
 		}
 	} while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT);
@@ -2917,7 +2907,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 
 			ret_val = e1000_flash_cycle_ich8lan(hw,
 					       ICH_FLASH_ERASE_COMMAND_TIMEOUT);
-			if (ret_val == 0)
+			if (!ret_val)
 				break;
 
 			/*
@@ -2987,7 +2977,7 @@ static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
 	/* Get default ID LED modes */
 	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	mac->ledctl_default = er32(LEDCTL);
 	mac->ledctl_mode1 = mac->ledctl_default;
@@ -3032,8 +3022,7 @@ static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
 		}
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -3148,11 +3137,11 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 	if (ctrl & E1000_CTRL_PHY_RST) {
 		ret_val = hw->phy.ops.get_cfg_done(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = e1000_post_phy_reset_ich8lan(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	/*
@@ -3170,8 +3159,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 	kab |= E1000_KABGTXD_BGSQLBIAS;
 	ew32(KABGTXD, kab);
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -3262,7 +3250,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
 	 */
 	e1000_clear_hw_cntrs_ich8lan(hw);
 
-	return 0;
+	return ret_val;
 }
 /**
  *  e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits
@@ -3465,6 +3453,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
 	default:
 		break;
 	}
+
 	return e1000e_setup_copper_link(hw);
 }
 
@@ -3676,9 +3665,10 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
  *
  *  During S0 to Sx transition, it is possible the link remains at gig
  *  instead of negotiating to a lower speed.  Before going to Sx, set
- *  'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
- *  to a lower speed.  For PCH and newer parts, the OEM bits PHY register
- *  (LED, GbE disable and LPLU configurations) also needs to be written.
+ *  'Gig Disable' to force link speed negotiation to a lower speed based on
+ *  the LPLU setting in the NVM or custom setting.  For PCH and newer parts,
+ *  the OEM bits PHY register (LED, GbE disable and LPLU configurations) also
+ *  needs to be written.
  **/
 void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
 {
@@ -3686,7 +3676,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
 	s32 ret_val;
 
 	phy_ctrl = er32(PHY_CTRL);
-	phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE;
+	phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE;
 	ew32(PHY_CTRL, phy_ctrl);
 
 	if (hw->mac.type == e1000_ich8lan)
@@ -3714,47 +3704,40 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
  **/
 void e1000_resume_workarounds_pchlan(struct e1000_hw *hw)
 {
-	u32 fwsm;
+	u16 phy_id1, phy_id2;
+	s32 ret_val;
 
-	if (hw->mac.type != e1000_pch2lan)
+	if ((hw->mac.type != e1000_pch2lan) || e1000_check_reset_block(hw))
 		return;
 
-	fwsm = er32(FWSM);
-	if (!(fwsm & E1000_ICH_FWSM_FW_VALID) || !e1000_check_reset_block(hw)) {
-		u16 phy_id1, phy_id2;
-		s32 ret_val;
-
-		ret_val = hw->phy.ops.acquire(hw);
-		if (ret_val) {
-			e_dbg("Failed to acquire PHY semaphore in resume\n");
-			return;
-		}
+	ret_val = hw->phy.ops.acquire(hw);
+	if (ret_val) {
+		e_dbg("Failed to acquire PHY semaphore in resume\n");
+		return;
+	}
 
-		/* Test access to the PHY registers by reading the ID regs */
-		ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1);
-		if (ret_val)
-			goto release;
-		ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2);
-		if (ret_val)
-			goto release;
+	/* Test access to the PHY registers by reading the ID regs */
+	ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1);
+	if (ret_val)
+		goto release;
+	ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2);
+	if (ret_val)
+		goto release;
 
-		if (hw->phy.id == ((u32)(phy_id1 << 16) |
-				   (u32)(phy_id2 & PHY_REVISION_MASK)))
-			goto release;
+	if (hw->phy.id == ((u32)(phy_id1 << 16) |
+			   (u32)(phy_id2 & PHY_REVISION_MASK)))
+		goto release;
 
-		e1000_toggle_lanphypc_value_ich8lan(hw);
+	e1000_toggle_lanphypc_value_ich8lan(hw);
 
-		hw->phy.ops.release(hw);
-		msleep(50);
-		e1000_phy_hw_reset(hw);
-		msleep(50);
-		return;
-	}
+	hw->phy.ops.release(hw);
+	msleep(50);
+	e1000_phy_hw_reset(hw);
+	msleep(50);
+	return;
 
 release:
 	hw->phy.ops.release(hw);
-
-	return;
 }
 
 /**
@@ -4088,10 +4071,9 @@ const struct e1000_info e1000_ich9_info = {
 				  | FLAG_HAS_WOL
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
 				  | FLAG_HAS_AMT
-				  | FLAG_HAS_ERT
 				  | FLAG_HAS_FLASH
 				  | FLAG_APME_IN_WUC,
-	.pba			= 10,
+	.pba			= 18,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
 	.get_variants		= e1000_get_variants_ich8lan,
 	.mac_ops		= &ich8_mac_ops,
@@ -4106,10 +4088,9 @@ const struct e1000_info e1000_ich10_info = {
 				  | FLAG_HAS_WOL
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
 				  | FLAG_HAS_AMT
-				  | FLAG_HAS_ERT
 				  | FLAG_HAS_FLASH
 				  | FLAG_APME_IN_WUC,
-	.pba			= 10,
+	.pba			= 18,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
 	.get_variants		= e1000_get_variants_ich8lan,
 	.mac_ops		= &ich8_mac_ops,
diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c
deleted file mode 100644
index 0893ab1..0000000
--- a/drivers/net/ethernet/intel/e1000e/lib.c
+++ /dev/null
@@ -1,2693 +0,0 @@
-/*******************************************************************************
-
-  Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
-
-  This program is free software; you can redistribute it and/or modify it
-  under the terms and conditions of the GNU General Public License,
-  version 2, as published by the Free Software Foundation.
-
-  This program is distributed in the hope 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.,
-  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-  The full GNU General Public License is included in this distribution in
-  the file called "COPYING".
-
-  Contact Information:
-  Linux NICS <linux.nics@intel.com>
-  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include "e1000.h"
-
-enum e1000_mng_mode {
-	e1000_mng_mode_none = 0,
-	e1000_mng_mode_asf,
-	e1000_mng_mode_pt,
-	e1000_mng_mode_ipmi,
-	e1000_mng_mode_host_if_only
-};
-
-#define E1000_FACTPS_MNGCG		0x20000000
-
-/* Intel(R) Active Management Technology signature */
-#define E1000_IAMT_SIGNATURE		0x544D4149
-
-/**
- *  e1000e_get_bus_info_pcie - Get PCIe bus information
- *  @hw: pointer to the HW structure
- *
- *  Determines and stores the system bus information for a particular
- *  network interface.  The following bus information is determined and stored:
- *  bus speed, bus width, type (PCIe), and PCIe function.
- **/
-s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	struct e1000_bus_info *bus = &hw->bus;
-	struct e1000_adapter *adapter = hw->adapter;
-	u16 pcie_link_status, cap_offset;
-
-	cap_offset = adapter->pdev->pcie_cap;
-	if (!cap_offset) {
-		bus->width = e1000_bus_width_unknown;
-	} else {
-		pci_read_config_word(adapter->pdev,
-				     cap_offset + PCIE_LINK_STATUS,
-				     &pcie_link_status);
-		bus->width = (enum e1000_bus_width)((pcie_link_status &
-						     PCIE_LINK_WIDTH_MASK) >>
-						    PCIE_LINK_WIDTH_SHIFT);
-	}
-
-	mac->ops.set_lan_id(hw);
-
-	return 0;
-}
-
-/**
- *  e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
- *
- *  @hw: pointer to the HW structure
- *
- *  Determines the LAN function id by reading memory-mapped registers
- *  and swaps the port value if requested.
- **/
-void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
-{
-	struct e1000_bus_info *bus = &hw->bus;
-	u32 reg;
-
-	/*
-	 * The status register reports the correct function number
-	 * for the device regardless of function swap state.
-	 */
-	reg = er32(STATUS);
-	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
-}
-
-/**
- *  e1000_set_lan_id_single_port - Set LAN id for a single port device
- *  @hw: pointer to the HW structure
- *
- *  Sets the LAN function id to zero for a single port device.
- **/
-void e1000_set_lan_id_single_port(struct e1000_hw *hw)
-{
-	struct e1000_bus_info *bus = &hw->bus;
-
-	bus->func = 0;
-}
-
-/**
- *  e1000_clear_vfta_generic - Clear VLAN filter table
- *  @hw: pointer to the HW structure
- *
- *  Clears the register array which contains the VLAN filter table by
- *  setting all the values to 0.
- **/
-void e1000_clear_vfta_generic(struct e1000_hw *hw)
-{
-	u32 offset;
-
-	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
-		e1e_flush();
-	}
-}
-
-/**
- *  e1000_write_vfta_generic - Write value to VLAN filter table
- *  @hw: pointer to the HW structure
- *  @offset: register offset in VLAN filter table
- *  @value: register value written to VLAN filter table
- *
- *  Writes value at the given offset in the register array which stores
- *  the VLAN filter table.
- **/
-void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
-{
-	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
-	e1e_flush();
-}
-
-/**
- *  e1000e_init_rx_addrs - Initialize receive address's
- *  @hw: pointer to the HW structure
- *  @rar_count: receive address registers
- *
- *  Setup the receive address registers by setting the base receive address
- *  register to the devices MAC address and clearing all the other receive
- *  address registers to 0.
- **/
-void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
-{
-	u32 i;
-	u8 mac_addr[ETH_ALEN] = {0};
-
-	/* Setup the receive address */
-	e_dbg("Programming MAC Address into RAR[0]\n");
-
-	e1000e_rar_set(hw, hw->mac.addr, 0);
-
-	/* Zero out the other (rar_entry_count - 1) receive addresses */
-	e_dbg("Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++)
-		e1000e_rar_set(hw, mac_addr, i);
-}
-
-/**
- *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
- *  @hw: pointer to the HW structure
- *
- *  Checks the nvm for an alternate MAC address.  An alternate MAC address
- *  can be setup by pre-boot software and must be treated like a permanent
- *  address and must override the actual permanent MAC address. If an
- *  alternate MAC address is found it is programmed into RAR0, replacing
- *  the permanent address that was installed into RAR0 by the Si on reset.
- *  This function will return SUCCESS unless it encounters an error while
- *  reading the EEPROM.
- **/
-s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
-{
-	u32 i;
-	s32 ret_val = 0;
-	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
-	u8 alt_mac_addr[ETH_ALEN];
-
-	ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
-	if (ret_val)
-		goto out;
-
-	/* Check for LOM (vs. NIC) or one of two valid mezzanine cards */
-	if (!((nvm_data & NVM_COMPAT_LOM) ||
-	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) ||
-	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) ||
-	      (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES)))
-		goto out;
-
-	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
-	                         &nvm_alt_mac_addr_offset);
-	if (ret_val) {
-		e_dbg("NVM Read Error\n");
-		goto out;
-	}
-
-	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
-	    (nvm_alt_mac_addr_offset == 0x0000))
-		/* There is no Alternate MAC Address */
-		goto out;
-
-	if (hw->bus.func == E1000_FUNC_1)
-		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
-	for (i = 0; i < ETH_ALEN; i += 2) {
-		offset = nvm_alt_mac_addr_offset + (i >> 1);
-		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
-		if (ret_val) {
-			e_dbg("NVM Read Error\n");
-			goto out;
-		}
-
-		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
-		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
-	}
-
-	/* if multicast bit is set, the alternate address will not be used */
-	if (is_multicast_ether_addr(alt_mac_addr)) {
-		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
-		goto out;
-	}
-
-	/*
-	 * We have a valid alternate MAC address, and we want to treat it the
-	 * same as the normal permanent MAC address stored by the HW into the
-	 * RAR. Do this by mapping this address into RAR0.
-	 */
-	e1000e_rar_set(hw, alt_mac_addr, 0);
-
-out:
-	return ret_val;
-}
-
-/**
- *  e1000e_rar_set - Set receive address register
- *  @hw: pointer to the HW structure
- *  @addr: pointer to the receive address
- *  @index: receive address array register
- *
- *  Sets the receive address array register at index to the address passed
- *  in by addr.
- **/
-void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
-{
-	u32 rar_low, rar_high;
-
-	/*
-	 * HW expects these in little endian so we reverse the byte order
-	 * from network order (big endian) to little endian
-	 */
-	rar_low = ((u32) addr[0] |
-		   ((u32) addr[1] << 8) |
-		    ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
-
-	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
-
-	/* If MAC address zero, no need to set the AV bit */
-	if (rar_low || rar_high)
-		rar_high |= E1000_RAH_AV;
-
-	/*
-	 * Some bridges will combine consecutive 32-bit writes into
-	 * a single burst write, which will malfunction on some parts.
-	 * The flushes avoid this.
-	 */
-	ew32(RAL(index), rar_low);
-	e1e_flush();
-	ew32(RAH(index), rar_high);
-	e1e_flush();
-}
-
-/**
- *  e1000_hash_mc_addr - Generate a multicast hash value
- *  @hw: pointer to the HW structure
- *  @mc_addr: pointer to a multicast address
- *
- *  Generates a multicast address hash value which is used to determine
- *  the multicast filter table array address and new table value.  See
- *  e1000_mta_set_generic()
- **/
-static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
-{
-	u32 hash_value, hash_mask;
-	u8 bit_shift = 0;
-
-	/* Register count multiplied by bits per register */
-	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
-
-	/*
-	 * For a mc_filter_type of 0, bit_shift is the number of left-shifts
-	 * where 0xFF would still fall within the hash mask.
-	 */
-	while (hash_mask >> bit_shift != 0xFF)
-		bit_shift++;
-
-	/*
-	 * The portion of the address that is used for the hash table
-	 * is determined by the mc_filter_type setting.
-	 * The algorithm is such that there is a total of 8 bits of shifting.
-	 * The bit_shift for a mc_filter_type of 0 represents the number of
-	 * left-shifts where the MSB of mc_addr[5] would still fall within
-	 * the hash_mask.  Case 0 does this exactly.  Since there are a total
-	 * of 8 bits of shifting, then mc_addr[4] will shift right the
-	 * remaining number of bits. Thus 8 - bit_shift.  The rest of the
-	 * cases are a variation of this algorithm...essentially raising the
-	 * number of bits to shift mc_addr[5] left, while still keeping the
-	 * 8-bit shifting total.
-	 *
-	 * For example, given the following Destination MAC Address and an
-	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
-	 * we can see that the bit_shift for case 0 is 4.  These are the hash
-	 * values resulting from each mc_filter_type...
-	 * [0] [1] [2] [3] [4] [5]
-	 * 01  AA  00  12  34  56
-	 * LSB		 MSB
-	 *
-	 * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
-	 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
-	 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
-	 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
-	 */
-	switch (hw->mac.mc_filter_type) {
-	default:
-	case 0:
-		break;
-	case 1:
-		bit_shift += 1;
-		break;
-	case 2:
-		bit_shift += 2;
-		break;
-	case 3:
-		bit_shift += 4;
-		break;
-	}
-
-	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
-				  (((u16) mc_addr[5]) << bit_shift)));
-
-	return hash_value;
-}
-
-/**
- *  e1000e_update_mc_addr_list_generic - Update Multicast addresses
- *  @hw: pointer to the HW structure
- *  @mc_addr_list: array of multicast addresses to program
- *  @mc_addr_count: number of multicast addresses to program
- *
- *  Updates entire Multicast Table Array.
- *  The caller must have a packed mc_addr_list of multicast addresses.
- **/
-void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
-					u8 *mc_addr_list, u32 mc_addr_count)
-{
-	u32 hash_value, hash_bit, hash_reg;
-	int i;
-
-	/* clear mta_shadow */
-	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
-
-	/* update mta_shadow from mc_addr_list */
-	for (i = 0; (u32) i < mc_addr_count; i++) {
-		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
-
-		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
-		hash_bit = hash_value & 0x1F;
-
-		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
-		mc_addr_list += (ETH_ALEN);
-	}
-
-	/* replace the entire MTA table */
-	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
-		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
-	e1e_flush();
-}
-
-/**
- *  e1000e_clear_hw_cntrs_base - Clear base hardware counters
- *  @hw: pointer to the HW structure
- *
- *  Clears the base hardware counters by reading the counter registers.
- **/
-void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
-{
-	er32(CRCERRS);
-	er32(SYMERRS);
-	er32(MPC);
-	er32(SCC);
-	er32(ECOL);
-	er32(MCC);
-	er32(LATECOL);
-	er32(COLC);
-	er32(DC);
-	er32(SEC);
-	er32(RLEC);
-	er32(XONRXC);
-	er32(XONTXC);
-	er32(XOFFRXC);
-	er32(XOFFTXC);
-	er32(FCRUC);
-	er32(GPRC);
-	er32(BPRC);
-	er32(MPRC);
-	er32(GPTC);
-	er32(GORCL);
-	er32(GORCH);
-	er32(GOTCL);
-	er32(GOTCH);
-	er32(RNBC);
-	er32(RUC);
-	er32(RFC);
-	er32(ROC);
-	er32(RJC);
-	er32(TORL);
-	er32(TORH);
-	er32(TOTL);
-	er32(TOTH);
-	er32(TPR);
-	er32(TPT);
-	er32(MPTC);
-	er32(BPTC);
-}
-
-/**
- *  e1000e_check_for_copper_link - Check for link (Copper)
- *  @hw: pointer to the HW structure
- *
- *  Checks to see of the link status of the hardware has changed.  If a
- *  change in link status has been detected, then we read the PHY registers
- *  to get the current speed/duplex if link exists.
- **/
-s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val;
-	bool link;
-
-	/*
-	 * We only want to go out to the PHY registers to see if Auto-Neg
-	 * has completed and/or if our link status has changed.  The
-	 * get_link_status flag is set upon receiving a Link Status
-	 * Change or Rx Sequence Error interrupt.
-	 */
-	if (!mac->get_link_status)
-		return 0;
-
-	/*
-	 * First we want to see if the MII Status Register reports
-	 * link.  If so, then we want to get the current speed/duplex
-	 * of the PHY.
-	 */
-	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
-	if (ret_val)
-		return ret_val;
-
-	if (!link)
-		return ret_val; /* No link detected */
-
-	mac->get_link_status = false;
-
-	/*
-	 * Check if there was DownShift, must be checked
-	 * immediately after link-up
-	 */
-	e1000e_check_downshift(hw);
-
-	/*
-	 * If we are forcing speed/duplex, then we simply return since
-	 * we have already determined whether we have link or not.
-	 */
-	if (!mac->autoneg) {
-		ret_val = -E1000_ERR_CONFIG;
-		return ret_val;
-	}
-
-	/*
-	 * Auto-Neg is enabled.  Auto Speed Detection takes care
-	 * of MAC speed/duplex configuration.  So we only need to
-	 * configure Collision Distance in the MAC.
-	 */
-	e1000e_config_collision_dist(hw);
-
-	/*
-	 * Configure Flow Control now that Auto-Neg has completed.
-	 * First, we need to restore the desired flow control
-	 * settings because we may have had to re-autoneg with a
-	 * different link partner.
-	 */
-	ret_val = e1000e_config_fc_after_link_up(hw);
-	if (ret_val)
-		e_dbg("Error configuring flow control\n");
-
-	return ret_val;
-}
-
-/**
- *  e1000e_check_for_fiber_link - Check for link (Fiber)
- *  @hw: pointer to the HW structure
- *
- *  Checks for link up on the hardware.  If link is not up and we have
- *  a signal, then we need to force link up.
- **/
-s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	u32 rxcw;
-	u32 ctrl;
-	u32 status;
-	s32 ret_val;
-
-	ctrl = er32(CTRL);
-	status = er32(STATUS);
-	rxcw = er32(RXCW);
-
-	/*
-	 * If we don't have link (auto-negotiation failed or link partner
-	 * cannot auto-negotiate), the cable is plugged in (we have signal),
-	 * and our link partner is not trying to auto-negotiate with us (we
-	 * are receiving idles or data), we need to force link up. We also
-	 * need to give auto-negotiation time to complete, in case the cable
-	 * was just plugged in. The autoneg_failed flag does this.
-	 */
-	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
-	if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) &&
-	    (!(rxcw & E1000_RXCW_C))) {
-		if (mac->autoneg_failed == 0) {
-			mac->autoneg_failed = 1;
-			return 0;
-		}
-		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
-
-		/* Disable auto-negotiation in the TXCW register */
-		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
-
-		/* Force link-up and also force full-duplex. */
-		ctrl = er32(CTRL);
-		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
-		ew32(CTRL, ctrl);
-
-		/* Configure Flow Control after forcing link up. */
-		ret_val = e1000e_config_fc_after_link_up(hw);
-		if (ret_val) {
-			e_dbg("Error configuring flow control\n");
-			return ret_val;
-		}
-	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-		/*
-		 * If we are forcing link and we are receiving /C/ ordered
-		 * sets, re-enable auto-negotiation in the TXCW register
-		 * and disable forced link in the Device Control register
-		 * in an attempt to auto-negotiate with our link partner.
-		 */
-		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
-		ew32(TXCW, mac->txcw);
-		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
-
-		mac->serdes_has_link = true;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_check_for_serdes_link - Check for link (Serdes)
- *  @hw: pointer to the HW structure
- *
- *  Checks for link up on the hardware.  If link is not up and we have
- *  a signal, then we need to force link up.
- **/
-s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	u32 rxcw;
-	u32 ctrl;
-	u32 status;
-	s32 ret_val;
-
-	ctrl = er32(CTRL);
-	status = er32(STATUS);
-	rxcw = er32(RXCW);
-
-	/*
-	 * If we don't have link (auto-negotiation failed or link partner
-	 * cannot auto-negotiate), and our link partner is not trying to
-	 * auto-negotiate with us (we are receiving idles or data),
-	 * we need to force link up. We also need to give auto-negotiation
-	 * time to complete.
-	 */
-	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
-	if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
-		if (mac->autoneg_failed == 0) {
-			mac->autoneg_failed = 1;
-			return 0;
-		}
-		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
-
-		/* Disable auto-negotiation in the TXCW register */
-		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
-
-		/* Force link-up and also force full-duplex. */
-		ctrl = er32(CTRL);
-		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
-		ew32(CTRL, ctrl);
-
-		/* Configure Flow Control after forcing link up. */
-		ret_val = e1000e_config_fc_after_link_up(hw);
-		if (ret_val) {
-			e_dbg("Error configuring flow control\n");
-			return ret_val;
-		}
-	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-		/*
-		 * If we are forcing link and we are receiving /C/ ordered
-		 * sets, re-enable auto-negotiation in the TXCW register
-		 * and disable forced link in the Device Control register
-		 * in an attempt to auto-negotiate with our link partner.
-		 */
-		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
-		ew32(TXCW, mac->txcw);
-		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
-
-		mac->serdes_has_link = true;
-	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
-		/*
-		 * If we force link for non-auto-negotiation switch, check
-		 * link status based on MAC synchronization for internal
-		 * serdes media type.
-		 */
-		/* SYNCH bit and IV bit are sticky. */
-		udelay(10);
-		rxcw = er32(RXCW);
-		if (rxcw & E1000_RXCW_SYNCH) {
-			if (!(rxcw & E1000_RXCW_IV)) {
-				mac->serdes_has_link = true;
-				e_dbg("SERDES: Link up - forced.\n");
-			}
-		} else {
-			mac->serdes_has_link = false;
-			e_dbg("SERDES: Link down - force failed.\n");
-		}
-	}
-
-	if (E1000_TXCW_ANE & er32(TXCW)) {
-		status = er32(STATUS);
-		if (status & E1000_STATUS_LU) {
-			/* SYNCH bit and IV bit are sticky, so reread rxcw.  */
-			udelay(10);
-			rxcw = er32(RXCW);
-			if (rxcw & E1000_RXCW_SYNCH) {
-				if (!(rxcw & E1000_RXCW_IV)) {
-					mac->serdes_has_link = true;
-					e_dbg("SERDES: Link up - autoneg "
-					   "completed successfully.\n");
-				} else {
-					mac->serdes_has_link = false;
-					e_dbg("SERDES: Link down - invalid"
-					   "codewords detected in autoneg.\n");
-				}
-			} else {
-				mac->serdes_has_link = false;
-				e_dbg("SERDES: Link down - no sync.\n");
-			}
-		} else {
-			mac->serdes_has_link = false;
-			e_dbg("SERDES: Link down - autoneg failed\n");
-		}
-	}
-
-	return 0;
-}
-
-/**
- *  e1000_set_default_fc_generic - Set flow control default values
- *  @hw: pointer to the HW structure
- *
- *  Read the EEPROM for the default values for flow control and store the
- *  values.
- **/
-static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
-{
-	s32 ret_val;
-	u16 nvm_data;
-
-	/*
-	 * Read and store word 0x0F of the EEPROM. This word contains bits
-	 * that determine the hardware's default PAUSE (flow control) mode,
-	 * a bit that determines whether the HW defaults to enabling or
-	 * disabling auto-negotiation, and the direction of the
-	 * SW defined pins. If there is no SW over-ride of the flow
-	 * control setting, then the variable hw->fc will
-	 * be initialized based on a value in the EEPROM.
-	 */
-	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
-
-	if (ret_val) {
-		e_dbg("NVM Read Error\n");
-		return ret_val;
-	}
-
-	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
-		hw->fc.requested_mode = e1000_fc_none;
-	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
-		 NVM_WORD0F_ASM_DIR)
-		hw->fc.requested_mode = e1000_fc_tx_pause;
-	else
-		hw->fc.requested_mode = e1000_fc_full;
-
-	return 0;
-}
-
-/**
- *  e1000e_setup_link - Setup flow control and link settings
- *  @hw: pointer to the HW structure
- *
- *  Determines which flow control settings to use, then configures flow
- *  control.  Calls the appropriate media-specific link configuration
- *  function.  Assuming the adapter has a valid link partner, a valid link
- *  should be established.  Assumes the hardware has previously been reset
- *  and the transmitter and receiver are not enabled.
- **/
-s32 e1000e_setup_link(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val;
-
-	/*
-	 * In the case of the phy reset being blocked, we already have a link.
-	 * We do not need to set it up again.
-	 */
-	if (e1000_check_reset_block(hw))
-		return 0;
-
-	/*
-	 * If requested flow control is set to default, set flow control
-	 * based on the EEPROM flow control settings.
-	 */
-	if (hw->fc.requested_mode == e1000_fc_default) {
-		ret_val = e1000_set_default_fc_generic(hw);
-		if (ret_val)
-			return ret_val;
-	}
-
-	/*
-	 * Save off the requested flow control mode for use later.  Depending
-	 * on the link partner's capabilities, we may or may not use this mode.
-	 */
-	hw->fc.current_mode = hw->fc.requested_mode;
-
-	e_dbg("After fix-ups FlowControl is now = %x\n",
-		hw->fc.current_mode);
-
-	/* Call the necessary media_type subroutine to configure the link. */
-	ret_val = mac->ops.setup_physical_interface(hw);
-	if (ret_val)
-		return ret_val;
-
-	/*
-	 * Initialize the flow control address, type, and PAUSE timer
-	 * registers to their default values.  This is done even if flow
-	 * control is disabled, because it does not hurt anything to
-	 * initialize these registers.
-	 */
-	e_dbg("Initializing the Flow Control address, type and timer regs\n");
-	ew32(FCT, FLOW_CONTROL_TYPE);
-	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
-	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
-
-	ew32(FCTTV, hw->fc.pause_time);
-
-	return e1000e_set_fc_watermarks(hw);
-}
-
-/**
- *  e1000_commit_fc_settings_generic - Configure flow control
- *  @hw: pointer to the HW structure
- *
- *  Write the flow control settings to the Transmit Config Word Register (TXCW)
- *  base on the flow control settings in e1000_mac_info.
- **/
-static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	u32 txcw;
-
-	/*
-	 * Check for a software override of the flow control settings, and
-	 * setup the device accordingly.  If auto-negotiation is enabled, then
-	 * software will have to set the "PAUSE" bits to the correct value in
-	 * the Transmit Config Word Register (TXCW) and re-start auto-
-	 * negotiation.  However, if auto-negotiation is disabled, then
-	 * software will have to manually configure the two flow control enable
-	 * bits in the CTRL register.
-	 *
-	 * The possible values of the "fc" parameter are:
-	 *      0:  Flow control is completely disabled
-	 *      1:  Rx flow control is enabled (we can receive pause frames,
-	 *          but not send pause frames).
-	 *      2:  Tx flow control is enabled (we can send pause frames but we
-	 *          do not support receiving pause frames).
-	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
-	 */
-	switch (hw->fc.current_mode) {
-	case e1000_fc_none:
-		/* Flow control completely disabled by a software over-ride. */
-		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
-		break;
-	case e1000_fc_rx_pause:
-		/*
-		 * Rx Flow control is enabled and Tx Flow control is disabled
-		 * by a software over-ride. Since there really isn't a way to
-		 * advertise that we are capable of Rx Pause ONLY, we will
-		 * advertise that we support both symmetric and asymmetric Rx
-		 * PAUSE.  Later, we will disable the adapter's ability to send
-		 * PAUSE frames.
-		 */
-		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
-		break;
-	case e1000_fc_tx_pause:
-		/*
-		 * Tx Flow control is enabled, and Rx Flow control is disabled,
-		 * by a software over-ride.
-		 */
-		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
-		break;
-	case e1000_fc_full:
-		/*
-		 * Flow control (both Rx and Tx) is enabled by a software
-		 * over-ride.
-		 */
-		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
-		break;
-	default:
-		e_dbg("Flow control param set incorrectly\n");
-		return -E1000_ERR_CONFIG;
-		break;
-	}
-
-	ew32(TXCW, txcw);
-	mac->txcw = txcw;
-
-	return 0;
-}
-
-/**
- *  e1000_poll_fiber_serdes_link_generic - Poll for link up
- *  @hw: pointer to the HW structure
- *
- *  Polls for link up by reading the status register, if link fails to come
- *  up with auto-negotiation, then the link is forced if a signal is detected.
- **/
-static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	u32 i, status;
-	s32 ret_val;
-
-	/*
-	 * If we have a signal (the cable is plugged in, or assumed true for
-	 * serdes media) then poll for a "Link-Up" indication in the Device
-	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds
-	 * seconds (Auto-negotiation should complete in less than 500
-	 * milliseconds even if the other end is doing it in SW).
-	 */
-	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
-		usleep_range(10000, 20000);
-		status = er32(STATUS);
-		if (status & E1000_STATUS_LU)
-			break;
-	}
-	if (i == FIBER_LINK_UP_LIMIT) {
-		e_dbg("Never got a valid link from auto-neg!!!\n");
-		mac->autoneg_failed = 1;
-		/*
-		 * AutoNeg failed to achieve a link, so we'll call
-		 * mac->check_for_link. This routine will force the
-		 * link up if we detect a signal. This will allow us to
-		 * communicate with non-autonegotiating link partners.
-		 */
-		ret_val = mac->ops.check_for_link(hw);
-		if (ret_val) {
-			e_dbg("Error while checking for link\n");
-			return ret_val;
-		}
-		mac->autoneg_failed = 0;
-	} else {
-		mac->autoneg_failed = 0;
-		e_dbg("Valid Link Found\n");
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
- *  @hw: pointer to the HW structure
- *
- *  Configures collision distance and flow control for fiber and serdes
- *  links.  Upon successful setup, poll for link.
- **/
-s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
-{
-	u32 ctrl;
-	s32 ret_val;
-
-	ctrl = er32(CTRL);
-
-	/* Take the link out of reset */
-	ctrl &= ~E1000_CTRL_LRST;
-
-	e1000e_config_collision_dist(hw);
-
-	ret_val = e1000_commit_fc_settings_generic(hw);
-	if (ret_val)
-		return ret_val;
-
-	/*
-	 * Since auto-negotiation is enabled, take the link out of reset (the
-	 * link will be in reset, because we previously reset the chip). This
-	 * will restart auto-negotiation.  If auto-negotiation is successful
-	 * then the link-up status bit will be set and the flow control enable
-	 * bits (RFCE and TFCE) will be set according to their negotiated value.
-	 */
-	e_dbg("Auto-negotiation enabled\n");
-
-	ew32(CTRL, ctrl);
-	e1e_flush();
-	usleep_range(1000, 2000);
-
-	/*
-	 * For these adapters, the SW definable pin 1 is set when the optics
-	 * detect a signal.  If we have a signal, then poll for a "Link-Up"
-	 * indication.
-	 */
-	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
-	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
-		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
-	} else {
-		e_dbg("No signal detected\n");
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_config_collision_dist - Configure collision distance
- *  @hw: pointer to the HW structure
- *
- *  Configures the collision distance to the default value and is used
- *  during link setup. Currently no func pointer exists and all
- *  implementations are handled in the generic version of this function.
- **/
-void e1000e_config_collision_dist(struct e1000_hw *hw)
-{
-	u32 tctl;
-
-	tctl = er32(TCTL);
-
-	tctl &= ~E1000_TCTL_COLD;
-	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
-
-	ew32(TCTL, tctl);
-	e1e_flush();
-}
-
-/**
- *  e1000e_set_fc_watermarks - Set flow control high/low watermarks
- *  @hw: pointer to the HW structure
- *
- *  Sets the flow control high/low threshold (watermark) registers.  If
- *  flow control XON frame transmission is enabled, then set XON frame
- *  transmission as well.
- **/
-s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
-{
-	u32 fcrtl = 0, fcrth = 0;
-
-	/*
-	 * Set the flow control receive threshold registers.  Normally,
-	 * these registers will be set to a default threshold that may be
-	 * adjusted later by the driver's runtime code.  However, if the
-	 * ability to transmit pause frames is not enabled, then these
-	 * registers will be set to 0.
-	 */
-	if (hw->fc.current_mode & e1000_fc_tx_pause) {
-		/*
-		 * We need to set up the Receive Threshold high and low water
-		 * marks as well as (optionally) enabling the transmission of
-		 * XON frames.
-		 */
-		fcrtl = hw->fc.low_water;
-		fcrtl |= E1000_FCRTL_XONE;
-		fcrth = hw->fc.high_water;
-	}
-	ew32(FCRTL, fcrtl);
-	ew32(FCRTH, fcrth);
-
-	return 0;
-}
-
-/**
- *  e1000e_force_mac_fc - Force the MAC's flow control settings
- *  @hw: pointer to the HW structure
- *
- *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
- *  device control register to reflect the adapter settings.  TFCE and RFCE
- *  need to be explicitly set by software when a copper PHY is used because
- *  autonegotiation is managed by the PHY rather than the MAC.  Software must
- *  also configure these bits when link is forced on a fiber connection.
- **/
-s32 e1000e_force_mac_fc(struct e1000_hw *hw)
-{
-	u32 ctrl;
-
-	ctrl = er32(CTRL);
-
-	/*
-	 * Because we didn't get link via the internal auto-negotiation
-	 * mechanism (we either forced link or we got link via PHY
-	 * auto-neg), we have to manually enable/disable transmit an
-	 * receive flow control.
-	 *
-	 * The "Case" statement below enables/disable flow control
-	 * according to the "hw->fc.current_mode" parameter.
-	 *
-	 * The possible values of the "fc" parameter are:
-	 *      0:  Flow control is completely disabled
-	 *      1:  Rx flow control is enabled (we can receive pause
-	 *          frames but not send pause frames).
-	 *      2:  Tx flow control is enabled (we can send pause frames
-	 *          frames but we do not receive pause frames).
-	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
-	 *  other:  No other values should be possible at this point.
-	 */
-	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
-
-	switch (hw->fc.current_mode) {
-	case e1000_fc_none:
-		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
-		break;
-	case e1000_fc_rx_pause:
-		ctrl &= (~E1000_CTRL_TFCE);
-		ctrl |= E1000_CTRL_RFCE;
-		break;
-	case e1000_fc_tx_pause:
-		ctrl &= (~E1000_CTRL_RFCE);
-		ctrl |= E1000_CTRL_TFCE;
-		break;
-	case e1000_fc_full:
-		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
-		break;
-	default:
-		e_dbg("Flow control param set incorrectly\n");
-		return -E1000_ERR_CONFIG;
-	}
-
-	ew32(CTRL, ctrl);
-
-	return 0;
-}
-
-/**
- *  e1000e_config_fc_after_link_up - Configures flow control after link
- *  @hw: pointer to the HW structure
- *
- *  Checks the status of auto-negotiation after link up to ensure that the
- *  speed and duplex were not forced.  If the link needed to be forced, then
- *  flow control needs to be forced also.  If auto-negotiation is enabled
- *  and did not fail, then we configure flow control based on our link
- *  partner.
- **/
-s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val = 0;
-	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
-	u16 speed, duplex;
-
-	/*
-	 * Check for the case where we have fiber media and auto-neg failed
-	 * so we had to force link.  In this case, we need to force the
-	 * configuration of the MAC to match the "fc" parameter.
-	 */
-	if (mac->autoneg_failed) {
-		if (hw->phy.media_type == e1000_media_type_fiber ||
-		    hw->phy.media_type == e1000_media_type_internal_serdes)
-			ret_val = e1000e_force_mac_fc(hw);
-	} else {
-		if (hw->phy.media_type == e1000_media_type_copper)
-			ret_val = e1000e_force_mac_fc(hw);
-	}
-
-	if (ret_val) {
-		e_dbg("Error forcing flow control settings\n");
-		return ret_val;
-	}
-
-	/*
-	 * Check for the case where we have copper media and auto-neg is
-	 * enabled.  In this case, we need to check and see if Auto-Neg
-	 * has completed, and if so, how the PHY and link partner has
-	 * flow control configured.
-	 */
-	if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
-		/*
-		 * Read the MII Status Register and check to see if AutoNeg
-		 * has completed.  We read this twice because this reg has
-		 * some "sticky" (latched) bits.
-		 */
-		ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
-		if (ret_val)
-			return ret_val;
-		ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
-		if (ret_val)
-			return ret_val;
-
-		if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
-			e_dbg("Copper PHY and Auto Neg "
-				 "has not completed.\n");
-			return ret_val;
-		}
-
-		/*
-		 * The AutoNeg process has completed, so we now need to
-		 * read both the Auto Negotiation Advertisement
-		 * Register (Address 4) and the Auto_Negotiation Base
-		 * Page Ability Register (Address 5) to determine how
-		 * flow control was negotiated.
-		 */
-		ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg);
-		if (ret_val)
-			return ret_val;
-		ret_val =
-		    e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg);
-		if (ret_val)
-			return ret_val;
-
-		/*
-		 * Two bits in the Auto Negotiation Advertisement Register
-		 * (Address 4) and two bits in the Auto Negotiation Base
-		 * Page Ability Register (Address 5) determine flow control
-		 * for both the PHY and the link partner.  The following
-		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
-		 * 1999, describes these PAUSE resolution bits and how flow
-		 * control is determined based upon these settings.
-		 * NOTE:  DC = Don't Care
-		 *
-		 *   LOCAL DEVICE  |   LINK PARTNER
-		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
-		 *-------|---------|-------|---------|--------------------
-		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
-		 *   0   |    1    |   0   |   DC    | e1000_fc_none
-		 *   0   |    1    |   1   |    0    | e1000_fc_none
-		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-		 *   1   |    0    |   0   |   DC    | e1000_fc_none
-		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
-		 *   1   |    1    |   0   |    0    | e1000_fc_none
-		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
-		 *
-		 * Are both PAUSE bits set to 1?  If so, this implies
-		 * Symmetric Flow Control is enabled at both ends.  The
-		 * ASM_DIR bits are irrelevant per the spec.
-		 *
-		 * For Symmetric Flow Control:
-		 *
-		 *   LOCAL DEVICE  |   LINK PARTNER
-		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
-		 *-------|---------|-------|---------|--------------------
-		 *   1   |   DC    |   1   |   DC    | E1000_fc_full
-		 *
-		 */
-		if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-		    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
-			/*
-			 * Now we need to check if the user selected Rx ONLY
-			 * of pause frames.  In this case, we had to advertise
-			 * FULL flow control because we could not advertise Rx
-			 * ONLY. Hence, we must now check to see if we need to
-			 * turn OFF the TRANSMISSION of PAUSE frames.
-			 */
-			if (hw->fc.requested_mode == e1000_fc_full) {
-				hw->fc.current_mode = e1000_fc_full;
-				e_dbg("Flow Control = FULL.\r\n");
-			} else {
-				hw->fc.current_mode = e1000_fc_rx_pause;
-				e_dbg("Flow Control = "
-				      "Rx PAUSE frames only.\r\n");
-			}
-		}
-		/*
-		 * For receiving PAUSE frames ONLY.
-		 *
-		 *   LOCAL DEVICE  |   LINK PARTNER
-		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
-		 *-------|---------|-------|---------|--------------------
-		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
-		 */
-		else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			hw->fc.current_mode = e1000_fc_tx_pause;
-			e_dbg("Flow Control = Tx PAUSE frames only.\r\n");
-		}
-		/*
-		 * For transmitting PAUSE frames ONLY.
-		 *
-		 *   LOCAL DEVICE  |   LINK PARTNER
-		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
-		 *-------|---------|-------|---------|--------------------
-		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
-		 */
-		else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			hw->fc.current_mode = e1000_fc_rx_pause;
-			e_dbg("Flow Control = Rx PAUSE frames only.\r\n");
-		} else {
-			/*
-			 * Per the IEEE spec, at this point flow control
-			 * should be disabled.
-			 */
-			hw->fc.current_mode = e1000_fc_none;
-			e_dbg("Flow Control = NONE.\r\n");
-		}
-
-		/*
-		 * Now we need to do one last check...  If we auto-
-		 * negotiated to HALF DUPLEX, flow control should not be
-		 * enabled per IEEE 802.3 spec.
-		 */
-		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
-		if (ret_val) {
-			e_dbg("Error getting link speed and duplex\n");
-			return ret_val;
-		}
-
-		if (duplex == HALF_DUPLEX)
-			hw->fc.current_mode = e1000_fc_none;
-
-		/*
-		 * Now we call a subroutine to actually force the MAC
-		 * controller to use the correct flow control settings.
-		 */
-		ret_val = e1000e_force_mac_fc(hw);
-		if (ret_val) {
-			e_dbg("Error forcing flow control settings\n");
-			return ret_val;
-		}
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
- *  @hw: pointer to the HW structure
- *  @speed: stores the current speed
- *  @duplex: stores the current duplex
- *
- *  Read the status register for the current speed/duplex and store the current
- *  speed and duplex for copper connections.
- **/
-s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex)
-{
-	u32 status;
-
-	status = er32(STATUS);
-	if (status & E1000_STATUS_SPEED_1000)
-		*speed = SPEED_1000;
-	else if (status & E1000_STATUS_SPEED_100)
-		*speed = SPEED_100;
-	else
-		*speed = SPEED_10;
-
-	if (status & E1000_STATUS_FD)
-		*duplex = FULL_DUPLEX;
-	else
-		*duplex = HALF_DUPLEX;
-
-	e_dbg("%u Mbps, %s Duplex\n",
-	      *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
-	      *duplex == FULL_DUPLEX ? "Full" : "Half");
-
-	return 0;
-}
-
-/**
- *  e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
- *  @hw: pointer to the HW structure
- *  @speed: stores the current speed
- *  @duplex: stores the current duplex
- *
- *  Sets the speed and duplex to gigabit full duplex (the only possible option)
- *  for fiber/serdes links.
- **/
-s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex)
-{
-	*speed = SPEED_1000;
-	*duplex = FULL_DUPLEX;
-
-	return 0;
-}
-
-/**
- *  e1000e_get_hw_semaphore - Acquire hardware semaphore
- *  @hw: pointer to the HW structure
- *
- *  Acquire the HW semaphore to access the PHY or NVM
- **/
-s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
-{
-	u32 swsm;
-	s32 timeout = hw->nvm.word_size + 1;
-	s32 i = 0;
-
-	/* Get the SW semaphore */
-	while (i < timeout) {
-		swsm = er32(SWSM);
-		if (!(swsm & E1000_SWSM_SMBI))
-			break;
-
-		udelay(50);
-		i++;
-	}
-
-	if (i == timeout) {
-		e_dbg("Driver can't access device - SMBI bit is set.\n");
-		return -E1000_ERR_NVM;
-	}
-
-	/* Get the FW semaphore. */
-	for (i = 0; i < timeout; i++) {
-		swsm = er32(SWSM);
-		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
-
-		/* Semaphore acquired if bit latched */
-		if (er32(SWSM) & E1000_SWSM_SWESMBI)
-			break;
-
-		udelay(50);
-	}
-
-	if (i == timeout) {
-		/* Release semaphores */
-		e1000e_put_hw_semaphore(hw);
-		e_dbg("Driver can't access the NVM\n");
-		return -E1000_ERR_NVM;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_put_hw_semaphore - Release hardware semaphore
- *  @hw: pointer to the HW structure
- *
- *  Release hardware semaphore used to access the PHY or NVM
- **/
-void e1000e_put_hw_semaphore(struct e1000_hw *hw)
-{
-	u32 swsm;
-
-	swsm = er32(SWSM);
-	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
-	ew32(SWSM, swsm);
-}
-
-/**
- *  e1000e_get_auto_rd_done - Check for auto read completion
- *  @hw: pointer to the HW structure
- *
- *  Check EEPROM for Auto Read done bit.
- **/
-s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
-{
-	s32 i = 0;
-
-	while (i < AUTO_READ_DONE_TIMEOUT) {
-		if (er32(EECD) & E1000_EECD_AUTO_RD)
-			break;
-		usleep_range(1000, 2000);
-		i++;
-	}
-
-	if (i == AUTO_READ_DONE_TIMEOUT) {
-		e_dbg("Auto read by HW from NVM has not completed.\n");
-		return -E1000_ERR_RESET;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_valid_led_default - Verify a valid default LED config
- *  @hw: pointer to the HW structure
- *  @data: pointer to the NVM (EEPROM)
- *
- *  Read the EEPROM for the current default LED configuration.  If the
- *  LED configuration is not valid, set to a valid LED configuration.
- **/
-s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
-{
-	s32 ret_val;
-
-	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
-	if (ret_val) {
-		e_dbg("NVM Read Error\n");
-		return ret_val;
-	}
-
-	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
-		*data = ID_LED_DEFAULT;
-
-	return 0;
-}
-
-/**
- *  e1000e_id_led_init -
- *  @hw: pointer to the HW structure
- *
- **/
-s32 e1000e_id_led_init(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val;
-	const u32 ledctl_mask = 0x000000FF;
-	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
-	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
-	u16 data, i, temp;
-	const u16 led_mask = 0x0F;
-
-	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
-	if (ret_val)
-		return ret_val;
-
-	mac->ledctl_default = er32(LEDCTL);
-	mac->ledctl_mode1 = mac->ledctl_default;
-	mac->ledctl_mode2 = mac->ledctl_default;
-
-	for (i = 0; i < 4; i++) {
-		temp = (data >> (i << 2)) & led_mask;
-		switch (temp) {
-		case ID_LED_ON1_DEF2:
-		case ID_LED_ON1_ON2:
-		case ID_LED_ON1_OFF2:
-			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
-			mac->ledctl_mode1 |= ledctl_on << (i << 3);
-			break;
-		case ID_LED_OFF1_DEF2:
-		case ID_LED_OFF1_ON2:
-		case ID_LED_OFF1_OFF2:
-			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
-			mac->ledctl_mode1 |= ledctl_off << (i << 3);
-			break;
-		default:
-			/* Do nothing */
-			break;
-		}
-		switch (temp) {
-		case ID_LED_DEF1_ON2:
-		case ID_LED_ON1_ON2:
-		case ID_LED_OFF1_ON2:
-			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
-			mac->ledctl_mode2 |= ledctl_on << (i << 3);
-			break;
-		case ID_LED_DEF1_OFF2:
-		case ID_LED_ON1_OFF2:
-		case ID_LED_OFF1_OFF2:
-			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
-			mac->ledctl_mode2 |= ledctl_off << (i << 3);
-			break;
-		default:
-			/* Do nothing */
-			break;
-		}
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_setup_led_generic - Configures SW controllable LED
- *  @hw: pointer to the HW structure
- *
- *  This prepares the SW controllable LED for use and saves the current state
- *  of the LED so it can be later restored.
- **/
-s32 e1000e_setup_led_generic(struct e1000_hw *hw)
-{
-	u32 ledctl;
-
-	if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
-		return -E1000_ERR_CONFIG;
-
-	if (hw->phy.media_type == e1000_media_type_fiber) {
-		ledctl = er32(LEDCTL);
-		hw->mac.ledctl_default = ledctl;
-		/* Turn off LED0 */
-		ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
-		            E1000_LEDCTL_LED0_BLINK |
-		            E1000_LEDCTL_LED0_MODE_MASK);
-		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
-		           E1000_LEDCTL_LED0_MODE_SHIFT);
-		ew32(LEDCTL, ledctl);
-	} else if (hw->phy.media_type == e1000_media_type_copper) {
-		ew32(LEDCTL, hw->mac.ledctl_mode1);
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_cleanup_led_generic - Set LED config to default operation
- *  @hw: pointer to the HW structure
- *
- *  Remove the current LED configuration and set the LED configuration
- *  to the default value, saved from the EEPROM.
- **/
-s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
-{
-	ew32(LEDCTL, hw->mac.ledctl_default);
-	return 0;
-}
-
-/**
- *  e1000e_blink_led_generic - Blink LED
- *  @hw: pointer to the HW structure
- *
- *  Blink the LEDs which are set to be on.
- **/
-s32 e1000e_blink_led_generic(struct e1000_hw *hw)
-{
-	u32 ledctl_blink = 0;
-	u32 i;
-
-	if (hw->phy.media_type == e1000_media_type_fiber) {
-		/* always blink LED0 for PCI-E fiber */
-		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
-		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
-	} else {
-		/*
-		 * set the blink bit for each LED that's "on" (0x0E)
-		 * in ledctl_mode2
-		 */
-		ledctl_blink = hw->mac.ledctl_mode2;
-		for (i = 0; i < 4; i++)
-			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
-			    E1000_LEDCTL_MODE_LED_ON)
-				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
-						 (i * 8));
-	}
-
-	ew32(LEDCTL, ledctl_blink);
-
-	return 0;
-}
-
-/**
- *  e1000e_led_on_generic - Turn LED on
- *  @hw: pointer to the HW structure
- *
- *  Turn LED on.
- **/
-s32 e1000e_led_on_generic(struct e1000_hw *hw)
-{
-	u32 ctrl;
-
-	switch (hw->phy.media_type) {
-	case e1000_media_type_fiber:
-		ctrl = er32(CTRL);
-		ctrl &= ~E1000_CTRL_SWDPIN0;
-		ctrl |= E1000_CTRL_SWDPIO0;
-		ew32(CTRL, ctrl);
-		break;
-	case e1000_media_type_copper:
-		ew32(LEDCTL, hw->mac.ledctl_mode2);
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_led_off_generic - Turn LED off
- *  @hw: pointer to the HW structure
- *
- *  Turn LED off.
- **/
-s32 e1000e_led_off_generic(struct e1000_hw *hw)
-{
-	u32 ctrl;
-
-	switch (hw->phy.media_type) {
-	case e1000_media_type_fiber:
-		ctrl = er32(CTRL);
-		ctrl |= E1000_CTRL_SWDPIN0;
-		ctrl |= E1000_CTRL_SWDPIO0;
-		ew32(CTRL, ctrl);
-		break;
-	case e1000_media_type_copper:
-		ew32(LEDCTL, hw->mac.ledctl_mode1);
-		break;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities
- *  @hw: pointer to the HW structure
- *  @no_snoop: bitmap of snoop events
- *
- *  Set the PCI-express register to snoop for events enabled in 'no_snoop'.
- **/
-void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
-{
-	u32 gcr;
-
-	if (no_snoop) {
-		gcr = er32(GCR);
-		gcr &= ~(PCIE_NO_SNOOP_ALL);
-		gcr |= no_snoop;
-		ew32(GCR, gcr);
-	}
-}
-
-/**
- *  e1000e_disable_pcie_master - Disables PCI-express master access
- *  @hw: pointer to the HW structure
- *
- *  Returns 0 if successful, else returns -10
- *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
- *  the master requests to be disabled.
- *
- *  Disables PCI-Express master access and verifies there are no pending
- *  requests.
- **/
-s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
-{
-	u32 ctrl;
-	s32 timeout = MASTER_DISABLE_TIMEOUT;
-
-	ctrl = er32(CTRL);
-	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
-	ew32(CTRL, ctrl);
-
-	while (timeout) {
-		if (!(er32(STATUS) &
-		      E1000_STATUS_GIO_MASTER_ENABLE))
-			break;
-		udelay(100);
-		timeout--;
-	}
-
-	if (!timeout) {
-		e_dbg("Master requests are pending.\n");
-		return -E1000_ERR_MASTER_REQUESTS_PENDING;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
- *  @hw: pointer to the HW structure
- *
- *  Reset the Adaptive Interframe Spacing throttle to default values.
- **/
-void e1000e_reset_adaptive(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-
-	if (!mac->adaptive_ifs) {
-		e_dbg("Not in Adaptive IFS mode!\n");
-		goto out;
-	}
-
-	mac->current_ifs_val = 0;
-	mac->ifs_min_val = IFS_MIN;
-	mac->ifs_max_val = IFS_MAX;
-	mac->ifs_step_size = IFS_STEP;
-	mac->ifs_ratio = IFS_RATIO;
-
-	mac->in_ifs_mode = false;
-	ew32(AIT, 0);
-out:
-	return;
-}
-
-/**
- *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
- *  @hw: pointer to the HW structure
- *
- *  Update the Adaptive Interframe Spacing Throttle value based on the
- *  time between transmitted packets and time between collisions.
- **/
-void e1000e_update_adaptive(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-
-	if (!mac->adaptive_ifs) {
-		e_dbg("Not in Adaptive IFS mode!\n");
-		goto out;
-	}
-
-	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
-		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
-			mac->in_ifs_mode = true;
-			if (mac->current_ifs_val < mac->ifs_max_val) {
-				if (!mac->current_ifs_val)
-					mac->current_ifs_val = mac->ifs_min_val;
-				else
-					mac->current_ifs_val +=
-						mac->ifs_step_size;
-				ew32(AIT, mac->current_ifs_val);
-			}
-		}
-	} else {
-		if (mac->in_ifs_mode &&
-		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
-			mac->current_ifs_val = 0;
-			mac->in_ifs_mode = false;
-			ew32(AIT, 0);
-		}
-	}
-out:
-	return;
-}
-
-/**
- *  e1000_raise_eec_clk - Raise EEPROM clock
- *  @hw: pointer to the HW structure
- *  @eecd: pointer to the EEPROM
- *
- *  Enable/Raise the EEPROM clock bit.
- **/
-static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
-{
-	*eecd = *eecd | E1000_EECD_SK;
-	ew32(EECD, *eecd);
-	e1e_flush();
-	udelay(hw->nvm.delay_usec);
-}
-
-/**
- *  e1000_lower_eec_clk - Lower EEPROM clock
- *  @hw: pointer to the HW structure
- *  @eecd: pointer to the EEPROM
- *
- *  Clear/Lower the EEPROM clock bit.
- **/
-static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
-{
-	*eecd = *eecd & ~E1000_EECD_SK;
-	ew32(EECD, *eecd);
-	e1e_flush();
-	udelay(hw->nvm.delay_usec);
-}
-
-/**
- *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
- *  @hw: pointer to the HW structure
- *  @data: data to send to the EEPROM
- *  @count: number of bits to shift out
- *
- *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
- *  "data" parameter will be shifted out to the EEPROM one bit at a time.
- *  In order to do this, "data" must be broken down into bits.
- **/
-static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
-{
-	struct e1000_nvm_info *nvm = &hw->nvm;
-	u32 eecd = er32(EECD);
-	u32 mask;
-
-	mask = 0x01 << (count - 1);
-	if (nvm->type == e1000_nvm_eeprom_spi)
-		eecd |= E1000_EECD_DO;
-
-	do {
-		eecd &= ~E1000_EECD_DI;
-
-		if (data & mask)
-			eecd |= E1000_EECD_DI;
-
-		ew32(EECD, eecd);
-		e1e_flush();
-
-		udelay(nvm->delay_usec);
-
-		e1000_raise_eec_clk(hw, &eecd);
-		e1000_lower_eec_clk(hw, &eecd);
-
-		mask >>= 1;
-	} while (mask);
-
-	eecd &= ~E1000_EECD_DI;
-	ew32(EECD, eecd);
-}
-
-/**
- *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
- *  @hw: pointer to the HW structure
- *  @count: number of bits to shift in
- *
- *  In order to read a register from the EEPROM, we need to shift 'count' bits
- *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
- *  the EEPROM (setting the SK bit), and then reading the value of the data out
- *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
- *  always be clear.
- **/
-static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
-{
-	u32 eecd;
-	u32 i;
-	u16 data;
-
-	eecd = er32(EECD);
-
-	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
-	data = 0;
-
-	for (i = 0; i < count; i++) {
-		data <<= 1;
-		e1000_raise_eec_clk(hw, &eecd);
-
-		eecd = er32(EECD);
-
-		eecd &= ~E1000_EECD_DI;
-		if (eecd & E1000_EECD_DO)
-			data |= 1;
-
-		e1000_lower_eec_clk(hw, &eecd);
-	}
-
-	return data;
-}
-
-/**
- *  e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
- *  @hw: pointer to the HW structure
- *  @ee_reg: EEPROM flag for polling
- *
- *  Polls the EEPROM status bit for either read or write completion based
- *  upon the value of 'ee_reg'.
- **/
-s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
-{
-	u32 attempts = 100000;
-	u32 i, reg = 0;
-
-	for (i = 0; i < attempts; i++) {
-		if (ee_reg == E1000_NVM_POLL_READ)
-			reg = er32(EERD);
-		else
-			reg = er32(EEWR);
-
-		if (reg & E1000_NVM_RW_REG_DONE)
-			return 0;
-
-		udelay(5);
-	}
-
-	return -E1000_ERR_NVM;
-}
-
-/**
- *  e1000e_acquire_nvm - Generic request for access to EEPROM
- *  @hw: pointer to the HW structure
- *
- *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
- *  Return successful if access grant bit set, else clear the request for
- *  EEPROM access and return -E1000_ERR_NVM (-1).
- **/
-s32 e1000e_acquire_nvm(struct e1000_hw *hw)
-{
-	u32 eecd = er32(EECD);
-	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
-
-	ew32(EECD, eecd | E1000_EECD_REQ);
-	eecd = er32(EECD);
-
-	while (timeout) {
-		if (eecd & E1000_EECD_GNT)
-			break;
-		udelay(5);
-		eecd = er32(EECD);
-		timeout--;
-	}
-
-	if (!timeout) {
-		eecd &= ~E1000_EECD_REQ;
-		ew32(EECD, eecd);
-		e_dbg("Could not acquire NVM grant\n");
-		return -E1000_ERR_NVM;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000_standby_nvm - Return EEPROM to standby state
- *  @hw: pointer to the HW structure
- *
- *  Return the EEPROM to a standby state.
- **/
-static void e1000_standby_nvm(struct e1000_hw *hw)
-{
-	struct e1000_nvm_info *nvm = &hw->nvm;
-	u32 eecd = er32(EECD);
-
-	if (nvm->type == e1000_nvm_eeprom_spi) {
-		/* Toggle CS to flush commands */
-		eecd |= E1000_EECD_CS;
-		ew32(EECD, eecd);
-		e1e_flush();
-		udelay(nvm->delay_usec);
-		eecd &= ~E1000_EECD_CS;
-		ew32(EECD, eecd);
-		e1e_flush();
-		udelay(nvm->delay_usec);
-	}
-}
-
-/**
- *  e1000_stop_nvm - Terminate EEPROM command
- *  @hw: pointer to the HW structure
- *
- *  Terminates the current command by inverting the EEPROM's chip select pin.
- **/
-static void e1000_stop_nvm(struct e1000_hw *hw)
-{
-	u32 eecd;
-
-	eecd = er32(EECD);
-	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
-		/* Pull CS high */
-		eecd |= E1000_EECD_CS;
-		e1000_lower_eec_clk(hw, &eecd);
-	}
-}
-
-/**
- *  e1000e_release_nvm - Release exclusive access to EEPROM
- *  @hw: pointer to the HW structure
- *
- *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
- **/
-void e1000e_release_nvm(struct e1000_hw *hw)
-{
-	u32 eecd;
-
-	e1000_stop_nvm(hw);
-
-	eecd = er32(EECD);
-	eecd &= ~E1000_EECD_REQ;
-	ew32(EECD, eecd);
-}
-
-/**
- *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
- *  @hw: pointer to the HW structure
- *
- *  Setups the EEPROM for reading and writing.
- **/
-static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
-{
-	struct e1000_nvm_info *nvm = &hw->nvm;
-	u32 eecd = er32(EECD);
-	u8 spi_stat_reg;
-
-	if (nvm->type == e1000_nvm_eeprom_spi) {
-		u16 timeout = NVM_MAX_RETRY_SPI;
-
-		/* Clear SK and CS */
-		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
-		ew32(EECD, eecd);
-		e1e_flush();
-		udelay(1);
-
-		/*
-		 * Read "Status Register" repeatedly until the LSB is cleared.
-		 * The EEPROM will signal that the command has been completed
-		 * by clearing bit 0 of the internal status register.  If it's
-		 * not cleared within 'timeout', then error out.
-		 */
-		while (timeout) {
-			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
-						 hw->nvm.opcode_bits);
-			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
-			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
-				break;
-
-			udelay(5);
-			e1000_standby_nvm(hw);
-			timeout--;
-		}
-
-		if (!timeout) {
-			e_dbg("SPI NVM Status error\n");
-			return -E1000_ERR_NVM;
-		}
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_read_nvm_eerd - Reads EEPROM using EERD register
- *  @hw: pointer to the HW structure
- *  @offset: offset of word in the EEPROM to read
- *  @words: number of words to read
- *  @data: word read from the EEPROM
- *
- *  Reads a 16 bit word from the EEPROM using the EERD register.
- **/
-s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
-	struct e1000_nvm_info *nvm = &hw->nvm;
-	u32 i, eerd = 0;
-	s32 ret_val = 0;
-
-	/*
-	 * A check for invalid values:  offset too large, too many words,
-	 * too many words for the offset, and not enough words.
-	 */
-	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
-	    (words == 0)) {
-		e_dbg("nvm parameter(s) out of bounds\n");
-		return -E1000_ERR_NVM;
-	}
-
-	for (i = 0; i < words; i++) {
-		eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
-		       E1000_NVM_RW_REG_START;
-
-		ew32(EERD, eerd);
-		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
-		if (ret_val)
-			break;
-
-		data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
-	}
-
-	return ret_val;
-}
-
-/**
- *  e1000e_write_nvm_spi - Write to EEPROM using SPI
- *  @hw: pointer to the HW structure
- *  @offset: offset within the EEPROM to be written to
- *  @words: number of words to write
- *  @data: 16 bit word(s) to be written to the EEPROM
- *
- *  Writes data to EEPROM at offset using SPI interface.
- *
- *  If e1000e_update_nvm_checksum is not called after this function , the
- *  EEPROM will most likely contain an invalid checksum.
- **/
-s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
-	struct e1000_nvm_info *nvm = &hw->nvm;
-	s32 ret_val;
-	u16 widx = 0;
-
-	/*
-	 * A check for invalid values:  offset too large, too many words,
-	 * and not enough words.
-	 */
-	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
-	    (words == 0)) {
-		e_dbg("nvm parameter(s) out of bounds\n");
-		return -E1000_ERR_NVM;
-	}
-
-	ret_val = nvm->ops.acquire(hw);
-	if (ret_val)
-		return ret_val;
-
-	while (widx < words) {
-		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
-
-		ret_val = e1000_ready_nvm_eeprom(hw);
-		if (ret_val) {
-			nvm->ops.release(hw);
-			return ret_val;
-		}
-
-		e1000_standby_nvm(hw);
-
-		/* Send the WRITE ENABLE command (8 bit opcode) */
-		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
-					 nvm->opcode_bits);
-
-		e1000_standby_nvm(hw);
-
-		/*
-		 * Some SPI eeproms use the 8th address bit embedded in the
-		 * opcode
-		 */
-		if ((nvm->address_bits == 8) && (offset >= 128))
-			write_opcode |= NVM_A8_OPCODE_SPI;
-
-		/* Send the Write command (8-bit opcode + addr) */
-		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
-		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
-					 nvm->address_bits);
-
-		/* Loop to allow for up to whole page write of eeprom */
-		while (widx < words) {
-			u16 word_out = data[widx];
-			word_out = (word_out >> 8) | (word_out << 8);
-			e1000_shift_out_eec_bits(hw, word_out, 16);
-			widx++;
-
-			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
-				e1000_standby_nvm(hw);
-				break;
-			}
-		}
-	}
-
-	usleep_range(10000, 20000);
-	nvm->ops.release(hw);
-	return 0;
-}
-
-/**
- *  e1000_read_pba_string_generic - Read device part number
- *  @hw: pointer to the HW structure
- *  @pba_num: pointer to device part number
- *  @pba_num_size: size of part number buffer
- *
- *  Reads the product board assembly (PBA) number from the EEPROM and stores
- *  the value in pba_num.
- **/
-s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
-				  u32 pba_num_size)
-{
-	s32 ret_val;
-	u16 nvm_data;
-	u16 pba_ptr;
-	u16 offset;
-	u16 length;
-
-	if (pba_num == NULL) {
-		e_dbg("PBA string buffer was null\n");
-		ret_val = E1000_ERR_INVALID_ARGUMENT;
-		goto out;
-	}
-
-	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
-	if (ret_val) {
-		e_dbg("NVM Read Error\n");
-		goto out;
-	}
-
-	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
-	if (ret_val) {
-		e_dbg("NVM Read Error\n");
-		goto out;
-	}
-
-	/*
-	 * if nvm_data is not ptr guard the PBA must be in legacy format which
-	 * means pba_ptr is actually our second data word for the PBA number
-	 * and we can decode it into an ascii string
-	 */
-	if (nvm_data != NVM_PBA_PTR_GUARD) {
-		e_dbg("NVM PBA number is not stored as string\n");
-
-		/* we will need 11 characters to store the PBA */
-		if (pba_num_size < 11) {
-			e_dbg("PBA string buffer too small\n");
-			return E1000_ERR_NO_SPACE;
-		}
-
-		/* extract hex string from data and pba_ptr */
-		pba_num[0] = (nvm_data >> 12) & 0xF;
-		pba_num[1] = (nvm_data >> 8) & 0xF;
-		pba_num[2] = (nvm_data >> 4) & 0xF;
-		pba_num[3] = nvm_data & 0xF;
-		pba_num[4] = (pba_ptr >> 12) & 0xF;
-		pba_num[5] = (pba_ptr >> 8) & 0xF;
-		pba_num[6] = '-';
-		pba_num[7] = 0;
-		pba_num[8] = (pba_ptr >> 4) & 0xF;
-		pba_num[9] = pba_ptr & 0xF;
-
-		/* put a null character on the end of our string */
-		pba_num[10] = '\0';
-
-		/* switch all the data but the '-' to hex char */
-		for (offset = 0; offset < 10; offset++) {
-			if (pba_num[offset] < 0xA)
-				pba_num[offset] += '0';
-			else if (pba_num[offset] < 0x10)
-				pba_num[offset] += 'A' - 0xA;
-		}
-
-		goto out;
-	}
-
-	ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
-	if (ret_val) {
-		e_dbg("NVM Read Error\n");
-		goto out;
-	}
-
-	if (length == 0xFFFF || length == 0) {
-		e_dbg("NVM PBA number section invalid length\n");
-		ret_val = E1000_ERR_NVM_PBA_SECTION;
-		goto out;
-	}
-	/* check if pba_num buffer is big enough */
-	if (pba_num_size < (((u32)length * 2) - 1)) {
-		e_dbg("PBA string buffer too small\n");
-		ret_val = E1000_ERR_NO_SPACE;
-		goto out;
-	}
-
-	/* trim pba length from start of string */
-	pba_ptr++;
-	length--;
-
-	for (offset = 0; offset < length; offset++) {
-		ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
-		if (ret_val) {
-			e_dbg("NVM Read Error\n");
-			goto out;
-		}
-		pba_num[offset * 2] = (u8)(nvm_data >> 8);
-		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
-	}
-	pba_num[offset * 2] = '\0';
-
-out:
-	return ret_val;
-}
-
-/**
- *  e1000_read_mac_addr_generic - Read device MAC address
- *  @hw: pointer to the HW structure
- *
- *  Reads the device MAC address from the EEPROM and stores the value.
- *  Since devices with two ports use the same EEPROM, we increment the
- *  last bit in the MAC address for the second port.
- **/
-s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
-{
-	u32 rar_high;
-	u32 rar_low;
-	u16 i;
-
-	rar_high = er32(RAH(0));
-	rar_low = er32(RAL(0));
-
-	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
-		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
-
-	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
-		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
-
-	for (i = 0; i < ETH_ALEN; i++)
-		hw->mac.addr[i] = hw->mac.perm_addr[i];
-
-	return 0;
-}
-
-/**
- *  e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
- *  @hw: pointer to the HW structure
- *
- *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
- *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
- **/
-s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
-{
-	s32 ret_val;
-	u16 checksum = 0;
-	u16 i, nvm_data;
-
-	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
-		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
-		if (ret_val) {
-			e_dbg("NVM Read Error\n");
-			return ret_val;
-		}
-		checksum += nvm_data;
-	}
-
-	if (checksum != (u16) NVM_SUM) {
-		e_dbg("NVM Checksum Invalid\n");
-		return -E1000_ERR_NVM;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_update_nvm_checksum_generic - Update EEPROM checksum
- *  @hw: pointer to the HW structure
- *
- *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
- *  up to the checksum.  Then calculates the EEPROM checksum and writes the
- *  value to the EEPROM.
- **/
-s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
-{
-	s32 ret_val;
-	u16 checksum = 0;
-	u16 i, nvm_data;
-
-	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
-		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
-		if (ret_val) {
-			e_dbg("NVM Read Error while updating checksum.\n");
-			return ret_val;
-		}
-		checksum += nvm_data;
-	}
-	checksum = (u16) NVM_SUM - checksum;
-	ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
-	if (ret_val)
-		e_dbg("NVM Write Error while updating checksum.\n");
-
-	return ret_val;
-}
-
-/**
- *  e1000e_reload_nvm - Reloads EEPROM
- *  @hw: pointer to the HW structure
- *
- *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
- *  extended control register.
- **/
-void e1000e_reload_nvm(struct e1000_hw *hw)
-{
-	u32 ctrl_ext;
-
-	udelay(10);
-	ctrl_ext = er32(CTRL_EXT);
-	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-	ew32(CTRL_EXT, ctrl_ext);
-	e1e_flush();
-}
-
-/**
- *  e1000_calculate_checksum - Calculate checksum for buffer
- *  @buffer: pointer to EEPROM
- *  @length: size of EEPROM to calculate a checksum for
- *
- *  Calculates the checksum for some buffer on a specified length.  The
- *  checksum calculated is returned.
- **/
-static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
-{
-	u32 i;
-	u8  sum = 0;
-
-	if (!buffer)
-		return 0;
-
-	for (i = 0; i < length; i++)
-		sum += buffer[i];
-
-	return (u8) (0 - sum);
-}
-
-/**
- *  e1000_mng_enable_host_if - Checks host interface is enabled
- *  @hw: pointer to the HW structure
- *
- *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
- *
- *  This function checks whether the HOST IF is enabled for command operation
- *  and also checks whether the previous command is completed.  It busy waits
- *  in case of previous command is not completed.
- **/
-static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
-{
-	u32 hicr;
-	u8 i;
-
-	if (!(hw->mac.arc_subsystem_valid)) {
-		e_dbg("ARC subsystem not valid.\n");
-		return -E1000_ERR_HOST_INTERFACE_COMMAND;
-	}
-
-	/* Check that the host interface is enabled. */
-	hicr = er32(HICR);
-	if ((hicr & E1000_HICR_EN) == 0) {
-		e_dbg("E1000_HOST_EN bit disabled.\n");
-		return -E1000_ERR_HOST_INTERFACE_COMMAND;
-	}
-	/* check the previous command is completed */
-	for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
-		hicr = er32(HICR);
-		if (!(hicr & E1000_HICR_C))
-			break;
-		mdelay(1);
-	}
-
-	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
-		e_dbg("Previous command timeout failed .\n");
-		return -E1000_ERR_HOST_INTERFACE_COMMAND;
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_check_mng_mode_generic - check management mode
- *  @hw: pointer to the HW structure
- *
- *  Reads the firmware semaphore register and returns true (>0) if
- *  manageability is enabled, else false (0).
- **/
-bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
-{
-	u32 fwsm = er32(FWSM);
-
-	return (fwsm & E1000_FWSM_MODE_MASK) ==
-		(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
-}
-
-/**
- *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
- *  @hw: pointer to the HW structure
- *
- *  Enables packet filtering on transmit packets if manageability is enabled
- *  and host interface is enabled.
- **/
-bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
-{
-	struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
-	u32 *buffer = (u32 *)&hw->mng_cookie;
-	u32 offset;
-	s32 ret_val, hdr_csum, csum;
-	u8 i, len;
-
-	hw->mac.tx_pkt_filtering = true;
-
-	/* No manageability, no filtering */
-	if (!e1000e_check_mng_mode(hw)) {
-		hw->mac.tx_pkt_filtering = false;
-		goto out;
-	}
-
-	/*
-	 * If we can't read from the host interface for whatever
-	 * reason, disable filtering.
-	 */
-	ret_val = e1000_mng_enable_host_if(hw);
-	if (ret_val) {
-		hw->mac.tx_pkt_filtering = false;
-		goto out;
-	}
-
-	/* Read in the header.  Length and offset are in dwords. */
-	len    = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
-	offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
-	for (i = 0; i < len; i++)
-		*(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i);
-	hdr_csum = hdr->checksum;
-	hdr->checksum = 0;
-	csum = e1000_calculate_checksum((u8 *)hdr,
-					E1000_MNG_DHCP_COOKIE_LENGTH);
-	/*
-	 * If either the checksums or signature don't match, then
-	 * the cookie area isn't considered valid, in which case we
-	 * take the safe route of assuming Tx filtering is enabled.
-	 */
-	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
-		hw->mac.tx_pkt_filtering = true;
-		goto out;
-	}
-
-	/* Cookie area is valid, make the final check for filtering. */
-	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
-		hw->mac.tx_pkt_filtering = false;
-		goto out;
-	}
-
-out:
-	return hw->mac.tx_pkt_filtering;
-}
-
-/**
- *  e1000_mng_write_cmd_header - Writes manageability command header
- *  @hw: pointer to the HW structure
- *  @hdr: pointer to the host interface command header
- *
- *  Writes the command header after does the checksum calculation.
- **/
-static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
-				  struct e1000_host_mng_command_header *hdr)
-{
-	u16 i, length = sizeof(struct e1000_host_mng_command_header);
-
-	/* Write the whole command header structure with new checksum. */
-
-	hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
-
-	length >>= 2;
-	/* Write the relevant command block into the ram area. */
-	for (i = 0; i < length; i++) {
-		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i,
-					    *((u32 *) hdr + i));
-		e1e_flush();
-	}
-
-	return 0;
-}
-
-/**
- *  e1000_mng_host_if_write - Write to the manageability host interface
- *  @hw: pointer to the HW structure
- *  @buffer: pointer to the host interface buffer
- *  @length: size of the buffer
- *  @offset: location in the buffer to write to
- *  @sum: sum of the data (not checksum)
- *
- *  This function writes the buffer content at the offset given on the host if.
- *  It also does alignment considerations to do the writes in most efficient
- *  way.  Also fills up the sum of the buffer in *buffer parameter.
- **/
-static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
-				   u16 length, u16 offset, u8 *sum)
-{
-	u8 *tmp;
-	u8 *bufptr = buffer;
-	u32 data = 0;
-	u16 remaining, i, j, prev_bytes;
-
-	/* sum = only sum of the data and it is not checksum */
-
-	if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
-		return -E1000_ERR_PARAM;
-
-	tmp = (u8 *)&data;
-	prev_bytes = offset & 0x3;
-	offset >>= 2;
-
-	if (prev_bytes) {
-		data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset);
-		for (j = prev_bytes; j < sizeof(u32); j++) {
-			*(tmp + j) = *bufptr++;
-			*sum += *(tmp + j);
-		}
-		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data);
-		length -= j - prev_bytes;
-		offset++;
-	}
-
-	remaining = length & 0x3;
-	length -= remaining;
-
-	/* Calculate length in DWORDs */
-	length >>= 2;
-
-	/*
-	 * The device driver writes the relevant command block into the
-	 * ram area.
-	 */
-	for (i = 0; i < length; i++) {
-		for (j = 0; j < sizeof(u32); j++) {
-			*(tmp + j) = *bufptr++;
-			*sum += *(tmp + j);
-		}
-
-		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
-	}
-	if (remaining) {
-		for (j = 0; j < sizeof(u32); j++) {
-			if (j < remaining)
-				*(tmp + j) = *bufptr++;
-			else
-				*(tmp + j) = 0;
-
-			*sum += *(tmp + j);
-		}
-		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
-	}
-
-	return 0;
-}
-
-/**
- *  e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
- *  @hw: pointer to the HW structure
- *  @buffer: pointer to the host interface
- *  @length: size of the buffer
- *
- *  Writes the DHCP information to the host interface.
- **/
-s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
-{
-	struct e1000_host_mng_command_header hdr;
-	s32 ret_val;
-	u32 hicr;
-
-	hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
-	hdr.command_length = length;
-	hdr.reserved1 = 0;
-	hdr.reserved2 = 0;
-	hdr.checksum = 0;
-
-	/* Enable the host interface */
-	ret_val = e1000_mng_enable_host_if(hw);
-	if (ret_val)
-		return ret_val;
-
-	/* Populate the host interface with the contents of "buffer". */
-	ret_val = e1000_mng_host_if_write(hw, buffer, length,
-					  sizeof(hdr), &(hdr.checksum));
-	if (ret_val)
-		return ret_val;
-
-	/* Write the manageability command header */
-	ret_val = e1000_mng_write_cmd_header(hw, &hdr);
-	if (ret_val)
-		return ret_val;
-
-	/* Tell the ARC a new command is pending. */
-	hicr = er32(HICR);
-	ew32(HICR, hicr | E1000_HICR_C);
-
-	return 0;
-}
-
-/**
- *  e1000e_enable_mng_pass_thru - Check if management passthrough is needed
- *  @hw: pointer to the HW structure
- *
- *  Verifies the hardware needs to leave interface enabled so that frames can
- *  be directed to and from the management interface.
- **/
-bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
-{
-	u32 manc;
-	u32 fwsm, factps;
-	bool ret_val = false;
-
-	manc = er32(MANC);
-
-	if (!(manc & E1000_MANC_RCV_TCO_EN))
-		goto out;
-
-	if (hw->mac.has_fwsm) {
-		fwsm = er32(FWSM);
-		factps = er32(FACTPS);
-
-		if (!(factps & E1000_FACTPS_MNGCG) &&
-		    ((fwsm & E1000_FWSM_MODE_MASK) ==
-		     (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
-			ret_val = true;
-			goto out;
-		}
-	} else if ((hw->mac.type == e1000_82574) ||
-		   (hw->mac.type == e1000_82583)) {
-		u16 data;
-
-		factps = er32(FACTPS);
-		e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
-
-		if (!(factps & E1000_FACTPS_MNGCG) &&
-		    ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
-		     (e1000_mng_mode_pt << 13))) {
-			ret_val = true;
-			goto out;
-		}
-	} else if ((manc & E1000_MANC_SMBUS_EN) &&
-		    !(manc & E1000_MANC_ASF_EN)) {
-			ret_val = true;
-			goto out;
-	}
-
-out:
-	return ret_val;
-}
diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c
new file mode 100644
index 0000000..17991e6
--- /dev/null
+++ b/drivers/net/ethernet/intel/e1000e/mac.c
@@ -0,0 +1,1710 @@
+/*******************************************************************************
+
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2012 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "e1000.h"
+
+/**
+ *  e1000e_get_bus_info_pcie - Get PCIe bus information
+ *  @hw: pointer to the HW structure
+ *
+ *  Determines and stores the system bus information for a particular
+ *  network interface.  The following bus information is determined and stored:
+ *  bus speed, bus width, type (PCIe), and PCIe function.
+ **/
+s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	struct e1000_bus_info *bus = &hw->bus;
+	struct e1000_adapter *adapter = hw->adapter;
+	u16 pcie_link_status, cap_offset;
+
+	cap_offset = adapter->pdev->pcie_cap;
+	if (!cap_offset) {
+		bus->width = e1000_bus_width_unknown;
+	} else {
+		pci_read_config_word(adapter->pdev,
+				     cap_offset + PCIE_LINK_STATUS,
+				     &pcie_link_status);
+		bus->width = (enum e1000_bus_width)((pcie_link_status &
+						     PCIE_LINK_WIDTH_MASK) >>
+						    PCIE_LINK_WIDTH_SHIFT);
+	}
+
+	mac->ops.set_lan_id(hw);
+
+	return 0;
+}
+
+/**
+ *  e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
+ *
+ *  @hw: pointer to the HW structure
+ *
+ *  Determines the LAN function id by reading memory-mapped registers
+ *  and swaps the port value if requested.
+ **/
+void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
+{
+	struct e1000_bus_info *bus = &hw->bus;
+	u32 reg;
+
+	/*
+	 * The status register reports the correct function number
+	 * for the device regardless of function swap state.
+	 */
+	reg = er32(STATUS);
+	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
+}
+
+/**
+ *  e1000_set_lan_id_single_port - Set LAN id for a single port device
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets the LAN function id to zero for a single port device.
+ **/
+void e1000_set_lan_id_single_port(struct e1000_hw *hw)
+{
+	struct e1000_bus_info *bus = &hw->bus;
+
+	bus->func = 0;
+}
+
+/**
+ *  e1000_clear_vfta_generic - Clear VLAN filter table
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the register array which contains the VLAN filter table by
+ *  setting all the values to 0.
+ **/
+void e1000_clear_vfta_generic(struct e1000_hw *hw)
+{
+	u32 offset;
+
+	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
+		e1e_flush();
+	}
+}
+
+/**
+ *  e1000_write_vfta_generic - Write value to VLAN filter table
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset in VLAN filter table
+ *  @value: register value written to VLAN filter table
+ *
+ *  Writes value at the given offset in the register array which stores
+ *  the VLAN filter table.
+ **/
+void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
+{
+	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
+	e1e_flush();
+}
+
+/**
+ *  e1000e_init_rx_addrs - Initialize receive address's
+ *  @hw: pointer to the HW structure
+ *  @rar_count: receive address registers
+ *
+ *  Setup the receive address registers by setting the base receive address
+ *  register to the devices MAC address and clearing all the other receive
+ *  address registers to 0.
+ **/
+void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
+{
+	u32 i;
+	u8 mac_addr[ETH_ALEN] = { 0 };
+
+	/* Setup the receive address */
+	e_dbg("Programming MAC Address into RAR[0]\n");
+
+	e1000e_rar_set(hw, hw->mac.addr, 0);
+
+	/* Zero out the other (rar_entry_count - 1) receive addresses */
+	e_dbg("Clearing RAR[1-%u]\n", rar_count - 1);
+	for (i = 1; i < rar_count; i++)
+		e1000e_rar_set(hw, mac_addr, i);
+}
+
+/**
+ *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks the nvm for an alternate MAC address.  An alternate MAC address
+ *  can be setup by pre-boot software and must be treated like a permanent
+ *  address and must override the actual permanent MAC address. If an
+ *  alternate MAC address is found it is programmed into RAR0, replacing
+ *  the permanent address that was installed into RAR0 by the Si on reset.
+ *  This function will return SUCCESS unless it encounters an error while
+ *  reading the EEPROM.
+ **/
+s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
+{
+	u32 i;
+	s32 ret_val = 0;
+	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
+	u8 alt_mac_addr[ETH_ALEN];
+
+	ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
+	if (ret_val)
+		return ret_val;
+
+	/* not supported on 82573 */
+	if (hw->mac.type == e1000_82573)
+		return 0;
+
+	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+				 &nvm_alt_mac_addr_offset);
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		return ret_val;
+	}
+
+	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
+	    (nvm_alt_mac_addr_offset == 0x0000))
+		/* There is no Alternate MAC Address */
+		return 0;
+
+	if (hw->bus.func == E1000_FUNC_1)
+		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
+	for (i = 0; i < ETH_ALEN; i += 2) {
+		offset = nvm_alt_mac_addr_offset + (i >> 1);
+		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
+		if (ret_val) {
+			e_dbg("NVM Read Error\n");
+			return ret_val;
+		}
+
+		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
+		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
+	}
+
+	/* if multicast bit is set, the alternate address will not be used */
+	if (is_multicast_ether_addr(alt_mac_addr)) {
+		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
+		return 0;
+	}
+
+	/*
+	 * We have a valid alternate MAC address, and we want to treat it the
+	 * same as the normal permanent MAC address stored by the HW into the
+	 * RAR. Do this by mapping this address into RAR0.
+	 */
+	e1000e_rar_set(hw, alt_mac_addr, 0);
+
+	return 0;
+}
+
+/**
+ *  e1000e_rar_set - Set receive address register
+ *  @hw: pointer to the HW structure
+ *  @addr: pointer to the receive address
+ *  @index: receive address array register
+ *
+ *  Sets the receive address array register at index to the address passed
+ *  in by addr.
+ **/
+void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
+{
+	u32 rar_low, rar_high;
+
+	/*
+	 * HW expects these in little endian so we reverse the byte order
+	 * from network order (big endian) to little endian
+	 */
+	rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
+		   ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
+
+	rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
+
+	/* If MAC address zero, no need to set the AV bit */
+	if (rar_low || rar_high)
+		rar_high |= E1000_RAH_AV;
+
+	/*
+	 * Some bridges will combine consecutive 32-bit writes into
+	 * a single burst write, which will malfunction on some parts.
+	 * The flushes avoid this.
+	 */
+	ew32(RAL(index), rar_low);
+	e1e_flush();
+	ew32(RAH(index), rar_high);
+	e1e_flush();
+}
+
+/**
+ *  e1000_hash_mc_addr - Generate a multicast hash value
+ *  @hw: pointer to the HW structure
+ *  @mc_addr: pointer to a multicast address
+ *
+ *  Generates a multicast address hash value which is used to determine
+ *  the multicast filter table array address and new table value.  See
+ *  e1000_mta_set_generic()
+ **/
+static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
+{
+	u32 hash_value, hash_mask;
+	u8 bit_shift = 0;
+
+	/* Register count multiplied by bits per register */
+	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
+
+	/*
+	 * For a mc_filter_type of 0, bit_shift is the number of left-shifts
+	 * where 0xFF would still fall within the hash mask.
+	 */
+	while (hash_mask >> bit_shift != 0xFF)
+		bit_shift++;
+
+	/*
+	 * The portion of the address that is used for the hash table
+	 * is determined by the mc_filter_type setting.
+	 * The algorithm is such that there is a total of 8 bits of shifting.
+	 * The bit_shift for a mc_filter_type of 0 represents the number of
+	 * left-shifts where the MSB of mc_addr[5] would still fall within
+	 * the hash_mask.  Case 0 does this exactly.  Since there are a total
+	 * of 8 bits of shifting, then mc_addr[4] will shift right the
+	 * remaining number of bits. Thus 8 - bit_shift.  The rest of the
+	 * cases are a variation of this algorithm...essentially raising the
+	 * number of bits to shift mc_addr[5] left, while still keeping the
+	 * 8-bit shifting total.
+	 *
+	 * For example, given the following Destination MAC Address and an
+	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
+	 * we can see that the bit_shift for case 0 is 4.  These are the hash
+	 * values resulting from each mc_filter_type...
+	 * [0] [1] [2] [3] [4] [5]
+	 * 01  AA  00  12  34  56
+	 * LSB           MSB
+	 *
+	 * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
+	 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
+	 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
+	 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
+	 */
+	switch (hw->mac.mc_filter_type) {
+	default:
+	case 0:
+		break;
+	case 1:
+		bit_shift += 1;
+		break;
+	case 2:
+		bit_shift += 2;
+		break;
+	case 3:
+		bit_shift += 4;
+		break;
+	}
+
+	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
+				   (((u16)mc_addr[5]) << bit_shift)));
+
+	return hash_value;
+}
+
+/**
+ *  e1000e_update_mc_addr_list_generic - Update Multicast addresses
+ *  @hw: pointer to the HW structure
+ *  @mc_addr_list: array of multicast addresses to program
+ *  @mc_addr_count: number of multicast addresses to program
+ *
+ *  Updates entire Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ **/
+void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
+					u8 *mc_addr_list, u32 mc_addr_count)
+{
+	u32 hash_value, hash_bit, hash_reg;
+	int i;
+
+	/* clear mta_shadow */
+	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
+
+	/* update mta_shadow from mc_addr_list */
+	for (i = 0; (u32)i < mc_addr_count; i++) {
+		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
+
+		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+		hash_bit = hash_value & 0x1F;
+
+		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
+		mc_addr_list += (ETH_ALEN);
+	}
+
+	/* replace the entire MTA table */
+	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
+	e1e_flush();
+}
+
+/**
+ *  e1000e_clear_hw_cntrs_base - Clear base hardware counters
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the base hardware counters by reading the counter registers.
+ **/
+void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
+{
+	er32(CRCERRS);
+	er32(SYMERRS);
+	er32(MPC);
+	er32(SCC);
+	er32(ECOL);
+	er32(MCC);
+	er32(LATECOL);
+	er32(COLC);
+	er32(DC);
+	er32(SEC);
+	er32(RLEC);
+	er32(XONRXC);
+	er32(XONTXC);
+	er32(XOFFRXC);
+	er32(XOFFTXC);
+	er32(FCRUC);
+	er32(GPRC);
+	er32(BPRC);
+	er32(MPRC);
+	er32(GPTC);
+	er32(GORCL);
+	er32(GORCH);
+	er32(GOTCL);
+	er32(GOTCH);
+	er32(RNBC);
+	er32(RUC);
+	er32(RFC);
+	er32(ROC);
+	er32(RJC);
+	er32(TORL);
+	er32(TORH);
+	er32(TOTL);
+	er32(TOTH);
+	er32(TPR);
+	er32(TPT);
+	er32(MPTC);
+	er32(BPTC);
+}
+
+/**
+ *  e1000e_check_for_copper_link - Check for link (Copper)
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks to see of the link status of the hardware has changed.  If a
+ *  change in link status has been detected, then we read the PHY registers
+ *  to get the current speed/duplex if link exists.
+ **/
+s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val;
+	bool link;
+
+	/*
+	 * We only want to go out to the PHY registers to see if Auto-Neg
+	 * has completed and/or if our link status has changed.  The
+	 * get_link_status flag is set upon receiving a Link Status
+	 * Change or Rx Sequence Error interrupt.
+	 */
+	if (!mac->get_link_status)
+		return 0;
+
+	/*
+	 * First we want to see if the MII Status Register reports
+	 * link.  If so, then we want to get the current speed/duplex
+	 * of the PHY.
+	 */
+	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
+	if (ret_val)
+		return ret_val;
+
+	if (!link)
+		return 0;	/* No link detected */
+
+	mac->get_link_status = false;
+
+	/*
+	 * Check if there was DownShift, must be checked
+	 * immediately after link-up
+	 */
+	e1000e_check_downshift(hw);
+
+	/*
+	 * If we are forcing speed/duplex, then we simply return since
+	 * we have already determined whether we have link or not.
+	 */
+	if (!mac->autoneg)
+		return -E1000_ERR_CONFIG;
+
+	/*
+	 * Auto-Neg is enabled.  Auto Speed Detection takes care
+	 * of MAC speed/duplex configuration.  So we only need to
+	 * configure Collision Distance in the MAC.
+	 */
+	e1000e_config_collision_dist(hw);
+
+	/*
+	 * Configure Flow Control now that Auto-Neg has completed.
+	 * First, we need to restore the desired flow control
+	 * settings because we may have had to re-autoneg with a
+	 * different link partner.
+	 */
+	ret_val = e1000e_config_fc_after_link_up(hw);
+	if (ret_val)
+		e_dbg("Error configuring flow control\n");
+
+	return ret_val;
+}
+
+/**
+ *  e1000e_check_for_fiber_link - Check for link (Fiber)
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks for link up on the hardware.  If link is not up and we have
+ *  a signal, then we need to force link up.
+ **/
+s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	u32 rxcw;
+	u32 ctrl;
+	u32 status;
+	s32 ret_val;
+
+	ctrl = er32(CTRL);
+	status = er32(STATUS);
+	rxcw = er32(RXCW);
+
+	/*
+	 * If we don't have link (auto-negotiation failed or link partner
+	 * cannot auto-negotiate), the cable is plugged in (we have signal),
+	 * and our link partner is not trying to auto-negotiate with us (we
+	 * are receiving idles or data), we need to force link up. We also
+	 * need to give auto-negotiation time to complete, in case the cable
+	 * was just plugged in. The autoneg_failed flag does this.
+	 */
+	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
+	if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) &&
+	    !(rxcw & E1000_RXCW_C)) {
+		if (!mac->autoneg_failed) {
+			mac->autoneg_failed = true;
+			return 0;
+		}
+		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
+
+		/* Disable auto-negotiation in the TXCW register */
+		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
+
+		/* Force link-up and also force full-duplex. */
+		ctrl = er32(CTRL);
+		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+		ew32(CTRL, ctrl);
+
+		/* Configure Flow Control after forcing link up. */
+		ret_val = e1000e_config_fc_after_link_up(hw);
+		if (ret_val) {
+			e_dbg("Error configuring flow control\n");
+			return ret_val;
+		}
+	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
+		/*
+		 * If we are forcing link and we are receiving /C/ ordered
+		 * sets, re-enable auto-negotiation in the TXCW register
+		 * and disable forced link in the Device Control register
+		 * in an attempt to auto-negotiate with our link partner.
+		 */
+		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
+		ew32(TXCW, mac->txcw);
+		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
+
+		mac->serdes_has_link = true;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_check_for_serdes_link - Check for link (Serdes)
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks for link up on the hardware.  If link is not up and we have
+ *  a signal, then we need to force link up.
+ **/
+s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	u32 rxcw;
+	u32 ctrl;
+	u32 status;
+	s32 ret_val;
+
+	ctrl = er32(CTRL);
+	status = er32(STATUS);
+	rxcw = er32(RXCW);
+
+	/*
+	 * If we don't have link (auto-negotiation failed or link partner
+	 * cannot auto-negotiate), and our link partner is not trying to
+	 * auto-negotiate with us (we are receiving idles or data),
+	 * we need to force link up. We also need to give auto-negotiation
+	 * time to complete.
+	 */
+	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
+	if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) {
+		if (!mac->autoneg_failed) {
+			mac->autoneg_failed = true;
+			return 0;
+		}
+		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
+
+		/* Disable auto-negotiation in the TXCW register */
+		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
+
+		/* Force link-up and also force full-duplex. */
+		ctrl = er32(CTRL);
+		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+		ew32(CTRL, ctrl);
+
+		/* Configure Flow Control after forcing link up. */
+		ret_val = e1000e_config_fc_after_link_up(hw);
+		if (ret_val) {
+			e_dbg("Error configuring flow control\n");
+			return ret_val;
+		}
+	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
+		/*
+		 * If we are forcing link and we are receiving /C/ ordered
+		 * sets, re-enable auto-negotiation in the TXCW register
+		 * and disable forced link in the Device Control register
+		 * in an attempt to auto-negotiate with our link partner.
+		 */
+		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
+		ew32(TXCW, mac->txcw);
+		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
+
+		mac->serdes_has_link = true;
+	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
+		/*
+		 * If we force link for non-auto-negotiation switch, check
+		 * link status based on MAC synchronization for internal
+		 * serdes media type.
+		 */
+		/* SYNCH bit and IV bit are sticky. */
+		udelay(10);
+		rxcw = er32(RXCW);
+		if (rxcw & E1000_RXCW_SYNCH) {
+			if (!(rxcw & E1000_RXCW_IV)) {
+				mac->serdes_has_link = true;
+				e_dbg("SERDES: Link up - forced.\n");
+			}
+		} else {
+			mac->serdes_has_link = false;
+			e_dbg("SERDES: Link down - force failed.\n");
+		}
+	}
+
+	if (E1000_TXCW_ANE & er32(TXCW)) {
+		status = er32(STATUS);
+		if (status & E1000_STATUS_LU) {
+			/* SYNCH bit and IV bit are sticky, so reread rxcw.  */
+			udelay(10);
+			rxcw = er32(RXCW);
+			if (rxcw & E1000_RXCW_SYNCH) {
+				if (!(rxcw & E1000_RXCW_IV)) {
+					mac->serdes_has_link = true;
+					e_dbg("SERDES: Link up - autoneg completed successfully.\n");
+				} else {
+					mac->serdes_has_link = false;
+					e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n");
+				}
+			} else {
+				mac->serdes_has_link = false;
+				e_dbg("SERDES: Link down - no sync.\n");
+			}
+		} else {
+			mac->serdes_has_link = false;
+			e_dbg("SERDES: Link down - autoneg failed\n");
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000_set_default_fc_generic - Set flow control default values
+ *  @hw: pointer to the HW structure
+ *
+ *  Read the EEPROM for the default values for flow control and store the
+ *  values.
+ **/
+static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u16 nvm_data;
+
+	/*
+	 * Read and store word 0x0F of the EEPROM. This word contains bits
+	 * that determine the hardware's default PAUSE (flow control) mode,
+	 * a bit that determines whether the HW defaults to enabling or
+	 * disabling auto-negotiation, and the direction of the
+	 * SW defined pins. If there is no SW over-ride of the flow
+	 * control setting, then the variable hw->fc will
+	 * be initialized based on a value in the EEPROM.
+	 */
+	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
+
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		return ret_val;
+	}
+
+	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
+		hw->fc.requested_mode = e1000_fc_none;
+	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR)
+		hw->fc.requested_mode = e1000_fc_tx_pause;
+	else
+		hw->fc.requested_mode = e1000_fc_full;
+
+	return 0;
+}
+
+/**
+ *  e1000e_setup_link - Setup flow control and link settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Determines which flow control settings to use, then configures flow
+ *  control.  Calls the appropriate media-specific link configuration
+ *  function.  Assuming the adapter has a valid link partner, a valid link
+ *  should be established.  Assumes the hardware has previously been reset
+ *  and the transmitter and receiver are not enabled.
+ **/
+s32 e1000e_setup_link(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val;
+
+	/*
+	 * In the case of the phy reset being blocked, we already have a link.
+	 * We do not need to set it up again.
+	 */
+	if (e1000_check_reset_block(hw))
+		return 0;
+
+	/*
+	 * If requested flow control is set to default, set flow control
+	 * based on the EEPROM flow control settings.
+	 */
+	if (hw->fc.requested_mode == e1000_fc_default) {
+		ret_val = e1000_set_default_fc_generic(hw);
+		if (ret_val)
+			return ret_val;
+	}
+
+	/*
+	 * Save off the requested flow control mode for use later.  Depending
+	 * on the link partner's capabilities, we may or may not use this mode.
+	 */
+	hw->fc.current_mode = hw->fc.requested_mode;
+
+	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
+
+	/* Call the necessary media_type subroutine to configure the link. */
+	ret_val = mac->ops.setup_physical_interface(hw);
+	if (ret_val)
+		return ret_val;
+
+	/*
+	 * Initialize the flow control address, type, and PAUSE timer
+	 * registers to their default values.  This is done even if flow
+	 * control is disabled, because it does not hurt anything to
+	 * initialize these registers.
+	 */
+	e_dbg("Initializing the Flow Control address, type and timer regs\n");
+	ew32(FCT, FLOW_CONTROL_TYPE);
+	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
+
+	ew32(FCTTV, hw->fc.pause_time);
+
+	return e1000e_set_fc_watermarks(hw);
+}
+
+/**
+ *  e1000_commit_fc_settings_generic - Configure flow control
+ *  @hw: pointer to the HW structure
+ *
+ *  Write the flow control settings to the Transmit Config Word Register (TXCW)
+ *  base on the flow control settings in e1000_mac_info.
+ **/
+static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	u32 txcw;
+
+	/*
+	 * Check for a software override of the flow control settings, and
+	 * setup the device accordingly.  If auto-negotiation is enabled, then
+	 * software will have to set the "PAUSE" bits to the correct value in
+	 * the Transmit Config Word Register (TXCW) and re-start auto-
+	 * negotiation.  However, if auto-negotiation is disabled, then
+	 * software will have to manually configure the two flow control enable
+	 * bits in the CTRL register.
+	 *
+	 * The possible values of the "fc" parameter are:
+	 *      0:  Flow control is completely disabled
+	 *      1:  Rx flow control is enabled (we can receive pause frames,
+	 *          but not send pause frames).
+	 *      2:  Tx flow control is enabled (we can send pause frames but we
+	 *          do not support receiving pause frames).
+	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
+	 */
+	switch (hw->fc.current_mode) {
+	case e1000_fc_none:
+		/* Flow control completely disabled by a software over-ride. */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
+		break;
+	case e1000_fc_rx_pause:
+		/*
+		 * Rx Flow control is enabled and Tx Flow control is disabled
+		 * by a software over-ride. Since there really isn't a way to
+		 * advertise that we are capable of Rx Pause ONLY, we will
+		 * advertise that we support both symmetric and asymmetric Rx
+		 * PAUSE.  Later, we will disable the adapter's ability to send
+		 * PAUSE frames.
+		 */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+		break;
+	case e1000_fc_tx_pause:
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is disabled,
+		 * by a software over-ride.
+		 */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
+		break;
+	case e1000_fc_full:
+		/*
+		 * Flow control (both Rx and Tx) is enabled by a software
+		 * over-ride.
+		 */
+		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+		break;
+	default:
+		e_dbg("Flow control param set incorrectly\n");
+		return -E1000_ERR_CONFIG;
+		break;
+	}
+
+	ew32(TXCW, txcw);
+	mac->txcw = txcw;
+
+	return 0;
+}
+
+/**
+ *  e1000_poll_fiber_serdes_link_generic - Poll for link up
+ *  @hw: pointer to the HW structure
+ *
+ *  Polls for link up by reading the status register, if link fails to come
+ *  up with auto-negotiation, then the link is forced if a signal is detected.
+ **/
+static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	u32 i, status;
+	s32 ret_val;
+
+	/*
+	 * If we have a signal (the cable is plugged in, or assumed true for
+	 * serdes media) then poll for a "Link-Up" indication in the Device
+	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds
+	 * seconds (Auto-negotiation should complete in less than 500
+	 * milliseconds even if the other end is doing it in SW).
+	 */
+	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
+		usleep_range(10000, 20000);
+		status = er32(STATUS);
+		if (status & E1000_STATUS_LU)
+			break;
+	}
+	if (i == FIBER_LINK_UP_LIMIT) {
+		e_dbg("Never got a valid link from auto-neg!!!\n");
+		mac->autoneg_failed = true;
+		/*
+		 * AutoNeg failed to achieve a link, so we'll call
+		 * mac->check_for_link. This routine will force the
+		 * link up if we detect a signal. This will allow us to
+		 * communicate with non-autonegotiating link partners.
+		 */
+		ret_val = mac->ops.check_for_link(hw);
+		if (ret_val) {
+			e_dbg("Error while checking for link\n");
+			return ret_val;
+		}
+		mac->autoneg_failed = false;
+	} else {
+		mac->autoneg_failed = false;
+		e_dbg("Valid Link Found\n");
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
+ *  @hw: pointer to the HW structure
+ *
+ *  Configures collision distance and flow control for fiber and serdes
+ *  links.  Upon successful setup, poll for link.
+ **/
+s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
+{
+	u32 ctrl;
+	s32 ret_val;
+
+	ctrl = er32(CTRL);
+
+	/* Take the link out of reset */
+	ctrl &= ~E1000_CTRL_LRST;
+
+	e1000e_config_collision_dist(hw);
+
+	ret_val = e1000_commit_fc_settings_generic(hw);
+	if (ret_val)
+		return ret_val;
+
+	/*
+	 * Since auto-negotiation is enabled, take the link out of reset (the
+	 * link will be in reset, because we previously reset the chip). This
+	 * will restart auto-negotiation.  If auto-negotiation is successful
+	 * then the link-up status bit will be set and the flow control enable
+	 * bits (RFCE and TFCE) will be set according to their negotiated value.
+	 */
+	e_dbg("Auto-negotiation enabled\n");
+
+	ew32(CTRL, ctrl);
+	e1e_flush();
+	usleep_range(1000, 2000);
+
+	/*
+	 * For these adapters, the SW definable pin 1 is set when the optics
+	 * detect a signal.  If we have a signal, then poll for a "Link-Up"
+	 * indication.
+	 */
+	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
+	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
+		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
+	} else {
+		e_dbg("No signal detected\n");
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000e_config_collision_dist - Configure collision distance
+ *  @hw: pointer to the HW structure
+ *
+ *  Configures the collision distance to the default value and is used
+ *  during link setup. Currently no func pointer exists and all
+ *  implementations are handled in the generic version of this function.
+ **/
+void e1000e_config_collision_dist(struct e1000_hw *hw)
+{
+	u32 tctl;
+
+	tctl = er32(TCTL);
+
+	tctl &= ~E1000_TCTL_COLD;
+	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+
+	ew32(TCTL, tctl);
+	e1e_flush();
+}
+
+/**
+ *  e1000e_set_fc_watermarks - Set flow control high/low watermarks
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets the flow control high/low threshold (watermark) registers.  If
+ *  flow control XON frame transmission is enabled, then set XON frame
+ *  transmission as well.
+ **/
+s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
+{
+	u32 fcrtl = 0, fcrth = 0;
+
+	/*
+	 * Set the flow control receive threshold registers.  Normally,
+	 * these registers will be set to a default threshold that may be
+	 * adjusted later by the driver's runtime code.  However, if the
+	 * ability to transmit pause frames is not enabled, then these
+	 * registers will be set to 0.
+	 */
+	if (hw->fc.current_mode & e1000_fc_tx_pause) {
+		/*
+		 * We need to set up the Receive Threshold high and low water
+		 * marks as well as (optionally) enabling the transmission of
+		 * XON frames.
+		 */
+		fcrtl = hw->fc.low_water;
+		fcrtl |= E1000_FCRTL_XONE;
+		fcrth = hw->fc.high_water;
+	}
+	ew32(FCRTL, fcrtl);
+	ew32(FCRTH, fcrth);
+
+	return 0;
+}
+
+/**
+ *  e1000e_force_mac_fc - Force the MAC's flow control settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
+ *  device control register to reflect the adapter settings.  TFCE and RFCE
+ *  need to be explicitly set by software when a copper PHY is used because
+ *  autonegotiation is managed by the PHY rather than the MAC.  Software must
+ *  also configure these bits when link is forced on a fiber connection.
+ **/
+s32 e1000e_force_mac_fc(struct e1000_hw *hw)
+{
+	u32 ctrl;
+
+	ctrl = er32(CTRL);
+
+	/*
+	 * Because we didn't get link via the internal auto-negotiation
+	 * mechanism (we either forced link or we got link via PHY
+	 * auto-neg), we have to manually enable/disable transmit an
+	 * receive flow control.
+	 *
+	 * The "Case" statement below enables/disable flow control
+	 * according to the "hw->fc.current_mode" parameter.
+	 *
+	 * The possible values of the "fc" parameter are:
+	 *      0:  Flow control is completely disabled
+	 *      1:  Rx flow control is enabled (we can receive pause
+	 *          frames but not send pause frames).
+	 *      2:  Tx flow control is enabled (we can send pause frames
+	 *          frames but we do not receive pause frames).
+	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
+	 *  other:  No other values should be possible at this point.
+	 */
+	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
+
+	switch (hw->fc.current_mode) {
+	case e1000_fc_none:
+		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
+		break;
+	case e1000_fc_rx_pause:
+		ctrl &= (~E1000_CTRL_TFCE);
+		ctrl |= E1000_CTRL_RFCE;
+		break;
+	case e1000_fc_tx_pause:
+		ctrl &= (~E1000_CTRL_RFCE);
+		ctrl |= E1000_CTRL_TFCE;
+		break;
+	case e1000_fc_full:
+		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
+		break;
+	default:
+		e_dbg("Flow control param set incorrectly\n");
+		return -E1000_ERR_CONFIG;
+	}
+
+	ew32(CTRL, ctrl);
+
+	return 0;
+}
+
+/**
+ *  e1000e_config_fc_after_link_up - Configures flow control after link
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks the status of auto-negotiation after link up to ensure that the
+ *  speed and duplex were not forced.  If the link needed to be forced, then
+ *  flow control needs to be forced also.  If auto-negotiation is enabled
+ *  and did not fail, then we configure flow control based on our link
+ *  partner.
+ **/
+s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val = 0;
+	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
+	u16 speed, duplex;
+
+	/*
+	 * Check for the case where we have fiber media and auto-neg failed
+	 * so we had to force link.  In this case, we need to force the
+	 * configuration of the MAC to match the "fc" parameter.
+	 */
+	if (mac->autoneg_failed) {
+		if (hw->phy.media_type == e1000_media_type_fiber ||
+		    hw->phy.media_type == e1000_media_type_internal_serdes)
+			ret_val = e1000e_force_mac_fc(hw);
+	} else {
+		if (hw->phy.media_type == e1000_media_type_copper)
+			ret_val = e1000e_force_mac_fc(hw);
+	}
+
+	if (ret_val) {
+		e_dbg("Error forcing flow control settings\n");
+		return ret_val;
+	}
+
+	/*
+	 * Check for the case where we have copper media and auto-neg is
+	 * enabled.  In this case, we need to check and see if Auto-Neg
+	 * has completed, and if so, how the PHY and link partner has
+	 * flow control configured.
+	 */
+	if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
+		/*
+		 * Read the MII Status Register and check to see if AutoNeg
+		 * has completed.  We read this twice because this reg has
+		 * some "sticky" (latched) bits.
+		 */
+		ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
+		if (ret_val)
+			return ret_val;
+		ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg);
+		if (ret_val)
+			return ret_val;
+
+		if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
+			e_dbg("Copper PHY and Auto Neg has not completed.\n");
+			return ret_val;
+		}
+
+		/*
+		 * The AutoNeg process has completed, so we now need to
+		 * read both the Auto Negotiation Advertisement
+		 * Register (Address 4) and the Auto_Negotiation Base
+		 * Page Ability Register (Address 5) to determine how
+		 * flow control was negotiated.
+		 */
+		ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg);
+		if (ret_val)
+			return ret_val;
+		ret_val =
+		    e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg);
+		if (ret_val)
+			return ret_val;
+
+		/*
+		 * Two bits in the Auto Negotiation Advertisement Register
+		 * (Address 4) and two bits in the Auto Negotiation Base
+		 * Page Ability Register (Address 5) determine flow control
+		 * for both the PHY and the link partner.  The following
+		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
+		 * 1999, describes these PAUSE resolution bits and how flow
+		 * control is determined based upon these settings.
+		 * NOTE:  DC = Don't Care
+		 *
+		 *   LOCAL DEVICE  |   LINK PARTNER
+		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
+		 *-------|---------|-------|---------|--------------------
+		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
+		 *   0   |    1    |   0   |   DC    | e1000_fc_none
+		 *   0   |    1    |   1   |    0    | e1000_fc_none
+		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+		 *   1   |    0    |   0   |   DC    | e1000_fc_none
+		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
+		 *   1   |    1    |   0   |    0    | e1000_fc_none
+		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+		 *
+		 * Are both PAUSE bits set to 1?  If so, this implies
+		 * Symmetric Flow Control is enabled at both ends.  The
+		 * ASM_DIR bits are irrelevant per the spec.
+		 *
+		 * For Symmetric Flow Control:
+		 *
+		 *   LOCAL DEVICE  |   LINK PARTNER
+		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+		 *-------|---------|-------|---------|--------------------
+		 *   1   |   DC    |   1   |   DC    | E1000_fc_full
+		 *
+		 */
+		if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+		    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
+			/*
+			 * Now we need to check if the user selected Rx ONLY
+			 * of pause frames.  In this case, we had to advertise
+			 * FULL flow control because we could not advertise Rx
+			 * ONLY. Hence, we must now check to see if we need to
+			 * turn OFF the TRANSMISSION of PAUSE frames.
+			 */
+			if (hw->fc.requested_mode == e1000_fc_full) {
+				hw->fc.current_mode = e1000_fc_full;
+				e_dbg("Flow Control = FULL.\n");
+			} else {
+				hw->fc.current_mode = e1000_fc_rx_pause;
+				e_dbg("Flow Control = Rx PAUSE frames only.\n");
+			}
+		}
+		/*
+		 * For receiving PAUSE frames ONLY.
+		 *
+		 *   LOCAL DEVICE  |   LINK PARTNER
+		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+		 *-------|---------|-------|---------|--------------------
+		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+		 */
+		else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+			 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+			hw->fc.current_mode = e1000_fc_tx_pause;
+			e_dbg("Flow Control = Tx PAUSE frames only.\n");
+		}
+		/*
+		 * For transmitting PAUSE frames ONLY.
+		 *
+		 *   LOCAL DEVICE  |   LINK PARTNER
+		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+		 *-------|---------|-------|---------|--------------------
+		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+		 */
+		else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+			hw->fc.current_mode = e1000_fc_rx_pause;
+			e_dbg("Flow Control = Rx PAUSE frames only.\n");
+		} else {
+			/*
+			 * Per the IEEE spec, at this point flow control
+			 * should be disabled.
+			 */
+			hw->fc.current_mode = e1000_fc_none;
+			e_dbg("Flow Control = NONE.\n");
+		}
+
+		/*
+		 * Now we need to do one last check...  If we auto-
+		 * negotiated to HALF DUPLEX, flow control should not be
+		 * enabled per IEEE 802.3 spec.
+		 */
+		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
+		if (ret_val) {
+			e_dbg("Error getting link speed and duplex\n");
+			return ret_val;
+		}
+
+		if (duplex == HALF_DUPLEX)
+			hw->fc.current_mode = e1000_fc_none;
+
+		/*
+		 * Now we call a subroutine to actually force the MAC
+		 * controller to use the correct flow control settings.
+		 */
+		ret_val = e1000e_force_mac_fc(hw);
+		if (ret_val) {
+			e_dbg("Error forcing flow control settings\n");
+			return ret_val;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
+ *  @hw: pointer to the HW structure
+ *  @speed: stores the current speed
+ *  @duplex: stores the current duplex
+ *
+ *  Read the status register for the current speed/duplex and store the current
+ *  speed and duplex for copper connections.
+ **/
+s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
+				       u16 *duplex)
+{
+	u32 status;
+
+	status = er32(STATUS);
+	if (status & E1000_STATUS_SPEED_1000)
+		*speed = SPEED_1000;
+	else if (status & E1000_STATUS_SPEED_100)
+		*speed = SPEED_100;
+	else
+		*speed = SPEED_10;
+
+	if (status & E1000_STATUS_FD)
+		*duplex = FULL_DUPLEX;
+	else
+		*duplex = HALF_DUPLEX;
+
+	e_dbg("%u Mbps, %s Duplex\n",
+	      *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
+	      *duplex == FULL_DUPLEX ? "Full" : "Half");
+
+	return 0;
+}
+
+/**
+ *  e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
+ *  @hw: pointer to the HW structure
+ *  @speed: stores the current speed
+ *  @duplex: stores the current duplex
+ *
+ *  Sets the speed and duplex to gigabit full duplex (the only possible option)
+ *  for fiber/serdes links.
+ **/
+s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed,
+					     u16 *duplex)
+{
+	*speed = SPEED_1000;
+	*duplex = FULL_DUPLEX;
+
+	return 0;
+}
+
+/**
+ *  e1000e_get_hw_semaphore - Acquire hardware semaphore
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquire the HW semaphore to access the PHY or NVM
+ **/
+s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
+{
+	u32 swsm;
+	s32 timeout = hw->nvm.word_size + 1;
+	s32 i = 0;
+
+	/* Get the SW semaphore */
+	while (i < timeout) {
+		swsm = er32(SWSM);
+		if (!(swsm & E1000_SWSM_SMBI))
+			break;
+
+		udelay(50);
+		i++;
+	}
+
+	if (i == timeout) {
+		e_dbg("Driver can't access device - SMBI bit is set.\n");
+		return -E1000_ERR_NVM;
+	}
+
+	/* Get the FW semaphore. */
+	for (i = 0; i < timeout; i++) {
+		swsm = er32(SWSM);
+		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
+
+		/* Semaphore acquired if bit latched */
+		if (er32(SWSM) & E1000_SWSM_SWESMBI)
+			break;
+
+		udelay(50);
+	}
+
+	if (i == timeout) {
+		/* Release semaphores */
+		e1000e_put_hw_semaphore(hw);
+		e_dbg("Driver can't access the NVM\n");
+		return -E1000_ERR_NVM;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_put_hw_semaphore - Release hardware semaphore
+ *  @hw: pointer to the HW structure
+ *
+ *  Release hardware semaphore used to access the PHY or NVM
+ **/
+void e1000e_put_hw_semaphore(struct e1000_hw *hw)
+{
+	u32 swsm;
+
+	swsm = er32(SWSM);
+	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+	ew32(SWSM, swsm);
+}
+
+/**
+ *  e1000e_get_auto_rd_done - Check for auto read completion
+ *  @hw: pointer to the HW structure
+ *
+ *  Check EEPROM for Auto Read done bit.
+ **/
+s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
+{
+	s32 i = 0;
+
+	while (i < AUTO_READ_DONE_TIMEOUT) {
+		if (er32(EECD) & E1000_EECD_AUTO_RD)
+			break;
+		usleep_range(1000, 2000);
+		i++;
+	}
+
+	if (i == AUTO_READ_DONE_TIMEOUT) {
+		e_dbg("Auto read by HW from NVM has not completed.\n");
+		return -E1000_ERR_RESET;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_valid_led_default - Verify a valid default LED config
+ *  @hw: pointer to the HW structure
+ *  @data: pointer to the NVM (EEPROM)
+ *
+ *  Read the EEPROM for the current default LED configuration.  If the
+ *  LED configuration is not valid, set to a valid LED configuration.
+ **/
+s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
+{
+	s32 ret_val;
+
+	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		return ret_val;
+	}
+
+	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
+		*data = ID_LED_DEFAULT;
+
+	return 0;
+}
+
+/**
+ *  e1000e_id_led_init -
+ *  @hw: pointer to the HW structure
+ *
+ **/
+s32 e1000e_id_led_init(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+	s32 ret_val;
+	const u32 ledctl_mask = 0x000000FF;
+	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
+	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
+	u16 data, i, temp;
+	const u16 led_mask = 0x0F;
+
+	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
+	if (ret_val)
+		return ret_val;
+
+	mac->ledctl_default = er32(LEDCTL);
+	mac->ledctl_mode1 = mac->ledctl_default;
+	mac->ledctl_mode2 = mac->ledctl_default;
+
+	for (i = 0; i < 4; i++) {
+		temp = (data >> (i << 2)) & led_mask;
+		switch (temp) {
+		case ID_LED_ON1_DEF2:
+		case ID_LED_ON1_ON2:
+		case ID_LED_ON1_OFF2:
+			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
+			mac->ledctl_mode1 |= ledctl_on << (i << 3);
+			break;
+		case ID_LED_OFF1_DEF2:
+		case ID_LED_OFF1_ON2:
+		case ID_LED_OFF1_OFF2:
+			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
+			mac->ledctl_mode1 |= ledctl_off << (i << 3);
+			break;
+		default:
+			/* Do nothing */
+			break;
+		}
+		switch (temp) {
+		case ID_LED_DEF1_ON2:
+		case ID_LED_ON1_ON2:
+		case ID_LED_OFF1_ON2:
+			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
+			mac->ledctl_mode2 |= ledctl_on << (i << 3);
+			break;
+		case ID_LED_DEF1_OFF2:
+		case ID_LED_ON1_OFF2:
+		case ID_LED_OFF1_OFF2:
+			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
+			mac->ledctl_mode2 |= ledctl_off << (i << 3);
+			break;
+		default:
+			/* Do nothing */
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_setup_led_generic - Configures SW controllable LED
+ *  @hw: pointer to the HW structure
+ *
+ *  This prepares the SW controllable LED for use and saves the current state
+ *  of the LED so it can be later restored.
+ **/
+s32 e1000e_setup_led_generic(struct e1000_hw *hw)
+{
+	u32 ledctl;
+
+	if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
+		return -E1000_ERR_CONFIG;
+
+	if (hw->phy.media_type == e1000_media_type_fiber) {
+		ledctl = er32(LEDCTL);
+		hw->mac.ledctl_default = ledctl;
+		/* Turn off LED0 */
+		ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK |
+			    E1000_LEDCTL_LED0_MODE_MASK);
+		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
+			   E1000_LEDCTL_LED0_MODE_SHIFT);
+		ew32(LEDCTL, ledctl);
+	} else if (hw->phy.media_type == e1000_media_type_copper) {
+		ew32(LEDCTL, hw->mac.ledctl_mode1);
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_cleanup_led_generic - Set LED config to default operation
+ *  @hw: pointer to the HW structure
+ *
+ *  Remove the current LED configuration and set the LED configuration
+ *  to the default value, saved from the EEPROM.
+ **/
+s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
+{
+	ew32(LEDCTL, hw->mac.ledctl_default);
+	return 0;
+}
+
+/**
+ *  e1000e_blink_led_generic - Blink LED
+ *  @hw: pointer to the HW structure
+ *
+ *  Blink the LEDs which are set to be on.
+ **/
+s32 e1000e_blink_led_generic(struct e1000_hw *hw)
+{
+	u32 ledctl_blink = 0;
+	u32 i;
+
+	if (hw->phy.media_type == e1000_media_type_fiber) {
+		/* always blink LED0 for PCI-E fiber */
+		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
+		    (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
+	} else {
+		/*
+		 * set the blink bit for each LED that's "on" (0x0E)
+		 * in ledctl_mode2
+		 */
+		ledctl_blink = hw->mac.ledctl_mode2;
+		for (i = 0; i < 4; i++)
+			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
+			    E1000_LEDCTL_MODE_LED_ON)
+				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
+						 (i * 8));
+	}
+
+	ew32(LEDCTL, ledctl_blink);
+
+	return 0;
+}
+
+/**
+ *  e1000e_led_on_generic - Turn LED on
+ *  @hw: pointer to the HW structure
+ *
+ *  Turn LED on.
+ **/
+s32 e1000e_led_on_generic(struct e1000_hw *hw)
+{
+	u32 ctrl;
+
+	switch (hw->phy.media_type) {
+	case e1000_media_type_fiber:
+		ctrl = er32(CTRL);
+		ctrl &= ~E1000_CTRL_SWDPIN0;
+		ctrl |= E1000_CTRL_SWDPIO0;
+		ew32(CTRL, ctrl);
+		break;
+	case e1000_media_type_copper:
+		ew32(LEDCTL, hw->mac.ledctl_mode2);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_led_off_generic - Turn LED off
+ *  @hw: pointer to the HW structure
+ *
+ *  Turn LED off.
+ **/
+s32 e1000e_led_off_generic(struct e1000_hw *hw)
+{
+	u32 ctrl;
+
+	switch (hw->phy.media_type) {
+	case e1000_media_type_fiber:
+		ctrl = er32(CTRL);
+		ctrl |= E1000_CTRL_SWDPIN0;
+		ctrl |= E1000_CTRL_SWDPIO0;
+		ew32(CTRL, ctrl);
+		break;
+	case e1000_media_type_copper:
+		ew32(LEDCTL, hw->mac.ledctl_mode1);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities
+ *  @hw: pointer to the HW structure
+ *  @no_snoop: bitmap of snoop events
+ *
+ *  Set the PCI-express register to snoop for events enabled in 'no_snoop'.
+ **/
+void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
+{
+	u32 gcr;
+
+	if (no_snoop) {
+		gcr = er32(GCR);
+		gcr &= ~(PCIE_NO_SNOOP_ALL);
+		gcr |= no_snoop;
+		ew32(GCR, gcr);
+	}
+}
+
+/**
+ *  e1000e_disable_pcie_master - Disables PCI-express master access
+ *  @hw: pointer to the HW structure
+ *
+ *  Returns 0 if successful, else returns -10
+ *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
+ *  the master requests to be disabled.
+ *
+ *  Disables PCI-Express master access and verifies there are no pending
+ *  requests.
+ **/
+s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
+{
+	u32 ctrl;
+	s32 timeout = MASTER_DISABLE_TIMEOUT;
+
+	ctrl = er32(CTRL);
+	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
+	ew32(CTRL, ctrl);
+
+	while (timeout) {
+		if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
+			break;
+		udelay(100);
+		timeout--;
+	}
+
+	if (!timeout) {
+		e_dbg("Master requests are pending.\n");
+		return -E1000_ERR_MASTER_REQUESTS_PENDING;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
+ *  @hw: pointer to the HW structure
+ *
+ *  Reset the Adaptive Interframe Spacing throttle to default values.
+ **/
+void e1000e_reset_adaptive(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+
+	if (!mac->adaptive_ifs) {
+		e_dbg("Not in Adaptive IFS mode!\n");
+		return;
+	}
+
+	mac->current_ifs_val = 0;
+	mac->ifs_min_val = IFS_MIN;
+	mac->ifs_max_val = IFS_MAX;
+	mac->ifs_step_size = IFS_STEP;
+	mac->ifs_ratio = IFS_RATIO;
+
+	mac->in_ifs_mode = false;
+	ew32(AIT, 0);
+}
+
+/**
+ *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
+ *  @hw: pointer to the HW structure
+ *
+ *  Update the Adaptive Interframe Spacing Throttle value based on the
+ *  time between transmitted packets and time between collisions.
+ **/
+void e1000e_update_adaptive(struct e1000_hw *hw)
+{
+	struct e1000_mac_info *mac = &hw->mac;
+
+	if (!mac->adaptive_ifs) {
+		e_dbg("Not in Adaptive IFS mode!\n");
+		return;
+	}
+
+	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
+		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
+			mac->in_ifs_mode = true;
+			if (mac->current_ifs_val < mac->ifs_max_val) {
+				if (!mac->current_ifs_val)
+					mac->current_ifs_val = mac->ifs_min_val;
+				else
+					mac->current_ifs_val +=
+					    mac->ifs_step_size;
+				ew32(AIT, mac->current_ifs_val);
+			}
+		}
+	} else {
+		if (mac->in_ifs_mode &&
+		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
+			mac->current_ifs_val = 0;
+			mac->in_ifs_mode = false;
+			ew32(AIT, 0);
+		}
+	}
+}
diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c
new file mode 100644
index 0000000..0d24b13
--- /dev/null
+++ b/drivers/net/ethernet/intel/e1000e/manage.c
@@ -0,0 +1,367 @@
+/*******************************************************************************
+
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2012 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "e1000.h"
+
+enum e1000_mng_mode {
+	e1000_mng_mode_none = 0,
+	e1000_mng_mode_asf,
+	e1000_mng_mode_pt,
+	e1000_mng_mode_ipmi,
+	e1000_mng_mode_host_if_only
+};
+
+#define E1000_FACTPS_MNGCG		0x20000000
+
+/* Intel(R) Active Management Technology signature */
+#define E1000_IAMT_SIGNATURE		0x544D4149
+
+/**
+ *  e1000_calculate_checksum - Calculate checksum for buffer
+ *  @buffer: pointer to EEPROM
+ *  @length: size of EEPROM to calculate a checksum for
+ *
+ *  Calculates the checksum for some buffer on a specified length.  The
+ *  checksum calculated is returned.
+ **/
+static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
+{
+	u32 i;
+	u8 sum = 0;
+
+	if (!buffer)
+		return 0;
+
+	for (i = 0; i < length; i++)
+		sum += buffer[i];
+
+	return (u8)(0 - sum);
+}
+
+/**
+ *  e1000_mng_enable_host_if - Checks host interface is enabled
+ *  @hw: pointer to the HW structure
+ *
+ *  Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
+ *
+ *  This function checks whether the HOST IF is enabled for command operation
+ *  and also checks whether the previous command is completed.  It busy waits
+ *  in case of previous command is not completed.
+ **/
+static s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
+{
+	u32 hicr;
+	u8 i;
+
+	if (!hw->mac.arc_subsystem_valid) {
+		e_dbg("ARC subsystem not valid.\n");
+		return -E1000_ERR_HOST_INTERFACE_COMMAND;
+	}
+
+	/* Check that the host interface is enabled. */
+	hicr = er32(HICR);
+	if ((hicr & E1000_HICR_EN) == 0) {
+		e_dbg("E1000_HOST_EN bit disabled.\n");
+		return -E1000_ERR_HOST_INTERFACE_COMMAND;
+	}
+	/* check the previous command is completed */
+	for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
+		hicr = er32(HICR);
+		if (!(hicr & E1000_HICR_C))
+			break;
+		mdelay(1);
+	}
+
+	if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
+		e_dbg("Previous command timeout failed .\n");
+		return -E1000_ERR_HOST_INTERFACE_COMMAND;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_check_mng_mode_generic - check management mode
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the firmware semaphore register and returns true (>0) if
+ *  manageability is enabled, else false (0).
+ **/
+bool e1000e_check_mng_mode_generic(struct e1000_hw *hw)
+{
+	u32 fwsm = er32(FWSM);
+
+	return (fwsm & E1000_FWSM_MODE_MASK) ==
+	    (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
+}
+
+/**
+ *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
+ *  @hw: pointer to the HW structure
+ *
+ *  Enables packet filtering on transmit packets if manageability is enabled
+ *  and host interface is enabled.
+ **/
+bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
+{
+	struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
+	u32 *buffer = (u32 *)&hw->mng_cookie;
+	u32 offset;
+	s32 ret_val, hdr_csum, csum;
+	u8 i, len;
+
+	hw->mac.tx_pkt_filtering = true;
+
+	/* No manageability, no filtering */
+	if (!e1000e_check_mng_mode(hw)) {
+		hw->mac.tx_pkt_filtering = false;
+		return hw->mac.tx_pkt_filtering;
+	}
+
+	/*
+	 * If we can't read from the host interface for whatever
+	 * reason, disable filtering.
+	 */
+	ret_val = e1000_mng_enable_host_if(hw);
+	if (ret_val) {
+		hw->mac.tx_pkt_filtering = false;
+		return hw->mac.tx_pkt_filtering;
+	}
+
+	/* Read in the header.  Length and offset are in dwords. */
+	len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
+	offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
+	for (i = 0; i < len; i++)
+		*(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF,
+						     offset + i);
+	hdr_csum = hdr->checksum;
+	hdr->checksum = 0;
+	csum = e1000_calculate_checksum((u8 *)hdr,
+					E1000_MNG_DHCP_COOKIE_LENGTH);
+	/*
+	 * If either the checksums or signature don't match, then
+	 * the cookie area isn't considered valid, in which case we
+	 * take the safe route of assuming Tx filtering is enabled.
+	 */
+	if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
+		hw->mac.tx_pkt_filtering = true;
+		return hw->mac.tx_pkt_filtering;
+	}
+
+	/* Cookie area is valid, make the final check for filtering. */
+	if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
+		hw->mac.tx_pkt_filtering = false;
+
+	return hw->mac.tx_pkt_filtering;
+}
+
+/**
+ *  e1000_mng_write_cmd_header - Writes manageability command header
+ *  @hw: pointer to the HW structure
+ *  @hdr: pointer to the host interface command header
+ *
+ *  Writes the command header after does the checksum calculation.
+ **/
+static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
+				      struct e1000_host_mng_command_header *hdr)
+{
+	u16 i, length = sizeof(struct e1000_host_mng_command_header);
+
+	/* Write the whole command header structure with new checksum. */
+
+	hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
+
+	length >>= 2;
+	/* Write the relevant command block into the ram area. */
+	for (i = 0; i < length; i++) {
+		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i));
+		e1e_flush();
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000_mng_host_if_write - Write to the manageability host interface
+ *  @hw: pointer to the HW structure
+ *  @buffer: pointer to the host interface buffer
+ *  @length: size of the buffer
+ *  @offset: location in the buffer to write to
+ *  @sum: sum of the data (not checksum)
+ *
+ *  This function writes the buffer content at the offset given on the host if.
+ *  It also does alignment considerations to do the writes in most efficient
+ *  way.  Also fills up the sum of the buffer in *buffer parameter.
+ **/
+static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
+				   u16 length, u16 offset, u8 *sum)
+{
+	u8 *tmp;
+	u8 *bufptr = buffer;
+	u32 data = 0;
+	u16 remaining, i, j, prev_bytes;
+
+	/* sum = only sum of the data and it is not checksum */
+
+	if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
+		return -E1000_ERR_PARAM;
+
+	tmp = (u8 *)&data;
+	prev_bytes = offset & 0x3;
+	offset >>= 2;
+
+	if (prev_bytes) {
+		data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset);
+		for (j = prev_bytes; j < sizeof(u32); j++) {
+			*(tmp + j) = *bufptr++;
+			*sum += *(tmp + j);
+		}
+		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data);
+		length -= j - prev_bytes;
+		offset++;
+	}
+
+	remaining = length & 0x3;
+	length -= remaining;
+
+	/* Calculate length in DWORDs */
+	length >>= 2;
+
+	/*
+	 * The device driver writes the relevant command block into the
+	 * ram area.
+	 */
+	for (i = 0; i < length; i++) {
+		for (j = 0; j < sizeof(u32); j++) {
+			*(tmp + j) = *bufptr++;
+			*sum += *(tmp + j);
+		}
+
+		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
+	}
+	if (remaining) {
+		for (j = 0; j < sizeof(u32); j++) {
+			if (j < remaining)
+				*(tmp + j) = *bufptr++;
+			else
+				*(tmp + j) = 0;
+
+			*sum += *(tmp + j);
+		}
+		E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data);
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_mng_write_dhcp_info - Writes DHCP info to host interface
+ *  @hw: pointer to the HW structure
+ *  @buffer: pointer to the host interface
+ *  @length: size of the buffer
+ *
+ *  Writes the DHCP information to the host interface.
+ **/
+s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
+{
+	struct e1000_host_mng_command_header hdr;
+	s32 ret_val;
+	u32 hicr;
+
+	hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
+	hdr.command_length = length;
+	hdr.reserved1 = 0;
+	hdr.reserved2 = 0;
+	hdr.checksum = 0;
+
+	/* Enable the host interface */
+	ret_val = e1000_mng_enable_host_if(hw);
+	if (ret_val)
+		return ret_val;
+
+	/* Populate the host interface with the contents of "buffer". */
+	ret_val = e1000_mng_host_if_write(hw, buffer, length,
+					  sizeof(hdr), &(hdr.checksum));
+	if (ret_val)
+		return ret_val;
+
+	/* Write the manageability command header */
+	ret_val = e1000_mng_write_cmd_header(hw, &hdr);
+	if (ret_val)
+		return ret_val;
+
+	/* Tell the ARC a new command is pending. */
+	hicr = er32(HICR);
+	ew32(HICR, hicr | E1000_HICR_C);
+
+	return 0;
+}
+
+/**
+ *  e1000e_enable_mng_pass_thru - Check if management passthrough is needed
+ *  @hw: pointer to the HW structure
+ *
+ *  Verifies the hardware needs to leave interface enabled so that frames can
+ *  be directed to and from the management interface.
+ **/
+bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw)
+{
+	u32 manc;
+	u32 fwsm, factps;
+
+	manc = er32(MANC);
+
+	if (!(manc & E1000_MANC_RCV_TCO_EN))
+		return false;
+
+	if (hw->mac.has_fwsm) {
+		fwsm = er32(FWSM);
+		factps = er32(FACTPS);
+
+		if (!(factps & E1000_FACTPS_MNGCG) &&
+		    ((fwsm & E1000_FWSM_MODE_MASK) ==
+		     (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
+			return true;
+	} else if ((hw->mac.type == e1000_82574) ||
+		   (hw->mac.type == e1000_82583)) {
+		u16 data;
+
+		factps = er32(FACTPS);
+		e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
+
+		if (!(factps & E1000_FACTPS_MNGCG) &&
+		    ((data & E1000_NVM_INIT_CTRL2_MNGM) ==
+		     (e1000_mng_mode_pt << 13)))
+			return true;
+	} else if ((manc & E1000_MANC_SMBUS_EN) &&
+		   !(manc & E1000_MANC_ASF_EN)) {
+		return true;
+	}
+
+	return false;
+}
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 3911401..732deba 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -56,7 +56,7 @@
 
 #define DRV_EXTRAVERSION "-k"
 
-#define DRV_VERSION "1.5.1" DRV_EXTRAVERSION
+#define DRV_VERSION "1.9.5" DRV_EXTRAVERSION
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -137,7 +137,7 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = {
 	{E1000_TDFPC, "TDFPC"},
 
 	/* List Terminator */
-	{}
+	{0, NULL}
 };
 
 /*
@@ -183,18 +183,18 @@ static void e1000e_dump(struct e1000_adapter *adapter)
 	struct e1000_ring *tx_ring = adapter->tx_ring;
 	struct e1000_tx_desc *tx_desc;
 	struct my_u0 {
-		u64 a;
-		u64 b;
+		__le64 a;
+		__le64 b;
 	} *u0;
 	struct e1000_buffer *buffer_info;
 	struct e1000_ring *rx_ring = adapter->rx_ring;
 	union e1000_rx_desc_packet_split *rx_desc_ps;
 	union e1000_rx_desc_extended *rx_desc;
 	struct my_u1 {
-		u64 a;
-		u64 b;
-		u64 c;
-		u64 d;
+		__le64 a;
+		__le64 b;
+		__le64 c;
+		__le64 d;
 	} *u1;
 	u32 staterr;
 	int i = 0;
@@ -221,7 +221,7 @@ static void e1000e_dump(struct e1000_adapter *adapter)
 
 	/* Print Tx Ring Summary */
 	if (!netdev || !netif_running(netdev))
-		goto exit;
+		return;
 
 	dev_info(&adapter->pdev->dev, "Tx Ring Summary\n");
 	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
@@ -308,7 +308,7 @@ rx_ring_summary:
 
 	/* Print Rx Ring */
 	if (!netif_msg_rx_status(adapter))
-		goto exit;
+		return;
 
 	dev_info(&adapter->pdev->dev, "Rx Ring Dump\n");
 	switch (adapter->rx_ps_pages) {
@@ -449,9 +449,6 @@ rx_ring_summary:
 			}
 		}
 	}
-
-exit:
-	return;
 }
 
 /**
@@ -487,22 +484,27 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
 
 /**
  * e1000_rx_checksum - Receive Checksum Offload
- * @adapter:     board private structure
- * @status_err:  receive descriptor status and error fields
- * @csum:	receive descriptor csum field
- * @sk_buff:     socket buffer with received data
+ * @adapter: board private structure
+ * @status_err: receive descriptor status and error fields
+ * @csum: receive descriptor csum field
+ * @sk_buff: socket buffer with received data
  **/
 static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
-			      u32 csum, struct sk_buff *skb)
+			      __le16 csum, struct sk_buff *skb)
 {
 	u16 status = (u16)status_err;
 	u8 errors = (u8)(status_err >> 24);
 
 	skb_checksum_none_assert(skb);
 
+	/* Rx checksum disabled */
+	if (!(adapter->netdev->features & NETIF_F_RXCSUM))
+		return;
+
 	/* Ignore Checksum bit is set */
 	if (status & E1000_RXD_STAT_IXSM)
 		return;
+
 	/* TCP/UDP checksum error bit is set */
 	if (errors & E1000_RXD_ERR_TCPE) {
 		/* let the stack verify checksum errors */
@@ -524,7 +526,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
 		 * Hardware complements the payload checksum, so we undo it
 		 * and then put the value in host order for further stack use.
 		 */
-		__sum16 sum = (__force __sum16)htons(csum);
+		__sum16 sum = (__force __sum16)swab16((__force u16)csum);
 		skb->csum = csum_unfold(~sum);
 		skb->ip_summed = CHECKSUM_COMPLETE;
 	}
@@ -545,7 +547,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
  * which has bit 24 set while ME is accessing Host CSR registers, wait
  * if it is set and try again a number of times.
  **/
-static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail,
+static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, void __iomem *tail,
 					unsigned int i)
 {
 	unsigned int j = 0;
@@ -562,12 +564,12 @@ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail,
 	return 0;
 }
 
-static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i)
+static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
 {
-	u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail);
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct e1000_hw *hw = &adapter->hw;
 
-	if (e1000e_update_tail_wa(hw, tail, i)) {
+	if (e1000e_update_tail_wa(hw, rx_ring->tail, i)) {
 		u32 rctl = er32(RCTL);
 		ew32(RCTL, rctl & ~E1000_RCTL_EN);
 		e_err("ME firmware caused invalid RDT - resetting\n");
@@ -575,12 +577,12 @@ static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i)
 	}
 }
 
-static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i)
+static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
 {
-	u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail);
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct e1000_hw *hw = &adapter->hw;
 
-	if (e1000e_update_tail_wa(hw, tail, i)) {
+	if (e1000e_update_tail_wa(hw, tx_ring->tail, i)) {
 		u32 tctl = er32(TCTL);
 		ew32(TCTL, tctl & ~E1000_TCTL_EN);
 		e_err("ME firmware caused invalid TDT - resetting\n");
@@ -590,14 +592,14 @@ static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i)
 
 /**
  * e1000_alloc_rx_buffers - Replace used receive buffers
- * @adapter: address of board private structure
+ * @rx_ring: Rx descriptor ring
  **/
-static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring,
 				   int cleaned_count, gfp_t gfp)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	union e1000_rx_desc_extended *rx_desc;
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
@@ -644,9 +646,9 @@ map_skb:
 			 */
 			wmb();
 			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
-				e1000e_update_rdt_wa(adapter, i);
+				e1000e_update_rdt_wa(rx_ring, i);
 			else
-				writel(i, adapter->hw.hw_addr + rx_ring->tail);
+				writel(i, rx_ring->tail);
 		}
 		i++;
 		if (i == rx_ring->count)
@@ -659,15 +661,15 @@ map_skb:
 
 /**
  * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
- * @adapter: address of board private structure
+ * @rx_ring: Rx descriptor ring
  **/
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring,
 				      int cleaned_count, gfp_t gfp)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	union e1000_rx_desc_packet_split *rx_desc;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	struct e1000_buffer *buffer_info;
 	struct e1000_ps_page *ps_page;
 	struct sk_buff *skb;
@@ -747,10 +749,9 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
 			 */
 			wmb();
 			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
-				e1000e_update_rdt_wa(adapter, i << 1);
+				e1000e_update_rdt_wa(rx_ring, i << 1);
 			else
-				writel(i << 1,
-				       adapter->hw.hw_addr + rx_ring->tail);
+				writel(i << 1, rx_ring->tail);
 		}
 
 		i++;
@@ -765,17 +766,17 @@ no_buffers:
 
 /**
  * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
- * @adapter: address of board private structure
+ * @rx_ring: Rx descriptor ring
  * @cleaned_count: number of buffers to allocate this pass
  **/
 
-static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
+static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring,
 					 int cleaned_count, gfp_t gfp)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	union e1000_rx_desc_extended *rx_desc;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
 	unsigned int i;
@@ -834,26 +835,33 @@ check_page:
 		 * such as IA-64). */
 		wmb();
 		if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
-			e1000e_update_rdt_wa(adapter, i);
+			e1000e_update_rdt_wa(rx_ring, i);
 		else
-			writel(i, adapter->hw.hw_addr + rx_ring->tail);
+			writel(i, rx_ring->tail);
 	}
 }
 
+static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
+				 struct sk_buff *skb)
+{
+	if (netdev->features & NETIF_F_RXHASH)
+		skb->rxhash = le32_to_cpu(rss);
+}
+
 /**
- * e1000_clean_rx_irq - Send received data up the network stack; legacy
- * @adapter: board private structure
+ * e1000_clean_rx_irq - Send received data up the network stack
+ * @rx_ring: Rx descriptor ring
  *
  * the return value indicates whether actual cleaning was done, there
  * is no guarantee that everything was cleaned
  **/
-static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
-			       int *work_done, int work_to_do)
+static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
+			       int work_to_do)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_hw *hw = &adapter->hw;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	union e1000_rx_desc_extended *rx_desc, *next_rxd;
 	struct e1000_buffer *buffer_info, *next_buffer;
 	u32 length, staterr;
@@ -957,8 +965,9 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 
 		/* Receive Checksum Offload */
 		e1000_rx_checksum(adapter, staterr,
-				  le16_to_cpu(rx_desc->wb.lower.hi_dword.
-					      csum_ip.csum), skb);
+				  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
+
+		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
 
 		e1000_receive_skb(adapter, netdev, skb, staterr,
 				  rx_desc->wb.upper.vlan);
@@ -968,7 +977,7 @@ next_desc:
 
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
-			adapter->alloc_rx_buf(adapter, cleaned_count,
+			adapter->alloc_rx_buf(rx_ring, cleaned_count,
 					      GFP_ATOMIC);
 			cleaned_count = 0;
 		}
@@ -983,16 +992,18 @@ next_desc:
 
 	cleaned_count = e1000_desc_unused(rx_ring);
 	if (cleaned_count)
-		adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC);
+		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
 
 	adapter->total_rx_bytes += total_rx_bytes;
 	adapter->total_rx_packets += total_rx_packets;
 	return cleaned;
 }
 
-static void e1000_put_txbuf(struct e1000_adapter *adapter,
-			     struct e1000_buffer *buffer_info)
+static void e1000_put_txbuf(struct e1000_ring *tx_ring,
+			    struct e1000_buffer *buffer_info)
 {
+	struct e1000_adapter *adapter = tx_ring->adapter;
+
 	if (buffer_info->dma) {
 		if (buffer_info->mapped_as_page)
 			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
@@ -1063,8 +1074,8 @@ static void e1000_print_hw_hang(struct work_struct *work)
 	      "PHY 1000BASE-T Status  <%x>\n"
 	      "PHY Extended Status    <%x>\n"
 	      "PCI Status             <%x>\n",
-	      readl(adapter->hw.hw_addr + tx_ring->head),
-	      readl(adapter->hw.hw_addr + tx_ring->tail),
+	      readl(tx_ring->head),
+	      readl(tx_ring->tail),
 	      tx_ring->next_to_use,
 	      tx_ring->next_to_clean,
 	      tx_ring->buffer_info[eop].time_stamp,
@@ -1080,16 +1091,16 @@ static void e1000_print_hw_hang(struct work_struct *work)
 
 /**
  * e1000_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring
  *
  * the return value indicates whether actual cleaning was done, there
  * is no guarantee that everything was cleaned
  **/
-static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
+static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
 {
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct e1000_hw *hw = &adapter->hw;
-	struct e1000_ring *tx_ring = adapter->tx_ring;
 	struct e1000_tx_desc *tx_desc, *eop_desc;
 	struct e1000_buffer *buffer_info;
 	unsigned int i, eop;
@@ -1119,7 +1130,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 				}
 			}
 
-			e1000_put_txbuf(adapter, buffer_info);
+			e1000_put_txbuf(tx_ring, buffer_info);
 			tx_desc->upper.data = 0;
 
 			i++;
@@ -1173,19 +1184,19 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 
 /**
  * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
- * @adapter: board private structure
+ * @rx_ring: Rx descriptor ring
  *
  * the return value indicates whether actual cleaning was done, there
  * is no guarantee that everything was cleaned
  **/
-static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-				  int *work_done, int work_to_do)
+static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
+				  int work_to_do)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct e1000_hw *hw = &adapter->hw;
 	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	struct e1000_buffer *buffer_info, *next_buffer;
 	struct e1000_ps_page *ps_page;
 	struct sk_buff *skb;
@@ -1253,43 +1264,48 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 		skb_put(skb, length);
 
 		{
-		/*
-		 * this looks ugly, but it seems compiler issues make it
-		 * more efficient than reusing j
-		 */
-		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
-
-		/*
-		 * page alloc/put takes too long and effects small packet
-		 * throughput, so unsplit small packets and save the alloc/put
-		 * only valid in softirq (napi) context to call kmap_*
-		 */
-		if (l1 && (l1 <= copybreak) &&
-		    ((length + l1) <= adapter->rx_ps_bsize0)) {
-			u8 *vaddr;
-
-			ps_page = &buffer_info->ps_pages[0];
+			/*
+			 * this looks ugly, but it seems compiler issues make
+			 * it more efficient than reusing j
+			 */
+			int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
 
 			/*
-			 * there is no documentation about how to call
-			 * kmap_atomic, so we can't hold the mapping
-			 * very long
+			 * page alloc/put takes too long and effects small
+			 * packet throughput, so unsplit small packets and
+			 * save the alloc/put only valid in softirq (napi)
+			 * context to call kmap_*
 			 */
-			dma_sync_single_for_cpu(&pdev->dev, ps_page->dma,
-						PAGE_SIZE, DMA_FROM_DEVICE);
-			vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
-			memcpy(skb_tail_pointer(skb), vaddr, l1);
-			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
-			dma_sync_single_for_device(&pdev->dev, ps_page->dma,
-						   PAGE_SIZE, DMA_FROM_DEVICE);
-
-			/* remove the CRC */
-			if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
-				l1 -= 4;
-
-			skb_put(skb, l1);
-			goto copydone;
-		} /* if */
+			if (l1 && (l1 <= copybreak) &&
+			    ((length + l1) <= adapter->rx_ps_bsize0)) {
+				u8 *vaddr;
+
+				ps_page = &buffer_info->ps_pages[0];
+
+				/*
+				 * there is no documentation about how to call
+				 * kmap_atomic, so we can't hold the mapping
+				 * very long
+				 */
+				dma_sync_single_for_cpu(&pdev->dev,
+							ps_page->dma,
+							PAGE_SIZE,
+							DMA_FROM_DEVICE);
+				vaddr = kmap_atomic(ps_page->page);
+				memcpy(skb_tail_pointer(skb), vaddr, l1);
+				kunmap_atomic(vaddr);
+				dma_sync_single_for_device(&pdev->dev,
+							   ps_page->dma,
+							   PAGE_SIZE,
+							   DMA_FROM_DEVICE);
+
+				/* remove the CRC */
+				if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
+					l1 -= 4;
+
+				skb_put(skb, l1);
+				goto copydone;
+			} /* if */
 		}
 
 		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
@@ -1318,8 +1334,10 @@ copydone:
 		total_rx_bytes += skb->len;
 		total_rx_packets++;
 
-		e1000_rx_checksum(adapter, staterr, le16_to_cpu(
-			rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
+		e1000_rx_checksum(adapter, staterr,
+				  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
+
+		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
 
 		if (rx_desc->wb.upper.header_status &
 			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
@@ -1334,7 +1352,7 @@ next_desc:
 
 		/* return some buffers to hardware, one at a time is too slow */
 		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
-			adapter->alloc_rx_buf(adapter, cleaned_count,
+			adapter->alloc_rx_buf(rx_ring, cleaned_count,
 					      GFP_ATOMIC);
 			cleaned_count = 0;
 		}
@@ -1349,7 +1367,7 @@ next_desc:
 
 	cleaned_count = e1000_desc_unused(rx_ring);
 	if (cleaned_count)
-		adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC);
+		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
 
 	adapter->total_rx_bytes += total_rx_bytes;
 	adapter->total_rx_packets += total_rx_packets;
@@ -1375,13 +1393,12 @@ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
  * the return value indicates whether actual cleaning was done, there
  * is no guarantee that everything was cleaned
  **/
-
-static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
-                                     int *work_done, int work_to_do)
+static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
+				     int work_to_do)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	union e1000_rx_desc_extended *rx_desc, *next_rxd;
 	struct e1000_buffer *buffer_info, *next_buffer;
 	u32 length, staterr;
@@ -1470,12 +1487,10 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
 				if (length <= copybreak &&
 				    skb_tailroom(skb) >= length) {
 					u8 *vaddr;
-					vaddr = kmap_atomic(buffer_info->page,
-					                   KM_SKB_DATA_SOFTIRQ);
+					vaddr = kmap_atomic(buffer_info->page);
 					memcpy(skb_tail_pointer(skb), vaddr,
 					       length);
-					kunmap_atomic(vaddr,
-					              KM_SKB_DATA_SOFTIRQ);
+					kunmap_atomic(vaddr);
 					/* re-use the page, so don't erase
 					 * buffer_info->page */
 					skb_put(skb, length);
@@ -1491,8 +1506,9 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
 
 		/* Receive Checksum Offload XXX recompute due to CRC strip? */
 		e1000_rx_checksum(adapter, staterr,
-				  le16_to_cpu(rx_desc->wb.lower.hi_dword.
-					      csum_ip.csum), skb);
+				  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
+
+		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
 
 		/* probably a little skewed due to removing CRC */
 		total_rx_bytes += skb->len;
@@ -1513,7 +1529,7 @@ next_desc:
 
 		/* return some buffers to hardware, one at a time is too slow */
 		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
-			adapter->alloc_rx_buf(adapter, cleaned_count,
+			adapter->alloc_rx_buf(rx_ring, cleaned_count,
 					      GFP_ATOMIC);
 			cleaned_count = 0;
 		}
@@ -1528,7 +1544,7 @@ next_desc:
 
 	cleaned_count = e1000_desc_unused(rx_ring);
 	if (cleaned_count)
-		adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC);
+		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
 
 	adapter->total_rx_bytes += total_rx_bytes;
 	adapter->total_rx_packets += total_rx_packets;
@@ -1537,11 +1553,11 @@ next_desc:
 
 /**
  * e1000_clean_rx_ring - Free Rx Buffers per Queue
- * @adapter: board private structure
+ * @rx_ring: Rx descriptor ring
  **/
-static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
+static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
 {
-	struct e1000_ring *rx_ring = adapter->rx_ring;
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct e1000_buffer *buffer_info;
 	struct e1000_ps_page *ps_page;
 	struct pci_dev *pdev = adapter->pdev;
@@ -1601,8 +1617,8 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
 	rx_ring->next_to_use = 0;
 	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
 
-	writel(0, adapter->hw.hw_addr + rx_ring->head);
-	writel(0, adapter->hw.hw_addr + rx_ring->tail);
+	writel(0, rx_ring->head);
+	writel(0, rx_ring->tail);
 }
 
 static void e1000e_downshift_workaround(struct work_struct *work)
@@ -1633,7 +1649,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
 	 */
 
 	if (icr & E1000_ICR_LSC) {
-		hw->mac.get_link_status = 1;
+		hw->mac.get_link_status = true;
 		/*
 		 * ICH8 workaround-- Call gig speed drop workaround on cable
 		 * disconnect (LSC) before accessing any PHY registers
@@ -1699,7 +1715,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
 	 */
 
 	if (icr & E1000_ICR_LSC) {
-		hw->mac.get_link_status = 1;
+		hw->mac.get_link_status = true;
 		/*
 		 * ICH8 workaround-- Call gig speed drop workaround on cable
 		 * disconnect (LSC) before accessing any PHY registers
@@ -1756,7 +1772,7 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
 	if (icr & E1000_ICR_OTHER) {
 		if (!(icr & E1000_ICR_LSC))
 			goto no_link_interrupt;
-		hw->mac.get_link_status = 1;
+		hw->mac.get_link_status = true;
 		/* guard against interrupt when we're going down */
 		if (!test_bit(__E1000_DOWN, &adapter->state))
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
@@ -1781,7 +1797,7 @@ static irqreturn_t e1000_intr_msix_tx(int irq, void *data)
 	adapter->total_tx_bytes = 0;
 	adapter->total_tx_packets = 0;
 
-	if (!e1000_clean_tx_irq(adapter))
+	if (!e1000_clean_tx_irq(tx_ring))
 		/* Ring was not completely cleaned, so fire another interrupt */
 		ew32(ICS, tx_ring->ims_val);
 
@@ -1792,14 +1808,15 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
 {
 	struct net_device *netdev = data;
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_ring *rx_ring = adapter->rx_ring;
 
 	/* Write the ITR value calculated at the end of the
 	 * previous interrupt.
 	 */
-	if (adapter->rx_ring->set_itr) {
-		writel(1000000000 / (adapter->rx_ring->itr_val * 256),
-		       adapter->hw.hw_addr + adapter->rx_ring->itr_register);
-		adapter->rx_ring->set_itr = 0;
+	if (rx_ring->set_itr) {
+		writel(1000000000 / (rx_ring->itr_val * 256),
+		       rx_ring->itr_register);
+		rx_ring->set_itr = 0;
 	}
 
 	if (napi_schedule_prep(&adapter->napi)) {
@@ -1839,9 +1856,9 @@ static void e1000_configure_msix(struct e1000_adapter *adapter)
 	adapter->eiac_mask |= rx_ring->ims_val;
 	if (rx_ring->itr_val)
 		writel(1000000000 / (rx_ring->itr_val * 256),
-		       hw->hw_addr + rx_ring->itr_register);
+		       rx_ring->itr_register);
 	else
-		writel(1, hw->hw_addr + rx_ring->itr_register);
+		writel(1, rx_ring->itr_register);
 	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
 
 	/* Configure Tx vector */
@@ -1849,9 +1866,9 @@ static void e1000_configure_msix(struct e1000_adapter *adapter)
 	vector++;
 	if (tx_ring->itr_val)
 		writel(1000000000 / (tx_ring->itr_val * 256),
-		       hw->hw_addr + tx_ring->itr_register);
+		       tx_ring->itr_register);
 	else
-		writel(1, hw->hw_addr + tx_ring->itr_register);
+		writel(1, tx_ring->itr_register);
 	adapter->eiac_mask |= tx_ring->ims_val;
 	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
 
@@ -1965,8 +1982,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
 			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
 			  netdev);
 	if (err)
-		goto out;
-	adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
+		return err;
+	adapter->rx_ring->itr_register = adapter->hw.hw_addr +
+	    E1000_EITR_82574(vector);
 	adapter->rx_ring->itr_val = adapter->itr;
 	vector++;
 
@@ -1980,20 +1998,20 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
 			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
 			  netdev);
 	if (err)
-		goto out;
-	adapter->tx_ring->itr_register = E1000_EITR_82574(vector);
+		return err;
+	adapter->tx_ring->itr_register = adapter->hw.hw_addr +
+	    E1000_EITR_82574(vector);
 	adapter->tx_ring->itr_val = adapter->itr;
 	vector++;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
 			  e1000_msix_other, 0, netdev->name, netdev);
 	if (err)
-		goto out;
+		return err;
 
 	e1000_configure_msix(adapter);
+
 	return 0;
-out:
-	return err;
 }
 
 /**
@@ -2162,13 +2180,13 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
 
 /**
  * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
- * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring
  *
  * Return 0 on success, negative on failure
  **/
-int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
+int e1000e_setup_tx_resources(struct e1000_ring *tx_ring)
 {
-	struct e1000_ring *tx_ring = adapter->tx_ring;
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	int err = -ENOMEM, size;
 
 	size = sizeof(struct e1000_buffer) * tx_ring->count;
@@ -2196,13 +2214,13 @@ err:
 
 /**
  * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
- * @adapter: board private structure
+ * @rx_ring: Rx descriptor ring
  *
  * Returns 0 on success, negative on failure
  **/
-int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
+int e1000e_setup_rx_resources(struct e1000_ring *rx_ring)
 {
-	struct e1000_ring *rx_ring = adapter->rx_ring;
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct e1000_buffer *buffer_info;
 	int i, size, desc_len, err = -ENOMEM;
 
@@ -2249,18 +2267,18 @@ err:
 
 /**
  * e1000_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring
  **/
-static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
+static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
 {
-	struct e1000_ring *tx_ring = adapter->tx_ring;
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct e1000_buffer *buffer_info;
 	unsigned long size;
 	unsigned int i;
 
 	for (i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
-		e1000_put_txbuf(adapter, buffer_info);
+		e1000_put_txbuf(tx_ring, buffer_info);
 	}
 
 	netdev_reset_queue(adapter->netdev);
@@ -2272,22 +2290,22 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
 
-	writel(0, adapter->hw.hw_addr + tx_ring->head);
-	writel(0, adapter->hw.hw_addr + tx_ring->tail);
+	writel(0, tx_ring->head);
+	writel(0, tx_ring->tail);
 }
 
 /**
  * e1000e_free_tx_resources - Free Tx Resources per Queue
- * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring
  *
  * Free all transmit software resources
  **/
-void e1000e_free_tx_resources(struct e1000_adapter *adapter)
+void e1000e_free_tx_resources(struct e1000_ring *tx_ring)
 {
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_ring *tx_ring = adapter->tx_ring;
 
-	e1000_clean_tx_ring(adapter);
+	e1000_clean_tx_ring(tx_ring);
 
 	vfree(tx_ring->buffer_info);
 	tx_ring->buffer_info = NULL;
@@ -2299,18 +2317,17 @@ void e1000e_free_tx_resources(struct e1000_adapter *adapter)
 
 /**
  * e1000e_free_rx_resources - Free Rx Resources
- * @adapter: board private structure
+ * @rx_ring: Rx descriptor ring
  *
  * Free all receive software resources
  **/
-
-void e1000e_free_rx_resources(struct e1000_adapter *adapter)
+void e1000e_free_rx_resources(struct e1000_ring *rx_ring)
 {
+	struct e1000_adapter *adapter = rx_ring->adapter;
 	struct pci_dev *pdev = adapter->pdev;
-	struct e1000_ring *rx_ring = adapter->rx_ring;
 	int i;
 
-	e1000_clean_rx_ring(adapter);
+	e1000_clean_rx_ring(rx_ring);
 
 	for (i = 0; i < rx_ring->count; i++)
 		kfree(rx_ring->buffer_info[i].ps_pages);
@@ -2346,7 +2363,7 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
 	unsigned int retval = itr_setting;
 
 	if (packets == 0)
-		goto update_itr_done;
+		return itr_setting;
 
 	switch (itr_setting) {
 	case lowest_latency:
@@ -2381,7 +2398,6 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
 		break;
 	}
 
-update_itr_done:
 	return retval;
 }
 
@@ -2464,13 +2480,19 @@ set_itr_now:
  **/
 static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
 {
-	adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+	int size = sizeof(struct e1000_ring);
+
+	adapter->tx_ring = kzalloc(size, GFP_KERNEL);
 	if (!adapter->tx_ring)
 		goto err;
+	adapter->tx_ring->count = adapter->tx_ring_count;
+	adapter->tx_ring->adapter = adapter;
 
-	adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+	adapter->rx_ring = kzalloc(size, GFP_KERNEL);
 	if (!adapter->rx_ring)
 		goto err;
+	adapter->rx_ring->count = adapter->rx_ring_count;
+	adapter->rx_ring->adapter = adapter;
 
 	return 0;
 err:
@@ -2498,10 +2520,10 @@ static int e1000_clean(struct napi_struct *napi, int budget)
 	    !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
 		goto clean_rx;
 
-	tx_cleaned = e1000_clean_tx_irq(adapter);
+	tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
 
 clean_rx:
-	adapter->clean_rx(adapter, &work_done, budget);
+	adapter->clean_rx(adapter->rx_ring, &work_done, budget);
 
 	if (!tx_cleaned)
 		work_done = budget;
@@ -2746,8 +2768,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_ring *tx_ring = adapter->tx_ring;
 	u64 tdba;
-	u32 tdlen, tctl, tipg, tarc;
-	u32 ipgr1, ipgr2;
+	u32 tdlen, tarc;
 
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 	tdba = tx_ring->dma;
@@ -2757,20 +2778,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 	ew32(TDLEN, tdlen);
 	ew32(TDH, 0);
 	ew32(TDT, 0);
-	tx_ring->head = E1000_TDH;
-	tx_ring->tail = E1000_TDT;
-
-	/* Set the default values for the Tx Inter Packet Gap timer */
-	tipg = DEFAULT_82543_TIPG_IPGT_COPPER;          /*  8  */
-	ipgr1 = DEFAULT_82543_TIPG_IPGR1;               /*  8  */
-	ipgr2 = DEFAULT_82543_TIPG_IPGR2;               /*  6  */
-
-	if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN)
-		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /*  7  */
-
-	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
-	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
-	ew32(TIPG, tipg);
+	tx_ring->head = adapter->hw.hw_addr + E1000_TDH;
+	tx_ring->tail = adapter->hw.hw_addr + E1000_TDT;
 
 	/* Set the Tx Interrupt Delay register */
 	ew32(TIDV, adapter->tx_int_delay);
@@ -2793,15 +2802,9 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 		 */
 		txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
 		ew32(TXDCTL(0), txdctl);
-		/* erratum work around: set txdctl the same for both queues */
-		ew32(TXDCTL(1), txdctl);
 	}
-
-	/* Program the Transmit Control Register */
-	tctl = er32(TCTL);
-	tctl &= ~E1000_TCTL_CT;
-	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
-		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+	/* erratum work around: set txdctl the same for both queues */
+	ew32(TXDCTL(1), er32(TXDCTL(0)));
 
 	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
 		tarc = er32(TARC(0));
@@ -2834,8 +2837,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 	/* enable Report Status bit */
 	adapter->txd_cmd |= E1000_TXD_CMD_RS;
 
-	ew32(TCTL, tctl);
-
 	e1000e_config_collision_dist(hw);
 }
 
@@ -2944,8 +2945,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 	 * per packet.
 	 */
 	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-	if (!(adapter->flags & FLAG_HAS_ERT) && (pages <= 3) &&
-	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
+	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
 		adapter->rx_ps_pages = pages;
 	else
 		adapter->rx_ps_pages = 0;
@@ -3072,8 +3072,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	ew32(RDLEN, rdlen);
 	ew32(RDH, 0);
 	ew32(RDT, 0);
-	rx_ring->head = E1000_RDH;
-	rx_ring->tail = E1000_RDT;
+	rx_ring->head = adapter->hw.hw_addr + E1000_RDH;
+	rx_ring->tail = adapter->hw.hw_addr + E1000_RDT;
 
 	/* Enable Receive Checksum Offload for TCP and UDP */
 	rxcsum = er32(RXCSUM);
@@ -3092,23 +3092,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	}
 	ew32(RXCSUM, rxcsum);
 
-	/*
-	 * Enable early receives on supported devices, only takes effect when
-	 * packet size is equal or larger than the specified value (in 8 byte
-	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
-	 */
-	if ((adapter->flags & FLAG_HAS_ERT) ||
-	    (adapter->hw.mac.type == e1000_pch2lan)) {
+	if (adapter->hw.mac.type == e1000_pch2lan) {
+		/*
+		 * With jumbo frames, excessive C-state transition
+		 * latencies result in dropped transactions.
+		 */
 		if (adapter->netdev->mtu > ETH_DATA_LEN) {
 			u32 rxdctl = er32(RXDCTL(0));
 			ew32(RXDCTL(0), rxdctl | 0x3);
-			if (adapter->flags & FLAG_HAS_ERT)
-				ew32(ERT, E1000_ERT_2048 | (1 << 13));
-			/*
-			 * With jumbo frames and early-receive enabled,
-			 * excessive C-state transition latencies result in
-			 * dropped transactions.
-			 */
 			pm_qos_update_request(&adapter->netdev->pm_qos_req, 55);
 		} else {
 			pm_qos_update_request(&adapter->netdev->pm_qos_req,
@@ -3268,22 +3259,62 @@ static void e1000e_set_rx_mode(struct net_device *netdev)
 		e1000e_vlan_strip_disable(adapter);
 }
 
+static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 mrqc, rxcsum;
+	int i;
+	static const u32 rsskey[10] = {
+		0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
+		0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
+	};
+
+	/* Fill out hash function seed */
+	for (i = 0; i < 10; i++)
+		ew32(RSSRK(i), rsskey[i]);
+
+	/* Direct all traffic to queue 0 */
+	for (i = 0; i < 32; i++)
+		ew32(RETA(i), 0);
+
+	/*
+	 * Disable raw packet checksumming so that RSS hash is placed in
+	 * descriptor on writeback.
+	 */
+	rxcsum = er32(RXCSUM);
+	rxcsum |= E1000_RXCSUM_PCSD;
+
+	ew32(RXCSUM, rxcsum);
+
+	mrqc = (E1000_MRQC_RSS_FIELD_IPV4 |
+		E1000_MRQC_RSS_FIELD_IPV4_TCP |
+		E1000_MRQC_RSS_FIELD_IPV6 |
+		E1000_MRQC_RSS_FIELD_IPV6_TCP |
+		E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
+
+	ew32(MRQC, mrqc);
+}
+
 /**
  * e1000_configure - configure the hardware for Rx and Tx
  * @adapter: private board structure
  **/
 static void e1000_configure(struct e1000_adapter *adapter)
 {
+	struct e1000_ring *rx_ring = adapter->rx_ring;
+
 	e1000e_set_rx_mode(adapter->netdev);
 
 	e1000_restore_vlan(adapter);
 	e1000_init_manageability_pt(adapter);
 
 	e1000_configure_tx(adapter);
+
+	if (adapter->netdev->features & NETIF_F_RXHASH)
+		e1000e_setup_rss_hash(adapter);
 	e1000_setup_rctl(adapter);
 	e1000_configure_rx(adapter);
-	adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring),
-			      GFP_KERNEL);
+	adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
 }
 
 /**
@@ -3379,9 +3410,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
 			 * if short on Rx space, Rx wins and must trump Tx
 			 * adjustment or use Early Receive if available
 			 */
-			if ((pba < min_rx_space) &&
-			    (!(adapter->flags & FLAG_HAS_ERT)))
-				/* ERT enabled in e1000_configure_rx */
+			if (pba < min_rx_space)
 				pba = min_rx_space;
 		}
 
@@ -3395,8 +3424,6 @@ void e1000e_reset(struct e1000_adapter *adapter)
 	 * (or the size used for early receive) above it in the Rx FIFO.
 	 * Set it to the lower of:
 	 * - 90% of the Rx FIFO size, and
-	 * - the full Rx FIFO size minus the early receive size (for parts
-	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
 	 * - the full Rx FIFO size minus one full frame
 	 */
 	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
@@ -3407,14 +3434,19 @@ void e1000e_reset(struct e1000_adapter *adapter)
 	fc->current_mode = fc->requested_mode;
 
 	switch (hw->mac.type) {
+	case e1000_ich9lan:
+	case e1000_ich10lan:
+		if (adapter->netdev->mtu > ETH_DATA_LEN) {
+			pba = 14;
+			ew32(PBA, pba);
+			fc->high_water = 0x2800;
+			fc->low_water = fc->high_water - 8;
+			break;
+		}
+		/* fall-through */
 	default:
-		if ((adapter->flags & FLAG_HAS_ERT) &&
-		    (adapter->netdev->mtu > ETH_DATA_LEN))
-			hwm = min(((pba << 10) * 9 / 10),
-				  ((pba << 10) - (E1000_ERT_2048 << 3)));
-		else
-			hwm = min(((pba << 10) * 9 / 10),
-				  ((pba << 10) - adapter->max_frame_size));
+		hwm = min(((pba << 10) * 9 / 10),
+			  ((pba << 10) - adapter->max_frame_size));
 
 		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
 		fc->low_water = fc->high_water - 8;
@@ -3447,11 +3479,10 @@ void e1000e_reset(struct e1000_adapter *adapter)
 
 	/*
 	 * Disable Adaptive Interrupt Moderation if 2 full packets cannot
-	 * fit in receive buffer and early-receive not supported.
+	 * fit in receive buffer.
 	 */
 	if (adapter->itr_setting & 0x3) {
-		if (((adapter->max_frame_size * 2) > (pba << 10)) &&
-		    !(adapter->flags & FLAG_HAS_ERT)) {
+		if ((adapter->max_frame_size * 2) > (pba << 10)) {
 			if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
 				dev_info(&adapter->pdev->dev,
 					"Interrupt Throttle Rate turned off\n");
@@ -3593,8 +3624,8 @@ void e1000e_down(struct e1000_adapter *adapter)
 	spin_unlock(&adapter->stats64_lock);
 
 	e1000e_flush_descriptors(adapter);
-	e1000_clean_tx_ring(adapter);
-	e1000_clean_rx_ring(adapter);
+	e1000_clean_tx_ring(adapter->tx_ring);
+	e1000_clean_rx_ring(adapter->rx_ring);
 
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
@@ -3634,6 +3665,8 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
 	adapter->rx_ps_bsize0 = 128;
 	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+	adapter->tx_ring_count = E1000_DEFAULT_TXD;
+	adapter->rx_ring_count = E1000_DEFAULT_RXD;
 
 	spin_lock_init(&adapter->stats64_lock);
 
@@ -3721,8 +3754,9 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
 	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
 		adapter->int_mode = E1000E_INT_MODE_LEGACY;
 		e_info("MSI interrupt test failed, using legacy interrupt.\n");
-	} else
+	} else {
 		e_dbg("MSI interrupt test succeeded!\n");
+	}
 
 	free_irq(adapter->pdev->irq, netdev);
 	pci_disable_msi(adapter->pdev);
@@ -3792,12 +3826,12 @@ static int e1000_open(struct net_device *netdev)
 	netif_carrier_off(netdev);
 
 	/* allocate transmit descriptors */
-	err = e1000e_setup_tx_resources(adapter);
+	err = e1000e_setup_tx_resources(adapter->tx_ring);
 	if (err)
 		goto err_setup_tx;
 
 	/* allocate receive descriptors */
-	err = e1000e_setup_rx_resources(adapter);
+	err = e1000e_setup_rx_resources(adapter->rx_ring);
 	if (err)
 		goto err_setup_rx;
 
@@ -3817,9 +3851,8 @@ static int e1000_open(struct net_device *netdev)
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
 		e1000_update_mng_vlan(adapter);
 
-	/* DMA latency requirement to workaround early-receive/jumbo issue */
-	if ((adapter->flags & FLAG_HAS_ERT) ||
-	    (adapter->hw.mac.type == e1000_pch2lan))
+	/* DMA latency requirement to workaround jumbo issue */
+	if (adapter->hw.mac.type == e1000_pch2lan)
 		pm_qos_add_request(&adapter->netdev->pm_qos_req,
 				   PM_QOS_CPU_DMA_LATENCY,
 				   PM_QOS_DEFAULT_VALUE);
@@ -3873,9 +3906,9 @@ static int e1000_open(struct net_device *netdev)
 err_req_irq:
 	e1000e_release_hw_control(adapter);
 	e1000_power_down_phy(adapter);
-	e1000e_free_rx_resources(adapter);
+	e1000e_free_rx_resources(adapter->rx_ring);
 err_setup_rx:
-	e1000e_free_tx_resources(adapter);
+	e1000e_free_tx_resources(adapter->tx_ring);
 err_setup_tx:
 	e1000e_reset(adapter);
 	pm_runtime_put_sync(&pdev->dev);
@@ -3911,8 +3944,8 @@ static int e1000_close(struct net_device *netdev)
 	}
 	e1000_power_down_phy(adapter);
 
-	e1000e_free_tx_resources(adapter);
-	e1000e_free_rx_resources(adapter);
+	e1000e_free_tx_resources(adapter->tx_ring);
+	e1000e_free_rx_resources(adapter->rx_ring);
 
 	/*
 	 * kill manageability vlan ID if supported, but not if a vlan with
@@ -3930,8 +3963,7 @@ static int e1000_close(struct net_device *netdev)
 	    !test_bit(__E1000_TESTING, &adapter->state))
 		e1000e_release_hw_control(adapter);
 
-	if ((adapter->flags & FLAG_HAS_ERT) ||
-	    (adapter->hw.mac.type == e1000_pch2lan))
+	if (adapter->hw.mac.type == e1000_pch2lan)
 		pm_qos_remove_request(&adapter->netdev->pm_qos_req);
 
 	pm_runtime_put_sync(&pdev->dev);
@@ -4569,10 +4601,8 @@ link_up:
 #define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
 #define E1000_TX_FLAGS_VLAN_SHIFT	16
 
-static int e1000_tso(struct e1000_adapter *adapter,
-		     struct sk_buff *skb)
+static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
 {
-	struct e1000_ring *tx_ring = adapter->tx_ring;
 	struct e1000_context_desc *context_desc;
 	struct e1000_buffer *buffer_info;
 	unsigned int i;
@@ -4641,9 +4671,9 @@ static int e1000_tso(struct e1000_adapter *adapter,
 	return 1;
 }
 
-static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
+static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
 {
-	struct e1000_ring *tx_ring = adapter->tx_ring;
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct e1000_context_desc *context_desc;
 	struct e1000_buffer *buffer_info;
 	unsigned int i;
@@ -4704,12 +4734,11 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
 #define E1000_MAX_PER_TXD	8192
 #define E1000_MAX_TXD_PWR	12
 
-static int e1000_tx_map(struct e1000_adapter *adapter,
-			struct sk_buff *skb, unsigned int first,
-			unsigned int max_per_txd, unsigned int nr_frags,
-			unsigned int mss)
+static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
+			unsigned int first, unsigned int max_per_txd,
+			unsigned int nr_frags, unsigned int mss)
 {
-	struct e1000_ring *tx_ring = adapter->tx_ring;
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_buffer *buffer_info;
 	unsigned int len = skb_headlen(skb);
@@ -4795,16 +4824,15 @@ dma_error:
 			i += tx_ring->count;
 		i--;
 		buffer_info = &tx_ring->buffer_info[i];
-		e1000_put_txbuf(adapter, buffer_info);
+		e1000_put_txbuf(tx_ring, buffer_info);
 	}
 
 	return 0;
 }
 
-static void e1000_tx_queue(struct e1000_adapter *adapter,
-			   int tx_flags, int count)
+static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count)
 {
-	struct e1000_ring *tx_ring = adapter->tx_ring;
+	struct e1000_adapter *adapter = tx_ring->adapter;
 	struct e1000_tx_desc *tx_desc = NULL;
 	struct e1000_buffer *buffer_info;
 	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
@@ -4857,9 +4885,9 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
 	tx_ring->next_to_use = i;
 
 	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
-		e1000e_update_tdt_wa(adapter, i);
+		e1000e_update_tdt_wa(tx_ring, i);
 	else
-		writel(i, adapter->hw.hw_addr + tx_ring->tail);
+		writel(i, tx_ring->tail);
 
 	/*
 	 * we need this if more than one processor can write to our tail
@@ -4907,11 +4935,11 @@ static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
 	return 0;
 }
 
-static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
+static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_adapter *adapter = tx_ring->adapter;
 
-	netif_stop_queue(netdev);
+	netif_stop_queue(adapter->netdev);
 	/*
 	 * Herbert's original patch had:
 	 *  smp_mb__after_netif_stop_queue();
@@ -4923,25 +4951,23 @@ static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
 	 * We need to check again in a case another CPU has just
 	 * made room available.
 	 */
-	if (e1000_desc_unused(adapter->tx_ring) < size)
+	if (e1000_desc_unused(tx_ring) < size)
 		return -EBUSY;
 
 	/* A reprieve! */
-	netif_start_queue(netdev);
+	netif_start_queue(adapter->netdev);
 	++adapter->restart_queue;
 	return 0;
 }
 
-static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
+static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-
-	if (e1000_desc_unused(adapter->tx_ring) >= size)
+	if (e1000_desc_unused(tx_ring) >= size)
 		return 0;
-	return __e1000_maybe_stop_tx(netdev, size);
+	return __e1000_maybe_stop_tx(tx_ring, size);
 }
 
-#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
+#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1)
 static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 				    struct net_device *netdev)
 {
@@ -4995,7 +5021,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 		if (skb->data_len && (hdr_len == len)) {
 			unsigned int pull_size;
 
-			pull_size = min((unsigned int)4, skb->data_len);
+			pull_size = min_t(unsigned int, 4, skb->data_len);
 			if (!__pskb_pull_tail(skb, pull_size)) {
 				e_err("__pskb_pull_tail failed.\n");
 				dev_kfree_skb_any(skb);
@@ -5024,7 +5050,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 	 * need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time
 	 */
-	if (e1000_maybe_stop_tx(netdev, count + 2))
+	if (e1000_maybe_stop_tx(tx_ring, count + 2))
 		return NETDEV_TX_BUSY;
 
 	if (vlan_tx_tag_present(skb)) {
@@ -5034,7 +5060,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
 	first = tx_ring->next_to_use;
 
-	tso = e1000_tso(adapter, skb);
+	tso = e1000_tso(tx_ring, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
@@ -5042,7 +5068,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
 	if (tso)
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	else if (e1000_tx_csum(adapter, skb))
+	else if (e1000_tx_csum(tx_ring, skb))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
 	/*
@@ -5054,12 +5080,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
 	/* if count is 0 then mapping error has occurred */
-	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
+	count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss);
 	if (count) {
 		netdev_sent_queue(netdev, skb->len);
-		e1000_tx_queue(adapter, tx_flags, count);
+		e1000_tx_queue(tx_ring, tx_flags, count);
 		/* Make sure there is space in the ring for the next send. */
-		e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
+		e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2);
 
 	} else {
 		dev_kfree_skb_any(skb);
@@ -5165,10 +5191,22 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
 	/* Jumbo frame support */
-	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
-	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
-		e_err("Jumbo Frames not supported.\n");
-		return -EINVAL;
+	if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
+		if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+			e_err("Jumbo Frames not supported.\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * IP payload checksum (enabled with jumbos/packet-split when
+		 * Rx checksum is enabled) and generation of RSS hash is
+		 * mutually exclusive in the hardware.
+		 */
+		if ((netdev->features & NETIF_F_RXCSUM) &&
+		    (netdev->features & NETIF_F_RXHASH)) {
+			e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled.  Disable one of the receive offload features before enabling jumbos.\n");
+			return -EINVAL;
+		}
 	}
 
 	/* Supported frame sizes */
@@ -5322,7 +5360,7 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
 	/* Enable access to wakeup registers on and set page to BM_WUC_PAGE */
 	retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
 	if (retval)
-		goto out;
+		goto release;
 
 	/* copy MAC MTA to PHY MTA - only needed for pchlan */
 	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
@@ -5366,7 +5404,7 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
 	retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
 	if (retval)
 		e_err("Could not set PHY Host Wakeup bit\n");
-out:
+release:
 	hw->phy.ops.release(hw);
 
 	return retval;
@@ -5908,7 +5946,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
 	ret_val = e1000_read_pba_string_generic(hw, pba_str,
 						E1000_PBANUM_LENGTH);
 	if (ret_val)
-		strncpy((char *)pba_str, "Unknown", sizeof(pba_str) - 1);
+		strlcpy((char *)pba_str, "Unknown", sizeof(pba_str));
 	e_info("MAC: %d, PHY: %d, PBA No: %s\n",
 	       hw->mac.type, hw->phy.type, pba_str);
 }
@@ -5923,7 +5961,8 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
 		return;
 
 	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
-	if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
+	le16_to_cpus(&buf);
+	if (!ret_val && (!(buf & (1 << 0)))) {
 		/* Deep Smart Power Down (DSPD) */
 		dev_warn(&adapter->pdev->dev,
 			 "Warning: detected DSPD enabled in EEPROM\n");
@@ -5931,7 +5970,7 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
 }
 
 static int e1000_set_features(struct net_device *netdev,
-	netdev_features_t features)
+			      netdev_features_t features)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	netdev_features_t changed = features ^ netdev->features;
@@ -5940,9 +5979,22 @@ static int e1000_set_features(struct net_device *netdev,
 		adapter->flags |= FLAG_TSO_FORCE;
 
 	if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX |
-			 NETIF_F_RXCSUM)))
+			 NETIF_F_RXCSUM | NETIF_F_RXHASH)))
 		return 0;
 
+	/*
+	 * IP payload checksum (enabled with jumbos/packet-split when Rx
+	 * checksum is enabled) and generation of RSS hash is mutually
+	 * exclusive in the hardware.
+	 */
+	if (adapter->rx_ps_pages &&
+	    (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) {
+		e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames.  Disable jumbos or enable only one of the receive offload features.\n");
+		return -EINVAL;
+	}
+
+	netdev->features = features;
+
 	if (netif_running(netdev))
 		e1000e_reinit_locked(adapter);
 	else
@@ -6087,7 +6139,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	e1000e_set_ethtool_ops(netdev);
 	netdev->watchdog_timeo		= 5 * HZ;
 	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
-	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+	strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
 
 	netdev->mem_start = mmio_start;
 	netdev->mem_end = mmio_start + mmio_len;
@@ -6133,6 +6185,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 			    NETIF_F_HW_VLAN_TX |
 			    NETIF_F_TSO |
 			    NETIF_F_TSO6 |
+			    NETIF_F_RXHASH |
 			    NETIF_F_RXCSUM |
 			    NETIF_F_HW_CSUM);
 
@@ -6268,7 +6321,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	if (!(adapter->flags & FLAG_HAS_AMT))
 		e1000e_get_hw_control(adapter);
 
-	strncpy(netdev->name, "eth%d", sizeof(netdev->name) - 1);
+	strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
 	err = register_netdev(netdev);
 	if (err)
 		goto err_register;
@@ -6449,7 +6502,7 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
 
-	{ }	/* terminate list */
+	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
 
@@ -6468,7 +6521,9 @@ static struct pci_driver e1000_driver = {
 	.probe    = e1000_probe,
 	.remove   = __devexit_p(e1000_remove),
 #ifdef CONFIG_PM
-	.driver.pm = &e1000_pm_ops,
+	.driver   = {
+		.pm = &e1000_pm_ops,
+	},
 #endif
 	.shutdown = e1000_shutdown,
 	.err_handler = &e1000_err_handler
@@ -6485,7 +6540,7 @@ static int __init e1000_init_module(void)
 	int ret;
 	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
 		e1000e_driver_version);
-	pr_info("Copyright(c) 1999 - 2011 Intel Corporation.\n");
+	pr_info("Copyright(c) 1999 - 2012 Intel Corporation.\n");
 	ret = pci_register_driver(&e1000_driver);
 
 	return ret;
diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c
new file mode 100644
index 0000000..24b7930
--- /dev/null
+++ b/drivers/net/ethernet/intel/e1000e/nvm.c
@@ -0,0 +1,643 @@
+/*******************************************************************************
+
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2012 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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.,
+  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics@intel.com>
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "e1000.h"
+
+/**
+ *  e1000_raise_eec_clk - Raise EEPROM clock
+ *  @hw: pointer to the HW structure
+ *  @eecd: pointer to the EEPROM
+ *
+ *  Enable/Raise the EEPROM clock bit.
+ **/
+static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
+{
+	*eecd = *eecd | E1000_EECD_SK;
+	ew32(EECD, *eecd);
+	e1e_flush();
+	udelay(hw->nvm.delay_usec);
+}
+
+/**
+ *  e1000_lower_eec_clk - Lower EEPROM clock
+ *  @hw: pointer to the HW structure
+ *  @eecd: pointer to the EEPROM
+ *
+ *  Clear/Lower the EEPROM clock bit.
+ **/
+static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
+{
+	*eecd = *eecd & ~E1000_EECD_SK;
+	ew32(EECD, *eecd);
+	e1e_flush();
+	udelay(hw->nvm.delay_usec);
+}
+
+/**
+ *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
+ *  @hw: pointer to the HW structure
+ *  @data: data to send to the EEPROM
+ *  @count: number of bits to shift out
+ *
+ *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
+ *  "data" parameter will be shifted out to the EEPROM one bit at a time.
+ *  In order to do this, "data" must be broken down into bits.
+ **/
+static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
+{
+	struct e1000_nvm_info *nvm = &hw->nvm;
+	u32 eecd = er32(EECD);
+	u32 mask;
+
+	mask = 0x01 << (count - 1);
+	if (nvm->type == e1000_nvm_eeprom_spi)
+		eecd |= E1000_EECD_DO;
+
+	do {
+		eecd &= ~E1000_EECD_DI;
+
+		if (data & mask)
+			eecd |= E1000_EECD_DI;
+
+		ew32(EECD, eecd);
+		e1e_flush();
+
+		udelay(nvm->delay_usec);
+
+		e1000_raise_eec_clk(hw, &eecd);
+		e1000_lower_eec_clk(hw, &eecd);
+
+		mask >>= 1;
+	} while (mask);
+
+	eecd &= ~E1000_EECD_DI;
+	ew32(EECD, eecd);
+}
+
+/**
+ *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
+ *  @hw: pointer to the HW structure
+ *  @count: number of bits to shift in
+ *
+ *  In order to read a register from the EEPROM, we need to shift 'count' bits
+ *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
+ *  the EEPROM (setting the SK bit), and then reading the value of the data out
+ *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
+ *  always be clear.
+ **/
+static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
+{
+	u32 eecd;
+	u32 i;
+	u16 data;
+
+	eecd = er32(EECD);
+
+	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+	data = 0;
+
+	for (i = 0; i < count; i++) {
+		data <<= 1;
+		e1000_raise_eec_clk(hw, &eecd);
+
+		eecd = er32(EECD);
+
+		eecd &= ~E1000_EECD_DI;
+		if (eecd & E1000_EECD_DO)
+			data |= 1;
+
+		e1000_lower_eec_clk(hw, &eecd);
+	}
+
+	return data;
+}
+
+/**
+ *  e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion
+ *  @hw: pointer to the HW structure
+ *  @ee_reg: EEPROM flag for polling
+ *
+ *  Polls the EEPROM status bit for either read or write completion based
+ *  upon the value of 'ee_reg'.
+ **/
+s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
+{
+	u32 attempts = 100000;
+	u32 i, reg = 0;
+
+	for (i = 0; i < attempts; i++) {
+		if (ee_reg == E1000_NVM_POLL_READ)
+			reg = er32(EERD);
+		else
+			reg = er32(EEWR);
+
+		if (reg & E1000_NVM_RW_REG_DONE)
+			return 0;
+
+		udelay(5);
+	}
+
+	return -E1000_ERR_NVM;
+}
+
+/**
+ *  e1000e_acquire_nvm - Generic request for access to EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
+ *  Return successful if access grant bit set, else clear the request for
+ *  EEPROM access and return -E1000_ERR_NVM (-1).
+ **/
+s32 e1000e_acquire_nvm(struct e1000_hw *hw)
+{
+	u32 eecd = er32(EECD);
+	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
+
+	ew32(EECD, eecd | E1000_EECD_REQ);
+	eecd = er32(EECD);
+
+	while (timeout) {
+		if (eecd & E1000_EECD_GNT)
+			break;
+		udelay(5);
+		eecd = er32(EECD);
+		timeout--;
+	}
+
+	if (!timeout) {
+		eecd &= ~E1000_EECD_REQ;
+		ew32(EECD, eecd);
+		e_dbg("Could not acquire NVM grant\n");
+		return -E1000_ERR_NVM;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000_standby_nvm - Return EEPROM to standby state
+ *  @hw: pointer to the HW structure
+ *
+ *  Return the EEPROM to a standby state.
+ **/
+static void e1000_standby_nvm(struct e1000_hw *hw)
+{
+	struct e1000_nvm_info *nvm = &hw->nvm;
+	u32 eecd = er32(EECD);
+
+	if (nvm->type == e1000_nvm_eeprom_spi) {
+		/* Toggle CS to flush commands */
+		eecd |= E1000_EECD_CS;
+		ew32(EECD, eecd);
+		e1e_flush();
+		udelay(nvm->delay_usec);
+		eecd &= ~E1000_EECD_CS;
+		ew32(EECD, eecd);
+		e1e_flush();
+		udelay(nvm->delay_usec);
+	}
+}
+
+/**
+ *  e1000_stop_nvm - Terminate EEPROM command
+ *  @hw: pointer to the HW structure
+ *
+ *  Terminates the current command by inverting the EEPROM's chip select pin.
+ **/
+static void e1000_stop_nvm(struct e1000_hw *hw)
+{
+	u32 eecd;
+
+	eecd = er32(EECD);
+	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
+		/* Pull CS high */
+		eecd |= E1000_EECD_CS;
+		e1000_lower_eec_clk(hw, &eecd);
+	}
+}
+
+/**
+ *  e1000e_release_nvm - Release exclusive access to EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
+ **/
+void e1000e_release_nvm(struct e1000_hw *hw)
+{
+	u32 eecd;
+
+	e1000_stop_nvm(hw);
+
+	eecd = er32(EECD);
+	eecd &= ~E1000_EECD_REQ;
+	ew32(EECD, eecd);
+}
+
+/**
+ *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
+ *  @hw: pointer to the HW structure
+ *
+ *  Setups the EEPROM for reading and writing.
+ **/
+static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
+{
+	struct e1000_nvm_info *nvm = &hw->nvm;
+	u32 eecd = er32(EECD);
+	u8 spi_stat_reg;
+
+	if (nvm->type == e1000_nvm_eeprom_spi) {
+		u16 timeout = NVM_MAX_RETRY_SPI;
+
+		/* Clear SK and CS */
+		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+		ew32(EECD, eecd);
+		e1e_flush();
+		udelay(1);
+
+		/*
+		 * Read "Status Register" repeatedly until the LSB is cleared.
+		 * The EEPROM will signal that the command has been completed
+		 * by clearing bit 0 of the internal status register.  If it's
+		 * not cleared within 'timeout', then error out.
+		 */
+		while (timeout) {
+			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
+						 hw->nvm.opcode_bits);
+			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
+			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
+				break;
+
+			udelay(5);
+			e1000_standby_nvm(hw);
+			timeout--;
+		}
+
+		if (!timeout) {
+			e_dbg("SPI NVM Status error\n");
+			return -E1000_ERR_NVM;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_read_nvm_eerd - Reads EEPROM using EERD register
+ *  @hw: pointer to the HW structure
+ *  @offset: offset of word in the EEPROM to read
+ *  @words: number of words to read
+ *  @data: word read from the EEPROM
+ *
+ *  Reads a 16 bit word from the EEPROM using the EERD register.
+ **/
+s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+	struct e1000_nvm_info *nvm = &hw->nvm;
+	u32 i, eerd = 0;
+	s32 ret_val = 0;
+
+	/*
+	 * A check for invalid values:  offset too large, too many words,
+	 * too many words for the offset, and not enough words.
+	 */
+	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
+	    (words == 0)) {
+		e_dbg("nvm parameter(s) out of bounds\n");
+		return -E1000_ERR_NVM;
+	}
+
+	for (i = 0; i < words; i++) {
+		eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) +
+		    E1000_NVM_RW_REG_START;
+
+		ew32(EERD, eerd);
+		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
+		if (ret_val)
+			break;
+
+		data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
+	}
+
+	return ret_val;
+}
+
+/**
+ *  e1000e_write_nvm_spi - Write to EEPROM using SPI
+ *  @hw: pointer to the HW structure
+ *  @offset: offset within the EEPROM to be written to
+ *  @words: number of words to write
+ *  @data: 16 bit word(s) to be written to the EEPROM
+ *
+ *  Writes data to EEPROM at offset using SPI interface.
+ *
+ *  If e1000e_update_nvm_checksum is not called after this function , the
+ *  EEPROM will most likely contain an invalid checksum.
+ **/
+s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+	struct e1000_nvm_info *nvm = &hw->nvm;
+	s32 ret_val;
+	u16 widx = 0;
+
+	/*
+	 * A check for invalid values:  offset too large, too many words,
+	 * and not enough words.
+	 */
+	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
+	    (words == 0)) {
+		e_dbg("nvm parameter(s) out of bounds\n");
+		return -E1000_ERR_NVM;
+	}
+
+	ret_val = nvm->ops.acquire(hw);
+	if (ret_val)
+		return ret_val;
+
+	while (widx < words) {
+		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
+
+		ret_val = e1000_ready_nvm_eeprom(hw);
+		if (ret_val)
+			goto release;
+
+		e1000_standby_nvm(hw);
+
+		/* Send the WRITE ENABLE command (8 bit opcode) */
+		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
+					 nvm->opcode_bits);
+
+		e1000_standby_nvm(hw);
+
+		/*
+		 * Some SPI eeproms use the 8th address bit embedded in the
+		 * opcode
+		 */
+		if ((nvm->address_bits == 8) && (offset >= 128))
+			write_opcode |= NVM_A8_OPCODE_SPI;
+
+		/* Send the Write command (8-bit opcode + addr) */
+		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
+		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
+					 nvm->address_bits);
+
+		/* Loop to allow for up to whole page write of eeprom */
+		while (widx < words) {
+			u16 word_out = data[widx];
+			word_out = (word_out >> 8) | (word_out << 8);
+			e1000_shift_out_eec_bits(hw, word_out, 16);
+			widx++;
+
+			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
+				e1000_standby_nvm(hw);
+				break;
+			}
+		}
+	}
+
+	usleep_range(10000, 20000);
+release:
+	nvm->ops.release(hw);
+
+	return ret_val;
+}
+
+/**
+ *  e1000_read_pba_string_generic - Read device part number
+ *  @hw: pointer to the HW structure
+ *  @pba_num: pointer to device part number
+ *  @pba_num_size: size of part number buffer
+ *
+ *  Reads the product board assembly (PBA) number from the EEPROM and stores
+ *  the value in pba_num.
+ **/
+s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
+				  u32 pba_num_size)
+{
+	s32 ret_val;
+	u16 nvm_data;
+	u16 pba_ptr;
+	u16 offset;
+	u16 length;
+
+	if (pba_num == NULL) {
+		e_dbg("PBA string buffer was null\n");
+		return -E1000_ERR_INVALID_ARGUMENT;
+	}
+
+	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		return ret_val;
+	}
+
+	ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		return ret_val;
+	}
+
+	/*
+	 * if nvm_data is not ptr guard the PBA must be in legacy format which
+	 * means pba_ptr is actually our second data word for the PBA number
+	 * and we can decode it into an ascii string
+	 */
+	if (nvm_data != NVM_PBA_PTR_GUARD) {
+		e_dbg("NVM PBA number is not stored as string\n");
+
+		/* we will need 11 characters to store the PBA */
+		if (pba_num_size < 11) {
+			e_dbg("PBA string buffer too small\n");
+			return E1000_ERR_NO_SPACE;
+		}
+
+		/* extract hex string from data and pba_ptr */
+		pba_num[0] = (nvm_data >> 12) & 0xF;
+		pba_num[1] = (nvm_data >> 8) & 0xF;
+		pba_num[2] = (nvm_data >> 4) & 0xF;
+		pba_num[3] = nvm_data & 0xF;
+		pba_num[4] = (pba_ptr >> 12) & 0xF;
+		pba_num[5] = (pba_ptr >> 8) & 0xF;
+		pba_num[6] = '-';
+		pba_num[7] = 0;
+		pba_num[8] = (pba_ptr >> 4) & 0xF;
+		pba_num[9] = pba_ptr & 0xF;
+
+		/* put a null character on the end of our string */
+		pba_num[10] = '\0';
+
+		/* switch all the data but the '-' to hex char */
+		for (offset = 0; offset < 10; offset++) {
+			if (pba_num[offset] < 0xA)
+				pba_num[offset] += '0';
+			else if (pba_num[offset] < 0x10)
+				pba_num[offset] += 'A' - 0xA;
+		}
+
+		return 0;
+	}
+
+	ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length);
+	if (ret_val) {
+		e_dbg("NVM Read Error\n");
+		return ret_val;
+	}
+
+	if (length == 0xFFFF || length == 0) {
+		e_dbg("NVM PBA number section invalid length\n");
+		return -E1000_ERR_NVM_PBA_SECTION;
+	}
+	/* check if pba_num buffer is big enough */
+	if (pba_num_size < (((u32)length * 2) - 1)) {
+		e_dbg("PBA string buffer too small\n");
+		return -E1000_ERR_NO_SPACE;
+	}
+
+	/* trim pba length from start of string */
+	pba_ptr++;
+	length--;
+
+	for (offset = 0; offset < length; offset++) {
+		ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data);
+		if (ret_val) {
+			e_dbg("NVM Read Error\n");
+			return ret_val;
+		}
+		pba_num[offset * 2] = (u8)(nvm_data >> 8);
+		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
+	}
+	pba_num[offset * 2] = '\0';
+
+	return 0;
+}
+
+/**
+ *  e1000_read_mac_addr_generic - Read device MAC address
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the device MAC address from the EEPROM and stores the value.
+ *  Since devices with two ports use the same EEPROM, we increment the
+ *  last bit in the MAC address for the second port.
+ **/
+s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
+{
+	u32 rar_high;
+	u32 rar_low;
+	u16 i;
+
+	rar_high = er32(RAH(0));
+	rar_low = er32(RAL(0));
+
+	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8));
+
+	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
+		hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8));
+
+	for (i = 0; i < ETH_ALEN; i++)
+		hw->mac.addr[i] = hw->mac.perm_addr[i];
+
+	return 0;
+}
+
+/**
+ *  e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum
+ *  @hw: pointer to the HW structure
+ *
+ *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
+ *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
+ **/
+s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u16 checksum = 0;
+	u16 i, nvm_data;
+
+	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
+		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
+		if (ret_val) {
+			e_dbg("NVM Read Error\n");
+			return ret_val;
+		}
+		checksum += nvm_data;
+	}
+
+	if (checksum != (u16)NVM_SUM) {
+		e_dbg("NVM Checksum Invalid\n");
+		return -E1000_ERR_NVM;
+	}
+
+	return 0;
+}
+
+/**
+ *  e1000e_update_nvm_checksum_generic - Update EEPROM checksum
+ *  @hw: pointer to the HW structure
+ *
+ *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
+ *  up to the checksum.  Then calculates the EEPROM checksum and writes the
+ *  value to the EEPROM.
+ **/
+s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u16 checksum = 0;
+	u16 i, nvm_data;
+
+	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
+		ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
+		if (ret_val) {
+			e_dbg("NVM Read Error while updating checksum.\n");
+			return ret_val;
+		}
+		checksum += nvm_data;
+	}
+	checksum = (u16)NVM_SUM - checksum;
+	ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
+	if (ret_val)
+		e_dbg("NVM Write Error while updating checksum.\n");
+
+	return ret_val;
+}
+
+/**
+ *  e1000e_reload_nvm - Reloads EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
+ *  extended control register.
+ **/
+void e1000e_reload_nvm(struct e1000_hw *hw)
+{
+	u32 ctrl_ext;
+
+	udelay(10);
+	ctrl_ext = er32(CTRL_EXT);
+	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+	ew32(CTRL_EXT, ctrl_ext);
+	e1e_flush();
+}
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c
index 20e93b0..9c6a56d 100644
--- a/drivers/net/ethernet/intel/e1000e/param.c
+++ b/drivers/net/ethernet/intel/e1000e/param.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -113,11 +113,20 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
 #define MAX_ITR 100000
 #define MIN_ITR 100
 
-/* IntMode (Interrupt Mode)
+/*
+ * IntMode (Interrupt Mode)
+ *
+ * Valid Range: varies depending on kernel configuration & hardware support
+ *
+ * legacy=0, MSI=1, MSI-X=2
  *
- * Valid Range: 0 - 2
+ * When MSI/MSI-X support is enabled in kernel-
+ *   Default Value: 2 (MSI-X) when supported by hardware, 1 (MSI) otherwise
+ * When MSI/MSI-X support is not enabled in kernel-
+ *   Default Value: 0 (legacy)
  *
- * Default Value: 2 (MSI-X)
+ * When a mode is specified that is not allowed/supported, it will be
+ * demoted to the most advanced interrupt mode available.
  */
 E1000_PARAM(IntMode, "Interrupt Mode");
 #define MAX_INTMODE	2
@@ -388,12 +397,33 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 		static struct e1000_option opt = {
 			.type = range_option,
 			.name = "Interrupt Mode",
-			.err  = "defaulting to 2 (MSI-X)",
-			.def  = E1000E_INT_MODE_MSIX,
-			.arg  = { .r = { .min = MIN_INTMODE,
-					 .max = MAX_INTMODE } }
+#ifndef CONFIG_PCI_MSI
+			.err  = "defaulting to 0 (legacy)",
+			.def  = E1000E_INT_MODE_LEGACY,
+			.arg  = { .r = { .min = 0,
+					 .max = 0 } }
+#endif
 		};
 
+#ifdef CONFIG_PCI_MSI
+		if (adapter->flags & FLAG_HAS_MSIX) {
+			opt.err = kstrdup("defaulting to 2 (MSI-X)",
+					  GFP_KERNEL);
+			opt.def = E1000E_INT_MODE_MSIX;
+			opt.arg.r.max = E1000E_INT_MODE_MSIX;
+		} else {
+			opt.err = kstrdup("defaulting to 1 (MSI)", GFP_KERNEL);
+			opt.def = E1000E_INT_MODE_MSI;
+			opt.arg.r.max = E1000E_INT_MODE_MSI;
+		}
+
+		if (!opt.err) {
+			dev_err(&adapter->pdev->dev,
+				"Failed to allocate memory\n");
+			return;
+		}
+#endif
+
 		if (num_IntMode > bd) {
 			unsigned int int_mode = IntMode[bd];
 			e1000_validate_option(&int_mode, &opt, adapter);
@@ -401,6 +431,10 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 		} else {
 			adapter->int_mode = opt.def;
 		}
+
+#ifdef CONFIG_PCI_MSI
+		kfree(opt.err);
+#endif
 	}
 	{ /* Smart Power Down */
 		static const struct e1000_option opt = {
diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c
index 8666476..d4dbbe7 100644
--- a/drivers/net/ethernet/intel/e1000e/phy.c
+++ b/drivers/net/ethernet/intel/e1000e/phy.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2011 Intel Corporation.
+  Copyright(c) 1999 - 2012 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -132,30 +132,30 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw)
 	u16 phy_id;
 	u16 retry_count = 0;
 
-	if (!(phy->ops.read_reg))
-		goto out;
+	if (!phy->ops.read_reg)
+		return 0;
 
 	while (retry_count < 2) {
 		ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		phy->id = (u32)(phy_id << 16);
 		udelay(20);
 		ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
 		phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
 
 		if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
-			goto out;
+			return 0;
 
 		retry_count++;
 	}
-out:
-	return ret_val;
+
+	return 0;
 }
 
 /**
@@ -382,29 +382,25 @@ static s32 __e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data,
 	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire))
-			goto out;
+		if (!hw->phy.ops.acquire)
+			return 0;
 
 		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
-	if (offset > MAX_PHY_MULTI_PAGE_REG) {
+	if (offset > MAX_PHY_MULTI_PAGE_REG)
 		ret_val = e1000e_write_phy_reg_mdic(hw,
 						    IGP01E1000_PHY_PAGE_SELECT,
 						    (u16)offset);
-		if (ret_val)
-			goto release;
-	}
-
-	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
-	                                  data);
-
-release:
+	if (!ret_val)
+		ret_val = e1000e_read_phy_reg_mdic(hw,
+						   MAX_PHY_REG_ADDRESS & offset,
+						   data);
 	if (!locked)
 		hw->phy.ops.release(hw);
-out:
+
 	return ret_val;
 }
 
@@ -453,30 +449,25 @@ static s32 __e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data,
 	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire))
-			goto out;
+		if (!hw->phy.ops.acquire)
+			return 0;
 
 		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
-	if (offset > MAX_PHY_MULTI_PAGE_REG) {
+	if (offset > MAX_PHY_MULTI_PAGE_REG)
 		ret_val = e1000e_write_phy_reg_mdic(hw,
 						    IGP01E1000_PHY_PAGE_SELECT,
 						    (u16)offset);
-		if (ret_val)
-			goto release;
-	}
-
-	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
-					    data);
-
-release:
+	if (!ret_val)
+		ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS &
+							offset,
+						    data);
 	if (!locked)
 		hw->phy.ops.release(hw);
 
-out:
 	return ret_val;
 }
 
@@ -523,15 +514,16 @@ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
                                  bool locked)
 {
 	u32 kmrnctrlsta;
-	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire))
-			goto out;
+		s32 ret_val = 0;
+
+		if (!hw->phy.ops.acquire)
+			return 0;
 
 		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
@@ -547,8 +539,7 @@ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data,
 	if (!locked)
 		hw->phy.ops.release(hw);
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -596,15 +587,16 @@ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
                                   bool locked)
 {
 	u32 kmrnctrlsta;
-	s32 ret_val = 0;
 
 	if (!locked) {
-		if (!(hw->phy.ops.acquire))
-			goto out;
+		s32 ret_val = 0;
+
+		if (!hw->phy.ops.acquire)
+			return 0;
 
 		ret_val = hw->phy.ops.acquire(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
 	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
@@ -617,8 +609,7 @@ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data,
 	if (!locked)
 		hw->phy.ops.release(hw);
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -663,17 +654,14 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
 	/* Enable CRS on Tx. This must be set for half-duplex operation. */
 	ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
 
 	/* Enable downshift */
 	phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
 
-	ret_val = e1e_wphy(hw, I82577_CFG_REG, phy_data);
-
-out:
-	return ret_val;
+	return e1e_wphy(hw, I82577_CFG_REG, phy_data);
 }
 
 /**
@@ -1064,8 +1052,7 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
 		break;
 	default:
 		e_dbg("Flow control param set incorrectly\n");
-		ret_val = -E1000_ERR_CONFIG;
-		return ret_val;
+		return -E1000_ERR_CONFIG;
 	}
 
 	ret_val = e1e_wphy(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
@@ -1136,13 +1123,12 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
 	if (phy->autoneg_wait_to_complete) {
 		ret_val = e1000_wait_autoneg(hw);
 		if (ret_val) {
-			e_dbg("Error while waiting for "
-				 "autoneg to complete\n");
+			e_dbg("Error while waiting for autoneg to complete\n");
 			return ret_val;
 		}
 	}
 
-	hw->mac.get_link_status = 1;
+	hw->mac.get_link_status = true;
 
 	return ret_val;
 }
@@ -1266,8 +1252,6 @@ s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
 						     PHY_FORCE_LIMIT,
 						     100000,
 						     &link);
-		if (ret_val)
-			return ret_val;
 	}
 
 	return ret_val;
@@ -1401,25 +1385,25 @@ s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, PHY_CONTROL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	e1000e_phy_force_speed_duplex_setup(hw, &data);
 
 	ret_val = e1e_wphy(hw, PHY_CONTROL, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* Disable MDI-X support for 10/100 */
 	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	data &= ~IFE_PMC_AUTO_MDIX;
 	data &= ~IFE_PMC_FORCE_MDIX;
 
 	ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	e_dbg("IFE PMC: %X\n", data);
 
@@ -1433,7 +1417,7 @@ s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
 		                                     100000,
 		                                     &link);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		if (!link)
 			e_dbg("Link taking longer than expected.\n");
@@ -1444,11 +1428,10 @@ s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
 		                                     100000,
 		                                     &link);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -1833,22 +1816,20 @@ s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
 	        M88E1000_PSSR_CABLE_LENGTH_SHIFT;
-	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
-		ret_val = -E1000_ERR_PHY;
-		goto out;
-	}
+
+	if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1)
+		return -E1000_ERR_PHY;
 
 	phy->min_cable_length = e1000_m88_cable_length_table[index];
 	phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -1918,7 +1899,7 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -2073,24 +2054,23 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
 
 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (!link) {
 		e_dbg("Phy info is only valid if link is up\n");
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
+		return -E1000_ERR_CONFIG;
 	}
 
 	ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 	phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE)
 	                           ? false : true;
 
 	if (phy->polarity_correction) {
 		ret_val = e1000_check_polarity_ife(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 	} else {
 		/* Polarity is forced */
 		phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY)
@@ -2100,7 +2080,7 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? true : false;
 
@@ -2109,8 +2089,7 @@ s32 e1000_get_phy_info_ife(struct e1000_hw *hw)
 	phy->local_rx = e1000_1000t_rx_status_undefined;
 	phy->remote_rx = e1000_1000t_rx_status_undefined;
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -2369,7 +2348,6 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
  **/
 s32 e1000e_determine_phy_address(struct e1000_hw *hw)
 {
-	s32 ret_val = -E1000_ERR_PHY_TYPE;
 	u32 phy_addr = 0;
 	u32 i;
 	enum e1000_phy_type phy_type = e1000_phy_unknown;
@@ -2388,17 +2366,15 @@ s32 e1000e_determine_phy_address(struct e1000_hw *hw)
 			 * If phy_type is valid, break - we found our
 			 * PHY address
 			 */
-			if (phy_type  != e1000_phy_unknown) {
-				ret_val = 0;
-				goto out;
-			}
+			if (phy_type  != e1000_phy_unknown)
+				return 0;
+
 			usleep_range(1000, 2000);
 			i++;
 		} while (i < 10);
 	}
 
-out:
-	return ret_val;
+	return -E1000_ERR_PHY_TYPE;
 }
 
 /**
@@ -2439,7 +2415,7 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
 	if (page == BM_WUC_PAGE) {
 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
 							 false, false);
-		goto out;
+		goto release;
 	}
 
 	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
@@ -2464,13 +2440,13 @@ s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
 		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
 		                                    (page << page_shift));
 		if (ret_val)
-			goto out;
+			goto release;
 	}
 
 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 	                                    data);
 
-out:
+release:
 	hw->phy.ops.release(hw);
 	return ret_val;
 }
@@ -2498,7 +2474,7 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
 	if (page == BM_WUC_PAGE) {
 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
 							 true, false);
-		goto out;
+		goto release;
 	}
 
 	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
@@ -2523,12 +2499,12 @@ s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
 		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
 		                                    (page << page_shift));
 		if (ret_val)
-			goto out;
+			goto release;
 	}
 
 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 	                                   data);
-out:
+release:
 	hw->phy.ops.release(hw);
 	return ret_val;
 }
@@ -2556,7 +2532,7 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
 	if (page == BM_WUC_PAGE) {
 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
 							 true, false);
-		goto out;
+		goto release;
 	}
 
 	hw->phy.addr = 1;
@@ -2568,12 +2544,12 @@ s32 e1000e_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
 						    page);
 
 		if (ret_val)
-			goto out;
+			goto release;
 	}
 
 	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 					   data);
-out:
+release:
 	hw->phy.ops.release(hw);
 	return ret_val;
 }
@@ -2600,7 +2576,7 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
 	if (page == BM_WUC_PAGE) {
 		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
 							 false, false);
-		goto out;
+		goto release;
 	}
 
 	hw->phy.addr = 1;
@@ -2611,13 +2587,13 @@ s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
 						    page);
 
 		if (ret_val)
-			goto out;
+			goto release;
 	}
 
 	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 					    data);
 
-out:
+release:
 	hw->phy.ops.release(hw);
 	return ret_val;
 }
@@ -2642,14 +2618,14 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
 	ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
 	if (ret_val) {
 		e_dbg("Could not set Port Control page\n");
-		goto out;
+		return ret_val;
 	}
 
 	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
 	if (ret_val) {
 		e_dbg("Could not read PHY register %d.%d\n",
 		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
-		goto out;
+		return ret_val;
 	}
 
 	/*
@@ -2664,15 +2640,14 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
 	if (ret_val) {
 		e_dbg("Could not write PHY register %d.%d\n",
 		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
-		goto out;
+		return ret_val;
 	}
 
-	/* Select Host Wakeup Registers page */
-	ret_val = e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
-
-	/* caller now able to write registers on the Wakeup registers page */
-out:
-	return ret_val;
+	/*
+	 * Select Host Wakeup Registers page - caller now able to write
+	 * registers on the Wakeup registers page
+	 */
+	return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
 }
 
 /**
@@ -2694,7 +2669,7 @@ s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
 	ret_val = e1000_set_page_igp(hw, (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
 	if (ret_val) {
 		e_dbg("Could not set Port Control page\n");
-		goto out;
+		return ret_val;
 	}
 
 	/* Restore 769.17 to its original value */
@@ -2702,7 +2677,7 @@ s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
 	if (ret_val)
 		e_dbg("Could not restore PHY register %d.%d\n",
 		      BM_PORT_CTRL_PAGE, BM_WUC_ENABLE_REG);
-out:
+
 	return ret_val;
 }
 
@@ -2750,7 +2725,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 		ret_val = e1000_enable_phy_wakeup_reg_access_bm(hw, &phy_reg);
 		if (ret_val) {
 			e_dbg("Could not enable PHY wakeup reg access\n");
-			goto out;
+			return ret_val;
 		}
 	}
 
@@ -2760,7 +2735,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
 	if (ret_val) {
 		e_dbg("Could not write address opcode to page %d\n", page);
-		goto out;
+		return ret_val;
 	}
 
 	if (read) {
@@ -2775,13 +2750,12 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
 
 	if (ret_val) {
 		e_dbg("Could not access PHY reg %d.%d\n", page, reg);
-		goto out;
+		return ret_val;
 	}
 
 	if (!page_set)
 		ret_val = e1000_disable_phy_wakeup_reg_access_bm(hw, &phy_reg);
 
-out:
 	return ret_val;
 }
 
@@ -3137,7 +3111,7 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
 	ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
 	if (ret_val) {
 		e_dbg("Could not write the Address Offset port register\n");
-		goto out;
+		return ret_val;
 	}
 
 	/* Read or write the data value next */
@@ -3146,12 +3120,9 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
 	else
 		ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
 
-	if (ret_val) {
+	if (ret_val)
 		e_dbg("Could not access the Data port register\n");
-		goto out;
-	}
 
-out:
 	return ret_val;
 }
 
@@ -3172,17 +3143,17 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
 	u16 data;
 
 	if (hw->phy.type != e1000_phy_82578)
-		goto out;
+		return 0;
 
 	/* Do not apply workaround if in PHY loopback bit 14 set */
 	e1e_rphy(hw, PHY_CONTROL, &data);
 	if (data & PHY_CONTROL_LB)
-		goto out;
+		return 0;
 
 	/* check if link is up and at 1Gbps */
 	ret_val = e1e_rphy(hw, BM_CS_STATUS, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	data &= BM_CS_STATUS_LINK_UP |
 	        BM_CS_STATUS_RESOLVED |
@@ -3191,7 +3162,7 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
 	if (data != (BM_CS_STATUS_LINK_UP |
 	             BM_CS_STATUS_RESOLVED |
 	             BM_CS_STATUS_SPEED_1000))
-		goto out;
+		return 0;
 
 	mdelay(200);
 
@@ -3199,12 +3170,9 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
 	ret_val = e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC |
 			   HV_MUX_DATA_CTRL_FORCE_SPEED);
 	if (ret_val)
-		goto out;
-
-	ret_val = e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC);
+		return ret_val;
 
-out:
-	return ret_val;
+	return e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC);
 }
 
 /**
@@ -3246,13 +3214,13 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
 
 	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	udelay(1);
 
@@ -3264,7 +3232,7 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
 		                                     100000,
 		                                     &link);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		if (!link)
 			e_dbg("Link taking longer than expected.\n");
@@ -3274,11 +3242,8 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
 		                                     PHY_FORCE_LIMIT,
 		                                     100000,
 		                                     &link);
-		if (ret_val)
-			goto out;
 	}
 
-out:
 	return ret_val;
 }
 
@@ -3300,23 +3265,22 @@ s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
 
 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (!link) {
 		e_dbg("Phy info is only valid if link is up\n");
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
+		return -E1000_ERR_CONFIG;
 	}
 
 	phy->polarity_correction = true;
 
 	ret_val = e1000_check_polarity_82577(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? true : false;
 
@@ -3324,11 +3288,11 @@ s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
 	    I82577_PHY_STATUS2_SPEED_1000MBPS) {
 		ret_val = hw->phy.ops.get_cable_length(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
 		                ? e1000_1000t_rx_status_ok
@@ -3343,8 +3307,7 @@ s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
 		phy->remote_rx = e1000_1000t_rx_status_undefined;
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -3362,7 +3325,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, I82577_PHY_DIAG_STATUS, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
 	         I82577_DSTATUS_CABLE_LENGTH_SHIFT;
@@ -3372,6 +3335,5 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
 
 	phy->cable_length = length;
 
-out:
-	return ret_val;
+	return 0;
 }
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 94be6c3..fda8247 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -173,7 +173,9 @@ static int igb_check_vf_assignment(struct igb_adapter *adapter);
 #endif
 
 #ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int igb_suspend(struct device *);
+#endif
 static int igb_resume(struct device *);
 #ifdef CONFIG_PM_RUNTIME
 static int igb_runtime_suspend(struct device *dev);
@@ -6710,6 +6712,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake,
 }
 
 #ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int igb_suspend(struct device *dev)
 {
 	int retval;
@@ -6729,6 +6732,7 @@ static int igb_suspend(struct device *dev)
 
 	return 0;
 }
+#endif /* CONFIG_PM_SLEEP */
 
 static int igb_resume(struct device *dev)
 {
diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c
index db7dce2..8ce6706 100644
--- a/drivers/net/ethernet/intel/igbvf/ethtool.c
+++ b/drivers/net/ethernet/intel/igbvf/ethtool.c
@@ -343,10 +343,10 @@ static int igbvf_get_coalesce(struct net_device *netdev,
 {
 	struct igbvf_adapter *adapter = netdev_priv(netdev);
 
-	if (adapter->itr_setting <= 3)
-		ec->rx_coalesce_usecs = adapter->itr_setting;
+	if (adapter->requested_itr <= 3)
+		ec->rx_coalesce_usecs = adapter->requested_itr;
 	else
-		ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
+		ec->rx_coalesce_usecs = adapter->current_itr >> 2;
 
 	return 0;
 }
@@ -365,15 +365,16 @@ static int igbvf_set_coalesce(struct net_device *netdev,
 
 	/* convert to rate of irq's per second */
 	if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
-		adapter->itr = IGBVF_START_ITR;
-		adapter->itr_setting = ec->rx_coalesce_usecs;
+		adapter->current_itr = IGBVF_START_ITR;
+		adapter->requested_itr = ec->rx_coalesce_usecs;
 	} else {
-		adapter->itr = ec->rx_coalesce_usecs << 2;
-		adapter->itr_setting = adapter->itr;
+		adapter->current_itr = ec->rx_coalesce_usecs << 2;
+		adapter->requested_itr = 1000000000 /
+					(adapter->current_itr * 256);
 	}
 
-	writel(adapter->itr,
-	       hw->hw_addr + adapter->rx_ring[0].itr_register);
+	writel(adapter->current_itr,
+	       hw->hw_addr + adapter->rx_ring->itr_register);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/intel/igbvf/igbvf.h b/drivers/net/ethernet/intel/igbvf/igbvf.h
index 2c6d87e..a895e2f 100644
--- a/drivers/net/ethernet/intel/igbvf/igbvf.h
+++ b/drivers/net/ethernet/intel/igbvf/igbvf.h
@@ -43,7 +43,18 @@ struct igbvf_info;
 struct igbvf_adapter;
 
 /* Interrupt defines */
-#define IGBVF_START_ITR                 648 /* ~6000 ints/sec */
+#define IGBVF_START_ITR                    488 /* ~8000 ints/sec */
+#define IGBVF_4K_ITR                       980
+#define IGBVF_20K_ITR                      196
+#define IGBVF_70K_ITR                       56
+
+enum latency_range {
+	lowest_latency = 0,
+	low_latency = 1,
+	bulk_latency = 2,
+	latency_invalid = 255
+};
+
 
 /* Interrupt modes, as used by the IntMode parameter */
 #define IGBVF_INT_MODE_LEGACY           0
@@ -155,6 +166,7 @@ struct igbvf_ring {
 	char name[IFNAMSIZ + 5];
 	u32 eims_value;
 	u32 itr_val;
+	enum latency_range itr_range;
 	u16 itr_register;
 	int set_itr;
 
@@ -187,10 +199,8 @@ struct igbvf_adapter {
 	unsigned long state;
 
 	/* Interrupt Throttle Rate */
-	u32 itr;
-	u32 itr_setting;
-	u16 tx_itr;
-	u16 rx_itr;
+	u32 requested_itr; /* ints/sec or adaptive */
+	u32 current_itr; /* Actual ITR register value, not ints/sec */
 
 	/*
 	 * Tx
@@ -299,13 +309,6 @@ enum igbvf_state_t {
 	__IGBVF_DOWN
 };
 
-enum latency_range {
-	lowest_latency = 0,
-	low_latency = 1,
-	bulk_latency = 2,
-	latency_invalid = 255
-};
-
 extern char igbvf_driver_name[];
 extern const char igbvf_driver_version[];
 
diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c
index 4e9141c..217c143 100644
--- a/drivers/net/ethernet/intel/igbvf/netdev.c
+++ b/drivers/net/ethernet/intel/igbvf/netdev.c
@@ -632,14 +632,13 @@ void igbvf_free_rx_resources(struct igbvf_ring *rx_ring)
  *      traffic pattern.  Constants in this function were computed
  *      based on theoretical maximum wire speed and thresholds were set based
  *      on testing data as well as attempting to minimize response time
- *      while increasing bulk throughput.  This functionality is controlled
- *      by the InterruptThrottleRate module parameter.
+ *      while increasing bulk throughput.
  **/
-static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter,
-                                     u16 itr_setting, int packets,
-                                     int bytes)
+static enum latency_range igbvf_update_itr(struct igbvf_adapter *adapter,
+					   enum latency_range itr_setting,
+					   int packets, int bytes)
 {
-	unsigned int retval = itr_setting;
+	enum latency_range retval = itr_setting;
 
 	if (packets == 0)
 		goto update_itr_done;
@@ -675,65 +674,87 @@ static unsigned int igbvf_update_itr(struct igbvf_adapter *adapter,
 			retval = low_latency;
 		}
 		break;
+	default:
+		break;
 	}
 
 update_itr_done:
 	return retval;
 }
 
-static void igbvf_set_itr(struct igbvf_adapter *adapter)
+static int igbvf_range_to_itr(enum latency_range current_range)
 {
-	struct e1000_hw *hw = &adapter->hw;
-	u16 current_itr;
-	u32 new_itr = adapter->itr;
-
-	adapter->tx_itr = igbvf_update_itr(adapter, adapter->tx_itr,
-	                                   adapter->total_tx_packets,
-	                                   adapter->total_tx_bytes);
-	/* conservative mode (itr 3) eliminates the lowest_latency setting */
-	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
-		adapter->tx_itr = low_latency;
-
-	adapter->rx_itr = igbvf_update_itr(adapter, adapter->rx_itr,
-	                                   adapter->total_rx_packets,
-	                                   adapter->total_rx_bytes);
-	/* conservative mode (itr 3) eliminates the lowest_latency setting */
-	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
-		adapter->rx_itr = low_latency;
-
-	current_itr = max(adapter->rx_itr, adapter->tx_itr);
+	int new_itr;
 
-	switch (current_itr) {
+	switch (current_range) {
 	/* counts and packets in update_itr are dependent on these numbers */
 	case lowest_latency:
-		new_itr = 70000;
+		new_itr = IGBVF_70K_ITR;
 		break;
 	case low_latency:
-		new_itr = 20000; /* aka hwitr = ~200 */
+		new_itr = IGBVF_20K_ITR;
 		break;
 	case bulk_latency:
-		new_itr = 4000;
+		new_itr = IGBVF_4K_ITR;
 		break;
 	default:
+		new_itr = IGBVF_START_ITR;
 		break;
 	}
+	return new_itr;
+}
+
+static void igbvf_set_itr(struct igbvf_adapter *adapter)
+{
+	u32 new_itr;
+
+	adapter->tx_ring->itr_range =
+			igbvf_update_itr(adapter,
+					 adapter->tx_ring->itr_val,
+					 adapter->total_tx_packets,
+					 adapter->total_tx_bytes);
+
+	/* conservative mode (itr 3) eliminates the lowest_latency setting */
+	if (adapter->requested_itr == 3 &&
+	    adapter->tx_ring->itr_range == lowest_latency)
+		adapter->tx_ring->itr_range = low_latency;
+
+	new_itr = igbvf_range_to_itr(adapter->tx_ring->itr_range);
+
 
-	if (new_itr != adapter->itr) {
+	if (new_itr != adapter->tx_ring->itr_val) {
+		u32 current_itr = adapter->tx_ring->itr_val;
 		/*
 		 * this attempts to bias the interrupt rate towards Bulk
 		 * by adding intermediate steps when interrupt rate is
 		 * increasing
 		 */
-		new_itr = new_itr > adapter->itr ?
-		             min(adapter->itr + (new_itr >> 2), new_itr) :
-		             new_itr;
-		adapter->itr = new_itr;
-		adapter->rx_ring->itr_val = 1952;
-
-		if (adapter->msix_entries)
-			adapter->rx_ring->set_itr = 1;
-		else
-			ew32(ITR, 1952);
+		new_itr = new_itr > current_itr ?
+			     min(current_itr + (new_itr >> 2), new_itr) :
+			     new_itr;
+		adapter->tx_ring->itr_val = new_itr;
+
+		adapter->tx_ring->set_itr = 1;
+	}
+
+	adapter->rx_ring->itr_range =
+			igbvf_update_itr(adapter, adapter->rx_ring->itr_val,
+					 adapter->total_rx_packets,
+					 adapter->total_rx_bytes);
+	if (adapter->requested_itr == 3 &&
+	    adapter->rx_ring->itr_range == lowest_latency)
+		adapter->rx_ring->itr_range = low_latency;
+
+	new_itr = igbvf_range_to_itr(adapter->rx_ring->itr_range);
+
+	if (new_itr != adapter->rx_ring->itr_val) {
+		u32 current_itr = adapter->rx_ring->itr_val;
+		new_itr = new_itr > current_itr ?
+			     min(current_itr + (new_itr >> 2), new_itr) :
+			     new_itr;
+		adapter->rx_ring->itr_val = new_itr;
+
+		adapter->rx_ring->set_itr = 1;
 	}
 }
 
@@ -835,6 +856,11 @@ static irqreturn_t igbvf_intr_msix_tx(int irq, void *data)
 	struct e1000_hw *hw = &adapter->hw;
 	struct igbvf_ring *tx_ring = adapter->tx_ring;
 
+	if (tx_ring->set_itr) {
+		writel(tx_ring->itr_val,
+		       adapter->hw.hw_addr + tx_ring->itr_register);
+		adapter->tx_ring->set_itr = 0;
+	}
 
 	adapter->total_tx_bytes = 0;
 	adapter->total_tx_packets = 0;
@@ -937,19 +963,10 @@ static void igbvf_configure_msix(struct igbvf_adapter *adapter)
 
 	igbvf_assign_vector(adapter, IGBVF_NO_QUEUE, 0, vector++);
 	adapter->eims_enable_mask |= tx_ring->eims_value;
-	if (tx_ring->itr_val)
-		writel(tx_ring->itr_val,
-		       hw->hw_addr + tx_ring->itr_register);
-	else
-		writel(1952, hw->hw_addr + tx_ring->itr_register);
-
+	writel(tx_ring->itr_val, hw->hw_addr + tx_ring->itr_register);
 	igbvf_assign_vector(adapter, 0, IGBVF_NO_QUEUE, vector++);
 	adapter->eims_enable_mask |= rx_ring->eims_value;
-	if (rx_ring->itr_val)
-		writel(rx_ring->itr_val,
-		       hw->hw_addr + rx_ring->itr_register);
-	else
-		writel(1952, hw->hw_addr + rx_ring->itr_register);
+	writel(rx_ring->itr_val, hw->hw_addr + rx_ring->itr_register);
 
 	/* set vector for other causes, i.e. link changes */
 
@@ -1027,7 +1044,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
 		goto out;
 
 	adapter->tx_ring->itr_register = E1000_EITR(vector);
-	adapter->tx_ring->itr_val = 1952;
+	adapter->tx_ring->itr_val = adapter->current_itr;
 	vector++;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
@@ -1037,7 +1054,7 @@ static int igbvf_request_msix(struct igbvf_adapter *adapter)
 		goto out;
 
 	adapter->rx_ring->itr_register = E1000_EITR(vector);
-	adapter->rx_ring->itr_val = 1952;
+	adapter->rx_ring->itr_val = adapter->current_itr;
 	vector++;
 
 	err = request_irq(adapter->msix_entries[vector].vector,
@@ -1151,7 +1168,7 @@ static int igbvf_poll(struct napi_struct *napi, int budget)
 	if (work_done < budget) {
 		napi_complete(napi);
 
-		if (adapter->itr_setting & 3)
+		if (adapter->requested_itr & 3)
 			igbvf_set_itr(adapter);
 
 		if (!test_bit(__IGBVF_DOWN, &adapter->state))
@@ -1521,8 +1538,8 @@ static int __devinit igbvf_sw_init(struct igbvf_adapter *adapter)
 	adapter->tx_abs_int_delay = 32;
 	adapter->rx_int_delay = 0;
 	adapter->rx_abs_int_delay = 8;
-	adapter->itr_setting = 3;
-	adapter->itr = 20000;
+	adapter->requested_itr = 3;
+	adapter->current_itr = IGBVF_START_ITR;
 
 	/* Set various function pointers */
 	adapter->ei->init_ops(&adapter->hw);
@@ -1695,6 +1712,7 @@ static int igbvf_set_mac(struct net_device *netdev, void *p)
 		return -EADDRNOTAVAIL;
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+	netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	return 0;
 }
@@ -2695,18 +2713,19 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
 		dev_info(&pdev->dev,
 			 "PF still in reset state, assigning new address."
 			 " Is the PF interface up?\n");
-		dev_hw_addr_random(adapter->netdev, hw->mac.addr);
+		eth_hw_addr_random(netdev);
+		memcpy(adapter->hw.mac.addr, netdev->dev_addr,
+			netdev->addr_len);
 	} else {
 		err = hw->mac.ops.read_mac_addr(hw);
 		if (err) {
 			dev_err(&pdev->dev, "Error reading MAC address\n");
 			goto err_hw_init;
 		}
+		memcpy(netdev->dev_addr, adapter->hw.mac.addr,
+			netdev->addr_len);
 	}
 
-	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
-
 	if (!is_valid_ether_addr(netdev->perm_addr)) {
 		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
 		        netdev->dev_addr);
@@ -2714,6 +2733,8 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
 		goto err_hw_init;
 	}
 
+	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+
 	setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
 	            (unsigned long) adapter);
 
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_ee.c b/drivers/net/ethernet/intel/ixgb/ixgb_ee.c
index 2ed925f..eca216b 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_ee.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_ee.c
@@ -533,10 +533,8 @@ __le16
 ixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index)
 {
 
-	if ((index < IXGB_EEPROM_SIZE) &&
-		(ixgb_check_and_get_eeprom_data(hw) == true)) {
-	   return hw->eeprom[index];
-	}
+	if (index < IXGB_EEPROM_SIZE && ixgb_check_and_get_eeprom_data(hw))
+		return hw->eeprom[index];
 
 	return 0;
 }
@@ -558,7 +556,7 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw,
 
 	ENTER();
 
-	if (ixgb_check_and_get_eeprom_data(hw) == true) {
+	if (ixgb_check_and_get_eeprom_data(hw)) {
 		for (i = 0; i < ETH_ALEN; i++) {
 			mac_addr[i] = ee_map->mac_addr[i];
 		}
@@ -578,7 +576,7 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw,
 u32
 ixgb_get_ee_pba_number(struct ixgb_hw *hw)
 {
-	if (ixgb_check_and_get_eeprom_data(hw) == true)
+	if (ixgb_check_and_get_eeprom_data(hw))
 		return le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
 			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16);
 
@@ -599,7 +597,7 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == true)
+	if (ixgb_check_and_get_eeprom_data(hw))
 		return le16_to_cpu(ee_map->device_id);
 
 	return 0;
diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
index 9bd5faf..0024788 100644
--- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c
+++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c
@@ -1136,10 +1136,8 @@ ixgb_set_multi(struct net_device *netdev)
 		u8 *mta = kmalloc(IXGB_MAX_NUM_MULTICAST_ADDRESSES *
 			      ETH_ALEN, GFP_ATOMIC);
 		u8 *addr;
-		if (!mta) {
-			pr_err("allocation of multicast memory failed\n");
+		if (!mta)
 			goto alloc_failed;
-		}
 
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index e6aeb64..2807a25 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -190,6 +190,7 @@ struct ixgbe_rx_queue_stats {
 	u64 non_eop_descs;
 	u64 alloc_rx_page_failed;
 	u64 alloc_rx_buff_failed;
+	u64 csum_err;
 };
 
 enum ixbge_ring_state_t {
@@ -198,6 +199,7 @@ enum ixbge_ring_state_t {
 	__IXGBE_HANG_CHECK_ARMED,
 	__IXGBE_RX_PS_ENABLED,
 	__IXGBE_RX_RSC_ENABLED,
+	__IXGBE_RX_CSUM_UDP_ZERO_ERR,
 };
 
 #define ring_is_ps_enabled(ring) \
@@ -329,6 +331,13 @@ struct ixgbe_q_vector {
 #define IXGBE_10K_ITR		400
 #define IXGBE_8K_ITR		500
 
+/* ixgbe_test_staterr - tests bits in Rx descriptor status and error fields */
+static inline __le32 ixgbe_test_staterr(union ixgbe_adv_rx_desc *rx_desc,
+					const u32 stat_err_bits)
+{
+	return rx_desc->wb.upper.status_error & cpu_to_le32(stat_err_bits);
+}
+
 static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
 {
 	u16 ntc = ring->next_to_clean;
@@ -337,11 +346,11 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
 	return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
 }
 
-#define IXGBE_RX_DESC_ADV(R, i)	    \
+#define IXGBE_RX_DESC(R, i)	    \
 	(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
-#define IXGBE_TX_DESC_ADV(R, i)	    \
+#define IXGBE_TX_DESC(R, i)	    \
 	(&(((union ixgbe_adv_tx_desc *)((R)->desc))[i]))
-#define IXGBE_TX_CTXTDESC_ADV(R, i)	    \
+#define IXGBE_TX_CTXTDESC(R, i)	    \
 	(&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
 
 #define IXGBE_MAX_JUMBO_FRAME_SIZE        16128
@@ -372,7 +381,6 @@ struct ixgbe_adapter {
 	 * thus the additional *_CAPABLE flags.
 	 */
 	u32 flags;
-#define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
 #define IXGBE_FLAG_MSI_CAPABLE                  (u32)(1 << 1)
 #define IXGBE_FLAG_MSI_ENABLED                  (u32)(1 << 2)
 #define IXGBE_FLAG_MSIX_CAPABLE                 (u32)(1 << 3)
@@ -535,12 +543,16 @@ enum ixbge_state_t {
 	__IXGBE_IN_SFP_INIT,
 };
 
-struct ixgbe_rsc_cb {
+struct ixgbe_cb {
+	union {				/* Union defining head/tail partner */
+		struct sk_buff *head;
+		struct sk_buff *tail;
+	};
 	dma_addr_t dma;
-	u16 skb_cnt;
+	u16 append_cnt;
 	bool delay_unmap;
 };
-#define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb)
+#define IXGBE_CB(skb) ((struct ixgbe_cb *)(skb)->cb)
 
 enum ixgbe_boards {
 	board_82598,
@@ -614,8 +626,7 @@ extern int ixgbe_fso(struct ixgbe_ring *tx_ring, struct sk_buff *skb,
 extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter);
 extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 			  union ixgbe_adv_rx_desc *rx_desc,
-			  struct sk_buff *skb,
-			  u32 staterr);
+			  struct sk_buff *skb);
 extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
                               struct scatterlist *sgl, unsigned int sgc);
 extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index b406c36..752dbe6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -617,7 +617,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
 				*link_up = false;
 		}
 
-		if (*link_up == false)
+		if (!*link_up)
 			goto out;
 	}
 
@@ -645,7 +645,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
 	else
 		*speed = IXGBE_LINK_SPEED_1GB_FULL;
 
-	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && (*link_up == true) &&
+	if ((hw->device_id == IXGBE_DEV_ID_82598AT2) && *link_up &&
 	    (ixgbe_validate_link_ready(hw) != 0))
 		*link_up = false;
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index a629754..8e2e473 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -1739,7 +1739,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring,
 	/* initialize next to clean and descriptor values */
 	rx_ntc = rx_ring->next_to_clean;
 	tx_ntc = tx_ring->next_to_clean;
-	rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc);
+	rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc);
 	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 
 	while (staterr & IXGBE_RXD_STAT_DD) {
@@ -1770,7 +1770,7 @@ static u16 ixgbe_clean_test_rings(struct ixgbe_ring *rx_ring,
 			tx_ntc = 0;
 
 		/* fetch next descriptor */
-		rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc);
+		rx_desc = IXGBE_RX_DESC(rx_ring, rx_ntc);
 		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 	}
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index 4bc7942..da7da75 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -357,22 +357,20 @@ int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
  */
 int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 		   union ixgbe_adv_rx_desc *rx_desc,
-		   struct sk_buff *skb,
-		   u32 staterr)
+		   struct sk_buff *skb)
 {
-	u16 xid;
-	u32 fctl;
-	u32 fceofe, fcerr, fcstat;
 	int rc = -EINVAL;
 	struct ixgbe_fcoe *fcoe;
 	struct ixgbe_fcoe_ddp *ddp;
 	struct fc_frame_header *fh;
 	struct fcoe_crc_eof *crc;
+	__le32 fcerr = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCERR);
+	__le32 ddp_err;
+	u32 fctl;
+	u16 xid;
 
-	fcerr = (staterr & IXGBE_RXDADV_ERR_FCERR);
-	fceofe = (staterr & IXGBE_RXDADV_ERR_FCEOFE);
-	if (fcerr == IXGBE_FCERR_BADCRC)
-		skb_checksum_none_assert(skb);
+	if (fcerr == cpu_to_le32(IXGBE_FCERR_BADCRC))
+		skb->ip_summed = CHECKSUM_NONE;
 	else
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
@@ -382,6 +380,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 	else
 		fh = (struct fc_frame_header *)(skb->data +
 			sizeof(struct fcoe_hdr));
+
 	fctl = ntoh24(fh->fh_f_ctl);
 	if (fctl & FC_FC_EX_CTX)
 		xid =  be16_to_cpu(fh->fh_ox_id);
@@ -396,27 +395,39 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 	if (!ddp->udl)
 		goto ddp_out;
 
-	if (fcerr | fceofe)
+	ddp_err = ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_FCEOFE |
+					      IXGBE_RXDADV_ERR_FCERR);
+	if (ddp_err)
 		goto ddp_out;
 
-	fcstat = (staterr & IXGBE_RXDADV_STAT_FCSTAT);
-	if (fcstat) {
+	switch (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_FCSTAT)) {
+	/* return 0 to bypass going to ULD for DDPed data */
+	case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_DDP):
 		/* update length of DDPed data */
 		ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
-		/* unmap the sg list when FCP_RSP is received */
-		if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) {
-			pci_unmap_sg(adapter->pdev, ddp->sgl,
-				     ddp->sgc, DMA_FROM_DEVICE);
-			ddp->err = (fcerr | fceofe);
-			ddp->sgl = NULL;
-			ddp->sgc = 0;
-		}
-		/* return 0 to bypass going to ULD for DDPed data */
-		if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP)
-			rc = 0;
-		else if (ddp->len)
+		rc = 0;
+		break;
+	/* unmap the sg list when FCPRSP is received */
+	case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_FCPRSP):
+		pci_unmap_sg(adapter->pdev, ddp->sgl,
+			     ddp->sgc, DMA_FROM_DEVICE);
+		ddp->err = ddp_err;
+		ddp->sgl = NULL;
+		ddp->sgc = 0;
+		/* fall through */
+	/* if DDP length is present pass it through to ULD */
+	case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NODDP):
+		/* update length of DDPed data */
+		ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+		if (ddp->len)
 			rc = ddp->len;
+		break;
+	/* no match will return as an error */
+	case __constant_cpu_to_le32(IXGBE_RXDADV_STAT_FCSTAT_NOMTCH):
+	default:
+		break;
 	}
+
 	/* In target mode, check the last data frame of the sequence.
 	 * For DDP in target mode, data is already DDPed but the header
 	 * indication of the last data frame ould allow is to tell if we
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3dc6cef..4e55860 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -131,6 +131,11 @@ MODULE_PARM_DESC(max_vfs,
 		 "Maximum number of virtual functions to allocate per physical function");
 #endif /* CONFIG_PCI_IOV */
 
+static unsigned int allow_unsupported_sfp;
+module_param(allow_unsupported_sfp, uint, 0);
+MODULE_PARM_DESC(allow_unsupported_sfp,
+		 "Allow unsupported and untested SFP+ modules on 82599-based adapters");
+
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
 MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
 MODULE_LICENSE("GPL");
@@ -361,7 +366,7 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
 			"leng  ntw timestamp        bi->skb\n");
 
 		for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
-			tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
+			tx_desc = IXGBE_TX_DESC(tx_ring, i);
 			tx_buffer_info = &tx_ring->tx_buffer_info[i];
 			u0 = (struct my_u0 *)tx_desc;
 			pr_info("T [0x%03X]    %016llX %016llX %016llX"
@@ -442,7 +447,7 @@ rx_ring_summary:
 
 		for (i = 0; i < rx_ring->count; i++) {
 			rx_buffer_info = &rx_ring->rx_buffer_info[i];
-			rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
+			rx_desc = IXGBE_RX_DESC(rx_ring, i);
 			u0 = (struct my_u0 *)rx_desc;
 			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 			if (staterr & IXGBE_RXD_STAT_DD) {
@@ -749,7 +754,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	u16 i = tx_ring->next_to_clean;
 
 	tx_buffer = &tx_ring->tx_buffer_info[i];
-	tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
+	tx_desc = IXGBE_TX_DESC(tx_ring, i);
 
 	for (; budget; budget--) {
 		union ixgbe_adv_tx_desc *eop_desc = tx_buffer->next_to_watch;
@@ -790,7 +795,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 				i = 0;
 
 				tx_buffer = tx_ring->tx_buffer_info;
-				tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0);
+				tx_desc = IXGBE_TX_DESC(tx_ring, 0);
 			}
 
 		} while (eop_desc);
@@ -807,7 +812,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
 	if (check_for_tx_hang(tx_ring) && ixgbe_check_tx_hang(tx_ring)) {
 		/* schedule immediate reset if we believe we hung */
 		struct ixgbe_hw *hw = &adapter->hw;
-		tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
+		tx_desc = IXGBE_TX_DESC(tx_ring, i);
 		e_err(drv, "Detected Tx Unit Hang\n"
 			"  Tx Queue             <%d>\n"
 			"  TDH, TDT             <%x>, <%x>\n"
@@ -986,10 +991,12 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
 }
 #endif /* CONFIG_IXGBE_DCA */
 
-static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc,
+static inline void ixgbe_rx_hash(struct ixgbe_ring *ring,
+				 union ixgbe_adv_rx_desc *rx_desc,
 				 struct sk_buff *skb)
 {
-	skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+	if (ring->netdev->features & NETIF_F_RXHASH)
+		skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
 }
 
 /**
@@ -1011,72 +1018,43 @@ static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter,
 }
 
 /**
- * ixgbe_receive_skb - Send a completed packet up the stack
- * @adapter: board private structure
- * @skb: packet to send up
- * @status: hardware indication of status of receive
- * @rx_ring: rx descriptor ring (for a specific queue) to setup
- * @rx_desc: rx descriptor
- **/
-static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
-			      struct sk_buff *skb, u8 status,
-			      struct ixgbe_ring *ring,
-			      union ixgbe_adv_rx_desc *rx_desc)
-{
-	struct ixgbe_adapter *adapter = q_vector->adapter;
-	struct napi_struct *napi = &q_vector->napi;
-	bool is_vlan = (status & IXGBE_RXD_STAT_VP);
-	u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
-
-	if (is_vlan && (tag & VLAN_VID_MASK))
-		__vlan_hwaccel_put_tag(skb, tag);
-
-	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
-		napi_gro_receive(napi, skb);
-	else
-		netif_rx(skb);
-}
-
-/**
  * ixgbe_rx_checksum - indicate in skb if hw indicated a good cksum
- * @adapter: address of board private structure
- * @status_err: hardware indication of status of receive
+ * @ring: structure containing ring specific data
+ * @rx_desc: current Rx descriptor being processed
  * @skb: skb currently being received and modified
- * @status_err: status error value of last descriptor in packet
  **/
-static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
+static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
 				     union ixgbe_adv_rx_desc *rx_desc,
-				     struct sk_buff *skb,
-				     u32 status_err)
+				     struct sk_buff *skb)
 {
-	skb->ip_summed = CHECKSUM_NONE;
+	skb_checksum_none_assert(skb);
 
 	/* Rx csum disabled */
-	if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
+	if (!(ring->netdev->features & NETIF_F_RXCSUM))
 		return;
 
 	/* if IP and error */
-	if ((status_err & IXGBE_RXD_STAT_IPCS) &&
-	    (status_err & IXGBE_RXDADV_ERR_IPE)) {
-		adapter->hw_csum_rx_error++;
+	if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) &&
+	    ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) {
+		ring->rx_stats.csum_err++;
 		return;
 	}
 
-	if (!(status_err & IXGBE_RXD_STAT_L4CS))
+	if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_L4CS))
 		return;
 
-	if (status_err & IXGBE_RXDADV_ERR_TCPE) {
+	if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) {
 		u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
 
 		/*
 		 * 82599 errata, UDP frames with a 0 checksum can be marked as
 		 * checksum errors.
 		 */
-		if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) &&
-		    (adapter->hw.mac.type == ixgbe_mac_82599EB))
+		if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_UDP)) &&
+		    test_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state))
 			return;
 
-		adapter->hw_csum_rx_error++;
+		ring->rx_stats.csum_err++;
 		return;
 	}
 
@@ -1086,6 +1064,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
 
 static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
 {
+	rx_ring->next_to_use = val;
 	/*
 	 * Force memory writes to complete before letting h/w
 	 * know there are new descriptors to fetch.  (Only
@@ -1096,8 +1075,72 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
 	writel(val, rx_ring->tail);
 }
 
+static bool ixgbe_alloc_mapped_skb(struct ixgbe_ring *rx_ring,
+				   struct ixgbe_rx_buffer *bi)
+{
+	struct sk_buff *skb = bi->skb;
+	dma_addr_t dma = bi->dma;
+
+	if (dma)
+		return true;
+
+	if (likely(!skb)) {
+		skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
+						rx_ring->rx_buf_len);
+		bi->skb = skb;
+		if (!skb) {
+			rx_ring->rx_stats.alloc_rx_buff_failed++;
+			return false;
+		}
+	}
+
+	dma = dma_map_single(rx_ring->dev, skb->data,
+			     rx_ring->rx_buf_len, DMA_FROM_DEVICE);
+
+	if (dma_mapping_error(rx_ring->dev, dma)) {
+		rx_ring->rx_stats.alloc_rx_buff_failed++;
+		return false;
+	}
+
+	bi->dma = dma;
+	return true;
+}
+
+static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
+				    struct ixgbe_rx_buffer *bi)
+{
+	struct page *page = bi->page;
+	dma_addr_t page_dma = bi->page_dma;
+	unsigned int page_offset = bi->page_offset ^ (PAGE_SIZE / 2);
+
+	if (page_dma)
+		return true;
+
+	if (!page) {
+		page = alloc_page(GFP_ATOMIC | __GFP_COLD);
+		bi->page = page;
+		if (unlikely(!page)) {
+			rx_ring->rx_stats.alloc_rx_page_failed++;
+			return false;
+		}
+	}
+
+	page_dma = dma_map_page(rx_ring->dev, page,
+				page_offset, PAGE_SIZE / 2,
+				DMA_FROM_DEVICE);
+
+	if (dma_mapping_error(rx_ring->dev, page_dma)) {
+		rx_ring->rx_stats.alloc_rx_page_failed++;
+		return false;
+	}
+
+	bi->page_dma = page_dma;
+	bi->page_offset = page_offset;
+	return true;
+}
+
 /**
- * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
+ * ixgbe_alloc_rx_buffers - Replace used receive buffers
  * @rx_ring: ring to place buffers on
  * @cleaned_count: number of buffers to replace
  **/
@@ -1105,86 +1148,50 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
 {
 	union ixgbe_adv_rx_desc *rx_desc;
 	struct ixgbe_rx_buffer *bi;
-	struct sk_buff *skb;
 	u16 i = rx_ring->next_to_use;
 
-	/* do nothing if no valid netdev defined */
-	if (!rx_ring->netdev)
+	/* nothing to do or no valid netdev defined */
+	if (!cleaned_count || !rx_ring->netdev)
 		return;
 
-	while (cleaned_count--) {
-		rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
-		bi = &rx_ring->rx_buffer_info[i];
-		skb = bi->skb;
-
-		if (!skb) {
-			skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
-							rx_ring->rx_buf_len);
-			if (!skb) {
-				rx_ring->rx_stats.alloc_rx_buff_failed++;
-				goto no_buffers;
-			}
-			/* initialize queue mapping */
-			skb_record_rx_queue(skb, rx_ring->queue_index);
-			bi->skb = skb;
-		}
+	rx_desc = IXGBE_RX_DESC(rx_ring, i);
+	bi = &rx_ring->rx_buffer_info[i];
+	i -= rx_ring->count;
 
-		if (!bi->dma) {
-			bi->dma = dma_map_single(rx_ring->dev,
-						 skb->data,
-						 rx_ring->rx_buf_len,
-						 DMA_FROM_DEVICE);
-			if (dma_mapping_error(rx_ring->dev, bi->dma)) {
-				rx_ring->rx_stats.alloc_rx_buff_failed++;
-				bi->dma = 0;
-				goto no_buffers;
-			}
-		}
+	while (cleaned_count--) {
+		if (!ixgbe_alloc_mapped_skb(rx_ring, bi))
+			break;
 
+		/* Refresh the desc even if buffer_addrs didn't change
+		 * because each write-back erases this info. */
 		if (ring_is_ps_enabled(rx_ring)) {
-			if (!bi->page) {
-				bi->page = alloc_page(GFP_ATOMIC | __GFP_COLD);
-				if (!bi->page) {
-					rx_ring->rx_stats.alloc_rx_page_failed++;
-					goto no_buffers;
-				}
-			}
+			rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
 
-			if (!bi->page_dma) {
-				/* use a half page if we're re-using */
-				bi->page_offset ^= PAGE_SIZE / 2;
-				bi->page_dma = dma_map_page(rx_ring->dev,
-							    bi->page,
-							    bi->page_offset,
-							    PAGE_SIZE / 2,
-							    DMA_FROM_DEVICE);
-				if (dma_mapping_error(rx_ring->dev,
-						      bi->page_dma)) {
-					rx_ring->rx_stats.alloc_rx_page_failed++;
-					bi->page_dma = 0;
-					goto no_buffers;
-				}
-			}
+			if (!ixgbe_alloc_mapped_page(rx_ring, bi))
+				break;
 
-			/* Refresh the desc even if buffer_addrs didn't change
-			 * because each write-back erases this info. */
 			rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
-			rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
 		} else {
 			rx_desc->read.pkt_addr = cpu_to_le64(bi->dma);
-			rx_desc->read.hdr_addr = 0;
 		}
 
+		rx_desc++;
+		bi++;
 		i++;
-		if (i == rx_ring->count)
-			i = 0;
+		if (unlikely(!i)) {
+			rx_desc = IXGBE_RX_DESC(rx_ring, 0);
+			bi = rx_ring->rx_buffer_info;
+			i -= rx_ring->count;
+		}
+
+		/* clear the hdr_addr for the next_to_use descriptor */
+		rx_desc->read.hdr_addr = 0;
 	}
 
-no_buffers:
-	if (rx_ring->next_to_use != i) {
-		rx_ring->next_to_use = i;
+	i += rx_ring->count;
+
+	if (rx_ring->next_to_use != i)
 		ixgbe_release_rx_desc(rx_ring, i);
-	}
 }
 
 static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc)
@@ -1202,65 +1209,283 @@ static inline u16 ixgbe_get_hlen(union ixgbe_adv_rx_desc *rx_desc)
 }
 
 /**
- * ixgbe_transform_rsc_queue - change rsc queue into a full packet
- * @skb: pointer to the last skb in the rsc queue
+ * ixgbe_merge_active_tail - merge active tail into lro skb
+ * @tail: pointer to active tail in frag_list
+ *
+ * This function merges the length and data of an active tail into the
+ * skb containing the frag_list.  It resets the tail's pointer to the head,
+ * but it leaves the heads pointer to tail intact.
+ **/
+static inline struct sk_buff *ixgbe_merge_active_tail(struct sk_buff *tail)
+{
+	struct sk_buff *head = IXGBE_CB(tail)->head;
+
+	if (!head)
+		return tail;
+
+	head->len += tail->len;
+	head->data_len += tail->len;
+	head->truesize += tail->len;
+
+	IXGBE_CB(tail)->head = NULL;
+
+	return head;
+}
+
+/**
+ * ixgbe_add_active_tail - adds an active tail into the skb frag_list
+ * @head: pointer to the start of the skb
+ * @tail: pointer to active tail to add to frag_list
+ *
+ * This function adds an active tail to the end of the frag list.  This tail
+ * will still be receiving data so we cannot yet ad it's stats to the main
+ * skb.  That is done via ixgbe_merge_active_tail.
+ **/
+static inline void ixgbe_add_active_tail(struct sk_buff *head,
+					 struct sk_buff *tail)
+{
+	struct sk_buff *old_tail = IXGBE_CB(head)->tail;
+
+	if (old_tail) {
+		ixgbe_merge_active_tail(old_tail);
+		old_tail->next = tail;
+	} else {
+		skb_shinfo(head)->frag_list = tail;
+	}
+
+	IXGBE_CB(tail)->head = head;
+	IXGBE_CB(head)->tail = tail;
+}
+
+/**
+ * ixgbe_close_active_frag_list - cleanup pointers on a frag_list skb
+ * @head: pointer to head of an active frag list
+ *
+ * This function will clear the frag_tail_tracker pointer on an active
+ * frag_list and returns true if the pointer was actually set
+ **/
+static inline bool ixgbe_close_active_frag_list(struct sk_buff *head)
+{
+	struct sk_buff *tail = IXGBE_CB(head)->tail;
+
+	if (!tail)
+		return false;
+
+	ixgbe_merge_active_tail(tail);
+
+	IXGBE_CB(head)->tail = NULL;
+
+	return true;
+}
+
+/**
+ * ixgbe_get_headlen - determine size of header for RSC/LRO/GRO/FCOE
+ * @data: pointer to the start of the headers
+ * @max_len: total length of section to find headers in
+ *
+ * This function is meant to determine the length of headers that will
+ * be recognized by hardware for LRO, GRO, and RSC offloads.  The main
+ * motivation of doing this is to only perform one pull for IPv4 TCP
+ * packets so that we can do basic things like calculating the gso_size
+ * based on the average data per packet.
+ **/
+static unsigned int ixgbe_get_headlen(unsigned char *data,
+				      unsigned int max_len)
+{
+	union {
+		unsigned char *network;
+		/* l2 headers */
+		struct ethhdr *eth;
+		struct vlan_hdr *vlan;
+		/* l3 headers */
+		struct iphdr *ipv4;
+	} hdr;
+	__be16 protocol;
+	u8 nexthdr = 0;	/* default to not TCP */
+	u8 hlen;
+
+	/* this should never happen, but better safe than sorry */
+	if (max_len < ETH_HLEN)
+		return max_len;
+
+	/* initialize network frame pointer */
+	hdr.network = data;
+
+	/* set first protocol and move network header forward */
+	protocol = hdr.eth->h_proto;
+	hdr.network += ETH_HLEN;
+
+	/* handle any vlan tag if present */
+	if (protocol == __constant_htons(ETH_P_8021Q)) {
+		if ((hdr.network - data) > (max_len - VLAN_HLEN))
+			return max_len;
+
+		protocol = hdr.vlan->h_vlan_encapsulated_proto;
+		hdr.network += VLAN_HLEN;
+	}
+
+	/* handle L3 protocols */
+	if (protocol == __constant_htons(ETH_P_IP)) {
+		if ((hdr.network - data) > (max_len - sizeof(struct iphdr)))
+			return max_len;
+
+		/* access ihl as a u8 to avoid unaligned access on ia64 */
+		hlen = (hdr.network[0] & 0x0F) << 2;
+
+		/* verify hlen meets minimum size requirements */
+		if (hlen < sizeof(struct iphdr))
+			return hdr.network - data;
+
+		/* record next protocol */
+		nexthdr = hdr.ipv4->protocol;
+		hdr.network += hlen;
+#ifdef CONFIG_FCOE
+	} else if (protocol == __constant_htons(ETH_P_FCOE)) {
+		if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN))
+			return max_len;
+		hdr.network += FCOE_HEADER_LEN;
+#endif
+	} else {
+		return hdr.network - data;
+	}
+
+	/* finally sort out TCP */
+	if (nexthdr == IPPROTO_TCP) {
+		if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
+			return max_len;
+
+		/* access doff as a u8 to avoid unaligned access on ia64 */
+		hlen = (hdr.network[12] & 0xF0) >> 2;
+
+		/* verify hlen meets minimum size requirements */
+		if (hlen < sizeof(struct tcphdr))
+			return hdr.network - data;
+
+		hdr.network += hlen;
+	}
+
+	/*
+	 * If everything has gone correctly hdr.network should be the
+	 * data section of the packet and will be the end of the header.
+	 * If not then it probably represents the end of the last recognized
+	 * header.
+	 */
+	if ((hdr.network - data) < max_len)
+		return hdr.network - data;
+	else
+		return max_len;
+}
+
+static void ixgbe_get_rsc_cnt(struct ixgbe_ring *rx_ring,
+			      union ixgbe_adv_rx_desc *rx_desc,
+			      struct sk_buff *skb)
+{
+	__le32 rsc_enabled;
+	u32 rsc_cnt;
+
+	if (!ring_is_rsc_enabled(rx_ring))
+		return;
+
+	rsc_enabled = rx_desc->wb.lower.lo_dword.data &
+		      cpu_to_le32(IXGBE_RXDADV_RSCCNT_MASK);
+
+	/* If this is an RSC frame rsc_cnt should be non-zero */
+	if (!rsc_enabled)
+		return;
+
+	rsc_cnt = le32_to_cpu(rsc_enabled);
+	rsc_cnt >>= IXGBE_RXDADV_RSCCNT_SHIFT;
+
+	IXGBE_CB(skb)->append_cnt += rsc_cnt - 1;
+}
+
+static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring,
+				   struct sk_buff *skb)
+{
+	u16 hdr_len = ixgbe_get_headlen(skb->data, skb_headlen(skb));
+
+	/* set gso_size to avoid messing up TCP MSS */
+	skb_shinfo(skb)->gso_size = DIV_ROUND_UP((skb->len - hdr_len),
+						 IXGBE_CB(skb)->append_cnt);
+}
+
+static void ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring,
+				   struct sk_buff *skb)
+{
+	/* if append_cnt is 0 then frame is not RSC */
+	if (!IXGBE_CB(skb)->append_cnt)
+		return;
+
+	rx_ring->rx_stats.rsc_count += IXGBE_CB(skb)->append_cnt;
+	rx_ring->rx_stats.rsc_flush++;
+
+	ixgbe_set_rsc_gso_size(rx_ring, skb);
+
+	/* gso_size is computed using append_cnt so always clear it last */
+	IXGBE_CB(skb)->append_cnt = 0;
+}
+
+/**
+ * ixgbe_process_skb_fields - Populate skb header fields from Rx descriptor
+ * @rx_ring: rx descriptor ring packet is being transacted on
+ * @rx_desc: pointer to the EOP Rx descriptor
+ * @skb: pointer to current skb being populated
  *
- * This function changes a queue full of hw rsc buffers into a completed
- * packet.  It uses the ->prev pointers to find the first packet and then
- * turns it into the frag list owner.
+ * This function checks the ring, descriptor, and packet information in
+ * order to populate the hash, checksum, VLAN, timestamp, protocol, and
+ * other fields within the skb.
  **/
-static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb)
+static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
+				     union ixgbe_adv_rx_desc *rx_desc,
+				     struct sk_buff *skb)
 {
-	unsigned int frag_list_size = 0;
-	unsigned int skb_cnt = 1;
+	ixgbe_update_rsc_stats(rx_ring, skb);
+
+	ixgbe_rx_hash(rx_ring, rx_desc, skb);
 
-	while (skb->prev) {
-		struct sk_buff *prev = skb->prev;
-		frag_list_size += skb->len;
-		skb->prev = NULL;
-		skb = prev;
-		skb_cnt++;
+	ixgbe_rx_checksum(rx_ring, rx_desc, skb);
+
+	if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
+		u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan);
+		__vlan_hwaccel_put_tag(skb, vid);
 	}
 
-	skb_shinfo(skb)->frag_list = skb->next;
-	skb->next = NULL;
-	skb->len += frag_list_size;
-	skb->data_len += frag_list_size;
-	skb->truesize += frag_list_size;
-	IXGBE_RSC_CB(skb)->skb_cnt = skb_cnt;
+	skb_record_rx_queue(skb, rx_ring->queue_index);
 
-	return skb;
+	skb->protocol = eth_type_trans(skb, rx_ring->netdev);
 }
 
-static inline bool ixgbe_get_rsc_state(union ixgbe_adv_rx_desc *rx_desc)
+static void ixgbe_rx_skb(struct ixgbe_q_vector *q_vector,
+			 struct sk_buff *skb)
 {
-	return !!(le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
-		IXGBE_RXDADV_RSCCNT_MASK);
+	struct ixgbe_adapter *adapter = q_vector->adapter;
+
+	if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
+		napi_gro_receive(&q_vector->napi, skb);
+	else
+		netif_rx(skb);
 }
 
 static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 			       struct ixgbe_ring *rx_ring,
 			       int budget)
 {
-	struct ixgbe_adapter *adapter = q_vector->adapter;
 	union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
-	struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
+	struct ixgbe_rx_buffer *rx_buffer_info;
 	struct sk_buff *skb;
 	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 	const int current_node = numa_node_id();
 #ifdef IXGBE_FCOE
+	struct ixgbe_adapter *adapter = q_vector->adapter;
 	int ddp_bytes = 0;
 #endif /* IXGBE_FCOE */
-	u32 staterr;
 	u16 i;
 	u16 cleaned_count = 0;
-	bool pkt_is_rsc = false;
 
 	i = rx_ring->next_to_clean;
-	rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i);
-	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+	rx_desc = IXGBE_RX_DESC(rx_ring, i);
 
-	while (staterr & IXGBE_RXD_STAT_DD) {
+	while (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_DD)) {
 		u32 upper_len = 0;
 
 		rmb(); /* read descriptor and rx_buffer_info after status DD */
@@ -1271,32 +1496,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 		rx_buffer_info->skb = NULL;
 		prefetch(skb->data);
 
-		if (ring_is_rsc_enabled(rx_ring))
-			pkt_is_rsc = ixgbe_get_rsc_state(rx_desc);
-
 		/* linear means we are building an skb from multiple pages */
 		if (!skb_is_nonlinear(skb)) {
 			u16 hlen;
-			if (pkt_is_rsc &&
-			    !(staterr & IXGBE_RXD_STAT_EOP) &&
-			    !skb->prev) {
-				/*
-				 * When HWRSC is enabled, delay unmapping
-				 * of the first packet. It carries the
-				 * header information, HW may still
-				 * access the header after the writeback.
-				 * Only unmap it when EOP is reached
-				 */
-				IXGBE_RSC_CB(skb)->delay_unmap = true;
-				IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma;
-			} else {
-				dma_unmap_single(rx_ring->dev,
-						 rx_buffer_info->dma,
-						 rx_ring->rx_buf_len,
-						 DMA_FROM_DEVICE);
-			}
-			rx_buffer_info->dma = 0;
-
 			if (ring_is_ps_enabled(rx_ring)) {
 				hlen = ixgbe_get_hlen(rx_desc);
 				upper_len = le16_to_cpu(rx_desc->wb.upper.length);
@@ -1305,6 +1507,23 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 			}
 
 			skb_put(skb, hlen);
+
+			/*
+			 * Delay unmapping of the first packet. It carries the
+			 * header information, HW may still access the header
+			 * after writeback.  Only unmap it when EOP is reached
+			 */
+			if (!IXGBE_CB(skb)->head) {
+				IXGBE_CB(skb)->delay_unmap = true;
+				IXGBE_CB(skb)->dma = rx_buffer_info->dma;
+			} else {
+				skb = ixgbe_merge_active_tail(skb);
+				dma_unmap_single(rx_ring->dev,
+						 rx_buffer_info->dma,
+						 rx_ring->rx_buf_len,
+						 DMA_FROM_DEVICE);
+			}
+			rx_buffer_info->dma = 0;
 		} else {
 			/* assume packet split since header is unmapped */
 			upper_len = le16_to_cpu(rx_desc->wb.upper.length);
@@ -1332,98 +1551,86 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
 			skb->truesize += PAGE_SIZE / 2;
 		}
 
+		ixgbe_get_rsc_cnt(rx_ring, rx_desc, skb);
+
 		i++;
 		if (i == rx_ring->count)
 			i = 0;
 
-		next_rxd = IXGBE_RX_DESC_ADV(rx_ring, i);
+		next_rxd = IXGBE_RX_DESC(rx_ring, i);
 		prefetch(next_rxd);
 		cleaned_count++;
 
-		if (pkt_is_rsc) {
-			u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >>
-				     IXGBE_RXDADV_NEXTP_SHIFT;
+		if ((!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))) {
+			struct ixgbe_rx_buffer *next_buffer;
+			u32 nextp;
+
+			if (IXGBE_CB(skb)->append_cnt) {
+				nextp = le32_to_cpu(
+						rx_desc->wb.upper.status_error);
+				nextp >>= IXGBE_RXDADV_NEXTP_SHIFT;
+			} else {
+				nextp = i;
+			}
+
 			next_buffer = &rx_ring->rx_buffer_info[nextp];
-		} else {
-			next_buffer = &rx_ring->rx_buffer_info[i];
-		}
 
-		if (!(staterr & IXGBE_RXD_STAT_EOP)) {
 			if (ring_is_ps_enabled(rx_ring)) {
 				rx_buffer_info->skb = next_buffer->skb;
 				rx_buffer_info->dma = next_buffer->dma;
 				next_buffer->skb = skb;
 				next_buffer->dma = 0;
 			} else {
-				skb->next = next_buffer->skb;
-				skb->next->prev = skb;
+				struct sk_buff *next_skb = next_buffer->skb;
+				ixgbe_add_active_tail(skb, next_skb);
+				IXGBE_CB(next_skb)->head = skb;
 			}
 			rx_ring->rx_stats.non_eop_descs++;
 			goto next_desc;
 		}
 
-		if (skb->prev) {
-			skb = ixgbe_transform_rsc_queue(skb);
-			/* if we got here without RSC the packet is invalid */
-			if (!pkt_is_rsc) {
-				__pskb_trim(skb, 0);
-				rx_buffer_info->skb = skb;
-				goto next_desc;
-			}
-		}
+		dma_unmap_single(rx_ring->dev,
+				 IXGBE_CB(skb)->dma,
+				 rx_ring->rx_buf_len,
+				 DMA_FROM_DEVICE);
+		IXGBE_CB(skb)->dma = 0;
+		IXGBE_CB(skb)->delay_unmap = false;
 
-		if (ring_is_rsc_enabled(rx_ring)) {
-			if (IXGBE_RSC_CB(skb)->delay_unmap) {
-				dma_unmap_single(rx_ring->dev,
-						 IXGBE_RSC_CB(skb)->dma,
-						 rx_ring->rx_buf_len,
-						 DMA_FROM_DEVICE);
-				IXGBE_RSC_CB(skb)->dma = 0;
-				IXGBE_RSC_CB(skb)->delay_unmap = false;
-			}
-		}
-		if (pkt_is_rsc) {
-			if (ring_is_ps_enabled(rx_ring))
-				rx_ring->rx_stats.rsc_count +=
-					skb_shinfo(skb)->nr_frags;
-			else
-				rx_ring->rx_stats.rsc_count +=
-					IXGBE_RSC_CB(skb)->skb_cnt;
-			rx_ring->rx_stats.rsc_flush++;
+		if (ixgbe_close_active_frag_list(skb) &&
+		    !IXGBE_CB(skb)->append_cnt) {
+			/* if we got here without RSC the packet is invalid */
+			dev_kfree_skb_any(skb);
+			goto next_desc;
 		}
 
 		/* ERR_MASK will only have valid bits if EOP set */
-		if (unlikely(staterr & IXGBE_RXDADV_ERR_FRAME_ERR_MASK)) {
+		if (unlikely(ixgbe_test_staterr(rx_desc,
+					    IXGBE_RXDADV_ERR_FRAME_ERR_MASK))) {
 			dev_kfree_skb_any(skb);
 			goto next_desc;
 		}
 
-		ixgbe_rx_checksum(adapter, rx_desc, skb, staterr);
-		if (adapter->netdev->features & NETIF_F_RXHASH)
-			ixgbe_rx_hash(rx_desc, skb);
-
 		/* probably a little skewed due to removing CRC */
 		total_rx_bytes += skb->len;
 		total_rx_packets++;
 
-		skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+		/* populate checksum, timestamp, VLAN, and protocol */
+		ixgbe_process_skb_fields(rx_ring, rx_desc, skb);
+
 #ifdef IXGBE_FCOE
 		/* if ddp, not passing to ULD unless for FCP_RSP or error */
 		if (ixgbe_rx_is_fcoe(adapter, rx_desc)) {
-			ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb,
-						   staterr);
+			ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb);
 			if (!ddp_bytes) {
 				dev_kfree_skb_any(skb);
 				goto next_desc;
 			}
 		}
 #endif /* IXGBE_FCOE */
-		ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
+		ixgbe_rx_skb(q_vector, skb);
 
 		budget--;
 next_desc:
-		rx_desc->wb.upper.status_error = 0;
-
 		if (!budget)
 			break;
 
@@ -1435,7 +1642,6 @@ next_desc:
 
 		/* use prefetched values */
 		rx_desc = next_rxd;
-		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
 	}
 
 	rx_ring->next_to_clean = i;
@@ -3876,19 +4082,18 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
 		if (rx_buffer_info->skb) {
 			struct sk_buff *skb = rx_buffer_info->skb;
 			rx_buffer_info->skb = NULL;
-			do {
-				struct sk_buff *this = skb;
-				if (IXGBE_RSC_CB(this)->delay_unmap) {
-					dma_unmap_single(dev,
-							 IXGBE_RSC_CB(this)->dma,
-							 rx_ring->rx_buf_len,
-							 DMA_FROM_DEVICE);
-					IXGBE_RSC_CB(this)->dma = 0;
-					IXGBE_RSC_CB(skb)->delay_unmap = false;
-				}
-				skb = skb->prev;
-				dev_kfree_skb(this);
-			} while (skb);
+			/* We need to clean up RSC frag lists */
+			skb = ixgbe_merge_active_tail(skb);
+			ixgbe_close_active_frag_list(skb);
+			if (IXGBE_CB(skb)->delay_unmap) {
+				dma_unmap_single(dev,
+						 IXGBE_CB(skb)->dma,
+						 rx_ring->rx_buf_len,
+						 DMA_FROM_DEVICE);
+				IXGBE_CB(skb)->dma = 0;
+				IXGBE_CB(skb)->delay_unmap = false;
+			}
+			dev_kfree_skb(skb);
 		}
 		if (!rx_buffer_info->page)
 			continue;
@@ -4661,6 +4866,13 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
 		ring->dev = &adapter->pdev->dev;
 		ring->netdev = adapter->netdev;
 
+		/*
+		 * 82599 errata, UDP frames with a 0 checksum can be marked as
+		 * checksum errors.
+		 */
+		if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+			set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state);
+
 		adapter->rx_ring[rx] = ring;
 	}
 
@@ -5065,9 +5277,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
 		return -EIO;
 	}
 
-	/* enable rx csum by default */
-	adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-
 	/* get assigned NUMA node */
 	adapter->node = dev_to_node(&pdev->dev);
 
@@ -5558,7 +5767,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 	u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
 	u64 non_eop_descs = 0, restart_queue = 0, tx_busy = 0;
 	u64 alloc_rx_page_failed = 0, alloc_rx_buff_failed = 0;
-	u64 bytes = 0, packets = 0;
+	u64 bytes = 0, packets = 0, hw_csum_rx_error = 0;
 #ifdef IXGBE_FCOE
 	struct ixgbe_fcoe *fcoe = &adapter->fcoe;
 	unsigned int cpu;
@@ -5588,12 +5797,14 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 		non_eop_descs += rx_ring->rx_stats.non_eop_descs;
 		alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed;
 		alloc_rx_buff_failed += rx_ring->rx_stats.alloc_rx_buff_failed;
+		hw_csum_rx_error += rx_ring->rx_stats.csum_err;
 		bytes += rx_ring->stats.bytes;
 		packets += rx_ring->stats.packets;
 	}
 	adapter->non_eop_descs = non_eop_descs;
 	adapter->alloc_rx_page_failed = alloc_rx_page_failed;
 	adapter->alloc_rx_buff_failed = alloc_rx_buff_failed;
+	adapter->hw_csum_rx_error = hw_csum_rx_error;
 	netdev->stats.rx_bytes = bytes;
 	netdev->stats.rx_packets = packets;
 
@@ -6279,7 +6490,7 @@ void ixgbe_tx_ctxtdesc(struct ixgbe_ring *tx_ring, u32 vlan_macip_lens,
 	struct ixgbe_adv_tx_context_desc *context_desc;
 	u16 i = tx_ring->next_to_use;
 
-	context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i);
+	context_desc = IXGBE_TX_CTXTDESC(tx_ring, i);
 
 	i++;
 	tx_ring->next_to_use = (i < tx_ring->count) ? i : 0;
@@ -6512,7 +6723,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 	cmd_type = ixgbe_tx_cmd_type(tx_flags);
 	olinfo_status = ixgbe_tx_olinfo_status(tx_flags, paylen);
 
-	tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i);
+	tx_desc = IXGBE_TX_DESC(tx_ring, i);
 
 	for (;;) {
 		while (size > IXGBE_MAX_DATA_PER_TXD) {
@@ -6527,7 +6738,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 			tx_desc++;
 			i++;
 			if (i == tx_ring->count) {
-				tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0);
+				tx_desc = IXGBE_TX_DESC(tx_ring, 0);
 				i = 0;
 			}
 		}
@@ -6563,7 +6774,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 		tx_desc++;
 		i++;
 		if (i == tx_ring->count) {
-			tx_desc = IXGBE_TX_DESC_ADV(tx_ring, 0);
+			tx_desc = IXGBE_TX_DESC(tx_ring, 0);
 			i = 0;
 		}
 	}
@@ -7222,12 +7433,6 @@ static int ixgbe_set_features(struct net_device *netdev,
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	bool need_reset = false;
 
-	/* If Rx checksum is disabled, then RSC/LRO should also be disabled */
-	if (!(data & NETIF_F_RXCSUM))
-		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
-	else
-		adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
-
 	/* Make sure RSC matches LRO, reset if change */
 	if (!!(data & NETIF_F_LRO) !=
 	     !!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) {
@@ -7493,6 +7698,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 			e_crit(probe, "Fan has stopped, replace the adapter\n");
 	}
 
+	if (allow_unsupported_sfp)
+		hw->allow_unsupported_sfp = allow_unsupported_sfp;
+
 	/* reset_hw fills in the perm_addr as well */
 	hw->phy.reset_if_overtemp = true;
 	err = hw->mac.ops.reset_hw(hw);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index b917735..bf9f82f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -834,6 +834,7 @@ out:
  **/
 s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 {
+	struct ixgbe_adapter *adapter = hw->back;
 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
 	u32 vendor_oui = 0;
 	enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
@@ -1068,9 +1069,16 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 			if (hw->phy.type == ixgbe_phy_sfp_intel) {
 				status = 0;
 			} else {
-				hw_dbg(hw, "SFP+ module not supported\n");
-				hw->phy.type = ixgbe_phy_sfp_unsupported;
-				status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+				if (hw->allow_unsupported_sfp) {
+					e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics.  Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter.  Intel Corporation is not responsible for any harm caused by using untested modules.");
+					status = 0;
+				} else {
+					hw_dbg(hw,
+					       "SFP+ module not supported\n");
+					hw->phy.type =
+						ixgbe_phy_sfp_unsupported;
+					status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+				}
 			}
 		} else {
 			status = 0;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index b01ecb4..88a58cb 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -258,7 +258,7 @@ static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
 
 	list_for_each(pos, &adapter->vf_mvs.l) {
 		entry = list_entry(pos, struct vf_macvlans, l);
-		if (entry->free == false)
+		if (!entry->free)
 			hw->mac.ops.set_rar(hw, entry->rar_entry,
 					    entry->vf_macvlan,
 					    entry->vf, IXGBE_RAH_AV);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 9b95bef..4c06029 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2892,6 +2892,7 @@ struct ixgbe_hw {
 	u8				revision_id;
 	bool				adapter_stopped;
 	bool				force_full_reset;
+	bool				allow_unsupported_sfp;
 };
 
 struct ixgbe_info {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
index f838a2b..5e9f05f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
@@ -760,7 +760,7 @@ static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
 	 * This will be reversed when we stop the blinking.
 	 */
 	hw->mac.ops.check_link(hw, &speed, &link_up, false);
-	if (link_up == false) {
+	if (!link_up) {
 		macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
 		macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
 		IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index e51d552..e10221d 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -2199,13 +2199,17 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
 	if (err) {
 		dev_info(&pdev->dev,
 		         "PF still in reset state, assigning new address\n");
-		dev_hw_addr_random(adapter->netdev, hw->mac.addr);
+		eth_hw_addr_random(adapter->netdev);
+		memcpy(adapter->hw.mac.addr, adapter->netdev->dev_addr,
+			adapter->netdev->addr_len);
 	} else {
 		err = hw->mac.ops.init_hw(hw);
 		if (err) {
 			pr_err("init_shared_code failed: %d\n", err);
 			goto out;
 		}
+		memcpy(adapter->netdev->dev_addr, adapter->hw.mac.addr,
+			adapter->netdev->addr_len);
 	}
 
 	/* Enable dynamic interrupt throttling rates */
@@ -2224,6 +2228,7 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
 	adapter->flags |= IXGBE_FLAG_RX_CSUM_ENABLED;
 
 	set_bit(__IXGBEVF_DOWN, &adapter->state);
+	return 0;
 
 out:
 	return err;
@@ -2521,12 +2526,8 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter,
 
 	size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count;
 	rx_ring->rx_buffer_info = vzalloc(size);
-	if (!rx_ring->rx_buffer_info) {
-		hw_dbg(&adapter->hw,
-		       "Unable to vmalloc buffer memory for "
-		       "the receive descriptor ring\n");
+	if (!rx_ring->rx_buffer_info)
 		goto alloc_failed;
-	}
 
 	/* Round up to nearest 4K */
 	rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
@@ -3398,6 +3399,17 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 
 	/* setup the private structure */
 	err = ixgbevf_sw_init(adapter);
+	if (err)
+		goto err_sw_init;
+
+	/* The HW MAC address was set and/or determined in sw_init */
+	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+
+	if (!is_valid_ether_addr(netdev->dev_addr)) {
+		pr_err("invalid MAC address\n");
+		err = -EIO;
+		goto err_sw_init;
+	}
 
 	netdev->hw_features = NETIF_F_SG |
 			   NETIF_F_IP_CSUM |
@@ -3422,16 +3434,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev,
 
 	netdev->priv_flags |= IFF_UNICAST_FLT;
 
-	/* The HW MAC address was set and/or determined in sw_init */
-	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
-	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
-
-	if (!is_valid_ether_addr(netdev->dev_addr)) {
-		pr_err("invalid MAC address\n");
-		err = -EIO;
-		goto err_sw_init;
-	}
-
 	init_timer(&adapter->watchdog_timer);
 	adapter->watchdog_timer.function = ixgbevf_watchdog;
 	adapter->watchdog_timer.data = (unsigned long)adapter;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 27d651a..1b86d0b 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2999,7 +2999,6 @@ jme_init_one(struct pci_dev *pdev,
 	 */
 	netdev = alloc_etherdev(sizeof(*jme));
 	if (!netdev) {
-		pr_err("Cannot allocate netdev structure\n");
 		rc = -ENOMEM;
 		goto err_out_release_regions;
 	}
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 6ad094f..f30db1c 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -1108,10 +1108,9 @@ static int korina_probe(struct platform_device *pdev)
 	int rc;
 
 	dev = alloc_etherdev(sizeof(struct korina_private));
-	if (!dev) {
-		printk(KERN_ERR DRV_NAME ": alloc_etherdev failed\n");
+	if (!dev)
 		return -ENOMEM;
-	}
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	lp = netdev_priv(dev);
 
@@ -1150,7 +1149,6 @@ static int korina_probe(struct platform_device *pdev)
 
 	lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
 	if (!lp->td_ring) {
-		printk(KERN_ERR DRV_NAME ": cannot allocate descriptors\n");
 		rc = -ENXIO;
 		goto probe_err_td_ring;
 	}
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
index 85e2c6c..5dc9cbd 100644
--- a/drivers/net/ethernet/lantiq_etop.c
+++ b/drivers/net/ethernet/lantiq_etop.c
@@ -114,7 +114,7 @@ struct ltq_etop_priv {
 static int
 ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
 {
-	ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
+	ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN);
 	if (!ch->skb[ch->dma.desc])
 		return -ENOMEM;
 	ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
@@ -634,6 +634,7 @@ ltq_etop_init(struct net_device *dev)
 	struct ltq_etop_priv *priv = netdev_priv(dev);
 	struct sockaddr mac;
 	int err;
+	bool random_mac = false;
 
 	ether_setup(dev);
 	dev->watchdog_timeo = 10 * HZ;
@@ -646,11 +647,17 @@ ltq_etop_init(struct net_device *dev)
 	if (!is_valid_ether_addr(mac.sa_data)) {
 		pr_warn("etop: invalid MAC, using random\n");
 		random_ether_addr(mac.sa_data);
+		random_mac = true;
 	}
 
 	err = ltq_etop_set_mac_address(dev, &mac);
 	if (err)
 		goto err_netdev;
+
+	/* Set addr_assign_type here, ltq_etop_set_mac_address would reset it. */
+	if (random_mac)
+		dev->addr_assign_type |= NET_ADDR_RANDOM;
+
 	ltq_etop_set_multicast_list(dev);
 	err = ltq_etop_mdio_init(dev);
 	if (err)
@@ -731,6 +738,10 @@ ltq_etop_probe(struct platform_device *pdev)
 	}
 
 	dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
+	if (!dev) {
+		err = -ENOMEM;
+		goto err_out;
+	}
 	strcpy(dev->name, "eth%d");
 	dev->netdev_ops = &ltq_eth_netdev_ops;
 	dev->ethtool_ops = &ltq_etop_ethtool_ops;
@@ -792,7 +803,7 @@ init_ltq_etop(void)
 	int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
 
 	if (ret)
-		pr_err("ltq_etop: Error registering platfom driver!");
+		pr_err("ltq_etop: Error registering platform driver!");
 	return ret;
 }
 
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 9edecfa..f702d0d 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -667,7 +667,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
 
 		skb = __skb_dequeue(&mp->rx_recycle);
 		if (skb == NULL)
-			skb = dev_alloc_skb(mp->skb_size);
+			skb = netdev_alloc_skb(mp->dev, mp->skb_size);
 
 		if (skb == NULL) {
 			mp->oom = 1;
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
index 953ba58..83e37ad 100644
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -350,7 +350,7 @@ static void rxq_refill(struct net_device *dev)
 	while (pep->rx_desc_count < pep->rx_ring_size) {
 		int size;
 
-		skb = dev_alloc_skb(pep->skb_size);
+		skb = netdev_alloc_skb(dev, pep->skb_size);
 		if (!skb)
 			break;
 		if (SKB_DMA_REALIGN)
@@ -629,6 +629,7 @@ static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr)
 	if (!is_valid_ether_addr(sa->sa_data))
 		return -EINVAL;
 	memcpy(oldMac, dev->dev_addr, ETH_ALEN);
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
 	netif_addr_lock_bh(dev);
 	update_hash_table_mac_address(pep, oldMac, dev->dev_addr);
@@ -1017,10 +1018,9 @@ static int rxq_init(struct net_device *dev)
 	/* Allocate RX skb rings */
 	pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size,
 			     GFP_KERNEL);
-	if (!pep->rx_skb) {
-		printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name);
+	if (!pep->rx_skb)
 		return -ENOMEM;
-	}
+
 	/* Allocate RX ring */
 	pep->rx_desc_count = 0;
 	size = pep->rx_ring_size * sizeof(struct rx_desc);
@@ -1081,10 +1081,9 @@ static int txq_init(struct net_device *dev)
 
 	pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size,
 			     GFP_KERNEL);
-	if (!pep->tx_skb) {
-		printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name);
+	if (!pep->tx_skb)
 		return -ENOMEM;
-	}
+
 	/* Allocate TX ring */
 	pep->tx_desc_count = 0;
 	size = pep->tx_ring_size * sizeof(struct tx_desc);
@@ -1522,7 +1521,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
 	INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
 
 	printk(KERN_INFO "%s:Using random mac address\n", DRIVER_NAME);
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 
 	pep->pd = pdev->dev.platform_data;
 	pep->rx_ring_size = NUM_RX_DESCS;
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 33947ac..5a30bf8 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -3807,10 +3807,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 	struct skge_port *skge;
 	struct net_device *dev = alloc_etherdev(sizeof(*skge));
 
-	if (!dev) {
-		dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
+	if (!dev)
 		return NULL;
-	}
 
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
 	dev->netdev_ops = &skge_netdev_ops;
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 760c2b1..82c2c86 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4700,10 +4700,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 	struct sky2_port *sky2;
 	struct net_device *dev = alloc_etherdev(sizeof(*sky2));
 
-	if (!dev) {
-		dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
+	if (!dev)
 		return NULL;
-	}
 
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
 	dev->irq = hw->pdev->irq;
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index eaf09d4..48d5c48 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1314,7 +1314,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
 		down(&priv->cmd.slave_sem);
 		if (mlx4_master_process_vhcr(dev, slave, NULL)) {
 			mlx4_err(dev, "Failed processing vhcr for slave:%d,"
-				 " reseting slave.\n", slave);
+				 " resetting slave.\n", slave);
 			up(&priv->cmd.slave_sem);
 			goto reset_slave;
 		}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 149e60d..9fe4f94 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1048,10 +1048,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 
 	dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv),
 	    prof->tx_ring_num, prof->rx_ring_num);
-	if (dev == NULL) {
-		mlx4_err(mdev, "Net device allocation failed\n");
+	if (dev == NULL)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(dev, &mdev->dev->pdev->dev);
 	dev->dev_id =  port - 1;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index d4ad8c2..d703ef2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -285,10 +285,9 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
 	tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS *
 					sizeof(struct skb_frag_struct));
 	ring->rx_info = vmalloc(tmp);
-	if (!ring->rx_info) {
-		en_err(priv, "Failed allocating rx_info ring\n");
+	if (!ring->rx_info)
 		return -ENOMEM;
-	}
+
 	en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
 		 ring->rx_info, tmp);
 
@@ -468,12 +467,11 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
 	int used_frags;
 	dma_addr_t dma;
 
-	skb = dev_alloc_skb(SMALL_PACKET_SIZE + NET_IP_ALIGN);
+	skb = netdev_alloc_skb(priv->dev, SMALL_PACKET_SIZE + NET_IP_ALIGN);
 	if (!skb) {
 		en_dbg(RX_ERR, priv, "Failed allocating skb\n");
 		return NULL;
 	}
-	skb->dev = priv->dev;
 	skb_reserve(skb, NET_IP_ALIGN);
 	skb->len = length;
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 9ef9038..ff32505 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -71,16 +71,14 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
 
 	tmp = size * sizeof(struct mlx4_en_tx_info);
 	ring->tx_info = vmalloc(tmp);
-	if (!ring->tx_info) {
-		en_err(priv, "Failed allocating tx_info ring\n");
+	if (!ring->tx_info)
 		return -ENOMEM;
-	}
+
 	en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
 		 ring->tx_info, tmp);
 
 	ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL);
 	if (!ring->bounce_buf) {
-		en_err(priv, "Failed allocating bounce buffer\n");
 		err = -ENOMEM;
 		goto err_tx;
 	}
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 8fa41f3..9129ace 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1036,7 +1036,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
 	struct mlx4_priv *priv = mlx4_priv(dev);
 	int vec = 0, err = 0, i;
 
-	spin_lock(&priv->msix_ctl.pool_lock);
+	mutex_lock(&priv->msix_ctl.pool_lock);
 	for (i = 0; !vec && i < dev->caps.comp_pool; i++) {
 		if (~priv->msix_ctl.pool_bm & 1ULL << i) {
 			priv->msix_ctl.pool_bm |= 1ULL << i;
@@ -1058,7 +1058,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
 			eq_set_ci(&priv->eq_table.eq[vec], 1);
 		}
 	}
-	spin_unlock(&priv->msix_ctl.pool_lock);
+	mutex_unlock(&priv->msix_ctl.pool_lock);
 
 	if (vec) {
 		*vector = vec;
@@ -1079,13 +1079,13 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec)
 	if (likely(i >= 0)) {
 		/*sanity check , making sure were not trying to free irq's
 		  Belonging to a legacy EQ*/
-		spin_lock(&priv->msix_ctl.pool_lock);
+		mutex_lock(&priv->msix_ctl.pool_lock);
 		if (priv->msix_ctl.pool_bm & 1ULL << i) {
 			free_irq(priv->eq_table.eq[vec].irq,
 				 &priv->eq_table.eq[vec]);
 			priv->msix_ctl.pool_bm &= ~(1ULL << i);
 		}
-		spin_unlock(&priv->msix_ctl.pool_lock);
+		mutex_unlock(&priv->msix_ctl.pool_lock);
 	}
 
 }
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 678558b..d9d950a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -531,15 +531,14 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
 	for (port = 0; port <  dev->caps.num_ports; port++) {
 		/* Change the port type only if the new type is different
 		 * from the current, and not set to Auto */
-		if (port_types[port] != dev->caps.port_type[port + 1]) {
+		if (port_types[port] != dev->caps.port_type[port + 1])
 			change = 1;
-			dev->caps.port_type[port + 1] = port_types[port];
-		}
 	}
 	if (change) {
 		mlx4_unregister_device(dev);
 		for (port = 1; port <= dev->caps.num_ports; port++) {
 			mlx4_CLOSE_PORT(dev, port);
+			dev->caps.port_type[port + 1] = port_types[port];
 			err = mlx4_SET_PORT(dev, port);
 			if (err) {
 				mlx4_err(dev, "Failed to set port %d, "
@@ -986,6 +985,9 @@ static int map_bf_area(struct mlx4_dev *dev)
 	resource_size_t bf_len;
 	int err = 0;
 
+	if (!dev->caps.bf_reg_size)
+		return -ENXIO;
+
 	bf_start = pci_resource_start(dev->pdev, 2) +
 			(dev->caps.num_uars << PAGE_SHIFT);
 	bf_len = pci_resource_len(dev->pdev, 2) -
@@ -1543,13 +1545,11 @@ static int mlx4_init_steering(struct mlx4_dev *dev)
 	if (!priv->steer)
 		return -ENOMEM;
 
-	for (i = 0; i < num_entries; i++) {
+	for (i = 0; i < num_entries; i++)
 		for (j = 0; j < MLX4_NUM_STEERS; j++) {
 			INIT_LIST_HEAD(&priv->steer[i].promisc_qps[j]);
 			INIT_LIST_HEAD(&priv->steer[i].steer_entries[j]);
 		}
-		INIT_LIST_HEAD(&priv->steer[i].high_prios);
-	}
 	return 0;
 }
 
@@ -1825,7 +1825,7 @@ slave_start:
 		goto err_master_mfunc;
 
 	priv->msix_ctl.pool_bm = 0;
-	spin_lock_init(&priv->msix_ctl.pool_lock);
+	mutex_init(&priv->msix_ctl.pool_lock);
 
 	mlx4_enable_msi_x(dev);
 	if ((mlx4_is_mfunc(dev)) &&
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index ca574d8..4799e82 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -562,14 +562,14 @@ out_mutex:
  */
 static int find_entry(struct mlx4_dev *dev, u8 port,
 		      u8 *gid, enum mlx4_protocol prot,
-		      enum mlx4_steer_type steer,
 		      struct mlx4_cmd_mailbox *mgm_mailbox,
-		      u16 *hash, int *prev, int *index)
+		      int *prev, int *index)
 {
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_mgm *mgm = mgm_mailbox->buf;
 	u8 *mgid;
 	int err;
+	u16 hash;
 	u8 op_mod = (prot == MLX4_PROT_ETH) ?
 		!!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER) : 0;
 
@@ -580,15 +580,15 @@ static int find_entry(struct mlx4_dev *dev, u8 port,
 
 	memcpy(mgid, gid, 16);
 
-	err = mlx4_GID_HASH(dev, mailbox, hash, op_mod);
+	err = mlx4_GID_HASH(dev, mailbox, &hash, op_mod);
 	mlx4_free_cmd_mailbox(dev, mailbox);
 	if (err)
 		return err;
 
 	if (0)
-		mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, *hash);
+		mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, hash);
 
-	*index = *hash;
+	*index = hash;
 	*prev  = -1;
 
 	do {
@@ -597,7 +597,7 @@ static int find_entry(struct mlx4_dev *dev, u8 port,
 			return err;
 
 		if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
-			if (*index != *hash) {
+			if (*index != hash) {
 				mlx4_err(dev, "Found zero MGID in AMGM.\n");
 				err = -EINVAL;
 			}
@@ -624,7 +624,6 @@ int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_mgm *mgm;
 	u32 members_count;
-	u16 hash;
 	int index, prev;
 	int link = 0;
 	int i;
@@ -638,8 +637,8 @@ int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 	mgm = mailbox->buf;
 
 	mutex_lock(&priv->mcg_table.mutex);
-	err = find_entry(dev, port, gid, prot, steer,
-			 mailbox, &hash, &prev, &index);
+	err = find_entry(dev, port, gid, prot,
+			 mailbox, &prev, &index);
 	if (err)
 		goto out;
 
@@ -733,7 +732,6 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 	struct mlx4_cmd_mailbox *mailbox;
 	struct mlx4_mgm *mgm;
 	u32 members_count;
-	u16 hash;
 	int prev, index;
 	int i, loc;
 	int err;
@@ -747,8 +745,8 @@ int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 
 	mutex_lock(&priv->mcg_table.mutex);
 
-	err = find_entry(dev, port, gid, prot, steer,
-			 mailbox, &hash, &prev, &index);
+	err = find_entry(dev, port, gid, prot,
+			 mailbox, &prev, &index);
 	if (err)
 		goto out;
 
@@ -872,44 +870,36 @@ static int mlx4_QP_ATTACH(struct mlx4_dev *dev, struct mlx4_qp *qp,
 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 			  int block_mcast_loopback, enum mlx4_protocol prot)
 {
-	enum mlx4_steer_type steer;
-
-	steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER;
-
 	if (prot == MLX4_PROT_ETH &&
 			!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
 		return 0;
 
 	if (prot == MLX4_PROT_ETH)
-		gid[7] |= (steer << 1);
+		gid[7] |= (MLX4_MC_STEER << 1);
 
 	if (mlx4_is_mfunc(dev))
 		return mlx4_QP_ATTACH(dev, qp, gid, 1,
 					block_mcast_loopback, prot);
 
 	return mlx4_qp_attach_common(dev, qp, gid, block_mcast_loopback,
-					prot, steer);
+					prot, MLX4_MC_STEER);
 }
 EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
 
 int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
 			  enum mlx4_protocol prot)
 {
-	enum mlx4_steer_type steer;
-
-	steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER;
-
 	if (prot == MLX4_PROT_ETH &&
 			!(dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_MC_STEER))
 		return 0;
 
 	if (prot == MLX4_PROT_ETH)
-		gid[7] |= (steer << 1);
+		gid[7] |= (MLX4_MC_STEER << 1);
 
 	if (mlx4_is_mfunc(dev))
 		return mlx4_QP_ATTACH(dev, qp, gid, 0, 0, prot);
 
-	return mlx4_qp_detach_common(dev, qp, gid, prot, steer);
+	return mlx4_qp_detach_common(dev, qp, gid, prot, MLX4_MC_STEER);
 }
 EXPORT_SYMBOL_GPL(mlx4_multicast_detach);
 
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index c92269f..5da51b9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -697,13 +697,12 @@ struct mlx4_sense {
 
 struct mlx4_msix_ctl {
 	u64		pool_bm;
-	spinlock_t	pool_lock;
+	struct mutex	pool_lock;
 };
 
 struct mlx4_steer {
 	struct list_head promisc_qps[MLX4_NUM_STEERS];
 	struct list_head steer_entries[MLX4_NUM_STEERS];
-	struct list_head high_prios;
 };
 
 struct mlx4_priv {
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index f44ae55..575839d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -87,7 +87,6 @@ static int mlx4_uc_steer_add(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn)
 	mac = cpu_to_be64(mac << 16);
 	memcpy(&gid[10], &mac, ETH_ALEN);
 	gid[5] = port;
-	gid[7] = MLX4_UC_STEER << 1;
 
 	err = mlx4_unicast_attach(dev, &qp, gid, 0, MLX4_PROT_ETH);
 	if (err)
@@ -107,7 +106,6 @@ static void mlx4_uc_steer_release(struct mlx4_dev *dev, u8 port,
 	mac = cpu_to_be64(mac << 16);
 	memcpy(&gid[10], &mac, ETH_ALEN);
 	gid[5] = port;
-	gid[7] = MLX4_UC_STEER << 1;
 
 	mlx4_unicast_detach(dev, &qp, gid, MLX4_PROT_ETH);
 }
diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
index ab81c0d..dccae1d 100644
--- a/drivers/net/ethernet/micrel/ks8695net.c
+++ b/drivers/net/ethernet/micrel/ks8695net.c
@@ -278,7 +278,8 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
 
 	for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
 		if (!ksp->rx_buffers[buff_n].skb) {
-			struct sk_buff *skb = dev_alloc_skb(MAX_RXBUF_SIZE);
+			struct sk_buff *skb =
+				netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE);
 			dma_addr_t mapping;
 
 			ksp->rx_buffers[buff_n].skb = skb;
@@ -299,7 +300,6 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
 				break;
 			}
 			ksp->rx_buffers[buff_n].dma_ptr = mapping;
-			skb->dev = ksp->ndev;
 			ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE;
 
 			/* Record this into the DMA ring */
@@ -1362,10 +1362,8 @@ ks8695_probe(struct platform_device *pdev)
 
 	/* Initialise a net_device */
 	ndev = alloc_etherdev(sizeof(struct ks8695_priv));
-	if (!ndev) {
-		dev_err(&pdev->dev, "could not allocate device.\n");
+	if (!ndev)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c
index 0a85690..0686b93 100644
--- a/drivers/net/ethernet/micrel/ks8842.c
+++ b/drivers/net/ethernet/micrel/ks8842.c
@@ -1080,6 +1080,7 @@ static int ks8842_set_mac(struct net_device *netdev, void *p)
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
+	netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(netdev->dev_addr, mac, netdev->addr_len);
 
 	ks8842_write_mac_addr(adapter, mac);
@@ -1211,7 +1212,7 @@ static int __devinit ks8842_probe(struct platform_device *pdev)
 		ks8842_read_mac_addr(adapter, netdev->dev_addr);
 
 		if (!is_valid_ether_addr(netdev->dev_addr))
-			random_ether_addr(netdev->dev_addr);
+			eth_hw_addr_random(netdev);
 	}
 
 	id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index 0c3e400..c722aa6 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -1,4 +1,4 @@
-/* drivers/net/ks8851.c
+/* drivers/net/ethernet/micrel/ks8851.c
  *
  * Copyright 2009 Simtec Electronics
  *	http://www.simtec.co.uk/
@@ -439,13 +439,13 @@ static void ks8851_init_mac(struct ks8851_net *ks)
 				dev->dev_addr);
 	}
 
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 	ks8851_write_mac_addr(dev);
 }
 
 /**
  * ks8851_irq - device interrupt handler
- * @irq: Interrupt number passed from the IRQ hnalder.
+ * @irq: Interrupt number passed from the IRQ handler.
  * @pw: The private word passed to register_irq(), our struct ks8851_net.
  *
  * Disable the interrupt from happening again until we've processed the
@@ -1050,6 +1050,7 @@ static int ks8851_set_mac_address(struct net_device *dev, void *addr)
 	if (!is_valid_ether_addr(sa->sa_data))
 		return -EADDRNOTAVAIL;
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
 	return ks8851_write_mac_addr(dev);
 }
@@ -1419,10 +1420,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)
 	int ret;
 
 	ndev = alloc_etherdev(sizeof(struct ks8851_net));
-	if (!ndev) {
-		dev_err(&spi->dev, "failed to alloc ethernet device\n");
+	if (!ndev)
 		return -ENOMEM;
-	}
 
 	spi->bits_per_word = 8;
 
diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h
index b0fae86..852256e 100644
--- a/drivers/net/ethernet/micrel/ks8851.h
+++ b/drivers/net/ethernet/micrel/ks8851.h
@@ -1,4 +1,4 @@
-/* drivers/net/ks8851.h
+/* drivers/net/ethernet/micrel/ks8851.h
  *
  * Copyright 2009 Simtec Electronics
  *      Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index 231176f..b8104d9 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -1,5 +1,5 @@
 /**
- * drivers/net/ks8851_mll.c
+ * drivers/net/ethernet/micrel/ks8851_mll.c
  * Copyright (c) 2009 Micrel Inc.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -794,7 +794,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
 
 	frame_hdr = ks->frame_head_info;
 	while (ks->frame_cnt--) {
-		skb = dev_alloc_skb(frame_hdr->len + 16);
+		skb = netdev_alloc_skb(netdev, frame_hdr->len + 16);
 		if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) &&
 			(frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
 			skb_reserve(skb, 2);
@@ -837,7 +837,7 @@ static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks)
 
 /**
  * ks_irq - device interrupt handler
- * @irq: Interrupt number passed from the IRQ hnalder.
+ * @irq: Interrupt number passed from the IRQ handler.
  * @pw: The private word passed to register_irq(), our struct ks_net.
  *
  * This is the handler invoked to find out what happened
@@ -1239,6 +1239,7 @@ static int ks_set_mac_address(struct net_device *netdev, void *paddr)
 	struct sockaddr *addr = paddr;
 	u8 *da;
 
+	netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
 	da = (u8 *)netdev->dev_addr;
@@ -1499,10 +1500,8 @@ static int ks_hw_init(struct ks_net *ks)
 	ks->mcast_lst_size = 0;
 
 	ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL);
-	if (!ks->frame_head_info) {
-		pr_err("Error: Fail to allocate frame memory\n");
+	if (!ks->frame_head_info)
 		return false;
-	}
 
 	ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS);
 	return true;
@@ -1545,7 +1544,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
 
 	netdev->irq = platform_get_irq(pdev, 0);
 
-	if (netdev->irq < 0) {
+	if ((int)netdev->irq < 0) {
 		err = netdev->irq;
 		goto err_get_irq;
 	}
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index e52cd31..ef723b1 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -1,5 +1,5 @@
 /**
- * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver
+ * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver
  *
  * Copyright (c) 2009-2010 Micrel, Inc.
  * 	Tristram Ha <Tristram.Ha@micrel.com>
@@ -4863,7 +4863,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
 				memset(&skb->data[skb->len], 0, 50 - skb->len);
 				skb->len = 50;
 			} else {
-				skb = dev_alloc_skb(50);
+				skb = netdev_alloc_skb(dev, 50);
 				if (!skb)
 					return NETDEV_TX_BUSY;
 				memcpy(skb->data, org_skb->data, org_skb->len);
@@ -4885,7 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
 				(ETH_P_IPV6 == htons(skb->protocol)))) {
 			struct sk_buff *org_skb = skb;
 
-			skb = dev_alloc_skb(org_skb->len);
+			skb = netdev_alloc_skb(dev, org_skb->len);
 			if (!skb) {
 				rc = NETDEV_TX_BUSY;
 				goto unlock;
@@ -5019,7 +5019,7 @@ static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw,
 
 	do {
 		/* skb->data != skb->head */
-		skb = dev_alloc_skb(packet_len + 2);
+		skb = netdev_alloc_skb(dev, packet_len + 2);
 		if (!skb) {
 			dev->stats.rx_dropped++;
 			return -ENOMEM;
diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c
index 50055e0..6118bda 100644
--- a/drivers/net/ethernet/microchip/enc28j60.c
+++ b/drivers/net/ethernet/microchip/enc28j60.c
@@ -527,6 +527,7 @@ static int enc28j60_set_mac_address(struct net_device *dev, void *addr)
 	if (!is_valid_ether_addr(address->sa_data))
 		return -EADDRNOTAVAIL;
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
 	return enc28j60_set_hw_macaddr(dev);
 }
@@ -954,14 +955,13 @@ static void enc28j60_hw_rx(struct net_device *ndev)
 		if (len > MAX_FRAMELEN)
 			ndev->stats.rx_over_errors++;
 	} else {
-		skb = dev_alloc_skb(len + NET_IP_ALIGN);
+		skb = netdev_alloc_skb(ndev, len + NET_IP_ALIGN);
 		if (!skb) {
 			if (netif_msg_rx_err(priv))
 				dev_err(&ndev->dev,
 					"out of memory for Rx'd frame\n");
 			ndev->stats.rx_dropped++;
 		} else {
-			skb->dev = ndev;
 			skb_reserve(skb, NET_IP_ALIGN);
 			/* copy the packet from the receive buffer */
 			enc28j60_mem_read(priv,
@@ -1553,9 +1553,6 @@ static int __devinit enc28j60_probe(struct spi_device *spi)
 
 	dev = alloc_etherdev(sizeof(struct enc28j60_net));
 	if (!dev) {
-		if (netif_msg_drv(&debug))
-			dev_err(&spi->dev, DRV_NAME
-				": unable to alloc new ethernet\n");
 		ret = -ENOMEM;
 		goto error_alloc;
 	}
@@ -1579,7 +1576,7 @@ static int __devinit enc28j60_probe(struct spi_device *spi)
 		ret = -EIO;
 		goto error_irq;
 	}
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 	enc28j60_set_hw_macaddr(dev);
 
 	/* Board setup must set the relevant edge trigger type;
diff --git a/drivers/net/ethernet/mipsnet.c b/drivers/net/ethernet/mipsnet.c
index d05b0c9..db5285b 100644
--- a/drivers/net/ethernet/mipsnet.c
+++ b/drivers/net/ethernet/mipsnet.c
@@ -152,7 +152,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t len)
 	if (!len)
 		return len;
 
-	skb = dev_alloc_skb(len + NET_IP_ALIGN);
+	skb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
 	if (!skb) {
 		dev->stats.rx_dropped++;
 		return -ENOMEM;
@@ -281,7 +281,7 @@ static int __devinit mipsnet_probe(struct platform_device *dev)
 	 * Lacking any better mechanism to allocate a MAC address we use a
 	 * random one ...
 	 */
-	random_ether_addr(netdev->dev_addr);
+	eth_hw_addr_random(netdev);
 
 	err = register_netdev(netdev);
 	if (err) {
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 20b72ec..27273ae 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -3910,10 +3910,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	static int board_number;
 
 	netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES);
-	if (netdev == NULL) {
-		dev_err(dev, "Could not allocate ethernet device\n");
+	if (netdev == NULL)
 		return -ENOMEM;
-	}
 
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 
diff --git a/drivers/net/ethernet/natsemi/ibmlana.c b/drivers/net/ethernet/natsemi/ibmlana.c
index 999407f..3f94ddb 100644
--- a/drivers/net/ethernet/natsemi/ibmlana.c
+++ b/drivers/net/ethernet/natsemi/ibmlana.c
@@ -589,7 +589,7 @@ static void irqrx_handler(struct net_device *dev)
 
 			/* fetch buffer */
 
-			skb = dev_alloc_skb(rda.length + 2);
+			skb = netdev_alloc_skb(dev, rda.length + 2);
 			if (skb == NULL)
 				dev->stats.rx_dropped++;
 			else {
diff --git a/drivers/net/ethernet/natsemi/macsonic.c b/drivers/net/ethernet/natsemi/macsonic.c
index f1b8556..e640e23 100644
--- a/drivers/net/ethernet/natsemi/macsonic.c
+++ b/drivers/net/ethernet/natsemi/macsonic.c
@@ -307,7 +307,7 @@ static void __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev)
 
 	printk(KERN_WARNING "macsonic: MAC address in CAM entry 15 "
 	                    "seems invalid, will use a random MAC\n");
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 }
 
 static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index ac7b16b..d38e48d 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -1934,11 +1934,10 @@ static void refill_rx(struct net_device *dev)
 		int entry = np->dirty_rx % RX_RING_SIZE;
 		if (np->rx_skbuff[entry] == NULL) {
 			unsigned int buflen = np->rx_buf_sz+NATSEMI_PADDING;
-			skb = dev_alloc_skb(buflen);
+			skb = netdev_alloc_skb(dev, buflen);
 			np->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break; /* Better luck next round. */
-			skb->dev = dev; /* Mark as being used by this device. */
 			np->rx_dma[entry] = pci_map_single(np->pci_dev,
 				skb->data, buflen, PCI_DMA_FROMDEVICE);
 			np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
@@ -2344,7 +2343,7 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do)
 			/* Check if the packet is long enough to accept
 			 * without copying to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + RX_OFFSET)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + RX_OFFSET)) != NULL) {
 				/* 16 byte align the IP header */
 				skb_reserve(skb, RX_OFFSET);
 				pci_dma_sync_single_for_cpu(np->pci_dev,
diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
index 26e25d7..46795e4 100644
--- a/drivers/net/ethernet/natsemi/sonic.c
+++ b/drivers/net/ethernet/natsemi/sonic.c
@@ -51,7 +51,7 @@ static int sonic_open(struct net_device *dev)
 		printk("sonic_open: initializing sonic driver.\n");
 
 	for (i = 0; i < SONIC_NUM_RRS; i++) {
-		struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2);
+		struct sk_buff *skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2);
 		if (skb == NULL) {
 			while(i > 0) { /* free any that were allocated successfully */
 				i--;
@@ -422,7 +422,7 @@ static void sonic_rx(struct net_device *dev)
 		status = sonic_rda_get(dev, entry, SONIC_RD_STATUS);
 		if (status & SONIC_RCR_PRX) {
 			/* Malloc up new buffer. */
-			new_skb = dev_alloc_skb(SONIC_RBSIZE + 2);
+			new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2);
 			if (new_skb == NULL) {
 				printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index 97f63e1..44a6065 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -2524,7 +2524,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 			size = ring->mtu + ALIGN_SIZE + BUF0_LEN + 4;
 
 		/* allocate skb */
-		skb = dev_alloc_skb(size);
+		skb = netdev_alloc_skb(nic->dev, size);
 		if (!skb) {
 			DBG_PRINT(INFO_DBG, "%s: Could not allocate skb\n",
 				  ring->dev->name);
@@ -6820,7 +6820,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 			 */
 			rxdp1->Buffer0_ptr = *temp0;
 		} else {
-			*skb = dev_alloc_skb(size);
+			*skb = netdev_alloc_skb(dev, size);
 			if (!(*skb)) {
 				DBG_PRINT(INFO_DBG,
 					  "%s: Out of memory to allocate %s\n",
@@ -6849,7 +6849,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 			rxdp3->Buffer0_ptr = *temp0;
 			rxdp3->Buffer1_ptr = *temp1;
 		} else {
-			*skb = dev_alloc_skb(size);
+			*skb = netdev_alloc_skb(dev, size);
 			if (!(*skb)) {
 				DBG_PRINT(INFO_DBG,
 					  "%s: Out of memory to allocate %s\n",
@@ -7760,7 +7760,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	else
 		dev = alloc_etherdev(sizeof(struct s2io_nic));
 	if (dev == NULL) {
-		DBG_PRINT(ERR_DBG, "Device allocation failed\n");
 		pci_disable_device(pdev);
 		pci_release_regions(pdev);
 		return -ENODEV;
diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c
index 8d288af..9d11ab7 100644
--- a/drivers/net/ethernet/netx-eth.c
+++ b/drivers/net/ethernet/netx-eth.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/netx-eth.c
+ * drivers/net/ethernet/netx-eth.c
  *
  * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
  *
@@ -150,7 +150,7 @@ static void netx_eth_receive(struct net_device *ndev)
 	seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT;
 	len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT;
 
-	skb = dev_alloc_skb(len);
+	skb = netdev_alloc_skb(ndev, len);
 	if (unlikely(skb == NULL)) {
 		printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
 			ndev->name);
@@ -383,7 +383,6 @@ static int netx_eth_drv_probe(struct platform_device *pdev)
 
 	ndev = alloc_etherdev(sizeof (struct netx_eth_priv));
 	if (!ndev) {
-		printk("%s: could not allocate device.\n", CARDNAME);
 		ret = -ENOMEM;
 		goto exit;
 	}
diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c
index b75a049..6893a65 100644
--- a/drivers/net/ethernet/nuvoton/w90p910_ether.c
+++ b/drivers/net/ethernet/nuvoton/w90p910_ether.c
@@ -735,7 +735,7 @@ static void netdev_rx(struct net_device *dev)
 
 		if (status & RXDS_RXGD) {
 			data = ether->rdesc->recv_buf[ether->cur_rx];
-			skb = dev_alloc_skb(length+2);
+			skb = netdev_alloc_skb(dev, length + 2);
 			if (!skb) {
 				dev_err(&pdev->dev, "get skb buffer error\n");
 				ether->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index 4c4e7f4..8561dd2 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -1815,7 +1815,7 @@ static int nv_alloc_rx(struct net_device *dev)
 		less_rx = np->last_rx.orig;
 
 	while (np->put_rx.orig != less_rx) {
-		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
+		struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz + NV_RX_ALLOC_PAD);
 		if (skb) {
 			np->put_rx_ctx->skb = skb;
 			np->put_rx_ctx->dma = pci_map_single(np->pci_dev,
@@ -1850,7 +1850,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
 		less_rx = np->last_rx.ex;
 
 	while (np->put_rx.ex != less_rx) {
-		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
+		struct sk_buff *skb = netdev_alloc_skb(dev, np->rx_buf_sz + NV_RX_ALLOC_PAD);
 		if (skb) {
 			np->put_rx_ctx->skb = skb;
 			np->put_rx_ctx->dma = pci_map_single(np->pci_dev,
@@ -3022,6 +3022,7 @@ static int nv_set_mac_address(struct net_device *dev, void *addr)
 
 	/* synchronized against open : rtnl_lock() held by caller */
 	memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN);
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	if (netif_running(dev)) {
 		netif_tx_lock_bh(dev);
@@ -4993,9 +4994,9 @@ static int nv_loopback_test(struct net_device *dev)
 
 	/* setup packet for tx */
 	pkt_len = ETH_DATA_LEN;
-	tx_skb = dev_alloc_skb(pkt_len);
+	tx_skb = netdev_alloc_skb(dev, pkt_len);
 	if (!tx_skb) {
-		netdev_err(dev, "dev_alloc_skb() failed during loopback test\n");
+		netdev_err(dev, "netdev_alloc_skb() failed during loopback test\n");
 		ret = 0;
 		goto out;
 	}
@@ -5741,7 +5742,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 		dev_err(&pci_dev->dev,
 			"Invalid MAC address detected: %pM - Please complain to your hardware vendor.\n",
 			dev->dev_addr);
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 		dev_err(&pci_dev->dev,
 			"Using random MAC address: %pM\n", dev->dev_addr);
 	}
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 3ead111..69a6654 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -1224,7 +1224,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
 
 	/* When request status is Receive interruption */
 	if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT)) ||
-	    (adapter->rx_stop_flag == true)) {
+	    (adapter->rx_stop_flag)) {
 		if (likely(napi_schedule_prep(&adapter->napi))) {
 			/* Enable only Rx Descriptor empty */
 			atomic_inc(&adapter->irq_sem);
@@ -1587,10 +1587,8 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter,
 
 	size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count;
 	tx_ring->buffer_info = vzalloc(size);
-	if (!tx_ring->buffer_info) {
-		pr_err("Unable to allocate memory for the buffer information\n");
+	if (!tx_ring->buffer_info)
 		return -ENOMEM;
-	}
 
 	tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc);
 
@@ -1636,10 +1634,9 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter,
 
 	size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count;
 	rx_ring->buffer_info = vzalloc(size);
-	if (!rx_ring->buffer_info) {
-		pr_err("Unable to allocate memory for the receive descriptor ring\n");
+	if (!rx_ring->buffer_info)
 		return -ENOMEM;
-	}
+
 	rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc);
 	rx_ring->desc =	dma_alloc_coherent(&pdev->dev, rx_ring->size,
 					   &rx_ring->dma, GFP_KERNEL);
@@ -2422,8 +2419,6 @@ static int pch_gbe_probe(struct pci_dev *pdev,
 	netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter));
 	if (!netdev) {
 		ret = -ENOMEM;
-		dev_err(&pdev->dev,
-			"ERR: Can't allocate and set up an Ethernet device\n");
 		goto err_release_pci;
 	}
 	SET_NETDEV_DEV(netdev, &pdev->dev);
diff --git a/drivers/net/ethernet/packetengines/hamachi.c b/drivers/net/ethernet/packetengines/hamachi.c
index 3458df3..0d29f5f 100644
--- a/drivers/net/ethernet/packetengines/hamachi.c
+++ b/drivers/net/ethernet/packetengines/hamachi.c
@@ -1188,11 +1188,10 @@ static void hamachi_init_ring(struct net_device *dev)
 	}
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2);
+		struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz + 2);
 		hmp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
-		skb->dev = dev;         /* Mark as being used by this device. */
 		skb_reserve(skb, 2); /* 16 byte align the IP header. */
                 hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
 			skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
@@ -1488,7 +1487,7 @@ static int hamachi_rx(struct net_device *dev)
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 #ifdef RX_CHECKSUM
 				printk(KERN_ERR "%s: rx_copybreak non-zero "
 				  "not good with RX_CHECKSUM\n", dev->name);
@@ -1591,12 +1590,11 @@ static int hamachi_rx(struct net_device *dev)
 		entry = hmp->dirty_rx % RX_RING_SIZE;
 		desc = &(hmp->rx_ring[entry]);
 		if (hmp->rx_skbuff[entry] == NULL) {
-			struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2);
+			struct sk_buff *skb = netdev_alloc_skb(dev, hmp->rx_buf_sz + 2);
 
 			hmp->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break;		/* Better luck next round. */
-			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
                 	desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
 				skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c
index db44e9a..7757b80 100644
--- a/drivers/net/ethernet/packetengines/yellowfin.c
+++ b/drivers/net/ethernet/packetengines/yellowfin.c
@@ -397,10 +397,9 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev,
 	if (i) return i;
 
 	dev = alloc_etherdev(sizeof(*np));
-	if (!dev) {
-		pr_err("cannot allocate ethernet device\n");
+	if (!dev)
 		return -ENOMEM;
-	}
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	np = netdev_priv(dev);
@@ -744,11 +743,10 @@ static int yellowfin_init_ring(struct net_device *dev)
 	}
 
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2);
+		struct sk_buff *skb = netdev_alloc_skb(dev, yp->rx_buf_sz + 2);
 		yp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
-		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
 			skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
@@ -1134,7 +1132,7 @@ static int yellowfin_rx(struct net_device *dev)
 					PCI_DMA_FROMDEVICE);
 				yp->rx_skbuff[entry] = NULL;
 			} else {
-				skb = dev_alloc_skb(pkt_len + 2);
+				skb = netdev_alloc_skb(dev, pkt_len + 2);
 				if (skb == NULL)
 					break;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
@@ -1157,11 +1155,10 @@ static int yellowfin_rx(struct net_device *dev)
 	for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) {
 		entry = yp->dirty_rx % RX_RING_SIZE;
 		if (yp->rx_skbuff[entry] == NULL) {
-			struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2);
+			struct sk_buff *skb = netdev_alloc_skb(dev, yp->rx_buf_sz + 2);
 			if (skb == NULL)
 				break;				/* Better luck next round. */
 			yp->rx_skbuff[entry] = skb;
-			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
 				skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c
index 49b549f..667498e 100644
--- a/drivers/net/ethernet/pasemi/pasemi_mac.c
+++ b/drivers/net/ethernet/pasemi/pasemi_mac.c
@@ -643,7 +643,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev,
 		/* Entry in use? */
 		WARN_ON(*buff);
 
-		skb = dev_alloc_skb(mac->bufsz);
+		skb = netdev_alloc_skb(dev, mac->bufsz);
 		skb_reserve(skb, LOCAL_SKB_ALIGN);
 
 		if (unlikely(!skb))
@@ -1740,8 +1740,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	dev = alloc_etherdev(sizeof(struct pasemi_mac));
 	if (dev == NULL) {
-		dev_err(&pdev->dev,
-			"pasemi_mac: Could not allocate ethernet device.\n");
 		err = -ENOMEM;
 		goto out_disable_device;
 	}
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
index a876dff..2eeac32 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 77
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.77"
+#define _NETXEN_NIC_LINUX_SUBVERSION 78
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.78"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
@@ -686,6 +686,18 @@ struct netxen_recv_context {
 	dma_addr_t phys_addr;
 };
 
+struct _cdrp_cmd {
+	u32 cmd;
+	u32 arg1;
+	u32 arg2;
+	u32 arg3;
+};
+
+struct netxen_cmd_args {
+	struct _cdrp_cmd req;
+	struct _cdrp_cmd rsp;
+};
+
 /* New HW context creation */
 
 #define NX_OS_CRB_RETRY_COUNT	4000
@@ -1142,6 +1154,7 @@ typedef struct {
 #define NETXEN_NIC_LRO_DISABLED		0x00
 #define NETXEN_NIC_BRIDGE_ENABLED       0X10
 #define NETXEN_NIC_DIAG_ENABLED		0x20
+#define NETXEN_FW_RESET_OWNER           0x40
 #define NETXEN_IS_MSI_FAMILY(adapter) \
 	((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
 
@@ -1159,6 +1172,419 @@ typedef struct {
 #define __NX_DEV_UP			1
 #define __NX_RESETTING			2
 
+/* Mini Coredump FW supported version */
+#define NX_MD_SUPPORT_MAJOR		4
+#define NX_MD_SUPPORT_MINOR		0
+#define NX_MD_SUPPORT_SUBVERSION	579
+
+#define LSW(x)  ((uint16_t)(x))
+#define LSD(x)  ((uint32_t)((uint64_t)(x)))
+#define MSD(x)  ((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
+
+/* Mini Coredump mask level */
+#define	NX_DUMP_MASK_MIN	0x03
+#define	NX_DUMP_MASK_DEF	0x1f
+#define	NX_DUMP_MASK_MAX	0xff
+
+/* Mini Coredump CDRP commands */
+#define NX_CDRP_CMD_TEMP_SIZE           0x0000002f
+#define NX_CDRP_CMD_GET_TEMP_HDR        0x00000030
+
+
+#define NX_DUMP_STATE_ARRAY_LEN		16
+#define NX_DUMP_CAP_SIZE_ARRAY_LEN	8
+
+/* Mini Coredump sysfs entries flags*/
+#define NX_FORCE_FW_DUMP_KEY		0xdeadfeed
+#define NX_ENABLE_FW_DUMP               0xaddfeed
+#define NX_DISABLE_FW_DUMP              0xbadfeed
+#define NX_FORCE_FW_RESET               0xdeaddead
+
+
+/* Flash read/write address */
+#define NX_FW_DUMP_REG1         0x00130060
+#define NX_FW_DUMP_REG2         0x001e0000
+#define NX_FLASH_SEM2_LK        0x0013C010
+#define NX_FLASH_SEM2_ULK       0x0013C014
+#define NX_FLASH_LOCK_ID        0x001B2100
+#define FLASH_ROM_WINDOW        0x42110030
+#define FLASH_ROM_DATA          0x42150000
+
+/* Mini Coredump register read/write routine */
+#define NX_RD_DUMP_REG(addr, bar0, data) do {                   \
+	writel((addr & 0xFFFF0000), (void __iomem *) (bar0 +            \
+		NX_FW_DUMP_REG1));                                      \
+	readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1));               \
+	*data = readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 +        \
+		LSW(addr)));                                            \
+} while (0)
+
+#define NX_WR_DUMP_REG(addr, bar0, data) do {                   \
+	writel((addr & 0xFFFF0000), (void __iomem *) (bar0 +            \
+		NX_FW_DUMP_REG1));                                      \
+	readl((void __iomem *) (bar0 + NX_FW_DUMP_REG1));                \
+	writel(data, (void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr)));\
+	readl((void __iomem *) (bar0 + NX_FW_DUMP_REG2 + LSW(addr)));  \
+} while (0)
+
+
+/*
+Entry Type Defines
+*/
+
+#define RDNOP	0
+#define RDCRB	1
+#define RDMUX	2
+#define QUEUE	3
+#define BOARD	4
+#define RDSRE	5
+#define RDOCM	6
+#define PREGS	7
+#define L1DTG	8
+#define L1ITG	9
+#define CACHE	10
+
+#define L1DAT	11
+#define L1INS	12
+#define RDSTK	13
+#define RDCON	14
+
+#define L2DTG	21
+#define L2ITG	22
+#define L2DAT	23
+#define L2INS	24
+#define RDOC3	25
+
+#define MEMBK	32
+
+#define RDROM	71
+#define RDMEM	72
+#define RDMN	73
+
+#define INFOR	81
+#define CNTRL	98
+
+#define TLHDR	99
+#define RDEND	255
+
+#define PRIMQ	103
+#define SQG2Q	104
+#define SQG3Q	105
+
+/*
+* Opcodes for Control Entries.
+* These Flags are bit fields.
+*/
+#define NX_DUMP_WCRB		0x01
+#define NX_DUMP_RWCRB		0x02
+#define NX_DUMP_ANDCRB		0x04
+#define NX_DUMP_ORCRB		0x08
+#define NX_DUMP_POLLCRB		0x10
+#define NX_DUMP_RD_SAVE		0x20
+#define NX_DUMP_WRT_SAVED	0x40
+#define NX_DUMP_MOD_SAVE_ST	0x80
+
+/* Driver Flags */
+#define NX_DUMP_SKIP		0x80	/*  driver skipped this entry  */
+#define NX_DUMP_SIZE_ERR 0x40	/*entry size vs capture size mismatch*/
+
+#define NX_PCI_READ_32(ADDR)			readl((ADDR))
+#define NX_PCI_WRITE_32(DATA, ADDR)	writel(DATA, (ADDR))
+
+
+
+struct netxen_minidump {
+	u32 pos;			/* position in the dump buffer */
+	u8  fw_supports_md;		/* FW supports Mini cordump */
+	u8  has_valid_dump;		/* indicates valid dump */
+	u8  md_capture_mask;		/* driver capture mask */
+	u8  md_enabled;			/* Turn Mini Coredump on/off */
+	u32 md_dump_size;		/* Total FW Mini Coredump size */
+	u32 md_capture_size;		/* FW dump capture size */
+	u32 md_template_size;		/* FW template size */
+	u32 md_template_ver;		/* FW template version */
+	u64 md_timestamp;		/* FW Mini dump timestamp */
+	void *md_template;		/* FW template will be stored */
+	void *md_capture_buff;		/* FW dump will be stored */
+};
+
+
+
+struct netxen_minidump_template_hdr {
+	u32 entry_type;
+	u32 first_entry_offset;
+	u32 size_of_template;
+	u32 capture_mask;
+	u32 num_of_entries;
+	u32 version;
+	u32 driver_timestamp;
+	u32 checksum;
+	u32 driver_capture_mask;
+	u32 driver_info_word2;
+	u32 driver_info_word3;
+	u32 driver_info_word4;
+	u32 saved_state_array[NX_DUMP_STATE_ARRAY_LEN];
+	u32 capture_size_array[NX_DUMP_CAP_SIZE_ARRAY_LEN];
+	u32 rsvd[0];
+};
+
+/* Common Entry Header:  Common to All Entry Types */
+/*
+ * Driver Code is for driver to write some info about the entry.
+ * Currently not used.
+ */
+
+struct netxen_common_entry_hdr {
+	u32 entry_type;
+	u32 entry_size;
+	u32 entry_capture_size;
+	union {
+		struct {
+			u8 entry_capture_mask;
+			u8 entry_code;
+			u8 driver_code;
+			u8 driver_flags;
+		};
+		u32 entry_ctrl_word;
+	};
+};
+
+
+/* Generic Entry Including Header */
+struct netxen_minidump_entry {
+	struct netxen_common_entry_hdr hdr;
+	u32 entry_data00;
+	u32 entry_data01;
+	u32 entry_data02;
+	u32 entry_data03;
+	u32 entry_data04;
+	u32 entry_data05;
+	u32 entry_data06;
+	u32 entry_data07;
+};
+
+/* Read ROM Header */
+struct netxen_minidump_entry_rdrom {
+	struct netxen_common_entry_hdr h;
+	union {
+		struct {
+			u32 select_addr_reg;
+		};
+		u32 rsvd_0;
+	};
+	union {
+		struct {
+			u8 addr_stride;
+			u8 addr_cnt;
+			u16 data_size;
+		};
+		u32 rsvd_1;
+	};
+	union {
+		struct {
+			u32 op_count;
+		};
+		u32 rsvd_2;
+	};
+	union {
+		struct {
+			u32 read_addr_reg;
+		};
+		u32 rsvd_3;
+	};
+	union {
+		struct {
+			u32 write_mask;
+		};
+		u32 rsvd_4;
+	};
+	union {
+		struct {
+			u32 read_mask;
+		};
+		u32 rsvd_5;
+	};
+	u32 read_addr;
+	u32 read_data_size;
+};
+
+
+/* Read CRB and Control Entry Header */
+struct netxen_minidump_entry_crb {
+	struct netxen_common_entry_hdr h;
+	u32 addr;
+	union {
+		struct {
+			u8 addr_stride;
+			u8 state_index_a;
+			u16 poll_timeout;
+			};
+		u32 addr_cntrl;
+	};
+	u32 data_size;
+	u32 op_count;
+	union {
+		struct {
+			u8 opcode;
+			u8 state_index_v;
+			u8 shl;
+			u8 shr;
+			};
+		u32 control_value;
+	};
+	u32 value_1;
+	u32 value_2;
+	u32 value_3;
+};
+
+/* Read Memory and MN Header */
+struct netxen_minidump_entry_rdmem {
+	struct netxen_common_entry_hdr h;
+	union {
+		struct {
+			u32 select_addr_reg;
+		};
+		u32 rsvd_0;
+	};
+	union {
+		struct {
+			u8 addr_stride;
+			u8 addr_cnt;
+			u16 data_size;
+		};
+		u32 rsvd_1;
+	};
+	union {
+		struct {
+			u32 op_count;
+		};
+		u32 rsvd_2;
+	};
+	union {
+		struct {
+			u32 read_addr_reg;
+		};
+		u32 rsvd_3;
+	};
+	union {
+		struct {
+			u32 cntrl_addr_reg;
+		};
+		u32 rsvd_4;
+	};
+	union {
+		struct {
+			u8 wr_byte0;
+			u8 wr_byte1;
+			u8 poll_mask;
+			u8 poll_cnt;
+		};
+		u32 rsvd_5;
+	};
+	u32 read_addr;
+	u32 read_data_size;
+};
+
+/* Read Cache L1 and L2 Header */
+struct netxen_minidump_entry_cache {
+	struct netxen_common_entry_hdr h;
+	u32 tag_reg_addr;
+	union {
+		struct {
+			u16 tag_value_stride;
+			u16 init_tag_value;
+		};
+		u32 select_addr_cntrl;
+	};
+	u32 data_size;
+	u32 op_count;
+	u32 control_addr;
+	union {
+		struct {
+			u16 write_value;
+			u8 poll_mask;
+			u8 poll_wait;
+		};
+		u32 control_value;
+	};
+	u32 read_addr;
+	union {
+		struct {
+			u8 read_addr_stride;
+			u8 read_addr_cnt;
+			u16 rsvd_1;
+		};
+		u32 read_addr_cntrl;
+	};
+};
+
+/* Read OCM Header */
+struct netxen_minidump_entry_rdocm {
+	struct netxen_common_entry_hdr h;
+	u32 rsvd_0;
+	union {
+		struct {
+			u32 rsvd_1;
+		};
+		u32 select_addr_cntrl;
+	};
+	u32 data_size;
+	u32 op_count;
+	u32 rsvd_2;
+	u32 rsvd_3;
+	u32 read_addr;
+	union {
+		struct {
+			u32 read_addr_stride;
+		};
+		u32 read_addr_cntrl;
+	};
+};
+
+/* Read MUX Header */
+struct netxen_minidump_entry_mux {
+	struct netxen_common_entry_hdr h;
+	u32 select_addr;
+	union {
+		struct {
+			u32 rsvd_0;
+		};
+		u32 select_addr_cntrl;
+	};
+	u32 data_size;
+	u32 op_count;
+	u32 select_value;
+	u32 select_value_stride;
+	u32 read_addr;
+	u32 rsvd_1;
+};
+
+/* Read Queue Header */
+struct netxen_minidump_entry_queue {
+	struct netxen_common_entry_hdr h;
+	u32 select_addr;
+	union {
+		struct {
+			u16 queue_id_stride;
+			u16 rsvd_0;
+		};
+		u32 select_addr_cntrl;
+	};
+	u32 data_size;
+	u32 op_count;
+	u32 rsvd_1;
+	u32 rsvd_2;
+	u32 read_addr;
+	union {
+		struct {
+			u8 read_addr_stride;
+			u8 read_addr_cnt;
+			u16 rsvd_3;
+		};
+		u32 read_addr_cntrl;
+	};
+};
+
 struct netxen_dummy_dma {
 	void *addr;
 	dma_addr_t phys_addr;
@@ -1263,6 +1689,8 @@ struct netxen_adapter {
 	__le32 file_prd_off;	/*File fw product offset*/
 	u32 fw_version;
 	const struct firmware *fw;
+	struct netxen_minidump mdump;   /* mdump ptr */
+	int fw_mdump_rdy;	/* for mdump ready */
 };
 
 int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val);
@@ -1365,13 +1793,16 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
 int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable);
 int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable);
 int netxen_send_lro_cleanup(struct netxen_adapter *adapter);
-
+int netxen_setup_minidump(struct netxen_adapter *adapter);
+void netxen_dump_fw(struct netxen_adapter *adapter);
 void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
 		struct nx_host_tx_ring *tx_ring);
 
 /* Functions from netxen_nic_main.c */
 int netxen_nic_reset_context(struct netxen_adapter *);
 
+int nx_dev_request_reset(struct netxen_adapter *adapter);
+
 /*
  * NetXen Board information
  */
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
index a925392..f3c0057 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
@@ -48,28 +48,27 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
 }
 
 static u32
-netxen_issue_cmd(struct netxen_adapter *adapter,
-	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd)
+netxen_issue_cmd(struct netxen_adapter *adapter, struct netxen_cmd_args *cmd)
 {
 	u32 rsp;
 	u32 signature = 0;
 	u32 rcode = NX_RCODE_SUCCESS;
 
-	signature = NX_CDRP_SIGNATURE_MAKE(pci_fn, version);
-
+	signature = NX_CDRP_SIGNATURE_MAKE(adapter->ahw.pci_func,
+						NXHAL_VERSION);
 	/* Acquire semaphore before accessing CRB */
 	if (netxen_api_lock(adapter))
 		return NX_RCODE_TIMEOUT;
 
 	NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
 
-	NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
+	NXWR32(adapter, NX_ARG1_CRB_OFFSET, cmd->req.arg1);
 
-	NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
+	NXWR32(adapter, NX_ARG2_CRB_OFFSET, cmd->req.arg2);
 
-	NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
+	NXWR32(adapter, NX_ARG3_CRB_OFFSET, cmd->req.arg3);
 
-	NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
+	NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd->req.cmd));
 
 	rsp = netxen_poll_rsp(adapter);
 
@@ -83,28 +82,179 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
 
 		printk(KERN_ERR "%s: failed card response code:0x%x\n",
 				netxen_nic_driver_name, rcode);
+	} else if (rsp == NX_CDRP_RSP_OK) {
+		cmd->rsp.cmd = NX_RCODE_SUCCESS;
+		if (cmd->rsp.arg2)
+			cmd->rsp.arg2 = NXRD32(adapter, NX_ARG2_CRB_OFFSET);
+		if (cmd->rsp.arg3)
+			cmd->rsp.arg3 = NXRD32(adapter, NX_ARG3_CRB_OFFSET);
 	}
 
+	if (cmd->rsp.arg1)
+		cmd->rsp.arg1 = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
 	/* Release semaphore */
 	netxen_api_unlock(adapter);
 
 	return rcode;
 }
 
+static int
+netxen_get_minidump_template_size(struct netxen_adapter *adapter)
+{
+	struct netxen_cmd_args cmd;
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.cmd = NX_CDRP_CMD_TEMP_SIZE;
+	memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd));
+	netxen_issue_cmd(adapter, &cmd);
+	if (cmd.rsp.cmd != NX_RCODE_SUCCESS) {
+		dev_info(&adapter->pdev->dev,
+			"Can't get template size %d\n", cmd.rsp.cmd);
+		return -EIO;
+	}
+	adapter->mdump.md_template_size = cmd.rsp.arg2;
+	adapter->mdump.md_template_ver = cmd.rsp.arg3;
+	return 0;
+}
+
+static int
+netxen_get_minidump_template(struct netxen_adapter *adapter)
+{
+	dma_addr_t md_template_addr;
+	void *addr;
+	u32 size;
+	struct netxen_cmd_args cmd;
+	size = adapter->mdump.md_template_size;
+
+	if (size == 0) {
+		dev_err(&adapter->pdev->dev, "Can not capture Minidump "
+			"template. Invalid template size.\n");
+		return NX_RCODE_INVALID_ARGS;
+	}
+
+	addr = pci_alloc_consistent(adapter->pdev, size, &md_template_addr);
+
+	if (!addr) {
+		dev_err(&adapter->pdev->dev, "Unable to allocate dmable memory for template.\n");
+		return -ENOMEM;
+	}
+
+	memset(addr, 0, size);
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd.rsp, 1, sizeof(struct _cdrp_cmd));
+	cmd.req.cmd = NX_CDRP_CMD_GET_TEMP_HDR;
+	cmd.req.arg1 = LSD(md_template_addr);
+	cmd.req.arg2 = MSD(md_template_addr);
+	cmd.req.arg3 |= size;
+	netxen_issue_cmd(adapter, &cmd);
+
+	if ((cmd.rsp.cmd == NX_RCODE_SUCCESS) && (size == cmd.rsp.arg2)) {
+		memcpy(adapter->mdump.md_template, addr, size);
+	} else {
+		dev_err(&adapter->pdev->dev, "Failed to get minidump template, "
+			"err_code : %d, requested_size : %d, actual_size : %d\n ",
+			cmd.rsp.cmd, size, cmd.rsp.arg2);
+	}
+	pci_free_consistent(adapter->pdev, size, addr, md_template_addr);
+	return 0;
+}
+
+static u32
+netxen_check_template_checksum(struct netxen_adapter *adapter)
+{
+	u64 sum =  0 ;
+	u32 *buff = adapter->mdump.md_template;
+	int count =  adapter->mdump.md_template_size/sizeof(uint32_t) ;
+
+	while (count-- > 0)
+		sum += *buff++ ;
+	while (sum >> 32)
+		sum = (sum & 0xFFFFFFFF) +  (sum >> 32) ;
+
+	return ~sum;
+}
+
+int
+netxen_setup_minidump(struct netxen_adapter *adapter)
+{
+	int err = 0, i;
+	u32 *template, *tmp_buf;
+	struct netxen_minidump_template_hdr *hdr;
+	err = netxen_get_minidump_template_size(adapter);
+	if (err) {
+		adapter->mdump.fw_supports_md = 0;
+		if ((err == NX_RCODE_CMD_INVALID) ||
+			(err == NX_RCODE_CMD_NOT_IMPL)) {
+			dev_info(&adapter->pdev->dev,
+				"Flashed firmware version does not support minidump, "
+				"minimum version required is [ %u.%u.%u ].\n ",
+				NX_MD_SUPPORT_MAJOR, NX_MD_SUPPORT_MINOR,
+				NX_MD_SUPPORT_SUBVERSION);
+		}
+		return err;
+	}
+
+	if (!adapter->mdump.md_template_size) {
+		dev_err(&adapter->pdev->dev, "Error : Invalid template size "
+		",should be non-zero.\n");
+		return -EIO;
+	}
+	adapter->mdump.md_template =
+		kmalloc(adapter->mdump.md_template_size, GFP_KERNEL);
+
+	if (!adapter->mdump.md_template) {
+		dev_err(&adapter->pdev->dev, "Unable to allocate memory "
+			"for minidump template.\n");
+		return -ENOMEM;
+	}
+
+	err = netxen_get_minidump_template(adapter);
+	if (err) {
+		if (err == NX_RCODE_CMD_NOT_IMPL)
+			adapter->mdump.fw_supports_md = 0;
+		goto free_template;
+	}
+
+	if (netxen_check_template_checksum(adapter)) {
+		dev_err(&adapter->pdev->dev, "Minidump template checksum Error\n");
+		err = -EIO;
+		goto free_template;
+	}
+
+	adapter->mdump.md_capture_mask = NX_DUMP_MASK_DEF;
+	tmp_buf = (u32 *) adapter->mdump.md_template;
+	template = (u32 *) adapter->mdump.md_template;
+	for (i = 0; i < adapter->mdump.md_template_size/sizeof(u32); i++)
+		*template++ = __le32_to_cpu(*tmp_buf++);
+	hdr = (struct netxen_minidump_template_hdr *)
+				adapter->mdump.md_template;
+	adapter->mdump.md_capture_buff = NULL;
+	adapter->mdump.fw_supports_md = 1;
+	adapter->mdump.md_enabled = 1;
+
+	return err;
+
+free_template:
+	kfree(adapter->mdump.md_template);
+	adapter->mdump.md_template = NULL;
+	return err;
+}
+
+
 int
 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
 {
 	u32 rcode = NX_RCODE_SUCCESS;
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct netxen_cmd_args cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.cmd = NX_CDRP_CMD_SET_MTU;
+	cmd.req.arg1 = recv_ctx->context_id;
+	cmd.req.arg2 = mtu;
+	cmd.req.arg3 = 0;
 
 	if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
-		rcode = netxen_issue_cmd(adapter,
-				adapter->ahw.pci_func,
-				NXHAL_VERSION,
-				recv_ctx->context_id,
-				mtu,
-				0,
-				NX_CDRP_CMD_SET_MTU);
+		netxen_issue_cmd(adapter, &cmd);
 
 	if (rcode != NX_RCODE_SUCCESS)
 		return -EIO;
@@ -116,15 +266,14 @@ int
 nx_fw_cmd_set_gbe_port(struct netxen_adapter *adapter,
 			u32 speed, u32 duplex, u32 autoneg)
 {
-
-	return netxen_issue_cmd(adapter,
-				adapter->ahw.pci_func,
-				NXHAL_VERSION,
-				speed,
-				duplex,
-				autoneg,
-				NX_CDRP_CMD_CONFIG_GBE_PORT);
-
+	struct netxen_cmd_args cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.cmd = NX_CDRP_CMD_CONFIG_GBE_PORT;
+	cmd.req.arg1 = speed;
+	cmd.req.arg2 = duplex;
+	cmd.req.arg3 = autoneg;
+	return netxen_issue_cmd(adapter, &cmd);
 }
 
 static int
@@ -139,6 +288,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 	nx_cardrsp_sds_ring_t *prsp_sds;
 	struct nx_host_rds_ring *rds_ring;
 	struct nx_host_sds_ring *sds_ring;
+	struct netxen_cmd_args cmd;
 
 	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
 	u64 phys_addr;
@@ -218,13 +368,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 	}
 
 	phys_addr = hostrq_phys_addr;
-	err = netxen_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			NXHAL_VERSION,
-			(u32)(phys_addr >> 32),
-			(u32)(phys_addr & 0xffffffff),
-			rq_size,
-			NX_CDRP_CMD_CREATE_RX_CTX);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.arg1 = (u32)(phys_addr >> 32);
+	cmd.req.arg2 = (u32)(phys_addr & 0xffffffff);
+	cmd.req.arg3 = rq_size;
+	cmd.req.cmd = NX_CDRP_CMD_CREATE_RX_CTX;
+	err = netxen_issue_cmd(adapter, &cmd);
 	if (err) {
 		printk(KERN_WARNING
 			"Failed to create rx ctx in firmware%d\n", err);
@@ -273,15 +422,15 @@ static void
 nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
 {
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct netxen_cmd_args cmd;
 
-	if (netxen_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			NXHAL_VERSION,
-			recv_ctx->context_id,
-			NX_DESTROY_CTX_RESET,
-			0,
-			NX_CDRP_CMD_DESTROY_RX_CTX)) {
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.arg1 = recv_ctx->context_id;
+	cmd.req.arg2 = NX_DESTROY_CTX_RESET;
+	cmd.req.arg3 = 0;
+	cmd.req.cmd = NX_CDRP_CMD_DESTROY_RX_CTX;
 
+	if (netxen_issue_cmd(adapter, &cmd)) {
 		printk(KERN_WARNING
 			"%s: Failed to destroy rx ctx in firmware\n",
 			netxen_nic_driver_name);
@@ -302,6 +451,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 	dma_addr_t	rq_phys_addr, rsp_phys_addr;
 	struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct netxen_cmd_args cmd;
 
 	rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
 	rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -345,13 +495,12 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 	prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
 
 	phys_addr = rq_phys_addr;
-	err = netxen_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			NXHAL_VERSION,
-			(u32)(phys_addr >> 32),
-			((u32)phys_addr & 0xffffffff),
-			rq_size,
-			NX_CDRP_CMD_CREATE_TX_CTX);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.arg1 = (u32)(phys_addr >> 32);
+	cmd.req.arg2 = ((u32)phys_addr & 0xffffffff);
+	cmd.req.arg3 = rq_size;
+	cmd.req.cmd = NX_CDRP_CMD_CREATE_TX_CTX;
+	err = netxen_issue_cmd(adapter, &cmd);
 
 	if (err == NX_RCODE_SUCCESS) {
 		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
@@ -380,14 +529,14 @@ out_free_rq:
 static void
 nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
 {
-	if (netxen_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			NXHAL_VERSION,
-			adapter->tx_context_id,
-			NX_DESTROY_CTX_RESET,
-			0,
-			NX_CDRP_CMD_DESTROY_TX_CTX)) {
-
+	struct netxen_cmd_args cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.arg1 = adapter->tx_context_id;
+	cmd.req.arg2 = NX_DESTROY_CTX_RESET;
+	cmd.req.arg3 = 0;
+	cmd.req.cmd = NX_CDRP_CMD_DESTROY_TX_CTX;
+	if (netxen_issue_cmd(adapter, &cmd)) {
 		printk(KERN_WARNING
 			"%s: Failed to destroy tx ctx in firmware\n",
 			netxen_nic_driver_name);
@@ -398,34 +547,37 @@ int
 nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val)
 {
 	u32 rcode;
-
-	rcode = netxen_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			NXHAL_VERSION,
-			reg,
-			0,
-			0,
-			NX_CDRP_CMD_READ_PHY);
-
+	struct netxen_cmd_args cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.arg1 = reg;
+	cmd.req.arg2 = 0;
+	cmd.req.arg3 = 0;
+	cmd.req.cmd = NX_CDRP_CMD_READ_PHY;
+	cmd.rsp.arg1 = 1;
+	rcode = netxen_issue_cmd(adapter, &cmd);
 	if (rcode != NX_RCODE_SUCCESS)
 		return -EIO;
 
-	return NXRD32(adapter, NX_ARG1_CRB_OFFSET);
+	if (val == NULL)
+		return -EIO;
+
+	*val = cmd.rsp.arg1;
+	return 0;
 }
 
 int
 nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val)
 {
 	u32 rcode;
-
-	rcode = netxen_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			NXHAL_VERSION,
-			reg,
-			val,
-			0,
-			NX_CDRP_CMD_WRITE_PHY);
-
+	struct netxen_cmd_args cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.req.arg1 = reg;
+	cmd.req.arg2 = val;
+	cmd.req.arg3 = 0;
+	cmd.req.cmd = NX_CDRP_CMD_WRITE_PHY;
+	rcode = netxen_issue_cmd(adapter, &cmd);
 	if (rcode != NX_RCODE_SUCCESS)
 		return -EIO;
 
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
index 8a37198..8c39299 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
@@ -248,6 +248,11 @@ skip:
 		}
 	}
 
+	if (!netif_running(dev) || !adapter->ahw.linkup) {
+		ecmd->duplex = DUPLEX_UNKNOWN;
+		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+	}
+
 	return 0;
 }
 
@@ -812,6 +817,107 @@ static int netxen_get_intr_coalesce(struct net_device *netdev,
 	return 0;
 }
 
+static int
+netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
+{
+	struct netxen_adapter *adapter = netdev_priv(netdev);
+	struct netxen_minidump *mdump = &adapter->mdump;
+	if (adapter->fw_mdump_rdy)
+		dump->len = mdump->md_dump_size;
+	else
+		dump->len = 0;
+	dump->flag = mdump->md_capture_mask;
+	dump->version = adapter->fw_version;
+	return 0;
+}
+
+static int
+netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)
+{
+	int ret = 0;
+	struct netxen_adapter *adapter = netdev_priv(netdev);
+	struct netxen_minidump *mdump = &adapter->mdump;
+
+	switch (val->flag) {
+	case NX_FORCE_FW_DUMP_KEY:
+		if (!mdump->md_enabled)
+			mdump->md_enabled = 1;
+		if (adapter->fw_mdump_rdy) {
+			netdev_info(netdev, "Previous dump not cleared, not forcing dump\n");
+			return ret;
+		}
+		netdev_info(netdev, "Forcing a fw dump\n");
+		nx_dev_request_reset(adapter);
+		break;
+	case NX_DISABLE_FW_DUMP:
+		if (mdump->md_enabled) {
+			netdev_info(netdev, "Disabling FW Dump\n");
+			mdump->md_enabled = 0;
+		}
+		break;
+	case NX_ENABLE_FW_DUMP:
+		if (!mdump->md_enabled) {
+			netdev_info(netdev, "Enabling FW dump\n");
+			mdump->md_enabled = 1;
+		}
+		break;
+	case NX_FORCE_FW_RESET:
+		netdev_info(netdev, "Forcing FW reset\n");
+		nx_dev_request_reset(adapter);
+		adapter->flags &= ~NETXEN_FW_RESET_OWNER;
+		break;
+	default:
+		if (val->flag <= NX_DUMP_MASK_MAX &&
+			val->flag >= NX_DUMP_MASK_MIN) {
+			mdump->md_capture_mask = val->flag & 0xff;
+			netdev_info(netdev, "Driver mask changed to: 0x%x\n",
+					mdump->md_capture_mask);
+			break;
+		}
+		netdev_info(netdev,
+			"Invalid dump level: 0x%x\n", val->flag);
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int
+netxen_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
+			void *buffer)
+{
+	int i, copy_sz;
+	u32 *hdr_ptr, *data;
+	struct netxen_adapter *adapter = netdev_priv(netdev);
+	struct netxen_minidump *mdump = &adapter->mdump;
+
+
+	if (!adapter->fw_mdump_rdy) {
+		netdev_info(netdev, "Dump not available\n");
+		return -EINVAL;
+	}
+	/* Copy template header first */
+	copy_sz = mdump->md_template_size;
+	hdr_ptr = (u32 *) mdump->md_template;
+	data = buffer;
+	for (i = 0; i < copy_sz/sizeof(u32); i++)
+		*data++ = cpu_to_le32(*hdr_ptr++);
+
+	/* Copy captured dump data */
+	memcpy(buffer + copy_sz,
+		mdump->md_capture_buff + mdump->md_template_size,
+			mdump->md_capture_size);
+	dump->len = copy_sz + mdump->md_capture_size;
+	dump->flag = mdump->md_capture_mask;
+
+	/* Free dump area once data has been captured */
+	vfree(mdump->md_capture_buff);
+	mdump->md_capture_buff = NULL;
+	adapter->fw_mdump_rdy = 0;
+	netdev_info(netdev, "extracted the fw dump Successfully\n");
+	return 0;
+}
+
 const struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_settings = netxen_nic_get_settings,
 	.set_settings = netxen_nic_set_settings,
@@ -833,4 +939,7 @@ const struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_sset_count = netxen_get_sset_count,
 	.get_coalesce = netxen_get_intr_coalesce,
 	.set_coalesce = netxen_set_intr_coalesce,
+	.get_dump_flag = netxen_get_dump_flag,
+	.get_dump_data = netxen_get_dump_data,
+	.set_dump = netxen_set_dump,
 };
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
index dc1967c..b1a897c 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
@@ -969,6 +969,7 @@ enum {
 #define NX_RCODE_FATAL_ERROR		0x80000000
 #define NX_FWERROR_PEGNUM(code)		((code) & 0xff)
 #define NX_FWERROR_CODE(code)		((code >> 8) & 0xfffff)
+#define NX_FWERROR_PEGSTAT1(code)	((code >> 8) & 0x1fffff)
 
 #define FW_POLL_DELAY			(2 * HZ)
 #define FW_FAIL_THRESH			3
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
index 3f89e57..6f37470 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
@@ -46,7 +46,6 @@ static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
 		void __iomem *addr, u32 data);
 static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
 		void __iomem *addr);
-
 #ifndef readq
 static inline u64 readq(void __iomem *addr)
 {
@@ -1974,3 +1973,631 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter)
 
 	return 0;
 }
+
+static u32 netxen_md_cntrl(struct netxen_adapter *adapter,
+			struct netxen_minidump_template_hdr *template_hdr,
+			struct netxen_minidump_entry_crb *crtEntry)
+{
+	int loop_cnt, i, rv = 0, timeout_flag;
+	u32 op_count, stride;
+	u32 opcode, read_value, addr;
+	unsigned long timeout, timeout_jiffies;
+	addr = crtEntry->addr;
+	op_count = crtEntry->op_count;
+	stride = crtEntry->addr_stride;
+
+	for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
+		for (i = 0; i < sizeof(crtEntry->opcode) * 8; i++) {
+			opcode = (crtEntry->opcode & (0x1 << i));
+			if (opcode) {
+				switch (opcode) {
+				case NX_DUMP_WCRB:
+					NX_WR_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+							crtEntry->value_1);
+					break;
+				case NX_DUMP_RWCRB:
+					NX_RD_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								&read_value);
+					NX_WR_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								read_value);
+					break;
+				case NX_DUMP_ANDCRB:
+					NX_RD_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								&read_value);
+					read_value &= crtEntry->value_2;
+					NX_WR_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								read_value);
+					break;
+				case NX_DUMP_ORCRB:
+					NX_RD_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								&read_value);
+					read_value |= crtEntry->value_3;
+					NX_WR_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								read_value);
+					break;
+				case NX_DUMP_POLLCRB:
+					timeout = crtEntry->poll_timeout;
+					NX_RD_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								&read_value);
+					timeout_jiffies =
+					msecs_to_jiffies(timeout) + jiffies;
+					for (timeout_flag = 0;
+						!timeout_flag
+					&& ((read_value & crtEntry->value_2)
+					!= crtEntry->value_1);) {
+						if (time_after(jiffies,
+							timeout_jiffies))
+							timeout_flag = 1;
+					NX_RD_DUMP_REG(addr,
+							adapter->ahw.pci_base0,
+								&read_value);
+					}
+
+					if (timeout_flag) {
+						dev_err(&adapter->pdev->dev, "%s : "
+							"Timeout in poll_crb control operation.\n"
+								, __func__);
+						return -1;
+					}
+					break;
+				case NX_DUMP_RD_SAVE:
+					/* Decide which address to use */
+					if (crtEntry->state_index_a)
+						addr =
+						template_hdr->saved_state_array
+						[crtEntry->state_index_a];
+					NX_RD_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								&read_value);
+					template_hdr->saved_state_array
+					[crtEntry->state_index_v]
+						= read_value;
+					break;
+				case NX_DUMP_WRT_SAVED:
+					/* Decide which value to use */
+					if (crtEntry->state_index_v)
+						read_value =
+						template_hdr->saved_state_array
+						[crtEntry->state_index_v];
+					else
+						read_value = crtEntry->value_1;
+
+					/* Decide which address to use */
+					if (crtEntry->state_index_a)
+						addr =
+						template_hdr->saved_state_array
+						[crtEntry->state_index_a];
+
+					NX_WR_DUMP_REG(addr,
+						adapter->ahw.pci_base0,
+								read_value);
+					break;
+				case NX_DUMP_MOD_SAVE_ST:
+					read_value =
+					template_hdr->saved_state_array
+						[crtEntry->state_index_v];
+					read_value <<= crtEntry->shl;
+					read_value >>= crtEntry->shr;
+					if (crtEntry->value_2)
+						read_value &=
+						crtEntry->value_2;
+					read_value |= crtEntry->value_3;
+					read_value += crtEntry->value_1;
+					/* Write value back to state area.*/
+					template_hdr->saved_state_array
+						[crtEntry->state_index_v]
+							= read_value;
+					break;
+				default:
+					rv = 1;
+					break;
+				}
+			}
+		}
+		addr = addr + stride;
+	}
+	return rv;
+}
+
+/* Read memory or MN */
+static u32
+netxen_md_rdmem(struct netxen_adapter *adapter,
+		struct netxen_minidump_entry_rdmem
+			*memEntry, u64 *data_buff)
+{
+	u64 addr, value = 0;
+	int i = 0, loop_cnt;
+
+	addr = (u64)memEntry->read_addr;
+	loop_cnt = memEntry->read_data_size;    /* This is size in bytes */
+	loop_cnt /= sizeof(value);
+
+	for (i = 0; i < loop_cnt; i++) {
+		if (netxen_nic_pci_mem_read_2M(adapter, addr, &value))
+			goto out;
+		*data_buff++ = value;
+		addr += sizeof(value);
+	}
+out:
+	return i * sizeof(value);
+}
+
+/* Read CRB operation */
+static u32 netxen_md_rd_crb(struct netxen_adapter *adapter,
+			struct netxen_minidump_entry_crb
+				*crbEntry, u32 *data_buff)
+{
+	int loop_cnt;
+	u32 op_count, addr, stride, value;
+
+	addr = crbEntry->addr;
+	op_count = crbEntry->op_count;
+	stride = crbEntry->addr_stride;
+
+	for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
+		NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0, &value);
+		*data_buff++ = addr;
+		*data_buff++ = value;
+		addr = addr + stride;
+	}
+	return loop_cnt * (2 * sizeof(u32));
+}
+
+/* Read ROM */
+static u32
+netxen_md_rdrom(struct netxen_adapter *adapter,
+			struct netxen_minidump_entry_rdrom
+				*romEntry, u32 *data_buff)
+{
+	int i, count = 0;
+	u32 size, lck_val;
+	u32 val;
+	u32 fl_addr, waddr, raddr;
+	fl_addr = romEntry->read_addr;
+	size = romEntry->read_data_size/4;
+lock_try:
+	lck_val = readl((void __iomem *)(adapter->ahw.pci_base0 +
+							NX_FLASH_SEM2_LK));
+	if (!lck_val && count < MAX_CTL_CHECK) {
+		msleep(20);
+		count++;
+		goto lock_try;
+	}
+	writel(adapter->ahw.pci_func, (void __iomem *)(adapter->ahw.pci_base0 +
+							NX_FLASH_LOCK_ID));
+	for (i = 0; i < size; i++) {
+		waddr = fl_addr & 0xFFFF0000;
+		NX_WR_DUMP_REG(FLASH_ROM_WINDOW, adapter->ahw.pci_base0, waddr);
+		raddr = FLASH_ROM_DATA + (fl_addr & 0x0000FFFF);
+		NX_RD_DUMP_REG(raddr, adapter->ahw.pci_base0, &val);
+		*data_buff++ = cpu_to_le32(val);
+		fl_addr += sizeof(val);
+	}
+	readl((void __iomem *)(adapter->ahw.pci_base0 + NX_FLASH_SEM2_ULK));
+	return romEntry->read_data_size;
+}
+
+/* Handle L2 Cache */
+static u32
+netxen_md_L2Cache(struct netxen_adapter *adapter,
+				struct netxen_minidump_entry_cache
+					*cacheEntry, u32 *data_buff)
+{
+	int loop_cnt, i, k, timeout_flag = 0;
+	u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr;
+	u32 tag_value, read_cnt;
+	u8 cntl_value_w, cntl_value_r;
+	unsigned long timeout, timeout_jiffies;
+
+	loop_cnt = cacheEntry->op_count;
+	read_addr = cacheEntry->read_addr;
+	cntrl_addr = cacheEntry->control_addr;
+	cntl_value_w = (u32) cacheEntry->write_value;
+	tag_reg_addr = cacheEntry->tag_reg_addr;
+	tag_value = cacheEntry->init_tag_value;
+	read_cnt = cacheEntry->read_addr_cnt;
+
+	for (i = 0; i < loop_cnt; i++) {
+		NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value);
+		if (cntl_value_w)
+			NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
+					(u32)cntl_value_w);
+		if (cacheEntry->poll_mask) {
+			timeout = cacheEntry->poll_wait;
+			NX_RD_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
+							&cntl_value_r);
+			timeout_jiffies = msecs_to_jiffies(timeout) + jiffies;
+			for (timeout_flag = 0; !timeout_flag &&
+			((cntl_value_r & cacheEntry->poll_mask) != 0);) {
+				if (time_after(jiffies, timeout_jiffies))
+					timeout_flag = 1;
+				NX_RD_DUMP_REG(cntrl_addr,
+					adapter->ahw.pci_base0,
+							&cntl_value_r);
+			}
+			if (timeout_flag) {
+				dev_err(&adapter->pdev->dev,
+						"Timeout in processing L2 Tag poll.\n");
+				return -1;
+			}
+		}
+		addr = read_addr;
+		for (k = 0; k < read_cnt; k++) {
+			NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0,
+					&read_value);
+			*data_buff++ = read_value;
+			addr += cacheEntry->read_addr_stride;
+		}
+		tag_value += cacheEntry->tag_value_stride;
+	}
+	return read_cnt * loop_cnt * sizeof(read_value);
+}
+
+
+/* Handle L1 Cache */
+static u32 netxen_md_L1Cache(struct netxen_adapter *adapter,
+				struct netxen_minidump_entry_cache
+					*cacheEntry, u32 *data_buff)
+{
+	int i, k, loop_cnt;
+	u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr;
+	u32 tag_value, read_cnt;
+	u8 cntl_value_w;
+
+	loop_cnt = cacheEntry->op_count;
+	read_addr = cacheEntry->read_addr;
+	cntrl_addr = cacheEntry->control_addr;
+	cntl_value_w = (u32) cacheEntry->write_value;
+	tag_reg_addr = cacheEntry->tag_reg_addr;
+	tag_value = cacheEntry->init_tag_value;
+	read_cnt = cacheEntry->read_addr_cnt;
+
+	for (i = 0; i < loop_cnt; i++) {
+		NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value);
+		NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
+						(u32) cntl_value_w);
+		addr = read_addr;
+		for (k = 0; k < read_cnt; k++) {
+			NX_RD_DUMP_REG(addr,
+				adapter->ahw.pci_base0,
+						&read_value);
+			*data_buff++ = read_value;
+			addr += cacheEntry->read_addr_stride;
+		}
+		tag_value += cacheEntry->tag_value_stride;
+	}
+	return read_cnt * loop_cnt * sizeof(read_value);
+}
+
+/* Reading OCM memory */
+static u32
+netxen_md_rdocm(struct netxen_adapter *adapter,
+				struct netxen_minidump_entry_rdocm
+					*ocmEntry, u32 *data_buff)
+{
+	int i, loop_cnt;
+	u32 value;
+	void __iomem *addr;
+	addr = (ocmEntry->read_addr + adapter->ahw.pci_base0);
+	loop_cnt = ocmEntry->op_count;
+
+	for (i = 0; i < loop_cnt; i++) {
+		value = readl(addr);
+		*data_buff++ = value;
+		addr += ocmEntry->read_addr_stride;
+	}
+	return i * sizeof(u32);
+}
+
+/* Read MUX data */
+static u32
+netxen_md_rdmux(struct netxen_adapter *adapter, struct netxen_minidump_entry_mux
+					*muxEntry, u32 *data_buff)
+{
+	int loop_cnt = 0;
+	u32 read_addr, read_value, select_addr, sel_value;
+
+	read_addr = muxEntry->read_addr;
+	sel_value = muxEntry->select_value;
+	select_addr = muxEntry->select_addr;
+
+	for (loop_cnt = 0; loop_cnt < muxEntry->op_count; loop_cnt++) {
+		NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, sel_value);
+		NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0, &read_value);
+		*data_buff++ = sel_value;
+		*data_buff++ = read_value;
+		sel_value += muxEntry->select_value_stride;
+	}
+	return loop_cnt * (2 * sizeof(u32));
+}
+
+/* Handling Queue State Reads */
+static u32
+netxen_md_rdqueue(struct netxen_adapter *adapter,
+				struct netxen_minidump_entry_queue
+					*queueEntry, u32 *data_buff)
+{
+	int loop_cnt, k;
+	u32 queue_id, read_addr, read_value, read_stride, select_addr, read_cnt;
+
+	read_cnt = queueEntry->read_addr_cnt;
+	read_stride = queueEntry->read_addr_stride;
+	select_addr = queueEntry->select_addr;
+
+	for (loop_cnt = 0, queue_id = 0; loop_cnt < queueEntry->op_count;
+				 loop_cnt++) {
+		NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id);
+		read_addr = queueEntry->read_addr;
+		for (k = 0; k < read_cnt; k--) {
+			NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0,
+							&read_value);
+			*data_buff++ = read_value;
+			read_addr += read_stride;
+		}
+		queue_id += queueEntry->queue_id_stride;
+	}
+	return loop_cnt * (read_cnt * sizeof(read_value));
+}
+
+
+/*
+* We catch an error where driver does not read
+* as much data as we expect from the entry.
+*/
+
+static int netxen_md_entry_err_chk(struct netxen_adapter *adapter,
+				struct netxen_minidump_entry *entry, int esize)
+{
+	if (esize < 0) {
+		entry->hdr.driver_flags |= NX_DUMP_SKIP;
+		return esize;
+	}
+	if (esize != entry->hdr.entry_capture_size) {
+		entry->hdr.entry_capture_size = esize;
+		entry->hdr.driver_flags |= NX_DUMP_SIZE_ERR;
+		dev_info(&adapter->pdev->dev,
+			"Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
+			entry->hdr.entry_type, entry->hdr.entry_capture_mask,
+			esize, entry->hdr.entry_capture_size);
+		dev_info(&adapter->pdev->dev, "Aborting further dump capture\n");
+	}
+	return 0;
+}
+
+static int netxen_parse_md_template(struct netxen_adapter *adapter)
+{
+	int num_of_entries, buff_level, e_cnt, esize;
+	int end_cnt = 0, rv = 0, sane_start = 0, sane_end = 0;
+	char *dbuff;
+	void *template_buff = adapter->mdump.md_template;
+	char *dump_buff = adapter->mdump.md_capture_buff;
+	int capture_mask = adapter->mdump.md_capture_mask;
+	struct netxen_minidump_template_hdr *template_hdr;
+	struct netxen_minidump_entry *entry;
+
+	if ((capture_mask & 0x3) != 0x3) {
+		dev_err(&adapter->pdev->dev, "Capture mask %02x below minimum needed "
+			"for valid firmware dump\n", capture_mask);
+		return -EINVAL;
+	}
+	template_hdr = (struct netxen_minidump_template_hdr *) template_buff;
+	num_of_entries = template_hdr->num_of_entries;
+	entry = (struct netxen_minidump_entry *) ((char *) template_buff +
+				template_hdr->first_entry_offset);
+	memcpy(dump_buff, template_buff, adapter->mdump.md_template_size);
+	dump_buff = dump_buff + adapter->mdump.md_template_size;
+
+	if (template_hdr->entry_type == TLHDR)
+		sane_start = 1;
+
+	for (e_cnt = 0, buff_level = 0; e_cnt < num_of_entries; e_cnt++) {
+		if (!(entry->hdr.entry_capture_mask & capture_mask)) {
+			entry->hdr.driver_flags |= NX_DUMP_SKIP;
+			entry = (struct netxen_minidump_entry *)
+				((char *) entry + entry->hdr.entry_size);
+			continue;
+		}
+		switch (entry->hdr.entry_type) {
+		case RDNOP:
+			entry->hdr.driver_flags |= NX_DUMP_SKIP;
+			break;
+		case RDEND:
+			entry->hdr.driver_flags |= NX_DUMP_SKIP;
+			if (!sane_end)
+				end_cnt = e_cnt;
+			sane_end += 1;
+			break;
+		case CNTRL:
+			rv = netxen_md_cntrl(adapter,
+				template_hdr, (void *)entry);
+			if (rv)
+				entry->hdr.driver_flags |= NX_DUMP_SKIP;
+			break;
+		case RDCRB:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_rd_crb(adapter,
+					(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case RDMN:
+		case RDMEM:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_rdmem(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case BOARD:
+		case RDROM:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_rdrom(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case L2ITG:
+		case L2DTG:
+		case L2DAT:
+		case L2INS:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_L2Cache(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case L1DAT:
+		case L1INS:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_L1Cache(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case RDOCM:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_rdocm(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case RDMUX:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_rdmux(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv < 0)
+				break;
+			buff_level += esize;
+			break;
+		case QUEUE:
+			dbuff = dump_buff + buff_level;
+			esize = netxen_md_rdqueue(adapter,
+				(void *) entry, (void *) dbuff);
+			rv = netxen_md_entry_err_chk
+				(adapter, entry, esize);
+			if (rv  < 0)
+				break;
+			buff_level += esize;
+			break;
+		default:
+			entry->hdr.driver_flags |= NX_DUMP_SKIP;
+			break;
+		}
+		/* Next entry in the template */
+		entry = (struct netxen_minidump_entry *)
+			((char *) entry + entry->hdr.entry_size);
+	}
+	if (!sane_start || sane_end > 1) {
+		dev_err(&adapter->pdev->dev,
+				"Firmware minidump template configuration error.\n");
+	}
+	return 0;
+}
+
+static int
+netxen_collect_minidump(struct netxen_adapter *adapter)
+{
+	int ret = 0;
+	struct netxen_minidump_template_hdr *hdr;
+	struct timespec val;
+	hdr = (struct netxen_minidump_template_hdr *)
+				adapter->mdump.md_template;
+	hdr->driver_capture_mask = adapter->mdump.md_capture_mask;
+	jiffies_to_timespec(jiffies, &val);
+	hdr->driver_timestamp = (u32) val.tv_sec;
+	hdr->driver_info_word2 = adapter->fw_version;
+	hdr->driver_info_word3 = NXRD32(adapter, CRB_DRIVER_VERSION);
+	ret = netxen_parse_md_template(adapter);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+
+void
+netxen_dump_fw(struct netxen_adapter *adapter)
+{
+	struct netxen_minidump_template_hdr *hdr;
+	int i, k, data_size = 0;
+	u32 capture_mask;
+	hdr = (struct netxen_minidump_template_hdr *)
+				adapter->mdump.md_template;
+	capture_mask = adapter->mdump.md_capture_mask;
+
+	for (i = 0x2, k = 1; (i & NX_DUMP_MASK_MAX); i <<= 1, k++) {
+		if (i & capture_mask)
+			data_size += hdr->capture_size_array[k];
+	}
+	if (!data_size) {
+		dev_err(&adapter->pdev->dev,
+				"Invalid cap sizes for capture_mask=0x%x\n",
+			adapter->mdump.md_capture_mask);
+		return;
+	}
+	adapter->mdump.md_capture_size = data_size;
+	adapter->mdump.md_dump_size = adapter->mdump.md_template_size +
+					adapter->mdump.md_capture_size;
+	if (!adapter->mdump.md_capture_buff) {
+		adapter->mdump.md_capture_buff =
+				vmalloc(adapter->mdump.md_dump_size);
+		if (!adapter->mdump.md_capture_buff) {
+			dev_info(&adapter->pdev->dev,
+				"Unable to allocate memory for minidump "
+				"capture_buffer(%d bytes).\n",
+					adapter->mdump.md_dump_size);
+			return;
+		}
+		memset(adapter->mdump.md_capture_buff, 0,
+				adapter->mdump.md_dump_size);
+		if (netxen_collect_minidump(adapter)) {
+			adapter->mdump.has_valid_dump = 0;
+			adapter->mdump.md_dump_size = 0;
+			vfree(adapter->mdump.md_capture_buff);
+			adapter->mdump.md_capture_buff = NULL;
+			dev_err(&adapter->pdev->dev,
+				"Error in collecting firmware minidump.\n");
+		} else {
+			adapter->mdump.md_timestamp = jiffies;
+			adapter->mdump.has_valid_dump = 1;
+			adapter->fw_mdump_rdy = 1;
+			dev_info(&adapter->pdev->dev, "%s Successfully "
+				"collected fw dump.\n", adapter->netdev->name);
+		}
+
+	} else {
+		dev_info(&adapter->pdev->dev,
+					"Cannot overwrite previously collected "
+							"firmware minidump.\n");
+		adapter->fw_mdump_rdy = 1;
+		return;
+	}
+}
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
index a8259cc..718b274 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
@@ -280,13 +280,10 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 
 		}
 		rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring));
-		if (rds_ring->rx_buf_arr == NULL) {
-			printk(KERN_ERR "%s: Failed to allocate "
-				"rx buffer ring %d\n",
-				netdev->name, ring);
+		if (rds_ring->rx_buf_arr == NULL)
 			/* free whatever was already allocated */
 			goto err_out;
-		}
+
 		INIT_LIST_HEAD(&rds_ring->free_list);
 		/*
 		 * Now go through all of them, set reference handles
@@ -449,7 +446,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter)
 
 	/* resetall */
 	netxen_rom_lock(adapter);
-	NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
+	NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xfeffffff);
 	netxen_rom_unlock(adapter);
 
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
@@ -480,11 +477,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter)
 	}
 
 	buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
-	if (buf == NULL) {
-		printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n",
-				netxen_nic_driver_name);
+	if (buf == NULL)
 		return -ENOMEM;
-	}
 
 	for (i = 0; i < n; i++) {
 		if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
@@ -1353,7 +1347,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
 
 	do {
 		val = NXRD32(adapter, CRB_CMDPEG_STATE);
-
 		switch (val) {
 		case PHAN_INITIALIZE_COMPLETE:
 		case PHAN_INITIALIZE_ACK:
@@ -1494,7 +1487,7 @@ netxen_alloc_rx_skb(struct netxen_adapter *adapter,
 	dma_addr_t dma;
 	struct pci_dev *pdev = adapter->pdev;
 
-	buffer->skb = dev_alloc_skb(rds_ring->skb_size);
+	buffer->skb = netdev_alloc_skb(adapter->netdev, rds_ring->skb_size);
 	if (!buffer->skb)
 		return 1;
 
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 7dd9a4b..8dc4a134 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -82,7 +82,6 @@ static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
 static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
 static void netxen_create_diag_entries(struct netxen_adapter *adapter);
 static void netxen_remove_diag_entries(struct netxen_adapter *adapter);
-
 static int nx_dev_request_aer(struct netxen_adapter *adapter);
 static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
 static int netxen_can_start_firmware(struct netxen_adapter *adapter);
@@ -802,10 +801,10 @@ err_out:
 static void
 netxen_check_options(struct netxen_adapter *adapter)
 {
-	u32 fw_major, fw_minor, fw_build;
+	u32 fw_major, fw_minor, fw_build, prev_fw_version;
 	char brd_name[NETXEN_MAX_SHORT_NAME];
 	char serial_num[32];
-	int i, offset, val;
+	int i, offset, val, err;
 	int *ptr32;
 	struct pci_dev *pdev = adapter->pdev;
 
@@ -826,9 +825,22 @@ netxen_check_options(struct netxen_adapter *adapter)
 	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
 	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
 	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-
+	prev_fw_version = adapter->fw_version;
 	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
 
+	/* Get FW Mini Coredump template and store it */
+	 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		if (adapter->mdump.md_template == NULL ||
+				adapter->fw_version > prev_fw_version) {
+			kfree(adapter->mdump.md_template);
+			adapter->mdump.md_template = NULL;
+			err = netxen_setup_minidump(adapter);
+			if (err)
+				dev_err(&adapter->pdev->dev,
+				"Failed to setup minidump rcode = %d\n", err);
+		}
+	}
+
 	if (adapter->portnum == 0) {
 		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
 
@@ -909,7 +921,12 @@ netxen_start_firmware(struct netxen_adapter *adapter)
 	if (err)
 		return err;
 
-	if (!netxen_can_start_firmware(adapter))
+	err = netxen_can_start_firmware(adapter);
+
+	if (err < 0)
+		return err;
+
+	if (!err)
 		goto wait_init;
 
 	first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
@@ -1403,7 +1420,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
 	if(!netdev) {
-		dev_err(&pdev->dev, "failed to allocate net_device\n");
 		err = -ENOMEM;
 		goto err_out_free_res;
 	}
@@ -1529,6 +1545,18 @@ err_out_disable_pdev:
 	return err;
 }
 
+static
+void netxen_cleanup_minidump(struct netxen_adapter *adapter)
+{
+	kfree(adapter->mdump.md_template);
+	adapter->mdump.md_template = NULL;
+
+	if (adapter->mdump.md_capture_buff) {
+		vfree(adapter->mdump.md_capture_buff);
+		adapter->mdump.md_capture_buff = NULL;
+	}
+}
+
 static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 {
 	struct netxen_adapter *adapter;
@@ -1564,8 +1592,10 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 	netxen_release_firmware(adapter);
 
-	if (NX_IS_REVISION_P3(pdev->revision))
+	if (NX_IS_REVISION_P3(pdev->revision)) {
+		netxen_cleanup_minidump(adapter);
 		pci_disable_pcie_error_reporting(pdev);
+	}
 
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -2317,7 +2347,7 @@ nx_incr_dev_ref_cnt(struct netxen_adapter *adapter)
 static int
 nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
 {
-	int count;
+	int count, state;
 	if (netxen_api_lock(adapter))
 		return -EIO;
 
@@ -2325,8 +2355,9 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
 	WARN_ON(count == 0);
 
 	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+	state = NXRD32(adapter, NX_CRB_DEV_STATE);
 
-	if (count == 0)
+	if (count == 0 && state != NX_DEV_FAILED)
 		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
 
 	netxen_api_unlock(adapter);
@@ -2355,7 +2386,7 @@ nx_dev_request_aer(struct netxen_adapter *adapter)
 	return ret;
 }
 
-static int
+int
 nx_dev_request_reset(struct netxen_adapter *adapter)
 {
 	u32 state;
@@ -2366,10 +2397,11 @@ nx_dev_request_reset(struct netxen_adapter *adapter)
 
 	state = NXRD32(adapter, NX_CRB_DEV_STATE);
 
-	if (state == NX_DEV_NEED_RESET)
+	if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED)
 		ret = 0;
 	else if (state != NX_DEV_INITALIZING && state != NX_DEV_NEED_AER) {
 		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
+		adapter->flags |= NETXEN_FW_RESET_OWNER;
 		ret = 0;
 	}
 
@@ -2384,8 +2416,10 @@ netxen_can_start_firmware(struct netxen_adapter *adapter)
 	int count;
 	int can_start = 0;
 
-	if (netxen_api_lock(adapter))
-		return 0;
+	if (netxen_api_lock(adapter)) {
+		nx_incr_dev_ref_cnt(adapter);
+		return -1;
+	}
 
 	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
 
@@ -2457,8 +2491,31 @@ netxen_fwinit_work(struct work_struct *work)
 	struct netxen_adapter *adapter = container_of(work,
 				struct netxen_adapter, fw_work.work);
 	int dev_state;
-
+	int count;
 	dev_state = NXRD32(adapter, NX_CRB_DEV_STATE);
+	if (adapter->flags & NETXEN_FW_RESET_OWNER) {
+		count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+		WARN_ON(count == 0);
+		if (count == 1) {
+			if (adapter->mdump.md_enabled) {
+				rtnl_lock();
+				netxen_dump_fw(adapter);
+				rtnl_unlock();
+			}
+			adapter->flags &= ~NETXEN_FW_RESET_OWNER;
+			if (netxen_api_lock(adapter)) {
+				clear_bit(__NX_RESETTING, &adapter->state);
+				NXWR32(adapter, NX_CRB_DEV_STATE,
+						NX_DEV_FAILED);
+				return;
+			}
+			count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+			NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+			NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
+			dev_state = NX_DEV_COLD;
+			netxen_api_unlock(adapter);
+		}
+	}
 
 	switch (dev_state) {
 	case NX_DEV_COLD:
@@ -2471,11 +2528,9 @@ netxen_fwinit_work(struct work_struct *work)
 
 	case NX_DEV_NEED_RESET:
 	case NX_DEV_INITALIZING:
-		if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
 			netxen_schedule_work(adapter,
 					netxen_fwinit_work, 2 * FW_POLL_DELAY);
 			return;
-		}
 
 	case NX_DEV_FAILED:
 	default:
@@ -2483,6 +2538,15 @@ netxen_fwinit_work(struct work_struct *work)
 		break;
 	}
 
+	if (netxen_api_lock(adapter)) {
+		clear_bit(__NX_RESETTING, &adapter->state);
+		return;
+	}
+	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_FAILED);
+	netxen_api_unlock(adapter);
+	dev_err(&adapter->pdev->dev, "%s: Device initialization Failed\n",
+				adapter->netdev->name);
+
 	clear_bit(__NX_RESETTING, &adapter->state);
 }
 
@@ -2492,7 +2556,7 @@ netxen_detach_work(struct work_struct *work)
 	struct netxen_adapter *adapter = container_of(work,
 				struct netxen_adapter, fw_work.work);
 	struct net_device *netdev = adapter->netdev;
-	int ref_cnt, delay;
+	int ref_cnt = 0, delay;
 	u32 status;
 
 	netif_device_detach(netdev);
@@ -2511,7 +2575,8 @@ netxen_detach_work(struct work_struct *work)
 	if (adapter->temp == NX_TEMP_PANIC)
 		goto err_ret;
 
-	ref_cnt = nx_decr_dev_ref_cnt(adapter);
+	if (!(adapter->flags & NETXEN_FW_RESET_OWNER))
+		ref_cnt = nx_decr_dev_ref_cnt(adapter);
 
 	if (ref_cnt == -EIO)
 		goto err_ret;
@@ -2531,6 +2596,7 @@ static int
 netxen_check_health(struct netxen_adapter *adapter)
 {
 	u32 state, heartbit;
+	u32 peg_status;
 	struct net_device *netdev = adapter->netdev;
 
 	state = NXRD32(adapter, NX_CRB_DEV_STATE);
@@ -2551,7 +2617,7 @@ netxen_check_health(struct netxen_adapter *adapter)
 	 * Send request to destroy context in case of tx timeout only
 	 * and doesn't required in case of Fw hang
 	 */
-	if (state == NX_DEV_NEED_RESET) {
+	if (state == NX_DEV_NEED_RESET || state == NX_DEV_FAILED) {
 		adapter->need_fw_reset = 1;
 		if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
 			goto detach;
@@ -2577,8 +2643,24 @@ netxen_check_health(struct netxen_adapter *adapter)
 
 	clear_bit(__NX_FW_ATTACHED, &adapter->state);
 
-	dev_info(&netdev->dev, "firmware hang detected\n");
-
+	dev_err(&netdev->dev, "firmware hang detected\n");
+	peg_status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+	dev_err(&adapter->pdev->dev, "Dumping hw/fw registers\n"
+			"PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n"
+			"PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n"
+			"PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n"
+			"PEG_NET_4_PC: 0x%x\n",
+			peg_status,
+			NXRD32(adapter, NETXEN_PEG_HALT_STATUS2),
+			NXRD32(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c),
+			NXRD32(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c),
+			NXRD32(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c),
+			NXRD32(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c),
+			NXRD32(adapter, NETXEN_CRB_PEG_NET_4 + 0x3c));
+	if (NX_FWERROR_PEGSTAT1(peg_status) == 0x67)
+		dev_err(&adapter->pdev->dev,
+			"Firmware aborted with error code 0x00006700. "
+				"Device is being reset.\n");
 detach:
 	if ((auto_fw_reset == AUTO_FW_RESET_ENABLED) &&
 			!test_and_set_bit(__NX_RESETTING, &adapter->state))
@@ -2848,13 +2930,12 @@ static struct bin_attribute bin_attr_mem = {
 static void
 netxen_create_sysfs_entries(struct netxen_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
-	struct device *dev = &netdev->dev;
+	struct device *dev = &adapter->pdev->dev;
 
 	if (adapter->capabilities & NX_FW_CAPABILITY_BDG) {
 		/* bridged_mode control */
 		if (device_create_file(dev, &dev_attr_bridged_mode)) {
-			dev_warn(&netdev->dev,
+			dev_warn(dev,
 				"failed to create bridged_mode sysfs entry\n");
 		}
 	}
@@ -2863,8 +2944,7 @@ netxen_create_sysfs_entries(struct netxen_adapter *adapter)
 static void
 netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
-	struct device *dev = &netdev->dev;
+	struct device *dev = &adapter->pdev->dev;
 
 	if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
 		device_remove_file(dev, &dev_attr_bridged_mode);
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
index 7931531..d49f6da 100644
--- a/drivers/net/ethernet/qlogic/qla3xxx.c
+++ b/drivers/net/ethernet/qlogic/qla3xxx.c
@@ -3805,7 +3805,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
 
 	ndev = alloc_etherdev(sizeof(struct ql3_adapter));
 	if (!ndev) {
-		pr_err("%s could not alloc etherdev\n", pci_name(pdev));
 		err = -ENOMEM;
 		goto err_out_free_regions;
 	}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 60976fc..2b5af22 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -37,7 +37,7 @@
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
 #define _QLCNIC_LINUX_SUBVERSION 25
-#define QLCNIC_LINUX_VERSIONID  "5.0.25"
+#define QLCNIC_LINUX_VERSIONID  "5.0.26"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index cc228cf..89ddf7f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -155,7 +155,6 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	int check_sfp_module = 0;
-	u16 pcifn = adapter->ahw->pci_func;
 
 	/* read which mode */
 	if (adapter->ahw->port_type == QLCNIC_GBE) {
@@ -194,10 +193,8 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 			goto skip;
 		}
 
-		val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
-		ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
-				      P3P_LINK_SPEED_VAL(pcifn, val));
-		ecmd->duplex = DUPLEX_FULL;
+		ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
+		ecmd->duplex = DUPLEX_UNKNOWN;
 		ecmd->autoneg = AUTONEG_DISABLE;
 	} else
 		return -EIO;
@@ -722,7 +719,7 @@ static int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
 	int i, loop, cnt = 0;
 
 	for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {
-		skb = dev_alloc_skb(QLCNIC_ILB_PKT_SIZE);
+		skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE);
 		qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);
 		skb_put(skb, QLCNIC_ILB_PKT_SIZE);
 
@@ -1155,7 +1152,6 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
 
 	if (!fw_dump->clr) {
 		netdev_info(netdev, "Dump not available\n");
-		qlcnic_api_unlock(adapter);
 		return -EINVAL;
 	}
 	/* Copy template header first */
@@ -1174,7 +1170,7 @@ qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
 	vfree(fw_dump->data);
 	fw_dump->data = NULL;
 	fw_dump->clr = 0;
-
+	netdev_info(netdev, "extracted the FW dump Successfully\n");
 	return 0;
 }
 
@@ -1192,7 +1188,7 @@ qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
 			return ret;
 		}
 		if (fw_dump->clr) {
-			dev_info(&adapter->pdev->dev,
+			netdev_info(netdev,
 			"Previous dump not cleared, not forcing dump\n");
 			return ret;
 		}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index 3866958..d32cf0d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
@@ -1369,7 +1369,13 @@ qlcnic_handle_linkevent(struct qlcnic_adapter *adapter,
 
 	adapter->module_type = module;
 	adapter->link_autoneg = autoneg;
-	adapter->link_speed = link_speed;
+
+	if (link_status) {
+		adapter->link_speed = link_speed;
+	} else {
+		adapter->link_speed = SPEED_UNKNOWN;
+		adapter->link_duplex = DUPLEX_UNKNOWN;
+	}
 }
 
 static void
@@ -1434,7 +1440,7 @@ qlcnic_alloc_rx_skb(struct qlcnic_adapter *adapter,
 	dma_addr_t dma;
 	struct pci_dev *pdev = adapter->pdev;
 
-	skb = dev_alloc_skb(rds_ring->skb_size);
+	skb = netdev_alloc_skb(adapter->netdev, rds_ring->skb_size);
 	if (!skb) {
 		adapter->stats.skb_alloc_failure++;
 		return -ENOMEM;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 69b8e4e..dba9531 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1576,7 +1576,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev = alloc_etherdev(sizeof(struct qlcnic_adapter));
 	if (!netdev) {
-		dev_err(&pdev->dev, "failed to allocate net_device\n");
 		err = -ENOMEM;
 		goto err_out_free_res;
 	}
@@ -3000,8 +2999,18 @@ qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter)
 void
 qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 {
-	u32 state;
-
+	u32 state, xg_val = 0, gb_val = 0;
+
+	qlcnic_xg_set_xg0_mask(xg_val);
+	qlcnic_xg_set_xg1_mask(xg_val);
+	QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, xg_val);
+	qlcnic_gb_set_gb0_mask(gb_val);
+	qlcnic_gb_set_gb1_mask(gb_val);
+	qlcnic_gb_set_gb2_mask(gb_val);
+	qlcnic_gb_set_gb3_mask(gb_val);
+	QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, gb_val);
+	dev_info(&adapter->pdev->dev, "Pause control frames disabled"
+				" on all ports\n");
 	adapter->need_fw_reset = 1;
 	if (qlcnic_api_lock(adapter))
 		return;
@@ -3150,7 +3159,7 @@ qlcnic_check_health(struct qlcnic_adapter *adapter)
 			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x3c),
 			QLCRD32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c));
 	peg_status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1);
-	if (LSW(MSB(peg_status)) == 0x67)
+	if (QLCNIC_FWERROR_CODE(peg_status) == 0x67)
 		dev_err(&adapter->pdev->dev,
 			"Firmware aborted with error code 0x00006700. "
 				"Device is being reset.\n");
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h
index b8478aa..5a639df 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge.h
+++ b/drivers/net/ethernet/qlogic/qlge/qlge.h
@@ -18,7 +18,7 @@
  */
 #define DRV_NAME  	"qlge"
 #define DRV_STRING 	"QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION	"v1.00.00.29.00.00-01"
+#define DRV_VERSION	"v1.00.00.30.00.00-01"
 
 #define WQ_ADDR_ALIGN	0x3	/* 4 byte alignment */
 
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index fca804f..58185b6 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
@@ -1824,10 +1824,8 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id)
 	pr_err("%s: Enter\n", __func__);
 
 	ptr = kmalloc(size, GFP_ATOMIC);
-	if (ptr == NULL) {
-		pr_err("%s: Couldn't allocate a buffer\n", __func__);
+	if (ptr == NULL)
 		return;
-	}
 
 	if (ql_write_cfg(qdev, ptr, size, bit, q_id)) {
 		pr_err("%s: Failed to upload control block!\n", __func__);
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index b548987..49343ec 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -375,13 +375,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
 			u32 lower =
 			    (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
 			    (addr[5]);
-
-			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-				     "Adding %s address %pM at index %d in the CAM.\n",
-				     type == MAC_ADDR_TYPE_MULTI_MAC ?
-				     "MULTICAST" : "UNICAST",
-				     addr, index);
-
 			status =
 			    ql_wait_reg_rdy(qdev,
 				MAC_ADDR_IDX, MAC_ADDR_MW, 0);
@@ -430,12 +423,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
 			 * addressing. It's either MAC_ADDR_E on or off.
 			 * That's bit-27 we're talking about.
 			 */
-			netif_info(qdev, ifup, qdev->ndev,
-				   "%s VLAN ID %d %s the CAM.\n",
-				   enable_bit ? "Adding" : "Removing",
-				   index,
-				   enable_bit ? "to" : "from");
-
 			status =
 			    ql_wait_reg_rdy(qdev,
 				MAC_ADDR_IDX, MAC_ADDR_MW, 0);
@@ -535,28 +522,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
 	int status = -EINVAL; /* Return error if no mask match. */
 	u32 value = 0;
 
-	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-		     "%s %s mask %s the routing reg.\n",
-		     enable ? "Adding" : "Removing",
-		     index == RT_IDX_ALL_ERR_SLOT ? "MAC ERROR/ALL ERROR" :
-		     index == RT_IDX_IP_CSUM_ERR_SLOT ? "IP CSUM ERROR" :
-		     index == RT_IDX_TCP_UDP_CSUM_ERR_SLOT ? "TCP/UDP CSUM ERROR" :
-		     index == RT_IDX_BCAST_SLOT ? "BROADCAST" :
-		     index == RT_IDX_MCAST_MATCH_SLOT ? "MULTICAST MATCH" :
-		     index == RT_IDX_ALLMULTI_SLOT ? "ALL MULTICAST MATCH" :
-		     index == RT_IDX_UNUSED6_SLOT ? "UNUSED6" :
-		     index == RT_IDX_UNUSED7_SLOT ? "UNUSED7" :
-		     index == RT_IDX_RSS_MATCH_SLOT ? "RSS ALL/IPV4 MATCH" :
-		     index == RT_IDX_RSS_IPV6_SLOT ? "RSS IPV6" :
-		     index == RT_IDX_RSS_TCP4_SLOT ? "RSS TCP4" :
-		     index == RT_IDX_RSS_TCP6_SLOT ? "RSS TCP6" :
-		     index == RT_IDX_CAM_HIT_SLOT ? "CAM HIT" :
-		     index == RT_IDX_UNUSED013 ? "UNUSED13" :
-		     index == RT_IDX_UNUSED014 ? "UNUSED14" :
-		     index == RT_IDX_PROMISCUOUS_SLOT ? "PROMISCUOUS" :
-		     "(Bad index != RT_IDX)",
-		     enable ? "to" : "from");
-
 	switch (mask) {
 	case RT_IDX_CAM_HIT:
 		{
@@ -1178,14 +1143,16 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 	int i;
 
 	while (rx_ring->lbq_free_cnt > 32) {
-		for (i = 0; i < 16; i++) {
+		for (i = (rx_ring->lbq_clean_idx % 16); i < 16; i++) {
 			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
 				     "lbq: try cleaning clean_idx = %d.\n",
 				     clean_idx);
 			lbq_desc = &rx_ring->lbq[clean_idx];
 			if (ql_get_next_chunk(qdev, rx_ring, lbq_desc)) {
+				rx_ring->lbq_clean_idx = clean_idx;
 				netif_err(qdev, ifup, qdev->ndev,
-					  "Could not get a page chunk.\n");
+						"Could not get a page chunk, i=%d, clean_idx =%d .\n",
+						i, clean_idx);
 				return;
 			}
 
@@ -1230,7 +1197,7 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 	int i;
 
 	while (rx_ring->sbq_free_cnt > 16) {
-		for (i = 0; i < 16; i++) {
+		for (i = (rx_ring->sbq_clean_idx % 16); i < 16; i++) {
 			sbq_desc = &rx_ring->sbq[clean_idx];
 			netif_printk(qdev, rx_status, KERN_DEBUG, qdev->ndev,
 				     "sbq: try cleaning clean_idx = %d.\n",
@@ -1576,13 +1543,14 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev,
 		} else if ((ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_U) &&
 				(ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_V4)) {
 			/* Unfragmented ipv4 UDP frame. */
-			struct iphdr *iph = (struct iphdr *) skb->data;
+			struct iphdr *iph =
+				(struct iphdr *) ((u8 *)addr + ETH_HLEN);
 			if (!(iph->frag_off &
 				cpu_to_be16(IP_MF|IP_OFFSET))) {
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
 				netif_printk(qdev, rx_status, KERN_DEBUG,
 					     qdev->ndev,
-					     "TCP checksum done!\n");
+					     "UDP checksum done!\n");
 			}
 		}
 	}
@@ -1690,7 +1658,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
 				netif_printk(qdev, rx_status, KERN_DEBUG,
 					     qdev->ndev,
-					     "TCP checksum done!\n");
+					     "UDP checksum done!\n");
 			}
 		}
 	}
@@ -2312,13 +2280,9 @@ static void qlge_vlan_mode(struct net_device *ndev, netdev_features_t features)
 	struct ql_adapter *qdev = netdev_priv(ndev);
 
 	if (features & NETIF_F_HW_VLAN_RX) {
-		netif_printk(qdev, ifup, KERN_DEBUG, ndev,
-			     "Turning on VLAN in NIC_RCV_CFG.\n");
 		ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK |
 				 NIC_RCV_CFG_VLAN_MATCH_AND_NON);
 	} else {
-		netif_printk(qdev, ifup, KERN_DEBUG, ndev,
-			     "Turning off VLAN in NIC_RCV_CFG.\n");
 		ql_write32(qdev, NIC_RCV_CFG, NIC_RCV_CFG_VLAN_MASK);
 	}
 }
@@ -3183,8 +3147,6 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
 			     "Invalid rx_ring->type = %d.\n", rx_ring->type);
 	}
-	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-		     "Initializing rx work queue.\n");
 	err = ql_write_cfg(qdev, cqicb, sizeof(struct cqicb),
 			   CFG_LCQ, rx_ring->cq_id);
 	if (err) {
@@ -3237,8 +3199,6 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
 		netif_err(qdev, ifup, qdev->ndev, "Failed to load tx_ring.\n");
 		return err;
 	}
-	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-		     "Successfully loaded WQICB.\n");
 	return err;
 }
 
@@ -3488,12 +3448,8 @@ static void ql_free_irq(struct ql_adapter *qdev)
 			if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
 				free_irq(qdev->msi_x_entry[i].vector,
 					 &qdev->rx_ring[i]);
-				netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev,
-					     "freeing msix interrupt %d.\n", i);
 			} else {
 				free_irq(qdev->pdev->irq, &qdev->rx_ring[0]);
-				netif_printk(qdev, ifdown, KERN_DEBUG, qdev->ndev,
-					     "freeing msi interrupt %d.\n", i);
 			}
 		}
 	}
@@ -3522,17 +3478,6 @@ static int ql_request_irq(struct ql_adapter *qdev)
 					  "Failed request for MSIX interrupt %d.\n",
 					  i);
 				goto err_irq;
-			} else {
-				netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-					     "Hooked intr %d, queue type %s, with name %s.\n",
-					     i,
-					     qdev->rx_ring[i].type == DEFAULT_Q ?
-					     "DEFAULT_Q" :
-					     qdev->rx_ring[i].type == TX_Q ?
-					     "TX_Q" :
-					     qdev->rx_ring[i].type == RX_Q ?
-					     "RX_Q" : "",
-					     intr_context->name);
 			}
 		} else {
 			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
@@ -3602,15 +3547,11 @@ static int ql_start_rss(struct ql_adapter *qdev)
 	memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
 	memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
 
-	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev, "Initializing RSS.\n");
-
 	status = ql_write_cfg(qdev, ricb, sizeof(*ricb), CFG_LR, 0);
 	if (status) {
 		netif_err(qdev, ifup, qdev->ndev, "Failed to load RICB.\n");
 		return status;
 	}
-	netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-		     "Successfully loaded RICB.\n");
 	return status;
 }
 
@@ -3817,11 +3758,8 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
 	}
 
 	/* Start NAPI for the RSS queues. */
-	for (i = 0; i < qdev->rss_ring_count; i++) {
-		netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-			     "Enabling NAPI for rx_ring[%d].\n", i);
+	for (i = 0; i < qdev->rss_ring_count; i++)
 		napi_enable(&qdev->rx_ring[i].napi);
-	}
 
 	return status;
 }
@@ -4121,10 +4059,6 @@ static int ql_configure_rings(struct ql_adapter *qdev)
 			rx_ring->lbq_size =
 			    rx_ring->lbq_len * sizeof(__le64);
 			rx_ring->lbq_buf_size = (u16)lbq_buf_len;
-			netif_printk(qdev, ifup, KERN_DEBUG, qdev->ndev,
-				     "lbq_buf_size %d, order = %d\n",
-				     rx_ring->lbq_buf_size,
-				     qdev->lbq_buf_order);
 			rx_ring->sbq_len = NUM_SMALL_BUFFERS;
 			rx_ring->sbq_size =
 			    rx_ring->sbq_len * sizeof(__le64);
diff --git a/drivers/net/ethernet/racal/ni5010.c b/drivers/net/ethernet/racal/ni5010.c
index 072810d..8079822 100644
--- a/drivers/net/ethernet/racal/ni5010.c
+++ b/drivers/net/ethernet/racal/ni5010.c
@@ -552,7 +552,7 @@ static void ni5010_rx(struct net_device *dev)
 	}
 
 	/* Malloc up new buffer. */
-	skb = dev_alloc_skb(i_pkt_size + 3);
+	skb = netdev_alloc_skb(dev, i_pkt_size + 3);
 	if (skb == NULL) {
 		printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
 		dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
index cb0eca8..b96e192 100644
--- a/drivers/net/ethernet/rdc/r6040.c
+++ b/drivers/net/ethernet/rdc/r6040.c
@@ -1107,7 +1107,6 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 
 	dev = alloc_etherdev(sizeof(struct r6040_private));
 	if (!dev) {
-		dev_err(&pdev->dev, "Failed to allocate etherdev\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
@@ -1152,7 +1151,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 	if (!(adrp[0] || adrp[1] || adrp[2])) {
 		netdev_warn(dev, "MAC address not initialized, "
 					"generating random\n");
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 	}
 
 	/* Link new device into r6040_root_dev */
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c
index a8779be..1c3feb0 100644
--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -754,10 +754,9 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
 
 	/* dev and priv zeroed in alloc_etherdev */
 	dev = alloc_etherdev (sizeof (*tp));
-	if (dev == NULL) {
-		dev_err(&pdev->dev, "Unable to alloc new net device\n");
+	if (dev == NULL)
 		return ERR_PTR(-ENOMEM);
-	}
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	tp = netdev_priv(dev);
diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig
index 0578859..5821966 100644
--- a/drivers/net/ethernet/realtek/Kconfig
+++ b/drivers/net/ethernet/realtek/Kconfig
@@ -24,11 +24,11 @@ config ATP
 	select CRC32
 	---help---
 	  This is a network (Ethernet) device which attaches to your parallel
-	  port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>, if you
-	  want to use this.  If you intend to use this driver, you should have
-	  said N to the "Parallel printer support", because the two drivers
-	  don't like each other.
+	  port. Read <file:drivers/net/ethernet/realtek/atp.c> as well as the
+	  Ethernet-HOWTO, available from <http://www.tldp.org/docs.html#howto>,
+	  if you want to use this.  If you intend to use this driver, you
+	  should have said N to the "Parallel printer support", because the two
+	  drivers don't like each other.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called atp.
diff --git a/drivers/net/ethernet/realtek/atp.c b/drivers/net/ethernet/realtek/atp.c
index e3f57fd..46c1932 100644
--- a/drivers/net/ethernet/realtek/atp.c
+++ b/drivers/net/ethernet/realtek/atp.c
@@ -783,7 +783,7 @@ static void net_rx(struct net_device *dev)
 		int pkt_len = (rx_head.rx_count & 0x7ff) - 4;
 		struct sk_buff *skb;
 
-		skb = dev_alloc_skb(pkt_len + 2);
+		skb = netdev_alloc_skb(dev, pkt_len + 2);
 		if (skb == NULL) {
 			printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n",
 				   dev->name);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 7a0c800..5eb6858 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -667,12 +667,19 @@ struct rtl8169_counters {
 	__le16	tx_underun;
 };
 
+enum rtl_flag {
+	RTL_FLAG_TASK_ENABLED,
+	RTL_FLAG_TASK_SLOW_PENDING,
+	RTL_FLAG_TASK_RESET_PENDING,
+	RTL_FLAG_TASK_PHY_PENDING,
+	RTL_FLAG_MAX
+};
+
 struct rtl8169_private {
 	void __iomem *mmio_addr;	/* memory map physical address */
 	struct pci_dev *pci_dev;
 	struct net_device *dev;
 	struct napi_struct napi;
-	spinlock_t lock;
 	u32 msg_enable;
 	u16 txd_version;
 	u16 mac_version;
@@ -688,9 +695,8 @@ struct rtl8169_private {
 	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
 	struct timer_list timer;
 	u16 cp_cmd;
-	u16 intr_event;
-	u16 napi_event;
-	u16 intr_mask;
+
+	u16 event_slow;
 
 	struct mdio_ops {
 		void (*write)(void __iomem *, int, int);
@@ -714,7 +720,13 @@ struct rtl8169_private {
 	unsigned int (*phy_reset_pending)(struct rtl8169_private *tp);
 	unsigned int (*link_ok)(void __iomem *);
 	int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
-	struct delayed_work task;
+
+	struct {
+		DECLARE_BITMAP(flags, RTL_FLAG_MAX);
+		struct mutex mutex;
+		struct work_struct work;
+	} wk;
+
 	unsigned features;
 
 	struct mii_if_info mii;
@@ -764,13 +776,20 @@ static int rtl8169_close(struct net_device *dev);
 static void rtl_set_rx_mode(struct net_device *dev);
 static void rtl8169_tx_timeout(struct net_device *dev);
 static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
-static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
-				void __iomem *, u32 budget);
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
-static void rtl8169_down(struct net_device *dev);
 static void rtl8169_rx_clear(struct rtl8169_private *tp);
 static int rtl8169_poll(struct napi_struct *napi, int budget);
 
+static void rtl_lock_work(struct rtl8169_private *tp)
+{
+	mutex_lock(&tp->wk.mutex);
+}
+
+static void rtl_unlock_work(struct rtl8169_private *tp)
+{
+	mutex_unlock(&tp->wk.mutex);
+}
+
 static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
 {
 	int cap = pci_pcie_cap(pdev);
@@ -1180,12 +1199,51 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
 	return value;
 }
 
+static u16 rtl_get_events(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	return RTL_R16(IntrStatus);
+}
+
+static void rtl_ack_events(struct rtl8169_private *tp, u16 bits)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	RTL_W16(IntrStatus, bits);
+	mmiowb();
+}
+
+static void rtl_irq_disable(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	RTL_W16(IntrMask, 0);
+	mmiowb();
+}
+
+static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	RTL_W16(IntrMask, bits);
+}
+
+#define RTL_EVENT_NAPI_RX	(RxOK | RxErr)
+#define RTL_EVENT_NAPI_TX	(TxOK | TxErr)
+#define RTL_EVENT_NAPI		(RTL_EVENT_NAPI_RX | RTL_EVENT_NAPI_TX)
+
+static void rtl_irq_enable_all(struct rtl8169_private *tp)
+{
+	rtl_irq_enable(tp, RTL_EVENT_NAPI | tp->event_slow);
+}
+
 static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	RTL_W16(IntrMask, 0x0000);
-	RTL_W16(IntrStatus, tp->intr_event);
+	rtl_irq_disable(tp);
+	rtl_ack_events(tp, RTL_EVENT_NAPI | tp->event_slow);
 	RTL_R8(ChipCmd);
 }
 
@@ -1276,9 +1334,6 @@ static void __rtl8169_check_link_status(struct net_device *dev,
 					struct rtl8169_private *tp,
 					void __iomem *ioaddr, bool pm)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&tp->lock, flags);
 	if (tp->link_ok(ioaddr)) {
 		rtl_link_chg_patch(tp);
 		/* This is to cancel a scheduled suspend if there's one. */
@@ -1293,7 +1348,6 @@ static void __rtl8169_check_link_status(struct net_device *dev,
 		if (pm)
 			pm_schedule_suspend(&tp->pci_dev->dev, 5000);
 	}
-	spin_unlock_irqrestore(&tp->lock, flags);
 }
 
 static void rtl8169_check_link_status(struct net_device *dev,
@@ -1336,12 +1390,12 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	spin_lock_irq(&tp->lock);
+	rtl_lock_work(tp);
 
 	wol->supported = WAKE_ANY;
 	wol->wolopts = __rtl8169_get_wol(tp);
 
-	spin_unlock_irq(&tp->lock);
+	rtl_unlock_work(tp);
 }
 
 static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
@@ -1378,14 +1432,15 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	spin_lock_irq(&tp->lock);
+	rtl_lock_work(tp);
 
 	if (wol->wolopts)
 		tp->features |= RTL_FEATURE_WOL;
 	else
 		tp->features &= ~RTL_FEATURE_WOL;
 	__rtl8169_set_wol(tp, wol->wolopts);
-	spin_unlock_irq(&tp->lock);
+
+	rtl_unlock_work(tp);
 
 	device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts);
 
@@ -1540,15 +1595,14 @@ out:
 static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	unsigned long flags;
 	int ret;
 
 	del_timer_sync(&tp->timer);
 
-	spin_lock_irqsave(&tp->lock, flags);
+	rtl_lock_work(tp);
 	ret = rtl8169_set_speed(dev, cmd->autoneg, ethtool_cmd_speed(cmd),
 				cmd->duplex, cmd->advertising);
-	spin_unlock_irqrestore(&tp->lock, flags);
+	rtl_unlock_work(tp);
 
 	return ret;
 }
@@ -1568,14 +1622,12 @@ static netdev_features_t rtl8169_fix_features(struct net_device *dev,
 	return features;
 }
 
-static int rtl8169_set_features(struct net_device *dev,
-	netdev_features_t features)
+static void __rtl8169_set_features(struct net_device *dev,
+				   netdev_features_t features)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
 
-	spin_lock_irqsave(&tp->lock, flags);
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	if (features & NETIF_F_RXCSUM)
 		tp->cp_cmd |= RxChkSum;
@@ -1589,12 +1641,21 @@ static int rtl8169_set_features(struct net_device *dev,
 
 	RTL_W16(CPlusCmd, tp->cp_cmd);
 	RTL_R16(CPlusCmd);
+}
+
+static int rtl8169_set_features(struct net_device *dev,
+				netdev_features_t features)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
 
-	spin_unlock_irqrestore(&tp->lock, flags);
+	rtl_lock_work(tp);
+	__rtl8169_set_features(dev, features);
+	rtl_unlock_work(tp);
 
 	return 0;
 }
 
+
 static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
 				      struct sk_buff *skb)
 {
@@ -1643,14 +1704,12 @@ static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
 static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	unsigned long flags;
 	int rc;
 
-	spin_lock_irqsave(&tp->lock, flags);
-
+	rtl_lock_work(tp);
 	rc = tp->get_settings(dev, cmd);
+	rtl_unlock_work(tp);
 
-	spin_unlock_irqrestore(&tp->lock, flags);
 	return rc;
 }
 
@@ -1658,14 +1717,13 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 			     void *p)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	unsigned long flags;
 
 	if (regs->len > R8169_REGS_SIZE)
 		regs->len = R8169_REGS_SIZE;
 
-	spin_lock_irqsave(&tp->lock, flags);
+	rtl_lock_work(tp);
 	memcpy_fromio(p, tp->mmio_addr, regs->len);
-	spin_unlock_irqrestore(&tp->lock, flags);
+	rtl_unlock_work(tp);
 }
 
 static u32 rtl8169_get_msglevel(struct net_device *dev)
@@ -3182,18 +3240,14 @@ static void rtl_hw_phy_config(struct net_device *dev)
 	}
 }
 
-static void rtl8169_phy_timer(unsigned long __opaque)
+static void rtl_phy_work(struct rtl8169_private *tp)
 {
-	struct net_device *dev = (struct net_device *)__opaque;
-	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long timeout = RTL8169_PHY_TIMEOUT;
 
 	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
 
-	spin_lock_irq(&tp->lock);
-
 	if (tp->phy_reset_pending(tp)) {
 		/*
 		 * A busy loop could burn quite a few cycles on nowadays CPU.
@@ -3204,32 +3258,36 @@ static void rtl8169_phy_timer(unsigned long __opaque)
 	}
 
 	if (tp->link_ok(ioaddr))
-		goto out_unlock;
+		return;
 
-	netif_warn(tp, link, dev, "PHY reset until link up\n");
+	netif_warn(tp, link, tp->dev, "PHY reset until link up\n");
 
 	tp->phy_reset_enable(tp);
 
 out_mod_timer:
 	mod_timer(timer, jiffies + timeout);
-out_unlock:
-	spin_unlock_irq(&tp->lock);
+}
+
+static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag)
+{
+	if (!test_and_set_bit(flag, tp->wk.flags))
+		schedule_work(&tp->wk.work);
+}
+
+static void rtl8169_phy_timer(unsigned long __opaque)
+{
+	struct net_device *dev = (struct net_device *)__opaque;
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
 static void rtl8169_netpoll(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	struct pci_dev *pdev = tp->pci_dev;
 
-	disable_irq(pdev->irq);
-	rtl8169_interrupt(pdev->irq, dev);
-	enable_irq(pdev->irq);
+	rtl8169_interrupt(tp->pci_dev->irq, dev);
 }
 #endif
 
@@ -3310,7 +3368,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 	low  = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
 	high = addr[4] | (addr[5] << 8);
 
-	spin_lock_irq(&tp->lock);
+	rtl_lock_work(tp);
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 
@@ -3334,7 +3392,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
 
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
-	spin_unlock_irq(&tp->lock);
+	rtl_unlock_work(tp);
 }
 
 static int rtl_set_mac_address(struct net_device *dev, void *p)
@@ -3388,8 +3446,7 @@ static const struct rtl_cfg_info {
 	void (*hw_start)(struct net_device *);
 	unsigned int region;
 	unsigned int align;
-	u16 intr_event;
-	u16 napi_event;
+	u16 event_slow;
 	unsigned features;
 	u8 default_ver;
 } rtl_cfg_infos [] = {
@@ -3397,9 +3454,7 @@ static const struct rtl_cfg_info {
 		.hw_start	= rtl_hw_start_8169,
 		.region		= 1,
 		.align		= 0,
-		.intr_event	= SYSErr | LinkChg | RxOverflow |
-				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+		.event_slow	= SYSErr | LinkChg | RxOverflow | RxFIFOOver,
 		.features	= RTL_FEATURE_GMII,
 		.default_ver	= RTL_GIGA_MAC_VER_01,
 	},
@@ -3407,9 +3462,7 @@ static const struct rtl_cfg_info {
 		.hw_start	= rtl_hw_start_8168,
 		.region		= 2,
 		.align		= 8,
-		.intr_event	= SYSErr | LinkChg | RxOverflow |
-				  TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= TxErr | TxOK | RxOK | RxOverflow,
+		.event_slow	= SYSErr | LinkChg | RxOverflow,
 		.features	= RTL_FEATURE_GMII | RTL_FEATURE_MSI,
 		.default_ver	= RTL_GIGA_MAC_VER_11,
 	},
@@ -3417,9 +3470,8 @@ static const struct rtl_cfg_info {
 		.hw_start	= rtl_hw_start_8101,
 		.region		= 2,
 		.align		= 8,
-		.intr_event	= SYSErr | LinkChg | RxOverflow | PCSTimeout |
-				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+		.event_slow	= SYSErr | LinkChg | RxOverflow | RxFIFOOver |
+				  PCSTimeout,
 		.features	= RTL_FEATURE_MSI,
 		.default_ver	= RTL_GIGA_MAC_VER_13,
 	}
@@ -3824,23 +3876,21 @@ static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp)
 static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
-	struct pci_dev *pdev = tp->pci_dev;
 
 	RTL_W8(MaxTxPacketSize, 0x3f);
 	RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0);
 	RTL_W8(Config4, RTL_R8(Config4) | 0x01);
-	pci_write_config_byte(pdev, 0x79, 0x20);
+	rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT);
 }
 
 static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
-	struct pci_dev *pdev = tp->pci_dev;
 
 	RTL_W8(MaxTxPacketSize, 0x0c);
 	RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0);
 	RTL_W8(Config4, RTL_R8(Config4) & ~0x01);
-	pci_write_config_byte(pdev, 0x79, 0x50);
+	rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT);
 }
 
 static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp)
@@ -3958,8 +4008,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	dev = alloc_etherdev(sizeof (*tp));
 	if (!dev) {
-		if (netif_msg_drv(&debug))
-			dev_err(&pdev->dev, "unable to alloc new ethernet\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -4048,11 +4096,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	rtl_init_rxcfg(tp);
 
-	RTL_W16(IntrMask, 0x0000);
+	rtl_irq_disable(tp);
 
 	rtl_hw_reset(tp);
 
-	RTL_W16(IntrStatus, 0xffff);
+	rtl_ack_events(tp, 0xffff);
 
 	pci_set_master(pdev);
 
@@ -4098,7 +4146,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		tp->do_ioctl = rtl_xmii_ioctl;
 	}
 
-	spin_lock_init(&tp->lock);
+	mutex_init(&tp->wk.mutex);
 
 	/* Get MAC address */
 	for (i = 0; i < ETH_ALEN; i++)
@@ -4126,10 +4174,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		/* 8110SCd requires hardware Rx VLAN - disallow toggling */
 		dev->hw_features &= ~NETIF_F_HW_VLAN_RX;
 
-	tp->intr_mask = 0xffff;
 	tp->hw_start = cfg->hw_start;
-	tp->intr_event = cfg->intr_event;
-	tp->napi_event = cfg->napi_event;
+	tp->event_slow = cfg->event_slow;
 
 	tp->opts1_mask = (tp->mac_version != RTL_GIGA_MAC_VER_01) ?
 		~(RxBOVF | RxFOVF) : ~0;
@@ -4196,7 +4242,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 		rtl8168_driver_stop(tp);
 	}
 
-	cancel_delayed_work_sync(&tp->task);
+	cancel_work_sync(&tp->wk.work);
 
 	unregister_netdev(dev);
 
@@ -4257,6 +4303,8 @@ static void rtl_request_firmware(struct rtl8169_private *tp)
 		rtl_request_uncached_firmware(tp);
 }
 
+static void rtl_task(struct work_struct *);
+
 static int rtl8169_open(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -4284,7 +4332,7 @@ static int rtl8169_open(struct net_device *dev)
 	if (retval < 0)
 		goto err_free_rx_1;
 
-	INIT_DELAYED_WORK(&tp->task, NULL);
+	INIT_WORK(&tp->wk.work, rtl_task);
 
 	smp_mb();
 
@@ -4296,16 +4344,24 @@ static int rtl8169_open(struct net_device *dev)
 	if (retval < 0)
 		goto err_release_fw_2;
 
+	rtl_lock_work(tp);
+
+	set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+
 	napi_enable(&tp->napi);
 
 	rtl8169_init_phy(dev, tp);
 
-	rtl8169_set_features(dev, dev->features);
+	__rtl8169_set_features(dev, dev->features);
 
 	rtl_pll_power_up(tp);
 
 	rtl_hw_start(dev);
 
+	netif_start_queue(dev);
+
+	rtl_unlock_work(tp);
+
 	tp->saved_wolopts = 0;
 	pm_runtime_put_noidle(&pdev->dev);
 
@@ -4379,7 +4435,7 @@ static void rtl_hw_start(struct net_device *dev)
 
 	tp->hw_start(dev);
 
-	netif_start_queue(dev);
+	rtl_irq_enable_all(tp);
 }
 
 static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
@@ -4506,9 +4562,6 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	/* no early-rx interrupts */
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
-
-	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16(IntrMask, tp->intr_event);
 }
 
 static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits)
@@ -4888,8 +4941,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
 
 	/* Work around for RxFIFO overflow. */
 	if (tp->mac_version == RTL_GIGA_MAC_VER_11) {
-		tp->intr_event |= RxFIFOOver | PCSTimeout;
-		tp->intr_event &= ~RxOverflow;
+		tp->event_slow |= RxFIFOOver | PCSTimeout;
+		tp->event_slow &= ~RxOverflow;
 	}
 
 	rtl_set_rx_tx_desc_registers(tp, ioaddr);
@@ -4977,8 +5030,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
-
-	RTL_W16(IntrMask, tp->intr_event);
 }
 
 #define R810X_CPCMD_QUIRK_MASK (\
@@ -5077,10 +5128,8 @@ static void rtl_hw_start_8101(struct net_device *dev)
 	void __iomem *ioaddr = tp->mmio_addr;
 	struct pci_dev *pdev = tp->pci_dev;
 
-	if (tp->mac_version >= RTL_GIGA_MAC_VER_30) {
-		tp->intr_event &= ~RxFIFOOver;
-		tp->napi_event &= ~RxFIFOOver;
-	}
+	if (tp->mac_version >= RTL_GIGA_MAC_VER_30)
+		tp->event_slow &= ~RxFIFOOver;
 
 	if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
 	    tp->mac_version == RTL_GIGA_MAC_VER_16) {
@@ -5136,8 +5185,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
 	rtl_set_rx_mode(dev);
 
 	RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
-
-	RTL_W16(IntrMask, tp->intr_event);
 }
 
 static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
@@ -5330,92 +5377,34 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
 	tp->cur_tx = tp->dirty_tx = 0;
 }
 
-static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-
-	PREPARE_DELAYED_WORK(&tp->task, task);
-	schedule_delayed_work(&tp->task, 4);
-}
-
-static void rtl8169_wait_for_quiescence(struct net_device *dev)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-
-	synchronize_irq(dev->irq);
-
-	/* Wait for any pending NAPI task to complete */
-	napi_disable(&tp->napi);
-
-	rtl8169_irq_mask_and_ack(tp);
-
-	tp->intr_mask = 0xffff;
-	RTL_W16(IntrMask, tp->intr_event);
-	napi_enable(&tp->napi);
-}
-
-static void rtl8169_reinit_task(struct work_struct *work)
+static void rtl_reset_work(struct rtl8169_private *tp)
 {
-	struct rtl8169_private *tp =
-		container_of(work, struct rtl8169_private, task.work);
-	struct net_device *dev = tp->dev;
-	int ret;
-
-	rtnl_lock();
-
-	if (!netif_running(dev))
-		goto out_unlock;
-
-	rtl8169_wait_for_quiescence(dev);
-	rtl8169_close(dev);
-
-	ret = rtl8169_open(dev);
-	if (unlikely(ret < 0)) {
-		if (net_ratelimit())
-			netif_err(tp, drv, dev,
-				  "reinit failure (status = %d). Rescheduling\n",
-				  ret);
-		rtl8169_schedule_work(dev, rtl8169_reinit_task);
-	}
-
-out_unlock:
-	rtnl_unlock();
-}
-
-static void rtl8169_reset_task(struct work_struct *work)
-{
-	struct rtl8169_private *tp =
-		container_of(work, struct rtl8169_private, task.work);
 	struct net_device *dev = tp->dev;
 	int i;
 
-	rtnl_lock();
-
-	if (!netif_running(dev))
-		goto out_unlock;
+	napi_disable(&tp->napi);
+	netif_stop_queue(dev);
+	synchronize_sched();
 
 	rtl8169_hw_reset(tp);
 
-	rtl8169_wait_for_quiescence(dev);
-
 	for (i = 0; i < NUM_RX_DESC; i++)
 		rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz);
 
 	rtl8169_tx_clear(tp);
 	rtl8169_init_ring_indexes(tp);
 
+	napi_enable(&tp->napi);
 	rtl_hw_start(dev);
 	netif_wake_queue(dev);
 	rtl8169_check_link_status(dev, tp, tp->mmio_addr);
-
-out_unlock:
-	rtnl_unlock();
 }
 
 static void rtl8169_tx_timeout(struct net_device *dev)
 {
-	rtl8169_schedule_work(dev, rtl8169_reset_task);
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 }
 
 static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
@@ -5552,9 +5541,22 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 
 	RTL_W8(TxPoll, NPQ);
 
+	mmiowb();
+
 	if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
+		/* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
+		 * not miss a ring update when it notices a stopped queue.
+		 */
+		smp_wmb();
 		netif_stop_queue(dev);
-		smp_rmb();
+		/* Sync with rtl_tx:
+		 * - publish queue status and cur_tx ring index (write barrier)
+		 * - refresh dirty_tx ring index (read barrier).
+		 * May the current thread have a pessimistic view of the ring
+		 * status and forget to wake up queue, a racing rtl_tx thread
+		 * can't.
+		 */
+		smp_mb();
 		if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
 			netif_wake_queue(dev);
 	}
@@ -5618,12 +5620,10 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
 
 	rtl8169_hw_reset(tp);
 
-	rtl8169_schedule_work(dev, rtl8169_reinit_task);
+	rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 }
 
-static void rtl8169_tx_interrupt(struct net_device *dev,
-				 struct rtl8169_private *tp,
-				 void __iomem *ioaddr)
+static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
 {
 	unsigned int dirty_tx, tx_left;
 
@@ -5655,7 +5655,14 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
 
 	if (tp->dirty_tx != dirty_tx) {
 		tp->dirty_tx = dirty_tx;
-		smp_wmb();
+		/* Sync with rtl8169_start_xmit:
+		 * - publish dirty_tx ring index (write barrier)
+		 * - refresh cur_tx ring index and queue status (read barrier)
+		 * May the current thread miss the stopped queue condition,
+		 * a racing xmit thread can only have a right view of the
+		 * ring status.
+		 */
+		smp_mb();
 		if (netif_queue_stopped(dev) &&
 		    (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
 			netif_wake_queue(dev);
@@ -5666,9 +5673,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
 		 * of start_xmit activity is detected (if it is not detected,
 		 * it is slow enough). -- FR
 		 */
-		smp_rmb();
-		if (tp->cur_tx != dirty_tx)
+		if (tp->cur_tx != dirty_tx) {
+			void __iomem *ioaddr = tp->mmio_addr;
+
 			RTL_W8(TxPoll, NPQ);
+		}
 	}
 }
 
@@ -5707,9 +5716,7 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data,
 	return skb;
 }
 
-static int rtl8169_rx_interrupt(struct net_device *dev,
-				struct rtl8169_private *tp,
-				void __iomem *ioaddr, u32 budget)
+static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget)
 {
 	unsigned int cur_rx, rx_left;
 	unsigned int count;
@@ -5737,7 +5744,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
 			if (status & RxCRC)
 				dev->stats.rx_crc_errors++;
 			if (status & RxFOVF) {
-				rtl8169_schedule_work(dev, rtl8169_reset_task);
+				rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 				dev->stats.rx_fifo_errors++;
 			}
 			rtl8169_mark_to_asic(desc, rx_buf_sz);
@@ -5798,101 +5805,120 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
 {
 	struct net_device *dev = dev_instance;
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
 	int handled = 0;
-	int status;
+	u16 status;
 
-	/* loop handling interrupts until we have no new ones or
-	 * we hit a invalid/hotplug case.
-	 */
-	status = RTL_R16(IntrStatus);
-	while (status && status != 0xffff) {
-		status &= tp->intr_event;
-		if (!status)
-			break;
+	status = rtl_get_events(tp);
+	if (status && status != 0xffff) {
+		status &= RTL_EVENT_NAPI | tp->event_slow;
+		if (status) {
+			handled = 1;
 
-		handled = 1;
+			rtl_irq_disable(tp);
+			napi_schedule(&tp->napi);
+		}
+	}
+	return IRQ_RETVAL(handled);
+}
 
-		/* Handle all of the error cases first. These will reset
-		 * the chip, so just exit the loop.
-		 */
-		if (unlikely(!netif_running(dev))) {
-			rtl8169_hw_reset(tp);
+/*
+ * Workqueue context.
+ */
+static void rtl_slow_event_work(struct rtl8169_private *tp)
+{
+	struct net_device *dev = tp->dev;
+	u16 status;
+
+	status = rtl_get_events(tp) & tp->event_slow;
+	rtl_ack_events(tp, status);
+
+	if (unlikely(status & RxFIFOOver)) {
+		switch (tp->mac_version) {
+		/* Work around for rx fifo overflow */
+		case RTL_GIGA_MAC_VER_11:
+			netif_stop_queue(dev);
+			/* XXX - Hack alert. See rtl_task(). */
+			set_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags);
+		default:
 			break;
 		}
+	}
 
-		if (unlikely(status & RxFIFOOver)) {
-			switch (tp->mac_version) {
-			/* Work around for rx fifo overflow */
-			case RTL_GIGA_MAC_VER_11:
-				netif_stop_queue(dev);
-				rtl8169_tx_timeout(dev);
-				goto done;
-			default:
-				break;
-			}
-		}
+	if (unlikely(status & SYSErr))
+		rtl8169_pcierr_interrupt(dev);
 
-		if (unlikely(status & SYSErr)) {
-			rtl8169_pcierr_interrupt(dev);
-			break;
-		}
+	if (status & LinkChg)
+		__rtl8169_check_link_status(dev, tp, tp->mmio_addr, true);
 
-		if (status & LinkChg)
-			__rtl8169_check_link_status(dev, tp, ioaddr, true);
+	napi_disable(&tp->napi);
+	rtl_irq_disable(tp);
 
-		/* We need to see the lastest version of tp->intr_mask to
-		 * avoid ignoring an MSI interrupt and having to wait for
-		 * another event which may never come.
-		 */
-		smp_rmb();
-		if (status & tp->intr_mask & tp->napi_event) {
-			RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
-			tp->intr_mask = ~tp->napi_event;
-
-			if (likely(napi_schedule_prep(&tp->napi)))
-				__napi_schedule(&tp->napi);
-			else
-				netif_info(tp, intr, dev,
-					   "interrupt %04x in poll\n", status);
-		}
+	napi_enable(&tp->napi);
+	napi_schedule(&tp->napi);
+}
 
-		/* We only get a new MSI interrupt when all active irq
-		 * sources on the chip have been acknowledged. So, ack
-		 * everything we've seen and check if new sources have become
-		 * active to avoid blocking all interrupts from the chip.
-		 */
-		RTL_W16(IntrStatus,
-			(status & RxFIFOOver) ? (status | RxOverflow) : status);
-		status = RTL_R16(IntrStatus);
+static void rtl_task(struct work_struct *work)
+{
+	static const struct {
+		int bitnr;
+		void (*action)(struct rtl8169_private *);
+	} rtl_work[] = {
+		/* XXX - keep rtl_slow_event_work() as first element. */
+		{ RTL_FLAG_TASK_SLOW_PENDING,	rtl_slow_event_work },
+		{ RTL_FLAG_TASK_RESET_PENDING,	rtl_reset_work },
+		{ RTL_FLAG_TASK_PHY_PENDING,	rtl_phy_work }
+	};
+	struct rtl8169_private *tp =
+		container_of(work, struct rtl8169_private, wk.work);
+	struct net_device *dev = tp->dev;
+	int i;
+
+	rtl_lock_work(tp);
+
+	if (!netif_running(dev) ||
+	    !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags))
+		goto out_unlock;
+
+	for (i = 0; i < ARRAY_SIZE(rtl_work); i++) {
+		bool pending;
+
+		pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags);
+		if (pending)
+			rtl_work[i].action(tp);
 	}
-done:
-	return IRQ_RETVAL(handled);
+
+out_unlock:
+	rtl_unlock_work(tp);
 }
 
 static int rtl8169_poll(struct napi_struct *napi, int budget)
 {
 	struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
 	struct net_device *dev = tp->dev;
-	void __iomem *ioaddr = tp->mmio_addr;
-	int work_done;
+	u16 enable_mask = RTL_EVENT_NAPI | tp->event_slow;
+	int work_done= 0;
+	u16 status;
+
+	status = rtl_get_events(tp);
+	rtl_ack_events(tp, status & ~tp->event_slow);
 
-	work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget);
-	rtl8169_tx_interrupt(dev, tp, ioaddr);
+	if (status & RTL_EVENT_NAPI_RX)
+		work_done = rtl_rx(dev, tp, (u32) budget);
+
+	if (status & RTL_EVENT_NAPI_TX)
+		rtl_tx(dev, tp);
+
+	if (status & tp->event_slow) {
+		enable_mask &= ~tp->event_slow;
+
+		rtl_schedule_task(tp, RTL_FLAG_TASK_SLOW_PENDING);
+	}
 
 	if (work_done < budget) {
 		napi_complete(napi);
 
-		/* We need for force the visibility of tp->intr_mask
-		 * for other CPUs, as we can loose an MSI interrupt
-		 * and potentially wait for a retransmit timeout if we don't.
-		 * The posted write to IntrMask is safe, as it will
-		 * eventually make it to the chip and we won't loose anything
-		 * until it does.
-		 */
-		tp->intr_mask = 0xffff;
-		wmb();
-		RTL_W16(IntrMask, tp->intr_event);
+		rtl_irq_enable(tp, enable_mask);
+		mmiowb();
 	}
 
 	return work_done;
@@ -5916,26 +5942,19 @@ static void rtl8169_down(struct net_device *dev)
 
 	del_timer_sync(&tp->timer);
 
-	netif_stop_queue(dev);
-
 	napi_disable(&tp->napi);
-
-	spin_lock_irq(&tp->lock);
+	netif_stop_queue(dev);
 
 	rtl8169_hw_reset(tp);
 	/*
 	 * At this point device interrupts can not be enabled in any function,
-	 * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task,
-	 * rtl8169_reinit_task) and napi is disabled (rtl8169_poll).
+	 * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task)
+	 * and napi is disabled (rtl8169_poll).
 	 */
 	rtl8169_rx_missed(dev, ioaddr);
 
-	spin_unlock_irq(&tp->lock);
-
-	synchronize_irq(dev->irq);
-
 	/* Give a racing hard_start_xmit a few cycles to complete. */
-	synchronize_sched();  /* FIXME: should this be synchronize_irq()? */
+	synchronize_sched();
 
 	rtl8169_tx_clear(tp);
 
@@ -5954,7 +5973,11 @@ static int rtl8169_close(struct net_device *dev)
 	/* Update counters before going down */
 	rtl8169_update_counters(dev);
 
+	rtl_lock_work(tp);
+	clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+
 	rtl8169_down(dev);
+	rtl_unlock_work(tp);
 
 	free_irq(dev->irq, dev);
 
@@ -5974,7 +5997,6 @@ static void rtl_set_rx_mode(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int rx_mode;
 	u32 tmp = 0;
@@ -6003,8 +6025,6 @@ static void rtl_set_rx_mode(struct net_device *dev)
 		}
 	}
 
-	spin_lock_irqsave(&tp->lock, flags);
-
 	tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode;
 
 	if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
@@ -6018,8 +6038,6 @@ static void rtl_set_rx_mode(struct net_device *dev)
 	RTL_W32(MAR0 + 0, mc_filter[0]);
 
 	RTL_W32(RxConfig, tmp);
-
-	spin_unlock_irqrestore(&tp->lock, flags);
 }
 
 /**
@@ -6032,13 +6050,9 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
 
-	if (netif_running(dev)) {
-		spin_lock_irqsave(&tp->lock, flags);
+	if (netif_running(dev))
 		rtl8169_rx_missed(dev, ioaddr);
-		spin_unlock_irqrestore(&tp->lock, flags);
-	}
 
 	return &dev->stats;
 }
@@ -6050,10 +6064,15 @@ static void rtl8169_net_suspend(struct net_device *dev)
 	if (!netif_running(dev))
 		return;
 
-	rtl_pll_power_down(tp);
-
 	netif_device_detach(dev);
 	netif_stop_queue(dev);
+
+	rtl_lock_work(tp);
+	napi_disable(&tp->napi);
+	clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+	rtl_unlock_work(tp);
+
+	rtl_pll_power_down(tp);
 }
 
 #ifdef CONFIG_PM
@@ -6076,7 +6095,9 @@ static void __rtl8169_resume(struct net_device *dev)
 
 	rtl_pll_power_up(tp);
 
-	rtl8169_schedule_work(dev, rtl8169_reset_task);
+	set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags);
+
+	rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 }
 
 static int rtl8169_resume(struct device *device)
@@ -6102,10 +6123,10 @@ static int rtl8169_runtime_suspend(struct device *device)
 	if (!tp->TxDescArray)
 		return 0;
 
-	spin_lock_irq(&tp->lock);
+	rtl_lock_work(tp);
 	tp->saved_wolopts = __rtl8169_get_wol(tp);
 	__rtl8169_set_wol(tp, WAKE_ANY);
-	spin_unlock_irq(&tp->lock);
+	rtl_unlock_work(tp);
 
 	rtl8169_net_suspend(dev);
 
@@ -6121,10 +6142,10 @@ static int rtl8169_runtime_resume(struct device *device)
 	if (!tp->TxDescArray)
 		return 0;
 
-	spin_lock_irq(&tp->lock);
+	rtl_lock_work(tp);
 	__rtl8169_set_wol(tp, tp->saved_wolopts);
 	tp->saved_wolopts = 0;
-	spin_unlock_irq(&tp->lock);
+	rtl_unlock_work(tp);
 
 	rtl8169_init_phy(dev, tp);
 
@@ -6192,12 +6213,8 @@ static void rtl_shutdown(struct pci_dev *pdev)
 	/* Restore original MAC address */
 	rtl_rar_set(tp, dev->perm_addr);
 
-	spin_lock_irq(&tp->lock);
-
 	rtl8169_hw_reset(tp);
 
-	spin_unlock_irq(&tp->lock);
-
 	if (system_state == SYSTEM_POWER_OFF) {
 		if (__rtl8169_get_wol(tp) & WAKE_ANY) {
 			rtl_wol_suspend_quirk(tp);
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 87b6501..8615961 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -34,7 +34,6 @@
 #include <linux/phy.h>
 #include <linux/cache.h>
 #include <linux/io.h>
-#include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/ethtool.h>
@@ -269,6 +268,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
 	.rpadir_value   = 2 << 16,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.tsu		= 1,
 };
 
 static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
@@ -654,13 +654,12 @@ static void sh_eth_ring_format(struct net_device *ndev)
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		/* skb */
 		mdp->rx_skbuff[i] = NULL;
-		skb = dev_alloc_skb(mdp->rx_buf_sz);
+		skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
 		mdp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
-		dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+		dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz,
 				DMA_FROM_DEVICE);
-		skb->dev = ndev; /* Mark as being used by this device. */
 		sh_eth_set_receive_align(skb);
 
 		/* RX descriptor */
@@ -883,8 +882,8 @@ static int sh_eth_txfree(struct net_device *ndev)
 		if (entry >= TX_RING_SIZE - 1)
 			txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
 
-		mdp->stats.tx_packets++;
-		mdp->stats.tx_bytes += txdesc->buffer_length;
+		ndev->stats.tx_packets++;
+		ndev->stats.tx_bytes += txdesc->buffer_length;
 	}
 	return freeNum;
 }
@@ -910,23 +909,23 @@ static int sh_eth_rx(struct net_device *ndev)
 			break;
 
 		if (!(desc_status & RDFEND))
-			mdp->stats.rx_length_errors++;
+			ndev->stats.rx_length_errors++;
 
 		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
 				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
-			mdp->stats.rx_errors++;
+			ndev->stats.rx_errors++;
 			if (desc_status & RD_RFS1)
-				mdp->stats.rx_crc_errors++;
+				ndev->stats.rx_crc_errors++;
 			if (desc_status & RD_RFS2)
-				mdp->stats.rx_frame_errors++;
+				ndev->stats.rx_frame_errors++;
 			if (desc_status & RD_RFS3)
-				mdp->stats.rx_length_errors++;
+				ndev->stats.rx_length_errors++;
 			if (desc_status & RD_RFS4)
-				mdp->stats.rx_length_errors++;
+				ndev->stats.rx_length_errors++;
 			if (desc_status & RD_RFS6)
-				mdp->stats.rx_missed_errors++;
+				ndev->stats.rx_missed_errors++;
 			if (desc_status & RD_RFS10)
-				mdp->stats.rx_over_errors++;
+				ndev->stats.rx_over_errors++;
 		} else {
 			if (!mdp->cd->hw_swap)
 				sh_eth_soft_swap(
@@ -939,8 +938,8 @@ static int sh_eth_rx(struct net_device *ndev)
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, ndev);
 			netif_rx(skb);
-			mdp->stats.rx_packets++;
-			mdp->stats.rx_bytes += pkt_len;
+			ndev->stats.rx_packets++;
+			ndev->stats.rx_bytes += pkt_len;
 		}
 		rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
 		entry = (++mdp->cur_rx) % RX_RING_SIZE;
@@ -955,13 +954,12 @@ static int sh_eth_rx(struct net_device *ndev)
 		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
 
 		if (mdp->rx_skbuff[entry] == NULL) {
-			skb = dev_alloc_skb(mdp->rx_buf_sz);
+			skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
 			mdp->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break;	/* Better luck next round. */
-			dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+			dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz,
 					DMA_FROM_DEVICE);
-			skb->dev = ndev;
 			sh_eth_set_receive_align(skb);
 
 			skb_checksum_none_assert(skb);
@@ -1009,7 +1007,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		felic_stat = sh_eth_read(ndev, ECSR);
 		sh_eth_write(ndev, felic_stat, ECSR);	/* clear int */
 		if (felic_stat & ECSR_ICD)
-			mdp->stats.tx_carrier_errors++;
+			ndev->stats.tx_carrier_errors++;
 		if (felic_stat & ECSR_LCHNG) {
 			/* Link Changed */
 			if (mdp->cd->no_psr || mdp->no_ether_link) {
@@ -1042,7 +1040,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 	if (intr_status & EESR_TWB) {
 		/* Write buck end. unused write back interrupt */
 		if (intr_status & EESR_TABT)	/* Transmit Abort int */
-			mdp->stats.tx_aborted_errors++;
+			ndev->stats.tx_aborted_errors++;
 			if (netif_msg_tx_err(mdp))
 				dev_err(&ndev->dev, "Transmit Abort\n");
 	}
@@ -1051,7 +1049,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		/* Receive Abort int */
 		if (intr_status & EESR_RFRMER) {
 			/* Receive Frame Overflow int */
-			mdp->stats.rx_frame_errors++;
+			ndev->stats.rx_frame_errors++;
 			if (netif_msg_rx_err(mdp))
 				dev_err(&ndev->dev, "Receive Abort\n");
 		}
@@ -1059,21 +1057,21 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 
 	if (intr_status & EESR_TDE) {
 		/* Transmit Descriptor Empty int */
-		mdp->stats.tx_fifo_errors++;
+		ndev->stats.tx_fifo_errors++;
 		if (netif_msg_tx_err(mdp))
 			dev_err(&ndev->dev, "Transmit Descriptor Empty\n");
 	}
 
 	if (intr_status & EESR_TFE) {
 		/* FIFO under flow */
-		mdp->stats.tx_fifo_errors++;
+		ndev->stats.tx_fifo_errors++;
 		if (netif_msg_tx_err(mdp))
 			dev_err(&ndev->dev, "Transmit FIFO Under flow\n");
 	}
 
 	if (intr_status & EESR_RDE) {
 		/* Receive Descriptor Empty int */
-		mdp->stats.rx_over_errors++;
+		ndev->stats.rx_over_errors++;
 
 		if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R)
 			sh_eth_write(ndev, EDRRR_R, EDRRR);
@@ -1083,14 +1081,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 
 	if (intr_status & EESR_RFE) {
 		/* Receive FIFO Overflow int */
-		mdp->stats.rx_fifo_errors++;
+		ndev->stats.rx_fifo_errors++;
 		if (netif_msg_rx_err(mdp))
 			dev_err(&ndev->dev, "Receive FIFO Overflow\n");
 	}
 
 	if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) {
 		/* Address Error */
-		mdp->stats.tx_fifo_errors++;
+		ndev->stats.tx_fifo_errors++;
 		if (netif_msg_tx_err(mdp))
 			dev_err(&ndev->dev, "Address Error\n");
 	}
@@ -1447,7 +1445,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
 	       " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));
 
 	/* tx_errors count up */
-	mdp->stats.tx_errors++;
+	ndev->stats.tx_errors++;
 
 	/* timer off */
 	del_timer_sync(&mdp->timer);
@@ -1569,27 +1567,27 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
 
 	pm_runtime_get_sync(&mdp->pdev->dev);
 
-	mdp->stats.tx_dropped += sh_eth_read(ndev, TROCR);
+	ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR);
 	sh_eth_write(ndev, 0, TROCR);	/* (write clear) */
-	mdp->stats.collisions += sh_eth_read(ndev, CDCR);
+	ndev->stats.collisions += sh_eth_read(ndev, CDCR);
 	sh_eth_write(ndev, 0, CDCR);	/* (write clear) */
-	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
+	ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
 	sh_eth_write(ndev, 0, LCCR);	/* (write clear) */
 	if (sh_eth_is_gether(mdp)) {
-		mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
+		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
 		sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
-		mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
+		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
 		sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
 	} else {
-		mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
+		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
 		sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
 	}
 	pm_runtime_put_sync(&mdp->pdev->dev);
 
-	return &mdp->stats;
+	return &ndev->stats;
 }
 
-/* ioctl to device funciotn*/
+/* ioctl to device function */
 static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
 				int cmd)
 {
@@ -1606,18 +1604,345 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
 }
 
 #if defined(SH_ETH_HAS_TSU)
+/* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */
+static void *sh_eth_tsu_get_post_reg_offset(struct sh_eth_private *mdp,
+					    int entry)
+{
+	return sh_eth_tsu_get_offset(mdp, TSU_POST1) + (entry / 8 * 4);
+}
+
+static u32 sh_eth_tsu_get_post_mask(int entry)
+{
+	return 0x0f << (28 - ((entry % 8) * 4));
+}
+
+static u32 sh_eth_tsu_get_post_bit(struct sh_eth_private *mdp, int entry)
+{
+	return (0x08 >> (mdp->port << 1)) << (28 - ((entry % 8) * 4));
+}
+
+static void sh_eth_tsu_enable_cam_entry_post(struct net_device *ndev,
+					     int entry)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	u32 tmp;
+	void *reg_offset;
+
+	reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry);
+	tmp = ioread32(reg_offset);
+	iowrite32(tmp | sh_eth_tsu_get_post_bit(mdp, entry), reg_offset);
+}
+
+static bool sh_eth_tsu_disable_cam_entry_post(struct net_device *ndev,
+					      int entry)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	u32 post_mask, ref_mask, tmp;
+	void *reg_offset;
+
+	reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry);
+	post_mask = sh_eth_tsu_get_post_mask(entry);
+	ref_mask = sh_eth_tsu_get_post_bit(mdp, entry) & ~post_mask;
+
+	tmp = ioread32(reg_offset);
+	iowrite32(tmp & ~post_mask, reg_offset);
+
+	/* If other port enables, the function returns "true" */
+	return tmp & ref_mask;
+}
+
+static int sh_eth_tsu_busy(struct net_device *ndev)
+{
+	int timeout = SH_ETH_TSU_TIMEOUT_MS * 100;
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+
+	while ((sh_eth_tsu_read(mdp, TSU_ADSBSY) & TSU_ADSBSY_0)) {
+		udelay(10);
+		timeout--;
+		if (timeout <= 0) {
+			dev_err(&ndev->dev, "%s: timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int sh_eth_tsu_write_entry(struct net_device *ndev, void *reg,
+				  const u8 *addr)
+{
+	u32 val;
+
+	val = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
+	iowrite32(val, reg);
+	if (sh_eth_tsu_busy(ndev) < 0)
+		return -EBUSY;
+
+	val = addr[4] << 8 | addr[5];
+	iowrite32(val, reg + 4);
+	if (sh_eth_tsu_busy(ndev) < 0)
+		return -EBUSY;
+
+	return 0;
+}
+
+static void sh_eth_tsu_read_entry(void *reg, u8 *addr)
+{
+	u32 val;
+
+	val = ioread32(reg);
+	addr[0] = (val >> 24) & 0xff;
+	addr[1] = (val >> 16) & 0xff;
+	addr[2] = (val >> 8) & 0xff;
+	addr[3] = val & 0xff;
+	val = ioread32(reg + 4);
+	addr[4] = (val >> 8) & 0xff;
+	addr[5] = val & 0xff;
+}
+
+
+static int sh_eth_tsu_find_entry(struct net_device *ndev, const u8 *addr)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
+	int i;
+	u8 c_addr[ETH_ALEN];
+
+	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) {
+		sh_eth_tsu_read_entry(reg_offset, c_addr);
+		if (memcmp(addr, c_addr, ETH_ALEN) == 0)
+			return i;
+	}
+
+	return -ENOENT;
+}
+
+static int sh_eth_tsu_find_empty(struct net_device *ndev)
+{
+	u8 blank[ETH_ALEN];
+	int entry;
+
+	memset(blank, 0, sizeof(blank));
+	entry = sh_eth_tsu_find_entry(ndev, blank);
+	return (entry < 0) ? -ENOMEM : entry;
+}
+
+static int sh_eth_tsu_disable_cam_entry_table(struct net_device *ndev,
+					      int entry)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
+	int ret;
+	u8 blank[ETH_ALEN];
+
+	sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) &
+			 ~(1 << (31 - entry)), TSU_TEN);
+
+	memset(blank, 0, sizeof(blank));
+	ret = sh_eth_tsu_write_entry(ndev, reg_offset + entry * 8, blank);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int sh_eth_tsu_add_entry(struct net_device *ndev, const u8 *addr)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
+	int i, ret;
+
+	if (!mdp->cd->tsu)
+		return 0;
+
+	i = sh_eth_tsu_find_entry(ndev, addr);
+	if (i < 0) {
+		/* No entry found, create one */
+		i = sh_eth_tsu_find_empty(ndev);
+		if (i < 0)
+			return -ENOMEM;
+		ret = sh_eth_tsu_write_entry(ndev, reg_offset + i * 8, addr);
+		if (ret < 0)
+			return ret;
+
+		/* Enable the entry */
+		sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) |
+				 (1 << (31 - i)), TSU_TEN);
+	}
+
+	/* Entry found or created, enable POST */
+	sh_eth_tsu_enable_cam_entry_post(ndev, i);
+
+	return 0;
+}
+
+static int sh_eth_tsu_del_entry(struct net_device *ndev, const u8 *addr)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int i, ret;
+
+	if (!mdp->cd->tsu)
+		return 0;
+
+	i = sh_eth_tsu_find_entry(ndev, addr);
+	if (i) {
+		/* Entry found */
+		if (sh_eth_tsu_disable_cam_entry_post(ndev, i))
+			goto done;
+
+		/* Disable the entry if both ports was disabled */
+		ret = sh_eth_tsu_disable_cam_entry_table(ndev, i);
+		if (ret < 0)
+			return ret;
+	}
+done:
+	return 0;
+}
+
+static int sh_eth_tsu_purge_all(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int i, ret;
+
+	if (unlikely(!mdp->cd->tsu))
+		return 0;
+
+	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) {
+		if (sh_eth_tsu_disable_cam_entry_post(ndev, i))
+			continue;
+
+		/* Disable the entry if both ports was disabled */
+		ret = sh_eth_tsu_disable_cam_entry_table(ndev, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void sh_eth_tsu_purge_mcast(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	u8 addr[ETH_ALEN];
+	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
+	int i;
+
+	if (unlikely(!mdp->cd->tsu))
+		return;
+
+	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) {
+		sh_eth_tsu_read_entry(reg_offset, addr);
+		if (is_multicast_ether_addr(addr))
+			sh_eth_tsu_del_entry(ndev, addr);
+	}
+}
+
 /* Multicast reception directions set */
 static void sh_eth_set_multicast_list(struct net_device *ndev)
 {
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	u32 ecmr_bits;
+	int mcast_all = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdp->lock, flags);
+	/*
+	 * Initial condition is MCT = 1, PRM = 0.
+	 * Depending on ndev->flags, set PRM or clear MCT
+	 */
+	ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT;
+
+	if (!(ndev->flags & IFF_MULTICAST)) {
+		sh_eth_tsu_purge_mcast(ndev);
+		mcast_all = 1;
+	}
+	if (ndev->flags & IFF_ALLMULTI) {
+		sh_eth_tsu_purge_mcast(ndev);
+		ecmr_bits &= ~ECMR_MCT;
+		mcast_all = 1;
+	}
+
 	if (ndev->flags & IFF_PROMISC) {
-		/* Set promiscuous. */
-		sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) |
-				ECMR_PRM, ECMR);
+		sh_eth_tsu_purge_all(ndev);
+		ecmr_bits = (ecmr_bits & ~ECMR_MCT) | ECMR_PRM;
+	} else if (mdp->cd->tsu) {
+		struct netdev_hw_addr *ha;
+		netdev_for_each_mc_addr(ha, ndev) {
+			if (mcast_all && is_multicast_ether_addr(ha->addr))
+				continue;
+
+			if (sh_eth_tsu_add_entry(ndev, ha->addr) < 0) {
+				if (!mcast_all) {
+					sh_eth_tsu_purge_mcast(ndev);
+					ecmr_bits &= ~ECMR_MCT;
+					mcast_all = 1;
+				}
+			}
+		}
 	} else {
 		/* Normal, unicast/broadcast-only mode. */
-		sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) |
-				ECMR_MCT, ECMR);
+		ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT;
 	}
+
+	/* update the ethernet mode */
+	sh_eth_write(ndev, ecmr_bits, ECMR);
+
+	spin_unlock_irqrestore(&mdp->lock, flags);
+}
+
+static int sh_eth_get_vtag_index(struct sh_eth_private *mdp)
+{
+	if (!mdp->port)
+		return TSU_VTAG0;
+	else
+		return TSU_VTAG1;
+}
+
+static int sh_eth_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int vtag_reg_index = sh_eth_get_vtag_index(mdp);
+
+	if (unlikely(!mdp->cd->tsu))
+		return -EPERM;
+
+	/* No filtering if vid = 0 */
+	if (!vid)
+		return 0;
+
+	mdp->vlan_num_ids++;
+
+	/*
+	 * The controller has one VLAN tag HW filter. So, if the filter is
+	 * already enabled, the driver disables it and the filte
+	 */
+	if (mdp->vlan_num_ids > 1) {
+		/* disable VLAN filter */
+		sh_eth_tsu_write(mdp, 0, vtag_reg_index);
+		return 0;
+	}
+
+	sh_eth_tsu_write(mdp, TSU_VTAG_ENABLE | (vid & TSU_VTAG_VID_MASK),
+			 vtag_reg_index);
+
+	return 0;
+}
+
+static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int vtag_reg_index = sh_eth_get_vtag_index(mdp);
+
+	if (unlikely(!mdp->cd->tsu))
+		return -EPERM;
+
+	/* No filtering if vid = 0 */
+	if (!vid)
+		return 0;
+
+	mdp->vlan_num_ids--;
+	sh_eth_tsu_write(mdp, 0, vtag_reg_index);
+
+	return 0;
 }
 #endif /* SH_ETH_HAS_TSU */
 
@@ -1768,6 +2093,8 @@ static const struct net_device_ops sh_eth_netdev_ops = {
 	.ndo_get_stats		= sh_eth_get_stats,
 #if defined(SH_ETH_HAS_TSU)
 	.ndo_set_rx_mode	= sh_eth_set_multicast_list,
+	.ndo_vlan_rx_add_vid	= sh_eth_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= sh_eth_vlan_rx_kill_vid,
 #endif
 	.ndo_tx_timeout		= sh_eth_tx_timeout,
 	.ndo_do_ioctl		= sh_eth_do_ioctl,
@@ -1794,7 +2121,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 
 	ndev = alloc_etherdev(sizeof(struct sh_eth_private));
 	if (!ndev) {
-		dev_err(&pdev->dev, "Could not allocate device.\n");
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -1862,18 +2188,22 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	/* read and set MAC address */
 	read_mac_address(ndev, pd->mac_addr);
 
-	/* First device only init */
-	if (!devno) {
-		if (mdp->cd->tsu) {
-			struct resource *rtsu;
-			rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-			if (!rtsu) {
-				dev_err(&pdev->dev, "Not found TSU resource\n");
-				goto out_release;
-			}
-			mdp->tsu_addr = ioremap(rtsu->start,
-						resource_size(rtsu));
+	/* ioremap the TSU registers */
+	if (mdp->cd->tsu) {
+		struct resource *rtsu;
+		rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		if (!rtsu) {
+			dev_err(&pdev->dev, "Not found TSU resource\n");
+			goto out_release;
 		}
+		mdp->tsu_addr = ioremap(rtsu->start,
+					resource_size(rtsu));
+		mdp->port = devno % 2;
+		ndev->features = NETIF_F_HW_VLAN_FILTER;
+	}
+
+	/* initialize first or needed device */
+	if (!devno || pd->needs_init) {
 		if (mdp->cd->chip_reset)
 			mdp->cd->chip_reset(ndev);
 
@@ -1922,7 +2252,8 @@ static int sh_eth_drv_remove(struct platform_device *pdev)
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
-	iounmap(mdp->tsu_addr);
+	if (mdp->cd->tsu)
+		iounmap(mdp->tsu_addr);
 	sh_mdio_release(ndev);
 	unregister_netdev(ndev);
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index cdbd844..57dc262 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -29,6 +29,8 @@
 #define RX_RING_SIZE	64	/* Rx ring size */
 #define ETHERSMALL		60
 #define PKT_BUF_SZ		1538
+#define SH_ETH_TSU_TIMEOUT_MS	500
+#define SH_ETH_TSU_CAM_ENTRIES	32
 
 enum {
 	/* E-DMAC registers */
@@ -677,6 +679,10 @@ enum TSU_FWSLC_BIT {
 	TSU_FWSLC_CAMSEL11 = 0x0002, TSU_FWSLC_CAMSEL10 = 0x0001,
 };
 
+/* TSU_VTAGn */
+#define TSU_VTAG_ENABLE		0x80000000
+#define TSU_VTAG_VID_MASK	0x00000fff
+
 /*
  * The sh ether Tx buffer descriptors.
  * This structure should be 20 bytes.
@@ -759,7 +765,6 @@ struct sh_eth_private {
 	struct sh_eth_txdesc *tx_ring;
 	struct sk_buff **rx_skbuff;
 	struct sk_buff **tx_skbuff;
-	struct net_device_stats stats;
 	struct timer_list timer;
 	spinlock_t lock;
 	u32 cur_rx, dirty_rx;	/* Producer/consumer ring indices */
@@ -779,6 +784,8 @@ struct sh_eth_private {
 	char post_rx;		/* POST receive */
 	char post_fw;		/* POST forward */
 	struct net_device_stats tsu_stats;	/* TSU forward status */
+	int port;		/* for TSU */
+	int vlan_num_ids;	/* for VLAN tag filter */
 
 	unsigned no_ether_link:1;
 	unsigned ether_link_active_low:1;
@@ -812,6 +819,12 @@ static inline unsigned long sh_eth_read(struct net_device *ndev,
 	return ioread32(mdp->addr + mdp->reg_offset[enum_index]);
 }
 
+static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp,
+					  int enum_index)
+{
+	return mdp->tsu_addr + mdp->reg_offset[enum_index];
+}
+
 static inline void sh_eth_tsu_write(struct sh_eth_private *mdp,
 				unsigned long data, int enum_index)
 {
diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c
index 22e9c01..1895605 100644
--- a/drivers/net/ethernet/s6gmac.c
+++ b/drivers/net/ethernet/s6gmac.c
@@ -370,12 +370,13 @@ struct s6gmac {
 	} link;
 };
 
-static void s6gmac_rx_fillfifo(struct s6gmac *pd)
+static void s6gmac_rx_fillfifo(struct net_device *dev)
 {
+	struct s6gmac *pd = netdev_priv(dev);
 	struct sk_buff *skb;
 	while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) &&
 	       (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) &&
-	       (skb = dev_alloc_skb(S6_MAX_FRLEN + 2))) {
+	       (skb = netdev_alloc_skb(dev, S6_MAX_FRLEN + 2))) {
 		pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb;
 		s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan,
 			pd->io, (u32)skb->data, S6_MAX_FRLEN);
@@ -514,7 +515,7 @@ static irqreturn_t s6gmac_interrupt(int irq, void *dev_id)
 	spin_lock(&pd->lock);
 	if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan))
 		s6gmac_rx_interrupt(dev);
-	s6gmac_rx_fillfifo(pd);
+	s6gmac_rx_fillfifo(dev);
 	if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan))
 		s6gmac_tx_interrupt(dev);
 	s6gmac_stats_interrupt(pd, 0);
@@ -894,7 +895,7 @@ static int s6gmac_open(struct net_device *dev)
 	s6gmac_init_device(dev);
 	s6gmac_init_stats(dev);
 	s6gmac_init_dmac(dev);
-	s6gmac_rx_fillfifo(pd);
+	s6gmac_rx_fillfifo(dev);
 	s6dmac_enable_chan(pd->rx_dma, pd->rx_chan,
 		2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1);
 	s6dmac_enable_chan(pd->tx_dma, pd->tx_chan,
@@ -960,11 +961,11 @@ static int __devinit s6gmac_probe(struct platform_device *pdev)
 	int res;
 	unsigned long i;
 	struct mii_bus *mb;
+
 	dev = alloc_etherdev(sizeof(*pd));
-	if (!dev) {
-		printk(KERN_ERR DRV_PRMT "etherdev alloc failed, aborting.\n");
+	if (!dev)
 		return -ENOMEM;
-	}
+
 	dev->open = s6gmac_open;
 	dev->stop = s6gmac_stop;
 	dev->hard_start_xmit = s6gmac_tx;
diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c
index 893c880..7b819bd 100644
--- a/drivers/net/ethernet/seeq/ether3.c
+++ b/drivers/net/ethernet/seeq/ether3.c
@@ -643,7 +643,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) {
 			if (next_ptr <= this_ptr)
 				length += RX_END - RX_START;
 
-			skb = dev_alloc_skb(length + 2);
+			skb = netdev_alloc_skb(dev, length + 2);
 			if (skb) {
 				unsigned char *buf;
 
diff --git a/drivers/net/ethernet/seeq/seeq8005.c b/drivers/net/ethernet/seeq/seeq8005.c
index 6056145..7989907 100644
--- a/drivers/net/ethernet/seeq/seeq8005.c
+++ b/drivers/net/ethernet/seeq/seeq8005.c
@@ -548,7 +548,7 @@ static void seeq8005_rx(struct net_device *dev)
 			struct sk_buff *skb;
 			unsigned char *buf;
 
-			skb = dev_alloc_skb(pkt_len);
+			skb = netdev_alloc_skb(dev, pkt_len);
 			if (skb == NULL) {
 				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
 				dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c
index f955a19..bb8c822 100644
--- a/drivers/net/ethernet/seeq/sgiseeq.c
+++ b/drivers/net/ethernet/seeq/sgiseeq.c
@@ -733,7 +733,6 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev)
 
 	dev = alloc_etherdev(sizeof (struct sgiseeq_private));
 	if (!dev) {
-		printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 5d18841..fb3cbc2 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -16,6 +16,21 @@ config SFC_MTD
 	depends on SFC && MTD && !(SFC=y && MTD=m)
 	default y
 	---help---
-	  This exposes the on-board flash memory as MTD devices (e.g.
-	  /dev/mtd1).  This makes it possible to upload new firmware
-	  to the NIC.
+	  This exposes the on-board flash and/or EEPROM as MTD devices
+	  (e.g. /dev/mtd1).  This is required to update the firmware or
+	  the boot configuration under Linux.
+config SFC_MCDI_MON
+	bool "Solarflare SFC9000-family hwmon support"
+	depends on SFC && HWMON && !(SFC=y && HWMON=m)
+	default y
+	----help---
+	  This exposes the on-board firmware-managed sensors as a
+	  hardware monitor device.
+config SFC_SRIOV
+	bool "Solarflare SFC9000-family SR-IOV support"
+	depends on SFC && PCI_IOV
+	default y
+	---help---
+	  This enables support for the SFC9000 I/O Virtualization
+	  features, allowing accelerated network performance in
+	  virtualized environments.
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile
index ab31c71..ea1f8db 100644
--- a/drivers/net/ethernet/sfc/Makefile
+++ b/drivers/net/ethernet/sfc/Makefile
@@ -2,7 +2,8 @@ sfc-y			+= efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \
 			   falcon_xmac.o mcdi_mac.o \
 			   selftest.o ethtool.o qt202x_phy.o mdio_10g.o \
 			   tenxpress.o txc43128_phy.o falcon_boards.o \
-			   mcdi.o mcdi_phy.o
+			   mcdi.o mcdi_phy.o mcdi_mon.o
 sfc-$(CONFIG_SFC_MTD)	+= mtd.o
+sfc-$(CONFIG_SFC_SRIOV)	+= siena_sriov.o
 
 obj-$(CONFIG_SFC)	+= sfc.o
diff --git a/drivers/net/ethernet/sfc/bitfield.h b/drivers/net/ethernet/sfc/bitfield.h
index 098ac2a..a2a9f40 100644
--- a/drivers/net/ethernet/sfc/bitfield.h
+++ b/drivers/net/ethernet/sfc/bitfield.h
@@ -448,40 +448,40 @@ typedef union efx_oword {
 	EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low))
 
 #define EFX_SET_OWORD64(oword, low, high, value) do {			\
-	(oword).u64[0] = (((oword).u64[0] 				\
+	(oword).u64[0] = (((oword).u64[0]				\
 			   & ~EFX_INPLACE_MASK64(0,  63, low, high))	\
 			  | EFX_INSERT64(0,  63, low, high, value));	\
-	(oword).u64[1] = (((oword).u64[1] 				\
+	(oword).u64[1] = (((oword).u64[1]				\
 			   & ~EFX_INPLACE_MASK64(64, 127, low, high))	\
 			  | EFX_INSERT64(64, 127, low, high, value));	\
 	} while (0)
 
 #define EFX_SET_QWORD64(qword, low, high, value) do {			\
-	(qword).u64[0] = (((qword).u64[0] 				\
+	(qword).u64[0] = (((qword).u64[0]				\
 			   & ~EFX_INPLACE_MASK64(0, 63, low, high))	\
 			  | EFX_INSERT64(0, 63, low, high, value));	\
 	} while (0)
 
 #define EFX_SET_OWORD32(oword, low, high, value) do {			\
-	(oword).u32[0] = (((oword).u32[0] 				\
+	(oword).u32[0] = (((oword).u32[0]				\
 			   & ~EFX_INPLACE_MASK32(0, 31, low, high))	\
 			  | EFX_INSERT32(0, 31, low, high, value));	\
-	(oword).u32[1] = (((oword).u32[1] 				\
+	(oword).u32[1] = (((oword).u32[1]				\
 			   & ~EFX_INPLACE_MASK32(32, 63, low, high))	\
 			  | EFX_INSERT32(32, 63, low, high, value));	\
-	(oword).u32[2] = (((oword).u32[2] 				\
+	(oword).u32[2] = (((oword).u32[2]				\
 			   & ~EFX_INPLACE_MASK32(64, 95, low, high))	\
 			  | EFX_INSERT32(64, 95, low, high, value));	\
-	(oword).u32[3] = (((oword).u32[3] 				\
+	(oword).u32[3] = (((oword).u32[3]				\
 			   & ~EFX_INPLACE_MASK32(96, 127, low, high))	\
 			  | EFX_INSERT32(96, 127, low, high, value));	\
 	} while (0)
 
 #define EFX_SET_QWORD32(qword, low, high, value) do {			\
-	(qword).u32[0] = (((qword).u32[0] 				\
+	(qword).u32[0] = (((qword).u32[0]				\
 			   & ~EFX_INPLACE_MASK32(0, 31, low, high))	\
 			  | EFX_INSERT32(0, 31, low, high, value));	\
-	(qword).u32[1] = (((qword).u32[1] 				\
+	(qword).u32[1] = (((qword).u32[1]				\
 			   & ~EFX_INPLACE_MASK32(32, 63, low, high))	\
 			  | EFX_INSERT32(32, 63, low, high, value));	\
 	} while (0)
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index e43702f..ac571cf 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -38,15 +38,15 @@
 
 /* Loopback mode names (see LOOPBACK_MODE()) */
 const unsigned int efx_loopback_mode_max = LOOPBACK_MAX;
-const char *efx_loopback_mode_names[] = {
+const char *const efx_loopback_mode_names[] = {
 	[LOOPBACK_NONE]		= "NONE",
 	[LOOPBACK_DATA]		= "DATAPATH",
 	[LOOPBACK_GMAC]		= "GMAC",
 	[LOOPBACK_XGMII]	= "XGMII",
 	[LOOPBACK_XGXS]		= "XGXS",
-	[LOOPBACK_XAUI]  	= "XAUI",
-	[LOOPBACK_GMII] 	= "GMII",
-	[LOOPBACK_SGMII] 	= "SGMII",
+	[LOOPBACK_XAUI]		= "XAUI",
+	[LOOPBACK_GMII]		= "GMII",
+	[LOOPBACK_SGMII]	= "SGMII",
 	[LOOPBACK_XGBR]		= "XGBR",
 	[LOOPBACK_XFI]		= "XFI",
 	[LOOPBACK_XAUI_FAR]	= "XAUI_FAR",
@@ -55,21 +55,21 @@ const char *efx_loopback_mode_names[] = {
 	[LOOPBACK_XFI_FAR]	= "XFI_FAR",
 	[LOOPBACK_GPHY]		= "GPHY",
 	[LOOPBACK_PHYXS]	= "PHYXS",
-	[LOOPBACK_PCS]	 	= "PCS",
-	[LOOPBACK_PMAPMD] 	= "PMA/PMD",
+	[LOOPBACK_PCS]		= "PCS",
+	[LOOPBACK_PMAPMD]	= "PMA/PMD",
 	[LOOPBACK_XPORT]	= "XPORT",
 	[LOOPBACK_XGMII_WS]	= "XGMII_WS",
-	[LOOPBACK_XAUI_WS]  	= "XAUI_WS",
+	[LOOPBACK_XAUI_WS]	= "XAUI_WS",
 	[LOOPBACK_XAUI_WS_FAR]  = "XAUI_WS_FAR",
 	[LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR",
-	[LOOPBACK_GMII_WS] 	= "GMII_WS",
+	[LOOPBACK_GMII_WS]	= "GMII_WS",
 	[LOOPBACK_XFI_WS]	= "XFI_WS",
 	[LOOPBACK_XFI_WS_FAR]	= "XFI_WS_FAR",
-	[LOOPBACK_PHYXS_WS]  	= "PHYXS_WS",
+	[LOOPBACK_PHYXS_WS]	= "PHYXS_WS",
 };
 
 const unsigned int efx_reset_type_max = RESET_TYPE_MAX;
-const char *efx_reset_type_names[] = {
+const char *const efx_reset_type_names[] = {
 	[RESET_TYPE_INVISIBLE]     = "INVISIBLE",
 	[RESET_TYPE_ALL]           = "ALL",
 	[RESET_TYPE_WORLD]         = "WORLD",
@@ -122,15 +122,6 @@ static int napi_weight = 64;
  */
 static unsigned int efx_monitor_interval = 1 * HZ;
 
-/* This controls whether or not the driver will initialise devices
- * with invalid MAC addresses stored in the EEPROM or flash.  If true,
- * such devices will be initialised with a random locally-generated
- * MAC address.  This allows for loading the sfc_mtd driver to
- * reprogram the flash, even if the flash contents (including the MAC
- * address) have previously been erased.
- */
-static unsigned int allow_bad_hwaddr;
-
 /* Initial interrupt moderation settings.  They can be modified after
  * module load with ethtool.
  *
@@ -162,7 +153,7 @@ static unsigned int interrupt_mode;
  * interrupt handling.
  *
  * Cards without MSI-X will only target one CPU via legacy or MSI interrupt.
- * The default (0) means to assign an interrupt to each package (level II cache)
+ * The default (0) means to assign an interrupt to each core.
  */
 static unsigned int rss_cpus;
 module_param(rss_cpus, uint, 0444);
@@ -195,9 +186,13 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
  *
  *************************************************************************/
 
+static void efx_start_interrupts(struct efx_nic *efx, bool may_keep_eventq);
+static void efx_stop_interrupts(struct efx_nic *efx, bool may_keep_eventq);
+static void efx_remove_channel(struct efx_channel *channel);
 static void efx_remove_channels(struct efx_nic *efx);
+static const struct efx_channel_type efx_default_channel_type;
 static void efx_remove_port(struct efx_nic *efx);
-static void efx_init_napi(struct efx_nic *efx);
+static void efx_init_napi_channel(struct efx_channel *channel);
 static void efx_fini_napi(struct efx_nic *efx);
 static void efx_fini_napi_channel(struct efx_channel *channel);
 static void efx_fini_struct(struct efx_nic *efx);
@@ -226,27 +221,27 @@ static void efx_stop_all(struct efx_nic *efx);
  */
 static int efx_process_channel(struct efx_channel *channel, int budget)
 {
-	struct efx_nic *efx = channel->efx;
 	int spent;
 
-	if (unlikely(efx->reset_pending || !channel->enabled))
+	if (unlikely(!channel->enabled))
 		return 0;
 
 	spent = efx_nic_process_eventq(channel, budget);
-	if (spent == 0)
-		return 0;
-
-	/* Deliver last RX packet. */
-	if (channel->rx_pkt) {
-		__efx_rx_packet(channel, channel->rx_pkt,
-				channel->rx_pkt_csummed);
-		channel->rx_pkt = NULL;
+	if (spent && efx_channel_has_rx_queue(channel)) {
+		struct efx_rx_queue *rx_queue =
+			efx_channel_get_rx_queue(channel);
+
+		/* Deliver last RX packet. */
+		if (channel->rx_pkt) {
+			__efx_rx_packet(channel, channel->rx_pkt);
+			channel->rx_pkt = NULL;
+		}
+		if (rx_queue->enabled) {
+			efx_rx_strategy(channel);
+			efx_fast_push_rx_descriptors(rx_queue);
+		}
 	}
 
-	efx_rx_strategy(channel);
-
-	efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
-
 	return spent;
 }
 
@@ -286,7 +281,7 @@ static int efx_poll(struct napi_struct *napi, int budget)
 	spent = efx_process_channel(channel, budget);
 
 	if (spent < budget) {
-		if (channel->channel < efx->n_rx_channels &&
+		if (efx_channel_has_rx_queue(channel) &&
 		    efx->irq_rx_adaptive &&
 		    unlikely(++channel->irq_count == 1000)) {
 			if (unlikely(channel->irq_mod_score <
@@ -373,7 +368,7 @@ static int efx_probe_eventq(struct efx_channel *channel)
 	struct efx_nic *efx = channel->efx;
 	unsigned long entries;
 
-	netif_dbg(channel->efx, probe, channel->efx->net_dev,
+	netif_dbg(efx, probe, efx->net_dev,
 		  "chan %d create event queue\n", channel->channel);
 
 	/* Build an event queue with room for one event per tx and rx buffer,
@@ -396,6 +391,34 @@ static void efx_init_eventq(struct efx_channel *channel)
 	efx_nic_init_eventq(channel);
 }
 
+/* Enable event queue processing and NAPI */
+static void efx_start_eventq(struct efx_channel *channel)
+{
+	netif_dbg(channel->efx, ifup, channel->efx->net_dev,
+		  "chan %d start event queue\n", channel->channel);
+
+	/* The interrupt handler for this channel may set work_pending
+	 * as soon as we enable it.  Make sure it's cleared before
+	 * then.  Similarly, make sure it sees the enabled flag set.
+	 */
+	channel->work_pending = false;
+	channel->enabled = true;
+	smp_wmb();
+
+	napi_enable(&channel->napi_str);
+	efx_nic_eventq_read_ack(channel);
+}
+
+/* Disable event queue processing and NAPI */
+static void efx_stop_eventq(struct efx_channel *channel)
+{
+	if (!channel->enabled)
+		return;
+
+	napi_disable(&channel->napi_str);
+	channel->enabled = false;
+}
+
 static void efx_fini_eventq(struct efx_channel *channel)
 {
 	netif_dbg(channel->efx, drv, channel->efx->net_dev,
@@ -418,8 +441,7 @@ static void efx_remove_eventq(struct efx_channel *channel)
  *
  *************************************************************************/
 
-/* Allocate and initialise a channel structure, optionally copying
- * parameters (but not resources) from an old channel structure. */
+/* Allocate and initialise a channel structure. */
 static struct efx_channel *
 efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
 {
@@ -428,45 +450,60 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
 	struct efx_tx_queue *tx_queue;
 	int j;
 
-	if (old_channel) {
-		channel = kmalloc(sizeof(*channel), GFP_KERNEL);
-		if (!channel)
-			return NULL;
+	channel = kzalloc(sizeof(*channel), GFP_KERNEL);
+	if (!channel)
+		return NULL;
 
-		*channel = *old_channel;
+	channel->efx = efx;
+	channel->channel = i;
+	channel->type = &efx_default_channel_type;
 
-		channel->napi_dev = NULL;
-		memset(&channel->eventq, 0, sizeof(channel->eventq));
+	for (j = 0; j < EFX_TXQ_TYPES; j++) {
+		tx_queue = &channel->tx_queue[j];
+		tx_queue->efx = efx;
+		tx_queue->queue = i * EFX_TXQ_TYPES + j;
+		tx_queue->channel = channel;
+	}
 
-		rx_queue = &channel->rx_queue;
-		rx_queue->buffer = NULL;
-		memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd));
+	rx_queue = &channel->rx_queue;
+	rx_queue->efx = efx;
+	setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
+		    (unsigned long)rx_queue);
 
-		for (j = 0; j < EFX_TXQ_TYPES; j++) {
-			tx_queue = &channel->tx_queue[j];
-			if (tx_queue->channel)
-				tx_queue->channel = channel;
-			tx_queue->buffer = NULL;
-			memset(&tx_queue->txd, 0, sizeof(tx_queue->txd));
-		}
-	} else {
-		channel = kzalloc(sizeof(*channel), GFP_KERNEL);
-		if (!channel)
-			return NULL;
+	return channel;
+}
 
-		channel->efx = efx;
-		channel->channel = i;
+/* Allocate and initialise a channel structure, copying parameters
+ * (but not resources) from an old channel structure.
+ */
+static struct efx_channel *
+efx_copy_channel(const struct efx_channel *old_channel)
+{
+	struct efx_channel *channel;
+	struct efx_rx_queue *rx_queue;
+	struct efx_tx_queue *tx_queue;
+	int j;
 
-		for (j = 0; j < EFX_TXQ_TYPES; j++) {
-			tx_queue = &channel->tx_queue[j];
-			tx_queue->efx = efx;
-			tx_queue->queue = i * EFX_TXQ_TYPES + j;
+	channel = kmalloc(sizeof(*channel), GFP_KERNEL);
+	if (!channel)
+		return NULL;
+
+	*channel = *old_channel;
+
+	channel->napi_dev = NULL;
+	memset(&channel->eventq, 0, sizeof(channel->eventq));
+
+	for (j = 0; j < EFX_TXQ_TYPES; j++) {
+		tx_queue = &channel->tx_queue[j];
+		if (tx_queue->channel)
 			tx_queue->channel = channel;
-		}
+		tx_queue->buffer = NULL;
+		memset(&tx_queue->txd, 0, sizeof(tx_queue->txd));
 	}
 
 	rx_queue = &channel->rx_queue;
-	rx_queue->efx = efx;
+	rx_queue->buffer = NULL;
+	memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd));
 	setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill,
 		    (unsigned long)rx_queue);
 
@@ -482,57 +519,62 @@ static int efx_probe_channel(struct efx_channel *channel)
 	netif_dbg(channel->efx, probe, channel->efx->net_dev,
 		  "creating channel %d\n", channel->channel);
 
+	rc = channel->type->pre_probe(channel);
+	if (rc)
+		goto fail;
+
 	rc = efx_probe_eventq(channel);
 	if (rc)
-		goto fail1;
+		goto fail;
 
 	efx_for_each_channel_tx_queue(tx_queue, channel) {
 		rc = efx_probe_tx_queue(tx_queue);
 		if (rc)
-			goto fail2;
+			goto fail;
 	}
 
 	efx_for_each_channel_rx_queue(rx_queue, channel) {
 		rc = efx_probe_rx_queue(rx_queue);
 		if (rc)
-			goto fail3;
+			goto fail;
 	}
 
 	channel->n_rx_frm_trunc = 0;
 
 	return 0;
 
- fail3:
-	efx_for_each_channel_rx_queue(rx_queue, channel)
-		efx_remove_rx_queue(rx_queue);
- fail2:
-	efx_for_each_channel_tx_queue(tx_queue, channel)
-		efx_remove_tx_queue(tx_queue);
- fail1:
+fail:
+	efx_remove_channel(channel);
 	return rc;
 }
 
+static void
+efx_get_channel_name(struct efx_channel *channel, char *buf, size_t len)
+{
+	struct efx_nic *efx = channel->efx;
+	const char *type;
+	int number;
+
+	number = channel->channel;
+	if (efx->tx_channel_offset == 0) {
+		type = "";
+	} else if (channel->channel < efx->tx_channel_offset) {
+		type = "-rx";
+	} else {
+		type = "-tx";
+		number -= efx->tx_channel_offset;
+	}
+	snprintf(buf, len, "%s%s-%d", efx->name, type, number);
+}
 
 static void efx_set_channel_names(struct efx_nic *efx)
 {
 	struct efx_channel *channel;
-	const char *type = "";
-	int number;
 
-	efx_for_each_channel(channel, efx) {
-		number = channel->channel;
-		if (efx->n_channels > efx->n_rx_channels) {
-			if (channel->channel < efx->n_rx_channels) {
-				type = "-rx";
-			} else {
-				type = "-tx";
-				number -= efx->n_rx_channels;
-			}
-		}
-		snprintf(efx->channel_name[channel->channel],
-			 sizeof(efx->channel_name[0]),
-			 "%s%s-%d", efx->name, type, number);
-	}
+	efx_for_each_channel(channel, efx)
+		channel->type->get_name(channel,
+					efx->channel_name[channel->channel],
+					sizeof(efx->channel_name[0]));
 }
 
 static int efx_probe_channels(struct efx_nic *efx)
@@ -565,7 +607,7 @@ fail:
  * to propagate configuration changes (mtu, checksum offload), or
  * to clear hardware error conditions
  */
-static void efx_init_channels(struct efx_nic *efx)
+static void efx_start_datapath(struct efx_nic *efx)
 {
 	struct efx_tx_queue *tx_queue;
 	struct efx_rx_queue *rx_queue;
@@ -584,68 +626,26 @@ static void efx_init_channels(struct efx_nic *efx)
 
 	/* Initialise the channels */
 	efx_for_each_channel(channel, efx) {
-		netif_dbg(channel->efx, drv, channel->efx->net_dev,
-			  "init chan %d\n", channel->channel);
-
-		efx_init_eventq(channel);
-
 		efx_for_each_channel_tx_queue(tx_queue, channel)
 			efx_init_tx_queue(tx_queue);
 
 		/* The rx buffer allocation strategy is MTU dependent */
 		efx_rx_strategy(channel);
 
-		efx_for_each_channel_rx_queue(rx_queue, channel)
+		efx_for_each_channel_rx_queue(rx_queue, channel) {
 			efx_init_rx_queue(rx_queue);
+			efx_nic_generate_fill_event(rx_queue);
+		}
 
 		WARN_ON(channel->rx_pkt != NULL);
 		efx_rx_strategy(channel);
 	}
-}
-
-/* This enables event queue processing and packet transmission.
- *
- * Note that this function is not allowed to fail, since that would
- * introduce too much complexity into the suspend/resume path.
- */
-static void efx_start_channel(struct efx_channel *channel)
-{
-	struct efx_rx_queue *rx_queue;
-
-	netif_dbg(channel->efx, ifup, channel->efx->net_dev,
-		  "starting chan %d\n", channel->channel);
-
-	/* The interrupt handler for this channel may set work_pending
-	 * as soon as we enable it.  Make sure it's cleared before
-	 * then.  Similarly, make sure it sees the enabled flag set. */
-	channel->work_pending = false;
-	channel->enabled = true;
-	smp_wmb();
-
-	/* Fill the queues before enabling NAPI */
-	efx_for_each_channel_rx_queue(rx_queue, channel)
-		efx_fast_push_rx_descriptors(rx_queue);
-
-	napi_enable(&channel->napi_str);
-}
 
-/* This disables event queue processing and packet transmission.
- * This function does not guarantee that all queue processing
- * (e.g. RX refill) is complete.
- */
-static void efx_stop_channel(struct efx_channel *channel)
-{
-	if (!channel->enabled)
-		return;
-
-	netif_dbg(channel->efx, ifdown, channel->efx->net_dev,
-		  "stop chan %d\n", channel->channel);
-
-	channel->enabled = false;
-	napi_disable(&channel->napi_str);
+	if (netif_device_present(efx->net_dev))
+		netif_tx_wake_all_queues(efx->net_dev);
 }
 
-static void efx_fini_channels(struct efx_nic *efx)
+static void efx_stop_datapath(struct efx_nic *efx)
 {
 	struct efx_channel *channel;
 	struct efx_tx_queue *tx_queue;
@@ -672,14 +672,21 @@ static void efx_fini_channels(struct efx_nic *efx)
 	}
 
 	efx_for_each_channel(channel, efx) {
-		netif_dbg(channel->efx, drv, channel->efx->net_dev,
-			  "shut down chan %d\n", channel->channel);
+		/* RX packet processing is pipelined, so wait for the
+		 * NAPI handler to complete.  At least event queue 0
+		 * might be kept active by non-data events, so don't
+		 * use napi_synchronize() but actually disable NAPI
+		 * temporarily.
+		 */
+		if (efx_channel_has_rx_queue(channel)) {
+			efx_stop_eventq(channel);
+			efx_start_eventq(channel);
+		}
 
 		efx_for_each_channel_rx_queue(rx_queue, channel)
 			efx_fini_rx_queue(rx_queue);
 		efx_for_each_possible_channel_tx_queue(tx_queue, channel)
 			efx_fini_tx_queue(tx_queue);
-		efx_fini_eventq(channel);
 	}
 }
 
@@ -711,16 +718,40 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
 {
 	struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel;
 	u32 old_rxq_entries, old_txq_entries;
-	unsigned i;
-	int rc;
+	unsigned i, next_buffer_table = 0;
+	int rc = 0;
+
+	/* Not all channels should be reallocated. We must avoid
+	 * reallocating their buffer table entries.
+	 */
+	efx_for_each_channel(channel, efx) {
+		struct efx_rx_queue *rx_queue;
+		struct efx_tx_queue *tx_queue;
+
+		if (channel->type->copy)
+			continue;
+		next_buffer_table = max(next_buffer_table,
+					channel->eventq.index +
+					channel->eventq.entries);
+		efx_for_each_channel_rx_queue(rx_queue, channel)
+			next_buffer_table = max(next_buffer_table,
+						rx_queue->rxd.index +
+						rx_queue->rxd.entries);
+		efx_for_each_channel_tx_queue(tx_queue, channel)
+			next_buffer_table = max(next_buffer_table,
+						tx_queue->txd.index +
+						tx_queue->txd.entries);
+	}
 
 	efx_stop_all(efx);
-	efx_fini_channels(efx);
+	efx_stop_interrupts(efx, true);
 
-	/* Clone channels */
+	/* Clone channels (where possible) */
 	memset(other_channel, 0, sizeof(other_channel));
 	for (i = 0; i < efx->n_channels; i++) {
-		channel = efx_alloc_channel(efx, i, efx->channel[i]);
+		channel = efx->channel[i];
+		if (channel->type->copy)
+			channel = channel->type->copy(channel);
 		if (!channel) {
 			rc = -ENOMEM;
 			goto out;
@@ -739,23 +770,31 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
 		other_channel[i] = channel;
 	}
 
-	rc = efx_probe_channels(efx);
-	if (rc)
-		goto rollback;
+	/* Restart buffer table allocation */
+	efx->next_buffer_table = next_buffer_table;
 
-	efx_init_napi(efx);
-
-	/* Destroy old channels */
 	for (i = 0; i < efx->n_channels; i++) {
-		efx_fini_napi_channel(other_channel[i]);
-		efx_remove_channel(other_channel[i]);
+		channel = efx->channel[i];
+		if (!channel->type->copy)
+			continue;
+		rc = efx_probe_channel(channel);
+		if (rc)
+			goto rollback;
+		efx_init_napi_channel(efx->channel[i]);
 	}
+
 out:
-	/* Free unused channel structures */
-	for (i = 0; i < efx->n_channels; i++)
-		kfree(other_channel[i]);
+	/* Destroy unused channel structures */
+	for (i = 0; i < efx->n_channels; i++) {
+		channel = other_channel[i];
+		if (channel && channel->type->copy) {
+			efx_fini_napi_channel(channel);
+			efx_remove_channel(channel);
+			kfree(channel);
+		}
+	}
 
-	efx_init_channels(efx);
+	efx_start_interrupts(efx, true);
 	efx_start_all(efx);
 	return rc;
 
@@ -776,6 +815,18 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue)
 	mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100));
 }
 
+static const struct efx_channel_type efx_default_channel_type = {
+	.pre_probe		= efx_channel_dummy_op_int,
+	.get_name		= efx_get_channel_name,
+	.copy			= efx_copy_channel,
+	.keep_eventq		= false,
+};
+
+int efx_channel_dummy_op_int(struct efx_channel *channel)
+{
+	return 0;
+}
+
 /**************************************************************************
  *
  * Port handling
@@ -807,16 +858,14 @@ void efx_link_status_changed(struct efx_nic *efx)
 	}
 
 	/* Status message for kernel log */
-	if (link_state->up) {
+	if (link_state->up)
 		netif_info(efx, link, efx->net_dev,
 			   "link up at %uMbps %s-duplex (MTU %d)%s\n",
 			   link_state->speed, link_state->fd ? "full" : "half",
 			   efx->net_dev->mtu,
 			   (efx->promiscuous ? " [PROMISC]" : ""));
-	} else {
+	else
 		netif_info(efx, link, efx->net_dev, "link down\n");
-	}
-
 }
 
 void efx_link_set_advertising(struct efx_nic *efx, u32 advertising)
@@ -863,11 +912,9 @@ int __efx_reconfigure_port(struct efx_nic *efx)
 
 	WARN_ON(!mutex_is_locked(&efx->mac_lock));
 
-	/* Serialise the promiscuous flag with efx_set_multicast_list. */
-	if (efx_dev_registered(efx)) {
-		netif_addr_lock_bh(efx->net_dev);
-		netif_addr_unlock_bh(efx->net_dev);
-	}
+	/* Serialise the promiscuous flag with efx_set_rx_mode. */
+	netif_addr_lock_bh(efx->net_dev);
+	netif_addr_unlock_bh(efx->net_dev);
 
 	/* Disable PHY transmit in mac level loopbacks */
 	phy_mode = efx->phy_mode;
@@ -907,16 +954,13 @@ static void efx_mac_work(struct work_struct *data)
 	struct efx_nic *efx = container_of(data, struct efx_nic, mac_work);
 
 	mutex_lock(&efx->mac_lock);
-	if (efx->port_enabled) {
-		efx->type->push_multicast_hash(efx);
-		efx->mac_op->reconfigure(efx);
-	}
+	if (efx->port_enabled)
+		efx->type->reconfigure_mac(efx);
 	mutex_unlock(&efx->mac_lock);
 }
 
 static int efx_probe_port(struct efx_nic *efx)
 {
-	unsigned char *perm_addr;
 	int rc;
 
 	netif_dbg(efx, probe, efx->net_dev, "create port\n");
@@ -929,28 +973,10 @@ static int efx_probe_port(struct efx_nic *efx)
 	if (rc)
 		return rc;
 
-	/* Sanity check MAC address */
-	perm_addr = efx->net_dev->perm_addr;
-	if (is_valid_ether_addr(perm_addr)) {
-		memcpy(efx->net_dev->dev_addr, perm_addr, ETH_ALEN);
-	} else {
-		netif_err(efx, probe, efx->net_dev, "invalid MAC address %pM\n",
-			  perm_addr);
-		if (!allow_bad_hwaddr) {
-			rc = -EINVAL;
-			goto err;
-		}
-		random_ether_addr(efx->net_dev->dev_addr);
-		netif_info(efx, probe, efx->net_dev,
-			   "using locally-generated MAC %pM\n",
-			   efx->net_dev->dev_addr);
-	}
+	/* Initialise MAC address to permanent address */
+	memcpy(efx->net_dev->dev_addr, efx->net_dev->perm_addr, ETH_ALEN);
 
 	return 0;
-
- err:
-	efx->type->remove_port(efx);
-	return rc;
 }
 
 static int efx_init_port(struct efx_nic *efx)
@@ -969,7 +995,7 @@ static int efx_init_port(struct efx_nic *efx)
 
 	/* Reconfigure the MAC before creating dma queues (required for
 	 * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */
-	efx->mac_op->reconfigure(efx);
+	efx->type->reconfigure_mac(efx);
 
 	/* Ensure the PHY advertises the correct flow control settings */
 	rc = efx->phy_op->reconfigure(efx);
@@ -996,8 +1022,7 @@ static void efx_start_port(struct efx_nic *efx)
 
 	/* efx_mac_work() might have been scheduled after efx_stop_port(),
 	 * and then cancelled by efx_flush_all() */
-	efx->type->push_multicast_hash(efx);
-	efx->mac_op->reconfigure(efx);
+	efx->type->reconfigure_mac(efx);
 
 	mutex_unlock(&efx->mac_lock);
 }
@@ -1012,10 +1037,8 @@ static void efx_stop_port(struct efx_nic *efx)
 	mutex_unlock(&efx->mac_lock);
 
 	/* Serialise against efx_set_multicast_list() */
-	if (efx_dev_registered(efx)) {
-		netif_addr_lock_bh(efx->net_dev);
-		netif_addr_unlock_bh(efx->net_dev);
-	}
+	netif_addr_lock_bh(efx->net_dev);
+	netif_addr_unlock_bh(efx->net_dev);
 }
 
 static void efx_fini_port(struct efx_nic *efx)
@@ -1069,9 +1092,11 @@ static int efx_init_io(struct efx_nic *efx)
 	 * masks event though they reject 46 bit masks.
 	 */
 	while (dma_mask > 0x7fffffffUL) {
-		if (pci_dma_supported(pci_dev, dma_mask) &&
-		    ((rc = pci_set_dma_mask(pci_dev, dma_mask)) == 0))
-			break;
+		if (pci_dma_supported(pci_dev, dma_mask)) {
+			rc = pci_set_dma_mask(pci_dev, dma_mask);
+			if (rc == 0)
+				break;
+		}
 		dma_mask >>= 1;
 	}
 	if (rc) {
@@ -1144,33 +1169,46 @@ static void efx_fini_io(struct efx_nic *efx)
 	pci_disable_device(efx->pci_dev);
 }
 
-/* Get number of channels wanted.  Each channel will have its own IRQ,
- * 1 RX queue and/or 2 TX queues. */
-static int efx_wanted_channels(void)
+static unsigned int efx_wanted_parallelism(struct efx_nic *efx)
 {
-	cpumask_var_t core_mask;
-	int count;
+	cpumask_var_t thread_mask;
+	unsigned int count;
 	int cpu;
 
-	if (rss_cpus)
-		return rss_cpus;
+	if (rss_cpus) {
+		count = rss_cpus;
+	} else {
+		if (unlikely(!zalloc_cpumask_var(&thread_mask, GFP_KERNEL))) {
+			netif_warn(efx, probe, efx->net_dev,
+				   "RSS disabled due to allocation failure\n");
+			return 1;
+		}
+
+		count = 0;
+		for_each_online_cpu(cpu) {
+			if (!cpumask_test_cpu(cpu, thread_mask)) {
+				++count;
+				cpumask_or(thread_mask, thread_mask,
+					   topology_thread_cpumask(cpu));
+			}
+		}
 
-	if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) {
-		printk(KERN_WARNING
-		       "sfc: RSS disabled due to allocation failure\n");
-		return 1;
+		free_cpumask_var(thread_mask);
 	}
 
-	count = 0;
-	for_each_online_cpu(cpu) {
-		if (!cpumask_test_cpu(cpu, core_mask)) {
-			++count;
-			cpumask_or(core_mask, core_mask,
-				   topology_core_cpumask(cpu));
-		}
+	/* If RSS is requested for the PF *and* VFs then we can't write RSS
+	 * table entries that are inaccessible to VFs
+	 */
+	if (efx_sriov_wanted(efx) && efx_vf_size(efx) > 1 &&
+	    count > efx_vf_size(efx)) {
+		netif_warn(efx, probe, efx->net_dev,
+			   "Reducing number of RSS channels from %u to %u for "
+			   "VF support. Increase vf-msix-limit to use more "
+			   "channels on the PF.\n",
+			   count, efx_vf_size(efx));
+		count = efx_vf_size(efx);
 	}
 
-	free_cpumask_var(core_mask);
 	return count;
 }
 
@@ -1178,7 +1216,8 @@ static int
 efx_init_rx_cpu_rmap(struct efx_nic *efx, struct msix_entry *xentries)
 {
 #ifdef CONFIG_RFS_ACCEL
-	int i, rc;
+	unsigned int i;
+	int rc;
 
 	efx->net_dev->rx_cpu_rmap = alloc_irq_cpu_rmap(efx->n_rx_channels);
 	if (!efx->net_dev->rx_cpu_rmap)
@@ -1201,17 +1240,24 @@ efx_init_rx_cpu_rmap(struct efx_nic *efx, struct msix_entry *xentries)
  */
 static int efx_probe_interrupts(struct efx_nic *efx)
 {
-	int max_channels =
-		min_t(int, efx->type->phys_addr_channels, EFX_MAX_CHANNELS);
-	int rc, i;
+	unsigned int max_channels =
+		min(efx->type->phys_addr_channels, EFX_MAX_CHANNELS);
+	unsigned int extra_channels = 0;
+	unsigned int i, j;
+	int rc;
+
+	for (i = 0; i < EFX_MAX_EXTRA_CHANNELS; i++)
+		if (efx->extra_channel_type[i])
+			++extra_channels;
 
 	if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
 		struct msix_entry xentries[EFX_MAX_CHANNELS];
-		int n_channels;
+		unsigned int n_channels;
 
-		n_channels = efx_wanted_channels();
+		n_channels = efx_wanted_parallelism(efx);
 		if (separate_tx_channels)
 			n_channels *= 2;
+		n_channels += extra_channels;
 		n_channels = min(n_channels, max_channels);
 
 		for (i = 0; i < n_channels; i++)
@@ -1220,7 +1266,7 @@ static int efx_probe_interrupts(struct efx_nic *efx)
 		if (rc > 0) {
 			netif_err(efx, drv, efx->net_dev,
 				  "WARNING: Insufficient MSI-X vectors"
-				  " available (%d < %d).\n", rc, n_channels);
+				  " available (%d < %u).\n", rc, n_channels);
 			netif_err(efx, drv, efx->net_dev,
 				  "WARNING: Performance may be reduced.\n");
 			EFX_BUG_ON_PARANOID(rc >= n_channels);
@@ -1231,22 +1277,23 @@ static int efx_probe_interrupts(struct efx_nic *efx)
 
 		if (rc == 0) {
 			efx->n_channels = n_channels;
+			if (n_channels > extra_channels)
+				n_channels -= extra_channels;
 			if (separate_tx_channels) {
-				efx->n_tx_channels =
-					max(efx->n_channels / 2, 1U);
-				efx->n_rx_channels =
-					max(efx->n_channels -
-					    efx->n_tx_channels, 1U);
+				efx->n_tx_channels = max(n_channels / 2, 1U);
+				efx->n_rx_channels = max(n_channels -
+							 efx->n_tx_channels,
+							 1U);
 			} else {
-				efx->n_tx_channels = efx->n_channels;
-				efx->n_rx_channels = efx->n_channels;
+				efx->n_tx_channels = n_channels;
+				efx->n_rx_channels = n_channels;
 			}
 			rc = efx_init_rx_cpu_rmap(efx, xentries);
 			if (rc) {
 				pci_disable_msix(efx->pci_dev);
 				return rc;
 			}
-			for (i = 0; i < n_channels; i++)
+			for (i = 0; i < efx->n_channels; i++)
 				efx_get_channel(efx, i)->irq =
 					xentries[i].vector;
 		} else {
@@ -1280,9 +1327,68 @@ static int efx_probe_interrupts(struct efx_nic *efx)
 		efx->legacy_irq = efx->pci_dev->irq;
 	}
 
+	/* Assign extra channels if possible */
+	j = efx->n_channels;
+	for (i = 0; i < EFX_MAX_EXTRA_CHANNELS; i++) {
+		if (!efx->extra_channel_type[i])
+			continue;
+		if (efx->interrupt_mode != EFX_INT_MODE_MSIX ||
+		    efx->n_channels <= extra_channels) {
+			efx->extra_channel_type[i]->handle_no_channel(efx);
+		} else {
+			--j;
+			efx_get_channel(efx, j)->type =
+				efx->extra_channel_type[i];
+		}
+	}
+
+	/* RSS might be usable on VFs even if it is disabled on the PF */
+	efx->rss_spread = (efx->n_rx_channels > 1 ?
+			   efx->n_rx_channels : efx_vf_size(efx));
+
 	return 0;
 }
 
+/* Enable interrupts, then probe and start the event queues */
+static void efx_start_interrupts(struct efx_nic *efx, bool may_keep_eventq)
+{
+	struct efx_channel *channel;
+
+	if (efx->legacy_irq)
+		efx->legacy_irq_enabled = true;
+	efx_nic_enable_interrupts(efx);
+
+	efx_for_each_channel(channel, efx) {
+		if (!channel->type->keep_eventq || !may_keep_eventq)
+			efx_init_eventq(channel);
+		efx_start_eventq(channel);
+	}
+
+	efx_mcdi_mode_event(efx);
+}
+
+static void efx_stop_interrupts(struct efx_nic *efx, bool may_keep_eventq)
+{
+	struct efx_channel *channel;
+
+	efx_mcdi_mode_poll(efx);
+
+	efx_nic_disable_interrupts(efx);
+	if (efx->legacy_irq) {
+		synchronize_irq(efx->legacy_irq);
+		efx->legacy_irq_enabled = false;
+	}
+
+	efx_for_each_channel(channel, efx) {
+		if (channel->irq)
+			synchronize_irq(channel->irq);
+
+		efx_stop_eventq(channel);
+		if (!channel->type->keep_eventq || !may_keep_eventq)
+			efx_fini_eventq(channel);
+	}
+}
+
 static void efx_remove_interrupts(struct efx_nic *efx)
 {
 	struct efx_channel *channel;
@@ -1333,11 +1439,13 @@ static int efx_probe_nic(struct efx_nic *efx)
 	if (rc)
 		goto fail;
 
+	efx->type->dimension_resources(efx);
+
 	if (efx->n_channels > 1)
 		get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key));
 	for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++)
 		efx->rx_indir_table[i] =
-			ethtool_rxfh_indir_default(i, efx->n_rx_channels);
+			ethtool_rxfh_indir_default(i, efx->rss_spread);
 
 	efx_set_channels(efx);
 	netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
@@ -1385,21 +1493,22 @@ static int efx_probe_all(struct efx_nic *efx)
 	}
 
 	efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
-	rc = efx_probe_channels(efx);
-	if (rc)
-		goto fail3;
 
 	rc = efx_probe_filters(efx);
 	if (rc) {
 		netif_err(efx, probe, efx->net_dev,
 			  "failed to create filter tables\n");
-		goto fail4;
+		goto fail3;
 	}
 
+	rc = efx_probe_channels(efx);
+	if (rc)
+		goto fail4;
+
 	return 0;
 
  fail4:
-	efx_remove_channels(efx);
+	efx_remove_filters(efx);
  fail3:
 	efx_remove_port(efx);
  fail2:
@@ -1408,15 +1517,13 @@ static int efx_probe_all(struct efx_nic *efx)
 	return rc;
 }
 
-/* Called after previous invocation(s) of efx_stop_all, restarts the
- * port, kernel transmit queue, NAPI processing and hardware interrupts,
- * and ensures that the port is scheduled to be reconfigured.
- * This function is safe to call multiple times when the NIC is in any
- * state. */
+/* Called after previous invocation(s) of efx_stop_all, restarts the port,
+ * kernel transmit queues and NAPI processing, and ensures that the port is
+ * scheduled to be reconfigured. This function is safe to call multiple
+ * times when the NIC is in any state.
+ */
 static void efx_start_all(struct efx_nic *efx)
 {
-	struct efx_channel *channel;
-
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
 	/* Check that it is appropriate to restart the interface. All
@@ -1425,31 +1532,11 @@ static void efx_start_all(struct efx_nic *efx)
 		return;
 	if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT))
 		return;
-	if (efx_dev_registered(efx) && !netif_running(efx->net_dev))
+	if (!netif_running(efx->net_dev))
 		return;
 
-	/* Mark the port as enabled so port reconfigurations can start, then
-	 * restart the transmit interface early so the watchdog timer stops */
 	efx_start_port(efx);
-
-	if (efx_dev_registered(efx) && netif_device_present(efx->net_dev))
-		netif_tx_wake_all_queues(efx->net_dev);
-
-	efx_for_each_channel(channel, efx)
-		efx_start_channel(channel);
-
-	if (efx->legacy_irq)
-		efx->legacy_irq_enabled = true;
-	efx_nic_enable_interrupts(efx);
-
-	/* Switch to event based MCDI completions after enabling interrupts.
-	 * If a reset has been scheduled, then we need to stay in polled mode.
-	 * Rather than serialising efx_mcdi_mode_event() [which sleeps] and
-	 * reset_pending [modified from an atomic context], we instead guarantee
-	 * that efx_mcdi_mode_poll() isn't reverted erroneously */
-	efx_mcdi_mode_event(efx);
-	if (efx->reset_pending)
-		efx_mcdi_mode_poll(efx);
+	efx_start_datapath(efx);
 
 	/* Start the hardware monitor if there is one. Otherwise (we're link
 	 * event driven), we have to poll the PHY because after an event queue
@@ -1485,8 +1572,6 @@ static void efx_flush_all(struct efx_nic *efx)
  * taking locks. */
 static void efx_stop_all(struct efx_nic *efx)
 {
-	struct efx_channel *channel;
-
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
 	/* port_enabled can be read safely under the rtnl lock */
@@ -1494,28 +1579,6 @@ static void efx_stop_all(struct efx_nic *efx)
 		return;
 
 	efx->type->stop_stats(efx);
-
-	/* Switch to MCDI polling on Siena before disabling interrupts */
-	efx_mcdi_mode_poll(efx);
-
-	/* Disable interrupts and wait for ISR to complete */
-	efx_nic_disable_interrupts(efx);
-	if (efx->legacy_irq) {
-		synchronize_irq(efx->legacy_irq);
-		efx->legacy_irq_enabled = false;
-	}
-	efx_for_each_channel(channel, efx) {
-		if (channel->irq)
-			synchronize_irq(channel->irq);
-	}
-
-	/* Stop all NAPI processing and synchronous rx refills */
-	efx_for_each_channel(channel, efx)
-		efx_stop_channel(channel);
-
-	/* Stop all asynchronous port reconfigurations. Since all
-	 * event processing has already been stopped, there is no
-	 * window to loose phy events */
 	efx_stop_port(efx);
 
 	/* Flush efx_mac_work(), refill_workqueue, monitor_work */
@@ -1523,17 +1586,15 @@ static void efx_stop_all(struct efx_nic *efx)
 
 	/* Stop the kernel transmit interface late, so the watchdog
 	 * timer isn't ticking over the flush */
-	if (efx_dev_registered(efx)) {
-		netif_tx_stop_all_queues(efx->net_dev);
-		netif_tx_lock_bh(efx->net_dev);
-		netif_tx_unlock_bh(efx->net_dev);
-	}
+	netif_tx_disable(efx->net_dev);
+
+	efx_stop_datapath(efx);
 }
 
 static void efx_remove_all(struct efx_nic *efx)
 {
-	efx_remove_filters(efx);
 	efx_remove_channels(efx);
+	efx_remove_filters(efx);
 	efx_remove_port(efx);
 	efx_remove_nic(efx);
 }
@@ -1544,13 +1605,13 @@ static void efx_remove_all(struct efx_nic *efx)
  *
  **************************************************************************/
 
-static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int resolution)
+static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int quantum_ns)
 {
 	if (usecs == 0)
 		return 0;
-	if (usecs < resolution)
+	if (usecs * 1000 < quantum_ns)
 		return 1; /* never round down to 0 */
-	return usecs / resolution;
+	return usecs * 1000 / quantum_ns;
 }
 
 /* Set interrupt moderation parameters */
@@ -1559,14 +1620,20 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
 			    bool rx_may_override_tx)
 {
 	struct efx_channel *channel;
-	unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION);
-	unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION);
+	unsigned int irq_mod_max = DIV_ROUND_UP(efx->type->timer_period_max *
+						efx->timer_quantum_ns,
+						1000);
+	unsigned int tx_ticks;
+	unsigned int rx_ticks;
 
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
-	if (tx_ticks > EFX_IRQ_MOD_MAX || rx_ticks > EFX_IRQ_MOD_MAX)
+	if (tx_usecs > irq_mod_max || rx_usecs > irq_mod_max)
 		return -EINVAL;
 
+	tx_ticks = irq_mod_ticks(tx_usecs, efx->timer_quantum_ns);
+	rx_ticks = irq_mod_ticks(rx_usecs, efx->timer_quantum_ns);
+
 	if (tx_ticks != rx_ticks && efx->tx_channel_offset == 0 &&
 	    !rx_may_override_tx) {
 		netif_err(efx, drv, efx->net_dev, "Channels are shared. "
@@ -1589,8 +1656,14 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs,
 void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
 			    unsigned int *rx_usecs, bool *rx_adaptive)
 {
+	/* We must round up when converting ticks to microseconds
+	 * because we round down when converting the other way.
+	 */
+
 	*rx_adaptive = efx->irq_rx_adaptive;
-	*rx_usecs = efx->irq_rx_moderation * EFX_IRQ_MOD_RESOLUTION;
+	*rx_usecs = DIV_ROUND_UP(efx->irq_rx_moderation *
+				 efx->timer_quantum_ns,
+				 1000);
 
 	/* If channels are shared between RX and TX, so is IRQ
 	 * moderation.  Otherwise, IRQ moderation is the same for all
@@ -1599,9 +1672,10 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs,
 	if (efx->tx_channel_offset == 0)
 		*tx_usecs = *rx_usecs;
 	else
-		*tx_usecs =
+		*tx_usecs = DIV_ROUND_UP(
 			efx->channel[efx->tx_channel_offset]->irq_moderation *
-			EFX_IRQ_MOD_RESOLUTION;
+			efx->timer_quantum_ns,
+			1000);
 }
 
 /**************************************************************************
@@ -1664,15 +1738,21 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
  *
  **************************************************************************/
 
+static void efx_init_napi_channel(struct efx_channel *channel)
+{
+	struct efx_nic *efx = channel->efx;
+
+	channel->napi_dev = efx->net_dev;
+	netif_napi_add(channel->napi_dev, &channel->napi_str,
+		       efx_poll, napi_weight);
+}
+
 static void efx_init_napi(struct efx_nic *efx)
 {
 	struct efx_channel *channel;
 
-	efx_for_each_channel(channel, efx) {
-		channel->napi_dev = efx->net_dev;
-		netif_napi_add(channel->napi_dev, &channel->napi_str,
-			       efx_poll, napi_weight);
-	}
+	efx_for_each_channel(channel, efx)
+		efx_init_napi_channel(channel);
 }
 
 static void efx_fini_napi_channel(struct efx_channel *channel)
@@ -1757,22 +1837,21 @@ static int efx_net_stop(struct net_device *net_dev)
 	if (efx->state != STATE_DISABLED) {
 		/* Stop the device and flush all the channels */
 		efx_stop_all(efx);
-		efx_fini_channels(efx);
-		efx_init_channels(efx);
 	}
 
 	return 0;
 }
 
 /* Context: process, dev_base_lock or RTNL held, non-blocking. */
-static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats)
+static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev,
+					       struct rtnl_link_stats64 *stats)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_mac_stats *mac_stats = &efx->mac_stats;
 
 	spin_lock_bh(&efx->stats_lock);
+
 	efx->type->update_stats(efx);
-	spin_unlock_bh(&efx->stats_lock);
 
 	stats->rx_packets = mac_stats->rx_packets;
 	stats->tx_packets = mac_stats->tx_packets;
@@ -1796,6 +1875,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc
 	stats->tx_errors = (stats->tx_window_errors +
 			    mac_stats->tx_bad);
 
+	spin_unlock_bh(&efx->stats_lock);
+
 	return stats;
 }
 
@@ -1816,7 +1897,6 @@ static void efx_watchdog(struct net_device *net_dev)
 static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	int rc = 0;
 
 	EFX_ASSERT_RESET_SERIALISED(efx);
 
@@ -1827,19 +1907,15 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
 
 	netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
 
-	efx_fini_channels(efx);
-
 	mutex_lock(&efx->mac_lock);
 	/* Reconfigure the MAC before enabling the dma queues so that
 	 * the RX buffers don't overflow */
 	net_dev->mtu = new_mtu;
-	efx->mac_op->reconfigure(efx);
+	efx->type->reconfigure_mac(efx);
 	mutex_unlock(&efx->mac_lock);
 
-	efx_init_channels(efx);
-
 	efx_start_all(efx);
-	return rc;
+	return 0;
 }
 
 static int efx_set_mac_address(struct net_device *net_dev, void *data)
@@ -1858,17 +1934,18 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
 	}
 
 	memcpy(net_dev->dev_addr, new_addr, net_dev->addr_len);
+	efx_sriov_mac_address_changed(efx);
 
 	/* Reconfigure the MAC */
 	mutex_lock(&efx->mac_lock);
-	efx->mac_op->reconfigure(efx);
+	efx->type->reconfigure_mac(efx);
 	mutex_unlock(&efx->mac_lock);
 
 	return 0;
 }
 
 /* Context: netif_addr_lock held, BHs disabled. */
-static void efx_set_multicast_list(struct net_device *net_dev)
+static void efx_set_rx_mode(struct net_device *net_dev)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct netdev_hw_addr *ha;
@@ -1922,8 +1999,14 @@ static const struct net_device_ops efx_netdev_ops = {
 	.ndo_do_ioctl		= efx_ioctl,
 	.ndo_change_mtu		= efx_change_mtu,
 	.ndo_set_mac_address	= efx_set_mac_address,
-	.ndo_set_rx_mode	= efx_set_multicast_list,
+	.ndo_set_rx_mode	= efx_set_rx_mode,
 	.ndo_set_features	= efx_set_features,
+#ifdef CONFIG_SFC_SRIOV
+	.ndo_set_vf_mac		= efx_sriov_set_vf_mac,
+	.ndo_set_vf_vlan	= efx_sriov_set_vf_vlan,
+	.ndo_set_vf_spoofchk	= efx_sriov_set_vf_spoofchk,
+	.ndo_get_vf_config	= efx_sriov_get_vf_config,
+#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = efx_netpoll,
 #endif
@@ -1975,10 +2058,6 @@ static int efx_register_netdev(struct efx_nic *efx)
 	net_dev->netdev_ops = &efx_netdev_ops;
 	SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
 
-	/* Clear MAC statistics */
-	efx->mac_op->update_stats(efx);
-	memset(&efx->mac_stats, 0, sizeof(efx->mac_stats));
-
 	rtnl_lock();
 
 	rc = dev_alloc_name(net_dev, net_dev->name);
@@ -1997,7 +2076,7 @@ static int efx_register_netdev(struct efx_nic *efx)
 	}
 
 	/* Always start with carrier off; PHY events will detect the link */
-	netif_carrier_off(efx->net_dev);
+	netif_carrier_off(net_dev);
 
 	rtnl_unlock();
 
@@ -2038,11 +2117,9 @@ static void efx_unregister_netdev(struct efx_nic *efx)
 			efx_release_tx_buffers(tx_queue);
 	}
 
-	if (efx_dev_registered(efx)) {
-		strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
-		device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type);
-		unregister_netdev(efx->net_dev);
-	}
+	strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name));
+	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type);
+	unregister_netdev(efx->net_dev);
 }
 
 /**************************************************************************
@@ -2060,7 +2137,7 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method)
 	efx_stop_all(efx);
 	mutex_lock(&efx->mac_lock);
 
-	efx_fini_channels(efx);
+	efx_stop_interrupts(efx, false);
 	if (efx->port_initialized && method != RESET_TYPE_INVISIBLE)
 		efx->phy_op->fini(efx);
 	efx->type->fini(efx);
@@ -2095,10 +2172,11 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok)
 				  "could not restore PHY settings\n");
 	}
 
-	efx->mac_op->reconfigure(efx);
+	efx->type->reconfigure_mac(efx);
 
-	efx_init_channels(efx);
+	efx_start_interrupts(efx, false);
 	efx_restore_filters(efx);
+	efx_sriov_reset(efx);
 
 	mutex_unlock(&efx->mac_lock);
 
@@ -2300,10 +2378,10 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type,
 	efx->net_dev = net_dev;
 	spin_lock_init(&efx->stats_lock);
 	mutex_init(&efx->mac_lock);
-	efx->mac_op = type->default_mac_ops;
 	efx->phy_op = &efx_dummy_phy_operations;
 	efx->mdio.dev = net_dev;
 	INIT_WORK(&efx->mac_work, efx_mac_work);
+	init_waitqueue_head(&efx->flush_wq);
 
 	for (i = 0; i < EFX_MAX_CHANNELS; i++) {
 		efx->channel[i] = efx_alloc_channel(efx, i, NULL);
@@ -2361,8 +2439,8 @@ static void efx_pci_remove_main(struct efx_nic *efx)
 	free_irq_cpu_rmap(efx->net_dev->rx_cpu_rmap);
 	efx->net_dev->rx_cpu_rmap = NULL;
 #endif
+	efx_stop_interrupts(efx, false);
 	efx_nic_fini_interrupt(efx);
-	efx_fini_channels(efx);
 	efx_fini_port(efx);
 	efx->type->fini(efx);
 	efx_fini_napi(efx);
@@ -2388,6 +2466,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
 	/* Allow any queued efx_resets() to complete */
 	rtnl_unlock();
 
+	efx_stop_interrupts(efx, false);
+	efx_sriov_fini(efx);
 	efx_unregister_netdev(efx);
 
 	efx_mtd_remove(efx);
@@ -2436,16 +2516,14 @@ static int efx_pci_probe_main(struct efx_nic *efx)
 		goto fail4;
 	}
 
-	efx_init_channels(efx);
-
 	rc = efx_nic_init_interrupt(efx);
 	if (rc)
 		goto fail5;
+	efx_start_interrupts(efx, false);
 
 	return 0;
 
  fail5:
-	efx_fini_channels(efx);
 	efx_fini_port(efx);
  fail4:
 	efx->type->fini(efx);
@@ -2459,7 +2537,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
 /* NIC initialisation
  *
  * This is called at module load (or hotplug insertion,
- * theoretically).  It sets up PCI mappings, tests and resets the NIC,
+ * theoretically).  It sets up PCI mappings, resets the NIC,
  * sets up and registers the network devices with the kernel and hooks
  * the interrupt service routine.  It does not prepare the device for
  * transmission; this is left to the first time one of the network
@@ -2471,7 +2549,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
 	const struct efx_nic_type *type = (const struct efx_nic_type *) entry->driver_data;
 	struct net_device *net_dev;
 	struct efx_nic *efx;
-	int i, rc;
+	int rc;
 
 	/* Allocate and initialise a struct net_device and struct efx_nic */
 	net_dev = alloc_etherdev_mqs(sizeof(*efx), EFX_MAX_CORE_TX_QUEUES,
@@ -2504,39 +2582,22 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
 	if (rc)
 		goto fail2;
 
-	/* No serialisation is required with the reset path because
-	 * we're in STATE_INIT. */
-	for (i = 0; i < 5; i++) {
-		rc = efx_pci_probe_main(efx);
-
-		/* Serialise against efx_reset(). No more resets will be
-		 * scheduled since efx_stop_all() has been called, and we
-		 * have not and never have been registered with either
-		 * the rtnetlink or driverlink layers. */
-		cancel_work_sync(&efx->reset_work);
+	rc = efx_pci_probe_main(efx);
 
-		if (rc == 0) {
-			if (efx->reset_pending) {
-				/* If there was a scheduled reset during
-				 * probe, the NIC is probably hosed anyway */
-				efx_pci_remove_main(efx);
-				rc = -EIO;
-			} else {
-				break;
-			}
-		}
-
-		/* Retry if a recoverably reset event has been scheduled */
-		if (efx->reset_pending &
-		    ~(1 << RESET_TYPE_INVISIBLE | 1 << RESET_TYPE_ALL) ||
-		    !efx->reset_pending)
-			goto fail3;
+	/* Serialise against efx_reset(). No more resets will be
+	 * scheduled since efx_stop_all() has been called, and we have
+	 * not and never have been registered.
+	 */
+	cancel_work_sync(&efx->reset_work);
 
-		efx->reset_pending = 0;
-	}
+	if (rc)
+		goto fail3;
 
-	if (rc) {
-		netif_err(efx, probe, efx->net_dev, "Could not reset NIC\n");
+	/* If there was a scheduled reset during probe, the NIC is
+	 * probably hosed anyway.
+	 */
+	if (efx->reset_pending) {
+		rc = -EIO;
 		goto fail4;
 	}
 
@@ -2546,18 +2607,27 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
 
 	rc = efx_register_netdev(efx);
 	if (rc)
-		goto fail5;
+		goto fail4;
+
+	rc = efx_sriov_init(efx);
+	if (rc)
+		netif_err(efx, probe, efx->net_dev,
+			  "SR-IOV can't be enabled rc %d\n", rc);
 
 	netif_dbg(efx, probe, efx->net_dev, "initialisation successful\n");
 
+	/* Try to create MTDs, but allow this to fail */
 	rtnl_lock();
-	efx_mtd_probe(efx); /* allowed to fail */
+	rc = efx_mtd_probe(efx);
 	rtnl_unlock();
+	if (rc)
+		netif_warn(efx, probe, efx->net_dev,
+			   "failed to create MTDs (%d)\n", rc);
+
 	return 0;
 
- fail5:
-	efx_pci_remove_main(efx);
  fail4:
+	efx_pci_remove_main(efx);
  fail3:
 	efx_fini_io(efx);
  fail2:
@@ -2578,7 +2648,7 @@ static int efx_pm_freeze(struct device *dev)
 	netif_device_detach(efx->net_dev);
 
 	efx_stop_all(efx);
-	efx_fini_channels(efx);
+	efx_stop_interrupts(efx, false);
 
 	return 0;
 }
@@ -2589,7 +2659,7 @@ static int efx_pm_thaw(struct device *dev)
 
 	efx->state = STATE_INIT;
 
-	efx_init_channels(efx);
+	efx_start_interrupts(efx, false);
 
 	mutex_lock(&efx->mac_lock);
 	efx->phy_op->reconfigure(efx);
@@ -2658,7 +2728,7 @@ static int efx_pm_suspend(struct device *dev)
 	return rc;
 }
 
-static struct dev_pm_ops efx_pm_ops = {
+static const struct dev_pm_ops efx_pm_ops = {
 	.suspend	= efx_pm_suspend,
 	.resume		= efx_pm_resume,
 	.freeze		= efx_pm_freeze,
@@ -2695,6 +2765,10 @@ static int __init efx_init_module(void)
 	if (rc)
 		goto err_notifier;
 
+	rc = efx_init_sriov();
+	if (rc)
+		goto err_sriov;
+
 	reset_workqueue = create_singlethread_workqueue("sfc_reset");
 	if (!reset_workqueue) {
 		rc = -ENOMEM;
@@ -2710,6 +2784,8 @@ static int __init efx_init_module(void)
  err_pci:
 	destroy_workqueue(reset_workqueue);
  err_reset:
+	efx_fini_sriov();
+ err_sriov:
 	unregister_netdevice_notifier(&efx_netdev_notifier);
  err_notifier:
 	return rc;
@@ -2721,6 +2797,7 @@ static void __exit efx_exit_module(void)
 
 	pci_unregister_driver(&efx_pci_driver);
 	destroy_workqueue(reset_workqueue);
+	efx_fini_sriov();
 	unregister_netdevice_notifier(&efx_netdev_notifier);
 
 }
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index a3541ac..4debfe0 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -40,9 +40,9 @@ extern void efx_rx_strategy(struct efx_channel *channel);
 extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
 extern void efx_rx_slow_fill(unsigned long context);
 extern void __efx_rx_packet(struct efx_channel *channel,
-			    struct efx_rx_buffer *rx_buf, bool checksummed);
+			    struct efx_rx_buffer *rx_buf);
 extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
-			  unsigned int len, bool checksummed, bool discard);
+			  unsigned int len, u16 flags);
 extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue);
 
 #define EFX_MAX_DMAQ_SIZE 4096UL
@@ -95,6 +95,7 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {}
 #endif
 
 /* Channels */
+extern int efx_channel_dummy_op_int(struct efx_channel *channel);
 extern void efx_process_channel_now(struct efx_channel *channel);
 extern int
 efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
@@ -145,6 +146,12 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
 	napi_schedule(&channel->napi_str);
 }
 
+static inline void efx_schedule_channel_irq(struct efx_channel *channel)
+{
+	channel->last_irq_cpu = raw_smp_processor_id();
+	efx_schedule_channel(channel);
+}
+
 extern void efx_link_status_changed(struct efx_nic *efx);
 extern void efx_link_set_advertising(struct efx_nic *efx, u32);
 extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 29b2ebf..f22f45f 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -52,11 +52,6 @@ static u64 efx_get_uint_stat(void *field)
 	return *(unsigned int *)field;
 }
 
-static u64 efx_get_ulong_stat(void *field)
-{
-	return *(unsigned long *)field;
-}
-
 static u64 efx_get_u64_stat(void *field)
 {
 	return *(u64 *) field;
@@ -67,12 +62,8 @@ static u64 efx_get_atomic_stat(void *field)
 	return atomic_read((atomic_t *) field);
 }
 
-#define EFX_ETHTOOL_ULONG_MAC_STAT(field)			\
-	EFX_ETHTOOL_STAT(field, mac_stats, field, 		\
-			  unsigned long, efx_get_ulong_stat)
-
 #define EFX_ETHTOOL_U64_MAC_STAT(field)				\
-	EFX_ETHTOOL_STAT(field, mac_stats, field, 		\
+	EFX_ETHTOOL_STAT(field, mac_stats, field,		\
 			  u64, efx_get_u64_stat)
 
 #define EFX_ETHTOOL_UINT_NIC_STAT(name)				\
@@ -91,36 +82,36 @@ static u64 efx_get_atomic_stat(void *field)
 	EFX_ETHTOOL_STAT(tx_##field, tx_queue, field,		\
 			 unsigned int, efx_get_uint_stat)
 
-static struct efx_ethtool_stat efx_ethtool_stats[] = {
+static const struct efx_ethtool_stat efx_ethtool_stats[] = {
 	EFX_ETHTOOL_U64_MAC_STAT(tx_bytes),
 	EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes),
 	EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_control),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_64),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error),
-	EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_packets),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_bad),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_pause),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_control),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_unicast),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_multicast),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_broadcast),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_lt64),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_64),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_65_to_127),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_128_to_255),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_256_to_511),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_512_to_1023),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_1024_to_15xx),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_15xx_to_jumbo),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_gtjumbo),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_collision),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_single_collision),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_multiple_collision),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_collision),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_deferred),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_late_collision),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_deferred),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_non_tcpudp),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_mac_src_error),
+	EFX_ETHTOOL_U64_MAC_STAT(tx_ip_src_error),
 	EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts),
 	EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers),
 	EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets),
@@ -128,34 +119,34 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
 	EFX_ETHTOOL_U64_MAC_STAT(rx_bytes),
 	EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes),
 	EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_good),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_control),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_64),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error),
-	EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_packets),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_good),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_bad),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_pause),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_control),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_unicast),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_multicast),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_broadcast),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_lt64),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_64),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_65_to_127),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_128_to_255),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_256_to_511),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_512_to_1023),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_1024_to_15xx),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_15xx_to_jumbo),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_gtjumbo),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_bad_lt64),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_bad_64_to_15xx),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_bad_15xx_to_jumbo),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_bad_gtjumbo),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_overflow),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_missed),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_false_carrier),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_symbol_error),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_align_error),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_length_error),
+	EFX_ETHTOOL_U64_MAC_STAT(rx_internal_error),
 	EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt),
 	EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset),
 	EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc),
@@ -404,10 +395,6 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
 			      &tests->eventq_int[channel->channel],
 			      EFX_CHANNEL_NAME(channel),
 			      "eventq.int", NULL);
-		efx_fill_test(n++, strings, data,
-			      &tests->eventq_poll[channel->channel],
-			      EFX_CHANNEL_NAME(channel),
-			      "eventq.poll", NULL);
 	}
 
 	efx_fill_test(n++, strings, data, &tests->registers,
@@ -486,16 +473,17 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_mac_stats *mac_stats = &efx->mac_stats;
-	struct efx_ethtool_stat *stat;
+	const struct efx_ethtool_stat *stat;
 	struct efx_channel *channel;
 	struct efx_tx_queue *tx_queue;
-	struct rtnl_link_stats64 temp;
 	int i;
 
 	EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS);
 
+	spin_lock_bh(&efx->stats_lock);
+
 	/* Update MAC and NIC statistics */
-	dev_get_stats(net_dev, &temp);
+	efx->type->update_stats(efx);
 
 	/* Fill detailed statistics buffer */
 	for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) {
@@ -525,6 +513,8 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
 			break;
 		}
 	}
+
+	spin_unlock_bh(&efx->stats_lock);
 }
 
 static void efx_ethtool_self_test(struct net_device *net_dev,
@@ -747,7 +737,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
 			/* Recover by resetting the EM block */
 			falcon_stop_nic_stats(efx);
 			falcon_drain_tx_fifo(efx);
-			efx->mac_op->reconfigure(efx);
+			falcon_reconfigure_xmac(efx);
 			falcon_start_nic_stats(efx);
 		} else {
 			/* Schedule a reset to recover */
@@ -772,7 +762,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
 	/* Reconfigure the MAC. The PHY *may* generate a link state change event
 	 * if the user just changed the advertised capabilities, but there's no
 	 * harm doing this twice */
-	efx->mac_op->reconfigure(efx);
+	efx->type->reconfigure_mac(efx);
 
 out:
 	mutex_unlock(&efx->mac_lock);
@@ -818,11 +808,16 @@ static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
 	return efx_reset(efx, rc);
 }
 
+/* MAC address mask including only MC flag */
+static const u8 mac_addr_mc_mask[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
+
 static int efx_ethtool_get_class_rule(struct efx_nic *efx,
 				      struct ethtool_rx_flow_spec *rule)
 {
 	struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
 	struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
+	struct ethhdr *mac_entry = &rule->h_u.ether_spec;
+	struct ethhdr *mac_mask = &rule->m_u.ether_spec;
 	struct efx_filter_spec spec;
 	u16 vid;
 	u8 proto;
@@ -838,11 +833,18 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx,
 	else
 		rule->ring_cookie = spec.dmaq_id;
 
-	rc = efx_filter_get_eth_local(&spec, &vid,
-				      rule->h_u.ether_spec.h_dest);
+	if (spec.type == EFX_FILTER_MC_DEF || spec.type == EFX_FILTER_UC_DEF) {
+		rule->flow_type = ETHER_FLOW;
+		memcpy(mac_mask->h_dest, mac_addr_mc_mask, ETH_ALEN);
+		if (spec.type == EFX_FILTER_MC_DEF)
+			memcpy(mac_entry->h_dest, mac_addr_mc_mask, ETH_ALEN);
+		return 0;
+	}
+
+	rc = efx_filter_get_eth_local(&spec, &vid, mac_entry->h_dest);
 	if (rc == 0) {
 		rule->flow_type = ETHER_FLOW;
-		memset(rule->m_u.ether_spec.h_dest, ~0, ETH_ALEN);
+		memset(mac_mask->h_dest, ~0, ETH_ALEN);
 		if (vid != EFX_FILTER_VID_UNSPEC) {
 			rule->flow_type |= FLOW_EXT;
 			rule->h_ext.vlan_tci = htons(vid);
@@ -1011,27 +1013,40 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx,
 	}
 
 	case ETHER_FLOW | FLOW_EXT:
-		/* Must match all or none of VID */
-		if (rule->m_ext.vlan_tci != htons(0xfff) &&
-		    rule->m_ext.vlan_tci != 0)
-			return -EINVAL;
-	case ETHER_FLOW:
-		/* Must match all of destination */
-		if (!is_broadcast_ether_addr(mac_mask->h_dest))
-			return -EINVAL;
-		/* and nothing else */
+	case ETHER_FLOW: {
+		u16 vlan_tag_mask = (rule->flow_type & FLOW_EXT ?
+				     ntohs(rule->m_ext.vlan_tci) : 0);
+
+		/* Must not match on source address or Ethertype */
 		if (!is_zero_ether_addr(mac_mask->h_source) ||
 		    mac_mask->h_proto)
 			return -EINVAL;
 
-		rc = efx_filter_set_eth_local(
-			&spec,
-			(rule->flow_type & FLOW_EXT && rule->m_ext.vlan_tci) ?
-			ntohs(rule->h_ext.vlan_tci) : EFX_FILTER_VID_UNSPEC,
-			mac_entry->h_dest);
+		/* Is it a default UC or MC filter? */
+		if (!compare_ether_addr(mac_mask->h_dest, mac_addr_mc_mask) &&
+		    vlan_tag_mask == 0) {
+			if (is_multicast_ether_addr(mac_entry->h_dest))
+				rc = efx_filter_set_mc_def(&spec);
+			else
+				rc = efx_filter_set_uc_def(&spec);
+		}
+		/* Otherwise, it must match all of destination and all
+		 * or none of VID.
+		 */
+		else if (is_broadcast_ether_addr(mac_mask->h_dest) &&
+			 (vlan_tag_mask == 0xfff || vlan_tag_mask == 0)) {
+			rc = efx_filter_set_eth_local(
+				&spec,
+				vlan_tag_mask ?
+				ntohs(rule->h_ext.vlan_tci) : EFX_FILTER_VID_UNSPEC,
+				mac_entry->h_dest);
+		} else {
+			rc = -EINVAL;
+		}
 		if (rc)
 			return rc;
 		break;
+	}
 
 	default:
 		return -EINVAL;
@@ -1070,7 +1085,8 @@ static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 
-	return (efx_nic_rev(efx) < EFX_REV_FALCON_B0 ?
+	return ((efx_nic_rev(efx) < EFX_REV_FALCON_B0 ||
+		 efx->n_rx_channels == 1) ?
 		0 : ARRAY_SIZE(efx->rx_indir_table));
 }
 
diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c
index 8ae1ebd..3a1ca2b 100644
--- a/drivers/net/ethernet/sfc/falcon.c
+++ b/drivers/net/ethernet/sfc/falcon.c
@@ -19,7 +19,6 @@
 #include "net_driver.h"
 #include "bitfield.h"
 #include "efx.h"
-#include "mac.h"
 #include "spi.h"
 #include "nic.h"
 #include "regs.h"
@@ -89,7 +88,7 @@ static int falcon_getscl(void *data)
 	return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN);
 }
 
-static struct i2c_algo_bit_data falcon_i2c_bit_operations = {
+static const struct i2c_algo_bit_data falcon_i2c_bit_operations = {
 	.setsda		= falcon_setsda,
 	.setscl		= falcon_setscl,
 	.getsda		= falcon_getsda,
@@ -104,8 +103,6 @@ static void falcon_push_irq_moderation(struct efx_channel *channel)
 	efx_dword_t timer_cmd;
 	struct efx_nic *efx = channel->efx;
 
-	BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_AB_TC_TIMER_VAL_WIDTH));
-
 	/* Set timer register */
 	if (channel->irq_moderation) {
 		EFX_POPULATE_DWORD_2(timer_cmd,
@@ -177,27 +174,24 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id)
 		   "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n",
 		   irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
 
+	/* Check to see if we have a serious error condition */
+	syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
+	if (unlikely(syserr))
+		return efx_nic_fatal_interrupt(efx);
+
 	/* Determine interrupting queues, clear interrupt status
 	 * register and acknowledge the device interrupt.
 	 */
 	BUILD_BUG_ON(FSF_AZ_NET_IVEC_INT_Q_WIDTH > EFX_MAX_CHANNELS);
 	queues = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_INT_Q);
-
-	/* Check to see if we have a serious error condition */
-	if (queues & (1U << efx->fatal_irq_level)) {
-		syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
-		if (unlikely(syserr))
-			return efx_nic_fatal_interrupt(efx);
-	}
-
 	EFX_ZERO_OWORD(*int_ker);
 	wmb(); /* Ensure the vector is cleared before interrupt ack */
 	falcon_irq_ack_a1(efx);
 
 	if (queues & 1)
-		efx_schedule_channel(efx_get_channel(efx, 0));
+		efx_schedule_channel_irq(efx_get_channel(efx, 0));
 	if (queues & 2)
-		efx_schedule_channel(efx_get_channel(efx, 1));
+		efx_schedule_channel_irq(efx_get_channel(efx, 1));
 	return IRQ_HANDLED;
 }
 /**************************************************************************
@@ -613,7 +607,7 @@ static void falcon_stats_complete(struct efx_nic *efx)
 	nic_data->stats_pending = false;
 	if (*nic_data->stats_dma_done == FALCON_STATS_DONE) {
 		rmb(); /* read the done flag before the stats */
-		efx->mac_op->update_stats(efx);
+		falcon_update_stats_xmac(efx);
 	} else {
 		netif_err(efx, hw, efx->net_dev,
 			  "timed out waiting for statistics\n");
@@ -670,7 +664,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx)
 	falcon_reset_macs(efx);
 
 	efx->phy_op->reconfigure(efx);
-	rc = efx->mac_op->reconfigure(efx);
+	rc = falcon_reconfigure_xmac(efx);
 	BUG_ON(rc);
 
 	falcon_start_nic_stats(efx);
@@ -1218,7 +1212,7 @@ static void falcon_monitor(struct efx_nic *efx)
 		falcon_deconfigure_mac_wrapper(efx);
 
 		falcon_reset_macs(efx);
-		rc = efx->mac_op->reconfigure(efx);
+		rc = falcon_reconfigure_xmac(efx);
 		BUG_ON(rc);
 
 		falcon_start_nic_stats(efx);
@@ -1339,6 +1333,12 @@ out:
 	return rc;
 }
 
+static void falcon_dimension_resources(struct efx_nic *efx)
+{
+	efx->rx_dc_base = 0x20000;
+	efx->tx_dc_base = 0x26000;
+}
+
 /* Probe all SPI devices on the NIC */
 static void falcon_probe_spi_devices(struct efx_nic *efx)
 {
@@ -1472,6 +1472,8 @@ static int falcon_probe_nic(struct efx_nic *efx)
 		goto fail5;
 	}
 
+	efx->timer_quantum_ns = 4968; /* 621 cycles */
+
 	/* Initialise I2C adapter */
 	board = falcon_board(efx);
 	board->i2c_adap.owner = THIS_MODULE;
@@ -1676,7 +1678,7 @@ static void falcon_update_nic_stats(struct efx_nic *efx)
 	    *nic_data->stats_dma_done == FALCON_STATS_DONE) {
 		nic_data->stats_pending = false;
 		rmb(); /* read the done flag before the stats */
-		efx->mac_op->update_stats(efx);
+		falcon_update_stats_xmac(efx);
 	}
 }
 
@@ -1753,6 +1755,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
 	.probe = falcon_probe_nic,
 	.remove = falcon_remove_nic,
 	.init = falcon_init_nic,
+	.dimension_resources = falcon_dimension_resources,
 	.fini = efx_port_dummy_op_void,
 	.monitor = falcon_monitor,
 	.map_reset_reason = falcon_map_reset_reason,
@@ -1767,13 +1770,13 @@ const struct efx_nic_type falcon_a1_nic_type = {
 	.stop_stats = falcon_stop_nic_stats,
 	.set_id_led = falcon_set_id_led,
 	.push_irq_moderation = falcon_push_irq_moderation,
-	.push_multicast_hash = falcon_push_multicast_hash,
 	.reconfigure_port = falcon_reconfigure_port,
+	.reconfigure_mac = falcon_reconfigure_xmac,
+	.check_mac_fault = falcon_xmac_check_fault,
 	.get_wol = falcon_get_wol,
 	.set_wol = falcon_set_wol,
 	.resume_wol = efx_port_dummy_op_void,
 	.test_nvram = falcon_test_nvram,
-	.default_mac_ops = &falcon_xmac_operations,
 
 	.revision = EFX_REV_FALCON_A1,
 	.mem_map_size = 0x20000,
@@ -1786,8 +1789,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
 	.rx_buffer_padding = 0x24,
 	.max_interrupt_mode = EFX_INT_MODE_MSI,
 	.phys_addr_channels = 4,
-	.tx_dc_base = 0x130000,
-	.rx_dc_base = 0x100000,
+	.timer_period_max =  1 << FRF_AB_TC_TIMER_VAL_WIDTH,
 	.offload_features = NETIF_F_IP_CSUM,
 };
 
@@ -1795,6 +1797,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
 	.probe = falcon_probe_nic,
 	.remove = falcon_remove_nic,
 	.init = falcon_init_nic,
+	.dimension_resources = falcon_dimension_resources,
 	.fini = efx_port_dummy_op_void,
 	.monitor = falcon_monitor,
 	.map_reset_reason = falcon_map_reset_reason,
@@ -1809,14 +1812,14 @@ const struct efx_nic_type falcon_b0_nic_type = {
 	.stop_stats = falcon_stop_nic_stats,
 	.set_id_led = falcon_set_id_led,
 	.push_irq_moderation = falcon_push_irq_moderation,
-	.push_multicast_hash = falcon_push_multicast_hash,
 	.reconfigure_port = falcon_reconfigure_port,
+	.reconfigure_mac = falcon_reconfigure_xmac,
+	.check_mac_fault = falcon_xmac_check_fault,
 	.get_wol = falcon_get_wol,
 	.set_wol = falcon_set_wol,
 	.resume_wol = efx_port_dummy_op_void,
 	.test_registers = falcon_b0_test_registers,
 	.test_nvram = falcon_test_nvram,
-	.default_mac_ops = &falcon_xmac_operations,
 
 	.revision = EFX_REV_FALCON_B0,
 	/* Map everything up to and including the RSS indirection
@@ -1837,8 +1840,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
 	.phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
 				   * interrupt handler only supports 32
 				   * channels */
-	.tx_dc_base = 0x130000,
-	.rx_dc_base = 0x100000,
+	.timer_period_max =  1 << FRF_AB_TC_TIMER_VAL_WIDTH,
 	.offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
 };
 
diff --git a/drivers/net/ethernet/sfc/falcon_boards.c b/drivers/net/ethernet/sfc/falcon_boards.c
index 6cc16b8..2084cc6 100644
--- a/drivers/net/ethernet/sfc/falcon_boards.c
+++ b/drivers/net/ethernet/sfc/falcon_boards.c
@@ -87,7 +87,7 @@ static const u8 falcon_lm87_common_regs[] = {
 	0
 };
 
-static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
+static int efx_init_lm87(struct efx_nic *efx, const struct i2c_board_info *info,
 			 const u8 *reg_values)
 {
 	struct falcon_board *board = falcon_board(efx);
@@ -179,7 +179,7 @@ static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
 #else /* !CONFIG_SENSORS_LM87 */
 
 static inline int
-efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
+efx_init_lm87(struct efx_nic *efx, const struct i2c_board_info *info,
 	      const u8 *reg_values)
 {
 	return 0;
@@ -442,7 +442,7 @@ static int sfe4001_check_hw(struct efx_nic *efx)
 	return (status < 0) ? -EIO : -ERANGE;
 }
 
-static struct i2c_board_info sfe4001_hwmon_info = {
+static const struct i2c_board_info sfe4001_hwmon_info = {
 	I2C_BOARD_INFO("max6647", 0x4e),
 };
 
@@ -522,7 +522,7 @@ static const u8 sfe4002_lm87_regs[] = {
 	0
 };
 
-static struct i2c_board_info sfe4002_hwmon_info = {
+static const struct i2c_board_info sfe4002_hwmon_info = {
 	I2C_BOARD_INFO("lm87", 0x2e),
 	.platform_data	= &sfe4002_lm87_channel,
 };
@@ -591,7 +591,7 @@ static const u8 sfn4112f_lm87_regs[] = {
 	0
 };
 
-static struct i2c_board_info sfn4112f_hwmon_info = {
+static const struct i2c_board_info sfn4112f_hwmon_info = {
 	I2C_BOARD_INFO("lm87", 0x2e),
 	.platform_data	= &sfn4112f_lm87_channel,
 };
@@ -653,7 +653,7 @@ static const u8 sfe4003_lm87_regs[] = {
 	0
 };
 
-static struct i2c_board_info sfe4003_hwmon_info = {
+static const struct i2c_board_info sfe4003_hwmon_info = {
 	I2C_BOARD_INFO("lm87", 0x2e),
 	.platform_data	= &sfe4003_lm87_channel,
 };
diff --git a/drivers/net/ethernet/sfc/falcon_xmac.c b/drivers/net/ethernet/sfc/falcon_xmac.c
index 9516452..6106ef1 100644
--- a/drivers/net/ethernet/sfc/falcon_xmac.c
+++ b/drivers/net/ethernet/sfc/falcon_xmac.c
@@ -14,7 +14,6 @@
 #include "nic.h"
 #include "regs.h"
 #include "io.h"
-#include "mac.h"
 #include "mdio_10g.h"
 #include "workarounds.h"
 
@@ -139,7 +138,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx)
 	return (efx->loopback_mode == LOOPBACK_XGMII ||
 		falcon_xgxs_link_ok(efx)) &&
 		(!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) ||
-		 LOOPBACK_INTERNAL(efx) || 
+		 LOOPBACK_INTERNAL(efx) ||
 		 efx_mdio_phyxgxs_lane_sync(efx));
 }
 
@@ -270,12 +269,12 @@ static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries)
 	return mac_up;
 }
 
-static bool falcon_xmac_check_fault(struct efx_nic *efx)
+bool falcon_xmac_check_fault(struct efx_nic *efx)
 {
 	return !falcon_xmac_link_ok_retry(efx, 5);
 }
 
-static int falcon_reconfigure_xmac(struct efx_nic *efx)
+int falcon_reconfigure_xmac(struct efx_nic *efx)
 {
 	struct falcon_nic_data *nic_data = efx->nic_data;
 
@@ -290,7 +289,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx)
 	return 0;
 }
 
-static void falcon_update_stats_xmac(struct efx_nic *efx)
+void falcon_update_stats_xmac(struct efx_nic *efx)
 {
 	struct efx_mac_stats *mac_stats = &efx->mac_stats;
 
@@ -361,9 +360,3 @@ void falcon_poll_xmac(struct efx_nic *efx)
 	nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1);
 	falcon_ack_status_intr(efx);
 }
-
-const struct efx_mac_operations falcon_xmac_operations = {
-	.reconfigure	= falcon_reconfigure_xmac,
-	.update_stats	= falcon_update_stats_xmac,
-	.check_fault	= falcon_xmac_check_fault,
-};
diff --git a/drivers/net/ethernet/sfc/filter.c b/drivers/net/ethernet/sfc/filter.c
index 1fbbbee..fea7f73 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -35,9 +35,17 @@
 enum efx_filter_table_id {
 	EFX_FILTER_TABLE_RX_IP = 0,
 	EFX_FILTER_TABLE_RX_MAC,
+	EFX_FILTER_TABLE_RX_DEF,
+	EFX_FILTER_TABLE_TX_MAC,
 	EFX_FILTER_TABLE_COUNT,
 };
 
+enum efx_filter_index {
+	EFX_FILTER_INDEX_UC_DEF,
+	EFX_FILTER_INDEX_MC_DEF,
+	EFX_FILTER_SIZE_RX_DEF,
+};
+
 struct efx_filter_table {
 	enum efx_filter_table_id id;
 	u32		offset;		/* address of table relative to BAR */
@@ -90,8 +98,9 @@ efx_filter_spec_table_id(const struct efx_filter_spec *spec)
 	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_WILD >> 2));
 	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_FULL >> 2));
 	BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_WILD >> 2));
+	BUILD_BUG_ON(EFX_FILTER_TABLE_TX_MAC != EFX_FILTER_TABLE_RX_MAC + 2);
 	EFX_BUG_ON_PARANOID(spec->type == EFX_FILTER_UNSPEC);
-	return spec->type >> 2;
+	return (spec->type >> 2) + ((spec->flags & EFX_FILTER_FLAG_TX) ? 2 : 0);
 }
 
 static struct efx_filter_table *
@@ -109,7 +118,7 @@ static void efx_filter_table_reset_search_depth(struct efx_filter_table *table)
 	memset(table->search_depth, 0, sizeof(table->search_depth));
 }
 
-static void efx_filter_push_rx_limits(struct efx_nic *efx)
+static void efx_filter_push_rx_config(struct efx_nic *efx)
 {
 	struct efx_filter_state *state = efx->filter_state;
 	struct efx_filter_table *table;
@@ -143,9 +152,58 @@ static void efx_filter_push_rx_limits(struct efx_nic *efx)
 			FILTER_CTL_SRCH_FUDGE_WILD);
 	}
 
+	table = &state->table[EFX_FILTER_TABLE_RX_DEF];
+	if (table->size) {
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_UNICAST_NOMATCH_Q_ID,
+			table->spec[EFX_FILTER_INDEX_UC_DEF].dmaq_id);
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED,
+			!!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags &
+			   EFX_FILTER_FLAG_RX_RSS));
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE,
+			!!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags &
+			   EFX_FILTER_FLAG_RX_OVERRIDE_IP));
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_MULTICAST_NOMATCH_Q_ID,
+			table->spec[EFX_FILTER_INDEX_MC_DEF].dmaq_id);
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED,
+			!!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags &
+			   EFX_FILTER_FLAG_RX_RSS));
+		EFX_SET_OWORD_FIELD(
+			filter_ctl, FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE,
+			!!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags &
+			   EFX_FILTER_FLAG_RX_OVERRIDE_IP));
+	}
+
 	efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
 }
 
+static void efx_filter_push_tx_limits(struct efx_nic *efx)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	struct efx_filter_table *table;
+	efx_oword_t tx_cfg;
+
+	efx_reado(efx, &tx_cfg, FR_AZ_TX_CFG);
+
+	table = &state->table[EFX_FILTER_TABLE_TX_MAC];
+	if (table->size) {
+		EFX_SET_OWORD_FIELD(
+			tx_cfg, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,
+			table->search_depth[EFX_FILTER_MAC_FULL] +
+			FILTER_CTL_SRCH_FUDGE_FULL);
+		EFX_SET_OWORD_FIELD(
+			tx_cfg, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,
+			table->search_depth[EFX_FILTER_MAC_WILD] +
+			FILTER_CTL_SRCH_FUDGE_WILD);
+	}
+
+	efx_writeo(efx, &tx_cfg, FR_AZ_TX_CFG);
+}
+
 static inline void __efx_filter_set_ipv4(struct efx_filter_spec *spec,
 					 __be32 host1, __be16 port1,
 					 __be32 host2, __be16 port2)
@@ -300,7 +358,8 @@ int efx_filter_get_ipv4_full(const struct efx_filter_spec *spec,
 int efx_filter_set_eth_local(struct efx_filter_spec *spec,
 			     u16 vid, const u8 *addr)
 {
-	EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
+	EFX_BUG_ON_PARANOID(!(spec->flags &
+			      (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)));
 
 	/* This cannot currently be combined with other filtering */
 	if (spec->type != EFX_FILTER_UNSPEC)
@@ -319,6 +378,52 @@ int efx_filter_set_eth_local(struct efx_filter_spec *spec,
 	return 0;
 }
 
+/**
+ * efx_filter_set_uc_def - specify matching otherwise-unmatched unicast
+ * @spec: Specification to initialise
+ */
+int efx_filter_set_uc_def(struct efx_filter_spec *spec)
+{
+	EFX_BUG_ON_PARANOID(!(spec->flags &
+			      (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)));
+
+	if (spec->type != EFX_FILTER_UNSPEC)
+		return -EINVAL;
+
+	spec->type = EFX_FILTER_UC_DEF;
+	memset(spec->data, 0, sizeof(spec->data)); /* ensure equality */
+	return 0;
+}
+
+/**
+ * efx_filter_set_mc_def - specify matching otherwise-unmatched multicast
+ * @spec: Specification to initialise
+ */
+int efx_filter_set_mc_def(struct efx_filter_spec *spec)
+{
+	EFX_BUG_ON_PARANOID(!(spec->flags &
+			      (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)));
+
+	if (spec->type != EFX_FILTER_UNSPEC)
+		return -EINVAL;
+
+	spec->type = EFX_FILTER_MC_DEF;
+	memset(spec->data, 0, sizeof(spec->data)); /* ensure equality */
+	return 0;
+}
+
+static void efx_filter_reset_rx_def(struct efx_nic *efx, unsigned filter_idx)
+{
+	struct efx_filter_state *state = efx->filter_state;
+	struct efx_filter_table *table = &state->table[EFX_FILTER_TABLE_RX_DEF];
+	struct efx_filter_spec *spec = &table->spec[filter_idx];
+
+	efx_filter_init_rx(spec, EFX_FILTER_PRI_MANUAL,
+			   EFX_FILTER_FLAG_RX_RSS, 0);
+	spec->type = EFX_FILTER_UC_DEF + filter_idx;
+	table->used_bitmap[0] |= 1 << filter_idx;
+}
+
 int efx_filter_get_eth_local(const struct efx_filter_spec *spec,
 			     u16 *vid, u8 *addr)
 {
@@ -366,6 +471,13 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
 		break;
 	}
 
+	case EFX_FILTER_TABLE_RX_DEF:
+		/* One filter spec per type */
+		BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0);
+		BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF !=
+			     EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF);
+		return spec->type - EFX_FILTER_UC_DEF;
+
 	case EFX_FILTER_TABLE_RX_MAC: {
 		bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
 		EFX_POPULATE_OWORD_8(
@@ -385,6 +497,18 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
 		break;
 	}
 
+	case EFX_FILTER_TABLE_TX_MAC: {
+		bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
+		EFX_POPULATE_OWORD_5(*filter,
+				     FRF_CZ_TMFT_TXQ_ID, spec->dmaq_id,
+				     FRF_CZ_TMFT_WILDCARD_MATCH, is_wild,
+				     FRF_CZ_TMFT_SRC_MAC_HI, spec->data[2],
+				     FRF_CZ_TMFT_SRC_MAC_LO, spec->data[1],
+				     FRF_CZ_TMFT_VLAN_ID, spec->data[0]);
+		data3 = is_wild | spec->dmaq_id << 1;
+		break;
+	}
+
 	default:
 		BUG();
 	}
@@ -399,6 +523,10 @@ static bool efx_filter_equal(const struct efx_filter_spec *left,
 	    memcmp(left->data, right->data, sizeof(left->data)))
 		return false;
 
+	if (left->flags & EFX_FILTER_FLAG_TX &&
+	    left->dmaq_id != right->dmaq_id)
+		return false;
+
 	return true;
 }
 
@@ -448,23 +576,40 @@ static int efx_filter_search(struct efx_filter_table *table,
  * MAC filters without overriding behaviour.
  */
 
+#define EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP	0
+#define EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP	1
+#define EFX_FILTER_MATCH_PRI_NORMAL_BASE	2
+
 #define EFX_FILTER_INDEX_WIDTH	13
 #define EFX_FILTER_INDEX_MASK	((1 << EFX_FILTER_INDEX_WIDTH) - 1)
 
 static inline u32 efx_filter_make_id(enum efx_filter_table_id table_id,
 				     unsigned int index, u8 flags)
 {
-	return (table_id == EFX_FILTER_TABLE_RX_MAC &&
-		flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) ?
-		index :
-		(table_id + 1) << EFX_FILTER_INDEX_WIDTH | index;
+	unsigned int match_pri = EFX_FILTER_MATCH_PRI_NORMAL_BASE + table_id;
+
+	if (flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) {
+		if (table_id == EFX_FILTER_TABLE_RX_MAC)
+			match_pri = EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP;
+		else if (table_id == EFX_FILTER_TABLE_RX_DEF)
+			match_pri = EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP;
+	}
+
+	return match_pri << EFX_FILTER_INDEX_WIDTH | index;
 }
 
 static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id)
 {
-	return (id <= EFX_FILTER_INDEX_MASK) ?
-		EFX_FILTER_TABLE_RX_MAC :
-		(id >> EFX_FILTER_INDEX_WIDTH) - 1;
+	unsigned int match_pri = id >> EFX_FILTER_INDEX_WIDTH;
+
+	switch (match_pri) {
+	case EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP:
+		return EFX_FILTER_TABLE_RX_MAC;
+	case EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP:
+		return EFX_FILTER_TABLE_RX_DEF;
+	default:
+		return match_pri - EFX_FILTER_MATCH_PRI_NORMAL_BASE;
+	}
 }
 
 static inline unsigned int efx_filter_id_index(u32 id)
@@ -474,23 +619,30 @@ static inline unsigned int efx_filter_id_index(u32 id)
 
 static inline u8 efx_filter_id_flags(u32 id)
 {
-	return (id <= EFX_FILTER_INDEX_MASK) ?
-		EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_OVERRIDE_IP :
-		EFX_FILTER_FLAG_RX;
+	unsigned int match_pri = id >> EFX_FILTER_INDEX_WIDTH;
+
+	if (match_pri < EFX_FILTER_MATCH_PRI_NORMAL_BASE)
+		return EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_OVERRIDE_IP;
+	else if (match_pri <=
+		 EFX_FILTER_MATCH_PRI_NORMAL_BASE + EFX_FILTER_TABLE_RX_DEF)
+		return EFX_FILTER_FLAG_RX;
+	else
+		return EFX_FILTER_FLAG_TX;
 }
 
 u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
 {
 	struct efx_filter_state *state = efx->filter_state;
+	unsigned int table_id = EFX_FILTER_TABLE_RX_DEF;
 
-	if (state->table[EFX_FILTER_TABLE_RX_MAC].size != 0)
-		return ((EFX_FILTER_TABLE_RX_MAC + 1) << EFX_FILTER_INDEX_WIDTH)
-			+ state->table[EFX_FILTER_TABLE_RX_MAC].size;
-	else if (state->table[EFX_FILTER_TABLE_RX_IP].size != 0)
-		return ((EFX_FILTER_TABLE_RX_IP + 1) << EFX_FILTER_INDEX_WIDTH)
-			+ state->table[EFX_FILTER_TABLE_RX_IP].size;
-	else
-		return 0;
+	do {
+		if (state->table[table_id].size != 0)
+			return ((EFX_FILTER_MATCH_PRI_NORMAL_BASE + table_id)
+				<< EFX_FILTER_INDEX_WIDTH) +
+				state->table[table_id].size;
+	} while (table_id--);
+
+	return 0;
 }
 
 /**
@@ -548,12 +700,20 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
 	}
 	*saved_spec = *spec;
 
-	if (table->search_depth[spec->type] < depth) {
-		table->search_depth[spec->type] = depth;
-		efx_filter_push_rx_limits(efx);
-	}
+	if (table->id == EFX_FILTER_TABLE_RX_DEF) {
+		efx_filter_push_rx_config(efx);
+	} else {
+		if (table->search_depth[spec->type] < depth) {
+			table->search_depth[spec->type] = depth;
+			if (spec->flags & EFX_FILTER_FLAG_TX)
+				efx_filter_push_tx_limits(efx);
+			else
+				efx_filter_push_rx_config(efx);
+		}
 
-	efx_writeo(efx, &filter, table->offset + table->step * filter_idx);
+		efx_writeo(efx, &filter,
+			   table->offset + table->step * filter_idx);
+	}
 
 	netif_vdbg(efx, hw, efx->net_dev,
 		   "%s: filter type %d index %d rxq %u set",
@@ -571,7 +731,11 @@ static void efx_filter_table_clear_entry(struct efx_nic *efx,
 {
 	static efx_oword_t filter;
 
-	if (test_bit(filter_idx, table->used_bitmap)) {
+	if (table->id == EFX_FILTER_TABLE_RX_DEF) {
+		/* RX default filters must always exist */
+		efx_filter_reset_rx_def(efx, filter_idx);
+		efx_filter_push_rx_config(efx);
+	} else if (test_bit(filter_idx, table->used_bitmap)) {
 		__clear_bit(filter_idx, table->used_bitmap);
 		--table->used;
 		memset(&table->spec[filter_idx], 0, sizeof(table->spec[0]));
@@ -617,7 +781,8 @@ int efx_filter_remove_id_safe(struct efx_nic *efx,
 	spin_lock_bh(&state->lock);
 
 	if (test_bit(filter_idx, table->used_bitmap) &&
-	    spec->priority == priority && spec->flags == filter_flags) {
+	    spec->priority == priority &&
+	    !((spec->flags ^ filter_flags) & EFX_FILTER_FLAG_RX_OVERRIDE_IP)) {
 		efx_filter_table_clear_entry(efx, table, filter_idx);
 		if (table->used == 0)
 			efx_filter_table_reset_search_depth(table);
@@ -668,7 +833,8 @@ int efx_filter_get_filter_safe(struct efx_nic *efx,
 	spin_lock_bh(&state->lock);
 
 	if (test_bit(filter_idx, table->used_bitmap) &&
-	    spec->priority == priority && spec->flags == filter_flags) {
+	    spec->priority == priority &&
+	    !((spec->flags ^ filter_flags) & EFX_FILTER_FLAG_RX_OVERRIDE_IP)) {
 		*spec_buf = *spec;
 		rc = 0;
 	} else {
@@ -722,7 +888,7 @@ u32 efx_filter_count_rx_used(struct efx_nic *efx,
 	spin_lock_bh(&state->lock);
 
 	for (table_id = EFX_FILTER_TABLE_RX_IP;
-	     table_id <= EFX_FILTER_TABLE_RX_MAC;
+	     table_id <= EFX_FILTER_TABLE_RX_DEF;
 	     table_id++) {
 		table = &state->table[table_id];
 		for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
@@ -750,7 +916,7 @@ s32 efx_filter_get_rx_ids(struct efx_nic *efx,
 	spin_lock_bh(&state->lock);
 
 	for (table_id = EFX_FILTER_TABLE_RX_IP;
-	     table_id <= EFX_FILTER_TABLE_RX_MAC;
+	     table_id <= EFX_FILTER_TABLE_RX_DEF;
 	     table_id++) {
 		table = &state->table[table_id];
 		for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
@@ -785,6 +951,11 @@ void efx_restore_filters(struct efx_nic *efx)
 
 	for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
 		table = &state->table[table_id];
+
+		/* Check whether this is a regular register table */
+		if (table->step == 0)
+			continue;
+
 		for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
 			if (!test_bit(filter_idx, table->used_bitmap))
 				continue;
@@ -794,7 +965,8 @@ void efx_restore_filters(struct efx_nic *efx)
 		}
 	}
 
-	efx_filter_push_rx_limits(efx);
+	efx_filter_push_rx_config(efx);
+	efx_filter_push_tx_limits(efx);
 
 	spin_unlock_bh(&state->lock);
 }
@@ -833,6 +1005,16 @@ int efx_probe_filters(struct efx_nic *efx)
 		table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
 		table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
 		table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
+
+		table = &state->table[EFX_FILTER_TABLE_RX_DEF];
+		table->id = EFX_FILTER_TABLE_RX_DEF;
+		table->size = EFX_FILTER_SIZE_RX_DEF;
+
+		table = &state->table[EFX_FILTER_TABLE_TX_MAC];
+		table->id = EFX_FILTER_TABLE_TX_MAC;
+		table->offset = FR_CZ_TX_MAC_FILTER_TBL0;
+		table->size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;
+		table->step = FR_CZ_TX_MAC_FILTER_TBL0_STEP;
 	}
 
 	for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
@@ -849,6 +1031,15 @@ int efx_probe_filters(struct efx_nic *efx)
 			goto fail;
 	}
 
+	if (state->table[EFX_FILTER_TABLE_RX_DEF].size) {
+		/* RX default filters must always exist */
+		unsigned i;
+		for (i = 0; i < EFX_FILTER_SIZE_RX_DEF; i++)
+			efx_filter_reset_rx_def(efx, i);
+	}
+
+	efx_filter_push_rx_config(efx);
+
 	return 0;
 
 fail:
diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
index 3d4108c..3c77802 100644
--- a/drivers/net/ethernet/sfc/filter.h
+++ b/drivers/net/ethernet/sfc/filter.h
@@ -20,6 +20,8 @@
  * @EFX_FILTER_UDP_WILD: Matching UDP/IPv4 destination (host, port)
  * @EFX_FILTER_MAC_FULL: Matching Ethernet destination MAC address, VID
  * @EFX_FILTER_MAC_WILD: Matching Ethernet destination MAC address
+ * @EFX_FILTER_UC_DEF: Matching all otherwise unmatched unicast
+ * @EFX_FILTER_MC_DEF: Matching all otherwise unmatched multicast
  * @EFX_FILTER_UNSPEC: Match type is unspecified
  *
  * Falcon NICs only support the TCP/IPv4 and UDP/IPv4 filter types.
@@ -31,6 +33,8 @@ enum efx_filter_type {
 	EFX_FILTER_UDP_WILD,
 	EFX_FILTER_MAC_FULL = 4,
 	EFX_FILTER_MAC_WILD,
+	EFX_FILTER_UC_DEF = 8,
+	EFX_FILTER_MC_DEF,
 	EFX_FILTER_TYPE_COUNT,		/* number of specific types */
 	EFX_FILTER_UNSPEC = 0xf,
 };
@@ -39,7 +43,8 @@ enum efx_filter_type {
  * enum efx_filter_priority - priority of a hardware filter specification
  * @EFX_FILTER_PRI_HINT: Performance hint
  * @EFX_FILTER_PRI_MANUAL: Manually configured filter
- * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour
+ * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour (user-level
+ *	networking and SR-IOV)
  */
 enum efx_filter_priority {
 	EFX_FILTER_PRI_HINT = 0,
@@ -60,12 +65,14 @@ enum efx_filter_priority {
  *	any IP filter that matches the same packet.  By default, IP
  *	filters take precedence.
  * @EFX_FILTER_FLAG_RX: Filter is for RX
+ * @EFX_FILTER_FLAG_TX: Filter is for TX
  */
 enum efx_filter_flags {
 	EFX_FILTER_FLAG_RX_RSS = 0x01,
 	EFX_FILTER_FLAG_RX_SCATTER = 0x02,
 	EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04,
 	EFX_FILTER_FLAG_RX = 0x08,
+	EFX_FILTER_FLAG_TX = 0x10,
 };
 
 /**
@@ -103,6 +110,15 @@ static inline void efx_filter_init_rx(struct efx_filter_spec *spec,
 	spec->dmaq_id = rxq_id;
 }
 
+static inline void efx_filter_init_tx(struct efx_filter_spec *spec,
+				      unsigned txq_id)
+{
+	spec->type = EFX_FILTER_UNSPEC;
+	spec->priority = EFX_FILTER_PRI_REQUIRED;
+	spec->flags = EFX_FILTER_FLAG_TX;
+	spec->dmaq_id = txq_id;
+}
+
 extern int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
 				     __be32 host, __be16 port);
 extern int efx_filter_get_ipv4_local(const struct efx_filter_spec *spec,
@@ -117,6 +133,8 @@ extern int efx_filter_set_eth_local(struct efx_filter_spec *spec,
 				    u16 vid, const u8 *addr);
 extern int efx_filter_get_eth_local(const struct efx_filter_spec *spec,
 				    u16 *vid, u8 *addr);
+extern int efx_filter_set_uc_def(struct efx_filter_spec *spec);
+extern int efx_filter_set_mc_def(struct efx_filter_spec *spec);
 enum {
 	EFX_FILTER_VID_UNSPEC = 0xffff,
 };
diff --git a/drivers/net/ethernet/sfc/mac.h b/drivers/net/ethernet/sfc/mac.h
deleted file mode 100644
index d6a255d..0000000
--- a/drivers/net/ethernet/sfc/mac.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2009 Solarflare Communications Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation, incorporated herein by reference.
- */
-
-#ifndef EFX_MAC_H
-#define EFX_MAC_H
-
-#include "net_driver.h"
-
-extern const struct efx_mac_operations falcon_xmac_operations;
-extern const struct efx_mac_operations efx_mcdi_mac_operations;
-extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
-			      u32 dma_len, int enable, int clear);
-
-#endif
diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c
index 81a4253..17b6463 100644
--- a/drivers/net/ethernet/sfc/mcdi.c
+++ b/drivers/net/ethernet/sfc/mcdi.c
@@ -22,22 +22,22 @@
  **************************************************************************
  */
 
-/* Software-defined structure to the shared-memory */
-#define CMD_NOTIFY_PORT0 0
-#define CMD_NOTIFY_PORT1 4
-#define CMD_PDU_PORT0    0x008
-#define CMD_PDU_PORT1    0x108
-#define REBOOT_FLAG_PORT0 0x3f8
-#define REBOOT_FLAG_PORT1 0x3fc
-
 #define MCDI_RPC_TIMEOUT       10 /*seconds */
 
 #define MCDI_PDU(efx)							\
-	(efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0)
+	(efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST)
 #define MCDI_DOORBELL(efx)						\
-	(efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0)
-#define MCDI_REBOOT_FLAG(efx)						\
-	(efx_port_num(efx) ? REBOOT_FLAG_PORT1 : REBOOT_FLAG_PORT0)
+	(efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST)
+#define MCDI_STATUS(efx)						\
+	(efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST)
+
+/* A reboot/assertion causes the MCDI status word to be set after the
+ * command word is set or a REBOOT event is sent. If we notice a reboot
+ * via these mechanisms then wait 10ms for the status word to be set. */
+#define MCDI_STATUS_DELAY_US		100
+#define MCDI_STATUS_DELAY_COUNT		100
+#define MCDI_STATUS_SLEEP_MS						\
+	(MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000)
 
 #define SEQ_MASK							\
 	EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ))
@@ -77,7 +77,7 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd,
 	u32 xflags, seqno;
 
 	BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
-	BUG_ON(inlen & 3 || inlen >= 0x100);
+	BUG_ON(inlen & 3 || inlen >= MC_SMEM_PDU_LEN);
 
 	seqno = mcdi->seqno & SEQ_MASK;
 	xflags = 0;
@@ -111,7 +111,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen)
 	int i;
 
 	BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT);
-	BUG_ON(outlen & 3 || outlen >= 0x100);
+	BUG_ON(outlen & 3 || outlen >= MC_SMEM_PDU_LEN);
 
 	for (i = 0; i < outlen; i += 4)
 		*((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i);
@@ -210,7 +210,7 @@ out:
 /* Test and clear MC-rebooted flag for this port/function */
 int efx_mcdi_poll_reboot(struct efx_nic *efx)
 {
-	unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx);
+	unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx);
 	efx_dword_t reg;
 	uint32_t value;
 
@@ -384,6 +384,11 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd,
 			netif_dbg(efx, hw, efx->net_dev,
 				  "MC command 0x%x inlen %d failed rc=%d\n",
 				  cmd, (int)inlen, -rc);
+
+		if (rc == -EIO || rc == -EINTR) {
+			msleep(MCDI_STATUS_SLEEP_MS);
+			efx_mcdi_poll_reboot(efx);
+		}
 	}
 
 	efx_mcdi_release(mcdi);
@@ -465,10 +470,20 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc)
 			mcdi->resplen = 0;
 			++mcdi->credits;
 		}
-	} else
+	} else {
+		int count;
+
 		/* Nobody was waiting for an MCDI request, so trigger a reset */
 		efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE);
 
+		/* Consume the status word since efx_mcdi_rpc_finish() won't */
+		for (count = 0; count < MCDI_STATUS_DELAY_COUNT; ++count) {
+			if (efx_mcdi_poll_reboot(efx))
+				break;
+			udelay(MCDI_STATUS_DELAY_US);
+		}
+	}
+
 	spin_unlock(&mcdi->iface_lock);
 }
 
@@ -502,49 +517,6 @@ static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev)
 	efx_link_status_changed(efx);
 }
 
-static const char *sensor_names[] = {
-	[MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor",
-	[MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor",
-	[MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling",
-	[MC_CMD_SENSOR_PHY0_TEMP] = "PHY 0 temp. sensor",
-	[MC_CMD_SENSOR_PHY0_COOLING] = "PHY 0 cooling",
-	[MC_CMD_SENSOR_PHY1_TEMP] = "PHY 1 temp. sensor",
-	[MC_CMD_SENSOR_PHY1_COOLING] = "PHY 1 cooling",
-	[MC_CMD_SENSOR_IN_1V0] = "1.0V supply sensor",
-	[MC_CMD_SENSOR_IN_1V2] = "1.2V supply sensor",
-	[MC_CMD_SENSOR_IN_1V8] = "1.8V supply sensor",
-	[MC_CMD_SENSOR_IN_2V5] = "2.5V supply sensor",
-	[MC_CMD_SENSOR_IN_3V3] = "3.3V supply sensor",
-	[MC_CMD_SENSOR_IN_12V0] = "12V supply sensor"
-};
-
-static const char *sensor_status_names[] = {
-	[MC_CMD_SENSOR_STATE_OK] = "OK",
-	[MC_CMD_SENSOR_STATE_WARNING] = "Warning",
-	[MC_CMD_SENSOR_STATE_FATAL] = "Fatal",
-	[MC_CMD_SENSOR_STATE_BROKEN] = "Device failure",
-};
-
-static void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
-{
-	unsigned int monitor, state, value;
-	const char *name, *state_txt;
-	monitor = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR);
-	state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE);
-	value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE);
-	/* Deal gracefully with the board having more drivers than we
-	 * know about, but do not expect new sensor states. */
-	name = (monitor >= ARRAY_SIZE(sensor_names))
-				    ? "No sensor name available" :
-				    sensor_names[monitor];
-	EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names));
-	state_txt = sensor_status_names[state];
-
-	netif_err(efx, hw, efx->net_dev,
-		  "Sensor %d (%s) reports condition '%s' for raw value %d\n",
-		  monitor, name, state_txt, value);
-}
-
 /* Called from  falcon_process_eventq for MCDI events */
 void efx_mcdi_process_event(struct efx_channel *channel,
 			    efx_qword_t *event)
@@ -588,6 +560,9 @@ void efx_mcdi_process_event(struct efx_channel *channel,
 	case MCDI_EVENT_CODE_MAC_STATS_DMA:
 		/* MAC stats are gather lazily.  We can ignore this. */
 		break;
+	case MCDI_EVENT_CODE_FLR:
+		efx_sriov_flr(efx, MCDI_EVENT_FIELD(*event, FLR_VF));
+		break;
 
 	default:
 		netif_err(efx, hw, efx->net_dev, "Unknown MCDI event 0x%x\n",
@@ -604,7 +579,7 @@ void efx_mcdi_process_event(struct efx_channel *channel,
 
 void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
 {
-	u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)];
+	u8 outbuf[ALIGN(MC_CMD_GET_VERSION_OUT_LEN, 4)];
 	size_t outlength;
 	const __le16 *ver_words;
 	int rc;
@@ -616,7 +591,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len)
 	if (rc)
 		goto fail;
 
-	if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) {
+	if (outlength < MC_CMD_GET_VERSION_OUT_LEN) {
 		rc = -EIO;
 		goto fail;
 	}
@@ -663,9 +638,9 @@ fail:
 }
 
 int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
-			   u16 *fw_subtype_list)
+			   u16 *fw_subtype_list, u32 *capabilities)
 {
-	uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN];
+	uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN];
 	size_t outlen;
 	int port_num = efx_port_num(efx);
 	int offset;
@@ -678,7 +653,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
 	if (rc)
 		goto fail;
 
-	if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LEN) {
+	if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) {
 		rc = -EIO;
 		goto fail;
 	}
@@ -691,7 +666,16 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
 	if (fw_subtype_list)
 		memcpy(fw_subtype_list,
 		       outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST,
-		       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN);
+		       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM *
+		       sizeof(fw_subtype_list[0]));
+	if (capabilities) {
+		if (port_num)
+			*capabilities = MCDI_DWORD(outbuf,
+					GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
+		else
+			*capabilities = MCDI_DWORD(outbuf,
+					GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
+	}
 
 	return 0;
 
@@ -779,7 +763,7 @@ int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type,
 	*size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_SIZE);
 	*erase_size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_ERASESIZE);
 	*protected_out = !!(MCDI_DWORD(outbuf, NVRAM_INFO_OUT_FLAGS) &
-				(1 << MC_CMD_NVRAM_PROTECTED_LBN));
+				(1 << MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN));
 	return 0;
 
 fail:
@@ -1060,7 +1044,7 @@ void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
 
 int efx_mcdi_reset_port(struct efx_nic *efx)
 {
-	int rc = efx_mcdi_rpc(efx, MC_CMD_PORT_RESET, NULL, 0, NULL, 0, NULL);
+	int rc = efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, NULL, 0, NULL, 0, NULL);
 	if (rc)
 		netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
 			  __func__, rc);
@@ -1173,6 +1157,37 @@ fail:
 	return rc;
 }
 
+int efx_mcdi_flush_rxqs(struct efx_nic *efx)
+{
+	struct efx_channel *channel;
+	struct efx_rx_queue *rx_queue;
+	__le32 *qid;
+	int rc, count;
+
+	qid = kmalloc(EFX_MAX_CHANNELS * sizeof(*qid), GFP_KERNEL);
+	if (qid == NULL)
+		return -ENOMEM;
+
+	count = 0;
+	efx_for_each_channel(channel, efx) {
+		efx_for_each_channel_rx_queue(rx_queue, channel) {
+			if (rx_queue->flush_pending) {
+				rx_queue->flush_pending = false;
+				atomic_dec(&efx->rxq_flush_pending);
+				qid[count++] = cpu_to_le32(
+					efx_rx_queue_index(rx_queue));
+			}
+		}
+	}
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)qid,
+			  count * sizeof(*qid), NULL, 0, NULL);
+	WARN_ON(rc > 0);
+
+	kfree(qid);
+
+	return rc;
+}
 
 int efx_mcdi_wol_filter_reset(struct efx_nic *efx)
 {
diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h
index aced2a7..0bdf3e3 100644
--- a/drivers/net/ethernet/sfc/mcdi.h
+++ b/drivers/net/ethernet/sfc/mcdi.h
@@ -56,6 +56,15 @@ struct efx_mcdi_iface {
 	size_t resplen;
 };
 
+struct efx_mcdi_mon {
+	struct efx_buffer dma_buf;
+	struct mutex update_lock;
+	unsigned long last_update;
+	struct device *device;
+	struct efx_mcdi_mon_attribute *attrs;
+	unsigned int n_attrs;
+};
+
 extern void efx_mcdi_init(struct efx_nic *efx);
 
 extern int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const u8 *inbuf,
@@ -68,6 +77,7 @@ extern void efx_mcdi_mode_event(struct efx_nic *efx);
 
 extern void efx_mcdi_process_event(struct efx_channel *channel,
 				   efx_qword_t *event);
+extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
 
 #define MCDI_PTR2(_buf, _ofst)						\
 	(((u8 *)_buf) + _ofst)
@@ -83,6 +93,10 @@ extern void efx_mcdi_process_event(struct efx_channel *channel,
 
 #define MCDI_PTR(_buf, _ofst)						\
 	MCDI_PTR2(_buf, MC_CMD_ ## _ofst ## _OFST)
+#define MCDI_ARRAY_PTR(_buf, _field, _type, _index)			\
+	MCDI_PTR2(_buf,							\
+		  MC_CMD_ ## _field ## _OFST +				\
+		  (_index) * MC_CMD_ ## _type ## _TYPEDEF_LEN)
 #define MCDI_SET_DWORD(_buf, _ofst, _value)				\
 	MCDI_SET_DWORD2(_buf, MC_CMD_ ## _ofst ## _OFST, _value)
 #define MCDI_DWORD(_buf, _ofst)						\
@@ -92,12 +106,18 @@ extern void efx_mcdi_process_event(struct efx_channel *channel,
 
 #define MCDI_EVENT_FIELD(_ev, _field)			\
 	EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
+#define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2)		\
+	EFX_DWORD_FIELD(						\
+		*((efx_dword_t *)					\
+		  (MCDI_ARRAY_PTR(_buf, _field1, _type, _index) +	\
+		   (MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \
+		MC_CMD_ ## _type ## _TYPEDEF_ ## _field2)
 
 extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len);
 extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
 			       bool *was_attached_out);
 extern int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address,
-				  u16 *fw_subtype_list);
+				  u16 *fw_subtype_list, u32 *capabilities);
 extern int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart,
 			     u32 dest_evq);
 extern int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out);
@@ -126,5 +146,19 @@ extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx,
 extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out);
 extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id);
 extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx);
+extern int efx_mcdi_flush_rxqs(struct efx_nic *efx);
+extern int efx_mcdi_set_mac(struct efx_nic *efx);
+extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
+			      u32 dma_len, int enable, int clear);
+extern int efx_mcdi_mac_reconfigure(struct efx_nic *efx);
+extern bool efx_mcdi_mac_check_fault(struct efx_nic *efx);
+
+#ifdef CONFIG_SFC_MCDI_MON
+extern int efx_mcdi_mon_probe(struct efx_nic *efx);
+extern void efx_mcdi_mon_remove(struct efx_nic *efx);
+#else
+static inline int efx_mcdi_mon_probe(struct efx_nic *efx) { return 0; }
+static inline void efx_mcdi_mon_remove(struct efx_nic *efx) {}
+#endif
 
 #endif /* EFX_MCDI_H */
diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c
index 50c2077..1003f30 100644
--- a/drivers/net/ethernet/sfc/mcdi_mac.c
+++ b/drivers/net/ethernet/sfc/mcdi_mac.c
@@ -9,11 +9,10 @@
 
 #include "net_driver.h"
 #include "efx.h"
-#include "mac.h"
 #include "mcdi.h"
 #include "mcdi_pcol.h"
 
-static int efx_mcdi_set_mac(struct efx_nic *efx)
+int efx_mcdi_set_mac(struct efx_nic *efx)
 {
 	u32 reject, fcntl;
 	u8 cmdbytes[MC_CMD_SET_MAC_IN_LEN];
@@ -45,6 +44,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx)
 	}
 	if (efx->wanted_fc & EFX_FC_AUTO)
 		fcntl = MC_CMD_FCNTL_AUTO;
+	if (efx->fc_disable)
+		fcntl = MC_CMD_FCNTL_OFF;
 
 	MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl);
 
@@ -52,7 +53,7 @@ static int efx_mcdi_set_mac(struct efx_nic *efx)
 			    NULL, 0, NULL);
 }
 
-static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults)
+bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
 {
 	u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
 	size_t outlength;
@@ -62,16 +63,13 @@ static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults)
 
 	rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
 			  outbuf, sizeof(outbuf), &outlength);
-	if (rc)
-		goto fail;
-
-	*faults = MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT);
-	return 0;
+	if (rc) {
+		netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
+			  __func__, rc);
+		return true;
+	}
 
-fail:
-	netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
-		  __func__, rc);
-	return rc;
+	return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
 }
 
 int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
@@ -84,7 +82,7 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
 	u32 addr_hi;
 	u32 addr_lo;
 
-	BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_LEN != 0);
+	BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0);
 
 	addr_lo = ((u64)dma_addr) >> 0;
 	addr_hi = ((u64)dma_addr) >> 32;
@@ -93,13 +91,13 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
 	MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_HI, addr_hi);
 	cmd_ptr = (efx_dword_t *)MCDI_PTR(inbuf, MAC_STATS_IN_CMD);
 	EFX_POPULATE_DWORD_7(*cmd_ptr,
-			     MC_CMD_MAC_STATS_CMD_DMA, !!enable,
-			     MC_CMD_MAC_STATS_CMD_CLEAR, clear,
-			     MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE, 1,
-			     MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE, !!enable,
-			     MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR, 0,
-			     MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT, 1,
-			     MC_CMD_MAC_STATS_CMD_PERIOD_MS, period);
+			     MC_CMD_MAC_STATS_IN_DMA, !!enable,
+			     MC_CMD_MAC_STATS_IN_CLEAR, clear,
+			     MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE, 1,
+			     MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE, !!enable,
+			     MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR, 0,
+			     MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT, 1,
+			     MC_CMD_MAC_STATS_IN_PERIOD_MS, period);
 	MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len);
 
 	rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf),
@@ -115,31 +113,18 @@ fail:
 	return rc;
 }
 
-static int efx_mcdi_mac_reconfigure(struct efx_nic *efx)
+int efx_mcdi_mac_reconfigure(struct efx_nic *efx)
 {
 	int rc;
 
+	WARN_ON(!mutex_is_locked(&efx->mac_lock));
+
 	rc = efx_mcdi_set_mac(efx);
 	if (rc != 0)
 		return rc;
 
-	/* Restore the multicast hash registers. */
-	efx->type->push_multicast_hash(efx);
-
-	return 0;
-}
-
-
-static bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
-{
-	u32 faults;
-	int rc = efx_mcdi_get_mac_faults(efx, &faults);
-	return (rc != 0) || (faults != 0);
+	return efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH,
+			    efx->multicast_hash.byte,
+			    sizeof(efx->multicast_hash),
+			    NULL, 0, NULL);
 }
-
-
-const struct efx_mac_operations efx_mcdi_mac_operations = {
-	.reconfigure	= efx_mcdi_mac_reconfigure,
-	.update_stats	= efx_port_dummy_op_void,
-	.check_fault 	= efx_mcdi_mac_check_fault,
-};
diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c
new file mode 100644
index 0000000..8a72c10
--- /dev/null
+++ b/drivers/net/ethernet/sfc/mcdi_mon.c
@@ -0,0 +1,415 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2011 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/hwmon.h>
+#include <linux/stat.h>
+
+#include "net_driver.h"
+#include "mcdi.h"
+#include "mcdi_pcol.h"
+#include "nic.h"
+
+enum efx_hwmon_type {
+	EFX_HWMON_UNKNOWN,
+	EFX_HWMON_TEMP,         /* temperature */
+	EFX_HWMON_COOL,         /* cooling device, probably a heatsink */
+	EFX_HWMON_IN            /* input voltage */
+};
+
+static const struct {
+	const char *label;
+	enum efx_hwmon_type hwmon_type;
+	int port;
+} efx_mcdi_sensor_type[MC_CMD_SENSOR_ENTRY_MAXNUM] = {
+#define SENSOR(name, label, hwmon_type, port)			\
+	[MC_CMD_SENSOR_##name] = { label, hwmon_type, port }
+	SENSOR(CONTROLLER_TEMP,	   "Controller temp.",	   EFX_HWMON_TEMP, -1),
+	SENSOR(PHY_COMMON_TEMP,	   "PHY temp.",		   EFX_HWMON_TEMP, -1),
+	SENSOR(CONTROLLER_COOLING, "Controller cooling",   EFX_HWMON_COOL, -1),
+	SENSOR(PHY0_TEMP,	   "PHY temp.",		   EFX_HWMON_TEMP, 0),
+	SENSOR(PHY0_COOLING,	   "PHY cooling",	   EFX_HWMON_COOL, 0),
+	SENSOR(PHY1_TEMP,	   "PHY temp.",		   EFX_HWMON_TEMP, 1),
+	SENSOR(PHY1_COOLING, 	   "PHY cooling",	   EFX_HWMON_COOL, 1),
+	SENSOR(IN_1V0,		   "1.0V supply",	   EFX_HWMON_IN,   -1),
+	SENSOR(IN_1V2,		   "1.2V supply",	   EFX_HWMON_IN,   -1),
+	SENSOR(IN_1V8,		   "1.8V supply",	   EFX_HWMON_IN,   -1),
+	SENSOR(IN_2V5,		   "2.5V supply",	   EFX_HWMON_IN,   -1),
+	SENSOR(IN_3V3,		   "3.3V supply",	   EFX_HWMON_IN,   -1),
+	SENSOR(IN_12V0,		   "12.0V supply",	   EFX_HWMON_IN,   -1),
+	SENSOR(IN_1V2A,		   "1.2V analogue supply", EFX_HWMON_IN,   -1),
+	SENSOR(IN_VREF,		   "ref. voltage",	   EFX_HWMON_IN,   -1),
+#undef SENSOR
+};
+
+static const char *const sensor_status_names[] = {
+	[MC_CMD_SENSOR_STATE_OK] = "OK",
+	[MC_CMD_SENSOR_STATE_WARNING] = "Warning",
+	[MC_CMD_SENSOR_STATE_FATAL] = "Fatal",
+	[MC_CMD_SENSOR_STATE_BROKEN] = "Device failure",
+};
+
+void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev)
+{
+	unsigned int type, state, value;
+	const char *name = NULL, *state_txt;
+
+	type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR);
+	state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE);
+	value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE);
+
+	/* Deal gracefully with the board having more drivers than we
+	 * know about, but do not expect new sensor states. */
+	if (type < ARRAY_SIZE(efx_mcdi_sensor_type))
+		name = efx_mcdi_sensor_type[type].label;
+	if (!name)
+		name = "No sensor name available";
+	EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names));
+	state_txt = sensor_status_names[state];
+
+	netif_err(efx, hw, efx->net_dev,
+		  "Sensor %d (%s) reports condition '%s' for raw value %d\n",
+		  type, name, state_txt, value);
+}
+
+#ifdef CONFIG_SFC_MCDI_MON
+
+struct efx_mcdi_mon_attribute {
+	struct device_attribute dev_attr;
+	unsigned int index;
+	unsigned int type;
+	unsigned int limit_value;
+	char name[12];
+};
+
+static int efx_mcdi_mon_update(struct efx_nic *efx)
+{
+	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
+	u8 inbuf[MC_CMD_READ_SENSORS_IN_LEN];
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, READ_SENSORS_IN_DMA_ADDR_LO,
+		       hwmon->dma_buf.dma_addr & 0xffffffff);
+	MCDI_SET_DWORD(inbuf, READ_SENSORS_IN_DMA_ADDR_HI,
+		       (u64)hwmon->dma_buf.dma_addr >> 32);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_READ_SENSORS,
+			  inbuf, sizeof(inbuf), NULL, 0, NULL);
+	if (rc == 0)
+		hwmon->last_update = jiffies;
+	return rc;
+}
+
+static ssize_t efx_mcdi_mon_show_name(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	return sprintf(buf, "%s\n", KBUILD_MODNAME);
+}
+
+static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index,
+				  efx_dword_t *entry)
+{
+	struct efx_nic *efx = dev_get_drvdata(dev);
+	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
+	int rc;
+
+	BUILD_BUG_ON(MC_CMD_READ_SENSORS_OUT_LEN != 0);
+
+	mutex_lock(&hwmon->update_lock);
+
+	/* Use cached value if last update was < 1 s ago */
+	if (time_before(jiffies, hwmon->last_update + HZ))
+		rc = 0;
+	else
+		rc = efx_mcdi_mon_update(efx);
+
+	/* Copy out the requested entry */
+	*entry = ((efx_dword_t *)hwmon->dma_buf.addr)[index];
+
+	mutex_unlock(&hwmon->update_lock);
+
+	return rc;
+}
+
+static ssize_t efx_mcdi_mon_show_value(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct efx_mcdi_mon_attribute *mon_attr =
+		container_of(attr, struct efx_mcdi_mon_attribute, dev_attr);
+	efx_dword_t entry;
+	unsigned int value;
+	int rc;
+
+	rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry);
+	if (rc)
+		return rc;
+
+	value = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE);
+
+	/* Convert temperature from degrees to milli-degrees Celsius */
+	if (efx_mcdi_sensor_type[mon_attr->type].hwmon_type == EFX_HWMON_TEMP)
+		value *= 1000;
+
+	return sprintf(buf, "%u\n", value);
+}
+
+static ssize_t efx_mcdi_mon_show_limit(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct efx_mcdi_mon_attribute *mon_attr =
+		container_of(attr, struct efx_mcdi_mon_attribute, dev_attr);
+	unsigned int value;
+
+	value = mon_attr->limit_value;
+
+	/* Convert temperature from degrees to milli-degrees Celsius */
+	if (efx_mcdi_sensor_type[mon_attr->type].hwmon_type == EFX_HWMON_TEMP)
+		value *= 1000;
+
+	return sprintf(buf, "%u\n", value);
+}
+
+static ssize_t efx_mcdi_mon_show_alarm(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct efx_mcdi_mon_attribute *mon_attr =
+		container_of(attr, struct efx_mcdi_mon_attribute, dev_attr);
+	efx_dword_t entry;
+	int state;
+	int rc;
+
+	rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry);
+	if (rc)
+		return rc;
+
+	state = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
+	return sprintf(buf, "%d\n", state != MC_CMD_SENSOR_STATE_OK);
+}
+
+static ssize_t efx_mcdi_mon_show_label(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct efx_mcdi_mon_attribute *mon_attr =
+		container_of(attr, struct efx_mcdi_mon_attribute, dev_attr);
+	return sprintf(buf, "%s\n",
+		       efx_mcdi_sensor_type[mon_attr->type].label);
+}
+
+static int
+efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name,
+		      ssize_t (*reader)(struct device *,
+					struct device_attribute *, char *),
+		      unsigned int index, unsigned int type,
+		      unsigned int limit_value)
+{
+	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
+	struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs];
+	int rc;
+
+	strlcpy(attr->name, name, sizeof(attr->name));
+	attr->index = index;
+	attr->type = type;
+	attr->limit_value = limit_value;
+	attr->dev_attr.attr.name = attr->name;
+	attr->dev_attr.attr.mode = S_IRUGO;
+	attr->dev_attr.show = reader;
+	rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr);
+	if (rc == 0)
+		++hwmon->n_attrs;
+	return rc;
+}
+
+int efx_mcdi_mon_probe(struct efx_nic *efx)
+{
+	struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx);
+	unsigned int n_attrs, n_temp = 0, n_cool = 0, n_in = 0;
+	u8 outbuf[MC_CMD_SENSOR_INFO_OUT_LENMAX];
+	size_t outlen;
+	char name[12];
+	u32 mask;
+	int rc, i, type;
+
+	BUILD_BUG_ON(MC_CMD_SENSOR_INFO_IN_LEN != 0);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_SENSOR_INFO, NULL, 0,
+			  outbuf, sizeof(outbuf), &outlen);
+	if (rc)
+		return rc;
+	if (outlen < MC_CMD_SENSOR_INFO_OUT_LENMIN)
+		return -EIO;
+
+	/* Find out which sensors are present.  Don't create a device
+	 * if there are none.
+	 */
+	mask = MCDI_DWORD(outbuf, SENSOR_INFO_OUT_MASK);
+	if (mask == 0)
+		return 0;
+
+	/* Check again for short response */
+	if (outlen < MC_CMD_SENSOR_INFO_OUT_LEN(hweight32(mask)))
+		return -EIO;
+
+	rc = efx_nic_alloc_buffer(efx, &hwmon->dma_buf,
+				  4 * MC_CMD_SENSOR_ENTRY_MAXNUM);
+	if (rc)
+		return rc;
+
+	mutex_init(&hwmon->update_lock);
+	efx_mcdi_mon_update(efx);
+
+	/* Allocate space for the maximum possible number of
+	 * attributes for this set of sensors: name of the driver plus
+	 * value, min, max, crit, alarm and label for each sensor.
+	 */
+	n_attrs = 1 + 6 * hweight32(mask);
+	hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL);
+	if (!hwmon->attrs) {
+		rc = -ENOMEM;
+		goto fail;
+	}
+
+	hwmon->device = hwmon_device_register(&efx->pci_dev->dev);
+	if (IS_ERR(hwmon->device)) {
+		rc = PTR_ERR(hwmon->device);
+		goto fail;
+	}
+
+	rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0);
+	if (rc)
+		goto fail;
+
+	for (i = 0, type = -1; ; i++) {
+		const char *hwmon_prefix;
+		unsigned hwmon_index;
+		u16 min1, max1, min2, max2;
+
+		/* Find next sensor type or exit if there is none */
+		type++;
+		while (!(mask & (1 << type))) {
+			type++;
+			if (type == 32)
+				return 0;
+		}
+
+		/* Skip sensors specific to a different port */
+		if (efx_mcdi_sensor_type[type].hwmon_type != EFX_HWMON_UNKNOWN &&
+		    efx_mcdi_sensor_type[type].port >= 0 &&
+		    efx_mcdi_sensor_type[type].port != efx_port_num(efx))
+			continue;
+
+		switch (efx_mcdi_sensor_type[type].hwmon_type) {
+		case EFX_HWMON_TEMP:
+			hwmon_prefix = "temp";
+			hwmon_index = ++n_temp; /* 1-based */
+			break;
+		case EFX_HWMON_COOL:
+			/* This is likely to be a heatsink, but there
+			 * is no convention for representing cooling
+			 * devices other than fans.
+			 */
+			hwmon_prefix = "fan";
+			hwmon_index = ++n_cool; /* 1-based */
+			break;
+		default:
+			hwmon_prefix = "in";
+			hwmon_index = n_in++; /* 0-based */
+			break;
+		}
+
+		min1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY,
+					SENSOR_INFO_ENTRY, i, MIN1);
+		max1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY,
+					SENSOR_INFO_ENTRY, i, MAX1);
+		min2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY,
+					SENSOR_INFO_ENTRY, i, MIN2);
+		max2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY,
+					SENSOR_INFO_ENTRY, i, MAX2);
+
+		if (min1 != max1) {
+			snprintf(name, sizeof(name), "%s%u_input",
+				 hwmon_prefix, hwmon_index);
+			rc = efx_mcdi_mon_add_attr(
+				efx, name, efx_mcdi_mon_show_value, i, type, 0);
+			if (rc)
+				goto fail;
+
+			snprintf(name, sizeof(name), "%s%u_min",
+				 hwmon_prefix, hwmon_index);
+			rc = efx_mcdi_mon_add_attr(
+				efx, name, efx_mcdi_mon_show_limit,
+				i, type, min1);
+			if (rc)
+				goto fail;
+
+			snprintf(name, sizeof(name), "%s%u_max",
+				 hwmon_prefix, hwmon_index);
+			rc = efx_mcdi_mon_add_attr(
+				efx, name, efx_mcdi_mon_show_limit,
+				i, type, max1);
+			if (rc)
+				goto fail;
+
+			if (min2 != max2) {
+				/* Assume max2 is critical value.
+				 * But we have no good way to expose min2.
+				 */
+				snprintf(name, sizeof(name), "%s%u_crit",
+					 hwmon_prefix, hwmon_index);
+				rc = efx_mcdi_mon_add_attr(
+					efx, name, efx_mcdi_mon_show_limit,
+					i, type, max2);
+				if (rc)
+					goto fail;
+			}
+		}
+
+		snprintf(name, sizeof(name), "%s%u_alarm",
+			 hwmon_prefix, hwmon_index);
+		rc = efx_mcdi_mon_add_attr(
+			efx, name, efx_mcdi_mon_show_alarm, i, type, 0);
+		if (rc)
+			goto fail;
+
+		if (efx_mcdi_sensor_type[type].label) {
+			snprintf(name, sizeof(name), "%s%u_label",
+				 hwmon_prefix, hwmon_index);
+			rc = efx_mcdi_mon_add_attr(
+				efx, name, efx_mcdi_mon_show_label, i, type, 0);
+			if (rc)
+				goto fail;
+		}
+	}
+
+fail:
+	efx_mcdi_mon_remove(efx);
+	return rc;
+}
+
+void efx_mcdi_mon_remove(struct efx_nic *efx)
+{
+	struct siena_nic_data *nic_data = efx->nic_data;
+	struct efx_mcdi_mon *hwmon = &nic_data->hwmon;
+	unsigned int i;
+
+	for (i = 0; i < hwmon->n_attrs; i++)
+		device_remove_file(&efx->pci_dev->dev,
+				   &hwmon->attrs[i].dev_attr);
+	kfree(hwmon->attrs);
+	if (hwmon->device)
+		hwmon_device_unregister(hwmon->device);
+	efx_nic_free_buffer(efx, &hwmon->dma_buf);
+}
+
+#endif /* CONFIG_SFC_MCDI_MON */
diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h
index 41fe06f..0310b9f 100644
--- a/drivers/net/ethernet/sfc/mcdi_pcol.h
+++ b/drivers/net/ethernet/sfc/mcdi_pcol.h
@@ -22,6 +22,18 @@
 /* The Scheduler has started. */
 #define MC_FW_STATE_SCHED (8)
 
+/* Siena MC shared memmory offsets */
+/* The 'doorbell' addresses are hard-wired to alert the MC when written */
+#define	MC_SMEM_P0_DOORBELL_OFST	0x000
+#define	MC_SMEM_P1_DOORBELL_OFST	0x004
+/* The rest of these are firmware-defined */
+#define	MC_SMEM_P0_PDU_OFST		0x008
+#define	MC_SMEM_P1_PDU_OFST		0x108
+#define	MC_SMEM_PDU_LEN			0x100
+#define	MC_SMEM_P0_PTP_TIME_OFST	0x7f0
+#define	MC_SMEM_P0_STATUS_OFST		0x7f8
+#define	MC_SMEM_P1_STATUS_OFST		0x7fc
+
 /* Values to be written to the per-port status dword in shared
  * memory on reboot and assert */
 #define MC_STATUS_DWORD_REBOOT (0xb007b007)
@@ -34,6 +46,8 @@
  */
 #define MCDI_PCOL_VERSION 1
 
+/* Unused commands: 0x23, 0x27, 0x30, 0x31 */
+
 /**
  * MCDI version 1
  *
@@ -131,53 +145,6 @@
  */
 #define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc
 
-#define MCDI_EVENT_DATA_LBN 0
-#define MCDI_EVENT_DATA_WIDTH 32
-#define MCDI_EVENT_CONT_LBN 32
-#define MCDI_EVENT_CONT_WIDTH 1
-#define MCDI_EVENT_LEVEL_LBN 33
-#define MCDI_EVENT_LEVEL_WIDTH 3
-#define MCDI_EVENT_LEVEL_INFO (0)
-#define MCDI_EVENT_LEVEL_WARN (1)
-#define MCDI_EVENT_LEVEL_ERR (2)
-#define MCDI_EVENT_LEVEL_FATAL (3)
-#define MCDI_EVENT_SRC_LBN 36
-#define MCDI_EVENT_SRC_WIDTH 8
-#define MCDI_EVENT_CODE_LBN 44
-#define MCDI_EVENT_CODE_WIDTH 8
-#define MCDI_EVENT_CODE_BADSSERT (1)
-#define MCDI_EVENT_CODE_PMNOTICE (2)
-#define MCDI_EVENT_CODE_CMDDONE (3)
-#define  MCDI_EVENT_CMDDONE_SEQ_LBN 0
-#define  MCDI_EVENT_CMDDONE_SEQ_WIDTH 8
-#define  MCDI_EVENT_CMDDONE_DATALEN_LBN 8
-#define  MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8
-#define  MCDI_EVENT_CMDDONE_ERRNO_LBN 16
-#define  MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8
-#define MCDI_EVENT_CODE_LINKCHANGE (4)
-#define  MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0
-#define  MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16
-#define  MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
-#define  MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
-#define  MCDI_EVENT_LINKCHANGE_SPEED_100M 1
-#define  MCDI_EVENT_LINKCHANGE_SPEED_1G 2
-#define  MCDI_EVENT_LINKCHANGE_SPEED_10G 3
-#define  MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
-#define  MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
-#define  MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
-#define  MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8
-#define MCDI_EVENT_CODE_SENSOREVT (5)
-#define  MCDI_EVENT_SENSOREVT_MONITOR_LBN 0
-#define  MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8
-#define  MCDI_EVENT_SENSOREVT_STATE_LBN 8
-#define  MCDI_EVENT_SENSOREVT_STATE_WIDTH 8
-#define  MCDI_EVENT_SENSOREVT_VALUE_LBN 16
-#define  MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16
-#define MCDI_EVENT_CODE_SCHEDERR (6)
-#define MCDI_EVENT_CODE_REBOOT (7)
-#define MCDI_EVENT_CODE_MAC_STATS_DMA (8)
-#define  MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0
-#define  MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32
 
 /* Non-existent command target */
 #define MC_CMD_ERR_ENOENT 2
@@ -198,121 +165,24 @@
 
 #define MC_CMD_ERR_CODE_OFST 0
 
+/* We define 8 "escape" commands to allow
+   for command number space extension */
+
+#define MC_CMD_CMD_SPACE_ESCAPE_0	      0x78
+#define MC_CMD_CMD_SPACE_ESCAPE_1	      0x79
+#define MC_CMD_CMD_SPACE_ESCAPE_2	      0x7A
+#define MC_CMD_CMD_SPACE_ESCAPE_3	      0x7B
+#define MC_CMD_CMD_SPACE_ESCAPE_4	      0x7C
+#define MC_CMD_CMD_SPACE_ESCAPE_5	      0x7D
+#define MC_CMD_CMD_SPACE_ESCAPE_6	      0x7E
+#define MC_CMD_CMD_SPACE_ESCAPE_7	      0x7F
+
+/* Vectors in the boot ROM */
+/* Point to the copycode entry point. */
+#define MC_BOOTROM_COPYCODE_VEC (0x7f4)
+/* Points to the recovery mode entry point. */
+#define MC_BOOTROM_NOFLASH_VEC (0x7f8)
 
-/* MC_CMD_READ32: (debug, variadic out)
- * Read multiple 32byte words from MC memory
- */
-#define MC_CMD_READ32 0x01
-#define MC_CMD_READ32_IN_LEN 8
-#define MC_CMD_READ32_IN_ADDR_OFST 0
-#define MC_CMD_READ32_IN_NUMWORDS_OFST 4
-#define MC_CMD_READ32_OUT_LEN(_numwords) \
-	(4 * (_numwords))
-#define MC_CMD_READ32_OUT_BUFFER_OFST 0
-
-/* MC_CMD_WRITE32: (debug, variadic in)
- * Write multiple 32byte words to MC memory
- */
-#define MC_CMD_WRITE32 0x02
-#define MC_CMD_WRITE32_IN_LEN(_numwords) (((_numwords) * 4) + 4)
-#define MC_CMD_WRITE32_IN_ADDR_OFST 0
-#define MC_CMD_WRITE32_IN_BUFFER_OFST 4
-#define MC_CMD_WRITE32_OUT_LEN 0
-
-/* MC_CMD_COPYCODE: (debug)
- * Copy MC code between two locations and jump
- */
-#define MC_CMD_COPYCODE 0x03
-#define MC_CMD_COPYCODE_IN_LEN 16
-#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0
-#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4
-#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8
-#define MC_CMD_COPYCODE_IN_JUMP_OFST 12
-/* Control should return to the caller rather than jumping */
-#define MC_CMD_COPYCODE_JUMP_NONE 1
-#define MC_CMD_COPYCODE_OUT_LEN 0
-
-/* MC_CMD_SET_FUNC: (debug)
- * Select function for function-specific commands.
- */
-#define MC_CMD_SET_FUNC 0x04
-#define MC_CMD_SET_FUNC_IN_LEN 4
-#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0
-#define MC_CMD_SET_FUNC_OUT_LEN 0
-
-/* MC_CMD_GET_BOOT_STATUS:
- * Get the instruction address from which the MC booted.
- */
-#define MC_CMD_GET_BOOT_STATUS 0x05
-#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0
-#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8
-#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0
-#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
-/* Reboot caused by watchdog */
-#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_LBN   (0)
-#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_WIDTH (1)
-/* MC booted from primary flash partition */
-#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_LBN    (1)
-#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_WIDTH  (1)
-/* MC booted from backup flash partition */
-#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_LBN     (2)
-#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_WIDTH   (1)
-
-/* MC_CMD_GET_ASSERTS: (debug, variadic out)
- * Get (and optionally clear) the current assertion status.
- *
- * Only OUT.GLOBAL_FLAGS is guaranteed to exist in the completion
- * payload. The other fields will only be present if
- * OUT.GLOBAL_FLAGS != NO_FAILS
- */
-#define MC_CMD_GET_ASSERTS 0x06
-#define MC_CMD_GET_ASSERTS_IN_LEN 4
-#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0
-#define MC_CMD_GET_ASSERTS_OUT_LEN 140
-/* Assertion status flag */
-#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0
-/*! No assertions have failed. */
-#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 1
-/*! A system-level assertion has failed. */
-#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 2
-/*! A thread-level assertion has failed. */
-#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 3
-/*! The system was reset by the watchdog. */
-#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 4
-/* Failing PC value */
-#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4
-/* Saved GP regs */
-#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8
-#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_LEN 124
-/* Failing thread address */
-#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132
-
-/* MC_CMD_LOG_CTRL:
- * Determine the output stream for various events and messages
- */
-#define MC_CMD_LOG_CTRL 0x07
-#define MC_CMD_LOG_CTRL_IN_LEN 8
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART (1)
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ (2)
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4
-#define MC_CMD_LOG_CTRL_OUT_LEN 0
-
-/* MC_CMD_GET_VERSION:
- * Get version information about the MC firmware
- */
-#define MC_CMD_GET_VERSION 0x08
-#define MC_CMD_GET_VERSION_IN_LEN 0
-#define MC_CMD_GET_VERSION_V0_OUT_LEN 4
-#define MC_CMD_GET_VERSION_V1_OUT_LEN 32
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0
-/* Reserved version number to indicate "any" version. */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff
-/* The version response of a boot ROM awaiting rescue */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000
-#define MC_CMD_GET_VERSION_V1_OUT_PCOL_OFST 4
-/* 128bit mask of functions supported by the current firmware */
-#define MC_CMD_GET_VERSION_V1_OUT_SUPPORTED_FUNCS_OFST 8
 /* The command set exported by the boot ROM (MCDI v0) */
 #define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS {		\
 	(1 << MC_CMD_READ32)	|			\
@@ -320,1456 +190,2214 @@
 	(1 << MC_CMD_COPYCODE)	|			\
 	(1 << MC_CMD_GET_VERSION),			\
 	0, 0, 0 }
-#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24
 
-/* Vectors in the boot ROM */
-/* Point to the copycode entry point. */
-#define MC_BOOTROM_COPYCODE_VEC (0x7f4)
-/* Points to the recovery mode entry point. */
-#define MC_BOOTROM_NOFLASH_VEC (0x7f8)
+#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x)		\
+	(MC_CMD_SENSOR_ENTRY_OFST + (_x))
+
+#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n)		\
+	(MC_CMD_DBI_WRITE_IN_DBIWROP_OFST +		\
+	 MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST +		\
+	 (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
+
+#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n)		\
+	(MC_CMD_DBI_WRITE_IN_DBIWROP_OFST +		\
+	 MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST +	\
+	 (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
+
+#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n)		\
+	(MC_CMD_DBI_WRITE_IN_DBIWROP_OFST +		\
+	 MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST +		\
+	 (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
+
+
+/* MCDI_EVENT structuredef */
+#define    MCDI_EVENT_LEN 8
+#define       MCDI_EVENT_CONT_LBN 32
+#define       MCDI_EVENT_CONT_WIDTH 1
+#define       MCDI_EVENT_LEVEL_LBN 33
+#define       MCDI_EVENT_LEVEL_WIDTH 3
+#define          MCDI_EVENT_LEVEL_INFO  0x0 /* enum */
+#define          MCDI_EVENT_LEVEL_WARN 0x1 /* enum */
+#define          MCDI_EVENT_LEVEL_ERR 0x2 /* enum */
+#define          MCDI_EVENT_LEVEL_FATAL 0x3 /* enum */
+#define       MCDI_EVENT_DATA_OFST 0
+#define        MCDI_EVENT_CMDDONE_SEQ_LBN 0
+#define        MCDI_EVENT_CMDDONE_SEQ_WIDTH 8
+#define        MCDI_EVENT_CMDDONE_DATALEN_LBN 8
+#define        MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8
+#define        MCDI_EVENT_CMDDONE_ERRNO_LBN 16
+#define        MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8
+#define        MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0
+#define        MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16
+#define        MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
+#define        MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
+#define          MCDI_EVENT_LINKCHANGE_SPEED_100M  0x1 /* enum */
+#define          MCDI_EVENT_LINKCHANGE_SPEED_1G  0x2 /* enum */
+#define          MCDI_EVENT_LINKCHANGE_SPEED_10G  0x3 /* enum */
+#define        MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
+#define        MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
+#define        MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
+#define        MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8
+#define        MCDI_EVENT_SENSOREVT_MONITOR_LBN 0
+#define        MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8
+#define        MCDI_EVENT_SENSOREVT_STATE_LBN 8
+#define        MCDI_EVENT_SENSOREVT_STATE_WIDTH 8
+#define        MCDI_EVENT_SENSOREVT_VALUE_LBN 16
+#define        MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16
+#define        MCDI_EVENT_FWALERT_DATA_LBN 8
+#define        MCDI_EVENT_FWALERT_DATA_WIDTH 24
+#define        MCDI_EVENT_FWALERT_REASON_LBN 0
+#define        MCDI_EVENT_FWALERT_REASON_WIDTH 8
+#define          MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1 /* enum */
+#define        MCDI_EVENT_FLR_VF_LBN 0
+#define        MCDI_EVENT_FLR_VF_WIDTH 8
+#define        MCDI_EVENT_TX_ERR_TXQ_LBN 0
+#define        MCDI_EVENT_TX_ERR_TXQ_WIDTH 12
+#define        MCDI_EVENT_TX_ERR_TYPE_LBN 12
+#define        MCDI_EVENT_TX_ERR_TYPE_WIDTH 4
+#define          MCDI_EVENT_TX_ERR_DL_FAIL 0x1 /* enum */
+#define          MCDI_EVENT_TX_ERR_NO_EOP 0x2 /* enum */
+#define          MCDI_EVENT_TX_ERR_2BIG 0x3 /* enum */
+#define        MCDI_EVENT_TX_ERR_INFO_LBN 16
+#define        MCDI_EVENT_TX_ERR_INFO_WIDTH 16
+#define        MCDI_EVENT_TX_FLUSH_TXQ_LBN 0
+#define        MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12
+#define        MCDI_EVENT_PTP_ERR_TYPE_LBN 0
+#define        MCDI_EVENT_PTP_ERR_TYPE_WIDTH 8
+#define          MCDI_EVENT_PTP_ERR_PLL_LOST 0x1 /* enum */
+#define          MCDI_EVENT_PTP_ERR_FILTER 0x2 /* enum */
+#define          MCDI_EVENT_PTP_ERR_FIFO 0x3 /* enum */
+#define          MCDI_EVENT_PTP_ERR_QUEUE 0x4 /* enum */
+#define       MCDI_EVENT_DATA_LBN 0
+#define       MCDI_EVENT_DATA_WIDTH 32
+#define       MCDI_EVENT_SRC_LBN 36
+#define       MCDI_EVENT_SRC_WIDTH 8
+#define       MCDI_EVENT_EV_CODE_LBN 60
+#define       MCDI_EVENT_EV_CODE_WIDTH 4
+#define       MCDI_EVENT_CODE_LBN 44
+#define       MCDI_EVENT_CODE_WIDTH 8
+#define          MCDI_EVENT_CODE_BADSSERT 0x1 /* enum */
+#define          MCDI_EVENT_CODE_PMNOTICE 0x2 /* enum */
+#define          MCDI_EVENT_CODE_CMDDONE 0x3 /* enum */
+#define          MCDI_EVENT_CODE_LINKCHANGE 0x4 /* enum */
+#define          MCDI_EVENT_CODE_SENSOREVT 0x5 /* enum */
+#define          MCDI_EVENT_CODE_SCHEDERR 0x6 /* enum */
+#define          MCDI_EVENT_CODE_REBOOT 0x7 /* enum */
+#define          MCDI_EVENT_CODE_MAC_STATS_DMA 0x8 /* enum */
+#define          MCDI_EVENT_CODE_FWALERT 0x9 /* enum */
+#define          MCDI_EVENT_CODE_FLR 0xa /* enum */
+#define          MCDI_EVENT_CODE_TX_ERR 0xb /* enum */
+#define          MCDI_EVENT_CODE_TX_FLUSH  0xc /* enum */
+#define          MCDI_EVENT_CODE_PTP_RX  0xd /* enum */
+#define          MCDI_EVENT_CODE_PTP_FAULT  0xe /* enum */
+#define       MCDI_EVENT_CMDDONE_DATA_OFST 0
+#define       MCDI_EVENT_CMDDONE_DATA_LBN 0
+#define       MCDI_EVENT_CMDDONE_DATA_WIDTH 32
+#define       MCDI_EVENT_LINKCHANGE_DATA_OFST 0
+#define       MCDI_EVENT_LINKCHANGE_DATA_LBN 0
+#define       MCDI_EVENT_LINKCHANGE_DATA_WIDTH 32
+#define       MCDI_EVENT_SENSOREVT_DATA_OFST 0
+#define       MCDI_EVENT_SENSOREVT_DATA_LBN 0
+#define       MCDI_EVENT_SENSOREVT_DATA_WIDTH 32
+#define       MCDI_EVENT_MAC_STATS_DMA_GENERATION_OFST 0
+#define       MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0
+#define       MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32
+#define       MCDI_EVENT_TX_ERR_DATA_OFST 0
+#define       MCDI_EVENT_TX_ERR_DATA_LBN 0
+#define       MCDI_EVENT_TX_ERR_DATA_WIDTH 32
+#define       MCDI_EVENT_PTP_SECONDS_OFST 0
+#define       MCDI_EVENT_PTP_SECONDS_LBN 0
+#define       MCDI_EVENT_PTP_SECONDS_WIDTH 32
+#define       MCDI_EVENT_PTP_NANOSECONDS_OFST 0
+#define       MCDI_EVENT_PTP_NANOSECONDS_LBN 0
+#define       MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32
+#define       MCDI_EVENT_PTP_UUID_OFST 0
+#define       MCDI_EVENT_PTP_UUID_LBN 0
+#define       MCDI_EVENT_PTP_UUID_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_READ32
+ * Read multiple 32byte words from MC memory.
+ */
+#define MC_CMD_READ32 0x1
+
+/* MC_CMD_READ32_IN msgrequest */
+#define    MC_CMD_READ32_IN_LEN 8
+#define       MC_CMD_READ32_IN_ADDR_OFST 0
+#define       MC_CMD_READ32_IN_NUMWORDS_OFST 4
+
+/* MC_CMD_READ32_OUT msgresponse */
+#define    MC_CMD_READ32_OUT_LENMIN 4
+#define    MC_CMD_READ32_OUT_LENMAX 252
+#define    MC_CMD_READ32_OUT_LEN(num) (0+4*(num))
+#define       MC_CMD_READ32_OUT_BUFFER_OFST 0
+#define       MC_CMD_READ32_OUT_BUFFER_LEN 4
+#define       MC_CMD_READ32_OUT_BUFFER_MINNUM 1
+#define       MC_CMD_READ32_OUT_BUFFER_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_WRITE32
+ * Write multiple 32byte words to MC memory.
+ */
+#define MC_CMD_WRITE32 0x2
+
+/* MC_CMD_WRITE32_IN msgrequest */
+#define    MC_CMD_WRITE32_IN_LENMIN 8
+#define    MC_CMD_WRITE32_IN_LENMAX 252
+#define    MC_CMD_WRITE32_IN_LEN(num) (4+4*(num))
+#define       MC_CMD_WRITE32_IN_ADDR_OFST 0
+#define       MC_CMD_WRITE32_IN_BUFFER_OFST 4
+#define       MC_CMD_WRITE32_IN_BUFFER_LEN 4
+#define       MC_CMD_WRITE32_IN_BUFFER_MINNUM 1
+#define       MC_CMD_WRITE32_IN_BUFFER_MAXNUM 62
+
+/* MC_CMD_WRITE32_OUT msgresponse */
+#define    MC_CMD_WRITE32_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_COPYCODE
+ * Copy MC code between two locations and jump.
+ */
+#define MC_CMD_COPYCODE 0x3
+
+/* MC_CMD_COPYCODE_IN msgrequest */
+#define    MC_CMD_COPYCODE_IN_LEN 16
+#define       MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0
+#define       MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4
+#define       MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8
+#define       MC_CMD_COPYCODE_IN_JUMP_OFST 12
+#define          MC_CMD_COPYCODE_JUMP_NONE 0x1 /* enum */
+
+/* MC_CMD_COPYCODE_OUT msgresponse */
+#define    MC_CMD_COPYCODE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SET_FUNC
+ */
+#define MC_CMD_SET_FUNC 0x4
+
+/* MC_CMD_SET_FUNC_IN msgrequest */
+#define    MC_CMD_SET_FUNC_IN_LEN 4
+#define       MC_CMD_SET_FUNC_IN_FUNC_OFST 0
+
+/* MC_CMD_SET_FUNC_OUT msgresponse */
+#define    MC_CMD_SET_FUNC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_BOOT_STATUS
+ */
+#define MC_CMD_GET_BOOT_STATUS 0x5
+
+/* MC_CMD_GET_BOOT_STATUS_IN msgrequest */
+#define    MC_CMD_GET_BOOT_STATUS_IN_LEN 0
+
+/* MC_CMD_GET_BOOT_STATUS_OUT msgresponse */
+#define    MC_CMD_GET_BOOT_STATUS_OUT_LEN 8
+#define       MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0
+#define       MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
+#define        MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0
+#define        MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1
+#define        MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_LBN 1
+#define        MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_WIDTH 1
+#define        MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_LBN 2
+#define        MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_WIDTH 1
 
-/* Test execution limits */
-#define MC_TESTEXEC_VARIANT_COUNT 16
-#define MC_TESTEXEC_RESULT_COUNT 7
 
-/* MC_CMD_SET_TESTVARS: (debug, variadic in)
- * Write variant words for test.
- *
- * The user supplies a bitmap of the variants they wish to set.
- * They must ensure that IN.LEN >= 4 + 4 * ffs(BITMAP)
- */
-#define MC_CMD_SET_TESTVARS 0x09
-#define MC_CMD_SET_TESTVARS_IN_LEN(_numwords)	\
-  (4 + 4*(_numwords))
-#define MC_CMD_SET_TESTVARS_IN_ARGS_BITMAP_OFST 0
-/* Up to MC_TESTEXEC_VARIANT_COUNT of 32byte words start here */
-#define MC_CMD_SET_TESTVARS_IN_ARGS_BUFFER_OFST 4
-#define MC_CMD_SET_TESTVARS_OUT_LEN 0
-
-/* MC_CMD_GET_TESTRCS: (debug, variadic out)
- * Return result words from test.
- */
-#define MC_CMD_GET_TESTRCS 0x0a
-#define MC_CMD_GET_TESTRCS_IN_LEN 4
-#define MC_CMD_GET_TESTRCS_IN_NUMWORDS_OFST 0
-#define MC_CMD_GET_TESTRCS_OUT_LEN(_numwords) \
-	(4 * (_numwords))
-#define MC_CMD_GET_TESTRCS_OUT_BUFFER_OFST 0
-
-/* MC_CMD_RUN_TEST: (debug)
- * Run the test exported by this firmware image
- */
-#define MC_CMD_RUN_TEST 0x0b
-#define MC_CMD_RUN_TEST_IN_LEN 0
-#define MC_CMD_RUN_TEST_OUT_LEN 0
-
-/* MC_CMD_CSR_READ32: (debug, variadic out)
- * Read 32bit words from the indirect memory map
- */
-#define MC_CMD_CSR_READ32 0x0c
-#define MC_CMD_CSR_READ32_IN_LEN 12
-#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0
-#define MC_CMD_CSR_READ32_IN_STEP_OFST 4
-#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8
-#define MC_CMD_CSR_READ32_OUT_LEN(_numwords)	\
-	(((_numwords) * 4) + 4)
-/* IN.NUMWORDS of 32bit words start here */
-#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0
-#define MC_CMD_CSR_READ32_OUT_IREG_STATUS_OFST(_numwords)	\
-	((_numwords) * 4)
-
-/* MC_CMD_CSR_WRITE32: (debug, variadic in)
- * Write 32bit dwords to the indirect memory map
- */
-#define MC_CMD_CSR_WRITE32 0x0d
-#define MC_CMD_CSR_WRITE32_IN_LEN(_numwords)	\
-	(((_numwords) * 4) + 8)
-#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0
-#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4
-/* Multiple 32bit words of data to write start here */
-#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8
-#define MC_CMD_CSR_WRITE32_OUT_LEN 4
-#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0
-
-/* MC_CMD_JTAG_WORK: (debug, fpga only)
- * Process JTAG work buffer for RBF acceleration.
- *
- *  Host: bit count, (up to) 32 words of data to clock out to JTAG
- *   (bits 1,0=TMS,TDO for first bit; bits 3,2=TMS,TDO for second bit, etc.)
- *  MC: bit count, (up to) 32 words of data clocked in from JTAG
- *   (bit 0=TDI for first bit, bit 1=TDI for second bit, etc.; [31:16] unused)
+/***********************************/
+/* MC_CMD_GET_ASSERTS
+ * Get and clear any assertion status.
  */
-#define MC_CMD_JTAG_WORK 0x0e
+#define MC_CMD_GET_ASSERTS 0x6
 
-/* MC_CMD_STACKINFO: (debug, variadic out)
- * Get stack information
- *
- * Host: nothing
- * MC: (thread ptr, stack size, free space) for each thread in system
- */
-#define MC_CMD_STACKINFO 0x0f
+/* MC_CMD_GET_ASSERTS_IN msgrequest */
+#define    MC_CMD_GET_ASSERTS_IN_LEN 4
+#define       MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0
+
+/* MC_CMD_GET_ASSERTS_OUT msgresponse */
+#define    MC_CMD_GET_ASSERTS_OUT_LEN 140
+#define       MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0
+#define          MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum */
+#define          MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 /* enum */
+#define          MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 /* enum */
+#define          MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 /* enum */
+#define       MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4
+#define       MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8
+#define       MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4
+#define       MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM 31
+#define       MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132
+#define       MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136
 
-/* MC_CMD_MDIO_READ:
- * MDIO register read
+
+/***********************************/
+/* MC_CMD_LOG_CTRL
+ * Configure the output stream for various events and messages.
+ */
+#define MC_CMD_LOG_CTRL 0x7
+
+/* MC_CMD_LOG_CTRL_IN msgrequest */
+#define    MC_CMD_LOG_CTRL_IN_LEN 8
+#define       MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0
+#define          MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum */
+#define          MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* enum */
+#define       MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4
+
+/* MC_CMD_LOG_CTRL_OUT msgresponse */
+#define    MC_CMD_LOG_CTRL_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_VERSION
+ * Get version information about the MC firmware.
+ */
+#define MC_CMD_GET_VERSION 0x8
+
+/* MC_CMD_GET_VERSION_IN msgrequest */
+#define    MC_CMD_GET_VERSION_IN_LEN 0
+
+/* MC_CMD_GET_VERSION_V0_OUT msgresponse */
+#define    MC_CMD_GET_VERSION_V0_OUT_LEN 4
+#define       MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0
+#define          MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum */
+#define          MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 /* enum */
+
+/* MC_CMD_GET_VERSION_OUT msgresponse */
+#define    MC_CMD_GET_VERSION_OUT_LEN 32
+/*            MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */
+/*            Enum values, see field(s): */
+/*               MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */
+#define       MC_CMD_GET_VERSION_OUT_PCOL_OFST 4
+#define       MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8
+#define       MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16
+#define       MC_CMD_GET_VERSION_OUT_VERSION_OFST 24
+#define       MC_CMD_GET_VERSION_OUT_VERSION_LEN 8
+#define       MC_CMD_GET_VERSION_OUT_VERSION_LO_OFST 24
+#define       MC_CMD_GET_VERSION_OUT_VERSION_HI_OFST 28
+
+
+/***********************************/
+/* MC_CMD_GET_FPGAREG
+ * Read multiple bytes from PTP FPGA.
+ */
+#define MC_CMD_GET_FPGAREG 0x9
+
+/* MC_CMD_GET_FPGAREG_IN msgrequest */
+#define    MC_CMD_GET_FPGAREG_IN_LEN 8
+#define       MC_CMD_GET_FPGAREG_IN_ADDR_OFST 0
+#define       MC_CMD_GET_FPGAREG_IN_NUMBYTES_OFST 4
+
+/* MC_CMD_GET_FPGAREG_OUT msgresponse */
+#define    MC_CMD_GET_FPGAREG_OUT_LENMIN 1
+#define    MC_CMD_GET_FPGAREG_OUT_LENMAX 255
+#define    MC_CMD_GET_FPGAREG_OUT_LEN(num) (0+1*(num))
+#define       MC_CMD_GET_FPGAREG_OUT_BUFFER_OFST 0
+#define       MC_CMD_GET_FPGAREG_OUT_BUFFER_LEN 1
+#define       MC_CMD_GET_FPGAREG_OUT_BUFFER_MINNUM 1
+#define       MC_CMD_GET_FPGAREG_OUT_BUFFER_MAXNUM 255
+
+
+/***********************************/
+/* MC_CMD_PUT_FPGAREG
+ * Write multiple bytes to PTP FPGA.
+ */
+#define MC_CMD_PUT_FPGAREG 0xa
+
+/* MC_CMD_PUT_FPGAREG_IN msgrequest */
+#define    MC_CMD_PUT_FPGAREG_IN_LENMIN 5
+#define    MC_CMD_PUT_FPGAREG_IN_LENMAX 255
+#define    MC_CMD_PUT_FPGAREG_IN_LEN(num) (4+1*(num))
+#define       MC_CMD_PUT_FPGAREG_IN_ADDR_OFST 0
+#define       MC_CMD_PUT_FPGAREG_IN_BUFFER_OFST 4
+#define       MC_CMD_PUT_FPGAREG_IN_BUFFER_LEN 1
+#define       MC_CMD_PUT_FPGAREG_IN_BUFFER_MINNUM 1
+#define       MC_CMD_PUT_FPGAREG_IN_BUFFER_MAXNUM 251
+
+/* MC_CMD_PUT_FPGAREG_OUT msgresponse */
+#define    MC_CMD_PUT_FPGAREG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_PTP
+ * Perform PTP operation
+ */
+#define MC_CMD_PTP 0xb
+
+/* MC_CMD_PTP_IN msgrequest */
+#define    MC_CMD_PTP_IN_LEN 1
+#define       MC_CMD_PTP_IN_OP_OFST 0
+#define       MC_CMD_PTP_IN_OP_LEN 1
+#define          MC_CMD_PTP_OP_ENABLE 0x1 /* enum */
+#define          MC_CMD_PTP_OP_DISABLE 0x2 /* enum */
+#define          MC_CMD_PTP_OP_TRANSMIT 0x3 /* enum */
+#define          MC_CMD_PTP_OP_READ_NIC_TIME 0x4 /* enum */
+#define          MC_CMD_PTP_OP_STATUS 0x5 /* enum */
+#define          MC_CMD_PTP_OP_ADJUST 0x6 /* enum */
+#define          MC_CMD_PTP_OP_SYNCHRONIZE 0x7 /* enum */
+#define          MC_CMD_PTP_OP_MANFTEST_BASIC 0x8 /* enum */
+#define          MC_CMD_PTP_OP_MANFTEST_PACKET 0x9 /* enum */
+#define          MC_CMD_PTP_OP_RESET_STATS 0xa /* enum */
+#define          MC_CMD_PTP_OP_DEBUG 0xb /* enum */
+#define          MC_CMD_PTP_OP_MAX 0xc /* enum */
+
+/* MC_CMD_PTP_IN_ENABLE msgrequest */
+#define    MC_CMD_PTP_IN_ENABLE_LEN 16
+#define       MC_CMD_PTP_IN_CMD_OFST 0
+#define       MC_CMD_PTP_IN_PERIPH_ID_OFST 4
+#define       MC_CMD_PTP_IN_ENABLE_QUEUE_OFST 8
+#define       MC_CMD_PTP_IN_ENABLE_MODE_OFST 12
+#define          MC_CMD_PTP_MODE_V1 0x0 /* enum */
+#define          MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */
+#define          MC_CMD_PTP_MODE_V2 0x2 /* enum */
+#define          MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */
+
+/* MC_CMD_PTP_IN_DISABLE msgrequest */
+#define    MC_CMD_PTP_IN_DISABLE_LEN 8
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_TRANSMIT msgrequest */
+#define    MC_CMD_PTP_IN_TRANSMIT_LENMIN 13
+#define    MC_CMD_PTP_IN_TRANSMIT_LENMAX 255
+#define    MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num))
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+#define       MC_CMD_PTP_IN_TRANSMIT_LENGTH_OFST 8
+#define       MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12
+#define       MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1
+#define       MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1
+#define       MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM 243
+
+/* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */
+#define    MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_STATUS msgrequest */
+#define    MC_CMD_PTP_IN_STATUS_LEN 8
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_ADJUST msgrequest */
+#define    MC_CMD_PTP_IN_ADJUST_LEN 24
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+#define       MC_CMD_PTP_IN_ADJUST_FREQ_OFST 8
+#define       MC_CMD_PTP_IN_ADJUST_FREQ_LEN 8
+#define       MC_CMD_PTP_IN_ADJUST_FREQ_LO_OFST 8
+#define       MC_CMD_PTP_IN_ADJUST_FREQ_HI_OFST 12
+#define          MC_CMD_PTP_IN_ADJUST_BITS 0x28 /* enum */
+#define       MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16
+#define       MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20
+
+/* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */
+#define    MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+#define       MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_OFST 8
+#define       MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_OFST 12
+#define       MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LEN 8
+#define       MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LO_OFST 12
+#define       MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_HI_OFST 16
+
+/* MC_CMD_PTP_IN_MANFTEST_BASIC msgrequest */
+#define    MC_CMD_PTP_IN_MANFTEST_BASIC_LEN 8
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_MANFTEST_PACKET msgrequest */
+#define    MC_CMD_PTP_IN_MANFTEST_PACKET_LEN 12
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+#define       MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8
+
+/* MC_CMD_PTP_IN_RESET_STATS msgrequest */
+#define    MC_CMD_PTP_IN_RESET_STATS_LEN 8
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_DEBUG msgrequest */
+#define    MC_CMD_PTP_IN_DEBUG_LEN 12
+/*            MC_CMD_PTP_IN_CMD_OFST 0 */
+/*            MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+#define       MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_OFST 8
+
+/* MC_CMD_PTP_OUT msgresponse */
+#define    MC_CMD_PTP_OUT_LEN 0
+
+/* MC_CMD_PTP_OUT_TRANSMIT msgresponse */
+#define    MC_CMD_PTP_OUT_TRANSMIT_LEN 8
+#define       MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0
+#define       MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4
+
+/* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */
+#define    MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8
+#define       MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0
+#define       MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4
+
+/* MC_CMD_PTP_OUT_STATUS msgresponse */
+#define    MC_CMD_PTP_OUT_STATUS_LEN 64
+#define       MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_OFST 0
+#define       MC_CMD_PTP_OUT_STATUS_STATS_TX_OFST 4
+#define       MC_CMD_PTP_OUT_STATUS_STATS_RX_OFST 8
+#define       MC_CMD_PTP_OUT_STATUS_STATS_TS_OFST 12
+#define       MC_CMD_PTP_OUT_STATUS_STATS_FM_OFST 16
+#define       MC_CMD_PTP_OUT_STATUS_STATS_NFM_OFST 20
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56
+#define       MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60
+
+/* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */
+#define    MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20
+#define    MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX 240
+#define    MC_CMD_PTP_OUT_SYNCHRONIZE_LEN(num) (0+20*(num))
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_OFST 0
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN 20
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MINNUM 1
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12
+#define       MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_OFST 16
+
+/* MC_CMD_PTP_OUT_MANFTEST_BASIC msgresponse */
+#define    MC_CMD_PTP_OUT_MANFTEST_BASIC_LEN 8
+#define       MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_OFST 0
+#define          MC_CMD_PTP_MANF_SUCCESS 0x0 /* enum */
+#define          MC_CMD_PTP_MANF_FPGA_LOAD 0x1 /* enum */
+#define          MC_CMD_PTP_MANF_FPGA_VERSION 0x2 /* enum */
+#define          MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3 /* enum */
+#define          MC_CMD_PTP_MANF_OSCILLATOR 0x4 /* enum */
+#define          MC_CMD_PTP_MANF_TIMESTAMPS 0x5 /* enum */
+#define          MC_CMD_PTP_MANF_PACKET_COUNT 0x6 /* enum */
+#define          MC_CMD_PTP_MANF_FILTER_COUNT 0x7 /* enum */
+#define          MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 /* enum */
+#define          MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 /* enum */
+#define       MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4
+
+/* MC_CMD_PTP_OUT_MANFTEST_PACKET msgresponse */
+#define    MC_CMD_PTP_OUT_MANFTEST_PACKET_LEN 12
+#define       MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_OFST 0
+#define       MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_OFST 4
+#define       MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_OFST 8
+
+
+/***********************************/
+/* MC_CMD_CSR_READ32
+ * Read 32bit words from the indirect memory map.
+ */
+#define MC_CMD_CSR_READ32 0xc
+
+/* MC_CMD_CSR_READ32_IN msgrequest */
+#define    MC_CMD_CSR_READ32_IN_LEN 12
+#define       MC_CMD_CSR_READ32_IN_ADDR_OFST 0
+#define       MC_CMD_CSR_READ32_IN_STEP_OFST 4
+#define       MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8
+
+/* MC_CMD_CSR_READ32_OUT msgresponse */
+#define    MC_CMD_CSR_READ32_OUT_LENMIN 4
+#define    MC_CMD_CSR_READ32_OUT_LENMAX 252
+#define    MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num))
+#define       MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0
+#define       MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4
+#define       MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1
+#define       MC_CMD_CSR_READ32_OUT_BUFFER_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_CSR_WRITE32
+ * Write 32bit dwords to the indirect memory map.
+ */
+#define MC_CMD_CSR_WRITE32 0xd
+
+/* MC_CMD_CSR_WRITE32_IN msgrequest */
+#define    MC_CMD_CSR_WRITE32_IN_LENMIN 12
+#define    MC_CMD_CSR_WRITE32_IN_LENMAX 252
+#define    MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num))
+#define       MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0
+#define       MC_CMD_CSR_WRITE32_IN_STEP_OFST 4
+#define       MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8
+#define       MC_CMD_CSR_WRITE32_IN_BUFFER_LEN 4
+#define       MC_CMD_CSR_WRITE32_IN_BUFFER_MINNUM 1
+#define       MC_CMD_CSR_WRITE32_IN_BUFFER_MAXNUM 61
+
+/* MC_CMD_CSR_WRITE32_OUT msgresponse */
+#define    MC_CMD_CSR_WRITE32_OUT_LEN 4
+#define       MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0
+
+
+/***********************************/
+/* MC_CMD_STACKINFO
+ * Get stack information.
+ */
+#define MC_CMD_STACKINFO 0xf
+
+/* MC_CMD_STACKINFO_IN msgrequest */
+#define    MC_CMD_STACKINFO_IN_LEN 0
+
+/* MC_CMD_STACKINFO_OUT msgresponse */
+#define    MC_CMD_STACKINFO_OUT_LENMIN 12
+#define    MC_CMD_STACKINFO_OUT_LENMAX 252
+#define    MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num))
+#define       MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0
+#define       MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12
+#define       MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1
+#define       MC_CMD_STACKINFO_OUT_THREAD_INFO_MAXNUM 21
+
+
+/***********************************/
+/* MC_CMD_MDIO_READ
+ * MDIO register read.
  */
 #define MC_CMD_MDIO_READ 0x10
-#define MC_CMD_MDIO_READ_IN_LEN 16
-#define MC_CMD_MDIO_READ_IN_BUS_OFST 0
-#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4
-#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8
-#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12
-#define MC_CMD_MDIO_READ_OUT_LEN 8
-#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0
-#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4
-
-/* MC_CMD_MDIO_WRITE:
- * MDIO register write
- */
-#define MC_CMD_MDIO_WRITE 0x11
-#define MC_CMD_MDIO_WRITE_IN_LEN 20
-#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0
-#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4
-#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8
-#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12
-#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16
-#define MC_CMD_MDIO_WRITE_OUT_LEN 4
-#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0
 
-/* By default all the MCDI MDIO operations perform clause45 mode.
- * If you want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22.
- */
-#define MC_CMD_MDIO_CLAUSE22 32
+/* MC_CMD_MDIO_READ_IN msgrequest */
+#define    MC_CMD_MDIO_READ_IN_LEN 16
+#define       MC_CMD_MDIO_READ_IN_BUS_OFST 0
+#define          MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum */
+#define          MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* enum */
+#define       MC_CMD_MDIO_READ_IN_PRTAD_OFST 4
+#define       MC_CMD_MDIO_READ_IN_DEVAD_OFST 8
+#define          MC_CMD_MDIO_CLAUSE22 0x20 /* enum */
+#define       MC_CMD_MDIO_READ_IN_ADDR_OFST 12
 
-/* There are two MDIO buses: one for the internal PHY, and one for external
- * devices.
- */
-#define MC_CMD_MDIO_BUS_INTERNAL 0
-#define MC_CMD_MDIO_BUS_EXTERNAL 1
+/* MC_CMD_MDIO_READ_OUT msgresponse */
+#define    MC_CMD_MDIO_READ_OUT_LEN 8
+#define       MC_CMD_MDIO_READ_OUT_VALUE_OFST 0
+#define       MC_CMD_MDIO_READ_OUT_STATUS_OFST 4
+#define          MC_CMD_MDIO_STATUS_GOOD 0x8 /* enum */
 
-/* The MDIO commands return the raw status bits from the MDIO block.  A "good"
- * transaction should have the DONE bit set and all other bits clear.
+
+/***********************************/
+/* MC_CMD_MDIO_WRITE
+ * MDIO register write.
  */
-#define MC_CMD_MDIO_STATUS_GOOD 0x08
+#define MC_CMD_MDIO_WRITE 0x11
 
+/* MC_CMD_MDIO_WRITE_IN msgrequest */
+#define    MC_CMD_MDIO_WRITE_IN_LEN 20
+#define       MC_CMD_MDIO_WRITE_IN_BUS_OFST 0
+/*               MC_CMD_MDIO_BUS_INTERNAL 0x0 */
+/*               MC_CMD_MDIO_BUS_EXTERNAL 0x1 */
+#define       MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4
+#define       MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8
+/*               MC_CMD_MDIO_CLAUSE22 0x20 */
+#define       MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12
+#define       MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16
 
-/* MC_CMD_DBI_WRITE: (debug)
- * Write DBI register(s)
- *
- * Host: address, byte-enables (and VF selection, and cs2 flag),
- *       value [,address ...]
- * MC: nothing
+/* MC_CMD_MDIO_WRITE_OUT msgresponse */
+#define    MC_CMD_MDIO_WRITE_OUT_LEN 4
+#define       MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0
+/*               MC_CMD_MDIO_STATUS_GOOD 0x8 */
+
+
+/***********************************/
+/* MC_CMD_DBI_WRITE
+ * Write DBI register(s).
  */
 #define MC_CMD_DBI_WRITE 0x12
-#define MC_CMD_DBI_WRITE_IN_LEN(_numwords)		\
-	(12 * (_numwords))
-#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(_word)		\
-	(((_word) * 12) + 0)
-#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(_word)	\
-	(((_word) * 12) + 4)
-#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(_word)		\
-	(((_word) * 12) + 8)
-#define MC_CMD_DBI_WRITE_OUT_LEN 0
-
-/* MC_CMD_DBI_READ: (debug)
- * Read DBI register(s)
- *
- * Host: address, [,address ...]
- * MC: value [,value ...]
- * (note: this does not support reading from VFs, but is retained for backwards
- * compatibility; see MC_CMD_DBI_READX below)
- */
-#define MC_CMD_DBI_READ 0x13
-#define MC_CMD_DBI_READ_IN_LEN(_numwords)		\
-	(4 * (_numwords))
-#define MC_CMD_DBI_READ_OUT_LEN(_numwords)		\
-	(4 * (_numwords))
-
-/* MC_CMD_PORT_READ32: (debug)
+
+/* MC_CMD_DBI_WRITE_IN msgrequest */
+#define    MC_CMD_DBI_WRITE_IN_LENMIN 12
+#define    MC_CMD_DBI_WRITE_IN_LENMAX 252
+#define    MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num))
+#define       MC_CMD_DBI_WRITE_IN_DBIWROP_OFST 0
+#define       MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12
+#define       MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1
+#define       MC_CMD_DBI_WRITE_IN_DBIWROP_MAXNUM 21
+
+/* MC_CMD_DBI_WRITE_OUT msgresponse */
+#define    MC_CMD_DBI_WRITE_OUT_LEN 0
+
+/* MC_CMD_DBIWROP_TYPEDEF structuredef */
+#define    MC_CMD_DBIWROP_TYPEDEF_LEN 12
+#define       MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0
+#define       MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0
+#define       MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32
+#define       MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST 4
+#define       MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_LBN 32
+#define       MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_WIDTH 32
+#define       MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8
+#define       MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64
+#define       MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_PORT_READ32
  * Read a 32-bit register from the indirect port register map.
- *
- * The port to access is implied by the Shared memory channel used.
  */
 #define MC_CMD_PORT_READ32 0x14
-#define MC_CMD_PORT_READ32_IN_LEN 4
-#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0
-#define MC_CMD_PORT_READ32_OUT_LEN 8
-#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0
-#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4
 
-/* MC_CMD_PORT_WRITE32: (debug)
+/* MC_CMD_PORT_READ32_IN msgrequest */
+#define    MC_CMD_PORT_READ32_IN_LEN 4
+#define       MC_CMD_PORT_READ32_IN_ADDR_OFST 0
+
+/* MC_CMD_PORT_READ32_OUT msgresponse */
+#define    MC_CMD_PORT_READ32_OUT_LEN 8
+#define       MC_CMD_PORT_READ32_OUT_VALUE_OFST 0
+#define       MC_CMD_PORT_READ32_OUT_STATUS_OFST 4
+
+
+/***********************************/
+/* MC_CMD_PORT_WRITE32
  * Write a 32-bit register to the indirect port register map.
- *
- * The port to access is implied by the Shared memory channel used.
  */
 #define MC_CMD_PORT_WRITE32 0x15
-#define MC_CMD_PORT_WRITE32_IN_LEN 8
-#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0
-#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4
-#define MC_CMD_PORT_WRITE32_OUT_LEN 4
-#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0
-
-/* MC_CMD_PORT_READ128: (debug)
- * Read a 128-bit register from indirect port register map
- *
- * The port to access is implied by the Shared memory channel used.
+
+/* MC_CMD_PORT_WRITE32_IN msgrequest */
+#define    MC_CMD_PORT_WRITE32_IN_LEN 8
+#define       MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0
+#define       MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4
+
+/* MC_CMD_PORT_WRITE32_OUT msgresponse */
+#define    MC_CMD_PORT_WRITE32_OUT_LEN 4
+#define       MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0
+
+
+/***********************************/
+/* MC_CMD_PORT_READ128
+ * Read a 128-bit register from the indirect port register map.
  */
 #define MC_CMD_PORT_READ128 0x16
-#define MC_CMD_PORT_READ128_IN_LEN 4
-#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0
-#define MC_CMD_PORT_READ128_OUT_LEN 20
-#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0
-#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16
-
-/* MC_CMD_PORT_WRITE128: (debug)
- * Write a 128-bit register to indirect port register map.
- *
- * The port to access is implied by the Shared memory channel used.
+
+/* MC_CMD_PORT_READ128_IN msgrequest */
+#define    MC_CMD_PORT_READ128_IN_LEN 4
+#define       MC_CMD_PORT_READ128_IN_ADDR_OFST 0
+
+/* MC_CMD_PORT_READ128_OUT msgresponse */
+#define    MC_CMD_PORT_READ128_OUT_LEN 20
+#define       MC_CMD_PORT_READ128_OUT_VALUE_OFST 0
+#define       MC_CMD_PORT_READ128_OUT_VALUE_LEN 16
+#define       MC_CMD_PORT_READ128_OUT_STATUS_OFST 16
+
+
+/***********************************/
+/* MC_CMD_PORT_WRITE128
+ * Write a 128-bit register to the indirect port register map.
  */
 #define MC_CMD_PORT_WRITE128 0x17
-#define MC_CMD_PORT_WRITE128_IN_LEN 20
-#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0
-#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4
-#define MC_CMD_PORT_WRITE128_OUT_LEN 4
-#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0
-
-/* MC_CMD_GET_BOARD_CFG:
- * Returns the MC firmware configuration structure
- *
- * The FW_SUBTYPE_LIST contains a 16-bit value for each of the 12 types of
- * NVRAM area.  The values are defined in the firmware/mc/platform/<xxx>.c file
- * for a specific board type, but otherwise have no meaning to the MC; they
- * are used by the driver to manage selection of appropriate firmware updates.
+
+/* MC_CMD_PORT_WRITE128_IN msgrequest */
+#define    MC_CMD_PORT_WRITE128_IN_LEN 20
+#define       MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0
+#define       MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4
+#define       MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16
+
+/* MC_CMD_PORT_WRITE128_OUT msgresponse */
+#define    MC_CMD_PORT_WRITE128_OUT_LEN 4
+#define       MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0
+
+
+/***********************************/
+/* MC_CMD_GET_BOARD_CFG
+ * Returns the MC firmware configuration structure.
  */
 #define MC_CMD_GET_BOARD_CFG 0x18
-#define MC_CMD_GET_BOARD_CFG_IN_LEN 0
-#define MC_CMD_GET_BOARD_CFG_OUT_LEN 96
-#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0
-#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4
-#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32
-#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36
-#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64
-#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68
-#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72
-#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 24
-
-/* MC_CMD_DBI_READX: (debug)
- * Read DBI register(s) -- extended functionality
- *
- * Host: vf selection, address, [,vf selection ...]
- * MC: value [,value ...]
+
+/* MC_CMD_GET_BOARD_CFG_IN msgrequest */
+#define    MC_CMD_GET_BOARD_CFG_IN_LEN 0
+
+/* MC_CMD_GET_BOARD_CFG_OUT msgresponse */
+#define    MC_CMD_GET_BOARD_CFG_OUT_LENMIN 96
+#define    MC_CMD_GET_BOARD_CFG_OUT_LENMAX 136
+#define    MC_CMD_GET_BOARD_CFG_OUT_LEN(num) (72+2*(num))
+#define       MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0
+#define       MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4
+#define       MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32
+#define       MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36
+#define          MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0x0 /* enum */
+#define          MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 0x1 /* enum */
+#define          MC_CMD_CAPABILITIES_TURBO_LBN 0x1 /* enum */
+#define          MC_CMD_CAPABILITIES_TURBO_WIDTH 0x1 /* enum */
+#define          MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 0x2 /* enum */
+#define          MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 0x1 /* enum */
+#define          MC_CMD_CAPABILITIES_PTP_LBN 0x3 /* enum */
+#define          MC_CMD_CAPABILITIES_PTP_WIDTH 0x1 /* enum */
+#define       MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40
+/*            Enum values, see field(s): */
+/*               CAPABILITIES_PORT0 */
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64
+#define       MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68
+#define       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72
+#define       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2
+#define       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM 12
+#define       MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM 32
+
+
+/***********************************/
+/* MC_CMD_DBI_READX
+ * Read DBI register(s).
  */
 #define MC_CMD_DBI_READX 0x19
-#define MC_CMD_DBI_READX_IN_LEN(_numwords)	\
-  (8*(_numwords))
-#define MC_CMD_DBI_READX_OUT_LEN(_numwords)	\
-  (4*(_numwords))
 
-/* MC_CMD_SET_RAND_SEED:
- * Set the 16byte seed for the MC pseudo-random generator
+/* MC_CMD_DBI_READX_IN msgrequest */
+#define    MC_CMD_DBI_READX_IN_LENMIN 8
+#define    MC_CMD_DBI_READX_IN_LENMAX 248
+#define    MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num))
+#define       MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0
+#define       MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8
+#define       MC_CMD_DBI_READX_IN_DBIRDOP_LO_OFST 0
+#define       MC_CMD_DBI_READX_IN_DBIRDOP_HI_OFST 4
+#define       MC_CMD_DBI_READX_IN_DBIRDOP_MINNUM 1
+#define       MC_CMD_DBI_READX_IN_DBIRDOP_MAXNUM 31
+
+/* MC_CMD_DBI_READX_OUT msgresponse */
+#define    MC_CMD_DBI_READX_OUT_LENMIN 4
+#define    MC_CMD_DBI_READX_OUT_LENMAX 252
+#define    MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num))
+#define       MC_CMD_DBI_READX_OUT_VALUE_OFST 0
+#define       MC_CMD_DBI_READX_OUT_VALUE_LEN 4
+#define       MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1
+#define       MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_SET_RAND_SEED
+ * Set the 16byte seed for the MC pseudo-random generator.
  */
 #define MC_CMD_SET_RAND_SEED 0x1a
-#define MC_CMD_SET_RAND_SEED_IN_LEN 16
-#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0
-#define MC_CMD_SET_RAND_SEED_OUT_LEN 0
 
-/* MC_CMD_LTSSM_HIST: (debug)
- * Retrieve the history of the LTSSM, if the build supports it.
- *
- * Host: nothing
- * MC: variable number of LTSSM values, as bytes
- * The history is read-to-clear.
+/* MC_CMD_SET_RAND_SEED_IN msgrequest */
+#define    MC_CMD_SET_RAND_SEED_IN_LEN 16
+#define       MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0
+#define       MC_CMD_SET_RAND_SEED_IN_SEED_LEN 16
+
+/* MC_CMD_SET_RAND_SEED_OUT msgresponse */
+#define    MC_CMD_SET_RAND_SEED_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_LTSSM_HIST
+ * Retrieve the history of the PCIE LTSSM.
  */
 #define MC_CMD_LTSSM_HIST 0x1b
 
-/* MC_CMD_DRV_ATTACH:
- * Inform MCPU that this port is managed on the host (i.e. driver active)
+/* MC_CMD_LTSSM_HIST_IN msgrequest */
+#define    MC_CMD_LTSSM_HIST_IN_LEN 0
+
+/* MC_CMD_LTSSM_HIST_OUT msgresponse */
+#define    MC_CMD_LTSSM_HIST_OUT_LENMIN 0
+#define    MC_CMD_LTSSM_HIST_OUT_LENMAX 252
+#define    MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num))
+#define       MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0
+#define       MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4
+#define       MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0
+#define       MC_CMD_LTSSM_HIST_OUT_DATA_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_DRV_ATTACH
+ * Inform MCPU that this port is managed on the host.
  */
 #define MC_CMD_DRV_ATTACH 0x1c
-#define MC_CMD_DRV_ATTACH_IN_LEN 8
-#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0
-#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
-#define MC_CMD_DRV_ATTACH_OUT_LEN 4
-#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0
 
-/* MC_CMD_NCSI_PROD: (debug)
- * Trigger an NC-SI event (and possibly an AEN in response)
+/* MC_CMD_DRV_ATTACH_IN msgrequest */
+#define    MC_CMD_DRV_ATTACH_IN_LEN 8
+#define       MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0
+#define       MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
+
+/* MC_CMD_DRV_ATTACH_OUT msgresponse */
+#define    MC_CMD_DRV_ATTACH_OUT_LEN 4
+#define       MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0
+
+
+/***********************************/
+/* MC_CMD_NCSI_PROD
+ * Trigger an NC-SI event.
  */
 #define MC_CMD_NCSI_PROD 0x1d
-#define MC_CMD_NCSI_PROD_IN_LEN 4
-#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0
-#define MC_CMD_NCSI_PROD_LINKCHANGE_LBN 0
-#define MC_CMD_NCSI_PROD_LINKCHANGE_WIDTH 1
-#define MC_CMD_NCSI_PROD_RESET_LBN 1
-#define MC_CMD_NCSI_PROD_RESET_WIDTH 1
-#define MC_CMD_NCSI_PROD_DRVATTACH_LBN 2
-#define MC_CMD_NCSI_PROD_DRVATTACH_WIDTH 1
-#define MC_CMD_NCSI_PROD_OUT_LEN 0
-
-/* Enumeration */
-#define MC_CMD_NCSI_PROD_LINKCHANGE 0
-#define MC_CMD_NCSI_PROD_RESET 1
-#define MC_CMD_NCSI_PROD_DRVATTACH 2
-
-/* MC_CMD_DEVEL: (debug)
- * Reserved for development
- */
-#define MC_CMD_DEVEL 0x1e
-
-/* MC_CMD_SHMUART: (debug)
+
+/* MC_CMD_NCSI_PROD_IN msgrequest */
+#define    MC_CMD_NCSI_PROD_IN_LEN 4
+#define       MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0
+#define          MC_CMD_NCSI_PROD_LINKCHANGE 0x0 /* enum */
+#define          MC_CMD_NCSI_PROD_RESET 0x1 /* enum */
+#define          MC_CMD_NCSI_PROD_DRVATTACH 0x2 /* enum */
+#define        MC_CMD_NCSI_PROD_IN_LINKCHANGE_LBN 0
+#define        MC_CMD_NCSI_PROD_IN_LINKCHANGE_WIDTH 1
+#define        MC_CMD_NCSI_PROD_IN_RESET_LBN 1
+#define        MC_CMD_NCSI_PROD_IN_RESET_WIDTH 1
+#define        MC_CMD_NCSI_PROD_IN_DRVATTACH_LBN 2
+#define        MC_CMD_NCSI_PROD_IN_DRVATTACH_WIDTH 1
+
+/* MC_CMD_NCSI_PROD_OUT msgresponse */
+#define    MC_CMD_NCSI_PROD_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SHMUART
  * Route UART output to circular buffer in shared memory instead.
  */
 #define MC_CMD_SHMUART 0x1f
-#define MC_CMD_SHMUART_IN_FLAG_OFST 0
-#define MC_CMD_SHMUART_IN_LEN 4
-#define MC_CMD_SHMUART_OUT_LEN 0
 
-/* MC_CMD_PORT_RESET:
- * Generic per-port reset. There is no equivalent for per-board reset.
- *
- * Locks required: None
- * Return code: 0, ETIME
- */
-#define MC_CMD_PORT_RESET 0x20
-#define MC_CMD_PORT_RESET_IN_LEN 0
-#define MC_CMD_PORT_RESET_OUT_LEN 0
-
-/* MC_CMD_RESOURCE_LOCK:
- * Generic resource lock/unlock interface.
- *
- * Locks required: None
- * Return code: 0,
- *              EBUSY (if trylock is contended by other port),
- *              EDEADLK (if trylock is already acquired by this port)
- *              EINVAL (if unlock doesn't own the lock)
- */
-#define MC_CMD_RESOURCE_LOCK 0x21
-#define MC_CMD_RESOURCE_LOCK_IN_LEN 8
-#define MC_CMD_RESOURCE_LOCK_IN_ACTION_OFST 0
-#define MC_CMD_RESOURCE_LOCK_ACTION_TRYLOCK 1
-#define MC_CMD_RESOURCE_LOCK_ACTION_UNLOCK 0
-#define MC_CMD_RESOURCE_LOCK_IN_RESOURCE_OFST 4
-#define MC_CMD_RESOURCE_LOCK_I2C 2
-#define MC_CMD_RESOURCE_LOCK_PHY 3
-#define MC_CMD_RESOURCE_LOCK_OUT_LEN 0
-
-/* MC_CMD_SPI_COMMAND: (variadic in, variadic out)
- * Read/Write to/from the SPI device.
- *
- * Locks required: SPI_LOCK
- * Return code: 0, ETIME, EINVAL, EACCES (if SPI_LOCK is not held)
- */
-#define MC_CMD_SPI_COMMAND 0x22
-#define MC_CMD_SPI_COMMAND_IN_LEN(_write_bytes)	(12 + (_write_bytes))
-#define MC_CMD_SPI_COMMAND_IN_ARGS_OFST 0
-#define MC_CMD_SPI_COMMAND_IN_ARGS_ADDRESS_OFST 0
-#define MC_CMD_SPI_COMMAND_IN_ARGS_READ_BYTES_OFST 4
-#define MC_CMD_SPI_COMMAND_IN_ARGS_CHIP_SELECT_OFST 8
-/* Data to write here */
-#define MC_CMD_SPI_COMMAND_IN_WRITE_BUFFER_OFST 12
-#define MC_CMD_SPI_COMMAND_OUT_LEN(_read_bytes) (_read_bytes)
-/* Data read here */
-#define MC_CMD_SPI_COMMAND_OUT_READ_BUFFER_OFST 0
-
-/* MC_CMD_I2C_READ_WRITE: (variadic in, variadic out)
- * Read/Write to/from the I2C bus.
- *
- * Locks required: I2C_LOCK
- * Return code: 0, ETIME, EINVAL, EACCES (if I2C_LOCK is not held)
- */
-#define MC_CMD_I2C_RW 0x23
-#define MC_CMD_I2C_RW_IN_LEN(_write_bytes) (8 + (_write_bytes))
-#define MC_CMD_I2C_RW_IN_ARGS_OFST 0
-#define MC_CMD_I2C_RW_IN_ARGS_ADDR_OFST 0
-#define MC_CMD_I2C_RW_IN_ARGS_READ_BYTES_OFST 4
-/* Data to write here */
-#define MC_CMD_I2C_RW_IN_WRITE_BUFFER_OFSET 8
-#define MC_CMD_I2C_RW_OUT_LEN(_read_bytes) (_read_bytes)
-/* Data read here */
-#define MC_CMD_I2C_RW_OUT_READ_BUFFER_OFST 0
-
-/* Generic phy capability bitmask */
-#define MC_CMD_PHY_CAP_10HDX_LBN 1
-#define MC_CMD_PHY_CAP_10HDX_WIDTH 1
-#define MC_CMD_PHY_CAP_10FDX_LBN 2
-#define MC_CMD_PHY_CAP_10FDX_WIDTH 1
-#define MC_CMD_PHY_CAP_100HDX_LBN 3
-#define MC_CMD_PHY_CAP_100HDX_WIDTH 1
-#define MC_CMD_PHY_CAP_100FDX_LBN 4
-#define MC_CMD_PHY_CAP_100FDX_WIDTH 1
-#define MC_CMD_PHY_CAP_1000HDX_LBN 5
-#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1
-#define MC_CMD_PHY_CAP_1000FDX_LBN 6
-#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1
-#define MC_CMD_PHY_CAP_10000FDX_LBN 7
-#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1
-#define MC_CMD_PHY_CAP_PAUSE_LBN 8
-#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1
-#define MC_CMD_PHY_CAP_ASYM_LBN 9
-#define MC_CMD_PHY_CAP_ASYM_WIDTH 1
-#define MC_CMD_PHY_CAP_AN_LBN 10
-#define MC_CMD_PHY_CAP_AN_WIDTH 1
-
-/* Generic loopback enumeration */
-#define MC_CMD_LOOPBACK_NONE 0
-#define MC_CMD_LOOPBACK_DATA 1
-#define MC_CMD_LOOPBACK_GMAC 2
-#define MC_CMD_LOOPBACK_XGMII 3
-#define MC_CMD_LOOPBACK_XGXS 4
-#define MC_CMD_LOOPBACK_XAUI 5
-#define MC_CMD_LOOPBACK_GMII 6
-#define MC_CMD_LOOPBACK_SGMII 7
-#define MC_CMD_LOOPBACK_XGBR 8
-#define MC_CMD_LOOPBACK_XFI 9
-#define MC_CMD_LOOPBACK_XAUI_FAR 10
-#define MC_CMD_LOOPBACK_GMII_FAR 11
-#define MC_CMD_LOOPBACK_SGMII_FAR 12
-#define MC_CMD_LOOPBACK_XFI_FAR 13
-#define MC_CMD_LOOPBACK_GPHY 14
-#define MC_CMD_LOOPBACK_PHYXS 15
-#define MC_CMD_LOOPBACK_PCS 16
-#define MC_CMD_LOOPBACK_PMAPMD 17
-#define MC_CMD_LOOPBACK_XPORT 18
-#define MC_CMD_LOOPBACK_XGMII_WS 19
-#define MC_CMD_LOOPBACK_XAUI_WS 20
-#define MC_CMD_LOOPBACK_XAUI_WS_FAR 21
-#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 22
-#define MC_CMD_LOOPBACK_GMII_WS 23
-#define MC_CMD_LOOPBACK_XFI_WS 24
-#define MC_CMD_LOOPBACK_XFI_WS_FAR 25
-#define MC_CMD_LOOPBACK_PHYXS_WS 26
-
-/* Generic PHY statistics enumeration */
-#define MC_CMD_OUI 0
-#define MC_CMD_PMA_PMD_LINK_UP 1
-#define MC_CMD_PMA_PMD_RX_FAULT 2
-#define MC_CMD_PMA_PMD_TX_FAULT 3
-#define MC_CMD_PMA_PMD_SIGNAL 4
-#define MC_CMD_PMA_PMD_SNR_A 5
-#define MC_CMD_PMA_PMD_SNR_B 6
-#define MC_CMD_PMA_PMD_SNR_C 7
-#define MC_CMD_PMA_PMD_SNR_D 8
-#define MC_CMD_PCS_LINK_UP 9
-#define MC_CMD_PCS_RX_FAULT 10
-#define MC_CMD_PCS_TX_FAULT 11
-#define MC_CMD_PCS_BER 12
-#define MC_CMD_PCS_BLOCK_ERRORS 13
-#define MC_CMD_PHYXS_LINK_UP 14
-#define MC_CMD_PHYXS_RX_FAULT 15
-#define MC_CMD_PHYXS_TX_FAULT 16
-#define MC_CMD_PHYXS_ALIGN 17
-#define MC_CMD_PHYXS_SYNC 18
-#define MC_CMD_AN_LINK_UP 19
-#define MC_CMD_AN_COMPLETE 20
-#define MC_CMD_AN_10GBT_STATUS 21
-#define MC_CMD_CL22_LINK_UP 22
-#define MC_CMD_PHY_NSTATS 23
-
-/* MC_CMD_GET_PHY_CFG:
- * Report PHY configuration.  This guarantees to succeed even if the PHY is in
- * a "zombie" state.
- *
- * Locks required: None
- * Return code: 0
+/* MC_CMD_SHMUART_IN msgrequest */
+#define    MC_CMD_SHMUART_IN_LEN 4
+#define       MC_CMD_SHMUART_IN_FLAG_OFST 0
+
+/* MC_CMD_SHMUART_OUT msgresponse */
+#define    MC_CMD_SHMUART_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_ENTITY_RESET
+ * Generic per-port reset.
+ */
+#define MC_CMD_ENTITY_RESET 0x20
+
+/* MC_CMD_ENTITY_RESET_IN msgrequest */
+#define    MC_CMD_ENTITY_RESET_IN_LEN 4
+#define       MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0
+#define        MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0
+#define        MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1
+
+/* MC_CMD_ENTITY_RESET_OUT msgresponse */
+#define    MC_CMD_ENTITY_RESET_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_PCIE_CREDITS
+ * Read instantaneous and minimum flow control thresholds.
+ */
+#define MC_CMD_PCIE_CREDITS 0x21
+
+/* MC_CMD_PCIE_CREDITS_IN msgrequest */
+#define    MC_CMD_PCIE_CREDITS_IN_LEN 8
+#define       MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0
+#define       MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4
+
+/* MC_CMD_PCIE_CREDITS_OUT msgresponse */
+#define    MC_CMD_PCIE_CREDITS_OUT_LEN 16
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_OFST 0
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_OFST 2
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_OFST 4
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_OFST 6
+#define       MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_OFST 8
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_OFST 10
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_OFST 12
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_LEN 2
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_OFST 14
+#define       MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_LEN 2
+
+
+/***********************************/
+/* MC_CMD_RXD_MONITOR
+ * Get histogram of RX queue fill level.
+ */
+#define MC_CMD_RXD_MONITOR 0x22
+
+/* MC_CMD_RXD_MONITOR_IN msgrequest */
+#define    MC_CMD_RXD_MONITOR_IN_LEN 12
+#define       MC_CMD_RXD_MONITOR_IN_QID_OFST 0
+#define       MC_CMD_RXD_MONITOR_IN_POLL_PERIOD_OFST 4
+#define       MC_CMD_RXD_MONITOR_IN_WIPE_OFST 8
+
+/* MC_CMD_RXD_MONITOR_OUT msgresponse */
+#define    MC_CMD_RXD_MONITOR_OUT_LEN 80
+#define       MC_CMD_RXD_MONITOR_OUT_QID_OFST 0
+#define       MC_CMD_RXD_MONITOR_OUT_RING_FILL_OFST 4
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_FILL_OFST 8
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_1_OFST 12
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_2_OFST 16
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_4_OFST 20
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_8_OFST 24
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_16_OFST 28
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_32_OFST 32
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_64_OFST 36
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_128_OFST 40
+#define       MC_CMD_RXD_MONITOR_OUT_RING_LT_256_OFST 44
+#define       MC_CMD_RXD_MONITOR_OUT_RING_GE_256_OFST 48
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_LT_1_OFST 52
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_LT_2_OFST 56
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_LT_4_OFST 60
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_LT_8_OFST 64
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_LT_16_OFST 68
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_LT_32_OFST 72
+#define       MC_CMD_RXD_MONITOR_OUT_CACHE_GE_32_OFST 76
+
+
+/***********************************/
+/* MC_CMD_PUTS
+ * puts(3) implementation over MCDI
+ */
+#define MC_CMD_PUTS 0x23
+
+/* MC_CMD_PUTS_IN msgrequest */
+#define    MC_CMD_PUTS_IN_LENMIN 13
+#define    MC_CMD_PUTS_IN_LENMAX 255
+#define    MC_CMD_PUTS_IN_LEN(num) (12+1*(num))
+#define       MC_CMD_PUTS_IN_DEST_OFST 0
+#define        MC_CMD_PUTS_IN_UART_LBN 0
+#define        MC_CMD_PUTS_IN_UART_WIDTH 1
+#define        MC_CMD_PUTS_IN_PORT_LBN 1
+#define        MC_CMD_PUTS_IN_PORT_WIDTH 1
+#define       MC_CMD_PUTS_IN_DHOST_OFST 4
+#define       MC_CMD_PUTS_IN_DHOST_LEN 6
+#define       MC_CMD_PUTS_IN_STRING_OFST 12
+#define       MC_CMD_PUTS_IN_STRING_LEN 1
+#define       MC_CMD_PUTS_IN_STRING_MINNUM 1
+#define       MC_CMD_PUTS_IN_STRING_MAXNUM 243
+
+/* MC_CMD_PUTS_OUT msgresponse */
+#define    MC_CMD_PUTS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_PHY_CFG
+ * Report PHY configuration.
  */
 #define MC_CMD_GET_PHY_CFG 0x24
 
-#define MC_CMD_GET_PHY_CFG_IN_LEN 0
-#define MC_CMD_GET_PHY_CFG_OUT_LEN 72
-
-#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
-#define MC_CMD_GET_PHY_CFG_PRESENT_LBN 0
-#define MC_CMD_GET_PHY_CFG_PRESENT_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN 1
-#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN 2
-#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_LOWPOWER_LBN 3
-#define MC_CMD_GET_PHY_CFG_LOWPOWER_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_POWEROFF_LBN 4
-#define MC_CMD_GET_PHY_CFG_POWEROFF_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_TXDIS_LBN 5
-#define MC_CMD_GET_PHY_CFG_TXDIS_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_BIST_LBN 6
-#define MC_CMD_GET_PHY_CFG_BIST_WIDTH 1
-#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4
-/* Bitmask of supported capabilities */
-#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
-#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12
-#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16
-/* PHY statistics bitmap */
-#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20
-/* PHY type/name string */
-#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24
-#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20
-#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44
-#define MC_CMD_MEDIA_XAUI 1
-#define MC_CMD_MEDIA_CX4 2
-#define MC_CMD_MEDIA_KX4 3
-#define MC_CMD_MEDIA_XFP 4
-#define MC_CMD_MEDIA_SFP_PLUS 5
-#define MC_CMD_MEDIA_BASE_T 6
-/* MDIO "MMDS" supported */
-#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48
-/* Native clause 22 */
-#define MC_CMD_MMD_CLAUSE22  0
-#define MC_CMD_MMD_CLAUSE45_PMAPMD 1
-#define MC_CMD_MMD_CLAUSE45_WIS 2
-#define MC_CMD_MMD_CLAUSE45_PCS 3
-#define MC_CMD_MMD_CLAUSE45_PHYXS 4
-#define MC_CMD_MMD_CLAUSE45_DTEXS 5
-#define MC_CMD_MMD_CLAUSE45_TC 6
-#define MC_CMD_MMD_CLAUSE45_AN 7
-/* Clause22 proxied over clause45 by PHY */
-#define MC_CMD_MMD_CLAUSE45_C22EXT 29
-#define MC_CMD_MMD_CLAUSE45_VEND1 30
-#define MC_CMD_MMD_CLAUSE45_VEND2 31
-/* PHY stepping version */
-#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52
-#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20
-
-/* MC_CMD_START_BIST:
+/* MC_CMD_GET_PHY_CFG_IN msgrequest */
+#define    MC_CMD_GET_PHY_CFG_IN_LEN 0
+
+/* MC_CMD_GET_PHY_CFG_OUT msgresponse */
+#define    MC_CMD_GET_PHY_CFG_OUT_LEN 72
+#define       MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
+#define        MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0
+#define        MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1
+#define        MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN 1
+#define        MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_WIDTH 1
+#define        MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN 2
+#define        MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_WIDTH 1
+#define        MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN 3
+#define        MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_WIDTH 1
+#define        MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN 4
+#define        MC_CMD_GET_PHY_CFG_OUT_POWEROFF_WIDTH 1
+#define        MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN 5
+#define        MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1
+#define        MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6
+#define        MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1
+#define       MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4
+#define       MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
+#define        MC_CMD_PHY_CAP_10HDX_LBN 1
+#define        MC_CMD_PHY_CAP_10HDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_10FDX_LBN 2
+#define        MC_CMD_PHY_CAP_10FDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_100HDX_LBN 3
+#define        MC_CMD_PHY_CAP_100HDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_100FDX_LBN 4
+#define        MC_CMD_PHY_CAP_100FDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_1000HDX_LBN 5
+#define        MC_CMD_PHY_CAP_1000HDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_1000FDX_LBN 6
+#define        MC_CMD_PHY_CAP_1000FDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_10000FDX_LBN 7
+#define        MC_CMD_PHY_CAP_10000FDX_WIDTH 1
+#define        MC_CMD_PHY_CAP_PAUSE_LBN 8
+#define        MC_CMD_PHY_CAP_PAUSE_WIDTH 1
+#define        MC_CMD_PHY_CAP_ASYM_LBN 9
+#define        MC_CMD_PHY_CAP_ASYM_WIDTH 1
+#define        MC_CMD_PHY_CAP_AN_LBN 10
+#define        MC_CMD_PHY_CAP_AN_WIDTH 1
+#define       MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12
+#define       MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16
+#define       MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20
+#define       MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24
+#define       MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20
+#define       MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44
+#define          MC_CMD_MEDIA_XAUI 0x1 /* enum */
+#define          MC_CMD_MEDIA_CX4 0x2 /* enum */
+#define          MC_CMD_MEDIA_KX4 0x3 /* enum */
+#define          MC_CMD_MEDIA_XFP 0x4 /* enum */
+#define          MC_CMD_MEDIA_SFP_PLUS 0x5 /* enum */
+#define          MC_CMD_MEDIA_BASE_T 0x6 /* enum */
+#define       MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48
+#define          MC_CMD_MMD_CLAUSE22 0x0 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_WIS 0x2 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_PCS 0x3 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_PHYXS 0x4 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_DTEXS 0x5 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_TC 0x6 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_AN 0x7 /* enum */
+#define          MC_CMD_MMD_CLAUSE45_C22EXT 0x1d /* enum */
+#define          MC_CMD_MMD_CLAUSE45_VEND1 0x1e /* enum */
+#define          MC_CMD_MMD_CLAUSE45_VEND2 0x1f /* enum */
+#define       MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52
+#define       MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20
+
+
+/***********************************/
+/* MC_CMD_START_BIST
  * Start a BIST test on the PHY.
- *
- * Locks required: PHY_LOCK if doing a  PHY BIST
- * Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held)
  */
 #define MC_CMD_START_BIST 0x25
-#define MC_CMD_START_BIST_IN_LEN 4
-#define MC_CMD_START_BIST_IN_TYPE_OFST 0
-#define MC_CMD_START_BIST_OUT_LEN 0
-
-/* Run the PHY's short cable BIST */
-#define MC_CMD_PHY_BIST_CABLE_SHORT  1
-/* Run the PHY's long cable BIST */
-#define MC_CMD_PHY_BIST_CABLE_LONG   2
-/* Run BIST on the currently selected BPX Serdes (XAUI or XFI) */
-#define MC_CMD_BPX_SERDES_BIST 3
-/* Run the MC loopback tests */
-#define MC_CMD_MC_LOOPBACK_BIST 4
-/* Run the PHY's standard BIST */
-#define MC_CMD_PHY_BIST 5
-
-/* MC_CMD_POLL_PHY_BIST: (variadic output)
- * Poll for BIST completion
- *
- * Returns a single status code, and optionally some PHY specific
- * bist output. The driver should only consume the BIST output
- * after validating OUTLEN and PHY_CFG.PHY_TYPE.
- *
- * If a driver can't successfully parse the BIST output, it should
- * still respect the pass/Fail in OUT.RESULT
- *
- * Locks required: PHY_LOCK if doing a  PHY BIST
- * Return code: 0, EACCES (if PHY_LOCK is not held)
+
+/* MC_CMD_START_BIST_IN msgrequest */
+#define    MC_CMD_START_BIST_IN_LEN 4
+#define       MC_CMD_START_BIST_IN_TYPE_OFST 0
+#define          MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum */
+#define          MC_CMD_PHY_BIST_CABLE_LONG 0x2 /* enum */
+#define          MC_CMD_BPX_SERDES_BIST 0x3 /* enum */
+#define          MC_CMD_MC_LOOPBACK_BIST 0x4 /* enum */
+#define          MC_CMD_PHY_BIST 0x5 /* enum */
+
+/* MC_CMD_START_BIST_OUT msgresponse */
+#define    MC_CMD_START_BIST_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_POLL_BIST
+ * Poll for BIST completion.
  */
 #define MC_CMD_POLL_BIST 0x26
-#define MC_CMD_POLL_BIST_IN_LEN 0
-#define MC_CMD_POLL_BIST_OUT_LEN UNKNOWN
-#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36
-#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8
-#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0
-#define MC_CMD_POLL_BIST_RUNNING 1
-#define MC_CMD_POLL_BIST_PASSED 2
-#define MC_CMD_POLL_BIST_FAILED 3
-#define MC_CMD_POLL_BIST_TIMEOUT 4
-/* Generic: */
-#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4
-/* SFT9001-specific: */
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28
-#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 1
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 2
-#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 3
-#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 4
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 9
-/* mrsfp "PHY" driver: */
-#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4
-#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 1
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 2
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 3
-#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 4
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 5
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 6
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 7
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 8
-
-/* MC_CMD_PHY_SPI: (variadic in, variadic out)
- * Read/Write/Erase the PHY SPI device
- *
- * Locks required: PHY_LOCK
- * Return code: 0, ETIME, EINVAL, EACCES (if PHY_LOCK is not held)
- */
-#define MC_CMD_PHY_SPI 0x27
-#define MC_CMD_PHY_SPI_IN_LEN(_write_bytes) (12 + (_write_bytes))
-#define MC_CMD_PHY_SPI_IN_ARGS_OFST 0
-#define MC_CMD_PHY_SPI_IN_ARGS_ADDR_OFST 0
-#define MC_CMD_PHY_SPI_IN_ARGS_READ_BYTES_OFST 4
-#define MC_CMD_PHY_SPI_IN_ARGS_ERASE_ALL_OFST 8
-/* Data to write here */
-#define MC_CMD_PHY_SPI_IN_WRITE_BUFFER_OFSET 12
-#define MC_CMD_PHY_SPI_OUT_LEN(_read_bytes) (_read_bytes)
-/* Data read here */
-#define MC_CMD_PHY_SPI_OUT_READ_BUFFER_OFST 0
-
-
-/* MC_CMD_GET_LOOPBACK_MODES:
- * Returns a bitmask of loopback modes evailable at each speed.
- *
- * Locks required: None
- * Return code: 0
+
+/* MC_CMD_POLL_BIST_IN msgrequest */
+#define    MC_CMD_POLL_BIST_IN_LEN 0
+
+/* MC_CMD_POLL_BIST_OUT msgresponse */
+#define    MC_CMD_POLL_BIST_OUT_LEN 8
+#define       MC_CMD_POLL_BIST_OUT_RESULT_OFST 0
+#define          MC_CMD_POLL_BIST_RUNNING 0x1 /* enum */
+#define          MC_CMD_POLL_BIST_PASSED 0x2 /* enum */
+#define          MC_CMD_POLL_BIST_FAILED 0x3 /* enum */
+#define          MC_CMD_POLL_BIST_TIMEOUT 0x4 /* enum */
+#define       MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4
+
+/* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */
+#define    MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36
+/*            MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
+/*            Enum values, see field(s): */
+/*               MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20
+#define          MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum */
+#define          MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2 /* enum */
+#define          MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3 /* enum */
+#define          MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4 /* enum */
+#define          MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* enum */
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24
+/*            Enum values, see field(s): */
+/*               CABLE_STATUS_A */
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28
+/*            Enum values, see field(s): */
+/*               CABLE_STATUS_A */
+#define       MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32
+/*            Enum values, see field(s): */
+/*               CABLE_STATUS_A */
+
+/* MC_CMD_POLL_BIST_OUT_MRSFP msgresponse */
+#define    MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8
+/*            MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
+/*            Enum values, see field(s): */
+/*               MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
+#define       MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7 /* enum */
+#define          MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8 /* enum */
+
+
+/***********************************/
+/* MC_CMD_FLUSH_RX_QUEUES
+ * Flush receive queue(s).
+ */
+#define MC_CMD_FLUSH_RX_QUEUES 0x27
+
+/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */
+#define    MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4
+#define    MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX 252
+#define    MC_CMD_FLUSH_RX_QUEUES_IN_LEN(num) (0+4*(num))
+#define       MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_OFST 0
+#define       MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_LEN 4
+#define       MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MINNUM 1
+#define       MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM 63
+
+/* MC_CMD_FLUSH_RX_QUEUES_OUT msgresponse */
+#define    MC_CMD_FLUSH_RX_QUEUES_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_LOOPBACK_MODES
+ * Get port's loopback modes.
  */
 #define MC_CMD_GET_LOOPBACK_MODES 0x28
-#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0
-#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32
-#define MC_CMD_GET_LOOPBACK_MODES_100M_OFST 0
-#define MC_CMD_GET_LOOPBACK_MODES_1G_OFST 8
-#define MC_CMD_GET_LOOPBACK_MODES_10G_OFST 16
-#define MC_CMD_GET_LOOPBACK_MODES_SUGGESTED_OFST 24
-
-/* Flow control enumeration */
-#define MC_CMD_FCNTL_OFF 0
-#define MC_CMD_FCNTL_RESPOND 1
-#define MC_CMD_FCNTL_BIDIR 2
-/* Auto - Use what the link has autonegotiated
- *      - The driver should modify the advertised capabilities via SET_LINK.CAP
- *        to control the negotiated flow control mode.
- *      - Can only be set if the PHY supports PAUSE+ASYM capabilities
- *      - Never returned by GET_LINK as the value programmed into the MAC
- */
-#define MC_CMD_FCNTL_AUTO 3
-
-/* Generic mac fault bitmask */
-#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0
-#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1
-#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1
-#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1
-#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2
-#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1
-
-/* MC_CMD_GET_LINK:
- * Read the unified MAC/PHY link state
- *
- * Locks required: None
- * Return code: 0, ETIME
+
+/* MC_CMD_GET_LOOPBACK_MODES_IN msgrequest */
+#define    MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0
+
+/* MC_CMD_GET_LOOPBACK_MODES_OUT msgresponse */
+#define    MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_100M_OFST 0
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LEN 8
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4
+#define          MC_CMD_LOOPBACK_NONE  0x0 /* enum */
+#define          MC_CMD_LOOPBACK_DATA  0x1 /* enum */
+#define          MC_CMD_LOOPBACK_GMAC  0x2 /* enum */
+#define          MC_CMD_LOOPBACK_XGMII 0x3 /* enum */
+#define          MC_CMD_LOOPBACK_XGXS  0x4 /* enum */
+#define          MC_CMD_LOOPBACK_XAUI  0x5 /* enum */
+#define          MC_CMD_LOOPBACK_GMII  0x6 /* enum */
+#define          MC_CMD_LOOPBACK_SGMII  0x7 /* enum */
+#define          MC_CMD_LOOPBACK_XGBR  0x8 /* enum */
+#define          MC_CMD_LOOPBACK_XFI  0x9 /* enum */
+#define          MC_CMD_LOOPBACK_XAUI_FAR  0xa /* enum */
+#define          MC_CMD_LOOPBACK_GMII_FAR  0xb /* enum */
+#define          MC_CMD_LOOPBACK_SGMII_FAR  0xc /* enum */
+#define          MC_CMD_LOOPBACK_XFI_FAR  0xd /* enum */
+#define          MC_CMD_LOOPBACK_GPHY  0xe /* enum */
+#define          MC_CMD_LOOPBACK_PHYXS  0xf /* enum */
+#define          MC_CMD_LOOPBACK_PCS  0x10 /* enum */
+#define          MC_CMD_LOOPBACK_PMAPMD  0x11 /* enum */
+#define          MC_CMD_LOOPBACK_XPORT  0x12 /* enum */
+#define          MC_CMD_LOOPBACK_XGMII_WS  0x13 /* enum */
+#define          MC_CMD_LOOPBACK_XAUI_WS  0x14 /* enum */
+#define          MC_CMD_LOOPBACK_XAUI_WS_FAR  0x15 /* enum */
+#define          MC_CMD_LOOPBACK_XAUI_WS_NEAR  0x16 /* enum */
+#define          MC_CMD_LOOPBACK_GMII_WS  0x17 /* enum */
+#define          MC_CMD_LOOPBACK_XFI_WS  0x18 /* enum */
+#define          MC_CMD_LOOPBACK_XFI_WS_FAR  0x19 /* enum */
+#define          MC_CMD_LOOPBACK_PHYXS_WS  0x1a /* enum */
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LO_OFST 8
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_1G_HI_OFST 12
+/*            Enum values, see field(s): */
+/*               100M */
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_10G_OFST 16
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LEN 8
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LO_OFST 16
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_10G_HI_OFST 20
+/*            Enum values, see field(s): */
+/*               100M */
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST 24
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN 8
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LO_OFST 24
+#define       MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_HI_OFST 28
+/*            Enum values, see field(s): */
+/*               100M */
+
+
+/***********************************/
+/* MC_CMD_GET_LINK
+ * Read the unified MAC/PHY link state.
  */
 #define MC_CMD_GET_LINK 0x29
-#define MC_CMD_GET_LINK_IN_LEN 0
-#define MC_CMD_GET_LINK_OUT_LEN 28
-/* near-side and link-partner advertised capabilities */
-#define MC_CMD_GET_LINK_OUT_CAP_OFST 0
-#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4
-/* Autonegotiated speed in mbit/s. The link may still be down
- * even if this reads non-zero */
-#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8
-#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12
-#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16
-/* Whether we have overall link up */
-#define MC_CMD_GET_LINK_LINK_UP_LBN 0
-#define MC_CMD_GET_LINK_LINK_UP_WIDTH 1
-#define MC_CMD_GET_LINK_FULL_DUPLEX_LBN 1
-#define MC_CMD_GET_LINK_FULL_DUPLEX_WIDTH 1
-/* Whether we have link at the layers provided by the BPX */
-#define MC_CMD_GET_LINK_BPX_LINK_LBN 2
-#define MC_CMD_GET_LINK_BPX_LINK_WIDTH 1
-/* Whether the PHY has external link */
-#define MC_CMD_GET_LINK_PHY_LINK_LBN 3
-#define MC_CMD_GET_LINK_PHY_LINK_WIDTH 1
-#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20
-#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24
-
-/* MC_CMD_SET_LINK:
- * Write the unified MAC/PHY link configuration
- *
- * A loopback speed of "0" is supported, and means
- * (choose any available speed)
- *
- * Locks required: None
- * Return code: 0, EINVAL, ETIME
+
+/* MC_CMD_GET_LINK_IN msgrequest */
+#define    MC_CMD_GET_LINK_IN_LEN 0
+
+/* MC_CMD_GET_LINK_OUT msgresponse */
+#define    MC_CMD_GET_LINK_OUT_LEN 28
+#define       MC_CMD_GET_LINK_OUT_CAP_OFST 0
+#define       MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4
+#define       MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8
+#define       MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12
+/*            Enum values, see field(s): */
+/*               MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
+#define       MC_CMD_GET_LINK_OUT_FLAGS_OFST 16
+#define        MC_CMD_GET_LINK_OUT_LINK_UP_LBN 0
+#define        MC_CMD_GET_LINK_OUT_LINK_UP_WIDTH 1
+#define        MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN 1
+#define        MC_CMD_GET_LINK_OUT_FULL_DUPLEX_WIDTH 1
+#define        MC_CMD_GET_LINK_OUT_BPX_LINK_LBN 2
+#define        MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1
+#define        MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3
+#define        MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1
+#define       MC_CMD_GET_LINK_OUT_FCNTL_OFST 20
+#define          MC_CMD_FCNTL_OFF 0x0 /* enum */
+#define          MC_CMD_FCNTL_RESPOND 0x1 /* enum */
+#define          MC_CMD_FCNTL_BIDIR 0x2 /* enum */
+#define       MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24
+#define        MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0
+#define        MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1
+#define        MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1
+#define        MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1
+#define        MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2
+#define        MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1
+#define        MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3
+#define        MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1
+
+
+/***********************************/
+/* MC_CMD_SET_LINK
+ * Write the unified MAC/PHY link configuration.
  */
 #define MC_CMD_SET_LINK 0x2a
-#define MC_CMD_SET_LINK_IN_LEN 16
-#define MC_CMD_SET_LINK_IN_CAP_OFST 0
-#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4
-#define MC_CMD_SET_LINK_LOWPOWER_LBN 0
-#define MC_CMD_SET_LINK_LOWPOWER_WIDTH 1
-#define MC_CMD_SET_LINK_POWEROFF_LBN 1
-#define MC_CMD_SET_LINK_POWEROFF_WIDTH 1
-#define MC_CMD_SET_LINK_TXDIS_LBN 2
-#define MC_CMD_SET_LINK_TXDIS_WIDTH 1
-#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8
-#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12
-#define MC_CMD_SET_LINK_OUT_LEN 0
-
-/* MC_CMD_SET_ID_LED:
- * Set indentification LED state
- *
- * Locks required: None
- * Return code: 0, EINVAL
+
+/* MC_CMD_SET_LINK_IN msgrequest */
+#define    MC_CMD_SET_LINK_IN_LEN 16
+#define       MC_CMD_SET_LINK_IN_CAP_OFST 0
+#define       MC_CMD_SET_LINK_IN_FLAGS_OFST 4
+#define        MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0
+#define        MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1
+#define        MC_CMD_SET_LINK_IN_POWEROFF_LBN 1
+#define        MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1
+#define        MC_CMD_SET_LINK_IN_TXDIS_LBN 2
+#define        MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1
+#define       MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8
+/*            Enum values, see field(s): */
+/*               MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
+#define       MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12
+
+/* MC_CMD_SET_LINK_OUT msgresponse */
+#define    MC_CMD_SET_LINK_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SET_ID_LED
+ * Set indentification LED state.
  */
 #define MC_CMD_SET_ID_LED 0x2b
-#define MC_CMD_SET_ID_LED_IN_LEN 4
-#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0
-#define  MC_CMD_LED_OFF 0
-#define  MC_CMD_LED_ON 1
-#define  MC_CMD_LED_DEFAULT 2
-#define MC_CMD_SET_ID_LED_OUT_LEN 0
-
-/* MC_CMD_SET_MAC:
- * Set MAC configuration
- *
- * The MTU is the MTU programmed directly into the XMAC/GMAC
- * (inclusive of EtherII, VLAN, bug16011 padding)
- *
- * Locks required: None
- * Return code: 0, EINVAL
+
+/* MC_CMD_SET_ID_LED_IN msgrequest */
+#define    MC_CMD_SET_ID_LED_IN_LEN 4
+#define       MC_CMD_SET_ID_LED_IN_STATE_OFST 0
+#define          MC_CMD_LED_OFF  0x0 /* enum */
+#define          MC_CMD_LED_ON  0x1 /* enum */
+#define          MC_CMD_LED_DEFAULT  0x2 /* enum */
+
+/* MC_CMD_SET_ID_LED_OUT msgresponse */
+#define    MC_CMD_SET_ID_LED_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SET_MAC
+ * Set MAC configuration.
  */
 #define MC_CMD_SET_MAC 0x2c
-#define MC_CMD_SET_MAC_IN_LEN 24
-#define MC_CMD_SET_MAC_IN_MTU_OFST 0
-#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4
-#define MC_CMD_SET_MAC_IN_ADDR_OFST 8
-#define MC_CMD_SET_MAC_IN_REJECT_OFST 16
-#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0
-#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1
-#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1
-#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1
-#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20
-#define MC_CMD_SET_MAC_OUT_LEN 0
-
-/* MC_CMD_PHY_STATS:
- * Get generic PHY statistics
- *
- * This call returns the statistics for a generic PHY in a sparse
- * array (indexed by the enumerate). Each value is represented by
- * a 32bit number.
- *
- * If the DMA_ADDR is 0, then no DMA is performed, and the statistics
- * may be read directly out of shared memory. If DMA_ADDR != 0, then
- * the statistics are dmad to that (page-aligned location)
- *
- * Locks required: None
- * Returns: 0, ETIME
- * Response methods: shared memory, event
+
+/* MC_CMD_SET_MAC_IN msgrequest */
+#define    MC_CMD_SET_MAC_IN_LEN 24
+#define       MC_CMD_SET_MAC_IN_MTU_OFST 0
+#define       MC_CMD_SET_MAC_IN_DRAIN_OFST 4
+#define       MC_CMD_SET_MAC_IN_ADDR_OFST 8
+#define       MC_CMD_SET_MAC_IN_ADDR_LEN 8
+#define       MC_CMD_SET_MAC_IN_ADDR_LO_OFST 8
+#define       MC_CMD_SET_MAC_IN_ADDR_HI_OFST 12
+#define       MC_CMD_SET_MAC_IN_REJECT_OFST 16
+#define        MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0
+#define        MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1
+#define        MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1
+#define        MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1
+#define       MC_CMD_SET_MAC_IN_FCNTL_OFST 20
+/*               MC_CMD_FCNTL_OFF 0x0 */
+/*               MC_CMD_FCNTL_RESPOND 0x1 */
+/*               MC_CMD_FCNTL_BIDIR 0x2 */
+#define          MC_CMD_FCNTL_AUTO 0x3 /* enum */
+
+/* MC_CMD_SET_MAC_OUT msgresponse */
+#define    MC_CMD_SET_MAC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_PHY_STATS
+ * Get generic PHY statistics.
  */
 #define MC_CMD_PHY_STATS 0x2d
-#define MC_CMD_PHY_STATS_IN_LEN 8
-#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0
-#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4
-#define MC_CMD_PHY_STATS_OUT_DMA_LEN 0
-#define MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (MC_CMD_PHY_NSTATS * 4)
-
-/* Unified MAC statistics enumeration */
-#define MC_CMD_MAC_GENERATION_START 0
-#define MC_CMD_MAC_TX_PKTS 1
-#define MC_CMD_MAC_TX_PAUSE_PKTS 2
-#define MC_CMD_MAC_TX_CONTROL_PKTS 3
-#define MC_CMD_MAC_TX_UNICAST_PKTS 4
-#define MC_CMD_MAC_TX_MULTICAST_PKTS 5
-#define MC_CMD_MAC_TX_BROADCAST_PKTS 6
-#define MC_CMD_MAC_TX_BYTES 7
-#define MC_CMD_MAC_TX_BAD_BYTES 8
-#define MC_CMD_MAC_TX_LT64_PKTS 9
-#define MC_CMD_MAC_TX_64_PKTS 10
-#define MC_CMD_MAC_TX_65_TO_127_PKTS 11
-#define MC_CMD_MAC_TX_128_TO_255_PKTS 12
-#define MC_CMD_MAC_TX_256_TO_511_PKTS 13
-#define MC_CMD_MAC_TX_512_TO_1023_PKTS 14
-#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 15
-#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 16
-#define MC_CMD_MAC_TX_GTJUMBO_PKTS 17
-#define MC_CMD_MAC_TX_BAD_FCS_PKTS 18
-#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 19
-#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 20
-#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 21
-#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 22
-#define MC_CMD_MAC_TX_DEFERRED_PKTS 23
-#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 24
-#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 25
-#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 26
-#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 27
-#define MC_CMD_MAC_RX_PKTS 28
-#define MC_CMD_MAC_RX_PAUSE_PKTS 29
-#define MC_CMD_MAC_RX_GOOD_PKTS 30
-#define MC_CMD_MAC_RX_CONTROL_PKTS 31
-#define MC_CMD_MAC_RX_UNICAST_PKTS 32
-#define MC_CMD_MAC_RX_MULTICAST_PKTS 33
-#define MC_CMD_MAC_RX_BROADCAST_PKTS 34
-#define MC_CMD_MAC_RX_BYTES 35
-#define MC_CMD_MAC_RX_BAD_BYTES 36
-#define MC_CMD_MAC_RX_64_PKTS 37
-#define MC_CMD_MAC_RX_65_TO_127_PKTS 38
-#define MC_CMD_MAC_RX_128_TO_255_PKTS 39
-#define MC_CMD_MAC_RX_256_TO_511_PKTS 40
-#define MC_CMD_MAC_RX_512_TO_1023_PKTS 41
-#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 42
-#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 43
-#define MC_CMD_MAC_RX_GTJUMBO_PKTS 44
-#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 45
-#define MC_CMD_MAC_RX_BAD_FCS_PKTS 46
-#define MC_CMD_MAC_RX_OVERFLOW_PKTS 47
-#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 48
-#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 49
-#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 50
-#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 51
-#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 52
-#define MC_CMD_MAC_RX_JABBER_PKTS 53
-#define MC_CMD_MAC_RX_NODESC_DROPS 54
-#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 55
-#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 56
-#define MC_CMD_MAC_RX_LANES01_DISP_ERR 57
-#define MC_CMD_MAC_RX_LANES23_DISP_ERR 58
-#define MC_CMD_MAC_RX_MATCH_FAULT 59
-#define MC_CMD_GMAC_DMABUF_START 64
-#define MC_CMD_GMAC_DMABUF_END   95
-/* Insert new members here. */
-#define MC_CMD_MAC_GENERATION_END 96
-#define MC_CMD_MAC_NSTATS (MC_CMD_MAC_GENERATION_END+1)
-
-/* MC_CMD_MAC_STATS:
- * Get unified GMAC/XMAC statistics
- *
- * This call returns unified statistics maintained by the MC as it
- * switches between the GMAC and XMAC. The MC will write out all
- * supported stats.  The driver should zero initialise the buffer to
- * guarantee consistent results.
- *
- * Locks required: None
- * Returns: 0
- * Response methods: shared memory, event
- */
-#define MC_CMD_MAC_STATS 0x2e
-#define MC_CMD_MAC_STATS_IN_LEN 16
-#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0
-#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4
-#define MC_CMD_MAC_STATS_IN_CMD_OFST 8
-#define MC_CMD_MAC_STATS_CMD_DMA_LBN 0
-#define MC_CMD_MAC_STATS_CMD_DMA_WIDTH 1
-#define MC_CMD_MAC_STATS_CMD_CLEAR_LBN 1
-#define MC_CMD_MAC_STATS_CMD_CLEAR_WIDTH 1
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_LBN 2
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_WIDTH 1
-/* Remaining PERIOD* fields only relevant when PERIODIC_CHANGE is set */
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_LBN 3
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_WIDTH 1
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_LBN 4
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_WIDTH 1
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT_LBN 5
-#define MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT_WIDTH 1
-#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_LBN 16
-#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_WIDTH 16
-#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12
-
-#define MC_CMD_MAC_STATS_OUT_LEN 0
-
-/* Callisto flags */
-#define MC_CMD_SFT9001_ROBUST_LBN 0
-#define MC_CMD_SFT9001_ROBUST_WIDTH 1
-#define MC_CMD_SFT9001_SHORT_REACH_LBN 1
-#define MC_CMD_SFT9001_SHORT_REACH_WIDTH 1
-
-/* MC_CMD_SFT9001_GET:
- * Read current callisto specific setting
- *
- * Locks required: None
- * Returns: 0, ETIME
- */
-#define MC_CMD_SFT9001_GET 0x30
-#define MC_CMD_SFT9001_GET_IN_LEN 0
-#define MC_CMD_SFT9001_GET_OUT_LEN 4
-#define MC_CMD_SFT9001_GET_OUT_FLAGS_OFST 0
 
-/* MC_CMD_SFT9001_SET:
- * Write current callisto specific setting
- *
- * Locks required: None
- * Returns: 0, ETIME, EINVAL
+/* MC_CMD_PHY_STATS_IN msgrequest */
+#define    MC_CMD_PHY_STATS_IN_LEN 8
+#define       MC_CMD_PHY_STATS_IN_DMA_ADDR_OFST 0
+#define       MC_CMD_PHY_STATS_IN_DMA_ADDR_LEN 8
+#define       MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0
+#define       MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4
+
+/* MC_CMD_PHY_STATS_OUT_DMA msgresponse */
+#define    MC_CMD_PHY_STATS_OUT_DMA_LEN 0
+
+/* MC_CMD_PHY_STATS_OUT_NO_DMA msgresponse */
+#define    MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (((MC_CMD_PHY_NSTATS*32))>>3)
+#define       MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_OFST 0
+#define       MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4
+#define       MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS
+#define          MC_CMD_OUI  0x0 /* enum */
+#define          MC_CMD_PMA_PMD_LINK_UP  0x1 /* enum */
+#define          MC_CMD_PMA_PMD_RX_FAULT  0x2 /* enum */
+#define          MC_CMD_PMA_PMD_TX_FAULT  0x3 /* enum */
+#define          MC_CMD_PMA_PMD_SIGNAL  0x4 /* enum */
+#define          MC_CMD_PMA_PMD_SNR_A  0x5 /* enum */
+#define          MC_CMD_PMA_PMD_SNR_B  0x6 /* enum */
+#define          MC_CMD_PMA_PMD_SNR_C  0x7 /* enum */
+#define          MC_CMD_PMA_PMD_SNR_D  0x8 /* enum */
+#define          MC_CMD_PCS_LINK_UP  0x9 /* enum */
+#define          MC_CMD_PCS_RX_FAULT  0xa /* enum */
+#define          MC_CMD_PCS_TX_FAULT  0xb /* enum */
+#define          MC_CMD_PCS_BER  0xc /* enum */
+#define          MC_CMD_PCS_BLOCK_ERRORS  0xd /* enum */
+#define          MC_CMD_PHYXS_LINK_UP  0xe /* enum */
+#define          MC_CMD_PHYXS_RX_FAULT  0xf /* enum */
+#define          MC_CMD_PHYXS_TX_FAULT  0x10 /* enum */
+#define          MC_CMD_PHYXS_ALIGN  0x11 /* enum */
+#define          MC_CMD_PHYXS_SYNC  0x12 /* enum */
+#define          MC_CMD_AN_LINK_UP  0x13 /* enum */
+#define          MC_CMD_AN_COMPLETE  0x14 /* enum */
+#define          MC_CMD_AN_10GBT_STATUS  0x15 /* enum */
+#define          MC_CMD_CL22_LINK_UP  0x16 /* enum */
+#define          MC_CMD_PHY_NSTATS  0x17 /* enum */
+
+
+/***********************************/
+/* MC_CMD_MAC_STATS
+ * Get generic MAC statistics.
  */
-#define MC_CMD_SFT9001_SET 0x31
-#define MC_CMD_SFT9001_SET_IN_LEN 4
-#define MC_CMD_SFT9001_SET_IN_FLAGS_OFST 0
-#define MC_CMD_SFT9001_SET_OUT_LEN 0
-
+#define MC_CMD_MAC_STATS 0x2e
 
-/* MC_CMD_WOL_FILTER_SET:
- * Set a WoL filter
- *
- * Locks required: None
- * Returns: 0, EBUSY, EINVAL, ENOSYS
+/* MC_CMD_MAC_STATS_IN msgrequest */
+#define    MC_CMD_MAC_STATS_IN_LEN 16
+#define       MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0
+#define       MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8
+#define       MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0
+#define       MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4
+#define       MC_CMD_MAC_STATS_IN_CMD_OFST 8
+#define        MC_CMD_MAC_STATS_IN_DMA_LBN 0
+#define        MC_CMD_MAC_STATS_IN_DMA_WIDTH 1
+#define        MC_CMD_MAC_STATS_IN_CLEAR_LBN 1
+#define        MC_CMD_MAC_STATS_IN_CLEAR_WIDTH 1
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_LBN 2
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_WIDTH 1
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_LBN 3
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_WIDTH 1
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_LBN 4
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_WIDTH 1
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_LBN 5
+#define        MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_WIDTH 1
+#define        MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16
+#define        MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16
+#define       MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12
+
+/* MC_CMD_MAC_STATS_OUT_DMA msgresponse */
+#define    MC_CMD_MAC_STATS_OUT_DMA_LEN 0
+
+/* MC_CMD_MAC_STATS_OUT_NO_DMA msgresponse */
+#define    MC_CMD_MAC_STATS_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS*64))>>3)
+#define       MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_OFST 0
+#define       MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LEN 8
+#define       MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LO_OFST 0
+#define       MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4
+#define       MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS
+#define          MC_CMD_MAC_GENERATION_START  0x0 /* enum */
+#define          MC_CMD_MAC_TX_PKTS  0x1 /* enum */
+#define          MC_CMD_MAC_TX_PAUSE_PKTS  0x2 /* enum */
+#define          MC_CMD_MAC_TX_CONTROL_PKTS  0x3 /* enum */
+#define          MC_CMD_MAC_TX_UNICAST_PKTS  0x4 /* enum */
+#define          MC_CMD_MAC_TX_MULTICAST_PKTS  0x5 /* enum */
+#define          MC_CMD_MAC_TX_BROADCAST_PKTS  0x6 /* enum */
+#define          MC_CMD_MAC_TX_BYTES  0x7 /* enum */
+#define          MC_CMD_MAC_TX_BAD_BYTES  0x8 /* enum */
+#define          MC_CMD_MAC_TX_LT64_PKTS  0x9 /* enum */
+#define          MC_CMD_MAC_TX_64_PKTS  0xa /* enum */
+#define          MC_CMD_MAC_TX_65_TO_127_PKTS  0xb /* enum */
+#define          MC_CMD_MAC_TX_128_TO_255_PKTS  0xc /* enum */
+#define          MC_CMD_MAC_TX_256_TO_511_PKTS  0xd /* enum */
+#define          MC_CMD_MAC_TX_512_TO_1023_PKTS  0xe /* enum */
+#define          MC_CMD_MAC_TX_1024_TO_15XX_PKTS  0xf /* enum */
+#define          MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS  0x10 /* enum */
+#define          MC_CMD_MAC_TX_GTJUMBO_PKTS  0x11 /* enum */
+#define          MC_CMD_MAC_TX_BAD_FCS_PKTS  0x12 /* enum */
+#define          MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS  0x13 /* enum */
+#define          MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS  0x14 /* enum */
+#define          MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS  0x15 /* enum */
+#define          MC_CMD_MAC_TX_LATE_COLLISION_PKTS  0x16 /* enum */
+#define          MC_CMD_MAC_TX_DEFERRED_PKTS  0x17 /* enum */
+#define          MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS  0x18 /* enum */
+#define          MC_CMD_MAC_TX_NON_TCPUDP_PKTS  0x19 /* enum */
+#define          MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS  0x1a /* enum */
+#define          MC_CMD_MAC_TX_IP_SRC_ERR_PKTS  0x1b /* enum */
+#define          MC_CMD_MAC_RX_PKTS  0x1c /* enum */
+#define          MC_CMD_MAC_RX_PAUSE_PKTS  0x1d /* enum */
+#define          MC_CMD_MAC_RX_GOOD_PKTS  0x1e /* enum */
+#define          MC_CMD_MAC_RX_CONTROL_PKTS  0x1f /* enum */
+#define          MC_CMD_MAC_RX_UNICAST_PKTS  0x20 /* enum */
+#define          MC_CMD_MAC_RX_MULTICAST_PKTS  0x21 /* enum */
+#define          MC_CMD_MAC_RX_BROADCAST_PKTS  0x22 /* enum */
+#define          MC_CMD_MAC_RX_BYTES  0x23 /* enum */
+#define          MC_CMD_MAC_RX_BAD_BYTES  0x24 /* enum */
+#define          MC_CMD_MAC_RX_64_PKTS  0x25 /* enum */
+#define          MC_CMD_MAC_RX_65_TO_127_PKTS  0x26 /* enum */
+#define          MC_CMD_MAC_RX_128_TO_255_PKTS  0x27 /* enum */
+#define          MC_CMD_MAC_RX_256_TO_511_PKTS  0x28 /* enum */
+#define          MC_CMD_MAC_RX_512_TO_1023_PKTS  0x29 /* enum */
+#define          MC_CMD_MAC_RX_1024_TO_15XX_PKTS  0x2a /* enum */
+#define          MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS  0x2b /* enum */
+#define          MC_CMD_MAC_RX_GTJUMBO_PKTS  0x2c /* enum */
+#define          MC_CMD_MAC_RX_UNDERSIZE_PKTS  0x2d /* enum */
+#define          MC_CMD_MAC_RX_BAD_FCS_PKTS  0x2e /* enum */
+#define          MC_CMD_MAC_RX_OVERFLOW_PKTS  0x2f /* enum */
+#define          MC_CMD_MAC_RX_FALSE_CARRIER_PKTS  0x30 /* enum */
+#define          MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS  0x31 /* enum */
+#define          MC_CMD_MAC_RX_ALIGN_ERROR_PKTS  0x32 /* enum */
+#define          MC_CMD_MAC_RX_LENGTH_ERROR_PKTS  0x33 /* enum */
+#define          MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS  0x34 /* enum */
+#define          MC_CMD_MAC_RX_JABBER_PKTS  0x35 /* enum */
+#define          MC_CMD_MAC_RX_NODESC_DROPS  0x36 /* enum */
+#define          MC_CMD_MAC_RX_LANES01_CHAR_ERR  0x37 /* enum */
+#define          MC_CMD_MAC_RX_LANES23_CHAR_ERR  0x38 /* enum */
+#define          MC_CMD_MAC_RX_LANES01_DISP_ERR  0x39 /* enum */
+#define          MC_CMD_MAC_RX_LANES23_DISP_ERR  0x3a /* enum */
+#define          MC_CMD_MAC_RX_MATCH_FAULT  0x3b /* enum */
+#define          MC_CMD_GMAC_DMABUF_START  0x40 /* enum */
+#define          MC_CMD_GMAC_DMABUF_END    0x5f /* enum */
+#define          MC_CMD_MAC_GENERATION_END 0x60 /* enum */
+#define          MC_CMD_MAC_NSTATS  0x61 /* enum */
+
+
+/***********************************/
+/* MC_CMD_SRIOV
+ * to be documented
+ */
+#define MC_CMD_SRIOV 0x30
+
+/* MC_CMD_SRIOV_IN msgrequest */
+#define    MC_CMD_SRIOV_IN_LEN 12
+#define       MC_CMD_SRIOV_IN_ENABLE_OFST 0
+#define       MC_CMD_SRIOV_IN_VI_BASE_OFST 4
+#define       MC_CMD_SRIOV_IN_VF_COUNT_OFST 8
+
+/* MC_CMD_SRIOV_OUT msgresponse */
+#define    MC_CMD_SRIOV_OUT_LEN 8
+#define       MC_CMD_SRIOV_OUT_VI_SCALE_OFST 0
+#define       MC_CMD_SRIOV_OUT_VF_TOTAL_OFST 4
+
+/* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */
+#define    MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_OFST 4
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_LBN 32
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_WIDTH 32
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_OFST 8
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LEN 8
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO_OFST 8
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_HI_OFST 12
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LBN 64
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_WIDTH 64
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_OFST 16
+#define          MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE 0x100 /* enum */
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_LBN 128
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_WIDTH 32
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_OFST 20
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LEN 8
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LO_OFST 20
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_HI_OFST 24
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LBN 160
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_WIDTH 64
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_OFST 28
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_LBN 224
+#define       MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_WIDTH 32
+
+
+/***********************************/
+/* MC_CMD_MEMCPY
+ * Perform memory copy operation.
+ */
+#define MC_CMD_MEMCPY 0x31
+
+/* MC_CMD_MEMCPY_IN msgrequest */
+#define    MC_CMD_MEMCPY_IN_LENMIN 32
+#define    MC_CMD_MEMCPY_IN_LENMAX 224
+#define    MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num))
+#define       MC_CMD_MEMCPY_IN_RECORD_OFST 0
+#define       MC_CMD_MEMCPY_IN_RECORD_LEN 32
+#define       MC_CMD_MEMCPY_IN_RECORD_MINNUM 1
+#define       MC_CMD_MEMCPY_IN_RECORD_MAXNUM 7
+
+/* MC_CMD_MEMCPY_OUT msgresponse */
+#define    MC_CMD_MEMCPY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_WOL_FILTER_SET
+ * Set a WoL filter.
  */
 #define MC_CMD_WOL_FILTER_SET 0x32
-#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 /* 190 rounded up to a word */
-#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0
-#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4
-
-/* There is a union at offset 8, following defines overlap due to
- * this */
-#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8
-
-#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST		\
-	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
-
-#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST   \
-	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
-#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST   \
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 4)
-#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST \
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 8)
-#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST \
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 10)
-
-#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST   \
-	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
-#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST   \
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 16)
-#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST \
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 32)
-#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST \
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 34)
-
-#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST	\
-	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
-#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_OFST		\
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 48)
-#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST	\
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 176)
-#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST	\
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 177)
-#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST	\
-	(MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 178)
-
-#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST	\
-	MC_CMD_WOL_FILTER_SET_IN_DATA_OFST
-#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN	0
-#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH	1
-#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN	1
-#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1
-
-#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4
-#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0
-
-/* WOL Filter types enumeration */
-#define MC_CMD_WOL_TYPE_MAGIC      0x0
-			 /* unused 0x1 */
-#define MC_CMD_WOL_TYPE_WIN_MAGIC  0x2
-#define MC_CMD_WOL_TYPE_IPV4_SYN   0x3
-#define MC_CMD_WOL_TYPE_IPV6_SYN   0x4
-#define MC_CMD_WOL_TYPE_BITMAP     0x5
-#define MC_CMD_WOL_TYPE_LINK       0x6
-#define MC_CMD_WOL_TYPE_MAX        0x7
-
-#define MC_CMD_FILTER_MODE_SIMPLE     0x0
-#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff
-
-/* MC_CMD_WOL_FILTER_REMOVE:
- * Remove a WoL filter
- *
- * Locks required: None
- * Returns: 0, EINVAL, ENOSYS
+
+/* MC_CMD_WOL_FILTER_SET_IN msgrequest */
+#define    MC_CMD_WOL_FILTER_SET_IN_LEN 192
+#define       MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0
+#define          MC_CMD_FILTER_MODE_SIMPLE    0x0 /* enum */
+#define          MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */
+#define       MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4
+#define          MC_CMD_WOL_TYPE_MAGIC      0x0 /* enum */
+#define          MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 /* enum */
+#define          MC_CMD_WOL_TYPE_IPV4_SYN   0x3 /* enum */
+#define          MC_CMD_WOL_TYPE_IPV6_SYN   0x4 /* enum */
+#define          MC_CMD_WOL_TYPE_BITMAP     0x5 /* enum */
+#define          MC_CMD_WOL_TYPE_LINK       0x6 /* enum */
+#define          MC_CMD_WOL_TYPE_MAX        0x7 /* enum */
+#define       MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8
+#define       MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4
+#define       MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46
+
+/* MC_CMD_WOL_FILTER_SET_IN_MAGIC msgrequest */
+#define    MC_CMD_WOL_FILTER_SET_IN_MAGIC_LEN 16
+/*            MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */
+/*            MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */
+#define       MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST 8
+#define       MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LEN 8
+#define       MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LO_OFST 8
+#define       MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_HI_OFST 12
+
+/* MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN msgrequest */
+#define    MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_LEN 20
+/*            MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */
+/*            MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST 8
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST 12
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST 16
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_LEN 2
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST 18
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_LEN 2
+
+/* MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN msgrequest */
+#define    MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_LEN 44
+/*            MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */
+/*            MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST 8
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_LEN 16
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST 24
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_LEN 16
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST 40
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_LEN 2
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST 42
+#define       MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_LEN 2
+
+/* MC_CMD_WOL_FILTER_SET_IN_BITMAP msgrequest */
+#define    MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN 187
+/*            MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */
+/*            MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST 8
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_LEN 48
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_OFST 56
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_LEN 128
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST 184
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_LEN 1
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST 185
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_LEN 1
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST 186
+#define       MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_LEN 1
+
+/* MC_CMD_WOL_FILTER_SET_IN_LINK msgrequest */
+#define    MC_CMD_WOL_FILTER_SET_IN_LINK_LEN 12
+/*            MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */
+/*            MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */
+#define       MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST 8
+#define        MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0
+#define        MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1
+#define        MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1
+#define        MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1
+
+/* MC_CMD_WOL_FILTER_SET_OUT msgresponse */
+#define    MC_CMD_WOL_FILTER_SET_OUT_LEN 4
+#define       MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0
+
+
+/***********************************/
+/* MC_CMD_WOL_FILTER_REMOVE
+ * Remove a WoL filter.
  */
 #define MC_CMD_WOL_FILTER_REMOVE 0x33
-#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4
-#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0
-#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0
 
+/* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */
+#define    MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4
+#define       MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0
 
-/* MC_CMD_WOL_FILTER_RESET:
- * Reset (i.e. remove all) WoL filters
- *
- * Locks required: None
- * Returns: 0, ENOSYS
+/* MC_CMD_WOL_FILTER_REMOVE_OUT msgresponse */
+#define    MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_WOL_FILTER_RESET
+ * Reset (i.e. remove all) WoL filters.
  */
 #define MC_CMD_WOL_FILTER_RESET 0x34
-#define MC_CMD_WOL_FILTER_RESET_IN_LEN 0
-#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0
 
-/* MC_CMD_SET_MCAST_HASH:
- * Set the MCASH hash value without otherwise
- * reconfiguring the MAC
+/* MC_CMD_WOL_FILTER_RESET_IN msgrequest */
+#define    MC_CMD_WOL_FILTER_RESET_IN_LEN 4
+#define       MC_CMD_WOL_FILTER_RESET_IN_MASK_OFST 0
+#define          MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS 0x1 /* enum */
+#define          MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS 0x2 /* enum */
+
+/* MC_CMD_WOL_FILTER_RESET_OUT msgresponse */
+#define    MC_CMD_WOL_FILTER_RESET_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SET_MCAST_HASH
+ * Set the MCASH hash value.
  */
 #define MC_CMD_SET_MCAST_HASH 0x35
-#define MC_CMD_SET_MCAST_HASH_IN_LEN 32
-#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0
-#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16
-#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0
 
-/* MC_CMD_NVRAM_TYPES:
- * Return bitfield indicating available types of virtual NVRAM partitions
- *
- * Locks required: none
- * Returns: 0
+/* MC_CMD_SET_MCAST_HASH_IN msgrequest */
+#define    MC_CMD_SET_MCAST_HASH_IN_LEN 32
+#define       MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0
+#define       MC_CMD_SET_MCAST_HASH_IN_HASH0_LEN 16
+#define       MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16
+#define       MC_CMD_SET_MCAST_HASH_IN_HASH1_LEN 16
+
+/* MC_CMD_SET_MCAST_HASH_OUT msgresponse */
+#define    MC_CMD_SET_MCAST_HASH_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_NVRAM_TYPES
+ * Get virtual NVRAM partitions information.
  */
 #define MC_CMD_NVRAM_TYPES 0x36
-#define MC_CMD_NVRAM_TYPES_IN_LEN 0
-#define MC_CMD_NVRAM_TYPES_OUT_LEN 4
-#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0
-
-/* Supported NVRAM types */
-#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0
-#define MC_CMD_NVRAM_TYPE_MC_FW 1
-#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 2
-#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 3
-#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 4
-#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 5
-#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 6
-#define MC_CMD_NVRAM_TYPE_EXP_ROM 7
-#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 8
-#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 9
-#define MC_CMD_NVRAM_TYPE_PHY_PORT0 10
-#define MC_CMD_NVRAM_TYPE_PHY_PORT1 11
-#define MC_CMD_NVRAM_TYPE_LOG 12
-
-/* MC_CMD_NVRAM_INFO:
- * Read info about a virtual NVRAM partition
- *
- * Locks required: none
- * Returns: 0, EINVAL (bad type)
+
+/* MC_CMD_NVRAM_TYPES_IN msgrequest */
+#define    MC_CMD_NVRAM_TYPES_IN_LEN 0
+
+/* MC_CMD_NVRAM_TYPES_OUT msgresponse */
+#define    MC_CMD_NVRAM_TYPES_OUT_LEN 4
+#define       MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0
+#define          MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum */
+#define          MC_CMD_NVRAM_TYPE_MC_FW 0x1 /* enum */
+#define          MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2 /* enum */
+#define          MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3 /* enum */
+#define          MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4 /* enum */
+#define          MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5 /* enum */
+#define          MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6 /* enum */
+#define          MC_CMD_NVRAM_TYPE_EXP_ROM 0x7 /* enum */
+#define          MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8 /* enum */
+#define          MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9 /* enum */
+#define          MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa /* enum */
+#define          MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb /* enum */
+#define          MC_CMD_NVRAM_TYPE_LOG 0xc /* enum */
+#define          MC_CMD_NVRAM_TYPE_FPGA 0xd /* enum */
+
+
+/***********************************/
+/* MC_CMD_NVRAM_INFO
+ * Read info about a virtual NVRAM partition.
  */
 #define MC_CMD_NVRAM_INFO 0x37
-#define MC_CMD_NVRAM_INFO_IN_LEN 4
-#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_INFO_OUT_LEN 24
-#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0
-#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4
-#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8
-#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12
-#define   MC_CMD_NVRAM_PROTECTED_LBN 0
-#define   MC_CMD_NVRAM_PROTECTED_WIDTH 1
-#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16
-#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20
-
-/* MC_CMD_NVRAM_UPDATE_START:
- * Start a group of update operations on a virtual NVRAM partition
- *
- * Locks required: PHY_LOCK if type==*PHY*
- * Returns: 0, EINVAL (bad type), EACCES (if PHY_LOCK required and not held)
+
+/* MC_CMD_NVRAM_INFO_IN msgrequest */
+#define    MC_CMD_NVRAM_INFO_IN_LEN 4
+#define       MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+
+/* MC_CMD_NVRAM_INFO_OUT msgresponse */
+#define    MC_CMD_NVRAM_INFO_OUT_LEN 24
+#define       MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+#define       MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4
+#define       MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8
+#define       MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12
+#define        MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0
+#define        MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1
+#define       MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16
+#define       MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20
+
+
+/***********************************/
+/* MC_CMD_NVRAM_UPDATE_START
+ * Start a group of update operations on a virtual NVRAM partition.
  */
 #define MC_CMD_NVRAM_UPDATE_START 0x38
-#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4
-#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0
 
-/* MC_CMD_NVRAM_READ:
- * Read data from a virtual NVRAM partition
- *
- * Locks required: PHY_LOCK if type==*PHY*
- * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+/* MC_CMD_NVRAM_UPDATE_START_IN msgrequest */
+#define    MC_CMD_NVRAM_UPDATE_START_IN_LEN 4
+#define       MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+
+/* MC_CMD_NVRAM_UPDATE_START_OUT msgresponse */
+#define    MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_NVRAM_READ
+ * Read data from a virtual NVRAM partition.
  */
 #define MC_CMD_NVRAM_READ 0x39
-#define MC_CMD_NVRAM_READ_IN_LEN 12
-#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4
-#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8
-#define MC_CMD_NVRAM_READ_OUT_LEN(_read_bytes) (_read_bytes)
-#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0
-
-/* MC_CMD_NVRAM_WRITE:
- * Write data to a virtual NVRAM partition
- *
- * Locks required: PHY_LOCK if type==*PHY*
- * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+
+/* MC_CMD_NVRAM_READ_IN msgrequest */
+#define    MC_CMD_NVRAM_READ_IN_LEN 12
+#define       MC_CMD_NVRAM_READ_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+#define       MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4
+#define       MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8
+
+/* MC_CMD_NVRAM_READ_OUT msgresponse */
+#define    MC_CMD_NVRAM_READ_OUT_LENMIN 1
+#define    MC_CMD_NVRAM_READ_OUT_LENMAX 255
+#define    MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num))
+#define       MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0
+#define       MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1
+#define       MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1
+#define       MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 255
+
+
+/***********************************/
+/* MC_CMD_NVRAM_WRITE
+ * Write data to a virtual NVRAM partition.
  */
 #define MC_CMD_NVRAM_WRITE 0x3a
-#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4
-#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8
-#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12
-#define MC_CMD_NVRAM_WRITE_IN_LEN(_write_bytes) (12 + _write_bytes)
-#define MC_CMD_NVRAM_WRITE_OUT_LEN 0
-
-/* MC_CMD_NVRAM_ERASE:
- * Erase sector(s) from a virtual NVRAM partition
- *
- * Locks required: PHY_LOCK if type==*PHY*
- * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+
+/* MC_CMD_NVRAM_WRITE_IN msgrequest */
+#define    MC_CMD_NVRAM_WRITE_IN_LENMIN 13
+#define    MC_CMD_NVRAM_WRITE_IN_LENMAX 255
+#define    MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num))
+#define       MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+#define       MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4
+#define       MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8
+#define       MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12
+#define       MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1
+#define       MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1
+#define       MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 243
+
+/* MC_CMD_NVRAM_WRITE_OUT msgresponse */
+#define    MC_CMD_NVRAM_WRITE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_NVRAM_ERASE
+ * Erase sector(s) from a virtual NVRAM partition.
  */
 #define MC_CMD_NVRAM_ERASE 0x3b
-#define MC_CMD_NVRAM_ERASE_IN_LEN 12
-#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4
-#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8
-#define MC_CMD_NVRAM_ERASE_OUT_LEN 0
-
-/* MC_CMD_NVRAM_UPDATE_FINISH:
- * Finish a group of update operations on a virtual NVRAM partition
- *
- * Locks required: PHY_LOCK if type==*PHY*
- * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held)
+
+/* MC_CMD_NVRAM_ERASE_IN msgrequest */
+#define    MC_CMD_NVRAM_ERASE_IN_LEN 12
+#define       MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+#define       MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4
+#define       MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8
+
+/* MC_CMD_NVRAM_ERASE_OUT msgresponse */
+#define    MC_CMD_NVRAM_ERASE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_NVRAM_UPDATE_FINISH
+ * Finish a group of update operations on a virtual NVRAM partition.
  */
 #define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
-#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8
-#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4
-#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0
 
-/* MC_CMD_REBOOT:
+/* MC_CMD_NVRAM_UPDATE_FINISH_IN msgrequest */
+#define    MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8
+#define       MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+#define       MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4
+
+/* MC_CMD_NVRAM_UPDATE_FINISH_OUT msgresponse */
+#define    MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_REBOOT
  * Reboot the MC.
- *
- * The AFTER_ASSERTION flag is intended to be used when the driver notices
- * an assertion failure (at which point it is expected to perform a complete
- * tear down and reinitialise), to allow both ports to reset the MC once
- * in an atomic fashion.
- *
- * Production mc firmwares are generally compiled with REBOOT_ON_ASSERT=1,
- * which means that they will automatically reboot out of the assertion
- * handler, so this is in practise an optional operation. It is still
- * recommended that drivers execute this to support custom firmwares
- * with REBOOT_ON_ASSERT=0.
- *
- * Locks required: NONE
- * Returns: Nothing. You get back a response with ERR=1, DATALEN=0
  */
 #define MC_CMD_REBOOT 0x3d
-#define MC_CMD_REBOOT_IN_LEN 4
-#define MC_CMD_REBOOT_IN_FLAGS_OFST 0
-#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 1
-#define MC_CMD_REBOOT_OUT_LEN 0
 
-/* MC_CMD_SCHEDINFO:
- * Request scheduler info. from the MC.
- *
- * Locks required: NONE
- * Returns: An array of (timeslice,maximum overrun), one for each thread,
- * in ascending order of thread address.s
+/* MC_CMD_REBOOT_IN msgrequest */
+#define    MC_CMD_REBOOT_IN_LEN 4
+#define       MC_CMD_REBOOT_IN_FLAGS_OFST 0
+#define          MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 0x1 /* enum */
+
+/* MC_CMD_REBOOT_OUT msgresponse */
+#define    MC_CMD_REBOOT_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SCHEDINFO
+ * Request scheduler info.
  */
 #define MC_CMD_SCHEDINFO 0x3e
-#define MC_CMD_SCHEDINFO_IN_LEN 0
 
+/* MC_CMD_SCHEDINFO_IN msgrequest */
+#define    MC_CMD_SCHEDINFO_IN_LEN 0
 
-/* MC_CMD_SET_REBOOT_MODE: (debug)
- * Set the mode for the next MC reboot.
- *
- * Locks required: NONE
- *
- * Sets the reboot mode to the specified value.  Returns the old mode.
+/* MC_CMD_SCHEDINFO_OUT msgresponse */
+#define    MC_CMD_SCHEDINFO_OUT_LENMIN 4
+#define    MC_CMD_SCHEDINFO_OUT_LENMAX 252
+#define    MC_CMD_SCHEDINFO_OUT_LEN(num) (0+4*(num))
+#define       MC_CMD_SCHEDINFO_OUT_DATA_OFST 0
+#define       MC_CMD_SCHEDINFO_OUT_DATA_LEN 4
+#define       MC_CMD_SCHEDINFO_OUT_DATA_MINNUM 1
+#define       MC_CMD_SCHEDINFO_OUT_DATA_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_REBOOT_MODE
  */
 #define MC_CMD_REBOOT_MODE 0x3f
-#define MC_CMD_REBOOT_MODE_IN_LEN 4
-#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0
-#define MC_CMD_REBOOT_MODE_OUT_LEN 4
-#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0
-#define   MC_CMD_REBOOT_MODE_NORMAL 0
-#define   MC_CMD_REBOOT_MODE_SNAPPER 3
-
-/* MC_CMD_DEBUG_LOG:
- * Null request/response command (debug)
- * - sequence number is always zero
- * - only supported on the UART interface
- * (the same set of bytes is delivered as an
- * event over PCI)
- */
-#define MC_CMD_DEBUG_LOG 0x40
-#define MC_CMD_DEBUG_LOG_IN_LEN 0
-#define MC_CMD_DEBUG_LOG_OUT_LEN 0
-
-/* Generic sensor enumeration. Note that a dual port NIC
- * will EITHER expose PHY_COMMON_TEMP OR PHY0_TEMP and
- * PHY1_TEMP depending on whether there is a single sensor
- * in the vicinity of the two port, or one per port.
- */
-#define MC_CMD_SENSOR_CONTROLLER_TEMP 0		/* degC */
-#define MC_CMD_SENSOR_PHY_COMMON_TEMP 1		/* degC */
-#define MC_CMD_SENSOR_CONTROLLER_COOLING 2	/* bool */
-#define MC_CMD_SENSOR_PHY0_TEMP 3		/* degC */
-#define MC_CMD_SENSOR_PHY0_COOLING 4		/* bool */
-#define MC_CMD_SENSOR_PHY1_TEMP 5		/* degC */
-#define MC_CMD_SENSOR_PHY1_COOLING 6		/* bool */
-#define MC_CMD_SENSOR_IN_1V0 7			/* mV */
-#define MC_CMD_SENSOR_IN_1V2 8			/* mV */
-#define MC_CMD_SENSOR_IN_1V8 9			/* mV */
-#define MC_CMD_SENSOR_IN_2V5 10			/* mV */
-#define MC_CMD_SENSOR_IN_3V3 11			/* mV */
-#define MC_CMD_SENSOR_IN_12V0 12		/* mV */
-
-
-/* Sensor state */
-#define MC_CMD_SENSOR_STATE_OK 0
-#define MC_CMD_SENSOR_STATE_WARNING 1
-#define MC_CMD_SENSOR_STATE_FATAL 2
-#define MC_CMD_SENSOR_STATE_BROKEN 3
-
-/* MC_CMD_SENSOR_INFO:
+
+/* MC_CMD_REBOOT_MODE_IN msgrequest */
+#define    MC_CMD_REBOOT_MODE_IN_LEN 4
+#define       MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0
+#define          MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum */
+#define          MC_CMD_REBOOT_MODE_SNAPPER 0x3 /* enum */
+
+/* MC_CMD_REBOOT_MODE_OUT msgresponse */
+#define    MC_CMD_REBOOT_MODE_OUT_LEN 4
+#define       MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0
+
+
+/***********************************/
+/* MC_CMD_SENSOR_INFO
  * Returns information about every available sensor.
- *
- * Each sensor has a single (16bit) value, and a corresponding state.
- * The mapping between value and sensor is nominally determined by the
- * MC, but in practise is implemented as zero (BROKEN), one (TEMPERATURE),
- * or two (VOLTAGE) ranges per sensor per state.
- *
- * This call returns a mask (32bit) of the sensors that are supported
- * by this platform, then an array (indexed by MC_CMD_SENSOR) of byte
- * offsets to the per-sensor arrays. Each sensor array has four 16bit
- * numbers, min1, max1, min2, max2.
- *
- * Locks required: None
- * Returns: 0
  */
 #define MC_CMD_SENSOR_INFO 0x41
-#define MC_CMD_SENSOR_INFO_IN_LEN 0
-#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
-#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \
-	(4 + (_x))
-#define MC_CMD_SENSOR_INFO_OUT_MIN1_OFST(_ofst) \
-	((_ofst) + 0)
-#define MC_CMD_SENSOR_INFO_OUT_MAX1_OFST(_ofst) \
-	((_ofst) + 2)
-#define MC_CMD_SENSOR_INFO_OUT_MIN2_OFST(_ofst) \
-	((_ofst) + 4)
-#define MC_CMD_SENSOR_INFO_OUT_MAX2_OFST(_ofst) \
-	((_ofst) + 6)
 
+/* MC_CMD_SENSOR_INFO_IN msgrequest */
+#define    MC_CMD_SENSOR_INFO_IN_LEN 0
+
+/* MC_CMD_SENSOR_INFO_OUT msgresponse */
+#define    MC_CMD_SENSOR_INFO_OUT_LENMIN 12
+#define    MC_CMD_SENSOR_INFO_OUT_LENMAX 252
+#define    MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num))
+#define       MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
+#define          MC_CMD_SENSOR_CONTROLLER_TEMP  0x0 /* enum */
+#define          MC_CMD_SENSOR_PHY_COMMON_TEMP  0x1 /* enum */
+#define          MC_CMD_SENSOR_CONTROLLER_COOLING  0x2 /* enum */
+#define          MC_CMD_SENSOR_PHY0_TEMP  0x3 /* enum */
+#define          MC_CMD_SENSOR_PHY0_COOLING  0x4 /* enum */
+#define          MC_CMD_SENSOR_PHY1_TEMP  0x5 /* enum */
+#define          MC_CMD_SENSOR_PHY1_COOLING  0x6 /* enum */
+#define          MC_CMD_SENSOR_IN_1V0  0x7 /* enum */
+#define          MC_CMD_SENSOR_IN_1V2  0x8 /* enum */
+#define          MC_CMD_SENSOR_IN_1V8  0x9 /* enum */
+#define          MC_CMD_SENSOR_IN_2V5  0xa /* enum */
+#define          MC_CMD_SENSOR_IN_3V3  0xb /* enum */
+#define          MC_CMD_SENSOR_IN_12V0  0xc /* enum */
+#define          MC_CMD_SENSOR_IN_1V2A  0xd /* enum */
+#define          MC_CMD_SENSOR_IN_VREF  0xe /* enum */
+#define       MC_CMD_SENSOR_ENTRY_OFST 4
+#define       MC_CMD_SENSOR_ENTRY_LEN 8
+#define       MC_CMD_SENSOR_ENTRY_LO_OFST 4
+#define       MC_CMD_SENSOR_ENTRY_HI_OFST 8
+#define       MC_CMD_SENSOR_ENTRY_MINNUM 1
+#define       MC_CMD_SENSOR_ENTRY_MAXNUM 31
+
+/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */
+#define    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_OFST 0
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LEN 2
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LBN 0
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_WIDTH 16
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_OFST 2
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LEN 2
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LBN 16
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_WIDTH 16
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_OFST 4
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LEN 2
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LBN 32
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_WIDTH 16
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_OFST 6
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LEN 2
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LBN 48
+#define       MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_WIDTH 16
+
+
+/***********************************/
 /* MC_CMD_READ_SENSORS
- * Returns the current reading from each sensor
- *
- * Returns a sparse array of sensor readings (indexed by the sensor
- * type) into host memory.  Each array element is a dword.
- *
- * The MC will send a SENSOREVT event every time any sensor changes state. The
- * driver is responsible for ensuring that it doesn't miss any events. The board
- * will function normally if all sensors are in STATE_OK or state_WARNING.
- * Otherwise the board should not be expected to function.
+ * Returns the current reading from each sensor.
  */
 #define MC_CMD_READ_SENSORS 0x42
-#define MC_CMD_READ_SENSORS_IN_LEN 8
-#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0
-#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4
-#define MC_CMD_READ_SENSORS_OUT_LEN 0
 
-/* Sensor reading fields */
-#define MC_CMD_READ_SENSOR_VALUE_LBN 0
-#define MC_CMD_READ_SENSOR_VALUE_WIDTH 16
-#define MC_CMD_READ_SENSOR_STATE_LBN 16
-#define MC_CMD_READ_SENSOR_STATE_WIDTH 8
-
-
-/* MC_CMD_GET_PHY_STATE:
- * Report current state of PHY.  A "zombie" PHY is a PHY that has failed to
- * boot (e.g. due to missing or corrupted firmware).
- *
- * Locks required: None
- * Return code: 0
+/* MC_CMD_READ_SENSORS_IN msgrequest */
+#define    MC_CMD_READ_SENSORS_IN_LEN 8
+#define       MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0
+#define       MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8
+#define       MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0
+#define       MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4
+
+/* MC_CMD_READ_SENSORS_OUT msgresponse */
+#define    MC_CMD_READ_SENSORS_OUT_LEN 0
+
+/* MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF structuredef */
+#define    MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 3
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_OFST 0
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LEN 2
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LBN 0
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_WIDTH 16
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1
+#define          MC_CMD_SENSOR_STATE_OK  0x0 /* enum */
+#define          MC_CMD_SENSOR_STATE_WARNING  0x1 /* enum */
+#define          MC_CMD_SENSOR_STATE_FATAL  0x2 /* enum */
+#define          MC_CMD_SENSOR_STATE_BROKEN  0x3 /* enum */
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16
+#define       MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8
+
+
+/***********************************/
+/* MC_CMD_GET_PHY_STATE
+ * Report current state of PHY.
  */
 #define MC_CMD_GET_PHY_STATE 0x43
 
-#define MC_CMD_GET_PHY_STATE_IN_LEN 0
-#define MC_CMD_GET_PHY_STATE_OUT_LEN 4
-#define MC_CMD_GET_PHY_STATE_STATE_OFST 0
-/* PHY state enumeration: */
-#define MC_CMD_PHY_STATE_OK 1
-#define MC_CMD_PHY_STATE_ZOMBIE 2
+/* MC_CMD_GET_PHY_STATE_IN msgrequest */
+#define    MC_CMD_GET_PHY_STATE_IN_LEN 0
 
+/* MC_CMD_GET_PHY_STATE_OUT msgresponse */
+#define    MC_CMD_GET_PHY_STATE_OUT_LEN 4
+#define       MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0
+#define          MC_CMD_PHY_STATE_OK 0x1 /* enum */
+#define          MC_CMD_PHY_STATE_ZOMBIE 0x2 /* enum */
 
-/* 802.1Qbb control. 8 Tx queues that map to priorities 0 - 7. Use all 1s to
- * disable 802.Qbb for a given priority. */
+
+/***********************************/
+/* MC_CMD_SETUP_8021QBB
+ * 802.1Qbb control.
+ */
 #define MC_CMD_SETUP_8021QBB 0x44
-#define MC_CMD_SETUP_8021QBB_IN_LEN 32
-#define MC_CMD_SETUP_8021QBB_OUT_LEN 0
-#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFFST 0
 
+/* MC_CMD_SETUP_8021QBB_IN msgrequest */
+#define    MC_CMD_SETUP_8021QBB_IN_LEN 32
+#define       MC_CMD_SETUP_8021QBB_IN_TXQS_OFST 0
+#define       MC_CMD_SETUP_8021QBB_IN_TXQS_LEN 32
 
-/* MC_CMD_WOL_FILTER_GET:
- * Retrieve ID of any WoL filters
- *
- * Locks required: None
- * Returns: 0, ENOSYS
- */
-#define MC_CMD_WOL_FILTER_GET 0x45
-#define MC_CMD_WOL_FILTER_GET_IN_LEN 0
-#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4
-#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0
+/* MC_CMD_SETUP_8021QBB_OUT msgresponse */
+#define    MC_CMD_SETUP_8021QBB_OUT_LEN 0
 
 
-/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD:
- * Offload a protocol to NIC for lights-out state
- *
- * Locks required: None
- * Returns: 0, ENOSYS
+/***********************************/
+/* MC_CMD_WOL_FILTER_GET
+ * Retrieve ID of any WoL filters.
  */
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+#define MC_CMD_WOL_FILTER_GET 0x45
 
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN 16
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
+/* MC_CMD_WOL_FILTER_GET_IN msgrequest */
+#define    MC_CMD_WOL_FILTER_GET_IN_LEN 0
 
-/* There is a union at offset 4, following defines overlap due to
- * this */
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPMAC_OFST 4
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPIP_OFST 10
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSMAC_OFST 4
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSSNIPV6_OFST 10
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSIPV6_OFST 26
+/* MC_CMD_WOL_FILTER_GET_OUT msgresponse */
+#define    MC_CMD_WOL_FILTER_GET_OUT_LEN 4
+#define       MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0
 
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0
 
+/***********************************/
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD
+ * Add a protocol offload to NIC for lights-out state.
+ */
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
 
-/* MC_CMD_REMOVE_LIGHTSOUT_PROTOCOL_OFFLOAD:
- * Offload a protocol to NIC for lights-out state
- *
- * Locks required: None
- * Returns: 0, ENOSYS
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */
+#define    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8
+#define    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX 252
+#define    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN(num) (4+4*(num))
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
+#define          MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */
+#define          MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS  0x2 /* enum */
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MAXNUM 62
+
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP msgrequest */
+#define    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN 14
+/*            MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_OFST 4
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_LEN 6
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP_OFST 10
+
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS msgrequest */
+#define    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN 42
+/*            MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_OFST 4
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_LEN 6
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_OFST 10
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_LEN 16
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_OFST 26
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_LEN 16
+
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT msgresponse */
+#define    MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4
+#define       MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0
+
+
+/***********************************/
+/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD
+ * Remove a protocol offload from NIC for lights-out state.
  */
 #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
-#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8
-#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0
 
-#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
-#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4
+/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */
+#define    MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8
+#define       MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0
+#define       MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4
 
-/* Lights-out offload protocols enumeration */
-#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1
-#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS  0x2
+/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT msgresponse */
+#define    MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0
 
 
-/* MC_CMD_MAC_RESET_RESTORE:
- * Restore MAC after block reset
- *
- * Locks required: None
- * Returns: 0
+/***********************************/
+/* MC_CMD_MAC_RESET_RESTORE
+ * Restore MAC after block reset.
  */
-
 #define MC_CMD_MAC_RESET_RESTORE 0x48
-#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0
-#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0
 
+/* MC_CMD_MAC_RESET_RESTORE_IN msgrequest */
+#define    MC_CMD_MAC_RESET_RESTORE_IN_LEN 0
+
+/* MC_CMD_MAC_RESET_RESTORE_OUT msgresponse */
+#define    MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0
 
-/* MC_CMD_TEST_ASSERT:
- * Deliberately trigger an assert-detonation in the firmware for testing
- * purposes (i.e. to allow tests that the driver copes gracefully).
- *
- * Locks required: None
- * Returns: 0
- */
 
+/***********************************/
+/* MC_CMD_TESTASSERT
+ */
 #define MC_CMD_TESTASSERT 0x49
-#define MC_CMD_TESTASSERT_IN_LEN 0
-#define MC_CMD_TESTASSERT_OUT_LEN 0
 
-/* MC_CMD_WORKAROUND 0x4a
- *
- * Enable/Disable a given workaround. The mcfw will return EINVAL if it
- * doesn't understand the given workaround number - which should not
- * be treated as a hard error by client code.
- *
- * This op does not imply any semantics about each workaround, that's between
- * the driver and the mcfw on a per-workaround basis.
- *
- * Locks required: None
- * Returns: 0, EINVAL
+/* MC_CMD_TESTASSERT_IN msgrequest */
+#define    MC_CMD_TESTASSERT_IN_LEN 0
+
+/* MC_CMD_TESTASSERT_OUT msgresponse */
+#define    MC_CMD_TESTASSERT_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_WORKAROUND
+ * Enable/Disable a given workaround.
  */
 #define MC_CMD_WORKAROUND 0x4a
-#define MC_CMD_WORKAROUND_IN_LEN 8
-#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0
-#define MC_CMD_WORKAROUND_BUG17230 1
-#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4
-#define MC_CMD_WORKAROUND_OUT_LEN 0
-
-/* MC_CMD_GET_PHY_MEDIA_INFO:
- * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for
- * SFP+ PHYs).
- *
- * The "media type" can be found via GET_PHY_CFG (GET_PHY_CFG_OUT_MEDIA_TYPE);
- * the valid "page number" input values, and the output data, are interpreted
- * on a per-type basis.
- *
- * For SFP+: PAGE=0 or 1 returns a 128-byte block read from module I2C address
- *           0xA0 offset 0 or 0x80.
- * Anything else: currently undefined.
- *
- * Locks required: None
- * Return code: 0
+
+/* MC_CMD_WORKAROUND_IN msgrequest */
+#define    MC_CMD_WORKAROUND_IN_LEN 8
+#define       MC_CMD_WORKAROUND_IN_TYPE_OFST 0
+#define          MC_CMD_WORKAROUND_BUG17230 0x1 /* enum */
+#define       MC_CMD_WORKAROUND_IN_ENABLED_OFST 4
+
+/* MC_CMD_WORKAROUND_OUT msgresponse */
+#define    MC_CMD_WORKAROUND_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_PHY_MEDIA_INFO
+ * Read media-specific data from PHY.
  */
 #define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
-#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4
-#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0
-#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(_num_bytes) (4 + (_num_bytes))
-#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
-#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
-
-/* MC_CMD_NVRAM_TEST:
- * Test a particular NVRAM partition for valid contents (where "valid"
- * depends on the type of partition).
- *
- * Locks required: None
- * Return code: 0
+
+/* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */
+#define    MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4
+#define       MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0
+
+/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */
+#define    MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5
+#define    MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 255
+#define    MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num))
+#define       MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
+#define       MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
+#define       MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1
+#define       MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1
+#define       MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 251
+
+
+/***********************************/
+/* MC_CMD_NVRAM_TEST
+ * Test a particular NVRAM partition.
  */
 #define MC_CMD_NVRAM_TEST 0x4c
-#define MC_CMD_NVRAM_TEST_IN_LEN 4
-#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0
-#define MC_CMD_NVRAM_TEST_OUT_LEN 4
-#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0
-#define MC_CMD_NVRAM_TEST_PASS 0
-#define MC_CMD_NVRAM_TEST_FAIL 1
-#define MC_CMD_NVRAM_TEST_NOTSUPP 2
-
-/* MC_CMD_MRSFP_TWEAK: (debug)
- * Read status and/or set parameters for the "mrsfp" driver in mr_rusty builds.
- * I2C I/O expander bits are always read; if equaliser parameters are supplied,
- * they are configured first.
- *
- * Locks required: None
- * Return code: 0, EINVAL
+
+/* MC_CMD_NVRAM_TEST_IN msgrequest */
+#define    MC_CMD_NVRAM_TEST_IN_LEN 4
+#define       MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
+
+/* MC_CMD_NVRAM_TEST_OUT msgresponse */
+#define    MC_CMD_NVRAM_TEST_OUT_LEN 4
+#define       MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0
+#define          MC_CMD_NVRAM_TEST_PASS 0x0 /* enum */
+#define          MC_CMD_NVRAM_TEST_FAIL 0x1 /* enum */
+#define          MC_CMD_NVRAM_TEST_NOTSUPP 0x2 /* enum */
+
+
+/***********************************/
+/* MC_CMD_MRSFP_TWEAK
+ * Read status and/or set parameters for the 'mrsfp' driver.
  */
 #define MC_CMD_MRSFP_TWEAK 0x4d
-#define MC_CMD_MRSFP_TWEAK_IN_LEN_READ_ONLY 0
-#define MC_CMD_MRSFP_TWEAK_IN_LEN_EQ_CONFIG 16
-#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_LEVEL_OFST 0    /* 0-6 low->high de-emph. */
-#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_DT_CFG_OFST 4   /* 0-8 low->high ref.V */
-#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_BOOST_OFST 8    /* 0-8 low->high boost */
-#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_DT_CFG_OFST 12  /* 0-8 low->high ref.V */
-#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0     /* input bits */
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4    /* output bits */
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8  /* dirs: 0=out, 1=in */
-
-/* MC_CMD_TEST_HACK: (debug (unsurprisingly))
-  * Change bits of network port state for test purposes in ways that would never be
-  * useful in normal operation and so need a special command to change. */
-#define MC_CMD_TEST_HACK 0x2f
-#define MC_CMD_TEST_HACK_IN_LEN 8
-#define MC_CMD_TEST_HACK_IN_TXPAD_OFST 0
-#define   MC_CMD_TEST_HACK_IN_TXPAD_AUTO  0 /* Let the MC manage things */
-#define   MC_CMD_TEST_HACK_IN_TXPAD_ON    1 /* Force on */
-#define   MC_CMD_TEST_HACK_IN_TXPAD_OFF   2 /* Force on */
-#define MC_CMD_TEST_HACK_IN_IPG_OFST   4 /* Takes a value in bits */
-#define   MC_CMD_TEST_HACK_IN_IPG_AUTO    0 /* The MC picks the value */
-#define MC_CMD_TEST_HACK_OUT_LEN 0
-
-/* MC_CMD_SENSOR_SET_LIMS: (debug) (mostly) adjust the sensor limits. This
- * is a warranty-voiding operation.
-  *
- * IN: sensor identifier (one of the enumeration starting with MC_CMD_SENSOR_CONTROLLER_TEMP
- * followed by 4 32-bit values: min(warning) max(warning), min(fatal), max(fatal). Which
- * of these limits are meaningful and what their interpretation is is sensor-specific.
- *
- * OUT: nothing
- *
- * Returns: ENOENT if the sensor specified does not exist, EINVAL if the limits are
-  * out of range.
+
+/* MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG msgrequest */
+#define    MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16
+#define       MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0
+#define       MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4
+#define       MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8
+#define       MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12
+
+/* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */
+#define    MC_CMD_MRSFP_TWEAK_IN_READ_ONLY_LEN 0
+
+/* MC_CMD_MRSFP_TWEAK_OUT msgresponse */
+#define    MC_CMD_MRSFP_TWEAK_OUT_LEN 12
+#define       MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0
+#define       MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4
+#define       MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8
+#define          MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum */
+#define          MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1 /* enum */
+
+
+/***********************************/
+/* MC_CMD_SENSOR_SET_LIMS
+ * Adjusts the sensor limits.
  */
 #define MC_CMD_SENSOR_SET_LIMS 0x4e
-#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20
-#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0
-#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4
-#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST  8
-#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12
-#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST  16
-
-/* Do NOT add new commands beyond 0x4f as part of 3.0 : 0x50 - 0x7f will be
- * used for post-3.0 extensions. If you run out of space, look for gaps or
- * commands that are unused in the existing range. */
+
+/* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */
+#define    MC_CMD_SENSOR_SET_LIMS_IN_LEN 20
+#define       MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0
+/*            Enum values, see field(s): */
+/*               MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+#define       MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4
+#define       MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8
+#define       MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12
+#define       MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16
+
+/* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */
+#define    MC_CMD_SENSOR_SET_LIMS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_RESOURCE_LIMITS
+ */
+#define MC_CMD_GET_RESOURCE_LIMITS 0x4f
+
+/* MC_CMD_GET_RESOURCE_LIMITS_IN msgrequest */
+#define    MC_CMD_GET_RESOURCE_LIMITS_IN_LEN 0
+
+/* MC_CMD_GET_RESOURCE_LIMITS_OUT msgresponse */
+#define    MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN 16
+#define       MC_CMD_GET_RESOURCE_LIMITS_OUT_BUFTBL_OFST 0
+#define       MC_CMD_GET_RESOURCE_LIMITS_OUT_EVQ_OFST 4
+#define       MC_CMD_GET_RESOURCE_LIMITS_OUT_RXQ_OFST 8
+#define       MC_CMD_GET_RESOURCE_LIMITS_OUT_TXQ_OFST 12
+
+/* MC_CMD_RESOURCE_SPECIFIER enum */
+#define          MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff /* enum */
+#define          MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe /* enum */
+
 
 #endif /* MCDI_PCOL_H */
diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c
index 6c63ab0..7bcad89 100644
--- a/drivers/net/ethernet/sfc/mcdi_phy.c
+++ b/drivers/net/ethernet/sfc/mcdi_phy.c
@@ -116,7 +116,7 @@ static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes)
 		goto fail;
 	}
 
-	*loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_SUGGESTED);
+	*loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED);
 
 	return 0;
 
@@ -264,22 +264,22 @@ static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx)
 
 	/* TODO: Advertise the capabilities supported by this PHY */
 	supported = 0;
-	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_TXDIS_LBN))
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN))
 		supported |= PHY_MODE_TX_DISABLED;
-	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_LOWPOWER_LBN))
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN))
 		supported |= PHY_MODE_LOW_POWER;
-	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_POWEROFF_LBN))
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN))
 		supported |= PHY_MODE_OFF;
 
 	mode = efx->phy_mode & supported;
 
 	flags = 0;
 	if (mode & PHY_MODE_TX_DISABLED)
-		flags |= (1 << MC_CMD_SET_LINK_TXDIS_LBN);
+		flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN);
 	if (mode & PHY_MODE_LOW_POWER)
-		flags |= (1 << MC_CMD_SET_LINK_LOWPOWER_LBN);
+		flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN);
 	if (mode & PHY_MODE_OFF)
-		flags |= (1 << MC_CMD_SET_LINK_POWEROFF_LBN);
+		flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN);
 
 	return flags;
 }
@@ -436,8 +436,8 @@ void efx_mcdi_phy_decode_link(struct efx_nic *efx,
 		break;
 	}
 
-	link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_LINK_UP_LBN));
-	link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_FULL_DUPLEX_LBN));
+	link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
+	link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
 	link_state->speed = speed;
 }
 
@@ -592,7 +592,7 @@ static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
 
 	if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
 		return -EIO;
-	if (MCDI_DWORD(outbuf, GET_PHY_STATE_STATE) != MC_CMD_PHY_STATE_OK)
+	if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK)
 		return -EINVAL;
 
 	return 0;
@@ -680,7 +680,7 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
 	u32 mode;
 	int rc;
 
-	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_LBN)) {
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
 		rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results);
 		if (rc < 0)
 			return rc;
@@ -691,15 +691,15 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results,
 	/* If we support both LONG and SHORT, then run each in response to
 	 * break or not. Otherwise, run the one we support */
 	mode = 0;
-	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN)) {
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) {
 		if ((flags & ETH_TEST_FL_OFFLINE) &&
 		    (phy_cfg->flags &
-		     (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN)))
+		     (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)))
 			mode = MC_CMD_PHY_BIST_CABLE_LONG;
 		else
 			mode = MC_CMD_PHY_BIST_CABLE_SHORT;
 	} else if (phy_cfg->flags &
-		   (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN))
+		   (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))
 		mode = MC_CMD_PHY_BIST_CABLE_LONG;
 
 	if (mode != 0) {
@@ -717,14 +717,14 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
 {
 	struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
 
-	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_LBN)) {
+	if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) {
 		if (index == 0)
 			return "bist";
 		--index;
 	}
 
-	if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN) |
-			      (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN))) {
+	if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) |
+			      (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) {
 		if (index == 0)
 			return "cable";
 		--index;
@@ -741,7 +741,7 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
 
 const struct efx_phy_operations efx_mcdi_phy_ops = {
 	.probe		= efx_mcdi_phy_probe,
-	.init 	 	= efx_port_dummy_op_int,
+	.init		= efx_port_dummy_op_int,
 	.reconfigure	= efx_mcdi_phy_reconfigure,
 	.poll		= efx_mcdi_phy_poll,
 	.fini		= efx_port_dummy_op_void,
diff --git a/drivers/net/ethernet/sfc/mdio_10g.c b/drivers/net/ethernet/sfc/mdio_10g.c
index 7ab385c..9acfd66 100644
--- a/drivers/net/ethernet/sfc/mdio_10g.c
+++ b/drivers/net/ethernet/sfc/mdio_10g.c
@@ -228,7 +228,7 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
 /**
  * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
  * @efx:		Efx NIC
- * @ecmd: 		New settings
+ * @ecmd:		New settings
  */
 int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c
index bc9dcd6..7581483 100644
--- a/drivers/net/ethernet/sfc/mtd.c
+++ b/drivers/net/ethernet/sfc/mtd.c
@@ -193,7 +193,7 @@ static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
 		erase->state = MTD_ERASE_DONE;
 	} else {
 		erase->state = MTD_ERASE_FAILED;
-		erase->fail_addr = 0xffffffff;
+		erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
 	}
 	mtd_erase_callback(erase);
 	return rc;
@@ -263,10 +263,10 @@ static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd)
 		part->mtd.owner = THIS_MODULE;
 		part->mtd.priv = efx_mtd;
 		part->mtd.name = part->name;
-		part->mtd.erase = efx_mtd_erase;
-		part->mtd.read = efx_mtd->ops->read;
-		part->mtd.write = efx_mtd->ops->write;
-		part->mtd.sync = efx_mtd_sync;
+		part->mtd._erase = efx_mtd_erase;
+		part->mtd._read = efx_mtd->ops->read;
+		part->mtd._write = efx_mtd->ops->write;
+		part->mtd._sync = efx_mtd_sync;
 
 		if (mtd_device_register(&part->mtd, NULL, 0))
 			goto fail;
@@ -280,7 +280,7 @@ fail:
 		--part;
 		efx_mtd_remove_partition(part);
 	}
-	/* mtd_device_register() returns 1 if the MTD table is full */
+	/* Failure is unlikely here, but probably means we're out of memory */
 	return -ENOMEM;
 }
 
@@ -382,7 +382,7 @@ static int falcon_mtd_sync(struct mtd_info *mtd)
 	return rc;
 }
 
-static struct efx_mtd_ops falcon_mtd_ops = {
+static const struct efx_mtd_ops falcon_mtd_ops = {
 	.read	= falcon_mtd_read,
 	.erase	= falcon_mtd_erase,
 	.write	= falcon_mtd_write,
@@ -560,7 +560,7 @@ static int siena_mtd_sync(struct mtd_info *mtd)
 	return rc;
 }
 
-static struct efx_mtd_ops siena_mtd_ops = {
+static const struct efx_mtd_ops siena_mtd_ops = {
 	.read	= siena_mtd_read,
 	.erase	= siena_mtd_erase,
 	.write	= siena_mtd_write,
@@ -572,7 +572,7 @@ struct siena_nvram_type_info {
 	const char *name;
 };
 
-static struct siena_nvram_type_info siena_nvram_types[] = {
+static const struct siena_nvram_type_info siena_nvram_types[] = {
 	[MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO]	= { 0, "sfc_dummy_phy" },
 	[MC_CMD_NVRAM_TYPE_MC_FW]		= { 0, "sfc_mcfw" },
 	[MC_CMD_NVRAM_TYPE_MC_FW_BACKUP]	= { 0, "sfc_mcfw_backup" },
@@ -593,7 +593,7 @@ static int siena_mtd_probe_partition(struct efx_nic *efx,
 				     unsigned int type)
 {
 	struct efx_mtd_partition *part = &efx_mtd->part[part_id];
-	struct siena_nvram_type_info *info;
+	const struct siena_nvram_type_info *info;
 	size_t size, erase_size;
 	bool protected;
 	int rc;
@@ -627,11 +627,10 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx,
 				     struct efx_mtd *efx_mtd)
 {
 	struct efx_mtd_partition *part;
-	uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN /
-				 sizeof(uint16_t)];
+	uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM];
 	int rc;
 
-	rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list);
+	rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL);
 	if (rc)
 		return rc;
 
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index c49502b..3fbec45 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -13,10 +13,6 @@
 #ifndef EFX_NET_DRIVER_H
 #define EFX_NET_DRIVER_H
 
-#if defined(EFX_ENABLE_DEBUG) && !defined(DEBUG)
-#define DEBUG
-#endif
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -28,6 +24,7 @@
 #include <linux/device.h>
 #include <linux/highmem.h>
 #include <linux/workqueue.h>
+#include <linux/mutex.h>
 #include <linux/vmalloc.h>
 #include <linux/i2c.h>
 
@@ -42,7 +39,7 @@
 
 #define EFX_DRIVER_VERSION	"3.1"
 
-#ifdef EFX_ENABLE_DEBUG
+#ifdef DEBUG
 #define EFX_BUG_ON_PARANOID(x) BUG_ON(x)
 #define EFX_WARN_ON_PARANOID(x) WARN_ON(x)
 #else
@@ -56,8 +53,10 @@
  *
  **************************************************************************/
 
-#define EFX_MAX_CHANNELS 32
+#define EFX_MAX_CHANNELS 32U
 #define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS
+#define EFX_EXTRA_CHANNEL_IOV	0
+#define EFX_MAX_EXTRA_CHANNELS	1U
 
 /* Checksum generation is a per-queue option in hardware, so each
  * queue visible to the networking core is backed by two hardware TX
@@ -85,15 +84,8 @@ struct efx_special_buffer {
 	void *addr;
 	dma_addr_t dma_addr;
 	unsigned int len;
-	int index;
-	int entries;
-};
-
-enum efx_flush_state {
-	FLUSH_NONE,
-	FLUSH_PENDING,
-	FLUSH_FAILED,
-	FLUSH_DONE,
+	unsigned int index;
+	unsigned int entries;
 };
 
 /**
@@ -142,7 +134,6 @@ struct efx_tx_buffer {
  * @txd: The hardware descriptor ring
  * @ptr_mask: The size of the ring minus 1.
  * @initialised: Has hardware queue been initialised?
- * @flushed: Used when handling queue flushing
  * @read_count: Current read pointer.
  *	This is the number of buffers that have been removed from both rings.
  * @old_write_count: The value of @write_count when last checked.
@@ -185,7 +176,6 @@ struct efx_tx_queue {
 	struct efx_special_buffer txd;
 	unsigned int ptr_mask;
 	bool initialised;
-	enum efx_flush_state flushed;
 
 	/* Members used mainly on the completion path */
 	unsigned int read_count ____cacheline_aligned_in_smp;
@@ -209,12 +199,12 @@ struct efx_tx_queue {
 /**
  * struct efx_rx_buffer - An Efx RX data buffer
  * @dma_addr: DMA base address of the buffer
- * @skb: The associated socket buffer, if any.
- *	If both this and page are %NULL, the buffer slot is currently free.
- * @page: The associated page buffer, if any.
- *	If both this and skb are %NULL, the buffer slot is currently free.
+ * @skb: The associated socket buffer. Valid iff !(@flags & %EFX_RX_BUF_PAGE).
+ *	Will be %NULL if the buffer slot is currently free.
+ * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE.
+ *	Will be %NULL if the buffer slot is currently free.
  * @len: Buffer length, in bytes.
- * @is_page: Indicates if @page is valid. If false, @skb is valid.
+ * @flags: Flags for buffer and packet state.
  */
 struct efx_rx_buffer {
 	dma_addr_t dma_addr;
@@ -223,8 +213,11 @@ struct efx_rx_buffer {
 		struct page *page;
 	} u;
 	unsigned int len;
-	bool is_page;
+	u16 flags;
 };
+#define EFX_RX_BUF_PAGE		0x0001
+#define EFX_RX_PKT_CSUMMED	0x0002
+#define EFX_RX_PKT_DISCARD	0x0004
 
 /**
  * struct efx_rx_page_state - Page-based rx buffer state
@@ -250,6 +243,9 @@ struct efx_rx_page_state {
  * @buffer: The software buffer ring
  * @rxd: The hardware descriptor ring
  * @ptr_mask: The size of the ring minus 1.
+ * @enabled: Receive queue enabled indicator.
+ * @flush_pending: Set when a RX flush is pending. Has the same lifetime as
+ *	@rxq_flush_pending.
  * @added_count: Number of buffers added to the receive queue.
  * @notified_count: Number of buffers given to NIC (<= @added_count).
  * @removed_count: Number of buffers removed from the receive queue.
@@ -264,13 +260,14 @@ struct efx_rx_page_state {
  * @alloc_page_count: RX allocation strategy counter.
  * @alloc_skb_count: RX allocation strategy counter.
  * @slow_fill: Timer used to defer efx_nic_generate_fill_event().
- * @flushed: Use when handling queue flushing
  */
 struct efx_rx_queue {
 	struct efx_nic *efx;
 	struct efx_rx_buffer *buffer;
 	struct efx_special_buffer rxd;
 	unsigned int ptr_mask;
+	bool enabled;
+	bool flush_pending;
 
 	int added_count;
 	int notified_count;
@@ -284,8 +281,6 @@ struct efx_rx_queue {
 	unsigned int alloc_skb_count;
 	struct timer_list slow_fill;
 	unsigned int slow_fill_count;
-
-	enum efx_flush_state flushed;
 };
 
 /**
@@ -319,6 +314,7 @@ enum efx_rx_alloc_method {
  *
  * @efx: Associated Efx NIC
  * @channel: Channel instance number
+ * @type: Channel type definition
  * @enabled: Channel enabled indicator
  * @irq: IRQ number (MSI and MSI-X only)
  * @irq_moderation: IRQ moderation value (in hardware ticks)
@@ -329,6 +325,7 @@ enum efx_rx_alloc_method {
  * @eventq_mask: Event queue pointer mask
  * @eventq_read_ptr: Event queue read pointer
  * @last_eventq_read_ptr: Last event queue read pointer value.
+ * @last_irq_cpu: Last CPU to handle interrupt for this channel
  * @irq_count: Number of IRQs since last adaptive moderation decision
  * @irq_mod_score: IRQ moderation score
  * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors
@@ -348,6 +345,7 @@ enum efx_rx_alloc_method {
 struct efx_channel {
 	struct efx_nic *efx;
 	int channel;
+	const struct efx_channel_type *type;
 	bool enabled;
 	int irq;
 	unsigned int irq_moderation;
@@ -359,6 +357,7 @@ struct efx_channel {
 	unsigned int eventq_read_ptr;
 	unsigned int last_eventq_read_ptr;
 
+	int last_irq_cpu;
 	unsigned int irq_count;
 	unsigned int irq_mod_score;
 #ifdef CONFIG_RFS_ACCEL
@@ -380,12 +379,31 @@ struct efx_channel {
 	 * access with prefetches.
 	 */
 	struct efx_rx_buffer *rx_pkt;
-	bool rx_pkt_csummed;
 
 	struct efx_rx_queue rx_queue;
 	struct efx_tx_queue tx_queue[EFX_TXQ_TYPES];
 };
 
+/**
+ * struct efx_channel_type - distinguishes traffic and extra channels
+ * @handle_no_channel: Handle failure to allocate an extra channel
+ * @pre_probe: Set up extra state prior to initialisation
+ * @post_remove: Tear down extra state after finalisation, if allocated.
+ *	May be called on channels that have not been probed.
+ * @get_name: Generate the channel's name (used for its IRQ handler)
+ * @copy: Copy the channel state prior to reallocation.  May be %NULL if
+ *	reallocation is not supported.
+ * @keep_eventq: Flag for whether event queue should be kept initialised
+ *	while the device is stopped
+ */
+struct efx_channel_type {
+	void (*handle_no_channel)(struct efx_nic *);
+	int (*pre_probe)(struct efx_channel *);
+	void (*get_name)(struct efx_channel *, char *buf, size_t len);
+	struct efx_channel *(*copy)(const struct efx_channel *);
+	bool keep_eventq;
+};
+
 enum efx_led_mode {
 	EFX_LED_OFF	= 0,
 	EFX_LED_ON	= 1,
@@ -395,12 +413,12 @@ enum efx_led_mode {
 #define STRING_TABLE_LOOKUP(val, member) \
 	((val) < member ## _max) ? member ## _names[val] : "(invalid)"
 
-extern const char *efx_loopback_mode_names[];
+extern const char *const efx_loopback_mode_names[];
 extern const unsigned int efx_loopback_mode_max;
 #define LOOPBACK_MODE(efx) \
 	STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode)
 
-extern const char *efx_reset_type_names[];
+extern const char *const efx_reset_type_names[];
 extern const unsigned int efx_reset_type_max;
 #define RESET_TYPE(type) \
 	STRING_TABLE_LOOKUP(type, efx_reset_type)
@@ -474,18 +492,6 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left,
 }
 
 /**
- * struct efx_mac_operations - Efx MAC operations table
- * @reconfigure: Reconfigure MAC. Serialised by the mac_lock
- * @update_stats: Update statistics
- * @check_fault: Check fault state. True if fault present.
- */
-struct efx_mac_operations {
-	int (*reconfigure) (struct efx_nic *efx);
-	void (*update_stats) (struct efx_nic *efx);
-	bool (*check_fault)(struct efx_nic *efx);
-};
-
-/**
  * struct efx_phy_operations - Efx PHY operations table
  * @probe: Probe PHY and initialise efx->mdio.mode_support, efx->mdio.mmds,
  *	efx->loopback_modes.
@@ -552,64 +558,64 @@ struct efx_mac_stats {
 	u64 tx_bytes;
 	u64 tx_good_bytes;
 	u64 tx_bad_bytes;
-	unsigned long tx_packets;
-	unsigned long tx_bad;
-	unsigned long tx_pause;
-	unsigned long tx_control;
-	unsigned long tx_unicast;
-	unsigned long tx_multicast;
-	unsigned long tx_broadcast;
-	unsigned long tx_lt64;
-	unsigned long tx_64;
-	unsigned long tx_65_to_127;
-	unsigned long tx_128_to_255;
-	unsigned long tx_256_to_511;
-	unsigned long tx_512_to_1023;
-	unsigned long tx_1024_to_15xx;
-	unsigned long tx_15xx_to_jumbo;
-	unsigned long tx_gtjumbo;
-	unsigned long tx_collision;
-	unsigned long tx_single_collision;
-	unsigned long tx_multiple_collision;
-	unsigned long tx_excessive_collision;
-	unsigned long tx_deferred;
-	unsigned long tx_late_collision;
-	unsigned long tx_excessive_deferred;
-	unsigned long tx_non_tcpudp;
-	unsigned long tx_mac_src_error;
-	unsigned long tx_ip_src_error;
+	u64 tx_packets;
+	u64 tx_bad;
+	u64 tx_pause;
+	u64 tx_control;
+	u64 tx_unicast;
+	u64 tx_multicast;
+	u64 tx_broadcast;
+	u64 tx_lt64;
+	u64 tx_64;
+	u64 tx_65_to_127;
+	u64 tx_128_to_255;
+	u64 tx_256_to_511;
+	u64 tx_512_to_1023;
+	u64 tx_1024_to_15xx;
+	u64 tx_15xx_to_jumbo;
+	u64 tx_gtjumbo;
+	u64 tx_collision;
+	u64 tx_single_collision;
+	u64 tx_multiple_collision;
+	u64 tx_excessive_collision;
+	u64 tx_deferred;
+	u64 tx_late_collision;
+	u64 tx_excessive_deferred;
+	u64 tx_non_tcpudp;
+	u64 tx_mac_src_error;
+	u64 tx_ip_src_error;
 	u64 rx_bytes;
 	u64 rx_good_bytes;
 	u64 rx_bad_bytes;
-	unsigned long rx_packets;
-	unsigned long rx_good;
-	unsigned long rx_bad;
-	unsigned long rx_pause;
-	unsigned long rx_control;
-	unsigned long rx_unicast;
-	unsigned long rx_multicast;
-	unsigned long rx_broadcast;
-	unsigned long rx_lt64;
-	unsigned long rx_64;
-	unsigned long rx_65_to_127;
-	unsigned long rx_128_to_255;
-	unsigned long rx_256_to_511;
-	unsigned long rx_512_to_1023;
-	unsigned long rx_1024_to_15xx;
-	unsigned long rx_15xx_to_jumbo;
-	unsigned long rx_gtjumbo;
-	unsigned long rx_bad_lt64;
-	unsigned long rx_bad_64_to_15xx;
-	unsigned long rx_bad_15xx_to_jumbo;
-	unsigned long rx_bad_gtjumbo;
-	unsigned long rx_overflow;
-	unsigned long rx_missed;
-	unsigned long rx_false_carrier;
-	unsigned long rx_symbol_error;
-	unsigned long rx_align_error;
-	unsigned long rx_length_error;
-	unsigned long rx_internal_error;
-	unsigned long rx_good_lt64;
+	u64 rx_packets;
+	u64 rx_good;
+	u64 rx_bad;
+	u64 rx_pause;
+	u64 rx_control;
+	u64 rx_unicast;
+	u64 rx_multicast;
+	u64 rx_broadcast;
+	u64 rx_lt64;
+	u64 rx_64;
+	u64 rx_65_to_127;
+	u64 rx_128_to_255;
+	u64 rx_256_to_511;
+	u64 rx_512_to_1023;
+	u64 rx_1024_to_15xx;
+	u64 rx_15xx_to_jumbo;
+	u64 rx_gtjumbo;
+	u64 rx_bad_lt64;
+	u64 rx_bad_64_to_15xx;
+	u64 rx_bad_15xx_to_jumbo;
+	u64 rx_bad_gtjumbo;
+	u64 rx_overflow;
+	u64 rx_missed;
+	u64 rx_false_carrier;
+	u64 rx_symbol_error;
+	u64 rx_align_error;
+	u64 rx_length_error;
+	u64 rx_internal_error;
+	u64 rx_good_lt64;
 };
 
 /* Number of bits used in a multicast filter hash address */
@@ -625,6 +631,8 @@ union efx_multicast_hash {
 };
 
 struct efx_filter_state;
+struct efx_vf;
+struct vfdi_status;
 
 /**
  * struct efx_nic - an Efx NIC
@@ -640,6 +648,7 @@ struct efx_filter_state;
  * @membase_phys: Memory BAR value as physical address
  * @membase: Memory BAR value
  * @interrupt_mode: Interrupt mode
+ * @timer_quantum_ns: Interrupt timer quantum, in nanoseconds
  * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
  * @irq_rx_moderation: IRQ moderation time for RX event queues
  * @msg_enable: Log message enable flags
@@ -649,8 +658,13 @@ struct efx_filter_state;
  * @rx_queue: RX DMA queues
  * @channel: Channels
  * @channel_name: Names for channels and their IRQs
+ * @extra_channel_types: Types of extra (non-traffic) channels that
+ *	should be allocated for this NIC
  * @rxq_entries: Size of receive queues requested by user.
  * @txq_entries: Size of transmit queues requested by user.
+ * @tx_dc_base: Base qword address in SRAM of TX queue descriptor caches
+ * @rx_dc_base: Base qword address in SRAM of RX queue descriptor caches
+ * @sram_lim_qw: Qword address limit of SRAM
  * @next_buffer_table: First available buffer table id
  * @n_channels: Number of channels in use
  * @n_rx_channels: Number of channels used for RX (= number of RX queues)
@@ -663,7 +677,7 @@ struct efx_filter_state;
  * @int_error_expire: Time at which error count will be expired
  * @irq_status: Interrupt status buffer
  * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0
- * @fatal_irq_level: IRQ level (bit number) used for serious errors
+ * @irq_level: IRQ level/index for IRQs not triggered by an event queue
  * @mtd_list: List of MTDs attached to the NIC
  * @nic_data: Hardware dependent state
  * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
@@ -676,7 +690,6 @@ struct efx_filter_state;
  * @port_initialized: Port initialized?
  * @net_dev: Operating system network device. Consider holding the rtnl lock
  * @stats_buffer: DMA buffer for statistics
- * @mac_op: MAC interface
  * @phy_type: PHY type
  * @phy_op: PHY interface
  * @phy_data: PHY private data (including PHY-specific stats)
@@ -689,21 +702,42 @@ struct efx_filter_state;
  * @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
  * @multicast_hash: Multicast hash table
  * @wanted_fc: Wanted flow control flags
+ * @fc_disable: When non-zero flow control is disabled. Typically used to
+ *	ensure that network back pressure doesn't delay dma queue flushes.
+ *	Serialised by the rtnl lock.
  * @mac_work: Work item for changing MAC promiscuity and multicast hash
  * @loopback_mode: Loopback status
  * @loopback_modes: Supported loopback mode bitmask
  * @loopback_selftest: Offline self-test private state
+ * @drain_pending: Count of RX and TX queues that haven't been flushed and drained.
+ * @rxq_flush_pending: Count of number of receive queues that need to be flushed.
+ *	Decremented when the efx_flush_rx_queue() is called.
+ * @rxq_flush_outstanding: Count of number of RX flushes started but not yet
+ *	completed (either success or failure). Not used when MCDI is used to
+ *	flush receive queues.
+ * @flush_wq: wait queue used by efx_nic_flush_queues() to wait for flush completions.
+ * @vf: Array of &struct efx_vf objects.
+ * @vf_count: Number of VFs intended to be enabled.
+ * @vf_init_count: Number of VFs that have been fully initialised.
+ * @vi_scale: log2 number of vnics per VF.
+ * @vf_buftbl_base: The zeroth buffer table index used to back VF queues.
+ * @vfdi_status: Common VFDI status page to be dmad to VF address space.
+ * @local_addr_list: List of local addresses. Protected by %local_lock.
+ * @local_page_list: List of DMA addressable pages used to broadcast
+ *	%local_addr_list. Protected by %local_lock.
+ * @local_lock: Mutex protecting %local_addr_list and %local_page_list.
+ * @peer_work: Work item to broadcast peer addresses to VMs.
  * @monitor_work: Hardware monitor workitem
  * @biu_lock: BIU (bus interface unit) lock
- * @last_irq_cpu: Last CPU to handle interrupt.
- *	This register is written with the SMP processor ID whenever an
- *	interrupt is handled.  It is used by efx_nic_test_interrupt()
- *	to verify that an interrupt has occurred.
+ * @last_irq_cpu: Last CPU to handle a possible test interrupt.  This
+ *	field is used by efx_test_interrupts() to verify that an
+ *	interrupt has occurred.
  * @n_rx_nodesc_drop_cnt: RX no descriptor drop count
  * @mac_stats: MAC statistics. These include all statistics the MACs
  *	can provide.  Generic code converts these into a standard
  *	&struct net_device_stats.
  * @stats_lock: Statistics update lock. Serialises statistics fetches
+ *	and access to @mac_stats.
  *
  * This is stored in the private area of the &struct net_device.
  */
@@ -722,6 +756,7 @@ struct efx_nic {
 	void __iomem *membase;
 
 	enum efx_int_mode interrupt_mode;
+	unsigned int timer_quantum_ns;
 	bool irq_rx_adaptive;
 	unsigned int irq_rx_moderation;
 	u32 msg_enable;
@@ -731,12 +766,18 @@ struct efx_nic {
 
 	struct efx_channel *channel[EFX_MAX_CHANNELS];
 	char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6];
+	const struct efx_channel_type *
+	extra_channel_type[EFX_MAX_EXTRA_CHANNELS];
 
 	unsigned rxq_entries;
 	unsigned txq_entries;
+	unsigned tx_dc_base;
+	unsigned rx_dc_base;
+	unsigned sram_lim_qw;
 	unsigned next_buffer_table;
 	unsigned n_channels;
 	unsigned n_rx_channels;
+	unsigned rss_spread;
 	unsigned tx_channel_offset;
 	unsigned n_tx_channels;
 	unsigned int rx_buffer_len;
@@ -749,7 +790,7 @@ struct efx_nic {
 
 	struct efx_buffer irq_status;
 	unsigned irq_zero_count;
-	unsigned fatal_irq_level;
+	unsigned irq_level;
 
 #ifdef CONFIG_SFC_MTD
 	struct list_head mtd_list;
@@ -766,8 +807,6 @@ struct efx_nic {
 
 	struct efx_buffer stats_buffer;
 
-	const struct efx_mac_operations *mac_op;
-
 	unsigned int phy_type;
 	const struct efx_phy_operations *phy_op;
 	void *phy_data;
@@ -782,6 +821,7 @@ struct efx_nic {
 	bool promiscuous;
 	union efx_multicast_hash multicast_hash;
 	u8 wanted_fc;
+	unsigned fc_disable;
 
 	atomic_t rx_reset;
 	enum efx_loopback_mode loopback_mode;
@@ -791,11 +831,30 @@ struct efx_nic {
 
 	struct efx_filter_state *filter_state;
 
+	atomic_t drain_pending;
+	atomic_t rxq_flush_pending;
+	atomic_t rxq_flush_outstanding;
+	wait_queue_head_t flush_wq;
+
+#ifdef CONFIG_SFC_SRIOV
+	struct efx_channel *vfdi_channel;
+	struct efx_vf *vf;
+	unsigned vf_count;
+	unsigned vf_init_count;
+	unsigned vi_scale;
+	unsigned vf_buftbl_base;
+	struct efx_buffer vfdi_status;
+	struct list_head local_addr_list;
+	struct list_head local_page_list;
+	struct mutex local_lock;
+	struct work_struct peer_work;
+#endif
+
 	/* The following fields may be written more often */
 
 	struct delayed_work monitor_work ____cacheline_aligned_in_smp;
 	spinlock_t biu_lock;
-	volatile signed int last_irq_cpu;
+	int last_irq_cpu;
 	unsigned n_rx_nodesc_drop_cnt;
 	struct efx_mac_stats mac_stats;
 	spinlock_t stats_lock;
@@ -806,15 +865,6 @@ static inline int efx_dev_registered(struct efx_nic *efx)
 	return efx->net_dev->reg_state == NETREG_REGISTERED;
 }
 
-/* Net device name, for inclusion in log messages if it has been registered.
- * Use efx->name not efx->net_dev->name so that races with (un)registration
- * are harmless.
- */
-static inline const char *efx_dev_name(struct efx_nic *efx)
-{
-	return efx_dev_registered(efx) ? efx->name : "";
-}
-
 static inline unsigned int efx_port_num(struct efx_nic *efx)
 {
 	return efx->net_dev->dev_id;
@@ -825,6 +875,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
  * @probe: Probe the controller
  * @remove: Free resources allocated by probe()
  * @init: Initialise the controller
+ * @dimension_resources: Dimension controller resources (buffer table,
+ *	and VIs once the available interrupt resources are clear)
  * @fini: Shut down the controller
  * @monitor: Periodic function for polling link state and hardware monitor
  * @map_reset_reason: Map ethtool reset reason to a reset method
@@ -840,14 +892,15 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
  * @stop_stats: Stop the regular fetching of statistics
  * @set_id_led: Set state of identifying LED or revert to automatic function
  * @push_irq_moderation: Apply interrupt moderation value
- * @push_multicast_hash: Apply multicast hash table
  * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY
+ * @reconfigure_mac: Push MAC address, MTU, flow control and filter settings
+ *	to the hardware.  Serialised by the mac_lock.
+ * @check_mac_fault: Check MAC fault state. True if fault present.
  * @get_wol: Get WoL configuration from driver state
  * @set_wol: Push WoL configuration to the NIC
  * @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume)
  * @test_registers: Test read/write functionality of control registers
  * @test_nvram: Test validity of NVRAM contents
- * @default_mac_ops: efx_mac_operations to set at startup
  * @revision: Hardware architecture revision
  * @mem_map_size: Memory BAR mapped size
  * @txd_ptr_tbl_base: TX descriptor ring base address
@@ -862,8 +915,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
  *	from &enum efx_init_mode.
  * @phys_addr_channels: Number of channels with physically addressed
  *	descriptors
- * @tx_dc_base: Base address in SRAM of TX queue descriptor caches
- * @rx_dc_base: Base address in SRAM of RX queue descriptor caches
+ * @timer_period_max: Maximum period of interrupt timer (in ticks)
  * @offload_features: net_device feature flags for protocol offload
  *	features implemented in hardware
  */
@@ -871,6 +923,7 @@ struct efx_nic_type {
 	int (*probe)(struct efx_nic *efx);
 	void (*remove)(struct efx_nic *efx);
 	int (*init)(struct efx_nic *efx);
+	void (*dimension_resources)(struct efx_nic *efx);
 	void (*fini)(struct efx_nic *efx);
 	void (*monitor)(struct efx_nic *efx);
 	enum reset_type (*map_reset_reason)(enum reset_type reason);
@@ -885,14 +938,14 @@ struct efx_nic_type {
 	void (*stop_stats)(struct efx_nic *efx);
 	void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode);
 	void (*push_irq_moderation)(struct efx_channel *channel);
-	void (*push_multicast_hash)(struct efx_nic *efx);
 	int (*reconfigure_port)(struct efx_nic *efx);
+	int (*reconfigure_mac)(struct efx_nic *efx);
+	bool (*check_mac_fault)(struct efx_nic *efx);
 	void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol);
 	int (*set_wol)(struct efx_nic *efx, u32 type);
 	void (*resume_wol)(struct efx_nic *efx);
 	int (*test_registers)(struct efx_nic *efx);
 	int (*test_nvram)(struct efx_nic *efx);
-	const struct efx_mac_operations *default_mac_ops;
 
 	int revision;
 	unsigned int mem_map_size;
@@ -906,8 +959,7 @@ struct efx_nic_type {
 	unsigned int rx_buffer_padding;
 	unsigned int max_interrupt_mode;
 	unsigned int phys_addr_channels;
-	unsigned int tx_dc_base;
-	unsigned int rx_dc_base;
+	unsigned int timer_period_max;
 	netdev_features_t offload_features;
 };
 
@@ -931,6 +983,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index)
 	     _channel = (_channel->channel + 1 < (_efx)->n_channels) ?	\
 		     (_efx)->channel[_channel->channel + 1] : NULL)
 
+/* Iterate over all used channels in reverse */
+#define efx_for_each_channel_rev(_channel, _efx)			\
+	for (_channel = (_efx)->channel[(_efx)->n_channels - 1];	\
+	     _channel;							\
+	     _channel = _channel->channel ?				\
+		     (_efx)->channel[_channel->channel - 1] : NULL)
+
 static inline struct efx_tx_queue *
 efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
 {
@@ -975,13 +1034,6 @@ static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue)
 	     _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES;		\
 	     _tx_queue++)
 
-static inline struct efx_rx_queue *
-efx_get_rx_queue(struct efx_nic *efx, unsigned index)
-{
-	EFX_BUG_ON_PARANOID(index >= efx->n_rx_channels);
-	return &efx->channel[index]->rx_queue;
-}
-
 static inline bool efx_channel_has_rx_queue(struct efx_channel *channel)
 {
 	return channel->channel < channel->efx->n_rx_channels;
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 3edfbaf..2bf4283 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -49,24 +49,29 @@
 #define EFX_INT_ERROR_EXPIRE 3600
 #define EFX_MAX_INT_ERRORS 5
 
-/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
- */
-#define EFX_FLUSH_INTERVAL 10
-#define EFX_FLUSH_POLL_COUNT 100
-
-/* Size and alignment of special buffers (4KB) */
-#define EFX_BUF_SIZE 4096
-
 /* Depth of RX flush request fifo */
 #define EFX_RX_FLUSH_COUNT 4
 
-/* Generated event code for efx_generate_test_event() */
-#define EFX_CHANNEL_MAGIC_TEST(_channel)	\
-	(0x00010100 + (_channel)->channel)
-
-/* Generated event code for efx_generate_fill_event() */
-#define EFX_CHANNEL_MAGIC_FILL(_channel)	\
-	(0x00010200 + (_channel)->channel)
+/* Driver generated events */
+#define _EFX_CHANNEL_MAGIC_TEST		0x000101
+#define _EFX_CHANNEL_MAGIC_FILL		0x000102
+#define _EFX_CHANNEL_MAGIC_RX_DRAIN	0x000103
+#define _EFX_CHANNEL_MAGIC_TX_DRAIN	0x000104
+
+#define _EFX_CHANNEL_MAGIC(_code, _data)	((_code) << 8 | (_data))
+#define _EFX_CHANNEL_MAGIC_CODE(_magic)		((_magic) >> 8)
+
+#define EFX_CHANNEL_MAGIC_TEST(_channel)				\
+	_EFX_CHANNEL_MAGIC(_EFX_CHANNEL_MAGIC_TEST, (_channel)->channel)
+#define EFX_CHANNEL_MAGIC_FILL(_rx_queue)				\
+	_EFX_CHANNEL_MAGIC(_EFX_CHANNEL_MAGIC_FILL,			\
+			   efx_rx_queue_index(_rx_queue))
+#define EFX_CHANNEL_MAGIC_RX_DRAIN(_rx_queue)				\
+	_EFX_CHANNEL_MAGIC(_EFX_CHANNEL_MAGIC_RX_DRAIN,			\
+			   efx_rx_queue_index(_rx_queue))
+#define EFX_CHANNEL_MAGIC_TX_DRAIN(_tx_queue)				\
+	_EFX_CHANNEL_MAGIC(_EFX_CHANNEL_MAGIC_TX_DRAIN,			\
+			   (_tx_queue)->queue)
 
 /**************************************************************************
  *
@@ -187,7 +192,7 @@ static void
 efx_init_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
 {
 	efx_qword_t buf_desc;
-	int index;
+	unsigned int index;
 	dma_addr_t dma_addr;
 	int i;
 
@@ -196,7 +201,7 @@ efx_init_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer)
 	/* Write buffer descriptors to NIC */
 	for (i = 0; i < buffer->entries; i++) {
 		index = buffer->index + i;
-		dma_addr = buffer->dma_addr + (i * 4096);
+		dma_addr = buffer->dma_addr + (i * EFX_BUF_SIZE);
 		netif_dbg(efx, probe, efx->net_dev,
 			  "mapping special buffer %d at %llx\n",
 			  index, (unsigned long long)dma_addr);
@@ -259,6 +264,10 @@ static int efx_alloc_special_buffer(struct efx_nic *efx,
 	/* Select new buffer ID */
 	buffer->index = efx->next_buffer_table;
 	efx->next_buffer_table += buffer->entries;
+#ifdef CONFIG_SFC_SRIOV
+	BUG_ON(efx_sriov_enabled(efx) &&
+	       efx->vf_buftbl_base < efx->next_buffer_table);
+#endif
 
 	netif_dbg(efx, probe, efx->net_dev,
 		  "allocating special buffers %d-%d at %llx+%x "
@@ -430,8 +439,6 @@ void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
 	struct efx_nic *efx = tx_queue->efx;
 	efx_oword_t reg;
 
-	tx_queue->flushed = FLUSH_NONE;
-
 	/* Pin TX descriptor ring */
 	efx_init_special_buffer(efx, &tx_queue->txd);
 
@@ -488,9 +495,6 @@ static void efx_flush_tx_queue(struct efx_tx_queue *tx_queue)
 	struct efx_nic *efx = tx_queue->efx;
 	efx_oword_t tx_flush_descq;
 
-	tx_queue->flushed = FLUSH_PENDING;
-
-	/* Post a flush command */
 	EFX_POPULATE_OWORD_2(tx_flush_descq,
 			     FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
 			     FRF_AZ_TX_FLUSH_DESCQ, tx_queue->queue);
@@ -502,9 +506,6 @@ void efx_nic_fini_tx(struct efx_tx_queue *tx_queue)
 	struct efx_nic *efx = tx_queue->efx;
 	efx_oword_t tx_desc_ptr;
 
-	/* The queue should have been flushed */
-	WARN_ON(tx_queue->flushed != FLUSH_DONE);
-
 	/* Remove TX descriptor ring from card */
 	EFX_ZERO_OWORD(tx_desc_ptr);
 	efx_writeo_table(efx, &tx_desc_ptr, efx->type->txd_ptr_tbl_base,
@@ -595,8 +596,6 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
 		  efx_rx_queue_index(rx_queue), rx_queue->rxd.index,
 		  rx_queue->rxd.index + rx_queue->rxd.entries - 1);
 
-	rx_queue->flushed = FLUSH_NONE;
-
 	/* Pin RX descriptor ring */
 	efx_init_special_buffer(efx, &rx_queue->rxd);
 
@@ -625,9 +624,6 @@ static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue)
 	struct efx_nic *efx = rx_queue->efx;
 	efx_oword_t rx_flush_descq;
 
-	rx_queue->flushed = FLUSH_PENDING;
-
-	/* Post a flush command */
 	EFX_POPULATE_OWORD_2(rx_flush_descq,
 			     FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
 			     FRF_AZ_RX_FLUSH_DESCQ,
@@ -640,9 +636,6 @@ void efx_nic_fini_rx(struct efx_rx_queue *rx_queue)
 	efx_oword_t rx_desc_ptr;
 	struct efx_nic *efx = rx_queue->efx;
 
-	/* The queue should already have been flushed */
-	WARN_ON(rx_queue->flushed != FLUSH_DONE);
-
 	/* Remove RX descriptor ring from card */
 	EFX_ZERO_OWORD(rx_desc_ptr);
 	efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base,
@@ -660,6 +653,103 @@ void efx_nic_remove_rx(struct efx_rx_queue *rx_queue)
 
 /**************************************************************************
  *
+ * Flush handling
+ *
+ **************************************************************************/
+
+/* efx_nic_flush_queues() must be woken up when all flushes are completed,
+ * or more RX flushes can be kicked off.
+ */
+static bool efx_flush_wake(struct efx_nic *efx)
+{
+	/* Ensure that all updates are visible to efx_nic_flush_queues() */
+	smp_mb();
+
+	return (atomic_read(&efx->drain_pending) == 0 ||
+		(atomic_read(&efx->rxq_flush_outstanding) < EFX_RX_FLUSH_COUNT
+		 && atomic_read(&efx->rxq_flush_pending) > 0));
+}
+
+/* Flush all the transmit queues, and continue flushing receive queues until
+ * they're all flushed. Wait for the DRAIN events to be recieved so that there
+ * are no more RX and TX events left on any channel. */
+int efx_nic_flush_queues(struct efx_nic *efx)
+{
+	unsigned timeout = msecs_to_jiffies(5000); /* 5s for all flushes and drains */
+	struct efx_channel *channel;
+	struct efx_rx_queue *rx_queue;
+	struct efx_tx_queue *tx_queue;
+	int rc = 0;
+
+	efx->fc_disable++;
+	efx->type->prepare_flush(efx);
+
+	efx_for_each_channel(channel, efx) {
+		efx_for_each_channel_tx_queue(tx_queue, channel) {
+			atomic_inc(&efx->drain_pending);
+			efx_flush_tx_queue(tx_queue);
+		}
+		efx_for_each_channel_rx_queue(rx_queue, channel) {
+			atomic_inc(&efx->drain_pending);
+			rx_queue->flush_pending = true;
+			atomic_inc(&efx->rxq_flush_pending);
+		}
+	}
+
+	while (timeout && atomic_read(&efx->drain_pending) > 0) {
+		/* If SRIOV is enabled, then offload receive queue flushing to
+		 * the firmware (though we will still have to poll for
+		 * completion). If that fails, fall back to the old scheme.
+		 */
+		if (efx_sriov_enabled(efx)) {
+			rc = efx_mcdi_flush_rxqs(efx);
+			if (!rc)
+				goto wait;
+		}
+
+		/* The hardware supports four concurrent rx flushes, each of
+		 * which may need to be retried if there is an outstanding
+		 * descriptor fetch
+		 */
+		efx_for_each_channel(channel, efx) {
+			efx_for_each_channel_rx_queue(rx_queue, channel) {
+				if (atomic_read(&efx->rxq_flush_outstanding) >=
+				    EFX_RX_FLUSH_COUNT)
+					break;
+
+				if (rx_queue->flush_pending) {
+					rx_queue->flush_pending = false;
+					atomic_dec(&efx->rxq_flush_pending);
+					atomic_inc(&efx->rxq_flush_outstanding);
+					efx_flush_rx_queue(rx_queue);
+				}
+			}
+		}
+
+	wait:
+		timeout = wait_event_timeout(efx->flush_wq, efx_flush_wake(efx),
+					     timeout);
+	}
+
+	if (atomic_read(&efx->drain_pending)) {
+		netif_err(efx, hw, efx->net_dev, "failed to flush %d queues "
+			  "(rx %d+%d)\n", atomic_read(&efx->drain_pending),
+			  atomic_read(&efx->rxq_flush_outstanding),
+			  atomic_read(&efx->rxq_flush_pending));
+		rc = -ETIMEDOUT;
+
+		atomic_set(&efx->drain_pending, 0);
+		atomic_set(&efx->rxq_flush_pending, 0);
+		atomic_set(&efx->rxq_flush_outstanding, 0);
+	}
+
+	efx->fc_disable--;
+
+	return rc;
+}
+
+/**************************************************************************
+ *
  * Event queue processing
  * Event queues are processed by per-channel tasklets.
  *
@@ -682,7 +772,8 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel)
 }
 
 /* Use HW to insert a SW defined event */
-static void efx_generate_event(struct efx_channel *channel, efx_qword_t *event)
+void efx_generate_event(struct efx_nic *efx, unsigned int evq,
+			efx_qword_t *event)
 {
 	efx_oword_t drv_ev_reg;
 
@@ -692,8 +783,18 @@ static void efx_generate_event(struct efx_channel *channel, efx_qword_t *event)
 	drv_ev_reg.u32[1] = event->u32[1];
 	drv_ev_reg.u32[2] = 0;
 	drv_ev_reg.u32[3] = 0;
-	EFX_SET_OWORD_FIELD(drv_ev_reg, FRF_AZ_DRV_EV_QID, channel->channel);
-	efx_writeo(channel->efx, &drv_ev_reg, FR_AZ_DRV_EV);
+	EFX_SET_OWORD_FIELD(drv_ev_reg, FRF_AZ_DRV_EV_QID, evq);
+	efx_writeo(efx, &drv_ev_reg, FR_AZ_DRV_EV);
+}
+
+static void efx_magic_event(struct efx_channel *channel, u32 magic)
+{
+	efx_qword_t event;
+
+	EFX_POPULATE_QWORD_2(event, FSF_AZ_EV_CODE,
+			     FSE_AZ_EV_CODE_DRV_GEN_EV,
+			     FSF_AZ_DRV_GEN_EV_MAGIC, magic);
+	efx_generate_event(channel->efx, channel->channel, &event);
 }
 
 /* Handle a transmit completion event
@@ -710,6 +811,9 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
 	struct efx_nic *efx = channel->efx;
 	int tx_packets = 0;
 
+	if (unlikely(ACCESS_ONCE(efx->reset_pending)))
+		return 0;
+
 	if (likely(EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_COMP))) {
 		/* Transmit completion */
 		tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
@@ -726,11 +830,9 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
 		tx_queue = efx_channel_get_tx_queue(
 			channel, tx_ev_q_label % EFX_TXQ_TYPES);
 
-		if (efx_dev_registered(efx))
-			netif_tx_lock(efx->net_dev);
+		netif_tx_lock(efx->net_dev);
 		efx_notify_tx_desc(tx_queue);
-		if (efx_dev_registered(efx))
-			netif_tx_unlock(efx->net_dev);
+		netif_tx_unlock(efx->net_dev);
 	} else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) &&
 		   EFX_WORKAROUND_10727(efx)) {
 		efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
@@ -745,10 +847,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
 }
 
 /* Detect errors included in the rx_evt_pkt_ok bit. */
-static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
-				 const efx_qword_t *event,
-				 bool *rx_ev_pkt_ok,
-				 bool *discard)
+static u16 efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
+				const efx_qword_t *event)
 {
 	struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
 	struct efx_nic *efx = rx_queue->efx;
@@ -793,15 +893,11 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 			++channel->n_rx_tcp_udp_chksum_err;
 	}
 
-	/* The frame must be discarded if any of these are true. */
-	*discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib |
-		    rx_ev_tobe_disc | rx_ev_pause_frm);
-
 	/* TOBE_DISC is expected on unicast mismatches; don't print out an
 	 * error message.  FRM_TRUNC indicates RXDP dropped the packet due
 	 * to a FIFO overflow.
 	 */
-#ifdef EFX_ENABLE_DEBUG
+#ifdef DEBUG
 	if (rx_ev_other_err && net_ratelimit()) {
 		netif_dbg(efx, rx_err, efx->net_dev,
 			  " RX queue %d unexpected RX event "
@@ -819,6 +915,11 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
 			  rx_ev_pause_frm ? " [PAUSE]" : "");
 	}
 #endif
+
+	/* The frame must be discarded if any of these are true. */
+	return (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib |
+		rx_ev_tobe_disc | rx_ev_pause_frm) ?
+		EFX_RX_PKT_DISCARD : 0;
 }
 
 /* Handle receive events that are not in-order. */
@@ -851,8 +952,13 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
 	unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt;
 	unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt;
 	unsigned expected_ptr;
-	bool rx_ev_pkt_ok, discard = false, checksummed;
+	bool rx_ev_pkt_ok;
+	u16 flags;
 	struct efx_rx_queue *rx_queue;
+	struct efx_nic *efx = channel->efx;
+
+	if (unlikely(ACCESS_ONCE(efx->reset_pending)))
+		return;
 
 	/* Basic packet information */
 	rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT);
@@ -874,12 +980,11 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
 		/* If packet is marked as OK and packet type is TCP/IP or
 		 * UDP/IP, then we can rely on the hardware checksum.
 		 */
-		checksummed =
-			rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
-			rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP;
+		flags = (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
+			 rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP) ?
+			EFX_RX_PKT_CSUMMED : 0;
 	} else {
-		efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard);
-		checksummed = false;
+		flags = efx_handle_rx_not_ok(rx_queue, event);
 	}
 
 	/* Detect multicast packets that didn't match the filter */
@@ -890,35 +995,111 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
 
 		if (unlikely(!rx_ev_mcast_hash_match)) {
 			++channel->n_rx_mcast_mismatch;
-			discard = true;
+			flags |= EFX_RX_PKT_DISCARD;
 		}
 	}
 
 	channel->irq_mod_score += 2;
 
 	/* Handle received packet */
-	efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
-		      checksummed, discard);
+	efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, flags);
+}
+
+/* If this flush done event corresponds to a &struct efx_tx_queue, then
+ * send an %EFX_CHANNEL_MAGIC_TX_DRAIN event to drain the event queue
+ * of all transmit completions.
+ */
+static void
+efx_handle_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+{
+	struct efx_tx_queue *tx_queue;
+	int qid;
+
+	qid = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA);
+	if (qid < EFX_TXQ_TYPES * efx->n_tx_channels) {
+		tx_queue = efx_get_tx_queue(efx, qid / EFX_TXQ_TYPES,
+					    qid % EFX_TXQ_TYPES);
+
+		efx_magic_event(tx_queue->channel,
+				EFX_CHANNEL_MAGIC_TX_DRAIN(tx_queue));
+	}
+}
+
+/* If this flush done event corresponds to a &struct efx_rx_queue: If the flush
+ * was succesful then send an %EFX_CHANNEL_MAGIC_RX_DRAIN, otherwise add
+ * the RX queue back to the mask of RX queues in need of flushing.
+ */
+static void
+efx_handle_rx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+{
+	struct efx_channel *channel;
+	struct efx_rx_queue *rx_queue;
+	int qid;
+	bool failed;
+
+	qid = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
+	failed = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
+	if (qid >= efx->n_channels)
+		return;
+	channel = efx_get_channel(efx, qid);
+	if (!efx_channel_has_rx_queue(channel))
+		return;
+	rx_queue = efx_channel_get_rx_queue(channel);
+
+	if (failed) {
+		netif_info(efx, hw, efx->net_dev,
+			   "RXQ %d flush retry\n", qid);
+		rx_queue->flush_pending = true;
+		atomic_inc(&efx->rxq_flush_pending);
+	} else {
+		efx_magic_event(efx_rx_queue_channel(rx_queue),
+				EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue));
+	}
+	atomic_dec(&efx->rxq_flush_outstanding);
+	if (efx_flush_wake(efx))
+		wake_up(&efx->flush_wq);
+}
+
+static void
+efx_handle_drain_event(struct efx_channel *channel)
+{
+	struct efx_nic *efx = channel->efx;
+
+	WARN_ON(atomic_read(&efx->drain_pending) == 0);
+	atomic_dec(&efx->drain_pending);
+	if (efx_flush_wake(efx))
+		wake_up(&efx->flush_wq);
 }
 
 static void
 efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
 {
 	struct efx_nic *efx = channel->efx;
-	unsigned code;
+	struct efx_rx_queue *rx_queue =
+		efx_channel_has_rx_queue(channel) ?
+		efx_channel_get_rx_queue(channel) : NULL;
+	unsigned magic, code;
 
-	code = EFX_QWORD_FIELD(*event, FSF_AZ_DRV_GEN_EV_MAGIC);
-	if (code == EFX_CHANNEL_MAGIC_TEST(channel))
-		; /* ignore */
-	else if (code == EFX_CHANNEL_MAGIC_FILL(channel))
+	magic = EFX_QWORD_FIELD(*event, FSF_AZ_DRV_GEN_EV_MAGIC);
+	code = _EFX_CHANNEL_MAGIC_CODE(magic);
+
+	if (magic == EFX_CHANNEL_MAGIC_TEST(channel)) {
+		/* ignore */
+	} else if (rx_queue && magic == EFX_CHANNEL_MAGIC_FILL(rx_queue)) {
 		/* The queue must be empty, so we won't receive any rx
 		 * events, so efx_process_channel() won't refill the
 		 * queue. Refill it here */
-		efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
-	else
+		efx_fast_push_rx_descriptors(rx_queue);
+	} else if (rx_queue && magic == EFX_CHANNEL_MAGIC_RX_DRAIN(rx_queue)) {
+		rx_queue->enabled = false;
+		efx_handle_drain_event(channel);
+	} else if (code == _EFX_CHANNEL_MAGIC_TX_DRAIN) {
+		efx_handle_drain_event(channel);
+	} else {
 		netif_dbg(efx, hw, efx->net_dev, "channel %d received "
 			  "generated event "EFX_QWORD_FMT"\n",
 			  channel->channel, EFX_QWORD_VAL(*event));
+	}
 }
 
 static void
@@ -935,10 +1116,14 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
 	case FSE_AZ_TX_DESCQ_FLS_DONE_EV:
 		netif_vdbg(efx, hw, efx->net_dev, "channel %d TXQ %d flushed\n",
 			   channel->channel, ev_sub_data);
+		efx_handle_tx_flush_done(efx, event);
+		efx_sriov_tx_flush_done(efx, event);
 		break;
 	case FSE_AZ_RX_DESCQ_FLS_DONE_EV:
 		netif_vdbg(efx, hw, efx->net_dev, "channel %d RXQ %d flushed\n",
 			   channel->channel, ev_sub_data);
+		efx_handle_rx_flush_done(efx, event);
+		efx_sriov_rx_flush_done(efx, event);
 		break;
 	case FSE_AZ_EVQ_INIT_DONE_EV:
 		netif_dbg(efx, hw, efx->net_dev,
@@ -970,16 +1155,24 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
 				   RESET_TYPE_DISABLE);
 		break;
 	case FSE_BZ_RX_DSC_ERROR_EV:
-		netif_err(efx, rx_err, efx->net_dev,
-			  "RX DMA Q %d reports descriptor fetch error."
-			  " RX Q %d is disabled.\n", ev_sub_data, ev_sub_data);
-		efx_schedule_reset(efx, RESET_TYPE_RX_DESC_FETCH);
+		if (ev_sub_data < EFX_VI_BASE) {
+			netif_err(efx, rx_err, efx->net_dev,
+				  "RX DMA Q %d reports descriptor fetch error."
+				  " RX Q %d is disabled.\n", ev_sub_data,
+				  ev_sub_data);
+			efx_schedule_reset(efx, RESET_TYPE_RX_DESC_FETCH);
+		} else
+			efx_sriov_desc_fetch_err(efx, ev_sub_data);
 		break;
 	case FSE_BZ_TX_DSC_ERROR_EV:
-		netif_err(efx, tx_err, efx->net_dev,
-			  "TX DMA Q %d reports descriptor fetch error."
-			  " TX Q %d is disabled.\n", ev_sub_data, ev_sub_data);
-		efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
+		if (ev_sub_data < EFX_VI_BASE) {
+			netif_err(efx, tx_err, efx->net_dev,
+				  "TX DMA Q %d reports descriptor fetch error."
+				  " TX Q %d is disabled.\n", ev_sub_data,
+				  ev_sub_data);
+			efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH);
+		} else
+			efx_sriov_desc_fetch_err(efx, ev_sub_data);
 		break;
 	default:
 		netif_vdbg(efx, hw, efx->net_dev,
@@ -1039,6 +1232,9 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
 		case FSE_AZ_EV_CODE_DRIVER_EV:
 			efx_handle_driver_event(channel, &event);
 			break;
+		case FSE_CZ_EV_CODE_USER_EV:
+			efx_sriov_event(channel, &event);
+			break;
 		case FSE_CZ_EV_CODE_MCDI_EV:
 			efx_mcdi_process_event(channel, &event);
 			break;
@@ -1139,161 +1335,13 @@ void efx_nic_remove_eventq(struct efx_channel *channel)
 
 void efx_nic_generate_test_event(struct efx_channel *channel)
 {
-	unsigned int magic = EFX_CHANNEL_MAGIC_TEST(channel);
-	efx_qword_t test_event;
-
-	EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE,
-			     FSE_AZ_EV_CODE_DRV_GEN_EV,
-			     FSF_AZ_DRV_GEN_EV_MAGIC, magic);
-	efx_generate_event(channel, &test_event);
+	efx_magic_event(channel, EFX_CHANNEL_MAGIC_TEST(channel));
 }
 
-void efx_nic_generate_fill_event(struct efx_channel *channel)
+void efx_nic_generate_fill_event(struct efx_rx_queue *rx_queue)
 {
-	unsigned int magic = EFX_CHANNEL_MAGIC_FILL(channel);
-	efx_qword_t test_event;
-
-	EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE,
-			     FSE_AZ_EV_CODE_DRV_GEN_EV,
-			     FSF_AZ_DRV_GEN_EV_MAGIC, magic);
-	efx_generate_event(channel, &test_event);
-}
-
-/**************************************************************************
- *
- * Flush handling
- *
- **************************************************************************/
-
-
-static void efx_poll_flush_events(struct efx_nic *efx)
-{
-	struct efx_channel *channel = efx_get_channel(efx, 0);
-	struct efx_tx_queue *tx_queue;
-	struct efx_rx_queue *rx_queue;
-	unsigned int read_ptr = channel->eventq_read_ptr;
-	unsigned int end_ptr = read_ptr + channel->eventq_mask - 1;
-
-	do {
-		efx_qword_t *event = efx_event(channel, read_ptr);
-		int ev_code, ev_sub_code, ev_queue;
-		bool ev_failed;
-
-		if (!efx_event_present(event))
-			break;
-
-		ev_code = EFX_QWORD_FIELD(*event, FSF_AZ_EV_CODE);
-		ev_sub_code = EFX_QWORD_FIELD(*event,
-					      FSF_AZ_DRIVER_EV_SUBCODE);
-		if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
-		    ev_sub_code == FSE_AZ_TX_DESCQ_FLS_DONE_EV) {
-			ev_queue = EFX_QWORD_FIELD(*event,
-						   FSF_AZ_DRIVER_EV_SUBDATA);
-			if (ev_queue < EFX_TXQ_TYPES * efx->n_tx_channels) {
-				tx_queue = efx_get_tx_queue(
-					efx, ev_queue / EFX_TXQ_TYPES,
-					ev_queue % EFX_TXQ_TYPES);
-				tx_queue->flushed = FLUSH_DONE;
-			}
-		} else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
-			   ev_sub_code == FSE_AZ_RX_DESCQ_FLS_DONE_EV) {
-			ev_queue = EFX_QWORD_FIELD(
-				*event, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
-			ev_failed = EFX_QWORD_FIELD(
-				*event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
-			if (ev_queue < efx->n_rx_channels) {
-				rx_queue = efx_get_rx_queue(efx, ev_queue);
-				rx_queue->flushed =
-					ev_failed ? FLUSH_FAILED : FLUSH_DONE;
-			}
-		}
-
-		/* We're about to destroy the queue anyway, so
-		 * it's ok to throw away every non-flush event */
-		EFX_SET_QWORD(*event);
-
-		++read_ptr;
-	} while (read_ptr != end_ptr);
-
-	channel->eventq_read_ptr = read_ptr;
-}
-
-/* Handle tx and rx flushes at the same time, since they run in
- * parallel in the hardware and there's no reason for us to
- * serialise them */
-int efx_nic_flush_queues(struct efx_nic *efx)
-{
-	struct efx_channel *channel;
-	struct efx_rx_queue *rx_queue;
-	struct efx_tx_queue *tx_queue;
-	int i, tx_pending, rx_pending;
-
-	/* If necessary prepare the hardware for flushing */
-	efx->type->prepare_flush(efx);
-
-	/* Flush all tx queues in parallel */
-	efx_for_each_channel(channel, efx) {
-		efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
-			if (tx_queue->initialised)
-				efx_flush_tx_queue(tx_queue);
-		}
-	}
-
-	/* The hardware supports four concurrent rx flushes, each of which may
-	 * need to be retried if there is an outstanding descriptor fetch */
-	for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) {
-		rx_pending = tx_pending = 0;
-		efx_for_each_channel(channel, efx) {
-			efx_for_each_channel_rx_queue(rx_queue, channel) {
-				if (rx_queue->flushed == FLUSH_PENDING)
-					++rx_pending;
-			}
-		}
-		efx_for_each_channel(channel, efx) {
-			efx_for_each_channel_rx_queue(rx_queue, channel) {
-				if (rx_pending == EFX_RX_FLUSH_COUNT)
-					break;
-				if (rx_queue->flushed == FLUSH_FAILED ||
-				    rx_queue->flushed == FLUSH_NONE) {
-					efx_flush_rx_queue(rx_queue);
-					++rx_pending;
-				}
-			}
-			efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
-				if (tx_queue->initialised &&
-				    tx_queue->flushed != FLUSH_DONE)
-					++tx_pending;
-			}
-		}
-
-		if (rx_pending == 0 && tx_pending == 0)
-			return 0;
-
-		msleep(EFX_FLUSH_INTERVAL);
-		efx_poll_flush_events(efx);
-	}
-
-	/* Mark the queues as all flushed. We're going to return failure
-	 * leading to a reset, or fake up success anyway */
-	efx_for_each_channel(channel, efx) {
-		efx_for_each_possible_channel_tx_queue(tx_queue, channel) {
-			if (tx_queue->initialised &&
-			    tx_queue->flushed != FLUSH_DONE)
-				netif_err(efx, hw, efx->net_dev,
-					  "tx queue %d flush command timed out\n",
-					  tx_queue->queue);
-			tx_queue->flushed = FLUSH_DONE;
-		}
-		efx_for_each_channel_rx_queue(rx_queue, channel) {
-			if (rx_queue->flushed != FLUSH_DONE)
-				netif_err(efx, hw, efx->net_dev,
-					  "rx queue %d flush command timed out\n",
-					  efx_rx_queue_index(rx_queue));
-			rx_queue->flushed = FLUSH_DONE;
-		}
-	}
-
-	return -ETIMEDOUT;
+	efx_magic_event(efx_rx_queue_channel(rx_queue),
+			EFX_CHANNEL_MAGIC_FILL(rx_queue));
 }
 
 /**************************************************************************
@@ -1311,7 +1359,7 @@ static inline void efx_nic_interrupts(struct efx_nic *efx,
 	efx_oword_t int_en_reg_ker;
 
 	EFX_POPULATE_OWORD_3(int_en_reg_ker,
-			     FRF_AZ_KER_INT_LEVE_SEL, efx->fatal_irq_level,
+			     FRF_AZ_KER_INT_LEVE_SEL, efx->irq_level,
 			     FRF_AZ_KER_INT_KER, force,
 			     FRF_AZ_DRV_INT_EN_KER, enabled);
 	efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER);
@@ -1319,18 +1367,10 @@ static inline void efx_nic_interrupts(struct efx_nic *efx,
 
 void efx_nic_enable_interrupts(struct efx_nic *efx)
 {
-	struct efx_channel *channel;
-
 	EFX_ZERO_OWORD(*((efx_oword_t *) efx->irq_status.addr));
 	wmb(); /* Ensure interrupt vector is clear before interrupts enabled */
 
-	/* Enable interrupts */
 	efx_nic_interrupts(efx, true, false);
-
-	/* Force processing of all the channels to get the EVQ RPTRs up to
-	   date */
-	efx_for_each_channel(channel, efx)
-		efx_schedule_channel(channel);
 }
 
 void efx_nic_disable_interrupts(struct efx_nic *efx)
@@ -1427,11 +1467,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
 	efx_readd(efx, &reg, FR_BZ_INT_ISR0);
 	queues = EFX_EXTRACT_DWORD(reg, 0, 31);
 
-	/* Check to see if we have a serious error condition */
-	if (queues & (1U << efx->fatal_irq_level)) {
+	/* Handle non-event-queue sources */
+	if (queues & (1U << efx->irq_level)) {
 		syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
 		if (unlikely(syserr))
 			return efx_nic_fatal_interrupt(efx);
+		efx->last_irq_cpu = raw_smp_processor_id();
 	}
 
 	if (queues != 0) {
@@ -1441,7 +1482,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
 		/* Schedule processing of any interrupting queues */
 		efx_for_each_channel(channel, efx) {
 			if (queues & 1)
-				efx_schedule_channel(channel);
+				efx_schedule_channel_irq(channel);
 			queues >>= 1;
 		}
 		result = IRQ_HANDLED;
@@ -1458,18 +1499,16 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
 		efx_for_each_channel(channel, efx) {
 			event = efx_event(channel, channel->eventq_read_ptr);
 			if (efx_event_present(event))
-				efx_schedule_channel(channel);
+				efx_schedule_channel_irq(channel);
 			else
 				efx_nic_eventq_read_ack(channel);
 		}
 	}
 
-	if (result == IRQ_HANDLED) {
-		efx->last_irq_cpu = raw_smp_processor_id();
+	if (result == IRQ_HANDLED)
 		netif_vdbg(efx, intr, efx->net_dev,
 			   "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
 			   irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
-	}
 
 	return result;
 }
@@ -1488,20 +1527,20 @@ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
 	efx_oword_t *int_ker = efx->irq_status.addr;
 	int syserr;
 
-	efx->last_irq_cpu = raw_smp_processor_id();
 	netif_vdbg(efx, intr, efx->net_dev,
 		   "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n",
 		   irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker));
 
-	/* Check to see if we have a serious error condition */
-	if (channel->channel == efx->fatal_irq_level) {
+	/* Handle non-event-queue sources */
+	if (channel->channel == efx->irq_level) {
 		syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT);
 		if (unlikely(syserr))
 			return efx_nic_fatal_interrupt(efx);
+		efx->last_irq_cpu = raw_smp_processor_id();
 	}
 
 	/* Schedule processing of the channel */
-	efx_schedule_channel(channel);
+	efx_schedule_channel_irq(channel);
 
 	return IRQ_HANDLED;
 }
@@ -1598,6 +1637,58 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
 		free_irq(efx->legacy_irq, efx);
 }
 
+/* Looks at available SRAM resources and works out how many queues we
+ * can support, and where things like descriptor caches should live.
+ *
+ * SRAM is split up as follows:
+ * 0                          buftbl entries for channels
+ * efx->vf_buftbl_base        buftbl entries for SR-IOV
+ * efx->rx_dc_base            RX descriptor caches
+ * efx->tx_dc_base            TX descriptor caches
+ */
+void efx_nic_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw)
+{
+	unsigned vi_count, buftbl_min;
+
+	/* Account for the buffer table entries backing the datapath channels
+	 * and the descriptor caches for those channels.
+	 */
+	buftbl_min = ((efx->n_rx_channels * EFX_MAX_DMAQ_SIZE +
+		       efx->n_tx_channels * EFX_TXQ_TYPES * EFX_MAX_DMAQ_SIZE +
+		       efx->n_channels * EFX_MAX_EVQ_SIZE)
+		      * sizeof(efx_qword_t) / EFX_BUF_SIZE);
+	vi_count = max(efx->n_channels, efx->n_tx_channels * EFX_TXQ_TYPES);
+
+#ifdef CONFIG_SFC_SRIOV
+	if (efx_sriov_wanted(efx)) {
+		unsigned vi_dc_entries, buftbl_free, entries_per_vf, vf_limit;
+
+		efx->vf_buftbl_base = buftbl_min;
+
+		vi_dc_entries = RX_DC_ENTRIES + TX_DC_ENTRIES;
+		vi_count = max(vi_count, EFX_VI_BASE);
+		buftbl_free = (sram_lim_qw - buftbl_min -
+			       vi_count * vi_dc_entries);
+
+		entries_per_vf = ((vi_dc_entries + EFX_VF_BUFTBL_PER_VI) *
+				  efx_vf_size(efx));
+		vf_limit = min(buftbl_free / entries_per_vf,
+			       (1024U - EFX_VI_BASE) >> efx->vi_scale);
+
+		if (efx->vf_count > vf_limit) {
+			netif_err(efx, probe, efx->net_dev,
+				  "Reducing VF count from from %d to %d\n",
+				  efx->vf_count, vf_limit);
+			efx->vf_count = vf_limit;
+		}
+		vi_count += efx->vf_count * efx_vf_size(efx);
+	}
+#endif
+
+	efx->tx_dc_base = sram_lim_qw - vi_count * TX_DC_ENTRIES;
+	efx->rx_dc_base = efx->tx_dc_base - vi_count * RX_DC_ENTRIES;
+}
+
 u32 efx_nic_fpga_ver(struct efx_nic *efx)
 {
 	efx_oword_t altera_build;
@@ -1610,11 +1701,9 @@ void efx_nic_init_common(struct efx_nic *efx)
 	efx_oword_t temp;
 
 	/* Set positions of descriptor caches in SRAM. */
-	EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR,
-			     efx->type->tx_dc_base / 8);
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_TX_DC_BASE_ADR, efx->tx_dc_base);
 	efx_writeo(efx, &temp, FR_AZ_SRM_TX_DC_CFG);
-	EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR,
-			     efx->type->rx_dc_base / 8);
+	EFX_POPULATE_OWORD_1(temp, FRF_AZ_SRM_RX_DC_BASE_ADR, efx->rx_dc_base);
 	efx_writeo(efx, &temp, FR_AZ_SRM_RX_DC_CFG);
 
 	/* Set TX descriptor cache size. */
@@ -1640,10 +1729,10 @@ void efx_nic_init_common(struct efx_nic *efx)
 
 	if (EFX_WORKAROUND_17213(efx) && !EFX_INT_MODE_USE_MSI(efx))
 		/* Use an interrupt level unused by event queues */
-		efx->fatal_irq_level = 0x1f;
+		efx->irq_level = 0x1f;
 	else
 		/* Use a valid MSI-X vector */
-		efx->fatal_irq_level = 0;
+		efx->irq_level = 0;
 
 	/* Enable all the genuinely fatal interrupts.  (They are still
 	 * masked by the overall interrupt mask, controlled by
@@ -1837,7 +1926,7 @@ struct efx_nic_reg_table {
 	REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev,	\
 	step, rows							\
 }
-#define REGISTER_TABLE(name, min_rev, max_rev) 				\
+#define REGISTER_TABLE(name, min_rev, max_rev)				\
 	REGISTER_TABLE_DIMENSIONS(					\
 		name, FR_ ## min_rev ## max_rev ## _ ## name,		\
 		min_rev, max_rev,					\
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index 5fb24d3..246c414 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -65,6 +65,11 @@ enum {
 #define FALCON_GMAC_LOOPBACKS			\
 	(1 << LOOPBACK_GMAC)
 
+/* Alignment of PCIe DMA boundaries (4KB) */
+#define EFX_PAGE_SIZE	4096
+/* Size and alignment of buffer table entries (same) */
+#define EFX_BUF_SIZE	EFX_PAGE_SIZE
+
 /**
  * struct falcon_board_type - board operations and type information
  * @id: Board type id, as found in NVRAM
@@ -144,12 +149,115 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx)
  * struct siena_nic_data - Siena NIC state
  * @mcdi: Management-Controller-to-Driver Interface
  * @wol_filter_id: Wake-on-LAN packet filter id
+ * @hwmon: Hardware monitor state
  */
 struct siena_nic_data {
 	struct efx_mcdi_iface mcdi;
 	int wol_filter_id;
+#ifdef CONFIG_SFC_MCDI_MON
+	struct efx_mcdi_mon hwmon;
+#endif
 };
 
+#ifdef CONFIG_SFC_MCDI_MON
+static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx)
+{
+	struct siena_nic_data *nic_data;
+	EFX_BUG_ON_PARANOID(efx_nic_rev(efx) < EFX_REV_SIENA_A0);
+	nic_data = efx->nic_data;
+	return &nic_data->hwmon;
+}
+#endif
+
+/*
+ * On the SFC9000 family each port is associated with 1 PCI physical
+ * function (PF) handled by sfc and a configurable number of virtual
+ * functions (VFs) that may be handled by some other driver, often in
+ * a VM guest.  The queue pointer registers are mapped in both PF and
+ * VF BARs such that an 8K region provides access to a single RX, TX
+ * and event queue (collectively a Virtual Interface, VI or VNIC).
+ *
+ * The PF has access to all 1024 VIs while VFs are mapped to VIs
+ * according to VI_BASE and VI_SCALE: VF i has access to VIs numbered
+ * in range [VI_BASE + i << VI_SCALE, VI_BASE + i + 1 << VI_SCALE).
+ * The number of VIs and the VI_SCALE value are configurable but must
+ * be established at boot time by firmware.
+ */
+
+/* Maximum VI_SCALE parameter supported by Siena */
+#define EFX_VI_SCALE_MAX 6
+/* Base VI to use for SR-IOV. Must be aligned to (1 << EFX_VI_SCALE_MAX),
+ * so this is the smallest allowed value. */
+#define EFX_VI_BASE 128U
+/* Maximum number of VFs allowed */
+#define EFX_VF_COUNT_MAX 127
+/* Limit EVQs on VFs to be only 8k to reduce buffer table reservation */
+#define EFX_MAX_VF_EVQ_SIZE 8192UL
+/* The number of buffer table entries reserved for each VI on a VF */
+#define EFX_VF_BUFTBL_PER_VI					\
+	((EFX_MAX_VF_EVQ_SIZE + 2 * EFX_MAX_DMAQ_SIZE) *	\
+	 sizeof(efx_qword_t) / EFX_BUF_SIZE)
+
+#ifdef CONFIG_SFC_SRIOV
+
+static inline bool efx_sriov_wanted(struct efx_nic *efx)
+{
+	return efx->vf_count != 0;
+}
+static inline bool efx_sriov_enabled(struct efx_nic *efx)
+{
+	return efx->vf_init_count != 0;
+}
+static inline unsigned int efx_vf_size(struct efx_nic *efx)
+{
+	return 1 << efx->vi_scale;
+}
+
+extern int efx_init_sriov(void);
+extern void efx_sriov_probe(struct efx_nic *efx);
+extern int efx_sriov_init(struct efx_nic *efx);
+extern void efx_sriov_mac_address_changed(struct efx_nic *efx);
+extern void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event);
+extern void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event);
+extern void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event);
+extern void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq);
+extern void efx_sriov_flr(struct efx_nic *efx, unsigned flr);
+extern void efx_sriov_reset(struct efx_nic *efx);
+extern void efx_sriov_fini(struct efx_nic *efx);
+extern void efx_fini_sriov(void);
+
+#else
+
+static inline bool efx_sriov_wanted(struct efx_nic *efx) { return false; }
+static inline bool efx_sriov_enabled(struct efx_nic *efx) { return false; }
+static inline unsigned int efx_vf_size(struct efx_nic *efx) { return 0; }
+
+static inline int efx_init_sriov(void) { return 0; }
+static inline void efx_sriov_probe(struct efx_nic *efx) {}
+static inline int efx_sriov_init(struct efx_nic *efx) { return -EOPNOTSUPP; }
+static inline void efx_sriov_mac_address_changed(struct efx_nic *efx) {}
+static inline void efx_sriov_tx_flush_done(struct efx_nic *efx,
+					   efx_qword_t *event) {}
+static inline void efx_sriov_rx_flush_done(struct efx_nic *efx,
+					   efx_qword_t *event) {}
+static inline void efx_sriov_event(struct efx_channel *channel,
+				   efx_qword_t *event) {}
+static inline void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq) {}
+static inline void efx_sriov_flr(struct efx_nic *efx, unsigned flr) {}
+static inline void efx_sriov_reset(struct efx_nic *efx) {}
+static inline void efx_sriov_fini(struct efx_nic *efx) {}
+static inline void efx_fini_sriov(void) {}
+
+#endif
+
+extern int efx_sriov_set_vf_mac(struct net_device *dev, int vf, u8 *mac);
+extern int efx_sriov_set_vf_vlan(struct net_device *dev, int vf,
+				 u16 vlan, u8 qos);
+extern int efx_sriov_get_vf_config(struct net_device *dev, int vf,
+				   struct ifla_vf_info *ivf);
+extern int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf,
+				     bool spoofchk);
+
 extern const struct efx_nic_type falcon_a1_nic_type;
 extern const struct efx_nic_type falcon_b0_nic_type;
 extern const struct efx_nic_type siena_a0_nic_type;
@@ -176,6 +284,7 @@ extern void efx_nic_init_rx(struct efx_rx_queue *rx_queue);
 extern void efx_nic_fini_rx(struct efx_rx_queue *rx_queue);
 extern void efx_nic_remove_rx(struct efx_rx_queue *rx_queue);
 extern void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue);
+extern void efx_nic_generate_fill_event(struct efx_rx_queue *rx_queue);
 
 /* Event data path */
 extern int efx_nic_probe_eventq(struct efx_channel *channel);
@@ -189,12 +298,14 @@ extern bool efx_nic_event_present(struct efx_channel *channel);
 /* MAC/PHY */
 extern void falcon_drain_tx_fifo(struct efx_nic *efx);
 extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx);
+extern bool falcon_xmac_check_fault(struct efx_nic *efx);
+extern int falcon_reconfigure_xmac(struct efx_nic *efx);
+extern void falcon_update_stats_xmac(struct efx_nic *efx);
 
 /* Interrupts and test events */
 extern int efx_nic_init_interrupt(struct efx_nic *efx);
 extern void efx_nic_enable_interrupts(struct efx_nic *efx);
 extern void efx_nic_generate_test_event(struct efx_channel *channel);
-extern void efx_nic_generate_fill_event(struct efx_channel *channel);
 extern void efx_nic_generate_interrupt(struct efx_nic *efx);
 extern void efx_nic_disable_interrupts(struct efx_nic *efx);
 extern void efx_nic_fini_interrupt(struct efx_nic *efx);
@@ -202,15 +313,14 @@ extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx);
 extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id);
 extern void falcon_irq_ack_a1(struct efx_nic *efx);
 
-#define EFX_IRQ_MOD_RESOLUTION	5
-#define EFX_IRQ_MOD_MAX		0x1000
-
 /* Global Resources */
 extern int efx_nic_flush_queues(struct efx_nic *efx);
 extern void falcon_start_nic_stats(struct efx_nic *efx);
 extern void falcon_stop_nic_stats(struct efx_nic *efx);
 extern void falcon_setup_xaui(struct efx_nic *efx);
 extern int falcon_reset_xaui(struct efx_nic *efx);
+extern void
+efx_nic_dimension_resources(struct efx_nic *efx, unsigned sram_lim_qw);
 extern void efx_nic_init_common(struct efx_nic *efx);
 extern void efx_nic_push_rx_indir_table(struct efx_nic *efx);
 
@@ -264,8 +374,8 @@ extern void efx_nic_get_regs(struct efx_nic *efx, void *buf);
 #define MAC_DATA_LBN 0
 #define MAC_DATA_WIDTH 32
 
-extern void efx_nic_generate_event(struct efx_channel *channel,
-				   efx_qword_t *event);
+extern void efx_generate_event(struct efx_nic *efx, unsigned int evq,
+			       efx_qword_t *event);
 
 extern void falcon_poll_xmac(struct efx_nic *efx);
 
diff --git a/drivers/net/ethernet/sfc/qt202x_phy.c b/drivers/net/ethernet/sfc/qt202x_phy.c
index 7ad97e3..8a7caf88 100644
--- a/drivers/net/ethernet/sfc/qt202x_phy.c
+++ b/drivers/net/ethernet/sfc/qt202x_phy.c
@@ -47,7 +47,7 @@
 #define PMA_PMD_FTX_STATIC_LBN	13
 #define PMA_PMD_VEND1_REG	0xc001
 #define PMA_PMD_VEND1_LBTXD_LBN	15
-#define PCS_VEND1_REG	   	0xc000
+#define PCS_VEND1_REG		0xc000
 #define PCS_VEND1_LBTXD_LBN	5
 
 void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode)
@@ -453,9 +453,9 @@ const struct efx_phy_operations falcon_qt202x_phy_ops = {
 	.probe		 = qt202x_phy_probe,
 	.init		 = qt202x_phy_init,
 	.reconfigure	 = qt202x_phy_reconfigure,
-	.poll	     	 = qt202x_phy_poll,
+	.poll		 = qt202x_phy_poll,
 	.fini		 = efx_port_dummy_op_void,
-	.remove	  	 = qt202x_phy_remove,
+	.remove		 = qt202x_phy_remove,
 	.get_settings	 = qt202x_phy_get_settings,
 	.set_settings	 = efx_mdio_set_settings,
 	.test_alive	 = efx_mdio_test_alive,
diff --git a/drivers/net/ethernet/sfc/regs.h b/drivers/net/ethernet/sfc/regs.h
index cc2c86b..ade4c4d 100644
--- a/drivers/net/ethernet/sfc/regs.h
+++ b/drivers/net/ethernet/sfc/regs.h
@@ -2446,8 +2446,8 @@
 #define	FRF_CZ_RMFT_RXQ_ID_WIDTH 12
 #define	FRF_CZ_RMFT_WILDCARD_MATCH_LBN 60
 #define	FRF_CZ_RMFT_WILDCARD_MATCH_WIDTH 1
-#define	FRF_CZ_RMFT_DEST_MAC_LBN 16
-#define	FRF_CZ_RMFT_DEST_MAC_WIDTH 44
+#define	FRF_CZ_RMFT_DEST_MAC_LBN 12
+#define	FRF_CZ_RMFT_DEST_MAC_WIDTH 48
 #define	FRF_CZ_RMFT_VLAN_ID_LBN 0
 #define	FRF_CZ_RMFT_VLAN_ID_WIDTH 12
 
@@ -2523,8 +2523,8 @@
 #define	FRF_CZ_TMFT_TXQ_ID_WIDTH 12
 #define	FRF_CZ_TMFT_WILDCARD_MATCH_LBN 60
 #define	FRF_CZ_TMFT_WILDCARD_MATCH_WIDTH 1
-#define	FRF_CZ_TMFT_SRC_MAC_LBN 16
-#define	FRF_CZ_TMFT_SRC_MAC_WIDTH 44
+#define	FRF_CZ_TMFT_SRC_MAC_LBN 12
+#define	FRF_CZ_TMFT_SRC_MAC_WIDTH 48
 #define	FRF_CZ_TMFT_VLAN_ID_LBN 0
 #define	FRF_CZ_TMFT_VLAN_ID_WIDTH 12
 
@@ -2895,17 +2895,17 @@
 
 /* RX_MAC_FILTER_TBL0 */
 /* RMFT_DEST_MAC is wider than 32 bits */
-#define FRF_CZ_RMFT_DEST_MAC_LO_LBN 12
+#define FRF_CZ_RMFT_DEST_MAC_LO_LBN FRF_CZ_RMFT_DEST_MAC_LBN
 #define FRF_CZ_RMFT_DEST_MAC_LO_WIDTH 32
-#define FRF_CZ_RMFT_DEST_MAC_HI_LBN 44
-#define FRF_CZ_RMFT_DEST_MAC_HI_WIDTH 16
+#define FRF_CZ_RMFT_DEST_MAC_HI_LBN (FRF_CZ_RMFT_DEST_MAC_LBN + 32)
+#define FRF_CZ_RMFT_DEST_MAC_HI_WIDTH (FRF_CZ_RMFT_DEST_MAC_WIDTH - 32)
 
 /* TX_MAC_FILTER_TBL0 */
 /* TMFT_SRC_MAC is wider than 32 bits */
-#define FRF_CZ_TMFT_SRC_MAC_LO_LBN 12
+#define FRF_CZ_TMFT_SRC_MAC_LO_LBN FRF_CZ_TMFT_SRC_MAC_LBN
 #define FRF_CZ_TMFT_SRC_MAC_LO_WIDTH 32
-#define FRF_CZ_TMFT_SRC_MAC_HI_LBN 44
-#define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH 16
+#define FRF_CZ_TMFT_SRC_MAC_HI_LBN (FRF_CZ_TMFT_SRC_MAC_LBN + 32)
+#define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH (FRF_CZ_TMFT_SRC_MAC_WIDTH - 32)
 
 /* TX_PACE_TBL */
 /* Values >20 are documented as reserved, but will result in a queue going
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index aca3498..506d246 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -98,8 +98,8 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
 	/* Offset is always within one page, so we don't need to consider
 	 * the page order.
 	 */
-	return (((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) +
-		efx->type->rx_buffer_hash_size);
+	return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) +
+		efx->type->rx_buffer_hash_size;
 }
 static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
 {
@@ -108,11 +108,10 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
 
 static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf)
 {
-	if (buf->is_page)
+	if (buf->flags & EFX_RX_BUF_PAGE)
 		return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf);
 	else
-		return ((u8 *)buf->u.skb->data +
-			efx->type->rx_buffer_hash_size);
+		return (u8 *)buf->u.skb->data + efx->type->rx_buffer_hash_size;
 }
 
 static inline u32 efx_rx_buf_hash(const u8 *eh)
@@ -122,10 +121,10 @@ static inline u32 efx_rx_buf_hash(const u8 *eh)
 	return __le32_to_cpup((const __le32 *)(eh - 4));
 #else
 	const u8 *data = eh - 4;
-	return ((u32)data[0]       |
-		(u32)data[1] << 8  |
-		(u32)data[2] << 16 |
-		(u32)data[3] << 24);
+	return (u32)data[0]	  |
+	       (u32)data[1] << 8  |
+	       (u32)data[2] << 16 |
+	       (u32)data[3] << 24;
 #endif
 }
 
@@ -159,7 +158,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue)
 		/* Adjust the SKB for padding and checksum */
 		skb_reserve(skb, NET_IP_ALIGN);
 		rx_buf->len = skb_len - NET_IP_ALIGN;
-		rx_buf->is_page = false;
+		rx_buf->flags = 0;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 		rx_buf->dma_addr = pci_map_single(efx->pci_dev,
@@ -228,7 +227,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
 		rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
 		rx_buf->u.page = page;
 		rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
-		rx_buf->is_page = true;
+		rx_buf->flags = EFX_RX_BUF_PAGE;
 		++rx_queue->added_count;
 		++rx_queue->alloc_page_count;
 		++state->refcnt;
@@ -249,7 +248,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
 static void efx_unmap_rx_buffer(struct efx_nic *efx,
 				struct efx_rx_buffer *rx_buf)
 {
-	if (rx_buf->is_page && rx_buf->u.page) {
+	if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) {
 		struct efx_rx_page_state *state;
 
 		state = page_address(rx_buf->u.page);
@@ -259,7 +258,7 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
 				       efx_rx_buf_size(efx),
 				       PCI_DMA_FROMDEVICE);
 		}
-	} else if (!rx_buf->is_page && rx_buf->u.skb) {
+	} else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) {
 		pci_unmap_single(efx->pci_dev, rx_buf->dma_addr,
 				 rx_buf->len, PCI_DMA_FROMDEVICE);
 	}
@@ -268,10 +267,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
 static void efx_free_rx_buffer(struct efx_nic *efx,
 			       struct efx_rx_buffer *rx_buf)
 {
-	if (rx_buf->is_page && rx_buf->u.page) {
+	if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) {
 		__free_pages(rx_buf->u.page, efx->rx_buffer_order);
 		rx_buf->u.page = NULL;
-	} else if (!rx_buf->is_page && rx_buf->u.skb) {
+	} else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) {
 		dev_kfree_skb_any(rx_buf->u.skb);
 		rx_buf->u.skb = NULL;
 	}
@@ -311,7 +310,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue,
 	new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1);
 	new_buf->u.page = rx_buf->u.page;
 	new_buf->len = rx_buf->len;
-	new_buf->is_page = true;
+	new_buf->flags = EFX_RX_BUF_PAGE;
 	++rx_queue->added_count;
 }
 
@@ -325,7 +324,10 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
 	struct efx_rx_buffer *new_buf;
 	unsigned index;
 
-	if (rx_buf->is_page && efx->rx_buffer_len <= EFX_RX_HALF_PAGE &&
+	rx_buf->flags &= EFX_RX_BUF_PAGE;
+
+	if ((rx_buf->flags & EFX_RX_BUF_PAGE) &&
+	    efx->rx_buffer_len <= EFX_RX_HALF_PAGE &&
 	    page_count(rx_buf->u.page) == 1)
 		efx_resurrect_rx_buffer(rx_queue, rx_buf);
 
@@ -403,17 +405,15 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
 void efx_rx_slow_fill(unsigned long context)
 {
 	struct efx_rx_queue *rx_queue = (struct efx_rx_queue *)context;
-	struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
 
 	/* Post an event to cause NAPI to run and refill the queue */
-	efx_nic_generate_fill_event(channel);
+	efx_nic_generate_fill_event(rx_queue);
 	++rx_queue->slow_fill_count;
 }
 
 static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
 				     struct efx_rx_buffer *rx_buf,
-				     int len, bool *discard,
-				     bool *leak_packet)
+				     int len, bool *leak_packet)
 {
 	struct efx_nic *efx = rx_queue->efx;
 	unsigned max_len = rx_buf->len - efx->type->rx_buffer_padding;
@@ -424,7 +424,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
 	/* The packet must be discarded, but this is only a fatal error
 	 * if the caller indicated it was
 	 */
-	*discard = true;
+	rx_buf->flags |= EFX_RX_PKT_DISCARD;
 
 	if ((len > rx_buf->len) && EFX_WORKAROUND_8071(efx)) {
 		if (net_ratelimit())
@@ -437,7 +437,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
 		 * data at the end of the skb will be trashed. So
 		 * we have no choice but to leak the fragment.
 		 */
-		*leak_packet = !rx_buf->is_page;
+		*leak_packet = !(rx_buf->flags & EFX_RX_BUF_PAGE);
 		efx_schedule_reset(efx, RESET_TYPE_RX_RECOVERY);
 	} else {
 		if (net_ratelimit())
@@ -457,13 +457,13 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
  */
 static void efx_rx_packet_gro(struct efx_channel *channel,
 			      struct efx_rx_buffer *rx_buf,
-			      const u8 *eh, bool checksummed)
+			      const u8 *eh)
 {
 	struct napi_struct *napi = &channel->napi_str;
 	gro_result_t gro_result;
 
 	/* Pass the skb/page into the GRO engine */
-	if (rx_buf->is_page) {
+	if (rx_buf->flags & EFX_RX_BUF_PAGE) {
 		struct efx_nic *efx = channel->efx;
 		struct page *page = rx_buf->u.page;
 		struct sk_buff *skb;
@@ -485,8 +485,8 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
 		skb->len = rx_buf->len;
 		skb->data_len = rx_buf->len;
 		skb->truesize += rx_buf->len;
-		skb->ip_summed =
-			checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
+		skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ?
+				  CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
 
 		skb_record_rx_queue(skb, channel->channel);
 
@@ -494,7 +494,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
 	} else {
 		struct sk_buff *skb = rx_buf->u.skb;
 
-		EFX_BUG_ON_PARANOID(!checksummed);
+		EFX_BUG_ON_PARANOID(!(rx_buf->flags & EFX_RX_PKT_CSUMMED));
 		rx_buf->u.skb = NULL;
 
 		gro_result = napi_gro_receive(napi, skb);
@@ -509,7 +509,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
 }
 
 void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
-		   unsigned int len, bool checksummed, bool discard)
+		   unsigned int len, u16 flags)
 {
 	struct efx_nic *efx = rx_queue->efx;
 	struct efx_channel *channel = efx_rx_queue_channel(rx_queue);
@@ -517,6 +517,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
 	bool leak_packet = false;
 
 	rx_buf = efx_rx_buffer(rx_queue, index);
+	rx_buf->flags |= flags;
 
 	/* This allows the refill path to post another buffer.
 	 * EFX_RXD_HEAD_ROOM ensures that the slot we are using
@@ -525,18 +526,17 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
 	rx_queue->removed_count++;
 
 	/* Validate the length encoded in the event vs the descriptor pushed */
-	efx_rx_packet__check_len(rx_queue, rx_buf, len,
-				 &discard, &leak_packet);
+	efx_rx_packet__check_len(rx_queue, rx_buf, len, &leak_packet);
 
 	netif_vdbg(efx, rx_status, efx->net_dev,
 		   "RX queue %d received id %x at %llx+%x %s%s\n",
 		   efx_rx_queue_index(rx_queue), index,
 		   (unsigned long long)rx_buf->dma_addr, len,
-		   (checksummed ? " [SUMMED]" : ""),
-		   (discard ? " [DISCARD]" : ""));
+		   (rx_buf->flags & EFX_RX_PKT_CSUMMED) ? " [SUMMED]" : "",
+		   (rx_buf->flags & EFX_RX_PKT_DISCARD) ? " [DISCARD]" : "");
 
 	/* Discard packet, if instructed to do so */
-	if (unlikely(discard)) {
+	if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) {
 		if (unlikely(leak_packet))
 			channel->n_skbuff_leaks++;
 		else
@@ -563,18 +563,33 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
 	rx_buf->len = len - efx->type->rx_buffer_hash_size;
 out:
 	if (channel->rx_pkt)
-		__efx_rx_packet(channel,
-				channel->rx_pkt, channel->rx_pkt_csummed);
+		__efx_rx_packet(channel, channel->rx_pkt);
 	channel->rx_pkt = rx_buf;
-	channel->rx_pkt_csummed = checksummed;
+}
+
+static void efx_rx_deliver(struct efx_channel *channel,
+			   struct efx_rx_buffer *rx_buf)
+{
+	struct sk_buff *skb;
+
+	/* We now own the SKB */
+	skb = rx_buf->u.skb;
+	rx_buf->u.skb = NULL;
+
+	/* Set the SKB flags */
+	skb_checksum_none_assert(skb);
+
+	/* Pass the packet up */
+	netif_receive_skb(skb);
+
+	/* Update allocation strategy method */
+	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
 }
 
 /* Handle a received packet.  Second half: Touches packet payload. */
-void __efx_rx_packet(struct efx_channel *channel,
-		     struct efx_rx_buffer *rx_buf, bool checksummed)
+void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf)
 {
 	struct efx_nic *efx = channel->efx;
-	struct sk_buff *skb;
 	u8 *eh = efx_rx_buf_eh(efx, rx_buf);
 
 	/* If we're in loopback test, then pass the packet directly to the
@@ -586,8 +601,8 @@ void __efx_rx_packet(struct efx_channel *channel,
 		return;
 	}
 
-	if (!rx_buf->is_page) {
-		skb = rx_buf->u.skb;
+	if (!(rx_buf->flags & EFX_RX_BUF_PAGE)) {
+		struct sk_buff *skb = rx_buf->u.skb;
 
 		prefetch(skb_shinfo(skb));
 
@@ -605,25 +620,12 @@ void __efx_rx_packet(struct efx_channel *channel,
 	}
 
 	if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
-		checksummed = false;
-
-	if (likely(checksummed || rx_buf->is_page)) {
-		efx_rx_packet_gro(channel, rx_buf, eh, checksummed);
-		return;
-	}
+		rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
 
-	/* We now own the SKB */
-	skb = rx_buf->u.skb;
-	rx_buf->u.skb = NULL;
-
-	/* Set the SKB flags */
-	skb_checksum_none_assert(skb);
-
-	/* Pass the packet up */
-	netif_receive_skb(skb);
-
-	/* Update allocation strategy method */
-	channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
+	if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED)))
+		efx_rx_packet_gro(channel, rx_buf, eh);
+	else
+		efx_rx_deliver(channel, rx_buf);
 }
 
 void efx_rx_strategy(struct efx_channel *channel)
@@ -703,6 +705,7 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
 	rx_queue->fast_fill_limit = limit;
 
 	/* Set up RX descriptor ring */
+	rx_queue->enabled = true;
 	efx_nic_init_rx(rx_queue);
 }
 
@@ -714,6 +717,9 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue)
 	netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
 		  "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue));
 
+	/* A flush failure might have left rx_queue->enabled */
+	rx_queue->enabled = false;
+
 	del_timer_sync(&rx_queue->slow_fill);
 	efx_nic_fini_rx(rx_queue);
 
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c
index 52edd24..febe2a9 100644
--- a/drivers/net/ethernet/sfc/selftest.c
+++ b/drivers/net/ethernet/sfc/selftest.c
@@ -19,7 +19,6 @@
 #include <linux/udp.h>
 #include <linux/rtnetlink.h>
 #include <linux/slab.h>
-#include <asm/io.h>
 #include "net_driver.h"
 #include "efx.h"
 #include "nic.h"
@@ -50,7 +49,7 @@ static const char payload_msg[] =
 
 /* Interrupt mode names */
 static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX;
-static const char *efx_interrupt_mode_names[] = {
+static const char *const efx_interrupt_mode_names[] = {
 	[EFX_INT_MODE_MSIX]   = "MSI-X",
 	[EFX_INT_MODE_MSI]    = "MSI",
 	[EFX_INT_MODE_LEGACY] = "legacy",
@@ -131,6 +130,8 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
 static int efx_test_interrupts(struct efx_nic *efx,
 			       struct efx_self_tests *tests)
 {
+	int cpu;
+
 	netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n");
 	tests->interrupt = -1;
 
@@ -143,7 +144,8 @@ static int efx_test_interrupts(struct efx_nic *efx,
 	/* Wait for arrival of test interrupt. */
 	netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n");
 	schedule_timeout_uninterruptible(HZ / 10);
-	if (efx->last_irq_cpu >= 0)
+	cpu = ACCESS_ONCE(efx->last_irq_cpu);
+	if (cpu >= 0)
 		goto success;
 
 	netif_err(efx, drv, efx->net_dev, "timed out waiting for interrupt\n");
@@ -151,8 +153,7 @@ static int efx_test_interrupts(struct efx_nic *efx,
 
  success:
 	netif_dbg(efx, drv, efx->net_dev, "%s test interrupt seen on CPU%d\n",
-		  INT_MODE(efx),
-		efx->last_irq_cpu);
+		  INT_MODE(efx), cpu);
 	tests->interrupt = 1;
 	return 0;
 }
@@ -162,56 +163,57 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
 			       struct efx_self_tests *tests)
 {
 	struct efx_nic *efx = channel->efx;
-	unsigned int read_ptr, count;
-
-	tests->eventq_dma[channel->channel] = -1;
-	tests->eventq_int[channel->channel] = -1;
-	tests->eventq_poll[channel->channel] = -1;
+	unsigned int read_ptr;
+	bool napi_ran, dma_seen, int_seen;
 
 	read_ptr = channel->eventq_read_ptr;
-	channel->efx->last_irq_cpu = -1;
+	channel->last_irq_cpu = -1;
 	smp_wmb();
 
 	efx_nic_generate_test_event(channel);
 
-	/* Wait for arrival of interrupt */
-	count = 0;
-	do {
-		schedule_timeout_uninterruptible(HZ / 100);
-
-		if (ACCESS_ONCE(channel->eventq_read_ptr) != read_ptr)
-			goto eventq_ok;
-	} while (++count < 2);
-
-	netif_err(efx, drv, efx->net_dev,
-		  "channel %d timed out waiting for event queue\n",
-		  channel->channel);
-
-	/* See if interrupt arrived */
-	if (channel->efx->last_irq_cpu >= 0) {
-		netif_err(efx, drv, efx->net_dev,
-			  "channel %d saw interrupt on CPU%d "
-			  "during event queue test\n", channel->channel,
-			  raw_smp_processor_id());
-		tests->eventq_int[channel->channel] = 1;
+	/* Wait for arrival of interrupt.  NAPI processing may or may
+	 * not complete in time, but we can cope in any case.
+	 */
+	msleep(10);
+	napi_disable(&channel->napi_str);
+	if (channel->eventq_read_ptr != read_ptr) {
+		napi_ran = true;
+		dma_seen = true;
+		int_seen = true;
+	} else {
+		napi_ran = false;
+		dma_seen = efx_nic_event_present(channel);
+		int_seen = ACCESS_ONCE(channel->last_irq_cpu) >= 0;
 	}
+	napi_enable(&channel->napi_str);
+	efx_nic_eventq_read_ack(channel);
+
+	tests->eventq_dma[channel->channel] = dma_seen ? 1 : -1;
+	tests->eventq_int[channel->channel] = int_seen ? 1 : -1;
 
-	/* Check to see if event was received even if interrupt wasn't */
-	if (efx_nic_event_present(channel)) {
+	if (dma_seen && int_seen) {
+		netif_dbg(efx, drv, efx->net_dev,
+			  "channel %d event queue passed (with%s NAPI)\n",
+			  channel->channel, napi_ran ? "" : "out");
+		return 0;
+	} else {
+		/* Report failure and whether either interrupt or DMA worked */
 		netif_err(efx, drv, efx->net_dev,
-			  "channel %d event was generated, but "
-			  "failed to trigger an interrupt\n", channel->channel);
-		tests->eventq_dma[channel->channel] = 1;
+			  "channel %d timed out waiting for event queue\n",
+			  channel->channel);
+		if (int_seen)
+			netif_err(efx, drv, efx->net_dev,
+				  "channel %d saw interrupt "
+				  "during event queue test\n",
+				  channel->channel);
+		if (dma_seen)
+			netif_err(efx, drv, efx->net_dev,
+				  "channel %d event was generated, but "
+				  "failed to trigger an interrupt\n",
+				  channel->channel);
+		return -ETIMEDOUT;
 	}
-
-	return -ETIMEDOUT;
- eventq_ok:
-	netif_dbg(efx, drv, efx->net_dev, "channel %d event queue passed\n",
-		  channel->channel);
-	tests->eventq_dma[channel->channel] = 1;
-	tests->eventq_int[channel->channel] = 1;
-	tests->eventq_poll[channel->channel] = 1;
-	return 0;
 }
 
 static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests,
@@ -316,7 +318,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx,
 	return;
 
  err:
-#ifdef EFX_ENABLE_DEBUG
+#ifdef DEBUG
 	if (atomic_read(&state->rx_bad) == 0) {
 		netif_err(efx, drv, efx->net_dev, "received packet:\n");
 		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1,
@@ -395,11 +397,9 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
 		 * interrupt handler. */
 		smp_wmb();
 
-		if (efx_dev_registered(efx))
-			netif_tx_lock_bh(efx->net_dev);
+		netif_tx_lock_bh(efx->net_dev);
 		rc = efx_enqueue_skb(tx_queue, skb);
-		if (efx_dev_registered(efx))
-			netif_tx_unlock_bh(efx->net_dev);
+		netif_tx_unlock_bh(efx->net_dev);
 
 		if (rc != NETDEV_TX_OK) {
 			netif_err(efx, drv, efx->net_dev,
@@ -440,20 +440,18 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue,
 	int tx_done = 0, rx_good, rx_bad;
 	int i, rc = 0;
 
-	if (efx_dev_registered(efx))
-		netif_tx_lock_bh(efx->net_dev);
+	netif_tx_lock_bh(efx->net_dev);
 
 	/* Count the number of tx completions, and decrement the refcnt. Any
 	 * skbs not already completed will be free'd when the queue is flushed */
-	for (i=0; i < state->packet_count; i++) {
+	for (i = 0; i < state->packet_count; i++) {
 		skb = state->skbs[i];
 		if (skb && !skb_shared(skb))
 			++tx_done;
 		dev_kfree_skb_any(skb);
 	}
 
-	if (efx_dev_registered(efx))
-		netif_tx_unlock_bh(efx->net_dev);
+	netif_tx_unlock_bh(efx->net_dev);
 
 	/* Check TX completion and received packet counts */
 	rx_good = atomic_read(&state->rx_good);
@@ -570,7 +568,7 @@ static int efx_wait_for_link(struct efx_nic *efx)
 		mutex_lock(&efx->mac_lock);
 		link_up = link_state->up;
 		if (link_up)
-			link_up = !efx->mac_op->check_fault(efx);
+			link_up = !efx->type->check_mac_fault(efx);
 		mutex_unlock(&efx->mac_lock);
 
 		if (link_up) {
diff --git a/drivers/net/ethernet/sfc/selftest.h b/drivers/net/ethernet/sfc/selftest.h
index dba5456..87abe2a 100644
--- a/drivers/net/ethernet/sfc/selftest.h
+++ b/drivers/net/ethernet/sfc/selftest.h
@@ -37,7 +37,6 @@ struct efx_self_tests {
 	int interrupt;
 	int eventq_dma[EFX_MAX_CHANNELS];
 	int eventq_int[EFX_MAX_CHANNELS];
-	int eventq_poll[EFX_MAX_CHANNELS];
 	/* offline tests */
 	int registers;
 	int phy_ext[EFX_MAX_PHY_TESTS];
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index 4d5d619..7bea790 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -18,7 +18,6 @@
 #include "bitfield.h"
 #include "efx.h"
 #include "nic.h"
-#include "mac.h"
 #include "spi.h"
 #include "regs.h"
 #include "io.h"
@@ -36,8 +35,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel)
 {
 	efx_dword_t timer_cmd;
 
-	BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_CZ_TC_TIMER_VAL_WIDTH));
-
 	if (channel->irq_moderation)
 		EFX_POPULATE_DWORD_2(timer_cmd,
 				     FRF_CZ_TC_TIMER_MODE,
@@ -53,15 +50,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel)
 			       channel->channel);
 }
 
-static void siena_push_multicast_hash(struct efx_nic *efx)
-{
-	WARN_ON(!mutex_is_locked(&efx->mac_lock));
-
-	efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH,
-		     efx->multicast_hash.byte, sizeof(efx->multicast_hash),
-		     NULL, 0, NULL);
-}
-
 static int siena_mdio_write(struct net_device *net_dev,
 			    int prtad, int devad, u16 addr, u16 value)
 {
@@ -226,7 +214,24 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method)
 
 static int siena_probe_nvconfig(struct efx_nic *efx)
 {
-	return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL);
+	u32 caps = 0;
+	int rc;
+
+	rc = efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, &caps);
+
+	efx->timer_quantum_ns =
+		(caps & (1 << MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN)) ?
+		3072 : 6144; /* 768 cycles */
+	return rc;
+}
+
+static void siena_dimension_resources(struct efx_nic *efx)
+{
+	/* Each port has a small block of internal SRAM dedicated to
+	 * the buffer table and descriptor caches.  In theory we can
+	 * map both blocks to one port, but we don't.
+	 */
+	efx_nic_dimension_resources(efx, FR_CZ_BUF_FULL_TBL_ROWS / 2);
 }
 
 static int siena_probe_nic(struct efx_nic *efx)
@@ -304,6 +309,12 @@ static int siena_probe_nic(struct efx_nic *efx)
 		goto fail5;
 	}
 
+	rc = efx_mcdi_mon_probe(efx);
+	if (rc)
+		goto fail5;
+
+	efx_sriov_probe(efx);
+
 	return 0;
 
 fail5:
@@ -391,6 +402,8 @@ static int siena_init_nic(struct efx_nic *efx)
 
 static void siena_remove_nic(struct efx_nic *efx)
 {
+	efx_mcdi_mon_remove(efx);
+
 	efx_nic_free_buffer(efx, &efx->irq_status);
 
 	siena_reset_hw(efx, RESET_TYPE_ALL);
@@ -617,6 +630,7 @@ const struct efx_nic_type siena_a0_nic_type = {
 	.probe = siena_probe_nic,
 	.remove = siena_remove_nic,
 	.init = siena_init_nic,
+	.dimension_resources = siena_dimension_resources,
 	.fini = efx_port_dummy_op_void,
 	.monitor = NULL,
 	.map_reset_reason = siena_map_reset_reason,
@@ -630,14 +644,14 @@ const struct efx_nic_type siena_a0_nic_type = {
 	.stop_stats = siena_stop_nic_stats,
 	.set_id_led = efx_mcdi_set_id_led,
 	.push_irq_moderation = siena_push_irq_moderation,
-	.push_multicast_hash = siena_push_multicast_hash,
+	.reconfigure_mac = efx_mcdi_mac_reconfigure,
+	.check_mac_fault = efx_mcdi_mac_check_fault,
 	.reconfigure_port = efx_mcdi_phy_reconfigure,
 	.get_wol = siena_get_wol,
 	.set_wol = siena_set_wol,
 	.resume_wol = siena_init_wol,
 	.test_registers = siena_test_registers,
 	.test_nvram = efx_mcdi_nvram_test_all,
-	.default_mac_ops = &efx_mcdi_mac_operations,
 
 	.revision = EFX_REV_SIENA_A0,
 	.mem_map_size = (FR_CZ_MC_TREG_SMEM +
@@ -654,8 +668,7 @@ const struct efx_nic_type siena_a0_nic_type = {
 	.phys_addr_channels = 32, /* Hardware limit is 64, but the legacy
 				   * interrupt handler only supports 32
 				   * channels */
-	.tx_dc_base = 0x88000,
-	.rx_dc_base = 0x68000,
+	.timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
 	.offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
 			     NETIF_F_RXHASH | NETIF_F_NTUPLE),
 };
diff --git a/drivers/net/ethernet/sfc/siena_sriov.c b/drivers/net/ethernet/sfc/siena_sriov.c
new file mode 100644
index 0000000..5c6839e
--- /dev/null
+++ b/drivers/net/ethernet/sfc/siena_sriov.c
@@ -0,0 +1,1642 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2010-2011 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+#include <linux/pci.h>
+#include <linux/module.h>
+#include "net_driver.h"
+#include "efx.h"
+#include "nic.h"
+#include "io.h"
+#include "mcdi.h"
+#include "filter.h"
+#include "mcdi_pcol.h"
+#include "regs.h"
+#include "vfdi.h"
+
+/* Number of longs required to track all the VIs in a VF */
+#define VI_MASK_LENGTH BITS_TO_LONGS(1 << EFX_VI_SCALE_MAX)
+
+/**
+ * enum efx_vf_tx_filter_mode - TX MAC filtering behaviour
+ * @VF_TX_FILTER_OFF: Disabled
+ * @VF_TX_FILTER_AUTO: Enabled if MAC address assigned to VF and only
+ *	2 TX queues allowed per VF.
+ * @VF_TX_FILTER_ON: Enabled
+ */
+enum efx_vf_tx_filter_mode {
+	VF_TX_FILTER_OFF,
+	VF_TX_FILTER_AUTO,
+	VF_TX_FILTER_ON,
+};
+
+/**
+ * struct efx_vf - Back-end resource and protocol state for a PCI VF
+ * @efx: The Efx NIC owning this VF
+ * @pci_rid: The PCI requester ID for this VF
+ * @pci_name: The PCI name (formatted address) of this VF
+ * @index: Index of VF within its port and PF.
+ * @req: VFDI incoming request work item. Incoming USR_EV events are received
+ *	by the NAPI handler, but must be handled by executing MCDI requests
+ *	inside a work item.
+ * @req_addr: VFDI incoming request DMA address (in VF's PCI address space).
+ * @req_type: Expected next incoming (from VF) %VFDI_EV_TYPE member.
+ * @req_seqno: Expected next incoming (from VF) %VFDI_EV_SEQ member.
+ * @msg_seqno: Next %VFDI_EV_SEQ member to reply to VF. Protected by
+ *	@status_lock
+ * @busy: VFDI request queued to be processed or being processed. Receiving
+ *	a VFDI request when @busy is set is an error condition.
+ * @buf: Incoming VFDI requests are DMA from the VF into this buffer.
+ * @buftbl_base: Buffer table entries for this VF start at this index.
+ * @rx_filtering: Receive filtering has been requested by the VF driver.
+ * @rx_filter_flags: The flags sent in the %VFDI_OP_INSERT_FILTER request.
+ * @rx_filter_qid: VF relative qid for RX filter requested by VF.
+ * @rx_filter_id: Receive MAC filter ID. Only one filter per VF is supported.
+ * @tx_filter_mode: Transmit MAC filtering mode.
+ * @tx_filter_id: Transmit MAC filter ID.
+ * @addr: The MAC address and outer vlan tag of the VF.
+ * @status_addr: VF DMA address of page for &struct vfdi_status updates.
+ * @status_lock: Mutex protecting @msg_seqno, @status_addr, @addr,
+ *	@peer_page_addrs and @peer_page_count from simultaneous
+ *	updates by the VM and consumption by
+ *	efx_sriov_update_vf_addr()
+ * @peer_page_addrs: Pointer to an array of guest pages for local addresses.
+ * @peer_page_count: Number of entries in @peer_page_count.
+ * @evq0_addrs: Array of guest pages backing evq0.
+ * @evq0_count: Number of entries in @evq0_addrs.
+ * @flush_waitq: wait queue used by %VFDI_OP_FINI_ALL_QUEUES handler
+ *	to wait for flush completions.
+ * @txq_lock: Mutex for TX queue allocation.
+ * @txq_mask: Mask of initialized transmit queues.
+ * @txq_count: Number of initialized transmit queues.
+ * @rxq_mask: Mask of initialized receive queues.
+ * @rxq_count: Number of initialized receive queues.
+ * @rxq_retry_mask: Mask or receive queues that need to be flushed again
+ *	due to flush failure.
+ * @rxq_retry_count: Number of receive queues in @rxq_retry_mask.
+ * @reset_work: Work item to schedule a VF reset.
+ */
+struct efx_vf {
+	struct efx_nic *efx;
+	unsigned int pci_rid;
+	char pci_name[13]; /* dddd:bb:dd.f */
+	unsigned int index;
+	struct work_struct req;
+	u64 req_addr;
+	int req_type;
+	unsigned req_seqno;
+	unsigned msg_seqno;
+	bool busy;
+	struct efx_buffer buf;
+	unsigned buftbl_base;
+	bool rx_filtering;
+	enum efx_filter_flags rx_filter_flags;
+	unsigned rx_filter_qid;
+	int rx_filter_id;
+	enum efx_vf_tx_filter_mode tx_filter_mode;
+	int tx_filter_id;
+	struct vfdi_endpoint addr;
+	u64 status_addr;
+	struct mutex status_lock;
+	u64 *peer_page_addrs;
+	unsigned peer_page_count;
+	u64 evq0_addrs[EFX_MAX_VF_EVQ_SIZE * sizeof(efx_qword_t) /
+		       EFX_BUF_SIZE];
+	unsigned evq0_count;
+	wait_queue_head_t flush_waitq;
+	struct mutex txq_lock;
+	unsigned long txq_mask[VI_MASK_LENGTH];
+	unsigned txq_count;
+	unsigned long rxq_mask[VI_MASK_LENGTH];
+	unsigned rxq_count;
+	unsigned long rxq_retry_mask[VI_MASK_LENGTH];
+	atomic_t rxq_retry_count;
+	struct work_struct reset_work;
+};
+
+struct efx_memcpy_req {
+	unsigned int from_rid;
+	void *from_buf;
+	u64 from_addr;
+	unsigned int to_rid;
+	u64 to_addr;
+	unsigned length;
+};
+
+/**
+ * struct efx_local_addr - A MAC address on the vswitch without a VF.
+ *
+ * Siena does not have a switch, so VFs can't transmit data to each
+ * other. Instead the VFs must be made aware of the local addresses
+ * on the vswitch, so that they can arrange for an alternative
+ * software datapath to be used.
+ *
+ * @link: List head for insertion into efx->local_addr_list.
+ * @addr: Ethernet address
+ */
+struct efx_local_addr {
+	struct list_head link;
+	u8 addr[ETH_ALEN];
+};
+
+/**
+ * struct efx_endpoint_page - Page of vfdi_endpoint structures
+ *
+ * @link: List head for insertion into efx->local_page_list.
+ * @ptr: Pointer to page.
+ * @addr: DMA address of page.
+ */
+struct efx_endpoint_page {
+	struct list_head link;
+	void *ptr;
+	dma_addr_t addr;
+};
+
+/* Buffer table entries are reserved txq0,rxq0,evq0,txq1,rxq1,evq1 */
+#define EFX_BUFTBL_TXQ_BASE(_vf, _qid)					\
+	((_vf)->buftbl_base + EFX_VF_BUFTBL_PER_VI * (_qid))
+#define EFX_BUFTBL_RXQ_BASE(_vf, _qid)					\
+	(EFX_BUFTBL_TXQ_BASE(_vf, _qid) +				\
+	 (EFX_MAX_DMAQ_SIZE * sizeof(efx_qword_t) / EFX_BUF_SIZE))
+#define EFX_BUFTBL_EVQ_BASE(_vf, _qid)					\
+	(EFX_BUFTBL_TXQ_BASE(_vf, _qid) +				\
+	 (2 * EFX_MAX_DMAQ_SIZE * sizeof(efx_qword_t) / EFX_BUF_SIZE))
+
+#define EFX_FIELD_MASK(_field)			\
+	((1 << _field ## _WIDTH) - 1)
+
+/* VFs can only use this many transmit channels */
+static unsigned int vf_max_tx_channels = 2;
+module_param(vf_max_tx_channels, uint, 0444);
+MODULE_PARM_DESC(vf_max_tx_channels,
+		 "Limit the number of TX channels VFs can use");
+
+static int max_vfs = -1;
+module_param(max_vfs, int, 0444);
+MODULE_PARM_DESC(max_vfs,
+		 "Reduce the number of VFs initialized by the driver");
+
+/* Workqueue used by VFDI communication.  We can't use the global
+ * workqueue because it may be running the VF driver's probe()
+ * routine, which will be blocked there waiting for a VFDI response.
+ */
+static struct workqueue_struct *vfdi_workqueue;
+
+static unsigned abs_index(struct efx_vf *vf, unsigned index)
+{
+	return EFX_VI_BASE + vf->index * efx_vf_size(vf->efx) + index;
+}
+
+static int efx_sriov_cmd(struct efx_nic *efx, bool enable,
+			 unsigned *vi_scale_out, unsigned *vf_total_out)
+{
+	u8 inbuf[MC_CMD_SRIOV_IN_LEN];
+	u8 outbuf[MC_CMD_SRIOV_OUT_LEN];
+	unsigned vi_scale, vf_total;
+	size_t outlen;
+	int rc;
+
+	MCDI_SET_DWORD(inbuf, SRIOV_IN_ENABLE, enable ? 1 : 0);
+	MCDI_SET_DWORD(inbuf, SRIOV_IN_VI_BASE, EFX_VI_BASE);
+	MCDI_SET_DWORD(inbuf, SRIOV_IN_VF_COUNT, efx->vf_count);
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_SRIOV, inbuf, MC_CMD_SRIOV_IN_LEN,
+			  outbuf, MC_CMD_SRIOV_OUT_LEN, &outlen);
+	if (rc)
+		return rc;
+	if (outlen < MC_CMD_SRIOV_OUT_LEN)
+		return -EIO;
+
+	vf_total = MCDI_DWORD(outbuf, SRIOV_OUT_VF_TOTAL);
+	vi_scale = MCDI_DWORD(outbuf, SRIOV_OUT_VI_SCALE);
+	if (vi_scale > EFX_VI_SCALE_MAX)
+		return -EOPNOTSUPP;
+
+	if (vi_scale_out)
+		*vi_scale_out = vi_scale;
+	if (vf_total_out)
+		*vf_total_out = vf_total;
+
+	return 0;
+}
+
+static void efx_sriov_usrev(struct efx_nic *efx, bool enabled)
+{
+	efx_oword_t reg;
+
+	EFX_POPULATE_OWORD_2(reg,
+			     FRF_CZ_USREV_DIS, enabled ? 0 : 1,
+			     FRF_CZ_DFLT_EVQ, efx->vfdi_channel->channel);
+	efx_writeo(efx, &reg, FR_CZ_USR_EV_CFG);
+}
+
+static int efx_sriov_memcpy(struct efx_nic *efx, struct efx_memcpy_req *req,
+			    unsigned int count)
+{
+	u8 *inbuf, *record;
+	unsigned int used;
+	u32 from_rid, from_hi, from_lo;
+	int rc;
+
+	mb();	/* Finish writing source/reading dest before DMA starts */
+
+	used = MC_CMD_MEMCPY_IN_LEN(count);
+	if (WARN_ON(used > MCDI_CTL_SDU_LEN_MAX))
+		return -ENOBUFS;
+
+	/* Allocate room for the largest request */
+	inbuf = kzalloc(MCDI_CTL_SDU_LEN_MAX, GFP_KERNEL);
+	if (inbuf == NULL)
+		return -ENOMEM;
+
+	record = inbuf;
+	MCDI_SET_DWORD(record, MEMCPY_IN_RECORD, count);
+	while (count-- > 0) {
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_RID,
+			       req->to_rid);
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO,
+			       (u32)req->to_addr);
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_TO_ADDR_HI,
+			       (u32)(req->to_addr >> 32));
+		if (req->from_buf == NULL) {
+			from_rid = req->from_rid;
+			from_lo = (u32)req->from_addr;
+			from_hi = (u32)(req->from_addr >> 32);
+		} else {
+			if (WARN_ON(used + req->length > MCDI_CTL_SDU_LEN_MAX)) {
+				rc = -ENOBUFS;
+				goto out;
+			}
+
+			from_rid = MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE;
+			from_lo = used;
+			from_hi = 0;
+			memcpy(inbuf + used, req->from_buf, req->length);
+			used += req->length;
+		}
+
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_FROM_RID, from_rid);
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LO,
+			       from_lo);
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_FROM_ADDR_HI,
+			       from_hi);
+		MCDI_SET_DWORD(record, MEMCPY_RECORD_TYPEDEF_LENGTH,
+			       req->length);
+
+		++req;
+		record += MC_CMD_MEMCPY_IN_RECORD_LEN;
+	}
+
+	rc = efx_mcdi_rpc(efx, MC_CMD_MEMCPY, inbuf, used, NULL, 0, NULL);
+out:
+	kfree(inbuf);
+
+	mb();	/* Don't write source/read dest before DMA is complete */
+
+	return rc;
+}
+
+/* The TX filter is entirely controlled by this driver, and is modified
+ * underneath the feet of the VF
+ */
+static void efx_sriov_reset_tx_filter(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct efx_filter_spec filter;
+	u16 vlan;
+	int rc;
+
+	if (vf->tx_filter_id != -1) {
+		efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
+					  vf->tx_filter_id);
+		netif_dbg(efx, hw, efx->net_dev, "Removed vf %s tx filter %d\n",
+			  vf->pci_name, vf->tx_filter_id);
+		vf->tx_filter_id = -1;
+	}
+
+	if (is_zero_ether_addr(vf->addr.mac_addr))
+		return;
+
+	/* Turn on TX filtering automatically if not explicitly
+	 * enabled or disabled.
+	 */
+	if (vf->tx_filter_mode == VF_TX_FILTER_AUTO && vf_max_tx_channels <= 2)
+		vf->tx_filter_mode = VF_TX_FILTER_ON;
+
+	vlan = ntohs(vf->addr.tci) & VLAN_VID_MASK;
+	efx_filter_init_tx(&filter, abs_index(vf, 0));
+	rc = efx_filter_set_eth_local(&filter,
+				      vlan ? vlan : EFX_FILTER_VID_UNSPEC,
+				      vf->addr.mac_addr);
+	BUG_ON(rc);
+
+	rc = efx_filter_insert_filter(efx, &filter, true);
+	if (rc < 0) {
+		netif_warn(efx, hw, efx->net_dev,
+			   "Unable to migrate tx filter for vf %s\n",
+			   vf->pci_name);
+	} else {
+		netif_dbg(efx, hw, efx->net_dev, "Inserted vf %s tx filter %d\n",
+			  vf->pci_name, rc);
+		vf->tx_filter_id = rc;
+	}
+}
+
+/* The RX filter is managed here on behalf of the VF driver */
+static void efx_sriov_reset_rx_filter(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct efx_filter_spec filter;
+	u16 vlan;
+	int rc;
+
+	if (vf->rx_filter_id != -1) {
+		efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
+					  vf->rx_filter_id);
+		netif_dbg(efx, hw, efx->net_dev, "Removed vf %s rx filter %d\n",
+			  vf->pci_name, vf->rx_filter_id);
+		vf->rx_filter_id = -1;
+	}
+
+	if (!vf->rx_filtering || is_zero_ether_addr(vf->addr.mac_addr))
+		return;
+
+	vlan = ntohs(vf->addr.tci) & VLAN_VID_MASK;
+	efx_filter_init_rx(&filter, EFX_FILTER_PRI_REQUIRED,
+			   vf->rx_filter_flags,
+			   abs_index(vf, vf->rx_filter_qid));
+	rc = efx_filter_set_eth_local(&filter,
+				      vlan ? vlan : EFX_FILTER_VID_UNSPEC,
+				      vf->addr.mac_addr);
+	BUG_ON(rc);
+
+	rc = efx_filter_insert_filter(efx, &filter, true);
+	if (rc < 0) {
+		netif_warn(efx, hw, efx->net_dev,
+			   "Unable to insert rx filter for vf %s\n",
+			   vf->pci_name);
+	} else {
+		netif_dbg(efx, hw, efx->net_dev, "Inserted vf %s rx filter %d\n",
+			  vf->pci_name, rc);
+		vf->rx_filter_id = rc;
+	}
+}
+
+static void __efx_sriov_update_vf_addr(struct efx_vf *vf)
+{
+	efx_sriov_reset_tx_filter(vf);
+	efx_sriov_reset_rx_filter(vf);
+	queue_work(vfdi_workqueue, &vf->efx->peer_work);
+}
+
+/* Push the peer list to this VF. The caller must hold status_lock to interlock
+ * with VFDI requests, and they must be serialised against manipulation of
+ * local_page_list, either by acquiring local_lock or by running from
+ * efx_sriov_peer_work()
+ */
+static void __efx_sriov_push_vf_status(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_status *status = efx->vfdi_status.addr;
+	struct efx_memcpy_req copy[4];
+	struct efx_endpoint_page *epp;
+	unsigned int pos, count;
+	unsigned data_offset;
+	efx_qword_t event;
+
+	WARN_ON(!mutex_is_locked(&vf->status_lock));
+	WARN_ON(!vf->status_addr);
+
+	status->local = vf->addr;
+	status->generation_end = ++status->generation_start;
+
+	memset(copy, '\0', sizeof(copy));
+	/* Write generation_start */
+	copy[0].from_buf = &status->generation_start;
+	copy[0].to_rid = vf->pci_rid;
+	copy[0].to_addr = vf->status_addr + offsetof(struct vfdi_status,
+						     generation_start);
+	copy[0].length = sizeof(status->generation_start);
+	/* DMA the rest of the structure (excluding the generations). This
+	 * assumes that the non-generation portion of vfdi_status is in
+	 * one chunk starting at the version member.
+	 */
+	data_offset = offsetof(struct vfdi_status, version);
+	copy[1].from_rid = efx->pci_dev->devfn;
+	copy[1].from_addr = efx->vfdi_status.dma_addr + data_offset;
+	copy[1].to_rid = vf->pci_rid;
+	copy[1].to_addr = vf->status_addr + data_offset;
+	copy[1].length =  status->length - data_offset;
+
+	/* Copy the peer pages */
+	pos = 2;
+	count = 0;
+	list_for_each_entry(epp, &efx->local_page_list, link) {
+		if (count == vf->peer_page_count) {
+			/* The VF driver will know they need to provide more
+			 * pages because peer_addr_count is too large.
+			 */
+			break;
+		}
+		copy[pos].from_buf = NULL;
+		copy[pos].from_rid = efx->pci_dev->devfn;
+		copy[pos].from_addr = epp->addr;
+		copy[pos].to_rid = vf->pci_rid;
+		copy[pos].to_addr = vf->peer_page_addrs[count];
+		copy[pos].length = EFX_PAGE_SIZE;
+
+		if (++pos == ARRAY_SIZE(copy)) {
+			efx_sriov_memcpy(efx, copy, ARRAY_SIZE(copy));
+			pos = 0;
+		}
+		++count;
+	}
+
+	/* Write generation_end */
+	copy[pos].from_buf = &status->generation_end;
+	copy[pos].to_rid = vf->pci_rid;
+	copy[pos].to_addr = vf->status_addr + offsetof(struct vfdi_status,
+						       generation_end);
+	copy[pos].length = sizeof(status->generation_end);
+	efx_sriov_memcpy(efx, copy, pos + 1);
+
+	/* Notify the guest */
+	EFX_POPULATE_QWORD_3(event,
+			     FSF_AZ_EV_CODE, FSE_CZ_EV_CODE_USER_EV,
+			     VFDI_EV_SEQ, (vf->msg_seqno & 0xff),
+			     VFDI_EV_TYPE, VFDI_EV_TYPE_STATUS);
+	++vf->msg_seqno;
+	efx_generate_event(efx, EFX_VI_BASE + vf->index * efx_vf_size(efx),
+			      &event);
+}
+
+static void efx_sriov_bufs(struct efx_nic *efx, unsigned offset,
+			   u64 *addr, unsigned count)
+{
+	efx_qword_t buf;
+	unsigned pos;
+
+	for (pos = 0; pos < count; ++pos) {
+		EFX_POPULATE_QWORD_3(buf,
+				     FRF_AZ_BUF_ADR_REGION, 0,
+				     FRF_AZ_BUF_ADR_FBUF,
+				     addr ? addr[pos] >> 12 : 0,
+				     FRF_AZ_BUF_OWNER_ID_FBUF, 0);
+		efx_sram_writeq(efx, efx->membase + FR_BZ_BUF_FULL_TBL,
+				&buf, offset + pos);
+	}
+}
+
+static bool bad_vf_index(struct efx_nic *efx, unsigned index)
+{
+	return index >= efx_vf_size(efx);
+}
+
+static bool bad_buf_count(unsigned buf_count, unsigned max_entry_count)
+{
+	unsigned max_buf_count = max_entry_count *
+		sizeof(efx_qword_t) / EFX_BUF_SIZE;
+
+	return ((buf_count & (buf_count - 1)) || buf_count > max_buf_count);
+}
+
+/* Check that VI specified by per-port index belongs to a VF.
+ * Optionally set VF index and VI index within the VF.
+ */
+static bool map_vi_index(struct efx_nic *efx, unsigned abs_index,
+			 struct efx_vf **vf_out, unsigned *rel_index_out)
+{
+	unsigned vf_i;
+
+	if (abs_index < EFX_VI_BASE)
+		return true;
+	vf_i = (abs_index - EFX_VI_BASE) * efx_vf_size(efx);
+	if (vf_i >= efx->vf_init_count)
+		return true;
+
+	if (vf_out)
+		*vf_out = efx->vf + vf_i;
+	if (rel_index_out)
+		*rel_index_out = abs_index % efx_vf_size(efx);
+	return false;
+}
+
+static int efx_vfdi_init_evq(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_req *req = vf->buf.addr;
+	unsigned vf_evq = req->u.init_evq.index;
+	unsigned buf_count = req->u.init_evq.buf_count;
+	unsigned abs_evq = abs_index(vf, vf_evq);
+	unsigned buftbl = EFX_BUFTBL_EVQ_BASE(vf, vf_evq);
+	efx_oword_t reg;
+
+	if (bad_vf_index(efx, vf_evq) ||
+	    bad_buf_count(buf_count, EFX_MAX_VF_EVQ_SIZE)) {
+		if (net_ratelimit())
+			netif_err(efx, hw, efx->net_dev,
+				  "ERROR: Invalid INIT_EVQ from %s: evq %d bufs %d\n",
+				  vf->pci_name, vf_evq, buf_count);
+		return VFDI_RC_EINVAL;
+	}
+
+	efx_sriov_bufs(efx, buftbl, req->u.init_evq.addr, buf_count);
+
+	EFX_POPULATE_OWORD_3(reg,
+			     FRF_CZ_TIMER_Q_EN, 1,
+			     FRF_CZ_HOST_NOTIFY_MODE, 0,
+			     FRF_CZ_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS);
+	efx_writeo_table(efx, &reg, FR_BZ_TIMER_TBL, abs_evq);
+	EFX_POPULATE_OWORD_3(reg,
+			     FRF_AZ_EVQ_EN, 1,
+			     FRF_AZ_EVQ_SIZE, __ffs(buf_count),
+			     FRF_AZ_EVQ_BUF_BASE_ID, buftbl);
+	efx_writeo_table(efx, &reg, FR_BZ_EVQ_PTR_TBL, abs_evq);
+
+	if (vf_evq == 0) {
+		memcpy(vf->evq0_addrs, req->u.init_evq.addr,
+		       buf_count * sizeof(u64));
+		vf->evq0_count = buf_count;
+	}
+
+	return VFDI_RC_SUCCESS;
+}
+
+static int efx_vfdi_init_rxq(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_req *req = vf->buf.addr;
+	unsigned vf_rxq = req->u.init_rxq.index;
+	unsigned vf_evq = req->u.init_rxq.evq;
+	unsigned buf_count = req->u.init_rxq.buf_count;
+	unsigned buftbl = EFX_BUFTBL_RXQ_BASE(vf, vf_rxq);
+	unsigned label;
+	efx_oword_t reg;
+
+	if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_rxq) ||
+	    bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) {
+		if (net_ratelimit())
+			netif_err(efx, hw, efx->net_dev,
+				  "ERROR: Invalid INIT_RXQ from %s: rxq %d evq %d "
+				  "buf_count %d\n", vf->pci_name, vf_rxq,
+				  vf_evq, buf_count);
+		return VFDI_RC_EINVAL;
+	}
+	if (__test_and_set_bit(req->u.init_rxq.index, vf->rxq_mask))
+		++vf->rxq_count;
+	efx_sriov_bufs(efx, buftbl, req->u.init_rxq.addr, buf_count);
+
+	label = req->u.init_rxq.label & EFX_FIELD_MASK(FRF_AZ_RX_DESCQ_LABEL);
+	EFX_POPULATE_OWORD_6(reg,
+			     FRF_AZ_RX_DESCQ_BUF_BASE_ID, buftbl,
+			     FRF_AZ_RX_DESCQ_EVQ_ID, abs_index(vf, vf_evq),
+			     FRF_AZ_RX_DESCQ_LABEL, label,
+			     FRF_AZ_RX_DESCQ_SIZE, __ffs(buf_count),
+			     FRF_AZ_RX_DESCQ_JUMBO,
+			     !!(req->u.init_rxq.flags &
+				VFDI_RXQ_FLAG_SCATTER_EN),
+			     FRF_AZ_RX_DESCQ_EN, 1);
+	efx_writeo_table(efx, &reg, FR_BZ_RX_DESC_PTR_TBL,
+			 abs_index(vf, vf_rxq));
+
+	return VFDI_RC_SUCCESS;
+}
+
+static int efx_vfdi_init_txq(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_req *req = vf->buf.addr;
+	unsigned vf_txq = req->u.init_txq.index;
+	unsigned vf_evq = req->u.init_txq.evq;
+	unsigned buf_count = req->u.init_txq.buf_count;
+	unsigned buftbl = EFX_BUFTBL_TXQ_BASE(vf, vf_txq);
+	unsigned label, eth_filt_en;
+	efx_oword_t reg;
+
+	if (bad_vf_index(efx, vf_evq) || bad_vf_index(efx, vf_txq) ||
+	    vf_txq >= vf_max_tx_channels ||
+	    bad_buf_count(buf_count, EFX_MAX_DMAQ_SIZE)) {
+		if (net_ratelimit())
+			netif_err(efx, hw, efx->net_dev,
+				  "ERROR: Invalid INIT_TXQ from %s: txq %d evq %d "
+				  "buf_count %d\n", vf->pci_name, vf_txq,
+				  vf_evq, buf_count);
+		return VFDI_RC_EINVAL;
+	}
+
+	mutex_lock(&vf->txq_lock);
+	if (__test_and_set_bit(req->u.init_txq.index, vf->txq_mask))
+		++vf->txq_count;
+	mutex_unlock(&vf->txq_lock);
+	efx_sriov_bufs(efx, buftbl, req->u.init_txq.addr, buf_count);
+
+	eth_filt_en = vf->tx_filter_mode == VF_TX_FILTER_ON;
+
+	label = req->u.init_txq.label & EFX_FIELD_MASK(FRF_AZ_TX_DESCQ_LABEL);
+	EFX_POPULATE_OWORD_8(reg,
+			     FRF_CZ_TX_DPT_Q_MASK_WIDTH, min(efx->vi_scale, 1U),
+			     FRF_CZ_TX_DPT_ETH_FILT_EN, eth_filt_en,
+			     FRF_AZ_TX_DESCQ_EN, 1,
+			     FRF_AZ_TX_DESCQ_BUF_BASE_ID, buftbl,
+			     FRF_AZ_TX_DESCQ_EVQ_ID, abs_index(vf, vf_evq),
+			     FRF_AZ_TX_DESCQ_LABEL, label,
+			     FRF_AZ_TX_DESCQ_SIZE, __ffs(buf_count),
+			     FRF_BZ_TX_NON_IP_DROP_DIS, 1);
+	efx_writeo_table(efx, &reg, FR_BZ_TX_DESC_PTR_TBL,
+			 abs_index(vf, vf_txq));
+
+	return VFDI_RC_SUCCESS;
+}
+
+/* Returns true when efx_vfdi_fini_all_queues should wake */
+static bool efx_vfdi_flush_wake(struct efx_vf *vf)
+{
+	/* Ensure that all updates are visible to efx_vfdi_fini_all_queues() */
+	smp_mb();
+
+	return (!vf->txq_count && !vf->rxq_count) ||
+		atomic_read(&vf->rxq_retry_count);
+}
+
+static void efx_vfdi_flush_clear(struct efx_vf *vf)
+{
+	memset(vf->txq_mask, 0, sizeof(vf->txq_mask));
+	vf->txq_count = 0;
+	memset(vf->rxq_mask, 0, sizeof(vf->rxq_mask));
+	vf->rxq_count = 0;
+	memset(vf->rxq_retry_mask, 0, sizeof(vf->rxq_retry_mask));
+	atomic_set(&vf->rxq_retry_count, 0);
+}
+
+static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	efx_oword_t reg;
+	unsigned count = efx_vf_size(efx);
+	unsigned vf_offset = EFX_VI_BASE + vf->index * efx_vf_size(efx);
+	unsigned timeout = HZ;
+	unsigned index, rxqs_count;
+	__le32 *rxqs;
+	int rc;
+
+	rxqs = kmalloc(count * sizeof(*rxqs), GFP_KERNEL);
+	if (rxqs == NULL)
+		return VFDI_RC_ENOMEM;
+
+	rtnl_lock();
+	if (efx->fc_disable++ == 0)
+		efx_mcdi_set_mac(efx);
+	rtnl_unlock();
+
+	/* Flush all the initialized queues */
+	rxqs_count = 0;
+	for (index = 0; index < count; ++index) {
+		if (test_bit(index, vf->txq_mask)) {
+			EFX_POPULATE_OWORD_2(reg,
+					     FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
+					     FRF_AZ_TX_FLUSH_DESCQ,
+					     vf_offset + index);
+			efx_writeo(efx, &reg, FR_AZ_TX_FLUSH_DESCQ);
+		}
+		if (test_bit(index, vf->rxq_mask))
+			rxqs[rxqs_count++] = cpu_to_le32(vf_offset + index);
+	}
+
+	atomic_set(&vf->rxq_retry_count, 0);
+	while (timeout && (vf->rxq_count || vf->txq_count)) {
+		rc = efx_mcdi_rpc(efx, MC_CMD_FLUSH_RX_QUEUES, (u8 *)rxqs,
+				  rxqs_count * sizeof(*rxqs), NULL, 0, NULL);
+		WARN_ON(rc < 0);
+
+		timeout = wait_event_timeout(vf->flush_waitq,
+					     efx_vfdi_flush_wake(vf),
+					     timeout);
+		rxqs_count = 0;
+		for (index = 0; index < count; ++index) {
+			if (test_and_clear_bit(index, vf->rxq_retry_mask)) {
+				atomic_dec(&vf->rxq_retry_count);
+				rxqs[rxqs_count++] =
+					cpu_to_le32(vf_offset + index);
+			}
+		}
+	}
+
+	rtnl_lock();
+	if (--efx->fc_disable == 0)
+		efx_mcdi_set_mac(efx);
+	rtnl_unlock();
+
+	/* Irrespective of success/failure, fini the queues */
+	EFX_ZERO_OWORD(reg);
+	for (index = 0; index < count; ++index) {
+		efx_writeo_table(efx, &reg, FR_BZ_RX_DESC_PTR_TBL,
+				 vf_offset + index);
+		efx_writeo_table(efx, &reg, FR_BZ_TX_DESC_PTR_TBL,
+				 vf_offset + index);
+		efx_writeo_table(efx, &reg, FR_BZ_EVQ_PTR_TBL,
+				 vf_offset + index);
+		efx_writeo_table(efx, &reg, FR_BZ_TIMER_TBL,
+				 vf_offset + index);
+	}
+	efx_sriov_bufs(efx, vf->buftbl_base, NULL,
+		       EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx));
+	kfree(rxqs);
+	efx_vfdi_flush_clear(vf);
+
+	vf->evq0_count = 0;
+
+	return timeout ? 0 : VFDI_RC_ETIMEDOUT;
+}
+
+static int efx_vfdi_insert_filter(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_req *req = vf->buf.addr;
+	unsigned vf_rxq = req->u.mac_filter.rxq;
+	unsigned flags;
+
+	if (bad_vf_index(efx, vf_rxq) || vf->rx_filtering) {
+		if (net_ratelimit())
+			netif_err(efx, hw, efx->net_dev,
+				  "ERROR: Invalid INSERT_FILTER from %s: rxq %d "
+				  "flags 0x%x\n", vf->pci_name, vf_rxq,
+				  req->u.mac_filter.flags);
+		return VFDI_RC_EINVAL;
+	}
+
+	flags = 0;
+	if (req->u.mac_filter.flags & VFDI_MAC_FILTER_FLAG_RSS)
+		flags |= EFX_FILTER_FLAG_RX_RSS;
+	if (req->u.mac_filter.flags & VFDI_MAC_FILTER_FLAG_SCATTER)
+		flags |= EFX_FILTER_FLAG_RX_SCATTER;
+	vf->rx_filter_flags = flags;
+	vf->rx_filter_qid = vf_rxq;
+	vf->rx_filtering = true;
+
+	efx_sriov_reset_rx_filter(vf);
+	queue_work(vfdi_workqueue, &efx->peer_work);
+
+	return VFDI_RC_SUCCESS;
+}
+
+static int efx_vfdi_remove_all_filters(struct efx_vf *vf)
+{
+	vf->rx_filtering = false;
+	efx_sriov_reset_rx_filter(vf);
+	queue_work(vfdi_workqueue, &vf->efx->peer_work);
+
+	return VFDI_RC_SUCCESS;
+}
+
+static int efx_vfdi_set_status_page(struct efx_vf *vf)
+{
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_req *req = vf->buf.addr;
+	unsigned int page_count;
+
+	page_count = req->u.set_status_page.peer_page_count;
+	if (!req->u.set_status_page.dma_addr || EFX_PAGE_SIZE <
+	    offsetof(struct vfdi_req,
+		     u.set_status_page.peer_page_addr[page_count])) {
+		if (net_ratelimit())
+			netif_err(efx, hw, efx->net_dev,
+				  "ERROR: Invalid SET_STATUS_PAGE from %s\n",
+				  vf->pci_name);
+		return VFDI_RC_EINVAL;
+	}
+
+	mutex_lock(&efx->local_lock);
+	mutex_lock(&vf->status_lock);
+	vf->status_addr = req->u.set_status_page.dma_addr;
+
+	kfree(vf->peer_page_addrs);
+	vf->peer_page_addrs = NULL;
+	vf->peer_page_count = 0;
+
+	if (page_count) {
+		vf->peer_page_addrs = kcalloc(page_count, sizeof(u64),
+					      GFP_KERNEL);
+		if (vf->peer_page_addrs) {
+			memcpy(vf->peer_page_addrs,
+			       req->u.set_status_page.peer_page_addr,
+			       page_count * sizeof(u64));
+			vf->peer_page_count = page_count;
+		}
+	}
+
+	__efx_sriov_push_vf_status(vf);
+	mutex_unlock(&vf->status_lock);
+	mutex_unlock(&efx->local_lock);
+
+	return VFDI_RC_SUCCESS;
+}
+
+static int efx_vfdi_clear_status_page(struct efx_vf *vf)
+{
+	mutex_lock(&vf->status_lock);
+	vf->status_addr = 0;
+	mutex_unlock(&vf->status_lock);
+
+	return VFDI_RC_SUCCESS;
+}
+
+typedef int (*efx_vfdi_op_t)(struct efx_vf *vf);
+
+static const efx_vfdi_op_t vfdi_ops[VFDI_OP_LIMIT] = {
+	[VFDI_OP_INIT_EVQ] = efx_vfdi_init_evq,
+	[VFDI_OP_INIT_TXQ] = efx_vfdi_init_txq,
+	[VFDI_OP_INIT_RXQ] = efx_vfdi_init_rxq,
+	[VFDI_OP_FINI_ALL_QUEUES] = efx_vfdi_fini_all_queues,
+	[VFDI_OP_INSERT_FILTER] = efx_vfdi_insert_filter,
+	[VFDI_OP_REMOVE_ALL_FILTERS] = efx_vfdi_remove_all_filters,
+	[VFDI_OP_SET_STATUS_PAGE] = efx_vfdi_set_status_page,
+	[VFDI_OP_CLEAR_STATUS_PAGE] = efx_vfdi_clear_status_page,
+};
+
+static void efx_sriov_vfdi(struct work_struct *work)
+{
+	struct efx_vf *vf = container_of(work, struct efx_vf, req);
+	struct efx_nic *efx = vf->efx;
+	struct vfdi_req *req = vf->buf.addr;
+	struct efx_memcpy_req copy[2];
+	int rc;
+
+	/* Copy this page into the local address space */
+	memset(copy, '\0', sizeof(copy));
+	copy[0].from_rid = vf->pci_rid;
+	copy[0].from_addr = vf->req_addr;
+	copy[0].to_rid = efx->pci_dev->devfn;
+	copy[0].to_addr = vf->buf.dma_addr;
+	copy[0].length = EFX_PAGE_SIZE;
+	rc = efx_sriov_memcpy(efx, copy, 1);
+	if (rc) {
+		/* If we can't get the request, we can't reply to the caller */
+		if (net_ratelimit())
+			netif_err(efx, hw, efx->net_dev,
+				  "ERROR: Unable to fetch VFDI request from %s rc %d\n",
+				  vf->pci_name, -rc);
+		vf->busy = false;
+		return;
+	}
+
+	if (req->op < VFDI_OP_LIMIT && vfdi_ops[req->op] != NULL) {
+		rc = vfdi_ops[req->op](vf);
+		if (rc == 0) {
+			netif_dbg(efx, hw, efx->net_dev,
+				  "vfdi request %d from %s ok\n",
+				  req->op, vf->pci_name);
+		}
+	} else {
+		netif_dbg(efx, hw, efx->net_dev,
+			  "ERROR: Unrecognised request %d from VF %s addr "
+			  "%llx\n", req->op, vf->pci_name,
+			  (unsigned long long)vf->req_addr);
+		rc = VFDI_RC_EOPNOTSUPP;
+	}
+
+	/* Allow subsequent VF requests */
+	vf->busy = false;
+	smp_wmb();
+
+	/* Respond to the request */
+	req->rc = rc;
+	req->op = VFDI_OP_RESPONSE;
+
+	memset(copy, '\0', sizeof(copy));
+	copy[0].from_buf = &req->rc;
+	copy[0].to_rid = vf->pci_rid;
+	copy[0].to_addr = vf->req_addr + offsetof(struct vfdi_req, rc);
+	copy[0].length = sizeof(req->rc);
+	copy[1].from_buf = &req->op;
+	copy[1].to_rid = vf->pci_rid;
+	copy[1].to_addr = vf->req_addr + offsetof(struct vfdi_req, op);
+	copy[1].length = sizeof(req->op);
+
+	(void) efx_sriov_memcpy(efx, copy, ARRAY_SIZE(copy));
+}
+
+
+
+/* After a reset the event queues inside the guests no longer exist. Fill the
+ * event ring in guest memory with VFDI reset events, then (re-initialise) the
+ * event queue to raise an interrupt. The guest driver will then recover.
+ */
+static void efx_sriov_reset_vf(struct efx_vf *vf, struct efx_buffer *buffer)
+{
+	struct efx_nic *efx = vf->efx;
+	struct efx_memcpy_req copy_req[4];
+	efx_qword_t event;
+	unsigned int pos, count, k, buftbl, abs_evq;
+	efx_oword_t reg;
+	efx_dword_t ptr;
+	int rc;
+
+	BUG_ON(buffer->len != EFX_PAGE_SIZE);
+
+	if (!vf->evq0_count)
+		return;
+	BUG_ON(vf->evq0_count & (vf->evq0_count - 1));
+
+	mutex_lock(&vf->status_lock);
+	EFX_POPULATE_QWORD_3(event,
+			     FSF_AZ_EV_CODE, FSE_CZ_EV_CODE_USER_EV,
+			     VFDI_EV_SEQ, vf->msg_seqno,
+			     VFDI_EV_TYPE, VFDI_EV_TYPE_RESET);
+	vf->msg_seqno++;
+	for (pos = 0; pos < EFX_PAGE_SIZE; pos += sizeof(event))
+		memcpy(buffer->addr + pos, &event, sizeof(event));
+
+	for (pos = 0; pos < vf->evq0_count; pos += count) {
+		count = min_t(unsigned, vf->evq0_count - pos,
+			      ARRAY_SIZE(copy_req));
+		for (k = 0; k < count; k++) {
+			copy_req[k].from_buf = NULL;
+			copy_req[k].from_rid = efx->pci_dev->devfn;
+			copy_req[k].from_addr = buffer->dma_addr;
+			copy_req[k].to_rid = vf->pci_rid;
+			copy_req[k].to_addr = vf->evq0_addrs[pos + k];
+			copy_req[k].length = EFX_PAGE_SIZE;
+		}
+		rc = efx_sriov_memcpy(efx, copy_req, count);
+		if (rc) {
+			if (net_ratelimit())
+				netif_err(efx, hw, efx->net_dev,
+					  "ERROR: Unable to notify %s of reset"
+					  ": %d\n", vf->pci_name, -rc);
+			break;
+		}
+	}
+
+	/* Reinitialise, arm and trigger evq0 */
+	abs_evq = abs_index(vf, 0);
+	buftbl = EFX_BUFTBL_EVQ_BASE(vf, 0);
+	efx_sriov_bufs(efx, buftbl, vf->evq0_addrs, vf->evq0_count);
+
+	EFX_POPULATE_OWORD_3(reg,
+			     FRF_CZ_TIMER_Q_EN, 1,
+			     FRF_CZ_HOST_NOTIFY_MODE, 0,
+			     FRF_CZ_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS);
+	efx_writeo_table(efx, &reg, FR_BZ_TIMER_TBL, abs_evq);
+	EFX_POPULATE_OWORD_3(reg,
+			     FRF_AZ_EVQ_EN, 1,
+			     FRF_AZ_EVQ_SIZE, __ffs(vf->evq0_count),
+			     FRF_AZ_EVQ_BUF_BASE_ID, buftbl);
+	efx_writeo_table(efx, &reg, FR_BZ_EVQ_PTR_TBL, abs_evq);
+	EFX_POPULATE_DWORD_1(ptr, FRF_AZ_EVQ_RPTR, 0);
+	efx_writed_table(efx, &ptr, FR_BZ_EVQ_RPTR, abs_evq);
+
+	mutex_unlock(&vf->status_lock);
+}
+
+static void efx_sriov_reset_vf_work(struct work_struct *work)
+{
+	struct efx_vf *vf = container_of(work, struct efx_vf, req);
+	struct efx_nic *efx = vf->efx;
+	struct efx_buffer buf;
+
+	if (!efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE)) {
+		efx_sriov_reset_vf(vf, &buf);
+		efx_nic_free_buffer(efx, &buf);
+	}
+}
+
+static void efx_sriov_handle_no_channel(struct efx_nic *efx)
+{
+	netif_err(efx, drv, efx->net_dev,
+		  "ERROR: IOV requires MSI-X and 1 additional interrupt"
+		  "vector. IOV disabled\n");
+	efx->vf_count = 0;
+}
+
+static int efx_sriov_probe_channel(struct efx_channel *channel)
+{
+	channel->efx->vfdi_channel = channel;
+	return 0;
+}
+
+static void
+efx_sriov_get_channel_name(struct efx_channel *channel, char *buf, size_t len)
+{
+	snprintf(buf, len, "%s-iov", channel->efx->name);
+}
+
+static const struct efx_channel_type efx_sriov_channel_type = {
+	.handle_no_channel	= efx_sriov_handle_no_channel,
+	.pre_probe		= efx_sriov_probe_channel,
+	.get_name		= efx_sriov_get_channel_name,
+	/* no copy operation; channel must not be reallocated */
+	.keep_eventq		= true,
+};
+
+void efx_sriov_probe(struct efx_nic *efx)
+{
+	unsigned count;
+
+	if (!max_vfs)
+		return;
+
+	if (efx_sriov_cmd(efx, false, &efx->vi_scale, &count))
+		return;
+	if (count > 0 && count > max_vfs)
+		count = max_vfs;
+
+	/* efx_nic_dimension_resources() will reduce vf_count as appopriate */
+	efx->vf_count = count;
+
+	efx->extra_channel_type[EFX_EXTRA_CHANNEL_IOV] = &efx_sriov_channel_type;
+}
+
+/* Copy the list of individual addresses into the vfdi_status.peers
+ * array and auxillary pages, protected by %local_lock. Drop that lock
+ * and then broadcast the address list to every VF.
+ */
+static void efx_sriov_peer_work(struct work_struct *data)
+{
+	struct efx_nic *efx = container_of(data, struct efx_nic, peer_work);
+	struct vfdi_status *vfdi_status = efx->vfdi_status.addr;
+	struct efx_vf *vf;
+	struct efx_local_addr *local_addr;
+	struct vfdi_endpoint *peer;
+	struct efx_endpoint_page *epp;
+	struct list_head pages;
+	unsigned int peer_space;
+	unsigned int peer_count;
+	unsigned int pos;
+
+	mutex_lock(&efx->local_lock);
+
+	/* Move the existing peer pages off %local_page_list */
+	INIT_LIST_HEAD(&pages);
+	list_splice_tail_init(&efx->local_page_list, &pages);
+
+	/* Populate the VF addresses starting from entry 1 (entry 0 is
+	 * the PF address)
+	 */
+	peer = vfdi_status->peers + 1;
+	peer_space = ARRAY_SIZE(vfdi_status->peers) - 1;
+	peer_count = 1;
+	for (pos = 0; pos < efx->vf_count; ++pos) {
+		vf = efx->vf + pos;
+
+		mutex_lock(&vf->status_lock);
+		if (vf->rx_filtering && !is_zero_ether_addr(vf->addr.mac_addr)) {
+			*peer++ = vf->addr;
+			++peer_count;
+			--peer_space;
+			BUG_ON(peer_space == 0);
+		}
+		mutex_unlock(&vf->status_lock);
+	}
+
+	/* Fill the remaining addresses */
+	list_for_each_entry(local_addr, &efx->local_addr_list, link) {
+		memcpy(peer->mac_addr, local_addr->addr, ETH_ALEN);
+		peer->tci = 0;
+		++peer;
+		++peer_count;
+		if (--peer_space == 0) {
+			if (list_empty(&pages)) {
+				epp = kmalloc(sizeof(*epp), GFP_KERNEL);
+				if (!epp)
+					break;
+				epp->ptr = dma_alloc_coherent(
+					&efx->pci_dev->dev, EFX_PAGE_SIZE,
+					&epp->addr, GFP_KERNEL);
+				if (!epp->ptr) {
+					kfree(epp);
+					break;
+				}
+			} else {
+				epp = list_first_entry(
+					&pages, struct efx_endpoint_page, link);
+				list_del(&epp->link);
+			}
+
+			list_add_tail(&epp->link, &efx->local_page_list);
+			peer = (struct vfdi_endpoint *)epp->ptr;
+			peer_space = EFX_PAGE_SIZE / sizeof(struct vfdi_endpoint);
+		}
+	}
+	vfdi_status->peer_count = peer_count;
+	mutex_unlock(&efx->local_lock);
+
+	/* Free any now unused endpoint pages */
+	while (!list_empty(&pages)) {
+		epp = list_first_entry(
+			&pages, struct efx_endpoint_page, link);
+		list_del(&epp->link);
+		dma_free_coherent(&efx->pci_dev->dev, EFX_PAGE_SIZE,
+				  epp->ptr, epp->addr);
+		kfree(epp);
+	}
+
+	/* Finally, push the pages */
+	for (pos = 0; pos < efx->vf_count; ++pos) {
+		vf = efx->vf + pos;
+
+		mutex_lock(&vf->status_lock);
+		if (vf->status_addr)
+			__efx_sriov_push_vf_status(vf);
+		mutex_unlock(&vf->status_lock);
+	}
+}
+
+static void efx_sriov_free_local(struct efx_nic *efx)
+{
+	struct efx_local_addr *local_addr;
+	struct efx_endpoint_page *epp;
+
+	while (!list_empty(&efx->local_addr_list)) {
+		local_addr = list_first_entry(&efx->local_addr_list,
+					      struct efx_local_addr, link);
+		list_del(&local_addr->link);
+		kfree(local_addr);
+	}
+
+	while (!list_empty(&efx->local_page_list)) {
+		epp = list_first_entry(&efx->local_page_list,
+				       struct efx_endpoint_page, link);
+		list_del(&epp->link);
+		dma_free_coherent(&efx->pci_dev->dev, EFX_PAGE_SIZE,
+				  epp->ptr, epp->addr);
+		kfree(epp);
+	}
+}
+
+static int efx_sriov_vf_alloc(struct efx_nic *efx)
+{
+	unsigned index;
+	struct efx_vf *vf;
+
+	efx->vf = kzalloc(sizeof(struct efx_vf) * efx->vf_count, GFP_KERNEL);
+	if (!efx->vf)
+		return -ENOMEM;
+
+	for (index = 0; index < efx->vf_count; ++index) {
+		vf = efx->vf + index;
+
+		vf->efx = efx;
+		vf->index = index;
+		vf->rx_filter_id = -1;
+		vf->tx_filter_mode = VF_TX_FILTER_AUTO;
+		vf->tx_filter_id = -1;
+		INIT_WORK(&vf->req, efx_sriov_vfdi);
+		INIT_WORK(&vf->reset_work, efx_sriov_reset_vf_work);
+		init_waitqueue_head(&vf->flush_waitq);
+		mutex_init(&vf->status_lock);
+		mutex_init(&vf->txq_lock);
+	}
+
+	return 0;
+}
+
+static void efx_sriov_vfs_fini(struct efx_nic *efx)
+{
+	struct efx_vf *vf;
+	unsigned int pos;
+
+	for (pos = 0; pos < efx->vf_count; ++pos) {
+		vf = efx->vf + pos;
+
+		efx_nic_free_buffer(efx, &vf->buf);
+		kfree(vf->peer_page_addrs);
+		vf->peer_page_addrs = NULL;
+		vf->peer_page_count = 0;
+
+		vf->evq0_count = 0;
+	}
+}
+
+static int efx_sriov_vfs_init(struct efx_nic *efx)
+{
+	struct pci_dev *pci_dev = efx->pci_dev;
+	unsigned index, devfn, sriov, buftbl_base;
+	u16 offset, stride;
+	struct efx_vf *vf;
+	int rc;
+
+	sriov = pci_find_ext_capability(pci_dev, PCI_EXT_CAP_ID_SRIOV);
+	if (!sriov)
+		return -ENOENT;
+
+	pci_read_config_word(pci_dev, sriov + PCI_SRIOV_VF_OFFSET, &offset);
+	pci_read_config_word(pci_dev, sriov + PCI_SRIOV_VF_STRIDE, &stride);
+
+	buftbl_base = efx->vf_buftbl_base;
+	devfn = pci_dev->devfn + offset;
+	for (index = 0; index < efx->vf_count; ++index) {
+		vf = efx->vf + index;
+
+		/* Reserve buffer entries */
+		vf->buftbl_base = buftbl_base;
+		buftbl_base += EFX_VF_BUFTBL_PER_VI * efx_vf_size(efx);
+
+		vf->pci_rid = devfn;
+		snprintf(vf->pci_name, sizeof(vf->pci_name),
+			 "%04x:%02x:%02x.%d",
+			 pci_domain_nr(pci_dev->bus), pci_dev->bus->number,
+			 PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+		rc = efx_nic_alloc_buffer(efx, &vf->buf, EFX_PAGE_SIZE);
+		if (rc)
+			goto fail;
+
+		devfn += stride;
+	}
+
+	return 0;
+
+fail:
+	efx_sriov_vfs_fini(efx);
+	return rc;
+}
+
+int efx_sriov_init(struct efx_nic *efx)
+{
+	struct net_device *net_dev = efx->net_dev;
+	struct vfdi_status *vfdi_status;
+	int rc;
+
+	/* Ensure there's room for vf_channel */
+	BUILD_BUG_ON(EFX_MAX_CHANNELS + 1 >= EFX_VI_BASE);
+	/* Ensure that VI_BASE is aligned on VI_SCALE */
+	BUILD_BUG_ON(EFX_VI_BASE & ((1 << EFX_VI_SCALE_MAX) - 1));
+
+	if (efx->vf_count == 0)
+		return 0;
+
+	rc = efx_sriov_cmd(efx, true, NULL, NULL);
+	if (rc)
+		goto fail_cmd;
+
+	rc = efx_nic_alloc_buffer(efx, &efx->vfdi_status, sizeof(*vfdi_status));
+	if (rc)
+		goto fail_status;
+	vfdi_status = efx->vfdi_status.addr;
+	memset(vfdi_status, 0, sizeof(*vfdi_status));
+	vfdi_status->version = 1;
+	vfdi_status->length = sizeof(*vfdi_status);
+	vfdi_status->max_tx_channels = vf_max_tx_channels;
+	vfdi_status->vi_scale = efx->vi_scale;
+	vfdi_status->rss_rxq_count = efx->rss_spread;
+	vfdi_status->peer_count = 1 + efx->vf_count;
+	vfdi_status->timer_quantum_ns = efx->timer_quantum_ns;
+
+	rc = efx_sriov_vf_alloc(efx);
+	if (rc)
+		goto fail_alloc;
+
+	mutex_init(&efx->local_lock);
+	INIT_WORK(&efx->peer_work, efx_sriov_peer_work);
+	INIT_LIST_HEAD(&efx->local_addr_list);
+	INIT_LIST_HEAD(&efx->local_page_list);
+
+	rc = efx_sriov_vfs_init(efx);
+	if (rc)
+		goto fail_vfs;
+
+	rtnl_lock();
+	memcpy(vfdi_status->peers[0].mac_addr,
+	       net_dev->dev_addr, ETH_ALEN);
+	efx->vf_init_count = efx->vf_count;
+	rtnl_unlock();
+
+	efx_sriov_usrev(efx, true);
+
+	/* At this point we must be ready to accept VFDI requests */
+
+	rc = pci_enable_sriov(efx->pci_dev, efx->vf_count);
+	if (rc)
+		goto fail_pci;
+
+	netif_info(efx, probe, net_dev,
+		   "enabled SR-IOV for %d VFs, %d VI per VF\n",
+		   efx->vf_count, efx_vf_size(efx));
+	return 0;
+
+fail_pci:
+	efx_sriov_usrev(efx, false);
+	rtnl_lock();
+	efx->vf_init_count = 0;
+	rtnl_unlock();
+	efx_sriov_vfs_fini(efx);
+fail_vfs:
+	cancel_work_sync(&efx->peer_work);
+	efx_sriov_free_local(efx);
+	kfree(efx->vf);
+fail_alloc:
+	efx_nic_free_buffer(efx, &efx->vfdi_status);
+fail_status:
+	efx_sriov_cmd(efx, false, NULL, NULL);
+fail_cmd:
+	return rc;
+}
+
+void efx_sriov_fini(struct efx_nic *efx)
+{
+	struct efx_vf *vf;
+	unsigned int pos;
+
+	if (efx->vf_init_count == 0)
+		return;
+
+	/* Disable all interfaces to reconfiguration */
+	BUG_ON(efx->vfdi_channel->enabled);
+	efx_sriov_usrev(efx, false);
+	rtnl_lock();
+	efx->vf_init_count = 0;
+	rtnl_unlock();
+
+	/* Flush all reconfiguration work */
+	for (pos = 0; pos < efx->vf_count; ++pos) {
+		vf = efx->vf + pos;
+		cancel_work_sync(&vf->req);
+		cancel_work_sync(&vf->reset_work);
+	}
+	cancel_work_sync(&efx->peer_work);
+
+	pci_disable_sriov(efx->pci_dev);
+
+	/* Tear down back-end state */
+	efx_sriov_vfs_fini(efx);
+	efx_sriov_free_local(efx);
+	kfree(efx->vf);
+	efx_nic_free_buffer(efx, &efx->vfdi_status);
+	efx_sriov_cmd(efx, false, NULL, NULL);
+}
+
+void efx_sriov_event(struct efx_channel *channel, efx_qword_t *event)
+{
+	struct efx_nic *efx = channel->efx;
+	struct efx_vf *vf;
+	unsigned qid, seq, type, data;
+
+	qid = EFX_QWORD_FIELD(*event, FSF_CZ_USER_QID);
+
+	/* USR_EV_REG_VALUE is dword0, so access the VFDI_EV fields directly */
+	BUILD_BUG_ON(FSF_CZ_USER_EV_REG_VALUE_LBN != 0);
+	seq = EFX_QWORD_FIELD(*event, VFDI_EV_SEQ);
+	type = EFX_QWORD_FIELD(*event, VFDI_EV_TYPE);
+	data = EFX_QWORD_FIELD(*event, VFDI_EV_DATA);
+
+	netif_vdbg(efx, hw, efx->net_dev,
+		   "USR_EV event from qid %d seq 0x%x type %d data 0x%x\n",
+		   qid, seq, type, data);
+
+	if (map_vi_index(efx, qid, &vf, NULL))
+		return;
+	if (vf->busy)
+		goto error;
+
+	if (type == VFDI_EV_TYPE_REQ_WORD0) {
+		/* Resynchronise */
+		vf->req_type = VFDI_EV_TYPE_REQ_WORD0;
+		vf->req_seqno = seq + 1;
+		vf->req_addr = 0;
+	} else if (seq != (vf->req_seqno++ & 0xff) || type != vf->req_type)
+		goto error;
+
+	switch (vf->req_type) {
+	case VFDI_EV_TYPE_REQ_WORD0:
+	case VFDI_EV_TYPE_REQ_WORD1:
+	case VFDI_EV_TYPE_REQ_WORD2:
+		vf->req_addr |= (u64)data << (vf->req_type << 4);
+		++vf->req_type;
+		return;
+
+	case VFDI_EV_TYPE_REQ_WORD3:
+		vf->req_addr |= (u64)data << 48;
+		vf->req_type = VFDI_EV_TYPE_REQ_WORD0;
+		vf->busy = true;
+		queue_work(vfdi_workqueue, &vf->req);
+		return;
+	}
+
+error:
+	if (net_ratelimit())
+		netif_err(efx, hw, efx->net_dev,
+			  "ERROR: Screaming VFDI request from %s\n",
+			  vf->pci_name);
+	/* Reset the request and sequence number */
+	vf->req_type = VFDI_EV_TYPE_REQ_WORD0;
+	vf->req_seqno = seq + 1;
+}
+
+void efx_sriov_flr(struct efx_nic *efx, unsigned vf_i)
+{
+	struct efx_vf *vf;
+
+	if (vf_i > efx->vf_init_count)
+		return;
+	vf = efx->vf + vf_i;
+	netif_info(efx, hw, efx->net_dev,
+		   "FLR on VF %s\n", vf->pci_name);
+
+	vf->status_addr = 0;
+	efx_vfdi_remove_all_filters(vf);
+	efx_vfdi_flush_clear(vf);
+
+	vf->evq0_count = 0;
+}
+
+void efx_sriov_mac_address_changed(struct efx_nic *efx)
+{
+	struct vfdi_status *vfdi_status = efx->vfdi_status.addr;
+
+	if (!efx->vf_init_count)
+		return;
+	memcpy(vfdi_status->peers[0].mac_addr,
+	       efx->net_dev->dev_addr, ETH_ALEN);
+	queue_work(vfdi_workqueue, &efx->peer_work);
+}
+
+void efx_sriov_tx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+{
+	struct efx_vf *vf;
+	unsigned queue, qid;
+
+	queue = EFX_QWORD_FIELD(*event,  FSF_AZ_DRIVER_EV_SUBDATA);
+	if (map_vi_index(efx, queue, &vf, &qid))
+		return;
+	/* Ignore flush completions triggered by an FLR */
+	if (!test_bit(qid, vf->txq_mask))
+		return;
+
+	__clear_bit(qid, vf->txq_mask);
+	--vf->txq_count;
+
+	if (efx_vfdi_flush_wake(vf))
+		wake_up(&vf->flush_waitq);
+}
+
+void efx_sriov_rx_flush_done(struct efx_nic *efx, efx_qword_t *event)
+{
+	struct efx_vf *vf;
+	unsigned ev_failed, queue, qid;
+
+	queue = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_RX_DESCQ_ID);
+	ev_failed = EFX_QWORD_FIELD(*event,
+				    FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
+	if (map_vi_index(efx, queue, &vf, &qid))
+		return;
+	if (!test_bit(qid, vf->rxq_mask))
+		return;
+
+	if (ev_failed) {
+		set_bit(qid, vf->rxq_retry_mask);
+		atomic_inc(&vf->rxq_retry_count);
+	} else {
+		__clear_bit(qid, vf->rxq_mask);
+		--vf->rxq_count;
+	}
+	if (efx_vfdi_flush_wake(vf))
+		wake_up(&vf->flush_waitq);
+}
+
+/* Called from napi. Schedule the reset work item */
+void efx_sriov_desc_fetch_err(struct efx_nic *efx, unsigned dmaq)
+{
+	struct efx_vf *vf;
+	unsigned int rel;
+
+	if (map_vi_index(efx, dmaq, &vf, &rel))
+		return;
+
+	if (net_ratelimit())
+		netif_err(efx, hw, efx->net_dev,
+			  "VF %d DMA Q %d reports descriptor fetch error.\n",
+			  vf->index, rel);
+	queue_work(vfdi_workqueue, &vf->reset_work);
+}
+
+/* Reset all VFs */
+void efx_sriov_reset(struct efx_nic *efx)
+{
+	unsigned int vf_i;
+	struct efx_buffer buf;
+	struct efx_vf *vf;
+
+	ASSERT_RTNL();
+
+	if (efx->vf_init_count == 0)
+		return;
+
+	efx_sriov_usrev(efx, true);
+	(void)efx_sriov_cmd(efx, true, NULL, NULL);
+
+	if (efx_nic_alloc_buffer(efx, &buf, EFX_PAGE_SIZE))
+		return;
+
+	for (vf_i = 0; vf_i < efx->vf_init_count; ++vf_i) {
+		vf = efx->vf + vf_i;
+		efx_sriov_reset_vf(vf, &buf);
+	}
+
+	efx_nic_free_buffer(efx, &buf);
+}
+
+int efx_init_sriov(void)
+{
+	/* A single threaded workqueue is sufficient. efx_sriov_vfdi() and
+	 * efx_sriov_peer_work() spend almost all their time sleeping for
+	 * MCDI to complete anyway
+	 */
+	vfdi_workqueue = create_singlethread_workqueue("sfc_vfdi");
+	if (!vfdi_workqueue)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void efx_fini_sriov(void)
+{
+	destroy_workqueue(vfdi_workqueue);
+}
+
+int efx_sriov_set_vf_mac(struct net_device *net_dev, int vf_i, u8 *mac)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	struct efx_vf *vf;
+
+	if (vf_i >= efx->vf_init_count)
+		return -EINVAL;
+	vf = efx->vf + vf_i;
+
+	mutex_lock(&vf->status_lock);
+	memcpy(vf->addr.mac_addr, mac, ETH_ALEN);
+	__efx_sriov_update_vf_addr(vf);
+	mutex_unlock(&vf->status_lock);
+
+	return 0;
+}
+
+int efx_sriov_set_vf_vlan(struct net_device *net_dev, int vf_i,
+			  u16 vlan, u8 qos)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	struct efx_vf *vf;
+	u16 tci;
+
+	if (vf_i >= efx->vf_init_count)
+		return -EINVAL;
+	vf = efx->vf + vf_i;
+
+	mutex_lock(&vf->status_lock);
+	tci = (vlan & VLAN_VID_MASK) | ((qos & 0x7) << VLAN_PRIO_SHIFT);
+	vf->addr.tci = htons(tci);
+	__efx_sriov_update_vf_addr(vf);
+	mutex_unlock(&vf->status_lock);
+
+	return 0;
+}
+
+int efx_sriov_set_vf_spoofchk(struct net_device *net_dev, int vf_i,
+			      bool spoofchk)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	struct efx_vf *vf;
+	int rc;
+
+	if (vf_i >= efx->vf_init_count)
+		return -EINVAL;
+	vf = efx->vf + vf_i;
+
+	mutex_lock(&vf->txq_lock);
+	if (vf->txq_count == 0) {
+		vf->tx_filter_mode =
+			spoofchk ? VF_TX_FILTER_ON : VF_TX_FILTER_OFF;
+		rc = 0;
+	} else {
+		/* This cannot be changed while TX queues are running */
+		rc = -EBUSY;
+	}
+	mutex_unlock(&vf->txq_lock);
+	return rc;
+}
+
+int efx_sriov_get_vf_config(struct net_device *net_dev, int vf_i,
+			    struct ifla_vf_info *ivi)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+	struct efx_vf *vf;
+	u16 tci;
+
+	if (vf_i >= efx->vf_init_count)
+		return -EINVAL;
+	vf = efx->vf + vf_i;
+
+	ivi->vf = vf_i;
+	memcpy(ivi->mac, vf->addr.mac_addr, ETH_ALEN);
+	ivi->tx_rate = 0;
+	tci = ntohs(vf->addr.tci);
+	ivi->vlan = tci & VLAN_VID_MASK;
+	ivi->qos = (tci >> VLAN_PRIO_SHIFT) & 0x7;
+	ivi->spoofchk = vf->tx_filter_mode == VF_TX_FILTER_ON;
+
+	return 0;
+}
+
diff --git a/drivers/net/ethernet/sfc/spi.h b/drivers/net/ethernet/sfc/spi.h
index 71f2e3e..5431a1b 100644
--- a/drivers/net/ethernet/sfc/spi.h
+++ b/drivers/net/ethernet/sfc/spi.h
@@ -68,7 +68,7 @@ static inline bool efx_spi_present(const struct efx_spi_device *spi)
 
 int falcon_spi_cmd(struct efx_nic *efx,
 		   const struct efx_spi_device *spi, unsigned int command,
-		   int address, const void* in, void *out, size_t len);
+		   int address, const void *in, void *out, size_t len);
 int falcon_spi_wait_write(struct efx_nic *efx,
 			  const struct efx_spi_device *spi);
 int falcon_spi_read(struct efx_nic *efx,
diff --git a/drivers/net/ethernet/sfc/tenxpress.c b/drivers/net/ethernet/sfc/tenxpress.c
index 7b0fd89..d37cb50 100644
--- a/drivers/net/ethernet/sfc/tenxpress.c
+++ b/drivers/net/ethernet/sfc/tenxpress.c
@@ -121,7 +121,7 @@
 #define GPHY_XCONTROL_REG	49152
 #define GPHY_ISOLATE_LBN	10
 #define GPHY_ISOLATE_WIDTH	1
-#define GPHY_DUPLEX_LBN	  	8
+#define GPHY_DUPLEX_LBN		8
 #define GPHY_DUPLEX_WIDTH	1
 #define GPHY_LOOPBACK_NEAR_LBN	14
 #define GPHY_LOOPBACK_NEAR_WIDTH 1
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index 72f0fbc..a096e28 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -110,7 +110,7 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr)
 	 * little benefit from using descriptors that cross those
 	 * boundaries and we keep things simple by not doing so.
 	 */
-	unsigned len = (~dma_addr & 0xfff) + 1;
+	unsigned len = (~dma_addr & (EFX_PAGE_SIZE - 1)) + 1;
 
 	/* Work around hardware bug for unaligned buffers. */
 	if (EFX_WORKAROUND_5391(efx) && (dma_addr & 0xf))
@@ -446,10 +446,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
 	    likely(efx->port_enabled) &&
 	    likely(netif_device_present(efx->net_dev))) {
 		fill_level = tx_queue->insert_count - tx_queue->read_count;
-		if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
-			EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
+		if (fill_level < EFX_TXQ_THRESHOLD(efx))
 			netif_tx_wake_queue(tx_queue->core_txq);
-		}
 	}
 
 	/* Check whether the hardware queue is now empty */
diff --git a/drivers/net/ethernet/sfc/txc43128_phy.c b/drivers/net/ethernet/sfc/txc43128_phy.c
index 7c21b33..29bb3f9 100644
--- a/drivers/net/ethernet/sfc/txc43128_phy.c
+++ b/drivers/net/ethernet/sfc/txc43128_phy.c
@@ -512,7 +512,7 @@ static bool txc43128_phy_poll(struct efx_nic *efx)
 	return efx->link_state.up != was_up;
 }
 
-static const char *txc43128_test_names[] = {
+static const char *const txc43128_test_names[] = {
 	"bist"
 };
 
diff --git a/drivers/net/ethernet/sfc/vfdi.h b/drivers/net/ethernet/sfc/vfdi.h
new file mode 100644
index 0000000..656fa70
--- /dev/null
+++ b/drivers/net/ethernet/sfc/vfdi.h
@@ -0,0 +1,254 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2010-2012 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+#ifndef _VFDI_H
+#define _VFDI_H
+
+/**
+ * DOC: Virtual Function Driver Interface
+ *
+ * This file contains software structures used to form a two way
+ * communication channel between the VF driver and the PF driver,
+ * named Virtual Function Driver Interface (VFDI).
+ *
+ * For the purposes of VFDI, a page is a memory region with size and
+ * alignment of 4K.  All addresses are DMA addresses to be used within
+ * the domain of the relevant VF.
+ *
+ * The only hardware-defined channels for a VF driver to communicate
+ * with the PF driver are the event mailboxes (%FR_CZ_USR_EV
+ * registers).  Writing to these registers generates an event with
+ * EV_CODE = EV_CODE_USR_EV, USER_QID set to the index of the mailbox
+ * and USER_EV_REG_VALUE set to the value written.  The PF driver may
+ * direct or disable delivery of these events by setting
+ * %FR_CZ_USR_EV_CFG.
+ *
+ * The PF driver can send arbitrary events to arbitrary event queues.
+ * However, for consistency, VFDI events from the PF are defined to
+ * follow the same form and be sent to the first event queue assigned
+ * to the VF while that queue is enabled by the VF driver.
+ *
+ * The general form of the variable bits of VFDI events is:
+ *
+ *       0             16                       24   31
+ *      | DATA        | TYPE                   | SEQ   |
+ *
+ * SEQ is a sequence number which should be incremented by 1 (modulo
+ * 256) for each event.  The sequence numbers used in each direction
+ * are independent.
+ *
+ * The VF submits requests of type &struct vfdi_req by sending the
+ * address of the request (ADDR) in a series of 4 events:
+ *
+ *       0             16                       24   31
+ *      | ADDR[0:15]  | VFDI_EV_TYPE_REQ_WORD0 | SEQ   |
+ *      | ADDR[16:31] | VFDI_EV_TYPE_REQ_WORD1 | SEQ+1 |
+ *      | ADDR[32:47] | VFDI_EV_TYPE_REQ_WORD2 | SEQ+2 |
+ *      | ADDR[48:63] | VFDI_EV_TYPE_REQ_WORD3 | SEQ+3 |
+ *
+ * The address must be page-aligned.  After receiving such a valid
+ * series of events, the PF driver will attempt to read the request
+ * and write a response to the same address.  In case of an invalid
+ * sequence of events or a DMA error, there will be no response.
+ *
+ * The VF driver may request that the PF driver writes status
+ * information into its domain asynchronously.  After writing the
+ * status, the PF driver will send an event of the form:
+ *
+ *       0             16                       24   31
+ *      | reserved    | VFDI_EV_TYPE_STATUS    | SEQ   |
+ *
+ * In case the VF must be reset for any reason, the PF driver will
+ * send an event of the form:
+ *
+ *       0             16                       24   31
+ *      | reserved    | VFDI_EV_TYPE_RESET     | SEQ   |
+ *
+ * It is then the responsibility of the VF driver to request
+ * reinitialisation of its queues.
+ */
+#define VFDI_EV_SEQ_LBN 24
+#define VFDI_EV_SEQ_WIDTH 8
+#define VFDI_EV_TYPE_LBN 16
+#define VFDI_EV_TYPE_WIDTH 8
+#define VFDI_EV_TYPE_REQ_WORD0 0
+#define VFDI_EV_TYPE_REQ_WORD1 1
+#define VFDI_EV_TYPE_REQ_WORD2 2
+#define VFDI_EV_TYPE_REQ_WORD3 3
+#define VFDI_EV_TYPE_STATUS 4
+#define VFDI_EV_TYPE_RESET 5
+#define VFDI_EV_DATA_LBN 0
+#define VFDI_EV_DATA_WIDTH 16
+
+struct vfdi_endpoint {
+	u8 mac_addr[ETH_ALEN];
+	__be16 tci;
+};
+
+/**
+ * enum vfdi_op - VFDI operation enumeration
+ * @VFDI_OP_RESPONSE: Indicates a response to the request.
+ * @VFDI_OP_INIT_EVQ: Initialize SRAM entries and initialize an EVQ.
+ * @VFDI_OP_INIT_RXQ: Initialize SRAM entries and initialize an RXQ.
+ * @VFDI_OP_INIT_TXQ: Initialize SRAM entries and initialize a TXQ.
+ * @VFDI_OP_FINI_ALL_QUEUES: Flush all queues, finalize all queues, then
+ *	finalize the SRAM entries.
+ * @VFDI_OP_INSERT_FILTER: Insert a MAC filter targetting the given RXQ.
+ * @VFDI_OP_REMOVE_ALL_FILTERS: Remove all filters.
+ * @VFDI_OP_SET_STATUS_PAGE: Set the DMA page(s) used for status updates
+ *	from PF and write the initial status.
+ * @VFDI_OP_CLEAR_STATUS_PAGE: Clear the DMA page(s) used for status
+ *	updates from PF.
+ */
+enum vfdi_op {
+	VFDI_OP_RESPONSE = 0,
+	VFDI_OP_INIT_EVQ = 1,
+	VFDI_OP_INIT_RXQ = 2,
+	VFDI_OP_INIT_TXQ = 3,
+	VFDI_OP_FINI_ALL_QUEUES = 4,
+	VFDI_OP_INSERT_FILTER = 5,
+	VFDI_OP_REMOVE_ALL_FILTERS = 6,
+	VFDI_OP_SET_STATUS_PAGE = 7,
+	VFDI_OP_CLEAR_STATUS_PAGE = 8,
+	VFDI_OP_LIMIT,
+};
+
+/* Response codes for VFDI operations. Other values may be used in future. */
+#define VFDI_RC_SUCCESS		0
+#define VFDI_RC_ENOMEM		(-12)
+#define VFDI_RC_EINVAL		(-22)
+#define VFDI_RC_EOPNOTSUPP	(-95)
+#define VFDI_RC_ETIMEDOUT	(-110)
+
+/**
+ * struct vfdi_req - Request from VF driver to PF driver
+ * @op: Operation code or response indicator, taken from &enum vfdi_op.
+ * @rc: Response code.  Set to 0 on success or a negative error code on failure.
+ * @u.init_evq.index: Index of event queue to create.
+ * @u.init_evq.buf_count: Number of 4k buffers backing event queue.
+ * @u.init_evq.addr: Array of length %u.init_evq.buf_count containing DMA
+ *	address of each page backing the event queue.
+ * @u.init_rxq.index: Index of receive queue to create.
+ * @u.init_rxq.buf_count: Number of 4k buffers backing receive queue.
+ * @u.init_rxq.evq: Instance of event queue to target receive events at.
+ * @u.init_rxq.label: Label used in receive events.
+ * @u.init_rxq.flags: Unused.
+ * @u.init_rxq.addr: Array of length %u.init_rxq.buf_count containing DMA
+ *	address of each page backing the receive queue.
+ * @u.init_txq.index: Index of transmit queue to create.
+ * @u.init_txq.buf_count: Number of 4k buffers backing transmit queue.
+ * @u.init_txq.evq: Instance of event queue to target transmit completion
+ *	events at.
+ * @u.init_txq.label: Label used in transmit completion events.
+ * @u.init_txq.flags: Checksum offload flags.
+ * @u.init_txq.addr: Array of length %u.init_txq.buf_count containing DMA
+ *	address of each page backing the transmit queue.
+ * @u.mac_filter.rxq: Insert MAC filter at VF local address/VLAN targetting
+ *	all traffic at this receive queue.
+ * @u.mac_filter.flags: MAC filter flags.
+ * @u.set_status_page.dma_addr: Base address for the &struct vfdi_status.
+ *	This address must be such that the structure fits within a page.
+ * @u.set_status_page.peer_page_count: Number of additional pages the VF
+ *	has provided into which peer addresses may be DMAd.
+ * @u.set_status_page.peer_page_addr: Array of DMA addresses of pages.
+ *	If the number of peers exceeds 256, then the VF must provide
+ *	additional pages in this array. The PF will then DMA up to
+ *	512 vfdi_endpoint structures into each page.  These addresses
+ *	must be page-aligned.
+ */
+struct vfdi_req {
+	u32 op;
+	u32 reserved1;
+	s32 rc;
+	u32 reserved2;
+	union {
+		struct {
+			u32 index;
+			u32 buf_count;
+			u64 addr[];
+		} init_evq;
+		struct {
+			u32 index;
+			u32 buf_count;
+			u32 evq;
+			u32 label;
+			u32 flags;
+#define VFDI_RXQ_FLAG_SCATTER_EN 1
+			u32 reserved;
+			u64 addr[];
+		} init_rxq;
+		struct {
+			u32 index;
+			u32 buf_count;
+			u32 evq;
+			u32 label;
+			u32 flags;
+#define VFDI_TXQ_FLAG_IP_CSUM_DIS 1
+#define VFDI_TXQ_FLAG_TCPUDP_CSUM_DIS 2
+			u32 reserved;
+			u64 addr[];
+		} init_txq;
+		struct {
+			u32 rxq;
+			u32 flags;
+#define VFDI_MAC_FILTER_FLAG_RSS 1
+#define VFDI_MAC_FILTER_FLAG_SCATTER 2
+		} mac_filter;
+		struct {
+			u64 dma_addr;
+			u64 peer_page_count;
+			u64 peer_page_addr[];
+		} set_status_page;
+	} u;
+};
+
+/**
+ * struct vfdi_status - Status provided by PF driver to VF driver
+ * @generation_start: A generation count DMA'd to VF *before* the
+ *	rest of the structure.
+ * @generation_end: A generation count DMA'd to VF *after* the
+ *	rest of the structure.
+ * @version: Version of this structure; currently set to 1.  Later
+ *	versions must either be layout-compatible or only be sent to VFs
+ *	that specifically request them.
+ * @length: Total length of this structure including embedded tables
+ * @vi_scale: log2 the number of VIs available on this VF. This quantity
+ *	is used by the hardware for register decoding.
+ * @max_tx_channels: The maximum number of transmit queues the VF can use.
+ * @rss_rxq_count: The number of receive queues present in the shared RSS
+ *	indirection table.
+ * @peer_count: Total number of peers in the complete peer list. If larger
+ *	than ARRAY_SIZE(%peers), then the VF must provide sufficient
+ *	additional pages each of which is filled with vfdi_endpoint structures.
+ * @local: The MAC address and outer VLAN tag of *this* VF
+ * @peers: Table of peer addresses.  The @tci fields in these structures
+ *	are currently unused and must be ignored.  Additional peers are
+ *	written into any additional pages provided by the VF.
+ * @timer_quantum_ns: Timer quantum (nominal period between timer ticks)
+ *	for interrupt moderation timers, in nanoseconds. This member is only
+ *	present if @length is sufficiently large.
+ */
+struct vfdi_status {
+	u32 generation_start;
+	u32 generation_end;
+	u32 version;
+	u32 length;
+	u8 vi_scale;
+	u8 max_tx_channels;
+	u8 rss_rxq_count;
+	u8 reserved1;
+	u16 peer_count;
+	u16 reserved2;
+	struct vfdi_endpoint local;
+	struct vfdi_endpoint peers[256];
+
+	/* Members below here extend version 1 of this structure */
+	u32 timer_quantum_ns;
+};
+
+#endif
diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c
index 5b118cd..a9deda8 100644
--- a/drivers/net/ethernet/sis/sis190.c
+++ b/drivers/net/ethernet/sis/sis190.c
@@ -1462,8 +1462,6 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
 
 	dev = alloc_etherdev(sizeof(*tp));
 	if (!dev) {
-		if (netif_msg_drv(&debug))
-			pr_err("unable to alloc new ethernet\n");
 		rc = -ENOMEM;
 		goto err_out_0;
 	}
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index c8efc70..5ccf02e 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -527,7 +527,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
 		ret = sis900_get_mac_addr(pci_dev, net_dev);
 
 	if (!ret || !is_valid_ether_addr(net_dev->dev_addr)) {
-		random_ether_addr(net_dev->dev_addr);
+		eth_hw_addr_random(net_dev);
 		printk(KERN_WARNING "%s: Unreadable or invalid MAC address,"
 				"using random generated one\n", dev_name);
 	}
@@ -619,7 +619,6 @@ static int __devinit sis900_mii_probe(struct net_device * net_dev)
 		}
 
 		if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) {
-			printk(KERN_WARNING "Cannot allocate mem for struct mii_phy\n");
 			mii_phy = sis_priv->first_mii;
 			while (mii_phy) {
 				struct mii_phy *phy;
@@ -1167,7 +1166,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		struct sk_buff *skb;
 
-		if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
+		if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) {
 			/* not enough memory for skbuff, this makes a "hole"
 			   on the buffer ring, it is not clear how the
 			   hardware will react to this kind of degenerated
@@ -1770,7 +1769,7 @@ static int sis900_rx(struct net_device *net_dev)
 
 			/* refill the Rx buffer, what if there is not enough
 			 * memory for new socket buffer ?? */
-			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
+			if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) {
 				/*
 				 * Not enough memory to refill the buffer
 				 * so we need to recycle the old one so
@@ -1828,7 +1827,7 @@ refill_rx_ring:
 		entry = sis_priv->dirty_rx % NUM_RX_DESC;
 
 		if (sis_priv->rx_skbuff[entry] == NULL) {
-			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
+			if ((skb = netdev_alloc_skb(net_dev, RX_BUF_SIZE)) == NULL) {
 				/* not enough memory for skbuff, this makes a
 				 * "hole" on the buffer ring, it is not clear
 				 * how the hardware will react to this kind
diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c
index 2c077ce..2a662e6 100644
--- a/drivers/net/ethernet/smsc/epic100.c
+++ b/drivers/net/ethernet/smsc/epic100.c
@@ -363,10 +363,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
 	ret = -ENOMEM;
 
 	dev = alloc_etherdev(sizeof (*ep));
-	if (!dev) {
-		dev_err(&pdev->dev, "no memory for eth device\n");
+	if (!dev)
 		goto err_out_free_res;
-	}
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 #ifdef USE_IO_OPS
@@ -935,7 +934,7 @@ static void epic_init_ring(struct net_device *dev)
 
 	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz + 2);
+		struct sk_buff *skb = netdev_alloc_skb(dev, ep->rx_buf_sz + 2);
 		ep->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
@@ -1200,7 +1199,7 @@ static int epic_rx(struct net_device *dev, int budget)
 			/* Check if the packet is long enough to accept without copying
 			   to a minimally-sized skbuff. */
 			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			    (skb = netdev_alloc_skb(dev, pkt_len + 2)) != NULL) {
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
 				pci_dma_sync_single_for_cpu(ep->pci_dev,
 							    ep->rx_ring[entry].bufaddr,
@@ -1233,7 +1232,7 @@ static int epic_rx(struct net_device *dev, int budget)
 		entry = ep->dirty_rx % RX_RING_SIZE;
 		if (ep->rx_skbuff[entry] == NULL) {
 			struct sk_buff *skb;
-			skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz + 2);
+			skb = ep->rx_skbuff[entry] = netdev_alloc_skb(dev, ep->rx_buf_sz + 2);
 			if (skb == NULL)
 				break;
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
index 313ba3b..8814b2f 100644
--- a/drivers/net/ethernet/smsc/smc911x.c
+++ b/drivers/net/ethernet/smsc/smc911x.c
@@ -401,7 +401,7 @@ static inline void	 smc911x_rcv(struct net_device *dev)
 	} else {
 		/* Receive a valid packet */
 		/* Alloc a buffer with extra room for DMA alignment */
-		skb=dev_alloc_skb(pkt_len+32);
+		skb = netdev_alloc_skb(dev, pkt_len+32);
 		if (unlikely(skb == NULL)) {
 			PRINTK( "%s: Low memory, rcvd packet dropped.\n",
 				dev->name);
@@ -2065,7 +2065,6 @@ static int __devinit smc911x_drv_probe(struct platform_device *pdev)
 
 	ndev = alloc_etherdev(sizeof(struct smc911x_local));
 	if (!ndev) {
-		printk("%s: could not allocate device.\n", CARDNAME);
 		ret = -ENOMEM;
 		goto release_1;
 	}
diff --git a/drivers/net/ethernet/smsc/smc9194.c b/drivers/net/ethernet/smsc/smc9194.c
index 4e45094..50823da 100644
--- a/drivers/net/ethernet/smsc/smc9194.c
+++ b/drivers/net/ethernet/smsc/smc9194.c
@@ -1222,7 +1222,7 @@ static void smc_rcv(struct net_device *dev)
 		if ( status & RS_MULTICAST )
 			dev->stats.multicast++;
 
-		skb = dev_alloc_skb( packet_length + 5);
+		skb = netdev_alloc_skb(dev, packet_length + 5);
 
 		if ( skb == NULL ) {
 			printk(KERN_NOTICE CARDNAME ": Low memory, packet dropped.\n");
diff --git a/drivers/net/ethernet/smsc/smc91c92_cs.c b/drivers/net/ethernet/smsc/smc91c92_cs.c
index ada927a..d12e48a 100644
--- a/drivers/net/ethernet/smsc/smc91c92_cs.c
+++ b/drivers/net/ethernet/smsc/smc91c92_cs.c
@@ -1500,7 +1500,7 @@ static void smc_rx(struct net_device *dev)
 	struct sk_buff *skb;
 	
 	/* Note: packet_length adds 5 or 6 extra bytes here! */
-	skb = dev_alloc_skb(packet_length+2);
+	skb = netdev_alloc_skb(dev, packet_length+2);
 	
 	if (skb == NULL) {
 	    pr_debug("%s: Low memory, packet dropped.\n", dev->name);
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 64ad3ed..fee4493 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -463,7 +463,7 @@ static inline void  smc_rcv(struct net_device *dev)
 		 * multiple of 4 bytes on 32 bit buses.
 		 * Hence packet_len - 6 + 2 + 2 + 2.
 		 */
-		skb = dev_alloc_skb(packet_len);
+		skb = netdev_alloc_skb(dev, packet_len);
 		if (unlikely(skb == NULL)) {
 			printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
 				dev->name);
@@ -2223,7 +2223,6 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
 
 	ndev = alloc_etherdev(sizeof(struct smc_local));
 	if (!ndev) {
-		printk("%s: could not allocate device.\n", CARDNAME);
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -2281,7 +2280,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
 	if (ret)
 		goto out_release_io;
 #if defined(CONFIG_SA1100_ASSABET)
-	NCR_0 |= NCR_ENET_OSC_EN;
+	neponset_ncr_set(NCR_ENET_OSC_EN);
 #endif
 	platform_set_drvdata(pdev, ndev);
 	ret = smc_enable_device(pdev);
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 24d2df0..4a69710 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1833,6 +1833,7 @@ static int smsc911x_set_mac_address(struct net_device *dev, void *p)
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
 
 	spin_lock_irq(&pdata->mac_lock);
@@ -2374,7 +2375,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
 
 	dev = alloc_etherdev(sizeof(struct smsc911x_data));
 	if (!dev) {
-		pr_warn("Could not allocate device\n");
 		retval = -ENOMEM;
 		goto out_release_io_1;
 	}
@@ -2486,7 +2486,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
 				   "Mac Address is read from LAN911x EEPROM");
 		} else {
 			/* eeprom values are invalid, generate random MAC */
-			random_ether_addr(dev->dev_addr);
+			eth_hw_addr_random(dev);
 			smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
 			SMSC_TRACE(pdata, probe,
 				   "MAC Address is set to random_ether_addr");
diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c
index a9efbdf..3838647 100644
--- a/drivers/net/ethernet/smsc/smsc9420.c
+++ b/drivers/net/ethernet/smsc/smsc9420.c
@@ -509,10 +509,9 @@ static void smsc9420_check_mac_address(struct net_device *dev)
 			smsc_dbg(PROBE, "Mac Address is read from EEPROM");
 		} else {
 			/* eeprom values are invalid, generate random MAC */
-			random_ether_addr(dev->dev_addr);
+			eth_hw_addr_random(dev);
 			smsc9420_set_mac_address(dev);
-			smsc_dbg(PROBE,
-				"MAC Address is set to random_ether_addr");
+			smsc_dbg(PROBE, "MAC Address is set to random");
 		}
 	}
 }
@@ -850,8 +849,6 @@ static int smsc9420_alloc_rx_buffer(struct smsc9420_pdata *pd, int index)
 		return -ENOMEM;
 	}
 
-	skb->dev = pd->dev;
-
 	mapping = pci_map_single(pd->pdev, skb_tail_pointer(skb),
 				 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 	if (pci_dma_mapping_error(pd->pdev, mapping)) {
@@ -1598,10 +1595,8 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	pci_set_master(pdev);
 
 	dev = alloc_etherdev(sizeof(*pd));
-	if (!dev) {
-		printk(KERN_ERR "ether device alloc failed\n");
+	if (!dev)
 		goto out_disable_pci_device_1;
-	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6ee593a..e85ffbd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -878,7 +878,7 @@ static void stmmac_check_ether_addr(struct stmmac_priv *priv)
 					     priv->dev->base_addr,
 					     priv->dev->dev_addr, 0);
 		if  (!is_valid_ether_addr(priv->dev->dev_addr))
-			random_ether_addr(priv->dev->dev_addr);
+			eth_hw_addr_random(priv->dev);
 	}
 	pr_warning("%s: device MAC address %pM\n", priv->dev->name,
 						   priv->dev->dev_addr);
@@ -910,10 +910,9 @@ static int stmmac_open(struct net_device *dev)
 
 #ifdef CONFIG_STMMAC_TIMER
 	priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
-	if (unlikely(priv->tm == NULL)) {
-		pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
+	if (unlikely(priv->tm == NULL))
 		return -ENOMEM;
-	}
+
 	priv->tm->freq = tmrate;
 
 	/* Test if the external timer can be actually used.
@@ -1801,10 +1800,8 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
 	struct stmmac_priv *priv;
 
 	ndev = alloc_etherdev(sizeof(struct stmmac_priv));
-	if (!ndev) {
-		pr_err("%s: ERROR: allocating the device\n", __func__);
+	if (!ndev)
 		return NULL;
-	}
 
 	SET_NETDEV_DEV(ndev, device);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 50ad5b8..da66ed7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -85,7 +85,7 @@ static int __devinit stmmac_pci_probe(struct pci_dev *pdev,
 			continue;
 		addr = pci_iomap(pdev, i, 0);
 		if (addr == NULL) {
-			pr_err("%s: ERROR: cannot map regiser memory, aborting",
+			pr_err("%s: ERROR: cannot map register memory, aborting",
 			       __func__);
 			ret = -EIO;
 			goto err_out_map_failed;
diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c
index f10665f..3c22955 100644
--- a/drivers/net/ethernet/sun/cassini.c
+++ b/drivers/net/ethernet/sun/cassini.c
@@ -104,8 +104,8 @@
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
 
-#define cas_page_map(x)      kmap_atomic((x), KM_SKB_DATA_SOFTIRQ)
-#define cas_page_unmap(x)    kunmap_atomic((x), KM_SKB_DATA_SOFTIRQ)
+#define cas_page_map(x)      kmap_atomic((x))
+#define cas_page_unmap(x)    kunmap_atomic((x))
 #define CAS_NCPUS            num_online_cpus()
 
 #define cas_skb_release(x)  netif_rx(x)
@@ -835,7 +835,6 @@ static int cas_saturn_firmware_init(struct cas *cp)
 	cp->fw_data = vmalloc(cp->fw_size);
 	if (!cp->fw_data) {
 		err = -ENOMEM;
-		pr_err("\"%s\" Failed %d\n", fw_name, err);
 		goto out;
 	}
 	memcpy(cp->fw_data, &fw->data[2], cp->fw_size);
@@ -1975,7 +1974,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
 	else
 		alloclen = max(hlen, RX_COPY_MIN);
 
-	skb = dev_alloc_skb(alloclen + swivel + cp->crc_size);
+	skb = netdev_alloc_skb(cp->dev, alloclen + swivel + cp->crc_size);
 	if (skb == NULL)
 		return -1;
 
@@ -4947,7 +4946,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
 
 	dev = alloc_etherdev(sizeof(*cp));
 	if (!dev) {
-		dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_out_disable_pdev;
 	}
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index cf43393..d83c508 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9685,10 +9685,8 @@ static struct net_device * __devinit niu_alloc_and_init(
 	struct niu *np;
 
 	dev = alloc_etherdev_mq(sizeof(struct niu), NIU_NUM_TXCHAN);
-	if (!dev) {
-		dev_err(gen_dev, "Etherdev alloc failed, aborting\n");
+	if (!dev)
 		return NULL;
-	}
 
 	SET_NETDEV_DEV(dev, gen_dev);
 
diff --git a/drivers/net/ethernet/sun/sunbmac.c b/drivers/net/ethernet/sun/sunbmac.c
index 220f724..f359863 100644
--- a/drivers/net/ethernet/sun/sunbmac.c
+++ b/drivers/net/ethernet/sun/sunbmac.c
@@ -853,7 +853,7 @@ static void bigmac_rx(struct bigmac *bp)
 			/* Trim the original skb for the netif. */
 			skb_trim(skb, len);
 		} else {
-			struct sk_buff *copy_skb = dev_alloc_skb(len + 2);
+			struct sk_buff *copy_skb = netdev_alloc_skb(bp->dev, len + 2);
 
 			if (copy_skb == NULL) {
 				drops++;
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 31441a8..ba04159 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2885,7 +2885,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
 	dev = alloc_etherdev(sizeof(*gp));
 	if (!dev) {
-		pr_err("Etherdev alloc failed, aborting\n");
 		err = -ENOMEM;
 		goto err_disable_device;
 	}
diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c
index 09c5186..8b627e2 100644
--- a/drivers/net/ethernet/sun/sunhme.c
+++ b/drivers/net/ethernet/sun/sunhme.c
@@ -2043,7 +2043,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
 			/* Trim the original skb for the netif. */
 			skb_trim(skb, len);
 		} else {
-			struct sk_buff *copy_skb = dev_alloc_skb(len + 2);
+			struct sk_buff *copy_skb = netdev_alloc_skb(dev, len + 2);
 
 			if (copy_skb == NULL) {
 				drops++;
diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c
index b28f743..b42d1c5 100644
--- a/drivers/net/ethernet/sun/sunqe.c
+++ b/drivers/net/ethernet/sun/sunqe.c
@@ -435,7 +435,7 @@ static void qe_rx(struct sunqe *qep)
 			dev->stats.rx_length_errors++;
 			dev->stats.rx_dropped++;
 		} else {
-			skb = dev_alloc_skb(len + 2);
+			skb = netdev_alloc_skb(dev, len + 2);
 			if (skb == NULL) {
 				drops++;
 				dev->stats.rx_dropped++;
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 8c6c059..92a037a 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -949,10 +949,9 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port)
 		int map_len = (ETH_FRAME_LEN + 7) & ~7;
 
 		err = -ENOMEM;
-		if (!buf) {
-			pr_err("TX buffer allocation failure\n");
+		if (!buf)
 			goto err_out;
-		}
+
 		err = -EFAULT;
 		if ((unsigned long)buf & (8UL - 1)) {
 			pr_err("TX buffer misaligned\n");
@@ -1027,10 +1026,8 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
 	int err, i;
 
 	dev = alloc_etherdev(sizeof(*vp));
-	if (!dev) {
-		pr_err("Etherdev alloc failed, aborting\n");
+	if (!dev)
 		return ERR_PTR(-ENOMEM);
-	}
 
 	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff;
@@ -1165,10 +1162,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
 
 	port = kzalloc(sizeof(*port), GFP_KERNEL);
 	err = -ENOMEM;
-	if (!port) {
-		pr_err("Cannot allocate vnet_port\n");
+	if (!port)
 		goto err_out_put_mdesc;
-	}
 
 	for (i = 0; i < ETH_ALEN; i++)
 		port->raddr[i] = (*rmac >> (5 - i) * 8) & 0xff;
diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c
index 4b19e9b..ad973ff 100644
--- a/drivers/net/ethernet/tehuti/tehuti.c
+++ b/drivers/net/ethernet/tehuti/tehuti.c
@@ -1089,12 +1089,11 @@ static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f)
 	ENTER;
 	dno = bdx_rxdb_available(db) - 1;
 	while (dno > 0) {
-		skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN);
+		skb = netdev_alloc_skb(priv->ndev, f->m.pktsz + NET_IP_ALIGN);
 		if (!skb) {
-			pr_err("NO MEM: dev_alloc_skb failed\n");
+			pr_err("NO MEM: netdev_alloc_skb failed\n");
 			break;
 		}
-		skb->dev = priv->ndev;
 		skb_reserve(skb, NET_IP_ALIGN);
 
 		idx = bdx_rxdb_alloc_elem(db);
@@ -1258,7 +1257,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
 		skb = dm->skb;
 
 		if (len < BDX_COPYBREAK &&
-		    (skb2 = dev_alloc_skb(len + NET_IP_ALIGN))) {
+		    (skb2 = netdev_alloc_skb(priv->ndev, len + NET_IP_ALIGN))) {
 			skb_reserve(skb2, NET_IP_ALIGN);
 			/*skb_put(skb2, len); */
 			pci_dma_sync_single_for_cpu(priv->pdev,
@@ -1978,7 +1977,6 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		ndev = alloc_etherdev(sizeof(struct bdx_priv));
 		if (!ndev) {
 			err = -ENOMEM;
-			pr_err("alloc_etherdev failed\n");
 			goto err_out_iomap;
 		}
 
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index cbc8df7..860c252 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -1143,11 +1143,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 	}
 
 	dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
-
-	if (!dev) {
-		printk(KERN_ERR "cpmac: Unable to allocate net_device\n");
+	if (!dev)
 		return -ENOMEM;
-	}
 
 	platform_set_drvdata(pdev, dev);
 	priv = netdev_priv(dev);
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 4fa0bcb..f053aeb 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -992,10 +992,9 @@ static irqreturn_t emac_irq(int irq, void *dev_id)
 
 static struct sk_buff *emac_rx_alloc(struct emac_priv *priv)
 {
-	struct sk_buff *skb = dev_alloc_skb(priv->rx_buf_size);
+	struct sk_buff *skb = netdev_alloc_skb(priv->ndev, priv->rx_buf_size);
 	if (WARN_ON(!skb))
 		return NULL;
-	skb->dev = priv->ndev;
 	skb_reserve(skb, NET_IP_ALIGN);
 	return skb;
 }
@@ -1260,10 +1259,10 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
 	/* Store mac addr in priv and rx channel and set it in EMAC hw */
 	memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
 	memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
+	ndev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	/* MAC address is configured only after the interface is enabled. */
 	if (netif_running(ndev)) {
-		memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
 		emac_setmac(priv, EMAC_DEF_RX_CH, priv->mac_addr);
 	}
 
@@ -1790,7 +1789,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 
 	ndev = alloc_etherdev(sizeof(struct emac_priv));
 	if (!ndev) {
-		dev_err(&pdev->dev, "error allocating net_device\n");
 		rc = -ENOMEM;
 		goto free_clk;
 	}
@@ -1898,7 +1896,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 
 	if (!is_valid_ether_addr(priv->mac_addr)) {
 		/* Use random MAC if none passed */
-		random_ether_addr(priv->mac_addr);
+		eth_hw_addr_random(ndev);
+		memcpy(priv->mac_addr, ndev->dev_addr, ndev->addr_len);
 		dev_warn(&pdev->dev, "using random MAC addr: %pM\n",
 							priv->mac_addr);
 	}
diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c
index 9c0dd6b..817ad3b 100644
--- a/drivers/net/ethernet/ti/tlan.c
+++ b/drivers/net/ethernet/ti/tlan.c
@@ -486,7 +486,6 @@ static int __devinit tlan_probe1(struct pci_dev *pdev,
 
 	dev = alloc_etherdev(sizeof(struct tlan_priv));
 	if (dev == NULL) {
-		pr_err("Could not allocate memory for device\n");
 		rc = -ENOMEM;
 		goto err_out_regions;
 	}
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c
index d9951af..948c4f2 100644
--- a/drivers/net/ethernet/tile/tilepro.c
+++ b/drivers/net/ethernet/tile/tilepro.c
@@ -419,7 +419,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
 #endif
 
 	/* Avoid "false sharing" with last cache line. */
-	/* ISSUE: This is already done by "dev_alloc_skb()". */
+	/* ISSUE: This is already done by "netdev_alloc_skb()". */
 	unsigned int len =
 		 (((small ? LIPP_SMALL_PACKET_SIZE : large_size) +
 		   CHIP_L2_LINE_SIZE() - 1) & -CHIP_L2_LINE_SIZE());
@@ -433,7 +433,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info,
 	struct sk_buff **skb_ptr;
 
 	/* Request 96 extra bytes for alignment purposes. */
-	skb = dev_alloc_skb(len + padding);
+	skb = netdev_alloc_skb(info->napi->dev, len + padding);
 	if (skb == NULL)
 		return false;
 
@@ -2190,6 +2190,7 @@ static int tile_net_set_mac_address(struct net_device *dev, void *p)
 
 	/* ISSUE: Note that "dev_addr" is now a pointer. */
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	return 0;
 }
@@ -2254,7 +2255,7 @@ static int tile_net_get_mac(struct net_device *dev)
 		 * can't get its MAC address, we are most likely running
 		 * the simulator, so let's generate a random MAC address.
 		 */
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 	}
 
 	return 0;
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
index fd4ed7f..5c14f82 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
@@ -1621,10 +1621,9 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
 		kfree(target->hwinfo);
 		target->hwinfo = kzalloc(be16_to_cpu(scan_info->size),
 					 GFP_KERNEL);
-		if (!target->hwinfo) {
-			pr_info("%s: kzalloc failed\n", __func__);
+		if (!target->hwinfo)
 			continue;
-		}
+
 		/* copy hw scan info */
 		memcpy(target->hwinfo, scan_info, scan_info->size);
 		target->essid_len = strnlen(scan_info->essid,
diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c
index 71b785c..651a70c 100644
--- a/drivers/net/ethernet/toshiba/tc35815.c
+++ b/drivers/net/ethernet/toshiba/tc35815.c
@@ -453,7 +453,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev,
 				       dma_addr_t *dma_handle)
 {
 	struct sk_buff *skb;
-	skb = dev_alloc_skb(RX_BUF_SIZE);
+	skb = netdev_alloc_skb(dev, RX_BUF_SIZE);
 	if (!skb)
 		return NULL;
 	*dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE,
@@ -808,10 +808,9 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev,
 
 	/* dev zeroed in alloc_etherdev */
 	dev = alloc_etherdev(sizeof(*lp));
-	if (dev == NULL) {
-		dev_err(&pdev->dev, "unable to alloc new ethernet\n");
+	if (dev == NULL)
 		return -ENOMEM;
-	}
+
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	lp = netdev_priv(dev);
 	lp->dev = dev;
@@ -850,7 +849,7 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev,
 	/* Retrieve the ethernet address. */
 	if (tc35815_init_dev_addr(dev)) {
 		dev_warn(&pdev->dev, "not valid ether addr\n");
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 	}
 
 	rc = register_netdev(dev);
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index 164fb77..fc5521c 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -1582,10 +1582,8 @@ tsi108_init_one(struct platform_device *pdev)
 	/* Create an ethernet device instance */
 
 	dev = alloc_etherdev(sizeof(struct tsi108_prv_data));
-	if (!dev) {
-		printk("tsi108_eth: Could not allocate a device structure\n");
+	if (!dev)
 		return -ENOMEM;
-	}
 
 	printk("tsi108_eth%d: probe...\n", pdev->id);
 	data = netdev_priv(dev);
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 10b18eb..39b8cf3 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -927,7 +927,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 	dev = alloc_etherdev(sizeof(struct rhine_private));
 	if (!dev) {
 		rc = -ENOMEM;
-		dev_err(&pdev->dev, "alloc_etherdev failed\n");
 		goto err_out;
 	}
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -984,7 +983,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 	if (!is_valid_ether_addr(dev->dev_addr)) {
 		/* Report it and use a random ethernet address instead */
 		netdev_err(dev, "Invalid MAC address: %pM\n", dev->dev_addr);
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 		netdev_info(dev, "Using random MAC address: %pM\n",
 			    dev->dev_addr);
 	}
@@ -1156,7 +1155,6 @@ static void alloc_rbufs(struct net_device *dev)
 		rp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
-		skb->dev = dev;                 /* Mark as being used by this device. */
 
 		rp->rx_skbuff_dma[i] =
 			pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
@@ -1941,7 +1939,6 @@ static int rhine_rx(struct net_device *dev, int limit)
 			rp->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break;	/* Better luck next round. */
-			skb->dev = dev;	/* Mark as being used by this device. */
 			rp->rx_skbuff_dma[entry] =
 				pci_map_single(rp->pdev, skb->data,
 					       rp->rx_buf_sz,
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index cb35b14..8a5d7c1 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -1509,7 +1509,7 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
 	struct rx_desc *rd = &(vptr->rx.ring[idx]);
 	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 
-	rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64);
+	rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx.buf_sz + 64);
 	if (rd_info->skb == NULL)
 		return -ENOMEM;
 
@@ -2730,10 +2730,8 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
 	}
 
 	dev = alloc_etherdev(sizeof(struct velocity_info));
-	if (!dev) {
-		dev_err(&pdev->dev, "allocate net device failed.\n");
+	if (!dev)
 		goto out;
-	}
 
 	/* Chain it all together */
 
diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig
index d5a8260..5778a4a 100644
--- a/drivers/net/ethernet/xilinx/Kconfig
+++ b/drivers/net/ethernet/xilinx/Kconfig
@@ -25,6 +25,14 @@ config XILINX_EMACLITE
 	---help---
 	  This driver supports the 10/100 Ethernet Lite from Xilinx.
 
+config XILINX_AXI_EMAC
+	tristate "Xilinx 10/100/1000 AXI Ethernet support"
+	depends on (PPC32 || MICROBLAZE)
+	select PHYLIB
+	---help---
+	  This driver supports the 10/100/1000 Ethernet from Xilinx for the
+	  AXI bus interface used in Xilinx Virtex FPGAs.
+
 config XILINX_LL_TEMAC
 	tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
 	depends on (PPC || MICROBLAZE)
diff --git a/drivers/net/ethernet/xilinx/Makefile b/drivers/net/ethernet/xilinx/Makefile
index 5feac73..214205e 100644
--- a/drivers/net/ethernet/xilinx/Makefile
+++ b/drivers/net/ethernet/xilinx/Makefile
@@ -5,3 +5,5 @@
 ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
 obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
 obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
+xilinx_emac-objs := xilinx_axienet_main.o xilinx_axienet_mdio.o
+obj-$(CONFIG_XILINX_AXI_EMAC) += xilinx_emac.o
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index f21addb..d21591a 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -327,7 +327,9 @@ static int temac_set_mac_address(struct net_device *ndev, void *address)
 		memcpy(ndev->dev_addr, address, ETH_ALEN);
 
 	if (!is_valid_ether_addr(ndev->dev_addr))
-		random_ether_addr(ndev->dev_addr);
+		eth_hw_addr_random(ndev);
+	else
+		ndev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
 	/* set up unicast MAC address filter set its mac address */
 	mutex_lock(&lp->indirect_mutex);
@@ -1011,10 +1013,9 @@ static int __devinit temac_of_probe(struct platform_device *op)
 
 	/* Init network device structure */
 	ndev = alloc_etherdev(sizeof(*lp));
-	if (!ndev) {
-		dev_err(&op->dev, "could not allocate device.\n");
+	if (!ndev)
 		return -ENOMEM;
-	}
+
 	ether_setup(ndev);
 	dev_set_drvdata(&op->dev, ndev);
 	SET_NETDEV_DEV(ndev, &op->dev);
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
new file mode 100644
index 0000000..cc83af0
--- /dev/null
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -0,0 +1,508 @@
+/*
+ * Definitions for Xilinx Axi Ethernet device driver.
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
+ * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ */
+
+#ifndef XILINX_AXIENET_H
+#define XILINX_AXIENET_H
+
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+/* Packet size info */
+#define XAE_HDR_SIZE			14 /* Size of Ethernet header */
+#define XAE_HDR_VLAN_SIZE		18 /* Size of an Ethernet hdr + VLAN */
+#define XAE_TRL_SIZE			 4 /* Size of Ethernet trailer (FCS) */
+#define XAE_MTU			      1500 /* Max MTU of an Ethernet frame */
+#define XAE_JUMBO_MTU		      9000 /* Max MTU of a jumbo Eth. frame */
+
+#define XAE_MAX_FRAME_SIZE	 (XAE_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE)
+#define XAE_MAX_VLAN_FRAME_SIZE  (XAE_MTU + XAE_HDR_VLAN_SIZE + XAE_TRL_SIZE)
+#define XAE_MAX_JUMBO_FRAME_SIZE (XAE_JUMBO_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE)
+
+/* Configuration options */
+
+/* Accept all incoming packets. Default: disabled (cleared) */
+#define XAE_OPTION_PROMISC			(1 << 0)
+
+/* Jumbo frame support for Tx & Rx. Default: disabled (cleared) */
+#define XAE_OPTION_JUMBO			(1 << 1)
+
+/* VLAN Rx & Tx frame support. Default: disabled (cleared) */
+#define XAE_OPTION_VLAN				(1 << 2)
+
+/* Enable recognition of flow control frames on Rx. Default: enabled (set) */
+#define XAE_OPTION_FLOW_CONTROL			(1 << 4)
+
+/* Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not
+ * stripped. Default: disabled (set) */
+#define XAE_OPTION_FCS_STRIP			(1 << 5)
+
+/* Generate FCS field and add PAD automatically for outgoing frames.
+ * Default: enabled (set) */
+#define XAE_OPTION_FCS_INSERT			(1 << 6)
+
+/* Enable Length/Type error checking for incoming frames. When this option is
+ * set, the MAC will filter frames that have a mismatched type/length field
+ * and if XAE_OPTION_REPORT_RXERR is set, the user is notified when these
+ * types of frames are encountered. When this option is cleared, the MAC will
+ * allow these types of frames to be received. Default: enabled (set) */
+#define XAE_OPTION_LENTYPE_ERR			(1 << 7)
+
+/* Enable the transmitter. Default: enabled (set) */
+#define XAE_OPTION_TXEN				(1 << 11)
+
+/*  Enable the receiver. Default: enabled (set) */
+#define XAE_OPTION_RXEN				(1 << 12)
+
+/*  Default options set when device is initialized or reset */
+#define XAE_OPTION_DEFAULTS				   \
+				(XAE_OPTION_TXEN |	   \
+				 XAE_OPTION_FLOW_CONTROL | \
+				 XAE_OPTION_RXEN)
+
+/* Axi DMA Register definitions */
+
+#define XAXIDMA_TX_CR_OFFSET	0x00000000 /* Channel control */
+#define XAXIDMA_TX_SR_OFFSET	0x00000004 /* Status */
+#define XAXIDMA_TX_CDESC_OFFSET	0x00000008 /* Current descriptor pointer */
+#define XAXIDMA_TX_TDESC_OFFSET	0x00000010 /* Tail descriptor pointer */
+
+#define XAXIDMA_RX_CR_OFFSET	0x00000030 /* Channel control */
+#define XAXIDMA_RX_SR_OFFSET	0x00000034 /* Status */
+#define XAXIDMA_RX_CDESC_OFFSET	0x00000038 /* Current descriptor pointer */
+#define XAXIDMA_RX_TDESC_OFFSET	0x00000040 /* Tail descriptor pointer */
+
+#define XAXIDMA_CR_RUNSTOP_MASK	0x00000001 /* Start/stop DMA channel */
+#define XAXIDMA_CR_RESET_MASK	0x00000004 /* Reset DMA engine */
+
+#define XAXIDMA_BD_NDESC_OFFSET		0x00 /* Next descriptor pointer */
+#define XAXIDMA_BD_BUFA_OFFSET		0x08 /* Buffer address */
+#define XAXIDMA_BD_CTRL_LEN_OFFSET	0x18 /* Control/buffer length */
+#define XAXIDMA_BD_STS_OFFSET		0x1C /* Status */
+#define XAXIDMA_BD_USR0_OFFSET		0x20 /* User IP specific word0 */
+#define XAXIDMA_BD_USR1_OFFSET		0x24 /* User IP specific word1 */
+#define XAXIDMA_BD_USR2_OFFSET		0x28 /* User IP specific word2 */
+#define XAXIDMA_BD_USR3_OFFSET		0x2C /* User IP specific word3 */
+#define XAXIDMA_BD_USR4_OFFSET		0x30 /* User IP specific word4 */
+#define XAXIDMA_BD_ID_OFFSET		0x34 /* Sw ID */
+#define XAXIDMA_BD_HAS_STSCNTRL_OFFSET	0x38 /* Whether has stscntrl strm */
+#define XAXIDMA_BD_HAS_DRE_OFFSET	0x3C /* Whether has DRE */
+
+#define XAXIDMA_BD_HAS_DRE_SHIFT	8 /* Whether has DRE shift */
+#define XAXIDMA_BD_HAS_DRE_MASK		0xF00 /* Whether has DRE mask */
+#define XAXIDMA_BD_WORDLEN_MASK		0xFF /* Whether has DRE mask */
+
+#define XAXIDMA_BD_CTRL_LENGTH_MASK	0x007FFFFF /* Requested len */
+#define XAXIDMA_BD_CTRL_TXSOF_MASK	0x08000000 /* First tx packet */
+#define XAXIDMA_BD_CTRL_TXEOF_MASK	0x04000000 /* Last tx packet */
+#define XAXIDMA_BD_CTRL_ALL_MASK	0x0C000000 /* All control bits */
+
+#define XAXIDMA_DELAY_MASK		0xFF000000 /* Delay timeout counter */
+#define XAXIDMA_COALESCE_MASK		0x00FF0000 /* Coalesce counter */
+
+#define XAXIDMA_DELAY_SHIFT		24
+#define XAXIDMA_COALESCE_SHIFT		16
+
+#define XAXIDMA_IRQ_IOC_MASK		0x00001000 /* Completion intr */
+#define XAXIDMA_IRQ_DELAY_MASK		0x00002000 /* Delay interrupt */
+#define XAXIDMA_IRQ_ERROR_MASK		0x00004000 /* Error interrupt */
+#define XAXIDMA_IRQ_ALL_MASK		0x00007000 /* All interrupts */
+
+/* Default TX/RX Threshold and waitbound values for SGDMA mode */
+#define XAXIDMA_DFT_TX_THRESHOLD	24
+#define XAXIDMA_DFT_TX_WAITBOUND	254
+#define XAXIDMA_DFT_RX_THRESHOLD	24
+#define XAXIDMA_DFT_RX_WAITBOUND	254
+
+#define XAXIDMA_BD_CTRL_TXSOF_MASK	0x08000000 /* First tx packet */
+#define XAXIDMA_BD_CTRL_TXEOF_MASK	0x04000000 /* Last tx packet */
+#define XAXIDMA_BD_CTRL_ALL_MASK	0x0C000000 /* All control bits */
+
+#define XAXIDMA_BD_STS_ACTUAL_LEN_MASK	0x007FFFFF /* Actual len */
+#define XAXIDMA_BD_STS_COMPLETE_MASK	0x80000000 /* Completed */
+#define XAXIDMA_BD_STS_DEC_ERR_MASK	0x40000000 /* Decode error */
+#define XAXIDMA_BD_STS_SLV_ERR_MASK	0x20000000 /* Slave error */
+#define XAXIDMA_BD_STS_INT_ERR_MASK	0x10000000 /* Internal err */
+#define XAXIDMA_BD_STS_ALL_ERR_MASK	0x70000000 /* All errors */
+#define XAXIDMA_BD_STS_RXSOF_MASK	0x08000000 /* First rx pkt */
+#define XAXIDMA_BD_STS_RXEOF_MASK	0x04000000 /* Last rx pkt */
+#define XAXIDMA_BD_STS_ALL_MASK		0xFC000000 /* All status bits */
+
+#define XAXIDMA_BD_MINIMUM_ALIGNMENT	0x40
+
+/* Axi Ethernet registers definition */
+#define XAE_RAF_OFFSET		0x00000000 /* Reset and Address filter */
+#define XAE_TPF_OFFSET		0x00000004 /* Tx Pause Frame */
+#define XAE_IFGP_OFFSET		0x00000008 /* Tx Inter-frame gap adjustment*/
+#define XAE_IS_OFFSET		0x0000000C /* Interrupt status */
+#define XAE_IP_OFFSET		0x00000010 /* Interrupt pending */
+#define XAE_IE_OFFSET		0x00000014 /* Interrupt enable */
+#define XAE_TTAG_OFFSET		0x00000018 /* Tx VLAN TAG */
+#define XAE_RTAG_OFFSET		0x0000001C /* Rx VLAN TAG */
+#define XAE_UAWL_OFFSET		0x00000020 /* Unicast address word lower */
+#define XAE_UAWU_OFFSET		0x00000024 /* Unicast address word upper */
+#define XAE_TPID0_OFFSET	0x00000028 /* VLAN TPID0 register */
+#define XAE_TPID1_OFFSET	0x0000002C /* VLAN TPID1 register */
+#define XAE_PPST_OFFSET		0x00000030 /* PCS PMA Soft Temac Status Reg */
+#define XAE_RCW0_OFFSET		0x00000400 /* Rx Configuration Word 0 */
+#define XAE_RCW1_OFFSET		0x00000404 /* Rx Configuration Word 1 */
+#define XAE_TC_OFFSET		0x00000408 /* Tx Configuration */
+#define XAE_FCC_OFFSET		0x0000040C /* Flow Control Configuration */
+#define XAE_EMMC_OFFSET		0x00000410 /* EMAC mode configuration */
+#define XAE_PHYC_OFFSET		0x00000414 /* RGMII/SGMII configuration */
+#define XAE_MDIO_MC_OFFSET	0x00000500 /* MII Management Config */
+#define XAE_MDIO_MCR_OFFSET	0x00000504 /* MII Management Control */
+#define XAE_MDIO_MWD_OFFSET	0x00000508 /* MII Management Write Data */
+#define XAE_MDIO_MRD_OFFSET	0x0000050C /* MII Management Read Data */
+#define XAE_MDIO_MIS_OFFSET	0x00000600 /* MII Management Interrupt Status */
+#define XAE_MDIO_MIP_OFFSET	0x00000620 /* MII Mgmt Interrupt Pending
+					    * register offset */
+#define XAE_MDIO_MIE_OFFSET	0x00000640 /* MII Management Interrupt Enable
+					    * register offset */
+#define XAE_MDIO_MIC_OFFSET	0x00000660 /* MII Management Interrupt Clear
+					    * register offset. */
+#define XAE_UAW0_OFFSET		0x00000700 /* Unicast address word 0 */
+#define XAE_UAW1_OFFSET		0x00000704 /* Unicast address word 1 */
+#define XAE_FMI_OFFSET		0x00000708 /* Filter Mask Index */
+#define XAE_AF0_OFFSET		0x00000710 /* Address Filter 0 */
+#define XAE_AF1_OFFSET		0x00000714 /* Address Filter 1 */
+
+#define XAE_TX_VLAN_DATA_OFFSET 0x00004000 /* TX VLAN data table address */
+#define XAE_RX_VLAN_DATA_OFFSET 0x00008000 /* RX VLAN data table address */
+#define XAE_MCAST_TABLE_OFFSET	0x00020000 /* Multicast table address */
+
+/* Bit Masks for Axi Ethernet RAF register */
+#define XAE_RAF_MCSTREJ_MASK		0x00000002 /* Reject receive multicast
+						    * destination address */
+#define XAE_RAF_BCSTREJ_MASK		0x00000004 /* Reject receive broadcast
+						    * destination address */
+#define XAE_RAF_TXVTAGMODE_MASK		0x00000018 /* Tx VLAN TAG mode */
+#define XAE_RAF_RXVTAGMODE_MASK		0x00000060 /* Rx VLAN TAG mode */
+#define XAE_RAF_TXVSTRPMODE_MASK	0x00000180 /* Tx VLAN STRIP mode */
+#define XAE_RAF_RXVSTRPMODE_MASK	0x00000600 /* Rx VLAN STRIP mode */
+#define XAE_RAF_NEWFNCENBL_MASK		0x00000800 /* New function mode */
+#define XAE_RAF_EMULTIFLTRENBL_MASK	0x00001000 /* Exteneded Multicast
+						    * Filtering mode
+						    */
+#define XAE_RAF_STATSRST_MASK		0x00002000 /* Stats. Counter Reset */
+#define XAE_RAF_RXBADFRMEN_MASK		0x00004000 /* Recv Bad Frame Enable */
+#define XAE_RAF_TXVTAGMODE_SHIFT	3 /* Tx Tag mode shift bits */
+#define XAE_RAF_RXVTAGMODE_SHIFT	5 /* Rx Tag mode shift bits */
+#define XAE_RAF_TXVSTRPMODE_SHIFT	7 /* Tx strip mode shift bits*/
+#define XAE_RAF_RXVSTRPMODE_SHIFT	9 /* Rx Strip mode shift bits*/
+
+/* Bit Masks for Axi Ethernet TPF and IFGP registers */
+#define XAE_TPF_TPFV_MASK		0x0000FFFF /* Tx pause frame value */
+#define XAE_IFGP0_IFGP_MASK		0x0000007F /* Transmit inter-frame
+						    * gap adjustment value */
+
+/* Bit Masks for Axi Ethernet IS, IE and IP registers, Same masks apply
+ * for all 3 registers. */
+#define XAE_INT_HARDACSCMPLT_MASK	0x00000001 /* Hard register access
+						    * complete */
+#define XAE_INT_AUTONEG_MASK		0x00000002 /* Auto negotiation
+						    * complete */
+#define XAE_INT_RXCMPIT_MASK		0x00000004 /* Rx complete */
+#define XAE_INT_RXRJECT_MASK		0x00000008 /* Rx frame rejected */
+#define XAE_INT_RXFIFOOVR_MASK		0x00000010 /* Rx fifo overrun */
+#define XAE_INT_TXCMPIT_MASK		0x00000020 /* Tx complete */
+#define XAE_INT_RXDCMLOCK_MASK		0x00000040 /* Rx Dcm Lock */
+#define XAE_INT_MGTRDY_MASK		0x00000080 /* MGT clock Lock */
+#define XAE_INT_PHYRSTCMPLT_MASK	0x00000100 /* Phy Reset complete */
+#define XAE_INT_ALL_MASK		0x0000003F /* All the ints */
+
+#define XAE_INT_RECV_ERROR_MASK				\
+	(XAE_INT_RXRJECT_MASK | XAE_INT_RXFIFOOVR_MASK) /* INT bits that
+							 * indicate receive
+							 * errors */
+
+/* Bit masks for Axi Ethernet VLAN TPID Word 0 register */
+#define XAE_TPID_0_MASK		0x0000FFFF /* TPID 0 */
+#define XAE_TPID_1_MASK		0xFFFF0000 /* TPID 1 */
+
+/* Bit masks for Axi Ethernet VLAN TPID Word 1 register */
+#define XAE_TPID_2_MASK		0x0000FFFF /* TPID 0 */
+#define XAE_TPID_3_MASK		0xFFFF0000 /* TPID 1 */
+
+/* Bit masks for Axi Ethernet RCW1 register */
+#define XAE_RCW1_RST_MASK	0x80000000 /* Reset */
+#define XAE_RCW1_JUM_MASK	0x40000000 /* Jumbo frame enable */
+#define XAE_RCW1_FCS_MASK	0x20000000 /* In-Band FCS enable
+					    * (FCS not stripped) */
+#define XAE_RCW1_RX_MASK	0x10000000 /* Receiver enable */
+#define XAE_RCW1_VLAN_MASK	0x08000000 /* VLAN frame enable */
+#define XAE_RCW1_LT_DIS_MASK	0x02000000 /* Length/type field valid check
+					    * disable */
+#define XAE_RCW1_CL_DIS_MASK	0x01000000 /* Control frame Length check
+					    * disable */
+#define XAE_RCW1_PAUSEADDR_MASK 0x0000FFFF /* Pause frame source address
+					    * bits [47:32]. Bits [31:0] are
+					    * stored in register RCW0 */
+
+/* Bit masks for Axi Ethernet TC register */
+#define XAE_TC_RST_MASK		0x80000000 /* Reset */
+#define XAE_TC_JUM_MASK		0x40000000 /* Jumbo frame enable */
+#define XAE_TC_FCS_MASK		0x20000000 /* In-Band FCS enable
+					    * (FCS not generated) */
+#define XAE_TC_TX_MASK		0x10000000 /* Transmitter enable */
+#define XAE_TC_VLAN_MASK	0x08000000 /* VLAN frame enable */
+#define XAE_TC_IFG_MASK		0x02000000 /* Inter-frame gap adjustment
+					    * enable */
+
+/* Bit masks for Axi Ethernet FCC register */
+#define XAE_FCC_FCRX_MASK	0x20000000 /* Rx flow control enable */
+#define XAE_FCC_FCTX_MASK	0x40000000 /* Tx flow control enable */
+
+/* Bit masks for Axi Ethernet EMMC register */
+#define XAE_EMMC_LINKSPEED_MASK	0xC0000000 /* Link speed */
+#define XAE_EMMC_RGMII_MASK	0x20000000 /* RGMII mode enable */
+#define XAE_EMMC_SGMII_MASK	0x10000000 /* SGMII mode enable */
+#define XAE_EMMC_GPCS_MASK	0x08000000 /* 1000BaseX mode enable */
+#define XAE_EMMC_HOST_MASK	0x04000000 /* Host interface enable */
+#define XAE_EMMC_TX16BIT	0x02000000 /* 16 bit Tx client enable */
+#define XAE_EMMC_RX16BIT	0x01000000 /* 16 bit Rx client enable */
+#define XAE_EMMC_LINKSPD_10	0x00000000 /* Link Speed mask for 10 Mbit */
+#define XAE_EMMC_LINKSPD_100	0x40000000 /* Link Speed mask for 100 Mbit */
+#define XAE_EMMC_LINKSPD_1000	0x80000000 /* Link Speed mask for 1000 Mbit */
+
+/* Bit masks for Axi Ethernet PHYC register */
+#define XAE_PHYC_SGMIILINKSPEED_MASK	0xC0000000 /* SGMII link speed mask*/
+#define XAE_PHYC_RGMIILINKSPEED_MASK	0x0000000C /* RGMII link speed */
+#define XAE_PHYC_RGMIIHD_MASK		0x00000002 /* RGMII Half-duplex */
+#define XAE_PHYC_RGMIILINK_MASK		0x00000001 /* RGMII link status */
+#define XAE_PHYC_RGLINKSPD_10		0x00000000 /* RGMII link 10 Mbit */
+#define XAE_PHYC_RGLINKSPD_100		0x00000004 /* RGMII link 100 Mbit */
+#define XAE_PHYC_RGLINKSPD_1000		0x00000008 /* RGMII link 1000 Mbit */
+#define XAE_PHYC_SGLINKSPD_10		0x00000000 /* SGMII link 10 Mbit */
+#define XAE_PHYC_SGLINKSPD_100		0x40000000 /* SGMII link 100 Mbit */
+#define XAE_PHYC_SGLINKSPD_1000		0x80000000 /* SGMII link 1000 Mbit */
+
+/* Bit masks for Axi Ethernet MDIO interface MC register */
+#define XAE_MDIO_MC_MDIOEN_MASK		0x00000040 /* MII management enable */
+#define XAE_MDIO_MC_CLOCK_DIVIDE_MAX	0x3F	   /* Maximum MDIO divisor */
+
+/* Bit masks for Axi Ethernet MDIO interface MCR register */
+#define XAE_MDIO_MCR_PHYAD_MASK		0x1F000000 /* Phy Address Mask */
+#define XAE_MDIO_MCR_PHYAD_SHIFT	24	   /* Phy Address Shift */
+#define XAE_MDIO_MCR_REGAD_MASK		0x001F0000 /* Reg Address Mask */
+#define XAE_MDIO_MCR_REGAD_SHIFT	16	   /* Reg Address Shift */
+#define XAE_MDIO_MCR_OP_MASK		0x0000C000 /* Operation Code Mask */
+#define XAE_MDIO_MCR_OP_SHIFT		13	   /* Operation Code Shift */
+#define XAE_MDIO_MCR_OP_READ_MASK	0x00008000 /* Op Code Read Mask */
+#define XAE_MDIO_MCR_OP_WRITE_MASK	0x00004000 /* Op Code Write Mask */
+#define XAE_MDIO_MCR_INITIATE_MASK	0x00000800 /* Ready Mask */
+#define XAE_MDIO_MCR_READY_MASK		0x00000080 /* Ready Mask */
+
+/* Bit masks for Axi Ethernet MDIO interface MIS, MIP, MIE, MIC registers */
+#define XAE_MDIO_INT_MIIM_RDY_MASK	0x00000001 /* MIIM Interrupt */
+
+/* Bit masks for Axi Ethernet UAW1 register */
+#define XAE_UAW1_UNICASTADDR_MASK	0x0000FFFF /* Station address bits
+						    * [47:32]; Station address
+						    * bits [31:0] are stored in
+						    * register UAW0 */
+
+/* Bit masks for Axi Ethernet FMI register */
+#define XAE_FMI_PM_MASK			0x80000000 /* Promis. mode enable */
+#define XAE_FMI_IND_MASK		0x00000003 /* Index Mask */
+
+#define XAE_MDIO_DIV_DFT		29 /* Default MDIO clock divisor */
+
+/* Defines for different options for C_PHY_TYPE parameter in Axi Ethernet IP */
+#define XAE_PHY_TYPE_MII		0
+#define XAE_PHY_TYPE_GMII		1
+#define XAE_PHY_TYPE_RGMII_1_3		2
+#define XAE_PHY_TYPE_RGMII_2_0		3
+#define XAE_PHY_TYPE_SGMII		4
+#define XAE_PHY_TYPE_1000BASE_X		5
+
+#define XAE_MULTICAST_CAM_TABLE_NUM	4 /* Total number of entries in the
+					   * hardware multicast table. */
+
+/* Axi Ethernet Synthesis features */
+#define XAE_FEATURE_PARTIAL_RX_CSUM	(1 << 0)
+#define XAE_FEATURE_PARTIAL_TX_CSUM	(1 << 1)
+#define XAE_FEATURE_FULL_RX_CSUM	(1 << 2)
+#define XAE_FEATURE_FULL_TX_CSUM	(1 << 3)
+
+#define XAE_NO_CSUM_OFFLOAD		0
+
+#define XAE_FULL_CSUM_STATUS_MASK	0x00000038
+#define XAE_IP_UDP_CSUM_VALIDATED	0x00000003
+#define XAE_IP_TCP_CSUM_VALIDATED	0x00000002
+
+#define DELAY_OF_ONE_MILLISEC		1000
+
+/**
+ * struct axidma_bd - Axi Dma buffer descriptor layout
+ * @next:         MM2S/S2MM Next Descriptor Pointer
+ * @reserved1:    Reserved and not used
+ * @phys:         MM2S/S2MM Buffer Address
+ * @reserved2:    Reserved and not used
+ * @reserved3:    Reserved and not used
+ * @reserved4:    Reserved and not used
+ * @cntrl:        MM2S/S2MM Control value
+ * @status:       MM2S/S2MM Status value
+ * @app0:         MM2S/S2MM User Application Field 0.
+ * @app1:         MM2S/S2MM User Application Field 1.
+ * @app2:         MM2S/S2MM User Application Field 2.
+ * @app3:         MM2S/S2MM User Application Field 3.
+ * @app4:         MM2S/S2MM User Application Field 4.
+ * @sw_id_offset: MM2S/S2MM Sw ID
+ * @reserved5:    Reserved and not used
+ * @reserved6:    Reserved and not used
+ */
+struct axidma_bd {
+	u32 next;	/* Physical address of next buffer descriptor */
+	u32 reserved1;
+	u32 phys;
+	u32 reserved2;
+	u32 reserved3;
+	u32 reserved4;
+	u32 cntrl;
+	u32 status;
+	u32 app0;
+	u32 app1;	/* TX start << 16 | insert */
+	u32 app2;	/* TX csum seed */
+	u32 app3;
+	u32 app4;
+	u32 sw_id_offset;
+	u32 reserved5;
+	u32 reserved6;
+};
+
+/**
+ * struct axienet_local - axienet private per device data
+ * @ndev:	Pointer for net_device to which it will be attached.
+ * @dev:	Pointer to device structure
+ * @phy_dev:	Pointer to PHY device structure attached to the axienet_local
+ * @phy_node:	Pointer to device node structure
+ * @mii_bus:	Pointer to MII bus structure
+ * @mdio_irqs:	IRQs table for MDIO bus required in mii_bus structure
+ * @regs:	Base address for the axienet_local device address space
+ * @dma_regs:	Base address for the axidma device address space
+ * @dma_err_tasklet: Tasklet structure to process Axi DMA errors
+ * @tx_irq:	Axidma TX IRQ number
+ * @rx_irq:	Axidma RX IRQ number
+ * @temac_type:	axienet type to identify between soft and hard temac
+ * @phy_type:	Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X
+ * @options:	AxiEthernet option word
+ * @last_link:	Phy link state in which the PHY was negotiated earlier
+ * @features:	Stores the extended features supported by the axienet hw
+ * @tx_bd_v:	Virtual address of the TX buffer descriptor ring
+ * @tx_bd_p:	Physical address(start address) of the TX buffer descr. ring
+ * @rx_bd_v:	Virtual address of the RX buffer descriptor ring
+ * @rx_bd_p:	Physical address(start address) of the RX buffer descr. ring
+ * @tx_bd_ci:	Stores the index of the Tx buffer descriptor in the ring being
+ *		accessed currently. Used while alloc. BDs before a TX starts
+ * @tx_bd_tail:	Stores the index of the Tx buffer descriptor in the ring being
+ *		accessed currently. Used while processing BDs after the TX
+ *		completed.
+ * @rx_bd_ci:	Stores the index of the Rx buffer descriptor in the ring being
+ *		accessed currently.
+ * @max_frm_size: Stores the maximum size of the frame that can be that
+ *		  Txed/Rxed in the existing hardware. If jumbo option is
+ *		  supported, the maximum frame size would be 9k. Else it is
+ *		  1522 bytes (assuming support for basic VLAN)
+ * @jumbo_support: Stores hardware configuration for jumbo support. If hardware
+ *		   can handle jumbo packets, this entry will be 1, else 0.
+ */
+struct axienet_local {
+	struct net_device *ndev;
+	struct device *dev;
+
+	/* Connection to PHY device */
+	struct phy_device *phy_dev;	/* Pointer to PHY device */
+	struct device_node *phy_node;
+
+	/* MDIO bus data */
+	struct mii_bus *mii_bus;	/* MII bus reference */
+	int mdio_irqs[PHY_MAX_ADDR];	/* IRQs table for MDIO bus */
+
+	/* IO registers, dma functions and IRQs */
+	void __iomem *regs;
+	void __iomem *dma_regs;
+
+	struct tasklet_struct dma_err_tasklet;
+
+	int tx_irq;
+	int rx_irq;
+	u32 temac_type;
+	u32 phy_type;
+
+	u32 options;			/* Current options word */
+	u32 last_link;
+	u32 features;
+
+	/* Buffer descriptors */
+	struct axidma_bd *tx_bd_v;
+	dma_addr_t tx_bd_p;
+	struct axidma_bd *rx_bd_v;
+	dma_addr_t rx_bd_p;
+	u32 tx_bd_ci;
+	u32 tx_bd_tail;
+	u32 rx_bd_ci;
+
+	u32 max_frm_size;
+	u32 jumbo_support;
+
+	int csum_offload_on_tx_path;
+	int csum_offload_on_rx_path;
+
+	u32 coalesce_count_rx;
+	u32 coalesce_count_tx;
+};
+
+/**
+ * struct axiethernet_option - Used to set axi ethernet hardware options
+ * @opt:	Option to be set.
+ * @reg:	Register offset to be written for setting the option
+ * @m_or:	Mask to be ORed for setting the option in the register
+ */
+struct axienet_option {
+	u32 opt;
+	u32 reg;
+	u32 m_or;
+};
+
+/**
+ * axienet_ior - Memory mapped Axi Ethernet register read
+ * @lp:         Pointer to axienet local structure
+ * @offset:     Address offset from the base address of Axi Ethernet core
+ *
+ * returns: The contents of the Axi Ethernet register
+ *
+ * This function returns the contents of the corresponding register.
+ */
+static inline u32 axienet_ior(struct axienet_local *lp, off_t offset)
+{
+	return in_be32(lp->regs + offset);
+}
+
+/**
+ * axienet_iow - Memory mapped Axi Ethernet register write
+ * @lp:         Pointer to axienet local structure
+ * @offset:     Address offset from the base address of Axi Ethernet core
+ * @value:      Value to be written into the Axi Ethernet register
+ *
+ * This function writes the desired value into the corresponding Axi Ethernet
+ * register.
+ */
+static inline void axienet_iow(struct axienet_local *lp, off_t offset,
+			       u32 value)
+{
+	out_be32((lp->regs + offset), value);
+}
+
+/* Function prototypes visible in xilinx_axienet_mdio.c for other files */
+int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np);
+int axienet_mdio_wait_until_ready(struct axienet_local *lp);
+void axienet_mdio_teardown(struct axienet_local *lp);
+
+#endif /* XILINX_AXI_ENET_H */
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
new file mode 100644
index 0000000..2fcbeba
--- /dev/null
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -0,0 +1,1669 @@
+/*
+ * Xilinx Axi Ethernet device driver
+ *
+ * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi
+ * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>
+ * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
+ * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
+ * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ *
+ * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6
+ * and Spartan6.
+ *
+ * TODO:
+ *  - Add Axi Fifo support.
+ *  - Factor out Axi DMA code into separate driver.
+ *  - Test and fix basic multicast filtering.
+ *  - Add support for extended multicast filtering.
+ *  - Test basic VLAN support.
+ *  - Add support for extended VLAN support.
+ */
+
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/phy.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+
+#include "xilinx_axienet.h"
+
+/* Descriptors defines for Tx and Rx DMA - 2^n for the best performance */
+#define TX_BD_NUM		64
+#define RX_BD_NUM		128
+
+/* Must be shorter than length of ethtool_drvinfo.driver field to fit */
+#define DRIVER_NAME		"xaxienet"
+#define DRIVER_DESCRIPTION	"Xilinx Axi Ethernet driver"
+#define DRIVER_VERSION		"1.00a"
+
+#define AXIENET_REGS_N		32
+
+/* Match table for of_platform binding */
+static struct of_device_id axienet_of_match[] __devinitdata = {
+	{ .compatible = "xlnx,axi-ethernet-1.00.a", },
+	{ .compatible = "xlnx,axi-ethernet-1.01.a", },
+	{ .compatible = "xlnx,axi-ethernet-2.01.a", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, axienet_of_match);
+
+/* Option table for setting up Axi Ethernet hardware options */
+static struct axienet_option axienet_options[] = {
+	/* Turn on jumbo packet support for both Rx and Tx */
+	{
+		.opt = XAE_OPTION_JUMBO,
+		.reg = XAE_TC_OFFSET,
+		.m_or = XAE_TC_JUM_MASK,
+	}, {
+		.opt = XAE_OPTION_JUMBO,
+		.reg = XAE_RCW1_OFFSET,
+		.m_or = XAE_RCW1_JUM_MASK,
+	}, { /* Turn on VLAN packet support for both Rx and Tx */
+		.opt = XAE_OPTION_VLAN,
+		.reg = XAE_TC_OFFSET,
+		.m_or = XAE_TC_VLAN_MASK,
+	}, {
+		.opt = XAE_OPTION_VLAN,
+		.reg = XAE_RCW1_OFFSET,
+		.m_or = XAE_RCW1_VLAN_MASK,
+	}, { /* Turn on FCS stripping on receive packets */
+		.opt = XAE_OPTION_FCS_STRIP,
+		.reg = XAE_RCW1_OFFSET,
+		.m_or = XAE_RCW1_FCS_MASK,
+	}, { /* Turn on FCS insertion on transmit packets */
+		.opt = XAE_OPTION_FCS_INSERT,
+		.reg = XAE_TC_OFFSET,
+		.m_or = XAE_TC_FCS_MASK,
+	}, { /* Turn off length/type field checking on receive packets */
+		.opt = XAE_OPTION_LENTYPE_ERR,
+		.reg = XAE_RCW1_OFFSET,
+		.m_or = XAE_RCW1_LT_DIS_MASK,
+	}, { /* Turn on Rx flow control */
+		.opt = XAE_OPTION_FLOW_CONTROL,
+		.reg = XAE_FCC_OFFSET,
+		.m_or = XAE_FCC_FCRX_MASK,
+	}, { /* Turn on Tx flow control */
+		.opt = XAE_OPTION_FLOW_CONTROL,
+		.reg = XAE_FCC_OFFSET,
+		.m_or = XAE_FCC_FCTX_MASK,
+	}, { /* Turn on promiscuous frame filtering */
+		.opt = XAE_OPTION_PROMISC,
+		.reg = XAE_FMI_OFFSET,
+		.m_or = XAE_FMI_PM_MASK,
+	}, { /* Enable transmitter */
+		.opt = XAE_OPTION_TXEN,
+		.reg = XAE_TC_OFFSET,
+		.m_or = XAE_TC_TX_MASK,
+	}, { /* Enable receiver */
+		.opt = XAE_OPTION_RXEN,
+		.reg = XAE_RCW1_OFFSET,
+		.m_or = XAE_RCW1_RX_MASK,
+	},
+	{}
+};
+
+/**
+ * axienet_dma_in32 - Memory mapped Axi DMA register read
+ * @lp:		Pointer to axienet local structure
+ * @reg:	Address offset from the base address of the Axi DMA core
+ *
+ * returns: The contents of the Axi DMA register
+ *
+ * This function returns the contents of the corresponding Axi DMA register.
+ */
+static inline u32 axienet_dma_in32(struct axienet_local *lp, off_t reg)
+{
+	return in_be32(lp->dma_regs + reg);
+}
+
+/**
+ * axienet_dma_out32 - Memory mapped Axi DMA register write.
+ * @lp:		Pointer to axienet local structure
+ * @reg:	Address offset from the base address of the Axi DMA core
+ * @value:	Value to be written into the Axi DMA register
+ *
+ * This function writes the desired value into the corresponding Axi DMA
+ * register.
+ */
+static inline void axienet_dma_out32(struct axienet_local *lp,
+				     off_t reg, u32 value)
+{
+	out_be32((lp->dma_regs + reg), value);
+}
+
+/**
+ * axienet_dma_bd_release - Release buffer descriptor rings
+ * @ndev:	Pointer to the net_device structure
+ *
+ * This function is used to release the descriptors allocated in
+ * axienet_dma_bd_init. axienet_dma_bd_release is called when Axi Ethernet
+ * driver stop api is called.
+ */
+static void axienet_dma_bd_release(struct net_device *ndev)
+{
+	int i;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	for (i = 0; i < RX_BD_NUM; i++) {
+		dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys,
+				 lp->max_frm_size, DMA_FROM_DEVICE);
+		dev_kfree_skb((struct sk_buff *)
+			      (lp->rx_bd_v[i].sw_id_offset));
+	}
+
+	if (lp->rx_bd_v) {
+		dma_free_coherent(ndev->dev.parent,
+				  sizeof(*lp->rx_bd_v) * RX_BD_NUM,
+				  lp->rx_bd_v,
+				  lp->rx_bd_p);
+	}
+	if (lp->tx_bd_v) {
+		dma_free_coherent(ndev->dev.parent,
+				  sizeof(*lp->tx_bd_v) * TX_BD_NUM,
+				  lp->tx_bd_v,
+				  lp->tx_bd_p);
+	}
+}
+
+/**
+ * axienet_dma_bd_init - Setup buffer descriptor rings for Axi DMA
+ * @ndev:	Pointer to the net_device structure
+ *
+ * returns: 0, on success
+ *	    -ENOMEM, on failure
+ *
+ * This function is called to initialize the Rx and Tx DMA descriptor
+ * rings. This initializes the descriptors with required default values
+ * and is called when Axi Ethernet driver reset is called.
+ */
+static int axienet_dma_bd_init(struct net_device *ndev)
+{
+	u32 cr;
+	int i;
+	struct sk_buff *skb;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	/* Reset the indexes which are used for accessing the BDs */
+	lp->tx_bd_ci = 0;
+	lp->tx_bd_tail = 0;
+	lp->rx_bd_ci = 0;
+
+	/*
+	 * Allocate the Tx and Rx buffer descriptors.
+	 */
+	lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+					 sizeof(*lp->tx_bd_v) * TX_BD_NUM,
+					 &lp->tx_bd_p,
+					 GFP_KERNEL);
+	if (!lp->tx_bd_v) {
+		dev_err(&ndev->dev, "unable to allocate DMA Tx buffer "
+			"descriptors");
+		goto out;
+	}
+
+	lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+					 sizeof(*lp->rx_bd_v) * RX_BD_NUM,
+					 &lp->rx_bd_p,
+					 GFP_KERNEL);
+	if (!lp->rx_bd_v) {
+		dev_err(&ndev->dev, "unable to allocate DMA Rx buffer "
+			"descriptors");
+		goto out;
+	}
+
+	memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM);
+	for (i = 0; i < TX_BD_NUM; i++) {
+		lp->tx_bd_v[i].next = lp->tx_bd_p +
+				      sizeof(*lp->tx_bd_v) *
+				      ((i + 1) % TX_BD_NUM);
+	}
+
+	memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM);
+	for (i = 0; i < RX_BD_NUM; i++) {
+		lp->rx_bd_v[i].next = lp->rx_bd_p +
+				      sizeof(*lp->rx_bd_v) *
+				      ((i + 1) % RX_BD_NUM);
+
+		skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size);
+		if (!skb) {
+			dev_err(&ndev->dev, "alloc_skb error %d\n", i);
+			goto out;
+		}
+
+		lp->rx_bd_v[i].sw_id_offset = (u32) skb;
+		lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
+						     skb->data,
+						     lp->max_frm_size,
+						     DMA_FROM_DEVICE);
+		lp->rx_bd_v[i].cntrl = lp->max_frm_size;
+	}
+
+	/* Start updating the Rx channel control register */
+	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+	/* Update the interrupt coalesce count */
+	cr = ((cr & ~XAXIDMA_COALESCE_MASK) |
+	      ((lp->coalesce_count_rx) << XAXIDMA_COALESCE_SHIFT));
+	/* Update the delay timer count */
+	cr = ((cr & ~XAXIDMA_DELAY_MASK) |
+	      (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+	/* Enable coalesce, delay timer and error interrupts */
+	cr |= XAXIDMA_IRQ_ALL_MASK;
+	/* Write to the Rx channel control register */
+	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
+	/* Start updating the Tx channel control register */
+	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+	/* Update the interrupt coalesce count */
+	cr = (((cr & ~XAXIDMA_COALESCE_MASK)) |
+	      ((lp->coalesce_count_tx) << XAXIDMA_COALESCE_SHIFT));
+	/* Update the delay timer count */
+	cr = (((cr & ~XAXIDMA_DELAY_MASK)) |
+	      (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+	/* Enable coalesce, delay timer and error interrupts */
+	cr |= XAXIDMA_IRQ_ALL_MASK;
+	/* Write to the Tx channel control register */
+	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+
+	/* Populate the tail pointer and bring the Rx Axi DMA engine out of
+	 * halted state. This will make the Rx side ready for reception.*/
+	axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
+	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
+			  cr | XAXIDMA_CR_RUNSTOP_MASK);
+	axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p +
+			  (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
+
+	/* Write to the RS (Run-stop) bit in the Tx channel control register.
+	 * Tx channel is now ready to run. But only after we write to the
+	 * tail pointer register that the Tx channel will start transmitting */
+	axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
+	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
+			  cr | XAXIDMA_CR_RUNSTOP_MASK);
+
+	return 0;
+out:
+	axienet_dma_bd_release(ndev);
+	return -ENOMEM;
+}
+
+/**
+ * axienet_set_mac_address - Write the MAC address
+ * @ndev:	Pointer to the net_device structure
+ * @address:	6 byte Address to be written as MAC address
+ *
+ * This function is called to initialize the MAC address of the Axi Ethernet
+ * core. It writes to the UAW0 and UAW1 registers of the core.
+ */
+static void axienet_set_mac_address(struct net_device *ndev, void *address)
+{
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	if (address)
+		memcpy(ndev->dev_addr, address, ETH_ALEN);
+	if (!is_valid_ether_addr(ndev->dev_addr))
+		random_ether_addr(ndev->dev_addr);
+
+	/* Set up unicast MAC address filter set its mac address */
+	axienet_iow(lp, XAE_UAW0_OFFSET,
+		    (ndev->dev_addr[0]) |
+		    (ndev->dev_addr[1] << 8) |
+		    (ndev->dev_addr[2] << 16) |
+		    (ndev->dev_addr[3] << 24));
+	axienet_iow(lp, XAE_UAW1_OFFSET,
+		    (((axienet_ior(lp, XAE_UAW1_OFFSET)) &
+		      ~XAE_UAW1_UNICASTADDR_MASK) |
+		     (ndev->dev_addr[4] |
+		     (ndev->dev_addr[5] << 8))));
+}
+
+/**
+ * netdev_set_mac_address - Write the MAC address (from outside the driver)
+ * @ndev:	Pointer to the net_device structure
+ * @p:		6 byte Address to be written as MAC address
+ *
+ * returns: 0 for all conditions. Presently, there is no failure case.
+ *
+ * This function is called to initialize the MAC address of the Axi Ethernet
+ * core. It calls the core specific axienet_set_mac_address. This is the
+ * function that goes into net_device_ops structure entry ndo_set_mac_address.
+ */
+static int netdev_set_mac_address(struct net_device *ndev, void *p)
+{
+	struct sockaddr *addr = p;
+	axienet_set_mac_address(ndev, addr->sa_data);
+	return 0;
+}
+
+/**
+ * axienet_set_multicast_list - Prepare the multicast table
+ * @ndev:	Pointer to the net_device structure
+ *
+ * This function is called to initialize the multicast table during
+ * initialization. The Axi Ethernet basic multicast support has a four-entry
+ * multicast table which is initialized here. Additionally this function
+ * goes into the net_device_ops structure entry ndo_set_multicast_list. This
+ * means whenever the multicast table entries need to be updated this
+ * function gets called.
+ */
+static void axienet_set_multicast_list(struct net_device *ndev)
+{
+	int i;
+	u32 reg, af0reg, af1reg;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
+	    netdev_mc_count(ndev) > XAE_MULTICAST_CAM_TABLE_NUM) {
+		/* We must make the kernel realize we had to move into
+		 * promiscuous mode. If it was a promiscuous mode request
+		 * the flag is already set. If not we set it. */
+		ndev->flags |= IFF_PROMISC;
+		reg = axienet_ior(lp, XAE_FMI_OFFSET);
+		reg |= XAE_FMI_PM_MASK;
+		axienet_iow(lp, XAE_FMI_OFFSET, reg);
+		dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
+	} else if (!netdev_mc_empty(ndev)) {
+		struct netdev_hw_addr *ha;
+
+		i = 0;
+		netdev_for_each_mc_addr(ha, ndev) {
+			if (i >= XAE_MULTICAST_CAM_TABLE_NUM)
+				break;
+
+			af0reg = (ha->addr[0]);
+			af0reg |= (ha->addr[1] << 8);
+			af0reg |= (ha->addr[2] << 16);
+			af0reg |= (ha->addr[3] << 24);
+
+			af1reg = (ha->addr[4]);
+			af1reg |= (ha->addr[5] << 8);
+
+			reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
+			reg |= i;
+
+			axienet_iow(lp, XAE_FMI_OFFSET, reg);
+			axienet_iow(lp, XAE_AF0_OFFSET, af0reg);
+			axienet_iow(lp, XAE_AF1_OFFSET, af1reg);
+			i++;
+		}
+	} else {
+		reg = axienet_ior(lp, XAE_FMI_OFFSET);
+		reg &= ~XAE_FMI_PM_MASK;
+
+		axienet_iow(lp, XAE_FMI_OFFSET, reg);
+
+		for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
+			reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
+			reg |= i;
+
+			axienet_iow(lp, XAE_FMI_OFFSET, reg);
+			axienet_iow(lp, XAE_AF0_OFFSET, 0);
+			axienet_iow(lp, XAE_AF1_OFFSET, 0);
+		}
+
+		dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
+	}
+}
+
+/**
+ * axienet_setoptions - Set an Axi Ethernet option
+ * @ndev:	Pointer to the net_device structure
+ * @options:	Option to be enabled/disabled
+ *
+ * The Axi Ethernet core has multiple features which can be selectively turned
+ * on or off. The typical options could be jumbo frame option, basic VLAN
+ * option, promiscuous mode option etc. This function is used to set or clear
+ * these options in the Axi Ethernet hardware. This is done through
+ * axienet_option structure .
+ */
+static void axienet_setoptions(struct net_device *ndev, u32 options)
+{
+	int reg;
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct axienet_option *tp = &axienet_options[0];
+
+	while (tp->opt) {
+		reg = ((axienet_ior(lp, tp->reg)) & ~(tp->m_or));
+		if (options & tp->opt)
+			reg |= tp->m_or;
+		axienet_iow(lp, tp->reg, reg);
+		tp++;
+	}
+
+	lp->options |= options;
+}
+
+static void __axienet_device_reset(struct axienet_local *lp,
+				   struct device *dev, off_t offset)
+{
+	u32 timeout;
+	/* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset
+	 * process of Axi DMA takes a while to complete as all pending
+	 * commands/transfers will be flushed or completed during this
+	 * reset process. */
+	axienet_dma_out32(lp, offset, XAXIDMA_CR_RESET_MASK);
+	timeout = DELAY_OF_ONE_MILLISEC;
+	while (axienet_dma_in32(lp, offset) & XAXIDMA_CR_RESET_MASK) {
+		udelay(1);
+		if (--timeout == 0) {
+			dev_err(dev, "axienet_device_reset DMA "
+				"reset timeout!\n");
+			break;
+		}
+	}
+}
+
+/**
+ * axienet_device_reset - Reset and initialize the Axi Ethernet hardware.
+ * @ndev:	Pointer to the net_device structure
+ *
+ * This function is called to reset and initialize the Axi Ethernet core. This
+ * is typically called during initialization. It does a reset of the Axi DMA
+ * Rx/Tx channels and initializes the Axi DMA BDs. Since Axi DMA reset lines
+ * areconnected to Axi Ethernet reset lines, this in turn resets the Axi
+ * Ethernet core. No separate hardware reset is done for the Axi Ethernet
+ * core.
+ */
+static void axienet_device_reset(struct net_device *ndev)
+{
+	u32 axienet_status;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	__axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET);
+	__axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET);
+
+	lp->max_frm_size = XAE_MAX_VLAN_FRAME_SIZE;
+	lp->options &= (~XAE_OPTION_JUMBO);
+
+	if ((ndev->mtu > XAE_MTU) &&
+	    (ndev->mtu <= XAE_JUMBO_MTU) &&
+	    (lp->jumbo_support)) {
+		lp->max_frm_size = ndev->mtu + XAE_HDR_VLAN_SIZE +
+				   XAE_TRL_SIZE;
+		lp->options |= XAE_OPTION_JUMBO;
+	}
+
+	if (axienet_dma_bd_init(ndev)) {
+		dev_err(&ndev->dev, "axienet_device_reset descriptor "
+			"allocation failed\n");
+	}
+
+	axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET);
+	axienet_status &= ~XAE_RCW1_RX_MASK;
+	axienet_iow(lp, XAE_RCW1_OFFSET, axienet_status);
+
+	axienet_status = axienet_ior(lp, XAE_IP_OFFSET);
+	if (axienet_status & XAE_INT_RXRJECT_MASK)
+		axienet_iow(lp, XAE_IS_OFFSET, XAE_INT_RXRJECT_MASK);
+
+	axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK);
+
+	/* Sync default options with HW but leave receiver and
+	 * transmitter disabled.*/
+	axienet_setoptions(ndev, lp->options &
+			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+	axienet_set_mac_address(ndev, NULL);
+	axienet_set_multicast_list(ndev);
+	axienet_setoptions(ndev, lp->options);
+
+	ndev->trans_start = jiffies;
+}
+
+/**
+ * axienet_adjust_link - Adjust the PHY link speed/duplex.
+ * @ndev:	Pointer to the net_device structure
+ *
+ * This function is called to change the speed and duplex setting after
+ * auto negotiation is done by the PHY. This is the function that gets
+ * registered with the PHY interface through the "of_phy_connect" call.
+ */
+static void axienet_adjust_link(struct net_device *ndev)
+{
+	u32 emmc_reg;
+	u32 link_state;
+	u32 setspeed = 1;
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct phy_device *phy = lp->phy_dev;
+
+	link_state = phy->speed | (phy->duplex << 1) | phy->link;
+	if (lp->last_link != link_state) {
+		if ((phy->speed == SPEED_10) || (phy->speed == SPEED_100)) {
+			if (lp->phy_type == XAE_PHY_TYPE_1000BASE_X)
+				setspeed = 0;
+		} else {
+			if ((phy->speed == SPEED_1000) &&
+			    (lp->phy_type == XAE_PHY_TYPE_MII))
+				setspeed = 0;
+		}
+
+		if (setspeed == 1) {
+			emmc_reg = axienet_ior(lp, XAE_EMMC_OFFSET);
+			emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK;
+
+			switch (phy->speed) {
+			case SPEED_1000:
+				emmc_reg |= XAE_EMMC_LINKSPD_1000;
+				break;
+			case SPEED_100:
+				emmc_reg |= XAE_EMMC_LINKSPD_100;
+				break;
+			case SPEED_10:
+				emmc_reg |= XAE_EMMC_LINKSPD_10;
+				break;
+			default:
+				dev_err(&ndev->dev, "Speed other than 10, 100 "
+					"or 1Gbps is not supported\n");
+				break;
+			}
+
+			axienet_iow(lp, XAE_EMMC_OFFSET, emmc_reg);
+			lp->last_link = link_state;
+			phy_print_status(phy);
+		} else {
+			dev_err(&ndev->dev, "Error setting Axi Ethernet "
+				"mac speed\n");
+		}
+	}
+}
+
+/**
+ * axienet_start_xmit_done - Invoked once a transmit is completed by the
+ * Axi DMA Tx channel.
+ * @ndev:	Pointer to the net_device structure
+ *
+ * This function is invoked from the Axi DMA Tx isr to notify the completion
+ * of transmit operation. It clears fields in the corresponding Tx BDs and
+ * unmaps the corresponding buffer so that CPU can regain ownership of the
+ * buffer. It finally invokes "netif_wake_queue" to restart transmission if
+ * required.
+ */
+static void axienet_start_xmit_done(struct net_device *ndev)
+{
+	u32 size = 0;
+	u32 packets = 0;
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct axidma_bd *cur_p;
+	unsigned int status = 0;
+
+	cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+	status = cur_p->status;
+	while (status & XAXIDMA_BD_STS_COMPLETE_MASK) {
+		dma_unmap_single(ndev->dev.parent, cur_p->phys,
+				(cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK),
+				DMA_TO_DEVICE);
+		if (cur_p->app4)
+			dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
+		/*cur_p->phys = 0;*/
+		cur_p->app0 = 0;
+		cur_p->app1 = 0;
+		cur_p->app2 = 0;
+		cur_p->app4 = 0;
+		cur_p->status = 0;
+
+		size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
+		packets++;
+
+		lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM;
+		cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+		status = cur_p->status;
+	}
+
+	ndev->stats.tx_packets += packets;
+	ndev->stats.tx_bytes += size;
+	netif_wake_queue(ndev);
+}
+
+/**
+ * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy
+ * @lp:		Pointer to the axienet_local structure
+ * @num_frag:	The number of BDs to check for
+ *
+ * returns: 0, on success
+ *	    NETDEV_TX_BUSY, if any of the descriptors are not free
+ *
+ * This function is invoked before BDs are allocated and transmission starts.
+ * This function returns 0 if a BD or group of BDs can be allocated for
+ * transmission. If the BD or any of the BDs are not free the function
+ * returns a busy status. This is invoked from axienet_start_xmit.
+ */
+static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
+					    int num_frag)
+{
+	struct axidma_bd *cur_p;
+	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % TX_BD_NUM];
+	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
+		return NETDEV_TX_BUSY;
+	return 0;
+}
+
+/**
+ * axienet_start_xmit - Starts the transmission.
+ * @skb:	sk_buff pointer that contains data to be Txed.
+ * @ndev:	Pointer to net_device structure.
+ *
+ * returns: NETDEV_TX_OK, on success
+ *	    NETDEV_TX_BUSY, if any of the descriptors are not free
+ *
+ * This function is invoked from upper layers to initiate transmission. The
+ * function uses the next available free BDs and populates their fields to
+ * start the transmission. Additionally if checksum offloading is supported,
+ * it populates AXI Stream Control fields with appropriate values.
+ */
+static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	u32 ii;
+	u32 num_frag;
+	u32 csum_start_off;
+	u32 csum_index_off;
+	skb_frag_t *frag;
+	dma_addr_t tail_p;
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct axidma_bd *cur_p;
+
+	num_frag = skb_shinfo(skb)->nr_frags;
+	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+
+	if (axienet_check_tx_bd_space(lp, num_frag)) {
+		if (!netif_queue_stopped(ndev))
+			netif_stop_queue(ndev);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		if (lp->features & XAE_FEATURE_FULL_TX_CSUM) {
+			/* Tx Full Checksum Offload Enabled */
+			cur_p->app0 |= 2;
+		} else if (lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) {
+			csum_start_off = skb_transport_offset(skb);
+			csum_index_off = csum_start_off + skb->csum_offset;
+			/* Tx Partial Checksum Offload Enabled */
+			cur_p->app0 |= 1;
+			cur_p->app1 = (csum_start_off << 16) | csum_index_off;
+		}
+	} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+		cur_p->app0 |= 2; /* Tx Full Checksum Offload Enabled */
+	}
+
+	cur_p->cntrl = skb_headlen(skb) | XAXIDMA_BD_CTRL_TXSOF_MASK;
+	cur_p->phys = dma_map_single(ndev->dev.parent, skb->data,
+				     skb_headlen(skb), DMA_TO_DEVICE);
+
+	for (ii = 0; ii < num_frag; ii++) {
+		lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM;
+		cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+		frag = &skb_shinfo(skb)->frags[ii];
+		cur_p->phys = dma_map_single(ndev->dev.parent,
+					     skb_frag_address(frag),
+					     skb_frag_size(frag),
+					     DMA_TO_DEVICE);
+		cur_p->cntrl = skb_frag_size(frag);
+	}
+
+	cur_p->cntrl |= XAXIDMA_BD_CTRL_TXEOF_MASK;
+	cur_p->app4 = (unsigned long)skb;
+
+	tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+	/* Start the transfer */
+	axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p);
+	lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM;
+
+	return NETDEV_TX_OK;
+}
+
+/**
+ * axienet_recv - Is called from Axi DMA Rx Isr to complete the received
+ *		  BD processing.
+ * @ndev:	Pointer to net_device structure.
+ *
+ * This function is invoked from the Axi DMA Rx isr to process the Rx BDs. It
+ * does minimal processing and invokes "netif_rx" to complete further
+ * processing.
+ */
+static void axienet_recv(struct net_device *ndev)
+{
+	u32 length;
+	u32 csumstatus;
+	u32 size = 0;
+	u32 packets = 0;
+	dma_addr_t tail_p;
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct sk_buff *skb, *new_skb;
+	struct axidma_bd *cur_p;
+
+	tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
+	cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+	while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) {
+		skb = (struct sk_buff *) (cur_p->sw_id_offset);
+		length = cur_p->app4 & 0x0000FFFF;
+
+		dma_unmap_single(ndev->dev.parent, cur_p->phys,
+				 lp->max_frm_size,
+				 DMA_FROM_DEVICE);
+
+		skb_put(skb, length);
+		skb->protocol = eth_type_trans(skb, ndev);
+		/*skb_checksum_none_assert(skb);*/
+		skb->ip_summed = CHECKSUM_NONE;
+
+		/* if we're doing Rx csum offload, set it up */
+		if (lp->features & XAE_FEATURE_FULL_RX_CSUM) {
+			csumstatus = (cur_p->app2 &
+				      XAE_FULL_CSUM_STATUS_MASK) >> 3;
+			if ((csumstatus == XAE_IP_TCP_CSUM_VALIDATED) ||
+			    (csumstatus == XAE_IP_UDP_CSUM_VALIDATED)) {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+			}
+		} else if ((lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) != 0 &&
+			   skb->protocol == __constant_htons(ETH_P_IP) &&
+			   skb->len > 64) {
+			skb->csum = be32_to_cpu(cur_p->app3 & 0xFFFF);
+			skb->ip_summed = CHECKSUM_COMPLETE;
+		}
+
+		netif_rx(skb);
+
+		size += length;
+		packets++;
+
+		new_skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size);
+		if (!new_skb) {
+			dev_err(&ndev->dev, "no memory for new sk_buff\n");
+			return;
+		}
+		cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
+					     lp->max_frm_size,
+					     DMA_FROM_DEVICE);
+		cur_p->cntrl = lp->max_frm_size;
+		cur_p->status = 0;
+		cur_p->sw_id_offset = (u32) new_skb;
+
+		lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM;
+		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+	}
+
+	ndev->stats.rx_packets += packets;
+	ndev->stats.rx_bytes += size;
+
+	axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
+}
+
+/**
+ * axienet_tx_irq - Tx Done Isr.
+ * @irq:	irq number
+ * @_ndev:	net_device pointer
+ *
+ * returns: IRQ_HANDLED for all cases.
+ *
+ * This is the Axi DMA Tx done Isr. It invokes "axienet_start_xmit_done"
+ * to complete the BD processing.
+ */
+static irqreturn_t axienet_tx_irq(int irq, void *_ndev)
+{
+	u32 cr;
+	unsigned int status;
+	struct net_device *ndev = _ndev;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	status = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET);
+	if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
+		axienet_start_xmit_done(lp->ndev);
+		goto out;
+	}
+	if (!(status & XAXIDMA_IRQ_ALL_MASK))
+		dev_err(&ndev->dev, "No interrupts asserted in Tx path");
+	if (status & XAXIDMA_IRQ_ERROR_MASK) {
+		dev_err(&ndev->dev, "DMA Tx error 0x%x\n", status);
+		dev_err(&ndev->dev, "Current BD is at: 0x%x\n",
+			(lp->tx_bd_v[lp->tx_bd_ci]).phys);
+
+		cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+		/* Disable coalesce, delay timer and error interrupts */
+		cr &= (~XAXIDMA_IRQ_ALL_MASK);
+		/* Write to the Tx channel control register */
+		axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+
+		cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+		/* Disable coalesce, delay timer and error interrupts */
+		cr &= (~XAXIDMA_IRQ_ALL_MASK);
+		/* Write to the Rx channel control register */
+		axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
+		tasklet_schedule(&lp->dma_err_tasklet);
+	}
+out:
+	axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status);
+	return IRQ_HANDLED;
+}
+
+/**
+ * axienet_rx_irq - Rx Isr.
+ * @irq:	irq number
+ * @_ndev:	net_device pointer
+ *
+ * returns: IRQ_HANDLED for all cases.
+ *
+ * This is the Axi DMA Rx Isr. It invokes "axienet_recv" to complete the BD
+ * processing.
+ */
+static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
+{
+	u32 cr;
+	unsigned int status;
+	struct net_device *ndev = _ndev;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	status = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET);
+	if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) {
+		axienet_recv(lp->ndev);
+		goto out;
+	}
+	if (!(status & XAXIDMA_IRQ_ALL_MASK))
+		dev_err(&ndev->dev, "No interrupts asserted in Rx path");
+	if (status & XAXIDMA_IRQ_ERROR_MASK) {
+		dev_err(&ndev->dev, "DMA Rx error 0x%x\n", status);
+		dev_err(&ndev->dev, "Current BD is at: 0x%x\n",
+			(lp->rx_bd_v[lp->rx_bd_ci]).phys);
+
+		cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+		/* Disable coalesce, delay timer and error interrupts */
+		cr &= (~XAXIDMA_IRQ_ALL_MASK);
+		/* Finally write to the Tx channel control register */
+		axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+
+		cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+		/* Disable coalesce, delay timer and error interrupts */
+		cr &= (~XAXIDMA_IRQ_ALL_MASK);
+		/* write to the Rx channel control register */
+		axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
+		tasklet_schedule(&lp->dma_err_tasklet);
+	}
+out:
+	axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status);
+	return IRQ_HANDLED;
+}
+
+/**
+ * axienet_open - Driver open routine.
+ * @ndev:	Pointer to net_device structure
+ *
+ * returns: 0, on success.
+ *	    -ENODEV, if PHY cannot be connected to
+ *	    non-zero error value on failure
+ *
+ * This is the driver open routine. It calls phy_start to start the PHY device.
+ * It also allocates interrupt service routines, enables the interrupt lines
+ * and ISR handling. Axi Ethernet core is reset through Axi DMA core. Buffer
+ * descriptors are initialized.
+ */
+static int axienet_open(struct net_device *ndev)
+{
+	int ret, mdio_mcreg;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	dev_dbg(&ndev->dev, "axienet_open()\n");
+
+	mdio_mcreg = axienet_ior(lp, XAE_MDIO_MC_OFFSET);
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+	/* Disable the MDIO interface till Axi Ethernet Reset is completed.
+	 * When we do an Axi Ethernet reset, it resets the complete core
+	 * including the MDIO. If MDIO is not disabled when the reset
+	 * process is started, MDIO will be broken afterwards. */
+	axienet_iow(lp, XAE_MDIO_MC_OFFSET,
+		    (mdio_mcreg & (~XAE_MDIO_MC_MDIOEN_MASK)));
+	axienet_device_reset(ndev);
+	/* Enable the MDIO */
+	axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg);
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+
+	if (lp->phy_node) {
+		lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+					     axienet_adjust_link, 0,
+					     PHY_INTERFACE_MODE_GMII);
+		if (!lp->phy_dev) {
+			dev_err(lp->dev, "of_phy_connect() failed\n");
+			return -ENODEV;
+		}
+		phy_start(lp->phy_dev);
+	}
+
+	/* Enable interrupts for Axi DMA Tx */
+	ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev);
+	if (ret)
+		goto err_tx_irq;
+	/* Enable interrupts for Axi DMA Rx */
+	ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev);
+	if (ret)
+		goto err_rx_irq;
+	/* Enable tasklets for Axi DMA error handling */
+	tasklet_enable(&lp->dma_err_tasklet);
+	return 0;
+
+err_rx_irq:
+	free_irq(lp->tx_irq, ndev);
+err_tx_irq:
+	if (lp->phy_dev)
+		phy_disconnect(lp->phy_dev);
+	lp->phy_dev = NULL;
+	dev_err(lp->dev, "request_irq() failed\n");
+	return ret;
+}
+
+/**
+ * axienet_stop - Driver stop routine.
+ * @ndev:	Pointer to net_device structure
+ *
+ * returns: 0, on success.
+ *
+ * This is the driver stop routine. It calls phy_disconnect to stop the PHY
+ * device. It also removes the interrupt handlers and disables the interrupts.
+ * The Axi DMA Tx/Rx BDs are released.
+ */
+static int axienet_stop(struct net_device *ndev)
+{
+	u32 cr;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	dev_dbg(&ndev->dev, "axienet_close()\n");
+
+	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
+			  cr & (~XAXIDMA_CR_RUNSTOP_MASK));
+	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
+			  cr & (~XAXIDMA_CR_RUNSTOP_MASK));
+	axienet_setoptions(ndev, lp->options &
+			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+
+	tasklet_disable(&lp->dma_err_tasklet);
+
+	free_irq(lp->tx_irq, ndev);
+	free_irq(lp->rx_irq, ndev);
+
+	if (lp->phy_dev)
+		phy_disconnect(lp->phy_dev);
+	lp->phy_dev = NULL;
+
+	axienet_dma_bd_release(ndev);
+	return 0;
+}
+
+/**
+ * axienet_change_mtu - Driver change mtu routine.
+ * @ndev:	Pointer to net_device structure
+ * @new_mtu:	New mtu value to be applied
+ *
+ * returns: Always returns 0 (success).
+ *
+ * This is the change mtu driver routine. It checks if the Axi Ethernet
+ * hardware supports jumbo frames before changing the mtu. This can be
+ * called only when the device is not up.
+ */
+static int axienet_change_mtu(struct net_device *ndev, int new_mtu)
+{
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	if (netif_running(ndev))
+		return -EBUSY;
+	if (lp->jumbo_support) {
+		if ((new_mtu > XAE_JUMBO_MTU) || (new_mtu < 64))
+			return -EINVAL;
+		ndev->mtu = new_mtu;
+	} else {
+		if ((new_mtu > XAE_MTU) || (new_mtu < 64))
+			return -EINVAL;
+		ndev->mtu = new_mtu;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * axienet_poll_controller - Axi Ethernet poll mechanism.
+ * @ndev:	Pointer to net_device structure
+ *
+ * This implements Rx/Tx ISR poll mechanisms. The interrupts are disabled prior
+ * to polling the ISRs and are enabled back after the polling is done.
+ */
+static void axienet_poll_controller(struct net_device *ndev)
+{
+	struct axienet_local *lp = netdev_priv(ndev);
+	disable_irq(lp->tx_irq);
+	disable_irq(lp->rx_irq);
+	axienet_rx_irq(lp->tx_irq, ndev);
+	axienet_tx_irq(lp->rx_irq, ndev);
+	enable_irq(lp->tx_irq);
+	enable_irq(lp->rx_irq);
+}
+#endif
+
+static const struct net_device_ops axienet_netdev_ops = {
+	.ndo_open = axienet_open,
+	.ndo_stop = axienet_stop,
+	.ndo_start_xmit = axienet_start_xmit,
+	.ndo_change_mtu	= axienet_change_mtu,
+	.ndo_set_mac_address = netdev_set_mac_address,
+	.ndo_validate_addr = eth_validate_addr,
+	.ndo_set_rx_mode = axienet_set_multicast_list,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = axienet_poll_controller,
+#endif
+};
+
+/**
+ * axienet_ethtools_get_settings - Get Axi Ethernet settings related to PHY.
+ * @ndev:	Pointer to net_device structure
+ * @ecmd:	Pointer to ethtool_cmd structure
+ *
+ * This implements ethtool command for getting PHY settings. If PHY could
+ * not be found, the function returns -ENODEV. This function calls the
+ * relevant PHY ethtool API to get the PHY settings.
+ * Issue "ethtool ethX" under linux prompt to execute this function.
+ */
+static int axienet_ethtools_get_settings(struct net_device *ndev,
+					 struct ethtool_cmd *ecmd)
+{
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = lp->phy_dev;
+	if (!phydev)
+		return -ENODEV;
+	return phy_ethtool_gset(phydev, ecmd);
+}
+
+/**
+ * axienet_ethtools_set_settings - Set PHY settings as passed in the argument.
+ * @ndev:	Pointer to net_device structure
+ * @ecmd:	Pointer to ethtool_cmd structure
+ *
+ * This implements ethtool command for setting various PHY settings. If PHY
+ * could not be found, the function returns -ENODEV. This function calls the
+ * relevant PHY ethtool API to set the PHY.
+ * Issue e.g. "ethtool -s ethX speed 1000" under linux prompt to execute this
+ * function.
+ */
+static int axienet_ethtools_set_settings(struct net_device *ndev,
+					 struct ethtool_cmd *ecmd)
+{
+	struct axienet_local *lp = netdev_priv(ndev);
+	struct phy_device *phydev = lp->phy_dev;
+	if (!phydev)
+		return -ENODEV;
+	return phy_ethtool_sset(phydev, ecmd);
+}
+
+/**
+ * axienet_ethtools_get_drvinfo - Get various Axi Ethernet driver information.
+ * @ndev:	Pointer to net_device structure
+ * @ed:		Pointer to ethtool_drvinfo structure
+ *
+ * This implements ethtool command for getting the driver information.
+ * Issue "ethtool -i ethX" under linux prompt to execute this function.
+ */
+static void axienet_ethtools_get_drvinfo(struct net_device *ndev,
+					 struct ethtool_drvinfo *ed)
+{
+	memset(ed, 0, sizeof(struct ethtool_drvinfo));
+	strcpy(ed->driver, DRIVER_NAME);
+	strcpy(ed->version, DRIVER_VERSION);
+	ed->regdump_len = sizeof(u32) * AXIENET_REGS_N;
+}
+
+/**
+ * axienet_ethtools_get_regs_len - Get the total regs length present in the
+ *				   AxiEthernet core.
+ * @ndev:	Pointer to net_device structure
+ *
+ * This implements ethtool command for getting the total register length
+ * information.
+ */
+static int axienet_ethtools_get_regs_len(struct net_device *ndev)
+{
+	return sizeof(u32) * AXIENET_REGS_N;
+}
+
+/**
+ * axienet_ethtools_get_regs - Dump the contents of all registers present
+ *			       in AxiEthernet core.
+ * @ndev:	Pointer to net_device structure
+ * @regs:	Pointer to ethtool_regs structure
+ * @ret:	Void pointer used to return the contents of the registers.
+ *
+ * This implements ethtool command for getting the Axi Ethernet register dump.
+ * Issue "ethtool -d ethX" to execute this function.
+ */
+static void axienet_ethtools_get_regs(struct net_device *ndev,
+				      struct ethtool_regs *regs, void *ret)
+{
+	u32 *data = (u32 *) ret;
+	size_t len = sizeof(u32) * AXIENET_REGS_N;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	regs->version = 0;
+	regs->len = len;
+
+	memset(data, 0, len);
+	data[0] = axienet_ior(lp, XAE_RAF_OFFSET);
+	data[1] = axienet_ior(lp, XAE_TPF_OFFSET);
+	data[2] = axienet_ior(lp, XAE_IFGP_OFFSET);
+	data[3] = axienet_ior(lp, XAE_IS_OFFSET);
+	data[4] = axienet_ior(lp, XAE_IP_OFFSET);
+	data[5] = axienet_ior(lp, XAE_IE_OFFSET);
+	data[6] = axienet_ior(lp, XAE_TTAG_OFFSET);
+	data[7] = axienet_ior(lp, XAE_RTAG_OFFSET);
+	data[8] = axienet_ior(lp, XAE_UAWL_OFFSET);
+	data[9] = axienet_ior(lp, XAE_UAWU_OFFSET);
+	data[10] = axienet_ior(lp, XAE_TPID0_OFFSET);
+	data[11] = axienet_ior(lp, XAE_TPID1_OFFSET);
+	data[12] = axienet_ior(lp, XAE_PPST_OFFSET);
+	data[13] = axienet_ior(lp, XAE_RCW0_OFFSET);
+	data[14] = axienet_ior(lp, XAE_RCW1_OFFSET);
+	data[15] = axienet_ior(lp, XAE_TC_OFFSET);
+	data[16] = axienet_ior(lp, XAE_FCC_OFFSET);
+	data[17] = axienet_ior(lp, XAE_EMMC_OFFSET);
+	data[18] = axienet_ior(lp, XAE_PHYC_OFFSET);
+	data[19] = axienet_ior(lp, XAE_MDIO_MC_OFFSET);
+	data[20] = axienet_ior(lp, XAE_MDIO_MCR_OFFSET);
+	data[21] = axienet_ior(lp, XAE_MDIO_MWD_OFFSET);
+	data[22] = axienet_ior(lp, XAE_MDIO_MRD_OFFSET);
+	data[23] = axienet_ior(lp, XAE_MDIO_MIS_OFFSET);
+	data[24] = axienet_ior(lp, XAE_MDIO_MIP_OFFSET);
+	data[25] = axienet_ior(lp, XAE_MDIO_MIE_OFFSET);
+	data[26] = axienet_ior(lp, XAE_MDIO_MIC_OFFSET);
+	data[27] = axienet_ior(lp, XAE_UAW0_OFFSET);
+	data[28] = axienet_ior(lp, XAE_UAW1_OFFSET);
+	data[29] = axienet_ior(lp, XAE_FMI_OFFSET);
+	data[30] = axienet_ior(lp, XAE_AF0_OFFSET);
+	data[31] = axienet_ior(lp, XAE_AF1_OFFSET);
+}
+
+/**
+ * axienet_ethtools_get_pauseparam - Get the pause parameter setting for
+ *				     Tx and Rx paths.
+ * @ndev:	Pointer to net_device structure
+ * @epauseparm:	Pointer to ethtool_pauseparam structure.
+ *
+ * This implements ethtool command for getting axi ethernet pause frame
+ * setting. Issue "ethtool -a ethX" to execute this function.
+ */
+static void
+axienet_ethtools_get_pauseparam(struct net_device *ndev,
+				struct ethtool_pauseparam *epauseparm)
+{
+	u32 regval;
+	struct axienet_local *lp = netdev_priv(ndev);
+	epauseparm->autoneg  = 0;
+	regval = axienet_ior(lp, XAE_FCC_OFFSET);
+	epauseparm->tx_pause = regval & XAE_FCC_FCTX_MASK;
+	epauseparm->rx_pause = regval & XAE_FCC_FCRX_MASK;
+}
+
+/**
+ * axienet_ethtools_set_pauseparam - Set device pause parameter(flow control)
+ *				     settings.
+ * @ndev:	Pointer to net_device structure
+ * @epauseparam:Pointer to ethtool_pauseparam structure
+ *
+ * This implements ethtool command for enabling flow control on Rx and Tx
+ * paths. Issue "ethtool -A ethX tx on|off" under linux prompt to execute this
+ * function.
+ */
+static int
+axienet_ethtools_set_pauseparam(struct net_device *ndev,
+				struct ethtool_pauseparam *epauseparm)
+{
+	u32 regval = 0;
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	if (netif_running(ndev)) {
+		printk(KERN_ERR	"%s: Please stop netif before applying "
+		       "configruation\n", ndev->name);
+		return -EFAULT;
+	}
+
+	regval = axienet_ior(lp, XAE_FCC_OFFSET);
+	if (epauseparm->tx_pause)
+		regval |= XAE_FCC_FCTX_MASK;
+	else
+		regval &= ~XAE_FCC_FCTX_MASK;
+	if (epauseparm->rx_pause)
+		regval |= XAE_FCC_FCRX_MASK;
+	else
+		regval &= ~XAE_FCC_FCRX_MASK;
+	axienet_iow(lp, XAE_FCC_OFFSET, regval);
+
+	return 0;
+}
+
+/**
+ * axienet_ethtools_get_coalesce - Get DMA interrupt coalescing count.
+ * @ndev:	Pointer to net_device structure
+ * @ecoalesce:	Pointer to ethtool_coalesce structure
+ *
+ * This implements ethtool command for getting the DMA interrupt coalescing
+ * count on Tx and Rx paths. Issue "ethtool -c ethX" under linux prompt to
+ * execute this function.
+ */
+static int axienet_ethtools_get_coalesce(struct net_device *ndev,
+					 struct ethtool_coalesce *ecoalesce)
+{
+	u32 regval = 0;
+	struct axienet_local *lp = netdev_priv(ndev);
+	regval = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+	ecoalesce->rx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK)
+					     >> XAXIDMA_COALESCE_SHIFT;
+	regval = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+	ecoalesce->tx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK)
+					     >> XAXIDMA_COALESCE_SHIFT;
+	return 0;
+}
+
+/**
+ * axienet_ethtools_set_coalesce - Set DMA interrupt coalescing count.
+ * @ndev:	Pointer to net_device structure
+ * @ecoalesce:	Pointer to ethtool_coalesce structure
+ *
+ * This implements ethtool command for setting the DMA interrupt coalescing
+ * count on Tx and Rx paths. Issue "ethtool -C ethX rx-frames 5" under linux
+ * prompt to execute this function.
+ */
+static int axienet_ethtools_set_coalesce(struct net_device *ndev,
+					 struct ethtool_coalesce *ecoalesce)
+{
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	if (netif_running(ndev)) {
+		printk(KERN_ERR	"%s: Please stop netif before applying "
+		       "configruation\n", ndev->name);
+		return -EFAULT;
+	}
+
+	if ((ecoalesce->rx_coalesce_usecs) ||
+	    (ecoalesce->rx_coalesce_usecs_irq) ||
+	    (ecoalesce->rx_max_coalesced_frames_irq) ||
+	    (ecoalesce->tx_coalesce_usecs) ||
+	    (ecoalesce->tx_coalesce_usecs_irq) ||
+	    (ecoalesce->tx_max_coalesced_frames_irq) ||
+	    (ecoalesce->stats_block_coalesce_usecs) ||
+	    (ecoalesce->use_adaptive_rx_coalesce) ||
+	    (ecoalesce->use_adaptive_tx_coalesce) ||
+	    (ecoalesce->pkt_rate_low) ||
+	    (ecoalesce->rx_coalesce_usecs_low) ||
+	    (ecoalesce->rx_max_coalesced_frames_low) ||
+	    (ecoalesce->tx_coalesce_usecs_low) ||
+	    (ecoalesce->tx_max_coalesced_frames_low) ||
+	    (ecoalesce->pkt_rate_high) ||
+	    (ecoalesce->rx_coalesce_usecs_high) ||
+	    (ecoalesce->rx_max_coalesced_frames_high) ||
+	    (ecoalesce->tx_coalesce_usecs_high) ||
+	    (ecoalesce->tx_max_coalesced_frames_high) ||
+	    (ecoalesce->rate_sample_interval))
+		return -EOPNOTSUPP;
+	if (ecoalesce->rx_max_coalesced_frames)
+		lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
+	if (ecoalesce->tx_max_coalesced_frames)
+		lp->coalesce_count_tx = ecoalesce->tx_max_coalesced_frames;
+
+	return 0;
+}
+
+static struct ethtool_ops axienet_ethtool_ops = {
+	.get_settings   = axienet_ethtools_get_settings,
+	.set_settings   = axienet_ethtools_set_settings,
+	.get_drvinfo    = axienet_ethtools_get_drvinfo,
+	.get_regs_len   = axienet_ethtools_get_regs_len,
+	.get_regs       = axienet_ethtools_get_regs,
+	.get_link       = ethtool_op_get_link,
+	.get_pauseparam = axienet_ethtools_get_pauseparam,
+	.set_pauseparam = axienet_ethtools_set_pauseparam,
+	.get_coalesce   = axienet_ethtools_get_coalesce,
+	.set_coalesce   = axienet_ethtools_set_coalesce,
+};
+
+/**
+ * axienet_dma_err_handler - Tasklet handler for Axi DMA Error
+ * @data:	Data passed
+ *
+ * Resets the Axi DMA and Axi Ethernet devices, and reconfigures the
+ * Tx/Rx BDs.
+ */
+static void axienet_dma_err_handler(unsigned long data)
+{
+	u32 axienet_status;
+	u32 cr, i;
+	int mdio_mcreg;
+	struct axienet_local *lp = (struct axienet_local *) data;
+	struct net_device *ndev = lp->ndev;
+	struct axidma_bd *cur_p;
+
+	axienet_setoptions(ndev, lp->options &
+			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+	mdio_mcreg = axienet_ior(lp, XAE_MDIO_MC_OFFSET);
+	axienet_mdio_wait_until_ready(lp);
+	/* Disable the MDIO interface till Axi Ethernet Reset is completed.
+	 * When we do an Axi Ethernet reset, it resets the complete core
+	 * including the MDIO. So if MDIO is not disabled when the reset
+	 * process is started, MDIO will be broken afterwards. */
+	axienet_iow(lp, XAE_MDIO_MC_OFFSET, (mdio_mcreg &
+		    ~XAE_MDIO_MC_MDIOEN_MASK));
+
+	__axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET);
+	__axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET);
+
+	axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg);
+	axienet_mdio_wait_until_ready(lp);
+
+	for (i = 0; i < TX_BD_NUM; i++) {
+		cur_p = &lp->tx_bd_v[i];
+		if (cur_p->phys)
+			dma_unmap_single(ndev->dev.parent, cur_p->phys,
+					 (cur_p->cntrl &
+					  XAXIDMA_BD_CTRL_LENGTH_MASK),
+					 DMA_TO_DEVICE);
+		if (cur_p->app4)
+			dev_kfree_skb_irq((struct sk_buff *) cur_p->app4);
+		cur_p->phys = 0;
+		cur_p->cntrl = 0;
+		cur_p->status = 0;
+		cur_p->app0 = 0;
+		cur_p->app1 = 0;
+		cur_p->app2 = 0;
+		cur_p->app3 = 0;
+		cur_p->app4 = 0;
+		cur_p->sw_id_offset = 0;
+	}
+
+	for (i = 0; i < RX_BD_NUM; i++) {
+		cur_p = &lp->rx_bd_v[i];
+		cur_p->status = 0;
+		cur_p->app0 = 0;
+		cur_p->app1 = 0;
+		cur_p->app2 = 0;
+		cur_p->app3 = 0;
+		cur_p->app4 = 0;
+	}
+
+	lp->tx_bd_ci = 0;
+	lp->tx_bd_tail = 0;
+	lp->rx_bd_ci = 0;
+
+	/* Start updating the Rx channel control register */
+	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+	/* Update the interrupt coalesce count */
+	cr = ((cr & ~XAXIDMA_COALESCE_MASK) |
+	      (XAXIDMA_DFT_RX_THRESHOLD << XAXIDMA_COALESCE_SHIFT));
+	/* Update the delay timer count */
+	cr = ((cr & ~XAXIDMA_DELAY_MASK) |
+	      (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+	/* Enable coalesce, delay timer and error interrupts */
+	cr |= XAXIDMA_IRQ_ALL_MASK;
+	/* Finally write to the Rx channel control register */
+	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+
+	/* Start updating the Tx channel control register */
+	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+	/* Update the interrupt coalesce count */
+	cr = (((cr & ~XAXIDMA_COALESCE_MASK)) |
+	      (XAXIDMA_DFT_TX_THRESHOLD << XAXIDMA_COALESCE_SHIFT));
+	/* Update the delay timer count */
+	cr = (((cr & ~XAXIDMA_DELAY_MASK)) |
+	      (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT));
+	/* Enable coalesce, delay timer and error interrupts */
+	cr |= XAXIDMA_IRQ_ALL_MASK;
+	/* Finally write to the Tx channel control register */
+	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+
+	/* Populate the tail pointer and bring the Rx Axi DMA engine out of
+	 * halted state. This will make the Rx side ready for reception.*/
+	axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p);
+	cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET);
+	axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET,
+			  cr | XAXIDMA_CR_RUNSTOP_MASK);
+	axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p +
+			  (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
+
+	/* Write to the RS (Run-stop) bit in the Tx channel control register.
+	 * Tx channel is now ready to run. But only after we write to the
+	 * tail pointer register that the Tx channel will start transmitting */
+	axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p);
+	cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET);
+	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET,
+			  cr | XAXIDMA_CR_RUNSTOP_MASK);
+
+	axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET);
+	axienet_status &= ~XAE_RCW1_RX_MASK;
+	axienet_iow(lp, XAE_RCW1_OFFSET, axienet_status);
+
+	axienet_status = axienet_ior(lp, XAE_IP_OFFSET);
+	if (axienet_status & XAE_INT_RXRJECT_MASK)
+		axienet_iow(lp, XAE_IS_OFFSET, XAE_INT_RXRJECT_MASK);
+	axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK);
+
+	/* Sync default options with HW but leave receiver and
+	 * transmitter disabled.*/
+	axienet_setoptions(ndev, lp->options &
+			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
+	axienet_set_mac_address(ndev, NULL);
+	axienet_set_multicast_list(ndev);
+	axienet_setoptions(ndev, lp->options);
+}
+
+/**
+ * axienet_of_probe - Axi Ethernet probe function.
+ * @op:		Pointer to platform device structure.
+ * @match:	Pointer to device id structure
+ *
+ * returns: 0, on success
+ *	    Non-zero error value on failure.
+ *
+ * This is the probe routine for Axi Ethernet driver. This is called before
+ * any other driver routines are invoked. It allocates and sets up the Ethernet
+ * device. Parses through device tree and populates fields of
+ * axienet_local. It registers the Ethernet device.
+ */
+static int __devinit axienet_of_probe(struct platform_device *op)
+{
+	__be32 *p;
+	int size, ret = 0;
+	struct device_node *np;
+	struct axienet_local *lp;
+	struct net_device *ndev;
+	const void *addr;
+
+	ndev = alloc_etherdev(sizeof(*lp));
+	if (!ndev)
+		return -ENOMEM;
+
+	ether_setup(ndev);
+	dev_set_drvdata(&op->dev, ndev);
+
+	SET_NETDEV_DEV(ndev, &op->dev);
+	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
+	ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+	ndev->netdev_ops = &axienet_netdev_ops;
+	ndev->ethtool_ops = &axienet_ethtool_ops;
+
+	lp = netdev_priv(ndev);
+	lp->ndev = ndev;
+	lp->dev = &op->dev;
+	lp->options = XAE_OPTION_DEFAULTS;
+	/* Map device registers */
+	lp->regs = of_iomap(op->dev.of_node, 0);
+	if (!lp->regs) {
+		dev_err(&op->dev, "could not map Axi Ethernet regs.\n");
+		goto nodev;
+	}
+	/* Setup checksum offload, but default to off if not specified */
+	lp->features = 0;
+
+	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
+	if (p) {
+		switch (be32_to_cpup(p)) {
+		case 1:
+			lp->csum_offload_on_tx_path =
+				XAE_FEATURE_PARTIAL_TX_CSUM;
+			lp->features |= XAE_FEATURE_PARTIAL_TX_CSUM;
+			/* Can checksum TCP/UDP over IPv4. */
+			ndev->features |= NETIF_F_IP_CSUM;
+			break;
+		case 2:
+			lp->csum_offload_on_tx_path =
+				XAE_FEATURE_FULL_TX_CSUM;
+			lp->features |= XAE_FEATURE_FULL_TX_CSUM;
+			/* Can checksum TCP/UDP over IPv4. */
+			ndev->features |= NETIF_F_IP_CSUM;
+			break;
+		default:
+			lp->csum_offload_on_tx_path = XAE_NO_CSUM_OFFLOAD;
+		}
+	}
+	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
+	if (p) {
+		switch (be32_to_cpup(p)) {
+		case 1:
+			lp->csum_offload_on_rx_path =
+				XAE_FEATURE_PARTIAL_RX_CSUM;
+			lp->features |= XAE_FEATURE_PARTIAL_RX_CSUM;
+			break;
+		case 2:
+			lp->csum_offload_on_rx_path =
+				XAE_FEATURE_FULL_RX_CSUM;
+			lp->features |= XAE_FEATURE_FULL_RX_CSUM;
+			break;
+		default:
+			lp->csum_offload_on_rx_path = XAE_NO_CSUM_OFFLOAD;
+		}
+	}
+	/* For supporting jumbo frames, the Axi Ethernet hardware must have
+	 * a larger Rx/Tx Memory. Typically, the size must be more than or
+	 * equal to 16384 bytes, so that we can enable jumbo option and start
+	 * supporting jumbo frames. Here we check for memory allocated for
+	 * Rx/Tx in the hardware from the device-tree and accordingly set
+	 * flags. */
+	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxmem", NULL);
+	if (p) {
+		if ((be32_to_cpup(p)) >= 0x4000)
+			lp->jumbo_support = 1;
+	}
+	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type",
+				       NULL);
+	if (p)
+		lp->temac_type = be32_to_cpup(p);
+	p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL);
+	if (p)
+		lp->phy_type = be32_to_cpup(p);
+
+	/* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
+	np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0);
+	if (!np) {
+		dev_err(&op->dev, "could not find DMA node\n");
+		goto err_iounmap;
+	}
+	lp->dma_regs = of_iomap(np, 0);
+	if (lp->dma_regs) {
+		dev_dbg(&op->dev, "MEM base: %p\n", lp->dma_regs);
+	} else {
+		dev_err(&op->dev, "unable to map DMA registers\n");
+		of_node_put(np);
+	}
+	lp->rx_irq = irq_of_parse_and_map(np, 1);
+	lp->tx_irq = irq_of_parse_and_map(np, 0);
+	of_node_put(np);
+	if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) {
+		dev_err(&op->dev, "could not determine irqs\n");
+		ret = -ENOMEM;
+		goto err_iounmap_2;
+	}
+
+	/* Retrieve the MAC address */
+	addr = of_get_property(op->dev.of_node, "local-mac-address", &size);
+	if ((!addr) || (size != 6)) {
+		dev_err(&op->dev, "could not find MAC address\n");
+		ret = -ENODEV;
+		goto err_iounmap_2;
+	}
+	axienet_set_mac_address(ndev, (void *) addr);
+
+	lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
+	lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
+
+	lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
+	ret = axienet_mdio_setup(lp, op->dev.of_node);
+	if (ret)
+		dev_warn(&op->dev, "error registering MDIO bus\n");
+
+	ret = register_netdev(lp->ndev);
+	if (ret) {
+		dev_err(lp->dev, "register_netdev() error (%i)\n", ret);
+		goto err_iounmap_2;
+	}
+
+	tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler,
+		     (unsigned long) lp);
+	tasklet_disable(&lp->dma_err_tasklet);
+
+	return 0;
+
+err_iounmap_2:
+	if (lp->dma_regs)
+		iounmap(lp->dma_regs);
+err_iounmap:
+	iounmap(lp->regs);
+nodev:
+	free_netdev(ndev);
+	ndev = NULL;
+	return ret;
+}
+
+static int __devexit axienet_of_remove(struct platform_device *op)
+{
+	struct net_device *ndev = dev_get_drvdata(&op->dev);
+	struct axienet_local *lp = netdev_priv(ndev);
+
+	axienet_mdio_teardown(lp);
+	unregister_netdev(ndev);
+
+	if (lp->phy_node)
+		of_node_put(lp->phy_node);
+	lp->phy_node = NULL;
+
+	dev_set_drvdata(&op->dev, NULL);
+
+	iounmap(lp->regs);
+	if (lp->dma_regs)
+		iounmap(lp->dma_regs);
+	free_netdev(ndev);
+
+	return 0;
+}
+
+static struct platform_driver axienet_of_driver = {
+	.probe = axienet_of_probe,
+	.remove = __devexit_p(axienet_of_remove),
+	.driver = {
+		 .owner = THIS_MODULE,
+		 .name = "xilinx_axienet",
+		 .of_match_table = axienet_of_match,
+	},
+};
+
+module_platform_driver(axienet_of_driver);
+
+MODULE_DESCRIPTION("Xilinx Axi Ethernet driver");
+MODULE_AUTHOR("Xilinx");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
new file mode 100644
index 0000000..d70b6e7
--- /dev/null
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
@@ -0,0 +1,238 @@
+/*
+ * MDIO bus driver for the Xilinx Axi Ethernet device
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ * Copyright (c) 2010 Xilinx, Inc. All rights reserved.
+ * Copyright (c) 2012 Daniel Borkmann, <daniel.borkmann@tik.ee.ethz.ch>
+ * Copyright (c) 2012 Ariane Keller, <ariane.keller@tik.ee.ethz.ch>
+ */
+
+#include <linux/of_address.h>
+#include <linux/of_mdio.h>
+#include <linux/jiffies.h>
+
+#include "xilinx_axienet.h"
+
+#define MAX_MDIO_FREQ		2500000 /* 2.5 MHz */
+#define DEFAULT_CLOCK_DIVISOR	XAE_MDIO_DIV_DFT
+
+/* Wait till MDIO interface is ready to accept a new transaction.*/
+int axienet_mdio_wait_until_ready(struct axienet_local *lp)
+{
+	long end = jiffies + 2;
+	while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) &
+		 XAE_MDIO_MCR_READY_MASK)) {
+		if (end - jiffies <= 0) {
+			WARN_ON(1);
+			return -ETIMEDOUT;
+		}
+		udelay(1);
+	}
+	return 0;
+}
+
+/**
+ * axienet_mdio_read - MDIO interface read function
+ * @bus:	Pointer to mii bus structure
+ * @phy_id:	Address of the PHY device
+ * @reg:	PHY register to read
+ *
+ * returns:	The register contents on success, -ETIMEDOUT on a timeout
+ *
+ * Reads the contents of the requested register from the requested PHY
+ * address by first writing the details into MCR register. After a while
+ * the register MRD is read to obtain the PHY register content.
+ */
+static int axienet_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+	u32 rc;
+	int ret;
+	struct axienet_local *lp = bus->priv;
+
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+
+	axienet_iow(lp, XAE_MDIO_MCR_OFFSET,
+		    (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) &
+		      XAE_MDIO_MCR_PHYAD_MASK) |
+		     ((reg << XAE_MDIO_MCR_REGAD_SHIFT) &
+		      XAE_MDIO_MCR_REGAD_MASK) |
+		     XAE_MDIO_MCR_INITIATE_MASK |
+		     XAE_MDIO_MCR_OP_READ_MASK));
+
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+
+	rc = axienet_ior(lp, XAE_MDIO_MRD_OFFSET) & 0x0000FFFF;
+
+	dev_dbg(lp->dev, "axienet_mdio_read(phy_id=%i, reg=%x) == %x\n",
+		phy_id, reg, rc);
+
+	return rc;
+}
+
+/**
+ * axienet_mdio_write - MDIO interface write function
+ * @bus:	Pointer to mii bus structure
+ * @phy_id:	Address of the PHY device
+ * @reg:	PHY register to write to
+ * @val:	Value to be written into the register
+ *
+ * returns:	0 on success, -ETIMEDOUT on a timeout
+ *
+ * Writes the value to the requested register by first writing the value
+ * into MWD register. The the MCR register is then appropriately setup
+ * to finish the write operation.
+ */
+static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg,
+			      u16 val)
+{
+	int ret;
+	struct axienet_local *lp = bus->priv;
+
+	dev_dbg(lp->dev, "axienet_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+		phy_id, reg, val);
+
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+
+	axienet_iow(lp, XAE_MDIO_MWD_OFFSET, (u32) val);
+	axienet_iow(lp, XAE_MDIO_MCR_OFFSET,
+		    (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) &
+		      XAE_MDIO_MCR_PHYAD_MASK) |
+		     ((reg << XAE_MDIO_MCR_REGAD_SHIFT) &
+		      XAE_MDIO_MCR_REGAD_MASK) |
+		     XAE_MDIO_MCR_INITIATE_MASK |
+		     XAE_MDIO_MCR_OP_WRITE_MASK));
+
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+/**
+ * axienet_mdio_setup - MDIO setup function
+ * @lp:		Pointer to axienet local data structure.
+ * @np:		Pointer to device node
+ *
+ * returns:	0 on success, -ETIMEDOUT on a timeout, -ENOMEM when
+ *		mdiobus_alloc (to allocate memory for mii bus structure) fails.
+ *
+ * Sets up the MDIO interface by initializing the MDIO clock and enabling the
+ * MDIO interface in hardware. Register the MDIO interface.
+ **/
+int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
+{
+	int ret;
+	u32 clk_div, host_clock;
+	u32 *property_p;
+	struct mii_bus *bus;
+	struct resource res;
+	struct device_node *np1;
+
+	/* clk_div can be calculated by deriving it from the equation:
+	 * fMDIO = fHOST / ((1 + clk_div) * 2)
+	 *
+	 * Where fMDIO <= 2500000, so we get:
+	 * fHOST / ((1 + clk_div) * 2) <= 2500000
+	 *
+	 * Then we get:
+	 * 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST)
+	 *
+	 * Then we get:
+	 * 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST)
+	 *
+	 * Then we get:
+	 * 1 / (1 + clk_div) <= (5000000 / fHOST)
+	 *
+	 * So:
+	 * (1 + clk_div) >= (fHOST / 5000000)
+	 *
+	 * And finally:
+	 * clk_div >= (fHOST / 5000000) - 1
+	 *
+	 * fHOST can be read from the flattened device tree as property
+	 * "clock-frequency" from the CPU
+	 */
+
+	np1 = of_find_node_by_name(NULL, "cpu");
+	if (!np1) {
+		printk(KERN_WARNING "%s(): Could not find CPU device node.",
+		       __func__);
+		printk(KERN_WARNING "Setting MDIO clock divisor to "
+		       "default %d\n", DEFAULT_CLOCK_DIVISOR);
+		clk_div = DEFAULT_CLOCK_DIVISOR;
+		goto issue;
+	}
+	property_p = (u32 *) of_get_property(np1, "clock-frequency", NULL);
+	if (!property_p) {
+		printk(KERN_WARNING "%s(): Could not find CPU property: "
+		       "clock-frequency.", __func__);
+		printk(KERN_WARNING "Setting MDIO clock divisor to "
+		       "default %d\n", DEFAULT_CLOCK_DIVISOR);
+		clk_div = DEFAULT_CLOCK_DIVISOR;
+		goto issue;
+	}
+
+	host_clock = be32_to_cpup(property_p);
+	clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1;
+	/* If there is any remainder from the division of
+	 * fHOST / (MAX_MDIO_FREQ * 2), then we need to add
+	 * 1 to the clock divisor or we will surely be above 2.5 MHz */
+	if (host_clock % (MAX_MDIO_FREQ * 2))
+		clk_div++;
+
+	printk(KERN_DEBUG "%s(): Setting MDIO clock divisor to %u based "
+	       "on %u Hz host clock.\n", __func__, clk_div, host_clock);
+
+	of_node_put(np1);
+issue:
+	axienet_iow(lp, XAE_MDIO_MC_OFFSET,
+		    (((u32) clk_div) | XAE_MDIO_MC_MDIOEN_MASK));
+
+	ret = axienet_mdio_wait_until_ready(lp);
+	if (ret < 0)
+		return ret;
+
+	bus = mdiobus_alloc();
+	if (!bus)
+		return -ENOMEM;
+
+	np1 = of_get_parent(lp->phy_node);
+	of_address_to_resource(np1, 0, &res);
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+		 (unsigned long long) res.start);
+
+	bus->priv = lp;
+	bus->name = "Xilinx Axi Ethernet MDIO";
+	bus->read = axienet_mdio_read;
+	bus->write = axienet_mdio_write;
+	bus->parent = lp->dev;
+	bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
+	lp->mii_bus = bus;
+
+	ret = of_mdiobus_register(bus, np1);
+	if (ret) {
+		mdiobus_free(bus);
+		return ret;
+	}
+	return 0;
+}
+
+/**
+ * axienet_mdio_teardown - MDIO remove function
+ * @lp:		Pointer to axienet local data structure.
+ *
+ * Unregisters the MDIO and frees any associate memory for mii bus.
+ */
+void axienet_mdio_teardown(struct axienet_local *lp)
+{
+	mdiobus_unregister(lp->mii_bus);
+	kfree(lp->mii_bus->irq);
+	mdiobus_free(lp->mii_bus);
+	lp->mii_bus = NULL;
+}
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
index 79013e5..77cfe51 100644
--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
@@ -613,7 +613,7 @@ static void xemaclite_rx_handler(struct net_device *dev)
 	u32 len;
 
 	len = ETH_FRAME_LEN + ETH_FCS_LEN;
-	skb = dev_alloc_skb(len + ALIGNMENT);
+	skb = netdev_alloc_skb(dev, len + ALIGNMENT);
 	if (!skb) {
 		/* Couldn't get memory. */
 		dev->stats.rx_dropped++;
@@ -1136,10 +1136,8 @@ static int __devinit xemaclite_of_probe(struct platform_device *ofdev)
 
 	/* Create an ethernet device instance */
 	ndev = alloc_etherdev(sizeof(struct net_local));
-	if (!ndev) {
-		dev_err(dev, "Could not allocate network device\n");
+	if (!ndev)
 		return -ENOMEM;
-	}
 
 	dev_set_drvdata(dev, ndev);
 	SET_NETDEV_DEV(ndev, &ofdev->dev);
diff --git a/drivers/net/ethernet/xircom/xirc2ps_cs.c b/drivers/net/ethernet/xircom/xirc2ps_cs.c
index 33979c3..5c69c6f 100644
--- a/drivers/net/ethernet/xircom/xirc2ps_cs.c
+++ b/drivers/net/ethernet/xircom/xirc2ps_cs.c
@@ -1039,7 +1039,8 @@ xirc2ps_interrupt(int irq, void *dev_id)
 
 	    pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
 
-	    skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
+	    /* 1 extra so we can use insw */
+	    skb = netdev_alloc_skb(dev, pktlen + 3);
 	    if (!skb) {
 		pr_notice("low memory, packet dropped (size=%u)\n", pktlen);
 		dev->stats.rx_dropped++;
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 9537aaa..49b8b58 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -1162,7 +1162,7 @@ static void baycom_probe(struct net_device *dev)
 /*
  * command line settable parameters
  */
-static const char *mode[NR_PORTS] = { "", };
+static char *mode[NR_PORTS] = { "", };
 static int iobase[NR_PORTS] = { 0x378, };
 
 module_param_array(mode, charp, NULL, 0);
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
index 279d229..f1aea0c 100644
--- a/drivers/net/hamradio/baycom_par.c
+++ b/drivers/net/hamradio/baycom_par.c
@@ -477,7 +477,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
 /*
  * command line settable parameters
  */
-static const char *mode[NR_PORTS] = { "picpar", };
+static char *mode[NR_PORTS] = { "picpar", };
 static int iobase[NR_PORTS] = { 0x378, };
 
 module_param_array(mode, charp, NULL, 0);
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 96a98d2..6963277 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -403,7 +403,6 @@ static unsigned char *add_mcs(unsigned char *bits, int bitrate,
 
 	/* Allocate a new mcs */
 	if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) {
-		printk(KERN_WARNING "YAM: no memory to allocate mcs\n");
 		release_firmware(fw);
 		return NULL;
 	}
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index e68c941..2a51363 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -1600,12 +1600,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		}
 
 		image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);
-		if (!image){
-			printk(KERN_ERR "%s: Unable to allocate memory "
-			       "for EEPROM image\n", dev->name);
+		if (!image)
 			return -ENOMEM;
-		}
-
 
 		if (rrpriv->fw_running){
 			printk("%s: Firmware already running\n", dev->name);
@@ -1637,8 +1633,6 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);
 		oldimage = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);
 		if (!image || !oldimage) {
-			printk(KERN_ERR "%s: Unable to allocate memory "
-			       "for EEPROM image\n", dev->name);
 			error = -ENOMEM;
 			goto wf_out;
 		}
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 466c58a..0ae7a1a 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -267,13 +267,10 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
 int netvsc_recv_callback(struct hv_device *device_obj,
 				struct hv_netvsc_packet *packet)
 {
-	struct net_device *net = dev_get_drvdata(&device_obj->device);
+	struct net_device *net;
 	struct sk_buff *skb;
-	struct netvsc_device *net_device;
-
-	net_device = hv_get_drvdata(device_obj);
-	net = net_device->ndev;
 
+	net = ((struct netvsc_device *)hv_get_drvdata(device_obj))->ndev;
 	if (!net) {
 		netdev_err(net, "got receive callback but net device"
 			" not initialized yet\n");
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 133b7fb..136efd8 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -758,66 +758,64 @@ int rndis_filter_open(struct hv_device *dev)
 
 int rndis_filter_close(struct hv_device *dev)
 {
-	struct netvsc_device *netDevice = hv_get_drvdata(dev);
+	struct netvsc_device *nvdev = hv_get_drvdata(dev);
 
-	if (!netDevice)
+	if (!nvdev)
 		return -EINVAL;
 
-	return rndis_filter_close_device(netDevice->extension);
+	return rndis_filter_close_device(nvdev->extension);
 }
 
 int rndis_filter_send(struct hv_device *dev,
 			     struct hv_netvsc_packet *pkt)
 {
 	int ret;
-	struct rndis_filter_packet *filterPacket;
-	struct rndis_message *rndisMessage;
-	struct rndis_packet *rndisPacket;
-	u32 rndisMessageSize;
+	struct rndis_filter_packet *filter_pkt;
+	struct rndis_message *rndis_msg;
+	struct rndis_packet *rndis_pkt;
+	u32 rndis_msg_size;
 
 	/* Add the rndis header */
-	filterPacket = (struct rndis_filter_packet *)pkt->extension;
-
-	memset(filterPacket, 0, sizeof(struct rndis_filter_packet));
+	filter_pkt = (struct rndis_filter_packet *)pkt->extension;
 
-	rndisMessage = &filterPacket->msg;
-	rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);
+	rndis_msg = &filter_pkt->msg;
+	rndis_msg_size = RNDIS_MESSAGE_SIZE(struct rndis_packet);
 
-	rndisMessage->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
-	rndisMessage->msg_len = pkt->total_data_buflen +
-				      rndisMessageSize;
+	rndis_msg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
+	rndis_msg->msg_len = pkt->total_data_buflen +
+				      rndis_msg_size;
 
-	rndisPacket = &rndisMessage->msg.pkt;
-	rndisPacket->data_offset = sizeof(struct rndis_packet);
-	rndisPacket->data_len = pkt->total_data_buflen;
+	rndis_pkt = &rndis_msg->msg.pkt;
+	rndis_pkt->data_offset = sizeof(struct rndis_packet);
+	rndis_pkt->data_len = pkt->total_data_buflen;
 
 	pkt->is_data_pkt = true;
-	pkt->page_buf[0].pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
+	pkt->page_buf[0].pfn = virt_to_phys(rndis_msg) >> PAGE_SHIFT;
 	pkt->page_buf[0].offset =
-			(unsigned long)rndisMessage & (PAGE_SIZE-1);
-	pkt->page_buf[0].len = rndisMessageSize;
+			(unsigned long)rndis_msg & (PAGE_SIZE-1);
+	pkt->page_buf[0].len = rndis_msg_size;
 
 	/* Add one page_buf if the rndis msg goes beyond page boundary */
-	if (pkt->page_buf[0].offset + rndisMessageSize > PAGE_SIZE) {
+	if (pkt->page_buf[0].offset + rndis_msg_size > PAGE_SIZE) {
 		int i;
 		for (i = pkt->page_buf_cnt; i > 1; i--)
 			pkt->page_buf[i] = pkt->page_buf[i-1];
 		pkt->page_buf_cnt++;
 		pkt->page_buf[0].len = PAGE_SIZE - pkt->page_buf[0].offset;
 		pkt->page_buf[1].pfn = virt_to_phys((void *)((ulong)
-			rndisMessage + pkt->page_buf[0].len)) >> PAGE_SHIFT;
+			rndis_msg + pkt->page_buf[0].len)) >> PAGE_SHIFT;
 		pkt->page_buf[1].offset = 0;
-		pkt->page_buf[1].len = rndisMessageSize - pkt->page_buf[0].len;
+		pkt->page_buf[1].len = rndis_msg_size - pkt->page_buf[0].len;
 	}
 
 	/* Save the packet send completion and context */
-	filterPacket->completion = pkt->completion.send.send_completion;
-	filterPacket->completion_ctx =
+	filter_pkt->completion = pkt->completion.send.send_completion;
+	filter_pkt->completion_ctx =
 				pkt->completion.send.send_completion_ctx;
 
 	/* Use ours */
 	pkt->completion.send.send_completion = rndis_filter_send_completion;
-	pkt->completion.send.send_completion_ctx = filterPacket;
+	pkt->completion.send.send_completion_ctx = filter_pkt;
 
 	ret = netvsc_send(dev, pkt);
 	if (ret != 0) {
@@ -826,9 +824,9 @@ int rndis_filter_send(struct hv_device *dev,
 		 * above
 		 */
 		pkt->completion.send.send_completion =
-				filterPacket->completion;
+				filter_pkt->completion;
 		pkt->completion.send.send_completion_ctx =
-				filterPacket->completion_ctx;
+				filter_pkt->completion_ctx;
 	}
 
 	return ret;
@@ -836,10 +834,10 @@ int rndis_filter_send(struct hv_device *dev,
 
 static void rndis_filter_send_completion(void *ctx)
 {
-	struct rndis_filter_packet *filterPacket = ctx;
+	struct rndis_filter_packet *filter_pkt = ctx;
 
 	/* Pass it back to the original handler */
-	filterPacket->completion(filterPacket->completion_ctx);
+	filter_pkt->completion(filter_pkt->completion_ctx);
 }
 
 
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index e05b645..344dceb 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -184,7 +184,7 @@ static void ifb_setup(struct net_device *dev)
 	dev->flags |= IFF_NOARP;
 	dev->flags &= ~IFF_MULTICAST;
 	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 }
 
 static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index e535137..4680478 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -356,7 +356,7 @@ config VLSI_FIR
 
 config SA1100_FIR
 	tristate "SA1100 Internal IR"
-	depends on ARCH_SA1100 && IRDA
+	depends on ARCH_SA1100 && IRDA && DMA_SA11X0
 
 config VIA_FIR
 	tristate "VIA VT8231/VT1211 SIR/MIR/FIR"
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 64f403d..617a446 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1608,7 +1608,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
   self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL);
   if (!self->ringbuf)
     {
-      printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n");
       err = -ENOMEM;
       goto freeregion;
     }
@@ -1647,7 +1646,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
 
   if (!ok)
     {
-      printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n");
       err = -ENOMEM;
       goto freebufs;
     }
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index da27050..a0d1913 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -15,7 +15,7 @@
  *  This driver takes one kernel command line parameter, sa1100ir=, with
  *  the following options:
  *	max_rate:baudrate	- set the maximum baud rate
- *	power_leve:level	- set the transmitter power level
+ *	power_level:level	- set the transmitter power level
  *	tx_lpm:0|1		- set transmit low power mode
  */
 #include <linux/module.h>
@@ -30,13 +30,13 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/sa11x0-dma.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
 
-#include <asm/irq.h>
-#include <mach/dma.h>
 #include <mach/hardware.h>
 #include <asm/mach/irda.h>
 
@@ -44,8 +44,15 @@ static int power_level = 3;
 static int tx_lpm;
 static int max_rate = 4000000;
 
+struct sa1100_buf {
+	struct device		*dev;
+	struct sk_buff		*skb;
+	struct scatterlist	sg;
+	struct dma_chan		*chan;
+	dma_cookie_t		cookie;
+};
+
 struct sa1100_irda {
-	unsigned char		hscr0;
 	unsigned char		utcr4;
 	unsigned char		power;
 	unsigned char		open;
@@ -53,12 +60,8 @@ struct sa1100_irda {
 	int			speed;
 	int			newspeed;
 
-	struct sk_buff		*txskb;
-	struct sk_buff		*rxskb;
-	dma_addr_t		txbuf_dma;
-	dma_addr_t		rxbuf_dma;
-	dma_regs_t		*txdma;
-	dma_regs_t		*rxdma;
+	struct sa1100_buf	dma_rx;
+	struct sa1100_buf	dma_tx;
 
 	struct device		*dev;
 	struct irda_platform_data *pdata;
@@ -67,23 +70,103 @@ struct sa1100_irda {
 
 	iobuff_t		tx_buff;
 	iobuff_t		rx_buff;
+
+	int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *);
+	irqreturn_t (*irq)(struct net_device *, struct sa1100_irda *);
 };
 
+static int sa1100_irda_set_speed(struct sa1100_irda *, int);
+
 #define IS_FIR(si)		((si)->speed >= 4000000)
 
 #define HPSIR_MAX_RXLEN		2047
 
+static struct dma_slave_config sa1100_irda_sir_tx = {
+	.direction	= DMA_TO_DEVICE,
+	.dst_addr	= __PREG(Ser2UTDR),
+	.dst_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.dst_maxburst	= 4,
+};
+
+static struct dma_slave_config sa1100_irda_fir_rx = {
+	.direction	= DMA_FROM_DEVICE,
+	.src_addr	= __PREG(Ser2HSDR),
+	.src_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.src_maxburst	= 8,
+};
+
+static struct dma_slave_config sa1100_irda_fir_tx = {
+	.direction	= DMA_TO_DEVICE,
+	.dst_addr	= __PREG(Ser2HSDR),
+	.dst_addr_width	= DMA_SLAVE_BUSWIDTH_1_BYTE,
+	.dst_maxburst	= 8,
+};
+
+static unsigned sa1100_irda_dma_xferred(struct sa1100_buf *buf)
+{
+	struct dma_chan *chan = buf->chan;
+	struct dma_tx_state state;
+	enum dma_status status;
+
+	status = chan->device->device_tx_status(chan, buf->cookie, &state);
+	if (status != DMA_PAUSED)
+		return 0;
+
+	return sg_dma_len(&buf->sg) - state.residue;
+}
+
+static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf,
+	const char *name, struct dma_slave_config *cfg)
+{
+	dma_cap_mask_t m;
+	int ret;
+
+	dma_cap_zero(m);
+	dma_cap_set(DMA_SLAVE, m);
+
+	buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name);
+	if (!buf->chan) {
+		dev_err(dev, "unable to request DMA channel for %s\n",
+			name);
+		return -ENOENT;
+	}
+
+	ret = dmaengine_slave_config(buf->chan, cfg);
+	if (ret)
+		dev_warn(dev, "DMA slave_config for %s returned %d\n",
+			name, ret);
+
+	buf->dev = buf->chan->device->dev;
+
+	return 0;
+}
+
+static void sa1100_irda_dma_start(struct sa1100_buf *buf,
+	enum dma_transfer_direction dir, dma_async_tx_callback cb, void *cb_p)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *chan = buf->chan;
+
+	desc = chan->device->device_prep_slave_sg(chan, &buf->sg, 1, dir,
+			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (desc) {
+		desc->callback = cb;
+		desc->callback_param = cb_p;
+		buf->cookie = dmaengine_submit(desc);
+		dma_async_issue_pending(chan);
+	}
+}
+
 /*
  * Allocate and map the receive buffer, unless it is already allocated.
  */
 static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
 {
-	if (si->rxskb)
+	if (si->dma_rx.skb)
 		return 0;
 
-	si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
-
-	if (!si->rxskb) {
+	si->dma_rx.skb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
+	if (!si->dma_rx.skb) {
 		printk(KERN_ERR "sa1100_ir: out of memory for RX SKB\n");
 		return -ENOMEM;
 	}
@@ -92,11 +175,14 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
 	 * Align any IP headers that may be contained
 	 * within the frame.
 	 */
-	skb_reserve(si->rxskb, 1);
+	skb_reserve(si->dma_rx.skb, 1);
+
+	sg_set_buf(&si->dma_rx.sg, si->dma_rx.skb->data, HPSIR_MAX_RXLEN);
+	if (dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE) == 0) {
+		dev_kfree_skb_any(si->dma_rx.skb);
+		return -ENOMEM;
+	}
 
-	si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data,
-					HPSIR_MAX_RXLEN,
-					DMA_FROM_DEVICE);
 	return 0;
 }
 
@@ -106,7 +192,7 @@ static int sa1100_irda_rx_alloc(struct sa1100_irda *si)
  */
 static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
 {
-	if (!si->rxskb) {
+	if (!si->dma_rx.skb) {
 		printk(KERN_ERR "sa1100_ir: rx buffer went missing\n");
 		return;
 	}
@@ -114,254 +200,87 @@ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si)
 	/*
 	 * First empty receive FIFO
 	 */
-	Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
+	Ser2HSCR0 = HSCR0_HSSP;
 
 	/*
 	 * Enable the DMA, receiver and receive interrupt.
 	 */
-	sa1100_clear_dma(si->rxdma);
-	sa1100_start_dma(si->rxdma, si->rxbuf_dma, HPSIR_MAX_RXLEN);
-	Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_RXE;
+	dmaengine_terminate_all(si->dma_rx.chan);
+	sa1100_irda_dma_start(&si->dma_rx, DMA_DEV_TO_MEM, NULL, NULL);
+
+	Ser2HSCR0 = HSCR0_HSSP | HSCR0_RXE;
 }
 
-/*
- * Set the IrDA communications speed.
- */
-static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
+static void sa1100_irda_check_speed(struct sa1100_irda *si)
 {
-	unsigned long flags;
-	int brd, ret = -EINVAL;
-
-	switch (speed) {
-	case 9600:	case 19200:	case 38400:
-	case 57600:	case 115200:
-		brd = 3686400 / (16 * speed) - 1;
-
-		/*
-		 * Stop the receive DMA.
-		 */
-		if (IS_FIR(si))
-			sa1100_stop_dma(si->rxdma);
-
-		local_irq_save(flags);
-
-		Ser2UTCR3 = 0;
-		Ser2HSCR0 = HSCR0_UART;
-
-		Ser2UTCR1 = brd >> 8;
-		Ser2UTCR2 = brd;
-
-		/*
-		 * Clear status register
-		 */
-		Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
-		Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
-
-		if (si->pdata->set_speed)
-			si->pdata->set_speed(si->dev, speed);
-
-		si->speed = speed;
-
-		local_irq_restore(flags);
-		ret = 0;
-		break;
-
-	case 4000000:
-		local_irq_save(flags);
-
-		si->hscr0 = 0;
-
-		Ser2HSSR0 = 0xff;
-		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
-		Ser2UTCR3 = 0;
-
-		si->speed = speed;
-
-		if (si->pdata->set_speed)
-			si->pdata->set_speed(si->dev, speed);
-
-		sa1100_irda_rx_alloc(si);
-		sa1100_irda_rx_dma_start(si);
-
-		local_irq_restore(flags);
-
-		break;
-
-	default:
-		break;
+	if (si->newspeed) {
+		sa1100_irda_set_speed(si, si->newspeed);
+		si->newspeed = 0;
 	}
-
-	return ret;
 }
 
 /*
- * Control the power state of the IrDA transmitter.
- * State:
- *  0 - off
- *  1 - short range, lowest power
- *  2 - medium range, medium power
- *  3 - maximum range, high power
- *
- * Currently, only assabet is known to support this.
+ * HP-SIR format support.
  */
-static int
-__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
-{
-	int ret = 0;
-	if (si->pdata->set_power)
-		ret = si->pdata->set_power(si->dev, state);
-	return ret;
-}
-
-static inline int
-sa1100_set_power(struct sa1100_irda *si, unsigned int state)
+static void sa1100_irda_sirtxdma_irq(void *id)
 {
-	int ret;
-
-	ret = __sa1100_irda_set_power(si, state);
-	if (ret == 0)
-		si->power = state;
-
-	return ret;
-}
+	struct net_device *dev = id;
+	struct sa1100_irda *si = netdev_priv(dev);
 
-static int sa1100_irda_startup(struct sa1100_irda *si)
-{
-	int ret;
+	dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE);
+	dev_kfree_skb(si->dma_tx.skb);
+	si->dma_tx.skb = NULL;
 
-	/*
-	 * Ensure that the ports for this device are setup correctly.
-	 */
-	if (si->pdata->startup)	{
-		ret = si->pdata->startup(si->dev);
-		if (ret)
-			return ret;
-	}
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += sg_dma_len(&si->dma_tx.sg);
 
-	/*
-	 * Configure PPC for IRDA - we want to drive TXD2 low.
-	 * We also want to drive this pin low during sleep.
-	 */
-	PPSR &= ~PPC_TXD2;
-	PSDR &= ~PPC_TXD2;
-	PPDR |= PPC_TXD2;
-
-	/*
-	 * Enable HP-SIR modulation, and ensure that the port is disabled.
-	 */
-	Ser2UTCR3 = 0;
-	Ser2HSCR0 = HSCR0_UART;
-	Ser2UTCR4 = si->utcr4;
-	Ser2UTCR0 = UTCR0_8BitData;
-	Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL;
+	/* We need to ensure that the transmitter has finished. */
+	do
+		rmb();
+	while (Ser2UTSR1 & UTSR1_TBY);
 
 	/*
-	 * Clear status register
+	 * Ok, we've finished transmitting.  Now enable the receiver.
+	 * Sometimes we get a receive IRQ immediately after a transmit...
 	 */
 	Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
+	Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
 
-	ret = sa1100_irda_set_speed(si, si->speed = 9600);
-	if (ret) {
-		Ser2UTCR3 = 0;
-		Ser2HSCR0 = 0;
+	sa1100_irda_check_speed(si);
 
-		if (si->pdata->shutdown)
-			si->pdata->shutdown(si->dev);
-	}
-
-	return ret;
-}
-
-static void sa1100_irda_shutdown(struct sa1100_irda *si)
-{
-	/*
-	 * Stop all DMA activity.
-	 */
-	sa1100_stop_dma(si->rxdma);
-	sa1100_stop_dma(si->txdma);
-
-	/* Disable the port. */
-	Ser2UTCR3 = 0;
-	Ser2HSCR0 = 0;
-
-	if (si->pdata->shutdown)
-		si->pdata->shutdown(si->dev);
+	/* I'm hungry! */
+	netif_wake_queue(dev);
 }
 
-#ifdef CONFIG_PM
-/*
- * Suspend the IrDA interface.
- */
-static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state)
+static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev,
+	struct sa1100_irda *si)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
-	struct sa1100_irda *si;
-
-	if (!dev)
-		return 0;
-
-	si = netdev_priv(dev);
-	if (si->open) {
-		/*
-		 * Stop the transmit queue
-		 */
-		netif_device_detach(dev);
-		disable_irq(dev->irq);
-		sa1100_irda_shutdown(si);
-		__sa1100_irda_set_power(si, 0);
+	si->tx_buff.data = si->tx_buff.head;
+	si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,
+					  si->tx_buff.truesize);
+
+	si->dma_tx.skb = skb;
+	sg_set_buf(&si->dma_tx.sg, si->tx_buff.data, si->tx_buff.len);
+	if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) {
+		si->dma_tx.skb = NULL;
+		netif_wake_queue(dev);
+		dev->stats.tx_dropped++;
+		return NETDEV_TX_OK;
 	}
 
-	return 0;
-}
-
-/*
- * Resume the IrDA interface.
- */
-static int sa1100_irda_resume(struct platform_device *pdev)
-{
-	struct net_device *dev = platform_get_drvdata(pdev);
-	struct sa1100_irda *si;
-
-	if (!dev)
-		return 0;
-
-	si = netdev_priv(dev);
-	if (si->open) {
-		/*
-		 * If we missed a speed change, initialise at the new speed
-		 * directly.  It is debatable whether this is actually
-		 * required, but in the interests of continuing from where
-		 * we left off it is desirable.  The converse argument is
-		 * that we should re-negotiate at 9600 baud again.
-		 */
-		if (si->newspeed) {
-			si->speed = si->newspeed;
-			si->newspeed = 0;
-		}
-
-		sa1100_irda_startup(si);
-		__sa1100_irda_set_power(si, si->power);
-		enable_irq(dev->irq);
+	sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_sirtxdma_irq, dev);
 
-		/*
-		 * This automatically wakes up the queue
-		 */
-		netif_device_attach(dev);
-	}
+	/*
+	 * The mean turn-around time is enforced by XBOF padding,
+	 * so we don't have to do anything special here.
+	 */
+	Ser2UTCR3 = UTCR3_TXE;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
-#else
-#define sa1100_irda_suspend	NULL
-#define sa1100_irda_resume	NULL
-#endif
 
-/*
- * HP-SIR format interrupt service routines.
- */
-static void sa1100_irda_hpsir_irq(struct net_device *dev)
+static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_irda *si)
 {
-	struct sa1100_irda *si = netdev_priv(dev);
 	int status;
 
 	status = Ser2UTSR0;
@@ -414,51 +333,96 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev)
 
 	}
 
-	if (status & UTSR0_TFS && si->tx_buff.len) {
-		/*
-		 * Transmitter FIFO is not full
-		 */
-		do {
-			Ser2UTDR = *si->tx_buff.data++;
-			si->tx_buff.len -= 1;
-		} while (Ser2UTSR1 & UTSR1_TNF && si->tx_buff.len);
+	return IRQ_HANDLED;
+}
 
-		if (si->tx_buff.len == 0) {
-			dev->stats.tx_packets++;
-			dev->stats.tx_bytes += si->tx_buff.data -
-					      si->tx_buff.head;
+/*
+ * FIR format support.
+ */
+static void sa1100_irda_firtxdma_irq(void *id)
+{
+	struct net_device *dev = id;
+	struct sa1100_irda *si = netdev_priv(dev);
+	struct sk_buff *skb;
 
-			/*
-			 * We need to ensure that the transmitter has
-			 * finished.
-			 */
-			do
-				rmb();
-			while (Ser2UTSR1 & UTSR1_TBY);
+	/*
+	 * Wait for the transmission to complete.  Unfortunately,
+	 * the hardware doesn't give us an interrupt to indicate
+	 * "end of frame".
+	 */
+	do
+		rmb();
+	while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY);
 
-			/*
-			 * Ok, we've finished transmitting.  Now enable
-			 * the receiver.  Sometimes we get a receive IRQ
-			 * immediately after a transmit...
-			 */
-			Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
-			Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
+	/*
+	 * Clear the transmit underrun bit.
+	 */
+	Ser2HSSR0 = HSSR0_TUR;
 
-			if (si->newspeed) {
-				sa1100_irda_set_speed(si, si->newspeed);
-				si->newspeed = 0;
-			}
+	/*
+	 * Do we need to change speed?  Note that we're lazy
+	 * here - we don't free the old dma_rx.skb.  We don't need
+	 * to allocate a buffer either.
+	 */
+	sa1100_irda_check_speed(si);
 
-			/* I'm hungry! */
-			netif_wake_queue(dev);
-		}
+	/*
+	 * Start reception.  This disables the transmitter for
+	 * us.  This will be using the existing RX buffer.
+	 */
+	sa1100_irda_rx_dma_start(si);
+
+	/* Account and free the packet. */
+	skb = si->dma_tx.skb;
+	if (skb) {
+		dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1,
+			     DMA_TO_DEVICE);
+		dev->stats.tx_packets ++;
+		dev->stats.tx_bytes += skb->len;
+		dev_kfree_skb_irq(skb);
+		si->dma_tx.skb = NULL;
 	}
+
+	/*
+	 * Make sure that the TX queue is available for sending
+	 * (for retries).  TX has priority over RX at all times.
+	 */
+	netif_wake_queue(dev);
+}
+
+static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
+	struct sa1100_irda *si)
+{
+	int mtt = irda_get_mtt(skb);
+
+	si->dma_tx.skb = skb;
+	sg_set_buf(&si->dma_tx.sg, skb->data, skb->len);
+	if (dma_map_sg(si->dma_tx.dev, &si->dma_tx.sg, 1, DMA_TO_DEVICE) == 0) {
+		si->dma_tx.skb = NULL;
+		netif_wake_queue(dev);
+		dev->stats.tx_dropped++;
+		dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
+	sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_firtxdma_irq, dev);
+
+	/*
+	 * If we have a mean turn-around time, impose the specified
+	 * specified delay.  We could shorten this by timing from
+	 * the point we received the packet.
+	 */
+	if (mtt)
+		udelay(mtt);
+
+	Ser2HSCR0 = HSCR0_HSSP | HSCR0_TXE;
+
+	return NETDEV_TX_OK;
 }
 
 static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev)
 {
-	struct sk_buff *skb = si->rxskb;
-	dma_addr_t dma_addr;
+	struct sk_buff *skb = si->dma_rx.skb;
 	unsigned int len, stat, data;
 
 	if (!skb) {
@@ -469,11 +433,10 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
 	/*
 	 * Get the current data position.
 	 */
-	dma_addr = sa1100_get_dma_pos(si->rxdma);
-	len = dma_addr - si->rxbuf_dma;
+	len = sa1100_irda_dma_xferred(&si->dma_rx);
 	if (len > HPSIR_MAX_RXLEN)
 		len = HPSIR_MAX_RXLEN;
-	dma_unmap_single(si->dev, si->rxbuf_dma, len, DMA_FROM_DEVICE);
+	dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE);
 
 	do {
 		/*
@@ -501,7 +464,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
 	} while (Ser2HSSR0 & HSSR0_EIF);
 
 	if (stat & HSSR1_EOF) {
-		si->rxskb = NULL;
+		si->dma_rx.skb = NULL;
 
 		skb_put(skb, len);
 		skb->dev = dev;
@@ -518,28 +481,23 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
 		netif_rx(skb);
 	} else {
 		/*
-		 * Remap the buffer.
+		 * Remap the buffer - it was previously mapped, and we
+		 * hope that this succeeds.
 		 */
-		si->rxbuf_dma = dma_map_single(si->dev, si->rxskb->data,
-						HPSIR_MAX_RXLEN,
-						DMA_FROM_DEVICE);
+		dma_map_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE);
 	}
 }
 
 /*
- * FIR format interrupt service routine.  We only have to
- * handle RX events; transmit events go via the TX DMA handler.
- *
- * No matter what, we disable RX, process, and the restart RX.
+ * We only have to handle RX events here; transmit events go via the TX
+ * DMA handler. We disable RX, process, and the restart RX.
  */
-static void sa1100_irda_fir_irq(struct net_device *dev)
+static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_irda *si)
 {
-	struct sa1100_irda *si = netdev_priv(dev);
-
 	/*
 	 * Stop RX DMA
 	 */
-	sa1100_stop_dma(si->rxdma);
+	dmaengine_pause(si->dma_rx.chan);
 
 	/*
 	 * Framing error - we throw away the packet completely.
@@ -555,7 +513,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
 		/*
 		 * Clear out the DMA...
 		 */
-		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
+		Ser2HSCR0 = HSCR0_HSSP;
 
 		/*
 		 * Clear selected status bits now, so we
@@ -577,74 +535,124 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
 	 * No matter what happens, we must restart reception.
 	 */
 	sa1100_irda_rx_dma_start(si);
+
+	return IRQ_HANDLED;
 }
 
-static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
+/*
+ * Set the IrDA communications speed.
+ */
+static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
 {
-	struct net_device *dev = dev_id;
-	if (IS_FIR(((struct sa1100_irda *)netdev_priv(dev))))
-		sa1100_irda_fir_irq(dev);
-	else
-		sa1100_irda_hpsir_irq(dev);
-	return IRQ_HANDLED;
+	unsigned long flags;
+	int brd, ret = -EINVAL;
+
+	switch (speed) {
+	case 9600:	case 19200:	case 38400:
+	case 57600:	case 115200:
+		brd = 3686400 / (16 * speed) - 1;
+
+		/* Stop the receive DMA, and configure transmit. */
+		if (IS_FIR(si)) {
+			dmaengine_terminate_all(si->dma_rx.chan);
+			dmaengine_slave_config(si->dma_tx.chan,
+						&sa1100_irda_sir_tx);
+		}
+
+		local_irq_save(flags);
+
+		Ser2UTCR3 = 0;
+		Ser2HSCR0 = HSCR0_UART;
+
+		Ser2UTCR1 = brd >> 8;
+		Ser2UTCR2 = brd;
+
+		/*
+		 * Clear status register
+		 */
+		Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
+		Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
+
+		if (si->pdata->set_speed)
+			si->pdata->set_speed(si->dev, speed);
+
+		si->speed = speed;
+		si->tx_start = sa1100_irda_sir_tx_start;
+		si->irq = sa1100_irda_sir_irq;
+
+		local_irq_restore(flags);
+		ret = 0;
+		break;
+
+	case 4000000:
+		if (!IS_FIR(si))
+			dmaengine_slave_config(si->dma_tx.chan,
+						&sa1100_irda_fir_tx);
+
+		local_irq_save(flags);
+
+		Ser2HSSR0 = 0xff;
+		Ser2HSCR0 = HSCR0_HSSP;
+		Ser2UTCR3 = 0;
+
+		si->speed = speed;
+		si->tx_start = sa1100_irda_fir_tx_start;
+		si->irq = sa1100_irda_fir_irq;
+
+		if (si->pdata->set_speed)
+			si->pdata->set_speed(si->dev, speed);
+
+		sa1100_irda_rx_alloc(si);
+		sa1100_irda_rx_dma_start(si);
+
+		local_irq_restore(flags);
+
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
 }
 
 /*
- * TX DMA completion handler.
+ * Control the power state of the IrDA transmitter.
+ * State:
+ *  0 - off
+ *  1 - short range, lowest power
+ *  2 - medium range, medium power
+ *  3 - maximum range, high power
+ *
+ * Currently, only assabet is known to support this.
  */
-static void sa1100_irda_txdma_irq(void *id)
+static int
+__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
 {
-	struct net_device *dev = id;
-	struct sa1100_irda *si = netdev_priv(dev);
-	struct sk_buff *skb = si->txskb;
-
-	si->txskb = NULL;
-
-	/*
-	 * Wait for the transmission to complete.  Unfortunately,
-	 * the hardware doesn't give us an interrupt to indicate
-	 * "end of frame".
-	 */
-	do
-		rmb();
-	while (!(Ser2HSSR0 & HSSR0_TUR) || Ser2HSSR1 & HSSR1_TBY);
+	int ret = 0;
+	if (si->pdata->set_power)
+		ret = si->pdata->set_power(si->dev, state);
+	return ret;
+}
 
-	/*
-	 * Clear the transmit underrun bit.
-	 */
-	Ser2HSSR0 = HSSR0_TUR;
+static inline int
+sa1100_set_power(struct sa1100_irda *si, unsigned int state)
+{
+	int ret;
 
-	/*
-	 * Do we need to change speed?  Note that we're lazy
-	 * here - we don't free the old rxskb.  We don't need
-	 * to allocate a buffer either.
-	 */
-	if (si->newspeed) {
-		sa1100_irda_set_speed(si, si->newspeed);
-		si->newspeed = 0;
-	}
+	ret = __sa1100_irda_set_power(si, state);
+	if (ret == 0)
+		si->power = state;
 
-	/*
-	 * Start reception.  This disables the transmitter for
-	 * us.  This will be using the existing RX buffer.
-	 */
-	sa1100_irda_rx_dma_start(si);
+	return ret;
+}
 
-	/*
-	 * Account and free the packet.
-	 */
-	if (skb) {
-		dma_unmap_single(si->dev, si->txbuf_dma, skb->len, DMA_TO_DEVICE);
-		dev->stats.tx_packets ++;
-		dev->stats.tx_bytes += skb->len;
-		dev_kfree_skb_irq(skb);
-	}
+static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct sa1100_irda *si = netdev_priv(dev);
 
-	/*
-	 * Make sure that the TX queue is available for sending
-	 * (for retries).  TX has priority over RX at all times.
-	 */
-	netif_wake_queue(dev);
+	return si->irq(dev, si);
 }
 
 static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -660,62 +668,19 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (speed != si->speed && speed != -1)
 		si->newspeed = speed;
 
-	/*
-	 * If this is an empty frame, we can bypass a lot.
-	 */
+	/* If this is an empty frame, we can bypass a lot. */
 	if (skb->len == 0) {
-		if (si->newspeed) {
-			si->newspeed = 0;
-			sa1100_irda_set_speed(si, speed);
-		}
+		sa1100_irda_check_speed(si);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 
-	if (!IS_FIR(si)) {
-		netif_stop_queue(dev);
-
-		si->tx_buff.data = si->tx_buff.head;
-		si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,
-						  si->tx_buff.truesize);
-
-		/*
-		 * Set the transmit interrupt enable.  This will fire
-		 * off an interrupt immediately.  Note that we disable
-		 * the receiver so we won't get spurious characteres
-		 * received.
-		 */
-		Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE;
-
-		dev_kfree_skb(skb);
-	} else {
-		int mtt = irda_get_mtt(skb);
-
-		/*
-		 * We must not be transmitting...
-		 */
-		BUG_ON(si->txskb);
-
-		netif_stop_queue(dev);
-
-		si->txskb = skb;
-		si->txbuf_dma = dma_map_single(si->dev, skb->data,
-					 skb->len, DMA_TO_DEVICE);
-
-		sa1100_start_dma(si->txdma, si->txbuf_dma, skb->len);
-
-		/*
-		 * If we have a mean turn-around time, impose the specified
-		 * specified delay.  We could shorten this by timing from
-		 * the point we received the packet.
-		 */
-		if (mtt)
-			udelay(mtt);
+	netif_stop_queue(dev);
 
-		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
-	}
+	/* We must not already have a skb to transmit... */
+	BUG_ON(si->dma_tx.skb);
 
-	return NETDEV_TX_OK;
+	return si->tx_start(skb, dev, si);
 }
 
 static int
@@ -762,6 +727,69 @@ sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
 	return ret;
 }
 
+static int sa1100_irda_startup(struct sa1100_irda *si)
+{
+	int ret;
+
+	/*
+	 * Ensure that the ports for this device are setup correctly.
+	 */
+	if (si->pdata->startup)	{
+		ret = si->pdata->startup(si->dev);
+		if (ret)
+			return ret;
+	}
+
+	/*
+	 * Configure PPC for IRDA - we want to drive TXD2 low.
+	 * We also want to drive this pin low during sleep.
+	 */
+	PPSR &= ~PPC_TXD2;
+	PSDR &= ~PPC_TXD2;
+	PPDR |= PPC_TXD2;
+
+	/*
+	 * Enable HP-SIR modulation, and ensure that the port is disabled.
+	 */
+	Ser2UTCR3 = 0;
+	Ser2HSCR0 = HSCR0_UART;
+	Ser2UTCR4 = si->utcr4;
+	Ser2UTCR0 = UTCR0_8BitData;
+	Ser2HSCR2 = HSCR2_TrDataH | HSCR2_RcDataL;
+
+	/*
+	 * Clear status register
+	 */
+	Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
+
+	ret = sa1100_irda_set_speed(si, si->speed = 9600);
+	if (ret) {
+		Ser2UTCR3 = 0;
+		Ser2HSCR0 = 0;
+
+		if (si->pdata->shutdown)
+			si->pdata->shutdown(si->dev);
+	}
+
+	return ret;
+}
+
+static void sa1100_irda_shutdown(struct sa1100_irda *si)
+{
+	/*
+	 * Stop all DMA activity.
+	 */
+	dmaengine_terminate_all(si->dma_rx.chan);
+	dmaengine_terminate_all(si->dma_tx.chan);
+
+	/* Disable the port. */
+	Ser2UTCR3 = 0;
+	Ser2HSCR0 = 0;
+
+	if (si->pdata->shutdown)
+		si->pdata->shutdown(si->dev);
+}
+
 static int sa1100_irda_start(struct net_device *dev)
 {
 	struct sa1100_irda *si = netdev_priv(dev);
@@ -769,26 +797,17 @@ static int sa1100_irda_start(struct net_device *dev)
 
 	si->speed = 9600;
 
-	err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev);
-	if (err)
-		goto err_irq;
-
-	err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive",
-				 NULL, NULL, &si->rxdma);
+	err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc",
+				&sa1100_irda_fir_rx);
 	if (err)
 		goto err_rx_dma;
 
-	err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit",
-				 sa1100_irda_txdma_irq, dev, &si->txdma);
+	err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr",
+				&sa1100_irda_sir_tx);
 	if (err)
 		goto err_tx_dma;
 
 	/*
-	 * The interrupt must remain disabled for now.
-	 */
-	disable_irq(dev->irq);
-
-	/*
 	 * Setup the serial port for the specified speed.
 	 */
 	err = sa1100_irda_startup(si);
@@ -803,44 +822,60 @@ static int sa1100_irda_start(struct net_device *dev)
 	if (!si->irlap)
 		goto err_irlap;
 
+	err = request_irq(dev->irq, sa1100_irda_irq, 0, dev->name, dev);
+	if (err)
+		goto err_irq;
+
 	/*
 	 * Now enable the interrupt and start the queue
 	 */
 	si->open = 1;
 	sa1100_set_power(si, power_level); /* low power mode */
-	enable_irq(dev->irq);
+
 	netif_start_queue(dev);
 	return 0;
 
+err_irq:
+	irlap_close(si->irlap);
 err_irlap:
 	si->open = 0;
 	sa1100_irda_shutdown(si);
 err_startup:
-	sa1100_free_dma(si->txdma);
+	dma_release_channel(si->dma_tx.chan);
 err_tx_dma:
-	sa1100_free_dma(si->rxdma);
+	dma_release_channel(si->dma_rx.chan);
 err_rx_dma:
-	free_irq(dev->irq, dev);
-err_irq:
 	return err;
 }
 
 static int sa1100_irda_stop(struct net_device *dev)
 {
 	struct sa1100_irda *si = netdev_priv(dev);
+	struct sk_buff *skb;
 
-	disable_irq(dev->irq);
+	netif_stop_queue(dev);
+
+	si->open = 0;
 	sa1100_irda_shutdown(si);
 
 	/*
-	 * If we have been doing DMA receive, make sure we
+	 * If we have been doing any DMA activity, make sure we
 	 * tidy that up cleanly.
 	 */
-	if (si->rxskb) {
-		dma_unmap_single(si->dev, si->rxbuf_dma, HPSIR_MAX_RXLEN,
-				 DMA_FROM_DEVICE);
-		dev_kfree_skb(si->rxskb);
-		si->rxskb = NULL;
+	skb = si->dma_rx.skb;
+	if (skb) {
+		dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1,
+			     DMA_FROM_DEVICE);
+		dev_kfree_skb(skb);
+		si->dma_rx.skb = NULL;
+	}
+
+	skb = si->dma_tx.skb;
+	if (skb) {
+		dma_unmap_sg(si->dma_tx.dev, &si->dma_tx.sg, 1,
+			     DMA_TO_DEVICE);
+		dev_kfree_skb(skb);
+		si->dma_tx.skb = NULL;
 	}
 
 	/* Stop IrLAP */
@@ -849,14 +884,11 @@ static int sa1100_irda_stop(struct net_device *dev)
 		si->irlap = NULL;
 	}
 
-	netif_stop_queue(dev);
-	si->open = 0;
-
 	/*
 	 * Free resources
 	 */
-	sa1100_free_dma(si->txdma);
-	sa1100_free_dma(si->rxdma);
+	dma_release_channel(si->dma_tx.chan);
+	dma_release_channel(si->dma_rx.chan);
 	free_irq(dev->irq, dev);
 
 	sa1100_set_power(si, 0);
@@ -888,11 +920,15 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 	struct net_device *dev;
 	struct sa1100_irda *si;
 	unsigned int baudrate_mask;
-	int err;
+	int err, irq;
 
 	if (!pdev->dev.platform_data)
 		return -EINVAL;
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return irq < 0 ? irq : -ENXIO;
+
 	err = request_mem_region(__PREG(Ser2UTCR0), 0x24, "IrDA") ? 0 : -EBUSY;
 	if (err)
 		goto err_mem_1;
@@ -907,22 +943,27 @@ static int sa1100_irda_probe(struct platform_device *pdev)
 	if (!dev)
 		goto err_mem_4;
 
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
 	si = netdev_priv(dev);
 	si->dev = &pdev->dev;
 	si->pdata = pdev->dev.platform_data;
 
+	sg_init_table(&si->dma_rx.sg, 1);
+	sg_init_table(&si->dma_tx.sg, 1);
+
 	/*
 	 * Initialise the HP-SIR buffers
 	 */
 	err = sa1100_irda_init_iobuf(&si->rx_buff, 14384);
 	if (err)
 		goto err_mem_5;
-	err = sa1100_irda_init_iobuf(&si->tx_buff, 4000);
+	err = sa1100_irda_init_iobuf(&si->tx_buff, IRDA_SIR_MAX_FRAME);
 	if (err)
 		goto err_mem_5;
 
 	dev->netdev_ops	= &sa1100_irda_netdev_ops;
-	dev->irq	= IRQ_Ser2ICP;
+	dev->irq	= irq;
 
 	irda_init_max_qos_capabilies(&si->qos);
 
@@ -996,6 +1037,74 @@ static int sa1100_irda_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+/*
+ * Suspend the IrDA interface.
+ */
+static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct sa1100_irda *si;
+
+	if (!dev)
+		return 0;
+
+	si = netdev_priv(dev);
+	if (si->open) {
+		/*
+		 * Stop the transmit queue
+		 */
+		netif_device_detach(dev);
+		disable_irq(dev->irq);
+		sa1100_irda_shutdown(si);
+		__sa1100_irda_set_power(si, 0);
+	}
+
+	return 0;
+}
+
+/*
+ * Resume the IrDA interface.
+ */
+static int sa1100_irda_resume(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	struct sa1100_irda *si;
+
+	if (!dev)
+		return 0;
+
+	si = netdev_priv(dev);
+	if (si->open) {
+		/*
+		 * If we missed a speed change, initialise at the new speed
+		 * directly.  It is debatable whether this is actually
+		 * required, but in the interests of continuing from where
+		 * we left off it is desirable.  The converse argument is
+		 * that we should re-negotiate at 9600 baud again.
+		 */
+		if (si->newspeed) {
+			si->speed = si->newspeed;
+			si->newspeed = 0;
+		}
+
+		sa1100_irda_startup(si);
+		__sa1100_irda_set_power(si, si->power);
+		enable_irq(dev->irq);
+
+		/*
+		 * This automatically wakes up the queue
+		 */
+		netif_device_attach(dev);
+	}
+
+	return 0;
+}
+#else
+#define sa1100_irda_suspend	NULL
+#define sa1100_irda_resume	NULL
+#endif
+
 static struct platform_driver sa1100ir_driver = {
 	.probe		= sa1100_irda_probe,
 	.remove		= sa1100_irda_remove,
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 9ea9921..f975afd 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -372,6 +372,7 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p)
 
 	if (!(dev->flags & IFF_UP)) {
 		/* Just copy in the new address */
+		dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 		memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
 	} else {
 		/* Rehash and update the device filters */
@@ -687,7 +688,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
 		return -EINVAL;
 
 	if (!tb[IFLA_ADDRESS])
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 	if (!macvlan_port_exists(lowerdev)) {
 		err = macvlan_port_create(lowerdev);
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 58dc117..0427c65 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/cdev.h>
+#include <linux/idr.h>
 #include <linux/fs.h>
 
 #include <net/net_namespace.h>
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index e888202..f9347ea 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -169,10 +169,8 @@ static struct netconsole_target *alloc_param_target(char *target_config)
 	 * Note that these targets get their config_item fields zeroed-out.
 	 */
 	nt = kzalloc(sizeof(*nt), GFP_KERNEL);
-	if (!nt) {
-		printk(KERN_ERR "netconsole: failed to allocate memory\n");
+	if (!nt)
 		goto fail;
-	}
 
 	nt->np.name = "netconsole";
 	strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ);
@@ -551,10 +549,8 @@ static struct config_item *make_netconsole_target(struct config_group *group,
 	 * Target is disabled at creation (enabled == 0).
 	 */
 	nt = kzalloc(sizeof(*nt), GFP_KERNEL);
-	if (!nt) {
-		printk(KERN_ERR "netconsole: failed to allocate memory\n");
+	if (!nt)
 		return ERR_PTR(-ENOMEM);
-	}
 
 	nt->np.name = "netconsole";
 	strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ);
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index e8be47d..60338ff 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -355,8 +355,7 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
 		}
 	}
 
-	if (clk125en == false ||
-	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
+	if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
 		val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
 	else
 		val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
@@ -373,8 +372,7 @@ static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
 
 	orig = val;
 
-	if (clk125en == false ||
-	    (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
+	if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
 		val |= BCM54XX_SHD_APD_EN;
 	else
 		val &= ~BCM54XX_SHD_APD_EN;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f320f46..e8c42d6 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -915,9 +915,7 @@ static int phy_probe(struct device *dev)
 
 	phydev = to_phy_device(dev);
 
-	/* Make sure the driver is held.
-	 * XXX -- Is this correct? */
-	drv = get_driver(phydev->dev.driver);
+	drv = phydev->dev.driver;
 	phydrv = to_phy_driver(drv);
 	phydev->drv = phydrv;
 
@@ -957,8 +955,6 @@ static int phy_remove(struct device *dev)
 
 	if (phydev->drv->remove)
 		phydev->drv->remove(phydev);
-
-	put_driver(dev->driver);
 	phydev->drv = NULL;
 
 	return 0;
diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c
index a9e9ca8..1a5a316 100644
--- a/drivers/net/plip/plip.c
+++ b/drivers/net/plip/plip.c
@@ -1260,10 +1260,8 @@ static void plip_attach (struct parport *port)
 
 		sprintf(name, "plip%d", unit);
 		dev = alloc_etherdev(sizeof(struct net_local));
-		if (!dev) {
-			printk(KERN_ERR "plip: memory squeeze\n");
+		if (!dev)
 			return;
-		}
 
 		strcpy(dev->name, name);
 
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index edfa15d..93a8639 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2113,7 +2113,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
 
 				skb->len += p->len;
 				skb->data_len += p->len;
-				skb->truesize += p->len;
+				skb->truesize += p->truesize;
 
 				if (p == tail)
 					break;
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index df884dd..234cd9d 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -670,10 +670,8 @@ static int __init pptp_init_module(void)
 	pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n");
 
 	callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *));
-	if (!callid_sock) {
-		pr_err("PPTP: cann't allocate memory\n");
+	if (!callid_sock)
 		return -ENOMEM;
-	}
 
 	err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP);
 	if (err) {
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 7145714..a57f057 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -497,8 +497,6 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 	/* Allocate our net_device structure */
 	ndev = alloc_etherdev(sizeof(struct rionet_private));
 	if (ndev == NULL) {
-		printk(KERN_INFO "%s: could not allocate ethernet device.\n",
-		       DRV_NAME);
 		rc = -ENOMEM;
 		goto out;
 	}
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index ba08341..69345df 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -1296,10 +1296,8 @@ static int __init slip_init(void)
 
 	slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev,
 								GFP_KERNEL);
-	if (!slip_devs) {
-		printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n");
+	if (!slip_devs)
 		return -ENOMEM;
-	}
 
 	/* Fill in our line protocol discipline, and register it */
 	status = tty_register_ldisc(N_SLIP, &sl_ldisc);
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 6b678f3..8f81805 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -868,6 +868,7 @@ static int team_set_mac_address(struct net_device *dev, void *p)
 	struct team_port *port;
 	struct sockaddr *addr = p;
 
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
 	rcu_read_lock();
 	list_for_each_entry_rcu(port, &team->port_list, list)
@@ -1087,7 +1088,7 @@ static int team_newlink(struct net *src_net, struct net_device *dev,
 	int err;
 
 	if (tb[IFLA_ADDRESS] == NULL)
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 	err = register_netdevice(dev);
 	if (err)
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index ef9fdf3..d7c292a 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -674,15 +674,11 @@ static int xl_open(struct net_device *dev)
 	/* These MUST be on 8 byte boundaries */
 	xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL);
 	if (xl_priv->xl_tx_ring == NULL) {
-		printk(KERN_WARNING "%s: Not enough memory to allocate tx buffers.\n",
-				     dev->name);
 		free_irq(dev->irq,dev);
 		return -ENOMEM;
 	}
 	xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL);
 	if (xl_priv->xl_rx_ring == NULL) {
-		printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n",
-				     dev->name);
 		free_irq(dev->irq,dev);
 		kfree(xl_priv->xl_tx_ring);
 		return -ENOMEM;
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 6153cfd..1cdc034 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -171,7 +171,6 @@ static int __devinit madgemc_probe(struct device *device)
 
 	card = kmalloc(sizeof(struct card_info), GFP_KERNEL);
 	if (card==NULL) {
-		printk("madgemc: unable to allocate card struct\n");
 		ret = -ENOMEM;
 		goto getout1;
 	}
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 65e9cf3..102f896 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -1525,10 +1525,8 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev)
 	/* Check if adapter is opened, avoiding COMMAND_REJECT
 	 * interrupt by the adapter!
 	 */
-	if(tp->AdapterOpenFlag == 0)
-	{
-		if(tp->CMDqueue & OC_OPEN)
-		{
+	if (tp->AdapterOpenFlag == 0) {
+		if (tp->CMDqueue & OC_OPEN) {
 			/* Execute OPEN command	*/
 			tp->CMDqueue ^= OC_OPEN;
 
@@ -1536,21 +1534,17 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev)
 			tp->scb.Parm[0] = LOWORD(Addr);
 			tp->scb.Parm[1] = HIWORD(Addr);
 			tp->scb.CMD = OPEN;
-		}
-		else
+		} else
 			/* No OPEN command queued, but adapter closed. Note:
 			 * We'll try to re-open the adapter in DriverPoll()
 			 */
 			return;		/* No adapter command issued */
-	}
-	else
-	{
+	} else {
 		/* Adapter is open; evaluate command queue: try to execute
 		 * outstanding commands (depending on priority!) CLOSE
 		 * command queued
 		 */
-		if(tp->CMDqueue & OC_CLOSE)
-		{
+		if (tp->CMDqueue & OC_CLOSE) {
 			tp->CMDqueue ^= OC_CLOSE;
 			tp->AdapterOpenFlag = 0;
 			tp->scb.Parm[0] = 0; /* Parm[0], Parm[1] are ignored */
@@ -1560,109 +1554,70 @@ static void tms380tr_chk_outstanding_cmds(struct net_device *dev)
 				tp->CMDqueue |= OC_OPEN; /* re-open adapter */
 			else
 				tp->CMDqueue = 0;	/* no more commands */
-		}
-		else
-		{
-			if(tp->CMDqueue & OC_RECEIVE)
-			{
-				tp->CMDqueue ^= OC_RECEIVE;
-				Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer);
-				tp->scb.Parm[0] = LOWORD(Addr);
-				tp->scb.Parm[1] = HIWORD(Addr);
-				tp->scb.CMD = RECEIVE;
-			}
-			else
-			{
-				if(tp->CMDqueue & OC_TRANSMIT_HALT)
-				{
-					/* NOTE: TRANSMIT.HALT must be checked 
-					 * before TRANSMIT.
-					 */
-					tp->CMDqueue ^= OC_TRANSMIT_HALT;
-					tp->scb.CMD = TRANSMIT_HALT;
-
-					/* Parm[0] and Parm[1] are ignored
-					 * but should be set to zero!
-					 */
-					tp->scb.Parm[0] = 0;
-					tp->scb.Parm[1] = 0;
-				}
-				else
-				{
-					if(tp->CMDqueue & OC_TRANSMIT)
-					{
-						/* NOTE: TRANSMIT must be 
-						 * checked after TRANSMIT.HALT
-						 */
-						if(tp->TransmitCommandActive)
-						{
-							if(!tp->TransmitHaltScheduled)
-							{
-								tp->TransmitHaltScheduled = 1;
-								tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT) ;
-							}
-							tp->TransmitCommandActive = 0;
-							return;
-						}
-
-						tp->CMDqueue ^= OC_TRANSMIT;
-						tms380tr_cancel_tx_queue(tp);
-						Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer);
-						tp->scb.Parm[0] = LOWORD(Addr);
-						tp->scb.Parm[1] = HIWORD(Addr);
-						tp->scb.CMD = TRANSMIT;
-						tp->TransmitCommandActive = 1;
-					}
-					else
-					{
-						if(tp->CMDqueue & OC_MODIFY_OPEN_PARMS)
-						{
-							tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS;
-							tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/
-							tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION;
-							tp->scb.Parm[1] = 0; /* is ignored but should be zero */
-							tp->scb.CMD = MODIFY_OPEN_PARMS;
-						}
-						else
-						{
-							if(tp->CMDqueue & OC_SET_FUNCT_ADDR)
-							{
-								tp->CMDqueue ^= OC_SET_FUNCT_ADDR;
-								tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr);
-								tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr);
-								tp->scb.CMD = SET_FUNCT_ADDR;
-							}
-							else
-							{
-								if(tp->CMDqueue & OC_SET_GROUP_ADDR)
-								{
-									tp->CMDqueue ^= OC_SET_GROUP_ADDR;
-									tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr);
-									tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr);
-									tp->scb.CMD = SET_GROUP_ADDR;
-								}
-								else
-								{
-									if(tp->CMDqueue & OC_READ_ERROR_LOG)
-									{
-										tp->CMDqueue ^= OC_READ_ERROR_LOG;
-										Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer);
-										tp->scb.Parm[0] = LOWORD(Addr);
-										tp->scb.Parm[1] = HIWORD(Addr);
-										tp->scb.CMD = READ_ERROR_LOG;
-									}
-									else
-									{
-										printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n");
-										tp->CMDqueue = 0;
-										return;
-									}
-								}
-							}
-						}
-					}
+		} else if (tp->CMDqueue & OC_RECEIVE) {
+			tp->CMDqueue ^= OC_RECEIVE;
+			Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer);
+			tp->scb.Parm[0] = LOWORD(Addr);
+			tp->scb.Parm[1] = HIWORD(Addr);
+			tp->scb.CMD = RECEIVE;
+		} else if (tp->CMDqueue & OC_TRANSMIT_HALT) {
+			/* NOTE: TRANSMIT.HALT must be checked
+			 * before TRANSMIT.
+			 */
+			tp->CMDqueue ^= OC_TRANSMIT_HALT;
+			tp->scb.CMD = TRANSMIT_HALT;
+
+			/* Parm[0] and Parm[1] are ignored
+			 * but should be set to zero!
+			 */
+			tp->scb.Parm[0] = 0;
+			tp->scb.Parm[1] = 0;
+		} else if (tp->CMDqueue & OC_TRANSMIT) {
+			/* NOTE: TRANSMIT must be
+			 * checked after TRANSMIT.HALT
+			 */
+			if (tp->TransmitCommandActive) {
+				if (!tp->TransmitHaltScheduled) {
+					tp->TransmitHaltScheduled = 1;
+					tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT);
 				}
+				tp->TransmitCommandActive = 0;
+				return;
 			}
+
+			tp->CMDqueue ^= OC_TRANSMIT;
+			tms380tr_cancel_tx_queue(tp);
+			Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer);
+			tp->scb.Parm[0] = LOWORD(Addr);
+			tp->scb.Parm[1] = HIWORD(Addr);
+			tp->scb.CMD = TRANSMIT;
+			tp->TransmitCommandActive = 1;
+		} else if (tp->CMDqueue & OC_MODIFY_OPEN_PARMS) {
+			tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS;
+			tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/
+			tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION;
+			tp->scb.Parm[1] = 0; /* is ignored but should be zero */
+			tp->scb.CMD = MODIFY_OPEN_PARMS;
+		} else if (tp->CMDqueue & OC_SET_FUNCT_ADDR) {
+			tp->CMDqueue ^= OC_SET_FUNCT_ADDR;
+			tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr);
+			tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr);
+			tp->scb.CMD = SET_FUNCT_ADDR;
+		} else if (tp->CMDqueue & OC_SET_GROUP_ADDR) {
+			tp->CMDqueue ^= OC_SET_GROUP_ADDR;
+			tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr);
+			tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr);
+			tp->scb.CMD = SET_GROUP_ADDR;
+		} else if (tp->CMDqueue & OC_READ_ERROR_LOG) {
+			tp->CMDqueue ^= OC_READ_ERROR_LOG;
+			Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer);
+			tp->scb.Parm[0] = LOWORD(Addr);
+			tp->scb.Parm[1] = HIWORD(Addr);
+			tp->scb.CMD = READ_ERROR_LOG;
+		} else {
+			printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n");
+			tp->CMDqueue = 0;
+			return;
 		}
 	}
 
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 93c5d72..2c5d349 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -531,7 +531,7 @@ static void tun_net_init(struct net_device *dev)
 		ether_setup(dev);
 		dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 2335761..4bad899 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -398,6 +398,27 @@ config USB_NET_KALMIA
 	  To compile this driver as a module, choose M here: the
 	  module will be called kalmia.
 
+config USB_NET_QMI_WWAN
+	tristate "QMI WWAN driver for Qualcomm MSM based 3G and LTE modems"
+	depends on USB_USBNET
+	help
+	  Support WWAN LTE/3G devices based on Qualcomm Mobile Data Modem
+	  (MDM) chipsets.  Examples of such devices are
+	    * Huawei E392/E398
+
+	  This driver will only drive the ethernet part of the chips.
+	  The devices require additional configuration to be usable.
+	  Multiple management interfaces with linux drivers are
+	  available:
+
+	    * option: AT commands on /dev/ttyUSBx
+	    * cdc-wdm: Qualcomm MSM Interface (QMI) protocol on /dev/cdc-wdmx
+
+	  A modem manager with support for QMI is recommended.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called qmi_wwan.
+
 config USB_HSO
 	tristate "Option USB High Speed Mobile Devices"
 	depends on USB && RFKILL
@@ -461,4 +482,5 @@ config USB_VL600
 
 	  http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
 
+
 endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index c203fa2..a2e2d72 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -29,4 +29,5 @@ obj-$(CONFIG_USB_SIERRA_NET)	+= sierra_net.o
 obj-$(CONFIG_USB_NET_CX82310_ETH)	+= cx82310_eth.o
 obj-$(CONFIG_USB_NET_CDC_NCM)	+= cdc_ncm.o
 obj-$(CONFIG_USB_VL600)		+= lg-vl600.o
+obj-$(CONFIG_USB_NET_QMI_WWAN)	+= qmi_wwan.o
 
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 5d99b8c..7523930 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -1332,10 +1332,8 @@ static int pegasus_probe(struct usb_interface *intf,
 	usb_get_dev(dev);
 
 	net = alloc_etherdev(sizeof(struct pegasus));
-	if (!net) {
-		dev_err(&intf->dev, "can't allocate %s\n", "device");
+	if (!net)
 		goto out;
-	}
 
 	pegasus = netdev_priv(net);
 	pegasus->dev_index = dev_index;
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
new file mode 100644
index 0000000..739e6de
--- /dev/null
+++ b/drivers/net/usb/qmi_wwan.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2012  Bjørn Mork <bjorn@mork.no>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+
+/* The name of the CDC Device Management driver */
+#define DM_DRIVER "cdc_wdm"
+
+/*
+ * This driver supports wwan (3G/LTE/?) devices using a vendor
+ * specific management protocol called Qualcomm MSM Interface (QMI) -
+ * in addition to the more common AT commands over serial interface
+ * management
+ *
+ * QMI is wrapped in CDC, using CDC encapsulated commands on the
+ * control ("master") interface of a two-interface CDC Union
+ * resembling standard CDC ECM.  The devices do not use the control
+ * interface for any other CDC messages.  Most likely because the
+ * management protocol is used in place of the standard CDC
+ * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE
+ *
+ * Handling a protocol like QMI is out of the scope for any driver.
+ * It can be exported as a character device using the cdc-wdm driver,
+ * which will enable userspace applications ("modem managers") to
+ * handle it.  This may be required to use the network interface
+ * provided by the driver.
+ *
+ * These devices may alternatively/additionally be configured using AT
+ * commands on any of the serial interfaces driven by the option driver
+ *
+ * This driver binds only to the data ("slave") interface to enable
+ * the cdc-wdm driver to bind to the control interface.  It still
+ * parses the CDC functional descriptors on the control interface to
+ *  a) verify that this is indeed a handled interface (CDC Union
+ *     header lists it as slave)
+ *  b) get MAC address and other ethernet config from the CDC Ethernet
+ *     header
+ *  c) enable user bind requests against the control interface, which
+ *     is the common way to bind to CDC Ethernet Control Model type
+ *     interfaces
+ *  d) provide a hint to the user about which interface is the
+ *     corresponding management interface
+ */
+
+static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int status = -1;
+	struct usb_interface *control = NULL;
+	u8 *buf = intf->cur_altsetting->extra;
+	int len = intf->cur_altsetting->extralen;
+	struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
+	struct usb_cdc_union_desc *cdc_union = NULL;
+	struct usb_cdc_ether_desc *cdc_ether = NULL;
+	u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE;
+	u32 found = 0;
+
+	/*
+	 * assume a data interface has no additional descriptors and
+	 * that the control and data interface are numbered
+	 * consecutively - this holds for the Huawei device at least
+	 */
+	if (len == 0 && desc->bInterfaceNumber > 0) {
+		control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1);
+		if (!control)
+			goto err;
+
+		buf = control->cur_altsetting->extra;
+		len = control->cur_altsetting->extralen;
+		dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n",
+			dev_name(&control->dev));
+	}
+
+	while (len > 3) {
+		struct usb_descriptor_header *h = (void *)buf;
+
+		/* ignore any misplaced descriptors */
+		if (h->bDescriptorType != USB_DT_CS_INTERFACE)
+			goto next_desc;
+
+		/* buf[2] is CDC descriptor subtype */
+		switch (buf[2]) {
+		case USB_CDC_HEADER_TYPE:
+			if (found & 1 << USB_CDC_HEADER_TYPE) {
+				dev_dbg(&intf->dev, "extra CDC header\n");
+				goto err;
+			}
+			if (h->bLength != sizeof(struct usb_cdc_header_desc)) {
+				dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength);
+				goto err;
+			}
+			break;
+		case USB_CDC_UNION_TYPE:
+			if (found & 1 << USB_CDC_UNION_TYPE) {
+				dev_dbg(&intf->dev, "extra CDC union\n");
+				goto err;
+			}
+			if (h->bLength != sizeof(struct usb_cdc_union_desc)) {
+				dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength);
+				goto err;
+			}
+			cdc_union = (struct usb_cdc_union_desc *)buf;
+			break;
+		case USB_CDC_ETHERNET_TYPE:
+			if (found & 1 << USB_CDC_ETHERNET_TYPE) {
+				dev_dbg(&intf->dev, "extra CDC ether\n");
+				goto err;
+			}
+			if (h->bLength != sizeof(struct usb_cdc_ether_desc)) {
+				dev_dbg(&intf->dev, "CDC ether len %u\n",  h->bLength);
+				goto err;
+			}
+			cdc_ether = (struct usb_cdc_ether_desc *)buf;
+			break;
+		}
+
+		/*
+		 * Remember which CDC functional descriptors we've seen.  Works
+		 * for all types we care about, of which USB_CDC_ETHERNET_TYPE
+		 * (0x0f) is the highest numbered
+		 */
+		if (buf[2] < 32)
+			found |= 1 << buf[2];
+
+next_desc:
+		len -= h->bLength;
+		buf += h->bLength;
+	}
+
+	/* did we find all the required ones? */
+	if ((found & required) != required) {
+		dev_err(&intf->dev, "CDC functional descriptors missing\n");
+		goto err;
+	}
+
+	/* give the user a helpful hint if trying to bind to the wrong interface */
+	if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) {
+		dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n",
+			dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev));
+		goto err;
+	}
+
+	/* errors aren't fatal - we can live with the dynamic address */
+	if (cdc_ether) {
+		dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize);
+		usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress);
+	}
+
+	/* success! point the user to the management interface */
+	if (control)
+		dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n",
+			dev_name(&control->dev));
+
+	/* XXX: add a sysfs symlink somewhere to help management applications find it? */
+
+	/* collect bulk endpoints now that we know intf == "data" interface */
+	status = usbnet_get_endpoints(dev, intf);
+
+err:
+	return status;
+}
+
+/* stolen from cdc_ether.c */
+static int qmi_wwan_manage_power(struct usbnet *dev, int on)
+{
+	dev->intf->needs_remote_wakeup = on;
+	return 0;
+}
+
+static const struct driver_info	qmi_wwan_info = {
+	.description	= "QMI speaking wwan device",
+	.flags		= FLAG_WWAN,
+	.bind		= qmi_wwan_bind,
+	.manage_power	= qmi_wwan_manage_power,
+};
+
+#define HUAWEI_VENDOR_ID	0x12D1
+
+static const struct usb_device_id products[] = {
+{
+	/* Huawei E392, E398 and possibly others sharing both device id and more... */
+	.match_flags        = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
+	.idVendor           = HUAWEI_VENDOR_ID,
+	.bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
+	.bInterfaceSubClass = 1,
+	.bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */
+	.driver_info        = (unsigned long)&qmi_wwan_info,
+}, {
+},	/* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver qmi_wwan_driver = {
+	.name		      = "qmi_wwan",
+	.id_table	      = products,
+	.probe		      =	usbnet_probe,
+	.disconnect	      = usbnet_disconnect,
+	.suspend	      = usbnet_suspend,
+	.resume		      =	usbnet_resume,
+	.reset_resume         = usbnet_resume,
+	.supports_autosuspend = 1,
+};
+
+static int __init qmi_wwan_init(void)
+{
+	return usb_register(&qmi_wwan_driver);
+}
+module_init(qmi_wwan_init);
+
+static void __exit qmi_wwan_exit(void)
+{
+	usb_deregister(&qmi_wwan_driver);
+}
+module_exit(qmi_wwan_exit);
+
+MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
+MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index 0710b4c..6dda2fe 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -894,10 +894,8 @@ static int rtl8150_probe(struct usb_interface *intf,
 	struct net_device *netdev;
 
 	netdev = alloc_etherdev(sizeof(rtl8150_t));
-	if (!netdev) {
-		err("Out of memory");
+	if (!netdev)
 		return -ENOMEM;
-	}
 
 	dev = netdev_priv(netdev);
 
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 3b017bb..187d01c 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -615,7 +615,7 @@ static void smsc75xx_init_mac_address(struct usbnet *dev)
 	}
 
 	/* no eeprom, or eeprom values are invalid. generate random MAC */
-	random_ether_addr(dev->net->dev_addr);
+	eth_hw_addr_random(dev->net);
 	netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
 }
 
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index d45520e..5f19f84 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -614,7 +614,7 @@ static void smsc95xx_init_mac_address(struct usbnet *dev)
 	}
 
 	/* no eeprom, or eeprom values are invalid. generate random MAC */
-	random_ether_addr(dev->net->dev_addr);
+	eth_hw_addr_random(dev->net);
 	netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr\n");
 }
 
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index fae0fbd..b924f46 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1334,10 +1334,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
 	// set up our own records
 	net = alloc_etherdev(sizeof(*dev));
-	if (!net) {
-		dbg ("can't kmalloc dev");
+	if (!net)
 		goto out;
-	}
 
 	/* netdev_printk() needs this so do it as early as possible */
 	SET_NETDEV_DEV(net, &udev->dev);
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index f701d41..ed2caed 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -316,6 +316,11 @@ static const struct usb_device_id	products [] = {
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info = ZAURUS_PXA_INFO,
 }, {
+	/* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */
+	USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+	.driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
 	.match_flags    =   USB_DEVICE_ID_MATCH_INT_INFO
 		 | USB_DEVICE_ID_MATCH_DEVICE,
 	.idVendor               = 0x04DD,
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 4a34028..5852361 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -346,7 +346,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
 	}
 
 	if (tbp[IFLA_ADDRESS] == NULL)
-		random_ether_addr(peer->dev_addr);
+		eth_hw_addr_random(peer);
 
 	err = register_netdevice(peer);
 	put_net(net);
@@ -368,7 +368,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
 	 */
 
 	if (tb[IFLA_ADDRESS] == NULL)
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 	if (tb[IFLA_IFNAME])
 		nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4880aa8..019da01 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -255,7 +255,7 @@ static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb)
 static void receive_buf(struct net_device *dev, void *buf, unsigned int len)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
-	struct virtnet_stats __percpu *stats = this_cpu_ptr(vi->stats);
+	struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
 	struct sk_buff *skb;
 	struct page *page;
 	struct skb_vnet_hdr *hdr;
@@ -549,7 +549,7 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
 {
 	struct sk_buff *skb;
 	unsigned int len, tot_sgs = 0;
-	struct virtnet_stats __percpu *stats = this_cpu_ptr(vi->stats);
+	struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
 
 	while ((skb = virtqueue_get_buf(vi->svq, &len)) != NULL) {
 		pr_debug("Sent skb %p\n", skb);
@@ -688,8 +688,7 @@ static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev,
 	unsigned int start;
 
 	for_each_possible_cpu(cpu) {
-		struct virtnet_stats __percpu *stats
-			= per_cpu_ptr(vi->stats, cpu);
+		struct virtnet_stats *stats = per_cpu_ptr(vi->stats, cpu);
 		u64 tpackets, tbytes, rpackets, rbytes;
 
 		do {
@@ -1061,7 +1060,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 	if (virtio_config_val_len(vdev, VIRTIO_NET_F_MAC,
 				  offsetof(struct virtio_net_config, mac),
 				  dev->dev_addr, dev->addr_len) < 0)
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 	/* Set up our device-specific information */
 	vi = netdev_priv(dev);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index de7fc34..adf527e 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -537,11 +537,8 @@ vmxnet3_tq_create(struct vmxnet3_tx_queue *tq,
 
 	tq->buf_info = kcalloc(tq->tx_ring.size, sizeof(tq->buf_info[0]),
 			       GFP_KERNEL);
-	if (!tq->buf_info) {
-		printk(KERN_ERR "%s: failed to allocate tx bufinfo\n",
-		       adapter->netdev->name);
+	if (!tq->buf_info)
 		goto err;
-	}
 
 	return 0;
 
@@ -636,7 +633,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
 
 	dev_dbg(&adapter->netdev->dev,
 		"alloc_rx_buf: %d allocated, next2fill %u, next2comp "
-		"%u, uncommited %u\n", num_allocated, ring->next2fill,
+		"%u, uncommitted %u\n", num_allocated, ring->next2fill,
 		ring->next2comp, rq->uncommitted[ring_idx]);
 
 	/* so that the device can distinguish a full ring and an empty ring */
@@ -816,35 +813,32 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
 
 	if (ctx->mss) {	/* TSO */
 		ctx->eth_ip_hdr_size = skb_transport_offset(skb);
-		ctx->l4_hdr_size = ((struct tcphdr *)
-				   skb_transport_header(skb))->doff * 4;
+		ctx->l4_hdr_size = tcp_hdrlen(skb);
 		ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size;
 	} else {
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
 			ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb);
 
 			if (ctx->ipv4) {
-				struct iphdr *iph = (struct iphdr *)
-						    skb_network_header(skb);
+				const struct iphdr *iph = ip_hdr(skb);
+
 				if (iph->protocol == IPPROTO_TCP)
-					ctx->l4_hdr_size = ((struct tcphdr *)
-					   skb_transport_header(skb))->doff * 4;
+					ctx->l4_hdr_size = tcp_hdrlen(skb);
 				else if (iph->protocol == IPPROTO_UDP)
 					/*
 					 * Use tcp header size so that bytes to
 					 * be copied are more than required by
 					 * the device.
 					 */
-					ctx->l4_hdr_size =
-							sizeof(struct tcphdr);
+					ctx->l4_hdr_size = sizeof(struct tcphdr);
 				else
 					ctx->l4_hdr_size = 0;
 			} else {
 				/* for simplicity, don't copy L4 headers */
 				ctx->l4_hdr_size = 0;
 			}
-			ctx->copy_size = ctx->eth_ip_hdr_size +
-					 ctx->l4_hdr_size;
+			ctx->copy_size = min(ctx->eth_ip_hdr_size +
+					 ctx->l4_hdr_size, skb->len);
 		} else {
 			ctx->eth_ip_hdr_size = 0;
 			ctx->l4_hdr_size = 0;
@@ -881,14 +875,17 @@ static void
 vmxnet3_prepare_tso(struct sk_buff *skb,
 		    struct vmxnet3_tx_ctx *ctx)
 {
-	struct tcphdr *tcph = (struct tcphdr *)skb_transport_header(skb);
+	struct tcphdr *tcph = tcp_hdr(skb);
+
 	if (ctx->ipv4) {
-		struct iphdr *iph = (struct iphdr *)skb_network_header(skb);
+		struct iphdr *iph = ip_hdr(skb);
+
 		iph->check = 0;
 		tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
 						 IPPROTO_TCP, 0);
 	} else {
-		struct ipv6hdr *iph = (struct ipv6hdr *)skb_network_header(skb);
+		struct ipv6hdr *iph = ipv6_hdr(skb);
+
 		tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
 					       IPPROTO_TCP, 0);
 	}
@@ -1519,11 +1516,9 @@ vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter)
 	sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size +
 						   rq->rx_ring[1].size);
 	bi = kzalloc(sz, GFP_KERNEL);
-	if (!bi) {
-		printk(KERN_ERR "%s: failed to allocate rx bufinfo\n",
-		       adapter->netdev->name);
+	if (!bi)
 		goto err;
-	}
+
 	rq->buf_info[0] = bi;
 	rq->buf_info[1] = bi + rq->rx_ring[0].size;
 
@@ -2923,11 +2918,8 @@ vmxnet3_probe_device(struct pci_dev *pdev,
 	printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n",
 	       num_tx_queues, num_rx_queues);
 
-	if (!netdev) {
-		printk(KERN_ERR "Failed to alloc ethernet device for adapter "
-			"%s\n",	pci_name(pdev));
+	if (!netdev)
 		return -ENOMEM;
-	}
 
 	pci_set_drvdata(pdev, netdev);
 	adapter = netdev_priv(netdev);
@@ -2964,8 +2956,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
 
 	adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL);
 	if (adapter->pm_conf == NULL) {
-		printk(KERN_ERR "Failed to allocate memory for %s\n",
-			pci_name(pdev));
 		err = -ENOMEM;
 		goto err_alloc_pm;
 	}
@@ -2974,8 +2964,6 @@ vmxnet3_probe_device(struct pci_dev *pdev,
 
 	adapter->rss_conf = kmalloc(sizeof(struct UPT1_RSSConf), GFP_KERNEL);
 	if (adapter->rss_conf == NULL) {
-		printk(KERN_ERR "Failed to allocate memory for %s\n",
-		       pci_name(pdev));
 		err = -ENOMEM;
 		goto err_alloc_rss;
 	}
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 54f995f..09a5075 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -325,10 +325,8 @@ static int __init c101_run(unsigned long irq, unsigned long winbase)
 	}
 
 	card = kzalloc(sizeof(card_t), GFP_KERNEL);
-	if (card == NULL) {
-		pr_err("unable to allocate memory\n");
+	if (card == NULL)
 		return -ENOBUFS;
-	}
 
 	card->dev = alloc_hdlcdev(card);
 	if (!card->dev) {
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 058e169..fe8d060 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -903,10 +903,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
 	int i, ret = -ENOMEM;
 
 	root = kcalloc(dev_per_card, sizeof(*root), GFP_KERNEL);
-	if (!root) {
-		pr_err("can't allocate data\n");
+	if (!root)
 		goto err_out;
-	}
 
 	for (i = 0; i < dev_per_card; i++) {
 		root[i].dev = alloc_hdlcdev(root + i);
@@ -915,10 +913,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
 	}
 
 	ppriv = kzalloc(sizeof(*ppriv), GFP_KERNEL);
-	if (!ppriv) {
-		pr_err("can't allocate private data\n");
+	if (!ppriv)
 		goto err_free_dev;
-	}
 
 	ppriv->root = root;
 	spin_lock_init(&ppriv->lock);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index eb20281..7c6cb4f3 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1087,7 +1087,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 	}
 
 	if (type == ARPHRD_ETHER)
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 	else {
 		*(__be16*)dev->dev_addr = htons(dlci);
 		dlci_to_q922(dev->broadcast, dlci);
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 05c9b0b..3ab72b3 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -101,7 +101,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
 		old_qlen = dev->tx_queue_len;
 		ether_setup(dev);
 		dev->tx_queue_len = old_qlen;
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 		netif_dormant_off(dev);
 		return 0;
 	}
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index b7f2358..76a8a4a 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -497,7 +497,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 
                     data = kmalloc(xc.len, GFP_KERNEL);
                     if (!data) {
-                            printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name);
                             ret = -ENOMEM;
                             break;
                     }
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 5129ad5..315bf09 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -358,10 +358,8 @@ static int __init n2_run(unsigned long io, unsigned long irq,
 	}
 
 	card = kzalloc(sizeof(card_t), GFP_KERNEL);
-	if (card == NULL) {
-		pr_err("unable to allocate memory\n");
+	if (card == NULL)
 		return -ENOBUFS;
-	}
 
 	card->ports[0].dev = alloc_hdlcdev(&card->ports[0]);
 	card->ports[1].dev = alloc_hdlcdev(&card->ports[1]);
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index c49c1b3..5fe246e 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -320,7 +320,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 
 	card = kzalloc(sizeof(card_t), GFP_KERNEL);
 	if (card == NULL) {
-		pr_err("unable to allocate memory\n");
 		pci_release_regions(pdev);
 		pci_disable_device(pdev);
 		return -ENOBUFS;
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index 1ce2116..9659fca 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -299,7 +299,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 
 	card = kzalloc(sizeof(card_t), GFP_KERNEL);
 	if (card == NULL) {
-		pr_err("unable to allocate memory\n");
 		pci_release_regions(pdev);
 		pci_disable_device(pdev);
 		return -ENOBUFS;
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 44b7071..feb7541 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -604,7 +604,6 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
 	alloc_size = sizeof(card_t) + ports * sizeof(port_t);
 	card = kzalloc(alloc_size, GFP_KERNEL);
 	if (card == NULL) {
-		pr_err("%s: unable to allocate memory\n", pci_name(pdev));
 		pci_release_regions(pdev);
 		pci_disable_device(pdev);
 		return -ENOBUFS;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 8a10bb7..e862369 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -786,10 +786,8 @@ static int __init init_x25_asy(void)
 
 	x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *),
 				GFP_KERNEL);
-	if (!x25_asy_devs) {
-		pr_warn("Can't allocate x25_asy_ctrls[] array! Uaargh! (-> No X.25 available)\n");
+	if (!x25_asy_devs)
 		return -ENOMEM;
-	}
 
 	return tty_register_ldisc(N_X25, &x25_ldisc);
 }
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c
index bf67416..35e9370 100644
--- a/drivers/net/wireless/ath/ath5k/ani.c
+++ b/drivers/net/wireless/ath/ath5k/ani.c
@@ -257,7 +257,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
 				  "beacon RSSI high");
 		/* only OFDM: beacon RSSI is high, we can disable ODFM weak
 		 * signal detection */
-		if (ofdm_trigger && as->ofdm_weak_sig == true) {
+		if (ofdm_trigger && as->ofdm_weak_sig) {
 			ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
 			ath5k_ani_set_spur_immunity_level(ah, 0);
 			return;
@@ -272,7 +272,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
 		 * but can raise firstep level */
 		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
 				  "beacon RSSI mid");
-		if (ofdm_trigger && as->ofdm_weak_sig == false)
+		if (ofdm_trigger && !as->ofdm_weak_sig)
 			ath5k_ani_set_ofdm_weak_signal_detection(ah, true);
 		if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL)
 			ath5k_ani_set_firstep_level(ah, as->firstep_level + 1);
@@ -282,7 +282,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as,
 		 * detect and zero firstep level to maximize CCK sensitivity */
 		ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI,
 				  "beacon RSSI low, 2GHz");
-		if (ofdm_trigger && as->ofdm_weak_sig == true)
+		if (ofdm_trigger && as->ofdm_weak_sig)
 			ath5k_ani_set_ofdm_weak_signal_detection(ah, false);
 		if (as->firstep_level > 0)
 			ath5k_ani_set_firstep_level(ah, 0);
@@ -326,7 +326,7 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
 		} else if (rssi > ATH5K_ANI_RSSI_THR_LOW) {
 			/* beacon RSSI is mid-range: turn on ODFM weak signal
 			 * detection and next, lower firstep level */
-			if (as->ofdm_weak_sig == false) {
+			if (!as->ofdm_weak_sig) {
 				ath5k_ani_set_ofdm_weak_signal_detection(ah,
 									 true);
 				return;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index d366dad..a339693 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -80,7 +80,7 @@ static bool modparam_fastchanswitch;
 module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
 MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
 
-static int ath5k_modparam_no_hw_rfkill_switch;
+static bool ath5k_modparam_no_hw_rfkill_switch;
 module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch,
 								bool, S_IRUGO);
 MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state");
@@ -2442,6 +2442,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
 		BIT(NL80211_IFTYPE_ADHOC) |
 		BIT(NL80211_IFTYPE_MESH_POINT);
 
+	/* SW support for IBSS_RSN is provided by mac80211 */
+	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
 	/* both antennas can be configured as RX or TX */
 	hw->wiphy->available_antennas_tx = 0x3;
 	hw->wiphy->available_antennas_rx = 0x3;
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 6ed4c07..af4c7ec 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -483,6 +483,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	if (ath5k_modparam_nohwcrypt)
 		return -EOPNOTSUPP;
 
+	if (vif->type == NL80211_IFTYPE_ADHOC &&
+	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
+	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
+	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+		/* don't program group keys when using IBSS_RSN */
+		return -EOPNOTSUPP;
+	}
+
 	switch (key->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 	case WLAN_CIPHER_SUITE_WEP104:
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
index 3d5f8be..d755a5e 100644
--- a/drivers/net/wireless/ath/ath6kl/Kconfig
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -1,12 +1,29 @@
 config ATH6KL
-	tristate "Atheros ath6kl support"
+	tristate "Atheros mobile chipsets support"
+
+config ATH6KL_SDIO
+	tristate "Atheros ath6kl SDIO support"
+	depends on ATH6KL
 	depends on MMC
 	depends on CFG80211
 	---help---
 	  This module adds support for wireless adapters based on
-	  Atheros AR6003 chipset running over SDIO. If you choose to
-	  build it as a module, it will be called ath6kl. Pls note
-	  that AR6002 and AR6001 are not supported by this driver.
+	  Atheros AR6003 and AR6004 chipsets running over SDIO. If you
+	  choose to build it as a module, it will be called ath6kl_sdio.
+	  Please note that AR6002 and AR6001 are not supported by this
+	  driver.
+
+config ATH6KL_USB
+	tristate "Atheros ath6kl USB support"
+	depends on ATH6KL
+	depends on USB
+	depends on CFG80211
+	depends on EXPERIMENTAL
+	---help---
+	  This module adds support for wireless adapters based on
+	  Atheros AR6004 chipset running over USB. This is still under
+	  implementation and it isn't functional. If you choose to
+	  build it as a module, it will be called ath6kl_usb.
 
 config ATH6KL_DEBUG
 	bool "Atheros ath6kl debugging"
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index 7070693..9ba42fa 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -21,17 +21,21 @@
 # Author(s): ="Atheros"
 #------------------------------------------------------------------------------
 
-obj-$(CONFIG_ATH6KL) := ath6kl.o
-ath6kl-y += debug.o
-ath6kl-y += hif.o
-ath6kl-y += htc.o
-ath6kl-y += bmi.o
-ath6kl-y += cfg80211.o
-ath6kl-y += init.o
-ath6kl-y += main.o
-ath6kl-y += txrx.o
-ath6kl-y += wmi.o
-ath6kl-y += sdio.o
-ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
+obj-$(CONFIG_ATH6KL) += ath6kl_core.o
+ath6kl_core-y += debug.o
+ath6kl_core-y += hif.o
+ath6kl_core-y += htc.o
+ath6kl_core-y += bmi.o
+ath6kl_core-y += cfg80211.o
+ath6kl_core-y += init.o
+ath6kl_core-y += main.o
+ath6kl_core-y += txrx.o
+ath6kl_core-y += wmi.o
+ath6kl_core-y += core.o
+ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
 
-ccflags-y += -D__CHECK_ENDIAN__
+obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
+ath6kl_sdio-y += sdio.o
+
+obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
+ath6kl_usb-y += usb.o
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
index bce3575..aef00d5 100644
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -57,8 +57,14 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar,
 		return ret;
 	}
 
-	ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
-				  sizeof(targ_info->version));
+	if (ar->hif_type == ATH6KL_HIF_TYPE_USB) {
+		ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info,
+					  sizeof(*targ_info));
+	} else {
+		ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
+				sizeof(targ_info->version));
+	}
+
 	if (ret) {
 		ath6kl_err("Unable to recv target info: %d\n", ret);
 		return ret;
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 6c59a21..d1922d8 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -15,6 +15,8 @@
  */
 
 #include <linux/moduleparam.h>
+#include <linux/inetdevice.h>
+#include <linux/export.h>
 
 #include "core.h"
 #include "cfg80211.h"
@@ -22,10 +24,6 @@
 #include "hif-ops.h"
 #include "testmode.h"
 
-static unsigned int ath6kl_p2p;
-
-module_param(ath6kl_p2p, uint, 0644);
-
 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
 	.bitrate    = (_rate),                  \
 	.flags      = (_flags),                 \
@@ -196,7 +194,7 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
 		break;
 
 	default:
-		ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
+		ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
 		return -ENOTSUPP;
 	}
 
@@ -461,13 +459,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 		}
 	}
 
-	if (sme->ie && (sme->ie_len > 0)) {
-		status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
-		if (status) {
-			up(&ar->sem);
-			return status;
-		}
-	} else
+	status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
+	if (status) {
+		up(&ar->sem);
+		return status;
+	}
+
+	if (sme->ie == NULL || sme->ie_len == 0)
 		ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
 
 	if (test_bit(CONNECTED, &vif->flags) &&
@@ -523,8 +521,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	    (vif->prwise_crypto == WEP_CRYPT)) {
 		struct ath6kl_key *key = NULL;
 
-		if (sme->key_idx < WMI_MIN_KEY_INDEX ||
-		    sme->key_idx > WMI_MAX_KEY_INDEX) {
+		if (sme->key_idx > WMI_MAX_KEY_INDEX) {
 			ath6kl_err("key index %d out of bounds\n",
 				   sme->key_idx);
 			up(&ar->sem);
@@ -605,11 +602,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
-static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
-				    enum network_type nw_type,
-				    const u8 *bssid,
-				    struct ieee80211_channel *chan,
-				    const u8 *beacon_ie, size_t beacon_ie_len)
+static struct cfg80211_bss *
+ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
+			 enum network_type nw_type,
+			 const u8 *bssid,
+			 struct ieee80211_channel *chan,
+			 const u8 *beacon_ie,
+			 size_t beacon_ie_len)
 {
 	struct ath6kl *ar = vif->ar;
 	struct cfg80211_bss *bss;
@@ -638,7 +637,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
 		 */
 		ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
 		if (ie == NULL)
-			return -ENOMEM;
+			return NULL;
 		ie[0] = WLAN_EID_SSID;
 		ie[1] = vif->ssid_len;
 		memcpy(ie + 2, vif->ssid, vif->ssid_len);
@@ -652,15 +651,9 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
 				   "cfg80211\n", bssid);
 		kfree(ie);
 	} else
-		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
-			   "entry\n");
-
-	if (bss == NULL)
-		return -ENOMEM;
+		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
 
-	cfg80211_put_bss(bss);
-
-	return 0;
+	return bss;
 }
 
 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
@@ -672,6 +665,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 {
 	struct ieee80211_channel *chan;
 	struct ath6kl *ar = vif->ar;
+	struct cfg80211_bss *bss;
 
 	/* capinfo + listen interval */
 	u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -712,8 +706,9 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 
 	chan = ieee80211_get_channel(ar->wiphy, (int) channel);
 
-	if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info,
-				     beacon_ie_len) < 0) {
+	bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
+				       assoc_info, beacon_ie_len);
+	if (!bss) {
 		ath6kl_err("could not add cfg80211 bss entry\n");
 		return;
 	}
@@ -722,6 +717,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
 			   nw_type & ADHOC_CREATOR ? "creator" : "joiner");
 		cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
+		cfg80211_put_bss(bss);
 		return;
 	}
 
@@ -732,11 +728,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
 					assoc_req_ie, assoc_req_len,
 					assoc_resp_ie, assoc_resp_len,
 					WLAN_STATUS_SUCCESS, GFP_KERNEL);
+		cfg80211_put_bss(bss);
 	} else if (vif->sme_state == SME_CONNECTED) {
 		/* inform roam event to cfg80211 */
-		cfg80211_roamed(vif->ndev, chan, bssid,
-				assoc_req_ie, assoc_req_len,
-				assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
+		cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
+				    assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
 	}
 }
 
@@ -984,6 +980,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 	struct ath6kl *ar = ath6kl_priv(ndev);
 	struct ath6kl_vif *vif = netdev_priv(ndev);
 	struct ath6kl_key *key = NULL;
+	int seq_len;
 	u8 key_usage;
 	u8 key_type;
 
@@ -997,7 +994,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 					      params->key);
 	}
 
-	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+	if (key_index > WMI_MAX_KEY_INDEX) {
 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 			   "%s: key index %d out of bounds\n", __func__,
 			   key_index);
@@ -1012,23 +1009,21 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
 	else
 		key_usage = GROUP_USAGE;
 
-	if (params) {
-		int seq_len = params->seq_len;
-		if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
-		    seq_len > ATH6KL_KEY_SEQ_LEN) {
-			/* Only first half of the WPI PN is configured */
-			seq_len = ATH6KL_KEY_SEQ_LEN;
-		}
-		if (params->key_len > WLAN_MAX_KEY_LEN ||
-		    seq_len > sizeof(key->seq))
-			return -EINVAL;
-
-		key->key_len = params->key_len;
-		memcpy(key->key, params->key, key->key_len);
-		key->seq_len = seq_len;
-		memcpy(key->seq, params->seq, key->seq_len);
-		key->cipher = params->cipher;
+	seq_len = params->seq_len;
+	if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
+	    seq_len > ATH6KL_KEY_SEQ_LEN) {
+		/* Only first half of the WPI PN is configured */
+		seq_len = ATH6KL_KEY_SEQ_LEN;
 	}
+	if (params->key_len > WLAN_MAX_KEY_LEN ||
+	    seq_len > sizeof(key->seq))
+		return -EINVAL;
+
+	key->key_len = params->key_len;
+	memcpy(key->key, params->key, key->key_len);
+	key->seq_len = seq_len;
+	memcpy(key->seq, params->seq, key->seq_len);
+	key->cipher = params->cipher;
 
 	switch (key->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
@@ -1115,7 +1110,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
 	if (!ath6kl_cfg80211_ready(vif))
 		return -EIO;
 
-	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+	if (key_index > WMI_MAX_KEY_INDEX) {
 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 			   "%s: key index %d out of bounds\n", __func__,
 			   key_index);
@@ -1148,7 +1143,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
 	if (!ath6kl_cfg80211_ready(vif))
 		return -EIO;
 
-	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+	if (key_index > WMI_MAX_KEY_INDEX) {
 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 			   "%s: key index %d out of bounds\n", __func__,
 			   key_index);
@@ -1184,7 +1179,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
 	if (!ath6kl_cfg80211_ready(vif))
 		return -EIO;
 
-	if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+	if (key_index > WMI_MAX_KEY_INDEX) {
 		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
 			   "%s: key index %d out of bounds\n",
 			   __func__, key_index);
@@ -1403,7 +1398,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
 
 	ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
 
-	ath6kl_deinit_if_data(vif);
+	ath6kl_cfg80211_vif_cleanup(vif);
 
 	return 0;
 }
@@ -1728,29 +1723,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
 	return 0;
 }
 
-static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
+			  struct cfg80211_wowlan *wow, u32 *filter)
 {
-	struct ath6kl_vif *vif;
-	int ret, pos, left;
-	u32 filter = 0;
-	u16 i;
+	int ret, pos;
 	u8 mask[WOW_MASK_SIZE];
+	u16 i;
 
-	vif = ath6kl_vif_first(ar);
-	if (!vif)
-		return -EIO;
-
-	if (!ath6kl_cfg80211_ready(vif))
-		return -EIO;
-
-	if (!test_bit(CONNECTED, &vif->flags))
-		return -EINVAL;
-
-	/* Clear existing WOW patterns */
-	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
-		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
-					       WOW_LIST_ID, i);
-	/* Configure new WOW patterns */
+	/* Configure the patterns that we received from the user. */
 	for (i = 0; i < wow->n_patterns; i++) {
 
 		/*
@@ -1773,29 +1753,221 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 		 * matched from the first byte of received pkt in the firmware.
 		 */
 		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
-					vif->fw_vif_idx, WOW_LIST_ID,
-					wow->patterns[i].pattern_len,
-					0 /* pattern offset */,
-					wow->patterns[i].pattern, mask);
+				vif->fw_vif_idx, WOW_LIST_ID,
+				wow->patterns[i].pattern_len,
+				0 /* pattern offset */,
+				wow->patterns[i].pattern, mask);
 		if (ret)
 			return ret;
 	}
 
 	if (wow->disconnect)
-		filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
+		*filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
 
 	if (wow->magic_pkt)
-		filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
+		*filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
 
 	if (wow->gtk_rekey_failure)
-		filter |= WOW_FILTER_OPTION_GTK_ERROR;
+		*filter |= WOW_FILTER_OPTION_GTK_ERROR;
 
 	if (wow->eap_identity_req)
-		filter |= WOW_FILTER_OPTION_EAP_REQ;
+		*filter |= WOW_FILTER_OPTION_EAP_REQ;
 
 	if (wow->four_way_handshake)
-		filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
+		*filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
+
+	return 0;
+}
+
+static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
+{
+	static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x08 };
+	static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x7f };
+	u8 unicst_offset = 0;
+	static const u8 arp_pattern[] = { 0x08, 0x06 };
+	static const u8 arp_mask[] = { 0xff, 0xff };
+	u8 arp_offset = 20;
+	static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
+	static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
+	u8 discvr_offset = 38;
+	static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
+	static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
+	u8 dhcp_offset = 0;
+	int ret;
+
+	/* Setup unicast IP, EAPOL-like and ARP pkt pattern */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(unicst_pattern), unicst_offset,
+			unicst_pattern, unicst_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW unicast IP pattern\n");
+		return ret;
+	}
+
+	/* Setup all ARP pkt pattern */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(arp_pattern), arp_offset,
+			arp_pattern, arp_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW ARP pattern\n");
+		return ret;
+	}
 
+	/*
+	 * Setup multicast pattern for mDNS 224.0.0.251,
+	 * SSDP 239.255.255.250 and LLMNR  224.0.0.252
+	 */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(discvr_pattern), discvr_offset,
+			discvr_pattern, discvr_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
+		return ret;
+	}
+
+	/* Setup all DHCP broadcast pkt pattern */
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+			vif->fw_vif_idx, WOW_LIST_ID,
+			sizeof(dhcp_pattern), dhcp_offset,
+			dhcp_pattern, dhcp_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
+{
+	struct net_device *ndev = vif->ndev;
+	static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
+	static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
+	u8 discvr_offset = 38;
+	u8 mac_mask[ETH_ALEN];
+	int ret;
+
+	/* Setup unicast pkt pattern */
+	memset(mac_mask, 0xff, ETH_ALEN);
+	ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+				vif->fw_vif_idx, WOW_LIST_ID,
+				ETH_ALEN, 0, ndev->dev_addr,
+				mac_mask);
+	if (ret) {
+		ath6kl_err("failed to add WOW unicast pattern\n");
+		return ret;
+	}
+
+	/*
+	 * Setup multicast pattern for mDNS 224.0.0.251,
+	 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
+	 */
+	if ((ndev->flags & IFF_ALLMULTI) ||
+	    (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
+		ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
+				vif->fw_vif_idx, WOW_LIST_ID,
+				sizeof(discvr_pattern), discvr_offset,
+				discvr_pattern, discvr_mask);
+		if (ret) {
+			ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
+				   "pattern\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+	struct in_device *in_dev;
+	struct in_ifaddr *ifa;
+	struct ath6kl_vif *vif;
+	int ret, left;
+	u32 filter = 0;
+	u16 i;
+	u8 index = 0;
+	__be32 ips[MAX_IP_ADDRS];
+
+	vif = ath6kl_vif_first(ar);
+	if (!vif)
+		return -EIO;
+
+	if (!ath6kl_cfg80211_ready(vif))
+		return -EIO;
+
+	if (!test_bit(CONNECTED, &vif->flags))
+		return -ENOTCONN;
+
+	if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
+		return -EINVAL;
+
+	/* Clear existing WOW patterns */
+	for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
+		ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
+					       WOW_LIST_ID, i);
+
+	/*
+	 * Skip the default WOW pattern configuration
+	 * if the driver receives any WOW patterns from
+	 * the user.
+	 */
+	if (wow)
+		ret = ath6kl_wow_usr(ar, vif, wow, &filter);
+	else if (vif->nw_type == AP_NETWORK)
+		ret = ath6kl_wow_ap(ar, vif);
+	else
+		ret = ath6kl_wow_sta(ar, vif);
+
+	if (ret)
+		return ret;
+
+	/* Setup own IP addr for ARP agent. */
+	in_dev = __in_dev_get_rtnl(vif->ndev);
+	if (!in_dev)
+		goto skip_arp;
+
+	ifa = in_dev->ifa_list;
+	memset(&ips, 0, sizeof(ips));
+
+	/* Configure IP addr only if IP address count < MAX_IP_ADDRS */
+	while (index < MAX_IP_ADDRS && ifa) {
+		ips[index] = ifa->ifa_local;
+		ifa = ifa->ifa_next;
+		index++;
+	}
+
+	if (ifa) {
+		ath6kl_err("total IP addr count is exceeding fw limit\n");
+		return -EINVAL;
+	}
+
+	ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
+	if (ret) {
+		ath6kl_err("fail to setup ip for arp agent\n");
+		return ret;
+	}
+
+skip_arp:
 	ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
 					  ATH6KL_WOW_MODE_ENABLE,
 					  filter,
@@ -1803,11 +1975,26 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 	if (ret)
 		return ret;
 
+	clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
+
 	ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
 						 ATH6KL_HOST_MODE_ASLEEP);
 	if (ret)
 		return ret;
 
+	left = wait_event_interruptible_timeout(ar->event_wq,
+			test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
+			WMI_TIMEOUT);
+	if (left == 0) {
+		ath6kl_warn("timeout, didn't get host sleep cmd "
+			    "processed event\n");
+		ret = -ETIMEDOUT;
+	} else if (left < 0) {
+		ath6kl_warn("error while waiting for host sleep cmd "
+			    "processed event %d\n", left);
+		ret = left;
+	}
+
 	if (ar->tx_pending[ar->ctrl_ep]) {
 		left = wait_event_interruptible_timeout(ar->event_wq,
 				ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
@@ -1911,6 +2098,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
 
 	return 0;
 }
+EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
 
 int ath6kl_cfg80211_resume(struct ath6kl *ar)
 {
@@ -1962,6 +2150,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar)
 
 	return 0;
 }
+EXPORT_SYMBOL(ath6kl_cfg80211_resume);
 
 #ifdef CONFIG_PM
 
@@ -2014,7 +2203,18 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
 			      struct ieee80211_channel *chan,
 			      enum nl80211_channel_type channel_type)
 {
-	struct ath6kl_vif *vif = netdev_priv(dev);
+	struct ath6kl_vif *vif;
+
+	/*
+	 * 'dev' could be NULL if a channel change is required for the hardware
+	 * device itself, instead of a particular VIF.
+	 *
+	 * FIXME: To be handled properly when monitor mode is supported.
+	 */
+	if (!dev)
+		return -EBUSY;
+
+	vif = netdev_priv(dev);
 
 	if (!ath6kl_cfg80211_ready(vif))
 		return -EIO;
@@ -2214,6 +2414,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
 	p.dot11_auth_mode = vif->dot11_auth_mode;
 	p.ch = cpu_to_le16(vif->next_chan);
 
+	/* Enable uAPSD support by default */
+	res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
+	if (res < 0)
+		return res;
+
 	if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
 		p.nw_subtype = SUBTYPE_P2PGO;
 	} else {
@@ -2259,6 +2464,19 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
 	return 0;
 }
 
+static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
+			      u8 *mac)
+{
+	struct ath6kl *ar = ath6kl_priv(dev);
+	struct ath6kl_vif *vif = netdev_priv(dev);
+	const u8 *addr = mac ? mac : bcast_addr;
+
+	return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
+				      addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+}
+
 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
 				 u8 *mac, struct station_parameters *params)
 {
@@ -2518,6 +2736,12 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
 	},
+	[NL80211_IFTYPE_AP] = {
+		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
+		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+		BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+	},
 	[NL80211_IFTYPE_P2P_CLIENT] = {
 		.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
 		BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
@@ -2562,6 +2786,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
 	.add_beacon = ath6kl_add_beacon,
 	.set_beacon = ath6kl_set_beacon,
 	.del_beacon = ath6kl_del_beacon,
+	.del_station = ath6kl_del_station,
 	.change_station = ath6kl_change_station,
 	.remain_on_channel = ath6kl_remain_on_channel,
 	.cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
@@ -2629,122 +2854,9 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
 		ath6kl_cfg80211_stop(vif);
 }
 
-struct ath6kl *ath6kl_core_alloc(struct device *dev)
-{
-	struct ath6kl *ar;
-	struct wiphy *wiphy;
-	u8 ctr;
-
-	/* create a new wiphy for use with cfg80211 */
-	wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
-
-	if (!wiphy) {
-		ath6kl_err("couldn't allocate wiphy device\n");
-		return NULL;
-	}
-
-	ar = wiphy_priv(wiphy);
-	ar->p2p = !!ath6kl_p2p;
-	ar->wiphy = wiphy;
-	ar->dev = dev;
-
-	ar->vif_max = 1;
-
-	ar->max_norm_iface = 1;
-
-	spin_lock_init(&ar->lock);
-	spin_lock_init(&ar->mcastpsq_lock);
-	spin_lock_init(&ar->list_lock);
-
-	init_waitqueue_head(&ar->event_wq);
-	sema_init(&ar->sem, 1);
-
-	INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
-	INIT_LIST_HEAD(&ar->vif_list);
-
-	clear_bit(WMI_ENABLED, &ar->flag);
-	clear_bit(SKIP_SCAN, &ar->flag);
-	clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
-
-	ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
-	ar->listen_intvl_b = 0;
-	ar->tx_pwr = 0;
-
-	ar->intra_bss = 1;
-	ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
-
-	ar->state = ATH6KL_STATE_OFF;
-
-	memset((u8 *)ar->sta_list, 0,
-	       AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
-
-	/* Init the PS queues */
-	for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
-		spin_lock_init(&ar->sta_list[ctr].psq_lock);
-		skb_queue_head_init(&ar->sta_list[ctr].psq);
-	}
-
-	skb_queue_head_init(&ar->mcastpsq);
-
-	memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
-
-	return ar;
-}
-
-int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
-{
-	struct wiphy *wiphy = ar->wiphy;
-	int ret;
-
-	wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
-
-	wiphy->max_remain_on_channel_duration = 5000;
-
-	/* set device pointer for wiphy */
-	set_wiphy_dev(wiphy, ar->dev);
-
-	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-				 BIT(NL80211_IFTYPE_ADHOC) |
-				 BIT(NL80211_IFTYPE_AP);
-	if (ar->p2p) {
-		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
-					  BIT(NL80211_IFTYPE_P2P_CLIENT);
-	}
-
-	/* max num of ssids that can be probed during scanning */
-	wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
-	wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
-	wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
-	wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
-	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
-	wiphy->cipher_suites = cipher_suites;
-	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-
-	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
-			      WIPHY_WOWLAN_DISCONNECT |
-			      WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
-			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
-			      WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
-			      WIPHY_WOWLAN_4WAY_HANDSHAKE;
-	wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
-	wiphy->wowlan.pattern_min_len = 1;
-	wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
-
-	wiphy->max_sched_scan_ssids = 10;
-
-	ret = wiphy_register(wiphy);
-	if (ret < 0) {
-		ath6kl_err("couldn't register wiphy device\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int ath6kl_init_if_data(struct ath6kl_vif *vif)
+static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
 {
-	vif->aggr_cntxt = aggr_init(vif->ndev);
+	vif->aggr_cntxt = aggr_init(vif);
 	if (!vif->aggr_cntxt) {
 		ath6kl_err("failed to initialize aggr\n");
 		return -ENOMEM;
@@ -2758,12 +2870,15 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif)
 	set_bit(WMM_ENABLED, &vif->flags);
 	spin_lock_init(&vif->if_lock);
 
+	INIT_LIST_HEAD(&vif->mc_filter);
+
 	return 0;
 }
 
-void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
+void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
 {
 	struct ath6kl *ar = vif->ar;
+	struct ath6kl_mc_filter *mc_filter, *tmp;
 
 	aggr_module_destroy(vif->aggr_cntxt);
 
@@ -2772,6 +2887,11 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
 	if (vif->nw_type == ADHOC_NETWORK)
 		ar->ibss_if_active = false;
 
+	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
+		list_del(&mc_filter->list);
+		kfree(mc_filter);
+	}
+
 	unregister_netdevice(vif->ndev);
 
 	ar->num_vif--;
@@ -2808,8 +2928,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
 
 	ath6kl_init_control_info(vif);
 
-	/* TODO: Pass interface specific pointer instead of ar */
-	if (ath6kl_init_if_data(vif))
+	if (ath6kl_cfg80211_vif_init(vif))
 		goto err;
 
 	if (register_netdevice(ndev))
@@ -2836,8 +2955,89 @@ err:
 	return NULL;
 }
 
-void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
+int ath6kl_cfg80211_init(struct ath6kl *ar)
+{
+	struct wiphy *wiphy = ar->wiphy;
+	int ret;
+
+	wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
+
+	wiphy->max_remain_on_channel_duration = 5000;
+
+	/* set device pointer for wiphy */
+	set_wiphy_dev(wiphy, ar->dev);
+
+	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+				 BIT(NL80211_IFTYPE_ADHOC) |
+				 BIT(NL80211_IFTYPE_AP);
+	if (ar->p2p) {
+		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
+					  BIT(NL80211_IFTYPE_P2P_CLIENT);
+	}
+
+	/* max num of ssids that can be probed during scanning */
+	wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+	wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
+	wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
+	wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+	wiphy->cipher_suites = cipher_suites;
+	wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+	wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
+			      WIPHY_WOWLAN_DISCONNECT |
+			      WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
+			      WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
+			      WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
+			      WIPHY_WOWLAN_4WAY_HANDSHAKE;
+	wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
+	wiphy->wowlan.pattern_min_len = 1;
+	wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
+
+	wiphy->max_sched_scan_ssids = 10;
+
+	ret = wiphy_register(wiphy);
+	if (ret < 0) {
+		ath6kl_err("couldn't register wiphy device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
 {
 	wiphy_unregister(ar->wiphy);
+}
+
+struct ath6kl *ath6kl_cfg80211_create(void)
+{
+	struct ath6kl *ar;
+	struct wiphy *wiphy;
+
+	/* create a new wiphy for use with cfg80211 */
+	wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
+
+	if (!wiphy) {
+		ath6kl_err("couldn't allocate wiphy device\n");
+		return NULL;
+	}
+
+	ar = wiphy_priv(wiphy);
+	ar->wiphy = wiphy;
+
+	return ar;
+}
+
+/* Note: ar variable must not be accessed after calling this! */
+void ath6kl_cfg80211_destroy(struct ath6kl *ar)
+{
+	int i;
+
+	for (i = 0; i < AP_MAX_NUM_STA; i++)
+		kfree(ar->sta_list[i].aggr_conn);
+
 	wiphy_free(ar->wiphy);
 }
+
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
index 81f20a5..3c693b7 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -27,10 +27,6 @@ enum ath6kl_cfg_suspend_mode {
 struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
 					enum nl80211_iftype type,
 					u8 fw_vif_idx, u8 nw_type);
-int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
-struct ath6kl *ath6kl_core_alloc(struct device *dev);
-void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);
-
 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
 
 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
@@ -53,7 +49,15 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar,
 
 int ath6kl_cfg80211_resume(struct ath6kl *ar);
 
+void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif);
+
 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif);
 void ath6kl_cfg80211_stop_all(struct ath6kl *ar);
 
+int ath6kl_cfg80211_init(struct ath6kl *ar);
+void ath6kl_cfg80211_cleanup(struct ath6kl *ar);
+
+struct ath6kl *ath6kl_cfg80211_create(void);
+void ath6kl_cfg80211_destroy(struct ath6kl *ar);
+
 #endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index bfd6597..f89f1e1 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -79,8 +79,5 @@ struct ath6kl;
 enum htc_credit_dist_reason;
 struct ath6kl_htc_credit_info;
 
-struct ath6kl *ath6kl_core_alloc(struct device *sdev);
-int ath6kl_core_init(struct ath6kl *ar);
-void ath6kl_core_cleanup(struct ath6kl *ar);
 struct sk_buff *ath6kl_buf_alloc(int size);
 #endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c
new file mode 100644
index 0000000..722ca59
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/core.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/export.h>
+
+#include "debug.h"
+#include "hif-ops.h"
+#include "cfg80211.h"
+
+unsigned int debug_mask;
+static unsigned int suspend_mode;
+static unsigned int uart_debug;
+static unsigned int ath6kl_p2p;
+static unsigned int testmode;
+
+module_param(debug_mask, uint, 0644);
+module_param(suspend_mode, uint, 0644);
+module_param(uart_debug, uint, 0644);
+module_param(ath6kl_p2p, uint, 0644);
+module_param(testmode, uint, 0644);
+
+int ath6kl_core_init(struct ath6kl *ar)
+{
+	struct ath6kl_bmi_target_info targ_info;
+	struct net_device *ndev;
+	int ret = 0, i;
+
+	ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
+	if (!ar->ath6kl_wq)
+		return -ENOMEM;
+
+	ret = ath6kl_bmi_init(ar);
+	if (ret)
+		goto err_wq;
+
+	/*
+	 * Turn on power to get hardware (target) version and leave power
+	 * on delibrately as we will boot the hardware anyway within few
+	 * seconds.
+	 */
+	ret = ath6kl_hif_power_on(ar);
+	if (ret)
+		goto err_bmi_cleanup;
+
+	ret = ath6kl_bmi_get_target_info(ar, &targ_info);
+	if (ret)
+		goto err_power_off;
+
+	ar->version.target_ver = le32_to_cpu(targ_info.version);
+	ar->target_type = le32_to_cpu(targ_info.type);
+	ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
+
+	ret = ath6kl_init_hw_params(ar);
+	if (ret)
+		goto err_power_off;
+
+	ar->htc_target = ath6kl_htc_create(ar);
+
+	if (!ar->htc_target) {
+		ret = -ENOMEM;
+		goto err_power_off;
+	}
+
+	ar->testmode = testmode;
+
+	ret = ath6kl_init_fetch_firmwares(ar);
+	if (ret)
+		goto err_htc_cleanup;
+
+	/* FIXME: we should free all firmwares in the error cases below */
+
+	/* Indicate that WMI is enabled (although not ready yet) */
+	set_bit(WMI_ENABLED, &ar->flag);
+	ar->wmi = ath6kl_wmi_init(ar);
+	if (!ar->wmi) {
+		ath6kl_err("failed to initialize wmi\n");
+		ret = -EIO;
+		goto err_htc_cleanup;
+	}
+
+	ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
+
+	ret = ath6kl_cfg80211_init(ar);
+	if (ret)
+		goto err_node_cleanup;
+
+	ret = ath6kl_debug_init(ar);
+	if (ret) {
+		wiphy_unregister(ar->wiphy);
+		goto err_node_cleanup;
+	}
+
+	for (i = 0; i < ar->vif_max; i++)
+		ar->avail_idx_map |= BIT(i);
+
+	rtnl_lock();
+
+	/* Add an initial station interface */
+	ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
+				    INFRA_NETWORK);
+
+	rtnl_unlock();
+
+	if (!ndev) {
+		ath6kl_err("Failed to instantiate a network device\n");
+		ret = -ENOMEM;
+		wiphy_unregister(ar->wiphy);
+		goto err_debug_init;
+	}
+
+
+	ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
+			__func__, ndev->name, ndev, ar);
+
+	/* setup access class priority mappings */
+	ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest  */
+	ar->ac_stream_pri_map[WMM_AC_BE] = 1;
+	ar->ac_stream_pri_map[WMM_AC_VI] = 2;
+	ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
+
+	/* give our connected endpoints some buffers */
+	ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
+	ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
+
+	/* allocate some buffers that handle larger AMSDU frames */
+	ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
+
+	ath6kl_cookie_init(ar);
+
+	ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
+			 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
+
+	if (suspend_mode &&
+		suspend_mode >= WLAN_POWER_STATE_CUT_PWR &&
+		suspend_mode <= WLAN_POWER_STATE_WOW)
+		ar->suspend_mode = suspend_mode;
+	else
+		ar->suspend_mode = 0;
+
+	if (uart_debug)
+		ar->conf_flags |= ATH6KL_CONF_UART_DEBUG;
+
+	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
+			    WIPHY_FLAG_HAVE_AP_SME |
+			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+			    WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
+
+	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
+		ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+
+	ar->wiphy->probe_resp_offload =
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
+		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
+
+	set_bit(FIRST_BOOT, &ar->flag);
+
+	ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+
+	ret = ath6kl_init_hw_start(ar);
+	if (ret) {
+		ath6kl_err("Failed to start hardware: %d\n", ret);
+		goto err_rxbuf_cleanup;
+	}
+
+	/*
+	 * Set mac address which is received in ready event
+	 * FIXME: Move to ath6kl_interface_add()
+	 */
+	memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
+
+	return ret;
+
+err_rxbuf_cleanup:
+	ath6kl_htc_flush_rx_buf(ar->htc_target);
+	ath6kl_cleanup_amsdu_rxbufs(ar);
+	rtnl_lock();
+	ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev));
+	rtnl_unlock();
+	wiphy_unregister(ar->wiphy);
+err_debug_init:
+	ath6kl_debug_cleanup(ar);
+err_node_cleanup:
+	ath6kl_wmi_shutdown(ar->wmi);
+	clear_bit(WMI_ENABLED, &ar->flag);
+	ar->wmi = NULL;
+err_htc_cleanup:
+	ath6kl_htc_cleanup(ar->htc_target);
+err_power_off:
+	ath6kl_hif_power_off(ar);
+err_bmi_cleanup:
+	ath6kl_bmi_cleanup(ar);
+err_wq:
+	destroy_workqueue(ar->ath6kl_wq);
+
+	return ret;
+}
+EXPORT_SYMBOL(ath6kl_core_init);
+
+struct ath6kl *ath6kl_core_create(struct device *dev)
+{
+	struct ath6kl *ar;
+	u8 ctr;
+
+	ar = ath6kl_cfg80211_create();
+	if (!ar)
+		return NULL;
+
+	ar->p2p = !!ath6kl_p2p;
+	ar->dev = dev;
+
+	ar->vif_max = 1;
+
+	ar->max_norm_iface = 1;
+
+	spin_lock_init(&ar->lock);
+	spin_lock_init(&ar->mcastpsq_lock);
+	spin_lock_init(&ar->list_lock);
+
+	init_waitqueue_head(&ar->event_wq);
+	sema_init(&ar->sem, 1);
+
+	INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
+	INIT_LIST_HEAD(&ar->vif_list);
+
+	clear_bit(WMI_ENABLED, &ar->flag);
+	clear_bit(SKIP_SCAN, &ar->flag);
+	clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+	ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL;
+	ar->tx_pwr = 0;
+
+	ar->intra_bss = 1;
+	ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
+
+	ar->state = ATH6KL_STATE_OFF;
+
+	memset((u8 *)ar->sta_list, 0,
+	       AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
+
+	/* Init the PS queues */
+	for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+		spin_lock_init(&ar->sta_list[ctr].psq_lock);
+		skb_queue_head_init(&ar->sta_list[ctr].psq);
+		skb_queue_head_init(&ar->sta_list[ctr].apsdq);
+		ar->sta_list[ctr].aggr_conn =
+			kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
+		if (!ar->sta_list[ctr].aggr_conn) {
+			ath6kl_err("Failed to allocate memory for sta aggregation information\n");
+			ath6kl_core_destroy(ar);
+			return NULL;
+		}
+	}
+
+	skb_queue_head_init(&ar->mcastpsq);
+
+	memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
+
+	return ar;
+}
+EXPORT_SYMBOL(ath6kl_core_create);
+
+void ath6kl_core_cleanup(struct ath6kl *ar)
+{
+	ath6kl_hif_power_off(ar);
+
+	destroy_workqueue(ar->ath6kl_wq);
+
+	if (ar->htc_target)
+		ath6kl_htc_cleanup(ar->htc_target);
+
+	ath6kl_cookie_cleanup(ar);
+
+	ath6kl_cleanup_amsdu_rxbufs(ar);
+
+	ath6kl_bmi_cleanup(ar);
+
+	ath6kl_debug_cleanup(ar);
+
+	kfree(ar->fw_board);
+	kfree(ar->fw_otp);
+	kfree(ar->fw);
+	kfree(ar->fw_patch);
+	kfree(ar->fw_testscript);
+
+	ath6kl_cfg80211_cleanup(ar);
+}
+EXPORT_SYMBOL(ath6kl_core_cleanup);
+
+void ath6kl_core_destroy(struct ath6kl *ar)
+{
+	ath6kl_cfg80211_destroy(ar);
+}
+EXPORT_SYMBOL(ath6kl_core_destroy);
+
+MODULE_AUTHOR("Qualcomm Atheros");
+MODULE_DESCRIPTION("Core module for AR600x SDIO and USB devices.");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c863a28..c4d66e0 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -44,6 +44,10 @@
 #define ATH6KL_MAX_ENDPOINTS   4
 #define MAX_NODE_NUM           15
 
+#define ATH6KL_APSD_ALL_FRAME		0xFFFF
+#define ATH6KL_APSD_NUM_OF_AC		0x4
+#define ATH6KL_APSD_FRAME_MASK		0xF
+
 /* Extra bytes for htc header alignment */
 #define ATH6KL_HTC_ALIGN_BYTES 3
 
@@ -55,7 +59,7 @@
 #define MAX_DEFAULT_SEND_QUEUE_DEPTH      (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
 
 #define DISCON_TIMER_INTVAL               10000  /* in msec */
-#define A_DEFAULT_LISTEN_INTERVAL         100
+#define A_DEFAULT_LISTEN_INTERVAL         1      /* beacon intervals */
 #define A_MAX_WOW_LISTEN_INTERVAL         1000
 
 /* includes also the null byte */
@@ -97,45 +101,49 @@ struct ath6kl_fw_ie {
 	u8 data[0];
 };
 
+#define ATH6KL_FW_API2_FILE "fw-2.bin"
+#define ATH6KL_FW_API3_FILE "fw-3.bin"
+
 /* AR6003 1.0 definitions */
 #define AR6003_HW_1_0_VERSION                 0x300002ba
 
 /* AR6003 2.0 definitions */
 #define AR6003_HW_2_0_VERSION                 0x30000384
 #define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS  0x57e910
-#define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
-#define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
-#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin"
-#define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
-#define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin"
+#define AR6003_HW_2_0_FW_DIR			"ath6k/AR6003/hw2.0"
+#define AR6003_HW_2_0_OTP_FILE			"otp.bin.z77"
+#define AR6003_HW_2_0_FIRMWARE_FILE		"athwlan.bin.z77"
+#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE	"athtcmd_ram.bin"
+#define AR6003_HW_2_0_PATCH_FILE		"data.patch.bin"
 #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
 #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
 			"ath6k/AR6003/hw2.0/bdata.SD31.bin"
 
 /* AR6003 3.0 definitions */
 #define AR6003_HW_2_1_1_VERSION                 0x30000582
-#define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
-#define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
-#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \
-			"ath6k/AR6003/hw2.1.1/athtcmd_ram.bin"
-#define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
-#define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin"
+#define AR6003_HW_2_1_1_FW_DIR			"ath6k/AR6003/hw2.1.1"
+#define AR6003_HW_2_1_1_OTP_FILE		"otp.bin"
+#define AR6003_HW_2_1_1_FIRMWARE_FILE		"athwlan.bin"
+#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE	"athtcmd_ram.bin"
+#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE	"utf.bin"
+#define AR6003_HW_2_1_1_TESTSCRIPT_FILE	"nullTestFlow.bin"
+#define AR6003_HW_2_1_1_PATCH_FILE		"data.patch.bin"
 #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
 #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE	\
 			"ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
 
 /* AR6004 1.0 definitions */
 #define AR6004_HW_1_0_VERSION                 0x30000623
-#define AR6004_HW_1_0_FIRMWARE_2_FILE         "ath6k/AR6004/hw1.0/fw-2.bin"
-#define AR6004_HW_1_0_FIRMWARE_FILE           "ath6k/AR6004/hw1.0/fw.ram.bin"
+#define AR6004_HW_1_0_FW_DIR			"ath6k/AR6004/hw1.0"
+#define AR6004_HW_1_0_FIRMWARE_FILE		"fw.ram.bin"
 #define AR6004_HW_1_0_BOARD_DATA_FILE         "ath6k/AR6004/hw1.0/bdata.bin"
 #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
 	"ath6k/AR6004/hw1.0/bdata.DB132.bin"
 
 /* AR6004 1.1 definitions */
 #define AR6004_HW_1_1_VERSION                 0x30000001
-#define AR6004_HW_1_1_FIRMWARE_2_FILE         "ath6k/AR6004/hw1.1/fw-2.bin"
-#define AR6004_HW_1_1_FIRMWARE_FILE           "ath6k/AR6004/hw1.1/fw.ram.bin"
+#define AR6004_HW_1_1_FW_DIR			"ath6k/AR6004/hw1.1"
+#define AR6004_HW_1_1_FIRMWARE_FILE		"fw.ram.bin"
 #define AR6004_HW_1_1_BOARD_DATA_FILE         "ath6k/AR6004/hw1.1/bdata.bin"
 #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
 	"ath6k/AR6004/hw1.1/bdata.DB132.bin"
@@ -144,6 +152,8 @@ struct ath6kl_fw_ie {
 #define STA_PS_AWAKE		BIT(0)
 #define	STA_PS_SLEEP		BIT(1)
 #define	STA_PS_POLLED		BIT(2)
+#define STA_PS_APSD_TRIGGER     BIT(3)
+#define STA_PS_APSD_EOSP        BIT(4)
 
 /* HTC TX packet tagging definitions */
 #define ATH6KL_CONTROL_PKT_TAG    HTC_TX_PACKET_TAG_USER_DEFINED
@@ -186,7 +196,7 @@ struct ath6kl_fw_ie {
 #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN  BIT(1)
 #define ATH6KL_CONF_ENABLE_11N			BIT(2)
 #define ATH6KL_CONF_ENABLE_TX_BURST		BIT(3)
-#define ATH6KL_CONF_SUSPEND_CUTPOWER		BIT(4)
+#define ATH6KL_CONF_UART_DEBUG			BIT(4)
 
 enum wlan_low_pwr_state {
 	WLAN_POWER_STATE_ON,
@@ -231,14 +241,19 @@ struct rxtid_stats {
 	u32 num_bar;
 };
 
-struct aggr_info {
+struct aggr_info_conn {
 	u8 aggr_sz;
 	u8 timer_scheduled;
 	struct timer_list timer;
 	struct net_device *dev;
 	struct rxtid rx_tid[NUM_OF_TIDS];
-	struct sk_buff_head free_q;
 	struct rxtid_stats stat[NUM_OF_TIDS];
+	struct aggr_info *aggr_info;
+};
+
+struct aggr_info {
+	struct aggr_info_conn *aggr_conn;
+	struct sk_buff_head rx_amsdu_freeq;
 };
 
 struct ath6kl_wep_key {
@@ -280,6 +295,9 @@ struct ath6kl_sta {
 	u8 wpa_ie[ATH6KL_MAX_IE];
 	struct sk_buff_head psq;
 	spinlock_t psq_lock;
+	u8 apsd_info;
+	struct sk_buff_head apsdq;
+	struct aggr_info_conn *aggr_conn;
 };
 
 struct ath6kl_version {
@@ -408,6 +426,13 @@ enum ath6kl_hif_type {
 	ATH6KL_HIF_TYPE_USB,
 };
 
+/* Max number of filters that hw supports */
+#define ATH6K_MAX_MC_FILTERS_PER_LIST 7
+struct ath6kl_mc_filter {
+	struct list_head list;
+	char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
+};
+
 /*
  * Driver's maximum limit, note that some firmwares support only one vif
  * and the runtime (current) limit must be checked from ar->vif_max.
@@ -426,6 +451,7 @@ enum ath6kl_vif_state {
 	DTIM_PERIOD_AVAIL,
 	WLAN_ENABLED,
 	STATS_UPDATE_PEND,
+	HOST_SLEEP_MODE_CMD_PROCESSED,
 };
 
 struct ath6kl_vif {
@@ -471,6 +497,8 @@ struct ath6kl_vif {
 	u8 assoc_bss_dtim_period;
 	struct net_device_stats net_stats;
 	struct target_stats target_stats;
+
+	struct list_head mc_filter;
 };
 
 #define WOW_LIST_ID		0
@@ -504,6 +532,7 @@ struct ath6kl {
 	struct wiphy *wiphy;
 
 	enum ath6kl_state state;
+	unsigned int testmode;
 
 	struct ath6kl_bmi bmi;
 	const struct ath6kl_hif_ops *hif_ops;
@@ -523,7 +552,6 @@ struct ath6kl {
 	spinlock_t lock;
 	struct semaphore sem;
 	u16 listen_intvl_b;
-	u16 listen_intvl_t;
 	u8 lrssi_roam_threshold;
 	struct ath6kl_version version;
 	u32 target_type;
@@ -574,17 +602,24 @@ struct ath6kl {
 		u32 board_addr;
 		u32 refclk_hz;
 		u32 uarttx_pin;
+		u32 testscript_addr;
+
+		struct ath6kl_hw_fw {
+			const char *dir;
+			const char *otp;
+			const char *fw;
+			const char *tcmd;
+			const char *patch;
+			const char *utf;
+			const char *testscript;
+		} fw;
 
-		const char *fw_otp;
-		const char *fw;
-		const char *fw_tcmd;
-		const char *fw_patch;
-		const char *fw_api2;
 		const char *fw_board;
 		const char *fw_default_board;
 	} hw;
 
 	u16 conf_flags;
+	u16 suspend_mode;
 	wait_queue_head_t event_wq;
 	struct ath6kl_mbox_info mbox_info;
 
@@ -603,6 +638,10 @@ struct ath6kl {
 	u8 *fw_patch;
 	size_t fw_patch_len;
 
+	u8 *fw_testscript;
+	size_t fw_testscript_len;
+
+	unsigned int fw_api;
 	unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
 
 	struct workqueue_struct *ath6kl_wq;
@@ -676,7 +715,9 @@ struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
 void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
 int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
 
-struct aggr_info *aggr_init(struct net_device *dev);
+struct aggr_info *aggr_init(struct ath6kl_vif *vif);
+void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
+		    struct aggr_info_conn *aggr_conn);
 void ath6kl_rx_refill(struct htc_target *target,
 		      enum htc_endpoint_id endpoint);
 void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
@@ -684,7 +725,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
 					    enum htc_endpoint_id endpoint,
 					    int len);
 void aggr_module_destroy(struct aggr_info *aggr_info);
-void aggr_reset_state(struct aggr_info *aggr_info);
+void aggr_reset_state(struct aggr_info_conn *aggr_conn);
 
 struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr);
 struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
@@ -700,7 +741,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
 void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel);
 void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
 				u8 keymgmt, u8 ucipher, u8 auth,
-				u8 assoc_req_len, u8 *assoc_info);
+				u8 assoc_req_len, u8 *assoc_info, u8 apsd_info);
 void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason,
 			     u8 *bssid, u8 assoc_resp_len,
 			     u8 *assoc_info, u16 prot_reason_status);
@@ -723,12 +764,18 @@ void ath6kl_wakeup_event(void *dev);
 void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
 			 bool wait_fot_compltn, bool cold_reset);
 void ath6kl_init_control_info(struct ath6kl_vif *vif);
-void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
-void ath6kl_core_free(struct ath6kl *ar);
 struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
 void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
 int ath6kl_init_hw_start(struct ath6kl *ar);
 int ath6kl_init_hw_stop(struct ath6kl *ar);
+int ath6kl_init_fetch_firmwares(struct ath6kl *ar);
+int ath6kl_init_hw_params(struct ath6kl *ar);
+
 void ath6kl_check_wow_status(struct ath6kl *ar);
 
+struct ath6kl *ath6kl_core_create(struct device *dev);
+int ath6kl_core_init(struct ath6kl *ar);
+void ath6kl_core_cleanup(struct ath6kl *ar);
+void ath6kl_core_destroy(struct ath6kl *ar);
+
 #endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index eb808b4..d832058 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -54,9 +54,42 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
 
 	return rtn;
 }
+EXPORT_SYMBOL(ath6kl_printk);
 
 #ifdef CONFIG_ATH6KL_DEBUG
 
+void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	if (!(debug_mask & mask))
+		return;
+
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
+
+	va_end(args);
+}
+EXPORT_SYMBOL(ath6kl_dbg);
+
+void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+		     const char *msg, const char *prefix,
+		     const void *buf, size_t len)
+{
+	if (debug_mask & mask) {
+		if (msg)
+			ath6kl_dbg(mask, "%s\n", msg);
+
+		print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
+	}
+}
+EXPORT_SYMBOL(ath6kl_dbg_dump);
+
 #define REG_OUTPUT_LEN_PER_LINE	25
 #define REGTYPE_STR_LEN		100
 
@@ -82,31 +115,31 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
 			   struct ath6kl_irq_enable_reg *irq_enable_reg)
 {
 
-	ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
+	ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n"));
 
 	if (irq_proc_reg != NULL) {
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			"Host Int status:           0x%x\n",
 			irq_proc_reg->host_int_status);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "CPU Int status:            0x%x\n",
 			irq_proc_reg->cpu_int_status);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "Error Int status:          0x%x\n",
 			irq_proc_reg->error_int_status);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "Counter Int status:        0x%x\n",
 			irq_proc_reg->counter_int_status);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "Mbox Frame:                0x%x\n",
 			irq_proc_reg->mbox_frame);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "Rx Lookahead Valid:        0x%x\n",
 			irq_proc_reg->rx_lkahd_valid);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "Rx Lookahead 0:            0x%x\n",
 			irq_proc_reg->rx_lkahd[0]);
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			   "Rx Lookahead 1:            0x%x\n",
 			irq_proc_reg->rx_lkahd[1]);
 
@@ -115,16 +148,16 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
 			 * If the target supports GMBOX hardware, dump some
 			 * additional state.
 			 */
-			ath6kl_dbg(ATH6KL_DBG_ANY,
+			ath6kl_dbg(ATH6KL_DBG_IRQ,
 				"GMBOX Host Int status 2:   0x%x\n",
 				irq_proc_reg->host_int_status2);
-			ath6kl_dbg(ATH6KL_DBG_ANY,
+			ath6kl_dbg(ATH6KL_DBG_IRQ,
 				"GMBOX RX Avail:            0x%x\n",
 				irq_proc_reg->gmbox_rx_avail);
-			ath6kl_dbg(ATH6KL_DBG_ANY,
+			ath6kl_dbg(ATH6KL_DBG_IRQ,
 				"GMBOX lookahead alias 0:   0x%x\n",
 				irq_proc_reg->rx_gmbox_lkahd_alias[0]);
-			ath6kl_dbg(ATH6KL_DBG_ANY,
+			ath6kl_dbg(ATH6KL_DBG_IRQ,
 				"GMBOX lookahead alias 1:   0x%x\n",
 				irq_proc_reg->rx_gmbox_lkahd_alias[1]);
 		}
@@ -132,13 +165,13 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
 	}
 
 	if (irq_enable_reg != NULL) {
-		ath6kl_dbg(ATH6KL_DBG_ANY,
+		ath6kl_dbg(ATH6KL_DBG_IRQ,
 			"Int status Enable:         0x%x\n",
 			irq_enable_reg->int_status_en);
-		ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
+		ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n",
 			irq_enable_reg->cntr_int_status_en);
 	}
-	ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
+	ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n");
 }
 
 static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
@@ -175,9 +208,6 @@ void dump_cred_dist_stats(struct htc_target *target)
 {
 	struct htc_endpoint_credit_dist *ep_list;
 
-	if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT))
-		return;
-
 	list_for_each_entry(ep_list, &target->cred_dist_list, list)
 		dump_cred_dist(ep_list);
 
@@ -1411,6 +1441,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file,
 		return -EINVAL;
 	pstream.medium_time = cpu_to_le32(val32);
 
+	pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000;
+
 	ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream);
 
 	return count;
@@ -1505,57 +1537,46 @@ static const struct file_operations fops_bgscan_int = {
 };
 
 static ssize_t ath6kl_listen_int_write(struct file *file,
-						const char __user *user_buf,
-						size_t count, loff_t *ppos)
+				       const char __user *user_buf,
+				       size_t count, loff_t *ppos)
 {
 	struct ath6kl *ar = file->private_data;
-	u16 listen_int_t, listen_int_b;
+	struct ath6kl_vif *vif;
+	u16 listen_interval;
 	char buf[32];
-	char *sptr, *token;
 	ssize_t len;
 
+	vif = ath6kl_vif_first(ar);
+	if (!vif)
+		return -EIO;
+
 	len = min(count, sizeof(buf) - 1);
 	if (copy_from_user(buf, user_buf, len))
 		return -EFAULT;
 
 	buf[len] = '\0';
-	sptr = buf;
-
-	token = strsep(&sptr, " ");
-	if (!token)
-		return -EINVAL;
-
-	if (kstrtou16(token, 0, &listen_int_t))
-		return -EINVAL;
-
-	if (kstrtou16(sptr, 0, &listen_int_b))
-		return -EINVAL;
-
-	if ((listen_int_t < 15) || (listen_int_t > 5000))
+	if (kstrtou16(buf, 0, &listen_interval))
 		return -EINVAL;
 
-	if ((listen_int_b < 1) || (listen_int_b > 50))
+	if ((listen_interval < 1) || (listen_interval > 50))
 		return -EINVAL;
 
-	ar->listen_intvl_t = listen_int_t;
-	ar->listen_intvl_b = listen_int_b;
-
-	ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t,
+	ar->listen_intvl_b = listen_interval;
+	ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0,
 				      ar->listen_intvl_b);
 
 	return count;
 }
 
 static ssize_t ath6kl_listen_int_read(struct file *file,
-						char __user *user_buf,
-						size_t count, loff_t *ppos)
+				      char __user *user_buf,
+				      size_t count, loff_t *ppos)
 {
 	struct ath6kl *ar = file->private_data;
 	char buf[32];
 	int len;
 
-	len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t,
-					ar->listen_intvl_b);
+	len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b);
 
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
@@ -1710,6 +1731,9 @@ int ath6kl_debug_init(struct ath6kl *ar)
 	debugfs_create_file("bgscan_interval", S_IWUSR,
 				ar->debugfs_phy, ar, &fops_bgscan_int);
 
+	debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR,
+			    ar->debugfs_phy, ar, &fops_listen_int);
+
 	debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
 						&fops_power_params);
 
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index 9853c9c..c4be6e5 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -41,6 +41,7 @@ enum ATH6K_DEBUG_MASK {
 	ATH6KL_DBG_BOOT		= BIT(18),    /* driver init and fw boot */
 	ATH6KL_DBG_WMI_DUMP	= BIT(19),
 	ATH6KL_DBG_SUSPEND	= BIT(20),
+	ATH6KL_DBG_USB		= BIT(21),
 	ATH6KL_DBG_ANY	        = 0xffffffff  /* enable all logs */
 };
 
@@ -55,35 +56,16 @@ int ath6kl_printk(const char *level, const char *fmt, ...);
 #define ath6kl_warn(fmt, ...)					\
 	ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
 
-#define AR_DBG_LVL_CHECK(mask)	(debug_mask & mask)
-
 enum ath6kl_war {
 	ATH6KL_WAR_INVALID_RATE,
 };
 
 #ifdef CONFIG_ATH6KL_DEBUG
-#define ath6kl_dbg(mask, fmt, ...)					\
-	({								\
-	 int rtn;							\
-	 if (debug_mask & mask)						\
-		rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__);	\
-	 else								\
-		rtn = 0;						\
-									\
-	 rtn;								\
-	 })
 
-static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
-				   const char *msg, const char *prefix,
-				   const void *buf, size_t len)
-{
-	if (debug_mask & mask) {
-		if (msg)
-			ath6kl_dbg(mask, "%s\n", msg);
-
-		print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
-	}
-}
+void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...);
+void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+		     const char *msg, const char *prefix,
+		     const void *buf, size_t len);
 
 void ath6kl_dump_registers(struct ath6kl_device *dev,
 			   struct ath6kl_irq_proc_registers *irq_proc_reg,
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index e57da35..e911737 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -15,6 +15,8 @@
  */
 #include "hif.h"
 
+#include <linux/export.h>
+
 #include "core.h"
 #include "target.h"
 #include "hif-ops.h"
@@ -59,6 +61,8 @@ int ath6kl_hif_rw_comp_handler(void *context, int status)
 
 	return 0;
 }
+EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler);
+
 #define REG_DUMP_COUNT_AR6003   60
 #define REGISTER_DUMP_LEN_MAX   60
 
@@ -429,9 +433,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
 		if (status)
 			goto out;
 
-		if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ))
-			ath6kl_dump_registers(dev, &dev->irq_proc_reg,
-					 &dev->irq_en_reg);
+		ath6kl_dump_registers(dev, &dev->irq_proc_reg,
+				      &dev->irq_en_reg);
 
 		/* Update only those registers that are enabled */
 		host_int_status = dev->irq_proc_reg.host_int_status &
@@ -561,6 +564,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
 
 	return status;
 }
+EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler);
 
 static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev)
 {
@@ -689,6 +693,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev)
 	ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
 		   dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
 
+	/* usb doesn't support enabling interrupts */
+	/* FIXME: remove check once USB support is implemented */
+	if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
+		return 0;
+
 	status = ath6kl_hif_disable_intrs(dev);
 
 fail_setup:
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index f3b63ca..2d72190 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -2062,6 +2062,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
 	enum htc_endpoint_id id;
 	int n_fetched = 0;
 
+	INIT_LIST_HEAD(&comp_pktq);
 	*num_pkts = 0;
 
 	/*
@@ -2543,6 +2544,12 @@ int ath6kl_htc_wait_target(struct htc_target *target)
 	struct htc_service_connect_resp resp;
 	int status;
 
+	/* FIXME: remove once USB support is implemented */
+	if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
+		ath6kl_err("HTC doesn't support USB yet. Patience!\n");
+		return -EOPNOTSUPP;
+	}
+
 	/* we should be getting 1 control message that the target is ready */
 	packet = htc_wait_for_ctrl_msg(target);
 
@@ -2772,7 +2779,9 @@ void ath6kl_htc_cleanup(struct htc_target *target)
 {
 	struct htc_packet *packet, *tmp_packet;
 
-	ath6kl_hif_cleanup_scatter(target->dev->ar);
+	/* FIXME: remove check once USB support is implemented */
+	if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
+		ath6kl_hif_cleanup_scatter(target->dev->ar);
 
 	list_for_each_entry_safe(packet, tmp_packet,
 			&target->free_ctrl_txbuf, list) {
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 7f55be3..0d76c37 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -17,22 +17,16 @@
 
 #include <linux/moduleparam.h>
 #include <linux/errno.h>
+#include <linux/export.h>
 #include <linux/of.h>
 #include <linux/mmc/sdio_func.h>
+
 #include "core.h"
 #include "cfg80211.h"
 #include "target.h"
 #include "debug.h"
 #include "hif-ops.h"
 
-unsigned int debug_mask;
-static unsigned int testmode;
-static bool suspend_cutpower;
-
-module_param(debug_mask, uint, 0644);
-module_param(testmode, uint, 0644);
-module_param(suspend_cutpower, bool, 0444);
-
 static const struct ath6kl_hw hw_list[] = {
 	{
 		.id				= AR6003_HW_2_0_VERSION,
@@ -47,11 +41,14 @@ static const struct ath6kl_hw hw_list[] = {
 		/* hw2.0 needs override address hardcoded */
 		.app_start_override_addr	= 0x944C00,
 
-		.fw_otp			= AR6003_HW_2_0_OTP_FILE,
-		.fw			= AR6003_HW_2_0_FIRMWARE_FILE,
-		.fw_tcmd		= AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
-		.fw_patch		= AR6003_HW_2_0_PATCH_FILE,
-		.fw_api2		= AR6003_HW_2_0_FIRMWARE_2_FILE,
+		.fw = {
+			.dir		= AR6003_HW_2_0_FW_DIR,
+			.otp		= AR6003_HW_2_0_OTP_FILE,
+			.fw		= AR6003_HW_2_0_FIRMWARE_FILE,
+			.tcmd		= AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
+			.patch		= AR6003_HW_2_0_PATCH_FILE,
+		},
+
 		.fw_board		= AR6003_HW_2_0_BOARD_DATA_FILE,
 		.fw_default_board	= AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE,
 	},
@@ -64,12 +61,18 @@ static const struct ath6kl_hw hw_list[] = {
 		.reserved_ram_size		= 512,
 		.refclk_hz			= 26000000,
 		.uarttx_pin			= 8,
+		.testscript_addr		= 0x57ef74,
+
+		.fw = {
+			.dir		= AR6003_HW_2_1_1_FW_DIR,
+			.otp		= AR6003_HW_2_1_1_OTP_FILE,
+			.fw		= AR6003_HW_2_1_1_FIRMWARE_FILE,
+			.tcmd		= AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
+			.patch		= AR6003_HW_2_1_1_PATCH_FILE,
+			.utf		= AR6003_HW_2_1_1_UTF_FIRMWARE_FILE,
+			.testscript	= AR6003_HW_2_1_1_TESTSCRIPT_FILE,
+		},
 
-		.fw_otp			= AR6003_HW_2_1_1_OTP_FILE,
-		.fw			= AR6003_HW_2_1_1_FIRMWARE_FILE,
-		.fw_tcmd		= AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
-		.fw_patch		= AR6003_HW_2_1_1_PATCH_FILE,
-		.fw_api2		= AR6003_HW_2_1_1_FIRMWARE_2_FILE,
 		.fw_board		= AR6003_HW_2_1_1_BOARD_DATA_FILE,
 		.fw_default_board	= AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
 	},
@@ -84,8 +87,11 @@ static const struct ath6kl_hw hw_list[] = {
 		.refclk_hz			= 26000000,
 		.uarttx_pin			= 11,
 
-		.fw			= AR6004_HW_1_0_FIRMWARE_FILE,
-		.fw_api2		= AR6004_HW_1_0_FIRMWARE_2_FILE,
+		.fw = {
+			.dir		= AR6004_HW_1_0_FW_DIR,
+			.fw		= AR6004_HW_1_0_FIRMWARE_FILE,
+		},
+
 		.fw_board		= AR6004_HW_1_0_BOARD_DATA_FILE,
 		.fw_default_board	= AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE,
 	},
@@ -100,8 +106,11 @@ static const struct ath6kl_hw hw_list[] = {
 		.refclk_hz			= 40000000,
 		.uarttx_pin			= 11,
 
-		.fw			= AR6004_HW_1_1_FIRMWARE_FILE,
-		.fw_api2		= AR6004_HW_1_1_FIRMWARE_2_FILE,
+		.fw = {
+			.dir		= AR6004_HW_1_1_FW_DIR,
+			.fw		= AR6004_HW_1_1_FIRMWARE_FILE,
+		},
+
 		.fw_board		= AR6004_HW_1_1_BOARD_DATA_FILE,
 		.fw_default_board	= AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
 	},
@@ -452,6 +461,13 @@ int ath6kl_configure_target(struct ath6kl *ar)
 	u8 fw_iftype, fw_mode = 0, fw_submode = 0;
 	int i, status;
 
+	param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG);
+	if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
+			     HI_ITEM(hi_serial_enable)), (u8 *)&param, 4)) {
+		ath6kl_err("bmi_write_memory for uart debug failed\n");
+		return -EIO;
+	}
+
 	/*
 	 * Note: Even though the firmware interface type is
 	 * chosen as BSS_STA for all three interfaces, can
@@ -573,36 +589,6 @@ int ath6kl_configure_target(struct ath6kl *ar)
 	return 0;
 }
 
-void ath6kl_core_free(struct ath6kl *ar)
-{
-	wiphy_free(ar->wiphy);
-}
-
-void ath6kl_core_cleanup(struct ath6kl *ar)
-{
-	ath6kl_hif_power_off(ar);
-
-	destroy_workqueue(ar->ath6kl_wq);
-
-	if (ar->htc_target)
-		ath6kl_htc_cleanup(ar->htc_target);
-
-	ath6kl_cookie_cleanup(ar);
-
-	ath6kl_cleanup_amsdu_rxbufs(ar);
-
-	ath6kl_bmi_cleanup(ar);
-
-	ath6kl_debug_cleanup(ar);
-
-	kfree(ar->fw_board);
-	kfree(ar->fw_otp);
-	kfree(ar->fw);
-	kfree(ar->fw_patch);
-
-	ath6kl_deinit_ieee80211_hw(ar);
-}
-
 /* firmware upload */
 static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
 			 u8 **fw, size_t *fw_len)
@@ -626,21 +612,6 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
 }
 
 #ifdef CONFIG_OF
-static const char *get_target_ver_dir(const struct ath6kl *ar)
-{
-	switch (ar->version.target_ver) {
-	case AR6003_HW_1_0_VERSION:
-		return "ath6k/AR6003/hw1.0";
-	case AR6003_HW_2_0_VERSION:
-		return "ath6k/AR6003/hw2.0";
-	case AR6003_HW_2_1_1_VERSION:
-		return "ath6k/AR6003/hw2.1.1";
-	}
-	ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__,
-		    ar->version.target_ver);
-	return NULL;
-}
-
 /*
  * Check the device tree for a board-id and use it to construct
  * the pathname to the firmware file.  Used (for now) to find a
@@ -663,7 +634,7 @@ static bool check_device_tree(struct ath6kl *ar)
 			continue;
 		}
 		snprintf(board_filename, sizeof(board_filename),
-			 "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id);
+			 "%s/bdata.%s.bin", ar->hw.fw.dir, board_id);
 
 		ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
 				    &ar->fw_board_len);
@@ -730,19 +701,20 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar)
 
 static int ath6kl_fetch_otp_file(struct ath6kl *ar)
 {
-	const char *filename;
+	char filename[100];
 	int ret;
 
 	if (ar->fw_otp != NULL)
 		return 0;
 
-	if (ar->hw.fw_otp == NULL) {
+	if (ar->hw.fw.otp == NULL) {
 		ath6kl_dbg(ATH6KL_DBG_BOOT,
 			   "no OTP file configured for this hw\n");
 		return 0;
 	}
 
-	filename = ar->hw.fw_otp;
+	snprintf(filename, sizeof(filename), "%s/%s",
+		 ar->hw.fw.dir, ar->hw.fw.otp);
 
 	ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
 			    &ar->fw_otp_len);
@@ -755,33 +727,61 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar)
 	return 0;
 }
 
-static int ath6kl_fetch_fw_file(struct ath6kl *ar)
+static int ath6kl_fetch_testmode_file(struct ath6kl *ar)
 {
-	const char *filename;
+	char filename[100];
 	int ret;
 
-	if (ar->fw != NULL)
+	if (ar->testmode == 0)
 		return 0;
 
-	if (testmode) {
-		if (ar->hw.fw_tcmd == NULL) {
-			ath6kl_warn("testmode not supported\n");
+	ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode);
+
+	if (ar->testmode == 2) {
+		if (ar->hw.fw.utf == NULL) {
+			ath6kl_warn("testmode 2 not supported\n");
+			return -EOPNOTSUPP;
+		}
+
+		snprintf(filename, sizeof(filename), "%s/%s",
+			 ar->hw.fw.dir, ar->hw.fw.utf);
+	} else {
+		if (ar->hw.fw.tcmd == NULL) {
+			ath6kl_warn("testmode 1 not supported\n");
 			return -EOPNOTSUPP;
 		}
 
-		filename = ar->hw.fw_tcmd;
+		snprintf(filename, sizeof(filename), "%s/%s",
+			 ar->hw.fw.dir, ar->hw.fw.tcmd);
+	}
 
-		set_bit(TESTMODE, &ar->flag);
+	set_bit(TESTMODE, &ar->flag);
 
-		goto get_fw;
+	ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
+	if (ret) {
+		ath6kl_err("Failed to get testmode %d firmware file %s: %d\n",
+			   ar->testmode, filename, ret);
+		return ret;
 	}
 
-	if (WARN_ON(ar->hw.fw == NULL))
+	return 0;
+}
+
+static int ath6kl_fetch_fw_file(struct ath6kl *ar)
+{
+	char filename[100];
+	int ret;
+
+	if (ar->fw != NULL)
+		return 0;
+
+	/* FIXME: remove WARN_ON() as we won't support FW API 1 for long */
+	if (WARN_ON(ar->hw.fw.fw == NULL))
 		return -EINVAL;
 
-	filename = ar->hw.fw;
+	snprintf(filename, sizeof(filename), "%s/%s",
+		 ar->hw.fw.dir, ar->hw.fw.fw);
 
-get_fw:
 	ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
 	if (ret) {
 		ath6kl_err("Failed to get firmware file %s: %d\n",
@@ -794,16 +794,17 @@ get_fw:
 
 static int ath6kl_fetch_patch_file(struct ath6kl *ar)
 {
-	const char *filename;
+	char filename[100];
 	int ret;
 
 	if (ar->fw_patch != NULL)
 		return 0;
 
-	if (ar->hw.fw_patch == NULL)
+	if (ar->hw.fw.patch == NULL)
 		return 0;
 
-	filename = ar->hw.fw_patch;
+	snprintf(filename, sizeof(filename), "%s/%s",
+		 ar->hw.fw.dir, ar->hw.fw.patch);
 
 	ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
 			    &ar->fw_patch_len);
@@ -816,6 +817,34 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar)
 	return 0;
 }
 
+static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
+{
+	char filename[100];
+	int ret;
+
+	if (ar->testmode != 2)
+		return 0;
+
+	if (ar->fw_testscript != NULL)
+		return 0;
+
+	if (ar->hw.fw.testscript == NULL)
+		return 0;
+
+	snprintf(filename, sizeof(filename), "%s/%s",
+		ar->hw.fw.dir, ar->hw.fw.testscript);
+
+	ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
+				&ar->fw_testscript_len);
+	if (ret) {
+		ath6kl_err("Failed to get testscript file %s: %d\n",
+			filename, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
 {
 	int ret;
@@ -832,23 +861,24 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
 	if (ret)
 		return ret;
 
+	ret = ath6kl_fetch_testscript_file(ar);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
-static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
+static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
 {
 	size_t magic_len, len, ie_len;
 	const struct firmware *fw;
 	struct ath6kl_fw_ie *hdr;
-	const char *filename;
+	char filename[100];
 	const u8 *data;
 	int ret, ie_id, i, index, bit;
 	__le32 *val;
 
-	if (ar->hw.fw_api2 == NULL)
-		return -EOPNOTSUPP;
-
-	filename = ar->hw.fw_api2;
+	snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
 
 	ret = request_firmware(&fw, filename, ar->dev);
 	if (ret)
@@ -907,6 +937,10 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar)
 			ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
 				ie_len);
 
+			/* in testmode we already might have a fw file */
+			if (ar->fw != NULL)
+				break;
+
 			ar->fw = kmemdup(data, ie_len, GFP_KERNEL);
 
 			if (ar->fw == NULL) {
@@ -1010,7 +1044,7 @@ out:
 	return ret;
 }
 
-static int ath6kl_fetch_firmwares(struct ath6kl *ar)
+int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
 {
 	int ret;
 
@@ -1018,17 +1052,30 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar)
 	if (ret)
 		return ret;
 
-	ret = ath6kl_fetch_fw_api2(ar);
+	ret = ath6kl_fetch_testmode_file(ar);
+	if (ret)
+		return ret;
+
+	ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
 	if (ret == 0) {
-		ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n");
-		return 0;
+		ar->fw_api = 3;
+		goto out;
+	}
+
+	ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE);
+	if (ret == 0) {
+		ar->fw_api = 2;
+		goto out;
 	}
 
 	ret = ath6kl_fetch_fw_api1(ar);
 	if (ret)
 		return ret;
 
-	ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n");
+	ar->fw_api = 1;
+
+out:
+	ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api);
 
 	return 0;
 }
@@ -1249,6 +1296,50 @@ static int ath6kl_upload_patch(struct ath6kl *ar)
 	return 0;
 }
 
+static int ath6kl_upload_testscript(struct ath6kl *ar)
+{
+	u32 address, param;
+	int ret;
+
+	if (ar->testmode != 2)
+		return 0;
+
+	if (ar->fw_testscript == NULL)
+		return 0;
+
+	address = ar->hw.testscript_addr;
+
+	ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
+		address, ar->fw_testscript_len);
+
+	ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
+		ar->fw_testscript_len);
+	if (ret) {
+		ath6kl_err("Failed to write testscript file: %d\n", ret);
+		return ret;
+	}
+
+	param = address;
+	ath6kl_bmi_write(ar,
+			ath6kl_get_hi_item_addr(ar,
+			HI_ITEM(hi_ota_testscript)),
+			(unsigned char *) &param, 4);
+
+	param = 4096;
+	ath6kl_bmi_write(ar,
+			ath6kl_get_hi_item_addr(ar,
+			HI_ITEM(hi_end_ram_reserve_sz)),
+			(unsigned char *) &param, 4);
+
+	param = 1;
+	ath6kl_bmi_write(ar,
+			ath6kl_get_hi_item_addr(ar,
+			HI_ITEM(hi_test_apps_related)),
+			(unsigned char *) &param, 4);
+
+	return 0;
+}
+
 static int ath6kl_init_upload(struct ath6kl *ar)
 {
 	u32 param, options, sleep, address;
@@ -1357,6 +1448,11 @@ static int ath6kl_init_upload(struct ath6kl *ar)
 	if (status)
 		return status;
 
+	/* Download the test script */
+	status = ath6kl_upload_testscript(ar);
+	if (status)
+		return status;
+
 	/* Restore system sleep */
 	address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
 	status = ath6kl_bmi_reg_write(ar, address, sleep);
@@ -1372,9 +1468,9 @@ static int ath6kl_init_upload(struct ath6kl *ar)
 	return status;
 }
 
-static int ath6kl_init_hw_params(struct ath6kl *ar)
+int ath6kl_init_hw_params(struct ath6kl *ar)
 {
-	const struct ath6kl_hw *hw;
+	const struct ath6kl_hw *uninitialized_var(hw);
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
@@ -1481,10 +1577,11 @@ int ath6kl_init_hw_start(struct ath6kl *ar)
 
 
 	if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
-		ath6kl_info("%s %s fw %s%s\n",
+		ath6kl_info("%s %s fw %s api %d%s\n",
 			    ar->hw.name,
 			    ath6kl_init_get_hif_name(ar->hif_type),
 			    ar->wiphy->fw_version,
+			    ar->fw_api,
 			    test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
 	}
 
@@ -1549,173 +1646,7 @@ int ath6kl_init_hw_stop(struct ath6kl *ar)
 	return 0;
 }
 
-int ath6kl_core_init(struct ath6kl *ar)
-{
-	struct ath6kl_bmi_target_info targ_info;
-	struct net_device *ndev;
-	int ret = 0, i;
-
-	ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
-	if (!ar->ath6kl_wq)
-		return -ENOMEM;
-
-	ret = ath6kl_bmi_init(ar);
-	if (ret)
-		goto err_wq;
-
-	/*
-	 * Turn on power to get hardware (target) version and leave power
-	 * on delibrately as we will boot the hardware anyway within few
-	 * seconds.
-	 */
-	ret = ath6kl_hif_power_on(ar);
-	if (ret)
-		goto err_bmi_cleanup;
-
-	ret = ath6kl_bmi_get_target_info(ar, &targ_info);
-	if (ret)
-		goto err_power_off;
-
-	ar->version.target_ver = le32_to_cpu(targ_info.version);
-	ar->target_type = le32_to_cpu(targ_info.type);
-	ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
-
-	ret = ath6kl_init_hw_params(ar);
-	if (ret)
-		goto err_power_off;
-
-	ar->htc_target = ath6kl_htc_create(ar);
-
-	if (!ar->htc_target) {
-		ret = -ENOMEM;
-		goto err_power_off;
-	}
-
-	ret = ath6kl_fetch_firmwares(ar);
-	if (ret)
-		goto err_htc_cleanup;
-
-	/* FIXME: we should free all firmwares in the error cases below */
-
-	/* Indicate that WMI is enabled (although not ready yet) */
-	set_bit(WMI_ENABLED, &ar->flag);
-	ar->wmi = ath6kl_wmi_init(ar);
-	if (!ar->wmi) {
-		ath6kl_err("failed to initialize wmi\n");
-		ret = -EIO;
-		goto err_htc_cleanup;
-	}
-
-	ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
-
-	ret = ath6kl_register_ieee80211_hw(ar);
-	if (ret)
-		goto err_node_cleanup;
-
-	ret = ath6kl_debug_init(ar);
-	if (ret) {
-		wiphy_unregister(ar->wiphy);
-		goto err_node_cleanup;
-	}
-
-	for (i = 0; i < ar->vif_max; i++)
-		ar->avail_idx_map |= BIT(i);
-
-	rtnl_lock();
-
-	/* Add an initial station interface */
-	ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
-				    INFRA_NETWORK);
-
-	rtnl_unlock();
-
-	if (!ndev) {
-		ath6kl_err("Failed to instantiate a network device\n");
-		ret = -ENOMEM;
-		wiphy_unregister(ar->wiphy);
-		goto err_debug_init;
-	}
-
-
-	ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
-			__func__, ndev->name, ndev, ar);
-
-	/* setup access class priority mappings */
-	ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest  */
-	ar->ac_stream_pri_map[WMM_AC_BE] = 1;
-	ar->ac_stream_pri_map[WMM_AC_VI] = 2;
-	ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
-
-	/* give our connected endpoints some buffers */
-	ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
-	ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
-
-	/* allocate some buffers that handle larger AMSDU frames */
-	ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
-
-	ath6kl_cookie_init(ar);
-
-	ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
-			 ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
-
-	if (suspend_cutpower)
-		ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER;
-
-	ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
-			    WIPHY_FLAG_HAVE_AP_SME |
-			    WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
-			    WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
-
-	if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
-		ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
-
-	ar->wiphy->probe_resp_offload =
-		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
-		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
-		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
-		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
-
-	set_bit(FIRST_BOOT, &ar->flag);
-
-	ret = ath6kl_init_hw_start(ar);
-	if (ret) {
-		ath6kl_err("Failed to start hardware: %d\n", ret);
-		goto err_rxbuf_cleanup;
-	}
-
-	/*
-	 * Set mac address which is received in ready event
-	 * FIXME: Move to ath6kl_interface_add()
-	 */
-	memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
-
-	return ret;
-
-err_rxbuf_cleanup:
-	ath6kl_htc_flush_rx_buf(ar->htc_target);
-	ath6kl_cleanup_amsdu_rxbufs(ar);
-	rtnl_lock();
-	ath6kl_deinit_if_data(netdev_priv(ndev));
-	rtnl_unlock();
-	wiphy_unregister(ar->wiphy);
-err_debug_init:
-	ath6kl_debug_cleanup(ar);
-err_node_cleanup:
-	ath6kl_wmi_shutdown(ar->wmi);
-	clear_bit(WMI_ENABLED, &ar->flag);
-	ar->wmi = NULL;
-err_htc_cleanup:
-	ath6kl_htc_cleanup(ar->htc_target);
-err_power_off:
-	ath6kl_hif_power_off(ar);
-err_bmi_cleanup:
-	ath6kl_bmi_cleanup(ar);
-err_wq:
-	destroy_workqueue(ar->ath6kl_wq);
-
-	return ret;
-}
-
+/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */
 void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
 {
 	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -1747,6 +1678,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
 void ath6kl_stop_txrx(struct ath6kl *ar)
 {
 	struct ath6kl_vif *vif, *tmp_vif;
+	int i;
 
 	set_bit(DESTROY_IN_PROGRESS, &ar->flag);
 
@@ -1755,13 +1687,16 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
 		return;
 	}
 
+	for (i = 0; i < AP_MAX_NUM_STA; i++)
+		aggr_reset_state(ar->sta_list[i].aggr_conn);
+
 	spin_lock_bh(&ar->list_lock);
 	list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
 		list_del(&vif->list);
 		spin_unlock_bh(&ar->list_lock);
 		ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
 		rtnl_lock();
-		ath6kl_deinit_if_data(vif);
+		ath6kl_cfg80211_vif_cleanup(vif);
 		rtnl_unlock();
 		spin_lock_bh(&ar->list_lock);
 	}
@@ -1796,3 +1731,4 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
 
 	clear_bit(WLAN_ENABLED, &ar->flag);
 }
+EXPORT_SYMBOL(ath6kl_stop_txrx);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index eea3c74..b96d01a 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -52,9 +52,11 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
 	return conn;
 }
 
-static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
-			u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
+static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid,
+			       u8 *wpaie, size_t ielen, u8 keymgmt,
+			       u8 ucipher, u8 auth, u8 apsd_info)
 {
+	struct ath6kl *ar = vif->ar;
 	struct ath6kl_sta *sta;
 	u8 free_slot;
 
@@ -68,9 +70,11 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
 	sta->keymgmt = keymgmt;
 	sta->ucipher = ucipher;
 	sta->auth = auth;
+	sta->apsd_info = apsd_info;
 
 	ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
 	ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
+	aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn);
 }
 
 static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
@@ -80,6 +84,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
 	/* empty the queued pkts in the PS queue if any */
 	spin_lock_bh(&sta->psq_lock);
 	skb_queue_purge(&sta->psq);
+	skb_queue_purge(&sta->apsdq);
 	spin_unlock_bh(&sta->psq_lock);
 
 	memset(&ar->ap_stats.sta[sta->aid - 1], 0,
@@ -90,7 +95,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
 	sta->sta_flags = 0;
 
 	ar->sta_list_index = ar->sta_list_index & ~(1 << i);
-
+	aggr_reset_state(sta->aggr_conn);
 }
 
 static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
@@ -252,7 +257,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar)
 	struct ath6kl_dbglog_hdr debug_hdr;
 	struct ath6kl_dbglog_buf debug_buf;
 	u32 address, length, dropped, firstbuf, debug_hdr_addr;
-	int ret = 0, loop;
+	int ret, loop;
 	u8 *buf;
 
 	buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
@@ -347,9 +352,6 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
 	case TARGET_TYPE_AR6004:
 		address = AR6004_RESET_CONTROL_ADDRESS;
 		break;
-	default:
-		address = AR6003_RESET_CONTROL_ADDRESS;
-		break;
 	}
 
 	status = ath6kl_diag_write32(ar, address, data);
@@ -363,7 +365,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
 	u8 index;
 	u8 keyusage;
 
-	for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+	for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) {
 		if (vif->wep_key_list[index].key_len) {
 			keyusage = GROUP_USAGE;
 			if (index == vif->def_txkey_index)
@@ -428,9 +430,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
 
 void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
 				u8 keymgmt, u8 ucipher, u8 auth,
-				u8 assoc_req_len, u8 *assoc_info)
+				u8 assoc_req_len, u8 *assoc_info, u8 apsd_info)
 {
-	struct ath6kl *ar = vif->ar;
 	u8 *ies = NULL, *wpa_ie = NULL, *pos;
 	size_t ies_len = 0;
 	struct station_info sinfo;
@@ -484,9 +485,9 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
 		pos += 2 + pos[1];
 	}
 
-	ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
+	ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie,
 			   wpa_ie ? 2 + wpa_ie[1] : 0,
-			   keymgmt, ucipher, auth);
+			   keymgmt, ucipher, auth, apsd_info);
 
 	/* send event to application */
 	memset(&sinfo, 0, sizeof(sinfo));
@@ -587,10 +588,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
 	memcpy(vif->bssid, bssid, sizeof(vif->bssid));
 	vif->bss_ch = channel;
 
-	if ((vif->nw_type == INFRA_NETWORK))
+	if ((vif->nw_type == INFRA_NETWORK)) {
+		ar->listen_intvl_b = listen_int;
 		ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
-					      ar->listen_intvl_t,
-					      ar->listen_intvl_b);
+					      0, ar->listen_intvl_b);
+	}
 
 	netif_wake_queue(vif->ndev);
 
@@ -601,7 +603,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
 	netif_carrier_on(vif->ndev);
 	spin_unlock_bh(&vif->if_lock);
 
-	aggr_reset_state(vif->aggr_cntxt);
+	aggr_reset_state(vif->aggr_cntxt->aggr_conn);
 	vif->reconnect_flag = 0;
 
 	if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
@@ -923,7 +925,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
 				       assoc_resp_len, assoc_info,
 				       prot_reason_status);
 
-	aggr_reset_state(vif->aggr_cntxt);
+	aggr_reset_state(vif->aggr_cntxt->aggr_conn);
 
 	del_timer(&vif->disconnect_timer);
 
@@ -1020,11 +1022,155 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
 	return &vif->net_stats;
 }
 
-static struct net_device_ops ath6kl_netdev_ops = {
+static int ath6kl_set_features(struct net_device *dev,
+			       netdev_features_t features)
+{
+	struct ath6kl_vif *vif = netdev_priv(dev);
+	struct ath6kl *ar = vif->ar;
+	int err = 0;
+
+	if ((features & NETIF_F_RXCSUM) &&
+	    (ar->rx_meta_ver != WMI_META_VERSION_2)) {
+		ar->rx_meta_ver = WMI_META_VERSION_2;
+		err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+							 vif->fw_vif_idx,
+							 ar->rx_meta_ver, 0, 0);
+		if (err) {
+			dev->features = features & ~NETIF_F_RXCSUM;
+			return err;
+		}
+	} else if (!(features & NETIF_F_RXCSUM) &&
+		   (ar->rx_meta_ver == WMI_META_VERSION_2)) {
+		ar->rx_meta_ver = 0;
+		err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+							 vif->fw_vif_idx,
+							 ar->rx_meta_ver, 0, 0);
+		if (err) {
+			dev->features = features | NETIF_F_RXCSUM;
+			return err;
+		}
+
+	}
+
+	return err;
+}
+
+static void ath6kl_set_multicast_list(struct net_device *ndev)
+{
+	struct ath6kl_vif *vif = netdev_priv(ndev);
+	bool mc_all_on = false, mc_all_off = false;
+	int mc_count = netdev_mc_count(ndev);
+	struct netdev_hw_addr *ha;
+	bool found;
+	struct ath6kl_mc_filter *mc_filter, *tmp;
+	struct list_head mc_filter_new;
+	int ret;
+
+	if (!test_bit(WMI_READY, &vif->ar->flag) ||
+	    !test_bit(WLAN_ENABLED, &vif->flags))
+		return;
+
+	mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
+		    !!(ndev->flags & IFF_ALLMULTI) ||
+		    !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
+
+	mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0;
+
+	if (mc_all_on || mc_all_off) {
+		/* Enable/disable all multicast */
+		ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n",
+			  mc_all_on ? "enabling" : "disabling");
+		ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
+						  mc_all_on);
+		if (ret)
+			ath6kl_warn("Failed to %s multicast receive\n",
+				    mc_all_on ? "enable" : "disable");
+		return;
+	}
+
+	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
+		found = false;
+		netdev_for_each_mc_addr(ha, ndev) {
+			if (memcmp(ha->addr, mc_filter->hw_addr,
+			    ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			/*
+			 * Delete the filter which was previously set
+			 * but not in the new request.
+			 */
+			ath6kl_dbg(ATH6KL_DBG_TRC,
+				   "Removing %pM from multicast filter\n",
+				   mc_filter->hw_addr);
+			ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
+					vif->fw_vif_idx, mc_filter->hw_addr,
+					false);
+			if (ret) {
+				ath6kl_warn("Failed to remove multicast filter:%pM\n",
+					     mc_filter->hw_addr);
+				return;
+			}
+
+			list_del(&mc_filter->list);
+			kfree(mc_filter);
+		}
+	}
+
+	INIT_LIST_HEAD(&mc_filter_new);
+
+	netdev_for_each_mc_addr(ha, ndev) {
+		found = false;
+		list_for_each_entry(mc_filter, &vif->mc_filter, list) {
+			if (memcmp(ha->addr, mc_filter->hw_addr,
+			    ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter),
+					    GFP_ATOMIC);
+			if (!mc_filter) {
+				WARN_ON(1);
+				goto out;
+			}
+
+			memcpy(mc_filter->hw_addr, ha->addr,
+			       ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
+			/* Set the multicast filter */
+			ath6kl_dbg(ATH6KL_DBG_TRC,
+				   "Adding %pM to multicast filter list\n",
+				   mc_filter->hw_addr);
+			ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
+					vif->fw_vif_idx, mc_filter->hw_addr,
+					true);
+			if (ret) {
+				ath6kl_warn("Failed to add multicast filter :%pM\n",
+					     mc_filter->hw_addr);
+				kfree(mc_filter);
+				goto out;
+			}
+
+			list_add_tail(&mc_filter->list, &mc_filter_new);
+		}
+	}
+
+out:
+	list_splice_tail(&mc_filter_new, &vif->mc_filter);
+}
+
+static const struct net_device_ops ath6kl_netdev_ops = {
 	.ndo_open               = ath6kl_open,
 	.ndo_stop               = ath6kl_close,
 	.ndo_start_xmit         = ath6kl_data_tx,
 	.ndo_get_stats          = ath6kl_get_stats,
+	.ndo_set_features       = ath6kl_set_features,
+	.ndo_set_rx_mode	= ath6kl_set_multicast_list,
 };
 
 void init_netdev(struct net_device *dev)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 9475e2d..4febee7 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -49,11 +49,13 @@ struct ath6kl_sdio {
 	/* scatter request list head */
 	struct list_head scat_req;
 
+	/* Avoids disabling irq while the interrupts being handled */
+	struct mutex mtx_irq;
+
 	spinlock_t scat_lock;
 	bool scatter_enabled;
 
 	bool is_disabled;
-	atomic_t irq_handling;
 	const struct sdio_device_id *id;
 	struct work_struct wr_async_work;
 	struct list_head wr_asyncq;
@@ -460,8 +462,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
 	ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
 
 	ar_sdio = sdio_get_drvdata(func);
-	atomic_set(&ar_sdio->irq_handling, 1);
-
+	mutex_lock(&ar_sdio->mtx_irq);
 	/*
 	 * Release the host during interrups so we can pick it back up when
 	 * we process commands.
@@ -470,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
 
 	status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
 	sdio_claim_host(ar_sdio->func);
-	atomic_set(&ar_sdio->irq_handling, 0);
+	mutex_unlock(&ar_sdio->mtx_irq);
 	WARN_ON(status && status != -ECANCELED);
 }
 
@@ -578,17 +579,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
 
 	sdio_claim_host(ar_sdio->func);
 
-	/* Mask our function IRQ */
-	while (atomic_read(&ar_sdio->irq_handling)) {
-		sdio_release_host(ar_sdio->func);
-		schedule_timeout(HZ / 10);
-		sdio_claim_host(ar_sdio->func);
-	}
+	mutex_lock(&ar_sdio->mtx_irq);
 
 	ret = sdio_release_irq(ar_sdio->func);
 	if (ret)
 		ath6kl_err("Failed to release sdio irq: %d\n", ret);
 
+	mutex_unlock(&ar_sdio->mtx_irq);
+
 	sdio_release_host(ar_sdio->func);
 }
 
@@ -772,7 +770,6 @@ static int ath6kl_sdio_config(struct ath6kl *ar)
 	if (ret) {
 		ath6kl_err("Set sdio block size %d failed: %d)\n",
 			   HIF_MBOX_BLOCK_SIZE, ret);
-		sdio_release_host(func);
 		goto out;
 	}
 
@@ -782,7 +779,7 @@ out:
 	return ret;
 }
 
-static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar)
 {
 	struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
 	struct sdio_func *func = ar_sdio->func;
@@ -793,60 +790,95 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
 
 	ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags);
 
-	if (!(flags & MMC_PM_KEEP_POWER) ||
-	    (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) {
-		/* as host doesn't support keep power we need to cut power */
-		return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER,
-					       NULL);
-	}
+	if (!(flags & MMC_PM_WAKE_SDIO_IRQ) ||
+	    !(flags & MMC_PM_KEEP_POWER))
+		return -EINVAL;
 
 	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
 	if (ret) {
-		printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
-		       ret);
+		ath6kl_err("set sdio keep pwr flag failed: %d\n", ret);
 		return ret;
 	}
 
-	if (!(flags & MMC_PM_WAKE_SDIO_IRQ))
-		goto deepsleep;
-
 	/* sdio irq wakes up host */
+	ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+	if (ret)
+		ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
+
+	return ret;
+}
+
+static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+	struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+	struct sdio_func *func = ar_sdio->func;
+	mmc_pm_flag_t flags;
+	int ret;
 
 	if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
+		ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n");
+
+		ret = ath6kl_set_sdio_pm_caps(ar);
+		if (ret)
+			goto cut_pwr;
+
 		ret =  ath6kl_cfg80211_suspend(ar,
 					       ATH6KL_CFG_SUSPEND_SCHED_SCAN,
 					       NULL);
-		if (ret) {
-			ath6kl_warn("Schedule scan suspend failed: %d", ret);
-			return ret;
-		}
+		if (ret)
+			goto cut_pwr;
+
+		return 0;
+	}
+
+	if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
+	    (!ar->suspend_mode && wow)) {
 
-		ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+		ret = ath6kl_set_sdio_pm_caps(ar);
 		if (ret)
-			ath6kl_warn("set sdio wake irq flag failed: %d\n", ret);
+			goto cut_pwr;
 
-		return ret;
+		ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
+		if (ret)
+			goto cut_pwr;
+
+		return 0;
 	}
 
-	if (wow) {
+	if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
+	    !ar->suspend_mode) {
+
+		flags = sdio_get_host_pm_caps(func);
+		if (!(flags & MMC_PM_KEEP_POWER))
+			goto cut_pwr;
+
+		ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+		if (ret)
+			goto cut_pwr;
+
 		/*
-		 * The host sdio controller is capable of keep power and
-		 * sdio irq wake up at this point. It's fine to continue
-		 * wow suspend operation.
+		 * Workaround to support Deep Sleep with MSM, set the host pm
+		 * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable
+		 * the sdc2_clock and internally allows MSM to enter
+		 * TCXO shutdown properly.
 		 */
-		ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow);
-		if (ret)
-			return ret;
+		if ((flags & MMC_PM_WAKE_SDIO_IRQ)) {
+			ret = sdio_set_host_pm_flags(func,
+						MMC_PM_WAKE_SDIO_IRQ);
+			if (ret)
+				goto cut_pwr;
+		}
 
-		ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
+		ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP,
+					      NULL);
 		if (ret)
-			ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
+			goto cut_pwr;
 
-		return ret;
+		return 0;
 	}
 
-deepsleep:
-	return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL);
+cut_pwr:
+	return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
 }
 
 static int ath6kl_sdio_resume(struct ath6kl *ar)
@@ -1253,6 +1285,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
 	spin_lock_init(&ar_sdio->scat_lock);
 	spin_lock_init(&ar_sdio->wr_async_lock);
 	mutex_init(&ar_sdio->dma_buffer_mutex);
+	mutex_init(&ar_sdio->mtx_irq);
 
 	INIT_LIST_HEAD(&ar_sdio->scat_req);
 	INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
@@ -1263,7 +1296,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
 	for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
 		ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
 
-	ar = ath6kl_core_alloc(&ar_sdio->func->dev);
+	ar = ath6kl_core_create(&ar_sdio->func->dev);
 	if (!ar) {
 		ath6kl_err("Failed to alloc ath6kl core\n");
 		ret = -ENOMEM;
@@ -1293,7 +1326,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
 	return ret;
 
 err_core_alloc:
-	ath6kl_core_free(ar_sdio->ar);
+	ath6kl_core_destroy(ar_sdio->ar);
 err_dma:
 	kfree(ar_sdio->dma_buffer);
 err_hif:
@@ -1316,6 +1349,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
 	cancel_work_sync(&ar_sdio->wr_async_work);
 
 	ath6kl_core_cleanup(ar_sdio->ar);
+	ath6kl_core_destroy(ar_sdio->ar);
 
 	kfree(ar_sdio->dma_buffer);
 	kfree(ar_sdio);
@@ -1332,7 +1366,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = {
 MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
 
 static struct sdio_driver ath6kl_sdio_driver = {
-	.name = "ath6kl",
+	.name = "ath6kl_sdio",
 	.id_table = ath6kl_sdio_devices,
 	.probe = ath6kl_sdio_probe,
 	.remove = ath6kl_sdio_remove,
@@ -1362,19 +1396,19 @@ MODULE_AUTHOR("Atheros Communications, Inc.");
 MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
 MODULE_LICENSE("Dual BSD/GPL");
 
-MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
 MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c
index 381eb66..f0cd61d 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.c
+++ b/drivers/net/wireless/ath/ath6kl/testmode.c
@@ -15,6 +15,7 @@
  */
 
 #include "testmode.h"
+#include "debug.h"
 
 #include <net/netlink.h>
 
@@ -30,7 +31,7 @@ enum ath6kl_tm_attr {
 
 enum ath6kl_tm_cmd {
 	ATH6KL_TM_CMD_TCMD		= 0,
-	ATH6KL_TM_CMD_RX_REPORT		= 1,
+	ATH6KL_TM_CMD_RX_REPORT		= 1,	/* not used anymore */
 };
 
 #define ATH6KL_TM_DATA_MAX_LEN		5000
@@ -41,84 +42,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
 					    .len = ATH6KL_TM_DATA_MAX_LEN },
 };
 
-void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len)
+void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len)
 {
-	if (down_interruptible(&ar->sem))
-		return;
-
-	kfree(ar->tm.rx_report);
-
-	ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
-	ar->tm.rx_report_len = buf_len;
-
-	up(&ar->sem);
-
-	wake_up(&ar->event_wq);
-}
-
-static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len,
-			       struct sk_buff *skb)
-{
-	int ret = 0;
-	long left;
-
-	if (down_interruptible(&ar->sem))
-		return -ERESTARTSYS;
-
-	if (!test_bit(WMI_READY, &ar->flag)) {
-		ret = -EIO;
-		goto out;
-	}
-
-	if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) {
-		up(&ar->sem);
-		return -EIO;
-	}
-
-	left = wait_event_interruptible_timeout(ar->event_wq,
-						ar->tm.rx_report != NULL,
-						WMI_TIMEOUT);
+	struct sk_buff *skb;
 
-	if (left == 0) {
-		ret = -ETIMEDOUT;
-		goto out;
-	} else if (left < 0) {
-		ret = left;
-		goto out;
-	}
+	if (!buf || buf_len == 0)
+		return;
 
-	if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) {
-		ret = -EINVAL;
-		goto out;
+	skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL);
+	if (!skb) {
+		ath6kl_warn("failed to allocate testmode rx skb!\n");
+		return;
 	}
-
-	NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len,
-		ar->tm.rx_report);
-
-	kfree(ar->tm.rx_report);
-	ar->tm.rx_report = NULL;
-
-out:
-	up(&ar->sem);
-
-	return ret;
+	NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD);
+	NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
+	cfg80211_testmode_event(skb, GFP_KERNEL);
+	return;
 
 nla_put_failure:
-	ret = -ENOBUFS;
-	goto out;
+	kfree_skb(skb);
+	ath6kl_warn("nla_put failed on testmode rx skb!\n");
 }
 
 int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
 {
 	struct ath6kl *ar = wiphy_priv(wiphy);
 	struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
-	int err, buf_len, reply_len;
-	struct sk_buff *skb;
+	int err, buf_len;
 	void *buf;
 
 	err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
@@ -143,24 +93,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
 
 		break;
 	case ATH6KL_TM_CMD_RX_REPORT:
-		if (!tb[ATH6KL_TM_ATTR_DATA])
-			return -EINVAL;
-
-		buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
-		buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
-
-		reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN);
-		skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
-		if (!skb)
-			return -ENOMEM;
-
-		err = ath6kl_tm_rx_report(ar, buf, buf_len, skb);
-		if (err < 0) {
-			kfree_skb(skb);
-			return err;
-		}
-
-		return cfg80211_testmode_reply(skb);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h
index 43dffcc..7fd47a6 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.h
+++ b/drivers/net/wireless/ath/ath6kl/testmode.h
@@ -18,13 +18,13 @@
 
 #ifdef CONFIG_NL80211_TESTMODE
 
-void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len);
+void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len);
 int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
 
 #else
 
-static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf,
-					     size_t buf_len)
+static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf,
+				      size_t buf_len)
 {
 }
 
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index 506a303..a3dc694 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -17,6 +17,23 @@
 #include "core.h"
 #include "debug.h"
 
+/*
+ * tid - tid_mux0..tid_mux3
+ * aid - tid_mux4..tid_mux7
+ */
+#define ATH6KL_TID_MASK 0xf
+#define ATH6KL_AID_SHIFT 4
+
+static inline u8 ath6kl_get_tid(u8 tid_mux)
+{
+	return tid_mux & ATH6KL_TID_MASK;
+}
+
+static inline u8 ath6kl_get_aid(u8 tid_mux)
+{
+	return tid_mux >> ATH6KL_AID_SHIFT;
+}
+
 static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
 			       u32 *map_no)
 {
@@ -77,12 +94,118 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
 	return ar->node_map[ep_map].ep_id;
 }
 
+static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
+				struct ath6kl_vif *vif,
+				struct sk_buff *skb,
+				u32 *flags)
+{
+	struct ath6kl *ar = vif->ar;
+	bool is_apsdq_empty = false;
+	struct ethhdr *datap = (struct ethhdr *) skb->data;
+	u8 up = 0, traffic_class, *ip_hdr;
+	u16 ether_type;
+	struct ath6kl_llc_snap_hdr *llc_hdr;
+
+	if (conn->sta_flags & STA_PS_APSD_TRIGGER) {
+		/*
+		 * This tx is because of a uAPSD trigger, determine
+		 * more and EOSP bit. Set EOSP if queue is empty
+		 * or sufficient frames are delivered for this trigger.
+		 */
+		spin_lock_bh(&conn->psq_lock);
+		if (!skb_queue_empty(&conn->apsdq))
+			*flags |= WMI_DATA_HDR_FLAGS_MORE;
+		else if (conn->sta_flags & STA_PS_APSD_EOSP)
+			*flags |= WMI_DATA_HDR_FLAGS_EOSP;
+		*flags |= WMI_DATA_HDR_FLAGS_UAPSD;
+		spin_unlock_bh(&conn->psq_lock);
+		return false;
+	} else if (!conn->apsd_info)
+		return false;
+
+	if (test_bit(WMM_ENABLED, &vif->flags)) {
+		ether_type = be16_to_cpu(datap->h_proto);
+		if (is_ethertype(ether_type)) {
+			/* packet is in DIX format  */
+			ip_hdr = (u8 *)(datap + 1);
+		} else {
+			/* packet is in 802.3 format */
+			llc_hdr = (struct ath6kl_llc_snap_hdr *)
+							(datap + 1);
+			ether_type = be16_to_cpu(llc_hdr->eth_type);
+			ip_hdr = (u8 *)(llc_hdr + 1);
+		}
+
+		if (ether_type == IP_ETHERTYPE)
+			up = ath6kl_wmi_determine_user_priority(
+							ip_hdr, 0);
+	}
+
+	traffic_class = ath6kl_wmi_get_traffic_class(up);
+
+	if ((conn->apsd_info & (1 << traffic_class)) == 0)
+		return false;
+
+	/* Queue the frames if the STA is sleeping */
+	spin_lock_bh(&conn->psq_lock);
+	is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+	skb_queue_tail(&conn->apsdq, skb);
+	spin_unlock_bh(&conn->psq_lock);
+
+	/*
+	 * If this is the first pkt getting queued
+	 * for this STA, update the PVB for this STA
+	 */
+	if (is_apsdq_empty) {
+		ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
+				vif->fw_vif_idx,
+				conn->aid, 1, 0);
+	}
+	*flags |= WMI_DATA_HDR_FLAGS_UAPSD;
+
+	return true;
+}
+
+static bool ath6kl_process_psq(struct ath6kl_sta *conn,
+				struct ath6kl_vif *vif,
+				struct sk_buff *skb,
+				u32 *flags)
+{
+	bool is_psq_empty = false;
+	struct ath6kl *ar = vif->ar;
+
+	if (conn->sta_flags & STA_PS_POLLED) {
+		spin_lock_bh(&conn->psq_lock);
+		if (!skb_queue_empty(&conn->psq))
+			*flags |= WMI_DATA_HDR_FLAGS_MORE;
+		spin_unlock_bh(&conn->psq_lock);
+		return false;
+	}
+
+	/* Queue the frames if the STA is sleeping */
+	spin_lock_bh(&conn->psq_lock);
+	is_psq_empty = skb_queue_empty(&conn->psq);
+	skb_queue_tail(&conn->psq, skb);
+	spin_unlock_bh(&conn->psq_lock);
+
+	/*
+	 * If this is the first pkt getting queued
+	 * for this STA, update the PVB for this
+	 * STA.
+	 */
+	if (is_psq_empty)
+		ath6kl_wmi_set_pvb_cmd(ar->wmi,
+				       vif->fw_vif_idx,
+				       conn->aid, 1);
+	return true;
+}
+
 static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
-				bool *more_data)
+				u32 *flags)
 {
 	struct ethhdr *datap = (struct ethhdr *) skb->data;
 	struct ath6kl_sta *conn = NULL;
-	bool ps_queued = false, is_psq_empty = false;
+	bool ps_queued = false;
 	struct ath6kl *ar = vif->ar;
 
 	if (is_multicast_ether_addr(datap->h_dest)) {
@@ -128,7 +251,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
 				 */
 				spin_lock_bh(&ar->mcastpsq_lock);
 				if (!skb_queue_empty(&ar->mcastpsq))
-					*more_data = true;
+					*flags |= WMI_DATA_HDR_FLAGS_MORE;
 				spin_unlock_bh(&ar->mcastpsq_lock);
 			}
 		}
@@ -142,37 +265,13 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
 		}
 
 		if (conn->sta_flags & STA_PS_SLEEP) {
-			if (!(conn->sta_flags & STA_PS_POLLED)) {
-				/* Queue the frames if the STA is sleeping */
-				spin_lock_bh(&conn->psq_lock);
-				is_psq_empty = skb_queue_empty(&conn->psq);
-				skb_queue_tail(&conn->psq, skb);
-				spin_unlock_bh(&conn->psq_lock);
-
-				/*
-				 * If this is the first pkt getting queued
-				 * for this STA, update the PVB for this
-				 * STA.
-				 */
-				if (is_psq_empty)
-					ath6kl_wmi_set_pvb_cmd(ar->wmi,
-							       vif->fw_vif_idx,
-							       conn->aid, 1);
-
-				ps_queued = true;
-			} else {
-				/*
-				 * This tx is because of a PsPoll.
-				 * Determine if MoreData bit has to be set.
-				 */
-				spin_lock_bh(&conn->psq_lock);
-				if (!skb_queue_empty(&conn->psq))
-					*more_data = true;
-				spin_unlock_bh(&conn->psq_lock);
-			}
+			ps_queued = ath6kl_process_uapsdq(conn,
+						vif, skb, flags);
+			if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD))
+				ps_queued = ath6kl_process_psq(conn,
+						vif, skb, flags);
 		}
 	}
-
 	return ps_queued;
 }
 
@@ -242,8 +341,13 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
 	u32 map_no = 0;
 	u16 htc_tag = ATH6KL_DATA_PKT_TAG;
 	u8 ac = 99 ; /* initialize to unmapped ac */
-	bool chk_adhoc_ps_mapping = false, more_data = false;
+	bool chk_adhoc_ps_mapping = false;
 	int ret;
+	struct wmi_tx_meta_v2 meta_v2;
+	void *meta;
+	u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed;
+	u8 meta_ver = 0;
+	u32 flags = 0;
 
 	ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
 		   "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
@@ -260,11 +364,19 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
 
 	/* AP mode Power saving processing */
 	if (vif->nw_type == AP_NETWORK) {
-		if (ath6kl_powersave_ap(vif, skb, &more_data))
+		if (ath6kl_powersave_ap(vif, skb, &flags))
 			return 0;
 	}
 
 	if (test_bit(WMI_ENABLED, &ar->flag)) {
+		if ((dev->features & NETIF_F_IP_CSUM) &&
+				(csum == CHECKSUM_PARTIAL)) {
+			csum_start = skb->csum_start -
+					(skb_network_header(skb) - skb->head) +
+					sizeof(struct ath6kl_llc_snap_hdr);
+			csum_dest = skb->csum_offset + csum_start;
+		}
+
 		if (skb_headroom(skb) < dev->needed_headroom) {
 			struct sk_buff *tmp_skb = skb;
 
@@ -281,10 +393,28 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
 			goto fail_tx;
 		}
 
-		if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE,
-					    more_data, 0, 0, NULL,
-					    vif->fw_vif_idx)) {
-			ath6kl_err("wmi_data_hdr_add failed\n");
+		if ((dev->features & NETIF_F_IP_CSUM) &&
+				(csum == CHECKSUM_PARTIAL)) {
+			meta_v2.csum_start = csum_start;
+			meta_v2.csum_dest = csum_dest;
+
+			/* instruct target to calculate checksum */
+			meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD;
+			meta_ver = WMI_META_VERSION_2;
+			meta = &meta_v2;
+		} else {
+			meta_ver = 0;
+			meta = NULL;
+		}
+
+		ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb,
+				DATA_MSGTYPE, flags, 0,
+				meta_ver,
+				meta, vif->fw_vif_idx);
+
+		if (ret) {
+			ath6kl_warn("failed to add wmi data header:%d\n"
+				, ret);
 			goto fail_tx;
 		}
 
@@ -449,9 +579,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
 		 * WMI queue with too many commands the only exception to
 		 * this is during testing using endpointping.
 		 */
-		spin_lock_bh(&ar->lock);
 		set_bit(WMI_CTRL_EP_FULL, &ar->flag);
-		spin_unlock_bh(&ar->lock);
 		ath6kl_err("wmi ctrl ep is full\n");
 		return action;
 	}
@@ -479,9 +607,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
 		    action != HTC_SEND_FULL_DROP) {
 			spin_unlock_bh(&ar->list_lock);
 
-			spin_lock_bh(&vif->if_lock);
 			set_bit(NETQ_STOPPED, &vif->flags);
-			spin_unlock_bh(&vif->if_lock);
 			netif_stop_queue(vif->ndev);
 
 			return action;
@@ -710,10 +836,12 @@ static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
 {
 	struct sk_buff *skb = NULL;
 
-	if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2))
-		ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+	if (skb_queue_len(&p_aggr->rx_amsdu_freeq) <
+	    (AGGR_NUM_OF_FREE_NETBUFS >> 2))
+		ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq,
+				     AGGR_NUM_OF_FREE_NETBUFS);
 
-	skb = skb_dequeue(&p_aggr->free_q);
+	skb = skb_dequeue(&p_aggr->rx_amsdu_freeq);
 
 	return skb;
 }
@@ -881,7 +1009,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr,
 	dev_kfree_skb(skb);
 }
 
-static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
+static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
 			    u16 seq_no, u8 order)
 {
 	struct sk_buff *skb;
@@ -890,11 +1018,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
 	u16 idx, idx_end, seq_end;
 	struct rxtid_stats *stats;
 
-	if (!p_aggr)
-		return;
-
-	rxtid = &p_aggr->rx_tid[tid];
-	stats = &p_aggr->stat[tid];
+	rxtid = &agg_conn->rx_tid[tid];
+	stats = &agg_conn->stat[tid];
 
 	idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
 
@@ -923,7 +1048,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
 
 		if (node->skb) {
 			if (node->is_amsdu)
-				aggr_slice_amsdu(p_aggr, rxtid, node->skb);
+				aggr_slice_amsdu(agg_conn->aggr_info, rxtid,
+						 node->skb);
 			else
 				skb_queue_tail(&rxtid->q, node->skb);
 			node->skb = NULL;
@@ -939,10 +1065,10 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
 	stats->num_delivered += skb_queue_len(&rxtid->q);
 
 	while ((skb = skb_dequeue(&rxtid->q)))
-		ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb);
+		ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb);
 }
 
-static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
+static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
 				  u16 seq_no,
 				  bool is_amsdu, struct sk_buff *frame)
 {
@@ -954,18 +1080,18 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 	bool is_queued = false;
 	u16 extended_end;
 
-	rxtid = &agg_info->rx_tid[tid];
-	stats = &agg_info->stat[tid];
+	rxtid = &agg_conn->rx_tid[tid];
+	stats = &agg_conn->stat[tid];
 
 	stats->num_into_aggr++;
 
 	if (!rxtid->aggr) {
 		if (is_amsdu) {
-			aggr_slice_amsdu(agg_info, rxtid, frame);
+			aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame);
 			is_queued = true;
 			stats->num_amsdu++;
 			while ((skb = skb_dequeue(&rxtid->q)))
-				ath6kl_deliver_frames_to_nw_stack(agg_info->dev,
+				ath6kl_deliver_frames_to_nw_stack(agg_conn->dev,
 								  skb);
 		}
 		return is_queued;
@@ -985,7 +1111,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 		     (cur < end || cur > extended_end)) ||
 		    ((end > extended_end) && (cur > extended_end) &&
 		     (cur < end))) {
-			aggr_deque_frms(agg_info, tid, 0, 0);
+			aggr_deque_frms(agg_conn, tid, 0, 0);
 			if (cur >= rxtid->hold_q_sz - 1)
 				rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
 			else
@@ -1002,7 +1128,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 				st = ATH6KL_MAX_SEQ_NO -
 					(rxtid->hold_q_sz - 2 - cur);
 
-			aggr_deque_frms(agg_info, tid, st, 0);
+			aggr_deque_frms(agg_conn, tid, st, 0);
 		}
 
 		stats->num_oow++;
@@ -1041,9 +1167,9 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 
 	spin_unlock_bh(&rxtid->lock);
 
-	aggr_deque_frms(agg_info, tid, 0, 1);
+	aggr_deque_frms(agg_conn, tid, 0, 1);
 
-	if (agg_info->timer_scheduled)
+	if (agg_conn->timer_scheduled)
 		rxtid->progress = true;
 	else
 		for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
@@ -1054,8 +1180,8 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 				 * the frame doesn't remain stuck
 				 * forever.
 				 */
-				agg_info->timer_scheduled = true;
-				mod_timer(&agg_info->timer,
+				agg_conn->timer_scheduled = true;
+				mod_timer(&agg_conn->timer,
 					  (jiffies +
 					   HZ * (AGGR_RX_TIMEOUT) / 1000));
 				rxtid->progress = false;
@@ -1067,6 +1193,76 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
 	return is_queued;
 }
 
+static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
+						 struct ath6kl_sta *conn)
+{
+	struct ath6kl *ar = vif->ar;
+	bool is_apsdq_empty, is_apsdq_empty_at_start;
+	u32 num_frames_to_deliver, flags;
+	struct sk_buff *skb = NULL;
+
+	/*
+	 * If the APSD q for this STA is not empty, dequeue and
+	 * send a pkt from the head of the q. Also update the
+	 * More data bit in the WMI_DATA_HDR if there are
+	 * more pkts for this STA in the APSD q.
+	 * If there are no more pkts for this STA,
+	 * update the APSD bitmap for this STA.
+	 */
+
+	num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) &
+						    ATH6KL_APSD_FRAME_MASK;
+	/*
+	 * Number of frames to send in a service period is
+	 * indicated by the station
+	 * in the QOS_INFO of the association request
+	 * If it is zero, send all frames
+	 */
+	if (!num_frames_to_deliver)
+		num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME;
+
+	spin_lock_bh(&conn->psq_lock);
+	is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+	spin_unlock_bh(&conn->psq_lock);
+	is_apsdq_empty_at_start = is_apsdq_empty;
+
+	while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
+
+		spin_lock_bh(&conn->psq_lock);
+		skb = skb_dequeue(&conn->apsdq);
+		is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+		spin_unlock_bh(&conn->psq_lock);
+
+		/*
+		 * Set the STA flag to Trigger delivery,
+		 * so that the frame will go out
+		 */
+		conn->sta_flags |= STA_PS_APSD_TRIGGER;
+		num_frames_to_deliver--;
+
+		/* Last frame in the service period, set EOSP or queue empty */
+		if ((is_apsdq_empty) || (!num_frames_to_deliver))
+			conn->sta_flags |= STA_PS_APSD_EOSP;
+
+		ath6kl_data_tx(skb, vif->ndev);
+		conn->sta_flags &= ~(STA_PS_APSD_TRIGGER);
+		conn->sta_flags &= ~(STA_PS_APSD_EOSP);
+	}
+
+	if (is_apsdq_empty) {
+		if (is_apsdq_empty_at_start)
+			flags = WMI_AP_APSD_NO_DELIVERY_FRAMES;
+		else
+			flags = 0;
+
+		ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
+				vif->fw_vif_idx,
+				conn->aid, 0, flags);
+	}
+
+	return;
+}
+
 void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 {
 	struct ath6kl *ar = target->dev->ar;
@@ -1078,10 +1274,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 	int status = packet->status;
 	enum htc_endpoint_id ept = packet->endpoint;
 	bool is_amsdu, prev_ps, ps_state = false;
+	bool trig_state = false;
 	struct ath6kl_sta *conn = NULL;
 	struct sk_buff *skb1 = NULL;
 	struct ethhdr *datap = NULL;
 	struct ath6kl_vif *vif;
+	struct aggr_info_conn *aggr_conn;
 	u16 seq_no, offset;
 	u8 tid, if_idx;
 
@@ -1171,6 +1369,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 			      WMI_DATA_HDR_PS_MASK);
 
 		offset = sizeof(struct wmi_data_hdr);
+		trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG);
 
 		switch (meta_type) {
 		case 0:
@@ -1209,18 +1408,36 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 		else
 			conn->sta_flags &= ~STA_PS_SLEEP;
 
+		/* Accept trigger only when the station is in sleep */
+		if ((conn->sta_flags & STA_PS_SLEEP) && trig_state)
+			ath6kl_uapsd_trigger_frame_rx(vif, conn);
+
 		if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
 			if (!(conn->sta_flags & STA_PS_SLEEP)) {
 				struct sk_buff *skbuff = NULL;
+				bool is_apsdq_empty;
 
 				spin_lock_bh(&conn->psq_lock);
-				while ((skbuff = skb_dequeue(&conn->psq))
-				       != NULL) {
+				while ((skbuff = skb_dequeue(&conn->psq))) {
+					spin_unlock_bh(&conn->psq_lock);
+					ath6kl_data_tx(skbuff, vif->ndev);
+					spin_lock_bh(&conn->psq_lock);
+				}
+
+				is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+				while ((skbuff = skb_dequeue(&conn->apsdq))) {
 					spin_unlock_bh(&conn->psq_lock);
 					ath6kl_data_tx(skbuff, vif->ndev);
 					spin_lock_bh(&conn->psq_lock);
 				}
 				spin_unlock_bh(&conn->psq_lock);
+
+				if (!is_apsdq_empty)
+					ath6kl_wmi_set_apsd_bfrd_traf(
+							ar->wmi,
+							vif->fw_vif_idx,
+							conn->aid, 0, 0);
+
 				/* Clear the PVB for this STA */
 				ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
 						       conn->aid, 0);
@@ -1314,11 +1531,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 
 	datap = (struct ethhdr *) skb->data;
 
-	if (is_unicast_ether_addr(datap->h_dest) &&
-	    aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no,
-				  is_amsdu, skb))
-		/* aggregation code will handle the skb */
-		return;
+	if (is_unicast_ether_addr(datap->h_dest)) {
+		if (vif->nw_type == AP_NETWORK) {
+			conn = ath6kl_find_sta(vif, datap->h_source);
+			if (!conn)
+				return;
+			aggr_conn = conn->aggr_conn;
+		} else
+			aggr_conn = vif->aggr_cntxt->aggr_conn;
+
+		if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
+		    is_amsdu, skb)) {
+			/* aggregation code will handle the skb */
+			return;
+		}
+	}
 
 	ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
 }
@@ -1326,13 +1553,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
 static void aggr_timeout(unsigned long arg)
 {
 	u8 i, j;
-	struct aggr_info *p_aggr = (struct aggr_info *) arg;
+	struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg;
 	struct rxtid *rxtid;
 	struct rxtid_stats *stats;
 
 	for (i = 0; i < NUM_OF_TIDS; i++) {
-		rxtid = &p_aggr->rx_tid[i];
-		stats = &p_aggr->stat[i];
+		rxtid = &aggr_conn->rx_tid[i];
+		stats = &aggr_conn->stat[i];
 
 		if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
 			continue;
@@ -1343,18 +1570,18 @@ static void aggr_timeout(unsigned long arg)
 			   rxtid->seq_next,
 			   ((rxtid->seq_next + rxtid->hold_q_sz-1) &
 			    ATH6KL_MAX_SEQ_NO));
-		aggr_deque_frms(p_aggr, i, 0, 0);
+		aggr_deque_frms(aggr_conn, i, 0, 0);
 	}
 
-	p_aggr->timer_scheduled = false;
+	aggr_conn->timer_scheduled = false;
 
 	for (i = 0; i < NUM_OF_TIDS; i++) {
-		rxtid = &p_aggr->rx_tid[i];
+		rxtid = &aggr_conn->rx_tid[i];
 
 		if (rxtid->aggr && rxtid->hold_q) {
 			for (j = 0; j < rxtid->hold_q_sz; j++) {
 				if (rxtid->hold_q[j].skb) {
-					p_aggr->timer_scheduled = true;
+					aggr_conn->timer_scheduled = true;
 					rxtid->timer_mon = true;
 					rxtid->progress = false;
 					break;
@@ -1366,24 +1593,24 @@ static void aggr_timeout(unsigned long arg)
 		}
 	}
 
-	if (p_aggr->timer_scheduled)
-		mod_timer(&p_aggr->timer,
+	if (aggr_conn->timer_scheduled)
+		mod_timer(&aggr_conn->timer,
 			  jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
 }
 
-static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
+static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
 {
 	struct rxtid *rxtid;
 	struct rxtid_stats *stats;
 
-	if (!p_aggr || tid >= NUM_OF_TIDS)
+	if (!aggr_conn || tid >= NUM_OF_TIDS)
 		return;
 
-	rxtid = &p_aggr->rx_tid[tid];
-	stats = &p_aggr->stat[tid];
+	rxtid = &aggr_conn->rx_tid[tid];
+	stats = &aggr_conn->stat[tid];
 
 	if (rxtid->aggr)
-		aggr_deque_frms(p_aggr, tid, 0, 0);
+		aggr_deque_frms(aggr_conn, tid, 0, 0);
 
 	rxtid->aggr = false;
 	rxtid->progress = false;
@@ -1398,26 +1625,40 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
 	memset(stats, 0, sizeof(struct rxtid_stats));
 }
 
-void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
+void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
 			     u8 win_sz)
 {
-	struct aggr_info *p_aggr = vif->aggr_cntxt;
+	struct ath6kl_sta *sta;
+	struct aggr_info_conn *aggr_conn = NULL;
 	struct rxtid *rxtid;
 	struct rxtid_stats *stats;
 	u16 hold_q_size;
+	u8 tid, aid;
 
-	if (!p_aggr)
+	if (vif->nw_type == AP_NETWORK) {
+		aid = ath6kl_get_aid(tid_mux);
+		sta = ath6kl_find_sta_by_aid(vif->ar, aid);
+		if (sta)
+			aggr_conn = sta->aggr_conn;
+	} else
+		aggr_conn = vif->aggr_cntxt->aggr_conn;
+
+	if (!aggr_conn)
+		return;
+
+	tid = ath6kl_get_tid(tid_mux);
+	if (tid >= NUM_OF_TIDS)
 		return;
 
-	rxtid = &p_aggr->rx_tid[tid];
-	stats = &p_aggr->stat[tid];
+	rxtid = &aggr_conn->rx_tid[tid];
+	stats = &aggr_conn->stat[tid];
 
 	if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
 		ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
 			   __func__, win_sz, tid);
 
 	if (rxtid->aggr)
-		aggr_delete_tid_state(p_aggr, tid);
+		aggr_delete_tid_state(aggr_conn, tid);
 
 	rxtid->seq_next = seq_no;
 	hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
@@ -1433,31 +1674,23 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
 	rxtid->aggr = true;
 }
 
-struct aggr_info *aggr_init(struct net_device *dev)
+void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
+		    struct aggr_info_conn *aggr_conn)
 {
-	struct aggr_info *p_aggr = NULL;
 	struct rxtid *rxtid;
 	u8 i;
 
-	p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
-	if (!p_aggr) {
-		ath6kl_err("failed to alloc memory for aggr_node\n");
-		return NULL;
-	}
-
-	p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
-	p_aggr->dev = dev;
-	init_timer(&p_aggr->timer);
-	p_aggr->timer.function = aggr_timeout;
-	p_aggr->timer.data = (unsigned long) p_aggr;
+	aggr_conn->aggr_sz = AGGR_SZ_DEFAULT;
+	aggr_conn->dev = vif->ndev;
+	init_timer(&aggr_conn->timer);
+	aggr_conn->timer.function = aggr_timeout;
+	aggr_conn->timer.data = (unsigned long) aggr_conn;
+	aggr_conn->aggr_info = aggr_info;
 
-	p_aggr->timer_scheduled = false;
-	skb_queue_head_init(&p_aggr->free_q);
-
-	ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+	aggr_conn->timer_scheduled = false;
 
 	for (i = 0; i < NUM_OF_TIDS; i++) {
-		rxtid = &p_aggr->rx_tid[i];
+		rxtid = &aggr_conn->rx_tid[i];
 		rxtid->aggr = false;
 		rxtid->progress = false;
 		rxtid->timer_mon = false;
@@ -1465,29 +1698,75 @@ struct aggr_info *aggr_init(struct net_device *dev)
 		spin_lock_init(&rxtid->lock);
 	}
 
+}
+
+struct aggr_info *aggr_init(struct ath6kl_vif *vif)
+{
+	struct aggr_info *p_aggr = NULL;
+
+	p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
+	if (!p_aggr) {
+		ath6kl_err("failed to alloc memory for aggr_node\n");
+		return NULL;
+	}
+
+	p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
+	if (!p_aggr->aggr_conn) {
+		ath6kl_err("failed to alloc memory for connection specific aggr info\n");
+		kfree(p_aggr);
+		return NULL;
+	}
+
+	aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn);
+
+	skb_queue_head_init(&p_aggr->rx_amsdu_freeq);
+	ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS);
+
 	return p_aggr;
 }
 
-void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid)
+void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux)
 {
-	struct aggr_info *p_aggr = vif->aggr_cntxt;
+	struct ath6kl_sta *sta;
 	struct rxtid *rxtid;
+	struct aggr_info_conn *aggr_conn = NULL;
+	u8 tid, aid;
+
+	if (vif->nw_type == AP_NETWORK) {
+		aid = ath6kl_get_aid(tid_mux);
+		sta = ath6kl_find_sta_by_aid(vif->ar, aid);
+		if (sta)
+			aggr_conn = sta->aggr_conn;
+	} else
+		aggr_conn = vif->aggr_cntxt->aggr_conn;
+
+	if (!aggr_conn)
+		return;
 
-	if (!p_aggr)
+	tid = ath6kl_get_tid(tid_mux);
+	if (tid >= NUM_OF_TIDS)
 		return;
 
-	rxtid = &p_aggr->rx_tid[tid];
+	rxtid = &aggr_conn->rx_tid[tid];
 
 	if (rxtid->aggr)
-		aggr_delete_tid_state(p_aggr, tid);
+		aggr_delete_tid_state(aggr_conn, tid);
 }
 
-void aggr_reset_state(struct aggr_info *aggr_info)
+void aggr_reset_state(struct aggr_info_conn *aggr_conn)
 {
 	u8 tid;
 
+	if (!aggr_conn)
+		return;
+
+	if (aggr_conn->timer_scheduled) {
+		del_timer(&aggr_conn->timer);
+		aggr_conn->timer_scheduled = false;
+	}
+
 	for (tid = 0; tid < NUM_OF_TIDS; tid++)
-		aggr_delete_tid_state(aggr_info, tid);
+		aggr_delete_tid_state(aggr_conn, tid);
 }
 
 /* clean up our amsdu buffer list */
@@ -1514,28 +1793,11 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
 
 void aggr_module_destroy(struct aggr_info *aggr_info)
 {
-	struct rxtid *rxtid;
-	u8 i, k;
-
 	if (!aggr_info)
 		return;
 
-	if (aggr_info->timer_scheduled) {
-		del_timer(&aggr_info->timer);
-		aggr_info->timer_scheduled = false;
-	}
-
-	for (i = 0; i < NUM_OF_TIDS; i++) {
-		rxtid = &aggr_info->rx_tid[i];
-		if (rxtid->hold_q) {
-			for (k = 0; k < rxtid->hold_q_sz; k++)
-				dev_kfree_skb(rxtid->hold_q[k].skb);
-			kfree(rxtid->hold_q);
-		}
-
-		skb_queue_purge(&rxtid->q);
-	}
-
-	skb_queue_purge(&aggr_info->free_q);
+	aggr_reset_state(aggr_info->aggr_conn);
+	skb_queue_purge(&aggr_info->rx_amsdu_freeq);
+	kfree(aggr_info->aggr_conn);
 	kfree(aggr_info);
 }
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
new file mode 100644
index 0000000..c72567c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/usb.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "debug.h"
+#include "core.h"
+
+/* usb device object */
+struct ath6kl_usb {
+	struct usb_device *udev;
+	struct usb_interface *interface;
+	u8 *diag_cmd_buffer;
+	u8 *diag_resp_buffer;
+	struct ath6kl *ar;
+};
+
+/* diagnostic command defnitions */
+#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD        1
+#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP       2
+#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD            3
+#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP           4
+
+#define ATH6KL_USB_CTRL_DIAG_CC_READ               0
+#define ATH6KL_USB_CTRL_DIAG_CC_WRITE              1
+
+struct ath6kl_usb_ctrl_diag_cmd_write {
+	__le32 cmd;
+	__le32 address;
+	__le32 value;
+	__le32 _pad[1];
+} __packed;
+
+struct ath6kl_usb_ctrl_diag_cmd_read {
+	__le32 cmd;
+	__le32 address;
+} __packed;
+
+struct ath6kl_usb_ctrl_diag_resp_read {
+	__le32 value;
+} __packed;
+
+#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write))
+#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read))
+
+static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
+{
+	usb_set_intfdata(ar_usb->interface, NULL);
+
+	kfree(ar_usb->diag_cmd_buffer);
+	kfree(ar_usb->diag_resp_buffer);
+
+	kfree(ar_usb);
+}
+
+static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
+{
+	struct ath6kl_usb *ar_usb = NULL;
+	struct usb_device *dev = interface_to_usbdev(interface);
+	int status = 0;
+
+	ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
+	if (ar_usb == NULL)
+		goto fail_ath6kl_usb_create;
+
+	memset(ar_usb, 0, sizeof(struct ath6kl_usb));
+	usb_set_intfdata(interface, ar_usb);
+	ar_usb->udev = dev;
+	ar_usb->interface = interface;
+
+	ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL);
+	if (ar_usb->diag_cmd_buffer == NULL) {
+		status = -ENOMEM;
+		goto fail_ath6kl_usb_create;
+	}
+
+	ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP,
+					   GFP_KERNEL);
+	if (ar_usb->diag_resp_buffer == NULL) {
+		status = -ENOMEM;
+		goto fail_ath6kl_usb_create;
+	}
+
+fail_ath6kl_usb_create:
+	if (status != 0) {
+		ath6kl_usb_destroy(ar_usb);
+		ar_usb = NULL;
+	}
+	return ar_usb;
+}
+
+static void ath6kl_usb_device_detached(struct usb_interface *interface)
+{
+	struct ath6kl_usb *ar_usb;
+
+	ar_usb = usb_get_intfdata(interface);
+	if (ar_usb == NULL)
+		return;
+
+	ath6kl_stop_txrx(ar_usb->ar);
+
+	ath6kl_core_cleanup(ar_usb->ar);
+
+	ath6kl_usb_destroy(ar_usb);
+}
+
+static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
+				   u8 req, u16 value, u16 index, void *data,
+				   u32 size)
+{
+	u8 *buf = NULL;
+	int ret;
+
+	if (size > 0) {
+		buf = kmalloc(size, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+
+		memcpy(buf, data, size);
+	}
+
+	/* note: if successful returns number of bytes transfered */
+	ret = usb_control_msg(ar_usb->udev,
+			      usb_sndctrlpipe(ar_usb->udev, 0),
+			      req,
+			      USB_DIR_OUT | USB_TYPE_VENDOR |
+			      USB_RECIP_DEVICE, value, index, buf,
+			      size, 1000);
+
+	if (ret < 0) {
+		ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
+			   __func__, ret);
+	}
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
+				  u8 req, u16 value, u16 index, void *data,
+				  u32 size)
+{
+	u8 *buf = NULL;
+	int ret;
+
+	if (size > 0) {
+		buf = kmalloc(size, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+	}
+
+	/* note: if successful returns number of bytes transfered */
+	ret = usb_control_msg(ar_usb->udev,
+				 usb_rcvctrlpipe(ar_usb->udev, 0),
+				 req,
+				 USB_DIR_IN | USB_TYPE_VENDOR |
+				 USB_RECIP_DEVICE, value, index, buf,
+				 size, 2 * HZ);
+
+	if (ret < 0) {
+		ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
+			   __func__, ret);
+	}
+
+	memcpy((u8 *) data, buf, size);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb,
+				     u8 req_val, u8 *req_buf, u32 req_len,
+				     u8 resp_val, u8 *resp_buf, u32 *resp_len)
+{
+	int ret;
+
+	/* send command */
+	ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0,
+					 req_buf, req_len);
+
+	if (ret != 0)
+		return ret;
+
+	if (resp_buf == NULL) {
+		/* no expected response */
+		return ret;
+	}
+
+	/* get response */
+	ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0,
+					resp_buf, *resp_len);
+
+	return ret;
+}
+
+static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
+{
+	struct ath6kl_usb *ar_usb = ar->hif_priv;
+	struct ath6kl_usb_ctrl_diag_resp_read *resp;
+	struct ath6kl_usb_ctrl_diag_cmd_read *cmd;
+	u32 resp_len;
+	int ret;
+
+	cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer;
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ;
+	cmd->address = cpu_to_le32(address);
+	resp_len = sizeof(*resp);
+
+	ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
+				ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
+				(u8 *) cmd,
+				sizeof(struct ath6kl_usb_ctrl_diag_cmd_write),
+				ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
+				ar_usb->diag_resp_buffer, &resp_len);
+
+	if (ret)
+		return ret;
+
+	resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
+		ar_usb->diag_resp_buffer;
+
+	*data = le32_to_cpu(resp->value);
+
+	return ret;
+}
+
+static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
+{
+	struct ath6kl_usb *ar_usb = ar->hif_priv;
+	struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
+
+	cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
+
+	memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write));
+	cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE);
+	cmd->address = cpu_to_le32(address);
+	cmd->value = data;
+
+	return ath6kl_usb_ctrl_msg_exchange(ar_usb,
+					    ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
+					    (u8 *) cmd,
+					    sizeof(*cmd),
+					    0, NULL, NULL);
+
+}
+
+static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
+{
+	struct ath6kl_usb *ar_usb = ar->hif_priv;
+	int ret;
+
+	/* get response */
+	ret = ath6kl_usb_submit_ctrl_in(ar_usb,
+					ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
+					0, 0, buf, len);
+	if (ret != 0) {
+		ath6kl_err("Unable to read the bmi data from the device: %d\n",
+			   ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
+{
+	struct ath6kl_usb *ar_usb = ar->hif_priv;
+	int ret;
+
+	/* send command */
+	ret = ath6kl_usb_submit_ctrl_out(ar_usb,
+					 ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
+					 0, 0, buf, len);
+	if (ret != 0) {
+		ath6kl_err("unable to send the bmi data to the device: %d\n",
+			   ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ath6kl_usb_power_on(struct ath6kl *ar)
+{
+	return 0;
+}
+
+static int ath6kl_usb_power_off(struct ath6kl *ar)
+{
+	return 0;
+}
+
+static const struct ath6kl_hif_ops ath6kl_usb_ops = {
+	.diag_read32 = ath6kl_usb_diag_read32,
+	.diag_write32 = ath6kl_usb_diag_write32,
+	.bmi_read = ath6kl_usb_bmi_read,
+	.bmi_write = ath6kl_usb_bmi_write,
+	.power_on = ath6kl_usb_power_on,
+	.power_off = ath6kl_usb_power_off,
+};
+
+/* ath6kl usb driver registered functions */
+static int ath6kl_usb_probe(struct usb_interface *interface,
+			    const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(interface);
+	struct ath6kl *ar;
+	struct ath6kl_usb *ar_usb = NULL;
+	int vendor_id, product_id;
+	int ret = 0;
+
+	usb_get_dev(dev);
+
+	vendor_id = le16_to_cpu(dev->descriptor.idVendor);
+	product_id = le16_to_cpu(dev->descriptor.idProduct);
+
+	ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id);
+	ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id);
+
+	if (interface->cur_altsetting)
+		ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n",
+			   interface->cur_altsetting->desc.bInterfaceNumber);
+
+
+	if (dev->speed == USB_SPEED_HIGH)
+		ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n");
+	else
+		ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n");
+
+	ar_usb = ath6kl_usb_create(interface);
+
+	if (ar_usb == NULL) {
+		ret = -ENOMEM;
+		goto err_usb_put;
+	}
+
+	ar = ath6kl_core_create(&ar_usb->udev->dev);
+	if (ar == NULL) {
+		ath6kl_err("Failed to alloc ath6kl core\n");
+		ret = -ENOMEM;
+		goto err_usb_destroy;
+	}
+
+	ar->hif_priv = ar_usb;
+	ar->hif_type = ATH6KL_HIF_TYPE_USB;
+	ar->hif_ops = &ath6kl_usb_ops;
+	ar->mbox_info.block_size = 16;
+	ar->bmi.max_data_size = 252;
+
+	ar_usb->ar = ar;
+
+	ret = ath6kl_core_init(ar);
+	if (ret) {
+		ath6kl_err("Failed to init ath6kl core: %d\n", ret);
+		goto err_core_free;
+	}
+
+	return ret;
+
+err_core_free:
+	ath6kl_core_destroy(ar);
+err_usb_destroy:
+	ath6kl_usb_destroy(ar_usb);
+err_usb_put:
+	usb_put_dev(dev);
+
+	return ret;
+}
+
+static void ath6kl_usb_remove(struct usb_interface *interface)
+{
+	usb_put_dev(interface_to_usbdev(interface));
+	ath6kl_usb_device_detached(interface);
+}
+
+/* table of devices that work with this driver */
+static struct usb_device_id ath6kl_usb_ids[] = {
+	{USB_DEVICE(0x0cf3, 0x9374)},
+	{ /* Terminating entry */ },
+};
+
+MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
+
+static struct usb_driver ath6kl_usb_driver = {
+	.name = "ath6kl_usb",
+	.probe = ath6kl_usb_probe,
+	.disconnect = ath6kl_usb_remove,
+	.id_table = ath6kl_usb_ids,
+};
+
+static int ath6kl_usb_init(void)
+{
+	usb_register(&ath6kl_usb_driver);
+	return 0;
+}
+
+static void ath6kl_usb_exit(void)
+{
+	usb_deregister(&ath6kl_usb_driver);
+}
+
+module_init(ath6kl_usb_init);
+module_exit(ath6kl_usb_exit);
+
+MODULE_AUTHOR("Atheros Communications, Inc.");
+MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index f6f2aa2..18fa9aa 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -180,7 +180,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
 }
 
 int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
-			    u8 msg_type, bool more_data,
+			    u8 msg_type, u32 flags,
 			    enum wmi_data_hdr_data_type data_type,
 			    u8 meta_ver, void *tx_meta_info, u8 if_idx)
 {
@@ -204,17 +204,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
 	data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
 	data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
 
-	if (more_data)
-		data_hdr->info |=
-		    WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
+	if (flags & WMI_DATA_HDR_FLAGS_MORE)
+		data_hdr->info |= WMI_DATA_HDR_MORE;
 
-	data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
-	data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
+	if (flags & WMI_DATA_HDR_FLAGS_EOSP)
+		data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP);
+
+	data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
+	data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
 
 	return 0;
 }
 
-static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
+u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
 {
 	struct iphdr *ip_hdr = (struct iphdr *) pkt;
 	u8 ip_pri;
@@ -236,6 +238,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
 		return ip_pri;
 }
 
+u8 ath6kl_wmi_get_traffic_class(u8 user_priority)
+{
+	return  up_to_ac[user_priority & 0x7];
+}
+
 int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
 				       struct sk_buff *skb,
 				       u32 layer2_priority, bool wmm_enabled,
@@ -419,9 +426,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
 	ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
 		   evt->num_msg, evt->msg_len, evt->msg_type);
 
-	if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
-		return 0;
-
 	for (index = 0; index < evt->num_msg; index++) {
 		size = sizeof(struct wmi_tx_complete_event) +
 		    (index * sizeof(struct tx_complete_msg_v1));
@@ -786,12 +790,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
 				   ev->u.ap_sta.keymgmt,
 				   le16_to_cpu(ev->u.ap_sta.cipher),
 				   ev->u.ap_sta.apsd_info);
+
 			ath6kl_connect_ap_mode_sta(
 				vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
 				ev->u.ap_sta.keymgmt,
 				le16_to_cpu(ev->u.ap_sta.cipher),
 				ev->u.ap_sta.auth, ev->assoc_req_len,
-				ev->assoc_info + ev->beacon_ie_len);
+				ev->assoc_info + ev->beacon_ie_len,
+				ev->u.ap_sta.apsd_info);
 		}
 		return 0;
 	}
@@ -1145,9 +1151,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
 	return 0;
 }
 
-static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len)
+static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len)
 {
-	ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len);
+	ath6kl_tm_rx_event(wmi->parent_dev, datap, len);
 
 	return 0;
 }
@@ -2479,15 +2485,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
 	return ret;
 }
 
-int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
+			  __be32 ips0, __be32 ips1)
 {
 	struct sk_buff *skb;
 	struct wmi_set_ip_cmd *cmd;
 	int ret;
 
 	/* Multicast address are not valid */
-	if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) ||
-	    (*((u8 *) &ip_cmd->ips[1]) >= 0xE0))
+	if (ipv4_is_multicast(ips0) ||
+	    ipv4_is_multicast(ips1))
 		return -EINVAL;
 
 	skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
@@ -2495,9 +2502,10 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
 		return -ENOMEM;
 
 	cmd = (struct wmi_set_ip_cmd *) skb->data;
-	memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd));
+	cmd->ips[0] = ips0;
+	cmd->ips[1] = ips1;
 
-	ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID,
+	ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID,
 				  NO_SYNC_WMIFLAG);
 	return ret;
 }
@@ -2582,6 +2590,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
 	return ret;
 }
 
+/* This command has zero length payload */
+static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi,
+						      struct ath6kl_vif *vif)
+{
+	struct ath6kl *ar = wmi->parent_dev;
+
+	set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
+	wake_up(&ar->event_wq);
+
+	return 0;
+}
+
 int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
 				enum ath6kl_wow_mode wow_mode,
 				u32 filter, u16 host_req_delay)
@@ -2612,7 +2632,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
 
 int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
 				   u8 list_id, u8 filter_size,
-				   u8 filter_offset, u8 *filter, u8 *mask)
+				   u8 filter_offset, const u8 *filter,
+				   const u8 *mask)
 {
 	struct sk_buff *skb;
 	struct wmi_add_wow_pattern_cmd *cmd;
@@ -2853,6 +2874,51 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
 	return ret;
 }
 
+int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on)
+{
+	struct sk_buff *skb;
+	struct wmi_mcast_filter_cmd *cmd;
+	int ret;
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_mcast_filter_cmd *) skb->data;
+	cmd->mcast_all_enable = mc_all_on;
+
+	ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID,
+				  NO_SYNC_WMIFLAG);
+	return ret;
+}
+
+int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
+					u8 *filter, bool add_filter)
+{
+	struct sk_buff *skb;
+	struct wmi_mcast_filter_add_del_cmd *cmd;
+	int ret;
+
+	if ((filter[0] != 0x33 || filter[1] != 0x33) &&
+	    (filter[0] != 0x01 || filter[1] != 0x00 ||
+	    filter[2] != 0x5e || filter[3] > 0x7f)) {
+		ath6kl_warn("invalid multicast filter address\n");
+		return -EINVAL;
+	}
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data;
+	memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
+	ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+				  add_filter ? WMI_SET_MCAST_FILTER_CMDID :
+				  WMI_DEL_MCAST_FILTER_CMDID,
+				  NO_SYNC_WMIFLAG);
+
+	return ret;
+}
 
 s32 ath6kl_wmi_get_rate(s8 rate_index)
 {
@@ -2946,6 +3012,43 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
 				   NO_SYNC_WMIFLAG);
 }
 
+/* This command will be used to enable/disable AP uAPSD feature */
+int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
+{
+	struct wmi_ap_set_apsd_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_ap_set_apsd_cmd *)skb->data;
+	cmd->enable = enable;
+
+	return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID,
+				   NO_SYNC_WMIFLAG);
+}
+
+int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx,
+					     u16 aid, u16 bitmap, u32 flags)
+{
+	struct wmi_ap_apsd_buffered_traffic_cmd *cmd;
+	struct sk_buff *skb;
+
+	skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+	if (!skb)
+		return -ENOMEM;
+
+	cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data;
+	cmd->aid = cpu_to_le16(aid);
+	cmd->bitmap = cpu_to_le16(bitmap);
+	cmd->flags = cpu_to_le32(flags);
+
+	return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
+				   WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
+				   NO_SYNC_WMIFLAG);
+}
+
 static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len,
 				      struct ath6kl_vif *vif)
 {
@@ -3400,7 +3503,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
 		break;
 	case WMI_TEST_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
-		ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len);
+		ret = ath6kl_wmi_test_rx(wmi, datap, len);
 		break;
 	case WMI_GET_FIXRATES_CMDID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
@@ -3465,6 +3568,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
 		ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
 		break;
+	case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
+		ath6kl_dbg(ATH6KL_DBG_WMI,
+			   "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
+		ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
+		break;
 	case WMI_REMAIN_ON_CHNL_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
 		ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 42ac311..e791986 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -149,8 +149,7 @@ enum wmi_msg_type {
 #define WMI_DATA_HDR_PS_MASK        0x1
 #define WMI_DATA_HDR_PS_SHIFT       5
 
-#define WMI_DATA_HDR_MORE_MASK      0x1
-#define WMI_DATA_HDR_MORE_SHIFT     5
+#define WMI_DATA_HDR_MORE	0x20
 
 enum wmi_data_hdr_data_type {
 	WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
@@ -160,6 +159,13 @@ enum wmi_data_hdr_data_type {
 	WMI_DATA_HDR_DATA_TYPE_ACL,
 };
 
+/* Bitmap of data header flags */
+enum wmi_data_hdr_flags {
+	WMI_DATA_HDR_FLAGS_MORE = 0x1,
+	WMI_DATA_HDR_FLAGS_EOSP = 0x2,
+	WMI_DATA_HDR_FLAGS_UAPSD = 0x4,
+};
+
 #define WMI_DATA_HDR_DATA_TYPE_MASK     0x3
 #define WMI_DATA_HDR_DATA_TYPE_SHIFT    6
 
@@ -173,8 +179,12 @@ enum wmi_data_hdr_data_type {
 #define WMI_DATA_HDR_META_MASK      0x7
 #define WMI_DATA_HDR_META_SHIFT     13
 
+/* Macros for operating on WMI_DATA_HDR (info3) field */
 #define WMI_DATA_HDR_IF_IDX_MASK    0xF
 
+#define WMI_DATA_HDR_TRIG	    0x10
+#define WMI_DATA_HDR_EOSP	    0x10
+
 struct wmi_data_hdr {
 	s8 rssi;
 
@@ -203,7 +213,8 @@ struct wmi_data_hdr {
 	/*
 	 * usage of info3, 16-bit:
 	 * b3:b0	- Interface index
-	 * b15:b4	- Reserved
+	 * b4		- uAPSD trigger in rx & EOSP in tx
+	 * b15:b5	- Reserved
 	 */
 	__le16 info3;
 } __packed;
@@ -257,6 +268,9 @@ static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr)
 #define WMI_META_VERSION_1	0x01
 #define WMI_META_VERSION_2	0x02
 
+/* Flag to signal to FW to calculate TCP checksum */
+#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01
+
 struct wmi_tx_meta_v1 {
 	/* packet ID to identify the tx request */
 	u8 pkt_id;
@@ -646,7 +660,6 @@ enum auth_mode {
 	WPA2_AUTH_CCKM = 0x40,
 };
 
-#define WMI_MIN_KEY_INDEX   0
 #define WMI_MAX_KEY_INDEX   3
 
 #define WMI_MAX_KEY_LEN     32
@@ -1237,6 +1250,15 @@ enum target_event_report_config {
 	NO_DISCONN_EVT_IN_RECONN
 };
 
+struct wmi_mcast_filter_cmd {
+	u8 mcast_all_enable;
+} __packed;
+
+#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6
+struct wmi_mcast_filter_add_del_cmd {
+	u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
+} __packed;
+
 /* Command Replies */
 
 /* WMI_GET_CHANNEL_LIST_CMDID reply */
@@ -1335,6 +1357,8 @@ enum wmi_event_id {
 	WMI_P2P_START_SDPD_EVENTID,
 	WMI_P2P_SDPD_RX_EVENTID,
 
+	WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047,
+
 	WMI_THIN_RESERVED_START_EVENTID = 0x8000,
 	/* Events in this range are reserved for thinmode */
 	WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
@@ -1903,7 +1927,7 @@ struct wow_filter {
 
 struct wmi_set_ip_cmd {
 	/* IP in network byte order */
-	__le32 ips[MAX_IP_ADDRS];
+	__be32 ips[MAX_IP_ADDRS];
 } __packed;
 
 enum ath6kl_wow_filters {
@@ -2105,6 +2129,19 @@ struct wmi_rx_frame_format_cmd {
 } __packed;
 
 /* AP mode events */
+struct wmi_ap_set_apsd_cmd {
+	u8 enable;
+} __packed;
+
+enum wmi_ap_apsd_buffered_traffic_flags {
+	WMI_AP_APSD_NO_DELIVERY_FRAMES =  0x1,
+};
+
+struct wmi_ap_apsd_buffered_traffic_cmd {
+	__le16 aid;
+	__le16 bitmap;
+	__le32 flags;
+} __packed;
 
 /* WMI_PS_POLL_EVENT */
 struct wmi_pspoll_event {
@@ -2321,7 +2358,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
 void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
 int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
 int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
-			    u8 msg_type, bool more_data,
+			    u8 msg_type, u32 flags,
 			    enum wmi_data_hdr_data_type data_type,
 			    u8 meta_ver, void *tx_meta_info, u8 if_idx);
 
@@ -2417,7 +2454,8 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
 
 s32 ath6kl_wmi_get_rate(s8 rate_index);
 
-int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
+			  __be32 ips0, __be32 ips1);
 int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
 				       enum ath6kl_host_mode host_mode);
 int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
@@ -2425,13 +2463,26 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
 				u32 filter, u16 host_req_delay);
 int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
 				   u8 list_id, u8 filter_size,
-				   u8 filter_offset, u8 *filter, u8 *mask);
+				   u8 filter_offset, const u8 *filter,
+				   const u8 *mask);
 int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
 				   u16 list_id, u16 filter_id);
 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
 int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
 int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
+int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
+int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
+					u8 *filter, bool add_filter);
+/* AP mode uAPSD */
+int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
+
+int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi,
+						u8 if_idx, u16 aid,
+						u16 bitmap, u32 flags);
+
+u8 ath6kl_wmi_get_traffic_class(u8 user_priority);
 
+u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri);
 /* AP mode */
 int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
 				 struct wmi_connect_cmd *p);
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index bc56f57..7e0ea4e 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -407,20 +407,20 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
 			if (aniState->ofdmWeakSigDetectOff) {
 				if (ath9k_hw_ani_control(ah,
 					 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-					 true) == true)
+					 true))
 					return;
 			}
 			if (aniState->firstepLevel > 0) {
 				if (ath9k_hw_ani_control(ah,
 					 ATH9K_ANI_FIRSTEP_LEVEL,
-					 aniState->firstepLevel - 1) == true)
+					 aniState->firstepLevel - 1))
 					return;
 			}
 		} else {
 			if (aniState->firstepLevel > 0) {
 				if (ath9k_hw_ani_control(ah,
 					 ATH9K_ANI_FIRSTEP_LEVEL,
-					 aniState->firstepLevel - 1) == true)
+					 aniState->firstepLevel - 1))
 					return;
 			}
 		}
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index f901a17..86a891f 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -489,8 +489,6 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)
 	ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows);
 	ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows);
 	ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows);
-	ATH_ALLOC_BANK(ah->addac5416_21,
-		       ah->iniAddac.ia_rows * ah->iniAddac.ia_columns);
 	ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows);
 
 	return 0;
@@ -519,7 +517,6 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah)
 	ATH_FREE_BANK(ah->analogBank6Data);
 	ATH_FREE_BANK(ah->analogBank6TPCData);
 	ATH_FREE_BANK(ah->analogBank7Data);
-	ATH_FREE_BANK(ah->addac5416_21);
 	ATH_FREE_BANK(ah->bank6Temp);
 
 #undef ATH_FREE_BANK
@@ -805,27 +802,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
 	if (ah->eep_ops->set_addac)
 		ah->eep_ops->set_addac(ah, chan);
 
-	if (AR_SREV_5416_22_OR_LATER(ah)) {
-		REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
-	} else {
-		struct ar5416IniArray temp;
-		u32 addacSize =
-			sizeof(u32) * ah->iniAddac.ia_rows *
-			ah->iniAddac.ia_columns;
-
-		/* For AR5416 2.0/2.1 */
-		memcpy(ah->addac5416_21,
-		       ah->iniAddac.ia_array, addacSize);
-
-		/* override CLKDRV value at [row, column] = [31, 1] */
-		(ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
-
-		temp.ia_array = ah->addac5416_21;
-		temp.ia_columns = ah->iniAddac.ia_columns;
-		temp.ia_rows = ah->iniAddac.ia_rows;
-		REG_WRITE_ARRAY(&temp, 1, regWrites);
-	}
-
+	REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
 	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
 
 	ENABLE_REGWRITE_BUFFER(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index 11f192a..d190411 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -180,6 +180,25 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
 		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
 			       ARRAY_SIZE(ar5416Addac), 2);
 	}
+
+	/* iniAddac needs to be modified for these chips */
+	if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) {
+		struct ar5416IniArray *addac = &ah->iniAddac;
+		u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns;
+		u32 *data;
+
+		data = kmalloc(size, GFP_KERNEL);
+		if (!data)
+			return;
+
+		memcpy(data, addac->ia_array, size);
+		addac->ia_array = data;
+
+		if (!AR_SREV_5416_22_OR_LATER(ah)) {
+			/* override CLKDRV value */
+			INI_RA(addac, 31,1) = 0;
+		}
+	}
 }
 
 /* Support for Japan ch.14 (2484) spread */
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 77c8ded..424aabb 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
 	ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
 }
 
-static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
-				     u32 drv_info)
+static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
 {
 	int transfer, err;
 	const void *data = hif_dev->firmware->data;
@@ -982,7 +981,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
 		return -ENOMEM;
 
 	while (len) {
-		transfer = min_t(int, len, 4096);
+		transfer = min_t(size_t, len, 4096);
 		memcpy(buf, data, transfer);
 
 		err = usb_control_msg(hif_dev->udev,
@@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
 	}
 	kfree(buf);
 
-	if (IS_AR7010_DEVICE(drv_info))
+	if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
 		firm_offset = AR7010_FIRMWARE_TEXT;
 	else
 		firm_offset = AR9271_FIRMWARE_TEXT;
@@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
 	return 0;
 }
 
-static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
+static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
 {
-	int ret, idx;
 	struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
 	struct usb_endpoint_descriptor *endp;
+	int ret, idx;
 
-	/* Request firmware */
-	ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
-			       &hif_dev->udev->dev);
-	if (ret) {
-		dev_err(&hif_dev->udev->dev,
-			"ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name);
-		goto err_fw_req;
-	}
-
-	/* Download firmware */
-	ret = ath9k_hif_usb_download_fw(hif_dev, drv_info);
+	ret = ath9k_hif_usb_download_fw(hif_dev);
 	if (ret) {
 		dev_err(&hif_dev->udev->dev,
 			"ath9k_htc: Firmware - %s download failed\n",
 			hif_dev->fw_name);
-		goto err_fw_download;
+		return ret;
 	}
 
 	/* On downloading the firmware to the target, the USB descriptor of EP4
@@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
 	if (ret) {
 		dev_err(&hif_dev->udev->dev,
 			"ath9k_htc: Unable to allocate URBs\n");
-		goto err_fw_download;
+		return ret;
 	}
 
 	return 0;
-
-err_fw_download:
-	release_firmware(hif_dev->firmware);
-err_fw_req:
-	hif_dev->firmware = NULL;
-	return ret;
 }
 
 static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
 {
 	ath9k_hif_usb_dealloc_urbs(hif_dev);
-	if (hif_dev->firmware)
-		release_firmware(hif_dev->firmware);
+}
+
+/*
+ * If initialization fails or the FW cannot be retrieved,
+ * detach the device.
+ */
+static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev)
+{
+	struct device *parent = hif_dev->udev->dev.parent;
+
+	complete(&hif_dev->fw_done);
+
+	if (parent)
+		device_lock(parent);
+
+	device_release_driver(&hif_dev->udev->dev);
+
+	if (parent)
+		device_unlock(parent);
+}
+
+static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
+{
+	struct hif_device_usb *hif_dev = context;
+	int ret;
+
+	if (!fw) {
+		dev_err(&hif_dev->udev->dev,
+			"ath9k_htc: Failed to get firmware %s\n",
+			hif_dev->fw_name);
+		goto err_fw;
+	}
+
+	hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
+						 &hif_dev->udev->dev);
+	if (hif_dev->htc_handle == NULL) {
+		goto err_fw;
+	}
+
+	hif_dev->firmware = fw;
+
+	/* Proceed with initialization */
+
+	ret = ath9k_hif_usb_dev_init(hif_dev);
+	if (ret)
+		goto err_dev_init;
+
+	ret = ath9k_htc_hw_init(hif_dev->htc_handle,
+				&hif_dev->interface->dev,
+				hif_dev->usb_device_id->idProduct,
+				hif_dev->udev->product,
+				hif_dev->usb_device_id->driver_info);
+	if (ret) {
+		ret = -EINVAL;
+		goto err_htc_hw_init;
+	}
+
+	complete(&hif_dev->fw_done);
+
+	return;
+
+err_htc_hw_init:
+	ath9k_hif_usb_dev_deinit(hif_dev);
+err_dev_init:
+	ath9k_htc_hw_free(hif_dev->htc_handle);
+	release_firmware(fw);
+	hif_dev->firmware = NULL;
+err_fw:
+	ath9k_hif_usb_firmware_fail(hif_dev);
 }
 
 /*
@@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
 	}
 
 	usb_get_dev(udev);
+
 	hif_dev->udev = udev;
 	hif_dev->interface = interface;
-	hif_dev->device_id = id->idProduct;
+	hif_dev->usb_device_id = id;
 #ifdef CONFIG_PM
 	udev->reset_resume = 1;
 #endif
 	usb_set_intfdata(interface, hif_dev);
 
-	hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
-						 &hif_dev->udev->dev);
-	if (hif_dev->htc_handle == NULL) {
-		ret = -ENOMEM;
-		goto err_htc_hw_alloc;
-	}
+	init_completion(&hif_dev->fw_done);
 
 	/* Find out which firmware to load */
 
@@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
 	else
 		hif_dev->fw_name = FIRMWARE_AR9271;
 
-	ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info);
-	if (ret) {
-		ret = -EINVAL;
-		goto err_hif_init_usb;
-	}
-
-	ret = ath9k_htc_hw_init(hif_dev->htc_handle,
-				&interface->dev, hif_dev->device_id,
-				hif_dev->udev->product, id->driver_info);
+	ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name,
+				      &hif_dev->udev->dev, GFP_KERNEL,
+				      hif_dev, ath9k_hif_usb_firmware_cb);
 	if (ret) {
-		ret = -EINVAL;
-		goto err_htc_hw_init;
+		dev_err(&hif_dev->udev->dev,
+			"ath9k_htc: Async request for firmware %s failed\n",
+			hif_dev->fw_name);
+		goto err_fw_req;
 	}
 
-	dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
+	dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n",
+		 hif_dev->fw_name);
 
 	return 0;
 
-err_htc_hw_init:
-	ath9k_hif_usb_dev_deinit(hif_dev);
-err_hif_init_usb:
-	ath9k_htc_hw_free(hif_dev->htc_handle);
-err_htc_hw_alloc:
+err_fw_req:
 	usb_set_intfdata(interface, NULL);
 	kfree(hif_dev);
 	usb_put_dev(udev);
@@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
 	if (!hif_dev)
 		return;
 
-	ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
-	ath9k_htc_hw_free(hif_dev->htc_handle);
-	ath9k_hif_usb_dev_deinit(hif_dev);
+	wait_for_completion(&hif_dev->fw_done);
+
+	if (hif_dev->firmware) {
+		ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
+		ath9k_htc_hw_free(hif_dev->htc_handle);
+		ath9k_hif_usb_dev_deinit(hif_dev);
+		release_firmware(hif_dev->firmware);
+	}
+
 	usb_set_intfdata(interface, NULL);
 
 	if (!unplugged && (hif_dev->flags & HIF_USB_START))
@@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
 		return ret;
 
 	if (hif_dev->firmware) {
-		ret = ath9k_hif_usb_download_fw(hif_dev,
-				htc_handle->drv_priv->ah->hw_version.usbdev);
+		ret = ath9k_hif_usb_download_fw(hif_dev);
 		if (ret)
 			goto fail_resume;
 	} else {
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 794f630..487ff65 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -87,10 +87,11 @@ struct cmd_buf {
 #define HIF_USB_START BIT(0)
 
 struct hif_device_usb {
-	u16 device_id;
 	struct usb_device *udev;
 	struct usb_interface *interface;
+	const struct usb_device_id *usb_device_id;
 	const struct firmware *firmware;
+	struct completion fw_done;
 	struct htc_target *htc_handle;
 	struct hif_usb_tx tx;
 	struct usb_anchor regout_submitted;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 9be10a2..fc7519c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -741,6 +741,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
 
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
+	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
 	hw->queues = 4;
 	hw->channel_change_time = 5000;
 	hw->max_listen_interval = 10;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index ef4c606..06101b6 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1409,6 +1409,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
 	if (htc_modparam_nohwcrypt)
 		return -ENOSPC;
 
+	if ((vif->type == NL80211_IFTYPE_ADHOC ||
+	     vif->type == NL80211_IFTYPE_MESH_POINT) &&
+	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
+	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
+	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+		/*
+		 * For now, disable hw crypto for the RSN IBSS group keys. This
+		 * could be optimized in the future to use a modified key cache
+		 * design to support per-STA RX GTK, but until that gets
+		 * implemented, use of software crypto for group addressed
+		 * frames is a acceptable to allow RSN IBSS to be used.
+		 */
+		return -EOPNOTSUPP;
+	}
+
 	mutex_lock(&priv->mutex);
 	ath_dbg(common, CONFIG, "Set HW Key\n");
 	ath9k_htc_ps_wakeup(priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 1b90ed8..c25226a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -431,11 +431,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
 	struct htc_target *target;
 
 	target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
-	if (!target) {
-		printk(KERN_ERR "Unable to allocate memory for"
-			"target device\n");
+	if (!target)
 		return NULL;
-	}
 
 	init_completion(&target->target_wait);
 	init_completion(&target->cmd_wait);
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index c4ad0b0..265bf77 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -24,7 +24,7 @@
 static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
 					       bool power_off)
 {
-	if (ah->aspm_enabled != true)
+	if (!ah->aspm_enabled)
 		return;
 
 	ath9k_hw_ops(ah)->config_pci_powersave(ah, power_off);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 87db1ee..d0d13d7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1600,7 +1600,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		allow_fbs = true;
 
 	if (bChannelChange &&
-	    (ah->chip_fullsleep != true) &&
+	    (!ah->chip_fullsleep) &&
 	    (ah->curchan != NULL) &&
 	    (chan->channel != ah->curchan->channel) &&
 	    (allow_fbs ||
@@ -2038,8 +2038,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 	if (setChip) {
 		if ((REG_READ(ah, AR_RTC_STATUS) &
 		     AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
-			if (ath9k_hw_set_reset_reg(ah,
-					   ATH9K_RESET_POWER_ON) != true) {
+			if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
 				return false;
 			}
 			if (!AR_SREV_9300_20_OR_LATER(ah))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 6a29004..c8261d4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -940,7 +940,6 @@ struct ath_hw {
 	u32 *analogBank6Data;
 	u32 *analogBank6TPCData;
 	u32 *analogBank7Data;
-	u32 *addac5416_21;
 	u32 *bank6Temp;
 
 	u8 txpower_limit;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4a00806..ec82e92 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -340,9 +340,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
 		fastcc = false;
 
 	ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
-		hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS |
-							  CHANNEL_HT40PLUS)),
-		fastcc);
+		hchan->channel, IS_CHAN_HT40(hchan), fastcc);
 
 	r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
 	if (r) {
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 635b592..a427a16 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 	fc = hdr->frame_control;
 	for (i = 0; i < sc->hw->max_rates; i++) {
 		struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
-		if (!rate->count)
+		if (rate->idx < 0 || !rate->count)
 			break;
 
 		final_ts_idx = i;
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 6cfbb41..0cea20e 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry);
 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
 	const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen);
 int carl9170_disable_key(struct ar9170 *ar, const u8 id);
+int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel);
 
 /* RX */
 void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
@@ -593,7 +594,6 @@ int carl9170_get_noisefloor(struct ar9170 *ar);
 
 /* FW */
 int carl9170_parse_firmware(struct ar9170 *ar);
-int carl9170_fw_fix_eeprom(struct ar9170 *ar);
 
 extern struct ieee80211_rate __carl9170_ratetable[];
 extern int modparam_noht;
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index 3de61ad..cffde8d 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -389,39 +389,6 @@ carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len)
 	return (void *)&fw_data[scan - found];
 }
 
-int carl9170_fw_fix_eeprom(struct ar9170 *ar)
-{
-	const struct carl9170fw_fix_desc *fix_desc = NULL;
-	unsigned int i, n, off;
-	u32 *data = (void *)&ar->eeprom;
-
-	fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC,
-		sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER);
-
-	if (!fix_desc)
-		return 0;
-
-	n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) /
-	    sizeof(struct carl9170fw_fix_entry);
-
-	for (i = 0; i < n; i++) {
-		off = le32_to_cpu(fix_desc->data[i].address) -
-		      AR9170_EEPROM_START;
-
-		if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) {
-			dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i);
-			continue;
-		}
-
-		data[off / sizeof(*data)] &=
-			le32_to_cpu(fix_desc->data[i].mask);
-		data[off / sizeof(*data)] |=
-			le32_to_cpu(fix_desc->data[i].value);
-	}
-
-	return 0;
-}
-
 int carl9170_parse_firmware(struct ar9170 *ar)
 {
 	const struct carl9170fw_desc_head *fw_desc = NULL;
diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index dfda919..53415bf 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id)
 	return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
 		sizeof(key), (u8 *)&key, 0, NULL);
 }
+
+int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
+{
+	unsigned int power, chains;
+
+	if (ar->eeprom.tx_mask != 1)
+		chains = AR9170_TX_PHY_TXCHAIN_2;
+	else
+		chains = AR9170_TX_PHY_TXCHAIN_1;
+
+	switch (channel->band) {
+	case IEEE80211_BAND_2GHZ:
+		power = ar->power_2G_ofdm[0] & 0x3f;
+		break;
+	case IEEE80211_BAND_5GHZ:
+		power = ar->power_5G_leg[0] & 0x3f;
+		break;
+	default:
+		BUG_ON(1);
+	}
+
+	power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
+
+	carl9170_regwrite_begin(ar);
+	carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
+			  0x3c1e | power << 20 | chains << 26);
+	carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
+			  power << 5 | chains << 11 |
+			  power << 21 | chains << 27);
+	carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
+			  power << 5 | chains << 11 |
+			  power << 21 | chains << 27);
+	carl9170_regwrite_finish();
+	return carl9170_regwrite_result();
+}
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index db77421..8d2523b 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
 			goto out;
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-		/* TODO */
-		err = 0;
-	}
-
 	if (changed & IEEE80211_CONF_CHANGE_SMPS) {
 		/* TODO */
 		err = 0;
@@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
 			goto out;
 	}
 
+	if (changed & IEEE80211_CONF_CHANGE_POWER) {
+		err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel);
+		if (err)
+			goto out;
+	}
+
 out:
 	mutex_unlock(&ar->mutex);
 	return err;
@@ -1796,6 +1797,9 @@ void *carl9170_alloc(size_t priv_size)
 		ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
 
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+
+	/* As IBSS Encryption is software-based, IBSS RSN is supported. */
+	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 	return ar;
 
 err_nomem:
@@ -1931,10 +1935,6 @@ int carl9170_register(struct ar9170 *ar)
 	if (err)
 		return err;
 
-	err = carl9170_fw_fix_eeprom(ar);
-	if (err)
-		return err;
-
 	err = carl9170_parse_eeprom(ar);
 	if (err)
 		return err;
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 472efc7..b72c09c 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw)
 #undef EDGES
 }
 
-static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
-				  enum carl9170_bw bw)
+static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
+				   enum carl9170_bw bw)
 {
 	struct ar9170_calibration_target_power_legacy *ctpl;
 	struct ar9170_calibration_target_power_ht *ctph;
 	u8 *ctpres;
 	int ntargets;
 	int idx, i, n;
-	u8 ackpower, ackchains, f;
+	u8 f;
 	u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
 
 	if (freq < 3000)
@@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
 
 	/* calc. conformance test limits and apply to ar->power*[] */
 	carl9170_calc_ctl(ar, freq, bw);
-
-	/* set ACK/CTS TX power */
-	carl9170_regwrite_begin(ar);
-
-	if (ar->eeprom.tx_mask != 1)
-		ackchains = AR9170_TX_PHY_TXCHAIN_2;
-	else
-		ackchains = AR9170_TX_PHY_TXCHAIN_1;
-
-	if (freq < 3000)
-		ackpower = ar->power_2G_ofdm[0] & 0x3f;
-	else
-		ackpower = ar->power_5G_leg[0] & 0x3f;
-
-	carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
-			  0x3c1e | ackpower << 20 | ackchains << 26);
-	carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
-			  ackpower << 5 | ackchains << 11 |
-			  ackpower << 21 | ackchains << 27);
-
-	carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
-			  ackpower << 5 | ackchains << 11 |
-			  ackpower << 21 | ackchains << 27);
-
-	carl9170_regwrite_finish();
-	return carl9170_regwrite_result();
 }
 
 int carl9170_get_noisefloor(struct ar9170 *ar)
@@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
 	if (err)
 		return err;
 
-	err = carl9170_set_power_cal(ar, channel->center_freq, bw);
+	carl9170_set_power_cal(ar, channel->center_freq, bw);
+
+	err = carl9170_set_mac_tpc(ar, channel);
 	if (err)
 		return err;
 
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index d19a9ee..771e1a9 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar,
 		else
 			*chains = AR9170_TX_PHY_TXCHAIN_2;
 	}
+
+	*tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2);
 }
 
 static __le32 carl9170_tx_physet(struct ar9170 *ar,
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 7e45ca2..3010cee 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1533,10 +1533,9 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
 
 	/* Create the network device object. */
 	dev = alloc_etherdev(sizeof(*priv));
-	if (!dev) {
-		printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
+	if (!dev)
 		return NULL;
-	}
+
 	if (dev_alloc_name(dev, dev->name) < 0) {
 		printk(KERN_ERR "atmel: Couldn't get name!\n");
 		goto err_out_free;
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 16e8f80..835462d 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -999,6 +999,12 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 	dev->dev->write16(dev->dev, offset, value);
 }
 
+static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
+				 u16 set)
+{
+	b43_write16(dev, offset, (b43_read16(dev, offset) & mask) | set);
+}
+
 static inline u32 b43_read32(struct b43_wldev *dev, u16 offset)
 {
 	return dev->dev->read32(dev->dev, offset);
@@ -1009,6 +1015,12 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
 	dev->dev->write32(dev->dev, offset, value);
 }
 
+static inline void b43_maskset32(struct b43_wldev *dev, u16 offset, u32 mask,
+				 u32 set)
+{
+	b43_write32(dev, offset, (b43_read32(dev, offset) & mask) | set);
+}
+
 static inline void b43_block_read(struct b43_wldev *dev, void *buffer,
 				 size_t count, u16 offset, u8 reg_width)
 {
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 23ffb1b..5189cf3 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -580,22 +580,14 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
 
 static void b43_time_lock(struct b43_wldev *dev)
 {
-	u32 macctl;
-
-	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	macctl |= B43_MACCTL_TBTTHOLD;
-	b43_write32(dev, B43_MMIO_MACCTL, macctl);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_TBTTHOLD);
 	/* Commit the write */
 	b43_read32(dev, B43_MMIO_MACCTL);
 }
 
 static void b43_time_unlock(struct b43_wldev *dev)
 {
-	u32 macctl;
-
-	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	macctl &= ~B43_MACCTL_TBTTHOLD;
-	b43_write32(dev, B43_MMIO_MACCTL, macctl);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_TBTTHOLD, 0);
 	/* Commit the write */
 	b43_read32(dev, B43_MMIO_MACCTL);
 }
@@ -2487,10 +2479,8 @@ static int b43_upload_microcode(struct b43_wldev *dev)
 	b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL);
 
 	/* Start the microcode PSM */
-	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	macctl &= ~B43_MACCTL_PSM_JMP0;
-	macctl |= B43_MACCTL_PSM_RUN;
-	b43_write32(dev, B43_MMIO_MACCTL, macctl);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_JMP0,
+		      B43_MACCTL_PSM_RUN);
 
 	/* Wait for the microcode to load and respond */
 	i = 0;
@@ -2590,10 +2580,9 @@ static int b43_upload_microcode(struct b43_wldev *dev)
 	return 0;
 
 error:
-	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	macctl &= ~B43_MACCTL_PSM_RUN;
-	macctl |= B43_MACCTL_PSM_JMP0;
-	b43_write32(dev, B43_MMIO_MACCTL, macctl);
+	/* Stop the microcode PSM. */
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
+		      B43_MACCTL_PSM_JMP0);
 
 	return err;
 }
@@ -2708,11 +2697,8 @@ static int b43_gpio_init(struct b43_wldev *dev)
 	struct ssb_device *gpiodev;
 	u32 mask, set;
 
-	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-		    & ~B43_MACCTL_GPOUTSMSK);
-
-	b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK)
-		    | 0x000F);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
+	b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF);
 
 	mask = 0x0000001F;
 	set = 0x0000000F;
@@ -2800,9 +2786,7 @@ void b43_mac_enable(struct b43_wldev *dev)
 	dev->mac_suspended--;
 	B43_WARN_ON(dev->mac_suspended < 0);
 	if (dev->mac_suspended == 0) {
-		b43_write32(dev, B43_MMIO_MACCTL,
-			    b43_read32(dev, B43_MMIO_MACCTL)
-			    | B43_MACCTL_ENABLED);
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_ENABLED);
 		b43_write32(dev, B43_MMIO_GEN_IRQ_REASON,
 			    B43_IRQ_MAC_SUSPENDED);
 		/* Commit writes */
@@ -2823,9 +2807,7 @@ void b43_mac_suspend(struct b43_wldev *dev)
 
 	if (dev->mac_suspended == 0) {
 		b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
-		b43_write32(dev, B43_MMIO_MACCTL,
-			    b43_read32(dev, B43_MMIO_MACCTL)
-			    & ~B43_MACCTL_ENABLED);
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_ENABLED, 0);
 		/* force pci to flush the write */
 		b43_read32(dev, B43_MMIO_MACCTL);
 		for (i = 35; i; i--) {
@@ -2931,15 +2913,10 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
 	 *        so always disable it. If we want to implement PMQ,
 	 *        we need to enable it here (clear DISCPMQ) in AP mode.
 	 */
-	if (0  /* ctl & B43_MACCTL_AP */) {
-		b43_write32(dev, B43_MMIO_MACCTL,
-			    b43_read32(dev, B43_MMIO_MACCTL)
-			    & ~B43_MACCTL_DISCPMQ);
-	} else {
-		b43_write32(dev, B43_MMIO_MACCTL,
-			    b43_read32(dev, B43_MMIO_MACCTL)
-			    | B43_MACCTL_DISCPMQ);
-	}
+	if (0  /* ctl & B43_MACCTL_AP */)
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_DISCPMQ, 0);
+	else
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_DISCPMQ);
 }
 
 static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
@@ -3083,10 +3060,8 @@ static int b43_chip_init(struct b43_wldev *dev)
 	if (dev->dev->core_rev < 5)
 		b43_write32(dev, 0x010C, 0x01000000);
 
-	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-		    & ~B43_MACCTL_INFRA);
-	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-		    | B43_MACCTL_INFRA);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_INFRA, 0);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_INFRA);
 
 	/* Probe Response Timeout value */
 	/* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
@@ -4564,8 +4539,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev)
 /* Locking: wl->mutex */
 static void b43_wireless_core_exit(struct b43_wldev *dev)
 {
-	u32 macctl;
-
 	B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
 	if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
 		return;
@@ -4576,10 +4549,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
 	b43_set_status(dev, B43_STAT_UNINIT);
 
 	/* Stop the microcode PSM. */
-	macctl = b43_read32(dev, B43_MMIO_MACCTL);
-	macctl &= ~B43_MACCTL_PSM_RUN;
-	macctl |= B43_MACCTL_PSM_JMP0;
-	b43_write32(dev, B43_MMIO_MACCTL, macctl);
+	b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
+		      B43_MACCTL_PSM_JMP0);
 
 	b43_dma_free(dev);
 	b43_pio_free(dev);
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index bf5a438..1081188 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -85,22 +85,11 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev)
 		(dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ));
 }
 
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
-static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */
+static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev)
 {
-	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-		if (dev->phy.rev >= 6) {
-			if (dev->dev->chip_id == 47162)
-				return txpwrctrl_tx_gain_ipa_rev5;
-			return txpwrctrl_tx_gain_ipa_rev6;
-		} else if (dev->phy.rev >= 5) {
-			return txpwrctrl_tx_gain_ipa_rev5;
-		} else {
-			return txpwrctrl_tx_gain_ipa;
-		}
-	} else {
-		return txpwrctrl_tx_gain_ipa_5g;
-	}
+	return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >>
+		B43_NPHY_RFSEQCA_RXEN_SHIFT;
 }
 
 /**************************************************
@@ -229,7 +218,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
 
 		reg = (i == 0) ?
 			B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2;
-		b43_phy_mask(dev, reg, 0xFBFF);
+		b43_phy_set(dev, reg, 0x400);
 
 		switch (field) {
 		case 0:
@@ -245,7 +234,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
 				b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
 						B43_NPHY_RFCTL_CMD_START);
 				for (j = 0; j < 100; j++) {
-					if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) {
+					if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) {
 						j = 0;
 						break;
 					}
@@ -264,7 +253,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
 				b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
 						B43_NPHY_RFCTL_CMD_RXTX);
 				for (j = 0; j < 100; j++) {
-					if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) {
+					if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) {
 						j = 0;
 						break;
 					}
@@ -1231,12 +1220,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
 	u16 s[2];
 
 	if (dev->phy.rev >= 3) {
-		save_regs_phy[0] = b43_phy_read(dev,
+		save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
+		save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
+		save_regs_phy[2] = b43_phy_read(dev,
 						B43_NPHY_RFCTL_LUT_TRSW_UP1);
-		save_regs_phy[1] = b43_phy_read(dev,
+		save_regs_phy[3] = b43_phy_read(dev,
 						B43_NPHY_RFCTL_LUT_TRSW_UP2);
-		save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
-		save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
 		save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
 		save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
 		save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
@@ -1285,12 +1274,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
 		b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
 
 	if (dev->phy.rev >= 3) {
+		b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
+		b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
 		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
-				save_regs_phy[0]);
+				save_regs_phy[2]);
 		b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
-				save_regs_phy[1]);
-		b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
-		b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
+				save_regs_phy[3]);
 		b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
 		b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
 		b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
@@ -1308,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
 	return out;
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
+static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+
+	u16 saved_regs_phy_rfctl[2];
+	u16 saved_regs_phy[13];
+	u16 regs_to_store[] = {
+		B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER,
+		B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2,
+		B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER,
+		B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1,
+		B43_NPHY_RFCTL_CMD,
+		B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2,
+		B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2
+	};
+
+	u16 class;
+
+	u16 clip_state[2];
+	u16 clip_off[2] = { 0xFFFF, 0xFFFF };
+
+	u8 vcm_final = 0;
+	s8 offset[4];
+	s32 results[8][4] = { };
+	s32 results_min[4] = { };
+	s32 poll_results[4] = { };
+
+	u16 *rssical_radio_regs = NULL;
+	u16 *rssical_phy_regs = NULL;
+
+	u16 r; /* routing */
+	u8 rx_core_state;
+	u8 core, i, j;
+
+	class = b43_nphy_classifier(dev, 0, 0);
+	b43_nphy_classifier(dev, 7, 4);
+	b43_nphy_read_clip_detection(dev, clip_state);
+	b43_nphy_write_clip_detection(dev, clip_off);
+
+	saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
+	saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
+	for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
+		saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]);
+
+	b43_nphy_rf_control_intc_override(dev, 0, 0, 7);
+	b43_nphy_rf_control_intc_override(dev, 1, 1, 7);
+	b43_nphy_rf_control_override(dev, 0x1, 0, 0, false);
+	b43_nphy_rf_control_override(dev, 0x2, 1, 0, false);
+	b43_nphy_rf_control_override(dev, 0x80, 1, 0, false);
+	b43_nphy_rf_control_override(dev, 0x40, 1, 0, false);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+		b43_nphy_rf_control_override(dev, 0x20, 0, 0, false);
+		b43_nphy_rf_control_override(dev, 0x10, 1, 0, false);
+	} else {
+		b43_nphy_rf_control_override(dev, 0x10, 0, 0, false);
+		b43_nphy_rf_control_override(dev, 0x20, 1, 0, false);
+	}
+
+	rx_core_state = b43_nphy_get_rx_core_state(dev);
+	for (core = 0; core < 2; core++) {
+		if (!(rx_core_state & (1 << core)))
+			continue;
+		r = core ? B2056_RX1 : B2056_RX0;
+		b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2);
+		b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2);
+		for (i = 0; i < 8; i++) {
+			b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
+					i << 2);
+			b43_nphy_poll_rssi(dev, 2, results[i], 8);
+		}
+		for (i = 0; i < 4; i++) {
+			s32 curr;
+			s32 mind = 40;
+			s32 minpoll = 249;
+			u8 minvcm = 0;
+			if (2 * core != i)
+				continue;
+			for (j = 0; j < 8; j++) {
+				curr = results[j][i] * results[j][i] +
+					results[j][i + 1] * results[j][i];
+				if (curr < mind) {
+					mind = curr;
+					minvcm = j;
+				}
+				if (results[j][i] < minpoll)
+					minpoll = results[j][i];
+			}
+			vcm_final = minvcm;
+			results_min[i] = minpoll;
+		}
+		b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3,
+				  vcm_final << 2);
+		for (i = 0; i < 4; i++) {
+			if (core != i / 2)
+				continue;
+			offset[i] = -results[vcm_final][i];
+			if (offset[i] < 0)
+				offset[i] = -((abs(offset[i]) + 4) / 8);
+			else
+				offset[i] = (offset[i] + 4) / 8;
+			if (results_min[i] == 248)
+				offset[i] = -32;
+			b43_nphy_scale_offset_rssi(dev, 0, offset[i],
+						   (i / 2 == 0) ? 1 : 2,
+						   (i % 2 == 0) ? 0 : 1,
+						   2);
+		}
+	}
+	for (core = 0; core < 2; core++) {
+		if (!(rx_core_state & (1 << core)))
+			continue;
+		for (i = 0; i < 2; i++) {
+			b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i);
+			b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i);
+			b43_nphy_poll_rssi(dev, i, poll_results, 8);
+			for (j = 0; j < 4; j++) {
+				if (j / 2 == core)
+					offset[j] = 232 - poll_results[j];
+				if (offset[j] < 0)
+					offset[j] = -(abs(offset[j] + 4) / 8);
+				else
+					offset[j] = (offset[j] + 4) / 8;
+				b43_nphy_scale_offset_rssi(dev, 0,
+					offset[2 * core], core + 1, j % 2, i);
+			}
+		}
+	}
+
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]);
+	b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]);
+
+	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+
+	b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1);
+	b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START);
+	b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
+
+	b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1);
+	b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX);
+	b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1);
+
+	for (i = 0; i < ARRAY_SIZE(regs_to_store); i++)
+		b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]);
+
+	/* Store for future configuration */
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
+		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
+	} else {
+		rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
+		rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
+	}
+	rssical_radio_regs[0] = b43_radio_read(dev, 0x602B);
+	rssical_radio_regs[0] = b43_radio_read(dev, 0x702B);
+	rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z);
+	rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z);
+	rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z);
+	rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z);
+	rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X);
+	rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X);
+	rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X);
+	rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X);
+	rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y);
+	rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y);
+	rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y);
+	rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y);
+
+	/* Remember for which channel we store configuration */
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq;
+	else
+		nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq;
+
+	/* End of calibration, restore configuration */
+	b43_nphy_classifier(dev, 7, class);
+	b43_nphy_write_clip_detection(dev, clip_state);
+}
+
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
 static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
 {
@@ -1472,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
 	b43_nphy_reset_cca(dev);
 }
 
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
-static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
-{
-	/* TODO */
-}
-
 /*
  * RSSI Calibration
  * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
@@ -2229,27 +2392,12 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
 	*/
 
 	for (i = 0; i < 2; i++) {
-		if (dev->phy.rev >= 3) {
-			if (b43_nphy_ipa(dev)) {
-				txgain = *(b43_nphy_get_ipa_gain_table(dev) +
-						txpi[i]);
-			} else if (b43_current_band(dev->wl) ==
-				   IEEE80211_BAND_5GHZ) {
-				/* FIXME: use 5GHz tables */
-				txgain =
-					b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
-			} else {
-				if (dev->phy.rev >= 5 &&
-				    sprom->fem.ghz5.extpa_gain == 3)
-					; /* FIXME: 5GHz_txgain_HiPwrEPA */
-				txgain =
-					b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
-			}
+		txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]);
+
+		if (dev->phy.rev >= 3)
 			radio_gain = (txgain >> 16) & 0x1FFFF;
-		} else {
-			txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
+		else
 			radio_gain = (txgain >> 16) & 0x1FFF;
-		}
 
 		if (dev->phy.rev >= 7)
 			dac_gain = (txgain >> 8) & 0x7;
@@ -2420,55 +2568,252 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
 	nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF;
 }
 
-static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
+/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */
+static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
 {
-	struct b43_phy *phy = &dev->phy;
+	struct b43_phy_n *nphy = dev->phy.n;
 
-	const u32 *table = NULL;
-#if 0
-	TODO: b43_ntab_papd_pga_gain_delta_ipa_2*
-	u32 rfpwr_offset;
-	u8 pga_gain;
-	int i;
-#endif
+	u8 idx, delta;
+	u8 i, stf_mode;
 
-	if (phy->rev >= 3) {
-		if (b43_nphy_ipa(dev)) {
-			table = b43_nphy_get_ipa_gain_table(dev);
+	for (i = 0; i < 4; i++)
+		nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i];
+
+	for (stf_mode = 0; stf_mode < 4; stf_mode++) {
+		delta = 0;
+		switch (stf_mode) {
+		case 0:
+			if (dev->phy.is_40mhz && dev->phy.rev >= 5) {
+				idx = 68;
+			} else {
+				delta = 1;
+				idx = dev->phy.is_40mhz ? 52 : 4;
+			}
+			break;
+		case 1:
+			idx = dev->phy.is_40mhz ? 76 : 28;
+			break;
+		case 2:
+			idx = dev->phy.is_40mhz ? 84 : 36;
+			break;
+		case 3:
+			idx = dev->phy.is_40mhz ? 92 : 44;
+			break;
+		}
+
+		for (i = 0; i < 20; i++) {
+			nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] =
+				nphy->tx_power_offset[idx];
+			if (i == 0)
+				idx += delta;
+			if (i == 14)
+				idx += 1 - delta;
+			if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 ||
+			    i == 13)
+				idx += 1;
+		}
+	}
+}
+
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
+static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
+{
+	struct b43_phy_n *nphy = dev->phy.n;
+	struct ssb_sprom *sprom = dev->dev->bus_sprom;
+
+	s16 a1[2], b0[2], b1[2];
+	u8 idle[2];
+	s8 target[2];
+	s32 num, den, pwr;
+	u32 regval[64];
+
+	u16 freq = dev->phy.channel_freq;
+	u16 tmp;
+	u16 r; /* routing */
+	u8 i, c;
+
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
+		b43_read32(dev, B43_MMIO_MACCTL);
+		udelay(1);
+	}
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, true);
+
+	b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN);
+	if (dev->phy.rev >= 3)
+		b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD,
+			     ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF);
+	else
+		b43_phy_set(dev, B43_NPHY_TXPCTL_CMD,
+			    B43_NPHY_TXPCTL_CMD_PCTLEN);
+
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
+
+	if (sprom->revision < 4) {
+		idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g;
+		idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g;
+		target[0] = target[1] = 52;
+		a1[0] = a1[1] = -424;
+		b0[0] = b0[1] = 5612;
+		b1[0] = b1[1] = -1393;
+	} else {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			for (c = 0; c < 2; c++) {
+				idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g;
+				target[c] = sprom->core_pwr_info[c].maxpwr_2g;
+				a1[c] = sprom->core_pwr_info[c].pa_2g[0];
+				b0[c] = sprom->core_pwr_info[c].pa_2g[1];
+				b1[c] = sprom->core_pwr_info[c].pa_2g[2];
+			}
+		} else if (freq >= 4900 && freq < 5100) {
+			for (c = 0; c < 2; c++) {
+				idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
+				target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
+				a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
+				b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
+				b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
+			}
+		} else if (freq >= 5100 && freq < 5500) {
+			for (c = 0; c < 2; c++) {
+				idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
+				target[c] = sprom->core_pwr_info[c].maxpwr_5g;
+				a1[c] = sprom->core_pwr_info[c].pa_5g[0];
+				b0[c] = sprom->core_pwr_info[c].pa_5g[1];
+				b1[c] = sprom->core_pwr_info[c].pa_5g[2];
+			}
+		} else if (freq >= 5500) {
+			for (c = 0; c < 2; c++) {
+				idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g;
+				target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
+				a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
+				b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
+				b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
+			}
 		} else {
-			if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
-				if (phy->rev == 3)
-					table = b43_ntab_tx_gain_rev3_5ghz;
-				if (phy->rev == 4)
-					table = b43_ntab_tx_gain_rev4_5ghz;
-				else
-					table = b43_ntab_tx_gain_rev5plus_5ghz;
+			idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g;
+			idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g;
+			target[0] = target[1] = 52;
+			a1[0] = a1[1] = -424;
+			b0[0] = b0[1] = 5612;
+			b1[0] = b1[1] = -1393;
+		}
+	}
+	/* target[0] = target[1] = nphy->tx_power_max; */
+
+	if (dev->phy.rev >= 3) {
+		if (sprom->fem.ghz2.tssipos)
+			b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000);
+		if (dev->phy.rev >= 7) {
+			for (c = 0; c < 2; c++) {
+				r = c ? 0x190 : 0x170;
+				if (b43_nphy_ipa(dev))
+					b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC);
+			}
+		} else {
+			if (b43_nphy_ipa(dev)) {
+				tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
+				b43_radio_write(dev,
+					B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp);
+				b43_radio_write(dev,
+					B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp);
 			} else {
-				table = b43_ntab_tx_gain_rev3plus_2ghz;
+				b43_radio_write(dev,
+					B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11);
+				b43_radio_write(dev,
+					B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11);
 			}
 		}
+	}
+
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000);
+		b43_read32(dev, B43_MMIO_MACCTL);
+		udelay(1);
+	}
+
+	if (dev->phy.rev >= 7) {
+		b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
+				~B43_NPHY_TXPCTL_CMD_INIT, 0x19);
+		b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
+				~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19);
 	} else {
-		table = b43_ntab_tx_gain_rev0_1_2;
+		b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
+				~B43_NPHY_TXPCTL_CMD_INIT, 0x40);
+		if (dev->phy.rev > 1)
+			b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
+				~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40);
+	}
+
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0);
+
+	b43_phy_write(dev, B43_NPHY_TXPCTL_N,
+		      0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT |
+		      3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT);
+	b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI,
+		      idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT |
+		      idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT |
+		      B43_NPHY_TXPCTL_ITSSI_BINF);
+	b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR,
+		      target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT |
+		      target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT);
+
+	for (c = 0; c < 2; c++) {
+		for (i = 0; i < 64; i++) {
+			num = 8 * (16 * b0[c] + b1[c] * i);
+			den = 32768 + a1[c] * i;
+			pwr = max((4 * num + den / 2) / den, -8);
+			if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1)))
+				pwr = max(pwr, target[c] + 1);
+			regval[i] = pwr;
+		}
+		b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval);
 	}
+
+	b43_nphy_tx_prepare_adjusted_power_table(dev);
+	/*
+	b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl);
+	b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl);
+	*/
+
+	if (nphy->hang_avoid)
+		b43_nphy_stay_in_carrier_search(dev, false);
+}
+
+static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
+{
+	struct b43_phy *phy = &dev->phy;
+
+	const u32 *table = NULL;
+	u32 rfpwr_offset;
+	u8 pga_gain;
+	int i;
+
+	table = b43_nphy_get_tx_gain_table(dev);
 	b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
 	b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
 
 	if (phy->rev >= 3) {
 #if 0
 		nphy->gmval = (table[0] >> 16) & 0x7000;
+#endif
 
 		for (i = 0; i < 128; i++) {
 			pga_gain = (table[i] >> 24) & 0xF;
 			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-				rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
+				rfpwr_offset =
+				 b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
 			else
-				rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain];
+				rfpwr_offset =
+				 0; /* FIXME */
 			b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
 				       rfpwr_offset);
 			b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
 				       rfpwr_offset);
 		}
-#endif
 	}
 }
 
@@ -3139,32 +3484,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
 			B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
 
 		for (i = 0; i < 2; ++i) {
+			table = b43_nphy_get_tx_gain_table(dev);
 			if (dev->phy.rev >= 3) {
-				enum ieee80211_band band =
-					b43_current_band(dev->wl);
-
-				if (b43_nphy_ipa(dev)) {
-					table = b43_nphy_get_ipa_gain_table(dev);
-				} else {
-					if (band == IEEE80211_BAND_5GHZ) {
-						if (dev->phy.rev == 3)
-							table = b43_ntab_tx_gain_rev3_5ghz;
-						else if (dev->phy.rev == 4)
-							table = b43_ntab_tx_gain_rev4_5ghz;
-						else
-							table = b43_ntab_tx_gain_rev5plus_5ghz;
-					} else {
-						table = b43_ntab_tx_gain_rev3plus_2ghz;
-					}
-				}
-
 				target.ipa[i] = (table[index[i]] >> 16) & 0xF;
 				target.pad[i] = (table[index[i]] >> 20) & 0xF;
 				target.pga[i] = (table[index[i]] >> 24) & 0xF;
 				target.txgm[i] = (table[index[i]] >> 28) & 0xF;
 			} else {
-				table = b43_ntab_tx_gain_rev0_1_2;
-
 				target.ipa[i] = (table[index[i]] >> 16) & 0x3;
 				target.pad[i] = (table[index[i]] >> 18) & 0x3;
 				target.pga[i] = (table[index[i]] >> 20) & 0x7;
@@ -3968,13 +4294,10 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
 #endif
 		}
 
-		b43_write32(dev, B43_MMIO_MACCTL,
-			b43_read32(dev, B43_MMIO_MACCTL) &
-			~B43_MACCTL_GPOUTSMSK);
-		b43_write16(dev, B43_MMIO_GPIO_MASK,
-			b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00);
-		b43_write16(dev, B43_MMIO_GPIO_CONTROL,
-			b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00);
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
+		b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00);
+		b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF),
+			      0);
 
 		if (init) {
 			b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
@@ -4110,7 +4433,7 @@ int b43_phy_initn(struct b43_wldev *dev)
 	b43_nphy_tx_power_ctrl(dev, false);
 	b43_nphy_tx_power_fix(dev);
 	b43_nphy_tx_power_ctl_idle_tssi(dev);
-	/* TODO N PHY TX Power Control Setup */
+	b43_nphy_tx_power_ctl_setup(dev);
 	b43_nphy_tx_gain_table_upload(dev);
 
 	if (nphy->phyrxchain != 3)
@@ -4530,8 +4853,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 {
 	check_phyreg(dev, reg);
 	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA,
-		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
+	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 }
 
 static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 5de8f74..fd12b38 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -798,6 +798,7 @@ struct b43_phy_n {
 	bool txpwrctrl;
 	bool pwg_gain_5ghz;
 	u8 tx_pwr_idx[2];
+	s8 tx_power_offset[101];
 	u16 adj_pwr_tbl[84];
 	u16 txcal_bbmult;
 	u16 txiqlocal_bestc[11];
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index f7def135..f0d8377 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2214,7 +2214,7 @@ static const u16 b43_ntab_antswctl2g_r3[4][32] = {
 };
 
 /* TX gain tables */
-const u32 b43_ntab_tx_gain_rev0_1_2[] = {
+static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
 	0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
 	0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
 	0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
@@ -2249,7 +2249,7 @@ const u32 b43_ntab_tx_gain_rev0_1_2[] = {
 	0x03801442, 0x03801344, 0x03801342, 0x00002b00,
 };
 
-const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
+static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
 	0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
 	0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
 	0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
@@ -2284,7 +2284,7 @@ const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
 	0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
 };
 
-const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
+static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
 	0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
 	0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
 	0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
@@ -2319,7 +2319,7 @@ const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
 	0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
 };
 
-const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
+static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
 	0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
 	0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
 	0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
@@ -2354,7 +2354,7 @@ const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
 	0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
 };
 
-const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
+static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
 	0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
 	0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
 	0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
@@ -2389,7 +2389,7 @@ const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
 	0x0062003b, 0x00620039, 0x00620037, 0x00620035,
 };
 
-const u32 txpwrctrl_tx_gain_ipa[] = {
+static const u32 txpwrctrl_tx_gain_ipa[] = {
 	0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
 	0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
 	0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
@@ -2424,7 +2424,7 @@ const u32 txpwrctrl_tx_gain_ipa[] = {
 	0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
 };
 
-const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
+static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
 	0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
 	0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
 	0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
@@ -2459,7 +2459,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
 	0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
 };
 
-const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
+static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
 	0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
 	0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
 	0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
@@ -2494,7 +2494,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
 	0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
 };
 
-const u32 txpwrctrl_tx_gain_ipa_5g[] = {
+static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
 	0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
 	0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
 	0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
@@ -2529,6 +2529,11 @@ const u32 txpwrctrl_tx_gain_ipa_5g[] = {
 	0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
 };
 
+const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
+	-114, -108, -98, -91, -84, -78, -70, -62,
+	-54, -46, -39, -31, -23, -15, -8, 0
+};
+
 const u16 tbl_iqcal_gainparams[2][9][8] = {
 	{
 		{ 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
@@ -2739,11 +2744,11 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = {
 	{ 0x0001,  0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */
 	{ 0x0002,  1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */
 	{ 0x0004,  2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */
-	{ 0x0016,  4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
+	{ 0x0010,  4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */
 	{ 0x0020,  5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */
 	{ 0x0040,  6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */
-	{ 0x0080,  6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
-	{ 0x0100,  7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
+	{ 0x0080,  7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */
+	{ 0x0100,  8, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */
 	{ 0x0007,  0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */
 	{ 0x0070,  4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */
 	{ 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */
@@ -3126,6 +3131,53 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
 		B43_WARN_ON(1);
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
+static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
+{
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		if (dev->phy.rev >= 6) {
+			if (dev->dev->chip_id == 47162)
+				return txpwrctrl_tx_gain_ipa_rev5;
+			return txpwrctrl_tx_gain_ipa_rev6;
+		} else if (dev->phy.rev >= 5) {
+			return txpwrctrl_tx_gain_ipa_rev5;
+		} else {
+			return txpwrctrl_tx_gain_ipa;
+		}
+	} else {
+		return txpwrctrl_tx_gain_ipa_5g;
+	}
+}
+
+const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
+{
+	enum ieee80211_band band = b43_current_band(dev->wl);
+	struct ssb_sprom *sprom = dev->dev->bus_sprom;
+
+	if (dev->phy.rev < 3)
+		return b43_ntab_tx_gain_rev0_1_2;
+
+	/* rev 3+ */
+	if ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
+	    (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
+		return b43_nphy_get_ipa_gain_table(dev);
+	} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+		if (dev->phy.rev == 3)
+			return b43_ntab_tx_gain_rev3_5ghz;
+		if (dev->phy.rev == 4)
+			return sprom->fem.ghz5.extpa_gain == 3 ?
+				b43_ntab_tx_gain_rev4_5ghz :
+				b43_ntab_tx_gain_rev4_5ghz; /* FIXME */
+		else
+			return b43_ntab_tx_gain_rev5plus_5ghz;
+	} else {
+		if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3)
+			return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */
+		else
+			return b43_ntab_tx_gain_rev3plus_2ghz;
+	}
+}
+
 struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	struct b43_wldev *dev, bool ghz5, bool ext_lna)
 {
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 97038c4..f348953 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -177,16 +177,10 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
 void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
 void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
 
-extern const u32 b43_ntab_tx_gain_rev0_1_2[];
-extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[];
-extern const u32 b43_ntab_tx_gain_rev3_5ghz[];
-extern const u32 b43_ntab_tx_gain_rev4_5ghz[];
-extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[];
-
-extern const u32 txpwrctrl_tx_gain_ipa[];
-extern const u32 txpwrctrl_tx_gain_ipa_rev5[];
-extern const u32 txpwrctrl_tx_gain_ipa_rev6[];
-extern const u32 txpwrctrl_tx_gain_ipa_5g[];
+const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev);
+
+extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[];
+
 extern const u16 tbl_iqcal_gainparams[2][9][8];
 extern const struct nphy_txiqcal_ladder ladder_lo[];
 extern const struct nphy_txiqcal_ladder ladder_iq[];
diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile
index f41c047..b987920 100644
--- a/drivers/net/wireless/brcm80211/Makefile
+++ b/drivers/net/wireless/brcm80211/Makefile
@@ -16,7 +16,7 @@
 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 # common flags
-subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DBCMDBG
+subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DDEBUG
 
 obj-$(CONFIG_BRCMUTIL)	+= brcmutil/
 obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 4bc8d25..e925290 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -15,6 +15,8 @@
  */
 /* ****************** SDIO CARD Interface Functions **************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/export.h>
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 9b8c0ed..ac71ade 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -13,6 +13,9 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/mmc/sdio.h>
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index e58ea40..07686a7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -644,9 +644,9 @@ extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
 extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
 				       uint cmd, void *buf, uint len);
 
-#ifdef BCMDBG
+#ifdef DEBUG
 extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
 extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index ac8d1f4..b3e3b7f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -19,6 +19,8 @@
  * For certain dcmd codes, the dongle interprets string data from the host.
  ******************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/sched.h>
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index a51d8f5..4187435 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -13,6 +13,9 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/sched.h>
@@ -38,7 +41,7 @@
 #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN	\
 	offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static const char brcmf_version[] =
 	"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
 	__DATE__ " at " __TIME__;
@@ -133,7 +136,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
 	return p != NULL;
 }
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static void
 brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
 {
@@ -399,10 +402,10 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
 		p = (char *)&buf[sizeof(struct msgtrace_hdr)];
 		while ((s = strstr(p, "\n")) != NULL) {
 			*s = '\0';
-			printk(KERN_DEBUG"%s\n", p);
+			pr_debug("%s\n", p);
 			p = s + 1;
 		}
-		printk(KERN_DEBUG "%s\n", p);
+		pr_debug("%s\n", p);
 
 		/* Reset datalen to avoid display below */
 		datalen = 0;
@@ -430,7 +433,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
 		brcmf_dbg(EVENT, "\n");
 	}
 }
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 int
 brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
@@ -518,9 +521,9 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
 		break;
 	}
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	brcmf_c_show_host_event(event, event_data);
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	return 0;
 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index bb26ee3..a2c4576 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -32,20 +32,20 @@
 #define BRCMF_BTA_VAL	0x1000
 #define BRCMF_ISCAN_VAL 0x2000
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 
 #define brcmf_dbg(level, fmt, ...)					\
 do {									\
 	if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) {			\
 		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
 			if (net_ratelimit())				\
-				printk(KERN_DEBUG "%s: " fmt,		\
-				       __func__, ##__VA_ARGS__);	\
+				pr_debug("%s: " fmt,			\
+					 __func__, ##__VA_ARGS__);	\
 		}							\
 	} else {							\
 		if (brcmf_msg_level & BRCMF_##level##_VAL) {		\
-			printk(KERN_DEBUG "%s: " fmt,			\
-			       __func__, ##__VA_ARGS__);		\
+			pr_debug("%s: " fmt,				\
+				 __func__, ##__VA_ARGS__);		\
 		}							\
 	}								\
 } while (0)
@@ -56,7 +56,7 @@ do {									\
 #define BRCMF_BYTES_ON()	(brcmf_msg_level & BRCMF_BYTES_VAL)
 #define BRCMF_GLOM_ON()		(brcmf_msg_level & BRCMF_GLOM_VAL)
 
-#else	/* (defined BCMDBG) || (defined BCMDBG) */
+#else	/* (defined DEBUG) || (defined DEBUG) */
 
 #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
 
@@ -66,7 +66,13 @@ do {									\
 #define BRCMF_BYTES_ON()	0
 #define BRCMF_GLOM_ON()		0
 
-#endif				/* defined(BCMDBG) */
+#endif				/* defined(DEBUG) */
+
+#define brcmf_dbg_hex_dump(test, data, len, fmt, ...)			\
+do {									\
+	if (test)							\
+		brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__);	\
+} while (0)
 
 extern int brcmf_msg_level;
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index eb9eb76..db2df1f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
@@ -590,8 +592,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
 	sprintf(info->bus_info, "%s", dev_name(drvr->dev));
 }
 
-static struct ethtool_ops brcmf_ethtool_ops = {
-	.get_drvinfo = brcmf_ethtool_get_drvinfo
+static const struct ethtool_ops brcmf_ethtool_ops = {
+	.get_drvinfo = brcmf_ethtool_get_drvinfo,
 };
 
 static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
@@ -1146,7 +1148,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
 	return pend;
 }
 
-#ifdef BCMDBG
+#ifdef DEBUG
 int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size)
 {
 	int ret = 0;
@@ -1180,4 +1182,4 @@ exit:
 
 	return ret;
 }
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index f7eeee1..bd2d1dd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
@@ -40,7 +42,7 @@
 
 #define DCMD_RESP_TIMEOUT  2000	/* In milli second */
 
-#ifdef BCMDBG
+#ifdef DEBUG
 
 #define BRCMF_TRAP_INFO_SIZE	80
 
@@ -84,7 +86,7 @@ struct rte_console {
 	char cbuf[CBUF_LEN];
 };
 
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 #include <chipcommon.h>
 
 #include "dhd_bus.h"
@@ -416,7 +418,7 @@ struct sdpcmd_regs {
 	u16 PAD[0x80];
 };
 
-#ifdef BCMDBG
+#ifdef DEBUG
 /* Device console log buffer state */
 struct brcmf_console {
 	uint count;		/* Poll interval msec counter */
@@ -426,7 +428,7 @@ struct brcmf_console {
 	u8 *buf;		/* Log buffer (host copy) */
 	uint last;		/* Last buffer read index */
 };
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 struct sdpcm_shared {
 	u32 flags;
@@ -507,11 +509,11 @@ struct brcmf_sdio {
 	uint polltick;		/* Tick counter */
 	uint pollcnt;		/* Count of active polls */
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	uint console_interval;
 	struct brcmf_console console;	/* Console output polling support */
 	uint console_addr;	/* Console address from shared struct */
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	uint regfails;		/* Count of R_REG failures */
 
@@ -587,10 +589,10 @@ struct brcmf_sdio {
 #define CLK_PENDING	2	/* Not used yet */
 #define CLK_AVAIL	3
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static int qcount[NUMPRIO];
 static int tx_packets[NUMPRIO];
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 #define SDIO_DRIVE_STRENGTH	6	/* in milliamps */
 
@@ -764,12 +766,12 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
 		bus->clkstate = CLK_AVAIL;
 		brcmf_dbg(INFO, "CLKCTL: turned ON\n");
 
-#if defined(BCMDBG)
-		if (bus->alp_only != true) {
+#if defined(DEBUG)
+		if (!bus->alp_only) {
 			if (SBSDIO_ALPONLY(clkctl))
 				brcmf_dbg(ERROR, "HT Clock should be on\n");
 		}
-#endif				/* defined (BCMDBG) */
+#endif				/* defined (DEBUG) */
 
 		bus->activity = true;
 	} else {
@@ -814,9 +816,9 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on)
 /* Transition SD and backplane clock readiness */
 static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
 {
-#ifdef BCMDBG
+#ifdef DEBUG
 	uint oldstate = bus->clkstate;
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -861,9 +863,9 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
 		brcmf_sdbrcm_wd_timer(bus, 0);
 		break;
 	}
-#ifdef BCMDBG
+#ifdef DEBUG
 	brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate);
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	return 0;
 }
@@ -1279,13 +1281,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 			}
 			return 0;
 		}
-#ifdef BCMDBG
-		if (BRCMF_GLOM_ON()) {
-			printk(KERN_DEBUG "SUPERFRAME:\n");
-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-				pfirst->data, min_t(int, pfirst->len, 48));
-		}
-#endif
+
+		brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+				   pfirst->data, min_t(int, pfirst->len, 48),
+				   "SUPERFRAME:\n");
 
 		/* Validate the superframe header */
 		dptr = (u8 *) (pfirst->data);
@@ -1362,13 +1361,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 			check = get_unaligned_le16(dptr + sizeof(u16));
 			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
 			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
-#ifdef BCMDBG
-			if (BRCMF_GLOM_ON()) {
-				printk(KERN_DEBUG "subframe:\n");
-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-						     dptr, 32);
-			}
-#endif
+			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+					   dptr, 32, "subframe:\n");
 
 			if ((u16)~(sublen ^ check)) {
 				brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
@@ -1433,13 +1427,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 			}
 			rxseq++;
 
-#ifdef BCMDBG
-			if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
-				printk(KERN_DEBUG "Rx Subframe Data:\n");
-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-						     dptr, dlen);
-			}
-#endif
+			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
+					   dptr, dlen, "Rx Subframe Data:\n");
 
 			__skb_trim(pfirst, sublen);
 			skb_pull(pfirst, doff);
@@ -1457,17 +1446,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
 				continue;
 			}
 
-#ifdef BCMDBG
-			if (BRCMF_GLOM_ON()) {
-				brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
-					  bus->glom.qlen, pfirst, pfirst->data,
-					  pfirst->len, pfirst->next,
-					  pfirst->prev);
-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-						pfirst->data,
-						min_t(int, pfirst->len, 32));
-			}
-#endif				/* BCMDBG */
+			brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+					   pfirst->data,
+					   min_t(int, pfirst->len, 32),
+					   "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
+					   bus->glom.qlen, pfirst, pfirst->data,
+					   pfirst->len, pfirst->next,
+					   pfirst->prev);
 		}
 		/* sent any remaining packets up */
 		if (bus->glom.qlen) {
@@ -1584,12 +1569,8 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
 
 gotpkt:
 
-#ifdef BCMDBG
-	if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
-		printk(KERN_DEBUG "RxCtrl:\n");
-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
-	}
-#endif
+	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
+			   bus->rxctl, len, "RxCtrl:\n");
 
 	/* Point to valid data and indicate its length */
 	bus->rxctl += doff;
@@ -1818,17 +1799,13 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
 			}
 			bus->tx_max = txmax;
 
-#ifdef BCMDBG
-			if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
-				printk(KERN_DEBUG "Rx Data:\n");
-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-						     rxbuf, len);
-			} else if (BRCMF_HDRS_ON()) {
-				printk(KERN_DEBUG "RxHdr:\n");
-				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-						     bus->rxhdr, SDPCM_HDRLEN);
-			}
-#endif
+			brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
+					   rxbuf, len, "Rx Data:\n");
+			brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
+					     BRCMF_DATA_ON()) &&
+					   BRCMF_HDRS_ON(),
+					   bus->rxhdr, SDPCM_HDRLEN,
+					   "RxHdr:\n");
 
 			if (chan == SDPCM_CONTROL_CHANNEL) {
 				brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n",
@@ -1865,13 +1842,9 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
 			brcmf_sdbrcm_rxfail(bus, true, true);
 			continue;
 		}
-#ifdef BCMDBG
-		if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) {
-			printk(KERN_DEBUG "RxHdr:\n");
-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-					     bus->rxhdr, SDPCM_HDRLEN);
-		}
-#endif
+		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
+				   bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n");
+
 
 		/* Extract hardware header fields */
 		len = get_unaligned_le16(bus->rxhdr);
@@ -2024,13 +1997,8 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
 		skb_push(pkt, BRCMF_FIRSTREAD);
 		memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD);
 
-#ifdef BCMDBG
-		if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) {
-			printk(KERN_DEBUG "Rx Data:\n");
-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-					     pkt->data, len);
-		}
-#endif
+		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
+				   pkt->data, len, "Rx Data:\n");
 
 deliver:
 		/* Save superframe descriptor and allocate packet frame */
@@ -2038,14 +2006,9 @@ deliver:
 			if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
 				brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
 					  len);
-#ifdef BCMDBG
-				if (BRCMF_GLOM_ON()) {
-					printk(KERN_DEBUG "Glom Data:\n");
-					print_hex_dump_bytes("",
-							     DUMP_PREFIX_OFFSET,
-							     pkt->data, len);
-				}
-#endif
+				brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
+						   pkt->data, len,
+						   "Glom Data:\n");
 				__skb_trim(pkt, len);
 				skb_pull(pkt, SDPCM_HDRLEN);
 				bus->glomd = pkt;
@@ -2078,13 +2041,11 @@ deliver:
 		down(&bus->sdsem);
 	}
 	rxcount = maxframes - rxleft;
-#ifdef BCMDBG
 	/* Message if we hit the limit */
 	if (!rxleft)
 		brcmf_dbg(DATA, "hit rx limit of %d frames\n",
 			  maxframes);
 	else
-#endif				/* BCMDBG */
 		brcmf_dbg(DATA, "processed %d frames\n", rxcount);
 	/* Back off rxseq if awaiting rtx, update rx_seq */
 	if (bus->rxskip)
@@ -2098,8 +2059,7 @@ static void
 brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
 {
 	up(&bus->sdsem);
-	wait_event_interruptible_timeout(bus->ctrl_wait,
-					 (*lockvar == false), HZ * 2);
+	wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
 	down(&bus->sdsem);
 	return;
 }
@@ -2176,20 +2136,22 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
 	put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
 	put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	tx_packets[pkt->priority]++;
-	if (BRCMF_BYTES_ON() &&
-	    (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
-	      (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
-		printk(KERN_DEBUG "Tx Frame:\n");
-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
-	} else if (BRCMF_HDRS_ON()) {
-		printk(KERN_DEBUG "TxHdr:\n");
-		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-				     frame, min_t(u16, len, 16));
-	}
 #endif
 
+	brcmf_dbg_hex_dump(BRCMF_BYTES_ON() &&
+			   ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
+			    (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)),
+			   frame, len, "Tx Frame:\n");
+	brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
+			     ((BRCMF_CTL_ON() &&
+			       chan == SDPCM_CONTROL_CHANNEL) ||
+			      (BRCMF_DATA_ON() &&
+			       chan != SDPCM_CONTROL_CHANNEL))) &&
+			   BRCMF_HDRS_ON(),
+			   frame, min_t(u16, len, 16), "TxHdr:\n");
+
 	/* Raise len to next SDIO block to eliminate tail command */
 	if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
 		u16 pad = bus->blocksize - (len % bus->blocksize);
@@ -2410,7 +2372,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 		int err;
 		u8 clkctl, devctl = 0;
 
-#ifdef BCMDBG
+#ifdef DEBUG
 		/* Check for inconsistent device control */
 		devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
 					       SBSDIO_DEVICE_CTL, &err);
@@ -2418,7 +2380,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
 			brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err);
 			bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
 		}
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 		/* Read CSR, if clock on switch to AVAIL, else ignore */
 		clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1,
@@ -2684,8 +2646,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
 
 	/* Priority based enq */
 	spin_lock_bh(&bus->txqlock);
-	if (brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec) ==
-	    false) {
+	if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
 		skb_pull(pkt, SDPCM_HDRLEN);
 		brcmf_txcomplete(bus->sdiodev->dev, pkt, false);
 		brcmu_pkt_buf_free_skb(pkt);
@@ -2701,7 +2662,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
 		brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
 	}
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	if (pktq_plen(&bus->txq, prec) > qcount[prec])
 		qcount[prec] = pktq_plen(&bus->txq, prec);
 #endif
@@ -2774,7 +2735,7 @@ xfer_done:
 	return bcmerror;
 }
 
-#ifdef BCMDBG
+#ifdef DEBUG
 #define CONSOLE_LINE_MAX	192
 
 static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
@@ -2845,14 +2806,14 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
 			if (line[n - 1] == '\r')
 				n--;
 			line[n] = 0;
-			printk(KERN_DEBUG "CONSOLE: %s\n", line);
+			pr_debug("CONSOLE: %s\n", line);
 		}
 	}
 break2:
 
 	return 0;
 }
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
 {
@@ -2972,7 +2933,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
 
 		brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
 
-		if (bus->ctrl_frame_stat == false) {
+		if (!bus->ctrl_frame_stat) {
 			brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
 			ret = 0;
 		} else {
@@ -2982,17 +2943,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
 	}
 
 	if (ret == -1) {
-#ifdef BCMDBG
-		if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) {
-			printk(KERN_DEBUG "Tx Frame:\n");
-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-					     frame, len);
-		} else if (BRCMF_HDRS_ON()) {
-			printk(KERN_DEBUG "TxHdr:\n");
-			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-					     frame, min_t(u16, len, 16));
-		}
-#endif
+		brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
+				   frame, len, "Tx Frame:\n");
+		brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) &&
+				   BRCMF_HDRS_ON(),
+				   frame, min_t(u16, len, 16), "TxHdr:\n");
 
 		do {
 			ret = brcmf_tx_frame(bus, frame, len);
@@ -3040,7 +2995,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
 			  rxlen, msglen);
 	} else if (timeleft == 0) {
 		brcmf_dbg(ERROR, "resumed on timeout\n");
-	} else if (pending == true) {
+	} else if (pending) {
 		brcmf_dbg(CTL, "cancelled\n");
 		return -ERESTARTSYS;
 	} else {
@@ -3096,9 +3051,9 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
 	u8 *vbuffer;
 	u32 varsizew;
 	__le32 varsizew_le;
-#ifdef BCMDBG
+#ifdef DEBUG
 	char *nvram_ularray;
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	/* Even if there are no vars are to be written, we still
 		 need to set the ramsize. */
@@ -3115,7 +3070,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
 		/* Write the vars list */
 		bcmerror =
 		    brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize);
-#ifdef BCMDBG
+#ifdef DEBUG
 		/* Verify NVRAM bytes */
 		brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize);
 		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
@@ -3142,7 +3097,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
 			brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n");
 
 		kfree(nvram_ularray);
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 		kfree(vbuffer);
 	}
@@ -3569,9 +3524,9 @@ void brcmf_sdbrcm_isr(void *arg)
 
 static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 {
-#ifdef BCMDBG
+#ifdef DEBUG
 	struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
-#endif	/* BCMDBG */
+#endif	/* DEBUG */
 
 	brcmf_dbg(TIMER, "Enter\n");
 
@@ -3616,7 +3571,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 		/* Update interrupt tracking */
 		bus->lastintrs = bus->intrcount;
 	}
-#ifdef BCMDBG
+#ifdef DEBUG
 	/* Poll for console output periodically */
 	if (bus_if->state == BRCMF_BUS_DATA &&
 	    bus->console_interval != 0) {
@@ -3630,7 +3585,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
 				bus->console_interval = 0;
 		}
 	}
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	/* On idle timeout clear activity flag and/or turn off clock */
 	if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
@@ -3721,11 +3676,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
 	if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE))
 		brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n");
 
-#ifdef BCMDBG
-	printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n",
-	       brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
-
-#endif				/* BCMDBG */
+	pr_debug("F1 signature read @0x18000000=0x%4x\n",
+		 brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4));
 
 	/*
 	 * Force PLL off until brcmf_sdio_chip_attach()
@@ -3944,8 +3896,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 	bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
 					bus, "brcmf_watchdog");
 	if (IS_ERR(bus->watchdog_tsk)) {
-		printk(KERN_WARNING
-		       "brcmf_watchdog thread failed to start\n");
+		pr_warn("brcmf_watchdog thread failed to start\n");
 		bus->watchdog_tsk = NULL;
 	}
 	/* Initialize DPC thread */
@@ -3953,8 +3904,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
 	bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
 				   bus, "brcmf_dpc");
 	if (IS_ERR(bus->dpc_tsk)) {
-		printk(KERN_WARNING
-		       "brcmf_dpc thread failed to start\n");
+		pr_warn("brcmf_dpc thread failed to start\n");
 		bus->dpc_tsk = NULL;
 	}
 
@@ -4031,7 +3981,7 @@ void
 brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
 {
 	/* Totally stop the timer */
-	if (!wdtick && bus->wd_timer_valid == true) {
+	if (!wdtick && bus->wd_timer_valid) {
 		del_timer_sync(&bus->timer);
 		bus->wd_timer_valid = false;
 		bus->save_ms = wdtick;
@@ -4044,7 +3994,7 @@ brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick)
 
 	if (wdtick) {
 		if (bus->save_ms != BRCMF_WD_POLL_MS) {
-			if (bus->wd_timer_valid == true)
+			if (bus->wd_timer_valid)
 				/* Stop timer and restart at new value */
 				del_timer_sync(&bus->timer);
 
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 11b2d7c..1534efc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -15,6 +15,8 @@
  */
 /* ***** SDIO interface chip backplane handle functions ***** */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/mmc/card.h>
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index bf11850..74c95a5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -16,6 +16,8 @@
 
 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/if_arp.h>
 #include <linux/sched.h>
@@ -2783,7 +2785,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
 	    wiphy_new(&wl_cfg80211_ops,
 		      sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
 	if (!wdev->wiphy) {
-		WL_ERR("Couldn not allocate wiphy device\n");
+		WL_ERR("Could not allocate wiphy device\n");
 		err = -ENOMEM;
 		goto wiphy_new_out;
 	}
@@ -2809,7 +2811,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
 								 */
 	err = wiphy_register(wdev->wiphy);
 	if (err < 0) {
-		WL_ERR("Couldn not register wiphy device (%d)\n", err);
+		WL_ERR("Could not register wiphy device (%d)\n", err);
 		goto wiphy_register_out;
 	}
 	return wdev;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index a613b49..b5d9b36 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -32,63 +32,63 @@ struct brcmf_cfg80211_ibss;
 #define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
 				(WL_DBG_SCAN) | (WL_DBG_CONN))
 
-#define	WL_ERR(fmt, args...)					\
+#define	WL_ERR(fmt, ...)					\
 do {								\
 	if (brcmf_dbg_level & WL_DBG_ERR) {			\
 		if (net_ratelimit()) {				\
-			printk(KERN_ERR "ERROR @%s : " fmt,	\
-				__func__, ##args);		\
+			pr_err("ERROR @%s : " fmt,		\
+			       __func__, ##__VA_ARGS__);	\
 		}						\
 	}							\
 } while (0)
 
-#if (defined BCMDBG)
-#define	WL_INFO(fmt, args...)					\
+#if (defined DEBUG)
+#define	WL_INFO(fmt, ...)					\
 do {								\
 	if (brcmf_dbg_level & WL_DBG_INFO) {			\
 		if (net_ratelimit()) {				\
-			printk(KERN_ERR "INFO @%s : " fmt,	\
-				__func__, ##args);		\
+			pr_err("INFO @%s : " fmt,		\
+			       __func__, ##__VA_ARGS__);	\
 		}						\
 	}							\
 } while (0)
 
-#define	WL_TRACE(fmt, args...)					\
+#define	WL_TRACE(fmt, ...)					\
 do {								\
 	if (brcmf_dbg_level & WL_DBG_TRACE) {			\
 		if (net_ratelimit()) {				\
-			printk(KERN_ERR "TRACE @%s : " fmt,	\
-				__func__, ##args);		\
+			pr_err("TRACE @%s : " fmt,		\
+			       __func__, ##__VA_ARGS__);	\
 		}						\
 	}							\
 } while (0)
 
-#define	WL_SCAN(fmt, args...)					\
+#define	WL_SCAN(fmt, ...)					\
 do {								\
 	if (brcmf_dbg_level & WL_DBG_SCAN) {			\
 		if (net_ratelimit()) {				\
-			printk(KERN_ERR "SCAN @%s : " fmt,	\
-				__func__, ##args);		\
+			pr_err("SCAN @%s : " fmt,		\
+			       __func__, ##__VA_ARGS__);	\
 		}						\
 	}							\
 } while (0)
 
-#define	WL_CONN(fmt, args...)					\
+#define	WL_CONN(fmt, ...)					\
 do {								\
 	if (brcmf_dbg_level & WL_DBG_CONN) {			\
 		if (net_ratelimit()) {				\
-			printk(KERN_ERR "CONN @%s : " fmt,	\
-				__func__, ##args);		\
+			pr_err("CONN @%s : " fmt,		\
+			       __func__, ##__VA_ARGS__);	\
 		}						\
 	}							\
 } while (0)
 
-#else /* (defined BCMDBG) */
+#else /* (defined DEBUG) */
 #define	WL_INFO(fmt, args...)
 #define	WL_TRACE(fmt, args...)
 #define	WL_SCAN(fmt, args...)
 #define	WL_CONN(fmt, args...)
-#endif /* (defined BCMDBG) */
+#endif /* (defined DEBUG) */
 
 #define WL_NUM_SCAN_MAX		1
 #define WL_NUM_PMKIDS_MAX	MAXPMKID	/* will be used
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index ab9bb11..c93ea35 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -326,11 +326,11 @@
 
 #define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID))
 
-#ifdef BCMDBG
+#ifdef DEBUG
 #define	SI_MSG(fmt, ...)	pr_debug(fmt, ##__VA_ARGS__)
 #else
 #define	SI_MSG(fmt, ...)	no_printk(fmt, ##__VA_ARGS__)
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 #define	GOODCOREADDR(x, b) \
 	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
index 90911ee..d89dcb1 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
@@ -915,7 +915,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
 	struct wiphy *wiphy = wlc->wiphy;
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	u8 hole[AMPDU_MAX_MPDU];
 	memset(hole, 0, sizeof(hole));
 #endif
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 2e90a9a..11054ae 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -177,7 +177,7 @@
 #define BCMEXTRAHDROOM 172
 
 /* debug/trace */
-#ifdef BCMDBG
+#ifdef DEBUG
 #define	DMA_ERROR(fmt, ...)					\
 do {								\
 	if (*di->msg_level & 1)					\
@@ -193,7 +193,7 @@ do {								\
 	no_printk(fmt, ##__VA_ARGS__)
 #define	DMA_TRACE(fmt, ...)			\
 	no_printk(fmt, ##__VA_ARGS__)
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 #define	DMA_NONE(fmt, ...)			\
 	no_printk(fmt, ##__VA_ARGS__)
@@ -968,7 +968,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
 			pktcnt++;
 		}
 
-#ifdef BCMDBG
+#ifdef DEBUG
 		if (resid > 0) {
 			uint cur;
 			cur =
@@ -979,7 +979,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
 			DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
 				   di->rxin, di->rxout, cur);
 		}
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 		if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
 			DMA_ERROR("%s: bad frame length (%d)\n",
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 448ab9c..c842797 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -15,6 +15,7 @@
  */
 
 #define __UNDEF_NO_VERSION__
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
@@ -96,10 +97,10 @@ static struct bcma_device_id brcms_coreid_table[] = {
 };
 MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static int msglevel = 0xdeadbeef;
 module_param(msglevel, int, 0);
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 static struct ieee80211_channel brcms_2ghz_chantable[] = {
 	CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
@@ -857,7 +858,7 @@ static void brcms_free(struct brcms_info *wl)
 	/* free timers */
 	for (t = wl->timers; t; t = next) {
 		next = t->next;
-#ifdef BCMDBG
+#ifdef DEBUG
 		kfree(t->name);
 #endif
 		kfree(t);
@@ -1121,8 +1122,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
 
 	wl = brcms_attach(pdev);
 	if (!wl) {
-		pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME,
-		       __func__);
+		pr_err("%s: brcms_attach failed!\n", __func__);
 		return -ENODEV;
 	}
 	return 0;
@@ -1177,13 +1177,13 @@ static int __init brcms_module_init(void)
 {
 	int error = -ENODEV;
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	if (msglevel != 0xdeadbeef)
 		brcm_msg_level = msglevel;
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	error = bcma_driver_register(&brcms_bcma_driver);
-	printk(KERN_ERR "%s: register returned %d\n", __func__, error);
+	pr_err("%s: register returned %d\n", __func__, error);
 	if (!error)
 		return 0;
 
@@ -1367,7 +1367,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
 	t->next = wl->timers;
 	wl->timers = t;
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
 	if (t->name)
 		strcpy(t->name, name);
@@ -1386,7 +1386,7 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
 {
 	struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	if (t->set)
 		wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
 			  __func__, t->name, periodic);
@@ -1431,7 +1431,7 @@ void brcms_free_timer(struct brcms_timer *t)
 
 	if (wl->timers == t) {
 		wl->timers = wl->timers->next;
-#ifdef BCMDBG
+#ifdef DEBUG
 		kfree(t->name);
 #endif
 		kfree(t);
@@ -1443,7 +1443,7 @@ void brcms_free_timer(struct brcms_timer *t)
 	while (tmp) {
 		if (tmp->next == t) {
 			tmp->next = t->next;
-#ifdef BCMDBG
+#ifdef DEBUG
 			kfree(t->name);
 #endif
 			kfree(t);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 8f60419..9358bd5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -40,7 +40,7 @@ struct brcms_timer {
 	bool periodic;
 	bool set;		/* indicates if timer is active */
 	struct brcms_timer *next;	/* for freeing on unload */
-#ifdef BCMDBG
+#ifdef DEBUG
 	char *name;		/* Description of the timer */
 #endif
 };
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index f6affc6..90331dd 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/pci_ids.h>
 #include <linux/if_ether.h>
 #include <net/mac80211.h>
@@ -293,11 +295,11 @@ const u8 prio2fifo[NUMPRIO] = {
 
 /* debug/trace */
 uint brcm_msg_level =
-#if defined(BCMDBG)
+#if defined(DEBUG)
 	LOG_ERROR_VAL;
 #else
 	0;
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 /* TX FIFO number to WME/802.1E Access Category */
 static const u8 wme_fifo2ac[] = {
@@ -342,14 +344,14 @@ static const u16 xmtfifo_sz[][NFIFO] = {
 	{9, 58, 22, 14, 14, 5},
 };
 
-#ifdef BCMDBG
+#ifdef DEBUG
 static const char * const fifo_names[] = {
 	"AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" };
 #else
 static const char fifo_names[6][0];
 #endif
 
-#ifdef BCMDBG
+#ifdef DEBUG
 /* pointer to most recently allocated wl/wlc */
 static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL);
 #endif
@@ -3075,30 +3077,30 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
 {
 	int i;
 	struct macstat macstats;
-#ifdef BCMDBG
+#ifdef DEBUG
 	u16 delta;
 	u16 rxf0ovfl;
 	u16 txfunfl[NFIFO];
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	/* if driver down, make no sense to update stats */
 	if (!wlc->pub->up)
 		return;
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	/* save last rx fifo 0 overflow count */
 	rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl;
 
 	/* save last tx fifo  underflow count */
 	for (i = 0; i < NFIFO; i++)
 		txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i];
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	/* Read mac stats from contiguous shared memory */
 	brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats,
 				sizeof(struct macstat), OBJADDR_SHM_SEL);
 
-#ifdef BCMDBG
+#ifdef DEBUG
 	/* check for rx fifo 0 overflow */
 	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
 	if (delta)
@@ -3114,7 +3116,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc)
 			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
 				  "\n", wlc->pub->unit, delta, i);
 	}
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
 
 	/* merge counters from dma module */
 	for (i = 0; i < NFIFO; i++) {
@@ -3246,7 +3248,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
 	}
 
 	/* For old ucode, txfifo sizes needs to be modified(increased) */
-	if (fifosz_fixup == true)
+	if (fifosz_fixup)
 		brcms_b_corerev_fifofixup(wlc_hw);
 
 	/* check txfifo allocations match between ucode and driver */
@@ -5425,7 +5427,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config)
 		return -EINVAL;
 
 	/* update configuration value */
-	if (config == true)
+	if (config)
 		brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode);
 
 	/* Clear rateset override */
@@ -5765,62 +5767,49 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name,
 	return -ENODATA;
 }
 
-#ifdef BCMDBG
-static const char * const supr_reason[] = {
-	"None", "PMQ Entry", "Flush request",
-	"Previous frag failure", "Channel mismatch",
-	"Lifetime Expiry", "Underflow"
-};
-
-static void brcms_c_print_txs_status(u16 s)
-{
-	printk(KERN_DEBUG "[15:12]  %d  frame attempts\n",
-	       (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT);
-	printk(KERN_DEBUG " [11:8]  %d  rts attempts\n",
-	       (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT);
-	printk(KERN_DEBUG "    [7]  %d  PM mode indicated\n",
-	       ((s & TX_STATUS_PMINDCTD) ? 1 : 0));
-	printk(KERN_DEBUG "    [6]  %d  intermediate status\n",
-	       ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0));
-	printk(KERN_DEBUG "    [5]  %d  AMPDU\n",
-	       (s & TX_STATUS_AMPDU) ? 1 : 0);
-	printk(KERN_DEBUG "  [4:2]  %d  Frame Suppressed Reason (%s)\n",
-	       ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT),
-	       supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]);
-	printk(KERN_DEBUG "    [1]  %d  acked\n",
-	       ((s & TX_STATUS_ACK_RCV) ? 1 : 0));
-}
-#endif				/* BCMDBG */
-
 void brcms_c_print_txstatus(struct tx_status *txs)
 {
-#if defined(BCMDBG)
-	u16 s = txs->status;
-	u16 ackphyrxsh = txs->ackphyrxsh;
-
-	printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n");
-
-	printk(KERN_DEBUG "FrameID: %04x   ", txs->frameid);
-	printk(KERN_DEBUG "TxStatus: %04x", s);
-	printk(KERN_DEBUG "\n");
-
-	brcms_c_print_txs_status(s);
-
-	printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime);
-	printk(KERN_DEBUG "Seq: %04x ", txs->sequence);
-	printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr);
-	printk(KERN_DEBUG "RxAckRSSI: %04x ",
-	       (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT);
-	printk(KERN_DEBUG "RxAckSQ: %04x",
-	       (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
-	printk(KERN_DEBUG "\n");
-#endif				/* defined(BCMDBG) */
+	pr_debug("\ntxpkt (MPDU) Complete\n");
+
+	pr_debug("FrameID: %04x   TxStatus: %04x\n", txs->frameid, txs->status);
+
+	pr_debug("[15:12]  %d  frame attempts\n",
+		  (txs->status & TX_STATUS_FRM_RTX_MASK) >>
+		 TX_STATUS_FRM_RTX_SHIFT);
+	pr_debug(" [11:8]  %d  rts attempts\n",
+		 (txs->status & TX_STATUS_RTS_RTX_MASK) >>
+		 TX_STATUS_RTS_RTX_SHIFT);
+	pr_debug("    [7]  %d  PM mode indicated\n",
+		 txs->status & TX_STATUS_PMINDCTD ? 1 : 0);
+	pr_debug("    [6]  %d  intermediate status\n",
+		 txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0);
+	pr_debug("    [5]  %d  AMPDU\n",
+		 txs->status & TX_STATUS_AMPDU ? 1 : 0);
+	pr_debug("  [4:2]  %d  Frame Suppressed Reason (%s)\n",
+		 (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT,
+		 (const char *[]) {
+			"None",
+			"PMQ Entry",
+			"Flush request",
+			"Previous frag failure",
+			"Channel mismatch",
+			"Lifetime Expiry",
+			"Underflow"
+		 } [(txs->status & TX_STATUS_SUPR_MASK) >>
+		    TX_STATUS_SUPR_SHIFT]);
+	pr_debug("    [1]  %d  acked\n",
+		 txs->status & TX_STATUS_ACK_RCV ? 1 : 0);
+
+	pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n",
+		 txs->lasttxtime, txs->sequence, txs->phyerr,
+		 (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT,
+		 (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT);
 }
 
 bool brcms_c_chipmatch(u16 vendor, u16 device)
 {
 	if (vendor != PCI_VENDOR_ID_BROADCOM) {
-		pr_err("chipmatch: unknown vendor id %04x\n", vendor);
+		pr_err("unknown vendor id %04x\n", vendor);
 		return false;
 	}
 
@@ -5833,11 +5822,11 @@ bool brcms_c_chipmatch(u16 vendor, u16 device)
 	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
 		return true;
 
-	pr_err("chipmatch: unknown device id %04x\n", device);
+	pr_err("unknown device id %04x\n", device);
 	return false;
 }
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 void brcms_c_print_txdesc(struct d11txh *txh)
 {
 	u16 mtcl = le16_to_cpu(txh->MacTxControlLow);
@@ -5871,57 +5860,56 @@ void brcms_c_print_txdesc(struct d11txh *txh)
 	struct ieee80211_rts rts = txh->rts_frame;
 
 	/* add plcp header along with txh descriptor */
-	printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
-	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
-			     txh, sizeof(struct d11txh) + 48);
-
-	printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
-	printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
-	printk(KERN_DEBUG "FC: %04x ", mfc);
-	printk(KERN_DEBUG "FES Time: %04x\n", tfest);
-	printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw,
+	brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48,
+			   "Raw TxDesc + plcp header:\n");
+
+	pr_debug("TxCtlLow: %04x ", mtcl);
+	pr_debug("TxCtlHigh: %04x ", mtch);
+	pr_debug("FC: %04x ", mfc);
+	pr_debug("FES Time: %04x\n", tfest);
+	pr_debug("PhyCtl: %04x%s ", ptcw,
 	       (ptcw & PHY_TXC_SHORT_HDR) ? " short" : "");
-	printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1);
-	printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
-	printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
-	printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
-	printk(KERN_DEBUG "MainRates: %04x ", mainrates);
-	printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft);
-	printk(KERN_DEBUG "\n");
+	pr_debug("PhyCtl_1: %04x ", ptcw_1);
+	pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr);
+	pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts);
+	pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts);
+	pr_debug("MainRates: %04x ", mainrates);
+	pr_debug("XtraFrameTypes: %04x ", xtraft);
+	pr_debug("\n");
 
 	print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV));
 	print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET,
 			     ra, sizeof(txh->TxFrameRA));
 
-	printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb);
+	pr_debug("Fb FES Time: %04x ", tfestfb);
 	print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET,
 			     rtspfb, sizeof(txh->RTSPLCPFallback));
-	printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb);
+	pr_debug("RTS DUR: %04x ", rtsdfb);
 	print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET,
 			     fragpfb, sizeof(txh->FragPLCPFallback));
-	printk(KERN_DEBUG "DUR: %04x", fragdfb);
-	printk(KERN_DEBUG "\n");
+	pr_debug("DUR: %04x", fragdfb);
+	pr_debug("\n");
 
-	printk(KERN_DEBUG "MModeLen: %04x ", mmodelen);
-	printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen);
+	pr_debug("MModeLen: %04x ", mmodelen);
+	pr_debug("MModeFbrLen: %04x\n", mmodefbrlen);
 
-	printk(KERN_DEBUG "FrameID:     %04x\n", tfid);
-	printk(KERN_DEBUG "TxStatus:    %04x\n", txs);
+	pr_debug("FrameID:     %04x\n", tfid);
+	pr_debug("TxStatus:    %04x\n", txs);
 
-	printk(KERN_DEBUG "MaxNumMpdu:  %04x\n", mnmpdu);
-	printk(KERN_DEBUG "MaxAggbyte:  %04x\n", mabyte);
-	printk(KERN_DEBUG "MaxAggbyte_fb:  %04x\n", mabyte_f);
-	printk(KERN_DEBUG "MinByte:     %04x\n", mmbyte);
+	pr_debug("MaxNumMpdu:  %04x\n", mnmpdu);
+	pr_debug("MaxAggbyte:  %04x\n", mabyte);
+	pr_debug("MaxAggbyte_fb:  %04x\n", mabyte_f);
+	pr_debug("MinByte:     %04x\n", mmbyte);
 
 	print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET,
 			     rtsph, sizeof(txh->RTSPhyHeader));
 	print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET,
 			     (u8 *)&rts, sizeof(txh->rts_frame));
-	printk(KERN_DEBUG "\n");
+	pr_debug("\n");
 }
-#endif				/* defined(BCMDBG) */
+#endif				/* defined(DEBUG) */
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 static int
 brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
 		     int len)
@@ -5975,9 +5963,9 @@ brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf,
 
 	return (int)(p - buf);
 }
-#endif				/* defined(BCMDBG) */
+#endif				/* defined(DEBUG) */
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 void brcms_c_print_rxh(struct d11rxhdr *rxh)
 {
 	u16 len = rxh->RxFrameSize;
@@ -5999,24 +5987,22 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh)
 		{0, NULL}
 	};
 
-	printk(KERN_DEBUG "Raw RxDesc:\n");
-	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh,
-			     sizeof(struct d11rxhdr));
+	brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n");
 
 	brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64);
 
 	snprintf(lenbuf, sizeof(lenbuf), "0x%x", len);
 
-	printk(KERN_DEBUG "RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
+	pr_debug("RxFrameSize:     %6s (%d)%s\n", lenbuf, len,
 	       (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : "");
-	printk(KERN_DEBUG "RxPHYStatus:     %04x %04x %04x %04x\n",
+	pr_debug("RxPHYStatus:     %04x %04x %04x %04x\n",
 	       phystatus_0, phystatus_1, phystatus_2, phystatus_3);
-	printk(KERN_DEBUG "RxMACStatus:     %x %s\n", macstatus1, flagstr);
-	printk(KERN_DEBUG "RXMACaggtype:    %x\n",
+	pr_debug("RxMACStatus:     %x %s\n", macstatus1, flagstr);
+	pr_debug("RXMACaggtype:    %x\n",
 	       (macstatus2 & RXS_AGGTYPE_MASK));
-	printk(KERN_DEBUG "RxTSFTime:       %04x\n", rxh->RxTSFTime);
+	pr_debug("RxTSFTime:       %04x\n", rxh->RxTSFTime);
 }
-#endif				/* defined(BCMDBG) */
+#endif				/* defined(DEBUG) */
 
 u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate)
 {
@@ -8354,7 +8340,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
 	wlc->wiphy = wl->wiphy;
 	pub = wlc->pub;
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 	wlc_info_dbg = wlc;
 #endif
 
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index adb136e..8debc74 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -648,10 +648,12 @@ extern void brcms_c_print_txstatus(struct tx_status *txs);
 extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
 		   uint *blocks);
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 extern void brcms_c_print_txdesc(struct d11txh *txh);
 #else
-#define brcms_c_print_txdesc(a)
+static inline void brcms_c_print_txdesc(struct d11txh *txh)
+{
+}
 #endif
 
 extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index a16f1ab..62eedd8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/cordic.h>
@@ -21462,7 +21464,7 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
 	if (NREV_GE(pi->pubpi.phy_rev, 3)) {
 		u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188;
 
-		if (lut_init == false)
+		if (!lut_init)
 			return;
 
 		if (pi->srom_fem2g.antswctrllut == 0) {
@@ -26434,8 +26436,7 @@ cal_try:
 	}
 
 	if (bcmerror != 0) {
-		printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__,
-		       cal_retry);
+		pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry);
 
 		if (cal_retry < CAL_RETRY_CNT) {
 			cal_retry++;
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index b7537f7..b45ab34 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -14,6 +14,8 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/netdevice.h>
 #include <linux/module.h>
 
@@ -240,17 +242,35 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
 }
 EXPORT_SYMBOL(brcmu_pktq_mdeq);
 
-#if defined(BCMDBG)
+#if defined(DEBUG)
 /* pretty hex print a pkt buffer chain */
 void brcmu_prpkt(const char *msg, struct sk_buff *p0)
 {
 	struct sk_buff *p;
 
 	if (msg && (msg[0] != '\0'))
-		printk(KERN_DEBUG "%s:\n", msg);
+		pr_debug("%s:\n", msg);
 
 	for (p = p0; p; p = p->next)
 		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
 }
 EXPORT_SYMBOL(brcmu_prpkt);
-#endif				/* defined(BCMDBG) */
+
+void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	pr_debug("%pV", &vaf);
+
+	va_end(args);
+
+	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size);
+}
+EXPORT_SYMBOL(brcmu_dbg_hex_dump);
+#endif				/* defined(DEBUG) */
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index ad249a0..477b92a 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -176,10 +176,21 @@ struct ipv4_addr;
 
 /* externs */
 /* format/print */
-#ifdef BCMDBG
+#ifdef DEBUG
 extern void brcmu_prpkt(const char *msg, struct sk_buff *p0);
 #else
 #define brcmu_prpkt(a, b)
-#endif				/* BCMDBG */
+#endif				/* DEBUG */
+
+#ifdef DEBUG
+extern __printf(3, 4)
+void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...);
+#else
+__printf(3, 4)
+static inline
+void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
+{
+}
+#endif
 
 #endif				/* _BRCMU_UTILS_H_ */
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index a8bddd8..50f87b6 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -347,11 +347,9 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0,
 		return -EINTR;
 
 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
-	if (entry == NULL) {
-		printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n",
-		       dev->name);
+	if (entry == NULL)
 		return -ENOMEM;
-	}
+
 	atomic_set(&entry->usecnt, 1);
 	entry->type = CMD_SLEEP;
 	entry->cmd = cmd;
@@ -515,11 +513,9 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0,
 	}
 
 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
-	if (entry == NULL) {
-		printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc "
-		       "failed\n", dev->name);
+	if (entry == NULL)
 		return -ENOMEM;
-	}
+
 	atomic_set(&entry->usecnt, 1);
 	entry->type = CMD_CALLBACK;
 	entry->cmd = cmd;
@@ -1470,7 +1466,7 @@ static int prism2_hw_enable(struct net_device *dev, int initial)
 	 * before it starts acting as an AP, so reset port automatically
 	 * here just in case */
 	if (initial && prism2_reset_port(dev)) {
-		printk("%s: MAC port 0 reseting failed\n", dev->name);
+		printk("%s: MAC port 0 resetting failed\n", dev->name);
 		return 1;
 	}
 
@@ -1561,7 +1557,7 @@ static void prism2_hw_reset(struct net_device *dev)
 	static long last_reset = 0;
 
 	/* do not reset card more than once per second to avoid ending up in a
-	 * busy loop reseting the card */
+	 * busy loop resetting the card */
 	if (time_before_eq(jiffies, last_reset + HZ))
 		return;
 	last_reset = jiffies;
@@ -2978,11 +2974,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set)
 	local = iface->local;
 
 	new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC);
-	if (new_entry == NULL) {
-		printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n",
-		       local->dev->name);
+	if (new_entry == NULL)
 		return -ENOMEM;
-	}
+
 	new_entry->aid = aid;
 	new_entry->set = set;
 
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index a0e5c21..e847737 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -3464,11 +3464,8 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
 	priv->msg_buffers =
 	    kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
 		    GFP_KERNEL);
-	if (!priv->msg_buffers) {
-		printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
-		       "buffers.\n", priv->net_dev->name);
+	if (!priv->msg_buffers)
 		return -ENOMEM;
-	}
 
 	for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
 		v = pci_alloc_consistent(priv->pci_dev,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index d5ef696..3adb240 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -150,10 +150,9 @@ struct net_device *alloc_libipw(int sizeof_priv, int monitor)
 	LIBIPW_DEBUG_INFO("Initializing...\n");
 
 	dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
-	if (!dev) {
-		LIBIPW_ERROR("Unable to allocate network device.\n");
+	if (!dev)
 		goto failed;
-	}
+
 	ieee = netdev_priv(dev);
 
 	ieee->dev = dev;
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 32a9966..c4955d2 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -172,7 +172,7 @@ libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb,
 			u16 stype)
 {
 	if (ieee->iw_mode == IW_MODE_MASTER) {
-		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
+		printk(KERN_DEBUG "%s: Master mode not yet supported.\n",
 		       ieee->dev->name);
 		return 0;
 /*
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index 54b2d39..aa8f5c0 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -140,7 +140,7 @@ il3945_set_ccmp_dynamic_key_info(struct il_priv *il,
 	key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
 	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
 
-	if (sta_id == il->ctx.bcast_sta_id)
+	if (sta_id == il->hw_params.bcast_id)
 		key_flags |= STA_KEY_MULTICAST_MSK;
 
 	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -341,7 +341,7 @@ il3945_send_beacon_cmd(struct il_priv *il)
 		return -ENOMEM;
 	}
 
-	rate = il_get_lowest_plcp(il, &il->ctx);
+	rate = il_get_lowest_plcp(il);
 
 	frame_size = il3945_hw_get_beacon_cmd(il, frame, rate);
 
@@ -512,7 +512,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
 	hdr_len = ieee80211_hdrlen(fc);
 
 	/* Find idx into station table for destination station */
-	sta_id = il_sta_id_or_broadcast(il, &il->ctx, info->control.sta);
+	sta_id = il_sta_id_or_broadcast(il, info->control.sta);
 	if (sta_id == IL_INVALID_STATION) {
 		D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1);
 		goto drop;
@@ -538,10 +538,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
 	idx = il_get_cmd_idx(q, q->write_ptr, 0);
 
-	/* Set up driver data for this TFD */
-	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
-	txq->txb[q->write_ptr].skb = skb;
-	txq->txb[q->write_ptr].ctx = &il->ctx;
+	txq->skbs[q->write_ptr] = skb;
 
 	/* Init first empty entry in queue's array of Tx/cmd buffers */
 	out_cmd = txq->cmd[idx];
@@ -619,8 +616,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
-	il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1,
-						 0);
+	il->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0);
 
 	/* Set up TFD's 2nd entry to point directly to remainder of skb,
 	 * if any (802.11 null frames have no payload). */
@@ -629,8 +625,8 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
 		phys_addr =
 		    pci_map_single(il->pci_dev, skb->data + hdr_len, len,
 				   PCI_DMA_TODEVICE);
-		il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
-							 len, 0, U32_PAD(len));
+		il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
+						    U32_PAD(len));
 	}
 
 	/* Tell device the write idx *just past* this latest filled TFD */
@@ -672,15 +668,13 @@ il3945_get_measurement(struct il_priv *il,
 	int rc;
 	int spectrum_resp_status;
 	int duration = le16_to_cpu(params->duration);
-	struct il_rxon_context *ctx = &il->ctx;
 
 	if (il_is_associated(il))
 		add_time =
 		    il_usecs_to_beacons(il,
 					le64_to_cpu(params->start_time) -
 					il->_3945.last_tsf,
-					le16_to_cpu(ctx->timing.
-						    beacon_interval));
+					le16_to_cpu(il->timing.beacon_interval));
 
 	memset(&spectrum, 0, sizeof(spectrum));
 
@@ -694,15 +688,14 @@ il3945_get_measurement(struct il_priv *il,
 	if (il_is_associated(il))
 		spectrum.start_time =
 		    il_add_beacon_time(il, il->_3945.last_beacon_time, add_time,
-				       le16_to_cpu(ctx->timing.
-						   beacon_interval));
+				       le16_to_cpu(il->timing.beacon_interval));
 	else
 		spectrum.start_time = 0;
 
 	spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
 	spectrum.channels[0].channel = params->channel;
 	spectrum.channels[0].type = type;
-	if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
+	if (il->active.flags & RXON_FLG_BAND_24G_MSK)
 		spectrum.flags |=
 		    RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
 		    RXON_FLG_TGG_PROTECT_MSK;
@@ -2150,7 +2143,6 @@ il3945_alive_start(struct il_priv *il)
 {
 	int thermal_spin = 0;
 	u32 rfkill;
-	struct il_rxon_context *ctx = &il->ctx;
 
 	D_INFO("Runtime Alive received.\n");
 
@@ -2206,13 +2198,13 @@ il3945_alive_start(struct il_priv *il)
 
 	if (il_is_associated(il)) {
 		struct il3945_rxon_cmd *active_rxon =
-		    (struct il3945_rxon_cmd *)(&ctx->active);
+		    (struct il3945_rxon_cmd *)(&il->active);
 
-		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+		il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	} else {
 		/* Initialize our rx_config data */
-		il_connection_init_rx_config(il, ctx);
+		il_connection_init_rx_config(il);
 	}
 
 	/* Configure Bluetooth device coexistence support */
@@ -2221,7 +2213,7 @@ il3945_alive_start(struct il_priv *il)
 	set_bit(S_READY, &il->status);
 
 	/* Configure the adapter for unassociated operation */
-	il3945_commit_rxon(il, ctx);
+	il3945_commit_rxon(il);
 
 	il3945_reg_txpower_periodic(il);
 
@@ -2253,7 +2245,7 @@ __il3945_down(struct il_priv *il)
 	del_timer_sync(&il->watchdog);
 
 	/* Station information will now be cleared in device */
-	il_clear_ucode_stations(il, NULL);
+	il_clear_ucode_stations(il);
 	il_dealloc_bcast_stations(il);
 	il_clear_driver_stations(il);
 
@@ -2339,12 +2331,11 @@ il3945_down(struct il_priv *il)
 static int
 il3945_alloc_bcast_station(struct il_priv *il)
 {
-	struct il_rxon_context *ctx = &il->ctx;
 	unsigned long flags;
 	u8 sta_id;
 
 	spin_lock_irqsave(&il->sta_lock, flags);
-	sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL);
+	sta_id = il_prep_station(il, il_bcast_addr, false, NULL);
 	if (sta_id == IL_INVALID_STATION) {
 		IL_ERR("Unable to prepare broadcast station\n");
 		spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -2422,7 +2413,7 @@ __il3945_up(struct il_priv *il)
 		/* load bootstrap state machine,
 		 * load bootstrap program into processor's memory,
 		 * prepare to load the "initialize" uCode */
-		rc = il->cfg->ops->lib->load_ucode(il);
+		rc = il->ops->lib->load_ucode(il);
 
 		if (rc) {
 			IL_ERR("Unable to set up bootstrap uCode: %d\n", rc);
@@ -2602,7 +2593,7 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 	/* We don't build a direct scan probe request; the uCode will do
 	 * that based on the direct_mask added to each channel entry */
 	scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-	scan->tx_cmd.sta_id = il->ctx.bcast_sta_id;
+	scan->tx_cmd.sta_id = il->hw_params.bcast_id;
 	scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
 	/* flags + rate selection */
@@ -2664,14 +2655,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 void
 il3945_post_scan(struct il_priv *il)
 {
-	struct il_rxon_context *ctx = &il->ctx;
-
 	/*
 	 * Since setting the RXON may have been deferred while
 	 * performing the scan, fire one off if needed
 	 */
-	if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
-		il3945_commit_rxon(il, ctx);
+	if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
+		il3945_commit_rxon(il);
 }
 
 static void
@@ -2684,7 +2673,8 @@ il3945_bg_restart(struct work_struct *data)
 
 	if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
 		mutex_lock(&il->mutex);
-		il->ctx.vif = NULL;
+		/* FIXME: vif can be dereferenced */
+		il->vif = NULL;
 		il->is_open = 0;
 		mutex_unlock(&il->mutex);
 		il3945_down(il);
@@ -2722,13 +2712,12 @@ il3945_post_associate(struct il_priv *il)
 {
 	int rc = 0;
 	struct ieee80211_conf *conf = NULL;
-	struct il_rxon_context *ctx = &il->ctx;
 
-	if (!ctx->vif || !il->is_open)
+	if (!il->vif || !il->is_open)
 		return;
 
-	D_ASSOC("Associated as %d to: %pM\n", ctx->vif->bss_conf.aid,
-		ctx->active.bssid_addr);
+	D_ASSOC("Associated as %d to: %pM\n", il->vif->bss_conf.aid,
+		il->active.bssid_addr);
 
 	if (test_bit(S_EXIT_PENDING, &il->status))
 		return;
@@ -2737,35 +2726,35 @@ il3945_post_associate(struct il_priv *il)
 
 	conf = &il->hw->conf;
 
-	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	il3945_commit_rxon(il, ctx);
+	il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+	il3945_commit_rxon(il);
 
-	rc = il_send_rxon_timing(il, ctx);
+	rc = il_send_rxon_timing(il);
 	if (rc)
 		IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n");
 
-	ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+	il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
-	ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
+	il->staging.assoc_id = cpu_to_le16(il->vif->bss_conf.aid);
 
-	D_ASSOC("assoc id %d beacon interval %d\n", ctx->vif->bss_conf.aid,
-		ctx->vif->bss_conf.beacon_int);
+	D_ASSOC("assoc id %d beacon interval %d\n", il->vif->bss_conf.aid,
+		il->vif->bss_conf.beacon_int);
 
-	if (ctx->vif->bss_conf.use_short_preamble)
-		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+	if (il->vif->bss_conf.use_short_preamble)
+		il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 	else
-		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+		il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-	if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
-		if (ctx->vif->bss_conf.use_short_slot)
-			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+	if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
+		if (il->vif->bss_conf.use_short_slot)
+			il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+			il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 	}
 
-	il3945_commit_rxon(il, ctx);
+	il3945_commit_rxon(il);
 
-	switch (ctx->vif->type) {
+	switch (il->vif->type) {
 	case NL80211_IFTYPE_STATION:
 		il3945_rate_scale_init(il->hw, IL_AP_ID);
 		break;
@@ -2774,7 +2763,7 @@ il3945_post_associate(struct il_priv *il)
 		break;
 	default:
 		IL_ERR("%s Should not be called in %d mode\n", __func__,
-		       ctx->vif->type);
+		      il->vif->type);
 		break;
 	}
 }
@@ -2891,8 +2880,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 void
 il3945_config_ap(struct il_priv *il)
 {
-	struct il_rxon_context *ctx = &il->ctx;
-	struct ieee80211_vif *vif = ctx->vif;
+	struct ieee80211_vif *vif = il->vif;
 	int rc = 0;
 
 	if (test_bit(S_EXIT_PENDING, &il->status))
@@ -2902,31 +2890,31 @@ il3945_config_ap(struct il_priv *il)
 	if (!(il_is_associated(il))) {
 
 		/* RXON - unassoc (to set timing command) */
-		ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-		il3945_commit_rxon(il, ctx);
+		il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+		il3945_commit_rxon(il);
 
 		/* RXON Timing */
-		rc = il_send_rxon_timing(il, ctx);
+		rc = il_send_rxon_timing(il);
 		if (rc)
 			IL_WARN("C_RXON_TIMING failed - "
 				"Attempting to continue.\n");
 
-		ctx->staging.assoc_id = 0;
+		il->staging.assoc_id = 0;
 
 		if (vif->bss_conf.use_short_preamble)
-			ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+			il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+			il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-		if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+		if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
 			if (vif->bss_conf.use_short_slot)
-				ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+				il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 			else
-				ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+				il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 		}
 		/* restore RXON assoc */
-		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-		il3945_commit_rxon(il, ctx);
+		il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+		il3945_commit_rxon(il);
 	}
 	il3945_send_beacon_cmd(il);
 }
@@ -2959,7 +2947,7 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	static_key = !il_is_associated(il);
 
 	if (!static_key) {
-		sta_id = il_sta_id_or_broadcast(il, &il->ctx, sta);
+		sta_id = il_sta_id_or_broadcast(il, sta);
 		if (sta_id == IL_INVALID_STATION)
 			return -EINVAL;
 	}
@@ -3007,8 +2995,7 @@ il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	D_INFO("proceeding to add station %pM\n", sta->addr);
 	sta_priv->common.sta_id = IL_INVALID_STATION;
 
-	ret =
-	    il_add_station_common(il, &il->ctx, sta->addr, is_ap, sta, &sta_id);
+	ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
 	if (ret) {
 		IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret);
 		/* Should we return success if return code is EEXIST ? */
@@ -3032,7 +3019,6 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 {
 	struct il_priv *il = hw->priv;
 	__le32 filter_or = 0, filter_nand = 0;
-	struct il_rxon_context *ctx = &il->ctx;
 
 #define CHK(test, flag)	do { \
 	if (*total_flags & (test))		\
@@ -3052,8 +3038,8 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
 	mutex_lock(&il->mutex);
 
-	ctx->staging.filter_flags &= ~filter_nand;
-	ctx->staging.filter_flags |= filter_or;
+	il->staging.filter_flags &= ~filter_nand;
+	il->staging.filter_flags |= filter_or;
 
 	/*
 	 * Not committing directly because hardware can perform a scan,
@@ -3170,9 +3156,8 @@ static ssize_t
 il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf)
 {
 	struct il_priv *il = dev_get_drvdata(d);
-	struct il_rxon_context *ctx = &il->ctx;
 
-	return sprintf(buf, "0x%04X\n", ctx->active.flags);
+	return sprintf(buf, "0x%04X\n", il->active.flags);
 }
 
 static ssize_t
@@ -3181,17 +3166,16 @@ il3945_store_flags(struct device *d, struct device_attribute *attr,
 {
 	struct il_priv *il = dev_get_drvdata(d);
 	u32 flags = simple_strtoul(buf, NULL, 0);
-	struct il_rxon_context *ctx = &il->ctx;
 
 	mutex_lock(&il->mutex);
-	if (le32_to_cpu(ctx->staging.flags) != flags) {
+	if (le32_to_cpu(il->staging.flags) != flags) {
 		/* Cancel any currently running scans... */
 		if (il_scan_cancel_timeout(il, 100))
 			IL_WARN("Could not cancel scan.\n");
 		else {
 			D_INFO("Committing rxon.flags = 0x%04X\n", flags);
-			ctx->staging.flags = cpu_to_le32(flags);
-			il3945_commit_rxon(il, ctx);
+			il->staging.flags = cpu_to_le32(flags);
+			il3945_commit_rxon(il);
 		}
 	}
 	mutex_unlock(&il->mutex);
@@ -3207,9 +3191,8 @@ il3945_show_filter_flags(struct device *d, struct device_attribute *attr,
 			 char *buf)
 {
 	struct il_priv *il = dev_get_drvdata(d);
-	struct il_rxon_context *ctx = &il->ctx;
 
-	return sprintf(buf, "0x%04X\n", le32_to_cpu(ctx->active.filter_flags));
+	return sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
 }
 
 static ssize_t
@@ -3217,19 +3200,18 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr,
 			  const char *buf, size_t count)
 {
 	struct il_priv *il = dev_get_drvdata(d);
-	struct il_rxon_context *ctx = &il->ctx;
 	u32 filter_flags = simple_strtoul(buf, NULL, 0);
 
 	mutex_lock(&il->mutex);
-	if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
+	if (le32_to_cpu(il->staging.filter_flags) != filter_flags) {
 		/* Cancel any currently running scans... */
 		if (il_scan_cancel_timeout(il, 100))
 			IL_WARN("Could not cancel scan.\n");
 		else {
 			D_INFO("Committing rxon.filter_flags = " "0x%04X\n",
 			       filter_flags);
-			ctx->staging.filter_flags = cpu_to_le32(filter_flags);
-			il3945_commit_rxon(il, ctx);
+			il->staging.filter_flags = cpu_to_le32(filter_flags);
+			il3945_commit_rxon(il);
 		}
 	}
 	mutex_unlock(&il->mutex);
@@ -3278,9 +3260,8 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
 			 const char *buf, size_t count)
 {
 	struct il_priv *il = dev_get_drvdata(d);
-	struct il_rxon_context *ctx = &il->ctx;
 	struct ieee80211_measurement_params params = {
-		.channel = le16_to_cpu(ctx->active.channel),
+		.channel = le16_to_cpu(il->active.channel),
 		.start_time = cpu_to_le64(il->_3945.last_tsf),
 		.duration = cpu_to_le16(1),
 	};
@@ -3474,7 +3455,7 @@ static struct attribute_group il3945_attribute_group = {
 	.attrs = il3945_sysfs_entries,
 };
 
-struct ieee80211_ops il3945_hw_ops = {
+struct ieee80211_ops il3945_mac_ops = {
 	.tx = il3945_mac_tx,
 	.start = il3945_mac_start,
 	.stop = il3945_mac_stop,
@@ -3567,7 +3548,8 @@ il3945_setup_mac(struct il_priv *il)
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT;
 
-	hw->wiphy->interface_modes = il->ctx.interface_modes;
+	hw->wiphy->interface_modes =
+	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
 
 	hw->wiphy->flags |=
 	    WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
@@ -3614,44 +3596,29 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 * 1. Allocating HW data
 	 * ********************/
 
-	/* mac80211 allocates memory for this device instance, including
-	 *   space for this driver's ilate structure */
-	hw = il_alloc_all(cfg);
-	if (hw == NULL) {
-		pr_err("Can not allocate network device\n");
+	hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il3945_mac_ops);
+	if (!hw) {
 		err = -ENOMEM;
 		goto out;
 	}
 	il = hw->priv;
+	il->hw = hw;
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 
 	il->cmd_queue = IL39_CMD_QUEUE_NUM;
 
-	il->ctx.ctxid = 0;
-
-	il->ctx.rxon_cmd = C_RXON;
-	il->ctx.rxon_timing_cmd = C_RXON_TIMING;
-	il->ctx.rxon_assoc_cmd = C_RXON_ASSOC;
-	il->ctx.qos_cmd = C_QOS_PARAM;
-	il->ctx.ap_sta_id = IL_AP_ID;
-	il->ctx.wep_key_cmd = C_WEPKEY;
-	il->ctx.interface_modes =
-	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
-	il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
-	il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
-	il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
-
 	/*
 	 * Disabling hardware scan means that mac80211 will perform scans
 	 * "the hard way", rather than using device's scan.
 	 */
 	if (il3945_mod_params.disable_hw_scan) {
 		D_INFO("Disabling hw_scan\n");
-		il3945_hw_ops.hw_scan = NULL;
+		il3945_mac_ops.hw_scan = NULL;
 	}
 
 	D_INFO("*** LOAD DRIVER ***\n");
 	il->cfg = cfg;
+	il->ops = &il3945_ops;
 	il->pci_dev = pdev;
 	il->inta_mask = CSR_INI_SET_MASK;
 
@@ -3773,8 +3740,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto out_release_irq;
 	}
 
-	il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5],
-			    &il->ctx);
+	il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5]);
 	il3945_setup_deferred_work(il);
 	il3945_setup_handlers(il);
 	il_power_initialize(il);
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index d7a83f2..70bee1a 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -342,7 +342,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
 	int i;
 
 	D_INFO("enter\n");
-	if (sta_id == il->ctx.bcast_sta_id)
+	if (sta_id == il->hw_params.bcast_id)
 		goto out;
 
 	psta = (struct il3945_sta_priv *)sta->drv_priv;
@@ -927,8 +927,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 
 	rcu_read_lock();
 
-	sta =
-	    ieee80211_find_sta(il->ctx.vif, il->stations[sta_id].sta.sta.addr);
+	sta = ieee80211_find_sta(il->vif, il->stations[sta_id].sta.sta.addr);
 	if (!sta) {
 		D_RATE("Unable to find station to initialize rate scaling.\n");
 		rcu_read_unlock();
@@ -944,7 +943,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 	switch (il->band) {
 	case IEEE80211_BAND_2GHZ:
 		/* TODO: this always does G, not a regression */
-		if (il->ctx.active.flags & RXON_FLG_TGG_PROTECT_MSK) {
+		if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) {
 			rs_sta->tgg = 1;
 			rs_sta->expected_tpt = il3945_expected_tpt_g_prot;
 		} else
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index 1489b15..6c1ae5f 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -293,17 +293,17 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
 {
 	struct il_tx_queue *txq = &il->txq[txq_id];
 	struct il_queue *q = &txq->q;
-	struct il_tx_info *tx_info;
+	struct sk_buff *skb;
 
 	BUG_ON(txq_id == IL39_CMD_QUEUE_NUM);
 
 	for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
 	     q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
-		tx_info = &txq->txb[txq->q.read_ptr];
-		ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
-		tx_info->skb = NULL;
-		il->cfg->ops->lib->txq_free_tfd(il, txq);
+		skb = txq->skbs[txq->q.read_ptr];
+		ieee80211_tx_status_irqsafe(il->hw, skb);
+		txq->skbs[txq->q.read_ptr] = NULL;
+		il->ops->lib->txq_free_tfd(il, txq);
 	}
 
 	if (il_queue_space(q) > q->low_mark && txq_id >= 0 &&
@@ -336,7 +336,7 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
 	}
 
 	txq->time_stamp = jiffies;
-	info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+	info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);
 	ieee80211_tx_info_clear_status(info);
 
 	/* Fill the MRR chain with some info about on-chip retransmissions */
@@ -660,15 +660,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
 				 PCI_DMA_TODEVICE);
 
 	/* free SKB */
-	if (txq->txb) {
-		struct sk_buff *skb;
-
-		skb = txq->txb[txq->q.read_ptr].skb;
+	if (txq->skbs) {
+		struct sk_buff *skb = txq->skbs[txq->q.read_ptr];
 
 		/* can be called from irqs-disabled context */
 		if (skb) {
 			dev_kfree_skb_any(skb);
-			txq->txb[txq->q.read_ptr].skb = NULL;
+			txq->skbs[txq->q.read_ptr] = NULL;
 		}
 	}
 }
@@ -960,12 +958,12 @@ il3945_hw_nic_init(struct il_priv *il)
 	struct il_rx_queue *rxq = &il->rxq;
 
 	spin_lock_irqsave(&il->lock, flags);
-	il->cfg->ops->lib->apm_ops.init(il);
+	il->ops->lib->apm_ops.init(il);
 	spin_unlock_irqrestore(&il->lock, flags);
 
 	il3945_set_pwr_vmain(il);
 
-	il->cfg->ops->lib->apm_ops.config(il);
+	il->ops->lib->apm_ops.config(il);
 
 	/* Allocate the RX queue, or reset if it is already allocated */
 	if (!rxq->bd) {
@@ -1388,7 +1386,7 @@ il3945_send_tx_power(struct il_priv *il)
 	int rate_idx, i;
 	const struct il_channel_info *ch_info = NULL;
 	struct il3945_txpowertable_cmd txpower = {
-		.channel = il->ctx.active.channel,
+		.channel = il->active.channel,
 	};
 	u16 chan;
 
@@ -1397,7 +1395,7 @@ il3945_send_tx_power(struct il_priv *il)
 	     "TX Power requested while scanning!\n"))
 		return -EAGAIN;
 
-	chan = le16_to_cpu(il->ctx.active.channel);
+	chan = le16_to_cpu(il->active.channel);
 
 	txpower.band = (il->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
 	ch_info = il_get_channel_info(il, il->band, chan);
@@ -1615,7 +1613,7 @@ il3945_hw_reg_comp_txpower_temp(struct il_priv *il)
 	}
 
 	/* send Txpower command for current channel to ucode */
-	return il->cfg->ops->lib->send_tx_power(il);
+	return il->ops->lib->send_tx_power(il);
 }
 
 int
@@ -1662,7 +1660,7 @@ il3945_hw_reg_set_txpower(struct il_priv *il, s8 power)
 }
 
 static int
-il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il3945_send_rxon_assoc(struct il_priv *il)
 {
 	int rc = 0;
 	struct il_rx_pkt *pkt;
@@ -1673,8 +1671,8 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
 		.flags = CMD_WANT_SKB,
 		.data = &rxon_assoc,
 	};
-	const struct il_rxon_cmd *rxon1 = &ctx->staging;
-	const struct il_rxon_cmd *rxon2 = &ctx->active;
+	const struct il_rxon_cmd *rxon1 = &il->staging;
+	const struct il_rxon_cmd *rxon2 = &il->active;
 
 	if (rxon1->flags == rxon2->flags &&
 	    rxon1->filter_flags == rxon2->filter_flags &&
@@ -1684,10 +1682,10 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
 		return 0;
 	}
 
-	rxon_assoc.flags = ctx->staging.flags;
-	rxon_assoc.filter_flags = ctx->staging.filter_flags;
-	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
-	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+	rxon_assoc.flags = il->staging.flags;
+	rxon_assoc.filter_flags = il->staging.filter_flags;
+	rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
+	rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
 	rxon_assoc.reserved = 0;
 
 	rc = il_send_cmd_sync(il, &cmd);
@@ -1714,11 +1712,11 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
  * a HW tune is required based on the RXON structure changes.
  */
 int
-il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il3945_commit_rxon(struct il_priv *il)
 {
 	/* cast away the const for active_rxon in this function */
-	struct il3945_rxon_cmd *active_rxon = (void *)&ctx->active;
-	struct il3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
+	struct il3945_rxon_cmd *active_rxon = (void *)&il->active;
+	struct il3945_rxon_cmd *staging_rxon = (void *)&il->staging;
 	int rc = 0;
 	bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
 
@@ -1735,7 +1733,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	staging_rxon->flags &= ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
 	staging_rxon->flags |= il3945_get_antenna_flags(il);
 
-	rc = il_check_rxon_cmd(il, ctx);
+	rc = il_check_rxon_cmd(il);
 	if (rc) {
 		IL_ERR("Invalid RXON configuration.  Not committing.\n");
 		return -EINVAL;
@@ -1744,8 +1742,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	/* If we don't need to send a full RXON, we can use
 	 * il3945_rxon_assoc_cmd which is used to reconfigure filter
 	 * and other flags for the current radio configuration. */
-	if (!il_full_rxon_required(il, &il->ctx)) {
-		rc = il_send_rxon_assoc(il, &il->ctx);
+	if (!il_full_rxon_required(il)) {
+		rc = il_send_rxon_assoc(il);
 		if (rc) {
 			IL_ERR("Error setting RXON_ASSOC "
 			       "configuration (%d).\n", rc);
@@ -1776,7 +1774,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 		active_rxon->reserved4 = 0;
 		active_rxon->reserved5 = 0;
 		rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),
-				     &il->ctx.active);
+				     &il->active);
 
 		/* If the mask clearing failed then we set
 		 * active_rxon back to what it was previously */
@@ -1786,8 +1784,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 			       "configuration (%d).\n", rc);
 			return rc;
 		}
-		il_clear_ucode_stations(il, &il->ctx);
-		il_restore_stations(il, &il->ctx);
+		il_clear_ucode_stations(il);
+		il_restore_stations(il);
 	}
 
 	D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
@@ -1801,7 +1799,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	staging_rxon->reserved4 = 0;
 	staging_rxon->reserved5 = 0;
 
-	il_set_rxon_hwcrypto(il, ctx, !il3945_mod_params.sw_crypto);
+	il_set_rxon_hwcrypto(il, !il3945_mod_params.sw_crypto);
 
 	/* Apply the new configuration */
 	rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),
@@ -1814,8 +1812,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
 
 	if (!new_assoc) {
-		il_clear_ucode_stations(il, &il->ctx);
-		il_restore_stations(il, &il->ctx);
+		il_clear_ucode_stations(il);
+		il_restore_stations(il);
 	}
 
 	/* If we issue a new RXON command which required a tune then we must
@@ -2258,7 +2256,6 @@ il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
 static int
 il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
 {
-	struct il_rxon_context *ctx = &il->ctx;
 	int ret;
 	u8 sta_id;
 	unsigned long flags;
@@ -2266,7 +2263,7 @@ il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
 	if (sta_id_r)
 		*sta_id_r = IL_INVALID_STATION;
 
-	ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
+	ret = il_add_station_common(il, addr, 0, NULL, &sta_id);
 	if (ret) {
 		IL_ERR("Unable to add station %pM\n", addr);
 		return ret;
@@ -2396,15 +2393,16 @@ il3945_hw_set_hw_params(struct il_priv *il)
 		return -ENOMEM;
 	}
 
+	il->hw_params.bcast_id = IL3945_BROADCAST_ID;
+
 	/* Assign number of Usable TX queues */
-	il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues;
+	il->hw_params.max_txq_num = il->cfg->num_of_queues;
 
 	il->hw_params.tfd_size = sizeof(struct il3945_tfd);
 	il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_3K);
 	il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
 	il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
 	il->hw_params.max_stations = IL3945_STATION_COUNT;
-	il->ctx.bcast_sta_id = IL3945_BROADCAST_ID;
 
 	il->sta_key_max_num = STA_KEY_MAX_NUM;
 
@@ -2425,7 +2423,7 @@ il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame,
 	tx_beacon_cmd = (struct il3945_tx_beacon_cmd *)&frame->u;
 	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 
-	tx_beacon_cmd->tx.sta_id = il->ctx.bcast_sta_id;
+	tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;
 	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
 	frame_size =
@@ -2685,23 +2683,12 @@ static struct il_hcmd_utils_ops il3945_hcmd_utils = {
 	.post_scan = il3945_post_scan,
 };
 
-static const struct il_ops il3945_ops = {
+const struct il_ops il3945_ops = {
 	.lib = &il3945_lib,
 	.hcmd = &il3945_hcmd,
 	.utils = &il3945_hcmd_utils,
 	.led = &il3945_led_ops,
 	.legacy = &il3945_legacy_ops,
-	.ieee80211_ops = &il3945_hw_ops,
-};
-
-static struct il_base_params il3945_base_params = {
-	.eeprom_size = IL3945_EEPROM_IMG_SIZE,
-	.num_of_queues = IL39_NUM_QUEUES,
-	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
-	.set_l0s = false,
-	.use_bsm = true,
-	.led_compensation = 64,
-	.wd_timeout = IL_DEF_WD_TIMEOUT,
 };
 
 static struct il_cfg il3945_bg_cfg = {
@@ -2711,10 +2698,16 @@ static struct il_cfg il3945_bg_cfg = {
 	.ucode_api_min = IL3945_UCODE_API_MIN,
 	.sku = IL_SKU_G,
 	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
-	.ops = &il3945_ops,
 	.mod_params = &il3945_mod_params,
-	.base_params = &il3945_base_params,
 	.led_mode = IL_LED_BLINK,
+
+	.eeprom_size = IL3945_EEPROM_IMG_SIZE,
+	.num_of_queues = IL39_NUM_QUEUES,
+	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+	.set_l0s = false,
+	.use_bsm = true,
+	.led_compensation = 64,
+	.wd_timeout = IL_DEF_WD_TIMEOUT
 };
 
 static struct il_cfg il3945_abg_cfg = {
@@ -2724,10 +2717,16 @@ static struct il_cfg il3945_abg_cfg = {
 	.ucode_api_min = IL3945_UCODE_API_MIN,
 	.sku = IL_SKU_A | IL_SKU_G,
 	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
-	.ops = &il3945_ops,
 	.mod_params = &il3945_mod_params,
-	.base_params = &il3945_base_params,
 	.led_mode = IL_LED_BLINK,
+
+	.eeprom_size = IL3945_EEPROM_IMG_SIZE,
+	.num_of_queues = IL39_NUM_QUEUES,
+	.pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+	.set_l0s = false,
+	.use_bsm = true,
+	.led_compensation = 64,
+	.wd_timeout = IL_DEF_WD_TIMEOUT
 };
 
 DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h
index 9f42f79..c00a8d3 100644
--- a/drivers/net/wireless/iwlegacy/3945.h
+++ b/drivers/net/wireless/iwlegacy/3945.h
@@ -36,6 +36,8 @@ extern const struct pci_device_id il3945_hw_card_ids[];
 
 #include "common.h"
 
+extern const struct il_ops il3945_ops;
+
 /* Highest firmware API version supported */
 #define IL3945_UCODE_API_MAX 2
 
@@ -249,7 +251,7 @@ extern int il4965_get_temperature(const struct il_priv *il);
 extern void il3945_post_associate(struct il_priv *il);
 extern void il3945_config_ap(struct il_priv *il);
 
-extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx);
+extern int il3945_commit_rxon(struct il_priv *il);
 
 /**
  * il3945_hw_find_station - Find station id for a given BSSID
@@ -261,8 +263,6 @@ extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx);
  */
 extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid);
 
-extern struct ieee80211_ops il3945_hw_ops;
-
 extern __le32 il3945_get_antenna_flags(const struct il_priv *il);
 extern int il3945_init_hw_rate_table(struct il_priv *il);
 extern void il3945_reg_txpower_periodic(struct il_priv *il);
diff --git a/drivers/net/wireless/iwlegacy/4965-calib.c b/drivers/net/wireless/iwlegacy/4965-calib.c
index d3248e3..fe91715 100644
--- a/drivers/net/wireless/iwlegacy/4965-calib.c
+++ b/drivers/net/wireless/iwlegacy/4965-calib.c
@@ -627,13 +627,13 @@ il4965_find_disconn_antenna(struct il_priv *il, u32 * average_sig,
 
 	average_sig[0] =
 	    data->chain_signal_a /
-	    il->cfg->base_params->chain_noise_num_beacons;
+	    il->cfg->chain_noise_num_beacons;
 	average_sig[1] =
 	    data->chain_signal_b /
-	    il->cfg->base_params->chain_noise_num_beacons;
+	    il->cfg->chain_noise_num_beacons;
 	average_sig[2] =
 	    data->chain_signal_c /
-	    il->cfg->base_params->chain_noise_num_beacons;
+	    il->cfg->chain_noise_num_beacons;
 
 	if (average_sig[0] >= average_sig[1]) {
 		max_average_sig = average_sig[0];
@@ -806,8 +806,6 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
 	unsigned long flags;
 	struct stats_rx_non_phy *rx_info;
 
-	struct il_rxon_context *ctx = &il->ctx;
-
 	if (il->disable_chain_noise_cal)
 		return;
 
@@ -833,8 +831,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
 		return;
 	}
 
-	rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
-	rxon_chnum = le16_to_cpu(ctx->staging.channel);
+	rxon_band24 = !!(il->staging.flags & RXON_FLG_BAND_24G_MSK);
+	rxon_chnum = le16_to_cpu(il->staging.channel);
 
 	stat_band24 =
 	    !!(((struct il_notif_stats *)stat_resp)->
@@ -888,7 +886,7 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
 	/* If this is the "chain_noise_num_beacons", determine:
 	 * 1)  Disconnected antennas (using signal strengths)
 	 * 2)  Differential gain (using silence noise) to balance receivers */
-	if (data->beacon_count != il->cfg->base_params->chain_noise_num_beacons)
+	if (data->beacon_count != il->cfg->chain_noise_num_beacons)
 		return;
 
 	/* Analyze signal for disconnected antenna */
@@ -896,11 +894,11 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
 
 	/* Analyze noise for rx balance */
 	average_noise[0] =
-	    data->chain_noise_a / il->cfg->base_params->chain_noise_num_beacons;
+	    data->chain_noise_a / il->cfg->chain_noise_num_beacons;
 	average_noise[1] =
-	    data->chain_noise_b / il->cfg->base_params->chain_noise_num_beacons;
+	    data->chain_noise_b / il->cfg->chain_noise_num_beacons;
 	average_noise[2] =
-	    data->chain_noise_c / il->cfg->base_params->chain_noise_num_beacons;
+	    data->chain_noise_c / il->cfg->chain_noise_num_beacons;
 
 	for (i = 0; i < NUM_RX_CHAINS; i++) {
 		if (!data->disconn_array[i] &&
@@ -925,8 +923,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
 	/* Some power changes may have been made during the calibration.
 	 * Update and commit the RXON
 	 */
-	if (il->cfg->ops->lib->update_chain_flags)
-		il->cfg->ops->lib->update_chain_flags(il);
+	if (il->ops->lib->update_chain_flags)
+		il->ops->lib->update_chain_flags(il);
 
 	data->state = IL_CHAIN_NOISE_DONE;
 	il_power_update_mode(il, false);
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 1667232..235812a 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -201,7 +201,7 @@ il4965_hw_nic_init(struct il_priv *il)
 
 	/* nic_init */
 	spin_lock_irqsave(&il->lock, flags);
-	il->cfg->ops->lib->apm_ops.init(il);
+	il->ops->lib->apm_ops.init(il);
 
 	/* Set interrupt coalescing calibration timer to default (512 usecs) */
 	il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF);
@@ -210,7 +210,7 @@ il4965_hw_nic_init(struct il_priv *il)
 
 	il4965_set_pwr_vmain(il);
 
-	il->cfg->ops->lib->apm_ops.config(il);
+	il->ops->lib->apm_ops.config(il);
 
 	/* Allocate the RX queue, or reset if it is already allocated */
 	if (!rxq->bd) {
@@ -843,7 +843,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 		.flags = CMD_SIZE_HUGE,
 	};
 	struct il_scan_cmd *scan;
-	struct il_rxon_context *ctx = &il->ctx;
 	u32 rate_flags = 0;
 	u16 cmd_len;
 	u16 rx_chain = 0;
@@ -859,8 +858,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 
 	lockdep_assert_held(&il->mutex);
 
-	ctx = il_rxon_ctx_from_vif(vif);
-
 	if (!il->scan_cmd) {
 		il->scan_cmd =
 		    kmalloc(sizeof(struct il_scan_cmd) + IL_MAX_SCAN_SIZE,
@@ -919,15 +916,14 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
 		D_SCAN("Start passive scan.\n");
 
 	scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-	scan->tx_cmd.sta_id = ctx->bcast_sta_id;
+	scan->tx_cmd.sta_id = il->hw_params.bcast_id;
 	scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
 	switch (il->scan_band) {
 	case IEEE80211_BAND_2GHZ:
 		scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
 		chan_mod =
-		    le32_to_cpu(il->ctx.active.
-				flags & RXON_FLG_CHANNEL_MODE_MSK) >>
+		    le32_to_cpu(il->active.flags & RXON_FLG_CHANNEL_MODE_MSK) >>
 		    RXON_FLG_CHANNEL_MODE_POS;
 		if (chan_mod == CHANNEL_MODE_PURE_40) {
 			rate = RATE_6M_PLCP;
@@ -1034,8 +1030,7 @@ il4965_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif,
 	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
 
 	if (add)
-		return il4965_add_bssid_station(il, vif_priv->ctx,
-						vif->bss_conf.bssid,
+		return il4965_add_bssid_station(il, vif->bss_conf.bssid,
 						&vif_priv->ibss_bssid_sta_id);
 	return il_remove_station(il, vif_priv->ibss_bssid_sta_id,
 				 vif->bss_conf.bssid);
@@ -1128,7 +1123,7 @@ il4965_count_chain_bitmap(u32 chain_bitmap)
  * This should not be used for scan command ... it puts data in wrong place.
  */
 void
-il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_set_rxon_chain(struct il_priv *il)
 {
 	bool is_single = il4965_is_single_rx_stream(il);
 	bool is_cam = !test_bit(S_POWER_PMI, &il->status);
@@ -1164,14 +1159,14 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
 	rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
 	rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
 
-	ctx->staging.rx_chain = cpu_to_le16(rx_chain);
+	il->staging.rx_chain = cpu_to_le16(rx_chain);
 
 	if (!is_single && active_rx_cnt >= IL_NUM_RX_CHAINS_SINGLE && is_cam)
-		ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+		il->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
 	else
-		ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+		il->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
 
-	D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", ctx->staging.rx_chain,
+	D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", il->staging.rx_chain,
 		active_rx_cnt, idle_rx_cnt);
 
 	WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
@@ -1386,8 +1381,8 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
 		il4965_rx_calc_noise(il);
 		queue_work(il->workqueue, &il->run_time_calib_work);
 	}
-	if (il->cfg->ops->lib->temp_ops.temperature && change)
-		il->cfg->ops->lib->temp_ops.temperature(il);
+	if (il->ops->lib->temp_ops.temperature && change)
+		il->ops->lib->temp_ops.temperature(il);
 }
 
 void
@@ -1457,10 +1452,17 @@ il4965_get_ac_from_tid(u16 tid)
 }
 
 static inline int
-il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid)
+il4965_get_fifo_from_tid(u16 tid)
 {
+	const u8 ac_to_fifo[] = {
+		IL_TX_FIFO_VO,
+		IL_TX_FIFO_VI,
+		IL_TX_FIFO_BE,
+		IL_TX_FIFO_BK,
+	};
+
 	if (likely(tid < ARRAY_SIZE(tid_to_ac)))
-		return ctx->ac_to_fifo[tid_to_ac[tid]];
+		return ac_to_fifo[tid_to_ac[tid]];
 
 	/* no support for TIDs 8-15 yet */
 	return -EINVAL;
@@ -1639,7 +1641,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 	struct il_device_cmd *out_cmd;
 	struct il_cmd_meta *out_meta;
 	struct il_tx_cmd *tx_cmd;
-	struct il_rxon_context *ctx = &il->ctx;
 	int txq_id;
 	dma_addr_t phys_addr;
 	dma_addr_t txcmd_phys;
@@ -1655,9 +1656,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 	unsigned long flags;
 	bool is_agg = false;
 
-	if (info->control.vif)
-		ctx = il_rxon_ctx_from_vif(info->control.vif);
-
 	spin_lock_irqsave(&il->lock, flags);
 	if (il_is_rfkill(il)) {
 		D_DROP("Dropping - RF KILL\n");
@@ -1679,10 +1677,10 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
 	/* For management frames use broadcast id to do not break aggregation */
 	if (!ieee80211_is_data(fc))
-		sta_id = ctx->bcast_sta_id;
+		sta_id = il->hw_params.bcast_id;
 	else {
 		/* Find idx into station table for destination station */
-		sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta);
+		sta_id = il_sta_id_or_broadcast(il, info->control.sta);
 
 		if (sta_id == IL_INVALID_STATION) {
 			D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1);
@@ -1709,19 +1707,11 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 		il4965_sta_modify_sleep_tx_count(il, sta_id, 1);
 	}
 
-	/*
-	 * Send this frame after DTIM -- there's a special queue
-	 * reserved for this for contexts that support AP mode.
-	 */
-	if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
-		txq_id = ctx->mcast_queue;
-		/*
-		 * The microcode will clear the more data
-		 * bit in the last frame it transmits.
-		 */
-		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-	} else
-		txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
+	/* FIXME: remove me ? */
+	WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
+
+	/* Access category (AC) is also the queue number */
+	txq_id = skb_get_queue_mapping(skb);
 
 	/* irqs already disabled/saved above when locking il->lock */
 	spin_lock(&il->sta_lock);
@@ -1763,10 +1753,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
 	spin_unlock(&il->sta_lock);
 
-	/* Set up driver data for this TFD */
-	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
-	txq->txb[q->write_ptr].skb = skb;
-	txq->txb[q->write_ptr].ctx = ctx;
+	txq->skbs[q->write_ptr] = skb;
 
 	/* Set up first empty entry in queue's array of Tx/cmd buffers */
 	out_cmd = txq->cmd[q->write_ptr];
@@ -1828,8 +1815,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 	dma_unmap_len_set(out_meta, len, firstlen);
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
-	il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen,
-						 1, 0);
+	il->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
 
 	if (!ieee80211_has_morefrags(hdr->frame_control)) {
 		txq->need_update = 1;
@@ -1845,8 +1831,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 		phys_addr =
 		    pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
 				   PCI_DMA_TODEVICE);
-		il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
-							 secondlen, 0, 0);
+		il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
+						    secondlen, 0, 0);
 	}
 
 	scratch_phys =
@@ -1866,9 +1852,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
 
 	/* Set up entry for this TFD in Tx byte-count array */
 	if (info->flags & IEEE80211_TX_CTL_AMPDU)
-		il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq,
-							   le16_to_cpu(tx_cmd->
-								       len));
+		il->ops->lib->txq_update_byte_cnt_tbl(il, txq,
+						      le16_to_cpu(tx_cmd->len));
 
 	pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen,
 				       PCI_DMA_BIDIRECTIONAL);
@@ -2163,11 +2148,11 @@ il4965_txq_agg_enable(struct il_priv *il, int txq_id, int tx_fifo, int sta_id,
 
 	if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IL49_FIRST_AMPDU_QUEUE +
-	     il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+	     il->cfg->num_of_ampdu_queues <= txq_id)) {
 		IL_WARN("queue number out of range: %d, must be %d to %d\n",
 			txq_id, IL49_FIRST_AMPDU_QUEUE,
 			IL49_FIRST_AMPDU_QUEUE +
-			il->cfg->base_params->num_of_ampdu_queues - 1);
+			il->cfg->num_of_ampdu_queues - 1);
 		return -EINVAL;
 	}
 
@@ -2230,7 +2215,8 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
 	unsigned long flags;
 	struct il_tid_data *tid_data;
 
-	tx_fifo = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
+	/* FIXME: warning if tx fifo not found ? */
+	tx_fifo = il4965_get_fifo_from_tid(tid);
 	if (unlikely(tx_fifo < 0))
 		return tx_fifo;
 
@@ -2290,11 +2276,11 @@ il4965_txq_agg_disable(struct il_priv *il, u16 txq_id, u16 ssn_idx, u8 tx_fifo)
 {
 	if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IL49_FIRST_AMPDU_QUEUE +
-	     il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+	     il->cfg->num_of_ampdu_queues <= txq_id)) {
 		IL_WARN("queue number out of range: %d, must be %d to %d\n",
 			txq_id, IL49_FIRST_AMPDU_QUEUE,
 			IL49_FIRST_AMPDU_QUEUE +
-			il->cfg->base_params->num_of_ampdu_queues - 1);
+			il->cfg->num_of_ampdu_queues - 1);
 		return -EINVAL;
 	}
 
@@ -2323,7 +2309,8 @@ il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
 	int write_ptr, read_ptr;
 	unsigned long flags;
 
-	tx_fifo_id = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
+	/* FIXME: warning if tx_fifo_id not found ? */
+	tx_fifo_id = il4965_get_fifo_from_tid(tid);
 	if (unlikely(tx_fifo_id < 0))
 		return tx_fifo_id;
 
@@ -2397,9 +2384,6 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
 	struct il_queue *q = &il->txq[txq_id].q;
 	u8 *addr = il->stations[sta_id].sta.sta.addr;
 	struct il_tid_data *tid_data = &il->stations[sta_id].tid[tid];
-	struct il_rxon_context *ctx;
-
-	ctx = &il->ctx;
 
 	lockdep_assert_held(&il->sta_lock);
 
@@ -2410,11 +2394,11 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
 		if (txq_id == tid_data->agg.txq_id &&
 		    q->read_ptr == q->write_ptr) {
 			u16 ssn = SEQ_TO_SN(tid_data->seq_number);
-			int tx_fifo = il4965_get_fifo_from_tid(ctx, tid);
+			int tx_fifo = il4965_get_fifo_from_tid(tid);
 			D_HT("HW queue empty: continue DELBA flow\n");
 			il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo);
 			tid_data->agg.state = IL_AGG_OFF;
-			ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
+			ieee80211_stop_tx_ba_cb_irqsafe(il->vif, addr, tid);
 		}
 		break;
 	case IL_EMPTYING_HW_QUEUE_ADDBA:
@@ -2422,7 +2406,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
 		if (tid_data->tfds_in_queue == 0) {
 			D_HT("HW queue empty: continue ADDBA flow\n");
 			tid_data->agg.state = IL_AGG_ON;
-			ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
+			ieee80211_start_tx_ba_cb_irqsafe(il->vif, addr, tid);
 		}
 		break;
 	}
@@ -2431,14 +2415,13 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
 }
 
 static void
-il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx,
-			 const u8 *addr1)
+il4965_non_agg_tx_status(struct il_priv *il, const u8 *addr1)
 {
 	struct ieee80211_sta *sta;
 	struct il_station_priv *sta_priv;
 
 	rcu_read_lock();
-	sta = ieee80211_find_sta(ctx->vif, addr1);
+	sta = ieee80211_find_sta(il->vif, addr1);
 	if (sta) {
 		sta_priv = (void *)sta->drv_priv;
 		/* avoid atomic ops if this isn't a client */
@@ -2450,14 +2433,14 @@ il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 static void
-il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info, bool is_agg)
+il4965_tx_status(struct il_priv *il, struct sk_buff *skb, bool is_agg)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
 	if (!is_agg)
-		il4965_non_agg_tx_status(il, tx_info->ctx, hdr->addr1);
+		il4965_non_agg_tx_status(il, hdr->addr1);
 
-	ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
+	ieee80211_tx_status_irqsafe(il->hw, skb);
 }
 
 int
@@ -2465,9 +2448,9 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
 {
 	struct il_tx_queue *txq = &il->txq[txq_id];
 	struct il_queue *q = &txq->q;
-	struct il_tx_info *tx_info;
 	int nfreed = 0;
 	struct ieee80211_hdr *hdr;
+	struct sk_buff *skb;
 
 	if (idx >= q->n_bd || il_queue_used(q, idx) == 0) {
 		IL_ERR("Read idx for DMA queue txq id (%d), idx %d, "
@@ -2479,20 +2462,19 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
 	for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
 	     q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
-		tx_info = &txq->txb[txq->q.read_ptr];
+		skb = txq->skbs[txq->q.read_ptr];
 
-		if (WARN_ON_ONCE(tx_info->skb == NULL))
+		if (WARN_ON_ONCE(skb == NULL))
 			continue;
 
-		hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+		hdr = (struct ieee80211_hdr *) skb->data;
 		if (ieee80211_is_data_qos(hdr->frame_control))
 			nfreed++;
 
-		il4965_tx_status(il, tx_info,
-				 txq_id >= IL4965_FIRST_AMPDU_QUEUE);
-		tx_info->skb = NULL;
+		il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE);
 
-		il->cfg->ops->lib->txq_free_tfd(il, txq);
+		txq->skbs[txq->q.read_ptr] = NULL;
+		il->ops->lib->txq_free_tfd(il, txq);
 	}
 	return nfreed;
 }
@@ -2555,7 +2537,7 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
 
 	D_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
 
-	info = IEEE80211_SKB_CB(il->txq[scd_flow].txb[agg->start_idx].skb);
+	info = IEEE80211_SKB_CB(il->txq[scd_flow].skbs[agg->start_idx]);
 	memset(&info->status, 0, sizeof(info->status));
 	info->flags |= IEEE80211_TX_STAT_ACK;
 	info->flags |= IEEE80211_TX_STAT_AMPDU;
@@ -2771,8 +2753,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id)
  * Function sleeps.
  */
 int
-il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
-			 const u8 *addr, u8 *sta_id_r)
+il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r)
 {
 	int ret;
 	u8 sta_id;
@@ -2782,7 +2763,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
 	if (sta_id_r)
 		*sta_id_r = IL_INVALID_STATION;
 
-	ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
+	ret = il_add_station_common(il, addr, 0, NULL, &sta_id);
 	if (ret) {
 		IL_ERR("Unable to add station %pM\n", addr);
 		return ret;
@@ -2803,7 +2784,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
 		return -ENOMEM;
 	}
 
-	ret = il_send_lq_cmd(il, ctx, link_cmd, CMD_SYNC, true);
+	ret = il_send_lq_cmd(il, link_cmd, CMD_SYNC, true);
 	if (ret)
 		IL_ERR("Link quality command failed (%d)\n", ret);
 
@@ -2815,19 +2796,19 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 static int
-il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
-			 bool send_if_empty)
+il4965_static_wepkey_cmd(struct il_priv *il, bool send_if_empty)
 {
-	int i, not_empty = 0;
+	int i;
 	u8 buff[sizeof(struct il_wep_cmd) +
 		sizeof(struct il_wep_key) * WEP_KEYS_MAX];
 	struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff;
 	size_t cmd_size = sizeof(struct il_wep_cmd);
 	struct il_host_cmd cmd = {
-		.id = ctx->wep_key_cmd,
+		.id = C_WEPKEY,
 		.data = wep_cmd,
 		.flags = CMD_SYNC,
 	};
+	bool not_empty = false;
 
 	might_sleep();
 
@@ -2835,24 +2816,23 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
 	       cmd_size + (sizeof(struct il_wep_key) * WEP_KEYS_MAX));
 
 	for (i = 0; i < WEP_KEYS_MAX; i++) {
+		u8 key_size = il->_4965.wep_keys[i].key_size;
+
 		wep_cmd->key[i].key_idx = i;
-		if (ctx->wep_keys[i].key_size) {
+		if (key_size) {
 			wep_cmd->key[i].key_offset = i;
-			not_empty = 1;
-		} else {
+			not_empty = true;
+		} else
 			wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
-		}
 
-		wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
-		memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
-		       ctx->wep_keys[i].key_size);
+		wep_cmd->key[i].key_size = key_size;
+		memcpy(&wep_cmd->key[i].key[3], il->_4965.wep_keys[i].key, key_size);
 	}
 
 	wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
 	wep_cmd->num_keys = WEP_KEYS_MAX;
 
 	cmd_size += sizeof(struct il_wep_key) * WEP_KEYS_MAX;
-
 	cmd.len = cmd_size;
 
 	if (not_empty || send_if_empty)
@@ -2862,66 +2842,66 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 int
-il4965_restore_default_wep_keys(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_restore_default_wep_keys(struct il_priv *il)
 {
 	lockdep_assert_held(&il->mutex);
 
-	return il4965_static_wepkey_cmd(il, ctx, false);
+	return il4965_static_wepkey_cmd(il, false);
 }
 
 int
-il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_remove_default_wep_key(struct il_priv *il,
 			      struct ieee80211_key_conf *keyconf)
 {
 	int ret;
+	int idx = keyconf->keyidx;
 
 	lockdep_assert_held(&il->mutex);
 
-	D_WEP("Removing default WEP key: idx=%d\n", keyconf->keyidx);
+	D_WEP("Removing default WEP key: idx=%d\n", idx);
 
-	memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
+	memset(&il->_4965.wep_keys[idx], 0, sizeof(struct il_wep_key));
 	if (il_is_rfkill(il)) {
 		D_WEP("Not sending C_WEPKEY command due to RFKILL.\n");
 		/* but keys in device are clear anyway so return success */
 		return 0;
 	}
-	ret = il4965_static_wepkey_cmd(il, ctx, 1);
-	D_WEP("Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret);
+	ret = il4965_static_wepkey_cmd(il, 1);
+	D_WEP("Remove default WEP key: idx=%d ret=%d\n", idx, ret);
 
 	return ret;
 }
 
 int
-il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_set_default_wep_key(struct il_priv *il,
 			   struct ieee80211_key_conf *keyconf)
 {
 	int ret;
+	int len = keyconf->keylen;
+	int idx = keyconf->keyidx;
 
 	lockdep_assert_held(&il->mutex);
 
-	if (keyconf->keylen != WEP_KEY_LEN_128 &&
-	    keyconf->keylen != WEP_KEY_LEN_64) {
+	if (len != WEP_KEY_LEN_128 && len != WEP_KEY_LEN_64) {
 		D_WEP("Bad WEP key length %d\n", keyconf->keylen);
 		return -EINVAL;
 	}
 
 	keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
 	keyconf->hw_key_idx = HW_KEY_DEFAULT;
-	il->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+	il->stations[IL_AP_ID].keyinfo.cipher = keyconf->cipher;
 
-	ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
-	memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
-	       keyconf->keylen);
+	il->_4965.wep_keys[idx].key_size = len;
+	memcpy(&il->_4965.wep_keys[idx].key, &keyconf->key, len);
 
-	ret = il4965_static_wepkey_cmd(il, ctx, false);
-	D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", keyconf->keylen,
-	      keyconf->keyidx, ret);
+	ret = il4965_static_wepkey_cmd(il, false);
 
+	D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", len, idx, ret);
 	return ret;
 }
 
 static int
-il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_set_wep_dynamic_key_info(struct il_priv *il,
 				struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
 	unsigned long flags;
@@ -2939,7 +2919,7 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
 	if (keyconf->keylen == WEP_KEY_LEN_128)
 		key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
 
-	if (sta_id == ctx->bcast_sta_id)
+	if (sta_id == il->hw_params.bcast_id)
 		key_flags |= STA_KEY_MULTICAST_MSK;
 
 	spin_lock_irqsave(&il->sta_lock, flags);
@@ -2976,7 +2956,6 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
 
 static int
 il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
-				 struct il_rxon_context *ctx,
 				 struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
 	unsigned long flags;
@@ -2989,7 +2968,7 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
 	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
 	key_flags &= ~STA_KEY_FLG_INVALID;
 
-	if (sta_id == ctx->bcast_sta_id)
+	if (sta_id == il->hw_params.bcast_id)
 		key_flags |= STA_KEY_MULTICAST_MSK;
 
 	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -3025,7 +3004,6 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
 
 static int
 il4965_set_tkip_dynamic_key_info(struct il_priv *il,
-				 struct il_rxon_context *ctx,
 				 struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
 	unsigned long flags;
@@ -3036,7 +3014,7 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il,
 	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
 	key_flags &= ~STA_KEY_FLG_INVALID;
 
-	if (sta_id == ctx->bcast_sta_id)
+	if (sta_id == il->hw_params.bcast_id)
 		key_flags |= STA_KEY_MULTICAST_MSK;
 
 	keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -3070,9 +3048,8 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il,
 }
 
 void
-il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
-		       struct ieee80211_key_conf *keyconf,
-		       struct ieee80211_sta *sta, u32 iv32, u16 * phase1key)
+il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
+		       struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
 {
 	u8 sta_id;
 	unsigned long flags;
@@ -3084,7 +3061,7 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
 		return;
 	}
 
-	sta_id = il_sta_id_or_broadcast(il, ctx, sta);
+	sta_id = il_sta_id_or_broadcast(il, sta);
 	if (sta_id == IL_INVALID_STATION)
 		return;
 
@@ -3102,11 +3079,10 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
 	il_send_add_sta(il, &il->stations[sta_id].sta, CMD_ASYNC);
 
 	spin_unlock_irqrestore(&il->sta_lock, flags);
-
 }
 
 int
-il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_remove_dynamic_key(struct il_priv *il,
 			  struct ieee80211_key_conf *keyconf, u8 sta_id)
 {
 	unsigned long flags;
@@ -3116,7 +3092,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
 
 	lockdep_assert_held(&il->mutex);
 
-	ctx->key_mapping_keys--;
+	il->_4965.key_mapping_keys--;
 
 	spin_lock_irqsave(&il->sta_lock, flags);
 	key_flags = le16_to_cpu(il->stations[sta_id].sta.key.key_flags);
@@ -3167,28 +3143,28 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
 }
 
 int
-il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
-		       struct ieee80211_key_conf *keyconf, u8 sta_id)
+il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
+		       u8 sta_id)
 {
 	int ret;
 
 	lockdep_assert_held(&il->mutex);
 
-	ctx->key_mapping_keys++;
+	il->_4965.key_mapping_keys++;
 	keyconf->hw_key_idx = HW_KEY_DYNAMIC;
 
 	switch (keyconf->cipher) {
 	case WLAN_CIPHER_SUITE_CCMP:
 		ret =
-		    il4965_set_ccmp_dynamic_key_info(il, ctx, keyconf, sta_id);
+		    il4965_set_ccmp_dynamic_key_info(il, keyconf, sta_id);
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
 		ret =
-		    il4965_set_tkip_dynamic_key_info(il, ctx, keyconf, sta_id);
+		    il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id);
 		break;
 	case WLAN_CIPHER_SUITE_WEP40:
 	case WLAN_CIPHER_SUITE_WEP104:
-		ret = il4965_set_wep_dynamic_key_info(il, ctx, keyconf, sta_id);
+		ret = il4965_set_wep_dynamic_key_info(il, keyconf, sta_id);
 		break;
 	default:
 		IL_ERR("Unknown alg: %s cipher = %x\n", __func__,
@@ -3210,14 +3186,14 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
  * device at the next best time.
  */
 int
-il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_alloc_bcast_station(struct il_priv *il)
 {
 	struct il_link_quality_cmd *link_cmd;
 	unsigned long flags;
 	u8 sta_id;
 
 	spin_lock_irqsave(&il->sta_lock, flags);
-	sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL);
+	sta_id = il_prep_station(il, il_bcast_addr, false, NULL);
 	if (sta_id == IL_INVALID_STATION) {
 		IL_ERR("Unable to prepare broadcast station\n");
 		spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -3250,11 +3226,11 @@ il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
  * code together.
  */
 static int
-il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_update_bcast_station(struct il_priv *il)
 {
 	unsigned long flags;
 	struct il_link_quality_cmd *link_cmd;
-	u8 sta_id = ctx->bcast_sta_id;
+	u8 sta_id = il->hw_params.bcast_id;
 
 	link_cmd = il4965_sta_alloc_lq(il, sta_id);
 	if (!link_cmd) {
@@ -3276,7 +3252,7 @@ il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
 int
 il4965_update_bcast_stations(struct il_priv *il)
 {
-	return il4965_update_bcast_station(il, &il->ctx);
+	return il4965_update_bcast_station(il);
 }
 
 /**
@@ -3376,10 +3352,10 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt)
 void
 il4965_update_chain_flags(struct il_priv *il)
 {
-	if (il->cfg->ops->hcmd->set_rxon_chain) {
-		il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
-		if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain)
-			il_commit_rxon(il, &il->ctx);
+	if (il->ops->hcmd->set_rxon_chain) {
+		il->ops->hcmd->set_rxon_chain(il);
+		if (il->active.rx_chain != il->staging.rx_chain)
+			il_commit_rxon(il);
 	}
 }
 
@@ -3491,8 +3467,8 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
 
 	lockdep_assert_held(&il->mutex);
 
-	if (!il->beacon_ctx) {
-		IL_ERR("trying to build beacon w/o beacon context!\n");
+	if (!il->beacon_enabled) {
+		IL_ERR("Trying to build beacon without beaconing enabled\n");
 		return 0;
 	}
 
@@ -3511,7 +3487,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
 
 	/* Set up TX command fields */
 	tx_beacon_cmd->tx.len = cpu_to_le16((u16) frame_size);
-	tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id;
+	tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;
 	tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 	tx_beacon_cmd->tx.tx_flags =
 	    TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK |
@@ -3522,7 +3498,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
 			      frame_size);
 
 	/* Set up packet rate and flags */
-	rate = il_get_lowest_plcp(il, il->beacon_ctx);
+	rate = il_get_lowest_plcp(il);
 	il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant);
 	rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS;
 	if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
@@ -3645,15 +3621,13 @@ il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
 				 PCI_DMA_TODEVICE);
 
 	/* free SKB */
-	if (txq->txb) {
-		struct sk_buff *skb;
-
-		skb = txq->txb[txq->q.read_ptr].skb;
+	if (txq->skbs) {
+		struct sk_buff *skb = txq->skbs[txq->q.read_ptr];
 
 		/* can be called from irqs-disabled context */
 		if (skb) {
 			dev_kfree_skb_any(skb);
-			txq->txb[txq->q.read_ptr].skb = NULL;
+			txq->skbs[txq->q.read_ptr] = NULL;
 		}
 	}
 }
@@ -3897,7 +3871,7 @@ il4965_setup_handlers(struct il_priv *il)
 	/* block ack */
 	il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba;
 	/* Set up hardware specific Rx handlers */
-	il->cfg->ops->lib->handler_setup(il);
+	il->ops->lib->handler_setup(il);
 }
 
 /**
@@ -4799,7 +4773,7 @@ il4965_dump_nic_error_log(struct il_priv *il)
 	else
 		base = le32_to_cpu(il->card_alive.error_event_table_ptr);
 
-	if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+	if (!il->ops->lib->is_valid_rtc_data_addr(base)) {
 		IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n",
 		       base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
 		return;
@@ -4979,7 +4953,6 @@ static void
 il4965_alive_start(struct il_priv *il)
 {
 	int ret = 0;
-	struct il_rxon_context *ctx = &il->ctx;
 
 	D_INFO("Runtime Alive received.\n");
 
@@ -5019,18 +4992,18 @@ il4965_alive_start(struct il_priv *il)
 
 	il->active_rate = RATES_MASK;
 
-	if (il_is_associated_ctx(ctx)) {
+	if (il_is_associated(il)) {
 		struct il_rxon_cmd *active_rxon =
-		    (struct il_rxon_cmd *)&ctx->active;
+		    (struct il_rxon_cmd *)&il->active;
 		/* apply any changes in staging */
-		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+		il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	} else {
 		/* Initialize our rx_config data */
-		il_connection_init_rx_config(il, &il->ctx);
+		il_connection_init_rx_config(il);
 
-		if (il->cfg->ops->hcmd->set_rxon_chain)
-			il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+		if (il->ops->hcmd->set_rxon_chain)
+			il->ops->hcmd->set_rxon_chain(il);
 	}
 
 	/* Configure bluetooth coexistence if enabled */
@@ -5041,7 +5014,7 @@ il4965_alive_start(struct il_priv *il)
 	set_bit(S_READY, &il->status);
 
 	/* Configure the adapter for unassociated operation */
-	il_commit_rxon(il, ctx);
+	il_commit_rxon(il);
 
 	/* At this point, the NIC is initialized and operational */
 	il4965_rf_kill_ct_config(il);
@@ -5076,7 +5049,21 @@ __il4965_down(struct il_priv *il)
 	 * to prevent rearm timer */
 	del_timer_sync(&il->watchdog);
 
-	il_clear_ucode_stations(il, NULL);
+	il_clear_ucode_stations(il);
+
+	/* FIXME: race conditions ? */
+	spin_lock_irq(&il->sta_lock);
+	/*
+	 * Remove all key information that is not stored as part
+	 * of station information since mac80211 may not have had
+	 * a chance to remove all the keys. When device is
+	 * reconfigured by mac80211 after an error all keys will
+	 * be reconfigured.
+	 */
+	memset(il->_4965.wep_keys, 0, sizeof(il->_4965.wep_keys));
+	il->_4965.key_mapping_keys = 0;
+	spin_unlock_irq(&il->sta_lock);
+
 	il_dealloc_bcast_stations(il);
 	il_clear_driver_stations(il);
 
@@ -5227,7 +5214,7 @@ __il4965_up(struct il_priv *il)
 		return -EIO;
 	}
 
-	ret = il4965_alloc_bcast_station(il, &il->ctx);
+	ret = il4965_alloc_bcast_station(il);
 	if (ret) {
 		il_dealloc_bcast_stations(il);
 		return ret;
@@ -5288,7 +5275,7 @@ __il4965_up(struct il_priv *il)
 		/* load bootstrap state machine,
 		 * load bootstrap program into processor's memory,
 		 * prepare to load the "initialize" uCode */
-		ret = il->cfg->ops->lib->load_ucode(il);
+		ret = il->ops->lib->load_ucode(il);
 
 		if (ret) {
 			IL_ERR("Unable to set up bootstrap uCode: %d\n", ret);
@@ -5329,7 +5316,7 @@ il4965_bg_init_alive_start(struct work_struct *data)
 	if (test_bit(S_EXIT_PENDING, &il->status))
 		goto out;
 
-	il->cfg->ops->lib->init_alive_start(il);
+	il->ops->lib->init_alive_start(il);
 out:
 	mutex_unlock(&il->mutex);
 }
@@ -5381,7 +5368,8 @@ il4965_bg_restart(struct work_struct *data)
 
 	if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
 		mutex_lock(&il->mutex);
-		il->ctx.vif = NULL;
+		/* FIXME: do we dereference vif without mutex locked ? */
+		il->vif = NULL;
 		il->is_open = 0;
 
 		__il4965_down(il);
@@ -5450,8 +5438,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
 	hw->sta_data_size = sizeof(struct il_station_priv);
 	hw->vif_data_size = sizeof(struct il_vif_priv);
 
-	hw->wiphy->interface_modes |= il->ctx.interface_modes;
-	hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes;
+	hw->wiphy->interface_modes =
+	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
 
 	hw->wiphy->flags |=
 	    WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -5578,12 +5566,10 @@ il4965_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			   struct ieee80211_sta *sta, u32 iv32, u16 * phase1key)
 {
 	struct il_priv *il = hw->priv;
-	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
 
 	D_MAC80211("enter\n");
 
-	il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta, iv32,
-			       phase1key);
+	il4965_update_tkip_key(il, keyconf, sta, iv32, phase1key);
 
 	D_MAC80211("leave\n");
 }
@@ -5594,8 +5580,6 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		   struct ieee80211_key_conf *key)
 {
 	struct il_priv *il = hw->priv;
-	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
-	struct il_rxon_context *ctx = vif_priv->ctx;
 	int ret;
 	u8 sta_id;
 	bool is_default_wep_key = false;
@@ -5607,7 +5591,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		return -EOPNOTSUPP;
 	}
 
-	sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta);
+	sta_id = il_sta_id_or_broadcast(il, sta);
 	if (sta_id == IL_INVALID_STATION)
 		return -EINVAL;
 
@@ -5623,7 +5607,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
 	     key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) {
 		if (cmd == SET_KEY)
-			is_default_wep_key = !ctx->key_mapping_keys;
+			is_default_wep_key = !il->_4965.key_mapping_keys;
 		else
 			is_default_wep_key =
 			    (key->hw_key_idx == HW_KEY_DEFAULT);
@@ -5632,20 +5616,17 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	switch (cmd) {
 	case SET_KEY:
 		if (is_default_wep_key)
-			ret =
-			    il4965_set_default_wep_key(il, vif_priv->ctx, key);
+			ret = il4965_set_default_wep_key(il, key);
 		else
-			ret =
-			    il4965_set_dynamic_key(il, vif_priv->ctx, key,
-						   sta_id);
+			ret = il4965_set_dynamic_key(il, key, sta_id);
 
 		D_MAC80211("enable hwcrypto key\n");
 		break;
 	case DISABLE_KEY:
 		if (is_default_wep_key)
-			ret = il4965_remove_default_wep_key(il, ctx, key);
+			ret = il4965_remove_default_wep_key(il, key);
 		else
-			ret = il4965_remove_dynamic_key(il, ctx, key, sta_id);
+			ret = il4965_remove_dynamic_key(il, key, sta_id);
 
 		D_MAC80211("disable hwcrypto key\n");
 		break;
@@ -5711,7 +5692,6 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 {
 	struct il_priv *il = hw->priv;
 	struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
 	bool is_ap = vif->type == NL80211_IFTYPE_STATION;
 	int ret;
 	u8 sta_id;
@@ -5724,8 +5704,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	atomic_set(&sta_priv->pending_frames, 0);
 
 	ret =
-	    il_add_station_common(il, vif_priv->ctx, sta->addr, is_ap, sta,
-				  &sta_id);
+	    il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
 	if (ret) {
 		IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret);
 		/* Should we return success if return code is EEXIST ? */
@@ -5752,8 +5731,6 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ieee80211_channel *channel = ch_switch->channel;
 	struct il_ht_config *ht_conf = &il->current_ht_config;
-
-	struct il_rxon_context *ctx = &il->ctx;
 	u16 ch;
 
 	D_MAC80211("enter\n");
@@ -5768,14 +5745,14 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
 	    test_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
 		goto out;
 
-	if (!il_is_associated_ctx(ctx))
+	if (!il_is_associated(il))
 		goto out;
 
-	if (!il->cfg->ops->lib->set_channel_switch)
+	if (!il->ops->lib->set_channel_switch)
 		goto out;
 
 	ch = channel->hw_value;
-	if (le16_to_cpu(ctx->active.channel) == ch)
+	if (le16_to_cpu(il->active.channel) == ch)
 		goto out;
 
 	ch_info = il_get_channel_info(il, channel->band, ch);
@@ -5789,30 +5766,30 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
 	il->current_ht_config.smps = conf->smps_mode;
 
 	/* Configure HT40 channels */
-	ctx->ht.enabled = conf_is_ht(conf);
-	if (ctx->ht.enabled) {
+	il->ht.enabled = conf_is_ht(conf);
+	if (il->ht.enabled) {
 		if (conf_is_ht40_minus(conf)) {
-			ctx->ht.extension_chan_offset =
+			il->ht.extension_chan_offset =
 			    IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-			ctx->ht.is_40mhz = true;
+			il->ht.is_40mhz = true;
 		} else if (conf_is_ht40_plus(conf)) {
-			ctx->ht.extension_chan_offset =
+			il->ht.extension_chan_offset =
 			    IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-			ctx->ht.is_40mhz = true;
+			il->ht.is_40mhz = true;
 		} else {
-			ctx->ht.extension_chan_offset =
+			il->ht.extension_chan_offset =
 			    IEEE80211_HT_PARAM_CHA_SEC_NONE;
-			ctx->ht.is_40mhz = false;
+			il->ht.is_40mhz = false;
 		}
 	} else
-		ctx->ht.is_40mhz = false;
+		il->ht.is_40mhz = false;
 
-	if ((le16_to_cpu(ctx->staging.channel) != ch))
-		ctx->staging.flags = 0;
+	if ((le16_to_cpu(il->staging.channel) != ch))
+		il->staging.flags = 0;
 
-	il_set_rxon_channel(il, channel, ctx);
+	il_set_rxon_channel(il, channel);
 	il_set_rxon_ht(il, ht_conf);
-	il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
+	il_set_flags_for_band(il, channel->band, il->vif);
 
 	spin_unlock_irq(&il->lock);
 
@@ -5823,10 +5800,10 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
 	 */
 	set_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
 	il->switch_channel = cpu_to_le16(ch);
-	if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) {
+	if (il->ops->lib->set_channel_switch(il, ch_switch)) {
 		clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
 		il->switch_channel = 0;
-		ieee80211_chswitch_done(ctx->vif, false);
+		ieee80211_chswitch_done(il->vif, false);
 	}
 
 out:
@@ -5860,8 +5837,8 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
 
 	mutex_lock(&il->mutex);
 
-	il->ctx.staging.filter_flags &= ~filter_nand;
-	il->ctx.staging.filter_flags |= filter_or;
+	il->staging.filter_flags &= ~filter_nand;
+	il->staging.filter_flags |= filter_or;
 
 	/*
 	 * Not committing directly because hardware can perform a scan,
@@ -5906,7 +5883,7 @@ il4965_bg_txpower_work(struct work_struct *work)
 	/* Regardless of if we are associated, we must reconfigure the
 	 * TX power since frames can be sent on non-radar channels while
 	 * not associated */
-	il->cfg->ops->lib->send_tx_power(il);
+	il->ops->lib->send_tx_power(il);
 
 	/* Update last_temperature to keep is_calib_needed from running
 	 * when it isn't needed... */
@@ -6012,6 +5989,28 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
 	       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
+const struct ieee80211_ops il4965_mac_ops = {
+	.tx = il4965_mac_tx,
+	.start = il4965_mac_start,
+	.stop = il4965_mac_stop,
+	.add_interface = il_mac_add_interface,
+	.remove_interface = il_mac_remove_interface,
+	.change_interface = il_mac_change_interface,
+	.config = il_mac_config,
+	.configure_filter = il4965_configure_filter,
+	.set_key = il4965_mac_set_key,
+	.update_tkip_key = il4965_mac_update_tkip_key,
+	.conf_tx = il_mac_conf_tx,
+	.reset_tsf = il_mac_reset_tsf,
+	.bss_info_changed = il_mac_bss_info_changed,
+	.ampdu_action = il4965_mac_ampdu_action,
+	.hw_scan = il_mac_hw_scan,
+	.sta_add = il4965_mac_sta_add,
+	.sta_remove = il_mac_sta_remove,
+	.channel_switch = il4965_mac_channel_switch,
+	.tx_last_beacon = il_mac_tx_last_beacon,
+};
+
 static int
 il4965_init_drv(struct il_priv *il)
 {
@@ -6036,8 +6035,8 @@ il4965_init_drv(struct il_priv *il)
 	il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
 
 	/* Choose which receivers/antennas to use */
-	if (il->cfg->ops->hcmd->set_rxon_chain)
-		il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
+	if (il->ops->hcmd->set_rxon_chain)
+		il->ops->hcmd->set_rxon_chain(il);
 
 	il_init_scan_params(il);
 
@@ -6080,9 +6079,37 @@ il4965_hw_detect(struct il_priv *il)
 	D_INFO("HW Revision ID = 0x%X\n", il->rev_id);
 }
 
-static int
+static struct il_sensitivity_ranges il4965_sensitivity = {
+	.min_nrg_cck = 97,
+	.max_nrg_cck = 0,	/* not used, set to 0 */
+
+	.auto_corr_min_ofdm = 85,
+	.auto_corr_min_ofdm_mrc = 170,
+	.auto_corr_min_ofdm_x1 = 105,
+	.auto_corr_min_ofdm_mrc_x1 = 220,
+
+	.auto_corr_max_ofdm = 120,
+	.auto_corr_max_ofdm_mrc = 210,
+	.auto_corr_max_ofdm_x1 = 140,
+	.auto_corr_max_ofdm_mrc_x1 = 270,
+
+	.auto_corr_min_cck = 125,
+	.auto_corr_max_cck = 200,
+	.auto_corr_min_cck_mrc = 200,
+	.auto_corr_max_cck_mrc = 400,
+
+	.nrg_th_cck = 100,
+	.nrg_th_ofdm = 100,
+
+	.barker_corr_th_min = 190,
+	.barker_corr_th_min_mrc = 390,
+	.nrg_th_cca = 62,
+};
+
+static void
 il4965_set_hw_params(struct il_priv *il)
 {
+	il->hw_params.bcast_id = IL4965_BROADCAST_ID;
 	il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
 	il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
 	if (il->cfg->mod_params->amsdu_size_8K)
@@ -6095,20 +6122,37 @@ il4965_set_hw_params(struct il_priv *il)
 	if (il->cfg->mod_params->disable_11n)
 		il->cfg->sku &= ~IL_SKU_N;
 
-	/* Device-specific setup */
-	return il->cfg->ops->lib->set_hw_params(il);
-}
+	if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES &&
+	    il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES)
+		il->cfg->num_of_queues =
+		    il->cfg->mod_params->num_of_queues;
 
-static const u8 il4965_bss_ac_to_fifo[] = {
-	IL_TX_FIFO_VO,
-	IL_TX_FIFO_VI,
-	IL_TX_FIFO_BE,
-	IL_TX_FIFO_BK,
-};
+	il->hw_params.max_txq_num = il->cfg->num_of_queues;
+	il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
+	il->hw_params.scd_bc_tbls_size =
+	    il->cfg->num_of_queues *
+	    sizeof(struct il4965_scd_bc_tbl);
 
-static const u8 il4965_bss_ac_to_queue[] = {
-	0, 1, 2, 3,
-};
+	il->hw_params.tfd_size = sizeof(struct il_tfd);
+	il->hw_params.max_stations = IL4965_STATION_COUNT;
+	il->hw_params.max_data_size = IL49_RTC_DATA_SIZE;
+	il->hw_params.max_inst_size = IL49_RTC_INST_SIZE;
+	il->hw_params.max_bsm_size = BSM_SRAM_SIZE;
+	il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
+
+	il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR;
+
+	il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant);
+	il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant);
+	il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant;
+	il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant;
+
+	il->hw_params.ct_kill_threshold =
+	   CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
+
+	il->hw_params.sens = &il4965_sensitivity;
+	il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS;
+}
 
 static int
 il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -6124,37 +6168,18 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 * 1. Allocating HW data
 	 ************************/
 
-	hw = il_alloc_all(cfg);
+	hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il4965_mac_ops);
 	if (!hw) {
 		err = -ENOMEM;
 		goto out;
 	}
 	il = hw->priv;
-	/* At this point both hw and il are allocated. */
-
-	il->ctx.ctxid = 0;
-
-	il->ctx.always_active = true;
-	il->ctx.is_active = true;
-	il->ctx.rxon_cmd = C_RXON;
-	il->ctx.rxon_timing_cmd = C_RXON_TIMING;
-	il->ctx.rxon_assoc_cmd = C_RXON_ASSOC;
-	il->ctx.qos_cmd = C_QOS_PARAM;
-	il->ctx.ap_sta_id = IL_AP_ID;
-	il->ctx.wep_key_cmd = C_WEPKEY;
-	il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo;
-	il->ctx.ac_to_queue = il4965_bss_ac_to_queue;
-	il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC);
-	il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION);
-	il->ctx.ap_devtype = RXON_DEV_TYPE_AP;
-	il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
-	il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
-	il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
-
+	il->hw = hw;
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 
 	D_INFO("*** LOAD DRIVER ***\n");
 	il->cfg = cfg;
+	il->ops = &il4965_ops;
 	il->pci_dev = pdev;
 	il->inta_mask = CSR_INI_SET_MASK;
 
@@ -6260,10 +6285,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/************************
 	 * 5. Setup HW constants
 	 ************************/
-	if (il4965_set_hw_params(il)) {
-		IL_ERR("failed to set hw parameters\n");
-		goto out_free_eeprom;
-	}
+	il4965_set_hw_params(il);
 
 	/*******************
 	 * 6. Setup il
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index 467d0cb..d7e2856 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -641,13 +641,10 @@ il4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
  * there are no non-GF stations present in the BSS.
  */
 static bool
-il4965_rs_use_green(struct ieee80211_sta *sta)
+il4965_rs_use_green(struct il_priv *il, struct ieee80211_sta *sta)
 {
-	struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-	struct il_rxon_context *ctx = sta_priv->common.ctx;
-
 	return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
-	    !(ctx->ht.non_gf_sta_present);
+	       !il->ht.non_gf_sta_present;
 }
 
 /**
@@ -823,8 +820,6 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
 	u32 tx_rate;
 	struct il_scale_tbl_info tbl_type;
 	struct il_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
-	struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-	struct il_rxon_context *ctx = sta_priv->common.ctx;
 
 	D_RATE("get frame ack response, update rate scale win\n");
 
@@ -892,7 +887,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
 		lq_sta->missed_rate_counter++;
 		if (lq_sta->missed_rate_counter > IL_MISSED_RATE_MAX) {
 			lq_sta->missed_rate_counter = 0;
-			il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+			il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
 		}
 		/* Regardless, ignore this status info for outdated rate */
 		return;
@@ -1184,8 +1179,6 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
 	u16 rate_mask;
 	s32 rate;
 	s8 is_green = lq_sta->is_green;
-	struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-	struct il_rxon_context *ctx = sta_priv->common.ctx;
 
 	if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
 		return -1;
@@ -1206,7 +1199,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
 	tbl->max_search = IL_MAX_SEARCH;
 	rate_mask = lq_sta->active_mimo2_rate;
 
-	if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+	if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
 		tbl->is_ht40 = 1;
 	else
 		tbl->is_ht40 = 0;
@@ -1240,8 +1233,6 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta,
 	u16 rate_mask;
 	u8 is_green = lq_sta->is_green;
 	s32 rate;
-	struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-	struct il_rxon_context *ctx = sta_priv->common.ctx;
 
 	if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
 		return -1;
@@ -1254,7 +1245,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta,
 	tbl->max_search = IL_MAX_SEARCH;
 	rate_mask = lq_sta->active_siso_rate;
 
-	if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+	if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
 		tbl->is_ht40 = 1;
 	else
 		tbl->is_ht40 = 0;
@@ -1733,8 +1724,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search)
  * setup rate table in uCode
  */
 static void
-il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx,
-			  struct il_lq_sta *lq_sta,
+il4965_rs_update_rate_tbl(struct il_priv *il, struct il_lq_sta *lq_sta,
 			  struct il_scale_tbl_info *tbl, int idx, u8 is_green)
 {
 	u32 rate;
@@ -1742,7 +1732,7 @@ il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx,
 	/* Update uCode's rate table. */
 	rate = il4965_rate_n_flags_from_tbl(il, tbl, idx, is_green);
 	il4965_rs_fill_link_cmd(il, lq_sta, rate);
-	il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+	il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
 }
 
 /*
@@ -1778,8 +1768,6 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
 	s32 sr;
 	u8 tid = MAX_TID_COUNT;
 	struct il_tid_data *tid_data;
-	struct il_station_priv *sta_priv = (void *)sta->drv_priv;
-	struct il_rxon_context *ctx = sta_priv->common.ctx;
 
 	D_RATE("rate scale calculate new rate for skb\n");
 
@@ -1815,7 +1803,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
 	if (is_legacy(tbl->lq_type))
 		lq_sta->is_green = 0;
 	else
-		lq_sta->is_green = il4965_rs_use_green(sta);
+		lq_sta->is_green = il4965_rs_use_green(il, sta);
 	is_green = lq_sta->is_green;
 
 	/* current tx rate */
@@ -1854,7 +1842,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
 			tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
 			/* get "active" rate info */
 			idx = il4965_hwrate_to_plcp_idx(tbl->current_rate);
-			il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx,
+			il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx,
 						      is_green);
 		}
 		return;
@@ -2057,8 +2045,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
 lq_update:
 	/* Replace uCode's rate table for the destination station. */
 	if (update_lq)
-		il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx,
-					      is_green);
+		il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green);
 
 	/* Should we stay with this modulation mode,
 	 * or search for a new one? */
@@ -2098,7 +2085,7 @@ lq_update:
 			D_RATE("Switch current  mcs: %X idx: %d\n",
 			       tbl->current_rate, idx);
 			il4965_rs_fill_link_cmd(il, lq_sta, tbl->current_rate);
-			il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+			il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
 		} else
 			done_search = 1;
 	}
@@ -2166,17 +2153,15 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
 	int rate_idx;
 	int i;
 	u32 rate;
-	u8 use_green = il4965_rs_use_green(sta);
+	u8 use_green = il4965_rs_use_green(il, sta);
 	u8 active_tbl = 0;
 	u8 valid_tx_ant;
 	struct il_station_priv *sta_priv;
-	struct il_rxon_context *ctx;
 
 	if (!sta || !lq_sta)
 		return;
 
 	sta_priv = (void *)sta->drv_priv;
-	ctx = sta_priv->common.ctx;
 
 	i = lq_sta->last_txrate_idx;
 
@@ -2208,7 +2193,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
 	il4965_rs_set_expected_tpt_table(lq_sta, tbl);
 	il4965_rs_fill_link_cmd(NULL, lq_sta, rate);
 	il->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
-	il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_SYNC, true);
+	il_send_lq_cmd(il, &lq_sta->lq, CMD_SYNC, true);
 }
 
 static void
@@ -2341,7 +2326,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
 	lq_sta->is_dup = 0;
 	lq_sta->max_rate_idx = -1;
 	lq_sta->missed_rate_counter = IL_MISSED_RATE_MAX;
-	lq_sta->is_green = il4965_rs_use_green(sta);
+	lq_sta->is_green = il4965_rs_use_green(il, sta);
 	lq_sta->active_legacy_rate = il->active_rate & ~(0x1000);
 	lq_sta->band = il->band;
 	/*
@@ -2579,9 +2564,6 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file,
 	char buf[64];
 	size_t buf_size;
 	u32 parsed_rate;
-	struct il_station_priv *sta_priv =
-	    container_of(lq_sta, struct il_station_priv, lq_sta);
-	struct il_rxon_context *ctx = sta_priv->common.ctx;
 
 	il = lq_sta->drv;
 	memset(buf, 0, sizeof(buf));
@@ -2603,7 +2585,7 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file,
 
 	if (lq_sta->dbg_fixed_rate) {
 		il4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
-		il_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, false);
+		il_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
 	}
 
 	return count;
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c
index cacbc03..79e4e79 100644
--- a/drivers/net/wireless/iwlegacy/4965.c
+++ b/drivers/net/wireless/iwlegacy/4965.c
@@ -569,82 +569,6 @@ il4965_chain_noise_reset(struct il_priv *il)
 	}
 }
 
-static struct il_sensitivity_ranges il4965_sensitivity = {
-	.min_nrg_cck = 97,
-	.max_nrg_cck = 0,	/* not used, set to 0 */
-
-	.auto_corr_min_ofdm = 85,
-	.auto_corr_min_ofdm_mrc = 170,
-	.auto_corr_min_ofdm_x1 = 105,
-	.auto_corr_min_ofdm_mrc_x1 = 220,
-
-	.auto_corr_max_ofdm = 120,
-	.auto_corr_max_ofdm_mrc = 210,
-	.auto_corr_max_ofdm_x1 = 140,
-	.auto_corr_max_ofdm_mrc_x1 = 270,
-
-	.auto_corr_min_cck = 125,
-	.auto_corr_max_cck = 200,
-	.auto_corr_min_cck_mrc = 200,
-	.auto_corr_max_cck_mrc = 400,
-
-	.nrg_th_cck = 100,
-	.nrg_th_ofdm = 100,
-
-	.barker_corr_th_min = 190,
-	.barker_corr_th_min_mrc = 390,
-	.nrg_th_cca = 62,
-};
-
-static void
-il4965_set_ct_threshold(struct il_priv *il)
-{
-	/* want Kelvin */
-	il->hw_params.ct_kill_threshold =
-	    CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
-}
-
-/**
- * il4965_hw_set_hw_params
- *
- * Called when initializing driver
- */
-static int
-il4965_hw_set_hw_params(struct il_priv *il)
-{
-	if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES &&
-	    il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES)
-		il->cfg->base_params->num_of_queues =
-		    il->cfg->mod_params->num_of_queues;
-
-	il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues;
-	il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
-	il->hw_params.scd_bc_tbls_size =
-	    il->cfg->base_params->num_of_queues *
-	    sizeof(struct il4965_scd_bc_tbl);
-	il->hw_params.tfd_size = sizeof(struct il_tfd);
-	il->hw_params.max_stations = IL4965_STATION_COUNT;
-	il->ctx.bcast_sta_id = IL4965_BROADCAST_ID;
-	il->hw_params.max_data_size = IL49_RTC_DATA_SIZE;
-	il->hw_params.max_inst_size = IL49_RTC_INST_SIZE;
-	il->hw_params.max_bsm_size = BSM_SRAM_SIZE;
-	il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
-
-	il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR;
-
-	il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant);
-	il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant);
-	il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant;
-	il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant;
-
-	il4965_set_ct_threshold(il);
-
-	il->hw_params.sens = &il4965_sensitivity;
-	il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS;
-
-	return 0;
-}
-
 static s32
 il4965_math_div_round(s32 num, s32 denom, s32 * res)
 {
@@ -1342,7 +1266,6 @@ il4965_send_tx_power(struct il_priv *il)
 	u8 band = 0;
 	bool is_ht40 = false;
 	u8 ctrl_chan_high = 0;
-	struct il_rxon_context *ctx = &il->ctx;
 
 	if (WARN_ONCE
 	    (test_bit(S_SCAN_HW, &il->status),
@@ -1351,16 +1274,16 @@ il4965_send_tx_power(struct il_priv *il)
 
 	band = il->band == IEEE80211_BAND_2GHZ;
 
-	is_ht40 = iw4965_is_ht40_channel(ctx->active.flags);
+	is_ht40 = iw4965_is_ht40_channel(il->active.flags);
 
-	if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+	if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
 		ctrl_chan_high = 1;
 
 	cmd.band = band;
-	cmd.channel = ctx->active.channel;
+	cmd.channel = il->active.channel;
 
 	ret =
-	    il4965_fill_txpower_tbl(il, band, le16_to_cpu(ctx->active.channel),
+	    il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel),
 				    is_ht40, ctrl_chan_high, &cmd.tx_power);
 	if (ret)
 		goto out;
@@ -1372,12 +1295,12 @@ out:
 }
 
 static int
-il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_send_rxon_assoc(struct il_priv *il)
 {
 	int ret = 0;
 	struct il4965_rxon_assoc_cmd rxon_assoc;
-	const struct il_rxon_cmd *rxon1 = &ctx->staging;
-	const struct il_rxon_cmd *rxon2 = &ctx->active;
+	const struct il_rxon_cmd *rxon1 = &il->staging;
+	const struct il_rxon_cmd *rxon2 = &il->active;
 
 	if (rxon1->flags == rxon2->flags &&
 	    rxon1->filter_flags == rxon2->filter_flags &&
@@ -1392,16 +1315,16 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
 		return 0;
 	}
 
-	rxon_assoc.flags = ctx->staging.flags;
-	rxon_assoc.filter_flags = ctx->staging.filter_flags;
-	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
-	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+	rxon_assoc.flags = il->staging.flags;
+	rxon_assoc.filter_flags = il->staging.filter_flags;
+	rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
+	rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
 	rxon_assoc.reserved = 0;
 	rxon_assoc.ofdm_ht_single_stream_basic_rates =
-	    ctx->staging.ofdm_ht_single_stream_basic_rates;
+	    il->staging.ofdm_ht_single_stream_basic_rates;
 	rxon_assoc.ofdm_ht_dual_stream_basic_rates =
-	    ctx->staging.ofdm_ht_dual_stream_basic_rates;
-	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+	    il->staging.ofdm_ht_dual_stream_basic_rates;
+	rxon_assoc.rx_chain_select_flags = il->staging.rx_chain;
 
 	ret =
 	    il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc),
@@ -1411,23 +1334,20 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
 }
 
 static int
-il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_commit_rxon(struct il_priv *il)
 {
 	/* cast away the const for active_rxon in this function */
-	struct il_rxon_cmd *active_rxon = (void *)&ctx->active;
+	struct il_rxon_cmd *active_rxon = (void *)&il->active;
 	int ret;
-	bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+	bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
 
 	if (!il_is_alive(il))
 		return -EBUSY;
 
-	if (!ctx->is_active)
-		return 0;
-
 	/* always get timestamp with Rx frame */
-	ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+	il->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
-	ret = il_check_rxon_cmd(il, ctx);
+	ret = il_check_rxon_cmd(il);
 	if (ret) {
 		IL_ERR("Invalid RXON configuration.  Not committing.\n");
 		return -EINVAL;
@@ -1438,7 +1358,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	 * abort any previous channel switch if still in process
 	 */
 	if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) &&
-	    il->switch_channel != ctx->staging.channel) {
+	    il->switch_channel != il->staging.channel) {
 		D_11H("abort channel switch on %d\n",
 		      le16_to_cpu(il->switch_channel));
 		il_chswitch_done(il, false);
@@ -1447,15 +1367,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	/* If we don't need to send a full RXON, we can use
 	 * il_rxon_assoc_cmd which is used to reconfigure filter
 	 * and other flags for the current radio configuration. */
-	if (!il_full_rxon_required(il, ctx)) {
-		ret = il_send_rxon_assoc(il, ctx);
+	if (!il_full_rxon_required(il)) {
+		ret = il_send_rxon_assoc(il);
 		if (ret) {
 			IL_ERR("Error setting RXON_ASSOC (%d)\n", ret);
 			return ret;
 		}
 
-		memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
-		il_print_rx_config_cmd(il, ctx);
+		memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
+		il_print_rx_config_cmd(il);
 		/*
 		 * We do not commit tx power settings while channel changing,
 		 * do it now if tx power changed.
@@ -1468,12 +1388,12 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	 * an RXON_ASSOC and the new config wants the associated mask enabled,
 	 * we must clear the associated from the active configuration
 	 * before we apply the new config */
-	if (il_is_associated_ctx(ctx) && new_assoc) {
+	if (il_is_associated(il) && new_assoc) {
 		D_INFO("Toggling associated bit on current RXON\n");
 		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
 		ret =
-		    il_send_cmd_pdu(il, ctx->rxon_cmd,
+		    il_send_cmd_pdu(il, C_RXON,
 				    sizeof(struct il_rxon_cmd), active_rxon);
 
 		/* If the mask clearing failed then we set
@@ -1483,9 +1403,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 			IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret);
 			return ret;
 		}
-		il_clear_ucode_stations(il, ctx);
-		il_restore_stations(il, ctx);
-		ret = il4965_restore_default_wep_keys(il, ctx);
+		il_clear_ucode_stations(il);
+		il_restore_stations(il);
+		ret = il4965_restore_default_wep_keys(il);
 		if (ret) {
 			IL_ERR("Failed to restore WEP keys (%d)\n", ret);
 			return ret;
@@ -1494,9 +1414,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 
 	D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
 	       "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"),
-	       le16_to_cpu(ctx->staging.channel), ctx->staging.bssid_addr);
+	       le16_to_cpu(il->staging.channel), il->staging.bssid_addr);
 
-	il_set_rxon_hwcrypto(il, ctx, !il->cfg->mod_params->sw_crypto);
+	il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto);
 
 	/* Apply the new configuration
 	 * RXON unassoc clears the station table in uCode so restoration of
@@ -1504,17 +1424,17 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 	 */
 	if (!new_assoc) {
 		ret =
-		    il_send_cmd_pdu(il, ctx->rxon_cmd,
-				    sizeof(struct il_rxon_cmd), &ctx->staging);
+		    il_send_cmd_pdu(il, C_RXON,
+				    sizeof(struct il_rxon_cmd), &il->staging);
 		if (ret) {
 			IL_ERR("Error setting new RXON (%d)\n", ret);
 			return ret;
 		}
 		D_INFO("Return from !new_assoc RXON.\n");
-		memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
-		il_clear_ucode_stations(il, ctx);
-		il_restore_stations(il, ctx);
-		ret = il4965_restore_default_wep_keys(il, ctx);
+		memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
+		il_clear_ucode_stations(il);
+		il_restore_stations(il);
+		ret = il4965_restore_default_wep_keys(il);
 		if (ret) {
 			IL_ERR("Failed to restore WEP keys (%d)\n", ret);
 			return ret;
@@ -1526,15 +1446,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
 		 * RXON assoc doesn't clear the station table in uCode,
 		 */
 		ret =
-		    il_send_cmd_pdu(il, ctx->rxon_cmd,
-				    sizeof(struct il_rxon_cmd), &ctx->staging);
+		    il_send_cmd_pdu(il, C_RXON,
+				    sizeof(struct il_rxon_cmd), &il->staging);
 		if (ret) {
 			IL_ERR("Error setting new RXON (%d)\n", ret);
 			return ret;
 		}
-		memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+		memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
 	}
-	il_print_rx_config_cmd(il, ctx);
+	il_print_rx_config_cmd(il);
 
 	il4965_init_sensitivity(il);
 
@@ -1553,7 +1473,6 @@ static int
 il4965_hw_channel_switch(struct il_priv *il,
 			 struct ieee80211_channel_switch *ch_switch)
 {
-	struct il_rxon_context *ctx = &il->ctx;
 	int rc;
 	u8 band = 0;
 	bool is_ht40 = false;
@@ -1564,21 +1483,24 @@ il4965_hw_channel_switch(struct il_priv *il,
 	u16 ch;
 	u32 tsf_low;
 	u8 switch_count;
-	u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
-	struct ieee80211_vif *vif = ctx->vif;
-	band = il->band == IEEE80211_BAND_2GHZ;
+	u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval);
+	struct ieee80211_vif *vif = il->vif;
+	band = (il->band == IEEE80211_BAND_2GHZ);
 
-	is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags);
+	if (WARN_ON_ONCE(vif == NULL))
+		return -EIO;
+
+	is_ht40 = iw4965_is_ht40_channel(il->staging.flags);
 
-	if (is_ht40 && (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+	if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
 		ctrl_chan_high = 1;
 
 	cmd.band = band;
 	cmd.expect_beacon = 0;
 	ch = ch_switch->channel->hw_value;
 	cmd.channel = cpu_to_le16(ch);
-	cmd.rxon_flags = ctx->staging.flags;
-	cmd.rxon_filter_flags = ctx->staging.filter_flags;
+	cmd.rxon_flags = il->staging.flags;
+	cmd.rxon_filter_flags = il->staging.filter_flags;
 	switch_count = ch_switch->count;
 	tsf_low = ch_switch->timestamp & 0x0ffffffff;
 	/*
@@ -1611,7 +1533,7 @@ il4965_hw_channel_switch(struct il_priv *il,
 		cmd.expect_beacon = il_is_channel_radar(ch_info);
 	else {
 		IL_ERR("invalid channel switch from %u to %u\n",
-		       ctx->active.channel, ch);
+		       il->active.channel, ch);
 		return -EFAULT;
 	}
 
@@ -1876,7 +1798,7 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
 		D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
 			   agg->frame_count, agg->start_idx, idx);
 
-		info = IEEE80211_SKB_CB(il->txq[txq_id].txb[idx].skb);
+		info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]);
 		info->status.rates[0].count = tx_resp->failure_frame + 1;
 		info->flags &= ~IEEE80211_TX_CTL_AMPDU;
 		info->flags |= il4965_tx_status_to_mac80211(status);
@@ -1891,6 +1813,7 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
 		/* Two or more frames were attempted; expect block-ack */
 		u64 bitmap = 0;
 		int start = agg->start_idx;
+		struct sk_buff *skb;
 
 		/* Construct bit-map of pending frames within Tx win */
 		for (i = 0; i < agg->frame_count; i++) {
@@ -1908,12 +1831,10 @@ il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
 			D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
 				   agg->frame_count, txq_id, idx);
 
-			hdr = il_tx_queue_get_hdr(il, txq_id, idx);
-			if (!hdr) {
-				IL_ERR("BUG_ON idx doesn't point to valid skb"
-				       " idx=%d, txq_id=%d\n", idx, txq_id);
+			skb = il->txq[txq_id].skbs[idx];
+			if (WARN_ON_ONCE(skb == NULL))
 				return -1;
-			}
+			hdr = (struct ieee80211_hdr *) skb->data;
 
 			sc = le16_to_cpu(hdr->seq_ctrl);
 			if (idx != (SEQ_TO_SN(sc) & 0xff)) {
@@ -1969,7 +1890,7 @@ il4965_find_station(struct il_priv *il, const u8 * addr)
 		start = IL_STA_ID;
 
 	if (is_broadcast_ether_addr(addr))
-		return il->ctx.bcast_sta_id;
+		return il->hw_params.bcast_id;
 
 	spin_lock_irqsave(&il->sta_lock, flags);
 	for (i = start; i < il->hw_params.max_stations; i++)
@@ -2021,6 +1942,7 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int idx = SEQ_TO_IDX(sequence);
 	struct il_tx_queue *txq = &il->txq[txq_id];
+	struct sk_buff *skb;
 	struct ieee80211_hdr *hdr;
 	struct ieee80211_tx_info *info;
 	struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
@@ -2039,10 +1961,12 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
 	}
 
 	txq->time_stamp = jiffies;
-	info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+
+	skb = txq->skbs[txq->q.read_ptr];
+	info = IEEE80211_SKB_CB(skb);
 	memset(&info->status, 0, sizeof(info->status));
 
-	hdr = il_tx_queue_get_hdr(il, txq_id, idx);
+	hdr = (struct ieee80211_hdr *) skb->data;
 	if (ieee80211_is_data_qos(hdr->frame_control)) {
 		qc = ieee80211_get_qos_ctl(hdr);
 		tid = qc[0] & 0xf;
@@ -2133,21 +2057,18 @@ static struct il_hcmd_ops il4965_hcmd = {
 static void
 il4965_post_scan(struct il_priv *il)
 {
-	struct il_rxon_context *ctx = &il->ctx;
-
 	/*
 	 * Since setting the RXON may have been deferred while
 	 * performing the scan, fire one off if needed
 	 */
-	if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
-		il_commit_rxon(il, ctx);
+	if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
+		il_commit_rxon(il);
 }
 
 static void
 il4965_post_associate(struct il_priv *il)
 {
-	struct il_rxon_context *ctx = &il->ctx;
-	struct ieee80211_vif *vif = ctx->vif;
+	struct ieee80211_vif *vif = il->vif;
 	struct ieee80211_conf *conf = NULL;
 	int ret = 0;
 
@@ -2161,41 +2082,41 @@ il4965_post_associate(struct il_priv *il)
 
 	conf = &il->hw->conf;
 
-	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	il_commit_rxon(il, ctx);
+	il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+	il_commit_rxon(il);
 
-	ret = il_send_rxon_timing(il, ctx);
+	ret = il_send_rxon_timing(il);
 	if (ret)
 		IL_WARN("RXON timing - " "Attempting to continue.\n");
 
-	ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+	il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
 	il_set_rxon_ht(il, &il->current_ht_config);
 
-	if (il->cfg->ops->hcmd->set_rxon_chain)
-		il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+	if (il->ops->hcmd->set_rxon_chain)
+		il->ops->hcmd->set_rxon_chain(il);
 
-	ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+	il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
 
 	D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid,
 		vif->bss_conf.beacon_int);
 
 	if (vif->bss_conf.use_short_preamble)
-		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+		il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 	else
-		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+		il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-	if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+	if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
 		if (vif->bss_conf.use_short_slot)
-			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+			il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+			il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 	}
 
-	il_commit_rxon(il, ctx);
+	il_commit_rxon(il);
 
 	D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid,
-		ctx->active.bssid_addr);
+		il->active.bssid_addr);
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
@@ -2223,8 +2144,7 @@ il4965_post_associate(struct il_priv *il)
 static void
 il4965_config_ap(struct il_priv *il)
 {
-	struct il_rxon_context *ctx = &il->ctx;
-	struct ieee80211_vif *vif = ctx->vif;
+	struct ieee80211_vif *vif = il->vif;
 	int ret = 0;
 
 	lockdep_assert_held(&il->mutex);
@@ -2233,14 +2153,14 @@ il4965_config_ap(struct il_priv *il)
 		return;
 
 	/* The following should be done only at AP bring up */
-	if (!il_is_associated_ctx(ctx)) {
+	if (!il_is_associated(il)) {
 
 		/* RXON - unassoc (to set timing command) */
-		ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-		il_commit_rxon(il, ctx);
+		il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+		il_commit_rxon(il);
 
 		/* RXON Timing */
-		ret = il_send_rxon_timing(il, ctx);
+		ret = il_send_rxon_timing(il);
 		if (ret)
 			IL_WARN("RXON timing failed - "
 				"Attempting to continue.\n");
@@ -2248,27 +2168,27 @@ il4965_config_ap(struct il_priv *il)
 		/* AP has all antennas */
 		il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
 		il_set_rxon_ht(il, &il->current_ht_config);
-		if (il->cfg->ops->hcmd->set_rxon_chain)
-			il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+		if (il->ops->hcmd->set_rxon_chain)
+			il->ops->hcmd->set_rxon_chain(il);
 
-		ctx->staging.assoc_id = 0;
+		il->staging.assoc_id = 0;
 
 		if (vif->bss_conf.use_short_preamble)
-			ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+			il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+			il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 
-		if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+		if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
 			if (vif->bss_conf.use_short_slot)
-				ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+				il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 			else
-				ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+				il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 		}
 		/* need to send beacon cmd before committing assoc RXON! */
 		il4965_send_beacon_cmd(il);
 		/* restore RXON assoc */
-		ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
-		il_commit_rxon(il, ctx);
+		il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+		il_commit_rxon(il);
 	}
 	il4965_send_beacon_cmd(il);
 }
@@ -2281,7 +2201,6 @@ static struct il_hcmd_utils_ops il4965_hcmd_utils = {
 };
 
 static struct il_lib_ops il4965_lib = {
-	.set_hw_params = il4965_hw_set_hw_params,
 	.txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
 	.txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
 	.txq_free_tfd = il4965_hw_txq_free_tfd,
@@ -2330,51 +2249,12 @@ static const struct il_legacy_ops il4965_legacy_ops = {
 	.update_bcast_stations = il4965_update_bcast_stations,
 };
 
-struct ieee80211_ops il4965_hw_ops = {
-	.tx = il4965_mac_tx,
-	.start = il4965_mac_start,
-	.stop = il4965_mac_stop,
-	.add_interface = il_mac_add_interface,
-	.remove_interface = il_mac_remove_interface,
-	.change_interface = il_mac_change_interface,
-	.config = il_mac_config,
-	.configure_filter = il4965_configure_filter,
-	.set_key = il4965_mac_set_key,
-	.update_tkip_key = il4965_mac_update_tkip_key,
-	.conf_tx = il_mac_conf_tx,
-	.reset_tsf = il_mac_reset_tsf,
-	.bss_info_changed = il_mac_bss_info_changed,
-	.ampdu_action = il4965_mac_ampdu_action,
-	.hw_scan = il_mac_hw_scan,
-	.sta_add = il4965_mac_sta_add,
-	.sta_remove = il_mac_sta_remove,
-	.channel_switch = il4965_mac_channel_switch,
-	.tx_last_beacon = il_mac_tx_last_beacon,
-};
-
-static const struct il_ops il4965_ops = {
+const struct il_ops il4965_ops = {
 	.lib = &il4965_lib,
 	.hcmd = &il4965_hcmd,
 	.utils = &il4965_hcmd_utils,
 	.led = &il4965_led_ops,
 	.legacy = &il4965_legacy_ops,
-	.ieee80211_ops = &il4965_hw_ops,
-};
-
-static struct il_base_params il4965_base_params = {
-	.eeprom_size = IL4965_EEPROM_IMG_SIZE,
-	.num_of_queues = IL49_NUM_QUEUES,
-	.num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
-	.pll_cfg_val = 0,
-	.set_l0s = true,
-	.use_bsm = true,
-	.led_compensation = 61,
-	.chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
-	.wd_timeout = IL_DEF_WD_TIMEOUT,
-	.temperature_kelvin = true,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 };
 
 struct il_cfg il4965_cfg = {
@@ -2387,15 +2267,27 @@ struct il_cfg il4965_cfg = {
 	.valid_rx_ant = ANT_ABC,
 	.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
-	.ops = &il4965_ops,
 	.mod_params = &il4965_mod_params,
-	.base_params = &il4965_base_params,
 	.led_mode = IL_LED_BLINK,
 	/*
 	 * Force use of chains B and C for scan RX on 5 GHz band
 	 * because the device has off-channel reception on chain A.
 	 */
 	.scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
+
+	.eeprom_size = IL4965_EEPROM_IMG_SIZE,
+	.num_of_queues = IL49_NUM_QUEUES,
+	.num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
+	.pll_cfg_val = 0,
+	.set_l0s = true,
+	.use_bsm = true,
+	.led_compensation = 61,
+	.chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
+	.wd_timeout = IL_DEF_WD_TIMEOUT,
+	.temperature_kelvin = true,
+	.ucode_tracing = true,
+	.sensitivity_calib_by_driver = true,
+	.chain_noise_calib_by_driver = true,
 };
 
 /* Module firmware */
diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h
index f280e01..83ab604 100644
--- a/drivers/net/wireless/iwlegacy/4965.h
+++ b/drivers/net/wireless/iwlegacy/4965.h
@@ -38,17 +38,16 @@ struct il_rxon_context;
 
 /* configuration for the _4965 devices */
 extern struct il_cfg il4965_cfg;
+extern const struct il_ops il4965_ops;
 
 extern struct il_mod_params il4965_mod_params;
 
-extern struct ieee80211_ops il4965_hw_ops;
-
 /* tx queue */
 void il4965_free_tfds_in_queue(struct il_priv *il, int sta_id, int tid,
 			       int freed);
 
 /* RXON */
-void il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx);
+void il4965_set_rxon_chain(struct il_priv *il);
 
 /* uCode */
 int il4965_verify_ucode(struct il_priv *il);
@@ -134,21 +133,18 @@ il4965_get_tx_fail_reason(u32 status)
 #endif
 
 /* station management */
-int il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx);
-int il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
-			     const u8 *addr, u8 *sta_id_r);
+int il4965_alloc_bcast_station(struct il_priv *il);
+int il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r);
 int il4965_remove_default_wep_key(struct il_priv *il,
-				  struct il_rxon_context *ctx,
 				  struct ieee80211_key_conf *key);
-int il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_set_default_wep_key(struct il_priv *il,
 			       struct ieee80211_key_conf *key);
-int il4965_restore_default_wep_keys(struct il_priv *il,
-				    struct il_rxon_context *ctx);
-int il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_restore_default_wep_keys(struct il_priv *il);
+int il4965_set_dynamic_key(struct il_priv *il,
 			   struct ieee80211_key_conf *key, u8 sta_id);
-int il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_remove_dynamic_key(struct il_priv *il,
 			      struct ieee80211_key_conf *key, u8 sta_id);
-void il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
+void il4965_update_tkip_key(struct il_priv *il,
 			    struct ieee80211_key_conf *keyconf,
 			    struct ieee80211_sta *sta, u32 iv32,
 			    u16 *phase1key);
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 36454d0..04ec38e 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -512,15 +512,15 @@ il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off)
 	}
 
 	D_LED("Led blink time compensation=%u\n",
-	      il->cfg->base_params->led_compensation);
+	      il->cfg->led_compensation);
 	led_cmd.on =
 	    il_blink_compensation(il, on,
-				  il->cfg->base_params->led_compensation);
+				  il->cfg->led_compensation);
 	led_cmd.off =
 	    il_blink_compensation(il, off,
-				  il->cfg->base_params->led_compensation);
+				  il->cfg->led_compensation);
 
-	ret = il->cfg->ops->led->cmd(il, &led_cmd);
+	ret = il->ops->led->cmd(il, &led_cmd);
 	if (!ret) {
 		il->blink_on = on;
 		il->blink_off = off;
@@ -691,7 +691,7 @@ il_eeprom_verify_signature(struct il_priv *il)
 const u8 *
 il_eeprom_query_addr(const struct il_priv *il, size_t offset)
 {
-	BUG_ON(offset >= il->cfg->base_params->eeprom_size);
+	BUG_ON(offset >= il->cfg->eeprom_size);
 	return &il->eeprom[offset];
 }
 EXPORT_SYMBOL(il_eeprom_query_addr);
@@ -722,7 +722,7 @@ il_eeprom_init(struct il_priv *il)
 	u16 addr;
 
 	/* allocate eeprom */
-	sz = il->cfg->base_params->eeprom_size;
+	sz = il->cfg->eeprom_size;
 	D_EEPROM("NVM size = %d\n", sz);
 	il->eeprom = kzalloc(sz, GFP_KERNEL);
 	if (!il->eeprom) {
@@ -731,7 +731,7 @@ il_eeprom_init(struct il_priv *il)
 	}
 	e = (__le16 *) il->eeprom;
 
-	il->cfg->ops->lib->apm_ops.init(il);
+	il->ops->lib->apm_ops.init(il);
 
 	ret = il_eeprom_verify_signature(il);
 	if (ret < 0) {
@@ -741,7 +741,7 @@ il_eeprom_init(struct il_priv *il)
 	}
 
 	/* Make sure driver (instead of uCode) is allowed to read EEPROM */
-	ret = il->cfg->ops->lib->eeprom_ops.acquire_semaphore(il);
+	ret = il->ops->lib->eeprom_ops.acquire_semaphore(il);
 	if (ret < 0) {
 		IL_ERR("Failed to acquire EEPROM semaphore.\n");
 		ret = -ENOENT;
@@ -773,7 +773,7 @@ il_eeprom_init(struct il_priv *il)
 
 	ret = 0;
 done:
-	il->cfg->ops->lib->eeprom_ops.release_semaphore(il);
+	il->ops->lib->eeprom_ops.release_semaphore(il);
 
 err:
 	if (ret)
@@ -800,7 +800,7 @@ il_init_band_reference(const struct il_priv *il, int eep_band,
 		       const u8 **eeprom_ch_idx)
 {
 	u32 offset =
-	    il->cfg->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1];
+	    il->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1];
 	switch (eep_band) {
 	case 1:		/* 2.4GHz band */
 		*eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_1);
@@ -1001,9 +1001,9 @@ il_init_channel_map(struct il_priv *il)
 	}
 
 	/* Check if we do have HT40 channels */
-	if (il->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
+	if (il->ops->lib->eeprom_ops.regulatory_bands[5] ==
 	    EEPROM_REGULATORY_BAND_NO_HT40 &&
-	    il->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
+	    il->ops->lib->eeprom_ops.regulatory_bands[6] ==
 	    EEPROM_REGULATORY_BAND_NO_HT40)
 		return 0;
 
@@ -1158,9 +1158,9 @@ il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
 		if (!(cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK))
 			clear_bit(S_POWER_PMI, &il->status);
 
-		if (il->cfg->ops->lib->update_chain_flags && update_chains)
-			il->cfg->ops->lib->update_chain_flags(il);
-		else if (il->cfg->ops->lib->update_chain_flags)
+		if (il->ops->lib->update_chain_flags && update_chains)
+			il->ops->lib->update_chain_flags(il);
+		else if (il->ops->lib->update_chain_flags)
 			D_POWER("Cannot update the power, chain noise "
 				"calibration running: %d\n",
 				il->chain_noise_data.state);
@@ -1442,7 +1442,6 @@ u16
 il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band,
 			  struct ieee80211_vif *vif)
 {
-	struct il_rxon_context *ctx = &il->ctx;
 	u16 value;
 
 	u16 passive =
@@ -1457,7 +1456,7 @@ il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band,
 		 * dwell time to be 98% of the smallest beacon interval
 		 * (minus 2 * channel tune time)
 		 */
-		value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
+		value = il->vif ? il->vif->bss_conf.beacon_int : 0;
 		if (value > IL_PASSIVE_DWELL_BASE || !value)
 			value = IL_PASSIVE_DWELL_BASE;
 		value = (value * 98) / 100 - IL_CHANNEL_TUNE_TIME * 2;
@@ -1486,7 +1485,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
 
 	lockdep_assert_held(&il->mutex);
 
-	if (WARN_ON(!il->cfg->ops->utils->request_scan))
+	if (WARN_ON(!il->ops->utils->request_scan))
 		return -EOPNOTSUPP;
 
 	cancel_delayed_work(&il->scan_check);
@@ -1511,7 +1510,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
 	set_bit(S_SCANNING, &il->status);
 	il->scan_start = jiffies;
 
-	ret = il->cfg->ops->utils->request_scan(il, vif);
+	ret = il->ops->utils->request_scan(il, vif);
 	if (ret) {
 		clear_bit(S_SCANNING, &il->status);
 		return ret;
@@ -1673,7 +1672,7 @@ out_settings:
 	il_power_set_mode(il, &il->power_data.sleep_cmd_next, false);
 	il_set_tx_power(il, il->tx_power_next, false);
 
-	il->cfg->ops->utils->post_scan(il);
+	il->ops->utils->post_scan(il);
 
 out:
 	mutex_unlock(&il->mutex);
@@ -1815,7 +1814,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
 		might_sleep();
 	}
 
-	cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data);
+	cmd.len = il->ops->utils->build_addsta_hcmd(sta, data);
 	ret = il_send_cmd(il, &cmd);
 
 	if (ret || (flags & CMD_ASYNC))
@@ -1832,8 +1831,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
 EXPORT_SYMBOL(il_send_add_sta);
 
 static void
-il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta,
-		      struct il_rxon_context *ctx)
+il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta)
 {
 	struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
 	__le32 sta_flags;
@@ -1874,7 +1872,7 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta,
 	    cpu_to_le32((u32) sta_ht_inf->
 			ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
-	if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+	if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
 		sta_flags |= STA_FLG_HT40_EN_MSK;
 	else
 		sta_flags &= ~STA_FLG_HT40_EN_MSK;
@@ -1890,8 +1888,8 @@ done:
  * should be called with sta_lock held
  */
 u8
-il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
-		const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
+il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
+		struct ieee80211_sta *sta)
 {
 	struct il_station_entry *station;
 	int i;
@@ -1899,9 +1897,9 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
 	u16 rate;
 
 	if (is_ap)
-		sta_id = ctx->ap_sta_id;
+		sta_id = IL_AP_ID;
 	else if (is_broadcast_ether_addr(addr))
-		sta_id = ctx->bcast_sta_id;
+		sta_id = il->hw_params.bcast_id;
 	else
 		for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) {
 			if (!compare_ether_addr
@@ -1950,22 +1948,14 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
 	memcpy(station->sta.sta.addr, addr, ETH_ALEN);
 	station->sta.mode = 0;
 	station->sta.sta.sta_id = sta_id;
-	station->sta.station_flags = ctx->station_flags;
-	station->ctxid = ctx->ctxid;
-
-	if (sta) {
-		struct il_station_priv_common *sta_priv;
-
-		sta_priv = (void *)sta->drv_priv;
-		sta_priv->ctx = ctx;
-	}
+	station->sta.station_flags = 0;
 
 	/*
 	 * OK to call unconditionally, since local stations (IBSS BSSID
 	 * STA and broadcast STA) pass in a NULL sta, and mac80211
 	 * doesn't allow HT IBSS.
 	 */
-	il_set_ht_add_station(il, sta_id, sta, ctx);
+	il_set_ht_add_station(il, sta_id, sta);
 
 	/* 3945 only */
 	rate = (il->band == IEEE80211_BAND_5GHZ) ? RATE_6M_PLCP : RATE_1M_PLCP;
@@ -1983,9 +1973,8 @@ EXPORT_SYMBOL_GPL(il_prep_station);
  * il_add_station_common -
  */
 int
-il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
-		      const u8 *addr, bool is_ap, struct ieee80211_sta *sta,
-		      u8 *sta_id_r)
+il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap,
+		      struct ieee80211_sta *sta, u8 *sta_id_r)
 {
 	unsigned long flags_spin;
 	int ret = 0;
@@ -1994,7 +1983,7 @@ il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
 
 	*sta_id_r = 0;
 	spin_lock_irqsave(&il->sta_lock, flags_spin);
-	sta_id = il_prep_station(il, ctx, addr, is_ap, sta);
+	sta_id = il_prep_station(il, addr, is_ap, sta);
 	if (sta_id == IL_INVALID_STATION) {
 		IL_ERR("Unable to prepare station %pM for addition\n", addr);
 		spin_unlock_irqrestore(&il->sta_lock, flags_spin);
@@ -2181,7 +2170,7 @@ EXPORT_SYMBOL_GPL(il_remove_station);
  * the ucode, e.g. unassociated RXON.
  */
 void
-il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx)
+il_clear_ucode_stations(struct il_priv *il)
 {
 	int i;
 	unsigned long flags_spin;
@@ -2191,9 +2180,6 @@ il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx)
 
 	spin_lock_irqsave(&il->sta_lock, flags_spin);
 	for (i = 0; i < il->hw_params.max_stations; i++) {
-		if (ctx && ctx->ctxid != il->stations[i].ctxid)
-			continue;
-
 		if (il->stations[i].used & IL_STA_UCODE_ACTIVE) {
 			D_INFO("Clearing ucode active for station %d\n", i);
 			il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
@@ -2216,7 +2202,7 @@ EXPORT_SYMBOL(il_clear_ucode_stations);
  * Function sleeps.
  */
 void
-il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
+il_restore_stations(struct il_priv *il)
 {
 	struct il_addsta_cmd sta_cmd;
 	struct il_link_quality_cmd lq;
@@ -2234,8 +2220,6 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
 	D_ASSOC("Restoring all known stations ... start.\n");
 	spin_lock_irqsave(&il->sta_lock, flags_spin);
 	for (i = 0; i < il->hw_params.max_stations; i++) {
-		if (ctx->ctxid != il->stations[i].ctxid)
-			continue;
 		if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) &&
 		    !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) {
 			D_ASSOC("Restoring sta %pM\n",
@@ -2273,7 +2257,7 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
 			 * current LQ command
 			 */
 			if (send_lq)
-				il_send_lq_cmd(il, ctx, &lq, CMD_SYNC, true);
+				il_send_lq_cmd(il, &lq, CMD_SYNC, true);
 			spin_lock_irqsave(&il->sta_lock, flags_spin);
 			il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS;
 		}
@@ -2353,15 +2337,14 @@ il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq)
  * RXON flags are updated and when LQ command is updated.
  */
 static bool
-il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx,
-		     struct il_link_quality_cmd *lq)
+il_is_lq_table_valid(struct il_priv *il, struct il_link_quality_cmd *lq)
 {
 	int i;
 
-	if (ctx->ht.enabled)
+	if (il->ht.enabled)
 		return true;
 
-	D_INFO("Channel %u is not an HT channel\n", ctx->active.channel);
+	D_INFO("Channel %u is not an HT channel\n", il->active.channel);
 	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
 		if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
 			D_INFO("idx %d of LQ expects HT channel\n", i);
@@ -2382,8 +2365,8 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx,
  * progress.
  */
 int
-il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
-	       struct il_link_quality_cmd *lq, u8 flags, bool init)
+il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq,
+	       u8 flags, bool init)
 {
 	int ret = 0;
 	unsigned long flags_spin;
@@ -2408,7 +2391,7 @@ il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
 	il_dump_lq_cmd(il, lq);
 	BUG_ON(init && (cmd.flags & CMD_ASYNC));
 
-	if (il_is_lq_table_valid(il, ctx, lq))
+	if (il_is_lq_table_valid(il, lq))
 		ret = il_send_cmd(il, &cmd);
 	else
 		ret = -EINVAL;
@@ -2648,7 +2631,7 @@ il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr,
 	 * All contexts have the same setting here due to it being
 	 * a module parameter, so OK to check any context.
 	 */
-	if (il->ctx.active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+	if (il->active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
 		return 0;
 
 	if (!(fc & IEEE80211_FCTL_PROTECTED))
@@ -2739,7 +2722,7 @@ il_tx_queue_unmap(struct il_priv *il, int txq_id)
 		return;
 
 	while (q->write_ptr != q->read_ptr) {
-		il->cfg->ops->lib->txq_free_tfd(il, txq);
+		il->ops->lib->txq_free_tfd(il, txq);
 		q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd);
 	}
 }
@@ -2772,8 +2755,8 @@ il_tx_queue_free(struct il_priv *il, int txq_id)
 				  txq->tfds, txq->q.dma_addr);
 
 	/* De-alloc array of per-TFD driver data */
-	kfree(txq->txb);
-	txq->txb = NULL;
+	kfree(txq->skbs);
+	txq->skbs = NULL;
 
 	/* deallocate arrays */
 	kfree(txq->cmd);
@@ -2947,23 +2930,21 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
 	/* Driver ilate data, only for Tx (not command) queues,
 	 * not shared with device. */
 	if (id != il->cmd_queue) {
-		txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]),
-				   GFP_KERNEL);
-		if (!txq->txb) {
-			IL_ERR("kmalloc for auxiliary BD "
-			       "structures failed\n");
+		txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(struct skb *),
+				    GFP_KERNEL);
+		if (!txq->skbs) {
+			IL_ERR("Fail to alloc skbs\n");
 			goto error;
 		}
-	} else {
-		txq->txb = NULL;
-	}
+	} else
+		txq->skbs = NULL;
 
 	/* Circular buffer of transmit frame descriptors (TFDs),
 	 * shared with device */
 	txq->tfds =
 	    dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL);
 	if (!txq->tfds) {
-		IL_ERR("pci_alloc_consistent(%zd) failed\n", tfd_sz);
+		IL_ERR("Fail to alloc TFDs\n");
 		goto error;
 	}
 	txq->q.id = id;
@@ -2971,8 +2952,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
 	return 0;
 
 error:
-	kfree(txq->txb);
-	txq->txb = NULL;
+	kfree(txq->skbs);
+	txq->skbs = NULL;
 
 	return -ENOMEM;
 }
@@ -3041,7 +3022,7 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
 	il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
 
 	/* Tell device where to find queue */
-	il->cfg->ops->lib->txq_init(il, txq);
+	il->ops->lib->txq_init(il, txq);
 
 	return 0;
 err:
@@ -3072,7 +3053,7 @@ il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
 	il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
 
 	/* Tell device where to find queue */
-	il->cfg->ops->lib->txq_init(il, txq);
+	il->ops->lib->txq_init(il, txq);
 }
 EXPORT_SYMBOL(il_tx_queue_reset);
 
@@ -3100,7 +3081,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
 	u32 idx;
 	u16 fix_size;
 
-	cmd->len = il->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
+	cmd->len = il->ops->utils->get_hcmd_size(cmd->id, cmd->len);
 	fix_size = (u16) (cmd->len + sizeof(out_cmd->hdr));
 
 	/* If any of the command structures end up being larger than
@@ -3179,9 +3160,9 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
 #endif
 	txq->need_update = 1;
 
-	if (il->cfg->ops->lib->txq_update_byte_cnt_tbl)
+	if (il->ops->lib->txq_update_byte_cnt_tbl)
 		/* Set up entry in queue's byte count circular buffer */
-		il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0);
+		il->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0);
 
 	phys_addr =
 	    pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size,
@@ -3189,8 +3170,8 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
 	dma_unmap_addr_set(out_meta, mapping, phys_addr);
 	dma_unmap_len_set(out_meta, len, fix_size);
 
-	il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size,
-						 1, U32_PAD(cmd->len));
+	il->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1,
+					    U32_PAD(cmd->len));
 
 	/* Increment and update queue's write idx */
 	q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -3332,30 +3313,6 @@ EXPORT_SYMBOL(il_debug_level);
 const u8 il_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 EXPORT_SYMBOL(il_bcast_addr);
 
-/* This function both allocates and initializes hw and il. */
-struct ieee80211_hw *
-il_alloc_all(struct il_cfg *cfg)
-{
-	struct il_priv *il;
-	/* mac80211 allocates memory for this device instance, including
-	 *   space for this driver's ilate structure */
-	struct ieee80211_hw *hw;
-
-	hw = ieee80211_alloc_hw(sizeof(struct il_priv),
-				cfg->ops->ieee80211_ops);
-	if (hw == NULL) {
-		pr_err("%s: Can not allocate network device\n", cfg->name);
-		goto out;
-	}
-
-	il = hw->priv;
-	il->hw = hw;
-
-out:
-	return hw;
-}
-EXPORT_SYMBOL(il_alloc_all);
-
 #define MAX_BIT_RATE_40_MHZ 150	/* Mbps */
 #define MAX_BIT_RATE_20_MHZ 72	/* Mbps */
 static void
@@ -3562,10 +3519,9 @@ il_is_channel_extension(struct il_priv *il, enum ieee80211_band band,
 }
 
 bool
-il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
-		      struct ieee80211_sta_ht_cap *ht_cap)
+il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap)
 {
-	if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
+	if (!il->ht.enabled || !il->ht.is_40mhz)
 		return false;
 
 	/*
@@ -3581,8 +3537,8 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
 #endif
 
 	return il_is_channel_extension(il, il->band,
-				       le16_to_cpu(ctx->staging.channel),
-				       ctx->ht.extension_chan_offset);
+				       le16_to_cpu(il->staging.channel),
+				       il->ht.extension_chan_offset);
 }
 EXPORT_SYMBOL(il_is_ht40_tx_allowed);
 
@@ -3621,22 +3577,22 @@ il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
 }
 
 int
-il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx)
+il_send_rxon_timing(struct il_priv *il)
 {
 	u64 tsf;
 	s32 interval_tm, rem;
 	struct ieee80211_conf *conf = NULL;
 	u16 beacon_int;
-	struct ieee80211_vif *vif = ctx->vif;
+	struct ieee80211_vif *vif = il->vif;
 
 	conf = &il->hw->conf;
 
 	lockdep_assert_held(&il->mutex);
 
-	memset(&ctx->timing, 0, sizeof(struct il_rxon_time_cmd));
+	memset(&il->timing, 0, sizeof(struct il_rxon_time_cmd));
 
-	ctx->timing.timestamp = cpu_to_le64(il->timestamp);
-	ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
+	il->timing.timestamp = cpu_to_le64(il->timestamp);
+	il->timing.listen_interval = cpu_to_le16(conf->listen_interval);
 
 	beacon_int = vif ? vif->bss_conf.beacon_int : 0;
 
@@ -3644,36 +3600,35 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx)
 	 * TODO: For IBSS we need to get atim_win from mac80211,
 	 *       for now just always use 0
 	 */
-	ctx->timing.atim_win = 0;
+	il->timing.atim_win = 0;
 
 	beacon_int =
 	    il_adjust_beacon_interval(beacon_int,
 				      il->hw_params.max_beacon_itrvl *
 				      TIME_UNIT);
-	ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
+	il->timing.beacon_interval = cpu_to_le16(beacon_int);
 
 	tsf = il->timestamp;	/* tsf is modifed by do_div: copy it */
 	interval_tm = beacon_int * TIME_UNIT;
 	rem = do_div(tsf, interval_tm);
-	ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+	il->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
 
-	ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1;
+	il->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1;
 
 	D_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
-		le16_to_cpu(ctx->timing.beacon_interval),
-		le32_to_cpu(ctx->timing.beacon_init_val),
-		le16_to_cpu(ctx->timing.atim_win));
+		le16_to_cpu(il->timing.beacon_interval),
+		le32_to_cpu(il->timing.beacon_init_val),
+		le16_to_cpu(il->timing.atim_win));
 
-	return il_send_cmd_pdu(il, ctx->rxon_timing_cmd, sizeof(ctx->timing),
-			       &ctx->timing);
+	return il_send_cmd_pdu(il, C_RXON_TIMING, sizeof(il->timing),
+			       &il->timing);
 }
 EXPORT_SYMBOL(il_send_rxon_timing);
 
 void
-il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx,
-		     int hw_decrypt)
+il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt)
 {
-	struct il_rxon_cmd *rxon = &ctx->staging;
+	struct il_rxon_cmd *rxon = &il->staging;
 
 	if (hw_decrypt)
 		rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -3685,9 +3640,9 @@ EXPORT_SYMBOL(il_set_rxon_hwcrypto);
 
 /* validate RXON structure is valid */
 int
-il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_check_rxon_cmd(struct il_priv *il)
 {
-	struct il_rxon_cmd *rxon = &ctx->staging;
+	struct il_rxon_cmd *rxon = &il->staging;
 	bool error = false;
 
 	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
@@ -3765,10 +3720,10 @@ EXPORT_SYMBOL(il_check_rxon_cmd);
  * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  */
 int
-il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
+il_full_rxon_required(struct il_priv *il)
 {
-	const struct il_rxon_cmd *staging = &ctx->staging;
-	const struct il_rxon_cmd *active = &ctx->active;
+	const struct il_rxon_cmd *staging = &il->staging;
+	const struct il_rxon_cmd *active = &il->active;
 
 #define CHK(cond)							\
 	if ((cond)) {							\
@@ -3785,7 +3740,7 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
 	}
 
 	/* These items are only settable from the full RXON command */
-	CHK(!il_is_associated_ctx(ctx));
+	CHK(!il_is_associated(il));
 	CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
 	CHK(compare_ether_addr(staging->node_addr, active->node_addr));
 	CHK(compare_ether_addr
@@ -3819,13 +3774,13 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
 EXPORT_SYMBOL(il_full_rxon_required);
 
 u8
-il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx)
+il_get_lowest_plcp(struct il_priv *il)
 {
 	/*
 	 * Assign the lowest rate -- should really get this from
 	 * the beacon skb from mac80211.
 	 */
-	if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
+	if (il->staging.flags & RXON_FLG_BAND_24G_MSK)
 		return RATE_1M_PLCP;
 	else
 		return RATE_6M_PLCP;
@@ -3833,12 +3788,11 @@ il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx)
 EXPORT_SYMBOL(il_get_lowest_plcp);
 
 static void
-_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
-		struct il_rxon_context *ctx)
+_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf)
 {
-	struct il_rxon_cmd *rxon = &ctx->staging;
+	struct il_rxon_cmd *rxon = &il->staging;
 
-	if (!ctx->ht.enabled) {
+	if (!il->ht.enabled) {
 		rxon->flags &=
 		    ~(RXON_FLG_CHANNEL_MODE_MSK |
 		      RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK
@@ -3847,19 +3801,19 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
 	}
 
 	rxon->flags |=
-	    cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
+	    cpu_to_le32(il->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
 
 	/* Set up channel bandwidth:
 	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
 	/* clear the HT channel mode before set the mode */
 	rxon->flags &=
 	    ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
-	if (il_is_ht40_tx_allowed(il, ctx, NULL)) {
+	if (il_is_ht40_tx_allowed(il, NULL)) {
 		/* pure ht40 */
-		if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
+		if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
 			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
 			/* Note: control channel is opposite of extension channel */
-			switch (ctx->ht.extension_chan_offset) {
+			switch (il->ht.extension_chan_offset) {
 			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
 				rxon->flags &=
 				    ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
@@ -3870,7 +3824,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
 			}
 		} else {
 			/* Note: control channel is opposite of extension channel */
-			switch (ctx->ht.extension_chan_offset) {
+			switch (il->ht.extension_chan_offset) {
 			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
 				rxon->flags &=
 				    ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
@@ -3891,18 +3845,18 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
 		rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
 	}
 
-	if (il->cfg->ops->hcmd->set_rxon_chain)
-		il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+	if (il->ops->hcmd->set_rxon_chain)
+		il->ops->hcmd->set_rxon_chain(il);
 
 	D_ASSOC("rxon flags 0x%X operation mode :0x%X "
 		"extension channel offset 0x%x\n", le32_to_cpu(rxon->flags),
-		ctx->ht.protection, ctx->ht.extension_chan_offset);
+		il->ht.protection, il->ht.extension_chan_offset);
 }
 
 void
 il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf)
 {
-	_il_set_rxon_ht(il, ht_conf, &il->ctx);
+	_il_set_rxon_ht(il, ht_conf);
 }
 EXPORT_SYMBOL(il_set_rxon_ht);
 
@@ -3925,7 +3879,7 @@ il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band)
 
 	for (i = min; i < max; i++) {
 		channel = il->channel_info[i].channel;
-		if (channel == le16_to_cpu(il->ctx.staging.channel))
+		if (channel == le16_to_cpu(il->staging.channel))
 			continue;
 
 		ch_info = il_get_channel_info(il, band, channel);
@@ -3945,20 +3899,19 @@ EXPORT_SYMBOL(il_get_single_channel_number);
  * in the staging RXON flag structure based on the ch->band
  */
 int
-il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
-		    struct il_rxon_context *ctx)
+il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch)
 {
 	enum ieee80211_band band = ch->band;
 	u16 channel = ch->hw_value;
 
-	if (le16_to_cpu(ctx->staging.channel) == channel && il->band == band)
+	if (le16_to_cpu(il->staging.channel) == channel && il->band == band)
 		return 0;
 
-	ctx->staging.channel = cpu_to_le16(channel);
+	il->staging.channel = cpu_to_le16(channel);
 	if (band == IEEE80211_BAND_5GHZ)
-		ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
+		il->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
 	else
-		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
+		il->staging.flags |= RXON_FLG_BAND_24G_MSK;
 
 	il->band = band;
 
@@ -3969,24 +3922,24 @@ il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
 EXPORT_SYMBOL(il_set_rxon_channel);
 
 void
-il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx,
-		      enum ieee80211_band band, struct ieee80211_vif *vif)
+il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band,
+		      struct ieee80211_vif *vif)
 {
 	if (band == IEEE80211_BAND_5GHZ) {
-		ctx->staging.flags &=
+		il->staging.flags &=
 		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
 		      RXON_FLG_CCK_MSK);
-		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+		il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 	} else {
 		/* Copied from il_post_associate() */
 		if (vif && vif->bss_conf.use_short_slot)
-			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+			il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+			il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
-		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
-		ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
-		ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
+		il->staging.flags |= RXON_FLG_BAND_24G_MSK;
+		il->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
+		il->staging.flags &= ~RXON_FLG_CCK_MSK;
 	}
 }
 EXPORT_SYMBOL(il_set_flags_for_band);
@@ -3995,69 +3948,60 @@ EXPORT_SYMBOL(il_set_flags_for_band);
  * initialize rxon structure with default values from eeprom
  */
 void
-il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx)
+il_connection_init_rx_config(struct il_priv *il)
 {
 	const struct il_channel_info *ch_info;
 
-	memset(&ctx->staging, 0, sizeof(ctx->staging));
-
-	if (!ctx->vif) {
-		ctx->staging.dev_type = ctx->unused_devtype;
-	} else
-		switch (ctx->vif->type) {
-
-		case NL80211_IFTYPE_STATION:
-			ctx->staging.dev_type = ctx->station_devtype;
-			ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
-			break;
-
-		case NL80211_IFTYPE_ADHOC:
-			ctx->staging.dev_type = ctx->ibss_devtype;
-			ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
-			ctx->staging.filter_flags =
-			    RXON_FILTER_BCON_AWARE_MSK |
-			    RXON_FILTER_ACCEPT_GRP_MSK;
-			break;
-
-		default:
-			IL_ERR("Unsupported interface type %d\n",
-			       ctx->vif->type);
-			break;
-		}
+	memset(&il->staging, 0, sizeof(il->staging));
+
+	if (!il->vif) {
+		il->staging.dev_type = RXON_DEV_TYPE_ESS;
+	} else if (il->vif->type == NL80211_IFTYPE_STATION) {
+		il->staging.dev_type = RXON_DEV_TYPE_ESS;
+		il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+	} else if (il->vif->type == NL80211_IFTYPE_ADHOC) {
+		il->staging.dev_type = RXON_DEV_TYPE_IBSS;
+		il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+		il->staging.filter_flags =
+		    RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
+	} else {
+		IL_ERR("Unsupported interface type %d\n", il->vif->type);
+		return;
+	}
 
 #if 0
 	/* TODO:  Figure out when short_preamble would be set and cache from
 	 * that */
 	if (!hw_to_local(il->hw)->short_preamble)
-		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+		il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 	else
-		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+		il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 #endif
 
 	ch_info =
-	    il_get_channel_info(il, il->band, le16_to_cpu(ctx->active.channel));
+	    il_get_channel_info(il, il->band, le16_to_cpu(il->active.channel));
 
 	if (!ch_info)
 		ch_info = &il->channel_info[0];
 
-	ctx->staging.channel = cpu_to_le16(ch_info->channel);
+	il->staging.channel = cpu_to_le16(ch_info->channel);
 	il->band = ch_info->band;
 
-	il_set_flags_for_band(il, ctx, il->band, ctx->vif);
+	il_set_flags_for_band(il, il->band, il->vif);
 
-	ctx->staging.ofdm_basic_rates =
+	il->staging.ofdm_basic_rates =
 	    (IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;
-	ctx->staging.cck_basic_rates =
+	il->staging.cck_basic_rates =
 	    (IL_CCK_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF;
 
 	/* clear both MIX and PURE40 mode flag */
-	ctx->staging.flags &=
+	il->staging.flags &=
 	    ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40);
-	if (ctx->vif)
-		memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
+	if (il->vif)
+		memcpy(il->staging.node_addr, il->vif->addr, ETH_ALEN);
 
-	ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
-	ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
+	il->staging.ofdm_ht_single_stream_basic_rates = 0xff;
+	il->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
 }
 EXPORT_SYMBOL(il_connection_init_rx_config);
 
@@ -4084,10 +4028,10 @@ il_set_rate(struct il_priv *il)
 
 	D_RATE("Set active_rate = %0x\n", il->active_rate);
 
-	il->ctx.staging.cck_basic_rates =
+	il->staging.cck_basic_rates =
 	    (IL_CCK_BASIC_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF;
 
-	il->ctx.staging.ofdm_basic_rates =
+	il->staging.ofdm_basic_rates =
 	    (IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;
 }
 EXPORT_SYMBOL(il_set_rate);
@@ -4095,13 +4039,11 @@ EXPORT_SYMBOL(il_set_rate);
 void
 il_chswitch_done(struct il_priv *il, bool is_success)
 {
-	struct il_rxon_context *ctx = &il->ctx;
-
 	if (test_bit(S_EXIT_PENDING, &il->status))
 		return;
 
 	if (test_and_clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
-		ieee80211_chswitch_done(ctx->vif, is_success);
+		ieee80211_chswitch_done(il->vif, is_success);
 }
 EXPORT_SYMBOL(il_chswitch_done);
 
@@ -4110,16 +4052,14 @@ il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb)
 {
 	struct il_rx_pkt *pkt = rxb_addr(rxb);
 	struct il_csa_notification *csa = &(pkt->u.csa_notif);
-
-	struct il_rxon_context *ctx = &il->ctx;
-	struct il_rxon_cmd *rxon = (void *)&ctx->active;
+	struct il_rxon_cmd *rxon = (void *)&il->active;
 
 	if (!test_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
 		return;
 
 	if (!le32_to_cpu(csa->status) && csa->channel == il->switch_channel) {
 		rxon->channel = csa->channel;
-		ctx->staging.channel = csa->channel;
+		il->staging.channel = csa->channel;
 		D_11H("CSA notif: channel %d\n", le16_to_cpu(csa->channel));
 		il_chswitch_done(il, true);
 	} else {
@@ -4132,9 +4072,9 @@ EXPORT_SYMBOL(il_hdl_csa);
 
 #ifdef CONFIG_IWLEGACY_DEBUG
 void
-il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_print_rx_config_cmd(struct il_priv *il)
 {
-	struct il_rxon_cmd *rxon = &ctx->staging;
+	struct il_rxon_cmd *rxon = &il->staging;
 
 	D_RADIO("RX CONFIG:\n");
 	il_print_hex_dump(il, IL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -4164,12 +4104,12 @@ il_irq_handle_error(struct il_priv *il)
 
 	IL_ERR("Loaded firmware version: %s\n", il->hw->wiphy->fw_version);
 
-	il->cfg->ops->lib->dump_nic_error_log(il);
-	if (il->cfg->ops->lib->dump_fh)
-		il->cfg->ops->lib->dump_fh(il, NULL, false);
+	il->ops->lib->dump_nic_error_log(il);
+	if (il->ops->lib->dump_fh)
+		il->ops->lib->dump_fh(il, NULL, false);
 #ifdef CONFIG_IWLEGACY_DEBUG
 	if (il_get_debug_level(il) & IL_DL_FW_ERRORS)
-		il_print_rx_config_cmd(il, &il->ctx);
+		il_print_rx_config_cmd(il);
 #endif
 
 	wake_up(&il->wait_command_queue);
@@ -4276,7 +4216,7 @@ il_apm_init(struct il_priv *il)
 	 * If not (unlikely), enable L0S, so there is at least some
 	 *    power savings, even without L1.
 	 */
-	if (il->cfg->base_params->set_l0s) {
+	if (il->cfg->set_l0s) {
 		lctl = il_pcie_link_ctl(il);
 		if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
 		    PCI_CFG_LINK_CTRL_VAL_L1_EN) {
@@ -4293,9 +4233,9 @@ il_apm_init(struct il_priv *il)
 	}
 
 	/* Configure analog phase-lock-loop before activating to D0A */
-	if (il->cfg->base_params->pll_cfg_val)
+	if (il->cfg->pll_cfg_val)
 		il_set_bit(il, CSR_ANA_PLL_CFG,
-			   il->cfg->base_params->pll_cfg_val);
+			   il->cfg->pll_cfg_val);
 
 	/*
 	 * Set "initialization complete" bit to move adapter from
@@ -4325,7 +4265,7 @@ il_apm_init(struct il_priv *il)
 	 * do not disable clocks.  This preserves any hardware bits already
 	 * set by default in "CLK_CTRL_REG" after reset.
 	 */
-	if (il->cfg->base_params->use_bsm)
+	if (il->cfg->use_bsm)
 		il_wr_prph(il, APMG_CLK_EN_REG,
 			   APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
 	else
@@ -4347,14 +4287,13 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
 	int ret;
 	s8 prev_tx_power;
 	bool defer;
-	struct il_rxon_context *ctx = &il->ctx;
 
 	lockdep_assert_held(&il->mutex);
 
 	if (il->tx_power_user_lmt == tx_power && !force)
 		return 0;
 
-	if (!il->cfg->ops->lib->send_tx_power)
+	if (!il->ops->lib->send_tx_power)
 		return -EOPNOTSUPP;
 
 	/* 0 dBm mean 1 milliwatt */
@@ -4378,7 +4317,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
 
 	/* do not set tx power when scanning or channel changing */
 	defer = test_bit(S_SCANNING, &il->status) ||
-	    memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
+	    memcmp(&il->active, &il->staging, sizeof(il->staging));
 	if (defer && !force) {
 		D_INFO("Deferring tx power set\n");
 		return 0;
@@ -4387,7 +4326,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
 	prev_tx_power = il->tx_power_user_lmt;
 	il->tx_power_user_lmt = tx_power;
 
-	ret = il->cfg->ops->lib->send_tx_power(il);
+	ret = il->ops->lib->send_tx_power(il);
 
 	/* if fail to set tx_power, restore the orig. tx power */
 	if (ret) {
@@ -4505,15 +4444,15 @@ il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
 
 	spin_lock_irqsave(&il->lock, flags);
 
-	il->ctx.qos_data.def_qos_parm.ac[q].cw_min =
+	il->qos_data.def_qos_parm.ac[q].cw_min =
 	    cpu_to_le16(params->cw_min);
-	il->ctx.qos_data.def_qos_parm.ac[q].cw_max =
+	il->qos_data.def_qos_parm.ac[q].cw_max =
 	    cpu_to_le16(params->cw_max);
-	il->ctx.qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
-	il->ctx.qos_data.def_qos_parm.ac[q].edca_txop =
+	il->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+	il->qos_data.def_qos_parm.ac[q].edca_txop =
 	    cpu_to_le16((params->txop * 32));
 
-	il->ctx.qos_data.def_qos_parm.ac[q].reserved1 = 0;
+	il->qos_data.def_qos_parm.ac[q].reserved1 = 0;
 
 	spin_unlock_irqrestore(&il->lock, flags);
 
@@ -4532,50 +4471,21 @@ il_mac_tx_last_beacon(struct ieee80211_hw *hw)
 EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon);
 
 static int
-il_set_mode(struct il_priv *il, struct il_rxon_context *ctx)
-{
-	il_connection_init_rx_config(il, ctx);
-
-	if (il->cfg->ops->hcmd->set_rxon_chain)
-		il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
-
-	return il_commit_rxon(il, ctx);
-}
-
-static int
-il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx)
+il_set_mode(struct il_priv *il)
 {
-	struct ieee80211_vif *vif = ctx->vif;
-	int err;
-
-	lockdep_assert_held(&il->mutex);
-
-	/*
-	 * This variable will be correct only when there's just
-	 * a single context, but all code using it is for hardware
-	 * that supports only one context.
-	 */
-	il->iw_mode = vif->type;
+	il_connection_init_rx_config(il);
 
-	ctx->is_active = true;
+	if (il->ops->hcmd->set_rxon_chain)
+		il->ops->hcmd->set_rxon_chain(il);
 
-	err = il_set_mode(il, ctx);
-	if (err) {
-		if (!ctx->always_active)
-			ctx->is_active = false;
-		return err;
-	}
-
-	return 0;
+	return il_commit_rxon(il);
 }
 
 int
 il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 	struct il_priv *il = hw->priv;
-	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
 	int err;
-	u32 modes;
 
 	D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
 
@@ -4587,25 +4497,17 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 		goto out;
 	}
 
-	/* check if busy context is exclusive */
-	if (il->ctx.vif &&
-	    (il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type))) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	modes = il->ctx.interface_modes | il->ctx.exclusive_interface_modes;
-	if (!(modes & BIT(vif->type))) {
+	if (il->vif) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	vif_priv->ctx = &il->ctx;
-	il->ctx.vif = vif;
+	il->vif = vif;
+	il->iw_mode = vif->type;
 
-	err = il_setup_interface(il, &il->ctx);
+	err = il_set_mode(il);
 	if (err) {
-		il->ctx.vif = NULL;
+		il->vif = NULL;
 		il->iw_mode = NL80211_IFTYPE_STATION;
 	}
 
@@ -4621,8 +4523,6 @@ static void
 il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
 		      bool mode_change)
 {
-	struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
 	lockdep_assert_held(&il->mutex);
 
 	if (il->scan_vif == vif) {
@@ -4630,25 +4530,22 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
 		il_force_scan_end(il);
 	}
 
-	if (!mode_change) {
-		il_set_mode(il, ctx);
-		if (!ctx->always_active)
-			ctx->is_active = false;
-	}
+	if (!mode_change)
+		il_set_mode(il);
+
 }
 
 void
 il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 	struct il_priv *il = hw->priv;
-	struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
 
 	D_MAC80211("enter\n");
 
 	mutex_lock(&il->mutex);
 
-	WARN_ON(ctx->vif != vif);
-	ctx->vif = NULL;
+	WARN_ON(il->vif != vif);
+	il->vif = NULL;
 
 	il_teardown_interface(il, vif, false);
 
@@ -4666,7 +4563,7 @@ il_alloc_txq_mem(struct il_priv *il)
 	if (!il->txq)
 		il->txq =
 		    kzalloc(sizeof(struct il_tx_queue) *
-			    il->cfg->base_params->num_of_queues, GFP_KERNEL);
+			    il->cfg->num_of_queues, GFP_KERNEL);
 	if (!il->txq) {
 		IL_ERR("Not enough memory for txq\n");
 		return -ENOMEM;
@@ -4987,15 +4884,14 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			enum nl80211_iftype newtype, bool newp2p)
 {
 	struct il_priv *il = hw->priv;
-	struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-	u32 modes;
 	int err;
 
-	newtype = ieee80211_iftype_p2p(newtype, newp2p);
+	if (newp2p)
+		return -EOPNOTSUPP;
 
 	mutex_lock(&il->mutex);
 
-	if (!ctx->vif || !il_is_ready_rf(il)) {
+	if (!il->vif || !il_is_ready_rf(il)) {
 		/*
 		 * Huh? But wait ... this can maybe happen when
 		 * we're in the middle of a firmware restart!
@@ -5004,23 +4900,11 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		goto out;
 	}
 
-	modes = ctx->interface_modes | ctx->exclusive_interface_modes;
-	if (!(modes & BIT(newtype))) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	if ((il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type)) ||
-	    (il->ctx.exclusive_interface_modes & BIT(newtype))) {
-		err = -EINVAL;
-		goto out;
-	}
-
 	/* success */
 	il_teardown_interface(il, vif, true);
 	vif->type = newtype;
-	vif->p2p = newp2p;
-	err = il_setup_interface(il, ctx);
+	vif->p2p = false;
+	err = il_set_mode(il);
 	WARN_ON(err);
 	/*
 	 * We've switched internally, but submitting to the
@@ -5056,11 +4940,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
 
 	timeout =
 	    txq->time_stamp +
-	    msecs_to_jiffies(il->cfg->base_params->wd_timeout);
+	    msecs_to_jiffies(il->cfg->wd_timeout);
 
 	if (time_after(jiffies, timeout)) {
 		IL_ERR("Queue %d stuck for %u ms.\n", q->id,
-		       il->cfg->base_params->wd_timeout);
+		       il->cfg->wd_timeout);
 		ret = il_force_reset(il, false);
 		return (ret == -EAGAIN) ? 0 : 1;
 	}
@@ -5088,7 +4972,7 @@ il_bg_watchdog(unsigned long data)
 	if (test_bit(S_EXIT_PENDING, &il->status))
 		return;
 
-	timeout = il->cfg->base_params->wd_timeout;
+	timeout = il->cfg->wd_timeout;
 	if (timeout == 0)
 		return;
 
@@ -5115,7 +4999,7 @@ EXPORT_SYMBOL(il_bg_watchdog);
 void
 il_setup_watchdog(struct il_priv *il)
 {
-	unsigned int timeout = il->cfg->base_params->wd_timeout;
+	unsigned int timeout = il->cfg->wd_timeout;
 
 	if (timeout)
 		mod_timer(&il->watchdog,
@@ -5252,28 +5136,25 @@ EXPORT_SYMBOL(il_pm_ops);
 #endif /* CONFIG_PM */
 
 static void
-il_update_qos(struct il_priv *il, struct il_rxon_context *ctx)
+il_update_qos(struct il_priv *il)
 {
 	if (test_bit(S_EXIT_PENDING, &il->status))
 		return;
 
-	if (!ctx->is_active)
-		return;
+	il->qos_data.def_qos_parm.qos_flags = 0;
 
-	ctx->qos_data.def_qos_parm.qos_flags = 0;
-
-	if (ctx->qos_data.qos_active)
-		ctx->qos_data.def_qos_parm.qos_flags |=
+	if (il->qos_data.qos_active)
+		il->qos_data.def_qos_parm.qos_flags |=
 		    QOS_PARAM_FLG_UPDATE_EDCA_MSK;
 
-	if (ctx->ht.enabled)
-		ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+	if (il->ht.enabled)
+		il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
 
 	D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
-	      ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags);
+	      il->qos_data.qos_active, il->qos_data.def_qos_parm.qos_flags);
 
-	il_send_cmd_pdu_async(il, ctx->qos_cmd, sizeof(struct il_qosparam_cmd),
-			      &ctx->qos_data.def_qos_parm, NULL);
+	il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd),
+			      &il->qos_data.def_qos_parm, NULL);
 }
 
 /**
@@ -5287,14 +5168,13 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ieee80211_channel *channel = conf->channel;
 	struct il_ht_config *ht_conf = &il->current_ht_config;
-	struct il_rxon_context *ctx = &il->ctx;
 	unsigned long flags = 0;
 	int ret = 0;
 	u16 ch;
 	int scan_active = 0;
 	bool ht_changed = false;
 
-	if (WARN_ON(!il->cfg->ops->legacy))
+	if (WARN_ON(!il->ops->legacy))
 		return -EOPNOTSUPP;
 
 	mutex_lock(&il->mutex);
@@ -5319,8 +5199,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
 		 * set up the SM PS mode to OFF if an HT channel is
 		 * configured.
 		 */
-		if (il->cfg->ops->hcmd->set_rxon_chain)
-			il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
+		if (il->ops->hcmd->set_rxon_chain)
+			il->ops->hcmd->set_rxon_chain(il);
 	}
 
 	/* during scanning mac80211 will delay channel setting until
@@ -5349,48 +5229,48 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
 		spin_lock_irqsave(&il->lock, flags);
 
 		/* Configure HT40 channels */
-		if (ctx->ht.enabled != conf_is_ht(conf)) {
-			ctx->ht.enabled = conf_is_ht(conf);
+		if (il->ht.enabled != conf_is_ht(conf)) {
+			il->ht.enabled = conf_is_ht(conf);
 			ht_changed = true;
 		}
-		if (ctx->ht.enabled) {
+		if (il->ht.enabled) {
 			if (conf_is_ht40_minus(conf)) {
-				ctx->ht.extension_chan_offset =
+				il->ht.extension_chan_offset =
 				    IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-				ctx->ht.is_40mhz = true;
+				il->ht.is_40mhz = true;
 			} else if (conf_is_ht40_plus(conf)) {
-				ctx->ht.extension_chan_offset =
+				il->ht.extension_chan_offset =
 				    IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-				ctx->ht.is_40mhz = true;
+				il->ht.is_40mhz = true;
 			} else {
-				ctx->ht.extension_chan_offset =
+				il->ht.extension_chan_offset =
 				    IEEE80211_HT_PARAM_CHA_SEC_NONE;
-				ctx->ht.is_40mhz = false;
+				il->ht.is_40mhz = false;
 			}
 		} else
-			ctx->ht.is_40mhz = false;
+			il->ht.is_40mhz = false;
 
 		/*
 		 * Default to no protection. Protection mode will
 		 * later be set from BSS config in il_ht_conf
 		 */
-		ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+		il->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
 
 		/* if we are switching from ht to 2.4 clear flags
 		 * from any ht related info since 2.4 does not
 		 * support ht */
-		if ((le16_to_cpu(ctx->staging.channel) != ch))
-			ctx->staging.flags = 0;
+		if ((le16_to_cpu(il->staging.channel) != ch))
+			il->staging.flags = 0;
 
-		il_set_rxon_channel(il, channel, ctx);
+		il_set_rxon_channel(il, channel);
 		il_set_rxon_ht(il, ht_conf);
 
-		il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
+		il_set_flags_for_band(il, channel->band, il->vif);
 
 		spin_unlock_irqrestore(&il->lock, flags);
 
-		if (il->cfg->ops->legacy->update_bcast_stations)
-			ret = il->cfg->ops->legacy->update_bcast_stations(il);
+		if (il->ops->legacy->update_bcast_stations)
+			ret = il->ops->legacy->update_bcast_stations(il);
 
 set_ch_out:
 		/* The list of supported rates and rate mask can be different
@@ -5420,12 +5300,12 @@ set_ch_out:
 	if (scan_active)
 		goto out;
 
-	if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
-		il_commit_rxon(il, ctx);
+	if (memcmp(&il->active, &il->staging, sizeof(il->staging)))
+		il_commit_rxon(il);
 	else
 		D_INFO("Not re-sending same RXON configuration.\n");
 	if (ht_changed)
-		il_update_qos(il, ctx);
+		il_update_qos(il);
 
 out:
 	D_MAC80211("leave\n");
@@ -5439,9 +5319,8 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 	struct il_priv *il = hw->priv;
 	unsigned long flags;
-	struct il_rxon_context *ctx = &il->ctx;
 
-	if (WARN_ON(!il->cfg->ops->legacy))
+	if (WARN_ON(!il->ops->legacy))
 		return;
 
 	mutex_lock(&il->mutex);
@@ -5473,8 +5352,8 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	/* we are restarting association process
 	 * clear RXON_FILTER_ASSOC_MSK bit
 	 */
-	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	il_commit_rxon(il, ctx);
+	il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+	il_commit_rxon(il);
 
 	il_set_rate(il);
 
@@ -5490,16 +5369,15 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif)
 	struct il_ht_config *ht_conf = &il->current_ht_config;
 	struct ieee80211_sta *sta;
 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-	struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
 
 	D_ASSOC("enter:\n");
 
-	if (!ctx->ht.enabled)
+	if (!il->ht.enabled)
 		return;
 
-	ctx->ht.protection =
+	il->ht.protection =
 	    bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
-	ctx->ht.non_gf_sta_present =
+	il->ht.non_gf_sta_present =
 	    !!(bss_conf->
 	       ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 
@@ -5548,16 +5426,14 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif)
 static inline void
 il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif)
 {
-	struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
 	/*
 	 * inform the ucode that there is no longer an
 	 * association and that no more packets should be
 	 * sent
 	 */
-	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-	ctx->staging.assoc_id = 0;
-	il_commit_rxon(il, ctx);
+	il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+	il->staging.assoc_id = 0;
+	il_commit_rxon(il);
 }
 
 static void
@@ -5575,8 +5451,8 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
 	lockdep_assert_held(&il->mutex);
 
-	if (!il->beacon_ctx) {
-		IL_ERR("update beacon but no beacon context!\n");
+	if (!il->beacon_enabled) {
+		IL_ERR("update beacon with no beaconing enabled\n");
 		dev_kfree_skb(skb);
 		return;
 	}
@@ -5599,7 +5475,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 		return;
 	}
 
-	il->cfg->ops->legacy->post_associate(il);
+	il->ops->legacy->post_associate(il);
 }
 
 void
@@ -5607,10 +5483,9 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			struct ieee80211_bss_conf *bss_conf, u32 changes)
 {
 	struct il_priv *il = hw->priv;
-	struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
 	int ret;
 
-	if (WARN_ON(!il->cfg->ops->legacy))
+	if (WARN_ON(!il->ops->legacy))
 		return;
 
 	D_MAC80211("changes = 0x%X\n", changes);
@@ -5626,21 +5501,17 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		unsigned long flags;
 
 		spin_lock_irqsave(&il->lock, flags);
-		ctx->qos_data.qos_active = bss_conf->qos;
-		il_update_qos(il, ctx);
+		il->qos_data.qos_active = bss_conf->qos;
+		il_update_qos(il);
 		spin_unlock_irqrestore(&il->lock, flags);
 	}
 
 	if (changes & BSS_CHANGED_BEACON_ENABLED) {
-		/*
-		 * the add_interface code must make sure we only ever
-		 * have a single interface that could be beaconing at
-		 * any time.
-		 */
+		/* FIXME: can we remove beacon_enabled ? */
 		if (vif->bss_conf.enable_beacon)
-			il->beacon_ctx = ctx;
+			il->beacon_enabled = true;
 		else
-			il->beacon_ctx = NULL;
+			il->beacon_enabled = false;
 	}
 
 	if (changes & BSS_CHANGED_BSSID) {
@@ -5660,13 +5531,13 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 		/* mac80211 only sets assoc when in STATION mode */
 		if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
-			memcpy(ctx->staging.bssid_addr, bss_conf->bssid,
+			memcpy(il->staging.bssid_addr, bss_conf->bssid,
 			       ETH_ALEN);
 
 			/* currently needed in a few places */
 			memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
 		} else {
-			ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+			il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		}
 
 	}
@@ -5682,21 +5553,21 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
 		D_MAC80211("ERP_PREAMBLE %d\n", bss_conf->use_short_preamble);
 		if (bss_conf->use_short_preamble)
-			ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+			il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+			il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
 	}
 
 	if (changes & BSS_CHANGED_ERP_CTS_PROT) {
 		D_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
 		if (bss_conf->use_cts_prot && il->band != IEEE80211_BAND_5GHZ)
-			ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+			il->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
 		else
-			ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+			il->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
 		if (bss_conf->use_cts_prot)
-			ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+			il->staging.flags |= RXON_FLG_SELF_CTS_EN;
 		else
-			ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+			il->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
 	}
 
 	if (changes & BSS_CHANGED_BASIC_RATES) {
@@ -5706,12 +5577,12 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		 * like this here:
 		 *
 		 if (A-band)
-		 ctx->staging.ofdm_basic_rates =
+		 il->staging.ofdm_basic_rates =
 		 bss_conf->basic_rates;
 		 else
-		 ctx->staging.ofdm_basic_rates =
+		 il->staging.ofdm_basic_rates =
 		 bss_conf->basic_rates >> 4;
-		 ctx->staging.cck_basic_rates =
+		 il->staging.cck_basic_rates =
 		 bss_conf->basic_rates & 0xF;
 		 */
 	}
@@ -5719,8 +5590,8 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	if (changes & BSS_CHANGED_HT) {
 		il_ht_conf(il, vif);
 
-		if (il->cfg->ops->hcmd->set_rxon_chain)
-			il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+		if (il->ops->hcmd->set_rxon_chain)
+			il->ops->hcmd->set_rxon_chain(il);
 	}
 
 	if (changes & BSS_CHANGED_ASSOC) {
@@ -5729,36 +5600,35 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			il->timestamp = bss_conf->timestamp;
 
 			if (!il_is_rfkill(il))
-				il->cfg->ops->legacy->post_associate(il);
+				il->ops->legacy->post_associate(il);
 		} else
 			il_set_no_assoc(il, vif);
 	}
 
-	if (changes && il_is_associated_ctx(ctx) && bss_conf->aid) {
+	if (changes && il_is_associated(il) && bss_conf->aid) {
 		D_MAC80211("Changes (%#x) while associated\n", changes);
-		ret = il_send_rxon_assoc(il, ctx);
+		ret = il_send_rxon_assoc(il);
 		if (!ret) {
 			/* Sync active_rxon with latest change. */
-			memcpy((void *)&ctx->active, &ctx->staging,
+			memcpy((void *)&il->active, &il->staging,
 			       sizeof(struct il_rxon_cmd));
 		}
 	}
 
 	if (changes & BSS_CHANGED_BEACON_ENABLED) {
 		if (vif->bss_conf.enable_beacon) {
-			memcpy(ctx->staging.bssid_addr, bss_conf->bssid,
+			memcpy(il->staging.bssid_addr, bss_conf->bssid,
 			       ETH_ALEN);
 			memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
-			il->cfg->ops->legacy->config_ap(il);
+			il->ops->legacy->config_ap(il);
 		} else
 			il_set_no_assoc(il, vif);
 	}
 
 	if (changes & BSS_CHANGED_IBSS) {
 		ret =
-		    il->cfg->ops->legacy->manage_ibss_station(il, vif,
-							      bss_conf->
-							      ibss_joined);
+		    il->ops->legacy->manage_ibss_station(il, vif,
+							 bss_conf->ibss_joined);
 		if (ret)
 			IL_ERR("failed to %s IBSS station %pM\n",
 			       bss_conf->ibss_joined ? "add" : "remove",
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index abfa388..7080956 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -143,12 +143,6 @@ struct il_queue {
 				 * space less than this */
 };
 
-/* One for each TFD */
-struct il_tx_info {
-	struct sk_buff *skb;
-	struct il_rxon_context *ctx;
-};
-
 /**
  * struct il_tx_queue - Tx Queue for DMA
  * @q: generic Rx/Tx queue descriptor
@@ -156,7 +150,7 @@ struct il_tx_info {
  * @cmd: array of command/TX buffer pointers
  * @meta: array of meta data for each command/tx buffer
  * @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
+ * @skbs: array of per-TFD socket buffer pointers
  * @time_stamp: time (in jiffies) of last read_ptr change
  * @need_update: indicates need to update read/write idx
  * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
@@ -172,7 +166,7 @@ struct il_tx_queue {
 	void *tfds;
 	struct il_device_cmd **cmd;
 	struct il_cmd_meta *meta;
-	struct il_tx_info *txb;
+	struct sk_buff **skbs;
 	unsigned long time_stamp;
 	u8 need_update;
 	u8 sched_retry;
@@ -735,13 +729,12 @@ struct il_qos_info {
 struct il_station_entry {
 	struct il_addsta_cmd sta;
 	struct il_tid_data tid[MAX_TID_COUNT];
-	u8 used, ctxid;
+	u8 used;
 	struct il_hw_key keyinfo;
 	struct il_link_quality_cmd *lq;
 };
 
 struct il_station_priv_common {
-	struct il_rxon_context *ctx;
 	u8 sta_id;
 };
 
@@ -752,7 +745,6 @@ struct il_station_priv_common {
  * space for us to put data into.
  */
 struct il_vif_priv {
-	struct il_rxon_context *ctx;
 	u8 ibss_bssid_sta_id;
 };
 
@@ -816,6 +808,7 @@ struct il_sensitivity_ranges {
 
 /**
  * struct il_hw_params
+ * @bcast_id: f/w broadcast station ID
  * @max_txq_num: Max # Tx queues supported
  * @dma_chnl_num: Number of Tx DMA/FIFO channels
  * @scd_bc_tbls_size: size of scheduler byte count tables
@@ -836,6 +829,7 @@ struct il_sensitivity_ranges {
  * @struct il_sensitivity_ranges: range of sensitivity values
  */
 struct il_hw_params {
+	u8 bcast_id;
 	u8 max_txq_num;
 	u8 dma_chnl_num;
 	u16 scd_bc_tbls_size;
@@ -1152,55 +1146,6 @@ struct il_force_reset {
 
 struct il_rxon_context {
 	struct ieee80211_vif *vif;
-
-	const u8 *ac_to_fifo;
-	const u8 *ac_to_queue;
-	u8 mcast_queue;
-
-	/*
-	 * We could use the vif to indicate active, but we
-	 * also need it to be active during disabling when
-	 * we already removed the vif for type setting.
-	 */
-	bool always_active, is_active;
-
-	bool ht_need_multiple_chains;
-
-	int ctxid;
-
-	u32 interface_modes, exclusive_interface_modes;
-	u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype;
-
-	/*
-	 * We declare this const so it can only be
-	 * changed via explicit cast within the
-	 * routines that actually update the physical
-	 * hardware.
-	 */
-	const struct il_rxon_cmd active;
-	struct il_rxon_cmd staging;
-
-	struct il_rxon_time_cmd timing;
-
-	struct il_qos_info qos_data;
-
-	u8 bcast_sta_id, ap_sta_id;
-
-	u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
-	u8 qos_cmd;
-	u8 wep_key_cmd;
-
-	struct il_wep_key wep_keys[WEP_KEYS_MAX];
-	u8 key_mapping_keys;
-
-	__le32 station_flags;
-
-	struct {
-		bool non_gf_sta_present;
-		u8 protection;
-		bool enabled, is_40mhz;
-		u8 extension_chan_offset;
-	} ht;
 };
 
 struct il_power_mgr {
@@ -1217,6 +1162,7 @@ struct il_priv {
 	struct ieee80211_channel *ieee_channels;
 	struct ieee80211_rate *ieee_rates;
 	struct il_cfg *cfg;
+	const struct il_ops *ops;
 
 	/* temporary frame storage list */
 	struct list_head free_frames;
@@ -1304,7 +1250,28 @@ struct il_priv {
 	u8 ucode_write_complete;	/* the image write is complete */
 	char firmware_name[25];
 
-	struct il_rxon_context ctx;
+	struct ieee80211_vif *vif;
+
+	struct il_qos_info qos_data;
+
+	struct {
+		bool enabled;
+		bool is_40mhz;
+		bool non_gf_sta_present;
+		u8 protection;
+		u8 extension_chan_offset;
+	} ht;
+
+	/*
+	 * We declare this const so it can only be
+	 * changed via explicit cast within the
+	 * routines that actually update the physical
+	 * hardware.
+	 */
+	const struct il_rxon_cmd active;
+	struct il_rxon_cmd staging;
+
+	struct il_rxon_time_cmd timing;
 
 	__le16 switch_channel;
 
@@ -1427,6 +1394,9 @@ struct il_priv {
 			u8 phy_calib_chain_noise_reset_cmd;
 			u8 phy_calib_chain_noise_gain_cmd;
 
+			u8 key_mapping_keys;
+			struct il_wep_key wep_keys[WEP_KEYS_MAX];
+
 			struct il_notif_stats stats;
 #ifdef CONFIG_IWLEGACY_DEBUGFS
 			struct il_notif_stats accum_stats;
@@ -1449,7 +1419,7 @@ struct il_priv {
 	struct work_struct rx_replenish;
 	struct work_struct abort_scan;
 
-	struct il_rxon_context *beacon_ctx;
+	bool beacon_enabled;
 	struct sk_buff *beacon_skb;
 
 	struct work_struct tx_flush;
@@ -1507,30 +1477,10 @@ il_txq_ctx_deactivate(struct il_priv *il, int txq_id)
 	clear_bit(txq_id, &il->txq_ctx_active_msk);
 }
 
-static inline struct ieee80211_hdr *
-il_tx_queue_get_hdr(struct il_priv *il, int txq_id, int idx)
-{
-	if (il->txq[txq_id].txb[idx].skb)
-		return (struct ieee80211_hdr *)il->txq[txq_id].txb[idx].skb->
-		    data;
-	return NULL;
-}
-
-static inline struct il_rxon_context *
-il_rxon_ctx_from_vif(struct ieee80211_vif *vif)
-{
-	struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
-
-	return vif_priv->ctx;
-}
-
-#define for_each_context(il, _ctx) \
-	for (_ctx = &il->ctx; _ctx == &il->ctx; _ctx++)
-
 static inline int
 il_is_associated(struct il_priv *il)
 {
-	return (il->ctx.active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+	return (il->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
 }
 
 static inline int
@@ -1540,12 +1490,6 @@ il_is_any_associated(struct il_priv *il)
 }
 
 static inline int
-il_is_associated_ctx(struct il_rxon_context *ctx)
-{
-	return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-static inline int
 il_is_channel_valid(const struct il_channel_info *ch_info)
 {
 	if (ch_info == NULL)
@@ -1614,10 +1558,9 @@ il_free_pages(struct il_priv *il, unsigned long page)
 #define IL_RX_BUF_SIZE_8K (8 * 1024)
 
 struct il_hcmd_ops {
-	int (*rxon_assoc) (struct il_priv *il, struct il_rxon_context *ctx);
-	int (*commit_rxon) (struct il_priv *il, struct il_rxon_context *ctx);
-	void (*set_rxon_chain) (struct il_priv *il,
-				struct il_rxon_context *ctx);
+	int (*rxon_assoc) (struct il_priv *il);
+	int (*commit_rxon) (struct il_priv *il);
+	void (*set_rxon_chain) (struct il_priv *il);
 };
 
 struct il_hcmd_utils_ops {
@@ -1649,8 +1592,6 @@ struct il_temp_ops {
 };
 
 struct il_lib_ops {
-	/* set hw dependent parameters */
-	int (*set_hw_params) (struct il_priv *il);
 	/* Handling TX */
 	void (*txq_update_byte_cnt_tbl) (struct il_priv *il,
 					 struct il_tx_queue *txq,
@@ -1712,7 +1653,6 @@ struct il_ops {
 	const struct il_led_ops *led;
 	const struct il_nic_ops *nic;
 	const struct il_legacy_ops *legacy;
-	const struct ieee80211_ops *ieee80211_ops;
 };
 
 struct il_mod_params {
@@ -1739,21 +1679,6 @@ struct il_mod_params {
  *	chain noise calibration operation
  */
 struct il_base_params {
-	int eeprom_size;
-	int num_of_queues;	/* def: HW dependent */
-	int num_of_ampdu_queues;	/* def: HW dependent */
-	/* for il_apm_init() */
-	u32 pll_cfg_val;
-	bool set_l0s;
-	bool use_bsm;
-
-	u16 led_compensation;
-	int chain_noise_num_beacons;
-	unsigned int wd_timeout;
-	bool temperature_kelvin;
-	const bool ucode_tracing;
-	const bool sensitivity_calib_by_driver;
-	const bool chain_noise_calib_by_driver;
 };
 
 #define IL_LED_SOLID 11
@@ -1821,7 +1746,6 @@ struct il_cfg {
 	unsigned int sku;
 	u16 eeprom_ver;
 	u16 eeprom_calib_ver;
-	const struct il_ops *ops;
 	/* module based parameters which can be set from modprobe cmd */
 	const struct il_mod_params *mod_params;
 	/* params not likely to change within a device family */
@@ -1829,31 +1753,43 @@ struct il_cfg {
 	/* params likely to change within a device family */
 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
 	enum il_led_mode led_mode;
+
+	int eeprom_size;
+	int num_of_queues;		/* def: HW dependent */
+	int num_of_ampdu_queues;	/* def: HW dependent */
+	/* for il_apm_init() */
+	u32 pll_cfg_val;
+	bool set_l0s;
+	bool use_bsm;
+
+	u16 led_compensation;
+	int chain_noise_num_beacons;
+	unsigned int wd_timeout;
+	bool temperature_kelvin;
+	const bool ucode_tracing;
+	const bool sensitivity_calib_by_driver;
+	const bool chain_noise_calib_by_driver;
 };
 
 /***************************
  *   L i b                 *
  ***************************/
 
-struct ieee80211_hw *il_alloc_all(struct il_cfg *cfg);
 int il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		   u16 queue, const struct ieee80211_tx_queue_params *params);
 int il_mac_tx_last_beacon(struct ieee80211_hw *hw);
 
-void il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx,
-			  int hw_decrypt);
-int il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx);
-int il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx);
-int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
-			struct il_rxon_context *ctx);
-void il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx,
-			   enum ieee80211_band band, struct ieee80211_vif *vif);
+void il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt);
+int il_check_rxon_cmd(struct il_priv *il);
+int il_full_rxon_required(struct il_priv *il);
+int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch);
+void il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band,
+			   struct ieee80211_vif *vif);
 u8 il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band);
 void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf);
-bool il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
+bool il_is_ht40_tx_allowed(struct il_priv *il,
 			   struct ieee80211_sta_ht_cap *ht_cap);
-void il_connection_init_rx_config(struct il_priv *il,
-				  struct il_rxon_context *ctx);
+void il_connection_init_rx_config(struct il_priv *il);
 void il_set_rate(struct il_priv *il);
 int il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr,
 			  u32 decrypt_res, struct ieee80211_rx_status *stats);
@@ -1956,7 +1892,7 @@ int il_set_tx_power(struct il_priv *il, s8 tx_power, bool force);
  * Rate
  ******************************************************************************/
 
-u8 il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx);
+u8 il_get_lowest_plcp(struct il_priv *il);
 
 /*******************************************************************************
  * Scanning
@@ -2043,10 +1979,10 @@ extern const struct dev_pm_ops il_pm_ops;
 ******************************************************/
 void il4965_dump_nic_error_log(struct il_priv *il);
 #ifdef CONFIG_IWLEGACY_DEBUG
-void il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx);
+void il_print_rx_config_cmd(struct il_priv *il);
 #else
 static inline void
-il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_print_rx_config_cmd(struct il_priv *il)
 {
 }
 #endif
@@ -2135,17 +2071,18 @@ extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear);
 void il_apm_stop(struct il_priv *il);
 int il_apm_init(struct il_priv *il);
 
-int il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx);
+int il_send_rxon_timing(struct il_priv *il);
+
 static inline int
-il_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il_send_rxon_assoc(struct il_priv *il)
 {
-	return il->cfg->ops->hcmd->rxon_assoc(il, ctx);
+	return il->ops->hcmd->rxon_assoc(il);
 }
 
 static inline int
-il_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il_commit_rxon(struct il_priv *il)
 {
-	return il->cfg->ops->hcmd->commit_rxon(il, ctx);
+	return il->ops->hcmd->commit_rxon(il);
 }
 
 static inline const struct ieee80211_supported_band *
@@ -2303,23 +2240,22 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
 				   (this is for the IBSS BSSID stations) */
 #define IL_STA_BCAST BIT(4)	/* this station is the special bcast station */
 
-void il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx);
-void il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx);
+void il_restore_stations(struct il_priv *il);
+void il_clear_ucode_stations(struct il_priv *il);
 void il_dealloc_bcast_stations(struct il_priv *il);
 int il_get_free_ucode_key_idx(struct il_priv *il);
 int il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags);
-int il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
-			  const u8 *addr, bool is_ap,
+int il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap,
 			  struct ieee80211_sta *sta, u8 *sta_id_r);
 int il_remove_station(struct il_priv *il, const u8 sta_id, const u8 * addr);
 int il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		      struct ieee80211_sta *sta);
 
-u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
-		   const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
+u8 il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
+		   struct ieee80211_sta *sta);
 
-int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
-		   struct il_link_quality_cmd *lq, u8 flags, bool init);
+int il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq,
+		   u8 flags, bool init);
 
 /**
  * il_clear_driver_stations - clear knowledge of all stations from driver
@@ -2334,24 +2270,11 @@ static inline void
 il_clear_driver_stations(struct il_priv *il)
 {
 	unsigned long flags;
-	struct il_rxon_context *ctx = &il->ctx;
 
 	spin_lock_irqsave(&il->sta_lock, flags);
 	memset(il->stations, 0, sizeof(il->stations));
 	il->num_stations = 0;
-
 	il->ucode_key_table = 0;
-
-	/*
-	 * Remove all key information that is not stored as part
-	 * of station information since mac80211 may not have had
-	 * a chance to remove all the keys. When device is
-	 * reconfigured by mac80211 after an error all keys will
-	 * be reconfigured.
-	 */
-	memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
-	ctx->key_mapping_keys = 0;
-
 	spin_unlock_irqrestore(&il->sta_lock, flags);
 }
 
@@ -2376,13 +2299,12 @@ il_sta_id(struct ieee80211_sta *sta)
  * inline wraps that pattern.
  */
 static inline int
-il_sta_id_or_broadcast(struct il_priv *il, struct il_rxon_context *context,
-		       struct ieee80211_sta *sta)
+il_sta_id_or_broadcast(struct il_priv *il, struct ieee80211_sta *sta)
 {
 	int sta_id;
 
 	if (!sta)
-		return context->bcast_sta_id;
+		return il->hw_params.bcast_id;
 
 	sta_id = il_sta_id(sta);
 
diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c
index b1b8926..bb7c956 100644
--- a/drivers/net/wireless/iwlegacy/debug.c
+++ b/drivers/net/wireless/iwlegacy/debug.c
@@ -361,7 +361,7 @@ il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,
 	const u8 *ptr;
 	char *buf;
 	u16 eeprom_ver;
-	size_t eeprom_len = il->cfg->base_params->eeprom_size;
+	size_t eeprom_len = il->cfg->eeprom_size;
 	buf_size = 4 * eeprom_len + 256;
 
 	if (eeprom_len % 16) {
@@ -644,12 +644,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
 		  loff_t *ppos)
 {
 	struct il_priv *il = file->private_data;
-	struct il_rxon_context *ctx = &il->ctx;
 	int pos = 0, i;
 	char buf[256];
 	const size_t bufsz = sizeof(buf);
 
-	pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", ctx->ctxid);
 	for (i = 0; i < AC_NUM; i++) {
 		pos +=
 		    scnprintf(buf + pos, bufsz - pos,
@@ -657,10 +655,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
 		pos +=
 		    scnprintf(buf + pos, bufsz - pos,
 			      "AC[%d]\t%u\t%u\t%u\t%u\n", i,
-			      ctx->qos_data.def_qos_parm.ac[i].cw_min,
-			      ctx->qos_data.def_qos_parm.ac[i].cw_max,
-			      ctx->qos_data.def_qos_parm.ac[i].aifsn,
-			      ctx->qos_data.def_qos_parm.ac[i].edca_txop);
+			      il->qos_data.def_qos_parm.ac[i].cw_min,
+			      il->qos_data.def_qos_parm.ac[i].cw_max,
+			      il->qos_data.def_qos_parm.ac[i].aifsn,
+			      il->qos_data.def_qos_parm.ac[i].edca_txop);
 	}
 
 	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -729,7 +727,7 @@ il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
 	char *buf;
 	int bufsz =
 	    ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
-	    (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
+	    (il->cfg->num_of_queues * 32 * 8) + 400;
 	const u8 *ptr;
 	ssize_t ret;
 
@@ -835,7 +833,7 @@ il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
 	int cnt;
 	int ret;
 	const size_t bufsz =
-	    sizeof(char) * 64 * il->cfg->base_params->num_of_queues;
+	    sizeof(char) * 64 * il->cfg->num_of_queues;
 
 	if (!il->txq) {
 		IL_ERR("txq not ready\n");
@@ -903,8 +901,7 @@ il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
 			     size_t count, loff_t *ppos)
 {
 	struct il_priv *il = file->private_data;
-	return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf,
-							    count, ppos);
+	return il->ops->lib->debugfs_ops.rx_stats_read(file, user_buf, count, ppos);
 }
 
 static ssize_t
@@ -912,8 +909,7 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
 			     size_t count, loff_t *ppos)
 {
 	struct il_priv *il = file->private_data;
-	return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf,
-							    count, ppos);
+	return il->ops->lib->debugfs_ops.tx_stats_read(file, user_buf, count, ppos);
 }
 
 static ssize_t
@@ -921,8 +917,7 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
 				  size_t count, loff_t *ppos)
 {
 	struct il_priv *il = file->private_data;
-	return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf,
-								 count, ppos);
+	return il->ops->lib->debugfs_ops.general_stats_read(file, user_buf, count, ppos);
 }
 
 static ssize_t
@@ -1153,7 +1148,7 @@ il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
 	int len = 0;
 	char buf[20];
 
-	len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.flags));
+	len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -1167,7 +1162,7 @@ il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
 	char buf[20];
 
 	len =
-	    sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.filter_flags));
+	    sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -1180,8 +1175,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
 	int pos = 0;
 	ssize_t ret = -EFAULT;
 
-	if (il->cfg->ops->lib->dump_fh) {
-		ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
+	if (il->ops->lib->dump_fh) {
+		ret = pos = il->ops->lib->dump_fh(il, &buf, true);
 		if (buf) {
 			ret =
 			    simple_read_from_buffer(user_buf, count, ppos, buf,
@@ -1298,7 +1293,7 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
 	if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
 		timeout = IL_DEF_WD_TIMEOUT;
 
-	il->cfg->base_params->wd_timeout = timeout;
+	il->cfg->wd_timeout = timeout;
 	il_setup_watchdog(il);
 	return count;
 }
@@ -1372,17 +1367,17 @@ il_dbgfs_register(struct il_priv *il, const char *name)
 	DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
 
-	if (il->cfg->base_params->sensitivity_calib_by_driver)
+	if (il->cfg->sensitivity_calib_by_driver)
 		DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
-	if (il->cfg->base_params->chain_noise_calib_by_driver)
+	if (il->cfg->chain_noise_calib_by_driver)
 		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
-	if (il->cfg->base_params->sensitivity_calib_by_driver)
+	if (il->cfg->sensitivity_calib_by_driver)
 		DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
 				 &il->disable_sens_cal);
-	if (il->cfg->base_params->chain_noise_calib_by_driver)
+	if (il->cfg->chain_noise_calib_by_driver)
 		DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
 				 &il->disable_chain_noise_cal);
 	DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 1ef7bfc..8c1466c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -84,13 +84,13 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
 static void iwl1000_nic_config(struct iwl_priv *priv)
 {
 	/* set CSR_HW_CONFIG_REG for uCode use */
-	iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
+	iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
 		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
 		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
 	/* Setting digital SVR for 1000 card to 1.32V */
 	/* locking is acquired in iwl_set_bits_mask_prph() function */
-	iwl_set_bits_mask_prph(bus(priv), APMG_DIGITAL_SVR_REG,
+	iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG,
 				APMG_SVR_DIGITAL_VOLTAGE_1_32,
 				~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
 }
@@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
 	hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
 	hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 0946933..d4f5f3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -87,7 +87,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
 	iwl_rf_config(priv);
 
 	if (cfg(priv)->iq_invert)
-		iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+		iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
 			    CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
 }
 
@@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
 	hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
 	hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b3a365f..dc9317d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -73,7 +73,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
 	 * (PCIe power is lost before PERST# is asserted),
 	 * causing ME FW to lose ownership and not being able to obtain it back.
 	 */
-	iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG,
+	iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG,
 				APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
 				~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
 
@@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
 	hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
 	hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
@@ -199,8 +197,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
 	hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE;
 	hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 54b7533..c36fb85 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -82,7 +82,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
 {
 	/* Indicate calibration version to uCode. */
 	if (iwl_eeprom_calib_version(priv->shrd) >= 6)
-		iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+		iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
 				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
 }
 
@@ -90,9 +90,9 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv)
 {
 	/* Indicate calibration version to uCode. */
 	if (iwl_eeprom_calib_version(priv->shrd) >= 6)
-		iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+		iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
 				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
-	iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
+	iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG,
 		    CSR_GP_DRIVER_REG_BIT_6050_1x2);
 }
 
@@ -104,7 +104,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
 	/* no locking required for register write */
 	if (cfg(priv)->pa_type == IWL_PA_INTERNAL) {
 		/* 2x2 IPA phy type */
-		iwl_write32(bus(priv), CSR_GP_DRIVER_REG,
+		iwl_write32(trans(priv), CSR_GP_DRIVER_REG,
 			     CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
 	}
 	/* do additional nic configuration if needed */
@@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 			iwlagn_mod_params.num_of_queues;
 
 	hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues;
-	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
-
 	hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE;
 	hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 50ff849..6aa0098 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
index 10275ce..9ed6683 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index 123ef5e..d0ec0ab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 64cf439..a8f7689 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 334b5ae..b9ba404 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 6675b3c..203b1c1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index b22b297..a14ddab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portionhelp of the ieee80211 subsystem header files.
@@ -628,16 +628,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
 	if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
 		     CT_CARD_DISABLED)) {
 
-		iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
+		iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
 			    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
-		iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C,
+		iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C,
 					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
 		if (!(flags & RXON_CARD_DISABLED)) {
-			iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+			iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
 				    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-			iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C,
+			iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C,
 					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 		}
 		if (flags & CT_CARD_DISABLED)
@@ -1172,20 +1172,22 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
 		wake_up_all(&priv->shrd->notif_waitq);
 	}
 
-	if (priv->pre_rx_handler)
+	if (priv->pre_rx_handler &&
+	    priv->shrd->ucode_owner == IWL_OWNERSHIP_TM)
 		priv->pre_rx_handler(priv, rxb);
-
-	/* Based on type of command response or notification,
-	 *   handle those that need handling via function in
-	 *   rx_handlers table.  See iwl_setup_rx_handlers() */
-	if (priv->rx_handlers[pkt->hdr.cmd]) {
-		priv->rx_handlers_stats[pkt->hdr.cmd]++;
-		err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
-	} else {
-		/* No handling needed */
-		IWL_DEBUG_RX(priv,
-			"No handler needed for %s, 0x%02x\n",
-			get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+	else {
+		/* Based on type of command response or notification,
+		 *   handle those that need handling via function in
+		 *   rx_handlers table.  See iwl_setup_rx_handlers() */
+		if (priv->rx_handlers[pkt->hdr.cmd]) {
+			priv->rx_handlers_stats[pkt->hdr.cmd]++;
+			err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
+		} else {
+			/* No handling needed */
+			IWL_DEBUG_RX(priv,
+				"No handler needed for %s, 0x%02x\n",
+				get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+		}
 	}
 	return err;
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 1c66594..8ca9570 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 7353826..f1298cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -35,9 +35,12 @@
 #include "iwl-trans.h"
 
 /* priv->shrd->sta_lock must be held */
-static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
+static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 {
-
+	if (sta_id >= IWLAGN_STATION_COUNT) {
+		IWL_ERR(priv, "invalid sta_id %u", sta_id);
+		return -EINVAL;
+	}
 	if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
 		IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u "
 			"addr %pM\n",
@@ -53,6 +56,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 		IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
 				sta_id, priv->stations[sta_id].sta.sta.addr);
 	}
+	return 0;
 }
 
 static int iwl_process_add_sta_resp(struct iwl_priv *priv,
@@ -77,8 +81,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
 	switch (pkt->u.add_sta.status) {
 	case ADD_STA_SUCCESS_MSK:
 		IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
-		iwl_sta_ucode_activate(priv, sta_id);
-		ret = 0;
+		ret = iwl_sta_ucode_activate(priv, sta_id);
 		break;
 	case ADD_STA_NO_ROOM_IN_TABLE:
 		IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
@@ -1187,6 +1190,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
 	unsigned long flags;
 	struct iwl_addsta_cmd sta_cmd;
 	u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta);
+	__le16 key_flags;
 
 	/* if station isn't there, neither is the key */
 	if (sta_id == IWL_INVALID_STATION)
@@ -1212,7 +1216,14 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
 		IWL_ERR(priv, "offset %d not used in uCode key table.\n",
 			keyconf->hw_key_idx);
 
-	sta_cmd.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+	key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+	key_flags |= STA_KEY_FLG_MAP_KEY_MSK | STA_KEY_FLG_NO_ENC |
+		     STA_KEY_FLG_INVALID;
+
+	if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+		key_flags |= STA_KEY_MULTICAST_MSK;
+
+	sta_cmd.key.key_flags = key_flags;
 	sta_cmd.key.key_offset = WEP_INVALID_OFFSET;
 	sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK;
 	sta_cmd.mode = STA_CONTROL_MODIFY_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index b0dff7a..c728ed7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -178,19 +178,19 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
 
 	if (tt->state == IWL_TI_CT_KILL) {
 		if (priv->thermal_throttle.ct_kill_toggle) {
-			iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+			iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
 				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
 			priv->thermal_throttle.ct_kill_toggle = false;
 		} else {
-			iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
+			iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
 				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
 			priv->thermal_throttle.ct_kill_toggle = true;
 		}
-		iwl_read32(bus(priv), CSR_UCODE_DRV_GP1);
-		spin_lock_irqsave(&bus(priv)->reg_lock, flags);
-		if (!iwl_grab_nic_access(bus(priv)))
-			iwl_release_nic_access(bus(priv));
-		spin_unlock_irqrestore(&bus(priv)->reg_lock, flags);
+		iwl_read32(trans(priv), CSR_UCODE_DRV_GP1);
+		spin_lock_irqsave(&trans(priv)->reg_lock, flags);
+		if (!iwl_grab_nic_access(trans(priv)))
+			iwl_release_nic_access(trans(priv));
+		spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
 
 		/* Reschedule the ct_kill timer to occur in
 		 * CT_KILL_EXIT_DURATION seconds to ensure we get a
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
index 7282a23..86bbf47 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 63bbc60..64f8db6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b5c7c5f..8837171 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -34,7 +34,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
@@ -42,6 +41,7 @@
 
 #include <asm/div64.h>
 
+#include "iwl-ucode.h"
 #include "iwl-eeprom.h"
 #include "iwl-wifi.h"
 #include "iwl-dev.h"
@@ -315,7 +315,7 @@ static void iwl_bg_statistics_periodic(unsigned long data)
 
 static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
 					u32 start_idx, u32 num_events,
-					u32 mode)
+					u32 capacity, u32 mode)
 {
 	u32 i;
 	u32 ptr;        /* SRAM byte address of log data */
@@ -328,87 +328,125 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
 		ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
 
 	/* Make sure device is powered up for SRAM reads */
-	spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags);
-	if (iwl_grab_nic_access(bus(priv))) {
-		spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags);
+	spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags);
+	if (iwl_grab_nic_access(trans(priv))) {
+		spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
 		return;
 	}
 
 	/* Set starting address; reads will auto-increment */
-	iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr);
+	iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr);
 	rmb();
 
 	/*
+	 * Refuse to read more than would have fit into the log from
+	 * the current start_idx. This used to happen due to the race
+	 * described below, but now WARN because the code below should
+	 * prevent it from happening here.
+	 */
+	if (WARN_ON(num_events > capacity - start_idx))
+		num_events = capacity - start_idx;
+
+	/*
 	 * "time" is actually "data" for mode 0 (no timestamp).
 	 * place event id # at far right for easier visual parsing.
 	 */
 	for (i = 0; i < num_events; i++) {
-		ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
-		time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
+		ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
+		time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
-			trace_iwlwifi_dev_ucode_cont_event(priv,
-							0, time, ev);
+			trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev);
 		} else {
-			data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
-			trace_iwlwifi_dev_ucode_cont_event(priv,
-						time, data, ev);
+			data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
+			trace_iwlwifi_dev_ucode_cont_event(priv, time,
+							   data, ev);
 		}
 	}
 	/* Allow device to power down */
-	iwl_release_nic_access(bus(priv));
-	spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags);
+	iwl_release_nic_access(trans(priv));
+	spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags);
 }
 
 static void iwl_continuous_event_trace(struct iwl_priv *priv)
 {
 	u32 capacity;   /* event log capacity in # entries */
+	struct {
+		u32 capacity;
+		u32 mode;
+		u32 wrap_counter;
+		u32 write_counter;
+	} __packed read;
 	u32 base;       /* SRAM byte address of event log header */
 	u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
 	u32 num_wraps;  /* # times uCode wrapped to top of log */
 	u32 next_entry; /* index of next entry to be written by uCode */
 
-	base = priv->shrd->device_pointers.error_event_table;
+	base = priv->shrd->device_pointers.log_event_table;
 	if (iwlagn_hw_valid_rtc_data_addr(base)) {
-		capacity = iwl_read_targ_mem(bus(priv), base);
-		num_wraps = iwl_read_targ_mem(bus(priv),
-						base + (2 * sizeof(u32)));
-		mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32)));
-		next_entry = iwl_read_targ_mem(bus(priv),
-						base + (3 * sizeof(u32)));
+		iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read));
+
+		capacity = read.capacity;
+		mode = read.mode;
+		num_wraps = read.wrap_counter;
+		next_entry = read.write_counter;
 	} else
 		return;
 
+	/*
+	 * Unfortunately, the uCode doesn't use temporary variables.
+	 * Therefore, it can happen that we read next_entry == capacity,
+	 * which really means next_entry == 0.
+	 */
+	if (unlikely(next_entry == capacity))
+		next_entry = 0;
+	/*
+	 * Additionally, the uCode increases the write pointer before
+	 * the wraps counter, so if the write pointer is smaller than
+	 * the old write pointer (wrap occurred) but we read that no
+	 * wrap occurred, we actually read between the next_entry and
+	 * num_wraps update (this does happen in practice!!) -- take
+	 * that into account by increasing num_wraps.
+	 */
+	if (unlikely(next_entry < priv->event_log.next_entry &&
+		     num_wraps == priv->event_log.num_wraps))
+		num_wraps++;
+
 	if (num_wraps == priv->event_log.num_wraps) {
-		iwl_print_cont_event_trace(priv,
-				       base, priv->event_log.next_entry,
-				       next_entry - priv->event_log.next_entry,
-				       mode);
+		iwl_print_cont_event_trace(
+			priv, base, priv->event_log.next_entry,
+			next_entry - priv->event_log.next_entry,
+			capacity, mode);
+
 		priv->event_log.non_wraps_count++;
 	} else {
-		if ((num_wraps - priv->event_log.num_wraps) > 1)
+		if (num_wraps - priv->event_log.num_wraps > 1)
 			priv->event_log.wraps_more_count++;
 		else
 			priv->event_log.wraps_once_count++;
+
 		trace_iwlwifi_dev_ucode_wrap_event(priv,
 				num_wraps - priv->event_log.num_wraps,
 				next_entry, priv->event_log.next_entry);
+
 		if (next_entry < priv->event_log.next_entry) {
-			iwl_print_cont_event_trace(priv, base,
-			       priv->event_log.next_entry,
-			       capacity - priv->event_log.next_entry,
-			       mode);
+			iwl_print_cont_event_trace(
+				priv, base, priv->event_log.next_entry,
+				capacity - priv->event_log.next_entry,
+				capacity, mode);
 
-			iwl_print_cont_event_trace(priv, base, 0,
-				next_entry, mode);
+			iwl_print_cont_event_trace(
+				priv, base, 0, next_entry, capacity, mode);
 		} else {
-			iwl_print_cont_event_trace(priv, base,
-			       next_entry, capacity - next_entry,
-			       mode);
+			iwl_print_cont_event_trace(
+				priv, base, next_entry,
+				capacity - next_entry,
+				capacity, mode);
 
-			iwl_print_cont_event_trace(priv, base, 0,
-				next_entry, mode);
+			iwl_print_cont_event_trace(
+				priv, base, 0, next_entry, capacity, mode);
 		}
 	}
+
 	priv->event_log.num_wraps = num_wraps;
 	priv->event_log.next_entry = next_entry;
 }
@@ -452,7 +490,7 @@ static void iwl_bg_tx_flush(struct work_struct *work)
 	iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
 }
 
-static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
+void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
 {
 	int i;
 
@@ -475,6 +513,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
 	priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
 	priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
 	priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
+	priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
 	priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes =
 		BIT(NL80211_IFTYPE_ADHOC);
 	priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
@@ -509,609 +548,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
 	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
 }
 
-static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
-
-#define UCODE_EXPERIMENTAL_INDEX	100
-#define UCODE_EXPERIMENTAL_TAG		"exp"
-
-static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
-{
-	const char *name_pre = cfg(priv)->fw_name_pre;
-	char tag[8];
-
-	if (first) {
-#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
-		priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
-		strcpy(tag, UCODE_EXPERIMENTAL_TAG);
-	} else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
-#endif
-		priv->fw_index = cfg(priv)->ucode_api_max;
-		sprintf(tag, "%d", priv->fw_index);
-	} else {
-		priv->fw_index--;
-		sprintf(tag, "%d", priv->fw_index);
-	}
-
-	if (priv->fw_index < cfg(priv)->ucode_api_min) {
-		IWL_ERR(priv, "no suitable firmware found!\n");
-		return -ENOENT;
-	}
-
-	sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
-
-	IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
-		       (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
-				? "EXPERIMENTAL " : "",
-		       priv->firmware_name);
-
-	return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
-				       bus(priv)->dev,
-				       GFP_KERNEL, priv, iwl_ucode_callback);
-}
-
-struct iwlagn_firmware_pieces {
-	const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
-	size_t inst_size, data_size, init_size, init_data_size,
-	       wowlan_inst_size, wowlan_data_size;
-
-	u32 build;
-
-	u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-	u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
-};
-
-static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
-				       const struct firmware *ucode_raw,
-				       struct iwlagn_firmware_pieces *pieces)
-{
-	struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
-	u32 api_ver, hdr_size;
-	const u8 *src;
-
-	priv->ucode_ver = le32_to_cpu(ucode->ver);
-	api_ver = IWL_UCODE_API(priv->ucode_ver);
-
-	switch (api_ver) {
-	default:
-		hdr_size = 28;
-		if (ucode_raw->size < hdr_size) {
-			IWL_ERR(priv, "File size too small!\n");
-			return -EINVAL;
-		}
-		pieces->build = le32_to_cpu(ucode->u.v2.build);
-		pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
-		pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
-		pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
-		pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
-		src = ucode->u.v2.data;
-		break;
-	case 0:
-	case 1:
-	case 2:
-		hdr_size = 24;
-		if (ucode_raw->size < hdr_size) {
-			IWL_ERR(priv, "File size too small!\n");
-			return -EINVAL;
-		}
-		pieces->build = 0;
-		pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
-		pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
-		pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
-		pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
-		src = ucode->u.v1.data;
-		break;
-	}
-
-	/* Verify size of file vs. image size info in file's header */
-	if (ucode_raw->size != hdr_size + pieces->inst_size +
-				pieces->data_size + pieces->init_size +
-				pieces->init_data_size) {
-
-		IWL_ERR(priv,
-			"uCode file size %d does not match expected size\n",
-			(int)ucode_raw->size);
-		return -EINVAL;
-	}
-
-	pieces->inst = src;
-	src += pieces->inst_size;
-	pieces->data = src;
-	src += pieces->data_size;
-	pieces->init = src;
-	src += pieces->init_size;
-	pieces->init_data = src;
-	src += pieces->init_data_size;
-
-	return 0;
-}
-
-static int iwlagn_load_firmware(struct iwl_priv *priv,
-				const struct firmware *ucode_raw,
-				struct iwlagn_firmware_pieces *pieces,
-				struct iwlagn_ucode_capabilities *capa)
-{
-	struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
-	struct iwl_ucode_tlv *tlv;
-	size_t len = ucode_raw->size;
-	const u8 *data;
-	int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
-	int tmp;
-	u64 alternatives;
-	u32 tlv_len;
-	enum iwl_ucode_tlv_type tlv_type;
-	const u8 *tlv_data;
-
-	if (len < sizeof(*ucode)) {
-		IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
-		return -EINVAL;
-	}
-
-	if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
-		IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
-			le32_to_cpu(ucode->magic));
-		return -EINVAL;
-	}
-
-	/*
-	 * Check which alternatives are present, and "downgrade"
-	 * when the chosen alternative is not present, warning
-	 * the user when that happens. Some files may not have
-	 * any alternatives, so don't warn in that case.
-	 */
-	alternatives = le64_to_cpu(ucode->alternatives);
-	tmp = wanted_alternative;
-	if (wanted_alternative > 63)
-		wanted_alternative = 63;
-	while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
-		wanted_alternative--;
-	if (wanted_alternative && wanted_alternative != tmp)
-		IWL_WARN(priv,
-			 "uCode alternative %d not available, choosing %d\n",
-			 tmp, wanted_alternative);
-
-	priv->ucode_ver = le32_to_cpu(ucode->ver);
-	pieces->build = le32_to_cpu(ucode->build);
-	data = ucode->data;
-
-	len -= sizeof(*ucode);
-
-	while (len >= sizeof(*tlv)) {
-		u16 tlv_alt;
-
-		len -= sizeof(*tlv);
-		tlv = (void *)data;
-
-		tlv_len = le32_to_cpu(tlv->length);
-		tlv_type = le16_to_cpu(tlv->type);
-		tlv_alt = le16_to_cpu(tlv->alternative);
-		tlv_data = tlv->data;
-
-		if (len < tlv_len) {
-			IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
-				len, tlv_len);
-			return -EINVAL;
-		}
-		len -= ALIGN(tlv_len, 4);
-		data += sizeof(*tlv) + ALIGN(tlv_len, 4);
-
-		/*
-		 * Alternative 0 is always valid.
-		 *
-		 * Skip alternative TLVs that are not selected.
-		 */
-		if (tlv_alt != 0 && tlv_alt != wanted_alternative)
-			continue;
-
-		switch (tlv_type) {
-		case IWL_UCODE_TLV_INST:
-			pieces->inst = tlv_data;
-			pieces->inst_size = tlv_len;
-			break;
-		case IWL_UCODE_TLV_DATA:
-			pieces->data = tlv_data;
-			pieces->data_size = tlv_len;
-			break;
-		case IWL_UCODE_TLV_INIT:
-			pieces->init = tlv_data;
-			pieces->init_size = tlv_len;
-			break;
-		case IWL_UCODE_TLV_INIT_DATA:
-			pieces->init_data = tlv_data;
-			pieces->init_data_size = tlv_len;
-			break;
-		case IWL_UCODE_TLV_BOOT:
-			IWL_ERR(priv, "Found unexpected BOOT ucode\n");
-			break;
-		case IWL_UCODE_TLV_PROBE_MAX_LEN:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			capa->max_probe_length =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_PAN:
-			if (tlv_len)
-				goto invalid_tlv_len;
-			capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
-			break;
-		case IWL_UCODE_TLV_FLAGS:
-			/* must be at least one u32 */
-			if (tlv_len < sizeof(u32))
-				goto invalid_tlv_len;
-			/* and a proper number of u32s */
-			if (tlv_len % sizeof(u32))
-				goto invalid_tlv_len;
-			/*
-			 * This driver only reads the first u32 as
-			 * right now no more features are defined,
-			 * if that changes then either the driver
-			 * will not work with the new firmware, or
-			 * it'll not take advantage of new features.
-			 */
-			capa->flags = le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			pieces->init_evtlog_ptr =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			pieces->init_evtlog_size =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			pieces->init_errlog_ptr =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			pieces->inst_evtlog_ptr =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			pieces->inst_evtlog_size =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			pieces->inst_errlog_ptr =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
-			if (tlv_len)
-				goto invalid_tlv_len;
-			priv->enhance_sensitivity_table = true;
-			break;
-		case IWL_UCODE_TLV_WOWLAN_INST:
-			pieces->wowlan_inst = tlv_data;
-			pieces->wowlan_inst_size = tlv_len;
-			break;
-		case IWL_UCODE_TLV_WOWLAN_DATA:
-			pieces->wowlan_data = tlv_data;
-			pieces->wowlan_data_size = tlv_len;
-			break;
-		case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
-			if (tlv_len != sizeof(u32))
-				goto invalid_tlv_len;
-			capa->standard_phy_calibration_size =
-					le32_to_cpup((__le32 *)tlv_data);
-			break;
-		default:
-			IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
-			break;
-		}
-	}
-
-	if (len) {
-		IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
-		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
-		return -EINVAL;
-	}
-
-	return 0;
-
- invalid_tlv_len:
-	IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
-	iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
-
-	return -EINVAL;
-}
-
-/**
- * iwl_ucode_callback - callback when firmware was loaded
- *
- * If loaded successfully, copies the firmware into buffers
- * for the card to fetch (via DMA).
- */
-static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
-{
-	struct iwl_priv *priv = context;
-	struct iwl_ucode_header *ucode;
-	int err;
-	struct iwlagn_firmware_pieces pieces;
-	const unsigned int api_max = cfg(priv)->ucode_api_max;
-	unsigned int api_ok = cfg(priv)->ucode_api_ok;
-	const unsigned int api_min = cfg(priv)->ucode_api_min;
-	u32 api_ver;
-	char buildstr[25];
-	u32 build;
-	struct iwlagn_ucode_capabilities ucode_capa = {
-		.max_probe_length = 200,
-		.standard_phy_calibration_size =
-			IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
-	};
-
-	if (!api_ok)
-		api_ok = api_max;
-
-	memset(&pieces, 0, sizeof(pieces));
-
-	if (!ucode_raw) {
-		if (priv->fw_index <= api_ok)
-			IWL_ERR(priv,
-				"request for firmware file '%s' failed.\n",
-				priv->firmware_name);
-		goto try_again;
-	}
-
-	IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
-		       priv->firmware_name, ucode_raw->size);
-
-	/* Make sure that we got at least the API version number */
-	if (ucode_raw->size < 4) {
-		IWL_ERR(priv, "File size way too small!\n");
-		goto try_again;
-	}
-
-	/* Data from ucode file:  header followed by uCode images */
-	ucode = (struct iwl_ucode_header *)ucode_raw->data;
-
-	if (ucode->ver)
-		err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
-	else
-		err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
-					   &ucode_capa);
-
-	if (err)
-		goto try_again;
-
-	api_ver = IWL_UCODE_API(priv->ucode_ver);
-	build = pieces.build;
-
-	/*
-	 * api_ver should match the api version forming part of the
-	 * firmware filename ... but we don't check for that and only rely
-	 * on the API version read from firmware header from here on forward
-	 */
-	/* no api version check required for experimental uCode */
-	if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
-		if (api_ver < api_min || api_ver > api_max) {
-			IWL_ERR(priv,
-				"Driver unable to support your firmware API. "
-				"Driver supports v%u, firmware is v%u.\n",
-				api_max, api_ver);
-			goto try_again;
-		}
-
-		if (api_ver < api_ok) {
-			if (api_ok != api_max)
-				IWL_ERR(priv, "Firmware has old API version, "
-					"expected v%u through v%u, got v%u.\n",
-					api_ok, api_max, api_ver);
-			else
-				IWL_ERR(priv, "Firmware has old API version, "
-					"expected v%u, got v%u.\n",
-					api_max, api_ver);
-			IWL_ERR(priv, "New firmware can be obtained from "
-				      "http://www.intellinuxwireless.org/.\n");
-		}
-	}
-
-	if (build)
-		sprintf(buildstr, " build %u%s", build,
-		       (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
-				? " (EXP)" : "");
-	else
-		buildstr[0] = '\0';
-
-	IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
-		 IWL_UCODE_MAJOR(priv->ucode_ver),
-		 IWL_UCODE_MINOR(priv->ucode_ver),
-		 IWL_UCODE_API(priv->ucode_ver),
-		 IWL_UCODE_SERIAL(priv->ucode_ver),
-		 buildstr);
-
-	snprintf(priv->hw->wiphy->fw_version,
-		 sizeof(priv->hw->wiphy->fw_version),
-		 "%u.%u.%u.%u%s",
-		 IWL_UCODE_MAJOR(priv->ucode_ver),
-		 IWL_UCODE_MINOR(priv->ucode_ver),
-		 IWL_UCODE_API(priv->ucode_ver),
-		 IWL_UCODE_SERIAL(priv->ucode_ver),
-		 buildstr);
-
-	/*
-	 * For any of the failures below (before allocating pci memory)
-	 * we will try to load a version with a smaller API -- maybe the
-	 * user just got a corrupted version of the latest API.
-	 */
-
-	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
-		       priv->ucode_ver);
-	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
-		       pieces.inst_size);
-	IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
-		       pieces.data_size);
-	IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
-		       pieces.init_size);
-	IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
-		       pieces.init_data_size);
-
-	/* Verify that uCode images will fit in card's SRAM */
-	if (pieces.inst_size > hw_params(priv).max_inst_size) {
-		IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
-			pieces.inst_size);
-		goto try_again;
-	}
-
-	if (pieces.data_size > hw_params(priv).max_data_size) {
-		IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
-			pieces.data_size);
-		goto try_again;
-	}
-
-	if (pieces.init_size > hw_params(priv).max_inst_size) {
-		IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
-			pieces.init_size);
-		goto try_again;
-	}
-
-	if (pieces.init_data_size > hw_params(priv).max_data_size) {
-		IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
-			pieces.init_data_size);
-		goto try_again;
-	}
-
-	/* Allocate ucode buffers for card's bus-master loading ... */
-
-	/* Runtime instructions and 2 copies of data:
-	 * 1) unmodified from disk
-	 * 2) backup cache for save/restore during power-downs */
-	if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code,
-			      pieces.inst, pieces.inst_size))
-		goto err_pci_alloc;
-	if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data,
-			      pieces.data, pieces.data_size))
-		goto err_pci_alloc;
-
-	/* Initialization instructions and data */
-	if (pieces.init_size && pieces.init_data_size) {
-		if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code,
-				      pieces.init, pieces.init_size))
-			goto err_pci_alloc;
-		if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data,
-				      pieces.init_data, pieces.init_data_size))
-			goto err_pci_alloc;
-	}
-
-	/* WoWLAN instructions and data */
-	if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
-		if (iwl_alloc_fw_desc(bus(priv),
-				      &trans(priv)->ucode_wowlan.code,
-				      pieces.wowlan_inst,
-				      pieces.wowlan_inst_size))
-			goto err_pci_alloc;
-		if (iwl_alloc_fw_desc(bus(priv),
-				      &trans(priv)->ucode_wowlan.data,
-				      pieces.wowlan_data,
-				      pieces.wowlan_data_size))
-			goto err_pci_alloc;
-	}
-
-	/* Now that we can no longer fail, copy information */
-
-	/*
-	 * The (size - 16) / 12 formula is based on the information recorded
-	 * for each event, which is of mode 1 (including timestamp) for all
-	 * new microcodes that include this information.
-	 */
-	priv->init_evtlog_ptr = pieces.init_evtlog_ptr;
-	if (pieces.init_evtlog_size)
-		priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
-	else
-		priv->init_evtlog_size =
-			cfg(priv)->base_params->max_event_log_size;
-	priv->init_errlog_ptr = pieces.init_errlog_ptr;
-	priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
-	if (pieces.inst_evtlog_size)
-		priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
-	else
-		priv->inst_evtlog_size =
-			cfg(priv)->base_params->max_event_log_size;
-	priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
-#ifndef CONFIG_IWLWIFI_P2P
-	ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
-#endif
-
-	priv->new_scan_threshold_behaviour =
-		!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
-
-	if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
-		ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
-
-	/*
-	 * if not PAN, then don't support P2P -- might be a uCode
-	 * packaging bug or due to the eeprom check above
-	 */
-	if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
-		ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
-
-	if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
-		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
-		priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
-	} else {
-		priv->sta_key_max_num = STA_KEY_MAX_NUM;
-		priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
-	}
-	/*
-	 * figure out the offset of chain noise reset and gain commands
-	 * base on the size of standard phy calibration commands table size
-	 */
-	if (ucode_capa.standard_phy_calibration_size >
-	    IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
-		ucode_capa.standard_phy_calibration_size =
-			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
-
-	priv->phy_calib_chain_noise_reset_cmd =
-		ucode_capa.standard_phy_calibration_size;
-	priv->phy_calib_chain_noise_gain_cmd =
-		ucode_capa.standard_phy_calibration_size + 1;
-
-	/* initialize all valid contexts */
-	iwl_init_context(priv, ucode_capa.flags);
-
-	/**************************************************
-	 * This is still part of probe() in a sense...
-	 *
-	 * 9. Setup and register with mac80211 and debugfs
-	 **************************************************/
-	err = iwlagn_mac_setup_register(priv, &ucode_capa);
-	if (err)
-		goto out_unbind;
-
-	err = iwl_dbgfs_register(priv, DRV_NAME);
-	if (err)
-		IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
-
-	/* We have our copies now, allow OS release its copies */
-	release_firmware(ucode_raw);
-	complete(&priv->firmware_loading_complete);
-	return;
-
- try_again:
-	/* try next, if any */
-	if (iwl_request_firmware(priv, false))
-		goto out_unbind;
-	release_firmware(ucode_raw);
-	return;
-
- err_pci_alloc:
-	IWL_ERR(priv, "failed to allocate pci memory\n");
-	iwl_dealloc_ucode(trans(priv));
- out_unbind:
-	complete(&priv->firmware_loading_complete);
-	device_release_driver(bus(priv)->dev);
-	release_firmware(ucode_raw);
-}
-
 static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 {
 	struct iwl_ct_kill_config cmd;
@@ -1120,7 +556,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 	int ret = 0;
 
 	spin_lock_irqsave(&priv->shrd->lock, flags);
-	iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+	iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
 		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
 	spin_unlock_irqrestore(&priv->shrd->lock, flags);
 	priv->thermal_throttle.ct_kill_toggle = false;
@@ -1205,9 +641,6 @@ int iwl_alive_start(struct iwl_priv *priv)
 	int ret = 0;
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-	/*TODO: this should go to the transport layer */
-	iwl_reset_ict(trans(priv));
-
 	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 
 	/* After the ALIVE response, we can send host commands to the uCode */
@@ -1219,6 +652,11 @@ int iwl_alive_start(struct iwl_priv *priv)
 	if (iwl_is_rfkill(priv->shrd))
 		return -ERFKILL;
 
+	if (priv->event_log.ucode_trace) {
+		/* start collecting data now */
+		mod_timer(&priv->ucode_trace, jiffies);
+	}
+
 	/* download priority table before any calibration request */
 	if (cfg(priv)->bt_params &&
 	    cfg(priv)->bt_params->advanced_bt_coexist) {
@@ -1649,13 +1087,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
 #endif
 }
 
-
-
-static u32 iwl_hw_detect(struct iwl_priv *priv)
-{
-	return iwl_read32(bus(priv), CSR_HW_REV);
-}
-
 /* Size of one Rx buffer in host DRAM */
 #define IWL_RX_BUF_SIZE_4K (4 * 1024)
 #define IWL_RX_BUF_SIZE_8K (8 * 1024)
@@ -1687,32 +1118,32 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
 
 static void iwl_debug_config(struct iwl_priv *priv)
 {
-	dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
+	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG "
 #ifdef CONFIG_IWLWIFI_DEBUG
 		"enabled\n");
 #else
 		"disabled\n");
 #endif
-	dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
+	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS "
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 		"enabled\n");
 #else
 		"disabled\n");
 #endif
-	dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
+	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING "
 #ifdef CONFIG_IWLWIFI_DEVICE_TRACING
 		"enabled\n");
 #else
 		"disabled\n");
 #endif
 
-	dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
+	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
 #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
 		"enabled\n");
 #else
 		"disabled\n");
 #endif
-	dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P "
+	dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P "
 #ifdef CONFIG_IWLWIFI_P2P
 		"enabled\n");
 #else
@@ -1727,7 +1158,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 	struct iwl_priv *priv;
 	struct ieee80211_hw *hw;
 	u16 num_mac;
-	u32 hw_rev;
 
 	/************************
 	 * 1. Allocating HW data
@@ -1740,22 +1170,14 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 	}
 
 	priv = hw->priv;
-	priv->shrd = &priv->_shrd;
-	bus->shrd = priv->shrd;
-	priv->shrd->bus = bus;
+	priv->shrd = bus->shrd;
 	priv->shrd->priv = priv;
 
-	priv->shrd->trans = trans_ops->alloc(priv->shrd);
-	if (priv->shrd->trans == NULL) {
-		err = -ENOMEM;
-		goto out_free_traffic_mem;
-	}
-
 	/* At this point both hw and priv are allocated. */
 
-	SET_IEEE80211_DEV(hw, bus(priv)->dev);
+	SET_IEEE80211_DEV(hw, trans(priv)->dev);
 
-	/* what debugging capabilities we have */
+	/* show what debugging capabilities we have */
 	iwl_debug_config(priv);
 
 	IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
@@ -1778,41 +1200,29 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 	/* these spin locks will be used in apm_ops.init and EEPROM access
 	 * we should init now
 	 */
-	spin_lock_init(&bus(priv)->reg_lock);
+	spin_lock_init(&trans(priv)->reg_lock);
 	spin_lock_init(&priv->shrd->lock);
 
-	/*
-	 * stop and reset the on-board processor just in case it is in a
-	 * strange state ... like being left stranded by a primary kernel
-	 * and this is now the kdump kernel trying to start up
-	 */
-	iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
-
 	/***********************
 	 * 3. Read REV register
 	 ***********************/
-	hw_rev = iwl_hw_detect(priv);
 	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
-		cfg(priv)->name, hw_rev);
+		cfg(priv)->name, trans(priv)->hw_rev);
 
-	err = iwl_trans_request_irq(trans(priv));
+	err = iwl_trans_start_hw(trans(priv));
 	if (err)
-		goto out_free_trans;
-
-	if (iwl_trans_prepare_card_hw(trans(priv))) {
-		err = -EIO;
-		IWL_WARN(priv, "Failed, HW not ready\n");
-		goto out_free_trans;
-	}
+		goto out_free_traffic_mem;
 
 	/*****************
 	 * 4. Read EEPROM
 	 *****************/
 	/* Read the EEPROM */
-	err = iwl_eeprom_init(priv, hw_rev);
+	err = iwl_eeprom_init(priv, trans(priv)->hw_rev);
+	/* Reset chip to save power until we load uCode during "up". */
+	iwl_trans_stop_hw(trans(priv));
 	if (err) {
 		IWL_ERR(priv, "Unable to init EEPROM\n");
-		goto out_free_trans;
+		goto out_free_traffic_mem;
 	}
 	err = iwl_eeprom_check_version(priv);
 	if (err)
@@ -1860,22 +1270,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
 	iwl_setup_rx_handlers(priv);
 	iwl_testmode_init(priv);
 
-	/*********************************************
-	 * 8. Enable interrupts
-	 *********************************************/
-
-	iwl_enable_rfkill_int(priv);
-
-	/* If platform's RF_KILL switch is NOT set to KILL */
-	if (iwl_read32(bus(priv),
-			CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-		clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
-	else
-		set_bit(STATUS_RF_KILL_HW, &priv->shrd->status);
-
-	wiphy_rfkill_set_hw_state(priv->hw->wiphy,
-		test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
-
 	iwl_power_initialize(priv);
 	iwl_tt_initialize(priv);
 
@@ -1893,8 +1287,6 @@ out_destroy_workqueue:
 	iwl_uninit_drv(priv);
 out_free_eeprom:
 	iwl_eeprom_free(priv->shrd);
-out_free_trans:
-	iwl_trans_free(trans(priv));
 out_free_traffic_mem:
 	iwl_free_traffic_mem(priv);
 	ieee80211_free_hw(priv->hw);
@@ -1938,8 +1330,6 @@ void __devexit iwl_remove(struct iwl_priv * priv)
 	priv->shrd->workqueue = NULL;
 	iwl_free_traffic_mem(priv);
 
-	iwl_trans_free(trans(priv));
-
 	iwl_uninit_drv(priv);
 
 	dev_kfree_skb(priv->beacon_skb);
@@ -2054,7 +1444,7 @@ MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
 
 module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO);
 MODULE_PARM_DESC(led_mode, "0=system default, "
-		"1=On(RF On)/Off(RF Off), 2=blinking (default: 0)");
+		"1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)");
 
 module_param_named(power_save, iwlagn_mod_params.power_save,
 		bool, S_IRUGO);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index f84fb3c..37c325f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -73,8 +73,6 @@ struct iwlagn_ucode_capabilities {
 
 extern struct ieee80211_ops iwlagn_hw_ops;
 
-int iwl_reset_ict(struct iwl_trans *trans);
-
 static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
 {
 	hdr->op_code = cmd;
@@ -109,6 +107,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf,
 int iwlagn_rx_calib_result(struct iwl_priv *priv,
 			    struct iwl_rx_mem_buffer *rxb,
 			    struct iwl_device_cmd *cmd);
+void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags);
 
 /* lib */
 int iwlagn_send_tx_power(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h
index 940d503..30965e0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-bus.h
+++ b/drivers/net/wireless/iwlwifi/iwl-bus.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -119,87 +119,23 @@ struct iwl_shared;
 struct iwl_bus;
 
 /**
- * struct iwl_bus_ops - bus specific operations
- * @get_pm_support: must returns true if the bus can go to sleep
- * @apm_config: will be called during the config of the APM
- * @get_hw_id_string: prints the hw_id in the provided buffer
- * @get_hw_id: get hw_id in u32
- * @write8: write a byte to register at offset ofs
- * @write32: write a dword to register at offset ofs
- * @wread32: read a dword at register at offset ofs
- */
-struct iwl_bus_ops {
-	bool (*get_pm_support)(struct iwl_bus *bus);
-	void (*apm_config)(struct iwl_bus *bus);
-	void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len);
-	u32 (*get_hw_id)(struct iwl_bus *bus);
-	void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
-	void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
-	u32 (*read32)(struct iwl_bus *bus, u32 ofs);
-};
-
-/**
  * struct iwl_bus - bus common data
  *
  * This data is common to all bus layer implementations.
  *
- * @dev - pointer to struct device * that represents the device
  * @ops - pointer to iwl_bus_ops
  * @shrd - pointer to iwl_shared which holds shared data from the upper layer
  *	NB: for the time being this needs to be set by the upper layer since
  *	it allocates the shared data
- * @irq - the irq number for the device
- * @reg_lock - protect hw register access
  */
 struct iwl_bus {
-	struct device *dev;
-	const struct iwl_bus_ops *ops;
 	struct iwl_shared *shrd;
 
-	unsigned int irq;
-	spinlock_t reg_lock;
-
 	/* pointer to bus specific struct */
 	/*Ensure that this pointer will always be aligned to sizeof pointer */
 	char bus_specific[0] __attribute__((__aligned__(sizeof(void *))));
 };
 
-static inline bool bus_get_pm_support(struct iwl_bus *bus)
-{
-	return bus->ops->get_pm_support(bus);
-}
-
-static inline void bus_apm_config(struct iwl_bus *bus)
-{
-	bus->ops->apm_config(bus);
-}
-
-static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[],
-		int buf_len)
-{
-	bus->ops->get_hw_id_string(bus, buf, buf_len);
-}
-
-static inline u32 bus_get_hw_id(struct iwl_bus *bus)
-{
-	return bus->ops->get_hw_id(bus);
-}
-
-static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val)
-{
-	bus->ops->write8(bus, ofs, val);
-}
-
-static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val)
-{
-	bus->ops->write32(bus, ofs, val);
-}
-
-static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs)
-{
-	return bus->ops->read32(bus, ofs);
-}
-
 /*****************************************************
 * Bus layer registration functions
 ******************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h
index e1d7825..957bc00 100644
--- a/drivers/net/wireless/iwlwifi/iwl-cfg.h
+++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index f822ac4..c20618d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7bcfa78..0677b3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -203,10 +203,9 @@ int iwl_init_geos(struct iwl_priv *priv)
 
 	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
 	     cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) {
-		char buf[32];
-		bus_get_hw_id_string(bus(priv), buf, sizeof(buf));
 		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
-			"Please send your %s to maintainer.\n", buf);
+			"Please send your %s to maintainer.\n",
+			trans(priv)->hw_id_str);
 		cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
 	}
 
@@ -883,129 +882,6 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
 	}
 }
 
-static int iwl_apm_stop_master(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	/* stop device's busmaster DMA activity */
-	iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
-
-	ret = iwl_poll_bit(bus(priv), CSR_RESET,
-			CSR_RESET_REG_FLAG_MASTER_DISABLED,
-			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
-	if (ret)
-		IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n");
-
-	IWL_DEBUG_INFO(priv, "stop master\n");
-
-	return ret;
-}
-
-void iwl_apm_stop(struct iwl_priv *priv)
-{
-	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
-
-	clear_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status);
-
-	/* Stop device's DMA activity */
-	iwl_apm_stop_master(priv);
-
-	/* Reset the entire device */
-	iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-
-	udelay(10);
-
-	/*
-	 * Clear "initialization complete" bit to move adapter from
-	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
-	 */
-	iwl_clear_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-}
-
-
-/*
- * Start up NIC's basic functionality after it has been reset
- * (e.g. after platform boot, or shutdown via iwl_apm_stop())
- * NOTE:  This does not load uCode nor start the embedded processor
- */
-int iwl_apm_init(struct iwl_priv *priv)
-{
-	int ret = 0;
-	IWL_DEBUG_INFO(priv, "Init card's basic functions\n");
-
-	/*
-	 * Use "set_bit" below rather than "write", to preserve any hardware
-	 * bits already set by default after reset.
-	 */
-
-	/* Disable L0S exit timer (platform NMI Work/Around) */
-	iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
-	/*
-	 * Disable L0s without affecting L1;
-	 *  don't wait for ICH L0s (ICH bug W/A)
-	 */
-	iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS,
-			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
-	/* Set FH wait threshold to maximum (HW error during stress W/A) */
-	iwl_set_bit(bus(priv), CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
-
-	/*
-	 * Enable HAP INTA (interrupt from management bus) to
-	 * wake device's PCI Express link L1a -> L0s
-	 */
-	iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
-				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
-
-	bus_apm_config(bus(priv));
-
-	/* Configure analog phase-lock-loop before activating to D0A */
-	if (cfg(priv)->base_params->pll_cfg_val)
-		iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG,
-			    cfg(priv)->base_params->pll_cfg_val);
-
-	/*
-	 * Set "initialization complete" bit to move adapter from
-	 * D0U* --> D0A* (powered-up active) state.
-	 */
-	iwl_set_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
-	/*
-	 * Wait for clock stabilization; once stabilized, access to
-	 * device-internal resources is supported, e.g. iwl_write_prph()
-	 * and accesses to uCode SRAM.
-	 */
-	ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
-	if (ret < 0) {
-		IWL_DEBUG_INFO(priv, "Failed to init the card\n");
-		goto out;
-	}
-
-	/*
-	 * Enable DMA clock and wait for it to stabilize.
-	 *
-	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
-	 * do not disable clocks.  This preserves any hardware bits already
-	 * set by default in "CLK_CTRL_REG" after reset.
-	 */
-	iwl_write_prph(bus(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-	udelay(20);
-
-	/* Disable L1-Active */
-	iwl_set_bits_prph(bus(priv), APMG_PCIDEV_STT_REG,
-			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-	set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status);
-
-out:
-	return ret;
-}
-
-
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 {
 	int ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7bf76ab..8d60dcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -297,12 +297,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
 	       cfg(priv)->bt_params->advanced_bt_coexist;
 }
 
-static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
-{
-	IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
-	iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
-}
-
 extern bool bt_siso_mode;
 
 #endif /* __iwl_core_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index fbc3095..5f96ce1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index f8fc239..351b41d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -35,10 +35,10 @@
 struct iwl_priv;
 
 /*No matter what is m (priv, bus, trans), this will work */
-#define IWL_ERR(m, f, a...) dev_err(bus(m)->dev, f, ## a)
-#define IWL_WARN(m, f, a...) dev_warn(bus(m)->dev, f, ## a)
-#define IWL_INFO(m, f, a...) dev_info(bus(m)->dev, f, ## a)
-#define IWL_CRIT(m, f, a...) dev_crit(bus(m)->dev, f, ## a)
+#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a)
+#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a)
+#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a)
+#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a)
 
 #define iwl_print_hex_error(m, p, len)					\
 do {									\
@@ -50,7 +50,7 @@ do {									\
 #define IWL_DEBUG(m, level, fmt, ...)					\
 do {									\
 	if (iwl_get_debug_level((m)->shrd) & (level))			\
-		dev_err(bus(m)->dev, "%c %s " fmt,			\
+		dev_err(trans(m)->dev, "%c %s " fmt,			\
 			in_interrupt() ? 'I' : 'U', __func__,		\
 			##__VA_ARGS__);					\
 } while (0)
@@ -59,7 +59,7 @@ do {									\
 do {									\
 	if (iwl_get_debug_level((m)->shrd) & (level) &&			\
 	    net_ratelimit())						\
-		dev_err(bus(m)->dev, "%c %s " fmt,			\
+		dev_err(trans(m)->dev, "%c %s " fmt,			\
 			in_interrupt() ? 'I' : 'U', __func__,		\
 			##__VA_ARGS__);					\
 } while (0)
@@ -74,12 +74,12 @@ do {                                            			\
 #define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...)				\
 do {									\
 	if (!iwl_is_rfkill(p->shrd))					\
-		dev_err(bus(p)->dev, "%s%c %s " fmt,			\
+		dev_err(trans(p)->dev, "%s%c %s " fmt,			\
 			"",						\
 			in_interrupt() ? 'I' : 'U', __func__,		\
 			##__VA_ARGS__);					\
 	else if	(iwl_get_debug_level(p->shrd) & IWL_DL_RADIO)		\
-		dev_err(bus(p)->dev, "%s%c %s " fmt,			\
+		dev_err(trans(p)->dev, "%s%c %s " fmt,			\
 			"(RFKILL) ",					\
 			in_interrupt() ? 'I' : 'U', __func__,		\
 			##__VA_ARGS__);					\
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 04a3343..136de6f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -263,7 +263,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
 	sram = priv->dbgfs_sram_offset & ~0x3;
 
 	/* read the first u32 from sram */
-	val = iwl_read_targ_mem(bus(priv), sram);
+	val = iwl_read_targ_mem(trans(priv), sram);
 
 	for (; len; len--) {
 		/* put the address at the start of every line */
@@ -282,7 +282,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
 		if (++offset == 4) {
 			sram += 4;
 			offset = 0;
-			val = iwl_read_targ_mem(bus(priv), sram);
+			val = iwl_read_targ_mem(trans(priv), sram);
 		}
 
 		/* put in extra spaces and split lines for human readability */
@@ -2055,7 +2055,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
 	const size_t bufsz = sizeof(buf);
 	u32 pwrsave_status;
 
-	pwrsave_status = iwl_read32(bus(priv), CSR_GP_CNTRL) &
+	pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) &
 			CSR_GP_REG_POWER_SAVE_STATUS_MSK;
 
 	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
@@ -2131,9 +2131,10 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
 
 	if (trace) {
 		priv->event_log.ucode_trace = true;
-		/* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
-		mod_timer(&priv->ucode_trace,
-			jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
+		if (iwl_is_alive(priv->shrd)) {
+			/* start collecting data now */
+			mod_timer(&priv->ucode_trace, jiffies);
+		}
 	} else {
 		priv->event_log.ucode_trace = false;
 		del_timer_sync(&priv->ucode_trace);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index e54a4d1..aa99457 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -292,114 +292,6 @@ struct iwl_vif_priv {
 	u8 ibss_bssid_sta_id;
 };
 
-/* v1/v2 uCode file layout */
-struct iwl_ucode_header {
-	__le32 ver;	/* major/minor/API/serial */
-	union {
-		struct {
-			__le32 inst_size;	/* bytes of runtime code */
-			__le32 data_size;	/* bytes of runtime data */
-			__le32 init_size;	/* bytes of init code */
-			__le32 init_data_size;	/* bytes of init data */
-			__le32 boot_size;	/* bytes of bootstrap code */
-			u8 data[0];		/* in same order as sizes */
-		} v1;
-		struct {
-			__le32 build;		/* build number */
-			__le32 inst_size;	/* bytes of runtime code */
-			__le32 data_size;	/* bytes of runtime data */
-			__le32 init_size;	/* bytes of init code */
-			__le32 init_data_size;	/* bytes of init data */
-			__le32 boot_size;	/* bytes of bootstrap code */
-			u8 data[0];		/* in same order as sizes */
-		} v2;
-	} u;
-};
-
-/*
- * new TLV uCode file layout
- *
- * The new TLV file format contains TLVs, that each specify
- * some piece of data. To facilitate "groups", for example
- * different instruction image with different capabilities,
- * bundled with the same init image, an alternative mechanism
- * is provided:
- * When the alternative field is 0, that means that the item
- * is always valid. When it is non-zero, then it is only
- * valid in conjunction with items of the same alternative,
- * in which case the driver (user) selects one alternative
- * to use.
- */
-
-enum iwl_ucode_tlv_type {
-	IWL_UCODE_TLV_INVALID		= 0, /* unused */
-	IWL_UCODE_TLV_INST		= 1,
-	IWL_UCODE_TLV_DATA		= 2,
-	IWL_UCODE_TLV_INIT		= 3,
-	IWL_UCODE_TLV_INIT_DATA		= 4,
-	IWL_UCODE_TLV_BOOT		= 5,
-	IWL_UCODE_TLV_PROBE_MAX_LEN	= 6, /* a u32 value */
-	IWL_UCODE_TLV_PAN		= 7,
-	IWL_UCODE_TLV_RUNT_EVTLOG_PTR	= 8,
-	IWL_UCODE_TLV_RUNT_EVTLOG_SIZE	= 9,
-	IWL_UCODE_TLV_RUNT_ERRLOG_PTR	= 10,
-	IWL_UCODE_TLV_INIT_EVTLOG_PTR	= 11,
-	IWL_UCODE_TLV_INIT_EVTLOG_SIZE	= 12,
-	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13,
-	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14,
-	IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
-	IWL_UCODE_TLV_WOWLAN_INST	= 16,
-	IWL_UCODE_TLV_WOWLAN_DATA	= 17,
-	IWL_UCODE_TLV_FLAGS		= 18,
-};
-
-/**
- * enum iwl_ucode_tlv_flag - ucode API flags
- * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
- *	was a separate TLV but moved here to save space.
- * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
- *	treats good CRC threshold as a boolean
- * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
- * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
- */
-enum iwl_ucode_tlv_flag {
-	IWL_UCODE_TLV_FLAGS_PAN		= BIT(0),
-	IWL_UCODE_TLV_FLAGS_NEWSCAN	= BIT(1),
-	IWL_UCODE_TLV_FLAGS_MFP		= BIT(2),
-	IWL_UCODE_TLV_FLAGS_P2P		= BIT(3),
-};
-
-struct iwl_ucode_tlv {
-	__le16 type;		/* see above */
-	__le16 alternative;	/* see comment */
-	__le32 length;		/* not including type/length fields */
-	u8 data[0];
-} __packed;
-
-#define IWL_TLV_UCODE_MAGIC	0x0a4c5749
-
-struct iwl_tlv_ucode_header {
-	/*
-	 * The TLV style ucode header is distinguished from
-	 * the v1/v2 style header by first four bytes being
-	 * zero, as such is an invalid combination of
-	 * major/minor/API/serial versions.
-	 */
-	__le32 zero;
-	__le32 magic;
-	u8 human_readable[64];
-	__le32 ver;		/* major/minor/API/serial */
-	__le32 build;
-	__le64 alternatives;	/* bitmask of valid alternatives */
-	/*
-	 * The data contained herein has a TLV layout,
-	 * see above for the TLV header and types.
-	 * Note that each TLV is padded to a length
-	 * that is a multiple of 4 for alignment.
-	 */
-	u8 data[0];
-};
-
 struct iwl_sensitivity_ranges {
 	u16 min_nrg_cck;
 	u16 max_nrg_cck;
@@ -661,7 +553,7 @@ struct traffic_stats {
  * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
  * to perform continuous uCode event logging operation if enabled
  */
-#define UCODE_TRACE_PERIOD (100)
+#define UCODE_TRACE_PERIOD (10)
 
 /*
  * iwl_event_log: current uCode event log position
@@ -821,7 +713,6 @@ struct iwl_wipan_noa_data {
 struct iwl_priv {
 
 	/*data shared among all the driver's layers */
-	struct iwl_shared _shrd;
 	struct iwl_shared *shrd;
 
 	/* ieee device used by generic ieee processing code */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 2a2c8de..91f45e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 9b212a8..4d89221 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index c1eda97..d1fd1cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -156,16 +156,16 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
 
 	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
 		/* Request semaphore */
-		iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG,
+		iwl_set_bit(trans(bus), CSR_HW_IF_CONFIG_REG,
 			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
 
 		/* See if we got it */
-		ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG,
+		ret = iwl_poll_bit(trans(bus), CSR_HW_IF_CONFIG_REG,
 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
 				EEPROM_SEM_TIMEOUT);
 		if (ret >= 0) {
-			IWL_DEBUG_EEPROM(bus,
+			IWL_DEBUG_EEPROM(trans(bus),
 				"Acquired semaphore after %d tries.\n",
 				count+1);
 			return ret;
@@ -177,14 +177,15 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus)
 
 static void iwl_eeprom_release_semaphore(struct iwl_bus *bus)
 {
-	iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG,
+	iwl_clear_bit(trans(bus), CSR_HW_IF_CONFIG_REG,
 		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
 
 }
 
 static int iwl_eeprom_verify_signature(struct iwl_trans *trans)
 {
-	u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
+	u32 gp = iwl_read32(trans, CSR_EEPROM_GP) &
+			   CSR_EEPROM_GP_VALID_MSK;
 	int ret = 0;
 
 	IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp);
@@ -305,13 +306,13 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac)
 
 static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode)
 {
-	iwl_read32(bus, CSR_OTP_GP_REG);
+	iwl_read32(trans(bus), CSR_OTP_GP_REG);
 
 	if (mode == IWL_OTP_ACCESS_ABSOLUTE)
-		iwl_clear_bit(bus, CSR_OTP_GP_REG,
+		iwl_clear_bit(trans(bus), CSR_OTP_GP_REG,
 			      CSR_OTP_GP_REG_OTP_ACCESS_MODE);
 	else
-		iwl_set_bit(bus, CSR_OTP_GP_REG,
+		iwl_set_bit(trans(bus), CSR_OTP_GP_REG,
 			    CSR_OTP_GP_REG_OTP_ACCESS_MODE);
 }
 
@@ -332,7 +333,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev)
 		nvm_type = NVM_DEVICE_TYPE_EEPROM;
 		break;
 	default:
-		otpgp = iwl_read32(bus, CSR_OTP_GP_REG);
+		otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG);
 		if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
 			nvm_type = NVM_DEVICE_TYPE_OTP;
 		else
@@ -347,22 +348,22 @@ static int iwl_init_otp_access(struct iwl_bus *bus)
 	int ret;
 
 	/* Enable 40MHz radio clock */
-	iwl_write32(bus, CSR_GP_CNTRL,
-		    iwl_read32(bus, CSR_GP_CNTRL) |
+	iwl_write32(trans(bus), CSR_GP_CNTRL,
+		    iwl_read32(trans(bus), CSR_GP_CNTRL) |
 		    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
 	/* wait for clock to be ready */
-	ret = iwl_poll_bit(bus, CSR_GP_CNTRL,
+	ret = iwl_poll_bit(trans(bus), CSR_GP_CNTRL,
 				 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 				 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 				 25000);
 	if (ret < 0)
 		IWL_ERR(bus, "Time out access OTP\n");
 	else {
-		iwl_set_bits_prph(bus, APMG_PS_CTRL_REG,
+		iwl_set_bits_prph(trans(bus), APMG_PS_CTRL_REG,
 				  APMG_PS_CTRL_VAL_RESET_REQ);
 		udelay(5);
-		iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG,
+		iwl_clear_bits_prph(trans(bus), APMG_PS_CTRL_REG,
 				    APMG_PS_CTRL_VAL_RESET_REQ);
 
 		/*
@@ -370,7 +371,7 @@ static int iwl_init_otp_access(struct iwl_bus *bus)
 		 * this is only applicable for HW with OTP shadow RAM
 		 */
 		if (cfg(bus)->base_params->shadow_ram_support)
-			iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG,
+			iwl_set_bit(trans(bus), CSR_DBG_LINK_PWR_MGMT_REG,
 				CSR_RESET_LINK_PWR_MGMT_DISABLED);
 	}
 	return ret;
@@ -382,9 +383,9 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data)
 	u32 r;
 	u32 otpgp;
 
-	iwl_write32(bus, CSR_EEPROM_REG,
+	iwl_write32(trans(bus), CSR_EEPROM_REG,
 		    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-	ret = iwl_poll_bit(bus, CSR_EEPROM_REG,
+	ret = iwl_poll_bit(trans(bus), CSR_EEPROM_REG,
 				 CSR_EEPROM_REG_READ_VALID_MSK,
 				 CSR_EEPROM_REG_READ_VALID_MSK,
 				 IWL_EEPROM_ACCESS_TIMEOUT);
@@ -392,13 +393,13 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data)
 		IWL_ERR(bus, "Time out reading OTP[%d]\n", addr);
 		return ret;
 	}
-	r = iwl_read32(bus, CSR_EEPROM_REG);
+	r = iwl_read32(trans(bus), CSR_EEPROM_REG);
 	/* check for ECC errors: */
-	otpgp = iwl_read32(bus, CSR_OTP_GP_REG);
+	otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG);
 	if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
 		/* stop in this case */
 		/* set the uncorrectable OTP ECC bit for acknowledgement */
-		iwl_set_bit(bus, CSR_OTP_GP_REG,
+		iwl_set_bit(trans(bus), CSR_OTP_GP_REG,
 			CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
 		IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n");
 		return -EINVAL;
@@ -406,7 +407,7 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data)
 	if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
 		/* continue in this case */
 		/* set the correctable OTP ECC bit for acknowledgement */
-		iwl_set_bit(bus, CSR_OTP_GP_REG,
+		iwl_set_bit(trans(bus), CSR_OTP_GP_REG,
 				CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
 		IWL_ERR(bus, "Correctable OTP ECC error, continue read\n");
 	}
@@ -656,7 +657,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 {
 	struct iwl_shared *shrd = priv->shrd;
 	__le16 *e;
-	u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP);
+	u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP);
 	int sz;
 	int ret;
 	u16 addr;
@@ -676,8 +677,6 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 	}
 	e = (__le16 *)shrd->eeprom;
 
-	iwl_apm_init(priv);
-
 	ret = iwl_eeprom_verify_signature(trans(priv));
 	if (ret < 0) {
 		IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
@@ -701,11 +700,11 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 			ret = -ENOENT;
 			goto done;
 		}
-		iwl_write32(bus(priv), CSR_EEPROM_GP,
-			    iwl_read32(bus(priv), CSR_EEPROM_GP) &
+		iwl_write32(trans(priv), CSR_EEPROM_GP,
+			    iwl_read32(trans(priv), CSR_EEPROM_GP) &
 			    ~CSR_EEPROM_GP_IF_OWNER_MSK);
 
-		iwl_set_bit(bus(priv), CSR_OTP_GP_REG,
+		iwl_set_bit(trans(priv), CSR_OTP_GP_REG,
 			     CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
 			     CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
 		/* traversing the linked list if no shadow ram supported */
@@ -730,10 +729,10 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 		for (addr = 0; addr < sz; addr += sizeof(u16)) {
 			u32 r;
 
-			iwl_write32(bus(priv), CSR_EEPROM_REG,
+			iwl_write32(trans(priv), CSR_EEPROM_REG,
 				    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
 
-			ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG,
+			ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG,
 						  CSR_EEPROM_REG_READ_VALID_MSK,
 						  CSR_EEPROM_REG_READ_VALID_MSK,
 						  IWL_EEPROM_ACCESS_TIMEOUT);
@@ -741,7 +740,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 				IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
 				goto done;
 			}
-			r = iwl_read32(bus(priv), CSR_EEPROM_REG);
+			r = iwl_read32(trans(priv), CSR_EEPROM_REG);
 			e[addr / 2] = cpu_to_le16(r >> 16);
 		}
 	}
@@ -758,8 +757,6 @@ done:
 err:
 	if (ret)
 		iwl_eeprom_free(priv->shrd);
-	/* Reset chip to save power until we load uCode during "up". */
-	iwl_apm_stop(priv);
 alloc_err:
 	return ret;
 }
@@ -1072,7 +1069,7 @@ void iwl_rf_config(struct iwl_priv *priv)
 
 	/* write radio config values to register */
 	if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
-		iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
+		iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
 			    EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
 			    EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
 			    EEPROM_RF_CFG_DASH_MSK(radio_cfg));
@@ -1084,7 +1081,7 @@ void iwl_rf_config(struct iwl_priv *priv)
 		WARN_ON(1);
 
 	/* set CSR_HW_CONFIG_REG for uCode use */
-	iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG,
+	iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG,
 		    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
 		    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 9fa937e..13f2d39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 5bede9d..9020809 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index d57ea64..e2e3b5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -34,41 +34,41 @@
 
 #define IWL_POLL_INTERVAL 10	/* microseconds */
 
-static inline void __iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
-	iwl_write32(bus, reg, iwl_read32(bus, reg) | mask);
+	iwl_write32(trans, reg, iwl_read32(trans, reg) | mask);
 }
 
-static inline void __iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
-	iwl_write32(bus, reg, iwl_read32(bus, reg) & ~mask);
+	iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask);
 }
 
-void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	__iwl_set_bit(bus, reg, mask);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	__iwl_set_bit(trans, reg, mask);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	__iwl_clear_bit(bus, reg, mask);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	__iwl_clear_bit(trans, reg, mask);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-int iwl_poll_bit(struct iwl_bus *bus, u32 addr,
+int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
 		 u32 bits, u32 mask, int timeout)
 {
 	int t = 0;
 
 	do {
-		if ((iwl_read32(bus, addr) & mask) == (bits & mask))
+		if ((iwl_read32(trans, addr) & mask) == (bits & mask))
 			return t;
 		udelay(IWL_POLL_INTERVAL);
 		t += IWL_POLL_INTERVAL;
@@ -77,14 +77,15 @@ int iwl_poll_bit(struct iwl_bus *bus, u32 addr,
 	return -ETIMEDOUT;
 }
 
-int iwl_grab_nic_access_silent(struct iwl_bus *bus)
+int iwl_grab_nic_access_silent(struct iwl_trans *trans)
 {
 	int ret;
 
-	lockdep_assert_held(&bus->reg_lock);
+	lockdep_assert_held(&trans->reg_lock);
 
 	/* this bit wakes up the NIC */
-	__iwl_set_bit(bus, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+	__iwl_set_bit(trans, CSR_GP_CNTRL,
+		      CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
 	/*
 	 * These bits say the device is running, and should keep running for
@@ -105,70 +106,70 @@ int iwl_grab_nic_access_silent(struct iwl_bus *bus)
 	 * 5000 series and later (including 1000 series) have non-volatile SRAM,
 	 * and do not save/restore SRAM when power cycling.
 	 */
-	ret = iwl_poll_bit(bus, CSR_GP_CNTRL,
+	ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
 			   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
 			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
 			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
 	if (ret < 0) {
-		iwl_write32(bus, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+		iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
 		return -EIO;
 	}
 
 	return 0;
 }
 
-int iwl_grab_nic_access(struct iwl_bus *bus)
+int iwl_grab_nic_access(struct iwl_trans *trans)
 {
-	int ret = iwl_grab_nic_access_silent(bus);
+	int ret = iwl_grab_nic_access_silent(trans);
 	if (ret) {
-		u32 val = iwl_read32(bus, CSR_GP_CNTRL);
-		IWL_ERR(bus,
+		u32 val = iwl_read32(trans, CSR_GP_CNTRL);
+		IWL_ERR(trans,
 			"MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
 	}
 
 	return ret;
 }
 
-void iwl_release_nic_access(struct iwl_bus *bus)
+void iwl_release_nic_access(struct iwl_trans *trans)
 {
-	lockdep_assert_held(&bus->reg_lock);
-	__iwl_clear_bit(bus, CSR_GP_CNTRL,
+	lockdep_assert_held(&trans->reg_lock);
+	__iwl_clear_bit(trans, CSR_GP_CNTRL,
 			CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 }
 
-u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg)
+u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
 {
 	u32 value;
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	iwl_grab_nic_access(bus);
-	value = iwl_read32(bus, reg);
-	iwl_release_nic_access(bus);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	iwl_grab_nic_access(trans);
+	value = iwl_read32(trans, reg);
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 
 	return value;
 }
 
-void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value)
+void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	if (!iwl_grab_nic_access(bus)) {
-		iwl_write32(bus, reg, value);
-		iwl_release_nic_access(bus);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	if (!iwl_grab_nic_access(trans)) {
+		iwl_write32(trans, reg, value);
+		iwl_release_nic_access(trans);
 	}
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask,
+int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
 			int timeout)
 {
 	int t = 0;
 
 	do {
-		if ((iwl_read_direct32(bus, addr) & mask) == mask)
+		if ((iwl_read_direct32(trans, addr) & mask) == mask)
 			return t;
 		udelay(IWL_POLL_INTERVAL);
 		t += IWL_POLL_INTERVAL;
@@ -177,135 +178,135 @@ int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask,
 	return -ETIMEDOUT;
 }
 
-static inline u32 __iwl_read_prph(struct iwl_bus *bus, u32 reg)
+static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg)
 {
-	iwl_write32(bus, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+	iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
 	rmb();
-	return iwl_read32(bus, HBUS_TARG_PRPH_RDAT);
+	return iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
 }
 
-static inline void __iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val)
+static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
 {
-	iwl_write32(bus, HBUS_TARG_PRPH_WADDR,
+	iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
 		    ((addr & 0x0000FFFF) | (3 << 24)));
 	wmb();
-	iwl_write32(bus, HBUS_TARG_PRPH_WDAT, val);
+	iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
 }
 
-u32 iwl_read_prph(struct iwl_bus *bus, u32 reg)
+u32 iwl_read_prph(struct iwl_trans *trans, u32 reg)
 {
 	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	iwl_grab_nic_access(bus);
-	val = __iwl_read_prph(bus, reg);
-	iwl_release_nic_access(bus);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	iwl_grab_nic_access(trans);
+	val = __iwl_read_prph(trans, reg);
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 	return val;
 }
 
-void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val)
+void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	if (!iwl_grab_nic_access(bus)) {
-		__iwl_write_prph(bus, addr, val);
-		iwl_release_nic_access(bus);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	if (!iwl_grab_nic_access(trans)) {
+		__iwl_write_prph(trans, addr, val);
+		iwl_release_nic_access(trans);
 	}
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	iwl_grab_nic_access(bus);
-	__iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask);
-	iwl_release_nic_access(bus);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	iwl_grab_nic_access(trans);
+	__iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask);
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg,
+void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
 			    u32 bits, u32 mask)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	iwl_grab_nic_access(bus);
-	__iwl_write_prph(bus, reg,
-			 (__iwl_read_prph(bus, reg) & mask) | bits);
-	iwl_release_nic_access(bus);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	iwl_grab_nic_access(trans);
+	__iwl_write_prph(trans, reg,
+			 (__iwl_read_prph(trans, reg) & mask) | bits);
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask)
+void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask)
 {
 	unsigned long flags;
 	u32 val;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	iwl_grab_nic_access(bus);
-	val = __iwl_read_prph(bus, reg);
-	__iwl_write_prph(bus, reg, (val & ~mask));
-	iwl_release_nic_access(bus);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	iwl_grab_nic_access(trans);
+	val = __iwl_read_prph(trans, reg);
+	__iwl_write_prph(trans, reg, (val & ~mask));
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr,
+void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
 			      void *buf, int words)
 {
 	unsigned long flags;
 	int offs;
 	u32 *vals = buf;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	iwl_grab_nic_access(bus);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	iwl_grab_nic_access(trans);
 
-	iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr);
+	iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
 	rmb();
 
 	for (offs = 0; offs < words; offs++)
-		vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT);
+		vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
 
-	iwl_release_nic_access(bus);
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 }
 
-u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr)
+u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr)
 {
 	u32 value;
 
-	_iwl_read_targ_mem_words(bus, addr, &value, 1);
+	_iwl_read_targ_mem_words(trans, addr, &value, 1);
 
 	return value;
 }
 
-int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr,
+int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
 				void *buf, int words)
 {
 	unsigned long flags;
 	int offs, result = 0;
 	u32 *vals = buf;
 
-	spin_lock_irqsave(&bus->reg_lock, flags);
-	if (!iwl_grab_nic_access(bus)) {
-		iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr);
+	spin_lock_irqsave(&trans->reg_lock, flags);
+	if (!iwl_grab_nic_access(trans)) {
+		iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
 		wmb();
 
 		for (offs = 0; offs < words; offs++)
-			iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]);
-		iwl_release_nic_access(bus);
+			iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
+		iwl_release_nic_access(trans);
 	} else
 		result = -EBUSY;
-	spin_unlock_irqrestore(&bus->reg_lock, flags);
+	spin_unlock_irqrestore(&trans->reg_lock, flags);
 
 	return result;
 }
 
-int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val)
+int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val)
 {
-	return _iwl_write_targ_mem_words(bus, addr, &val, 1);
+	return _iwl_write_targ_mem_words(trans, addr, &val, 1);
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index aae2eeb..782486f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -31,63 +31,63 @@
 
 #include "iwl-devtrace.h"
 #include "iwl-shared.h"
-#include "iwl-bus.h"
+#include "iwl-trans.h"
 
-static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val)
+static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
 {
-	trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val);
-	bus_write8(bus, ofs, val);
+	trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val);
+	iwl_trans_write8(trans, ofs, val);
 }
 
-static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val)
+static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val)
 {
-	trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val);
-	bus_write32(bus, ofs, val);
+	trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val);
+	iwl_trans_write32(trans, ofs, val);
 }
 
-static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs)
+static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs)
 {
-	u32 val = bus_read32(bus, ofs);
-	trace_iwlwifi_dev_ioread32(priv(bus), ofs, val);
+	u32 val = iwl_trans_read32(trans, ofs);
+	trace_iwlwifi_dev_ioread32(priv(trans), ofs, val);
 	return val;
 }
 
-void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask);
-void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask);
+void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask);
+void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask);
 
-int iwl_poll_bit(struct iwl_bus *bus, u32 addr,
+int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
 		 u32 bits, u32 mask, int timeout);
-int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask,
+int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
 			int timeout);
 
-int iwl_grab_nic_access_silent(struct iwl_bus *bus);
-int iwl_grab_nic_access(struct iwl_bus *bus);
-void iwl_release_nic_access(struct iwl_bus *bus);
+int iwl_grab_nic_access_silent(struct iwl_trans *trans);
+int iwl_grab_nic_access(struct iwl_trans *trans);
+void iwl_release_nic_access(struct iwl_trans *trans);
 
-u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg);
-void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value);
+u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
+void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value);
 
 
-u32 iwl_read_prph(struct iwl_bus *bus, u32 reg);
-void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val);
-void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask);
-void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg,
+u32 iwl_read_prph(struct iwl_trans *trans, u32 reg);
+void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val);
+void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask);
+void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg,
 			    u32 bits, u32 mask);
-void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask);
+void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask);
 
-void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr,
+void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr,
 			      void *buf, int words);
 
-#define iwl_read_targ_mem_words(bus, addr, buf, bufsize)	\
+#define iwl_read_targ_mem_words(trans, addr, buf, bufsize)	\
 	do {							\
 		BUILD_BUG_ON((bufsize) % sizeof(u32));		\
-		_iwl_read_targ_mem_words(bus, addr, buf,	\
+		_iwl_read_targ_mem_words(trans, addr, buf,	\
 					 (bufsize) / sizeof(u32));\
 	} while (0)
 
-int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr,
+int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr,
 			      void *buf, int words);
 
-u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr);
-int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val);
+u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr);
+int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val);
 #endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 14dcbfc..5c7741f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -71,7 +71,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = {
 /* Set led register off */
 void iwlagn_led_enable(struct iwl_priv *priv)
 {
-	iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON);
+	iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON);
 }
 
 /*
@@ -107,9 +107,10 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
 	};
 	u32 reg;
 
-	reg = iwl_read32(bus(priv), CSR_LED_REG);
+	reg = iwl_read32(trans(priv), CSR_LED_REG);
 	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
-		iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+		iwl_write32(trans(priv), CSR_LED_REG,
+			    reg & CSR_LED_BSM_CTRL_MSK);
 
 	return iwl_trans_send_cmd(trans(priv), &cmd);
 }
@@ -177,6 +178,10 @@ void iwl_leds_init(struct iwl_priv *priv)
 	int mode = iwlagn_mod_params.led_mode;
 	int ret;
 
+	if (mode == IWL_LED_DISABLE) {
+		IWL_INFO(priv, "Led disabled\n");
+		return;
+	}
 	if (mode == IWL_LED_DEFAULT)
 		mode = cfg(priv)->led_mode;
 
@@ -202,7 +207,7 @@ void iwl_leds_init(struct iwl_priv *priv)
 		break;
 	}
 
-	ret = led_classdev_register(bus(priv)->dev, &priv->led);
+	ret = led_classdev_register(trans(priv)->dev, &priv->led);
 	if (ret) {
 		kfree(priv->led.name);
 		return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 2550b3c..b02a853 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index f980e57..d8025fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -35,7 +35,6 @@
 #include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
@@ -43,6 +42,7 @@
 
 #include <asm/div64.h>
 
+#include "iwl-ucode.h"
 #include "iwl-eeprom.h"
 #include "iwl-wifi.h"
 #include "iwl-dev.h"
@@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 			    WIPHY_FLAG_IBSS_RSN;
 
 	if (trans(priv)->ucode_wowlan.code.len &&
-	    device_can_wakeup(bus(priv)->dev)) {
+	    device_can_wakeup(trans(priv)->dev)) {
 		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
 					  WIPHY_WOWLAN_DISCONNECT |
 					  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
@@ -234,7 +234,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 		priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 			&priv->bands[IEEE80211_BAND_5GHZ];
 
-	hw->wiphy->hw_version = bus_get_hw_id(bus(priv));
+	hw->wiphy->hw_version = trans(priv)->hw_id;
 
 	iwl_leds_init(priv);
 
@@ -346,9 +346,10 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 	flush_workqueue(priv->shrd->workqueue);
 
 	/* User space software may expect getting rfkill changes
-	 * even if interface is down */
-	iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF);
-	iwl_enable_rfkill_int(priv);
+	 * even if interface is down, trans->down will leave the RF
+	 * kill interrupt enabled
+	 */
+	iwl_trans_stop_hw(trans(priv));
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
@@ -405,10 +406,10 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
 	if (ret)
 		goto error;
 
-	device_set_wakeup_enable(bus(priv)->dev, true);
+	device_set_wakeup_enable(trans(priv)->dev, true);
 
 	/* Now let the ucode operate on its own */
-	iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET,
+	iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET,
 			  CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
 
 	goto out;
@@ -436,19 +437,19 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 	mutex_lock(&priv->shrd->mutex);
 
-	iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
+	iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR,
 			  CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
 
 	base = priv->shrd->device_pointers.error_event_table;
 	if (iwlagn_hw_valid_rtc_data_addr(base)) {
-		spin_lock_irqsave(&bus(priv)->reg_lock, flags);
-		ret = iwl_grab_nic_access_silent(bus(priv));
+		spin_lock_irqsave(&trans(priv)->reg_lock, flags);
+		ret = iwl_grab_nic_access_silent(trans(priv));
 		if (ret == 0) {
-			iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base);
-			status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
-			iwl_release_nic_access(bus(priv));
+			iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base);
+			status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT);
+			iwl_release_nic_access(trans(priv));
 		}
-		spin_unlock_irqrestore(&bus(priv)->reg_lock, flags);
+		spin_unlock_irqrestore(&trans(priv)->reg_lock, flags);
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 		if (ret == 0) {
@@ -460,7 +461,8 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 
 			if (priv->wowlan_sram)
 				_iwl_read_targ_mem_words(
-					bus(priv), 0x800000, priv->wowlan_sram,
+					trans(priv), 0x800000,
+					priv->wowlan_sram,
 					trans->ucode_wowlan.data.len / 4);
 		}
 #endif
@@ -471,7 +473,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
 
 	priv->shrd->wowlan = false;
 
-	device_set_wakeup_enable(bus(priv)->dev, false);
+	device_set_wakeup_enable(trans(priv)->dev, false);
 
 	iwlagn_prepare_restart(priv);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c
index fb30ea7..3e2fce4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ b/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -71,112 +71,6 @@
 #include "iwl-csr.h"
 #include "iwl-cfg.h"
 
-/* PCI registers */
-#define PCI_CFG_RETRY_TIMEOUT	0x041
-#define PCI_CFG_LINK_CTRL_VAL_L0S_EN	0x01
-#define PCI_CFG_LINK_CTRL_VAL_L1_EN	0x02
-
-struct iwl_pci_bus {
-	/* basic pci-network driver stuff */
-	struct pci_dev *pci_dev;
-
-	/* pci hardware address support */
-	void __iomem *hw_base;
-};
-
-#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \
-			((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific))
-
-#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \
-			((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev)
-
-static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus)
-{
-	int pos;
-	u16 pci_lnk_ctl;
-
-	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-
-	pos = pci_pcie_cap(pci_dev);
-	pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
-	return pci_lnk_ctl;
-}
-
-static bool iwl_pci_is_pm_supported(struct iwl_bus *bus)
-{
-	u16 lctl = iwl_pciexp_link_ctrl(bus);
-
-	return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
-}
-
-static void iwl_pci_apm_config(struct iwl_bus *bus)
-{
-	/*
-	 * HW bug W/A for instability in PCIe bus L0S->L1 transition.
-	 * Check if BIOS (or OS) enabled L1-ASPM on this device.
-	 * If so (likely), disable L0S, so device moves directly L0->L1;
-	 *    costs negligible amount of power savings.
-	 * If not (unlikely), enable L0S, so there is at least some
-	 *    power savings, even without L1.
-	 */
-	u16 lctl = iwl_pciexp_link_ctrl(bus);
-
-	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
-				PCI_CFG_LINK_CTRL_VAL_L1_EN) {
-		/* L1-ASPM enabled; disable(!) L0S */
-		iwl_set_bit(bus, CSR_GIO_REG,
-				CSR_GIO_REG_VAL_L0S_ENABLED);
-		dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n");
-	} else {
-		/* L1-ASPM disabled; enable(!) L0S */
-		iwl_clear_bit(bus, CSR_GIO_REG,
-				CSR_GIO_REG_VAL_L0S_ENABLED);
-		dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n");
-	}
-}
-
-static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[],
-			      int buf_len)
-{
-	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-
-	snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device,
-		 pci_dev->subsystem_device);
-}
-
-static u32 iwl_pci_get_hw_id(struct iwl_bus *bus)
-{
-	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
-
-	return (pci_dev->device << 16) + pci_dev->subsystem_device;
-}
-
-static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val)
-{
-	iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs);
-}
-
-static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val)
-{
-	iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs);
-}
-
-static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs)
-{
-	u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs);
-	return val;
-}
-
-static const struct iwl_bus_ops bus_ops_pci = {
-	.get_pm_support = iwl_pci_is_pm_supported,
-	.apm_config = iwl_pci_apm_config,
-	.get_hw_id_string = iwl_pci_get_hw_id_string,
-	.get_hw_id = iwl_pci_get_hw_id,
-	.write8 = iwl_pci_write8,
-	.write32 = iwl_pci_write32,
-	.read32 = iwl_pci_read32,
-};
-
 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
 	.vendor = PCI_VENDOR_ID_INTEL,  .device = (dev), \
 	.subvendor = PCI_ANY_ID, .subdevice = (subdev), \
@@ -362,112 +256,61 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
 };
 MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
 
+/* PCI registers */
+#define PCI_CFG_RETRY_TIMEOUT	0x041
+
 static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
 	struct iwl_bus *bus;
-	struct iwl_pci_bus *pci_bus;
-	u16 pci_cmd;
 	int err;
 
-	bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL);
+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
 	if (!bus) {
 		dev_printk(KERN_ERR, &pdev->dev,
 			   "Couldn't allocate iwl_pci_bus");
-		err = -ENOMEM;
-		goto out_no_pci;
+		return -ENOMEM;
 	}
 
-	pci_bus = IWL_BUS_GET_PCI_BUS(bus);
-	pci_bus->pci_dev = pdev;
-
-	pci_set_drvdata(pdev, bus);
-
-	/* W/A - seems to solve weird behavior. We need to remove this if we
-	 * don't want to stay in L1 all the time. This wastes a lot of power */
-	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
-				PCIE_LINK_STATE_CLKPM);
-
-	if (pci_enable_device(pdev)) {
-		err = -ENODEV;
-		goto out_no_pci;
+	bus->shrd = kzalloc(sizeof(*bus->shrd), GFP_KERNEL);
+	if (!bus->shrd) {
+		dev_printk(KERN_ERR, &pdev->dev,
+			   "Couldn't allocate iwl_shared");
+		err = -ENOMEM;
+		goto out_free_bus;
 	}
 
-	pci_set_master(pdev);
-
-	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
-	if (!err)
-		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
-	if (err) {
-		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-		if (!err)
-			err = pci_set_consistent_dma_mask(pdev,
-							DMA_BIT_MASK(32));
-		/* both attempts failed: */
-		if (err) {
-			dev_printk(KERN_ERR, bus->dev,
-				   "No suitable DMA available.\n");
-			goto out_pci_disable_device;
-		}
-	}
+	bus->shrd->bus = bus;
 
-	err = pci_request_regions(pdev, DRV_NAME);
-	if (err) {
-		dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed");
-		goto out_pci_disable_device;
-	}
+	pci_set_drvdata(pdev, bus);
 
-	pci_bus->hw_base = pci_iomap(pdev, 0, 0);
-	if (!pci_bus->hw_base) {
-		dev_printk(KERN_ERR, bus->dev, "pci_iomap failed");
-		err = -ENODEV;
-		goto out_pci_release_regions;
+#ifdef CONFIG_IWLWIFI_IDI
+	trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent);
+	if (trans(bus) == NULL) {
+		err = -ENOMEM;
+		goto out_free_bus;
 	}
 
-	dev_printk(KERN_INFO, &pdev->dev,
-		"pci_resource_len = 0x%08llx\n",
-		(unsigned long long) pci_resource_len(pdev, 0));
-	dev_printk(KERN_INFO, &pdev->dev,
-		"pci_resource_base = %p\n", pci_bus->hw_base);
-
-	dev_printk(KERN_INFO, &pdev->dev,
-		"HW Revision ID = 0x%X\n", pdev->revision);
-
-	/* We disable the RETRY_TIMEOUT register (0x41) to keep
-	 * PCI Tx retries from interfering with C3 CPU state */
-	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
-
-	err = pci_enable_msi(pdev);
-	if (err)
-		dev_printk(KERN_ERR, &pdev->dev,
-			"pci_enable_msi failed(0X%x)", err);
-
-	/* TODO: Move this away, not needed if not MSI */
-	/* enable rfkill interrupt: hw bug w/a */
-	pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
-	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
-		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
-		pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
+	err = iwl_probe(bus, &trans_ops_idi, cfg);
+#else
+	trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent);
+	if (trans(bus) == NULL) {
+		err = -ENOMEM;
+		goto out_free_bus;
 	}
 
-	bus->dev = &pdev->dev;
-	bus->irq = pdev->irq;
-	bus->ops = &bus_ops_pci;
-
 	err = iwl_probe(bus, &trans_ops_pcie, cfg);
+#endif
 	if (err)
-		goto out_disable_msi;
+		goto out_free_trans;
+
 	return 0;
 
-out_disable_msi:
-	pci_disable_msi(pdev);
-	pci_iounmap(pdev, pci_bus->hw_base);
-out_pci_release_regions:
+out_free_trans:
+	iwl_trans_free(trans(bus));
 	pci_set_drvdata(pdev, NULL);
-	pci_release_regions(pdev);
-out_pci_disable_device:
-	pci_disable_device(pdev);
-out_no_pci:
+out_free_bus:
+	kfree(bus->shrd);
 	kfree(bus);
 	return err;
 }
@@ -475,18 +318,14 @@ out_no_pci:
 static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 {
 	struct iwl_bus *bus = pci_get_drvdata(pdev);
-	struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus);
-	struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus);
 	struct iwl_shared *shrd = bus->shrd;
 
 	iwl_remove(shrd->priv);
+	iwl_trans_free(shrd->trans);
 
-	pci_disable_msi(pci_dev);
-	pci_iounmap(pci_dev, pci_bus->hw_base);
-	pci_release_regions(pci_dev);
-	pci_disable_device(pci_dev);
-	pci_set_drvdata(pci_dev, NULL);
+	pci_set_drvdata(pdev, NULL);
 
+	kfree(bus->shrd);
 	kfree(bus);
 }
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 2b188a6..fd008c4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
-	priv->power_data.bus_pm = bus_get_pm_support(bus(priv));
+	priv->power_data.bus_pm = trans(priv)->pm_support;
 
 	priv->power_data.debug_sleep_level_override = -1;
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 5f7b720..07a19fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index bebdd82..a4d1101 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index a645472..7f2e3a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -414,10 +414,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
 	for_each_context(priv, ctx) {
 		u16 value;
 
-		if (!iwl_is_associated_ctx(ctx))
-			continue;
-		if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P)
+		switch (ctx->staging.dev_type) {
+		case RXON_DEV_TYPE_P2P:
+			/* no timing constraints */
 			continue;
+		case RXON_DEV_TYPE_ESS:
+		default:
+			/* timing constraints if associated */
+			if (!iwl_is_associated_ctx(ctx))
+				continue;
+			break;
+		case RXON_DEV_TYPE_CP:
+		case RXON_DEV_TYPE_2STA:
+			/*
+			 * These seem to always have timers for TBTT
+			 * active in uCode even when not associated yet.
+			 */
+			break;
+		}
+
 		value = ctx->beacon_int;
 		if (!value)
 			value = IWL_PASSIVE_DWELL_BASE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index dc55cc4..63d4a4f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ struct iwl_trans_ops;
 
 #define DRV_NAME        "iwlwifi"
 #define IWLWIFI_VERSION "in-tree:"
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2011 Intel Corporation"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2012 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
 extern struct iwl_mod_params iwlagn_mod_params;
@@ -264,11 +264,13 @@ enum iwl_pa_type {
  *			LED ON  = RF ON
  *			LED OFF = RF OFF
  *    IWL_LED_BLINK:    adjust led blink rate based on blink table
+ *    IWL_LED_DISABLE:	led disabled
  */
 enum iwl_led_mode {
 	IWL_LED_DEFAULT,
 	IWL_LED_RF_STATE,
 	IWL_LED_BLINK,
+	IWL_LED_DISABLE,
 };
 
 /**
@@ -541,8 +543,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
 void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state);
 void iwl_nic_config(struct iwl_priv *priv);
 void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb);
-void iwl_apm_stop(struct iwl_priv *priv);
-int iwl_apm_init(struct iwl_priv *priv);
 void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
 const char *get_cmd_string(u8 cmd);
 bool iwl_check_for_ct_kill(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c
index 4a5cddd..df7ab33 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -79,6 +79,7 @@
 #include "iwl-testmode.h"
 #include "iwl-trans.h"
 #include "iwl-bus.h"
+#include "iwl-fh.h"
 
 /* The TLVs used in the gnl message policy between the kernel module and
  * user space application. iwl_testmode_gnl_msg_policy is to be carried
@@ -115,6 +116,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
 
 	[IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
 	[IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
+	[IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
+	[IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
+	[IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
 };
 
 /*
@@ -205,7 +209,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv)
 	if (priv->testmode_trace.trace_enabled) {
 		if (priv->testmode_trace.cpu_addr &&
 		    priv->testmode_trace.dma_addr)
-			dma_free_coherent(bus(priv)->dev,
+			dma_free_coherent(trans(priv)->dev,
 					priv->testmode_trace.total_size,
 					priv->testmode_trace.cpu_addr,
 					priv->testmode_trace.dma_addr);
@@ -285,7 +289,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 {
 	struct iwl_priv *priv = hw->priv;
-	u32 ofs, val32;
+	u32 ofs, val32, cmd;
 	u8 val8;
 	struct sk_buff *skb;
 	int status = 0;
@@ -297,9 +301,22 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 	ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
 	IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
 
-	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+	/* Allow access only to FH/CSR/HBUS in direct mode.
+	Since we don't have the upper bounds for the CSR and HBUS segments,
+	we will use only the upper bound of FH for sanity check. */
+	cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
+	if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 ||
+		cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 ||
+		cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) &&
+		(ofs >= FH_MEM_UPPER_BOUND)) {
+		IWL_DEBUG_INFO(priv, "offset out of segment (0x0 - 0x%x)\n",
+			FH_MEM_UPPER_BOUND);
+		return -EINVAL;
+	}
+
+	switch (cmd) {
 	case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
-		val32 = iwl_read32(bus(priv), ofs);
+		val32 = iwl_read_direct32(trans(priv), ofs);
 		IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
 
 		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
@@ -321,7 +338,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 		} else {
 			val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
 			IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
-			iwl_write32(bus(priv), ofs, val32);
+			iwl_write_direct32(trans(priv), ofs, val32);
 		}
 		break;
 	case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
@@ -331,11 +348,11 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 		} else {
 			val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
 			IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
-			iwl_write8(bus(priv), ofs, val8);
+			iwl_write8(trans(priv), ofs, val8);
 		}
 		break;
 	case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
-		val32 = iwl_read_prph(bus(priv), ofs);
+		val32 = iwl_read_prph(trans(priv), ofs);
 		IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
 
 		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
@@ -357,7 +374,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 		} else {
 			val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
 			IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
-			iwl_write_prph(bus(priv), ofs, val32);
+			iwl_write_prph(trans(priv), ofs, val32);
 		}
 		break;
 	default:
@@ -422,7 +439,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 	struct sk_buff *skb;
 	unsigned char *rsp_data_ptr = NULL;
 	int status = 0, rsp_data_len = 0;
-	u32 devid;
+	u32 devid, inst_size = 0, data_size = 0;
 
 	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
 	case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
@@ -533,7 +550,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 		break;
 
 	case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
-		devid = bus_get_hw_id(bus(priv));
+		devid = trans(priv)->hw_id;
 		IWL_INFO(priv, "hw version: 0x%x\n", devid);
 
 		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
@@ -548,6 +565,41 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
 					"Error sending msg : %d\n", status);
 		break;
 
+	case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
+		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
+		if (!skb) {
+			IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+			return -ENOMEM;
+		}
+		switch (priv->shrd->ucode_type) {
+		case IWL_UCODE_REGULAR:
+			inst_size = trans(priv)->ucode_rt.code.len;
+			data_size = trans(priv)->ucode_rt.data.len;
+			break;
+		case IWL_UCODE_INIT:
+			inst_size = trans(priv)->ucode_init.code.len;
+			data_size = trans(priv)->ucode_init.data.len;
+			break;
+		case IWL_UCODE_WOWLAN:
+			inst_size = trans(priv)->ucode_wowlan.code.len;
+			data_size = trans(priv)->ucode_wowlan.data.len;
+			break;
+		case IWL_UCODE_NONE:
+			IWL_DEBUG_INFO(priv, "The uCode has not been loaded\n");
+			break;
+		default:
+			IWL_DEBUG_INFO(priv, "Unsupported uCode type\n");
+			break;
+		}
+		NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
+		NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
+		NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
+		status = cfg80211_testmode_reply(skb);
+		if (status < 0)
+			IWL_DEBUG_INFO(priv,
+					"Error sending msg : %d\n", status);
+		break;
+
 	default:
 		IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
 		return -ENOSYS;
@@ -577,7 +629,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
 	struct iwl_priv *priv = hw->priv;
 	struct sk_buff *skb;
 	int status = 0;
-	struct device *dev = bus(priv)->dev;
+	struct device *dev = trans(priv)->dev;
 
 	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
 	case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
@@ -733,7 +785,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
 static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
 {
 	struct iwl_priv *priv = hw->priv;
-	u32 base, ofs, size, maxsize;
+	u32 ofs, size, maxsize;
 
 	if (priv->testmode_sram.sram_readed)
 		return -EBUSY;
@@ -759,25 +811,24 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
 		maxsize = trans(priv)->ucode_wowlan.data.len;
 		break;
 	case IWL_UCODE_NONE:
-		IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n");
+		IWL_ERR(priv, "Error, uCode does not been loaded\n");
 		return -ENOSYS;
 	default:
-		IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n");
+		IWL_ERR(priv, "Error, unsupported uCode type\n");
 		return -ENOSYS;
 	}
-	if ((ofs + size) > maxsize) {
-		IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n");
+	if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) {
+		IWL_ERR(priv, "Invalid offset/size: out of range\n");
 		return -EINVAL;
 	}
 	priv->testmode_sram.buff_size = (size / 4) * 4;
 	priv->testmode_sram.buff_addr =
 		kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
 	if (priv->testmode_sram.buff_addr == NULL) {
-		IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+		IWL_ERR(priv, "Error allocating memory\n");
 		return -ENOMEM;
 	}
-	base = 0x800000;
-	_iwl_read_targ_mem_words(bus(priv), base + ofs,
+	_iwl_read_targ_mem_words(trans(priv), ofs,
 					priv->testmode_sram.buff_addr,
 					priv->testmode_sram.buff_size / 4);
 	priv->testmode_sram.num_chunks =
@@ -882,6 +933,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
 	case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
 	case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
 	case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
+	case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
 		IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
 		result = iwl_testmode_driver(hw, tb);
 		break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index 26138f1..f97d061 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -111,15 +111,17 @@
  *
  * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
  * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
- *	commands from user applicaiton to indirectly access peripheral register
+ *	commands from user application to indirectly access peripheral register
  *
  * @IWL_TM_CMD_APP2DEV_READ_SRAM:
  * @IWL_TM_CMD_APP2DEV_DUMP_SRAM:
- *	commands from user applicaiton to read data in sram
+ *	commands from user application to read data in sram
  *
- * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image
+ * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
  * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
  * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
+ * @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
+ *	retrieve information of existing loaded uCode image
  *
  */
 enum iwl_tm_cmd_t {
@@ -147,7 +149,8 @@ enum iwl_tm_cmd_t {
 	IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW	= 22,
 	IWL_TM_CMD_APP2DEV_GET_FW_VERSION	= 23,
 	IWL_TM_CMD_APP2DEV_GET_DEVICE_ID	= 24,
-	IWL_TM_CMD_MAX				= 25,
+	IWL_TM_CMD_APP2DEV_GET_FW_INFO		= 25,
+	IWL_TM_CMD_MAX				= 26,
 };
 
 /*
@@ -237,6 +240,15 @@ enum iwl_tm_cmd_t {
  *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID,
  *	IWL_TM_ATTR_DEVICE_ID for the device ID information
  *
+ * @IWL_TM_ATTR_FW_TYPE:
+ * @IWL_TM_ATTR_FW_INST_SIZE:
+ * @IWL_TM_ATTR_FW_DATA_SIZE:
+ *	When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO,
+ *	The mandatory fields are:
+ *	IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...)
+ *	IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
+ *	IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
+ *
  */
 enum iwl_tm_attr_t {
 	IWL_TM_ATTR_NOT_APPLICABLE		= 0,
@@ -259,7 +271,10 @@ enum iwl_tm_attr_t {
 	IWL_TM_ATTR_SRAM_DUMP			= 17,
 	IWL_TM_ATTR_FW_VERSION			= 18,
 	IWL_TM_ATTR_DEVICE_ID			= 19,
-	IWL_TM_ATTR_MAX				= 20,
+	IWL_TM_ATTR_FW_TYPE			= 20,
+	IWL_TM_ATTR_FW_INST_SIZE		= 21,
+	IWL_TM_ATTR_FW_DATA_SIZE		= 22,
+	IWL_TM_ATTR_MAX				= 23,
 };
 
 /* uCode trace buffer */
@@ -271,4 +286,7 @@ enum iwl_tm_attr_t {
 /* Maximum data size of each dump it packet */
 #define DUMP_CHUNK_SIZE		(PAGE_SIZE - 1024)
 
+/* Address offset of data segment in SRAM */
+#define SRAM_DATA_SEG_OFFSET   0x800000
+
 #endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
index f6debf9..561865f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -201,6 +201,7 @@ struct iwl_tx_queue {
  * @rxq: all the RX queue data
  * @rx_replenish: work that will be called when buffers need to be allocated
  * @trans: pointer to the generic transport area
+ * @irq_requested: true when the irq has been requested
  * @scd_base_addr: scheduler sram base address in SRAM
  * @scd_bc_tbls: pointer to the byte count table of the scheduler
  * @kw: keep warm address
@@ -211,6 +212,8 @@ struct iwl_tx_queue {
  * @txq_ctx_active_msk: what queue is active
  * queue_stopped: tracks what queue is stopped
  * queue_stop_count: tracks what SW queue is stopped
+ * @pci_dev: basic pci-network driver stuff
+ * @hw_base: pci hardware address support
  */
 struct iwl_trans_pcie {
 	struct iwl_rx_queue rxq;
@@ -223,6 +226,7 @@ struct iwl_trans_pcie {
 	int ict_index;
 	u32 inta;
 	bool use_ict;
+	bool irq_requested;
 	struct tasklet_struct irq_tasklet;
 	struct isr_statistics isr_stats;
 
@@ -241,6 +245,10 @@ struct iwl_trans_pcie {
 #define IWL_MAX_HW_QUEUES	32
 	unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
 	atomic_t queue_stop_count[4];
+
+	/* PCI bus related data */
+	struct pci_dev *pci_dev;
+	void __iomem *hw_base;
 };
 
 #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
@@ -258,7 +266,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
 /*****************************************************
 * ICT
 ******************************************************/
-int iwl_reset_ict(struct iwl_trans *trans);
+void iwl_reset_ict(struct iwl_trans *trans);
 void iwl_disable_ict(struct iwl_trans *trans);
 int iwl_alloc_isr_ict(struct iwl_trans *trans);
 void iwl_free_isr_ict(struct iwl_trans *trans);
@@ -311,12 +319,12 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans)
 	clear_bit(STATUS_INT_ENABLED, &trans->shrd->status);
 
 	/* disable interrupts from uCode/NIC to host */
-	iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000);
+	iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
 	/* acknowledge/clear/reset any interrupts still pending
 	 * from uCode or flow handler (Rx/Tx DMA) */
-	iwl_write32(bus(trans), CSR_INT, 0xffffffff);
-	iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff);
+	iwl_write32(trans, CSR_INT, 0xffffffff);
+	iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff);
 	IWL_DEBUG_ISR(trans, "Disabled interrupts\n");
 }
 
@@ -327,7 +335,7 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans)
 
 	IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
 	set_bit(STATUS_INT_ENABLED, &trans->shrd->status);
-	iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask);
+	iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
 }
 
 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
index 65d1f05..3826852 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -35,6 +35,10 @@
 #include "iwl-io.h"
 #include "iwl-trans-pcie-int.h"
 
+#ifdef CONFIG_IWLWIFI_IDI
+#include "iwl-amfh.h"
+#endif
+
 /******************************************************************************
  *
  * RX path functions
@@ -140,30 +144,30 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
 		/* shadow register enabled */
 		/* Device expects a multiple of 8 */
 		q->write_actual = (q->write & ~0x7);
-		iwl_write32(bus(trans), FH_RSCSR_CHNL0_WPTR, q->write_actual);
+		iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual);
 	} else {
 		/* If power-saving is in use, make sure device is awake */
 		if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) {
-			reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1);
+			reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
 
 			if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
 				IWL_DEBUG_INFO(trans,
 					"Rx queue requesting wakeup,"
 					" GP1 = 0x%x\n", reg);
-				iwl_set_bit(bus(trans), CSR_GP_CNTRL,
+				iwl_set_bit(trans, CSR_GP_CNTRL,
 					CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 				goto exit_unlock;
 			}
 
 			q->write_actual = (q->write & ~0x7);
-			iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR,
+			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
 					q->write_actual);
 
 		/* Else device is assumed to be awake */
 		} else {
 			/* Device expects a multiple of 8 */
 			q->write_actual = (q->write & ~0x7);
-			iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR,
+			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
 				q->write_actual);
 		}
 	}
@@ -308,7 +312,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
 		BUG_ON(rxb->page);
 		rxb->page = page;
 		/* Get physical address of the RB */
-		rxb->page_dma = dma_map_page(bus(trans)->dev, page, 0,
+		rxb->page_dma = dma_map_page(trans->dev, page, 0,
 				PAGE_SIZE << hw_params(trans).rx_page_order,
 				DMA_FROM_DEVICE);
 		/* dma address must be no more than 36 bits */
@@ -414,7 +418,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
 
 		rxq->queue[i] = NULL;
 
-		dma_unmap_page(bus(trans)->dev, rxb->page_dma,
+		dma_unmap_page(trans->dev, rxb->page_dma,
 			       PAGE_SIZE << hw_params(trans).rx_page_order,
 			       DMA_FROM_DEVICE);
 		pkt = rxb_addr(rxb);
@@ -485,7 +489,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
 		 * rx_free list for reuse later. */
 		spin_lock_irqsave(&rxq->lock, flags);
 		if (rxb->page != NULL) {
-			rxb->page_dma = dma_map_page(bus(trans)->dev, rxb->page,
+			rxb->page_dma = dma_map_page(trans->dev, rxb->page,
 				0, PAGE_SIZE <<
 				    hw_params(trans).rx_page_order,
 				DMA_FROM_DEVICE);
@@ -612,7 +616,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 		return;
 	}
 
-	iwl_read_targ_mem_words(bus(priv), base, &table, sizeof(table));
+	iwl_read_targ_mem_words(trans(priv), base, &table, sizeof(table));
 
 	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
 		IWL_ERR(trans, "Start IWL Error Log Dump:\n");
@@ -673,9 +677,9 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
 	struct iwl_priv *priv = priv(trans);
 	/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
 	if (cfg(priv)->internal_wimax_coex &&
-	    (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) &
+	    (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) &
 			APMS_CLK_VAL_MRB_FUNC_MODE) ||
-	     (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) &
+	     (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
 			APMG_PS_CTRL_VAL_RESET_REQ))) {
 		/*
 		 * Keep the restart process from trying to send host
@@ -741,18 +745,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
 	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
 
 	/* Make sure device is powered up for SRAM reads */
-	spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags);
-	iwl_grab_nic_access(bus(trans));
+	spin_lock_irqsave(&trans->reg_lock, reg_flags);
+	iwl_grab_nic_access(trans);
 
 	/* Set starting address; reads will auto-increment */
-	iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr);
+	iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr);
 	rmb();
 
 	/* "time" is actually "data" for mode 0 (no timestamp).
 	* place event id # at far right for easier visual parsing. */
 	for (i = 0; i < num_events; i++) {
-		ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
-		time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
+		ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
+		time = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
 			/* data, ev */
 			if (bufsz) {
@@ -766,7 +770,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
 					time, ev);
 			}
 		} else {
-			data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
+			data = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
 			if (bufsz) {
 				pos += scnprintf(*buf + pos, bufsz - pos,
 						"EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -781,8 +785,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
 	}
 
 	/* Allow device to power down */
-	iwl_release_nic_access(bus(trans));
-	spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags);
+	iwl_release_nic_access(trans);
+	spin_unlock_irqrestore(&trans->reg_lock, reg_flags);
 	return pos;
 }
 
@@ -859,10 +863,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
 	}
 
 	/* event log header */
-	capacity = iwl_read_targ_mem(bus(trans), base);
-	mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32)));
-	num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32)));
-	next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32)));
+	capacity = iwl_read_targ_mem(trans, base);
+	mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32)));
+	num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32)));
+	next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32)));
 
 	if (capacity > logsize) {
 		IWL_ERR(trans, "Log capacity %d is bogus, limit to %d "
@@ -958,7 +962,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 	 * hardware bugs here by ACKing all the possible interrupts so that
 	 * interrupt coalescing can still be achieved.
 	 */
-	iwl_write32(bus(trans), CSR_INT,
+	iwl_write32(trans, CSR_INT,
 		trans_pcie->inta | ~trans_pcie->inta_mask);
 
 	inta = trans_pcie->inta;
@@ -966,7 +970,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 #ifdef CONFIG_IWLWIFI_DEBUG
 	if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) {
 		/* just for debug */
-		inta_mask = iwl_read32(bus(trans), CSR_INT_MASK);
+		inta_mask = iwl_read32(trans, CSR_INT_MASK);
 		IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ",
 				inta, inta_mask);
 	}
@@ -1014,7 +1018,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 	/* HW RF KILL switch toggled */
 	if (inta & CSR_INT_BIT_RF_KILL) {
 		int hw_rf_kill = 0;
-		if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) &
+		if (!(iwl_read32(trans, CSR_GP_CNTRL) &
 				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
 			hw_rf_kill = 1;
 
@@ -1078,12 +1082,12 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 		IWL_DEBUG_ISR(trans, "Rx interrupt\n");
 		if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
 			handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
-			iwl_write32(bus(trans), CSR_FH_INT_STATUS,
+			iwl_write32(trans, CSR_FH_INT_STATUS,
 					CSR_FH_INT_RX_MASK);
 		}
 		if (inta & CSR_INT_BIT_RX_PERIODIC) {
 			handled |= CSR_INT_BIT_RX_PERIODIC;
-			iwl_write32(bus(trans),
+			iwl_write32(trans,
 				CSR_INT, CSR_INT_BIT_RX_PERIODIC);
 		}
 		/* Sending RX interrupt require many steps to be done in the
@@ -1098,10 +1102,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 		 */
 
 		/* Disable periodic interrupt; we use it as just a one-shot. */
-		iwl_write8(bus(trans), CSR_INT_PERIODIC_REG,
+		iwl_write8(trans, CSR_INT_PERIODIC_REG,
 			    CSR_INT_PERIODIC_DIS);
+#ifdef CONFIG_IWLWIFI_IDI
+		iwl_amfh_rx_handler();
+#else
 		iwl_rx_handle(trans);
-
+#endif
 		/*
 		 * Enable periodic interrupt in 8 msec only if we received
 		 * real RX interrupt (instead of just periodic int), to catch
@@ -1110,7 +1117,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 		 * to extend the periodic interrupt; one-shot is enough.
 		 */
 		if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
-			iwl_write8(bus(trans), CSR_INT_PERIODIC_REG,
+			iwl_write8(trans, CSR_INT_PERIODIC_REG,
 				    CSR_INT_PERIODIC_ENA);
 
 		isr_stats->rx++;
@@ -1118,7 +1125,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 
 	/* This "Tx" DMA channel is used only for loading uCode */
 	if (inta & CSR_INT_BIT_FH_TX) {
-		iwl_write32(bus(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
+		iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
 		IWL_DEBUG_ISR(trans, "uCode load interrupt\n");
 		isr_stats->tx++;
 		handled |= CSR_INT_BIT_FH_TX;
@@ -1142,8 +1149,10 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
 	if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status))
 		iwl_enable_interrupts(trans);
 	/* Re-enable RF_KILL if it occurred */
-	else if (handled & CSR_INT_BIT_RF_KILL)
-		iwl_enable_rfkill_int(priv(trans));
+	else if (handled & CSR_INT_BIT_RF_KILL) {
+		IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
+		iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+	}
 }
 
 /******************************************************************************
@@ -1164,7 +1173,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans)
 		IWL_TRANS_GET_PCIE_TRANS(trans);
 
 	if (trans_pcie->ict_tbl) {
-		dma_free_coherent(bus(trans)->dev, ICT_SIZE,
+		dma_free_coherent(trans->dev, ICT_SIZE,
 				  trans_pcie->ict_tbl,
 				  trans_pcie->ict_tbl_dma);
 		trans_pcie->ict_tbl = NULL;
@@ -1184,7 +1193,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
 		IWL_TRANS_GET_PCIE_TRANS(trans);
 
 	trans_pcie->ict_tbl =
-		dma_alloc_coherent(bus(trans)->dev, ICT_SIZE,
+		dma_alloc_coherent(trans->dev, ICT_SIZE,
 				   &trans_pcie->ict_tbl_dma,
 				   GFP_KERNEL);
 	if (!trans_pcie->ict_tbl)
@@ -1213,7 +1222,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
 /* Device is going up inform it about using ICT interrupt table,
  * also we need to tell the driver to start using ICT interrupt.
  */
-int iwl_reset_ict(struct iwl_trans *trans)
+void iwl_reset_ict(struct iwl_trans *trans)
 {
 	u32 val;
 	unsigned long flags;
@@ -1221,7 +1230,7 @@ int iwl_reset_ict(struct iwl_trans *trans)
 		IWL_TRANS_GET_PCIE_TRANS(trans);
 
 	if (!trans_pcie->ict_tbl)
-		return 0;
+		return;
 
 	spin_lock_irqsave(&trans->shrd->lock, flags);
 	iwl_disable_interrupts(trans);
@@ -1235,14 +1244,12 @@ int iwl_reset_ict(struct iwl_trans *trans)
 
 	IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val);
 
-	iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val);
+	iwl_write32(trans, CSR_DRAM_INT_TBL_REG, val);
 	trans_pcie->use_ict = true;
 	trans_pcie->ict_index = 0;
-	iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask);
+	iwl_write32(trans, CSR_INT, trans_pcie->inta_mask);
 	iwl_enable_interrupts(trans);
 	spin_unlock_irqrestore(&trans->shrd->lock, flags);
-
-	return 0;
 }
 
 /* Device is going down disable ict interrupt usage */
@@ -1280,11 +1287,11 @@ static irqreturn_t iwl_isr(int irq, void *data)
 	 *    back-to-back ISRs and sporadic interrupts from our NIC.
 	 * If we have something to service, the tasklet will re-enable ints.
 	 * If we *don't* have something, we'll re-enable before leaving here. */
-	inta_mask = iwl_read32(bus(trans), CSR_INT_MASK);  /* just for debug */
-	iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000);
+	inta_mask = iwl_read32(trans, CSR_INT_MASK);  /* just for debug */
+	iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
 	/* Discover which interrupts are active/pending */
-	inta = iwl_read32(bus(trans), CSR_INT);
+	inta = iwl_read32(trans, CSR_INT);
 
 	/* Ignore interrupt if there's nothing in NIC to service.
 	 * This may be due to IRQ shared with another device,
@@ -1303,7 +1310,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 	if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
-		inta_fh = iwl_read32(bus(trans), CSR_FH_INT_STATUS);
+		inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS);
 		IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, "
 			      "fh 0x%08x\n", inta, inta_mask, inta_fh);
 	}
@@ -1369,8 +1376,8 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
 	 * If we have something to service, the tasklet will re-enable ints.
 	 * If we *don't* have something, we'll re-enable before leaving here.
 	 */
-	inta_mask = iwl_read32(bus(trans), CSR_INT_MASK);  /* just for debug */
-	iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000);
+	inta_mask = iwl_read32(trans, CSR_INT_MASK);  /* just for debug */
+	iwl_write32(trans, CSR_INT_MASK, 0x00000000);
 
 
 	/* Ignore interrupt if there's nothing in NIC to service.
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
index bd29568..a8dfeca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -100,7 +100,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
 
 	if (hw_params(trans).shadow_reg_enable) {
 		/* shadow register enabled */
-		iwl_write32(bus(trans), HBUS_TARG_WRPTR,
+		iwl_write32(trans, HBUS_TARG_WRPTR,
 			    txq->q.write_ptr | (txq_id << 8));
 	} else {
 		/* if we're trying to save power */
@@ -108,18 +108,18 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
 			/* wake up nic if it's powered down ...
 			 * uCode will wake up, and interrupt us again, so next
 			 * time we'll skip this part. */
-			reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1);
+			reg = iwl_read32(trans, CSR_UCODE_DRV_GP1);
 
 			if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
 				IWL_DEBUG_INFO(trans,
 					"Tx queue %d requesting wakeup,"
 					" GP1 = 0x%x\n", txq_id, reg);
-				iwl_set_bit(bus(trans), CSR_GP_CNTRL,
+				iwl_set_bit(trans, CSR_GP_CNTRL,
 					CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 				return;
 			}
 
-			iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR,
+			iwl_write_direct32(trans, HBUS_TARG_WRPTR,
 				     txq->q.write_ptr | (txq_id << 8));
 
 		/*
@@ -128,7 +128,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq)
 		 * trying to tx (during RFKILL, we're not trying to tx).
 		 */
 		} else
-			iwl_write32(bus(trans), HBUS_TARG_WRPTR,
+			iwl_write32(trans, HBUS_TARG_WRPTR,
 				    txq->q.write_ptr | (txq_id << 8));
 	}
 	txq->need_update = 0;
@@ -190,14 +190,14 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta,
 
 	/* Unmap tx_cmd */
 	if (num_tbs)
-		dma_unmap_single(bus(trans)->dev,
+		dma_unmap_single(trans->dev,
 				dma_unmap_addr(meta, mapping),
 				dma_unmap_len(meta, len),
 				DMA_BIDIRECTIONAL);
 
 	/* Unmap chunks, if any. */
 	for (i = 1; i < num_tbs; i++)
-		dma_unmap_single(bus(trans)->dev, iwl_tfd_tb_get_addr(tfd, i),
+		dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i),
 				iwl_tfd_tb_get_len(tfd, i), dma_dir);
 }
 
@@ -383,14 +383,14 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid,
 	tbl_dw_addr = trans_pcie->scd_base_addr +
 			SCD_TRANS_TBL_OFFSET_QUEUE(txq_id);
 
-	tbl_dw = iwl_read_targ_mem(bus(trans), tbl_dw_addr);
+	tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr);
 
 	if (txq_id & 0x1)
 		tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
 	else
 		tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
 
-	iwl_write_targ_mem(bus(trans), tbl_dw_addr, tbl_dw);
+	iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw);
 
 	return 0;
 }
@@ -399,7 +399,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id)
 {
 	/* Simply stop the queue, but don't change any configuration;
 	 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
-	iwl_write_prph(bus(trans),
+	iwl_write_prph(trans,
 		SCD_QUEUE_STATUS_BITS(txq_id),
 		(0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
 		(1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
@@ -409,9 +409,9 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans,
 				int txq_id, u32 index)
 {
 	IWL_DEBUG_TX_QUEUES(trans, "Q %d  WrPtr: %d", txq_id, index & 0xff);
-	iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR,
+	iwl_write_direct32(trans, HBUS_TARG_WRPTR,
 			(index & 0xff) | (txq_id << 8));
-	iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index);
+	iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index);
 }
 
 void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
@@ -423,7 +423,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
 	int active =
 		test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0;
 
-	iwl_write_prph(bus(trans), SCD_QUEUE_STATUS_BITS(txq_id),
+	iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
 			(active << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
 			(tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
 			(1 << SCD_QUEUE_STTS_REG_POS_WSL) |
@@ -431,9 +431,12 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans,
 
 	txq->sched_retry = scd_retry;
 
-	IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n",
-		       active ? "Activate" : "Deactivate",
-		       scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
+	if (active)
+		IWL_DEBUG_TX_QUEUES(trans, "Activate %s Queue %d on FIFO %d\n",
+			scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
+	else
+		IWL_DEBUG_TX_QUEUES(trans, "Deactivate %s Queue %d\n",
+			scd_retry ? "BA" : "AC/CMD", txq_id);
 }
 
 static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie,
@@ -478,7 +481,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
 	}
 
 	txq_id = trans_pcie->agg_txq[sta_id][tid];
-	if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) {
+	if (WARN_ON_ONCE(!is_agg_txqid_valid(trans, txq_id))) {
 		IWL_ERR(trans,
 			"queue number out of range: %d, must be %d to %d\n",
 			txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
@@ -498,10 +501,10 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
 	iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id);
 
 	/* Set this queue as a chain-building queue */
-	iwl_set_bits_prph(bus(trans), SCD_QUEUECHAIN_SEL, (1<<txq_id));
+	iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, (1<<txq_id));
 
 	/* enable aggregations for the queue */
-	iwl_set_bits_prph(bus(trans), SCD_AGGR_SEL, (1<<txq_id));
+	iwl_set_bits_prph(trans, SCD_AGGR_SEL, (1<<txq_id));
 
 	/* Place first TFD at index corresponding to start sequence number.
 	 * Assumes that ssn_idx is valid (!= 0xFFF) */
@@ -510,7 +513,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
 	iwl_trans_set_wr_ptrs(trans, txq_id, ssn);
 
 	/* Set up Tx window size and frame limit for this queue */
-	iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
+	iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
 			SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
 			sizeof(u32),
 			((frame_limit <<
@@ -520,7 +523,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans,
 			SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
 			SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
 
-	iwl_set_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id));
+	iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id));
 
 	/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
 	iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id],
@@ -573,7 +576,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid)
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	u8 txq_id = trans_pcie->agg_txq[sta_id][tid];
 
-	if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) {
+	if (WARN_ON_ONCE(!is_agg_txqid_valid(trans, txq_id))) {
 		IWL_ERR(trans,
 			"queue number out of range: %d, must be %d to %d\n",
 			txq_id, IWLAGN_FIRST_AMPDU_QUEUE,
@@ -584,7 +587,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid)
 
 	iwlagn_tx_queue_stop_scheduler(trans, txq_id);
 
-	iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id));
+	iwl_clear_bits_prph(trans, SCD_AGGR_SEL, (1 << txq_id));
 
 	trans_pcie->agg_txq[sta_id][tid] = 0;
 	trans_pcie->txq[txq_id].q.read_ptr = 0;
@@ -592,7 +595,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid)
 	/* supposes that ssn_idx is valid (!= 0xFFF) */
 	iwl_trans_set_wr_ptrs(trans, txq_id, 0);
 
-	iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id));
+	iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id));
 	iwl_txq_ctx_deactivate(trans_pcie, txq_id);
 	iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0);
 	return 0;
@@ -725,9 +728,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 			le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
 			q->write_ptr, idx, trans->shrd->cmd_queue);
 
-	phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size,
+	phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
 				DMA_BIDIRECTIONAL);
-	if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
+	if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
 		idx = -ENOMEM;
 		goto out;
 	}
@@ -748,10 +751,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 			continue;
 		if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
 			continue;
-		phys_addr = dma_map_single(bus(trans)->dev,
+		phys_addr = dma_map_single(trans->dev,
 					   (void *)cmd->data[i],
 					   cmd->len[i], DMA_BIDIRECTIONAL);
-		if (dma_mapping_error(bus(trans)->dev, phys_addr)) {
+		if (dma_mapping_error(trans->dev, phys_addr)) {
 			iwlagn_unmap_tfd(trans, out_meta,
 					 &txq->tfds[q->write_ptr],
 					 DMA_BIDIRECTIONAL);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 324d06d..f5cb5d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -60,8 +60,11 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+#include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/interrupt.h>
 #include <linux/debugfs.h>
+#include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/gfp.h>
 
@@ -72,13 +75,14 @@
 #include "iwl-shared.h"
 #include "iwl-eeprom.h"
 #include "iwl-agn-hw.h"
+#include "iwl-core.h"
 
 static int iwl_trans_rx_alloc(struct iwl_trans *trans)
 {
 	struct iwl_trans_pcie *trans_pcie =
 		IWL_TRANS_GET_PCIE_TRANS(trans);
 	struct iwl_rx_queue *rxq = &trans_pcie->rxq;
-	struct device *dev = bus(trans)->dev;
+	struct device *dev = trans->dev;
 
 	memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
 
@@ -122,7 +126,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans)
 		/* In the reset function, these buffers may have been allocated
 		 * to an SKB, so we need to unmap and free potential storage */
 		if (rxq->pool[i].page != NULL) {
-			dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma,
+			dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
 				PAGE_SIZE << hw_params(trans).rx_page_order,
 				DMA_FROM_DEVICE);
 			__free_pages(rxq->pool[i].page,
@@ -146,17 +150,17 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
 		rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
 
 	/* Stop Rx DMA */
-	iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+	iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
 
 	/* Reset driver's Rx queue write index */
-	iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
+	iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
 
 	/* Tell device where to find RBD circular buffer in DRAM */
-	iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+	iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
 			   (u32)(rxq->bd_dma >> 8));
 
 	/* Tell device where in DRAM to update its Rx status */
-	iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG,
+	iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG,
 			   rxq->rb_stts_dma >> 4);
 
 	/* Enable Rx DMA
@@ -167,7 +171,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
 	 * RB timeout 0x10
 	 * 256 RBDs
 	 */
-	iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG,
+	iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG,
 			   FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
 			   FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
 			   FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
@@ -177,7 +181,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans,
 			   (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
 
 	/* Set interrupt coalescing timer to default (2048 usecs) */
-	iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
+	iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
 }
 
 static int iwl_rx_init(struct iwl_trans *trans)
@@ -242,13 +246,13 @@ static void iwl_trans_pcie_rx_free(struct iwl_trans *trans)
 	iwl_trans_rxq_free_rx_bufs(trans);
 	spin_unlock_irqrestore(&rxq->lock, flags);
 
-	dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE,
+	dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
 			  rxq->bd, rxq->bd_dma);
 	memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
 	rxq->bd = NULL;
 
 	if (rxq->rb_stts)
-		dma_free_coherent(bus(trans)->dev,
+		dma_free_coherent(trans->dev,
 				  sizeof(struct iwl_rb_status),
 				  rxq->rb_stts, rxq->rb_stts_dma);
 	else
@@ -261,8 +265,8 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans)
 {
 
 	/* stop Rx DMA */
-	iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-	return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG,
+	iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+	return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG,
 			    FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
 }
 
@@ -272,7 +276,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans,
 	if (WARN_ON(ptr->addr))
 		return -EINVAL;
 
-	ptr->addr = dma_alloc_coherent(bus(trans)->dev, size,
+	ptr->addr = dma_alloc_coherent(trans->dev, size,
 				       &ptr->dma, GFP_KERNEL);
 	if (!ptr->addr)
 		return -ENOMEM;
@@ -286,7 +290,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans,
 	if (unlikely(!ptr->addr))
 		return;
 
-	dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma);
+	dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma);
 	memset(ptr, 0, sizeof(*ptr));
 }
 
@@ -333,7 +337,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans,
 
 	/* Circular buffer of transmit frame descriptors (TFDs),
 	 * shared with device */
-	txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz,
+	txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz,
 				       &txq->q.dma_addr, GFP_KERNEL);
 	if (!txq->tfds) {
 		IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
@@ -389,7 +393,7 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq,
 	 * Tell nic where to find circular buffer of Tx Frame Descriptors for
 	 * given Tx queue, and enable the DMA channel used for that queue.
 	 * Circular buffer (TFD queue in DRAM) physical base address */
-	iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id),
+	iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id),
 			     txq->q.dma_addr >> 8);
 
 	return 0;
@@ -443,7 +447,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id)
 {
 	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 	struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
-	struct device *dev = bus(trans)->dev;
+	struct device *dev = trans->dev;
 	int i;
 	if (WARN_ON(!txq))
 		return;
@@ -584,10 +588,10 @@ static int iwl_tx_init(struct iwl_trans *trans)
 	spin_lock_irqsave(&trans->shrd->lock, flags);
 
 	/* Turn off all Tx DMA fifos */
-	iwl_write_prph(bus(trans), SCD_TXFACT, 0);
+	iwl_write_prph(trans, SCD_TXFACT, 0);
 
 	/* Tell NIC where to find the "keep warm" buffer */
-	iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG,
+	iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
 			   trans_pcie->kw.dma >> 4);
 
 	spin_unlock_irqrestore(&trans->shrd->lock, flags);
@@ -619,26 +623,194 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans)
  * to set power to V_AUX, do:
 
 		if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
-			iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG,
+			iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
 					       APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
 					       ~APMG_PS_CTRL_MSK_PWR_SRC);
  */
 
-	iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG,
+	iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG,
 			       APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
 			       ~APMG_PS_CTRL_MSK_PWR_SRC);
 }
 
+/* PCI registers */
+#define PCI_CFG_RETRY_TIMEOUT	0x041
+#define PCI_CFG_LINK_CTRL_VAL_L0S_EN	0x01
+#define PCI_CFG_LINK_CTRL_VAL_L1_EN	0x02
+
+static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans)
+{
+	int pos;
+	u16 pci_lnk_ctl;
+	struct iwl_trans_pcie *trans_pcie =
+		IWL_TRANS_GET_PCIE_TRANS(trans);
+
+	struct pci_dev *pci_dev = trans_pcie->pci_dev;
+
+	pos = pci_pcie_cap(pci_dev);
+	pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+	return pci_lnk_ctl;
+}
+
+static void iwl_apm_config(struct iwl_trans *trans)
+{
+	/*
+	 * HW bug W/A for instability in PCIe bus L0S->L1 transition.
+	 * Check if BIOS (or OS) enabled L1-ASPM on this device.
+	 * If so (likely), disable L0S, so device moves directly L0->L1;
+	 *    costs negligible amount of power savings.
+	 * If not (unlikely), enable L0S, so there is at least some
+	 *    power savings, even without L1.
+	 */
+	u16 lctl = iwl_pciexp_link_ctrl(trans);
+
+	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+				PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+		/* L1-ASPM enabled; disable(!) L0S */
+		iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+		dev_printk(KERN_INFO, trans->dev,
+			   "L1 Enabled; Disabling L0S\n");
+	} else {
+		/* L1-ASPM disabled; enable(!) L0S */
+		iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
+		dev_printk(KERN_INFO, trans->dev,
+			   "L1 Disabled; Enabling L0S\n");
+	}
+	trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+}
+
+/*
+ * Start up NIC's basic functionality after it has been reset
+ * (e.g. after platform boot, or shutdown via iwl_apm_stop())
+ * NOTE:  This does not load uCode nor start the embedded processor
+ */
+static int iwl_apm_init(struct iwl_trans *trans)
+{
+	int ret = 0;
+	IWL_DEBUG_INFO(trans, "Init card's basic functions\n");
+
+	/*
+	 * Use "set_bit" below rather than "write", to preserve any hardware
+	 * bits already set by default after reset.
+	 */
+
+	/* Disable L0S exit timer (platform NMI Work/Around) */
+	iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+	/*
+	 * Disable L0s without affecting L1;
+	 *  don't wait for ICH L0s (ICH bug W/A)
+	 */
+	iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS,
+			  CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+	/* Set FH wait threshold to maximum (HW error during stress W/A) */
+	iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
+
+	/*
+	 * Enable HAP INTA (interrupt from management bus) to
+	 * wake device's PCI Express link L1a -> L0s
+	 */
+	iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
+				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
+
+	iwl_apm_config(trans);
+
+	/* Configure analog phase-lock-loop before activating to D0A */
+	if (cfg(trans)->base_params->pll_cfg_val)
+		iwl_set_bit(trans, CSR_ANA_PLL_CFG,
+			    cfg(trans)->base_params->pll_cfg_val);
+
+	/*
+	 * Set "initialization complete" bit to move adapter from
+	 * D0U* --> D0A* (powered-up active) state.
+	 */
+	iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+	/*
+	 * Wait for clock stabilization; once stabilized, access to
+	 * device-internal resources is supported, e.g. iwl_write_prph()
+	 * and accesses to uCode SRAM.
+	 */
+	ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
+			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+			CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+	if (ret < 0) {
+		IWL_DEBUG_INFO(trans, "Failed to init the card\n");
+		goto out;
+	}
+
+	/*
+	 * Enable DMA clock and wait for it to stabilize.
+	 *
+	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
+	 * do not disable clocks.  This preserves any hardware bits already
+	 * set by default in "CLK_CTRL_REG" after reset.
+	 */
+	iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+	udelay(20);
+
+	/* Disable L1-Active */
+	iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
+			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+	set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status);
+
+out:
+	return ret;
+}
+
+static int iwl_apm_stop_master(struct iwl_trans *trans)
+{
+	int ret = 0;
+
+	/* stop device's busmaster DMA activity */
+	iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+
+	ret = iwl_poll_bit(trans, CSR_RESET,
+			CSR_RESET_REG_FLAG_MASTER_DISABLED,
+			CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+	if (ret)
+		IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");
+
+	IWL_DEBUG_INFO(trans, "stop master\n");
+
+	return ret;
+}
+
+static void iwl_apm_stop(struct iwl_trans *trans)
+{
+	IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
+
+	clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status);
+
+	/* Stop device's DMA activity */
+	iwl_apm_stop_master(trans);
+
+	/* Reset the entire device */
+	iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+	udelay(10);
+
+	/*
+	 * Clear "initialization complete" bit to move adapter from
+	 * D0A* (powered-up Active) --> D0U* (Uninitialized) state.
+	 */
+	iwl_clear_bit(trans, CSR_GP_CNTRL,
+		      CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+}
+
 static int iwl_nic_init(struct iwl_trans *trans)
 {
 	unsigned long flags;
 
 	/* nic_init */
 	spin_lock_irqsave(&trans->shrd->lock, flags);
-	iwl_apm_init(priv(trans));
+	iwl_apm_init(trans);
 
 	/* Set interrupt coalescing calibration timer to default (512 usecs) */
-	iwl_write8(bus(trans), CSR_INT_COALESCING,
+	iwl_write8(trans, CSR_INT_COALESCING,
 		IWL_HOST_INT_CALIB_TIMEOUT_DEF);
 
 	spin_unlock_irqrestore(&trans->shrd->lock, flags);
@@ -647,8 +819,10 @@ static int iwl_nic_init(struct iwl_trans *trans)
 
 	iwl_nic_config(priv(trans));
 
+#ifndef CONFIG_IWLWIFI_IDI
 	/* Allocate the RX queue, or reset if it is already allocated */
 	iwl_rx_init(trans);
+#endif
 
 	/* Allocate or reset and init all Tx and Command queues */
 	if (iwl_tx_init(trans))
@@ -656,7 +830,7 @@ static int iwl_nic_init(struct iwl_trans *trans)
 
 	if (hw_params(trans).shadow_reg_enable) {
 		/* enable shadow regs in HW */
-		iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL,
+		iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL,
 			0x800FFFFF);
 	}
 
@@ -672,11 +846,11 @@ static int iwl_set_hw_ready(struct iwl_trans *trans)
 {
 	int ret;
 
-	iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+	iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
 		CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
 
 	/* See if we got it */
-	ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+	ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
 				CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
 				CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
 				HW_READY_TIMEOUT);
@@ -686,21 +860,22 @@ static int iwl_set_hw_ready(struct iwl_trans *trans)
 }
 
 /* Note: returns standard 0/-ERROR code */
-static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans)
+static int iwl_prepare_card_hw(struct iwl_trans *trans)
 {
 	int ret;
 
 	IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n");
 
 	ret = iwl_set_hw_ready(trans);
+	/* If the card is ready, exit 0 */
 	if (ret >= 0)
 		return 0;
 
 	/* If HW is not ready, prepare the conditions to check again */
-	iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+	iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
 			CSR_HW_IF_CONFIG_REG_PREPARE);
 
-	ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG,
+	ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG,
 			~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
 			CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
 
@@ -767,7 +942,79 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
 	7, 6, 5, 4,
 };
 
-static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
+/*
+ * ucode
+ */
+static int iwl_load_section(struct iwl_trans *trans, const char *name,
+				struct fw_desc *image, u32 dst_addr)
+{
+	dma_addr_t phy_addr = image->p_addr;
+	u32 byte_cnt = image->len;
+	int ret;
+
+	trans->ucode_write_complete = 0;
+
+	iwl_write_direct32(trans,
+		FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
+		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
+
+	iwl_write_direct32(trans,
+		FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
+
+	iwl_write_direct32(trans,
+		FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
+		phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
+
+	iwl_write_direct32(trans,
+		FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
+		(iwl_get_dma_hi_addr(phy_addr)
+			<< FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
+
+	iwl_write_direct32(trans,
+		FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
+		1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
+		1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
+		FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
+
+	iwl_write_direct32(trans,
+		FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
+		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE	|
+		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE	|
+		FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
+
+	IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name);
+	ret = wait_event_timeout(trans->shrd->wait_command_queue,
+				 trans->ucode_write_complete, 5 * HZ);
+	if (!ret) {
+		IWL_ERR(trans, "Could not load the %s uCode section\n",
+			name);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image)
+{
+	int ret = 0;
+
+	ret = iwl_load_section(trans, "INST", &image->code,
+				   IWLAGN_RTC_INST_LOWER_BOUND);
+	if (ret)
+		return ret;
+
+	ret = iwl_load_section(trans, "DATA", &image->data,
+				    IWLAGN_RTC_DATA_LOWER_BOUND);
+	if (ret)
+		return ret;
+
+	/* Remove all resets to allow NIC to operate */
+	iwl_write32(trans, CSR_RESET, 0);
+
+	return 0;
+}
+
+static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw)
 {
 	int ret;
 	struct iwl_trans_pcie *trans_pcie =
@@ -784,13 +1031,13 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
 	trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE;
 
 	if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) &&
-	     iwl_trans_pcie_prepare_card_hw(trans)) {
+	     iwl_prepare_card_hw(trans)) {
 		IWL_WARN(trans, "Exit HW not ready\n");
 		return -EIO;
 	}
 
 	/* If platform's RF_KILL switch is NOT set to KILL */
-	if (iwl_read32(bus(trans), CSR_GP_CNTRL) &
+	if (iwl_read32(trans, CSR_GP_CNTRL) &
 			CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
 		clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
 	else
@@ -802,7 +1049,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
 		return -ERFKILL;
 	}
 
-	iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF);
+	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
 
 	ret = iwl_nic_init(trans);
 	if (ret) {
@@ -811,17 +1058,20 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
 	}
 
 	/* make sure rfkill handshake bits are cleared */
-	iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-	iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR,
+	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
 		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
 	/* clear (again), then enable host interrupts */
-	iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF);
+	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
 	iwl_enable_interrupts(trans);
 
 	/* really make sure rfkill handshake bits are cleared */
-	iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-	iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+
+	/* Load the given image to the HW */
+	iwl_load_given_ucode(trans, fw);
 
 	return 0;
 }
@@ -832,10 +1082,10 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
  */
 static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
 {
-	iwl_write_prph(bus(trans), SCD_TXFACT, mask);
+	iwl_write_prph(trans, SCD_TXFACT, mask);
 }
 
-static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
+static void iwl_tx_start(struct iwl_trans *trans)
 {
 	const struct queue_to_fifo_ac *queue_to_fifo;
 	struct iwl_trans_pcie *trans_pcie =
@@ -848,46 +1098,46 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
 	spin_lock_irqsave(&trans->shrd->lock, flags);
 
 	trans_pcie->scd_base_addr =
-		iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR);
+		iwl_read_prph(trans, SCD_SRAM_BASE_ADDR);
 	a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND;
 	/* reset conext data memory */
 	for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND;
 		a += 4)
-		iwl_write_targ_mem(bus(trans), a, 0);
+		iwl_write_targ_mem(trans, a, 0);
 	/* reset tx status memory */
 	for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND;
 		a += 4)
-		iwl_write_targ_mem(bus(trans), a, 0);
+		iwl_write_targ_mem(trans, a, 0);
 	for (; a < trans_pcie->scd_base_addr +
 	       SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num);
 	       a += 4)
-		iwl_write_targ_mem(bus(trans), a, 0);
+		iwl_write_targ_mem(trans, a, 0);
 
-	iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR,
+	iwl_write_prph(trans, SCD_DRAM_BASE_ADDR,
 		       trans_pcie->scd_bc_tbls.dma >> 10);
 
 	/* Enable DMA channel */
 	for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++)
-		iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan),
+		iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
 				FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
 				FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
 
 	/* Update FH chicken bits */
-	reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG);
-	iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG,
+	reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG);
+	iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG,
 			   reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
 
-	iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL,
+	iwl_write_prph(trans, SCD_QUEUECHAIN_SEL,
 		SCD_QUEUECHAIN_SEL_ALL(trans));
-	iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0);
+	iwl_write_prph(trans, SCD_AGGR_SEL, 0);
 
 	/* initiate the queues */
 	for (i = 0; i < hw_params(trans).max_txq_num; i++) {
-		iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0);
-		iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8));
-		iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
+		iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0);
+		iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8));
+		iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
 				SCD_CONTEXT_QUEUE_OFFSET(i), 0);
-		iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr +
+		iwl_write_targ_mem(trans, trans_pcie->scd_base_addr +
 				SCD_CONTEXT_QUEUE_OFFSET(i) +
 				sizeof(u32),
 				((SCD_WIN_SIZE <<
@@ -898,7 +1148,7 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
 				SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
 	}
 
-	iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK,
+	iwl_write_prph(trans, SCD_INTERRUPT_MASK,
 			IWL_MASK(0, hw_params(trans).max_txq_num));
 
 	/* Activate all Tx DMA/FIFO channels */
@@ -944,10 +1194,16 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
 	spin_unlock_irqrestore(&trans->shrd->lock, flags);
 
 	/* Enable L1-Active */
-	iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG,
+	iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG,
 			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 }
 
+static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans)
+{
+	iwl_reset_ict(trans);
+	iwl_tx_start(trans);
+}
+
 /**
  * iwlagn_txq_ctx_stop - Stop all Tx DMA channels
  */
@@ -964,14 +1220,14 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans)
 
 	/* Stop each Tx DMA channel, and wait for it to be idle */
 	for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
-		iwl_write_direct32(bus(trans),
+		iwl_write_direct32(trans,
 				   FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
-		if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG,
+		if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
 				    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
 				    1000))
 			IWL_ERR(trans, "Failing on timeout while stopping"
 			    " DMA channel %d [0x%08x]", ch,
-			    iwl_read_direct32(bus(trans),
+			    iwl_read_direct32(trans,
 					      FH_TSSR_TX_STATUS_REG));
 	}
 	spin_unlock_irqrestore(&trans->shrd->lock, flags);
@@ -1010,20 +1266,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 	 */
 	if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) {
 		iwl_trans_tx_stop(trans);
+#ifndef CONFIG_IWLWIFI_IDI
 		iwl_trans_rx_stop(trans);
-
+#endif
 		/* Power-down device's busmaster DMA clocks */
-		iwl_write_prph(bus(trans), APMG_CLK_DIS_REG,
+		iwl_write_prph(trans, APMG_CLK_DIS_REG,
 			       APMG_CLK_VAL_DMA_CLK_RQT);
 		udelay(5);
 	}
 
 	/* Make sure (redundant) we've released our request to stay awake */
-	iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
+	iwl_clear_bit(trans, CSR_GP_CNTRL,
 			CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 
 	/* Stop the device, and put it in low power state */
-	iwl_apm_stop(priv(trans));
+	iwl_apm_stop(trans);
 
 	/* Upon stop, the APM issues an interrupt if HW RF kill is set.
 	 * Clean again the interrupt here
@@ -1033,11 +1290,11 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
 	spin_unlock_irqrestore(&trans->shrd->lock, flags);
 
 	/* wait to make sure we flush pending tasklet*/
-	synchronize_irq(bus(trans)->irq);
+	synchronize_irq(trans->irq);
 	tasklet_kill(&trans_pcie->irq_tasklet);
 
 	/* stop and reset the on-board processor */
-	iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+	iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 }
 
 static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
@@ -1134,10 +1391,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 
 	/* Physical address of this Tx command's header (not MAC header!),
 	 * within command buffer array. */
-	txcmd_phys = dma_map_single(bus(trans)->dev,
+	txcmd_phys = dma_map_single(trans->dev,
 				    &dev_cmd->hdr, firstlen,
 				    DMA_BIDIRECTIONAL);
-	if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys)))
+	if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
 		return -1;
 	dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
 	dma_unmap_len_set(out_meta, len, firstlen);
@@ -1153,10 +1410,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 	 * if any (802.11 null frames have no payload). */
 	secondlen = skb->len - hdr_len;
 	if (secondlen > 0) {
-		phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len,
+		phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
 					   secondlen, DMA_TO_DEVICE);
-		if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) {
-			dma_unmap_single(bus(trans)->dev,
+		if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
+			dma_unmap_single(trans->dev,
 					 dma_unmap_addr(out_meta, mapping),
 					 dma_unmap_len(out_meta, len),
 					 DMA_BIDIRECTIONAL);
@@ -1174,7 +1431,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 				offsetof(struct iwl_tx_cmd, scratch);
 
 	/* take back ownership of DMA buffer to enable update */
-	dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen,
+	dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
 			DMA_BIDIRECTIONAL);
 	tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
 	tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
@@ -1188,7 +1445,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 	/* Set up entry for this TFD in Tx byte-count array */
 	iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
 
-	dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen,
+	dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
 			DMA_BIDIRECTIONAL);
 
 	trace_iwlwifi_dev_tx(priv(trans),
@@ -1218,13 +1475,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
 	return 0;
 }
 
-static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans)
-{
-	/* Remove all resets to allow NIC to operate */
-	iwl_write32(bus(trans), CSR_RESET, 0);
-}
-
-static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
+static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
 {
 	struct iwl_trans_pcie *trans_pcie =
 		IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -1232,21 +1483,62 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans)
 
 	trans_pcie->inta_mask = CSR_INI_SET_MASK;
 
-	tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
-		iwl_irq_tasklet, (unsigned long)trans);
+	if (!trans_pcie->irq_requested) {
+		tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long))
+			iwl_irq_tasklet, (unsigned long)trans);
 
-	iwl_alloc_isr_ict(trans);
+		iwl_alloc_isr_ict(trans);
+
+		err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED,
+			DRV_NAME, trans);
+		if (err) {
+			IWL_ERR(trans, "Error allocating IRQ %d\n",
+				trans->irq);
+			goto error;
+		}
 
-	err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED,
-		DRV_NAME, trans);
+		INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
+		trans_pcie->irq_requested = true;
+	}
+
+	err = iwl_prepare_card_hw(trans);
 	if (err) {
-		IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq);
-		iwl_free_isr_ict(trans);
-		return err;
+		IWL_ERR(trans, "Error while preparing HW: %d", err);
+		goto err_free_irq;
 	}
 
-	INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish);
-	return 0;
+	iwl_apm_init(trans);
+
+	/* If platform's RF_KILL switch is NOT set to KILL */
+	if (iwl_read32(trans,
+			CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+		clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+	else
+		set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
+
+	iwl_set_hw_rfkill_state(priv(trans),
+				test_bit(STATUS_RF_KILL_HW,
+					 &trans->shrd->status));
+
+	return err;
+
+err_free_irq:
+	free_irq(trans->irq, trans);
+error:
+	iwl_free_isr_ict(trans);
+	tasklet_kill(&trans_pcie->irq_tasklet);
+	return err;
+}
+
+static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans)
+{
+	iwl_apm_stop(trans);
+
+	iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
+
+	/* Even if we stop the HW, we still want the RF kill interrupt */
+	IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
+	iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
 }
 
 static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
@@ -1289,13 +1581,42 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
 	return 0;
 }
 
+static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
+{
+	iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+}
+
+static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val)
+{
+	iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+}
+
+static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
+{
+	u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs);
+	return val;
+}
+
 static void iwl_trans_pcie_free(struct iwl_trans *trans)
 {
+	struct iwl_trans_pcie *trans_pcie =
+		IWL_TRANS_GET_PCIE_TRANS(trans);
+
 	iwl_calib_free_results(trans);
 	iwl_trans_pcie_tx_free(trans);
+#ifndef CONFIG_IWLWIFI_IDI
 	iwl_trans_pcie_rx_free(trans);
-	free_irq(bus(trans)->irq, trans);
-	iwl_free_isr_ict(trans);
+#endif
+	if (trans_pcie->irq_requested == true) {
+		free_irq(trans->irq, trans);
+		iwl_free_isr_ict(trans);
+	}
+
+	pci_disable_msi(trans_pcie->pci_dev);
+	pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base);
+	pci_release_regions(trans_pcie->pci_dev);
+	pci_disable_device(trans_pcie->pci_dev);
+
 	trans->shrd->trans = NULL;
 	kfree(trans);
 }
@@ -1315,10 +1636,10 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 	 * things already :-)
 	 */
 	if (!trans->shrd->wowlan) {
-		iwl_apm_stop(priv(trans));
+		iwl_apm_stop(trans);
 	} else {
 		iwl_disable_interrupts(trans);
-		iwl_clear_bit(bus(trans), CSR_GP_CNTRL,
+		iwl_clear_bit(trans, CSR_GP_CNTRL,
 			      CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 	}
 
@@ -1331,7 +1652,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
 
 	iwl_enable_interrupts(trans);
 
-	if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) &
+	if (!(iwl_read32(trans, CSR_GP_CNTRL) &
 				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
 		hw_rfkill = true;
 
@@ -1364,25 +1685,6 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans,
 	}
 }
 
-const struct iwl_trans_ops trans_ops_pcie;
-
-static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd)
-{
-	struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) +
-					      sizeof(struct iwl_trans_pcie),
-					      GFP_KERNEL);
-	if (iwl_trans) {
-		struct iwl_trans_pcie *trans_pcie =
-			IWL_TRANS_GET_PCIE_TRANS(iwl_trans);
-		iwl_trans->ops = &trans_ops_pcie;
-		iwl_trans->shrd = shrd;
-		trans_pcie->trans = iwl_trans;
-		spin_lock_init(&iwl_trans->hcmd_lock);
-	}
-
-	return iwl_trans;
-}
-
 static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id,
 				      const char *msg)
 {
@@ -1446,9 +1748,9 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt)
 		IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
 			q->read_ptr, q->write_ptr);
 		IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n",
-			iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt))
+			iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt))
 				& (TFD_QUEUE_SIZE_MAX - 1),
-			iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt)));
+			iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt)));
 		return 1;
 	}
 
@@ -1502,7 +1804,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
 			pos += scnprintf(*buf + pos, bufsz - pos,
 				"  %34s: 0X%08x\n",
 				get_fh_string(fh_tbl[i]),
-				iwl_read_direct32(bus(trans), fh_tbl[i]));
+				iwl_read_direct32(trans, fh_tbl[i]));
 		}
 		return pos;
 	}
@@ -1511,7 +1813,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
 	for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
 		IWL_ERR(trans, "  %34s: 0X%08x\n",
 			get_fh_string(fh_tbl[i]),
-			iwl_read_direct32(bus(trans), fh_tbl[i]));
+			iwl_read_direct32(trans, fh_tbl[i]));
 	}
 	return 0;
 }
@@ -1581,7 +1883,7 @@ void iwl_dump_csr(struct iwl_trans *trans)
 	for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
 		IWL_ERR(trans, "  %25s: 0X%08x\n",
 			get_csr_string(csr_tbl[i]),
-			iwl_read32(bus(trans), csr_tbl[i]));
+			iwl_read32(trans, csr_tbl[i]));
 	}
 }
 
@@ -1902,13 +2204,12 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
 #endif /*CONFIG_IWLWIFI_DEBUGFS */
 
 const struct iwl_trans_ops trans_ops_pcie = {
-	.alloc = iwl_trans_pcie_alloc,
-	.request_irq = iwl_trans_pcie_request_irq,
-	.start_device = iwl_trans_pcie_start_device,
-	.prepare_card_hw = iwl_trans_pcie_prepare_card_hw,
+	.start_hw = iwl_trans_pcie_start_hw,
+	.stop_hw = iwl_trans_pcie_stop_hw,
+	.fw_alive = iwl_trans_pcie_fw_alive,
+	.start_fw = iwl_trans_pcie_start_fw,
 	.stop_device = iwl_trans_pcie_stop_device,
 
-	.tx_start = iwl_trans_pcie_tx_start,
 	.wake_any_queue = iwl_trans_pcie_wake_any_queue,
 
 	.send_cmd = iwl_trans_pcie_send_cmd,
@@ -1920,8 +2221,6 @@ const struct iwl_trans_ops trans_ops_pcie = {
 	.tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc,
 	.tx_agg_setup = iwl_trans_pcie_tx_agg_setup,
 
-	.kick_nic = iwl_trans_pcie_kick_nic,
-
 	.free = iwl_trans_pcie_free,
 	.stop_queue = iwl_trans_pcie_stop_queue,
 
@@ -1934,4 +2233,116 @@ const struct iwl_trans_ops trans_ops_pcie = {
 	.suspend = iwl_trans_pcie_suspend,
 	.resume = iwl_trans_pcie_resume,
 #endif
+	.write8 = iwl_trans_pcie_write8,
+	.write32 = iwl_trans_pcie_write32,
+	.read32 = iwl_trans_pcie_read32,
 };
+
+struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
+				       struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
+{
+	struct iwl_trans_pcie *trans_pcie;
+	struct iwl_trans *trans;
+	u16 pci_cmd;
+	int err;
+
+	trans = kzalloc(sizeof(struct iwl_trans) +
+			     sizeof(struct iwl_trans_pcie), GFP_KERNEL);
+
+	if (WARN_ON(!trans))
+		return NULL;
+
+	trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+	trans->ops = &trans_ops_pcie;
+	trans->shrd = shrd;
+	trans_pcie->trans = trans;
+	spin_lock_init(&trans->hcmd_lock);
+
+	/* W/A - seems to solve weird behavior. We need to remove this if we
+	 * don't want to stay in L1 all the time. This wastes a lot of power */
+	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+				PCIE_LINK_STATE_CLKPM);
+
+	if (pci_enable_device(pdev)) {
+		err = -ENODEV;
+		goto out_no_pci;
+	}
+
+	pci_set_master(pdev);
+
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
+	if (!err)
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
+	if (err) {
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (!err)
+			err = pci_set_consistent_dma_mask(pdev,
+							DMA_BIT_MASK(32));
+		/* both attempts failed: */
+		if (err) {
+			dev_printk(KERN_ERR, &pdev->dev,
+				   "No suitable DMA available.\n");
+			goto out_pci_disable_device;
+		}
+	}
+
+	err = pci_request_regions(pdev, DRV_NAME);
+	if (err) {
+		dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed");
+		goto out_pci_disable_device;
+	}
+
+	trans_pcie->hw_base = pci_iomap(pdev, 0, 0);
+	if (!trans_pcie->hw_base) {
+		dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed");
+		err = -ENODEV;
+		goto out_pci_release_regions;
+	}
+
+	dev_printk(KERN_INFO, &pdev->dev,
+		"pci_resource_len = 0x%08llx\n",
+		(unsigned long long) pci_resource_len(pdev, 0));
+	dev_printk(KERN_INFO, &pdev->dev,
+		"pci_resource_base = %p\n", trans_pcie->hw_base);
+
+	dev_printk(KERN_INFO, &pdev->dev,
+		"HW Revision ID = 0x%X\n", pdev->revision);
+
+	/* We disable the RETRY_TIMEOUT register (0x41) to keep
+	 * PCI Tx retries from interfering with C3 CPU state */
+	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+
+	err = pci_enable_msi(pdev);
+	if (err)
+		dev_printk(KERN_ERR, &pdev->dev,
+			"pci_enable_msi failed(0X%x)", err);
+
+	trans->dev = &pdev->dev;
+	trans->irq = pdev->irq;
+	trans_pcie->pci_dev = pdev;
+	trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
+	trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
+	snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
+		 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
+
+	/* TODO: Move this away, not needed if not MSI */
+	/* enable rfkill interrupt: hw bug w/a */
+	pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
+	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+		pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
+	}
+
+	return trans;
+
+out_pci_release_regions:
+	pci_release_regions(pdev);
+out_pci_disable_device:
+	pci_disable_device(pdev);
+out_no_pci:
+	kfree(trans);
+	return NULL;
+}
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index 1b20c4f..506c062 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index e6bf3f5..ae68c51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -131,16 +131,26 @@ struct iwl_host_cmd {
 	u8 id;
 };
 
+/* one for each uCode image (inst/data, boot/init/runtime) */
+struct fw_desc {
+	dma_addr_t p_addr;	/* hardware address */
+	void *v_addr;		/* software address */
+	u32 len;		/* size in bytes */
+};
+
+struct fw_img {
+	struct fw_desc code;	/* firmware code image */
+	struct fw_desc data;	/* firmware data image */
+};
+
 /**
  * struct iwl_trans_ops - transport specific operations
- * @alloc: allocates the meta data (not the queues themselves)
- * @request_irq: requests IRQ - will be called before the FW load in probe flow
- * @start_device: allocates and inits all the resources for the transport
- *                layer.
- * @prepare_card_hw: claim the ownership on the HW. Will be called during
- *                   probe.
- * @tx_start: starts and configures all the Tx fifo - usually done once the fw
- *           is alive.
+ * @start_hw: starts the HW- from that point on, the HW can send interrupts
+ * @stop_hw: stops the HW- from that point on, the HW will be in low power but
+ *	will still issue interrupt if the HW RF kill is triggered.
+ * @start_fw: allocates and inits all the resources for the transport
+ *	layer. Also kick a fw image. This handler may sleep.
+ * @fw_alive: called when the fw sends alive notification
  * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_*
  * @stop_device:stops the whole device (embedded CPU put to reset)
  * @send_cmd:send a host command
@@ -150,7 +160,6 @@ struct iwl_host_cmd {
  * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is
  *                 ready and a successful ADDBA response has been received.
  * @tx_agg_disable: de-configure a Tx queue to send AMPDUs
- * @kick_nic: remove the RESET from the embedded CPU and let it run
  * @free: release all the ressource for the transport layer itself such as
  *        irq, tasklet etc...
  * @stop_queue: stop a specific queue
@@ -160,15 +169,17 @@ struct iwl_host_cmd {
  *	automatically deleted.
  * @suspend: stop the device unless WoWLAN is configured
  * @resume: resume activity of the device
+ * @write8: write a u8 to a register at offset ofs from the BAR
+ * @write32: write a u32 to a register at offset ofs from the BAR
+ * @read32: read a u32 register at offset ofs from the BAR
  */
 struct iwl_trans_ops {
 
-	struct iwl_trans *(*alloc)(struct iwl_shared *shrd);
-	int (*request_irq)(struct iwl_trans *iwl_trans);
-	int (*start_device)(struct iwl_trans *trans);
-	int (*prepare_card_hw)(struct iwl_trans *trans);
+	int (*start_hw)(struct iwl_trans *iwl_trans);
+	void (*stop_hw)(struct iwl_trans *iwl_trans);
+	int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw);
+	void (*fw_alive)(struct iwl_trans *trans);
 	void (*stop_device)(struct iwl_trans *trans);
-	void (*tx_start)(struct iwl_trans *trans);
 
 	void (*wake_any_queue)(struct iwl_trans *trans,
 			       enum iwl_rxon_context_id ctx,
@@ -191,8 +202,6 @@ struct iwl_trans_ops {
 			     enum iwl_rxon_context_id ctx, int sta_id, int tid,
 			     int frame_limit, u16 ssn);
 
-	void (*kick_nic)(struct iwl_trans *trans);
-
 	void (*free)(struct iwl_trans *trans);
 
 	void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg);
@@ -204,18 +213,9 @@ struct iwl_trans_ops {
 	int (*suspend)(struct iwl_trans *trans);
 	int (*resume)(struct iwl_trans *trans);
 #endif
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
-	dma_addr_t p_addr;	/* hardware address */
-	void *v_addr;		/* software address */
-	u32 len;		/* size in bytes */
-};
-
-struct fw_img {
-	struct fw_desc code;	/* firmware code image */
-	struct fw_desc data;	/* firmware data image */
+	void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
+	void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
+	u32 (*read32)(struct iwl_trans *trans, u32 ofs);
 };
 
 /* Opaque calibration results */
@@ -231,17 +231,31 @@ struct iwl_calib_result {
  * @ops - pointer to iwl_trans_ops
  * @shrd - pointer to iwl_shared which holds shared data from the upper layer
  * @hcmd_lock: protects HCMD
+ * @reg_lock - protect hw register access
+ * @dev - pointer to struct device * that represents the device
+ * @irq - the irq number for the device
+ * @hw_id: a u32 with the ID of the device / subdevice.
+  *	Set during transport alloaction.
+ * @hw_id_str: a string with info about HW ID. Set during transport allocation.
  * @ucode_write_complete: indicates that the ucode has been copied.
  * @ucode_rt: run time ucode image
  * @ucode_init: init ucode image
  * @ucode_wowlan: wake on wireless ucode image (optional)
  * @nvm_device_type: indicates OTP or eeprom
+ * @pm_support: set to true in start_hw if link pm is supported
  * @calib_results: list head for init calibration results
  */
 struct iwl_trans {
 	const struct iwl_trans_ops *ops;
 	struct iwl_shared *shrd;
 	spinlock_t hcmd_lock;
+	spinlock_t reg_lock;
+
+	struct device *dev;
+	unsigned int irq;
+	u32 hw_rev;
+	u32 hw_id;
+	char hw_id_str[52];
 
 	u8 ucode_write_complete;	/* the image write is complete */
 	struct fw_img ucode_rt;
@@ -250,6 +264,7 @@ struct iwl_trans {
 
 	/* eeprom related variables */
 	int    nvm_device_type;
+	bool pm_support;
 
 	/* init calibration results */
 	struct list_head calib_results;
@@ -259,29 +274,31 @@ struct iwl_trans {
 	char trans_specific[0] __attribute__((__aligned__(sizeof(void *))));
 };
 
-static inline int iwl_trans_request_irq(struct iwl_trans *trans)
+static inline int iwl_trans_start_hw(struct iwl_trans *trans)
 {
-	return trans->ops->request_irq(trans);
+	return trans->ops->start_hw(trans);
 }
 
-static inline int iwl_trans_start_device(struct iwl_trans *trans)
+static inline void iwl_trans_stop_hw(struct iwl_trans *trans)
 {
-	return trans->ops->start_device(trans);
+	trans->ops->stop_hw(trans);
 }
 
-static inline int iwl_trans_prepare_card_hw(struct iwl_trans *trans)
+static inline void iwl_trans_fw_alive(struct iwl_trans *trans)
 {
-	return trans->ops->prepare_card_hw(trans);
+	trans->ops->fw_alive(trans);
 }
 
-static inline void iwl_trans_stop_device(struct iwl_trans *trans)
+static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw)
 {
-	trans->ops->stop_device(trans);
+	might_sleep();
+
+	return trans->ops->start_fw(trans, fw);
 }
 
-static inline void iwl_trans_tx_start(struct iwl_trans *trans)
+static inline void iwl_trans_stop_device(struct iwl_trans *trans)
 {
-	trans->ops->tx_start(trans);
+	trans->ops->stop_device(trans);
 }
 
 static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans,
@@ -337,11 +354,6 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans,
 	trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn);
 }
 
-static inline void iwl_trans_kick_nic(struct iwl_trans *trans)
-{
-	trans->ops->kick_nic(trans);
-}
-
 static inline void iwl_trans_free(struct iwl_trans *trans)
 {
 	trans->ops->free(trans);
@@ -380,13 +392,24 @@ static inline int iwl_trans_resume(struct iwl_trans *trans)
 }
 #endif
 
+static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val)
+{
+	trans->ops->write8(trans, ofs, val);
+}
+
+static inline void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val)
+{
+	trans->ops->write32(trans, ofs, val);
+}
+
+static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs)
+{
+	return trans->ops->read32(trans, ofs);
+}
+
 /*****************************************************
-* Transport layers implementations
+* Utils functions
 ******************************************************/
-extern const struct iwl_trans_ops trans_ops_pcie;
-
-int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
-		      const void *data, size_t len);
 void iwl_dealloc_ucode(struct iwl_trans *trans);
 
 int iwl_send_calib_results(struct iwl_trans *trans);
@@ -394,4 +417,18 @@ int iwl_calib_set(struct iwl_trans *trans,
 		  const struct iwl_calib_hdr *cmd, int len);
 void iwl_calib_free_results(struct iwl_trans *trans);
 
+/*****************************************************
+* Transport layers implementations + their allocation function
+******************************************************/
+struct pci_dev;
+struct pci_device_id;
+extern const struct iwl_trans_ops trans_ops_pcie;
+struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd,
+				       struct pci_dev *pdev,
+				       const struct pci_device_id *ent);
+
+extern const struct iwl_trans_ops trans_ops_idi;
+struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd,
+				      void *pdev_void,
+				      const void *ent_void);
 #endif /* __iwl_trans_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c
index 36a1b5b..11b659a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,9 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/dma-mapping.h>
+#include <linux/firmware.h>
 
+#include "iwl-ucode.h"
 #include "iwl-wifi.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
@@ -80,29 +82,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
  *
  ******************************************************************************/
 
-static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc)
+static void iwl_free_fw_desc(struct iwl_trans *trans, struct fw_desc *desc)
 {
 	if (desc->v_addr)
-		dma_free_coherent(bus->dev, desc->len,
+		dma_free_coherent(trans->dev, desc->len,
 				  desc->v_addr, desc->p_addr);
 	desc->v_addr = NULL;
 	desc->len = 0;
 }
 
-static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img)
+static void iwl_free_fw_img(struct iwl_trans *trans, struct fw_img *img)
 {
-	iwl_free_fw_desc(bus, &img->code);
-	iwl_free_fw_desc(bus, &img->data);
+	iwl_free_fw_desc(trans, &img->code);
+	iwl_free_fw_desc(trans, &img->data);
 }
 
 void iwl_dealloc_ucode(struct iwl_trans *trans)
 {
-	iwl_free_fw_img(bus(trans), &trans->ucode_rt);
-	iwl_free_fw_img(bus(trans), &trans->ucode_init);
-	iwl_free_fw_img(bus(trans), &trans->ucode_wowlan);
+	iwl_free_fw_img(trans, &trans->ucode_rt);
+	iwl_free_fw_img(trans, &trans->ucode_init);
+	iwl_free_fw_img(trans, &trans->ucode_wowlan);
 }
 
-int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
+static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc,
 		      const void *data, size_t len)
 {
 	if (!len) {
@@ -110,7 +112,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
 		return -EINVAL;
 	}
 
-	desc->v_addr = dma_alloc_coherent(bus->dev, len,
+	desc->v_addr = dma_alloc_coherent(trans->dev, len,
 					  &desc->p_addr, GFP_KERNEL);
 	if (!desc->v_addr)
 		return -ENOMEM;
@@ -120,59 +122,6 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
 	return 0;
 }
 
-/*
- * ucode
- */
-static int iwl_load_section(struct iwl_trans *trans, const char *name,
-				struct fw_desc *image, u32 dst_addr)
-{
-	struct iwl_bus *bus = bus(trans);
-	dma_addr_t phy_addr = image->p_addr;
-	u32 byte_cnt = image->len;
-	int ret;
-
-	trans->ucode_write_complete = 0;
-
-	iwl_write_direct32(bus,
-		FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
-		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
-
-	iwl_write_direct32(bus,
-		FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
-
-	iwl_write_direct32(bus,
-		FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
-		phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
-
-	iwl_write_direct32(bus,
-		FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
-		(iwl_get_dma_hi_addr(phy_addr)
-			<< FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
-
-	iwl_write_direct32(bus,
-		FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
-		1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
-		1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX |
-		FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
-
-	iwl_write_direct32(bus,
-		FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
-		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE	|
-		FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE	|
-		FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
-
-	IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name);
-	ret = wait_event_timeout(trans->shrd->wait_command_queue,
-				 trans->ucode_write_complete, 5 * HZ);
-	if (!ret) {
-		IWL_ERR(trans, "Could not load the %s uCode section\n",
-			name);
-		return -ETIMEDOUT;
-	}
-
-	return 0;
-}
-
 static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
 					enum iwl_ucode_type ucode_type)
 {
@@ -189,28 +138,6 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans,
 	return NULL;
 }
 
-static int iwl_load_given_ucode(struct iwl_trans *trans,
-				   enum iwl_ucode_type ucode_type)
-{
-	int ret = 0;
-	struct fw_img *image = iwl_get_ucode_image(trans, ucode_type);
-
-
-	if (!image) {
-		IWL_ERR(trans, "Invalid ucode requested (%d)\n",
-			ucode_type);
-		return -EINVAL;
-	}
-
-	ret = iwl_load_section(trans, "INST", &image->code,
-				   IWLAGN_RTC_INST_LOWER_BOUND);
-	if (ret)
-		return ret;
-
-	return iwl_load_section(trans, "DATA", &image->data,
-				    IWLAGN_RTC_DATA_LOWER_BOUND);
-}
-
 /*
  *  Calibration
  */
@@ -447,7 +374,7 @@ static int iwl_alive_notify(struct iwl_trans *trans)
 	if (!priv->tx_cmd_pool)
 		return -ENOMEM;
 
-	iwl_trans_tx_start(trans);
+	iwl_trans_fw_alive(trans);
 	for_each_context(priv, ctx)
 		ctx->last_tx_rejected = false;
 
@@ -470,7 +397,7 @@ static int iwl_alive_notify(struct iwl_trans *trans)
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl_verify_inst_sparse(struct iwl_bus *bus,
+static int iwl_verify_inst_sparse(struct iwl_trans *trans,
 				      struct fw_desc *fw_desc)
 {
 	__le32 *image = (__le32 *)fw_desc->v_addr;
@@ -478,15 +405,15 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus,
 	u32 val;
 	u32 i;
 
-	IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len);
+	IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len);
 
 	for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
 		/* read data comes through single port, auto-incr addr */
 		/* NOTE: Use the debugless read so we don't flood kernel log
 		 * if IWL_DL_IO is set */
-		iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR,
+		iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR,
 			i + IWLAGN_RTC_INST_LOWER_BOUND);
-		val = iwl_read32(bus, HBUS_TARG_MEM_RDAT);
+		val = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image))
 			return -EIO;
 	}
@@ -494,7 +421,7 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus,
 	return 0;
 }
 
-static void iwl_print_mismatch_inst(struct iwl_bus *bus,
+static void iwl_print_mismatch_inst(struct iwl_trans *trans,
 				    struct fw_desc *fw_desc)
 {
 	__le32 *image = (__le32 *)fw_desc->v_addr;
@@ -503,18 +430,18 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus,
 	u32 offs;
 	int errors = 0;
 
-	IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len);
+	IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len);
 
-	iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR,
+	iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR,
 			   IWLAGN_RTC_INST_LOWER_BOUND);
 
 	for (offs = 0;
 	     offs < len && errors < 20;
 	     offs += sizeof(u32), image++) {
 		/* read data comes through single port, auto-incr addr */
-		val = iwl_read32(bus, HBUS_TARG_MEM_RDAT);
+		val = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image)) {
-			IWL_ERR(bus, "uCode INST section at "
+			IWL_ERR(trans, "uCode INST section at "
 				"offset 0x%x, is 0x%x, s/b 0x%x\n",
 				offs, val, le32_to_cpu(*image));
 			errors++;
@@ -536,14 +463,14 @@ static int iwl_verify_ucode(struct iwl_trans *trans,
 		return -EINVAL;
 	}
 
-	if (!iwl_verify_inst_sparse(bus(trans), &img->code)) {
+	if (!iwl_verify_inst_sparse(trans, &img->code)) {
 		IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n");
 		return 0;
 	}
 
 	IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
 
-	iwl_print_mismatch_inst(bus(trans), &img->code);
+	iwl_print_mismatch_inst(trans, &img->code);
 	return -EIO;
 }
 
@@ -647,28 +574,27 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans,
 {
 	struct iwl_notification_wait alive_wait;
 	struct iwl_alive_data alive_data;
+	struct fw_img *fw;
 	int ret;
 	enum iwl_ucode_type old_type;
 
-	ret = iwl_trans_start_device(trans);
-	if (ret)
-		return ret;
-
 	iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE,
 				      iwl_alive_fn, &alive_data);
 
 	old_type = trans->shrd->ucode_type;
 	trans->shrd->ucode_type = ucode_type;
+	fw = iwl_get_ucode_image(trans, ucode_type);
+
+	if (!fw)
+		return -EINVAL;
 
-	ret = iwl_load_given_ucode(trans, ucode_type);
+	ret = iwl_trans_start_fw(trans, fw);
 	if (ret) {
 		trans->shrd->ucode_type = old_type;
 		iwl_remove_notification(trans->shrd, &alive_wait);
 		return ret;
 	}
 
-	iwl_trans_kick_nic(trans);
-
 	/*
 	 * Some things may run in the background now, but we
 	 * just wait for the ALIVE notification here.
@@ -756,3 +682,609 @@ int iwl_run_init_ucode(struct iwl_trans *trans)
 	iwl_trans_stop_device(trans);
 	return ret;
 }
+
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
+
+#define UCODE_EXPERIMENTAL_INDEX	100
+#define UCODE_EXPERIMENTAL_TAG		"exp"
+
+int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
+{
+	const char *name_pre = cfg(priv)->fw_name_pre;
+	char tag[8];
+
+	if (first) {
+#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE
+		priv->fw_index = UCODE_EXPERIMENTAL_INDEX;
+		strcpy(tag, UCODE_EXPERIMENTAL_TAG);
+	} else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
+#endif
+		priv->fw_index = cfg(priv)->ucode_api_max;
+		sprintf(tag, "%d", priv->fw_index);
+	} else {
+		priv->fw_index--;
+		sprintf(tag, "%d", priv->fw_index);
+	}
+
+	if (priv->fw_index < cfg(priv)->ucode_api_min) {
+		IWL_ERR(priv, "no suitable firmware found!\n");
+		return -ENOENT;
+	}
+
+	sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
+
+	IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n",
+		       (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+				? "EXPERIMENTAL " : "",
+		       priv->firmware_name);
+
+	return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
+				       trans(priv)->dev,
+				       GFP_KERNEL, priv, iwl_ucode_callback);
+}
+
+struct iwlagn_firmware_pieces {
+	const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data;
+	size_t inst_size, data_size, init_size, init_data_size,
+	       wowlan_inst_size, wowlan_data_size;
+
+	u32 build;
+
+	u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+	u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+};
+
+static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
+				       const struct firmware *ucode_raw,
+				       struct iwlagn_firmware_pieces *pieces)
+{
+	struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
+	u32 api_ver, hdr_size;
+	const u8 *src;
+
+	priv->ucode_ver = le32_to_cpu(ucode->ver);
+	api_ver = IWL_UCODE_API(priv->ucode_ver);
+
+	switch (api_ver) {
+	default:
+		hdr_size = 28;
+		if (ucode_raw->size < hdr_size) {
+			IWL_ERR(priv, "File size too small!\n");
+			return -EINVAL;
+		}
+		pieces->build = le32_to_cpu(ucode->u.v2.build);
+		pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
+		pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
+		pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
+		pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
+		src = ucode->u.v2.data;
+		break;
+	case 0:
+	case 1:
+	case 2:
+		hdr_size = 24;
+		if (ucode_raw->size < hdr_size) {
+			IWL_ERR(priv, "File size too small!\n");
+			return -EINVAL;
+		}
+		pieces->build = 0;
+		pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
+		pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
+		pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
+		pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
+		src = ucode->u.v1.data;
+		break;
+	}
+
+	/* Verify size of file vs. image size info in file's header */
+	if (ucode_raw->size != hdr_size + pieces->inst_size +
+				pieces->data_size + pieces->init_size +
+				pieces->init_data_size) {
+
+		IWL_ERR(priv,
+			"uCode file size %d does not match expected size\n",
+			(int)ucode_raw->size);
+		return -EINVAL;
+	}
+
+	pieces->inst = src;
+	src += pieces->inst_size;
+	pieces->data = src;
+	src += pieces->data_size;
+	pieces->init = src;
+	src += pieces->init_size;
+	pieces->init_data = src;
+	src += pieces->init_data_size;
+
+	return 0;
+}
+
+static int iwlagn_load_firmware(struct iwl_priv *priv,
+				const struct firmware *ucode_raw,
+				struct iwlagn_firmware_pieces *pieces,
+				struct iwlagn_ucode_capabilities *capa)
+{
+	struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
+	struct iwl_ucode_tlv *tlv;
+	size_t len = ucode_raw->size;
+	const u8 *data;
+	int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative;
+	int tmp;
+	u64 alternatives;
+	u32 tlv_len;
+	enum iwl_ucode_tlv_type tlv_type;
+	const u8 *tlv_data;
+
+	if (len < sizeof(*ucode)) {
+		IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
+		return -EINVAL;
+	}
+
+	if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
+		IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
+			le32_to_cpu(ucode->magic));
+		return -EINVAL;
+	}
+
+	/*
+	 * Check which alternatives are present, and "downgrade"
+	 * when the chosen alternative is not present, warning
+	 * the user when that happens. Some files may not have
+	 * any alternatives, so don't warn in that case.
+	 */
+	alternatives = le64_to_cpu(ucode->alternatives);
+	tmp = wanted_alternative;
+	if (wanted_alternative > 63)
+		wanted_alternative = 63;
+	while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
+		wanted_alternative--;
+	if (wanted_alternative && wanted_alternative != tmp)
+		IWL_WARN(priv,
+			 "uCode alternative %d not available, choosing %d\n",
+			 tmp, wanted_alternative);
+
+	priv->ucode_ver = le32_to_cpu(ucode->ver);
+	pieces->build = le32_to_cpu(ucode->build);
+	data = ucode->data;
+
+	len -= sizeof(*ucode);
+
+	while (len >= sizeof(*tlv)) {
+		u16 tlv_alt;
+
+		len -= sizeof(*tlv);
+		tlv = (void *)data;
+
+		tlv_len = le32_to_cpu(tlv->length);
+		tlv_type = le16_to_cpu(tlv->type);
+		tlv_alt = le16_to_cpu(tlv->alternative);
+		tlv_data = tlv->data;
+
+		if (len < tlv_len) {
+			IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
+				len, tlv_len);
+			return -EINVAL;
+		}
+		len -= ALIGN(tlv_len, 4);
+		data += sizeof(*tlv) + ALIGN(tlv_len, 4);
+
+		/*
+		 * Alternative 0 is always valid.
+		 *
+		 * Skip alternative TLVs that are not selected.
+		 */
+		if (tlv_alt != 0 && tlv_alt != wanted_alternative)
+			continue;
+
+		switch (tlv_type) {
+		case IWL_UCODE_TLV_INST:
+			pieces->inst = tlv_data;
+			pieces->inst_size = tlv_len;
+			break;
+		case IWL_UCODE_TLV_DATA:
+			pieces->data = tlv_data;
+			pieces->data_size = tlv_len;
+			break;
+		case IWL_UCODE_TLV_INIT:
+			pieces->init = tlv_data;
+			pieces->init_size = tlv_len;
+			break;
+		case IWL_UCODE_TLV_INIT_DATA:
+			pieces->init_data = tlv_data;
+			pieces->init_data_size = tlv_len;
+			break;
+		case IWL_UCODE_TLV_BOOT:
+			IWL_ERR(priv, "Found unexpected BOOT ucode\n");
+			break;
+		case IWL_UCODE_TLV_PROBE_MAX_LEN:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			capa->max_probe_length =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_PAN:
+			if (tlv_len)
+				goto invalid_tlv_len;
+			capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
+			break;
+		case IWL_UCODE_TLV_FLAGS:
+			/* must be at least one u32 */
+			if (tlv_len < sizeof(u32))
+				goto invalid_tlv_len;
+			/* and a proper number of u32s */
+			if (tlv_len % sizeof(u32))
+				goto invalid_tlv_len;
+			/*
+			 * This driver only reads the first u32 as
+			 * right now no more features are defined,
+			 * if that changes then either the driver
+			 * will not work with the new firmware, or
+			 * it'll not take advantage of new features.
+			 */
+			capa->flags = le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->init_evtlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->init_evtlog_size =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->init_errlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->inst_evtlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->inst_evtlog_size =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			pieces->inst_errlog_ptr =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
+			if (tlv_len)
+				goto invalid_tlv_len;
+			priv->enhance_sensitivity_table = true;
+			break;
+		case IWL_UCODE_TLV_WOWLAN_INST:
+			pieces->wowlan_inst = tlv_data;
+			pieces->wowlan_inst_size = tlv_len;
+			break;
+		case IWL_UCODE_TLV_WOWLAN_DATA:
+			pieces->wowlan_data = tlv_data;
+			pieces->wowlan_data_size = tlv_len;
+			break;
+		case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
+			if (tlv_len != sizeof(u32))
+				goto invalid_tlv_len;
+			capa->standard_phy_calibration_size =
+					le32_to_cpup((__le32 *)tlv_data);
+			break;
+		default:
+			IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
+			break;
+		}
+	}
+
+	if (len) {
+		IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
+		iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
+		return -EINVAL;
+	}
+
+	return 0;
+
+ invalid_tlv_len:
+	IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
+	iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
+
+	return -EINVAL;
+}
+
+/**
+ * iwl_ucode_callback - callback when firmware was loaded
+ *
+ * If loaded successfully, copies the firmware into buffers
+ * for the card to fetch (via DMA).
+ */
+static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
+{
+	struct iwl_priv *priv = context;
+	struct iwl_ucode_header *ucode;
+	int err;
+	struct iwlagn_firmware_pieces pieces;
+	const unsigned int api_max = cfg(priv)->ucode_api_max;
+	unsigned int api_ok = cfg(priv)->ucode_api_ok;
+	const unsigned int api_min = cfg(priv)->ucode_api_min;
+	u32 api_ver;
+	char buildstr[25];
+	u32 build;
+	struct iwlagn_ucode_capabilities ucode_capa = {
+		.max_probe_length = 200,
+		.standard_phy_calibration_size =
+			IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE,
+	};
+
+	if (!api_ok)
+		api_ok = api_max;
+
+	memset(&pieces, 0, sizeof(pieces));
+
+	if (!ucode_raw) {
+		if (priv->fw_index <= api_ok)
+			IWL_ERR(priv,
+				"request for firmware file '%s' failed.\n",
+				priv->firmware_name);
+		goto try_again;
+	}
+
+	IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
+		       priv->firmware_name, ucode_raw->size);
+
+	/* Make sure that we got at least the API version number */
+	if (ucode_raw->size < 4) {
+		IWL_ERR(priv, "File size way too small!\n");
+		goto try_again;
+	}
+
+	/* Data from ucode file:  header followed by uCode images */
+	ucode = (struct iwl_ucode_header *)ucode_raw->data;
+
+	if (ucode->ver)
+		err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
+	else
+		err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
+					   &ucode_capa);
+
+	if (err)
+		goto try_again;
+
+	api_ver = IWL_UCODE_API(priv->ucode_ver);
+	build = pieces.build;
+
+	/*
+	 * api_ver should match the api version forming part of the
+	 * firmware filename ... but we don't check for that and only rely
+	 * on the API version read from firmware header from here on forward
+	 */
+	/* no api version check required for experimental uCode */
+	if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) {
+		if (api_ver < api_min || api_ver > api_max) {
+			IWL_ERR(priv,
+				"Driver unable to support your firmware API. "
+				"Driver supports v%u, firmware is v%u.\n",
+				api_max, api_ver);
+			goto try_again;
+		}
+
+		if (api_ver < api_ok) {
+			if (api_ok != api_max)
+				IWL_ERR(priv, "Firmware has old API version, "
+					"expected v%u through v%u, got v%u.\n",
+					api_ok, api_max, api_ver);
+			else
+				IWL_ERR(priv, "Firmware has old API version, "
+					"expected v%u, got v%u.\n",
+					api_max, api_ver);
+			IWL_ERR(priv, "New firmware can be obtained from "
+				      "http://www.intellinuxwireless.org/.\n");
+		}
+	}
+
+	if (build)
+		sprintf(buildstr, " build %u%s", build,
+		       (priv->fw_index == UCODE_EXPERIMENTAL_INDEX)
+				? " (EXP)" : "");
+	else
+		buildstr[0] = '\0';
+
+	IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
+		 IWL_UCODE_MAJOR(priv->ucode_ver),
+		 IWL_UCODE_MINOR(priv->ucode_ver),
+		 IWL_UCODE_API(priv->ucode_ver),
+		 IWL_UCODE_SERIAL(priv->ucode_ver),
+		 buildstr);
+
+	snprintf(priv->hw->wiphy->fw_version,
+		 sizeof(priv->hw->wiphy->fw_version),
+		 "%u.%u.%u.%u%s",
+		 IWL_UCODE_MAJOR(priv->ucode_ver),
+		 IWL_UCODE_MINOR(priv->ucode_ver),
+		 IWL_UCODE_API(priv->ucode_ver),
+		 IWL_UCODE_SERIAL(priv->ucode_ver),
+		 buildstr);
+
+	/*
+	 * For any of the failures below (before allocating pci memory)
+	 * we will try to load a version with a smaller API -- maybe the
+	 * user just got a corrupted version of the latest API.
+	 */
+
+	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
+		       priv->ucode_ver);
+	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
+		       pieces.inst_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
+		       pieces.data_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
+		       pieces.init_size);
+	IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
+		       pieces.init_data_size);
+
+	/* Verify that uCode images will fit in card's SRAM */
+	if (pieces.inst_size > hw_params(priv).max_inst_size) {
+		IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
+			pieces.inst_size);
+		goto try_again;
+	}
+
+	if (pieces.data_size > hw_params(priv).max_data_size) {
+		IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
+			pieces.data_size);
+		goto try_again;
+	}
+
+	if (pieces.init_size > hw_params(priv).max_inst_size) {
+		IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
+			pieces.init_size);
+		goto try_again;
+	}
+
+	if (pieces.init_data_size > hw_params(priv).max_data_size) {
+		IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
+			pieces.init_data_size);
+		goto try_again;
+	}
+
+	/* Allocate ucode buffers for card's bus-master loading ... */
+
+	/* Runtime instructions and 2 copies of data:
+	 * 1) unmodified from disk
+	 * 2) backup cache for save/restore during power-downs */
+	if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code,
+			      pieces.inst, pieces.inst_size))
+		goto err_pci_alloc;
+	if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data,
+			      pieces.data, pieces.data_size))
+		goto err_pci_alloc;
+
+	/* Initialization instructions and data */
+	if (pieces.init_size && pieces.init_data_size) {
+		if (iwl_alloc_fw_desc(trans(priv),
+				      &trans(priv)->ucode_init.code,
+				      pieces.init, pieces.init_size))
+			goto err_pci_alloc;
+		if (iwl_alloc_fw_desc(trans(priv),
+				      &trans(priv)->ucode_init.data,
+				      pieces.init_data, pieces.init_data_size))
+			goto err_pci_alloc;
+	}
+
+	/* WoWLAN instructions and data */
+	if (pieces.wowlan_inst_size && pieces.wowlan_data_size) {
+		if (iwl_alloc_fw_desc(trans(priv),
+				      &trans(priv)->ucode_wowlan.code,
+				      pieces.wowlan_inst,
+				      pieces.wowlan_inst_size))
+			goto err_pci_alloc;
+		if (iwl_alloc_fw_desc(trans(priv),
+				      &trans(priv)->ucode_wowlan.data,
+				      pieces.wowlan_data,
+				      pieces.wowlan_data_size))
+			goto err_pci_alloc;
+	}
+
+	/* Now that we can no longer fail, copy information */
+
+	/*
+	 * The (size - 16) / 12 formula is based on the information recorded
+	 * for each event, which is of mode 1 (including timestamp) for all
+	 * new microcodes that include this information.
+	 */
+	priv->init_evtlog_ptr = pieces.init_evtlog_ptr;
+	if (pieces.init_evtlog_size)
+		priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
+	else
+		priv->init_evtlog_size =
+			cfg(priv)->base_params->max_event_log_size;
+	priv->init_errlog_ptr = pieces.init_errlog_ptr;
+	priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
+	if (pieces.inst_evtlog_size)
+		priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
+	else
+		priv->inst_evtlog_size =
+			cfg(priv)->base_params->max_event_log_size;
+	priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
+#ifndef CONFIG_IWLWIFI_P2P
+	ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+#endif
+
+	priv->new_scan_threshold_behaviour =
+		!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
+
+	if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE))
+		ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
+
+	/*
+	 * if not PAN, then don't support P2P -- might be a uCode
+	 * packaging bug or due to the eeprom check above
+	 */
+	if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN))
+		ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P;
+
+	if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
+		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
+		priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+	} else {
+		priv->sta_key_max_num = STA_KEY_MAX_NUM;
+		priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
+	}
+	/*
+	 * figure out the offset of chain noise reset and gain commands
+	 * base on the size of standard phy calibration commands table size
+	 */
+	if (ucode_capa.standard_phy_calibration_size >
+	    IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
+		ucode_capa.standard_phy_calibration_size =
+			IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
+
+	priv->phy_calib_chain_noise_reset_cmd =
+		ucode_capa.standard_phy_calibration_size;
+	priv->phy_calib_chain_noise_gain_cmd =
+		ucode_capa.standard_phy_calibration_size + 1;
+
+	/* initialize all valid contexts */
+	iwl_init_context(priv, ucode_capa.flags);
+
+	/**************************************************
+	 * This is still part of probe() in a sense...
+	 *
+	 * 9. Setup and register with mac80211 and debugfs
+	 **************************************************/
+	err = iwlagn_mac_setup_register(priv, &ucode_capa);
+	if (err)
+		goto out_unbind;
+
+	err = iwl_dbgfs_register(priv, DRV_NAME);
+	if (err)
+		IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
+
+	/* We have our copies now, allow OS release its copies */
+	release_firmware(ucode_raw);
+	complete(&priv->firmware_loading_complete);
+	return;
+
+ try_again:
+	/* try next, if any */
+	if (iwl_request_firmware(priv, false))
+		goto out_unbind;
+	release_firmware(ucode_raw);
+	return;
+
+ err_pci_alloc:
+	IWL_ERR(priv, "failed to allocate pci memory\n");
+	iwl_dealloc_ucode(trans(priv));
+ out_unbind:
+	complete(&priv->firmware_loading_complete);
+	device_release_driver(trans(priv)->dev);
+	release_firmware(ucode_raw);
+}
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h
new file mode 100644
index 0000000..eccf925
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-ucode.h
@@ -0,0 +1,178 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#ifndef __iwl_ucode_h__
+#define __iwl_ucode_h__
+
+/* v1/v2 uCode file layout */
+struct iwl_ucode_header {
+	__le32 ver;	/* major/minor/API/serial */
+	union {
+		struct {
+			__le32 inst_size;	/* bytes of runtime code */
+			__le32 data_size;	/* bytes of runtime data */
+			__le32 init_size;	/* bytes of init code */
+			__le32 init_data_size;	/* bytes of init data */
+			__le32 boot_size;	/* bytes of bootstrap code */
+			u8 data[0];		/* in same order as sizes */
+		} v1;
+		struct {
+			__le32 build;		/* build number */
+			__le32 inst_size;	/* bytes of runtime code */
+			__le32 data_size;	/* bytes of runtime data */
+			__le32 init_size;	/* bytes of init code */
+			__le32 init_data_size;	/* bytes of init data */
+			__le32 boot_size;	/* bytes of bootstrap code */
+			u8 data[0];		/* in same order as sizes */
+		} v2;
+	} u;
+};
+
+/*
+ * new TLV uCode file layout
+ *
+ * The new TLV file format contains TLVs, that each specify
+ * some piece of data. To facilitate "groups", for example
+ * different instruction image with different capabilities,
+ * bundled with the same init image, an alternative mechanism
+ * is provided:
+ * When the alternative field is 0, that means that the item
+ * is always valid. When it is non-zero, then it is only
+ * valid in conjunction with items of the same alternative,
+ * in which case the driver (user) selects one alternative
+ * to use.
+ */
+
+enum iwl_ucode_tlv_type {
+	IWL_UCODE_TLV_INVALID		= 0, /* unused */
+	IWL_UCODE_TLV_INST		= 1,
+	IWL_UCODE_TLV_DATA		= 2,
+	IWL_UCODE_TLV_INIT		= 3,
+	IWL_UCODE_TLV_INIT_DATA		= 4,
+	IWL_UCODE_TLV_BOOT		= 5,
+	IWL_UCODE_TLV_PROBE_MAX_LEN	= 6, /* a u32 value */
+	IWL_UCODE_TLV_PAN		= 7,
+	IWL_UCODE_TLV_RUNT_EVTLOG_PTR	= 8,
+	IWL_UCODE_TLV_RUNT_EVTLOG_SIZE	= 9,
+	IWL_UCODE_TLV_RUNT_ERRLOG_PTR	= 10,
+	IWL_UCODE_TLV_INIT_EVTLOG_PTR	= 11,
+	IWL_UCODE_TLV_INIT_EVTLOG_SIZE	= 12,
+	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13,
+	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14,
+	IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
+	IWL_UCODE_TLV_WOWLAN_INST	= 16,
+	IWL_UCODE_TLV_WOWLAN_DATA	= 17,
+	IWL_UCODE_TLV_FLAGS		= 18,
+};
+
+/**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+ *	was a separate TLV but moved here to save space.
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ *	treats good CRC threshold as a boolean
+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
+ */
+enum iwl_ucode_tlv_flag {
+	IWL_UCODE_TLV_FLAGS_PAN		= BIT(0),
+	IWL_UCODE_TLV_FLAGS_NEWSCAN	= BIT(1),
+	IWL_UCODE_TLV_FLAGS_MFP		= BIT(2),
+	IWL_UCODE_TLV_FLAGS_P2P		= BIT(3),
+};
+
+struct iwl_ucode_tlv {
+	__le16 type;		/* see above */
+	__le16 alternative;	/* see comment */
+	__le32 length;		/* not including type/length fields */
+	u8 data[0];
+};
+
+#define IWL_TLV_UCODE_MAGIC	0x0a4c5749
+
+struct iwl_tlv_ucode_header {
+	/*
+	 * The TLV style ucode header is distinguished from
+	 * the v1/v2 style header by first four bytes being
+	 * zero, as such is an invalid combination of
+	 * major/minor/API/serial versions.
+	 */
+	__le32 zero;
+	__le32 magic;
+	u8 human_readable[64];
+	__le32 ver;		/* major/minor/API/serial */
+	__le32 build;
+	__le64 alternatives;	/* bitmask of valid alternatives */
+	/*
+	 * The data contained herein has a TLV layout,
+	 * see above for the TLV header and types.
+	 * Note that each TLV is padded to a length
+	 * that is a multiple of 4 for alignment.
+	 */
+	u8 data[0];
+};
+
+struct iwl_priv;
+
+int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first);
+
+#endif  /* __iwl_ucode_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h
index 1850110..7e6eb20 100644
--- a/drivers/net/wireless/iwlwifi/iwl-wifi.h
+++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
  *
  * BSD LICENSE
  *
- * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h
index abb4805..f5f7070 100644
--- a/drivers/net/wireless/iwmc3200wifi/trace.h
+++ b/drivers/net/wireless/iwmc3200wifi/trace.h
@@ -144,7 +144,7 @@ TRACE_EVENT(iwm_tx_packets,
 
 	TP_printk(
 		IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, "
-		"ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes",
+		"ra_tid 0x%x, credit_group 0x%x, embedded_packets %d, %d bytes",
 		IWM_PR_ARG, !__entry->eot ? "concatenated " : "",
 		__entry->eot, __entry->seq, __entry->color, __entry->ra_tid,
 		__entry->credit_group, __entry->npkt, __entry->bytes
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 3f7bf4d..234ee88 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -815,10 +815,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
 	lbs_deb_enter(LBS_DEB_CS);
 
 	card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
-	if (!card) {
-		pr_err("error in kzalloc\n");
+	if (!card)
 		goto out;
-	}
+
 	card->p_dev = p_dev;
 	p_dev->priv = card;
 
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index b5fbbc7..74da5f1 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -261,10 +261,8 @@ static int if_usb_probe(struct usb_interface *intf,
 	udev = interface_to_usbdev(intf);
 
 	cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
-	if (!cardp) {
-		pr_err("Out of memory allocating private data\n");
+	if (!cardp)
 		goto error;
-	}
 
 	setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
 	init_waitqueue_head(&cardp->fw_wq);
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index aff8b57..7ced130 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -153,10 +153,8 @@ static int if_usb_probe(struct usb_interface *intf,
 	udev = interface_to_usbdev(intf);
 
 	cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
-	if (!cardp) {
-		pr_err("Out of memory allocating private data.\n");
+	if (!cardp)
 		goto error;
-	}
 
 	setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
 	init_waitqueue_head(&cardp->fw_wq);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 4b9e730..29e930a 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -592,7 +592,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
 	return;
 
 nla_put_failure:
-	printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+	printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
 }
 
 static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
@@ -1564,7 +1564,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 
 	return 0;
 err:
-	printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+	printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
 	goto out;
 out:
 	dev_kfree_skb(skb);
@@ -1584,7 +1584,7 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
 
 	return 0;
 out:
-	printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+	printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
 	return -EINVAL;
 }
 
@@ -1647,7 +1647,7 @@ static int hwsim_init_netlink(void)
 	return 0;
 
 failure:
-	printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__);
+	printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
 	return -EINVAL;
 }
 
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 079e553..ea6832d 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -182,7 +182,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
 	skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
 	tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
 
-	tx_info_aggr->bss_index = tx_info_src->bss_index;
+	tx_info_aggr->bss_type = tx_info_src->bss_type;
+	tx_info_aggr->bss_num = tx_info_src->bss_num;
 	skb_aggr->priority = skb_src->priority;
 
 	do {
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c3b6c46..8d8ee63 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -79,7 +79,7 @@ static int
 mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
 			 u8 key_index, bool pairwise, const u8 *mac_addr)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
 	if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
 		wiphy_err(wiphy, "deleting the crypto keys\n");
@@ -122,7 +122,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
 				struct net_device *dev,
 				bool enabled, int timeout)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 	u32 ps_mode;
 
 	if (timeout)
@@ -143,7 +143,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
 				 u8 key_index, bool unicast,
 				 bool multicast)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
 	/* Return if WEP key not configured */
 	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED)
@@ -165,7 +165,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
 			 u8 key_index, bool pairwise, const u8 *mac_addr,
 			 struct key_params *params)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
 
 	if (mwifiex_set_encode(priv, params->key, params->key_len,
 							key_index, 0)) {
@@ -376,7 +376,12 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
 			     struct ieee80211_channel *chan,
 			     enum nl80211_channel_type channel_type)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv;
+
+	if (dev)
+		priv = mwifiex_netdev_get_priv(dev);
+	else
+		priv = mwifiex_cfg80211_get_priv(wiphy);
 
 	if (priv->media_connected) {
 		wiphy_err(wiphy, "This setting is valid only when station "
@@ -534,6 +539,11 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
 		ret = -EFAULT;
 	}
 
+	/* Get DTIM period information from firmware */
+	mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+			      HostCmd_ACT_GEN_GET, DTIM_PERIOD_I,
+			      &priv->dtim_period);
+
 	/*
 	 * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid
 	 * MCS index values for us are 0 to 7.
@@ -557,6 +567,22 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
 	/* bit rate is in 500 kb/s units. Convert it to 100kb/s units */
 	sinfo->txrate.legacy = rate.rate * 5;
 
+	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+		sinfo->filled |= STATION_INFO_BSS_PARAM;
+		sinfo->bss_param.flags = 0;
+		if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
+						WLAN_CAPABILITY_SHORT_PREAMBLE)
+			sinfo->bss_param.flags |=
+					BSS_PARAM_FLAGS_SHORT_PREAMBLE;
+		if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
+						WLAN_CAPABILITY_SHORT_SLOT_TIME)
+			sinfo->bss_param.flags |=
+					BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
+		sinfo->bss_param.dtim_period = priv->dtim_period;
+		sinfo->bss_param.beacon_interval =
+			priv->curr_bss_params.bss_descriptor.beacon_period;
+	}
+
 	return ret;
 }
 
@@ -841,7 +867,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
 		ret = mwifiex_set_rf_channel(priv, channel,
 						priv->adapter->channel_type);
 
-	ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);	/* Disable keys */
+	/* As this is new association, clear locally stored
+	 * keys and security related flags */
+	priv->sec_info.wpa_enabled = false;
+	priv->sec_info.wpa2_enabled = false;
+	priv->wep_key_curr_index = 0;
+	ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
 
 	if (mode == NL80211_IFTYPE_ADHOC) {
 		/* "privacy" is set only for ad-hoc mode */
@@ -886,6 +917,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
 			dev_dbg(priv->adapter->dev,
 				"info: setting wep encryption"
 				" with key len %d\n", sme->key_len);
+			priv->wep_key_curr_index = sme->key_idx;
 			ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
 							sme->key_idx, 0);
 		}
@@ -1004,7 +1036,7 @@ static int
 mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
 			   struct cfg80211_ibss_params *params)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 	int ret = 0;
 
 	if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
@@ -1042,7 +1074,7 @@ done:
 static int
 mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
 	wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
 			priv->cfg_bssid);
@@ -1217,7 +1249,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 		priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
 		priv->bss_priority = 0;
 		priv->bss_role = MWIFIEX_BSS_ROLE_STA;
-		priv->bss_index = 0;
 		priv->bss_num = 0;
 
 		break;
@@ -1281,10 +1312,7 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
  */
 int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
 {
-	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
-
-	if (!priv || !dev)
-		return 0;
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
 #ifdef CONFIG_DEBUG_FS
 	mwifiex_dev_debugfs_remove(priv);
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 6e0a3ea..6623db6 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -391,7 +391,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
 
 	if (skb) {
 		rx_info = MWIFIEX_SKB_RXCB(skb);
-		rx_info->bss_index = priv->bss_index;
+		rx_info->bss_num = priv->bss_num;
+		rx_info->bss_type = priv->bss_type;
 	}
 
 	if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index ae17ce0..3735c77 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -102,7 +102,8 @@ struct mwifiex_wait_queue {
 };
 
 struct mwifiex_rxinfo {
-	u8 bss_index;
+	u8 bss_num;
+	u8 bss_type;
 	struct sk_buff *parent;
 	u8 use_count;
 };
@@ -110,7 +111,8 @@ struct mwifiex_rxinfo {
 struct mwifiex_txinfo {
 	u32 status_code;
 	u8 flags;
-	u8 bss_index;
+	u8 bss_num;
+	u8 bss_type;
 };
 
 enum mwifiex_wmm_ac_e {
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 1d0ec57..ca59cc0 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -280,6 +280,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
 	adapter->adhoc_awake_period = 0;
 	memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
 	adapter->arp_filter_size = 0;
+	adapter->channel_type = NL80211_CHAN_HT20;
 }
 
 /*
@@ -527,8 +528,9 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
 		cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
 		lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
 		dev_dbg(adapter->dev, "info: delete BSS priority table,"
-				" index = %d, i = %d, head = %p, cur = %p\n",
-			      priv->bss_index, i, head, *cur);
+				" bss_type = %d, bss_num = %d, i = %d,"
+				" head = %p, cur = %p\n",
+			      priv->bss_type, priv->bss_num, i, head, *cur);
 		if (*cur) {
 			spin_lock_irqsave(lock, flags);
 			if (list_empty(head)) {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index b728f54..790a379 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -424,8 +424,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct sk_buff *new_skb;
 	struct mwifiex_txinfo *tx_info;
 
-	dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
-				jiffies, priv->bss_index);
+	dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
+				jiffies, priv->bss_type, priv->bss_num);
 
 	if (priv->adapter->surprise_removed) {
 		kfree_skb(skb);
@@ -458,10 +458,11 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
-	tx_info->bss_index = priv->bss_index;
+	tx_info->bss_num = priv->bss_num;
+	tx_info->bss_type = priv->bss_type;
 	mwifiex_fill_buffer(skb);
 
-	mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
+	mwifiex_wmm_add_buf_txqueue(priv, skb);
 	atomic_inc(&priv->adapter->tx_pending);
 
 	if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
@@ -531,8 +532,8 @@ mwifiex_tx_timeout(struct net_device *dev)
 {
 	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 
-	dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
-				jiffies, priv->bss_index);
+	dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
+				jiffies, priv->bss_type, priv->bss_num);
 	mwifiex_set_trans_start(dev);
 	priv->num_tx_timeout++;
 }
@@ -605,18 +606,6 @@ int is_command_pending(struct mwifiex_adapter *adapter)
 }
 
 /*
- * This function returns the correct private structure pointer based
- * upon the BSS number.
- */
-struct mwifiex_private *
-mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
-{
-	if (!adapter || (bss_index >= adapter->priv_num))
-		return NULL;
-	return adapter->priv[bss_index];
-}
-
-/*
  * This is the main work queue function.
  *
  * It handles the main process, which in turn handles the complete
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 3186aa4..52810b1 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -352,7 +352,6 @@ struct mwifiex_private;
 
 struct mwifiex_private {
 	struct mwifiex_adapter *adapter;
-	u8 bss_index;
 	u8 bss_type;
 	u8 bss_role;
 	u8 bss_priority;
@@ -392,6 +391,7 @@ struct mwifiex_private {
 	u8 prev_bssid[ETH_ALEN];
 	struct mwifiex_current_bss_params curr_bss_params;
 	u16 beacon_period;
+	u8 dtim_period;
 	u16 listen_interval;
 	u16 atim_window;
 	u8 adhoc_channel;
@@ -884,8 +884,6 @@ mwifiex_netdev_get_priv(struct net_device *dev)
 	return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
 }
 
-struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
-						*adapter, u8 bss_index);
 int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
 			     u32 func_init_shutdown);
 int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4053509..f4fbad9 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -86,10 +86,8 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
 				pdev->vendor, pdev->device, pdev->revision);
 
 	card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL);
-	if (!card) {
-		pr_err("%s: failed to alloc memory\n", __func__);
+	if (!card)
 		return -ENOMEM;
-	}
 
 	card->dev = pdev;
 
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 6396d33..98f1ca9 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -2001,7 +2001,7 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
 
 		kfree(priv->curr_bcn_buf);
 		priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
-						GFP_KERNEL);
+						GFP_ATOMIC);
 		if (!priv->curr_bcn_buf) {
 			dev_err(priv->adapter->dev,
 					"failed to alloc curr_bcn_buf\n");
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index d39d845..8359027 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -70,10 +70,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
 	       func->vendor, func->device, func->class, func->num);
 
 	card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
-	if (!card) {
-		pr_err("%s: failed to alloc memory\n", __func__);
+	if (!card)
 		return -ENOMEM;
-	}
 
 	card->func = func;
 
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 6e443ff..324c651 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -103,7 +103,7 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv,
 static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
 				       struct host_cmd_ds_command *cmd,
 				       u16 cmd_action, u32 cmd_oid,
-				       u32 *ul_temp)
+				       u16 *ul_temp)
 {
 	struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib;
 
@@ -112,62 +112,18 @@ static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
 	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
 		- 1 + S_DS_GEN);
 
+	snmp_mib->oid = cpu_to_le16((u16)cmd_oid);
 	if (cmd_action == HostCmd_ACT_GEN_GET) {
 		snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
 		snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
-		cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-			+ MAX_SNMP_BUF_SIZE);
+		le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE);
+	} else if (cmd_action == HostCmd_ACT_GEN_SET) {
+		snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+		snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+		*((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp);
+		le16_add_cpu(&cmd->size, sizeof(u16));
 	}
 
-	switch (cmd_oid) {
-	case FRAG_THRESH_I:
-		snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I);
-		if (cmd_action == HostCmd_ACT_GEN_SET) {
-			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-			*((__le16 *) (snmp_mib->value)) =
-				cpu_to_le16((u16) *ul_temp);
-			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-				+ sizeof(u16));
-		}
-		break;
-	case RTS_THRESH_I:
-		snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I);
-		if (cmd_action == HostCmd_ACT_GEN_SET) {
-			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-			*(__le16 *) (snmp_mib->value) =
-				cpu_to_le16((u16) *ul_temp);
-			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-				+ sizeof(u16));
-		}
-		break;
-
-	case SHORT_RETRY_LIM_I:
-		snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I);
-		if (cmd_action == HostCmd_ACT_GEN_SET) {
-			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-			*((__le16 *) (snmp_mib->value)) =
-				cpu_to_le16((u16) *ul_temp);
-			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-				+ sizeof(u16));
-		}
-		break;
-	case DOT11D_I:
-		snmp_mib->oid = cpu_to_le16((u16) DOT11D_I);
-		if (cmd_action == HostCmd_ACT_GEN_SET) {
-			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
-			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
-			*((__le16 *) (snmp_mib->value)) =
-				cpu_to_le16((u16) *ul_temp);
-			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
-				+ sizeof(u16));
-		}
-		break;
-	default:
-		break;
-	}
 	dev_dbg(priv->adapter->dev,
 		"cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
 		" Value=0x%x\n",
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index e812db8..0d8618a 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -210,6 +210,9 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
 			dev_dbg(priv->adapter->dev,
 				"info: SNMP_RESP: TxRetryCount=%u\n", ul_temp);
 			break;
+		case DTIM_PERIOD_I:
+			dev_dbg(priv->adapter->dev,
+				"info: SNMP_RESP: DTIM period=%u\n", ul_temp);
 		default:
 			break;
 		}
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 5e1ef7e..d7a5d76 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -43,7 +43,8 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
 {
 	int ret;
 	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
-	struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+	struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
+			rx_info->bss_num, rx_info->bss_type);
 	struct rx_packet_hdr *rx_pkt_hdr;
 	struct rxpd *local_rx_pd;
 	int hdr_chop;
@@ -124,7 +125,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
 	struct rx_packet_hdr *rx_pkt_hdr;
 	u8 ta[ETH_ALEN];
 	u16 rx_pkt_type;
-	struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+	struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter,
+			rx_info->bss_num, rx_info->bss_type);
 
 	if (!priv)
 		return -1;
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index d97facd..94d31a9 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -136,7 +136,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
 		return -1;
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
-	tx_info->bss_index = priv->bss_index;
+	tx_info->bss_num = priv->bss_num;
+	tx_info->bss_type = priv->bss_type;
 	skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN);
 	skb_push(skb, sizeof(struct txpd));
 
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index d9274a1..9a6eacc 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -48,7 +48,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
 	if (!priv)
 		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
 
-	rx_info->bss_index = priv->bss_index;
+	rx_info->bss_num = priv->bss_num;
+	rx_info->bss_type = priv->bss_type;
 
 	return mwifiex_process_sta_rx_packet(adapter, skb);
 }
@@ -130,7 +131,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
 		return 0;
 
 	tx_info = MWIFIEX_SKB_TXCB(skb);
-	priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index);
+	priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
+			tx_info->bss_type);
 	if (!priv)
 		goto done;
 
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 06976f5..9c48f37 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -159,7 +159,8 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
 		return -1;
 
 	rx_info = MWIFIEX_SKB_RXCB(skb);
-	priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
+	priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num,
+			rx_info->bss_type);
 	if (!priv)
 		return -1;
 
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 6c239c3..75f79ef 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -599,11 +599,10 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv,
  * is queued at the list tail.
  */
 void
-mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
+mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
 			    struct sk_buff *skb)
 {
-	struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
-	struct mwifiex_private *priv = adapter->priv[tx_info->bss_index];
+	struct mwifiex_adapter *adapter = priv->adapter;
 	u32 tid;
 	struct mwifiex_ra_list_tbl *ra_list;
 	u8 ra[ETH_ALEN], tid_down;
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index fcea1f6..ec83995 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -80,8 +80,8 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead)
 	return true;
 }
 
-void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
-				 struct sk_buff *skb);
+void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv,
+					struct sk_buff *skb);
 void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
 
 int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index dd5aeaf..b48674b 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -402,6 +402,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
 #define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
 #define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
 #define MWL8K_CMD_GET_WATCHDOG_BITMAP	0x0205
+#define MWL8K_CMD_DEL_MAC_ADDR		0x0206		/* per-vif */
 #define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
 #define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
 #define MWL8K_CMD_UPDATE_ENCRYPTION	0x1122		/* per-vif */
@@ -1330,7 +1331,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 								wh->addr1);
 
 			if (mwl8k_vif != NULL &&
-			    mwl8k_vif->is_hw_crypto_enabled == true) {
+			    mwl8k_vif->is_hw_crypto_enabled) {
 				/*
 				 * When MMIC ERROR is encountered
 				 * by the firmware, payload is
@@ -1993,8 +1994,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 	 */
 
 	if (txq->len >= MWL8K_TX_DESCS - 2) {
-		if (mgmtframe == false ||
-			txq->len == MWL8K_TX_DESCS) {
+		if (!mgmtframe || txq->len == MWL8K_TX_DESCS) {
 			if (start_ba_session) {
 				spin_lock(&priv->stream_lock);
 				mwl8k_remove_stream(hw, stream);
@@ -3430,10 +3430,7 @@ static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable)
 	return rc;
 }
 
-/*
- * CMD_SET_MAC_ADDR.
- */
-struct mwl8k_cmd_set_mac_addr {
+struct mwl8k_cmd_update_mac_addr {
 	struct mwl8k_cmd_pkt header;
 	union {
 		struct {
@@ -3449,12 +3446,12 @@ struct mwl8k_cmd_set_mac_addr {
 #define MWL8K_MAC_TYPE_PRIMARY_AP		2
 #define MWL8K_MAC_TYPE_SECONDARY_AP		3
 
-static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
-				  struct ieee80211_vif *vif, u8 *mac)
+static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif, u8 *mac, bool set)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
-	struct mwl8k_cmd_set_mac_addr *cmd;
+	struct mwl8k_cmd_update_mac_addr *cmd;
 	int mac_type;
 	int rc;
 
@@ -3475,7 +3472,11 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
 	if (cmd == NULL)
 		return -ENOMEM;
 
-	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+	if (set)
+		cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
+	else
+		cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR);
+
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	if (priv->ap_fw) {
 		cmd->mbss.mac_type = cpu_to_le16(mac_type);
@@ -3491,6 +3492,24 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
 }
 
 /*
+ * MWL8K_CMD_SET_MAC_ADDR.
+ */
+static inline int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif, u8 *mac)
+{
+	return mwl8k_cmd_update_mac_addr(hw, vif, mac, true);
+}
+
+/*
+ * MWL8K_CMD_DEL_MAC_ADDR.
+ */
+static inline int mwl8k_cmd_del_mac_addr(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif, u8 *mac)
+{
+	return mwl8k_cmd_update_mac_addr(hw, vif, mac, false);
+}
+
+/*
  * CMD_SET_RATEADAPT_MODE.
  */
 struct mwl8k_cmd_set_rate_adapt_mode {
@@ -4093,7 +4112,7 @@ static int mwl8k_set_key(struct ieee80211_hw *hw,
 		return -EOPNOTSUPP;
 
 	if (sta == NULL)
-		addr = hw->wiphy->perm_addr;
+		addr = vif->addr;
 	else
 		addr = sta->addr;
 
@@ -4542,7 +4561,7 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
 	if (priv->ap_fw)
 		mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
 
-	mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
+	mwl8k_cmd_del_mac_addr(hw, vif, vif->addr);
 
 	mwl8k_remove_vif(priv, mwl8k_vif);
 }
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 9fb77d0..dd6c64a 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -941,11 +941,9 @@ void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw)
 
 	/* Add desc and skb to rx queue */
 	rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
-	if (!rx_data) {
-		printk(KERN_WARNING "%s: Can't allocate RX packet\n",
-			dev->name);
+	if (!rx_data)
 		goto drop;
-	}
+
 	rx_data->desc = desc;
 	rx_data->skb = skb;
 	list_add_tail(&rx_data->list, &priv->rx_list);
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index ae8ce56..f634d45 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -1754,11 +1754,6 @@ static struct usb_driver orinoco_driver = {
 	.id_table = ezusb_table,
 };
 
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-	" (Manuel Estrada Sainz)";
-
 module_usb_driver(orinoco_driver);
 
 MODULE_AUTHOR("Manuel Estrada Sainz");
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index af2ca1a..40f4eb7 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -228,6 +228,8 @@ static int p54_add_interface(struct ieee80211_hw *dev,
 {
 	struct p54_common *priv = dev->priv;
 
+	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
 	mutex_lock(&priv->conf_mutex);
 	if (priv->mode != NL80211_IFTYPE_MONITOR) {
 		mutex_unlock(&priv->conf_mutex);
@@ -734,7 +736,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
 		     IEEE80211_HW_SIGNAL_DBM |
 		     IEEE80211_HW_SUPPORTS_PS |
 		     IEEE80211_HW_PS_NULLFUNC_STACK |
-		     IEEE80211_HW_BEACON_FILTER |
 		     IEEE80211_HW_REPORTS_TX_ACK_STATUS;
 
 	dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index a5224f6..851fa10 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -192,11 +192,9 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
 
 	err = -ENOMEM;
 	p = buf.mem = kmalloc(frag_len, GFP_KERNEL);
-	if (!buf.mem) {
-		printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n",
-		       ndev->name);
+	if (!buf.mem)
 		goto error;
-	}
+
 	buf.size = frag_len;
 
 	/* create the header directly in the fragment data area */
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 2571a2f..06acabd 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1796,6 +1796,14 @@ struct mac_iveiv_entry {
 #define RFCSR2_RESCAL_EN		FIELD8(0x80)
 
 /*
+ * RFCSR 3:
+ */
+#define RFCSR3_K			FIELD8(0x0f)
+/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */
+#define RFCSR3_PA1_BIAS_CCK		FIELD8(0x70);
+#define RFCSR3_PA2_CASCODE_BIAS_CCKK	FIELD8(0x80);
+
+/*
  * FRCSR 5:
  */
 #define RFCSR5_R1			FIELD8(0x0c)
@@ -1811,10 +1819,12 @@ struct mac_iveiv_entry {
  * RFCSR 7:
  */
 #define RFCSR7_RF_TUNING		FIELD8(0x01)
-#define RFCSR7_R02				FIELD8(0x07)
-#define RFCSR7_R3				FIELD8(0x08)
-#define RFCSR7_R45				FIELD8(0x30)
-#define RFCSR7_R67				FIELD8(0xc0)
+#define RFCSR7_BIT1			FIELD8(0x02)
+#define RFCSR7_BIT2			FIELD8(0x04)
+#define RFCSR7_BIT3			FIELD8(0x08)
+#define RFCSR7_BIT4			FIELD8(0x10)
+#define RFCSR7_BIT5			FIELD8(0x20)
+#define RFCSR7_BITS67			FIELD8(0xc0)
 
 /*
  * RFCSR 11:
@@ -1839,6 +1849,11 @@ struct mac_iveiv_entry {
 #define RFCSR15_TX_LO2_EN		FIELD8(0x08)
 
 /*
+ * RFCSR 16:
+ */
+#define RFCSR16_TXMIXER_GAIN		FIELD8(0x07)
+
+/*
  * RFCSR 17:
  */
 #define RFCSR17_TXMIXER_GAIN		FIELD8(0x07)
@@ -1867,6 +1882,13 @@ struct mac_iveiv_entry {
 #define RFCSR23_FREQ_OFFSET		FIELD8(0x7f)
 
 /*
+ * RFCSR 24:
+ */
+#define RFCSR24_TX_AGC_FC		FIELD8(0x1f)
+#define RFCSR24_TX_H20M			FIELD8(0x20)
+#define RFCSR24_TX_CALIB		FIELD8(0x7f)
+
+/*
  * RFCSR 27:
  */
 #define RFCSR27_R1			FIELD8(0x03)
@@ -1887,6 +1909,7 @@ struct mac_iveiv_entry {
  */
 #define RFCSR31_RX_AGC_FC		FIELD8(0x1f)
 #define RFCSR31_RX_H20M			FIELD8(0x20)
+#define RFCSR31_RX_CALIB		FIELD8(0x7f)
 
 /*
  * RFCSR 38:
@@ -2093,6 +2116,12 @@ struct mac_iveiv_entry {
 #define EEPROM_RSSI_A2_LNA_A2		FIELD16(0xff00)
 
 /*
+ * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2).
+ */
+#define EEPROM_TXMIXER_GAIN_A		0x0026
+#define EEPROM_TXMIXER_GAIN_A_VAL	FIELD16(0x0007)
+
+/*
  * EEPROM EIRP Maximum TX power values(unit: dbm)
  */
 #define EEPROM_EIRP_MAX_TX_POWER	0x0027
@@ -2422,4 +2451,16 @@ struct mac_iveiv_entry {
  */
 #define EIRP_MAX_TX_POWER_LIMIT	0x50
 
+/*
+ * RT2800 driver data structure
+ */
+struct rt2800_drv_data {
+	u8 calibration_bw20;
+	u8 calibration_bw40;
+	u8 bbp25;
+	u8 bbp26;
+	u8 txmixer_gain_24g;
+	u8 txmixer_gain_5g;
+};
+
 #endif /* RT2800_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 7bef66d..772d4ae 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -412,18 +412,6 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 	}
 
 	/*
-	 * Disable DMA, will be reenabled later when enabling
-	 * the radio.
-	 */
-	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
-	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
-	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
-
-	/*
 	 * Write firmware to the device.
 	 */
 	rt2800_drv_write_firmware(rt2x00dev, data, len);
@@ -444,10 +432,21 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 	}
 
 	/*
+	 * Disable DMA, will be reenabled later when enabling
+	 * the radio.
+	 */
+	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+	/*
 	 * Initialize firmware.
 	 */
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	if (rt2x00_is_usb(rt2x00dev))
+		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
 	msleep(1);
 
 	return 0;
@@ -1646,10 +1645,14 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
 					 struct rf_channel *rf,
 					 struct channel_info *info)
 {
-	u8 rfcsr;
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+	u8 rfcsr, calib_tx, calib_rx;
 
 	rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1);
-	rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3);
+
+	rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR3_K, rf->rf3);
+	rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
 
 	rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr);
 	rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2);
@@ -1663,16 +1666,82 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2);
 	rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
 
+	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
+	if (rt2x00_rt(rt2x00dev, RT3390)) {
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD,
+				  rt2x00dev->default_ant.rx_chain_num == 1);
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD,
+				  rt2x00dev->default_ant.tx_chain_num == 1);
+	} else {
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+		rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+		rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
+
+		switch (rt2x00dev->default_ant.tx_chain_num) {
+		case 1:
+			rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
+			/* fall through */
+		case 2:
+			rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1);
+			break;
+		}
+
+		switch (rt2x00dev->default_ant.rx_chain_num) {
+		case 1:
+			rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
+			/* fall through */
+		case 2:
+			rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1);
+			break;
+		}
+	}
+	rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+	msleep(1);
+	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+
 	rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr);
 	rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
 	rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
 
-	rt2800_rfcsr_write(rt2x00dev, 24,
-			      rt2x00dev->calibration[conf_is_ht40(conf)]);
+	if (rt2x00_rt(rt2x00dev, RT3390)) {
+		calib_tx = conf_is_ht40(conf) ? 0x68 : 0x4f;
+		calib_rx = conf_is_ht40(conf) ? 0x6f : 0x4f;
+	} else {
+		if (conf_is_ht40(conf)) {
+			calib_tx = drv_data->calibration_bw40;
+			calib_rx = drv_data->calibration_bw40;
+		} else {
+			calib_tx = drv_data->calibration_bw20;
+			calib_rx = drv_data->calibration_bw20;
+		}
+	}
+
+	rt2800_rfcsr_read(rt2x00dev, 24, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR24_TX_CALIB, calib_tx);
+	rt2800_rfcsr_write(rt2x00dev, 24, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR31_RX_CALIB, calib_rx);
+	rt2800_rfcsr_write(rt2x00dev, 31, rfcsr);
 
 	rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
 	rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
 	rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
+
+	rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr);
+	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
+	msleep(1);
+	rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+	rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
 }
 
 static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
@@ -1680,12 +1749,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 					 struct rf_channel *rf,
 					 struct channel_info *info)
 {
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
 	u8 rfcsr;
 	u32 reg;
 
 	if (rf->channel <= 14) {
-		rt2800_bbp_write(rt2x00dev, 25, 0x15);
-		rt2800_bbp_write(rt2x00dev, 26, 0x85);
+		rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25);
+		rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26);
 	} else {
 		rt2800_bbp_write(rt2x00dev, 25, 0x09);
 		rt2800_bbp_write(rt2x00dev, 26, 0xff);
@@ -1713,8 +1783,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 	if (rf->channel <= 14) {
 		rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3);
 		rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
-				(info->default_power1 & 0x3) |
-				((info->default_power1 & 0xC) << 1));
+				  info->default_power1);
 	} else {
 		rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7);
 		rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
@@ -1727,8 +1796,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 	if (rf->channel <= 14) {
 		rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3);
 		rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
-				(info->default_power2 & 0x3) |
-				((info->default_power2 & 0xC) << 1));
+				  info->default_power2);
 	} else {
 		rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7);
 		rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER,
@@ -1738,11 +1806,12 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 	rt2800_rfcsr_write(rt2x00dev, 13, rfcsr);
 
 	rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
-	rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1);
 	rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0);
 	rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0);
 	rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
 	rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
+	rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
 	if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
 		if (rf->channel <= 14) {
 			rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
@@ -1773,10 +1842,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
 	rt2800_rfcsr_write(rt2x00dev, 23, rfcsr);
 
-	rt2800_rfcsr_write(rt2x00dev, 24,
-			      rt2x00dev->calibration[conf_is_ht40(conf)]);
-	rt2800_rfcsr_write(rt2x00dev, 31,
-			      rt2x00dev->calibration[conf_is_ht40(conf)]);
+	if (conf_is_ht40(conf)) {
+		rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw40);
+		rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw40);
+	} else {
+		rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw20);
+		rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw20);
+	}
 
 	if (rf->channel <= 14) {
 		rt2800_rfcsr_write(rt2x00dev, 7, 0xd8);
@@ -1784,7 +1856,10 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 		rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
 		rt2800_rfcsr_write(rt2x00dev, 11, 0xb9);
 		rt2800_rfcsr_write(rt2x00dev, 15, 0x53);
-		rt2800_rfcsr_write(rt2x00dev, 16, 0x4c);
+		rfcsr = 0x4c;
+		rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN,
+				  drv_data->txmixer_gain_24g);
+		rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
 		rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
 		rt2800_rfcsr_write(rt2x00dev, 19, 0x93);
 		rt2800_rfcsr_write(rt2x00dev, 20, 0xb3);
@@ -1793,12 +1868,20 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
 		rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
 		rt2800_rfcsr_write(rt2x00dev, 29, 0x9b);
 	} else {
-		rt2800_rfcsr_write(rt2x00dev, 7, 0x14);
+		rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
+		rt2x00_set_field8(&rfcsr, RFCSR7_BIT2, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR7_BIT3, 0);
+		rt2x00_set_field8(&rfcsr, RFCSR7_BIT4, 1);
+		rt2x00_set_field8(&rfcsr, RFCSR7_BITS67, 0);
+		rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
 		rt2800_rfcsr_write(rt2x00dev, 9, 0xc0);
 		rt2800_rfcsr_write(rt2x00dev, 10, 0xf1);
 		rt2800_rfcsr_write(rt2x00dev, 11, 0x00);
 		rt2800_rfcsr_write(rt2x00dev, 15, 0x43);
-		rt2800_rfcsr_write(rt2x00dev, 16, 0x7a);
+		rfcsr = 0x7a;
+		rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN,
+				  drv_data->txmixer_gain_5g);
+		rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
 		rt2800_rfcsr_write(rt2x00dev, 17, 0x23);
 		if (rf->channel <= 64) {
 			rt2800_rfcsr_write(rt2x00dev, 19, 0xb7);
@@ -3247,6 +3330,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev,
 
 static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 {
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
 	u8 rfcsr;
 	u8 bbp;
 	u32 reg;
@@ -3535,20 +3619,26 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 	 * Set RX Filter calibration for 20MHz and 40MHz
 	 */
 	if (rt2x00_rt(rt2x00dev, RT3070)) {
-		rt2x00dev->calibration[0] =
+		drv_data->calibration_bw20 =
 			rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
-		rt2x00dev->calibration[1] =
+		drv_data->calibration_bw40 =
 			rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
 	} else if (rt2x00_rt(rt2x00dev, RT3071) ||
 		   rt2x00_rt(rt2x00dev, RT3090) ||
 		   rt2x00_rt(rt2x00dev, RT3390) ||
 		   rt2x00_rt(rt2x00dev, RT3572)) {
-		rt2x00dev->calibration[0] =
+		drv_data->calibration_bw20 =
 			rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13);
-		rt2x00dev->calibration[1] =
+		drv_data->calibration_bw40 =
 			rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15);
 	}
 
+	/*
+	 * Save BBP 25 & 26 values for later use in channel switching
+	 */
+	rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25);
+	rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
+
 	if (!rt2x00_rt(rt2x00dev, RT5390)) {
 		/*
 		 * Set back to initial state
@@ -3588,11 +3678,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
 				      &rt2x00dev->cap_flags))
 				rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
 		}
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
-		if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1)
-			rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
-					rt2x00_get_field16(eeprom,
-						EEPROM_TXMIXER_GAIN_BG_VAL));
+		rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN,
+				  drv_data->txmixer_gain_24g);
 		rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
 	}
 
@@ -3800,6 +3887,7 @@ EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
 
 int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 {
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
 	u16 word;
 	u8 *mac;
 	u8 default_lna_gain;
@@ -3883,6 +3971,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 		rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
 	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
 
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
+	if ((word & 0x00ff) != 0x00ff) {
+		drv_data->txmixer_gain_24g =
+			rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL);
+	} else {
+		drv_data->txmixer_gain_24g = 0;
+	}
+
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
 		rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
@@ -3892,6 +3988,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 				   default_lna_gain);
 	rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
 
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word);
+	if ((word & 0x00ff) != 0x00ff) {
+		drv_data->txmixer_gain_5g =
+			rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL);
+	} else {
+		drv_data->txmixer_gain_5g = 0;
+	}
+
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
 	if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
 		rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index dc88bae..6ad6929 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -489,7 +489,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
 
 	rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
 
-	rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	reg = 0;
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
 	rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
@@ -1093,6 +1093,7 @@ static const struct data_queue_desc rt2800pci_queue_bcn = {
 
 static const struct rt2x00_ops rt2800pci_ops = {
 	.name			= KBUILD_MODNAME,
+	.drv_data_size		= sizeof(struct rt2800_drv_data),
 	.max_sta_intf		= 1,
 	.max_ap_intf		= 8,
 	.eeprom_size		= EEPROM_SIZE,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 262ee9e..d009b6b 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -226,9 +226,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
 	rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
 
-	rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
-
-	rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	reg = 0;
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
 	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
@@ -829,6 +827,7 @@ static const struct data_queue_desc rt2800usb_queue_bcn = {
 
 static const struct rt2x00_ops rt2800usb_ops = {
 	.name			= KBUILD_MODNAME,
+	.drv_data_size		= sizeof(struct rt2800_drv_data),
 	.max_sta_intf		= 1,
 	.max_ap_intf		= 8,
 	.eeprom_size		= EEPROM_SIZE,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index b03b22c..ed2ae6e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -647,6 +647,7 @@ struct rt2x00lib_ops {
  */
 struct rt2x00_ops {
 	const char *name;
+	const unsigned int drv_data_size;
 	const unsigned int max_sta_intf;
 	const unsigned int max_ap_intf;
 	const unsigned int eeprom_size;
@@ -742,6 +743,11 @@ struct rt2x00_dev {
 	const struct rt2x00_ops *ops;
 
 	/*
+	 * Driver data.
+	 */
+	void *drv_data;
+
+	/*
 	 * IEEE80211 control structure.
 	 */
 	struct ieee80211_hw *hw;
@@ -886,18 +892,11 @@ struct rt2x00_dev {
 	u8 rssi_offset;
 
 	/*
-	 * Frequency offset (for rt61pci & rt73usb).
+	 * Frequency offset.
 	 */
 	u8 freq_offset;
 
 	/*
-	 * Calibration information (for rt2800usb & rt2800pci).
-	 * [0] -> BW20
-	 * [1] -> BW40
-	 */
-	u8 calibration[2];
-
-	/*
 	 * Association id.
 	 */
 	u16 aid;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c3e1aa7..d62e64f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1121,6 +1121,18 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 {
 	int retval = -ENOMEM;
 
+	/*
+	 * Allocate the driver data memory, if necessary.
+	 */
+	if (rt2x00dev->ops->drv_data_size > 0) {
+		rt2x00dev->drv_data = kzalloc(rt2x00dev->ops->drv_data_size,
+			                      GFP_KERNEL);
+		if (!rt2x00dev->drv_data) {
+			retval = -ENOMEM;
+			goto exit;
+		}
+	}
+
 	spin_lock_init(&rt2x00dev->irqmask_lock);
 	mutex_init(&rt2x00dev->csr_mutex);
 
@@ -1220,7 +1232,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 		cancel_work_sync(&rt2x00dev->rxdone_work);
 		cancel_work_sync(&rt2x00dev->txdone_work);
 	}
-	destroy_workqueue(rt2x00dev->workqueue);
+	if (rt2x00dev->workqueue)
+		destroy_workqueue(rt2x00dev->workqueue);
 
 	/*
 	 * Free the tx status fifo.
@@ -1261,6 +1274,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	 * Free queue structures.
 	 */
 	rt2x00queue_free(rt2x00dev);
+
+	/*
+	 * Free the driver data.
+	 */
+	if (rt2x00dev->drv_data)
+		kfree(rt2x00dev->drv_data);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
 
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig
index d6c42e6..44b9c0a 100644
--- a/drivers/net/wireless/rtlwifi/Kconfig
+++ b/drivers/net/wireless/rtlwifi/Kconfig
@@ -49,6 +49,11 @@ config RTLWIFI
 	depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
 	default m
 
+config RTLWIFI_DEBUG
+	tristate "Additional debugging output"
+	depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE
+	default y
+
 config RTL8192C_COMMON
 	tristate
 	depends on RTL8192CE || RTL8192CU
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 8d6eb0f..df5655c 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,10 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/ip.h>
-#include <linux/module.h>
 #include "wifi.h"
 #include "rc.h"
 #include "base.h"
@@ -39,6 +35,9 @@
 #include "ps.h"
 #include "regd.h"
 
+#include <linux/ip.h>
+#include <linux/module.h>
+
 /*
  *NOTICE!!!: This file will be very big, we hsould
  *keep it clear under follwing roles:
@@ -211,7 +210,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
 	 */
 	if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) {
 
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n");
 
 		ht_cap->mcs.rx_mask[0] = 0xFF;
 		ht_cap->mcs.rx_mask[1] = 0xFF;
@@ -220,7 +219,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
 		ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
 	} else if (get_rf_type(rtlphy) == RF_1T1R) {
 
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n");
 
 		ht_cap->mcs.rx_mask[0] = 0xFF;
 		ht_cap->mcs.rx_mask[1] = 0x00;
@@ -302,15 +301,13 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
 			/* <4> set mac->sband to wiphy->sband */
 			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
 		} else {
-			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-				 ("Err BAND %d\n",
-				 rtlhal->current_bandtype));
+			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n",
+				 rtlhal->current_bandtype);
 		}
 	}
 	/* <5> set hw caps */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 	    IEEE80211_HW_RX_INCLUDES_FCS |
-	    IEEE80211_HW_BEACON_FILTER |
 	    IEEE80211_HW_AMPDU_AGGREGATION |
 	    IEEE80211_HW_CONNECTION_MONITOR |
 	    /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
@@ -413,6 +410,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw)
 
 	wiphy_rfkill_start_polling(hw->wiphy);
 }
+EXPORT_SYMBOL(rtl_init_rfkill);
 
 void rtl_deinit_rfkill(struct ieee80211_hw *hw)
 {
@@ -436,13 +434,13 @@ int rtl_init_core(struct ieee80211_hw *hw)
 	 * mac80211 hw  in _rtl_init_mac80211.
 	 */
 	if (rtl_regd_init(hw, rtl_reg_notifier)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n");
 		return 1;
 	} else {
 		/* CRDA regd hint must after init CRDA */
 		if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-				 ("regulatory_hint fail\n"));
+				 "regulatory_hint fail\n");
 		}
 	}
 
@@ -922,17 +920,17 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 				return false;
 
 			RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-				 ("%s ACT_ADDBAREQ From :%pM\n",
-				  is_tx ? "Tx" : "Rx", hdr->addr2));
+				 "%s ACT_ADDBAREQ From :%pM\n",
+				 is_tx ? "Tx" : "Rx", hdr->addr2);
 			break;
 		case ACT_ADDBARSP:
 			RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-				 ("%s ACT_ADDBARSP From :%pM\n",
-				  is_tx ? "Tx" : "Rx", hdr->addr2));
+				 "%s ACT_ADDBARSP From :%pM\n",
+				 is_tx ? "Tx" : "Rx", hdr->addr2);
 			break;
 		case ACT_DELBA:
 			RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-				 ("ACT_ADDBADEL From :%pM\n", hdr->addr2));
+				 "ACT_ADDBADEL From :%pM\n", hdr->addr2);
 			break;
 		}
 		break;
@@ -975,8 +973,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 				 * 67 : UDP BOOTP server
 				 */
 				RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV),
-					 DBG_DMESG, ("dhcp %s !!\n",
-						     (is_tx) ? "Tx" : "Rx"));
+					 DBG_DMESG, "dhcp %s !!\n",
+					 is_tx ? "Tx" : "Rx");
 
 				if (is_tx) {
 					rtl_lps_leave(hw);
@@ -996,7 +994,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 		return true;
 	} else if (ETH_P_PAE == ether_type) {
 		RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG,
-			 ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
+			 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");
 
 		if (is_tx) {
 			rtl_lps_leave(hw);
@@ -1036,9 +1034,8 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw,
 		return -ENXIO;
 	tid_data = &sta_entry->tids[tid];
 
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-		 ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
-		 tid_data->seq_number));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n",
+		 sta->addr, tid, tid_data->seq_number);
 
 	*ssn = tid_data->seq_number;
 	tid_data->agg.agg_state = RTL_AGG_START;
@@ -1059,12 +1056,12 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw,
 		return -EINVAL;
 
 	if (!sta->addr) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n");
 		return -EINVAL;
 	}
 
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-		 ("on ra = %pM tid = %d\n", sta->addr, tid));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n",
+		 sta->addr, tid);
 
 	if (unlikely(tid >= MAX_TID_COUNT))
 		return -EINVAL;
@@ -1087,12 +1084,12 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw,
 		return -EINVAL;
 
 	if (!sta->addr) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n");
 		return -EINVAL;
 	}
 
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-		 ("on ra = %pM tid = %d\n", sta->addr, tid));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n",
+		 sta->addr, tid);
 
 	if (unlikely(tid >= MAX_TID_COUNT))
 		return -EINVAL;
@@ -1474,29 +1471,29 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
 		(memcmp(mac->bssid, ap5_6, 3) == 0) ||
 		vendor == PEER_ATH) {
 		vendor = PEER_ATH;
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n"));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n");
 	} else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
 		(memcmp(mac->bssid, ap4_5, 3) == 0) ||
 		(memcmp(mac->bssid, ap4_1, 3) == 0) ||
 		(memcmp(mac->bssid, ap4_2, 3) == 0) ||
 		(memcmp(mac->bssid, ap4_3, 3) == 0) ||
 		vendor == PEER_RAL) {
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n"));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n");
 		vendor = PEER_RAL;
 	} else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
 		vendor == PEER_CISCO) {
 		vendor = PEER_CISCO;
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n"));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n");
 	} else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
 		(memcmp(mac->bssid, ap3_2, 3) == 0) ||
 		(memcmp(mac->bssid, ap3_3, 3) == 0) ||
 		vendor == PEER_BROAD) {
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n"));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n");
 		vendor = PEER_BROAD;
 	} else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
 		vendor == PEER_MARV) {
 		vendor = PEER_MARV;
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n"));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n");
 	}
 
 	mac->vendor = vendor;
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index f66b575..5a23a6d 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c
index dc36d74..5c7d579 100644
--- a/drivers/net/wireless/rtlwifi/cam.c
+++ b/drivers/net/wireless/rtlwifi/cam.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include <linux/export.h>
 #include "wifi.h"
 #include "cam.h"
@@ -55,10 +53,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
 	u8 entry_i;
 
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-		 ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
-		  key_cont_128[0], key_cont_128[1],
-		  key_cont_128[2], key_cont_128[3],
-		  key_cont_128[4], key_cont_128[5]));
+		 "key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
+		 key_cont_128[0], key_cont_128[1],
+		 key_cont_128[2], key_cont_128[3],
+		 key_cont_128[4], key_cont_128[5]);
 
 	for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
 		target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
@@ -73,14 +71,12 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
 			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
 					target_command);
 
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n",
+				 rtlpriv->cfg->maps[WCAMI], target_content);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("WRITE %x: %x\n",
-				  rtlpriv->cfg->maps[WCAMI], target_content));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The Key ID is %d\n", entry_no));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("WRITE %x: %x\n",
-				  rtlpriv->cfg->maps[RWCAM], target_command));
+				 "The Key ID is %d\n", entry_no);
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n",
+				 rtlpriv->cfg->maps[RWCAM], target_command);
 
 		} else if (entry_i == 1) {
 
@@ -94,10 +90,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
 			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
 					target_command);
 
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("WRITE A4: %x\n", target_content));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("WRITE A0: %x\n", target_command));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n",
+				 target_content);
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n",
+				 target_command);
 
 		} else {
 
@@ -114,15 +110,15 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
 					target_command);
 			udelay(100);
 
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("WRITE A4: %x\n", target_content));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("WRITE A0: %x\n", target_command));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n",
+				 target_content);
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n",
+				 target_command);
 		}
 	}
 
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-		 ("after set key, usconfig:%x\n", us_config));
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "after set key, usconfig:%x\n",
+		 us_config);
 }
 
 u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
@@ -133,14 +129,13 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-		 ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, "
-		  "ulUseDK=%x MacAddr %pM\n",
-		  ul_entry_idx, ul_key_id, ul_enc_alg,
-		  ul_default_key, mac_addr));
+		 "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
+		 ul_entry_idx, ul_key_id, ul_enc_alg,
+		 ul_default_key, mac_addr);
 
 	if (ul_key_id == TOTAL_CAM_ENTRY) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("<=== ulKeyId exceed!\n"));
+			 "<=== ulKeyId exceed!\n");
 		return 0;
 	}
 
@@ -153,7 +148,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
 	rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
 			      (u8 *) key_content, us_config);
 
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n"));
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n");
 
 	return 1;
 
@@ -166,7 +161,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
 	u32 ul_command;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id));
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id);
 
 	ul_command = ul_key_id * CAM_CONTENT_COUNT;
 	ul_command = ul_command | BIT(31) | BIT(16);
@@ -175,9 +170,9 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
 	rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
 
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-		 ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0));
+		 "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0);
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-		 ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command));
+		 "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command);
 
 	return 0;
 
@@ -229,9 +224,9 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
 	rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
 
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-		 ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content));
+		 "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content);
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-		 ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command));
+		 "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command);
 }
 EXPORT_SYMBOL(rtl_cam_mark_invalid);
 
@@ -279,11 +274,11 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
 		rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
 
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-			 ("rtl_cam_empty_entry(): WRITE A4: %x\n",
-			  ul_content));
+			 "rtl_cam_empty_entry(): WRITE A4: %x\n",
+			 ul_content);
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-			 ("rtl_cam_empty_entry(): WRITE A0: %x\n",
-			  ul_command));
+			 "rtl_cam_empty_entry(): WRITE A0: %x\n",
+			 ul_command);
 	}
 
 }
@@ -297,8 +292,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
 	u8 i, *addr;
 
 	if (NULL == sta_addr) {
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-			("sta_addr is NULL.\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n");
 		return TOTAL_CAM_ENTRY;
 	}
 	/* Does STA already exist? */
@@ -311,8 +305,8 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
 	for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
 		if ((bitmap & BIT(0)) == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-				("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
-				 rtlpriv->sec.hwsec_cam_bitmap, entry_idx));
+				 "-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
+				 rtlpriv->sec.hwsec_cam_bitmap, entry_idx);
 			rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
 			memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
 			       sta_addr, ETH_ALEN);
@@ -331,14 +325,13 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
 	u8 i, *addr;
 
 	if (NULL == sta_addr) {
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-			("sta_addr is NULL.\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n");
 	}
 
 	if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\
 				sta_addr[4]|sta_addr[5]) == 0) {
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
-			("sta_addr is 00:00:00:00:00:00.\n"));
+			 "sta_addr is 00:00:00:00:00:00\n");
 		return;
 	}
 	/* Does STA already exist? */
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h
index c62da4e..35e0008 100644
--- a/drivers/net/wireless/rtlwifi/cam.h
+++ b/drivers/net/wireless/rtlwifi/cam.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 3f0f056..278e9f9 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -31,8 +31,50 @@
 #include "core.h"
 #include "cam.h"
 #include "base.h"
+#include "pci.h"
 #include "ps.h"
 
+#include <linux/export.h>
+
+void rtl_fw_cb(const struct firmware *firmware, void *context)
+{
+	struct ieee80211_hw *hw = context;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	int err;
+
+	RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+			 "Firmware callback routine entered!\n");
+	complete(&rtlpriv->firmware_loading_complete);
+	if (!firmware) {
+		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
+		rtlpriv->max_fw_size = 0;
+		return;
+	}
+	if (firmware->size > rtlpriv->max_fw_size) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "Firmware is too big!\n");
+		release_firmware(firmware);
+		return;
+	}
+	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+	rtlpriv->rtlhal.fwsize = firmware->size;
+	release_firmware(firmware);
+
+	err = ieee80211_register_hw(hw);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "Can't register mac80211 hw\n");
+		return;
+	} else {
+		rtlpriv->mac80211.mac80211_registered = 1;
+	}
+	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+	/*init rfkill */
+	rtl_init_rfkill(hw);
+}
+EXPORT_SYMBOL(rtl_fw_cb);
+
 /*mutex for start & stop is must here. */
 static int rtl_op_start(struct ieee80211_hw *hw)
 {
@@ -112,9 +154,11 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	int err = 0;
 
+	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+
 	if (mac->vif) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("vif has been set!! mac->vif = 0x%p\n", mac->vif));
+			 "vif has been set!! mac->vif = 0x%p\n", mac->vif);
 		return -EOPNOTSUPP;
 	}
 
@@ -125,7 +169,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
 	case NL80211_IFTYPE_STATION:
 		if (mac->beacon_enabled == 1) {
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("NL80211_IFTYPE_STATION\n"));
+				 "NL80211_IFTYPE_STATION\n");
 			mac->beacon_enabled = 0;
 			rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
 					rtlpriv->cfg->maps
@@ -134,7 +178,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-			 ("NL80211_IFTYPE_ADHOC\n"));
+			 "NL80211_IFTYPE_ADHOC\n");
 
 		mac->link_state = MAC80211_LINKED;
 		rtlpriv->cfg->ops->set_bcn_reg(hw);
@@ -148,7 +192,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
 		break;
 	case NL80211_IFTYPE_AP:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-			 ("NL80211_IFTYPE_AP\n"));
+			 "NL80211_IFTYPE_AP\n");
 
 		mac->link_state = MAC80211_LINKED;
 		rtlpriv->cfg->ops->set_bcn_reg(hw);
@@ -161,7 +205,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("operation mode %d is not support!\n", vif->type));
+			 "operation mode %d is not supported!\n", vif->type);
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -221,7 +265,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
 	mutex_lock(&rtlpriv->locks.conf_mutex);
 	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {	/*BIT(2)*/
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-			 ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"));
+			 "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n");
 	}
 
 	/*For IPS */
@@ -264,8 +308,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
 
 	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-			 ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
-			  hw->conf.long_frame_max_tx_count));
+			 "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n",
+			 hw->conf.long_frame_max_tx_count);
 		mac->retry_long = hw->conf.long_frame_max_tx_count;
 		mac->retry_short = hw->conf.long_frame_max_tx_count;
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
@@ -320,7 +364,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
 		default:
 			mac->bw_40 = false;
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-					("switch case not processed\n"));
+				 "switch case not processed\n");
 			break;
 		}
 
@@ -369,12 +413,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
 			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] |
 			    rtlpriv->cfg->maps[MAC_RCR_AB];
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Enable receive multicast frame.\n"));
+				 "Enable receive multicast frame\n");
 		} else {
 			mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] |
 					  rtlpriv->cfg->maps[MAC_RCR_AB]);
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Disable receive multicast frame.\n"));
+				 "Disable receive multicast frame\n");
 		}
 	}
 
@@ -382,11 +426,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
 		if (*new_flags & FIF_FCSFAIL) {
 			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32];
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Enable receive FCS error frame.\n"));
+				 "Enable receive FCS error frame\n");
 		} else {
 			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32];
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Disable receive FCS error frame.\n"));
+				 "Disable receive FCS error frame\n");
 		}
 	}
 
@@ -409,11 +453,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
 			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
 
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Enable receive control frame.\n"));
+				 "Enable receive control frame\n");
 		} else {
 			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Disable receive control frame.\n"));
+				 "Disable receive control frame\n");
 		}
 	}
 
@@ -421,11 +465,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw,
 		if (*new_flags & FIF_OTHER_BSS) {
 			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP];
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Enable receive other BSS's frame.\n"));
+				 "Enable receive other BSS's frame\n");
 		} else {
 			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP];
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-				 ("Disable receive other BSS's frame.\n"));
+				 "Disable receive other BSS's frame\n");
 		}
 	}
 }
@@ -456,7 +500,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw,
 			sta_entry->wireless_mode = WIRELESS_MODE_G;
 
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-			("Add sta addr is %pM\n", sta->addr));
+			 "Add sta addr is %pM\n", sta->addr);
 		rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
 	}
 	return 0;
@@ -469,7 +513,7 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw,
 	struct rtl_sta_info *sta_entry;
 	if (sta) {
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-			("Remove sta addr is %pM\n", sta->addr));
+			 "Remove sta addr is %pM\n", sta->addr);
 		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
 		sta_entry->wireless_mode = 0;
 		sta_entry->ratr_index = 0;
@@ -514,7 +558,7 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw,
 
 	if (queue >= AC_MAX) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("queue number %d is incorrect!\n", queue));
+			 "queue number %d is incorrect!\n", queue);
 		return -EINVAL;
 	}
 
@@ -547,7 +591,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 		     bss_conf->enable_beacon)) {
 			if (mac->beacon_enabled == 0) {
 				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-					 ("BSS_CHANGED_BEACON_ENABLED\n"));
+					 "BSS_CHANGED_BEACON_ENABLED\n");
 
 				/*start hw beacon interrupt. */
 				/*rtlpriv->cfg->ops->set_bcn_reg(hw); */
@@ -565,7 +609,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 			!bss_conf->enable_beacon)) {
 			if (mac->beacon_enabled == 1) {
 				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-					 ("ADHOC DISABLE BEACON\n"));
+					 "ADHOC DISABLE BEACON\n");
 
 				mac->beacon_enabled = 0;
 				rtlpriv->cfg->ops->update_interrupt_mask(hw, 0,
@@ -575,7 +619,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 		}
 		if (changed & BSS_CHANGED_BEACON_INT) {
 			RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
-				 ("BSS_CHANGED_BEACON_INT\n"));
+				 "BSS_CHANGED_BEACON_INT\n");
 			mac->beacon_interval = bss_conf->beacon_int;
 			rtlpriv->cfg->ops->set_bcn_intv(hw);
 		}
@@ -604,7 +648,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 			if (mac->opmode == NL80211_IFTYPE_STATION && sta)
 				rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-				 ("BSS_CHANGED_ASSOC\n"));
+				 "BSS_CHANGED_ASSOC\n");
 		} else {
 			if (mac->link_state == MAC80211_LINKED)
 				rtl_lps_leave(hw);
@@ -619,20 +663,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 			mac->vendor = PEER_UNKNOWN;
 
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-				 ("BSS_CHANGED_UN_ASSOC\n"));
+				 "BSS_CHANGED_UN_ASSOC\n");
 		}
 	}
 
 	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("BSS_CHANGED_ERP_CTS_PROT\n"));
+			 "BSS_CHANGED_ERP_CTS_PROT\n");
 		mac->use_cts_protect = bss_conf->use_cts_prot;
 	}
 
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-			 ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
-			  bss_conf->use_short_preamble));
+			 "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n",
+			 bss_conf->use_short_preamble);
 
 		mac->short_preamble = bss_conf->use_short_preamble;
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE,
@@ -641,7 +685,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 
 	if (changed & BSS_CHANGED_ERP_SLOT) {
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("BSS_CHANGED_ERP_SLOT\n"));
+			 "BSS_CHANGED_ERP_SLOT\n");
 
 		if (bss_conf->use_short_slot)
 			mac->slot_time = RTL_SLOT_TIME_9;
@@ -653,8 +697,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 	}
 
 	if (changed & BSS_CHANGED_HT) {
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("BSS_CHANGED_HT\n"));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n");
 		rcu_read_lock();
 		sta = get_sta(hw, vif, bss_conf->bssid);
 		if (sta) {
@@ -683,8 +726,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
 					      (u8 *) bss_conf->bssid);
 
-		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
-			 ("%pM\n", bss_conf->bssid));
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, "%pM\n",
+			 bss_conf->bssid);
 
 		mac->vendor = PEER_UNKNOWN;
 		memcpy(mac->bssid, bss_conf->bssid, 6);
@@ -831,30 +874,30 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
 	switch (action) {
 	case IEEE80211_AMPDU_TX_START:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
+			 "IEEE80211_AMPDU_TX_START: TID:%d\n", tid);
 		return rtl_tx_agg_start(hw, sta, tid, ssn);
 		break;
 	case IEEE80211_AMPDU_TX_STOP:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
+			 "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid);
 		return rtl_tx_agg_stop(hw, sta, tid);
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
+			 "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid);
 		rtl_tx_agg_oper(hw, sta, tid);
 		break;
 	case IEEE80211_AMPDU_RX_START:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid));
+			 "IEEE80211_AMPDU_RX_START:TID:%d\n", tid);
 		break;
 	case IEEE80211_AMPDU_RX_STOP:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
-			 ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid));
+			 "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid);
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("IEEE80211_AMPDU_ERR!!!!:\n"));
+			 "IEEE80211_AMPDU_ERR!!!!:\n");
 		return -EOPNOTSUPP;
 	}
 	return 0;
@@ -867,7 +910,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw)
 
 	mac->act_scanning = true;
 
-	RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
+	RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
 
 	if (mac->link_state == MAC80211_LINKED) {
 		rtl_lps_leave(hw);
@@ -888,7 +931,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
-	RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
+	RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n");
 	mac->act_scanning = false;
 	/* Dual mac */
 	rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
@@ -921,13 +964,13 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
 	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("not open hw encryption\n"));
+			 "not open hw encryption\n");
 		return -ENOSPC;	/*User disabled HW-crypto */
 	}
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-		 ("%s hardware based encryption for keyidx: %d, mac: %pM\n",
-		  cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
-		  sta ? sta->addr : bcast_addr));
+		 "%s hardware based encryption for keyidx: %d, mac: %pM\n",
+		 cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
+		 sta ? sta->addr : bcast_addr);
 	rtlpriv->sec.being_setkey = true;
 	rtl_ips_nic_on(hw);
 	mutex_lock(&rtlpriv->locks.conf_mutex);
@@ -936,24 +979,23 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	switch (key->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 		key_type = WEP40_ENCRYPTION;
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n");
 		break;
 	case WLAN_CIPHER_SUITE_WEP104:
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-			 ("alg:WEP104\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n");
 		key_type = WEP104_ENCRYPTION;
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
 		key_type = TKIP_ENCRYPTION;
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n");
 		break;
 	case WLAN_CIPHER_SUITE_CCMP:
 		key_type = AESCCMP_ENCRYPTION;
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n");
 		break;
 	default:
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("alg_err:%x!!!!:\n", key->cipher));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n",
+			 key->cipher);
 		goto out_unlock;
 	}
 	if (key_type == WEP40_ENCRYPTION ||
@@ -995,8 +1037,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 				wep_only = true;
 			rtlpriv->sec.pairwise_enc_algorithm = key_type;
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1"
-				" TKIP:2 AES:4 WEP104:5)\n", key_type));
+				 "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n",
+				 key_type);
 			rtlpriv->cfg->ops->enable_hw_sec(hw);
 		}
 	}
@@ -1005,7 +1047,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	case SET_KEY:
 		if (wep_only) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("set WEP(group/pairwise) key\n"));
+				 "set WEP(group/pairwise) key\n");
 			/* Pairwise key with an assigned MAC address. */
 			rtlpriv->sec.pairwise_enc_algorithm = key_type;
 			rtlpriv->sec.group_enc_algorithm = key_type;
@@ -1016,7 +1058,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 			memcpy(mac_addr, zero_addr, ETH_ALEN);
 		} else if (group_key) {	/* group key */
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("set group key\n"));
+				 "set group key\n");
 			/* group key */
 			rtlpriv->sec.group_enc_algorithm = key_type;
 			/*set local buf about group key. */
@@ -1026,10 +1068,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 			memcpy(mac_addr, bcast_addr, ETH_ALEN);
 		} else {	/* pairwise key */
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("set pairwise key\n"));
+				 "set pairwise key\n");
 			if (!sta) {
-				RT_ASSERT(false, ("pairwise key withnot"
-						  "mac_addr\n"));
+				RT_ASSERT(false,
+					  "pairwise key without mac_addr\n");
 
 				err = -EOPNOTSUPP;
 				goto out_unlock;
@@ -1056,7 +1098,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		break;
 	case DISABLE_KEY:
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-			 ("disable key delete one entry\n"));
+			 "disable key delete one entry\n");
 		/*set local buf about wep key. */
 		if (mac->opmode == NL80211_IFTYPE_AP) {
 			if (sta)
@@ -1077,7 +1119,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("cmd_err:%x!!!!:\n", cmd));
+			 "cmd_err:%x!!!!\n", cmd);
 	}
 out_unlock:
 	mutex_unlock(&rtlpriv->locks.conf_mutex);
@@ -1106,8 +1148,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
 			rtlpriv->rfkill.rfkill_state = radio_state;
 
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-				 (KERN_INFO "wireless radio switch turned %s\n",
-				  radio_state ? "on" : "off"));
+				 "wireless radio switch turned %s\n",
+				 radio_state ? "on" : "off");
 
 			blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
 			wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index f02824a..2fe46a1 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -30,8 +30,6 @@
 #ifndef __RTL_CORE_H__
 #define __RTL_CORE_H__
 
-#include <net/mac80211.h>
-
 #define RTL_SUPPORTED_FILTERS		\
 	(FIF_PROMISC_IN_BSS | \
 	FIF_ALLMULTI | FIF_CONTROL | \
@@ -42,4 +40,6 @@
 #define RTL_SUPPORTED_CTRL_FILTER	0xFF
 
 extern const struct ieee80211_ops rtl_ops;
+void rtl_fw_cb(const struct firmware *firmware, void *context);
+
 #endif
diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c
index 1b5cb71..bdda9b2 100644
--- a/drivers/net/wireless/rtlwifi/debug.c
+++ b/drivers/net/wireless/rtlwifi/debug.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -28,6 +28,8 @@
 
 #include "wifi.h"
 
+#include <linux/moduleparam.h>
+
 void rtl_dbgp_flag_init(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
index 160dd06..07493d2 100644
--- a/drivers/net/wireless/rtlwifi/debug.h
+++ b/drivers/net/wireless/rtlwifi/debug.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -156,53 +156,78 @@ enum dbgp_flag_e {
 	DBGP_TYPE_MAX
 };
 
-#define RT_ASSERT(_exp, fmt)				\
-	do {						\
-		if (!(_exp)) {			\
-			printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \
-			__func__);			\
-			printk fmt;			\
-		} \
-	} while (0);
-
-#define RT_TRACE(rtlpriv, comp, level, fmt)\
-	do { \
-		if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \
-			((level) <= rtlpriv->dbg.global_debuglevel))) {\
-			printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \
-			__func__, in_interrupt(), in_atomic());	\
-			printk fmt;				\
-		} \
-	} while (0);
-
-#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr)	\
-	do {						\
-		if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \
-			printk(KERN_DEBUG "%s: ", KBUILD_MODNAME);	\
-			printk printstr;		\
-		}					\
-	} while (0);
-
-#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \
-		_hexdatalen) \
-	do {\
-		if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\
-			(_level <= rtlpriv->dbg.global_debuglevel)))	{ \
-			int __i;					\
-			u8*	ptr = (u8 *)_hexdata;			\
-			printk(KERN_DEBUG "%s: ", KBUILD_MODNAME);	\
-			printk("In process \"%s\" (pid %i):", current->comm,\
-					current->pid); \
-			printk(_titlestring);		\
-			for (__i = 0; __i < (int)_hexdatalen; __i++) {	\
-				printk("%02X%s", ptr[__i], (((__i + 1) % 4)\
-							== 0) ? "  " : " ");\
-				if (((__i + 1) % 16) == 0)		\
-					printk("\n");			\
-			}				\
-			printk(KERN_DEBUG "\n");			\
-		} \
-	} while (0);
+#ifdef CONFIG_RTLWIFI_DEBUG
+
+#define RT_ASSERT(_exp, fmt, ...)					\
+do {									\
+	if (!(_exp)) {							\
+		printk(KERN_DEBUG KBUILD_MODNAME ":%s(): " fmt,		\
+		       __func__, ##__VA_ARGS__);			\
+	}								\
+} while (0)
+
+#define RT_TRACE(rtlpriv, comp, level, fmt, ...)			\
+do {									\
+	if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) &&	\
+		     ((level) <= rtlpriv->dbg.global_debuglevel))) {	\
+		printk(KERN_DEBUG KBUILD_MODNAME ":%s():<%lx-%x> " fmt,	\
+		       __func__, in_interrupt(), in_atomic(),		\
+		       ##__VA_ARGS__);					\
+	}								\
+} while (0)
+
+#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...)			\
+do {									\
+	if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) {	\
+		printk(KERN_DEBUG KBUILD_MODNAME ": " fmt,		\
+		       ##__VA_ARGS__);					\
+	}								\
+} while (0)
+
+#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata,	\
+		      _hexdatalen)					\
+do {									\
+	if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&	\
+		     (_level <= rtlpriv->dbg.global_debuglevel))) {	\
+		printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \
+		       KBUILD_MODNAME, current->comm, current->pid,	\
+		       _titlestring);					\
+		print_hex_dump_bytes("", DUMP_PREFIX_NONE,		\
+				     _hexdata, _hexdatalen);		\
+	}								\
+} while (0)
+
+#else
+
+struct rtl_priv;
+
+__printf(2, 3)
+static inline void RT_ASSERT(int exp, const char *fmt, ...)
+{
+}
+
+__printf(4, 5)
+static inline void RT_TRACE(struct rtl_priv *rtlpriv,
+			    int comp, int level,
+			    const char *fmt, ...)
+{
+}
+
+__printf(4, 5)
+static inline void RTPRINT(struct rtl_priv *rtlpriv,
+			   int dbgtype, int dbgflag,
+			   const char *fmt, ...)
+{
+}
+
+static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv,
+				 int comp, int level,
+				 const char *titlestring,
+				 const void *hexdata, size_t hexdatalen)
+{
+}
+
+#endif
 
 void rtl_dbgp_flag_init(struct ieee80211_hw *hw);
 #endif
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c
index ed1058b..1f14380 100644
--- a/drivers/net/wireless/rtlwifi/efuse.c
+++ b/drivers/net/wireless/rtlwifi/efuse.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * Tmis program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -162,8 +162,8 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value)
 	const u32 efuse_len =
 		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
 
-	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-		 ("Addr=%x Data =%x\n", address, value));
+	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n",
+		 address, value);
 
 	if (address < efuse_len) {
 		rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
@@ -252,8 +252,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 
 	if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
 		RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-			 ("read_efuse(): Invalid offset(%#x) with read "
-			  "bytes(%#x)!!\n", _offset, _size_byte));
+			 "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n",
+			 _offset, _size_byte);
 		return;
 	}
 
@@ -280,7 +280,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 	if (*rtemp8 != 0xFF) {
 		efuse_utilized++;
 		RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
-			("Addr=%d\n", efuse_addr));
+			"Addr=%d\n", efuse_addr);
 		efuse_addr++;
 	}
 
@@ -290,13 +290,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 		if (offset < efuse_max_section) {
 			wren = (*rtemp8 & 0x0f);
 			RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
-				("offset-%d Worden=%x\n", offset, wren));
+				"offset-%d Worden=%x\n", offset, wren);
 
 			for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
 				if (!(wren & 0x01)) {
 					RTPRINT(rtlpriv, FEEPROM,
-						EFUSE_READ_ALL, ("Addr=%d\n",
-								 efuse_addr));
+						EFUSE_READ_ALL,
+						"Addr=%d\n", efuse_addr);
 
 					read_efuse_byte(hw, efuse_addr, rtemp8);
 					efuse_addr++;
@@ -308,8 +308,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 						break;
 
 					RTPRINT(rtlpriv, FEEPROM,
-						EFUSE_READ_ALL, ("Addr=%d\n",
-								 efuse_addr));
+						EFUSE_READ_ALL,
+						"Addr=%d\n", efuse_addr);
 
 					read_efuse_byte(hw, efuse_addr, rtemp8);
 					efuse_addr++;
@@ -326,7 +326,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf)
 		}
 
 		RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
-			("Addr=%d\n", efuse_addr));
+			"Addr=%d\n", efuse_addr);
 		read_efuse_byte(hw, efuse_addr, rtemp8);
 		if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
 			efuse_utilized++;
@@ -395,9 +395,8 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
 		result = false;
 
 	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-		 ("efuse_shadow_update_chk(): totalbytes(%#x), "
-		  "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
-		  totalbytes, hdr_num, words_need, efuse_used));
+		 "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
+		 totalbytes, hdr_num, words_need, efuse_used);
 
 	return result;
 }
@@ -434,7 +433,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
 	u8 word_en = 0x0F;
 	u8 first_pg = false;
 
-	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n"));
+	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "--->\n");
 
 	if (!efuse_shadow_update_chk(hw)) {
 		efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
@@ -443,7 +442,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
 		       rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
 
 		RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-			 ("<---efuse out of capacity!!\n"));
+			 "<---efuse out of capacity!!\n");
 		return false;
 	}
 	efuse_power_switch(hw, true, true);
@@ -478,12 +477,12 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
 			       &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base],
 			       8);
 			RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD,
-				      ("U-efuse\n"), tmpdata, 8);
+				      "U-efuse", tmpdata, 8);
 
 			if (!efuse_pg_packet_write(hw, (u8) offset, word_en,
 						   tmpdata)) {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("PG section(%#x) fail!!\n", offset));
+					 "PG section(%#x) fail!!\n", offset);
 				break;
 			}
 		}
@@ -497,7 +496,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw)
 	       &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
 	       rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
 
-	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n"));
+	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "<---\n");
 	return true;
 }
 
@@ -634,8 +633,8 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u8 tmpidx = 0;
 
-	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-		 ("Addr = %x Data=%x\n", addr, data));
+	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n",
+		 addr, data);
 
 	rtl_write_byte(rtlpriv,
 		       rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff));
@@ -778,7 +777,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 				dataempty = false;
 		}
 
-		if (dataempty == false) {
+		if (!dataempty) {
 			*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
 			*write_state = PG_STATE_HEADER;
 		} else {
@@ -851,7 +850,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
 			}
 		}
 	}
-	RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n"));
+	RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,  "efuse PG_STATE_HEADER-1\n");
 }
 
 static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
@@ -916,7 +915,7 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
 		}
 
 		RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-			("efuse PG_STATE_HEADER-2\n"));
+			"efuse PG_STATE_HEADER-2\n");
 	}
 }
 
@@ -936,7 +935,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 	if (efuse_get_current_size(hw) >=
 	    (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
 		RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-			("efuse_pg_packet_write error\n"));
+			"efuse_pg_packet_write error\n");
 		return false;
 	}
 
@@ -948,7 +947,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 	efuse_word_enable_data_read(word_en, data, target_pkt.data);
 	target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en);
 
-	RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
+	RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,  "efuse Power ON\n");
 
 	while (continual && (efuse_addr <
 	       (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
@@ -956,7 +955,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 		if (write_state == PG_STATE_HEADER) {
 			badworden = 0x0F;
 			RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-				("efuse PG_STATE_HEADER\n"));
+				"efuse PG_STATE_HEADER\n");
 
 			if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) &&
 			    (efuse_data != 0xFF))
@@ -976,7 +975,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 
 		} else if (write_state == PG_STATE_DATA) {
 			RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-				("efuse PG_STATE_DATA\n"));
+				"efuse PG_STATE_DATA\n");
 			badworden =
 			    efuse_word_enable_data_write(hw, efuse_addr + 1,
 							 target_pkt.word_en,
@@ -999,14 +998,14 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw,
 					result = false;
 				}
 				RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
-					("efuse PG_STATE_HEADER-3\n"));
+					"efuse PG_STATE_HEADER-3\n");
 			}
 		}
 	}
 
 	if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) {
 		RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-			 ("efuse_addr(%#x) Out of size!!\n", efuse_addr));
+			 "efuse_addr(%#x) Out of size!!\n", efuse_addr);
 	}
 
 	return true;
@@ -1046,8 +1045,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
 	u8 tmpdata[8];
 
 	memset(tmpdata, 0xff, PGPKT_DATA_SIZE);
-	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
-		 ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr));
+	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n",
+		 word_en, efuse_addr);
 
 	if (!(word_en & BIT(0))) {
 		tmpaddr = start_addr;
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
index 164daba..2bdea9a 100644
--- a/drivers/net/wireless/rtlwifi/efuse.h
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 9245d88..07dd38e 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,13 +27,13 @@
  *
  *****************************************************************************/
 
-#include <linux/export.h>
-#include "core.h"
 #include "wifi.h"
+#include "core.h"
 #include "pci.h"
 #include "base.h"
 #include "ps.h"
 #include "efuse.h"
+#include <linux/export.h>
 
 static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
 	PCI_VENDOR_ID_INTEL,
@@ -170,7 +170,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 
@@ -198,7 +198,7 @@ static bool _rtl_pci_platform_switch_device_pci_aspm(
 }
 
 /*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
-static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
+static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -207,8 +207,6 @@ static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
 
 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
 		udelay(100);
-
-	return true;
 }
 
 /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
@@ -232,7 +230,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw)
 
 	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("PCI(Bridge) UNKNOWN.\n"));
+			 "PCI(Bridge) UNKNOWN\n");
 
 		return;
 	}
@@ -286,7 +284,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
 
 	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("PCI(Bridge) UNKNOWN.\n"));
+			 "PCI(Bridge) UNKNOWN\n");
 		return;
 	}
 
@@ -303,11 +301,10 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw)
 			      u_pcibridge_aspmsetting);
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("PlatformEnableASPM():PciBridge busnumber[%x], "
-		  "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n",
-		  pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
-		  (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
-		  u_pcibridge_aspmsetting));
+		 "PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n",
+		 pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum,
+		 (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
+		 u_pcibridge_aspmsetting);
 
 	udelay(50);
 
@@ -382,9 +379,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
 	pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg);
 	pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Link Control Register =%x\n",
-		  pcipriv->ndis_adapter.linkctrl_reg));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n",
+		 pcipriv->ndis_adapter.linkctrl_reg);
 
 	pci_read_config_byte(pdev, 0x98, &tmp);
 	tmp |= BIT(4);
@@ -551,11 +547,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
 			skb_pull(skb, EM_HDR_LEN);
 
 		RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
-			 ("new ring->idx:%d, "
-			  "free: skb_queue_len:%d, free: seq:%x\n",
-			  ring->idx,
-			  skb_queue_len(&ring->queue),
-			  *(u16 *) (skb->data + 22)));
+			 "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n",
+			 ring->idx,
+			 skb_queue_len(&ring->queue),
+			 *(u16 *) (skb->data + 22));
 
 		if (prio == TXCMD_QUEUE) {
 			dev_kfree_skb(skb);
@@ -593,11 +588,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
 				== 2) {
 
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
-					("more desc left, wake"
-					 "skb_queue@%d,ring->idx = %d,"
-					 "skb_queue_len = 0x%d\n",
-					 prio, ring->idx,
-					 skb_queue_len(&ring->queue)));
+				 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n",
+				 prio, ring->idx,
+				 skb_queue_len(&ring->queue));
 
 			ieee80211_wake_queue(hw,
 					skb_get_queue_mapping
@@ -657,6 +650,8 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
 		return;
 
 	uskb = dev_alloc_skb(skb->len + 128);
+	if (!uskb)
+		return;		/* exit if allocation failed */
 	memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status));
 	pdata = (u8 *)skb_put(uskb, skb->len);
 	memcpy(pdata, skb->data, skb->len);
@@ -709,9 +704,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
 
 		new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
 		if (unlikely(!new_skb)) {
-			RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
-				 DBG_DMESG,
-				 ("can't alloc skb for rx\n"));
+			RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), DBG_DMESG,
+				 "can't alloc skb for rx\n");
 			goto done;
 		}
 
@@ -796,38 +790,37 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 	/*<1> beacon related */
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) {
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("beacon ok interrupt!\n"));
+			 "beacon ok interrupt!\n");
 	}
 
 	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) {
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("beacon err interrupt!\n"));
+			 "beacon err interrupt!\n");
 	}
 
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) {
-		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("beacon interrupt!\n"));
+		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n");
 	}
 
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) {
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("prepare beacon for interrupt!\n"));
+			 "prepare beacon for interrupt!\n");
 		tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet);
 	}
 
 	/*<3> Tx related */
 	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW]))
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n");
 
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) {
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("Manage ok interrupt!\n"));
+			 "Manage ok interrupt!\n");
 		_rtl_pci_tx_isr(hw, MGNT_QUEUE);
 	}
 
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) {
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("HIGH_QUEUE ok interrupt!\n"));
+			 "HIGH_QUEUE ok interrupt!\n");
 		_rtl_pci_tx_isr(hw, HIGH_QUEUE);
 	}
 
@@ -835,7 +828,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 		rtlpriv->link_info.num_tx_inperiod++;
 
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("BK Tx OK interrupt!\n"));
+			 "BK Tx OK interrupt!\n");
 		_rtl_pci_tx_isr(hw, BK_QUEUE);
 	}
 
@@ -843,7 +836,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 		rtlpriv->link_info.num_tx_inperiod++;
 
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("BE TX OK interrupt!\n"));
+			 "BE TX OK interrupt!\n");
 		_rtl_pci_tx_isr(hw, BE_QUEUE);
 	}
 
@@ -851,7 +844,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 		rtlpriv->link_info.num_tx_inperiod++;
 
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("VI TX OK interrupt!\n"));
+			 "VI TX OK interrupt!\n");
 		_rtl_pci_tx_isr(hw, VI_QUEUE);
 	}
 
@@ -859,7 +852,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 		rtlpriv->link_info.num_tx_inperiod++;
 
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-			 ("Vo TX OK interrupt!\n"));
+			 "Vo TX OK interrupt!\n");
 		_rtl_pci_tx_isr(hw, VO_QUEUE);
 	}
 
@@ -868,25 +861,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id)
 			rtlpriv->link_info.num_tx_inperiod++;
 
 			RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
-					("CMD TX OK interrupt!\n"));
+				 "CMD TX OK interrupt!\n");
 			_rtl_pci_tx_isr(hw, TXCMD_QUEUE);
 		}
 	}
 
 	/*<2> Rx related */
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
-		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
+		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n");
 		_rtl_pci_rx_interrupt(hw);
 	}
 
 	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("rx descriptor unavailable!\n"));
+			 "rx descriptor unavailable!\n");
 		_rtl_pci_rx_interrupt(hw);
 	}
 
 	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n");
 		_rtl_pci_rx_interrupt(hw);
 	}
 
@@ -1028,7 +1021,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
 
 	if (!ring || (unsigned long)ring & 0xFF) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Cannot allocate TX ring (prio = %d)\n", prio));
+			 "Cannot allocate TX ring (prio = %d)\n", prio);
 		return -ENOMEM;
 	}
 
@@ -1039,8 +1032,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw,
 	rtlpci->tx_ring[prio].entries = entries;
 	skb_queue_head_init(&rtlpci->tx_ring[prio].queue);
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("queue:%d, ring_addr:%p\n", prio, ring));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n",
+		 prio, ring);
 
 	for (i = 0; i < entries; i++) {
 		nextdescaddress = (u32) dma +
@@ -1078,7 +1071,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
 		if (!rtlpci->rx_ring[rx_queue_idx].desc ||
 		    (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Cannot allocate RX ring\n"));
+				 "Cannot allocate RX ring\n");
 			return -ENOMEM;
 		}
 
@@ -1155,10 +1148,12 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
 		ring->idx = (ring->idx + 1) % ring->entries;
 	}
 
-	pci_free_consistent(rtlpci->pdev,
-			    sizeof(*ring->desc) * ring->entries,
-			    ring->desc, ring->dma);
-	ring->desc = NULL;
+	if (ring->desc) {
+		pci_free_consistent(rtlpci->pdev,
+				    sizeof(*ring->desc) * ring->entries,
+				    ring->desc, ring->dma);
+		ring->desc = NULL;
+	}
 }
 
 static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
@@ -1182,12 +1177,14 @@ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
 			kfree_skb(skb);
 		}
 
-		pci_free_consistent(rtlpci->pdev,
+		if (rtlpci->rx_ring[rx_queue_idx].desc) {
+			pci_free_consistent(rtlpci->pdev,
 				    sizeof(*rtlpci->rx_ring[rx_queue_idx].
 					   desc) * rtlpci->rxringcount,
 				    rtlpci->rx_ring[rx_queue_idx].desc,
 				    rtlpci->rx_ring[rx_queue_idx].dma);
-		rtlpci->rx_ring[rx_queue_idx].desc = NULL;
+			rtlpci->rx_ring[rx_queue_idx].desc = NULL;
+		}
 	}
 }
 
@@ -1355,7 +1352,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	u8 temp_one = 1;
 
 	if (ieee80211_is_auth(fc)) {
-		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
 		rtl_ips_nic_on(hw);
 	}
 
@@ -1388,10 +1385,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 
 	if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("No more TX desc@%d, ring->idx = %d,"
-			  "idx = %d, skb_queue_len = 0x%d\n",
-			  hw_queue, ring->idx, idx,
-			  skb_queue_len(&ring->queue)));
+			 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",
+			 hw_queue, ring->idx, idx,
+			 skb_queue_len(&ring->queue));
 
 		spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
 		return skb->len;
@@ -1426,11 +1422,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	    hw_queue != BEACON_QUEUE) {
 
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
-			 ("less desc left, stop skb_queue@%d, "
-			  "ring->idx = %d,"
-			  "idx = %d, skb_queue_len = 0x%d\n",
-			  hw_queue, ring->idx, idx,
-			  skb_queue_len(&ring->queue)));
+			 "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n",
+			 hw_queue, ring->idx, idx,
+			 skb_queue_len(&ring->queue));
 
 		ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
 	}
@@ -1497,7 +1491,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev)
 	err = _rtl_pci_init_trx_ring(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("tx ring initialization failed"));
+			 "tx ring initialization failed\n");
 		return err;
 	}
 
@@ -1519,12 +1513,12 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
 	err = rtlpriv->cfg->ops->hw_init(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("Failed to config hardware!\n"));
+			 "Failed to config hardware!\n");
 		return err;
 	}
 
 	rtlpriv->cfg->ops->enable_interrupt(hw);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n");
 
 	rtl_init_rx_config(hw);
 
@@ -1535,7 +1529,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw)
 
 	rtlpci->up_first_time = false;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n");
 	return 0;
 }
 
@@ -1573,6 +1567,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
 
 	rtlpci->driver_is_goingto_unload = true;
 	rtlpriv->cfg->ops->hw_disable(hw);
+	/* some things are not needed if firmware not available */
+	if (!rtlpriv->max_fw_size)
+		return;
 	rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
 
 	spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
@@ -1622,20 +1619,20 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
 		switch (revisionid) {
 		case RTL_PCI_REVISION_ID_8192PCIE:
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-				 ("8192 PCI-E is found - "
-				  "vid/did=%x/%x\n", venderid, deviceid));
+				 "8192 PCI-E is found - vid/did=%x/%x\n",
+				 venderid, deviceid);
 			rtlhal->hw_type = HARDWARE_TYPE_RTL8192E;
 			break;
 		case RTL_PCI_REVISION_ID_8192SE:
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-				 ("8192SE is found - "
-				  "vid/did=%x/%x\n", venderid, deviceid));
+				 "8192SE is found - vid/did=%x/%x\n",
+				 venderid, deviceid);
 			rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-				 ("Err: Unknown device - "
-				  "vid/did=%x/%x\n", venderid, deviceid));
+				 "Err: Unknown device - vid/did=%x/%x\n",
+				 venderid, deviceid);
 			rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE;
 			break;
 
@@ -1646,18 +1643,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
 		   deviceid == RTL_PCI_8188CE_DID) {
 		rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("8192C PCI-E is found - "
-			  "vid/did=%x/%x\n", venderid, deviceid));
+			 "8192C PCI-E is found - vid/did=%x/%x\n",
+			 venderid, deviceid);
 	} else if (deviceid == RTL_PCI_8192DE_DID ||
 		   deviceid == RTL_PCI_8192DE_DID2) {
 		rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("8192D PCI-E is found - "
-			  "vid/did=%x/%x\n", venderid, deviceid));
+			 "8192D PCI-E is found - vid/did=%x/%x\n",
+			 venderid, deviceid);
 	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Err: Unknown device -"
-			  " vid/did=%x/%x\n", venderid, deviceid));
+			 "Err: Unknown device - vid/did=%x/%x\n",
+			 venderid, deviceid);
 
 		rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
 	}
@@ -1665,19 +1662,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
 		if (revisionid == 0 || revisionid == 1) {
 			if (revisionid == 0) {
-				RT_TRACE(rtlpriv, COMP_INIT,
-					 DBG_LOUD, ("Find 92DE MAC0.\n"));
+				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+					 "Find 92DE MAC0\n");
 				rtlhal->interfaceindex = 0;
 			} else if (revisionid == 1) {
 				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-					("Find 92DE MAC1.\n"));
+					 "Find 92DE MAC1\n");
 				rtlhal->interfaceindex = 1;
 			}
 		} else {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				("Unknown device - "
-				"VendorID/DeviceID=%x/%x, Revision=%x\n",
-				venderid, deviceid, revisionid));
+				 "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n",
+				 venderid, deviceid, revisionid);
 			rtlhal->interfaceindex = 0;
 		}
 	}
@@ -1693,8 +1689,8 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
 			if (bridge_pdev->vendor == pcibridge_vendors[tmp]) {
 				pcipriv->ndis_adapter.pcibridge_vendor = tmp;
 				RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-					 ("Pci Bridge Vendor is found index:"
-					 " %d\n", tmp));
+					 "Pci Bridge Vendor is found index: %d\n",
+					 tmp);
 				break;
 			}
 		}
@@ -1723,23 +1719,21 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
 	}
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("pcidev busnumber:devnumber:funcnumber:"
-		  "vendor:link_ctl %d:%d:%d:%x:%x\n",
-		  pcipriv->ndis_adapter.busnumber,
-		  pcipriv->ndis_adapter.devnumber,
-		  pcipriv->ndis_adapter.funcnumber,
-		  pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg));
+		 "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n",
+		 pcipriv->ndis_adapter.busnumber,
+		 pcipriv->ndis_adapter.devnumber,
+		 pcipriv->ndis_adapter.funcnumber,
+		 pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg);
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("pci_bridge busnumber:devnumber:funcnumber:vendor:"
-		  "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
-		  pcipriv->ndis_adapter.pcibridge_busnum,
-		  pcipriv->ndis_adapter.pcibridge_devnum,
-		  pcipriv->ndis_adapter.pcibridge_funcnum,
-		  pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
-		  pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
-		  pcipriv->ndis_adapter.pcibridge_linkctrlreg,
-		  pcipriv->ndis_adapter.amd_l1_patch));
+		 "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
+		 pcipriv->ndis_adapter.pcibridge_busnum,
+		 pcipriv->ndis_adapter.pcibridge_devnum,
+		 pcipriv->ndis_adapter.pcibridge_funcnum,
+		 pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
+		 pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
+		 pcipriv->ndis_adapter.pcibridge_linkctrlreg,
+		 pcipriv->ndis_adapter.amd_l1_patch);
 
 	rtl_pci_parse_configuration(pdev, hw);
 
@@ -1759,18 +1753,17 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 
 	err = pci_enable_device(pdev);
 	if (err) {
-		RT_ASSERT(false,
-			  ("%s : Cannot enable new PCI device\n",
-			   pci_name(pdev)));
+		RT_ASSERT(false, "%s : Cannot enable new PCI device\n",
+			  pci_name(pdev));
 		return err;
 	}
 
 	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
 		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
-			RT_ASSERT(false, ("Unable to obtain 32bit DMA "
-					  "for consistent allocations\n"));
-			pci_disable_device(pdev);
-			return -ENOMEM;
+			RT_ASSERT(false,
+				  "Unable to obtain 32bit DMA for consistent allocations\n");
+			err = -ENOMEM;
+			goto fail1;
 		}
 	}
 
@@ -1780,7 +1773,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 				sizeof(struct rtl_priv), &rtl_ops);
 	if (!hw) {
 		RT_ASSERT(false,
-			  ("%s : ieee80211 alloc failed\n", pci_name(pdev)));
+			  "%s : ieee80211 alloc failed\n", pci_name(pdev));
 		err = -ENOMEM;
 		goto fail1;
 	}
@@ -1791,6 +1784,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 	rtlpriv = hw->priv;
 	pcipriv = (void *)rtlpriv->priv;
 	pcipriv->dev.pdev = pdev;
+	init_completion(&rtlpriv->firmware_loading_complete);
 
 	/* init cfg & intf_ops */
 	rtlpriv->rtlhal.interface = INTF_PCI;
@@ -1810,8 +1804,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 	/* MEM map */
 	err = pci_request_regions(pdev, KBUILD_MODNAME);
 	if (err) {
-		RT_ASSERT(false, ("Can't obtain PCI resources\n"));
-		return err;
+		RT_ASSERT(false, "Can't obtain PCI resources\n");
+		goto fail1;
 	}
 
 	pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
@@ -1823,15 +1817,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 			(unsigned long)pci_iomap(pdev,
 			rtlpriv->cfg->bar_id, pmem_len);
 	if (rtlpriv->io.pci_mem_start == 0) {
-		RT_ASSERT(false, ("Can't map PCI mem\n"));
+		RT_ASSERT(false, "Can't map PCI mem\n");
+		err = -ENOMEM;
 		goto fail2;
 	}
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("mem mapped space: start: 0x%08lx len:%08lx "
-		  "flags:%08lx, after map:0x%08lx\n",
-		  pmem_start, pmem_len, pmem_flags,
-		  rtlpriv->io.pci_mem_start));
+		 "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n",
+		 pmem_start, pmem_len, pmem_flags,
+		 rtlpriv->io.pci_mem_start);
 
 	/* Disable Clk Request */
 	pci_write_config_byte(pdev, 0x81, 0);
@@ -1841,8 +1835,10 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 	pci_write_config_byte(pdev, 0x04, 0x07);
 
 	/* find adapter */
-	if (!_rtl_pci_find_adapter(pdev, hw))
+	if (!_rtl_pci_find_adapter(pdev, hw)) {
+		err = -ENODEV;
 		goto fail3;
+	}
 
 	/* Init IO handler */
 	_rtl_pci_io_handler_init(&pdev->dev, hw);
@@ -1851,8 +1847,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 	rtlpriv->cfg->ops->read_eeprom_info(hw);
 
 	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't init_sw_vars.\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
+		err = -ENODEV;
 		goto fail3;
 	}
 
@@ -1865,69 +1861,55 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 	err = rtl_init_core(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't allocate sw for mac80211.\n"));
+			 "Can't allocate sw for mac80211\n");
 		goto fail3;
 	}
 
 	/* Init PCI sw */
 	err = rtl_pci_init(hw, pdev);
 	if (err) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Failed to init PCI.\n"));
-		goto fail3;
-	}
-
-	err = ieee80211_register_hw(hw);
-	if (err) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't register mac80211 hw.\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to init PCI\n");
 		goto fail3;
-	} else {
-		rtlpriv->mac80211.mac80211_registered = 1;
 	}
 
 	err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("failed to create sysfs device attributes\n"));
+			 "failed to create sysfs device attributes\n");
 		goto fail3;
 	}
 
-	/*init rfkill */
-	rtl_init_rfkill(hw);
-
 	rtlpci = rtl_pcidev(pcipriv);
 	err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
 			  IRQF_SHARED, KBUILD_MODNAME, hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("%s: failed to register IRQ handler\n",
-			  wiphy_name(hw->wiphy)));
+			 "%s: failed to register IRQ handler\n",
+			 wiphy_name(hw->wiphy));
 		goto fail3;
-	} else {
-		rtlpci->irq_alloc = 1;
 	}
+	rtlpci->irq_alloc = 1;
 
-	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 	return 0;
 
 fail3:
-	pci_set_drvdata(pdev, NULL);
 	rtl_deinit_core(hw);
 	_rtl_pci_io_handler_release(hw);
-	ieee80211_free_hw(hw);
 
 	if (rtlpriv->io.pci_mem_start != 0)
 		pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
 
 fail2:
 	pci_release_regions(pdev);
+	complete(&rtlpriv->firmware_loading_complete);
 
 fail1:
-
+	if (hw)
+		ieee80211_free_hw(hw);
+	pci_set_drvdata(pdev, NULL);
 	pci_disable_device(pdev);
 
-	return -ENODEV;
+	return err;
 
 }
 EXPORT_SYMBOL(rtl_pci_probe);
@@ -1940,6 +1922,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
 	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
 	struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
 
+	/* just in case driver is removed before firmware callback */
+	wait_for_completion(&rtlpriv->firmware_loading_complete);
 	clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 
 	sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index ebe0b42..241448f 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
 void rtl_pci_disconnect(struct pci_dev *pdev);
 int rtl_pci_suspend(struct device *dev);
 int rtl_pci_resume(struct device *dev);
-
 static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
 	return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 130fdd9..5b9c3b5 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -44,10 +44,11 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw)
 
 	if (is_hal_stop(rtlhal))
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Driver is already down!\n"));
+			 "Driver is already down!\n");
 
 	/*<2> Enable Adapter */
-	rtlpriv->cfg->ops->hw_init(hw);
+	if (rtlpriv->cfg->ops->hw_init(hw))
+		return 1;
 	RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 
 	/*<3> Enable Interrupt */
@@ -104,8 +105,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
 
 	case ERFOFF:
 
-		if ((changesource == RF_CHANGE_BY_HW)
-		    && (ppsc->hwradiooff == false)) {
+		if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) {
 			ppsc->hwradiooff = true;
 		}
 
@@ -120,7 +120,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
 
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 
@@ -176,7 +176,7 @@ void rtl_ips_nic_off_wq_callback(void *data)
 
 	if (mac->opmode != NL80211_IFTYPE_STATION) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("not station return\n"));
+			 "not station return\n");
 		return;
 	}
 
@@ -207,7 +207,7 @@ void rtl_ips_nic_off_wq_callback(void *data)
 		    (mac->link_state == MAC80211_NOLINK) &&
 		    !mac->act_scanning) {
 			RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-				 ("IPSEnter(): Turn off RF.\n"));
+				 "IPSEnter(): Turn off RF\n");
 
 			ppsc->inactive_pwrstate = ERFOFF;
 			ppsc->in_powersavemode = true;
@@ -280,8 +280,7 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw)
 
 	if (ps_timediff < 2000) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("Delay enter Fw LPS for DHCP, ARP,"
-			  " or EAPOL exchanging state.\n"));
+			 "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n");
 		return false;
 	}
 
@@ -328,8 +327,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
 		bool fw_current_inps;
 		if (ppsc->dot11_psmode == EACTIVE) {
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-				 ("FW LPS leave ps_mode:%x\n",
-				  FW_PS_ACTIVE_MODE));
+				 "FW LPS leave ps_mode:%x\n",
+				 FW_PS_ACTIVE_MODE);
 
 			rpwm_val = 0x0C;	/* RF on */
 			fw_pwrmode = FW_PS_ACTIVE_MODE;
@@ -347,8 +346,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
 		} else {
 			if (rtl_get_fwlps_doze(hw)) {
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-						("FW LPS enter ps_mode:%x\n",
-						 ppsc->fwctrl_psmode));
+					 "FW LPS enter ps_mode:%x\n",
+					 ppsc->fwctrl_psmode);
 
 				rpwm_val = 0x02;	/* RF off */
 				fw_current_inps = true;
@@ -402,7 +401,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
 	if (mac->cnt_after_linked >= 2) {
 		if (ppsc->dot11_psmode == EACTIVE) {
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-					("Enter 802.11 power save mode...\n"));
+				 "Enter 802.11 power save mode...\n");
 
 			rtl_lps_set_psmode(hw, EAUTOPS);
 		}
@@ -434,7 +433,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
 			}
 
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("Busy Traffic,Leave 802.11 power save..\n"));
+				 "Busy Traffic,Leave 802.11 power save..\n");
 
 			rtl_lps_set_psmode(hw, EACTIVE);
 		}
@@ -518,8 +517,8 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
 		queue_delayed_work(rtlpriv->works.rtl_wq,
 				&rtlpriv->works.ps_work, MSECS(5));
 	} else {
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, "
-				"m_buffered: %x\n", u_buffed, m_buffed));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+			 "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed);
 	}
 }
 
@@ -607,8 +606,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
 	 * sleep  = dtim_period, that meaons, we should
 	 * awake before every dtim */
 	RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-		 ("dtim_counter:%x will sleep :%d"
-		 " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv));
+		 "dtim_counter:%x will sleep :%d beacon_intv\n",
+		 rtlpriv->psc.dtim_counter, sleep_intv);
 
 	/* we tested that 40ms is enough for sw & hw sw delay */
 	queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h
index 84628e60..1357856 100644
--- a/drivers/net/wireless/rtlwifi/ps.h
+++ b/drivers/net/wireless/rtlwifi/ps.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
index 539df66..c66f08a 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -251,7 +251,7 @@ static void *rtl_rate_alloc_sta(void *ppriv,
 	rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp);
 	if (!rate_priv) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Unable to allocate private rc structure\n"));
+			 "Unable to allocate private rc structure\n");
 		return NULL;
 	}
 
diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h
index 4afa2c2..4d61761 100644
--- a/drivers/net/wireless/rtlwifi/rc.h
+++ b/drivers/net/wireless/rtlwifi/rc.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
index 9fedb1f..c1608cd 100644
--- a/drivers/net/wireless/rtlwifi/regd.c
+++ b/drivers/net/wireless/rtlwifi/regd.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -398,13 +398,11 @@ int rtl_regd_init(struct ieee80211_hw *hw,
 	rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;
 
 	RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
-		 (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
-		  rtlpriv->regd.country_code));
+		 "rtl: EEPROM regdomain: 0x%0x\n", rtlpriv->regd.country_code);
 
 	if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) {
 		RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG,
-			 (KERN_DEBUG "rtl: EEPROM indicates invalid contry code"
-			  "world wide 13 should be used\n"));
+			 "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n");
 
 		rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
 	}
@@ -420,8 +418,8 @@ int rtl_regd_init(struct ieee80211_hw *hw,
 	}
 
 	RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
-		 (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n",
-		  rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]));
+		 "rtl: Country alpha2 being used: %c%c\n",
+		 rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]);
 
 	_rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier);
 
@@ -433,7 +431,7 @@ int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n"));
+	RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n");
 
 	return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd);
 }
diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h
index d231189..70ef2f4 100644
--- a/drivers/net/wireless/rtlwifi/regd.h
+++ b/drivers/net/wireless/rtlwifi/regd.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index 72a98ca..a644735 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -246,16 +246,15 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
 
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("cnt_parity_fail = %d, cnt_rate_illegal = %d, "
-		  "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
-		  falsealm_cnt->cnt_parity_fail,
-		  falsealm_cnt->cnt_rate_illegal,
-		  falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail));
+		 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
+		 falsealm_cnt->cnt_parity_fail,
+		 falsealm_cnt->cnt_rate_illegal,
+		 falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
 
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
-		  falsealm_cnt->cnt_ofdm_fail,
-		  falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all));
+		 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
+		 falsealm_cnt->cnt_ofdm_fail,
+		 falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
 }
 
 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
@@ -313,8 +312,8 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
 		    dm_digtable.backoff_val;
 
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("rssi_val_min = %x backoff_val %x\n",
-		  dm_digtable.rssi_val_min, dm_digtable.backoff_val));
+		 "rssi_val_min = %x backoff_val %x\n",
+		 dm_digtable.rssi_val_min, dm_digtable.backoff_val);
 
 	rtl92c_dm_write_dig(hw);
 }
@@ -330,8 +329,8 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
 	if (mac->opmode == NL80211_IFTYPE_ADHOC)
 		multi_sta = true;
 
-	if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=
-				     DIG_STA_DISCONNECT)) {
+	if (!multi_sta ||
+	    dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) {
 		initialized = false;
 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 		return;
@@ -364,10 +363,9 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
 	}
 
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("curmultista_connectstate = "
-		  "%x dig_ext_port_stage %x\n",
-		  dm_digtable.curmultista_connectstate,
-		  dm_digtable.dig_ext_port_stage));
+		 "curmultista_connectstate = %x dig_ext_port_stage %x\n",
+		 dm_digtable.curmultista_connectstate,
+		 dm_digtable.dig_ext_port_stage);
 }
 
 static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
@@ -375,10 +373,9 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("presta_connectstate = %x,"
-		  " cursta_connectctate = %x\n",
-		  dm_digtable.presta_connectstate,
-		  dm_digtable.cursta_connectctate));
+		 "presta_connectstate = %x, cursta_connectctate = %x\n",
+		 dm_digtable.presta_connectstate,
+		 dm_digtable.cursta_connectctate);
 
 	if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate
 	    || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT
@@ -464,11 +461,11 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
 		dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state;
 	}
 
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n",
+		 dm_digtable.cur_cck_pd_state);
 
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
-		 ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version)));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n",
+		 IS_92C_SERIAL(rtlhal->version));
 }
 
 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
@@ -519,10 +516,9 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-		 ("cur_igvalue = 0x%x, "
-		  "pre_igvalue = 0x%x, backoff_val = %d\n",
-		  dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
-		  dm_digtable.backoff_val));
+		 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
+		 dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
+		 dm_digtable.backoff_val);
 
 	if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
 		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
@@ -676,15 +672,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
 	rtlpriv->dm.txpower_trackinginit = true;
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
+		 "rtl92c_dm_txpower_tracking_callback_thermalmeter\n");
 
 	thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
 
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-		  "eeprom_thermalmeter 0x%x\n",
-		  thermalvalue, rtlpriv->dm.thermalvalue,
-		  rtlefuse->eeprom_thermalmeter));
+		 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
+		 thermalvalue, rtlpriv->dm.thermalvalue,
+		 rtlefuse->eeprom_thermalmeter);
 
 	rtl92c_phy_ap_calibrate(hw, (thermalvalue -
 				     rtlefuse->eeprom_thermalmeter));
@@ -702,10 +697,9 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 				ofdm_index_old[0] = (u8) i;
 
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					("Initial pathA ele_d reg0x%x = 0x%lx, "
-					 "ofdm_index=0x%x\n",
+					 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
 					 ROFDM0_XATXIQIMBALANCE,
-					 ele_d, ofdm_index_old[0]));
+					 ele_d, ofdm_index_old[0]);
 				break;
 			}
 		}
@@ -719,11 +713,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 				    MASKOFDM_D)) {
 
 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
-					   DBG_LOUD,
-					   ("Initial pathB ele_d reg0x%x = "
-					   "0x%lx, ofdm_index=0x%x\n",
-					   ROFDM0_XBTXIQIMBALANCE, ele_d,
-					   ofdm_index_old[1]));
+						 DBG_LOUD,
+						 "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
+						 ROFDM0_XBTXIQIMBALANCE, ele_d,
+						 ofdm_index_old[1]);
 					break;
 				}
 			}
@@ -741,11 +734,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
 						 DBG_LOUD,
-						 ("Initial reg0x%x = 0x%lx, "
-						  "cck_index=0x%x, ch 14 %d\n",
-						  RCCK0_TXFILTER2, temp_cck,
-						  cck_index_old,
-						  rtlpriv->dm.cck_inch14));
+						 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n",
+						 RCCK0_TXFILTER2, temp_cck,
+						 cck_index_old,
+						 rtlpriv->dm.cck_inch14);
 					break;
 				}
 			} else {
@@ -757,11 +749,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
 						 DBG_LOUD,
-						 ("Initial reg0x%x = 0x%lx, "
-						  "cck_index=0x%x, ch14 %d\n",
-						  RCCK0_TXFILTER2, temp_cck,
-						  cck_index_old,
-						  rtlpriv->dm.cck_inch14));
+						 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n",
+						 RCCK0_TXFILTER2, temp_cck,
+						 cck_index_old,
+						 rtlpriv->dm.cck_inch14);
 					break;
 				}
 			}
@@ -790,12 +781,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 		    (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
 
 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-			("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-			 "eeprom_thermalmeter 0x%x delta 0x%x "
-			 "delta_lck 0x%x delta_iqk 0x%x\n",
+			 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
 			 thermalvalue, rtlpriv->dm.thermalvalue,
 			 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
-			 delta_iqk));
+			 delta_iqk);
 
 		if (delta_lck > 1) {
 			rtlpriv->dm.thermalvalue_lck = thermalvalue;
@@ -815,18 +804,15 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
 			if (is2t) {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("temp OFDM_A_index=0x%x, "
-					  "OFDM_B_index=0x%x,"
-					  "cck_index=0x%x\n",
-					  rtlpriv->dm.ofdm_index[0],
-					  rtlpriv->dm.ofdm_index[1],
-					  rtlpriv->dm.cck_index));
+					 "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
+					 rtlpriv->dm.ofdm_index[0],
+					 rtlpriv->dm.ofdm_index[1],
+					 rtlpriv->dm.cck_index);
 			} else {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("temp OFDM_A_index=0x%x,"
-					  "cck_index=0x%x\n",
-					  rtlpriv->dm.ofdm_index[0],
-					  rtlpriv->dm.cck_index));
+					 "temp OFDM_A_index=0x%x, cck_index=0x%x\n",
+					 rtlpriv->dm.ofdm_index[0],
+					 rtlpriv->dm.cck_index);
 			}
 
 			if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
@@ -918,16 +904,13 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 
 			if (is2t) {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("new OFDM_A_index=0x%x, "
-					  "OFDM_B_index=0x%x,"
-					  "cck_index=0x%x\n",
-					  ofdm_index[0], ofdm_index[1],
-					  cck_index));
+					 "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n",
+					 ofdm_index[0], ofdm_index[1],
+					 cck_index);
 			} else {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("new OFDM_A_index=0x%x,"
-					  "cck_index=0x%x\n",
-					  ofdm_index[0], cck_index));
+					 "new OFDM_A_index=0x%x, cck_index=0x%x\n",
+					 ofdm_index[0], cck_index);
 			}
 		}
 
@@ -1085,7 +1068,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
 			rtlpriv->dm.thermalvalue = thermalvalue;
 	}
 
-	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
+	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
 
 }
 
@@ -1098,8 +1081,8 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
 	rtlpriv->dm.txpower_trackinginit = false;
 
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("pMgntInfo->txpower_tracking = %d\n",
-		  rtlpriv->dm.txpower_tracking));
+		 "pMgntInfo->txpower_tracking = %d\n",
+		 rtlpriv->dm.txpower_tracking);
 }
 
 static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
@@ -1125,12 +1108,12 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter(
 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
 			      0x60);
 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-			 ("Trigger 92S Thermal Meter!!\n"));
+			 "Trigger 92S Thermal Meter!!\n");
 		tm_trigger = 1;
 		return;
 	} else {
 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-			 ("Schedule TxPowerTracking direct call!!\n"));
+			 "Schedule TxPowerTracking direct call!!\n");
 		rtl92c_dm_txpower_tracking_directcall(hw);
 		tm_trigger = 0;
 	}
@@ -1169,13 +1152,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
 
 	if (is_hal_stop(rtlhal)) {
 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-			 ("<---- driver is going to unload\n"));
+			 "<---- driver is going to unload\n");
 		return;
 	}
 
 	if (!rtlpriv->dm.useramask) {
 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-			("<---- driver does not control rate adaptive mask\n"));
+			 "<---- driver does not control rate adaptive mask\n");
 		return;
 	}
 
@@ -1210,14 +1193,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
 			p_ra->ratr_state = DM_RATR_STA_LOW;
 
 		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
+			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n",
+				 rtlpriv->dm.undecorated_smoothed_pwdb);
 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-				 ("RSSI = %ld\n",
-				  rtlpriv->dm.undecorated_smoothed_pwdb));
+				 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-				 ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
-			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
-				 ("PreState = %d, CurState = %d\n",
-				  p_ra->pre_ratr_state, p_ra->ratr_state));
+				 "PreState = %d, CurState = %d\n",
+				 p_ra->pre_ratr_state, p_ra->ratr_state);
 
 			rcu_read_lock();
 			sta = ieee80211_find_sta(mac->vif, mac->bssid);
@@ -1316,8 +1298,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
 	if (((mac->link_state == MAC80211_NOLINK)) &&
 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
 		dm_pstable.rssi_val_min = 0;
-		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-			 ("Not connected to any\n"));
+		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n");
 	}
 
 	if (mac->link_state == MAC80211_LINKED) {
@@ -1325,22 +1306,22 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
 			dm_pstable.rssi_val_min =
 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 			RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-				 ("AP Client PWDB = 0x%lx\n",
-				  dm_pstable.rssi_val_min));
+				 "AP Client PWDB = 0x%lx\n",
+				 dm_pstable.rssi_val_min);
 		} else {
 			dm_pstable.rssi_val_min =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%lx\n",
-				  dm_pstable.rssi_val_min));
+				 "STA Default Port PWDB = 0x%lx\n",
+				 dm_pstable.rssi_val_min);
 		}
 	} else {
 		dm_pstable.rssi_val_min =
 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
 		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
-			 ("AP Ext Port PWDB = 0x%lx\n",
-			  dm_pstable.rssi_val_min));
+			 "AP Ext Port PWDB = 0x%lx\n",
+			 dm_pstable.rssi_val_min);
 	}
 
 	if (IS_92C_SERIAL(rtlhal->version))
@@ -1381,7 +1362,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
 	if ((mac->link_state < MAC80211_LINKED) &&
 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Not connected to any\n"));
+			 "Not connected to any\n");
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 
@@ -1394,28 +1375,28 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("AP Client PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "AP Client PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		} else {
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "STA Default Port PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		}
 	} else {
 		undecorated_smoothed_pwdb =
 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("AP Ext Port PWDB = 0x%lx\n",
-			  undecorated_smoothed_pwdb));
+			 "AP Ext Port PWDB = 0x%lx\n",
+			 undecorated_smoothed_pwdb);
 	}
 
 	if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
 	} else if ((undecorated_smoothed_pwdb <
 		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
 		   (undecorated_smoothed_pwdb >=
@@ -1423,18 +1404,18 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
 	} else if (undecorated_smoothed_pwdb <
 		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_NORMAL\n"));
+			 "TXHIGHPWRLEVEL_NORMAL\n");
 	}
 
 	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-			  rtlphy->current_channel));
+			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+			 rtlphy->current_channel);
 		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
 	}
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
index b9736d3..2178e37 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
index 931d979..c20b3c3 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,16 +27,13 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/firmware.h>
-#include <linux/export.h>
 #include "../wifi.h"
 #include "../pci.h"
 #include "../base.h"
 #include "../rtl8192ce/reg.h"
 #include "../rtl8192ce/def.h"
 #include "fw_common.h"
+#include <linux/export.h>
 
 static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable)
 {
@@ -172,7 +169,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 *bufferPtr = (u8 *) buffer;
 
-	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
+	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size);
 
 	if (IS_CHIP_VER_B(version)) {
 		u32 pageNums, remainSize;
@@ -186,7 +183,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw,
 
 		if (pageNums > 4) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Page numbers should not greater then 4\n"));
+				 "Page numbers should not greater then 4\n");
 		}
 
 		for (page = 0; page < pageNums; page++) {
@@ -219,13 +216,12 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
 
 	if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
-			  value32));
+			 "chksum report faill ! REG_MCUFWDL:0x%08x\n", value32);
 		return -EIO;
 	}
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-		 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+		 "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
 
 	value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
 	value32 |= MCUFWDL_RDY;
@@ -238,9 +234,8 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
 		value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
 		if (value32 & WINTINI_RDY) {
 			RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-				 ("Polling FW ready success!!"
-				 " REG_MCUFWDL:0x%08x .\n",
-				 value32));
+				 "Polling FW ready success!! REG_MCUFWDL:0x%08x\n",
+				 value32);
 			return 0;
 		}
 
@@ -249,7 +244,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
 	} while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT);
 
 	RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-		 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
+		 "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", value32);
 	return -EIO;
 }
 
@@ -262,20 +257,19 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
 	u32 fwsize;
 	enum version_8192c version = rtlhal->version;
 
-	if (!rtlhal->pfirmware)
+	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
 		return 1;
 
-	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
 	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
 	pfwdata = (u8 *) rtlhal->pfirmware;
 	fwsize = rtlhal->fwsize;
 
 	if (IS_FW_HEADER_EXIST(pfwheader)) {
 		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-			 ("Firmware Version(%d), Signature(%#x),Size(%d)\n",
+			 "Firmware Version(%d), Signature(%#x),Size(%d)\n",
 			 le16_to_cpu(pfwheader->version),
 			 le16_to_cpu(pfwheader->signature),
-			 (uint)sizeof(struct rtl92c_firmware_header)));
+			 (uint)sizeof(struct rtl92c_firmware_header));
 
 		pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header);
 		fwsize = fwsize - sizeof(struct rtl92c_firmware_header);
@@ -287,10 +281,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
 
 	if (_rtl92c_fw_free_to_go(hw)) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is not ready to run!\n"));
+			 "Firmware is not ready to run!\n");
 	} else {
 		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-			 ("Firmware is ready to run!\n"));
+			 "Firmware is ready to run!\n");
 	}
 
 	return 0;
@@ -328,22 +322,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 	unsigned long flag;
 	u8 idx;
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
 
 	while (true) {
 		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 		if (rtlhal->h2c_setinprogress) {
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("H2C set in progress! Wait to set.."
-				  "element_id(%d).\n", element_id));
+				 "H2C set in progress! Wait to set..element_id(%d)\n",
+				 element_id);
 
 			while (rtlhal->h2c_setinprogress) {
 				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
 						       flag);
 				h2c_waitcounter++;
 				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-					 ("Wait 100 us (%d times)...\n",
-					  h2c_waitcounter));
+					 "Wait 100 us (%d times)...\n",
+					 h2c_waitcounter);
 				udelay(100);
 
 				if (h2c_waitcounter > 1000)
@@ -363,8 +357,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 		wait_writeh2c_limmit--;
 		if (wait_writeh2c_limmit == 0) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Write H2C fail because no trigger "
-				  "for FW INT!\n"));
+				 "Write H2C fail because no trigger for FW INT!\n");
 			break;
 		}
 
@@ -388,7 +381,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 
@@ -398,8 +391,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 			wait_h2c_limmit--;
 			if (wait_h2c_limmit == 0) {
 				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-					 ("Wating too long for FW read "
-					  "clear HMEBox(%d)!\n", boxnum));
+					 "Waiting too long for FW read clear HMEBox(%d)!\n",
+					 boxnum);
 				break;
 			}
 
@@ -408,14 +401,14 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 			isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum);
 			u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Wating for FW read clear HMEBox(%d)!!! "
-				  "0x1BF = %2x\n", boxnum, u1b_tmp));
+				 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
+				 boxnum, u1b_tmp);
 		}
 
 		if (!isfw_read) {
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Write H2C register BOX[%d] fail!!!!! "
-				  "Fw do not read.\n", boxnum));
+				 "Write H2C register BOX[%d] fail!!!!! Fw do not read\n",
+				 boxnum);
 			break;
 		}
 
@@ -423,8 +416,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 		memset(boxextcontent, 0, sizeof(boxextcontent));
 		boxcontent[0] = element_id;
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			 ("Write element_id box_reg(%4x) = %2x\n",
-			  box_reg, element_id));
+			 "Write element_id box_reg(%4x) = %2x\n",
+			 box_reg, element_id);
 
 		switch (cmd_len) {
 		case 1:
@@ -493,7 +486,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 
@@ -504,29 +497,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 			rtlhal->last_hmeboxnum = 0;
 
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			 ("pHalData->last_hmeboxnum  = %d\n",
-			  rtlhal->last_hmeboxnum));
+			 "pHalData->last_hmeboxnum  = %d\n",
+			 rtlhal->last_hmeboxnum);
 	}
 
 	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 	rtlhal->h2c_setinprogress = false;
 	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
 }
 
 void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
 			 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
 {
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u32 tmp_cmdbuf[2];
 
-	if (rtlhal->fw_ready == false) {
-		RT_ASSERT(false, ("return H2C cmd because of Fw "
-				  "download fail!!!\n"));
-		return;
-	}
-
 	memset(tmp_cmdbuf, 0, 8);
 	memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
 	_rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
@@ -547,7 +533,7 @@ void rtl92c_firmware_selfreset(struct ieee80211_hw *hw)
 	while (u1b_tmp & BIT(2)) {
 		delay--;
 		if (delay == 0) {
-			RT_ASSERT(false, ("8051 reset fail.\n"));
+			RT_ASSERT(false, "8051 reset fail\n");
 			break;
 		}
 		udelay(50);
@@ -562,7 +548,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 	u8 u1_h2c_set_pwrmode[3] = {0};
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
-	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
 
 	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
 	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
@@ -570,7 +556,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 					      ppsc->reg_max_lps_awakeintvl);
 
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-		      "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
+		      "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
 		      u1_h2c_set_pwrmode, 3);
 	rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
 
@@ -780,14 +766,16 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
 	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
 
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-		      "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+		      "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
 		      &reserved_page_packet[0], totalpacketlen);
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-		      "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+		      "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
 		      u1RsvdPageLoc, 3);
 
 
 	skb = dev_alloc_skb(totalpacketlen);
+	if (!skb)
+		return;
 	memcpy((u8 *) skb_put(skb, totalpacketlen),
 	       &reserved_page_packet, totalpacketlen);
 
@@ -798,15 +786,14 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
 
 	if (dlok) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("Set RSVD page location to Fw.\n"));
+			 "Set RSVD page location to Fw\n");
 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-				"H2C_RSVDPAGE:\n",
-				u1RsvdPageLoc, 3);
+			      "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
 		rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE,
 				    sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
 	} else
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+			 "Set RSVD page location to Fw FAIL!!!!!!\n");
 }
 EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt);
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
index cec5a3a..780ea5b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c
index 605ff19..918b1d1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,8 @@
  *
  *****************************************************************************/
 
-#include <linux/module.h>
 #include "../wifi.h"
+#include <linux/module.h>
 
 
 MODULE_AUTHOR("lizhaoming	<chaoming_li@realsil.com.cn>");
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
index 1f07558..bfff5fe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -42,16 +42,15 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 returnvalue, originalvalue, bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-					       "bitmask(%#x)\n", regaddr,
-					       bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+		 regaddr, bitmask);
 	originalvalue = rtl_read_dword(rtlpriv, regaddr);
 	bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
 	returnvalue = (originalvalue & bitmask) >> bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
-					       "Addr[0x%x]=0x%x\n", bitmask,
-					       regaddr, originalvalue));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+		 bitmask, regaddr, originalvalue);
 
 	return returnvalue;
 
@@ -64,9 +63,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 originalvalue, bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-					       " data(%#x)\n", regaddr, bitmask,
-					       data));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+		 regaddr, bitmask, data);
 
 	if (bitmask != MASKDWORD) {
 		originalvalue = rtl_read_dword(rtlpriv, regaddr);
@@ -76,9 +75,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
 
 	rtl_write_dword(rtlpriv, regaddr, data);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-					       " data(%#x)\n", regaddr, bitmask,
-					       data));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+		 regaddr, bitmask, data);
 
 }
 EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
@@ -86,7 +85,7 @@ EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
 u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
 				  enum radio_path rfpath, u32 offset)
 {
-	RT_ASSERT(false, ("deprecated!\n"));
+	RT_ASSERT(false, "deprecated!\n");
 	return 0;
 
 }
@@ -96,7 +95,7 @@ void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
 				    enum radio_path rfpath, u32 offset,
 				    u32 data)
 {
-	RT_ASSERT(false, ("deprecated!\n"));
+	RT_ASSERT(false, "deprecated!\n");
 }
 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
 
@@ -114,7 +113,7 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
 	offset &= 0x3f;
 	newoffset = offset;
 	if (RT_CANNOT_IO(hw)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
 		return 0xFFFFFFFF;
 	}
 	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
@@ -144,9 +143,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
 	else
 		retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
 					 BLSSIREADBACKDATA);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
-					       rfpath, pphyreg->rflssi_readback,
-					       retvalue));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rflssi_readback, retvalue);
 	return retvalue;
 }
 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
@@ -162,16 +160,15 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
 	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 
 	if (RT_CANNOT_IO(hw)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
 		return;
 	}
 	offset &= 0x3f;
 	newoffset = offset;
 	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
-					       rfpath, pphyreg->rf3wire_offset,
-					       data_and_addr));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rf3wire_offset, data_and_addr);
 }
 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write);
 
@@ -216,30 +213,30 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	bool rtstatus;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
 	rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
 						 BASEBAND_CONFIG_PHY_REG);
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
 		return false;
 	}
 	if (rtlphy->rf_type == RF_1T2R) {
 		_rtl92c_phy_bb_config_1t(hw);
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
 	}
 	if (rtlefuse->autoload_failflag == false) {
 		rtlphy->pwrgroup_cnt = 0;
 		rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw,
 						   BASEBAND_CONFIG_PHY_REG);
 	}
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
 		return false;
 	}
 	rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
 						 BASEBAND_CONFIG_AGC_TAB);
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
 		return false;
 	}
 	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
@@ -260,114 +257,114 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
 	if (regaddr == RTXAGC_A_RATE18_06) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]));
+			 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]);
 	}
 	if (regaddr == RTXAGC_A_RATE54_24) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]));
+			 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]);
 	}
 	if (regaddr == RTXAGC_A_CCK1_MCS32) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]));
+			 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]);
 	}
 	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]));
+			 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]);
 	}
 	if (regaddr == RTXAGC_A_MCS03_MCS00) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]));
+			 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]);
 	}
 	if (regaddr == RTXAGC_A_MCS07_MCS04) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]));
+			 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]);
 	}
 	if (regaddr == RTXAGC_A_MCS11_MCS08) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]));
+			 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]);
 	}
 	if (regaddr == RTXAGC_A_MCS15_MCS12) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]));
+			 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]);
 	}
 	if (regaddr == RTXAGC_B_RATE18_06) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]));
+			 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]);
 	}
 	if (regaddr == RTXAGC_B_RATE54_24) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
+			 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]);
 	}
 	if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
+			 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]);
 	}
 	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
+			 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]);
 	}
 	if (regaddr == RTXAGC_B_MCS03_MCS00) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
+			 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]);
 	}
 	if (regaddr == RTXAGC_B_MCS07_MCS04) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
+			 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]);
 	}
 	if (regaddr == RTXAGC_B_MCS11_MCS08) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
+			 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]);
 	}
 	if (regaddr == RTXAGC_B_MCS15_MCS12) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]));
+			 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]);
 
 		rtlphy->pwrgroup_cnt++;
 	}
@@ -389,12 +386,11 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Default initial gain (c50=0x%x, "
-		  "c58=0x%x, c60=0x%x, c68=0x%x\n",
-		  rtlphy->default_initialgain[0],
-		  rtlphy->default_initialgain[1],
-		  rtlphy->default_initialgain[2],
-		  rtlphy->default_initialgain[3]));
+		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
+		 rtlphy->default_initialgain[0],
+		 rtlphy->default_initialgain[1],
+		 rtlphy->default_initialgain[2],
+		 rtlphy->default_initialgain[3]);
 
 	rtlphy->framesync = (u8) rtl_get_bbreg(hw,
 					       ROFDM0_RXDETECTOR3, MASKBYTE0);
@@ -402,8 +398,8 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 					      ROFDM0_RXDETECTOR2, MASKDWORD);
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Default framesync (0x%x) = 0x%x\n",
-		  ROFDM0_RXDETECTOR3, rtlphy->framesync));
+		 "Default framesync (0x%x) = 0x%x\n",
+		 ROFDM0_RXDETECTOR3, rtlphy->framesync);
 }
 
 void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
@@ -584,7 +580,7 @@ void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
 	u8 cckpowerlevel[2], ofdmpowerlevel[2];
 
-	if (rtlefuse->txpwr_fromeprom == false)
+	if (!rtlefuse->txpwr_fromeprom)
 		return;
 	_rtl92c_get_txpower_index(hw, channel,
 				  &cckpowerlevel[0], &ofdmpowerlevel[0]);
@@ -615,8 +611,8 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
 	else
 		ofdmtxpwridx = 0;
 	RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
-		 ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
-		  power_indbm, ccktxpwridx, ofdmtxpwridx));
+		 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
+		 power_indbm, ccktxpwridx, ofdmtxpwridx);
 	for (idx = 0; idx < 14; idx++) {
 		for (rf_path = 0; rf_path < 2; rf_path++) {
 			rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
@@ -710,7 +706,7 @@ void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Unknown Scan Backup operation.\n"));
+				 "Unknown Scan Backup operation\n");
 			break;
 		}
 	}
@@ -732,7 +728,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
 		rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
 	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("FALSE driver sleep or unload\n"));
+			 "FALSE driver sleep or unload\n");
 		rtlphy->set_bwmode_inprogress = false;
 		rtlphy->current_chan_bw = tmp_bw;
 	}
@@ -747,7 +743,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
 	u32 delay;
 
 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-		 ("switch to channel%d\n", rtlphy->current_channel));
+		 "switch to channel%d\n", rtlphy->current_channel);
 	if (is_hal_stop(rtlhal))
 		return;
 	do {
@@ -765,7 +761,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
 		}
 		break;
 	} while (true);
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback);
 
@@ -780,19 +776,18 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
 	if (rtlphy->set_bwmode_inprogress)
 		return 0;
 	RT_ASSERT((rtlphy->current_channel <= 14),
-		  ("WIRELESS_MODE_G but channel>14"));
+		  "WIRELESS_MODE_G but channel>14\n");
 	rtlphy->sw_chnl_inprogress = true;
 	rtlphy->sw_chnl_stage = 0;
 	rtlphy->sw_chnl_step = 0;
 	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 		rtl92c_phy_sw_chnl_callback(hw);
 		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
-			 ("sw_chnl_inprogress false schdule workitem\n"));
+			 "sw_chnl_inprogress false schdule workitem\n");
 		rtlphy->sw_chnl_inprogress = false;
 	} else {
 		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
-			 ("sw_chnl_inprogress false driver sleep or"
-			  " unload\n"));
+			 "sw_chnl_inprogress false driver sleep or unload\n");
 		rtlphy->sw_chnl_inprogress = false;
 	}
 	return 1;
@@ -807,7 +802,7 @@ static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
 	struct swchnlcmd *pcmd;
 
 	if (cmdtable == NULL) {
-		RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+		RT_ASSERT(false, "cmdtable cannot be NULL\n");
 		return false;
 	}
 
@@ -853,7 +848,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 	rfdependcmdcnt = 0;
 
 	RT_ASSERT((channel >= 1 && channel <= 14),
-		  ("illegal channel for Zebra: %d\n", channel));
+		  "invalid channel for Zebra: %d\n", channel);
 
 	_rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 					 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
@@ -916,7 +911,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 
@@ -1920,23 +1915,23 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
 	bool postprocessing = false;
 
 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-		 ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
-		  iotype, rtlphy->set_io_inprogress));
+		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+		 iotype, rtlphy->set_io_inprogress);
 	do {
 		switch (iotype) {
 		case IO_CMD_RESUME_DM_BY_SCAN:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-				 ("[IO CMD] Resume DM after scan.\n"));
+				 "[IO CMD] Resume DM after scan\n");
 			postprocessing = true;
 			break;
 		case IO_CMD_PAUSE_DM_BY_SCAN:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-				 ("[IO CMD] Pause DM before scan.\n"));
+				 "[IO CMD] Pause DM before scan\n");
 			postprocessing = true;
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 	} while (false);
@@ -1947,7 +1942,7 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
 		return false;
 	}
 	rtl92c_phy_set_io(hw);
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
 	return true;
 }
 EXPORT_SYMBOL(rtl92c_phy_set_io_cmd);
@@ -1958,8 +1953,8 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw)
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-		 ("--->Cmd(%#x), set_io_inprogress(%d)\n",
-		  rtlphy->current_io_type, rtlphy->set_io_inprogress));
+		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
+		 rtlphy->current_io_type, rtlphy->set_io_inprogress);
 	switch (rtlphy->current_io_type) {
 	case IO_CMD_RESUME_DM_BY_SCAN:
 		dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
@@ -1973,12 +1968,12 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	rtlphy->set_io_inprogress = false;
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-		 ("<---(%#x)\n", rtlphy->current_io_type));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
+		 rtlphy->current_io_type);
 }
 EXPORT_SYMBOL(rtl92c_phy_set_io);
 
@@ -2018,7 +2013,7 @@ void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw)
 		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Switch RF timeout !!!.\n"));
+			 "Switch RF timeout !!!\n");
 		return;
 	}
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
index 9a264c0..cec10d6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 9fc804d..04c3aef 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
index 2df33e5..27b3af8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -54,7 +54,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
 	if ((mac->link_state < MAC80211_LINKED) &&
 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Not connected to any\n"));
+			 "Not connected to any\n");
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 
@@ -67,28 +67,28 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("AP Client PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "AP Client PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		} else {
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "STA Default Port PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		}
 	} else {
 		undecorated_smoothed_pwdb =
 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("AP Ext Port PWDB = 0x%lx\n",
-			  undecorated_smoothed_pwdb));
+			 "AP Ext Port PWDB = 0x%lx\n",
+			 undecorated_smoothed_pwdb);
 	}
 
 	if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
 	} else if ((undecorated_smoothed_pwdb <
 		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
 		   (undecorated_smoothed_pwdb >=
@@ -96,18 +96,18 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
 	} else if (undecorated_smoothed_pwdb <
 		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_NORMAL\n"));
+			 "TXHIGHPWRLEVEL_NORMAL\n");
 	}
 
 	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-			  rtlphy->current_channel));
+			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+			 rtlphy->current_channel);
 		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
 	}
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
index 07dd955..26747fa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index a3deaef..5c4d9bc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -141,7 +141,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		}
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 }
@@ -207,7 +207,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			u8 e_aci;
 
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("HW_VAR_SLOT_TIME %x\n", val[0]));
+				 "HW_VAR_SLOT_TIME %x\n", val[0]);
 
 			rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
 
@@ -246,8 +246,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 				*val = min_spacing_to_set;
 
 				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-					 ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-					  mac->min_space_cfg));
+					 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+					 mac->min_space_cfg);
 
 				rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 					       mac->min_space_cfg);
@@ -261,8 +261,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			mac->min_space_cfg |= (density_to_set << 3);
 
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-				  mac->min_space_cfg));
+				 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+				 mac->min_space_cfg);
 
 			rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 				       mac->min_space_cfg);
@@ -310,8 +310,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 				}
 
 				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-					 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-					  factor_toset));
+					 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+					 factor_toset);
 			}
 			break;
 		}
@@ -348,8 +348,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					break;
 				default:
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("HW_VAR_ACM_CTRL acm set "
-						  "failed: eACI is %d\n", acm));
+						 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+						 acm);
 					break;
 				}
 			} else {
@@ -365,14 +365,14 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					break;
 				default:
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-						 ("switch case not process\n"));
+						 "switch case not processed\n");
 					break;
 				}
 			}
 
 			RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-				 ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
-				  "Write 0x%X\n", acm_ctrl));
+				 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+				 acm_ctrl);
 			rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
 			break;
 		}
@@ -507,8 +507,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 
 		}
 	default:
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-							"not process\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "switch case not processed\n");
 		break;
 	}
 }
@@ -530,8 +530,8 @@ static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 
 		if (count > POLLING_LLT_THRESHOLD) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Failed to polling write LLT done at "
-				  "address %d!\n", address));
+				 "Failed to polling write LLT done at address %d!\n",
+				 address);
 			status = false;
 			break;
 		}
@@ -669,18 +669,15 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
 	udelay(2);
 
 	retry = 0;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
-						rtl_read_dword(rtlpriv, 0xEC),
-						bytetmp));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n",
+		 rtl_read_dword(rtlpriv, 0xEC), bytetmp);
 
 	while ((bytetmp & BIT(0)) && retry < 1000) {
 		retry++;
 		udelay(50);
 		bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n",
-							rtl_read_dword(rtlpriv,
-								       0xEC),
-							bytetmp));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n",
+			 rtl_read_dword(rtlpriv, 0xEC), bytetmp);
 		udelay(50);
 	}
 
@@ -696,7 +693,7 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
 
 	rtl_write_word(rtlpriv, REG_CR, 0x2ff);
 
-	if (_rtl92ce_llt_table_init(hw) == false)
+	if (!_rtl92ce_llt_table_init(hw))
 		return false;
 
 	rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
@@ -864,13 +861,13 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
 	u8 sec_reg_value;
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
-		  rtlpriv->sec.pairwise_enc_algorithm,
-		  rtlpriv->sec.group_enc_algorithm));
+		 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+		 rtlpriv->sec.pairwise_enc_algorithm,
+		 rtlpriv->sec.group_enc_algorithm);
 
 	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open "
-							"hw encryption\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+			 "not open hw encryption\n");
 		return;
 	}
 
@@ -886,7 +883,7 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw)
 	rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
 
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-		 ("The SECR-value %x\n", sec_reg_value));
+		 "The SECR-value %x\n", sec_reg_value);
 
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 
@@ -909,8 +906,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
 	rtlpci->being_init_adapter = true;
 	rtlpriv->intf_ops->disable_aspm(hw);
 	rtstatus = _rtl92ce_init_mac(hw);
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
 		err = 1;
 		return err;
 	}
@@ -918,13 +915,9 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
 	err = rtl92c_download_fw(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Failed to download FW. Init HW "
-			  "without FW now..\n"));
+			 "Failed to download FW. Init HW without FW now..\n");
 		err = 1;
-		rtlhal->fw_ready = false;
 		return err;
-	} else {
-		rtlhal->fw_ready = true;
 	}
 
 	rtlhal->last_hmeboxnum = 0;
@@ -968,12 +961,12 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
 	tmp_u1b = efuse_read_1byte(hw, 0x1FA);
 	if (!(tmp_u1b & BIT(0))) {
 		rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
 	}
 
 	if (!(tmp_u1b & BIT(1)) && is92c) {
 		rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05);
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path B\n");
 	}
 
 	if (!(tmp_u1b & BIT(4))) {
@@ -982,7 +975,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw)
 		rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
 		udelay(10);
 		rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
 	}
 	rtl92c_dm_init(hw);
 	rtlpci->being_init_adapter = false;
@@ -995,6 +988,7 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	enum version_8192c version = VERSION_UNKNOWN;
 	u32 value32;
+	const char *versionid;
 
 	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
 	if (value32 & TRP_VAUX_EN) {
@@ -1007,27 +1001,25 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
 
 	switch (version) {
 	case VERSION_B_CHIP_92C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
+		versionid = "B_CHIP_92C";
 		break;
 	case VERSION_B_CHIP_88C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Chip Version ID: VERSION_B_CHIP_88C.\n"));
+		versionid = "B_CHIP_88C";
 		break;
 	case VERSION_A_CHIP_92C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Chip Version ID: VERSION_A_CHIP_92C.\n"));
+		versionid = "A_CHIP_92C";
 		break;
 	case VERSION_A_CHIP_88C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Chip Version ID: VERSION_A_CHIP_88C.\n"));
+		versionid = "A_CHIP_88C";
 		break;
 	default:
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Chip Version ID: Unknown. Bug?\n"));
+		versionid = "Unknown. Bug?";
 		break;
 	}
 
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+		 "Chip Version ID: %s\n", versionid);
+
 	switch (version & 0x3) {
 	case CHIP_88C:
 		rtlphy->rf_type = RF_1T1R;
@@ -1041,13 +1033,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
 	default:
 		rtlphy->rf_type = RF_1T1R;
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("ERROR RF_Type is set!!"));
+			 "ERROR RF_Type is set!!\n");
 		break;
 	}
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
-		  "RF_2T2R" : "RF_1T1R"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n",
+		 rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
 
 	return version;
 }
@@ -1069,8 +1060,8 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
 		_rtl92ce_disable_bcn_sub_func(hw);
 	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Set HW_VAR_MEDIA_STATUS: "
-			  "No such media status(%x).\n", type));
+			 "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
+			 type);
 	}
 
 	switch (type) {
@@ -1078,27 +1069,27 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
 		bt_msr |= MSR_NOLINK;
 		ledaction = LED_CTL_LINK;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to NO LINK!\n"));
+			 "Set Network type to NO LINK!\n");
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		bt_msr |= MSR_ADHOC;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to Ad Hoc!\n"));
+			 "Set Network type to Ad Hoc!\n");
 		break;
 	case NL80211_IFTYPE_STATION:
 		bt_msr |= MSR_INFRA;
 		ledaction = LED_CTL_LINK;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to STA!\n"));
+			 "Set Network type to STA!\n");
 		break;
 	case NL80211_IFTYPE_AP:
 		bt_msr |= MSR_AP;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to AP!\n"));
+			 "Set Network type to AP!\n");
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Network type %d not support!\n", type));
+			 "Network type %d not supported!\n", type);
 		return 1;
 		break;
 
@@ -1126,7 +1117,7 @@ void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
 					      (u8 *) (&reg_rcr));
 		_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
-	} else if (check_bssid == false) {
+	} else if (!check_bssid) {
 		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
 		_rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
 		rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -1171,7 +1162,7 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
 		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
 		break;
 	default:
-		RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+		RT_ASSERT(false, "invalid aci: %d !\n", aci);
 		break;
 	}
 }
@@ -1199,7 +1190,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 u1b_tmp;
 	u32 u4b_tmp;
 
@@ -1210,7 +1200,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
 	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
-	if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
+	if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7))
 		rtl92c_firmware_selfreset(hw);
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
 	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
@@ -1300,7 +1290,7 @@ void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw)
 	u16 bcn_interval = mac->beacon_interval;
 
 	RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
-		 ("beacon_interval:%d\n", bcn_interval));
+		 "beacon_interval:%d\n", bcn_interval);
 	rtl92ce_disable_interrupt(hw);
 	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 	rtl92ce_enable_interrupt(hw);
@@ -1312,8 +1302,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+		 add_msr, rm_msr);
 
 	if (add_msr)
 		rtlpci->irq_mask[0] |= add_msr;
@@ -1367,25 +1357,24 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
-				 i,
-				 rtlefuse->
-				 eeprom_chnlarea_txpwr_cck[rf_path][i]));
+				"RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->
+				eeprom_chnlarea_txpwr_cck[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->
-				 eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]));
+				"RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->
+				eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->
-				 eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
-				 [i]));
+				"RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->
+				eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]);
 
 	for (rf_path = 0; rf_path < 2; rf_path++) {
 		for (i = 0; i < 14; i++) {
@@ -1416,11 +1405,11 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 
 		for (i = 0; i < 14; i++) {
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
-				 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
-				 rtlefuse->txpwrlevel_cck[rf_path][i],
-				 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
-				 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+				"RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
+				rf_path, i,
+				rtlefuse->txpwrlevel_cck[rf_path][i],
+				rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+				rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
 		}
 	}
 
@@ -1457,13 +1446,13 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 			}
 
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->pwrgroup_ht20[rf_path][i]));
+				"RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+				rf_path, i,
+				rtlefuse->pwrgroup_ht20[rf_path][i]);
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->pwrgroup_ht40[rf_path][i]));
+				"RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+				rf_path, i,
+				rtlefuse->pwrgroup_ht40[rf_path][i]);
 		}
 	}
 
@@ -1502,27 +1491,27 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+			"RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+			"RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+			"RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+			"RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 
 	if (!autoload_fail)
 		rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
 	else
 		rtlefuse->eeprom_regulatory = 0;
 	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+		"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 
 	if (!autoload_fail) {
 		rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
@@ -1531,10 +1520,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 		rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
 		rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
 	}
-	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
-		 rtlefuse->eeprom_tssi[RF90_PATH_A],
-		 rtlefuse->eeprom_tssi[RF90_PATH_B]));
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+		rtlefuse->eeprom_tssi[RF90_PATH_A],
+		rtlefuse->eeprom_tssi[RF90_PATH_B]);
 
 	if (!autoload_fail)
 		tempval = hwinfo[EEPROM_THERMAL_METER];
@@ -1547,7 +1535,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 
 	rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
 	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+		"thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 }
 
 static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
@@ -1567,19 +1555,19 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
 		       HWSET_MAX_SIZE);
 	} else if (rtlefuse->epromtype == EEPROM_93C46) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("RTL819X Not boot from eeprom, check it !!"));
+			 "RTL819X Not boot from eeprom, check it !!");
 	}
 
-	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
 		      hwinfo, HWSET_MAX_SIZE);
 
 	eeprom_id = *((u16 *)&hwinfo[0]);
 	if (eeprom_id != RTL8190_EEPROM_ID) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+			 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
 		rtlefuse->autoload_failflag = true;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 		rtlefuse->autoload_failflag = false;
 	}
 
@@ -1591,8 +1579,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
 		*((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
 	}
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("%pM\n", rtlefuse->dev_addr));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
 
 	_rtl92ce_read_txpower_info_from_hwpg(hw,
 					     rtlefuse->autoload_failflag,
@@ -1608,7 +1595,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw)
 	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+		 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
 
 	/* set channel paln to world wide 13 */
 	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
@@ -1662,7 +1649,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw)
 		break;
 	}
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
+		 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
 }
 
 void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
@@ -1679,22 +1666,22 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw)
 	else
 		rtlpriv->dm.rfpath_rxenable[0] =
 		    rtlpriv->dm.rfpath_rxenable[1] = true;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
-						rtlhal->version));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
+		 rtlhal->version);
 	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
 	if (tmp_u1b & BIT(4)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
 		rtlefuse->epromtype = EEPROM_93C46;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
 		rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
 	}
 	if (tmp_u1b & BIT(5)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 		rtlefuse->autoload_failflag = false;
 		_rtl92ce_read_adapter_info(hw);
 	} else {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
 	}
 	_rtl92ce_hal_customized_behavior(hw);
 }
@@ -1790,8 +1777,8 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
 
 	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
 
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-		 ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+		 rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
@@ -1919,16 +1906,15 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
 		break;
 	}
 	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-		 ("ratr_bitmap :%x\n", ratr_bitmap));
+		 "ratr_bitmap :%x\n", ratr_bitmap);
 	*(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
 				     (ratr_index << 28));
 	rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
-						 "ratr_val:%x, %x:%x:%x:%x:%x\n",
-						 ratr_index, ratr_bitmap,
-						 rate_mask[0], rate_mask[1],
-						 rate_mask[2], rate_mask[3],
-						 rate_mask[4]));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+		 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
+		 ratr_index, ratr_bitmap,
+		 rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
+		 rate_mask[4]);
 	rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
 
 	if (macid != 0)
@@ -1994,15 +1980,14 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
 
 	if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("GPIOChangeRF  - HW Radio ON, RF ON\n"));
+			 "GPIOChangeRF  - HW Radio ON, RF ON\n");
 
 		e_rfpowerstate_toset = ERFON;
 		ppsc->hwradiooff = false;
 		actuallyset = true;
-	} else if ((ppsc->hwradiooff == false)
-		   && (e_rfpowerstate_toset == ERFOFF)) {
+	} else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("GPIOChangeRF  - HW Radio OFF, RF OFF\n"));
+			 "GPIOChangeRF  - HW Radio OFF, RF OFF\n");
 
 		e_rfpowerstate_toset = ERFOFF;
 		ppsc->hwradiooff = true;
@@ -2053,7 +2038,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 		u8 cam_offset = 0;
 		u8 clear_number = 5;
 
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 
 		for (idx = 0; idx < clear_number; idx++) {
 			rtl_cam_mark_invalid(hw, cam_offset + idx);
@@ -2081,8 +2066,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 			enc_algo = CAM_AES;
 			break;
 		default:
-			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-					"not process\n"));
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 "switch case not processed\n");
 			enc_algo = CAM_TKIP;
 			break;
 		}
@@ -2100,9 +2085,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 								 p_macaddr);
 					if (entry_id >=  TOTAL_CAM_ENTRY) {
 						RT_TRACE(rtlpriv, COMP_SEC,
-						     DBG_EMERG,
-						     ("Can not find free hw"
-						     " security cam entry\n"));
+							 DBG_EMERG,
+							 "Can not find free hw security cam entry\n");
 						return;
 					}
 				} else {
@@ -2116,31 +2100,31 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 
 		if (rtlpriv->sec.key_len[key_index] == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("delete one entry, entry_id is %d\n",
-				 entry_id));
+				 "delete one entry, entry_id is %d\n",
+				 entry_id);
 			if (mac->opmode == NL80211_IFTYPE_AP)
 				rtl_cam_del_entry(hw, p_macaddr);
 			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 		} else {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY length is %d\n",
-				  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+				 "The insert KEY length is %d\n",
+				 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY  is %x %x\n",
-				  rtlpriv->sec.key_buf[0][0],
-				  rtlpriv->sec.key_buf[0][1]));
+				 "The insert KEY is %x %x\n",
+				 rtlpriv->sec.key_buf[0][0],
+				 rtlpriv->sec.key_buf[0][1]);
 
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("add one entry\n"));
+				 "add one entry\n");
 			if (is_pairwise) {
 				RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-					      "Pairwiase Key content :",
+					      "Pairwise Key content",
 					      rtlpriv->sec.pairwise_key,
 					      rtlpriv->sec.
 					      key_len[PAIRWISE_KEYIDX]);
 
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set Pairwiase key\n"));
+					 "set Pairwise key\n");
 
 				rtl_cam_add_one_entry(hw, macaddr, key_index,
 						      entry_id, enc_algo,
@@ -2149,7 +2133,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 						      key_buf[key_index]);
 			} else {
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set group key\n"));
+					 "set group key\n");
 
 				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 					rtl_cam_add_one_entry(hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
index 07dbe3e..52a3aea 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
index 28a1a70..8283e9b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -45,8 +45,8 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 	u8 ledcfg;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 REG_LEDCFG2, pled->ledpin);
 
 	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 
@@ -62,7 +62,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = true;
@@ -74,8 +74,8 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
 	u8 ledcfg;
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 REG_LEDCFG2, pled->ledpin);
 
 	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 
@@ -97,7 +97,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = false;
@@ -145,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw,
 	     ledaction == LED_CTL_POWER_ON)) {
 		return;
 	}
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n",
-				ledaction));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n",
+		 ledaction);
 	_rtl92ce_sw_led_control(hw, ledaction);
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
index 7dfccea..c576106 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
index 3b585aa..88deae6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -47,9 +47,9 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
 	u32 original_value, readback_value, bitshift;
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-					       "rfpath(%#x), bitmask(%#x)\n",
-					       regaddr, rfpath, bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+		 regaddr, rfpath, bitmask);
 
 	spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -67,9 +67,8 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
 	spin_unlock(&rtlpriv->locks.rf_lock);
 
 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-		 ("regaddr(%#x), rfpath(%#x), "
-		  "bitmask(%#x), original_value(%#x)\n",
-		  regaddr, rfpath, bitmask, original_value));
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+		 regaddr, rfpath, bitmask, original_value);
 
 	return readback_value;
 }
@@ -121,8 +120,8 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
 	u32 original_value, bitshift;
 
 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-		 ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
-		  regaddr, bitmask, data, rfpath));
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 
 	spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -153,10 +152,9 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
 
 	spin_unlock(&rtlpriv->locks.rf_lock);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-					       "bitmask(%#x), data(%#x), "
-					       "rfpath(%#x)\n", regaddr,
-					       bitmask, data, rfpath));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 }
 
 static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
@@ -166,11 +164,10 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 	u32 arraylength;
 	u32 *ptrarray;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
 	arraylength = MAC_2T_ARRAYLENGTH;
 	ptrarray = RTL8192CEMAC_2T_ARRAY;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Img:RTL8192CEMAC_2T_ARRAY\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
 	for (i = 0; i < arraylength; i = i + 2)
 		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 	return true;
@@ -215,10 +212,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 				      phy_regarray_table[i + 1]);
 			udelay(1);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("The phy_regarray_table[0] is %x"
-				  " Rtl819XPHY_REGArray[1] is %x\n",
-				  phy_regarray_table[i],
-				  phy_regarray_table[i + 1]));
+				 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+				 phy_regarray_table[i],
+				 phy_regarray_table[i + 1]);
 		}
 	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 		for (i = 0; i < agctab_arraylen; i = i + 2) {
@@ -226,10 +222,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 				      agctab_array_table[i + 1]);
 			udelay(1);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("The agctab_array_table[0] is "
-				  "%x Rtl819XPHY_REGArray[1] is %x\n",
-				  agctab_array_table[i],
-				  agctab_array_table[i + 1]));
+				 "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+				 agctab_array_table[i],
+				 agctab_array_table[i + 1]);
 		}
 	}
 	return true;
@@ -269,7 +264,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 	} else {
 
 		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-			 ("configtype != BaseBand_Config_PHY_REG\n"));
+			 "configtype != BaseBand_Config_PHY_REG\n");
 	}
 	return true;
 }
@@ -291,20 +286,20 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 		radiob_arraylen = RADIOB_2TARRAYLENGTH;
 		radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
+			 "Radio_A:RTL8192CERADIOA_2TARRAY\n");
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
+			 "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
 	} else {
 		radioa_arraylen = RADIOA_1TARRAYLENGTH;
 		radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
 		radiob_arraylen = RADIOB_1TARRAYLENGTH;
 		radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
+			 "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
+			 "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
 	}
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
 	switch (rfpath) {
 	case RF90_PATH_A:
 		for (i = 0; i < radioa_arraylen; i = i + 2) {
@@ -352,11 +347,11 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 		break;
 	case RF90_PATH_C:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	case RF90_PATH_D:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	return true;
@@ -371,10 +366,9 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 	u8 reg_bw_opmode;
 	u8 reg_prsr_rsc;
 
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-		 ("Switch to %s bandwidth\n",
-		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-		  "20MHz" : "40MHz"))
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+		 "20MHz" : "40MHz");
 
 	if (is_hal_stop(rtlhal)) {
 		rtlphy->set_bwmode_inprogress = false;
@@ -398,7 +392,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 
@@ -423,12 +417,12 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 	rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 	rtlphy->set_bwmode_inprogress = false;
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
@@ -499,7 +493,7 @@ static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
 		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Switch RF timeout !!!.\n"));
+			 "Switch RF timeout !!!\n");
 		return;
 	}
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
@@ -526,18 +520,17 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
 				do {
 					InitializeCount++;
 					RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-						 ("IPS Set eRf nic enable\n"));
+						 "IPS Set eRf nic enable\n");
 					rtstatus = rtl_ps_enable_nic(hw);
-				} while ((rtstatus != true)
-					 && (InitializeCount < 10));
+				} while (!rtstatus && (InitializeCount < 10));
 				RT_CLEAR_PS_LEVEL(ppsc,
 						  RT_RF_OFF_LEVL_HALT_NIC);
 			} else {
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-					 ("Set ERFON sleeped:%d ms\n",
-					  jiffies_to_msecs(jiffies -
-						   ppsc->
-						   last_sleep_jiffies)));
+					 "Set ERFON sleeped:%d ms\n",
+					 jiffies_to_msecs(jiffies -
+							  ppsc->
+							  last_sleep_jiffies));
 				ppsc->last_awake_jiffies = jiffies;
 				rtl92ce_phy_set_rf_on(hw);
 			}
@@ -553,7 +546,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
 	case ERFOFF:{
 			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-					 ("IPS Set eRf nic disable\n"));
+					 "IPS Set eRf nic disable\n");
 				rtl_ps_disable_nic(hw);
 				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 			} else {
@@ -578,35 +571,33 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
 					continue;
 				} else {
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("eRf Off/Sleep: %d times "
-						  "TcbBusyQueue[%d] =%d before "
-						  "doze!\n", (i + 1), queue_id,
-						  skb_queue_len(&ring->queue)));
+						 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+						 i + 1, queue_id,
+						 skb_queue_len(&ring->queue));
 
 					udelay(10);
 					i++;
 				}
 				if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("\n ERFSLEEP: %d times "
-						  "TcbBusyQueue[%d] = %d !\n",
-						  MAX_DOZE_WAITING_TIMES_9x,
-						  queue_id,
-						  skb_queue_len(&ring->queue)));
+						 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
+						 MAX_DOZE_WAITING_TIMES_9x,
+						 queue_id,
+						 skb_queue_len(&ring->queue));
 					break;
 				}
 			}
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-				 ("Set ERFSLEEP awaked:%d ms\n",
-				  jiffies_to_msecs(jiffies -
-						   ppsc->last_awake_jiffies)));
+				 "Set ERFSLEEP awaked:%d ms\n",
+				 jiffies_to_msecs(jiffies -
+						  ppsc->last_awake_jiffies));
 			ppsc->last_sleep_jiffies = jiffies;
 			_rtl92ce_phy_set_rf_sleep(hw);
 			break;
 		}
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		bresult = false;
 		break;
 	}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
index be2c92a..d5e3b70 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
index ba5ff04..43806d9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
index d3b01e6..54c7614 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -56,7 +56,7 @@ void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", bandwidth));
+			 "unknown bandwidth: %#X\n", bandwidth);
 		break;
 	}
 }
@@ -123,8 +123,8 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
 	rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
 
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_A_CCK1_MCS32));
+		"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_A_CCK1_MCS32);
 
 	tmpval = tx_agc[RF90_PATH_A] >> 8;
 
@@ -133,22 +133,22 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
 
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_B_CCK11_A_CCK2_11));
+		"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 
 	tmpval = tx_agc[RF90_PATH_B] >> 24;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
 
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_B_CCK11_A_CCK2_11));
+		"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 
 	tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
 
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_B_CCK1_55_MCS32));
+		"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK1_55_MCS32);
 }
 
 static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
@@ -171,8 +171,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
 		    (powerBase0 << 8) | powerBase0;
 		*(ofdmbase + i) = powerBase0;
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			(" [OFDM power base index rf(%c) = 0x%x]\n",
-			 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+			" [OFDM power base index rf(%c) = 0x%x]\n",
+			i == 0 ? 'A' : 'B', *(ofdmbase + i));
 	}
 
 	for (i = 0; i < 2; i++) {
@@ -187,8 +187,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
 		*(mcsbase + i) = powerBase1;
 
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			(" [MCS power base index rf(%c) = 0x%x]\n",
-			 ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+			" [MCS power base index rf(%c) = 0x%x]\n",
+			i == 0 ? 'A' : 'B', *(mcsbase + i));
 	}
 }
 
@@ -215,9 +215,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 			    + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("RTK better performance, "
-				 "writeVal(%c) = 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), writeVal));
+				"RTK better performance, writeVal(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		case 1:
 			if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
@@ -225,9 +224,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 					    powerBase1[rf]);
 
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("Realtek regulatory, 40MHz, "
-					 "writeVal(%c) = 0x%x\n",
-					 ((rf == 0) ? 'A' : 'B'), writeVal));
+					"Realtek regulatory, 40MHz, writeVal(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B', writeVal);
 			} else {
 				if (rtlphy->pwrgroup_cnt == 1)
 					chnlgroup = 0;
@@ -249,9 +247,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 							      powerBase1[rf]);
 
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("Realtek regulatory, 20MHz, "
-					 "writeVal(%c) = 0x%x\n",
-					 ((rf == 0) ? 'A' : 'B'), writeVal));
+					"Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B', writeVal);
 			}
 			break;
 		case 2:
@@ -259,27 +256,24 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 			    ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Better regulatory, "
-				 "writeVal(%c) = 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), writeVal));
+				"Better regulatory, writeVal(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		case 3:
 			chnlgroup = 0;
 
 			if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("customer's limit, 40MHz "
-					 "rf(%c) = 0x%x\n",
-					 ((rf == 0) ? 'A' : 'B'),
-					 rtlefuse->pwrgroup_ht40[rf][channel -
-								     1]));
+					"customer's limit, 40MHz rf(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B',
+					rtlefuse->pwrgroup_ht40[rf][channel -
+								    1]);
 			} else {
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("customer's limit, 20MHz "
-					 "rf(%c) = 0x%x\n",
-					 ((rf == 0) ? 'A' : 'B'),
-					 rtlefuse->pwrgroup_ht20[rf][channel -
-								     1]));
+					"customer's limit, 20MHz rf(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B',
+					rtlefuse->pwrgroup_ht20[rf][channel -
+								    1]);
 			}
 			for (i = 0; i < 4; i++) {
 				pwr_diff_limit[i] =
@@ -311,15 +305,15 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 			    (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
 
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Customer's limit rf(%c) = 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), customer_limit));
+				"Customer's limit rf(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', customer_limit);
 
 			writeVal = customer_limit +
 			    ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Customer, writeVal rf(%c)= 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), writeVal));
+				"Customer, writeVal rf(%c)= 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		default:
 			chnlgroup = 0;
@@ -329,9 +323,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 			    + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("RTK better performance, writeVal "
-				 "rf(%c) = 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), writeVal));
+				"RTK better performance, writeVal rf(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		}
 
@@ -383,7 +376,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
 		rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
 
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			("Set 0x%x = %08x\n", regoffset, writeVal));
+			"Set 0x%x = %08x\n", regoffset, writeVal);
 
 		if (((get_rf_type(rtlphy) == RF_2T2R) &&
 		     (regoffset == RTXAGC_A_MCS15_MCS12 ||
@@ -510,14 +503,14 @@ static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
 			break;
 		}
 
-		if (rtstatus != true) {
+		if (!rtstatus) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("Radio[%d] Fail!!", rfpath));
+				 "Radio[%d] Fail!!\n", rfpath);
 			return false;
 		}
 
 	}
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
 	return rtstatus;
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
index 39ff036..6c8d56e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 89ef698..2c3b733 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,9 +27,6 @@
  *
  *****************************************************************************/
 
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
@@ -43,6 +40,8 @@
 #include "trx.h"
 #include "led.h"
 
+#include <linux/module.h>
+
 static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -92,9 +91,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 	int err;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	const struct firmware *firmware;
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	char *fw_name = NULL;
 
 	rtl8192ce_bt_reg_init(hw);
 
@@ -159,33 +156,27 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
 	if (!rtlpriv->rtlhal.pfirmware) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't alloc buffer for fw.\n"));
+			 "Can't alloc buffer for fw\n");
 		return 1;
 	}
 
 	/* request fw */
 	if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
 	    !IS_92C_SERIAL(rtlhal->version))
-		fw_name = "rtlwifi/rtl8192cfwU.bin";
+		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
 	else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
-		fw_name = "rtlwifi/rtl8192cfwU_B.bin";
-	else
-		fw_name = rtlpriv->cfg->fw_name;
-	err = request_firmware(&firmware, fw_name, rtlpriv->io.dev);
+		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
+
+	rtlpriv->max_fw_size = 0x4000;
+	pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
+	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+				      rtlpriv->io.dev, GFP_KERNEL, hw,
+				      rtl_fw_cb);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Failed to request firmware!\n"));
-		return 1;
-	}
-	if (firmware->size > 0x4000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
+			 "Failed to request firmware!\n");
 		return 1;
 	}
-	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-	rtlpriv->rtlhal.fwsize = firmware->size;
-	release_firmware(firmware);
 
 	return 0;
 }
@@ -404,7 +395,7 @@ static int __init rtl92ce_module_init(void)
 
 	ret = pci_register_driver(&rtl92ce_driver);
 	if (ret)
-		RT_ASSERT(false, (": No device found\n"));
+		RT_ASSERT(false, "No device found\n");
 
 	return ret;
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
index b7dc326..d2367a5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
index ba938b9..752f943 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
index 3a6e8b6..8b79161 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 4fb5ae2..37b1363 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -725,7 +725,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 		if (ieee80211_is_data_qos(fc)) {
 			if (mac->rdg_en) {
 				RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-					 ("Enable RDG function.\n"));
+					 "Enable RDG function\n");
 				SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 				SET_TX_DESC_HTC(pdesc, 1);
 			}
@@ -763,7 +763,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 		SET_TX_DESC_BMC(pdesc, 1);
 	}
 
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 }
 
 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
@@ -821,8 +821,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
 	}
 
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-		      "H2C Tx Cmd Content\n",
-		      pdesc, TX_DESC_SIZE);
+		      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 }
 
 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
@@ -837,8 +836,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR txdesc :%d"
-					  " not process\n", desc_name));
+			RT_ASSERT(false, "ERR txdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	} else {
@@ -857,8 +856,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 			SET_RX_DESC_EOR(pdesc, 1);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR rxdesc :%d "
-					  "not process\n", desc_name));
+			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	}
@@ -877,8 +876,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR txdesc :%d "
-					  "not process\n", desc_name));
+			RT_ASSERT(false, "ERR txdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	} else {
@@ -891,8 +890,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 			ret = GET_RX_DESC_PKT_LEN(pdesc);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR rxdesc :%d "
-					  "not process\n", desc_name));
+			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
index c8977a5..efb9ab2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
index d097efb..f916555 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
index f311bae..6fd39ea 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -52,7 +52,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
 	if ((mac->link_state < MAC80211_LINKED) &&
 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Not connected to any\n"));
+			 "Not connected to any\n");
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 
@@ -65,28 +65,28 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("AP Client PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "AP Client PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		} else {
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "STA Default Port PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		}
 	} else {
 		undecorated_smoothed_pwdb =
 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("AP Ext Port PWDB = 0x%lx\n",
-			  undecorated_smoothed_pwdb));
+			 "AP Ext Port PWDB = 0x%lx\n",
+			 undecorated_smoothed_pwdb);
 	}
 
 	if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
 	} else if ((undecorated_smoothed_pwdb <
 		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
 		   (undecorated_smoothed_pwdb >=
@@ -94,18 +94,18 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+			 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
 	} else if (undecorated_smoothed_pwdb <
 		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("TXHIGHPWRLEVEL_NORMAL\n"));
+			 "TXHIGHPWRLEVEL_NORMAL\n");
 	}
 
 	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-			  rtlphy->current_channel));
+			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+			 rtlphy->current_channel);
 		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
 	}
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
index 7f966c6..d947e7d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 124cf63..0c74d4f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
@@ -162,24 +160,24 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
-				 i, rtlefuse->
-				 eeprom_chnlarea_txpwr_cck[rf_path][i]));
+				"RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->
+				eeprom_chnlarea_txpwr_cck[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->
-				 eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]));
+				"RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->
+				eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->
-				 eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path]
-				 [i]));
+				"RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->
+				eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++) {
 		for (i = 0; i < 14; i++) {
 			index = _rtl92c_get_chnl_group((u8) i);
@@ -205,11 +203,10 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 		}
 		for (i = 0; i < 14; i++) {
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
-				 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
-				 rtlefuse->txpwrlevel_cck[rf_path][i],
-				 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
-				 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+				"RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i,
+				rtlefuse->txpwrlevel_cck[rf_path][i],
+				rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+				rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
 		}
 	}
 	for (i = 0; i < 3; i++) {
@@ -242,13 +239,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 				      & 0xf0) >> 4);
 			}
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->pwrgroup_ht20[rf_path][i]));
+				"RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+				rf_path, i,
+				rtlefuse->pwrgroup_ht20[rf_path][i]);
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->pwrgroup_ht40[rf_path][i]));
+				"RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+				rf_path, i,
+				rtlefuse->pwrgroup_ht40[rf_path][i]);
 		}
 	}
 	for (i = 0; i < 14; i++) {
@@ -277,26 +274,26 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 	    rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+			"RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+			"RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+			"RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+			"RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 	if (!autoload_fail)
 		rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
 	else
 		rtlefuse->eeprom_regulatory = 0;
 	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+		"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 	if (!autoload_fail) {
 		rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
 		rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B];
@@ -305,9 +302,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 		rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
 	}
 	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
-		 rtlefuse->eeprom_tssi[RF90_PATH_A],
-		 rtlefuse->eeprom_tssi[RF90_PATH_B]));
+		"TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+		rtlefuse->eeprom_tssi[RF90_PATH_A],
+		rtlefuse->eeprom_tssi[RF90_PATH_B]);
 	if (!autoload_fail)
 		tempval = hwinfo[EEPROM_THERMAL_METER];
 	else
@@ -320,7 +317,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 		rtlefuse->apk_thermalmeterignore = true;
 	rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
 	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+		"thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 }
 
 static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
@@ -340,144 +337,8 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
 	if (IS_HIGHT_PA(rtlefuse->board_type))
 		rtlefuse->external_pa = 1;
 	pr_info("Board Type %x\n", rtlefuse->board_type);
-
-#ifdef CONFIG_ANTENNA_DIVERSITY
-	/* Antenna Diversity setting. */
-	if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */
-		rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3;
-	else
-		rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */
-
-	pr_info("Antenna Config %x\n", rtl_efuse->antenna_cfg);
-#endif
-}
-
-#ifdef CONFIG_BT_COEXIST
-static void _update_bt_param(_adapter *padapter)
-{
-	struct btcoexist_priv	 *pbtpriv = &(padapter->halpriv.bt_coexist);
-	struct registry_priv	*registry_par = &padapter->registrypriv;
-	if (2 != registry_par->bt_iso) {
-		/* 0:Low, 1:High, 2:From Efuse */
-		pbtpriv->BT_Ant_isolation = registry_par->bt_iso;
-	}
-	if (registry_par->bt_sco == 1) {
-		/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy,
-		 * 5.OtherBusy */
-		pbtpriv->BT_Service = BT_OtherAction;
-	} else if (registry_par->bt_sco == 2) {
-		pbtpriv->BT_Service = BT_SCO;
-	} else if (registry_par->bt_sco == 4) {
-		pbtpriv->BT_Service = BT_Busy;
-	} else if (registry_par->bt_sco == 5) {
-		pbtpriv->BT_Service = BT_OtherBusy;
-	} else {
-		pbtpriv->BT_Service = BT_Idle;
-	}
-	pbtpriv->BT_Ampdu = registry_par->bt_ampdu;
-	pbtpriv->bCOBT = _TRUE;
-	pbtpriv->BtEdcaUL = 0;
-	pbtpriv->BtEdcaDL = 0;
-	pbtpriv->BtRssiState = 0xff;
-	pbtpriv->bInitSet = _FALSE;
-	pbtpriv->bBTBusyTraffic = _FALSE;
-	pbtpriv->bBTTrafficModeSet = _FALSE;
-	pbtpriv->bBTNonTrafficModeSet = _FALSE;
-	pbtpriv->CurrentState = 0;
-	pbtpriv->PreviousState = 0;
-	pr_info("BT Coexistance = %s\n",
-		(pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable");
-	if (pbtpriv->BT_Coexist) {
-		if (pbtpriv->BT_Ant_Num == Ant_x2)
-			pr_info("BlueTooth BT_Ant_Num = Antx2\n");
-		else if (pbtpriv->BT_Ant_Num == Ant_x1)
-			pr_info("BlueTooth BT_Ant_Num = Antx1\n");
-		switch (pbtpriv->BT_CoexistType) {
-		case BT_2Wire:
-			pr_info("BlueTooth BT_CoexistType = BT_2Wire\n");
-			break;
-		case BT_ISSC_3Wire:
-			pr_info("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n");
-			break;
-		case BT_Accel:
-			pr_info("BlueTooth BT_CoexistType = BT_Accel\n");
-			break;
-		case BT_CSR_BC4:
-			pr_info("BlueTooth BT_CoexistType = BT_CSR_BC4\n");
-			break;
-		case BT_CSR_BC8:
-			pr_info("BlueTooth BT_CoexistType = BT_CSR_BC8\n");
-			break;
-		case BT_RTL8756:
-			pr_info("BlueTooth BT_CoexistType = BT_RTL8756\n");
-			break;
-		default:
-			pr_info("BlueTooth BT_CoexistType = Unknown\n");
-			break;
-		}
-		pr_info("BlueTooth BT_Ant_isolation = %d\n",
-			pbtpriv->BT_Ant_isolation);
-		switch (pbtpriv->BT_Service) {
-		case BT_OtherAction:
-			pr_info("BlueTooth BT_Service = BT_OtherAction\n");
-			break;
-		case BT_SCO:
-			pr_info("BlueTooth BT_Service = BT_SCO\n");
-			break;
-		case BT_Busy:
-			pr_info("BlueTooth BT_Service = BT_Busy\n");
-			break;
-		case BT_OtherBusy:
-			pr_info("BlueTooth BT_Service = BT_OtherBusy\n");
-			break;
-		default:
-			pr_info("BlueTooth BT_Service = BT_Idle\n");
-			break;
-		}
-		pr_info("BT_RadioSharedType = 0x%x\n",
-			pbtpriv->BT_RadioSharedType);
-	}
 }
 
-#define GET_BT_COEXIST(priv) (&priv->bt_coexist)
-
-static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw,
-						u8 *contents,
-						bool bautoloadfailed);
-{
-	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(Adapter);
-	bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID);
-	struct btcoexist_priv	 *pbtpriv = &pHalData->bt_coexist;
-	u8	rf_opt4;
-
-	_rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv));
-	if (AutoloadFail) {
-		pbtpriv->BT_Coexist = _FALSE;
-		pbtpriv->BT_CoexistType = BT_2Wire;
-		pbtpriv->BT_Ant_Num = Ant_x2;
-		pbtpriv->BT_Ant_isolation = 0;
-		pbtpriv->BT_RadioSharedType = BT_Radio_Shared;
-		return;
-	}
-	if (isNormal) {
-		if (pHalData->BoardType == BOARD_USB_COMBO)
-			pbtpriv->BT_Coexist = _TRUE;
-		else
-			pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] &
-					      0x20) >> 5); /* bit[5] */
-		rf_opt4 = PROMContent[EEPROM_RF_OPT4];
-		pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */
-		pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */
-		pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */
-		pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */
-	} else {
-		pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ?
-				       _TRUE : _FALSE;
-	}
-	_update_bt_param(Adapter);
-}
-#endif
-
 static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -494,17 +355,17 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
 		       HWSET_MAX_SIZE);
 	} else if (rtlefuse->epromtype == EEPROM_93C46) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("RTL819X Not boot from eeprom, check it !!"));
+			 "RTL819X Not boot from eeprom, check it !!\n");
 	}
-	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
+	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP",
 		      hwinfo, HWSET_MAX_SIZE);
 	eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0]));
 	if (eeprom_id != RTL8190_EEPROM_ID) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+			 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
 		rtlefuse->autoload_failflag = true;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 		rtlefuse->autoload_failflag = false;
 	}
 	if (rtlefuse->autoload_failflag)
@@ -518,16 +379,15 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
 					   rtlefuse->autoload_failflag, hwinfo);
 	rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]);
 	rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 (" VID = 0x%02x PID = 0x%02x\n",
-		 rtlefuse->eeprom_vid, rtlefuse->eeprom_did));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n",
+		 rtlefuse->eeprom_vid, rtlefuse->eeprom_did);
 	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
 	rtlefuse->eeprom_version =
 			 le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]);
 	rtlefuse->txpwr_fromeprom = true;
 	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n",
+		 rtlefuse->eeprom_oemid);
 	if (rtlhal->oem_id == RT_CID_DEFAULT) {
 		switch (rtlefuse->eeprom_oemid) {
 		case EEPROM_CID_DEFAULT:
@@ -554,10 +414,6 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
 		}
 	}
 	_rtl92cu_read_board_type(hw, hwinfo);
-#ifdef CONFIG_BT_COEXIST
-	_rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo,
-					    rtlefuse->autoload_failflag);
-#endif
 }
 
 static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)
@@ -579,8 +435,8 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)
 	default:
 		break;
 	}
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("RT Customized ID: 0x%02X\n", rtlhal->oem_id));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n",
+		 rtlhal->oem_id);
 }
 
 void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)
@@ -596,11 +452,11 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)
 	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
 	rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ?
 			       EEPROM_93C46 : EEPROM_BOOT_EFUSE;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n",
-		 (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n",
+		 tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE");
 	rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n",
-		 (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n",
+		 tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!");
 	_rtl92cu_read_adapter_info(hw);
 	_rtl92cu_hal_customized_behavior(hw);
 	return;
@@ -618,13 +474,12 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
 	do {
 		if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-				 ("Autoload Done!\n"));
+				 "Autoload Done!\n");
 			break;
 		}
 		if (pollingCount++ > 100) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-				 ("Failed to polling REG_APS_FSMCO[PFM_ALDN]"
-				 " done!\n"));
+				 "Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n");
 			return -ENODEV;
 		}
 	} while (true);
@@ -639,8 +494,8 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
 		value8 |= LDV12_EN;
 		rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8);
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",
-			 value8));
+			 " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n",
+			 value8);
 		udelay(100);
 		value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
 		value8 &= ~ISO_MD2PP;
@@ -658,8 +513,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
 		}
 		if (pollingCount++ > 100) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-				 ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]"
-				 " done!\n"));
+				 "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n");
 			return -ENODEV;
 		}
 	} while (true);
@@ -877,8 +731,8 @@ static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw,
 		hiQ	= QUEUE_HIGH;
 	}
 	_rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-		 ("Tx queue select :0x%02x..\n", queue_sel));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n",
+		 queue_sel);
 }
 
 static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw,
@@ -937,8 +791,8 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw,
 		break;
 	}
 	rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-		 ("Tx queue select :0x%02x..\n", hq_sele));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n",
+		 hq_sele);
 }
 
 static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw,
@@ -998,7 +852,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
 
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			("Failed to init power on!\n"));
+			 "Failed to init power on!\n");
 		return err;
 	}
 	if (!wmm_enable) {
@@ -1010,7 +864,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
 	}
 	if (false == rtl92c_init_llt_table(hw, boundary)) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			("Failed to init LLT Table!\n"));
+			 "Failed to init LLT Table!\n");
 		return -EINVAL;
 	}
 	_rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums,
@@ -1043,12 +897,12 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw)
 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
-		  rtlpriv->sec.pairwise_enc_algorithm,
-		  rtlpriv->sec.group_enc_algorithm));
+		 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+		 rtlpriv->sec.pairwise_enc_algorithm,
+		 rtlpriv->sec.group_enc_algorithm);
 	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-			 ("not open sw encryption\n"));
+			 "not open sw encryption\n");
 		return;
 	}
 	sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
@@ -1059,8 +913,8 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw)
 	if (IS_NORMAL_CHIP(rtlhal->version))
 		sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
 	rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-		 ("The SECR-value %x\n", sec_reg_value));
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n",
+		 sec_reg_value);
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 }
 
@@ -1111,34 +965,6 @@ static void _InitPABias(struct ieee80211_hw *hw)
 	}
 }
 
-static void _InitAntenna_Selection(struct ieee80211_hw *hw)
-{
-#ifdef CONFIG_ANTENNA_DIVERSITY
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	struct rtl_phy *rtlphy = &(rtlpriv->phy);
-
-	if (pHalData->AntDivCfg == 0)
-		return;
-
-	if (rtlphy->rf_type == RF_1T1R) {
-		rtl_write_dword(rtlpriv, REG_LEDCFG0,
-				rtl_read_dword(rtlpriv,
-				REG_LEDCFG0)|BIT(23));
-		rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
-		if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) ==
-		    Antenna_A)
-			pHalData->CurAntenna = Antenna_A;
-		else
-			pHalData->CurAntenna = Antenna_B;
-	}
-#endif
-}
-
-static void _dump_registers(struct ieee80211_hw *hw)
-{
-}
-
 static void _update_mac_setting(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1163,18 +989,15 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
 	rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;
 	err = _rtl92cu_init_mac(hw);
 	if (err) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
 		return err;
 	}
 	err = rtl92c_download_fw(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Failed to download FW. Init HW without FW now..\n"));
+			 "Failed to download FW. Init HW without FW now..\n");
 		err = 1;
-		rtlhal->fw_ready = false;
 		return err;
-	} else {
-		rtlhal->fw_ready = true;
 	}
 	rtlhal->last_hmeboxnum = 0; /* h2c */
 	_rtl92cu_phy_param_tab_init(hw);
@@ -1209,10 +1032,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
 	}
 	_rtl92cu_hw_configure(hw);
 	_InitPABias(hw);
-	_InitAntenna_Selection(hw);
 	_update_mac_setting(hw);
 	rtl92c_dm_init(hw);
-	_dump_registers(hw);
 	return err;
 }
 
@@ -1270,24 +1091,21 @@ static void  _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM)
 		if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) {
 			/* reset MCU ready status */
 			rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
-			if (rtlhal->fw_ready) {
-				/* 8051 reset by self */
-				rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
-				while ((retry_cnts++ < 100) &&
-				       (FEN_CPUEN & rtl_read_word(rtlpriv,
-				       REG_SYS_FUNC_EN))) {
-					udelay(50);
-				}
-				if (retry_cnts >= 100) {
-					RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-						("#####=> 8051 reset failed!.."
-						".......................\n"););
-					/* if 8051 reset fail, reset MAC. */
-					rtl_write_byte(rtlpriv,
-						       REG_SYS_FUNC_EN + 1,
-						       0x50);
-					udelay(100);
-				}
+			/* 8051 reset by self */
+			rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
+			while ((retry_cnts++ < 100) &&
+			       (FEN_CPUEN & rtl_read_word(rtlpriv,
+			       REG_SYS_FUNC_EN))) {
+				udelay(50);
+			}
+			if (retry_cnts >= 100) {
+				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+					 "#####=> 8051 reset failed!.........................\n");
+				/* if 8051 reset fail, reset MAC. */
+				rtl_write_byte(rtlpriv,
+					       REG_SYS_FUNC_EN + 1,
+					       0x50);
+				udelay(100);
 			}
 		}
 		/* Reset MAC and Enable 8051 */
@@ -1495,35 +1313,36 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw,
 		_rtl92cu_resume_tx_beacon(hw);
 		_rtl92cu_disable_bcn_sub_func(hw);
 	} else {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_"
-			 "STATUS:No such media status(%x).\n", type));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+			 "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n",
+			 type);
 	}
 	switch (type) {
 	case NL80211_IFTYPE_UNSPECIFIED:
 		bt_msr |= MSR_NOLINK;
 		ledaction = LED_CTL_LINK;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to NO LINK!\n"));
+			 "Set Network type to NO LINK!\n");
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		bt_msr |= MSR_ADHOC;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to Ad Hoc!\n"));
+			 "Set Network type to Ad Hoc!\n");
 		break;
 	case NL80211_IFTYPE_STATION:
 		bt_msr |= MSR_INFRA;
 		ledaction = LED_CTL_LINK;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to STA!\n"));
+			 "Set Network type to STA!\n");
 		break;
 	case NL80211_IFTYPE_AP:
 		bt_msr |= MSR_AP;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to AP!\n"));
+			 "Set Network type to AP!\n");
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Network type %d not support!\n", type));
+			 "Network type %d not supported!\n", type);
 		goto error_out;
 	}
 	rtl_write_byte(rtlpriv, (MSR), bt_msr);
@@ -1684,8 +1503,8 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw)
 	value32 |= TSFRST;
 	rtl_write_dword(rtlpriv, REG_TCR, value32);
 	RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD,
-		 ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n",
-		 value32));
+		 "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n",
+		 value32);
 	/* TODO: Modify later (Find the right parameters)
 	 * NOTE: Fix test chip's bug (about contention windows's randomness) */
 	if ((mac->opmode == NL80211_IFTYPE_ADHOC) ||
@@ -1702,8 +1521,8 @@ void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw)
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	u16 bcn_interval = mac->beacon_interval;
 
-	RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
-		 ("beacon_interval:%d\n", bcn_interval));
+	RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n",
+		 bcn_interval);
 	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 }
 
@@ -1767,7 +1586,7 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 }
@@ -1827,8 +1646,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
 			rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]);
 			rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]);
-			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("HW_VAR_SIFS\n"));
+			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n");
 			break;
 		}
 	case HW_VAR_SLOT_TIME:{
@@ -1837,7 +1655,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 
 			rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("HW_VAR_SLOT_TIME %x\n", val[0]));
+				 "HW_VAR_SLOT_TIME %x\n", val[0]);
 			if (QOS_MODE) {
 				for (e_aci = 0; e_aci < AC_MAX; e_aci++)
 					rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -1901,8 +1719,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 						     min_spacing_to_set);
 				*val = min_spacing_to_set;
 				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-					("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-					mac->min_space_cfg));
+					 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+					 mac->min_space_cfg);
 				rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 					       mac->min_space_cfg);
 			}
@@ -1916,8 +1734,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			mac->min_space_cfg &= 0x07;
 			mac->min_space_cfg |= (density_to_set << 3);
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-				  mac->min_space_cfg));
+				 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+				 mac->min_space_cfg);
 			rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 				       mac->min_space_cfg);
 			break;
@@ -1950,8 +1768,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 						       p_regtoset[index]);
 				}
 				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-					 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-					  factor_toset));
+					 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+					 factor_toset);
 			}
 			break;
 		}
@@ -1969,8 +1787,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					 AC_PARAM_ECW_MAX_OFFSET);
 			u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET;
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("queue:%x, ac_param:%x\n", e_aci,
-				  u4b_ac_param));
+				 "queue:%x, ac_param:%x\n",
+				 e_aci, u4b_ac_param);
 			switch (e_aci) {
 			case AC1_BK:
 				rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
@@ -1989,8 +1807,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 						u4b_ac_param);
 				break;
 			default:
-				RT_ASSERT(false, ("SetHwReg8185(): invalid"
-					  " aci: %d !\n", e_aci));
+				RT_ASSERT(false,
+					  "SetHwReg8185(): invalid aci: %d !\n",
+					  e_aci);
 				break;
 			}
 			if (rtlusb->acm_method != eAcmWay2_SW)
@@ -2020,8 +1839,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					break;
 				default:
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("HW_VAR_ACM_CTRL acm set "
-						  "failed: eACI is %d\n", acm));
+						 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+						 acm);
 					break;
 				}
 			} else {
@@ -2037,13 +1856,13 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					break;
 				default:
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-						 ("switch case not process\n"));
+						 "switch case not processed\n");
 					break;
 				}
 			}
 			RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-				 ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
-				  "Write 0x%X\n", acm_ctrl));
+				 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+				 acm_ctrl);
 			rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
 			break;
 		}
@@ -2051,7 +1870,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
 			mac->rx_conf = ((u32 *) (val))[0];
 			RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG,
-				 ("### Set RCR(0x%08x) ###\n", mac->rx_conf));
+				 "### Set RCR(0x%08x) ###\n", mac->rx_conf);
 			break;
 		}
 	case HW_VAR_RETRY_LIMIT:{
@@ -2060,8 +1879,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			rtl_write_word(rtlpriv, REG_RL,
 				       retry_limit << RETRY_LIMIT_SHORT_SHIFT |
 				       retry_limit << RETRY_LIMIT_LONG_SHIFT);
-			RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R"
-				 "ETRY_LIMIT(0x%08x)\n", retry_limit));
+			RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG,
+				 "Set HW_VAR_RETRY_LIMIT(0x%08x)\n",
+				 retry_limit);
 			break;
 		}
 	case HW_VAR_DUAL_TSF_RST:
@@ -2165,8 +1985,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val);
 		break;
 	default:
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-							"not process\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "switch case not processed\n");
 		break;
 	}
 }
@@ -2239,8 +2059,8 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
 			       (shortgi_rate << 4) | (shortgi_rate);
 	}
 	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv,
-		 REG_ARFR0)));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+		 rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
@@ -2344,17 +2164,16 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
 			ratr_bitmap &= 0x0f0ff0ff;
 		break;
 	}
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n",
-		 ratr_bitmap));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n",
+		 ratr_bitmap);
 	*(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) |
 				      ratr_index << 28);
 	rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
-						"ratr_val:%x, %x:%x:%x:%x:%x\n",
-						ratr_index, ratr_bitmap,
-						rate_mask[0], rate_mask[1],
-						rate_mask[2], rate_mask[3],
-						rate_mask[4]));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+		 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
+		 ratr_index, ratr_bitmap,
+		 rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3],
+		 rate_mask[4]);
 	rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
 }
 
@@ -2404,7 +2223,7 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
 			e_rfpowerstate_toset = (u1tmp & BIT(7)) ?
 					       ERFOFF : ERFON;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-				 ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp));
+				 "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp);
 		} else {
 			rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG,
 				       rtl_read_byte(rtlpriv,
@@ -2413,27 +2232,26 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
 			e_rfpowerstate_toset  = (u1tmp & BIT(3)) ?
 						 ERFON : ERFOFF;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-				("GPIO_IN=%02x\n", u1tmp));
+				 "GPIO_IN=%02x\n", u1tmp);
 		}
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n",
-			 e_rfpowerstate_toset));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n",
+			 e_rfpowerstate_toset);
 	}
 	if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF  - HW "
-			 "Radio ON, RF ON\n"));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 "GPIOChangeRF  - HW Radio ON, RF ON\n");
 		ppsc->hwradiooff = false;
 		actuallyset = true;
 	} else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset  ==
 		    ERFOFF)) {
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF  - HW"
-			 " Radio OFF\n"));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 "GPIOChangeRF  - HW Radio OFF\n");
 		ppsc->hwradiooff = true;
 		actuallyset = true;
 	} else {
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
-			 ("pHalData->bHwRadioOff and eRfPowerStateToSet do not"
-			 " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet "
-			 "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n",
+			 ppsc->hwradiooff, e_rfpowerstate_toset);
 	}
 	if (actuallyset) {
 		ppsc->hwradiooff = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index 32f85cb..f41a3aa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c
index 2ff9d83..75a2deb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -47,8 +47,8 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 	u8 ledcfg;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 REG_LEDCFG2, pled->ledpin);
 	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 	switch (pled->ledpin) {
 	case LED_PIN_GPIO0:
@@ -62,7 +62,7 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = true;
@@ -74,8 +74,8 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 	struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw);
 	u8 ledcfg;
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 REG_LEDCFG2, pled->ledpin);
 	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 	switch (pled->ledpin) {
 	case LED_PIN_GPIO0:
@@ -95,7 +95,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = false;
@@ -136,7 +136,6 @@ void rtl92cu_led_control(struct ieee80211_hw *hw,
 	     ledaction == LED_CTL_POWER_ON)) {
 		return;
 	}
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
-				ledaction));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction);
 	_rtl92cu_sw_led_control(hw, ledaction);
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h
index decaee4..0f37227 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index 9e0c8fc..025bdc2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,10 +27,6 @@
  *
 ****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../pci.h"
 #include "../usb.h"
@@ -44,6 +40,8 @@
 #include "mac.h"
 #include "trx.h"
 
+#include <linux/module.h>
+
 /* macro to shorten lines */
 
 #define LINK_Q	ui_link_quality
@@ -57,6 +55,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw)
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 	enum version_8192c chip_version = VERSION_UNKNOWN;
+	const char *versionid;
 	u32 value32;
 
 	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
@@ -84,88 +83,69 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw)
 		}
 	}
 	rtlhal->version  = (enum version_8192c)chip_version;
-	pr_info("rtl8192cu: Chip version 0x%x\n", chip_version);
+	pr_info("Chip version 0x%x\n", chip_version);
 	switch (rtlhal->version) {
 	case VERSION_NORMAL_TSMC_CHIP_92C_1T2R:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Chip Version ID: VERSION_B_CHIP_92C.\n"));
+		versionid = "NORMAL_B_CHIP_92C";
 		break;
 	case VERSION_NORMAL_TSMC_CHIP_92C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n"));
+		versionid = "NORMAL_TSMC_CHIP_92C";
 		break;
 	case VERSION_NORMAL_TSMC_CHIP_88C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n"));
+		versionid = "NORMAL_TSMC_CHIP_88C";
 		break;
 	case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i"
-			"92C_1T2R_A_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT";
 		break;
 	case VERSION_NORMAL_UMC_CHIP_92C_A_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_UMC_CHIP_"
-			"92C_A_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_92C_A_CUT";
 		break;
 	case VERSION_NORMAL_UMC_CHIP_88C_A_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-			"_88C_A_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_88C_A_CUT";
 		break;
 	case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-			"_92C_1T2R_B_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT";
 		break;
 	case VERSION_NORMAL_UMC_CHIP_92C_B_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-			"_92C_B_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_92C_B_CUT";
 		break;
 	case VERSION_NORMAL_UMC_CHIP_88C_B_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMAL_UMC_CHIP"
-			"_88C_B_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_88C_B_CUT";
 		break;
 	case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMA_UMC_CHIP"
-			"_8723_1T1R_A_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT";
 		break;
 	case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_NORMA_UMC_CHIP"
-			"_8723_1T1R_B_CUT.\n"));
+		versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT";
 		break;
 	case VERSION_TEST_CHIP_92C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_TEST_CHIP_92C.\n"));
+		versionid = "TEST_CHIP_92C";
 		break;
 	case VERSION_TEST_CHIP_88C:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: VERSION_TEST_CHIP_88C.\n"));
+		versionid = "TEST_CHIP_88C";
 		break;
 	default:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			("Chip Version ID: ???????????????.\n"));
+		versionid = "UNKNOWN";
 		break;
 	}
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+		 "Chip Version ID: %s\n", versionid);
+
 	if (IS_92C_SERIAL(rtlhal->version))
 		rtlphy->rf_type =
 			 (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R;
 	else
 		rtlphy->rf_type = RF_1T1R;
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
-		  "RF_2T2R" : "RF_1T1R"));
+		 "Chip RF Type: %s\n",
+		 rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R");
 	if (get_rf_type(rtlphy) == RF_1T1R)
 		rtlpriv->dm.rfpath_rxenable[0] = true;
 	else
 		rtlpriv->dm.rfpath_rxenable[0] =
 		    rtlpriv->dm.rfpath_rxenable[1] = true;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n",
-						rtlhal->version));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
+		 rtlhal->version);
 }
 
 /**
@@ -192,9 +172,8 @@ bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 			break;
 		if (count > POLLING_LLT_THRESHOLD) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Failed to polling write LLT done at"
-				 " address %d! _LLT_OP_VALUE(%x)\n",
-				 address, _LLT_OP_VALUE(value)));
+				 "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n",
+				 address, _LLT_OP_VALUE(value));
 			status = false;
 			break;
 		}
@@ -272,7 +251,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
 		u8 cam_offset = 0;
 		u8 clear_number = 5;
 
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 		for (idx = 0; idx < clear_number; idx++) {
 			rtl_cam_mark_invalid(hw, cam_offset + idx);
 			rtl_cam_empty_entry(hw, cam_offset + idx);
@@ -298,7 +277,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				("iillegal switch case\n"));
+				 "illegal switch case\n");
 			enc_algo = CAM_TKIP;
 			break;
 		}
@@ -317,26 +296,26 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
 		}
 		if (rtlpriv->sec.key_len[key_index] == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("delete one entry\n"));
+				 "delete one entry\n");
 			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 		} else {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY length is %d\n",
-				  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+				 "The insert KEY length is %d\n",
+				 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY  is %x %x\n",
-				  rtlpriv->sec.key_buf[0][0],
-				  rtlpriv->sec.key_buf[0][1]));
+				 "The insert KEY is %x %x\n",
+				 rtlpriv->sec.key_buf[0][0],
+				 rtlpriv->sec.key_buf[0][1]);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("add one entry\n"));
+				 "add one entry\n");
 			if (is_pairwise) {
 				RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-					      "Pairwiase Key content :",
+					      "Pairwise Key content",
 					      rtlpriv->sec.pairwise_key,
 					      rtlpriv->sec.
 					      key_len[PAIRWISE_KEYIDX]);
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set Pairwiase key\n"));
+					 "set Pairwise key\n");
 
 				rtl_cam_add_one_entry(hw, macaddr, key_index,
 						entry_id, enc_algo,
@@ -345,7 +324,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index,
 						key_buf[key_index]);
 			} else {
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set group key\n"));
+					 "set group key\n");
 				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 					rtl_cam_add_one_entry(hw,
 						rtlefuse->dev_addr,
@@ -421,8 +400,8 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
 	    AC_PARAM_ECW_MAX_OFFSET;
 	u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) <<
 			 AC_PARAM_TXOP_OFFSET;
-	RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD,
-		 ("queue:%x, ac_param:%x\n", aci, u4b_ac_param));
+	RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, "queue:%x, ac_param:%x\n",
+		 aci, u4b_ac_param);
 	switch (aci) {
 	case AC1_BK:
 		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
@@ -437,7 +416,7 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci)
 		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
 		break;
 	default:
-		RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+		RT_ASSERT(false, "invalid aci: %d !\n", aci);
 		break;
 	}
 }
@@ -453,14 +432,14 @@ void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr)
 	for (i = 0 ; i < ETH_ALEN ; i++)
 		rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i));
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-"
-		"%02X-%02X-%02X\n",
-		rtl_read_byte(rtlpriv, REG_MACID),
-		rtl_read_byte(rtlpriv, REG_MACID+1),
-		rtl_read_byte(rtlpriv, REG_MACID+2),
-		rtl_read_byte(rtlpriv, REG_MACID+3),
-		rtl_read_byte(rtlpriv, REG_MACID+4),
-		rtl_read_byte(rtlpriv, REG_MACID+5)));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+		 "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n",
+		 rtl_read_byte(rtlpriv, REG_MACID),
+		 rtl_read_byte(rtlpriv, REG_MACID+1),
+		 rtl_read_byte(rtlpriv, REG_MACID+2),
+		 rtl_read_byte(rtlpriv, REG_MACID+3),
+		 rtl_read_byte(rtlpriv, REG_MACID+4),
+		 rtl_read_byte(rtlpriv, REG_MACID+5));
 }
 
 void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size)
@@ -478,26 +457,26 @@ int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 	case NL80211_IFTYPE_UNSPECIFIED:
 		value = NT_NO_LINK;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			("Set Network type to NO LINK!\n"));
+			 "Set Network type to NO LINK!\n");
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		value = NT_LINK_AD_HOC;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			("Set Network type to Ad Hoc!\n"));
+			 "Set Network type to Ad Hoc!\n");
 		break;
 	case NL80211_IFTYPE_STATION:
 		value = NT_LINK_AP;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			("Set Network type to STA!\n"));
+			 "Set Network type to STA!\n");
 		break;
 	case NL80211_IFTYPE_AP:
 		value = NT_AS_AP;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			("Set Network type to AP!\n"));
+			 "Set Network type to AP!\n");
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			("Network type %d not support!\n", type));
+			 "Network type %d not supported!\n", type);
 		return -EOPNOTSUPP;
 	}
 	rtl_write_byte(rtlpriv, (REG_CR + 2), value);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
index 626d88e..bf53652 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
index e49cf22..34e5630 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -44,9 +44,9 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
 	u32 original_value, readback_value, bitshift;
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-					       "rfpath(%#x), bitmask(%#x)\n",
-					       regaddr, rfpath, bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+		 regaddr, rfpath, bitmask);
 	if (rtlphy->rf_mode != RF_OP_BY_FW) {
 		original_value = _rtl92c_phy_rf_serial_read(hw,
 							    rfpath, regaddr);
@@ -57,9 +57,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
 	bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
 	readback_value = (original_value & bitmask) >> bitshift;
 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-		 ("regaddr(%#x), rfpath(%#x), "
-		  "bitmask(%#x), original_value(%#x)\n",
-		  regaddr, rfpath, bitmask, original_value));
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+		 regaddr, rfpath, bitmask, original_value);
 	return readback_value;
 }
 
@@ -72,8 +71,8 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
 	u32 original_value, bitshift;
 
 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-		 ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
-		  regaddr, bitmask, data, rfpath));
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 	if (rtlphy->rf_mode != RF_OP_BY_FW) {
 		if (bitmask != RFREG_OFFSET_MASK) {
 			original_value = _rtl92c_phy_rf_serial_read(hw,
@@ -97,9 +96,9 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
 		}
 		_rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
 	}
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-					       "bitmask(%#x), data(%#x), rfpath(%#x)\n",
-					       regaddr, bitmask, data, rfpath));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 }
 
 bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw)
@@ -152,11 +151,10 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 	u32 arraylength;
 	u32 *ptrarray;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
 	arraylength =  rtlphy->hwparam_tables[MAC_REG].length ;
 	ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Img:RTL8192CEMAC_2T_ARRAY\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
 	for (i = 0; i < arraylength; i = i + 2)
 		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 	return true;
@@ -202,10 +200,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 				      phy_regarray_table[i + 1]);
 			udelay(1);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("The phy_regarray_table[0] is %x"
-				  " Rtl819XPHY_REGArray[1] is %x\n",
-				  phy_regarray_table[i],
-				  phy_regarray_table[i + 1]));
+				 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+				 phy_regarray_table[i],
+				 phy_regarray_table[i + 1]);
 		}
 	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 		for (i = 0; i < agctab_arraylen; i = i + 2) {
@@ -213,10 +210,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 				      agctab_array_table[i + 1]);
 			udelay(1);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("The agctab_array_table[0] is "
-				  "%x Rtl819XPHY_REGArray[1] is %x\n",
-				  agctab_array_table[i],
-				  agctab_array_table[i + 1]));
+				 "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+				 agctab_array_table[i],
+				 agctab_array_table[i + 1]);
 		}
 	}
 	return true;
@@ -255,7 +251,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 		}
 	} else {
 		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-			 ("configtype != BaseBand_Config_PHY_REG\n"));
+			 "configtype != BaseBand_Config_PHY_REG\n");
 	}
 	return true;
 }
@@ -277,20 +273,20 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 		radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length;
 		radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_A:RTL8192CERADIOA_2TARRAY\n"));
+			 "Radio_A:RTL8192CERADIOA_2TARRAY\n");
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n"));
+			 "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
 	} else {
 		radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length;
 		radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata;
 		radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length;
 		radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n"));
+			 "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n"));
+			 "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
 	}
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
 	switch (rfpath) {
 	case RF90_PATH_A:
 		for (i = 0; i < radioa_arraylen; i = i + 2) {
@@ -338,11 +334,11 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 		break;
 	case RF90_PATH_C:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	case RF90_PATH_D:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	return true;
@@ -357,10 +353,9 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 	u8 reg_bw_opmode;
 	u8 reg_prsr_rsc;
 
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-		 ("Switch to %s bandwidth\n",
-		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-		  "20MHz" : "40MHz"))
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+		 "20MHz" : "40MHz");
 	if (is_hal_stop(rtlhal)) {
 		rtlphy->set_bwmode_inprogress = false;
 		return;
@@ -381,7 +376,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 	switch (rtlphy->current_chan_bw) {
@@ -403,12 +398,12 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 	rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 	rtlphy->set_bwmode_inprogress = false;
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 void rtl92cu_bb_block_on(struct ieee80211_hw *hw)
@@ -480,18 +475,16 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 			do {
 				InitializeCount++;
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-					 ("IPS Set eRf nic enable\n"));
+					 "IPS Set eRf nic enable\n");
 				rtstatus = rtl_ps_enable_nic(hw);
-			} while ((rtstatus != true)
-				 && (InitializeCount < 10));
+			} while (!rtstatus && (InitializeCount < 10));
 			RT_CLEAR_PS_LEVEL(ppsc,
 					  RT_RF_OFF_LEVL_HALT_NIC);
 		} else {
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-				 ("Set ERFON sleeped:%d ms\n",
-				  jiffies_to_msecs(jiffies -
-						   ppsc->
-						   last_sleep_jiffies)));
+				 "Set ERFON sleeped:%d ms\n",
+				 jiffies_to_msecs(jiffies -
+						  ppsc->last_sleep_jiffies));
 			ppsc->last_awake_jiffies = jiffies;
 			rtl92ce_phy_set_rf_on(hw);
 		}
@@ -513,27 +506,25 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 				continue;
 			} else {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("eRf Off/Sleep: %d times "
-					  "TcbBusyQueue[%d] "
-					  "=%d before doze!\n", (i + 1),
-					  queue_id,
-					  skb_queue_len(&ring->queue)));
+					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+					 i + 1,
+					 queue_id,
+					 skb_queue_len(&ring->queue));
 				udelay(10);
 				i++;
 			}
 			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("\nERFOFF: %d times "
-					  "TcbBusyQueue[%d] = %d !\n",
-					  MAX_DOZE_WAITING_TIMES_9x,
-					  queue_id,
-					  skb_queue_len(&ring->queue)));
+					 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
+					 MAX_DOZE_WAITING_TIMES_9x,
+					 queue_id,
+					 skb_queue_len(&ring->queue));
 				break;
 			}
 		}
 		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-				 ("IPS Set eRf nic disable\n"));
+				 "IPS Set eRf nic disable\n");
 			rtl_ps_disable_nic(hw);
 			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 		} else {
@@ -557,33 +548,30 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 				continue;
 			} else {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("eRf Off/Sleep: %d times "
-					  "TcbBusyQueue[%d] =%d before "
-					  "doze!\n", (i + 1), queue_id,
-					  skb_queue_len(&ring->queue)));
+					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+					 i + 1, queue_id,
+					 skb_queue_len(&ring->queue));
 				udelay(10);
 				i++;
 			}
 			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("\n ERFSLEEP: %d times "
-					  "TcbBusyQueue[%d] = %d !\n",
-					  MAX_DOZE_WAITING_TIMES_9x,
-					  queue_id,
-					  skb_queue_len(&ring->queue)));
+					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
+					 MAX_DOZE_WAITING_TIMES_9x,
+					 queue_id,
+					 skb_queue_len(&ring->queue));
 				break;
 			}
 		}
 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("Set ERFSLEEP awaked:%d ms\n",
-			  jiffies_to_msecs(jiffies -
-					   ppsc->last_awake_jiffies)));
+			 "Set ERFSLEEP awaked:%d ms\n",
+			 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
 		ppsc->last_sleep_jiffies = jiffies;
 		_rtl92c_phy_set_rf_sleep(hw);
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		bresult = false;
 		break;
 	}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
index ff81a61..42b0686 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h
index 7f1be61..8b81465 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
index 1e851aa..506b9a0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -56,7 +56,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", bandwidth));
+			 "unknown bandwidth: %#X\n", bandwidth);
 		break;
 	}
 }
@@ -140,26 +140,26 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
 	rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
 
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_A_CCK1_MCS32));
+		"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_A_CCK1_MCS32);
 
 	tmpval = tx_agc[RF90_PATH_A] >> 8;
 	if (mac->mode == WIRELESS_MODE_B)
 		tmpval = tmpval & 0xff00ffff;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_B_CCK11_A_CCK2_11));
+		"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 	tmpval = tx_agc[RF90_PATH_B] >> 24;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_B_CCK11_A_CCK2_11));
+		"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 	tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-		 RTXAGC_B_CCK1_55_MCS32));
+		"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK1_55_MCS32);
 }
 
 static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
@@ -181,8 +181,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
 		    (powerBase0 << 8) | powerBase0;
 		*(ofdmbase + i) = powerBase0;
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			(" [OFDM power base index rf(%c) = 0x%x]\n",
-			 ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+			" [OFDM power base index rf(%c) = 0x%x]\n",
+			i == 0 ? 'A' : 'B', *(ofdmbase + i));
 	}
 	for (i = 0; i < 2; i++) {
 		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
@@ -194,8 +194,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw,
 		    (powerBase1 << 16) | (powerBase1 << 8) | powerBase1;
 		*(mcsbase + i) = powerBase1;
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			(" [MCS power base index rf(%c) = 0x%x]\n",
-			 ((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+			" [MCS power base index rf(%c) = 0x%x]\n",
+			i == 0 ? 'A' : 'B', *(mcsbase + i));
 	}
 }
 
@@ -219,8 +219,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 			    [chnlgroup][index + (rf ? 8 : 0)]
 			    + ((index < 2) ? powerBase0[rf] : powerBase1[rf]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("RTK better performance,writeVal(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeVal));
+				"RTK better performance,writeVal(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		case 1:
 			if (rtlphy->pwrgroup_cnt == 1)
@@ -244,32 +244,31 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 					((index < 2) ? powerBase0[rf] :
 					powerBase1[rf]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Realtek regulatory, 20MHz, "
-				"writeVal(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeVal));
+				"Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		case 2:
 			writeVal = ((index < 2) ? powerBase0[rf] :
 				   powerBase1[rf]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Better regulatory,writeVal(%c) = 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), writeVal));
+				"Better regulatory,writeVal(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		case 3:
 			chnlgroup = 0;
 			if (rtlphy->current_chan_bw ==
 			    HT_CHANNEL_WIDTH_20_40) {
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("customer's limit, 40MHzrf(%c) = "
-					"0x%x\n", ((rf == 0) ? 'A' : 'B'),
+					"customer's limit, 40MHzrf(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B',
 					rtlefuse->pwrgroup_ht40[rf]
-					[channel - 1]));
+					[channel - 1]);
 			} else {
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("customer's limit, 20MHz rf(%c) = "
-					"0x%x\n", ((rf == 0) ? 'A' : 'B'),
+					"customer's limit, 20MHz rf(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B',
 					rtlefuse->pwrgroup_ht20[rf]
-					[channel - 1]));
+					[channel - 1]);
 			}
 			for (i = 0; i < 4; i++) {
 				pwr_diff_limit[i] =
@@ -297,22 +296,22 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 			    (pwr_diff_limit[2] << 16) |
 			    (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Customer's limit rf(%c) = 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), customer_limit));
+				"Customer's limit rf(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', customer_limit);
 			writeVal = customer_limit + ((index < 2) ?
 				   powerBase0[rf] : powerBase1[rf]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Customer, writeVal rf(%c)= 0x%x\n",
-				 ((rf == 0) ? 'A' : 'B'), writeVal));
+				"Customer, writeVal rf(%c)= 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		default:
 			chnlgroup = 0;
 			writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup]
 				   [index + (rf ? 8 : 0)] + ((index < 2) ?
 				   powerBase0[rf] : powerBase1[rf]);
-			RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
-				"performance, writeValrf(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeVal));
+			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+				"RTK better performance, writeValrf(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeVal);
 			break;
 		}
 		if (rtlpriv->dm.dynamic_txhighpower_lvl ==
@@ -365,7 +364,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
 			regoffset = regoffset_b[index];
 		rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal);
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			("Set 0x%x = %08x\n", regoffset, writeVal));
+			"Set 0x%x = %08x\n", regoffset, writeVal);
 		if (((get_rf_type(rtlphy) == RF_2T2R) &&
 		     (regoffset == RTXAGC_A_MCS15_MCS12 ||
 		      regoffset == RTXAGC_B_MCS15_MCS12)) ||
@@ -480,13 +479,13 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
 				      BRFSI_RFENV << 16, u4_regvalue);
 			break;
 		}
-		if (rtstatus != true) {
+		if (!rtstatus) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("Radio[%d] Fail!!", rfpath));
+				 "Radio[%d] Fail!!", rfpath);
 			goto phy_rf_cfg_fail;
 		}
 	}
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
 	return rtstatus;
 phy_rf_cfg_fail:
 	return rtstatus;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
index 500a209..090fd33 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 6d2ca77..82c85286 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -41,7 +41,6 @@
 #include "trx.h"
 #include "led.h"
 #include "hw.h"
-#include <linux/vmalloc.h>
 #include <linux/module.h>
 
 MODULE_AUTHOR("Georgia		<georgia@realtek.com>");
@@ -54,7 +53,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	const struct firmware *firmware;
 	int err;
 
 	rtlpriv->dm.dm_initialgain_enable = true;
@@ -62,29 +60,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->dm.disable_framebursting = false;
 	rtlpriv->dm.thermalvalue = 0;
 	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
-	rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
+
+	/* for firmware buf */
+	rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
 	if (!rtlpriv->rtlhal.pfirmware) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't alloc buffer for fw.\n"));
+			 "Can't alloc buffer for fw\n");
 		return 1;
 	}
-	/* request fw */
-	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-			rtlpriv->io.dev);
-	if (err) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Failed to request firmware!\n"));
-		return 1;
-	}
-	if (firmware->size > 0x4000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
-		return 1;
-	}
-	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-	rtlpriv->rtlhal.fwsize = firmware->size;
-	release_firmware(firmware);
+
+	pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
+	rtlpriv->max_fw_size = 0x4000;
+	err = request_firmware_nowait(THIS_MODULE, 1,
+				      rtlpriv->cfg->fw_name, rtlpriv->io.dev,
+				      GFP_KERNEL, hw, rtl_fw_cb);
+
 
 	return 0;
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
index 43b1177..a1310ab 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
index d57ef5e..966be51 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h
index c3d5cd8..4b020e9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index b3cc7b9..21bc827 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -108,7 +108,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB,
 
 	if (bwificfg) { /* for WMM */
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("USB Chip-B & WMM Setting.....\n"));
+			 "USB Chip-B & WMM Setting.....\n");
 		ep_map->ep_mapping[RTL_TXQ_BE]	= 2;
 		ep_map->ep_mapping[RTL_TXQ_BK]	= 3;
 		ep_map->ep_mapping[RTL_TXQ_VI]	= 3;
@@ -118,7 +118,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB,
 		ep_map->ep_mapping[RTL_TXQ_HI]	= 2;
 	} else { /* typical setting */
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("USB typical Setting.....\n"));
+			 "USB typical Setting.....\n");
 		ep_map->ep_mapping[RTL_TXQ_BE]	= 3;
 		ep_map->ep_mapping[RTL_TXQ_BK]	= 3;
 		ep_map->ep_mapping[RTL_TXQ_VI]	= 2;
@@ -135,7 +135,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool  bwificfg,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	if (bwificfg) { /* for WMM */
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("USB 3EP Setting for WMM.....\n"));
+			 "USB 3EP Setting for WMM.....\n");
 		ep_map->ep_mapping[RTL_TXQ_BE]	= 5;
 		ep_map->ep_mapping[RTL_TXQ_BK]	= 3;
 		ep_map->ep_mapping[RTL_TXQ_VI]	= 3;
@@ -145,7 +145,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool  bwificfg,
 		ep_map->ep_mapping[RTL_TXQ_HI]	= 2;
 	} else { /* typical setting */
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("USB 3EP Setting for typical.....\n"));
+			 "USB 3EP Setting for typical.....\n");
 		ep_map->ep_mapping[RTL_TXQ_BE]	= 5;
 		ep_map->ep_mapping[RTL_TXQ_BK]	= 5;
 		ep_map->ep_mapping[RTL_TXQ_VI]	= 3;
@@ -244,8 +244,8 @@ u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index)
 		break;
 	default:
 		hw_queue_index = RTL_TXQ_BE;
-		RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
-			  mac80211_queue_index));
+		RT_ASSERT(false, "QSLT_BE queue, skb_queue:%d\n",
+			  mac80211_queue_index);
 		break;
 	}
 out:
@@ -270,23 +270,23 @@ static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw,
 	case 0:	/* VO */
 		qsel = QSLT_VO;
 		RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-			 ("VO queue, set qsel = 0x%x\n", QSLT_VO));
+			 "VO queue, set qsel = 0x%x\n", QSLT_VO);
 		break;
 	case 1:	/* VI */
 		qsel = QSLT_VI;
 		RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-			 ("VI queue, set qsel = 0x%x\n", QSLT_VI));
+			 "VI queue, set qsel = 0x%x\n", QSLT_VI);
 		break;
 	case 3:	/* BK */
 		qsel = QSLT_BK;
 		RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-			 ("BK queue, set qsel = 0x%x\n", QSLT_BK));
+			 "BK queue, set qsel = 0x%x\n", QSLT_BK);
 		break;
 	case 2:	/* BE */
 	default:
 		qsel = QSLT_BE;
 		RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG,
-			 ("BE queue, set qsel = 0x%x\n", QSLT_BE));
+			 "BE queue, set qsel = 0x%x\n", QSLT_BE);
 		break;
 	}
 out:
@@ -422,17 +422,17 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
 	bv = ieee80211_is_probe_resp(fc);
 	if (bv)
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("Got probe response frame.\n"));
+			 "Got probe response frame\n");
 	if (ieee80211_is_beacon(fc))
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("Got beacon frame.\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n");
 	if (ieee80211_is_data(fc))
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n");
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:"
-		 "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
-		 (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
-		 (u32)hdr->addr1[5]));
+		 "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n",
+		 fc,
+		 (u32)hdr->addr1[0], (u32)hdr->addr1[1],
+		 (u32)hdr->addr1[2], (u32)hdr->addr1[3],
+		 (u32)hdr->addr1[4], (u32)hdr->addr1[5]);
 	memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
 	ieee80211_rx_irqsafe(hw, skb);
 }
@@ -594,7 +594,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
 	if (ieee80211_is_data_qos(fc)) {
 		if (mac->rdg_en) {
 			RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-				 ("Enable RDG function.\n"));
+				 "Enable RDG function\n");
 			SET_TX_DESC_RDG_ENABLE(txdesc, 1);
 			SET_TX_DESC_HTC(txdesc, 1);
 		}
@@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
 		SET_TX_DESC_BMC(txdesc, 1);
 	_rtl_fill_usb_tx_desc(txdesc);
 	_rtl_tx_desc_checksum(txdesc);
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n");
 }
 
 void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
@@ -677,7 +677,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
 		SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 		SET_TX_DESC_PKT_ID(pdesc, 8);
 	}
-	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n",
+	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content",
 		      pdesc, RTL_TX_DESC_SIZE);
 }
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
index 53de5f6..332b06e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
index 9463047..eafdf76 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index 3cd0736..4737018 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -246,23 +246,21 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
 		rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
 		rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
 	}
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, "
-		 "Cnt_SB_Search_fail = %x\n",
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+		 "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n",
 		 falsealm_cnt->cnt_fast_fsync_fail,
-		 falsealm_cnt->cnt_sb_search_fail));
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, "
-		 "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, "
-		 "Cnt_Mcs_fail = %x\n",
+		 falsealm_cnt->cnt_sb_search_fail);
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+		 "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n",
 		 falsealm_cnt->cnt_parity_fail,
 		 falsealm_cnt->cnt_rate_illegal,
 		 falsealm_cnt->cnt_crc8_fail,
-		 falsealm_cnt->cnt_mcs_fail));
+		 falsealm_cnt->cnt_mcs_fail);
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-		 ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, "
-		 "Cnt_all = %x\n",
+		 "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n",
 		 falsealm_cnt->cnt_ofdm_fail,
 		 falsealm_cnt->cnt_cck_fail,
-		 falsealm_cnt->cnt_all));
+		 falsealm_cnt->cnt_all);
 }
 
 static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
@@ -275,7 +273,7 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
 	    (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
 		de_digtable.min_undecorated_pwdb_for_dm = 0;
 		RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-			 ("Not connected to any\n"));
+			 "Not connected to any\n");
 	}
 	if (mac->link_state >= MAC80211_LINKED) {
 		if (mac->opmode == NL80211_IFTYPE_AP ||
@@ -283,25 +281,25 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw)
 			de_digtable.min_undecorated_pwdb_for_dm =
 			    rtlpriv->dm.UNDEC_SM_PWDB;
 			RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-				 ("AP Client PWDB = 0x%lx\n",
-				  rtlpriv->dm.UNDEC_SM_PWDB));
+				 "AP Client PWDB = 0x%lx\n",
+				 rtlpriv->dm.UNDEC_SM_PWDB);
 		} else {
 			de_digtable.min_undecorated_pwdb_for_dm =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%x\n",
-				  de_digtable.min_undecorated_pwdb_for_dm));
+				 "STA Default Port PWDB = 0x%x\n",
+				 de_digtable.min_undecorated_pwdb_for_dm);
 		}
 	} else {
 		de_digtable.min_undecorated_pwdb_for_dm =
 		    rtlpriv->dm.UNDEC_SM_PWDB;
 		RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
-			 ("AP Ext Port or disconnet PWDB = 0x%x\n",
-			  de_digtable.min_undecorated_pwdb_for_dm));
+			 "AP Ext Port or disconnect PWDB = 0x%x\n",
+			 de_digtable.min_undecorated_pwdb_for_dm);
 	}
 
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n",
-			de_digtable.min_undecorated_pwdb_for_dm));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
+		 de_digtable.min_undecorated_pwdb_for_dm);
 }
 
 static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
@@ -340,14 +338,14 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
 		}
 		de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state;
 	}
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n",
-		 (de_digtable.cursta_connectctate == DIG_STA_CONNECT ?
-		 "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT")));
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n",
-		 (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
-		 "Low RSSI " : "High RSSI ")));
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n",
-		 IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n",
+		 de_digtable.cursta_connectctate == DIG_STA_CONNECT ?
+		 "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT");
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n",
+		 de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ?
+		 "Low RSSI " : "High RSSI ");
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n",
+		 IS_92D_SINGLEPHY(rtlpriv->rtlhal.version));
 
 }
 
@@ -355,12 +353,12 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, "
-		 "pre_igvalue = 0x%x, backoff_val = %d\n",
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
+		 "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n",
 		 de_digtable.cur_igvalue, de_digtable.pre_igvalue,
-		 de_digtable.backoff_val));
+		 de_digtable.backoff_val);
 	if (de_digtable.dig_enable_flag == false) {
-		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n"));
+		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n");
 		de_digtable.pre_igvalue = 0x17;
 		return;
 	}
@@ -377,22 +375,21 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv)
 {
 	if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) &&
 	    (rtlpriv->mac80211.vendor == PEER_CISCO)) {
-		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-			 ("IOT_PEER = CISCO\n"));
+		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n");
 		if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50
 		    && de_digtable.min_undecorated_pwdb_for_dm < 50) {
 			rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00);
 			RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-				 ("Early Mode Off\n"));
+				 "Early Mode Off\n");
 		} else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 &&
 			   de_digtable.min_undecorated_pwdb_for_dm > 55) {
 			rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
 			RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-				 ("Early Mode On\n"));
+				 "Early Mode On\n");
 		}
 	} else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) {
 		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f);
-		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n"));
+		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n");
 	}
 }
 
@@ -402,13 +399,13 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
 	u8 value_igi = de_digtable.cur_igvalue;
 	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
 
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n"));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n");
 	if (rtlpriv->rtlhal.earlymode_enable) {
 		rtl92d_early_mode_enabled(rtlpriv);
 		de_digtable.last_min_undecorated_pwdb_for_dm =
 				 de_digtable.min_undecorated_pwdb_for_dm;
 	}
-	if (rtlpriv->dm.dm_initialgain_enable == false)
+	if (!rtlpriv->dm.dm_initialgain_enable)
 		return;
 
 	/* because we will send data pkt when scanning
@@ -421,7 +418,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
 	/* Not STA mode return tmp */
 	if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
 		return;
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n"));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n");
 	/* Decide the current status and if modify initial gain or not */
 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
 		de_digtable.cursta_connectctate = DIG_STA_CONNECT;
@@ -438,16 +435,16 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
 	else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2)
 		value_igi += 2;
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-		 ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
-		 de_digtable.large_fa_hit, de_digtable.forbidden_igi));
+		 "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n",
+		 de_digtable.large_fa_hit, de_digtable.forbidden_igi);
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-		 ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n",
-		 de_digtable.recover_cnt, de_digtable.rx_gain_range_min));
+		 "dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n",
+		 de_digtable.recover_cnt, de_digtable.rx_gain_range_min);
 
 	/* deal with abnorally large false alarm */
 	if (falsealm_cnt->cnt_all > 10000) {
 		RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-			 ("dm_DIG(): Abnornally false alarm case.\n"));
+			 "dm_DIG(): Abnormally false alarm case\n");
 
 		de_digtable.large_fa_hit++;
 		if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) {
@@ -486,11 +483,11 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
 		}
 	}
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-		 ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
-		  de_digtable.large_fa_hit, de_digtable.forbidden_igi));
+		 "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n",
+		 de_digtable.large_fa_hit, de_digtable.forbidden_igi);
 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
-		 ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n",
-		  de_digtable.recover_cnt, de_digtable.rx_gain_range_min));
+		 "dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n",
+		 de_digtable.recover_cnt, de_digtable.rx_gain_range_min);
 
 	if (value_igi > DM_DIG_MAX)
 		value_igi = DM_DIG_MAX;
@@ -500,7 +497,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw)
 	rtl92d_dm_write_dig(hw);
 	if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G)
 		rtl92d_dm_cck_packet_detection_thresh(hw);
-	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n"));
+	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n");
 }
 
 static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
@@ -528,7 +525,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
 	if ((mac->link_state < MAC80211_LINKED) &&
 	    (rtlpriv->dm.UNDEC_SM_PWDB == 0)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Not connected to any\n"));
+			 "Not connected to any\n");
 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
 		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
 		return;
@@ -538,40 +535,40 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.UNDEC_SM_PWDB;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("IBSS Client PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "IBSS Client PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		} else {
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "STA Default Port PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		}
 	} else {
 		undecorated_smoothed_pwdb =
 		    rtlpriv->dm.UNDEC_SM_PWDB;
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("AP Ext Port PWDB = 0x%lx\n",
-			  undecorated_smoothed_pwdb));
+			 "AP Ext Port PWDB = 0x%lx\n",
+			 undecorated_smoothed_pwdb);
 	}
 	if (rtlhal->current_bandtype == BAND_ON_5G) {
 		if (undecorated_smoothed_pwdb >= 0x33) {
 			rtlpriv->dm.dynamic_txhighpower_lvl =
 						 TXHIGHPWRLEVEL_LEVEL2;
 			RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
-				 ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"));
+				 "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n");
 		} else if ((undecorated_smoothed_pwdb < 0x33)
 			   && (undecorated_smoothed_pwdb >= 0x2b)) {
 			rtlpriv->dm.dynamic_txhighpower_lvl =
 						 TXHIGHPWRLEVEL_LEVEL1;
 			RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
-				 ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"));
+				 "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n");
 		} else if (undecorated_smoothed_pwdb < 0x2b) {
 			rtlpriv->dm.dynamic_txhighpower_lvl =
 						 TXHIGHPWRLEVEL_NORMAL;
 			RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD,
-				 ("5G:TxHighPwrLevel_Normal\n"));
+				 "5G:TxHighPwrLevel_Normal\n");
 		}
 	} else {
 		if (undecorated_smoothed_pwdb >=
@@ -579,7 +576,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			rtlpriv->dm.dynamic_txhighpower_lvl =
 						 TXHIGHPWRLEVEL_LEVEL2;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+				 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
 		} else
 		    if ((undecorated_smoothed_pwdb <
 			 (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3))
@@ -589,19 +586,19 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			rtlpriv->dm.dynamic_txhighpower_lvl =
 						 TXHIGHPWRLEVEL_LEVEL1;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+				 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
 		} else if (undecorated_smoothed_pwdb <
 			   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
 			rtlpriv->dm.dynamic_txhighpower_lvl =
 						 TXHIGHPWRLEVEL_NORMAL;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("TXHIGHPWRLEVEL_NORMAL\n"));
+				 "TXHIGHPWRLEVEL_NORMAL\n");
 		}
 	}
 	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
-			  rtlphy->current_channel));
+			 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
+			 rtlphy->current_channel);
 		rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
 	}
 	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
@@ -717,7 +714,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw)
 	u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter -
 				rtlpriv->dm.thermalvalue_rxgain)]) << 12;
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("===> Rx Gain %x\n", u4tmp));
+		 "===> Rx Gain %x\n", u4tmp);
 	for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++)
 		rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK,
 			      (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp);
@@ -741,27 +738,22 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg,
 			if (!memcmp((void *)&temp_cck,
 			    (void *)&cckswing_table_ch14[i][2], 4)) {
 				*cck_index_old = (u8) i;
-				RT_TRACE(rtlpriv,
-					 COMP_POWER_TRACKING,
-					 DBG_LOUD,
-					 ("Initial reg0x%x = 0x%lx, "
-					  "cck_index=0x%x, ch 14 %d\n",
-					  RCCK0_TXFILTER2,
-					  temp_cck, *cck_index_old,
-					  rtlpriv->dm.cck_inch14));
+				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+					 "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n",
+					 RCCK0_TXFILTER2, temp_cck,
+					 *cck_index_old,
+					 rtlpriv->dm.cck_inch14);
 				break;
 			}
 		} else {
 			if (!memcmp((void *) &temp_cck,
 			    &cckswing_table_ch1ch13[i][2], 4)) {
 				*cck_index_old = (u8) i;
-				RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
-					 DBG_LOUD,
-					 ("Initial reg0x%x = 0x%lx, "
-					 "cck_index = 0x%x, ch14 %d\n",
-					 RCCK0_TXFILTER2,
-					 temp_cck, *cck_index_old,
-					 rtlpriv->dm.cck_inch14));
+				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+					 "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n",
+					 RCCK0_TXFILTER2, temp_cck,
+					 *cck_index_old,
+					 rtlpriv->dm.cck_inch14);
 				break;
 			}
 		}
@@ -884,12 +876,12 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 	};
 
 	rtlpriv->dm.txpower_trackinginit = true;
-	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n"));
+	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n");
 	thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800);
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-		 "eeprom_thermalmeter 0x%x\n", thermalvalue,
-		 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+		 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
+		 thermalvalue,
+		 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
 	rtl92d_phy_ap_calibrate(hw, (thermalvalue -
 				     rtlefuse->eeprom_thermalmeter));
 	if (is2t)
@@ -904,10 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 				ofdm_index_old[0] = (u8) i;
 
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("Initial pathA ele_d reg0x%x = 0x%lx,"
-					 " ofdm_index=0x%x\n",
+					 "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n",
 					 ROFDM0_XATxIQIMBALANCE,
-					 ele_d, ofdm_index_old[0]));
+					 ele_d, ofdm_index_old[0]);
 				break;
 			}
 		}
@@ -920,11 +911,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 					ofdm_index_old[1] = (u8) i;
 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
 						 DBG_LOUD,
-						 ("Initial pathB ele_d reg "
-						 "0x%x = 0x%lx, ofdm_index "
-						 "= 0x%x\n",
+						 "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n",
 						 ROFDM0_XBTxIQIMBALANCE, ele_d,
-						 ofdm_index_old[1]));
+						 ofdm_index_old[1]);
 					break;
 				}
 			}
@@ -952,7 +941,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 				rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
 			rtlpriv->dm.cck_index = cck_index_old;
 			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-				 ("reload ofdm index for band switch\n"));
+				 "reload ofdm index for band switch\n");
 		}
 		rtlpriv->dm.thermalvalue_avg
 			    [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue;
@@ -995,12 +984,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 			(thermalvalue - rtlpriv->dm.thermalvalue_rxgain) :
 			(rtlpriv->dm.thermalvalue_rxgain - thermalvalue);
 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-			 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x"
-			  " eeprom_thermalmeter 0x%x delta 0x%x "
-			  "delta_lck 0x%x delta_iqk 0x%x\n",
-			  thermalvalue, rtlpriv->dm.thermalvalue,
-			  rtlefuse->eeprom_thermalmeter, delta, delta_lck,
-			  delta_iqk));
+			 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
+			 thermalvalue, rtlpriv->dm.thermalvalue,
+			 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
+			 delta_iqk);
 		if ((delta_lck > rtlefuse->delta_lck) &&
 		    (rtlefuse->delta_lck != 0)) {
 			rtlpriv->dm.thermalvalue_lck = thermalvalue;
@@ -1036,17 +1023,15 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 			}
 			if (is2t) {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("temp OFDM_A_index=0x%x, OFDM_B_index"
-					 " = 0x%x,cck_index=0x%x\n",
-					  rtlpriv->dm.ofdm_index[0],
-					  rtlpriv->dm.ofdm_index[1],
-					  rtlpriv->dm.cck_index));
+					 "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x,cck_index=0x%x\n",
+					 rtlpriv->dm.ofdm_index[0],
+					 rtlpriv->dm.ofdm_index[1],
+					 rtlpriv->dm.cck_index);
 			} else {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("temp OFDM_A_index=0x%x,cck_index = "
-					 "0x%x\n",
-					  rtlpriv->dm.ofdm_index[0],
-							rtlpriv->dm.cck_index));
+					 "temp OFDM_A_index=0x%x,cck_index = 0x%x\n",
+					 rtlpriv->dm.ofdm_index[0],
+					 rtlpriv->dm.cck_index);
 			}
 			for (i = 0; i < rf; i++) {
 				if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1)
@@ -1070,15 +1055,13 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 			}
 			if (is2t) {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("new OFDM_A_index=0x%x, OFDM_B_index "
-					 "= 0x%x, cck_index=0x%x\n",
+					 "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n",
 					 ofdm_index[0], ofdm_index[1],
-					 cck_index));
+					 cck_index);
 			} else {
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("new OFDM_A_index=0x%x,cck_index = "
-					 "0x%x\n",
-					  ofdm_index[0], cck_index));
+					 "new OFDM_A_index=0x%x,cck_index = 0x%x\n",
+					 ofdm_index[0], cck_index);
 			}
 			ele_d = (ofdmswing_table[(u8) ofdm_index[0]] &
 						 0xFFC00000) >> 22;
@@ -1124,12 +1107,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 			}
 
 			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-				 ("TxPwrTracking for interface %d path A: X ="
-				 " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = "
-				 "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = "
-				 "0x%lx\n", rtlhal->interfaceindex,
+				 "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n",
+				 rtlhal->interfaceindex,
 				 val_x, val_y, ele_a, ele_c, ele_d,
-				 val_x, val_y));
+				 val_x, val_y);
 
 			if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 				/* Adjust CCK according to IQK result */
@@ -1232,20 +1213,16 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 						      BIT(28), 0x00);
 				}
 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-					 ("TxPwrTracking path B: X = 0x%lx, "
-					 "Y = 0x%lx ele_A = 0x%lx ele_C = 0x"
-					 "%lx ele_D = 0x%lx 0xeb4 = 0x%lx "
-					 "0xebc = 0x%lx\n",
-					  val_x, val_y, ele_a, ele_c,
-					  ele_d, val_x, val_y));
+					 "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n",
+					 val_x, val_y, ele_a, ele_c,
+					 ele_d, val_x, val_y);
 			}
 			RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-				 ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = "
-				 "0x%x RF 0x24 = 0x%x\n",
+				 "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n",
 				 rtl_get_bbreg(hw, 0xc80, BMASKDWORD),
 				 rtl_get_bbreg(hw, 0xc94, BMASKDWORD),
 				 rtl_get_rfreg(hw, RF90_PATH_A, 0x24,
-				 BRFREGOFFSETMASK)));
+					       BRFREGOFFSETMASK));
 		}
 		if ((delta_iqk > rtlefuse->delta_iqk) &&
 		    (rtlefuse->delta_iqk != 0)) {
@@ -1262,7 +1239,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter(
 			rtlpriv->dm.thermalvalue = thermalvalue;
 	}
 
-	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
+	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n");
 }
 
 static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
@@ -1273,8 +1250,8 @@ static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
 	rtlpriv->dm.txpower_trackinginit = false;
 	rtlpriv->dm.txpower_track_control = true;
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("pMgntInfo->txpower_tracking = %d\n",
-		 rtlpriv->dm.txpower_tracking));
+		 "pMgntInfo->txpower_tracking = %d\n",
+		 rtlpriv->dm.txpower_tracking);
 }
 
 void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
@@ -1289,12 +1266,12 @@ void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw)
 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) |
 			      BIT(16), 0x03);
 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-			 ("Trigger 92S Thermal Meter!!\n"));
+			 "Trigger 92S Thermal Meter!!\n");
 		tm_trigger = 1;
 		return;
 	} else {
 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-			 ("Schedule TxPowerTracking direct call!!\n"));
+			 "Schedule TxPowerTracking direct call!!\n");
 		rtl92d_dm_txpower_tracking_callback_thermalmeter(hw);
 		tm_trigger = 0;
 	}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
index 6935465..91030ec 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
index 82f060b..f548a8d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -124,14 +124,14 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw,
 	u32 pagenums, remainSize;
 	u32 page, offset;
 
-	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size));
+	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size);
 	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE)
 		_rtl92d_fill_dummy(bufferPtr, &size);
 	pagenums = size / FW_8192D_PAGE_SIZE;
 	remainSize = size % FW_8192D_PAGE_SIZE;
 	if (pagenums > 8) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Page numbers should not greater then 8\n"));
+			 "Page numbers should not greater then 8\n");
 	}
 	for (page = 0; page < pagenums; page++) {
 		offset = page * FW_8192D_PAGE_SIZE;
@@ -158,12 +158,12 @@ static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw)
 		 (!(value32 & FWDL_ChkSum_rpt)));
 	if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
-			 value32));
+			 "chksum report faill ! REG_MCUFWDL:0x%08x\n",
+			 value32);
 		return -EIO;
 	}
 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-		 ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32));
+		 "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32);
 	value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL);
 	value32 |= MCUFWDL_RDY;
 	rtl_write_dword(rtlpriv, REG_MCUFWDL, value32);
@@ -186,9 +186,9 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw)
 		udelay(50);
 		u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
 	}
-	RT_ASSERT((delay > 0), ("8051 reset failed!\n"));
+	RT_ASSERT((delay > 0), "8051 reset failed!\n");
 	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-		 ("=====> 8051 reset success (%d) .\n", delay));
+		 "=====> 8051 reset success (%d)\n", delay);
 }
 
 static int _rtl92d_fw_init(struct ieee80211_hw *hw)
@@ -197,7 +197,7 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u32 counter;
 
-	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n"));
+	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n");
 	/* polling for FW ready */
 	counter = 0;
 	do {
@@ -205,10 +205,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
 			if (rtl_read_byte(rtlpriv, FW_MAC0_READY) &
 			    MAC0_READY) {
 				RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-					 ("Polling FW ready success!! "
-					 "REG_MCUFWDL: 0x%x .\n",
+					 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
 					 rtl_read_byte(rtlpriv,
-					 FW_MAC0_READY)));
+						       FW_MAC0_READY));
 				return 0;
 			}
 			udelay(5);
@@ -216,10 +215,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
 			if (rtl_read_byte(rtlpriv, FW_MAC1_READY) &
 			    MAC1_READY) {
 				RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-					 ("Polling FW ready success!! "
-					 "REG_MCUFWDL: 0x%x .\n",
+					 "Polling FW ready success!! REG_MCUFWDL: 0x%x\n",
 					 rtl_read_byte(rtlpriv,
-						       FW_MAC1_READY)));
+						       FW_MAC1_READY));
 				return 0;
 			}
 			udelay(5);
@@ -228,18 +226,16 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw)
 
 	if (rtlhal->interfaceindex == 0) {
 		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-			 ("Polling FW ready fail!! MAC0 FW init not ready: "
-			 "0x%x .\n",
-			 rtl_read_byte(rtlpriv, FW_MAC0_READY)));
+			 "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n",
+			 rtl_read_byte(rtlpriv, FW_MAC0_READY));
 	} else {
 		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-			 ("Polling FW ready fail!! MAC1 FW init not ready: "
-			 "0x%x .\n",
-			 rtl_read_byte(rtlpriv, FW_MAC1_READY)));
+			 "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n",
+			 rtl_read_byte(rtlpriv, FW_MAC1_READY));
 	}
 	RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-		 ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n",
-		 rtl_read_dword(rtlpriv, REG_MCUFWDL)));
+		 "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n",
+		 rtl_read_dword(rtlpriv, REG_MCUFWDL));
 	return -1;
 }
 
@@ -257,20 +253,20 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
 	bool fw_downloaded = false, fwdl_in_process = false;
 	unsigned long flags;
 
-	if (!rtlhal->pfirmware)
+	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
 		return 1;
 	fwsize = rtlhal->fwsize;
 	pfwheader = (u8 *) rtlhal->pfirmware;
 	pfwdata = (u8 *) rtlhal->pfirmware;
 	rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader);
 	rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d),"
-		 "FirmwareSubVersion(%d), Signature(%#x)\n",
-		 rtlhal->fw_version,	rtlhal->fw_subversion,
-		 GET_FIRMWARE_HDR_SIGNATURE(pfwheader)));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n",
+		 rtlhal->fw_version, rtlhal->fw_subversion,
+		 GET_FIRMWARE_HDR_SIGNATURE(pfwheader));
 	if (IS_FW_HEADER_EXIST(pfwheader)) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("Shift 32 bytes for FW header!!\n"));
+			 "Shift 32 bytes for FW header!!\n");
 		pfwdata = pfwdata + 32;
 		fwsize = fwsize - 32;
 	}
@@ -302,8 +298,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
 				break;
 			else
 				RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
-					 ("Wait for another mac "
-					 "download fw\n"));
+					 "Wait for another mac download fw\n");
 		}
 		spin_lock_irqsave(&globalmutex_for_fwdownload, flags);
 		value = rtl_read_byte(rtlpriv, 0x1f);
@@ -337,11 +332,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw)
 	spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("fw is not ready to run!\n"));
+			 "fw is not ready to run!\n");
 		goto exit;
 	} else {
-		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
-			 ("fw is ready to run!\n"));
+		RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n");
 	}
 exit:
 	err = _rtl92d_fw_init(hw);
@@ -381,24 +375,24 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 
 	if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) {
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			 ("Return as RF is off!!!\n"));
+			 "Return as RF is off!!!\n");
 		return;
 	}
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n");
 	while (true) {
 		spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 		if (rtlhal->h2c_setinprogress) {
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("H2C set in progress! Wait to set.."
-				 "element_id(%d).\n", element_id));
+				 "H2C set in progress! Wait to set..element_id(%d)\n",
+				 element_id);
 
 			while (rtlhal->h2c_setinprogress) {
 				spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock,
 						       flag);
 				h2c_waitcounter++;
 				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-					 ("Wait 100 us (%d times)...\n",
-					 h2c_waitcounter));
+					 "Wait 100 us (%d times)...\n",
+					 h2c_waitcounter);
 				udelay(100);
 
 				if (h2c_waitcounter > 1000)
@@ -418,8 +412,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 		wait_writeh2c_limmit--;
 		if (wait_writeh2c_limmit == 0) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Write H2C fail because no trigger "
-				 "for FW INT!\n"));
+				 "Write H2C fail because no trigger for FW INT!\n");
 			break;
 		}
 		boxnum = rtlhal->last_hmeboxnum;
@@ -442,7 +435,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 		isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
@@ -450,29 +443,29 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 			wait_h2c_limmit--;
 			if (wait_h2c_limmit == 0) {
 				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-					 ("Wating too long for FW read "
-					 "clear HMEBox(%d)!\n", boxnum));
+					 "Waiting too long for FW read clear HMEBox(%d)!\n",
+					 boxnum);
 				break;
 			}
 			udelay(10);
 			isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum);
 			u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF);
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Wating for FW read clear HMEBox(%d)!!! "
-				 "0x1BF = %2x\n", boxnum, u1b_tmp));
+				 "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n",
+				 boxnum, u1b_tmp);
 		}
 		if (!isfw_read) {
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Write H2C register BOX[%d] fail!!!!! "
-				 "Fw do not read.\n", boxnum));
+				 "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n",
+				 boxnum);
 			break;
 		}
 		memset(boxcontent, 0, sizeof(boxcontent));
 		memset(boxextcontent, 0, sizeof(boxextcontent));
 		boxcontent[0] = element_id;
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			 ("Write element_id box_reg(%4x) = %2x\n",
-			 box_reg, element_id));
+			 "Write element_id box_reg(%4x) = %2x\n",
+			 box_reg, element_id);
 		switch (cmd_len) {
 		case 1:
 			boxcontent[0] &= ~(BIT(7));
@@ -519,7 +512,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 		bwrite_sucess = true;
@@ -527,26 +520,20 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw,
 		if (rtlhal->last_hmeboxnum == 4)
 			rtlhal->last_hmeboxnum = 0;
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			 ("pHalData->last_hmeboxnum  = %d\n",
-			  rtlhal->last_hmeboxnum));
+			 "pHalData->last_hmeboxnum  = %d\n",
+			 rtlhal->last_hmeboxnum);
 	}
 	spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag);
 	rtlhal->h2c_setinprogress = false;
 	spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag);
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n");
 }
 
 void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
 			 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
 {
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u32 tmp_cmdbuf[2];
 
-	if (rtlhal->fw_ready == false) {
-		RT_ASSERT(false, ("return H2C cmd because of Fw "
-				  "download fail!!!\n"));
-		return;
-	}
 	memset(tmp_cmdbuf, 0, 8);
 	memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
 	_rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
@@ -559,13 +546,13 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
 	u8 u1_h2c_set_pwrmode[3] = { 0 };
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
-	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode));
+	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
 	SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
 	SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
 	SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
 					      ppsc->reg_max_lps_awakeintvl);
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-		      "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n",
+		      "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
 		      u1_h2c_set_pwrmode, 3);
 	rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
 }
@@ -757,28 +744,32 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
 	totalpacketlen = TOTAL_RESERVED_PKT_LEN;
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
 		      &reserved_page_packet[0], totalpacketlen);
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+		      "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL",
 		      u1RsvdPageLoc, 3);
 	skb = dev_alloc_skb(totalpacketlen);
-	memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet,
-		totalpacketlen);
-	rtstatus = _rtl92d_cmd_send_packet(hw, skb);
+	if (!skb) {
+		dlok = false;
+	} else {
+		memcpy((u8 *) skb_put(skb, totalpacketlen),
+			&reserved_page_packet, totalpacketlen);
+		rtstatus = _rtl92d_cmd_send_packet(hw, skb);
 
-	if (rtstatus)
-		dlok = true;
+		if (rtstatus)
+			dlok = true;
+	}
 	if (dlok) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			("Set RSVD page location to Fw.\n"));
+			 "Set RSVD page location to Fw\n");
 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
-			      "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3);
+			      "H2C_RSVDPAGE", u1RsvdPageLoc, 3);
 		rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE,
 			sizeof(u1RsvdPageLoc), u1RsvdPageLoc);
 	} else
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			("Set RSVD page location to Fw FAIL!!!!!!.\n"));
+			 "Set RSVD page location to Fw FAIL!!!!!!\n");
 }
 
 void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
index 0c4d489..1ffacdd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 9d89d7c..509f5af 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -166,7 +166,7 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 }
@@ -230,7 +230,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		u8 e_aci;
 
 		RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-			 ("HW_VAR_SLOT_TIME %x\n", val[0]));
+			 "HW_VAR_SLOT_TIME %x\n", val[0]);
 		rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
 		for (e_aci = 0; e_aci < AC_MAX; e_aci++)
 			rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -261,8 +261,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					      min_spacing_to_set);
 			*val = min_spacing_to_set;
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-				 mac->min_space_cfg));
+				 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+				 mac->min_space_cfg);
 			rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 				       mac->min_space_cfg);
 		}
@@ -275,8 +275,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
 		mac->min_space_cfg |= (density_to_set << 3);
 		RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-			 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-			 mac->min_space_cfg));
+			 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+			 mac->min_space_cfg);
 		rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
 			       mac->min_space_cfg);
 		break;
@@ -310,8 +310,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			}
 			rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet);
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-				 factor_toset));
+				 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+				 factor_toset);
 		}
 		break;
 	}
@@ -344,8 +344,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 				break;
 			default:
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("HW_VAR_ACM_CTRL acm set "
-					 "failed: eACI is %d\n", acm));
+					 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+					 acm);
 				break;
 			}
 		} else {
@@ -361,13 +361,13 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 				break;
 			default:
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-					 ("switch case not process\n"));
+					 "switch case not processed\n");
 				break;
 			}
 		}
 		RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-			 ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
-			 "Write 0x%X\n", acm_ctrl));
+			 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
+			 acm_ctrl);
 		rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
 		break;
 	}
@@ -502,7 +502,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 	}
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 }
@@ -522,8 +522,8 @@ static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
 			break;
 		if (count > POLLING_LLT_THRESHOLD) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Failed to polling write LLT done at "
-				  "address %d!\n", address));
+				 "Failed to polling write LLT done at address %d!\n",
+				 address);
 			status = false;
 			break;
 		}
@@ -707,7 +707,7 @@ static bool _rtl92de_init_mac(struct ieee80211_hw *hw)
 
 	/* System init */
 	/* 18.  LLT_table_init(Adapter);  */
-	if (_rtl92de_llt_table_init(hw) == false)
+	if (!_rtl92de_llt_table_init(hw))
 		return false;
 
 	/* Clear interrupt and enable interrupt */
@@ -879,12 +879,12 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw)
 	u8 sec_reg_value;
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
-		  rtlpriv->sec.pairwise_enc_algorithm,
-		  rtlpriv->sec.group_enc_algorithm));
+		 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
+		 rtlpriv->sec.pairwise_enc_algorithm,
+		 rtlpriv->sec.group_enc_algorithm);
 	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-			 ("not open hw encryption\n"));
+			 "not open hw encryption\n");
 		return;
 	}
 	sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
@@ -895,7 +895,7 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw)
 	sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
 	rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
 	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-		 ("The SECR-value %x\n", sec_reg_value));
+		 "The SECR-value %x\n", sec_reg_value);
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 }
 
@@ -920,8 +920,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
 	rtl92d_phy_reset_iqk_result(hw);
 	/* rtlpriv->intf_ops->disable_aspm(hw); */
 	rtstatus = _rtl92de_init_mac(hw);
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
 		err = 1;
 		spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
 		return err;
@@ -930,12 +930,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
 	spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Failed to download FW. Init HW "
-			 "without FW..\n"));
-		rtlhal->fw_ready = false;
+			 "Failed to download FW. Init HW without FW..\n");
 		return 1;
-	} else {
-		rtlhal->fw_ready = true;
 	}
 	rtlhal->last_hmeboxnum = 0;
 	rtlpriv->psc.fw_current_inpsmode = false;
@@ -946,7 +942,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw)
 
 	if (rtlhal->earlymode_enable) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("EarlyMode Enabled!!!\n"));
+			 "EarlyMode Enabled!!!\n");
 
 		tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0);
 		tmp_u1b = tmp_u1b | 0x1f;
@@ -1064,10 +1060,10 @@ static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw)
 	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
 	if (!(value32 & 0x000f0000)) {
 		version = VERSION_TEST_CHIP_92D_SINGLEPHY;
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n");
 	} else {
 		version = VERSION_NORMAL_CHIP_92D_SINGLEPHY;
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n");
 	}
 	return version;
 }
@@ -1092,8 +1088,8 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
 		_rtl92de_disable_bcn_sub_func(hw);
 	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Set HW_VAR_MEDIA_STATUS: No such media "
-			 "status(%x).\n", type));
+			 "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
+			 type);
 	}
 	bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL);
 	switch (type) {
@@ -1102,30 +1098,30 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
 		ledaction = LED_CTL_LINK;
 		bcnfunc_enable &= 0xF7;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to NO LINK!\n"));
+			 "Set Network type to NO LINK!\n");
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		bt_msr |= MSR_ADHOC;
 		bcnfunc_enable |= 0x08;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to Ad Hoc!\n"));
+			 "Set Network type to Ad Hoc!\n");
 		break;
 	case NL80211_IFTYPE_STATION:
 		bt_msr |= MSR_INFRA;
 		ledaction = LED_CTL_LINK;
 		bcnfunc_enable &= 0xF7;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to STA!\n"));
+			 "Set Network type to STA!\n");
 		break;
 	case NL80211_IFTYPE_AP:
 		bt_msr |= MSR_AP;
 		bcnfunc_enable |= 0x08;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to AP!\n"));
+			 "Set Network type to AP!\n");
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Network type %d not support!\n", type));
+			 "Network type %d not supported!\n", type);
 		return 1;
 		break;
 
@@ -1151,7 +1147,7 @@ void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
 		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
 		_rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4));
-	} else if (check_bssid == false) {
+	} else if (!check_bssid) {
 		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
 		_rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0);
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
@@ -1189,7 +1185,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw)
 	indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
 	if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) {
 		RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG,
-				("Do IQK for channel:%d.\n", channel));
+			 "Do IQK for channel:%d\n", channel);
 		rtl92d_phy_iq_calibrate(hw);
 	}
 }
@@ -1214,7 +1210,7 @@ void rtl92de_set_qos(struct ieee80211_hw *hw, int aci)
 		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
 		break;
 	default:
-		RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+		RT_ASSERT(false, "invalid aci: %d !\n", aci);
 		break;
 	}
 }
@@ -1305,8 +1301,8 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
 	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL,
-		  rtl_read_byte(rtlpriv, REG_SPS0_CTRL)));
+		 "In PowerOff,reg0x%x=%X\n",
+		 REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL));
 	/* r.   Note: for PCIe interface, PON will not turn */
 	/* off m-bias and BandGap in PCIe suspend mode.  */
 
@@ -1319,7 +1315,7 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw)
 		spin_unlock_irqrestore(&globalmutex_power, flags);
 	}
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n");
 }
 
 void rtl92de_card_disable(struct ieee80211_hw *hw)
@@ -1377,7 +1373,7 @@ void rtl92de_card_disable(struct ieee80211_hw *hw)
 	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff);
 	udelay(50);
 	rtl_write_byte(rtlpriv, REG_CR, 0x0);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n");
 	if (rtl92d_phy_check_poweroff(hw))
 		_rtl92de_poweroff_adapter(hw);
 	return;
@@ -1425,7 +1421,7 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw)
 	u16 bcn_interval = mac->beacon_interval;
 
 	RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
-		 ("beacon_interval:%d\n", bcn_interval));
+		 "beacon_interval:%d\n", bcn_interval);
 	/* rtl92de_disable_interrupt(hw); */
 	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
 	/* rtl92de_enable_interrupt(hw); */
@@ -1437,8 +1433,8 @@ void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+		 add_msr, rm_msr);
 	if (add_msr)
 		rtlpci->irq_mask[0] |= add_msr;
 	if (rm_msr)
@@ -1615,9 +1611,9 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw,
 			rtlefuse->internal_pa_5g[1] =
 				!((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-				 ("Is D cut,Internal PA0 %d Internal PA1 %d\n",
+				 "Is D cut,Internal PA0 %d Internal PA1 %d\n",
 				 rtlefuse->internal_pa_5g[0],
-				 rtlefuse->internal_pa_5g[1]))
+				 rtlefuse->internal_pa_5g[1]);
 		}
 		rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6];
 		rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7];
@@ -1667,14 +1663,14 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw,
 	if (rtlefuse->eeprom_c9 == 0xFF)
 		rtlefuse->eeprom_c9 = 0x00;
 	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+		 "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter));
+		 "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("CrystalCap = 0x%x\n", rtlefuse->crystalcap));
+		 "CrystalCap = 0x%x\n", rtlefuse->crystalcap);
 	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk,
-		 rtlefuse->delta_lck));
+		 "Delta_IQK = 0x%x Delta_LCK = 0x%x\n",
+		 rtlefuse->delta_iqk, rtlefuse->delta_lck);
 
 	for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) {
 		for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
@@ -1710,11 +1706,11 @@ static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw,
 	if (macphy_crvalue & BIT(3)) {
 		rtlhal->macphymode = SINGLEMAC_SINGLEPHY;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("MacPhyMode SINGLEMAC_SINGLEPHY\n"));
+			 "MacPhyMode SINGLEMAC_SINGLEPHY\n");
 	} else {
 		rtlhal->macphymode = DUALMAC_DUALPHY;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("MacPhyMode DUALMAC_DUALPHY\n"));
+			 "MacPhyMode DUALMAC_DUALPHY\n");
 	}
 }
 
@@ -1741,15 +1737,15 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw)
 	switch (chipvalue) {
 	case 0xAA55:
 		chipver |= CHIP_92D_C_CUT;
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n");
 		break;
 	case 0x9966:
 		chipver |= CHIP_92D_D_CUT;
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n");
 		break;
 	default:
 		chipver |= CHIP_92D_D_CUT;
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unkown CUT!\n");
 		break;
 	}
 	rtlpriv->rtlhal.version = chipver;
@@ -1775,23 +1771,23 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
 		       HWSET_MAX_SIZE);
 	} else if (rtlefuse->epromtype == EEPROM_93C46) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("RTL819X Not boot from eeprom, check it !!"));
+			 "RTL819X Not boot from eeprom, check it !!\n");
 	}
-	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
 		      hwinfo, HWSET_MAX_SIZE);
 
 	eeprom_id = *((u16 *)&hwinfo[0]);
 	if (eeprom_id != RTL8190_EEPROM_ID) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+			 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
 		rtlefuse->autoload_failflag = true;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 		rtlefuse->autoload_failflag = false;
 	}
 	if (rtlefuse->autoload_failflag) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("RTL819X Not boot from eeprom, check it !!"));
+			 "RTL819X Not boot from eeprom, check it !!\n");
 		return;
 	}
 	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID];
@@ -1802,16 +1798,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
 	rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
 	rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
 	rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROMId = 0x%4x\n", eeprom_id));
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+		 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+		 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+		 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+		 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
 
 	/* Read Permanent MAC address */
 	if (rtlhal->interfaceindex == 0) {
@@ -1827,8 +1822,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
 	}
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR,
 				      rtlefuse->dev_addr);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("%pM\n", rtlefuse->dev_addr));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
 	_rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo);
 
 	/* Read Channel Plan */
@@ -1849,7 +1843,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw)
 	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
 	rtlefuse->txpwr_fromeprom = true;
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
+		 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
 }
 
 void rtl92de_read_eeprom_info(struct ieee80211_hw *hw)
@@ -1863,19 +1857,19 @@ void rtl92de_read_eeprom_info(struct ieee80211_hw *hw)
 	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
 	rtlefuse->autoload_status = tmp_u1b;
 	if (tmp_u1b & BIT(4)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
 		rtlefuse->epromtype = EEPROM_93C46;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
 		rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
 	}
 	if (tmp_u1b & BIT(5)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 
 		rtlefuse->autoload_failflag = false;
 		_rtl92de_read_adapter_info(hw);
 	} else {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
 	}
 	return;
 }
@@ -1958,8 +1952,8 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw,
 		    (shortgi_rate << 4) | (shortgi_rate);
 	}
 	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-		 ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+		 rtl_read_dword(rtlpriv, REG_ARFR0));
 }
 
 static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
@@ -2092,8 +2086,8 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
 	value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28);
 	value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
 	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-		 ("ratr_bitmap :%x value0:%x value1:%x\n",
-		  ratr_bitmap, value[0], value[1]));
+		 "ratr_bitmap :%x value0:%x value1:%x\n",
+		 ratr_bitmap, value[0], value[1]);
 	rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value);
 	if (macid != 0)
 		sta_entry->ratr_index = ratr_index;
@@ -2153,14 +2147,13 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
 	e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF;
 	if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) {
 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("GPIOChangeRF  - HW Radio ON, RF ON\n"));
+			 "GPIOChangeRF  - HW Radio ON, RF ON\n");
 		e_rfpowerstate_toset = ERFON;
 		ppsc->hwradiooff = false;
 		actuallyset = true;
-	} else if ((ppsc->hwradiooff == false)
-		&& (e_rfpowerstate_toset == ERFOFF)) {
+	} else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("GPIOChangeRF  - HW Radio OFF, RF OFF\n"));
+			 "GPIOChangeRF  - HW Radio OFF, RF OFF\n");
 		e_rfpowerstate_toset = ERFOFF;
 		ppsc->hwradiooff = true;
 		actuallyset = true;
@@ -2204,7 +2197,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
 		u8 idx;
 		u8 cam_offset = 0;
 		u8 clear_number = 5;
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 		for (idx = 0; idx < clear_number; idx++) {
 			rtl_cam_mark_invalid(hw, cam_offset + idx);
 			rtl_cam_empty_entry(hw, cam_offset + idx);
@@ -2230,8 +2223,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
 			enc_algo = CAM_AES;
 			break;
 		default:
-			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
-						"not process\n"));
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 "switch case not processed\n");
 			enc_algo = CAM_TKIP;
 			break;
 		}
@@ -2248,9 +2241,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
 								 p_macaddr);
 					if (entry_id >=  TOTAL_CAM_ENTRY) {
 						RT_TRACE(rtlpriv, COMP_SEC,
-							 DBG_EMERG, ("Can not "
-							 "find free hw security"
-							 " cam entry\n"));
+							 DBG_EMERG,
+							 "Can not find free hw security cam entry\n");
 						return;
 					}
 				} else {
@@ -2262,29 +2254,29 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
 		}
 		if (rtlpriv->sec.key_len[key_index] == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("delete one entry, entry_id is %d\n",
-				 entry_id));
+				 "delete one entry, entry_id is %d\n",
+				 entry_id);
 			if (mac->opmode == NL80211_IFTYPE_AP)
 				rtl_cam_del_entry(hw, p_macaddr);
 			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 		} else {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY length is %d\n",
-				  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+				 "The insert KEY length is %d\n",
+				 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY  is %x %x\n",
-				  rtlpriv->sec.key_buf[0][0],
-				  rtlpriv->sec.key_buf[0][1]));
+				 "The insert KEY is %x %x\n",
+				 rtlpriv->sec.key_buf[0][0],
+				 rtlpriv->sec.key_buf[0][1]);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("add one entry\n"));
+				 "add one entry\n");
 			if (is_pairwise) {
 				RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-					      "Pairwiase Key content :",
+					      "Pairwise Key content",
 					      rtlpriv->sec.pairwise_key,
 					      rtlpriv->
 					      sec.key_len[PAIRWISE_KEYIDX]);
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set Pairwiase key\n"));
+					 "set Pairwise key\n");
 				rtl_cam_add_one_entry(hw, macaddr, key_index,
 						      entry_id, enc_algo,
 						      CAM_CONFIG_NO_USEDK,
@@ -2292,7 +2284,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index,
 						      sec.key_buf[key_index]);
 			} else {
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set group key\n"));
+					 "set group key\n");
 				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 					rtl_cam_add_one_entry(hw,
 						rtlefuse->dev_addr,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h
index ad44ffa..7c9f7a2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c
index f1552f4..76a57ae 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -45,8 +45,8 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 	u8 ledcfg;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 REG_LEDCFG2, pled->ledpin);
 
 	switch (pled->ledpin) {
 	case LED_PIN_GPIO0:
@@ -71,7 +71,7 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = true;
@@ -83,8 +83,8 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
 	u8 ledcfg;
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 REG_LEDCFG2, pled->ledpin);
 
 	ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
 
@@ -106,7 +106,7 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = false;
@@ -153,7 +153,7 @@ void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
 	     ledaction == LED_CTL_POWER_ON)) {
 		return;
 	}
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction);
 
 	_rtl92ce_sw_led_control(hw, ledaction);
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h
index 57f4a3c..a29df30 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 0883349..93eecbd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -204,8 +204,8 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
 	u32 returnvalue, originalvalue, bitshift;
 	u8 dbi_direct;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-		"bitmask(%#x)\n", regaddr, bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+		 regaddr, bitmask);
 	if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) {
 		/* mac1 use phy0 read radio_b. */
 		/* mac0 use phy1 read radio_b. */
@@ -220,8 +220,9 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
 	}
 	bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
 	returnvalue = (originalvalue & bitmask) >> bitshift;
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
-		"Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+		 bitmask, regaddr, originalvalue);
 	return returnvalue;
 }
 
@@ -233,8 +234,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
 	u8 dbi_direct = 0;
 	u32 originalvalue, bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-		" data(%#x)\n", regaddr, bitmask, data));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+		 regaddr, bitmask, data);
 	if (rtlhal->during_mac1init_radioa)
 		dbi_direct = BIT(3);
 	else if (rtlhal->during_mac0init_radiob)
@@ -255,8 +257,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
 		rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct);
 	else
 		rtl_write_dword(rtlpriv, regaddr, data);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-		 " data(%#x)\n", regaddr, bitmask, data));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+		 regaddr, bitmask, data);
 }
 
 static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
@@ -300,8 +303,8 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
 	else
 		retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
 			BLSSIREADBACKDATA);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n",
-		 rfpath, pphyreg->rflssi_readback, retvalue));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n",
+		 rfpath, pphyreg->rflssi_readback, retvalue);
 	return retvalue;
 }
 
@@ -319,8 +322,8 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,
 	/* T65 RF */
 	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
-		rfpath, pphyreg->rf3wire_offset, data_and_addr));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rf3wire_offset, data_and_addr);
 }
 
 u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
@@ -330,17 +333,17 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
 	u32 original_value, readback_value, bitshift;
 	unsigned long flags;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-		"rfpath(%#x), bitmask(%#x)\n",
-		regaddr, rfpath, bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+		 regaddr, rfpath, bitmask);
 	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 	original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr);
 	bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
 	readback_value = (original_value & bitmask) >> bitshift;
 	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
-		"bitmask(%#x), original_value(%#x)\n",
-		regaddr, rfpath, bitmask, original_value));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+		 regaddr, rfpath, bitmask, original_value);
 	return readback_value;
 }
 
@@ -353,8 +356,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 	unsigned long flags;
 
 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-		("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
-		regaddr, bitmask, data, rfpath));
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 	if (bitmask == 0)
 		return;
 	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
@@ -369,9 +372,9 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 		_rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data);
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
-		"bitmask(%#x), data(%#x), rfpath(%#x)\n",
-		regaddr, bitmask, data, rfpath));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 }
 
 bool rtl92d_phy_mac_config(struct ieee80211_hw *hw)
@@ -381,10 +384,10 @@ bool rtl92d_phy_mac_config(struct ieee80211_hw *hw)
 	u32 arraylength;
 	u32 *ptrarray;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
 	arraylength = MAC_2T_ARRAYLENGTH;
 	ptrarray = rtl8192de_mac_2tarray;
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n");
 	for (i = 0; i < arraylength; i = i + 2)
 		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 	if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) {
@@ -561,25 +564,25 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 		agctab_arraylen = AGCTAB_ARRAYLENGTH;
 		agctab_array_table = rtl8192de_agctab_array;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n"));
+			 " ===> phy:MAC0, Rtl819XAGCTAB_Array\n");
 	} else {
 		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 			agctab_arraylen = AGCTAB_2G_ARRAYLENGTH;
 			agctab_array_table = rtl8192de_agctab_2garray;
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				 (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"));
+				 " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n");
 		} else {
 			agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH;
 			agctab_5garray_table = rtl8192de_agctab_5garray;
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				 (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"));
+				 " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n");
 
 		}
 	}
 	phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH;
 	phy_regarray_table = rtl8192de_phy_reg_2tarray;
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 (" ===> phy:Rtl819XPHY_REG_Array_PG\n"));
+		 " ===> phy:Rtl819XPHY_REG_Array_PG\n");
 	if (configtype == BASEBAND_CONFIG_PHY_REG) {
 		for (i = 0; i < phy_reg_arraylen; i = i + 2) {
 			if (phy_regarray_table[i] == 0xfe)
@@ -598,10 +601,9 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 				      phy_regarray_table[i + 1]);
 			udelay(1);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				 ("The phy_regarray_table[0] is %x"
-				  " Rtl819XPHY_REGArray[1] is %x\n",
-				  phy_regarray_table[i],
-				  phy_regarray_table[i + 1]));
+				 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
+				 phy_regarray_table[i],
+				 phy_regarray_table[i + 1]);
 		}
 	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 		if (rtlhal->interfaceindex == 0) {
@@ -613,15 +615,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 				 * setting. */
 				udelay(1);
 				RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-					 ("The Rtl819XAGCTAB_Array_"
-					 "Table[0] is %ul "
-					 "Rtl819XPHY_REGArray[1] is %ul\n",
+					 "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
 					 agctab_array_table[i],
-					 agctab_array_table[i + 1]));
+					 agctab_array_table[i + 1]);
 			}
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				 ("Normal Chip, MAC0, load "
-				 "Rtl819XAGCTAB_Array\n"));
+				 "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n");
 		} else {
 			if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 				for (i = 0; i < agctab_arraylen; i = i + 2) {
@@ -632,14 +631,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 					 * setting. */
 					udelay(1);
 					RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-						 ("The Rtl819XAGCTAB_Array_"
-						 "Table[0] is %ul Rtl819XPHY_"
-						 "REGArray[1] is %ul\n",
+						 "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
 						 agctab_array_table[i],
-						 agctab_array_table[i + 1]));
+						 agctab_array_table[i + 1]);
 				}
 				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-					 ("Load Rtl819XAGCTAB_2GArray\n"));
+					 "Load Rtl819XAGCTAB_2GArray\n");
 			} else {
 				for (i = 0; i < agctab_5garraylen; i = i + 2) {
 					rtl_set_bbreg(hw,
@@ -650,14 +647,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 					 * setting. */
 					udelay(1);
 					RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-						 ("The Rtl819XAGCTAB_5GArray_"
-						 "Table[0] is %ul Rtl819XPHY_"
-						 "REGArray[1] is %ul\n",
+						 "The Rtl819XAGCTAB_5GArray_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
 						 agctab_5garray_table[i],
-						 agctab_5garray_table[i + 1]));
+						 agctab_5garray_table[i + 1]);
 				}
 				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-					("Load Rtl819XAGCTAB_5GArray\n"));
+					 "Load Rtl819XAGCTAB_5GArray\n");
 			}
 		}
 	}
@@ -675,145 +670,145 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][0]));
+			 [rtlphy->pwrgroup_cnt][0]);
 	}
 	if (regaddr == RTXAGC_A_RATE54_24) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][1]));
+			 [rtlphy->pwrgroup_cnt][1]);
 	}
 	if (regaddr == RTXAGC_A_CCK1_MCS32) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][6]));
+			 [rtlphy->pwrgroup_cnt][6]);
 	}
 	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][7]));
+			 [rtlphy->pwrgroup_cnt][7]);
 	}
 	if (regaddr == RTXAGC_A_MCS03_MCS00) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][2]));
+			 [rtlphy->pwrgroup_cnt][2]);
 	}
 	if (regaddr == RTXAGC_A_MCS07_MCS04) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][3]));
+			 [rtlphy->pwrgroup_cnt][3]);
 	}
 	if (regaddr == RTXAGC_A_MCS11_MCS08) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][4]));
+			 [rtlphy->pwrgroup_cnt][4]);
 	}
 	if (regaddr == RTXAGC_A_MCS15_MCS12) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][5]));
+			 [rtlphy->pwrgroup_cnt][5]);
 	}
 	if (regaddr == RTXAGC_B_RATE18_06) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][8]));
+			 [rtlphy->pwrgroup_cnt][8]);
 	}
 	if (regaddr == RTXAGC_B_RATE54_24) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][9]));
+			 [rtlphy->pwrgroup_cnt][9]);
 	}
 	if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][14]));
+			 [rtlphy->pwrgroup_cnt][14]);
 	}
 	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][15]));
+			 [rtlphy->pwrgroup_cnt][15]);
 	}
 	if (regaddr == RTXAGC_B_MCS03_MCS00) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][10]));
+			 [rtlphy->pwrgroup_cnt][10]);
 	}
 	if (regaddr == RTXAGC_B_MCS07_MCS04) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n",
+			 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n",
 			 rtlphy->pwrgroup_cnt,
 			 rtlphy->mcs_txpwrlevel_origoffset
-			 [rtlphy->pwrgroup_cnt][11]));
+			 [rtlphy->pwrgroup_cnt][11]);
 	}
 	if (regaddr == RTXAGC_B_MCS11_MCS08) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->mcs_txpwrlevel_origoffset
-					[rtlphy->pwrgroup_cnt][12]));
+			 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->mcs_txpwrlevel_origoffset
+			 [rtlphy->pwrgroup_cnt][12]);
 	}
 	if (regaddr == RTXAGC_B_MCS15_MCS12) {
 		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
 									 data;
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n",
-			  rtlphy->pwrgroup_cnt,
-			  rtlphy->mcs_txpwrlevel_origoffset
-					[rtlphy->pwrgroup_cnt][13]));
+			 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n",
+			 rtlphy->pwrgroup_cnt,
+			 rtlphy->mcs_txpwrlevel_origoffset
+			 [rtlphy->pwrgroup_cnt][13]);
 		rtlphy->pwrgroup_cnt++;
 	}
 }
@@ -849,7 +844,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 		}
 	} else {
 		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-			 ("configtype != BaseBand_Config_PHY_REG\n"));
+			 "configtype != BaseBand_Config_PHY_REG\n");
 	}
 	return true;
 }
@@ -861,17 +856,17 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	bool rtstatus = true;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
 	rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
 		BASEBAND_CONFIG_PHY_REG);
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
 		return false;
 	}
 
 	/* if (rtlphy->rf_type == RF_1T2R) {
 	 *      _rtl92c_phy_bb_config_1t(hw);
-	 *     RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
+	 *     RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
 	 *} */
 
 	if (rtlefuse->autoload_failflag == false) {
@@ -879,14 +874,14 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
 		rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw,
 			BASEBAND_CONFIG_PHY_REG);
 	}
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
 		return false;
 	}
 	rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
 		BASEBAND_CONFIG_AGC_TAB);
-	if (rtstatus != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
 		return false;
 	}
 	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
@@ -951,19 +946,17 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 		radiob_array_table = rtl8192de_radiob_2t_int_paarray;
 	}
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("PHY_ConfigRFWithHeaderFile() "
-		 "Radio_A:Rtl819XRadioA_1TArray\n"));
+		 "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n");
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("PHY_ConfigRFWithHeaderFile() "
-		 "Radio_B:Rtl819XRadioB_1TArray\n"));
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath));
+		 "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n");
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
 
 	/* this only happens when DMDP, mac0 start on 2.4G,
 	 * mac1 start on 5G, mac 0 has to set phy0&phy1
 	 * pathA or mac1 has to set phy0&phy1 pathA */
 	if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 (" ===> althougth Path A, we load radiob.txt\n"));
+			 " ===> althougth Path A, we load radiob.txt\n");
 		radioa_arraylen = radiob_arraylen;
 		radioa_array_table = radiob_array_table;
 	}
@@ -1022,11 +1015,11 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 		break;
 	case RF90_PATH_C:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	case RF90_PATH_D:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	return true;
@@ -1046,19 +1039,18 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 	rtlphy->default_initialgain[3] =
 	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Default initial gain (c50=0x%x, "
-		  "c58=0x%x, c60=0x%x, c68=0x%x\n",
-		  rtlphy->default_initialgain[0],
-		  rtlphy->default_initialgain[1],
-		  rtlphy->default_initialgain[2],
-		  rtlphy->default_initialgain[3]));
+		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
+		 rtlphy->default_initialgain[0],
+		 rtlphy->default_initialgain[1],
+		 rtlphy->default_initialgain[2],
+		 rtlphy->default_initialgain[3]);
 	rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
 					      BMASKBYTE0);
 	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
 					      BMASKDWORD);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-		 ("Default framesync (0x%x) = 0x%x\n",
-		  ROFDM0_RXDETECTOR3, rtlphy->framesync));
+		 "Default framesync (0x%x) = 0x%x\n",
+		 ROFDM0_RXDETECTOR3, rtlphy->framesync);
 }
 
 static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
@@ -1137,7 +1129,7 @@ void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u8 cckpowerlevel[2], ofdmpowerlevel[2];
 
-	if (rtlefuse->txpwr_fromeprom == false)
+	if (!rtlefuse->txpwr_fromeprom)
 		return;
 	channel = _rtl92c_phy_get_rightchnlplace(channel);
 	_rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0],
@@ -1172,7 +1164,7 @@ void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Unknown Scan Backup operation.\n"));
+				 "Unknown Scan Backup operation\n");
 			break;
 		}
 	}
@@ -1193,14 +1185,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
 		return;
 	if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("FALSE driver sleep or unload\n"));
+			 "FALSE driver sleep or unload\n");
 		return;
 	}
 	rtlphy->set_bwmode_inprogress = true;
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-		 ("Switch to %s bandwidth\n",
-		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-		  "20MHz" : "40MHz"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+		 "20MHz" : "40MHz");
 	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
 	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
 	switch (rtlphy->current_chan_bw) {
@@ -1218,7 +1209,7 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 	switch (rtlphy->current_chan_bw) {
@@ -1250,13 +1241,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 
 	}
 	rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 	rtlphy->set_bwmode_inprogress = false;
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
@@ -1273,7 +1264,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 value8;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
 	rtlhal->bandset = band;
 	rtlhal->current_bandtype = band;
 	if (IS_92D_SINGLEPHY(rtlhal->version))
@@ -1283,13 +1274,13 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
 	/* reconfig BB/RF according to wireless mode */
 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 		/* BB & RF Config */
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n");
 		if (rtlhal->interfaceindex == 1)
 			_rtl92d_phy_config_bb_with_headerfile(hw,
 				BASEBAND_CONFIG_AGC_TAB);
 	} else {
 		/* 5G band */
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n");
 		if (rtlhal->interfaceindex == 1)
 			_rtl92d_phy_config_bb_with_headerfile(hw,
 				BASEBAND_CONFIG_AGC_TAB);
@@ -1317,7 +1308,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
 			0 ? REG_MAC0 : REG_MAC1), value8);
 	}
 	mdelay(1);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n");
 }
 
 static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
@@ -1329,9 +1320,9 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
 	u8 group, i;
 	unsigned long flag = 0;
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath);
 	if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
 		rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
 		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
 		/* fc area 0xd2c */
@@ -1353,14 +1344,13 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
 	} else {
 		/* G band. */
 		RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
-			 ("Load RF IMR parameters for G band. IMR already "
-			 "setting %d\n",
-			  rtlpriv->rtlhal.load_imrandiqk_setting_for2g));
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n"));
+			 "Load RF IMR parameters for G band. IMR already setting %d\n",
+			 rtlpriv->rtlhal.load_imrandiqk_setting_for2g);
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
 		if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) {
 			RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
-				("Load RF IMR parameters "
-				"for G band. %d\n", rfpath));
+				 "Load RF IMR parameters for G band. %d\n",
+				 rfpath);
 			rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
 			rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
 			rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
@@ -1378,7 +1368,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
 			rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
 		}
 	}
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
@@ -1388,7 +1378,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
 	/*----Store original RFENV control type----*/
 	switch (rfpath) {
 	case RF90_PATH_A:
@@ -1414,7 +1404,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
 	/*Set 0 to 12 bits for 8255 */
 	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
 	udelay(1);
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
 }
 
 static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
@@ -1424,7 +1414,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n");
 	/*----Restore RFENV control type----*/ ;
 	switch (rfpath) {
 	case RF90_PATH_A:
@@ -1437,7 +1427,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
 			      *pu4_regval);
 		break;
 	}
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n");
 }
 
 static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
@@ -1451,13 +1441,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
 	bool need_pwr_down = false, internal_pa = false;
 	u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2;
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n");
 	/* config path A for 5G */
 	if (rtlhal->current_bandtype == BAND_ON_5G) {
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
 		u4tmp = curveindex_5g[channel - 1];
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, "
-			"0x28 = 0x%x !!\n", u4tmp));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,
+			"ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp);
 		for (i = 0; i < RF_CHNL_NUM_5G; i++) {
 			if (channel == rf_chnl_5g[i] && channel <= 140)
 				index = 0;
@@ -1503,12 +1493,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
 					      rf_reg_pram_c_5g[index][i]);
 			}
 			RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-				("offset 0x%x value 0x%x "
-				"path %d index %d readback 0x%x\n",
-				rf_reg_for_c_cut_5g[i],
-				rf_reg_pram_c_5g[index][i], path,
-				index, rtl_get_rfreg(hw, (enum radio_path)path,
-				rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK)));
+				 "offset 0x%x value 0x%x path %d index %d readback 0x%x\n",
+				 rf_reg_for_c_cut_5g[i],
+				 rf_reg_pram_c_5g[index][i],
+				 path, index,
+				 rtl_get_rfreg(hw, (enum radio_path)path,
+					       rf_reg_for_c_cut_5g[i],
+					       BRFREGOFFSETMASK));
 		}
 		if (need_pwr_down)
 			_rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
@@ -1541,11 +1532,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
 						BRFREGOFFSETMASK,
 						rf_pram_c_5g_int_pa[index][i]);
 					RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
-						 ("offset 0x%x value 0x%x "
-						 "path %d index %d\n",
+						 "offset 0x%x value 0x%x path %d index %d\n",
 						 rf_for_c_cut_5g_internal_pa[i],
 						 rf_pram_c_5g_int_pa[index][i],
-						 rfpath, index));
+						 rfpath, index);
 				}
 			} else {
 				rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
@@ -1553,10 +1543,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
 			}
 		}
 	} else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
 		u4tmp = curveindex_2g[channel - 1];
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, "
-			"0x28 = 0x%x !!\n", u4tmp));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,
+			"ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
 		if (channel == 1 || channel == 2 || channel == 4 || channel == 9
 		    || channel == 10 || channel == 11 || channel == 12)
 			index = 0;
@@ -1590,18 +1580,17 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
 					      rf_reg_param_for_c_cut_2g
 					      [index][i]);
 			RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-				("offset 0x%x value 0x%x mak 0x%x path %d "
-				"index %d readback 0x%x\n",
-				rf_reg_for_c_cut_2g[i],
-				rf_reg_param_for_c_cut_2g[index][i],
-				rf_reg_mask_for_c_cut_2g[i], path, index,
-				rtl_get_rfreg(hw, (enum radio_path)path,
-				rf_reg_for_c_cut_2g[i],
-				BRFREGOFFSETMASK)));
+				 "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n",
+				 rf_reg_for_c_cut_2g[i],
+				 rf_reg_param_for_c_cut_2g[index][i],
+				 rf_reg_mask_for_c_cut_2g[i], path, index,
+				 rtl_get_rfreg(hw, (enum radio_path)path,
+					       rf_reg_for_c_cut_2g[i],
+					       BRFREGOFFSETMASK));
 		}
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
-			rf_syn_g4_for_c_cut_2g | (u4tmp << 11)));
+			"cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
+			rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
 
 		rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
 			      BRFREGOFFSETMASK,
@@ -1611,7 +1600,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
 		if (rtlhal->during_mac0init_radiob)
 			rtl92d_phy_powerdown_anotherphy(hw, true);
 	}
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
@@ -1648,9 +1637,9 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
 	u32 regeac, rege94, rege9c, regea4;
 	u8 result = 0;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK!\n");
 	/* path-A IQK setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
 	if (rtlhal->interfaceindex == 0) {
 		rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f);
 		rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f);
@@ -1668,26 +1657,26 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
 		rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206);
 	}
 	/* LO calibration setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
 	rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
 	/* One shot, path A LOK & IQK */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n");
 	rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
 	rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
 	/* delay x ms */
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("Delay %d ms for One shot, path A LOK & IQK.\n",
-		IQK_DELAY_TIME));
+		"Delay %d ms for One shot, path A LOK & IQK\n",
+		IQK_DELAY_TIME);
 	mdelay(IQK_DELAY_TIME);
 	/* Check failed */
 	regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
 	rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94);
 	rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c);
 	regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);
 	if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
 	    (((rege9c & 0x03FF0000) >> 16) != 0x42))
 		result |= 0x01;
@@ -1698,7 +1687,7 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
 	    (((regeac & 0x03FF0000) >> 16) != 0x36))
 		result |= 0x02;
 	else
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n"));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A Rx IQK fail!!\n");
 	return result;
 }
 
@@ -1719,9 +1708,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
 		TxOKBit = BIT(31);
 		RxOKBit = BIT(30);
 	}
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK!\n");
 	/* path-A IQK setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
 	rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
 	rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
 	rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307);
@@ -1734,7 +1723,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
 		rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000);
 	}
 	/* LO calibration setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
 	rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
 	/* path-A PA on */
 	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60);
@@ -1742,29 +1731,29 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
 	for (i = 0; i < retrycount; i++) {
 		/* One shot, path A LOK & IQK */
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("One shot, path A LOK & IQK!\n"));
+			"One shot, path A LOK & IQK!\n");
 		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
 		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
 		/* delay x ms */
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("Delay %d ms for One shot, path A LOK & IQK.\n",
-			IQK_DELAY_TIME));
+			"Delay %d ms for One shot, path A LOK & IQK.\n",
+			IQK_DELAY_TIME);
 		mdelay(IQK_DELAY_TIME * 10);
 		/* Check failed */
 		regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
 		rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe94 = 0x%x\n", rege94);
 		rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xe9c = 0x%x\n", rege9c);
 		regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xea4 = 0x%x\n", regea4);
 		if (!(regeac & TxOKBit) &&
 		     (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
 			result |= 0x01;
 		} else { /* if Tx not OK, ignore Rx */
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path A Tx IQK fail!!\n"));
+				"Path A Tx IQK fail!!\n");
 			continue;
 		}
 
@@ -1775,7 +1764,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
 			break;
 		} else {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path A Rx IQK fail!!\n"));
+				"Path A Rx IQK fail!!\n");
 		}
 	}
 	/* path A PA off */
@@ -1793,27 +1782,26 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
 	u32 regeac, regeb4, regebc, regec4, regecc;
 	u8 result = 0;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B IQK!\n");
 	/* One shot, path B LOK & IQK */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "One shot, path A LOK & IQK!\n");
 	rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002);
 	rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000);
 	/* delay x ms  */
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("Delay %d ms for One shot, path B LOK & IQK.\n",
-		IQK_DELAY_TIME));
+		"Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);
 	mdelay(IQK_DELAY_TIME);
 	/* Check failed */
 	regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
 	regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4);
 	regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc);
 	regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4);
 	regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);
 	if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
 	    (((regebc & 0x03FF0000) >> 16) != 0x42))
 		result |= 0x01;
@@ -1823,7 +1811,7 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
 	    (((regecc & 0x03FF0000) >> 16) != 0x36))
 		result |= 0x02;
 	else
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n"));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B Rx IQK fail!!\n");
 	return result;
 }
 
@@ -1837,9 +1825,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
 	u8 i;
 	u8 retrycount = 2;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path B IQK!\n");
 	/* path-A IQK setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A IQK setting!\n");
 	rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
 	rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
 	rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000);
@@ -1852,7 +1840,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
 	rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960);
 
 	/* LO calibration setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LO calibration setting!\n");
 	rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
 
 	/* path-B PA on */
@@ -1862,26 +1850,26 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
 	for (i = 0; i < retrycount; i++) {
 		/* One shot, path B LOK & IQK */
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("One shot, path A LOK & IQK!\n"));
+			"One shot, path A LOK & IQK!\n");
 		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000);
 		rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
 
 		/* delay x ms */
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("Delay %d ms for One shot, path B LOK & IQK.\n", 10));
+			"Delay %d ms for One shot, path B LOK & IQK.\n", 10);
 		mdelay(IQK_DELAY_TIME * 10);
 
 		/* Check failed */
 		regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeac = 0x%x\n", regeac);
 		regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xeb4 = 0x%x\n", regeb4);
 		regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xebc = 0x%x\n", regebc);
 		regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xec4 = 0x%x\n", regec4);
 		regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "0xecc = 0x%x\n", regecc);
 		if (!(regeac & BIT(31)) &&
 		    (((regeb4 & 0x03FF0000) >> 16) != 0x142))
 			result |= 0x01;
@@ -1893,7 +1881,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
 			break;
 		} else {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path B Rx IQK fail!!\n"));
+				"Path B Rx IQK fail!!\n");
 		}
 	}
 
@@ -1912,7 +1900,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 i;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Save ADDA parameters.\n");
 	for (i = 0; i < regnum; i++)
 		adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD);
 }
@@ -1923,7 +1911,7 @@ static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 i;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Save MAC parameters.\n");
 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
 		macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
 	macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
@@ -1937,7 +1925,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,
 	u32 i;
 
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("Reload ADDA power saving parameters !\n"));
+		"Reload ADDA power saving parameters !\n");
 	for (i = 0; i < regnum; i++)
 		rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]);
 }
@@ -1948,7 +1936,7 @@ static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 i;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Reload MAC parameters !\n");
 	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
 		rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
 	rtl_write_byte(rtlpriv, macreg[i], macbackup[i]);
@@ -1961,7 +1949,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
 	u32 pathon;
 	u32 i;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "ADDA ON.\n");
 	pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4;
 	if (patha_on)
 		pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
@@ -1976,7 +1964,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 i;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "MAC settings for Calibration.\n");
 	rtl_write_byte(rtlpriv, macreg[0], 0x3F);
 
 	for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
@@ -1988,7 +1976,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
 static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path-A standby mode!\n");
 
 	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0);
 	rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000);
@@ -2001,7 +1989,7 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
 	u32 mode;
 
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI")));
+		"BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");
 	mode = pi_mode ? 0x01000100 : 0x01000000;
 	rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode);
 	rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode);
@@ -2033,12 +2021,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 	const u32 retrycount = 2;
 	u32 bbvalue;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 2.4G :Start!!!\n");
 	if (t == 0) {
 		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue));
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n",
-			(is2t ? "2T2R" : "1T1R")));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);
+		RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
+			is2t ? "2T2R" : "1T1R");
 
 		/*  Save ADDA parameters, turn Path A ADDA on */
 		_rtl92d_phy_save_adda_registers(hw, adda_reg,
@@ -2076,7 +2064,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 	if (is2t)
 		rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
 	/* IQ calibration setting */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n");
 	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
 	rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00);
 	rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
@@ -2084,7 +2072,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 		patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);
 		if (patha_ok == 0x03) {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path A IQK Success!!\n"));
+				"Path A IQK Success!!\n");
 			result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
 					0x3FF0000) >> 16;
 			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
@@ -2097,7 +2085,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 		} else if (i == (retrycount - 1) && patha_ok == 0x01) {
 			/* Tx IQK OK */
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path A IQK Only  Tx Success!!\n"));
+				"Path A IQK Only  Tx Success!!\n");
 
 			result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
 					0x3FF0000) >> 16;
@@ -2106,7 +2094,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 		}
 	}
 	if (0x00 == patha_ok)
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n"));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK failed!!\n");
 	if (is2t) {
 		_rtl92d_phy_patha_standby(hw);
 		/* Turn Path B ADDA on */
@@ -2115,7 +2103,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 			pathb_ok = _rtl92d_phy_pathb_iqk(hw);
 			if (pathb_ok == 0x03) {
 				RTPRINT(rtlpriv, FINIT, INIT_IQK,
-					("Path B IQK Success!!\n"));
+					"Path B IQK Success!!\n");
 				result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
 					       BMASKDWORD) & 0x3FF0000) >> 16;
 				result[t][5] = (rtl_get_bbreg(hw, 0xebc,
@@ -2128,7 +2116,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 			} else if (i == (retrycount - 1) && pathb_ok == 0x01) {
 				/* Tx IQK OK */
 				RTPRINT(rtlpriv, FINIT, INIT_IQK,
-					("Path B Only Tx IQK Success!!\n"));
+					"Path B Only Tx IQK Success!!\n");
 				result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
 					       BMASKDWORD) & 0x3FF0000) >> 16;
 				result[t][5] = (rtl_get_bbreg(hw, 0xebc,
@@ -2137,12 +2125,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 		}
 		if (0x00 == pathb_ok)
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path B IQK failed!!\n"));
+				"Path B IQK failed!!\n");
 	}
 
 	/* Back to BB mode, load original value */
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("IQK:Back to BB mode, load original value!\n"));
+		"IQK:Back to BB mode, load original value!\n");
 
 	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
 	if (t != 0) {
@@ -2167,7 +2155,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
 		rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00);
 		rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00);
 	}
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");
 }
 
 static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
@@ -2199,13 +2187,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
 	/* Note: IQ calibration must be performed after loading
 	 * PHY_REG.txt , and radio_a, radio_b.txt */
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK for 5G NORMAL:Start!!!\n");
 	mdelay(IQK_DELAY_TIME * 20);
 	if (t == 0) {
 		bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue));
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n",
-			(is2t ? "2T2R" : "1T1R")));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "==>0x%08x\n", bbvalue);
+		RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
+			is2t ? "2T2R" : "1T1R");
 		/* Save ADDA parameters, turn Path A ADDA on */
 		_rtl92d_phy_save_adda_registers(hw, adda_reg,
 						rtlphy->adda_backup,
@@ -2242,13 +2230,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
 	if (is2t)
 		rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
 	/* IQ calibration setting  */
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "IQK setting!\n");
 	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
 	rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00);
 	rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
 	patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);
 	if (patha_ok == 0x03) {
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n"));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Success!!\n");
 		result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
 				0x3FF0000) >> 16;
 		result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
@@ -2259,14 +2247,14 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
 				0x3FF0000) >> 16;
 	} else if (patha_ok == 0x01) {	/* Tx IQK OK */
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("Path A IQK Only  Tx Success!!\n"));
+			"Path A IQK Only  Tx Success!!\n");
 
 		result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
 				0x3FF0000) >> 16;
 		result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
 				0x3FF0000) >> 16;
 	} else {
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n"));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "Path A IQK Fail!!\n");
 	}
 	if (is2t) {
 		/* _rtl92d_phy_patha_standby(hw); */
@@ -2275,7 +2263,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
 		pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw);
 		if (pathb_ok == 0x03) {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path B IQK Success!!\n"));
+				"Path B IQK Success!!\n");
 			result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
 			     0x3FF0000) >> 16;
 			result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
@@ -2286,20 +2274,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
 			     0x3FF0000) >> 16;
 		} else if (pathb_ok == 0x01) { /* Tx IQK OK */
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path B Only Tx IQK Success!!\n"));
+				"Path B Only Tx IQK Success!!\n");
 			result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
 			     0x3FF0000) >> 16;
 			result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
 			     0x3FF0000) >> 16;
 		} else {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("Path B IQK failed!!\n"));
+				"Path B IQK failed!!\n");
 		}
 	}
 
 	/* Back to BB mode, load original value */
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("IQK:Back to BB mode, load original value!\n"));
+		"IQK:Back to BB mode, load original value!\n");
 	rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
 	if (t != 0) {
 		if (is2t)
@@ -2321,7 +2309,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
 						  rtlphy->adda_backup,
 						  IQK_ADDA_REG_NUM);
 	}
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "<==\n");
 }
 
 static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw,
@@ -2395,8 +2383,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
 	    rtlhal->macphymode == DUALMAC_DUALPHY;
 
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("Path A IQ Calibration %s !\n",
-		(iqk_ok) ? "Success" : "Failed"));
+		"Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
 	if (final_candidate == 0xFF) {
 		return;
 	} else if (iqk_ok) {
@@ -2406,8 +2393,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
 		if ((val_x & 0x00000200) != 0)
 			val_x = val_x | 0xFFFFFC00;
 		tx0_a = (val_x * oldval_0) >> 8;
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x,"
-			" oldval_0 0x%x\n",	val_x, tx0_a, oldval_0));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,
+			"X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n",
+			val_x, tx0_a, oldval_0);
 		rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a);
 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
 			      ((val_x * oldval_0 >> 7) & 0x1));
@@ -2419,8 +2407,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
 			rtlhal->current_bandtype == BAND_ON_5G)
 			val_y += 3;
 		tx0_c = (val_y * oldval_0) >> 8;
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n",
-			val_y, tx0_c));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,
+			"Y = 0x%lx, tx0_c = 0x%lx\n",
+			val_y, tx0_c);
 		rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000,
 			      ((tx0_c & 0x3C0) >> 6));
 		rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000,
@@ -2428,11 +2417,11 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
 		if (is2t)
 			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26),
 				      ((val_y * oldval_0 >> 7) & 0x1));
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n",
-			 rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
-				       BMASKDWORD)));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",
+			rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
+				      BMASKDWORD));
 		if (txonly) {
-			RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n"));
+			RTPRINT(rtlpriv, FINIT, INIT_IQK,  "only Tx OK\n");
 			return;
 		}
 		reg = result[final_candidate][2];
@@ -2452,8 +2441,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
 	u32 oldval_1, val_x, tx1_a, reg;
 	long val_y, tx1_c;
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n",
-		 (iqk_ok) ? "Success" : "Failed"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n",
+		iqk_ok ? "Success" : "Failed");
 	if (final_candidate == 0xFF) {
 		return;
 	} else if (iqk_ok) {
@@ -2463,8 +2452,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
 		if ((val_x & 0x00000200) != 0)
 			val_x = val_x | 0xFFFFFC00;
 		tx1_a = (val_x * oldval_1) >> 8;
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n",
-			val_x, tx1_a));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n",
+			val_x, tx1_a);
 		rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a);
 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
 			      ((val_x * oldval_1 >> 7) & 0x1));
@@ -2474,8 +2463,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
 		if (rtlhal->current_bandtype == BAND_ON_5G)
 			val_y += 3;
 		tx1_c = (val_y * oldval_1) >> 8;
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n",
-			val_y, tx1_c));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n",
+			val_y, tx1_c);
 		rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000,
 			      ((tx1_c & 0x3C0) >> 6));
 		rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000,
@@ -2507,7 +2496,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
 	unsigned long flag = 0;
 
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("IQK:Start!!!channel %d\n", rtlphy->current_channel));
+		"IQK:Start!!!channel %d\n", rtlphy->current_channel);
 	for (i = 0; i < 8; i++) {
 		result[0][i] = 0;
 		result[1][i] = 0;
@@ -2521,7 +2510,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
 	is23simular = false;
 	is13simular = false;
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("IQK !!!currentband %d\n", rtlhal->current_bandtype));
+		"IQK !!!currentband %d\n", rtlhal->current_bandtype);
 	rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
 	for (i = 0; i < 3; i++) {
 		if (rtlhal->current_bandtype == BAND_ON_5G) {
@@ -2573,10 +2562,9 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
 		regec4 = result[i][6];
 		regecc = result[i][7];
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx "
-			"regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ",
+			"IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
 			rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
-			regecc));
+			regecc);
 	}
 	if (final_candidate != 0xff) {
 		rtlphy->reg_e94 = rege94 = result[final_candidate][0];
@@ -2588,12 +2576,11 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
 		regec4 = result[final_candidate][6];
 		regecc = result[final_candidate][7];
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("IQK: final_candidate is %x\n", final_candidate));
+			"IQK: final_candidate is %x\n", final_candidate);
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx "
-			"regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ",
+			"IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
 			rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
-			regecc));
+			regecc);
 		patha_ok = pathb_ok = true;
 	} else {
 		rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */
@@ -2618,7 +2605,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
 			true;
 
 		RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
-			 ("\nIQK OK indexforchannel %d.\n", indexforchannel));
+			 "IQK OK indexforchannel %d\n", indexforchannel);
 	}
 }
 
@@ -2629,17 +2616,17 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
 	struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 	u8 indexforchannel;
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel);
 	/*------Do IQK for normal chip and test chip 5G band------- */
 	indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-		("indexforchannel %d done %d\n", indexforchannel,
-		rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n",
+		 indexforchannel,
+		 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done);
 	if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done &&
 		rtlphy->need_iqk) {
 		/* Re Do IQK. */
 		RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
-			 ("Do IQK Matrix reg for channel:%d....\n", channel));
+			 "Do IQK Matrix reg for channel:%d....\n", channel);
 		rtl92d_phy_iq_calibrate(hw);
 	} else {
 		/* Just load the value. */
@@ -2647,8 +2634,8 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
 		if (((!rtlhal->load_imrandiqk_setting_for2g) &&
 		    indexforchannel == 0) || indexforchannel > 0) {
 			RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
-				 ("Just Read IQK Matrix reg for channel:%d"
-				 "....\n", channel));
+				 "Just Read IQK Matrix reg for channel:%d....\n",
+				 channel);
 			if ((rtlphy->iqk_matrix_regsetting[indexforchannel].
 			     value[0] != NULL)
 				/*&&(regea4 != 0) */)
@@ -2672,7 +2659,7 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
 		}
 	}
 	rtlphy->need_iqk = false;
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2)
@@ -2727,8 +2714,8 @@ static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
 			}
 		}
 		smallest_abs_val = 0xffffffff;
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i,
-			curveindex[i]));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n",
+			i, curveindex[i]);
 	}
 }
 
@@ -2743,14 +2730,14 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
 	u32 u4tmp = 0, u4regvalue = 0;
 	bool bneed_powerdown_radio = false;
 
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath));
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n",
-		rtlpriv->rtlhal.current_bandtype));
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath);
+	RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n",
+		rtlpriv->rtlhal.current_bandtype);
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "channel = %d\n", channel);
 	if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
 		u4tmp = curveindex_5g[channel-1];
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("ver 1 set RF-A, 5G,	0x28 = 0x%ulx !!\n", u4tmp));
+			"ver 1 set RF-A, 5G,	0x28 = 0x%ulx !!\n", u4tmp);
 		if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
 			rtlpriv->rtlhal.interfaceindex == 1) {
 			bneed_powerdown_radio =
@@ -2769,7 +2756,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
 	} else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
 		u4tmp = curveindex_2g[channel-1];
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp));
+			"ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp);
 		if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
 			rtlpriv->rtlhal.interfaceindex == 0) {
 			bneed_powerdown_radio =
@@ -2781,14 +2768,14 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
 		}
 		rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
-			rtl_get_rfreg(hw,  erfpath, RF_SYN_G4, 0x3f800)));
+			"ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
+			rtl_get_rfreg(hw,  erfpath, RF_SYN_G4, 0x3f800));
 		if (bneed_powerdown_radio)
 			_rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
 		if (rtlpriv->rtlhal.during_mac0init_radiob)
 			rtl92d_phy_powerdown_anotherphy(hw, true);
 	}
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n"));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
 }
 
 static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
@@ -2836,20 +2823,20 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
 					      RF_SYN_G6, BRFREGOFFSETMASK);
 		}
 		RTPRINT(rtlpriv, FINIT, INIT_IQK,
-			("PHY_LCK finish delay for %d ms=2\n", timecount));
+			"PHY_LCK finish delay for %d ms=2\n", timecount);
 		u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK);
 		if (index == 0 && rtlhal->interfaceindex == 0) {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("path-A / 5G LCK\n"));
+				"path-A / 5G LCK\n");
 		} else {
 			RTPRINT(rtlpriv, FINIT, INIT_IQK,
-				("path-B / 2.4G LCK\n"));
+				"path-B / 2.4G LCK\n");
 		}
 		memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2);
 		/* Set LC calibration off */
 		rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
 			      0x08000, 0x0);
-		RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n"));
+		RTPRINT(rtlpriv, FINIT, INIT_IQK,  "set RF 0x18[15] = 0\n");
 		/* save Curve-counting number */
 		for (i = 0; i < CV_CURVE_CNT; i++) {
 			u32 readval = 0, readval2 = 0;
@@ -2899,7 +2886,7 @@ static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "cosa PHY_LCK ver=2\n");
 	_rtl92d_phy_lc_calibrate_sw(hw, is2t);
 }
 
@@ -2917,8 +2904,8 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
 
 	rtlphy->lck_inprogress = true;
 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
-		("LCK:Start!!! currentband %x delay %d ms\n",
-		 rtlhal->current_bandtype, timecount));
+		"LCK:Start!!! currentband %x delay %d ms\n",
+		rtlhal->current_bandtype, timecount);
 	if (IS_92D_SINGLEPHY(rtlhal->version)) {
 		_rtl92d_phy_lc_calibrate(hw, true);
 	} else {
@@ -2926,7 +2913,7 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
 		_rtl92d_phy_lc_calibrate(hw, false);
 	}
 	rtlphy->lck_inprogress = false;
-	RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n"));
+	RTPRINT(rtlpriv, FINIT, INIT_IQK,  "LCK:Finish!!!\n");
 }
 
 void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
@@ -2941,7 +2928,7 @@ static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
 	struct swchnlcmd *pcmd;
 
 	if (cmdtable == NULL) {
-		RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+		RT_ASSERT(false, "cmdtable cannot be NULL\n");
 		return false;
 	}
 	if (cmdtableidx >= cmdtablesz)
@@ -2962,10 +2949,10 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
 	u8 i;
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			("settings regs %d default regs %d\n",
-			(int)(sizeof(rtlphy->iqk_matrix_regsetting) /
-			sizeof(struct iqk_matrix_regs)),
-			IQK_MATRIX_REG_NUM));
+		 "settings regs %d default regs %d\n",
+		 (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
+		       sizeof(struct iqk_matrix_regs)),
+		 IQK_MATRIX_REG_NUM);
 	/* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
 	for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
 		rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100;
@@ -3084,7 +3071,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 		break;
@@ -3111,7 +3098,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
 
 	if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
 		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
-			 ("sw_chnl_inprogress false driver sleep or unload\n"));
+			 "sw_chnl_inprogress false driver sleep or unload\n");
 		return 0;
 	}
 	while (rtlphy->lck_inprogress && timecount < timeout) {
@@ -3133,19 +3120,18 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
 		 * 5G and 2.4G band. */
 		if (channel <= 14)
 			return 0;
-		RT_ASSERT((channel > 14), ("5G but channel<=14"));
+		RT_ASSERT((channel > 14), "5G but channel<=14\n");
 		break;
 	case BAND_ON_2_4G:
 		/* Get first channel error when change between
 		 * 5G and 2.4G band. */
 		if (channel > 14)
 			return 0;
-		RT_ASSERT((channel <= 14), ("2G but channel>14"));
+		RT_ASSERT((channel <= 14), "2G but channel>14\n");
 		break;
 	default:
-		RT_ASSERT(false,
-			  ("Invalid WirelessMode(%#x)!!\n",
-			   rtlpriv->mac80211.mode));
+		RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n",
+			  rtlpriv->mac80211.mode);
 		break;
 	}
 	rtlphy->sw_chnl_inprogress = true;
@@ -3154,7 +3140,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
 	rtlphy->sw_chnl_stage = 0;
 	rtlphy->sw_chnl_step = 0;
 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-		 ("switch to channel%d\n", rtlphy->current_channel));
+		 "switch to channel%d\n", rtlphy->current_channel);
 
 	do {
 		if (!rtlphy->sw_chnl_inprogress)
@@ -3171,7 +3157,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
 		}
 		break;
 	} while (true);
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 	rtlphy->sw_chnl_inprogress = false;
 	return 1;
 }
@@ -3182,8 +3168,8 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 
 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-		 ("--->Cmd(%#x), set_io_inprogress(%d)\n",
-		 rtlphy->current_io_type, rtlphy->set_io_inprogress));
+		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
+		 rtlphy->current_io_type, rtlphy->set_io_inprogress);
 	switch (rtlphy->current_io_type) {
 	case IO_CMD_RESUME_DM_BY_SCAN:
 		de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
@@ -3197,12 +3183,12 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	rtlphy->set_io_inprogress = false;
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-		 ("<---(%#x)\n", rtlphy->current_io_type));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
+		 rtlphy->current_io_type);
 }
 
 bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
@@ -3212,23 +3198,23 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
 	bool postprocessing = false;
 
 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-		 ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
-		 iotype, rtlphy->set_io_inprogress));
+		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
+		 iotype, rtlphy->set_io_inprogress);
 	do {
 		switch (iotype) {
 		case IO_CMD_RESUME_DM_BY_SCAN:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-				 ("[IO CMD] Resume DM after scan.\n"));
+				 "[IO CMD] Resume DM after scan\n");
 			postprocessing = true;
 			break;
 		case IO_CMD_PAUSE_DM_BY_SCAN:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
-				 ("[IO CMD] Pause DM before scan.\n"));
+				 "[IO CMD] Pause DM before scan\n");
 			postprocessing = true;
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 	} while (false);
@@ -3239,7 +3225,7 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
 		return false;
 	}
 	rtl92d_phy_set_io(hw);
-	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
 	return true;
 }
 
@@ -3297,7 +3283,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
 		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			("Fail !!! Switch RF timeout.\n"));
+			 "Fail !!! Switch RF timeout\n");
 		return;
 	}
 	/* e.   For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */
@@ -3332,20 +3318,18 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
 			do {
 				InitializeCount++;
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-					 ("IPS Set eRf nic enable\n"));
+					 "IPS Set eRf nic enable\n");
 				rtstatus = rtl_ps_enable_nic(hw);
-			} while ((rtstatus != true) &&
-				 (InitializeCount < 10));
+			} while (!rtstatus && (InitializeCount < 10));
 
 			RT_CLEAR_PS_LEVEL(ppsc,
 					  RT_RF_OFF_LEVL_HALT_NIC);
 		} else {
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-				 ("awake, sleeped:%d ms state_"
-				 "inap:%x\n",
+				 "awake, sleeped:%d ms state_inap:%x\n",
 				 jiffies_to_msecs(jiffies -
-				 ppsc->last_sleep_jiffies),
-				 rtlpriv->psc.state_inap));
+						  ppsc->last_sleep_jiffies),
+				 rtlpriv->psc.state_inap);
 			ppsc->last_awake_jiffies = jiffies;
 			_rtl92d_phy_set_rfon(hw);
 		}
@@ -3360,7 +3344,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
 	case ERFOFF:
 		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-				 ("IPS Set eRf nic disable\n"));
+				 "IPS Set eRf nic disable\n");
 			rtl_ps_disable_nic(hw);
 			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 		} else {
@@ -3385,41 +3369,40 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
 				continue;
 			} else if (rtlpci->pdev->current_state != PCI_D0) {
 				RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-					 ("eRf Off/Sleep: %d times TcbBusyQueu"
-					 "e[%d] !=0 but lower power state!\n",
-					 (i + 1), queue_id));
+					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n",
+					 i + 1, queue_id);
 				break;
 			} else {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("eRf Off/Sleep: %d times TcbBusyQueu"
-					 "e[%d] =%d "
-					 "before doze!\n", (i + 1), queue_id,
-					  skb_queue_len(&ring->queue)));
+					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
+					 i + 1, queue_id,
+					 skb_queue_len(&ring->queue));
 				udelay(10);
 				i++;
 			}
 
 			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-					 ("\nERFOFF: %d times TcbBusyQueue[%d] "
-					 "= %d !\n",
-					  MAX_DOZE_WAITING_TIMES_9x, queue_id,
-					  skb_queue_len(&ring->queue)));
+					 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
+					 MAX_DOZE_WAITING_TIMES_9x, queue_id,
+					 skb_queue_len(&ring->queue));
 				break;
 			}
 		}
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-			 ("Set rfsleep awaked:%d ms\n",
-			 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)));
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms "
-			 "state_inap:%x\n", jiffies_to_msecs(jiffies -
-			 ppsc->last_awake_jiffies), rtlpriv->psc.state_inap));
+			 "Set rfsleep awaked:%d ms\n",
+			 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+			 "sleep awaked:%d ms state_inap:%x\n",
+			 jiffies_to_msecs(jiffies -
+					  ppsc->last_awake_jiffies),
+			 rtlpriv->psc.state_inap);
 		ppsc->last_sleep_jiffies = jiffies;
 		_rtl92d_phy_set_rfsleep(hw);
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		bresult = false;
 		break;
 	}
@@ -3437,17 +3420,17 @@ void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw)
 	switch (rtlhal->macphymode) {
 	case DUALMAC_DUALPHY:
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("MacPhyMode: DUALMAC_DUALPHY\n"));
+			 "MacPhyMode: DUALMAC_DUALPHY\n");
 		rtl_write_byte(rtlpriv, offset, 0xF3);
 		break;
 	case SINGLEMAC_SINGLEPHY:
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("MacPhyMode: SINGLEMAC_SINGLEPHY\n"));
+			 "MacPhyMode: SINGLEMAC_SINGLEPHY\n");
 		rtl_write_byte(rtlpriv, offset, 0xF4);
 		break;
 	case DUALMAC_SINGLEPHY:
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("MacPhyMode: DUALMAC_SINGLEPHY\n"));
+			 "MacPhyMode: DUALMAC_SINGLEPHY\n");
 		rtl_write_byte(rtlpriv, offset, 0xF1);
 		break;
 	}
@@ -3578,7 +3561,7 @@ void rtl92d_phy_set_poweron(struct ieee80211_hw *hw)
 			}
 		}
 		if (i == 200)
-			RT_ASSERT(false, ("Another mac power off over time\n"));
+			RT_ASSERT(false, "Another mac power off over time\n");
 	}
 }
 
@@ -3615,7 +3598,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	u8 rfpath, i;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
 	/* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */
 	if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 		/* r_select_5G for path_A/B,0x878 */
@@ -3764,7 +3747,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
 		} else {
 			rtl92d_phy_enable_anotherphy(hw, false);
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				 ("MAC1 use DBI to update 0x888"));
+				 "MAC1 use DBI to update 0x888\n");
 			/* 0x888 */
 			rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN,
 						rtl92de_read_dword_dbi(hw,
@@ -3789,9 +3772,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
 			BRFREGOFFSETMASK);
 	}
 	for (i = 0; i < 2; i++)
-		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n",
-			  rtlphy->rfreg_chnlval[i]));
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n"));
+		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n",
+			 rtlphy->rfreg_chnlval[i]);
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n");
 
 }
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
index a52c824..f074952 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
index 131acc3..9bc4623 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
index db27ceb..3066a7f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -50,8 +50,8 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
 				      BIT(11), 0x01);
 
 			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
-				 ("20M RF 0x18 = 0x%x\n",
-				 rtlphy->rfreg_chnlval[rfpath]));
+				 "20M RF 0x18 = 0x%x\n",
+				 rtlphy->rfreg_chnlval[rfpath]);
 		}
 
 		break;
@@ -62,13 +62,13 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
 			rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
 				      0x00);
 			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
-				 ("40M RF 0x18 = 0x%x\n",
-				 rtlphy->rfreg_chnlval[rfpath]));
+				 "40M RF 0x18 = 0x%x\n",
+				 rtlphy->rfreg_chnlval[rfpath]);
 		}
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", bandwidth));
+			 "unknown bandwidth: %#X\n", bandwidth);
 		break;
 	}
 }
@@ -127,23 +127,23 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
 	tmpval = tx_agc[RF90_PATH_A] & 0xff;
 	rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-		RTXAGC_A_CCK1_MCS32));
+		"CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_A_CCK1_MCS32);
 	tmpval = tx_agc[RF90_PATH_A] >> 8;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
-		RTXAGC_B_CCK11_A_CCK2_11));
+		"CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 	tmpval = tx_agc[RF90_PATH_B] >> 24;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-		RTXAGC_B_CCK11_A_CCK2_11));
+		"CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 	tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
 	rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-		("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
-		RTXAGC_B_CCK1_55_MCS32));
+		"CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
+		tmpval, RTXAGC_B_CCK1_55_MCS32);
 }
 
 static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
@@ -165,8 +165,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
 		    (powerbase0 << 8) | powerbase0;
 		*(ofdmbase + i) = powerbase0;
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			(" [OFDM power base index rf(%c) = 0x%x]\n",
-			((i == 0) ? 'A' : 'B'), *(ofdmbase + i)));
+			" [OFDM power base index rf(%c) = 0x%x]\n",
+			i == 0 ? 'A' : 'B', *(ofdmbase + i));
 	}
 
 	for (i = 0; i < 2; i++) {
@@ -179,8 +179,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
 			     (powerbase1 << 8) | powerbase1;
 		*(mcsbase + i) = powerbase1;
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			(" [MCS power base index rf(%c) = 0x%x]\n",
-			((i == 0) ? 'A' : 'B'), *(mcsbase + i)));
+			" [MCS power base index rf(%c) = 0x%x]\n",
+			i == 0 ? 'A' : 'B', *(mcsbase + i));
 	}
 }
 
@@ -232,9 +232,9 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 					(rf ? 8 : 0)] + ((index < 2) ?
 					powerbase0[rf] :
 					powerbase1[rf]);
-			RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
-				"performance, writeval(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeval));
+			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+				"RTK better performance, writeval(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeval);
 			break;
 		case 1:
 			if (rtlphy->pwrgroup_cnt == 1)
@@ -253,33 +253,31 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 						powerbase0[rf] :
 						powerbase1[rf]);
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("Realtek regulatory, "
-					"20MHz, writeval(%c) = 0x%x\n",
-					((rf == 0) ? 'A' : 'B'),
-					writeval));
+					"Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B', writeval);
 			}
 			break;
 		case 2:
 			writeval = ((index < 2) ? powerbase0[rf] :
 				   powerbase1[rf]);
-			RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, "
-				"writeval(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeval));
+			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
+				"Better regulatory, writeval(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeval);
 			break;
 		case 3:
 			chnlgroup = 0;
 			if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("customer's limit, 40MHz rf(%c) = "
-					"0x%x\n", ((rf == 0) ? 'A' : 'B'),
+					"customer's limit, 40MHz rf(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B',
 					rtlefuse->pwrgroup_ht40[rf]
-					[channel - 1]));
+					[channel - 1]);
 			} else {
 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-					("customer's limit, 20MHz rf(%c) = "
-					"0x%x\n", ((rf == 0) ? 'A' : 'B'),
+					"customer's limit, 20MHz rf(%c) = 0x%x\n",
+					rf == 0 ? 'A' : 'B',
 					rtlefuse->pwrgroup_ht20[rf]
-					[channel - 1]));
+					[channel - 1]);
 			}
 			for (i = 0; i < 4; i++) {
 				pwr_diff_limit[i] =
@@ -308,13 +306,13 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 					 (pwr_diff_limit[1] << 8) |
 					 (pwr_diff_limit[0]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Customer's limit rf(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), customer_limit));
+				"Customer's limit rf(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', customer_limit);
 			writeval = customer_limit + ((index < 2) ?
 				   powerbase0[rf] : powerbase1[rf]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("Customer, writeval rf(%c)= 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeval));
+				"Customer, writeval rf(%c)= 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeval);
 			break;
 		default:
 			chnlgroup = 0;
@@ -323,9 +321,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 				   (rf ? 8 : 0)] + ((index < 2) ?
 				   powerbase0[rf] : powerbase1[rf]);
 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-				("RTK better performance, writeval "
-				"rf(%c) = 0x%x\n",
-				((rf == 0) ? 'A' : 'B'), writeval));
+				"RTK better performance, writeval rf(%c) = 0x%x\n",
+				rf == 0 ? 'A' : 'B', writeval);
 			break;
 		}
 		*(p_outwriteval + rf) = writeval;
@@ -367,7 +364,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
 			regoffset = regoffset_b[index];
 		rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval);
 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
-			("Set 0x%x = %08x\n", regoffset, writeval));
+			"Set 0x%x = %08x\n", regoffset, writeval);
 		if (((get_rf_type(rtlphy) == RF_2T2R) &&
 		    (regoffset == RTXAGC_A_MCS15_MCS12 ||
 		    regoffset == RTXAGC_B_MCS15_MCS12)) ||
@@ -423,11 +420,11 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 
 	rtlhal->during_mac0init_radiob = false;
 	rtlhal->during_mac1init_radioa = false;
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n");
 	/* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
 	u1btmp = rtl_read_byte(rtlpriv, mac_reg);
 	if (!(u1btmp & mac_on_bit)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n");
 		/* Enable BB and RF power */
 		rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
 			rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
@@ -437,7 +434,7 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 		 * and radio_b.txt has been load. */
 		bresult = false;
 	}
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n");
 	return bresult;
 
 }
@@ -453,17 +450,17 @@ void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 
 	rtlhal->during_mac0init_radiob = false;
 	rtlhal->during_mac1init_radioa = false;
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
 	/* check MAC0 enable or not again now, if
 	 * enabled, not power down radio A. */
 	u1btmp = rtl_read_byte(rtlpriv, mac_reg);
 	if (!(u1btmp & mac_on_bit)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n");
 		/* power down RF radio A according to YuNan's advice. */
 		rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
 					0x00000000, direct);
 	}
-	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
 }
 
 bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
@@ -604,9 +601,9 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
 				      u4_regvalue);
 			break;
 		}
-		if (rtstatus != true) {
+		if (!rtstatus) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-				("Radio[%d] Fail!!", rfpath));
+				 "Radio[%d] Fail!!", rfpath);
 			goto phy_rf_cfg_fail;
 		}
 
@@ -620,7 +617,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
 		rtl92d_phy_powerdown_anotherphy(hw, false);
 	else if (need_pwrdown_radiob)
 		rtl92d_phy_powerdown_anotherphy(hw, true);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
 	return rtstatus;
 
 phy_rf_cfg_fail:
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h
index 74b9cfc..0fe1a48 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index 7911c9c..4898c50 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,11 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
@@ -44,6 +39,8 @@
 #include "trx.h"
 #include "led.h"
 
+#include <linux/module.h>
+
 static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -94,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
 	u8 tid;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	const struct firmware *firmware;
 	static int header_print;
 
 	rtlpriv->dm.dm_initialgain_enable = true;
@@ -154,9 +150,9 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
 	if (!rtlpriv->psc.inactiveps)
-		pr_info("rtl8192ce: Power Save off (module option)\n");
+		pr_info("Power Save off (module option)\n");
 	if (!rtlpriv->psc.fwctrl_lps)
-		pr_info("rtl8192ce: FW Power Save off (module option)\n");
+		pr_info("FW Power Save off (module option)\n");
 	rtlpriv->psc.reg_fwctrl_lps = 3;
 	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
 	/* for ASPM, you can close aspm through
@@ -170,41 +166,38 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw)
 	else if (rtlpriv->psc.reg_fwctrl_lps == 3)
 		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
 
+	/* for early mode */
+	rtlpriv->rtlhal.earlymode_enable = true;
+	for (tid = 0; tid < 8; tid++)
+		skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
+
+	/* Only load firmware for first MAC */
+	if (header_print)
+		return 0;
+
 	/* for firmware buf */
 	rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
 	if (!rtlpriv->rtlhal.pfirmware) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't alloc buffer for fw.\n"));
+			 "Can't alloc buffer for fw\n");
 		return 1;
 	}
 
-	if (!header_print) {
-		pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
-		pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
-		header_print++;
-	}
+	rtlpriv->max_fw_size = 0x8000;
+	pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
+	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+	header_print++;
+
 	/* request fw */
-	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-			       rtlpriv->io.dev);
+	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+				      rtlpriv->io.dev, GFP_KERNEL, hw,
+				      rtl_fw_cb);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Failed to request firmware!\n"));
-		return 1;
-	}
-	if (firmware->size > 0x8000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
+			 "Failed to request firmware!\n");
 		return 1;
 	}
-	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-	rtlpriv->rtlhal.fwsize = firmware->size;
-	release_firmware(firmware);
 
-	/* for early mode */
-	rtlpriv->rtlhal.earlymode_enable = true;
-	for (tid = 0; tid < 8; tid++)
-		skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
 	return 0;
 }
 
@@ -424,7 +417,7 @@ static int __init rtl92de_module_init(void)
 
 	ret = pci_register_driver(&rtl92de_driver);
 	if (ret)
-		RT_ASSERT(false, (": No device found\n"));
+		RT_ASSERT(false, "No device found\n");
 	return ret;
 }
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h
index c95e47d..0e6035b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/rtlwifi/rtl8192de/table.c
index bad7f94..8ea6f52 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/rtlwifi/rtl8192de/table.h
index 93f30ca..8b724a8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/table.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index 3637c0c..a7f6126 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -602,8 +602,8 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
 					   EM_HDR_LEN);
 			if (ptcb_desc->empkt_num) {
 				RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD,
-					 ("Insert 8 byte.pTcb->EMPktNum:%d\n",
-					  ptcb_desc->empkt_num));
+					 "Insert 8 byte.pTcb->EMPktNum:%d\n",
+					 ptcb_desc->empkt_num);
 				_rtl92de_insert_emcontent(ptcb_desc,
 							  (u8 *)(skb->data));
 			}
@@ -700,7 +700,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
 		if (ieee80211_is_data_qos(fc)) {
 			if (mac->rdg_en) {
 				RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
-					("Enable RDG function.\n"));
+					 "Enable RDG function\n");
 				SET_TX_DESC_RDG_ENABLE(pdesc, 1);
 				SET_TX_DESC_HTC(pdesc, 1);
 			}
@@ -726,7 +726,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
 		SET_TX_DESC_PKT_ID(pdesc, 8);
 	}
 	SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 }
 
 void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
@@ -776,7 +776,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
 	}
 
 	RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
-		      "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE);
+		      "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
 	wmb();
 	SET_TX_DESC_OWN(pdesc, 1);
 }
@@ -793,8 +793,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR txdesc :%d"
-					  " not process\n", desc_name));
+			RT_ASSERT(false, "ERR txdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	} else {
@@ -813,8 +813,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 			SET_RX_DESC_EOR(pdesc, 1);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR rxdesc :%d "
-					  "not process\n", desc_name));
+			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	}
@@ -833,8 +833,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR txdesc :%d "
-					  "not process\n", desc_name));
+			RT_ASSERT(false, "ERR txdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	} else {
@@ -847,8 +847,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name)
 			ret = GET_RX_DESC_PKT_LEN(pdesc);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR rxdesc :%d "
-					  "not process\n", desc_name));
+			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
index 4d55d0b..0dc736c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index c6c0448..d1b0a1e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
index 4203a85..fbabae1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -170,9 +170,9 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
 	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
 
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
-		 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
-		  "eeprom_thermalmeter 0x%x\n", thermalvalue,
-		  rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+		 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
+		 thermalvalue,
+		 rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
 
 	if (thermalvalue) {
 		rtlpriv->dm.thermalvalue = thermalvalue;
@@ -282,11 +282,11 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
 		}
 
 		if (ra->pre_ratr_state != ra->ratr_state) {
-			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld "
-				"RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
-				rtlpriv->dm.undecorated_smoothed_pwdb,
-				ra->ratr_state,
-				ra->pre_ratr_state, ra->ratr_state));
+			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
+				 "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
+				 rtlpriv->dm.undecorated_smoothed_pwdb,
+				 ra->ratr_state,
+				 ra->pre_ratr_state, ra->ratr_state);
 
 			rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
 							   ra->ratr_state);
@@ -586,7 +586,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
 	if ((mac->link_state < MAC80211_LINKED) &&
 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
-			 ("Not connected to any\n"));
+			 "Not connected to any\n");
 
 		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
 
@@ -599,22 +599,22 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("AP Client PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "AP Client PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		} else {
 			undecorated_smoothed_pwdb =
 			    rtlpriv->dm.undecorated_smoothed_pwdb;
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("STA Default Port PWDB = 0x%lx\n",
-				  undecorated_smoothed_pwdb));
+				 "STA Default Port PWDB = 0x%lx\n",
+				 undecorated_smoothed_pwdb);
 		}
 	} else {
 		undecorated_smoothed_pwdb =
 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("AP Ext Port PWDB = 0x%lx\n",
-			  undecorated_smoothed_pwdb));
+			 "AP Ext Port PWDB = 0x%lx\n",
+			 undecorated_smoothed_pwdb);
 	}
 
 	txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
index 9051a55..e1b19a6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
index 3fda6b1..380e7d4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -66,7 +66,7 @@ static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw)
 		cpustatus = rtl_read_byte(rtlpriv, TCR);
 		if (cpustatus & IMEM_RDY) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				("IMEM Ready after CPU has refilled.\n"));
+				 "IMEM Ready after CPU has refilled\n");
 			break;
 		}
 
@@ -120,9 +120,8 @@ static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
 		return 0x22;
 		break;
 	default:
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("Unknown RF type(%x)\n",
-			 rtlphy->rf_type));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown RF type(%x)\n",
+			 rtlphy->rf_type);
 		break;
 	}
 	return 0x22;
@@ -177,7 +176,7 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
 
 	if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			("Size over FIRMWARE_CODE_SIZE!\n"));
+			 "Size over FIRMWARE_CODE_SIZE!\n");
 
 		return false;
 	}
@@ -231,8 +230,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 	short pollingcnt = 1000;
 	bool rtstatus = true;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n",
-		 loadfw_status));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 "LoadStaus(%d)\n", loadfw_status);
 
 	firmware->fwstatus = (enum fw_status)loadfw_status;
 
@@ -248,8 +247,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
 		if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("FW_STATUS_LOAD_IMEM"
-				 " FAIL CPU, Status=%x\r\n", cpustatus));
+				 "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n",
+				 cpustatus);
 			goto status_check_fail;
 		}
 		break;
@@ -266,16 +265,16 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
 		if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("FW_STATUS_LOAD_EMEM"
-				 " FAIL CPU, Status=%x\r\n", cpustatus));
+				 "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n",
+				 cpustatus);
 			goto status_check_fail;
 		}
 
 		/* Turn On CPU */
 		rtstatus = _rtl92s_firmware_enable_cpu(hw);
-		if (rtstatus != true) {
+		if (!rtstatus) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Enable CPU fail!\n"));
+				 "Enable CPU fail!\n");
 			goto status_check_fail;
 		}
 		break;
@@ -291,14 +290,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
 		if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Polling  DMEM code done"
-				 " fail ! cpustatus(%#x)\n", cpustatus));
+				 "Polling DMEM code done fail ! cpustatus(%#x)\n",
+				 cpustatus);
 			goto status_check_fail;
 		}
 
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("DMEM code download success,"
-			" cpustatus(%#x)\n", cpustatus));
+			 "DMEM code download success, cpustatus(%#x)\n",
+			 cpustatus);
 
 		/* Prevent Delay too much and being scheduled out */
 		/* Polling Load Firmware ready */
@@ -311,14 +310,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 		} while (pollingcnt--);
 
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("Polling Load Firmware ready,"
-			" cpustatus(%x)\n",	cpustatus));
+			 "Polling Load Firmware ready, cpustatus(%x)\n",
+			 cpustatus);
 
 		if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
 		    (pollingcnt <= 0)) {
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Polling Load Firmware"
-				" ready fail ! cpustatus(%x)\n", cpustatus));
+				 "Polling Load Firmware ready fail ! cpustatus(%x)\n",
+				 cpustatus);
 			goto status_check_fail;
 		}
 
@@ -332,7 +331,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 				RCR_APP_ICV | RCR_APP_MIC));
 
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			 ("Current RCR settings(%#x)\n", tmpu4b));
+			 "Current RCR settings(%#x)\n", tmpu4b);
 
 		/* Set to normal mode. */
 		rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL);
@@ -340,14 +339,15 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
 
 	default:
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("Unknown status check!\n"));
+			 "Unknown status check!\n");
 		rtstatus = false;
 		break;
 	}
 
 status_check_fail:
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), "
-		 "rtstatus(%x)\n", loadfw_status, rtstatus));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 "loadfw_status(%d), rtstatus(%x)\n",
+		 loadfw_status, rtstatus);
 	return rtstatus;
 }
 
@@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
 	u8 fwstatus = FW_STATUS_INIT;
 	bool rtstatus = true;
 
-	if (!rtlhal->pfirmware)
+	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
 		return 1;
 
 	firmware = (struct rt_firmware *)rtlhal->pfirmware;
@@ -378,17 +378,17 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
 	firmware->firmwareversion =  byte(pfwheader->version, 0);
 	firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:"
-		 "%x, size:%x,"
-		 "imemsize:%x, sram size:%x\n", pfwheader->signature,
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n",
+		 pfwheader->signature,
 		 pfwheader->version, pfwheader->dmem_size,
-		 pfwheader->img_imem_size, pfwheader->img_sram_size));
+		 pfwheader->img_imem_size, pfwheader->img_sram_size);
 
 	/* 2. Retrieve IMEM image. */
 	if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size >
 	    sizeof(firmware->fw_imem))) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			("memory for data image is less than IMEM required\n"));
+			 "memory for data image is less than IMEM required\n");
 		goto fail;
 	} else {
 		puc_mappedfile += fwhdr_size;
@@ -401,7 +401,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
 	/* 3. Retriecve EMEM image. */
 	if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			("memory for data image is less than EMEM required\n"));
+			 "memory for data image is less than EMEM required\n");
 		goto fail;
 	} else {
 		puc_mappedfile += firmware->fw_imem_len;
@@ -436,7 +436,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-					("Unexpected Download step!!\n"));
+				 "Unexpected Download step!!\n");
 			goto fail;
 			break;
 		}
@@ -445,15 +445,15 @@ int rtl92s_download_fw(struct ieee80211_hw *hw)
 		rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile,
 				ul_filelength);
 
-		if (rtstatus != true) {
-			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+		if (!rtstatus) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n");
 			goto fail;
 		}
 
 		/* <3> Check whether load FW process is ready */
 		rtstatus = _rtl92s_firmware_checkready(hw, fwstatus);
-		if (rtstatus != true) {
-			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+		if (!rtstatus) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n");
 			goto fail;
 		}
 
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
index 74cc503..babe85d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index c474486..b141c35 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
@@ -80,8 +78,8 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			break;
 		}
 	default: {
-			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "switch case not processed\n");
 			break;
 		}
 	}
@@ -140,7 +138,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			u8 e_aci;
 
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("HW_VAR_SLOT_TIME %x\n", val[0]));
+				 "HW_VAR_SLOT_TIME %x\n", val[0]);
 
 			rtl_write_byte(rtlpriv, SLOT_TIME, val[0]);
 
@@ -185,8 +183,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 				*val = min_spacing_to_set;
 
 				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-					 ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
-					  mac->min_space_cfg));
+					 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+					 mac->min_space_cfg);
 
 				rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
 					       mac->min_space_cfg);
@@ -201,8 +199,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 			mac->min_space_cfg |= (density_to_set << 3);
 
 			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
-				  mac->min_space_cfg));
+				 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+				 mac->min_space_cfg);
 
 			rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
 				       mac->min_space_cfg);
@@ -244,8 +242,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 				rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset);
 
 				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-					 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
-					  factor_toset));
+					 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
+					 factor_toset);
 			}
 			break;
 		}
@@ -282,8 +280,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					break;
 				default:
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("HW_VAR_ACM_CTRL acm set "
-						  "failed: eACI is %d\n", acm));
+						 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
+						 acm);
 					break;
 				}
 			} else {
@@ -299,13 +297,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 					break;
 				default:
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-						 ("switch case not process\n"));
+						 "switch case not processed\n");
 					break;
 				}
 			}
 
 			RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
-				 ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl));
+				 "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl);
 			rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl);
 			break;
 		}
@@ -404,7 +402,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 		}
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 
@@ -415,14 +413,14 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u8 sec_reg_value = 0x0;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d "
-		 "GroupEncAlgorithm = %d\n",
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
 		 rtlpriv->sec.pairwise_enc_algorithm,
-		 rtlpriv->sec.group_enc_algorithm));
+		 rtlpriv->sec.group_enc_algorithm);
 
 	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-			 ("not open hw encryption\n"));
+			 "not open hw encryption\n");
 		return;
 	}
 
@@ -433,8 +431,8 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
 		sec_reg_value |= SCR_RXUSEDK;
 	}
 
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n",
-			sec_reg_value));
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n",
+		 sec_reg_value);
 
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 
@@ -718,8 +716,8 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
 
 	if (pollingcnt <= 0) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Polling TXDMA_INIT_VALUE "
-			 "timeout!! Current TCR(%#x)\n", tmpu1b));
+			 "Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n",
+			 tmpu1b);
 		tmpu1b = rtl_read_byte(rtlpriv, CMDR);
 		rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN));
 		udelay(2);
@@ -870,10 +868,10 @@ static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw)
 
 		/* Change Program timing */
 		rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72);
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n");
 	}
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n");
 
 }
 
@@ -951,12 +949,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 	rtstatus = rtl92s_download_fw(hw);
 	if (!rtstatus) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Failed to download FW. "
-			 "Init HW without FW now.., Please copy FW into"
-			 "/lib/firmware/rtlwifi\n"));
-		rtlhal->fw_ready = false;
-	} else {
-		rtlhal->fw_ready = true;
+			 "Failed to download FW. Init HW without FW now... "
+			 "Please copy FW into /lib/firmware/rtlwifi\n");
+		return 1;
 	}
 
 	/* After FW download, we have to reset MAC register */
@@ -967,8 +962,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 	rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK);
 
 	/* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
-	if (rtl92s_phy_mac_config(hw) != true) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n"));
+	if (!rtl92s_phy_mac_config(hw)) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n");
 		return rtstatus;
 	}
 
@@ -977,8 +972,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 	rtl_write_dword(rtlpriv, CMDR, 0x37FC);
 
 	/* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
-	if (rtl92s_phy_bb_config(hw) != true) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n"));
+	if (!rtl92s_phy_bb_config(hw)) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n");
 		return rtstatus;
 	}
 
@@ -1013,8 +1008,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
 	else
 		rtl_write_byte(rtlpriv, RF_CTRL, 0x07);
 
-	if (rtl92s_phy_rf_config(hw) != true) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n"));
+	if (!rtl92s_phy_rf_config(hw)) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n");
 		return rtstatus;
 	}
 
@@ -1110,7 +1105,7 @@ void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
 	if (check_bssid) {
 		reg_rcr |= (RCR_CBSSID);
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
-	} else if (check_bssid == false) {
+	} else if (!check_bssid) {
 		reg_rcr &= (~RCR_CBSSID);
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
 	}
@@ -1129,26 +1124,26 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
 	case NL80211_IFTYPE_UNSPECIFIED:
 		bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to NO LINK!\n"));
+			 "Set Network type to NO LINK!\n");
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to Ad Hoc!\n"));
+			 "Set Network type to Ad Hoc!\n");
 		break;
 	case NL80211_IFTYPE_STATION:
 		bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to STA!\n"));
+			 "Set Network type to STA!\n");
 		break;
 	case NL80211_IFTYPE_AP:
 		bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
-			 ("Set Network type to AP!\n"));
+			 "Set Network type to AP!\n");
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Network type %d not support!\n", type));
+			 "Network type %d not supported!\n", type);
 		return 1;
 		break;
 
@@ -1202,7 +1197,7 @@ void rtl92se_set_qos(struct ieee80211_hw *hw, int aci)
 		rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222);
 		break;
 	default:
-		RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+		RT_ASSERT(false, "invalid aci: %d !\n", aci);
 		break;
 	}
 }
@@ -1219,9 +1214,14 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
 
 void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
 {
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_priv *rtlpriv;
+	struct rtl_pci *rtlpci;
 
+	rtlpriv = rtl_priv(hw);
+	/* if firmware not available, no interrupts */
+	if (!rtlpriv || !rtlpriv->max_fw_size)
+		return;
+	rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	rtl_write_dword(rtlpriv, INTA_MASK, 0);
 	rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
 
@@ -1583,8 +1583,8 @@ void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 
-	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
-		 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
+		 add_msr, rm_msr);
 
 	if (add_msr)
 		rtlpci->irq_mask[0] |= add_msr;
@@ -1627,7 +1627,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 
 	if (rtlefuse->epromtype == EEPROM_93C46) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("RTL819X Not boot from eeprom, check it !!"));
+			 "RTL819X Not boot from eeprom, check it !!\n");
 	} else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
 		rtl_efuse_shadow_map_update(hw);
 
@@ -1636,16 +1636,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 			HWSET_MAX_SIZE_92S);
 	}
 
-	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
 		      hwinfo, HWSET_MAX_SIZE_92S);
 
 	eeprom_id = *((u16 *)&hwinfo[0]);
 	if (eeprom_id != RTL8190_EEPROM_ID) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+			 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
 		rtlefuse->autoload_failflag = true;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 		rtlefuse->autoload_failflag = false;
 	}
 
@@ -1663,15 +1663,15 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
 
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			("EEPROMId = 0x%4x\n", eeprom_id));
+		 "EEPROMId = 0x%4x\n", eeprom_id);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+		 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+		 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+		 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-			("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+		 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
 
 	for (i = 0; i < 6; i += 2) {
 		usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
@@ -1681,8 +1681,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 	for (i = 0; i < 6; i++)
 		rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-		 ("%pM\n", rtlefuse->dev_addr));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
 
 	/* Get Tx Power Level by Channel */
 	/* Read Tx power of Channel 1 ~ 14 from EEPROM. */
@@ -1707,23 +1706,24 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
-				i, rtlefuse->eeprom_chnlarea_txpwr_cck
-					[rf_path][i]));
+				"RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->eeprom_chnlarea_txpwr_cck
+				[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
-						[rf_path][i]));
+				"RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
+				[rf_path][i]);
 	for (rf_path = 0; rf_path < 2; rf_path++)
 		for (i = 0; i < 3; i++)
 			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
-				("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
-					[rf_path][i]));
+				"RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+				rf_path, i,
+				rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
+				[rf_path][i]);
 
 	for (rf_path = 0; rf_path < 2; rf_path++) {
 
@@ -1754,11 +1754,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 
 		for (i = 0; i < 14; i++) {
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
-				 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
-				 rtlefuse->txpwrlevel_cck[rf_path][i],
-				 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
-				 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+				"RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
+				rf_path, i,
+				rtlefuse->txpwrlevel_cck[rf_path][i],
+				rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+				rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
 		}
 	}
 
@@ -1791,13 +1791,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 				0xf0) >> 4);
 
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->pwrgroup_ht20[rf_path][i]));
+				"RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+				rf_path, i,
+				rtlefuse->pwrgroup_ht20[rf_path][i]);
 			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-				("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
-				 rf_path, i,
-				 rtlefuse->pwrgroup_ht40[rf_path][i]));
+				"RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+				rf_path, i,
+				rtlefuse->pwrgroup_ht40[rf_path][i]);
 			}
 	}
 
@@ -1852,27 +1852,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 				 (hwinfo[EEPROM_REGULATORY] & 0x1);
 	}
 	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-		("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+		"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+			"RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+			"RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+			"RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
 	for (i = 0; i < 14; i++)
 		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
-			("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
-			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+			"RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
+			i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 
-	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n",
-		rtlefuse->txpwr_safetyflag));
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+		"TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag);
 
 	/* Read RF-indication and Tx Power gain
 	 * index diff of legacy to HT OFDM rate. */
@@ -1881,8 +1881,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 	rtlefuse->legacy_httxpowerdiff =
 		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
 
-	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n",
-		rtlefuse->eeprom_txpowerdiff));
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+		"TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff);
 
 	/* Get TSSI value for each path. */
 	usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A];
@@ -1890,16 +1890,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 	usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B];
 	rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
 
-	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
-		 rtlefuse->eeprom_tssi[RF90_PATH_A],
-		 rtlefuse->eeprom_tssi[RF90_PATH_B]));
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+		rtlefuse->eeprom_tssi[RF90_PATH_A],
+		rtlefuse->eeprom_tssi[RF90_PATH_B]);
 
 	/* Read antenna tx power offset of B/C/D to A  from EEPROM */
 	/* and read ThermalMeter from EEPROM */
 	tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER];
 	rtlefuse->eeprom_thermalmeter = tempval;
-	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n",
-		rtlefuse->eeprom_thermalmeter));
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+		"thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 
 	/* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
 	rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
@@ -1915,8 +1915,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 	/* Version ID, Channel plan */
 	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
 	rtlefuse->txpwr_fromeprom = true;
-	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n",
-		rtlefuse->eeprom_channelplan));
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+		"EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan);
 
 	/* Read Customer ID or Board Type!!! */
 	tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE];
@@ -1937,14 +1937,14 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
 		if (!(tempval & BIT(0))) {
 			rtlefuse->b1x1_recvcombine = true;
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-				("RF_TYPE=1T2R but only 1SS\n"));
+				 "RF_TYPE=1T2R but only 1SS\n");
 		}
 	}
 	rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
 	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID];
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x",
-			rtlefuse->eeprom_oemid));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x",
+		 rtlefuse->eeprom_oemid);
 
 	/* set channel paln to world wide 13 */
 	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
@@ -1959,19 +1959,19 @@ void rtl92se_read_eeprom_info(struct ieee80211_hw *hw)
 	tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD);
 
 	if (tmp_u1b & BIT(4)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
 		rtlefuse->epromtype = EEPROM_93C46;
 	} else {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
 		rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
 	}
 
 	if (tmp_u1b & BIT(5)) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 		rtlefuse->autoload_failflag = false;
 		_rtl92se_read_adapter_info(hw);
 	} else {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
 		rtlefuse->autoload_failflag = true;
 	}
 }
@@ -2071,8 +2071,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
 	else
 		rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG);
 
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
-		 ("%x\n", rtl_read_dword(rtlpriv, ARFR0)));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
+		 rtl_read_dword(rtlpriv, ARFR0));
 }
 
 static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
@@ -2224,8 +2224,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
 
 	mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf);
 
-	RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n",
-			mask, ratr_bitmap));
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n",
+		 mask, ratr_bitmap);
 	rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap);
 	rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8)));
 
@@ -2301,14 +2301,14 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
 
 	if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) {
 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("RFKILL-HW Radio ON, RF ON\n"));
+			 "RFKILL-HW Radio ON, RF ON\n");
 
 		rfpwr_toset = ERFON;
 		ppsc->hwradiooff = false;
 		actuallyset = true;
-	} else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) {
-		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-			 ("RFKILL-HW Radio OFF, RF OFF\n"));
+	} else if ((!ppsc->hwradiooff) && (rfpwr_toset == ERFOFF)) {
+		RT_TRACE(rtlpriv, COMP_RF,
+			 DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n");
 
 		rfpwr_toset = ERFOFF;
 		ppsc->hwradiooff = true;
@@ -2372,7 +2372,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
 		u8 cam_offset = 0;
 		u8 clear_number = 5;
 
-		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
 
 		for (idx = 0; idx < clear_number; idx++) {
 			rtl_cam_mark_invalid(hw, cam_offset + idx);
@@ -2401,7 +2401,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-					("switch case not process\n"));
+				 "switch case not processed\n");
 			enc_algo = CAM_TKIP;
 			break;
 		}
@@ -2419,9 +2419,8 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
 								 p_macaddr);
 					if (entry_id >=  TOTAL_CAM_ENTRY) {
 						RT_TRACE(rtlpriv,
-						   COMP_SEC, DBG_EMERG,
-						   ("Can not find free hw"
-						   " security cam entry\n"));
+							 COMP_SEC, DBG_EMERG,
+							 "Can not find free hw security cam entry\n");
 						return;
 					}
 				} else {
@@ -2435,30 +2434,31 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
 
 		if (rtlpriv->sec.key_len[key_index] == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("delete one entry, entry_id is %d\n",
-				 entry_id));
+				 "delete one entry, entry_id is %d\n",
+				 entry_id);
 			if (mac->opmode == NL80211_IFTYPE_AP)
 				rtl_cam_del_entry(hw, p_macaddr);
 			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 		} else {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY length is %d\n",
-				  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+				 "The insert KEY length is %d\n",
+				 rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
-				 ("The insert KEY  is %x %x\n",
-				  rtlpriv->sec.key_buf[0][0],
-				  rtlpriv->sec.key_buf[0][1]));
+				 "The insert KEY is %x %x\n",
+				 rtlpriv->sec.key_buf[0][0],
+				 rtlpriv->sec.key_buf[0][1]);
 
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("add one entry\n"));
+				 "add one entry\n");
 			if (is_pairwise) {
 				RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
-				      "Pairwiase Key content :",
-				       rtlpriv->sec.pairwise_key,
-				       rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
+					      "Pairwise Key content",
+					      rtlpriv->sec.pairwise_key,
+					      rtlpriv->sec.
+					      key_len[PAIRWISE_KEYIDX]);
 
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set Pairwiase key\n"));
+					 "set Pairwise key\n");
 
 				rtl_cam_add_one_entry(hw, macaddr, key_index,
 					entry_id, enc_algo,
@@ -2466,7 +2466,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
 					rtlpriv->sec.key_buf[key_index]);
 			} else {
 				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-					 ("set group key\n"));
+					 "set group key\n");
 
 				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 					rtl_cam_add_one_entry(hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
index 6160a9b..1886c26 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
index e3fe7c9..44949b5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -52,8 +52,8 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 	u8 ledcfg;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 LEDCFG, pled->ledpin);
 
 	ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
 
@@ -68,7 +68,7 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = true;
@@ -76,12 +76,15 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 
 void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 {
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_priv *rtlpriv;
 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
 	u8 ledcfg;
 
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
-		 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+	rtlpriv = rtl_priv(hw);
+	if (!rtlpriv || rtlpriv->max_fw_size)
+		return;
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n",
+		 LEDCFG, pled->ledpin);
 
 	ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
 
@@ -101,7 +104,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		break;
 	}
 	pled->ledon = false;
@@ -141,8 +144,7 @@ void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
 	    ledaction == LED_CTL_POWER_ON)) {
 		return;
 	}
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
-		 ledaction));
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction);
 
 	_rtl92se_sw_led_control(hw, ledaction);
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h
index 8cce387..2182dbe 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/led.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
index f10ac1a..3bfc411 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "../pci.h"
 #include "../ps.h"
@@ -58,16 +56,15 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 returnvalue = 0, originalvalue, bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
-			regaddr, bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
+		 regaddr, bitmask);
 
 	originalvalue = rtl_read_dword(rtlpriv, regaddr);
 	bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
 	returnvalue = (originalvalue & bitmask) >> bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
-		 ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
-		 bitmask, regaddr, originalvalue));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+		 bitmask, regaddr, originalvalue);
 
 	return returnvalue;
 
@@ -79,8 +76,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 originalvalue, bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-			" data(%#x)\n", regaddr, bitmask, data));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+		 regaddr, bitmask, data);
 
 	if (bitmask != MASKDWORD) {
 		originalvalue = rtl_read_dword(rtlpriv, regaddr);
@@ -90,8 +88,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
 
 	rtl_write_dword(rtlpriv, regaddr, data);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-			" data(%#x)\n",	regaddr, bitmask, data));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
+		 regaddr, bitmask, data);
 
 }
 
@@ -149,8 +148,8 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
 	retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
 				 BLSSI_READBACK_DATA);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
-		 rfpath, pphyreg->rflssi_readback, retvalue));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rflssi_readback, retvalue);
 
 	return retvalue;
 
@@ -172,8 +171,8 @@ static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
 	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
-		 rfpath, pphyreg->rf3wire_offset, data_and_addr));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rf3wire_offset, data_and_addr);
 }
 
 
@@ -183,8 +182,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 original_value, readback_value, bitshift;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
-		 "bitmask(%#x)\n", regaddr, rfpath, bitmask));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
+		 regaddr, rfpath, bitmask);
 
 	spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -195,9 +195,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 
 	spin_unlock(&rtlpriv->locks.rf_lock);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
-		 "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
-		 bitmask, original_value));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
+		 regaddr, rfpath, bitmask, original_value);
 
 	return readback_value;
 }
@@ -212,8 +212,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 	if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
 		return;
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
-		 " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 
 	spin_lock(&rtlpriv->locks.rf_lock);
 
@@ -228,8 +229,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 
 	spin_unlock(&rtlpriv->locks.rf_lock);
 
-	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
-		 "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
+		 regaddr, bitmask, data, rfpath);
 
 }
 
@@ -249,7 +251,7 @@ void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("Unknown operation.\n"));
+				 "Unknown operation\n");
 			break;
 		}
 	}
@@ -264,9 +266,9 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	u8 reg_bw_opmode;
 
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
-		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
-		  "20MHz" : "40MHz"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
+		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+		 "20MHz" : "40MHz");
 
 	if (rtlphy->set_bwmode_inprogress)
 		return;
@@ -290,8 +292,7 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n",
-			 rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 
@@ -316,13 +317,13 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 		break;
 	}
 
 	rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 	rtlphy->set_bwmode_inprogress = false;
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 }
 
 static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
@@ -332,7 +333,7 @@ static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
 	struct swchnlcmd *pcmd;
 
 	if (cmdtable == NULL) {
-		RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+		RT_ASSERT(false, "cmdtable cannot be NULL\n");
 		return false;
 	}
 
@@ -377,7 +378,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 	rfdependcmdcnt = 0;
 
 	RT_ASSERT((channel >= 1 && channel <= 14),
-		  ("illegal channel for Zebra: %d\n", channel));
+		  "invalid channel for Zebra: %d\n", channel);
 
 	_rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 					 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
@@ -438,7 +439,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 			break;
 		default:
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not process\n"));
+				 "switch case not processed\n");
 			break;
 		}
 
@@ -458,9 +459,8 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
 	u32 delay;
 	bool ret;
 
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
-		 ("switch to channel%d\n",
-		 rtlphy->current_channel));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n",
+		 rtlphy->current_channel);
 
 	if (rtlphy->sw_chnl_inprogress)
 		return 0;
@@ -496,7 +496,7 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
 
 	rtlphy->sw_chnl_inprogress = false;
 
-	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 
 	return 1;
 }
@@ -556,20 +556,19 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
 				do {
 					InitializeCount++;
 					RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-						 ("IPS Set eRf nic enable\n"));
+						 "IPS Set eRf nic enable\n");
 					rtstatus = rtl_ps_enable_nic(hw);
-				} while ((rtstatus != true) &&
-					 (InitializeCount < 10));
+				} while (!rtstatus && (InitializeCount < 10));
 
 				RT_CLEAR_PS_LEVEL(ppsc,
 						  RT_RF_OFF_LEVL_HALT_NIC);
 			} else {
 				RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-					 ("awake, sleeped:%d ms "
-					"state_inap:%x\n",
-					jiffies_to_msecs(jiffies -
-					ppsc->last_sleep_jiffies),
-					rtlpriv->psc.state_inap));
+					 "awake, sleeped:%d ms state_inap:%x\n",
+					 jiffies_to_msecs(jiffies -
+							  ppsc->
+							  last_sleep_jiffies),
+					 rtlpriv->psc.state_inap);
 				ppsc->last_awake_jiffies = jiffies;
 				rtl_write_word(rtlpriv, CMDR, 0x37FC);
 				rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
@@ -587,7 +586,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
 	case ERFOFF:{
 			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
-					 ("IPS Set eRf nic disable\n"));
+					 "IPS Set eRf nic disable\n");
 				rtl_ps_disable_nic(hw);
 				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 			} else {
@@ -613,11 +612,9 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
 					continue;
 				} else {
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("eRf Off/Sleep: "
-						 "%d times TcbBusyQueue[%d] = "
-						 "%d before doze!\n",
-						 (i + 1), queue_id,
-						 skb_queue_len(&ring->queue)));
+						 "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n",
+						 i + 1, queue_id,
+						 skb_queue_len(&ring->queue));
 
 					udelay(10);
 					i++;
@@ -625,31 +622,30 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
 
 				if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("\nERFOFF: %d times"
-						 "TcbBusyQueue[%d] = %d !\n",
+						 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
 						 MAX_DOZE_WAITING_TIMES_9x,
 						 queue_id,
-						 skb_queue_len(&ring->queue)));
+						 skb_queue_len(&ring->queue));
 					break;
 				}
 			}
 
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-				 ("Set ERFSLEEP awaked:%d ms\n",
+				 "Set ERFSLEEP awaked:%d ms\n",
 				 jiffies_to_msecs(jiffies -
-				 ppsc->last_awake_jiffies)));
+						  ppsc->last_awake_jiffies));
 
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
-				 ("sleep awaked:%d ms "
-				"state_inap:%x\n", jiffies_to_msecs(jiffies -
-				ppsc->last_awake_jiffies),
-				rtlpriv->psc.state_inap));
+				 "sleep awaked:%d ms state_inap:%x\n",
+				 jiffies_to_msecs(jiffies -
+						  ppsc->last_awake_jiffies),
+				 rtlpriv->psc.state_inap);
 			ppsc->last_sleep_jiffies = jiffies;
 			_rtl92se_phy_set_rf_sleep(hw);
 	    break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("switch case not process\n"));
+			 "switch case not processed\n");
 		bresult = false;
 		break;
 	}
@@ -993,9 +989,9 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
 		rtstatus = false;
 	}
 
-	if (rtstatus != true) {
+	if (!rtstatus) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("Write BB Reg Fail!!"));
+			 "Write BB Reg Fail!!\n");
 		goto phy_BB8190_Config_ParaFile_Fail;
 	}
 
@@ -1007,17 +1003,16 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
 		rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
 						 BASEBAND_CONFIG_PHY_REG);
 	}
-	if (rtstatus != true) {
+	if (!rtstatus) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("_rtl92s_phy_bb_config_parafile(): "
-			 "BB_PG Reg Fail!!"));
+			 "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n");
 		goto phy_BB8190_Config_ParaFile_Fail;
 	}
 
 	/* 3. BB AGC table Initialization */
 	rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
 
-	if (rtstatus != true) {
+	if (!rtstatus) {
 		pr_err("%s(): AGC Table Fail\n", __func__);
 		goto phy_BB8190_Config_ParaFile_Fail;
 	}
@@ -1053,7 +1048,7 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
 		radio_b_tblen = RADIOB_ARRAYLENGTH;
 	}
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 	rtstatus = true;
 
 	switch (rfpath) {
@@ -1175,11 +1170,11 @@ bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
 	    (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
 	    (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("RF_Type(%x) does not match "
-			 "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
+			 "RF_Type(%x) does not match RF_Num(%x)!!\n",
+			 rtlphy->rf_type, rf_num);
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("path1 0x%x, path2 0x%x, pathmap "
-			  "0x%x\n", path1, path2, pathmap));
+			 "path1 0x%x, path2 0x%x, pathmap 0x%x\n",
+			 path1, path2, pathmap);
 	}
 
 	return rtstatus;
@@ -1214,20 +1209,20 @@ void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 			ROFDM0_XCAGCCORE1, MASKBYTE0);
 	rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
 			ROFDM0_XDAGCCORE1, MASKBYTE0);
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
-		 "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
 		 rtlphy->default_initialgain[0],
 		 rtlphy->default_initialgain[1],
 		 rtlphy->default_initialgain[2],
-		 rtlphy->default_initialgain[3]));
+		 rtlphy->default_initialgain[3]);
 
 	/* read framesync */
 	rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
 	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
 					      MASKDWORD);
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
-		 ("Default framesync (0x%x) = 0x%x\n",
-		 ROFDM0_RXDETECTOR3, rtlphy->framesync));
+		 "Default framesync (0x%x) = 0x%x\n",
+		 ROFDM0_RXDETECTOR3, rtlphy->framesync);
 
 }
 
@@ -1274,7 +1269,7 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8	channel)
 	/* [0]:RF-A, [1]:RF-B */
 	u8 cckpowerlevel[2], ofdmpowerLevel[2];
 
-	if (rtlefuse->txpwr_fromeprom == false)
+	if (!rtlefuse->txpwr_fromeprom)
 		return;
 
 	/* Mainly we use RF-A Tx Power to write the Tx Power registers,
@@ -1287,10 +1282,9 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8	channel)
 			&ofdmpowerLevel[0]);
 
 	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			("Channel-%d, cckPowerLevel (A / B) = "
-			"0x%x / 0x%x,   ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
-			channel, cckpowerlevel[0], cckpowerlevel[1],
-			ofdmpowerLevel[0], ofdmpowerLevel[1]));
+		 "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
+		 channel, cckpowerlevel[0], cckpowerlevel[1],
+		 ofdmpowerLevel[0], ofdmpowerLevel[1]);
 
 	_rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
 			&ofdmpowerLevel[0]);
@@ -1316,7 +1310,7 @@ void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
 	} while (--pollingcnt);
 
 	if (pollingcnt == 0)
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n");
 }
 
 
@@ -1345,20 +1339,17 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
 
 	switch (rtlhal->current_fwcmd_io) {
 	case FW_CMD_RA_RESET:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_RA_RESET\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
 	case FW_CMD_RA_ACTIVE:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_RA_ACTIVE\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
 	case FW_CMD_RA_REFRESH_N:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_RA_REFRESH_N\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n");
 		input = FW_RA_REFRESH;
 		rtl_write_dword(rtlpriv, WFM5, input);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
@@ -1367,7 +1358,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
 		break;
 	case FW_CMD_RA_REFRESH_BG:
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_RA_REFRESH_BG\n"));
+			 "FW_CMD_RA_REFRESH_BG\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
@@ -1375,21 +1366,20 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
 		break;
 	case FW_CMD_RA_REFRESH_N_COMB:
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_RA_REFRESH_N_COMB\n"));
+			 "FW_CMD_RA_REFRESH_N_COMB\n");
 		input = FW_RA_IOT_N_COMB;
 		rtl_write_dword(rtlpriv, WFM5, input);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
 	case FW_CMD_RA_REFRESH_BG_COMB:
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_RA_REFRESH_BG_COMB\n"));
+			 "FW_CMD_RA_REFRESH_BG_COMB\n");
 		input = FW_RA_IOT_BG_COMB;
 		rtl_write_dword(rtlpriv, WFM5, input);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
 	case FW_CMD_IQK_ENABLE:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_IQK_ENABLE\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
@@ -1424,8 +1414,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
 		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
 		break;
 	case FW_CMD_LPS_ENTER:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_LPS_ENTER\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n");
 		current_aid = rtlpriv->mac80211.assoc_id;
 		rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
 				((current_aid | 0xc000) << 8)));
@@ -1434,20 +1423,18 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
 		 * turbo mode until driver leave LPS */
 		break;
 	case FW_CMD_LPS_LEAVE:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_LPS_LEAVE\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
 	case FW_CMD_ADD_A2_ENTRY:
-		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
-			 ("FW_CMD_ADD_A2_ENTRY\n"));
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
 	case FW_CMD_CTRL_DM_BY_DRIVER:
 		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			 ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
+			 "FW_CMD_CTRL_DM_BY_DRIVER\n");
 		rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
 		rtl92s_phy_chk_fwcmd_iodone(hw);
 		break;
@@ -1472,8 +1459,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 	bool bPostProcessing = false;
 
 	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-			("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
-			fw_cmdio, rtlhal->set_fwcmd_inprogress));
+		 "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
+		 fw_cmdio, rtlhal->set_fwcmd_inprogress);
 
 	do {
 		/* We re-map to combined FW CMD ones if firmware version */
@@ -1501,7 +1488,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 		 * DM map table in the future. */
 		switch (fw_cmdio) {
 		case FW_CMD_RA_INIT:
-			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n");
 			fw_cmdmap |= FW_RA_INIT_CTL;
 			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
 			/* Clear control flag to sync with FW. */
@@ -1509,7 +1496,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 			break;
 		case FW_CMD_DIG_DISABLE:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Set DIG disable!!\n"));
+				 "Set DIG disable!!\n");
 			fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
 			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
 			break;
@@ -1517,14 +1504,14 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 		case FW_CMD_DIG_RESUME:
 			if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
 				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-					("Set DIG enable or resume!!\n"));
+					 "Set DIG enable or resume!!\n");
 				fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
 				FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
 			}
 			break;
 		case FW_CMD_DIG_HALT:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Set DIG halt!!\n"));
+				 "Set DIG halt!!\n");
 			fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
 			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
 			break;
@@ -1540,9 +1527,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 				     (rtlefuse->thermalmeter[0] << 16));
 
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("Set TxPwr tracking!! "
-				 "FwCmdMap(%#x), FwParam(%#x)\n",
-				 fw_cmdmap, fw_param));
+				 "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n",
+				 fw_cmdmap, fw_param);
 
 			FW_CMD_PARA_SET(rtlpriv, fw_param);
 			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
@@ -1563,9 +1549,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 			fw_param &= FW_RA_PARAM_CLR;
 
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("[FW CMD] [New Version] "
-				 "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
-				 "FwParam(%#x)\n", fw_cmdmap, fw_param));
+				 "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n",
+				 fw_cmdmap, fw_param);
 
 			FW_CMD_PARA_SET(rtlpriv, fw_param);
 			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
@@ -1635,7 +1620,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 			break;
 		case FW_CMD_HIGH_PWR_ENABLE:
 			if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
-				(rtlpriv->dm.dynamic_txpower_enable != true)) {
+			    !rtlpriv->dm.dynamic_txpower_enable) {
 				fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
 					      FW_SS_CTL);
 				FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
@@ -1652,7 +1637,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
 			break;
 		case FW_CMD_PAPE_CONTROL:
 			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
-				 ("[FW CMD] Set PAPE Control\n"));
+				 "[FW CMD] Set PAPE Control\n");
 			fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
 
 			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
index 37e504a..ac03877 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
index 11f125c..84d1181 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
index 0ad50fe..08c2f56 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
 #include "../wifi.h"
 #include "reg.h"
 #include "def.h"
@@ -123,13 +121,13 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
 	}
 
 	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx "
-			"(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
-			p_final_pwridx[1]));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n",
+			 p_final_pwridx[0], p_final_pwridx[1]);
 	} else {
-		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx "
-			"(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
-			 p_final_pwridx[1]));
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n",
+			 p_final_pwridx[0], p_final_pwridx[1]);
 	}
 }
 
@@ -153,9 +151,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
 			ant_pwr_diff = -8;
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("Antenna Diff from RF-B "
-			"to RF-A = %d (0x%x)\n", ant_pwr_diff,
-			 ant_pwr_diff & 0xf));
+			 "Antenna Diff from RF-B to RF-A = %d (0x%x)\n",
+			 ant_pwr_diff, ant_pwr_diff & 0xf);
 
 		ant_pwr_diff &= 0xf;
 	}
@@ -172,9 +169,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
 	rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC),
 		      u4reg_val);
 
-	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-		 ("Write BCD-Diff(0x%x) = 0x%x\n",
-		 RFPGA0_TXGAINSTAGE, u4reg_val));
+	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n",
+		 RFPGA0_TXGAINSTAGE, u4reg_val);
 }
 
 static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
@@ -201,8 +197,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
 				((index < 2) ? pwrbase0 : pwrbase1);
 
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("RTK better performance, "
-			 "writeval = 0x%x\n", writeval));
+			 "RTK better performance, writeval = 0x%x\n", writeval);
 		break;
 	case 1:
 		/* Realtek regulatory increase power diff defined
@@ -211,8 +206,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
 			writeval = ((index < 2) ? pwrbase0 : pwrbase1);
 
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("Realtek regulatory, "
-				 "40MHz, writeval = 0x%x\n", writeval));
+				 "Realtek regulatory, 40MHz, writeval = 0x%x\n",
+				 writeval);
 		} else {
 			if (rtlphy->pwrgroup_cnt == 1)
 				chnlgroup = 0;
@@ -234,16 +229,15 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
 					pwrbase0 : pwrbase1);
 
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				 ("Realtek regulatory, "
-				 "20MHz, writeval = 0x%x\n", writeval));
+				 "Realtek regulatory, 20MHz, writeval = 0x%x\n",
+				 writeval);
 		}
 		break;
 	case 2:
 		/* Better regulatory don't increase any power diff */
 		writeval = ((index < 2) ? pwrbase0 : pwrbase1);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("Better regulatory, "
-			 "writeval = 0x%x\n", writeval));
+			 "Better regulatory, writeval = 0x%x\n", writeval);
 		break;
 	case 3:
 		/* Customer defined power diff. increase power diff
@@ -252,14 +246,14 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
 
 		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				("customer's limit, 40MHz = 0x%x\n",
-				rtlefuse->pwrgroup_ht40
-				[RF90_PATH_A][chnl - 1]));
+				 "customer's limit, 40MHz = 0x%x\n",
+				 rtlefuse->pwrgroup_ht40
+				 [RF90_PATH_A][chnl - 1]);
 		} else {
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-				("customer's limit, 20MHz = 0x%x\n",
-				rtlefuse->pwrgroup_ht20
-				[RF90_PATH_A][chnl - 1]));
+				 "customer's limit, 20MHz = 0x%x\n",
+				 rtlefuse->pwrgroup_ht20
+				 [RF90_PATH_A][chnl - 1]);
 		}
 
 		for (i = 0; i < 4; i++) {
@@ -293,22 +287,19 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
 				(pwrdiff_limit[1] << 8) |
 				(pwrdiff_limit[0]);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("Customer's limit = 0x%x\n",
-			 customer_limit));
+			 "Customer's limit = 0x%x\n", customer_limit);
 
 		writeval = customer_limit + ((index < 2) ?
 					     pwrbase0 : pwrbase1);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("Customer, writeval = "
-			 "0x%x\n", writeval));
+			 "Customer, writeval = 0x%x\n", writeval);
 		break;
 	default:
 		chnlgroup = 0;
 		writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] +
 				((index < 2) ? pwrbase0 : pwrbase1);
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
-			 ("RTK better performance, "
-			 "writeval = 0x%x\n", writeval));
+			 "RTK better performance, writeval = 0x%x\n", writeval);
 		break;
 	}
 
@@ -508,7 +499,7 @@ bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw)
 			break;
 		}
 
-		if (rtstatus != true) {
+		if (!rtstatus) {
 			pr_err("Radio[%d] Fail!!\n", rfpath);
 			goto fail;
 		}
@@ -541,8 +532,7 @@ void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("unknown bandwidth: %#X\n",
-			 bandwidth));
+			 "unknown bandwidth: %#X\n", bandwidth);
 		break;
 	}
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
index 3843baa..8a29eb9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index 78723cf..eda30b9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -27,14 +27,11 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
+#include "../base.h"
+#include "../pci.h"
 #include "reg.h"
 #include "def.h"
 #include "phy.h"
@@ -45,6 +42,8 @@
 #include "trx.h"
 #include "led.h"
 
+#include <linux/module.h>
+
 static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -89,12 +88,53 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
 	rtlpci->const_support_pciaspm = 2;
 }
 
+static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
+{
+	struct ieee80211_hw *hw = context;
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+	struct rt_firmware *pfirmware = NULL;
+	int err;
+
+	RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+			 "Firmware callback routine entered!\n");
+	complete(&rtlpriv->firmware_loading_complete);
+	if (!firmware) {
+		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
+		rtlpriv->max_fw_size = 0;
+		return;
+	}
+	if (firmware->size > rtlpriv->max_fw_size) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "Firmware is too big!\n");
+		release_firmware(firmware);
+		return;
+	}
+	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
+	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
+	pfirmware->sz_fw_tmpbufferlen = firmware->size;
+	release_firmware(firmware);
+
+	err = ieee80211_register_hw(hw);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 "Can't register mac80211 hw\n");
+		return;
+	} else {
+		rtlpriv->mac80211.mac80211_registered = 1;
+	}
+	rtlpci->irq_alloc = 1;
+	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+	/*init rfkill */
+	rtl_init_rfkill(hw);
+}
+
 static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	const struct firmware *firmware;
-	struct rt_firmware *pfirmware = NULL;
 	int err = 0;
 	u16 earlyrxthreshold = 7;
 
@@ -168,9 +208,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
 	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
 	if (!rtlpriv->psc.inactiveps)
-		pr_info("rtl8192ce: Power Save off (module option)\n");
+		pr_info("Power Save off (module option)\n");
 	if (!rtlpriv->psc.fwctrl_lps)
-		pr_info("rtl8192ce: FW Power Save off (module option)\n");
+		pr_info("FW Power Save off (module option)\n");
 	rtlpriv->psc.reg_fwctrl_lps = 3;
 	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
 	/* for ASPM, you can close aspm through
@@ -186,33 +226,22 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 
 	/* for firmware buf */
 	rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware));
-	if (!rtlpriv->rtlhal.pfirmware) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't alloc buffer for fw.\n"));
+	if (!rtlpriv->rtlhal.pfirmware)
 		return 1;
-	}
+
+	rtlpriv->max_fw_size = sizeof(struct rt_firmware);
 
 	pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
 		"Loading firmware %s\n", rtlpriv->cfg->fw_name);
 	/* request fw */
-	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-			rtlpriv->io.dev);
+	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+				      rtlpriv->io.dev, GFP_KERNEL, hw,
+				      rtl92se_fw_cb);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Failed to request firmware!\n"));
+			 "Failed to request firmware!\n");
 		return 1;
 	}
-	if (firmware->size > sizeof(struct rt_firmware)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
-		return 1;
-	}
-
-	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
-	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
-	pfirmware->sz_fw_tmpbufferlen = firmware->size;
-	release_firmware(firmware);
 
 	return err;
 }
@@ -426,7 +455,7 @@ static int __init rtl92se_module_init(void)
 
 	ret = pci_register_driver(&rtl92se_driver);
 	if (ret)
-		RT_ASSERT(false, (": No device found\n"));
+		RT_ASSERT(false, "No device found\n");
 
 	return ret;
 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
index fc4eb28..2eb8886 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c
index 154185b..f1a73f7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h
index b4ed6d9..2feb73b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/table.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2012 Realtek Corporation. All rights reserved.
  *
  * This program is distributed in the hope that it will be useful, but WITHOUT
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index fbebe3e..2fd3d13 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -756,7 +756,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
 	/* DOWRD 8 */
 	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
 
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
 }
 
 void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
@@ -823,8 +823,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR txdesc :%d not process\n",
-				  desc_name));
+			RT_ASSERT(false, "ERR txdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	} else {
@@ -843,8 +843,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
 			SET_RX_STATUS_DESC_EOR(pdesc, 1);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
-				  desc_name));
+			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	}
@@ -863,8 +863,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
 			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR txdesc :%d not process\n",
-				  desc_name));
+			RT_ASSERT(false, "ERR txdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	} else {
@@ -876,8 +876,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
 			ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
 			break;
 		default:
-			RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
-				  desc_name));
+			RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+				  desc_name);
 			break;
 		}
 	}
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
index 05862c5..011e7b0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index e956fa7..ffcf89f 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2011  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -25,16 +25,13 @@
  *
  *****************************************************************************/
 
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/usb.h>
-#include <linux/export.h>
-#include "core.h"
 #include "wifi.h"
+#include "core.h"
 #include "usb.h"
 #include "base.h"
 #include "ps.h"
 #include "rtl8192c/fw_common.h"
+#include <linux/export.h>
 
 #define	REALTEK_USB_VENQT_READ			0xC0
 #define	REALTEK_USB_VENQT_WRITE			0x40
@@ -276,14 +273,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw)
 						    ? USB_HIGH_SPEED_BULK_SIZE
 						    : USB_FULL_SPEED_BULK_SIZE;
 
-	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n",
-		 rtlusb->max_bulk_out_size));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n",
+		 rtlusb->max_bulk_out_size);
 
 	for (i = 0; i < __RTL_TXQ_NUM; i++) {
 		u32 ep_num = rtlusb->ep_map.ep_mapping[i];
 		if (!ep_num) {
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-				 ("Invalid endpoint map setting!\n"));
+				 "Invalid endpoint map setting!\n");
 			return -EINVAL;
 		}
 	}
@@ -345,9 +342,9 @@ static int _rtl_usb_init(struct ieee80211_hw *hw)
 			rtlusb->out_ep_nums++;
 
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
-			 ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n",
+			 "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n",
 			 pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize,
-			 pep_desc->bInterval));
+			 pep_desc->bInterval);
 	}
 	if (rtlusb->in_ep_nums <  rtlpriv->cfg->usb_interface_cfg->in_ep_num)
 		return -EINVAL ;
@@ -414,7 +411,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw,
 			       gfp_mask);
 	if (!skb) {
 		RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-			 ("Failed to __dev_alloc_skb!!\n"))
+			 "Failed to __dev_alloc_skb!!\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -520,12 +517,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
 			u8 *pdata;
 
 			uskb = dev_alloc_skb(skb->len + 128);
-			memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
-			       sizeof(rx_status));
-			pdata = (u8 *)skb_put(uskb, skb->len);
-			memcpy(pdata, skb->data, skb->len);
+			if (uskb) {	/* drop packet on allocation failure */
+				memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
+				       sizeof(rx_status));
+				pdata = (u8 *)skb_put(uskb, skb->len);
+				memcpy(pdata, skb->data, skb->len);
+				ieee80211_rx_irqsafe(hw, uskb);
+			}
 			dev_kfree_skb_any(skb);
-			ieee80211_rx_irqsafe(hw, uskb);
 		} else {
 			dev_kfree_skb_any(skb);
 		}
@@ -575,7 +574,7 @@ static void _rtl_rx_completed(struct urb *_urb)
 			if (IS_ERR(_skb)) {
 				err = PTR_ERR(_skb);
 				RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-					("Can't allocate skb for bulk IN!\n"));
+					 "Can't allocate skb for bulk IN!\n");
 				return;
 			}
 			skb = _skb;
@@ -632,14 +631,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
 		urb = usb_alloc_urb(0, GFP_KERNEL);
 		if (!urb) {
 			RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-				 ("Failed to alloc URB!!\n"))
+				 "Failed to alloc URB!!\n");
 			goto err_out;
 		}
 
 		skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL);
 		if (IS_ERR(skb)) {
 			RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-				 ("Failed to prep_rx_urb!!\n"))
+				 "Failed to prep_rx_urb!!\n");
 			err = PTR_ERR(skb);
 			goto err_out;
 		}
@@ -665,15 +664,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw)
 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 
 	err = rtlpriv->cfg->ops->hw_init(hw);
-	rtl_init_rx_config(hw);
+	if (!err) {
+		rtl_init_rx_config(hw);
 
-	/* Enable software */
-	SET_USB_START(rtlusb);
-	/* should after adapter start and interrupt enable. */
-	set_hal_start(rtlhal);
+		/* Enable software */
+		SET_USB_START(rtlusb);
+		/* should after adapter start and interrupt enable. */
+		set_hal_start(rtlhal);
 
-	/* Start bulk IN */
-	_rtl_usb_receive(hw);
+		/* Start bulk IN */
+		_rtl_usb_receive(hw);
+	}
 
 	return err;
 }
@@ -745,7 +746,7 @@ static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb)
 		struct sk_buff *skb;
 
 		RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-			 ("Failed to submit urb.\n"));
+			 "Failed to submit urb\n");
 		usb_unanchor_urb(_urb);
 		skb = (struct sk_buff *)_urb->context;
 		kfree_skb(skb);
@@ -768,7 +769,7 @@ static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb,
 
 	if (urb->status) {
 		RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-			 ("Urb has error status 0x%X\n", urb->status));
+			 "Urb has error status 0x%X\n", urb->status);
 		goto out;
 	}
 	/*  TODO:	statistics */
@@ -805,7 +806,7 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw,
 	_urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!_urb) {
 		RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-			 ("Can't allocate URB for bulk out!\n"));
+			 "Can't allocate URB for bulk out!\n");
 		kfree_skb(skb);
 		return NULL;
 	}
@@ -830,7 +831,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
 	WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl);
 	if (unlikely(IS_USB_STOP(rtlusb))) {
 		RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
-			 ("USB device is stopping...\n"));
+			 "USB device is stopping...\n");
 		kfree_skb(skb);
 		return;
 	}
@@ -840,7 +841,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
 	_urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num);
 	if (unlikely(!_urb)) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't allocate urb. Drop skb!\n"));
+			 "Can't allocate urb. Drop skb!\n");
 		return;
 	}
 	urb_list = &rtlusb->tx_pending[ep_num];
@@ -865,7 +866,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb,
 
 	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
 	if (ieee80211_is_auth(fc)) {
-		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n");
 		rtl_ips_nic_on(hw);
 	}
 
@@ -946,10 +947,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
 	hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) +
 				sizeof(struct rtl_usb_priv), &rtl_ops);
 	if (!hw) {
-		RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__));
+		RT_ASSERT(false, "ieee80211 alloc failed\n");
 		return -ENOMEM;
 	}
 	rtlpriv = hw->priv;
+	init_completion(&rtlpriv->firmware_loading_complete);
 	SET_IEEE80211_DEV(hw, &intf->dev);
 	udev = interface_to_usbdev(intf);
 	usb_get_dev(udev);
@@ -969,8 +971,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
 	/*like read eeprom and so on */
 	rtlpriv->cfg->ops->read_eeprom_info(hw);
 	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't init_sw_vars.\n"));
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
 		goto error_out;
 	}
 	rtlpriv->cfg->ops->init_sw_leds(hw);
@@ -980,28 +981,16 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
 	err = rtl_init_core(hw);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't allocate sw for mac80211.\n"));
+			 "Can't allocate sw for mac80211\n");
 		goto error_out;
 	}
 
-	/*init rfkill */
-	/* rtl_init_rfkill(hw); */
-
-	err = ieee80211_register_hw(hw);
-	if (err) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("Can't register mac80211 hw.\n"));
-		goto error_out;
-	} else {
-		rtlpriv->mac80211.mac80211_registered = 1;
-	}
-	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 	return 0;
 error_out:
 	rtl_deinit_core(hw);
 	_rtl_usb_io_handler_release(hw);
-	ieee80211_free_hw(hw);
 	usb_put_dev(udev);
+	complete(&rtlpriv->firmware_loading_complete);
 	return -ENODEV;
 }
 EXPORT_SYMBOL(rtl_usb_probe);
@@ -1015,6 +1004,9 @@ void rtl_usb_disconnect(struct usb_interface *intf)
 
 	if (unlikely(!rtlpriv))
 		return;
+
+	/* just in case driver is removed before firmware callback */
+	wait_for_completion(&rtlpriv->firmware_loading_complete);
 	/*ieee80211_unregister_hw will call ops_stop */
 	if (rtlmac->mac80211_registered == 1) {
 		ieee80211_unregister_hw(hw);
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index d2a63fb..43846b3 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2011  Realtek Corporation. All rights reserved.
+ * Copyright(c) 2009-2012  Realtek Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -28,7 +28,6 @@
 #ifndef __RTL_USB_H__
 #define __RTL_USB_H__
 
-#include <linux/usb.h>
 #include <linux/skbuff.h>
 
 #define RTL_RX_DESC_SIZE		24
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index cdaf142..b591614 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009-2010  Realtek Corporation.
+ * Copyright(c) 2009-2012  Realtek Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -30,12 +30,15 @@
 #ifndef __RTL_WIFI_H__
 #define __RTL_WIFI_H__
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/firmware.h>
 #include <linux/etherdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/usb.h>
 #include <net/mac80211.h>
+#include <linux/completion.h>
 #include "debug.h"
 
 #define RF_CHANGE_BY_INIT			0
@@ -1045,7 +1048,6 @@ struct rtl_hal {
 	u16 fw_subversion;
 	bool h2c_setinprogress;
 	u8 last_hmeboxnum;
-	bool fw_ready;
 	/*Reserve page start offset except beacon in TxQ. */
 	u8 fw_rsvdpage_startoffset;
 	u8 h2c_txcmd_seq;
@@ -1591,6 +1593,7 @@ struct rtl_debug {
 };
 
 struct rtl_priv {
+	struct completion firmware_loading_complete;
 	struct rtl_locks locks;
 	struct rtl_works works;
 	struct rtl_mac mac80211;
@@ -1612,6 +1615,7 @@ struct rtl_priv {
 	struct rtl_rate_priv *rate_priv;
 
 	struct rtl_debug dbg;
+	int max_fw_size;
 
 	/*
 	 *hal_cfg : for diff cards
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index ba3268e..41302c7 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -514,6 +514,9 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
 	struct wl1251 *wl = hw->priv;
 	int ret = 0;
 
+	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+
 	wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
 		     vif->type, vif->addr);
 
@@ -1338,9 +1341,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
 
 	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		IEEE80211_HW_SUPPORTS_PS |
-		IEEE80211_HW_BEACON_FILTER |
-		IEEE80211_HW_SUPPORTS_UAPSD |
-		IEEE80211_HW_SUPPORTS_CQM_RSSI;
+		IEEE80211_HW_SUPPORTS_UAPSD;
 
 	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 					 BIT(NL80211_IFTYPE_ADHOC);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index d5f55a1..f8748ce 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2060,6 +2060,9 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
 	u8 role_type;
 	bool booted = false;
 
+	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
+			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
+
 	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
 		     ieee80211_vif_type_p2p(vif), vif->addr);
 
@@ -4898,12 +4901,10 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
 	wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
 
 	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-		IEEE80211_HW_BEACON_FILTER |
 		IEEE80211_HW_SUPPORTS_PS |
 		IEEE80211_HW_SUPPORTS_UAPSD |
 		IEEE80211_HW_HAS_RATE_CONTROL |
 		IEEE80211_HW_CONNECTION_MONITOR |
-		IEEE80211_HW_SUPPORTS_CQM_RSSI |
 		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
 		IEEE80211_HW_SPECTRUM_MGMT |
 		IEEE80211_HW_AP_LINK_PS |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 98a574a..c14084b 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -846,7 +846,7 @@ reset_device:
 
 	/* semaphore stuck, reset device to avoid fw freeze later */
 	dev_warn(zd_mac_dev(mac), "CR_BCN_FIFO_SEMAPHORE stuck, "
-				  "reseting device...");
+				  "resetting device...");
 	usb_queue_reset_device(mac->chip.usb.intf);
 
 	return r;
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 785bdbe..f766b3e 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1104,7 +1104,7 @@ static void zd_tx_watchdog_handler(struct work_struct *work)
 		goto out;
 
 	/* TX halted, try reset */
-	dev_warn(zd_usb_dev(usb), "TX-stall detected, reseting device...");
+	dev_warn(zd_usb_dev(usb), "TX-stall detected, resetting device...");
 
 	usb_queue_reset_device(usb->intf);
 
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 59effac..2596401 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -1639,10 +1639,8 @@ static int __init netback_init(void)
 
 	xen_netbk_group_nr = num_online_cpus();
 	xen_netbk = vzalloc(sizeof(struct xen_netbk) * xen_netbk_group_nr);
-	if (!xen_netbk) {
-		printk(KERN_ALERT "%s: out of memory\n", __func__);
+	if (!xen_netbk)
 		return -ENOMEM;
-	}
 
 	for (group = 0; group < xen_netbk_group_nr; group++) {
 		struct xen_netbk *netbk = &xen_netbk[group];
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 698b905..b161750 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -489,6 +489,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	int frags = skb_shinfo(skb)->nr_frags;
 	unsigned int offset = offset_in_page(data);
 	unsigned int len = skb_headlen(skb);
+	unsigned long flags;
 
 	frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
 	if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
@@ -498,12 +499,12 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		goto drop;
 	}
 
-	spin_lock_irq(&np->tx_lock);
+	spin_lock_irqsave(&np->tx_lock, flags);
 
 	if (unlikely(!netif_carrier_ok(dev) ||
 		     (frags > 1 && !xennet_can_sg(dev)) ||
 		     netif_needs_gso(skb, netif_skb_features(skb)))) {
-		spin_unlock_irq(&np->tx_lock);
+		spin_unlock_irqrestore(&np->tx_lock, flags);
 		goto drop;
 	}
 
@@ -574,7 +575,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (!netfront_tx_slot_available(np))
 		netif_stop_queue(dev);
 
-	spin_unlock_irq(&np->tx_lock);
+	spin_unlock_irqrestore(&np->tx_lock, flags);
 
 	return NETDEV_TX_OK;
 
@@ -1228,6 +1229,33 @@ static int xennet_set_features(struct net_device *dev,
 	return 0;
 }
 
+static irqreturn_t xennet_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct netfront_info *np = netdev_priv(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&np->tx_lock, flags);
+
+	if (likely(netif_carrier_ok(dev))) {
+		xennet_tx_buf_gc(dev);
+		/* Under tx_lock: protects access to rx shared-ring indexes. */
+		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
+			napi_schedule(&np->napi);
+	}
+
+	spin_unlock_irqrestore(&np->tx_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void xennet_poll_controller(struct net_device *dev)
+{
+	xennet_interrupt(0, dev);
+}
+#endif
+
 static const struct net_device_ops xennet_netdev_ops = {
 	.ndo_open            = xennet_open,
 	.ndo_uninit          = xennet_uninit,
@@ -1239,6 +1267,9 @@ static const struct net_device_ops xennet_netdev_ops = {
 	.ndo_validate_addr   = eth_validate_addr,
 	.ndo_fix_features    = xennet_fix_features,
 	.ndo_set_features    = xennet_set_features,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = xennet_poll_controller,
+#endif
 };
 
 static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev)
@@ -1248,11 +1279,8 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
 	struct netfront_info *np;
 
 	netdev = alloc_etherdev(sizeof(struct netfront_info));
-	if (!netdev) {
-		printk(KERN_WARNING "%s> alloc_etherdev failed.\n",
-		       __func__);
+	if (!netdev)
 		return ERR_PTR(-ENOMEM);
-	}
 
 	np                   = netdev_priv(netdev);
 	np->xbdev            = dev;
@@ -1448,26 +1476,6 @@ static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
 	return 0;
 }
 
-static irqreturn_t xennet_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct netfront_info *np = netdev_priv(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&np->tx_lock, flags);
-
-	if (likely(netif_carrier_ok(dev))) {
-		xennet_tx_buf_gc(dev);
-		/* Under tx_lock: protects access to rx shared-ring indexes. */
-		if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
-			napi_schedule(&np->napi);
-	}
-
-	spin_unlock_irqrestore(&np->tx_lock, flags);
-
-	return IRQ_HANDLED;
-}
-
 static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
 {
 	struct xen_netif_tx_sring *txs;
diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c
index 06c3642..1f74a77 100644
--- a/drivers/nfc/nfcwilink.c
+++ b/drivers/nfc/nfcwilink.c
@@ -28,6 +28,8 @@
  */
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/types.h>
+#include <linux/firmware.h>
 #include <linux/nfc.h>
 #include <net/nfc/nci.h>
 #include <net/nfc/nci_core.h>
@@ -40,11 +42,52 @@
 #define NFCWILINK_OFFSET_LEN_IN_HDR	1
 #define NFCWILINK_LEN_SIZE		2
 #define NFCWILINK_REGISTER_TIMEOUT	8000	/* 8 sec */
+#define NFCWILINK_CMD_TIMEOUT		5000	/* 5 sec */
+
+#define BTS_FILE_NAME_MAX_SIZE		40
+#define BTS_FILE_HDR_MAGIC		0x42535442
+#define BTS_FILE_CMD_MAX_LEN		0xff
+#define BTS_FILE_ACTION_TYPE_SEND_CMD	1
+
+#define NCI_VS_NFCC_INFO_CMD_GID	0x2f
+#define NCI_VS_NFCC_INFO_CMD_OID	0x12
+#define NCI_VS_NFCC_INFO_RSP_GID	0x4f
+#define NCI_VS_NFCC_INFO_RSP_OID	0x12
 
 struct nfcwilink_hdr {
-	u8 chnl;
-	u8 opcode;
-	u16 len;
+	__u8 chnl;
+	__u8 opcode;
+	__le16 len;
+} __packed;
+
+struct nci_vs_nfcc_info_cmd {
+	__u8 gid;
+	__u8 oid;
+	__u8 plen;
+} __packed;
+
+struct nci_vs_nfcc_info_rsp {
+	__u8 gid;
+	__u8 oid;
+	__u8 plen;
+	__u8 status;
+	__u8 hw_id;
+	__u8 sw_ver_x;
+	__u8 sw_ver_z;
+	__u8 patch_id;
+} __packed;
+
+struct bts_file_hdr {
+	__le32 magic;
+	__le32 ver;
+	__u8 rfu[24];
+	__u8 actions[0];
+} __packed;
+
+struct bts_file_action {
+	__le16 type;
+	__le16 len;
+	__u8 data[0];
 } __packed;
 
 struct nfcwilink {
@@ -54,14 +97,241 @@ struct nfcwilink {
 
 	char				st_register_cb_status;
 	long				(*st_write) (struct sk_buff *);
-	struct completion		st_register_completed;
+
+	struct completion		completed;
+
+	struct nci_vs_nfcc_info_rsp	nfcc_info;
 };
 
 /* NFCWILINK driver flags */
 enum {
 	NFCWILINK_RUNNING,
+	NFCWILINK_FW_DOWNLOAD,
 };
 
+static int nfcwilink_send(struct sk_buff *skb);
+
+static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_skb(len + NFCWILINK_HDR_LEN, how);
+	if (skb)
+		skb_reserve(skb, NFCWILINK_HDR_LEN);
+
+	return skb;
+}
+
+static void nfcwilink_fw_download_receive(struct nfcwilink *drv,
+						struct sk_buff *skb)
+{
+	struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data;
+
+	/* Detect NCI_VS_NFCC_INFO_RSP and store the result */
+	if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) &&
+		(rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) {
+		memcpy(&drv->nfcc_info, rsp,
+			sizeof(struct nci_vs_nfcc_info_rsp));
+	}
+
+	kfree_skb(skb);
+
+	complete(&drv->completed);
+}
+
+static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
+{
+	struct nci_vs_nfcc_info_cmd *cmd;
+	struct sk_buff *skb;
+	unsigned long comp_ret;
+	int rc;
+
+	nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry");
+
+	skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd),
+					GFP_KERNEL);
+	if (!skb) {
+		nfc_dev_err(&drv->pdev->dev,
+				"no memory for nci_vs_nfcc_info_cmd");
+		return -ENOMEM;
+	}
+
+	skb->dev = (void *)drv->ndev;
+
+	cmd = (struct nci_vs_nfcc_info_cmd *)
+			skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd));
+	cmd->gid = NCI_VS_NFCC_INFO_CMD_GID;
+	cmd->oid = NCI_VS_NFCC_INFO_CMD_OID;
+	cmd->plen = 0;
+
+	drv->nfcc_info.plen = 0;
+
+	rc = nfcwilink_send(skb);
+	if (rc)
+		return rc;
+
+	comp_ret = wait_for_completion_timeout(&drv->completed,
+				msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
+	nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld",
+			comp_ret);
+	if (comp_ret == 0) {
+		nfc_dev_err(&drv->pdev->dev,
+				"timeout on wait_for_completion_timeout");
+		return -ETIMEDOUT;
+	}
+
+	nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d",
+			drv->nfcc_info.plen,
+			drv->nfcc_info.status);
+
+	if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) {
+		nfc_dev_err(&drv->pdev->dev,
+				"invalid nci_vs_nfcc_info_rsp");
+		return -EINVAL;
+	}
+
+	snprintf(file_name, BTS_FILE_NAME_MAX_SIZE,
+			"TINfcInit_%d.%d.%d.%d.bts",
+			drv->nfcc_info.hw_id,
+			drv->nfcc_info.sw_ver_x,
+			drv->nfcc_info.sw_ver_z,
+			drv->nfcc_info.patch_id);
+
+	nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name);
+
+	return 0;
+}
+
+static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
+{
+	struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data;
+	struct sk_buff *skb;
+	unsigned long comp_ret;
+	int rc;
+
+	nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry");
+
+	/* verify valid cmd for the NFC channel */
+	if ((len <= sizeof(struct nfcwilink_hdr)) ||
+		(len > BTS_FILE_CMD_MAX_LEN) ||
+		(hdr->chnl != NFCWILINK_CHNL) ||
+		(hdr->opcode != NFCWILINK_OPCODE)) {
+		nfc_dev_err(&drv->pdev->dev,
+			"ignoring invalid bts cmd, len %d, chnl %d, opcode %d",
+			len, hdr->chnl, hdr->opcode);
+		return 0;
+	}
+
+	/* remove the ST header */
+	len -= sizeof(struct nfcwilink_hdr);
+	data += sizeof(struct nfcwilink_hdr);
+
+	skb = nfcwilink_skb_alloc(len, GFP_KERNEL);
+	if (!skb) {
+		nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd");
+		return -ENOMEM;
+	}
+
+	skb->dev = (void *)drv->ndev;
+
+	memcpy(skb_put(skb, len), data, len);
+
+	rc = nfcwilink_send(skb);
+	if (rc)
+		return rc;
+
+	comp_ret = wait_for_completion_timeout(&drv->completed,
+				msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
+	nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld",
+			comp_ret);
+	if (comp_ret == 0) {
+		nfc_dev_err(&drv->pdev->dev,
+				"timeout on wait_for_completion_timeout");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int nfcwilink_download_fw(struct nfcwilink *drv)
+{
+	unsigned char file_name[BTS_FILE_NAME_MAX_SIZE];
+	const struct firmware *fw;
+	__u16 action_type, action_len;
+	__u8 *ptr;
+	int len, rc;
+
+	nfc_dev_dbg(&drv->pdev->dev, "download_fw entry");
+
+	set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
+
+	rc = nfcwilink_get_bts_file_name(drv, file_name);
+	if (rc)
+		goto exit;
+
+	rc = request_firmware(&fw, file_name, &drv->pdev->dev);
+	if (rc) {
+		nfc_dev_err(&drv->pdev->dev, "request_firmware failed %d", rc);
+
+		/* if the file is not found, don't exit with failure */
+		if (rc == -ENOENT)
+			rc = 0;
+
+		goto exit;
+	}
+
+	len = fw->size;
+	ptr = (__u8 *)fw->data;
+
+	if ((len == 0) || (ptr == NULL)) {
+		nfc_dev_dbg(&drv->pdev->dev,
+				"request_firmware returned size %d", len);
+		goto release_fw;
+	}
+
+	if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) !=
+			BTS_FILE_HDR_MAGIC) {
+		nfc_dev_err(&drv->pdev->dev, "wrong bts magic number");
+		rc = -EINVAL;
+		goto release_fw;
+	}
+
+	/* remove the BTS header */
+	len -= sizeof(struct bts_file_hdr);
+	ptr += sizeof(struct bts_file_hdr);
+
+	while (len > 0) {
+		action_type =
+			__le16_to_cpu(((struct bts_file_action *)ptr)->type);
+		action_len =
+			__le16_to_cpu(((struct bts_file_action *)ptr)->len);
+
+		nfc_dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d",
+				action_type, action_len);
+
+		switch (action_type) {
+		case BTS_FILE_ACTION_TYPE_SEND_CMD:
+			rc = nfcwilink_send_bts_cmd(drv,
+					((struct bts_file_action *)ptr)->data,
+					action_len);
+			if (rc)
+				goto release_fw;
+			break;
+		}
+
+		/* advance to the next action */
+		len -= (sizeof(struct bts_file_action) + action_len);
+		ptr += (sizeof(struct bts_file_action) + action_len);
+	}
+
+release_fw:
+	release_firmware(fw);
+
+exit:
+	clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
+	return rc;
+}
+
 /* Called by ST when registration is complete */
 static void nfcwilink_register_complete(void *priv_data, char data)
 {
@@ -73,7 +343,7 @@ static void nfcwilink_register_complete(void *priv_data, char data)
 	drv->st_register_cb_status = data;
 
 	/* complete the wait in nfc_st_open() */
-	complete(&drv->st_register_completed);
+	complete(&drv->completed);
 }
 
 /* Called by ST when receive data is available */
@@ -96,6 +366,11 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
 	(apart for the chnl byte, which is not received in the hdr) */
 	skb_pull(skb, (NFCWILINK_HDR_LEN-1));
 
+	if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) {
+		nfcwilink_fw_download_receive(drv, skb);
+		return 0;
+	}
+
 	skb->dev = (void *) drv->ndev;
 
 	/* Forward skb to NCI core layer */
@@ -136,14 +411,14 @@ static int nfcwilink_open(struct nci_dev *ndev)
 
 	nfcwilink_proto.priv_data = drv;
 
-	init_completion(&drv->st_register_completed);
+	init_completion(&drv->completed);
 	drv->st_register_cb_status = -EINPROGRESS;
 
 	rc = st_register(&nfcwilink_proto);
 	if (rc < 0) {
 		if (rc == -EINPROGRESS) {
 			comp_ret = wait_for_completion_timeout(
-			&drv->st_register_completed,
+			&drv->completed,
 			msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT));
 
 			nfc_dev_dbg(&drv->pdev->dev,
@@ -171,6 +446,12 @@ static int nfcwilink_open(struct nci_dev *ndev)
 	BUG_ON(nfcwilink_proto.write == NULL);
 	drv->st_write = nfcwilink_proto.write;
 
+	if (nfcwilink_download_fw(drv)) {
+		nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d",
+				rc);
+		/* open should succeed, even if the FW download failed */
+	}
+
 	goto exit;
 
 clear_exit:
@@ -208,11 +489,13 @@ static int nfcwilink_send(struct sk_buff *skb)
 
 	nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len);
 
-	if (!test_bit(NFCWILINK_RUNNING, &drv->flags))
-		return -EBUSY;
+	if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
 
 	/* add the ST hdr to the start of the buffer */
-	hdr.len = skb->len;
+	hdr.len = cpu_to_le16(skb->len);
 	memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN);
 
 	/* Insert skb to shared transport layer's transmit queue.
@@ -239,7 +522,7 @@ static int nfcwilink_probe(struct platform_device *pdev)
 {
 	static struct nfcwilink *drv;
 	int rc;
-	u32 protocols;
+	__u32 protocols;
 
 	nfc_dev_dbg(&pdev->dev, "probe entry");
 
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 268163d..6ea51dc 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -35,9 +35,10 @@ config OF_EARLY_FLATTREE
 config OF_PROMTREE
 	bool
 
+# Hardly any platforms need this.  It is safe to select, but only do so if you
+# need it.
 config OF_DYNAMIC
-	def_bool y
-	depends on PPC_OF
+	bool
 
 config OF_ADDRESS
 	def_bool y
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 133908a..5806449 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -88,7 +88,7 @@ int of_n_size_cells(struct device_node *np)
 }
 EXPORT_SYMBOL(of_n_size_cells);
 
-#if !defined(CONFIG_SPARC)   /* SPARC doesn't do ref counting (yet) */
+#if defined(CONFIG_OF_DYNAMIC)
 /**
  *	of_node_get - Increment refcount of a node
  *	@node:	Node to inc refcount, NULL is supported to
@@ -161,7 +161,7 @@ void of_node_put(struct device_node *node)
 		kref_put(&node->kref, of_node_release);
 }
 EXPORT_SYMBOL(of_node_put);
-#endif /* !CONFIG_SPARC */
+#endif /* CONFIG_OF_DYNAMIC */
 
 struct property *of_find_property(const struct device_node *np,
 				  const char *name,
@@ -761,6 +761,42 @@ int of_property_read_string_index(struct device_node *np, const char *propname,
 }
 EXPORT_SYMBOL_GPL(of_property_read_string_index);
 
+/**
+ * of_property_match_string() - Find string in a list and return index
+ * @np: pointer to node containing string list property
+ * @propname: string list property name
+ * @string: pointer to string to search for in string list
+ *
+ * This function searches a string list property and returns the index
+ * of a specific string value.
+ */
+int of_property_match_string(struct device_node *np, const char *propname,
+			     const char *string)
+{
+	struct property *prop = of_find_property(np, propname, NULL);
+	size_t l;
+	int i;
+	const char *p, *end;
+
+	if (!prop)
+		return -EINVAL;
+	if (!prop->value)
+		return -ENODATA;
+
+	p = prop->value;
+	end = p + prop->length;
+
+	for (i = 0; p < end; i++, p += l) {
+		l = strlen(p) + 1;
+		if (p + l > end)
+			return -EILSEQ;
+		pr_debug("comparing %s with %s\n", string, p);
+		if (strcmp(string, p) == 0)
+			return i; /* Found it; return index */
+	}
+	return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(of_property_match_string);
 
 /**
  * of_property_count_strings - Find and return the number of strings from a
diff --git a/drivers/of/device.c b/drivers/of/device.c
index 62b4b32..4c74e4f 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -128,39 +128,41 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 /**
  * of_device_uevent - Display OF related uevent information
  */
-int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	const char *compat;
 	int seen = 0, cplen, sl;
 
 	if ((!dev) || (!dev->of_node))
-		return -ENODEV;
-
-	if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name))
-		return -ENOMEM;
+		return;
 
-	if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type))
-		return -ENOMEM;
+	add_uevent_var(env, "OF_NAME=%s", dev->of_node->name);
+	add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name);
+	if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0)
+		add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type);
 
 	/* Since the compatible field can contain pretty much anything
 	 * it's not really legal to split it out with commas. We split it
 	 * up using a number of environment variables instead. */
-
 	compat = of_get_property(dev->of_node, "compatible", &cplen);
 	while (compat && *compat && cplen > 0) {
-		if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
-			return -ENOMEM;
-
+		add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
 		sl = strlen(compat) + 1;
 		compat += sl;
 		cplen -= sl;
 		seen++;
 	}
+	add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
+}
 
-	if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
-		return -ENOMEM;
+int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
+{
+	int sl;
+
+	if ((!dev) || (!dev->of_node))
+		return -ENODEV;
 
-	/* modalias is trickier, we add it in 2 steps */
+	/* Devicetree modalias is tricky, we add it in 2 steps */
 	if (add_uevent_var(env, "MODALIAS="))
 		return -ENOMEM;
 
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 7e62d15..e034b38 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -78,8 +78,9 @@ err0:
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
 /**
- * of_gpio_count - Count GPIOs for a device
+ * of_gpio_named_count - Count GPIOs for a device
  * @np:		device node to count GPIOs for
+ * @propname:	property name containing gpio specifier(s)
  *
  * The function returns the count of GPIOs specified for a node.
  *
@@ -93,14 +94,14 @@ EXPORT_SYMBOL(of_get_named_gpio_flags);
  * defines four GPIOs (so this function will return 4), two of which
  * are not specified.
  */
-unsigned int of_gpio_count(struct device_node *np)
+unsigned int of_gpio_named_count(struct device_node *np, const char* propname)
 {
 	unsigned int cnt = 0;
 
 	do {
 		int ret;
 
-		ret = of_parse_phandle_with_args(np, "gpios", "#gpio-cells",
+		ret = of_parse_phandle_with_args(np, propname, "#gpio-cells",
 						 cnt, NULL);
 		/* A hole in the gpios = <> counts anyway. */
 		if (ret < 0 && ret != -EEXIST)
@@ -109,7 +110,7 @@ unsigned int of_gpio_count(struct device_node *np)
 
 	return cnt;
 }
-EXPORT_SYMBOL(of_gpio_count);
+EXPORT_SYMBOL(of_gpio_named_count);
 
 /**
  * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 63b3ec4..cae9477 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -253,7 +253,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	if (!of_device_is_available(node))
 		return NULL;
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	dev = amba_device_alloc(NULL, 0, 0);
 	if (!dev)
 		return NULL;
 
@@ -283,14 +283,14 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
 	if (ret)
 		goto err_free;
 
-	ret = amba_device_register(dev, &iomem_resource);
+	ret = amba_device_add(dev, &iomem_resource);
 	if (ret)
 		goto err_free;
 
 	return dev;
 
 err_free:
-	kfree(dev);
+	amba_device_put(dev);
 	return NULL;
 }
 #else /* CONFIG_ARM_AMBA */
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index 9d2b480..f24ffd7 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -120,6 +120,34 @@ static void __init of_selftest_parse_phandle_with_args(void)
 	pr_info("end - %s\n", passed_all ? "PASS" : "FAIL");
 }
 
+static void __init of_selftest_property_match_string(void)
+{
+	struct device_node *np;
+	int rc;
+
+	pr_info("start\n");
+	np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a");
+	if (!np) {
+		pr_err("No testcase data in device tree\n");
+		return;
+	}
+
+	rc = of_property_match_string(np, "phandle-list-names", "first");
+	selftest(rc == 0, "first expected:0 got:%i\n", rc);
+	rc = of_property_match_string(np, "phandle-list-names", "second");
+	selftest(rc == 1, "second expected:0 got:%i\n", rc);
+	rc = of_property_match_string(np, "phandle-list-names", "third");
+	selftest(rc == 2, "third expected:0 got:%i\n", rc);
+	rc = of_property_match_string(np, "phandle-list-names", "fourth");
+	selftest(rc == -ENODATA, "unmatched string; rc=%i", rc);
+	rc = of_property_match_string(np, "missing-property", "blah");
+	selftest(rc == -EINVAL, "missing property; rc=%i", rc);
+	rc = of_property_match_string(np, "empty-property", "blah");
+	selftest(rc == -ENODATA, "empty property; rc=%i", rc);
+	rc = of_property_match_string(np, "unterminated-string", "blah");
+	selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc);
+}
+
 static int __init of_selftest(void)
 {
 	struct device_node *np;
@@ -133,6 +161,7 @@ static int __init of_selftest(void)
 
 	pr_info("start of selftest - you will see error messages\n");
 	of_selftest_parse_phandle_with_args();
+	of_selftest_property_match_string();
 	pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL");
 	return 0;
 }
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 2f0aa0f..ee8fd03 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -238,7 +238,6 @@ struct dentry *oprofilefs_mkdir(struct super_block *sb,
 static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *root_inode;
-	struct dentry *root_dentry;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -251,15 +250,11 @@ static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent)
 		return -ENOMEM;
 	root_inode->i_op = &simple_dir_inode_operations;
 	root_inode->i_fop = &simple_dir_operations;
-	root_dentry = d_alloc_root(root_inode);
-	if (!root_dentry) {
-		iput(root_inode);
+	sb->s_root = d_make_root(root_inode);
+	if (!sb->s_root)
 		return -ENOMEM;
-	}
-
-	sb->s_root = root_dentry;
 
-	oprofile_create_files(sb, root_dentry);
+	oprofile_create_files(sb, sb->s_root);
 
 	// FIXME: verify kill_litter_super removes our dentries
 	return 0;
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 9ddf69e..12d070c 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -800,20 +800,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 	if (slot->flags & SLOT_ENABLED)
 		goto err_exit;
 
-	/* sanity check: dev should be NULL when hot-plugged in */
-	dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
-	if (dev) {
-		/* This case shouldn't happen */
-		err("pci_dev structure already exists.\n");
-		pci_dev_put(dev);
-		retval = -1;
-		goto err_exit;
-	}
-
 	num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
 	if (num == 0) {
-		err("No new device found\n");
-		retval = -1;
+		/* Maybe only part of funcs are added. */
+		dbg("No new device found\n");
 		goto err_exit;
 	}
 
@@ -848,11 +838,16 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 
 	pci_bus_add_devices(bus);
 
+	slot->flags |= SLOT_ENABLED;
 	list_for_each_entry(func, &slot->funcs, sibling) {
 		dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
 						  func->function));
-		if (!dev)
+		if (!dev) {
+			/* Do not set SLOT_ENABLED flag if some funcs
+			   are not added. */
+			slot->flags &= (~SLOT_ENABLED);
 			continue;
+		}
 
 		if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
 		    dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) {
@@ -867,7 +862,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 		pci_dev_put(dev);
 	}
 
-	slot->flags |= SLOT_ENABLED;
 
  err_exit:
 	return retval;
@@ -892,9 +886,12 @@ static int disable_device(struct acpiphp_slot *slot)
 {
 	struct acpiphp_func *func;
 	struct pci_dev *pdev;
+	struct pci_bus *bus = slot->bridge->pci_bus;
 
-	/* is this slot already disabled? */
-	if (!(slot->flags & SLOT_ENABLED))
+	/* The slot will be enabled when func 0 is added, so check
+	   func 0 before disable the slot. */
+	pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
+	if (!pdev)
 		goto err_exit;
 
 	list_for_each_entry(func, &slot->funcs, sibling) {
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index fb3f846..81af764 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -62,7 +62,7 @@
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
 
 /* local variables */
-static int debug;
+static bool debug;
 static char *bridge;
 static u8 bridge_busnr;
 static u8 bridge_slot;
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index 2850e64..714ca5c 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -368,8 +368,10 @@ int __init ibmphp_access_ebda (void)
 			debug ("rio blk id: %x\n", blk_id);
 
 			rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL);
-			if (!rio_table_ptr)
-				return -ENOMEM; 
+			if (!rio_table_ptr) {
+				rc = -ENOMEM;
+				goto out;
+			}
 			rio_table_ptr->ver_num = readb (io_mem + offset);
 			rio_table_ptr->scal_count = readb (io_mem + offset + 1);
 			rio_table_ptr->riodev_count = readb (io_mem + offset + 2);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index bcdbb16..a960fae 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -241,34 +241,79 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
 	return retval;
 }
 
-static inline int check_link_active(struct controller *ctrl)
+static bool check_link_active(struct controller *ctrl)
 {
-	u16 link_status;
+	bool ret = false;
+	u16 lnk_status;
 
-	if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &link_status))
-		return 0;
-	return !!(link_status & PCI_EXP_LNKSTA_DLLLA);
+	if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status))
+		return ret;
+
+	ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
+
+	if (ret)
+		ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
+
+	return ret;
 }
 
-static void pcie_wait_link_active(struct controller *ctrl)
+static void __pcie_wait_link_active(struct controller *ctrl, bool active)
 {
 	int timeout = 1000;
 
-	if (check_link_active(ctrl))
+	if (check_link_active(ctrl) == active)
 		return;
 	while (timeout > 0) {
 		msleep(10);
 		timeout -= 10;
-		if (check_link_active(ctrl))
+		if (check_link_active(ctrl) == active)
 			return;
 	}
-	ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n");
+	ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n",
+			active ? "set" : "cleared");
+}
+
+static void pcie_wait_link_active(struct controller *ctrl)
+{
+	__pcie_wait_link_active(ctrl, true);
+}
+
+static void pcie_wait_link_not_active(struct controller *ctrl)
+{
+	__pcie_wait_link_active(ctrl, false);
+}
+
+static bool pci_bus_check_dev(struct pci_bus *bus, int devfn)
+{
+	u32 l;
+	int count = 0;
+	int delay = 1000, step = 20;
+	bool found = false;
+
+	do {
+		found = pci_bus_read_dev_vendor_id(bus, devfn, &l, 0);
+		count++;
+
+		if (found)
+			break;
+
+		msleep(step);
+		delay -= step;
+	} while (delay > 0);
+
+	if (count > 1 && pciehp_debug)
+		printk(KERN_DEBUG "pci %04x:%02x:%02x.%d id reading try %d times with interval %d ms to get %08x\n",
+			pci_domain_nr(bus), bus->number, PCI_SLOT(devfn),
+			PCI_FUNC(devfn), count, step, l);
+
+	return found;
 }
 
 int pciehp_check_link_status(struct controller *ctrl)
 {
 	u16 lnk_status;
 	int retval = 0;
+	bool found = false;
 
         /*
          * Data Link Layer Link Active Reporting must be capable for
@@ -280,13 +325,10 @@ int pciehp_check_link_status(struct controller *ctrl)
         else
                 msleep(1000);
 
-	/*
-	 * Need to wait for 1000 ms after Data Link Layer Link Active
-	 * (DLLLA) bit reads 1b before sending configuration request.
-	 * We need it before checking Link Training (LT) bit becuase
-	 * LT is still set even after DLLLA bit is set on some platform.
-	 */
-	msleep(1000);
+	/* wait 100ms before read pci conf, and try in 1s */
+	msleep(100);
+	found = pci_bus_check_dev(ctrl->pcie->port->subordinate,
+					PCI_DEVFN(0, 0));
 
 	retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status);
 	if (retval) {
@@ -302,19 +344,50 @@ int pciehp_check_link_status(struct controller *ctrl)
 		return retval;
 	}
 
-	/*
-	 * If the port supports Link speeds greater than 5.0 GT/s, we
-	 * must wait for 100 ms after Link training completes before
-	 * sending configuration request.
-	 */
-	if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT)
-		msleep(100);
-
 	pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
 
+	if (!found && !retval)
+		retval = -1;
+
 	return retval;
 }
 
+static int __pciehp_link_set(struct controller *ctrl, bool enable)
+{
+	u16 lnk_ctrl;
+	int retval = 0;
+
+	retval = pciehp_readw(ctrl, PCI_EXP_LNKCTL, &lnk_ctrl);
+	if (retval) {
+		ctrl_err(ctrl, "Cannot read LNKCTRL register\n");
+		return retval;
+	}
+
+	if (enable)
+		lnk_ctrl &= ~PCI_EXP_LNKCTL_LD;
+	else
+		lnk_ctrl |= PCI_EXP_LNKCTL_LD;
+
+	retval = pciehp_writew(ctrl, PCI_EXP_LNKCTL, lnk_ctrl);
+	if (retval) {
+		ctrl_err(ctrl, "Cannot write LNKCTRL register\n");
+		return retval;
+	}
+	ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl);
+
+	return retval;
+}
+
+static int pciehp_link_enable(struct controller *ctrl)
+{
+	return __pciehp_link_set(ctrl, true);
+}
+
+static int pciehp_link_disable(struct controller *ctrl)
+{
+	return __pciehp_link_set(ctrl, false);
+}
+
 int pciehp_get_attention_status(struct slot *slot, u8 *status)
 {
 	struct controller *ctrl = slot->ctrl;
@@ -533,6 +606,10 @@ int pciehp_power_on_slot(struct slot * slot)
 	ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
 		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 
+	retval = pciehp_link_enable(ctrl);
+	if (retval)
+		ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__);
+
 	return retval;
 }
 
@@ -543,6 +620,14 @@ int pciehp_power_off_slot(struct slot * slot)
 	u16 cmd_mask;
 	int retval;
 
+	/* Disable the link at first */
+	pciehp_link_disable(ctrl);
+	/* wait the link is down */
+	if (ctrl->link_active_reporting)
+		pcie_wait_link_not_active(ctrl);
+	else
+		msleep(1000);
+
 	slot_cmd = POWER_OFF;
 	cmd_mask = PCI_EXP_SLTCTL_PCC;
 	retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 0dab5ec..687b3c8 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -173,7 +173,13 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset)
 
 	sprintf(buf, "virtfn%u", id);
 	sysfs_remove_link(&dev->dev.kobj, buf);
-	sysfs_remove_link(&virtfn->dev.kobj, "physfn");
+	/*
+	 * pci_stop_dev() could have been called for this virtfn already,
+	 * so the directory for the virtfn may have been removed before.
+	 * Double check to avoid spurious sysfs warnings.
+	 */
+	if (virtfn->dev.kobj.sd)
+		sysfs_remove_link(&virtfn->dev.kobj, "physfn");
 
 	mutex_lock(&iov->dev->sriov->lock);
 	pci_remove_bus_device(virtfn);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 3623d65..6b54b23 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -72,9 +72,7 @@ int pci_add_dynid(struct pci_driver *drv,
 	list_add_tail(&dynid->node, &drv->dynids.list);
 	spin_unlock(&drv->dynids.lock);
 
-	get_driver(&drv->driver);
 	retval = driver_attach(&drv->driver);
-	put_driver(&drv->driver);
 
 	return retval;
 }
@@ -190,43 +188,34 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count)
 static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
 
 static int
-pci_create_newid_file(struct pci_driver *drv)
+pci_create_newid_files(struct pci_driver *drv)
 {
 	int error = 0;
-	if (drv->probe != NULL)
-		error = driver_create_file(&drv->driver, &driver_attr_new_id);
-	return error;
-}
 
-static void pci_remove_newid_file(struct pci_driver *drv)
-{
-	driver_remove_file(&drv->driver, &driver_attr_new_id);
-}
-
-static int
-pci_create_removeid_file(struct pci_driver *drv)
-{
-	int error = 0;
-	if (drv->probe != NULL)
-		error = driver_create_file(&drv->driver,&driver_attr_remove_id);
+	if (drv->probe != NULL) {
+		error = driver_create_file(&drv->driver, &driver_attr_new_id);
+		if (error == 0) {
+			error = driver_create_file(&drv->driver,
+					&driver_attr_remove_id);
+			if (error)
+				driver_remove_file(&drv->driver,
+						&driver_attr_new_id);
+		}
+	}
 	return error;
 }
 
-static void pci_remove_removeid_file(struct pci_driver *drv)
+static void pci_remove_newid_files(struct pci_driver *drv)
 {
 	driver_remove_file(&drv->driver, &driver_attr_remove_id);
+	driver_remove_file(&drv->driver, &driver_attr_new_id);
 }
 #else /* !CONFIG_HOTPLUG */
-static inline int pci_create_newid_file(struct pci_driver *drv)
-{
-	return 0;
-}
-static inline void pci_remove_newid_file(struct pci_driver *drv) {}
-static inline int pci_create_removeid_file(struct pci_driver *drv)
+static inline int pci_create_newid_files(struct pci_driver *drv)
 {
 	return 0;
 }
-static inline void pci_remove_removeid_file(struct pci_driver *drv) {}
+static inline void pci_remove_newid_files(struct pci_driver *drv) {}
 #endif
 
 /**
@@ -430,6 +419,16 @@ static void pci_device_shutdown(struct device *dev)
 		drv->shutdown(pci_dev);
 	pci_msi_shutdown(pci_dev);
 	pci_msix_shutdown(pci_dev);
+
+	/*
+	 * Devices may be enabled to wake up by runtime PM, but they need not
+	 * be supposed to wake up the system from its "power off" state (e.g.
+	 * ACPI S5).  Therefore disable wakeup for all devices that aren't
+	 * supposed to wake up the system at this point.  The state argument
+	 * will be ignored by pci_enable_wake().
+	 */
+	if (!device_may_wakeup(dev))
+		pci_enable_wake(pci_dev, PCI_UNKNOWN, false);
 }
 
 #ifdef CONFIG_PM
@@ -1138,18 +1137,12 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
 	if (error)
 		goto out;
 
-	error = pci_create_newid_file(drv);
+	error = pci_create_newid_files(drv);
 	if (error)
 		goto out_newid;
-
-	error = pci_create_removeid_file(drv);
-	if (error)
-		goto out_removeid;
 out:
 	return error;
 
-out_removeid:
-	pci_remove_newid_file(drv);
 out_newid:
 	driver_unregister(&drv->driver);
 	goto out;
@@ -1168,8 +1161,7 @@ out_newid:
 void
 pci_unregister_driver(struct pci_driver *drv)
 {
-	pci_remove_removeid_file(drv);
-	pci_remove_newid_file(drv);
+	pci_remove_newid_files(drv);
 	driver_unregister(&drv->driver);
 	pci_free_dynids(drv);
 }
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index a3cd8ca..d972303 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -366,7 +366,10 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
 
 	if (val) {
 		mutex_lock(&pci_remove_rescan_mutex);
-		pci_rescan_bus(bus);
+		if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
+			pci_rescan_bus_bridge_resize(bus->self);
+		else
+			pci_rescan_bus(bus);
 		mutex_unlock(&pci_remove_rescan_mutex);
 	}
 	return count;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index af295bb..9c89447 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -959,6 +959,7 @@ void pci_restore_state(struct pci_dev *dev)
 {
 	int i;
 	u32 val;
+	int tries;
 
 	if (!dev->state_saved)
 		return;
@@ -973,12 +974,16 @@ void pci_restore_state(struct pci_dev *dev)
 	 */
 	for (i = 15; i >= 0; i--) {
 		pci_read_config_dword(dev, i * 4, &val);
-		if (val != dev->saved_config_space[i]) {
+		tries = 10;		
+		while (tries && val != dev->saved_config_space[i]) {
 			dev_dbg(&dev->dev, "restoring config "
 				"space at offset %#x (was %#x, writing %#x)\n",
 				i, val, (int)dev->saved_config_space[i]);
 			pci_write_config_dword(dev,i * 4,
 				dev->saved_config_space[i]);
+			pci_read_config_dword(dev, i * 4, &val);
+			mdelay(10);
+			tries--;
 		}
 	}
 	pci_restore_pcix_state(dev);
@@ -3163,6 +3168,31 @@ int __pci_reset_function(struct pci_dev *dev)
 EXPORT_SYMBOL_GPL(__pci_reset_function);
 
 /**
+ * __pci_reset_function_locked - reset a PCI device function while holding
+ * the @dev mutex lock.
+ * @dev: PCI device to reset
+ *
+ * Some devices allow an individual function to be reset without affecting
+ * other functions in the same device.  The PCI device must be responsive
+ * to PCI config space in order to use this function.
+ *
+ * The device function is presumed to be unused and the caller is holding
+ * the device mutex lock when this function is called.
+ * Resetting the device will make the contents of PCI configuration space
+ * random, so any caller of this must be prepared to reinitialise the
+ * device including MSI, bus mastering, BARs, decoding IO and memory spaces,
+ * etc.
+ *
+ * Returns 0 if the device function was successfully reset or negative if the
+ * device doesn't support resetting a single function.
+ */
+int __pci_reset_function_locked(struct pci_dev *dev)
+{
+	return pci_dev_reset(dev, 1);
+}
+EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
+
+/**
  * pci_probe_reset_function - check whether the device can be safely reset
  * @dev: PCI device to reset
  *
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1009a5e..aaf7ff8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -207,6 +207,8 @@ enum pci_bar_type {
 	pci_bar_mem64,		/* A 64-bit memory BAR */
 };
 
+bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
+				int crs_timeout);
 extern int pci_setup_device(struct pci_dev *dev);
 extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 				struct resource *res, unsigned int reg);
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index 72962cc..6c8bc58 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -55,6 +55,31 @@ config PCIEASPM_DEBUG
 	  This enables PCI Express ASPM debug support. It will add per-device
 	  interface to control ASPM.
 
+choice
+	prompt "Default ASPM policy"
+	default PCIEASPM_DEFAULT
+	depends on PCIEASPM
+
+config PCIEASPM_DEFAULT
+        bool "BIOS default"
+	depends on PCIEASPM
+	help
+	  Use the BIOS defaults for PCI Express ASPM.
+
+config PCIEASPM_POWERSAVE
+        bool "Powersave"
+	depends on PCIEASPM
+	help
+	  Enable PCI Express ASPM L0s and L1 where possible, even if the
+	  BIOS did not.
+
+config PCIEASPM_PERFORMANCE
+        bool "Performance"
+	depends on PCIEASPM
+	help
+	  Disable PCI Express ASPM L0s and L1, even if the BIOS enabled them.
+endchoice
+
 config PCIE_PME
 	def_bool y
 	depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 1cfbf22..a0de5e1 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -76,7 +76,15 @@ static LIST_HEAD(link_list);
 #define POLICY_DEFAULT 0	/* BIOS default setting */
 #define POLICY_PERFORMANCE 1	/* high performance */
 #define POLICY_POWERSAVE 2	/* high power saving */
+
+#ifdef CONFIG_PCIEASPM_PERFORMANCE
+static int aspm_policy = POLICY_PERFORMANCE;
+#elif defined CONFIG_PCIEASPM_POWERSAVE
+static int aspm_policy = POLICY_POWERSAVE;
+#else
 static int aspm_policy;
+#endif
+
 static const char *policy_str[] = {
 	[POLICY_DEFAULT] = "default",
 	[POLICY_PERFORMANCE] = "performance",
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 71eac9c..9f2ff8c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1118,40 +1118,54 @@ struct pci_dev *alloc_pci_dev(void)
 }
 EXPORT_SYMBOL(alloc_pci_dev);
 
-/*
- * Read the config data for a PCI device, sanity-check it
- * and fill in the dev structure...
- */
-static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
+bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
+				 int crs_timeout)
 {
-	struct pci_dev *dev;
-	u32 l;
 	int delay = 1;
 
-	if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
-		return NULL;
+	if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
+		return false;
 
 	/* some broken boards return 0 or ~0 if a slot is empty: */
-	if (l == 0xffffffff || l == 0x00000000 ||
-	    l == 0x0000ffff || l == 0xffff0000)
-		return NULL;
+	if (*l == 0xffffffff || *l == 0x00000000 ||
+	    *l == 0x0000ffff || *l == 0xffff0000)
+		return false;
 
 	/* Configuration request Retry Status */
-	while (l == 0xffff0001) {
+	while (*l == 0xffff0001) {
+		if (!crs_timeout)
+			return false;
+
 		msleep(delay);
 		delay *= 2;
-		if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
-			return NULL;
+		if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
+			return false;
 		/* Card hasn't responded in 60 seconds?  Must be stuck. */
-		if (delay > 60 * 1000) {
+		if (delay > crs_timeout) {
 			printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not "
 					"responding\n", pci_domain_nr(bus),
 					bus->number, PCI_SLOT(devfn),
 					PCI_FUNC(devfn));
-			return NULL;
+			return false;
 		}
 	}
 
+	return true;
+}
+EXPORT_SYMBOL(pci_bus_read_dev_vendor_id);
+
+/*
+ * Read the config data for a PCI device, sanity-check it
+ * and fill in the dev structure...
+ */
+static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
+{
+	struct pci_dev *dev;
+	u32 l;
+
+	if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000))
+		return NULL;
+
 	dev = alloc_pci_dev();
 	if (!dev)
 		return NULL;
@@ -1667,36 +1681,29 @@ EXPORT_SYMBOL(pci_scan_bus);
 
 #ifdef CONFIG_HOTPLUG
 /**
- * pci_rescan_bus - scan a PCI bus for devices.
- * @bus: PCI bus to scan
+ * pci_rescan_bus_bridge_resize - scan a PCI bus for devices.
+ * @bridge: PCI bridge for the bus to scan
  *
- * Scan a PCI bus and child buses for new devices, adds them,
- * and enables them.
+ * Scan a PCI bus and child buses for new devices, add them,
+ * and enable them, resizing bridge mmio/io resource if necessary
+ * and possible.  The caller must ensure the child devices are already
+ * removed for resizing to occur.
  *
  * Returns the max number of subordinate bus discovered.
  */
-unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
+unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
 {
 	unsigned int max;
-	struct pci_dev *dev;
+	struct pci_bus *bus = bridge->subordinate;
 
 	max = pci_scan_child_bus(bus);
 
-	down_read(&pci_bus_sem);
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
-			if (dev->subordinate)
-				pci_bus_size_bridges(dev->subordinate);
-	up_read(&pci_bus_sem);
+	pci_assign_unassigned_bridge_resources(bridge);
 
-	pci_bus_assign_resources(bus);
-	pci_enable_bridges(bus);
 	pci_bus_add_devices(bus);
 
 	return max;
 }
-EXPORT_SYMBOL_GPL(pci_rescan_bus);
 
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_scan_slot);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6476547..fb544d6 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -26,6 +26,8 @@
 #include <linux/dmi.h>
 #include <linux/pci-aspm.h>
 #include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/ktime.h>
 #include <asm/dma.h>	/* isa_dma_bridge_buggy */
 #include "pci.h"
 
@@ -2906,6 +2908,56 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f8, quirk_intel_mc_errata);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
 
+
+static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *dev)
+{
+	ktime_t calltime, delta, rettime;
+	unsigned long long duration;
+
+	printk(KERN_DEBUG "calling  %pF @ %i\n", fn, task_pid_nr(current));
+	calltime = ktime_get();
+	fn(dev);
+	rettime = ktime_get();
+	delta = ktime_sub(rettime, calltime);
+	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
+	printk(KERN_DEBUG "pci fixup %pF returned after %lld usecs\n", fn,
+		duration);
+}
+
+/*
+ * Some BIOS implementations leave the Intel GPU interrupts enabled,
+ * even though no one is handling them (f.e. i915 driver is never loaded).
+ * Additionally the interrupt destination is not set up properly
+ * and the interrupt ends up -somewhere-.
+ *
+ * These spurious interrupts are "sticky" and the kernel disables
+ * the (shared) interrupt line after 100.000+ generated interrupts.
+ *
+ * Fix it by disabling the still enabled interrupts.
+ * This resolves crashes often seen on monitor unplug.
+ */
+#define I915_DEIER_REG 0x4400c
+static void __devinit disable_igfx_irq(struct pci_dev *dev)
+{
+	void __iomem *regs = pci_iomap(dev, 0, 0);
+	if (regs == NULL) {
+		dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n");
+		return;
+	}
+
+	/* Check if any interrupt line is still enabled */
+	if (readl(regs + I915_DEIER_REG) != 0) {
+		dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; "
+			"disabling\n");
+
+		writel(0, regs + I915_DEIER_REG);
+	}
+
+	pci_iounmap(dev, regs);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
 			  struct pci_fixup *end)
 {
@@ -2913,7 +2965,10 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
 		if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
 		    (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
 			dev_dbg(&dev->dev, "calling %pF\n", f->hook);
-			f->hook(dev);
+			if (initcall_debug)
+				do_one_fixup_debug(f->hook, dev);
+			else
+				f->hook(dev);
 		}
 		f++;
 	}
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index ef8b18c..82f8ae5 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -144,7 +144,15 @@ static void pci_stop_bus_devices(struct pci_bus *bus)
 {
 	struct list_head *l, *n;
 
-	list_for_each_safe(l, n, &bus->devices) {
+	/*
+	 * VFs could be removed by pci_remove_bus_device() in the
+	 *  pci_stop_bus_devices() code path for PF.
+	 *  aka, bus->devices get updated in the process.
+	 * but VFs are inserted after PFs when SRIOV is enabled for PF,
+	 * We can iterate the list backwards to get prev valid PF instead
+	 *  of removed VF.
+	 */
+	list_for_each_prev_safe(l, n, &bus->devices) {
 		struct pci_dev *dev = pci_dev_b(l);
 		pci_stop_bus_device(dev);
 	}
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 86b69f85..090217a 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -27,8 +27,8 @@
 #include <linux/slab.h>
 #include "pci.h"
 
-struct resource_list_x {
-	struct resource_list_x *next;
+struct pci_dev_resource {
+	struct list_head list;
 	struct resource *res;
 	struct pci_dev *dev;
 	resource_size_t start;
@@ -38,15 +38,15 @@ struct resource_list_x {
 	unsigned long flags;
 };
 
-#define free_list(type, head) do {                      \
-	struct type *list, *tmp;			\
-	for (list = (head)->next; list;) {		\
-		tmp = list;				\
-		list = list->next;			\
-		kfree(tmp);				\
-	}						\
-	(head)->next = NULL;				\
-} while (0)
+static void free_list(struct list_head *head)
+{
+	struct pci_dev_resource *dev_res, *tmp;
+
+	list_for_each_entry_safe(dev_res, tmp, head, list) {
+		list_del(&dev_res->list);
+		kfree(dev_res);
+	}
+}
 
 int pci_realloc_enable = 0;
 #define pci_realloc_enabled() pci_realloc_enable
@@ -64,21 +64,18 @@ void pci_realloc(void)
  * @add_size:	additional size to be optionally added
  *              to the resource
  */
-static void add_to_list(struct resource_list_x *head,
+static int add_to_list(struct list_head *head,
 		 struct pci_dev *dev, struct resource *res,
 		 resource_size_t add_size, resource_size_t min_align)
 {
-	struct resource_list_x *list = head;
-	struct resource_list_x *ln = list->next;
-	struct resource_list_x *tmp;
+	struct pci_dev_resource *tmp;
 
-	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
 	if (!tmp) {
 		pr_warning("add_to_list: kmalloc() failed!\n");
-		return;
+		return -ENOMEM;
 	}
 
-	tmp->next = ln;
 	tmp->res = res;
 	tmp->dev = dev;
 	tmp->start = res->start;
@@ -86,19 +83,100 @@ static void add_to_list(struct resource_list_x *head,
 	tmp->flags = res->flags;
 	tmp->add_size = add_size;
 	tmp->min_align = min_align;
-	list->next = tmp;
+
+	list_add(&tmp->list, head);
+
+	return 0;
+}
+
+static void remove_from_list(struct list_head *head,
+				 struct resource *res)
+{
+	struct pci_dev_resource *dev_res, *tmp;
+
+	list_for_each_entry_safe(dev_res, tmp, head, list) {
+		if (dev_res->res == res) {
+			list_del(&dev_res->list);
+			kfree(dev_res);
+			break;
+		}
+	}
 }
 
-static void add_to_failed_list(struct resource_list_x *head,
-				struct pci_dev *dev, struct resource *res)
+static resource_size_t get_res_add_size(struct list_head *head,
+					struct resource *res)
 {
-	add_to_list(head, dev, res,
-			0 /* dont care */,
-			0 /* dont care */);
+	struct pci_dev_resource *dev_res;
+
+	list_for_each_entry(dev_res, head, list) {
+		if (dev_res->res == res) {
+			int idx = res - &dev_res->dev->resource[0];
+
+			dev_printk(KERN_DEBUG, &dev_res->dev->dev,
+				 "res[%d]=%pR get_res_add_size add_size %llx\n",
+				 idx, dev_res->res,
+				 (unsigned long long)dev_res->add_size);
+
+			return dev_res->add_size;
+		}
+	}
+
+	return 0;
+}
+
+/* Sort resources by alignment */
+static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
+{
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		struct resource *r;
+		struct pci_dev_resource *dev_res, *tmp;
+		resource_size_t r_align;
+		struct list_head *n;
+
+		r = &dev->resource[i];
+
+		if (r->flags & IORESOURCE_PCI_FIXED)
+			continue;
+
+		if (!(r->flags) || r->parent)
+			continue;
+
+		r_align = pci_resource_alignment(dev, r);
+		if (!r_align) {
+			dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
+				 i, r);
+			continue;
+		}
+
+		tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+		if (!tmp)
+			panic("pdev_sort_resources(): "
+			      "kmalloc() failed!\n");
+		tmp->res = r;
+		tmp->dev = dev;
+
+		/* fallback is smallest one or list is empty*/
+		n = head;
+		list_for_each_entry(dev_res, head, list) {
+			resource_size_t align;
+
+			align = pci_resource_alignment(dev_res->dev,
+							 dev_res->res);
+
+			if (r_align > align) {
+				n = &dev_res->list;
+				break;
+			}
+		}
+		/* Insert it just before n*/
+		list_add_tail(&tmp->list, n);
+	}
 }
 
 static void __dev_sort_resources(struct pci_dev *dev,
-				 struct resource_list *head)
+				 struct list_head *head)
 {
 	u16 class = dev->class >> 8;
 
@@ -136,49 +214,54 @@ static inline void reset_resource(struct resource *res)
  * additional resources for the element, provided the element
  * is in the head list.
  */
-static void reassign_resources_sorted(struct resource_list_x *realloc_head,
-		struct resource_list *head)
+static void reassign_resources_sorted(struct list_head *realloc_head,
+		struct list_head *head)
 {
 	struct resource *res;
-	struct resource_list_x *list, *tmp, *prev;
-	struct resource_list *hlist;
+	struct pci_dev_resource *add_res, *tmp;
+	struct pci_dev_resource *dev_res;
 	resource_size_t add_size;
 	int idx;
 
-	prev = realloc_head;
-	for (list = realloc_head->next; list;) {
-		res = list->res;
+	list_for_each_entry_safe(add_res, tmp, realloc_head, list) {
+		bool found_match = false;
+
+		res = add_res->res;
 		/* skip resource that has been reset */
 		if (!res->flags)
 			goto out;
 
 		/* skip this resource if not found in head list */
-		for (hlist = head->next; hlist && hlist->res != res;
-				hlist = hlist->next);
-		if (!hlist) { /* just skip */
-			prev = list;
-			list = list->next;
-			continue;
+		list_for_each_entry(dev_res, head, list) {
+			if (dev_res->res == res) {
+				found_match = true;
+				break;
+			}
 		}
+		if (!found_match)/* just skip */
+			continue;
 
-		idx = res - &list->dev->resource[0];
-		add_size=list->add_size;
+		idx = res - &add_res->dev->resource[0];
+		add_size = add_res->add_size;
 		if (!resource_size(res)) {
-			res->start = list->start;
+			res->start = add_res->start;
 			res->end = res->start + add_size - 1;
-			if(pci_assign_resource(list->dev, idx))
+			if (pci_assign_resource(add_res->dev, idx))
 				reset_resource(res);
 		} else {
-			resource_size_t align = list->min_align;
-			res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
-			if (pci_reassign_resource(list->dev, idx, add_size, align))
-				dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n",
-							res);
+			resource_size_t align = add_res->min_align;
+			res->flags |= add_res->flags &
+				 (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
+			if (pci_reassign_resource(add_res->dev, idx,
+						  add_size, align))
+				dev_printk(KERN_DEBUG, &add_res->dev->dev,
+					   "failed to add %llx res[%d]=%pR\n",
+					   (unsigned long long)add_size,
+					   idx, res);
 		}
 out:
-		tmp = list;
-		prev->next = list = list->next;
-		kfree(tmp);
+		list_del(&add_res->list);
+		kfree(add_res);
 	}
 }
 
@@ -192,35 +275,99 @@ out:
  * Satisfy resource requests of each element in the list. Add
  * requests that could not satisfied to the failed_list.
  */
-static void assign_requested_resources_sorted(struct resource_list *head,
-				 struct resource_list_x *fail_head)
+static void assign_requested_resources_sorted(struct list_head *head,
+				 struct list_head *fail_head)
 {
 	struct resource *res;
-	struct resource_list *list;
+	struct pci_dev_resource *dev_res;
 	int idx;
 
-	for (list = head->next; list; list = list->next) {
-		res = list->res;
-		idx = res - &list->dev->resource[0];
-		if (resource_size(res) && pci_assign_resource(list->dev, idx)) {
-			if (fail_head && !pci_is_root_bus(list->dev->bus)) {
+	list_for_each_entry(dev_res, head, list) {
+		res = dev_res->res;
+		idx = res - &dev_res->dev->resource[0];
+		if (resource_size(res) &&
+		    pci_assign_resource(dev_res->dev, idx)) {
+			if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) {
 				/*
 				 * if the failed res is for ROM BAR, and it will
 				 * be enabled later, don't add it to the list
 				 */
 				if (!((idx == PCI_ROM_RESOURCE) &&
 				      (!(res->flags & IORESOURCE_ROM_ENABLE))))
-					add_to_failed_list(fail_head, list->dev, res);
+					add_to_list(fail_head,
+						    dev_res->dev, res,
+						    0 /* dont care */,
+						    0 /* dont care */);
 			}
 			reset_resource(res);
 		}
 	}
 }
 
-static void __assign_resources_sorted(struct resource_list *head,
-				 struct resource_list_x *realloc_head,
-				 struct resource_list_x *fail_head)
+static void __assign_resources_sorted(struct list_head *head,
+				 struct list_head *realloc_head,
+				 struct list_head *fail_head)
 {
+	/*
+	 * Should not assign requested resources at first.
+	 *   they could be adjacent, so later reassign can not reallocate
+	 *   them one by one in parent resource window.
+	 * Try to assign requested + add_size at begining
+	 *  if could do that, could get out early.
+	 *  if could not do that, we still try to assign requested at first,
+	 *    then try to reassign add_size for some resources.
+	 */
+	LIST_HEAD(save_head);
+	LIST_HEAD(local_fail_head);
+	struct pci_dev_resource *save_res;
+	struct pci_dev_resource *dev_res;
+
+	/* Check if optional add_size is there */
+	if (!realloc_head || list_empty(realloc_head))
+		goto requested_and_reassign;
+
+	/* Save original start, end, flags etc at first */
+	list_for_each_entry(dev_res, head, list) {
+		if (add_to_list(&save_head, dev_res->dev, dev_res->res, 0, 0)) {
+			free_list(&save_head);
+			goto requested_and_reassign;
+		}
+	}
+
+	/* Update res in head list with add_size in realloc_head list */
+	list_for_each_entry(dev_res, head, list)
+		dev_res->res->end += get_res_add_size(realloc_head,
+							dev_res->res);
+
+	/* Try updated head list with add_size added */
+	assign_requested_resources_sorted(head, &local_fail_head);
+
+	/* all assigned with add_size ? */
+	if (list_empty(&local_fail_head)) {
+		/* Remove head list from realloc_head list */
+		list_for_each_entry(dev_res, head, list)
+			remove_from_list(realloc_head, dev_res->res);
+		free_list(&save_head);
+		free_list(head);
+		return;
+	}
+
+	free_list(&local_fail_head);
+	/* Release assigned resource */
+	list_for_each_entry(dev_res, head, list)
+		if (dev_res->res->parent)
+			release_resource(dev_res->res);
+	/* Restore start/end/flags from saved list */
+	list_for_each_entry(save_res, &save_head, list) {
+		struct resource *res = save_res->res;
+
+		res->start = save_res->start;
+		res->end = save_res->end;
+		res->flags = save_res->flags;
+	}
+	free_list(&save_head);
+
+requested_and_reassign:
 	/* Satisfy the must-have resource requests */
 	assign_requested_resources_sorted(head, fail_head);
 
@@ -228,28 +375,27 @@ static void __assign_resources_sorted(struct resource_list *head,
 		requests */
 	if (realloc_head)
 		reassign_resources_sorted(realloc_head, head);
-	free_list(resource_list, head);
+	free_list(head);
 }
 
 static void pdev_assign_resources_sorted(struct pci_dev *dev,
-				 struct resource_list_x *fail_head)
+				 struct list_head *add_head,
+				 struct list_head *fail_head)
 {
-	struct resource_list head;
+	LIST_HEAD(head);
 
-	head.next = NULL;
 	__dev_sort_resources(dev, &head);
-	__assign_resources_sorted(&head, NULL, fail_head);
+	__assign_resources_sorted(&head, add_head, fail_head);
 
 }
 
 static void pbus_assign_resources_sorted(const struct pci_bus *bus,
-					 struct resource_list_x *realloc_head,
-					 struct resource_list_x *fail_head)
+					 struct list_head *realloc_head,
+					 struct list_head *fail_head)
 {
 	struct pci_dev *dev;
-	struct resource_list head;
+	LIST_HEAD(head);
 
-	head.next = NULL;
 	list_for_each_entry(dev, &bus->devices, bus_list)
 		__dev_sort_resources(dev, &head);
 
@@ -548,20 +694,6 @@ static resource_size_t calculate_memsize(resource_size_t size,
 	return size;
 }
 
-static resource_size_t get_res_add_size(struct resource_list_x *realloc_head,
-					struct resource *res)
-{
-	struct resource_list_x *list;
-
-	/* check if it is in realloc_head list */
-	for (list = realloc_head->next; list && list->res != res;
-			list = list->next);
-	if (list)
-		return list->add_size;
-
-	return 0;
-}
-
 /**
  * pbus_size_io() - size the io window of a given bus
  *
@@ -576,7 +708,7 @@ static resource_size_t get_res_add_size(struct resource_list_x *realloc_head,
  * We must be careful with the ISA aliasing though.
  */
 static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
-		resource_size_t add_size, struct resource_list_x *realloc_head)
+		resource_size_t add_size, struct list_head *realloc_head)
 {
 	struct pci_dev *dev;
 	struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
@@ -612,7 +744,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 	if (children_add_size > add_size)
 		add_size = children_add_size;
 	size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
-		calculate_iosize(size, min_size+add_size, size1,
+		calculate_iosize(size, min_size, add_size + size1,
 			resource_size(b_res), 4096);
 	if (!size0 && !size1) {
 		if (b_res->start || b_res->end)
@@ -626,8 +758,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 	b_res->start = 4096;
 	b_res->end = b_res->start + size0 - 1;
 	b_res->flags |= IORESOURCE_STARTALIGN;
-	if (size1 > size0 && realloc_head)
+	if (size1 > size0 && realloc_head) {
 		add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
+		dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
+				 "%pR to [bus %02x-%02x] add_size %lx\n", b_res,
+				 bus->secondary, bus->subordinate, size1-size0);
+	}
 }
 
 /**
@@ -644,7 +780,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 			 unsigned long type, resource_size_t min_size,
 			resource_size_t add_size,
-			struct resource_list_x *realloc_head)
+			struct list_head *realloc_head)
 {
 	struct pci_dev *dev;
 	resource_size_t min_align, align, size, size0, size1;
@@ -726,7 +862,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 	if (children_add_size > add_size)
 		add_size = children_add_size;
 	size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 :
-		calculate_memsize(size, min_size+add_size, 0,
+		calculate_memsize(size, min_size, add_size,
 				resource_size(b_res), min_align);
 	if (!size0 && !size1) {
 		if (b_res->start || b_res->end)
@@ -739,8 +875,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 	b_res->start = min_align;
 	b_res->end = size0 + min_align - 1;
 	b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask;
-	if (size1 > size0 && realloc_head)
+	if (size1 > size0 && realloc_head) {
 		add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
+		dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
+				 "%pR to [bus %02x-%02x] add_size %llx\n", b_res,
+				 bus->secondary, bus->subordinate, (unsigned long long)size1-size0);
+	}
 	return 1;
 }
 
@@ -754,7 +894,7 @@ unsigned long pci_cardbus_resource_alignment(struct resource *res)
 }
 
 static void pci_bus_size_cardbus(struct pci_bus *bus,
-			struct resource_list_x *realloc_head)
+			struct list_head *realloc_head)
 {
 	struct pci_dev *bridge = bus->self;
 	struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
@@ -816,7 +956,7 @@ static void pci_bus_size_cardbus(struct pci_bus *bus,
 }
 
 void __ref __pci_bus_size_bridges(struct pci_bus *bus,
-			struct resource_list_x *realloc_head)
+			struct list_head *realloc_head)
 {
 	struct pci_dev *dev;
 	unsigned long mask, prefmask;
@@ -858,7 +998,8 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
 		 * Follow thru
 		 */
 	default:
-		pbus_size_io(bus, 0, additional_io_size, realloc_head);
+		pbus_size_io(bus, realloc_head ? 0 : additional_io_size,
+			     additional_io_size, realloc_head);
 		/* If the bridge supports prefetchable range, size it
 		   separately. If it doesn't, or its prefetchable window
 		   has already been allocated by arch code, try
@@ -866,11 +1007,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
 		   resources. */
 		mask = IORESOURCE_MEM;
 		prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-		if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, realloc_head))
+		if (pbus_size_mem(bus, prefmask, prefmask,
+				  realloc_head ? 0 : additional_mem_size,
+				  additional_mem_size, realloc_head))
 			mask = prefmask; /* Success, size non-prefetch only. */
 		else
 			additional_mem_size += additional_mem_size;
-		pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, realloc_head);
+		pbus_size_mem(bus, mask, IORESOURCE_MEM,
+				realloc_head ? 0 : additional_mem_size,
+				additional_mem_size, realloc_head);
 		break;
 	}
 }
@@ -882,8 +1027,8 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
 static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
-					 struct resource_list_x *realloc_head,
-					 struct resource_list_x *fail_head)
+					 struct list_head *realloc_head,
+					 struct list_head *fail_head)
 {
 	struct pci_bus *b;
 	struct pci_dev *dev;
@@ -922,17 +1067,19 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus)
 EXPORT_SYMBOL(pci_bus_assign_resources);
 
 static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge,
-					 struct resource_list_x *fail_head)
+					 struct list_head *add_head,
+					 struct list_head *fail_head)
 {
 	struct pci_bus *b;
 
-	pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head);
+	pdev_assign_resources_sorted((struct pci_dev *)bridge,
+					 add_head, fail_head);
 
 	b = bridge->subordinate;
 	if (!b)
 		return;
 
-	__pci_bus_assign_resources(b, NULL, fail_head);
+	__pci_bus_assign_resources(b, add_head, fail_head);
 
 	switch (bridge->class >> 8) {
 	case PCI_CLASS_BRIDGE_PCI:
@@ -1105,59 +1252,61 @@ void __init
 pci_assign_unassigned_resources(void)
 {
 	struct pci_bus *bus;
-	struct resource_list_x realloc_list; /* list of resources that
+	LIST_HEAD(realloc_head); /* list of resources that
 					want additional resources */
+	struct list_head *add_list = NULL;
 	int tried_times = 0;
 	enum release_type rel_type = leaf_only;
-	struct resource_list_x head, *list;
+	LIST_HEAD(fail_head);
+	struct pci_dev_resource *fail_res;
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
 				  IORESOURCE_PREFETCH;
 	unsigned long failed_type;
-	int max_depth = pci_get_max_depth();
-	int pci_try_num;
-
+	int pci_try_num = 1;
 
-	head.next = NULL;
-	realloc_list.next = NULL;
+	/* don't realloc if asked to do so */
+	if (pci_realloc_enabled()) {
+		int max_depth = pci_get_max_depth();
 
-	pci_try_num = max_depth + 1;
-	printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
-		 max_depth, pci_try_num);
+		pci_try_num = max_depth + 1;
+		printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
+			 max_depth, pci_try_num);
+	}
 
 again:
+	/*
+	 * last try will use add_list, otherwise will try good to have as
+	 * must have, so can realloc parent bridge resource
+	 */
+	if (tried_times + 1 == pci_try_num)
+		add_list = &realloc_head;
 	/* Depth first, calculate sizes and alignments of all
 	   subordinate buses. */
 	list_for_each_entry(bus, &pci_root_buses, node)
-		__pci_bus_size_bridges(bus, &realloc_list);
+		__pci_bus_size_bridges(bus, add_list);
 
 	/* Depth last, allocate resources and update the hardware. */
 	list_for_each_entry(bus, &pci_root_buses, node)
-		__pci_bus_assign_resources(bus, &realloc_list, &head);
-	BUG_ON(realloc_list.next);
+		__pci_bus_assign_resources(bus, add_list, &fail_head);
+	if (add_list)
+		BUG_ON(!list_empty(add_list));
 	tried_times++;
 
 	/* any device complain? */
-	if (!head.next)
-		goto enable_and_dump;
-
-	/* don't realloc if asked to do so */
-	if (!pci_realloc_enabled()) {
-		free_list(resource_list_x, &head);
+	if (list_empty(&fail_head))
 		goto enable_and_dump;
-	}
 
 	failed_type = 0;
-	for (list = head.next; list;) {
-		failed_type |= list->flags;
-		list = list->next;
-	}
+	list_for_each_entry(fail_res, &fail_head, list)
+		failed_type |= fail_res->flags;
+
 	/*
 	 * io port are tight, don't try extra
 	 * or if reach the limit, don't want to try more
 	 */
 	failed_type &= type_mask;
 	if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
-		free_list(resource_list_x, &head);
+		free_list(&fail_head);
 		goto enable_and_dump;
 	}
 
@@ -1172,25 +1321,23 @@ again:
 	 * Try to release leaf bridge's resources that doesn't fit resource of
 	 * child device under that bridge
 	 */
-	for (list = head.next; list;) {
-		bus = list->dev->bus;
-		pci_bus_release_bridge_resources(bus, list->flags & type_mask,
-						  rel_type);
-		list = list->next;
+	list_for_each_entry(fail_res, &fail_head, list) {
+		bus = fail_res->dev->bus;
+		pci_bus_release_bridge_resources(bus,
+						 fail_res->flags & type_mask,
+						 rel_type);
 	}
 	/* restore size and flags */
-	for (list = head.next; list;) {
-		struct resource *res = list->res;
+	list_for_each_entry(fail_res, &fail_head, list) {
+		struct resource *res = fail_res->res;
 
-		res->start = list->start;
-		res->end = list->end;
-		res->flags = list->flags;
-		if (list->dev->subordinate)
+		res->start = fail_res->start;
+		res->end = fail_res->end;
+		res->flags = fail_res->flags;
+		if (fail_res->dev->subordinate)
 			res->flags = 0;
-
-		list = list->next;
 	}
-	free_list(resource_list_x, &head);
+	free_list(&fail_head);
 
 	goto again;
 
@@ -1207,26 +1354,27 @@ enable_and_dump:
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 {
 	struct pci_bus *parent = bridge->subordinate;
+	LIST_HEAD(add_list); /* list of resources that
+					want additional resources */
 	int tried_times = 0;
-	struct resource_list_x head, *list;
+	LIST_HEAD(fail_head);
+	struct pci_dev_resource *fail_res;
 	int retval;
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
 				  IORESOURCE_PREFETCH;
 
-	head.next = NULL;
-
 again:
-	pci_bus_size_bridges(parent);
-	__pci_bridge_assign_resources(bridge, &head);
-
+	__pci_bus_size_bridges(parent, &add_list);
+	__pci_bridge_assign_resources(bridge, &add_list, &fail_head);
+	BUG_ON(!list_empty(&add_list));
 	tried_times++;
 
-	if (!head.next)
+	if (list_empty(&fail_head))
 		goto enable_all;
 
 	if (tried_times >= 2) {
 		/* still fail, don't need to try more */
-		free_list(resource_list_x, &head);
+		free_list(&fail_head);
 		goto enable_all;
 	}
 
@@ -1237,27 +1385,24 @@ again:
 	 * Try to release leaf bridge's resources that doesn't fit resource of
 	 * child device under that bridge
 	 */
-	for (list = head.next; list;) {
-		struct pci_bus *bus = list->dev->bus;
-		unsigned long flags = list->flags;
+	list_for_each_entry(fail_res, &fail_head, list) {
+		struct pci_bus *bus = fail_res->dev->bus;
+		unsigned long flags = fail_res->flags;
 
 		pci_bus_release_bridge_resources(bus, flags & type_mask,
 						 whole_subtree);
-		list = list->next;
 	}
 	/* restore size and flags */
-	for (list = head.next; list;) {
-		struct resource *res = list->res;
+	list_for_each_entry(fail_res, &fail_head, list) {
+		struct resource *res = fail_res->res;
 
-		res->start = list->start;
-		res->end = list->end;
-		res->flags = list->flags;
-		if (list->dev->subordinate)
+		res->start = fail_res->start;
+		res->end = fail_res->end;
+		res->flags = fail_res->flags;
+		if (fail_res->dev->subordinate)
 			res->flags = 0;
-
-		list = list->next;
 	}
-	free_list(resource_list_x, &head);
+	free_list(&fail_head);
 
 	goto again;
 
@@ -1267,3 +1412,41 @@ enable_all:
 	pci_enable_bridges(parent);
 }
 EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
+
+#ifdef CONFIG_HOTPLUG
+/**
+ * pci_rescan_bus - scan a PCI bus for devices.
+ * @bus: PCI bus to scan
+ *
+ * Scan a PCI bus and child buses for new devices, adds them,
+ * and enables them.
+ *
+ * Returns the max number of subordinate bus discovered.
+ */
+unsigned int __ref pci_rescan_bus(struct pci_bus *bus)
+{
+	unsigned int max;
+	struct pci_dev *dev;
+	LIST_HEAD(add_list); /* list of resources that
+					want additional resources */
+
+	max = pci_scan_child_bus(bus);
+
+	down_read(&pci_bus_sem);
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+			if (dev->subordinate)
+				__pci_bus_size_bridges(dev->subordinate,
+							 &add_list);
+	up_read(&pci_bus_sem);
+	__pci_bus_assign_resources(bus, &add_list, NULL);
+	BUG_ON(!list_empty(&add_list));
+
+	pci_enable_bridges(bus);
+	pci_bus_add_devices(bus);
+
+	return max;
+}
+EXPORT_SYMBOL_GPL(pci_rescan_bus);
+#endif
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index b66bfdb..f968185 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -158,22 +158,44 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	return ret;
 }
 
+/*
+ * Generic function that returns a value indicating that the device's
+ * original BIOS BAR address was not saved and so is not available for
+ * reinstatement.
+ *
+ * Can be over-ridden by architecture specific code that implements
+ * reinstatement functionality rather than leaving it disabled when
+ * normal allocation attempts fail.
+ */
+resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
+{
+	return 0;
+}
+
 static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, 
 		int resno, resource_size_t size)
 {
 	struct resource *root, *conflict;
-	resource_size_t start, end;
+	resource_size_t fw_addr, start, end;
 	int ret = 0;
 
-	if (res->flags & IORESOURCE_IO)
-		root = &ioport_resource;
-	else
-		root = &iomem_resource;
+	fw_addr = pcibios_retrieve_fw_addr(dev, resno);
+	if (!fw_addr)
+		return 1;
 
 	start = res->start;
 	end = res->end;
-	res->start = dev->fw_addr[resno];
+	res->start = fw_addr;
 	res->end = res->start + size - 1;
+
+	root = pci_find_parent_resource(dev, res);
+	if (!root) {
+		if (res->flags & IORESOURCE_IO)
+			root = &ioport_resource;
+		else
+			root = &iomem_resource;
+	}
+
 	dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
 		 resno, res);
 	conflict = request_resource_conflict(root, res);
@@ -228,16 +250,17 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
 	int ret;
 
 	if (!res->parent) {
-		dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resouce %pR "
+		dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR "
 			 "\n", resno, res);
 		return -EINVAL;
 	}
 
-	new_size = resource_size(res) + addsize + min_align;
+	/* already aligned with min_align */
+	new_size = resource_size(res) + addsize;
 	ret = _pci_assign_resource(dev, resno, new_size, min_align);
 	if (!ret) {
 		res->flags &= ~IORESOURCE_STARTALIGN;
-		dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
+		dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
 		if (resno < PCI_BRIDGE_RESOURCES)
 			pci_update_resource(dev, resno);
 	}
@@ -267,7 +290,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 	 * where firmware left it.  That at least has a chance of
 	 * working, which is better than just leaving it disabled.
 	 */
-	if (ret < 0 && dev->fw_addr[resno])
+	if (ret < 0)
 		ret = pci_revert_fw_address(res, dev, resno, size);
 
 	if (!ret) {
@@ -279,53 +302,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 	return ret;
 }
 
-
-/* Sort resources by alignment */
-void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
-{
-	int i;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		struct resource *r;
-		struct resource_list *list, *tmp;
-		resource_size_t r_align;
-
-		r = &dev->resource[i];
-
-		if (r->flags & IORESOURCE_PCI_FIXED)
-			continue;
-
-		if (!(r->flags) || r->parent)
-			continue;
-
-		r_align = pci_resource_alignment(dev, r);
-		if (!r_align) {
-			dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
-				 i, r);
-			continue;
-		}
-		for (list = head; ; list = list->next) {
-			resource_size_t align = 0;
-			struct resource_list *ln = list->next;
-
-			if (ln)
-				align = pci_resource_alignment(ln->dev, ln->res);
-
-			if (r_align > align) {
-				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
-				if (!tmp)
-					panic("pdev_sort_resources(): "
-					      "kmalloc() failed!\n");
-				tmp->next = ln;
-				tmp->res = r;
-				tmp->dev = dev;
-				list->next = tmp;
-				break;
-			}
-		}
-	}
-}
-
 int pci_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 1620088..4010901 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -593,7 +593,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
 	}
 	pdrv = pcidev->driver;
 
-	if (get_driver(&pdrv->driver)) {
+	if (pdrv) {
 		if (pdrv->err_handler && pdrv->err_handler->error_detected) {
 			dev_dbg(&pcidev->dev,
 				"trying to call AER service\n");
@@ -623,7 +623,6 @@ static pci_ers_result_t pcifront_common_process(int cmd,
 				}
 			}
 		}
-		put_driver(&pdrv->driver);
 	}
 	if (!flag)
 		result = PCI_ERS_RESULT_NONE;
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index f9e3fb3..bba3ab2 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -183,10 +183,14 @@ config PCMCIA_BCM63XX
 config PCMCIA_SOC_COMMON
 	tristate
 
+config PCMCIA_SA11XX_BASE
+	tristate
+
 config PCMCIA_SA1100
 	tristate "SA1100 support"
 	depends on ARM && ARCH_SA1100 && PCMCIA
 	select PCMCIA_SOC_COMMON
+	select PCMCIA_SA11XX_BASE
 	help
 	  Say Y here to include support for SA11x0-based PCMCIA or CF
 	  sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
@@ -196,8 +200,9 @@ config PCMCIA_SA1100
 
 config PCMCIA_SA1111
 	tristate "SA1111 support"
-	depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
+	depends on ARM && SA1111 && PCMCIA
 	select PCMCIA_SOC_COMMON
+	select PCMCIA_SA11XX_BASE if ARCH_SA1100
 	help
 	  Say Y  here to include support for SA1111-based PCMCIA or CF
 	  sockets, found on the Jornada 720, Graphicsmaster and other
@@ -213,6 +218,7 @@ config PCMCIA_PXA2XX
 		    || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
 		    || MACH_VPAC270 || MACH_BALLOON3 || MACH_COLIBRI \
 		    || MACH_COLIBRI320)
+	select PCMCIA_SA1111 if ARCH_LUBBOCK && SA1111
 	select PCMCIA_SOC_COMMON
 	help
 	  Say Y here to include support for the PXA2xx PCMCIA controller
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index ec543a4..47525de 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,8 +25,9 @@ obj-$(CONFIG_I82092)				+= i82092.o
 obj-$(CONFIG_TCIC)				+= tcic.o
 obj-$(CONFIG_PCMCIA_M8XX)			+= m8xx_pcmcia.o
 obj-$(CONFIG_PCMCIA_SOC_COMMON)			+= soc_common.o
-obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_base.o sa1100_cs.o
-obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_base.o sa1111_cs.o
+obj-$(CONFIG_PCMCIA_SA11XX_BASE)		+= sa11xx_base.o
+obj-$(CONFIG_PCMCIA_SA1100)			+= sa1100_cs.o
+obj-$(CONFIG_PCMCIA_SA1111)			+= sa1111_cs.o
 obj-$(CONFIG_M32R_PCC)				+= m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)				+= m32r_cfc.o
 obj-$(CONFIG_PCMCIA_BCM63XX)			+= bcm63xx_pcmcia.o
@@ -39,9 +40,10 @@ obj-$(CONFIG_ELECTRA_CF)			+= electra_cf.o
 obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD)		+= db1xxx_ss.o
 
 sa1111_cs-y					+= sa1111_generic.o
-sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1100_neponset.o
-sa1111_cs-$(CONFIG_SA1100_BADGE4)		+= sa1100_badge4.o
-sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1100_jornada720.o
+sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+= sa1111_neponset.o
+sa1111_cs-$(CONFIG_SA1100_BADGE4)		+= sa1111_badge4.o
+sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1111_jornada720.o
+sa1111_cs-$(CONFIG_ARCH_LUBBOCK)		+= sa1111_lubbock.o
 
 sa1100_cs-y					+= sa1100_generic.o
 sa1100_cs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
@@ -52,9 +54,7 @@ sa1100_cs-$(CONFIG_SA1100_NANOENGINE)		+= sa1100_nanoengine.o
 sa1100_cs-$(CONFIG_SA1100_SHANNON)		+= sa1100_shannon.o
 sa1100_cs-$(CONFIG_SA1100_SIMPAD)		+= sa1100_simpad.o
 
-pxa2xx_lubbock_cs-y				+= pxa2xx_lubbock.o sa1111_generic.o
 pxa2xx_cm_x2xx_cs-y				+= pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
-pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK)		+= pxa2xx_lubbock_cs.o
 pxa2xx-obj-$(CONFIG_MACH_MAINSTONE)		+= pxa2xx_mainstone.o
 pxa2xx-obj-$(CONFIG_PXA_SHARPSL)		+= pxa2xx_sharpsl.o
 pxa2xx-obj-$(CONFIG_MACH_ARMCORE)		+= pxa2xx_cm_x2xx_cs.o
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 1932029..079629b 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -127,10 +127,7 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
 	list_add_tail(&dynid->node, &pdrv->dynids.list);
 	mutex_unlock(&pdrv->dynids.lock);
 
-	if (get_driver(&pdrv->drv)) {
-		retval = driver_attach(&pdrv->drv);
-		put_driver(&pdrv->drv);
-	}
+	retval = driver_attach(&pdrv->drv);
 
 	if (retval)
 		return retval;
@@ -160,6 +157,11 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv)
 	return error;
 }
 
+static void
+pcmcia_remove_newid_file(struct pcmcia_driver *drv)
+{
+	driver_remove_file(&drv->drv, &driver_attr_new_id);
+}
 
 /**
  * pcmcia_register_driver - register a PCMCIA driver with the bus core
@@ -204,6 +206,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
 void pcmcia_unregister_driver(struct pcmcia_driver *driver)
 {
 	pr_debug("unregistering driver %s\n", driver->name);
+	pcmcia_remove_newid_file(driver);
 	driver_unregister(&driver->drv);
 	pcmcia_free_dynids(driver);
 }
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c
index 22a75e6..2ef576c 100644
--- a/drivers/pcmcia/pxa2xx_balloon3.c
+++ b/drivers/pcmcia/pxa2xx_balloon3.c
@@ -29,15 +29,6 @@
 
 #include "soc_common.h"
 
-/*
- * These are a list of interrupt sources that provokes a polled
- * check of status
- */
-static struct pcmcia_irqs irqs[] = {
-	{ 0, BALLOON3_S0_CD_IRQ, "PCMCIA0 CD" },
-	{ 0, BALLOON3_BP_NSTSCHG_IRQ, "PCMCIA0 STSCHG" },
-};
-
 static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	uint16_t ver;
@@ -49,12 +40,12 @@ static int balloon3_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 			ver);
 
 	skt->socket.pci_irq = BALLOON3_BP_CF_NRDY_IRQ;
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
+	skt->stat[SOC_STAT_CD].gpio = BALLOON3_GPIO_S0_CD;
+	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+	skt->stat[SOC_STAT_BVD1].irq = BALLOON3_BP_NSTSCHG_IRQ;
+	skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
 
-static void balloon3_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	return 0;
 }
 
 static unsigned long balloon3_pcmcia_status[2] = {
@@ -85,13 +76,11 @@ static void balloon3_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 			disable_irq(BALLOON3_BP_NSTSCHG_IRQ);
 	}
 
-	state->detect	= !gpio_get_value(BALLOON3_GPIO_S0_CD);
 	state->ready	= !!(status & BALLOON3_CF_nIRQ);
 	state->bvd1	= !!(status & BALLOON3_CF_nSTSCHG_BVD1);
 	state->bvd2	= 0;	/* not available */
 	state->vs_3v	= 1;	/* Always true its a CF card */
 	state->vs_Xv	= 0;	/* not available */
-	state->wrprot	= 0;	/* not available */
 }
 
 static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
@@ -106,7 +95,6 @@ static int balloon3_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 static struct pcmcia_low_level balloon3_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 	.hw_init		= balloon3_pcmcia_hw_init,
-	.hw_shutdown		= balloon3_pcmcia_hw_shutdown,
 	.socket_state		= balloon3_pcmcia_socket_state,
 	.configure_socket	= balloon3_pcmcia_configure_socket,
 	.first			= 0,
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index a87e272..18474f0 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 
 		skt->nr = ops->first + i;
 		skt->clk = clk;
-		skt->ops = ops;
-		skt->socket.owner = ops->owner;
-		skt->socket.dev.parent = &dev->dev;
-		skt->socket.pci_irq = NO_IRQ;
+		soc_pcmcia_init_one(skt, ops, &dev->dev);
 
 		ret = pxa2xx_drv_pcmcia_add_one(skt);
 		if (ret)
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 31ab6ddf..da40908 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -25,17 +25,6 @@
 #define GPIO_PCMCIA_S1_RDYINT	(8)
 #define GPIO_PCMCIA_RESET	(9)
 
-#define PCMCIA_S0_CD_VALID	gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
-#define PCMCIA_S1_CD_VALID	gpio_to_irq(GPIO_PCMCIA_S1_CD_VALID)
-#define PCMCIA_S0_RDYINT	gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
-#define PCMCIA_S1_RDYINT	gpio_to_irq(GPIO_PCMCIA_S1_RDYINT)
-
-
-static struct pcmcia_irqs irqs[] = {
-	{ .sock = 0, .str = "PCMCIA0 CD" },
-	{ .sock = 1, .str = "PCMCIA1 CD" },
-};
-
 static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
@@ -43,19 +32,23 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 		return ret;
 	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-	skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
-	irqs[0].irq = PCMCIA_S0_CD_VALID;
-	irqs[1].irq = PCMCIA_S1_CD_VALID;
-	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-	if (!ret)
-		gpio_free(GPIO_PCMCIA_RESET);
+	if (skt->nr == 0) {
+		skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
+	} else {
+		skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S1_CD_VALID;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S1_RDYINT;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA1 RDY";
+	}
 
-	return ret;
+	return 0;
 }
 
 static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 	gpio_free(GPIO_PCMCIA_RESET);
 }
 
@@ -63,16 +56,8 @@ static void cmx255_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 				       struct pcmcia_state *state)
 {
-	int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
-	int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
-
-	state->detect = !gpio_get_value(cd);
-	state->ready  = !!gpio_get_value(rdy);
-	state->bvd1   = 1;
-	state->bvd2   = 1;
 	state->vs_3v  = 0;
 	state->vs_Xv  = 0;
-	state->wrprot = 0;  /* not available */
 }
 
 
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index 3dc7621..f59223f 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -22,14 +22,6 @@
 #define GPIO_PCMCIA_S0_RDYINT	(82)
 #define GPIO_PCMCIA_RESET	(53)
 
-#define PCMCIA_S0_CD_VALID	gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID)
-#define PCMCIA_S0_RDYINT	gpio_to_irq(GPIO_PCMCIA_S0_RDYINT)
-
-
-static struct pcmcia_irqs irqs[] = {
-	{ .sock = 0, .str = "PCMCIA0 CD" },
-};
-
 static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset");
@@ -37,18 +29,16 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 		return ret;
 	gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-	skt->socket.pci_irq = PCMCIA_S0_RDYINT;
-	irqs[0].irq = PCMCIA_S0_CD_VALID;
-	ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-	if (!ret)
-		gpio_free(GPIO_PCMCIA_RESET);
+	skt->stat[SOC_STAT_CD].gpio = GPIO_PCMCIA_S0_CD_VALID;
+	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+	skt->stat[SOC_STAT_RDY].gpio = GPIO_PCMCIA_S0_RDYINT;
+	skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
 
 	return ret;
 }
 
 static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 	gpio_free(GPIO_PCMCIA_RESET);
 }
 
@@ -56,13 +46,8 @@ static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt)
 static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 				       struct pcmcia_state *state)
 {
-	state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0;
-	state->ready  = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1;
-	state->bvd1   = 1;
-	state->bvd2   = 1;
 	state->vs_3v  = 0;
 	state->vs_Xv  = 0;
-	state->wrprot = 0;  /* not available */
 }
 
 
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c
index c6dec57..4dee7b2 100644
--- a/drivers/pcmcia/pxa2xx_colibri.c
+++ b/drivers/pcmcia/pxa2xx_colibri.c
@@ -53,13 +53,6 @@ static struct gpio colibri_pcmcia_gpios[] = {
 	{ 0,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
 };
 
-static struct pcmcia_irqs colibri_irqs[] = {
-	{
-		.sock = 0,
-		.str  = "PCMCIA CD"
-	},
-};
-
 static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret;
@@ -69,19 +62,10 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	if (ret)
 		goto err1;
 
-	colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
 	skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
+	skt->stat[SOC_STAT_CD].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
+	skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
 
-	ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
-					ARRAY_SIZE(colibri_irqs));
-	if (ret)
-		goto err2;
-
-	return ret;
-
-err2:
-	gpio_free_array(colibri_pcmcia_gpios,
-			ARRAY_SIZE(colibri_pcmcia_gpios));
 err1:
 	return ret;
 }
@@ -100,7 +84,6 @@ static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 	state->ready  = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
 	state->bvd1   = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
 	state->bvd2   = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
-	state->wrprot = 0;
 	state->vs_3v  = 1;
 	state->vs_Xv  = 0;
 }
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c
index 17cd2ce..8751a32 100644
--- a/drivers/pcmcia/pxa2xx_e740.c
+++ b/drivers/pcmcia/pxa2xx_e740.c
@@ -23,53 +23,27 @@
 
 #include "soc_common.h"
 
-static struct pcmcia_irqs cd_irqs[] = {
-	{
-		.sock = 0,
-		.str  = "CF card detect"
-	},
-	{
-		.sock = 1,
-		.str  = "Wifi switch"
-	},
-};
-
 static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	if (skt->nr == 0)
-		skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0);
-	else
-		skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1);
-
-	cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0);
-	cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1);
-
-	return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
-}
+	if (skt->nr == 0) {
+		skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD0;
+		skt->stat[SOC_STAT_CD].name = "CF card detect";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY0;
+		skt->stat[SOC_STAT_RDY].name = "CF ready";
+	} else {
+		skt->stat[SOC_STAT_CD].gpio = GPIO_E740_PCMCIA_CD1;
+		skt->stat[SOC_STAT_CD].name = "Wifi switch";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO_E740_PCMCIA_RDY1;
+		skt->stat[SOC_STAT_RDY].name = "Wifi ready";
+	}
 
-/*
- * Release all resources.
- */
-static void e740_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, &cd_irqs[skt->nr], 1);
+	return 0;
 }
 
 static void e740_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 					struct pcmcia_state *state)
 {
-	if (skt->nr == 0) {
-		state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD0) ? 0 : 1;
-		state->ready  = gpio_get_value(GPIO_E740_PCMCIA_RDY0) ? 1 : 0;
-	} else {
-		state->detect = gpio_get_value(GPIO_E740_PCMCIA_CD1) ? 0 : 1;
-		state->ready  = gpio_get_value(GPIO_E740_PCMCIA_RDY1) ? 1 : 0;
-	}
-
 	state->vs_3v  = 1;
-	state->bvd1   = 1;
-	state->bvd2   = 1;
-	state->wrprot = 0;
 	state->vs_Xv  = 0;
 }
 
@@ -109,32 +83,11 @@ static int e740_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	return 0;
 }
 
-/*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void e740_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_enable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
-}
-
-/*
- * Disable card status IRQs on suspend.
- */
-static void e740_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_disable_irqs(skt, cd_irqs, ARRAY_SIZE(cd_irqs));
-}
-
 static struct pcmcia_low_level e740_pcmcia_ops = {
 	.owner            = THIS_MODULE,
 	.hw_init          = e740_pcmcia_hw_init,
-	.hw_shutdown      = e740_pcmcia_hw_shutdown,
 	.socket_state     = e740_pcmcia_socket_state,
 	.configure_socket = e740_pcmcia_configure_socket,
-	.socket_init      = e740_pcmcia_socket_init,
-	.socket_suspend   = e740_pcmcia_socket_suspend,
 	.nr               = 2,
 };
 
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
deleted file mode 100644
index c21888e..0000000
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * linux/drivers/pcmcia/pxa2xx_lubbock.c
- *
- * Author:	George Davis
- * Created:	Jan 10, 2002
- * Copyright:	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 version 2 as
- * published by the Free Software Foundation.
- *
- * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
- *
- * Lubbock PCMCIA specific routines.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
-#include <asm/mach-types.h>
-#include <mach/lubbock.h>
-
-#include "sa1111_generic.h"
-
-static int
-lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
-				const socket_state_t *state)
-{
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
-	int ret = 0;
-
-	pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
-
-	/* Lubbock uses the Maxim MAX1602, with the following connections:
-	 *
-	 * Socket 0 (PCMCIA):
-	 *	MAX1602	Lubbock		Register
-	 *	Pin	Signal
-	 *	-----	-------		----------------------
-	 *	A0VPP	S0_PWR0		SA-1111 GPIO A<0>
-	 *	A1VPP	S0_PWR1		SA-1111 GPIO A<1>
-	 *	A0VCC	S0_PWR2		SA-1111 GPIO A<2>
-	 *	A1VCC	S0_PWR3		SA-1111 GPIO A<3>
-	 *	VX	VCC
-	 *	VY	+3.3V
-	 *	12IN	+12V
-	 *	CODE	+3.3V		Cirrus  Code, CODE = High (VY)
-	 *
-	 * Socket 1 (CF):
-	 *	MAX1602	Lubbock		Register
-	 *	Pin	Signal
-	 *	-----	-------		----------------------
-	 *	A0VPP	GND		VPP is not connected
-	 *	A1VPP	GND		VPP is not connected
-	 *	A0VCC	S1_PWR0		MISC_WR<14>
-	 *	A1VCC	S1_PWR1		MISC_WR<15>
-	 *	VX	VCC
-	 *	VY	+3.3V
-	 *	12IN	GND		VPP is not connected
-	 *	CODE	+3.3V		Cirrus  Code, CODE = High (VY)
-	 *
-	 */
-
- again:
-	switch (skt->nr) {
-	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			pa_dwr_set |= GPIO_A3;
-			break;
-
-		case 50: /* VX */
-			pa_dwr_set |= GPIO_A2;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-		}
-
-		switch (state->Vpp) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 120: /* 12IN */
-			pa_dwr_set |= GPIO_A1;
-			break;
-
-		default: /* VCC */
-			if (state->Vpp == state->Vcc)
-				pa_dwr_set |= GPIO_A0;
-			else {
-				printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-				       __func__, state->Vpp);
-				ret = -1;
-				break;
-			}
-		}
-		break;
-
-	case 1:
-		misc_mask = (1 << 15) | (1 << 14);
-
-		switch (state->Vcc) {
-		case 0: /* Hi-Z */
-			break;
-
-		case 33: /* VY */
-			misc_set |= 1 << 15;
-			break;
-
-		case 50: /* VX */
-			misc_set |= 1 << 14;
-			break;
-
-		default:
-			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-			       __func__, state->Vcc);
-			ret = -1;
-			break;
-		}
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-			       __func__, state->Vpp);
-			ret = -1;
-			break;
-		}
-		break;
-
-	default:
-		ret = -1;
-	}
-
-	if (ret == 0)
-		ret = sa1111_pcmcia_configure_socket(skt, state);
-
-	if (ret == 0) {
-		lubbock_set_misc_wr(misc_mask, misc_set);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
-
-#if 1
-	if (ret == 0 && state->Vcc == 33) {
-		struct pcmcia_state new_state;
-
-		/*
-		 * HACK ALERT:
-		 * We can't sense the voltage properly on Lubbock before
-		 * actually applying some power to the socket (catch 22).
-		 * Resense the socket Voltage Sense pins after applying
-		 * socket power.
-		 *
-		 * Note: It takes about 2.5ms for the MAX1602 VCC output
-		 * to rise.
-		 */
-		mdelay(3);
-
-		sa1111_pcmcia_socket_state(skt, &new_state);
-
-		if (!new_state.vs_3v && !new_state.vs_Xv) {
-			/*
-			 * Switch to 5V,  Configure socket with 5V voltage
-			 */
-			lubbock_set_misc_wr(misc_mask, 0);
-			sa1111_set_io(s->dev, pa_dwr_mask, 0);
-
-			/*
-			 * It takes about 100ms to turn off Vcc.
-			 */
-			mdelay(100);
-
-			/*
-			 * We need to hack around the const qualifier as
-			 * well to keep this ugly workaround localized and
-			 * not force it to the rest of the code. Barf bags
-			 * available in the seat pocket in front of you!
-			 */
-			((socket_state_t *)state)->Vcc = 50;
-			((socket_state_t *)state)->Vpp = 50;
-			goto again;
-		}
-	}
-#endif
-
-	return ret;
-}
-
-static struct pcmcia_low_level lubbock_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-	.configure_socket	= lubbock_pcmcia_configure_socket,
-	.socket_init		= sa1111_pcmcia_socket_init,
-	.first			= 0,
-	.nr			= 2,
-};
-
-#include "pxa2xx_base.h"
-
-int pcmcia_lubbock_init(struct sa1111_dev *sadev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_lubbock()) {
-		/*
-		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-		 * and switch to standby mode.
-		 */
-		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-
-		/* Set CF Socket 1 power to standby mode. */
-		lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
-
-		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
-		pxa2xx_configure_sockets(&sadev->dev);
-		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
-				pxa2xx_drv_pcmcia_add_one);
-	}
-
-	return ret;
-}
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index aded706c..7e32e25 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -30,27 +30,26 @@
 #include "soc_common.h"
 
 
-static struct pcmcia_irqs irqs[] = {
-	{ 0, MAINSTONE_S0_CD_IRQ, "PCMCIA0 CD" },
-	{ 1, MAINSTONE_S1_CD_IRQ, "PCMCIA1 CD" },
-	{ 0, MAINSTONE_S0_STSCHG_IRQ, "PCMCIA0 STSCHG" },
-	{ 1, MAINSTONE_S1_STSCHG_IRQ, "PCMCIA1 STSCHG" },
-};
-
 static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	/*
 	 * Setup default state of GPIO outputs
 	 * before we enable them as outputs.
 	 */
-
-	skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void mst_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	if (skt->nr == 0) {
+		skt->socket.pci_irq = MAINSTONE_S0_IRQ;
+		skt->stat[SOC_STAT_CD].irq = MAINSTONE_S0_CD_IRQ;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+		skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S0_STSCHG_IRQ;
+		skt->stat[SOC_STAT_BVD1].name = "PCMCIA0 STSCHG";
+	} else {
+		skt->socket.pci_irq = MAINSTONE_S1_IRQ;
+		skt->stat[SOC_STAT_CD].irq = MAINSTONE_S1_CD_IRQ;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA1 CD";
+		skt->stat[SOC_STAT_BVD1].irq = MAINSTONE_S1_STSCHG_IRQ;
+		skt->stat[SOC_STAT_BVD1].name = "PCMCIA1 STSCHG";
+	}
+	return 0;
 }
 
 static unsigned long mst_pcmcia_status[2];
@@ -84,7 +83,6 @@ static void mst_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 	state->bvd2   = (status & MST_PCMCIA_nSPKR_BVD2) ? 1 : 0;
 	state->vs_3v  = (status & MST_PCMCIA_nVS1) ? 0 : 1;
 	state->vs_Xv  = (status & MST_PCMCIA_nVS2) ? 0 : 1;
-	state->wrprot = 0;  /* not available */
 }
 
 static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
@@ -131,7 +129,6 @@ static int mst_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 static struct pcmcia_low_level mst_pcmcia_ops __initdata = {
 	.owner			= THIS_MODULE,
 	.hw_init		= mst_pcmcia_hw_init,
-	.hw_shutdown		= mst_pcmcia_hw_shutdown,
 	.socket_state		= mst_pcmcia_socket_state,
 	.configure_socket	= mst_pcmcia_configure_socket,
 	.nr			= 2,
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
index 6a8e011..ed7d4db 100644
--- a/drivers/pcmcia/pxa2xx_palmld.c
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -23,7 +23,6 @@
 static struct gpio palmld_pcmcia_gpios[] = {
 	{ GPIO_NR_PALMLD_PCMCIA_POWER,	GPIOF_INIT_LOW,	"PCMCIA Power" },
 	{ GPIO_NR_PALMLD_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
-	{ GPIO_NR_PALMLD_PCMCIA_READY,	GPIOF_IN,	"PCMCIA Ready" },
 };
 
 static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
@@ -33,7 +32,8 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	ret = gpio_request_array(palmld_pcmcia_gpios,
 				ARRAY_SIZE(palmld_pcmcia_gpios));
 
-	skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMLD_PCMCIA_READY);
+	skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMLD_PCMCIA_READY;
+	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 
 	return ret;
 }
@@ -47,10 +47,6 @@ static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 					struct pcmcia_state *state)
 {
 	state->detect = 1; /* always inserted */
-	state->ready  = !!gpio_get_value(GPIO_NR_PALMLD_PCMCIA_READY);
-	state->bvd1   = 1;
-	state->bvd2   = 1;
-	state->wrprot = 0;
 	state->vs_3v  = 1;
 	state->vs_Xv  = 0;
 }
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c
index 9e38de7..81225a7 100644
--- a/drivers/pcmcia/pxa2xx_palmtc.c
+++ b/drivers/pcmcia/pxa2xx_palmtc.c
@@ -26,7 +26,6 @@ static struct gpio palmtc_pcmcia_gpios[] = {
 	{ GPIO_NR_PALMTC_PCMCIA_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },
 	{ GPIO_NR_PALMTC_PCMCIA_POWER3,	GPIOF_INIT_LOW,	"PCMCIA Power 3" },
 	{ GPIO_NR_PALMTC_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
-	{ GPIO_NR_PALMTC_PCMCIA_READY,	GPIOF_IN,	"PCMCIA Ready" },
 	{ GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN,	"PCMCIA Power Ready" },
 };
 
@@ -37,7 +36,8 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	ret = gpio_request_array(palmtc_pcmcia_gpios,
 				ARRAY_SIZE(palmtc_pcmcia_gpios));
 
-	skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTC_PCMCIA_READY);
+	skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTC_PCMCIA_READY;
+	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 
 	return ret;
 }
@@ -51,10 +51,6 @@ static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 					struct pcmcia_state *state)
 {
 	state->detect = 1; /* always inserted */
-	state->ready  = !!gpio_get_value(GPIO_NR_PALMTC_PCMCIA_READY);
-	state->bvd1   = 1;
-	state->bvd2   = 1;
-	state->wrprot = 0;
 	state->vs_3v  = 1;
 	state->vs_Xv  = 0;
 }
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index 80645a6..069b6bb 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -23,7 +23,6 @@ static struct gpio palmtx_pcmcia_gpios[] = {
 	{ GPIO_NR_PALMTX_PCMCIA_POWER1,	GPIOF_INIT_LOW,	"PCMCIA Power 1" },
 	{ GPIO_NR_PALMTX_PCMCIA_POWER2,	GPIOF_INIT_LOW,	"PCMCIA Power 2" },
 	{ GPIO_NR_PALMTX_PCMCIA_RESET,	GPIOF_INIT_HIGH,"PCMCIA Reset" },
-	{ GPIO_NR_PALMTX_PCMCIA_READY,	GPIOF_IN,	"PCMCIA Ready" },
 };
 
 static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
@@ -33,7 +32,8 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	ret = gpio_request_array(palmtx_pcmcia_gpios,
 				ARRAY_SIZE(palmtx_pcmcia_gpios));
 
-	skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
+	skt->stat[SOC_STAT_RDY].gpio = GPIO_NR_PALMTX_PCMCIA_READY;
+	skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 
 	return ret;
 }
@@ -47,10 +47,6 @@ static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 					struct pcmcia_state *state)
 {
 	state->detect = 1; /* always inserted */
-	state->ready  = !!gpio_get_value(GPIO_NR_PALMTX_PCMCIA_READY);
-	state->bvd1   = 1;
-	state->bvd2   = 1;
-	state->wrprot = 0;
 	state->vs_3v  = 1;
 	state->vs_Xv  = 0;
 }
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 69ae2fd..b066273 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -46,21 +46,9 @@ static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt)
 
 static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	int ret;
-
-	/* Register interrupts */
 	if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
-		struct pcmcia_irqs cd_irq;
-
-		cd_irq.sock = skt->nr;
-		cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq;
-		cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str;
-		ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
-
-		if (ret) {
-			printk(KERN_ERR "Request for Compact Flash IRQ failed\n");
-			return ret;
-		}
+		skt->stat[SOC_STAT_CD].irq = SCOOP_DEV[skt->nr].cd_irq;
+		skt->stat[SOC_STAT_CD].name = SCOOP_DEV[skt->nr].cd_irq_str;
 	}
 
 	skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
@@ -68,19 +56,6 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	return 0;
 }
 
-static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
-		struct pcmcia_irqs cd_irq;
-
-		cd_irq.sock = skt->nr;
-		cd_irq.irq  = SCOOP_DEV[skt->nr].cd_irq;
-		cd_irq.str  = SCOOP_DEV[skt->nr].cd_irq_str;
-		soc_pcmcia_free_irqs(skt, &cd_irq, 1);
-	}
-}
-
-
 static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 				    struct pcmcia_state *state)
 {
@@ -222,7 +197,6 @@ static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 static struct pcmcia_low_level sharpsl_pcmcia_ops __initdata = {
 	.owner                  = THIS_MODULE,
 	.hw_init                = sharpsl_pcmcia_hw_init,
-	.hw_shutdown            = sharpsl_pcmcia_hw_shutdown,
 	.socket_state           = sharpsl_pcmcia_socket_state,
 	.configure_socket       = sharpsl_pcmcia_configure_socket,
 	.socket_init            = sharpsl_pcmcia_socket_init,
diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c
index 6c2366b..1d73c44 100644
--- a/drivers/pcmcia/pxa2xx_stargate2.c
+++ b/drivers/pcmcia/pxa2xx_stargate2.c
@@ -33,10 +33,6 @@
 #define SG2_S0_GPIO_DETECT	53
 #define SG2_S0_GPIO_READY	81
 
-static struct pcmcia_irqs irqs[] = {
-	{.sock = 0, .str = "PCMCIA0 CD" },
-};
-
 static struct gpio sg2_pcmcia_gpios[] = {
 	{ SG2_S0_GPIO_RESET, GPIOF_OUT_INIT_HIGH, "PCMCIA Reset" },
 	{ SG2_S0_POWER_CTL, GPIOF_OUT_INIT_HIGH, "PCMCIA Power Ctrl" },
@@ -44,27 +40,20 @@ static struct gpio sg2_pcmcia_gpios[] = {
 
 static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY);
-	irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT);
-
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sg2_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	skt->stat[SOC_STAT_CD].gpio = SG2_S0_GPIO_DETECT;
+	skt->stat[SOC_STAT_CD].name = "PCMCIA0 CD";
+	skt->stat[SOC_STAT_RDY].gpio = SG2_S0_GPIO_READY;
+	skt->stat[SOC_STAT_RDY].name = "PCMCIA0 RDY";
+	return 0;
 }
 
 static void sg2_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 				    struct pcmcia_state *state)
 {
-	state->detect = !gpio_get_value(SG2_S0_GPIO_DETECT);
-	state->ready  = !!gpio_get_value(SG2_S0_GPIO_READY);
 	state->bvd1   = 0; /* not available - battery detect on card */
 	state->bvd2   = 0; /* not available */
 	state->vs_3v  = 1; /* not available - voltage detect for card */
 	state->vs_Xv  = 0; /* not available */
-	state->wrprot = 0; /* not available - write protect */
 }
 
 static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
@@ -94,24 +83,11 @@ static int sg2_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	return 0;
 }
 
-static void sg2_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sg2_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static struct pcmcia_low_level sg2_pcmcia_ops __initdata = {
 	.owner			= THIS_MODULE,
 	.hw_init		= sg2_pcmcia_hw_init,
-	.hw_shutdown		= sg2_pcmcia_hw_shutdown,
 	.socket_state		= sg2_pcmcia_socket_state,
 	.configure_socket	= sg2_pcmcia_configure_socket,
-	.socket_init		= sg2_pcmcia_socket_init,
-	.socket_suspend		= sg2_pcmcia_socket_suspend,
 	.nr			= 1,
 };
 
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
index 7c33f89..d326ba1 100644
--- a/drivers/pcmcia/pxa2xx_trizeps4.c
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -29,32 +29,17 @@
 
 extern void board_pcmcia_power(int power);
 
-static struct pcmcia_irqs irqs[] = {
-	{ .sock = 0, .str = "cs0_cd" }
-	/* on other baseboards we can have more inputs */
-};
-
 static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	int ret, i;
 	/* we dont have voltage/card/ready detection
 	 * so we dont need interrupts for it
 	 */
 	switch (skt->nr) {
 	case 0:
-		if (gpio_request(GPIO_PRDY, "cf_irq") < 0) {
-			pr_err("%s: sock %d unable to request gpio %d\n", __func__,
-				skt->nr, GPIO_PRDY);
-			return -EBUSY;
-		}
-		if (gpio_direction_input(GPIO_PRDY) < 0) {
-			pr_err("%s: sock %d unable to set input gpio %d\n", __func__,
-				skt->nr, GPIO_PRDY);
-			gpio_free(GPIO_PRDY);
-			return -EINVAL;
-		}
-		skt->socket.pci_irq = gpio_to_irq(GPIO_PRDY);
-		irqs[0].irq = gpio_to_irq(GPIO_PCD);
+		skt->stat[SOC_STAT_CD].gpio = GPIO_PCD;
+		skt->stat[SOC_STAT_CD].name = "cs0_cd";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO_PRDY;
+		skt->stat[SOC_STAT_RDY].name = "cs0_rdy";
 		break;
 	default:
 		break;
@@ -62,39 +47,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	/* release the reset of this card */
 	pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
 
-	/* supplementory irqs for the socket */
-	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		if (irqs[i].sock != skt->nr)
-			continue;
-		if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) {
-			pr_err("%s: sock %d unable to request gpio %d\n",
-				__func__, skt->nr, irq_to_gpio(irqs[i].irq));
-			ret = -EBUSY;
-			goto error;
-		}
-		if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) {
-			pr_err("%s: sock %d unable to set input gpio %d\n",
-				__func__, skt->nr, irq_to_gpio(irqs[i].irq));
-			ret = -EINVAL;
-			goto error;
-		}
-	}
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
-error:
-	for (; i >= 0; i--) {
-		gpio_free(irq_to_gpio(irqs[i].irq));
-	}
-	return (ret);
-}
-
-static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	int i;
-	/* free allocated gpio's */
-	gpio_free(GPIO_PRDY);
-	for (i = 0; i < ARRAY_SIZE(irqs); i++)
-		gpio_free(irq_to_gpio(irqs[i].irq));
+	return 0;
 }
 
 static unsigned long trizeps_pcmcia_status[2];
@@ -118,13 +71,10 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 	switch (skt->nr) {
 	case 0:
 		/* just fill in fix states */
-		state->detect = gpio_get_value(GPIO_PCD) ? 0 : 1;
-		state->ready  = gpio_get_value(GPIO_PRDY) ? 1 : 0;
 		state->bvd1   = (status & ConXS_CFSR_BVD1) ? 1 : 0;
 		state->bvd2   = (status & ConXS_CFSR_BVD2) ? 1 : 0;
 		state->vs_3v  = (status & ConXS_CFSR_VS1) ? 0 : 1;
 		state->vs_Xv  = (status & ConXS_CFSR_VS2) ? 0 : 1;
-		state->wrprot = 0;	/* not available */
 		break;
 
 #ifndef CONFIG_MACH_TRIZEPS_CONXS
@@ -136,7 +86,6 @@ static void trizeps_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 		state->bvd2   = 0;
 		state->vs_3v  = 0;
 		state->vs_Xv  = 0;
-		state->wrprot = 0;
 		break;
 
 #endif
@@ -204,7 +153,6 @@ static void trizeps_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 static struct pcmcia_low_level trizeps_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 	.hw_init		= trizeps_pcmcia_hw_init,
-	.hw_shutdown		= trizeps_pcmcia_hw_shutdown,
 	.socket_state		= trizeps_pcmcia_socket_state,
 	.configure_socket	= trizeps_pcmcia_configure_socket,
 	.socket_init		= trizeps_pcmcia_socket_init,
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
index 1064b1c..adfae49 100644
--- a/drivers/pcmcia/pxa2xx_viper.c
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -32,13 +32,6 @@
 
 static struct platform_device *arcom_pcmcia_dev;
 
-static struct pcmcia_irqs irqs[] = {
-	{
-		.sock	= 0,
-		.str	= "PCMCIA_CD",
-	},
-};
-
 static inline struct arcom_pcmcia_pdata *viper_get_pdata(void)
 {
 	return arcom_pcmcia_dev->dev.platform_data;
@@ -49,38 +42,28 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
 	unsigned long flags;
 
-	skt->socket.pci_irq = gpio_to_irq(pdata->rdy_gpio);
-	irqs[0].irq = gpio_to_irq(pdata->cd_gpio);
-
-	if (gpio_request(pdata->cd_gpio, "CF detect"))
-		goto err_request_cd;
-
-	if (gpio_request(pdata->rdy_gpio, "CF ready"))
-		goto err_request_rdy;
+	skt->stat[SOC_STAT_CD].gpio = pdata->cd_gpio;
+	skt->stat[SOC_STAT_CD].name = "PCMCIA_CD";
+	skt->stat[SOC_STAT_RDY].gpio = pdata->rdy_gpio;
+	skt->stat[SOC_STAT_RDY].name = "CF ready";
 
 	if (gpio_request(pdata->pwr_gpio, "CF power"))
 		goto err_request_pwr;
 
 	local_irq_save(flags);
 
-	if (gpio_direction_output(pdata->pwr_gpio, 0) ||
-	    gpio_direction_input(pdata->cd_gpio) ||
-	    gpio_direction_input(pdata->rdy_gpio)) {
+	if (gpio_direction_output(pdata->pwr_gpio, 0)) {
 		local_irq_restore(flags);
 		goto err_dir;
 	}
 
 	local_irq_restore(flags);
 
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	return 0;
 
 err_dir:
 	gpio_free(pdata->pwr_gpio);
 err_request_pwr:
-	gpio_free(pdata->rdy_gpio);
-err_request_rdy:
-	gpio_free(pdata->cd_gpio);
-err_request_cd:
 	dev_err(&arcom_pcmcia_dev->dev, "Failed to setup PCMCIA GPIOs\n");
 	return -1;
 }
@@ -92,22 +75,12 @@ static void viper_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
 	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
 
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 	gpio_free(pdata->pwr_gpio);
-	gpio_free(pdata->rdy_gpio);
-	gpio_free(pdata->cd_gpio);
 }
 
 static void viper_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 				      struct pcmcia_state *state)
 {
-	struct arcom_pcmcia_pdata *pdata = viper_get_pdata();
-
-	state->detect = !gpio_get_value(pdata->cd_gpio);
-	state->ready  = !!gpio_get_value(pdata->rdy_gpio);
-	state->bvd1   = 1;
-	state->bvd2   = 1;
-	state->wrprot = 0;
 	state->vs_3v  = 1; /* Can only apply 3.3V */
 	state->vs_Xv  = 0;
 }
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c
index 61b17d2..a47dcd2 100644
--- a/drivers/pcmcia/pxa2xx_vpac270.c
+++ b/drivers/pcmcia/pxa2xx_vpac270.c
@@ -23,29 +23,14 @@
 #include "soc_common.h"
 
 static struct gpio vpac270_pcmcia_gpios[] = {
-	{ GPIO84_VPAC270_PCMCIA_CD,	GPIOF_IN,	"PCMCIA Card Detect" },
-	{ GPIO35_VPAC270_PCMCIA_RDY,	GPIOF_IN,	"PCMCIA Ready" },
 	{ GPIO107_VPAC270_PCMCIA_PPEN,	GPIOF_INIT_LOW,	"PCMCIA PPEN" },
 	{ GPIO11_VPAC270_PCMCIA_RESET,	GPIOF_INIT_LOW,	"PCMCIA Reset" },
 };
 
 static struct gpio vpac270_cf_gpios[] = {
-	{ GPIO17_VPAC270_CF_CD,		GPIOF_IN,	"CF Card Detect" },
-	{ GPIO12_VPAC270_CF_RDY,	GPIOF_IN,	"CF Ready" },
 	{ GPIO16_VPAC270_CF_RESET,	GPIOF_INIT_LOW,	"CF Reset" },
 };
 
-static struct pcmcia_irqs cd_irqs[] = {
-	{
-		.sock = 0,
-		.str  = "PCMCIA CD"
-	},
-	{
-		.sock = 1,
-		.str  = "CF CD"
-	},
-};
-
 static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int ret;
@@ -54,20 +39,18 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 		ret = gpio_request_array(vpac270_pcmcia_gpios,
 				ARRAY_SIZE(vpac270_pcmcia_gpios));
 
-		skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
-		cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD);
-
-		if (!ret)
-			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
+		skt->stat[SOC_STAT_CD].gpio = GPIO84_VPAC270_PCMCIA_CD;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA CD";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO35_VPAC270_PCMCIA_RDY;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA Ready";
 	} else {
 		ret = gpio_request_array(vpac270_cf_gpios,
 				ARRAY_SIZE(vpac270_cf_gpios));
 
-		skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
-		cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD);
-
-		if (!ret)
-			ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
+		skt->stat[SOC_STAT_CD].gpio = GPIO17_VPAC270_CF_CD;
+		skt->stat[SOC_STAT_CD].name = "CF CD";
+		skt->stat[SOC_STAT_RDY].gpio = GPIO12_VPAC270_CF_RDY;
+		skt->stat[SOC_STAT_RDY].name = "CF Ready";
 	}
 
 	return ret;
@@ -86,16 +69,6 @@ static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 					struct pcmcia_state *state)
 {
-	if (skt->nr == 0) {
-		state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
-		state->ready  = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
-	} else {
-		state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
-		state->ready  = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
-	}
-	state->bvd1   = 1;
-	state->bvd2   = 1;
-	state->wrprot = 0;
 	state->vs_3v  = 1;
 	state->vs_Xv  = 0;
 }
@@ -117,14 +90,6 @@ vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	return 0;
 }
 
-static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-}
-
-static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-}
-
 static struct pcmcia_low_level vpac270_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 
@@ -136,9 +101,6 @@ static struct pcmcia_low_level vpac270_pcmcia_ops = {
 
 	.socket_state		= vpac270_pcmcia_socket_state,
 	.configure_socket	= vpac270_pcmcia_configure_socket,
-
-	.socket_init		= vpac270_pcmcia_socket_init,
-	.socket_suspend		= vpac270_pcmcia_socket_suspend,
 };
 
 static struct platform_device *vpac270_pcmcia_device;
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index f1e8822..ba8557e 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -10,46 +10,30 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/irq.h>
-#include <asm/signal.h>
 #include <mach/assabet.h>
 
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs[] = {
-	{ 1, ASSABET_IRQ_GPIO_CF_CD,   "CF CD"   },
-	{ 1, ASSABET_IRQ_GPIO_CF_BVD2, "CF BVD2" },
-	{ 1, ASSABET_IRQ_GPIO_CF_BVD1, "CF BVD1" },
-};
-
 static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ;
-
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
+	skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD;
+	skt->stat[SOC_STAT_CD].name = "CF CD";
+	skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1;
+	skt->stat[SOC_STAT_BVD1].name = "CF BVD1";
+	skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2;
+	skt->stat[SOC_STAT_BVD2].name = "CF BVD2";
+	skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ;
+	skt->stat[SOC_STAT_RDY].name = "CF RDY";
 
-/*
- * Release all resources.
- */
-static void assabet_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	return 0;
 }
 
 static void
 assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
-
-	state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
-	state->ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
-	state->bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
-	state->bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
-	state->wrprot = 0; /* Not available on Assabet. */
 	state->vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
 	state->vs_Xv  = 0;
 }
@@ -78,38 +62,24 @@ assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_stat
 		return -1;
 	}
 
-	/* Silently ignore Vpp, output enable, speaker enable. */
+	/* Silently ignore Vpp, speaker enable. */
 
 	if (state->flags & SS_RESET)
 		mask |= ASSABET_BCR_CF_RST;
+	if (!(state->flags & SS_OUTPUT_ENA))
+		mask |= ASSABET_BCR_CF_BUS_OFF;
 
-	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask);
+	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR |
+			ASSABET_BCR_CF_BUS_OFF, mask);
 
 	return 0;
 }
 
 /*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void assabet_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	/*
-	 * Enable CF bus
-	 */
-	ASSABET_BCR_clear(ASSABET_BCR_CF_BUS_OFF);
-
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-/*
  * Disable card status IRQs on suspend.
  */
 static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
 	/*
 	 * Tristate the CF bus signals.  Also assert CF
 	 * reset as per user guide page 4-11.
@@ -119,14 +89,9 @@ static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 
 static struct pcmcia_low_level assabet_pcmcia_ops = { 
 	.owner			= THIS_MODULE,
-
 	.hw_init		= assabet_pcmcia_hw_init,
-	.hw_shutdown		= assabet_pcmcia_hw_shutdown,
-
 	.socket_state		= assabet_pcmcia_socket_state,
 	.configure_socket	= assabet_pcmcia_configure_socket,
-
-	.socket_init		= assabet_pcmcia_socket_init,
 	.socket_suspend		= assabet_pcmcia_socket_suspend,
 };
 
diff --git a/drivers/pcmcia/sa1100_badge4.c b/drivers/pcmcia/sa1100_badge4.c
deleted file mode 100644
index 1ce53f4..0000000
--- a/drivers/pcmcia/sa1100_badge4.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * linux/drivers/pcmcia/sa1100_badge4.c
- *
- * BadgePAD 4 PCMCIA specific routines
- *
- *   Christopher Hoover <ch@hpl.hp.com>
- *
- * Copyright (C) 2002 Hewlett-Packard Company
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <mach/badge4.h>
-#include <asm/hardware/sa1111.h>
-
-#include "sa1111_generic.h"
-
-/*
- * BadgePAD 4 Details
- *
- * PCM Vcc:
- *
- *  PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3
- *  on JP6) or 5v0 (short pins 3 and 5 on JP6).
- *
- * PCM Vpp:
- *
- *  PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6
- *  on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6).  N.B.,
- *  12v0 operation requires that the power supply actually supply 12v0
- *  via pin 7 of JP7.
- *
- * CF Vcc:
- *
- *  CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1
- *  and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10).
- *
- * Unfortunately there's no way programmatically to determine how a
- * given board is jumpered.  This code assumes a default jumpering
- * as described below.
- *
- * If the defaults aren't correct, you may override them with a pcmv
- * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>.  The units are
- * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0
- * PCM Vpp, and 5v0 CF Vcc.
- *
- */
-
-static int badge4_pcmvcc = 50;  /* pins 3 and 5 jumpered on JP6 */
-static int badge4_pcmvpp = 50;  /* pins 2 and 4 jumpered on JP6 */
-static int badge4_cfvcc = 33;   /* pins 1 and 2 jumpered on JP10 */
-
-static void complain_about_jumpering(const char *whom,
-				     const char *supply,
-				     int given, int wanted)
-{
-	printk(KERN_ERR
-	 "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
-	 "; re-jumper the board and/or use pcmv=xx,xx,xx\n",
-	       whom, supply,
-	       wanted / 10, wanted % 10,
-	       supply,
-	       given / 10, given % 10);
-}
-
-static int
-badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	int ret;
-
-	switch (skt->nr) {
-	case 0:
-		if ((state->Vcc != 0) &&
-		    (state->Vcc != badge4_pcmvcc)) {
-			complain_about_jumpering(__func__, "pcmvcc",
-						 badge4_pcmvcc, state->Vcc);
-			// Apply power regardless of the jumpering.
-			// return -1;
-		}
-		if ((state->Vpp != 0) &&
-		    (state->Vpp != badge4_pcmvpp)) {
-			complain_about_jumpering(__func__, "pcmvpp",
-						 badge4_pcmvpp, state->Vpp);
-			return -1;
-		}
-		break;
-
-	case 1:
-		if ((state->Vcc != 0) &&
-		    (state->Vcc != badge4_cfvcc)) {
-			complain_about_jumpering(__func__, "cfvcc",
-						 badge4_cfvcc, state->Vcc);
-			return -1;
-		}
-		break;
-
-	default:
-		return -1;
-	}
-
-	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		unsigned long flags;
-		int need5V;
-
-		local_irq_save(flags);
-
-		need5V = ((state->Vcc == 50) || (state->Vpp == 50));
-
-		badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V);
-
-		local_irq_restore(flags);
-	}
-
-	return 0;
-}
-
-static struct pcmcia_low_level badge4_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-	.configure_socket	= badge4_pcmcia_configure_socket,
-	.socket_init		= sa1111_pcmcia_socket_init,
-	.first			= 0,
-	.nr			= 2,
-};
-
-int pcmcia_badge4_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_badge4()) {
-		printk(KERN_INFO
-		       "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
-		       __func__,
-		       badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
-
-		sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
-		ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
-				sa11xx_drv_pcmcia_add_one);
-	}
-
-	return ret;
-}
-
-static int __init pcmv_setup(char *s)
-{
-	int v[4];
-
-	s = get_options(s, ARRAY_SIZE(v), v);
-
-	if (v[0] >= 1) badge4_pcmvcc = v[1];
-	if (v[0] >= 2) badge4_pcmvpp = v[2];
-	if (v[0] >= 3) badge4_cfvcc = v[3];
-
-	return 1;
-}
-
-__setup("pcmv=", pcmv_setup);
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index 30560df..c59c449 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -10,6 +10,7 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -19,34 +20,34 @@
 
 #define CERF_SOCKET	1
 
-static struct pcmcia_irqs irqs[] = {
-	{ CERF_SOCKET, CERF_IRQ_GPIO_CF_CD,   "CF_CD"   },
-	{ CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" },
-	{ CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" }
-};
-
 static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-	skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ;
+	int ret;
+
+	ret = gpio_request_one(CERF_GPIO_CF_RESET, GPIOF_OUT_INIT_LOW, "CF_RESET");
+	if (ret)
+		return ret;
+
+	skt->stat[SOC_STAT_CD].gpio = CERF_GPIO_CF_CD;
+	skt->stat[SOC_STAT_CD].name = "CF_CD";
+	skt->stat[SOC_STAT_BVD1].gpio = CERF_GPIO_CF_BVD1;
+	skt->stat[SOC_STAT_BVD1].name = "CF_BVD1";
+	skt->stat[SOC_STAT_BVD2].gpio = CERF_GPIO_CF_BVD2;
+	skt->stat[SOC_STAT_BVD2].name = "CF_BVD2";
+	skt->stat[SOC_STAT_RDY].gpio = CERF_GPIO_CF_IRQ;
+	skt->stat[SOC_STAT_RDY].name = "CF_IRQ";
 
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	return 0;
 }
 
 static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	gpio_free(CERF_GPIO_CF_RESET);
 }
 
 static void
 cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
-
-	state->detect	= (levels & CERF_GPIO_CF_CD)  ?0:1;
-	state->ready	= (levels & CERF_GPIO_CF_IRQ) ?1:0;
-	state->bvd1	= (levels & CERF_GPIO_CF_BVD1)?1:0;
-	state->bvd2	= (levels & CERF_GPIO_CF_BVD2)?1:0;
-	state->wrprot	= 0;
 	state->vs_3v	= 1;
 	state->vs_Xv	= 0;
 }
@@ -67,34 +68,17 @@ cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 		return -1;
 	}
 
-	if (state->flags & SS_RESET) {
-		GPSR = CERF_GPIO_CF_RESET;
-	} else {
-		GPCR = CERF_GPIO_CF_RESET;
-	}
+	gpio_set_value(CERF_GPIO_CF_RESET, !!(state->flags & SS_RESET));
 
 	return 0;
 }
 
-static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static struct pcmcia_low_level cerf_pcmcia_ops = { 
 	.owner			= THIS_MODULE,
 	.hw_init		= cerf_pcmcia_hw_init,
 	.hw_shutdown		= cerf_pcmcia_hw_shutdown,
 	.socket_state		= cerf_pcmcia_socket_state,
 	.configure_socket	= cerf_pcmcia_configure_socket,
-
-	.socket_init		= cerf_pcmcia_socket_init,
-	.socket_suspend		= cerf_pcmcia_socket_suspend,
 };
 
 int __devinit pcmcia_cerf_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index edf8f00..d9c7337 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -19,36 +19,20 @@
 
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs[] = {
-	{ .sock = 0, .str = "PCMCIA CD0" }, /* .irq will be filled later */
-	{ .sock = 1, .str = "PCMCIA CD1" }
-};
-
 static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	int err;
 
 	switch (skt->nr) {
 	case 0:
-		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ0, "PCMCIA IRQ0");
-		if (err)
-			goto err00;
-		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ0);
-		if (err)
-			goto err01;
-		skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ0);
-
-		err = gpio_request(H3XXX_GPIO_PCMCIA_CD0, "PCMCIA CD0");
-		if (err)
-			goto err01;
-		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD0);
-		if (err)
-			goto err02;
-		irqs[0].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD0);
+		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD0;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA CD0";
+		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ0;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ0";
 
 		err = gpio_request(H3XXX_EGPIO_OPT_NVRAM_ON, "OPT NVRAM ON");
 		if (err)
-			goto err02;
+			goto err01;
 		err = gpio_direction_output(H3XXX_EGPIO_OPT_NVRAM_ON, 0);
 		if (err)
 			goto err03;
@@ -70,30 +54,12 @@ static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 		err = gpio_direction_output(H3XXX_EGPIO_CARD_RESET, 0);
 		if (err)
 			goto err06;
-		err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-		if (err)
-			goto err06;
 		break;
 	case 1:
-		err = gpio_request(H3XXX_GPIO_PCMCIA_IRQ1, "PCMCIA IRQ1");
-		if (err)
-			goto err10;
-		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_IRQ1);
-		if (err)
-			goto err11;
-		skt->socket.pci_irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_IRQ1);
-
-		err = gpio_request(H3XXX_GPIO_PCMCIA_CD1, "PCMCIA CD1");
-		if (err)
-			goto err11;
-		err = gpio_direction_input(H3XXX_GPIO_PCMCIA_CD1);
-		if (err)
-			goto err12;
-		irqs[1].irq = gpio_to_irq(H3XXX_GPIO_PCMCIA_CD1);
-
-		err = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-		if (err)
-			goto err12;
+		skt->stat[SOC_STAT_CD].gpio = H3XXX_GPIO_PCMCIA_CD1;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA CD1";
+		skt->stat[SOC_STAT_RDY].gpio = H3XXX_GPIO_PCMCIA_IRQ1;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA IRQ1";
 		break;
 	}
 	return 0;
@@ -102,19 +68,12 @@ err06:	gpio_free(H3XXX_EGPIO_CARD_RESET);
 err05:	gpio_free(H3XXX_EGPIO_OPT_RESET);
 err04:	gpio_free(H3XXX_EGPIO_OPT_ON);
 err03:	gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
-err02:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);
 err01:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
-err00:	return err;
-
-err12:	gpio_free(H3XXX_GPIO_PCMCIA_CD0);
-err11:	gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
-err10:	return err;
+	return err;
 }
 
 static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-  
 	switch (skt->nr) {
 	case 0:
 		/* Disable CF bus: */
@@ -126,12 +85,8 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 		gpio_free(H3XXX_EGPIO_OPT_RESET);
 		gpio_free(H3XXX_EGPIO_OPT_ON);
 		gpio_free(H3XXX_EGPIO_OPT_NVRAM_ON);
-		gpio_free(H3XXX_GPIO_PCMCIA_CD0);
-		gpio_free(H3XXX_GPIO_PCMCIA_IRQ0);
 		break;
 	case 1:
-		gpio_free(H3XXX_GPIO_PCMCIA_CD1);
-		gpio_free(H3XXX_GPIO_PCMCIA_IRQ1);
 		break;
 	}
 }
@@ -139,27 +94,10 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 static void
 h3600_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	switch (skt->nr) {
-	case 0:
-		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD0);
-		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ0);
-		state->bvd1 = 0;
-		state->bvd2 = 0;
-		state->wrprot = 0; /* Not available on H3600. */
-		state->vs_3v = 0;
-		state->vs_Xv = 0;
-		break;
-
-	case 1:
-		state->detect = !gpio_get_value(H3XXX_GPIO_PCMCIA_CD1);
-		state->ready = !!gpio_get_value(H3XXX_GPIO_PCMCIA_IRQ1);
-		state->bvd1 = 0;
-		state->bvd2 = 0;
-		state->wrprot = 0; /* Not available on H3600. */
-		state->vs_3v = 0;
-		state->vs_Xv = 0;
-		break;
-	}
+	state->bvd1 = 0;
+	state->bvd2 = 0;
+	state->vs_3v = 0;
+	state->vs_Xv = 0;
 }
 
 static int
@@ -186,14 +124,10 @@ static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 	gpio_set_value(H3XXX_EGPIO_OPT_RESET, 0);
 
 	msleep(10);
-
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
 static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
 	/*
 	 * FIXME:  This doesn't fit well.  We don't have the mechanism in
 	 * the generic PCMCIA layer to deal with the idea of two sockets
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
deleted file mode 100644
index 6bcabee..0000000
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * drivers/pcmcia/sa1100_jornada720.c
- *
- * Jornada720 PCMCIA specific routines
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/sa1111.h>
-#include <asm/mach-types.h>
-
-#include "sa1111_generic.h"
-
-/* Does SOCKET1_3V actually do anything? */
-#define SOCKET0_POWER	GPIO_GPIO0
-#define SOCKET0_3V	GPIO_GPIO2
-#define SOCKET1_POWER	(GPIO_GPIO1 | GPIO_GPIO3)
-#define SOCKET1_3V	GPIO_GPIO3
-
-static int
-jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int pa_dwr_mask, pa_dwr_set;
-	int ret;
-
-	printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
-		skt->nr, state->Vcc, state->Vpp);
-
-	switch (skt->nr) {
-	case 0:
-		pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
-
-		switch (state->Vcc) {
-		default:
-		case  0:
-			pa_dwr_set = 0;
-			break;
-		case 33:
-			pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
-			break;
-		case 50:
-			pa_dwr_set = SOCKET0_POWER;
-			break;
-		}
-		break;
-
-	case 1:
-		pa_dwr_mask = SOCKET1_POWER;
-
-		switch (state->Vcc) {
-		default:
-		case 0:
-			pa_dwr_set = 0;
-			break;
-		case 33:
-			pa_dwr_set = SOCKET1_POWER;
-			break;
-		case 50:
-			pa_dwr_set = SOCKET1_POWER;
-			break;
-		}
-		break;
-
-	default:
-		return -1;
-	}
-
-	if (state->Vpp != state->Vcc && state->Vpp != 0) {
-		printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
-			__func__, state->Vpp);
-		return -EPERM;
-	}
-
-	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		unsigned long flags;
-
-		local_irq_save(flags);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-		local_irq_restore(flags);
-	}
-
-	return ret;
-}
-
-static struct pcmcia_low_level jornada720_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-	.configure_socket	= jornada720_pcmcia_configure_socket,
-	.socket_init		= sa1111_pcmcia_socket_init,
-	.first			= 0,
-	.nr			= 2,
-};
-
-int __devinit pcmcia_jornada720_init(struct device *dev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_jornada720()) {
-		unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-		GRER |= 0x00000002;
-
-		/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-		sa1111_set_io_dir(dev, pin, 0, 0);
-		sa1111_set_io(dev, pin, 0);
-		sa1111_set_sleep_io(dev, pin, 0);
-
-		sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
-		ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
-				sa11xx_drv_pcmcia_add_one);
-	}
-
-	return ret;
-}
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
index 93b9c9b..35c30ff 100644
--- a/drivers/pcmcia/sa1100_nanoengine.c
+++ b/drivers/pcmcia/sa1100_nanoengine.c
@@ -19,6 +19,7 @@
  */
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/init.h>
@@ -34,43 +35,23 @@
 
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs_skt0[] = {
-	/* socket, IRQ, name */
-	{ 0, NANOENGINE_IRQ_GPIO_PC_CD0, "PC CD0" },
-};
-
-static struct pcmcia_irqs irqs_skt1[] = {
-	/* socket, IRQ, name */
-	{ 1, NANOENGINE_IRQ_GPIO_PC_CD1, "PC CD1" },
-};
-
 struct nanoengine_pins {
-	unsigned input_pins;
 	unsigned output_pins;
 	unsigned clear_outputs;
-	unsigned transition_pins;
-	unsigned pci_irq;
-	struct pcmcia_irqs *pcmcia_irqs;
-	unsigned pcmcia_irqs_size;
+	int gpio_rst;
+	int gpio_cd;
+	int gpio_rdy;
 };
 
 static struct nanoengine_pins nano_skts[] = {
 	{
-		.input_pins		= GPIO_PC_READY0 | GPIO_PC_CD0,
-		.output_pins		= GPIO_PC_RESET0,
-		.clear_outputs		= GPIO_PC_RESET0,
-		.transition_pins	= NANOENGINE_IRQ_GPIO_PC_CD0,
-		.pci_irq		= NANOENGINE_IRQ_GPIO_PC_READY0,
-		.pcmcia_irqs		= irqs_skt0,
-		.pcmcia_irqs_size	= ARRAY_SIZE(irqs_skt0)
+		.gpio_rst		= GPIO_PC_RESET0,
+		.gpio_cd		= GPIO_PC_CD0,
+		.gpio_rdy		= GPIO_PC_READY0,
 	}, {
-		.input_pins		= GPIO_PC_READY1 | GPIO_PC_CD1,
-		.output_pins		= GPIO_PC_RESET1,
-		.clear_outputs		= GPIO_PC_RESET1,
-		.transition_pins	= NANOENGINE_IRQ_GPIO_PC_CD1,
-		.pci_irq		= NANOENGINE_IRQ_GPIO_PC_READY1,
-		.pcmcia_irqs		= irqs_skt1,
-		.pcmcia_irqs_size	= ARRAY_SIZE(irqs_skt1)
+		.gpio_rst		= GPIO_PC_RESET1,
+		.gpio_cd		= GPIO_PC_CD1,
+		.gpio_rdy		= GPIO_PC_READY1,
 	}
 };
 
@@ -79,58 +60,38 @@ unsigned num_nano_pcmcia_sockets = ARRAY_SIZE(nano_skts);
 static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	unsigned i = skt->nr;
+	int ret;
 
 	if (i >= num_nano_pcmcia_sockets)
 		return -ENXIO;
 
-	GPDR &= ~nano_skts[i].input_pins;
-	GPDR |= nano_skts[i].output_pins;
-	GPCR = nano_skts[i].clear_outputs;
-	irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH);
-	skt->socket.pci_irq = nano_skts[i].pci_irq;
+	ret = gpio_request_one(nano_skts[i].gpio_rst, GPIOF_OUT_INIT_LOW,
+		i ? "PC RST1" : "PC RST0");
+	if (ret)
+		return ret;
+
+	skt->stat[SOC_STAT_CD].gpio = nano_skts[i].gpio_cd;
+	skt->stat[SOC_STAT_CD].name = i ? "PC CD1" : "PC CD0";
+	skt->stat[SOC_STAT_RDY].gpio = nano_skts[i].gpio_rdy;
+	skt->stat[SOC_STAT_RDY].name = i ? "PC RDY1" : "PC RDY0";
 
-	return soc_pcmcia_request_irqs(skt,
-		nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+	return 0;
 }
 
-/*
- * Release all resources.
- */
 static void nanoengine_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return;
-
-	soc_pcmcia_free_irqs(skt,
-		nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
+	gpio_free(nano_skts[skt->nr].gpio_rst);
 }
 
 static int nanoengine_pcmcia_configure_socket(
 	struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-	unsigned reset;
 	unsigned i = skt->nr;
 
 	if (i >= num_nano_pcmcia_sockets)
 		return -ENXIO;
 
-	switch (i) {
-	case 0:
-		reset = GPIO_PC_RESET0;
-		break;
-	case 1:
-		reset = GPIO_PC_RESET1;
-		break;
-	default:
-		return -ENXIO;
-	}
-
-	if (state->flags & SS_RESET)
-		GPSR = reset;
-	else
-		GPCR = reset;
+	gpio_set_value(nano_skts[skt->nr].gpio_rst, !!(state->flags & SS_RESET));
 
 	return 0;
 }
@@ -138,62 +99,17 @@ static int nanoengine_pcmcia_configure_socket(
 static void nanoengine_pcmcia_socket_state(
 	struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
 	unsigned i = skt->nr;
 
 	if (i >= num_nano_pcmcia_sockets)
 		return;
 
-	memset(state, 0, sizeof(struct pcmcia_state));
-	switch (i) {
-	case 0:
-		state->ready = (levels & GPIO_PC_READY0) ? 1 : 0;
-		state->detect = !(levels & GPIO_PC_CD0) ? 1 : 0;
-		break;
-	case 1:
-		state->ready = (levels & GPIO_PC_READY1) ? 1 : 0;
-		state->detect = !(levels & GPIO_PC_CD1) ? 1 : 0;
-		break;
-	default:
-		return;
-	}
 	state->bvd1 = 1;
 	state->bvd2 = 1;
-	state->wrprot = 0; /* Not available */
 	state->vs_3v = 1; /* Can only apply 3.3V */
 	state->vs_Xv = 0;
 }
 
-/*
- * Enable card status IRQs on (re-)initialisation.  This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
-static void nanoengine_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return;
-
-	soc_pcmcia_enable_irqs(skt,
-		nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
-}
-
-/*
- * Disable card status IRQs on suspend.
- */
-static void nanoengine_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	unsigned i = skt->nr;
-
-	if (i >= num_nano_pcmcia_sockets)
-		return;
-
-	soc_pcmcia_disable_irqs(skt,
-		nano_skts[i].pcmcia_irqs, nano_skts[i].pcmcia_irqs_size);
-}
-
 static struct pcmcia_low_level nanoengine_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 
@@ -202,8 +118,6 @@ static struct pcmcia_low_level nanoengine_pcmcia_ops = {
 
 	.configure_socket	= nanoengine_pcmcia_configure_socket,
 	.socket_state		= nanoengine_pcmcia_socket_state,
-	.socket_init		= nanoengine_pcmcia_socket_init,
-	.socket_suspend		= nanoengine_pcmcia_socket_suspend,
 };
 
 int pcmcia_nanoengine_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
deleted file mode 100644
index c95639b..0000000
--- a/drivers/pcmcia/sa1100_neponset.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * linux/drivers/pcmcia/sa1100_neponset.c
- *
- * Neponset PCMCIA specific routines
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <mach/neponset.h>
-#include <asm/hardware/sa1111.h>
-
-#include "sa1111_generic.h"
-
-/*
- * Neponset uses the Maxim MAX1600, with the following connections:
- *
- *   MAX1600      Neponset
- *
- *    A0VCC        SA-1111 GPIO A<1>
- *    A1VCC        SA-1111 GPIO A<0>
- *    A0VPP        CPLD NCR A0VPP
- *    A1VPP        CPLD NCR A1VPP
- *    B0VCC        SA-1111 GPIO A<2>
- *    B1VCC        SA-1111 GPIO A<3>
- *    B0VPP        ground (slot B is CF)
- *    B1VPP        ground (slot B is CF)
- *
- *     VX          VCC (5V)
- *     VY          VCC3_3 (3.3V)
- *     12INA       12V
- *     12INB       ground (slot B is CF)
- *
- * The MAX1600 CODE pin is tied to ground, placing the device in 
- * "Standard Intel code" mode. Refer to the Maxim data sheet for
- * the corresponding truth table.
- */
-
-static int
-neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
-{
-	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
-	int ret;
-
-	switch (skt->nr) {
-	case 0:
-		pa_dwr_mask = GPIO_A0 | GPIO_A1;
-		ncr_mask = NCR_A0VPP | NCR_A1VPP;
-
-		if (state->Vpp == 0)
-			ncr_set = 0;
-		else if (state->Vpp == 120)
-			ncr_set = NCR_A1VPP;
-		else if (state->Vpp == state->Vcc)
-			ncr_set = NCR_A0VPP;
-		else {
-			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
-
-	case 1:
-		pa_dwr_mask = GPIO_A2 | GPIO_A3;
-		ncr_mask = 0;
-		ncr_set = 0;
-
-		if (state->Vpp != state->Vcc && state->Vpp != 0) {
-			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-			       __func__, state->Vpp);
-			return -1;
-		}
-		break;
-
-	default:
-		return -1;
-	}
-
-	/*
-	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
-	 * pa_dwr_mask selects which bits (and therefore socket) we change.
-	 */
-	switch (state->Vcc) {
-	default:
-	case 0:  pa_dwr_set = 0;		break;
-	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
-	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
-	}
-
-	ret = sa1111_pcmcia_configure_socket(skt, state);
-	if (ret == 0) {
-		unsigned long flags;
-
-		local_irq_save(flags);
-		NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
-
-		local_irq_restore(flags);
-		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
-	}
-
-	return 0;
-}
-
-static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	if (skt->nr == 0)
-		NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP);
-
-	sa1111_pcmcia_socket_init(skt);
-}
-
-static struct pcmcia_low_level neponset_pcmcia_ops = {
-	.owner			= THIS_MODULE,
-	.configure_socket	= neponset_pcmcia_configure_socket,
-	.socket_init		= neponset_pcmcia_socket_init,
-	.first			= 0,
-	.nr			= 2,
-};
-
-int pcmcia_neponset_init(struct sa1111_dev *sadev)
-{
-	int ret = -ENODEV;
-
-	if (machine_is_assabet()) {
-		/*
-		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
-		 * and switch to standby mode.
-		 */
-		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
-		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-		sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
-		ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
-				sa11xx_drv_pcmcia_add_one);
-	}
-
-	return ret;
-}
diff --git a/drivers/pcmcia/sa1100_shannon.c b/drivers/pcmcia/sa1100_shannon.c
index 7ff1b43..decb347 100644
--- a/drivers/pcmcia/sa1100_shannon.c
+++ b/drivers/pcmcia/sa1100_shannon.c
@@ -15,40 +15,35 @@
 #include <asm/irq.h>
 #include "sa1100_generic.h"
 
-static struct pcmcia_irqs irqs[] = {
-	{ 0, SHANNON_IRQ_GPIO_EJECT_0, "PCMCIA_CD_0" },
-	{ 1, SHANNON_IRQ_GPIO_EJECT_1, "PCMCIA_CD_1" },
-};
-
 static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 	/* All those are inputs */
-	GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
-		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
-	GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
-		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
-
-	skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
-
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
+	GAFR &= ~(GPIO_GPIO(SHANNON_GPIO_EJECT_0) |
+		  GPIO_GPIO(SHANNON_GPIO_EJECT_1) |
+		  GPIO_GPIO(SHANNON_GPIO_RDY_0) |
+		  GPIO_GPIO(SHANNON_GPIO_RDY_1));
+
+	if (skt->nr == 0) {
+		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_0;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_0";
+		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_0;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_0";
+	} else {
+		skt->stat[SOC_STAT_CD].gpio = SHANNON_GPIO_EJECT_1;
+		skt->stat[SOC_STAT_CD].name = "PCMCIA_CD_1";
+		skt->stat[SOC_STAT_RDY].gpio = SHANNON_GPIO_RDY_1;
+		skt->stat[SOC_STAT_RDY].name = "PCMCIA_RDY_1";
+	}
 
-static void shannon_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	return 0;
 }
 
 static void
 shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 			    struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
-
 	switch (skt->nr) {
 	case 0:
-		state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
-		state->ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
-		state->wrprot = 0; /* Not available on Shannon. */
 		state->bvd1   = 1; 
 		state->bvd2   = 1; 
 		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
@@ -56,9 +51,6 @@ shannon_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 		break;
 
 	case 1:
-		state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
-		state->ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
-		state->wrprot = 0; /* Not available on Shannon. */
 		state->bvd1   = 1; 
 		state->bvd2   = 1; 
 		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
@@ -92,25 +84,11 @@ shannon_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	return 0;
 }
 
-static void shannon_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void shannon_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static struct pcmcia_low_level shannon_pcmcia_ops = {
 	.owner			= THIS_MODULE,
 	.hw_init		= shannon_pcmcia_hw_init,
-	.hw_shutdown		= shannon_pcmcia_hw_shutdown,
 	.socket_state		= shannon_pcmcia_socket_state,
 	.configure_socket	= shannon_pcmcia_configure_socket,
-
-	.socket_init		= shannon_pcmcia_socket_init,
-	.socket_suspend		= shannon_pcmcia_socket_suspend,
 };
 
 int __devinit pcmcia_shannon_init(struct device *dev)
diff --git a/drivers/pcmcia/sa1100_simpad.c b/drivers/pcmcia/sa1100_simpad.c
index 0fac965..8647b17 100644
--- a/drivers/pcmcia/sa1100_simpad.c
+++ b/drivers/pcmcia/sa1100_simpad.c
@@ -15,24 +15,21 @@
 #include <mach/simpad.h>
 #include "sa1100_generic.h"
  
-static struct pcmcia_irqs irqs[] = {
-	{ 1, IRQ_GPIO_CF_CD, "CF_CD" },
-};
-
 static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
 
 	simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-	skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
+	skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD;
+	skt->stat[SOC_STAT_CD].name = "CF_CD";
+	skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ;
+	skt->stat[SOC_STAT_RDY].name = "CF_RDY";
 
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
+	return 0;
 }
 
 static void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-
 	/* Disable CF bus: */
 	/*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/
 	simpad_clear_cs3_bit(PCMCIA_RESET);
@@ -42,14 +39,13 @@ static void
 simpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
 			   struct pcmcia_state *state)
 {
-	unsigned long levels = GPLR;
 	long cs3reg = simpad_get_cs3_ro();
 
-	state->detect=((levels & GPIO_CF_CD)==0)?1:0;
-	state->ready=(levels & GPIO_CF_IRQ)?1:0;
+	/* the detect signal is inverted - fix that up here */
+	state->detect = !state->detect;
+
 	state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */
 	state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */
-	state->wrprot=0; /* Not available on Simpad. */
 
 	if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) ==
 			(PCMCIA_VS1|PCMCIA_VS2)) {
@@ -99,14 +95,8 @@ simpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 	return 0;
 }
 
-static void simpad_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 static void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 	simpad_set_cs3_bit(PCMCIA_RESET);
 }
 
@@ -116,7 +106,6 @@ static struct pcmcia_low_level simpad_pcmcia_ops = {
 	.hw_shutdown		= simpad_pcmcia_hw_shutdown,
 	.socket_state		= simpad_pcmcia_socket_state,
 	.configure_socket	= simpad_pcmcia_configure_socket,
-	.socket_init		= simpad_pcmcia_socket_init,
 	.socket_suspend		= simpad_pcmcia_socket_suspend,
 };
 
diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c
new file mode 100644
index 0000000..4d206f4
--- /dev/null
+++ b/drivers/pcmcia/sa1111_badge4.c
@@ -0,0 +1,166 @@
+/*
+ * linux/drivers/pcmcia/sa1100_badge4.c
+ *
+ * BadgePAD 4 PCMCIA specific routines
+ *
+ *   Christopher Hoover <ch@hpl.hp.com>
+ *
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <mach/badge4.h>
+#include <asm/hardware/sa1111.h>
+
+#include "sa1111_generic.h"
+
+/*
+ * BadgePAD 4 Details
+ *
+ * PCM Vcc:
+ *
+ *  PCM Vcc on BadgePAD 4 can be jumpered for 3v3 (short pins 1 and 3
+ *  on JP6) or 5v0 (short pins 3 and 5 on JP6).
+ *
+ * PCM Vpp:
+ *
+ *  PCM Vpp on BadgePAD 4 can be jumpered for 12v0 (short pins 4 and 6
+ *  on JP6) or tied to PCM Vcc (short pins 2 and 4 on JP6).  N.B.,
+ *  12v0 operation requires that the power supply actually supply 12v0
+ *  via pin 7 of JP7.
+ *
+ * CF Vcc:
+ *
+ *  CF Vcc on BadgePAD 4 can be jumpered either for 3v3 (short pins 1
+ *  and 2 on JP10) or 5v0 (short pins 2 and 3 on JP10).
+ *
+ * Unfortunately there's no way programmatically to determine how a
+ * given board is jumpered.  This code assumes a default jumpering
+ * as described below.
+ *
+ * If the defaults aren't correct, you may override them with a pcmv
+ * setup argument: pcmv=<pcm vcc>,<pcm vpp>,<cf vcc>.  The units are
+ * tenths of volts; e.g. pcmv=33,120,50 indicates 3v3 PCM Vcc, 12v0
+ * PCM Vpp, and 5v0 CF Vcc.
+ *
+ */
+
+static int badge4_pcmvcc = 50;  /* pins 3 and 5 jumpered on JP6 */
+static int badge4_pcmvpp = 50;  /* pins 2 and 4 jumpered on JP6 */
+static int badge4_cfvcc = 33;   /* pins 1 and 2 jumpered on JP10 */
+
+static void complain_about_jumpering(const char *whom,
+				     const char *supply,
+				     int given, int wanted)
+{
+	printk(KERN_ERR
+	 "%s: %s %d.%dV wanted but board is jumpered for %s %d.%dV operation"
+	 "; re-jumper the board and/or use pcmv=xx,xx,xx\n",
+	       whom, supply,
+	       wanted / 10, wanted % 10,
+	       supply,
+	       given / 10, given % 10);
+}
+
+static int
+badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+	int ret;
+
+	switch (skt->nr) {
+	case 0:
+		if ((state->Vcc != 0) &&
+		    (state->Vcc != badge4_pcmvcc)) {
+			complain_about_jumpering(__func__, "pcmvcc",
+						 badge4_pcmvcc, state->Vcc);
+			// Apply power regardless of the jumpering.
+			// return -1;
+		}
+		if ((state->Vpp != 0) &&
+		    (state->Vpp != badge4_pcmvpp)) {
+			complain_about_jumpering(__func__, "pcmvpp",
+						 badge4_pcmvpp, state->Vpp);
+			return -1;
+		}
+		break;
+
+	case 1:
+		if ((state->Vcc != 0) &&
+		    (state->Vcc != badge4_cfvcc)) {
+			complain_about_jumpering(__func__, "cfvcc",
+						 badge4_cfvcc, state->Vcc);
+			return -1;
+		}
+		break;
+
+	default:
+		return -1;
+	}
+
+	ret = sa1111_pcmcia_configure_socket(skt, state);
+	if (ret == 0) {
+		unsigned long flags;
+		int need5V;
+
+		local_irq_save(flags);
+
+		need5V = ((state->Vcc == 50) || (state->Vpp == 50));
+
+		badge4_set_5V(BADGE4_5V_PCMCIA_SOCK(skt->nr), need5V);
+
+		local_irq_restore(flags);
+	}
+
+	return ret;
+}
+
+static struct pcmcia_low_level badge4_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+	.configure_socket	= badge4_pcmcia_configure_socket,
+	.first			= 0,
+	.nr			= 2,
+};
+
+int pcmcia_badge4_init(struct device *dev)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_badge4()) {
+		printk(KERN_INFO
+		       "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n",
+		       __func__,
+		       badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
+
+		sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
+		ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
+				sa11xx_drv_pcmcia_add_one);
+	}
+
+	return ret;
+}
+
+static int __init pcmv_setup(char *s)
+{
+	int v[4];
+
+	s = get_options(s, ARRAY_SIZE(v), v);
+
+	if (v[0] >= 1) badge4_pcmvcc = v[1];
+	if (v[0] >= 2) badge4_pcmvpp = v[2];
+	if (v[0] >= 3) badge4_cfvcc = v[3];
+
+	return 1;
+}
+
+__setup("pcmv=", pcmv_setup);
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 27f2fe3..70f728c 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -22,6 +22,40 @@
 
 #include "sa1111_generic.h"
 
+/*
+ * These are offsets from the above base.
+ */
+#define PCCR	0x0000
+#define PCSSR	0x0004
+#define PCSR	0x0008
+
+#define PCSR_S0_READY	(1<<0)
+#define PCSR_S1_READY	(1<<1)
+#define PCSR_S0_DETECT	(1<<2)
+#define PCSR_S1_DETECT	(1<<3)
+#define PCSR_S0_VS1	(1<<4)
+#define PCSR_S0_VS2	(1<<5)
+#define PCSR_S1_VS1	(1<<6)
+#define PCSR_S1_VS2	(1<<7)
+#define PCSR_S0_WP	(1<<8)
+#define PCSR_S1_WP	(1<<9)
+#define PCSR_S0_BVD1	(1<<10)
+#define PCSR_S0_BVD2	(1<<11)
+#define PCSR_S1_BVD1	(1<<12)
+#define PCSR_S1_BVD2	(1<<13)
+
+#define PCCR_S0_RST	(1<<0)
+#define PCCR_S1_RST	(1<<1)
+#define PCCR_S0_FLT	(1<<2)
+#define PCCR_S1_FLT	(1<<3)
+#define PCCR_S0_PWAITEN	(1<<4)
+#define PCCR_S1_PWAITEN	(1<<5)
+#define PCCR_S0_PSE	(1<<6)
+#define PCCR_S1_PSE	(1<<7)
+
+#define PCSSR_S0_SLEEP	(1<<0)
+#define PCSSR_S1_SLEEP	(1<<1)
+
 #define IDX_IRQ_S0_READY_NINT	(0)
 #define IDX_IRQ_S0_CD_VALID	(1)
 #define IDX_IRQ_S0_BVD1_STSCHG	(2)
@@ -29,27 +63,10 @@
 #define IDX_IRQ_S1_CD_VALID	(4)
 #define IDX_IRQ_S1_BVD1_STSCHG	(5)
 
-static struct pcmcia_irqs irqs[] = {
-	{ 0, NO_IRQ, "SA1111 PCMCIA card detect" },
-	{ 0, NO_IRQ, "SA1111 PCMCIA BVD1"        },
-	{ 1, NO_IRQ, "SA1111 CF card detect"     },
-	{ 1, NO_IRQ, "SA1111 CF BVD1"            },
-};
-
-static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-	return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
 	struct sa1111_pcmcia_socket *s = to_skt(skt);
-	unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR);
+	unsigned long status = sa1111_readl(s->dev->mapbase + PCSR);
 
 	switch (skt->nr) {
 	case 0:
@@ -105,35 +122,22 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 		pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
 
 	local_irq_save(flags);
-	val = sa1111_readl(s->dev->mapbase + SA1111_PCCR);
+	val = sa1111_readl(s->dev->mapbase + PCCR);
 	val &= ~pccr_skt_mask;
 	val |= pccr_set_mask & pccr_skt_mask;
-	sa1111_writel(val, s->dev->mapbase + SA1111_PCCR);
+	sa1111_writel(val, s->dev->mapbase + PCCR);
 	local_irq_restore(flags);
 
 	return 0;
 }
 
-void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
-static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
-{
-	soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
-}
-
 int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
 	int (*add)(struct soc_pcmcia_socket *))
 {
 	struct sa1111_pcmcia_socket *s;
 	int i, ret = 0;
 
-	ops->hw_init = sa1111_pcmcia_hw_init;
-	ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
 	ops->socket_state = sa1111_pcmcia_socket_state;
-	ops->socket_suspend = sa1111_pcmcia_socket_suspend;
 
 	for (i = 0; i < ops->nr; i++) {
 		s = kzalloc(sizeof(*s), GFP_KERNEL);
@@ -141,13 +145,21 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
 			return -ENOMEM;
 
 		s->soc.nr = ops->first + i;
-		s->soc.ops = ops;
-		s->soc.socket.owner = ops->owner;
-		s->soc.socket.dev.parent = &dev->dev;
-		s->soc.socket.pci_irq = s->soc.nr ?
-				dev->irq[IDX_IRQ_S0_READY_NINT] :
-				dev->irq[IDX_IRQ_S1_READY_NINT];
+		soc_pcmcia_init_one(&s->soc, ops, &dev->dev);
 		s->dev = dev;
+		if (s->soc.nr) {
+			s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S1_READY_NINT];
+			s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
+			s->soc.stat[SOC_STAT_CD].name = "SA1111 CF card detect";
+			s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
+			s->soc.stat[SOC_STAT_BVD1].name = "SA1111 CF BVD1";
+		} else {
+			s->soc.socket.pci_irq = dev->irq[IDX_IRQ_S0_READY_NINT];
+			s->soc.stat[SOC_STAT_CD].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
+			s->soc.stat[SOC_STAT_CD].name = "SA1111 PCMCIA card detect";
+			s->soc.stat[SOC_STAT_BVD1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
+			s->soc.stat[SOC_STAT_BVD1].name = "SA1111 PCMCIA BVD1";
+		}
 
 		ret = add(&s->soc);
 		if (ret == 0) {
@@ -163,26 +175,26 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
 static int pcmcia_probe(struct sa1111_dev *dev)
 {
 	void __iomem *base;
+	int ret;
+
+	ret = sa1111_enable_device(dev);
+	if (ret)
+		return ret;
 
 	dev_set_drvdata(&dev->dev, NULL);
 
-	if (!request_mem_region(dev->res.start, 512,
-				SA1111_DRIVER_NAME(dev)))
+	if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) {
+		sa1111_disable_device(dev);
 		return -EBUSY;
+	}
 
 	base = dev->mapbase;
 
-	/* Initialize PCMCIA IRQs */
-	irqs[0].irq = dev->irq[IDX_IRQ_S0_CD_VALID];
-	irqs[1].irq = dev->irq[IDX_IRQ_S0_BVD1_STSCHG];
-	irqs[2].irq = dev->irq[IDX_IRQ_S1_CD_VALID];
-	irqs[3].irq = dev->irq[IDX_IRQ_S1_BVD1_STSCHG];
-
 	/*
 	 * Initialise the suspend state.
 	 */
-	sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR);
-	sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR);
+	sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR);
+	sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR);
 
 #ifdef CONFIG_SA1100_BADGE4
 	pcmcia_badge4_init(&dev->dev);
@@ -212,6 +224,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
 	}
 
 	release_mem_region(dev->res.start, 512);
+	sa1111_disable_device(dev);
 	return 0;
 }
 
diff --git a/drivers/pcmcia/sa1111_generic.h b/drivers/pcmcia/sa1111_generic.h
index 02dc857..f6376e3 100644
--- a/drivers/pcmcia/sa1111_generic.h
+++ b/drivers/pcmcia/sa1111_generic.h
@@ -17,7 +17,6 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
 
 extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
 extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
-extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
 
 extern int pcmcia_badge4_init(struct device *);
 extern int pcmcia_jornada720_init(struct device *);
diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c
new file mode 100644
index 0000000..69428d1
--- /dev/null
+++ b/drivers/pcmcia/sa1111_jornada720.c
@@ -0,0 +1,114 @@
+/*
+ * drivers/pcmcia/sa1100_jornada720.c
+ *
+ * Jornada720 PCMCIA specific routines
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/mach-types.h>
+
+#include "sa1111_generic.h"
+
+/* Does SOCKET1_3V actually do anything? */
+#define SOCKET0_POWER	GPIO_GPIO0
+#define SOCKET0_3V	GPIO_GPIO2
+#define SOCKET1_POWER	(GPIO_GPIO1 | GPIO_GPIO3)
+#define SOCKET1_3V	GPIO_GPIO3
+
+static int
+jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	unsigned int pa_dwr_mask, pa_dwr_set;
+	int ret;
+
+	printk(KERN_INFO "%s(): config socket %d vcc %d vpp %d\n", __func__,
+		skt->nr, state->Vcc, state->Vpp);
+
+	switch (skt->nr) {
+	case 0:
+		pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
+
+		switch (state->Vcc) {
+		default:
+		case  0:
+			pa_dwr_set = 0;
+			break;
+		case 33:
+			pa_dwr_set = SOCKET0_POWER | SOCKET0_3V;
+			break;
+		case 50:
+			pa_dwr_set = SOCKET0_POWER;
+			break;
+		}
+		break;
+
+	case 1:
+		pa_dwr_mask = SOCKET1_POWER;
+
+		switch (state->Vcc) {
+		default:
+		case 0:
+			pa_dwr_set = 0;
+			break;
+		case 33:
+			pa_dwr_set = SOCKET1_POWER;
+			break;
+		case 50:
+			pa_dwr_set = SOCKET1_POWER;
+			break;
+		}
+		break;
+
+	default:
+		return -1;
+	}
+
+	if (state->Vpp != state->Vcc && state->Vpp != 0) {
+		printk(KERN_ERR "%s(): slot cannot support VPP %u\n",
+			__func__, state->Vpp);
+		return -EPERM;
+	}
+
+	ret = sa1111_pcmcia_configure_socket(skt, state);
+	if (ret == 0)
+		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+
+	return ret;
+}
+
+static struct pcmcia_low_level jornada720_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+	.configure_socket	= jornada720_pcmcia_configure_socket,
+	.first			= 0,
+	.nr			= 2,
+};
+
+int __devinit pcmcia_jornada720_init(struct device *dev)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_jornada720()) {
+		unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+		GRER |= 0x00000002;
+
+		/* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+		sa1111_set_io_dir(dev, pin, 0, 0);
+		sa1111_set_io(dev, pin, 0);
+		sa1111_set_sleep_io(dev, pin, 0);
+
+		sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
+		ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+				sa11xx_drv_pcmcia_add_one);
+	}
+
+	return ret;
+}
diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c
new file mode 100644
index 0000000..c5caf57
--- /dev/null
+++ b/drivers/pcmcia/sa1111_lubbock.c
@@ -0,0 +1,236 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_lubbock.c
+ *
+ * Author:	George Davis
+ * Created:	Jan 10, 2002
+ * Copyright:	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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
+ *
+ * Lubbock PCMCIA specific routines.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/mach-types.h>
+#include <mach/lubbock.h>
+
+#include "sa1111_generic.h"
+
+static int
+lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+				const socket_state_t *state)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
+	int ret = 0;
+
+	pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0;
+
+	/* Lubbock uses the Maxim MAX1602, with the following connections:
+	 *
+	 * Socket 0 (PCMCIA):
+	 *	MAX1602	Lubbock		Register
+	 *	Pin	Signal
+	 *	-----	-------		----------------------
+	 *	A0VPP	S0_PWR0		SA-1111 GPIO A<0>
+	 *	A1VPP	S0_PWR1		SA-1111 GPIO A<1>
+	 *	A0VCC	S0_PWR2		SA-1111 GPIO A<2>
+	 *	A1VCC	S0_PWR3		SA-1111 GPIO A<3>
+	 *	VX	VCC
+	 *	VY	+3.3V
+	 *	12IN	+12V
+	 *	CODE	+3.3V		Cirrus  Code, CODE = High (VY)
+	 *
+	 * Socket 1 (CF):
+	 *	MAX1602	Lubbock		Register
+	 *	Pin	Signal
+	 *	-----	-------		----------------------
+	 *	A0VPP	GND		VPP is not connected
+	 *	A1VPP	GND		VPP is not connected
+	 *	A0VCC	S1_PWR0		MISC_WR<14>
+	 *	A1VCC	S1_PWR1		MISC_WR<15>
+	 *	VX	VCC
+	 *	VY	+3.3V
+	 *	12IN	GND		VPP is not connected
+	 *	CODE	+3.3V		Cirrus  Code, CODE = High (VY)
+	 *
+	 */
+
+ again:
+	switch (skt->nr) {
+	case 0:
+		pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+		switch (state->Vcc) {
+		case 0: /* Hi-Z */
+			break;
+
+		case 33: /* VY */
+			pa_dwr_set |= GPIO_A3;
+			break;
+
+		case 50: /* VX */
+			pa_dwr_set |= GPIO_A2;
+			break;
+
+		default:
+			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
+			       __func__, state->Vcc);
+			ret = -1;
+		}
+
+		switch (state->Vpp) {
+		case 0: /* Hi-Z */
+			break;
+
+		case 120: /* 12IN */
+			pa_dwr_set |= GPIO_A1;
+			break;
+
+		default: /* VCC */
+			if (state->Vpp == state->Vcc)
+				pa_dwr_set |= GPIO_A0;
+			else {
+				printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
+				       __func__, state->Vpp);
+				ret = -1;
+				break;
+			}
+		}
+		break;
+
+	case 1:
+		misc_mask = (1 << 15) | (1 << 14);
+
+		switch (state->Vcc) {
+		case 0: /* Hi-Z */
+			break;
+
+		case 33: /* VY */
+			misc_set |= 1 << 15;
+			break;
+
+		case 50: /* VX */
+			misc_set |= 1 << 14;
+			break;
+
+		default:
+			printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
+			       __func__, state->Vcc);
+			ret = -1;
+			break;
+		}
+
+		if (state->Vpp != state->Vcc && state->Vpp != 0) {
+			printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
+			       __func__, state->Vpp);
+			ret = -1;
+			break;
+		}
+		break;
+
+	default:
+		ret = -1;
+	}
+
+	if (ret == 0)
+		ret = sa1111_pcmcia_configure_socket(skt, state);
+
+	if (ret == 0) {
+		lubbock_set_misc_wr(misc_mask, misc_set);
+		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+	}
+
+#if 1
+	if (ret == 0 && state->Vcc == 33) {
+		struct pcmcia_state new_state;
+
+		/*
+		 * HACK ALERT:
+		 * We can't sense the voltage properly on Lubbock before
+		 * actually applying some power to the socket (catch 22).
+		 * Resense the socket Voltage Sense pins after applying
+		 * socket power.
+		 *
+		 * Note: It takes about 2.5ms for the MAX1602 VCC output
+		 * to rise.
+		 */
+		mdelay(3);
+
+		sa1111_pcmcia_socket_state(skt, &new_state);
+
+		if (!new_state.vs_3v && !new_state.vs_Xv) {
+			/*
+			 * Switch to 5V,  Configure socket with 5V voltage
+			 */
+			lubbock_set_misc_wr(misc_mask, 0);
+			sa1111_set_io(s->dev, pa_dwr_mask, 0);
+
+			/*
+			 * It takes about 100ms to turn off Vcc.
+			 */
+			mdelay(100);
+
+			/*
+			 * We need to hack around the const qualifier as
+			 * well to keep this ugly workaround localized and
+			 * not force it to the rest of the code. Barf bags
+			 * available in the seat pocket in front of you!
+			 */
+			((socket_state_t *)state)->Vcc = 50;
+			((socket_state_t *)state)->Vpp = 50;
+			goto again;
+		}
+	}
+#endif
+
+	return ret;
+}
+
+static struct pcmcia_low_level lubbock_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+	.configure_socket	= lubbock_pcmcia_configure_socket,
+	.first			= 0,
+	.nr			= 2,
+};
+
+#include "pxa2xx_base.h"
+
+int pcmcia_lubbock_init(struct sa1111_dev *sadev)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_lubbock()) {
+		/*
+		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
+		 * and switch to standby mode.
+		 */
+		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
+		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+
+		/* Set CF Socket 1 power to standby mode. */
+		lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
+
+		pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
+		pxa2xx_configure_sockets(&sadev->dev);
+		ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
+				pxa2xx_drv_pcmcia_add_one);
+	}
+
+	return ret;
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c
new file mode 100644
index 0000000..1d78739
--- /dev/null
+++ b/drivers/pcmcia/sa1111_neponset.c
@@ -0,0 +1,129 @@
+/*
+ * linux/drivers/pcmcia/sa1100_neponset.c
+ *
+ * Neponset PCMCIA specific routines
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <mach/neponset.h>
+#include <asm/hardware/sa1111.h>
+
+#include "sa1111_generic.h"
+
+/*
+ * Neponset uses the Maxim MAX1600, with the following connections:
+ *
+ *   MAX1600      Neponset
+ *
+ *    A0VCC        SA-1111 GPIO A<1>
+ *    A1VCC        SA-1111 GPIO A<0>
+ *    A0VPP        CPLD NCR A0VPP
+ *    A1VPP        CPLD NCR A1VPP
+ *    B0VCC        SA-1111 GPIO A<2>
+ *    B1VCC        SA-1111 GPIO A<3>
+ *    B0VPP        ground (slot B is CF)
+ *    B1VPP        ground (slot B is CF)
+ *
+ *     VX          VCC (5V)
+ *     VY          VCC3_3 (3.3V)
+ *     12INA       12V
+ *     12INB       ground (slot B is CF)
+ *
+ * The MAX1600 CODE pin is tied to ground, placing the device in 
+ * "Standard Intel code" mode. Refer to the Maxim data sheet for
+ * the corresponding truth table.
+ */
+
+static int
+neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
+{
+	struct sa1111_pcmcia_socket *s = to_skt(skt);
+	unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
+	int ret;
+
+	switch (skt->nr) {
+	case 0:
+		pa_dwr_mask = GPIO_A0 | GPIO_A1;
+		ncr_mask = NCR_A0VPP | NCR_A1VPP;
+
+		if (state->Vpp == 0)
+			ncr_set = 0;
+		else if (state->Vpp == 120)
+			ncr_set = NCR_A1VPP;
+		else if (state->Vpp == state->Vcc)
+			ncr_set = NCR_A0VPP;
+		else {
+			printk(KERN_ERR "%s(): unrecognized VPP %u\n",
+			       __func__, state->Vpp);
+			return -1;
+		}
+		break;
+
+	case 1:
+		pa_dwr_mask = GPIO_A2 | GPIO_A3;
+		ncr_mask = 0;
+		ncr_set = 0;
+
+		if (state->Vpp != state->Vcc && state->Vpp != 0) {
+			printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
+			       __func__, state->Vpp);
+			return -1;
+		}
+		break;
+
+	default:
+		return -1;
+	}
+
+	/*
+	 * pa_dwr_set is the mask for selecting Vcc on both sockets.
+	 * pa_dwr_mask selects which bits (and therefore socket) we change.
+	 */
+	switch (state->Vcc) {
+	default:
+	case 0:  pa_dwr_set = 0;		break;
+	case 33: pa_dwr_set = GPIO_A1|GPIO_A2;	break;
+	case 50: pa_dwr_set = GPIO_A0|GPIO_A3;	break;
+	}
+
+	ret = sa1111_pcmcia_configure_socket(skt, state);
+	if (ret == 0) {
+		neponset_ncr_frob(ncr_mask, ncr_set);
+		sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
+	}
+
+	return ret;
+}
+
+static struct pcmcia_low_level neponset_pcmcia_ops = {
+	.owner			= THIS_MODULE,
+	.configure_socket	= neponset_pcmcia_configure_socket,
+	.first			= 0,
+	.nr			= 2,
+};
+
+int pcmcia_neponset_init(struct sa1111_dev *sadev)
+{
+	int ret = -ENODEV;
+
+	if (machine_is_assabet()) {
+		/*
+		 * Set GPIO_A<3:0> to be outputs for the MAX1600,
+		 * and switch to standby mode.
+		 */
+		sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
+		sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+		sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+		sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
+		ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
+				sa11xx_drv_pcmcia_add_one);
+	}
+
+	return ret;
+}
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 0c62fe3..a3ee89a 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
 		skt = &sinfo->skt[i];
 
 		skt->nr = first + i;
-		skt->ops = ops;
-		skt->socket.owner = ops->owner;
-		skt->socket.dev.parent = dev;
-		skt->socket.pci_irq = NO_IRQ;
+		soc_pcmcia_init_one(skt, ops, dev);
 
 		ret = sa11xx_drv_pcmcia_add_one(skt);
 		if (ret)
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index a0a9c2a..e0433f5 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -32,6 +32,7 @@
 
 
 #include <linux/cpufreq.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -49,6 +50,8 @@
 
 #include "soc_common.h"
 
+static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev);
+
 #ifdef CONFIG_PCMCIA_DEBUG
 
 static int pc_debug;
@@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt,
 }
 EXPORT_SYMBOL(soc_common_pcmcia_get_timing);
 
+static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt,
+	unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++) {
+		if (skt->stat[i].irq)
+			free_irq(skt->stat[i].irq, skt);
+		if (gpio_is_valid(skt->stat[i].gpio))
+			gpio_free(skt->stat[i].gpio);
+	}
+
+	if (skt->ops->hw_shutdown)
+		skt->ops->hw_shutdown(skt);
+}
+
+static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+	__soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat));
+}
+
+static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+	int ret = 0, i;
+
+	if (skt->ops->hw_init) {
+		ret = skt->ops->hw_init(skt);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++) {
+		if (gpio_is_valid(skt->stat[i].gpio)) {
+			int irq;
+
+			ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN,
+					       skt->stat[i].name);
+			if (ret) {
+				__soc_pcmcia_hw_shutdown(skt, i);
+				return ret;
+			}
+
+			irq = gpio_to_irq(skt->stat[i].gpio);
+
+			if (i == SOC_STAT_RDY)
+				skt->socket.pci_irq = irq;
+			else
+				skt->stat[i].irq = irq;
+		}
+
+		if (skt->stat[i].irq) {
+			ret = request_irq(skt->stat[i].irq,
+					  soc_common_pcmcia_interrupt,
+					  IRQF_TRIGGER_NONE,
+					  skt->stat[i].name, skt);
+			if (ret) {
+				if (gpio_is_valid(skt->stat[i].gpio))
+					gpio_free(skt->stat[i].gpio);
+				__soc_pcmcia_hw_shutdown(skt, i);
+				return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
+		if (skt->stat[i].irq) {
+			irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING);
+			irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH);
+		}
+}
+
+static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
+		if (skt->stat[i].irq)
+			irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE);
+}
+
 static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 {
 	struct pcmcia_state state;
@@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt)
 
 	memset(&state, 0, sizeof(struct pcmcia_state));
 
+	/* Make battery voltage state report 'good' */
+	state.bvd1 = 1;
+	state.bvd2 = 1;
+
+	/* CD is active low by default */
+	if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio))
+		state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio);
+
+	/* RDY and BVD are active high by default */
+	if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio))
+		state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio);
+	if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio))
+		state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio);
+	if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio))
+		state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio);
+
 	skt->ops->socket_state(skt, &state);
 
 	stat = state.detect  ? SS_DETECT : 0;
@@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock)
 	debug(skt, 2, "initializing socket\n");
 	if (skt->ops->socket_init)
 		skt->ops->socket_init(skt);
+	soc_pcmcia_hw_enable(skt);
 	return 0;
 }
 
@@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock)
 
 	debug(skt, 2, "suspending socket\n");
 
+	soc_pcmcia_hw_disable(skt);
 	if (skt->ops->socket_suspend)
 		skt->ops->socket_suspend(skt);
 
@@ -526,69 +634,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {
 };
 
 
-int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
-			    struct pcmcia_irqs *irqs, int nr)
-{
-	int i, res = 0;
-
-	for (i = 0; i < nr; i++) {
-		if (irqs[i].sock != skt->nr)
-			continue;
-		res = request_irq(irqs[i].irq, soc_common_pcmcia_interrupt,
-				  IRQF_DISABLED, irqs[i].str, skt);
-		if (res)
-			break;
-		irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
-	}
-
-	if (res) {
-		printk(KERN_ERR "PCMCIA: request for IRQ%d failed (%d)\n",
-			irqs[i].irq, res);
-
-		while (i--)
-			if (irqs[i].sock == skt->nr)
-				free_irq(irqs[i].irq, skt);
-	}
-	return res;
-}
-EXPORT_SYMBOL(soc_pcmcia_request_irqs);
-
-void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt,
-			  struct pcmcia_irqs *irqs, int nr)
-{
-	int i;
-
-	for (i = 0; i < nr; i++)
-		if (irqs[i].sock == skt->nr)
-			free_irq(irqs[i].irq, skt);
-}
-EXPORT_SYMBOL(soc_pcmcia_free_irqs);
-
-void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
-			     struct pcmcia_irqs *irqs, int nr)
-{
-	int i;
-
-	for (i = 0; i < nr; i++)
-		if (irqs[i].sock == skt->nr)
-			irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
-}
-EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
-
-void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
-			    struct pcmcia_irqs *irqs, int nr)
-{
-	int i;
-
-	for (i = 0; i < nr; i++)
-		if (irqs[i].sock == skt->nr) {
-			irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
-			irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
-		}
-}
-EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
-
-
 static LIST_HEAD(soc_pcmcia_sockets);
 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
@@ -635,6 +680,21 @@ module_exit(soc_pcmcia_cpufreq_unregister);
 
 #endif
 
+void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
+	struct pcmcia_low_level *ops, struct device *dev)
+{
+	int i;
+
+	skt->ops = ops;
+	skt->socket.owner = ops->owner;
+	skt->socket.dev.parent = dev;
+	skt->socket.pci_irq = NO_IRQ;
+
+	for (i = 0; i < ARRAY_SIZE(skt->stat); i++)
+		skt->stat[i].gpio = -EINVAL;
+}
+EXPORT_SYMBOL(soc_pcmcia_init_one);
+
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 {
 	mutex_lock(&soc_pcmcia_sockets_lock);
@@ -642,8 +702,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 
 	pcmcia_unregister_socket(&skt->socket);
 
-	skt->ops->hw_shutdown(skt);
+	soc_pcmcia_hw_shutdown(skt);
 
+	/* should not be required; violates some lowlevel drivers */
 	soc_common_pcmcia_config_skt(skt, &dead_socket);
 
 	list_del(&skt->node);
@@ -700,7 +761,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 	 */
 	skt->ops->set_timing(skt);
 
-	ret = skt->ops->hw_init(skt);
+	ret = soc_pcmcia_hw_init(skt);
 	if (ret)
 		goto out_err_6;
 
@@ -733,7 +794,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
 	pcmcia_unregister_socket(&skt->socket);
 
  out_err_7:
-	skt->ops->hw_shutdown(skt);
+	soc_pcmcia_hw_shutdown(skt);
  out_err_6:
 	list_del(&skt->node);
 	mutex_unlock(&soc_pcmcia_sockets_lock);
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 9daa736..e6fcbea 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -50,6 +50,16 @@ struct soc_pcmcia_socket {
 	struct resource		res_attr;
 	void __iomem		*virt_io;
 
+	struct {
+		int		gpio;
+		unsigned int	irq;
+		const char	*name;
+	} stat[4];
+#define SOC_STAT_CD		0	/* Card detect */
+#define SOC_STAT_BVD1		1	/* BATDEAD / IOSTSCHG */
+#define SOC_STAT_BVD2		2	/* BATWARN / IOSPKR */
+#define SOC_STAT_RDY		3	/* Ready / Interrupt */
+
 	unsigned int		irq_state;
 
 	struct timer_list	poll_timer;
@@ -115,25 +125,16 @@ struct pcmcia_low_level {
 };
 
 
-struct pcmcia_irqs {
-	int sock;
-	int irq;
-	const char *str;
-};
-
 struct soc_pcmcia_timing {
 	unsigned short io;
 	unsigned short mem;
 	unsigned short attr;
 };
 
-extern int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
-extern void soc_pcmcia_free_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
-extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
-extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr);
 extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
 
-
+void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
+	struct pcmcia_low_level *ops, struct device *dev);
 void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
 int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index afaf885..c6d29ff 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -23,11 +23,48 @@ config DEBUG_PINCTRL
 	help
 	  Say Y here to add some extra checks and diagnostics to PINCTRL calls.
 
+config PINCTRL_PXA3xx
+	bool
+	select PINMUX
+
+config PINCTRL_MMP2
+	bool "MMP2 pin controller driver"
+	depends on ARCH_MMP
+	select PINCTRL_PXA3xx
+	select PINCONF
+
+config PINCTRL_PXA168
+	bool "PXA168 pin controller driver"
+	depends on ARCH_MMP
+	select PINCTRL_PXA3xx
+	select PINCONF
+
+config PINCTRL_PXA910
+	bool "PXA910 pin controller driver"
+	depends on ARCH_MMP
+	select PINCTRL_PXA3xx
+	select PINCONF
+
 config PINCTRL_SIRF
 	bool "CSR SiRFprimaII pin controller driver"
 	depends on ARCH_PRIMA2
 	select PINMUX
 
+config PINCTRL_TEGRA
+	bool
+
+config PINCTRL_TEGRA20
+	bool
+	select PINMUX
+	select PINCONF
+	select PINCTRL_TEGRA
+
+config PINCTRL_TEGRA30
+	bool
+	select PINMUX
+	select PINCONF
+	select PINCTRL_TEGRA
+
 config PINCTRL_U300
 	bool "U300 pin controller driver"
 	depends on ARCH_U300
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 827601c..754329b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -5,6 +5,13 @@ ccflags-$(CONFIG_DEBUG_PINCTRL)	+= -DDEBUG
 obj-$(CONFIG_PINCTRL)		+= core.o
 obj-$(CONFIG_PINMUX)		+= pinmux.o
 obj-$(CONFIG_PINCONF)		+= pinconf.o
+obj-$(CONFIG_PINCTRL_PXA3xx)	+= pinctrl-pxa3xx.o
+obj-$(CONFIG_PINCTRL_MMP2)	+= pinctrl-mmp2.o
+obj-$(CONFIG_PINCTRL_PXA168)	+= pinctrl-pxa168.o
+obj-$(CONFIG_PINCTRL_PXA910)	+= pinctrl-pxa910.o
 obj-$(CONFIG_PINCTRL_SIRF)	+= pinctrl-sirf.o
+obj-$(CONFIG_PINCTRL_TEGRA)	+= pinctrl-tegra.o
+obj-$(CONFIG_PINCTRL_TEGRA20)	+= pinctrl-tegra20.o
+obj-$(CONFIG_PINCTRL_TEGRA30)	+= pinctrl-tegra30.o
 obj-$(CONFIG_PINCTRL_U300)	+= pinctrl-u300.o
 obj-$(CONFIG_PINCTRL_COH901)	+= pinctrl-coh901.o
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 894cd5e..fb3fbb7 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1,12 +1,14 @@
 /*
  * Core driver for the pin control subsystem
  *
- * Copyright (C) 2011 ST-Ericsson SA
+ * Copyright (C) 2011-2012 ST-Ericsson SA
  * Written on behalf of Linaro for ST-Ericsson
  * Based on bits of regulator core, gpio core and clk core
  *
  * Author: Linus Walleij <linus.walleij@linaro.org>
  *
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
  * License terms: GNU General Public License (GPL) version 2
  */
 #define pr_fmt(fmt) "pinctrl core: " fmt
@@ -30,10 +32,48 @@
 #include "pinmux.h"
 #include "pinconf.h"
 
+/**
+ * struct pinctrl_maps - a list item containing part of the mapping table
+ * @node: mapping table list node
+ * @maps: array of mapping table entries
+ * @num_maps: the number of entries in @maps
+ */
+struct pinctrl_maps {
+	struct list_head node;
+	struct pinctrl_map const *maps;
+	unsigned num_maps;
+};
+
+/**
+ * struct pinctrl_hog - a list item to stash control hogs
+ * @node: pin control hog list node
+ * @map: map entry responsible for this hogging
+ * @pmx: the pin control hogged by this item
+ */
+struct pinctrl_hog {
+	struct list_head node;
+	struct pinctrl_map const *map;
+	struct pinctrl *p;
+};
+
 /* Global list of pin control devices */
 static DEFINE_MUTEX(pinctrldev_list_mutex);
 static LIST_HEAD(pinctrldev_list);
 
+/* List of pin controller handles */
+static DEFINE_MUTEX(pinctrl_list_mutex);
+static LIST_HEAD(pinctrl_list);
+
+/* Global pinctrl maps */
+static DEFINE_MUTEX(pinctrl_maps_mutex);
+static LIST_HEAD(pinctrl_maps);
+
+#define for_each_maps(_maps_node_, _i_, _map_) \
+	list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
+		for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
+			_i_ < _maps_node_->num_maps; \
+			i++, _map_ = &_maps_node_->maps[_i_])
+
 const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
 {
 	/* We're not allowed to register devices without name */
@@ -48,31 +88,23 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
 EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata);
 
 /**
- * get_pinctrl_dev_from_dev() - look up pin controller device
- * @dev: a device pointer, this may be NULL but then devname needs to be
- *	defined instead
- * @devname: the name of a device instance, as returned by dev_name(), this
- *	may be NULL but then dev needs to be defined instead
+ * get_pinctrl_dev_from_devname() - look up pin controller device
+ * @devname: the name of a device instance, as returned by dev_name()
  *
  * Looks up a pin control device matching a certain device name or pure device
  * pointer, the pure device pointer will take precedence.
  */
-struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
-					     const char *devname)
+struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname)
 {
 	struct pinctrl_dev *pctldev = NULL;
 	bool found = false;
 
+	if (!devname)
+		return NULL;
+
 	mutex_lock(&pinctrldev_list_mutex);
 	list_for_each_entry(pctldev, &pinctrldev_list, node) {
-		if (dev && pctldev->dev == dev) {
-			/* Matched on device pointer */
-			found = true;
-			break;
-		}
-
-		if (devname &&
-		    !strcmp(dev_name(pctldev->dev), devname)) {
+		if (!strcmp(dev_name(pctldev->dev), devname)) {
 			/* Matched on device name */
 			found = true;
 			break;
@@ -261,9 +293,9 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
  * the GPIO subsystem, return the device and the matching GPIO range. Returns
  * negative if the GPIO range could not be found in any device.
  */
-int pinctrl_get_device_gpio_range(unsigned gpio,
-				struct pinctrl_dev **outdev,
-				struct pinctrl_gpio_range **outrange)
+static int pinctrl_get_device_gpio_range(unsigned gpio,
+					 struct pinctrl_dev **outdev,
+					 struct pinctrl_gpio_range **outrange)
 {
 	struct pinctrl_dev *pctldev = NULL;
 
@@ -297,9 +329,10 @@ void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
 			    struct pinctrl_gpio_range *range)
 {
 	mutex_lock(&pctldev->gpio_ranges_lock);
-	list_add(&range->node, &pctldev->gpio_ranges);
+	list_add_tail(&range->node, &pctldev->gpio_ranges);
 	mutex_unlock(&pctldev->gpio_ranges_lock);
 }
+EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range);
 
 /**
  * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
@@ -313,6 +346,7 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
 	list_del(&range->node);
 	mutex_unlock(&pctldev->gpio_ranges_lock);
 }
+EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
 
 /**
  * pinctrl_get_group_selector() - returns the group selector for a group
@@ -345,6 +379,464 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
 	return -EINVAL;
 }
 
+/**
+ * pinctrl_request_gpio() - request a single pin to be used in as GPIO
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_request() semantics, platforms and individual drivers
+ * shall *NOT* request GPIO pins to be muxed in.
+ */
+int pinctrl_request_gpio(unsigned gpio)
+{
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_gpio_range *range;
+	int ret;
+	int pin;
+
+	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
+	if (ret)
+		return -EINVAL;
+
+	/* Convert to the pin controllers number space */
+	pin = gpio - range->base + range->pin_base;
+
+	return pinmux_request_gpio(pctldev, range, pin, gpio);
+}
+EXPORT_SYMBOL_GPL(pinctrl_request_gpio);
+
+/**
+ * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_free() semantics, platforms and individual drivers
+ * shall *NOT* request GPIO pins to be muxed out.
+ */
+void pinctrl_free_gpio(unsigned gpio)
+{
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_gpio_range *range;
+	int ret;
+	int pin;
+
+	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
+	if (ret)
+		return;
+
+	/* Convert to the pin controllers number space */
+	pin = gpio - range->base + range->pin_base;
+
+	return pinmux_free_gpio(pctldev, pin, range);
+}
+EXPORT_SYMBOL_GPL(pinctrl_free_gpio);
+
+static int pinctrl_gpio_direction(unsigned gpio, bool input)
+{
+	struct pinctrl_dev *pctldev;
+	struct pinctrl_gpio_range *range;
+	int ret;
+	int pin;
+
+	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
+	if (ret)
+		return ret;
+
+	/* Convert to the pin controllers number space */
+	pin = gpio - range->base + range->pin_base;
+
+	return pinmux_gpio_direction(pctldev, range, pin, input);
+}
+
+/**
+ * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_direction_input() semantics, platforms and individual
+ * drivers shall *NOT* touch pin control GPIO calls.
+ */
+int pinctrl_gpio_direction_input(unsigned gpio)
+{
+	return pinctrl_gpio_direction(gpio, true);
+}
+EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input);
+
+/**
+ * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_direction_output() semantics, platforms and individual
+ * drivers shall *NOT* touch pin control GPIO calls.
+ */
+int pinctrl_gpio_direction_output(unsigned gpio)
+{
+	return pinctrl_gpio_direction(gpio, false);
+}
+EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output);
+
+static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name)
+{
+	struct pinctrl_dev *pctldev = NULL;
+	const char *devname = NULL;
+	struct pinctrl *p;
+	bool found_map;
+	unsigned num_maps = 0;
+	int ret = -ENODEV;
+	struct pinctrl_maps *maps_node;
+	int i;
+	struct pinctrl_map const *map;
+
+	/* We must have dev or ID or both */
+	if (!dev && !name)
+		return ERR_PTR(-EINVAL);
+
+	if (dev)
+		devname = dev_name(dev);
+
+	pr_debug("get pin control handle %s for device %s\n", name,
+		 devname ? devname : "(none)");
+
+	/*
+	 * create the state cookie holder struct pinctrl for each
+	 * mapping, this is what consumers will get when requesting
+	 * a pin control handle with pinctrl_get()
+	 */
+	p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL);
+	if (p == NULL)
+		return ERR_PTR(-ENOMEM);
+	mutex_init(&p->mutex);
+	pinmux_init_pinctrl_handle(p);
+
+	/* Iterate over the pin control maps to locate the right ones */
+	for_each_maps(maps_node, i, map) {
+		found_map = false;
+
+		/*
+		 * First, try to find the pctldev given in the map
+		 */
+		pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
+		if (!pctldev) {
+			dev_err(dev, "unknown pinctrl device %s in map entry",
+				map->ctrl_dev_name);
+			pinmux_put(p);
+			kfree(p);
+			/* Eventually, this should trigger deferred probe */
+			return ERR_PTR(-ENODEV);
+		}
+
+		pr_debug("in map, found pctldev %s to handle function %s",
+			 dev_name(pctldev->dev), map->function);
+
+		/*
+		 * If we're looking for a specific named map, this must match,
+		 * else we loop and look for the next.
+		 */
+		if (name != NULL) {
+			if (map->name == NULL)
+				continue;
+			if (strcmp(map->name, name))
+				continue;
+		}
+
+		/*
+		 * This is for the case where no device name is given, we
+		 * already know that the function name matches from above
+		 * code.
+		 */
+		if (!map->dev_name && (name != NULL))
+			found_map = true;
+
+		/* If the mapping has a device set up it must match */
+		if (map->dev_name &&
+		    (!devname || !strcmp(map->dev_name, devname)))
+			/* MATCH! */
+			found_map = true;
+
+		/* If this map is applicable, then apply it */
+		if (found_map) {
+			ret = pinmux_apply_muxmap(pctldev, p, dev,
+						   devname, map);
+			if (ret) {
+				kfree(p);
+				return ERR_PTR(ret);
+			}
+			num_maps++;
+		}
+	}
+
+	/*
+	 * This may be perfectly legitimate. An IP block may get re-used
+	 * across SoCs. Not all of those SoCs may need pinmux settings for the
+	 * IP block, e.g. if one SoC dedicates pins to that function but
+	 * another doesn't. The driver won't know this, and will always
+	 * attempt to set up the pinmux. The mapping table defines whether any
+	 * HW programming is actually needed.
+	 */
+	if (!num_maps)
+		dev_info(dev, "zero maps found for mapping %s\n", name);
+
+	pr_debug("found %u mux maps for device %s, UD %s\n",
+		 num_maps,
+		 devname ? devname : "(anonymous)",
+		 name ? name : "(undefined)");
+
+	/* Add the pinmux to the global list */
+	mutex_lock(&pinctrl_list_mutex);
+	list_add_tail(&p->node, &pinctrl_list);
+	mutex_unlock(&pinctrl_list_mutex);
+
+	return p;
+}
+
+/**
+ * pinctrl_get() - retrieves the pin controller handle for a certain device
+ * @dev: the device to get the pin controller handle for
+ * @name: an optional specific control mapping name or NULL, the name is only
+ *	needed if you want to have more than one mapping per device, or if you
+ *	need an anonymous pin control (not tied to any specific device)
+ */
+struct pinctrl *pinctrl_get(struct device *dev, const char *name)
+{
+	struct pinctrl *p;
+
+	mutex_lock(&pinctrl_maps_mutex);
+	p = pinctrl_get_locked(dev, name);
+	mutex_unlock(&pinctrl_maps_mutex);
+
+	return p;
+}
+EXPORT_SYMBOL_GPL(pinctrl_get);
+
+/**
+ * pinctrl_put() - release a previously claimed pin control handle
+ * @p: a pin control handle previously claimed by pinctrl_get()
+ */
+void pinctrl_put(struct pinctrl *p)
+{
+	if (p == NULL)
+		return;
+
+	mutex_lock(&p->mutex);
+	if (p->usecount)
+		pr_warn("releasing pin control handle with active users!\n");
+	/* Free the groups and all acquired pins */
+	pinmux_put(p);
+	mutex_unlock(&p->mutex);
+
+	/* Remove from list */
+	mutex_lock(&pinctrl_list_mutex);
+	list_del(&p->node);
+	mutex_unlock(&pinctrl_list_mutex);
+
+	kfree(p);
+}
+EXPORT_SYMBOL_GPL(pinctrl_put);
+
+/**
+ * pinctrl_enable() - enable a certain pin controller setting
+ * @p: the pin control handle to enable, previously claimed by pinctrl_get()
+ */
+int pinctrl_enable(struct pinctrl *p)
+{
+	int ret = 0;
+
+	if (p == NULL)
+		return -EINVAL;
+	mutex_lock(&p->mutex);
+	if (p->usecount++ == 0) {
+		ret = pinmux_enable(p);
+		if (ret)
+			p->usecount--;
+	}
+	mutex_unlock(&p->mutex);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_enable);
+
+/**
+ * pinctrl_disable() - disable a certain pin control setting
+ * @p: the pin control handle to disable, previously claimed by pinctrl_get()
+ */
+void pinctrl_disable(struct pinctrl *p)
+{
+	if (p == NULL)
+		return;
+
+	mutex_lock(&p->mutex);
+	if (--p->usecount == 0) {
+		pinmux_disable(p);
+	}
+	mutex_unlock(&p->mutex);
+}
+EXPORT_SYMBOL_GPL(pinctrl_disable);
+
+/**
+ * pinctrl_register_mappings() - register a set of pin controller mappings
+ * @maps: the pincontrol mappings table to register. This should probably be
+ *	marked with __initdata so it can be discarded after boot. This
+ *	function will perform a shallow copy for the mapping entries.
+ * @num_maps: the number of maps in the mapping table
+ */
+int pinctrl_register_mappings(struct pinctrl_map const *maps,
+			      unsigned num_maps)
+{
+	int i;
+	struct pinctrl_maps *maps_node;
+
+	pr_debug("add %d pinmux maps\n", num_maps);
+
+	/* First sanity check the new mapping */
+	for (i = 0; i < num_maps; i++) {
+		if (!maps[i].name) {
+			pr_err("failed to register map %d: no map name given\n",
+					i);
+			return -EINVAL;
+		}
+
+		if (!maps[i].ctrl_dev_name) {
+			pr_err("failed to register map %s (%d): no pin control device given\n",
+			       maps[i].name, i);
+			return -EINVAL;
+		}
+
+		if (!maps[i].function) {
+			pr_err("failed to register map %s (%d): no function ID given\n",
+					maps[i].name, i);
+			return -EINVAL;
+		}
+
+		if (!maps[i].dev_name)
+			pr_debug("add system map %s function %s with no device\n",
+				 maps[i].name,
+				 maps[i].function);
+		else
+			pr_debug("register map %s, function %s\n",
+				 maps[i].name,
+				 maps[i].function);
+	}
+
+	maps_node = kzalloc(sizeof(*maps_node), GFP_KERNEL);
+	if (!maps_node) {
+		pr_err("failed to alloc struct pinctrl_maps\n");
+		return -ENOMEM;
+	}
+
+	maps_node->num_maps = num_maps;
+	maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL);
+	if (!maps_node->maps) {
+		kfree(maps_node);
+		return -ENOMEM;
+	}
+
+	mutex_lock(&pinctrl_maps_mutex);
+	list_add_tail(&maps_node->node, &pinctrl_maps);
+	mutex_unlock(&pinctrl_maps_mutex);
+
+	return 0;
+}
+
+/* Hog a single map entry and add to the hoglist */
+static int pinctrl_hog_map(struct pinctrl_dev *pctldev,
+			   struct pinctrl_map const *map)
+{
+	struct pinctrl_hog *hog;
+	struct pinctrl *p;
+	int ret;
+
+	hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL);
+	if (!hog)
+		return -ENOMEM;
+
+	p = pinctrl_get_locked(pctldev->dev, map->name);
+	if (IS_ERR(p)) {
+		kfree(hog);
+		dev_err(pctldev->dev,
+			"could not get the %s pin control mapping for hogging\n",
+			map->name);
+		return PTR_ERR(p);
+	}
+
+	ret = pinctrl_enable(p);
+	if (ret) {
+		pinctrl_put(p);
+		kfree(hog);
+		dev_err(pctldev->dev,
+			"could not enable the %s pin control mapping for hogging\n",
+			map->name);
+		return ret;
+	}
+
+	hog->map = map;
+	hog->p = p;
+
+	dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name,
+		 map->function);
+	mutex_lock(&pctldev->pinctrl_hogs_lock);
+	list_add_tail(&hog->node, &pctldev->pinctrl_hogs);
+	mutex_unlock(&pctldev->pinctrl_hogs_lock);
+
+	return 0;
+}
+
+/**
+ * pinctrl_hog_maps() - hog specific map entries on controller device
+ * @pctldev: the pin control device to hog entries on
+ *
+ * When the pin controllers are registered, there may be some specific pinmux
+ * map entries that need to be hogged, i.e. get+enabled until the system shuts
+ * down.
+ */
+static int pinctrl_hog_maps(struct pinctrl_dev *pctldev)
+{
+	struct device *dev = pctldev->dev;
+	const char *devname = dev_name(dev);
+	int ret;
+	struct pinctrl_maps *maps_node;
+	int i;
+	struct pinctrl_map const *map;
+
+	INIT_LIST_HEAD(&pctldev->pinctrl_hogs);
+	mutex_init(&pctldev->pinctrl_hogs_lock);
+
+	mutex_lock(&pinctrl_maps_mutex);
+	for_each_maps(maps_node, i, map) {
+		if (!strcmp(map->ctrl_dev_name, devname) &&
+		    !strcmp(map->dev_name, devname)) {
+			/* OK time to hog! */
+			ret = pinctrl_hog_map(pctldev, map);
+			if (ret) {
+				mutex_unlock(&pinctrl_maps_mutex);
+				return ret;
+			}
+		}
+	}
+	mutex_unlock(&pinctrl_maps_mutex);
+
+	return 0;
+}
+
+/**
+ * pinctrl_unhog_maps() - unhog specific map entries on controller device
+ * @pctldev: the pin control device to unhog entries on
+ */
+static void pinctrl_unhog_maps(struct pinctrl_dev *pctldev)
+{
+	struct list_head *node, *tmp;
+
+	mutex_lock(&pctldev->pinctrl_hogs_lock);
+	list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) {
+		struct pinctrl_hog *hog =
+			list_entry(node, struct pinctrl_hog, node);
+		pinctrl_disable(hog->p);
+		pinctrl_put(hog->p);
+		list_del(node);
+		kfree(hog);
+	}
+	mutex_unlock(&pctldev->pinctrl_hogs_lock);
+}
+
 #ifdef CONFIG_DEBUG_FS
 
 static int pinctrl_pins_show(struct seq_file *s, void *what)
@@ -435,6 +927,46 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
 	return 0;
 }
 
+static int pinctrl_maps_show(struct seq_file *s, void *what)
+{
+	struct pinctrl_maps *maps_node;
+	int i;
+	struct pinctrl_map const *map;
+
+	seq_puts(s, "Pinctrl maps:\n");
+
+	mutex_lock(&pinctrl_maps_mutex);
+	for_each_maps(maps_node, i, map) {
+		seq_printf(s, "%s:\n", map->name);
+		if (map->dev_name)
+			seq_printf(s, "  device: %s\n",
+				   map->dev_name);
+		else
+			seq_printf(s, "  SYSTEM MUX\n");
+		seq_printf(s, "  controlling device %s\n",
+			   map->ctrl_dev_name);
+		seq_printf(s, "  function: %s\n", map->function);
+		seq_printf(s, "  group: %s\n", map->group ? map->group :
+			   "(default)");
+	}
+	mutex_unlock(&pinctrl_maps_mutex);
+
+	return 0;
+}
+
+static int pinmux_hogs_show(struct seq_file *s, void *what)
+{
+	struct pinctrl_dev *pctldev = s->private;
+	struct pinctrl_hog *hog;
+
+	seq_puts(s, "Pin control map hogs held by device\n");
+
+	list_for_each_entry(hog, &pctldev->pinctrl_hogs, node)
+		seq_printf(s, "%s\n", hog->map->name);
+
+	return 0;
+}
+
 static int pinctrl_devices_show(struct seq_file *s, void *what)
 {
 	struct pinctrl_dev *pctldev;
@@ -458,6 +990,32 @@ static int pinctrl_devices_show(struct seq_file *s, void *what)
 	return 0;
 }
 
+static int pinctrl_show(struct seq_file *s, void *what)
+{
+	struct pinctrl *p;
+
+	seq_puts(s, "Requested pin control handlers their pinmux maps:\n");
+	list_for_each_entry(p, &pinctrl_list, node) {
+		struct pinctrl_dev *pctldev = p->pctldev;
+
+		if (!pctldev) {
+			seq_puts(s, "NO PIN CONTROLLER DEVICE\n");
+			continue;
+		}
+
+		seq_printf(s, "device: %s",
+			   pinctrl_dev_get_name(p->pctldev));
+
+		pinmux_dbg_show(s, p);
+
+		seq_printf(s, " users: %u map-> %s\n",
+			   p->usecount,
+			   p->dev ? dev_name(p->dev) : "(system)");
+	}
+
+	return 0;
+}
+
 static int pinctrl_pins_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, pinctrl_pins_show, inode->i_private);
@@ -473,11 +1031,26 @@ static int pinctrl_gpioranges_open(struct inode *inode, struct file *file)
 	return single_open(file, pinctrl_gpioranges_show, inode->i_private);
 }
 
+static int pinctrl_maps_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pinctrl_maps_show, inode->i_private);
+}
+
+static int pinmux_hogs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pinmux_hogs_show, inode->i_private);
+}
+
 static int pinctrl_devices_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, pinctrl_devices_show, NULL);
 }
 
+static int pinctrl_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pinctrl_show, NULL);
+}
+
 static const struct file_operations pinctrl_pins_ops = {
 	.open		= pinctrl_pins_open,
 	.read		= seq_read,
@@ -499,6 +1072,20 @@ static const struct file_operations pinctrl_gpioranges_ops = {
 	.release	= single_release,
 };
 
+static const struct file_operations pinctrl_maps_ops = {
+	.open		= pinctrl_maps_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations pinmux_hogs_ops = {
+	.open		= pinmux_hogs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static const struct file_operations pinctrl_devices_ops = {
 	.open		= pinctrl_devices_open,
 	.read		= seq_read,
@@ -506,6 +1093,13 @@ static const struct file_operations pinctrl_devices_ops = {
 	.release	= single_release,
 };
 
+static const struct file_operations pinctrl_ops = {
+	.open		= pinctrl_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static struct dentry *debugfs_root;
 
 static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
@@ -527,6 +1121,10 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
 			    device_root, pctldev, &pinctrl_groups_ops);
 	debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO,
 			    device_root, pctldev, &pinctrl_gpioranges_ops);
+	debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO,
+			    device_root, pctldev, &pinctrl_maps_ops);
+	debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO,
+			    device_root, pctldev, &pinmux_hogs_ops);
 	pinmux_init_device_debugfs(device_root, pctldev);
 	pinconf_init_device_debugfs(device_root, pctldev);
 }
@@ -547,7 +1145,8 @@ static void pinctrl_init_debugfs(void)
 
 	debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO,
 			    debugfs_root, NULL, &pinctrl_devices_ops);
-	pinmux_init_debugfs(debugfs_root);
+	debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO,
+			    debugfs_root, NULL, &pinctrl_ops);
 }
 
 #else /* CONFIG_DEBUG_FS */
@@ -630,9 +1229,9 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
 
 	pinctrl_init_device_debugfs(pctldev);
 	mutex_lock(&pinctrldev_list_mutex);
-	list_add(&pctldev->node, &pinctrldev_list);
+	list_add_tail(&pctldev->node, &pinctrldev_list);
 	mutex_unlock(&pinctrldev_list_mutex);
-	pinmux_hog_maps(pctldev);
+	pinctrl_hog_maps(pctldev);
 	return pctldev;
 
 out_err:
@@ -653,7 +1252,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
 		return;
 
 	pinctrl_remove_device_debugfs(pctldev);
-	pinmux_unhog_maps(pctldev);
+	pinctrl_unhog_maps(pctldev);
 	/* TODO: check that no pinmuxes are still active? */
 	mutex_lock(&pinctrldev_list_mutex);
 	list_del(&pctldev->node);
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index cfa86da..7c30567 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -28,8 +28,9 @@ struct pinctrl_gpio_range;
  * @owner: module providing the pin controller, used for refcounting
  * @driver_data: driver data for drivers registering to the pin controller
  *	subsystem
- * @pinmux_hogs_lock: lock for the pinmux hog list
- * @pinmux_hogs: list of pinmux maps hogged by this device
+ * @pinctrl_hogs_lock: lock for the pin control hog list
+ * @pinctrl_hogs: list of pin control maps hogged by this device
+ * @device_root: debugfs root for this device
  */
 struct pinctrl_dev {
 	struct list_head node;
@@ -41,12 +42,37 @@ struct pinctrl_dev {
 	struct device *dev;
 	struct module *owner;
 	void *driver_data;
+	struct mutex pinctrl_hogs_lock;
+	struct list_head pinctrl_hogs;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *device_root;
 #endif
+};
+
+/**
+ * struct pinctrl - per-device pin control state holder
+ * @node: global list node
+ * @dev: the device using this pin control handle
+ * @usecount: the number of active users of this pin controller setting, used
+ *	to keep track of nested use cases
+ * @pctldev: pin control device handling this pin control handle
+ * @mutex: a lock for the pin control state holder
+ * @func_selector: the function selector for the pinmux device handling
+ *	this pinmux
+ * @groups: the group selectors for the pinmux device and
+ *	selector combination handling this pinmux, this is a list that
+ *	will be traversed on all pinmux operations such as
+ *	get/put/enable/disable
+ */
+struct pinctrl {
+	struct list_head node;
+	struct device *dev;
+	unsigned usecount;
+	struct pinctrl_dev *pctldev;
+	struct mutex mutex;
 #ifdef CONFIG_PINMUX
-	struct mutex pinmux_hogs_lock;
-	struct list_head pinmux_hogs;
+	unsigned func_selector;
+	struct list_head groups;
 #endif
 };
 
@@ -72,12 +98,8 @@ struct pin_desc {
 #endif
 };
 
-struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
-					     const char *dev_name);
+struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
 struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
 int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
-int pinctrl_get_device_gpio_range(unsigned gpio,
-				  struct pinctrl_dev **outdev,
-				  struct pinctrl_gpio_range **outrange);
 int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
 			       const char *pin_group);
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index 9fb7545..0c9d08d 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -23,7 +23,20 @@
 #include "core.h"
 #include "pinconf.h"
 
-int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
+int pinconf_check_ops(struct pinctrl_dev *pctldev)
+{
+	const struct pinconf_ops *ops = pctldev->desc->confops;
+
+	/* We must be able to read out pin status */
+	if (!ops->pin_config_get && !ops->pin_config_group_get)
+		return -EINVAL;
+	/* We have to be able to config the pins in SOME way */
+	if (!ops->pin_config_set && !ops->pin_config_group_set)
+		return -EINVAL;
+	return 0;
+}
+
+static int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long *config)
 {
 	const struct pinconf_ops *ops = pctldev->desc->confops;
@@ -51,7 +64,7 @@ int pin_config_get(const char *dev_name, const char *name,
 	struct pinctrl_dev *pctldev;
 	int pin;
 
-	pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
+	pctldev = get_pinctrl_dev_from_devname(dev_name);
 	if (!pctldev)
 		return -EINVAL;
 
@@ -63,7 +76,7 @@ int pin_config_get(const char *dev_name, const char *name,
 }
 EXPORT_SYMBOL(pin_config_get);
 
-int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
+static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long config)
 {
 	const struct pinconf_ops *ops = pctldev->desc->confops;
@@ -99,7 +112,7 @@ int pin_config_set(const char *dev_name, const char *name,
 	struct pinctrl_dev *pctldev;
 	int pin;
 
-	pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
+	pctldev = get_pinctrl_dev_from_devname(dev_name);
 	if (!pctldev)
 		return -EINVAL;
 
@@ -118,7 +131,7 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
 	const struct pinconf_ops *ops;
 	int selector;
 
-	pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
+	pctldev = get_pinctrl_dev_from_devname(dev_name);
 	if (!pctldev)
 		return -EINVAL;
 	ops = pctldev->desc->confops;
@@ -138,7 +151,6 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
 }
 EXPORT_SYMBOL(pin_config_group_get);
 
-
 int pin_config_group_set(const char *dev_name, const char *pin_group,
 			 unsigned long config)
 {
@@ -151,7 +163,7 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
 	int ret;
 	int i;
 
-	pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
+	pctldev = get_pinctrl_dev_from_devname(dev_name);
 	if (!pctldev)
 		return -EINVAL;
 	ops = pctldev->desc->confops;
@@ -205,19 +217,6 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
 }
 EXPORT_SYMBOL(pin_config_group_set);
 
-int pinconf_check_ops(struct pinctrl_dev *pctldev)
-{
-	const struct pinconf_ops *ops = pctldev->desc->confops;
-
-	/* We must be able to read out pin status */
-	if (!ops->pin_config_get && !ops->pin_config_group_get)
-		return -EINVAL;
-	/* We have to be able to config the pins in SOME way */
-	if (!ops->pin_config_set && !ops->pin_config_group_set)
-		return -EINVAL;
-	return 0;
-}
-
 #ifdef CONFIG_DEBUG_FS
 
 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index 006b77f..1d6ea9d 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -14,12 +14,9 @@
 #ifdef CONFIG_PINCONF
 
 int pinconf_check_ops(struct pinctrl_dev *pctldev);
+
 void pinconf_init_device_debugfs(struct dentry *devroot,
 				 struct pinctrl_dev *pctldev);
-int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long *config);
-int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config);
 
 #else
 
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index 69fb707..b90c011 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -22,7 +22,7 @@
 #include <linux/gpio.h>
 #include <linux/list.h>
 #include <linux/slab.h>
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
 #include <mach/gpio-u300.h>
 
 /*
@@ -360,14 +360,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset)
 	 */
 	int gpio = chip->base + offset;
 
-	return pinmux_request_gpio(gpio);
+	return pinctrl_request_gpio(gpio);
 }
 
 static void u300_gpio_free(struct gpio_chip *chip, unsigned offset)
 {
 	int gpio = chip->base + offset;
 
-	pinmux_free_gpio(gpio);
+	pinctrl_free_gpio(gpio);
 }
 
 static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
 	list_for_each_safe(p, n, &gpio->port_list) {
 		port = list_entry(p, struct u300_gpio_port, node);
 		list_del(&port->node);
-		free_irq(port->irq, port);
 		kfree(port);
 	}
 }
@@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
 		goto err_no_chip;
 	}
 
+	/* Spawn pin controller device as child of the GPIO, pass gpio chip */
+	plat->pinctrl_device->dev.platform_data = &gpio->chip;
+	err = platform_device_register(plat->pinctrl_device);
+	if (err)
+		goto err_no_pinctrl;
+
 	platform_set_drvdata(pdev, gpio);
 
 	return 0;
 
+err_no_pinctrl:
+	err = gpiochip_remove(&gpio->chip);
 err_no_chip:
 err_no_port:
 	u300_gpio_free_ports(gpio);
@@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = {
 	.remove		= __exit_p(u300_gpio_remove),
 };
 
-
 static int __init u300_gpio_init(void)
 {
 	return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c
new file mode 100644
index 0000000..2cfed55
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mmp2.c
@@ -0,0 +1,722 @@
+/*
+ *  linux/drivers/pinctrl/pinmux-mmp2.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "pinctrl-pxa3xx.h"
+
+#define MMP2_DS_MASK		0x1800
+#define MMP2_DS_SHIFT		11
+#define MMP2_SLEEP_MASK		0x38
+#define MMP2_SLEEP_SELECT	(1 << 9)
+#define MMP2_SLEEP_DATA		(1 << 8)
+#define MMP2_SLEEP_DIR		(1 << 7)
+
+#define MFPR_MMP2(a, r, f0, f1, f2, f3, f4, f5, f6, f7)		\
+	{							\
+		.name = #a,					\
+		.pin = a,					\
+		.mfpr = r,					\
+		.func = {					\
+			MMP2_MUX_##f0,				\
+			MMP2_MUX_##f1,				\
+			MMP2_MUX_##f2,				\
+			MMP2_MUX_##f3,				\
+			MMP2_MUX_##f4,				\
+			MMP2_MUX_##f5,				\
+			MMP2_MUX_##f6,				\
+			MMP2_MUX_##f7,				\
+		},						\
+	}
+
+#define GRP_MMP2(a, m, p)		\
+	{ .name = a, .mux = MMP2_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+/* 174 pins */
+enum mmp2_pin_list {
+	/* 0~168: GPIO0~GPIO168 */
+	TWSI4_SCL = 169,
+	TWSI4_SDA, /* 170 */
+	G_CLKREQ,
+	VCXO_REQ,
+	VCXO_OUT,
+};
+
+enum mmp2_mux {
+	/* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
+	MMP2_MUX_GPIO = 0,
+	MMP2_MUX_G_CLKREQ,
+	MMP2_MUX_VCXO_REQ,
+	MMP2_MUX_VCXO_OUT,
+	MMP2_MUX_KP_MK,
+	MMP2_MUX_KP_DK,
+	MMP2_MUX_CCIC1,
+	MMP2_MUX_CCIC2,
+	MMP2_MUX_SPI,
+	MMP2_MUX_SSPA2,
+	MMP2_MUX_ROT,
+	MMP2_MUX_I2S,
+	MMP2_MUX_TB,
+	MMP2_MUX_CAM2,
+	MMP2_MUX_HDMI,
+	MMP2_MUX_TWSI2,
+	MMP2_MUX_TWSI3,
+	MMP2_MUX_TWSI4,
+	MMP2_MUX_TWSI5,
+	MMP2_MUX_TWSI6,
+	MMP2_MUX_UART1,
+	MMP2_MUX_UART2,
+	MMP2_MUX_UART3,
+	MMP2_MUX_UART4,
+	MMP2_MUX_SSP1_RX,
+	MMP2_MUX_SSP1_FRM,
+	MMP2_MUX_SSP1_TXRX,
+	MMP2_MUX_SSP2_RX,
+	MMP2_MUX_SSP2_FRM,
+	MMP2_MUX_SSP1,
+	MMP2_MUX_SSP2,
+	MMP2_MUX_SSP3,
+	MMP2_MUX_SSP4,
+	MMP2_MUX_MMC1,
+	MMP2_MUX_MMC2,
+	MMP2_MUX_MMC3,
+	MMP2_MUX_MMC4,
+	MMP2_MUX_ULPI,
+	MMP2_MUX_AC,
+	MMP2_MUX_CA,
+	MMP2_MUX_PWM,
+	MMP2_MUX_USIM,
+	MMP2_MUX_TIPU,
+	MMP2_MUX_PLL,
+	MMP2_MUX_NAND,
+	MMP2_MUX_FSIC,
+	MMP2_MUX_SLEEP_IND,
+	MMP2_MUX_EXT_DMA,
+	MMP2_MUX_ONE_WIRE,
+	MMP2_MUX_LCD,
+	MMP2_MUX_SMC,
+	MMP2_MUX_SMC_INT,
+	MMP2_MUX_MSP,
+	MMP2_MUX_G_CLKOUT,
+	MMP2_MUX_32K_CLKOUT,
+	MMP2_MUX_PRI_JTAG,
+	MMP2_MUX_AAS_JTAG,
+	MMP2_MUX_AAS_GPIO,
+	MMP2_MUX_AAS_SPI,
+	MMP2_MUX_AAS_TWSI,
+	MMP2_MUX_AAS_DEU_EX,
+	MMP2_MUX_NONE = 0xffff,
+};
+
+static struct pinctrl_pin_desc mmp2_pads[] = {
+	/*
+	 * The name indicates function 0 of this pin.
+	 * After reset, function 0 is the default function of pin.
+	 */
+	PINCTRL_PIN(GPIO0, "GPIO0"),
+	PINCTRL_PIN(GPIO1, "GPIO1"),
+	PINCTRL_PIN(GPIO2, "GPIO2"),
+	PINCTRL_PIN(GPIO3, "GPIO3"),
+	PINCTRL_PIN(GPIO4, "GPIO4"),
+	PINCTRL_PIN(GPIO5, "GPIO5"),
+	PINCTRL_PIN(GPIO6, "GPIO6"),
+	PINCTRL_PIN(GPIO7, "GPIO7"),
+	PINCTRL_PIN(GPIO8, "GPIO8"),
+	PINCTRL_PIN(GPIO9, "GPIO9"),
+	PINCTRL_PIN(GPIO10, "GPIO10"),
+	PINCTRL_PIN(GPIO11, "GPIO11"),
+	PINCTRL_PIN(GPIO12, "GPIO12"),
+	PINCTRL_PIN(GPIO13, "GPIO13"),
+	PINCTRL_PIN(GPIO14, "GPIO14"),
+	PINCTRL_PIN(GPIO15, "GPIO15"),
+	PINCTRL_PIN(GPIO16, "GPIO16"),
+	PINCTRL_PIN(GPIO17, "GPIO17"),
+	PINCTRL_PIN(GPIO18, "GPIO18"),
+	PINCTRL_PIN(GPIO19, "GPIO19"),
+	PINCTRL_PIN(GPIO20, "GPIO20"),
+	PINCTRL_PIN(GPIO21, "GPIO21"),
+	PINCTRL_PIN(GPIO22, "GPIO22"),
+	PINCTRL_PIN(GPIO23, "GPIO23"),
+	PINCTRL_PIN(GPIO24, "GPIO24"),
+	PINCTRL_PIN(GPIO25, "GPIO25"),
+	PINCTRL_PIN(GPIO26, "GPIO26"),
+	PINCTRL_PIN(GPIO27, "GPIO27"),
+	PINCTRL_PIN(GPIO28, "GPIO28"),
+	PINCTRL_PIN(GPIO29, "GPIO29"),
+	PINCTRL_PIN(GPIO30, "GPIO30"),
+	PINCTRL_PIN(GPIO31, "GPIO31"),
+	PINCTRL_PIN(GPIO32, "GPIO32"),
+	PINCTRL_PIN(GPIO33, "GPIO33"),
+	PINCTRL_PIN(GPIO34, "GPIO34"),
+	PINCTRL_PIN(GPIO35, "GPIO35"),
+	PINCTRL_PIN(GPIO36, "GPIO36"),
+	PINCTRL_PIN(GPIO37, "GPIO37"),
+	PINCTRL_PIN(GPIO38, "GPIO38"),
+	PINCTRL_PIN(GPIO39, "GPIO39"),
+	PINCTRL_PIN(GPIO40, "GPIO40"),
+	PINCTRL_PIN(GPIO41, "GPIO41"),
+	PINCTRL_PIN(GPIO42, "GPIO42"),
+	PINCTRL_PIN(GPIO43, "GPIO43"),
+	PINCTRL_PIN(GPIO44, "GPIO44"),
+	PINCTRL_PIN(GPIO45, "GPIO45"),
+	PINCTRL_PIN(GPIO46, "GPIO46"),
+	PINCTRL_PIN(GPIO47, "GPIO47"),
+	PINCTRL_PIN(GPIO48, "GPIO48"),
+	PINCTRL_PIN(GPIO49, "GPIO49"),
+	PINCTRL_PIN(GPIO50, "GPIO50"),
+	PINCTRL_PIN(GPIO51, "GPIO51"),
+	PINCTRL_PIN(GPIO52, "GPIO52"),
+	PINCTRL_PIN(GPIO53, "GPIO53"),
+	PINCTRL_PIN(GPIO54, "GPIO54"),
+	PINCTRL_PIN(GPIO55, "GPIO55"),
+	PINCTRL_PIN(GPIO56, "GPIO56"),
+	PINCTRL_PIN(GPIO57, "GPIO57"),
+	PINCTRL_PIN(GPIO58, "GPIO58"),
+	PINCTRL_PIN(GPIO59, "GPIO59"),
+	PINCTRL_PIN(GPIO60, "GPIO60"),
+	PINCTRL_PIN(GPIO61, "GPIO61"),
+	PINCTRL_PIN(GPIO62, "GPIO62"),
+	PINCTRL_PIN(GPIO63, "GPIO63"),
+	PINCTRL_PIN(GPIO64, "GPIO64"),
+	PINCTRL_PIN(GPIO65, "GPIO65"),
+	PINCTRL_PIN(GPIO66, "GPIO66"),
+	PINCTRL_PIN(GPIO67, "GPIO67"),
+	PINCTRL_PIN(GPIO68, "GPIO68"),
+	PINCTRL_PIN(GPIO69, "GPIO69"),
+	PINCTRL_PIN(GPIO70, "GPIO70"),
+	PINCTRL_PIN(GPIO71, "GPIO71"),
+	PINCTRL_PIN(GPIO72, "GPIO72"),
+	PINCTRL_PIN(GPIO73, "GPIO73"),
+	PINCTRL_PIN(GPIO74, "GPIO74"),
+	PINCTRL_PIN(GPIO75, "GPIO75"),
+	PINCTRL_PIN(GPIO76, "GPIO76"),
+	PINCTRL_PIN(GPIO77, "GPIO77"),
+	PINCTRL_PIN(GPIO78, "GPIO78"),
+	PINCTRL_PIN(GPIO79, "GPIO79"),
+	PINCTRL_PIN(GPIO80, "GPIO80"),
+	PINCTRL_PIN(GPIO81, "GPIO81"),
+	PINCTRL_PIN(GPIO82, "GPIO82"),
+	PINCTRL_PIN(GPIO83, "GPIO83"),
+	PINCTRL_PIN(GPIO84, "GPIO84"),
+	PINCTRL_PIN(GPIO85, "GPIO85"),
+	PINCTRL_PIN(GPIO86, "GPIO86"),
+	PINCTRL_PIN(GPIO87, "GPIO87"),
+	PINCTRL_PIN(GPIO88, "GPIO88"),
+	PINCTRL_PIN(GPIO89, "GPIO89"),
+	PINCTRL_PIN(GPIO90, "GPIO90"),
+	PINCTRL_PIN(GPIO91, "GPIO91"),
+	PINCTRL_PIN(GPIO92, "GPIO92"),
+	PINCTRL_PIN(GPIO93, "GPIO93"),
+	PINCTRL_PIN(GPIO94, "GPIO94"),
+	PINCTRL_PIN(GPIO95, "GPIO95"),
+	PINCTRL_PIN(GPIO96, "GPIO96"),
+	PINCTRL_PIN(GPIO97, "GPIO97"),
+	PINCTRL_PIN(GPIO98, "GPIO98"),
+	PINCTRL_PIN(GPIO99, "GPIO99"),
+	PINCTRL_PIN(GPIO100, "GPIO100"),
+	PINCTRL_PIN(GPIO101, "GPIO101"),
+	PINCTRL_PIN(GPIO102, "GPIO102"),
+	PINCTRL_PIN(GPIO103, "GPIO103"),
+	PINCTRL_PIN(GPIO104, "GPIO104"),
+	PINCTRL_PIN(GPIO105, "GPIO105"),
+	PINCTRL_PIN(GPIO106, "GPIO106"),
+	PINCTRL_PIN(GPIO107, "GPIO107"),
+	PINCTRL_PIN(GPIO108, "GPIO108"),
+	PINCTRL_PIN(GPIO109, "GPIO109"),
+	PINCTRL_PIN(GPIO110, "GPIO110"),
+	PINCTRL_PIN(GPIO111, "GPIO111"),
+	PINCTRL_PIN(GPIO112, "GPIO112"),
+	PINCTRL_PIN(GPIO113, "GPIO113"),
+	PINCTRL_PIN(GPIO114, "GPIO114"),
+	PINCTRL_PIN(GPIO115, "GPIO115"),
+	PINCTRL_PIN(GPIO116, "GPIO116"),
+	PINCTRL_PIN(GPIO117, "GPIO117"),
+	PINCTRL_PIN(GPIO118, "GPIO118"),
+	PINCTRL_PIN(GPIO119, "GPIO119"),
+	PINCTRL_PIN(GPIO120, "GPIO120"),
+	PINCTRL_PIN(GPIO121, "GPIO121"),
+	PINCTRL_PIN(GPIO122, "GPIO122"),
+	PINCTRL_PIN(GPIO123, "GPIO123"),
+	PINCTRL_PIN(GPIO124, "GPIO124"),
+	PINCTRL_PIN(GPIO125, "GPIO125"),
+	PINCTRL_PIN(GPIO126, "GPIO126"),
+	PINCTRL_PIN(GPIO127, "GPIO127"),
+	PINCTRL_PIN(GPIO128, "GPIO128"),
+	PINCTRL_PIN(GPIO129, "GPIO129"),
+	PINCTRL_PIN(GPIO130, "GPIO130"),
+	PINCTRL_PIN(GPIO131, "GPIO131"),
+	PINCTRL_PIN(GPIO132, "GPIO132"),
+	PINCTRL_PIN(GPIO133, "GPIO133"),
+	PINCTRL_PIN(GPIO134, "GPIO134"),
+	PINCTRL_PIN(GPIO135, "GPIO135"),
+	PINCTRL_PIN(GPIO136, "GPIO136"),
+	PINCTRL_PIN(GPIO137, "GPIO137"),
+	PINCTRL_PIN(GPIO138, "GPIO138"),
+	PINCTRL_PIN(GPIO139, "GPIO139"),
+	PINCTRL_PIN(GPIO140, "GPIO140"),
+	PINCTRL_PIN(GPIO141, "GPIO141"),
+	PINCTRL_PIN(GPIO142, "GPIO142"),
+	PINCTRL_PIN(GPIO143, "GPIO143"),
+	PINCTRL_PIN(GPIO144, "GPIO144"),
+	PINCTRL_PIN(GPIO145, "GPIO145"),
+	PINCTRL_PIN(GPIO146, "GPIO146"),
+	PINCTRL_PIN(GPIO147, "GPIO147"),
+	PINCTRL_PIN(GPIO148, "GPIO148"),
+	PINCTRL_PIN(GPIO149, "GPIO149"),
+	PINCTRL_PIN(GPIO150, "GPIO150"),
+	PINCTRL_PIN(GPIO151, "GPIO151"),
+	PINCTRL_PIN(GPIO152, "GPIO152"),
+	PINCTRL_PIN(GPIO153, "GPIO153"),
+	PINCTRL_PIN(GPIO154, "GPIO154"),
+	PINCTRL_PIN(GPIO155, "GPIO155"),
+	PINCTRL_PIN(GPIO156, "GPIO156"),
+	PINCTRL_PIN(GPIO157, "GPIO157"),
+	PINCTRL_PIN(GPIO158, "GPIO158"),
+	PINCTRL_PIN(GPIO159, "GPIO159"),
+	PINCTRL_PIN(GPIO160, "GPIO160"),
+	PINCTRL_PIN(GPIO161, "GPIO161"),
+	PINCTRL_PIN(GPIO162, "GPIO162"),
+	PINCTRL_PIN(GPIO163, "GPIO163"),
+	PINCTRL_PIN(GPIO164, "GPIO164"),
+	PINCTRL_PIN(GPIO165, "GPIO165"),
+	PINCTRL_PIN(GPIO166, "GPIO166"),
+	PINCTRL_PIN(GPIO167, "GPIO167"),
+	PINCTRL_PIN(GPIO168, "GPIO168"),
+	PINCTRL_PIN(TWSI4_SCL, "TWSI4_SCL"),
+	PINCTRL_PIN(TWSI4_SDA, "TWSI4_SDA"),
+	PINCTRL_PIN(G_CLKREQ, "G_CLKREQ"),
+	PINCTRL_PIN(VCXO_REQ, "VCXO_REQ"),
+	PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"),
+};
+
+struct pxa3xx_mfp_pin mmp2_mfp[] = {
+	/*       pin         offs   f0        f1          f2          f3          f4          f5        f6        f7  */
+	MFPR_MMP2(GPIO0,     0x054, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO1,     0x058, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO2,     0x05C, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO3,     0x060, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO4,     0x064, GPIO,     KP_MK,      NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO5,     0x068, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO6,     0x06C, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO7,     0x070, GPIO,     KP_MK,      NONE,       SPI,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO8,     0x074, GPIO,     KP_MK,      NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO9,     0x078, GPIO,     KP_MK,      NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO10,    0x07C, GPIO,     KP_MK,      NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO11,    0x080, GPIO,     KP_MK,      NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO12,    0x084, GPIO,     KP_MK,      NONE,       CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO13,    0x088, GPIO,     KP_MK,      NONE,       CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO14,    0x08C, GPIO,     KP_MK,      NONE,       CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO15,    0x090, GPIO,     KP_MK,      KP_DK,      CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO16,    0x094, GPIO,     KP_DK,      ROT,        CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO17,    0x098, GPIO,     KP_DK,      ROT,        CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO18,    0x09C, GPIO,     KP_DK,      ROT,        CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO19,    0x0A0, GPIO,     KP_DK,      ROT,        CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO20,    0x0A4, GPIO,     KP_DK,      TB,         CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO21,    0x0A8, GPIO,     KP_DK,      TB,         CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO22,    0x0AC, GPIO,     KP_DK,      TB,         CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO23,    0x0B0, GPIO,     KP_DK,      TB,         CCIC1,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO24,    0x0B4, GPIO,     I2S,        VCXO_OUT,   NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO25,    0x0B8, GPIO,     I2S,        HDMI,       SSPA2,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO26,    0x0BC, GPIO,     I2S,        HDMI,       SSPA2,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO27,    0x0C0, GPIO,     I2S,        HDMI,       SSPA2,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO28,    0x0C4, GPIO,     I2S,        NONE,       SSPA2,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO29,    0x0C8, GPIO,     UART1,      KP_MK,      NONE,       NONE,       NONE,     AAS_SPI,  NONE),
+	MFPR_MMP2(GPIO30,    0x0CC, GPIO,     UART1,      KP_MK,      NONE,       NONE,       NONE,     AAS_SPI,  NONE),
+	MFPR_MMP2(GPIO31,    0x0D0, GPIO,     UART1,      KP_MK,      NONE,       NONE,       NONE,     AAS_SPI,  NONE),
+	MFPR_MMP2(GPIO32,    0x0D4, GPIO,     UART1,      KP_MK,      NONE,       NONE,       NONE,     AAS_SPI,  NONE),
+	MFPR_MMP2(GPIO33,    0x0D8, GPIO,     SSPA2,      I2S,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO34,    0x0DC, GPIO,     SSPA2,      I2S,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO35,    0x0E0, GPIO,     SSPA2,      I2S,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO36,    0x0E4, GPIO,     SSPA2,      I2S,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO37,    0x0E8, GPIO,     MMC2,       SSP1,       TWSI2,      UART2,      UART3,    AAS_SPI,  AAS_TWSI),
+	MFPR_MMP2(GPIO38,    0x0EC, GPIO,     MMC2,       SSP1,       TWSI2,      UART2,      UART3,    AAS_SPI,  AAS_TWSI),
+	MFPR_MMP2(GPIO39,    0x0F0, GPIO,     MMC2,       SSP1,       TWSI2,      UART2,      UART3,    AAS_SPI,  AAS_TWSI),
+	MFPR_MMP2(GPIO40,    0x0F4, GPIO,     MMC2,       SSP1,       TWSI2,      UART2,      UART3,    AAS_SPI,  AAS_TWSI),
+	MFPR_MMP2(GPIO41,    0x0F8, GPIO,     MMC2,       TWSI5,      NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO42,    0x0FC, GPIO,     MMC2,       TWSI5,      NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO43,    0x100, GPIO,     TWSI2,      UART4,      SSP1,       UART2,      UART3,    NONE,     AAS_TWSI),
+	MFPR_MMP2(GPIO44,    0x104, GPIO,     TWSI2,      UART4,      SSP1,       UART2,      UART3,    NONE,     AAS_TWSI),
+	MFPR_MMP2(GPIO45,    0x108, GPIO,     UART1,      UART4,      SSP1,       UART2,      UART3,    NONE,     NONE),
+	MFPR_MMP2(GPIO46,    0x10C, GPIO,     UART1,      UART4,      SSP1,       UART2,      UART3,    NONE,     NONE),
+	MFPR_MMP2(GPIO47,    0x110, GPIO,     UART2,      SSP2,       TWSI6,      CAM2,       AAS_SPI,  AAS_GPIO, NONE),
+	MFPR_MMP2(GPIO48,    0x114, GPIO,     UART2,      SSP2,       TWSI6,      CAM2,       AAS_SPI,  AAS_GPIO, NONE),
+	MFPR_MMP2(GPIO49,    0x118, GPIO,     UART2,      SSP2,       PWM,        CCIC2,      AAS_SPI,  NONE,     NONE),
+	MFPR_MMP2(GPIO50,    0x11C, GPIO,     UART2,      SSP2,       PWM,        CCIC2,      AAS_SPI,  NONE,     NONE),
+	MFPR_MMP2(GPIO51,    0x120, GPIO,     UART3,      ROT,        AAS_GPIO,   PWM,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO52,    0x124, GPIO,     UART3,      ROT,        AAS_GPIO,   PWM,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO53,    0x128, GPIO,     UART3,      TWSI2,      VCXO_REQ,   NONE,       PWM,      NONE,     AAS_TWSI),
+	MFPR_MMP2(GPIO54,    0x12C, GPIO,     UART3,      TWSI2,      VCXO_OUT,   HDMI,       PWM,      NONE,     AAS_TWSI),
+	MFPR_MMP2(GPIO55,    0x130, GPIO,     SSP2,       SSP1,       UART2,      ROT,        TWSI2,    SSP3,     AAS_TWSI),
+	MFPR_MMP2(GPIO56,    0x134, GPIO,     SSP2,       SSP1,       UART2,      ROT,        TWSI2,    KP_DK,    AAS_TWSI),
+	MFPR_MMP2(GPIO57,    0x138, GPIO,     SSP2_RX,    SSP1_TXRX,  SSP2_FRM,   SSP1_RX,    VCXO_REQ, KP_DK,    NONE),
+	MFPR_MMP2(GPIO58,    0x13C, GPIO,     SSP2,       SSP1_RX,    SSP1_FRM,   SSP1_TXRX,  VCXO_REQ, KP_DK,    NONE),
+	MFPR_MMP2(GPIO59,    0x280, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      UART3,    UART4,    NONE),
+	MFPR_MMP2(GPIO60,    0x284, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      UART3,    UART4,    NONE),
+	MFPR_MMP2(GPIO61,    0x288, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      UART3,    HDMI,     NONE),
+	MFPR_MMP2(GPIO62,    0x28C, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      UART3,    NONE,     NONE),
+	MFPR_MMP2(GPIO63,    0x290, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      UART4,    NONE),
+	MFPR_MMP2(GPIO64,    0x294, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      UART4,    NONE),
+	MFPR_MMP2(GPIO65,    0x298, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      UART4,    NONE),
+	MFPR_MMP2(GPIO66,    0x29C, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      UART4,    NONE),
+	MFPR_MMP2(GPIO67,    0x2A0, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      NONE,     NONE),
+	MFPR_MMP2(GPIO68,    0x2A4, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      LCD,      NONE),
+	MFPR_MMP2(GPIO69,    0x2A8, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      NONE,     LCD,      NONE),
+	MFPR_MMP2(GPIO70,    0x2AC, GPIO,     CCIC1,      ULPI,       MMC3,       CCIC2,      MSP,      LCD,      NONE),
+	MFPR_MMP2(GPIO71,    0x2B0, GPIO,     TWSI3,      NONE,       PWM,        NONE,       NONE,     LCD,      AAS_TWSI),
+	MFPR_MMP2(GPIO72,    0x2B4, GPIO,     TWSI3,      HDMI,       PWM,        NONE,       NONE,     LCD,      AAS_TWSI),
+	MFPR_MMP2(GPIO73,    0x2B8, GPIO,     VCXO_REQ,   32K_CLKOUT, PWM,        VCXO_OUT,   NONE,     LCD,      NONE),
+	MFPR_MMP2(GPIO74,    0x170, GPIO,     LCD,        SMC,        MMC4,       SSP3,       UART2,    UART4,    TIPU),
+	MFPR_MMP2(GPIO75,    0x174, GPIO,     LCD,        SMC,        MMC4,       SSP3,       UART2,    UART4,    TIPU),
+	MFPR_MMP2(GPIO76,    0x178, GPIO,     LCD,        SMC,        MMC4,       SSP3,       UART2,    UART4,    TIPU),
+	MFPR_MMP2(GPIO77,    0x17C, GPIO,     LCD,        SMC,        MMC4,       SSP3,       UART2,    UART4,    TIPU),
+	MFPR_MMP2(GPIO78,    0x180, GPIO,     LCD,        HDMI,       MMC4,       NONE,       SSP4,     AAS_SPI,  TIPU),
+	MFPR_MMP2(GPIO79,    0x184, GPIO,     LCD,        AAS_GPIO,   MMC4,       NONE,       SSP4,     AAS_SPI,  TIPU),
+	MFPR_MMP2(GPIO80,    0x188, GPIO,     LCD,        AAS_GPIO,   MMC4,       NONE,       SSP4,     AAS_SPI,  TIPU),
+	MFPR_MMP2(GPIO81,    0x18C, GPIO,     LCD,        AAS_GPIO,   MMC4,       NONE,       SSP4,     AAS_SPI,  TIPU),
+	MFPR_MMP2(GPIO82,    0x190, GPIO,     LCD,        NONE,       MMC4,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO83,    0x194, GPIO,     LCD,        NONE,       MMC4,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO84,    0x198, GPIO,     LCD,        SMC,        MMC2,       NONE,       TWSI5,    AAS_TWSI, TIPU),
+	MFPR_MMP2(GPIO85,    0x19C, GPIO,     LCD,        SMC,        MMC2,       NONE,       TWSI5,    AAS_TWSI, TIPU),
+	MFPR_MMP2(GPIO86,    0x1A0, GPIO,     LCD,        SMC,        MMC2,       NONE,       TWSI6,    CCIC2,    TIPU),
+	MFPR_MMP2(GPIO87,    0x1A4, GPIO,     LCD,        SMC,        MMC2,       NONE,       TWSI6,    CCIC2,    TIPU),
+	MFPR_MMP2(GPIO88,    0x1A8, GPIO,     LCD,        AAS_GPIO,   MMC2,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO89,    0x1AC, GPIO,     LCD,        AAS_GPIO,   MMC2,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO90,    0x1B0, GPIO,     LCD,        AAS_GPIO,   MMC2,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO91,    0x1B4, GPIO,     LCD,        AAS_GPIO,   MMC2,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO92,    0x1B8, GPIO,     LCD,        AAS_GPIO,   MMC2,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO93,    0x1BC, GPIO,     LCD,        AAS_GPIO,   MMC2,       NONE,       NONE,     CCIC2,    TIPU),
+	MFPR_MMP2(GPIO94,    0x1C0, GPIO,     LCD,        AAS_GPIO,   SPI,        NONE,       AAS_SPI,  CCIC2,    TIPU),
+	MFPR_MMP2(GPIO95,    0x1C4, GPIO,     LCD,        TWSI3,      SPI,        AAS_DEU_EX, AAS_SPI,  CCIC2,    TIPU),
+	MFPR_MMP2(GPIO96,    0x1C8, GPIO,     LCD,        TWSI3,      SPI,        AAS_DEU_EX, AAS_SPI,  NONE,     TIPU),
+	MFPR_MMP2(GPIO97,    0x1CC, GPIO,     LCD,        TWSI6,      SPI,        AAS_DEU_EX, AAS_SPI,  NONE,     TIPU),
+	MFPR_MMP2(GPIO98,    0x1D0, GPIO,     LCD,        TWSI6,      SPI,        ONE_WIRE,   NONE,     NONE,     TIPU),
+	MFPR_MMP2(GPIO99,    0x1D4, GPIO,     LCD,        SMC,        SPI,        TWSI5,      NONE,     NONE,     TIPU),
+	MFPR_MMP2(GPIO100,   0x1D8, GPIO,     LCD,        SMC,        SPI,        TWSI5,      NONE,     NONE,     TIPU),
+	MFPR_MMP2(GPIO101,   0x1DC, GPIO,     LCD,        SMC,        SPI,        NONE,       NONE,     NONE,     TIPU),
+	MFPR_MMP2(GPIO102,   0x000, USIM,     GPIO,       FSIC,       KP_DK,      LCD,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO103,   0x004, USIM,     GPIO,       FSIC,       KP_DK,      LCD,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO104,   0x1FC, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO105,   0x1F8, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO106,   0x1F4, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO107,   0x1F0, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO108,   0x21C, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO109,   0x218, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO110,   0x214, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO111,   0x200, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO112,   0x244, NAND,     GPIO,       MMC3,       SMC,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO113,   0x25C, SMC,      GPIO,       EXT_DMA,    MMC3,       SMC,        HDMI,     NONE,     NONE),
+	MFPR_MMP2(GPIO114,   0x164, G_CLKOUT, 32K_CLKOUT, HDMI,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO115,   0x260, GPIO,     NONE,       AC,         UART4,      UART3,      SSP1,     NONE,     NONE),
+	MFPR_MMP2(GPIO116,   0x264, GPIO,     NONE,       AC,         UART4,      UART3,      SSP1,     NONE,     NONE),
+	MFPR_MMP2(GPIO117,   0x268, GPIO,     NONE,       AC,         UART4,      UART3,      SSP1,     NONE,     NONE),
+	MFPR_MMP2(GPIO118,   0x26C, GPIO,     NONE,       AC,         UART4,      UART3,      SSP1,     NONE,     NONE),
+	MFPR_MMP2(GPIO119,   0x270, GPIO,     NONE,       CA,         SSP3,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO120,   0x274, GPIO,     NONE,       CA,         SSP3,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO121,   0x278, GPIO,     NONE,       CA,         SSP3,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO122,   0x27C, GPIO,     NONE,       CA,         SSP3,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO123,   0x148, GPIO,     SLEEP_IND,  ONE_WIRE,   32K_CLKOUT, NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO124,   0x00C, GPIO,     MMC1,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO125,   0x010, GPIO,     MMC1,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO126,   0x014, GPIO,     MMC1,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO127,   0x018, GPIO,     NONE,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO128,   0x01C, GPIO,     NONE,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO129,   0x020, GPIO,     MMC1,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO130,   0x024, GPIO,     MMC1,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO131,   0x028, GPIO,     MMC1,       NONE,       MSP,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO132,   0x02C, GPIO,     MMC1,       PRI_JTAG,   MSP,        SSP3,       AAS_JTAG, NONE,     NONE),
+	MFPR_MMP2(GPIO133,   0x030, GPIO,     MMC1,       PRI_JTAG,   MSP,        SSP3,       AAS_JTAG, NONE,     NONE),
+	MFPR_MMP2(GPIO134,   0x034, GPIO,     MMC1,       PRI_JTAG,   MSP,        SSP3,       AAS_JTAG, NONE,     NONE),
+	MFPR_MMP2(GPIO135,   0x038, GPIO,     NONE,       LCD,        MMC3,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO136,   0x03C, GPIO,     MMC1,       PRI_JTAG,   MSP,        SSP3,       AAS_JTAG, NONE,     NONE),
+	MFPR_MMP2(GPIO137,   0x040, GPIO,     HDMI,       LCD,        MSP,        NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO138,   0x044, GPIO,     NONE,       LCD,        MMC3,       SMC,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO139,   0x048, GPIO,     MMC1,       PRI_JTAG,   MSP,        NONE,       AAS_JTAG, NONE,     NONE),
+	MFPR_MMP2(GPIO140,   0x04C, GPIO,     MMC1,       LCD,        NONE,       NONE,       UART2,    UART1,    NONE),
+	MFPR_MMP2(GPIO141,   0x050, GPIO,     MMC1,       LCD,        NONE,       NONE,       UART2,    UART1,    NONE),
+	MFPR_MMP2(GPIO142,   0x008, USIM,     GPIO,       FSIC,       KP_DK,      NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO143,   0x220, NAND,     GPIO,       SMC,        NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO144,   0x224, NAND,     GPIO,       SMC_INT,    SMC,        NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO145,   0x228, SMC,      GPIO,       NONE,       NONE,       SMC,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO146,   0x22C, SMC,      GPIO,       NONE,       NONE,       SMC,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO147,   0x230, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO148,   0x234, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO149,   0x238, NAND,     GPIO,       NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO150,   0x23C, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO151,   0x240, SMC,      GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO152,   0x248, SMC,      GPIO,       NONE,       NONE,       SMC,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO153,   0x24C, SMC,      GPIO,       NONE,       NONE,       SMC,        NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO154,   0x254, SMC_INT,  GPIO,       SMC,        NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO155,   0x258, EXT_DMA,  GPIO,       SMC,        NONE,       EXT_DMA,    NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO156,   0x14C, PRI_JTAG, GPIO,       PWM,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO157,   0x150, PRI_JTAG, GPIO,       PWM,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO158,   0x154, PRI_JTAG, GPIO,       PWM,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO159,   0x158, PRI_JTAG, GPIO,       PWM,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO160,   0x250, NAND,     GPIO,       SMC,        NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO161,   0x210, NAND,     GPIO,       NONE,       NONE,       NAND,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO162,   0x20C, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO163,   0x208, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO164,   0x204, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO165,   0x1EC, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO166,   0x1E8, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO167,   0x1E4, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(GPIO168,   0x1E0, NAND,     GPIO,       MMC3,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(TWSI4_SCL, 0x2BC, TWSI4,    LCD,        NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(TWSI4_SDA, 0x2C0, TWSI4,    LCD,        NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(G_CLKREQ,  0x160, G_CLKREQ, ONE_WIRE,   NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(VCXO_REQ,  0x168, VCXO_REQ, ONE_WIRE,   PLL,        NONE,       NONE,       NONE,     NONE,     NONE),
+	MFPR_MMP2(VCXO_OUT,  0x16C, VCXO_OUT, 32K_CLKOUT, NONE,       NONE,       NONE,       NONE,     NONE,     NONE),
+};
+
+static const unsigned mmp2_uart1_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32};
+static const unsigned mmp2_uart1_pin2[] = {GPIO45, GPIO46};
+static const unsigned mmp2_uart1_pin3[] = {GPIO140, GPIO141};
+static const unsigned mmp2_uart2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
+static const unsigned mmp2_uart2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_uart2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned mmp2_uart2_pin4[] = {GPIO74, GPIO75, GPIO76, GPIO77};
+static const unsigned mmp2_uart2_pin5[] = {GPIO55, GPIO56};
+static const unsigned mmp2_uart2_pin6[] = {GPIO140, GPIO141};
+static const unsigned mmp2_uart3_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
+static const unsigned mmp2_uart3_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_uart3_pin3[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned mmp2_uart3_pin4[] = {GPIO59, GPIO60, GPIO61, GPIO62};
+static const unsigned mmp2_uart3_pin5[] = {GPIO115, GPIO116, GPIO117, GPIO118};
+static const unsigned mmp2_uart3_pin6[] = {GPIO51, GPIO52};
+static const unsigned mmp2_uart4_pin1[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_uart4_pin2[] = {GPIO63, GPIO64, GPIO65, GPIO66};
+static const unsigned mmp2_uart4_pin3[] = {GPIO74, GPIO75, GPIO76, GPIO77};
+static const unsigned mmp2_uart4_pin4[] = {GPIO115, GPIO116, GPIO117, GPIO118};
+static const unsigned mmp2_uart4_pin5[] = {GPIO59, GPIO60};
+static const unsigned mmp2_kpdk_pin1[] = {GPIO16, GPIO17, GPIO18, GPIO19};
+static const unsigned mmp2_kpdk_pin2[] = {GPIO16, GPIO17};
+static const unsigned mmp2_twsi2_pin1[] = {GPIO37, GPIO38};
+static const unsigned mmp2_twsi2_pin2[] = {GPIO39, GPIO40};
+static const unsigned mmp2_twsi2_pin3[] = {GPIO43, GPIO44};
+static const unsigned mmp2_twsi2_pin4[] = {GPIO53, GPIO54};
+static const unsigned mmp2_twsi2_pin5[] = {GPIO55, GPIO56};
+static const unsigned mmp2_twsi3_pin1[] = {GPIO71, GPIO72};
+static const unsigned mmp2_twsi3_pin2[] = {GPIO95, GPIO96};
+static const unsigned mmp2_twsi4_pin1[] = {TWSI4_SCL, TWSI4_SDA};
+static const unsigned mmp2_twsi5_pin1[] = {GPIO41, GPIO42};
+static const unsigned mmp2_twsi5_pin2[] = {GPIO84, GPIO85};
+static const unsigned mmp2_twsi5_pin3[] = {GPIO99, GPIO100};
+static const unsigned mmp2_twsi6_pin1[] = {GPIO47, GPIO48};
+static const unsigned mmp2_twsi6_pin2[] = {GPIO86, GPIO87};
+static const unsigned mmp2_twsi6_pin3[] = {GPIO97, GPIO98};
+static const unsigned mmp2_ccic1_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15,
+	GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23};
+static const unsigned mmp2_ccic1_pin2[] = {GPIO59, GPIO60, GPIO61, GPIO62,
+	GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
+static const unsigned mmp2_ccic2_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62,
+	GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
+static const unsigned mmp2_ccic2_pin2[] = {GPIO82, GPIO83, GPIO86, GPIO87,
+	GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95};
+static const unsigned mmp2_ulpi_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62,
+	GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
+static const unsigned mmp2_ro_pin1[] = {GPIO16, GPIO17};
+static const unsigned mmp2_ro_pin2[] = {GPIO18, GPIO19};
+static const unsigned mmp2_ro_pin3[] = {GPIO51, GPIO52};
+static const unsigned mmp2_ro_pin4[] = {GPIO55, GPIO56};
+static const unsigned mmp2_i2s_pin1[] = {GPIO24, GPIO25, GPIO26, GPIO27,
+	GPIO28};
+static const unsigned mmp2_i2s_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned mmp2_ssp1_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
+static const unsigned mmp2_ssp1_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_ssp1_pin3[] = {GPIO115, GPIO116, GPIO117, GPIO118};
+static const unsigned mmp2_ssp2_pin1[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned mmp2_ssp3_pin1[] = {GPIO119, GPIO120, GPIO121, GPIO122};
+static const unsigned mmp2_ssp3_pin2[] = {GPIO132, GPIO133, GPIO133, GPIO136};
+static const unsigned mmp2_sspa2_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28};
+static const unsigned mmp2_sspa2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned mmp2_mmc1_pin1[] = {GPIO131, GPIO132, GPIO133, GPIO134,
+	GPIO136, GPIO139, GPIO140, GPIO141};
+static const unsigned mmp2_mmc2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+	GPIO41, GPIO42};
+static const unsigned mmp2_mmc3_pin1[] = {GPIO111, GPIO112, GPIO151, GPIO162,
+	GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, GPIO168};
+
+static struct pxa3xx_pin_group mmp2_grps[] = {
+	GRP_MMP2("uart1 4p1", UART1, mmp2_uart1_pin1),
+	GRP_MMP2("uart1 2p2", UART1, mmp2_uart1_pin2),
+	GRP_MMP2("uart1 2p3", UART1, mmp2_uart1_pin3),
+	GRP_MMP2("uart2 4p1", UART2, mmp2_uart2_pin1),
+	GRP_MMP2("uart2 4p2", UART2, mmp2_uart2_pin2),
+	GRP_MMP2("uart2 4p3", UART2, mmp2_uart2_pin3),
+	GRP_MMP2("uart2 4p4", UART2, mmp2_uart2_pin4),
+	GRP_MMP2("uart2 2p5", UART2, mmp2_uart2_pin5),
+	GRP_MMP2("uart2 2p6", UART2, mmp2_uart2_pin6),
+	GRP_MMP2("uart3 4p1", UART3, mmp2_uart3_pin1),
+	GRP_MMP2("uart3 4p2", UART3, mmp2_uart3_pin2),
+	GRP_MMP2("uart3 4p3", UART3, mmp2_uart3_pin3),
+	GRP_MMP2("uart3 4p4", UART3, mmp2_uart3_pin4),
+	GRP_MMP2("uart3 4p5", UART3, mmp2_uart3_pin5),
+	GRP_MMP2("uart3 2p6", UART3, mmp2_uart3_pin6),
+	GRP_MMP2("uart4 4p1", UART4, mmp2_uart4_pin1),
+	GRP_MMP2("uart4 4p2", UART4, mmp2_uart4_pin2),
+	GRP_MMP2("uart4 4p3", UART4, mmp2_uart4_pin3),
+	GRP_MMP2("uart4 4p4", UART4, mmp2_uart4_pin4),
+	GRP_MMP2("uart4 2p5", UART4, mmp2_uart4_pin5),
+	GRP_MMP2("kpdk 4p1", KP_DK, mmp2_kpdk_pin1),
+	GRP_MMP2("kpdk 4p2", KP_DK, mmp2_kpdk_pin2),
+	GRP_MMP2("twsi2-1", TWSI2, mmp2_twsi2_pin1),
+	GRP_MMP2("twsi2-2", TWSI2, mmp2_twsi2_pin2),
+	GRP_MMP2("twsi2-3", TWSI2, mmp2_twsi2_pin3),
+	GRP_MMP2("twsi2-4", TWSI2, mmp2_twsi2_pin4),
+	GRP_MMP2("twsi2-5", TWSI2, mmp2_twsi2_pin5),
+	GRP_MMP2("twsi3-1", TWSI3, mmp2_twsi3_pin1),
+	GRP_MMP2("twsi3-2", TWSI3, mmp2_twsi3_pin2),
+	GRP_MMP2("twsi4", TWSI4, mmp2_twsi4_pin1),
+	GRP_MMP2("twsi5-1", TWSI5, mmp2_twsi5_pin1),
+	GRP_MMP2("twsi5-2", TWSI5, mmp2_twsi5_pin2),
+	GRP_MMP2("twsi5-3", TWSI5, mmp2_twsi5_pin3),
+	GRP_MMP2("twsi6-1", TWSI6, mmp2_twsi6_pin1),
+	GRP_MMP2("twsi6-2", TWSI6, mmp2_twsi6_pin2),
+	GRP_MMP2("twsi6-3", TWSI6, mmp2_twsi6_pin3),
+	GRP_MMP2("ccic1-1", CCIC1, mmp2_ccic1_pin1),
+	GRP_MMP2("ccic1-2", CCIC1, mmp2_ccic1_pin2),
+	GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin1),
+	GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin2),
+	GRP_MMP2("ulpi", ULPI, mmp2_ulpi_pin1),
+	GRP_MMP2("ro-1", ROT, mmp2_ro_pin1),
+	GRP_MMP2("ro-2", ROT, mmp2_ro_pin2),
+	GRP_MMP2("ro-3", ROT, mmp2_ro_pin3),
+	GRP_MMP2("ro-4", ROT, mmp2_ro_pin4),
+	GRP_MMP2("i2s 5p1", I2S, mmp2_i2s_pin1),
+	GRP_MMP2("i2s 4p2", I2S, mmp2_i2s_pin2),
+	GRP_MMP2("ssp1 4p1", SSP1, mmp2_ssp1_pin1),
+	GRP_MMP2("ssp1 4p2", SSP1, mmp2_ssp1_pin2),
+	GRP_MMP2("ssp1 4p3", SSP1, mmp2_ssp1_pin3),
+	GRP_MMP2("ssp2 4p1", SSP2, mmp2_ssp2_pin1),
+	GRP_MMP2("ssp3 4p1", SSP3, mmp2_ssp3_pin1),
+	GRP_MMP2("ssp3 4p2", SSP3, mmp2_ssp3_pin2),
+	GRP_MMP2("sspa2 4p1", SSPA2, mmp2_sspa2_pin1),
+	GRP_MMP2("sspa2 4p2", SSPA2, mmp2_sspa2_pin2),
+	GRP_MMP2("mmc1 8p1", MMC1, mmp2_mmc1_pin1),
+	GRP_MMP2("mmc2 6p1", MMC2, mmp2_mmc2_pin1),
+	GRP_MMP2("mmc3 10p1", MMC3, mmp2_mmc3_pin1),
+};
+
+static const char * const mmp2_uart1_grps[] = {"uart1 4p1", "uart1 2p2",
+	"uart1 2p3"};
+static const char * const mmp2_uart2_grps[] = {"uart2 4p1", "uart2 4p2",
+	"uart2 4p3", "uart2 4p4", "uart2 4p5", "uart2 4p6"};
+static const char * const mmp2_uart3_grps[] = {"uart3 4p1", "uart3 4p2",
+	"uart3 4p3", "uart3 4p4", "uart3 4p5", "uart3 2p6"};
+static const char * const mmp2_uart4_grps[] = {"uart4 4p1", "uart4 4p2",
+	"uart4 4p3", "uart4 4p4", "uart4 2p5"};
+static const char * const mmp2_kpdk_grps[] = {"kpdk 4p1", "kpdk 4p2"};
+static const char * const mmp2_twsi2_grps[] = {"twsi2-1", "twsi2-2",
+	"twsi2-3", "twsi2-4", "twsi2-5"};
+static const char * const mmp2_twsi3_grps[] = {"twsi3-1", "twsi3-2"};
+static const char * const mmp2_twsi4_grps[] = {"twsi4"};
+static const char * const mmp2_twsi5_grps[] = {"twsi5-1", "twsi5-2",
+	"twsi5-3"};
+static const char * const mmp2_twsi6_grps[] = {"twsi6-1", "twsi6-2",
+	"twsi6-3"};
+static const char * const mmp2_ccic1_grps[] = {"ccic1-1", "ccic1-2"};
+static const char * const mmp2_ccic2_grps[] = {"ccic2-1", "ccic2-2"};
+static const char * const mmp2_ulpi_grps[] = {"ulpi"};
+static const char * const mmp2_ro_grps[] = {"ro-1", "ro-2", "ro-3", "ro-4"};
+static const char * const mmp2_i2s_grps[] = {"i2s 5p1", "i2s 4p2"};
+static const char * const mmp2_ssp1_grps[] = {"ssp1 4p1", "ssp1 4p2",
+	"ssp1 4p3"};
+static const char * const mmp2_ssp2_grps[] = {"ssp2 4p1"};
+static const char * const mmp2_ssp3_grps[] = {"ssp3 4p1", "ssp3 4p2"};
+static const char * const mmp2_sspa2_grps[] = {"sspa2 4p1", "sspa2 4p2"};
+static const char * const mmp2_mmc1_grps[] = {"mmc1 8p1"};
+static const char * const mmp2_mmc2_grps[] = {"mmc2 6p1"};
+static const char * const mmp2_mmc3_grps[] = {"mmc3 10p1"};
+
+static struct pxa3xx_pmx_func mmp2_funcs[] = {
+	{"uart1",	ARRAY_AND_SIZE(mmp2_uart1_grps)},
+	{"uart2",	ARRAY_AND_SIZE(mmp2_uart2_grps)},
+	{"uart3",	ARRAY_AND_SIZE(mmp2_uart3_grps)},
+	{"uart4",	ARRAY_AND_SIZE(mmp2_uart4_grps)},
+	{"kpdk",	ARRAY_AND_SIZE(mmp2_kpdk_grps)},
+	{"twsi2",	ARRAY_AND_SIZE(mmp2_twsi2_grps)},
+	{"twsi3",	ARRAY_AND_SIZE(mmp2_twsi3_grps)},
+	{"twsi4",	ARRAY_AND_SIZE(mmp2_twsi4_grps)},
+	{"twsi5",	ARRAY_AND_SIZE(mmp2_twsi5_grps)},
+	{"twsi6",	ARRAY_AND_SIZE(mmp2_twsi6_grps)},
+	{"ccic1",	ARRAY_AND_SIZE(mmp2_ccic1_grps)},
+	{"ccic2",	ARRAY_AND_SIZE(mmp2_ccic2_grps)},
+	{"ulpi",	ARRAY_AND_SIZE(mmp2_ulpi_grps)},
+	{"ro",		ARRAY_AND_SIZE(mmp2_ro_grps)},
+	{"i2s",		ARRAY_AND_SIZE(mmp2_i2s_grps)},
+	{"ssp1",	ARRAY_AND_SIZE(mmp2_ssp1_grps)},
+	{"ssp2",	ARRAY_AND_SIZE(mmp2_ssp2_grps)},
+	{"ssp3",	ARRAY_AND_SIZE(mmp2_ssp3_grps)},
+	{"sspa2",	ARRAY_AND_SIZE(mmp2_sspa2_grps)},
+	{"mmc1",	ARRAY_AND_SIZE(mmp2_mmc1_grps)},
+	{"mmc2",	ARRAY_AND_SIZE(mmp2_mmc2_grps)},
+	{"mmc3",	ARRAY_AND_SIZE(mmp2_mmc3_grps)},
+};
+
+static struct pinctrl_desc mmp2_pctrl_desc = {
+	.name		= "mmp2-pinctrl",
+	.owner		= THIS_MODULE,
+};
+
+static struct pxa3xx_pinmux_info mmp2_info = {
+	.mfp		= mmp2_mfp,
+	.num_mfp	= ARRAY_SIZE(mmp2_mfp),
+	.grps		= mmp2_grps,
+	.num_grps	= ARRAY_SIZE(mmp2_grps),
+	.funcs		= mmp2_funcs,
+	.num_funcs	= ARRAY_SIZE(mmp2_funcs),
+	.num_gpio	= 169,
+	.desc		= &mmp2_pctrl_desc,
+	.pads		= mmp2_pads,
+	.num_pads	= ARRAY_SIZE(mmp2_pads),
+
+	.cputype	= PINCTRL_MMP2,
+	.ds_mask	= MMP2_DS_MASK,
+	.ds_shift	= MMP2_DS_SHIFT,
+};
+
+static int __devinit mmp2_pinmux_probe(struct platform_device *pdev)
+{
+	return pxa3xx_pinctrl_register(pdev, &mmp2_info);
+}
+
+static int __devexit mmp2_pinmux_remove(struct platform_device *pdev)
+{
+	return pxa3xx_pinctrl_unregister(pdev);
+}
+
+static struct platform_driver mmp2_pinmux_driver = {
+	.driver = {
+		.name	= "mmp2-pinmux",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= mmp2_pinmux_probe,
+	.remove	= __devexit_p(mmp2_pinmux_remove),
+};
+
+static int __init mmp2_pinmux_init(void)
+{
+	return platform_driver_register(&mmp2_pinmux_driver);
+}
+core_initcall_sync(mmp2_pinmux_init);
+
+static void __exit mmp2_pinmux_exit(void)
+{
+	platform_driver_unregister(&mmp2_pinmux_driver);
+}
+module_exit(mmp2_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c
new file mode 100644
index 0000000..c1997fa
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa168.c
@@ -0,0 +1,651 @@
+/*
+ *  linux/drivers/pinctrl/pinmux-pxa168.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "pinctrl-pxa3xx.h"
+
+#define PXA168_DS_MASK		0x1800
+#define PXA168_DS_SHIFT		11
+#define PXA168_SLEEP_MASK	0x38
+#define PXA168_SLEEP_SELECT	(1 << 9)
+#define PXA168_SLEEP_DATA	(1 << 8)
+#define PXA168_SLEEP_DIR	(1 << 7)
+
+#define MFPR_168(a, r, f0, f1, f2, f3, f4, f5, f6, f7)		\
+	{							\
+		.name = #a,					\
+		.pin = a,					\
+		.mfpr = r,					\
+		.func = {					\
+			PXA168_MUX_##f0,			\
+			PXA168_MUX_##f1,			\
+			PXA168_MUX_##f2,			\
+			PXA168_MUX_##f3,			\
+			PXA168_MUX_##f4,			\
+			PXA168_MUX_##f5,			\
+			PXA168_MUX_##f6,			\
+			PXA168_MUX_##f7,			\
+		},						\
+	}
+
+#define GRP_168(a, m, p)		\
+	{ .name = a, .mux = PXA168_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+/* 131 pins */
+enum pxa168_pin_list {
+	/* 0~122: GPIO0~GPIO122 */
+	PWR_SCL = 123,
+	PWR_SDA,
+	TDI,
+	TMS,
+	TCK,
+	TDO,
+	TRST,
+	WAKEUP = 130,
+};
+
+enum pxa168_mux {
+	/* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
+	PXA168_MUX_GPIO = 0,
+	PXA168_MUX_DFIO,
+	PXA168_MUX_NAND,
+	PXA168_MUX_SMC,
+	PXA168_MUX_SMC_CS0,
+	PXA168_MUX_SMC_CS1,
+	PXA168_MUX_SMC_INT,
+	PXA168_MUX_SMC_RDY,
+	PXA168_MUX_MMC1,
+	PXA168_MUX_MMC2,
+	PXA168_MUX_MMC2_CMD,
+	PXA168_MUX_MMC2_CLK,
+	PXA168_MUX_MMC3,
+	PXA168_MUX_MMC3_CMD,
+	PXA168_MUX_MMC3_CLK,
+	PXA168_MUX_MMC4,
+	PXA168_MUX_MSP,
+	PXA168_MUX_MSP_DAT3,
+	PXA168_MUX_MSP_INS,
+	PXA168_MUX_I2C,
+	PXA168_MUX_PWRI2C,
+	PXA168_MUX_AC97,
+	PXA168_MUX_AC97_SYSCLK,
+	PXA168_MUX_PWM,
+	PXA168_MUX_PWM1,
+	PXA168_MUX_XD,
+	PXA168_MUX_XP,
+	PXA168_MUX_LCD,
+	PXA168_MUX_CCIC,
+	PXA168_MUX_CF,
+	PXA168_MUX_CF_RDY,
+	PXA168_MUX_CF_nINPACK,
+	PXA168_MUX_CF_nWAIT,
+	PXA168_MUX_KP_MKOUT,
+	PXA168_MUX_KP_MKIN,
+	PXA168_MUX_KP_DK,
+	PXA168_MUX_ETH,
+	PXA168_MUX_ETH_TX,
+	PXA168_MUX_ETH_RX,
+	PXA168_MUX_ONE_WIRE,
+	PXA168_MUX_UART1,
+	PXA168_MUX_UART1_TX,
+	PXA168_MUX_UART1_CTS,
+	PXA168_MUX_UART1_nRI,
+	PXA168_MUX_UART1_DTR,
+	PXA168_MUX_UART2,
+	PXA168_MUX_UART2_TX,
+	PXA168_MUX_UART3,
+	PXA168_MUX_UART3_TX,
+	PXA168_MUX_UART3_CTS,
+	PXA168_MUX_SSP1,
+	PXA168_MUX_SSP1_TX,
+	PXA168_MUX_SSP2,
+	PXA168_MUX_SSP2_TX,
+	PXA168_MUX_SSP3,
+	PXA168_MUX_SSP3_TX,
+	PXA168_MUX_SSP4,
+	PXA168_MUX_SSP4_TX,
+	PXA168_MUX_SSP5,
+	PXA168_MUX_SSP5_TX,
+	PXA168_MUX_USB,
+	PXA168_MUX_JTAG,
+	PXA168_MUX_RESET,
+	PXA168_MUX_WAKEUP,
+	PXA168_MUX_EXT_32K_IN,
+	PXA168_MUX_NONE = 0xffff,
+};
+
+static struct pinctrl_pin_desc pxa168_pads[] = {
+	PINCTRL_PIN(GPIO0, "GPIO0"),
+	PINCTRL_PIN(GPIO1, "GPIO1"),
+	PINCTRL_PIN(GPIO2, "GPIO2"),
+	PINCTRL_PIN(GPIO3, "GPIO3"),
+	PINCTRL_PIN(GPIO4, "GPIO4"),
+	PINCTRL_PIN(GPIO5, "GPIO5"),
+	PINCTRL_PIN(GPIO6, "GPIO6"),
+	PINCTRL_PIN(GPIO7, "GPIO7"),
+	PINCTRL_PIN(GPIO8, "GPIO8"),
+	PINCTRL_PIN(GPIO9, "GPIO9"),
+	PINCTRL_PIN(GPIO10, "GPIO10"),
+	PINCTRL_PIN(GPIO11, "GPIO11"),
+	PINCTRL_PIN(GPIO12, "GPIO12"),
+	PINCTRL_PIN(GPIO13, "GPIO13"),
+	PINCTRL_PIN(GPIO14, "GPIO14"),
+	PINCTRL_PIN(GPIO15, "GPIO15"),
+	PINCTRL_PIN(GPIO16, "GPIO16"),
+	PINCTRL_PIN(GPIO17, "GPIO17"),
+	PINCTRL_PIN(GPIO18, "GPIO18"),
+	PINCTRL_PIN(GPIO19, "GPIO19"),
+	PINCTRL_PIN(GPIO20, "GPIO20"),
+	PINCTRL_PIN(GPIO21, "GPIO21"),
+	PINCTRL_PIN(GPIO22, "GPIO22"),
+	PINCTRL_PIN(GPIO23, "GPIO23"),
+	PINCTRL_PIN(GPIO24, "GPIO24"),
+	PINCTRL_PIN(GPIO25, "GPIO25"),
+	PINCTRL_PIN(GPIO26, "GPIO26"),
+	PINCTRL_PIN(GPIO27, "GPIO27"),
+	PINCTRL_PIN(GPIO28, "GPIO28"),
+	PINCTRL_PIN(GPIO29, "GPIO29"),
+	PINCTRL_PIN(GPIO30, "GPIO30"),
+	PINCTRL_PIN(GPIO31, "GPIO31"),
+	PINCTRL_PIN(GPIO32, "GPIO32"),
+	PINCTRL_PIN(GPIO33, "GPIO33"),
+	PINCTRL_PIN(GPIO34, "GPIO34"),
+	PINCTRL_PIN(GPIO35, "GPIO35"),
+	PINCTRL_PIN(GPIO36, "GPIO36"),
+	PINCTRL_PIN(GPIO37, "GPIO37"),
+	PINCTRL_PIN(GPIO38, "GPIO38"),
+	PINCTRL_PIN(GPIO39, "GPIO39"),
+	PINCTRL_PIN(GPIO40, "GPIO40"),
+	PINCTRL_PIN(GPIO41, "GPIO41"),
+	PINCTRL_PIN(GPIO42, "GPIO42"),
+	PINCTRL_PIN(GPIO43, "GPIO43"),
+	PINCTRL_PIN(GPIO44, "GPIO44"),
+	PINCTRL_PIN(GPIO45, "GPIO45"),
+	PINCTRL_PIN(GPIO46, "GPIO46"),
+	PINCTRL_PIN(GPIO47, "GPIO47"),
+	PINCTRL_PIN(GPIO48, "GPIO48"),
+	PINCTRL_PIN(GPIO49, "GPIO49"),
+	PINCTRL_PIN(GPIO50, "GPIO50"),
+	PINCTRL_PIN(GPIO51, "GPIO51"),
+	PINCTRL_PIN(GPIO52, "GPIO52"),
+	PINCTRL_PIN(GPIO53, "GPIO53"),
+	PINCTRL_PIN(GPIO54, "GPIO54"),
+	PINCTRL_PIN(GPIO55, "GPIO55"),
+	PINCTRL_PIN(GPIO56, "GPIO56"),
+	PINCTRL_PIN(GPIO57, "GPIO57"),
+	PINCTRL_PIN(GPIO58, "GPIO58"),
+	PINCTRL_PIN(GPIO59, "GPIO59"),
+	PINCTRL_PIN(GPIO60, "GPIO60"),
+	PINCTRL_PIN(GPIO61, "GPIO61"),
+	PINCTRL_PIN(GPIO62, "GPIO62"),
+	PINCTRL_PIN(GPIO63, "GPIO63"),
+	PINCTRL_PIN(GPIO64, "GPIO64"),
+	PINCTRL_PIN(GPIO65, "GPIO65"),
+	PINCTRL_PIN(GPIO66, "GPIO66"),
+	PINCTRL_PIN(GPIO67, "GPIO67"),
+	PINCTRL_PIN(GPIO68, "GPIO68"),
+	PINCTRL_PIN(GPIO69, "GPIO69"),
+	PINCTRL_PIN(GPIO70, "GPIO70"),
+	PINCTRL_PIN(GPIO71, "GPIO71"),
+	PINCTRL_PIN(GPIO72, "GPIO72"),
+	PINCTRL_PIN(GPIO73, "GPIO73"),
+	PINCTRL_PIN(GPIO74, "GPIO74"),
+	PINCTRL_PIN(GPIO75, "GPIO75"),
+	PINCTRL_PIN(GPIO76, "GPIO76"),
+	PINCTRL_PIN(GPIO77, "GPIO77"),
+	PINCTRL_PIN(GPIO78, "GPIO78"),
+	PINCTRL_PIN(GPIO79, "GPIO79"),
+	PINCTRL_PIN(GPIO80, "GPIO80"),
+	PINCTRL_PIN(GPIO81, "GPIO81"),
+	PINCTRL_PIN(GPIO82, "GPIO82"),
+	PINCTRL_PIN(GPIO83, "GPIO83"),
+	PINCTRL_PIN(GPIO84, "GPIO84"),
+	PINCTRL_PIN(GPIO85, "GPIO85"),
+	PINCTRL_PIN(GPIO86, "GPIO86"),
+	PINCTRL_PIN(GPIO87, "GPIO87"),
+	PINCTRL_PIN(GPIO88, "GPIO88"),
+	PINCTRL_PIN(GPIO89, "GPIO89"),
+	PINCTRL_PIN(GPIO90, "GPIO90"),
+	PINCTRL_PIN(GPIO91, "GPIO91"),
+	PINCTRL_PIN(GPIO92, "GPIO92"),
+	PINCTRL_PIN(GPIO93, "GPIO93"),
+	PINCTRL_PIN(GPIO94, "GPIO94"),
+	PINCTRL_PIN(GPIO95, "GPIO95"),
+	PINCTRL_PIN(GPIO96, "GPIO96"),
+	PINCTRL_PIN(GPIO97, "GPIO97"),
+	PINCTRL_PIN(GPIO98, "GPIO98"),
+	PINCTRL_PIN(GPIO99, "GPIO99"),
+	PINCTRL_PIN(GPIO100, "GPIO100"),
+	PINCTRL_PIN(GPIO101, "GPIO101"),
+	PINCTRL_PIN(GPIO102, "GPIO102"),
+	PINCTRL_PIN(GPIO103, "GPIO103"),
+	PINCTRL_PIN(GPIO104, "GPIO104"),
+	PINCTRL_PIN(GPIO105, "GPIO105"),
+	PINCTRL_PIN(GPIO106, "GPIO106"),
+	PINCTRL_PIN(GPIO107, "GPIO107"),
+	PINCTRL_PIN(GPIO108, "GPIO108"),
+	PINCTRL_PIN(GPIO109, "GPIO109"),
+	PINCTRL_PIN(GPIO110, "GPIO110"),
+	PINCTRL_PIN(GPIO111, "GPIO111"),
+	PINCTRL_PIN(GPIO112, "GPIO112"),
+	PINCTRL_PIN(GPIO113, "GPIO113"),
+	PINCTRL_PIN(GPIO114, "GPIO114"),
+	PINCTRL_PIN(GPIO115, "GPIO115"),
+	PINCTRL_PIN(GPIO116, "GPIO116"),
+	PINCTRL_PIN(GPIO117, "GPIO117"),
+	PINCTRL_PIN(GPIO118, "GPIO118"),
+	PINCTRL_PIN(GPIO119, "GPIO119"),
+	PINCTRL_PIN(GPIO120, "GPIO120"),
+	PINCTRL_PIN(GPIO121, "GPIO121"),
+	PINCTRL_PIN(GPIO122, "GPIO122"),
+	PINCTRL_PIN(PWR_SCL, "PWR_SCL"),
+	PINCTRL_PIN(PWR_SDA, "PWR_SDA"),
+	PINCTRL_PIN(TDI, "TDI"),
+	PINCTRL_PIN(TMS, "TMS"),
+	PINCTRL_PIN(TCK, "TCK"),
+	PINCTRL_PIN(TDO, "TDO"),
+	PINCTRL_PIN(TRST, "TRST"),
+	PINCTRL_PIN(WAKEUP, "WAKEUP"),
+};
+
+struct pxa3xx_mfp_pin pxa168_mfp[] = {
+	/*       pin      offs   f0       f1           f2         f3           f4           f5        f6           f7  */
+	MFPR_168(GPIO0,   0x04C, DFIO,    NONE,        NONE,      MSP,         MMC3_CMD,    GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO1,   0x050, DFIO,    NONE,        NONE,      MSP,         MMC3_CLK,    GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO2,   0x054, DFIO,    NONE,        NONE,      MSP,         NONE,        GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO3,   0x058, DFIO,    NONE,        NONE,      NONE,        NONE,        GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO4,   0x05C, DFIO,    NONE,        NONE,      MSP_DAT3,    NONE,        GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO5,   0x060, DFIO,    NONE,        NONE,      MSP,         NONE,        GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO6,   0x064, DFIO,    NONE,        NONE,      MSP,         NONE,        GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO7,   0x068, DFIO,    NONE,        NONE,      MSP,         NONE,        GPIO,     MMC3,        NONE),
+	MFPR_168(GPIO8,   0x06C, DFIO,    MMC2,        UART3_TX,  NONE,        MMC2_CMD,    GPIO,     MMC3_CLK,    NONE),
+	MFPR_168(GPIO9,   0x070, DFIO,    MMC2,        UART3,     NONE,        MMC2_CLK,    GPIO,     MMC3_CMD,    NONE),
+	MFPR_168(GPIO10,  0x074, DFIO,    MMC2,        UART3,     NONE,        NONE,        GPIO,     MSP_DAT3,    NONE),
+	MFPR_168(GPIO11,  0x078, DFIO,    MMC2,        UART3,     NONE,        NONE,        GPIO,     MSP,         NONE),
+	MFPR_168(GPIO12,  0x07C, DFIO,    MMC2,        UART3,     NONE,        NONE,        GPIO,     MSP,         NONE),
+	MFPR_168(GPIO13,  0x080, DFIO,    MMC2,        UART3,     NONE,        NONE,        GPIO,     MSP,         NONE),
+	MFPR_168(GPIO14,  0x084, DFIO,    MMC2,        NONE,      NONE,        NONE,        GPIO,     MSP,         NONE),
+	MFPR_168(GPIO15,  0x088, DFIO,    MMC2,        NONE,      NONE,        NONE,        GPIO,     MSP,         NONE),
+	MFPR_168(GPIO16,  0x08C, GPIO,    NAND,        SMC_CS0,   SMC_CS1,     NONE,        NONE,     MMC3,        NONE),
+	MFPR_168(GPIO17,  0x090, NAND,    NONE,        NONE,      NONE,        NONE,        GPIO,     MSP,         NONE),
+	MFPR_168(GPIO18,  0x094, GPIO,    NAND,        SMC_CS1,   SMC_CS0,     NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO19,  0x098, SMC_CS0, NONE,        NONE,      CF,          NONE,        GPIO,     NONE,        NONE),
+	MFPR_168(GPIO20,  0x09C, GPIO,    NONE,        SMC_CS1,   CF,          CF_RDY,      NONE,     NONE,        NONE),
+	MFPR_168(GPIO21,  0x0A0, NAND,    MMC2_CLK,    NONE,      NONE,        NONE,        GPIO,     NONE,        NONE),
+	MFPR_168(GPIO22,  0x0A4, NAND,    MMC2_CMD,    NONE,      NONE,        NONE,        GPIO,     NONE,        NONE),
+	MFPR_168(GPIO23,  0x0A8, SMC,     NAND,        NONE,      CF,          NONE,        GPIO,     NONE,        NONE),
+	MFPR_168(GPIO24,  0x0AC, NAND,    NONE,        NONE,      NONE,        NONE,        GPIO,     NONE,        NONE),
+	MFPR_168(GPIO25,  0x0B0, SMC,     NAND,        NONE,      CF,          NONE,        GPIO,     NONE,        NONE),
+	MFPR_168(GPIO26,  0x0B4, GPIO,    NAND,        NONE,      NONE,        CF,          NONE,     NONE,        NONE),
+	MFPR_168(GPIO27,  0x0B8, SMC_INT, NAND,        SMC,       NONE,        SMC_RDY,     GPIO,     NONE,        NONE),
+	MFPR_168(GPIO28,  0x0BC, SMC_RDY, MMC4,        SMC,       CF_RDY,      NONE,        GPIO,     MMC2_CMD,    NONE),
+	MFPR_168(GPIO29,  0x0C0, SMC,     MMC4,        NONE,      CF,          NONE,        GPIO,     MMC2_CLK,    KP_DK),
+	MFPR_168(GPIO30,  0x0C4, SMC,     MMC4,        UART3_TX,  CF,          NONE,        GPIO,     MMC2,        KP_DK),
+	MFPR_168(GPIO31,  0x0C8, SMC,     MMC4,        UART3,     CF,          NONE,        GPIO,     MMC2,        KP_DK),
+	MFPR_168(GPIO32,  0x0CC, SMC,     MMC4,        UART3,     CF,          NONE,        GPIO,     MMC2,        KP_DK),
+	MFPR_168(GPIO33,  0x0D0, SMC,     MMC4,        UART3,     CF,          CF_nINPACK,  GPIO,     MMC2,        KP_DK),
+	MFPR_168(GPIO34,  0x0D4, GPIO,    NONE,        SMC_CS1,   CF,          CF_nWAIT,    NONE,     MMC3,        KP_DK),
+	MFPR_168(GPIO35,  0x0D8, GPIO,    NONE,        SMC,       CF_nINPACK,  NONE,        NONE,     MMC3_CMD,    KP_DK),
+	MFPR_168(GPIO36,  0x0DC, GPIO,    NONE,        SMC,       CF_nWAIT,    NONE,        NONE,     MMC3_CLK,    KP_DK),
+	MFPR_168(GPIO37,  0x000, GPIO,    MMC1,        NONE,      KP_MKOUT,    CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO38,  0x004, GPIO,    MMC1,        NONE,      KP_MKOUT,    CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO39,  0x008, GPIO,    NONE,        NONE,      KP_MKOUT,    CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO40,  0x00C, GPIO,    MMC1,        MSP,       KP_MKOUT,    CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO41,  0x010, GPIO,    MMC1,        MSP,       NONE,        CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO42,  0x014, GPIO,    I2C,         NONE,      MSP,         CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO43,  0x018, GPIO,    MMC1,        MSP,       MSP_INS,     NONE,        NONE,     KP_MKIN,     KP_DK),
+	MFPR_168(GPIO44,  0x01C, GPIO,    MMC1,        MSP_DAT3,  MSP,         CCIC,        XP,       KP_MKIN,     KP_DK),
+	MFPR_168(GPIO45,  0x020, GPIO,    NONE,        NONE,      MSP,         CCIC,        XP,       NONE,        KP_DK),
+	MFPR_168(GPIO46,  0x024, GPIO,    MMC1,        MSP_INS,   MSP,         CCIC,        NONE,     KP_MKOUT,    KP_DK),
+	MFPR_168(GPIO47,  0x028, GPIO,    NONE,        NONE,      MSP_INS,     NONE,        XP,       NONE,        KP_DK),
+	MFPR_168(GPIO48,  0x02C, GPIO,    MMC1,        NONE,      MSP_DAT3,    CCIC,        NONE,     NONE,        KP_DK),
+	MFPR_168(GPIO49,  0x030, GPIO,    MMC1,        NONE,      MSP,         NONE,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO50,  0x034, GPIO,    I2C,         NONE,      MSP,         CCIC,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO51,  0x038, GPIO,    MMC1,        NONE,      MSP,         NONE,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO52,  0x03C, GPIO,    MMC1,        NONE,      MSP,         NONE,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO53,  0x040, GPIO,    MMC1,        NONE,      NONE,        NONE,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO54,  0x044, GPIO,    MMC1,        NONE,      NONE,        CCIC,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO55,  0x048, GPIO,    NONE,        NONE,      MSP,         CCIC,        XD,       KP_MKOUT,    NONE),
+	MFPR_168(GPIO56,  0x0E0, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO57,  0x0E4, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO58,  0x0E8, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO59,  0x0EC, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO60,  0x0F0, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO61,  0x0F4, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO62,  0x0F8, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO63,  0x0FC, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO64,  0x100, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO65,  0x104, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO66,  0x108, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO67,  0x10C, GPIO,    LCD,         NONE,      NONE,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO68,  0x110, GPIO,    LCD,         NONE,      XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO69,  0x114, GPIO,    LCD,         NONE,      XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO70,  0x118, GPIO,    LCD,         NONE,      XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO71,  0x11C, GPIO,    LCD,         NONE,      XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO72,  0x120, GPIO,    LCD,         NONE,      XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO73,  0x124, GPIO,    LCD,         NONE,      XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO74,  0x128, GPIO,    LCD,         PWM,       XD,          NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO75,  0x12C, GPIO,    LCD,         PWM,       XD,          ONE_WIRE,    NONE,     NONE,        NONE),
+	MFPR_168(GPIO76,  0x130, GPIO,    LCD,         PWM,       I2C,         NONE,        NONE,     MSP_INS,     NONE),
+	MFPR_168(GPIO77,  0x134, GPIO,    LCD,         PWM1,      I2C,         ONE_WIRE,    NONE,     XD,          NONE),
+	MFPR_168(GPIO78,  0x138, GPIO,    LCD,         NONE,      NONE,        NONE,        MMC4,     NONE,        NONE),
+	MFPR_168(GPIO79,  0x13C, GPIO,    LCD,         NONE,      NONE,        ONE_WIRE,    MMC4,     NONE,        NONE),
+	MFPR_168(GPIO80,  0x140, GPIO,    LCD,         NONE,      I2C,         NONE,        MMC4,     NONE,        NONE),
+	MFPR_168(GPIO81,  0x144, GPIO,    LCD,         NONE,      I2C,         ONE_WIRE,    MMC4,     NONE,        NONE),
+	MFPR_168(GPIO82,  0x148, GPIO,    LCD,         PWM,       NONE,        NONE,        MMC4,     NONE,        NONE),
+	MFPR_168(GPIO83,  0x14C, GPIO,    LCD,         PWM,       NONE,        RESET,       MMC4,     NONE,        NONE),
+	MFPR_168(GPIO84,  0x150, GPIO,    NONE,        PWM,       ONE_WIRE,    PWM1,        NONE,     NONE,        EXT_32K_IN),
+	MFPR_168(GPIO85,  0x154, GPIO,    NONE,        PWM1,      NONE,        NONE,        NONE,     NONE,        USB),
+	MFPR_168(GPIO86,  0x158, GPIO,    MMC2,        UART2,     NONE,        JTAG,        ETH_TX,   SSP5_TX,     SSP5),
+	MFPR_168(GPIO87,  0x15C, GPIO,    MMC2,        UART2,     NONE,        JTAG,        ETH_TX,   SSP5,        SSP5_TX),
+	MFPR_168(GPIO88,  0x160, GPIO,    MMC2,        UART2,     UART2_TX,    JTAG,        ETH_TX,   ETH_RX,      SSP5),
+	MFPR_168(GPIO89,  0x164, GPIO,    MMC2,        UART2_TX,  UART2,       JTAG,        ETH_TX,   ETH_RX,      SSP5),
+	MFPR_168(GPIO90,  0x168, GPIO,    MMC2,        NONE,      SSP3,        JTAG,        ETH_TX,   ETH_RX,      NONE),
+	MFPR_168(GPIO91,  0x16C, GPIO,    MMC2,        NONE,      SSP3,        SSP4,        ETH_TX,   ETH_RX,      NONE),
+	MFPR_168(GPIO92,  0x170, GPIO,    MMC2,        NONE,      SSP3,        SSP3_TX,     ETH,      NONE,        NONE),
+	MFPR_168(GPIO93,  0x174, GPIO,    MMC2,        NONE,      SSP3_TX,     SSP3,        ETH,      NONE,        NONE),
+	MFPR_168(GPIO94,  0x178, GPIO,    MMC2_CMD,    SSP3,      AC97_SYSCLK, AC97,        ETH,      NONE,        NONE),
+	MFPR_168(GPIO95,  0x17C, GPIO,    MMC2_CLK,    NONE,      NONE,        AC97,        ETH,      NONE,        NONE),
+	MFPR_168(GPIO96,  0x180, GPIO,    PWM,         NONE,      MMC2,        NONE,        ETH_RX,   ETH_TX,      NONE),
+	MFPR_168(GPIO97,  0x184, GPIO,    PWM,         ONE_WIRE,  NONE,        NONE,        ETH_RX,   ETH_TX,      NONE),
+	MFPR_168(GPIO98,  0x188, GPIO,    PWM1,        UART3_TX,  UART3,       NONE,        ETH_RX,   ETH_TX,      NONE),
+	MFPR_168(GPIO99,  0x18C, GPIO,    ONE_WIRE,    UART3,     UART3_TX,    NONE,        ETH_RX,   ETH_TX,      NONE),
+	MFPR_168(GPIO100, 0x190, GPIO,    NONE,        UART3_CTS, UART3,       NONE,        ETH,      NONE,        NONE),
+	MFPR_168(GPIO101, 0x194, GPIO,    NONE,        UART3,     UART3_CTS,   NONE,        ETH,      NONE,        NONE),
+	MFPR_168(GPIO102, 0x198, GPIO,    I2C,         UART3,     SSP4,        NONE,        NONE,     NONE,        NONE),
+	MFPR_168(GPIO103, 0x19C, GPIO,    I2C,         UART3,     SSP4,        SSP2,        ETH,      NONE,        NONE),
+	MFPR_168(GPIO104, 0x1A0, GPIO,    PWM,         UART1,     SSP4,        SSP4_TX,     AC97,     KP_MKOUT,    NONE),
+	MFPR_168(GPIO105, 0x1A4, GPIO,    I2C,         UART1,     SSP4_TX,     SSP4,        AC97,     KP_MKOUT,    NONE),
+	MFPR_168(GPIO106, 0x1A8, GPIO,    I2C,         PWM1,      AC97_SYSCLK, MMC2,        NONE,     KP_MKOUT,    NONE),
+	MFPR_168(GPIO107, 0x1AC, GPIO,    UART1_TX,    UART1,     NONE,        SSP2,        MSP_DAT3, NONE,        KP_MKIN),
+	MFPR_168(GPIO108, 0x1B0, GPIO,    UART1,       UART1_TX,  NONE,        SSP2_TX,     MSP,      NONE,        KP_MKIN),
+	MFPR_168(GPIO109, 0x1B4, GPIO,    UART1_CTS,   UART1,     NONE,        AC97_SYSCLK, MSP,      NONE,        KP_MKIN),
+	MFPR_168(GPIO110, 0x1B8, GPIO,    UART1,       UART1_CTS, NONE,        SMC_RDY,     MSP,      NONE,        KP_MKIN),
+	MFPR_168(GPIO111, 0x1BC, GPIO,    UART1_nRI,   UART1,     SSP3,        SSP2,        MSP,      XD,          KP_MKOUT),
+	MFPR_168(GPIO112, 0x1C0, GPIO,    UART1_DTR,   UART1,     ONE_WIRE,    SSP2,        MSP,      XD,          KP_MKOUT),
+	MFPR_168(GPIO113, 0x1C4, GPIO,    NONE,        NONE,      NONE,        NONE,        NONE,     AC97_SYSCLK, NONE),
+	MFPR_168(GPIO114, 0x1C8, GPIO,    SSP1,        NONE,      NONE,        NONE,        NONE,     AC97,        NONE),
+	MFPR_168(GPIO115, 0x1CC, GPIO,    SSP1,        NONE,      NONE,        NONE,        NONE,     AC97,        NONE),
+	MFPR_168(GPIO116, 0x1D0, GPIO,    SSP1_TX,     SSP1,      NONE,        NONE,        NONE,     AC97,        NONE),
+	MFPR_168(GPIO117, 0x1D4, GPIO,    SSP1,        SSP1_TX,   NONE,        MMC2_CMD,    NONE,     AC97,        NONE),
+	MFPR_168(GPIO118, 0x1D8, GPIO,    SSP2,        NONE,      NONE,        MMC2_CLK,    NONE,     AC97,        KP_MKIN),
+	MFPR_168(GPIO119, 0x1DC, GPIO,    SSP2,        NONE,      NONE,        MMC2,        NONE,     AC97,        KP_MKIN),
+	MFPR_168(GPIO120, 0x1E0, GPIO,    SSP2,        SSP2_TX,   NONE,        MMC2,        NONE,     NONE,        KP_MKIN),
+	MFPR_168(GPIO121, 0x1E4, GPIO,    SSP2_TX,     SSP2,      NONE,        MMC2,        NONE,     NONE,        KP_MKIN),
+	MFPR_168(GPIO122, 0x1E8, GPIO,    AC97_SYSCLK, SSP2,      PWM,         MMC2,        NONE,     NONE,        NONE),
+	MFPR_168(PWR_SCL, 0x1EC, PWRI2C,  NONE,        NONE,      NONE,        NONE,        NONE,     GPIO,        MMC4),
+	MFPR_168(PWR_SDA, 0x1F0, PWRI2C,  NONE,        NONE,      NONE,        NONE,        NONE,     GPIO,        NONE),
+	MFPR_168(TDI,     0x1F4, JTAG,    PWM1,        UART2,     MMC4,        SSP5,        NONE,     XD,          MMC4),
+	MFPR_168(TMS,     0x1F8, JTAG,    PWM,         UART2,     NONE,        SSP5,        NONE,     XD,          MMC4),
+	MFPR_168(TCK,     0x1FC, JTAG,    PWM,         UART2,     UART2_TX,    SSP5,        NONE,     XD,          MMC4),
+	MFPR_168(TDO,     0x200, JTAG,    PWM,         UART2_TX,  UART2,       SSP5_TX,     NONE,     XD,          MMC4),
+	MFPR_168(TRST,    0x204, JTAG,    ONE_WIRE,    SSP2,      SSP3,        AC97_SYSCLK, NONE,     XD,          MMC4),
+	MFPR_168(WAKEUP,  0x208, WAKEUP,  ONE_WIRE,    PWM1,      PWM,         SSP2,        NONE,     GPIO,        MMC4),
+};
+
+static const unsigned p168_jtag_pin1[] = {TDI, TMS, TCK, TDO, TRST};
+static const unsigned p168_wakeup_pin1[] = {WAKEUP};
+static const unsigned p168_ssp1rx_pin1[] = {GPIO114, GPIO115, GPIO116};
+static const unsigned p168_ssp1tx_pin1[] = {GPIO117};
+static const unsigned p168_ssp4rx_pin1[] = {GPIO102, GPIO103, GPIO104};
+static const unsigned p168_ssp4tx_pin1[] = {GPIO105};
+static const unsigned p168_ssp5rx_pin1[] = {GPIO86, GPIO88, GPIO89};
+static const unsigned p168_ssp5tx_pin1[] = {GPIO87};
+static const unsigned p168_i2c_pin1[] = {GPIO105, GPIO106};
+static const unsigned p168_pwri2c_pin1[] = {PWR_SCL, PWR_SDA};
+static const unsigned p168_mmc1_pin1[] = {GPIO40, GPIO41, GPIO43, GPIO46,
+	GPIO49, GPIO51, GPIO52, GPIO53};
+static const unsigned p168_mmc2_data_pin1[] = {GPIO90, GPIO91, GPIO92, GPIO93};
+static const unsigned p168_mmc2_cmd_pin1[] = {GPIO94};
+static const unsigned p168_mmc2_clk_pin1[] = {GPIO95};
+static const unsigned p168_mmc3_data_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3,
+	GPIO4, GPIO5, GPIO6, GPIO7};
+static const unsigned p168_mmc3_cmd_pin1[] = {GPIO9};
+static const unsigned p168_mmc3_clk_pin1[] = {GPIO8};
+static const unsigned p168_eth_pin1[] = {GPIO92, GPIO93, GPIO100, GPIO101,
+	GPIO103};
+static const unsigned p168_ethtx_pin1[] = {GPIO86, GPIO87, GPIO88, GPIO89,
+	GPIO90, GPIO91};
+static const unsigned p168_ethrx_pin1[] = {GPIO94, GPIO95, GPIO96, GPIO97,
+	GPIO98, GPIO99};
+static const unsigned p168_uart1rx_pin1[] = {GPIO107};
+static const unsigned p168_uart1tx_pin1[] = {GPIO108};
+static const unsigned p168_uart3rx_pin1[] = {GPIO98, GPIO100, GPIO101};
+static const unsigned p168_uart3tx_pin1[] = {GPIO99};
+static const unsigned p168_msp_pin1[] = {GPIO40, GPIO41, GPIO42, GPIO43,
+	GPIO44, GPIO50};
+static const unsigned p168_ccic_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+	GPIO41, GPIO42, GPIO44, GPIO45, GPIO46, GPIO48, GPIO54, GPIO55};
+static const unsigned p168_xd_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+	GPIO41, GPIO42, GPIO44, GPIO45, GPIO47, GPIO48, GPIO49, GPIO50,
+	GPIO51, GPIO52};
+static const unsigned p168_lcd_pin1[] = {GPIO56, GPIO57, GPIO58, GPIO59,
+	GPIO60, GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67,
+	GPIO68, GPIO69, GPIO70, GPIO71, GPIO72, GPIO73, GPIO74, GPIO75,
+	GPIO76, GPIO77, GPIO78, GPIO79, GPIO80, GPIO81, GPIO82, GPIO83};
+static const unsigned p168_dfio_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3,
+	GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12,
+	GPIO13, GPIO14, GPIO15};
+static const unsigned p168_nand_pin1[] = {GPIO16, GPIO17, GPIO21, GPIO22,
+	GPIO24, GPIO26};
+static const unsigned p168_smc_pin1[] = {GPIO23, GPIO25, GPIO29, GPIO35,
+	GPIO36};
+static const unsigned p168_smccs0_pin1[] = {GPIO18};
+static const unsigned p168_smccs1_pin1[] = {GPIO34};
+static const unsigned p168_smcrdy_pin1[] = {GPIO28};
+static const unsigned p168_ac97sysclk_pin1[] = {GPIO113};
+static const unsigned p168_ac97_pin1[] = {GPIO114, GPIO115, GPIO117, GPIO118,
+	GPIO119};
+static const unsigned p168_cf_pin1[] = {GPIO19, GPIO20, GPIO23, GPIO25,
+	GPIO28, GPIO29, GPIO30, GPIO31, GPIO32, GPIO33, GPIO34, GPIO35,
+	GPIO36};
+static const unsigned p168_kpmkin_pin1[] = {GPIO109, GPIO110, GPIO121};
+static const unsigned p168_kpmkout_pin1[] = {GPIO111, GPIO112};
+static const unsigned p168_gpio86_pin1[] = {WAKEUP};
+static const unsigned p168_gpio86_pin2[] = {GPIO86};
+static const unsigned p168_gpio87_pin1[] = {GPIO87};
+static const unsigned p168_gpio87_pin2[] = {PWR_SDA};
+static const unsigned p168_gpio88_pin1[] = {GPIO88};
+static const unsigned p168_gpio88_pin2[] = {PWR_SCL};
+
+static struct pxa3xx_pin_group pxa168_grps[] = {
+	GRP_168("uart1rx-1", UART1, p168_uart1rx_pin1),
+	GRP_168("uart1tx-1", UART1_TX, p168_uart1tx_pin1),
+	GRP_168("uart3rx-1", UART3, p168_uart3rx_pin1),
+	GRP_168("uart3tx-1", UART3_TX, p168_uart3tx_pin1),
+	GRP_168("ssp1rx-1", SSP1, p168_ssp1rx_pin1),
+	GRP_168("ssp1tx-1", SSP1_TX, p168_ssp1tx_pin1),
+	GRP_168("ssp4rx-1", SSP4, p168_ssp4rx_pin1),
+	GRP_168("ssp4tx-1", SSP4_TX, p168_ssp4tx_pin1),
+	GRP_168("ssp5rx-1", SSP5, p168_ssp5rx_pin1),
+	GRP_168("ssp5tx-1", SSP5_TX, p168_ssp5tx_pin1),
+	GRP_168("jtag", JTAG, p168_jtag_pin1),
+	GRP_168("wakeup", WAKEUP, p168_wakeup_pin1),
+	GRP_168("i2c", I2C, p168_i2c_pin1),
+	GRP_168("pwri2c", PWRI2C, p168_pwri2c_pin1),
+	GRP_168("mmc1 8p1", MMC1, p168_mmc1_pin1),
+	GRP_168("mmc2 4p1", MMC2, p168_mmc2_data_pin1),
+	GRP_168("mmc2 cmd1", MMC2_CMD, p168_mmc2_cmd_pin1),
+	GRP_168("mmc2 clk1", MMC2_CLK, p168_mmc2_clk_pin1),
+	GRP_168("mmc3 8p1", MMC3, p168_mmc3_data_pin1),
+	GRP_168("mmc3 cmd1", MMC3_CMD, p168_mmc3_cmd_pin1),
+	GRP_168("mmc3 clk1", MMC3_CLK, p168_mmc3_clk_pin1),
+	GRP_168("eth", ETH, p168_eth_pin1),
+	GRP_168("eth rx", ETH_RX, p168_ethrx_pin1),
+	GRP_168("eth tx", ETH_TX, p168_ethtx_pin1),
+	GRP_168("msp", MSP, p168_msp_pin1),
+	GRP_168("ccic", CCIC, p168_ccic_pin1),
+	GRP_168("xd", XD, p168_xd_pin1),
+	GRP_168("lcd", LCD, p168_lcd_pin1),
+	GRP_168("dfio", DFIO, p168_dfio_pin1),
+	GRP_168("nand", NAND, p168_nand_pin1),
+	GRP_168("smc", SMC, p168_smc_pin1),
+	GRP_168("smc cs0", SMC_CS0, p168_smccs0_pin1),
+	GRP_168("smc cs1", SMC_CS1, p168_smccs1_pin1),
+	GRP_168("smc rdy", SMC_RDY, p168_smcrdy_pin1),
+	GRP_168("ac97 sysclk", AC97_SYSCLK, p168_ac97sysclk_pin1),
+	GRP_168("ac97", AC97, p168_ac97_pin1),
+	GRP_168("cf", CF, p168_cf_pin1),
+	GRP_168("kp mkin 3p1", KP_MKIN, p168_kpmkin_pin1),
+	GRP_168("kp mkout 2p1", KP_MKOUT, p168_kpmkout_pin1),
+	GRP_168("gpio86-1", GPIO, p168_gpio86_pin1),
+	GRP_168("gpio86-2", GPIO, p168_gpio86_pin2),
+	GRP_168("gpio87-1", GPIO, p168_gpio87_pin1),
+	GRP_168("gpio87-2", GPIO, p168_gpio87_pin2),
+	GRP_168("gpio88-1", GPIO, p168_gpio88_pin1),
+	GRP_168("gpio88-2", GPIO, p168_gpio88_pin2),
+};
+
+static const char * const p168_uart1rx_grps[] = {"uart1rx-1"};
+static const char * const p168_uart1tx_grps[] = {"uart1tx-1"};
+static const char * const p168_uart3rx_grps[] = {"uart3rx-1"};
+static const char * const p168_uart3tx_grps[] = {"uart3tx-1"};
+static const char * const p168_ssp1rx_grps[] = {"ssp1rx-1"};
+static const char * const p168_ssp1tx_grps[] = {"ssp1tx-1"};
+static const char * const p168_ssp4rx_grps[] = {"ssp4rx-1"};
+static const char * const p168_ssp4tx_grps[] = {"ssp4tx-1"};
+static const char * const p168_ssp5rx_grps[] = {"ssp5rx-1"};
+static const char * const p168_ssp5tx_grps[] = {"ssp5tx-1"};
+static const char * const p168_i2c_grps[] = {"i2c"};
+static const char * const p168_pwri2c_grps[] = {"pwri2c"};
+static const char * const p168_mmc1_grps[] = {"mmc1 8p1"};
+static const char * const p168_mmc2_data_grps[] = {"mmc2 4p1"};
+static const char * const p168_mmc2_cmd_grps[] = {"mmc2 cmd1"};
+static const char * const p168_mmc2_clk_grps[] = {"mmc2 clk1"};
+static const char * const p168_mmc3_data_grps[] = {"mmc3 8p1"};
+static const char * const p168_mmc3_cmd_grps[] = {"mmc3 cmd1"};
+static const char * const p168_mmc3_clk_grps[] = {"mmc3 clk1"};
+static const char * const p168_eth_grps[] = {"eth"};
+static const char * const p168_ethrx_grps[] = {"eth rx"};
+static const char * const p168_ethtx_grps[] = {"eth tx"};
+static const char * const p168_msp_grps[] = {"msp"};
+static const char * const p168_ccic_grps[] = {"ccic"};
+static const char * const p168_xd_grps[] = {"xd"};
+static const char * const p168_lcd_grps[] = {"lcd"};
+static const char * const p168_dfio_grps[] = {"dfio"};
+static const char * const p168_nand_grps[] = {"nand"};
+static const char * const p168_smc_grps[] = {"smc"};
+static const char * const p168_smccs0_grps[] = {"smc cs0"};
+static const char * const p168_smccs1_grps[] = {"smc cs1"};
+static const char * const p168_smcrdy_grps[] = {"smc rdy"};
+static const char * const p168_ac97sysclk_grps[] = {"ac97 sysclk"};
+static const char * const p168_ac97_grps[] = {"ac97"};
+static const char * const p168_cf_grps[] = {"cf"};
+static const char * const p168_kpmkin_grps[] = {"kp mkin 3p1"};
+static const char * const p168_kpmkout_grps[] = {"kp mkout 2p1"};
+static const char * const p168_gpio86_grps[] = {"gpio86-1", "gpio86-2"};
+static const char * const p168_gpio87_grps[] = {"gpio87-1", "gpio87-2"};
+static const char * const p168_gpio88_grps[] = {"gpio88-1", "gpio88-2"};
+
+static struct pxa3xx_pmx_func pxa168_funcs[] = {
+	{"uart1 rx",	ARRAY_AND_SIZE(p168_uart1rx_grps)},
+	{"uart1 tx",	ARRAY_AND_SIZE(p168_uart1tx_grps)},
+	{"uart3 rx",	ARRAY_AND_SIZE(p168_uart3rx_grps)},
+	{"uart3 tx",	ARRAY_AND_SIZE(p168_uart3tx_grps)},
+	{"ssp1 rx",	ARRAY_AND_SIZE(p168_ssp1rx_grps)},
+	{"ssp1 tx",	ARRAY_AND_SIZE(p168_ssp1tx_grps)},
+	{"ssp4 rx",	ARRAY_AND_SIZE(p168_ssp4rx_grps)},
+	{"ssp4 tx",	ARRAY_AND_SIZE(p168_ssp4tx_grps)},
+	{"ssp5 rx",	ARRAY_AND_SIZE(p168_ssp5rx_grps)},
+	{"ssp5 tx",	ARRAY_AND_SIZE(p168_ssp5tx_grps)},
+	{"i2c",		ARRAY_AND_SIZE(p168_i2c_grps)},
+	{"pwri2c",	ARRAY_AND_SIZE(p168_pwri2c_grps)},
+	{"mmc1",	ARRAY_AND_SIZE(p168_mmc1_grps)},
+	{"mmc2",	ARRAY_AND_SIZE(p168_mmc2_data_grps)},
+	{"mmc2 cmd",	ARRAY_AND_SIZE(p168_mmc2_cmd_grps)},
+	{"mmc2 clk",	ARRAY_AND_SIZE(p168_mmc2_clk_grps)},
+	{"mmc3",	ARRAY_AND_SIZE(p168_mmc3_data_grps)},
+	{"mmc3 cmd",	ARRAY_AND_SIZE(p168_mmc3_cmd_grps)},
+	{"mmc3 clk",	ARRAY_AND_SIZE(p168_mmc3_clk_grps)},
+	{"eth",		ARRAY_AND_SIZE(p168_eth_grps)},
+	{"eth rx",	ARRAY_AND_SIZE(p168_ethrx_grps)},
+	{"eth tx",	ARRAY_AND_SIZE(p168_ethtx_grps)},
+	{"msp",		ARRAY_AND_SIZE(p168_msp_grps)},
+	{"ccic",	ARRAY_AND_SIZE(p168_ccic_grps)},
+	{"xd",		ARRAY_AND_SIZE(p168_xd_grps)},
+	{"lcd",		ARRAY_AND_SIZE(p168_lcd_grps)},
+	{"dfio",	ARRAY_AND_SIZE(p168_dfio_grps)},
+	{"nand",	ARRAY_AND_SIZE(p168_nand_grps)},
+	{"smc",		ARRAY_AND_SIZE(p168_smc_grps)},
+	{"smc cs0",	ARRAY_AND_SIZE(p168_smccs0_grps)},
+	{"smc cs1",	ARRAY_AND_SIZE(p168_smccs1_grps)},
+	{"smc rdy",	ARRAY_AND_SIZE(p168_smcrdy_grps)},
+	{"ac97",	ARRAY_AND_SIZE(p168_ac97_grps)},
+	{"ac97 sysclk",	ARRAY_AND_SIZE(p168_ac97sysclk_grps)},
+	{"cf",		ARRAY_AND_SIZE(p168_cf_grps)},
+	{"kpmkin",	ARRAY_AND_SIZE(p168_kpmkin_grps)},
+	{"kpmkout",	ARRAY_AND_SIZE(p168_kpmkout_grps)},
+	{"gpio86",	ARRAY_AND_SIZE(p168_gpio86_grps)},
+	{"gpio87",	ARRAY_AND_SIZE(p168_gpio87_grps)},
+	{"gpio88",	ARRAY_AND_SIZE(p168_gpio88_grps)},
+};
+
+static struct pinctrl_desc pxa168_pctrl_desc = {
+	.name		= "pxa168-pinctrl",
+	.owner		= THIS_MODULE,
+};
+
+static struct pxa3xx_pinmux_info pxa168_info = {
+	.mfp		= pxa168_mfp,
+	.num_mfp	= ARRAY_SIZE(pxa168_mfp),
+	.grps		= pxa168_grps,
+	.num_grps	= ARRAY_SIZE(pxa168_grps),
+	.funcs		= pxa168_funcs,
+	.num_funcs	= ARRAY_SIZE(pxa168_funcs),
+	.num_gpio	= 128,
+	.desc		= &pxa168_pctrl_desc,
+	.pads		= pxa168_pads,
+	.num_pads	= ARRAY_SIZE(pxa168_pads),
+
+	.cputype	= PINCTRL_PXA168,
+	.ds_mask	= PXA168_DS_MASK,
+	.ds_shift	= PXA168_DS_SHIFT,
+};
+
+static int __devinit pxa168_pinmux_probe(struct platform_device *pdev)
+{
+	return pxa3xx_pinctrl_register(pdev, &pxa168_info);
+}
+
+static int __devexit pxa168_pinmux_remove(struct platform_device *pdev)
+{
+	return pxa3xx_pinctrl_unregister(pdev);
+}
+
+static struct platform_driver pxa168_pinmux_driver = {
+	.driver = {
+		.name	= "pxa168-pinmux",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= pxa168_pinmux_probe,
+	.remove	= __devexit_p(pxa168_pinmux_remove),
+};
+
+static int __init pxa168_pinmux_init(void)
+{
+	return platform_driver_register(&pxa168_pinmux_driver);
+}
+core_initcall_sync(pxa168_pinmux_init);
+
+static void __exit pxa168_pinmux_exit(void)
+{
+	platform_driver_unregister(&pxa168_pinmux_driver);
+}
+module_exit(pxa168_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c
new file mode 100644
index 0000000..079dce0
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa3xx.c
@@ -0,0 +1,244 @@
+/*
+ *  linux/drivers/pinctrl/pinctrl-pxa3xx.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "pinctrl-pxa3xx.h"
+
+static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
+	.name		= "PXA3xx GPIO",
+	.id		= 0,
+	.base		= 0,
+	.pin_base	= 0,
+};
+
+static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector >= info->num_grps)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
+					 unsigned selector)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector >= info->num_grps)
+		return NULL;
+	return info->grps[selector].name;
+}
+
+static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
+				 unsigned selector,
+				 const unsigned **pins,
+				 unsigned *num_pins)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector >= info->num_grps)
+		return -EINVAL;
+	*pins = info->grps[selector].pins;
+	*num_pins = info->grps[selector].npins;
+	return 0;
+}
+
+static struct pinctrl_ops pxa3xx_pctrl_ops = {
+	.list_groups	= pxa3xx_list_groups,
+	.get_group_name	= pxa3xx_get_group_name,
+	.get_group_pins	= pxa3xx_get_group_pins,
+};
+
+static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (func >= info->num_funcs)
+		return -EINVAL;
+	return 0;
+}
+
+static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
+					    unsigned func)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	return info->funcs[func].name;
+}
+
+static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
+				 const char * const **groups,
+				 unsigned * const num_groups)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	*groups = info->funcs[func].groups;
+	*num_groups = info->funcs[func].num_groups;
+	return 0;
+}
+
+/* Return function number. If failure, return negative value. */
+static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux)
+{
+	int i;
+	for (i = 0; i < PXA3xx_MAX_MUX; i++) {
+		if (mfp->func[i] == mux)
+			break;
+	}
+	if (i >= PXA3xx_MAX_MUX)
+		return -EINVAL;
+	return i;
+}
+
+/* check whether current pin configuration is valid. Negative for failure */
+static int match_group_mux(struct pxa3xx_pin_group *grp,
+			   struct pxa3xx_pinmux_info *info,
+			   unsigned mux)
+{
+	int i, pin, ret = 0;
+	for (i = 0; i < grp->npins; i++) {
+		pin = grp->pins[i];
+		ret = match_mux(&info->mfp[pin], mux);
+		if (ret < 0) {
+			dev_err(info->dev, "Can't find mux %d on pin%d\n",
+				mux, pin);
+			break;
+		}
+	}
+	return ret;
+}
+
+static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
+			     unsigned group)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	struct pxa3xx_pin_group *pin_grp = &info->grps[group];
+	unsigned int data;
+	int i, mfpr, pin, pin_func;
+
+	if (!pin_grp->npins ||
+		(match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
+		dev_err(info->dev, "Failed to set the pin group: %d\n", group);
+		return -EINVAL;
+	}
+	for (i = 0; i < pin_grp->npins; i++) {
+		pin = pin_grp->pins[i];
+		pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
+		mfpr = info->mfp[pin].mfpr;
+		data = readl_relaxed(info->virt_base + mfpr);
+		data &= ~MFPR_FUNC_MASK;
+		data |= pin_func;
+		writel_relaxed(data, info->virt_base + mfpr);
+	}
+	return 0;
+}
+
+static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
+			       unsigned group)
+{
+}
+
+static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
+				   struct pinctrl_gpio_range *range,
+				   unsigned pin)
+{
+	struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	unsigned int data;
+	int pin_func, mfpr;
+
+	pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO);
+	if (pin_func < 0) {
+		dev_err(info->dev, "No GPIO function on pin%d (%s)\n",
+			pin, info->pads[pin].name);
+		return -EINVAL;
+	}
+	mfpr = info->mfp[pin].mfpr;
+	/* write gpio function into mfpr register */
+	data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK;
+	data |= pin_func;
+	writel_relaxed(data, info->virt_base + mfpr);
+	return 0;
+}
+
+static struct pinmux_ops pxa3xx_pmx_ops = {
+	.list_functions		= pxa3xx_pmx_list_func,
+	.get_function_name	= pxa3xx_pmx_get_func_name,
+	.get_function_groups	= pxa3xx_pmx_get_groups,
+	.enable			= pxa3xx_pmx_enable,
+	.disable		= pxa3xx_pmx_disable,
+	.gpio_request_enable	= pxa3xx_pmx_request_gpio,
+};
+
+int pxa3xx_pinctrl_register(struct platform_device *pdev,
+			    struct pxa3xx_pinmux_info *info)
+{
+	struct pinctrl_desc *desc;
+	struct resource *res;
+	int ret = 0;
+
+	if (!info || !info->cputype)
+		return -EINVAL;
+	desc = info->desc;
+	desc->pins = info->pads;
+	desc->npins = info->num_pads;
+	desc->pctlops = &pxa3xx_pctrl_ops;
+	desc->pmxops = &pxa3xx_pmx_ops;
+	info->dev = &pdev->dev;
+	pxa3xx_pinctrl_gpio_range.npins = info->num_gpio;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+	info->phy_base = res->start;
+	info->phy_size = resource_size(res);
+	info->virt_base = ioremap(info->phy_base, info->phy_size);
+	if (!info->virt_base)
+		return -ENOMEM;
+	info->pctrl = pinctrl_register(desc, &pdev->dev, info);
+	if (!info->pctrl) {
+		dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
+	platform_set_drvdata(pdev, info);
+	return 0;
+err:
+	iounmap(info->virt_base);
+	return ret;
+}
+
+int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
+{
+	struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
+
+	pinctrl_unregister(info->pctrl);
+	iounmap(info->virt_base);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static int __init pxa3xx_pinctrl_init(void)
+{
+	pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n");
+	return 0;
+}
+core_initcall_sync(pxa3xx_pinctrl_init);
+
+static void __exit pxa3xx_pinctrl_exit(void)
+{
+}
+module_exit(pxa3xx_pinctrl_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h
new file mode 100644
index 0000000..8135744
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa3xx.h
@@ -0,0 +1,264 @@
+/*
+ *  linux/drivers/pinctrl/pinctrl-pxa3xx.h
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#ifndef __PINCTRL_PXA3XX_H
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
+
+#define PXA3xx_MUX_GPIO		0
+
+#define PXA3xx_MAX_MUX		8
+#define MFPR_FUNC_MASK		0x7
+
+enum pxa_cpu_type {
+	PINCTRL_INVALID = 0,
+	PINCTRL_PXA300,
+	PINCTRL_PXA310,
+	PINCTRL_PXA320,
+	PINCTRL_PXA168,
+	PINCTRL_PXA910,
+	PINCTRL_PXA930,
+	PINCTRL_PXA955,
+	PINCTRL_MMP2,
+	PINCTRL_MAX,
+};
+
+struct pxa3xx_mfp_pin {
+	const char *name;
+	const unsigned int pin;
+	const unsigned int mfpr;	/* register offset */
+	const unsigned short func[8];
+};
+
+struct pxa3xx_pin_group {
+	const char *name;
+	const unsigned mux;
+	const unsigned *pins;
+	const unsigned npins;
+};
+
+struct pxa3xx_pmx_func {
+	const char *name;
+	const char * const * groups;
+	const unsigned num_groups;
+};
+
+struct pxa3xx_pinmux_info {
+	struct device *dev;
+	struct pinctrl_dev *pctrl;
+	enum pxa_cpu_type cputype;
+	unsigned int phy_base;
+	unsigned int phy_size;
+	void __iomem *virt_base;
+
+	struct pxa3xx_mfp_pin *mfp;
+	unsigned int num_mfp;
+	struct pxa3xx_pin_group *grps;
+	unsigned int num_grps;
+	struct pxa3xx_pmx_func *funcs;
+	unsigned int num_funcs;
+	unsigned int num_gpio;
+	struct pinctrl_desc *desc;
+	struct pinctrl_pin_desc *pads;
+	unsigned int num_pads;
+
+	unsigned ds_mask;	/* drive strength mask */
+	unsigned ds_shift;	/* drive strength shift */
+	unsigned slp_mask;	/* sleep mask */
+	unsigned slp_input_low;
+	unsigned slp_input_high;
+	unsigned slp_output_low;
+	unsigned slp_output_high;
+	unsigned slp_float;
+};
+
+enum pxa3xx_pin_list {
+	GPIO0 = 0,
+	GPIO1,
+	GPIO2,
+	GPIO3,
+	GPIO4,
+	GPIO5,
+	GPIO6,
+	GPIO7,
+	GPIO8,
+	GPIO9,
+	GPIO10, /* 10 */
+	GPIO11,
+	GPIO12,
+	GPIO13,
+	GPIO14,
+	GPIO15,
+	GPIO16,
+	GPIO17,
+	GPIO18,
+	GPIO19,
+	GPIO20, /* 20 */
+	GPIO21,
+	GPIO22,
+	GPIO23,
+	GPIO24,
+	GPIO25,
+	GPIO26,
+	GPIO27,
+	GPIO28,
+	GPIO29,
+	GPIO30, /* 30 */
+	GPIO31,
+	GPIO32,
+	GPIO33,
+	GPIO34,
+	GPIO35,
+	GPIO36,
+	GPIO37,
+	GPIO38,
+	GPIO39,
+	GPIO40, /* 40 */
+	GPIO41,
+	GPIO42,
+	GPIO43,
+	GPIO44,
+	GPIO45,
+	GPIO46,
+	GPIO47,
+	GPIO48,
+	GPIO49,
+	GPIO50, /* 50 */
+	GPIO51,
+	GPIO52,
+	GPIO53,
+	GPIO54,
+	GPIO55,
+	GPIO56,
+	GPIO57,
+	GPIO58,
+	GPIO59,
+	GPIO60, /* 60 */
+	GPIO61,
+	GPIO62,
+	GPIO63,
+	GPIO64,
+	GPIO65,
+	GPIO66,
+	GPIO67,
+	GPIO68,
+	GPIO69,
+	GPIO70, /* 70 */
+	GPIO71,
+	GPIO72,
+	GPIO73,
+	GPIO74,
+	GPIO75,
+	GPIO76,
+	GPIO77,
+	GPIO78,
+	GPIO79,
+	GPIO80, /* 80 */
+	GPIO81,
+	GPIO82,
+	GPIO83,
+	GPIO84,
+	GPIO85,
+	GPIO86,
+	GPIO87,
+	GPIO88,
+	GPIO89,
+	GPIO90, /* 90 */
+	GPIO91,
+	GPIO92,
+	GPIO93,
+	GPIO94,
+	GPIO95,
+	GPIO96,
+	GPIO97,
+	GPIO98,
+	GPIO99,
+	GPIO100, /* 100 */
+	GPIO101,
+	GPIO102,
+	GPIO103,
+	GPIO104,
+	GPIO105,
+	GPIO106,
+	GPIO107,
+	GPIO108,
+	GPIO109,
+	GPIO110, /* 110 */
+	GPIO111,
+	GPIO112,
+	GPIO113,
+	GPIO114,
+	GPIO115,
+	GPIO116,
+	GPIO117,
+	GPIO118,
+	GPIO119,
+	GPIO120, /* 120 */
+	GPIO121,
+	GPIO122,
+	GPIO123,
+	GPIO124,
+	GPIO125,
+	GPIO126,
+	GPIO127,
+	GPIO128,
+	GPIO129,
+	GPIO130, /* 130 */
+	GPIO131,
+	GPIO132,
+	GPIO133,
+	GPIO134,
+	GPIO135,
+	GPIO136,
+	GPIO137,
+	GPIO138,
+	GPIO139,
+	GPIO140, /* 140 */
+	GPIO141,
+	GPIO142,
+	GPIO143,
+	GPIO144,
+	GPIO145,
+	GPIO146,
+	GPIO147,
+	GPIO148,
+	GPIO149,
+	GPIO150, /* 150 */
+	GPIO151,
+	GPIO152,
+	GPIO153,
+	GPIO154,
+	GPIO155,
+	GPIO156,
+	GPIO157,
+	GPIO158,
+	GPIO159,
+	GPIO160, /* 160 */
+	GPIO161,
+	GPIO162,
+	GPIO163,
+	GPIO164,
+	GPIO165,
+	GPIO166,
+	GPIO167,
+	GPIO168,
+	GPIO169,
+};
+
+extern int pxa3xx_pinctrl_register(struct platform_device *pdev,
+				   struct pxa3xx_pinmux_info *info);
+extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev);
+#endif	/* __PINCTRL_PXA3XX_H */
diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c
new file mode 100644
index 0000000..c72ab4b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa910.c
@@ -0,0 +1,1007 @@
+/*
+ *  linux/drivers/pinctrl/pinmux-pxa910.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ *  Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "pinctrl-pxa3xx.h"
+
+#define PXA910_DS_MASK		0x1800
+#define PXA910_DS_SHIFT		11
+#define PXA910_SLEEP_MASK	0x38
+#define PXA910_SLEEP_SELECT	(1 << 9)
+#define PXA910_SLEEP_DATA	(1 << 8)
+#define PXA910_SLEEP_DIR	(1 << 7)
+
+#define MFPR_910(a, r, f0, f1, f2, f3, f4, f5, f6, f7)		\
+	{							\
+		.name = #a,					\
+		.pin = a,					\
+		.mfpr = r,					\
+		.func = {					\
+			PXA910_MUX_##f0,			\
+			PXA910_MUX_##f1,			\
+			PXA910_MUX_##f2,			\
+			PXA910_MUX_##f3,			\
+			PXA910_MUX_##f4,			\
+			PXA910_MUX_##f5,			\
+			PXA910_MUX_##f6,			\
+			PXA910_MUX_##f7,			\
+		},						\
+	}
+
+#define GRP_910(a, m, p)		\
+	{ .name = a, .mux = PXA910_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+/* 170 pins */
+enum pxa910_pin_list {
+	/* 0~127: GPIO0~GPIO127 */
+	ND_IO15 = 128,
+	ND_IO14,
+	ND_IO13, /* 130 */
+	ND_IO12,
+	ND_IO11,
+	ND_IO10,
+	ND_IO9,
+	ND_IO8,
+	ND_IO7,
+	ND_IO6,
+	ND_IO5,
+	ND_IO4,
+	ND_IO3, /* 140 */
+	ND_IO2,
+	ND_IO1,
+	ND_IO0,
+	ND_NCS0,
+	ND_NCS1,
+	SM_NCS0,
+	SM_NCS1,
+	ND_NWE,
+	ND_NRE,
+	ND_CLE, /* 150 */
+	ND_ALE,
+	SM_SCLK,
+	ND_RDY0,
+	SM_ADV,
+	ND_RDY1,
+	SM_ADVMUX,
+	SM_RDY,
+	MMC1_DAT7,
+	MMC1_DAT6,
+	MMC1_DAT5, /* 160 */
+	MMC1_DAT4,
+	MMC1_DAT3,
+	MMC1_DAT2,
+	MMC1_DAT1,
+	MMC1_DAT0,
+	MMC1_CMD,
+	MMC1_CLK,
+	MMC1_CD,
+	VCXO_OUT,
+};
+
+enum pxa910_mux {
+	/* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
+	PXA910_MUX_GPIO = 0,
+	PXA910_MUX_NAND,
+	PXA910_MUX_USIM2,
+	PXA910_MUX_EXT_DMA,
+	PXA910_MUX_EXT_INT,
+	PXA910_MUX_MMC1,
+	PXA910_MUX_MMC2,
+	PXA910_MUX_MMC3,
+	PXA910_MUX_SM_INT,
+	PXA910_MUX_PRI_JTAG,
+	PXA910_MUX_SEC1_JTAG,
+	PXA910_MUX_SEC2_JTAG,
+	PXA910_MUX_RESET,	/* SLAVE RESET OUT */
+	PXA910_MUX_CLK_REQ,
+	PXA910_MUX_VCXO_REQ,
+	PXA910_MUX_VCXO_OUT,
+	PXA910_MUX_VCXO_REQ2,
+	PXA910_MUX_VCXO_OUT2,
+	PXA910_MUX_SPI,
+	PXA910_MUX_SPI2,
+	PXA910_MUX_GSSP,
+	PXA910_MUX_SSP0,
+	PXA910_MUX_SSP1,
+	PXA910_MUX_SSP2,
+	PXA910_MUX_DSSP2,
+	PXA910_MUX_DSSP3,
+	PXA910_MUX_UART0,
+	PXA910_MUX_UART1,
+	PXA910_MUX_UART2,
+	PXA910_MUX_TWSI,
+	PXA910_MUX_CCIC,
+	PXA910_MUX_PWM0,
+	PXA910_MUX_PWM1,
+	PXA910_MUX_PWM2,
+	PXA910_MUX_PWM3,
+	PXA910_MUX_HSL,
+	PXA910_MUX_ONE_WIRE,
+	PXA910_MUX_LCD,
+	PXA910_MUX_DAC_ST23,
+	PXA910_MUX_ULPI,
+	PXA910_MUX_TB,
+	PXA910_MUX_KP_MK,
+	PXA910_MUX_KP_DK,
+	PXA910_MUX_TCU_GPOA,
+	PXA910_MUX_TCU_GPOB,
+	PXA910_MUX_ROT,
+	PXA910_MUX_TDS,
+	PXA910_MUX_32K_CLK, /* 32KHz CLK OUT */
+	PXA910_MUX_MN_CLK, /* MN CLK OUT */
+	PXA910_MUX_SMC,
+	PXA910_MUX_SM_ADDR18,
+	PXA910_MUX_SM_ADDR19,
+	PXA910_MUX_SM_ADDR20,
+	PXA910_MUX_NONE = 0xffff,
+};
+
+
+static struct pinctrl_pin_desc pxa910_pads[] = {
+	PINCTRL_PIN(GPIO0, "GPIO0"),
+	PINCTRL_PIN(GPIO1, "GPIO1"),
+	PINCTRL_PIN(GPIO2, "GPIO2"),
+	PINCTRL_PIN(GPIO3, "GPIO3"),
+	PINCTRL_PIN(GPIO4, "GPIO4"),
+	PINCTRL_PIN(GPIO5, "GPIO5"),
+	PINCTRL_PIN(GPIO6, "GPIO6"),
+	PINCTRL_PIN(GPIO7, "GPIO7"),
+	PINCTRL_PIN(GPIO8, "GPIO8"),
+	PINCTRL_PIN(GPIO9, "GPIO9"),
+	PINCTRL_PIN(GPIO10, "GPIO10"),
+	PINCTRL_PIN(GPIO11, "GPIO11"),
+	PINCTRL_PIN(GPIO12, "GPIO12"),
+	PINCTRL_PIN(GPIO13, "GPIO13"),
+	PINCTRL_PIN(GPIO14, "GPIO14"),
+	PINCTRL_PIN(GPIO15, "GPIO15"),
+	PINCTRL_PIN(GPIO16, "GPIO16"),
+	PINCTRL_PIN(GPIO17, "GPIO17"),
+	PINCTRL_PIN(GPIO18, "GPIO18"),
+	PINCTRL_PIN(GPIO19, "GPIO19"),
+	PINCTRL_PIN(GPIO20, "GPIO20"),
+	PINCTRL_PIN(GPIO21, "GPIO21"),
+	PINCTRL_PIN(GPIO22, "GPIO22"),
+	PINCTRL_PIN(GPIO23, "GPIO23"),
+	PINCTRL_PIN(GPIO24, "GPIO24"),
+	PINCTRL_PIN(GPIO25, "GPIO25"),
+	PINCTRL_PIN(GPIO26, "GPIO26"),
+	PINCTRL_PIN(GPIO27, "GPIO27"),
+	PINCTRL_PIN(GPIO28, "GPIO28"),
+	PINCTRL_PIN(GPIO29, "GPIO29"),
+	PINCTRL_PIN(GPIO30, "GPIO30"),
+	PINCTRL_PIN(GPIO31, "GPIO31"),
+	PINCTRL_PIN(GPIO32, "GPIO32"),
+	PINCTRL_PIN(GPIO33, "GPIO33"),
+	PINCTRL_PIN(GPIO34, "GPIO34"),
+	PINCTRL_PIN(GPIO35, "GPIO35"),
+	PINCTRL_PIN(GPIO36, "GPIO36"),
+	PINCTRL_PIN(GPIO37, "GPIO37"),
+	PINCTRL_PIN(GPIO38, "GPIO38"),
+	PINCTRL_PIN(GPIO39, "GPIO39"),
+	PINCTRL_PIN(GPIO40, "GPIO40"),
+	PINCTRL_PIN(GPIO41, "GPIO41"),
+	PINCTRL_PIN(GPIO42, "GPIO42"),
+	PINCTRL_PIN(GPIO43, "GPIO43"),
+	PINCTRL_PIN(GPIO44, "GPIO44"),
+	PINCTRL_PIN(GPIO45, "GPIO45"),
+	PINCTRL_PIN(GPIO46, "GPIO46"),
+	PINCTRL_PIN(GPIO47, "GPIO47"),
+	PINCTRL_PIN(GPIO48, "GPIO48"),
+	PINCTRL_PIN(GPIO49, "GPIO49"),
+	PINCTRL_PIN(GPIO50, "GPIO50"),
+	PINCTRL_PIN(GPIO51, "GPIO51"),
+	PINCTRL_PIN(GPIO52, "GPIO52"),
+	PINCTRL_PIN(GPIO53, "GPIO53"),
+	PINCTRL_PIN(GPIO54, "GPIO54"),
+	PINCTRL_PIN(GPIO55, "GPIO55"),
+	PINCTRL_PIN(GPIO56, "GPIO56"),
+	PINCTRL_PIN(GPIO57, "GPIO57"),
+	PINCTRL_PIN(GPIO58, "GPIO58"),
+	PINCTRL_PIN(GPIO59, "GPIO59"),
+	PINCTRL_PIN(GPIO60, "GPIO60"),
+	PINCTRL_PIN(GPIO61, "GPIO61"),
+	PINCTRL_PIN(GPIO62, "GPIO62"),
+	PINCTRL_PIN(GPIO63, "GPIO63"),
+	PINCTRL_PIN(GPIO64, "GPIO64"),
+	PINCTRL_PIN(GPIO65, "GPIO65"),
+	PINCTRL_PIN(GPIO66, "GPIO66"),
+	PINCTRL_PIN(GPIO67, "GPIO67"),
+	PINCTRL_PIN(GPIO68, "GPIO68"),
+	PINCTRL_PIN(GPIO69, "GPIO69"),
+	PINCTRL_PIN(GPIO70, "GPIO70"),
+	PINCTRL_PIN(GPIO71, "GPIO71"),
+	PINCTRL_PIN(GPIO72, "GPIO72"),
+	PINCTRL_PIN(GPIO73, "GPIO73"),
+	PINCTRL_PIN(GPIO74, "GPIO74"),
+	PINCTRL_PIN(GPIO75, "GPIO75"),
+	PINCTRL_PIN(GPIO76, "GPIO76"),
+	PINCTRL_PIN(GPIO77, "GPIO77"),
+	PINCTRL_PIN(GPIO78, "GPIO78"),
+	PINCTRL_PIN(GPIO79, "GPIO79"),
+	PINCTRL_PIN(GPIO80, "GPIO80"),
+	PINCTRL_PIN(GPIO81, "GPIO81"),
+	PINCTRL_PIN(GPIO82, "GPIO82"),
+	PINCTRL_PIN(GPIO83, "GPIO83"),
+	PINCTRL_PIN(GPIO84, "GPIO84"),
+	PINCTRL_PIN(GPIO85, "GPIO85"),
+	PINCTRL_PIN(GPIO86, "GPIO86"),
+	PINCTRL_PIN(GPIO87, "GPIO87"),
+	PINCTRL_PIN(GPIO88, "GPIO88"),
+	PINCTRL_PIN(GPIO89, "GPIO89"),
+	PINCTRL_PIN(GPIO90, "GPIO90"),
+	PINCTRL_PIN(GPIO91, "GPIO91"),
+	PINCTRL_PIN(GPIO92, "GPIO92"),
+	PINCTRL_PIN(GPIO93, "GPIO93"),
+	PINCTRL_PIN(GPIO94, "GPIO94"),
+	PINCTRL_PIN(GPIO95, "GPIO95"),
+	PINCTRL_PIN(GPIO96, "GPIO96"),
+	PINCTRL_PIN(GPIO97, "GPIO97"),
+	PINCTRL_PIN(GPIO98, "GPIO98"),
+	PINCTRL_PIN(GPIO99, "GPIO99"),
+	PINCTRL_PIN(GPIO100, "GPIO100"),
+	PINCTRL_PIN(GPIO101, "GPIO101"),
+	PINCTRL_PIN(GPIO102, "GPIO102"),
+	PINCTRL_PIN(GPIO103, "GPIO103"),
+	PINCTRL_PIN(GPIO104, "GPIO104"),
+	PINCTRL_PIN(GPIO105, "GPIO105"),
+	PINCTRL_PIN(GPIO106, "GPIO106"),
+	PINCTRL_PIN(GPIO107, "GPIO107"),
+	PINCTRL_PIN(GPIO108, "GPIO108"),
+	PINCTRL_PIN(GPIO109, "GPIO109"),
+	PINCTRL_PIN(GPIO110, "GPIO110"),
+	PINCTRL_PIN(GPIO111, "GPIO111"),
+	PINCTRL_PIN(GPIO112, "GPIO112"),
+	PINCTRL_PIN(GPIO113, "GPIO113"),
+	PINCTRL_PIN(GPIO114, "GPIO114"),
+	PINCTRL_PIN(GPIO115, "GPIO115"),
+	PINCTRL_PIN(GPIO116, "GPIO116"),
+	PINCTRL_PIN(GPIO117, "GPIO117"),
+	PINCTRL_PIN(GPIO118, "GPIO118"),
+	PINCTRL_PIN(GPIO119, "GPIO119"),
+	PINCTRL_PIN(GPIO120, "GPIO120"),
+	PINCTRL_PIN(GPIO121, "GPIO121"),
+	PINCTRL_PIN(GPIO122, "GPIO122"),
+	PINCTRL_PIN(GPIO123, "GPIO123"),
+	PINCTRL_PIN(GPIO124, "GPIO124"),
+	PINCTRL_PIN(GPIO125, "GPIO125"),
+	PINCTRL_PIN(GPIO126, "GPIO126"),
+	PINCTRL_PIN(GPIO127, "GPIO127"),
+	PINCTRL_PIN(ND_IO15, "ND_IO15"),
+	PINCTRL_PIN(ND_IO14, "ND_IO14"),
+	PINCTRL_PIN(ND_IO13, "ND_IO13"),
+	PINCTRL_PIN(ND_IO12, "ND_IO12"),
+	PINCTRL_PIN(ND_IO11, "ND_IO11"),
+	PINCTRL_PIN(ND_IO10, "ND_IO10"),
+	PINCTRL_PIN(ND_IO9, "ND_IO9"),
+	PINCTRL_PIN(ND_IO8, "ND_IO8"),
+	PINCTRL_PIN(ND_IO7, "ND_IO7"),
+	PINCTRL_PIN(ND_IO6, "ND_IO6"),
+	PINCTRL_PIN(ND_IO5, "ND_IO5"),
+	PINCTRL_PIN(ND_IO4, "ND_IO4"),
+	PINCTRL_PIN(ND_IO3, "ND_IO3"),
+	PINCTRL_PIN(ND_IO2, "ND_IO2"),
+	PINCTRL_PIN(ND_IO1, "ND_IO1"),
+	PINCTRL_PIN(ND_IO0, "ND_IO0"),
+	PINCTRL_PIN(ND_NCS0, "ND_NCS0_SM_NCS2"),
+	PINCTRL_PIN(ND_NCS1, "ND_NCS1_SM_NCS3"),
+	PINCTRL_PIN(SM_NCS0, "SM_NCS0"),
+	PINCTRL_PIN(SM_NCS1, "SM_NCS1"),
+	PINCTRL_PIN(ND_NWE, "ND_NWE"),
+	PINCTRL_PIN(ND_NRE, "ND_NRE"),
+	PINCTRL_PIN(ND_CLE, "ND_CLE_SM_NOE"),
+	PINCTRL_PIN(ND_ALE, "ND_ALE_SM_NWE"),
+	PINCTRL_PIN(SM_SCLK, "SM_SCLK"),
+	PINCTRL_PIN(ND_RDY0, "ND_RDY0"),
+	PINCTRL_PIN(SM_ADV, "SM_ADV"),
+	PINCTRL_PIN(ND_RDY1, "ND_RDY1"),
+	PINCTRL_PIN(SM_RDY, "SM_RDY"),
+	PINCTRL_PIN(MMC1_DAT7, "MMC1_DAT7"),
+	PINCTRL_PIN(MMC1_DAT6, "MMC1_DAT6"),
+	PINCTRL_PIN(MMC1_DAT5, "MMC1_DAT5"),
+	PINCTRL_PIN(MMC1_DAT4, "MMC1_DAT4"),
+	PINCTRL_PIN(MMC1_DAT3, "MMC1_DAT3"),
+	PINCTRL_PIN(MMC1_DAT2, "MMC1_DAT2"),
+	PINCTRL_PIN(MMC1_DAT1, "MMC1_DAT1"),
+	PINCTRL_PIN(MMC1_DAT0, "MMC1_DAT0"),
+	PINCTRL_PIN(MMC1_CMD, "MMC1 CMD"),
+	PINCTRL_PIN(MMC1_CLK, "MMC1 CLK"),
+	PINCTRL_PIN(MMC1_CD, "MMC1 CD"),
+	PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"),
+};
+
+struct pxa3xx_mfp_pin pxa910_mfp[] = {
+	/*       pin        offs   f0        f1      f2         f3         f4         f5        f6        f7  */
+	MFPR_910(GPIO0,     0x0DC, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO1,     0x0E0, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO2,     0x0E4, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO3,     0x0E8, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO4,     0x0EC, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO5,     0x0F0, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO6,     0x0F4, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO7,     0x0F8, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO8,     0x0FC, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO9,     0x100, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO10,    0x104, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO11,    0x108, GPIO,     KP_MK,  NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO12,    0x10C, GPIO,     KP_MK,  NONE,      NONE,      KP_DK,     NONE,     NONE,     NONE),
+	MFPR_910(GPIO13,    0x110, GPIO,     KP_MK,  NONE,      NONE,      KP_DK,     NONE,     NONE,     NONE),
+	MFPR_910(GPIO14,    0x114, GPIO,     KP_MK,  NONE,      NONE,      KP_DK,     TB,       NONE,     NONE),
+	MFPR_910(GPIO15,    0x118, GPIO,     KP_MK,  NONE,      NONE,      KP_DK,     TB,       NONE,     NONE),
+	MFPR_910(GPIO16,    0x11C, GPIO,     KP_DK,  NONE,      NONE,      NONE,      TB,       NONE,     NONE),
+	MFPR_910(GPIO17,    0x120, GPIO,     KP_DK,  NONE,      NONE,      NONE,      TB,       NONE,     NONE),
+	MFPR_910(GPIO18,    0x124, GPIO,     KP_DK,  NONE,      NONE,      ROT,       NONE,     NONE,     NONE),
+	MFPR_910(GPIO19,    0x128, GPIO,     KP_DK,  NONE,      NONE,      ROT,       NONE,     NONE,     NONE),
+	MFPR_910(GPIO20,    0x12C, GPIO,     SSP1,   NONE,      NONE,      VCXO_OUT,  NONE,     NONE,     NONE),
+	MFPR_910(GPIO21,    0x130, GPIO,     SSP1,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO22,    0x134, GPIO,     SSP1,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO23,    0x138, GPIO,     SSP1,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO24,    0x13C, GPIO,     SSP1,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO25,    0x140, GPIO,     GSSP,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO26,    0x144, GPIO,     GSSP,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO27,    0x148, GPIO,     GSSP,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO28,    0x14C, GPIO,     GSSP,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO29,    0x150, GPIO,     UART0,  NONE,      NONE,      UART1,     NONE,     NONE,     NONE),
+	MFPR_910(GPIO30,    0x154, GPIO,     UART0,  NONE,      NONE,      UART1,     NONE,     NONE,     NONE),
+	MFPR_910(GPIO31,    0x158, GPIO,     UART0,  NONE,      NONE,      UART1,     NONE,     NONE,     NONE),
+	MFPR_910(GPIO32,    0x15C, GPIO,     UART0,  DAC_ST23,  NONE,      UART1,     NONE,     NONE,     NONE),
+	MFPR_910(GPIO33,    0x160, GPIO,     MMC2,   SSP0,      SSP2,      NONE,      SPI,      NONE,     MMC3),
+	MFPR_910(GPIO34,    0x164, GPIO,     MMC2,   SSP0,      SSP2,      NONE,      SPI,      NONE,     MMC3),
+	MFPR_910(GPIO35,    0x168, GPIO,     MMC2,   SSP0,      SSP2,      NONE,      SPI,      NONE,     MMC3),
+	MFPR_910(GPIO36,    0x16C, GPIO,     MMC2,   SSP0,      SSP2,      NONE,      SPI,      NONE,     MMC3),
+	MFPR_910(GPIO37,    0x170, GPIO,     MMC2,   NONE,      NONE,      NONE,      SPI,      HSL,      NONE),
+	MFPR_910(GPIO38,    0x174, GPIO,     MMC2,   NONE,      NONE,      NONE,      NONE,     HSL,      NONE),
+	MFPR_910(GPIO39,    0x178, GPIO,     MMC2,   NONE,      NONE,      NONE,      NONE,     HSL,      NONE),
+	MFPR_910(GPIO40,    0x17C, GPIO,     MMC2,   NONE,      NONE,      NONE,      NONE,     HSL,      NONE),
+	MFPR_910(GPIO41,    0x180, GPIO,     MMC2,   NONE,      NONE,      NONE,      NONE,     HSL,      NONE),
+	MFPR_910(GPIO42,    0x184, GPIO,     MMC2,   NONE,      NONE,      NONE,      NONE,     HSL,      NONE),
+	MFPR_910(GPIO43,    0x188, GPIO,     UART1,  NONE,      DAC_ST23,  NONE,      DSSP2,    SPI,      UART2),
+	MFPR_910(GPIO44,    0x18C, GPIO,     UART1,  NONE,      EXT_INT,   NONE,      DSSP2,    SPI,      UART2),
+	MFPR_910(GPIO45,    0x190, GPIO,     UART1,  NONE,      EXT_INT,   NONE,      DSSP2,    SPI,      UART2),
+	MFPR_910(GPIO46,    0x194, GPIO,     UART1,  NONE,      EXT_INT,   NONE,      DSSP2,    SPI,      UART2),
+	MFPR_910(GPIO47,    0x198, GPIO,     SSP0,   NONE,      NONE,      NONE,      SSP2,     UART1,    NONE),
+	MFPR_910(GPIO48,    0x19C, GPIO,     SSP0,   NONE,      NONE,      NONE,      SSP2,     UART1,    NONE),
+	MFPR_910(GPIO49,    0x1A0, GPIO,     SSP0,   UART0,     VCXO_REQ,  NONE,      SSP2,     NONE,     MMC3),
+	MFPR_910(GPIO50,    0x1A4, GPIO,     SSP0,   UART0,     VCXO_OUT,  NONE,      SSP2,     NONE,     MMC3),
+	MFPR_910(GPIO51,    0x1A8, GPIO,     UART2,  PWM1,      TWSI,      SSP0,      NONE,     DSSP3,    NONE),
+	MFPR_910(GPIO52,    0x1AC, GPIO,     UART2,  DAC_ST23,  TWSI,      SSP0,      NONE,     DSSP3,    NONE),
+	MFPR_910(GPIO53,    0x1B0, GPIO,     UART2,  TWSI,      NONE,      SSP0,      NONE,     DSSP3,    NONE),
+	MFPR_910(GPIO54,    0x1B4, GPIO,     UART2,  TWSI,      SSP0,      NONE,      NONE,     DSSP3,    NONE),
+	MFPR_910(GPIO55,    0x2F0, TDS,      GPIO,   TB,        NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO56,    0x2F4, TDS,      GPIO,   TB,        NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO57,    0x2F8, TDS,      GPIO,   TB,        NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO58,    0x2FC, TDS,      GPIO,   TB,        NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO59,    0x300, TDS,      GPIO,   TCU_GPOA,  TCU_GPOB,  ONE_WIRE,  NONE,     NONE,     NONE),
+	MFPR_910(GPIO60,    0x304, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO61,    0x308, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     HSL),
+	MFPR_910(GPIO62,    0x30C, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     HSL),
+	MFPR_910(GPIO63,    0x310, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     HSL),
+	MFPR_910(GPIO64,    0x314, GPIO,     SPI2,   NONE,      NONE,      NONE,      NONE,     NONE,     HSL),
+	MFPR_910(GPIO65,    0x318, GPIO,     SPI2,   NONE,      NONE,      NONE,      NONE,     ONE_WIRE, HSL),
+	MFPR_910(GPIO66,    0x31C, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     HSL),
+	MFPR_910(GPIO67,    0x1B8, GPIO,     CCIC,   SPI,       NONE,      NONE,      ULPI,     NONE,     USIM2),
+	MFPR_910(GPIO68,    0x1BC, GPIO,     CCIC,   SPI,       NONE,      NONE,      ULPI,     NONE,     USIM2),
+	MFPR_910(GPIO69,    0x1C0, GPIO,     CCIC,   SPI,       NONE,      NONE,      ULPI,     NONE,     USIM2),
+	MFPR_910(GPIO70,    0x1C4, GPIO,     CCIC,   SPI,       NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO71,    0x1C8, GPIO,     CCIC,   SPI,       NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO72,    0x1CC, GPIO,     CCIC,   EXT_DMA,   NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO73,    0x1D0, GPIO,     CCIC,   EXT_DMA,   NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO74,    0x1D4, GPIO,     CCIC,   EXT_DMA,   NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO75,    0x1D8, GPIO,     CCIC,   NONE,      NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO76,    0x1DC, GPIO,     CCIC,   NONE,      NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO77,    0x1E0, GPIO,     CCIC,   NONE,      NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO78,    0x1E4, GPIO,     CCIC,   NONE,      NONE,      NONE,      ULPI,     NONE,     NONE),
+	MFPR_910(GPIO79,    0x1E8, GPIO,     TWSI,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO80,    0x1EC, GPIO,     TWSI,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO81,    0x1F0, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO82,    0x1F4, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO83,    0x1F8, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO84,    0x1FC, GPIO,     LCD,    VCXO_REQ2, NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO85,    0x200, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO86,    0x204, GPIO,     LCD,    VCXO_OUT2, NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO87,    0x208, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO88,    0x20C, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO89,    0x210, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO90,    0x214, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO91,    0x218, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO92,    0x21C, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO93,    0x220, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO94,    0x224, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO95,    0x228, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO96,    0x22C, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO97,    0x230, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO98,    0x234, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO99,    0x0B0, MMC1,     GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO100,   0x238, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO101,   0x23C, GPIO,     LCD,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO102,   0x240, GPIO,     LCD,    DSSP2,     SPI,       NONE,      NONE,     NONE,     SPI2),
+	MFPR_910(GPIO103,   0x244, GPIO,     LCD,    DSSP2,     SPI,       NONE,      NONE,     NONE,     SPI2),
+	MFPR_910(GPIO104,   0x248, GPIO,     LCD,    DSSP2,     SPI,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO105,   0x24C, GPIO,     LCD,    DSSP2,     SPI,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO106,   0x250, GPIO,     LCD,    DSSP3,     ONE_WIRE,  NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO107,   0x254, GPIO,     LCD,    DSSP3,     SPI,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO108,   0x258, GPIO,     LCD,    DSSP3,     SPI,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO109,   0x25C, GPIO,     LCD,    DSSP3,     SPI,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO110,   0x298, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO111,   0x29C, GPIO,     NONE,   DSSP2,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO112,   0x2A0, GPIO,     NONE,   DSSP2,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO113,   0x2A4, GPIO,     NONE,   DSSP2,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO114,   0x2A8, GPIO,     NONE,   DSSP3,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO115,   0x2AC, GPIO,     NONE,   DSSP3,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO116,   0x2B0, GPIO,     NONE,   DSSP3,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO117,   0x0B4, PRI_JTAG, GPIO,   PWM0,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO118,   0x0B8, PRI_JTAG, GPIO,   PWM1,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO119,   0x0BC, PRI_JTAG, GPIO,   PWM2,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO120,   0x0C0, PRI_JTAG, GPIO,   PWM3,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO121,   0x32C, GPIO,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO122,   0x0C8, RESET,    GPIO,   32K_CLK,   NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO123,   0x0CC, CLK_REQ,  GPIO,   ONE_WIRE,  EXT_DMA,   NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO124,   0x0D0, GPIO,     MN_CLK, DAC_ST23,  NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO125,   0x0D4, VCXO_REQ, GPIO,   NONE,      EXT_INT,   NONE,      NONE,     NONE,     NONE),
+	MFPR_910(GPIO126,   0x06C, GPIO,     SMC,    NONE,      SM_ADDR18, NONE,      EXT_DMA,  NONE,     NONE),
+	MFPR_910(GPIO127,   0x070, GPIO,     SMC,    NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO15,   0x004, NAND,     GPIO,   USIM2,     EXT_DMA,   NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO14,   0x008, NAND,     GPIO,   USIM2,     NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO13,   0x00C, NAND,     GPIO,   USIM2,     EXT_INT,   NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO12,   0x010, NAND,     GPIO,   SSP2,      EXT_INT,   NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO11,   0x014, NAND,     GPIO,   SSP2,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO10,   0x018, NAND,     GPIO,   SSP2,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO9,    0x01C, NAND,     GPIO,   SSP2,      NONE,      VCXO_OUT2, NONE,     NONE,     NONE),
+	MFPR_910(ND_IO8,    0x020, NAND,     GPIO,   NONE,      NONE,      PWM3,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO7,    0x024, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO6,    0x028, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO5,    0x02C, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO4,    0x030, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO3,    0x034, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO2,    0x038, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO1,    0x03C, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_IO0,    0x040, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_NCS0,   0x044, NAND,     GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_NCS1,   0x048, NAND,     GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(SM_NCS0,   0x04C, SMC,      GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(SM_NCS1,   0x050, SMC,      GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_NWE,    0x054, GPIO,     NAND,   NONE,      SM_ADDR20, NONE,      SMC,      NONE,     NONE),
+	MFPR_910(ND_NRE,    0x058, GPIO,     NAND,   NONE,      SMC,       NONE,      EXT_DMA,  NONE,     NONE),
+	MFPR_910(ND_CLE,    0x05C, NAND,     MMC3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_ALE,    0x060, GPIO,     NAND,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(SM_SCLK,   0x064, MMC3,     NONE,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_RDY0,   0x068, NAND,     GPIO,   NONE,      SMC,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(SM_ADV,    0x074, SMC,      GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(ND_RDY1,   0x078, NAND,     GPIO,   NONE,      SMC,       NONE,      NONE,     NONE,     NONE),
+	MFPR_910(SM_ADVMUX, 0x07C, SMC,      GPIO,   NONE,      SM_ADDR19, NONE,      NONE,     NONE,     NONE),
+	MFPR_910(SM_RDY,    0x080, SMC,      GPIO,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT7, 0x084, MMC1,     GPIO,   SEC1_JTAG, TB,        NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT6, 0x088, MMC1,     GPIO,   SEC1_JTAG, TB,        NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT5, 0x08C, MMC1,     GPIO,   SEC1_JTAG, TB,        NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT4, 0x090, MMC1,     GPIO,   NONE,      TB,        NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT3, 0x094, MMC1,     HSL,    SEC2_JTAG, SSP0,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT2, 0x098, MMC1,     HSL,    SEC2_JTAG, SSP2,      SSP0,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT1, 0x09C, MMC1,     HSL,    SEC2_JTAG, SSP2,      SSP0,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_DAT0, 0x0A0, MMC1,     HSL,    SEC2_JTAG, SSP2,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_CMD,  0x0A4, MMC1,     HSL,    SEC1_JTAG, SSP2,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_CLK,  0x0A8, MMC1,     HSL,    SEC2_JTAG, SSP0,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(MMC1_CD,   0x0AC, MMC1,     GPIO,   SEC1_JTAG, NONE,      NONE,      NONE,     NONE,     NONE),
+	MFPR_910(VCXO_OUT,  0x0D8, VCXO_OUT, PWM3,   NONE,      NONE,      NONE,      NONE,     NONE,     NONE),
+};
+
+
+static const unsigned p910_usim2_pin1[] = {GPIO67, GPIO68, GPIO69};
+static const unsigned p910_usim2_pin2[] = {ND_IO15, ND_IO14, ND_IO13};
+static const unsigned p910_mmc1_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5,
+	MMC1_DAT4, MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, MMC1_CMD,
+	MMC1_CLK, MMC1_CD, GPIO99};
+static const unsigned p910_mmc2_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36,
+	GPIO37, GPIO38, GPIO39, GPIO40, GPIO41, GPIO42};
+static const unsigned p910_mmc3_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36,
+	GPIO49, GPIO50};
+static const unsigned p910_mmc3_pin2[] = {ND_IO7, ND_IO6, ND_IO5, ND_IO4,
+	ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_CLE, SM_SCLK};
+static const unsigned p910_uart0_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32};
+static const unsigned p910_uart1_pin1[] = {GPIO47, GPIO48};
+static const unsigned p910_uart1_pin2[] = {GPIO31, GPIO32};
+static const unsigned p910_uart1_pin3[] = {GPIO45, GPIO46};
+static const unsigned p910_uart1_pin4[] = {GPIO29, GPIO30, GPIO31, GPIO32};
+static const unsigned p910_uart1_pin5[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_uart2_pin1[] = {GPIO43, GPIO44};
+static const unsigned p910_uart2_pin2[] = {GPIO51, GPIO52};
+static const unsigned p910_uart2_pin3[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_uart2_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned p910_twsi_pin1[] = {GPIO51, GPIO52};
+static const unsigned p910_twsi_pin2[] = {GPIO53, GPIO54};
+static const unsigned p910_twsi_pin3[] = {GPIO79, GPIO80};
+static const unsigned p910_ccic_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70,
+	GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78};
+static const unsigned p910_lcd_pin1[] = {GPIO81, GPIO82, GPIO83, GPIO84,
+	GPIO85, GPIO86, GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92,
+	GPIO93, GPIO94, GPIO95, GPIO96, GPIO97, GPIO98, GPIO100, GPIO101,
+	GPIO102, GPIO103};
+static const unsigned p910_spi_pin1[] = {GPIO104, GPIO105, GPIO107, GPIO108};
+static const unsigned p910_spi_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_spi_pin3[] = {GPIO33, GPIO34, GPIO35, GPIO36,
+	GPIO37};
+static const unsigned p910_spi_pin4[] = {GPIO67, GPIO68, GPIO69, GPIO70,
+	GPIO71};
+static const unsigned p910_spi2_pin1[] = {GPIO64, GPIO65};
+static const unsigned p910_spi2_pin2[] = {GPIO102, GPIO103};
+static const unsigned p910_dssp2_pin1[] = {GPIO102, GPIO103, GPIO104, GPIO105};
+static const unsigned p910_dssp2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_dssp2_pin3[] = {GPIO111, GPIO112, GPIO113};
+static const unsigned p910_dssp3_pin1[] = {GPIO106, GPIO107, GPIO108, GPIO109};
+static const unsigned p910_dssp3_pin2[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned p910_dssp3_pin3[] = {GPIO114, GPIO115, GPIO116};
+static const unsigned p910_ssp0_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1,
+	MMC1_CLK};
+static const unsigned p910_ssp0_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned p910_ssp0_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned p910_ssp0_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned p910_ssp1_pin1[] = {GPIO21, GPIO22, GPIO23, GPIO24};
+static const unsigned p910_ssp1_pin2[] = {GPIO20, GPIO21, GPIO22, GPIO23,
+	GPIO24};
+static const unsigned p910_ssp2_pin1[] = {MMC1_DAT2, MMC1_DAT1, MMC1_DAT0,
+	MMC1_CMD};
+static const unsigned p910_ssp2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned p910_ssp2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned p910_ssp2_pin4[] = {ND_IO12, ND_IO11, ND_IO10, ND_IO9};
+static const unsigned p910_gssp_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28};
+static const unsigned p910_pwm0_pin1[] = {GPIO117};
+static const unsigned p910_pwm1_pin1[] = {GPIO118};
+static const unsigned p910_pwm1_pin2[] = {GPIO51};
+static const unsigned p910_pwm2_pin1[] = {GPIO119};
+static const unsigned p910_pwm3_pin1[] = {GPIO120};
+static const unsigned p910_pwm3_pin2[] = {ND_IO8};
+static const unsigned p910_pwm3_pin3[] = {VCXO_OUT};
+static const unsigned p910_pri_jtag_pin1[] = {GPIO117, GPIO118, GPIO119,
+	GPIO120};
+static const unsigned p910_sec1_jtag_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5,
+	MMC1_CMD, MMC1_CD};
+static const unsigned p910_sec2_jtag_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1,
+	MMC1_DAT0, MMC1_CLK};
+static const unsigned p910_hsl_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+	GPIO41, GPIO42};
+static const unsigned p910_hsl_pin2[] = {GPIO61, GPIO62, GPIO63, GPIO64,
+	GPIO65, GPIO66};
+static const unsigned p910_hsl_pin3[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1,
+	MMC1_DAT0, MMC1_CMD, MMC1_CLK};
+static const unsigned p910_w1_pin1[] = {GPIO59};
+static const unsigned p910_w1_pin2[] = {GPIO65};
+static const unsigned p910_w1_pin3[] = {GPIO106};
+static const unsigned p910_w1_pin4[] = {GPIO123};
+static const unsigned p910_kpmk_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4,
+	GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13,
+	GPIO14, GPIO15};
+static const unsigned p910_kpmk_pin2[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4,
+	GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO12};
+static const unsigned p910_kpdk_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15,
+	GPIO16, GPIO17, GPIO18, GPIO19};
+static const unsigned p910_tds_pin1[] = {GPIO55, GPIO56, GPIO57, GPIO58,
+	GPIO59};
+static const unsigned p910_tds_pin2[] = {GPIO55, GPIO57, GPIO58, GPIO59};
+static const unsigned p910_tb_pin1[] = {GPIO14, GPIO15, GPIO16, GPIO17};
+static const unsigned p910_tb_pin2[] = {GPIO55, GPIO56, GPIO57, GPIO58};
+static const unsigned p910_tb_pin3[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5,
+	MMC1_DAT4};
+static const unsigned p910_ext_dma0_pin1[] = {GPIO72};
+static const unsigned p910_ext_dma0_pin2[] = {ND_IO15};
+static const unsigned p910_ext_dma0_pin3[] = {ND_NRE};
+static const unsigned p910_ext_dma1_pin1[] = {GPIO73};
+static const unsigned p910_ext_dma1_pin2[] = {GPIO123};
+static const unsigned p910_ext_dma1_pin3[] = {GPIO126};
+static const unsigned p910_ext_dma2_pin1[] = {GPIO74};
+static const unsigned p910_ext0_int_pin1[] = {GPIO44};
+static const unsigned p910_ext0_int_pin2[] = {ND_IO13};
+static const unsigned p910_ext1_int_pin1[] = {GPIO45};
+static const unsigned p910_ext1_int_pin2[] = {ND_IO12};
+static const unsigned p910_ext2_int_pin1[] = {GPIO46};
+static const unsigned p910_ext2_int_pin2[] = {GPIO125};
+static const unsigned p910_dac_st23_pin1[] = {GPIO32};
+static const unsigned p910_dac_st23_pin2[] = {GPIO43};
+static const unsigned p910_dac_st23_pin3[] = {GPIO52};
+static const unsigned p910_dac_st23_pin4[] = {GPIO124};
+static const unsigned p910_vcxo_out_pin1[] = {GPIO50};
+static const unsigned p910_vcxo_out_pin2[] = {VCXO_OUT};
+static const unsigned p910_vcxo_out_pin3[] = {GPIO20};
+static const unsigned p910_vcxo_req_pin1[] = {GPIO49};
+static const unsigned p910_vcxo_req_pin2[] = {GPIO125};
+static const unsigned p910_vcxo_out2_pin1[] = {GPIO86};
+static const unsigned p910_vcxo_out2_pin2[] = {ND_IO9};
+static const unsigned p910_vcxo_req2_pin1[] = {GPIO84};
+static const unsigned p910_ulpi_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70,
+	GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78};
+static const unsigned p910_nand_pin1[] = {ND_IO15, ND_IO14, ND_IO13, ND_IO12,
+	ND_IO11, ND_IO10, ND_IO9, ND_IO8, ND_IO7, ND_IO6, ND_IO5, ND_IO4,
+	ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_NCS0, ND_NWE, ND_NRE, ND_CLE,
+	ND_ALE, ND_RDY0};
+static const unsigned p910_gpio0_pin1[] = {GPIO0};
+static const unsigned p910_gpio0_pin2[] = {SM_ADV};
+static const unsigned p910_gpio1_pin1[] = {GPIO1};
+static const unsigned p910_gpio1_pin2[] = {ND_RDY1};
+static const unsigned p910_gpio2_pin1[] = {GPIO2};
+static const unsigned p910_gpio2_pin2[] = {SM_ADVMUX};
+static const unsigned p910_gpio3_pin1[] = {GPIO3};
+static const unsigned p910_gpio3_pin2[] = {SM_RDY};
+static const unsigned p910_gpio20_pin1[] = {GPIO20};
+static const unsigned p910_gpio20_pin2[] = {ND_IO15};
+static const unsigned p910_gpio20_pin3[] = {MMC1_DAT6};
+static const unsigned p910_gpio21_pin1[] = {GPIO21};
+static const unsigned p910_gpio21_pin2[] = {ND_IO14};
+static const unsigned p910_gpio21_pin3[] = {MMC1_DAT5};
+static const unsigned p910_gpio22_pin1[] = {GPIO22};
+static const unsigned p910_gpio22_pin2[] = {ND_IO13};
+static const unsigned p910_gpio22_pin3[] = {MMC1_DAT4};
+static const unsigned p910_gpio23_pin1[] = {GPIO23};
+static const unsigned p910_gpio23_pin2[] = {ND_IO12};
+static const unsigned p910_gpio23_pin3[] = {MMC1_CD};
+static const unsigned p910_gpio24_pin1[] = {GPIO24};
+static const unsigned p910_gpio24_pin2[] = {ND_IO11};
+static const unsigned p910_gpio24_pin3[] = {MMC1_DAT7};
+static const unsigned p910_gpio25_pin1[] = {GPIO25};
+static const unsigned p910_gpio25_pin2[] = {ND_IO10};
+static const unsigned p910_gpio26_pin1[] = {GPIO26};
+static const unsigned p910_gpio26_pin2[] = {ND_IO9};
+static const unsigned p910_gpio27_pin1[] = {GPIO27};
+static const unsigned p910_gpio27_pin2[] = {ND_IO8};
+static const unsigned p910_gpio85_pin1[] = {GPIO85};
+static const unsigned p910_gpio85_pin2[] = {ND_NCS0};
+static const unsigned p910_gpio86_pin1[] = {GPIO86};
+static const unsigned p910_gpio86_pin2[] = {ND_NCS1};
+static const unsigned p910_gpio87_pin1[] = {GPIO87};
+static const unsigned p910_gpio87_pin2[] = {SM_NCS0};
+static const unsigned p910_gpio88_pin1[] = {GPIO88};
+static const unsigned p910_gpio88_pin2[] = {SM_NCS1};
+static const unsigned p910_gpio89_pin1[] = {GPIO89};
+static const unsigned p910_gpio89_pin2[] = {ND_NWE};
+static const unsigned p910_gpio90_pin1[] = {GPIO90};
+static const unsigned p910_gpio90_pin2[] = {ND_NRE};
+static const unsigned p910_gpio91_pin1[] = {GPIO91};
+static const unsigned p910_gpio91_pin2[] = {ND_ALE};
+static const unsigned p910_gpio92_pin1[] = {GPIO92};
+static const unsigned p910_gpio92_pin2[] = {ND_RDY0};
+
+static struct pxa3xx_pin_group pxa910_grps[] = {
+	GRP_910("usim2 3p1", USIM2, p910_usim2_pin1),
+	GRP_910("usim2 3p2", USIM2, p910_usim2_pin2),
+	GRP_910("mmc1 12p", MMC1, p910_mmc1_pin1),
+	GRP_910("mmc2 10p", MMC2, p910_mmc2_pin1),
+	GRP_910("mmc3 6p", MMC3, p910_mmc3_pin1),
+	GRP_910("mmc3 10p", MMC3, p910_mmc3_pin2),
+	GRP_910("uart0 4p", UART0, p910_uart0_pin1),
+	GRP_910("uart1 2p1", UART1, p910_uart1_pin1),
+	GRP_910("uart1 2p2", UART1, p910_uart1_pin2),
+	GRP_910("uart1 2p3", UART1, p910_uart1_pin3),
+	GRP_910("uart1 4p4", UART1, p910_uart1_pin4),
+	GRP_910("uart1 4p5", UART1, p910_uart1_pin5),
+	GRP_910("uart2 2p1", UART2, p910_uart2_pin1),
+	GRP_910("uart2 2p2", UART2, p910_uart2_pin2),
+	GRP_910("uart2 4p3", UART2, p910_uart2_pin3),
+	GRP_910("uart2 4p4", UART2, p910_uart2_pin4),
+	GRP_910("twsi 2p1", TWSI, p910_twsi_pin1),
+	GRP_910("twsi 2p2", TWSI, p910_twsi_pin2),
+	GRP_910("twsi 2p3", TWSI, p910_twsi_pin3),
+	GRP_910("ccic", CCIC, p910_ccic_pin1),
+	GRP_910("lcd", LCD, p910_lcd_pin1),
+	GRP_910("spi 4p1", SPI, p910_spi_pin1),
+	GRP_910("spi 4p2", SPI, p910_spi_pin2),
+	GRP_910("spi 5p3", SPI, p910_spi_pin3),
+	GRP_910("spi 5p4", SPI, p910_spi_pin4),
+	GRP_910("dssp2 4p1", DSSP2, p910_dssp2_pin1),
+	GRP_910("dssp2 4p2", DSSP2, p910_dssp2_pin2),
+	GRP_910("dssp2 3p3", DSSP2, p910_dssp2_pin3),
+	GRP_910("dssp3 4p1", DSSP3, p910_dssp3_pin1),
+	GRP_910("dssp3 4p2", DSSP3, p910_dssp3_pin2),
+	GRP_910("dssp3 3p3", DSSP3, p910_dssp3_pin3),
+	GRP_910("ssp0 4p1", SSP0, p910_ssp0_pin1),
+	GRP_910("ssp0 4p2", SSP0, p910_ssp0_pin2),
+	GRP_910("ssp0 4p3", SSP0, p910_ssp0_pin3),
+	GRP_910("ssp0 4p4", SSP0, p910_ssp0_pin4),
+	GRP_910("ssp1 4p1", SSP1, p910_ssp1_pin1),
+	GRP_910("ssp1 5p2", SSP1, p910_ssp1_pin2),
+	GRP_910("ssp2 4p1", SSP2, p910_ssp2_pin1),
+	GRP_910("ssp2 4p2", SSP2, p910_ssp2_pin2),
+	GRP_910("ssp2 4p3", SSP2, p910_ssp2_pin3),
+	GRP_910("ssp2 4p4", SSP2, p910_ssp2_pin4),
+	GRP_910("gssp", GSSP, p910_gssp_pin1),
+	GRP_910("pwm0", PWM0, p910_pwm0_pin1),
+	GRP_910("pwm1-1", PWM1, p910_pwm1_pin1),
+	GRP_910("pwm1-2", PWM1, p910_pwm1_pin2),
+	GRP_910("pwm2", PWM2, p910_pwm2_pin1),
+	GRP_910("pwm3-1", PWM3, p910_pwm3_pin1),
+	GRP_910("pwm3-2", PWM3, p910_pwm3_pin2),
+	GRP_910("pwm3-3", PWM3, p910_pwm3_pin3),
+	GRP_910("pri jtag", PRI_JTAG, p910_pri_jtag_pin1),
+	GRP_910("sec1 jtag", SEC1_JTAG, p910_sec1_jtag_pin1),
+	GRP_910("sec2 jtag", SEC2_JTAG, p910_sec2_jtag_pin1),
+	GRP_910("hsl 6p1", HSL, p910_hsl_pin1),
+	GRP_910("hsl 6p2", HSL, p910_hsl_pin2),
+	GRP_910("hsl 6p3", HSL, p910_hsl_pin3),
+	GRP_910("w1-1", ONE_WIRE, p910_w1_pin1),
+	GRP_910("w1-2", ONE_WIRE, p910_w1_pin2),
+	GRP_910("w1-3", ONE_WIRE, p910_w1_pin3),
+	GRP_910("w1-4", ONE_WIRE, p910_w1_pin4),
+	GRP_910("kpmk 16p1", KP_MK, p910_kpmk_pin1),
+	GRP_910("kpmk 11p2", KP_MK, p910_kpmk_pin2),
+	GRP_910("kpdk 8p1", KP_DK, p910_kpdk_pin1),
+	GRP_910("tds 5p1", TDS, p910_tds_pin1),
+	GRP_910("tds 4p2", TDS, p910_tds_pin2),
+	GRP_910("tb 4p1", TB, p910_tb_pin1),
+	GRP_910("tb 4p2", TB, p910_tb_pin2),
+	GRP_910("tb 4p3", TB, p910_tb_pin3),
+	GRP_910("ext dma0-1", EXT_DMA, p910_ext_dma0_pin1),
+	GRP_910("ext dma0-2", EXT_DMA, p910_ext_dma0_pin2),
+	GRP_910("ext dma0-3", EXT_DMA, p910_ext_dma0_pin3),
+	GRP_910("ext dma1-1", EXT_DMA, p910_ext_dma1_pin1),
+	GRP_910("ext dma1-2", EXT_DMA, p910_ext_dma1_pin2),
+	GRP_910("ext dma1-3", EXT_DMA, p910_ext_dma1_pin3),
+	GRP_910("ext dma2", EXT_DMA, p910_ext_dma2_pin1),
+	GRP_910("ext0 int-1", EXT_INT, p910_ext0_int_pin1),
+	GRP_910("ext0 int-2", EXT_INT, p910_ext0_int_pin2),
+	GRP_910("ext1 int-1", EXT_INT, p910_ext1_int_pin1),
+	GRP_910("ext1 int-2", EXT_INT, p910_ext1_int_pin2),
+	GRP_910("ext2 int-1", EXT_INT, p910_ext2_int_pin1),
+	GRP_910("ext2 int-2", EXT_INT, p910_ext2_int_pin2),
+	GRP_910("dac st23-1", DAC_ST23, p910_dac_st23_pin1),
+	GRP_910("dac st23-2", DAC_ST23, p910_dac_st23_pin2),
+	GRP_910("dac st23-3", DAC_ST23, p910_dac_st23_pin3),
+	GRP_910("dac st23-4", DAC_ST23, p910_dac_st23_pin4),
+	GRP_910("vcxo out-1", VCXO_OUT, p910_vcxo_out_pin1),
+	GRP_910("vcxo out-2", VCXO_OUT, p910_vcxo_out_pin2),
+	GRP_910("vcxo out-3", VCXO_OUT, p910_vcxo_out_pin3),
+	GRP_910("vcxo req-1", VCXO_REQ, p910_vcxo_req_pin1),
+	GRP_910("vcxo req-2", VCXO_REQ, p910_vcxo_req_pin2),
+	GRP_910("vcxo out2-1", VCXO_OUT2, p910_vcxo_out2_pin1),
+	GRP_910("vcxo out2-2", VCXO_OUT2, p910_vcxo_out2_pin2),
+	GRP_910("vcxo req2", VCXO_REQ2, p910_vcxo_req2_pin1),
+	GRP_910("ulpi", ULPI, p910_ulpi_pin1),
+	GRP_910("nand", NAND, p910_nand_pin1),
+	GRP_910("gpio0-1", GPIO, p910_gpio0_pin1),
+	GRP_910("gpio0-2", GPIO, p910_gpio0_pin2),
+	GRP_910("gpio1-1", GPIO, p910_gpio1_pin1),
+	GRP_910("gpio1-2", GPIO, p910_gpio1_pin2),
+	GRP_910("gpio2-1", GPIO, p910_gpio2_pin1),
+	GRP_910("gpio2-2", GPIO, p910_gpio2_pin2),
+	GRP_910("gpio3-1", GPIO, p910_gpio3_pin1),
+	GRP_910("gpio3-2", GPIO, p910_gpio3_pin2),
+	GRP_910("gpio20-1", GPIO, p910_gpio20_pin1),
+	GRP_910("gpio20-2", GPIO, p910_gpio20_pin2),
+	GRP_910("gpio21-1", GPIO, p910_gpio21_pin1),
+	GRP_910("gpio21-2", GPIO, p910_gpio21_pin2),
+	GRP_910("gpio22-1", GPIO, p910_gpio22_pin1),
+	GRP_910("gpio22-2", GPIO, p910_gpio22_pin2),
+	GRP_910("gpio23-1", GPIO, p910_gpio23_pin1),
+	GRP_910("gpio23-2", GPIO, p910_gpio23_pin2),
+	GRP_910("gpio24-1", GPIO, p910_gpio24_pin1),
+	GRP_910("gpio24-2", GPIO, p910_gpio24_pin2),
+	GRP_910("gpio25-1", GPIO, p910_gpio25_pin1),
+	GRP_910("gpio25-2", GPIO, p910_gpio25_pin2),
+	GRP_910("gpio26-1", GPIO, p910_gpio26_pin1),
+	GRP_910("gpio26-2", GPIO, p910_gpio26_pin2),
+	GRP_910("gpio27-1", GPIO, p910_gpio27_pin1),
+	GRP_910("gpio27-2", GPIO, p910_gpio27_pin2),
+	GRP_910("gpio85-1", GPIO, p910_gpio85_pin1),
+	GRP_910("gpio85-2", GPIO, p910_gpio85_pin2),
+	GRP_910("gpio86-1", GPIO, p910_gpio86_pin1),
+	GRP_910("gpio86-2", GPIO, p910_gpio86_pin2),
+	GRP_910("gpio87-1", GPIO, p910_gpio87_pin1),
+	GRP_910("gpio87-2", GPIO, p910_gpio87_pin2),
+	GRP_910("gpio88-1", GPIO, p910_gpio88_pin1),
+	GRP_910("gpio88-2", GPIO, p910_gpio88_pin2),
+	GRP_910("gpio89-1", GPIO, p910_gpio89_pin1),
+	GRP_910("gpio89-2", GPIO, p910_gpio89_pin2),
+	GRP_910("gpio90-1", GPIO, p910_gpio90_pin1),
+	GRP_910("gpio90-2", GPIO, p910_gpio90_pin2),
+	GRP_910("gpio91-1", GPIO, p910_gpio91_pin1),
+	GRP_910("gpio91-2", GPIO, p910_gpio91_pin2),
+	GRP_910("gpio92-1", GPIO, p910_gpio92_pin1),
+	GRP_910("gpio92-2", GPIO, p910_gpio92_pin2),
+};
+
+static const char * const p910_usim2_grps[] = {"usim2 3p1", "usim2 3p2"};
+static const char * const p910_mmc1_grps[] = {"mmc1 12p"};
+static const char * const p910_mmc2_grps[] = {"mmc2 10p"};
+static const char * const p910_mmc3_grps[] = {"mmc3 6p", "mmc3 10p"};
+static const char * const p910_uart0_grps[] = {"uart0 4p"};
+static const char * const p910_uart1_grps[] = {"uart1 2p1", "uart1 2p2",
+	"uart1 2p3", "uart1 4p4", "uart1 4p5"};
+static const char * const p910_uart2_grps[] = {"uart2 2p1", "uart2 2p2",
+	"uart2 4p3", "uart2 4p4"};
+static const char * const p910_twsi_grps[] = {"twsi 2p1", "twsi 2p2",
+	"twsi 2p3"};
+static const char * const p910_ccic_grps[] = {"ccic"};
+static const char * const p910_lcd_grps[] = {"lcd"};
+static const char * const p910_spi_grps[] = {"spi 4p1", "spi 4p2", "spi 5p3",
+	"spi 5p4"};
+static const char * const p910_dssp2_grps[] = {"dssp2 4p1", "dssp2 4p2",
+	"dssp2 3p3"};
+static const char * const p910_dssp3_grps[] = {"dssp3 4p1", "dssp3 4p2",
+	"dssp3 3p3"};
+static const char * const p910_ssp0_grps[] = {"ssp0 4p1", "ssp0 4p2",
+	"ssp0 4p3", "ssp0 4p4"};
+static const char * const p910_ssp1_grps[] = {"ssp1 4p1", "ssp1 5p2"};
+static const char * const p910_ssp2_grps[] = {"ssp2 4p1", "ssp2 4p2",
+	"ssp2 4p3", "ssp2 4p4"};
+static const char * const p910_gssp_grps[] = {"gssp"};
+static const char * const p910_pwm0_grps[] = {"pwm0"};
+static const char * const p910_pwm1_grps[] = {"pwm1-1", "pwm1-2"};
+static const char * const p910_pwm2_grps[] = {"pwm2"};
+static const char * const p910_pwm3_grps[] = {"pwm3-1", "pwm3-2", "pwm3-3"};
+static const char * const p910_pri_jtag_grps[] = {"pri jtag"};
+static const char * const p910_sec1_jtag_grps[] = {"sec1 jtag"};
+static const char * const p910_sec2_jtag_grps[] = {"sec2 jtag"};
+static const char * const p910_hsl_grps[] = {"hsl 6p1", "hsl 6p2", "hsl 6p3"};
+static const char * const p910_w1_grps[] = {"w1-1", "w1-2", "w1-3", "w1-4"};
+static const char * const p910_kpmk_grps[] = {"kpmk 16p1", "kpmk 11p2"};
+static const char * const p910_kpdk_grps[] = {"kpdk 8p1"};
+static const char * const p910_tds_grps[] = {"tds 5p1", "tds 4p2"};
+static const char * const p910_tb_grps[] = {"tb 4p1", "tb 4p2", "tb 4p3"};
+static const char * const p910_dma0_grps[] = {"ext dma0-1", "ext dma0-2",
+	"ext dma0-3"};
+static const char * const p910_dma1_grps[] = {"ext dma1-1", "ext dma1-2",
+	"ext dma1-3"};
+static const char * const p910_dma2_grps[] = {"ext dma2"};
+static const char * const p910_int0_grps[] = {"ext0 int-1", "ext0 int-2"};
+static const char * const p910_int1_grps[] = {"ext1 int-1", "ext1 int-2"};
+static const char * const p910_int2_grps[] = {"ext2 int-1", "ext2 int-2"};
+static const char * const p910_dac_st23_grps[] = {"dac st23-1", "dac st23-2",
+	"dac st23-3", "dac st23-4"};
+static const char * const p910_vcxo_out_grps[] = {"vcxo out-1", "vcxo out-2",
+	"vcxo out-3"};
+static const char * const p910_vcxo_req_grps[] = {"vcxo req-1", "vcxo req-2"};
+static const char * const p910_vcxo_out2_grps[] = {"vcxo out2-1",
+	"vcxo out2-2"};
+static const char * const p910_vcxo_req2_grps[] = {"vcxo req2"};
+static const char * const p910_ulpi_grps[] = {"ulpi"};
+static const char * const p910_nand_grps[] = {"nand"};
+static const char * const p910_gpio0_grps[] = {"gpio0-1", "gpio0-2"};
+static const char * const p910_gpio1_grps[] = {"gpio1-1", "gpio1-2"};
+static const char * const p910_gpio2_grps[] = {"gpio2-1", "gpio2-2"};
+static const char * const p910_gpio3_grps[] = {"gpio3-1", "gpio3-2"};
+static const char * const p910_gpio20_grps[] = {"gpio20-1", "gpio20-2"};
+static const char * const p910_gpio21_grps[] = {"gpio21-1", "gpio21-2"};
+static const char * const p910_gpio22_grps[] = {"gpio22-1", "gpio22-2"};
+static const char * const p910_gpio23_grps[] = {"gpio23-1", "gpio23-2"};
+static const char * const p910_gpio24_grps[] = {"gpio24-1", "gpio24-2"};
+static const char * const p910_gpio25_grps[] = {"gpio25-1", "gpio25-2"};
+static const char * const p910_gpio26_grps[] = {"gpio26-1", "gpio26-2"};
+static const char * const p910_gpio27_grps[] = {"gpio27-1", "gpio27-2"};
+static const char * const p910_gpio85_grps[] = {"gpio85-1", "gpio85-2"};
+static const char * const p910_gpio86_grps[] = {"gpio86-1", "gpio86-2"};
+static const char * const p910_gpio87_grps[] = {"gpio87-1", "gpio87-2"};
+static const char * const p910_gpio88_grps[] = {"gpio88-1", "gpio88-2"};
+static const char * const p910_gpio89_grps[] = {"gpio89-1", "gpio89-2"};
+static const char * const p910_gpio90_grps[] = {"gpio90-1", "gpio90-2"};
+static const char * const p910_gpio91_grps[] = {"gpio91-1", "gpio91-2"};
+static const char * const p910_gpio92_grps[] = {"gpio92-1", "gpio92-2"};
+
+static struct pxa3xx_pmx_func pxa910_funcs[] = {
+	{"usim2",	ARRAY_AND_SIZE(p910_usim2_grps)},
+	{"mmc1",	ARRAY_AND_SIZE(p910_mmc1_grps)},
+	{"mmc2",	ARRAY_AND_SIZE(p910_mmc2_grps)},
+	{"mmc3",	ARRAY_AND_SIZE(p910_mmc3_grps)},
+	{"uart0",	ARRAY_AND_SIZE(p910_uart0_grps)},
+	{"uart1",	ARRAY_AND_SIZE(p910_uart1_grps)},
+	{"uart2",	ARRAY_AND_SIZE(p910_uart2_grps)},
+	{"twsi",	ARRAY_AND_SIZE(p910_twsi_grps)},
+	{"ccic",	ARRAY_AND_SIZE(p910_ccic_grps)},
+	{"lcd",		ARRAY_AND_SIZE(p910_lcd_grps)},
+	{"spi",		ARRAY_AND_SIZE(p910_spi_grps)},
+	{"dssp2",	ARRAY_AND_SIZE(p910_dssp2_grps)},
+	{"dssp3",	ARRAY_AND_SIZE(p910_dssp3_grps)},
+	{"ssp0",	ARRAY_AND_SIZE(p910_ssp0_grps)},
+	{"ssp1",	ARRAY_AND_SIZE(p910_ssp1_grps)},
+	{"ssp2",	ARRAY_AND_SIZE(p910_ssp2_grps)},
+	{"gssp",	ARRAY_AND_SIZE(p910_gssp_grps)},
+	{"pwm0",	ARRAY_AND_SIZE(p910_pwm0_grps)},
+	{"pwm1",	ARRAY_AND_SIZE(p910_pwm1_grps)},
+	{"pwm2",	ARRAY_AND_SIZE(p910_pwm2_grps)},
+	{"pwm3",	ARRAY_AND_SIZE(p910_pwm3_grps)},
+	{"pri_jtag",	ARRAY_AND_SIZE(p910_pri_jtag_grps)},
+	{"sec1_jtag",	ARRAY_AND_SIZE(p910_sec1_jtag_grps)},
+	{"sec2_jtag",	ARRAY_AND_SIZE(p910_sec2_jtag_grps)},
+	{"hsl",		ARRAY_AND_SIZE(p910_hsl_grps)},
+	{"w1",		ARRAY_AND_SIZE(p910_w1_grps)},
+	{"kpmk",	ARRAY_AND_SIZE(p910_kpmk_grps)},
+	{"kpdk",	ARRAY_AND_SIZE(p910_kpdk_grps)},
+	{"tds",		ARRAY_AND_SIZE(p910_tds_grps)},
+	{"tb",		ARRAY_AND_SIZE(p910_tb_grps)},
+	{"dma0",	ARRAY_AND_SIZE(p910_dma0_grps)},
+	{"dma1",	ARRAY_AND_SIZE(p910_dma1_grps)},
+	{"dma2",	ARRAY_AND_SIZE(p910_dma2_grps)},
+	{"int0",	ARRAY_AND_SIZE(p910_int0_grps)},
+	{"int1",	ARRAY_AND_SIZE(p910_int1_grps)},
+	{"int2",	ARRAY_AND_SIZE(p910_int2_grps)},
+	{"dac_st23",	ARRAY_AND_SIZE(p910_dac_st23_grps)},
+	{"vcxo_out",	ARRAY_AND_SIZE(p910_vcxo_out_grps)},
+	{"vcxo_req",	ARRAY_AND_SIZE(p910_vcxo_req_grps)},
+	{"vcxo_out2",	ARRAY_AND_SIZE(p910_vcxo_out2_grps)},
+	{"vcxo_req2",	ARRAY_AND_SIZE(p910_vcxo_req2_grps)},
+	{"ulpi",	ARRAY_AND_SIZE(p910_ulpi_grps)},
+	{"nand",	ARRAY_AND_SIZE(p910_nand_grps)},
+	{"gpio0",	ARRAY_AND_SIZE(p910_gpio0_grps)},
+	{"gpio1",	ARRAY_AND_SIZE(p910_gpio1_grps)},
+	{"gpio2",	ARRAY_AND_SIZE(p910_gpio2_grps)},
+	{"gpio3",	ARRAY_AND_SIZE(p910_gpio3_grps)},
+	{"gpio20",	ARRAY_AND_SIZE(p910_gpio20_grps)},
+	{"gpio21",	ARRAY_AND_SIZE(p910_gpio21_grps)},
+	{"gpio22",	ARRAY_AND_SIZE(p910_gpio22_grps)},
+	{"gpio23",	ARRAY_AND_SIZE(p910_gpio23_grps)},
+	{"gpio24",	ARRAY_AND_SIZE(p910_gpio24_grps)},
+	{"gpio25",	ARRAY_AND_SIZE(p910_gpio25_grps)},
+	{"gpio26",	ARRAY_AND_SIZE(p910_gpio26_grps)},
+	{"gpio27",	ARRAY_AND_SIZE(p910_gpio27_grps)},
+	{"gpio85",	ARRAY_AND_SIZE(p910_gpio85_grps)},
+	{"gpio86",	ARRAY_AND_SIZE(p910_gpio86_grps)},
+	{"gpio87",	ARRAY_AND_SIZE(p910_gpio87_grps)},
+	{"gpio88",	ARRAY_AND_SIZE(p910_gpio88_grps)},
+	{"gpio89",	ARRAY_AND_SIZE(p910_gpio89_grps)},
+	{"gpio90",	ARRAY_AND_SIZE(p910_gpio90_grps)},
+	{"gpio91",	ARRAY_AND_SIZE(p910_gpio91_grps)},
+	{"gpio92",	ARRAY_AND_SIZE(p910_gpio92_grps)},
+};
+
+static struct pinctrl_desc pxa910_pctrl_desc = {
+	.name		= "pxa910-pinctrl",
+	.owner		= THIS_MODULE,
+};
+
+static struct pxa3xx_pinmux_info pxa910_info = {
+	.mfp		= pxa910_mfp,
+	.num_mfp	= ARRAY_SIZE(pxa910_mfp),
+	.grps		= pxa910_grps,
+	.num_grps	= ARRAY_SIZE(pxa910_grps),
+	.funcs		= pxa910_funcs,
+	.num_funcs	= ARRAY_SIZE(pxa910_funcs),
+	.num_gpio	= 128,
+	.desc		= &pxa910_pctrl_desc,
+	.pads		= pxa910_pads,
+	.num_pads	= ARRAY_SIZE(pxa910_pads),
+
+	.cputype	= PINCTRL_PXA910,
+	.ds_mask	= PXA910_DS_MASK,
+	.ds_shift	= PXA910_DS_SHIFT,
+};
+
+static int __devinit pxa910_pinmux_probe(struct platform_device *pdev)
+{
+	return pxa3xx_pinctrl_register(pdev, &pxa910_info);
+}
+
+static int __devexit pxa910_pinmux_remove(struct platform_device *pdev)
+{
+	return pxa3xx_pinctrl_unregister(pdev);
+}
+
+static struct platform_driver pxa910_pinmux_driver = {
+	.driver = {
+		.name	= "pxa910-pinmux",
+		.owner	= THIS_MODULE,
+	},
+	.probe	= pxa910_pinmux_probe,
+	.remove	= __devexit_p(pxa910_pinmux_remove),
+};
+
+static int __init pxa910_pinmux_init(void)
+{
+	return platform_driver_register(&pxa910_pinmux_driver);
+}
+core_initcall_sync(pxa910_pinmux_init);
+
+static void __exit pxa910_pinmux_exit(void)
+{
+	platform_driver_unregister(&pxa910_pinmux_driver);
+}
+module_exit(pxa910_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
new file mode 100644
index 0000000..9b32968
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -0,0 +1,559 @@
+/*
+ * Driver for the NVIDIA Tegra pinmux
+ *
+ * Copyright (c) 2011, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Derived from code:
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 NVIDIA Corporation
+ * Copyright (C) 2009-2011 ST-Ericsson AB
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+
+#include <mach/pinconf-tegra.h>
+
+#include "pinctrl-tegra.h"
+
+#define DRIVER_NAME "tegra-pinmux-disabled"
+
+struct tegra_pmx {
+	struct device *dev;
+	struct pinctrl_dev *pctl;
+
+	const struct tegra_pinctrl_soc_data *soc;
+
+	int nbanks;
+	void __iomem **regs;
+};
+
+static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
+{
+	return readl(pmx->regs[bank] + reg);
+}
+
+static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
+{
+	writel(val, pmx->regs[bank] + reg);
+}
+
+static int tegra_pinctrl_list_groups(struct pinctrl_dev *pctldev,
+				     unsigned group)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (group >= pmx->soc->ngroups)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+						unsigned group)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (group >= pmx->soc->ngroups)
+		return NULL;
+
+	return pmx->soc->groups[group].name;
+}
+
+static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+					unsigned group,
+					const unsigned **pins,
+					unsigned *num_pins)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (group >= pmx->soc->ngroups)
+		return -EINVAL;
+
+	*pins = pmx->soc->groups[group].pins;
+	*num_pins = pmx->soc->groups[group].npins;
+
+	return 0;
+}
+
+static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+				       struct seq_file *s,
+				       unsigned offset)
+{
+	seq_printf(s, " " DRIVER_NAME);
+}
+
+static struct pinctrl_ops tegra_pinctrl_ops = {
+	.list_groups = tegra_pinctrl_list_groups,
+	.get_group_name = tegra_pinctrl_get_group_name,
+	.get_group_pins = tegra_pinctrl_get_group_pins,
+	.pin_dbg_show = tegra_pinctrl_pin_dbg_show,
+};
+
+static int tegra_pinctrl_list_funcs(struct pinctrl_dev *pctldev,
+				    unsigned function)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (function >= pmx->soc->nfunctions)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+					       unsigned function)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (function >= pmx->soc->nfunctions)
+		return NULL;
+
+	return pmx->soc->functions[function].name;
+}
+
+static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+					 unsigned function,
+					 const char * const **groups,
+					 unsigned * const num_groups)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+	if (function >= pmx->soc->nfunctions)
+		return -EINVAL;
+
+	*groups = pmx->soc->functions[function].groups;
+	*num_groups = pmx->soc->functions[function].ngroups;
+
+	return 0;
+}
+
+static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
+			       unsigned group)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tegra_pingroup *g;
+	int i;
+	u32 val;
+
+	if (group >= pmx->soc->ngroups)
+		return -EINVAL;
+	g = &pmx->soc->groups[group];
+
+	if (g->mux_reg < 0)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
+		if (g->funcs[i] == function)
+			break;
+	}
+	if (i == ARRAY_SIZE(g->funcs))
+		return -EINVAL;
+
+	val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
+	val &= ~(0x3 << g->mux_bit);
+	val |= i << g->mux_bit;
+	pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
+
+	return 0;
+}
+
+static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
+				  unsigned function, unsigned group)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	const struct tegra_pingroup *g;
+	u32 val;
+
+	if (group >= pmx->soc->ngroups)
+		return;
+	g = &pmx->soc->groups[group];
+
+	if (g->mux_reg < 0)
+		return;
+
+	val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
+	val &= ~(0x3 << g->mux_bit);
+	val |= g->func_safe << g->mux_bit;
+	pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
+}
+
+static struct pinmux_ops tegra_pinmux_ops = {
+	.list_functions = tegra_pinctrl_list_funcs,
+	.get_function_name = tegra_pinctrl_get_func_name,
+	.get_function_groups = tegra_pinctrl_get_func_groups,
+	.enable = tegra_pinctrl_enable,
+	.disable = tegra_pinctrl_disable,
+};
+
+static int tegra_pinconf_reg(struct tegra_pmx *pmx,
+			     const struct tegra_pingroup *g,
+			     enum tegra_pinconf_param param,
+			     s8 *bank, s16 *reg, s8 *bit, s8 *width)
+{
+	switch (param) {
+	case TEGRA_PINCONF_PARAM_PULL:
+		*bank = g->pupd_bank;
+		*reg = g->pupd_reg;
+		*bit = g->pupd_bit;
+		*width = 2;
+		break;
+	case TEGRA_PINCONF_PARAM_TRISTATE:
+		*bank = g->tri_bank;
+		*reg = g->tri_reg;
+		*bit = g->tri_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_ENABLE_INPUT:
+		*bank = g->einput_bank;
+		*reg = g->einput_reg;
+		*bit = g->einput_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_OPEN_DRAIN:
+		*bank = g->odrain_bank;
+		*reg = g->odrain_reg;
+		*bit = g->odrain_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_LOCK:
+		*bank = g->lock_bank;
+		*reg = g->lock_reg;
+		*bit = g->lock_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_IORESET:
+		*bank = g->ioreset_bank;
+		*reg = g->ioreset_reg;
+		*bit = g->ioreset_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->hsm_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_SCHMITT:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->schmitt_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_LOW_POWER_MODE:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->lpmd_bit;
+		*width = 1;
+		break;
+	case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->drvdn_bit;
+		*width = g->drvdn_width;
+		break;
+	case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->drvup_bit;
+		*width = g->drvup_width;
+		break;
+	case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->slwf_bit;
+		*width = g->slwf_width;
+		break;
+	case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING:
+		*bank = g->drv_bank;
+		*reg = g->drv_reg;
+		*bit = g->slwr_bit;
+		*width = g->slwr_width;
+		break;
+	default:
+		dev_err(pmx->dev, "Invalid config param %04x\n", param);
+		return -ENOTSUPP;
+	}
+
+	if (*reg < 0) {
+		dev_err(pmx->dev,
+			"Config param %04x not supported on group %s\n",
+			param, g->name);
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
+			     unsigned pin, unsigned long *config)
+{
+	return -ENOTSUPP;
+}
+
+static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
+			     unsigned pin, unsigned long config)
+{
+	return -ENOTSUPP;
+}
+
+static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
+				   unsigned group, unsigned long *config)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config);
+	u16 arg;
+	const struct tegra_pingroup *g;
+	int ret;
+	s8 bank, bit, width;
+	s16 reg;
+	u32 val, mask;
+
+	if (group >= pmx->soc->ngroups)
+		return -EINVAL;
+	g = &pmx->soc->groups[group];
+
+	ret = tegra_pinconf_reg(pmx, g, param, &bank, &reg, &bit, &width);
+	if (ret < 0)
+		return ret;
+
+	val = pmx_readl(pmx, bank, reg);
+	mask = (1 << width) - 1;
+	arg = (val >> bit) & mask;
+
+	*config = TEGRA_PINCONF_PACK(param, arg);
+
+	return 0;
+}
+
+static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
+				   unsigned group, unsigned long config)
+{
+	struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+	enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config);
+	u16 arg = TEGRA_PINCONF_UNPACK_ARG(config);
+	const struct tegra_pingroup *g;
+	int ret;
+	s8 bank, bit, width;
+	s16 reg;
+	u32 val, mask;
+
+	if (group >= pmx->soc->ngroups)
+		return -EINVAL;
+	g = &pmx->soc->groups[group];
+
+	ret = tegra_pinconf_reg(pmx, g, param, &bank, &reg, &bit, &width);
+	if (ret < 0)
+		return ret;
+
+	val = pmx_readl(pmx, bank, reg);
+
+	/* LOCK can't be cleared */
+	if (param == TEGRA_PINCONF_PARAM_LOCK) {
+		if ((val & BIT(bit)) && !arg)
+			return -EINVAL;
+	}
+
+	/* Special-case Boolean values; allow any non-zero as true */
+	if (width == 1)
+		arg = !!arg;
+
+	/* Range-check user-supplied value */
+	mask = (1 << width) - 1;
+	if (arg & ~mask)
+		return -EINVAL;
+
+	/* Update register */
+	val &= ~(mask << bit);
+	val |= arg << bit;
+	pmx_writel(pmx, val, bank, reg);
+
+	return 0;
+}
+
+static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				   struct seq_file *s, unsigned offset)
+{
+}
+
+static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
+					 struct seq_file *s, unsigned selector)
+{
+}
+
+struct pinconf_ops tegra_pinconf_ops = {
+	.pin_config_get = tegra_pinconf_get,
+	.pin_config_set = tegra_pinconf_set,
+	.pin_config_group_get = tegra_pinconf_group_get,
+	.pin_config_group_set = tegra_pinconf_group_set,
+	.pin_config_dbg_show = tegra_pinconf_dbg_show,
+	.pin_config_group_dbg_show = tegra_pinconf_group_dbg_show,
+};
+
+static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
+	.name = "Tegra GPIOs",
+	.id = 0,
+	.base = 0,
+};
+
+static struct pinctrl_desc tegra_pinctrl_desc = {
+	.name = DRIVER_NAME,
+	.pctlops = &tegra_pinctrl_ops,
+	.pmxops = &tegra_pinmux_ops,
+	.confops = &tegra_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static struct of_device_id tegra_pinctrl_of_match[] __devinitdata = {
+#ifdef CONFIG_PINCTRL_TEGRA20
+	{
+		.compatible = "nvidia,tegra20-pinmux-disabled",
+		.data = tegra20_pinctrl_init,
+	},
+#endif
+#ifdef CONFIG_PINCTRL_TEGRA30
+	{
+		.compatible = "nvidia,tegra30-pinmux-disabled",
+		.data = tegra30_pinctrl_init,
+	},
+#endif
+	{},
+};
+
+static int __devinit tegra_pinctrl_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	tegra_pinctrl_soc_initf initf = NULL;
+	struct tegra_pmx *pmx;
+	struct resource *res;
+	int i;
+
+	match = of_match_device(tegra_pinctrl_of_match, &pdev->dev);
+	if (match)
+		initf = (tegra_pinctrl_soc_initf)match->data;
+#ifdef CONFIG_PINCTRL_TEGRA20
+	if (!initf)
+		initf = tegra20_pinctrl_init;
+#endif
+	if (!initf) {
+		dev_err(&pdev->dev,
+			"Could not determine SoC-specific init func\n");
+		return -EINVAL;
+	}
+
+	pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
+	if (!pmx) {
+		dev_err(&pdev->dev, "Can't alloc tegra_pmx\n");
+		return -ENOMEM;
+	}
+	pmx->dev = &pdev->dev;
+
+	(*initf)(&pmx->soc);
+
+	tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
+	tegra_pinctrl_desc.pins = pmx->soc->pins;
+	tegra_pinctrl_desc.npins = pmx->soc->npins;
+
+	for (i = 0; ; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res)
+			break;
+	}
+	pmx->nbanks = i;
+
+	pmx->regs = devm_kzalloc(&pdev->dev, pmx->nbanks * sizeof(*pmx->regs),
+				 GFP_KERNEL);
+	if (!pmx->regs) {
+		dev_err(&pdev->dev, "Can't alloc regs pointer\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < pmx->nbanks; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res) {
+			dev_err(&pdev->dev, "Missing MEM resource\n");
+			return -ENODEV;
+		}
+
+		if (!devm_request_mem_region(&pdev->dev, res->start,
+					    resource_size(res),
+					    dev_name(&pdev->dev))) {
+			dev_err(&pdev->dev,
+				"Couldn't request MEM resource %d\n", i);
+			return -ENODEV;
+		}
+
+		pmx->regs[i] = devm_ioremap(&pdev->dev, res->start,
+					    resource_size(res));
+		if (!pmx->regs[i]) {
+			dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i);
+			return -ENODEV;
+		}
+	}
+
+	pmx->pctl = pinctrl_register(&tegra_pinctrl_desc, &pdev->dev, pmx);
+	if (IS_ERR(pmx->pctl)) {
+		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+		return PTR_ERR(pmx->pctl);
+	}
+
+	pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
+
+	platform_set_drvdata(pdev, pmx);
+
+	dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n");
+
+	return 0;
+}
+
+static int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
+{
+	struct tegra_pmx *pmx = platform_get_drvdata(pdev);
+
+	pinctrl_remove_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
+	pinctrl_unregister(pmx->pctl);
+
+	return 0;
+}
+
+static struct platform_driver tegra_pinctrl_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = tegra_pinctrl_of_match,
+	},
+	.probe = tegra_pinctrl_probe,
+	.remove = __devexit_p(tegra_pinctrl_remove),
+};
+
+static int __init tegra_pinctrl_init(void)
+{
+	return platform_driver_register(&tegra_pinctrl_driver);
+}
+arch_initcall(tegra_pinctrl_init);
+
+static void __exit tegra_pinctrl_exit(void)
+{
+	platform_driver_unregister(&tegra_pinctrl_driver);
+}
+module_exit(tegra_pinctrl_exit);
+
+MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, tegra_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-tegra.h b/drivers/pinctrl/pinctrl-tegra.h
new file mode 100644
index 0000000..782c795
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra.h
@@ -0,0 +1,163 @@
+/*
+ * Driver for the NVIDIA Tegra pinmux
+ *
+ * Copyright (c) 2011, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#ifndef __PINMUX_TEGRA_H__
+#define __PINMUX_TEGRA_H__
+
+/**
+ * struct tegra_function - Tegra pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct tegra_function {
+	const char *name;
+	const char * const *groups;
+	unsigned ngroups;
+};
+
+/**
+ * struct tegra_pingroup - Tegra pin group
+ * @mux_reg:		Mux register offset. -1 if unsupported.
+ * @mux_bank:		Mux register bank. 0 if unsupported.
+ * @mux_bit:		Mux register bit. 0 if unsupported.
+ * @pupd_reg:		Pull-up/down register offset. -1 if unsupported.
+ * @pupd_bank:		Pull-up/down register bank. 0 if unsupported.
+ * @pupd_bit:		Pull-up/down register bit. 0 if unsupported.
+ * @tri_reg:		Tri-state register offset. -1 if unsupported.
+ * @tri_bank:		Tri-state register bank. 0 if unsupported.
+ * @tri_bit:		Tri-state register bit. 0 if unsupported.
+ * @einput_reg:		Enable-input register offset. -1 if unsupported.
+ * @einput_bank:	Enable-input register bank. 0 if unsupported.
+ * @einput_bit:		Enable-input register bit. 0 if unsupported.
+ * @odrain_reg:		Open-drain register offset. -1 if unsupported.
+ * @odrain_bank:	Open-drain register bank. 0 if unsupported.
+ * @odrain_bit:		Open-drain register bit. 0 if unsupported.
+ * @lock_reg:		Lock register offset. -1 if unsupported.
+ * @lock_bank:		Lock register bank. 0 if unsupported.
+ * @lock_bit:		Lock register bit. 0 if unsupported.
+ * @ioreset_reg:	IO reset register offset. -1 if unsupported.
+ * @ioreset_bank:	IO reset register bank. 0 if unsupported.
+ * @ioreset_bit:	IO reset register bit. 0 if unsupported.
+ * @drv_reg:		Drive fields register offset. -1 if unsupported.
+ *			This register contains the hsm, schmitt, lpmd, drvdn,
+ *			drvup, slwr, and slwf parameters.
+ * @drv_bank:		Drive fields register bank. 0 if unsupported.
+ * @hsm_bit:		High Speed Mode register bit. 0 if unsupported.
+ * @schmitt_bit:	Scmitt register bit. 0 if unsupported.
+ * @lpmd_bit:		Low Power Mode register bit. 0 if unsupported.
+ * @drvdn_bit:		Drive Down register bit. 0 if unsupported.
+ * @drvdn_width:	Drive Down field width. 0 if unsupported.
+ * @drvup_bit:		Drive Up register bit. 0 if unsupported.
+ * @drvup_width:	Drive Up field width. 0 if unsupported.
+ * @slwr_bit:		Slew Rising register bit. 0 if unsupported.
+ * @slwr_width:		Slew Rising field width. 0 if unsupported.
+ * @slwf_bit:		Slew Falling register bit. 0 if unsupported.
+ * @slwf_width:		Slew Falling field width. 0 if unsupported.
+ *
+ * A representation of a group of pins (possibly just one pin) in the Tegra
+ * pin controller. Each group allows some parameter or parameters to be
+ * configured. The most common is mux function selection. Many others exist
+ * such as pull-up/down, tri-state, etc. Tegra's pin controller is complex;
+ * certain groups may only support configuring certain parameters, hence
+ * each parameter is optional, represented by a -1 "reg" value.
+ */
+struct tegra_pingroup {
+	const char *name;
+	const unsigned *pins;
+	unsigned npins;
+	unsigned funcs[4];
+	unsigned func_safe;
+	s16 mux_reg;
+	s16 pupd_reg;
+	s16 tri_reg;
+	s16 einput_reg;
+	s16 odrain_reg;
+	s16 lock_reg;
+	s16 ioreset_reg;
+	s16 drv_reg;
+	u32 mux_bank:2;
+	u32 pupd_bank:2;
+	u32 tri_bank:2;
+	u32 einput_bank:2;
+	u32 odrain_bank:2;
+	u32 ioreset_bank:2;
+	u32 lock_bank:2;
+	u32 drv_bank:2;
+	u32 mux_bit:5;
+	u32 pupd_bit:5;
+	u32 tri_bit:5;
+	u32 einput_bit:5;
+	u32 odrain_bit:5;
+	u32 lock_bit:5;
+	u32 ioreset_bit:5;
+	u32 hsm_bit:5;
+	u32 schmitt_bit:5;
+	u32 lpmd_bit:5;
+	u32 drvdn_bit:5;
+	u32 drvup_bit:5;
+	u32 slwr_bit:5;
+	u32 slwf_bit:5;
+	u32 drvdn_width:6;
+	u32 drvup_width:6;
+	u32 slwr_width:6;
+	u32 slwf_width:6;
+};
+
+/**
+ * struct tegra_pinctrl_soc_data - Tegra pin controller driver configuration
+ * @ngpios:	The number of GPIO pins the pin controller HW affects.
+ * @pins:	An array describing all pins the pin controller affects.
+ *		All pins which are also GPIOs must be listed first within the
+ *		array, and be numbered identically to the GPIO controller's
+ *		numbering.
+ * @npins:	The numbmer of entries in @pins.
+ * @functions:	An array describing all mux functions the SoC supports.
+ * @nfunctions:	The numbmer of entries in @functions.
+ * @groups:	An array describing all pin groups the pin SoC supports.
+ * @ngroups:	The numbmer of entries in @groups.
+ */
+struct tegra_pinctrl_soc_data {
+	unsigned ngpios;
+	const struct pinctrl_pin_desc *pins;
+	unsigned npins;
+	const struct tegra_function *functions;
+	unsigned nfunctions;
+	const struct tegra_pingroup *groups;
+	unsigned ngroups;
+};
+
+/**
+ * tegra_pinctrl_soc_initf() - Retrieve pin controller details for a SoC.
+ * @soc_data:	This pointer must be updated to point at a struct containing
+ *		details of the SoC.
+ */
+typedef void (*tegra_pinctrl_soc_initf)(
+			const struct tegra_pinctrl_soc_data **soc_data);
+
+/**
+ * tegra20_pinctrl_init() - Retrieve pin controller details for Tegra20
+ * @soc_data:	This pointer will be updated to point at a struct containing
+ *		details of Tegra20's pin controller.
+ */
+void tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
+/**
+ * tegra30_pinctrl_init() - Retrieve pin controller details for Tegra20
+ * @soc_data:	This pointer will be updated to point at a struct containing
+ *		details of Tegra30's pin controller.
+ */
+void tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
+
+#endif
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
new file mode 100644
index 0000000..f69ff96
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -0,0 +1,2860 @@
+/*
+ * Pinctrl data for the NVIDIA Tegra20 pinmux
+ *
+ * Copyright (c) 2011, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * Derived from code:
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-tegra.h"
+
+/*
+ * Most pins affected by the pinmux can also be GPIOs. Define these first.
+ * These must match how the GPIO driver names/numbers its pins.
+ */
+#define _GPIO(offset)			(offset)
+
+#define TEGRA_PIN_VI_GP6_PA0		_GPIO(0)
+#define TEGRA_PIN_UART3_CTS_N_PA1	_GPIO(1)
+#define TEGRA_PIN_DAP2_FS_PA2		_GPIO(2)
+#define TEGRA_PIN_DAP2_SCLK_PA3		_GPIO(3)
+#define TEGRA_PIN_DAP2_DIN_PA4		_GPIO(4)
+#define TEGRA_PIN_DAP2_DOUT_PA5		_GPIO(5)
+#define TEGRA_PIN_SDIO3_CLK_PA6		_GPIO(6)
+#define TEGRA_PIN_SDIO3_CMD_PA7		_GPIO(7)
+#define TEGRA_PIN_GMI_AD17_PB0		_GPIO(8)
+#define TEGRA_PIN_GMI_AD18_PB1		_GPIO(9)
+#define TEGRA_PIN_LCD_PWR0_PB2		_GPIO(10)
+#define TEGRA_PIN_LCD_PCLK_PB3		_GPIO(11)
+#define TEGRA_PIN_SDIO3_DAT3_PB4	_GPIO(12)
+#define TEGRA_PIN_SDIO3_DAT2_PB5	_GPIO(13)
+#define TEGRA_PIN_SDIO3_DAT1_PB6	_GPIO(14)
+#define TEGRA_PIN_SDIO3_DAT0_PB7	_GPIO(15)
+#define TEGRA_PIN_UART3_RTS_N_PC0	_GPIO(16)
+#define TEGRA_PIN_LCD_PWR1_PC1		_GPIO(17)
+#define TEGRA_PIN_UART2_TXD_PC2		_GPIO(18)
+#define TEGRA_PIN_UART2_RXD_PC3		_GPIO(19)
+#define TEGRA_PIN_GEN1_I2C_SCL_PC4	_GPIO(20)
+#define TEGRA_PIN_GEN1_I2C_SDA_PC5	_GPIO(21)
+#define TEGRA_PIN_LCD_PWR2_PC6		_GPIO(22)
+#define TEGRA_PIN_GMI_WP_N_PC7		_GPIO(23)
+#define TEGRA_PIN_SDIO3_DAT5_PD0	_GPIO(24)
+#define TEGRA_PIN_SDIO3_DAT4_PD1	_GPIO(25)
+#define TEGRA_PIN_VI_GP5_PD2		_GPIO(26)
+#define TEGRA_PIN_SDIO3_DAT6_PD3	_GPIO(27)
+#define TEGRA_PIN_SDIO3_DAT7_PD4	_GPIO(28)
+#define TEGRA_PIN_VI_D1_PD5		_GPIO(29)
+#define TEGRA_PIN_VI_VSYNC_PD6		_GPIO(30)
+#define TEGRA_PIN_VI_HSYNC_PD7		_GPIO(31)
+#define TEGRA_PIN_LCD_D0_PE0		_GPIO(32)
+#define TEGRA_PIN_LCD_D1_PE1		_GPIO(33)
+#define TEGRA_PIN_LCD_D2_PE2		_GPIO(34)
+#define TEGRA_PIN_LCD_D3_PE3		_GPIO(35)
+#define TEGRA_PIN_LCD_D4_PE4		_GPIO(36)
+#define TEGRA_PIN_LCD_D5_PE5		_GPIO(37)
+#define TEGRA_PIN_LCD_D6_PE6		_GPIO(38)
+#define TEGRA_PIN_LCD_D7_PE7		_GPIO(39)
+#define TEGRA_PIN_LCD_D8_PF0		_GPIO(40)
+#define TEGRA_PIN_LCD_D9_PF1		_GPIO(41)
+#define TEGRA_PIN_LCD_D10_PF2		_GPIO(42)
+#define TEGRA_PIN_LCD_D11_PF3		_GPIO(43)
+#define TEGRA_PIN_LCD_D12_PF4		_GPIO(44)
+#define TEGRA_PIN_LCD_D13_PF5		_GPIO(45)
+#define TEGRA_PIN_LCD_D14_PF6		_GPIO(46)
+#define TEGRA_PIN_LCD_D15_PF7		_GPIO(47)
+#define TEGRA_PIN_GMI_AD0_PG0		_GPIO(48)
+#define TEGRA_PIN_GMI_AD1_PG1		_GPIO(49)
+#define TEGRA_PIN_GMI_AD2_PG2		_GPIO(50)
+#define TEGRA_PIN_GMI_AD3_PG3		_GPIO(51)
+#define TEGRA_PIN_GMI_AD4_PG4		_GPIO(52)
+#define TEGRA_PIN_GMI_AD5_PG5		_GPIO(53)
+#define TEGRA_PIN_GMI_AD6_PG6		_GPIO(54)
+#define TEGRA_PIN_GMI_AD7_PG7		_GPIO(55)
+#define TEGRA_PIN_GMI_AD8_PH0		_GPIO(56)
+#define TEGRA_PIN_GMI_AD9_PH1		_GPIO(57)
+#define TEGRA_PIN_GMI_AD10_PH2		_GPIO(58)
+#define TEGRA_PIN_GMI_AD11_PH3		_GPIO(59)
+#define TEGRA_PIN_GMI_AD12_PH4		_GPIO(60)
+#define TEGRA_PIN_GMI_AD13_PH5		_GPIO(61)
+#define TEGRA_PIN_GMI_AD14_PH6		_GPIO(62)
+#define TEGRA_PIN_GMI_AD15_PH7		_GPIO(63)
+#define TEGRA_PIN_GMI_HIOW_N_PI0	_GPIO(64)
+#define TEGRA_PIN_GMI_HIOR_N_PI1	_GPIO(65)
+#define TEGRA_PIN_GMI_CS5_N_PI2		_GPIO(66)
+#define TEGRA_PIN_GMI_CS6_N_PI3		_GPIO(67)
+#define TEGRA_PIN_GMI_RST_N_PI4		_GPIO(68)
+#define TEGRA_PIN_GMI_IORDY_PI5		_GPIO(69)
+#define TEGRA_PIN_GMI_CS7_N_PI6		_GPIO(70)
+#define TEGRA_PIN_GMI_WAIT_PI7		_GPIO(71)
+#define TEGRA_PIN_GMI_CS0_N_PJ0		_GPIO(72)
+#define TEGRA_PIN_LCD_DE_PJ1		_GPIO(73)
+#define TEGRA_PIN_GMI_CS1_N_PJ2		_GPIO(74)
+#define TEGRA_PIN_LCD_HSYNC_PJ3		_GPIO(75)
+#define TEGRA_PIN_LCD_VSYNC_PJ4		_GPIO(76)
+#define TEGRA_PIN_UART2_CTS_N_PJ5	_GPIO(77)
+#define TEGRA_PIN_UART2_RTS_N_PJ6	_GPIO(78)
+#define TEGRA_PIN_GMI_AD16_PJ7		_GPIO(79)
+#define TEGRA_PIN_GMI_ADV_N_PK0		_GPIO(80)
+#define TEGRA_PIN_GMI_CLK_PK1		_GPIO(81)
+#define TEGRA_PIN_GMI_CS4_N_PK2		_GPIO(82)
+#define TEGRA_PIN_GMI_CS2_N_PK3		_GPIO(83)
+#define TEGRA_PIN_GMI_CS3_N_PK4		_GPIO(84)
+#define TEGRA_PIN_SPDIF_OUT_PK5		_GPIO(85)
+#define TEGRA_PIN_SPDIF_IN_PK6		_GPIO(86)
+#define TEGRA_PIN_GMI_AD19_PK7		_GPIO(87)
+#define TEGRA_PIN_VI_D2_PL0		_GPIO(88)
+#define TEGRA_PIN_VI_D3_PL1		_GPIO(89)
+#define TEGRA_PIN_VI_D4_PL2		_GPIO(90)
+#define TEGRA_PIN_VI_D5_PL3		_GPIO(91)
+#define TEGRA_PIN_VI_D6_PL4		_GPIO(92)
+#define TEGRA_PIN_VI_D7_PL5		_GPIO(93)
+#define TEGRA_PIN_VI_D8_PL6		_GPIO(94)
+#define TEGRA_PIN_VI_D9_PL7		_GPIO(95)
+#define TEGRA_PIN_LCD_D16_PM0		_GPIO(96)
+#define TEGRA_PIN_LCD_D17_PM1		_GPIO(97)
+#define TEGRA_PIN_LCD_D18_PM2		_GPIO(98)
+#define TEGRA_PIN_LCD_D19_PM3		_GPIO(99)
+#define TEGRA_PIN_LCD_D20_PM4		_GPIO(100)
+#define TEGRA_PIN_LCD_D21_PM5		_GPIO(101)
+#define TEGRA_PIN_LCD_D22_PM6		_GPIO(102)
+#define TEGRA_PIN_LCD_D23_PM7		_GPIO(103)
+#define TEGRA_PIN_DAP1_FS_PN0		_GPIO(104)
+#define TEGRA_PIN_DAP1_DIN_PN1		_GPIO(105)
+#define TEGRA_PIN_DAP1_DOUT_PN2		_GPIO(106)
+#define TEGRA_PIN_DAP1_SCLK_PN3		_GPIO(107)
+#define TEGRA_PIN_LCD_CS0_N_PN4		_GPIO(108)
+#define TEGRA_PIN_LCD_SDOUT_PN5		_GPIO(109)
+#define TEGRA_PIN_LCD_DC0_PN6		_GPIO(110)
+#define TEGRA_PIN_HDMI_INT_N_PN7	_GPIO(111)
+#define TEGRA_PIN_ULPI_DATA7_PO0	_GPIO(112)
+#define TEGRA_PIN_ULPI_DATA0_PO1	_GPIO(113)
+#define TEGRA_PIN_ULPI_DATA1_PO2	_GPIO(114)
+#define TEGRA_PIN_ULPI_DATA2_PO3	_GPIO(115)
+#define TEGRA_PIN_ULPI_DATA3_PO4	_GPIO(116)
+#define TEGRA_PIN_ULPI_DATA4_PO5	_GPIO(117)
+#define TEGRA_PIN_ULPI_DATA5_PO6	_GPIO(118)
+#define TEGRA_PIN_ULPI_DATA6_PO7	_GPIO(119)
+#define TEGRA_PIN_DAP3_FS_PP0		_GPIO(120)
+#define TEGRA_PIN_DAP3_DIN_PP1		_GPIO(121)
+#define TEGRA_PIN_DAP3_DOUT_PP2		_GPIO(122)
+#define TEGRA_PIN_DAP3_SCLK_PP3		_GPIO(123)
+#define TEGRA_PIN_DAP4_FS_PP4		_GPIO(124)
+#define TEGRA_PIN_DAP4_DIN_PP5		_GPIO(125)
+#define TEGRA_PIN_DAP4_DOUT_PP6		_GPIO(126)
+#define TEGRA_PIN_DAP4_SCLK_PP7		_GPIO(127)
+#define TEGRA_PIN_KB_COL0_PQ0		_GPIO(128)
+#define TEGRA_PIN_KB_COL1_PQ1		_GPIO(129)
+#define TEGRA_PIN_KB_COL2_PQ2		_GPIO(130)
+#define TEGRA_PIN_KB_COL3_PQ3		_GPIO(131)
+#define TEGRA_PIN_KB_COL4_PQ4		_GPIO(132)
+#define TEGRA_PIN_KB_COL5_PQ5		_GPIO(133)
+#define TEGRA_PIN_KB_COL6_PQ6		_GPIO(134)
+#define TEGRA_PIN_KB_COL7_PQ7		_GPIO(135)
+#define TEGRA_PIN_KB_ROW0_PR0		_GPIO(136)
+#define TEGRA_PIN_KB_ROW1_PR1		_GPIO(137)
+#define TEGRA_PIN_KB_ROW2_PR2		_GPIO(138)
+#define TEGRA_PIN_KB_ROW3_PR3		_GPIO(139)
+#define TEGRA_PIN_KB_ROW4_PR4		_GPIO(140)
+#define TEGRA_PIN_KB_ROW5_PR5		_GPIO(141)
+#define TEGRA_PIN_KB_ROW6_PR6		_GPIO(142)
+#define TEGRA_PIN_KB_ROW7_PR7		_GPIO(143)
+#define TEGRA_PIN_KB_ROW8_PS0		_GPIO(144)
+#define TEGRA_PIN_KB_ROW9_PS1		_GPIO(145)
+#define TEGRA_PIN_KB_ROW10_PS2		_GPIO(146)
+#define TEGRA_PIN_KB_ROW11_PS3		_GPIO(147)
+#define TEGRA_PIN_KB_ROW12_PS4		_GPIO(148)
+#define TEGRA_PIN_KB_ROW13_PS5		_GPIO(149)
+#define TEGRA_PIN_KB_ROW14_PS6		_GPIO(150)
+#define TEGRA_PIN_KB_ROW15_PS7		_GPIO(151)
+#define TEGRA_PIN_VI_PCLK_PT0		_GPIO(152)
+#define TEGRA_PIN_VI_MCLK_PT1		_GPIO(153)
+#define TEGRA_PIN_VI_D10_PT2		_GPIO(154)
+#define TEGRA_PIN_VI_D11_PT3		_GPIO(155)
+#define TEGRA_PIN_VI_D0_PT4		_GPIO(156)
+#define TEGRA_PIN_GEN2_I2C_SCL_PT5	_GPIO(157)
+#define TEGRA_PIN_GEN2_I2C_SDA_PT6	_GPIO(158)
+#define TEGRA_PIN_GMI_DPD_PT7		_GPIO(159)
+#define TEGRA_PIN_PU0			_GPIO(160)
+#define TEGRA_PIN_PU1			_GPIO(161)
+#define TEGRA_PIN_PU2			_GPIO(162)
+#define TEGRA_PIN_PU3			_GPIO(163)
+#define TEGRA_PIN_PU4			_GPIO(164)
+#define TEGRA_PIN_PU5			_GPIO(165)
+#define TEGRA_PIN_PU6			_GPIO(166)
+#define TEGRA_PIN_JTAG_RTCK_PU7		_GPIO(167)
+#define TEGRA_PIN_PV0			_GPIO(168)
+#define TEGRA_PIN_PV1			_GPIO(169)
+#define TEGRA_PIN_PV2			_GPIO(170)
+#define TEGRA_PIN_PV3			_GPIO(171)
+#define TEGRA_PIN_PV4			_GPIO(172)
+#define TEGRA_PIN_PV5			_GPIO(173)
+#define TEGRA_PIN_PV6			_GPIO(174)
+#define TEGRA_PIN_LCD_DC1_PV7		_GPIO(175)
+#define TEGRA_PIN_LCD_CS1_N_PW0		_GPIO(176)
+#define TEGRA_PIN_LCD_M1_PW1		_GPIO(177)
+#define TEGRA_PIN_SPI2_CS1_N_PW2	_GPIO(178)
+#define TEGRA_PIN_SPI2_CS2_N_PW3	_GPIO(179)
+#define TEGRA_PIN_DAP_MCLK1_PW4		_GPIO(180)
+#define TEGRA_PIN_DAP_MCLK2_PW5		_GPIO(181)
+#define TEGRA_PIN_UART3_TXD_PW6		_GPIO(182)
+#define TEGRA_PIN_UART3_RXD_PW7		_GPIO(183)
+#define TEGRA_PIN_SPI2_MOSI_PX0		_GPIO(184)
+#define TEGRA_PIN_SPI2_MISO_PX1		_GPIO(185)
+#define TEGRA_PIN_SPI2_SCK_PX2		_GPIO(186)
+#define TEGRA_PIN_SPI2_CS0_N_PX3	_GPIO(187)
+#define TEGRA_PIN_SPI1_MOSI_PX4		_GPIO(188)
+#define TEGRA_PIN_SPI1_SCK_PX5		_GPIO(189)
+#define TEGRA_PIN_SPI1_CS0_N_PX6	_GPIO(190)
+#define TEGRA_PIN_SPI1_MISO_PX7		_GPIO(191)
+#define TEGRA_PIN_ULPI_CLK_PY0		_GPIO(192)
+#define TEGRA_PIN_ULPI_DIR_PY1		_GPIO(193)
+#define TEGRA_PIN_ULPI_NXT_PY2		_GPIO(194)
+#define TEGRA_PIN_ULPI_STP_PY3		_GPIO(195)
+#define TEGRA_PIN_SDIO1_DAT3_PY4	_GPIO(196)
+#define TEGRA_PIN_SDIO1_DAT2_PY5	_GPIO(197)
+#define TEGRA_PIN_SDIO1_DAT1_PY6	_GPIO(198)
+#define TEGRA_PIN_SDIO1_DAT0_PY7	_GPIO(199)
+#define TEGRA_PIN_SDIO1_CLK_PZ0		_GPIO(200)
+#define TEGRA_PIN_SDIO1_CMD_PZ1		_GPIO(201)
+#define TEGRA_PIN_LCD_SDIN_PZ2		_GPIO(202)
+#define TEGRA_PIN_LCD_WR_N_PZ3		_GPIO(203)
+#define TEGRA_PIN_LCD_SCK_PZ4		_GPIO(204)
+#define TEGRA_PIN_SYS_CLK_REQ_PZ5	_GPIO(205)
+#define TEGRA_PIN_PWR_I2C_SCL_PZ6	_GPIO(206)
+#define TEGRA_PIN_PWR_I2C_SDA_PZ7	_GPIO(207)
+#define TEGRA_PIN_GMI_AD20_PAA0		_GPIO(208)
+#define TEGRA_PIN_GMI_AD21_PAA1		_GPIO(209)
+#define TEGRA_PIN_GMI_AD22_PAA2		_GPIO(210)
+#define TEGRA_PIN_GMI_AD23_PAA3		_GPIO(211)
+#define TEGRA_PIN_GMI_AD24_PAA4		_GPIO(212)
+#define TEGRA_PIN_GMI_AD25_PAA5		_GPIO(213)
+#define TEGRA_PIN_GMI_AD26_PAA6		_GPIO(214)
+#define TEGRA_PIN_GMI_AD27_PAA7		_GPIO(215)
+#define TEGRA_PIN_LED_BLINK_PBB0	_GPIO(216)
+#define TEGRA_PIN_VI_GP0_PBB1		_GPIO(217)
+#define TEGRA_PIN_CAM_I2C_SCL_PBB2	_GPIO(218)
+#define TEGRA_PIN_CAM_I2C_SDA_PBB3	_GPIO(219)
+#define TEGRA_PIN_VI_GP3_PBB4		_GPIO(220)
+#define TEGRA_PIN_VI_GP4_PBB5		_GPIO(221)
+#define TEGRA_PIN_PBB6			_GPIO(222)
+#define TEGRA_PIN_PBB7			_GPIO(223)
+
+/* All non-GPIO pins follow */
+#define NUM_GPIOS			(TEGRA_PIN_PBB7 + 1)
+#define _PIN(offset)			(NUM_GPIOS + (offset))
+
+#define TEGRA_PIN_CRT_HSYNC		_PIN(30)
+#define TEGRA_PIN_CRT_VSYNC		_PIN(31)
+#define TEGRA_PIN_DDC_SCL		_PIN(32)
+#define TEGRA_PIN_DDC_SDA		_PIN(33)
+#define TEGRA_PIN_OWC			_PIN(34)
+#define TEGRA_PIN_CORE_PWR_REQ		_PIN(35)
+#define TEGRA_PIN_CPU_PWR_REQ		_PIN(36)
+#define TEGRA_PIN_PWR_INT_N		_PIN(37)
+#define TEGRA_PIN_CLK_32_K_IN		_PIN(38)
+#define TEGRA_PIN_DDR_COMP_PD		_PIN(39)
+#define TEGRA_PIN_DDR_COMP_PU		_PIN(40)
+#define TEGRA_PIN_DDR_A0		_PIN(41)
+#define TEGRA_PIN_DDR_A1		_PIN(42)
+#define TEGRA_PIN_DDR_A2		_PIN(43)
+#define TEGRA_PIN_DDR_A3		_PIN(44)
+#define TEGRA_PIN_DDR_A4		_PIN(45)
+#define TEGRA_PIN_DDR_A5		_PIN(46)
+#define TEGRA_PIN_DDR_A6		_PIN(47)
+#define TEGRA_PIN_DDR_A7		_PIN(48)
+#define TEGRA_PIN_DDR_A8		_PIN(49)
+#define TEGRA_PIN_DDR_A9		_PIN(50)
+#define TEGRA_PIN_DDR_A10		_PIN(51)
+#define TEGRA_PIN_DDR_A11		_PIN(52)
+#define TEGRA_PIN_DDR_A12		_PIN(53)
+#define TEGRA_PIN_DDR_A13		_PIN(54)
+#define TEGRA_PIN_DDR_A14		_PIN(55)
+#define TEGRA_PIN_DDR_CAS_N		_PIN(56)
+#define TEGRA_PIN_DDR_BA0		_PIN(57)
+#define TEGRA_PIN_DDR_BA1		_PIN(58)
+#define TEGRA_PIN_DDR_BA2		_PIN(59)
+#define TEGRA_PIN_DDR_DQS0P		_PIN(60)
+#define TEGRA_PIN_DDR_DQS0N		_PIN(61)
+#define TEGRA_PIN_DDR_DQS1P		_PIN(62)
+#define TEGRA_PIN_DDR_DQS1N		_PIN(63)
+#define TEGRA_PIN_DDR_DQS2P		_PIN(64)
+#define TEGRA_PIN_DDR_DQS2N		_PIN(65)
+#define TEGRA_PIN_DDR_DQS3P		_PIN(66)
+#define TEGRA_PIN_DDR_DQS3N		_PIN(67)
+#define TEGRA_PIN_DDR_CKE0		_PIN(68)
+#define TEGRA_PIN_DDR_CKE1		_PIN(69)
+#define TEGRA_PIN_DDR_CLK		_PIN(70)
+#define TEGRA_PIN_DDR_CLK_N		_PIN(71)
+#define TEGRA_PIN_DDR_DM0		_PIN(72)
+#define TEGRA_PIN_DDR_DM1		_PIN(73)
+#define TEGRA_PIN_DDR_DM2		_PIN(74)
+#define TEGRA_PIN_DDR_DM3		_PIN(75)
+#define TEGRA_PIN_DDR_ODT		_PIN(76)
+#define TEGRA_PIN_DDR_QUSE0		_PIN(77)
+#define TEGRA_PIN_DDR_QUSE1		_PIN(78)
+#define TEGRA_PIN_DDR_QUSE2		_PIN(79)
+#define TEGRA_PIN_DDR_QUSE3		_PIN(80)
+#define TEGRA_PIN_DDR_RAS_N		_PIN(81)
+#define TEGRA_PIN_DDR_WE_N		_PIN(82)
+#define TEGRA_PIN_DDR_DQ0		_PIN(83)
+#define TEGRA_PIN_DDR_DQ1		_PIN(84)
+#define TEGRA_PIN_DDR_DQ2		_PIN(85)
+#define TEGRA_PIN_DDR_DQ3		_PIN(86)
+#define TEGRA_PIN_DDR_DQ4		_PIN(87)
+#define TEGRA_PIN_DDR_DQ5		_PIN(88)
+#define TEGRA_PIN_DDR_DQ6		_PIN(89)
+#define TEGRA_PIN_DDR_DQ7		_PIN(90)
+#define TEGRA_PIN_DDR_DQ8		_PIN(91)
+#define TEGRA_PIN_DDR_DQ9		_PIN(92)
+#define TEGRA_PIN_DDR_DQ10		_PIN(93)
+#define TEGRA_PIN_DDR_DQ11		_PIN(94)
+#define TEGRA_PIN_DDR_DQ12		_PIN(95)
+#define TEGRA_PIN_DDR_DQ13		_PIN(96)
+#define TEGRA_PIN_DDR_DQ14		_PIN(97)
+#define TEGRA_PIN_DDR_DQ15		_PIN(98)
+#define TEGRA_PIN_DDR_DQ16		_PIN(99)
+#define TEGRA_PIN_DDR_DQ17		_PIN(100)
+#define TEGRA_PIN_DDR_DQ18		_PIN(101)
+#define TEGRA_PIN_DDR_DQ19		_PIN(102)
+#define TEGRA_PIN_DDR_DQ20		_PIN(103)
+#define TEGRA_PIN_DDR_DQ21		_PIN(104)
+#define TEGRA_PIN_DDR_DQ22		_PIN(105)
+#define TEGRA_PIN_DDR_DQ23		_PIN(106)
+#define TEGRA_PIN_DDR_DQ24		_PIN(107)
+#define TEGRA_PIN_DDR_DQ25		_PIN(108)
+#define TEGRA_PIN_DDR_DQ26		_PIN(109)
+#define TEGRA_PIN_DDR_DQ27		_PIN(110)
+#define TEGRA_PIN_DDR_DQ28		_PIN(111)
+#define TEGRA_PIN_DDR_DQ29		_PIN(112)
+#define TEGRA_PIN_DDR_DQ30		_PIN(113)
+#define TEGRA_PIN_DDR_DQ31		_PIN(114)
+#define TEGRA_PIN_DDR_CS0_N		_PIN(115)
+#define TEGRA_PIN_DDR_CS1_N		_PIN(116)
+#define TEGRA_PIN_SYS_RESET		_PIN(117)
+#define TEGRA_PIN_JTAG_TRST_N		_PIN(118)
+#define TEGRA_PIN_JTAG_TDO		_PIN(119)
+#define TEGRA_PIN_JTAG_TMS		_PIN(120)
+#define TEGRA_PIN_JTAG_TCK		_PIN(121)
+#define TEGRA_PIN_JTAG_TDI		_PIN(122)
+#define TEGRA_PIN_TEST_MODE_EN		_PIN(123)
+
+static const struct pinctrl_pin_desc tegra20_pins[] = {
+	PINCTRL_PIN(TEGRA_PIN_VI_GP6_PA0, "VI_GP6 PA0"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_CTS_N_PA1, "UART3_CTS_N PA1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PA2, "DAP2_FS PA2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PA3, "DAP2_SCLK PA3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PA4, "DAP2_DIN PA4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PA5, "DAP2_DOUT PA5"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_CLK_PA6, "SDIO3_CLK PA6"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_CMD_PA7, "SDIO3_CMD PA7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD17_PB0, "GMI_AD17 PB0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD18_PB1, "GMI_AD18 PB1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PWR0_PB2, "LCD_PWR0 PB2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PCLK_PB3, "LCD_PCLK PB3"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT3_PB4, "SDIO3_DAT3 PB4"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT2_PB5, "SDIO3_DAT2 PB5"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT1_PB6, "SDIO3_DAT1 PB6"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT0_PB7, "SDIO3_DAT0 PB7"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_RTS_N_PC0, "UART3_RTS_N PC0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PWR1_PC1, "LCD_PWR1 PC1"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_TXD_PC2, "UART2_TXD PC2"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_RXD_PC3, "UART2_RXD PC3"),
+	PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PC4, "GEN1_I2C_SCL PC4"),
+	PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PC5, "GEN1_I2C_SDA PC5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PWR2_PC6, "LCD_PWR2 PC6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WP_N_PC7, "GMI_WP_N PC7"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT5_PD0, "SDIO3_DAT5 PD0"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT4_PD1, "SDIO3_DAT4 PD1"),
+	PINCTRL_PIN(TEGRA_PIN_VI_GP5_PD2, "VI_GP5 PD2"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT6_PD3, "SDIO3_DAT6 PD3"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT7_PD4, "SDIO3_DAT7 PD4"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D1_PD5, "VI_D1 PD5"),
+	PINCTRL_PIN(TEGRA_PIN_VI_VSYNC_PD6, "VI_VSYNC PD6"),
+	PINCTRL_PIN(TEGRA_PIN_VI_HSYNC_PD7, "VI_HSYNC PD7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D0_PE0, "LCD_D0 PE0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D1_PE1, "LCD_D1 PE1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D2_PE2, "LCD_D2 PE2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D3_PE3, "LCD_D3 PE3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D4_PE4, "LCD_D4 PE4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D5_PE5, "LCD_D5 PE5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D6_PE6, "LCD_D6 PE6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D7_PE7, "LCD_D7 PE7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D8_PF0, "LCD_D8 PF0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D9_PF1, "LCD_D9 PF1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D10_PF2, "LCD_D10 PF2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D11_PF3, "LCD_D11 PF3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D12_PF4, "LCD_D12 PF4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D13_PF5, "LCD_D13 PF5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D14_PF6, "LCD_D14 PF6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D15_PF7, "LCD_D15 PF7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD0_PG0, "GMI_AD0 PG0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD1_PG1, "GMI_AD1 PG1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD2_PG2, "GMI_AD2 PG2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD3_PG3, "GMI_AD3 PG3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD4_PG4, "GMI_AD4 PG4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD5_PG5, "GMI_AD5 PG5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD6_PG6, "GMI_AD6 PG6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD7_PG7, "GMI_AD7 PG7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD8_PH0, "GMI_AD8 PH0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD9_PH1, "GMI_AD9 PH1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD10_PH2, "GMI_AD10 PH2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD11_PH3, "GMI_AD11 PH3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD12_PH4, "GMI_AD12 PH4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD13_PH5, "GMI_AD13 PH5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD14_PH6, "GMI_AD14 PH6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD15_PH7, "GMI_AD15 PH7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_HIOW_N_PI0, "GMI_HIOW_N PI0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_HIOR_N_PI1, "GMI_HIOR_N PI1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS5_N_PI2, "GMI_CS5_N PI2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS6_N_PI3, "GMI_CS6_N PI3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_RST_N_PI4, "GMI_RST_N PI4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_IORDY_PI5, "GMI_IORDY PI5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS7_N_PI6, "GMI_CS7_N PI6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WAIT_PI7, "GMI_WAIT PI7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS0_N_PJ0, "GMI_CS0_N PJ0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_DE_PJ1, "LCD_DE PJ1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS1_N_PJ2, "GMI_CS1_N PJ2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_HSYNC_PJ3, "LCD_HSYNC PJ3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_VSYNC_PJ4, "LCD_VSYNC PJ4"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_CTS_N_PJ5, "UART2_CTS_N PJ5"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_RTS_N_PJ6, "UART2_RTS_N PJ6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD16_PJ7, "GMI_AD16 PJ7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_ADV_N_PK0, "GMI_ADV_N PK0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CLK_PK1, "GMI_CLK PK1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS4_N_PK2, "GMI_CS4_N PK2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS2_N_PK3, "GMI_CS2_N PK3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS3_N_PK4, "GMI_CS3_N PK4"),
+	PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PK5, "SPDIF_OUT PK5"),
+	PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PK6, "SPDIF_IN PK6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD19_PK7, "GMI_AD19 PK7"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D2_PL0, "VI_D2 PL0"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D3_PL1, "VI_D3 PL1"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D4_PL2, "VI_D4 PL2"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D5_PL3, "VI_D5 PL3"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D6_PL4, "VI_D6 PL4"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D7_PL5, "VI_D7 PL5"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D8_PL6, "VI_D8 PL6"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D9_PL7, "VI_D9 PL7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D16_PM0, "LCD_D16 PM0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D17_PM1, "LCD_D17 PM1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D18_PM2, "LCD_D18 PM2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D19_PM3, "LCD_D19 PM3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D20_PM4, "LCD_D20 PM4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D21_PM5, "LCD_D21 PM5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D22_PM6, "LCD_D22 PM6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D23_PM7, "LCD_D23 PM7"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PN0, "DAP1_FS PN0"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PN1, "DAP1_DIN PN1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PN2, "DAP1_DOUT PN2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PN3, "DAP1_SCLK PN3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_CS0_N_PN4, "LCD_CS0_N PN4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_SDOUT_PN5, "LCD_SDOUT PN5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_DC0_PN6, "LCD_DC0 PN6"),
+	PINCTRL_PIN(TEGRA_PIN_HDMI_INT_N_PN7, "HDMI_INT_N PN7"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA7_PO0, "ULPI_DATA7 PO0"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA0_PO1, "ULPI_DATA0 PO1"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA1_PO2, "ULPI_DATA1 PO2"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA2_PO3, "ULPI_DATA2 PO3"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA3_PO4, "ULPI_DATA3 PO4"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA4_PO5, "ULPI_DATA4 PO5"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA5_PO6, "ULPI_DATA5 PO6"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA6_PO7, "ULPI_DATA6 PO7"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_FS_PP0, "DAP3_FS PP0"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_DIN_PP1, "DAP3_DIN PP1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_DOUT_PP2, "DAP3_DOUT PP2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_SCLK_PP3, "DAP3_SCLK PP3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PP4, "DAP4_FS PP4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PP5, "DAP4_DIN PP5"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PP6, "DAP4_DOUT PP6"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PP7, "DAP4_SCLK PP7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL0_PQ0, "KB_COL0 PQ0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL1_PQ1, "KB_COL1 PQ1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL2_PQ2, "KB_COL2 PQ2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL3_PQ3, "KB_COL3 PQ3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL4_PQ4, "KB_COL4 PQ4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL5_PQ5, "KB_COL5 PQ5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL6_PQ6, "KB_COL6 PQ6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL7_PQ7, "KB_COL7 PQ7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW0_PR0, "KB_ROW0 PR0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW1_PR1, "KB_ROW1 PR1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW2_PR2, "KB_ROW2 PR2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW3_PR3, "KB_ROW3 PR3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW4_PR4, "KB_ROW4 PR4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW5_PR5, "KB_ROW5 PR5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW6_PR6, "KB_ROW6 PR6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW7_PR7, "KB_ROW7 PR7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW8_PS0, "KB_ROW8 PS0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW9_PS1, "KB_ROW9 PS1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW10_PS2, "KB_ROW10 PS2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW11_PS3, "KB_ROW11 PS3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW12_PS4, "KB_ROW12 PS4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW13_PS5, "KB_ROW13 PS5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW14_PS6, "KB_ROW14 PS6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW15_PS7, "KB_ROW15 PS7"),
+	PINCTRL_PIN(TEGRA_PIN_VI_PCLK_PT0, "VI_PCLK PT0"),
+	PINCTRL_PIN(TEGRA_PIN_VI_MCLK_PT1, "VI_MCLK PT1"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D10_PT2, "VD_D10 PT2"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D11_PT3, "VI_D11 PT3"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D0_PT4, "VI_D0 PT4"),
+	PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PT5, "GEN2_I2C_SCL PT5"),
+	PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PT6, "GEN2_I2C_SDA PT6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_DPD_PT7, "GMI_DPD PT7"),
+	/* PU0..6: GPIO only */
+	PINCTRL_PIN(TEGRA_PIN_PU0, "PU0"),
+	PINCTRL_PIN(TEGRA_PIN_PU1, "PU1"),
+	PINCTRL_PIN(TEGRA_PIN_PU2, "PU2"),
+	PINCTRL_PIN(TEGRA_PIN_PU3, "PU3"),
+	PINCTRL_PIN(TEGRA_PIN_PU4, "PU4"),
+	PINCTRL_PIN(TEGRA_PIN_PU5, "PU5"),
+	PINCTRL_PIN(TEGRA_PIN_PU6, "PU6"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_RTCK_PU7, "JTAG_RTCK PU7"),
+	/* PV0..1: GPIO only */
+	PINCTRL_PIN(TEGRA_PIN_PV0, "PV0"),
+	PINCTRL_PIN(TEGRA_PIN_PV1, "PV1"),
+	/* PV2..3: Balls are named after GPIO not function */
+	PINCTRL_PIN(TEGRA_PIN_PV2, "PV2"),
+	PINCTRL_PIN(TEGRA_PIN_PV3, "PV3"),
+	/* PV4..6: GPIO only */
+	PINCTRL_PIN(TEGRA_PIN_PV4, "PV4"),
+	PINCTRL_PIN(TEGRA_PIN_PV5, "PV5"),
+	PINCTRL_PIN(TEGRA_PIN_PV6, "PV6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_DC1_PV7, "LCD_DC1 PV7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_CS1_N_PW0, "LCD_CS1_N PW0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_M1_PW1, "LCD_M1 PW1"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_CS1_N_PW2, "SPI2_CS1_N PW2"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_CS2_N_PW3, "SPI2_CS2_N PW3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP_MCLK1_PW4, "DAP_MCLK1 PW4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP_MCLK2_PW5, "DAP_MCLK2 PW5"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_TXD_PW6, "UART3_TXD PW6"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_RXD_PW7, "UART3_RXD PW7"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_MOSI_PX0, "SPI2_MOSI PX0"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_MISO_PX1, "SPI2_MISO PX1"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_SCK_PX2, "SPI2_SCK PX2"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_CS0_N_PX3, "SPI2_CS0_N PX3"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_MOSI_PX4, "SPI1_MOSI PX4"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_SCK_PX5, "SPI1_SCK PX5"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_CS0_N_PX6, "SPI1_CS0_N PX6"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_MISO_PX7, "SPI1_MISO PX7"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_CLK_PY0, "ULPI_CLK PY0"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DIR_PY1, "ULPI_DIR PY1"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_NXT_PY2, "ULPI_NXT PY2"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_STP_PY3, "ULPI_STP PY3"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT3_PY4, "SDIO1_DAT3 PY4"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT2_PY5, "SDIO1_DAT2 PY5"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT1_PY6, "SDIO1_DAT1 PY6"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT0_PY7, "SDIO1_DAT0 PY7"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO1_CLK_PZ0, "SDIO1_CLK PZ0"),
+	PINCTRL_PIN(TEGRA_PIN_SDIO1_CMD_PZ1, "SDIO1_CMD PZ1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_SDIN_PZ2, "LCD_SDIN PZ2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_WR_N_PZ3, "LCD_WR_N PZ3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_SCK_PZ4, "LCD_SCK PZ4"),
+	PINCTRL_PIN(TEGRA_PIN_SYS_CLK_REQ_PZ5, "SYS_CLK_REQ PZ5"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PZ6, "PWR_I2C_SCL PZ6"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PZ7, "PWR_I2C_SDA PZ7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD20_PAA0, "GMI_AD20 PAA0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD21_PAA1, "GMI_AD21 PAA1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD22_PAA2, "GMI_AD22 PAA2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD23_PAA3, "GMI_AD23 PAA3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD24_PAA4, "GMI_AD24 PAA4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD25_PAA5, "GMI_AD25 PAA5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD26_PAA6, "GMI_AD26 PAA6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD27_PAA7, "GMI_AD27 PAA7"),
+	PINCTRL_PIN(TEGRA_PIN_LED_BLINK_PBB0, "LED_BLINK PBB0"),
+	PINCTRL_PIN(TEGRA_PIN_VI_GP0_PBB1, "VI_GP0 PBB1"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PBB2, "CAM_I2C_SCL PBB2"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PBB3, "CAM_I2C_SDA PBB3"),
+	PINCTRL_PIN(TEGRA_PIN_VI_GP3_PBB4, "VI_GP3 PBB4"),
+	PINCTRL_PIN(TEGRA_PIN_VI_GP4_PBB5, "VI_GP4 PBB5"),
+	PINCTRL_PIN(TEGRA_PIN_PBB6, "PBB6"),
+	PINCTRL_PIN(TEGRA_PIN_PBB7, "PBB7"),
+	PINCTRL_PIN(TEGRA_PIN_CRT_HSYNC, "CRT_HSYNC"),
+	PINCTRL_PIN(TEGRA_PIN_CRT_VSYNC, "CRT_VSYNC"),
+	PINCTRL_PIN(TEGRA_PIN_DDC_SCL, "DDC_SCL"),
+	PINCTRL_PIN(TEGRA_PIN_DDC_SDA, "DDC_SDA"),
+	PINCTRL_PIN(TEGRA_PIN_OWC, "OWC"),
+	PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"),
+	PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"),
+	PINCTRL_PIN(TEGRA_PIN_CLK_32_K_IN, "CLK_32_K_IN"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_COMP_PD, "DDR_COMP_PD"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_COMP_PU, "DDR_COMP_PU"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A0, "DDR_A0"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A1, "DDR_A1"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A2, "DDR_A2"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A3, "DDR_A3"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A4, "DDR_A4"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A5, "DDR_A5"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A6, "DDR_A6"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A7, "DDR_A7"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A8, "DDR_A8"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A9, "DDR_A9"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A10, "DDR_A10"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A11, "DDR_A11"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A12, "DDR_A12"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A13, "DDR_A13"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_A14, "DDR_A14"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CAS_N, "DDR_CAS_N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_BA0, "DDR_BA0"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_BA1, "DDR_BA1"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_BA2, "DDR_BA2"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS0P, "DDR_DQS0P"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS0N, "DDR_DQS0N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS1P, "DDR_DQS1P"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS1N, "DDR_DQS1N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS2P, "DDR_DQS2P"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS2N, "DDR_DQS2N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS3P, "DDR_DQS3P"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQS3N, "DDR_DQS3N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CKE0, "DDR_CKE0"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CKE1, "DDR_CKE1"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CLK, "DDR_CLK"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CLK_N, "DDR_CLK_N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DM0, "DDR_DM0"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DM1, "DDR_DM1"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DM2, "DDR_DM2"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DM3, "DDR_DM3"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_ODT, "DDR_ODT"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_QUSE0, "DDR_QUSE0"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_QUSE1, "DDR_QUSE1"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_QUSE2, "DDR_QUSE2"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_QUSE3, "DDR_QUSE3"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_RAS_N, "DDR_RAS_N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_WE_N, "DDR_WE_N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ0, "DDR_DQ0"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ1, "DDR_DQ1"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ2, "DDR_DQ2"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ3, "DDR_DQ3"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ4, "DDR_DQ4"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ5, "DDR_DQ5"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ6, "DDR_DQ6"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ7, "DDR_DQ7"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ8, "DDR_DQ8"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ9, "DDR_DQ9"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ10, "DDR_DQ10"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ11, "DDR_DQ11"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ12, "DDR_DQ12"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ13, "DDR_DQ13"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ14, "DDR_DQ14"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ15, "DDR_DQ15"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ16, "DDR_DQ16"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ17, "DDR_DQ17"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ18, "DDR_DQ18"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ19, "DDR_DQ19"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ20, "DDR_DQ20"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ21, "DDR_DQ21"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ22, "DDR_DQ22"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ23, "DDR_DQ23"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ24, "DDR_DQ24"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ25, "DDR_DQ25"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ26, "DDR_DQ26"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ27, "DDR_DQ27"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ28, "DDR_DQ28"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ29, "DDR_DQ29"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ30, "DDR_DQ30"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_DQ31, "DDR_DQ31"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CS0_N, "DDR_CS0_N"),
+	PINCTRL_PIN(TEGRA_PIN_DDR_CS1_N, "DDR_CS1_N"),
+	PINCTRL_PIN(TEGRA_PIN_SYS_RESET, "SYS_RESET"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TRST_N, "JTAG_TRST_N"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TDO, "JTAG_TDO"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TMS, "JTAG_TMS"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TCK, "JTAG_TCK"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TDI, "JTAG_TDI"),
+	PINCTRL_PIN(TEGRA_PIN_TEST_MODE_EN, "TEST_MODE_EN"),
+};
+
+static const unsigned ata_pins[] = {
+	TEGRA_PIN_GMI_CS6_N_PI3,
+	TEGRA_PIN_GMI_CS7_N_PI6,
+	TEGRA_PIN_GMI_RST_N_PI4,
+};
+
+static const unsigned atb_pins[] = {
+	TEGRA_PIN_GMI_CS5_N_PI2,
+	TEGRA_PIN_GMI_DPD_PT7,
+};
+
+static const unsigned atc_pins[] = {
+	TEGRA_PIN_GMI_IORDY_PI5,
+	TEGRA_PIN_GMI_WAIT_PI7,
+	TEGRA_PIN_GMI_ADV_N_PK0,
+	TEGRA_PIN_GMI_CLK_PK1,
+	TEGRA_PIN_GMI_CS2_N_PK3,
+	TEGRA_PIN_GMI_CS3_N_PK4,
+	TEGRA_PIN_GMI_CS4_N_PK2,
+	TEGRA_PIN_GMI_AD0_PG0,
+	TEGRA_PIN_GMI_AD1_PG1,
+	TEGRA_PIN_GMI_AD2_PG2,
+	TEGRA_PIN_GMI_AD3_PG3,
+	TEGRA_PIN_GMI_AD4_PG4,
+	TEGRA_PIN_GMI_AD5_PG5,
+	TEGRA_PIN_GMI_AD6_PG6,
+	TEGRA_PIN_GMI_AD7_PG7,
+	TEGRA_PIN_GMI_HIOW_N_PI0,
+	TEGRA_PIN_GMI_HIOR_N_PI1,
+};
+
+static const unsigned atd_pins[] = {
+	TEGRA_PIN_GMI_AD8_PH0,
+	TEGRA_PIN_GMI_AD9_PH1,
+	TEGRA_PIN_GMI_AD10_PH2,
+	TEGRA_PIN_GMI_AD11_PH3,
+};
+
+static const unsigned ate_pins[] = {
+	TEGRA_PIN_GMI_AD12_PH4,
+	TEGRA_PIN_GMI_AD13_PH5,
+	TEGRA_PIN_GMI_AD14_PH6,
+	TEGRA_PIN_GMI_AD15_PH7,
+};
+
+static const unsigned cdev1_pins[] = {
+	TEGRA_PIN_DAP_MCLK1_PW4,
+};
+
+static const unsigned cdev2_pins[] = {
+	TEGRA_PIN_DAP_MCLK2_PW5,
+};
+
+static const unsigned crtp_pins[] = {
+	TEGRA_PIN_CRT_HSYNC,
+	TEGRA_PIN_CRT_VSYNC,
+};
+
+static const unsigned csus_pins[] = {
+	TEGRA_PIN_VI_MCLK_PT1,
+};
+
+static const unsigned dap1_pins[] = {
+	TEGRA_PIN_DAP1_FS_PN0,
+	TEGRA_PIN_DAP1_DIN_PN1,
+	TEGRA_PIN_DAP1_DOUT_PN2,
+	TEGRA_PIN_DAP1_SCLK_PN3,
+};
+
+static const unsigned dap2_pins[] = {
+	TEGRA_PIN_DAP2_FS_PA2,
+	TEGRA_PIN_DAP2_SCLK_PA3,
+	TEGRA_PIN_DAP2_DIN_PA4,
+	TEGRA_PIN_DAP2_DOUT_PA5,
+};
+
+static const unsigned dap3_pins[] = {
+	TEGRA_PIN_DAP3_FS_PP0,
+	TEGRA_PIN_DAP3_DIN_PP1,
+	TEGRA_PIN_DAP3_DOUT_PP2,
+	TEGRA_PIN_DAP3_SCLK_PP3,
+};
+
+static const unsigned dap4_pins[] = {
+	TEGRA_PIN_DAP4_FS_PP4,
+	TEGRA_PIN_DAP4_DIN_PP5,
+	TEGRA_PIN_DAP4_DOUT_PP6,
+	TEGRA_PIN_DAP4_SCLK_PP7,
+};
+
+static const unsigned ddc_pins[] = {
+	TEGRA_PIN_DDC_SCL,
+	TEGRA_PIN_DDC_SDA,
+};
+
+static const unsigned dta_pins[] = {
+	TEGRA_PIN_VI_D0_PT4,
+	TEGRA_PIN_VI_D1_PD5,
+};
+
+static const unsigned dtb_pins[] = {
+	TEGRA_PIN_VI_D10_PT2,
+	TEGRA_PIN_VI_D11_PT3,
+};
+
+static const unsigned dtc_pins[] = {
+	TEGRA_PIN_VI_HSYNC_PD7,
+	TEGRA_PIN_VI_VSYNC_PD6,
+};
+
+static const unsigned dtd_pins[] = {
+	TEGRA_PIN_VI_PCLK_PT0,
+	TEGRA_PIN_VI_D2_PL0,
+	TEGRA_PIN_VI_D3_PL1,
+	TEGRA_PIN_VI_D4_PL2,
+	TEGRA_PIN_VI_D5_PL3,
+	TEGRA_PIN_VI_D6_PL4,
+	TEGRA_PIN_VI_D7_PL5,
+	TEGRA_PIN_VI_D8_PL6,
+	TEGRA_PIN_VI_D9_PL7,
+};
+
+static const unsigned dte_pins[] = {
+	TEGRA_PIN_VI_GP0_PBB1,
+	TEGRA_PIN_VI_GP3_PBB4,
+	TEGRA_PIN_VI_GP4_PBB5,
+	TEGRA_PIN_VI_GP5_PD2,
+	TEGRA_PIN_VI_GP6_PA0,
+};
+
+static const unsigned dtf_pins[] = {
+	TEGRA_PIN_CAM_I2C_SCL_PBB2,
+	TEGRA_PIN_CAM_I2C_SDA_PBB3,
+};
+
+static const unsigned gma_pins[] = {
+	TEGRA_PIN_GMI_AD20_PAA0,
+	TEGRA_PIN_GMI_AD21_PAA1,
+	TEGRA_PIN_GMI_AD22_PAA2,
+	TEGRA_PIN_GMI_AD23_PAA3,
+};
+
+static const unsigned gmb_pins[] = {
+	TEGRA_PIN_GMI_WP_N_PC7,
+};
+
+static const unsigned gmc_pins[] = {
+	TEGRA_PIN_GMI_AD16_PJ7,
+	TEGRA_PIN_GMI_AD17_PB0,
+	TEGRA_PIN_GMI_AD18_PB1,
+	TEGRA_PIN_GMI_AD19_PK7,
+};
+
+static const unsigned gmd_pins[] = {
+	TEGRA_PIN_GMI_CS0_N_PJ0,
+	TEGRA_PIN_GMI_CS1_N_PJ2,
+};
+
+static const unsigned gme_pins[] = {
+	TEGRA_PIN_GMI_AD24_PAA4,
+	TEGRA_PIN_GMI_AD25_PAA5,
+	TEGRA_PIN_GMI_AD26_PAA6,
+	TEGRA_PIN_GMI_AD27_PAA7,
+};
+
+static const unsigned gpu_pins[] = {
+	TEGRA_PIN_PU0,
+	TEGRA_PIN_PU1,
+	TEGRA_PIN_PU2,
+	TEGRA_PIN_PU3,
+	TEGRA_PIN_PU4,
+	TEGRA_PIN_PU5,
+	TEGRA_PIN_PU6,
+};
+
+static const unsigned gpu7_pins[] = {
+	TEGRA_PIN_JTAG_RTCK_PU7,
+};
+
+static const unsigned gpv_pins[] = {
+	TEGRA_PIN_PV4,
+	TEGRA_PIN_PV5,
+	TEGRA_PIN_PV6,
+};
+
+static const unsigned hdint_pins[] = {
+	TEGRA_PIN_HDMI_INT_N_PN7,
+};
+
+static const unsigned i2cp_pins[] = {
+	TEGRA_PIN_PWR_I2C_SCL_PZ6,
+	TEGRA_PIN_PWR_I2C_SDA_PZ7,
+};
+
+static const unsigned irrx_pins[] = {
+	TEGRA_PIN_UART2_RTS_N_PJ6,
+};
+
+static const unsigned irtx_pins[] = {
+	TEGRA_PIN_UART2_CTS_N_PJ5,
+};
+
+static const unsigned kbca_pins[] = {
+	TEGRA_PIN_KB_ROW0_PR0,
+	TEGRA_PIN_KB_ROW1_PR1,
+	TEGRA_PIN_KB_ROW2_PR2,
+};
+
+static const unsigned kbcb_pins[] = {
+	TEGRA_PIN_KB_ROW7_PR7,
+	TEGRA_PIN_KB_ROW8_PS0,
+	TEGRA_PIN_KB_ROW9_PS1,
+	TEGRA_PIN_KB_ROW10_PS2,
+	TEGRA_PIN_KB_ROW11_PS3,
+	TEGRA_PIN_KB_ROW12_PS4,
+	TEGRA_PIN_KB_ROW13_PS5,
+	TEGRA_PIN_KB_ROW14_PS6,
+	TEGRA_PIN_KB_ROW15_PS7,
+};
+
+static const unsigned kbcc_pins[] = {
+	TEGRA_PIN_KB_COL0_PQ0,
+	TEGRA_PIN_KB_COL1_PQ1,
+};
+
+static const unsigned kbcd_pins[] = {
+	TEGRA_PIN_KB_ROW3_PR3,
+	TEGRA_PIN_KB_ROW4_PR4,
+	TEGRA_PIN_KB_ROW5_PR5,
+	TEGRA_PIN_KB_ROW6_PR6,
+};
+
+static const unsigned kbce_pins[] = {
+	TEGRA_PIN_KB_COL7_PQ7,
+};
+
+static const unsigned kbcf_pins[] = {
+	TEGRA_PIN_KB_COL2_PQ2,
+	TEGRA_PIN_KB_COL3_PQ3,
+	TEGRA_PIN_KB_COL4_PQ4,
+	TEGRA_PIN_KB_COL5_PQ5,
+	TEGRA_PIN_KB_COL6_PQ6,
+};
+
+static const unsigned lcsn_pins[] = {
+	TEGRA_PIN_LCD_CS0_N_PN4,
+};
+
+static const unsigned ld0_pins[] = {
+	TEGRA_PIN_LCD_D0_PE0,
+};
+
+static const unsigned ld1_pins[] = {
+	TEGRA_PIN_LCD_D1_PE1,
+};
+
+static const unsigned ld2_pins[] = {
+	TEGRA_PIN_LCD_D2_PE2,
+};
+
+static const unsigned ld3_pins[] = {
+	TEGRA_PIN_LCD_D3_PE3,
+};
+
+static const unsigned ld4_pins[] = {
+	TEGRA_PIN_LCD_D4_PE4,
+};
+
+static const unsigned ld5_pins[] = {
+	TEGRA_PIN_LCD_D5_PE5,
+};
+
+static const unsigned ld6_pins[] = {
+	TEGRA_PIN_LCD_D6_PE6,
+};
+
+static const unsigned ld7_pins[] = {
+	TEGRA_PIN_LCD_D7_PE7,
+};
+
+static const unsigned ld8_pins[] = {
+	TEGRA_PIN_LCD_D8_PF0,
+};
+
+static const unsigned ld9_pins[] = {
+	TEGRA_PIN_LCD_D9_PF1,
+};
+
+static const unsigned ld10_pins[] = {
+	TEGRA_PIN_LCD_D10_PF2,
+};
+
+static const unsigned ld11_pins[] = {
+	TEGRA_PIN_LCD_D11_PF3,
+};
+
+static const unsigned ld12_pins[] = {
+	TEGRA_PIN_LCD_D12_PF4,
+};
+
+static const unsigned ld13_pins[] = {
+	TEGRA_PIN_LCD_D13_PF5,
+};
+
+static const unsigned ld14_pins[] = {
+	TEGRA_PIN_LCD_D14_PF6,
+};
+
+static const unsigned ld15_pins[] = {
+	TEGRA_PIN_LCD_D15_PF7,
+};
+
+static const unsigned ld16_pins[] = {
+	TEGRA_PIN_LCD_D16_PM0,
+};
+
+static const unsigned ld17_pins[] = {
+	TEGRA_PIN_LCD_D17_PM1,
+};
+
+static const unsigned ldc_pins[] = {
+	TEGRA_PIN_LCD_DC0_PN6,
+};
+
+static const unsigned ldi_pins[] = {
+	TEGRA_PIN_LCD_D22_PM6,
+};
+
+static const unsigned lhp0_pins[] = {
+	TEGRA_PIN_LCD_D21_PM5,
+};
+
+static const unsigned lhp1_pins[] = {
+	TEGRA_PIN_LCD_D18_PM2,
+};
+
+static const unsigned lhp2_pins[] = {
+	TEGRA_PIN_LCD_D19_PM3,
+};
+
+static const unsigned lhs_pins[] = {
+	TEGRA_PIN_LCD_HSYNC_PJ3,
+};
+
+static const unsigned lm0_pins[] = {
+	TEGRA_PIN_LCD_CS1_N_PW0,
+};
+
+static const unsigned lm1_pins[] = {
+	TEGRA_PIN_LCD_M1_PW1,
+};
+
+static const unsigned lpp_pins[] = {
+	TEGRA_PIN_LCD_D23_PM7,
+};
+
+static const unsigned lpw0_pins[] = {
+	TEGRA_PIN_LCD_PWR0_PB2,
+};
+
+static const unsigned lpw1_pins[] = {
+	TEGRA_PIN_LCD_PWR1_PC1,
+};
+
+static const unsigned lpw2_pins[] = {
+	TEGRA_PIN_LCD_PWR2_PC6,
+};
+
+static const unsigned lsc0_pins[] = {
+	TEGRA_PIN_LCD_PCLK_PB3,
+};
+
+static const unsigned lsc1_pins[] = {
+	TEGRA_PIN_LCD_WR_N_PZ3,
+};
+
+static const unsigned lsck_pins[] = {
+	TEGRA_PIN_LCD_SCK_PZ4,
+};
+
+static const unsigned lsda_pins[] = {
+	TEGRA_PIN_LCD_SDOUT_PN5,
+};
+
+static const unsigned lsdi_pins[] = {
+	TEGRA_PIN_LCD_SDIN_PZ2,
+};
+
+static const unsigned lspi_pins[] = {
+	TEGRA_PIN_LCD_DE_PJ1,
+};
+
+static const unsigned lvp0_pins[] = {
+	TEGRA_PIN_LCD_DC1_PV7,
+};
+
+static const unsigned lvp1_pins[] = {
+	TEGRA_PIN_LCD_D20_PM4,
+};
+
+static const unsigned lvs_pins[] = {
+	TEGRA_PIN_LCD_VSYNC_PJ4,
+};
+
+static const unsigned ls_pins[] = {
+	TEGRA_PIN_LCD_PWR0_PB2,
+	TEGRA_PIN_LCD_PWR1_PC1,
+	TEGRA_PIN_LCD_PWR2_PC6,
+	TEGRA_PIN_LCD_SDIN_PZ2,
+	TEGRA_PIN_LCD_SDOUT_PN5,
+	TEGRA_PIN_LCD_WR_N_PZ3,
+	TEGRA_PIN_LCD_CS0_N_PN4,
+	TEGRA_PIN_LCD_DC0_PN6,
+	TEGRA_PIN_LCD_SCK_PZ4,
+};
+
+static const unsigned lc_pins[] = {
+	TEGRA_PIN_LCD_PCLK_PB3,
+	TEGRA_PIN_LCD_DE_PJ1,
+	TEGRA_PIN_LCD_HSYNC_PJ3,
+	TEGRA_PIN_LCD_VSYNC_PJ4,
+	TEGRA_PIN_LCD_CS1_N_PW0,
+	TEGRA_PIN_LCD_M1_PW1,
+	TEGRA_PIN_LCD_DC1_PV7,
+	TEGRA_PIN_HDMI_INT_N_PN7,
+};
+
+static const unsigned ld17_0_pins[] = {
+	TEGRA_PIN_LCD_D0_PE0,
+	TEGRA_PIN_LCD_D1_PE1,
+	TEGRA_PIN_LCD_D2_PE2,
+	TEGRA_PIN_LCD_D3_PE3,
+	TEGRA_PIN_LCD_D4_PE4,
+	TEGRA_PIN_LCD_D5_PE5,
+	TEGRA_PIN_LCD_D6_PE6,
+	TEGRA_PIN_LCD_D7_PE7,
+	TEGRA_PIN_LCD_D8_PF0,
+	TEGRA_PIN_LCD_D9_PF1,
+	TEGRA_PIN_LCD_D10_PF2,
+	TEGRA_PIN_LCD_D11_PF3,
+	TEGRA_PIN_LCD_D12_PF4,
+	TEGRA_PIN_LCD_D13_PF5,
+	TEGRA_PIN_LCD_D14_PF6,
+	TEGRA_PIN_LCD_D15_PF7,
+	TEGRA_PIN_LCD_D16_PM0,
+	TEGRA_PIN_LCD_D17_PM1,
+};
+
+static const unsigned ld19_18_pins[] = {
+	TEGRA_PIN_LCD_D18_PM2,
+	TEGRA_PIN_LCD_D19_PM3,
+};
+
+static const unsigned ld21_20_pins[] = {
+	TEGRA_PIN_LCD_D20_PM4,
+	TEGRA_PIN_LCD_D21_PM5,
+};
+
+static const unsigned ld23_22_pins[] = {
+	TEGRA_PIN_LCD_D22_PM6,
+	TEGRA_PIN_LCD_D23_PM7,
+};
+
+static const unsigned owc_pins[] = {
+	TEGRA_PIN_OWC,
+};
+
+static const unsigned pmc_pins[] = {
+	TEGRA_PIN_LED_BLINK_PBB0,
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+	TEGRA_PIN_CORE_PWR_REQ,
+	TEGRA_PIN_CPU_PWR_REQ,
+	TEGRA_PIN_PWR_INT_N,
+};
+
+static const unsigned pta_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SCL_PT5,
+	TEGRA_PIN_GEN2_I2C_SDA_PT6,
+};
+
+static const unsigned rm_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SCL_PC4,
+	TEGRA_PIN_GEN1_I2C_SDA_PC5,
+};
+
+static const unsigned sdb_pins[] = {
+	TEGRA_PIN_SDIO3_CMD_PA7,
+};
+
+static const unsigned sdc_pins[] = {
+	TEGRA_PIN_SDIO3_DAT0_PB7,
+	TEGRA_PIN_SDIO3_DAT1_PB6,
+	TEGRA_PIN_SDIO3_DAT2_PB5,
+	TEGRA_PIN_SDIO3_DAT3_PB4,
+};
+
+static const unsigned sdd_pins[] = {
+	TEGRA_PIN_SDIO3_CLK_PA6,
+};
+
+static const unsigned sdio1_pins[] = {
+	TEGRA_PIN_SDIO1_CLK_PZ0,
+	TEGRA_PIN_SDIO1_CMD_PZ1,
+	TEGRA_PIN_SDIO1_DAT0_PY7,
+	TEGRA_PIN_SDIO1_DAT1_PY6,
+	TEGRA_PIN_SDIO1_DAT2_PY5,
+	TEGRA_PIN_SDIO1_DAT3_PY4,
+};
+
+static const unsigned slxa_pins[] = {
+	TEGRA_PIN_SDIO3_DAT4_PD1,
+};
+
+static const unsigned slxc_pins[] = {
+	TEGRA_PIN_SDIO3_DAT6_PD3,
+};
+
+static const unsigned slxd_pins[] = {
+	TEGRA_PIN_SDIO3_DAT7_PD4,
+};
+
+static const unsigned slxk_pins[] = {
+	TEGRA_PIN_SDIO3_DAT5_PD0,
+};
+
+static const unsigned spdi_pins[] = {
+	TEGRA_PIN_SPDIF_IN_PK6,
+};
+
+static const unsigned spdo_pins[] = {
+	TEGRA_PIN_SPDIF_OUT_PK5,
+};
+
+static const unsigned spia_pins[] = {
+	TEGRA_PIN_SPI2_MOSI_PX0,
+};
+
+static const unsigned spib_pins[] = {
+	TEGRA_PIN_SPI2_MISO_PX1,
+};
+
+static const unsigned spic_pins[] = {
+	TEGRA_PIN_SPI2_CS0_N_PX3,
+	TEGRA_PIN_SPI2_SCK_PX2,
+};
+
+static const unsigned spid_pins[] = {
+	TEGRA_PIN_SPI1_MOSI_PX4,
+};
+
+static const unsigned spie_pins[] = {
+	TEGRA_PIN_SPI1_CS0_N_PX6,
+	TEGRA_PIN_SPI1_SCK_PX5,
+};
+
+static const unsigned spif_pins[] = {
+	TEGRA_PIN_SPI1_MISO_PX7,
+};
+
+static const unsigned spig_pins[] = {
+	TEGRA_PIN_SPI2_CS1_N_PW2,
+};
+
+static const unsigned spih_pins[] = {
+	TEGRA_PIN_SPI2_CS2_N_PW3,
+};
+
+static const unsigned uaa_pins[] = {
+	TEGRA_PIN_ULPI_DATA0_PO1,
+	TEGRA_PIN_ULPI_DATA1_PO2,
+	TEGRA_PIN_ULPI_DATA2_PO3,
+	TEGRA_PIN_ULPI_DATA3_PO4,
+};
+
+static const unsigned uab_pins[] = {
+	TEGRA_PIN_ULPI_DATA4_PO5,
+	TEGRA_PIN_ULPI_DATA5_PO6,
+	TEGRA_PIN_ULPI_DATA6_PO7,
+	TEGRA_PIN_ULPI_DATA7_PO0,
+};
+
+static const unsigned uac_pins[] = {
+	TEGRA_PIN_PV0,
+	TEGRA_PIN_PV1,
+	TEGRA_PIN_PV2,
+	TEGRA_PIN_PV3,
+};
+
+static const unsigned ck32_pins[] = {
+	TEGRA_PIN_CLK_32_K_IN,
+};
+
+static const unsigned uad_pins[] = {
+	TEGRA_PIN_UART2_RXD_PC3,
+	TEGRA_PIN_UART2_TXD_PC2,
+};
+
+static const unsigned uca_pins[] = {
+	TEGRA_PIN_UART3_RXD_PW7,
+	TEGRA_PIN_UART3_TXD_PW6,
+};
+
+static const unsigned ucb_pins[] = {
+	TEGRA_PIN_UART3_CTS_N_PA1,
+	TEGRA_PIN_UART3_RTS_N_PC0,
+};
+
+static const unsigned uda_pins[] = {
+	TEGRA_PIN_ULPI_CLK_PY0,
+	TEGRA_PIN_ULPI_DIR_PY1,
+	TEGRA_PIN_ULPI_NXT_PY2,
+	TEGRA_PIN_ULPI_STP_PY3,
+};
+
+static const unsigned ddrc_pins[] = {
+	TEGRA_PIN_DDR_COMP_PD,
+	TEGRA_PIN_DDR_COMP_PU,
+};
+
+static const unsigned pmca_pins[] = {
+	TEGRA_PIN_LED_BLINK_PBB0,
+};
+
+static const unsigned pmcb_pins[] = {
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+};
+
+static const unsigned pmcc_pins[] = {
+	TEGRA_PIN_CORE_PWR_REQ,
+};
+
+static const unsigned pmcd_pins[] = {
+	TEGRA_PIN_CPU_PWR_REQ,
+};
+
+static const unsigned pmce_pins[] = {
+	TEGRA_PIN_PWR_INT_N,
+};
+
+static const unsigned xm2c_pins[] = {
+	TEGRA_PIN_DDR_A0,
+	TEGRA_PIN_DDR_A1,
+	TEGRA_PIN_DDR_A2,
+	TEGRA_PIN_DDR_A3,
+	TEGRA_PIN_DDR_A4,
+	TEGRA_PIN_DDR_A5,
+	TEGRA_PIN_DDR_A6,
+	TEGRA_PIN_DDR_A7,
+	TEGRA_PIN_DDR_A8,
+	TEGRA_PIN_DDR_A9,
+	TEGRA_PIN_DDR_A10,
+	TEGRA_PIN_DDR_A11,
+	TEGRA_PIN_DDR_A12,
+	TEGRA_PIN_DDR_A13,
+	TEGRA_PIN_DDR_A14,
+	TEGRA_PIN_DDR_CAS_N,
+	TEGRA_PIN_DDR_BA0,
+	TEGRA_PIN_DDR_BA1,
+	TEGRA_PIN_DDR_BA2,
+	TEGRA_PIN_DDR_DQS0P,
+	TEGRA_PIN_DDR_DQS0N,
+	TEGRA_PIN_DDR_DQS1P,
+	TEGRA_PIN_DDR_DQS1N,
+	TEGRA_PIN_DDR_DQS2P,
+	TEGRA_PIN_DDR_DQS2N,
+	TEGRA_PIN_DDR_DQS3P,
+	TEGRA_PIN_DDR_DQS3N,
+	TEGRA_PIN_DDR_CS0_N,
+	TEGRA_PIN_DDR_CS1_N,
+	TEGRA_PIN_DDR_CKE0,
+	TEGRA_PIN_DDR_CKE1,
+	TEGRA_PIN_DDR_CLK,
+	TEGRA_PIN_DDR_CLK_N,
+	TEGRA_PIN_DDR_DM0,
+	TEGRA_PIN_DDR_DM1,
+	TEGRA_PIN_DDR_DM2,
+	TEGRA_PIN_DDR_DM3,
+	TEGRA_PIN_DDR_ODT,
+	TEGRA_PIN_DDR_RAS_N,
+	TEGRA_PIN_DDR_WE_N,
+	TEGRA_PIN_DDR_QUSE0,
+	TEGRA_PIN_DDR_QUSE1,
+	TEGRA_PIN_DDR_QUSE2,
+	TEGRA_PIN_DDR_QUSE3,
+};
+
+static const unsigned xm2d_pins[] = {
+	TEGRA_PIN_DDR_DQ0,
+	TEGRA_PIN_DDR_DQ1,
+	TEGRA_PIN_DDR_DQ2,
+	TEGRA_PIN_DDR_DQ3,
+	TEGRA_PIN_DDR_DQ4,
+	TEGRA_PIN_DDR_DQ5,
+	TEGRA_PIN_DDR_DQ6,
+	TEGRA_PIN_DDR_DQ7,
+	TEGRA_PIN_DDR_DQ8,
+	TEGRA_PIN_DDR_DQ9,
+	TEGRA_PIN_DDR_DQ10,
+	TEGRA_PIN_DDR_DQ11,
+	TEGRA_PIN_DDR_DQ12,
+	TEGRA_PIN_DDR_DQ13,
+	TEGRA_PIN_DDR_DQ14,
+	TEGRA_PIN_DDR_DQ15,
+	TEGRA_PIN_DDR_DQ16,
+	TEGRA_PIN_DDR_DQ17,
+	TEGRA_PIN_DDR_DQ18,
+	TEGRA_PIN_DDR_DQ19,
+	TEGRA_PIN_DDR_DQ20,
+	TEGRA_PIN_DDR_DQ21,
+	TEGRA_PIN_DDR_DQ22,
+	TEGRA_PIN_DDR_DQ23,
+	TEGRA_PIN_DDR_DQ24,
+	TEGRA_PIN_DDR_DQ25,
+	TEGRA_PIN_DDR_DQ26,
+	TEGRA_PIN_DDR_DQ27,
+	TEGRA_PIN_DDR_DQ28,
+	TEGRA_PIN_DDR_DQ29,
+	TEGRA_PIN_DDR_DQ30,
+	TEGRA_PIN_DDR_DQ31,
+};
+
+static const unsigned drive_ao1_pins[] = {
+	TEGRA_PIN_SYS_RESET,
+	TEGRA_PIN_PWR_I2C_SCL_PZ6,
+	TEGRA_PIN_PWR_I2C_SDA_PZ7,
+	TEGRA_PIN_KB_ROW0_PR0,
+	TEGRA_PIN_KB_ROW1_PR1,
+	TEGRA_PIN_KB_ROW2_PR2,
+	TEGRA_PIN_KB_ROW3_PR3,
+	TEGRA_PIN_KB_ROW4_PR4,
+	TEGRA_PIN_KB_ROW5_PR5,
+	TEGRA_PIN_KB_ROW6_PR6,
+	TEGRA_PIN_KB_ROW7_PR7,
+};
+
+static const unsigned drive_ao2_pins[] = {
+	TEGRA_PIN_KB_ROW8_PS0,
+	TEGRA_PIN_KB_ROW9_PS1,
+	TEGRA_PIN_KB_ROW10_PS2,
+	TEGRA_PIN_KB_ROW11_PS3,
+	TEGRA_PIN_KB_ROW12_PS4,
+	TEGRA_PIN_KB_ROW13_PS5,
+	TEGRA_PIN_KB_ROW14_PS6,
+	TEGRA_PIN_KB_ROW15_PS7,
+	TEGRA_PIN_KB_COL0_PQ0,
+	TEGRA_PIN_KB_COL1_PQ1,
+	TEGRA_PIN_KB_COL2_PQ2,
+	TEGRA_PIN_KB_COL3_PQ3,
+	TEGRA_PIN_KB_COL4_PQ4,
+	TEGRA_PIN_KB_COL5_PQ5,
+	TEGRA_PIN_KB_COL6_PQ6,
+	TEGRA_PIN_KB_COL7_PQ7,
+	TEGRA_PIN_LED_BLINK_PBB0,
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+	TEGRA_PIN_CORE_PWR_REQ,
+	TEGRA_PIN_CPU_PWR_REQ,
+	TEGRA_PIN_PWR_INT_N,
+	TEGRA_PIN_CLK_32_K_IN,
+};
+
+static const unsigned drive_at1_pins[] = {
+	TEGRA_PIN_GMI_IORDY_PI5,
+	TEGRA_PIN_GMI_AD8_PH0,
+	TEGRA_PIN_GMI_AD9_PH1,
+	TEGRA_PIN_GMI_AD10_PH2,
+	TEGRA_PIN_GMI_AD11_PH3,
+	TEGRA_PIN_GMI_AD12_PH4,
+	TEGRA_PIN_GMI_AD13_PH5,
+	TEGRA_PIN_GMI_AD14_PH6,
+	TEGRA_PIN_GMI_AD15_PH7,
+	TEGRA_PIN_GMI_CS7_N_PI6,
+	TEGRA_PIN_GMI_DPD_PT7,
+	TEGRA_PIN_GEN2_I2C_SCL_PT5,
+	TEGRA_PIN_GEN2_I2C_SDA_PT6,
+};
+
+static const unsigned drive_at2_pins[] = {
+	TEGRA_PIN_GMI_WAIT_PI7,
+	TEGRA_PIN_GMI_ADV_N_PK0,
+	TEGRA_PIN_GMI_CLK_PK1,
+	TEGRA_PIN_GMI_CS6_N_PI3,
+	TEGRA_PIN_GMI_CS5_N_PI2,
+	TEGRA_PIN_GMI_CS4_N_PK2,
+	TEGRA_PIN_GMI_CS3_N_PK4,
+	TEGRA_PIN_GMI_CS2_N_PK3,
+	TEGRA_PIN_GMI_AD0_PG0,
+	TEGRA_PIN_GMI_AD1_PG1,
+	TEGRA_PIN_GMI_AD2_PG2,
+	TEGRA_PIN_GMI_AD3_PG3,
+	TEGRA_PIN_GMI_AD4_PG4,
+	TEGRA_PIN_GMI_AD5_PG5,
+	TEGRA_PIN_GMI_AD6_PG6,
+	TEGRA_PIN_GMI_AD7_PG7,
+	TEGRA_PIN_GMI_HIOW_N_PI0,
+	TEGRA_PIN_GMI_HIOR_N_PI1,
+	TEGRA_PIN_GMI_RST_N_PI4,
+};
+
+static const unsigned drive_cdev1_pins[] = {
+	TEGRA_PIN_DAP_MCLK1_PW4,
+};
+
+static const unsigned drive_cdev2_pins[] = {
+	TEGRA_PIN_DAP_MCLK2_PW5,
+};
+
+static const unsigned drive_csus_pins[] = {
+	TEGRA_PIN_VI_MCLK_PT1,
+};
+
+static const unsigned drive_dap1_pins[] = {
+	TEGRA_PIN_DAP1_FS_PN0,
+	TEGRA_PIN_DAP1_DIN_PN1,
+	TEGRA_PIN_DAP1_DOUT_PN2,
+	TEGRA_PIN_DAP1_SCLK_PN3,
+	TEGRA_PIN_SPDIF_OUT_PK5,
+	TEGRA_PIN_SPDIF_IN_PK6,
+};
+
+static const unsigned drive_dap2_pins[] = {
+	TEGRA_PIN_DAP2_FS_PA2,
+	TEGRA_PIN_DAP2_SCLK_PA3,
+	TEGRA_PIN_DAP2_DIN_PA4,
+	TEGRA_PIN_DAP2_DOUT_PA5,
+};
+
+static const unsigned drive_dap3_pins[] = {
+	TEGRA_PIN_DAP3_FS_PP0,
+	TEGRA_PIN_DAP3_DIN_PP1,
+	TEGRA_PIN_DAP3_DOUT_PP2,
+	TEGRA_PIN_DAP3_SCLK_PP3,
+};
+
+static const unsigned drive_dap4_pins[] = {
+	TEGRA_PIN_DAP4_FS_PP4,
+	TEGRA_PIN_DAP4_DIN_PP5,
+	TEGRA_PIN_DAP4_DOUT_PP6,
+	TEGRA_PIN_DAP4_SCLK_PP7,
+};
+
+static const unsigned drive_dbg_pins[] = {
+	TEGRA_PIN_PU0,
+	TEGRA_PIN_PU1,
+	TEGRA_PIN_PU2,
+	TEGRA_PIN_PU3,
+	TEGRA_PIN_PU4,
+	TEGRA_PIN_PU5,
+	TEGRA_PIN_PU6,
+	TEGRA_PIN_JTAG_RTCK_PU7,
+	TEGRA_PIN_GEN1_I2C_SDA_PC5,
+	TEGRA_PIN_GEN1_I2C_SCL_PC4,
+	TEGRA_PIN_JTAG_TRST_N,
+	TEGRA_PIN_JTAG_TDO,
+	TEGRA_PIN_JTAG_TMS,
+	TEGRA_PIN_JTAG_TCK,
+	TEGRA_PIN_JTAG_TDI,
+	TEGRA_PIN_TEST_MODE_EN,
+};
+
+static const unsigned drive_lcd1_pins[] = {
+	TEGRA_PIN_LCD_PWR1_PC1,
+	TEGRA_PIN_LCD_PWR2_PC6,
+	TEGRA_PIN_LCD_SDIN_PZ2,
+	TEGRA_PIN_LCD_SDOUT_PN5,
+	TEGRA_PIN_LCD_WR_N_PZ3,
+	TEGRA_PIN_LCD_CS0_N_PN4,
+	TEGRA_PIN_LCD_DC0_PN6,
+	TEGRA_PIN_LCD_SCK_PZ4,
+};
+
+static const unsigned drive_lcd2_pins[] = {
+	TEGRA_PIN_LCD_PWR0_PB2,
+	TEGRA_PIN_LCD_PCLK_PB3,
+	TEGRA_PIN_LCD_DE_PJ1,
+	TEGRA_PIN_LCD_HSYNC_PJ3,
+	TEGRA_PIN_LCD_VSYNC_PJ4,
+	TEGRA_PIN_LCD_D0_PE0,
+	TEGRA_PIN_LCD_D1_PE1,
+	TEGRA_PIN_LCD_D2_PE2,
+	TEGRA_PIN_LCD_D3_PE3,
+	TEGRA_PIN_LCD_D4_PE4,
+	TEGRA_PIN_LCD_D5_PE5,
+	TEGRA_PIN_LCD_D6_PE6,
+	TEGRA_PIN_LCD_D7_PE7,
+	TEGRA_PIN_LCD_D8_PF0,
+	TEGRA_PIN_LCD_D9_PF1,
+	TEGRA_PIN_LCD_D10_PF2,
+	TEGRA_PIN_LCD_D11_PF3,
+	TEGRA_PIN_LCD_D12_PF4,
+	TEGRA_PIN_LCD_D13_PF5,
+	TEGRA_PIN_LCD_D14_PF6,
+	TEGRA_PIN_LCD_D15_PF7,
+	TEGRA_PIN_LCD_D16_PM0,
+	TEGRA_PIN_LCD_D17_PM1,
+	TEGRA_PIN_LCD_D18_PM2,
+	TEGRA_PIN_LCD_D19_PM3,
+	TEGRA_PIN_LCD_D20_PM4,
+	TEGRA_PIN_LCD_D21_PM5,
+	TEGRA_PIN_LCD_D22_PM6,
+	TEGRA_PIN_LCD_D23_PM7,
+	TEGRA_PIN_LCD_CS1_N_PW0,
+	TEGRA_PIN_LCD_M1_PW1,
+	TEGRA_PIN_LCD_DC1_PV7,
+	TEGRA_PIN_HDMI_INT_N_PN7,
+};
+
+static const unsigned drive_sdmmc2_pins[] = {
+	TEGRA_PIN_SDIO3_DAT4_PD1,
+	TEGRA_PIN_SDIO3_DAT5_PD0,
+	TEGRA_PIN_SDIO3_DAT6_PD3,
+	TEGRA_PIN_SDIO3_DAT7_PD4,
+};
+
+static const unsigned drive_sdmmc3_pins[] = {
+	TEGRA_PIN_SDIO3_CLK_PA6,
+	TEGRA_PIN_SDIO3_CMD_PA7,
+	TEGRA_PIN_SDIO3_DAT0_PB7,
+	TEGRA_PIN_SDIO3_DAT1_PB6,
+	TEGRA_PIN_SDIO3_DAT2_PB5,
+	TEGRA_PIN_SDIO3_DAT3_PB4,
+	TEGRA_PIN_PV4,
+	TEGRA_PIN_PV5,
+	TEGRA_PIN_PV6,
+};
+
+static const unsigned drive_spi_pins[] = {
+	TEGRA_PIN_SPI2_MOSI_PX0,
+	TEGRA_PIN_SPI2_MISO_PX1,
+	TEGRA_PIN_SPI2_SCK_PX2,
+	TEGRA_PIN_SPI2_CS0_N_PX3,
+	TEGRA_PIN_SPI1_MOSI_PX4,
+	TEGRA_PIN_SPI1_SCK_PX5,
+	TEGRA_PIN_SPI1_CS0_N_PX6,
+	TEGRA_PIN_SPI1_MISO_PX7,
+	TEGRA_PIN_SPI2_CS1_N_PW2,
+	TEGRA_PIN_SPI2_CS2_N_PW3,
+};
+
+static const unsigned drive_uaa_pins[] = {
+	TEGRA_PIN_ULPI_DATA0_PO1,
+	TEGRA_PIN_ULPI_DATA1_PO2,
+	TEGRA_PIN_ULPI_DATA2_PO3,
+	TEGRA_PIN_ULPI_DATA3_PO4,
+};
+
+static const unsigned drive_uab_pins[] = {
+	TEGRA_PIN_ULPI_DATA4_PO5,
+	TEGRA_PIN_ULPI_DATA5_PO6,
+	TEGRA_PIN_ULPI_DATA6_PO7,
+	TEGRA_PIN_ULPI_DATA7_PO0,
+	TEGRA_PIN_PV0,
+	TEGRA_PIN_PV1,
+	TEGRA_PIN_PV2,
+	TEGRA_PIN_PV3,
+};
+
+static const unsigned drive_uart2_pins[] = {
+	TEGRA_PIN_UART2_TXD_PC2,
+	TEGRA_PIN_UART2_RXD_PC3,
+	TEGRA_PIN_UART2_RTS_N_PJ6,
+	TEGRA_PIN_UART2_CTS_N_PJ5,
+};
+
+static const unsigned drive_uart3_pins[] = {
+	TEGRA_PIN_UART3_TXD_PW6,
+	TEGRA_PIN_UART3_RXD_PW7,
+	TEGRA_PIN_UART3_RTS_N_PC0,
+	TEGRA_PIN_UART3_CTS_N_PA1,
+};
+
+static const unsigned drive_vi1_pins[] = {
+	TEGRA_PIN_VI_D0_PT4,
+	TEGRA_PIN_VI_D1_PD5,
+	TEGRA_PIN_VI_D2_PL0,
+	TEGRA_PIN_VI_D3_PL1,
+	TEGRA_PIN_VI_D4_PL2,
+	TEGRA_PIN_VI_D5_PL3,
+	TEGRA_PIN_VI_D6_PL4,
+	TEGRA_PIN_VI_D7_PL5,
+	TEGRA_PIN_VI_D8_PL6,
+	TEGRA_PIN_VI_D9_PL7,
+	TEGRA_PIN_VI_D10_PT2,
+	TEGRA_PIN_VI_D11_PT3,
+	TEGRA_PIN_VI_PCLK_PT0,
+	TEGRA_PIN_VI_VSYNC_PD6,
+	TEGRA_PIN_VI_HSYNC_PD7,
+};
+
+static const unsigned drive_vi2_pins[] = {
+	TEGRA_PIN_VI_GP0_PBB1,
+	TEGRA_PIN_CAM_I2C_SCL_PBB2,
+	TEGRA_PIN_CAM_I2C_SDA_PBB3,
+	TEGRA_PIN_VI_GP3_PBB4,
+	TEGRA_PIN_VI_GP4_PBB5,
+	TEGRA_PIN_VI_GP5_PD2,
+	TEGRA_PIN_VI_GP6_PA0,
+};
+
+static const unsigned drive_xm2a_pins[] = {
+	TEGRA_PIN_DDR_A0,
+	TEGRA_PIN_DDR_A1,
+	TEGRA_PIN_DDR_A2,
+	TEGRA_PIN_DDR_A3,
+	TEGRA_PIN_DDR_A4,
+	TEGRA_PIN_DDR_A5,
+	TEGRA_PIN_DDR_A6,
+	TEGRA_PIN_DDR_A7,
+	TEGRA_PIN_DDR_A8,
+	TEGRA_PIN_DDR_A9,
+	TEGRA_PIN_DDR_A10,
+	TEGRA_PIN_DDR_A11,
+	TEGRA_PIN_DDR_A12,
+	TEGRA_PIN_DDR_A13,
+	TEGRA_PIN_DDR_A14,
+	TEGRA_PIN_DDR_BA0,
+	TEGRA_PIN_DDR_BA1,
+	TEGRA_PIN_DDR_BA2,
+	TEGRA_PIN_DDR_CS0_N,
+	TEGRA_PIN_DDR_CS1_N,
+	TEGRA_PIN_DDR_ODT,
+	TEGRA_PIN_DDR_RAS_N,
+	TEGRA_PIN_DDR_CAS_N,
+	TEGRA_PIN_DDR_WE_N,
+	TEGRA_PIN_DDR_CKE0,
+	TEGRA_PIN_DDR_CKE1,
+};
+
+static const unsigned drive_xm2c_pins[] = {
+	TEGRA_PIN_DDR_DQS0P,
+	TEGRA_PIN_DDR_DQS0N,
+	TEGRA_PIN_DDR_DQS1P,
+	TEGRA_PIN_DDR_DQS1N,
+	TEGRA_PIN_DDR_DQS2P,
+	TEGRA_PIN_DDR_DQS2N,
+	TEGRA_PIN_DDR_DQS3P,
+	TEGRA_PIN_DDR_DQS3N,
+	TEGRA_PIN_DDR_QUSE0,
+	TEGRA_PIN_DDR_QUSE1,
+	TEGRA_PIN_DDR_QUSE2,
+	TEGRA_PIN_DDR_QUSE3,
+};
+
+static const unsigned drive_xm2d_pins[] = {
+	TEGRA_PIN_DDR_DQ0,
+	TEGRA_PIN_DDR_DQ1,
+	TEGRA_PIN_DDR_DQ2,
+	TEGRA_PIN_DDR_DQ3,
+	TEGRA_PIN_DDR_DQ4,
+	TEGRA_PIN_DDR_DQ5,
+	TEGRA_PIN_DDR_DQ6,
+	TEGRA_PIN_DDR_DQ7,
+	TEGRA_PIN_DDR_DQ8,
+	TEGRA_PIN_DDR_DQ9,
+	TEGRA_PIN_DDR_DQ10,
+	TEGRA_PIN_DDR_DQ11,
+	TEGRA_PIN_DDR_DQ12,
+	TEGRA_PIN_DDR_DQ13,
+	TEGRA_PIN_DDR_DQ14,
+	TEGRA_PIN_DDR_DQ15,
+	TEGRA_PIN_DDR_DQ16,
+	TEGRA_PIN_DDR_DQ17,
+	TEGRA_PIN_DDR_DQ18,
+	TEGRA_PIN_DDR_DQ19,
+	TEGRA_PIN_DDR_DQ20,
+	TEGRA_PIN_DDR_DQ21,
+	TEGRA_PIN_DDR_DQ22,
+	TEGRA_PIN_DDR_DQ23,
+	TEGRA_PIN_DDR_DQ24,
+	TEGRA_PIN_DDR_DQ25,
+	TEGRA_PIN_DDR_DQ26,
+	TEGRA_PIN_DDR_DQ27,
+	TEGRA_PIN_DDR_DQ28,
+	TEGRA_PIN_DDR_DQ29,
+	TEGRA_PIN_DDR_DQ30,
+	TEGRA_PIN_DDR_DQ31,
+	TEGRA_PIN_DDR_DM0,
+	TEGRA_PIN_DDR_DM1,
+	TEGRA_PIN_DDR_DM2,
+	TEGRA_PIN_DDR_DM3,
+};
+
+static const unsigned drive_xm2clk_pins[] = {
+	TEGRA_PIN_DDR_CLK,
+	TEGRA_PIN_DDR_CLK_N,
+};
+
+static const unsigned drive_sdio1_pins[] = {
+	TEGRA_PIN_SDIO1_CLK_PZ0,
+	TEGRA_PIN_SDIO1_CMD_PZ1,
+	TEGRA_PIN_SDIO1_DAT0_PY7,
+	TEGRA_PIN_SDIO1_DAT1_PY6,
+	TEGRA_PIN_SDIO1_DAT2_PY5,
+	TEGRA_PIN_SDIO1_DAT3_PY4,
+};
+
+static const unsigned drive_crt_pins[] = {
+	TEGRA_PIN_CRT_HSYNC,
+	TEGRA_PIN_CRT_VSYNC,
+};
+
+static const unsigned drive_ddc_pins[] = {
+	TEGRA_PIN_DDC_SCL,
+	TEGRA_PIN_DDC_SDA,
+};
+
+static const unsigned drive_gma_pins[] = {
+	TEGRA_PIN_GMI_AD20_PAA0,
+	TEGRA_PIN_GMI_AD21_PAA1,
+	TEGRA_PIN_GMI_AD22_PAA2,
+	TEGRA_PIN_GMI_AD23_PAA3,
+};
+
+static const unsigned drive_gmb_pins[] = {
+	TEGRA_PIN_GMI_WP_N_PC7,
+};
+
+static const unsigned drive_gmc_pins[] = {
+	TEGRA_PIN_GMI_AD16_PJ7,
+	TEGRA_PIN_GMI_AD17_PB0,
+	TEGRA_PIN_GMI_AD18_PB1,
+	TEGRA_PIN_GMI_AD19_PK7,
+};
+
+static const unsigned drive_gmd_pins[] = {
+	TEGRA_PIN_GMI_CS0_N_PJ0,
+	TEGRA_PIN_GMI_CS1_N_PJ2,
+};
+
+static const unsigned drive_gme_pins[] = {
+	TEGRA_PIN_GMI_AD24_PAA4,
+	TEGRA_PIN_GMI_AD25_PAA5,
+	TEGRA_PIN_GMI_AD26_PAA6,
+	TEGRA_PIN_GMI_AD27_PAA7,
+};
+
+static const unsigned drive_owr_pins[] = {
+	TEGRA_PIN_OWC,
+};
+
+static const unsigned drive_uda_pins[] = {
+	TEGRA_PIN_ULPI_CLK_PY0,
+	TEGRA_PIN_ULPI_DIR_PY1,
+	TEGRA_PIN_ULPI_NXT_PY2,
+	TEGRA_PIN_ULPI_STP_PY3,
+};
+
+enum tegra_mux {
+	TEGRA_MUX_AHB_CLK,
+	TEGRA_MUX_APB_CLK,
+	TEGRA_MUX_AUDIO_SYNC,
+	TEGRA_MUX_CRT,
+	TEGRA_MUX_DAP1,
+	TEGRA_MUX_DAP2,
+	TEGRA_MUX_DAP3,
+	TEGRA_MUX_DAP4,
+	TEGRA_MUX_DAP5,
+	TEGRA_MUX_DISPLAYA,
+	TEGRA_MUX_DISPLAYB,
+	TEGRA_MUX_EMC_TEST0_DLL,
+	TEGRA_MUX_EMC_TEST1_DLL,
+	TEGRA_MUX_GMI,
+	TEGRA_MUX_GMI_INT,
+	TEGRA_MUX_HDMI,
+	TEGRA_MUX_I2CP,
+	TEGRA_MUX_I2C1,
+	TEGRA_MUX_I2C2,
+	TEGRA_MUX_I2C3,
+	TEGRA_MUX_IDE,
+	TEGRA_MUX_IRDA,
+	TEGRA_MUX_KBC,
+	TEGRA_MUX_MIO,
+	TEGRA_MUX_MIPI_HS,
+	TEGRA_MUX_NAND,
+	TEGRA_MUX_OSC,
+	TEGRA_MUX_OWR,
+	TEGRA_MUX_PCIE,
+	TEGRA_MUX_PLLA_OUT,
+	TEGRA_MUX_PLLC_OUT1,
+	TEGRA_MUX_PLLM_OUT1,
+	TEGRA_MUX_PLLP_OUT2,
+	TEGRA_MUX_PLLP_OUT3,
+	TEGRA_MUX_PLLP_OUT4,
+	TEGRA_MUX_PWM,
+	TEGRA_MUX_PWR_INTR,
+	TEGRA_MUX_PWR_ON,
+	TEGRA_MUX_RSVD1,
+	TEGRA_MUX_RSVD2,
+	TEGRA_MUX_RSVD3,
+	TEGRA_MUX_RSVD4,
+	TEGRA_MUX_RTCK,
+	TEGRA_MUX_SDIO1,
+	TEGRA_MUX_SDIO2,
+	TEGRA_MUX_SDIO3,
+	TEGRA_MUX_SDIO4,
+	TEGRA_MUX_SFLASH,
+	TEGRA_MUX_SPDIF,
+	TEGRA_MUX_SPI1,
+	TEGRA_MUX_SPI2,
+	TEGRA_MUX_SPI2_ALT,
+	TEGRA_MUX_SPI3,
+	TEGRA_MUX_SPI4,
+	TEGRA_MUX_TRACE,
+	TEGRA_MUX_TWC,
+	TEGRA_MUX_UARTA,
+	TEGRA_MUX_UARTB,
+	TEGRA_MUX_UARTC,
+	TEGRA_MUX_UARTD,
+	TEGRA_MUX_UARTE,
+	TEGRA_MUX_ULPI,
+	TEGRA_MUX_VI,
+	TEGRA_MUX_VI_SENSOR_CLK,
+	TEGRA_MUX_XIO,
+};
+
+static const char * const ahb_clk_groups[] = {
+	"cdev2",
+};
+
+static const char * const apb_clk_groups[] = {
+	"cdev2",
+};
+
+static const char * const audio_sync_groups[] = {
+	"cdev1",
+};
+
+static const char * const crt_groups[] = {
+	"crtp",
+	"lm1",
+};
+
+static const char * const dap1_groups[] = {
+	"dap1",
+};
+
+static const char * const dap2_groups[] = {
+	"dap2",
+};
+
+static const char * const dap3_groups[] = {
+	"dap3",
+};
+
+static const char * const dap4_groups[] = {
+	"dap4",
+};
+
+static const char * const dap5_groups[] = {
+	"gme",
+};
+
+static const char * const displaya_groups[] = {
+	"lcsn",
+	"ld0",
+	"ld1",
+	"ld10",
+	"ld11",
+	"ld12",
+	"ld13",
+	"ld14",
+	"ld15",
+	"ld16",
+	"ld17",
+	"ld2",
+	"ld3",
+	"ld4",
+	"ld5",
+	"ld6",
+	"ld7",
+	"ld8",
+	"ld9",
+	"ldc",
+	"ldi",
+	"lhp0",
+	"lhp1",
+	"lhp2",
+	"lhs",
+	"lm0",
+	"lm1",
+	"lpp",
+	"lpw0",
+	"lpw1",
+	"lpw2",
+	"lsc0",
+	"lsc1",
+	"lsck",
+	"lsda",
+	"lsdi",
+	"lspi",
+	"lvp0",
+	"lvp1",
+	"lvs",
+};
+
+static const char * const displayb_groups[] = {
+	"lcsn",
+	"ld0",
+	"ld1",
+	"ld10",
+	"ld11",
+	"ld12",
+	"ld13",
+	"ld14",
+	"ld15",
+	"ld16",
+	"ld17",
+	"ld2",
+	"ld3",
+	"ld4",
+	"ld5",
+	"ld6",
+	"ld7",
+	"ld8",
+	"ld9",
+	"ldc",
+	"ldi",
+	"lhp0",
+	"lhp1",
+	"lhp2",
+	"lhs",
+	"lm0",
+	"lm1",
+	"lpp",
+	"lpw0",
+	"lpw1",
+	"lpw2",
+	"lsc0",
+	"lsc1",
+	"lsck",
+	"lsda",
+	"lsdi",
+	"lspi",
+	"lvp0",
+	"lvp1",
+	"lvs",
+};
+
+static const char * const emc_test0_dll_groups[] = {
+	"kbca",
+};
+
+static const char * const emc_test1_dll_groups[] = {
+	"kbcc",
+};
+
+static const char * const gmi_groups[] = {
+	"ata",
+	"atb",
+	"atc",
+	"atd",
+	"ate",
+	"dap1",
+	"dap2",
+	"dap4",
+	"gma",
+	"gmb",
+	"gmc",
+	"gmd",
+	"gme",
+	"gpu",
+	"irrx",
+	"irtx",
+	"pta",
+	"spia",
+	"spib",
+	"spic",
+	"spid",
+	"spie",
+	"uca",
+	"ucb",
+};
+
+static const char * const gmi_int_groups[] = {
+	"gmb",
+};
+
+static const char * const hdmi_groups[] = {
+	"hdint",
+	"lpw0",
+	"lpw2",
+	"lsc1",
+	"lsck",
+	"lsda",
+	"lspi",
+	"pta",
+};
+
+static const char * const i2cp_groups[] = {
+	"i2cp",
+};
+
+static const char * const i2c1_groups[] = {
+	"rm",
+	"spdi",
+	"spdo",
+	"spig",
+	"spih",
+};
+
+static const char * const i2c2_groups[] = {
+	"ddc",
+	"pta",
+};
+
+static const char * const i2c3_groups[] = {
+	"dtf",
+};
+
+static const char * const ide_groups[] = {
+	"ata",
+	"atb",
+	"atc",
+	"atd",
+	"ate",
+	"gmb",
+};
+
+static const char * const irda_groups[] = {
+	"uad",
+};
+
+static const char * const kbc_groups[] = {
+	"kbca",
+	"kbcb",
+	"kbcc",
+	"kbcd",
+	"kbce",
+	"kbcf",
+};
+
+static const char * const mio_groups[] = {
+	"kbcb",
+	"kbcd",
+	"kbcf",
+};
+
+static const char * const mipi_hs_groups[] = {
+	"uaa",
+	"uab",
+};
+
+static const char * const nand_groups[] = {
+	"ata",
+	"atb",
+	"atc",
+	"atd",
+	"ate",
+	"gmb",
+	"gmd",
+	"kbca",
+	"kbcb",
+	"kbcc",
+	"kbcd",
+	"kbce",
+	"kbcf",
+};
+
+static const char * const osc_groups[] = {
+	"cdev1",
+	"cdev2",
+};
+
+static const char * const owr_groups[] = {
+	"kbce",
+	"owc",
+	"uac",
+};
+
+static const char * const pcie_groups[] = {
+	"gpv",
+	"slxa",
+	"slxk",
+};
+
+static const char * const plla_out_groups[] = {
+	"cdev1",
+};
+
+static const char * const pllc_out1_groups[] = {
+	"csus",
+};
+
+static const char * const pllm_out1_groups[] = {
+	"cdev1",
+};
+
+static const char * const pllp_out2_groups[] = {
+	"csus",
+};
+
+static const char * const pllp_out3_groups[] = {
+	"csus",
+};
+
+static const char * const pllp_out4_groups[] = {
+	"cdev2",
+};
+
+static const char * const pwm_groups[] = {
+	"gpu",
+	"sdb",
+	"sdc",
+	"sdd",
+	"ucb",
+};
+
+static const char * const pwr_intr_groups[] = {
+	"pmc",
+};
+
+static const char * const pwr_on_groups[] = {
+	"pmc",
+};
+
+static const char * const rsvd1_groups[] = {
+	"dta",
+	"dtb",
+	"dtc",
+	"dtd",
+	"dte",
+	"gmd",
+	"gme",
+};
+
+static const char * const rsvd2_groups[] = {
+	"crtp",
+	"dap1",
+	"dap3",
+	"dap4",
+	"ddc",
+	"dtb",
+	"dtc",
+	"dte",
+	"dtf",
+	"gpu7",
+	"gpv",
+	"hdint",
+	"i2cp",
+	"owc",
+	"rm",
+	"sdio1",
+	"spdi",
+	"spdo",
+	"uac",
+	"uca",
+	"uda",
+};
+
+static const char * const rsvd3_groups[] = {
+	"crtp",
+	"dap2",
+	"dap3",
+	"ddc",
+	"gpu7",
+	"gpv",
+	"hdint",
+	"i2cp",
+	"ld17",
+	"ldc",
+	"ldi",
+	"lhp0",
+	"lhp1",
+	"lhp2",
+	"lm1",
+	"lpp",
+	"lpw1",
+	"lvp0",
+	"lvp1",
+	"owc",
+	"pmc",
+	"rm",
+	"uac",
+};
+
+static const char * const rsvd4_groups[] = {
+	"ata",
+	"ate",
+	"crtp",
+	"dap3",
+	"dap4",
+	"ddc",
+	"dta",
+	"dtc",
+	"dtd",
+	"dtf",
+	"gpu",
+	"gpu7",
+	"gpv",
+	"hdint",
+	"i2cp",
+	"kbce",
+	"lcsn",
+	"ld0",
+	"ld1",
+	"ld2",
+	"ld3",
+	"ld4",
+	"ld5",
+	"ld6",
+	"ld7",
+	"ld8",
+	"ld9",
+	"ld10",
+	"ld11",
+	"ld12",
+	"ld13",
+	"ld14",
+	"ld15",
+	"ld16",
+	"ld17",
+	"ldc",
+	"ldi",
+	"lhp0",
+	"lhp1",
+	"lhp2",
+	"lhs",
+	"lm0",
+	"lpp",
+	"lpw1",
+	"lsc0",
+	"lsdi",
+	"lvp0",
+	"lvp1",
+	"lvs",
+	"owc",
+	"pmc",
+	"pta",
+	"rm",
+	"spif",
+	"uac",
+	"uca",
+	"ucb",
+};
+
+static const char * const rtck_groups[] = {
+	"gpu7",
+};
+
+static const char * const sdio1_groups[] = {
+	"sdio1",
+};
+
+static const char * const sdio2_groups[] = {
+	"dap1",
+	"dta",
+	"dtd",
+	"kbca",
+	"kbcb",
+	"kbcd",
+	"spdi",
+	"spdo",
+};
+
+static const char * const sdio3_groups[] = {
+	"sdb",
+	"sdc",
+	"sdd",
+	"slxa",
+	"slxc",
+	"slxd",
+	"slxk",
+};
+
+static const char * const sdio4_groups[] = {
+	"atb",
+	"atc",
+	"atd",
+	"gma",
+	"gme",
+};
+
+static const char * const sflash_groups[] = {
+	"gmc",
+	"gmd",
+};
+
+static const char * const spdif_groups[] = {
+	"slxc",
+	"slxd",
+	"spdi",
+	"spdo",
+	"uad",
+};
+
+static const char * const spi1_groups[] = {
+	"dtb",
+	"dte",
+	"spia",
+	"spib",
+	"spic",
+	"spid",
+	"spie",
+	"spif",
+	"uda",
+};
+
+static const char * const spi2_groups[] = {
+	"sdb",
+	"slxa",
+	"slxc",
+	"slxd",
+	"slxk",
+	"spia",
+	"spib",
+	"spic",
+	"spid",
+	"spie",
+	"spif",
+	"spig",
+	"spih",
+	"uab",
+};
+
+static const char * const spi2_alt_groups[] = {
+	"spid",
+	"spie",
+	"spig",
+	"spih",
+};
+
+static const char * const spi3_groups[] = {
+	"gma",
+	"lcsn",
+	"lm0",
+	"lpw0",
+	"lpw2",
+	"lsc1",
+	"lsck",
+	"lsda",
+	"lsdi",
+	"sdc",
+	"sdd",
+	"spia",
+	"spib",
+	"spic",
+	"spif",
+	"spig",
+	"spih",
+	"uaa",
+};
+
+static const char * const spi4_groups[] = {
+	"gmc",
+	"irrx",
+	"irtx",
+	"slxa",
+	"slxc",
+	"slxd",
+	"slxk",
+	"uad",
+};
+
+static const char * const trace_groups[] = {
+	"kbcc",
+	"kbcf",
+};
+
+static const char * const twc_groups[] = {
+	"dap2",
+	"sdc",
+};
+
+static const char * const uarta_groups[] = {
+	"gpu",
+	"irrx",
+	"irtx",
+	"sdb",
+	"sdd",
+	"sdio1",
+	"uaa",
+	"uab",
+	"uad",
+};
+
+static const char * const uartb_groups[] = {
+	"irrx",
+	"irtx",
+};
+
+static const char * const uartc_groups[] = {
+	"uca",
+	"ucb",
+};
+
+static const char * const uartd_groups[] = {
+	"gmc",
+	"uda",
+};
+
+static const char * const uarte_groups[] = {
+	"gma",
+	"sdio1",
+};
+
+static const char * const ulpi_groups[] = {
+	"uaa",
+	"uab",
+	"uda",
+};
+
+static const char * const vi_groups[] = {
+	"dta",
+	"dtb",
+	"dtc",
+	"dtd",
+	"dte",
+	"dtf",
+};
+
+static const char * const vi_sensor_clk_groups[] = {
+	"csus",
+};
+
+static const char * const xio_groups[] = {
+	"ld0",
+	"ld1",
+	"ld10",
+	"ld11",
+	"ld12",
+	"ld13",
+	"ld14",
+	"ld15",
+	"ld16",
+	"ld2",
+	"ld3",
+	"ld4",
+	"ld5",
+	"ld6",
+	"ld7",
+	"ld8",
+	"ld9",
+	"lhs",
+	"lsc0",
+	"lspi",
+	"lvs",
+};
+
+#define FUNCTION(fname)					\
+	{						\
+		.name = #fname,				\
+		.groups = fname##_groups,		\
+		.ngroups = ARRAY_SIZE(fname##_groups),	\
+	}
+
+static const struct tegra_function tegra20_functions[] = {
+	FUNCTION(ahb_clk),
+	FUNCTION(apb_clk),
+	FUNCTION(audio_sync),
+	FUNCTION(crt),
+	FUNCTION(dap1),
+	FUNCTION(dap2),
+	FUNCTION(dap3),
+	FUNCTION(dap4),
+	FUNCTION(dap5),
+	FUNCTION(displaya),
+	FUNCTION(displayb),
+	FUNCTION(emc_test0_dll),
+	FUNCTION(emc_test1_dll),
+	FUNCTION(gmi),
+	FUNCTION(gmi_int),
+	FUNCTION(hdmi),
+	FUNCTION(i2cp),
+	FUNCTION(i2c1),
+	FUNCTION(i2c2),
+	FUNCTION(i2c3),
+	FUNCTION(ide),
+	FUNCTION(irda),
+	FUNCTION(kbc),
+	FUNCTION(mio),
+	FUNCTION(mipi_hs),
+	FUNCTION(nand),
+	FUNCTION(osc),
+	FUNCTION(owr),
+	FUNCTION(pcie),
+	FUNCTION(plla_out),
+	FUNCTION(pllc_out1),
+	FUNCTION(pllm_out1),
+	FUNCTION(pllp_out2),
+	FUNCTION(pllp_out3),
+	FUNCTION(pllp_out4),
+	FUNCTION(pwm),
+	FUNCTION(pwr_intr),
+	FUNCTION(pwr_on),
+	FUNCTION(rsvd1),
+	FUNCTION(rsvd2),
+	FUNCTION(rsvd3),
+	FUNCTION(rsvd4),
+	FUNCTION(rtck),
+	FUNCTION(sdio1),
+	FUNCTION(sdio2),
+	FUNCTION(sdio3),
+	FUNCTION(sdio4),
+	FUNCTION(sflash),
+	FUNCTION(spdif),
+	FUNCTION(spi1),
+	FUNCTION(spi2),
+	FUNCTION(spi2_alt),
+	FUNCTION(spi3),
+	FUNCTION(spi4),
+	FUNCTION(trace),
+	FUNCTION(twc),
+	FUNCTION(uarta),
+	FUNCTION(uartb),
+	FUNCTION(uartc),
+	FUNCTION(uartd),
+	FUNCTION(uarte),
+	FUNCTION(ulpi),
+	FUNCTION(vi),
+	FUNCTION(vi_sensor_clk),
+	FUNCTION(xio),
+};
+
+#define TRISTATE_REG_A		0x14
+#define PIN_MUX_CTL_REG_A	0x80
+#define PULLUPDOWN_REG_A	0xa0
+#define PINGROUP_REG_A		0x868
+
+/* Pin group with mux control, and typically tri-state and pull-up/down too */
+#define MUX_PG(pg_name, f0, f1, f2, f3, f_safe,			\
+	       tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b)	\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.funcs = {					\
+			TEGRA_MUX_ ## f0,			\
+			TEGRA_MUX_ ## f1,			\
+			TEGRA_MUX_ ## f2,			\
+			TEGRA_MUX_ ## f3,			\
+		},						\
+		.func_safe = TEGRA_MUX_ ## f_safe,		\
+		.mux_reg = ((mux_r) - PIN_MUX_CTL_REG_A),	\
+		.mux_bank = 1,					\
+		.mux_bit = mux_b,				\
+		.pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A),	\
+		.pupd_bank = 2,					\
+		.pupd_bit = pupd_b,				\
+		.tri_reg = ((tri_r) - TRISTATE_REG_A),		\
+		.tri_bank = 0,					\
+		.tri_bit = tri_b,				\
+		.einput_reg = -1,				\
+		.odrain_reg = -1,				\
+		.lock_reg = -1,					\
+		.ioreset_reg = -1,				\
+		.drv_reg = -1,					\
+	}
+
+/* Pin groups with only pull up and pull down control */
+#define PULL_PG(pg_name, pupd_r, pupd_b)			\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.mux_reg = -1,					\
+		.pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A),	\
+		.pupd_bank = 2,					\
+		.pupd_bit = pupd_b,				\
+		.tri_reg = -1,					\
+		.einput_reg = -1,				\
+		.odrain_reg = -1,				\
+		.lock_reg = -1,					\
+		.ioreset_reg = -1,				\
+		.drv_reg = -1,					\
+	}
+
+/* Pin groups for drive strength registers (configurable version) */
+#define DRV_PG_EXT(pg_name, r, hsm_b, schmitt_b, lpmd_b,	\
+		   drvdn_b, drvup_b,				\
+		   slwr_b, slwr_w, slwf_b, slwf_w)		\
+	{							\
+		.name = "drive_" #pg_name,			\
+		.pins = drive_##pg_name##_pins,			\
+		.npins = ARRAY_SIZE(drive_##pg_name##_pins),	\
+		.mux_reg = -1,					\
+		.pupd_reg = -1,					\
+		.tri_reg = -1,					\
+		.einput_reg = -1,				\
+		.odrain_reg = -1,				\
+		.lock_reg = -1,					\
+		.ioreset_reg = -1,				\
+		.drv_reg = ((r) - PINGROUP_REG_A),		\
+		.drv_bank = 3,					\
+		.hsm_bit = hsm_b,				\
+		.schmitt_bit = schmitt_b,			\
+		.lpmd_bit = lpmd_b,				\
+		.drvdn_bit = drvdn_b,				\
+		.drvdn_width = 5,				\
+		.drvup_bit = drvup_b,				\
+		.drvup_width = 5,				\
+		.slwr_bit = slwr_b,				\
+		.slwr_width = slwr_w,				\
+		.slwf_bit = slwf_b,				\
+		.slwf_width = slwf_w,				\
+	}
+
+/* Pin groups for drive strength registers (simple version) */
+#define DRV_PG(pg_name, r) \
+	DRV_PG_EXT(pg_name, r, 2,  3,  4, 12, 20, 28, 2, 30, 2)
+
+static const struct tegra_pingroup tegra20_groups[] = {
+	/*     name,   f0,        f1,        f2,        f3,            f_safe,    tri r/b,  mux r/b,  pupd r/b */
+	MUX_PG(ata,    IDE,       NAND,      GMI,       RSVD4,         IDE,       0x14, 0,  0x80, 24, 0xa0, 0),
+	MUX_PG(atb,    IDE,       NAND,      GMI,       SDIO4,         IDE,       0x14, 1,  0x80, 16, 0xa0, 2),
+	MUX_PG(atc,    IDE,       NAND,      GMI,       SDIO4,         IDE,       0x14, 2,  0x80, 22, 0xa0, 4),
+	MUX_PG(atd,    IDE,       NAND,      GMI,       SDIO4,         IDE,       0x14, 3,  0x80, 20, 0xa0, 6),
+	MUX_PG(ate,    IDE,       NAND,      GMI,       RSVD4,         IDE,       0x18, 25, 0x80, 12, 0xa0, 8),
+	MUX_PG(cdev1,  OSC,       PLLA_OUT,  PLLM_OUT1, AUDIO_SYNC,    OSC,       0x14, 4,  0x88, 2,  0xa8, 0),
+	MUX_PG(cdev2,  OSC,       AHB_CLK,   APB_CLK,   PLLP_OUT4,     OSC,       0x14, 5,  0x88, 4,  0xa8, 2),
+	MUX_PG(crtp,   CRT,       RSVD2,     RSVD3,     RSVD4,         RSVD2,     0x20, 14, 0x98, 20, 0xa4, 24),
+	MUX_PG(csus,   PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6,  0x88, 6,  0xac, 24),
+	MUX_PG(dap1,   DAP1,      RSVD2,     GMI,       SDIO2,         DAP1,      0x14, 7,  0x88, 20, 0xa0, 10),
+	MUX_PG(dap2,   DAP2,      TWC,       RSVD3,     GMI,           DAP2,      0x14, 8,  0x88, 22, 0xa0, 12),
+	MUX_PG(dap3,   DAP3,      RSVD2,     RSVD3,     RSVD4,         DAP3,      0x14, 9,  0x88, 24, 0xa0, 14),
+	MUX_PG(dap4,   DAP4,      RSVD2,     GMI,       RSVD4,         DAP4,      0x14, 10, 0x88, 26, 0xa0, 16),
+	MUX_PG(ddc,    I2C2,      RSVD2,     RSVD3,     RSVD4,         RSVD4,     0x18, 31, 0x88, 0,  0xb0, 28),
+	MUX_PG(dta,    RSVD1,     SDIO2,     VI,        RSVD4,         RSVD4,     0x14, 11, 0x84, 20, 0xa0, 18),
+	MUX_PG(dtb,    RSVD1,     RSVD2,     VI,        SPI1,          RSVD1,     0x14, 12, 0x84, 22, 0xa0, 20),
+	MUX_PG(dtc,    RSVD1,     RSVD2,     VI,        RSVD4,         RSVD1,     0x14, 13, 0x84, 26, 0xa0, 22),
+	MUX_PG(dtd,    RSVD1,     SDIO2,     VI,        RSVD4,         RSVD1,     0x14, 14, 0x84, 28, 0xa0, 24),
+	MUX_PG(dte,    RSVD1,     RSVD2,     VI,        SPI1,          RSVD1,     0x14, 15, 0x84, 30, 0xa0, 26),
+	MUX_PG(dtf,    I2C3,      RSVD2,     VI,        RSVD4,         RSVD4,     0x20, 12, 0x98, 30, 0xa0, 28),
+	MUX_PG(gma,    UARTE,     SPI3,      GMI,       SDIO4,         SPI3,      0x14, 28, 0x84, 0,  0xb0, 20),
+	MUX_PG(gmb,    IDE,       NAND,      GMI,       GMI_INT,       GMI,       0x18, 29, 0x88, 28, 0xb0, 22),
+	MUX_PG(gmc,    UARTD,     SPI4,      GMI,       SFLASH,        SPI4,      0x14, 29, 0x84, 2,  0xb0, 24),
+	MUX_PG(gmd,    RSVD1,     NAND,      GMI,       SFLASH,        GMI,       0x18, 30, 0x88, 30, 0xb0, 26),
+	MUX_PG(gme,    RSVD1,     DAP5,      GMI,       SDIO4,         GMI,       0x18, 0,  0x8c, 0,  0xa8, 24),
+	MUX_PG(gpu,    PWM,       UARTA,     GMI,       RSVD4,         RSVD4,     0x14, 16, 0x8c, 4,  0xa4, 20),
+	MUX_PG(gpu7,   RTCK,      RSVD2,     RSVD3,     RSVD4,         RTCK,      0x20, 11, 0x98, 28, 0xa4, 6),
+	MUX_PG(gpv,    PCIE,      RSVD2,     RSVD3,     RSVD4,         PCIE,      0x14, 17, 0x8c, 2,  0xa0, 30),
+	MUX_PG(hdint,  HDMI,      RSVD2,     RSVD3,     RSVD4,         HDMI,      0x1c, 23, 0x84, 4,  -1,   -1),
+	MUX_PG(i2cp,   I2CP,      RSVD2,     RSVD3,     RSVD4,         RSVD4,     0x14, 18, 0x88, 8,  0xa4, 2),
+	MUX_PG(irrx,   UARTA,     UARTB,     GMI,       SPI4,          UARTB,     0x14, 20, 0x88, 18, 0xa8, 22),
+	MUX_PG(irtx,   UARTA,     UARTB,     GMI,       SPI4,          UARTB,     0x14, 19, 0x88, 16, 0xa8, 20),
+	MUX_PG(kbca,   KBC,       NAND,      SDIO2,     EMC_TEST0_DLL, KBC,       0x14, 22, 0x88, 10, 0xa4, 8),
+	MUX_PG(kbcb,   KBC,       NAND,      SDIO2,     MIO,           KBC,       0x14, 21, 0x88, 12, 0xa4, 10),
+	MUX_PG(kbcc,   KBC,       NAND,      TRACE,     EMC_TEST1_DLL, KBC,       0x18, 26, 0x88, 14, 0xa4, 12),
+	MUX_PG(kbcd,   KBC,       NAND,      SDIO2,     MIO,           KBC,       0x20, 10, 0x98, 26, 0xa4, 14),
+	MUX_PG(kbce,   KBC,       NAND,      OWR,       RSVD4,         KBC,       0x14, 26, 0x80, 28, 0xb0, 2),
+	MUX_PG(kbcf,   KBC,       NAND,      TRACE,     MIO,           KBC,       0x14, 27, 0x80, 26, 0xb0, 0),
+	MUX_PG(lcsn,   DISPLAYA,  DISPLAYB,  SPI3,      RSVD4,         RSVD4,     0x1c, 31, 0x90, 12, -1,   -1),
+	MUX_PG(ld0,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 0,  0x94, 0,  -1,   -1),
+	MUX_PG(ld1,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 1,  0x94, 2,  -1,   -1),
+	MUX_PG(ld2,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 2,  0x94, 4,  -1,   -1),
+	MUX_PG(ld3,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 3,  0x94, 6,  -1,   -1),
+	MUX_PG(ld4,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 4,  0x94, 8,  -1,   -1),
+	MUX_PG(ld5,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 5,  0x94, 10, -1,   -1),
+	MUX_PG(ld6,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 6,  0x94, 12, -1,   -1),
+	MUX_PG(ld7,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 7,  0x94, 14, -1,   -1),
+	MUX_PG(ld8,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 8,  0x94, 16, -1,   -1),
+	MUX_PG(ld9,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 9,  0x94, 18, -1,   -1),
+	MUX_PG(ld10,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 10, 0x94, 20, -1,   -1),
+	MUX_PG(ld11,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 11, 0x94, 22, -1,   -1),
+	MUX_PG(ld12,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 12, 0x94, 24, -1,   -1),
+	MUX_PG(ld13,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 13, 0x94, 26, -1,   -1),
+	MUX_PG(ld14,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 14, 0x94, 28, -1,   -1),
+	MUX_PG(ld15,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 15, 0x94, 30, -1,   -1),
+	MUX_PG(ld16,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 16, 0x98, 0,  -1,   -1),
+	MUX_PG(ld17,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 17, 0x98, 2,  -1,   -1),
+	MUX_PG(ldc,    DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 30, 0x90, 14, -1,   -1),
+	MUX_PG(ldi,    DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x20, 6,  0x98, 16, -1,   -1),
+	MUX_PG(lhp0,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 18, 0x98, 10, -1,   -1),
+	MUX_PG(lhp1,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 19, 0x98, 4,  -1,   -1),
+	MUX_PG(lhp2,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 20, 0x98, 6,  -1,   -1),
+	MUX_PG(lhs,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x20, 7,  0x90, 22, -1,   -1),
+	MUX_PG(lm0,    DISPLAYA,  DISPLAYB,  SPI3,      RSVD4,         RSVD4,     0x1c, 24, 0x90, 26, -1,   -1),
+	MUX_PG(lm1,    DISPLAYA,  DISPLAYB,  RSVD3,     CRT,           RSVD3,     0x1c, 25, 0x90, 28, -1,   -1),
+	MUX_PG(lpp,    DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x20, 8,  0x98, 14, -1,   -1),
+	MUX_PG(lpw0,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x20, 3,  0x90, 0,  -1,   -1),
+	MUX_PG(lpw1,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x20, 4,  0x90, 2,  -1,   -1),
+	MUX_PG(lpw2,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x20, 5,  0x90, 4,  -1,   -1),
+	MUX_PG(lsc0,   DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 27, 0x90, 18, -1,   -1),
+	MUX_PG(lsc1,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x1c, 28, 0x90, 20, -1,   -1),
+	MUX_PG(lsck,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x1c, 29, 0x90, 16, -1,   -1),
+	MUX_PG(lsda,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x20, 1,  0x90, 8,  -1,   -1),
+	MUX_PG(lsdi,   DISPLAYA,  DISPLAYB,  SPI3,      RSVD4,         DISPLAYA,  0x20, 2,  0x90, 6,  -1,   -1),
+	MUX_PG(lspi,   DISPLAYA,  DISPLAYB,  XIO,       HDMI,          DISPLAYA,  0x20, 0,  0x90, 10, -1,   -1),
+	MUX_PG(lvp0,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 21, 0x90, 30, -1,   -1),
+	MUX_PG(lvp1,   DISPLAYA,  DISPLAYB,  RSVD3,     RSVD4,         RSVD4,     0x1c, 22, 0x98, 8,  -1,   -1),
+	MUX_PG(lvs,    DISPLAYA,  DISPLAYB,  XIO,       RSVD4,         RSVD4,     0x1c, 26, 0x90, 24, -1,   -1),
+	MUX_PG(owc,    OWR,       RSVD2,     RSVD3,     RSVD4,         OWR,       0x14, 31, 0x84, 8,  0xb0, 30),
+	MUX_PG(pmc,    PWR_ON,    PWR_INTR,  RSVD3,     RSVD4,         PWR_ON,    0x14, 23, 0x98, 18, -1,   -1),
+	MUX_PG(pta,    I2C2,      HDMI,      GMI,       RSVD4,         RSVD4,     0x14, 24, 0x98, 22, 0xa4, 4),
+	MUX_PG(rm,     I2C1,      RSVD2,     RSVD3,     RSVD4,         RSVD4,     0x14, 25, 0x80, 14, 0xa4, 0),
+	MUX_PG(sdb,    UARTA,     PWM,       SDIO3,     SPI2,          PWM,       0x20, 15, 0x8c, 10, -1,   -1),
+	MUX_PG(sdc,    PWM,       TWC,       SDIO3,     SPI3,          TWC,       0x18, 1,  0x8c, 12, 0xac, 28),
+	MUX_PG(sdd,    UARTA,     PWM,       SDIO3,     SPI3,          PWM,       0x18, 2,  0x8c, 14, 0xac, 30),
+	MUX_PG(sdio1,  SDIO1,     RSVD2,     UARTE,     UARTA,         RSVD2,     0x14, 30, 0x80, 30, 0xb0, 18),
+	MUX_PG(slxa,   PCIE,      SPI4,      SDIO3,     SPI2,          PCIE,      0x18, 3,  0x84, 6,  0xa4, 22),
+	MUX_PG(slxc,   SPDIF,     SPI4,      SDIO3,     SPI2,          SPI4,      0x18, 5,  0x84, 10, 0xa4, 26),
+	MUX_PG(slxd,   SPDIF,     SPI4,      SDIO3,     SPI2,          SPI4,      0x18, 6,  0x84, 12, 0xa4, 28),
+	MUX_PG(slxk,   PCIE,      SPI4,      SDIO3,     SPI2,          PCIE,      0x18, 7,  0x84, 14, 0xa4, 30),
+	MUX_PG(spdi,   SPDIF,     RSVD2,     I2C1,      SDIO2,         RSVD2,     0x18, 8,  0x8c, 8,  0xa4, 16),
+	MUX_PG(spdo,   SPDIF,     RSVD2,     I2C1,      SDIO2,         RSVD2,     0x18, 9,  0x8c, 6,  0xa4, 18),
+	MUX_PG(spia,   SPI1,      SPI2,      SPI3,      GMI,           GMI,       0x18, 10, 0x8c, 30, 0xa8, 4),
+	MUX_PG(spib,   SPI1,      SPI2,      SPI3,      GMI,           GMI,       0x18, 11, 0x8c, 28, 0xa8, 6),
+	MUX_PG(spic,   SPI1,      SPI2,      SPI3,      GMI,           GMI,       0x18, 12, 0x8c, 26, 0xa8, 8),
+	MUX_PG(spid,   SPI2,      SPI1,      SPI2_ALT,  GMI,           GMI,       0x18, 13, 0x8c, 24, 0xa8, 10),
+	MUX_PG(spie,   SPI2,      SPI1,      SPI2_ALT,  GMI,           GMI,       0x18, 14, 0x8c, 22, 0xa8, 12),
+	MUX_PG(spif,   SPI3,      SPI1,      SPI2,      RSVD4,         RSVD4,     0x18, 15, 0x8c, 20, 0xa8, 14),
+	MUX_PG(spig,   SPI3,      SPI2,      SPI2_ALT,  I2C1,          SPI2_ALT,  0x18, 16, 0x8c, 18, 0xa8, 16),
+	MUX_PG(spih,   SPI3,      SPI2,      SPI2_ALT,  I2C1,          SPI2_ALT,  0x18, 17, 0x8c, 16, 0xa8, 18),
+	MUX_PG(uaa,    SPI3,      MIPI_HS,   UARTA,     ULPI,          MIPI_HS,   0x18, 18, 0x80, 0,  0xac, 0),
+	MUX_PG(uab,    SPI2,      MIPI_HS,   UARTA,     ULPI,          MIPI_HS,   0x18, 19, 0x80, 2,  0xac, 2),
+	MUX_PG(uac,    OWR,       RSVD2,     RSVD3,     RSVD4,         RSVD4,     0x18, 20, 0x80, 4,  0xac, 4),
+	MUX_PG(uad,    IRDA,      SPDIF,     UARTA,     SPI4,          SPDIF,     0x18, 21, 0x80, 6,  0xac, 6),
+	MUX_PG(uca,    UARTC,     RSVD2,     GMI,       RSVD4,         RSVD4,     0x18, 22, 0x84, 16, 0xac, 8),
+	MUX_PG(ucb,    UARTC,     PWM,       GMI,       RSVD4,         RSVD4,     0x18, 23, 0x84, 18, 0xac, 10),
+	MUX_PG(uda,    SPI1,      RSVD2,     UARTD,     ULPI,          RSVD2,     0x20, 13, 0x80, 8,  0xb0, 16),
+	/*      pg_name, pupd_r/b */
+	PULL_PG(ck32,    0xb0, 14),
+	PULL_PG(ddrc,    0xac, 26),
+	PULL_PG(pmca,    0xb0, 4),
+	PULL_PG(pmcb,    0xb0, 6),
+	PULL_PG(pmcc,    0xb0, 8),
+	PULL_PG(pmcd,    0xb0, 10),
+	PULL_PG(pmce,    0xb0, 12),
+	PULL_PG(xm2c,    0xa8, 30),
+	PULL_PG(xm2d,    0xa8, 28),
+	PULL_PG(ls,      0xac, 20),
+	PULL_PG(lc,      0xac, 22),
+	PULL_PG(ld17_0,  0xac, 12),
+	PULL_PG(ld19_18, 0xac, 14),
+	PULL_PG(ld21_20, 0xac, 16),
+	PULL_PG(ld23_22, 0xac, 18),
+	/*     pg_name,    r */
+	DRV_PG(ao1,        0x868),
+	DRV_PG(ao2,        0x86c),
+	DRV_PG(at1,        0x870),
+	DRV_PG(at2,        0x874),
+	DRV_PG(cdev1,      0x878),
+	DRV_PG(cdev2,      0x87c),
+	DRV_PG(csus,       0x880),
+	DRV_PG(dap1,       0x884),
+	DRV_PG(dap2,       0x888),
+	DRV_PG(dap3,       0x88c),
+	DRV_PG(dap4,       0x890),
+	DRV_PG(dbg,        0x894),
+	DRV_PG(lcd1,       0x898),
+	DRV_PG(lcd2,       0x89c),
+	DRV_PG(sdmmc2,     0x8a0),
+	DRV_PG(sdmmc3,     0x8a4),
+	DRV_PG(spi,        0x8a8),
+	DRV_PG(uaa,        0x8ac),
+	DRV_PG(uab,        0x8b0),
+	DRV_PG(uart2,      0x8b4),
+	DRV_PG(uart3,      0x8b8),
+	DRV_PG(vi1,        0x8bc),
+	DRV_PG(vi2,        0x8c0),
+	/*         pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, drvup_b, slwr_b, slwr_w, slwf_b, slwf_w */
+	DRV_PG_EXT(xm2a,   0x8c4, -1, -1,  4, 14, 19, 24, 4, 28, 4),
+	DRV_PG_EXT(xm2c,   0x8c8, -1,  3, -1, 14, 19, 24, 4, 28, 4),
+	DRV_PG_EXT(xm2d,   0x8cc, -1,  3, -1, 14, 19, 24, 4, 28, 4),
+	DRV_PG_EXT(xm2clk, 0x8d0, -1, -1, -1, 14, 19, 24, 4, 28, 4),
+	/*     pg_name,    r */
+	DRV_PG(sdio1,      0x8e0),
+	DRV_PG(crt,        0x8ec),
+	DRV_PG(ddc,        0x8f0),
+	DRV_PG(gma,        0x8f4),
+	DRV_PG(gmb,        0x8f8),
+	DRV_PG(gmc,        0x8fc),
+	DRV_PG(gmd,        0x900),
+	DRV_PG(gme,        0x904),
+	DRV_PG(owr,        0x908),
+	DRV_PG(uda,        0x90c),
+};
+
+static const struct tegra_pinctrl_soc_data tegra20_pinctrl = {
+	.ngpios = NUM_GPIOS,
+	.pins = tegra20_pins,
+	.npins = ARRAY_SIZE(tegra20_pins),
+	.functions = tegra20_functions,
+	.nfunctions = ARRAY_SIZE(tegra20_functions),
+	.groups = tegra20_groups,
+	.ngroups = ARRAY_SIZE(tegra20_groups),
+};
+
+void __devinit tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc)
+{
+	*soc = &tegra20_pinctrl;
+}
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
new file mode 100644
index 0000000..1ea1e6a
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -0,0 +1,3726 @@
+/*
+ * Pinctrl data for the NVIDIA Tegra30 pinmux
+ *
+ * Copyright (c) 2011, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-tegra.h"
+
+/*
+ * Most pins affected by the pinmux can also be GPIOs. Define these first.
+ * These must match how the GPIO driver names/numbers its pins.
+ */
+#define _GPIO(offset)				(offset)
+
+#define TEGRA_PIN_CLK_32K_OUT_PA0	_GPIO(0)
+#define TEGRA_PIN_UART3_CTS_N_PA1	_GPIO(1)
+#define TEGRA_PIN_DAP2_FS_PA2		_GPIO(2)
+#define TEGRA_PIN_DAP2_SCLK_PA3		_GPIO(3)
+#define TEGRA_PIN_DAP2_DIN_PA4		_GPIO(4)
+#define TEGRA_PIN_DAP2_DOUT_PA5		_GPIO(5)
+#define TEGRA_PIN_SDMMC3_CLK_PA6	_GPIO(6)
+#define TEGRA_PIN_SDMMC3_CMD_PA7	_GPIO(7)
+#define TEGRA_PIN_GMI_A17_PB0		_GPIO(8)
+#define TEGRA_PIN_GMI_A18_PB1		_GPIO(9)
+#define TEGRA_PIN_LCD_PWR0_PB2		_GPIO(10)
+#define TEGRA_PIN_LCD_PCLK_PB3		_GPIO(11)
+#define TEGRA_PIN_SDMMC3_DAT3_PB4	_GPIO(12)
+#define TEGRA_PIN_SDMMC3_DAT2_PB5	_GPIO(13)
+#define TEGRA_PIN_SDMMC3_DAT1_PB6	_GPIO(14)
+#define TEGRA_PIN_SDMMC3_DAT0_PB7	_GPIO(15)
+#define TEGRA_PIN_UART3_RTS_N_PC0	_GPIO(16)
+#define TEGRA_PIN_LCD_PWR1_PC1		_GPIO(17)
+#define TEGRA_PIN_UART2_TXD_PC2		_GPIO(18)
+#define TEGRA_PIN_UART2_RXD_PC3		_GPIO(19)
+#define TEGRA_PIN_GEN1_I2C_SCL_PC4	_GPIO(20)
+#define TEGRA_PIN_GEN1_I2C_SDA_PC5	_GPIO(21)
+#define TEGRA_PIN_LCD_PWR2_PC6		_GPIO(22)
+#define TEGRA_PIN_GMI_WP_N_PC7		_GPIO(23)
+#define TEGRA_PIN_SDMMC3_DAT5_PD0	_GPIO(24)
+#define TEGRA_PIN_SDMMC3_DAT4_PD1	_GPIO(25)
+#define TEGRA_PIN_LCD_DC1_PD2		_GPIO(26)
+#define TEGRA_PIN_SDMMC3_DAT6_PD3	_GPIO(27)
+#define TEGRA_PIN_SDMMC3_DAT7_PD4	_GPIO(28)
+#define TEGRA_PIN_VI_D1_PD5		_GPIO(29)
+#define TEGRA_PIN_VI_VSYNC_PD6		_GPIO(30)
+#define TEGRA_PIN_VI_HSYNC_PD7		_GPIO(31)
+#define TEGRA_PIN_LCD_D0_PE0		_GPIO(32)
+#define TEGRA_PIN_LCD_D1_PE1		_GPIO(33)
+#define TEGRA_PIN_LCD_D2_PE2		_GPIO(34)
+#define TEGRA_PIN_LCD_D3_PE3		_GPIO(35)
+#define TEGRA_PIN_LCD_D4_PE4		_GPIO(36)
+#define TEGRA_PIN_LCD_D5_PE5		_GPIO(37)
+#define TEGRA_PIN_LCD_D6_PE6		_GPIO(38)
+#define TEGRA_PIN_LCD_D7_PE7		_GPIO(39)
+#define TEGRA_PIN_LCD_D8_PF0		_GPIO(40)
+#define TEGRA_PIN_LCD_D9_PF1		_GPIO(41)
+#define TEGRA_PIN_LCD_D10_PF2		_GPIO(42)
+#define TEGRA_PIN_LCD_D11_PF3		_GPIO(43)
+#define TEGRA_PIN_LCD_D12_PF4		_GPIO(44)
+#define TEGRA_PIN_LCD_D13_PF5		_GPIO(45)
+#define TEGRA_PIN_LCD_D14_PF6		_GPIO(46)
+#define TEGRA_PIN_LCD_D15_PF7		_GPIO(47)
+#define TEGRA_PIN_GMI_AD0_PG0		_GPIO(48)
+#define TEGRA_PIN_GMI_AD1_PG1		_GPIO(49)
+#define TEGRA_PIN_GMI_AD2_PG2		_GPIO(50)
+#define TEGRA_PIN_GMI_AD3_PG3		_GPIO(51)
+#define TEGRA_PIN_GMI_AD4_PG4		_GPIO(52)
+#define TEGRA_PIN_GMI_AD5_PG5		_GPIO(53)
+#define TEGRA_PIN_GMI_AD6_PG6		_GPIO(54)
+#define TEGRA_PIN_GMI_AD7_PG7		_GPIO(55)
+#define TEGRA_PIN_GMI_AD8_PH0		_GPIO(56)
+#define TEGRA_PIN_GMI_AD9_PH1		_GPIO(57)
+#define TEGRA_PIN_GMI_AD10_PH2		_GPIO(58)
+#define TEGRA_PIN_GMI_AD11_PH3		_GPIO(59)
+#define TEGRA_PIN_GMI_AD12_PH4		_GPIO(60)
+#define TEGRA_PIN_GMI_AD13_PH5		_GPIO(61)
+#define TEGRA_PIN_GMI_AD14_PH6		_GPIO(62)
+#define TEGRA_PIN_GMI_AD15_PH7		_GPIO(63)
+#define TEGRA_PIN_GMI_WR_N_PI0		_GPIO(64)
+#define TEGRA_PIN_GMI_OE_N_PI1		_GPIO(65)
+#define TEGRA_PIN_GMI_DQS_PI2		_GPIO(66)
+#define TEGRA_PIN_GMI_CS6_N_PI3		_GPIO(67)
+#define TEGRA_PIN_GMI_RST_N_PI4		_GPIO(68)
+#define TEGRA_PIN_GMI_IORDY_PI5		_GPIO(69)
+#define TEGRA_PIN_GMI_CS7_N_PI6		_GPIO(70)
+#define TEGRA_PIN_GMI_WAIT_PI7		_GPIO(71)
+#define TEGRA_PIN_GMI_CS0_N_PJ0		_GPIO(72)
+#define TEGRA_PIN_LCD_DE_PJ1		_GPIO(73)
+#define TEGRA_PIN_GMI_CS1_N_PJ2		_GPIO(74)
+#define TEGRA_PIN_LCD_HSYNC_PJ3		_GPIO(75)
+#define TEGRA_PIN_LCD_VSYNC_PJ4		_GPIO(76)
+#define TEGRA_PIN_UART2_CTS_N_PJ5	_GPIO(77)
+#define TEGRA_PIN_UART2_RTS_N_PJ6	_GPIO(78)
+#define TEGRA_PIN_GMI_A16_PJ7		_GPIO(79)
+#define TEGRA_PIN_GMI_ADV_N_PK0		_GPIO(80)
+#define TEGRA_PIN_GMI_CLK_PK1		_GPIO(81)
+#define TEGRA_PIN_GMI_CS4_N_PK2		_GPIO(82)
+#define TEGRA_PIN_GMI_CS2_N_PK3		_GPIO(83)
+#define TEGRA_PIN_GMI_CS3_N_PK4		_GPIO(84)
+#define TEGRA_PIN_SPDIF_OUT_PK5		_GPIO(85)
+#define TEGRA_PIN_SPDIF_IN_PK6		_GPIO(86)
+#define TEGRA_PIN_GMI_A19_PK7		_GPIO(87)
+#define TEGRA_PIN_VI_D2_PL0		_GPIO(88)
+#define TEGRA_PIN_VI_D3_PL1		_GPIO(89)
+#define TEGRA_PIN_VI_D4_PL2		_GPIO(90)
+#define TEGRA_PIN_VI_D5_PL3		_GPIO(91)
+#define TEGRA_PIN_VI_D6_PL4		_GPIO(92)
+#define TEGRA_PIN_VI_D7_PL5		_GPIO(93)
+#define TEGRA_PIN_VI_D8_PL6		_GPIO(94)
+#define TEGRA_PIN_VI_D9_PL7		_GPIO(95)
+#define TEGRA_PIN_LCD_D16_PM0		_GPIO(96)
+#define TEGRA_PIN_LCD_D17_PM1		_GPIO(97)
+#define TEGRA_PIN_LCD_D18_PM2		_GPIO(98)
+#define TEGRA_PIN_LCD_D19_PM3		_GPIO(99)
+#define TEGRA_PIN_LCD_D20_PM4		_GPIO(100)
+#define TEGRA_PIN_LCD_D21_PM5		_GPIO(101)
+#define TEGRA_PIN_LCD_D22_PM6		_GPIO(102)
+#define TEGRA_PIN_LCD_D23_PM7		_GPIO(103)
+#define TEGRA_PIN_DAP1_FS_PN0		_GPIO(104)
+#define TEGRA_PIN_DAP1_DIN_PN1		_GPIO(105)
+#define TEGRA_PIN_DAP1_DOUT_PN2		_GPIO(106)
+#define TEGRA_PIN_DAP1_SCLK_PN3		_GPIO(107)
+#define TEGRA_PIN_LCD_CS0_N_PN4		_GPIO(108)
+#define TEGRA_PIN_LCD_SDOUT_PN5		_GPIO(109)
+#define TEGRA_PIN_LCD_DC0_PN6		_GPIO(110)
+#define TEGRA_PIN_HDMI_INT_PN7		_GPIO(111)
+#define TEGRA_PIN_ULPI_DATA7_PO0	_GPIO(112)
+#define TEGRA_PIN_ULPI_DATA0_PO1	_GPIO(113)
+#define TEGRA_PIN_ULPI_DATA1_PO2	_GPIO(114)
+#define TEGRA_PIN_ULPI_DATA2_PO3	_GPIO(115)
+#define TEGRA_PIN_ULPI_DATA3_PO4	_GPIO(116)
+#define TEGRA_PIN_ULPI_DATA4_PO5	_GPIO(117)
+#define TEGRA_PIN_ULPI_DATA5_PO6	_GPIO(118)
+#define TEGRA_PIN_ULPI_DATA6_PO7	_GPIO(119)
+#define TEGRA_PIN_DAP3_FS_PP0		_GPIO(120)
+#define TEGRA_PIN_DAP3_DIN_PP1		_GPIO(121)
+#define TEGRA_PIN_DAP3_DOUT_PP2		_GPIO(122)
+#define TEGRA_PIN_DAP3_SCLK_PP3		_GPIO(123)
+#define TEGRA_PIN_DAP4_FS_PP4		_GPIO(124)
+#define TEGRA_PIN_DAP4_DIN_PP5		_GPIO(125)
+#define TEGRA_PIN_DAP4_DOUT_PP6		_GPIO(126)
+#define TEGRA_PIN_DAP4_SCLK_PP7		_GPIO(127)
+#define TEGRA_PIN_KB_COL0_PQ0		_GPIO(128)
+#define TEGRA_PIN_KB_COL1_PQ1		_GPIO(129)
+#define TEGRA_PIN_KB_COL2_PQ2		_GPIO(130)
+#define TEGRA_PIN_KB_COL3_PQ3		_GPIO(131)
+#define TEGRA_PIN_KB_COL4_PQ4		_GPIO(132)
+#define TEGRA_PIN_KB_COL5_PQ5		_GPIO(133)
+#define TEGRA_PIN_KB_COL6_PQ6		_GPIO(134)
+#define TEGRA_PIN_KB_COL7_PQ7		_GPIO(135)
+#define TEGRA_PIN_KB_ROW0_PR0		_GPIO(136)
+#define TEGRA_PIN_KB_ROW1_PR1		_GPIO(137)
+#define TEGRA_PIN_KB_ROW2_PR2		_GPIO(138)
+#define TEGRA_PIN_KB_ROW3_PR3		_GPIO(139)
+#define TEGRA_PIN_KB_ROW4_PR4		_GPIO(140)
+#define TEGRA_PIN_KB_ROW5_PR5		_GPIO(141)
+#define TEGRA_PIN_KB_ROW6_PR6		_GPIO(142)
+#define TEGRA_PIN_KB_ROW7_PR7		_GPIO(143)
+#define TEGRA_PIN_KB_ROW8_PS0		_GPIO(144)
+#define TEGRA_PIN_KB_ROW9_PS1		_GPIO(145)
+#define TEGRA_PIN_KB_ROW10_PS2		_GPIO(146)
+#define TEGRA_PIN_KB_ROW11_PS3		_GPIO(147)
+#define TEGRA_PIN_KB_ROW12_PS4		_GPIO(148)
+#define TEGRA_PIN_KB_ROW13_PS5		_GPIO(149)
+#define TEGRA_PIN_KB_ROW14_PS6		_GPIO(150)
+#define TEGRA_PIN_KB_ROW15_PS7		_GPIO(151)
+#define TEGRA_PIN_VI_PCLK_PT0		_GPIO(152)
+#define TEGRA_PIN_VI_MCLK_PT1		_GPIO(153)
+#define TEGRA_PIN_VI_D10_PT2		_GPIO(154)
+#define TEGRA_PIN_VI_D11_PT3		_GPIO(155)
+#define TEGRA_PIN_VI_D0_PT4		_GPIO(156)
+#define TEGRA_PIN_GEN2_I2C_SCL_PT5	_GPIO(157)
+#define TEGRA_PIN_GEN2_I2C_SDA_PT6	_GPIO(158)
+#define TEGRA_PIN_SDMMC4_CMD_PT7	_GPIO(159)
+#define TEGRA_PIN_PU0			_GPIO(160)
+#define TEGRA_PIN_PU1			_GPIO(161)
+#define TEGRA_PIN_PU2			_GPIO(162)
+#define TEGRA_PIN_PU3			_GPIO(163)
+#define TEGRA_PIN_PU4			_GPIO(164)
+#define TEGRA_PIN_PU5			_GPIO(165)
+#define TEGRA_PIN_PU6			_GPIO(166)
+#define TEGRA_PIN_JTAG_RTCK_PU7		_GPIO(167)
+#define TEGRA_PIN_PV0			_GPIO(168)
+#define TEGRA_PIN_PV1			_GPIO(169)
+#define TEGRA_PIN_PV2			_GPIO(170)
+#define TEGRA_PIN_PV3			_GPIO(171)
+#define TEGRA_PIN_DDC_SCL_PV4		_GPIO(172)
+#define TEGRA_PIN_DDC_SDA_PV5		_GPIO(173)
+#define TEGRA_PIN_CRT_HSYNC_PV6		_GPIO(174)
+#define TEGRA_PIN_CRT_VSYNC_PV7		_GPIO(175)
+#define TEGRA_PIN_LCD_CS1_N_PW0		_GPIO(176)
+#define TEGRA_PIN_LCD_M1_PW1		_GPIO(177)
+#define TEGRA_PIN_SPI2_CS1_N_PW2	_GPIO(178)
+#define TEGRA_PIN_SPI2_CS2_N_PW3	_GPIO(179)
+#define TEGRA_PIN_CLK1_OUT_PW4		_GPIO(180)
+#define TEGRA_PIN_CLK2_OUT_PW5		_GPIO(181)
+#define TEGRA_PIN_UART3_TXD_PW6		_GPIO(182)
+#define TEGRA_PIN_UART3_RXD_PW7		_GPIO(183)
+#define TEGRA_PIN_SPI2_MOSI_PX0		_GPIO(184)
+#define TEGRA_PIN_SPI2_MISO_PX1		_GPIO(185)
+#define TEGRA_PIN_SPI2_SCK_PX2		_GPIO(186)
+#define TEGRA_PIN_SPI2_CS0_N_PX3	_GPIO(187)
+#define TEGRA_PIN_SPI1_MOSI_PX4		_GPIO(188)
+#define TEGRA_PIN_SPI1_SCK_PX5		_GPIO(189)
+#define TEGRA_PIN_SPI1_CS0_N_PX6	_GPIO(190)
+#define TEGRA_PIN_SPI1_MISO_PX7		_GPIO(191)
+#define TEGRA_PIN_ULPI_CLK_PY0		_GPIO(192)
+#define TEGRA_PIN_ULPI_DIR_PY1		_GPIO(193)
+#define TEGRA_PIN_ULPI_NXT_PY2		_GPIO(194)
+#define TEGRA_PIN_ULPI_STP_PY3		_GPIO(195)
+#define TEGRA_PIN_SDMMC1_DAT3_PY4	_GPIO(196)
+#define TEGRA_PIN_SDMMC1_DAT2_PY5	_GPIO(197)
+#define TEGRA_PIN_SDMMC1_DAT1_PY6	_GPIO(198)
+#define TEGRA_PIN_SDMMC1_DAT0_PY7	_GPIO(199)
+#define TEGRA_PIN_SDMMC1_CLK_PZ0	_GPIO(200)
+#define TEGRA_PIN_SDMMC1_CMD_PZ1	_GPIO(201)
+#define TEGRA_PIN_LCD_SDIN_PZ2		_GPIO(202)
+#define TEGRA_PIN_LCD_WR_N_PZ3		_GPIO(203)
+#define TEGRA_PIN_LCD_SCK_PZ4		_GPIO(204)
+#define TEGRA_PIN_SYS_CLK_REQ_PZ5	_GPIO(205)
+#define TEGRA_PIN_PWR_I2C_SCL_PZ6	_GPIO(206)
+#define TEGRA_PIN_PWR_I2C_SDA_PZ7	_GPIO(207)
+#define TEGRA_PIN_SDMMC4_DAT0_PAA0	_GPIO(208)
+#define TEGRA_PIN_SDMMC4_DAT1_PAA1	_GPIO(209)
+#define TEGRA_PIN_SDMMC4_DAT2_PAA2	_GPIO(210)
+#define TEGRA_PIN_SDMMC4_DAT3_PAA3	_GPIO(211)
+#define TEGRA_PIN_SDMMC4_DAT4_PAA4	_GPIO(212)
+#define TEGRA_PIN_SDMMC4_DAT5_PAA5	_GPIO(213)
+#define TEGRA_PIN_SDMMC4_DAT6_PAA6	_GPIO(214)
+#define TEGRA_PIN_SDMMC4_DAT7_PAA7	_GPIO(215)
+#define TEGRA_PIN_PBB0			_GPIO(216)
+#define TEGRA_PIN_CAM_I2C_SCL_PBB1	_GPIO(217)
+#define TEGRA_PIN_CAM_I2C_SDA_PBB2	_GPIO(218)
+#define TEGRA_PIN_PBB3			_GPIO(219)
+#define TEGRA_PIN_PBB4			_GPIO(220)
+#define TEGRA_PIN_PBB5			_GPIO(221)
+#define TEGRA_PIN_PBB6			_GPIO(222)
+#define TEGRA_PIN_PBB7			_GPIO(223)
+#define TEGRA_PIN_CAM_MCLK_PCC0		_GPIO(224)
+#define TEGRA_PIN_PCC1			_GPIO(225)
+#define TEGRA_PIN_PCC2			_GPIO(226)
+#define TEGRA_PIN_SDMMC4_RST_N_PCC3	_GPIO(227)
+#define TEGRA_PIN_SDMMC4_CLK_PCC4	_GPIO(228)
+#define TEGRA_PIN_CLK2_REQ_PCC5		_GPIO(229)
+#define TEGRA_PIN_PEX_L2_RST_N_PCC6	_GPIO(230)
+#define TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7	_GPIO(231)
+#define TEGRA_PIN_PEX_L0_PRSNT_N_PDD0	_GPIO(232)
+#define TEGRA_PIN_PEX_L0_RST_N_PDD1	_GPIO(233)
+#define TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2	_GPIO(234)
+#define TEGRA_PIN_PEX_WAKE_N_PDD3	_GPIO(235)
+#define TEGRA_PIN_PEX_L1_PRSNT_N_PDD4	_GPIO(236)
+#define TEGRA_PIN_PEX_L1_RST_N_PDD5	_GPIO(237)
+#define TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6	_GPIO(238)
+#define TEGRA_PIN_PEX_L2_PRSNT_N_PDD7	_GPIO(239)
+#define TEGRA_PIN_CLK3_OUT_PEE0		_GPIO(240)
+#define TEGRA_PIN_CLK3_REQ_PEE1		_GPIO(241)
+#define TEGRA_PIN_CLK1_REQ_PEE2		_GPIO(242)
+#define TEGRA_PIN_HDMI_CEC_PEE3		_GPIO(243)
+#define TEGRA_PIN_PEE4			_GPIO(244)
+#define TEGRA_PIN_PEE5			_GPIO(245)
+#define TEGRA_PIN_PEE6			_GPIO(246)
+#define TEGRA_PIN_PEE7			_GPIO(247)
+
+/* All non-GPIO pins follow */
+#define NUM_GPIOS				(TEGRA_PIN_PEE7 + 1)
+#define _PIN(offset)				(NUM_GPIOS + (offset))
+
+/* Non-GPIO pins */
+#define TEGRA_PIN_CLK_32K_IN		_PIN(0)
+#define TEGRA_PIN_CORE_PWR_REQ		_PIN(1)
+#define TEGRA_PIN_CPU_PWR_REQ		_PIN(2)
+#define TEGRA_PIN_JTAG_TCK		_PIN(3)
+#define TEGRA_PIN_JTAG_TDI		_PIN(4)
+#define TEGRA_PIN_JTAG_TDO		_PIN(5)
+#define TEGRA_PIN_JTAG_TMS		_PIN(6)
+#define TEGRA_PIN_JTAG_TRST_N		_PIN(7)
+#define TEGRA_PIN_OWR			_PIN(8)
+#define TEGRA_PIN_PWR_INT_N		_PIN(9)
+#define TEGRA_PIN_SYS_RESET_N		_PIN(10)
+#define TEGRA_PIN_TEST_MODE_EN		_PIN(11)
+
+static const struct pinctrl_pin_desc tegra30_pins[] = {
+	PINCTRL_PIN(TEGRA_PIN_CLK_32K_OUT_PA0, "CLK_32K_OUT PA0"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_CTS_N_PA1, "UART3_CTS_N PA1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PA2, "DAP2_FS PA2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PA3, "DAP2_SCLK PA3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PA4, "DAP2_DIN PA4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PA5, "DAP2_DOUT PA5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CLK_PA6, "SDMMC3_CLK PA6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_CMD_PA7, "SDMMC3_CMD PA7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A17_PB0, "GMI_A17 PB0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A18_PB1, "GMI_A18 PB1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PWR0_PB2, "LCD_PWR0 PB2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PCLK_PB3, "LCD_PCLK PB3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT3_PB4, "SDMMC3_DAT3 PB4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT2_PB5, "SDMMC3_DAT2 PB5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT1_PB6, "SDMMC3_DAT1 PB6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT0_PB7, "SDMMC3_DAT0 PB7"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_RTS_N_PC0, "UART3_RTS_N PC0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PWR1_PC1, "LCD_PWR1 PC1"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_TXD_PC2, "UART2_TXD PC2"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_RXD_PC3, "UART2_RXD PC3"),
+	PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PC4, "GEN1_I2C_SCL PC4"),
+	PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PC5, "GEN1_I2C_SDA PC5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_PWR2_PC6, "LCD_PWR2 PC6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WP_N_PC7, "GMI_WP_N PC7"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT5_PD0, "SDMMC3_DAT5 PD0"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT4_PD1, "SDMMC3_DAT4 PD1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_DC1_PD2, "LCD_DC1 PD2"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT6_PD3, "SDMMC3_DAT6 PD3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT7_PD4, "SDMMC3_DAT7 PD4"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D1_PD5, "VI_D1 PD5"),
+	PINCTRL_PIN(TEGRA_PIN_VI_VSYNC_PD6, "VI_VSYNC PD6"),
+	PINCTRL_PIN(TEGRA_PIN_VI_HSYNC_PD7, "VI_HSYNC PD7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D0_PE0, "LCD_D0 PE0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D1_PE1, "LCD_D1 PE1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D2_PE2, "LCD_D2 PE2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D3_PE3, "LCD_D3 PE3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D4_PE4, "LCD_D4 PE4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D5_PE5, "LCD_D5 PE5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D6_PE6, "LCD_D6 PE6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D7_PE7, "LCD_D7 PE7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D8_PF0, "LCD_D8 PF0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D9_PF1, "LCD_D9 PF1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D10_PF2, "LCD_D10 PF2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D11_PF3, "LCD_D11 PF3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D12_PF4, "LCD_D12 PF4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D13_PF5, "LCD_D13 PF5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D14_PF6, "LCD_D14 PF6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D15_PF7, "LCD_D15 PF7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD0_PG0, "GMI_AD0 PG0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD1_PG1, "GMI_AD1 PG1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD2_PG2, "GMI_AD2 PG2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD3_PG3, "GMI_AD3 PG3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD4_PG4, "GMI_AD4 PG4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD5_PG5, "GMI_AD5 PG5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD6_PG6, "GMI_AD6 PG6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD7_PG7, "GMI_AD7 PG7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD8_PH0, "GMI_AD8 PH0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD9_PH1, "GMI_AD9 PH1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD10_PH2, "GMI_AD10 PH2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD11_PH3, "GMI_AD11 PH3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD12_PH4, "GMI_AD12 PH4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD13_PH5, "GMI_AD13 PH5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD14_PH6, "GMI_AD14 PH6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_AD15_PH7, "GMI_AD15 PH7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WR_N_PI0, "GMI_WR_N PI0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_OE_N_PI1, "GMI_OE_N PI1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_DQS_PI2, "GMI_DQS PI2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS6_N_PI3, "GMI_CS6_N PI3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_RST_N_PI4, "GMI_RST_N PI4"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_IORDY_PI5, "GMI_IORDY PI5"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS7_N_PI6, "GMI_CS7_N PI6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_WAIT_PI7, "GMI_WAIT PI7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS0_N_PJ0, "GMI_CS0_N PJ0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_DE_PJ1, "LCD_DE PJ1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS1_N_PJ2, "GMI_CS1_N PJ2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_HSYNC_PJ3, "LCD_HSYNC PJ3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_VSYNC_PJ4, "LCD_VSYNC PJ4"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_CTS_N_PJ5, "UART2_CTS_N PJ5"),
+	PINCTRL_PIN(TEGRA_PIN_UART2_RTS_N_PJ6, "UART2_RTS_N PJ6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A16_PJ7, "GMI_A16 PJ7"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_ADV_N_PK0, "GMI_ADV_N PK0"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CLK_PK1, "GMI_CLK PK1"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS4_N_PK2, "GMI_CS4_N PK2"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS2_N_PK3, "GMI_CS2_N PK3"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_CS3_N_PK4, "GMI_CS3_N PK4"),
+	PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PK5, "SPDIF_OUT PK5"),
+	PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PK6, "SPDIF_IN PK6"),
+	PINCTRL_PIN(TEGRA_PIN_GMI_A19_PK7, "GMI_A19 PK7"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D2_PL0, "VI_D2 PL0"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D3_PL1, "VI_D3 PL1"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D4_PL2, "VI_D4 PL2"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D5_PL3, "VI_D5 PL3"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D6_PL4, "VI_D6 PL4"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D7_PL5, "VI_D7 PL5"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D8_PL6, "VI_D8 PL6"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D9_PL7, "VI_D9 PL7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D16_PM0, "LCD_D16 PM0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D17_PM1, "LCD_D17 PM1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D18_PM2, "LCD_D18 PM2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D19_PM3, "LCD_D19 PM3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D20_PM4, "LCD_D20 PM4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D21_PM5, "LCD_D21 PM5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D22_PM6, "LCD_D22 PM6"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_D23_PM7, "LCD_D23 PM7"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PN0, "DAP1_FS PN0"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PN1, "DAP1_DIN PN1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PN2, "DAP1_DOUT PN2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PN3, "DAP1_SCLK PN3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_CS0_N_PN4, "LCD_CS0_N PN4"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_SDOUT_PN5, "LCD_SDOUT PN5"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_DC0_PN6, "LCD_DC0 PN6"),
+	PINCTRL_PIN(TEGRA_PIN_HDMI_INT_PN7, "HDMI_INT PN7"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA7_PO0, "ULPI_DATA7 PO0"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA0_PO1, "ULPI_DATA0 PO1"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA1_PO2, "ULPI_DATA1 PO2"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA2_PO3, "ULPI_DATA2 PO3"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA3_PO4, "ULPI_DATA3 PO4"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA4_PO5, "ULPI_DATA4 PO5"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA5_PO6, "ULPI_DATA5 PO6"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DATA6_PO7, "ULPI_DATA6 PO7"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_FS_PP0, "DAP3_FS PP0"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_DIN_PP1, "DAP3_DIN PP1"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_DOUT_PP2, "DAP3_DOUT PP2"),
+	PINCTRL_PIN(TEGRA_PIN_DAP3_SCLK_PP3, "DAP3_SCLK PP3"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PP4, "DAP4_FS PP4"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PP5, "DAP4_DIN PP5"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PP6, "DAP4_DOUT PP6"),
+	PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PP7, "DAP4_SCLK PP7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL0_PQ0, "KB_COL0 PQ0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL1_PQ1, "KB_COL1 PQ1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL2_PQ2, "KB_COL2 PQ2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL3_PQ3, "KB_COL3 PQ3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL4_PQ4, "KB_COL4 PQ4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL5_PQ5, "KB_COL5 PQ5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL6_PQ6, "KB_COL6 PQ6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_COL7_PQ7, "KB_COL7 PQ7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW0_PR0, "KB_ROW0 PR0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW1_PR1, "KB_ROW1 PR1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW2_PR2, "KB_ROW2 PR2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW3_PR3, "KB_ROW3 PR3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW4_PR4, "KB_ROW4 PR4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW5_PR5, "KB_ROW5 PR5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW6_PR6, "KB_ROW6 PR6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW7_PR7, "KB_ROW7 PR7"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW8_PS0, "KB_ROW8 PS0"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW9_PS1, "KB_ROW9 PS1"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW10_PS2, "KB_ROW10 PS2"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW11_PS3, "KB_ROW11 PS3"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW12_PS4, "KB_ROW12 PS4"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW13_PS5, "KB_ROW13 PS5"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW14_PS6, "KB_ROW14 PS6"),
+	PINCTRL_PIN(TEGRA_PIN_KB_ROW15_PS7, "KB_ROW15 PS7"),
+	PINCTRL_PIN(TEGRA_PIN_VI_PCLK_PT0, "VI_PCLK PT0"),
+	PINCTRL_PIN(TEGRA_PIN_VI_MCLK_PT1, "VI_MCLK PT1"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D10_PT2, "VI_D10 PT2"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D11_PT3, "VI_D11 PT3"),
+	PINCTRL_PIN(TEGRA_PIN_VI_D0_PT4, "VI_D0 PT4"),
+	PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PT5, "GEN2_I2C_SCL PT5"),
+	PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PT6, "GEN2_I2C_SDA PT6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_CMD_PT7, "SDMMC4_CMD PT7"),
+	PINCTRL_PIN(TEGRA_PIN_PU0, "PU0"),
+	PINCTRL_PIN(TEGRA_PIN_PU1, "PU1"),
+	PINCTRL_PIN(TEGRA_PIN_PU2, "PU2"),
+	PINCTRL_PIN(TEGRA_PIN_PU3, "PU3"),
+	PINCTRL_PIN(TEGRA_PIN_PU4, "PU4"),
+	PINCTRL_PIN(TEGRA_PIN_PU5, "PU5"),
+	PINCTRL_PIN(TEGRA_PIN_PU6, "PU6"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_RTCK_PU7, "JTAG_RTCK PU7"),
+	PINCTRL_PIN(TEGRA_PIN_PV0, "PV0"),
+	PINCTRL_PIN(TEGRA_PIN_PV1, "PV1"),
+	PINCTRL_PIN(TEGRA_PIN_PV2, "PV2"),
+	PINCTRL_PIN(TEGRA_PIN_PV3, "PV3"),
+	PINCTRL_PIN(TEGRA_PIN_DDC_SCL_PV4, "DDC_SCL PV4"),
+	PINCTRL_PIN(TEGRA_PIN_DDC_SDA_PV5, "DDC_SDA PV5"),
+	PINCTRL_PIN(TEGRA_PIN_CRT_HSYNC_PV6, "CRT_HSYNC PV6"),
+	PINCTRL_PIN(TEGRA_PIN_CRT_VSYNC_PV7, "CRT_VSYNC PV7"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_CS1_N_PW0, "LCD_CS1_N PW0"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_M1_PW1, "LCD_M1 PW1"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_CS1_N_PW2, "SPI2_CS1_N PW2"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_CS2_N_PW3, "SPI2_CS2_N PW3"),
+	PINCTRL_PIN(TEGRA_PIN_CLK1_OUT_PW4, "CLK1_OUT PW4"),
+	PINCTRL_PIN(TEGRA_PIN_CLK2_OUT_PW5, "CLK2_OUT PW5"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_TXD_PW6, "UART3_TXD PW6"),
+	PINCTRL_PIN(TEGRA_PIN_UART3_RXD_PW7, "UART3_RXD PW7"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_MOSI_PX0, "SPI2_MOSI PX0"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_MISO_PX1, "SPI2_MISO PX1"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_SCK_PX2, "SPI2_SCK PX2"),
+	PINCTRL_PIN(TEGRA_PIN_SPI2_CS0_N_PX3, "SPI2_CS0_N PX3"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_MOSI_PX4, "SPI1_MOSI PX4"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_SCK_PX5, "SPI1_SCK PX5"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_CS0_N_PX6, "SPI1_CS0_N PX6"),
+	PINCTRL_PIN(TEGRA_PIN_SPI1_MISO_PX7, "SPI1_MISO PX7"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_CLK_PY0, "ULPI_CLK PY0"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_DIR_PY1, "ULPI_DIR PY1"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_NXT_PY2, "ULPI_NXT PY2"),
+	PINCTRL_PIN(TEGRA_PIN_ULPI_STP_PY3, "ULPI_STP PY3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT3_PY4, "SDMMC1_DAT3 PY4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT2_PY5, "SDMMC1_DAT2 PY5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT1_PY6, "SDMMC1_DAT1 PY6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT0_PY7, "SDMMC1_DAT0 PY7"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_CLK_PZ0, "SDMMC1_CLK PZ0"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC1_CMD_PZ1, "SDMMC1_CMD PZ1"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_SDIN_PZ2, "LCD_SDIN PZ2"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_WR_N_PZ3, "LCD_WR_N PZ3"),
+	PINCTRL_PIN(TEGRA_PIN_LCD_SCK_PZ4, "LCD_SCK PZ4"),
+	PINCTRL_PIN(TEGRA_PIN_SYS_CLK_REQ_PZ5, "SYS_CLK_REQ PZ5"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PZ6, "PWR_I2C_SCL PZ6"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PZ7, "PWR_I2C_SDA PZ7"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT0_PAA0, "SDMMC4_DAT0 PAA0"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT1_PAA1, "SDMMC4_DAT1 PAA1"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT2_PAA2, "SDMMC4_DAT2 PAA2"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT3_PAA3, "SDMMC4_DAT3 PAA3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT4_PAA4, "SDMMC4_DAT4 PAA4"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT5_PAA5, "SDMMC4_DAT5 PAA5"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT6_PAA6, "SDMMC4_DAT6 PAA6"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT7_PAA7, "SDMMC4_DAT7 PAA7"),
+	PINCTRL_PIN(TEGRA_PIN_PBB0, "PBB0"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PBB1, "CAM_I2C_SCL PBB1"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PBB2, "CAM_I2C_SDA PBB2"),
+	PINCTRL_PIN(TEGRA_PIN_PBB3, "PBB3"),
+	PINCTRL_PIN(TEGRA_PIN_PBB4, "PBB4"),
+	PINCTRL_PIN(TEGRA_PIN_PBB5, "PBB5"),
+	PINCTRL_PIN(TEGRA_PIN_PBB6, "PBB6"),
+	PINCTRL_PIN(TEGRA_PIN_PBB7, "PBB7"),
+	PINCTRL_PIN(TEGRA_PIN_CAM_MCLK_PCC0, "CAM_MCLK PCC0"),
+	PINCTRL_PIN(TEGRA_PIN_PCC1, "PCC1"),
+	PINCTRL_PIN(TEGRA_PIN_PCC2, "PCC2"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_RST_N_PCC3, "SDMMC4_RST_N PCC3"),
+	PINCTRL_PIN(TEGRA_PIN_SDMMC4_CLK_PCC4, "SDMMC4_CLK PCC4"),
+	PINCTRL_PIN(TEGRA_PIN_CLK2_REQ_PCC5, "CLK2_REQ PCC5"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L2_RST_N_PCC6, "PEX_L2_RST_N PCC6"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7, "PEX_L2_CLKREQ_N PCC7"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L0_PRSNT_N_PDD0, "PEX_L0_PRSNT_N PDD0"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L0_RST_N_PDD1, "PEX_L0_RST_N PDD1"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2, "PEX_L0_CLKREQ_N PDD2"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_WAKE_N_PDD3, "PEX_WAKE_N PDD3"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L1_PRSNT_N_PDD4, "PEX_L1_PRSNT_N PDD4"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L1_RST_N_PDD5, "PEX_L1_RST_N PDD5"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6, "PEX_L1_CLKREQ_N PDD6"),
+	PINCTRL_PIN(TEGRA_PIN_PEX_L2_PRSNT_N_PDD7, "PEX_L2_PRSNT_N PDD7"),
+	PINCTRL_PIN(TEGRA_PIN_CLK3_OUT_PEE0, "CLK3_OUT PEE0"),
+	PINCTRL_PIN(TEGRA_PIN_CLK3_REQ_PEE1, "CLK3_REQ PEE1"),
+	PINCTRL_PIN(TEGRA_PIN_CLK1_REQ_PEE2, "CLK1_REQ PEE2"),
+	PINCTRL_PIN(TEGRA_PIN_HDMI_CEC_PEE3, "HDMI_CEC PEE3"),
+	PINCTRL_PIN(TEGRA_PIN_PEE4, "PEE4"),
+	PINCTRL_PIN(TEGRA_PIN_PEE5, "PEE5"),
+	PINCTRL_PIN(TEGRA_PIN_PEE6, "PEE6"),
+	PINCTRL_PIN(TEGRA_PIN_PEE7, "PEE7"),
+	PINCTRL_PIN(TEGRA_PIN_CLK_32K_IN, "CLK_32K_IN"),
+	PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"),
+	PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TCK, "JTAG_TCK"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TDI, "JTAG_TDI"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TDO, "JTAG_TDO"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TMS, "JTAG_TMS"),
+	PINCTRL_PIN(TEGRA_PIN_JTAG_TRST_N, "JTAG_TRST_N"),
+	PINCTRL_PIN(TEGRA_PIN_OWR, "OWR"),
+	PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"),
+	PINCTRL_PIN(TEGRA_PIN_SYS_RESET_N, "SYS_RESET_N"),
+	PINCTRL_PIN(TEGRA_PIN_TEST_MODE_EN, "TEST_MODE_EN"),
+};
+
+static const unsigned clk_32k_out_pa0_pins[] = {
+	TEGRA_PIN_CLK_32K_OUT_PA0,
+};
+
+static const unsigned uart3_cts_n_pa1_pins[] = {
+	TEGRA_PIN_UART3_CTS_N_PA1,
+};
+
+static const unsigned dap2_fs_pa2_pins[] = {
+	TEGRA_PIN_DAP2_FS_PA2,
+};
+
+static const unsigned dap2_sclk_pa3_pins[] = {
+	TEGRA_PIN_DAP2_SCLK_PA3,
+};
+
+static const unsigned dap2_din_pa4_pins[] = {
+	TEGRA_PIN_DAP2_DIN_PA4,
+};
+
+static const unsigned dap2_dout_pa5_pins[] = {
+	TEGRA_PIN_DAP2_DOUT_PA5,
+};
+
+static const unsigned sdmmc3_clk_pa6_pins[] = {
+	TEGRA_PIN_SDMMC3_CLK_PA6,
+};
+
+static const unsigned sdmmc3_cmd_pa7_pins[] = {
+	TEGRA_PIN_SDMMC3_CMD_PA7,
+};
+
+static const unsigned gmi_a17_pb0_pins[] = {
+	TEGRA_PIN_GMI_A17_PB0,
+};
+
+static const unsigned gmi_a18_pb1_pins[] = {
+	TEGRA_PIN_GMI_A18_PB1,
+};
+
+static const unsigned lcd_pwr0_pb2_pins[] = {
+	TEGRA_PIN_LCD_PWR0_PB2,
+};
+
+static const unsigned lcd_pclk_pb3_pins[] = {
+	TEGRA_PIN_LCD_PCLK_PB3,
+};
+
+static const unsigned sdmmc3_dat3_pb4_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT3_PB4,
+};
+
+static const unsigned sdmmc3_dat2_pb5_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT2_PB5,
+};
+
+static const unsigned sdmmc3_dat1_pb6_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT1_PB6,
+};
+
+static const unsigned sdmmc3_dat0_pb7_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT0_PB7,
+};
+
+static const unsigned uart3_rts_n_pc0_pins[] = {
+	TEGRA_PIN_UART3_RTS_N_PC0,
+};
+
+static const unsigned lcd_pwr1_pc1_pins[] = {
+	TEGRA_PIN_LCD_PWR1_PC1,
+};
+
+static const unsigned uart2_txd_pc2_pins[] = {
+	TEGRA_PIN_UART2_TXD_PC2,
+};
+
+static const unsigned uart2_rxd_pc3_pins[] = {
+	TEGRA_PIN_UART2_RXD_PC3,
+};
+
+static const unsigned gen1_i2c_scl_pc4_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SCL_PC4,
+};
+
+static const unsigned gen1_i2c_sda_pc5_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SDA_PC5,
+};
+
+static const unsigned lcd_pwr2_pc6_pins[] = {
+	TEGRA_PIN_LCD_PWR2_PC6,
+};
+
+static const unsigned gmi_wp_n_pc7_pins[] = {
+	TEGRA_PIN_GMI_WP_N_PC7,
+};
+
+static const unsigned sdmmc3_dat5_pd0_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT5_PD0,
+};
+
+static const unsigned sdmmc3_dat4_pd1_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT4_PD1,
+};
+
+static const unsigned lcd_dc1_pd2_pins[] = {
+	TEGRA_PIN_LCD_DC1_PD2,
+};
+
+static const unsigned sdmmc3_dat6_pd3_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT6_PD3,
+};
+
+static const unsigned sdmmc3_dat7_pd4_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT7_PD4,
+};
+
+static const unsigned vi_d1_pd5_pins[] = {
+	TEGRA_PIN_VI_D1_PD5,
+};
+
+static const unsigned vi_vsync_pd6_pins[] = {
+	TEGRA_PIN_VI_VSYNC_PD6,
+};
+
+static const unsigned vi_hsync_pd7_pins[] = {
+	TEGRA_PIN_VI_HSYNC_PD7,
+};
+
+static const unsigned lcd_d0_pe0_pins[] = {
+	TEGRA_PIN_LCD_D0_PE0,
+};
+
+static const unsigned lcd_d1_pe1_pins[] = {
+	TEGRA_PIN_LCD_D1_PE1,
+};
+
+static const unsigned lcd_d2_pe2_pins[] = {
+	TEGRA_PIN_LCD_D2_PE2,
+};
+
+static const unsigned lcd_d3_pe3_pins[] = {
+	TEGRA_PIN_LCD_D3_PE3,
+};
+
+static const unsigned lcd_d4_pe4_pins[] = {
+	TEGRA_PIN_LCD_D4_PE4,
+};
+
+static const unsigned lcd_d5_pe5_pins[] = {
+	TEGRA_PIN_LCD_D5_PE5,
+};
+
+static const unsigned lcd_d6_pe6_pins[] = {
+	TEGRA_PIN_LCD_D6_PE6,
+};
+
+static const unsigned lcd_d7_pe7_pins[] = {
+	TEGRA_PIN_LCD_D7_PE7,
+};
+
+static const unsigned lcd_d8_pf0_pins[] = {
+	TEGRA_PIN_LCD_D8_PF0,
+};
+
+static const unsigned lcd_d9_pf1_pins[] = {
+	TEGRA_PIN_LCD_D9_PF1,
+};
+
+static const unsigned lcd_d10_pf2_pins[] = {
+	TEGRA_PIN_LCD_D10_PF2,
+};
+
+static const unsigned lcd_d11_pf3_pins[] = {
+	TEGRA_PIN_LCD_D11_PF3,
+};
+
+static const unsigned lcd_d12_pf4_pins[] = {
+	TEGRA_PIN_LCD_D12_PF4,
+};
+
+static const unsigned lcd_d13_pf5_pins[] = {
+	TEGRA_PIN_LCD_D13_PF5,
+};
+
+static const unsigned lcd_d14_pf6_pins[] = {
+	TEGRA_PIN_LCD_D14_PF6,
+};
+
+static const unsigned lcd_d15_pf7_pins[] = {
+	TEGRA_PIN_LCD_D15_PF7,
+};
+
+static const unsigned gmi_ad0_pg0_pins[] = {
+	TEGRA_PIN_GMI_AD0_PG0,
+};
+
+static const unsigned gmi_ad1_pg1_pins[] = {
+	TEGRA_PIN_GMI_AD1_PG1,
+};
+
+static const unsigned gmi_ad2_pg2_pins[] = {
+	TEGRA_PIN_GMI_AD2_PG2,
+};
+
+static const unsigned gmi_ad3_pg3_pins[] = {
+	TEGRA_PIN_GMI_AD3_PG3,
+};
+
+static const unsigned gmi_ad4_pg4_pins[] = {
+	TEGRA_PIN_GMI_AD4_PG4,
+};
+
+static const unsigned gmi_ad5_pg5_pins[] = {
+	TEGRA_PIN_GMI_AD5_PG5,
+};
+
+static const unsigned gmi_ad6_pg6_pins[] = {
+	TEGRA_PIN_GMI_AD6_PG6,
+};
+
+static const unsigned gmi_ad7_pg7_pins[] = {
+	TEGRA_PIN_GMI_AD7_PG7,
+};
+
+static const unsigned gmi_ad8_ph0_pins[] = {
+	TEGRA_PIN_GMI_AD8_PH0,
+};
+
+static const unsigned gmi_ad9_ph1_pins[] = {
+	TEGRA_PIN_GMI_AD9_PH1,
+};
+
+static const unsigned gmi_ad10_ph2_pins[] = {
+	TEGRA_PIN_GMI_AD10_PH2,
+};
+
+static const unsigned gmi_ad11_ph3_pins[] = {
+	TEGRA_PIN_GMI_AD11_PH3,
+};
+
+static const unsigned gmi_ad12_ph4_pins[] = {
+	TEGRA_PIN_GMI_AD12_PH4,
+};
+
+static const unsigned gmi_ad13_ph5_pins[] = {
+	TEGRA_PIN_GMI_AD13_PH5,
+};
+
+static const unsigned gmi_ad14_ph6_pins[] = {
+	TEGRA_PIN_GMI_AD14_PH6,
+};
+
+static const unsigned gmi_ad15_ph7_pins[] = {
+	TEGRA_PIN_GMI_AD15_PH7,
+};
+
+static const unsigned gmi_wr_n_pi0_pins[] = {
+	TEGRA_PIN_GMI_WR_N_PI0,
+};
+
+static const unsigned gmi_oe_n_pi1_pins[] = {
+	TEGRA_PIN_GMI_OE_N_PI1,
+};
+
+static const unsigned gmi_dqs_pi2_pins[] = {
+	TEGRA_PIN_GMI_DQS_PI2,
+};
+
+static const unsigned gmi_cs6_n_pi3_pins[] = {
+	TEGRA_PIN_GMI_CS6_N_PI3,
+};
+
+static const unsigned gmi_rst_n_pi4_pins[] = {
+	TEGRA_PIN_GMI_RST_N_PI4,
+};
+
+static const unsigned gmi_iordy_pi5_pins[] = {
+	TEGRA_PIN_GMI_IORDY_PI5,
+};
+
+static const unsigned gmi_cs7_n_pi6_pins[] = {
+	TEGRA_PIN_GMI_CS7_N_PI6,
+};
+
+static const unsigned gmi_wait_pi7_pins[] = {
+	TEGRA_PIN_GMI_WAIT_PI7,
+};
+
+static const unsigned gmi_cs0_n_pj0_pins[] = {
+	TEGRA_PIN_GMI_CS0_N_PJ0,
+};
+
+static const unsigned lcd_de_pj1_pins[] = {
+	TEGRA_PIN_LCD_DE_PJ1,
+};
+
+static const unsigned gmi_cs1_n_pj2_pins[] = {
+	TEGRA_PIN_GMI_CS1_N_PJ2,
+};
+
+static const unsigned lcd_hsync_pj3_pins[] = {
+	TEGRA_PIN_LCD_HSYNC_PJ3,
+};
+
+static const unsigned lcd_vsync_pj4_pins[] = {
+	TEGRA_PIN_LCD_VSYNC_PJ4,
+};
+
+static const unsigned uart2_cts_n_pj5_pins[] = {
+	TEGRA_PIN_UART2_CTS_N_PJ5,
+};
+
+static const unsigned uart2_rts_n_pj6_pins[] = {
+	TEGRA_PIN_UART2_RTS_N_PJ6,
+};
+
+static const unsigned gmi_a16_pj7_pins[] = {
+	TEGRA_PIN_GMI_A16_PJ7,
+};
+
+static const unsigned gmi_adv_n_pk0_pins[] = {
+	TEGRA_PIN_GMI_ADV_N_PK0,
+};
+
+static const unsigned gmi_clk_pk1_pins[] = {
+	TEGRA_PIN_GMI_CLK_PK1,
+};
+
+static const unsigned gmi_cs4_n_pk2_pins[] = {
+	TEGRA_PIN_GMI_CS4_N_PK2,
+};
+
+static const unsigned gmi_cs2_n_pk3_pins[] = {
+	TEGRA_PIN_GMI_CS2_N_PK3,
+};
+
+static const unsigned gmi_cs3_n_pk4_pins[] = {
+	TEGRA_PIN_GMI_CS3_N_PK4,
+};
+
+static const unsigned spdif_out_pk5_pins[] = {
+	TEGRA_PIN_SPDIF_OUT_PK5,
+};
+
+static const unsigned spdif_in_pk6_pins[] = {
+	TEGRA_PIN_SPDIF_IN_PK6,
+};
+
+static const unsigned gmi_a19_pk7_pins[] = {
+	TEGRA_PIN_GMI_A19_PK7,
+};
+
+static const unsigned vi_d2_pl0_pins[] = {
+	TEGRA_PIN_VI_D2_PL0,
+};
+
+static const unsigned vi_d3_pl1_pins[] = {
+	TEGRA_PIN_VI_D3_PL1,
+};
+
+static const unsigned vi_d4_pl2_pins[] = {
+	TEGRA_PIN_VI_D4_PL2,
+};
+
+static const unsigned vi_d5_pl3_pins[] = {
+	TEGRA_PIN_VI_D5_PL3,
+};
+
+static const unsigned vi_d6_pl4_pins[] = {
+	TEGRA_PIN_VI_D6_PL4,
+};
+
+static const unsigned vi_d7_pl5_pins[] = {
+	TEGRA_PIN_VI_D7_PL5,
+};
+
+static const unsigned vi_d8_pl6_pins[] = {
+	TEGRA_PIN_VI_D8_PL6,
+};
+
+static const unsigned vi_d9_pl7_pins[] = {
+	TEGRA_PIN_VI_D9_PL7,
+};
+
+static const unsigned lcd_d16_pm0_pins[] = {
+	TEGRA_PIN_LCD_D16_PM0,
+};
+
+static const unsigned lcd_d17_pm1_pins[] = {
+	TEGRA_PIN_LCD_D17_PM1,
+};
+
+static const unsigned lcd_d18_pm2_pins[] = {
+	TEGRA_PIN_LCD_D18_PM2,
+};
+
+static const unsigned lcd_d19_pm3_pins[] = {
+	TEGRA_PIN_LCD_D19_PM3,
+};
+
+static const unsigned lcd_d20_pm4_pins[] = {
+	TEGRA_PIN_LCD_D20_PM4,
+};
+
+static const unsigned lcd_d21_pm5_pins[] = {
+	TEGRA_PIN_LCD_D21_PM5,
+};
+
+static const unsigned lcd_d22_pm6_pins[] = {
+	TEGRA_PIN_LCD_D22_PM6,
+};
+
+static const unsigned lcd_d23_pm7_pins[] = {
+	TEGRA_PIN_LCD_D23_PM7,
+};
+
+static const unsigned dap1_fs_pn0_pins[] = {
+	TEGRA_PIN_DAP1_FS_PN0,
+};
+
+static const unsigned dap1_din_pn1_pins[] = {
+	TEGRA_PIN_DAP1_DIN_PN1,
+};
+
+static const unsigned dap1_dout_pn2_pins[] = {
+	TEGRA_PIN_DAP1_DOUT_PN2,
+};
+
+static const unsigned dap1_sclk_pn3_pins[] = {
+	TEGRA_PIN_DAP1_SCLK_PN3,
+};
+
+static const unsigned lcd_cs0_n_pn4_pins[] = {
+	TEGRA_PIN_LCD_CS0_N_PN4,
+};
+
+static const unsigned lcd_sdout_pn5_pins[] = {
+	TEGRA_PIN_LCD_SDOUT_PN5,
+};
+
+static const unsigned lcd_dc0_pn6_pins[] = {
+	TEGRA_PIN_LCD_DC0_PN6,
+};
+
+static const unsigned hdmi_int_pn7_pins[] = {
+	TEGRA_PIN_HDMI_INT_PN7,
+};
+
+static const unsigned ulpi_data7_po0_pins[] = {
+	TEGRA_PIN_ULPI_DATA7_PO0,
+};
+
+static const unsigned ulpi_data0_po1_pins[] = {
+	TEGRA_PIN_ULPI_DATA0_PO1,
+};
+
+static const unsigned ulpi_data1_po2_pins[] = {
+	TEGRA_PIN_ULPI_DATA1_PO2,
+};
+
+static const unsigned ulpi_data2_po3_pins[] = {
+	TEGRA_PIN_ULPI_DATA2_PO3,
+};
+
+static const unsigned ulpi_data3_po4_pins[] = {
+	TEGRA_PIN_ULPI_DATA3_PO4,
+};
+
+static const unsigned ulpi_data4_po5_pins[] = {
+	TEGRA_PIN_ULPI_DATA4_PO5,
+};
+
+static const unsigned ulpi_data5_po6_pins[] = {
+	TEGRA_PIN_ULPI_DATA5_PO6,
+};
+
+static const unsigned ulpi_data6_po7_pins[] = {
+	TEGRA_PIN_ULPI_DATA6_PO7,
+};
+
+static const unsigned dap3_fs_pp0_pins[] = {
+	TEGRA_PIN_DAP3_FS_PP0,
+};
+
+static const unsigned dap3_din_pp1_pins[] = {
+	TEGRA_PIN_DAP3_DIN_PP1,
+};
+
+static const unsigned dap3_dout_pp2_pins[] = {
+	TEGRA_PIN_DAP3_DOUT_PP2,
+};
+
+static const unsigned dap3_sclk_pp3_pins[] = {
+	TEGRA_PIN_DAP3_SCLK_PP3,
+};
+
+static const unsigned dap4_fs_pp4_pins[] = {
+	TEGRA_PIN_DAP4_FS_PP4,
+};
+
+static const unsigned dap4_din_pp5_pins[] = {
+	TEGRA_PIN_DAP4_DIN_PP5,
+};
+
+static const unsigned dap4_dout_pp6_pins[] = {
+	TEGRA_PIN_DAP4_DOUT_PP6,
+};
+
+static const unsigned dap4_sclk_pp7_pins[] = {
+	TEGRA_PIN_DAP4_SCLK_PP7,
+};
+
+static const unsigned kb_col0_pq0_pins[] = {
+	TEGRA_PIN_KB_COL0_PQ0,
+};
+
+static const unsigned kb_col1_pq1_pins[] = {
+	TEGRA_PIN_KB_COL1_PQ1,
+};
+
+static const unsigned kb_col2_pq2_pins[] = {
+	TEGRA_PIN_KB_COL2_PQ2,
+};
+
+static const unsigned kb_col3_pq3_pins[] = {
+	TEGRA_PIN_KB_COL3_PQ3,
+};
+
+static const unsigned kb_col4_pq4_pins[] = {
+	TEGRA_PIN_KB_COL4_PQ4,
+};
+
+static const unsigned kb_col5_pq5_pins[] = {
+	TEGRA_PIN_KB_COL5_PQ5,
+};
+
+static const unsigned kb_col6_pq6_pins[] = {
+	TEGRA_PIN_KB_COL6_PQ6,
+};
+
+static const unsigned kb_col7_pq7_pins[] = {
+	TEGRA_PIN_KB_COL7_PQ7,
+};
+
+static const unsigned kb_row0_pr0_pins[] = {
+	TEGRA_PIN_KB_ROW0_PR0,
+};
+
+static const unsigned kb_row1_pr1_pins[] = {
+	TEGRA_PIN_KB_ROW1_PR1,
+};
+
+static const unsigned kb_row2_pr2_pins[] = {
+	TEGRA_PIN_KB_ROW2_PR2,
+};
+
+static const unsigned kb_row3_pr3_pins[] = {
+	TEGRA_PIN_KB_ROW3_PR3,
+};
+
+static const unsigned kb_row4_pr4_pins[] = {
+	TEGRA_PIN_KB_ROW4_PR4,
+};
+
+static const unsigned kb_row5_pr5_pins[] = {
+	TEGRA_PIN_KB_ROW5_PR5,
+};
+
+static const unsigned kb_row6_pr6_pins[] = {
+	TEGRA_PIN_KB_ROW6_PR6,
+};
+
+static const unsigned kb_row7_pr7_pins[] = {
+	TEGRA_PIN_KB_ROW7_PR7,
+};
+
+static const unsigned kb_row8_ps0_pins[] = {
+	TEGRA_PIN_KB_ROW8_PS0,
+};
+
+static const unsigned kb_row9_ps1_pins[] = {
+	TEGRA_PIN_KB_ROW9_PS1,
+};
+
+static const unsigned kb_row10_ps2_pins[] = {
+	TEGRA_PIN_KB_ROW10_PS2,
+};
+
+static const unsigned kb_row11_ps3_pins[] = {
+	TEGRA_PIN_KB_ROW11_PS3,
+};
+
+static const unsigned kb_row12_ps4_pins[] = {
+	TEGRA_PIN_KB_ROW12_PS4,
+};
+
+static const unsigned kb_row13_ps5_pins[] = {
+	TEGRA_PIN_KB_ROW13_PS5,
+};
+
+static const unsigned kb_row14_ps6_pins[] = {
+	TEGRA_PIN_KB_ROW14_PS6,
+};
+
+static const unsigned kb_row15_ps7_pins[] = {
+	TEGRA_PIN_KB_ROW15_PS7,
+};
+
+static const unsigned vi_pclk_pt0_pins[] = {
+	TEGRA_PIN_VI_PCLK_PT0,
+};
+
+static const unsigned vi_mclk_pt1_pins[] = {
+	TEGRA_PIN_VI_MCLK_PT1,
+};
+
+static const unsigned vi_d10_pt2_pins[] = {
+	TEGRA_PIN_VI_D10_PT2,
+};
+
+static const unsigned vi_d11_pt3_pins[] = {
+	TEGRA_PIN_VI_D11_PT3,
+};
+
+static const unsigned vi_d0_pt4_pins[] = {
+	TEGRA_PIN_VI_D0_PT4,
+};
+
+static const unsigned gen2_i2c_scl_pt5_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SCL_PT5,
+};
+
+static const unsigned gen2_i2c_sda_pt6_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SDA_PT6,
+};
+
+static const unsigned sdmmc4_cmd_pt7_pins[] = {
+	TEGRA_PIN_SDMMC4_CMD_PT7,
+};
+
+static const unsigned pu0_pins[] = {
+	TEGRA_PIN_PU0,
+};
+
+static const unsigned pu1_pins[] = {
+	TEGRA_PIN_PU1,
+};
+
+static const unsigned pu2_pins[] = {
+	TEGRA_PIN_PU2,
+};
+
+static const unsigned pu3_pins[] = {
+	TEGRA_PIN_PU3,
+};
+
+static const unsigned pu4_pins[] = {
+	TEGRA_PIN_PU4,
+};
+
+static const unsigned pu5_pins[] = {
+	TEGRA_PIN_PU5,
+};
+
+static const unsigned pu6_pins[] = {
+	TEGRA_PIN_PU6,
+};
+
+static const unsigned jtag_rtck_pu7_pins[] = {
+	TEGRA_PIN_JTAG_RTCK_PU7,
+};
+
+static const unsigned pv0_pins[] = {
+	TEGRA_PIN_PV0,
+};
+
+static const unsigned pv1_pins[] = {
+	TEGRA_PIN_PV1,
+};
+
+static const unsigned pv2_pins[] = {
+	TEGRA_PIN_PV2,
+};
+
+static const unsigned pv3_pins[] = {
+	TEGRA_PIN_PV3,
+};
+
+static const unsigned ddc_scl_pv4_pins[] = {
+	TEGRA_PIN_DDC_SCL_PV4,
+};
+
+static const unsigned ddc_sda_pv5_pins[] = {
+	TEGRA_PIN_DDC_SDA_PV5,
+};
+
+static const unsigned crt_hsync_pv6_pins[] = {
+	TEGRA_PIN_CRT_HSYNC_PV6,
+};
+
+static const unsigned crt_vsync_pv7_pins[] = {
+	TEGRA_PIN_CRT_VSYNC_PV7,
+};
+
+static const unsigned lcd_cs1_n_pw0_pins[] = {
+	TEGRA_PIN_LCD_CS1_N_PW0,
+};
+
+static const unsigned lcd_m1_pw1_pins[] = {
+	TEGRA_PIN_LCD_M1_PW1,
+};
+
+static const unsigned spi2_cs1_n_pw2_pins[] = {
+	TEGRA_PIN_SPI2_CS1_N_PW2,
+};
+
+static const unsigned spi2_cs2_n_pw3_pins[] = {
+	TEGRA_PIN_SPI2_CS2_N_PW3,
+};
+
+static const unsigned clk1_out_pw4_pins[] = {
+	TEGRA_PIN_CLK1_OUT_PW4,
+};
+
+static const unsigned clk2_out_pw5_pins[] = {
+	TEGRA_PIN_CLK2_OUT_PW5,
+};
+
+static const unsigned uart3_txd_pw6_pins[] = {
+	TEGRA_PIN_UART3_TXD_PW6,
+};
+
+static const unsigned uart3_rxd_pw7_pins[] = {
+	TEGRA_PIN_UART3_RXD_PW7,
+};
+
+static const unsigned spi2_mosi_px0_pins[] = {
+	TEGRA_PIN_SPI2_MOSI_PX0,
+};
+
+static const unsigned spi2_miso_px1_pins[] = {
+	TEGRA_PIN_SPI2_MISO_PX1,
+};
+
+static const unsigned spi2_sck_px2_pins[] = {
+	TEGRA_PIN_SPI2_SCK_PX2,
+};
+
+static const unsigned spi2_cs0_n_px3_pins[] = {
+	TEGRA_PIN_SPI2_CS0_N_PX3,
+};
+
+static const unsigned spi1_mosi_px4_pins[] = {
+	TEGRA_PIN_SPI1_MOSI_PX4,
+};
+
+static const unsigned spi1_sck_px5_pins[] = {
+	TEGRA_PIN_SPI1_SCK_PX5,
+};
+
+static const unsigned spi1_cs0_n_px6_pins[] = {
+	TEGRA_PIN_SPI1_CS0_N_PX6,
+};
+
+static const unsigned spi1_miso_px7_pins[] = {
+	TEGRA_PIN_SPI1_MISO_PX7,
+};
+
+static const unsigned ulpi_clk_py0_pins[] = {
+	TEGRA_PIN_ULPI_CLK_PY0,
+};
+
+static const unsigned ulpi_dir_py1_pins[] = {
+	TEGRA_PIN_ULPI_DIR_PY1,
+};
+
+static const unsigned ulpi_nxt_py2_pins[] = {
+	TEGRA_PIN_ULPI_NXT_PY2,
+};
+
+static const unsigned ulpi_stp_py3_pins[] = {
+	TEGRA_PIN_ULPI_STP_PY3,
+};
+
+static const unsigned sdmmc1_dat3_py4_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT3_PY4,
+};
+
+static const unsigned sdmmc1_dat2_py5_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT2_PY5,
+};
+
+static const unsigned sdmmc1_dat1_py6_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT1_PY6,
+};
+
+static const unsigned sdmmc1_dat0_py7_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT0_PY7,
+};
+
+static const unsigned sdmmc1_clk_pz0_pins[] = {
+	TEGRA_PIN_SDMMC1_CLK_PZ0,
+};
+
+static const unsigned sdmmc1_cmd_pz1_pins[] = {
+	TEGRA_PIN_SDMMC1_CMD_PZ1,
+};
+
+static const unsigned lcd_sdin_pz2_pins[] = {
+	TEGRA_PIN_LCD_SDIN_PZ2,
+};
+
+static const unsigned lcd_wr_n_pz3_pins[] = {
+	TEGRA_PIN_LCD_WR_N_PZ3,
+};
+
+static const unsigned lcd_sck_pz4_pins[] = {
+	TEGRA_PIN_LCD_SCK_PZ4,
+};
+
+static const unsigned sys_clk_req_pz5_pins[] = {
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+};
+
+static const unsigned pwr_i2c_scl_pz6_pins[] = {
+	TEGRA_PIN_PWR_I2C_SCL_PZ6,
+};
+
+static const unsigned pwr_i2c_sda_pz7_pins[] = {
+	TEGRA_PIN_PWR_I2C_SDA_PZ7,
+};
+
+static const unsigned sdmmc4_dat0_paa0_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT0_PAA0,
+};
+
+static const unsigned sdmmc4_dat1_paa1_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT1_PAA1,
+};
+
+static const unsigned sdmmc4_dat2_paa2_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT2_PAA2,
+};
+
+static const unsigned sdmmc4_dat3_paa3_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT3_PAA3,
+};
+
+static const unsigned sdmmc4_dat4_paa4_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT4_PAA4,
+};
+
+static const unsigned sdmmc4_dat5_paa5_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT5_PAA5,
+};
+
+static const unsigned sdmmc4_dat6_paa6_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT6_PAA6,
+};
+
+static const unsigned sdmmc4_dat7_paa7_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT7_PAA7,
+};
+
+static const unsigned pbb0_pins[] = {
+	TEGRA_PIN_PBB0,
+};
+
+static const unsigned cam_i2c_scl_pbb1_pins[] = {
+	TEGRA_PIN_CAM_I2C_SCL_PBB1,
+};
+
+static const unsigned cam_i2c_sda_pbb2_pins[] = {
+	TEGRA_PIN_CAM_I2C_SDA_PBB2,
+};
+
+static const unsigned pbb3_pins[] = {
+	TEGRA_PIN_PBB3,
+};
+
+static const unsigned pbb4_pins[] = {
+	TEGRA_PIN_PBB4,
+};
+
+static const unsigned pbb5_pins[] = {
+	TEGRA_PIN_PBB5,
+};
+
+static const unsigned pbb6_pins[] = {
+	TEGRA_PIN_PBB6,
+};
+
+static const unsigned pbb7_pins[] = {
+	TEGRA_PIN_PBB7,
+};
+
+static const unsigned cam_mclk_pcc0_pins[] = {
+	TEGRA_PIN_CAM_MCLK_PCC0,
+};
+
+static const unsigned pcc1_pins[] = {
+	TEGRA_PIN_PCC1,
+};
+
+static const unsigned pcc2_pins[] = {
+	TEGRA_PIN_PCC2,
+};
+
+static const unsigned sdmmc4_rst_n_pcc3_pins[] = {
+	TEGRA_PIN_SDMMC4_RST_N_PCC3,
+};
+
+static const unsigned sdmmc4_clk_pcc4_pins[] = {
+	TEGRA_PIN_SDMMC4_CLK_PCC4,
+};
+
+static const unsigned clk2_req_pcc5_pins[] = {
+	TEGRA_PIN_CLK2_REQ_PCC5,
+};
+
+static const unsigned pex_l2_rst_n_pcc6_pins[] = {
+	TEGRA_PIN_PEX_L2_RST_N_PCC6,
+};
+
+static const unsigned pex_l2_clkreq_n_pcc7_pins[] = {
+	TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7,
+};
+
+static const unsigned pex_l0_prsnt_n_pdd0_pins[] = {
+	TEGRA_PIN_PEX_L0_PRSNT_N_PDD0,
+};
+
+static const unsigned pex_l0_rst_n_pdd1_pins[] = {
+	TEGRA_PIN_PEX_L0_RST_N_PDD1,
+};
+
+static const unsigned pex_l0_clkreq_n_pdd2_pins[] = {
+	TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2,
+};
+
+static const unsigned pex_wake_n_pdd3_pins[] = {
+	TEGRA_PIN_PEX_WAKE_N_PDD3,
+};
+
+static const unsigned pex_l1_prsnt_n_pdd4_pins[] = {
+	TEGRA_PIN_PEX_L1_PRSNT_N_PDD4,
+};
+
+static const unsigned pex_l1_rst_n_pdd5_pins[] = {
+	TEGRA_PIN_PEX_L1_RST_N_PDD5,
+};
+
+static const unsigned pex_l1_clkreq_n_pdd6_pins[] = {
+	TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6,
+};
+
+static const unsigned pex_l2_prsnt_n_pdd7_pins[] = {
+	TEGRA_PIN_PEX_L2_PRSNT_N_PDD7,
+};
+
+static const unsigned clk3_out_pee0_pins[] = {
+	TEGRA_PIN_CLK3_OUT_PEE0,
+};
+
+static const unsigned clk3_req_pee1_pins[] = {
+	TEGRA_PIN_CLK3_REQ_PEE1,
+};
+
+static const unsigned clk1_req_pee2_pins[] = {
+	TEGRA_PIN_CLK1_REQ_PEE2,
+};
+
+static const unsigned hdmi_cec_pee3_pins[] = {
+	TEGRA_PIN_HDMI_CEC_PEE3,
+};
+
+static const unsigned clk_32k_in_pins[] = {
+	TEGRA_PIN_CLK_32K_IN,
+};
+
+static const unsigned core_pwr_req_pins[] = {
+	TEGRA_PIN_CORE_PWR_REQ,
+};
+
+static const unsigned cpu_pwr_req_pins[] = {
+	TEGRA_PIN_CPU_PWR_REQ,
+};
+
+static const unsigned owr_pins[] = {
+	TEGRA_PIN_OWR,
+};
+
+static const unsigned pwr_int_n_pins[] = {
+	TEGRA_PIN_PWR_INT_N,
+};
+
+static const unsigned drive_ao1_pins[] = {
+	TEGRA_PIN_KB_ROW0_PR0,
+	TEGRA_PIN_KB_ROW1_PR1,
+	TEGRA_PIN_KB_ROW2_PR2,
+	TEGRA_PIN_KB_ROW3_PR3,
+	TEGRA_PIN_KB_ROW4_PR4,
+	TEGRA_PIN_KB_ROW5_PR5,
+	TEGRA_PIN_KB_ROW6_PR6,
+	TEGRA_PIN_KB_ROW7_PR7,
+	TEGRA_PIN_PWR_I2C_SCL_PZ6,
+	TEGRA_PIN_PWR_I2C_SDA_PZ7,
+	TEGRA_PIN_SYS_RESET_N,
+};
+
+static const unsigned drive_ao2_pins[] = {
+	TEGRA_PIN_CLK_32K_OUT_PA0,
+	TEGRA_PIN_KB_COL0_PQ0,
+	TEGRA_PIN_KB_COL1_PQ1,
+	TEGRA_PIN_KB_COL2_PQ2,
+	TEGRA_PIN_KB_COL3_PQ3,
+	TEGRA_PIN_KB_COL4_PQ4,
+	TEGRA_PIN_KB_COL5_PQ5,
+	TEGRA_PIN_KB_COL6_PQ6,
+	TEGRA_PIN_KB_COL7_PQ7,
+	TEGRA_PIN_KB_ROW8_PS0,
+	TEGRA_PIN_KB_ROW9_PS1,
+	TEGRA_PIN_KB_ROW10_PS2,
+	TEGRA_PIN_KB_ROW11_PS3,
+	TEGRA_PIN_KB_ROW12_PS4,
+	TEGRA_PIN_KB_ROW13_PS5,
+	TEGRA_PIN_KB_ROW14_PS6,
+	TEGRA_PIN_KB_ROW15_PS7,
+	TEGRA_PIN_SYS_CLK_REQ_PZ5,
+	TEGRA_PIN_CLK_32K_IN,
+	TEGRA_PIN_CORE_PWR_REQ,
+	TEGRA_PIN_CPU_PWR_REQ,
+	TEGRA_PIN_PWR_INT_N,
+};
+
+static const unsigned drive_at1_pins[] = {
+	TEGRA_PIN_GMI_AD8_PH0,
+	TEGRA_PIN_GMI_AD9_PH1,
+	TEGRA_PIN_GMI_AD10_PH2,
+	TEGRA_PIN_GMI_AD11_PH3,
+	TEGRA_PIN_GMI_AD12_PH4,
+	TEGRA_PIN_GMI_AD13_PH5,
+	TEGRA_PIN_GMI_AD14_PH6,
+	TEGRA_PIN_GMI_AD15_PH7,
+	TEGRA_PIN_GMI_IORDY_PI5,
+	TEGRA_PIN_GMI_CS7_N_PI6,
+};
+
+static const unsigned drive_at2_pins[] = {
+	TEGRA_PIN_GMI_AD0_PG0,
+	TEGRA_PIN_GMI_AD1_PG1,
+	TEGRA_PIN_GMI_AD2_PG2,
+	TEGRA_PIN_GMI_AD3_PG3,
+	TEGRA_PIN_GMI_AD4_PG4,
+	TEGRA_PIN_GMI_AD5_PG5,
+	TEGRA_PIN_GMI_AD6_PG6,
+	TEGRA_PIN_GMI_AD7_PG7,
+	TEGRA_PIN_GMI_WR_N_PI0,
+	TEGRA_PIN_GMI_OE_N_PI1,
+	TEGRA_PIN_GMI_DQS_PI2,
+	TEGRA_PIN_GMI_CS6_N_PI3,
+	TEGRA_PIN_GMI_RST_N_PI4,
+	TEGRA_PIN_GMI_WAIT_PI7,
+	TEGRA_PIN_GMI_ADV_N_PK0,
+	TEGRA_PIN_GMI_CLK_PK1,
+	TEGRA_PIN_GMI_CS4_N_PK2,
+	TEGRA_PIN_GMI_CS2_N_PK3,
+	TEGRA_PIN_GMI_CS3_N_PK4,
+};
+
+static const unsigned drive_at3_pins[] = {
+	TEGRA_PIN_GMI_WP_N_PC7,
+	TEGRA_PIN_GMI_CS0_N_PJ0,
+};
+
+static const unsigned drive_at4_pins[] = {
+	TEGRA_PIN_GMI_A17_PB0,
+	TEGRA_PIN_GMI_A18_PB1,
+	TEGRA_PIN_GMI_CS1_N_PJ2,
+	TEGRA_PIN_GMI_A16_PJ7,
+	TEGRA_PIN_GMI_A19_PK7,
+};
+
+static const unsigned drive_at5_pins[] = {
+	TEGRA_PIN_GEN2_I2C_SCL_PT5,
+	TEGRA_PIN_GEN2_I2C_SDA_PT6,
+};
+
+static const unsigned drive_cdev1_pins[] = {
+	TEGRA_PIN_CLK1_OUT_PW4,
+	TEGRA_PIN_CLK1_REQ_PEE2,
+};
+
+static const unsigned drive_cdev2_pins[] = {
+	TEGRA_PIN_CLK2_OUT_PW5,
+	TEGRA_PIN_CLK2_REQ_PCC5,
+};
+
+static const unsigned drive_cec_pins[] = {
+	TEGRA_PIN_HDMI_CEC_PEE3,
+};
+
+static const unsigned drive_crt_pins[] = {
+	TEGRA_PIN_CRT_HSYNC_PV6,
+	TEGRA_PIN_CRT_VSYNC_PV7,
+};
+
+static const unsigned drive_csus_pins[] = {
+	TEGRA_PIN_VI_MCLK_PT1,
+};
+
+static const unsigned drive_dap1_pins[] = {
+	TEGRA_PIN_SPDIF_OUT_PK5,
+	TEGRA_PIN_SPDIF_IN_PK6,
+	TEGRA_PIN_DAP1_FS_PN0,
+	TEGRA_PIN_DAP1_DIN_PN1,
+	TEGRA_PIN_DAP1_DOUT_PN2,
+	TEGRA_PIN_DAP1_SCLK_PN3,
+};
+
+static const unsigned drive_dap2_pins[] = {
+	TEGRA_PIN_DAP2_FS_PA2,
+	TEGRA_PIN_DAP2_SCLK_PA3,
+	TEGRA_PIN_DAP2_DIN_PA4,
+	TEGRA_PIN_DAP2_DOUT_PA5,
+};
+
+static const unsigned drive_dap3_pins[] = {
+	TEGRA_PIN_DAP3_FS_PP0,
+	TEGRA_PIN_DAP3_DIN_PP1,
+	TEGRA_PIN_DAP3_DOUT_PP2,
+	TEGRA_PIN_DAP3_SCLK_PP3,
+};
+
+static const unsigned drive_dap4_pins[] = {
+	TEGRA_PIN_DAP4_FS_PP4,
+	TEGRA_PIN_DAP4_DIN_PP5,
+	TEGRA_PIN_DAP4_DOUT_PP6,
+	TEGRA_PIN_DAP4_SCLK_PP7,
+};
+
+static const unsigned drive_dbg_pins[] = {
+	TEGRA_PIN_GEN1_I2C_SCL_PC4,
+	TEGRA_PIN_GEN1_I2C_SDA_PC5,
+	TEGRA_PIN_PU0,
+	TEGRA_PIN_PU1,
+	TEGRA_PIN_PU2,
+	TEGRA_PIN_PU3,
+	TEGRA_PIN_PU4,
+	TEGRA_PIN_PU5,
+	TEGRA_PIN_PU6,
+	TEGRA_PIN_JTAG_RTCK_PU7,
+	TEGRA_PIN_JTAG_TCK,
+	TEGRA_PIN_JTAG_TDI,
+	TEGRA_PIN_JTAG_TDO,
+	TEGRA_PIN_JTAG_TMS,
+	TEGRA_PIN_JTAG_TRST_N,
+	TEGRA_PIN_TEST_MODE_EN,
+};
+
+static const unsigned drive_ddc_pins[] = {
+	TEGRA_PIN_DDC_SCL_PV4,
+	TEGRA_PIN_DDC_SDA_PV5,
+};
+
+static const unsigned drive_dev3_pins[] = {
+	TEGRA_PIN_CLK3_OUT_PEE0,
+	TEGRA_PIN_CLK3_REQ_PEE1,
+};
+
+static const unsigned drive_gma_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT0_PAA0,
+	TEGRA_PIN_SDMMC4_DAT1_PAA1,
+	TEGRA_PIN_SDMMC4_DAT2_PAA2,
+	TEGRA_PIN_SDMMC4_DAT3_PAA3,
+	TEGRA_PIN_SDMMC4_RST_N_PCC3,
+};
+
+static const unsigned drive_gmb_pins[] = {
+	TEGRA_PIN_SDMMC4_DAT4_PAA4,
+	TEGRA_PIN_SDMMC4_DAT5_PAA5,
+	TEGRA_PIN_SDMMC4_DAT6_PAA6,
+	TEGRA_PIN_SDMMC4_DAT7_PAA7,
+};
+
+static const unsigned drive_gmc_pins[] = {
+	TEGRA_PIN_SDMMC4_CLK_PCC4,
+};
+
+static const unsigned drive_gmd_pins[] = {
+	TEGRA_PIN_SDMMC4_CMD_PT7,
+};
+
+static const unsigned drive_gme_pins[] = {
+	TEGRA_PIN_PBB0,
+	TEGRA_PIN_CAM_I2C_SCL_PBB1,
+	TEGRA_PIN_CAM_I2C_SDA_PBB2,
+	TEGRA_PIN_PBB3,
+	TEGRA_PIN_PCC2,
+};
+
+static const unsigned drive_gmf_pins[] = {
+	TEGRA_PIN_PBB4,
+	TEGRA_PIN_PBB5,
+	TEGRA_PIN_PBB6,
+	TEGRA_PIN_PBB7,
+};
+
+static const unsigned drive_gmg_pins[] = {
+	TEGRA_PIN_CAM_MCLK_PCC0,
+};
+
+static const unsigned drive_gmh_pins[] = {
+	TEGRA_PIN_PCC1,
+};
+
+static const unsigned drive_gpv_pins[] = {
+	TEGRA_PIN_PEX_L2_RST_N_PCC6,
+	TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7,
+	TEGRA_PIN_PEX_L0_PRSNT_N_PDD0,
+	TEGRA_PIN_PEX_L0_RST_N_PDD1,
+	TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2,
+	TEGRA_PIN_PEX_WAKE_N_PDD3,
+	TEGRA_PIN_PEX_L1_PRSNT_N_PDD4,
+	TEGRA_PIN_PEX_L1_RST_N_PDD5,
+	TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6,
+	TEGRA_PIN_PEX_L2_PRSNT_N_PDD7,
+};
+
+static const unsigned drive_lcd1_pins[] = {
+	TEGRA_PIN_LCD_PWR1_PC1,
+	TEGRA_PIN_LCD_PWR2_PC6,
+	TEGRA_PIN_LCD_CS0_N_PN4,
+	TEGRA_PIN_LCD_SDOUT_PN5,
+	TEGRA_PIN_LCD_DC0_PN6,
+	TEGRA_PIN_LCD_SDIN_PZ2,
+	TEGRA_PIN_LCD_WR_N_PZ3,
+	TEGRA_PIN_LCD_SCK_PZ4,
+};
+
+static const unsigned drive_lcd2_pins[] = {
+	TEGRA_PIN_LCD_PWR0_PB2,
+	TEGRA_PIN_LCD_PCLK_PB3,
+	TEGRA_PIN_LCD_DC1_PD2,
+	TEGRA_PIN_LCD_D0_PE0,
+	TEGRA_PIN_LCD_D1_PE1,
+	TEGRA_PIN_LCD_D2_PE2,
+	TEGRA_PIN_LCD_D3_PE3,
+	TEGRA_PIN_LCD_D4_PE4,
+	TEGRA_PIN_LCD_D5_PE5,
+	TEGRA_PIN_LCD_D6_PE6,
+	TEGRA_PIN_LCD_D7_PE7,
+	TEGRA_PIN_LCD_D8_PF0,
+	TEGRA_PIN_LCD_D9_PF1,
+	TEGRA_PIN_LCD_D10_PF2,
+	TEGRA_PIN_LCD_D11_PF3,
+	TEGRA_PIN_LCD_D12_PF4,
+	TEGRA_PIN_LCD_D13_PF5,
+	TEGRA_PIN_LCD_D14_PF6,
+	TEGRA_PIN_LCD_D15_PF7,
+	TEGRA_PIN_LCD_DE_PJ1,
+	TEGRA_PIN_LCD_HSYNC_PJ3,
+	TEGRA_PIN_LCD_VSYNC_PJ4,
+	TEGRA_PIN_LCD_D16_PM0,
+	TEGRA_PIN_LCD_D17_PM1,
+	TEGRA_PIN_LCD_D18_PM2,
+	TEGRA_PIN_LCD_D19_PM3,
+	TEGRA_PIN_LCD_D20_PM4,
+	TEGRA_PIN_LCD_D21_PM5,
+	TEGRA_PIN_LCD_D22_PM6,
+	TEGRA_PIN_LCD_D23_PM7,
+	TEGRA_PIN_HDMI_INT_PN7,
+	TEGRA_PIN_LCD_CS1_N_PW0,
+	TEGRA_PIN_LCD_M1_PW1,
+};
+
+static const unsigned drive_owr_pins[] = {
+	TEGRA_PIN_OWR,
+};
+
+static const unsigned drive_sdio1_pins[] = {
+	TEGRA_PIN_SDMMC1_DAT3_PY4,
+	TEGRA_PIN_SDMMC1_DAT2_PY5,
+	TEGRA_PIN_SDMMC1_DAT1_PY6,
+	TEGRA_PIN_SDMMC1_DAT0_PY7,
+	TEGRA_PIN_SDMMC1_CLK_PZ0,
+	TEGRA_PIN_SDMMC1_CMD_PZ1,
+};
+
+static const unsigned drive_sdio2_pins[] = {
+	TEGRA_PIN_SDMMC3_DAT5_PD0,
+	TEGRA_PIN_SDMMC3_DAT4_PD1,
+	TEGRA_PIN_SDMMC3_DAT6_PD3,
+	TEGRA_PIN_SDMMC3_DAT7_PD4,
+};
+
+static const unsigned drive_sdio3_pins[] = {
+	TEGRA_PIN_SDMMC3_CLK_PA6,
+	TEGRA_PIN_SDMMC3_CMD_PA7,
+	TEGRA_PIN_SDMMC3_DAT3_PB4,
+	TEGRA_PIN_SDMMC3_DAT2_PB5,
+	TEGRA_PIN_SDMMC3_DAT1_PB6,
+	TEGRA_PIN_SDMMC3_DAT0_PB7,
+};
+
+static const unsigned drive_spi_pins[] = {
+	TEGRA_PIN_SPI2_CS1_N_PW2,
+	TEGRA_PIN_SPI2_CS2_N_PW3,
+	TEGRA_PIN_SPI2_MOSI_PX0,
+	TEGRA_PIN_SPI2_MISO_PX1,
+	TEGRA_PIN_SPI2_SCK_PX2,
+	TEGRA_PIN_SPI2_CS0_N_PX3,
+	TEGRA_PIN_SPI1_MOSI_PX4,
+	TEGRA_PIN_SPI1_SCK_PX5,
+	TEGRA_PIN_SPI1_CS0_N_PX6,
+	TEGRA_PIN_SPI1_MISO_PX7,
+};
+
+static const unsigned drive_uaa_pins[] = {
+	TEGRA_PIN_ULPI_DATA0_PO1,
+	TEGRA_PIN_ULPI_DATA1_PO2,
+	TEGRA_PIN_ULPI_DATA2_PO3,
+	TEGRA_PIN_ULPI_DATA3_PO4,
+};
+
+static const unsigned drive_uab_pins[] = {
+	TEGRA_PIN_ULPI_DATA7_PO0,
+	TEGRA_PIN_ULPI_DATA4_PO5,
+	TEGRA_PIN_ULPI_DATA5_PO6,
+	TEGRA_PIN_ULPI_DATA6_PO7,
+	TEGRA_PIN_PV0,
+	TEGRA_PIN_PV1,
+	TEGRA_PIN_PV2,
+	TEGRA_PIN_PV3,
+};
+
+static const unsigned drive_uart2_pins[] = {
+	TEGRA_PIN_UART2_TXD_PC2,
+	TEGRA_PIN_UART2_RXD_PC3,
+	TEGRA_PIN_UART2_CTS_N_PJ5,
+	TEGRA_PIN_UART2_RTS_N_PJ6,
+};
+
+static const unsigned drive_uart3_pins[] = {
+	TEGRA_PIN_UART3_CTS_N_PA1,
+	TEGRA_PIN_UART3_RTS_N_PC0,
+	TEGRA_PIN_UART3_TXD_PW6,
+	TEGRA_PIN_UART3_RXD_PW7,
+};
+
+static const unsigned drive_uda_pins[] = {
+	TEGRA_PIN_ULPI_CLK_PY0,
+	TEGRA_PIN_ULPI_DIR_PY1,
+	TEGRA_PIN_ULPI_NXT_PY2,
+	TEGRA_PIN_ULPI_STP_PY3,
+};
+
+static const unsigned drive_vi1_pins[] = {
+	TEGRA_PIN_VI_D1_PD5,
+	TEGRA_PIN_VI_VSYNC_PD6,
+	TEGRA_PIN_VI_HSYNC_PD7,
+	TEGRA_PIN_VI_D2_PL0,
+	TEGRA_PIN_VI_D3_PL1,
+	TEGRA_PIN_VI_D4_PL2,
+	TEGRA_PIN_VI_D5_PL3,
+	TEGRA_PIN_VI_D6_PL4,
+	TEGRA_PIN_VI_D7_PL5,
+	TEGRA_PIN_VI_D8_PL6,
+	TEGRA_PIN_VI_D9_PL7,
+	TEGRA_PIN_VI_PCLK_PT0,
+	TEGRA_PIN_VI_D10_PT2,
+	TEGRA_PIN_VI_D11_PT3,
+	TEGRA_PIN_VI_D0_PT4,
+};
+
+enum tegra_mux {
+	TEGRA_MUX_BLINK,
+	TEGRA_MUX_CEC,
+	TEGRA_MUX_CLK_12M_OUT,
+	TEGRA_MUX_CLK_32K_IN,
+	TEGRA_MUX_CORE_PWR_REQ,
+	TEGRA_MUX_CPU_PWR_REQ,
+	TEGRA_MUX_CRT,
+	TEGRA_MUX_DAP,
+	TEGRA_MUX_DDR,
+	TEGRA_MUX_DEV3,
+	TEGRA_MUX_DISPLAYA,
+	TEGRA_MUX_DISPLAYB,
+	TEGRA_MUX_DTV,
+	TEGRA_MUX_EXTPERIPH1,
+	TEGRA_MUX_EXTPERIPH2,
+	TEGRA_MUX_EXTPERIPH3,
+	TEGRA_MUX_GMI,
+	TEGRA_MUX_GMI_ALT,
+	TEGRA_MUX_HDA,
+	TEGRA_MUX_HDCP,
+	TEGRA_MUX_HDMI,
+	TEGRA_MUX_HSI,
+	TEGRA_MUX_I2C1,
+	TEGRA_MUX_I2C2,
+	TEGRA_MUX_I2C3,
+	TEGRA_MUX_I2C4,
+	TEGRA_MUX_I2CPWR,
+	TEGRA_MUX_I2S0,
+	TEGRA_MUX_I2S1,
+	TEGRA_MUX_I2S2,
+	TEGRA_MUX_I2S3,
+	TEGRA_MUX_I2S4,
+	TEGRA_MUX_INVALID,
+	TEGRA_MUX_KBC,
+	TEGRA_MUX_MIO,
+	TEGRA_MUX_NAND,
+	TEGRA_MUX_NAND_ALT,
+	TEGRA_MUX_OWR,
+	TEGRA_MUX_PCIE,
+	TEGRA_MUX_PWM0,
+	TEGRA_MUX_PWM1,
+	TEGRA_MUX_PWM2,
+	TEGRA_MUX_PWM3,
+	TEGRA_MUX_PWR_INT_N,
+	TEGRA_MUX_RSVD1,
+	TEGRA_MUX_RSVD2,
+	TEGRA_MUX_RSVD3,
+	TEGRA_MUX_RSVD4,
+	TEGRA_MUX_RTCK,
+	TEGRA_MUX_SATA,
+	TEGRA_MUX_SDMMC1,
+	TEGRA_MUX_SDMMC2,
+	TEGRA_MUX_SDMMC3,
+	TEGRA_MUX_SDMMC4,
+	TEGRA_MUX_SPDIF,
+	TEGRA_MUX_SPI1,
+	TEGRA_MUX_SPI2,
+	TEGRA_MUX_SPI2_ALT,
+	TEGRA_MUX_SPI3,
+	TEGRA_MUX_SPI4,
+	TEGRA_MUX_SPI5,
+	TEGRA_MUX_SPI6,
+	TEGRA_MUX_SYSCLK,
+	TEGRA_MUX_TEST,
+	TEGRA_MUX_TRACE,
+	TEGRA_MUX_UARTA,
+	TEGRA_MUX_UARTB,
+	TEGRA_MUX_UARTC,
+	TEGRA_MUX_UARTD,
+	TEGRA_MUX_UARTE,
+	TEGRA_MUX_ULPI,
+	TEGRA_MUX_VGP1,
+	TEGRA_MUX_VGP2,
+	TEGRA_MUX_VGP3,
+	TEGRA_MUX_VGP4,
+	TEGRA_MUX_VGP5,
+	TEGRA_MUX_VGP6,
+	TEGRA_MUX_VI,
+	TEGRA_MUX_VI_ALT1,
+	TEGRA_MUX_VI_ALT2,
+	TEGRA_MUX_VI_ALT3,
+};
+static const char * const blink_groups[] = {
+	"CLK_32K_OUT_PA0",
+};
+
+static const char * const cec_groups[] = {
+	"HDMI_CEC_PEE3",
+	"OWR",
+};
+
+static const char * const clk_12m_out_groups[] = {
+	"PV3",
+};
+
+static const char * const clk_32k_in_groups[] = {
+	"CLK_32K_IN",
+};
+
+static const char * const core_pwr_req_groups[] = {
+	"CORE_PWR_REQ",
+};
+
+static const char * const cpu_pwr_req_groups[] = {
+	"CPU_PWR_REQ",
+};
+
+static const char * const crt_groups[] = {
+	"CRT_HSYNC_PV6",
+	"CRT_VSYNC_PV7",
+};
+
+static const char * const dap_groups[] = {
+	"CLK1_REQ_PEE2",
+	"CLK2_REQ_PCC5",
+};
+
+static const char * const ddr_groups[] = {
+	"VI_D0_PT4",
+	"VI_D1_PD5",
+	"VI_D10_PT2",
+	"VI_D11_PT3",
+	"VI_D2_PL0",
+	"VI_D3_PL1",
+	"VI_D4_PL2",
+	"VI_D5_PL3",
+	"VI_D6_PL4",
+	"VI_D7_PL5",
+	"VI_D8_PL6",
+	"VI_D9_PL7",
+	"VI_HSYNC_PD7",
+	"VI_VSYNC_PD6",
+};
+
+static const char * const dev3_groups[] = {
+	"CLK3_REQ_PEE1",
+};
+
+static const char * const displaya_groups[] = {
+	"DAP3_DIN_PP1",
+	"DAP3_DOUT_PP2",
+	"DAP3_FS_PP0",
+	"DAP3_SCLK_PP3",
+	"PBB3",
+	"PBB4",
+	"PBB5",
+	"PBB6",
+	"LCD_CS0_N_PN4",
+	"LCD_CS1_N_PW0",
+	"LCD_D0_PE0",
+	"LCD_D1_PE1",
+	"LCD_D10_PF2",
+	"LCD_D11_PF3",
+	"LCD_D12_PF4",
+	"LCD_D13_PF5",
+	"LCD_D14_PF6",
+	"LCD_D15_PF7",
+	"LCD_D16_PM0",
+	"LCD_D17_PM1",
+	"LCD_D18_PM2",
+	"LCD_D19_PM3",
+	"LCD_D2_PE2",
+	"LCD_D20_PM4",
+	"LCD_D21_PM5",
+	"LCD_D22_PM6",
+	"LCD_D23_PM7",
+	"LCD_D3_PE3",
+	"LCD_D4_PE4",
+	"LCD_D5_PE5",
+	"LCD_D6_PE6",
+	"LCD_D7_PE7",
+	"LCD_D8_PF0",
+	"LCD_D9_PF1",
+	"LCD_DC0_PN6",
+	"LCD_DC1_PD2",
+	"LCD_DE_PJ1",
+	"LCD_HSYNC_PJ3",
+	"LCD_M1_PW1",
+	"LCD_PCLK_PB3",
+	"LCD_PWR0_PB2",
+	"LCD_PWR1_PC1",
+	"LCD_PWR2_PC6",
+	"LCD_SCK_PZ4",
+	"LCD_SDIN_PZ2",
+	"LCD_SDOUT_PN5",
+	"LCD_VSYNC_PJ4",
+	"LCD_WR_N_PZ3",
+};
+
+static const char * const displayb_groups[] = {
+	"DAP3_DIN_PP1",
+	"DAP3_DOUT_PP2",
+	"DAP3_FS_PP0",
+	"DAP3_SCLK_PP3",
+	"PBB3",
+	"PBB4",
+	"PBB5",
+	"PBB6",
+	"LCD_CS0_N_PN4",
+	"LCD_CS1_N_PW0",
+	"LCD_D0_PE0",
+	"LCD_D1_PE1",
+	"LCD_D10_PF2",
+	"LCD_D11_PF3",
+	"LCD_D12_PF4",
+	"LCD_D13_PF5",
+	"LCD_D14_PF6",
+	"LCD_D15_PF7",
+	"LCD_D16_PM0",
+	"LCD_D17_PM1",
+	"LCD_D18_PM2",
+	"LCD_D19_PM3",
+	"LCD_D2_PE2",
+	"LCD_D20_PM4",
+	"LCD_D21_PM5",
+	"LCD_D22_PM6",
+	"LCD_D23_PM7",
+	"LCD_D3_PE3",
+	"LCD_D4_PE4",
+	"LCD_D5_PE5",
+	"LCD_D6_PE6",
+	"LCD_D7_PE7",
+	"LCD_D8_PF0",
+	"LCD_D9_PF1",
+	"LCD_DC0_PN6",
+	"LCD_DC1_PD2",
+	"LCD_DE_PJ1",
+	"LCD_HSYNC_PJ3",
+	"LCD_M1_PW1",
+	"LCD_PCLK_PB3",
+	"LCD_PWR0_PB2",
+	"LCD_PWR1_PC1",
+	"LCD_PWR2_PC6",
+	"LCD_SCK_PZ4",
+	"LCD_SDIN_PZ2",
+	"LCD_SDOUT_PN5",
+	"LCD_VSYNC_PJ4",
+	"LCD_WR_N_PZ3",
+};
+
+static const char * const dtv_groups[] = {
+	"GMI_A17_PB0",
+	"GMI_A18_PB1",
+	"GMI_CS0_N_PJ0",
+	"GMI_CS1_N_PJ2",
+};
+
+static const char * const extperiph1_groups[] = {
+	"CLK1_OUT_PW4",
+};
+
+static const char * const extperiph2_groups[] = {
+	"CLK2_OUT_PW5",
+};
+
+static const char * const extperiph3_groups[] = {
+	"CLK3_OUT_PEE0",
+};
+
+static const char * const gmi_groups[] = {
+	"DAP1_DIN_PN1",
+	"DAP1_DOUT_PN2",
+	"DAP1_FS_PN0",
+	"DAP1_SCLK_PN3",
+	"DAP2_DIN_PA4",
+	"DAP2_DOUT_PA5",
+	"DAP2_FS_PA2",
+	"DAP2_SCLK_PA3",
+	"DAP4_DIN_PP5",
+	"DAP4_DOUT_PP6",
+	"DAP4_FS_PP4",
+	"DAP4_SCLK_PP7",
+	"GEN2_I2C_SCL_PT5",
+	"GEN2_I2C_SDA_PT6",
+	"GMI_A16_PJ7",
+	"GMI_A17_PB0",
+	"GMI_A18_PB1",
+	"GMI_A19_PK7",
+	"GMI_AD0_PG0",
+	"GMI_AD1_PG1",
+	"GMI_AD10_PH2",
+	"GMI_AD11_PH3",
+	"GMI_AD12_PH4",
+	"GMI_AD13_PH5",
+	"GMI_AD14_PH6",
+	"GMI_AD15_PH7",
+	"GMI_AD2_PG2",
+	"GMI_AD3_PG3",
+	"GMI_AD4_PG4",
+	"GMI_AD5_PG5",
+	"GMI_AD6_PG6",
+	"GMI_AD7_PG7",
+	"GMI_AD8_PH0",
+	"GMI_AD9_PH1",
+	"GMI_ADV_N_PK0",
+	"GMI_CLK_PK1",
+	"GMI_CS0_N_PJ0",
+	"GMI_CS1_N_PJ2",
+	"GMI_CS2_N_PK3",
+	"GMI_CS3_N_PK4",
+	"GMI_CS4_N_PK2",
+	"GMI_CS6_N_PI3",
+	"GMI_CS7_N_PI6",
+	"GMI_DQS_PI2",
+	"GMI_IORDY_PI5",
+	"GMI_OE_N_PI1",
+	"GMI_RST_N_PI4",
+	"GMI_WAIT_PI7",
+	"GMI_WP_N_PC7",
+	"GMI_WR_N_PI0",
+	"PU0",
+	"PU1",
+	"PU2",
+	"PU3",
+	"PU4",
+	"PU5",
+	"PU6",
+	"SDMMC4_CLK_PCC4",
+	"SDMMC4_CMD_PT7",
+	"SDMMC4_DAT0_PAA0",
+	"SDMMC4_DAT1_PAA1",
+	"SDMMC4_DAT2_PAA2",
+	"SDMMC4_DAT3_PAA3",
+	"SDMMC4_DAT4_PAA4",
+	"SDMMC4_DAT5_PAA5",
+	"SDMMC4_DAT6_PAA6",
+	"SDMMC4_DAT7_PAA7",
+	"SPI1_CS0_N_PX6",
+	"SPI1_MOSI_PX4",
+	"SPI1_SCK_PX5",
+	"SPI2_CS0_N_PX3",
+	"SPI2_MISO_PX1",
+	"SPI2_MOSI_PX0",
+	"SPI2_SCK_PX2",
+	"UART2_CTS_N_PJ5",
+	"UART2_RTS_N_PJ6",
+	"UART3_CTS_N_PA1",
+	"UART3_RTS_N_PC0",
+	"UART3_RXD_PW7",
+	"UART3_TXD_PW6",
+};
+
+static const char * const gmi_alt_groups[] = {
+	"GMI_A16_PJ7",
+	"GMI_CS3_N_PK4",
+	"GMI_CS7_N_PI6",
+	"GMI_WP_N_PC7",
+};
+
+static const char * const hda_groups[] = {
+	"CLK1_REQ_PEE2",
+	"DAP1_DIN_PN1",
+	"DAP1_DOUT_PN2",
+	"DAP1_FS_PN0",
+	"DAP1_SCLK_PN3",
+	"DAP2_DIN_PA4",
+	"DAP2_DOUT_PA5",
+	"DAP2_FS_PA2",
+	"DAP2_SCLK_PA3",
+	"PEX_L0_CLKREQ_N_PDD2",
+	"PEX_L0_PRSNT_N_PDD0",
+	"PEX_L0_RST_N_PDD1",
+	"PEX_L1_CLKREQ_N_PDD6",
+	"PEX_L1_PRSNT_N_PDD4",
+	"PEX_L1_RST_N_PDD5",
+	"PEX_L2_CLKREQ_N_PCC7",
+	"PEX_L2_PRSNT_N_PDD7",
+	"PEX_L2_RST_N_PCC6",
+	"PEX_WAKE_N_PDD3",
+	"SPDIF_IN_PK6",
+};
+
+static const char * const hdcp_groups[] = {
+	"GEN2_I2C_SCL_PT5",
+	"GEN2_I2C_SDA_PT6",
+	"LCD_PWR0_PB2",
+	"LCD_PWR2_PC6",
+	"LCD_SCK_PZ4",
+	"LCD_SDOUT_PN5",
+	"LCD_WR_N_PZ3",
+};
+
+static const char * const hdmi_groups[] = {
+	"HDMI_INT_PN7",
+};
+
+static const char * const hsi_groups[] = {
+	"ULPI_DATA0_PO1",
+	"ULPI_DATA1_PO2",
+	"ULPI_DATA2_PO3",
+	"ULPI_DATA3_PO4",
+	"ULPI_DATA4_PO5",
+	"ULPI_DATA5_PO6",
+	"ULPI_DATA6_PO7",
+	"ULPI_DATA7_PO0",
+};
+
+static const char * const i2c1_groups[] = {
+	"GEN1_I2C_SCL_PC4",
+	"GEN1_I2C_SDA_PC5",
+	"SPDIF_IN_PK6",
+	"SPDIF_OUT_PK5",
+	"SPI2_CS1_N_PW2",
+	"SPI2_CS2_N_PW3",
+};
+
+static const char * const i2c2_groups[] = {
+	"GEN2_I2C_SCL_PT5",
+	"GEN2_I2C_SDA_PT6",
+};
+
+static const char * const i2c3_groups[] = {
+	"CAM_I2C_SCL_PBB1",
+	"CAM_I2C_SDA_PBB2",
+	"SDMMC4_CMD_PT7",
+	"SDMMC4_DAT4_PAA4",
+};
+
+static const char * const i2c4_groups[] = {
+	"DDC_SCL_PV4",
+	"DDC_SDA_PV5",
+};
+
+static const char * const i2cpwr_groups[] = {
+	"PWR_I2C_SCL_PZ6",
+	"PWR_I2C_SDA_PZ7",
+};
+
+static const char * const i2s0_groups[] = {
+	"DAP1_DIN_PN1",
+	"DAP1_DOUT_PN2",
+	"DAP1_FS_PN0",
+	"DAP1_SCLK_PN3",
+};
+
+static const char * const i2s1_groups[] = {
+	"DAP2_DIN_PA4",
+	"DAP2_DOUT_PA5",
+	"DAP2_FS_PA2",
+	"DAP2_SCLK_PA3",
+};
+
+static const char * const i2s2_groups[] = {
+	"DAP3_DIN_PP1",
+	"DAP3_DOUT_PP2",
+	"DAP3_FS_PP0",
+	"DAP3_SCLK_PP3",
+};
+
+static const char * const i2s3_groups[] = {
+	"DAP4_DIN_PP5",
+	"DAP4_DOUT_PP6",
+	"DAP4_FS_PP4",
+	"DAP4_SCLK_PP7",
+};
+
+static const char * const i2s4_groups[] = {
+	"PBB0",
+	"PBB7",
+	"PCC1",
+	"PCC2",
+	"SDMMC4_DAT4_PAA4",
+	"SDMMC4_DAT5_PAA5",
+	"SDMMC4_DAT6_PAA6",
+	"SDMMC4_DAT7_PAA7",
+};
+
+static const char * const invalid_groups[] = {
+	"KB_ROW3_PR3",
+	"SDMMC4_CLK_PCC4",
+};
+
+static const char * const kbc_groups[] = {
+	"KB_COL0_PQ0",
+	"KB_COL1_PQ1",
+	"KB_COL2_PQ2",
+	"KB_COL3_PQ3",
+	"KB_COL4_PQ4",
+	"KB_COL5_PQ5",
+	"KB_COL6_PQ6",
+	"KB_COL7_PQ7",
+	"KB_ROW0_PR0",
+	"KB_ROW1_PR1",
+	"KB_ROW10_PS2",
+	"KB_ROW11_PS3",
+	"KB_ROW12_PS4",
+	"KB_ROW13_PS5",
+	"KB_ROW14_PS6",
+	"KB_ROW15_PS7",
+	"KB_ROW2_PR2",
+	"KB_ROW3_PR3",
+	"KB_ROW4_PR4",
+	"KB_ROW5_PR5",
+	"KB_ROW6_PR6",
+	"KB_ROW7_PR7",
+	"KB_ROW8_PS0",
+	"KB_ROW9_PS1",
+};
+
+static const char * const mio_groups[] = {
+	"KB_COL6_PQ6",
+	"KB_COL7_PQ7",
+	"KB_ROW10_PS2",
+	"KB_ROW11_PS3",
+	"KB_ROW12_PS4",
+	"KB_ROW13_PS5",
+	"KB_ROW14_PS6",
+	"KB_ROW15_PS7",
+	"KB_ROW6_PR6",
+	"KB_ROW7_PR7",
+	"KB_ROW8_PS0",
+	"KB_ROW9_PS1",
+};
+
+static const char * const nand_groups[] = {
+	"GMI_AD0_PG0",
+	"GMI_AD1_PG1",
+	"GMI_AD10_PH2",
+	"GMI_AD11_PH3",
+	"GMI_AD12_PH4",
+	"GMI_AD13_PH5",
+	"GMI_AD14_PH6",
+	"GMI_AD15_PH7",
+	"GMI_AD2_PG2",
+	"GMI_AD3_PG3",
+	"GMI_AD4_PG4",
+	"GMI_AD5_PG5",
+	"GMI_AD6_PG6",
+	"GMI_AD7_PG7",
+	"GMI_AD8_PH0",
+	"GMI_AD9_PH1",
+	"GMI_ADV_N_PK0",
+	"GMI_CLK_PK1",
+	"GMI_CS0_N_PJ0",
+	"GMI_CS1_N_PJ2",
+	"GMI_CS2_N_PK3",
+	"GMI_CS3_N_PK4",
+	"GMI_CS4_N_PK2",
+	"GMI_CS6_N_PI3",
+	"GMI_CS7_N_PI6",
+	"GMI_DQS_PI2",
+	"GMI_IORDY_PI5",
+	"GMI_OE_N_PI1",
+	"GMI_RST_N_PI4",
+	"GMI_WAIT_PI7",
+	"GMI_WP_N_PC7",
+	"GMI_WR_N_PI0",
+	"KB_COL0_PQ0",
+	"KB_COL1_PQ1",
+	"KB_COL2_PQ2",
+	"KB_COL3_PQ3",
+	"KB_COL4_PQ4",
+	"KB_COL5_PQ5",
+	"KB_COL6_PQ6",
+	"KB_COL7_PQ7",
+	"KB_ROW0_PR0",
+	"KB_ROW1_PR1",
+	"KB_ROW10_PS2",
+	"KB_ROW11_PS3",
+	"KB_ROW12_PS4",
+	"KB_ROW13_PS5",
+	"KB_ROW14_PS6",
+	"KB_ROW15_PS7",
+	"KB_ROW2_PR2",
+	"KB_ROW3_PR3",
+	"KB_ROW4_PR4",
+	"KB_ROW5_PR5",
+	"KB_ROW6_PR6",
+	"KB_ROW7_PR7",
+	"KB_ROW8_PS0",
+	"KB_ROW9_PS1",
+	"SDMMC4_CLK_PCC4",
+	"SDMMC4_CMD_PT7",
+};
+
+static const char * const nand_alt_groups[] = {
+	"GMI_CS6_N_PI3",
+	"GMI_CS7_N_PI6",
+	"GMI_RST_N_PI4",
+};
+
+static const char * const owr_groups[] = {
+	"PU0",
+	"PV2",
+	"KB_ROW5_PR5",
+	"OWR",
+};
+
+static const char * const pcie_groups[] = {
+	"PEX_L0_CLKREQ_N_PDD2",
+	"PEX_L0_PRSNT_N_PDD0",
+	"PEX_L0_RST_N_PDD1",
+	"PEX_L1_CLKREQ_N_PDD6",
+	"PEX_L1_PRSNT_N_PDD4",
+	"PEX_L1_RST_N_PDD5",
+	"PEX_L2_CLKREQ_N_PCC7",
+	"PEX_L2_PRSNT_N_PDD7",
+	"PEX_L2_RST_N_PCC6",
+	"PEX_WAKE_N_PDD3",
+};
+
+static const char * const pwm0_groups[] = {
+	"GMI_AD8_PH0",
+	"PU3",
+	"SDMMC3_DAT3_PB4",
+	"SDMMC3_DAT5_PD0",
+	"UART3_RTS_N_PC0",
+};
+
+static const char * const pwm1_groups[] = {
+	"GMI_AD9_PH1",
+	"PU4",
+	"SDMMC3_DAT2_PB5",
+	"SDMMC3_DAT4_PD1",
+};
+
+static const char * const pwm2_groups[] = {
+	"GMI_AD10_PH2",
+	"PU5",
+	"SDMMC3_CLK_PA6",
+};
+
+static const char * const pwm3_groups[] = {
+	"GMI_AD11_PH3",
+	"PU6",
+	"SDMMC3_CMD_PA7",
+};
+
+static const char * const pwr_int_n_groups[] = {
+	"PWR_INT_N",
+};
+
+static const char * const rsvd1_groups[] = {
+	"GMI_AD0_PG0",
+	"GMI_AD1_PG1",
+	"GMI_AD12_PH4",
+	"GMI_AD13_PH5",
+	"GMI_AD14_PH6",
+	"GMI_AD15_PH7",
+	"GMI_AD2_PG2",
+	"GMI_AD3_PG3",
+	"GMI_AD4_PG4",
+	"GMI_AD5_PG5",
+	"GMI_AD6_PG6",
+	"GMI_AD7_PG7",
+	"GMI_ADV_N_PK0",
+	"GMI_CLK_PK1",
+	"GMI_CS0_N_PJ0",
+	"GMI_CS1_N_PJ2",
+	"GMI_CS2_N_PK3",
+	"GMI_CS3_N_PK4",
+	"GMI_CS4_N_PK2",
+	"GMI_DQS_PI2",
+	"GMI_IORDY_PI5",
+	"GMI_OE_N_PI1",
+	"GMI_WAIT_PI7",
+	"GMI_WP_N_PC7",
+	"GMI_WR_N_PI0",
+	"PU1",
+	"PU2",
+	"PV0",
+	"PV1",
+	"SDMMC3_DAT0_PB7",
+	"SDMMC3_DAT1_PB6",
+	"SDMMC3_DAT2_PB5",
+	"SDMMC3_DAT3_PB4",
+	"VI_PCLK_PT0",
+};
+
+static const char * const rsvd2_groups[] = {
+	"CLK1_OUT_PW4",
+	"CLK2_OUT_PW5",
+	"CLK2_REQ_PCC5",
+	"CLK3_OUT_PEE0",
+	"CLK3_REQ_PEE1",
+	"CLK_32K_IN",
+	"CLK_32K_OUT_PA0",
+	"CORE_PWR_REQ",
+	"CPU_PWR_REQ",
+	"CRT_HSYNC_PV6",
+	"CRT_VSYNC_PV7",
+	"DAP3_DIN_PP1",
+	"DAP3_DOUT_PP2",
+	"DAP3_FS_PP0",
+	"DAP3_SCLK_PP3",
+	"DAP4_DIN_PP5",
+	"DAP4_DOUT_PP6",
+	"DAP4_FS_PP4",
+	"DAP4_SCLK_PP7",
+	"DDC_SCL_PV4",
+	"DDC_SDA_PV5",
+	"GEN1_I2C_SCL_PC4",
+	"GEN1_I2C_SDA_PC5",
+	"PBB0",
+	"PBB7",
+	"PCC1",
+	"PCC2",
+	"PV0",
+	"PV1",
+	"PV2",
+	"PV3",
+	"HDMI_CEC_PEE3",
+	"HDMI_INT_PN7",
+	"JTAG_RTCK_PU7",
+	"PWR_I2C_SCL_PZ6",
+	"PWR_I2C_SDA_PZ7",
+	"PWR_INT_N",
+	"SDMMC1_CLK_PZ0",
+	"SDMMC1_CMD_PZ1",
+	"SDMMC1_DAT0_PY7",
+	"SDMMC1_DAT1_PY6",
+	"SDMMC1_DAT2_PY5",
+	"SDMMC1_DAT3_PY4",
+	"SDMMC3_DAT0_PB7",
+	"SDMMC3_DAT1_PB6",
+	"SDMMC4_RST_N_PCC3",
+	"SPDIF_OUT_PK5",
+	"SYS_CLK_REQ_PZ5",
+	"UART3_CTS_N_PA1",
+	"UART3_RXD_PW7",
+	"UART3_TXD_PW6",
+	"ULPI_CLK_PY0",
+	"ULPI_DIR_PY1",
+	"ULPI_NXT_PY2",
+	"ULPI_STP_PY3",
+	"VI_D0_PT4",
+	"VI_D10_PT2",
+	"VI_D11_PT3",
+	"VI_HSYNC_PD7",
+	"VI_VSYNC_PD6",
+};
+
+static const char * const rsvd3_groups[] = {
+	"CAM_I2C_SCL_PBB1",
+	"CAM_I2C_SDA_PBB2",
+	"CLK1_OUT_PW4",
+	"CLK1_REQ_PEE2",
+	"CLK2_OUT_PW5",
+	"CLK2_REQ_PCC5",
+	"CLK3_OUT_PEE0",
+	"CLK3_REQ_PEE1",
+	"CLK_32K_IN",
+	"CLK_32K_OUT_PA0",
+	"CORE_PWR_REQ",
+	"CPU_PWR_REQ",
+	"CRT_HSYNC_PV6",
+	"CRT_VSYNC_PV7",
+	"DAP2_DIN_PA4",
+	"DAP2_DOUT_PA5",
+	"DAP2_FS_PA2",
+	"DAP2_SCLK_PA3",
+	"DDC_SCL_PV4",
+	"DDC_SDA_PV5",
+	"GEN1_I2C_SCL_PC4",
+	"GEN1_I2C_SDA_PC5",
+	"PBB0",
+	"PBB7",
+	"PCC1",
+	"PCC2",
+	"PV0",
+	"PV1",
+	"PV2",
+	"PV3",
+	"HDMI_CEC_PEE3",
+	"HDMI_INT_PN7",
+	"JTAG_RTCK_PU7",
+	"KB_ROW0_PR0",
+	"KB_ROW1_PR1",
+	"KB_ROW2_PR2",
+	"KB_ROW3_PR3",
+	"LCD_D0_PE0",
+	"LCD_D1_PE1",
+	"LCD_D10_PF2",
+	"LCD_D11_PF3",
+	"LCD_D12_PF4",
+	"LCD_D13_PF5",
+	"LCD_D14_PF6",
+	"LCD_D15_PF7",
+	"LCD_D16_PM0",
+	"LCD_D17_PM1",
+	"LCD_D18_PM2",
+	"LCD_D19_PM3",
+	"LCD_D2_PE2",
+	"LCD_D20_PM4",
+	"LCD_D21_PM5",
+	"LCD_D22_PM6",
+	"LCD_D23_PM7",
+	"LCD_D3_PE3",
+	"LCD_D4_PE4",
+	"LCD_D5_PE5",
+	"LCD_D6_PE6",
+	"LCD_D7_PE7",
+	"LCD_D8_PF0",
+	"LCD_D9_PF1",
+	"LCD_DC0_PN6",
+	"LCD_DC1_PD2",
+	"LCD_DE_PJ1",
+	"LCD_HSYNC_PJ3",
+	"LCD_M1_PW1",
+	"LCD_PCLK_PB3",
+	"LCD_PWR1_PC1",
+	"LCD_VSYNC_PJ4",
+	"OWR",
+	"PEX_L0_CLKREQ_N_PDD2",
+	"PEX_L0_PRSNT_N_PDD0",
+	"PEX_L0_RST_N_PDD1",
+	"PEX_L1_CLKREQ_N_PDD6",
+	"PEX_L1_PRSNT_N_PDD4",
+	"PEX_L1_RST_N_PDD5",
+	"PEX_L2_CLKREQ_N_PCC7",
+	"PEX_L2_PRSNT_N_PDD7",
+	"PEX_L2_RST_N_PCC6",
+	"PEX_WAKE_N_PDD3",
+	"PWR_I2C_SCL_PZ6",
+	"PWR_I2C_SDA_PZ7",
+	"PWR_INT_N",
+	"SDMMC1_CLK_PZ0",
+	"SDMMC1_CMD_PZ1",
+	"SDMMC4_RST_N_PCC3",
+	"SYS_CLK_REQ_PZ5",
+};
+
+static const char * const rsvd4_groups[] = {
+	"CLK1_OUT_PW4",
+	"CLK1_REQ_PEE2",
+	"CLK2_OUT_PW5",
+	"CLK2_REQ_PCC5",
+	"CLK3_OUT_PEE0",
+	"CLK3_REQ_PEE1",
+	"CLK_32K_IN",
+	"CLK_32K_OUT_PA0",
+	"CORE_PWR_REQ",
+	"CPU_PWR_REQ",
+	"CRT_HSYNC_PV6",
+	"CRT_VSYNC_PV7",
+	"DAP4_DIN_PP5",
+	"DAP4_DOUT_PP6",
+	"DAP4_FS_PP4",
+	"DAP4_SCLK_PP7",
+	"DDC_SCL_PV4",
+	"DDC_SDA_PV5",
+	"GEN1_I2C_SCL_PC4",
+	"GEN1_I2C_SDA_PC5",
+	"GEN2_I2C_SCL_PT5",
+	"GEN2_I2C_SDA_PT6",
+	"GMI_A19_PK7",
+	"GMI_AD0_PG0",
+	"GMI_AD1_PG1",
+	"GMI_AD10_PH2",
+	"GMI_AD11_PH3",
+	"GMI_AD12_PH4",
+	"GMI_AD13_PH5",
+	"GMI_AD14_PH6",
+	"GMI_AD15_PH7",
+	"GMI_AD2_PG2",
+	"GMI_AD3_PG3",
+	"GMI_AD4_PG4",
+	"GMI_AD5_PG5",
+	"GMI_AD6_PG6",
+	"GMI_AD7_PG7",
+	"GMI_AD8_PH0",
+	"GMI_AD9_PH1",
+	"GMI_ADV_N_PK0",
+	"GMI_CLK_PK1",
+	"GMI_CS2_N_PK3",
+	"GMI_CS4_N_PK2",
+	"GMI_DQS_PI2",
+	"GMI_IORDY_PI5",
+	"GMI_OE_N_PI1",
+	"GMI_RST_N_PI4",
+	"GMI_WAIT_PI7",
+	"GMI_WR_N_PI0",
+	"PCC2",
+	"PU0",
+	"PU1",
+	"PU2",
+	"PU3",
+	"PU4",
+	"PU5",
+	"PU6",
+	"PV0",
+	"PV1",
+	"PV2",
+	"PV3",
+	"HDMI_CEC_PEE3",
+	"HDMI_INT_PN7",
+	"JTAG_RTCK_PU7",
+	"KB_COL2_PQ2",
+	"KB_COL3_PQ3",
+	"KB_COL4_PQ4",
+	"KB_COL5_PQ5",
+	"KB_ROW0_PR0",
+	"KB_ROW1_PR1",
+	"KB_ROW2_PR2",
+	"KB_ROW4_PR4",
+	"LCD_CS0_N_PN4",
+	"LCD_CS1_N_PW0",
+	"LCD_D0_PE0",
+	"LCD_D1_PE1",
+	"LCD_D10_PF2",
+	"LCD_D11_PF3",
+	"LCD_D12_PF4",
+	"LCD_D13_PF5",
+	"LCD_D14_PF6",
+	"LCD_D15_PF7",
+	"LCD_D16_PM0",
+	"LCD_D17_PM1",
+	"LCD_D18_PM2",
+	"LCD_D19_PM3",
+	"LCD_D2_PE2",
+	"LCD_D20_PM4",
+	"LCD_D21_PM5",
+	"LCD_D22_PM6",
+	"LCD_D23_PM7",
+	"LCD_D3_PE3",
+	"LCD_D4_PE4",
+	"LCD_D5_PE5",
+	"LCD_D6_PE6",
+	"LCD_D7_PE7",
+	"LCD_D8_PF0",
+	"LCD_D9_PF1",
+	"LCD_DC0_PN6",
+	"LCD_DC1_PD2",
+	"LCD_DE_PJ1",
+	"LCD_HSYNC_PJ3",
+	"LCD_M1_PW1",
+	"LCD_PCLK_PB3",
+	"LCD_PWR1_PC1",
+	"LCD_SDIN_PZ2",
+	"LCD_VSYNC_PJ4",
+	"OWR",
+	"PEX_L0_CLKREQ_N_PDD2",
+	"PEX_L0_PRSNT_N_PDD0",
+	"PEX_L0_RST_N_PDD1",
+	"PEX_L1_CLKREQ_N_PDD6",
+	"PEX_L1_PRSNT_N_PDD4",
+	"PEX_L1_RST_N_PDD5",
+	"PEX_L2_CLKREQ_N_PCC7",
+	"PEX_L2_PRSNT_N_PDD7",
+	"PEX_L2_RST_N_PCC6",
+	"PEX_WAKE_N_PDD3",
+	"PWR_I2C_SCL_PZ6",
+	"PWR_I2C_SDA_PZ7",
+	"PWR_INT_N",
+	"SPI1_MISO_PX7",
+	"SYS_CLK_REQ_PZ5",
+	"UART3_CTS_N_PA1",
+	"UART3_RTS_N_PC0",
+	"UART3_RXD_PW7",
+	"UART3_TXD_PW6",
+	"VI_D0_PT4",
+	"VI_D1_PD5",
+	"VI_D10_PT2",
+	"VI_D11_PT3",
+	"VI_D2_PL0",
+	"VI_D3_PL1",
+	"VI_D4_PL2",
+	"VI_D5_PL3",
+	"VI_D6_PL4",
+	"VI_D7_PL5",
+	"VI_D8_PL6",
+	"VI_D9_PL7",
+	"VI_HSYNC_PD7",
+	"VI_PCLK_PT0",
+	"VI_VSYNC_PD6",
+};
+
+static const char * const rtck_groups[] = {
+	"JTAG_RTCK_PU7",
+};
+
+static const char * const sata_groups[] = {
+	"GMI_CS6_N_PI3",
+};
+
+static const char * const sdmmc1_groups[] = {
+	"SDMMC1_CLK_PZ0",
+	"SDMMC1_CMD_PZ1",
+	"SDMMC1_DAT0_PY7",
+	"SDMMC1_DAT1_PY6",
+	"SDMMC1_DAT2_PY5",
+	"SDMMC1_DAT3_PY4",
+};
+
+static const char * const sdmmc2_groups[] = {
+	"DAP1_DIN_PN1",
+	"DAP1_DOUT_PN2",
+	"DAP1_FS_PN0",
+	"DAP1_SCLK_PN3",
+	"KB_ROW10_PS2",
+	"KB_ROW11_PS3",
+	"KB_ROW12_PS4",
+	"KB_ROW13_PS5",
+	"KB_ROW14_PS6",
+	"KB_ROW15_PS7",
+	"KB_ROW6_PR6",
+	"KB_ROW7_PR7",
+	"KB_ROW8_PS0",
+	"KB_ROW9_PS1",
+	"SPDIF_IN_PK6",
+	"SPDIF_OUT_PK5",
+	"VI_D1_PD5",
+	"VI_D2_PL0",
+	"VI_D3_PL1",
+	"VI_D4_PL2",
+	"VI_D5_PL3",
+	"VI_D6_PL4",
+	"VI_D7_PL5",
+	"VI_D8_PL6",
+	"VI_D9_PL7",
+	"VI_PCLK_PT0",
+};
+
+static const char * const sdmmc3_groups[] = {
+	"SDMMC3_CLK_PA6",
+	"SDMMC3_CMD_PA7",
+	"SDMMC3_DAT0_PB7",
+	"SDMMC3_DAT1_PB6",
+	"SDMMC3_DAT2_PB5",
+	"SDMMC3_DAT3_PB4",
+	"SDMMC3_DAT4_PD1",
+	"SDMMC3_DAT5_PD0",
+	"SDMMC3_DAT6_PD3",
+	"SDMMC3_DAT7_PD4",
+};
+
+static const char * const sdmmc4_groups[] = {
+	"CAM_I2C_SCL_PBB1",
+	"CAM_I2C_SDA_PBB2",
+	"CAM_MCLK_PCC0",
+	"PBB0",
+	"PBB3",
+	"PBB4",
+	"PBB5",
+	"PBB6",
+	"PBB7",
+	"PCC1",
+	"SDMMC4_CLK_PCC4",
+	"SDMMC4_CMD_PT7",
+	"SDMMC4_DAT0_PAA0",
+	"SDMMC4_DAT1_PAA1",
+	"SDMMC4_DAT2_PAA2",
+	"SDMMC4_DAT3_PAA3",
+	"SDMMC4_DAT4_PAA4",
+	"SDMMC4_DAT5_PAA5",
+	"SDMMC4_DAT6_PAA6",
+	"SDMMC4_DAT7_PAA7",
+	"SDMMC4_RST_N_PCC3",
+};
+
+static const char * const spdif_groups[] = {
+	"SDMMC3_DAT6_PD3",
+	"SDMMC3_DAT7_PD4",
+	"SPDIF_IN_PK6",
+	"SPDIF_OUT_PK5",
+	"UART2_RXD_PC3",
+	"UART2_TXD_PC2",
+};
+
+static const char * const spi1_groups[] = {
+	"SPI1_CS0_N_PX6",
+	"SPI1_MISO_PX7",
+	"SPI1_MOSI_PX4",
+	"SPI1_SCK_PX5",
+	"ULPI_CLK_PY0",
+	"ULPI_DIR_PY1",
+	"ULPI_NXT_PY2",
+	"ULPI_STP_PY3",
+};
+
+static const char * const spi2_groups[] = {
+	"SDMMC3_CMD_PA7",
+	"SDMMC3_DAT4_PD1",
+	"SDMMC3_DAT5_PD0",
+	"SDMMC3_DAT6_PD3",
+	"SDMMC3_DAT7_PD4",
+	"SPI1_CS0_N_PX6",
+	"SPI1_MOSI_PX4",
+	"SPI1_SCK_PX5",
+	"SPI2_CS0_N_PX3",
+	"SPI2_CS1_N_PW2",
+	"SPI2_CS2_N_PW3",
+	"SPI2_MISO_PX1",
+	"SPI2_MOSI_PX0",
+	"SPI2_SCK_PX2",
+	"ULPI_DATA4_PO5",
+	"ULPI_DATA5_PO6",
+	"ULPI_DATA6_PO7",
+	"ULPI_DATA7_PO0",
+};
+
+static const char * const spi2_alt_groups[] = {
+	"SPI1_CS0_N_PX6",
+	"SPI1_MISO_PX7",
+	"SPI1_MOSI_PX4",
+	"SPI1_SCK_PX5",
+	"SPI2_CS1_N_PW2",
+	"SPI2_CS2_N_PW3",
+};
+
+static const char * const spi3_groups[] = {
+	"SDMMC3_CLK_PA6",
+	"SDMMC3_DAT0_PB7",
+	"SDMMC3_DAT1_PB6",
+	"SDMMC3_DAT2_PB5",
+	"SDMMC3_DAT3_PB4",
+	"SDMMC4_DAT0_PAA0",
+	"SDMMC4_DAT1_PAA1",
+	"SDMMC4_DAT2_PAA2",
+	"SDMMC4_DAT3_PAA3",
+	"SPI1_MISO_PX7",
+	"SPI2_CS0_N_PX3",
+	"SPI2_CS1_N_PW2",
+	"SPI2_CS2_N_PW3",
+	"SPI2_MISO_PX1",
+	"SPI2_MOSI_PX0",
+	"SPI2_SCK_PX2",
+	"ULPI_DATA0_PO1",
+	"ULPI_DATA1_PO2",
+	"ULPI_DATA2_PO3",
+	"ULPI_DATA3_PO4",
+};
+
+static const char * const spi4_groups[] = {
+	"GMI_A16_PJ7",
+	"GMI_A17_PB0",
+	"GMI_A18_PB1",
+	"GMI_A19_PK7",
+	"SDMMC3_DAT4_PD1",
+	"SDMMC3_DAT5_PD0",
+	"SDMMC3_DAT6_PD3",
+	"SDMMC3_DAT7_PD4",
+	"UART2_CTS_N_PJ5",
+	"UART2_RTS_N_PJ6",
+	"UART2_RXD_PC3",
+	"UART2_TXD_PC2",
+};
+
+static const char * const spi5_groups[] = {
+	"LCD_CS0_N_PN4",
+	"LCD_CS1_N_PW0",
+	"LCD_PWR0_PB2",
+	"LCD_PWR2_PC6",
+	"LCD_SCK_PZ4",
+	"LCD_SDIN_PZ2",
+	"LCD_SDOUT_PN5",
+	"LCD_WR_N_PZ3",
+};
+
+static const char * const spi6_groups[] = {
+	"SPI2_CS0_N_PX3",
+	"SPI2_MISO_PX1",
+	"SPI2_MOSI_PX0",
+	"SPI2_SCK_PX2",
+};
+
+static const char * const sysclk_groups[] = {
+	"SYS_CLK_REQ_PZ5",
+};
+
+static const char * const test_groups[] = {
+	"KB_COL0_PQ0",
+	"KB_COL1_PQ1",
+};
+
+static const char * const trace_groups[] = {
+	"KB_COL0_PQ0",
+	"KB_COL1_PQ1",
+	"KB_COL2_PQ2",
+	"KB_COL3_PQ3",
+	"KB_COL4_PQ4",
+	"KB_COL5_PQ5",
+	"KB_COL6_PQ6",
+	"KB_COL7_PQ7",
+	"KB_ROW4_PR4",
+	"KB_ROW5_PR5",
+};
+
+static const char * const uarta_groups[] = {
+	"PU0",
+	"PU1",
+	"PU2",
+	"PU3",
+	"PU4",
+	"PU5",
+	"PU6",
+	"SDMMC1_CLK_PZ0",
+	"SDMMC1_CMD_PZ1",
+	"SDMMC1_DAT0_PY7",
+	"SDMMC1_DAT1_PY6",
+	"SDMMC1_DAT2_PY5",
+	"SDMMC1_DAT3_PY4",
+	"SDMMC3_CLK_PA6",
+	"SDMMC3_CMD_PA7",
+	"UART2_CTS_N_PJ5",
+	"UART2_RTS_N_PJ6",
+	"UART2_RXD_PC3",
+	"UART2_TXD_PC2",
+	"ULPI_DATA0_PO1",
+	"ULPI_DATA1_PO2",
+	"ULPI_DATA2_PO3",
+	"ULPI_DATA3_PO4",
+	"ULPI_DATA4_PO5",
+	"ULPI_DATA5_PO6",
+	"ULPI_DATA6_PO7",
+	"ULPI_DATA7_PO0",
+};
+
+static const char * const uartb_groups[] = {
+	"UART2_CTS_N_PJ5",
+	"UART2_RTS_N_PJ6",
+	"UART2_RXD_PC3",
+	"UART2_TXD_PC2",
+};
+
+static const char * const uartc_groups[] = {
+	"UART3_CTS_N_PA1",
+	"UART3_RTS_N_PC0",
+	"UART3_RXD_PW7",
+	"UART3_TXD_PW6",
+};
+
+static const char * const uartd_groups[] = {
+	"GMI_A16_PJ7",
+	"GMI_A17_PB0",
+	"GMI_A18_PB1",
+	"GMI_A19_PK7",
+	"ULPI_CLK_PY0",
+	"ULPI_DIR_PY1",
+	"ULPI_NXT_PY2",
+	"ULPI_STP_PY3",
+};
+
+static const char * const uarte_groups[] = {
+	"SDMMC1_DAT0_PY7",
+	"SDMMC1_DAT1_PY6",
+	"SDMMC1_DAT2_PY5",
+	"SDMMC1_DAT3_PY4",
+	"SDMMC4_DAT0_PAA0",
+	"SDMMC4_DAT1_PAA1",
+	"SDMMC4_DAT2_PAA2",
+	"SDMMC4_DAT3_PAA3",
+};
+
+static const char * const ulpi_groups[] = {
+	"ULPI_CLK_PY0",
+	"ULPI_DATA0_PO1",
+	"ULPI_DATA1_PO2",
+	"ULPI_DATA2_PO3",
+	"ULPI_DATA3_PO4",
+	"ULPI_DATA4_PO5",
+	"ULPI_DATA5_PO6",
+	"ULPI_DATA6_PO7",
+	"ULPI_DATA7_PO0",
+	"ULPI_DIR_PY1",
+	"ULPI_NXT_PY2",
+	"ULPI_STP_PY3",
+};
+
+static const char * const vgp1_groups[] = {
+	"CAM_I2C_SCL_PBB1",
+};
+
+static const char * const vgp2_groups[] = {
+	"CAM_I2C_SDA_PBB2",
+};
+
+static const char * const vgp3_groups[] = {
+	"PBB3",
+	"SDMMC4_DAT5_PAA5",
+};
+
+static const char * const vgp4_groups[] = {
+	"PBB4",
+	"SDMMC4_DAT6_PAA6",
+};
+
+static const char * const vgp5_groups[] = {
+	"PBB5",
+	"SDMMC4_DAT7_PAA7",
+};
+
+static const char * const vgp6_groups[] = {
+	"PBB6",
+	"SDMMC4_RST_N_PCC3",
+};
+
+static const char * const vi_groups[] = {
+	"CAM_MCLK_PCC0",
+	"VI_D0_PT4",
+	"VI_D1_PD5",
+	"VI_D10_PT2",
+	"VI_D11_PT3",
+	"VI_D2_PL0",
+	"VI_D3_PL1",
+	"VI_D4_PL2",
+	"VI_D5_PL3",
+	"VI_D6_PL4",
+	"VI_D7_PL5",
+	"VI_D8_PL6",
+	"VI_D9_PL7",
+	"VI_HSYNC_PD7",
+	"VI_MCLK_PT1",
+	"VI_PCLK_PT0",
+	"VI_VSYNC_PD6",
+};
+
+static const char * const vi_alt1_groups[] = {
+	"CAM_MCLK_PCC0",
+	"VI_MCLK_PT1",
+};
+
+static const char * const vi_alt2_groups[] = {
+	"VI_MCLK_PT1",
+};
+
+static const char * const vi_alt3_groups[] = {
+	"CAM_MCLK_PCC0",
+	"VI_MCLK_PT1",
+};
+
+#define FUNCTION(fname)					\
+	{						\
+		.name = #fname,				\
+		.groups = fname##_groups,		\
+		.ngroups = ARRAY_SIZE(fname##_groups),	\
+	}
+
+static const struct tegra_function tegra30_functions[] = {
+	FUNCTION(blink),
+	FUNCTION(cec),
+	FUNCTION(clk_12m_out),
+	FUNCTION(clk_32k_in),
+	FUNCTION(core_pwr_req),
+	FUNCTION(cpu_pwr_req),
+	FUNCTION(crt),
+	FUNCTION(dap),
+	FUNCTION(ddr),
+	FUNCTION(dev3),
+	FUNCTION(displaya),
+	FUNCTION(displayb),
+	FUNCTION(dtv),
+	FUNCTION(extperiph1),
+	FUNCTION(extperiph2),
+	FUNCTION(extperiph3),
+	FUNCTION(gmi),
+	FUNCTION(gmi_alt),
+	FUNCTION(hda),
+	FUNCTION(hdcp),
+	FUNCTION(hdmi),
+	FUNCTION(hsi),
+	FUNCTION(i2c1),
+	FUNCTION(i2c2),
+	FUNCTION(i2c3),
+	FUNCTION(i2c4),
+	FUNCTION(i2cpwr),
+	FUNCTION(i2s0),
+	FUNCTION(i2s1),
+	FUNCTION(i2s2),
+	FUNCTION(i2s3),
+	FUNCTION(i2s4),
+	FUNCTION(invalid),
+	FUNCTION(kbc),
+	FUNCTION(mio),
+	FUNCTION(nand),
+	FUNCTION(nand_alt),
+	FUNCTION(owr),
+	FUNCTION(pcie),
+	FUNCTION(pwm0),
+	FUNCTION(pwm1),
+	FUNCTION(pwm2),
+	FUNCTION(pwm3),
+	FUNCTION(pwr_int_n),
+	FUNCTION(rsvd1),
+	FUNCTION(rsvd2),
+	FUNCTION(rsvd3),
+	FUNCTION(rsvd4),
+	FUNCTION(rtck),
+	FUNCTION(sata),
+	FUNCTION(sdmmc1),
+	FUNCTION(sdmmc2),
+	FUNCTION(sdmmc3),
+	FUNCTION(sdmmc4),
+	FUNCTION(spdif),
+	FUNCTION(spi1),
+	FUNCTION(spi2),
+	FUNCTION(spi2_alt),
+	FUNCTION(spi3),
+	FUNCTION(spi4),
+	FUNCTION(spi5),
+	FUNCTION(spi6),
+	FUNCTION(sysclk),
+	FUNCTION(test),
+	FUNCTION(trace),
+	FUNCTION(uarta),
+	FUNCTION(uartb),
+	FUNCTION(uartc),
+	FUNCTION(uartd),
+	FUNCTION(uarte),
+	FUNCTION(ulpi),
+	FUNCTION(vgp1),
+	FUNCTION(vgp2),
+	FUNCTION(vgp3),
+	FUNCTION(vgp4),
+	FUNCTION(vgp5),
+	FUNCTION(vgp6),
+	FUNCTION(vi),
+	FUNCTION(vi_alt1),
+	FUNCTION(vi_alt2),
+	FUNCTION(vi_alt3),
+};
+
+#define MUXCTL_REG_A	0x3000
+#define PINGROUP_REG_A	0x868
+
+#define PINGROUP_REG_Y(r) ((r) - MUXCTL_REG_A)
+#define PINGROUP_REG_N(r) -1
+
+#define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior)	\
+	{							\
+		.name = #pg_name,				\
+		.pins = pg_name##_pins,				\
+		.npins = ARRAY_SIZE(pg_name##_pins),		\
+		.funcs = {					\
+			TEGRA_MUX_ ## f0,			\
+			TEGRA_MUX_ ## f1,			\
+			TEGRA_MUX_ ## f2,			\
+			TEGRA_MUX_ ## f3,			\
+		},						\
+		.func_safe = TEGRA_MUX_ ## f_safe,		\
+		.mux_reg = PINGROUP_REG_Y(r),			\
+		.mux_bank = 0,					\
+		.mux_bit = 0,					\
+		.pupd_reg = PINGROUP_REG_Y(r),			\
+		.pupd_bank = 0,					\
+		.pupd_bit = 2,					\
+		.tri_reg = PINGROUP_REG_Y(r),			\
+		.tri_bank = 0,					\
+		.tri_bit = 4,					\
+		.einput_reg = PINGROUP_REG_Y(r),		\
+		.einput_bank = 0,				\
+		.einput_bit = 5,				\
+		.odrain_reg = PINGROUP_REG_##od(r),		\
+		.odrain_bank = 0,				\
+		.odrain_bit = 6,				\
+		.lock_reg = PINGROUP_REG_Y(r),			\
+		.lock_bank = 0,					\
+		.lock_bit = 7,					\
+		.ioreset_reg = PINGROUP_REG_##ior(r),		\
+		.ioreset_bank = 0,				\
+		.ioreset_bit = 8,				\
+		.drv_reg = -1,					\
+	}
+
+#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b,	\
+		     drvdn_b, drvdn_w, drvup_b, drvup_w,	\
+		     slwr_b, slwr_w, slwf_b, slwf_w)		\
+	{							\
+		.name = "drive_" #pg_name,			\
+		.pins = drive_##pg_name##_pins,			\
+		.npins = ARRAY_SIZE(drive_##pg_name##_pins),	\
+		.mux_reg = -1,					\
+		.pupd_reg = -1,					\
+		.tri_reg = -1,					\
+		.einput_reg = -1,				\
+		.odrain_reg = -1,				\
+		.lock_reg = -1,					\
+		.ioreset_reg = -1,				\
+		.drv_reg = ((r) - PINGROUP_REG_A),		\
+		.drv_bank = 1,					\
+		.hsm_bit = hsm_b,				\
+		.schmitt_bit = schmitt_b,			\
+		.lpmd_bit = lpmd_b,				\
+		.drvdn_bit = drvdn_b,				\
+		.drvdn_width = drvdn_w,				\
+		.drvup_bit = drvup_b,				\
+		.drvup_width = drvup_w,				\
+		.slwr_bit = slwr_b,				\
+		.slwr_width = slwr_w,				\
+		.slwf_bit = slwf_b,				\
+		.slwf_width = slwf_w,				\
+	}
+
+static const struct tegra_pingroup tegra30_groups[] = {
+	/*       pg_name,              f0,           f1,           f2,           f3,           safe,         r,      od, ior */
+	/* FIXME: Fill in correct data in safe column */
+	PINGROUP(clk_32k_out_pa0,      BLINK,        RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x331c, N, N),
+	PINGROUP(uart3_cts_n_pa1,      UARTC,        RSVD2,        GMI,          RSVD4,        RSVD4,        0x317c, N, N),
+	PINGROUP(dap2_fs_pa2,          I2S1,         HDA,          RSVD3,        GMI,          RSVD3,        0x3358, N, N),
+	PINGROUP(dap2_sclk_pa3,        I2S1,         HDA,          RSVD3,        GMI,          RSVD3,        0x3364, N, N),
+	PINGROUP(dap2_din_pa4,         I2S1,         HDA,          RSVD3,        GMI,          RSVD3,        0x335c, N, N),
+	PINGROUP(dap2_dout_pa5,        I2S1,         HDA,          RSVD3,        GMI,          RSVD3,        0x3360, N, N),
+	PINGROUP(sdmmc3_clk_pa6,       UARTA,        PWM2,         SDMMC3,       SPI3,         SPI3,         0x3390, N, N),
+	PINGROUP(sdmmc3_cmd_pa7,       UARTA,        PWM3,         SDMMC3,       SPI2,         SPI2,         0x3394, N, N),
+	PINGROUP(gmi_a17_pb0,          UARTD,        SPI4,         GMI,          DTV,          DTV,          0x3234, N, N),
+	PINGROUP(gmi_a18_pb1,          UARTD,        SPI4,         GMI,          DTV,          DTV,          0x3238, N, N),
+	PINGROUP(lcd_pwr0_pb2,         DISPLAYA,     DISPLAYB,     SPI5,         HDCP,         HDCP,         0x3090, N, N),
+	PINGROUP(lcd_pclk_pb3,         DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x3094, N, N),
+	PINGROUP(sdmmc3_dat3_pb4,      RSVD1,        PWM0,         SDMMC3,       SPI3,         RSVD1,        0x33a4, N, N),
+	PINGROUP(sdmmc3_dat2_pb5,      RSVD1,        PWM1,         SDMMC3,       SPI3,         RSVD1,        0x33a0, N, N),
+	PINGROUP(sdmmc3_dat1_pb6,      RSVD1,        RSVD2,        SDMMC3,       SPI3,         RSVD2,        0x339c, N, N),
+	PINGROUP(sdmmc3_dat0_pb7,      RSVD1,        RSVD2,        SDMMC3,       SPI3,         RSVD2,        0x3398, N, N),
+	PINGROUP(uart3_rts_n_pc0,      UARTC,        PWM0,         GMI,          RSVD4,        RSVD4,        0x3180, N, N),
+	PINGROUP(lcd_pwr1_pc1,         DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x3070, N, N),
+	PINGROUP(uart2_txd_pc2,        UARTB,        SPDIF,        UARTA,        SPI4,         SPI4,         0x3168, N, N),
+	PINGROUP(uart2_rxd_pc3,        UARTB,        SPDIF,        UARTA,        SPI4,         SPI4,         0x3164, N, N),
+	PINGROUP(gen1_i2c_scl_pc4,     I2C1,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x31a4, Y, N),
+	PINGROUP(gen1_i2c_sda_pc5,     I2C1,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x31a0, Y, N),
+	PINGROUP(lcd_pwr2_pc6,         DISPLAYA,     DISPLAYB,     SPI5,         HDCP,         HDCP,         0x3074, N, N),
+	PINGROUP(gmi_wp_n_pc7,         RSVD1,        NAND,         GMI,          GMI_ALT,      RSVD1,        0x31c0, N, N),
+	PINGROUP(sdmmc3_dat5_pd0,      PWM0,         SPI4,         SDMMC3,       SPI2,         SPI2,         0x33ac, N, N),
+	PINGROUP(sdmmc3_dat4_pd1,      PWM1,         SPI4,         SDMMC3,       SPI2,         SPI2,         0x33a8, N, N),
+	PINGROUP(lcd_dc1_pd2,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x310c, N, N),
+	PINGROUP(sdmmc3_dat6_pd3,      SPDIF,        SPI4,         SDMMC3,       SPI2,         SPI2,         0x33b0, N, N),
+	PINGROUP(sdmmc3_dat7_pd4,      SPDIF,        SPI4,         SDMMC3,       SPI2,         SPI2,         0x33b4, N, N),
+	PINGROUP(vi_d1_pd5,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3128, N, Y),
+	PINGROUP(vi_vsync_pd6,         DDR,          RSVD2,        VI,           RSVD4,        RSVD4,        0x315c, N, Y),
+	PINGROUP(vi_hsync_pd7,         DDR,          RSVD2,        VI,           RSVD4,        RSVD4,        0x3160, N, Y),
+	PINGROUP(lcd_d0_pe0,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30a4, N, N),
+	PINGROUP(lcd_d1_pe1,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30a8, N, N),
+	PINGROUP(lcd_d2_pe2,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30ac, N, N),
+	PINGROUP(lcd_d3_pe3,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30b0, N, N),
+	PINGROUP(lcd_d4_pe4,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30b4, N, N),
+	PINGROUP(lcd_d5_pe5,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30b8, N, N),
+	PINGROUP(lcd_d6_pe6,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30bc, N, N),
+	PINGROUP(lcd_d7_pe7,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30c0, N, N),
+	PINGROUP(lcd_d8_pf0,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30c4, N, N),
+	PINGROUP(lcd_d9_pf1,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30c8, N, N),
+	PINGROUP(lcd_d10_pf2,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30cc, N, N),
+	PINGROUP(lcd_d11_pf3,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30d0, N, N),
+	PINGROUP(lcd_d12_pf4,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30d4, N, N),
+	PINGROUP(lcd_d13_pf5,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30d8, N, N),
+	PINGROUP(lcd_d14_pf6,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30dc, N, N),
+	PINGROUP(lcd_d15_pf7,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30e0, N, N),
+	PINGROUP(gmi_ad0_pg0,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31f0, N, N),
+	PINGROUP(gmi_ad1_pg1,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31f4, N, N),
+	PINGROUP(gmi_ad2_pg2,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31f8, N, N),
+	PINGROUP(gmi_ad3_pg3,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31fc, N, N),
+	PINGROUP(gmi_ad4_pg4,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3200, N, N),
+	PINGROUP(gmi_ad5_pg5,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3204, N, N),
+	PINGROUP(gmi_ad6_pg6,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3208, N, N),
+	PINGROUP(gmi_ad7_pg7,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x320c, N, N),
+	PINGROUP(gmi_ad8_ph0,          PWM0,         NAND,         GMI,          RSVD4,        RSVD4,        0x3210, N, N),
+	PINGROUP(gmi_ad9_ph1,          PWM1,         NAND,         GMI,          RSVD4,        RSVD4,        0x3214, N, N),
+	PINGROUP(gmi_ad10_ph2,         PWM2,         NAND,         GMI,          RSVD4,        RSVD4,        0x3218, N, N),
+	PINGROUP(gmi_ad11_ph3,         PWM3,         NAND,         GMI,          RSVD4,        RSVD4,        0x321c, N, N),
+	PINGROUP(gmi_ad12_ph4,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3220, N, N),
+	PINGROUP(gmi_ad13_ph5,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3224, N, N),
+	PINGROUP(gmi_ad14_ph6,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3228, N, N),
+	PINGROUP(gmi_ad15_ph7,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x322c, N, N),
+	PINGROUP(gmi_wr_n_pi0,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3240, N, N),
+	PINGROUP(gmi_oe_n_pi1,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3244, N, N),
+	PINGROUP(gmi_dqs_pi2,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x3248, N, N),
+	PINGROUP(gmi_cs6_n_pi3,        NAND,         NAND_ALT,     GMI,          SATA,         SATA,         0x31e8, N, N),
+	PINGROUP(gmi_rst_n_pi4,        NAND,         NAND_ALT,     GMI,          RSVD4,        RSVD4,        0x324c, N, N),
+	PINGROUP(gmi_iordy_pi5,        RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31c4, N, N),
+	PINGROUP(gmi_cs7_n_pi6,        NAND,         NAND_ALT,     GMI,          GMI_ALT,      GMI_ALT,      0x31ec, N, N),
+	PINGROUP(gmi_wait_pi7,         RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31c8, N, N),
+	PINGROUP(gmi_cs0_n_pj0,        RSVD1,        NAND,         GMI,          DTV,          RSVD1,        0x31d4, N, N),
+	PINGROUP(lcd_de_pj1,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x3098, N, N),
+	PINGROUP(gmi_cs1_n_pj2,        RSVD1,        NAND,         GMI,          DTV,          RSVD1,        0x31d8, N, N),
+	PINGROUP(lcd_hsync_pj3,        DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x309c, N, N),
+	PINGROUP(lcd_vsync_pj4,        DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30a0, N, N),
+	PINGROUP(uart2_cts_n_pj5,      UARTA,        UARTB,        GMI,          SPI4,         SPI4,         0x3170, N, N),
+	PINGROUP(uart2_rts_n_pj6,      UARTA,        UARTB,        GMI,          SPI4,         SPI4,         0x316c, N, N),
+	PINGROUP(gmi_a16_pj7,          UARTD,        SPI4,         GMI,          GMI_ALT,      GMI_ALT,      0x3230, N, N),
+	PINGROUP(gmi_adv_n_pk0,        RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31cc, N, N),
+	PINGROUP(gmi_clk_pk1,          RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31d0, N, N),
+	PINGROUP(gmi_cs4_n_pk2,        RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31e4, N, N),
+	PINGROUP(gmi_cs2_n_pk3,        RSVD1,        NAND,         GMI,          RSVD4,        RSVD4,        0x31dc, N, N),
+	PINGROUP(gmi_cs3_n_pk4,        RSVD1,        NAND,         GMI,          GMI_ALT,      RSVD1,        0x31e0, N, N),
+	PINGROUP(spdif_out_pk5,        SPDIF,        RSVD2,        I2C1,         SDMMC2,       RSVD2,        0x3354, N, N),
+	PINGROUP(spdif_in_pk6,         SPDIF,        HDA,          I2C1,         SDMMC2,       SDMMC2,       0x3350, N, N),
+	PINGROUP(gmi_a19_pk7,          UARTD,        SPI4,         GMI,          RSVD4,        RSVD4,        0x323c, N, N),
+	PINGROUP(vi_d2_pl0,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x312c, N, Y),
+	PINGROUP(vi_d3_pl1,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3130, N, Y),
+	PINGROUP(vi_d4_pl2,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3134, N, Y),
+	PINGROUP(vi_d5_pl3,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3138, N, Y),
+	PINGROUP(vi_d6_pl4,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x313c, N, Y),
+	PINGROUP(vi_d7_pl5,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3140, N, Y),
+	PINGROUP(vi_d8_pl6,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3144, N, Y),
+	PINGROUP(vi_d9_pl7,            DDR,          SDMMC2,       VI,           RSVD4,        RSVD4,        0x3148, N, Y),
+	PINGROUP(lcd_d16_pm0,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30e4, N, N),
+	PINGROUP(lcd_d17_pm1,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30e8, N, N),
+	PINGROUP(lcd_d18_pm2,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30ec, N, N),
+	PINGROUP(lcd_d19_pm3,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30f0, N, N),
+	PINGROUP(lcd_d20_pm4,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30f4, N, N),
+	PINGROUP(lcd_d21_pm5,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30f8, N, N),
+	PINGROUP(lcd_d22_pm6,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x30fc, N, N),
+	PINGROUP(lcd_d23_pm7,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x3100, N, N),
+	PINGROUP(dap1_fs_pn0,          I2S0,         HDA,          GMI,          SDMMC2,       SDMMC2,       0x3338, N, N),
+	PINGROUP(dap1_din_pn1,         I2S0,         HDA,          GMI,          SDMMC2,       SDMMC2,       0x333c, N, N),
+	PINGROUP(dap1_dout_pn2,        I2S0,         HDA,          GMI,          SDMMC2,       SDMMC2,       0x3340, N, N),
+	PINGROUP(dap1_sclk_pn3,        I2S0,         HDA,          GMI,          SDMMC2,       SDMMC2,       0x3344, N, N),
+	PINGROUP(lcd_cs0_n_pn4,        DISPLAYA,     DISPLAYB,     SPI5,         RSVD4,        RSVD4,        0x3084, N, N),
+	PINGROUP(lcd_sdout_pn5,        DISPLAYA,     DISPLAYB,     SPI5,         HDCP,         HDCP,         0x307c, N, N),
+	PINGROUP(lcd_dc0_pn6,          DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x3088, N, N),
+	PINGROUP(hdmi_int_pn7,         HDMI,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3110, N, N),
+	PINGROUP(ulpi_data7_po0,       SPI2,         HSI,          UARTA,        ULPI,         ULPI,         0x301c, N, N),
+	PINGROUP(ulpi_data0_po1,       SPI3,         HSI,          UARTA,        ULPI,         ULPI,         0x3000, N, N),
+	PINGROUP(ulpi_data1_po2,       SPI3,         HSI,          UARTA,        ULPI,         ULPI,         0x3004, N, N),
+	PINGROUP(ulpi_data2_po3,       SPI3,         HSI,          UARTA,        ULPI,         ULPI,         0x3008, N, N),
+	PINGROUP(ulpi_data3_po4,       SPI3,         HSI,          UARTA,        ULPI,         ULPI,         0x300c, N, N),
+	PINGROUP(ulpi_data4_po5,       SPI2,         HSI,          UARTA,        ULPI,         ULPI,         0x3010, N, N),
+	PINGROUP(ulpi_data5_po6,       SPI2,         HSI,          UARTA,        ULPI,         ULPI,         0x3014, N, N),
+	PINGROUP(ulpi_data6_po7,       SPI2,         HSI,          UARTA,        ULPI,         ULPI,         0x3018, N, N),
+	PINGROUP(dap3_fs_pp0,          I2S2,         RSVD2,        DISPLAYA,     DISPLAYB,     RSVD2,        0x3030, N, N),
+	PINGROUP(dap3_din_pp1,         I2S2,         RSVD2,        DISPLAYA,     DISPLAYB,     RSVD2,        0x3034, N, N),
+	PINGROUP(dap3_dout_pp2,        I2S2,         RSVD2,        DISPLAYA,     DISPLAYB,     RSVD2,        0x3038, N, N),
+	PINGROUP(dap3_sclk_pp3,        I2S2,         RSVD2,        DISPLAYA,     DISPLAYB,     RSVD2,        0x303c, N, N),
+	PINGROUP(dap4_fs_pp4,          I2S3,         RSVD2,        GMI,          RSVD4,        RSVD4,        0x31a8, N, N),
+	PINGROUP(dap4_din_pp5,         I2S3,         RSVD2,        GMI,          RSVD4,        RSVD4,        0x31ac, N, N),
+	PINGROUP(dap4_dout_pp6,        I2S3,         RSVD2,        GMI,          RSVD4,        RSVD4,        0x31b0, N, N),
+	PINGROUP(dap4_sclk_pp7,        I2S3,         RSVD2,        GMI,          RSVD4,        RSVD4,        0x31b4, N, N),
+	PINGROUP(kb_col0_pq0,          KBC,          NAND,         TRACE,        TEST,         TEST,         0x32fc, N, N),
+	PINGROUP(kb_col1_pq1,          KBC,          NAND,         TRACE,        TEST,         TEST,         0x3300, N, N),
+	PINGROUP(kb_col2_pq2,          KBC,          NAND,         TRACE,        RSVD4,        RSVD4,        0x3304, N, N),
+	PINGROUP(kb_col3_pq3,          KBC,          NAND,         TRACE,        RSVD4,        RSVD4,        0x3308, N, N),
+	PINGROUP(kb_col4_pq4,          KBC,          NAND,         TRACE,        RSVD4,        RSVD4,        0x330c, N, N),
+	PINGROUP(kb_col5_pq5,          KBC,          NAND,         TRACE,        RSVD4,        RSVD4,        0x3310, N, N),
+	PINGROUP(kb_col6_pq6,          KBC,          NAND,         TRACE,        MIO,          MIO,          0x3314, N, N),
+	PINGROUP(kb_col7_pq7,          KBC,          NAND,         TRACE,        MIO,          MIO,          0x3318, N, N),
+	PINGROUP(kb_row0_pr0,          KBC,          NAND,         RSVD3,        RSVD4,        RSVD4,        0x32bc, N, N),
+	PINGROUP(kb_row1_pr1,          KBC,          NAND,         RSVD3,        RSVD4,        RSVD4,        0x32c0, N, N),
+	PINGROUP(kb_row2_pr2,          KBC,          NAND,         RSVD3,        RSVD4,        RSVD4,        0x32c4, N, N),
+	PINGROUP(kb_row3_pr3,          KBC,          NAND,         RSVD3,        INVALID,      RSVD3,        0x32c8, N, N),
+	PINGROUP(kb_row4_pr4,          KBC,          NAND,         TRACE,        RSVD4,        RSVD4,        0x32cc, N, N),
+	PINGROUP(kb_row5_pr5,          KBC,          NAND,         TRACE,        OWR,          OWR,          0x32d0, N, N),
+	PINGROUP(kb_row6_pr6,          KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32d4, N, N),
+	PINGROUP(kb_row7_pr7,          KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32d8, N, N),
+	PINGROUP(kb_row8_ps0,          KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32dc, N, N),
+	PINGROUP(kb_row9_ps1,          KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32e0, N, N),
+	PINGROUP(kb_row10_ps2,         KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32e4, N, N),
+	PINGROUP(kb_row11_ps3,         KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32e8, N, N),
+	PINGROUP(kb_row12_ps4,         KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32ec, N, N),
+	PINGROUP(kb_row13_ps5,         KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32f0, N, N),
+	PINGROUP(kb_row14_ps6,         KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32f4, N, N),
+	PINGROUP(kb_row15_ps7,         KBC,          NAND,         SDMMC2,       MIO,          MIO,          0x32f8, N, N),
+	PINGROUP(vi_pclk_pt0,          RSVD1,        SDMMC2,       VI,           RSVD4,        RSVD4,        0x3154, N, Y),
+	PINGROUP(vi_mclk_pt1,          VI,           VI_ALT1,      VI_ALT2,      VI_ALT3,      VI_ALT3,      0x3158, N, Y),
+	PINGROUP(vi_d10_pt2,           DDR,          RSVD2,        VI,           RSVD4,        RSVD4,        0x314c, N, Y),
+	PINGROUP(vi_d11_pt3,           DDR,          RSVD2,        VI,           RSVD4,        RSVD4,        0x3150, N, Y),
+	PINGROUP(vi_d0_pt4,            DDR,          RSVD2,        VI,           RSVD4,        RSVD4,        0x3124, N, Y),
+	PINGROUP(gen2_i2c_scl_pt5,     I2C2,         HDCP,         GMI,          RSVD4,        RSVD4,        0x3250, Y, N),
+	PINGROUP(gen2_i2c_sda_pt6,     I2C2,         HDCP,         GMI,          RSVD4,        RSVD4,        0x3254, Y, N),
+	PINGROUP(sdmmc4_cmd_pt7,       I2C3,         NAND,         GMI,          SDMMC4,       SDMMC4,       0x325c, N, Y),
+	PINGROUP(pu0,                  OWR,          UARTA,        GMI,          RSVD4,        RSVD4,        0x3184, N, N),
+	PINGROUP(pu1,                  RSVD1,        UARTA,        GMI,          RSVD4,        RSVD4,        0x3188, N, N),
+	PINGROUP(pu2,                  RSVD1,        UARTA,        GMI,          RSVD4,        RSVD4,        0x318c, N, N),
+	PINGROUP(pu3,                  PWM0,         UARTA,        GMI,          RSVD4,        RSVD4,        0x3190, N, N),
+	PINGROUP(pu4,                  PWM1,         UARTA,        GMI,          RSVD4,        RSVD4,        0x3194, N, N),
+	PINGROUP(pu5,                  PWM2,         UARTA,        GMI,          RSVD4,        RSVD4,        0x3198, N, N),
+	PINGROUP(pu6,                  PWM3,         UARTA,        GMI,          RSVD4,        RSVD4,        0x319c, N, N),
+	PINGROUP(jtag_rtck_pu7,        RTCK,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x32b0, N, N),
+	PINGROUP(pv0,                  RSVD1,        RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3040, N, N),
+	PINGROUP(pv1,                  RSVD1,        RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3044, N, N),
+	PINGROUP(pv2,                  OWR,          RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3060, N, N),
+	PINGROUP(pv3,                  CLK_12M_OUT,  RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3064, N, N),
+	PINGROUP(ddc_scl_pv4,          I2C4,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3114, N, N),
+	PINGROUP(ddc_sda_pv5,          I2C4,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3118, N, N),
+	PINGROUP(crt_hsync_pv6,        CRT,          RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x311c, N, N),
+	PINGROUP(crt_vsync_pv7,        CRT,          RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3120, N, N),
+	PINGROUP(lcd_cs1_n_pw0,        DISPLAYA,     DISPLAYB,     SPI5,         RSVD4,        RSVD4,        0x3104, N, N),
+	PINGROUP(lcd_m1_pw1,           DISPLAYA,     DISPLAYB,     RSVD3,        RSVD4,        RSVD4,        0x3108, N, N),
+	PINGROUP(spi2_cs1_n_pw2,       SPI3,         SPI2,         SPI2_ALT,     I2C1,         I2C1,         0x3388, N, N),
+	PINGROUP(spi2_cs2_n_pw3,       SPI3,         SPI2,         SPI2_ALT,     I2C1,         I2C1,         0x338c, N, N),
+	PINGROUP(clk1_out_pw4,         EXTPERIPH1,   RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x334c, N, N),
+	PINGROUP(clk2_out_pw5,         EXTPERIPH2,   RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3068, N, N),
+	PINGROUP(uart3_txd_pw6,        UARTC,        RSVD2,        GMI,          RSVD4,        RSVD4,        0x3174, N, N),
+	PINGROUP(uart3_rxd_pw7,        UARTC,        RSVD2,        GMI,          RSVD4,        RSVD4,        0x3178, N, N),
+	PINGROUP(spi2_mosi_px0,        SPI6,         SPI2,         SPI3,         GMI,          GMI,          0x3368, N, N),
+	PINGROUP(spi2_miso_px1,        SPI6,         SPI2,         SPI3,         GMI,          GMI,          0x336c, N, N),
+	PINGROUP(spi2_sck_px2,         SPI6,         SPI2,         SPI3,         GMI,          GMI,          0x3374, N, N),
+	PINGROUP(spi2_cs0_n_px3,       SPI6,         SPI2,         SPI3,         GMI,          GMI,          0x3370, N, N),
+	PINGROUP(spi1_mosi_px4,        SPI2,         SPI1,         SPI2_ALT,     GMI,          GMI,          0x3378, N, N),
+	PINGROUP(spi1_sck_px5,         SPI2,         SPI1,         SPI2_ALT,     GMI,          GMI,          0x337c, N, N),
+	PINGROUP(spi1_cs0_n_px6,       SPI2,         SPI1,         SPI2_ALT,     GMI,          GMI,          0x3380, N, N),
+	PINGROUP(spi1_miso_px7,        SPI3,         SPI1,         SPI2_ALT,     RSVD4,        RSVD4,        0x3384, N, N),
+	PINGROUP(ulpi_clk_py0,         SPI1,         RSVD2,        UARTD,        ULPI,         RSVD2,        0x3020, N, N),
+	PINGROUP(ulpi_dir_py1,         SPI1,         RSVD2,        UARTD,        ULPI,         RSVD2,        0x3024, N, N),
+	PINGROUP(ulpi_nxt_py2,         SPI1,         RSVD2,        UARTD,        ULPI,         RSVD2,        0x3028, N, N),
+	PINGROUP(ulpi_stp_py3,         SPI1,         RSVD2,        UARTD,        ULPI,         RSVD2,        0x302c, N, N),
+	PINGROUP(sdmmc1_dat3_py4,      SDMMC1,       RSVD2,        UARTE,        UARTA,        RSVD2,        0x3050, N, N),
+	PINGROUP(sdmmc1_dat2_py5,      SDMMC1,       RSVD2,        UARTE,        UARTA,        RSVD2,        0x3054, N, N),
+	PINGROUP(sdmmc1_dat1_py6,      SDMMC1,       RSVD2,        UARTE,        UARTA,        RSVD2,        0x3058, N, N),
+	PINGROUP(sdmmc1_dat0_py7,      SDMMC1,       RSVD2,        UARTE,        UARTA,        RSVD2,        0x305c, N, N),
+	PINGROUP(sdmmc1_clk_pz0,       SDMMC1,       RSVD2,        RSVD3,        UARTA,        RSVD3,        0x3048, N, N),
+	PINGROUP(sdmmc1_cmd_pz1,       SDMMC1,       RSVD2,        RSVD3,        UARTA,        RSVD3,        0x304c, N, N),
+	PINGROUP(lcd_sdin_pz2,         DISPLAYA,     DISPLAYB,     SPI5,         RSVD4,        RSVD4,        0x3078, N, N),
+	PINGROUP(lcd_wr_n_pz3,         DISPLAYA,     DISPLAYB,     SPI5,         HDCP,         HDCP,         0x3080, N, N),
+	PINGROUP(lcd_sck_pz4,          DISPLAYA,     DISPLAYB,     SPI5,         HDCP,         HDCP,         0x308c, N, N),
+	PINGROUP(sys_clk_req_pz5,      SYSCLK,       RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3320, N, N),
+	PINGROUP(pwr_i2c_scl_pz6,      I2CPWR,       RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x32b4, Y, N),
+	PINGROUP(pwr_i2c_sda_pz7,      I2CPWR,       RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x32b8, Y, N),
+	PINGROUP(sdmmc4_dat0_paa0,     UARTE,        SPI3,         GMI,          SDMMC4,       SDMMC4,       0x3260, N, Y),
+	PINGROUP(sdmmc4_dat1_paa1,     UARTE,        SPI3,         GMI,          SDMMC4,       SDMMC4,       0x3264, N, Y),
+	PINGROUP(sdmmc4_dat2_paa2,     UARTE,        SPI3,         GMI,          SDMMC4,       SDMMC4,       0x3268, N, Y),
+	PINGROUP(sdmmc4_dat3_paa3,     UARTE,        SPI3,         GMI,          SDMMC4,       SDMMC4,       0x326c, N, Y),
+	PINGROUP(sdmmc4_dat4_paa4,     I2C3,         I2S4,         GMI,          SDMMC4,       SDMMC4,       0x3270, N, Y),
+	PINGROUP(sdmmc4_dat5_paa5,     VGP3,         I2S4,         GMI,          SDMMC4,       SDMMC4,       0x3274, N, Y),
+	PINGROUP(sdmmc4_dat6_paa6,     VGP4,         I2S4,         GMI,          SDMMC4,       SDMMC4,       0x3278, N, Y),
+	PINGROUP(sdmmc4_dat7_paa7,     VGP5,         I2S4,         GMI,          SDMMC4,       SDMMC4,       0x327c, N, Y),
+	PINGROUP(pbb0,                 I2S4,         RSVD2,        RSVD3,        SDMMC4,       RSVD3,        0x328c, N, N),
+	PINGROUP(cam_i2c_scl_pbb1,     VGP1,         I2C3,         RSVD3,        SDMMC4,       RSVD3,        0x3290, Y, N),
+	PINGROUP(cam_i2c_sda_pbb2,     VGP2,         I2C3,         RSVD3,        SDMMC4,       RSVD3,        0x3294, Y, N),
+	PINGROUP(pbb3,                 VGP3,         DISPLAYA,     DISPLAYB,     SDMMC4,       SDMMC4,       0x3298, N, N),
+	PINGROUP(pbb4,                 VGP4,         DISPLAYA,     DISPLAYB,     SDMMC4,       SDMMC4,       0x329c, N, N),
+	PINGROUP(pbb5,                 VGP5,         DISPLAYA,     DISPLAYB,     SDMMC4,       SDMMC4,       0x32a0, N, N),
+	PINGROUP(pbb6,                 VGP6,         DISPLAYA,     DISPLAYB,     SDMMC4,       SDMMC4,       0x32a4, N, N),
+	PINGROUP(pbb7,                 I2S4,         RSVD2,        RSVD3,        SDMMC4,       RSVD3,        0x32a8, N, N),
+	PINGROUP(cam_mclk_pcc0,        VI,           VI_ALT1,      VI_ALT3,      SDMMC4,       SDMMC4,       0x3284, N, N),
+	PINGROUP(pcc1,                 I2S4,         RSVD2,        RSVD3,        SDMMC4,       RSVD3,        0x3288, N, N),
+	PINGROUP(pcc2,                 I2S4,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x32ac, N, N),
+	PINGROUP(sdmmc4_rst_n_pcc3,    VGP6,         RSVD2,        RSVD3,        SDMMC4,       RSVD3,        0x3280, N, Y),
+	PINGROUP(sdmmc4_clk_pcc4,      INVALID,      NAND,         GMI,          SDMMC4,       SDMMC4,       0x3258, N, Y),
+	PINGROUP(clk2_req_pcc5,        DAP,          RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x306c, N, N),
+	PINGROUP(pex_l2_rst_n_pcc6,    PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33d8, N, N),
+	PINGROUP(pex_l2_clkreq_n_pcc7, PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33dc, N, N),
+	PINGROUP(pex_l0_prsnt_n_pdd0,  PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33b8, N, N),
+	PINGROUP(pex_l0_rst_n_pdd1,    PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33bc, N, N),
+	PINGROUP(pex_l0_clkreq_n_pdd2, PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33c0, N, N),
+	PINGROUP(pex_wake_n_pdd3,      PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33c4, N, N),
+	PINGROUP(pex_l1_prsnt_n_pdd4,  PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33c8, N, N),
+	PINGROUP(pex_l1_rst_n_pdd5,    PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33cc, N, N),
+	PINGROUP(pex_l1_clkreq_n_pdd6, PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33d0, N, N),
+	PINGROUP(pex_l2_prsnt_n_pdd7,  PCIE,         HDA,          RSVD3,        RSVD4,        RSVD4,        0x33d4, N, N),
+	PINGROUP(clk3_out_pee0,        EXTPERIPH3,   RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x31b8, N, N),
+	PINGROUP(clk3_req_pee1,        DEV3,         RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x31bc, N, N),
+	PINGROUP(clk1_req_pee2,        DAP,          HDA,          RSVD3,        RSVD4,        RSVD4,        0x3348, N, N),
+	PINGROUP(hdmi_cec_pee3,        CEC,          RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x33e0, Y, N),
+	PINGROUP(clk_32k_in,           CLK_32K_IN,   RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3330, N, N),
+	PINGROUP(core_pwr_req,         CORE_PWR_REQ, RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3324, N, N),
+	PINGROUP(cpu_pwr_req,          CPU_PWR_REQ,  RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x3328, N, N),
+	PINGROUP(owr,                  OWR,          CEC,          RSVD3,        RSVD4,        RSVD4,        0x3334, N, N),
+	PINGROUP(pwr_int_n,            PWR_INT_N,    RSVD2,        RSVD3,        RSVD4,        RSVD4,        0x332c, N, N),
+	/* pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, slwf_b, slwf_w */
+	DRV_PINGROUP(ao1,   0x868,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(ao2,   0x86c,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(at1,   0x870,  2,  3,  4,  14,  5,  19,  5,  24,  2,  28,  2),
+	DRV_PINGROUP(at2,   0x874,  2,  3,  4,  14,  5,  19,  5,  24,  2,  28,  2),
+	DRV_PINGROUP(at3,   0x878,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(at4,   0x87c,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(at5,   0x880,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(cdev1, 0x884,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(cdev2, 0x888,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(cec,   0x938,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(crt,   0x8f8,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(csus,  0x88c, -1, -1, -1,  12,  5,  19,  5,  24,  4,  28,  4),
+	DRV_PINGROUP(dap1,  0x890,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(dap2,  0x894,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(dap3,  0x898,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(dap4,  0x89c,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(dbg,   0x8a0,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(ddc,   0x8fc,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(dev3,  0x92c,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(gma,   0x900, -1, -1, -1,  14,  5,  19,  5,  24,  4,  28,  4),
+	DRV_PINGROUP(gmb,   0x904, -1, -1, -1,  14,  5,  19,  5,  24,  4,  28,  4),
+	DRV_PINGROUP(gmc,   0x908, -1, -1, -1,  14,  5,  19,  5,  24,  4,  28,  4),
+	DRV_PINGROUP(gmd,   0x90c, -1, -1, -1,  14,  5,  19,  5,  24,  4,  28,  4),
+	DRV_PINGROUP(gme,   0x910,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(gmf,   0x914,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(gmg,   0x918,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(gmh,   0x91c,  2,  3,  4,  14,  5,  19,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(gpv,   0x928,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(lcd1,  0x8a4,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(lcd2,  0x8a8,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(owr,   0x920,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(sdio1, 0x8ec,  2,  3, -1,  12,  7,  20,  7,  28,  2,  30,  2),
+	DRV_PINGROUP(sdio2, 0x8ac,  2,  3, -1,  12,  7,  20,  7,  28,  2,  30,  2),
+	DRV_PINGROUP(sdio3, 0x8b0,  2,  3, -1,  12,  7,  20,  7,  28,  2,  30,  2),
+	DRV_PINGROUP(spi,   0x8b4,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(uaa,   0x8b8,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(uab,   0x8bc,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(uart2, 0x8c0,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(uart3, 0x8c4,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(uda,   0x924,  2,  3,  4,  12,  5,  20,  5,  28,  2,  30,  2),
+	DRV_PINGROUP(vi1,   0x8c8, -1, -1, -1,  14,  5,  19,  5,  24,  4,  28,  4),
+};
+
+static const struct tegra_pinctrl_soc_data tegra30_pinctrl = {
+	.ngpios = NUM_GPIOS,
+	.pins = tegra30_pins,
+	.npins = ARRAY_SIZE(tegra30_pins),
+	.functions = tegra30_functions,
+	.nfunctions = ARRAY_SIZE(tegra30_functions),
+	.groups = tegra30_groups,
+	.ngroups = ARRAY_SIZE(tegra30_groups),
+};
+
+void __devinit tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc)
+{
+	*soc = &tegra30_pinctrl;
+}
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index c8d02f1..fc4a281 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -162,7 +162,7 @@
 #define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS		0x0100
 #define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N	0x0200
 
-#define DRIVER_NAME "pinmux-u300"
+#define DRIVER_NAME "pinctrl-u300"
 
 /*
  * The DB3350 has 467 pads, I have enumerated the pads clockwise around the
@@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = {
 	.owner = THIS_MODULE,
 };
 
-static int __init u300_pmx_probe(struct platform_device *pdev)
+static int __devinit u300_pmx_probe(struct platform_device *pdev)
 {
 	struct u300_pmx *upmx;
 	struct resource *res;
+	struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
 	int ret;
 	int i;
 
+	pr_err("U300 PMX PROBE\n");
+
 	/* Create state holders etc for this driver */
 	upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
 	if (!upmx)
@@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
 	}
 
 	/* We will handle a range of GPIO pins */
-	for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
+	for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
+		u300_gpio_ranges[i].gc = gpio_chip;
 		pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
+	}
 
 	platform_set_drvdata(pdev, upmx);
 
-	dev_info(&pdev->dev, "initialized U300 pinmux driver\n");
+	dev_info(&pdev->dev, "initialized U300 pin control driver\n");
 
 	return 0;
 
@@ -1115,7 +1120,7 @@ out_no_resource:
 	return ret;
 }
 
-static int __exit u300_pmx_remove(struct platform_device *pdev)
+static int __devexit u300_pmx_remove(struct platform_device *pdev)
 {
 	struct u300_pmx *upmx = platform_get_drvdata(pdev);
 	int i;
@@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = {
 		.name = DRIVER_NAME,
 		.owner = THIS_MODULE,
 	},
-	.remove = __exit_p(u300_pmx_remove),
+	.probe = u300_pmx_probe,
+	.remove = __devexit_p(u300_pmx_remove),
 };
 
 static int __init u300_pmx_init(void)
 {
-	return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe);
+	return platform_driver_register(&u300_pmx_driver);
 }
 arch_initcall(u300_pmx_init);
 
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 7c3193f..ea31c46 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -1,7 +1,7 @@
 /*
  * Core driver for the pin muxing portions of the pin control subsystem
  *
- * Copyright (C) 2011 ST-Ericsson SA
+ * Copyright (C) 2011-2012 ST-Ericsson SA
  * Written on behalf of Linaro for ST-Ericsson
  * Based on bits of regulator core, gpio core and clk core
  *
@@ -28,14 +28,7 @@
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinmux.h>
 #include "core.h"
-
-/* List of pinmuxes */
-static DEFINE_MUTEX(pinmux_list_mutex);
-static LIST_HEAD(pinmux_list);
-
-/* Global pinmux maps */
-static struct pinmux_map *pinmux_maps;
-static unsigned pinmux_maps_num;
+#include "pinmux.h"
 
 /**
  * struct pinmux_group - group list item for pinmux groups
@@ -47,42 +40,33 @@ struct pinmux_group {
 	unsigned group_selector;
 };
 
-/**
- * struct pinmux - per-device pinmux state holder
- * @node: global list node
- * @dev: the device using this pinmux
- * @usecount: the number of active users of this mux setting, used to keep
- *	track of nested use cases
- * @pctldev: pin control device handling this pinmux
- * @func_selector: the function selector for the pinmux device handling
- *	this pinmux
- * @groups: the group selectors for the pinmux device and
- *	selector combination handling this pinmux, this is a list that
- *	will be traversed on all pinmux operations such as
- *	get/put/enable/disable
- * @mutex: a lock for the pinmux state holder
- */
-struct pinmux {
-	struct list_head node;
-	struct device *dev;
-	unsigned usecount;
-	struct pinctrl_dev *pctldev;
-	unsigned func_selector;
-	struct list_head groups;
-	struct mutex mutex;
-};
+int pinmux_check_ops(struct pinctrl_dev *pctldev)
+{
+	const struct pinmux_ops *ops = pctldev->desc->pmxops;
+	unsigned selector = 0;
 
-/**
- * struct pinmux_hog - a list item to stash mux hogs
- * @node: pinmux hog list node
- * @map: map entry responsible for this hogging
- * @pmx: the pinmux hogged by this item
- */
-struct pinmux_hog {
-	struct list_head node;
-	struct pinmux_map const *map;
-	struct pinmux *pmx;
-};
+	/* Check that we implement required operations */
+	if (!ops->list_functions ||
+	    !ops->get_function_name ||
+	    !ops->get_function_groups ||
+	    !ops->enable ||
+	    !ops->disable)
+		return -EINVAL;
+
+	/* Check that all functions registered have names */
+	while (ops->list_functions(pctldev, selector) >= 0) {
+		const char *fname = ops->get_function_name(pctldev,
+							   selector);
+		if (!fname) {
+			pr_err("pinmux ops has no name for function%u\n",
+				selector);
+			return -EINVAL;
+		}
+		selector++;
+	}
+
+	return 0;
+}
 
 /**
  * pin_request() - request a single pin to be muxed in, typically for GPIO
@@ -207,28 +191,18 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
 }
 
 /**
- * pinmux_request_gpio() - request a single pin to be muxed in as GPIO
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_request() semantics, platforms and individual drivers
- * shall *NOT* request GPIO pins to be muxed in.
+ * pinmux_request_gpio() - request pinmuxing for a GPIO pin
+ * @pctldev: pin controller device affected
+ * @pin: the pin to mux in for GPIO
+ * @range: the applicable GPIO range
  */
-int pinmux_request_gpio(unsigned gpio)
+int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range,
+			unsigned pin, unsigned gpio)
 {
 	char gpiostr[16];
 	const char *function;
-	struct pinctrl_dev *pctldev;
-	struct pinctrl_gpio_range *range;
 	int ret;
-	int pin;
-
-	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
-	if (ret)
-		return -EINVAL;
-
-	/* Convert to the pin controllers number space */
-	pin = gpio - range->base + range->pin_base;
 
 	/* Conjure some name stating what chip and pin this is taken by */
 	snprintf(gpiostr, 15, "%s:%d", range->name, gpio);
@@ -243,53 +217,38 @@ int pinmux_request_gpio(unsigned gpio)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(pinmux_request_gpio);
 
 /**
- * pinmux_free_gpio() - free a single pin, currently used as GPIO
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_free() semantics, platforms and individual drivers
- * shall *NOT* request GPIO pins to be muxed out.
+ * pinmux_free_gpio() - release a pin from GPIO muxing
+ * @pctldev: the pin controller device for the pin
+ * @pin: the affected currently GPIO-muxed in pin
+ * @range: applicable GPIO range
  */
-void pinmux_free_gpio(unsigned gpio)
+void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin,
+		      struct pinctrl_gpio_range *range)
 {
-	struct pinctrl_dev *pctldev;
-	struct pinctrl_gpio_range *range;
-	int ret;
-	int pin;
 	const char *func;
 
-	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
-	if (ret)
-		return;
-
-	/* Convert to the pin controllers number space */
-	pin = gpio - range->base + range->pin_base;
-
 	func = pin_free(pctldev, pin, range);
 	kfree(func);
 }
-EXPORT_SYMBOL_GPL(pinmux_free_gpio);
 
-static int pinmux_gpio_direction(unsigned gpio, bool input)
+/**
+ * pinmux_gpio_direction() - set the direction of a single muxed-in GPIO pin
+ * @pctldev: the pin controller handling this pin
+ * @range: applicable GPIO range
+ * @pin: the affected GPIO pin in this controller
+ * @input: true if we set the pin as input, false for output
+ */
+int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+			  struct pinctrl_gpio_range *range,
+			  unsigned pin, bool input)
 {
-	struct pinctrl_dev *pctldev;
-	struct pinctrl_gpio_range *range;
 	const struct pinmux_ops *ops;
 	int ret;
-	int pin;
-
-	ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
-	if (ret)
-		return ret;
 
 	ops = pctldev->desc->pmxops;
 
-	/* Convert to the pin controllers number space */
-	pin = gpio - range->base + range->pin_base;
-
 	if (ops->gpio_set_direction)
 		ret = ops->gpio_set_direction(pctldev, range, pin, input);
 	else
@@ -299,111 +258,6 @@ static int pinmux_gpio_direction(unsigned gpio, bool input)
 }
 
 /**
- * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_direction_input() semantics, platforms and individual
- * drivers shall *NOT* touch pinmux GPIO calls.
- */
-int pinmux_gpio_direction_input(unsigned gpio)
-{
-	return pinmux_gpio_direction(gpio, true);
-}
-EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input);
-
-/**
- * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_direction_output() semantics, platforms and individual
- * drivers shall *NOT* touch pinmux GPIO calls.
- */
-int pinmux_gpio_direction_output(unsigned gpio)
-{
-	return pinmux_gpio_direction(gpio, false);
-}
-EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
-
-/**
- * pinmux_register_mappings() - register a set of pinmux mappings
- * @maps: the pinmux mappings table to register, this should be marked with
- *	__initdata so it can be discarded after boot, this function will
- *	perform a shallow copy for the mapping entries.
- * @num_maps: the number of maps in the mapping table
- *
- * Only call this once during initialization of your machine, the function is
- * tagged as __init and won't be callable after init has completed. The map
- * passed into this function will be owned by the pinmux core and cannot be
- * freed.
- */
-int __init pinmux_register_mappings(struct pinmux_map const *maps,
-				    unsigned num_maps)
-{
-	void *tmp_maps;
-	int i;
-
-	pr_debug("add %d pinmux maps\n", num_maps);
-
-	/* First sanity check the new mapping */
-	for (i = 0; i < num_maps; i++) {
-		if (!maps[i].name) {
-			pr_err("failed to register map %d: no map name given\n",
-					i);
-			return -EINVAL;
-		}
-
-		if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
-			pr_err("failed to register map %s (%d): no pin control device given\n",
-			       maps[i].name, i);
-			return -EINVAL;
-		}
-
-		if (!maps[i].function) {
-			pr_err("failed to register map %s (%d): no function ID given\n",
-					maps[i].name, i);
-			return -EINVAL;
-		}
-
-		if (!maps[i].dev && !maps[i].dev_name)
-			pr_debug("add system map %s function %s with no device\n",
-				 maps[i].name,
-				 maps[i].function);
-		else
-			pr_debug("register map %s, function %s\n",
-				 maps[i].name,
-				 maps[i].function);
-	}
-
-	/*
-	 * Make a copy of the map array - string pointers will end up in the
-	 * kernel const section anyway so these do not need to be deep copied.
-	 */
-	if (!pinmux_maps_num) {
-		/* On first call, just copy them */
-		tmp_maps = kmemdup(maps,
-				   sizeof(struct pinmux_map) * num_maps,
-				   GFP_KERNEL);
-		if (!tmp_maps)
-			return -ENOMEM;
-	} else {
-		/* Subsequent calls, reallocate array to new size */
-		size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num;
-		size_t newsize = sizeof(struct pinmux_map) * num_maps;
-
-		tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL);
-		if (!tmp_maps)
-			return -ENOMEM;
-		memcpy((tmp_maps + oldsize), maps, newsize);
-	}
-
-	pinmux_maps = tmp_maps;
-	pinmux_maps_num += num_maps;
-	return 0;
-}
-
-/**
  * acquire_pins() - acquire all the pins for a certain function on a pinmux
  * @pctldev: the device to take the pins on
  * @func_selector: the function selector to acquire the pins for
@@ -560,7 +414,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
  * negative otherwise
  */
 static int pinmux_search_function(struct pinctrl_dev *pctldev,
-				  struct pinmux_map const *map,
+				  struct pinctrl_map const *map,
 				  unsigned *func_selector,
 				  unsigned *group_selector)
 {
@@ -598,10 +452,10 @@ static int pinmux_search_function(struct pinctrl_dev *pctldev,
  * pinmux_enable_muxmap() - enable a map entry for a certain pinmux
  */
 static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
-				struct pinmux *pmx,
+				struct pinctrl *p,
 				struct device *dev,
 				const char *devname,
-				struct pinmux_map const *map)
+				struct pinctrl_map const *map)
 {
 	unsigned func_selector;
 	unsigned group_selector;
@@ -615,14 +469,14 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
 	 * by anyone else.
 	 */
 
-	if (pmx->pctldev && pmx->pctldev != pctldev) {
+	if (p->pctldev && p->pctldev != pctldev) {
 		dev_err(pctldev->dev,
 			"different pin control devices given for device %s, function %s\n",
 			devname, map->function);
 		return -EINVAL;
 	}
-	pmx->dev = dev;
-	pmx->pctldev = pctldev;
+	p->dev = dev;
+	p->pctldev = pctldev;
 
 	/* Now go into the driver and try to match a function and group */
 	ret = pinmux_search_function(pctldev, map, &func_selector,
@@ -635,14 +489,14 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
 	 * we support several groups with one function but not several
 	 * functions with one or several groups in the same pinmux.
 	 */
-	if (pmx->func_selector != UINT_MAX &&
-	    pmx->func_selector != func_selector) {
+	if (p->func_selector != UINT_MAX &&
+	    p->func_selector != func_selector) {
 		dev_err(pctldev->dev,
 			"dual function defines in the map for device %s\n",
 		       devname);
 		return -EINVAL;
 	}
-	pmx->func_selector = func_selector;
+	p->func_selector = func_selector;
 
 	/* Now add this group selector, we may have many of them */
 	grp = kmalloc(sizeof(struct pinmux_group), GFP_KERNEL);
@@ -654,378 +508,85 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
 		kfree(grp);
 		return ret;
 	}
-	list_add(&grp->node, &pmx->groups);
+	list_add_tail(&grp->node, &p->groups);
 
 	return 0;
 }
 
-static void pinmux_free_groups(struct pinmux *pmx)
-{
-	struct list_head *node, *tmp;
-
-	list_for_each_safe(node, tmp, &pmx->groups) {
-		struct pinmux_group *grp =
-			list_entry(node, struct pinmux_group, node);
-		/* Release all pins taken by this group */
-		release_pins(pmx->pctldev, grp->group_selector);
-		list_del(node);
-		kfree(grp);
-	}
-}
-
 /**
- * pinmux_get() - retrieves the pinmux for a certain device
- * @dev: the device to get the pinmux for
- * @name: an optional specific mux mapping name or NULL, the name is only
- *	needed if you want to have more than one mapping per device, or if you
- *	need an anonymous pinmux (not tied to any specific device)
+ * pinmux_apply_muxmap() - apply a certain mux mapping entry
  */
-struct pinmux *pinmux_get(struct device *dev, const char *name)
+int pinmux_apply_muxmap(struct pinctrl_dev *pctldev,
+			struct pinctrl *p,
+			struct device *dev,
+			const char *devname,
+			struct pinctrl_map const *map)
 {
-	struct pinmux_map const *map = NULL;
-	struct pinctrl_dev *pctldev = NULL;
-	const char *devname = NULL;
-	struct pinmux *pmx;
-	bool found_map;
-	unsigned num_maps = 0;
-	int ret = -ENODEV;
-	int i;
-
-	/* We must have dev or ID or both */
-	if (!dev && !name)
-		return ERR_PTR(-EINVAL);
-
-	if (dev)
-		devname = dev_name(dev);
-
-	pr_debug("get mux %s for device %s\n", name,
-		 devname ? devname : "(none)");
-
-	/*
-	 * create the state cookie holder struct pinmux for each
-	 * mapping, this is what consumers will get when requesting
-	 * a pinmux handle with pinmux_get()
-	 */
-	pmx = kzalloc(sizeof(struct pinmux), GFP_KERNEL);
-	if (pmx == NULL)
-		return ERR_PTR(-ENOMEM);
-	mutex_init(&pmx->mutex);
-	pmx->func_selector = UINT_MAX;
-	INIT_LIST_HEAD(&pmx->groups);
-
-	/* Iterate over the pinmux maps to locate the right ones */
-	for (i = 0; i < pinmux_maps_num; i++) {
-		map = &pinmux_maps[i];
-		found_map = false;
-
-		/*
-		 * First, try to find the pctldev given in the map
-		 */
-		pctldev = get_pinctrl_dev_from_dev(map->ctrl_dev,
-						   map->ctrl_dev_name);
-		if (!pctldev) {
-			const char *devname = NULL;
-
-			if (map->ctrl_dev)
-				devname = dev_name(map->ctrl_dev);
-			else if (map->ctrl_dev_name)
-				devname = map->ctrl_dev_name;
-
-			pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n",
-				   map->function);
-			pr_warning("given pinctrl device name: %s",
-				   devname ? devname : "UNDEFINED");
-
-			/* Continue to check the other mappings anyway... */
-			continue;
-		}
-
-		pr_debug("in map, found pctldev %s to handle function %s",
-			 dev_name(pctldev->dev), map->function);
-
-
-		/*
-		 * If we're looking for a specific named map, this must match,
-		 * else we loop and look for the next.
-		 */
-		if (name != NULL) {
-			if (map->name == NULL)
-				continue;
-			if (strcmp(map->name, name))
-				continue;
-		}
-
-		/*
-		 * This is for the case where no device name is given, we
-		 * already know that the function name matches from above
-		 * code.
-		 */
-		if (!map->dev_name && (name != NULL))
-			found_map = true;
-
-		/* If the mapping has a device set up it must match */
-		if (map->dev_name &&
-		    (!devname || !strcmp(map->dev_name, devname)))
-			/* MATCH! */
-			found_map = true;
-
-		/* If this map is applicable, then apply it */
-		if (found_map) {
-			ret = pinmux_enable_muxmap(pctldev, pmx, dev,
-						   devname, map);
-			if (ret) {
-				pinmux_free_groups(pmx);
-				kfree(pmx);
-				return ERR_PTR(ret);
-			}
-			num_maps++;
-		}
-	}
-
+	int ret;
 
-	/* We should have atleast one map, right */
-	if (!num_maps) {
-		pr_err("could not find any mux maps for device %s, ID %s\n",
-		       devname ? devname : "(anonymous)",
-		       name ? name : "(undefined)");
-		kfree(pmx);
-		return ERR_PTR(-EINVAL);
+	ret = pinmux_enable_muxmap(pctldev, p, dev,
+				   devname, map);
+	if (ret) {
+		pinmux_put(p);
+		return ret;
 	}
 
-	pr_debug("found %u mux maps for device %s, UD %s\n",
-		 num_maps,
-		 devname ? devname : "(anonymous)",
-		 name ? name : "(undefined)");
-
-	/* Add the pinmux to the global list */
-	mutex_lock(&pinmux_list_mutex);
-	list_add(&pmx->node, &pinmux_list);
-	mutex_unlock(&pinmux_list_mutex);
-
-	return pmx;
-}
-EXPORT_SYMBOL_GPL(pinmux_get);
-
-/**
- * pinmux_put() - release a previously claimed pinmux
- * @pmx: a pinmux previously claimed by pinmux_get()
- */
-void pinmux_put(struct pinmux *pmx)
-{
-	if (pmx == NULL)
-		return;
-
-	mutex_lock(&pmx->mutex);
-	if (pmx->usecount)
-		pr_warn("releasing pinmux with active users!\n");
-	/* Free the groups and all acquired pins */
-	pinmux_free_groups(pmx);
-	mutex_unlock(&pmx->mutex);
-
-	/* Remove from list */
-	mutex_lock(&pinmux_list_mutex);
-	list_del(&pmx->node);
-	mutex_unlock(&pinmux_list_mutex);
-
-	kfree(pmx);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(pinmux_put);
 
 /**
- * pinmux_enable() - enable a certain pinmux setting
- * @pmx: the pinmux to enable, previously claimed by pinmux_get()
+ * pinmux_put() - free up the pinmux portions of a pin controller handle
  */
-int pinmux_enable(struct pinmux *pmx)
+void pinmux_put(struct pinctrl *p)
 {
-	int ret = 0;
+	struct list_head *node, *tmp;
 
-	if (pmx == NULL)
-		return -EINVAL;
-	mutex_lock(&pmx->mutex);
-	if (pmx->usecount++ == 0) {
-		struct pinctrl_dev *pctldev = pmx->pctldev;
-		const struct pinmux_ops *ops = pctldev->desc->pmxops;
-		struct pinmux_group *grp;
-
-		list_for_each_entry(grp, &pmx->groups, node) {
-			ret = ops->enable(pctldev, pmx->func_selector,
-					  grp->group_selector);
-			if (ret) {
-				/*
-				 * TODO: call disable() on all groups we called
-				 * enable() on to this point?
-				 */
-				pmx->usecount--;
-				break;
-			}
-		}
+	list_for_each_safe(node, tmp, &p->groups) {
+		struct pinmux_group *grp =
+			list_entry(node, struct pinmux_group, node);
+		/* Release all pins taken by this group */
+		release_pins(p->pctldev, grp->group_selector);
+		list_del(node);
+		kfree(grp);
 	}
-	mutex_unlock(&pmx->mutex);
-	return ret;
 }
-EXPORT_SYMBOL_GPL(pinmux_enable);
 
 /**
- * pinmux_disable() - disable a certain pinmux setting
- * @pmx: the pinmux to disable, previously claimed by pinmux_get()
+ * pinmux_enable() - enable the pinmux portion of a pin control handle
  */
-void pinmux_disable(struct pinmux *pmx)
-{
-	if (pmx == NULL)
-		return;
-
-	mutex_lock(&pmx->mutex);
-	if (--pmx->usecount == 0) {
-		struct pinctrl_dev *pctldev = pmx->pctldev;
-		const struct pinmux_ops *ops = pctldev->desc->pmxops;
-		struct pinmux_group *grp;
-
-		list_for_each_entry(grp, &pmx->groups, node) {
-			ops->disable(pctldev, pmx->func_selector,
-				     grp->group_selector);
-		}
-	}
-	mutex_unlock(&pmx->mutex);
-}
-EXPORT_SYMBOL_GPL(pinmux_disable);
-
-int pinmux_check_ops(struct pinctrl_dev *pctldev)
+int pinmux_enable(struct pinctrl *p)
 {
+	struct pinctrl_dev *pctldev = p->pctldev;
 	const struct pinmux_ops *ops = pctldev->desc->pmxops;
-	unsigned selector = 0;
-
-	/* Check that we implement required operations */
-	if (!ops->list_functions ||
-	    !ops->get_function_name ||
-	    !ops->get_function_groups ||
-	    !ops->enable ||
-	    !ops->disable)
-		return -EINVAL;
-
-	/* Check that all functions registered have names */
-	while (ops->list_functions(pctldev, selector) >= 0) {
-		const char *fname = ops->get_function_name(pctldev,
-							   selector);
-		if (!fname) {
-			pr_err("pinmux ops has no name for function%u\n",
-				selector);
-			return -EINVAL;
-		}
-		selector++;
-	}
-
-	return 0;
-}
-
-/* Hog a single map entry and add to the hoglist */
-static int pinmux_hog_map(struct pinctrl_dev *pctldev,
-			  struct pinmux_map const *map)
-{
-	struct pinmux_hog *hog;
-	struct pinmux *pmx;
-	int ret;
-
-	if (map->dev || map->dev_name) {
-		/*
-		 * TODO: the day we have device tree support, we can
-		 * traverse the device tree and hog to specific device nodes
-		 * without any problems, so then we can hog pinmuxes for
-		 * all devices that just want a static pin mux at this point.
-		 */
-		dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n",
-				map->name);
-		return -EINVAL;
-	}
-
-	hog = kzalloc(sizeof(struct pinmux_hog), GFP_KERNEL);
-	if (!hog)
-		return -ENOMEM;
-
-	pmx = pinmux_get(NULL, map->name);
-	if (IS_ERR(pmx)) {
-		kfree(hog);
-		dev_err(pctldev->dev,
-			"could not get the %s pinmux mapping for hogging\n",
-			map->name);
-		return PTR_ERR(pmx);
-	}
-
-	ret = pinmux_enable(pmx);
-	if (ret) {
-		pinmux_put(pmx);
-		kfree(hog);
-		dev_err(pctldev->dev,
-			"could not enable the %s pinmux mapping for hogging\n",
-			map->name);
-		return ret;
-	}
-
-	hog->map = map;
-	hog->pmx = pmx;
-
-	dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name,
-		 map->function);
-	mutex_lock(&pctldev->pinmux_hogs_lock);
-	list_add(&hog->node, &pctldev->pinmux_hogs);
-	mutex_unlock(&pctldev->pinmux_hogs_lock);
-
-	return 0;
-}
-
-/**
- * pinmux_hog_maps() - hog specific map entries on controller device
- * @pctldev: the pin control device to hog entries on
- *
- * When the pin controllers are registered, there may be some specific pinmux
- * map entries that need to be hogged, i.e. get+enabled until the system shuts
- * down.
- */
-int pinmux_hog_maps(struct pinctrl_dev *pctldev)
-{
-	struct device *dev = pctldev->dev;
-	const char *devname = dev_name(dev);
+	struct pinmux_group *grp;
 	int ret;
-	int i;
-
-	INIT_LIST_HEAD(&pctldev->pinmux_hogs);
-	mutex_init(&pctldev->pinmux_hogs_lock);
-
-	for (i = 0; i < pinmux_maps_num; i++) {
-		struct pinmux_map const *map = &pinmux_maps[i];
-
-		if (!map->hog_on_boot)
-			continue;
 
-		if ((map->ctrl_dev == dev) ||
-			(map->ctrl_dev_name &&
-				!strcmp(map->ctrl_dev_name, devname))) {
-			/* OK time to hog! */
-			ret = pinmux_hog_map(pctldev, map);
-			if (ret)
-				return ret;
-		}
+	list_for_each_entry(grp, &p->groups, node) {
+		ret = ops->enable(pctldev, p->func_selector,
+				  grp->group_selector);
+		if (ret)
+			/*
+			 * TODO: call disable() on all groups we called
+			 * enable() on to this point?
+			 */
+			return ret;
 	}
 	return 0;
 }
 
 /**
- * pinmux_unhog_maps() - unhog specific map entries on controller device
- * @pctldev: the pin control device to unhog entries on
+ * pinmux_disable() - disable the pinmux portions of a pin control handle
  */
-void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
+void pinmux_disable(struct pinctrl *p)
 {
-	struct list_head *node, *tmp;
+	struct pinctrl_dev *pctldev = p->pctldev;
+	const struct pinmux_ops *ops = pctldev->desc->pmxops;
+	struct pinmux_group *grp;
 
-	mutex_lock(&pctldev->pinmux_hogs_lock);
-	list_for_each_safe(node, tmp, &pctldev->pinmux_hogs) {
-		struct pinmux_hog *hog =
-			list_entry(node, struct pinmux_hog, node);
-		pinmux_disable(hog->pmx);
-		pinmux_put(hog->pmx);
-		list_del(node);
-		kfree(hog);
+	list_for_each_entry(grp, &p->groups, node) {
+		ops->disable(pctldev, p->func_selector,
+			     grp->group_selector);
 	}
-	mutex_unlock(&pctldev->pinmux_hogs_lock);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -1091,85 +652,29 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
 	return 0;
 }
 
-static int pinmux_hogs_show(struct seq_file *s, void *what)
+void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p)
 {
-	struct pinctrl_dev *pctldev = s->private;
-	struct pinmux_hog *hog;
-
-	seq_puts(s, "Pinmux map hogs held by device\n");
-
-	list_for_each_entry(hog, &pctldev->pinmux_hogs, node)
-		seq_printf(s, "%s\n", hog->map->name);
-
-	return 0;
-}
-
-static int pinmux_show(struct seq_file *s, void *what)
-{
-	struct pinmux *pmx;
-
-	seq_puts(s, "Requested pinmuxes and their maps:\n");
-	list_for_each_entry(pmx, &pinmux_list, node) {
-		struct pinctrl_dev *pctldev = pmx->pctldev;
-		const struct pinmux_ops *pmxops;
-		const struct pinctrl_ops *pctlops;
-		struct pinmux_group *grp;
-
-		if (!pctldev) {
-			seq_puts(s, "NO PIN CONTROLLER DEVICE\n");
-			continue;
-		}
-
-		pmxops = pctldev->desc->pmxops;
-		pctlops = pctldev->desc->pctlops;
-
-		seq_printf(s, "device: %s function: %s (%u),",
-			   pinctrl_dev_get_name(pmx->pctldev),
-			   pmxops->get_function_name(pctldev,
-				   pmx->func_selector),
-			   pmx->func_selector);
-
-		seq_printf(s, " groups: [");
-		list_for_each_entry(grp, &pmx->groups, node) {
-			seq_printf(s, " %s (%u)",
-				   pctlops->get_group_name(pctldev,
-					   grp->group_selector),
-				   grp->group_selector);
-		}
-		seq_printf(s, " ]");
-
-		seq_printf(s, " users: %u map-> %s\n",
-			   pmx->usecount,
-			   pmx->dev ? dev_name(pmx->dev) : "(system)");
-	}
+	struct pinctrl_dev *pctldev = p->pctldev;
+	const struct pinmux_ops *pmxops;
+	const struct pinctrl_ops *pctlops;
+	struct pinmux_group *grp;
 
-	return 0;
-}
+	pmxops = pctldev->desc->pmxops;
+	pctlops = pctldev->desc->pctlops;
 
-static int pinmux_maps_show(struct seq_file *s, void *what)
-{
-	int i;
+	seq_printf(s, " function: %s (%u),",
+		   pmxops->get_function_name(pctldev,
+					     p->func_selector),
+		   p->func_selector);
 
-	seq_puts(s, "Pinmux maps:\n");
-
-	for (i = 0; i < pinmux_maps_num; i++) {
-		struct pinmux_map const *map = &pinmux_maps[i];
-
-		seq_printf(s, "%s:\n", map->name);
-		if (map->dev || map->dev_name)
-			seq_printf(s, "  device: %s\n",
-				   map->dev ? dev_name(map->dev) :
-				   map->dev_name);
-		else
-			seq_printf(s, "  SYSTEM MUX\n");
-		seq_printf(s, "  controlling device %s\n",
-			   map->ctrl_dev ? dev_name(map->ctrl_dev) :
-			   map->ctrl_dev_name);
-		seq_printf(s, "  function: %s\n", map->function);
-		seq_printf(s, "  group: %s\n", map->group ? map->group :
-			   "(default)");
+	seq_printf(s, " groups: [");
+	list_for_each_entry(grp, &p->groups, node) {
+		seq_printf(s, " %s (%u)",
+			   pctlops->get_group_name(pctldev,
+						   grp->group_selector),
+			   grp->group_selector);
 	}
-	return 0;
+	seq_printf(s, " ]");
 }
 
 static int pinmux_functions_open(struct inode *inode, struct file *file)
@@ -1182,21 +687,6 @@ static int pinmux_pins_open(struct inode *inode, struct file *file)
 	return single_open(file, pinmux_pins_show, inode->i_private);
 }
 
-static int pinmux_hogs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pinmux_hogs_show, inode->i_private);
-}
-
-static int pinmux_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pinmux_show, NULL);
-}
-
-static int pinmux_maps_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, pinmux_maps_show, NULL);
-}
-
 static const struct file_operations pinmux_functions_ops = {
 	.open		= pinmux_functions_open,
 	.read		= seq_read,
@@ -1211,27 +701,6 @@ static const struct file_operations pinmux_pins_ops = {
 	.release	= single_release,
 };
 
-static const struct file_operations pinmux_hogs_ops = {
-	.open		= pinmux_hogs_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static const struct file_operations pinmux_ops = {
-	.open		= pinmux_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static const struct file_operations pinmux_maps_ops = {
-	.open		= pinmux_maps_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
 void pinmux_init_device_debugfs(struct dentry *devroot,
 			 struct pinctrl_dev *pctldev)
 {
@@ -1239,16 +708,6 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
 			    devroot, pctldev, &pinmux_functions_ops);
 	debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO,
 			    devroot, pctldev, &pinmux_pins_ops);
-	debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO,
-			    devroot, pctldev, &pinmux_hogs_ops);
-}
-
-void pinmux_init_debugfs(struct dentry *subsys_root)
-{
-	debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO,
-			    subsys_root, NULL, &pinmux_ops);
-	debugfs_create_file("pinmux-maps", S_IFREG | S_IRUGO,
-			    subsys_root, NULL, &pinmux_maps_ops);
 }
 
 #endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
index 97f5222..84b8fe9 100644
--- a/drivers/pinctrl/pinmux.h
+++ b/drivers/pinctrl/pinmux.h
@@ -13,11 +13,30 @@
 #ifdef CONFIG_PINMUX
 
 int pinmux_check_ops(struct pinctrl_dev *pctldev);
+int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range,
+			unsigned pin, unsigned gpio);
+void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin,
+		      struct pinctrl_gpio_range *range);
+int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+			  struct pinctrl_gpio_range *range,
+			  unsigned pin, bool input);
+static inline void pinmux_init_pinctrl_handle(struct pinctrl *p)
+{
+	p->func_selector = UINT_MAX;
+	INIT_LIST_HEAD(&p->groups);
+}
+int pinmux_apply_muxmap(struct pinctrl_dev *pctldev,
+			struct pinctrl *p,
+			struct device *dev,
+			const char *devname,
+			struct pinctrl_map const *map);
+void pinmux_put(struct pinctrl *p);
+int pinmux_enable(struct pinctrl *p);
+void pinmux_disable(struct pinctrl *p);
 void pinmux_init_device_debugfs(struct dentry *devroot,
 				struct pinctrl_dev *pctldev);
-void pinmux_init_debugfs(struct dentry *subsys_root);
-int pinmux_hog_maps(struct pinctrl_dev *pctldev);
-void pinmux_unhog_maps(struct pinctrl_dev *pctldev);
+void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p);
 
 #else
 
@@ -26,21 +45,57 @@ static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
 	return 0;
 }
 
-static inline void pinmux_init_device_debugfs(struct dentry *devroot,
-					      struct pinctrl_dev *pctldev)
+static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range,
+			unsigned pin, unsigned gpio)
 {
+	return 0;
 }
 
-static inline void pinmux_init_debugfs(struct dentry *subsys_root)
+static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev,
+				    unsigned pin,
+				    struct pinctrl_gpio_range *range)
 {
 }
 
-static inline int pinmux_hog_maps(struct pinctrl_dev *pctldev)
+static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned pin, bool input)
 {
 	return 0;
 }
 
-static inline void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
+static inline void pinmux_init_pinctrl_handle(struct pinctrl *p)
+{
+}
+
+static inline int pinmux_apply_muxmap(struct pinctrl_dev *pctldev,
+				      struct pinctrl *p,
+				      struct device *dev,
+				      const char *devname,
+				      struct pinctrl_map const *map)
+{
+	return 0;
+}
+
+static inline void pinmux_put(struct pinctrl *p)
+{
+}
+
+static inline int pinmux_enable(struct pinctrl *p)
+{
+}
+
+static inline void pinmux_disable(struct pinctrl *p)
+{
+}
+
+static inline void pinmux_init_device_debugfs(struct dentry *devroot,
+					      struct pinctrl_dev *pctldev)
+{
+}
+
+static inline void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p)
 {
 }
 
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index f995e6e..86720bc 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -672,33 +672,11 @@ config INTEL_MID_POWER_BUTTON
 
 config INTEL_MFLD_THERMAL
        tristate "Thermal driver for Intel Medfield platform"
-       depends on INTEL_SCU_IPC && THERMAL
+       depends on MFD_INTEL_MSIC && THERMAL
        help
          Say Y here to enable thermal driver support for the  Intel Medfield
          platform.
 
-config RAR_REGISTER
-	bool "Restricted Access Region Register Driver"
-	depends on PCI && X86_MRST
-	default n
-	---help---
-	  This driver allows other kernel drivers access to the
-	  contents of the restricted access region control registers.
-
-	  The restricted access region control registers
-	  (rar_registers) are used to pass address and
-	  locking information on restricted access regions
-	  to other drivers that use restricted access regions.
-
-	  The restricted access regions are regions of memory
-	  on the Intel MID Platform that are not accessible to
-	  the x86 processor, but are accessible to dedicated
-	  processors on board peripheral devices.
-
-	  The purpose of the restricted access regions is to
-	  protect sensitive data from compromise by unauthorized
-	  programs running on the x86 processor.
-
 config INTEL_IPS
 	tristate "Intel Intelligent Power Sharing"
 	depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 293a320..1b6665e 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -34,7 +34,6 @@ obj-$(CONFIG_TOSHIBA_BT_RFKILL)	+= toshiba_bluetooth.o
 obj-$(CONFIG_INTEL_SCU_IPC)	+= intel_scu_ipc.o
 obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
 obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
-obj-$(CONFIG_RAR_REGISTER)	+= intel_rar_register.o
 obj-$(CONFIG_INTEL_IPS)		+= intel_ips.o
 obj-$(CONFIG_GPIO_INTEL_PMIC)	+= intel_pmic_gpio.o
 obj-$(CONFIG_XO1_RFKILL)	+= xo1-rfkill.o
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 760c6d7..833c0ec 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -50,7 +50,7 @@
  */
 #undef START_IN_KERNEL_MODE
 
-#define DRV_VER "0.5.24"
+#define DRV_VER "0.5.26"
 
 /*
  * According to the Atom N270 datasheet,
@@ -83,8 +83,8 @@ static int kernelmode;
 #endif
 
 static unsigned int interval = 10;
-static unsigned int fanon = 63000;
-static unsigned int fanoff = 58000;
+static unsigned int fanon = 60000;
+static unsigned int fanoff = 53000;
 static unsigned int verbose;
 static unsigned int fanstate = ACERHDF_FAN_AUTO;
 static char force_bios[16];
@@ -150,6 +150,8 @@ static const struct bios_settings_t bios_tbl[] = {
 	{"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} },
 	{"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} },
 	{"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
+	/* LT1005u */
+	{"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} },
 	/* Acer 1410 */
 	{"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
 	{"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} },
@@ -161,6 +163,7 @@ static const struct bios_settings_t bios_tbl[] = {
 	{"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} },
 	{"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} },
 	{"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },
+	{"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },
 	/* Acer 1810xx */
 	{"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
 	{"Acer", "Aspire 1810T",  "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
@@ -183,29 +186,44 @@ static const struct bios_settings_t bios_tbl[] = {
 	{"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} },
 	{"Acer", "Aspire 1810T",  "v1.3310", 0x55, 0x58, {0x9e, 0x00} },
 	{"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} },
+	{"Acer", "Aspire 1810T",  "v1.3314", 0x55, 0x58, {0x9e, 0x00} },
 	/* Acer 531 */
+	{"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} },
 	{"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} },
+	{"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} },
+	/* Acer 751 */
+	{"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} },
+	/* Acer 1825 */
+	{"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} },
+	{"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} },
+	/* Acer TravelMate 7730 */
+	{"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} },
 	/* Gateway */
-	{"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
-	{"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} },
-	{"Gateway", "LT31",   "v1.3103", 0x55, 0x58, {0x9e, 0x00} },
-	{"Gateway", "LT31",   "v1.3201", 0x55, 0x58, {0x9e, 0x00} },
-	{"Gateway", "LT31",   "v1.3302", 0x55, 0x58, {0x9e, 0x00} },
+	{"Gateway", "AOA110", "v0.3103",  0x55, 0x58, {0x21, 0x00} },
+	{"Gateway", "AOA150", "v0.3103",  0x55, 0x58, {0x20, 0x00} },
+	{"Gateway", "LT31",   "v1.3103",  0x55, 0x58, {0x9e, 0x00} },
+	{"Gateway", "LT31",   "v1.3201",  0x55, 0x58, {0x9e, 0x00} },
+	{"Gateway", "LT31",   "v1.3302",  0x55, 0x58, {0x9e, 0x00} },
+	{"Gateway", "LT31",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00} },
 	/* Packard Bell */
-	{"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} },
-	{"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
-	{"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
-	{"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} },
-	{"Packard Bell", "DOTMU",  "v1.3303", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v0.3120", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v0.3108", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v0.3113", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v0.3115", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v0.3117", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v0.3119", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMU",  "v1.3204", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMA",  "v1.3201", 0x55, 0x58, {0x9e, 0x00} },
-	{"Packard Bell", "DOTMA",  "v1.3302", 0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOA150",  "v0.3104",  0x55, 0x58, {0x21, 0x00} },
+	{"Packard Bell", "DOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00} },
+	{"Packard Bell", "AOA110",  "v0.3105",  0x55, 0x58, {0x21, 0x00} },
+	{"Packard Bell", "AOA150",  "v0.3105",  0x55, 0x58, {0x20, 0x00} },
+	{"Packard Bell", "ENBFT",   "V1.3118",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "ENBFT",   "V1.3127",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v1.3303",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v0.3120",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v0.3108",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v0.3113",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v0.3115",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v0.3117",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v0.3119",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMU",   "v1.3204",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMA",   "v1.3201",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMA",   "v1.3302",  0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTMA",   "v1.3303t", 0x55, 0x58, {0x9e, 0x00} },
+	{"Packard Bell", "DOTVR46", "v1.3308",  0x55, 0x58, {0x9e, 0x00} },
 	/* pewpew-terminator */
 	{"", "", "", 0, 0, {0, 0} }
 };
@@ -704,15 +722,20 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Peter Feuerer");
 MODULE_DESCRIPTION("Aspire One temperature and fan driver");
 MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:");
 MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:");
 MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:");
+MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:");
 MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:");
+MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:");
 MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:");
 MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:");
 MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:");
 MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:");
 MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:");
+MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:");
 MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:");
+MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:");
 
 module_init(acerhdf_init);
 module_exit(acerhdf_exit);
diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c
index 5a34973..ba68d4e 100644
--- a/drivers/platform/x86/hdaps.c
+++ b/drivers/platform/x86/hdaps.c
@@ -379,7 +379,7 @@ static ssize_t hdaps_temp1_show(struct device *dev,
 	int ret;
 
 	ret = hdaps_readb_one(HDAPS_PORT_TEMP1, &temp);
-	if (ret < 0)
+	if (ret)
 		return ret;
 
 	return sprintf(buf, "%u\n", temp);
@@ -392,7 +392,7 @@ static ssize_t hdaps_temp2_show(struct device *dev,
 	int ret;
 
 	ret = hdaps_readb_one(HDAPS_PORT_TEMP2, &temp);
-	if (ret < 0)
+	if (ret)
 		return ret;
 
 	return sprintf(buf, "%u\n", temp);
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
index f1ae507..bcbad84 100644
--- a/drivers/platform/x86/intel_mid_powerbtn.c
+++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -23,21 +23,27 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-
-#include <asm/intel_scu_ipc.h>
+#include <linux/mfd/intel_msic.h>
 
 #define DRIVER_NAME "msic_power_btn"
 
-#define MSIC_PB_STATUS	0x3f
 #define MSIC_PB_LEVEL	(1 << 3) /* 1 - release, 0 - press */
 
+/*
+ * MSIC document ti_datasheet defines the 1st bit reg 0x21 is used to mask
+ * power button interrupt
+ */
+#define MSIC_PWRBTNM    (1 << 0)
+
 static irqreturn_t mfld_pb_isr(int irq, void *dev_id)
 {
 	struct input_dev *input = dev_id;
 	int ret;
 	u8 pbstat;
 
-	ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat);
+	ret = intel_msic_reg_read(INTEL_MSIC_PBSTATUS, &pbstat);
+	dev_dbg(input->dev.parent, "PB_INT status= %d\n", pbstat);
+
 	if (ret < 0) {
 		dev_err(input->dev.parent, "Read error %d while reading"
 			       " MSIC_PB_STATUS\n", ret);
@@ -72,7 +78,7 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev)
 
 	input_set_capability(input, EV_KEY, KEY_POWER);
 
-	error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0,
+	error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND,
 			DRIVER_NAME, input);
 	if (error) {
 		dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
@@ -88,6 +94,24 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, input);
+
+	/*
+	 * SCU firmware might send power button interrupts to IA core before
+	 * kernel boots and doesn't get EOI from IA core. The first bit of
+	 * MSIC reg 0x21 is kept masked, and SCU firmware doesn't send new
+	 * power interrupt to Android kernel. Unmask the bit when probing
+	 * power button in kernel.
+	 * There is a very narrow race between irq handler and power button
+	 * initialization. The race happens rarely. So we needn't worry
+	 * about it.
+	 */
+	error = intel_msic_reg_update(INTEL_MSIC_IRQLVL1MSK, 0, MSIC_PWRBTNM);
+	if (error) {
+		dev_err(&pdev->dev, "Unable to clear power button interrupt, "
+				"error: %d\n", error);
+		goto err_free_irq;
+	}
+
 	return 0;
 
 err_free_irq:
@@ -118,17 +142,7 @@ static struct platform_driver mfld_pb_driver = {
 	.remove	= __devexit_p(mfld_pb_remove),
 };
 
-static int __init mfld_pb_init(void)
-{
-	return platform_driver_register(&mfld_pb_driver);
-}
-module_init(mfld_pb_init);
-
-static void __exit mfld_pb_exit(void)
-{
-	platform_driver_unregister(&mfld_pb_driver);
-}
-module_exit(mfld_pb_exit);
+module_platform_driver(mfld_pb_driver);
 
 MODULE_AUTHOR("Hong Liu <hong.liu@intel.com>");
 MODULE_DESCRIPTION("Intel Medfield Power Button Driver");
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
index ccd7b1f..9a10b9e 100644
--- a/drivers/platform/x86/intel_mid_thermal.c
+++ b/drivers/platform/x86/intel_mid_thermal.c
@@ -33,18 +33,15 @@
 #include <linux/slab.h>
 #include <linux/pm.h>
 #include <linux/thermal.h>
-
-#include <asm/intel_scu_ipc.h>
+#include <linux/mfd/intel_msic.h>
 
 /* Number of thermal sensors */
 #define MSIC_THERMAL_SENSORS	4
 
 /* ADC1 - thermal registers */
-#define MSIC_THERM_ADC1CNTL1	0x1C0
 #define MSIC_ADC_ENBL		0x10
 #define MSIC_ADC_START		0x08
 
-#define MSIC_THERM_ADC1CNTL3	0x1C2
 #define MSIC_ADCTHERM_ENBL	0x04
 #define MSIC_ADCRRDATA_ENBL	0x05
 #define MSIC_CHANL_MASK_VAL	0x0F
@@ -75,8 +72,8 @@
 #define ADC_VAL60C		315
 
 /* ADC base addresses */
-#define ADC_CHNL_START_ADDR	0x1C5	/* increments by 1 */
-#define ADC_DATA_START_ADDR	0x1D4	/* increments by 2 */
+#define ADC_CHNL_START_ADDR	INTEL_MSIC_ADC1ADDR0	/* increments by 1 */
+#define ADC_DATA_START_ADDR	INTEL_MSIC_ADC1SNS0H	/* increments by 2 */
 
 /* MSIC die attributes */
 #define MSIC_DIE_ADC_MIN	488
@@ -189,17 +186,17 @@ static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
 	addr = td_info->chnl_addr;
 
 	/* Enable the msic for conversion before reading */
-	ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
+	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
 	if (ret)
 		return ret;
 
 	/* Re-toggle the RRDATARD bit (temporary workaround) */
-	ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
+	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
 	if (ret)
 		return ret;
 
 	/* Read the higher bits of data */
-	ret = intel_scu_ipc_ioread8(addr, &data);
+	ret = intel_msic_reg_read(addr, &data);
 	if (ret)
 		return ret;
 
@@ -207,7 +204,7 @@ static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
 	adc_val = (data << 2);
 	addr++;
 
-	ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */
+	ret = intel_msic_reg_read(addr, &data);/* Read lower bits */
 	if (ret)
 		return ret;
 
@@ -235,7 +232,7 @@ static int configure_adc(int val)
 	int ret;
 	uint8_t data;
 
-	ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
+	ret = intel_msic_reg_read(INTEL_MSIC_ADC1CNTL1, &data);
 	if (ret)
 		return ret;
 
@@ -246,7 +243,7 @@ static int configure_adc(int val)
 		/* Just stop the ADC */
 		data &= (~MSIC_ADC_START);
 	}
-	return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data);
+	return intel_msic_reg_write(INTEL_MSIC_ADC1CNTL1, data);
 }
 
 /**
@@ -262,21 +259,21 @@ static int set_up_therm_channel(u16 base_addr)
 	int ret;
 
 	/* Enable all the sensor channels */
-	ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE);
+	ret = intel_msic_reg_write(base_addr, SKIN_SENSOR0_CODE);
 	if (ret)
 		return ret;
 
-	ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE);
+	ret = intel_msic_reg_write(base_addr + 1, SKIN_SENSOR1_CODE);
 	if (ret)
 		return ret;
 
-	ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE);
+	ret = intel_msic_reg_write(base_addr + 2, SYS_SENSOR_CODE);
 	if (ret)
 		return ret;
 
 	/* Since this is the last channel, set the stop bit
 	 * to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
-	ret = intel_scu_ipc_iowrite8(base_addr + 3,
+	ret = intel_msic_reg_write(base_addr + 3,
 			(MSIC_DIE_SENSOR_CODE | 0x10));
 	if (ret)
 		return ret;
@@ -295,11 +292,11 @@ static int reset_stopbit(uint16_t addr)
 {
 	int ret;
 	uint8_t data;
-	ret = intel_scu_ipc_ioread8(addr, &data);
+	ret = intel_msic_reg_read(addr, &data);
 	if (ret)
 		return ret;
 	/* Set the stop bit to zero */
-	return intel_scu_ipc_iowrite8(addr, (data & 0xEF));
+	return intel_msic_reg_write(addr, (data & 0xEF));
 }
 
 /**
@@ -322,7 +319,7 @@ static int find_free_channel(void)
 	uint8_t data;
 
 	/* check whether ADC is enabled */
-	ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
+	ret = intel_msic_reg_read(INTEL_MSIC_ADC1CNTL1, &data);
 	if (ret)
 		return ret;
 
@@ -331,7 +328,7 @@ static int find_free_channel(void)
 
 	/* ADC is already enabled; Looking for an empty channel */
 	for (i = 0; i < ADC_CHANLS_MAX; i++) {
-		ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data);
+		ret = intel_msic_reg_read(ADC_CHNL_START_ADDR + i, &data);
 		if (ret)
 			return ret;
 
@@ -359,12 +356,14 @@ static int mid_initialize_adc(struct device *dev)
 	 * Ensure that adctherm is disabled before we
 	 * initialize the ADC
 	 */
-	ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data);
+	ret = intel_msic_reg_read(INTEL_MSIC_ADC1CNTL3, &data);
 	if (ret)
 		return ret;
 
-	if (data & MSIC_ADCTHERM_MASK)
-		dev_warn(dev, "ADCTHERM already set");
+	data &= ~MSIC_ADCTHERM_MASK;
+	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, data);
+	if (ret)
+		return ret;
 
 	/* Index of the first channel in which the stop bit is set */
 	channel_index = find_free_channel();
@@ -546,7 +545,7 @@ static int mid_thermal_remove(struct platform_device *pdev)
 	return configure_adc(0);
 }
 
-#define DRIVER_NAME "msic_sensor"
+#define DRIVER_NAME "msic_thermal"
 
 static const struct platform_device_id therm_id_table[] = {
 	{ DRIVER_NAME, 1 },
@@ -565,18 +564,7 @@ static struct platform_driver mid_thermal_driver = {
 	.id_table = therm_id_table,
 };
 
-static int __init mid_thermal_module_init(void)
-{
-	return platform_driver_register(&mid_thermal_driver);
-}
-
-static void __exit mid_thermal_module_exit(void)
-{
-	platform_driver_unregister(&mid_thermal_driver);
-}
-
-module_init(mid_thermal_module_init);
-module_exit(mid_thermal_module_exit);
+module_platform_driver(mid_thermal_driver);
 
 MODULE_AUTHOR("Durgadoss R <durgadoss.r@intel.com>");
 MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver");
diff --git a/drivers/platform/x86/intel_rar_register.c b/drivers/platform/x86/intel_rar_register.c
deleted file mode 100644
index c8a6aed..0000000
--- a/drivers/platform/x86/intel_rar_register.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- *  rar_register.c - An Intel Restricted Access Region register driver
- *
- *  Copyright(c) 2009 Intel Corporation. All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License as
- *  published by the Free Software Foundation; 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., 59 Temple Place - Suite 330, Boston, MA
- *  02111-1307, USA.
- *
- * -------------------------------------------------------------------
- *  20091204 Mark Allyn <mark.a.allyn@intel.com>
- *	     Ossama Othman <ossama.othman@intel.com>
- *	Cleanup per feedback from Alan Cox and Arjan Van De Ven
- *
- *  20090806 Ossama Othman <ossama.othman@intel.com>
- *      Return zero high address if upper 22 bits is zero.
- *      Cleaned up checkpatch errors.
- *      Clarified that driver is dealing with bus addresses.
- *
- *  20090702 Ossama Othman <ossama.othman@intel.com>
- *      Removed unnecessary include directives
- *      Cleaned up spinlocks.
- *      Cleaned up logging.
- *      Improved invalid parameter checks.
- *      Fixed and simplified RAR address retrieval and RAR locking
- *      code.
- *
- *  20090626 Mark Allyn <mark.a.allyn@intel.com>
- *      Initial publish
- */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/rar_register.h>
-
-/* === Lincroft Message Bus Interface === */
-#define LNC_MCR_OFFSET		0xD0	/* Message Control Register */
-#define LNC_MDR_OFFSET		0xD4	/* Message Data Register */
-
-/* Message Opcodes */
-#define LNC_MESSAGE_READ_OPCODE	0xD0
-#define LNC_MESSAGE_WRITE_OPCODE 0xE0
-
-/* Message Write Byte Enables */
-#define LNC_MESSAGE_BYTE_WRITE_ENABLES	0xF
-
-/* B-unit Port */
-#define LNC_BUNIT_PORT	0x3
-
-/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
-#define LNC_BRAR0L	0x10
-#define LNC_BRAR0H	0x11
-#define LNC_BRAR1L	0x12
-#define LNC_BRAR1H	0x13
-/* Reserved for SeP */
-#define LNC_BRAR2L	0x14
-#define LNC_BRAR2H	0x15
-
-/* Moorestown supports three restricted access regions. */
-#define MRST_NUM_RAR 3
-
-/* RAR Bus Address Range */
-struct rar_addr {
-	dma_addr_t low;
-	dma_addr_t high;
-};
-
-/*
- *	We create one of these for each RAR
- */
-struct client {
-	int (*callback)(unsigned long data);
-	unsigned long driver_priv;
-	bool busy;
-};
-
-static DEFINE_MUTEX(rar_mutex);
-static DEFINE_MUTEX(lnc_reg_mutex);
-
-/*
- *	One per RAR device (currently only one device)
- */
-struct rar_device {
-	struct rar_addr rar_addr[MRST_NUM_RAR];
-	struct pci_dev *rar_dev;
-	bool registered;
-	bool allocated;
-	struct client client[MRST_NUM_RAR];
-};
-
-/* Current platforms have only one rar_device for 3 rar regions */
-static struct rar_device my_rar_device;
-
-/*
- *	Abstract out multiple device support. Current platforms only
- *	have a single RAR device.
- */
-
-/**
- *	alloc_rar_device	-	return a new RAR structure
- *
- *	Return a new (but not yet ready) RAR device object
- */
-static struct rar_device *alloc_rar_device(void)
-{
-	if (my_rar_device.allocated)
-		return NULL;
-	my_rar_device.allocated = 1;
-	return &my_rar_device;
-}
-
-/**
- *	free_rar_device		-	free a RAR object
- *	@rar: the RAR device being freed
- *
- *	Release a RAR object and any attached resources
- */
-static void free_rar_device(struct rar_device *rar)
-{
-	pci_dev_put(rar->rar_dev);
-	rar->allocated = 0;
-}
-
-/**
- *	_rar_to_device		-	return the device handling this RAR
- *	@rar: RAR number
- *	@off: returned offset
- *
- *	Internal helper for looking up RAR devices. This and alloc are the
- *	two functions that need touching to go to multiple RAR devices.
- */
-static struct rar_device *_rar_to_device(int rar, int *off)
-{
-	if (rar >= 0 && rar < MRST_NUM_RAR) {
-		*off = rar;
-		return &my_rar_device;
-	}
-	return NULL;
-}
-
-/**
- *	rar_to_device		-	return the device handling this RAR
- *	@rar: RAR number
- *	@off: returned offset
- *
- *	Return the device this RAR maps to if one is present, otherwise
- *	returns NULL. Reports the offset relative to the base of this
- *	RAR device in off.
- */
-static struct rar_device *rar_to_device(int rar, int *off)
-{
-	struct rar_device *rar_dev = _rar_to_device(rar, off);
-	if (rar_dev == NULL || !rar_dev->registered)
-		return NULL;
-	return rar_dev;
-}
-
-/**
- *	rar_to_client		-	return the client handling this RAR
- *	@rar: RAR number
- *
- *	Return the client this RAR maps to if a mapping is known, otherwise
- *	returns NULL.
- */
-static struct client *rar_to_client(int rar)
-{
-	int idx;
-	struct rar_device *r = _rar_to_device(rar, &idx);
-	if (r != NULL)
-		return &r->client[idx];
-	return NULL;
-}
-
-/**
- *	rar_read_addr		-	retrieve a RAR mapping
- *	@pdev: PCI device for the RAR
- *	@offset: offset for message
- *	@addr: returned address
- *
- *	Reads the address of a given RAR register. Returns 0 on success
- *	or an error code on failure.
- */
-static int rar_read_addr(struct pci_dev *pdev, int offset, dma_addr_t *addr)
-{
-	/*
-	 * ======== The Lincroft Message Bus Interface ========
-	 * Lincroft registers may be obtained via PCI from
-	 * the host bridge using the Lincroft Message Bus
-	 * Interface.  That message bus interface is generally
-	 * comprised of two registers: a control register (MCR, 0xDO)
-	 * and a data register (MDR, 0xD4).
-	 *
-	 * The MCR (message control register) format is the following:
-	 *   1.  [31:24]: Opcode
-	 *   2.  [23:16]: Port
-	 *   3.  [15:8]: Register Offset
-	 *   4.  [7:4]: Byte Enables (use 0xF to set all of these bits
-	 *              to 1)
-	 *   5.  [3:0]: reserved
-	 *
-	 *  Read (0xD0) and write (0xE0) opcodes are written to the
-	 *  control register when reading and writing to Lincroft
-	 *  registers, respectively.
-	 *
-	 *  We're interested in registers found in the Lincroft
-	 *  B-unit.  The B-unit port is 0x3.
-	 *
-	 *  The six B-unit RAR register offsets we use are listed
-	 *  earlier in this file.
-	 *
-	 *  Lastly writing to the MCR register requires the "Byte
-	 *  enables" bits to be set to 1.  This may be achieved by
-	 *  writing 0xF at bit 4.
-	 *
-	 * The MDR (message data register) format is the following:
-	 *   1. [31:0]: Read/Write Data
-	 *
-	 *  Data being read from this register is only available after
-	 *  writing the appropriate control message to the MCR
-	 *  register.
-	 *
-	 *  Data being written to this register must be written before
-	 *  writing the appropriate control message to the MCR
-	 *  register.
-	*/
-
-	int result;
-	u32 addr32;
-
-	/* Construct control message */
-	u32 const message =
-		 (LNC_MESSAGE_READ_OPCODE << 24)
-		 | (LNC_BUNIT_PORT << 16)
-		 | (offset << 8)
-		 | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
-
-	dev_dbg(&pdev->dev, "Offset for 'get' LNC MSG is %x\n", offset);
-
-	/*
-	* We synchronize access to the Lincroft MCR and MDR registers
-	* until BOTH the command is issued through the MCR register
-	* and the corresponding data is read from the MDR register.
-	* Otherwise a race condition would exist between accesses to
-	* both registers.
-	*/
-
-	mutex_lock(&lnc_reg_mutex);
-
-	/* Send the control message */
-	result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
-	if (!result) {
-		/* Read back the address as a 32bit value */
-		result = pci_read_config_dword(pdev, LNC_MDR_OFFSET, &addr32);
-		*addr = (dma_addr_t)addr32;
-	}
-	mutex_unlock(&lnc_reg_mutex);
-	return result;
-}
-
-/**
- *	rar_set_addr		-	Set a RAR mapping
- *	@pdev: PCI device for the RAR
- *	@offset: offset for message
- *	@addr: address to set
- *
- *	Sets the address of a given RAR register. Returns 0 on success
- *	or an error code on failure.
- */
-static int rar_set_addr(struct pci_dev *pdev,
-	int offset,
-	dma_addr_t addr)
-{
-	/*
-	* Data being written to this register must be written before
-	* writing the appropriate control message to the MCR
-	* register.
-	* See rar_get_addrs() for a description of the
-	* message bus interface being used here.
-	*/
-
-	int result;
-
-	/* Construct control message */
-	u32 const message = (LNC_MESSAGE_WRITE_OPCODE << 24)
-		| (LNC_BUNIT_PORT << 16)
-		| (offset << 8)
-		| (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
-
-	/*
-	* We synchronize access to the Lincroft MCR and MDR registers
-	* until BOTH the command is issued through the MCR register
-	* and the corresponding data is read from the MDR register.
-	* Otherwise a race condition would exist between accesses to
-	* both registers.
-	*/
-
-	mutex_lock(&lnc_reg_mutex);
-
-	/* Send the control message */
-	result = pci_write_config_dword(pdev, LNC_MDR_OFFSET, addr);
-	if (!result)
-		/* And address */
-		result = pci_write_config_dword(pdev, LNC_MCR_OFFSET, message);
-
-	mutex_unlock(&lnc_reg_mutex);
-	return result;
-}
-
-/*
- *	rar_init_params		-	Initialize RAR parameters
- *	@rar: RAR device to initialise
- *
- *	Initialize RAR parameters, such as bus addresses, etc. Returns 0
- *	on success, or an error code on failure.
- */
-static int init_rar_params(struct rar_device *rar)
-{
-	struct pci_dev *pdev = rar->rar_dev;
-	unsigned int i;
-	int result = 0;
-	int offset = 0x10;	/* RAR 0 to 2 in order low/high/low/high/... */
-
-	/* Retrieve RAR start and end bus addresses.
-	* Access the RAR registers through the Lincroft Message Bus
-	* Interface on PCI device: 00:00.0 Host bridge.
-	*/
-
-	for (i = 0; i < MRST_NUM_RAR; ++i) {
-		struct rar_addr *addr = &rar->rar_addr[i];
-
-		result = rar_read_addr(pdev, offset++, &addr->low);
-		if (result != 0)
-			return result;
-
-		result = rar_read_addr(pdev, offset++, &addr->high);
-		if (result != 0)
-			return result;
-
-
-		/*
-		* Only the upper 22 bits of the RAR addresses are
-		* stored in their corresponding RAR registers so we
-		* must set the lower 10 bits accordingly.
-
-		* The low address has its lower 10 bits cleared, and
-		* the high address has all its lower 10 bits set,
-		* e.g.:
-		* low = 0x2ffffc00
-		*/
-
-		addr->low &= (dma_addr_t)0xfffffc00u;
-
-		/*
-		* Set bits 9:0 on uppser address if bits 31:10 are non
-		* zero; otherwize clear all bits
-		*/
-
-		if ((addr->high & 0xfffffc00u) == 0)
-			addr->high = 0;
-		else
-			addr->high |= 0x3ffu;
-	}
-	/* Done accessing the device. */
-
-	if (result == 0) {
-		for (i = 0; i != MRST_NUM_RAR; ++i) {
-			/*
-			* "BRAR" refers to the RAR registers in the
-			* Lincroft B-unit.
-			*/
-			dev_info(&pdev->dev, "BRAR[%u] bus address range = "
-			  "[%lx, %lx]\n", i,
-			  (unsigned long)rar->rar_addr[i].low,
-			  (unsigned long)rar->rar_addr[i].high);
-		}
-	}
-	return result;
-}
-
-/**
- *	rar_get_address		-	get the bus address in a RAR
- *	@start: return value of start address of block
- *	@end: return value of end address of block
- *
- *	The rar_get_address function is used by other device drivers
- *	to obtain RAR address information on a RAR. It takes three
- *	parameters:
- *
- *	The function returns a 0 upon success or an error if there is no RAR
- *	facility on this system.
- */
-int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end)
-{
-	int idx;
-	struct rar_device *rar = rar_to_device(rar_index, &idx);
-
-	if (rar == NULL) {
-		WARN_ON(1);
-		return -ENODEV;
-	}
-
-	*start = rar->rar_addr[idx].low;
-	*end = rar->rar_addr[idx].high;
-	return 0;
-}
-EXPORT_SYMBOL(rar_get_address);
-
-/**
- *	rar_lock	-	lock a RAR register
- *	@rar_index: RAR to lock (0-2)
- *
- *	The rar_lock function is ued by other device drivers to lock an RAR.
- *	once a RAR is locked, it stays locked until the next system reboot.
- *
- *	The function returns a 0 upon success or an error if there is no RAR
- *	facility on this system, or the locking fails
- */
-int rar_lock(int rar_index)
-{
-	struct rar_device *rar;
-	int result;
-	int idx;
-	dma_addr_t low, high;
-
-	rar = rar_to_device(rar_index, &idx);
-
-	if (rar == NULL) {
-		WARN_ON(1);
-		return -EINVAL;
-	}
-
-	low = rar->rar_addr[idx].low & 0xfffffc00u;
-	high = rar->rar_addr[idx].high & 0xfffffc00u;
-
-	/*
-	* Only allow I/O from the graphics and Langwell;
-	* not from the x86 processor
-	*/
-
-	if (rar_index == RAR_TYPE_VIDEO) {
-		low |= 0x00000009;
-		high |= 0x00000015;
-	} else if (rar_index == RAR_TYPE_AUDIO) {
-		/* Only allow I/O from Langwell; nothing from x86 */
-		low |= 0x00000008;
-		high |= 0x00000018;
-	} else
-		/* Read-only from all agents */
-		high |= 0x00000018;
-
-	/*
-	* Now program the register using the Lincroft message
-	* bus interface.
-	*/
-	result = rar_set_addr(rar->rar_dev,
-				2 * idx, low);
-
-	if (result == 0)
-		result = rar_set_addr(rar->rar_dev,
-				2 * idx + 1, high);
-
-	return result;
-}
-EXPORT_SYMBOL(rar_lock);
-
-/**
- *	register_rar		-	register a RAR handler
- *	@num: RAR we wish to register for
- *	@callback: function to call when RAR support is available
- *	@data: data to pass to this function
- *
- *	The register_rar function is to used by other device drivers
- *	to ensure that this driver is ready. As we cannot be sure of
- *	the compile/execute order of drivers in the kernel, it is
- *	best to give this driver a callback function to call when
- *	it is ready to give out addresses. The callback function
- *	would have those steps that continue the initialization of
- *	a driver that do require a valid RAR address. One of those
- *	steps would be to call rar_get_address()
- *
- *	This function return 0 on success or an error code on failure.
- */
-int register_rar(int num, int (*callback)(unsigned long data),
-							unsigned long data)
-{
-	/* For now we hardcode a single RAR device */
-	struct rar_device *rar;
-	struct client *c;
-	int idx;
-	int retval = 0;
-
-	mutex_lock(&rar_mutex);
-
-	/* Do we have a client mapping for this RAR number ? */
-	c = rar_to_client(num);
-	if (c == NULL) {
-		retval = -ERANGE;
-		goto done;
-	}
-	/* Is it claimed ? */
-	if (c->busy) {
-		retval = -EBUSY;
-		goto done;
-	}
-	c->busy = 1;
-
-	/* See if we have a handler for this RAR yet, if we do then fire it */
-	rar = rar_to_device(num, &idx);
-
-	if (rar) {
-		/*
-		* if the driver already registered, then we can simply
-		* call the callback right now
-		*/
-		(*callback)(data);
-		goto done;
-	}
-
-	/* Arrange to be called back when the hardware is found */
-	c->callback = callback;
-	c->driver_priv = data;
-done:
-	mutex_unlock(&rar_mutex);
-	return retval;
-}
-EXPORT_SYMBOL(register_rar);
-
-/**
- *	unregister_rar	-	release a RAR allocation
- *	@num: RAR number
- *
- *	Releases a RAR allocation, or pending allocation. If a callback is
- *	pending then this function will either complete before the unregister
- *	returns or not at all.
- */
-
-void unregister_rar(int num)
-{
-	struct client *c;
-
-	mutex_lock(&rar_mutex);
-	c = rar_to_client(num);
-	if (c == NULL || !c->busy)
-		WARN_ON(1);
-	else
-		c->busy = 0;
-	mutex_unlock(&rar_mutex);
-}
-EXPORT_SYMBOL(unregister_rar);
-
-/**
- *	rar_callback		-	Process callbacks
- *	@rar: new RAR device
- *
- *	Process the callbacks for a newly found RAR device.
- */
-
-static void rar_callback(struct rar_device *rar)
-{
-	struct client *c = &rar->client[0];
-	int i;
-
-	mutex_lock(&rar_mutex);
-
-	rar->registered = 1;	/* Ensure no more callbacks queue */
-
-	for (i = 0; i < MRST_NUM_RAR; i++) {
-		if (c->callback && c->busy) {
-			c->callback(c->driver_priv);
-			c->callback = NULL;
-		}
-		c++;
-	}
-	mutex_unlock(&rar_mutex);
-}
-
-/**
- *	rar_probe		-	PCI probe callback
- *	@dev: PCI device
- *	@id: matching entry in the match table
- *
- *	A RAR device has been discovered. Initialise it and if successful
- *	process any pending callbacks that can now be completed.
- */
-static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int error;
-	struct rar_device *rar;
-
-	dev_dbg(&dev->dev, "PCI probe starting\n");
-
-	rar = alloc_rar_device();
-	if (rar == NULL)
-		return -EBUSY;
-
-	/* Enable the device */
-	error = pci_enable_device(dev);
-	if (error) {
-		dev_err(&dev->dev,
-			"Error enabling RAR register PCI device\n");
-		goto end_function;
-	}
-
-	/* Fill in the rar_device structure */
-	rar->rar_dev = pci_dev_get(dev);
-	pci_set_drvdata(dev, rar);
-
-	/*
-	 * Initialize the RAR parameters, which have to be retrieved
-	 * via the message bus interface.
-	 */
-	error = init_rar_params(rar);
-	if (error) {
-		pci_disable_device(dev);
-		dev_err(&dev->dev, "Error retrieving RAR addresses\n");
-		goto end_function;
-	}
-	/* now call anyone who has registered (using callbacks) */
-	rar_callback(rar);
-	return 0;
-end_function:
-	free_rar_device(rar);
-	return error;
-}
-
-static DEFINE_PCI_DEVICE_TABLE(rar_pci_id_tbl) = {
-	{ PCI_VDEVICE(INTEL, 0x4110) },
-	{ 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
-
-/* field for registering driver to PCI device */
-static struct pci_driver rar_pci_driver = {
-	.name = "rar_register_driver",
-	.id_table = rar_pci_id_tbl,
-	.probe = rar_probe,
-	/* Cannot be unplugged - no remove */
-};
-
-static int __init rar_init_handler(void)
-{
-	return pci_register_driver(&rar_pci_driver);
-}
-
-static void __exit rar_exit_handler(void)
-{
-	pci_unregister_driver(&rar_pci_driver);
-}
-
-module_init(rar_init_handler);
-module_exit(rar_exit_handler);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Intel Restricted Access Region Register Driver");
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index f00d0d1..9215ed7 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -159,7 +159,7 @@ static inline int busy_loop(void) /* Wait till scu status is busy */
 /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
 static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
 {
-	int i, nc, bytes, d;
+	int nc;
 	u32 offset = 0;
 	int err;
 	u8 cbuf[IPC_WWBUF_SIZE] = { };
@@ -174,55 +174,34 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
 		return -ENODEV;
 	}
 
-	if (platform != MRST_CPU_CHIP_PENWELL) {
-		bytes = 0;
-		d = 0;
-		for (i = 0; i < count; i++) {
-			cbuf[bytes++] = addr[i];
-			cbuf[bytes++] = addr[i] >> 8;
-			if (id != IPC_CMD_PCNTRL_R)
-				cbuf[bytes++] = data[d++];
-			if (id == IPC_CMD_PCNTRL_M)
-				cbuf[bytes++] = data[d++];
-		}
-		for (i = 0; i < bytes; i += 4)
-			ipc_data_writel(wbuf[i/4], i);
-		ipc_command(bytes << 16 |  id << 12 | 0 << 8 | op);
-	} else {
-		for (nc = 0; nc < count; nc++, offset += 2) {
-			cbuf[offset] = addr[nc];
-			cbuf[offset + 1] = addr[nc] >> 8;
-		}
+	for (nc = 0; nc < count; nc++, offset += 2) {
+		cbuf[offset] = addr[nc];
+		cbuf[offset + 1] = addr[nc] >> 8;
+	}
 
-		if (id == IPC_CMD_PCNTRL_R) {
-			for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
-				ipc_data_writel(wbuf[nc], offset);
-			ipc_command((count*2) << 16 |  id << 12 | 0 << 8 | op);
-		} else if (id == IPC_CMD_PCNTRL_W) {
-			for (nc = 0; nc < count; nc++, offset += 1)
-				cbuf[offset] = data[nc];
-			for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
-				ipc_data_writel(wbuf[nc], offset);
-			ipc_command((count*3) << 16 |  id << 12 | 0 << 8 | op);
-		} else if (id == IPC_CMD_PCNTRL_M) {
-			cbuf[offset] = data[0];
-			cbuf[offset + 1] = data[1];
-			ipc_data_writel(wbuf[0], 0); /* Write wbuff */
-			ipc_command(4 << 16 |  id << 12 | 0 << 8 | op);
-		}
+	if (id == IPC_CMD_PCNTRL_R) {
+		for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
+			ipc_data_writel(wbuf[nc], offset);
+		ipc_command((count*2) << 16 |  id << 12 | 0 << 8 | op);
+	} else if (id == IPC_CMD_PCNTRL_W) {
+		for (nc = 0; nc < count; nc++, offset += 1)
+			cbuf[offset] = data[nc];
+		for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
+			ipc_data_writel(wbuf[nc], offset);
+		ipc_command((count*3) << 16 |  id << 12 | 0 << 8 | op);
+	} else if (id == IPC_CMD_PCNTRL_M) {
+		cbuf[offset] = data[0];
+		cbuf[offset + 1] = data[1];
+		ipc_data_writel(wbuf[0], 0); /* Write wbuff */
+		ipc_command(4 << 16 |  id << 12 | 0 << 8 | op);
 	}
 
 	err = busy_loop();
 	if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
 		/* Workaround: values are read as 0 without memcpy_fromio */
 		memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16);
-		if (platform != MRST_CPU_CHIP_PENWELL) {
-			for (nc = 0, offset = 2; nc < count; nc++, offset += 3)
-				data[nc] = ipc_data_readb(offset);
-		} else {
-			for (nc = 0; nc < count; nc++)
-				data[nc] = ipc_data_readb(nc);
-		}
+		for (nc = 0; nc < count; nc++)
+			data[nc] = ipc_data_readb(nc);
 	}
 	mutex_unlock(&ipclock);
 	return err;
@@ -503,148 +482,6 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
 }
 EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
 
-#define IPC_FW_LOAD_ADDR 0xFFFC0000 /* Storage location for FW image */
-#define IPC_FW_UPDATE_MBOX_ADDR 0xFFFFDFF4 /* Mailbox between ipc and scu */
-#define IPC_MAX_FW_SIZE 262144 /* 256K storage size for loading the FW image */
-#define IPC_FW_MIP_HEADER_SIZE 2048 /* Firmware MIP header size */
-/* IPC inform SCU to get ready for update process */
-#define IPC_CMD_FW_UPDATE_READY  0x10FE
-/* IPC inform SCU to go for update process */
-#define IPC_CMD_FW_UPDATE_GO     0x20FE
-/* Status code for fw update */
-#define IPC_FW_UPDATE_SUCCESS	0x444f4e45 /* Status code 'DONE' */
-#define IPC_FW_UPDATE_BADN	0x4241444E /* Status code 'BADN' */
-#define IPC_FW_TXHIGH		0x54784849 /* Status code 'IPC_FW_TXHIGH' */
-#define IPC_FW_TXLOW		0x54784c4f /* Status code 'IPC_FW_TXLOW' */
-
-struct fw_update_mailbox {
-	u32    status;
-	u32    scu_flag;
-	u32    driver_flag;
-};
-
-
-/**
- *	intel_scu_ipc_fw_update	-	 Firmware update utility
- *	@buffer: firmware buffer
- *	@length: size of firmware buffer
- *
- *	This function provides an interface to load the firmware into
- *	the SCU. Returns 0 on success or -1 on failure
- */
-int intel_scu_ipc_fw_update(u8 *buffer, u32 length)
-{
-	void __iomem *fw_update_base;
-	struct fw_update_mailbox __iomem *mailbox = NULL;
-	int retry_cnt = 0;
-	u32 status;
-
-	mutex_lock(&ipclock);
-	fw_update_base = ioremap_nocache(IPC_FW_LOAD_ADDR, (128*1024));
-	if (fw_update_base == NULL) {
-		mutex_unlock(&ipclock);
-		return -ENOMEM;
-	}
-	mailbox = ioremap_nocache(IPC_FW_UPDATE_MBOX_ADDR,
-					sizeof(struct fw_update_mailbox));
-	if (mailbox == NULL) {
-		iounmap(fw_update_base);
-		mutex_unlock(&ipclock);
-		return -ENOMEM;
-	}
-
-	ipc_command(IPC_CMD_FW_UPDATE_READY);
-
-	/* Intitialize mailbox */
-	writel(0, &mailbox->status);
-	writel(0, &mailbox->scu_flag);
-	writel(0, &mailbox->driver_flag);
-
-	/* Driver copies the 2KB MIP header to SRAM at 0xFFFC0000*/
-	memcpy_toio(fw_update_base, buffer, 0x800);
-
-	/* Driver sends "FW Update" IPC command (CMD_ID 0xFE; MSG_ID 0x02).
-	* Upon receiving this command, SCU will write the 2K MIP header
-	* from 0xFFFC0000 into NAND.
-	* SCU will write a status code into the Mailbox, and then set scu_flag.
-	*/
-
-	ipc_command(IPC_CMD_FW_UPDATE_GO);
-
-	/*Driver stalls until scu_flag is set */
-	while (readl(&mailbox->scu_flag) != 1) {
-		rmb();
-		mdelay(1);
-	}
-
-	/* Driver checks Mailbox status.
-	 * If the status is 'BADN', then abort (bad NAND).
-	 * If the status is 'IPC_FW_TXLOW', then continue.
-	 */
-	while (readl(&mailbox->status) != IPC_FW_TXLOW) {
-		rmb();
-		mdelay(10);
-	}
-	mdelay(10);
-
-update_retry:
-	if (retry_cnt > 5)
-		goto update_end;
-
-	if (readl(&mailbox->status) != IPC_FW_TXLOW)
-		goto update_end;
-	buffer = buffer + 0x800;
-	memcpy_toio(fw_update_base, buffer, 0x20000);
-	writel(1, &mailbox->driver_flag);
-	while (readl(&mailbox->scu_flag) == 1) {
-		rmb();
-		mdelay(1);
-	}
-
-	/* check for 'BADN' */
-	if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN)
-		goto update_end;
-
-	while (readl(&mailbox->status) != IPC_FW_TXHIGH) {
-		rmb();
-		mdelay(10);
-	}
-	mdelay(10);
-
-	if (readl(&mailbox->status) != IPC_FW_TXHIGH)
-		goto update_end;
-
-	buffer = buffer + 0x20000;
-	memcpy_toio(fw_update_base, buffer, 0x20000);
-	writel(0, &mailbox->driver_flag);
-
-	while (mailbox->scu_flag == 0) {
-		rmb();
-		mdelay(1);
-	}
-
-	/* check for 'BADN' */
-	if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN)
-		goto update_end;
-
-	if (readl(&mailbox->status) == IPC_FW_TXLOW) {
-		++retry_cnt;
-		goto update_retry;
-	}
-
-update_end:
-	status = readl(&mailbox->status);
-
-	iounmap(fw_update_base);
-	iounmap(mailbox);
-	mutex_unlock(&ipclock);
-
-	if (status == IPC_FW_UPDATE_SUCCESS)
-		return 0;
-	return -EIO;
-}
-EXPORT_SYMBOL(intel_scu_ipc_fw_update);
-
 /*
  * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
  * When ioc bit is set to 1, caller api must wait for interrupt handler called
@@ -727,7 +564,6 @@ static void ipc_remove(struct pci_dev *pdev)
 }
 
 static DEFINE_PCI_DEVICE_TABLE(pci_ids) = {
-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)},
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)},
 	{ 0,}
 };
diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c
index 2d0f913..02bc5a6 100644
--- a/drivers/platform/x86/intel_scu_ipcutil.c
+++ b/drivers/platform/x86/intel_scu_ipcutil.c
@@ -26,13 +26,10 @@
 
 static int major;
 
-#define MAX_FW_SIZE 264192
-
 /* ioctl commnds */
 #define	INTE_SCU_IPC_REGISTER_READ	0
 #define INTE_SCU_IPC_REGISTER_WRITE	1
 #define INTE_SCU_IPC_REGISTER_UPDATE	2
-#define INTE_SCU_IPC_FW_UPDATE		0xA2
 
 struct scu_ipc_data {
 	u32     count;  /* No. of registers */
@@ -88,27 +85,14 @@ static long scu_ipc_ioctl(struct file *fp, unsigned int cmd,
 	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 
-	if (cmd == INTE_SCU_IPC_FW_UPDATE) {
-			u8 *fwbuf = kmalloc(MAX_FW_SIZE, GFP_KERNEL);
-			if (fwbuf == NULL)
-				return -ENOMEM;
-			if (copy_from_user(fwbuf, (u8 *)arg, MAX_FW_SIZE)) {
-				kfree(fwbuf);
-				return -EFAULT;
-			}
-			ret = intel_scu_ipc_fw_update(fwbuf, MAX_FW_SIZE);
-			kfree(fwbuf);
-			return ret;
-	} else {
-		if (copy_from_user(&data, argp, sizeof(struct scu_ipc_data)))
-			return -EFAULT;
-		ret = scu_reg_access(cmd, &data);
-		if (ret < 0)
-			return ret;
-		if (copy_to_user(argp, &data, sizeof(struct scu_ipc_data)))
-			return -EFAULT;
-		return 0;
-	}
+	if (copy_from_user(&data, argp, sizeof(struct scu_ipc_data)))
+		return -EFAULT;
+	ret = scu_reg_access(cmd, &data);
+	if (ret < 0)
+		return ret;
+	if (copy_to_user(argp, &data, sizeof(struct scu_ipc_data)))
+		return -EFAULT;
+	return 0;
 }
 
 static const struct file_operations scu_ipc_fops = {
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index c006dee..f5d369d 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -347,6 +347,7 @@ static void sony_laptop_report_input_event(u8 event)
 	struct input_dev *jog_dev = sony_laptop_input.jog_dev;
 	struct input_dev *key_dev = sony_laptop_input.key_dev;
 	struct sony_laptop_keypress kp = { NULL };
+	int scancode = -1;
 
 	if (event == SONYPI_EVENT_FNKEY_RELEASED ||
 			event == SONYPI_EVENT_ANYBUTTON_RELEASED) {
@@ -380,8 +381,9 @@ static void sony_laptop_report_input_event(u8 event)
 			dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
 			break;
 		}
-		if (sony_laptop_input_index[event] != -1) {
-			kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]];
+		scancode = sony_laptop_input_index[event];
+		if (scancode != -1) {
+			kp.key = sony_laptop_input_keycode_map[scancode];
 			if (kp.key != KEY_UNKNOWN)
 				kp.dev = key_dev;
 		}
@@ -389,9 +391,13 @@ static void sony_laptop_report_input_event(u8 event)
 	}
 
 	if (kp.dev) {
+		/*
+		 * If we have a scancode we emit it so we can always remap the
+		 * key
+		 */
+		if (scancode != -1)
+			input_event(kp.dev, EV_MSC, MSC_SCAN, scancode);
 		input_report_key(kp.dev, kp.key, 1);
-		/* we emit the scancode so we can always remap the key */
-		input_event(kp.dev, EV_MSC, MSC_SCAN, event);
 		input_sync(kp.dev);
 
 		/* schedule key release */
@@ -466,7 +472,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
 	jog_dev->name = "Sony Vaio Jogdial";
 	jog_dev->id.bustype = BUS_ISA;
 	jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
-	key_dev->dev.parent = &acpi_device->dev;
+	jog_dev->dev.parent = &acpi_device->dev;
 
 	input_set_capability(jog_dev, EV_KEY, BTN_MIDDLE);
 	input_set_capability(jog_dev, EV_REL, REL_WHEEL);
diff --git a/drivers/platform/x86/xo1-rfkill.c b/drivers/platform/x86/xo1-rfkill.c
index e549eee..41781ed 100644
--- a/drivers/platform/x86/xo1-rfkill.c
+++ b/drivers/platform/x86/xo1-rfkill.c
@@ -67,19 +67,8 @@ static struct platform_driver xo1_rfkill_driver = {
 	.remove		= __devexit_p(xo1_rfkill_remove),
 };
 
-static int __init xo1_rfkill_init(void)
-{
-	return platform_driver_register(&xo1_rfkill_driver);
-}
-
-static void __exit xo1_rfkill_exit(void)
-{
-	platform_driver_unregister(&xo1_rfkill_driver);
-}
+module_platform_driver(xo1_rfkill_driver);
 
 MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:xo1-rfkill");
-
-module_init(xo1_rfkill_init);
-module_exit(xo1_rfkill_exit);
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 1ed6ea0..222ccd8 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -47,10 +47,10 @@
 #define BQ27x00_REG_TTE			0x16
 #define BQ27x00_REG_TTF			0x18
 #define BQ27x00_REG_TTECP		0x26
-#define BQ27x00_REG_NAC			0x0C /* Nominal available capaciy */
+#define BQ27x00_REG_NAC			0x0C /* Nominal available capacity */
 #define BQ27x00_REG_LMD			0x12 /* Last measured discharge */
 #define BQ27x00_REG_CYCT		0x2A /* Cycle count total */
-#define BQ27x00_REG_AE			0x22 /* Available enery */
+#define BQ27x00_REG_AE			0x22 /* Available energy */
 
 #define BQ27000_REG_RSOC		0x0B /* Relative State-of-Charge */
 #define BQ27000_REG_ILMD		0x76 /* Initial last measured discharge */
diff --git a/drivers/power/max8998_charger.c b/drivers/power/max8998_charger.c
index 9b3f2bf..5c5f281 100644
--- a/drivers/power/max8998_charger.c
+++ b/drivers/power/max8998_charger.c
@@ -21,7 +21,6 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
-#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7a61b17..edcd9e2 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -136,6 +136,14 @@ config REGULATOR_MAX8998
 	  via I2C bus. The provided regulator is suitable for S3C6410
 	  and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages.
 
+config REGULATOR_S5M8767
+	tristate "Samsung S5M8767A voltage regulator"
+	depends on MFD_S5M_CORE
+	help
+	 This driver supports a Samsung S5M8767A voltage output regulator
+	 via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and
+	 supports DVS mode with 8bits of output voltage control.
+
 config REGULATOR_TWL4030
 	bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC"
 	depends on TWL4030_CORE
@@ -267,6 +275,15 @@ config REGULATOR_TPS6507X
 	  three step-down converters and two general-purpose LDO voltage regulators.
 	  It supports TI's software based Class-2 SmartReflex implementation.
 
+config REGULATOR_TPS65217
+	tristate "TI TPS65217 Power regulators"
+	depends on MFD_TPS65217
+	help
+	  This driver supports TPS65217 voltage regulator chips. TPS65217
+	  provides three step-down converters and four general-purpose LDO
+	  voltage regulators. It supports software based voltage control
+	  for different voltage domains
+
 config REGULATOR_TPS65912
 	tristate "TI TPS65912 Power regulator"
 	depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI)
@@ -299,9 +316,13 @@ config REGULATOR_AB8500
 	  This driver supports the regulators found on the ST-Ericsson mixed
 	  signal AB8500 PMIC
 
+config REGULATOR_DBX500_PRCMU
+	bool
+
 config REGULATOR_DB8500_PRCMU
 	bool "ST-Ericsson DB8500 Voltage Domain Regulators"
 	depends on MFD_DB8500_PRCMU
+	select REGULATOR_DBX500_PRCMU
 	help
 	  This driver supports the voltage domain regulators controlled by the
 	  DB8500 PRCMU
@@ -323,10 +344,20 @@ config REGULATOR_TPS6524X
 	  port controller.
 
 config REGULATOR_TPS65910
-	tristate "TI TPS65910 Power Regulator"
+	tristate "TI TPS65910/TPS65911 Power Regulators"
 	depends on MFD_TPS65910
 	help
-	  This driver supports TPS65910 voltage regulator chips.
+	  This driver supports TPS65910/TPS65911 voltage regulator chips.
+
+config REGULATOR_TPS62360
+	tristate "TI TPS62360 Power Regulator"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  This driver supports TPS62360 voltage regulator chip. This
+	  regulator is meant for processor core supply. This chip is
+	  high-frequency synchronous step down dc-dc converter optimized
+	  for battery-powered portable applications.
 
 config REGULATOR_AAT2870
 	tristate "AnalogicTech AAT2870 Regulators"
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 503bac8..4cbf8c5 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -40,13 +40,18 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
+obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o
 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
 obj-$(CONFIG_REGULATOR_AB8500)	+= ab8500.o
+obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o
 obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
 obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
+obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
 obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
+obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
+
 
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e9a83f8..beeeb7f 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -13,8 +13,6 @@
  *
  */
 
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
@@ -54,9 +52,7 @@ static LIST_HEAD(regulator_map_list);
 static bool has_full_constraints;
 static bool board_wants_dummy_regulator;
 
-#ifdef CONFIG_DEBUG_FS
 static struct dentry *debugfs_root;
-#endif
 
 /*
  * struct regulator_map
@@ -84,9 +80,7 @@ struct regulator {
 	char *supply_name;
 	struct device_attribute dev_attr;
 	struct regulator_dev *rdev;
-#ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs;
-#endif
 };
 
 static int _regulator_is_enabled(struct regulator_dev *rdev);
@@ -807,6 +801,11 @@ static void print_constraints(struct regulator_dev *rdev)
 		count += sprintf(buf + count, "standby");
 
 	rdev_info(rdev, "%s\n", buf);
+
+	if ((constraints->min_uV != constraints->max_uV) &&
+	    !(constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE))
+		rdev_warn(rdev,
+			  "Voltage range but no REGULATOR_CHANGE_VOLTAGE\n");
 }
 
 static int machine_constraints_voltage(struct regulator_dev *rdev,
@@ -996,7 +995,6 @@ static int set_supply(struct regulator_dev *rdev,
 /**
  * set_consumer_device_supply - Bind a regulator to a symbolic supply
  * @rdev:         regulator source
- * @consumer_dev: device the supply applies to
  * @consumer_dev_name: dev_name() string for device supply applies to
  * @supply:       symbolic name for supply
  *
@@ -1004,22 +1002,14 @@ static int set_supply(struct regulator_dev *rdev,
  * sources to symbolic names for supplies for use by devices.  Devices
  * should use these symbolic names to request regulators, avoiding the
  * need to provide board-specific regulator names as platform data.
- *
- * Only one of consumer_dev and consumer_dev_name may be specified.
  */
 static int set_consumer_device_supply(struct regulator_dev *rdev,
-	struct device *consumer_dev, const char *consumer_dev_name,
-	const char *supply)
+				      const char *consumer_dev_name,
+				      const char *supply)
 {
 	struct regulator_map *node;
 	int has_dev;
 
-	if (consumer_dev && consumer_dev_name)
-		return -EINVAL;
-
-	if (!consumer_dev_name && consumer_dev)
-		consumer_dev_name = dev_name(consumer_dev);
-
 	if (supply == NULL)
 		return -EINVAL;
 
@@ -1039,11 +1029,12 @@ static int set_consumer_device_supply(struct regulator_dev *rdev,
 		if (strcmp(node->supply, supply) != 0)
 			continue;
 
-		dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n",
-			dev_name(&node->regulator->dev),
-			node->regulator->desc->name,
-			supply,
-			dev_name(&rdev->dev), rdev_get_name(rdev));
+		pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n",
+			 consumer_dev_name,
+			 dev_name(&node->regulator->dev),
+			 node->regulator->desc->name,
+			 supply,
+			 dev_name(&rdev->dev), rdev_get_name(rdev));
 		return -EBUSY;
 	}
 
@@ -1142,12 +1133,10 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 			goto attr_err;
 	}
 
-#ifdef CONFIG_DEBUG_FS
 	regulator->debugfs = debugfs_create_dir(regulator->supply_name,
 						rdev->debugfs);
-	if (IS_ERR_OR_NULL(regulator->debugfs)) {
+	if (!regulator->debugfs) {
 		rdev_warn(rdev, "Failed to create debugfs directory\n");
-		regulator->debugfs = NULL;
 	} else {
 		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
 				   &regulator->uA_load);
@@ -1156,7 +1145,6 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
 				   &regulator->max_uV);
 	}
-#endif
 
 	mutex_unlock(&rdev->mutex);
 	return regulator;
@@ -1320,6 +1308,40 @@ struct regulator *regulator_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL_GPL(regulator_get);
 
+static void devm_regulator_release(struct device *dev, void *res)
+{
+	regulator_put(*(struct regulator **)res);
+}
+
+/**
+ * devm_regulator_get - Resource managed regulator_get()
+ * @dev: device for regulator "consumer"
+ * @id: Supply name or regulator ID.
+ *
+ * Managed regulator_get(). Regulators returned from this function are
+ * automatically regulator_put() on driver detach. See regulator_get() for more
+ * information.
+ */
+struct regulator *devm_regulator_get(struct device *dev, const char *id)
+{
+	struct regulator **ptr, *regulator;
+
+	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	regulator = regulator_get(dev, id);
+	if (!IS_ERR(regulator)) {
+		*ptr = regulator;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return regulator;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get);
+
 /**
  * regulator_get_exclusive - obtain exclusive access to a regulator.
  * @dev: device for regulator "consumer"
@@ -1365,9 +1387,7 @@ void regulator_put(struct regulator *regulator)
 	mutex_lock(&regulator_list_mutex);
 	rdev = regulator->rdev;
 
-#ifdef CONFIG_DEBUG_FS
 	debugfs_remove_recursive(regulator->debugfs);
-#endif
 
 	/* remove any sysfs entries */
 	if (regulator->dev) {
@@ -1387,6 +1407,34 @@ void regulator_put(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(regulator_put);
 
+static int devm_regulator_match(struct device *dev, void *res, void *data)
+{
+	struct regulator **r = res;
+	if (!r || !*r) {
+		WARN_ON(!r || !*r);
+		return 0;
+	}
+	return *r == data;
+}
+
+/**
+ * devm_regulator_put - Resource managed regulator_put()
+ * @regulator: regulator to free
+ *
+ * Deallocate a regulator allocated with devm_regulator_get(). Normally
+ * this function will not need to be called and the resource management
+ * code will ensure that the resource is freed.
+ */
+void devm_regulator_put(struct regulator *regulator)
+{
+	int rc;
+
+	rc = devres_destroy(regulator->dev, devm_regulator_release,
+			    devm_regulator_match, regulator);
+	WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_regulator_put);
+
 static int _regulator_can_change_status(struct regulator_dev *rdev)
 {
 	if (!rdev->constraints)
@@ -2394,13 +2442,59 @@ int regulator_bulk_get(struct device *dev, int num_consumers,
 	return 0;
 
 err:
-	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
+	while (--i >= 0)
 		regulator_put(consumers[i].consumer);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(regulator_bulk_get);
 
+/**
+ * devm_regulator_bulk_get - managed get multiple regulator consumers
+ *
+ * @dev:           Device to supply
+ * @num_consumers: Number of consumers to register
+ * @consumers:     Configuration of consumers; clients are stored here.
+ *
+ * @return 0 on success, an errno on failure.
+ *
+ * This helper function allows drivers to get several regulator
+ * consumers in one operation with management, the regulators will
+ * automatically be freed when the device is unbound.  If any of the
+ * regulators cannot be acquired then any regulators that were
+ * allocated will be freed before returning to the caller.
+ */
+int devm_regulator_bulk_get(struct device *dev, int num_consumers,
+			    struct regulator_bulk_data *consumers)
+{
+	int i;
+	int ret;
+
+	for (i = 0; i < num_consumers; i++)
+		consumers[i].consumer = NULL;
+
+	for (i = 0; i < num_consumers; i++) {
+		consumers[i].consumer = devm_regulator_get(dev,
+							   consumers[i].supply);
+		if (IS_ERR(consumers[i].consumer)) {
+			ret = PTR_ERR(consumers[i].consumer);
+			dev_err(dev, "Failed to get supply '%s': %d\n",
+				consumers[i].supply, ret);
+			consumers[i].consumer = NULL;
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	for (i = 0; i < num_consumers && consumers[i].consumer; i++)
+		devm_regulator_put(consumers[i].consumer);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_bulk_get);
+
 static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
 {
 	struct regulator_bulk_data *bulk = data;
@@ -2444,12 +2538,9 @@ int regulator_bulk_enable(int num_consumers,
 	return 0;
 
 err:
-	for (i = 0; i < num_consumers; i++)
-		if (consumers[i].ret == 0)
-			regulator_disable(consumers[i].consumer);
-		else
-			pr_err("Failed to enable %s: %d\n",
-			       consumers[i].supply, consumers[i].ret);
+	pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
+	while (--i >= 0)
+		regulator_disable(consumers[i].consumer);
 
 	return ret;
 }
@@ -2463,8 +2554,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_enable);
  * @return         0 on success, an errno on failure
  *
  * This convenience API allows consumers to disable multiple regulator
- * clients in a single API call.  If any consumers cannot be enabled
- * then any others that were disabled will be disabled again prior to
+ * clients in a single API call.  If any consumers cannot be disabled
+ * then any others that were disabled will be enabled again prior to
  * return.
  */
 int regulator_bulk_disable(int num_consumers,
@@ -2473,7 +2564,7 @@ int regulator_bulk_disable(int num_consumers,
 	int i;
 	int ret;
 
-	for (i = 0; i < num_consumers; i++) {
+	for (i = num_consumers - 1; i >= 0; --i) {
 		ret = regulator_disable(consumers[i].consumer);
 		if (ret != 0)
 			goto err;
@@ -2483,7 +2574,7 @@ int regulator_bulk_disable(int num_consumers,
 
 err:
 	pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret);
-	for (--i; i >= 0; --i)
+	for (++i; i < num_consumers; ++i)
 		regulator_enable(consumers[i].consumer);
 
 	return ret;
@@ -2710,11 +2801,9 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
 
 static void rdev_init_debugfs(struct regulator_dev *rdev)
 {
-#ifdef CONFIG_DEBUG_FS
 	rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root);
-	if (IS_ERR(rdev->debugfs) || !rdev->debugfs) {
+	if (!rdev->debugfs) {
 		rdev_warn(rdev, "Failed to create debugfs directory\n");
-		rdev->debugfs = NULL;
 		return;
 	}
 
@@ -2722,7 +2811,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
 			   &rdev->use_count);
 	debugfs_create_u32("open_count", 0444, rdev->debugfs,
 			   &rdev->open_count);
-#endif
 }
 
 /**
@@ -2855,7 +2943,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 	if (init_data) {
 		for (i = 0; i < init_data->num_consumer_supplies; i++) {
 			ret = set_consumer_device_supply(rdev,
-				init_data->consumer_supplies[i].dev,
 				init_data->consumer_supplies[i].dev_name,
 				init_data->consumer_supplies[i].supply);
 			if (ret < 0) {
@@ -2902,9 +2989,7 @@ void regulator_unregister(struct regulator_dev *rdev)
 		return;
 
 	mutex_lock(&regulator_list_mutex);
-#ifdef CONFIG_DEBUG_FS
 	debugfs_remove_recursive(rdev->debugfs);
-#endif
 	flush_work_sync(&rdev->disable_work.work);
 	WARN_ON(rdev->open_count);
 	unset_regulator_supplies(rdev);
@@ -3114,12 +3199,14 @@ static ssize_t supply_map_read_file(struct file *file, char __user *user_buf,
 
 	return ret;
 }
+#endif
 
 static const struct file_operations supply_map_fops = {
+#ifdef CONFIG_DEBUG_FS
 	.read = supply_map_read_file,
 	.llseek = default_llseek,
-};
 #endif
+};
 
 static int __init regulator_init(void)
 {
@@ -3127,17 +3214,12 @@ static int __init regulator_init(void)
 
 	ret = class_register(&regulator_class);
 
-#ifdef CONFIG_DEBUG_FS
 	debugfs_root = debugfs_create_dir("regulator", NULL);
-	if (IS_ERR(debugfs_root) || !debugfs_root) {
+	if (!debugfs_root)
 		pr_warn("regulator: Failed to create debugfs directory\n");
-		debugfs_root = NULL;
-	}
 
-	if (IS_ERR(debugfs_create_file("supply_map", 0444, debugfs_root,
-				       NULL, &supply_map_fops)))
-		pr_warn("regulator: Failed to create supplies debugfs\n");
-#endif
+	debugfs_create_file("supply_map", 0444, debugfs_root, NULL,
+			    &supply_map_fops);
 
 	regulator_dummy_init();
 
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c
index 515443f..4bd25e7 100644
--- a/drivers/regulator/db8500-prcmu.c
+++ b/drivers/regulator/db8500-prcmu.c
@@ -18,74 +18,11 @@
 #include <linux/regulator/machine.h>
 #include <linux/regulator/db8500-prcmu.h>
 #include <linux/module.h>
-
-/*
- * power state reference count
- */
-static int power_state_active_cnt; /* will initialize to zero */
-static DEFINE_SPINLOCK(power_state_active_lock);
-
-static void power_state_active_enable(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&power_state_active_lock, flags);
-	power_state_active_cnt++;
-	spin_unlock_irqrestore(&power_state_active_lock, flags);
-}
-
-static int power_state_active_disable(void)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&power_state_active_lock, flags);
-	if (power_state_active_cnt <= 0) {
-		pr_err("power state: unbalanced enable/disable calls\n");
-		ret = -EINVAL;
-		goto out;
-	}
-
-	power_state_active_cnt--;
-out:
-	spin_unlock_irqrestore(&power_state_active_lock, flags);
-	return ret;
-}
-
-/*
- * Exported interface for CPUIdle only. This function is called when interrupts
- * are turned off. Hence, no locking.
- */
-int power_state_active_is_enabled(void)
-{
-	return (power_state_active_cnt > 0);
-}
-
-/**
- * struct db8500_regulator_info - db8500 regulator information
- * @dev: device pointer
- * @desc: regulator description
- * @rdev: regulator device pointer
- * @is_enabled: status of the regulator
- * @epod_id: id for EPOD (power domain)
- * @is_ramret: RAM retention switch for EPOD (power domain)
- * @operating_point: operating point (only for vape, to be removed)
- *
- */
-struct db8500_regulator_info {
-	struct device *dev;
-	struct regulator_desc desc;
-	struct regulator_dev *rdev;
-	bool is_enabled;
-	u16 epod_id;
-	bool is_ramret;
-	bool exclude_from_power_state;
-	unsigned int operating_point;
-};
+#include "dbx500-prcmu.h"
 
 static int db8500_regulator_enable(struct regulator_dev *rdev)
 {
-	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
 
 	if (info == NULL)
 		return -EINVAL;
@@ -93,16 +30,18 @@ static int db8500_regulator_enable(struct regulator_dev *rdev)
 	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
 		info->desc.name);
 
-	info->is_enabled = true;
-	if (!info->exclude_from_power_state)
-		power_state_active_enable();
+	if (!info->is_enabled) {
+		info->is_enabled = true;
+		if (!info->exclude_from_power_state)
+			power_state_active_enable();
+	}
 
 	return 0;
 }
 
 static int db8500_regulator_disable(struct regulator_dev *rdev)
 {
-	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
 	int ret = 0;
 
 	if (info == NULL)
@@ -111,16 +50,18 @@ static int db8500_regulator_disable(struct regulator_dev *rdev)
 	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
 		info->desc.name);
 
-	info->is_enabled = false;
-	if (!info->exclude_from_power_state)
-		ret = power_state_active_disable();
+	if (info->is_enabled) {
+		info->is_enabled = false;
+		if (!info->exclude_from_power_state)
+			ret = power_state_active_disable();
+	}
 
 	return ret;
 }
 
 static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
 {
-	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
 
 	if (info == NULL)
 		return -EINVAL;
@@ -197,7 +138,7 @@ static int disable_epod(u16 epod_id, bool ramret)
  */
 static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
 {
-	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
 	int ret;
 
 	if (info == NULL)
@@ -221,7 +162,7 @@ out:
 
 static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
 {
-	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
 	int ret;
 
 	if (info == NULL)
@@ -245,7 +186,7 @@ out:
 
 static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
 {
-	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
 
 	if (info == NULL)
 		return -EINVAL;
@@ -266,8 +207,8 @@ static struct regulator_ops db8500_regulator_switch_ops = {
 /*
  * Regulator information
  */
-static struct db8500_regulator_info
-db8500_regulator_info[DB8500_NUM_REGULATORS] = {
+static struct dbx500_regulator_info
+dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
 	[DB8500_REGULATOR_VAPE] = {
 		.desc = {
 			.name	= "db8500-vape",
@@ -476,12 +417,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
 	int i, err;
 
 	/* register all regulators */
-	for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
-		struct db8500_regulator_info *info;
+	for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
+		struct dbx500_regulator_info *info;
 		struct regulator_init_data *init_data = &db8500_init_data[i];
 
 		/* assign per-regulator data */
-		info = &db8500_regulator_info[i];
+		info = &dbx500_regulator_info[i];
 		info->dev = &pdev->dev;
 
 		/* register with the regulator framework */
@@ -494,7 +435,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
 
 			/* if failing, unregister all earlier regulators */
 			while (--i >= 0) {
-				info = &db8500_regulator_info[i];
+				info = &dbx500_regulator_info[i];
 				regulator_unregister(info->rdev);
 			}
 			return err;
@@ -503,17 +444,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev)
 		dev_dbg(rdev_get_dev(info->rdev),
 			"regulator-%s-probed\n", info->desc.name);
 	}
+	err = ux500_regulator_debug_init(pdev,
+					 dbx500_regulator_info,
+					 ARRAY_SIZE(dbx500_regulator_info));
 
-	return 0;
+	return err;
 }
 
 static int __exit db8500_regulator_remove(struct platform_device *pdev)
 {
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
-		struct db8500_regulator_info *info;
-		info = &db8500_regulator_info[i];
+	ux500_regulator_debug_exit();
+
+	for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
+		struct dbx500_regulator_info *info;
+		info = &dbx500_regulator_info[i];
 
 		dev_vdbg(rdev_get_dev(info->rdev),
 			"regulator-%s-remove\n", info->desc.name);
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c
new file mode 100644
index 0000000..f2e5ecd
--- /dev/null
+++ b/drivers/regulator/dbx500-prcmu.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
+ *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
+ *
+ * UX500 common part of Power domain regulators
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/regulator/driver.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+
+#include "dbx500-prcmu.h"
+
+/*
+ * power state reference count
+ */
+static int power_state_active_cnt; /* will initialize to zero */
+static DEFINE_SPINLOCK(power_state_active_lock);
+
+int power_state_active_get(void)
+{
+	unsigned long flags;
+	int cnt;
+
+	spin_lock_irqsave(&power_state_active_lock, flags);
+	cnt = power_state_active_cnt;
+	spin_unlock_irqrestore(&power_state_active_lock, flags);
+
+	return cnt;
+}
+
+void power_state_active_enable(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&power_state_active_lock, flags);
+	power_state_active_cnt++;
+	spin_unlock_irqrestore(&power_state_active_lock, flags);
+}
+
+int power_state_active_disable(void)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&power_state_active_lock, flags);
+	if (power_state_active_cnt <= 0) {
+		pr_err("power state: unbalanced enable/disable calls\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	power_state_active_cnt--;
+out:
+	spin_unlock_irqrestore(&power_state_active_lock, flags);
+	return ret;
+}
+
+#ifdef CONFIG_REGULATOR_DEBUG
+
+static struct ux500_regulator_debug {
+	struct dentry *dir;
+	struct dentry *status_file;
+	struct dentry *power_state_cnt_file;
+	struct dbx500_regulator_info *regulator_array;
+	int num_regulators;
+	u8 *state_before_suspend;
+	u8 *state_after_suspend;
+} rdebug;
+
+void ux500_regulator_suspend_debug(void)
+{
+	int i;
+	for (i = 0; i < rdebug.num_regulators; i++)
+		rdebug.state_before_suspend[i] =
+			rdebug.regulator_array[i].is_enabled;
+}
+
+void ux500_regulator_resume_debug(void)
+{
+	int i;
+	for (i = 0; i < rdebug.num_regulators; i++)
+		rdebug.state_after_suspend[i] =
+			rdebug.regulator_array[i].is_enabled;
+}
+
+static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p)
+{
+	struct device *dev = s->private;
+	int err;
+
+	/* print power state count */
+	err = seq_printf(s, "ux500-regulator power state count: %i\n",
+		power_state_active_get());
+	if (err < 0)
+		dev_err(dev, "seq_printf overflow\n");
+
+	return 0;
+}
+
+static int ux500_regulator_power_state_cnt_open(struct inode *inode,
+	struct file *file)
+{
+	return single_open(file, ux500_regulator_power_state_cnt_print,
+		inode->i_private);
+}
+
+static const struct file_operations ux500_regulator_power_state_cnt_fops = {
+	.open = ux500_regulator_power_state_cnt_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+static int ux500_regulator_status_print(struct seq_file *s, void *p)
+{
+	struct device *dev = s->private;
+	int err;
+	int i;
+
+	/* print dump header */
+	err = seq_printf(s, "ux500-regulator status:\n");
+	if (err < 0)
+		dev_err(dev, "seq_printf overflow\n");
+
+	err = seq_printf(s, "%31s : %8s : %8s\n", "current",
+		"before", "after");
+	if (err < 0)
+		dev_err(dev, "seq_printf overflow\n");
+
+	for (i = 0; i < rdebug.num_regulators; i++) {
+		struct dbx500_regulator_info *info;
+		/* Access per-regulator data */
+		info = &rdebug.regulator_array[i];
+
+		/* print status */
+		err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name,
+			info->is_enabled ? "enabled" : "disabled",
+			rdebug.state_before_suspend[i] ? "enabled" : "disabled",
+			rdebug.state_after_suspend[i] ? "enabled" : "disabled");
+		if (err < 0)
+			dev_err(dev, "seq_printf overflow\n");
+	}
+
+	return 0;
+}
+
+static int ux500_regulator_status_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ux500_regulator_status_print,
+		inode->i_private);
+}
+
+static const struct file_operations ux500_regulator_status_fops = {
+	.open = ux500_regulator_status_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.owner = THIS_MODULE,
+};
+
+int __attribute__((weak)) dbx500_regulator_testcase(
+	struct dbx500_regulator_info *regulator_info,
+	int num_regulators)
+{
+	return 0;
+}
+
+int __devinit
+ux500_regulator_debug_init(struct platform_device *pdev,
+	struct dbx500_regulator_info *regulator_info,
+	int num_regulators)
+{
+	/* create directory */
+	rdebug.dir = debugfs_create_dir("ux500-regulator", NULL);
+	if (!rdebug.dir)
+		goto exit_no_debugfs;
+
+	/* create "status" file */
+	rdebug.status_file = debugfs_create_file("status",
+		S_IRUGO, rdebug.dir, &pdev->dev,
+		&ux500_regulator_status_fops);
+	if (!rdebug.status_file)
+		goto exit_destroy_dir;
+
+	/* create "power-state-count" file */
+	rdebug.power_state_cnt_file = debugfs_create_file("power-state-count",
+		S_IRUGO, rdebug.dir, &pdev->dev,
+		&ux500_regulator_power_state_cnt_fops);
+	if (!rdebug.power_state_cnt_file)
+		goto exit_destroy_status;
+
+	rdebug.regulator_array = regulator_info;
+	rdebug.num_regulators = num_regulators;
+
+	rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL);
+	if (!rdebug.state_before_suspend) {
+		dev_err(&pdev->dev,
+			"could not allocate memory for saving state\n");
+		goto exit_destroy_power_state;
+	}
+
+	rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL);
+	if (!rdebug.state_after_suspend) {
+		dev_err(&pdev->dev,
+			"could not allocate memory for saving state\n");
+		goto exit_free;
+	}
+
+	dbx500_regulator_testcase(regulator_info, num_regulators);
+	return 0;
+
+exit_free:
+	kfree(rdebug.state_before_suspend);
+exit_destroy_power_state:
+	debugfs_remove(rdebug.power_state_cnt_file);
+exit_destroy_status:
+	debugfs_remove(rdebug.status_file);
+exit_destroy_dir:
+	debugfs_remove(rdebug.dir);
+exit_no_debugfs:
+	dev_err(&pdev->dev, "failed to create debugfs entries.\n");
+	return -ENOMEM;
+}
+
+int __devexit ux500_regulator_debug_exit(void)
+{
+	debugfs_remove_recursive(rdebug.dir);
+	kfree(rdebug.state_after_suspend);
+	kfree(rdebug.state_before_suspend);
+
+	return 0;
+}
+#endif
diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h
new file mode 100644
index 0000000..e763883
--- /dev/null
+++ b/drivers/regulator/dbx500-prcmu.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Bengt Jonsson <bengt.jonsson@stericsson.com> for ST-Ericsson,
+ *	   Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ *
+ * License Terms: GNU General Public License v2
+ *
+ */
+
+#ifndef DBX500_REGULATOR_H
+#define DBX500_REGULATOR_H
+
+#include <linux/platform_device.h>
+
+/**
+ * struct dbx500_regulator_info - dbx500 regulator information
+ * @dev: device pointer
+ * @desc: regulator description
+ * @rdev: regulator device pointer
+ * @is_enabled: status of the regulator
+ * @epod_id: id for EPOD (power domain)
+ * @is_ramret: RAM retention switch for EPOD (power domain)
+ * @operating_point: operating point (only for vape, to be removed)
+ *
+ */
+struct dbx500_regulator_info {
+	struct device *dev;
+	struct regulator_desc desc;
+	struct regulator_dev *rdev;
+	bool is_enabled;
+	u16 epod_id;
+	bool is_ramret;
+	bool exclude_from_power_state;
+	unsigned int operating_point;
+};
+
+void power_state_active_enable(void);
+int power_state_active_disable(void);
+
+
+#ifdef CONFIG_REGULATOR_DEBUG
+int ux500_regulator_debug_init(struct platform_device *pdev,
+			       struct dbx500_regulator_info *regulator_info,
+			       int num_regulators);
+
+int ux500_regulator_debug_exit(void);
+#else
+
+static inline int ux500_regulator_debug_init(struct platform_device *pdev,
+			     struct dbx500_regulator_info *regulator_info,
+			     int num_regulators)
+{
+	return 0;
+}
+
+static inline int ux500_regulator_debug_exit(void)
+{
+	return 0;
+}
+
+#endif
+#endif
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c
index d0e1180..f724644 100644
--- a/drivers/regulator/max8649.c
+++ b/drivers/regulator/max8649.c
@@ -270,7 +270,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client,
 			ret);
 		goto out;
 	}
-	dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret);
+	dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val);
 
 	/* enable VID0 & VID1 */
 	regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index d26e864..bb7cd9d 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -908,13 +908,13 @@ static struct regulator_desc regulators[] = {
 	},
 	regulator_desc_buck(7),
 	{
-		.name	= "EN32KHz AP",
+		.name	= "EN32KHz_AP",
 		.id	= MAX8997_EN32KHZ_AP,
 		.ops	= &max8997_fixedvolt_ops,
 		.type	= REGULATOR_VOLTAGE,
 		.owner	= THIS_MODULE,
 	}, {
-		.name	= "EN32KHz CP",
+		.name	= "EN32KHz_CP",
 		.id	= MAX8997_EN32KHZ_CP,
 		.ops	= &max8997_fixedvolt_ops,
 		.type	= REGULATOR_VOLTAGE,
@@ -938,7 +938,7 @@ static struct regulator_desc regulators[] = {
 		.type	= REGULATOR_VOLTAGE,
 		.owner	 = THIS_MODULE,
 	}, {
-		.name	= "CHARGER CV",
+		.name	= "CHARGER_CV",
 		.id	= MAX8997_CHARGER_CV,
 		.ops	= &max8997_fixedstate_ops,
 		.type	= REGULATOR_VOLTAGE,
@@ -950,7 +950,7 @@ static struct regulator_desc regulators[] = {
 		.type	= REGULATOR_CURRENT,
 		.owner	 = THIS_MODULE,
 	}, {
-		.name	= "CHARGER TOPOFF",
+		.name	= "CHARGER_TOPOFF",
 		.id	= MAX8997_CHARGER_TOPOFF,
 		.ops	= &max8997_charger_fixedstate_ops,
 		.type	= REGULATOR_CURRENT,
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
new file mode 100644
index 0000000..2fb2add
--- /dev/null
+++ b/drivers/regulator/s5m8767.c
@@ -0,0 +1,832 @@
+/*
+ * s5m8767.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ *              http://www.samsung.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/bug.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+
+struct s5m8767_info {
+	struct device *dev;
+	struct s5m87xx_dev *iodev;
+	int num_regulators;
+	struct regulator_dev **rdev;
+
+	int ramp_delay;
+	bool buck2_ramp;
+	bool buck3_ramp;
+	bool buck4_ramp;
+
+	bool buck2_gpiodvs;
+	bool buck3_gpiodvs;
+	bool buck4_gpiodvs;
+	u8 buck2_vol[8];
+	u8 buck3_vol[8];
+	u8 buck4_vol[8];
+	int buck_gpios[3];
+	int buck_gpioindex;
+};
+
+struct s5m_voltage_desc {
+	int max;
+	int min;
+	int step;
+};
+
+static const struct s5m_voltage_desc buck_voltage_val1 = {
+	.max = 2225000,
+	.min =  650000,
+	.step =   6250,
+};
+
+static const struct s5m_voltage_desc buck_voltage_val2 = {
+	.max = 1600000,
+	.min =  600000,
+	.step =   6250,
+};
+
+static const struct s5m_voltage_desc buck_voltage_val3 = {
+	.max = 3000000,
+	.min =  750000,
+	.step =  12500,
+};
+
+static const struct s5m_voltage_desc ldo_voltage_val1 = {
+	.max = 3950000,
+	.min =  800000,
+	.step =  50000,
+};
+
+static const struct s5m_voltage_desc ldo_voltage_val2 = {
+	.max = 2375000,
+	.min =  800000,
+	.step =  25000,
+};
+
+static const struct s5m_voltage_desc *reg_voltage_map[] = {
+	[S5M8767_LDO1] = &ldo_voltage_val2,
+	[S5M8767_LDO2] = &ldo_voltage_val2,
+	[S5M8767_LDO3] = &ldo_voltage_val1,
+	[S5M8767_LDO4] = &ldo_voltage_val1,
+	[S5M8767_LDO5] = &ldo_voltage_val1,
+	[S5M8767_LDO6] = &ldo_voltage_val2,
+	[S5M8767_LDO7] = &ldo_voltage_val2,
+	[S5M8767_LDO8] = &ldo_voltage_val2,
+	[S5M8767_LDO9] = &ldo_voltage_val1,
+	[S5M8767_LDO10] = &ldo_voltage_val1,
+	[S5M8767_LDO11] = &ldo_voltage_val1,
+	[S5M8767_LDO12] = &ldo_voltage_val1,
+	[S5M8767_LDO13] = &ldo_voltage_val1,
+	[S5M8767_LDO14] = &ldo_voltage_val1,
+	[S5M8767_LDO15] = &ldo_voltage_val2,
+	[S5M8767_LDO16] = &ldo_voltage_val1,
+	[S5M8767_LDO17] = &ldo_voltage_val1,
+	[S5M8767_LDO18] = &ldo_voltage_val1,
+	[S5M8767_LDO19] = &ldo_voltage_val1,
+	[S5M8767_LDO20] = &ldo_voltage_val1,
+	[S5M8767_LDO21] = &ldo_voltage_val1,
+	[S5M8767_LDO22] = &ldo_voltage_val1,
+	[S5M8767_LDO23] = &ldo_voltage_val1,
+	[S5M8767_LDO24] = &ldo_voltage_val1,
+	[S5M8767_LDO25] = &ldo_voltage_val1,
+	[S5M8767_LDO26] = &ldo_voltage_val1,
+	[S5M8767_LDO27] = &ldo_voltage_val1,
+	[S5M8767_LDO28] = &ldo_voltage_val1,
+	[S5M8767_BUCK1] = &buck_voltage_val1,
+	[S5M8767_BUCK2] = &buck_voltage_val2,
+	[S5M8767_BUCK3] = &buck_voltage_val2,
+	[S5M8767_BUCK4] = &buck_voltage_val2,
+	[S5M8767_BUCK5] = &buck_voltage_val1,
+	[S5M8767_BUCK6] = &buck_voltage_val1,
+	[S5M8767_BUCK7] = NULL,
+	[S5M8767_BUCK8] = NULL,
+	[S5M8767_BUCK9] = &buck_voltage_val3,
+};
+
+static int s5m8767_list_voltage(struct regulator_dev *rdev,
+				unsigned int selector)
+{
+	const struct s5m_voltage_desc *desc;
+	int reg_id = rdev_get_id(rdev);
+	int val;
+
+	if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0)
+		return -EINVAL;
+
+	desc = reg_voltage_map[reg_id];
+	if (desc == NULL)
+		return -EINVAL;
+
+	val = desc->min + desc->step * selector;
+	if (val > desc->max)
+		return -EINVAL;
+
+	return val;
+}
+
+static int s5m8767_get_register(struct regulator_dev *rdev, int *reg)
+{
+	int reg_id = rdev_get_id(rdev);
+
+	switch (reg_id) {
+	case S5M8767_LDO1 ... S5M8767_LDO2:
+		*reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
+		break;
+	case S5M8767_LDO3 ... S5M8767_LDO28:
+		*reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
+		break;
+	case S5M8767_BUCK1:
+		*reg = S5M8767_REG_BUCK1CTRL1;
+		break;
+	case S5M8767_BUCK2 ... S5M8767_BUCK4:
+		*reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9;
+		break;
+	case S5M8767_BUCK5:
+		*reg = S5M8767_REG_BUCK5CTRL1;
+		break;
+	case S5M8767_BUCK6 ... S5M8767_BUCK9:
+		*reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	int ret, reg;
+	int mask = 0xc0, pattern = 0xc0;
+	u8 val;
+
+	ret = s5m8767_get_register(rdev, &reg);
+	if (ret == -EINVAL)
+		return 1;
+	else if (ret)
+		return ret;
+
+	ret = s5m_reg_read(s5m8767->iodev, reg, &val);
+	if (ret)
+		return ret;
+
+	return (val & mask) == pattern;
+}
+
+static int s5m8767_reg_enable(struct regulator_dev *rdev)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	int ret, reg;
+	int mask = 0xc0, pattern = 0xc0;
+
+	ret = s5m8767_get_register(rdev, &reg);
+	if (ret)
+		return ret;
+
+	return s5m_reg_update(s5m8767->iodev, reg, pattern, mask);
+}
+
+static int s5m8767_reg_disable(struct regulator_dev *rdev)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	int ret, reg;
+	int  mask = 0xc0, pattern = 0xc0;
+
+	ret = s5m8767_get_register(rdev, &reg);
+	if (ret)
+		return ret;
+
+	return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask);
+}
+
+static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg)
+{
+	int reg_id = rdev_get_id(rdev);
+	int reg;
+
+	switch (reg_id) {
+	case S5M8767_LDO1 ... S5M8767_LDO2:
+		reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1);
+		break;
+	case S5M8767_LDO3 ... S5M8767_LDO28:
+		reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3);
+		break;
+	case S5M8767_BUCK1:
+		reg = S5M8767_REG_BUCK1CTRL2;
+		break;
+	case S5M8767_BUCK2:
+		reg = S5M8767_REG_BUCK2DVS1;
+		break;
+	case S5M8767_BUCK3:
+		reg = S5M8767_REG_BUCK3DVS1;
+		break;
+	case S5M8767_BUCK4:
+		reg = S5M8767_REG_BUCK4DVS1;
+		break;
+	case S5M8767_BUCK5:
+		reg = S5M8767_REG_BUCK5CTRL2;
+		break;
+	case S5M8767_BUCK6 ... S5M8767_BUCK9:
+		reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	*_reg = reg;
+
+	return 0;
+}
+
+static int s5m8767_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	int reg, mask = 0xff, ret;
+	int reg_id = rdev_get_id(rdev);
+	u8 val;
+
+	ret = s5m8767_get_voltage_register(rdev, &reg);
+	if (ret)
+		return ret;
+
+	switch (reg_id) {
+	case S5M8767_LDO1 ... S5M8767_LDO28:
+		mask = 0x3f;
+		break;
+	case S5M8767_BUCK2:
+		if (s5m8767->buck2_gpiodvs)
+			reg += s5m8767->buck_gpioindex;
+		break;
+	case S5M8767_BUCK3:
+		if (s5m8767->buck3_gpiodvs)
+			reg += s5m8767->buck_gpioindex;
+		break;
+	case S5M8767_BUCK4:
+		if (s5m8767->buck4_gpiodvs)
+			reg += s5m8767->buck_gpioindex;
+		break;
+	}
+
+	ret = s5m_reg_read(s5m8767->iodev, reg, &val);
+	if (ret)
+		return ret;
+
+	val &= mask;
+
+	return val;
+}
+
+static inline int s5m8767_convert_voltage(
+		const struct s5m_voltage_desc *desc,
+		int min_vol, int max_vol)
+{
+	int out_vol = 0;
+
+	if (desc == NULL)
+		return -EINVAL;
+
+	if (max_vol < desc->min || min_vol > desc->max)
+		return -EINVAL;
+
+	out_vol = (min_vol - desc->min) / desc->step;
+
+	if (desc->min + desc->step * out_vol > max_vol)
+		return -EINVAL;
+
+	return out_vol;
+}
+
+static int s5m8767_set_voltage(struct regulator_dev *rdev,
+				int min_uV, int max_uV, unsigned *selector)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	int min_vol = min_uV, max_vol = max_uV;
+	const struct s5m_voltage_desc *desc;
+	int reg_id = rdev_get_id(rdev);
+	int reg, mask, ret;
+	int i;
+	u8 val;
+
+	switch (reg_id) {
+	case S5M8767_LDO1 ... S5M8767_LDO28:
+		mask = 0x3f;
+		break;
+	case S5M8767_BUCK1 ... S5M8767_BUCK6:
+		mask = 0xff;
+		break;
+	case S5M8767_BUCK7 ... S5M8767_BUCK8:
+		return -EINVAL;
+	case S5M8767_BUCK9:
+		mask = 0xff;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	desc = reg_voltage_map[reg_id];
+
+	i = s5m8767_convert_voltage(desc, min_vol, max_vol);
+	if (i < 0)
+		return i;
+
+	ret = s5m8767_get_voltage_register(rdev, &reg);
+	if (ret)
+		return ret;
+
+	s5m_reg_read(s5m8767->iodev, reg, &val);
+	val = val & mask;
+
+	ret = s5m_reg_write(s5m8767->iodev, reg, val);
+	*selector = i;
+
+	return ret;
+}
+
+static inline void s5m8767_set_high(struct s5m8767_info *s5m8767)
+{
+	int temp_index = s5m8767->buck_gpioindex;
+
+	gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+	gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+	gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+}
+
+static inline void s5m8767_set_low(struct s5m8767_info *s5m8767)
+{
+	int temp_index = s5m8767->buck_gpioindex;
+
+	gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1);
+	gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1);
+	gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1);
+}
+
+static int s5m8767_set_voltage_buck(struct regulator_dev *rdev,
+				    int min_uV, int max_uV, unsigned *selector)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	int reg_id = rdev_get_id(rdev);
+	const struct s5m_voltage_desc *desc;
+	int new_val, old_val, i = 0;
+	int min_vol = min_uV, max_vol = max_uV;
+
+	if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6)
+		return -EINVAL;
+
+	switch (reg_id) {
+	case S5M8767_BUCK1:
+		return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
+	case S5M8767_BUCK2 ... S5M8767_BUCK4:
+		break;
+	case S5M8767_BUCK5 ... S5M8767_BUCK6:
+		return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
+	case S5M8767_BUCK9:
+		return s5m8767_set_voltage(rdev, min_uV, max_uV, selector);
+	}
+
+	desc = reg_voltage_map[reg_id];
+	new_val = s5m8767_convert_voltage(desc, min_vol, max_vol);
+	if (new_val < 0)
+		return new_val;
+
+	switch (reg_id) {
+	case S5M8767_BUCK2:
+		if (s5m8767->buck2_gpiodvs) {
+			while (s5m8767->buck2_vol[i] != new_val)
+				i++;
+		} else
+			return s5m8767_set_voltage(rdev, min_uV,
+						   max_uV, selector);
+		break;
+	case S5M8767_BUCK3:
+		if (s5m8767->buck3_gpiodvs) {
+			while (s5m8767->buck3_vol[i] != new_val)
+				i++;
+		} else
+			return s5m8767_set_voltage(rdev, min_uV,
+						   max_uV, selector);
+		break;
+	case S5M8767_BUCK4:
+		if (s5m8767->buck3_gpiodvs) {
+			while (s5m8767->buck4_vol[i] != new_val)
+				i++;
+		} else
+			return s5m8767_set_voltage(rdev, min_uV,
+						   max_uV, selector);
+		break;
+	}
+
+	old_val = s5m8767->buck_gpioindex;
+	s5m8767->buck_gpioindex = i;
+
+	if (i > old_val)
+		s5m8767_set_high(s5m8767);
+	else
+		s5m8767_set_low(s5m8767);
+
+	*selector = new_val;
+	return 0;
+}
+
+static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev,
+					     unsigned int old_sel,
+					     unsigned int new_sel)
+{
+	struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
+	const struct s5m_voltage_desc *desc;
+	int reg_id = rdev_get_id(rdev);
+	int mask;
+	int new_val, old_val;
+
+	switch (reg_id) {
+	case S5M8767_LDO1 ... S5M8767_LDO28:
+		mask = 0x3f;
+		break;
+	case S5M8767_BUCK1 ... S5M8767_BUCK6:
+		mask = 0xff;
+		break;
+	case S5M8767_BUCK7 ... S5M8767_BUCK8:
+		return -EINVAL;
+	case S5M8767_BUCK9:
+		mask = 0xff;
+		break;
+	default:
+		return -EINVAL;
+	}
+	desc = reg_voltage_map[reg_id];
+
+	new_val = s5m8767_convert_voltage(desc, new_sel, new_sel);
+	if (new_val < 0)
+		return new_val;
+
+	old_val = s5m8767_convert_voltage(desc, old_sel, old_sel);
+	if (old_val < 0)
+		return old_val;
+
+	if (old_sel < new_sel)
+		return DIV_ROUND_UP(desc->step * (new_val - old_val),
+					s5m8767->ramp_delay);
+	else
+		return 0;
+}
+
+static struct regulator_ops s5m8767_ldo_ops = {
+	.list_voltage		= s5m8767_list_voltage,
+	.is_enabled		= s5m8767_reg_is_enabled,
+	.enable			= s5m8767_reg_enable,
+	.disable		= s5m8767_reg_disable,
+	.get_voltage_sel	= s5m8767_get_voltage_sel,
+	.set_voltage		= s5m8767_set_voltage,
+	.set_voltage_time_sel	= s5m8767_set_voltage_time_sel,
+};
+
+static struct regulator_ops s5m8767_buck_ops = {
+	.list_voltage		= s5m8767_list_voltage,
+	.is_enabled		= s5m8767_reg_is_enabled,
+	.enable			= s5m8767_reg_enable,
+	.disable		= s5m8767_reg_disable,
+	.get_voltage_sel	= s5m8767_get_voltage_sel,
+	.set_voltage		= s5m8767_set_voltage_buck,
+	.set_voltage_time_sel	= s5m8767_set_voltage_time_sel,
+};
+
+#define regulator_desc_ldo(num)		{	\
+	.name		= "LDO"#num,		\
+	.id		= S5M8767_LDO##num,	\
+	.ops		= &s5m8767_ldo_ops,	\
+	.type		= REGULATOR_VOLTAGE,	\
+	.owner		= THIS_MODULE,		\
+}
+#define regulator_desc_buck(num)	{	\
+	.name		= "BUCK"#num,		\
+	.id		= S5M8767_BUCK##num,	\
+	.ops		= &s5m8767_buck_ops,	\
+	.type		= REGULATOR_VOLTAGE,	\
+	.owner		= THIS_MODULE,		\
+}
+
+static struct regulator_desc regulators[] = {
+	regulator_desc_ldo(1),
+	regulator_desc_ldo(2),
+	regulator_desc_ldo(3),
+	regulator_desc_ldo(4),
+	regulator_desc_ldo(5),
+	regulator_desc_ldo(6),
+	regulator_desc_ldo(7),
+	regulator_desc_ldo(8),
+	regulator_desc_ldo(9),
+	regulator_desc_ldo(10),
+	regulator_desc_ldo(11),
+	regulator_desc_ldo(12),
+	regulator_desc_ldo(13),
+	regulator_desc_ldo(14),
+	regulator_desc_ldo(15),
+	regulator_desc_ldo(16),
+	regulator_desc_ldo(17),
+	regulator_desc_ldo(18),
+	regulator_desc_ldo(19),
+	regulator_desc_ldo(20),
+	regulator_desc_ldo(21),
+	regulator_desc_ldo(22),
+	regulator_desc_ldo(23),
+	regulator_desc_ldo(24),
+	regulator_desc_ldo(25),
+	regulator_desc_ldo(26),
+	regulator_desc_ldo(27),
+	regulator_desc_ldo(28),
+	regulator_desc_buck(1),
+	regulator_desc_buck(2),
+	regulator_desc_buck(3),
+	regulator_desc_buck(4),
+	regulator_desc_buck(5),
+	regulator_desc_buck(6),
+	regulator_desc_buck(7),
+	regulator_desc_buck(8),
+	regulator_desc_buck(9),
+};
+
+static __devinit int s5m8767_pmic_probe(struct platform_device *pdev)
+{
+	struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+	struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev);
+	struct regulator_dev **rdev;
+	struct s5m8767_info *s5m8767;
+	struct i2c_client *i2c;
+	int i, ret, size;
+
+	if (!pdata) {
+		dev_err(pdev->dev.parent, "Platform data not supplied\n");
+		return -ENODEV;
+	}
+
+	s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info),
+				GFP_KERNEL);
+	if (!s5m8767)
+		return -ENOMEM;
+
+	size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2);
+	s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+	if (!s5m8767->rdev)
+		return -ENOMEM;
+
+	rdev = s5m8767->rdev;
+	s5m8767->dev = &pdev->dev;
+	s5m8767->iodev = iodev;
+	s5m8767->num_regulators = S5M8767_REG_MAX - 2;
+	platform_set_drvdata(pdev, s5m8767);
+	i2c = s5m8767->iodev->i2c;
+
+	s5m8767->buck_gpioindex = pdata->buck_default_idx;
+	s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs;
+	s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs;
+	s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs;
+	s5m8767->buck_gpios[0] = pdata->buck_gpios[0];
+	s5m8767->buck_gpios[1] = pdata->buck_gpios[1];
+	s5m8767->buck_gpios[2] = pdata->buck_gpios[2];
+	s5m8767->ramp_delay = pdata->buck_ramp_delay;
+	s5m8767->buck2_ramp = pdata->buck2_ramp_enable;
+	s5m8767->buck3_ramp = pdata->buck3_ramp_enable;
+	s5m8767->buck4_ramp = pdata->buck4_ramp_enable;
+
+	for (i = 0; i < 8; i++) {
+		if (s5m8767->buck2_gpiodvs) {
+			s5m8767->buck2_vol[i] =
+				s5m8767_convert_voltage(
+						&buck_voltage_val2,
+						pdata->buck2_voltage[i],
+						pdata->buck2_voltage[i] +
+						buck_voltage_val2.step);
+		}
+
+		if (s5m8767->buck3_gpiodvs) {
+			s5m8767->buck3_vol[i] =
+				s5m8767_convert_voltage(
+						&buck_voltage_val2,
+						pdata->buck3_voltage[i],
+						pdata->buck3_voltage[i] +
+						buck_voltage_val2.step);
+		}
+
+		if (s5m8767->buck4_gpiodvs) {
+			s5m8767->buck4_vol[i] =
+				s5m8767_convert_voltage(
+						&buck_voltage_val2,
+						pdata->buck4_voltage[i],
+						pdata->buck4_voltage[i] +
+						buck_voltage_val2.step);
+		}
+	}
+
+	if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
+		pdata->buck4_gpiodvs) {
+		if (gpio_is_valid(pdata->buck_gpios[0]) &&
+			gpio_is_valid(pdata->buck_gpios[1]) &&
+			gpio_is_valid(pdata->buck_gpios[2])) {
+			ret = gpio_request(pdata->buck_gpios[0],
+						"S5M8767 SET1");
+			if (ret == -EBUSY)
+				dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n");
+
+			ret = gpio_request(pdata->buck_gpios[1],
+					   "S5M8767 SET2");
+			if (ret == -EBUSY)
+				dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n");
+
+			ret = gpio_request(pdata->buck_gpios[2],
+					   "S5M8767 SET3");
+			if (ret == -EBUSY)
+				dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n");
+			/* SET1 GPIO */
+			gpio_direction_output(pdata->buck_gpios[0],
+					(s5m8767->buck_gpioindex >> 2) & 0x1);
+			/* SET2 GPIO */
+			gpio_direction_output(pdata->buck_gpios[1],
+					(s5m8767->buck_gpioindex >> 1) & 0x1);
+			/* SET3 GPIO */
+			gpio_direction_output(pdata->buck_gpios[2],
+					(s5m8767->buck_gpioindex >> 0) & 0x1);
+			ret = 0;
+		} else {
+			dev_err(&pdev->dev, "GPIO NOT VALID\n");
+			ret = -EINVAL;
+			return ret;
+		}
+	}
+
+	if (pdata->buck2_gpiodvs) {
+		if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) {
+			dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
+			ret = -EINVAL;
+			return ret;
+		}
+	}
+
+	if (pdata->buck3_gpiodvs) {
+		if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) {
+			dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
+			ret = -EINVAL;
+			return ret;
+		}
+	}
+
+	if (pdata->buck4_gpiodvs) {
+		if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) {
+			dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n");
+			ret = -EINVAL;
+			return ret;
+		}
+	}
+
+	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL,
+			(pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1);
+	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL,
+			(pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1);
+	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL,
+			(pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1);
+
+	/* Initialize GPIO DVS registers */
+	for (i = 0; i < 8; i++) {
+		if (s5m8767->buck2_gpiodvs) {
+			s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i,
+					   s5m8767->buck2_vol[i]);
+		}
+
+		if (s5m8767->buck3_gpiodvs) {
+			s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i,
+					   s5m8767->buck3_vol[i]);
+		}
+
+		if (s5m8767->buck4_gpiodvs) {
+			s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i,
+					   s5m8767->buck4_vol[i]);
+		}
+	}
+	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff);
+	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff);
+	s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff);
+
+	if (s5m8767->buck2_ramp)
+		s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08);
+
+	if (s5m8767->buck3_ramp)
+		s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04);
+
+	if (s5m8767->buck4_ramp)
+		s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02);
+
+	if (s5m8767->buck2_ramp || s5m8767->buck3_ramp
+		|| s5m8767->buck4_ramp) {
+		switch (s5m8767->ramp_delay) {
+		case 15:
+			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+					0xc0, 0xf0);
+			break;
+		case 25:
+			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+					0xd0, 0xf0);
+			break;
+		case 50:
+			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+					0xe0, 0xf0);
+			break;
+		case 100:
+			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+					0xf0, 0xf0);
+			break;
+		default:
+			s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP,
+					0x90, 0xf0);
+		}
+	}
+
+	for (i = 0; i < pdata->num_regulators; i++) {
+		const struct s5m_voltage_desc *desc;
+		int id = pdata->regulators[i].id;
+
+		desc = reg_voltage_map[id];
+		if (desc)
+			regulators[id].n_voltages =
+				(desc->max - desc->min) / desc->step + 1;
+
+		rdev[i] = regulator_register(&regulators[id], s5m8767->dev,
+				pdata->regulators[i].initdata, s5m8767, NULL);
+		if (IS_ERR(rdev[i])) {
+			ret = PTR_ERR(rdev[i]);
+			dev_err(s5m8767->dev, "regulator init failed for %d\n",
+					id);
+			rdev[i] = NULL;
+			goto err;
+		}
+	}
+
+	return 0;
+err:
+	for (i = 0; i < s5m8767->num_regulators; i++)
+		if (rdev[i])
+			regulator_unregister(rdev[i]);
+
+	return ret;
+}
+
+static int __devexit s5m8767_pmic_remove(struct platform_device *pdev)
+{
+	struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev);
+	struct regulator_dev **rdev = s5m8767->rdev;
+	int i;
+
+	for (i = 0; i < s5m8767->num_regulators; i++)
+		if (rdev[i])
+			regulator_unregister(rdev[i]);
+
+	return 0;
+}
+
+static const struct platform_device_id s5m8767_pmic_id[] = {
+	{ "s5m8767-pmic", 0},
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
+
+static struct platform_driver s5m8767_pmic_driver = {
+	.driver = {
+		.name = "s5m8767-pmic",
+		.owner = THIS_MODULE,
+	},
+	.probe = s5m8767_pmic_probe,
+	.remove = __devexit_p(s5m8767_pmic_remove),
+	.id_table = s5m8767_pmic_id,
+};
+
+static int __init s5m8767_pmic_init(void)
+{
+	return platform_driver_register(&s5m8767_pmic_driver);
+}
+subsys_initcall(s5m8767_pmic_init);
+
+static void __exit s5m8767_pmic_exit(void)
+{
+	platform_driver_unregister(&s5m8767_pmic_driver);
+}
+module_exit(s5m8767_pmic_exit);
+
+/* Module information */
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
new file mode 100644
index 0000000..e2ec730
--- /dev/null
+++ b/drivers/regulator/tps62360-regulator.c
@@ -0,0 +1,472 @@
+/*
+ * tps62360.c -- TI tps62360
+ *
+ * Driver for processor core supply tps62360 and tps62361B
+ *
+ * Copyright (c) 2012, NVIDIA Corporation.
+ *
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; 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., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/tps62360.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+
+/* Register definitions */
+#define REG_VSET0		0
+#define REG_VSET1		1
+#define REG_VSET2		2
+#define REG_VSET3		3
+#define REG_CONTROL		4
+#define REG_TEMP		5
+#define REG_RAMPCTRL		6
+#define REG_CHIPID		8
+
+enum chips {TPS62360, TPS62361};
+
+#define TPS62360_BASE_VOLTAGE	770
+#define TPS62360_N_VOLTAGES	64
+
+#define TPS62361_BASE_VOLTAGE	500
+#define TPS62361_N_VOLTAGES	128
+
+/* tps 62360 chip information */
+struct tps62360_chip {
+	const char *name;
+	struct device *dev;
+	struct regulator_desc desc;
+	struct i2c_client *client;
+	struct regulator_dev *rdev;
+	struct regmap *regmap;
+	int chip_id;
+	int vsel0_gpio;
+	int vsel1_gpio;
+	int voltage_base;
+	u8 voltage_reg_mask;
+	bool en_internal_pulldn;
+	bool en_force_pwm;
+	bool en_discharge;
+	bool valid_gpios;
+	int lru_index[4];
+	int curr_vset_vsel[4];
+	int curr_vset_id;
+};
+
+/*
+ * find_voltage_set_register: Find new voltage configuration register
+ * (VSET) id.
+ * The finding of the new VSET register will be based on the LRU mechanism.
+ * Each VSET register will have different voltage configured . This
+ * Function will look if any of the VSET register have requested voltage set
+ * or not.
+ *     - If it is already there then it will make that register as most
+ *       recently used and return as found so that caller need not to set
+ *       the VSET register but need to set the proper gpios to select this
+ *       VSET register.
+ *     - If requested voltage is not found then it will use the least
+ *       recently mechanism to get new VSET register for new configuration
+ *       and will return not_found so that caller need to set new VSET
+ *       register and then gpios (both).
+ */
+static bool find_voltage_set_register(struct tps62360_chip *tps,
+		int req_vsel, int *vset_reg_id)
+{
+	int i;
+	bool found = false;
+	int new_vset_reg = tps->lru_index[3];
+	int found_index = 3;
+	for (i = 0; i < 4; ++i) {
+		if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) {
+			new_vset_reg = tps->lru_index[i];
+			found_index = i;
+			found = true;
+			goto update_lru_index;
+		}
+	}
+
+update_lru_index:
+	for (i = found_index; i > 0; i--)
+		tps->lru_index[i] = tps->lru_index[i - 1];
+
+	tps->lru_index[0] = new_vset_reg;
+	*vset_reg_id = new_vset_reg;
+	return found;
+}
+
+static int tps62360_dcdc_get_voltage(struct regulator_dev *dev)
+{
+	struct tps62360_chip *tps = rdev_get_drvdata(dev);
+	int vsel;
+	unsigned int data;
+	int ret;
+
+	ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data);
+	if (ret < 0) {
+		dev_err(tps->dev, "%s: Error in reading register %d\n",
+			__func__, REG_VSET0 + tps->curr_vset_id);
+		return ret;
+	}
+	vsel = (int)data & tps->voltage_reg_mask;
+	return (tps->voltage_base + vsel * 10) * 1000;
+}
+
+static int tps62360_dcdc_set_voltage(struct regulator_dev *dev,
+	     int min_uV, int max_uV, unsigned *selector)
+{
+	struct tps62360_chip *tps = rdev_get_drvdata(dev);
+	int vsel;
+	int ret;
+	bool found = false;
+	int new_vset_id = tps->curr_vset_id;
+
+	if (max_uV < min_uV)
+		return -EINVAL;
+
+	if (min_uV >
+		((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000))
+		return -EINVAL;
+
+	if (max_uV < tps->voltage_base * 1000)
+		return -EINVAL;
+
+	vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000);
+	if (selector)
+		*selector = (vsel & tps->voltage_reg_mask);
+
+	/*
+	 * If gpios are available to select the VSET register then least
+	 * recently used register for new configuration.
+	 */
+	if (tps->valid_gpios)
+		found = find_voltage_set_register(tps, vsel, &new_vset_id);
+
+	if (!found) {
+		ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id,
+				tps->voltage_reg_mask, vsel);
+		if (ret < 0) {
+			dev_err(tps->dev, "%s: Error in updating register %d\n",
+				 __func__, REG_VSET0 + new_vset_id);
+			return ret;
+		}
+		tps->curr_vset_id = new_vset_id;
+		tps->curr_vset_vsel[new_vset_id] = vsel;
+	}
+
+	/* Select proper VSET register vio gpios */
+	if (tps->valid_gpios) {
+		gpio_set_value_cansleep(tps->vsel0_gpio,
+					new_vset_id & 0x1);
+		gpio_set_value_cansleep(tps->vsel1_gpio,
+					(new_vset_id >> 1) & 0x1);
+	}
+	return 0;
+}
+
+static int tps62360_dcdc_list_voltage(struct regulator_dev *dev,
+					unsigned selector)
+{
+	struct tps62360_chip *tps = rdev_get_drvdata(dev);
+
+	if (selector >= tps->desc.n_voltages)
+		return -EINVAL;
+	return (tps->voltage_base + selector * 10) * 1000;
+}
+
+static struct regulator_ops tps62360_dcdc_ops = {
+	.get_voltage = tps62360_dcdc_get_voltage,
+	.set_voltage = tps62360_dcdc_set_voltage,
+	.list_voltage = tps62360_dcdc_list_voltage,
+};
+
+static int tps62360_init_force_pwm(struct tps62360_chip *tps,
+	struct tps62360_regulator_platform_data *pdata,
+	int vset_id)
+{
+	unsigned int data;
+	int ret;
+	ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data);
+	if (ret < 0) {
+		dev_err(tps->dev, "%s() fails in writing reg %d\n",
+			__func__, REG_VSET0 + vset_id);
+		return ret;
+	}
+	tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask;
+	if (pdata->en_force_pwm)
+		data |= BIT(7);
+	else
+		data &= ~BIT(7);
+	ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data);
+	if (ret < 0)
+		dev_err(tps->dev, "%s() fails in writing reg %d\n",
+				__func__, REG_VSET0 + vset_id);
+	return ret;
+}
+
+static int tps62360_init_dcdc(struct tps62360_chip *tps,
+		struct tps62360_regulator_platform_data *pdata)
+{
+	int ret;
+	int i;
+
+	/* Initailize internal pull up/down control */
+	if (tps->en_internal_pulldn)
+		ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0);
+	else
+		ret = regmap_write(tps->regmap, REG_CONTROL, 0x0);
+	if (ret < 0) {
+		dev_err(tps->dev, "%s() fails in writing reg %d\n",
+			__func__, REG_CONTROL);
+		return ret;
+	}
+
+	/* Initailize force PWM mode */
+	if (tps->valid_gpios) {
+		for (i = 0; i < 4; ++i) {
+			ret = tps62360_init_force_pwm(tps, pdata, i);
+			if (ret < 0)
+				return ret;
+		}
+	} else {
+		ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Reset output discharge path to reduce power consumption */
+	ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0);
+	if (ret < 0)
+		dev_err(tps->dev, "%s() fails in updating reg %d\n",
+			__func__, REG_RAMPCTRL);
+	return ret;
+}
+
+static const struct regmap_config tps62360_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int __devinit tps62360_probe(struct i2c_client *client,
+				     const struct i2c_device_id *id)
+{
+	struct tps62360_regulator_platform_data *pdata;
+	struct regulator_dev *rdev;
+	struct tps62360_chip *tps;
+	int ret;
+	int i;
+
+	pdata = client->dev.platform_data;
+	if (!pdata) {
+		dev_err(&client->dev, "%s() Err: Platform data not found\n",
+						__func__);
+		return -EIO;
+	}
+
+	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
+	if (!tps) {
+		dev_err(&client->dev, "%s() Err: Memory allocation fails\n",
+						__func__);
+		return -ENOMEM;
+	}
+
+	tps->en_force_pwm = pdata->en_force_pwm;
+	tps->en_discharge = pdata->en_discharge;
+	tps->en_internal_pulldn = pdata->en_internal_pulldn;
+	tps->vsel0_gpio = pdata->vsel0_gpio;
+	tps->vsel1_gpio = pdata->vsel1_gpio;
+	tps->client = client;
+	tps->dev = &client->dev;
+	tps->name = id->name;
+	tps->voltage_base = (id->driver_data == TPS62360) ?
+				TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE;
+	tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F;
+
+	tps->desc.name = id->name;
+	tps->desc.id = 0;
+	tps->desc.n_voltages = (id->driver_data == TPS62360) ?
+				TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES;
+	tps->desc.ops = &tps62360_dcdc_ops;
+	tps->desc.type = REGULATOR_VOLTAGE;
+	tps->desc.owner = THIS_MODULE;
+	tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config);
+	if (IS_ERR(tps->regmap)) {
+		ret = PTR_ERR(tps->regmap);
+		dev_err(&client->dev, "%s() Err: Failed to allocate register"
+			"map: %d\n", __func__, ret);
+		return ret;
+	}
+	i2c_set_clientdata(client, tps);
+
+	tps->curr_vset_id = (pdata->vsel1_def_state & 1) * 2 +
+				(pdata->vsel0_def_state & 1);
+	tps->lru_index[0] = tps->curr_vset_id;
+	tps->valid_gpios = false;
+
+	if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) {
+		ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0");
+		if (ret) {
+			dev_err(&client->dev,
+				"Err: Could not obtain vsel0 GPIO %d: %d\n",
+						tps->vsel0_gpio, ret);
+			goto err_gpio0;
+		}
+		ret = gpio_direction_output(tps->vsel0_gpio,
+					pdata->vsel0_def_state);
+		if (ret) {
+			dev_err(&client->dev, "Err: Could not set direction of"
+				"vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret);
+			gpio_free(tps->vsel0_gpio);
+			goto err_gpio0;
+		}
+
+		ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1");
+		if (ret) {
+			dev_err(&client->dev,
+				"Err: Could not obtain vsel1 GPIO %d: %d\n",
+						tps->vsel1_gpio, ret);
+			goto err_gpio1;
+		}
+		ret = gpio_direction_output(tps->vsel1_gpio,
+					pdata->vsel1_def_state);
+		if (ret) {
+			dev_err(&client->dev, "Err: Could not set direction of"
+				"vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret);
+			gpio_free(tps->vsel1_gpio);
+			goto err_gpio1;
+		}
+		tps->valid_gpios = true;
+
+		/*
+		 * Initialize the lru index with vset_reg id
+		 * The index 0 will be most recently used and
+		 * set with the tps->curr_vset_id */
+		for (i = 0; i < 4; ++i)
+			tps->lru_index[i] = i;
+		tps->lru_index[0] = tps->curr_vset_id;
+		tps->lru_index[tps->curr_vset_id] = 0;
+	}
+
+	ret = tps62360_init_dcdc(tps, pdata);
+	if (ret < 0) {
+		dev_err(tps->dev, "%s() Err: Init fails with = %d\n",
+				__func__, ret);
+		goto err_init;
+	}
+
+	/* Register the regulators */
+	rdev = regulator_register(&tps->desc, &client->dev,
+				&pdata->reg_init_data, tps, NULL);
+	if (IS_ERR(rdev)) {
+		dev_err(tps->dev, "%s() Err: Failed to register %s\n",
+				__func__, id->name);
+		ret = PTR_ERR(rdev);
+		goto err_init;
+	}
+
+	tps->rdev = rdev;
+	return 0;
+
+err_init:
+	if (gpio_is_valid(tps->vsel1_gpio))
+		gpio_free(tps->vsel1_gpio);
+err_gpio1:
+	if (gpio_is_valid(tps->vsel0_gpio))
+		gpio_free(tps->vsel0_gpio);
+err_gpio0:
+	regmap_exit(tps->regmap);
+	return ret;
+}
+
+/**
+ * tps62360_remove - tps62360 driver i2c remove handler
+ * @client: i2c driver client device structure
+ *
+ * Unregister TPS driver as an i2c client device driver
+ */
+static int __devexit tps62360_remove(struct i2c_client *client)
+{
+	struct tps62360_chip *tps = i2c_get_clientdata(client);
+
+	if (gpio_is_valid(tps->vsel1_gpio))
+		gpio_free(tps->vsel1_gpio);
+
+	if (gpio_is_valid(tps->vsel0_gpio))
+		gpio_free(tps->vsel0_gpio);
+
+	regulator_unregister(tps->rdev);
+	regmap_exit(tps->regmap);
+	return 0;
+}
+
+static void tps62360_shutdown(struct i2c_client *client)
+{
+	struct tps62360_chip *tps = i2c_get_clientdata(client);
+	int st;
+
+	if (!tps->en_discharge)
+		return;
+
+	/* Configure the output discharge path */
+	st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2));
+	if (st < 0)
+		dev_err(tps->dev, "%s() fails in updating reg %d\n",
+			__func__, REG_RAMPCTRL);
+}
+
+static const struct i2c_device_id tps62360_id[] = {
+	{.name = "tps62360", .driver_data = TPS62360},
+	{.name = "tps62361", .driver_data = TPS62361},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, tps62360_id);
+
+static struct i2c_driver tps62360_i2c_driver = {
+	.driver = {
+		.name = "tps62360",
+		.owner = THIS_MODULE,
+	},
+	.probe = tps62360_probe,
+	.remove = __devexit_p(tps62360_remove),
+	.shutdown = tps62360_shutdown,
+	.id_table = tps62360_id,
+};
+
+static int __init tps62360_init(void)
+{
+	return i2c_add_driver(&tps62360_i2c_driver);
+}
+subsys_initcall(tps62360_init);
+
+static void __exit tps62360_cleanup(void)
+{
+	i2c_del_driver(&tps62360_i2c_driver);
+}
+module_exit(tps62360_cleanup);
+
+MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
+MODULE_DESCRIPTION("TPS62360 voltage regulator driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index 18d61a0..43e4902 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -491,10 +491,6 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
 	regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
 			TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
 
-	/* Enable setting output voltage by I2C */
-	regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
-			TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
-
 	return 0;
 
  fail:
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c
new file mode 100644
index 0000000..28a10ea
--- /dev/null
+++ b/drivers/regulator/tps65217-regulator.c
@@ -0,0 +1,493 @@
+/*
+ * tps65217-regulator.c
+ *
+ * Regulator driver for TPS65217 PMIC
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/tps65217.h>
+
+#define TPS65217_REGULATOR(_name, _id, _ops, _n)	\
+	{						\
+		.name		= _name,		\
+		.id		= _id,			\
+		.ops		= &_ops,		\
+		.n_voltages	= _n,			\
+		.type		= REGULATOR_VOLTAGE,	\
+		.owner		= THIS_MODULE,		\
+	}						\
+
+#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm)	\
+	{						\
+		.name		= _nm,			\
+		.min_uV		= _min,			\
+		.max_uV		= _max,			\
+		.vsel_to_uv	= _f1,			\
+		.uv_to_vsel	= _f2,			\
+		.table		= _t,			\
+		.table_len	= _n,			\
+		.enable_mask	= _em,			\
+		.set_vout_reg	= _vr,			\
+		.set_vout_mask	= _vm,			\
+	}
+
+static const int LDO1_VSEL_table[] = {
+	1000000, 1100000, 1200000, 1250000,
+	1300000, 1350000, 1400000, 1500000,
+	1600000, 1800000, 2500000, 2750000,
+	2800000, 3000000, 3100000, 3300000,
+};
+
+static int tps65217_vsel_to_uv1(unsigned int vsel)
+{
+	int uV = 0;
+
+	if (vsel > 63)
+		return -EINVAL;
+
+	if (vsel <= 24)
+		uV = vsel * 25000 + 900000;
+	else if (vsel <= 52)
+		uV = (vsel - 24) * 50000 + 1500000;
+	else if (vsel < 56)
+		uV = (vsel - 52) * 100000 + 2900000;
+	else
+		uV = 3300000;
+
+	return uV;
+}
+
+static int tps65217_uv_to_vsel1(int uV, unsigned int *vsel)
+{
+	if ((uV < 0) && (uV > 3300000))
+		return -EINVAL;
+
+	if (uV <= 1500000)
+		*vsel = (uV - 875001) / 25000;
+	else if (uV <= 2900000)
+		*vsel = 24 + (uV - 1450001) / 50000;
+	else if (uV < 3300000)
+		*vsel = 52 + (uV - 2800001) / 100000;
+	else
+		*vsel = 56;
+
+	return 0;
+}
+
+static int tps65217_vsel_to_uv2(unsigned int vsel)
+{
+	int uV = 0;
+
+	if (vsel > 31)
+		return -EINVAL;
+
+	if (vsel <= 8)
+		uV = vsel * 50000 + 1500000;
+	else if (vsel <= 13)
+		uV = (vsel - 8) * 100000 + 1900000;
+	else
+		uV = (vsel - 13) * 50000 + 2400000;
+
+	return uV;
+}
+
+static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel)
+{
+	if ((uV < 0) && (uV > 3300000))
+		return -EINVAL;
+
+	if (uV <= 1900000)
+		*vsel = (uV - 1450001) / 50000;
+	else if (uV <= 2400000)
+		*vsel = 8 + (uV - 1800001) / 100000;
+	else
+		*vsel = 13 + (uV - 2350001) / 50000;
+
+	return 0;
+}
+
+static struct tps_info tps65217_pmic_regs[] = {
+	TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1,
+			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN,
+			TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK),
+	TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1,
+			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN,
+			TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK),
+	TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1,
+			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN,
+			TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK),
+	TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table,
+			16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1,
+			TPS65217_DEFLDO1_LDO1_MASK),
+	TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1,
+			tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN,
+			TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK),
+	TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2,
+			tps65217_uv_to_vsel2, NULL, 32,
+			TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN,
+			TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK),
+	TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2,
+			tps65217_uv_to_vsel2, NULL, 32,
+			TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN,
+			TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK),
+};
+
+static int tps65217_pmic_dcdc_is_enabled(struct regulator_dev *dev)
+{
+	int ret;
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int data, dcdc = rdev_get_id(dev);
+
+	if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3)
+		return -EINVAL;
+
+	ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data);
+	if (ret)
+		return ret;
+
+	return (data & tps->info[dcdc]->enable_mask) ? 1 : 0;
+}
+
+static int tps65217_pmic_ldo_is_enabled(struct regulator_dev *dev)
+{
+	int ret;
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int data, ldo = rdev_get_id(dev);
+
+	if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4)
+		return -EINVAL;
+
+	ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data);
+	if (ret)
+		return ret;
+
+	return (data & tps->info[ldo]->enable_mask) ? 1 : 0;
+}
+
+static int tps65217_pmic_dcdc_enable(struct regulator_dev *dev)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int dcdc = rdev_get_id(dev);
+
+	if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3)
+		return -EINVAL;
+
+	/* Enable the regulator and password protection is level 1 */
+	return tps65217_set_bits(tps, TPS65217_REG_ENABLE,
+				tps->info[dcdc]->enable_mask,
+				tps->info[dcdc]->enable_mask,
+				TPS65217_PROTECT_L1);
+}
+
+static int tps65217_pmic_dcdc_disable(struct regulator_dev *dev)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int dcdc = rdev_get_id(dev);
+
+	if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3)
+		return -EINVAL;
+
+	/* Disable the regulator and password protection is level 1 */
+	return tps65217_clear_bits(tps, TPS65217_REG_ENABLE,
+			tps->info[dcdc]->enable_mask, TPS65217_PROTECT_L1);
+}
+
+static int tps65217_pmic_ldo_enable(struct regulator_dev *dev)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int ldo = rdev_get_id(dev);
+
+	if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4)
+		return -EINVAL;
+
+	/* Enable the regulator and password protection is level 1 */
+	return tps65217_set_bits(tps, TPS65217_REG_ENABLE,
+				tps->info[ldo]->enable_mask,
+				tps->info[ldo]->enable_mask,
+				TPS65217_PROTECT_L1);
+}
+
+static int tps65217_pmic_ldo_disable(struct regulator_dev *dev)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int ldo = rdev_get_id(dev);
+
+	if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4)
+		return -EINVAL;
+
+	/* Disable the regulator and password protection is level 1 */
+	return tps65217_clear_bits(tps, TPS65217_REG_ENABLE,
+			tps->info[ldo]->enable_mask, TPS65217_PROTECT_L1);
+}
+
+static int tps65217_pmic_dcdc_get_voltage_sel(struct regulator_dev *dev)
+{
+	int ret;
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int selector, dcdc = rdev_get_id(dev);
+
+	if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3)
+		return -EINVAL;
+
+	ret = tps65217_reg_read(tps, tps->info[dcdc]->set_vout_reg, &selector);
+	if (ret)
+		return ret;
+
+	selector &= tps->info[dcdc]->set_vout_mask;
+
+	return selector;
+}
+
+static int tps65217_pmic_dcdc_set_voltage(struct regulator_dev *dev,
+				  int min_uV, int max_uV, unsigned *selector)
+{
+	int ret;
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int dcdc = rdev_get_id(dev);
+
+	if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3)
+		return -EINVAL;
+
+	if (min_uV < tps->info[dcdc]->min_uV
+		|| min_uV > tps->info[dcdc]->max_uV)
+		return -EINVAL;
+
+	if (max_uV < tps->info[dcdc]->min_uV
+		|| max_uV > tps->info[dcdc]->max_uV)
+		return -EINVAL;
+
+	ret = tps->info[dcdc]->uv_to_vsel(min_uV, selector);
+	if (ret)
+		return ret;
+
+	/* Set the voltage based on vsel value and write protect level is 2 */
+	ret = tps65217_set_bits(tps, tps->info[dcdc]->set_vout_reg,
+					tps->info[dcdc]->set_vout_mask,
+					*selector, TPS65217_PROTECT_L2);
+	if (ret)
+		return ret;
+
+	/* Set GO bit to initiate voltage transistion */
+	return tps65217_set_bits(tps, TPS65217_REG_DEFSLEW,
+				TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO,
+				TPS65217_PROTECT_L2);
+}
+
+static int tps65217_pmic_ldo_get_voltage_sel(struct regulator_dev *dev)
+{
+	int ret;
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int selector, ldo = rdev_get_id(dev);
+
+	if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4)
+		return -EINVAL;
+
+	ret = tps65217_reg_read(tps, tps->info[ldo]->set_vout_reg, &selector);
+	if (ret)
+		return ret;
+
+	selector &= tps->info[ldo]->set_vout_mask;
+
+	return selector;
+}
+
+static int tps65217_pmic_ldo_set_voltage_sel(struct regulator_dev *dev,
+						unsigned selector)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	int ldo = rdev_get_id(dev);
+
+	if (ldo != TPS65217_LDO_1)
+		return -EINVAL;
+
+	if (selector >= tps->info[ldo]->table_len)
+		return -EINVAL;
+
+	/* Set the voltage based on vsel value and write protect level is 2 */
+	return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg,
+					tps->info[ldo]->set_vout_mask,
+					selector, TPS65217_PROTECT_L2);
+}
+
+static int tps65217_pmic_ldo_set_voltage(struct regulator_dev *dev,
+				  int min_uV, int max_uV, unsigned *selector)
+{
+	int ret;
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int ldo = rdev_get_id(dev);
+
+	if (ldo < TPS65217_LDO_2 || ldo > TPS65217_LDO_4)
+		return -EINVAL;
+
+	if (min_uV < tps->info[ldo]->min_uV
+		|| min_uV > tps->info[ldo]->max_uV)
+		return -EINVAL;
+
+	if (max_uV < tps->info[ldo]->min_uV
+		|| max_uV > tps->info[ldo]->max_uV)
+		return -EINVAL;
+
+	ret = tps->info[ldo]->uv_to_vsel(min_uV, selector);
+	if (ret)
+		return ret;
+
+	/* Set the voltage based on vsel value and write protect level is 2 */
+	return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg,
+					tps->info[ldo]->set_vout_mask,
+					*selector, TPS65217_PROTECT_L2);
+}
+
+static int tps65217_pmic_dcdc_list_voltage(struct regulator_dev *dev,
+					unsigned selector)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int dcdc = rdev_get_id(dev);
+
+	if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3)
+		return -EINVAL;
+
+	if (selector >= tps->info[dcdc]->table_len)
+		return -EINVAL;
+
+	return tps->info[dcdc]->vsel_to_uv(selector);
+}
+
+static int tps65217_pmic_ldo_list_voltage(struct regulator_dev *dev,
+					unsigned selector)
+{
+	struct tps65217 *tps = rdev_get_drvdata(dev);
+	unsigned int ldo = rdev_get_id(dev);
+
+	if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4)
+		return -EINVAL;
+
+	if (selector >= tps->info[ldo]->table_len)
+		return -EINVAL;
+
+	if (tps->info[ldo]->table)
+		return tps->info[ldo]->table[selector];
+
+	return tps->info[ldo]->vsel_to_uv(selector);
+}
+
+/* Operations permitted on DCDCx */
+static struct regulator_ops tps65217_pmic_dcdc_ops = {
+	.is_enabled		= tps65217_pmic_dcdc_is_enabled,
+	.enable			= tps65217_pmic_dcdc_enable,
+	.disable		= tps65217_pmic_dcdc_disable,
+	.get_voltage_sel	= tps65217_pmic_dcdc_get_voltage_sel,
+	.set_voltage		= tps65217_pmic_dcdc_set_voltage,
+	.list_voltage		= tps65217_pmic_dcdc_list_voltage,
+};
+
+/* Operations permitted on LDO1 */
+static struct regulator_ops tps65217_pmic_ldo1_ops = {
+	.is_enabled		= tps65217_pmic_ldo_is_enabled,
+	.enable			= tps65217_pmic_ldo_enable,
+	.disable		= tps65217_pmic_ldo_disable,
+	.get_voltage_sel	= tps65217_pmic_ldo_get_voltage_sel,
+	.set_voltage_sel	= tps65217_pmic_ldo_set_voltage_sel,
+	.list_voltage		= tps65217_pmic_ldo_list_voltage,
+};
+
+/* Operations permitted on LDO2, LDO3 and LDO4 */
+static struct regulator_ops tps65217_pmic_ldo234_ops = {
+	.is_enabled		= tps65217_pmic_ldo_is_enabled,
+	.enable			= tps65217_pmic_ldo_enable,
+	.disable		= tps65217_pmic_ldo_disable,
+	.get_voltage_sel	= tps65217_pmic_ldo_get_voltage_sel,
+	.set_voltage		= tps65217_pmic_ldo_set_voltage,
+	.list_voltage		= tps65217_pmic_ldo_list_voltage,
+};
+
+static struct regulator_desc regulators[] = {
+	TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1,
+				tps65217_pmic_dcdc_ops, 64),
+	TPS65217_REGULATOR("DCDC2",TPS65217_DCDC_2,
+				tps65217_pmic_dcdc_ops, 64),
+	TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3,
+				tps65217_pmic_dcdc_ops, 64),
+	TPS65217_REGULATOR("LDO1", TPS65217_LDO_1,
+				tps65217_pmic_ldo1_ops, 16),
+	TPS65217_REGULATOR("LDO2", TPS65217_LDO_2,
+				tps65217_pmic_ldo234_ops, 64),
+	TPS65217_REGULATOR("LDO3", TPS65217_LDO_3,
+				tps65217_pmic_ldo234_ops, 32),
+	TPS65217_REGULATOR("LDO4", TPS65217_LDO_4,
+				tps65217_pmic_ldo234_ops, 32),
+};
+
+static int __devinit tps65217_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev;
+	struct tps65217 *tps;
+	struct tps_info *info = &tps65217_pmic_regs[pdev->id];
+
+	/* Already set by core driver */
+	tps = dev_to_tps65217(pdev->dev.parent);
+	tps->info[pdev->id] = info;
+
+	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
+				  pdev->dev.platform_data, tps, NULL);
+	if (IS_ERR(rdev))
+		return PTR_ERR(rdev);
+
+	platform_set_drvdata(pdev, rdev);
+
+	return 0;
+}
+
+static int __devexit tps65217_regulator_remove(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	regulator_unregister(rdev);
+
+	return 0;
+}
+
+static struct platform_driver tps65217_regulator_driver = {
+	.driver = {
+		.name = "tps65217-pmic",
+	},
+	.probe = tps65217_regulator_probe,
+	.remove = __devexit_p(tps65217_regulator_remove),
+};
+
+static int __init tps65217_regulator_init(void)
+{
+	return platform_driver_register(&tps65217_regulator_driver);
+}
+subsys_initcall(tps65217_regulator_init);
+
+static void __exit tps65217_regulator_exit(void)
+{
+	platform_driver_unregister(&tps65217_regulator_driver);
+}
+module_exit(tps65217_regulator_exit);
+
+
+MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
+MODULE_DESCRIPTION("TPS65217 voltage regulator driver");
+MODULE_ALIAS("platform:tps65217-pmic");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 5c15ba0..15b5f1e 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -26,6 +26,9 @@
 #include <linux/mfd/tps65910.h>
 
 #define TPS65910_SUPPLY_STATE_ENABLED	0x1
+#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 |	\
+			TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 |		\
+			TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
 
 /* supported VIO voltages in milivolts */
 static const u16 VIO_VSEL_table[] = {
@@ -83,8 +86,8 @@ struct tps_info {
 	const char *name;
 	unsigned min_uV;
 	unsigned max_uV;
-	u8 table_len;
-	const u16 *table;
+	u8 n_voltages;
+	const u16 *voltage_table;
 };
 
 static struct tps_info tps65910_regs[] = {
@@ -95,8 +98,8 @@ static struct tps_info tps65910_regs[] = {
 		.name = "VIO",
 		.min_uV = 1500000,
 		.max_uV = 3300000,
-		.table_len = ARRAY_SIZE(VIO_VSEL_table),
-		.table = VIO_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
+		.voltage_table = VIO_VSEL_table,
 	},
 	{
 		.name = "VDD1",
@@ -112,132 +115,179 @@ static struct tps_info tps65910_regs[] = {
 		.name = "VDD3",
 		.min_uV = 5000000,
 		.max_uV = 5000000,
-		.table_len = ARRAY_SIZE(VDD3_VSEL_table),
-		.table = VDD3_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VDD3_VSEL_table),
+		.voltage_table = VDD3_VSEL_table,
 	},
 	{
 		.name = "VDIG1",
 		.min_uV = 1200000,
 		.max_uV = 2700000,
-		.table_len = ARRAY_SIZE(VDIG1_VSEL_table),
-		.table = VDIG1_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VDIG1_VSEL_table),
+		.voltage_table = VDIG1_VSEL_table,
 	},
 	{
 		.name = "VDIG2",
 		.min_uV = 1000000,
 		.max_uV = 1800000,
-		.table_len = ARRAY_SIZE(VDIG2_VSEL_table),
-		.table = VDIG2_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VDIG2_VSEL_table),
+		.voltage_table = VDIG2_VSEL_table,
 	},
 	{
 		.name = "VPLL",
 		.min_uV = 1000000,
 		.max_uV = 2500000,
-		.table_len = ARRAY_SIZE(VPLL_VSEL_table),
-		.table = VPLL_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VPLL_VSEL_table),
+		.voltage_table = VPLL_VSEL_table,
 	},
 	{
 		.name = "VDAC",
 		.min_uV = 1800000,
 		.max_uV = 2850000,
-		.table_len = ARRAY_SIZE(VDAC_VSEL_table),
-		.table = VDAC_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VDAC_VSEL_table),
+		.voltage_table = VDAC_VSEL_table,
 	},
 	{
 		.name = "VAUX1",
 		.min_uV = 1800000,
 		.max_uV = 2850000,
-		.table_len = ARRAY_SIZE(VAUX1_VSEL_table),
-		.table = VAUX1_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VAUX1_VSEL_table),
+		.voltage_table = VAUX1_VSEL_table,
 	},
 	{
 		.name = "VAUX2",
 		.min_uV = 1800000,
 		.max_uV = 3300000,
-		.table_len = ARRAY_SIZE(VAUX2_VSEL_table),
-		.table = VAUX2_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VAUX2_VSEL_table),
+		.voltage_table = VAUX2_VSEL_table,
 	},
 	{
 		.name = "VAUX33",
 		.min_uV = 1800000,
 		.max_uV = 3300000,
-		.table_len = ARRAY_SIZE(VAUX33_VSEL_table),
-		.table = VAUX33_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VAUX33_VSEL_table),
+		.voltage_table = VAUX33_VSEL_table,
 	},
 	{
 		.name = "VMMC",
 		.min_uV = 1800000,
 		.max_uV = 3300000,
-		.table_len = ARRAY_SIZE(VMMC_VSEL_table),
-		.table = VMMC_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VMMC_VSEL_table),
+		.voltage_table = VMMC_VSEL_table,
 	},
 };
 
 static struct tps_info tps65911_regs[] = {
 	{
+		.name = "VRTC",
+	},
+	{
 		.name = "VIO",
 		.min_uV = 1500000,
 		.max_uV = 3300000,
-		.table_len = ARRAY_SIZE(VIO_VSEL_table),
-		.table = VIO_VSEL_table,
+		.n_voltages = ARRAY_SIZE(VIO_VSEL_table),
+		.voltage_table = VIO_VSEL_table,
 	},
 	{
 		.name = "VDD1",
 		.min_uV = 600000,
 		.max_uV = 4500000,
+		.n_voltages = 73,
 	},
 	{
 		.name = "VDD2",
 		.min_uV = 600000,
 		.max_uV = 4500000,
+		.n_voltages = 73,
 	},
 	{
 		.name = "VDDCTRL",
 		.min_uV = 600000,
 		.max_uV = 1400000,
+		.n_voltages = 65,
 	},
 	{
 		.name = "LDO1",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 47,
 	},
 	{
 		.name = "LDO2",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 47,
 	},
 	{
 		.name = "LDO3",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 24,
 	},
 	{
 		.name = "LDO4",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 47,
 	},
 	{
 		.name = "LDO5",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 24,
 	},
 	{
 		.name = "LDO6",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 24,
 	},
 	{
 		.name = "LDO7",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 24,
 	},
 	{
 		.name = "LDO8",
 		.min_uV = 1000000,
 		.max_uV = 3300000,
+		.n_voltages = 24,
 	},
 };
 
+#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
+static unsigned int tps65910_ext_sleep_control[] = {
+	0,
+	EXT_CONTROL_REG_BITS(VIO,    1, 0),
+	EXT_CONTROL_REG_BITS(VDD1,   1, 1),
+	EXT_CONTROL_REG_BITS(VDD2,   1, 2),
+	EXT_CONTROL_REG_BITS(VDD3,   1, 3),
+	EXT_CONTROL_REG_BITS(VDIG1,  0, 1),
+	EXT_CONTROL_REG_BITS(VDIG2,  0, 2),
+	EXT_CONTROL_REG_BITS(VPLL,   0, 6),
+	EXT_CONTROL_REG_BITS(VDAC,   0, 7),
+	EXT_CONTROL_REG_BITS(VAUX1,  0, 3),
+	EXT_CONTROL_REG_BITS(VAUX2,  0, 4),
+	EXT_CONTROL_REG_BITS(VAUX33, 0, 5),
+	EXT_CONTROL_REG_BITS(VMMC,   0, 0),
+};
+
+static unsigned int tps65911_ext_sleep_control[] = {
+	0,
+	EXT_CONTROL_REG_BITS(VIO,     1, 0),
+	EXT_CONTROL_REG_BITS(VDD1,    1, 1),
+	EXT_CONTROL_REG_BITS(VDD2,    1, 2),
+	EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3),
+	EXT_CONTROL_REG_BITS(LDO1,    0, 1),
+	EXT_CONTROL_REG_BITS(LDO2,    0, 2),
+	EXT_CONTROL_REG_BITS(LDO3,    0, 7),
+	EXT_CONTROL_REG_BITS(LDO4,    0, 6),
+	EXT_CONTROL_REG_BITS(LDO5,    0, 3),
+	EXT_CONTROL_REG_BITS(LDO6,    0, 0),
+	EXT_CONTROL_REG_BITS(LDO7,    0, 5),
+	EXT_CONTROL_REG_BITS(LDO8,    0, 4),
+};
+
 struct tps65910_reg {
 	struct regulator_desc *desc;
 	struct tps65910 *mfd;
@@ -247,6 +297,8 @@ struct tps65910_reg {
 	int num_regulators;
 	int mode;
 	int  (*get_ctrl_reg)(int);
+	unsigned int *ext_sleep_control;
+	unsigned int board_ext_control[TPS65910_NUM_REGS];
 };
 
 static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
@@ -572,7 +624,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev)
 		return -EINVAL;
 	}
 
-	voltage = pmic->info[id]->table[value] * 1000;
+	voltage = pmic->info[id]->voltage_table[value] * 1000;
 
 	return voltage;
 }
@@ -622,8 +674,9 @@ static int tps65911_get_voltage(struct regulator_dev *dev)
 		step_mv = 100;
 		break;
 	case TPS65910_REG_VIO:
-		return pmic->info[id]->table[value] * 1000;
-		break;
+		value &= LDO_SEL_MASK;
+		value >>= LDO_SEL_SHIFT;
+		return pmic->info[id]->voltage_table[value] * 1000;
 	default:
 		return -EINVAL;
 	}
@@ -715,9 +768,11 @@ static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector)
 	case TPS65911_REG_LDO6:
 	case TPS65911_REG_LDO7:
 	case TPS65911_REG_LDO8:
-	case TPS65910_REG_VIO:
 		return tps65910_modify_bits(pmic, reg,
 				(selector << LDO_SEL_SHIFT), LDO3_SEL_MASK);
+	case TPS65910_REG_VIO:
+		return tps65910_modify_bits(pmic, reg,
+				(selector << LDO_SEL_SHIFT), LDO_SEL_MASK);
 	}
 
 	return -EINVAL;
@@ -756,10 +811,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev,
 	if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC)
 		return -EINVAL;
 
-	if (selector >= pmic->info[id]->table_len)
+	if (selector >= pmic->info[id]->n_voltages)
 		return -EINVAL;
 	else
-		voltage = pmic->info[id]->table[selector] * 1000;
+		voltage = pmic->info[id]->voltage_table[selector] * 1000;
 
 	return voltage;
 }
@@ -795,7 +850,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
 		step_mv = 100;
 		break;
 	case TPS65910_REG_VIO:
-		return pmic->info[id]->table[selector] * 1000;
+		return pmic->info[id]->voltage_table[selector] * 1000;
 	default:
 		return -EINVAL;
 	}
@@ -847,6 +902,131 @@ static struct regulator_ops tps65911_ops = {
 	.list_voltage		= tps65911_list_voltage,
 };
 
+static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
+		int id, int ext_sleep_config)
+{
+	struct tps65910 *mfd = pmic->mfd;
+	u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF;
+	u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF);
+	int ret;
+
+	/*
+	 * Regulator can not be control from multiple external input EN1, EN2
+	 * and EN3 together.
+	 */
+	if (ext_sleep_config & EXT_SLEEP_CONTROL) {
+		int en_count;
+		en_count = ((ext_sleep_config &
+				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0);
+		en_count += ((ext_sleep_config &
+				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0);
+		en_count += ((ext_sleep_config &
+				TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0);
+		if (en_count > 1) {
+			dev_err(mfd->dev,
+				"External sleep control flag is not proper\n");
+			return -EINVAL;
+		}
+	}
+
+	pmic->board_ext_control[id] = ext_sleep_config;
+
+	/* External EN1 control */
+	if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1)
+		ret = tps65910_set_bits(mfd,
+				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
+	else
+		ret = tps65910_clear_bits(mfd,
+				TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
+	if (ret < 0) {
+		dev_err(mfd->dev,
+			"Error in configuring external control EN1\n");
+		return ret;
+	}
+
+	/* External EN2 control */
+	if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2)
+		ret = tps65910_set_bits(mfd,
+				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
+	else
+		ret = tps65910_clear_bits(mfd,
+				TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
+	if (ret < 0) {
+		dev_err(mfd->dev,
+			"Error in configuring external control EN2\n");
+		return ret;
+	}
+
+	/* External EN3 control for TPS65910 LDO only */
+	if ((tps65910_chip_id(mfd) == TPS65910) &&
+			(id >= TPS65910_REG_VDIG1)) {
+		if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
+			ret = tps65910_set_bits(mfd,
+				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
+		else
+			ret = tps65910_clear_bits(mfd,
+				TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
+		if (ret < 0) {
+			dev_err(mfd->dev,
+				"Error in configuring external control EN3\n");
+			return ret;
+		}
+	}
+
+	/* Return if no external control is selected */
+	if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) {
+		/* Clear all sleep controls */
+		ret = tps65910_clear_bits(mfd,
+			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
+		if (!ret)
+			ret = tps65910_clear_bits(mfd,
+				TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
+		if (ret < 0)
+			dev_err(mfd->dev,
+				"Error in configuring SLEEP register\n");
+		return ret;
+	}
+
+	/*
+	 * For regulator that has separate operational and sleep register make
+	 * sure that operational is used and clear sleep register to turn
+	 * regulator off when external control is inactive
+	 */
+	if ((id == TPS65910_REG_VDD1) ||
+		(id == TPS65910_REG_VDD2) ||
+			((id == TPS65911_REG_VDDCTRL) &&
+				(tps65910_chip_id(mfd) == TPS65911))) {
+		int op_reg_add = pmic->get_ctrl_reg(id) + 1;
+		int sr_reg_add = pmic->get_ctrl_reg(id) + 2;
+		int opvsel = tps65910_reg_read(pmic, op_reg_add);
+		int srvsel = tps65910_reg_read(pmic, sr_reg_add);
+		if (opvsel & VDD1_OP_CMD_MASK) {
+			u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
+			ret = tps65910_reg_write(pmic, op_reg_add, reg_val);
+			if (ret < 0) {
+				dev_err(mfd->dev,
+					"Error in configuring op register\n");
+				return ret;
+			}
+		}
+		ret = tps65910_reg_write(pmic, sr_reg_add, 0);
+		if (ret < 0) {
+			dev_err(mfd->dev, "Error in settting sr register\n");
+			return ret;
+		}
+	}
+
+	ret = tps65910_clear_bits(mfd,
+			TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
+	if (!ret)
+		ret = tps65910_set_bits(mfd,
+			TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
+	if (ret < 0)
+		dev_err(mfd->dev,
+			"Error in configuring SLEEP register\n");
+	return ret;
+}
+
 static __devinit int tps65910_probe(struct platform_device *pdev)
 {
 	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
@@ -877,11 +1057,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
 	case TPS65910:
 		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
 		pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
+		pmic->ext_sleep_control = tps65910_ext_sleep_control;
 		info = tps65910_regs;
 		break;
 	case TPS65911:
 		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
 		pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
+		pmic->ext_sleep_control = tps65911_ext_sleep_control;
 		info = tps65911_regs;
 		break;
 	default:
@@ -926,7 +1108,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
 
 		pmic->desc[i].name = info->name;
 		pmic->desc[i].id = i;
-		pmic->desc[i].n_voltages = info->table_len;
+		pmic->desc[i].n_voltages = info->n_voltages;
 
 		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
 			pmic->desc[i].ops = &tps65910_ops_dcdc;
@@ -944,6 +1126,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
 				pmic->desc[i].ops = &tps65911_ops;
 		}
 
+		err = tps65910_set_ext_sleep_config(pmic, i,
+				pmic_plat_data->regulator_ext_sleep_control[i]);
+		/*
+		 * Failing on regulator for configuring externally control
+		 * is not a serious issue, just throw warning.
+		 */
+		if (err < 0)
+			dev_warn(tps65910->dev,
+				"Failed to initialise ext control config\n");
+
 		pmic->desc[i].type = REGULATOR_VOLTAGE;
 		pmic->desc[i].owner = THIS_MODULE;
 
@@ -990,6 +1182,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static void tps65910_shutdown(struct platform_device *pdev)
+{
+	struct tps65910_reg *pmic = platform_get_drvdata(pdev);
+	int i;
+
+	/*
+	 * Before bootloader jumps to kernel, it makes sure that required
+	 * external control signals are in desired state so that given rails
+	 * can be configure accordingly.
+	 * If rails are configured to be controlled from external control
+	 * then before shutting down/rebooting the system, the external
+	 * control configuration need to be remove from the rails so that
+	 * its output will be available as per register programming even
+	 * if external controls are removed. This is require when the POR
+	 * value of the control signals are not in active state and before
+	 * bootloader initializes it, the system requires the rail output
+	 * to be active for booting.
+	 */
+	for (i = 0; i < pmic->num_regulators; i++) {
+		int err;
+		if (!pmic->rdev[i])
+			continue;
+
+		err = tps65910_set_ext_sleep_config(pmic, i, 0);
+		if (err < 0)
+			dev_err(&pdev->dev,
+				"Error in clearing external control\n");
+	}
+}
+
 static struct platform_driver tps65910_driver = {
 	.driver = {
 		.name = "tps65910-pmic",
@@ -997,6 +1219,7 @@ static struct platform_driver tps65910_driver = {
 	},
 	.probe = tps65910_probe,
 	.remove = __devexit_p(tps65910_remove),
+	.shutdown = tps65910_shutdown,
 };
 
 static int __init tps65910_init(void)
@@ -1012,6 +1235,6 @@ static void __exit tps65910_cleanup(void)
 module_exit(tps65910_cleanup);
 
 MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
-MODULE_DESCRIPTION("TPS6507x voltage regulator driver");
+MODULE_DESCRIPTION("TPS65910/TPS65911 voltage regulator driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:tps65910-pmic");
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 181a2cf..7ff8bb2 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -58,6 +58,16 @@ struct twlreg_info {
 
 	/* chip specific features */
 	unsigned long 		features;
+
+	/*
+	 * optional override functions for voltage set/get
+	 * these are currently only used for SMPS regulators
+	 */
+	int			(*get_voltage)(void *data);
+	int			(*set_voltage)(void *data, int target_uV);
+
+	/* data passed from board for external get/set voltage */
+	void			*data;
 };
 
 
@@ -522,15 +532,25 @@ twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
 	struct twlreg_info *info = rdev_get_drvdata(rdev);
 	int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);
 
-	twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030,
-		vsel);
+	if (info->set_voltage) {
+		return info->set_voltage(info->data, min_uV);
+	} else {
+		twlreg_write(info, TWL_MODULE_PM_RECEIVER,
+			VREG_VOLTAGE_SMPS_4030, vsel);
+	}
+
 	return 0;
 }
 
 static int twl4030smps_get_voltage(struct regulator_dev *rdev)
 {
 	struct twlreg_info *info = rdev_get_drvdata(rdev);
-	int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
+	int vsel;
+
+	if (info->get_voltage)
+		return info->get_voltage(info->data);
+
+	vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
 		VREG_VOLTAGE_SMPS_4030);
 
 	return vsel * 12500 + 600000;
@@ -755,12 +775,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
 	case 0:
 		if (min_uV == 0)
 			vsel = 0;
-		else if ((min_uV >= 600000) && (max_uV <= 1300000)) {
+		else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
+			int calc_uV;
 			vsel = (min_uV - 600000) / 125;
 			if (vsel % 100)
 				vsel += 100;
 			vsel /= 100;
 			vsel++;
+			calc_uV = twl6030smps_list_voltage(rdev, vsel);
+			if (calc_uV > max_uV)
+				return -EINVAL;
 		}
 		/* Values 1..57 for vsel are linear and can be calculated
 		 * values 58..62 are non linear.
@@ -781,12 +805,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
 	case SMPS_OFFSET_EN:
 		if (min_uV == 0)
 			vsel = 0;
-		else if ((min_uV >= 700000) && (max_uV <= 1420000)) {
+		else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
+			int calc_uV;
 			vsel = (min_uV - 700000) / 125;
 			if (vsel % 100)
 				vsel += 100;
 			vsel /= 100;
 			vsel++;
+			calc_uV = twl6030smps_list_voltage(rdev, vsel);
+			if (calc_uV > max_uV)
+				return -EINVAL;
 		}
 		/* Values 1..57 for vsel are linear and can be calculated
 		 * values 58..62 are non linear.
@@ -819,7 +847,7 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
 		if (min_uV == 0)
 			vsel = 0;
 		else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
-			vsel = (min_uV - 1852000) / 386;
+			vsel = (min_uV - 2161000) / 386;
 			if (vsel % 100)
 				vsel += 100;
 			vsel /= 100;
@@ -1052,6 +1080,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
 	struct regulator_init_data	*initdata;
 	struct regulation_constraints	*c;
 	struct regulator_dev		*rdev;
+	struct twl_regulator_driver_data	*drvdata;
 
 	for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
 		if (twl_regs[i].desc.id != pdev->id)
@@ -1066,8 +1095,16 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
 	if (!initdata)
 		return -EINVAL;
 
-	/* copy the features into regulator data */
-	info->features = (unsigned long)initdata->driver_data;
+	drvdata = initdata->driver_data;
+
+	if (!drvdata)
+		return -EINVAL;
+
+	/* copy the driver data into regulator data */
+	info->features = drvdata->features;
+	info->data = drvdata->data;
+	info->set_voltage = drvdata->set_voltage;
+	info->get_voltage = drvdata->get_voltage;
 
 	/* Constrain board-specific capabilities according to what
 	 * this driver and the chip itself can actually do.
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 6894009..4f46067 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1544,7 +1544,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
 		return -ENOMEM;
 	}
 
-	led->isink_consumer.dev = &pdev->dev;
+	led->isink_consumer.dev_name = dev_name(&pdev->dev);
 	led->isink_consumer.supply = "led_isink";
 	led->isink_init.num_consumer_supplies = 1;
 	led->isink_init.consumer_supplies = &led->isink_consumer;
@@ -1559,7 +1559,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
 		return ret;
 	}
 
-	led->dcdc_consumer.dev = &pdev->dev;
+	led->dcdc_consumer.dev_name = dev_name(&pdev->dev);
 	led->dcdc_consumer.supply = "led_vcc";
 	led->dcdc_init.num_consumer_supplies = 1;
 	led->dcdc_init.consumer_supplies = &led->dcdc_consumer;
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c
index 435e335..75ed402 100644
--- a/drivers/regulator/wm8994-regulator.c
+++ b/drivers/regulator/wm8994-regulator.c
@@ -241,7 +241,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
 	if (!pdata)
 		return -ENODEV;
 
-	ldo = kzalloc(sizeof(struct wm8994_ldo), GFP_KERNEL);
+	ldo = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_ldo), GFP_KERNEL);
 	if (ldo == NULL) {
 		dev_err(&pdev->dev, "Unable to allocate private data\n");
 		return -ENOMEM;
@@ -285,7 +285,6 @@ err_gpio:
 	if (gpio_is_valid(ldo->enable))
 		gpio_free(ldo->enable);
 err:
-	kfree(ldo);
 	return ret;
 }
 
@@ -298,7 +297,6 @@ static __devexit int wm8994_ldo_remove(struct platform_device *pdev)
 	regulator_unregister(ldo->regulator);
 	if (gpio_is_valid(ldo->enable))
 		gpio_free(ldo->enable);
-	kfree(ldo);
 
 	return 0;
 }
diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
new file mode 100644
index 0000000..25fc4cc
--- /dev/null
+++ b/drivers/remoteproc/Kconfig
@@ -0,0 +1,29 @@
+menu "Remoteproc drivers (EXPERIMENTAL)"
+
+# REMOTEPROC gets selected by whoever wants it
+config REMOTEPROC
+	tristate
+	depends on EXPERIMENTAL
+
+config OMAP_REMOTEPROC
+	tristate "OMAP remoteproc support"
+	depends on ARCH_OMAP4
+	select OMAP_IOMMU
+	select REMOTEPROC
+	select OMAP_MBOX_FWK
+	select RPMSG
+	default m
+	help
+	  Say y here to support OMAP's remote processors (dual M3
+	  and DSP on OMAP4) via the remote processor framework.
+
+	  Currently only supported on OMAP4.
+
+	  Usually you want to say y here, in order to enable multimedia
+	  use-cases to run on your platform (multimedia codecs are
+	  offloaded to remote DSP processors using this framework).
+
+	  It's safe to say n here if you're not interested in multimedia
+	  offloading or just want a bare minimum kernel.
+
+endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
new file mode 100644
index 0000000..df0897f
--- /dev/null
+++ b/drivers/remoteproc/Makefile
@@ -0,0 +1,9 @@
+#
+# Generic framework for controlling remote processors
+#
+
+obj-$(CONFIG_REMOTEPROC)		+= remoteproc.o
+remoteproc-y				:= remoteproc_core.o
+remoteproc-y				+= remoteproc_debugfs.o
+remoteproc-y				+= remoteproc_rpmsg.o
+obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
new file mode 100644
index 0000000..aa3ce52
--- /dev/null
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -0,0 +1,238 @@
+/*
+ * OMAP Remote Processor driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Hari Kanigeri <h-kanigeri2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/remoteproc.h>
+
+#include <plat/mailbox.h>
+#include <plat/remoteproc.h>
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+
+/**
+ * struct omap_rproc - omap remote processor state
+ * @mbox: omap mailbox handle
+ * @nb: notifier block that will be invoked on inbound mailbox messages
+ * @rproc: rproc handle
+ */
+struct omap_rproc {
+	struct omap_mbox *mbox;
+	struct notifier_block nb;
+	struct rproc *rproc;
+};
+
+/**
+ * omap_rproc_mbox_callback() - inbound mailbox message handler
+ * @this: notifier block
+ * @index: unused
+ * @data: mailbox payload
+ *
+ * This handler is invoked by omap's mailbox driver whenever a mailbox
+ * message is received. Usually, the mailbox payload simply contains
+ * the index of the virtqueue that is kicked by the remote processor,
+ * and we let remoteproc core handle it.
+ *
+ * In addition to virtqueue indices, we also have some out-of-band values
+ * that indicates different events. Those values are deliberately very
+ * big so they don't coincide with virtqueue indices.
+ */
+static int omap_rproc_mbox_callback(struct notifier_block *this,
+					unsigned long index, void *data)
+{
+	mbox_msg_t msg = (mbox_msg_t) data;
+	struct omap_rproc *oproc = container_of(this, struct omap_rproc, nb);
+	struct device *dev = oproc->rproc->dev;
+	const char *name = oproc->rproc->name;
+
+	dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+
+	switch (msg) {
+	case RP_MBOX_CRASH:
+		/* just log this for now. later, we'll also do recovery */
+		dev_err(dev, "omap rproc %s crashed\n", name);
+		break;
+	case RP_MBOX_ECHO_REPLY:
+		dev_info(dev, "received echo reply from %s\n", name);
+		break;
+	default:
+		/* ignore vq indices which are too large to be valid */
+		if (msg >= 2) {
+			dev_warn(dev, "invalid mbox msg: 0x%x\n", msg);
+			break;
+		}
+
+		/*
+		 * At this point, 'msg' contains the index of the vring
+		 * which was just triggered.
+		 */
+		if (rproc_vq_interrupt(oproc->rproc, msg) == IRQ_NONE)
+			dev_dbg(dev, "no message was found in vqid %d\n", msg);
+	}
+
+	return NOTIFY_DONE;
+}
+
+/* kick a virtqueue */
+static void omap_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct omap_rproc *oproc = rproc->priv;
+	int ret;
+
+	/* send the index of the triggered virtqueue in the mailbox payload */
+	ret = omap_mbox_msg_send(oproc->mbox, vqid);
+	if (ret)
+		dev_err(rproc->dev, "omap_mbox_msg_send failed: %d\n", ret);
+}
+
+/*
+ * Power up the remote processor.
+ *
+ * This function will be invoked only after the firmware for this rproc
+ * was loaded, parsed successfully, and all of its resource requirements
+ * were met.
+ */
+static int omap_rproc_start(struct rproc *rproc)
+{
+	struct omap_rproc *oproc = rproc->priv;
+	struct platform_device *pdev = to_platform_device(rproc->dev);
+	struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
+	int ret;
+
+	oproc->nb.notifier_call = omap_rproc_mbox_callback;
+
+	/* every omap rproc is assigned a mailbox instance for messaging */
+	oproc->mbox = omap_mbox_get(pdata->mbox_name, &oproc->nb);
+	if (IS_ERR(oproc->mbox)) {
+		ret = PTR_ERR(oproc->mbox);
+		dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Ping the remote processor. this is only for sanity-sake;
+	 * there is no functional effect whatsoever.
+	 *
+	 * Note that the reply will _not_ arrive immediately: this message
+	 * will wait in the mailbox fifo until the remote processor is booted.
+	 */
+	ret = omap_mbox_msg_send(oproc->mbox, RP_MBOX_ECHO_REQUEST);
+	if (ret) {
+		dev_err(rproc->dev, "omap_mbox_get failed: %d\n", ret);
+		goto put_mbox;
+	}
+
+	ret = pdata->device_enable(pdev);
+	if (ret) {
+		dev_err(rproc->dev, "omap_device_enable failed: %d\n", ret);
+		goto put_mbox;
+	}
+
+	return 0;
+
+put_mbox:
+	omap_mbox_put(oproc->mbox, &oproc->nb);
+	return ret;
+}
+
+/* power off the remote processor */
+static int omap_rproc_stop(struct rproc *rproc)
+{
+	struct platform_device *pdev = to_platform_device(rproc->dev);
+	struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
+	struct omap_rproc *oproc = rproc->priv;
+	int ret;
+
+	ret = pdata->device_shutdown(pdev);
+	if (ret)
+		return ret;
+
+	omap_mbox_put(oproc->mbox, &oproc->nb);
+
+	return 0;
+}
+
+static struct rproc_ops omap_rproc_ops = {
+	.start		= omap_rproc_start,
+	.stop		= omap_rproc_stop,
+	.kick		= omap_rproc_kick,
+};
+
+static int __devinit omap_rproc_probe(struct platform_device *pdev)
+{
+	struct omap_rproc_pdata *pdata = pdev->dev.platform_data;
+	struct omap_rproc *oproc;
+	struct rproc *rproc;
+	int ret;
+
+	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret);
+		return ret;
+	}
+
+	rproc = rproc_alloc(&pdev->dev, pdata->name, &omap_rproc_ops,
+				pdata->firmware, sizeof(*oproc));
+	if (!rproc)
+		return -ENOMEM;
+
+	oproc = rproc->priv;
+	oproc->rproc = rproc;
+
+	platform_set_drvdata(pdev, rproc);
+
+	ret = rproc_register(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_free(rproc);
+	return ret;
+}
+
+static int __devexit omap_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+
+	return rproc_unregister(rproc);
+}
+
+static struct platform_driver omap_rproc_driver = {
+	.probe = omap_rproc_probe,
+	.remove = __devexit_p(omap_rproc_remove),
+	.driver = {
+		.name = "omap-rproc",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(omap_rproc_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("OMAP Remote Processor control driver");
diff --git a/drivers/remoteproc/omap_remoteproc.h b/drivers/remoteproc/omap_remoteproc.h
new file mode 100644
index 0000000..f6d2036
--- /dev/null
+++ b/drivers/remoteproc/omap_remoteproc.h
@@ -0,0 +1,69 @@
+/*
+ * Remote processor messaging
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _OMAP_RPMSG_H
+#define _OMAP_RPMSG_H
+
+/*
+ * enum - Predefined Mailbox Messages
+ *
+ * @RP_MBOX_READY: informs the M3's that we're up and running. this is
+ * part of the init sequence sent that the M3 expects to see immediately
+ * after it is booted.
+ *
+ * @RP_MBOX_PENDING_MSG: informs the receiver that there is an inbound
+ * message waiting in its own receive-side vring. please note that currently
+ * this message is optional: alternatively, one can explicitly send the index
+ * of the triggered virtqueue itself. the preferred approach will be decided
+ * as we progress and experiment with those two different approaches.
+ *
+ * @RP_MBOX_CRASH: this message is sent if BIOS crashes
+ *
+ * @RP_MBOX_ECHO_REQUEST: a mailbox-level "ping" message.
+ *
+ * @RP_MBOX_ECHO_REPLY: a mailbox-level reply to a "ping"
+ *
+ * @RP_MBOX_ABORT_REQUEST: a "please crash" request, used for testing the
+ * recovery mechanism (to some extent).
+ */
+enum omap_rp_mbox_messages {
+	RP_MBOX_READY		= 0xFFFFFF00,
+	RP_MBOX_PENDING_MSG	= 0xFFFFFF01,
+	RP_MBOX_CRASH		= 0xFFFFFF02,
+	RP_MBOX_ECHO_REQUEST	= 0xFFFFFF03,
+	RP_MBOX_ECHO_REPLY	= 0xFFFFFF04,
+	RP_MBOX_ABORT_REQUEST	= 0xFFFFFF05,
+};
+
+#endif /* _OMAP_RPMSG_H */
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
new file mode 100644
index 0000000..729911b
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -0,0 +1,1450 @@
+/*
+ * Remote Processor Framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Robert Tivy <rtivy@ti.com>
+ * Armando Uribe De Leon <x0095078@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt)    "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
+#include <linux/string.h>
+#include <linux/debugfs.h>
+#include <linux/remoteproc.h>
+#include <linux/iommu.h>
+#include <linux/klist.h>
+#include <linux/elf.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_ring.h>
+#include <asm/byteorder.h>
+
+#include "remoteproc_internal.h"
+
+static void klist_rproc_get(struct klist_node *n);
+static void klist_rproc_put(struct klist_node *n);
+
+/*
+ * klist of the available remote processors.
+ *
+ * We need this in order to support name-based lookups (needed by the
+ * rproc_get_by_name()).
+ *
+ * That said, we don't use rproc_get_by_name() anymore within the rpmsg
+ * framework. The use cases that do require its existence should be
+ * scrutinized, and hopefully migrated to rproc_boot() using device-based
+ * binding.
+ *
+ * If/when this materializes, we could drop the klist (and the by_name
+ * API).
+ */
+static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put);
+
+typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
+				struct fw_resource *rsc, int len);
+typedef int (*rproc_handle_resource_t)(struct rproc *rproc,
+				struct fw_resource *rsc);
+
+/*
+ * This is the IOMMU fault handler we register with the IOMMU API
+ * (when relevant; not all remote processors access memory through
+ * an IOMMU).
+ *
+ * IOMMU core will invoke this handler whenever the remote processor
+ * will try to access an unmapped device address.
+ *
+ * Currently this is mostly a stub, but it will be later used to trigger
+ * the recovery of the remote processor.
+ */
+static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev,
+		unsigned long iova, int flags)
+{
+	dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags);
+
+	/*
+	 * Let the iommu core know we're not really handling this fault;
+	 * we just plan to use this as a recovery trigger.
+	 */
+	return -ENOSYS;
+}
+
+static int rproc_enable_iommu(struct rproc *rproc)
+{
+	struct iommu_domain *domain;
+	struct device *dev = rproc->dev;
+	int ret;
+
+	/*
+	 * We currently use iommu_present() to decide if an IOMMU
+	 * setup is needed.
+	 *
+	 * This works for simple cases, but will easily fail with
+	 * platforms that do have an IOMMU, but not for this specific
+	 * rproc.
+	 *
+	 * This will be easily solved by introducing hw capabilities
+	 * that will be set by the remoteproc driver.
+	 */
+	if (!iommu_present(dev->bus)) {
+		dev_dbg(dev, "iommu not found\n");
+		return 0;
+	}
+
+	domain = iommu_domain_alloc(dev->bus);
+	if (!domain) {
+		dev_err(dev, "can't alloc iommu domain\n");
+		return -ENOMEM;
+	}
+
+	iommu_set_fault_handler(domain, rproc_iommu_fault);
+
+	ret = iommu_attach_device(domain, dev);
+	if (ret) {
+		dev_err(dev, "can't attach iommu device: %d\n", ret);
+		goto free_domain;
+	}
+
+	rproc->domain = domain;
+
+	return 0;
+
+free_domain:
+	iommu_domain_free(domain);
+	return ret;
+}
+
+static void rproc_disable_iommu(struct rproc *rproc)
+{
+	struct iommu_domain *domain = rproc->domain;
+	struct device *dev = rproc->dev;
+
+	if (!domain)
+		return;
+
+	iommu_detach_device(domain, dev);
+	iommu_domain_free(domain);
+
+	return;
+}
+
+/*
+ * Some remote processors will ask us to allocate them physically contiguous
+ * memory regions (which we call "carveouts"), and map them to specific
+ * device addresses (which are hardcoded in the firmware).
+ *
+ * They may then ask us to copy objects into specific device addresses (e.g.
+ * code/data sections) or expose us certain symbols in other device address
+ * (e.g. their trace buffer).
+ *
+ * This function is an internal helper with which we can go over the allocated
+ * carveouts and translate specific device address to kernel virtual addresses
+ * so we can access the referenced memory.
+ *
+ * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too,
+ * but only on kernel direct mapped RAM memory. Instead, we're just using
+ * here the output of the DMA API, which should be more correct.
+ */
+static void *rproc_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+	struct rproc_mem_entry *carveout;
+	void *ptr = NULL;
+
+	list_for_each_entry(carveout, &rproc->carveouts, node) {
+		int offset = da - carveout->da;
+
+		/* try next carveout if da is too small */
+		if (offset < 0)
+			continue;
+
+		/* try next carveout if da is too large */
+		if (offset + len > carveout->len)
+			continue;
+
+		ptr = carveout->va + offset;
+
+		break;
+	}
+
+	return ptr;
+}
+
+/**
+ * rproc_load_segments() - load firmware segments to memory
+ * @rproc: remote processor which will be booted using these fw segments
+ * @elf_data: the content of the ELF firmware image
+ * @len: firmware size (in bytes)
+ *
+ * This function loads the firmware segments to memory, where the remote
+ * processor expects them.
+ *
+ * Some remote processors will expect their code and data to be placed
+ * in specific device addresses, and can't have them dynamically assigned.
+ *
+ * We currently support only those kind of remote processors, and expect
+ * the program header's paddr member to contain those addresses. We then go
+ * through the physically contiguous "carveout" memory regions which we
+ * allocated (and mapped) earlier on behalf of the remote processor,
+ * and "translate" device address to kernel addresses, so we can copy the
+ * segments where they are expected.
+ *
+ * Currently we only support remote processors that required carveout
+ * allocations and got them mapped onto their iommus. Some processors
+ * might be different: they might not have iommus, and would prefer to
+ * directly allocate memory for every segment/resource. This is not yet
+ * supported, though.
+ */
+static int
+rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len)
+{
+	struct device *dev = rproc->dev;
+	struct elf32_hdr *ehdr;
+	struct elf32_phdr *phdr;
+	int i, ret = 0;
+
+	ehdr = (struct elf32_hdr *)elf_data;
+	phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff);
+
+	/* go through the available ELF segments */
+	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+		u32 da = phdr->p_paddr;
+		u32 memsz = phdr->p_memsz;
+		u32 filesz = phdr->p_filesz;
+		u32 offset = phdr->p_offset;
+		void *ptr;
+
+		if (phdr->p_type != PT_LOAD)
+			continue;
+
+		dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n",
+					phdr->p_type, da, memsz, filesz);
+
+		if (filesz > memsz) {
+			dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n",
+							filesz, memsz);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (offset + filesz > len) {
+			dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n",
+					offset + filesz, len);
+			ret = -EINVAL;
+			break;
+		}
+
+		/* grab the kernel address for this device address */
+		ptr = rproc_da_to_va(rproc, da, memsz);
+		if (!ptr) {
+			dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz);
+			ret = -EINVAL;
+			break;
+		}
+
+		/* put the segment where the remote processor expects it */
+		if (phdr->p_filesz)
+			memcpy(ptr, elf_data + phdr->p_offset, filesz);
+
+		/*
+		 * Zero out remaining memory for this segment.
+		 *
+		 * This isn't strictly required since dma_alloc_coherent already
+		 * did this for us. albeit harmless, we may consider removing
+		 * this.
+		 */
+		if (memsz > filesz)
+			memset(ptr + filesz, 0, memsz - filesz);
+	}
+
+	return ret;
+}
+
+/**
+ * rproc_handle_virtio_hdr() - handle a virtio header resource
+ * @rproc: the remote processor
+ * @rsc: the resource descriptor
+ *
+ * The existence of this virtio hdr resource entry means that the firmware
+ * of this @rproc supports this virtio device.
+ *
+ * Currently we support only a single virtio device of type VIRTIO_ID_RPMSG,
+ * but the plan is to remove this limitation and support any number
+ * of virtio devices (and of any type). We'll also add support for dynamically
+ * adding (and removing) virtio devices over the rpmsg bus, but small
+ * firmwares that doesn't want to get involved with rpmsg will be able
+ * to simple use the resource table for this.
+ *
+ * At this point this virtio header entry is rather simple: it just
+ * announces the virtio device id and the supported virtio device features.
+ * The plan though is to extend this to include the vring information and
+ * the virtio config space, too (but first, some resource table overhaul
+ * is needed: move from fixed-sized to variable-length TLV entries).
+ *
+ * For now, the 'flags' member of the resource entry contains the virtio
+ * device id, the 'da' member contains the device features, and 'pa' is
+ * where we need to store the guest features once negotiation completes.
+ * As usual, the 'id' member of this resource contains the index of this
+ * resource type (i.e. is this the first virtio hdr entry, the 2nd, ...).
+ *
+ * Returns 0 on success, or an appropriate error code otherwise
+ */
+static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc)
+{
+	struct rproc_vdev *rvdev;
+
+	/* we only support VIRTIO_ID_RPMSG devices for now */
+	if (rsc->flags != VIRTIO_ID_RPMSG) {
+		dev_warn(rproc->dev, "unsupported vdev: %d\n", rsc->flags);
+		return -EINVAL;
+	}
+
+	/* we only support a single vdev per rproc for now */
+	if (rsc->id || rproc->rvdev) {
+		dev_warn(rproc->dev, "redundant vdev entry: %s\n", rsc->name);
+		return -EINVAL;
+	}
+
+	rvdev = kzalloc(sizeof(struct rproc_vdev), GFP_KERNEL);
+	if (!rvdev)
+		return -ENOMEM;
+
+	/* remember the device features */
+	rvdev->dfeatures = rsc->da;
+
+	rproc->rvdev = rvdev;
+	rvdev->rproc = rproc;
+
+	return 0;
+}
+
+/**
+ * rproc_handle_vring() - handle a vring fw resource
+ * @rproc: the remote processor
+ * @rsc: the vring resource descriptor
+ *
+ * This resource entry requires allocation of non-cacheable memory
+ * for a virtio vring. Currently we only support two vrings per remote
+ * processor, required for the virtio rpmsg device.
+ *
+ * The 'len' member of @rsc should contain the number of buffers this vring
+ * support and 'da' should either contain the device address where
+ * the remote processor is expecting the vring, or indicate that
+ * dynamically allocation of the vring's device address is supported.
+ *
+ * Note: 'da' is currently not handled. This will be revised when the generic
+ * iommu-based DMA API will arrive, or a dynanic & non-iommu use case show
+ * up. Meanwhile, statically-addressed iommu-based images should use
+ * RSC_DEVMEM resource entries to map their require 'da' to the physical
+ * address of their base CMA region.
+ *
+ * Returns 0 on success, or an appropriate error code otherwise
+ */
+static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc)
+{
+	struct device *dev = rproc->dev;
+	struct rproc_vdev *rvdev = rproc->rvdev;
+	dma_addr_t dma;
+	int size, id = rsc->id;
+	void *va;
+
+	/* no vdev is in place ? */
+	if (!rvdev) {
+		dev_err(dev, "vring requested without a virtio dev entry\n");
+		return -EINVAL;
+	}
+
+	/* the firmware must provide the expected queue size */
+	if (!rsc->len) {
+		dev_err(dev, "missing expected queue size\n");
+		return -EINVAL;
+	}
+
+	/* we currently support two vrings per rproc (for rx and tx) */
+	if (id >= ARRAY_SIZE(rvdev->vring)) {
+		dev_err(dev, "%s: invalid vring id %d\n", rsc->name, id);
+		return -EINVAL;
+	}
+
+	/* have we already allocated this vring id ? */
+	if (rvdev->vring[id].len) {
+		dev_err(dev, "%s: duplicated id %d\n", rsc->name, id);
+		return -EINVAL;
+	}
+
+	/* actual size of vring (in bytes) */
+	size = PAGE_ALIGN(vring_size(rsc->len, AMP_VRING_ALIGN));
+
+	/*
+	 * Allocate non-cacheable memory for the vring. In the future
+	 * this call will also configure the IOMMU for us
+	 */
+	va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL);
+	if (!va) {
+		dev_err(dev, "dma_alloc_coherent failed\n");
+		return -ENOMEM;
+	}
+
+	dev_dbg(dev, "vring%d: va %p dma %x qsz %d ring size %x\n", id, va,
+					dma, rsc->len, size);
+
+	rvdev->vring[id].len = rsc->len;
+	rvdev->vring[id].va = va;
+	rvdev->vring[id].dma = dma;
+
+	return 0;
+}
+
+/**
+ * rproc_handle_trace() - handle a shared trace buffer resource
+ * @rproc: the remote processor
+ * @rsc: the trace resource descriptor
+ *
+ * In case the remote processor dumps trace logs into memory,
+ * export it via debugfs.
+ *
+ * Currently, the 'da' member of @rsc should contain the device address
+ * where the remote processor is dumping the traces. Later we could also
+ * support dynamically allocating this address using the generic
+ * DMA API (but currently there isn't a use case for that).
+ *
+ * Returns 0 on success, or an appropriate error code otherwise
+ */
+static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
+{
+	struct rproc_mem_entry *trace;
+	struct device *dev = rproc->dev;
+	void *ptr;
+	char name[15];
+
+	/* what's the kernel address of this resource ? */
+	ptr = rproc_da_to_va(rproc, rsc->da, rsc->len);
+	if (!ptr) {
+		dev_err(dev, "erroneous trace resource entry\n");
+		return -EINVAL;
+	}
+
+	trace = kzalloc(sizeof(*trace), GFP_KERNEL);
+	if (!trace) {
+		dev_err(dev, "kzalloc trace failed\n");
+		return -ENOMEM;
+	}
+
+	/* set the trace buffer dma properties */
+	trace->len = rsc->len;
+	trace->va = ptr;
+
+	/* make sure snprintf always null terminates, even if truncating */
+	snprintf(name, sizeof(name), "trace%d", rproc->num_traces);
+
+	/* create the debugfs entry */
+	trace->priv = rproc_create_trace_file(name, rproc, trace);
+	if (!trace->priv) {
+		trace->va = NULL;
+		kfree(trace);
+		return -EINVAL;
+	}
+
+	list_add_tail(&trace->node, &rproc->traces);
+
+	rproc->num_traces++;
+
+	dev_dbg(dev, "%s added: va %p, da 0x%llx, len 0x%x\n", name, ptr,
+						rsc->da, rsc->len);
+
+	return 0;
+}
+
+/**
+ * rproc_handle_devmem() - handle devmem resource entry
+ * @rproc: remote processor handle
+ * @rsc: the devmem resource entry
+ *
+ * Remote processors commonly need to access certain on-chip peripherals.
+ *
+ * Some of these remote processors access memory via an iommu device,
+ * and might require us to configure their iommu before they can access
+ * the on-chip peripherals they need.
+ *
+ * This resource entry is a request to map such a peripheral device.
+ *
+ * These devmem entries will contain the physical address of the device in
+ * the 'pa' member. If a specific device address is expected, then 'da' will
+ * contain it (currently this is the only use case supported). 'len' will
+ * contain the size of the physical region we need to map.
+ *
+ * Currently we just "trust" those devmem entries to contain valid physical
+ * addresses, but this is going to change: we want the implementations to
+ * tell us ranges of physical addresses the firmware is allowed to request,
+ * and not allow firmwares to request access to physical addresses that
+ * are outside those ranges.
+ */
+static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc)
+{
+	struct rproc_mem_entry *mapping;
+	int ret;
+
+	/* no point in handling this resource without a valid iommu domain */
+	if (!rproc->domain)
+		return -EINVAL;
+
+	mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+	if (!mapping) {
+		dev_err(rproc->dev, "kzalloc mapping failed\n");
+		return -ENOMEM;
+	}
+
+	ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len, rsc->flags);
+	if (ret) {
+		dev_err(rproc->dev, "failed to map devmem: %d\n", ret);
+		goto out;
+	}
+
+	/*
+	 * We'll need this info later when we'll want to unmap everything
+	 * (e.g. on shutdown).
+	 *
+	 * We can't trust the remote processor not to change the resource
+	 * table, so we must maintain this info independently.
+	 */
+	mapping->da = rsc->da;
+	mapping->len = rsc->len;
+	list_add_tail(&mapping->node, &rproc->mappings);
+
+	dev_dbg(rproc->dev, "mapped devmem pa 0x%llx, da 0x%llx, len 0x%x\n",
+					rsc->pa, rsc->da, rsc->len);
+
+	return 0;
+
+out:
+	kfree(mapping);
+	return ret;
+}
+
+/**
+ * rproc_handle_carveout() - handle phys contig memory allocation requests
+ * @rproc: rproc handle
+ * @rsc: the resource entry
+ *
+ * This function will handle firmware requests for allocation of physically
+ * contiguous memory regions.
+ *
+ * These request entries should come first in the firmware's resource table,
+ * as other firmware entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ */
+static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc)
+{
+	struct rproc_mem_entry *carveout, *mapping;
+	struct device *dev = rproc->dev;
+	dma_addr_t dma;
+	void *va;
+	int ret;
+
+	mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+	if (!mapping) {
+		dev_err(dev, "kzalloc mapping failed\n");
+		return -ENOMEM;
+	}
+
+	carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
+	if (!carveout) {
+		dev_err(dev, "kzalloc carveout failed\n");
+		ret = -ENOMEM;
+		goto free_mapping;
+	}
+
+	va = dma_alloc_coherent(dev, rsc->len, &dma, GFP_KERNEL);
+	if (!va) {
+		dev_err(dev, "failed to dma alloc carveout: %d\n", rsc->len);
+		ret = -ENOMEM;
+		goto free_carv;
+	}
+
+	dev_dbg(dev, "carveout va %p, dma %x, len 0x%x\n", va, dma, rsc->len);
+
+	/*
+	 * Ok, this is non-standard.
+	 *
+	 * Sometimes we can't rely on the generic iommu-based DMA API
+	 * to dynamically allocate the device address and then set the IOMMU
+	 * tables accordingly, because some remote processors might
+	 * _require_ us to use hard coded device addresses that their
+	 * firmware was compiled with.
+	 *
+	 * In this case, we must use the IOMMU API directly and map
+	 * the memory to the device address as expected by the remote
+	 * processor.
+	 *
+	 * Obviously such remote processor devices should not be configured
+	 * to use the iommu-based DMA API: we expect 'dma' to contain the
+	 * physical address in this case.
+	 */
+	if (rproc->domain) {
+		ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
+								rsc->flags);
+		if (ret) {
+			dev_err(dev, "iommu_map failed: %d\n", ret);
+			goto dma_free;
+		}
+
+		/*
+		 * We'll need this info later when we'll want to unmap
+		 * everything (e.g. on shutdown).
+		 *
+		 * We can't trust the remote processor not to change the
+		 * resource table, so we must maintain this info independently.
+		 */
+		mapping->da = rsc->da;
+		mapping->len = rsc->len;
+		list_add_tail(&mapping->node, &rproc->mappings);
+
+		dev_dbg(dev, "carveout mapped 0x%llx to 0x%x\n", rsc->da, dma);
+
+		/*
+		 * Some remote processors might need to know the pa
+		 * even though they are behind an IOMMU. E.g., OMAP4's
+		 * remote M3 processor needs this so it can control
+		 * on-chip hardware accelerators that are not behind
+		 * the IOMMU, and therefor must know the pa.
+		 *
+		 * Generally we don't want to expose physical addresses
+		 * if we don't have to (remote processors are generally
+		 * _not_ trusted), so we might want to do this only for
+		 * remote processor that _must_ have this (e.g. OMAP4's
+		 * dual M3 subsystem).
+		 */
+		rsc->pa = dma;
+	}
+
+	carveout->va = va;
+	carveout->len = rsc->len;
+	carveout->dma = dma;
+	carveout->da = rsc->da;
+
+	list_add_tail(&carveout->node, &rproc->carveouts);
+
+	return 0;
+
+dma_free:
+	dma_free_coherent(dev, rsc->len, va, dma);
+free_carv:
+	kfree(carveout);
+free_mapping:
+	kfree(mapping);
+	return ret;
+}
+
+/*
+ * A lookup table for resource handlers. The indices are defined in
+ * enum fw_resource_type.
+ */
+static rproc_handle_resource_t rproc_handle_rsc[] = {
+	[RSC_CARVEOUT] = rproc_handle_carveout,
+	[RSC_DEVMEM] = rproc_handle_devmem,
+	[RSC_TRACE] = rproc_handle_trace,
+	[RSC_VRING] = rproc_handle_vring,
+	[RSC_VIRTIO_DEV] = NULL, /* handled early upon registration */
+};
+
+/* handle firmware resource entries before booting the remote processor */
+static int
+rproc_handle_boot_rsc(struct rproc *rproc, struct fw_resource *rsc, int len)
+{
+	struct device *dev = rproc->dev;
+	rproc_handle_resource_t handler;
+	int ret = 0;
+
+	for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) {
+		dev_dbg(dev, "rsc: type %d, da 0x%llx, pa 0x%llx, len 0x%x, "
+			"id %d, name %s, flags %x\n", rsc->type, rsc->da,
+			rsc->pa, rsc->len, rsc->id, rsc->name, rsc->flags);
+
+		if (rsc->type >= RSC_LAST) {
+			dev_warn(dev, "unsupported resource %d\n", rsc->type);
+			continue;
+		}
+
+		handler = rproc_handle_rsc[rsc->type];
+		if (!handler)
+			continue;
+
+		ret = handler(rproc, rsc);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/* handle firmware resource entries while registering the remote processor */
+static int
+rproc_handle_virtio_rsc(struct rproc *rproc, struct fw_resource *rsc, int len)
+{
+	struct device *dev = rproc->dev;
+	int ret = -ENODEV;
+
+	for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc))
+		if (rsc->type == RSC_VIRTIO_DEV) {
+			dev_dbg(dev, "found vdev %d/%s features %llx\n",
+					rsc->flags, rsc->name, rsc->da);
+			ret = rproc_handle_virtio_hdr(rproc, rsc);
+			break;
+		}
+
+	return ret;
+}
+
+/**
+ * rproc_handle_resources() - find and handle the resource table
+ * @rproc: the rproc handle
+ * @elf_data: the content of the ELF firmware image
+ * @len: firmware size (in bytes)
+ * @handler: function that should be used to handle the resource table
+ *
+ * This function finds the resource table inside the remote processor's
+ * firmware, and invoke a user-supplied handler with it (we have two
+ * possible handlers: one is invoked upon registration of @rproc,
+ * in order to register the supported virito devices, and the other is
+ * invoked when @rproc is actually booted).
+ *
+ * Currently this function fails if a resource table doesn't exist.
+ * This restriction will be removed when we'll start supporting remote
+ * processors that don't need a resource table.
+ */
+static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
+				size_t len, rproc_handle_resources_t handler)
+
+{
+	struct elf32_hdr *ehdr;
+	struct elf32_shdr *shdr;
+	const char *name_table;
+	int i, ret = -EINVAL;
+
+	ehdr = (struct elf32_hdr *)elf_data;
+	shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
+	name_table = elf_data + shdr[ehdr->e_shstrndx].sh_offset;
+
+	/* look for the resource table and handle it */
+	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
+		if (!strcmp(name_table + shdr->sh_name, ".resource_table")) {
+			struct fw_resource *table = (struct fw_resource *)
+						(elf_data + shdr->sh_offset);
+
+			if (shdr->sh_offset + shdr->sh_size > len) {
+				dev_err(rproc->dev,
+					"truncated fw: need 0x%x avail 0x%x\n",
+					shdr->sh_offset + shdr->sh_size, len);
+				ret = -EINVAL;
+			}
+
+			ret = handler(rproc, table, shdr->sh_size);
+
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * rproc_resource_cleanup() - clean up and free all acquired resources
+ * @rproc: rproc handle
+ *
+ * This function will free all resources acquired for @rproc, and it
+ * is called when @rproc shuts down, or just failed booting.
+ */
+static void rproc_resource_cleanup(struct rproc *rproc)
+{
+	struct rproc_mem_entry *entry, *tmp;
+	struct device *dev = rproc->dev;
+	struct rproc_vdev *rvdev = rproc->rvdev;
+	int i;
+
+	/* clean up debugfs trace entries */
+	list_for_each_entry_safe(entry, tmp, &rproc->traces, node) {
+		rproc_remove_trace_file(entry->priv);
+		rproc->num_traces--;
+		list_del(&entry->node);
+		kfree(entry);
+	}
+
+	/* free the coherent memory allocated for the vrings */
+	for (i = 0; rvdev && i < ARRAY_SIZE(rvdev->vring); i++) {
+		int qsz = rvdev->vring[i].len;
+		void *va = rvdev->vring[i].va;
+		int dma = rvdev->vring[i].dma;
+
+		/* virtqueue size is expressed in number of buffers supported */
+		if (qsz) {
+			/* how many bytes does this vring really occupy ? */
+			int size = PAGE_ALIGN(vring_size(qsz, AMP_VRING_ALIGN));
+
+			dma_free_coherent(rproc->dev, size, va, dma);
+
+			rvdev->vring[i].len = 0;
+		}
+	}
+
+	/* clean up carveout allocations */
+	list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) {
+		dma_free_coherent(dev, entry->len, entry->va, entry->dma);
+		list_del(&entry->node);
+		kfree(entry);
+	}
+
+	/* clean up iommu mapping entries */
+	list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) {
+		size_t unmapped;
+
+		unmapped = iommu_unmap(rproc->domain, entry->da, entry->len);
+		if (unmapped != entry->len) {
+			/* nothing much to do besides complaining */
+			dev_err(dev, "failed to unmap %u/%u\n", entry->len,
+								unmapped);
+		}
+
+		list_del(&entry->node);
+		kfree(entry);
+	}
+}
+
+/* make sure this fw image is sane */
+static int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
+{
+	const char *name = rproc->firmware;
+	struct device *dev = rproc->dev;
+	struct elf32_hdr *ehdr;
+
+	if (!fw) {
+		dev_err(dev, "failed to load %s\n", name);
+		return -EINVAL;
+	}
+
+	if (fw->size < sizeof(struct elf32_hdr)) {
+		dev_err(dev, "Image is too small\n");
+		return -EINVAL;
+	}
+
+	ehdr = (struct elf32_hdr *)fw->data;
+
+	/* We assume the firmware has the same endianess as the host */
+# ifdef __LITTLE_ENDIAN
+	if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
+# else /* BIG ENDIAN */
+	if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
+# endif
+		dev_err(dev, "Unsupported firmware endianess\n");
+		return -EINVAL;
+	}
+
+	if (fw->size < ehdr->e_shoff + sizeof(struct elf32_shdr)) {
+		dev_err(dev, "Image is too small\n");
+		return -EINVAL;
+	}
+
+	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
+		dev_err(dev, "Image is corrupted (bad magic)\n");
+		return -EINVAL;
+	}
+
+	if (ehdr->e_phnum == 0) {
+		dev_err(dev, "No loadable segments\n");
+		return -EINVAL;
+	}
+
+	if (ehdr->e_phoff > fw->size) {
+		dev_err(dev, "Firmware size is too small\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+ * take a firmware and boot a remote processor with it.
+ */
+static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
+{
+	struct device *dev = rproc->dev;
+	const char *name = rproc->firmware;
+	struct elf32_hdr *ehdr;
+	int ret;
+
+	ret = rproc_fw_sanity_check(rproc, fw);
+	if (ret)
+		return ret;
+
+	ehdr = (struct elf32_hdr *)fw->data;
+
+	dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size);
+
+	/*
+	 * if enabling an IOMMU isn't relevant for this rproc, this is
+	 * just a nop
+	 */
+	ret = rproc_enable_iommu(rproc);
+	if (ret) {
+		dev_err(dev, "can't enable iommu: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * The ELF entry point is the rproc's boot addr (though this is not
+	 * a configurable property of all remote processors: some will always
+	 * boot at a specific hardcoded address).
+	 */
+	rproc->bootaddr = ehdr->e_entry;
+
+	/* handle fw resources which are required to boot rproc */
+	ret = rproc_handle_resources(rproc, fw->data, fw->size,
+						rproc_handle_boot_rsc);
+	if (ret) {
+		dev_err(dev, "Failed to process resources: %d\n", ret);
+		goto clean_up;
+	}
+
+	/* load the ELF segments to memory */
+	ret = rproc_load_segments(rproc, fw->data, fw->size);
+	if (ret) {
+		dev_err(dev, "Failed to load program segments: %d\n", ret);
+		goto clean_up;
+	}
+
+	/* power up the remote processor */
+	ret = rproc->ops->start(rproc);
+	if (ret) {
+		dev_err(dev, "can't start rproc %s: %d\n", rproc->name, ret);
+		goto clean_up;
+	}
+
+	rproc->state = RPROC_RUNNING;
+
+	dev_info(dev, "remote processor %s is now up\n", rproc->name);
+
+	return 0;
+
+clean_up:
+	rproc_resource_cleanup(rproc);
+	rproc_disable_iommu(rproc);
+	return ret;
+}
+
+/*
+ * take a firmware and look for virtio devices to register.
+ *
+ * Note: this function is called asynchronously upon registration of the
+ * remote processor (so we must wait until it completes before we try
+ * to unregister the device. one other option is just to use kref here,
+ * that might be cleaner).
+ */
+static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
+{
+	struct rproc *rproc = context;
+	struct device *dev = rproc->dev;
+	int ret;
+
+	if (rproc_fw_sanity_check(rproc, fw) < 0)
+		goto out;
+
+	/* does the fw supports any virtio devices ? */
+	ret = rproc_handle_resources(rproc, fw->data, fw->size,
+						rproc_handle_virtio_rsc);
+	if (ret) {
+		dev_info(dev, "No fw virtio device was found\n");
+		goto out;
+	}
+
+	/* add the virtio device (currently only rpmsg vdevs are supported) */
+	ret = rproc_add_rpmsg_vdev(rproc);
+	if (ret)
+		goto out;
+
+out:
+	if (fw)
+		release_firmware(fw);
+	/* allow rproc_unregister() contexts, if any, to proceed */
+	complete_all(&rproc->firmware_loading_complete);
+}
+
+/**
+ * rproc_boot() - boot a remote processor
+ * @rproc: handle of a remote processor
+ *
+ * Boot a remote processor (i.e. load its firmware, power it on, ...).
+ *
+ * If the remote processor is already powered on, this function immediately
+ * returns (successfully).
+ *
+ * Returns 0 on success, and an appropriate error value otherwise.
+ */
+int rproc_boot(struct rproc *rproc)
+{
+	const struct firmware *firmware_p;
+	struct device *dev;
+	int ret;
+
+	if (!rproc) {
+		pr_err("invalid rproc handle\n");
+		return -EINVAL;
+	}
+
+	dev = rproc->dev;
+
+	ret = mutex_lock_interruptible(&rproc->lock);
+	if (ret) {
+		dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
+		return ret;
+	}
+
+	/* loading a firmware is required */
+	if (!rproc->firmware) {
+		dev_err(dev, "%s: no firmware to load\n", __func__);
+		ret = -EINVAL;
+		goto unlock_mutex;
+	}
+
+	/* prevent underlying implementation from being removed */
+	if (!try_module_get(dev->driver->owner)) {
+		dev_err(dev, "%s: can't get owner\n", __func__);
+		ret = -EINVAL;
+		goto unlock_mutex;
+	}
+
+	/* skip the boot process if rproc is already powered up */
+	if (atomic_inc_return(&rproc->power) > 1) {
+		ret = 0;
+		goto unlock_mutex;
+	}
+
+	dev_info(dev, "powering up %s\n", rproc->name);
+
+	/* load firmware */
+	ret = request_firmware(&firmware_p, rproc->firmware, dev);
+	if (ret < 0) {
+		dev_err(dev, "request_firmware failed: %d\n", ret);
+		goto downref_rproc;
+	}
+
+	ret = rproc_fw_boot(rproc, firmware_p);
+
+	release_firmware(firmware_p);
+
+downref_rproc:
+	if (ret) {
+		module_put(dev->driver->owner);
+		atomic_dec(&rproc->power);
+	}
+unlock_mutex:
+	mutex_unlock(&rproc->lock);
+	return ret;
+}
+EXPORT_SYMBOL(rproc_boot);
+
+/**
+ * rproc_shutdown() - power off the remote processor
+ * @rproc: the remote processor
+ *
+ * Power off a remote processor (previously booted with rproc_boot()).
+ *
+ * In case @rproc is still being used by an additional user(s), then
+ * this function will just decrement the power refcount and exit,
+ * without really powering off the device.
+ *
+ * Every call to rproc_boot() must (eventually) be accompanied by a call
+ * to rproc_shutdown(). Calling rproc_shutdown() redundantly is a bug.
+ *
+ * Notes:
+ * - we're not decrementing the rproc's refcount, only the power refcount.
+ *   which means that the @rproc handle stays valid even after rproc_shutdown()
+ *   returns, and users can still use it with a subsequent rproc_boot(), if
+ *   needed.
+ * - don't call rproc_shutdown() to unroll rproc_get_by_name(), exactly
+ *   because rproc_shutdown() _does not_ decrement the refcount of @rproc.
+ *   To decrement the refcount of @rproc, use rproc_put() (but _only_ if
+ *   you acquired @rproc using rproc_get_by_name()).
+ */
+void rproc_shutdown(struct rproc *rproc)
+{
+	struct device *dev = rproc->dev;
+	int ret;
+
+	ret = mutex_lock_interruptible(&rproc->lock);
+	if (ret) {
+		dev_err(dev, "can't lock rproc %s: %d\n", rproc->name, ret);
+		return;
+	}
+
+	/* if the remote proc is still needed, bail out */
+	if (!atomic_dec_and_test(&rproc->power))
+		goto out;
+
+	/* power off the remote processor */
+	ret = rproc->ops->stop(rproc);
+	if (ret) {
+		atomic_inc(&rproc->power);
+		dev_err(dev, "can't stop rproc: %d\n", ret);
+		goto out;
+	}
+
+	/* clean up all acquired resources */
+	rproc_resource_cleanup(rproc);
+
+	rproc_disable_iommu(rproc);
+
+	rproc->state = RPROC_OFFLINE;
+
+	dev_info(dev, "stopped remote processor %s\n", rproc->name);
+
+out:
+	mutex_unlock(&rproc->lock);
+	if (!ret)
+		module_put(dev->driver->owner);
+}
+EXPORT_SYMBOL(rproc_shutdown);
+
+/**
+ * rproc_release() - completely deletes the existence of a remote processor
+ * @kref: the rproc's kref
+ *
+ * This function should _never_ be called directly.
+ *
+ * The only reasonable location to use it is as an argument when kref_put'ing
+ * @rproc's refcount.
+ *
+ * This way it will be called when no one holds a valid pointer to this @rproc
+ * anymore (and obviously after it is removed from the rprocs klist).
+ *
+ * Note: this function is not static because rproc_vdev_release() needs it when
+ * it decrements @rproc's refcount.
+ */
+void rproc_release(struct kref *kref)
+{
+	struct rproc *rproc = container_of(kref, struct rproc, refcount);
+
+	dev_info(rproc->dev, "removing %s\n", rproc->name);
+
+	rproc_delete_debug_dir(rproc);
+
+	/* at this point no one holds a reference to rproc anymore */
+	kfree(rproc);
+}
+
+/* will be called when an rproc is added to the rprocs klist */
+static void klist_rproc_get(struct klist_node *n)
+{
+	struct rproc *rproc = container_of(n, struct rproc, node);
+
+	kref_get(&rproc->refcount);
+}
+
+/* will be called when an rproc is removed from the rprocs klist */
+static void klist_rproc_put(struct klist_node *n)
+{
+	struct rproc *rproc = container_of(n, struct rproc, node);
+
+	kref_put(&rproc->refcount, rproc_release);
+}
+
+static struct rproc *next_rproc(struct klist_iter *i)
+{
+	struct klist_node *n;
+
+	n = klist_next(i);
+	if (!n)
+		return NULL;
+
+	return container_of(n, struct rproc, node);
+}
+
+/**
+ * rproc_get_by_name() - find a remote processor by name and boot it
+ * @name: name of the remote processor
+ *
+ * Finds an rproc handle using the remote processor's name, and then
+ * boot it. If it's already powered on, then just immediately return
+ * (successfully).
+ *
+ * Returns the rproc handle on success, and NULL on failure.
+ *
+ * This function increments the remote processor's refcount, so always
+ * use rproc_put() to decrement it back once rproc isn't needed anymore.
+ *
+ * Note: currently this function (and its counterpart rproc_put()) are not
+ * used anymore by the rpmsg subsystem. We need to scrutinize the use cases
+ * that still need them, and see if we can migrate them to use the non
+ * name-based boot/shutdown interface.
+ */
+struct rproc *rproc_get_by_name(const char *name)
+{
+	struct rproc *rproc;
+	struct klist_iter i;
+	int ret;
+
+	/* find the remote processor, and upref its refcount */
+	klist_iter_init(&rprocs, &i);
+	while ((rproc = next_rproc(&i)) != NULL)
+		if (!strcmp(rproc->name, name)) {
+			kref_get(&rproc->refcount);
+			break;
+		}
+	klist_iter_exit(&i);
+
+	/* can't find this rproc ? */
+	if (!rproc) {
+		pr_err("can't find remote processor %s\n", name);
+		return NULL;
+	}
+
+	ret = rproc_boot(rproc);
+	if (ret < 0) {
+		kref_put(&rproc->refcount, rproc_release);
+		return NULL;
+	}
+
+	return rproc;
+}
+EXPORT_SYMBOL(rproc_get_by_name);
+
+/**
+ * rproc_put() - decrement the refcount of a remote processor, and shut it down
+ * @rproc: the remote processor
+ *
+ * This function tries to shutdown @rproc, and it then decrements its
+ * refcount.
+ *
+ * After this function returns, @rproc may _not_ be used anymore, and its
+ * handle should be considered invalid.
+ *
+ * This function should be called _iff_ the @rproc handle was grabbed by
+ * calling rproc_get_by_name().
+ */
+void rproc_put(struct rproc *rproc)
+{
+	/* try to power off the remote processor */
+	rproc_shutdown(rproc);
+
+	/* downref rproc's refcount */
+	kref_put(&rproc->refcount, rproc_release);
+}
+EXPORT_SYMBOL(rproc_put);
+
+/**
+ * rproc_register() - register a remote processor
+ * @rproc: the remote processor handle to register
+ *
+ * Registers @rproc with the remoteproc framework, after it has been
+ * allocated with rproc_alloc().
+ *
+ * This is called by the platform-specific rproc implementation, whenever
+ * a new remote processor device is probed.
+ *
+ * Returns 0 on success and an appropriate error code otherwise.
+ *
+ * Note: this function initiates an asynchronous firmware loading
+ * context, which will look for virtio devices supported by the rproc's
+ * firmware.
+ *
+ * If found, those virtio devices will be created and added, so as a result
+ * of registering this remote processor, additional virtio drivers will be
+ * probed.
+ *
+ * Currently, though, we only support a single RPMSG virtio vdev per remote
+ * processor.
+ */
+int rproc_register(struct rproc *rproc)
+{
+	struct device *dev = rproc->dev;
+	int ret = 0;
+
+	/* expose to rproc_get_by_name users */
+	klist_add_tail(&rproc->node, &rprocs);
+
+	dev_info(rproc->dev, "%s is available\n", rproc->name);
+
+	dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n");
+	dev_info(dev, "THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed.\n");
+
+	/* create debugfs entries */
+	rproc_create_debug_dir(rproc);
+
+	/* rproc_unregister() calls must wait until async loader completes */
+	init_completion(&rproc->firmware_loading_complete);
+
+	/*
+	 * We must retrieve early virtio configuration info from
+	 * the firmware (e.g. whether to register a virtio rpmsg device,
+	 * what virtio features does it support, ...).
+	 *
+	 * We're initiating an asynchronous firmware loading, so we can
+	 * be built-in kernel code, without hanging the boot process.
+	 */
+	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+					rproc->firmware, dev, GFP_KERNEL,
+					rproc, rproc_fw_config_virtio);
+	if (ret < 0) {
+		dev_err(dev, "request_firmware_nowait failed: %d\n", ret);
+		complete_all(&rproc->firmware_loading_complete);
+		klist_remove(&rproc->node);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(rproc_register);
+
+/**
+ * rproc_alloc() - allocate a remote processor handle
+ * @dev: the underlying device
+ * @name: name of this remote processor
+ * @ops: platform-specific handlers (mainly start/stop)
+ * @firmware: name of firmware file to load
+ * @len: length of private data needed by the rproc driver (in bytes)
+ *
+ * Allocates a new remote processor handle, but does not register
+ * it yet.
+ *
+ * This function should be used by rproc implementations during initialization
+ * of the remote processor.
+ *
+ * After creating an rproc handle using this function, and when ready,
+ * implementations should then call rproc_register() to complete
+ * the registration of the remote processor.
+ *
+ * On success the new rproc is returned, and on failure, NULL.
+ *
+ * Note: _never_ directly deallocate @rproc, even if it was not registered
+ * yet. Instead, if you just need to unroll rproc_alloc(), use rproc_free().
+ */
+struct rproc *rproc_alloc(struct device *dev, const char *name,
+				const struct rproc_ops *ops,
+				const char *firmware, int len)
+{
+	struct rproc *rproc;
+
+	if (!dev || !name || !ops)
+		return NULL;
+
+	rproc = kzalloc(sizeof(struct rproc) + len, GFP_KERNEL);
+	if (!rproc) {
+		dev_err(dev, "%s: kzalloc failed\n", __func__);
+		return NULL;
+	}
+
+	rproc->dev = dev;
+	rproc->name = name;
+	rproc->ops = ops;
+	rproc->firmware = firmware;
+	rproc->priv = &rproc[1];
+
+	atomic_set(&rproc->power, 0);
+
+	kref_init(&rproc->refcount);
+
+	mutex_init(&rproc->lock);
+
+	INIT_LIST_HEAD(&rproc->carveouts);
+	INIT_LIST_HEAD(&rproc->mappings);
+	INIT_LIST_HEAD(&rproc->traces);
+
+	rproc->state = RPROC_OFFLINE;
+
+	return rproc;
+}
+EXPORT_SYMBOL(rproc_alloc);
+
+/**
+ * rproc_free() - free an rproc handle that was allocated by rproc_alloc
+ * @rproc: the remote processor handle
+ *
+ * This function should _only_ be used if @rproc was only allocated,
+ * but not registered yet.
+ *
+ * If @rproc was already successfully registered (by calling rproc_register()),
+ * then use rproc_unregister() instead.
+ */
+void rproc_free(struct rproc *rproc)
+{
+	kfree(rproc);
+}
+EXPORT_SYMBOL(rproc_free);
+
+/**
+ * rproc_unregister() - unregister a remote processor
+ * @rproc: rproc handle to unregister
+ *
+ * Unregisters a remote processor, and decrements its refcount.
+ * If its refcount drops to zero, then @rproc will be freed. If not,
+ * it will be freed later once the last reference is dropped.
+ *
+ * This function should be called when the platform specific rproc
+ * implementation decides to remove the rproc device. it should
+ * _only_ be called if a previous invocation of rproc_register()
+ * has completed successfully.
+ *
+ * After rproc_unregister() returns, @rproc is _not_ valid anymore and
+ * it shouldn't be used. More specifically, don't call rproc_free()
+ * or try to directly free @rproc after rproc_unregister() returns;
+ * none of these are needed, and calling them is a bug.
+ *
+ * Returns 0 on success and -EINVAL if @rproc isn't valid.
+ */
+int rproc_unregister(struct rproc *rproc)
+{
+	if (!rproc)
+		return -EINVAL;
+
+	/* if rproc is just being registered, wait */
+	wait_for_completion(&rproc->firmware_loading_complete);
+
+	/* was an rpmsg vdev created ? */
+	if (rproc->rvdev)
+		rproc_remove_rpmsg_vdev(rproc);
+
+	klist_remove(&rproc->node);
+
+	kref_put(&rproc->refcount, rproc_release);
+
+	return 0;
+}
+EXPORT_SYMBOL(rproc_unregister);
+
+static int __init remoteproc_init(void)
+{
+	rproc_init_debugfs();
+	return 0;
+}
+module_init(remoteproc_init);
+
+static void __exit remoteproc_exit(void)
+{
+	rproc_exit_debugfs();
+}
+module_exit(remoteproc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Generic Remote Processor Framework");
diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
new file mode 100644
index 0000000..70277a5
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -0,0 +1,179 @@
+/*
+ * Remote Processor Framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Mark Grosen <mgrosen@ti.com>
+ * Brian Swetland <swetland@google.com>
+ * Fernando Guzman Lugo <fernando.lugo@ti.com>
+ * Suman Anna <s-anna@ti.com>
+ * Robert Tivy <rtivy@ti.com>
+ * Armando Uribe De Leon <x0095078@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt)    "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/remoteproc.h>
+#include <linux/device.h>
+
+/* remoteproc debugfs parent dir */
+static struct dentry *rproc_dbg;
+
+/*
+ * Some remote processors may support dumping trace logs into a shared
+ * memory buffer. We expose this trace buffer using debugfs, so users
+ * can easily tell what's going on remotely.
+ *
+ * We will most probably improve the rproc tracing facilities later on,
+ * but this kind of lightweight and simple mechanism is always good to have,
+ * as it provides very early tracing with little to no dependencies at all.
+ */
+static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct rproc_mem_entry *trace = filp->private_data;
+	int len = strnlen(trace->va, trace->len);
+
+	return simple_read_from_buffer(userbuf, count, ppos, trace->va, len);
+}
+
+static int rproc_open_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+
+	return 0;
+}
+
+static const struct file_operations trace_rproc_ops = {
+	.read = rproc_trace_read,
+	.open = rproc_open_generic,
+	.llseek	= generic_file_llseek,
+};
+
+/*
+ * A state-to-string lookup table, for exposing a human readable state
+ * via debugfs. Always keep in sync with enum rproc_state
+ */
+static const char * const rproc_state_string[] = {
+	"offline",
+	"suspended",
+	"running",
+	"crashed",
+	"invalid",
+};
+
+/* expose the state of the remote processor via debugfs */
+static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	unsigned int state;
+	char buf[30];
+	int i;
+
+	state = rproc->state > RPROC_LAST ? RPROC_LAST : rproc->state;
+
+	i = snprintf(buf, 30, "%.28s (%d)\n", rproc_state_string[state],
+							rproc->state);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
+}
+
+static const struct file_operations rproc_state_ops = {
+	.read = rproc_state_read,
+	.open = rproc_open_generic,
+	.llseek	= generic_file_llseek,
+};
+
+/* expose the name of the remote processor via debugfs */
+static ssize_t rproc_name_read(struct file *filp, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	/* need room for the name, a newline and a terminating null */
+	char buf[100];
+	int i;
+
+	i = snprintf(buf, sizeof(buf), "%.98s\n", rproc->name);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
+}
+
+static const struct file_operations rproc_name_ops = {
+	.read = rproc_name_read,
+	.open = rproc_open_generic,
+	.llseek	= generic_file_llseek,
+};
+
+void rproc_remove_trace_file(struct dentry *tfile)
+{
+	debugfs_remove(tfile);
+}
+
+struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
+					struct rproc_mem_entry *trace)
+{
+	struct dentry *tfile;
+
+	tfile = debugfs_create_file(name, 0400, rproc->dbg_dir,
+						trace, &trace_rproc_ops);
+	if (!tfile) {
+		dev_err(rproc->dev, "failed to create debugfs trace entry\n");
+		return NULL;
+	}
+
+	return tfile;
+}
+
+void rproc_delete_debug_dir(struct rproc *rproc)
+{
+	if (!rproc->dbg_dir)
+		return;
+
+	debugfs_remove_recursive(rproc->dbg_dir);
+}
+
+void rproc_create_debug_dir(struct rproc *rproc)
+{
+	struct device *dev = rproc->dev;
+
+	if (!rproc_dbg)
+		return;
+
+	rproc->dbg_dir = debugfs_create_dir(dev_name(dev), rproc_dbg);
+	if (!rproc->dbg_dir)
+		return;
+
+	debugfs_create_file("name", 0400, rproc->dbg_dir,
+					rproc, &rproc_name_ops);
+	debugfs_create_file("state", 0400, rproc->dbg_dir,
+					rproc, &rproc_state_ops);
+}
+
+void __init rproc_init_debugfs(void)
+{
+	if (debugfs_initialized()) {
+		rproc_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
+		if (!rproc_dbg)
+			pr_err("can't create debugfs dir\n");
+	}
+}
+
+void __exit rproc_exit_debugfs(void)
+{
+	if (rproc_dbg)
+		debugfs_remove(rproc_dbg);
+}
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
new file mode 100644
index 0000000..8b2fc40
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -0,0 +1,44 @@
+/*
+ * Remote processor framework
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#ifndef REMOTEPROC_INTERNAL_H
+#define REMOTEPROC_INTERNAL_H
+
+#include <linux/irqreturn.h>
+
+struct rproc;
+
+/* from remoteproc_core.c */
+void rproc_release(struct kref *kref);
+irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id);
+
+/* from remoteproc_rpmsg.c */
+int rproc_add_rpmsg_vdev(struct rproc *);
+void rproc_remove_rpmsg_vdev(struct rproc *rproc);
+
+/* from remoteproc_debugfs.c */
+void rproc_remove_trace_file(struct dentry *tfile);
+struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
+					struct rproc_mem_entry *trace);
+void rproc_delete_debug_dir(struct rproc *rproc);
+void rproc_create_debug_dir(struct rproc *rproc);
+void rproc_init_debugfs(void);
+void rproc_exit_debugfs(void);
+
+#endif /* REMOTEPROC_INTERNAL_H */
diff --git a/drivers/remoteproc/remoteproc_rpmsg.c b/drivers/remoteproc/remoteproc_rpmsg.c
new file mode 100644
index 0000000..4f73e81
--- /dev/null
+++ b/drivers/remoteproc/remoteproc_rpmsg.c
@@ -0,0 +1,299 @@
+/*
+ * Remote processor messaging transport (OMAP platform-specific bits)
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/export.h>
+#include <linux/remoteproc.h>
+#include <linux/rpmsg.h>
+#include <linux/virtio.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_ring.h>
+#include <linux/err.h>
+#include <linux/kref.h>
+#include <linux/slab.h>
+
+#include "remoteproc_internal.h"
+
+/**
+ * struct rproc_virtio_vq_info - virtqueue state
+ * @vq_id: a unique index of this virtqueue (unique for this @rproc)
+ * @rproc: handle to the remote processor
+ *
+ * Such a struct will be maintained for every virtqueue we're
+ * using to communicate with the remote processor
+ */
+struct rproc_virtio_vq_info {
+	__u16 vq_id;
+	struct rproc *rproc;
+};
+
+/* kick the remote processor, and let it know which virtqueue to poke at */
+static void rproc_virtio_notify(struct virtqueue *vq)
+{
+	struct rproc_virtio_vq_info *rpvq = vq->priv;
+	struct rproc *rproc = rpvq->rproc;
+
+	dev_dbg(rproc->dev, "kicking vq id: %d\n", rpvq->vq_id);
+
+	rproc->ops->kick(rproc, rpvq->vq_id);
+}
+
+/**
+ * rproc_vq_interrupt() - tell remoteproc that a virtqueue is interrupted
+ * @rproc: handle to the remote processor
+ * @vq_id: index of the signalled virtqueue
+ *
+ * This function should be called by the platform-specific rproc driver,
+ * when the remote processor signals that a specific virtqueue has pending
+ * messages available.
+ *
+ * Returns IRQ_NONE if no message was found in the @vq_id virtqueue,
+ * and otherwise returns IRQ_HANDLED.
+ */
+irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id)
+{
+	return vring_interrupt(0, rproc->rvdev->vq[vq_id]);
+}
+EXPORT_SYMBOL(rproc_vq_interrupt);
+
+static struct virtqueue *rp_find_vq(struct virtio_device *vdev,
+				    unsigned id,
+				    void (*callback)(struct virtqueue *vq),
+				    const char *name)
+{
+	struct rproc *rproc = vdev_to_rproc(vdev);
+	struct rproc_vdev *rvdev = rproc->rvdev;
+	struct rproc_virtio_vq_info *rpvq;
+	struct virtqueue *vq;
+	void *addr;
+	int ret, len;
+
+	rpvq = kmalloc(sizeof(*rpvq), GFP_KERNEL);
+	if (!rpvq)
+		return ERR_PTR(-ENOMEM);
+
+	rpvq->rproc = rproc;
+	rpvq->vq_id = id;
+
+	addr = rvdev->vring[id].va;
+	len = rvdev->vring[id].len;
+
+	dev_dbg(rproc->dev, "vring%d: va %p qsz %d\n", id, addr, len);
+
+	/*
+	 * Create the new vq, and tell virtio we're not interested in
+	 * the 'weak' smp barriers, since we're talking with a real device.
+	 */
+	vq = vring_new_virtqueue(len, AMP_VRING_ALIGN, vdev, false, addr,
+					rproc_virtio_notify, callback, name);
+	if (!vq) {
+		dev_err(rproc->dev, "vring_new_virtqueue %s failed\n", name);
+		ret = -ENOMEM;
+		goto free_rpvq;
+	}
+
+	rvdev->vq[id] = vq;
+	vq->priv = rpvq;
+
+	return vq;
+
+free_rpvq:
+	kfree(rpvq);
+	return ERR_PTR(ret);
+}
+
+static void rproc_virtio_del_vqs(struct virtio_device *vdev)
+{
+	struct virtqueue *vq, *n;
+	struct rproc *rproc = vdev_to_rproc(vdev);
+
+	list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
+		struct rproc_virtio_vq_info *rpvq = vq->priv;
+		vring_del_virtqueue(vq);
+		kfree(rpvq);
+	}
+
+	/* power down the remote processor */
+	rproc_shutdown(rproc);
+}
+
+static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
+		       struct virtqueue *vqs[],
+		       vq_callback_t *callbacks[],
+		       const char *names[])
+{
+	struct rproc *rproc = vdev_to_rproc(vdev);
+	int i, ret;
+
+	/* we maintain two virtqueues per remote processor (for RX and TX) */
+	if (nvqs != 2)
+		return -EINVAL;
+
+	/* boot the remote processor */
+	ret = rproc_boot(rproc);
+	if (ret) {
+		dev_err(rproc->dev, "rproc_boot() failed %d\n", ret);
+		goto error;
+	}
+
+	for (i = 0; i < nvqs; ++i) {
+		vqs[i] = rp_find_vq(vdev, i, callbacks[i], names[i]);
+		if (IS_ERR(vqs[i])) {
+			ret = PTR_ERR(vqs[i]);
+			goto error;
+		}
+	}
+
+	return 0;
+
+error:
+	rproc_virtio_del_vqs(vdev);
+	return ret;
+}
+
+/*
+ * We don't support yet real virtio status semantics.
+ *
+ * The plan is to provide this via the VIRTIO HDR resource entry
+ * which is part of the firmware: this way the remote processor
+ * will be able to access the status values as set by us.
+ */
+static u8 rproc_virtio_get_status(struct virtio_device *vdev)
+{
+	return 0;
+}
+
+static void rproc_virtio_set_status(struct virtio_device *vdev, u8 status)
+{
+	dev_dbg(&vdev->dev, "new status: %d\n", status);
+}
+
+static void rproc_virtio_reset(struct virtio_device *vdev)
+{
+	dev_dbg(&vdev->dev, "reset !\n");
+}
+
+/* provide the vdev features as retrieved from the firmware */
+static u32 rproc_virtio_get_features(struct virtio_device *vdev)
+{
+	struct rproc *rproc = vdev_to_rproc(vdev);
+
+	/* we only support a single vdev device for now */
+	return rproc->rvdev->dfeatures;
+}
+
+static void rproc_virtio_finalize_features(struct virtio_device *vdev)
+{
+	struct rproc *rproc = vdev_to_rproc(vdev);
+
+	/* Give virtio_ring a chance to accept features */
+	vring_transport_features(vdev);
+
+	/*
+	 * Remember the finalized features of our vdev, and provide it
+	 * to the remote processor once it is powered on.
+	 *
+	 * Similarly to the status field, we don't expose yet the negotiated
+	 * features to the remote processors at this point. This will be
+	 * fixed as part of a small resource table overhaul and then an
+	 * extension of the virtio resource entries.
+	 */
+	rproc->rvdev->gfeatures = vdev->features[0];
+}
+
+static struct virtio_config_ops rproc_virtio_config_ops = {
+	.get_features	= rproc_virtio_get_features,
+	.finalize_features = rproc_virtio_finalize_features,
+	.find_vqs	= rproc_virtio_find_vqs,
+	.del_vqs	= rproc_virtio_del_vqs,
+	.reset		= rproc_virtio_reset,
+	.set_status	= rproc_virtio_set_status,
+	.get_status	= rproc_virtio_get_status,
+};
+
+/*
+ * This function is called whenever vdev is released, and is responsible
+ * to decrement the remote processor's refcount taken when vdev was
+ * added.
+ *
+ * Never call this function directly; it will be called by the driver
+ * core when needed.
+ */
+static void rproc_vdev_release(struct device *dev)
+{
+	struct virtio_device *vdev = dev_to_virtio(dev);
+	struct rproc *rproc = vdev_to_rproc(vdev);
+
+	kref_put(&rproc->refcount, rproc_release);
+}
+
+/**
+ * rproc_add_rpmsg_vdev() - create an rpmsg virtio device
+ * @rproc: the rproc handle
+ *
+ * This function is called if virtio rpmsg support was found in the
+ * firmware of the remote processor.
+ *
+ * Today we only support creating a single rpmsg vdev (virtio device),
+ * but the plan is to remove this limitation. At that point this interface
+ * will be revised/extended.
+ */
+int rproc_add_rpmsg_vdev(struct rproc *rproc)
+{
+	struct device *dev = rproc->dev;
+	struct rproc_vdev *rvdev = rproc->rvdev;
+	int ret;
+
+	rvdev->vdev.id.device	= VIRTIO_ID_RPMSG,
+	rvdev->vdev.config	= &rproc_virtio_config_ops,
+	rvdev->vdev.dev.parent	= dev;
+	rvdev->vdev.dev.release	= rproc_vdev_release;
+
+	/*
+	 * We're indirectly making a non-temporary copy of the rproc pointer
+	 * here, because drivers probed with this vdev will indirectly
+	 * access the wrapping rproc.
+	 *
+	 * Therefore we must increment the rproc refcount here, and decrement
+	 * it _only_ when the vdev is released.
+	 */
+	kref_get(&rproc->refcount);
+
+	ret = register_virtio_device(&rvdev->vdev);
+	if (ret) {
+		kref_put(&rproc->refcount, rproc_release);
+		dev_err(dev, "failed to register vdev: %d\n", ret);
+	}
+
+	return ret;
+}
+
+/**
+ * rproc_remove_rpmsg_vdev() - remove an rpmsg vdev device
+ * @rproc: the rproc handle
+ *
+ * This function is called whenever @rproc is removed _iff_ an rpmsg
+ * vdev was created beforehand.
+ */
+void rproc_remove_rpmsg_vdev(struct rproc *rproc)
+{
+	struct rproc_vdev *rvdev = rproc->rvdev;
+
+	unregister_virtio_device(&rvdev->vdev);
+}
diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig
new file mode 100644
index 0000000..32aead6
--- /dev/null
+++ b/drivers/rpmsg/Kconfig
@@ -0,0 +1,10 @@
+menu "Rpmsg drivers (EXPERIMENTAL)"
+
+# RPMSG always gets selected by whoever wants it
+config RPMSG
+	tristate
+	select VIRTIO
+	select VIRTIO_RING
+	depends on EXPERIMENTAL
+
+endmenu
diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile
new file mode 100644
index 0000000..7617fcb
--- /dev/null
+++ b/drivers/rpmsg/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RPMSG)	+= virtio_rpmsg_bus.o
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c
new file mode 100644
index 0000000..8980ac2
--- /dev/null
+++ b/drivers/rpmsg/virtio_rpmsg_bus.c
@@ -0,0 +1,1026 @@
+/*
+ * Virtio-based remote processor messaging bus
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/rpmsg.h>
+#include <linux/mutex.h>
+
+/**
+ * struct virtproc_info - virtual remote processor state
+ * @vdev:	the virtio device
+ * @rvq:	rx virtqueue
+ * @svq:	tx virtqueue
+ * @rbufs:	kernel address of rx buffers
+ * @sbufs:	kernel address of tx buffers
+ * @last_sbuf:	index of last tx buffer used
+ * @bufs_dma:	dma base addr of the buffers
+ * @tx_lock:	protects svq, sbufs and sleepers, to allow concurrent senders.
+ *		sending a message might require waking up a dozing remote
+ *		processor, which involves sleeping, hence the mutex.
+ * @endpoints:	idr of local endpoints, allows fast retrieval
+ * @endpoints_lock: lock of the endpoints set
+ * @sendq:	wait queue of sending contexts waiting for a tx buffers
+ * @sleepers:	number of senders that are waiting for a tx buffer
+ * @ns_ept:	the bus's name service endpoint
+ *
+ * This structure stores the rpmsg state of a given virtio remote processor
+ * device (there might be several virtio proc devices for each physical
+ * remote processor).
+ */
+struct virtproc_info {
+	struct virtio_device *vdev;
+	struct virtqueue *rvq, *svq;
+	void *rbufs, *sbufs;
+	int last_sbuf;
+	dma_addr_t bufs_dma;
+	struct mutex tx_lock;
+	struct idr endpoints;
+	struct mutex endpoints_lock;
+	wait_queue_head_t sendq;
+	atomic_t sleepers;
+	struct rpmsg_endpoint *ns_ept;
+};
+
+/**
+ * struct rpmsg_channel_info - internal channel info representation
+ * @name: name of service
+ * @src: local address
+ * @dst: destination address
+ */
+struct rpmsg_channel_info {
+	char name[RPMSG_NAME_SIZE];
+	u32 src;
+	u32 dst;
+};
+
+#define to_rpmsg_channel(d) container_of(d, struct rpmsg_channel, dev)
+#define to_rpmsg_driver(d) container_of(d, struct rpmsg_driver, drv)
+
+/*
+ * We're allocating 512 buffers of 512 bytes for communications, and then
+ * using the first 256 buffers for RX, and the last 256 buffers for TX.
+ *
+ * Each buffer will have 16 bytes for the msg header and 496 bytes for
+ * the payload.
+ *
+ * This will require a total space of 256KB for the buffers.
+ *
+ * We might also want to add support for user-provided buffers in time.
+ * This will allow bigger buffer size flexibility, and can also be used
+ * to achieve zero-copy messaging.
+ *
+ * Note that these numbers are purely a decision of this driver - we
+ * can change this without changing anything in the firmware of the remote
+ * processor.
+ */
+#define RPMSG_NUM_BUFS		(512)
+#define RPMSG_BUF_SIZE		(512)
+#define RPMSG_TOTAL_BUF_SPACE	(RPMSG_NUM_BUFS * RPMSG_BUF_SIZE)
+
+/*
+ * Local addresses are dynamically allocated on-demand.
+ * We do not dynamically assign addresses from the low 1024 range,
+ * in order to reserve that address range for predefined services.
+ */
+#define RPMSG_RESERVED_ADDRESSES	(1024)
+
+/* Address 53 is reserved for advertising remote services */
+#define RPMSG_NS_ADDR			(53)
+
+/* sysfs show configuration fields */
+#define rpmsg_show_attr(field, path, format_string)			\
+static ssize_t								\
+field##_show(struct device *dev,					\
+			struct device_attribute *attr, char *buf)	\
+{									\
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);		\
+									\
+	return sprintf(buf, format_string, rpdev->path);		\
+}
+
+/* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */
+rpmsg_show_attr(name, id.name, "%s\n");
+rpmsg_show_attr(src, src, "0x%x\n");
+rpmsg_show_attr(dst, dst, "0x%x\n");
+rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n");
+
+/*
+ * Unique (and free running) index for rpmsg devices.
+ *
+ * Yeah, we're not recycling those numbers (yet?). will be easy
+ * to change if/when we want to.
+ */
+static unsigned int rpmsg_dev_index;
+
+static ssize_t modalias_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+	return sprintf(buf, RPMSG_DEVICE_MODALIAS_FMT "\n", rpdev->id.name);
+}
+
+static struct device_attribute rpmsg_dev_attrs[] = {
+	__ATTR_RO(name),
+	__ATTR_RO(modalias),
+	__ATTR_RO(dst),
+	__ATTR_RO(src),
+	__ATTR_RO(announce),
+	__ATTR_NULL
+};
+
+/* rpmsg devices and drivers are matched using the service name */
+static inline int rpmsg_id_match(const struct rpmsg_channel *rpdev,
+				  const struct rpmsg_device_id *id)
+{
+	return strncmp(id->name, rpdev->id.name, RPMSG_NAME_SIZE) == 0;
+}
+
+/* match rpmsg channel and rpmsg driver */
+static int rpmsg_dev_match(struct device *dev, struct device_driver *drv)
+{
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+	struct rpmsg_driver *rpdrv = to_rpmsg_driver(drv);
+	const struct rpmsg_device_id *ids = rpdrv->id_table;
+	unsigned int i;
+
+	for (i = 0; ids[i].name[0]; i++)
+		if (rpmsg_id_match(rpdev, &ids[i]))
+			return 1;
+
+	return 0;
+}
+
+static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+	return add_uevent_var(env, "MODALIAS=" RPMSG_DEVICE_MODALIAS_FMT,
+					rpdev->id.name);
+}
+
+/* for more info, see below documentation of rpmsg_create_ept() */
+static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp,
+		struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb,
+		void *priv, u32 addr)
+{
+	int err, tmpaddr, request;
+	struct rpmsg_endpoint *ept;
+	struct device *dev = rpdev ? &rpdev->dev : &vrp->vdev->dev;
+
+	if (!idr_pre_get(&vrp->endpoints, GFP_KERNEL))
+		return NULL;
+
+	ept = kzalloc(sizeof(*ept), GFP_KERNEL);
+	if (!ept) {
+		dev_err(dev, "failed to kzalloc a new ept\n");
+		return NULL;
+	}
+
+	ept->rpdev = rpdev;
+	ept->cb = cb;
+	ept->priv = priv;
+
+	/* do we need to allocate a local address ? */
+	request = addr == RPMSG_ADDR_ANY ? RPMSG_RESERVED_ADDRESSES : addr;
+
+	mutex_lock(&vrp->endpoints_lock);
+
+	/* bind the endpoint to an rpmsg address (and allocate one if needed) */
+	err = idr_get_new_above(&vrp->endpoints, ept, request, &tmpaddr);
+	if (err) {
+		dev_err(dev, "idr_get_new_above failed: %d\n", err);
+		goto free_ept;
+	}
+
+	/* make sure the user's address request is fulfilled, if relevant */
+	if (addr != RPMSG_ADDR_ANY && tmpaddr != addr) {
+		dev_err(dev, "address 0x%x already in use\n", addr);
+		goto rem_idr;
+	}
+
+	ept->addr = tmpaddr;
+
+	mutex_unlock(&vrp->endpoints_lock);
+
+	return ept;
+
+rem_idr:
+	idr_remove(&vrp->endpoints, request);
+free_ept:
+	mutex_unlock(&vrp->endpoints_lock);
+	kfree(ept);
+	return NULL;
+}
+
+/**
+ * rpmsg_create_ept() - create a new rpmsg_endpoint
+ * @rpdev: rpmsg channel device
+ * @cb: rx callback handler
+ * @priv: private data for the driver's use
+ * @addr: local rpmsg address to bind with @cb
+ *
+ * Every rpmsg address in the system is bound to an rx callback (so when
+ * inbound messages arrive, they are dispatched by the rpmsg bus using the
+ * appropriate callback handler) by means of an rpmsg_endpoint struct.
+ *
+ * This function allows drivers to create such an endpoint, and by that,
+ * bind a callback, and possibly some private data too, to an rpmsg address
+ * (either one that is known in advance, or one that will be dynamically
+ * assigned for them).
+ *
+ * Simple rpmsg drivers need not call rpmsg_create_ept, because an endpoint
+ * is already created for them when they are probed by the rpmsg bus
+ * (using the rx callback provided when they registered to the rpmsg bus).
+ *
+ * So things should just work for simple drivers: they already have an
+ * endpoint, their rx callback is bound to their rpmsg address, and when
+ * relevant inbound messages arrive (i.e. messages which their dst address
+ * equals to the src address of their rpmsg channel), the driver's handler
+ * is invoked to process it.
+ *
+ * That said, more complicated drivers might do need to allocate
+ * additional rpmsg addresses, and bind them to different rx callbacks.
+ * To accomplish that, those drivers need to call this function.
+ *
+ * Drivers should provide their @rpdev channel (so the new endpoint would belong
+ * to the same remote processor their channel belongs to), an rx callback
+ * function, an optional private data (which is provided back when the
+ * rx callback is invoked), and an address they want to bind with the
+ * callback. If @addr is RPMSG_ADDR_ANY, then rpmsg_create_ept will
+ * dynamically assign them an available rpmsg address (drivers should have
+ * a very good reason why not to always use RPMSG_ADDR_ANY here).
+ *
+ * Returns a pointer to the endpoint on success, or NULL on error.
+ */
+struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev,
+				rpmsg_rx_cb_t cb, void *priv, u32 addr)
+{
+	return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, addr);
+}
+EXPORT_SYMBOL(rpmsg_create_ept);
+
+/**
+ * rpmsg_destroy_ept() - destroy an existing rpmsg endpoint
+ * @ept: endpoing to destroy
+ *
+ * Should be used by drivers to destroy an rpmsg endpoint previously
+ * created with rpmsg_create_ept().
+ */
+void rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
+{
+	struct virtproc_info *vrp = ept->rpdev->vrp;
+
+	mutex_lock(&vrp->endpoints_lock);
+	idr_remove(&vrp->endpoints, ept->addr);
+	mutex_unlock(&vrp->endpoints_lock);
+
+	kfree(ept);
+}
+EXPORT_SYMBOL(rpmsg_destroy_ept);
+
+/*
+ * when an rpmsg driver is probed with a channel, we seamlessly create
+ * it an endpoint, binding its rx callback to a unique local rpmsg
+ * address.
+ *
+ * if we need to, we also announce about this channel to the remote
+ * processor (needed in case the driver is exposing an rpmsg service).
+ */
+static int rpmsg_dev_probe(struct device *dev)
+{
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+	struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
+	struct virtproc_info *vrp = rpdev->vrp;
+	struct rpmsg_endpoint *ept;
+	int err;
+
+	ept = rpmsg_create_ept(rpdev, rpdrv->callback, NULL, rpdev->src);
+	if (!ept) {
+		dev_err(dev, "failed to create endpoint\n");
+		err = -ENOMEM;
+		goto out;
+	}
+
+	rpdev->ept = ept;
+	rpdev->src = ept->addr;
+
+	err = rpdrv->probe(rpdev);
+	if (err) {
+		dev_err(dev, "%s: failed: %d\n", __func__, err);
+		rpmsg_destroy_ept(ept);
+		goto out;
+	}
+
+	/* need to tell remote processor's name service about this channel ? */
+	if (rpdev->announce &&
+			virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
+		struct rpmsg_ns_msg nsm;
+
+		strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+		nsm.addr = rpdev->src;
+		nsm.flags = RPMSG_NS_CREATE;
+
+		err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
+		if (err)
+			dev_err(dev, "failed to announce service %d\n", err);
+	}
+
+out:
+	return err;
+}
+
+static int rpmsg_dev_remove(struct device *dev)
+{
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+	struct rpmsg_driver *rpdrv = to_rpmsg_driver(rpdev->dev.driver);
+	struct virtproc_info *vrp = rpdev->vrp;
+	int err = 0;
+
+	/* tell remote processor's name service we're removing this channel */
+	if (rpdev->announce &&
+			virtio_has_feature(vrp->vdev, VIRTIO_RPMSG_F_NS)) {
+		struct rpmsg_ns_msg nsm;
+
+		strncpy(nsm.name, rpdev->id.name, RPMSG_NAME_SIZE);
+		nsm.addr = rpdev->src;
+		nsm.flags = RPMSG_NS_DESTROY;
+
+		err = rpmsg_sendto(rpdev, &nsm, sizeof(nsm), RPMSG_NS_ADDR);
+		if (err)
+			dev_err(dev, "failed to announce service %d\n", err);
+	}
+
+	rpdrv->remove(rpdev);
+
+	rpmsg_destroy_ept(rpdev->ept);
+
+	return err;
+}
+
+static struct bus_type rpmsg_bus = {
+	.name		= "rpmsg",
+	.match		= rpmsg_dev_match,
+	.dev_attrs	= rpmsg_dev_attrs,
+	.uevent		= rpmsg_uevent,
+	.probe		= rpmsg_dev_probe,
+	.remove		= rpmsg_dev_remove,
+};
+
+/**
+ * register_rpmsg_driver() - register an rpmsg driver with the rpmsg bus
+ * @rpdrv: pointer to a struct rpmsg_driver
+ *
+ * Returns 0 on success, and an appropriate error value on failure.
+ */
+int register_rpmsg_driver(struct rpmsg_driver *rpdrv)
+{
+	rpdrv->drv.bus = &rpmsg_bus;
+	return driver_register(&rpdrv->drv);
+}
+EXPORT_SYMBOL(register_rpmsg_driver);
+
+/**
+ * unregister_rpmsg_driver() - unregister an rpmsg driver from the rpmsg bus
+ * @rpdrv: pointer to a struct rpmsg_driver
+ *
+ * Returns 0 on success, and an appropriate error value on failure.
+ */
+void unregister_rpmsg_driver(struct rpmsg_driver *rpdrv)
+{
+	driver_unregister(&rpdrv->drv);
+}
+EXPORT_SYMBOL(unregister_rpmsg_driver);
+
+static void rpmsg_release_device(struct device *dev)
+{
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+	kfree(rpdev);
+}
+
+/*
+ * match an rpmsg channel with a channel info struct.
+ * this is used to make sure we're not creating rpmsg devices for channels
+ * that already exist.
+ */
+static int rpmsg_channel_match(struct device *dev, void *data)
+{
+	struct rpmsg_channel_info *chinfo = data;
+	struct rpmsg_channel *rpdev = to_rpmsg_channel(dev);
+
+	if (chinfo->src != RPMSG_ADDR_ANY && chinfo->src != rpdev->src)
+		return 0;
+
+	if (chinfo->dst != RPMSG_ADDR_ANY && chinfo->dst != rpdev->dst)
+		return 0;
+
+	if (strncmp(chinfo->name, rpdev->id.name, RPMSG_NAME_SIZE))
+		return 0;
+
+	/* found a match ! */
+	return 1;
+}
+
+/*
+ * create an rpmsg channel using its name and address info.
+ * this function will be used to create both static and dynamic
+ * channels.
+ */
+static struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp,
+				struct rpmsg_channel_info *chinfo)
+{
+	struct rpmsg_channel *rpdev;
+	struct device *tmp, *dev = &vrp->vdev->dev;
+	int ret;
+
+	/* make sure a similar channel doesn't already exist */
+	tmp = device_find_child(dev, chinfo, rpmsg_channel_match);
+	if (tmp) {
+		/* decrement the matched device's refcount back */
+		put_device(tmp);
+		dev_err(dev, "channel %s:%x:%x already exist\n",
+				chinfo->name, chinfo->src, chinfo->dst);
+		return NULL;
+	}
+
+	rpdev = kzalloc(sizeof(struct rpmsg_channel), GFP_KERNEL);
+	if (!rpdev) {
+		pr_err("kzalloc failed\n");
+		return NULL;
+	}
+
+	rpdev->vrp = vrp;
+	rpdev->src = chinfo->src;
+	rpdev->dst = chinfo->dst;
+
+	/*
+	 * rpmsg server channels has predefined local address (for now),
+	 * and their existence needs to be announced remotely
+	 */
+	rpdev->announce = rpdev->src != RPMSG_ADDR_ANY ? true : false;
+
+	strncpy(rpdev->id.name, chinfo->name, RPMSG_NAME_SIZE);
+
+	/* very simple device indexing plumbing which is enough for now */
+	dev_set_name(&rpdev->dev, "rpmsg%d", rpmsg_dev_index++);
+
+	rpdev->dev.parent = &vrp->vdev->dev;
+	rpdev->dev.bus = &rpmsg_bus;
+	rpdev->dev.release = rpmsg_release_device;
+
+	ret = device_register(&rpdev->dev);
+	if (ret) {
+		dev_err(dev, "device_register failed: %d\n", ret);
+		put_device(&rpdev->dev);
+		return NULL;
+	}
+
+	return rpdev;
+}
+
+/*
+ * find an existing channel using its name + address properties,
+ * and destroy it
+ */
+static int rpmsg_destroy_channel(struct virtproc_info *vrp,
+					struct rpmsg_channel_info *chinfo)
+{
+	struct virtio_device *vdev = vrp->vdev;
+	struct device *dev;
+
+	dev = device_find_child(&vdev->dev, chinfo, rpmsg_channel_match);
+	if (!dev)
+		return -EINVAL;
+
+	device_unregister(dev);
+
+	put_device(dev);
+
+	return 0;
+}
+
+/* super simple buffer "allocator" that is just enough for now */
+static void *get_a_tx_buf(struct virtproc_info *vrp)
+{
+	unsigned int len;
+	void *ret;
+
+	/* support multiple concurrent senders */
+	mutex_lock(&vrp->tx_lock);
+
+	/*
+	 * either pick the next unused tx buffer
+	 * (half of our buffers are used for sending messages)
+	 */
+	if (vrp->last_sbuf < RPMSG_NUM_BUFS / 2)
+		ret = vrp->sbufs + RPMSG_BUF_SIZE * vrp->last_sbuf++;
+	/* or recycle a used one */
+	else
+		ret = virtqueue_get_buf(vrp->svq, &len);
+
+	mutex_unlock(&vrp->tx_lock);
+
+	return ret;
+}
+
+/**
+ * rpmsg_upref_sleepers() - enable "tx-complete" interrupts, if needed
+ * @vrp: virtual remote processor state
+ *
+ * This function is called before a sender is blocked, waiting for
+ * a tx buffer to become available.
+ *
+ * If we already have blocking senders, this function merely increases
+ * the "sleepers" reference count, and exits.
+ *
+ * Otherwise, if this is the first sender to block, we also enable
+ * virtio's tx callbacks, so we'd be immediately notified when a tx
+ * buffer is consumed (we rely on virtio's tx callback in order
+ * to wake up sleeping senders as soon as a tx buffer is used by the
+ * remote processor).
+ */
+static void rpmsg_upref_sleepers(struct virtproc_info *vrp)
+{
+	/* support multiple concurrent senders */
+	mutex_lock(&vrp->tx_lock);
+
+	/* are we the first sleeping context waiting for tx buffers ? */
+	if (atomic_inc_return(&vrp->sleepers) == 1)
+		/* enable "tx-complete" interrupts before dozing off */
+		virtqueue_enable_cb(vrp->svq);
+
+	mutex_unlock(&vrp->tx_lock);
+}
+
+/**
+ * rpmsg_downref_sleepers() - disable "tx-complete" interrupts, if needed
+ * @vrp: virtual remote processor state
+ *
+ * This function is called after a sender, that waited for a tx buffer
+ * to become available, is unblocked.
+ *
+ * If we still have blocking senders, this function merely decreases
+ * the "sleepers" reference count, and exits.
+ *
+ * Otherwise, if there are no more blocking senders, we also disable
+ * virtio's tx callbacks, to avoid the overhead incurred with handling
+ * those (now redundant) interrupts.
+ */
+static void rpmsg_downref_sleepers(struct virtproc_info *vrp)
+{
+	/* support multiple concurrent senders */
+	mutex_lock(&vrp->tx_lock);
+
+	/* are we the last sleeping context waiting for tx buffers ? */
+	if (atomic_dec_and_test(&vrp->sleepers))
+		/* disable "tx-complete" interrupts */
+		virtqueue_disable_cb(vrp->svq);
+
+	mutex_unlock(&vrp->tx_lock);
+}
+
+/**
+ * rpmsg_send_offchannel_raw() - send a message across to the remote processor
+ * @rpdev: the rpmsg channel
+ * @src: source address
+ * @dst: destination address
+ * @data: payload of message
+ * @len: length of payload
+ * @wait: indicates whether caller should block in case no TX buffers available
+ *
+ * This function is the base implementation for all of the rpmsg sending API.
+ *
+ * It will send @data of length @len to @dst, and say it's from @src. The
+ * message will be sent to the remote processor which the @rpdev channel
+ * belongs to.
+ *
+ * The message is sent using one of the TX buffers that are available for
+ * communication with this remote processor.
+ *
+ * If @wait is true, the caller will be blocked until either a TX buffer is
+ * available, or 15 seconds elapses (we don't want callers to
+ * sleep indefinitely due to misbehaving remote processors), and in that
+ * case -ERESTARTSYS is returned. The number '15' itself was picked
+ * arbitrarily; there's little point in asking drivers to provide a timeout
+ * value themselves.
+ *
+ * Otherwise, if @wait is false, and there are no TX buffers available,
+ * the function will immediately fail, and -ENOMEM will be returned.
+ *
+ * Normally drivers shouldn't use this function directly; instead, drivers
+ * should use the appropriate rpmsg_{try}send{to, _offchannel} API
+ * (see include/linux/rpmsg.h).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+int rpmsg_send_offchannel_raw(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+					void *data, int len, bool wait)
+{
+	struct virtproc_info *vrp = rpdev->vrp;
+	struct device *dev = &rpdev->dev;
+	struct scatterlist sg;
+	struct rpmsg_hdr *msg;
+	int err;
+
+	/* bcasting isn't allowed */
+	if (src == RPMSG_ADDR_ANY || dst == RPMSG_ADDR_ANY) {
+		dev_err(dev, "invalid addr (src 0x%x, dst 0x%x)\n", src, dst);
+		return -EINVAL;
+	}
+
+	/*
+	 * We currently use fixed-sized buffers, and therefore the payload
+	 * length is limited.
+	 *
+	 * One of the possible improvements here is either to support
+	 * user-provided buffers (and then we can also support zero-copy
+	 * messaging), or to improve the buffer allocator, to support
+	 * variable-length buffer sizes.
+	 */
+	if (len > RPMSG_BUF_SIZE - sizeof(struct rpmsg_hdr)) {
+		dev_err(dev, "message is too big (%d)\n", len);
+		return -EMSGSIZE;
+	}
+
+	/* grab a buffer */
+	msg = get_a_tx_buf(vrp);
+	if (!msg && !wait)
+		return -ENOMEM;
+
+	/* no free buffer ? wait for one (but bail after 15 seconds) */
+	while (!msg) {
+		/* enable "tx-complete" interrupts, if not already enabled */
+		rpmsg_upref_sleepers(vrp);
+
+		/*
+		 * sleep until a free buffer is available or 15 secs elapse.
+		 * the timeout period is not configurable because there's
+		 * little point in asking drivers to specify that.
+		 * if later this happens to be required, it'd be easy to add.
+		 */
+		err = wait_event_interruptible_timeout(vrp->sendq,
+					(msg = get_a_tx_buf(vrp)),
+					msecs_to_jiffies(15000));
+
+		/* disable "tx-complete" interrupts if we're the last sleeper */
+		rpmsg_downref_sleepers(vrp);
+
+		/* timeout ? */
+		if (!err) {
+			dev_err(dev, "timeout waiting for a tx buffer\n");
+			return -ERESTARTSYS;
+		}
+	}
+
+	msg->len = len;
+	msg->flags = 0;
+	msg->src = src;
+	msg->dst = dst;
+	msg->reserved = 0;
+	memcpy(msg->data, data, len);
+
+	dev_dbg(dev, "TX From 0x%x, To 0x%x, Len %d, Flags %d, Reserved %d\n",
+					msg->src, msg->dst, msg->len,
+					msg->flags, msg->reserved);
+	print_hex_dump(KERN_DEBUG, "rpmsg_virtio TX: ", DUMP_PREFIX_NONE, 16, 1,
+					msg, sizeof(*msg) + msg->len, true);
+
+	sg_init_one(&sg, msg, sizeof(*msg) + len);
+
+	mutex_lock(&vrp->tx_lock);
+
+	/* add message to the remote processor's virtqueue */
+	err = virtqueue_add_buf(vrp->svq, &sg, 1, 0, msg, GFP_KERNEL);
+	if (err < 0) {
+		/*
+		 * need to reclaim the buffer here, otherwise it's lost
+		 * (memory won't leak, but rpmsg won't use it again for TX).
+		 * this will wait for a buffer management overhaul.
+		 */
+		dev_err(dev, "virtqueue_add_buf failed: %d\n", err);
+		goto out;
+	}
+
+	/* tell the remote processor it has a pending message to read */
+	virtqueue_kick(vrp->svq);
+
+	err = 0;
+out:
+	mutex_unlock(&vrp->tx_lock);
+	return err;
+}
+EXPORT_SYMBOL(rpmsg_send_offchannel_raw);
+
+/* called when an rx buffer is used, and it's time to digest a message */
+static void rpmsg_recv_done(struct virtqueue *rvq)
+{
+	struct rpmsg_hdr *msg;
+	unsigned int len;
+	struct rpmsg_endpoint *ept;
+	struct scatterlist sg;
+	struct virtproc_info *vrp = rvq->vdev->priv;
+	struct device *dev = &rvq->vdev->dev;
+	int err;
+
+	msg = virtqueue_get_buf(rvq, &len);
+	if (!msg) {
+		dev_err(dev, "uhm, incoming signal, but no used buffer ?\n");
+		return;
+	}
+
+	dev_dbg(dev, "From: 0x%x, To: 0x%x, Len: %d, Flags: %d, Reserved: %d\n",
+					msg->src, msg->dst, msg->len,
+					msg->flags, msg->reserved);
+	print_hex_dump(KERN_DEBUG, "rpmsg_virtio RX: ", DUMP_PREFIX_NONE, 16, 1,
+					msg, sizeof(*msg) + msg->len, true);
+
+	/* use the dst addr to fetch the callback of the appropriate user */
+	mutex_lock(&vrp->endpoints_lock);
+	ept = idr_find(&vrp->endpoints, msg->dst);
+	mutex_unlock(&vrp->endpoints_lock);
+
+	if (ept && ept->cb)
+		ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src);
+	else
+		dev_warn(dev, "msg received with no recepient\n");
+
+	sg_init_one(&sg, msg, sizeof(*msg) + len);
+
+	/* add the buffer back to the remote processor's virtqueue */
+	err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, msg, GFP_KERNEL);
+	if (err < 0) {
+		dev_err(dev, "failed to add a virtqueue buffer: %d\n", err);
+		return;
+	}
+
+	/* tell the remote processor we added another available rx buffer */
+	virtqueue_kick(vrp->rvq);
+}
+
+/*
+ * This is invoked whenever the remote processor completed processing
+ * a TX msg we just sent it, and the buffer is put back to the used ring.
+ *
+ * Normally, though, we suppress this "tx complete" interrupt in order to
+ * avoid the incurred overhead.
+ */
+static void rpmsg_xmit_done(struct virtqueue *svq)
+{
+	struct virtproc_info *vrp = svq->vdev->priv;
+
+	dev_dbg(&svq->vdev->dev, "%s\n", __func__);
+
+	/* wake up potential senders that are waiting for a tx buffer */
+	wake_up_interruptible(&vrp->sendq);
+}
+
+/* invoked when a name service announcement arrives */
+static void rpmsg_ns_cb(struct rpmsg_channel *rpdev, void *data, int len,
+							void *priv, u32 src)
+{
+	struct rpmsg_ns_msg *msg = data;
+	struct rpmsg_channel *newch;
+	struct rpmsg_channel_info chinfo;
+	struct virtproc_info *vrp = priv;
+	struct device *dev = &vrp->vdev->dev;
+	int ret;
+
+	print_hex_dump(KERN_DEBUG, "NS announcement: ",
+			DUMP_PREFIX_NONE, 16, 1,
+			data, len, true);
+
+	if (len != sizeof(*msg)) {
+		dev_err(dev, "malformed ns msg (%d)\n", len);
+		return;
+	}
+
+	/*
+	 * the name service ept does _not_ belong to a real rpmsg channel,
+	 * and is handled by the rpmsg bus itself.
+	 * for sanity reasons, make sure a valid rpdev has _not_ sneaked
+	 * in somehow.
+	 */
+	if (rpdev) {
+		dev_err(dev, "anomaly: ns ept has an rpdev handle\n");
+		return;
+	}
+
+	/* don't trust the remote processor for null terminating the name */
+	msg->name[RPMSG_NAME_SIZE - 1] = '\0';
+
+	dev_info(dev, "%sing channel %s addr 0x%x\n",
+			msg->flags & RPMSG_NS_DESTROY ? "destroy" : "creat",
+			msg->name, msg->addr);
+
+	strncpy(chinfo.name, msg->name, sizeof(chinfo.name));
+	chinfo.src = RPMSG_ADDR_ANY;
+	chinfo.dst = msg->addr;
+
+	if (msg->flags & RPMSG_NS_DESTROY) {
+		ret = rpmsg_destroy_channel(vrp, &chinfo);
+		if (ret)
+			dev_err(dev, "rpmsg_destroy_channel failed: %d\n", ret);
+	} else {
+		newch = rpmsg_create_channel(vrp, &chinfo);
+		if (!newch)
+			dev_err(dev, "rpmsg_create_channel failed\n");
+	}
+}
+
+static int rpmsg_probe(struct virtio_device *vdev)
+{
+	vq_callback_t *vq_cbs[] = { rpmsg_recv_done, rpmsg_xmit_done };
+	const char *names[] = { "input", "output" };
+	struct virtqueue *vqs[2];
+	struct virtproc_info *vrp;
+	void *bufs_va;
+	int err = 0, i;
+
+	vrp = kzalloc(sizeof(*vrp), GFP_KERNEL);
+	if (!vrp)
+		return -ENOMEM;
+
+	vrp->vdev = vdev;
+
+	idr_init(&vrp->endpoints);
+	mutex_init(&vrp->endpoints_lock);
+	mutex_init(&vrp->tx_lock);
+	init_waitqueue_head(&vrp->sendq);
+
+	/* We expect two virtqueues, rx and tx (and in this order) */
+	err = vdev->config->find_vqs(vdev, 2, vqs, vq_cbs, names);
+	if (err)
+		goto free_vrp;
+
+	vrp->rvq = vqs[0];
+	vrp->svq = vqs[1];
+
+	/* allocate coherent memory for the buffers */
+	bufs_va = dma_alloc_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE,
+				&vrp->bufs_dma, GFP_KERNEL);
+	if (!bufs_va)
+		goto vqs_del;
+
+	dev_dbg(&vdev->dev, "buffers: va %p, dma 0x%x\n", bufs_va,
+						vrp->bufs_dma);
+
+	/* half of the buffers is dedicated for RX */
+	vrp->rbufs = bufs_va;
+
+	/* and half is dedicated for TX */
+	vrp->sbufs = bufs_va + RPMSG_TOTAL_BUF_SPACE / 2;
+
+	/* set up the receive buffers */
+	for (i = 0; i < RPMSG_NUM_BUFS / 2; i++) {
+		struct scatterlist sg;
+		void *cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE;
+
+		sg_init_one(&sg, cpu_addr, RPMSG_BUF_SIZE);
+
+		err = virtqueue_add_buf(vrp->rvq, &sg, 0, 1, cpu_addr,
+								GFP_KERNEL);
+		WARN_ON(err < 0); /* sanity check; this can't really happen */
+	}
+
+	/* suppress "tx-complete" interrupts */
+	virtqueue_disable_cb(vrp->svq);
+
+	vdev->priv = vrp;
+
+	/* if supported by the remote processor, enable the name service */
+	if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) {
+		/* a dedicated endpoint handles the name service msgs */
+		vrp->ns_ept = __rpmsg_create_ept(vrp, NULL, rpmsg_ns_cb,
+						vrp, RPMSG_NS_ADDR);
+		if (!vrp->ns_ept) {
+			dev_err(&vdev->dev, "failed to create the ns ept\n");
+			err = -ENOMEM;
+			goto free_coherent;
+		}
+	}
+
+	/* tell the remote processor it can start sending messages */
+	virtqueue_kick(vrp->rvq);
+
+	dev_info(&vdev->dev, "rpmsg host is online\n");
+
+	return 0;
+
+free_coherent:
+	dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, bufs_va,
+					vrp->bufs_dma);
+vqs_del:
+	vdev->config->del_vqs(vrp->vdev);
+free_vrp:
+	kfree(vrp);
+	return err;
+}
+
+static int rpmsg_remove_device(struct device *dev, void *data)
+{
+	device_unregister(dev);
+
+	return 0;
+}
+
+static void __devexit rpmsg_remove(struct virtio_device *vdev)
+{
+	struct virtproc_info *vrp = vdev->priv;
+	int ret;
+
+	vdev->config->reset(vdev);
+
+	ret = device_for_each_child(&vdev->dev, NULL, rpmsg_remove_device);
+	if (ret)
+		dev_warn(&vdev->dev, "can't remove rpmsg device: %d\n", ret);
+
+	idr_remove_all(&vrp->endpoints);
+	idr_destroy(&vrp->endpoints);
+
+	vdev->config->del_vqs(vrp->vdev);
+
+	dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE,
+					vrp->rbufs, vrp->bufs_dma);
+
+	kfree(vrp);
+}
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_RPMSG, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static unsigned int features[] = {
+	VIRTIO_RPMSG_F_NS,
+};
+
+static struct virtio_driver virtio_ipc_driver = {
+	.feature_table	= features,
+	.feature_table_size = ARRAY_SIZE(features),
+	.driver.name	= KBUILD_MODNAME,
+	.driver.owner	= THIS_MODULE,
+	.id_table	= id_table,
+	.probe		= rpmsg_probe,
+	.remove		= __devexit_p(rpmsg_remove),
+};
+
+static int __init rpmsg_init(void)
+{
+	int ret;
+
+	ret = bus_register(&rpmsg_bus);
+	if (ret) {
+		pr_err("failed to register rpmsg bus: %d\n", ret);
+		return ret;
+	}
+
+	ret = register_virtio_driver(&virtio_ipc_driver);
+	if (ret) {
+		pr_err("failed to register virtio driver: %d\n", ret);
+		bus_unregister(&rpmsg_bus);
+	}
+
+	return ret;
+}
+module_init(rpmsg_init);
+
+static void __exit rpmsg_fini(void)
+{
+	unregister_virtio_driver(&virtio_ipc_driver);
+	bus_unregister(&rpmsg_bus);
+}
+module_exit(rpmsg_fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio-based remote processor messaging bus");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 3a125b8..4f9fb25 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -554,6 +554,13 @@ config RTC_DRV_DS1742
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-ds1742.
 
+config RTC_DRV_DA9052
+	tristate "Dialog DA9052/DA9053 RTC"
+	depends on PMIC_DA9052
+	help
+	  Say y here to support the RTC driver for Dialog Semiconductor
+	  DA9052-BC and DA9053-AA/Bx PMICs.
+
 config RTC_DRV_EFI
 	tristate "EFI RTC"
 	depends on IA64
@@ -1070,4 +1077,14 @@ config RTC_DRV_PUV3
 	  This drive can also be built as a module. If so, the module
 	  will be called rtc-puv3.
 
+config RTC_DRV_LOONGSON1
+	tristate "loongson1 RTC support"
+	depends on MACH_LOONGSON1
+	help
+	  This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year
+	  counter) to be used as a RTC.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-ls1x.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 6e69823..727ae77 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K)	+= rtc-bq32k.o
 obj-$(CONFIG_RTC_DRV_BQ4802)	+= rtc-bq4802.o
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_COH901331)	+= rtc-coh901331.o
+obj-$(CONFIG_RTC_DRV_DA9052)	+= rtc-da9052.o
 obj-$(CONFIG_RTC_DRV_DAVINCI)	+= rtc-davinci.o
 obj-$(CONFIG_RTC_DRV_DM355EVM)	+= rtc-dm355evm.o
 obj-$(CONFIG_RTC_DRV_VRTC)	+= rtc-mrst.o
@@ -53,6 +54,7 @@ obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
 obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o
 obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o
 obj-$(CONFIG_RTC_DRV_LPC32XX)	+= rtc-lpc32xx.o
+obj-$(CONFIG_RTC_DRV_LOONGSON1)	+= rtc-ls1x.o
 obj-$(CONFIG_RTC_DRV_M41T80)	+= rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M41T93)	+= rtc-m41t93.o
 obj-$(CONFIG_RTC_DRV_M41T94)	+= rtc-m41t94.o
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index ee3c122..274a0aa 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -335,7 +335,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
 
 	/* register irq handler after we know what name we'll use */
 	ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
-				IRQF_DISABLED | IRQF_SHARED,
+				IRQF_SHARED,
 				dev_name(&rtc->rtcdev->dev), rtc);
 	if (ret) {
 		dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 408cc8f..f090159 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -187,17 +187,7 @@ static struct i2c_driver bq32k_driver = {
 	.id_table	= bq32k_id,
 };
 
-static __init int bq32k_init(void)
-{
-	return i2c_add_driver(&bq32k_driver);
-}
-module_init(bq32k_init);
-
-static __exit void bq32k_exit(void)
-{
-	i2c_del_driver(&bq32k_driver);
-}
-module_exit(bq32k_exit);
+module_i2c_driver(bq32k_driver);
 
 MODULE_AUTHOR("Semihalf, Piotr Ziecik <kosmo@semihalf.com>");
 MODULE_DESCRIPTION("TI BQ32000 I2C RTC driver");
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index d7782aa..7d5f56e 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -714,7 +714,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
 			rtc_cmos_int_handler = cmos_interrupt;
 
 		retval = request_irq(rtc_irq, rtc_cmos_int_handler,
-				IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev),
+				0, dev_name(&cmos_rtc.rtc->dev),
 				cmos_rtc.rtc);
 		if (retval < 0) {
 			dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 80f9c88..a5b8a0c 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -199,7 +199,7 @@ static int __init coh901331_probe(struct platform_device *pdev)
 	}
 
 	rtap->irq = platform_get_irq(pdev, 0);
-	if (request_irq(rtap->irq, coh901331_interrupt, IRQF_DISABLED,
+	if (request_irq(rtap->irq, coh901331_interrupt, 0,
 			"RTC COH 901 331 Alarm", rtap)) {
 		ret = -EIO;
 		goto out_no_irq;
diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c
new file mode 100644
index 0000000..da6ab52
--- /dev/null
+++ b/drivers/rtc/rtc-da9052.c
@@ -0,0 +1,293 @@
+/*
+ * Real time clock driver for DA9052
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Dajun Dajun Chen <dajun.chen@diasemi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/reg.h>
+
+#define rtc_err(da9052, fmt, ...) \
+		dev_err(da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__)
+
+struct da9052_rtc {
+	struct rtc_device *rtc;
+	struct da9052 *da9052;
+	int irq;
+};
+
+static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable)
+{
+	int ret;
+	if (enable) {
+		ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+					DA9052_ALARM_Y_ALARM_ON,
+					DA9052_ALARM_Y_ALARM_ON);
+		if (ret != 0)
+			rtc_err(da9052, "Failed to enable ALM: %d\n", ret);
+	} else {
+		ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+					DA9052_ALARM_Y_ALARM_ON, 0);
+		if (ret != 0)
+			rtc_err(da9052, "Write error: %d\n", ret);
+	}
+	return ret;
+}
+
+static irqreturn_t da9052_rtc_irq(int irq, void *data)
+{
+	struct da9052_rtc *rtc = data;
+	int ret;
+
+	ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_MI_REG);
+	if (ret < 0) {
+		rtc_err(rtc->da9052, "Read error: %d\n", ret);
+		return IRQ_NONE;
+	}
+
+	if (ret & DA9052_ALARMMI_ALARMTYPE) {
+		da9052_rtc_enable_alarm(rtc->da9052, 0);
+		rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
+	} else
+		rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_PF);
+
+	return IRQ_HANDLED;
+}
+
+static int da9052_read_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
+{
+	int ret;
+	uint8_t v[5];
+
+	ret = da9052_group_read(da9052, DA9052_ALARM_MI_REG, 5, v);
+	if (ret != 0) {
+		rtc_err(da9052, "Failed to group read ALM: %d\n", ret);
+		return ret;
+	}
+
+	rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100;
+	rtc_tm->tm_mon  = (v[3] & DA9052_RTC_MONTH) - 1;
+	rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY;
+	rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR;
+	rtc_tm->tm_min  = v[0] & DA9052_RTC_MIN;
+
+	ret = rtc_valid_tm(rtc_tm);
+	if (ret != 0)
+		return ret;
+	return ret;
+}
+
+static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm)
+{
+	int ret;
+	uint8_t v[3];
+
+	rtc_tm->tm_year -= 100;
+	rtc_tm->tm_mon += 1;
+
+	ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG,
+				DA9052_RTC_MIN, rtc_tm->tm_min);
+	if (ret != 0) {
+		rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret);
+		return ret;
+	}
+
+	v[0] = rtc_tm->tm_hour;
+	v[1] = rtc_tm->tm_mday;
+	v[2] = rtc_tm->tm_mon;
+
+	ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v);
+	if (ret < 0)
+		return ret;
+
+	ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG,
+				DA9052_RTC_YEAR, rtc_tm->tm_year);
+	if (ret != 0)
+		rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret);
+
+	return ret;
+}
+
+static int da9052_rtc_get_alarm_status(struct da9052 *da9052)
+{
+	int ret;
+
+	ret = da9052_reg_read(da9052, DA9052_ALARM_Y_REG);
+	if (ret < 0) {
+		rtc_err(da9052, "Failed to read ALM: %d\n", ret);
+		return ret;
+	}
+	ret &= DA9052_ALARM_Y_ALARM_ON;
+	return (ret > 0) ? 1 : 0;
+}
+
+static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
+{
+	struct da9052_rtc *rtc = dev_get_drvdata(dev);
+	uint8_t v[6];
+	int ret;
+
+	ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
+	if (ret < 0) {
+		rtc_err(rtc->da9052, "Failed to read RTC time : %d\n", ret);
+		return ret;
+	}
+
+	rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100;
+	rtc_tm->tm_mon  = (v[4] & DA9052_RTC_MONTH) - 1;
+	rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY;
+	rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR;
+	rtc_tm->tm_min  = v[1] & DA9052_RTC_MIN;
+	rtc_tm->tm_sec  = v[0] & DA9052_RTC_SEC;
+
+	ret = rtc_valid_tm(rtc_tm);
+	if (ret != 0) {
+		rtc_err(rtc->da9052, "rtc_valid_tm failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct da9052_rtc *rtc;
+	uint8_t v[6];
+
+	rtc = dev_get_drvdata(dev);
+
+	v[0] = tm->tm_sec;
+	v[1] = tm->tm_min;
+	v[2] = tm->tm_hour;
+	v[3] = tm->tm_mday;
+	v[4] = tm->tm_mon + 1;
+	v[5] = tm->tm_year - 100;
+
+	return da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v);
+}
+
+static int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	int ret;
+	struct rtc_time *tm = &alrm->time;
+	struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+	ret = da9052_read_alarm(rtc->da9052, tm);
+
+	if (ret)
+		return ret;
+
+	alrm->enabled = da9052_rtc_get_alarm_status(rtc->da9052);
+
+	return 0;
+}
+
+static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	int ret;
+	struct rtc_time *tm = &alrm->time;
+	struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+	ret = da9052_rtc_enable_alarm(rtc->da9052, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = da9052_set_alarm(rtc->da9052, tm);
+	if (ret)
+		return ret;
+
+	ret = da9052_rtc_enable_alarm(rtc->da9052, 1);
+
+	return ret;
+}
+
+static int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct da9052_rtc *rtc = dev_get_drvdata(dev);
+
+	return da9052_rtc_enable_alarm(rtc->da9052, enabled);
+}
+
+static const struct rtc_class_ops da9052_rtc_ops = {
+	.read_time	= da9052_rtc_read_time,
+	.set_time	= da9052_rtc_set_time,
+	.read_alarm	= da9052_rtc_read_alarm,
+	.set_alarm	= da9052_rtc_set_alarm,
+	.alarm_irq_enable = da9052_rtc_alarm_irq_enable,
+};
+
+static int __devinit da9052_rtc_probe(struct platform_device *pdev)
+{
+	struct da9052_rtc *rtc;
+	int ret;
+
+	rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL);
+	if (!rtc)
+		return -ENOMEM;
+
+	rtc->da9052 = dev_get_drvdata(pdev->dev.parent);
+	platform_set_drvdata(pdev, rtc);
+	rtc->irq = platform_get_irq_byname(pdev, "ALM");
+	ret = request_threaded_irq(rtc->irq, NULL, da9052_rtc_irq,
+				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				   "ALM", rtc);
+	if (ret != 0) {
+		rtc_err(rtc->da9052, "irq registration failed: %d\n", ret);
+		goto err_mem;
+	}
+
+	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+				       &da9052_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc->rtc)) {
+		ret = PTR_ERR(rtc->rtc);
+		goto err_free_irq;
+	}
+
+	return 0;
+
+err_free_irq:
+	free_irq(rtc->irq, rtc);
+err_mem:
+	devm_kfree(&pdev->dev, rtc);
+	return ret;
+}
+
+static int __devexit da9052_rtc_remove(struct platform_device *pdev)
+{
+	struct da9052_rtc *rtc = pdev->dev.platform_data;
+
+	rtc_device_unregister(rtc->rtc);
+	free_irq(rtc->irq, rtc);
+	platform_set_drvdata(pdev, NULL);
+	devm_kfree(&pdev->dev, rtc);
+
+	return 0;
+}
+
+static struct platform_driver da9052_rtc_driver = {
+	.probe	= da9052_rtc_probe,
+	.remove	= __devexit_p(da9052_rtc_remove),
+	.driver = {
+		.name	= "da9052-rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(da9052_rtc_driver);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:da9052-rtc");
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c
index 755e1fe..14c2109 100644
--- a/drivers/rtc/rtc-davinci.c
+++ b/drivers/rtc/rtc-davinci.c
@@ -542,7 +542,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev)
 	rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
 
 	ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
-			  IRQF_DISABLED, "davinci_rtc", davinci_rtc);
+			  0, "davinci_rtc", davinci_rtc);
 	if (ret < 0) {
 		dev_err(dev, "unable to register davinci RTC interrupt\n");
 		goto fail4;
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index 3a33b1f..686a865 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -814,17 +814,7 @@ static struct spi_driver ds1305_driver = {
 	/* REVISIT add suspend/resume */
 };
 
-static int __init ds1305_init(void)
-{
-	return spi_register_driver(&ds1305_driver);
-}
-module_init(ds1305_init);
-
-static void __exit ds1305_exit(void)
-{
-	spi_unregister_driver(&ds1305_driver);
-}
-module_exit(ds1305_exit);
+module_spi_driver(ds1305_driver);
 
 MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 62b0763..58edcb0 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -938,17 +938,7 @@ static struct i2c_driver ds1307_driver = {
 	.id_table	= ds1307_id,
 };
 
-static int __init ds1307_init(void)
-{
-	return i2c_add_driver(&ds1307_driver);
-}
-module_init(ds1307_init);
-
-static void __exit ds1307_exit(void)
-{
-	i2c_del_driver(&ds1307_driver);
-}
-module_exit(ds1307_exit);
+module_i2c_driver(ds1307_driver);
 
 MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips");
 MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index e6e71de..9663160 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -446,18 +446,7 @@ static struct i2c_driver ds1374_driver = {
 	.id_table = ds1374_id,
 };
 
-static int __init ds1374_init(void)
-{
-	return i2c_add_driver(&ds1374_driver);
-}
-
-static void __exit ds1374_exit(void)
-{
-	i2c_del_driver(&ds1374_driver);
-}
-
-module_init(ds1374_init);
-module_exit(ds1374_exit);
+module_i2c_driver(ds1374_driver);
 
 MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
 MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c
index b038d2c..b0a99e1 100644
--- a/drivers/rtc/rtc-ds1390.c
+++ b/drivers/rtc/rtc-ds1390.c
@@ -175,17 +175,7 @@ static struct spi_driver ds1390_driver = {
 	.remove = __devexit_p(ds1390_remove),
 };
 
-static __init int ds1390_init(void)
-{
-	return spi_register_driver(&ds1390_driver);
-}
-module_init(ds1390_init);
-
-static __exit void ds1390_exit(void)
-{
-	spi_unregister_driver(&ds1390_driver);
-}
-module_exit(ds1390_exit);
+module_spi_driver(ds1390_driver);
 
 MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver");
 MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>");
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 761f36b..1f675f5 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -532,7 +532,7 @@ ds1511_rtc_probe(struct platform_device *pdev)
 	if (pdata->irq > 0) {
 		rtc_read(RTC_CMD1);
 		if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
-			IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) {
+			IRQF_SHARED, pdev->name, pdev) < 0) {
 
 			dev_warn(&pdev->dev, "interrupt not available.\n");
 			pdata->irq = 0;
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 6f0a1b5..6ccedbb 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -320,7 +320,7 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev)
 		writeb(0, ioaddr + RTC_INTERRUPTS);
 		if (devm_request_irq(&pdev->dev, pdata->irq,
 				ds1553_rtc_interrupt,
-				IRQF_DISABLED, pdev->name, pdev) < 0) {
+				0, pdev->name, pdev) < 0) {
 			dev_warn(&pdev->dev, "interrupt not available.\n");
 			pdata->irq = 0;
 		}
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index a319402..7fa67d0 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -202,20 +202,9 @@ static struct i2c_driver ds1672_driver = {
 	.id_table = ds1672_id,
 };
 
-static int __init ds1672_init(void)
-{
-	return i2c_add_driver(&ds1672_driver);
-}
-
-static void __exit ds1672_exit(void)
-{
-	i2c_del_driver(&ds1672_driver);
-}
+module_i2c_driver(ds1672_driver);
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(ds1672_init);
-module_exit(ds1672_exit);
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 27b7bf6..e194509 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -473,18 +473,7 @@ static struct i2c_driver ds3232_driver = {
 	.id_table = ds3232_id,
 };
 
-static int __init ds3232_init(void)
-{
-	return i2c_add_driver(&ds3232_driver);
-}
-
-static void __exit ds3232_exit(void)
-{
-	i2c_del_driver(&ds3232_driver);
-}
-
-module_init(ds3232_init);
-module_exit(ds3232_exit);
+module_i2c_driver(ds3232_driver);
 
 MODULE_AUTHOR("Srikanth Srinivasan <srikanth.srinivasan@freescale.com>");
 MODULE_DESCRIPTION("Maxim/Dallas DS3232 RTC Driver");
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
index bbd2622..fda7079 100644
--- a/drivers/rtc/rtc-ds3234.c
+++ b/drivers/rtc/rtc-ds3234.c
@@ -173,17 +173,7 @@ static struct spi_driver ds3234_driver = {
 	.remove = __devexit_p(ds3234_remove),
 };
 
-static __init int ds3234_init(void)
-{
-	return spi_register_driver(&ds3234_driver);
-}
-module_init(ds3234_init);
-
-static __exit void ds3234_exit(void)
-{
-	spi_unregister_driver(&ds3234_driver);
-}
-module_exit(ds3234_exit);
+module_spi_driver(ds3234_driver);
 
 MODULE_DESCRIPTION("DS3234 SPI RTC driver");
 MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c
index 8414dea..0104ea7 100644
--- a/drivers/rtc/rtc-em3027.c
+++ b/drivers/rtc/rtc-em3027.c
@@ -144,19 +144,8 @@ static struct i2c_driver em3027_driver = {
 	.id_table = em3027_id,
 };
 
-static int __init em3027_init(void)
-{
-	return i2c_add_driver(&em3027_driver);
-}
-
-static void __exit em3027_exit(void)
-{
-	i2c_del_driver(&em3027_driver);
-}
+module_i2c_driver(em3027_driver);
 
 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
 MODULE_LICENSE("GPL");
-
-module_init(em3027_init);
-module_exit(em3027_exit);
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
index 4cf2e70..86b6ecc 100644
--- a/drivers/rtc/rtc-fm3130.c
+++ b/drivers/rtc/rtc-fm3130.c
@@ -565,17 +565,7 @@ static struct i2c_driver fm3130_driver = {
 	.id_table	= fm3130_id,
 };
 
-static int __init fm3130_init(void)
-{
-	return i2c_add_driver(&fm3130_driver);
-}
-module_init(fm3130_init);
-
-static void __exit fm3130_exit(void)
-{
-	i2c_del_driver(&fm3130_driver);
-}
-module_exit(fm3130_exit);
+module_i2c_driver(fm3130_driver);
 
 MODULE_DESCRIPTION("RTC driver for FM3130");
 MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>");
diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index 6186833..1850104 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -309,18 +309,7 @@ static struct i2c_driver isl12022_driver = {
 	.id_table	= isl12022_id,
 };
 
-static int __init isl12022_init(void)
-{
-	return i2c_add_driver(&isl12022_driver);
-}
-
-static void __exit isl12022_exit(void)
-{
-	i2c_del_driver(&isl12022_driver);
-}
-
-module_init(isl12022_init);
-module_exit(isl12022_exit);
+module_i2c_driver(isl12022_driver);
 
 MODULE_AUTHOR("roman.fietze@telemotive.de");
 MODULE_DESCRIPTION("ISL 12022 RTC driver");
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index da8beb8..dd2aeee 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -710,22 +710,9 @@ static struct i2c_driver isl1208_driver = {
 	.id_table = isl1208_id,
 };
 
-static int __init
-isl1208_init(void)
-{
-	return i2c_add_driver(&isl1208_driver);
-}
-
-static void __exit
-isl1208_exit(void)
-{
-	i2c_del_driver(&isl1208_driver);
-}
+module_i2c_driver(isl1208_driver);
 
 MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
 MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(isl1208_init);
-module_exit(isl1208_exit);
diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c
index ecc1713..63c7218 100644
--- a/drivers/rtc/rtc-lpc32xx.c
+++ b/drivers/rtc/rtc-lpc32xx.c
@@ -287,7 +287,7 @@ static int __devinit lpc32xx_rtc_probe(struct platform_device *pdev)
 	if (rtc->irq >= 0) {
 		if (devm_request_irq(&pdev->dev, rtc->irq,
 				     lpc32xx_rtc_alarm_interrupt,
-				     IRQF_DISABLED, pdev->name, rtc) < 0) {
+				     0, pdev->name, rtc) < 0) {
 			dev_warn(&pdev->dev, "Can't request interrupt.\n");
 			rtc->irq = -1;
 		} else {
diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c
new file mode 100644
index 0000000..7305986
--- /dev/null
+++ b/drivers/rtc/rtc-ls1x.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2011 Zhao Zhang <zhzhl555@gmail.com>
+ *
+ * Derived from driver/rtc/rtc-au1xxx.c
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <asm/mach-loongson1/loongson1.h>
+
+#define LS1X_RTC_REG_OFFSET	(LS1X_RTC_BASE + 0x20)
+#define LS1X_RTC_REGS(x) \
+		((void __iomem *)KSEG1ADDR(LS1X_RTC_REG_OFFSET + (x)))
+
+/*RTC programmable counters 0 and 1*/
+#define SYS_COUNTER_CNTRL		(LS1X_RTC_REGS(0x20))
+#define SYS_CNTRL_ERS			(1 << 23)
+#define SYS_CNTRL_RTS			(1 << 20)
+#define SYS_CNTRL_RM2			(1 << 19)
+#define SYS_CNTRL_RM1			(1 << 18)
+#define SYS_CNTRL_RM0			(1 << 17)
+#define SYS_CNTRL_RS			(1 << 16)
+#define SYS_CNTRL_BP			(1 << 14)
+#define SYS_CNTRL_REN			(1 << 13)
+#define SYS_CNTRL_BRT			(1 << 12)
+#define SYS_CNTRL_TEN			(1 << 11)
+#define SYS_CNTRL_BTT			(1 << 10)
+#define SYS_CNTRL_E0			(1 << 8)
+#define SYS_CNTRL_ETS			(1 << 7)
+#define SYS_CNTRL_32S			(1 << 5)
+#define SYS_CNTRL_TTS			(1 << 4)
+#define SYS_CNTRL_TM2			(1 << 3)
+#define SYS_CNTRL_TM1			(1 << 2)
+#define SYS_CNTRL_TM0			(1 << 1)
+#define SYS_CNTRL_TS			(1 << 0)
+
+/* Programmable Counter 0 Registers */
+#define SYS_TOYTRIM		(LS1X_RTC_REGS(0))
+#define SYS_TOYWRITE0		(LS1X_RTC_REGS(4))
+#define SYS_TOYWRITE1		(LS1X_RTC_REGS(8))
+#define SYS_TOYREAD0		(LS1X_RTC_REGS(0xC))
+#define SYS_TOYREAD1		(LS1X_RTC_REGS(0x10))
+#define SYS_TOYMATCH0		(LS1X_RTC_REGS(0x14))
+#define SYS_TOYMATCH1		(LS1X_RTC_REGS(0x18))
+#define SYS_TOYMATCH2		(LS1X_RTC_REGS(0x1C))
+
+/* Programmable Counter 1 Registers */
+#define SYS_RTCTRIM		(LS1X_RTC_REGS(0x40))
+#define SYS_RTCWRITE0		(LS1X_RTC_REGS(0x44))
+#define SYS_RTCREAD0		(LS1X_RTC_REGS(0x48))
+#define SYS_RTCMATCH0		(LS1X_RTC_REGS(0x4C))
+#define SYS_RTCMATCH1		(LS1X_RTC_REGS(0x50))
+#define SYS_RTCMATCH2		(LS1X_RTC_REGS(0x54))
+
+#define LS1X_SEC_OFFSET		(4)
+#define LS1X_MIN_OFFSET		(10)
+#define LS1X_HOUR_OFFSET	(16)
+#define LS1X_DAY_OFFSET		(21)
+#define LS1X_MONTH_OFFSET	(26)
+
+
+#define LS1X_SEC_MASK		(0x3f)
+#define LS1X_MIN_MASK		(0x3f)
+#define LS1X_HOUR_MASK		(0x1f)
+#define LS1X_DAY_MASK		(0x1f)
+#define LS1X_MONTH_MASK		(0x3f)
+#define LS1X_YEAR_MASK		(0xffffffff)
+
+#define ls1x_get_sec(t)		(((t) >> LS1X_SEC_OFFSET) & LS1X_SEC_MASK)
+#define ls1x_get_min(t)		(((t) >> LS1X_MIN_OFFSET) & LS1X_MIN_MASK)
+#define ls1x_get_hour(t)	(((t) >> LS1X_HOUR_OFFSET) & LS1X_HOUR_MASK)
+#define ls1x_get_day(t)		(((t) >> LS1X_DAY_OFFSET) & LS1X_DAY_MASK)
+#define ls1x_get_month(t)	(((t) >> LS1X_MONTH_OFFSET) & LS1X_MONTH_MASK)
+
+#define RTC_CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
+
+static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm)
+{
+	unsigned long v, t;
+
+	v = readl(SYS_TOYREAD0);
+	t = readl(SYS_TOYREAD1);
+
+	memset(rtm, 0, sizeof(struct rtc_time));
+	t  = mktime((t & LS1X_YEAR_MASK), ls1x_get_month(v),
+			ls1x_get_day(v), ls1x_get_hour(v),
+			ls1x_get_min(v), ls1x_get_sec(v));
+	rtc_time_to_tm(t, rtm);
+
+	return rtc_valid_tm(rtm);
+}
+
+static int ls1x_rtc_set_time(struct device *dev, struct  rtc_time *rtm)
+{
+	unsigned long v, t, c;
+	int ret = -ETIMEDOUT;
+
+	v = ((rtm->tm_mon + 1)  << LS1X_MONTH_OFFSET)
+		| (rtm->tm_mday << LS1X_DAY_OFFSET)
+		| (rtm->tm_hour << LS1X_HOUR_OFFSET)
+		| (rtm->tm_min  << LS1X_MIN_OFFSET)
+		| (rtm->tm_sec  << LS1X_SEC_OFFSET);
+
+	writel(v, SYS_TOYWRITE0);
+	c = 0x10000;
+	/* add timeout check counter, for more safe */
+	while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c)
+		usleep_range(1000, 3000);
+
+	if (!c) {
+		dev_err(dev, "set time timeout!\n");
+		goto err;
+	}
+
+	t = rtm->tm_year + 1900;
+	writel(t, SYS_TOYWRITE1);
+	c = 0x10000;
+	while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TS) && --c)
+		usleep_range(1000, 3000);
+
+	if (!c) {
+		dev_err(dev, "set time timeout!\n");
+		goto err;
+	}
+	return 0;
+err:
+	return ret;
+}
+
+static struct rtc_class_ops  ls1x_rtc_ops = {
+	.read_time	= ls1x_rtc_read_time,
+	.set_time	= ls1x_rtc_set_time,
+};
+
+static int __devinit ls1x_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtcdev;
+	unsigned long v;
+	int ret;
+
+	v = readl(SYS_COUNTER_CNTRL);
+	if (!(v & RTC_CNTR_OK)) {
+		dev_err(&pdev->dev, "rtc counters not working\n");
+		ret = -ENODEV;
+		goto err;
+	}
+	ret = -ETIMEDOUT;
+	/* set to 1 HZ if needed */
+	if (readl(SYS_TOYTRIM) != 32767) {
+		v = 0x100000;
+		while ((readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS) && --v)
+			usleep_range(1000, 3000);
+
+		if (!v) {
+			dev_err(&pdev->dev, "time out\n");
+			goto err;
+		}
+		writel(32767, SYS_TOYTRIM);
+	}
+	/* this loop coundn't be endless */
+	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_TTS)
+		usleep_range(1000, 3000);
+
+	rtcdev = rtc_device_register("ls1x-rtc", &pdev->dev,
+					&ls1x_rtc_ops , THIS_MODULE);
+	if (IS_ERR(rtcdev)) {
+		ret = PTR_ERR(rtcdev);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, rtcdev);
+	return 0;
+err:
+	return ret;
+}
+
+static int __devexit ls1x_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *rtcdev = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(rtcdev);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver  ls1x_rtc_driver = {
+	.driver		= {
+		.name	= "ls1x-rtc",
+		.owner	= THIS_MODULE,
+	},
+	.remove		= __devexit_p(ls1x_rtc_remove),
+	.probe		= ls1x_rtc_probe,
+};
+
+module_platform_driver(ls1x_rtc_driver);
+
+MODULE_AUTHOR("zhao zhang <zhzhl555@gmail.com>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 64aedd8..4e0f84a 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -900,20 +900,9 @@ static struct i2c_driver m41t80_driver = {
 	.id_table = m41t80_id,
 };
 
-static int __init m41t80_rtc_init(void)
-{
-	return i2c_add_driver(&m41t80_driver);
-}
-
-static void __exit m41t80_rtc_exit(void)
-{
-	i2c_del_driver(&m41t80_driver);
-}
+module_i2c_driver(m41t80_driver);
 
 MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
 MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(m41t80_rtc_init);
-module_exit(m41t80_rtc_exit);
diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c
index ef71132..10f1c29 100644
--- a/drivers/rtc/rtc-m41t93.c
+++ b/drivers/rtc/rtc-m41t93.c
@@ -206,17 +206,7 @@ static struct spi_driver m41t93_driver = {
 	.remove = __devexit_p(m41t93_remove),
 };
 
-static __init int m41t93_init(void)
-{
-	return spi_register_driver(&m41t93_driver);
-}
-module_init(m41t93_init);
-
-static __exit void m41t93_exit(void)
-{
-	spi_unregister_driver(&m41t93_driver);
-}
-module_exit(m41t93_exit);
+module_spi_driver(m41t93_driver);
 
 MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
 MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC");
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c
index 2a4721f..6e78193 100644
--- a/drivers/rtc/rtc-m41t94.c
+++ b/drivers/rtc/rtc-m41t94.c
@@ -153,19 +153,7 @@ static struct spi_driver m41t94_driver = {
 	.remove = __devexit_p(m41t94_remove),
 };
 
-static __init int m41t94_init(void)
-{
-	return spi_register_driver(&m41t94_driver);
-}
-
-module_init(m41t94_init);
-
-static __exit void m41t94_exit(void)
-{
-	spi_unregister_driver(&m41t94_driver);
-}
-
-module_exit(m41t94_exit);
+module_spi_driver(m41t94_driver);
 
 MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>");
 MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC");
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
index 486142c..a00e332 100644
--- a/drivers/rtc/rtc-max6900.c
+++ b/drivers/rtc/rtc-max6900.c
@@ -261,20 +261,9 @@ static struct i2c_driver max6900_driver = {
 	.id_table = max6900_id,
 };
 
-static int __init max6900_init(void)
-{
-	return i2c_add_driver(&max6900_driver);
-}
-
-static void __exit max6900_exit(void)
-{
-	i2c_del_driver(&max6900_driver);
-}
+module_i2c_driver(max6900_driver);
 
 MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
 MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(max6900_init);
-module_exit(max6900_exit);
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 1f6b3cc..36c74d2 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -160,17 +160,7 @@ static struct spi_driver max6902_driver = {
 	.remove = __devexit_p(max6902_remove),
 };
 
-static __init int max6902_init(void)
-{
-	return spi_register_driver(&max6902_driver);
-}
-module_init(max6902_init);
-
-static __exit void max6902_exit(void)
-{
-	spi_unregister_driver(&max6902_driver);
-}
-module_exit(max6902_exit);
+module_spi_driver(max6902_driver);
 
 MODULE_DESCRIPTION ("max6902 spi RTC driver");
 MODULE_AUTHOR ("Raphael Assenat");
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
index 2d71943..1459055 100644
--- a/drivers/rtc/rtc-max8925.c
+++ b/drivers/rtc/rtc-max8925.c
@@ -193,10 +193,17 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	ret = max8925_reg_read(info->rtc, MAX8925_RTC_IRQ_MASK);
 	if (ret < 0)
 		goto out;
-	if ((ret & ALARM0_IRQ) == 0)
-		alrm->enabled = 1;
-	else
+	if (ret & ALARM0_IRQ) {
 		alrm->enabled = 0;
+	} else {
+		ret = max8925_reg_read(info->rtc, MAX8925_ALARM0_CNTL);
+		if (ret < 0)
+			goto out;
+		if (!ret)
+			alrm->enabled = 0;
+		else
+			alrm->enabled = 1;
+	}
 	ret = max8925_reg_read(info->rtc, MAX8925_RTC_STATUS);
 	if (ret < 0)
 		goto out;
@@ -204,6 +211,7 @@ static int max8925_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 		alrm->pending = 1;
 	else
 		alrm->pending = 0;
+	return 0;
 out:
 	return ret;
 }
@@ -220,8 +228,11 @@ static int max8925_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	ret = max8925_bulk_write(info->rtc, MAX8925_ALARM0_SEC, TIME_NUM, buf);
 	if (ret < 0)
 		goto out;
-	/* only enable alarm on year/month/day/hour/min/sec */
-	ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
+	if (alrm->enabled)
+		/* only enable alarm on year/month/day/hour/min/sec */
+		ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x77);
+	else
+		ret = max8925_reg_write(info->rtc, MAX8925_ALARM0_CNTL, 0x0);
 	if (ret < 0)
 		goto out;
 out:
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index 9d3cacc..e954a75 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -327,7 +327,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)
 	dev_set_drvdata(&op->dev, rtc);
 
 	rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
-	err = request_irq(rtc->irq, mpc5121_rtc_handler, IRQF_DISABLED,
+	err = request_irq(rtc->irq, mpc5121_rtc_handler, 0,
 						"mpc5121-rtc", &op->dev);
 	if (err) {
 		dev_err(&op->dev, "%s: could not request irq: %i\n",
@@ -337,7 +337,7 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)
 
 	rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0);
 	err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd,
-				IRQF_DISABLED, "mpc5121-rtc_upd", &op->dev);
+				0, "mpc5121-rtc_upd", &op->dev);
 	if (err) {
 		dev_err(&op->dev, "%s: could not request irq: %i\n",
 						__func__, rtc->irq_periodic);
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index 6cd6c72..f51719b 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -366,7 +366,7 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
 
 	if (rtc_irq) {
 		retval = request_irq(rtc_irq, mrst_rtc_irq,
-				IRQF_DISABLED, dev_name(&mrst_rtc.rtc->dev),
+				0, dev_name(&mrst_rtc.rtc->dev),
 				mrst_rtc.rtc);
 		if (retval < 0) {
 			dev_dbg(dev, "IRQ %d is already in use, err %d\n",
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 768e2ed..1300962 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -273,7 +273,7 @@ static int __devinit mv_rtc_probe(struct platform_device *pdev)
 	if (pdata->irq >= 0) {
 		writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
 		if (devm_request_irq(&pdev->dev, pdata->irq, mv_rtc_interrupt,
-				     IRQF_DISABLED | IRQF_SHARED,
+				     IRQF_SHARED,
 				     pdev->name, pdata) < 0) {
 			dev_warn(&pdev->dev, "interrupt not available.\n");
 			pdata->irq = -1;
diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c
index 781068d..b7901098 100644
--- a/drivers/rtc/rtc-nuc900.c
+++ b/drivers/rtc/rtc-nuc900.c
@@ -269,7 +269,7 @@ static int __devinit nuc900_rtc_probe(struct platform_device *pdev)
 
 	nuc900_rtc->irq_num = platform_get_irq(pdev, 0);
 	if (request_irq(nuc900_rtc->irq_num, nuc900_rtc_interrupt,
-				IRQF_DISABLED, "nuc900rtc", nuc900_rtc)) {
+				0, "nuc900rtc", nuc900_rtc)) {
 		dev_err(&pdev->dev, "NUC900 RTC request irq failed\n");
 		err = -EBUSY;
 		goto fail4;
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 7789002..0b614e3 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -348,14 +348,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
 		rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);
 
 	/* handle periodic and alarm irqs */
-	if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
+	if (request_irq(omap_rtc_timer, rtc_irq, 0,
 			dev_name(&rtc->dev), rtc)) {
 		pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
 			pdev->name, omap_rtc_timer);
 		goto fail1;
 	}
 	if ((omap_rtc_timer != omap_rtc_alarm) &&
-		(request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
+		(request_irq(omap_rtc_alarm, rtc_irq, 0,
 			dev_name(&rtc->dev), rtc))) {
 		pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
 			pdev->name, omap_rtc_alarm);
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
index b46c400..8361187 100644
--- a/drivers/rtc/rtc-pcf2123.c
+++ b/drivers/rtc/rtc-pcf2123.c
@@ -346,20 +346,9 @@ static struct spi_driver pcf2123_driver = {
 	.remove	= __devexit_p(pcf2123_remove),
 };
 
-static int __init pcf2123_init(void)
-{
-	return spi_register_driver(&pcf2123_driver);
-}
-
-static void __exit pcf2123_exit(void)
-{
-	spi_unregister_driver(&pcf2123_driver);
-}
+module_spi_driver(pcf2123_driver);
 
 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
 MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(pcf2123_init);
-module_exit(pcf2123_exit);
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 606fdfa..bc0677d 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -252,20 +252,9 @@ static struct i2c_driver pcf8563_driver = {
 	.id_table	= pcf8563_id,
 };
 
-static int __init pcf8563_init(void)
-{
-	return i2c_add_driver(&pcf8563_driver);
-}
-
-static void __exit pcf8563_exit(void)
-{
-	i2c_del_driver(&pcf8563_driver);
-}
+module_i2c_driver(pcf8563_driver);
 
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(pcf8563_init);
-module_exit(pcf8563_exit);
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index 2d201af..019ff35 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -320,18 +320,7 @@ static struct i2c_driver pcf8583_driver = {
 	.id_table	= pcf8583_id,
 };
 
-static __init int pcf8583_init(void)
-{
-	return i2c_add_driver(&pcf8583_driver);
-}
-
-static __exit void pcf8583_exit(void)
-{
-	i2c_del_driver(&pcf8583_driver);
-}
-
-module_init(pcf8583_init);
-module_exit(pcf8583_exit);
+module_i2c_driver(pcf8583_driver);
 
 MODULE_AUTHOR("Russell King");
 MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index 02111fe..a4a1e53 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -123,7 +123,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
 
 	amba_set_drvdata(dev, rtc);
 
-	ret = request_irq(dev->irq[0], pl030_interrupt, IRQF_DISABLED,
+	ret = request_irq(dev->irq[0], pl030_interrupt, 0,
 			  "rtc-pl030", rtc);
 	if (ret)
 		goto err_irq;
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index a952c8d..3a470e2 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -352,7 +352,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
 	}
 
 	if (request_irq(adev->irq[0], pl031_interrupt,
-			IRQF_DISABLED, "rtc-pl031", ldata)) {
+			0, "rtc-pl031", ldata)) {
 		ret = -EIO;
 		goto out_no_irq;
 	}
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 9f1d6bc..d00bd24 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -520,7 +520,7 @@ static int pm8xxx_rtc_suspend(struct device *dev)
 }
 #endif
 
-SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume);
+static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume);
 
 static struct platform_driver pm8xxx_rtc_driver = {
 	.probe		= pm8xxx_rtc_probe,
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c
index fc9f499..0075c8f 100644
--- a/drivers/rtc/rtc-pxa.c
+++ b/drivers/rtc/rtc-pxa.c
@@ -174,14 +174,14 @@ static int pxa_rtc_open(struct device *dev)
 	struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev);
 	int ret;
 
-	ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, IRQF_DISABLED,
+	ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, 0,
 			  "rtc 1Hz", dev);
 	if (ret < 0) {
 		dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz,
 			ret);
 		goto err_irq_1Hz;
 	}
-	ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, IRQF_DISABLED,
+	ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, 0,
 			  "rtc Alrm", dev);
 	if (ret < 0) {
 		dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm,
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c
index 9beba49c..931f95c 100644
--- a/drivers/rtc/rtc-r9701.c
+++ b/drivers/rtc/rtc-r9701.c
@@ -159,17 +159,7 @@ static struct spi_driver r9701_driver = {
 	.remove = __devexit_p(r9701_remove),
 };
 
-static __init int r9701_init(void)
-{
-	return spi_register_driver(&r9701_driver);
-}
-module_init(r9701_init);
-
-static __exit void r9701_exit(void)
-{
-	spi_unregister_driver(&r9701_driver);
-}
-module_exit(r9701_exit);
+module_spi_driver(r9701_driver);
 
 MODULE_DESCRIPTION("r9701 spi RTC driver");
 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index ce2ca85..77074cc 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -235,18 +235,7 @@ static struct spi_driver rs5c348_driver = {
 	.remove	= __devexit_p(rs5c348_remove),
 };
 
-static __init int rs5c348_init(void)
-{
-	return spi_register_driver(&rs5c348_driver);
-}
-
-static __exit void rs5c348_exit(void)
-{
-	spi_unregister_driver(&rs5c348_driver);
-}
-
-module_init(rs5c348_init);
-module_exit(rs5c348_exit);
+module_spi_driver(rs5c348_driver);
 
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index d29f543..fb4842c 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -689,18 +689,7 @@ static struct i2c_driver rs5c372_driver = {
 	.id_table	= rs5c372_id,
 };
 
-static __init int rs5c372_init(void)
-{
-	return i2c_add_driver(&rs5c372_driver);
-}
-
-static __exit void rs5c372_exit(void)
-{
-	i2c_del_driver(&rs5c372_driver);
-}
-
-module_init(rs5c372_init);
-module_exit(rs5c372_exit);
+module_i2c_driver(rs5c372_driver);
 
 MODULE_AUTHOR(
 		"Pavel Mironchik <pmironchik@optifacio.net>, "
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index ea09ff2..0fbe57b 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -436,18 +436,7 @@ static struct i2c_driver rv3029c2_driver = {
 	.id_table = rv3029c2_id,
 };
 
-static int __init rv3029c2_init(void)
-{
-	return i2c_add_driver(&rv3029c2_driver);
-}
-
-static void __exit rv3029c2_exit(void)
-{
-	i2c_del_driver(&rv3029c2_driver);
-}
-
-module_init(rv3029c2_init);
-module_exit(rv3029c2_exit);
+module_i2c_driver(rv3029c2_driver);
 
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c
index fde172f..0de902d 100644
--- a/drivers/rtc/rtc-rx8025.c
+++ b/drivers/rtc/rtc-rx8025.c
@@ -644,19 +644,8 @@ static struct i2c_driver rx8025_driver = {
 	.id_table	= rx8025_id,
 };
 
-static int __init rx8025_init(void)
-{
-	return i2c_add_driver(&rx8025_driver);
-}
-
-static void __exit rx8025_exit(void)
-{
-	i2c_del_driver(&rx8025_driver);
-}
+module_i2c_driver(rx8025_driver);
 
 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
 MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver");
 MODULE_LICENSE("GPL");
-
-module_init(rx8025_init);
-module_exit(rx8025_exit);
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c
index 600b890..d848251 100644
--- a/drivers/rtc/rtc-rx8581.c
+++ b/drivers/rtc/rtc-rx8581.c
@@ -276,20 +276,9 @@ static struct i2c_driver rx8581_driver = {
 	.id_table	= rx8581_id,
 };
 
-static int __init rx8581_init(void)
-{
-	return i2c_add_driver(&rx8581_driver);
-}
-
-static void __exit rx8581_exit(void)
-{
-	i2c_del_driver(&rx8581_driver);
-}
+module_i2c_driver(rx8581_driver);
 
 MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
 MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(rx8581_init);
-module_exit(rx8581_exit);
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index f789e00..c9562ce 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -304,19 +304,8 @@ static struct i2c_driver s35390a_driver = {
 	.id_table	= s35390a_id,
 };
 
-static int __init s35390a_rtc_init(void)
-{
-	return i2c_add_driver(&s35390a_driver);
-}
-
-static void __exit s35390a_rtc_exit(void)
-{
-	i2c_del_driver(&s35390a_driver);
-}
+module_i2c_driver(s35390a_driver);
 
 MODULE_AUTHOR("Byron Bradley <byron.bbradley@gmail.com>");
 MODULE_DESCRIPTION("S35390A RTC driver");
 MODULE_LICENSE("GPL");
-
-module_init(s35390a_rtc_init);
-module_exit(s35390a_rtc_exit);
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index aef40bd..9ccea13 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -35,6 +35,8 @@
 
 enum s3c_cpu_type {
 	TYPE_S3C2410,
+	TYPE_S3C2416,
+	TYPE_S3C2443,
 	TYPE_S3C64XX,
 };
 
@@ -132,6 +134,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
 	unsigned int tmp = 0;
+	int val;
 
 	if (!is_power_of_2(freq))
 		return -EINVAL;
@@ -139,12 +142,22 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
 	clk_enable(rtc_clk);
 	spin_lock_irq(&s3c_rtc_pie_lock);
 
-	if (s3c_rtc_cpu_type == TYPE_S3C2410) {
+	if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
 		tmp = readb(s3c_rtc_base + S3C2410_TICNT);
 		tmp &= S3C2410_TICNT_ENABLE;
 	}
 
-	tmp |= (rtc_dev->max_user_freq / freq)-1;
+	val = (rtc_dev->max_user_freq / freq) - 1;
+
+	if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
+		tmp |= S3C2443_TICNT_PART(val);
+		writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1);
+
+		if (s3c_rtc_cpu_type == TYPE_S3C2416)
+			writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2);
+	} else {
+		tmp |= val;
+	}
 
 	writel(tmp, s3c_rtc_base + S3C2410_TICNT);
 	spin_unlock_irq(&s3c_rtc_pie_lock);
@@ -371,7 +384,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
 		tmp &= ~S3C2410_RTCCON_RTCEN;
 		writew(tmp, base + S3C2410_RTCCON);
 
-		if (s3c_rtc_cpu_type == TYPE_S3C2410) {
+		if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
 			tmp = readb(base + S3C2410_TICNT);
 			tmp &= ~S3C2410_TICNT_ENABLE;
 			writeb(tmp, base + S3C2410_TICNT);
@@ -428,12 +441,27 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
 	return 0;
 }
 
+static const struct of_device_id s3c_rtc_dt_match[];
+
+static inline int s3c_rtc_get_driver_data(struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
+		return match->data;
+	}
+#endif
+	return platform_get_device_id(pdev)->driver_data;
+}
+
 static int __devinit s3c_rtc_probe(struct platform_device *pdev)
 {
 	struct rtc_device *rtc;
 	struct rtc_time rtc_tm;
 	struct resource *res;
 	int ret;
+	int tmp;
 
 	pr_debug("%s: probe=%p\n", __func__, pdev);
 
@@ -508,13 +536,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
 		goto err_nortc;
 	}
 
-#ifdef CONFIG_OF
-	if (pdev->dev.of_node)
-		s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node,
-			"samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410;
-	else
-#endif
-		s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
+	s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev);
 
 	/* Check RTC Time */
 
@@ -533,24 +555,30 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
 		dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
 	}
 
-	if (s3c_rtc_cpu_type == TYPE_S3C64XX)
+	if (s3c_rtc_cpu_type != TYPE_S3C2410)
 		rtc->max_user_freq = 32768;
 	else
 		rtc->max_user_freq = 128;
 
+	if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
+		tmp = readw(s3c_rtc_base + S3C2410_RTCCON);
+		tmp |= S3C2443_RTCCON_TICSEL;
+		writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
+	}
+
 	platform_set_drvdata(pdev, rtc);
 
 	s3c_rtc_setfreq(&pdev->dev, 1);
 
 	ret = request_irq(s3c_rtc_alarmno, s3c_rtc_alarmirq,
-			  IRQF_DISABLED,  "s3c2410-rtc alarm", rtc);
+			  0,  "s3c2410-rtc alarm", rtc);
 	if (ret) {
 		dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_alarmno, ret);
 		goto err_alarm_irq;
 	}
 
 	ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
-			  IRQF_DISABLED,  "s3c2410-rtc tick", rtc);
+			  0,  "s3c2410-rtc tick", rtc);
 	if (ret) {
 		dev_err(&pdev->dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
 		free_irq(s3c_rtc_alarmno, rtc);
@@ -638,8 +666,19 @@ static int s3c_rtc_resume(struct platform_device *pdev)
 
 #ifdef CONFIG_OF
 static const struct of_device_id s3c_rtc_dt_match[] = {
-	{ .compatible = "samsung,s3c2410-rtc" },
-	{ .compatible = "samsung,s3c6410-rtc" },
+	{
+		.compatible = "samsung,s3c2410-rtc"
+		.data = TYPE_S3C2410,
+	}, {
+		.compatible = "samsung,s3c2416-rtc"
+		.data = TYPE_S3C2416,
+	}, {
+		.compatible = "samsung,s3c2443-rtc"
+		.data = TYPE_S3C2443,
+	}, {
+		.compatible = "samsung,s3c6410-rtc"
+		.data = TYPE_S3C64XX,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
@@ -652,6 +691,12 @@ static struct platform_device_id s3c_rtc_driver_ids[] = {
 		.name		= "s3c2410-rtc",
 		.driver_data	= TYPE_S3C2410,
 	}, {
+		.name		= "s3c2416-rtc",
+		.driver_data	= TYPE_S3C2416,
+	}, {
+		.name		= "s3c2443-rtc",
+		.driver_data	= TYPE_S3C2443,
+	}, {
 		.name		= "s3c64xx-rtc",
 		.driver_data	= TYPE_S3C64XX,
 	},
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index cb9a585..eb63aa3 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -160,13 +160,13 @@ static int sa1100_rtc_open(struct device *dev)
 	struct platform_device *plat_dev = to_platform_device(dev);
 	struct rtc_device *rtc = platform_get_drvdata(plat_dev);
 
-	ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
+	ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, 0,
 		"rtc 1Hz", dev);
 	if (ret) {
 		dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
 		goto fail_ui;
 	}
-	ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED,
+	ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, 0,
 		"rtc Alrm", dev);
 	if (ret) {
 		dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 6ac55fd..e55a763 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -666,7 +666,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
 	if (rtc->carry_irq <= 0) {
 		/* register shared periodic/carry/alarm irq */
 		ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
-				  IRQF_DISABLED, "sh-rtc", rtc);
+				  0, "sh-rtc", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request IRQ failed with %d, IRQ %d\n", ret,
@@ -676,7 +676,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
 	} else {
 		/* register periodic/carry/alarm irqs */
 		ret = request_irq(rtc->periodic_irq, sh_rtc_periodic,
-				  IRQF_DISABLED, "sh-rtc period", rtc);
+				  0, "sh-rtc period", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request period IRQ failed with %d, IRQ %d\n",
@@ -685,7 +685,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
 		}
 
 		ret = request_irq(rtc->carry_irq, sh_rtc_interrupt,
-				  IRQF_DISABLED, "sh-rtc carry", rtc);
+				  0, "sh-rtc carry", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request carry IRQ failed with %d, IRQ %d\n",
@@ -695,7 +695,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev)
 		}
 
 		ret = request_irq(rtc->alarm_irq, sh_rtc_alarm,
-				  IRQF_DISABLED, "sh-rtc alarm", rtc);
+				  0, "sh-rtc alarm", rtc);
 		if (unlikely(ret)) {
 			dev_err(&pdev->dev,
 				"request alarm IRQ failed with %d, IRQ %d\n",
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c
index 19a28a6..e38da0d 100644
--- a/drivers/rtc/rtc-spear.c
+++ b/drivers/rtc/rtc-spear.c
@@ -77,9 +77,11 @@
 #define STATUS_FAIL		(LOST_WR_TIME | LOST_WR_DATE)
 
 struct spear_rtc_config {
+	struct rtc_device *rtc;
 	struct clk *clk;
 	spinlock_t lock;
 	void __iomem *ioaddr;
+	unsigned int irq_wake;
 };
 
 static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config)
@@ -149,8 +151,7 @@ static void rtc_wait_not_busy(struct spear_rtc_config *config)
 
 static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
 {
-	struct rtc_device *rtc = (struct rtc_device *)dev_id;
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = dev_id;
 	unsigned long flags, events = 0;
 	unsigned int irq_data;
 
@@ -161,7 +162,7 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
 	if ((irq_data & RTC_INT_MASK)) {
 		spear_rtc_clear_interrupt(config);
 		events = RTC_IRQF | RTC_AF;
-		rtc_update_irq(rtc, 1, events);
+		rtc_update_irq(config->rtc, 1, events);
 		return IRQ_HANDLED;
 	} else
 		return IRQ_NONE;
@@ -203,9 +204,7 @@ static void bcd2tm(struct rtc_time *tm)
  */
 static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = dev_get_drvdata(dev);
 	unsigned int time, date;
 
 	/* we don't report wday/yday/isdst ... */
@@ -234,9 +233,7 @@ static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
  */
 static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = dev_get_drvdata(dev);
 	unsigned int time, date, err = 0;
 
 	if (tm2bcd(tm) < 0)
@@ -266,9 +263,7 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
  */
 static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = dev_get_drvdata(dev);
 	unsigned int time, date;
 
 	rtc_wait_not_busy(config);
@@ -298,9 +293,7 @@ static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
  */
 static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 {
-	struct platform_device *pdev = to_platform_device(dev);
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = dev_get_drvdata(dev);
 	unsigned int time, date, err = 0;
 
 	if (tm2bcd(&alm->time) < 0)
@@ -326,17 +319,42 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 
 	return 0;
 }
+
+static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct spear_rtc_config *config = dev_get_drvdata(dev);
+	int ret = 0;
+
+	spear_rtc_clear_interrupt(config);
+
+	switch (enabled) {
+	case 0:
+		/* alarm off */
+		spear_rtc_disable_interrupt(config);
+		break;
+	case 1:
+		/* alarm on */
+		spear_rtc_enable_interrupt(config);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 static struct rtc_class_ops spear_rtc_ops = {
 	.read_time = spear_rtc_read_time,
 	.set_time = spear_rtc_set_time,
 	.read_alarm = spear_rtc_read_alarm,
 	.set_alarm = spear_rtc_set_alarm,
+	.alarm_irq_enable = spear_alarm_irq_enable,
 };
 
 static int __devinit spear_rtc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	struct rtc_device *rtc;
 	struct spear_rtc_config *config;
 	unsigned int status = 0;
 	int irq;
@@ -376,19 +394,17 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
 	}
 
 	spin_lock_init(&config->lock);
+	platform_set_drvdata(pdev, config);
 
-	rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops,
-			THIS_MODULE);
-	if (IS_ERR(rtc)) {
+	config->rtc = rtc_device_register(pdev->name, &pdev->dev,
+			&spear_rtc_ops, THIS_MODULE);
+	if (IS_ERR(config->rtc)) {
 		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
-				PTR_ERR(rtc));
-		status = PTR_ERR(rtc);
+				PTR_ERR(config->rtc));
+		status = PTR_ERR(config->rtc);
 		goto err_iounmap;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-	dev_set_drvdata(&rtc->dev, config);
-
 	/* alarm irqs */
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -397,7 +413,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
 		goto err_clear_platdata;
 	}
 
-	status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc);
+	status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config);
 	if (status) {
 		dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
 				claimed\n", irq);
@@ -411,8 +427,7 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev)
 
 err_clear_platdata:
 	platform_set_drvdata(pdev, NULL);
-	dev_set_drvdata(&rtc->dev, NULL);
-	rtc_device_unregister(rtc);
+	rtc_device_unregister(config->rtc);
 err_iounmap:
 	iounmap(config->ioaddr);
 err_disable_clock:
@@ -429,8 +444,7 @@ err_release_region:
 
 static int __devexit spear_rtc_remove(struct platform_device *pdev)
 {
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = platform_get_drvdata(pdev);
 	int irq;
 	struct resource *res;
 
@@ -448,8 +462,7 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
 	if (res)
 		release_mem_region(res->start, resource_size(res));
 	platform_set_drvdata(pdev, NULL);
-	dev_set_drvdata(&rtc->dev, NULL);
-	rtc_device_unregister(rtc);
+	rtc_device_unregister(config->rtc);
 
 	return 0;
 }
@@ -458,14 +471,14 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev)
 
 static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = platform_get_drvdata(pdev);
 	int irq;
 
 	irq = platform_get_irq(pdev, 0);
-	if (device_may_wakeup(&pdev->dev))
-		enable_irq_wake(irq);
-	else {
+	if (device_may_wakeup(&pdev->dev)) {
+		if (!enable_irq_wake(irq))
+			config->irq_wake = 1;
+	} else {
 		spear_rtc_disable_interrupt(config);
 		clk_disable(config->clk);
 	}
@@ -475,15 +488,17 @@ static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
 
 static int spear_rtc_resume(struct platform_device *pdev)
 {
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = platform_get_drvdata(pdev);
 	int irq;
 
 	irq = platform_get_irq(pdev, 0);
 
-	if (device_may_wakeup(&pdev->dev))
-		disable_irq_wake(irq);
-	else {
+	if (device_may_wakeup(&pdev->dev)) {
+		if (config->irq_wake) {
+			disable_irq_wake(irq);
+			config->irq_wake = 0;
+		}
+	} else {
 		clk_enable(config->clk);
 		spear_rtc_enable_interrupt(config);
 	}
@@ -498,8 +513,7 @@ static int spear_rtc_resume(struct platform_device *pdev)
 
 static void spear_rtc_shutdown(struct platform_device *pdev)
 {
-	struct rtc_device *rtc = platform_get_drvdata(pdev);
-	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	struct spear_rtc_config *config = platform_get_drvdata(pdev);
 
 	spear_rtc_disable_interrupt(config);
 	clk_disable(config->clk);
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 7621116..279f5cf 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -329,7 +329,7 @@ static int __devinit stk17ta8_rtc_probe(struct platform_device *pdev)
 		writeb(0, ioaddr + RTC_INTERRUPTS);
 		if (devm_request_irq(&pdev->dev, pdata->irq,
 				stk17ta8_rtc_interrupt,
-				IRQF_DISABLED | IRQF_SHARED,
+				IRQF_SHARED,
 				pdev->name, pdev) < 0) {
 			dev_warn(&pdev->dev, "interrupt not available.\n");
 			pdata->irq = 0;
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index d43b4f6..4c2c6df 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -176,6 +176,10 @@ static int set_rtc_irq_bit(unsigned char bit)
 	unsigned char val;
 	int ret;
 
+	/* if the bit is set, return from here */
+	if (rtc_irq_bits & bit)
+		return 0;
+
 	val = rtc_irq_bits | bit;
 	val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
 	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
@@ -193,6 +197,10 @@ static int mask_rtc_irq_bit(unsigned char bit)
 	unsigned char val;
 	int ret;
 
+	/* if the bit is clear, return from here */
+	if (!(rtc_irq_bits & bit))
+		return 0;
+
 	val = rtc_irq_bits & ~bit;
 	ret = twl_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
 	if (ret == 0)
@@ -357,7 +365,7 @@ out:
 
 static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
 {
-	unsigned long events = 0;
+	unsigned long events;
 	int ret = IRQ_NONE;
 	int res;
 	u8 rd_reg;
@@ -372,11 +380,11 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
 	 * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
 	 */
 	if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
-		events |= RTC_IRQF | RTC_AF;
+		events = RTC_IRQF | RTC_AF;
 	else
-		events |= RTC_IRQF | RTC_UF;
+		events = RTC_IRQF | RTC_PF;
 
-	res = twl_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
+	res = twl_rtc_write_u8(BIT_RTC_STATUS_REG_ALARM_M,
 				   REG_RTC_STATUS_REG);
 	if (res)
 		goto out;
@@ -449,19 +457,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
 			REG_INT_MSK_STS_A);
 	}
 
-	/* Check RTC module status, Enable if it is off */
-	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
+	dev_info(&pdev->dev, "Enabling TWL-RTC\n");
+	ret = twl_rtc_write_u8(BIT_RTC_CTRL_REG_STOP_RTC_M, REG_RTC_CTRL_REG);
 	if (ret < 0)
 		goto out1;
 
-	if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
-		dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
-		rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
-		ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
-		if (ret < 0)
-			goto out1;
-	}
-
 	/* init cached IRQ enable bits */
 	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
 	if (ret < 0)
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c
index aac0ffe..a12bfac 100644
--- a/drivers/rtc/rtc-tx4939.c
+++ b/drivers/rtc/rtc-tx4939.c
@@ -266,7 +266,7 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev)
 	spin_lock_init(&pdata->lock);
 	tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP);
 	if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt,
-			     IRQF_DISABLED, pdev->name, &pdev->dev) < 0)
+			     0, pdev->name, &pdev->dev) < 0)
 		return -EBUSY;
 	rtc = rtc_device_register(pdev->name, &pdev->dev,
 				  &tx4939_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index fcbfdda..5f60a7c 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -333,7 +333,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
 		goto err_device_unregister;
 	}
 
-	retval = request_irq(aie_irq, elapsedtime_interrupt, IRQF_DISABLED,
+	retval = request_irq(aie_irq, elapsedtime_interrupt, 0,
 	                     "elapsed_time", pdev);
 	if (retval < 0)
 		goto err_device_unregister;
@@ -342,7 +342,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
 	if (pie_irq <= 0)
 		goto err_free_irq;
 
-	retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
+	retval = request_irq(pie_irq, rtclong1_interrupt, 0,
 		             "rtclong1", pdev);
 	if (retval < 0)
 		goto err_free_irq;
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 8c051d3..403b3d4 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -623,15 +623,7 @@ static struct i2c_driver x1205_driver = {
 	.id_table	= x1205_id,
 };
 
-static int __init x1205_init(void)
-{
-	return i2c_add_driver(&x1205_driver);
-}
-
-static void __exit x1205_exit(void)
-{
-	i2c_del_driver(&x1205_driver);
-}
+module_i2c_driver(x1205_driver);
 
 MODULE_AUTHOR(
 	"Karen Spearel <kas111 at gmail dot com>, "
@@ -639,6 +631,3 @@ MODULE_AUTHOR(
 MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
-
-module_init(x1205_init);
-module_exit(x1205_exit);
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 46784b8..0cea7e9 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -229,7 +229,7 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr)
 }
 
 /* Handle external interruption. */
-static void dasd_ext_handler(unsigned int ext_int_code,
+static void dasd_ext_handler(struct ext_code ext_code,
 			     unsigned int param32, unsigned long param64)
 {
 	struct dasd_ccw_req *cqr, *next;
@@ -239,7 +239,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
 	addr_t ip;
 	int rc;
 
-	switch (ext_int_code >> 24) {
+	switch (ext_code.subcode >> 8) {
 	case DASD_DIAG_CODE_31BIT:
 		ip = (addr_t) param32;
 		break;
@@ -280,7 +280,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
 	cqr->stopclk = get_clock();
 
 	expires = 0;
-	if ((ext_int_code & 0xff0000) == 0) {
+	if ((ext_code.subcode & 0xff) == 0) {
 		cqr->status = DASD_CQR_SUCCESS;
 		/* Start first request on queue if possible -> fast_io. */
 		if (!list_empty(&device->ccw_queue)) {
@@ -296,7 +296,7 @@ static void dasd_ext_handler(unsigned int ext_int_code,
 		cqr->status = DASD_CQR_QUEUED;
 		DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
 			      "request %p was %d (%d retries left)", cqr,
-			      (ext_int_code >> 16) & 0xff, cqr->retries);
+			      ext_code.subcode & 0xff, cqr->retries);
 		dasd_diag_erp(device);
 	}
 
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 934458a..e71a50d 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -87,6 +87,7 @@ struct raw3215_info {
 	struct tty_struct *tty;	      /* pointer to tty structure if present */
 	struct raw3215_req *queued_read; /* pointer to queued read requests */
 	struct raw3215_req *queued_write;/* pointer to queued write requests */
+	struct tasklet_struct tlet;   /* tasklet to invoke tty_wakeup */
 	wait_queue_head_t empty_wait; /* wait queue for flushing */
 	struct timer_list timer;      /* timer for delayed output */
 	int line_pos;		      /* position on the line (for tabs) */
@@ -334,19 +335,23 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
 }
 
 /*
+ * Call tty_wakeup from tasklet context
+ */
+static void raw3215_wakeup(unsigned long data)
+{
+	struct raw3215_info *raw = (struct raw3215_info *) data;
+	tty_wakeup(raw->tty);
+}
+
+/*
  * Try to start the next IO and wake up processes waiting on the tty.
  */
 static void raw3215_next_io(struct raw3215_info *raw)
 {
-	struct tty_struct *tty;
-
 	raw3215_mk_write_req(raw);
 	raw3215_try_io(raw);
-	tty = raw->tty;
-	if (tty != NULL &&
-	    RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
-	    	tty_wakeup(tty);
-	}
+	if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
+		tasklet_schedule(&raw->tlet);
 }
 
 /*
@@ -682,6 +687,7 @@ static int raw3215_probe (struct ccw_device *cdev)
 		return -ENOMEM;
 	}
 	init_waitqueue_head(&raw->empty_wait);
+	tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
 
 	dev_set_drvdata(&cdev->dev, raw);
 	cdev->handler = raw3215_irq;
@@ -901,6 +907,7 @@ static int __init con3215_init(void)
 
 	raw->flags |= RAW3215_FIXED;
 	init_waitqueue_head(&raw->empty_wait);
+	tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
 
 	/* Request the console irq */
 	if (raw3215_startup(raw) != 0) {
@@ -966,6 +973,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
 	tty->closing = 1;
 	/* Shutdown the terminal */
 	raw3215_shutdown(raw);
+	tasklet_kill(&raw->tlet);
 	tty->closing = 0;
 	raw->tty = NULL;
 }
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index eaa7e78..30f29a0 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -393,7 +393,7 @@ __sclp_find_req(u32 sccb)
 /* Handler for external interruption. Perform request post-processing.
  * Prepare read event data request if necessary. Start processing of next
  * request on queue. */
-static void sclp_interrupt_handler(unsigned int ext_int_code,
+static void sclp_interrupt_handler(struct ext_code ext_code,
 				   unsigned int param32, unsigned long param64)
 {
 	struct sclp_req *req;
@@ -818,7 +818,7 @@ EXPORT_SYMBOL(sclp_reactivate);
 
 /* Handler for external interruption used during initialization. Modify
  * request state to done. */
-static void sclp_check_handler(unsigned int ext_int_code,
+static void sclp_check_handler(struct ext_code ext_code,
 			       unsigned int param32, unsigned long param64)
 {
 	u32 finished_sccb;
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 0b54a91..168525a 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -441,9 +441,8 @@ static int sclp_mem_notifier(struct notifier_block *nb,
 	start = arg->start_pfn << PAGE_SHIFT;
 	size = arg->nr_pages << PAGE_SHIFT;
 	mutex_lock(&sclp_mem_mutex);
-	for (id = 0; id <= sclp_max_storage_id; id++)
-		if (!test_bit(id, sclp_storage_ids))
-			sclp_attach_storage(id);
+	for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1)
+		sclp_attach_storage(id);
 	switch (action) {
 	case MEM_ONLINE:
 	case MEM_GOING_OFFLINE:
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index 87fc0ac..69df137 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -15,7 +15,6 @@
 #include <linux/reboot.h>
 #include <linux/atomic.h>
 #include <asm/ptrace.h>
-#include <asm/sigp.h>
 #include <asm/smp.h>
 
 #include "sclp.h"
diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c
index fa733ec..69e6c50 100644
--- a/drivers/s390/char/sclp_sdias.c
+++ b/drivers/s390/char/sclp_sdias.c
@@ -8,6 +8,7 @@
 #define KMSG_COMPONENT "sclp_sdias"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/completion.h>
 #include <linux/sched.h>
 #include <asm/sclp.h>
 #include <asm/debug.h>
@@ -62,15 +63,29 @@ struct sdias_sccb {
 } __attribute__((packed));
 
 static struct sdias_sccb sccb __attribute__((aligned(4096)));
+static struct sdias_evbuf sdias_evbuf;
 
-static int sclp_req_done;
-static wait_queue_head_t sdias_wq;
+static DECLARE_COMPLETION(evbuf_accepted);
+static DECLARE_COMPLETION(evbuf_done);
 static DEFINE_MUTEX(sdias_mutex);
 
+/*
+ * Called by SCLP base when read event data has been completed (async mode only)
+ */
+static void sclp_sdias_receiver_fn(struct evbuf_header *evbuf)
+{
+	memcpy(&sdias_evbuf, evbuf,
+	       min_t(unsigned long, sizeof(sdias_evbuf), evbuf->length));
+	complete(&evbuf_done);
+	TRACE("sclp_sdias_receiver_fn done\n");
+}
+
+/*
+ * Called by SCLP base when sdias event has been accepted
+ */
 static void sdias_callback(struct sclp_req *request, void *data)
 {
-	sclp_req_done = 1;
-	wake_up(&sdias_wq); /* Inform caller, that request is complete */
+	complete(&evbuf_accepted);
 	TRACE("callback done\n");
 }
 
@@ -80,7 +95,6 @@ static int sdias_sclp_send(struct sclp_req *req)
 	int rc;
 
 	for (retries = SDIAS_RETRIES; retries; retries--) {
-		sclp_req_done = 0;
 		TRACE("add request\n");
 		rc = sclp_add_request(req);
 		if (rc) {
@@ -91,16 +105,31 @@ static int sdias_sclp_send(struct sclp_req *req)
 			continue;
 		}
 		/* initiated, wait for completion of service call */
-		wait_event(sdias_wq, (sclp_req_done == 1));
+		wait_for_completion(&evbuf_accepted);
 		if (req->status == SCLP_REQ_FAILED) {
 			TRACE("sclp request failed\n");
-			rc = -EIO;
 			continue;
 		}
+		/* if not accepted, retry */
+		if (!(sccb.evbuf.hdr.flags & 0x80)) {
+			TRACE("sclp request failed: flags=%x\n",
+			      sccb.evbuf.hdr.flags);
+			continue;
+		}
+		/*
+		 * for the sync interface the response is in the initial sccb
+		 */
+		if (!sclp_sdias_register.receiver_fn) {
+			memcpy(&sdias_evbuf, &sccb.evbuf, sizeof(sdias_evbuf));
+			TRACE("sync request done\n");
+			return 0;
+		}
+		/* otherwise we wait for completion */
+		wait_for_completion(&evbuf_done);
 		TRACE("request done\n");
-		break;
+		return 0;
 	}
-	return rc;
+	return -EIO;
 }
 
 /*
@@ -140,13 +169,12 @@ int sclp_sdias_blk_count(void)
 		goto out;
 	}
 
-	switch (sccb.evbuf.event_status) {
+	switch (sdias_evbuf.event_status) {
 		case 0:
-			rc = sccb.evbuf.blk_cnt;
+			rc = sdias_evbuf.blk_cnt;
 			break;
 		default:
-			pr_err("SCLP error: %x\n",
-			       sccb.evbuf.event_status);
+			pr_err("SCLP error: %x\n", sdias_evbuf.event_status);
 			rc = -EIO;
 			goto out;
 	}
@@ -211,18 +239,18 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
 		goto out;
 	}
 
-	switch (sccb.evbuf.event_status) {
+	switch (sdias_evbuf.event_status) {
 		case EVSTATE_ALL_STORED:
 			TRACE("all stored\n");
 		case EVSTATE_PART_STORED:
-			TRACE("part stored: %i\n", sccb.evbuf.blk_cnt);
+			TRACE("part stored: %i\n", sdias_evbuf.blk_cnt);
 			break;
 		case EVSTATE_NO_DATA:
 			TRACE("no data\n");
 		default:
 			pr_err("Error from SCLP while copying hsa. "
 			       "Event status = %x\n",
-			       sccb.evbuf.event_status);
+			       sdias_evbuf.event_status);
 			rc = -EIO;
 	}
 out:
@@ -230,19 +258,50 @@ out:
 	return rc;
 }
 
-int __init sclp_sdias_init(void)
+static int __init sclp_sdias_register_check(void)
 {
 	int rc;
 
+	rc = sclp_register(&sclp_sdias_register);
+	if (rc)
+		return rc;
+	if (sclp_sdias_blk_count() == 0) {
+		sclp_unregister(&sclp_sdias_register);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int __init sclp_sdias_init_sync(void)
+{
+	TRACE("Try synchronous mode\n");
+	sclp_sdias_register.receive_mask = 0;
+	sclp_sdias_register.receiver_fn = NULL;
+	return sclp_sdias_register_check();
+}
+
+static int __init sclp_sdias_init_async(void)
+{
+	TRACE("Try asynchronous mode\n");
+	sclp_sdias_register.receive_mask = EVTYP_SDIAS_MASK;
+	sclp_sdias_register.receiver_fn = sclp_sdias_receiver_fn;
+	return sclp_sdias_register_check();
+}
+
+int __init sclp_sdias_init(void)
+{
 	if (ipl_info.type != IPL_TYPE_FCP_DUMP)
 		return 0;
 	sdias_dbf = debug_register("dump_sdias", 4, 1, 4 * sizeof(long));
 	debug_register_view(sdias_dbf, &debug_sprintf_view);
 	debug_set_level(sdias_dbf, 6);
-	rc = sclp_register(&sclp_sdias_register);
-	if (rc)
-		return rc;
-	init_waitqueue_head(&sdias_wq);
+	if (sclp_sdias_init_sync() == 0)
+		goto out;
+	if (sclp_sdias_init_async() == 0)
+		goto out;
+	TRACE("init failed\n");
+	return -ENODEV;
+out:
 	TRACE("init done\n");
 	return 0;
 }
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 1b6d924..3303d66 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -21,7 +21,6 @@
 #include <asm/ipl.h>
 #include <asm/sclp.h>
 #include <asm/setup.h>
-#include <asm/sigp.h>
 #include <asm/uaccess.h>
 #include <asm/debug.h>
 #include <asm/processor.h>
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 4f1989d..5f1dc6f 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -580,7 +580,6 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
 	struct device *dev;
 
 	/* We don't want ccwgroup devices to live longer than their driver. */
-	get_driver(&cdriver->driver);
 	while ((dev = driver_find_device(&cdriver->driver, NULL, NULL,
 					 __ccwgroup_match_all))) {
 		struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
@@ -592,7 +591,6 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)
 		mutex_unlock(&gdev->reg_mutex);
 		put_device(dev);
 	}
-	put_driver(&cdriver->driver);
 	driver_unregister(&cdriver->driver);
 }
 EXPORT_SYMBOL(ccwgroup_driver_unregister);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index dc67c39..a49c46c 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -601,8 +601,6 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
 	struct pt_regs *old_regs;
 
 	old_regs = set_irq_regs(regs);
-	s390_idle_check(regs, S390_lowcore.int_clock,
-			S390_lowcore.async_enter_timer);
 	irq_enter();
 	__this_cpu_write(s390_idle.nohz_delay, 1);
 	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 4726985..02d0152 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1676,15 +1676,9 @@ struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv,
 				       const char *bus_id)
 {
 	struct device *dev;
-	struct device_driver *drv;
 
-	drv = get_driver(&cdrv->driver);
-	if (!drv)
-		return NULL;
-
-	dev = driver_find_device(drv, NULL, (void *)bus_id,
+	dev = driver_find_device(&cdrv->driver, NULL, (void *)bus_id,
 				 __ccwdev_check_busid);
-	put_driver(drv);
 
 	return dev ? to_ccwdev(dev) : NULL;
 }
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 7bc1955..d74e9ae 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -380,15 +380,13 @@ static void hotplug_devices(struct work_struct *dummy)
 /*
  * we emulate the request_irq behaviour on top of s390 extints
  */
-static void kvm_extint_handler(unsigned int ext_int_code,
+static void kvm_extint_handler(struct ext_code ext_code,
 			       unsigned int param32, unsigned long param64)
 {
 	struct virtqueue *vq;
-	u16 subcode;
 	u32 param;
 
-	subcode = ext_int_code >> 16;
-	if ((subcode & 0xff00) != VIRTIO_SUBCODE_64)
+	if ((ext_code.subcode & 0xff00) != VIRTIO_SUBCODE_64)
 		return;
 	kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++;
 
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 4abc79d..ec7921b 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -906,6 +906,7 @@ void qeth_prepare_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, char);
 struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *);
 int qeth_mdio_read(struct net_device *, int, int);
 int qeth_snmp_command(struct qeth_card *, char __user *);
+int qeth_query_oat_command(struct qeth_card *, char __user *);
 struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *, __u32, __u32);
 int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
 					unsigned long);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 9c3f38d..cbb1018 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -26,6 +26,7 @@
 #include <asm/ebcdic.h>
 #include <asm/io.h>
 #include <asm/sysinfo.h>
+#include <asm/compat.h>
 
 #include "qeth_core.h"
 
@@ -677,6 +678,7 @@ void qeth_release_buffer(struct qeth_channel *channel,
 	iob->callback = qeth_send_control_data_cb;
 	iob->rc = 0;
 	spin_unlock_irqrestore(&channel->iob_lock, flags);
+	wake_up(&channel->wait_q);
 }
 EXPORT_SYMBOL_GPL(qeth_release_buffer);
 
@@ -4402,6 +4404,104 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata)
 }
 EXPORT_SYMBOL_GPL(qeth_snmp_command);
 
+static int qeth_setadpparms_query_oat_cb(struct qeth_card *card,
+		struct qeth_reply *reply, unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+	struct qeth_qoat_priv *priv;
+	char *resdata;
+	int resdatalen;
+
+	QETH_CARD_TEXT(card, 3, "qoatcb");
+
+	cmd = (struct qeth_ipa_cmd *)data;
+	priv = (struct qeth_qoat_priv *)reply->param;
+	resdatalen = cmd->data.setadapterparms.hdr.cmdlength;
+	resdata = (char *)data + 28;
+
+	if (resdatalen > (priv->buffer_len - priv->response_len)) {
+		cmd->hdr.return_code = IPA_RC_FFFF;
+		return 0;
+	}
+
+	memcpy((priv->buffer + priv->response_len), resdata,
+		resdatalen);
+	priv->response_len += resdatalen;
+
+	if (cmd->data.setadapterparms.hdr.seq_no <
+	    cmd->data.setadapterparms.hdr.used_total)
+		return 1;
+	return 0;
+}
+
+int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
+{
+	int rc = 0;
+	struct qeth_cmd_buffer *iob;
+	struct qeth_ipa_cmd *cmd;
+	struct qeth_query_oat *oat_req;
+	struct qeth_query_oat_data oat_data;
+	struct qeth_qoat_priv priv;
+	void __user *tmp;
+
+	QETH_CARD_TEXT(card, 3, "qoatcmd");
+
+	if (!qeth_adp_supported(card, IPA_SETADP_QUERY_OAT)) {
+		rc = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (copy_from_user(&oat_data, udata,
+	    sizeof(struct qeth_query_oat_data))) {
+			rc = -EFAULT;
+			goto out;
+	}
+
+	priv.buffer_len = oat_data.buffer_len;
+	priv.response_len = 0;
+	priv.buffer =  kzalloc(oat_data.buffer_len, GFP_KERNEL);
+	if (!priv.buffer) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT,
+				   sizeof(struct qeth_ipacmd_setadpparms_hdr) +
+				   sizeof(struct qeth_query_oat));
+	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+	oat_req = &cmd->data.setadapterparms.data.query_oat;
+	oat_req->subcmd_code = oat_data.command;
+
+	rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_query_oat_cb,
+			       &priv);
+	if (!rc) {
+		if (is_compat_task())
+			tmp = compat_ptr(oat_data.ptr);
+		else
+			tmp = (void __user *)(unsigned long)oat_data.ptr;
+
+		if (copy_to_user(tmp, priv.buffer,
+		    priv.response_len)) {
+			rc = -EFAULT;
+			goto out_free;
+		}
+
+		oat_data.response_len = priv.response_len;
+
+		if (copy_to_user(udata, &oat_data,
+		    sizeof(struct qeth_query_oat_data)))
+			rc = -EFAULT;
+	} else
+		if (rc == IPA_RC_FFFF)
+			rc = -EFAULT;
+
+out_free:
+	kfree(priv.buffer);
+out:
+	return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_query_oat_command);
+
 static inline int qeth_get_qdio_q_format(struct qeth_card *card)
 {
 	switch (card->info.type) {
diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h
index e5a9d1c..578e19a 100644
--- a/drivers/s390/net/qeth_core_mpc.h
+++ b/drivers/s390/net/qeth_core_mpc.h
@@ -249,6 +249,7 @@ enum qeth_ipa_setadp_cmd {
 	IPA_SETADP_SET_PROMISC_MODE		= 0x00000800L,
 	IPA_SETADP_SET_DIAG_ASSIST		= 0x00002000L,
 	IPA_SETADP_SET_ACCESS_CONTROL		= 0x00010000L,
+	IPA_SETADP_QUERY_OAT			= 0x00080000L,
 };
 enum qeth_ipa_mac_ops {
 	CHANGE_ADDR_READ_MAC		= 0,
@@ -398,6 +399,17 @@ struct qeth_set_access_ctrl {
 	__u32 subcmd_code;
 } __attribute__((packed));
 
+struct qeth_query_oat {
+	__u32 subcmd_code;
+	__u8 reserved[12];
+} __packed;
+
+struct qeth_qoat_priv {
+	__u32 buffer_len;
+	__u32 response_len;
+	char *buffer;
+};
+
 struct qeth_ipacmd_setadpparms_hdr {
 	__u32 supp_hw_cmds;
 	__u32 reserved1;
@@ -417,6 +429,7 @@ struct qeth_ipacmd_setadpparms {
 		struct qeth_change_addr change_addr;
 		struct qeth_snmp_cmd snmp;
 		struct qeth_set_access_ctrl set_access_ctrl;
+		struct qeth_query_oat query_oat;
 		__u32 mode;
 	} data;
 } __attribute__ ((packed));
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index c129671..e5c9cf1 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -75,6 +75,9 @@ static int qeth_l2_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 			mii_data->val_out = qeth_mdio_read(dev,
 				mii_data->phy_id, mii_data->reg_num);
 		break;
+	case SIOC_QETH_QUERY_OAT:
+		rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data);
+		break;
 	default:
 		rc = -EOPNOTSUPP;
 	}
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 9648e4e..73bf888 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -28,6 +28,8 @@
 
 #include <net/ip.h>
 #include <net/arp.h>
+#include <net/route.h>
+#include <net/ip6_fib.h>
 #include <net/ip6_checksum.h>
 #include <net/iucv/af_iucv.h>
 
@@ -2743,6 +2745,9 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 							mii_data->phy_id,
 							mii_data->reg_num);
 		break;
+	case SIOC_QETH_QUERY_OAT:
+		rc = qeth_query_oat_command(card, rq->ifr_ifru.ifru_data);
+		break;
 	default:
 		rc = -EOPNOTSUPP;
 	}
@@ -2832,7 +2837,6 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card,
 static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
 		struct sk_buff *skb, int ipv, int cast_type)
 {
-	struct neighbour *n = NULL;
 	struct dst_entry *dst;
 
 	memset(hdr, 0, sizeof(struct qeth_hdr));
@@ -2855,33 +2859,29 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
 
 	rcu_read_lock();
 	dst = skb_dst(skb);
-	if (dst)
-		n = dst_get_neighbour_noref(dst);
 	if (ipv == 4) {
+		struct rtable *rt = (struct rtable *) dst;
+		__be32 *pkey = &ip_hdr(skb)->daddr;
+
+		if (rt->rt_gateway)
+			pkey = &rt->rt_gateway;
+
 		/* IPv4 */
 		hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type);
 		memset(hdr->hdr.l3.dest_addr, 0, 12);
-		if (n) {
-			*((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
-			    *((u32 *) n->primary_key);
-		} else {
-			/* fill in destination address used in ip header */
-			*((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
-							ip_hdr(skb)->daddr;
-		}
+		*((__be32 *) (&hdr->hdr.l3.dest_addr[12])) = *pkey;
 	} else if (ipv == 6) {
+		struct rt6_info *rt = (struct rt6_info *) dst;
+		struct in6_addr *pkey = &ipv6_hdr(skb)->daddr;
+
+		if (!ipv6_addr_any(&rt->rt6i_gateway))
+			pkey = &rt->rt6i_gateway;
+
 		/* IPv6 */
 		hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type);
 		if (card->info.type == QETH_CARD_TYPE_IQD)
 			hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
-		if (n) {
-			memcpy(hdr->hdr.l3.dest_addr,
-			       n->primary_key, 16);
-		} else {
-			/* fill in destination address used in ip header */
-			memcpy(hdr->hdr.l3.dest_addr,
-			       &ipv6_hdr(skb)->daddr, 16);
-		}
+		memcpy(hdr->hdr.l3.dest_addr, pkey, 16);
 	} else {
 		/* passthrough */
 		if ((skb->dev->type == ARPHRD_IEEE802_TR) &&
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
index 4d2ea40..32515a2 100644
--- a/drivers/s390/net/smsgiucv_app.c
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -168,7 +168,7 @@ static int __init smsgiucv_app_init(void)
 	rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT);
 	if (rc) {
 		kfree(smsg_app_dev);
-		goto fail_put_driver;
+		goto fail;
 	}
 	smsg_app_dev->bus = &iucv_bus;
 	smsg_app_dev->parent = iucv_root;
@@ -177,7 +177,7 @@ static int __init smsgiucv_app_init(void)
 	rc = device_register(smsg_app_dev);
 	if (rc) {
 		put_device(smsg_app_dev);
-		goto fail_put_driver;
+		goto fail;
 	}
 
 	/* convert sender to uppercase characters */
@@ -191,12 +191,11 @@ static int __init smsgiucv_app_init(void)
 	rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
 	if (rc) {
 		device_unregister(smsg_app_dev);
-		goto fail_put_driver;
+		goto fail;
 	}
 
 	rc = 0;
-fail_put_driver:
-	put_driver(smsgiucv_drv);
+fail:
 	return rc;
 }
 module_init(smsgiucv_app_init);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 16570aa..5b213b1 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -662,6 +662,13 @@ config VMWARE_PVSCSI
 	  To compile this driver as a module, choose M here: the
 	  module will be called vmw_pvscsi.
 
+config HYPERV_STORAGE
+	tristate "Microsoft Hyper-V virtual storage driver"
+	depends on SCSI && HYPERV
+	default HYPERV
+	help
+	  Select this option to enable the Hyper-V virtual storage driver.
+
 config LIBFC
 	tristate "LibFC module"
 	select SCSI_FC_ATTRS
@@ -1897,6 +1904,14 @@ config SCSI_BFA_FC
 	  To compile this driver as a module, choose M here. The module will
 	  be called bfa.
 
+config SCSI_VIRTIO
+	tristate "virtio-scsi support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	help
+          This is the virtual HBA driver for virtio.  If the kernel will
+          be used in a virtual machine, say Y or M.
+
+
 endif # SCSI_LOWLEVEL
 
 source "drivers/scsi/pcmcia/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 2b88749..ad24e06 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -141,7 +141,9 @@ obj-$(CONFIG_SCSI_CXGB4_ISCSI)	+= libiscsi.o libiscsi_tcp.o cxgbi/
 obj-$(CONFIG_SCSI_BNX2_ISCSI)	+= libiscsi.o bnx2i/
 obj-$(CONFIG_BE2ISCSI)		+= libiscsi.o be2iscsi/
 obj-$(CONFIG_SCSI_PMCRAID)	+= pmcraid.o
+obj-$(CONFIG_SCSI_VIRTIO)	+= virtio_scsi.o
 obj-$(CONFIG_VMWARE_PVSCSI)	+= vmw_pvscsi.o
+obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
 
 obj-$(CONFIG_ARM)		+= arm/
 
@@ -170,6 +172,8 @@ scsi_mod-$(CONFIG_SCSI_PROC_FS)	+= scsi_proc.o
 scsi_mod-y			+= scsi_trace.o
 scsi_mod-$(CONFIG_PM)		+= scsi_pm.o
 
+hv_storvsc-y			:= storvsc_drv.o
+
 scsi_tgt-y			+= scsi_tgt_lib.o scsi_tgt_if.o
 
 sd_mod-objs	:= sd.o
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 409f580..5255166 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -151,7 +151,11 @@ int aac_msi;
 int aac_commit = -1;
 int startup_timeout = 180;
 int aif_timeout = 120;
+int aac_sync_mode;  /* Only Sync. transfer - disabled */
 
+module_param(aac_sync_mode, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(aac_sync_mode, "Force sync. transfer mode"
+	" 0=off, 1=on");
 module_param(nondasd, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices."
 	" 0=off, 1=on");
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index ffb5878..3fcf627 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
  *----------------------------------------------------------------------------*/
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 28000
+# define AAC_DRIVER_BUILD 28900
 # define AAC_DRIVER_BRANCH "-ms"
 #endif
 #define MAXIMUM_NUM_CONTAINERS	32
@@ -756,8 +756,16 @@ struct src_mu_registers {
 
 struct src_registers {
 	struct src_mu_registers MUnit;	/* 00h - c7h */
-	__le32 reserved1[130790];	/* c8h - 7fc5fh */
-	struct src_inbound IndexRegs;	/* 7fc60h */
+	union {
+		struct {
+			__le32 reserved1[130790];	/* c8h - 7fc5fh */
+			struct src_inbound IndexRegs;	/* 7fc60h */
+		} tupelo;
+		struct {
+			__le32 reserved1[974];		/* c8h - fffh */
+			struct src_inbound IndexRegs;	/* 1000h */
+		} denali;
+	} u;
 };
 
 #define src_readb(AEP, CSR)		readb(&((AEP)->regs.src.bar0->CSR))
@@ -999,6 +1007,10 @@ struct aac_bus_info_response {
 #define AAC_OPT_NEW_COMM		cpu_to_le32(1<<17)
 #define AAC_OPT_NEW_COMM_64		cpu_to_le32(1<<18)
 #define AAC_OPT_NEW_COMM_TYPE1		cpu_to_le32(1<<28)
+#define AAC_OPT_NEW_COMM_TYPE2		cpu_to_le32(1<<29)
+#define AAC_OPT_NEW_COMM_TYPE3		cpu_to_le32(1<<30)
+#define AAC_OPT_NEW_COMM_TYPE4		cpu_to_le32(1<<31)
+
 
 struct aac_dev
 {
@@ -1076,6 +1088,8 @@ struct aac_dev
 #	define AAC_MIN_FOOTPRINT_SIZE 8192
 #	define AAC_MIN_SRC_BAR0_SIZE 0x400000
 #	define AAC_MIN_SRC_BAR1_SIZE 0x800
+#	define AAC_MIN_SRCV_BAR0_SIZE 0x100000
+#	define AAC_MIN_SRCV_BAR1_SIZE 0x400
 #endif
 	union
 	{
@@ -1116,7 +1130,10 @@ struct aac_dev
 	u8			msi;
 	int			management_fib_count;
 	spinlock_t		manage_lock;
-
+	spinlock_t		sync_lock;
+	int			sync_mode;
+	struct fib		*sync_fib;
+	struct list_head	sync_fib_list;
 };
 
 #define aac_adapter_interrupt(dev) \
@@ -1163,6 +1180,7 @@ struct aac_dev
 
 #define FIB_CONTEXT_FLAG_TIMED_OUT		(0x00000001)
 #define FIB_CONTEXT_FLAG			(0x00000002)
+#define FIB_CONTEXT_FLAG_WAIT			(0x00000004)
 
 /*
  *	Define the command values
@@ -1970,6 +1988,7 @@ int aac_rkt_init(struct aac_dev *dev);
 int aac_nark_init(struct aac_dev *dev);
 int aac_sa_init(struct aac_dev *dev);
 int aac_src_init(struct aac_dev *dev);
+int aac_srcv_init(struct aac_dev *dev);
 int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify);
 unsigned int aac_response_normal(struct aac_queue * q);
 unsigned int aac_command_normal(struct aac_queue * q);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 7ac8fdb..a35f54e 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -325,12 +325,14 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 {
 	u32 status[5];
 	struct Scsi_Host * host = dev->scsi_host_ptr;
+	extern int aac_sync_mode;
 
 	/*
 	 *	Check the preferred comm settings, defaults from template.
 	 */
 	dev->management_fib_count = 0;
 	spin_lock_init(&dev->manage_lock);
+	spin_lock_init(&dev->sync_lock);
 	dev->max_fib_size = sizeof(struct hw_fib);
 	dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
 		- sizeof(struct aac_fibhdr)
@@ -344,13 +346,21 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 	 		(status[0] == 0x00000001)) {
 		if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
 			dev->raw_io_64 = 1;
-		if (dev->a_ops.adapter_comm) {
-			if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1)) {
-				dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
-				dev->raw_io_interface = 1;
-			} else if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM)) {
+		dev->sync_mode = aac_sync_mode;
+		if (dev->a_ops.adapter_comm &&
+			(status[1] & le32_to_cpu(AAC_OPT_NEW_COMM))) {
 				dev->comm_interface = AAC_COMM_MESSAGE;
 				dev->raw_io_interface = 1;
+			if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1))) {
+				/* driver supports TYPE1 (Tupelo) */
+				dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
+			} else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE4)) ||
+				  (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE3)) ||
+				  (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE2))) {
+					/* driver doesn't support TYPE2 (Series7), TYPE3 and TYPE4 */
+					/* switch to sync. mode */
+					dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
+					dev->sync_mode = 1;
 			}
 		}
 		if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
@@ -455,6 +465,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 	}
 		
 	INIT_LIST_HEAD(&dev->fib_list);
+	INIT_LIST_HEAD(&dev->sync_fib_list);
 
 	return dev;
 }
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index e5f2d7d..4b32ca4 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -416,6 +416,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 	unsigned long flags = 0;
 	unsigned long qflags;
 	unsigned long mflags = 0;
+	unsigned long sflags = 0;
 
 
 	if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
@@ -512,6 +513,31 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 		spin_lock_irqsave(&fibptr->event_lock, flags);
 	}
 
+	if (dev->sync_mode) {
+		if (wait)
+			spin_unlock_irqrestore(&fibptr->event_lock, flags);
+		spin_lock_irqsave(&dev->sync_lock, sflags);
+		if (dev->sync_fib) {
+			list_add_tail(&fibptr->fiblink, &dev->sync_fib_list);
+			spin_unlock_irqrestore(&dev->sync_lock, sflags);
+		} else {
+			dev->sync_fib = fibptr;
+			spin_unlock_irqrestore(&dev->sync_lock, sflags);
+			aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
+				(u32)fibptr->hw_fib_pa, 0, 0, 0, 0, 0,
+				NULL, NULL, NULL, NULL, NULL);
+		}
+		if (wait) {
+			fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;
+			if (down_interruptible(&fibptr->event_wait)) {
+				fibptr->flags &= ~FIB_CONTEXT_FLAG_WAIT;
+				return -EFAULT;
+			}
+			return 0;
+		}
+		return -EINPROGRESS;
+	}
+
 	if (aac_adapter_deliver(fibptr) != 0) {
 		printk(KERN_ERR "aac_fib_send: returned -EBUSY\n");
 		if (wait) {
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 705e13e..0d279c44 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -56,7 +56,7 @@
 
 #include "aacraid.h"
 
-#define AAC_DRIVER_VERSION		"1.1-7"
+#define AAC_DRIVER_VERSION		"1.2-0"
 #ifndef AAC_DRIVER_BRANCH
 #define AAC_DRIVER_BRANCH		""
 #endif
@@ -162,7 +162,10 @@ static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
 	{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
 	{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
 	{ 0x9005, 0x0288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 61 }, /* Adaptec NEMER/ARK Catch All */
-	{ 0x9005, 0x028b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 62 }, /* Adaptec PMC Catch All */
+	{ 0x9005, 0x028b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 62 }, /* Adaptec PMC Series 6 (Tupelo) */
+	{ 0x9005, 0x028c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 63 }, /* Adaptec PMC Series 7 (Denali) */
+	{ 0x9005, 0x028d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 64 }, /* Adaptec PMC Series 8 */
+	{ 0x9005, 0x028f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 65 }, /* Adaptec PMC Series 9 */
 	{ 0,}
 };
 MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@ -238,7 +241,10 @@ static struct aac_driver_ident aac_drivers[] = {
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "RAID            ", 2 }, /* Adaptec Catch All */
 	{ aac_rkt_init, "aacraid", "ADAPTEC ", "RAID            ", 2 }, /* Adaptec Rocket Catch All */
 	{ aac_nark_init, "aacraid", "ADAPTEC ", "RAID           ", 2 }, /* Adaptec NEMER/ARK Catch All */
-	{ aac_src_init, "aacraid", "ADAPTEC ", "RAID            ", 2 } /* Adaptec PMC Catch All */
+	{ aac_src_init, "aacraid", "ADAPTEC ", "RAID            ", 2 }, /* Adaptec PMC Series 6 (Tupelo) */
+	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2 }, /* Adaptec PMC Series 7 (Denali) */
+	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2 }, /* Adaptec PMC Series 8 */
+	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2 } /* Adaptec PMC Series 9 */
 };
 
 /**
@@ -1102,6 +1108,7 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
 	int error = -ENODEV;
 	int unique_id = 0;
 	u64 dmamask;
+	extern int aac_sync_mode;
 
 	list_for_each_entry(aac, &aac_devices, entry) {
 		if (aac->id > unique_id)
@@ -1162,6 +1169,21 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
 	if ((*aac_drivers[index].init)(aac))
 		goto out_unmap;
 
+	if (aac->sync_mode) {
+		if (aac_sync_mode)
+			printk(KERN_INFO "%s%d: Sync. mode enforced "
+				"by driver parameter. This will cause "
+				"a significant performance decrease!\n",
+				aac->name,
+				aac->id);
+		else
+			printk(KERN_INFO "%s%d: Async. mode not supported "
+				"by current driver, sync. mode enforced."
+				"\nPlease update driver to get full performance.\n",
+				aac->name,
+				aac->id);
+	}
+
 	/*
 	 *	Start any kernel threads needed
 	 */
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index ce530f1..b029c7c 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -643,6 +643,7 @@ int _aac_rx_init(struct aac_dev *dev)
 	if (aac_init_adapter(dev) == NULL)
 		goto error_iounmap;
 	aac_adapter_comm(dev, dev->comm_interface);
+	dev->sync_mode = 0;	/* sync. mode not supported */
 	dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
 	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
 			IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index e5d4457..beb5336 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -385,6 +385,7 @@ int aac_sa_init(struct aac_dev *dev)
 
 	if(aac_init_adapter(dev) == NULL)
 		goto error_irq;
+	dev->sync_mode = 0;	/* sync. mode not supported */
 	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
 			IRQF_SHARED|IRQF_DISABLED,
 			"aacraid", (void *)dev ) < 0) {
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 957595a..2bee515 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -96,6 +96,38 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
 			our_interrupt = 1;
 			/* handle AIF */
 			aac_intr_normal(dev, 0, 2, 0, NULL);
+		} else if (bellbits_shifted & OUTBOUNDDOORBELL_0) {
+			unsigned long sflags;
+			struct list_head *entry;
+			int send_it = 0;
+
+			if (dev->sync_fib) {
+				our_interrupt = 1;
+				if (dev->sync_fib->callback)
+					dev->sync_fib->callback(dev->sync_fib->callback_data,
+						dev->sync_fib);
+				spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
+				if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
+					dev->management_fib_count--;
+					up(&dev->sync_fib->event_wait);
+				}
+				spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
+				spin_lock_irqsave(&dev->sync_lock, sflags);
+				if (!list_empty(&dev->sync_fib_list)) {
+					entry = dev->sync_fib_list.next;
+					dev->sync_fib = list_entry(entry, struct fib, fiblink);
+					list_del(entry);
+					send_it = 1;
+				} else {
+					dev->sync_fib = NULL;
+				}
+				spin_unlock_irqrestore(&dev->sync_lock, sflags);
+				if (send_it) {
+					aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
+						(u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
+						NULL, NULL, NULL, NULL, NULL);
+				}
+			}
 		}
 	}
 
@@ -177,56 +209,63 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
 	 */
 	src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
 
-	ok = 0;
-	start = jiffies;
+	if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) {
+		ok = 0;
+		start = jiffies;
 
-	/*
-	 *	Wait up to 30 seconds
-	 */
-	while (time_before(jiffies, start+30*HZ)) {
-		/* Delay 5 microseconds to let Mon960 get info. */
-		udelay(5);
-
-		/* Mon960 will set doorbell0 bit
-		 * when it has completed the command
+		/*
+		 *	Wait up to 5 minutes
 		 */
-		if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
-			/* Clear the doorbell */
-			src_writel(dev,
-				MUnit.ODR_C,
-				OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
-			ok = 1;
-			break;
+		while (time_before(jiffies, start+300*HZ)) {
+			udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
+			/*
+			 *	Mon960 will set doorbell0 bit when it has completed the command.
+			 */
+			if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
+				/*
+				 *	Clear the doorbell.
+				 */
+				src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
+				ok = 1;
+				break;
+			}
+			/*
+			 *	Yield the processor in case we are slow
+			 */
+			msleep(1);
 		}
-
-		 /* Yield the processor in case we are slow */
-		msleep(1);
-	}
-	if (unlikely(ok != 1)) {
-		 /* Restore interrupt mask even though we timed out */
-		aac_adapter_enable_int(dev);
-		return -ETIMEDOUT;
+		if (unlikely(ok != 1)) {
+			/*
+			 *	Restore interrupt mask even though we timed out
+			 */
+			aac_adapter_enable_int(dev);
+			return -ETIMEDOUT;
+		}
+		/*
+		 *	Pull the synch status from Mailbox 0.
+		 */
+		if (status)
+			*status = readl(&dev->IndexRegs->Mailbox[0]);
+		if (r1)
+			*r1 = readl(&dev->IndexRegs->Mailbox[1]);
+		if (r2)
+			*r2 = readl(&dev->IndexRegs->Mailbox[2]);
+		if (r3)
+			*r3 = readl(&dev->IndexRegs->Mailbox[3]);
+		if (r4)
+			*r4 = readl(&dev->IndexRegs->Mailbox[4]);
+
+		/*
+		 *	Clear the synch command doorbell.
+		 */
+		src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 	}
 
-	 /* Pull the synch status from Mailbox 0 */
-	if (status)
-		*status = readl(&dev->IndexRegs->Mailbox[0]);
-	if (r1)
-		*r1 = readl(&dev->IndexRegs->Mailbox[1]);
-	if (r2)
-		*r2 = readl(&dev->IndexRegs->Mailbox[2]);
-	if (r3)
-		*r3 = readl(&dev->IndexRegs->Mailbox[3]);
-	if (r4)
-		*r4 = readl(&dev->IndexRegs->Mailbox[4]);
-
-	 /* Clear the synch command doorbell */
-	src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
-
-	 /* Restore interrupt mask */
+	/*
+	 *	Restore interrupt mask
+	 */
 	aac_adapter_enable_int(dev);
 	return 0;
-
 }
 
 /**
@@ -386,9 +425,7 @@ static int aac_src_ioremap(struct aac_dev *dev, u32 size)
 {
 	if (!size) {
 		iounmap(dev->regs.src.bar0);
-		dev->regs.src.bar0 = NULL;
-		iounmap(dev->base);
-		dev->base = NULL;
+		dev->base = dev->regs.src.bar0 = NULL;
 		return 0;
 	}
 	dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
@@ -404,7 +441,27 @@ static int aac_src_ioremap(struct aac_dev *dev, u32 size)
 		return -1;
 	}
 	dev->IndexRegs = &((struct src_registers __iomem *)
-		dev->base)->IndexRegs;
+		dev->base)->u.tupelo.IndexRegs;
+	return 0;
+}
+
+/**
+ *  aac_srcv_ioremap
+ *	@size: mapping resize request
+ *
+ */
+static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
+{
+	if (!size) {
+		iounmap(dev->regs.src.bar0);
+		dev->base = dev->regs.src.bar0 = NULL;
+		return 0;
+	}
+	dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, size);
+	if (dev->base == NULL)
+		return -1;
+	dev->IndexRegs = &((struct src_registers __iomem *)
+		dev->base)->u.denali.IndexRegs;
 	return 0;
 }
 
@@ -419,7 +476,7 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
 		bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
 			0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
 			if (bled || (var != 0x00000001))
-				bled = -EINVAL;
+				return -EINVAL;
 		if (dev->supplement_adapter_info.SupportedOptions2 &
 			AAC_OPTION_DOORBELL_RESET) {
 			src_writel(dev, MUnit.IDR, reset_mask);
@@ -579,15 +636,149 @@ int aac_src_init(struct aac_dev *dev)
 	dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
 
 	aac_adapter_enable_int(dev);
+
+	if (!dev->sync_mode) {
+		/*
+		 * Tell the adapter that all is configured, and it can
+		 * start accepting requests
+		 */
+		aac_src_start_adapter(dev);
+	}
+	return 0;
+
+error_iounmap:
+
+	return -1;
+}
+
+/**
+ *  aac_srcv_init	-	initialize an SRCv card
+ *  @dev: device to configure
+ *
+ */
+
+int aac_srcv_init(struct aac_dev *dev)
+{
+	unsigned long start;
+	unsigned long status;
+	int restart = 0;
+	int instance = dev->id;
+	const char *name = dev->name;
+
+	dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
+	dev->a_ops.adapter_comm = aac_src_select_comm;
+
+	dev->base_size = AAC_MIN_SRCV_BAR0_SIZE;
+	if (aac_adapter_ioremap(dev, dev->base_size)) {
+		printk(KERN_WARNING "%s: unable to map adapter.\n", name);
+		goto error_iounmap;
+	}
+
+	/* Failure to reset here is an option ... */
+	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
+	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
+	if ((aac_reset_devices || reset_devices) &&
+		!aac_src_restart_adapter(dev, 0))
+		++restart;
 	/*
-	 *	Tell the adapter that all is configured, and it can
-	 * start accepting requests
+	 *	Check to see if the board panic'd while booting.
 	 */
-	aac_src_start_adapter(dev);
+	status = src_readl(dev, MUnit.OMR);
+	if (status & KERNEL_PANIC) {
+		if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
+			goto error_iounmap;
+		++restart;
+	}
+	/*
+	 *	Check to see if the board failed any self tests.
+	 */
+	status = src_readl(dev, MUnit.OMR);
+	if (status & SELF_TEST_FAILED) {
+		printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
+		goto error_iounmap;
+	}
+	/*
+	 *	Check to see if the monitor panic'd while booting.
+	 */
+	if (status & MONITOR_PANIC) {
+		printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
+		goto error_iounmap;
+	}
+	start = jiffies;
+	/*
+	 *	Wait for the adapter to be up and running. Wait up to 3 minutes
+	 */
+	while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING)) {
+		if ((restart &&
+		  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
+		  time_after(jiffies, start+HZ*startup_timeout)) {
+			printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
+					dev->name, instance, status);
+			goto error_iounmap;
+		}
+		if (!restart &&
+		  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
+		  time_after(jiffies, start + HZ *
+		  ((startup_timeout > 60)
+		    ? (startup_timeout - 60)
+		    : (startup_timeout / 2))))) {
+			if (likely(!aac_src_restart_adapter(dev, aac_src_check_health(dev))))
+				start = jiffies;
+			++restart;
+		}
+		msleep(1);
+	}
+	if (restart && aac_commit)
+		aac_commit = 1;
+	/*
+	 *	Fill in the common function dispatch table.
+	 */
+	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
+	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
+	dev->a_ops.adapter_notify = aac_src_notify_adapter;
+	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
+	dev->a_ops.adapter_check_health = aac_src_check_health;
+	dev->a_ops.adapter_restart = aac_src_restart_adapter;
+
+	/*
+	 *	First clear out all interrupts.  Then enable the one's that we
+	 *	can handle.
+	 */
+	aac_adapter_comm(dev, AAC_COMM_MESSAGE);
+	aac_adapter_disable_int(dev);
+	src_writel(dev, MUnit.ODR_C, 0xffffffff);
+	aac_adapter_enable_int(dev);
 
+	if (aac_init_adapter(dev) == NULL)
+		goto error_iounmap;
+	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
+		goto error_iounmap;
+	dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
+	if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
+		IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
+		if (dev->msi)
+			pci_disable_msi(dev->pdev);
+		printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+			name, instance);
+		goto error_iounmap;
+	}
+	dev->dbg_base = dev->scsi_host_ptr->base;
+	dev->dbg_base_mapped = dev->base;
+	dev->dbg_size = dev->base_size;
+
+	aac_adapter_enable_int(dev);
+
+	if (!dev->sync_mode) {
+		/*
+		 * Tell the adapter that all is configured, and it can
+		 * start accepting requests
+		 */
+		aac_src_start_adapter(dev);
+	}
 	return 0;
 
 error_iounmap:
 
 	return -1;
 }
+
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 5f8617d..25417d0 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -8993,7 +8993,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
 					printk("Invalid Command IU Field\n");
 					break;
 				case SIU_PFC_TMF_NOT_SUPPORTED:
-					printk("TMF not supportd\n");
+					printk("TMF not supported\n");
 					break;
 				case SIU_PFC_TMF_FAILED:
 					printk("TMF failed\n");
@@ -9113,7 +9113,7 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
 		break;
 	}
 	case SCSI_STATUS_OK:
-		printk("%s: Interrupted for staus of 0???\n",
+		printk("%s: Interrupted for status of 0???\n",
 		       ahd_name(ahd));
 		/* FALLTHROUGH */
 	default:
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index dc28b0a..10172a3 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -1049,7 +1049,7 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat)
 		ahc_set_scsi_status(scb, hscb->shared_data.status.scsi_status);
 		switch (hscb->shared_data.status.scsi_status) {
 		case SCSI_STATUS_OK:
-			printk("%s: Interrupted for staus of 0???\n",
+			printk("%s: Interrupted for status of 0???\n",
 			       ahc_name(ahc));
 			break;
 		case SCSI_STATUS_CMD_TERMINATED:
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h
index 2863a9d..66cda66 100644
--- a/drivers/scsi/aic94xx/aic94xx.h
+++ b/drivers/scsi/aic94xx/aic94xx.h
@@ -80,6 +80,8 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id);
 
 int  asd_execute_task(struct sas_task *, int num, gfp_t gfp_flags);
 
+void asd_set_dmamode(struct domain_device *dev);
+
 /* ---------- TMFs ---------- */
 int  asd_abort_task(struct sas_task *);
 int  asd_abort_task_set(struct domain_device *, u8 *lun);
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c
index 2e2ddec..64136c56 100644
--- a/drivers/scsi/aic94xx/aic94xx_dev.c
+++ b/drivers/scsi/aic94xx/aic94xx_dev.c
@@ -109,26 +109,37 @@ static int asd_init_sata_tag_ddb(struct domain_device *dev)
 	return 0;
 }
 
-static int asd_init_sata(struct domain_device *dev)
+void asd_set_dmamode(struct domain_device *dev)
 {
 	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
+	struct ata_device *ata_dev = sas_to_ata_dev(dev);
 	int ddb = (int) (unsigned long) dev->lldd_dev;
 	u32 qdepth = 0;
-	int res = 0;
 
-	asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF);
-	if ((dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM_PORT) &&
-	    dev->sata_dev.identify_device &&
-	    dev->sata_dev.identify_device[10] != 0) {
-		u16 w75 = le16_to_cpu(dev->sata_dev.identify_device[75]);
-		u16 w76 = le16_to_cpu(dev->sata_dev.identify_device[76]);
-
-		if (w76 & 0x100) /* NCQ? */
-			qdepth = (w75 & 0x1F) + 1;
+	if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM_PORT) {
+		if (ata_id_has_ncq(ata_dev->id))
+			qdepth = ata_id_queue_depth(ata_dev->id);
 		asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK,
 					(1ULL<<qdepth)-1);
 		asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth);
 	}
+
+	if (qdepth > 0)
+		if (asd_init_sata_tag_ddb(dev) != 0) {
+			unsigned long flags;
+
+			spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
+			ata_dev->flags |= ATA_DFLAG_NCQ_OFF;
+			spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
+		}
+}
+
+static int asd_init_sata(struct domain_device *dev)
+{
+	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
+	int ddb = (int) (unsigned long) dev->lldd_dev;
+
+	asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF);
 	if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM ||
 	    dev->dev_type == SATA_PM_PORT) {
 		struct dev_to_host_fis *fis = (struct dev_to_host_fis *)
@@ -136,9 +147,8 @@ static int asd_init_sata(struct domain_device *dev)
 		asd_ddbsite_write_byte(asd_ha, ddb, SATA_STATUS, fis->status);
 	}
 	asd_ddbsite_write_word(asd_ha, ddb, NCQ_DATA_SCB_PTR, 0xFFFF);
-	if (qdepth > 0)
-		res = asd_init_sata_tag_ddb(dev);
-	return res;
+
+	return 0;
 }
 
 static int asd_init_target_ddb(struct domain_device *dev)
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index d5ff142..ff80552 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -68,7 +68,6 @@ static struct scsi_host_template aic94xx_sht = {
 	.queuecommand		= sas_queuecommand,
 	.target_alloc		= sas_target_alloc,
 	.slave_configure	= sas_slave_configure,
-	.slave_destroy		= sas_slave_destroy,
 	.scan_finished		= asd_scan_finished,
 	.scan_start		= asd_scan_start,
 	.change_queue_depth	= sas_change_queue_depth,
@@ -82,7 +81,6 @@ static struct scsi_host_template aic94xx_sht = {
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_device_reset_handler	= sas_eh_device_reset_handler,
 	.eh_bus_reset_handler	= sas_eh_bus_reset_handler,
-	.slave_alloc		= sas_slave_alloc,
 	.target_destroy		= sas_target_destroy,
 	.ioctl			= sas_ioctl,
 };
@@ -972,7 +970,7 @@ static int asd_scan_finished(struct Scsi_Host *shost, unsigned long time)
 	if (time < HZ)
 		return 0;
 	/* Wait for discovery to finish */
-	scsi_flush_work(shost);
+	sas_drain_work(SHOST_TO_SAS_HA(shost));
 	return 1;
 }
 
@@ -1010,6 +1008,8 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
 	.lldd_clear_nexus_ha	= asd_clear_nexus_ha,
 
 	.lldd_control_phy	= asd_control_phy,
+
+	.lldd_ata_set_dmamode	= asd_set_dmamode,
 };
 
 static const struct pci_device_id aic94xx_pci_table[] __devinitdata = {
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 0add73b..cf90409 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -181,7 +181,7 @@ static int asd_clear_nexus_I_T(struct domain_device *dev,
 int asd_I_T_nexus_reset(struct domain_device *dev)
 {
 	int res, tmp_res, i;
-	struct sas_phy *phy = sas_find_local_phy(dev);
+	struct sas_phy *phy = sas_get_local_phy(dev);
 	/* Standard mandates link reset for ATA  (type 0) and
 	 * hard reset for SSP (type 1) */
 	int reset_type = (dev->dev_type == SATA_DEV ||
@@ -192,7 +192,7 @@ int asd_I_T_nexus_reset(struct domain_device *dev)
 	ASD_DPRINTK("sending %s reset to %s\n",
 		    reset_type ? "hard" : "soft", dev_name(&phy->dev));
 	res = sas_phy_reset(phy, reset_type);
-	if (res == TMF_RESP_FUNC_COMPLETE) {
+	if (res == TMF_RESP_FUNC_COMPLETE || res == -ENODEV) {
 		/* wait for the maximum settle time */
 		msleep(500);
 		/* clear all outstanding commands (keep nexus suspended) */
@@ -201,7 +201,7 @@ int asd_I_T_nexus_reset(struct domain_device *dev)
 	for (i = 0 ; i < 3; i++) {
 		tmp_res = asd_clear_nexus_I_T(dev, NEXUS_PHASE_RESUME);
 		if (tmp_res == TC_RESUME)
-			return res;
+			goto out;
 		msleep(500);
 	}
 
@@ -211,7 +211,10 @@ int asd_I_T_nexus_reset(struct domain_device *dev)
 	dev_printk(KERN_ERR, &phy->dev,
 		   "Failed to resume nexus after reset 0x%x\n", tmp_res);
 
-	return TMF_RESP_FUNC_FAILED;
+	res = TMF_RESP_FUNC_FAILED;
+ out:
+	sas_put_local_phy(phy);
+	return res;
 }
 
 static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun)
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f980600..2fe9e90 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1736,7 +1736,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
 						(uint32_t ) cmd->cmnd[8];
 						/* 4 bytes: Areca io control code */
 	sg = scsi_sglist(cmd);
-	buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
+	buffer = kmap_atomic(sg_page(sg)) + sg->offset;
 	if (scsi_sg_count(cmd) > 1) {
 		retvalue = ARCMSR_MESSAGE_FAIL;
 		goto message_out;
@@ -1985,7 +1985,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
 	}
 	message_out:
 	sg = scsi_sglist(cmd);
-	kunmap_atomic(buffer - sg->offset, KM_IRQ0);
+	kunmap_atomic(buffer - sg->offset);
 	return retvalue;
 }
 
@@ -2035,11 +2035,11 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
 		strncpy(&inqdata[32], "R001", 4); /* Product Revision */
 
 		sg = scsi_sglist(cmd);
-		buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
+		buffer = kmap_atomic(sg_page(sg)) + sg->offset;
 
 		memcpy(buffer, inqdata, sizeof(inqdata));
 		sg = scsi_sglist(cmd);
-		kunmap_atomic(buffer - sg->offset, KM_IRQ0);
+		kunmap_atomic(buffer - sg->offset);
 
 		cmd->scsi_done(cmd);
 	}
diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
index a750aa7..2a28b4a 100644
--- a/drivers/scsi/arm/arxescsi.c
+++ b/drivers/scsi/arm/arxescsi.c
@@ -305,7 +305,7 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 	info->base = base;
 
 	info->info.scsi.io_base		= base + 0x2000;
-	info->info.scsi.irq		= NO_IRQ;
+	info->info.scsi.irq		= 0;
 	info->info.scsi.dma		= NO_DMA;
 	info->info.scsi.io_shift	= 5;
 	info->info.ifcfg.clockrate	= 24; /* MHz */
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index e85c40b..6206a66 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2176,7 +2176,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
 	fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
 	fn(info, SCpnt, result);
 
-	if (info->scsi.irq != NO_IRQ) {
+	if (info->scsi.irq) {
 		spin_lock_irqsave(&info->host_lock, flags);
 		if (info->scsi.phase == PHASE_IDLE)
 			fas216_kick(info);
@@ -2276,7 +2276,7 @@ static int fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt,
 	 * We should only be using this if we don't have an interrupt.
 	 * Provide some "incentive" to use the queueing code.
 	 */
-	BUG_ON(info->scsi.irq != NO_IRQ);
+	BUG_ON(info->scsi.irq);
 
 	info->internal_done = 0;
 	fas216_queue_command_lck(SCpnt, fas216_internal_done);
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
index 84b7127..df2e1b3 100644
--- a/drivers/scsi/arm/fas216.h
+++ b/drivers/scsi/arm/fas216.h
@@ -12,10 +12,6 @@
 #ifndef FAS216_H
 #define FAS216_H
 
-#ifndef NO_IRQ
-#define NO_IRQ 255
-#endif
-
 #include <scsi/scsi_eh.h>
 
 #include "queue.h"
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 530de2b..8005c6c 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -3047,8 +3047,7 @@ bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
 	 * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload
 	 * buffer of size bsg_data->payload_len
 	 */
-	bsg_fcpt = (struct bfa_bsg_fcpt_s *)
-		   kzalloc(bsg_data->payload_len, GFP_KERNEL);
+	bsg_fcpt = kzalloc(bsg_data->payload_len, GFP_KERNEL);
 	if (!bsg_fcpt)
 		goto out;
 
@@ -3060,6 +3059,7 @@ bfad_im_bsg_els_ct_request(struct fc_bsg_job *job)
 
 	drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL);
 	if (drv_fcxp == NULL) {
+		kfree(bsg_fcpt);
 		rc = -ENOMEM;
 		goto out;
 	}
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 049ea90..a4953ef 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -62,7 +62,7 @@
 #include "bnx2fc_constants.h"
 
 #define BNX2FC_NAME		"bnx2fc"
-#define BNX2FC_VERSION		"1.0.9"
+#define BNX2FC_VERSION		"1.0.10"
 
 #define PFX			"bnx2fc: "
 
@@ -114,6 +114,8 @@
 #define BNX2FC_HASH_TBL_CHUNK_SIZE	(16 * 1024)
 
 #define BNX2FC_MAX_SEQS			255
+#define BNX2FC_MAX_RETRY_CNT		3
+#define BNX2FC_MAX_RPORT_RETRY_CNT	255
 
 #define BNX2FC_READ			(1 << 1)
 #define BNX2FC_WRITE			(1 << 0)
@@ -121,8 +123,10 @@
 #define BNX2FC_MIN_XID			0
 #define BNX2FC_MAX_XID			\
 			(BNX2FC_MAX_OUTSTANDING_CMNDS + BNX2FC_ELSTM_XIDS - 1)
+#define FCOE_MAX_NUM_XIDS		0x2000
 #define FCOE_MIN_XID			(BNX2FC_MAX_XID + 1)
-#define FCOE_MAX_XID			(FCOE_MIN_XID + 4095)
+#define FCOE_MAX_XID			(FCOE_MIN_XID + FCOE_MAX_NUM_XIDS - 1)
+#define FCOE_XIDS_PER_CPU		(FCOE_MIN_XID + (512 * nr_cpu_ids) - 1)
 #define BNX2FC_MAX_LUN			0xFFFF
 #define BNX2FC_MAX_FCP_TGT		256
 #define BNX2FC_MAX_CMD_LEN		16
diff --git a/drivers/scsi/bnx2fc/bnx2fc_constants.h b/drivers/scsi/bnx2fc/bnx2fc_constants.h
index 399cda0..c12702b 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_constants.h
+++ b/drivers/scsi/bnx2fc/bnx2fc_constants.h
@@ -7,7 +7,7 @@
 
 /* Current FCoE HSI version number composed of two fields (16 bit) */
 /* Implies on a change broken previous HSI */
-#define FCOE_HSI_MAJOR_VERSION (1)
+#define FCOE_HSI_MAJOR_VERSION (2)
 /* Implies on a change which does not broken previous HSI */
 #define FCOE_HSI_MINOR_VERSION (1)
 
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 8c6156a..abd72a0 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu);
 
 #define DRV_MODULE_NAME		"bnx2fc"
 #define DRV_MODULE_VERSION	BNX2FC_VERSION
-#define DRV_MODULE_RELDATE	"Oct 21, 2011"
+#define DRV_MODULE_RELDATE	"Jan 22, 2011"
 
 
 static char version[] __devinitdata =
@@ -322,8 +322,7 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp)
 			return -ENOMEM;
 		}
 		frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
-		cp = kmap_atomic(skb_frag_page(frag), KM_SKB_DATA_SOFTIRQ)
-				+ frag->page_offset;
+		cp = kmap_atomic(skb_frag_page(frag)) + frag->page_offset;
 	} else {
 		cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
 	}
@@ -332,7 +331,7 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp)
 	cp->fcoe_eof = eof;
 	cp->fcoe_crc32 = cpu_to_le32(~crc);
 	if (skb_is_nonlinear(skb)) {
-		kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
+		kunmap_atomic(cp);
 		cp = NULL;
 	}
 
@@ -940,8 +939,14 @@ static int bnx2fc_libfc_config(struct fc_lport *lport)
 
 static int bnx2fc_em_config(struct fc_lport *lport)
 {
+	int max_xid;
+
+	if (nr_cpu_ids <= 2)
+		max_xid = FCOE_XIDS_PER_CPU;
+	else
+		max_xid = FCOE_MAX_XID;
 	if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, FCOE_MIN_XID,
-				FCOE_MAX_XID, NULL)) {
+				max_xid, NULL)) {
 		printk(KERN_ERR PFX "em_config:fc_exch_mgr_alloc failed\n");
 		return -ENOMEM;
 	}
@@ -953,8 +958,8 @@ static int bnx2fc_lport_config(struct fc_lport *lport)
 {
 	lport->link_up = 0;
 	lport->qfull = 0;
-	lport->max_retry_count = 3;
-	lport->max_rport_retry_count = 3;
+	lport->max_retry_count = BNX2FC_MAX_RETRY_CNT;
+	lport->max_rport_retry_count = BNX2FC_MAX_RPORT_RETRY_CNT;
 	lport->e_d_tov = 2 * 1000;
 	lport->r_a_tov = 10 * 1000;
 
@@ -1537,6 +1542,7 @@ static void __bnx2fc_destroy(struct bnx2fc_interface *interface)
 static int bnx2fc_destroy(struct net_device *netdev)
 {
 	struct bnx2fc_interface *interface = NULL;
+	struct workqueue_struct *timer_work_queue;
 	int rc = 0;
 
 	rtnl_lock();
@@ -1549,9 +1555,9 @@ static int bnx2fc_destroy(struct net_device *netdev)
 		goto netdev_err;
 	}
 
-
-	destroy_workqueue(interface->timer_work_queue);
+	timer_work_queue = interface->timer_work_queue;
 	__bnx2fc_destroy(interface);
+	destroy_workqueue(timer_work_queue);
 
 netdev_err:
 	mutex_unlock(&bnx2fc_dev_lock);
@@ -2055,6 +2061,7 @@ if_create_err:
 ifput_err:
 	bnx2fc_net_cleanup(interface);
 	bnx2fc_interface_put(interface);
+	goto mod_err;
 netdev_err:
 	module_put(THIS_MODULE);
 mod_err:
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index 1923a25..afd5709 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -1716,15 +1716,19 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
 
 	/* Tx only */
 	bd_count = bd_tbl->bd_valid;
+	cached_sge = &task->rxwr_only.union_ctx.read_info.sgl_ctx.cached_sge;
 	if (task_type == FCOE_TASK_TYPE_WRITE) {
 		if ((dev_type == TYPE_DISK) && (bd_count == 1)) {
 			struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl;
 
 			task->txwr_only.sgl_ctx.cached_sge.cur_buf_addr.lo =
+			cached_sge->cur_buf_addr.lo =
 					fcoe_bd_tbl->buf_addr_lo;
 			task->txwr_only.sgl_ctx.cached_sge.cur_buf_addr.hi =
+			cached_sge->cur_buf_addr.hi =
 					fcoe_bd_tbl->buf_addr_hi;
 			task->txwr_only.sgl_ctx.cached_sge.cur_buf_rem =
+			cached_sge->cur_buf_rem =
 					fcoe_bd_tbl->buf_len;
 
 			task->txwr_rxrd.const_ctx.init_flags |= 1 <<
@@ -1790,11 +1794,13 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
 	task->rxwr_txrd.var_ctx.rx_id = 0xffff;
 
 	/* Rx Only */
-	cached_sge = &task->rxwr_only.union_ctx.read_info.sgl_ctx.cached_sge;
+	if (task_type != FCOE_TASK_TYPE_READ)
+		return;
+
 	sgl = &task->rxwr_only.union_ctx.read_info.sgl_ctx.sgl;
 	bd_count = bd_tbl->bd_valid;
-	if (task_type == FCOE_TASK_TYPE_READ &&
-	    dev_type == TYPE_DISK) {
+
+	if (dev_type == TYPE_DISK) {
 		if (bd_count == 1) {
 
 			struct fcoe_bd_ctx *fcoe_bd_tbl = bd_tbl->bd_tbl;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 84a78af..e897ce9 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1682,9 +1682,7 @@ void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req,
 
 	memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));
 
-	int_to_scsilun(sc_cmd->device->lun,
-			(struct scsi_lun *) fcp_cmnd->fc_lun);
-
+	int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
 
 	fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
 	memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 1ad0b82..f9d6f41 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1312,14 +1312,18 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba)
 		  ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_EXP_DATASN) |
 		/* EMC */
 		(1ULL << ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_LUN));
-	if (error_mask1)
+	if (error_mask1) {
 		iscsi_init2.error_bit_map[0] = error_mask1;
-	else
+		mask64 &= (u32)(~mask64);
+		mask64 |= error_mask1;
+	} else
 		iscsi_init2.error_bit_map[0] = (u32) mask64;
 
-	if (error_mask2)
+	if (error_mask2) {
 		iscsi_init2.error_bit_map[1] = error_mask2;
-	else
+		mask64 &= 0xffffffff;
+		mask64 |= ((u64)error_mask2 << 32);
+	} else
 		iscsi_init2.error_bit_map[1] = (u32) (mask64 >> 32);
 
 	iscsi_error_mask = mask64;
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index 1a947f1..4927cca 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -49,11 +49,11 @@ module_param(en_tcp_dack, int, 0664);
 MODULE_PARM_DESC(en_tcp_dack, "Enable TCP Delayed ACK");
 
 unsigned int error_mask1 = 0x00;
-module_param(error_mask1, int, 0664);
+module_param(error_mask1, uint, 0664);
 MODULE_PARM_DESC(error_mask1, "Config FW iSCSI Error Mask #1");
 
 unsigned int error_mask2 = 0x00;
-module_param(error_mask2, int, 0664);
+module_param(error_mask2, uint, 0664);
 MODULE_PARM_DESC(error_mask2, "Config FW iSCSI Error Mask #2");
 
 unsigned int sq_size;
@@ -393,8 +393,9 @@ static void bnx2i_percpu_thread_create(unsigned int cpu)
 
 	p = &per_cpu(bnx2i_percpu, cpu);
 
-	thread = kthread_create(bnx2i_percpu_io_thread, (void *)p,
-				"bnx2i_thread/%d", cpu);
+	thread = kthread_create_on_node(bnx2i_percpu_io_thread, (void *)p,
+					cpu_to_node(cpu),
+					"bnx2i_thread/%d", cpu);
 	/* bind thread to the cpu */
 	if (likely(!IS_ERR(thread))) {
 		kthread_bind(thread, cpu);
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index d3ff9cd..d9253db 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1956,12 +1956,11 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
 
 			/* data fits in the skb's headroom */
 			for (i = 0; i < tdata->nr_frags; i++, frag++) {
-				char *src = kmap_atomic(frag->page,
-							KM_SOFTIRQ0);
+				char *src = kmap_atomic(frag->page);
 
 				memcpy(dst, src+frag->offset, frag->size);
 				dst += frag->size;
-				kunmap_atomic(src, KM_SOFTIRQ0);
+				kunmap_atomic(src);
 			}
 			if (padlen) {
 				memset(dst, 0, padlen);
@@ -2148,11 +2147,10 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn,
 			enum iscsi_param param, char *buf, int buflen)
 {
 	struct iscsi_conn *conn = cls_conn->dd_data;
-	struct iscsi_session *session = conn->session;
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
 	struct cxgbi_conn *cconn = tcp_conn->dd_data;
 	struct cxgbi_sock *csk = cconn->cep->csk;
-	int value, err = 0;
+	int err;
 
 	log_debug(1 << CXGBI_DBG_ISCSI,
 		"cls_conn 0x%p, param %d, buf(%d) %s.\n",
@@ -2174,15 +2172,7 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn,
 							conn->datadgst_en, 0);
 		break;
 	case ISCSI_PARAM_MAX_R2T:
-		sscanf(buf, "%d", &value);
-		if (value <= 0 || !is_power_of_2(value))
-			return -EINVAL;
-		if (session->max_r2t == value)
-			break;
-		iscsi_tcp_r2tpool_free(session);
-		err = iscsi_set_param(cls_conn, param, buf, buflen);
-		if (!err && iscsi_tcp_r2tpool_alloc(session))
-			return -ENOMEM;
+		return iscsi_tcp_set_max_r2t(conn, buf);
 	case ISCSI_PARAM_MAX_RECV_DLENGTH:
 		err = iscsi_set_param(cls_conn, param, buf, buflen);
 		if (!err)
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index e959960..ddf3181 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -168,6 +168,14 @@ static struct fc_function_template fcoe_nport_fc_functions = {
 	.show_host_supported_fc4s = 1,
 	.show_host_active_fc4s = 1,
 	.show_host_maxframe_size = 1,
+	.show_host_serial_number = 1,
+	.show_host_manufacturer = 1,
+	.show_host_model = 1,
+	.show_host_model_description = 1,
+	.show_host_hardware_version = 1,
+	.show_host_driver_version = 1,
+	.show_host_firmware_version = 1,
+	.show_host_optionrom_version = 1,
 
 	.show_host_port_id = 1,
 	.show_host_supported_speeds = 1,
@@ -208,6 +216,14 @@ static struct fc_function_template fcoe_vport_fc_functions = {
 	.show_host_supported_fc4s = 1,
 	.show_host_active_fc4s = 1,
 	.show_host_maxframe_size = 1,
+	.show_host_serial_number = 1,
+	.show_host_manufacturer = 1,
+	.show_host_model = 1,
+	.show_host_model_description = 1,
+	.show_host_hardware_version = 1,
+	.show_host_driver_version = 1,
+	.show_host_firmware_version = 1,
+	.show_host_optionrom_version = 1,
 
 	.show_host_port_id = 1,
 	.show_host_supported_speeds = 1,
@@ -364,11 +380,10 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
 	if (!fcoe) {
 		FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
 		fcoe = ERR_PTR(-ENOMEM);
-		goto out_nomod;
+		goto out_putmod;
 	}
 
 	dev_hold(netdev);
-	kref_init(&fcoe->kref);
 
 	/*
 	 * Initialize FIP.
@@ -384,54 +399,18 @@ static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev,
 		kfree(fcoe);
 		dev_put(netdev);
 		fcoe = ERR_PTR(err);
-		goto out_nomod;
+		goto out_putmod;
 	}
 
 	goto out;
 
-out_nomod:
+out_putmod:
 	module_put(THIS_MODULE);
 out:
 	return fcoe;
 }
 
 /**
- * fcoe_interface_release() - fcoe_port kref release function
- * @kref: Embedded reference count in an fcoe_interface struct
- */
-static void fcoe_interface_release(struct kref *kref)
-{
-	struct fcoe_interface *fcoe;
-	struct net_device *netdev;
-
-	fcoe = container_of(kref, struct fcoe_interface, kref);
-	netdev = fcoe->netdev;
-	/* tear-down the FCoE controller */
-	fcoe_ctlr_destroy(&fcoe->ctlr);
-	kfree(fcoe);
-	dev_put(netdev);
-	module_put(THIS_MODULE);
-}
-
-/**
- * fcoe_interface_get() - Get a reference to a FCoE interface
- * @fcoe: The FCoE interface to be held
- */
-static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
-{
-	kref_get(&fcoe->kref);
-}
-
-/**
- * fcoe_interface_put() - Put a reference to a FCoE interface
- * @fcoe: The FCoE interface to be released
- */
-static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
-{
-	kref_put(&fcoe->kref, fcoe_interface_release);
-}
-
-/**
  * fcoe_interface_cleanup() - Clean up a FCoE interface
  * @fcoe: The FCoE interface to be cleaned up
  *
@@ -478,7 +457,11 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
 	rtnl_unlock();
 
 	/* Release the self-reference taken during fcoe_interface_create() */
-	fcoe_interface_put(fcoe);
+	/* tear-down the FCoE controller */
+	fcoe_ctlr_destroy(fip);
+	kfree(fcoe);
+	dev_put(netdev);
+	module_put(THIS_MODULE);
 }
 
 /**
@@ -734,6 +717,85 @@ static int fcoe_shost_config(struct fc_lport *lport, struct device *dev)
 	return 0;
 }
 
+
+/**
+ * fcoe_fdmi_info() - Get FDMI related info from net devive for SW FCoE
+ * @lport:  The local port that is associated with the net device
+ * @netdev: The associated net device
+ *
+ * Must be called after fcoe_shost_config() as it will use local port mutex
+ *
+ */
+static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev)
+{
+	struct fcoe_interface *fcoe;
+	struct fcoe_port *port;
+	struct net_device *realdev;
+	int rc;
+	struct netdev_fcoe_hbainfo fdmi;
+
+	port = lport_priv(lport);
+	fcoe = port->priv;
+	realdev = fcoe->realdev;
+
+	if (!realdev)
+		return;
+
+	/* No FDMI state m/c for NPIV ports */
+	if (lport->vport)
+		return;
+
+	if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) {
+		memset(&fdmi, 0, sizeof(fdmi));
+		rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev,
+							       &fdmi);
+		if (rc) {
+			printk(KERN_INFO "fcoe: Failed to retrieve FDMI "
+					"information from netdev.\n");
+			return;
+		}
+
+		snprintf(fc_host_serial_number(lport->host),
+			 FC_SERIAL_NUMBER_SIZE,
+			 "%s",
+			 fdmi.serial_number);
+		snprintf(fc_host_manufacturer(lport->host),
+			 FC_SERIAL_NUMBER_SIZE,
+			 "%s",
+			 fdmi.manufacturer);
+		snprintf(fc_host_model(lport->host),
+			 FC_SYMBOLIC_NAME_SIZE,
+			 "%s",
+			 fdmi.model);
+		snprintf(fc_host_model_description(lport->host),
+			 FC_SYMBOLIC_NAME_SIZE,
+			 "%s",
+			 fdmi.model_description);
+		snprintf(fc_host_hardware_version(lport->host),
+			 FC_VERSION_STRING_SIZE,
+			 "%s",
+			 fdmi.hardware_version);
+		snprintf(fc_host_driver_version(lport->host),
+			 FC_VERSION_STRING_SIZE,
+			 "%s",
+			 fdmi.driver_version);
+		snprintf(fc_host_optionrom_version(lport->host),
+			 FC_VERSION_STRING_SIZE,
+			 "%s",
+			 fdmi.optionrom_version);
+		snprintf(fc_host_firmware_version(lport->host),
+			 FC_VERSION_STRING_SIZE,
+			 "%s",
+			 fdmi.firmware_version);
+
+		/* Enable FDMI lport states */
+		lport->fdmi_enabled = 1;
+	} else {
+		lport->fdmi_enabled = 0;
+		printk(KERN_INFO "fcoe: No FDMI support.\n");
+	}
+}
+
 /**
  * fcoe_oem_match() - The match routine for the offloaded exchange manager
  * @fp: The I/O frame
@@ -881,9 +943,6 @@ static void fcoe_if_destroy(struct fc_lport *lport)
 		dev_uc_del(netdev, port->data_src_addr);
 	rtnl_unlock();
 
-	/* Release reference held in fcoe_if_create() */
-	fcoe_interface_put(fcoe);
-
 	/* Free queued packets for the per-CPU receive threads */
 	fcoe_percpu_clean(lport);
 
@@ -1047,6 +1106,9 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
 		goto out_lp_destroy;
 	}
 
+	/* Initialized FDMI information */
+	fcoe_fdmi_info(lport, netdev);
+
 	/*
 	 * fcoe_em_alloc() and fcoe_hostlist_add() both
 	 * need to be atomic with respect to other changes to the
@@ -1070,7 +1132,6 @@ static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
 		goto out_lp_destroy;
 	}
 
-	fcoe_interface_get(fcoe);
 	return lport;
 
 out_lp_destroy:
@@ -1515,7 +1576,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 			return -ENOMEM;
 		}
 		frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
-		cp = kmap_atomic(skb_frag_page(frag), KM_SKB_DATA_SOFTIRQ)
+		cp = kmap_atomic(skb_frag_page(frag))
 			+ frag->page_offset;
 	} else {
 		cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
@@ -1526,7 +1587,7 @@ static int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp)
 	cp->fcoe_crc32 = cpu_to_le32(~crc);
 
 	if (skb_is_nonlinear(skb)) {
-		kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
+		kunmap_atomic(cp);
 		cp = NULL;
 	}
 
@@ -2009,20 +2070,13 @@ static void fcoe_destroy_work(struct work_struct *work)
 {
 	struct fcoe_port *port;
 	struct fcoe_interface *fcoe;
-	int npiv = 0;
 
 	port = container_of(work, struct fcoe_port, destroy_work);
 	mutex_lock(&fcoe_config_mutex);
 
-	/* set if this is an NPIV port */
-	npiv = port->lport->vport ? 1 : 0;
-
 	fcoe = port->priv;
 	fcoe_if_destroy(port->lport);
-
-	/* Do not tear down the fcoe interface for NPIV port */
-	if (!npiv)
-		fcoe_interface_cleanup(fcoe);
+	fcoe_interface_cleanup(fcoe);
 
 	mutex_unlock(&fcoe_config_mutex);
 }
@@ -2593,12 +2647,15 @@ static int fcoe_vport_destroy(struct fc_vport *vport)
 	struct Scsi_Host *shost = vport_to_shost(vport);
 	struct fc_lport *n_port = shost_priv(shost);
 	struct fc_lport *vn_port = vport->dd_data;
-	struct fcoe_port *port = lport_priv(vn_port);
 
 	mutex_lock(&n_port->lp_mutex);
 	list_del(&vn_port->list);
 	mutex_unlock(&n_port->lp_mutex);
-	queue_work(fcoe_wq, &port->destroy_work);
+
+	mutex_lock(&fcoe_config_mutex);
+	fcoe_if_destroy(vn_port);
+	mutex_unlock(&fcoe_config_mutex);
+
 	return 0;
 }
 
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index bcc89e6..3c2733a 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -71,8 +71,6 @@ do {                                                            	\
  * @ctlr:	      The FCoE controller (for FIP)
  * @oem:	      The offload exchange manager for all local port
  *		      instances associated with this port
- * @kref:	      The kernel reference
- *
  * This structure is 1:1 with a net devive.
  */
 struct fcoe_interface {
@@ -83,7 +81,6 @@ struct fcoe_interface {
 	struct packet_type fip_packet_type;
 	struct fcoe_ctlr   ctlr;
 	struct fc_exch_mgr *oem;
-	struct kref	   kref;
 };
 
 #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c
index bd97b22..710e149 100644
--- a/drivers/scsi/fcoe/fcoe_transport.c
+++ b/drivers/scsi/fcoe/fcoe_transport.c
@@ -210,10 +210,9 @@ u32 fcoe_fc_crc(struct fc_frame *fp)
 		while (len > 0) {
 			clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
 			data = kmap_atomic(
-				skb_frag_page(frag) + (off >> PAGE_SHIFT),
-				KM_SKB_DATA_SOFTIRQ);
+				skb_frag_page(frag) + (off >> PAGE_SHIFT));
 			crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
-			kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
+			kunmap_atomic(data);
 			off += clen;
 			len -= clen;
 		}
@@ -620,8 +619,8 @@ static int libfcoe_device_notification(struct notifier_block *notifier,
 
 	switch (event) {
 	case NETDEV_UNREGISTER:
-		printk(KERN_ERR "libfcoe_device_notification: NETDEV_UNREGISTER %s\n",
-				netdev->name);
+		LIBFCOE_TRANSPORT_DBG("NETDEV_UNREGISTER %s\n",
+				      netdev->name);
 		fcoe_del_netdev_mapping(netdev);
 		break;
 	}
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3242bca..d42ec92 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2310,10 +2310,10 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
                 return;
             }
             local_irq_save(flags);
-            address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
+            address = kmap_atomic(sg_page(sl)) + sl->offset;
             memcpy(address, buffer, cpnow);
             flush_dcache_page(sg_page(sl));
-            kunmap_atomic(address, KM_BIO_SRC_IRQ);
+            kunmap_atomic(address);
             local_irq_restore(flags);
             if (cpsum == cpcount)
                 break;
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index b96962c..500e20d 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -56,6 +56,7 @@
 /* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.' */
 #define HPSA_DRIVER_VERSION "2.0.2-1"
 #define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
+#define HPSA "hpsa"
 
 /* How long to wait (in milliseconds) for board to go into simple mode */
 #define MAX_CONFIG_WAIT 30000
@@ -202,30 +203,31 @@ static int check_for_unit_attention(struct ctlr_info *h,
 
 	switch (c->err_info->SenseInfo[12]) {
 	case STATE_CHANGED:
-		dev_warn(&h->pdev->dev, "hpsa%d: a state change "
+		dev_warn(&h->pdev->dev, HPSA "%d: a state change "
 			"detected, command retried\n", h->ctlr);
 		break;
 	case LUN_FAILED:
-		dev_warn(&h->pdev->dev, "hpsa%d: LUN failure "
+		dev_warn(&h->pdev->dev, HPSA "%d: LUN failure "
 			"detected, action required\n", h->ctlr);
 		break;
 	case REPORT_LUNS_CHANGED:
-		dev_warn(&h->pdev->dev, "hpsa%d: report LUN data "
+		dev_warn(&h->pdev->dev, HPSA "%d: report LUN data "
 			"changed, action required\n", h->ctlr);
 	/*
-	 * Note: this REPORT_LUNS_CHANGED condition only occurs on the MSA2012.
+	 * Note: this REPORT_LUNS_CHANGED condition only occurs on the external
+	 * target (array) devices.
 	 */
 		break;
 	case POWER_OR_RESET:
-		dev_warn(&h->pdev->dev, "hpsa%d: a power on "
+		dev_warn(&h->pdev->dev, HPSA "%d: a power on "
 			"or device reset detected\n", h->ctlr);
 		break;
 	case UNIT_ATTENTION_CLEARED:
-		dev_warn(&h->pdev->dev, "hpsa%d: unit attention "
+		dev_warn(&h->pdev->dev, HPSA "%d: unit attention "
 		    "cleared by another initiator\n", h->ctlr);
 		break;
 	default:
-		dev_warn(&h->pdev->dev, "hpsa%d: unknown "
+		dev_warn(&h->pdev->dev, HPSA "%d: unknown "
 			"unit attention detected\n", h->ctlr);
 		break;
 	}
@@ -296,11 +298,23 @@ static u32 unresettable_controller[] = {
 	0x40800E11, /* Smart Array 5i */
 	0x409C0E11, /* Smart Array 6400 */
 	0x409D0E11, /* Smart Array 6400 EM */
+	0x40700E11, /* Smart Array 5300 */
+	0x40820E11, /* Smart Array 532 */
+	0x40830E11, /* Smart Array 5312 */
+	0x409A0E11, /* Smart Array 641 */
+	0x409B0E11, /* Smart Array 642 */
+	0x40910E11, /* Smart Array 6i */
 };
 
 /* List of controllers which cannot even be soft reset */
 static u32 soft_unresettable_controller[] = {
 	0x40800E11, /* Smart Array 5i */
+	0x40700E11, /* Smart Array 5300 */
+	0x40820E11, /* Smart Array 532 */
+	0x40830E11, /* Smart Array 5312 */
+	0x409A0E11, /* Smart Array 641 */
+	0x409B0E11, /* Smart Array 642 */
+	0x40910E11, /* Smart Array 6i */
 	/* Exclude 640x boards.  These are two pci devices in one slot
 	 * which share a battery backed cache module.  One controls the
 	 * cache, the other accesses the cache through the one that controls
@@ -475,8 +489,8 @@ static struct device_attribute *hpsa_shost_attrs[] = {
 
 static struct scsi_host_template hpsa_driver_template = {
 	.module			= THIS_MODULE,
-	.name			= "hpsa",
-	.proc_name		= "hpsa",
+	.name			= HPSA,
+	.proc_name		= HPSA,
 	.queuecommand		= hpsa_scsi_queue_command,
 	.scan_start		= hpsa_scan_start,
 	.scan_finished		= hpsa_scan_finished,
@@ -577,21 +591,19 @@ static int hpsa_find_target_lun(struct ctlr_info *h,
 	int i, found = 0;
 	DECLARE_BITMAP(lun_taken, HPSA_MAX_DEVICES);
 
-	memset(&lun_taken[0], 0, HPSA_MAX_DEVICES >> 3);
+	bitmap_zero(lun_taken, HPSA_MAX_DEVICES);
 
 	for (i = 0; i < h->ndevices; i++) {
 		if (h->dev[i]->bus == bus && h->dev[i]->target != -1)
-			set_bit(h->dev[i]->target, lun_taken);
+			__set_bit(h->dev[i]->target, lun_taken);
 	}
 
-	for (i = 0; i < HPSA_MAX_DEVICES; i++) {
-		if (!test_bit(i, lun_taken)) {
-			/* *bus = 1; */
-			*target = i;
-			*lun = 0;
-			found = 1;
-			break;
-		}
+	i = find_first_zero_bit(lun_taken, HPSA_MAX_DEVICES);
+	if (i < HPSA_MAX_DEVICES) {
+		/* *bus = 1; */
+		*target = i;
+		*lun = 0;
+		found = 1;
 	}
 	return !found;
 }
@@ -675,6 +687,20 @@ lun_assigned:
 	return 0;
 }
 
+/* Update an entry in h->dev[] array. */
+static void hpsa_scsi_update_entry(struct ctlr_info *h, int hostno,
+	int entry, struct hpsa_scsi_dev_t *new_entry)
+{
+	/* assumes h->devlock is held */
+	BUG_ON(entry < 0 || entry >= HPSA_MAX_DEVICES);
+
+	/* Raid level changed. */
+	h->dev[entry]->raid_level = new_entry->raid_level;
+	dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d updated.\n",
+		scsi_device_type(new_entry->devtype), hostno, new_entry->bus,
+		new_entry->target, new_entry->lun);
+}
+
 /* Replace an entry from h->dev[] array. */
 static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
 	int entry, struct hpsa_scsi_dev_t *new_entry,
@@ -781,10 +807,25 @@ static inline int device_is_the_same(struct hpsa_scsi_dev_t *dev1,
 	return 1;
 }
 
+static inline int device_updated(struct hpsa_scsi_dev_t *dev1,
+	struct hpsa_scsi_dev_t *dev2)
+{
+	/* Device attributes that can change, but don't mean
+	 * that the device is a different device, nor that the OS
+	 * needs to be told anything about the change.
+	 */
+	if (dev1->raid_level != dev2->raid_level)
+		return 1;
+	return 0;
+}
+
 /* Find needle in haystack.  If exact match found, return DEVICE_SAME,
  * and return needle location in *index.  If scsi3addr matches, but not
  * vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle
- * location in *index.  If needle not found, return DEVICE_NOT_FOUND.
+ * location in *index.
+ * In the case of a minor device attribute change, such as RAID level, just
+ * return DEVICE_UPDATED, along with the updated device's location in index.
+ * If needle not found, return DEVICE_NOT_FOUND.
  */
 static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
 	struct hpsa_scsi_dev_t *haystack[], int haystack_size,
@@ -794,15 +835,19 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
 #define DEVICE_NOT_FOUND 0
 #define DEVICE_CHANGED 1
 #define DEVICE_SAME 2
+#define DEVICE_UPDATED 3
 	for (i = 0; i < haystack_size; i++) {
 		if (haystack[i] == NULL) /* previously removed. */
 			continue;
 		if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) {
 			*index = i;
-			if (device_is_the_same(needle, haystack[i]))
+			if (device_is_the_same(needle, haystack[i])) {
+				if (device_updated(needle, haystack[i]))
+					return DEVICE_UPDATED;
 				return DEVICE_SAME;
-			else
+			} else {
 				return DEVICE_CHANGED;
+			}
 		}
 	}
 	*index = -1;
@@ -838,6 +883,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 	 * sd[] and remove them from h->dev[], and for any
 	 * devices which have changed, remove the old device
 	 * info and add the new device info.
+	 * If minor device attributes change, just update
+	 * the existing device structure.
 	 */
 	i = 0;
 	nremoved = 0;
@@ -858,6 +905,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, int hostno,
 			 * at the bottom of hpsa_update_scsi_devices()
 			 */
 			sd[entry] = NULL;
+		} else if (device_change == DEVICE_UPDATED) {
+			hpsa_scsi_update_entry(h, hostno, i, sd[entry]);
 		}
 		i++;
 	}
@@ -1257,46 +1306,6 @@ static void complete_scsi_command(struct CommandList *cp)
 	cmd_free(h, cp);
 }
 
-static int hpsa_scsi_detect(struct ctlr_info *h)
-{
-	struct Scsi_Host *sh;
-	int error;
-
-	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
-	if (sh == NULL)
-		goto fail;
-
-	sh->io_port = 0;
-	sh->n_io_port = 0;
-	sh->this_id = -1;
-	sh->max_channel = 3;
-	sh->max_cmd_len = MAX_COMMAND_SIZE;
-	sh->max_lun = HPSA_MAX_LUN;
-	sh->max_id = HPSA_MAX_LUN;
-	sh->can_queue = h->nr_cmds;
-	sh->cmd_per_lun = h->nr_cmds;
-	sh->sg_tablesize = h->maxsgentries;
-	h->scsi_host = sh;
-	sh->hostdata[0] = (unsigned long) h;
-	sh->irq = h->intr[h->intr_mode];
-	sh->unique_id = sh->irq;
-	error = scsi_add_host(sh, &h->pdev->dev);
-	if (error)
-		goto fail_host_put;
-	scsi_scan_host(sh);
-	return 0;
-
- fail_host_put:
-	dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_add_host"
-		" failed for controller %d\n", h->ctlr);
-	scsi_host_put(sh);
-	return error;
- fail:
-	dev_err(&h->pdev->dev, "hpsa_scsi_detect: scsi_host_alloc"
-		" failed for controller %d\n", h->ctlr);
-	return -ENOMEM;
-}
-
 static void hpsa_pci_unmap(struct pci_dev *pdev,
 	struct CommandList *c, int sg_used, int data_direction)
 {
@@ -1641,7 +1650,7 @@ bail_out:
 	return 1;
 }
 
-static unsigned char *msa2xxx_model[] = {
+static unsigned char *ext_target_model[] = {
 	"MSA2012",
 	"MSA2024",
 	"MSA2312",
@@ -1650,78 +1659,54 @@ static unsigned char *msa2xxx_model[] = {
 	NULL,
 };
 
-static int is_msa2xxx(struct ctlr_info *h, struct hpsa_scsi_dev_t *device)
+static int is_ext_target(struct ctlr_info *h, struct hpsa_scsi_dev_t *device)
 {
 	int i;
 
-	for (i = 0; msa2xxx_model[i]; i++)
-		if (strncmp(device->model, msa2xxx_model[i],
-			strlen(msa2xxx_model[i])) == 0)
+	for (i = 0; ext_target_model[i]; i++)
+		if (strncmp(device->model, ext_target_model[i],
+			strlen(ext_target_model[i])) == 0)
 			return 1;
 	return 0;
 }
 
 /* Helper function to assign bus, target, lun mapping of devices.
- * Puts non-msa2xxx logical volumes on bus 0, msa2xxx logical
+ * Puts non-external target logical volumes on bus 0, external target logical
  * volumes on bus 1, physical devices on bus 2. and the hba on bus 3.
  * Logical drive target and lun are assigned at this time, but
  * physical device lun and target assignment are deferred (assigned
  * in hpsa_find_target_lun, called by hpsa_scsi_add_entry.)
  */
 static void figure_bus_target_lun(struct ctlr_info *h,
-	u8 *lunaddrbytes, int *bus, int *target, int *lun,
-	struct hpsa_scsi_dev_t *device)
+	u8 *lunaddrbytes, struct hpsa_scsi_dev_t *device)
 {
-	u32 lunid;
+	u32 lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
 
-	if (is_logical_dev_addr_mode(lunaddrbytes)) {
-		/* logical device */
-		if (unlikely(is_scsi_rev_5(h))) {
-			/* p1210m, logical drives lun assignments
-			 * match SCSI REPORT LUNS data.
-			 */
-			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
-			*bus = 0;
-			*target = 0;
-			*lun = (lunid & 0x3fff) + 1;
-		} else {
-			/* not p1210m... */
-			lunid = le32_to_cpu(*((__le32 *) lunaddrbytes));
-			if (is_msa2xxx(h, device)) {
-				/* msa2xxx way, put logicals on bus 1
-				 * and match target/lun numbers box
-				 * reports.
-				 */
-				*bus = 1;
-				*target = (lunid >> 16) & 0x3fff;
-				*lun = lunid & 0x00ff;
-			} else {
-				/* Traditional smart array way. */
-				*bus = 0;
-				*lun = 0;
-				*target = lunid & 0x3fff;
-			}
-		}
-	} else {
-		/* physical device */
+	if (!is_logical_dev_addr_mode(lunaddrbytes)) {
+		/* physical device, target and lun filled in later */
 		if (is_hba_lunid(lunaddrbytes))
-			if (unlikely(is_scsi_rev_5(h))) {
-				*bus = 0; /* put p1210m ctlr at 0,0,0 */
-				*target = 0;
-				*lun = 0;
-				return;
-			} else
-				*bus = 3; /* traditional smartarray */
+			hpsa_set_bus_target_lun(device, 3, 0, lunid & 0x3fff);
 		else
-			*bus = 2; /* physical disk */
-		*target = -1;
-		*lun = -1; /* we will fill these in later. */
+			/* defer target, lun assignment for physical devices */
+			hpsa_set_bus_target_lun(device, 2, -1, -1);
+		return;
+	}
+	/* It's a logical device */
+	if (is_ext_target(h, device)) {
+		/* external target way, put logicals on bus 1
+		 * and match target/lun numbers box
+		 * reports, other smart array, bus 0, target 0, match lunid
+		 */
+		hpsa_set_bus_target_lun(device,
+			1, (lunid >> 16) & 0x3fff, lunid & 0x00ff);
+		return;
 	}
+	hpsa_set_bus_target_lun(device, 0, 0, lunid & 0x3fff);
 }
 
 /*
  * If there is no lun 0 on a target, linux won't find any devices.
- * For the MSA2xxx boxes, we have to manually detect the enclosure
+ * For the external targets (arrays), we have to manually detect the enclosure
  * which is at lun zero, as CCISS_REPORT_PHYSICAL_LUNS doesn't report
  * it for some reason.  *tmpdevice is the target we're adding,
  * this_device is a pointer into the current element of currentsd[]
@@ -1730,46 +1715,46 @@ static void figure_bus_target_lun(struct ctlr_info *h,
  * lun 0 assigned.
  * Returns 1 if an enclosure was added, 0 if not.
  */
-static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
+static int add_ext_target_dev(struct ctlr_info *h,
 	struct hpsa_scsi_dev_t *tmpdevice,
 	struct hpsa_scsi_dev_t *this_device, u8 *lunaddrbytes,
-	int bus, int target, int lun, unsigned long lunzerobits[],
-	int *nmsa2xxx_enclosures)
+	unsigned long lunzerobits[], int *n_ext_target_devs)
 {
 	unsigned char scsi3addr[8];
 
-	if (test_bit(target, lunzerobits))
+	if (test_bit(tmpdevice->target, lunzerobits))
 		return 0; /* There is already a lun 0 on this target. */
 
 	if (!is_logical_dev_addr_mode(lunaddrbytes))
 		return 0; /* It's the logical targets that may lack lun 0. */
 
-	if (!is_msa2xxx(h, tmpdevice))
-		return 0; /* It's only the MSA2xxx that have this problem. */
+	if (!is_ext_target(h, tmpdevice))
+		return 0; /* Only external target devices have this problem. */
 
-	if (lun == 0) /* if lun is 0, then obviously we have a lun 0. */
+	if (tmpdevice->lun == 0) /* if lun is 0, then we have a lun 0. */
 		return 0;
 
 	memset(scsi3addr, 0, 8);
-	scsi3addr[3] = target;
+	scsi3addr[3] = tmpdevice->target;
 	if (is_hba_lunid(scsi3addr))
 		return 0; /* Don't add the RAID controller here. */
 
 	if (is_scsi_rev_5(h))
 		return 0; /* p1210m doesn't need to do this. */
 
-	if (*nmsa2xxx_enclosures >= MAX_MSA2XXX_ENCLOSURES) {
-		dev_warn(&h->pdev->dev, "Maximum number of MSA2XXX "
-			"enclosures exceeded.  Check your hardware "
+	if (*n_ext_target_devs >= MAX_EXT_TARGETS) {
+		dev_warn(&h->pdev->dev, "Maximum number of external "
+			"target devices exceeded.  Check your hardware "
 			"configuration.");
 		return 0;
 	}
 
 	if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
 		return 0;
-	(*nmsa2xxx_enclosures)++;
-	hpsa_set_bus_target_lun(this_device, bus, target, 0);
-	set_bit(target, lunzerobits);
+	(*n_ext_target_devs)++;
+	hpsa_set_bus_target_lun(this_device,
+				tmpdevice->bus, tmpdevice->target, 0);
+	set_bit(tmpdevice->target, lunzerobits);
 	return 1;
 }
 
@@ -1863,10 +1848,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 	struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice;
 	int ncurrent = 0;
 	int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8;
-	int i, nmsa2xxx_enclosures, ndevs_to_allocate;
-	int bus, target, lun;
+	int i, n_ext_target_devs, ndevs_to_allocate;
 	int raid_ctlr_position;
-	DECLARE_BITMAP(lunzerobits, HPSA_MAX_TARGETS_PER_CTLR);
+	DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS);
 
 	currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL);
 	physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
@@ -1883,11 +1867,11 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 			logdev_list, &nlogicals))
 		goto out;
 
-	/* We might see up to 32 MSA2xxx enclosures, actually 8 of them
-	 * but each of them 4 times through different paths.  The plus 1
-	 * is for the RAID controller.
+	/* We might see up to the maximum number of logical and physical disks
+	 * plus external target devices, and a device for the local RAID
+	 * controller.
 	 */
-	ndevs_to_allocate = nphysicals + nlogicals + MAX_MSA2XXX_ENCLOSURES + 1;
+	ndevs_to_allocate = nphysicals + nlogicals + MAX_EXT_TARGETS + 1;
 
 	/* Allocate the per device structures */
 	for (i = 0; i < ndevs_to_allocate; i++) {
@@ -1913,7 +1897,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 		raid_ctlr_position = nphysicals + nlogicals;
 
 	/* adjust our table of devices */
-	nmsa2xxx_enclosures = 0;
+	n_ext_target_devs = 0;
 	for (i = 0; i < nphysicals + nlogicals + 1; i++) {
 		u8 *lunaddrbytes, is_OBDR = 0;
 
@@ -1929,26 +1913,24 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
 		if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
 							&is_OBDR))
 			continue; /* skip it if we can't talk to it. */
-		figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
-			tmpdevice);
+		figure_bus_target_lun(h, lunaddrbytes, tmpdevice);
 		this_device = currentsd[ncurrent];
 
 		/*
-		 * For the msa2xxx boxes, we have to insert a LUN 0 which
+		 * For external target devices, we have to insert a LUN 0 which
 		 * doesn't show up in CCISS_REPORT_PHYSICAL data, but there
 		 * is nonetheless an enclosure device there.  We have to
 		 * present that otherwise linux won't find anything if
 		 * there is no lun 0.
 		 */
-		if (add_msa2xxx_enclosure_device(h, tmpdevice, this_device,
-				lunaddrbytes, bus, target, lun, lunzerobits,
-				&nmsa2xxx_enclosures)) {
+		if (add_ext_target_dev(h, tmpdevice, this_device,
+				lunaddrbytes, lunzerobits,
+				&n_ext_target_devs)) {
 			ncurrent++;
 			this_device = currentsd[ncurrent];
 		}
 
 		*this_device = *tmpdevice;
-		hpsa_set_bus_target_lun(this_device, bus, target, lun);
 
 		switch (this_device->devtype) {
 		case TYPE_ROM:
@@ -2228,13 +2210,42 @@ static void hpsa_unregister_scsi(struct ctlr_info *h)
 
 static int hpsa_register_scsi(struct ctlr_info *h)
 {
-	int rc;
+	struct Scsi_Host *sh;
+	int error;
 
-	rc = hpsa_scsi_detect(h);
-	if (rc != 0)
-		dev_err(&h->pdev->dev, "hpsa_register_scsi: failed"
-			" hpsa_scsi_detect(), rc is %d\n", rc);
-	return rc;
+	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
+	if (sh == NULL)
+		goto fail;
+
+	sh->io_port = 0;
+	sh->n_io_port = 0;
+	sh->this_id = -1;
+	sh->max_channel = 3;
+	sh->max_cmd_len = MAX_COMMAND_SIZE;
+	sh->max_lun = HPSA_MAX_LUN;
+	sh->max_id = HPSA_MAX_LUN;
+	sh->can_queue = h->nr_cmds;
+	sh->cmd_per_lun = h->nr_cmds;
+	sh->sg_tablesize = h->maxsgentries;
+	h->scsi_host = sh;
+	sh->hostdata[0] = (unsigned long) h;
+	sh->irq = h->intr[h->intr_mode];
+	sh->unique_id = sh->irq;
+	error = scsi_add_host(sh, &h->pdev->dev);
+	if (error)
+		goto fail_host_put;
+	scsi_scan_host(sh);
+	return 0;
+
+ fail_host_put:
+	dev_err(&h->pdev->dev, "%s: scsi_add_host"
+		" failed for controller %d\n", __func__, h->ctlr);
+	scsi_host_put(sh);
+	return error;
+ fail:
+	dev_err(&h->pdev->dev, "%s: scsi_host_alloc"
+		" failed for controller %d\n", __func__, h->ctlr);
+	return -ENOMEM;
 }
 
 static int wait_for_device_to_become_ready(struct ctlr_info *h,
@@ -2700,16 +2711,16 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
 		status = -EINVAL;
 		goto cleanup1;
 	}
-	if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES) {
+	if (ioc->buf_size > ioc->malloc_size * SG_ENTRIES_IN_CMD) {
 		status = -EINVAL;
 		goto cleanup1;
 	}
-	buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
+	buff = kzalloc(SG_ENTRIES_IN_CMD * sizeof(char *), GFP_KERNEL);
 	if (!buff) {
 		status = -ENOMEM;
 		goto cleanup1;
 	}
-	buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL);
+	buff_size = kmalloc(SG_ENTRIES_IN_CMD * sizeof(int), GFP_KERNEL);
 	if (!buff_size) {
 		status = -ENOMEM;
 		goto cleanup1;
@@ -3354,7 +3365,7 @@ static int hpsa_controller_hard_reset(struct pci_dev *pdev,
 static __devinit void init_driver_version(char *driver_version, int len)
 {
 	memset(driver_version, 0, len);
-	strncpy(driver_version, "hpsa " HPSA_DRIVER_VERSION, len - 1);
+	strncpy(driver_version, HPSA " " HPSA_DRIVER_VERSION, len - 1);
 }
 
 static __devinit int write_driver_ver_to_cfgtable(
@@ -3935,7 +3946,7 @@ static int __devinit hpsa_pci_init(struct ctlr_info *h)
 		return err;
 	}
 
-	err = pci_request_regions(h->pdev, "hpsa");
+	err = pci_request_regions(h->pdev, HPSA);
 	if (err) {
 		dev_err(&h->pdev->dev,
 			"cannot obtain PCI resources, aborting\n");
@@ -4253,7 +4264,7 @@ static void start_controller_lockup_detector(struct ctlr_info *h)
 		spin_lock_init(&lockup_detector_lock);
 		hpsa_lockup_detector =
 			kthread_run(detect_controller_lockup_thread,
-						NULL, "hpsa");
+						NULL, HPSA);
 	}
 	if (!hpsa_lockup_detector) {
 		dev_warn(&h->pdev->dev,
@@ -4325,7 +4336,7 @@ reinit_after_soft_reset:
 	if (rc != 0)
 		goto clean1;
 
-	sprintf(h->devname, "hpsa%d", number_of_controllers);
+	sprintf(h->devname, HPSA "%d", number_of_controllers);
 	h->ctlr = number_of_controllers;
 	number_of_controllers++;
 
@@ -4482,6 +4493,14 @@ static void hpsa_shutdown(struct pci_dev *pdev)
 #endif				/* CONFIG_PCI_MSI */
 }
 
+static void __devexit hpsa_free_device_info(struct ctlr_info *h)
+{
+	int i;
+
+	for (i = 0; i < h->ndevices; i++)
+		kfree(h->dev[i]);
+}
+
 static void __devexit hpsa_remove_one(struct pci_dev *pdev)
 {
 	struct ctlr_info *h;
@@ -4497,6 +4516,7 @@ static void __devexit hpsa_remove_one(struct pci_dev *pdev)
 	iounmap(h->vaddr);
 	iounmap(h->transtable);
 	iounmap(h->cfgtable);
+	hpsa_free_device_info(h);
 	hpsa_free_sg_chain_blocks(h);
 	pci_free_consistent(h->pdev,
 		h->nr_cmds * sizeof(struct CommandList),
@@ -4530,7 +4550,7 @@ static int hpsa_resume(__attribute__((unused)) struct pci_dev *pdev)
 }
 
 static struct pci_driver hpsa_pci_driver = {
-	.name = "hpsa",
+	.name = HPSA,
 	.probe = hpsa_init_one,
 	.remove = __devexit_p(hpsa_remove_one),
 	.id_table = hpsa_pci_device_id,	/* id_table */
@@ -4592,15 +4612,15 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h,
 	 * Each SG entry requires 16 bytes.  The eight registers are programmed
 	 * with the number of 16-byte blocks a command of that size requires.
 	 * The smallest command possible requires 5 such 16 byte blocks.
-	 * the largest command possible requires MAXSGENTRIES + 4 16-byte
+	 * the largest command possible requires SG_ENTRIES_IN_CMD + 4 16-byte
 	 * blocks.  Note, this only extends to the SG entries contained
 	 * within the command block, and does not extend to chained blocks
 	 * of SG elements.   bft[] contains the eight values we write to
 	 * the registers.  They are not evenly distributed, but have more
 	 * sizes for small commands, and fewer sizes for larger commands.
 	 */
-	int bft[8] = {5, 6, 8, 10, 12, 20, 28, MAXSGENTRIES + 4};
-	BUILD_BUG_ON(28 > MAXSGENTRIES + 4);
+	int bft[8] = {5, 6, 8, 10, 12, 20, 28, SG_ENTRIES_IN_CMD + 4};
+	BUILD_BUG_ON(28 > SG_ENTRIES_IN_CMD + 4);
 	/*  5 = 1 s/g entry or 4k
 	 *  6 = 2 s/g entry or 8k
 	 *  8 = 4 s/g entry or 16k
@@ -4613,8 +4633,9 @@ static __devinit void hpsa_enter_performant_mode(struct ctlr_info *h,
 	memset(h->reply_pool, 0, h->reply_pool_size);
 	h->reply_pool_head = h->reply_pool;
 
-	bft[7] = h->max_sg_entries + 4;
-	calc_bucket_map(bft, ARRAY_SIZE(bft), 32, h->blockFetchTable);
+	bft[7] = SG_ENTRIES_IN_CMD + 4;
+	calc_bucket_map(bft, ARRAY_SIZE(bft),
+				SG_ENTRIES_IN_CMD, h->blockFetchTable);
 	for (i = 0; i < 8; i++)
 		writel(bft[i], &h->transtable->BlockFetch[i]);
 
@@ -4652,14 +4673,13 @@ static __devinit void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h)
 		return;
 
 	hpsa_get_max_perf_mode_cmds(h);
-	h->max_sg_entries = 32;
 	/* Performant mode ring buffer and supporting data structures */
 	h->reply_pool_size = h->max_commands * sizeof(u64);
 	h->reply_pool = pci_alloc_consistent(h->pdev, h->reply_pool_size,
 				&(h->reply_pool_dhandle));
 
 	/* Need a block fetch table for performant mode */
-	h->blockFetchTable = kmalloc(((h->max_sg_entries+1) *
+	h->blockFetchTable = kmalloc(((SG_ENTRIES_IN_CMD + 1) *
 				sizeof(u32)), GFP_KERNEL);
 
 	if ((h->reply_pool == NULL)
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 91edafb..7b28d54 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -58,7 +58,6 @@ struct ctlr_info {
 	unsigned long paddr;
 	int 	nr_cmds; /* Number of commands allowed on this controller */
 	struct CfgTable __iomem *cfgtable;
-	int     max_sg_entries;
 	int	interrupts_enabled;
 	int	major;
 	int 	max_commands;
@@ -317,7 +316,7 @@ static unsigned long SA5_completed(struct ctlr_info *h)
 		dev_dbg(&h->pdev->dev, "Read %lx back from board\n",
 			register_value);
 	else
-		dev_dbg(&h->pdev->dev, "hpsa: FIFO Empty read\n");
+		dev_dbg(&h->pdev->dev, "FIFO Empty read\n");
 #endif
 
 	return register_value;
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h
index 3fd4715..8049815 100644
--- a/drivers/scsi/hpsa_cmd.h
+++ b/drivers/scsi/hpsa_cmd.h
@@ -23,7 +23,7 @@
 
 /* general boundary defintions */
 #define SENSEINFOBYTES          32 /* may vary between hbas */
-#define MAXSGENTRIES            32
+#define SG_ENTRIES_IN_CMD	32 /* Max SG entries excluding chain blocks */
 #define HPSA_SG_CHAIN		0x80000000
 #define MAXREPLYQS              256
 
@@ -122,12 +122,11 @@ union u64bit {
 };
 
 /* FIXME this is a per controller value (barf!) */
-#define HPSA_MAX_TARGETS_PER_CTLR 16
 #define HPSA_MAX_LUN 1024
 #define HPSA_MAX_PHYS_LUN 1024
-#define MAX_MSA2XXX_ENCLOSURES 32
+#define MAX_EXT_TARGETS 32
 #define HPSA_MAX_DEVICES (HPSA_MAX_PHYS_LUN + HPSA_MAX_LUN + \
-	MAX_MSA2XXX_ENCLOSURES + 1) /* + 1 is for the controller itself */
+	MAX_EXT_TARGETS + 1) /* + 1 is for the controller itself */
 
 /* SCSI-3 Commands */
 #pragma pack(1)
@@ -282,7 +281,7 @@ struct CommandList {
 	struct CommandListHeader Header;
 	struct RequestBlock      Request;
 	struct ErrDescriptor     ErrDesc;
-	struct SGDescriptor      SG[MAXSGENTRIES];
+	struct SGDescriptor      SG[SG_ENTRIES_IN_CMD];
 	/* information associated with the command */
 	u32			   busaddr; /* physical addr of this record */
 	struct ErrorInfo *err_info; /* pointer to the allocated mem */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 67b169b..b538f08 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4613,11 +4613,13 @@ static int __ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd)
 	ENTER;
 	ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
 
-	dev_err(&ioa_cfg->pdev->dev,
-		"Adapter being reset as a result of error recovery.\n");
+	if (!ioa_cfg->in_reset_reload) {
+		dev_err(&ioa_cfg->pdev->dev,
+			"Adapter being reset as a result of error recovery.\n");
 
-	if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
-		ioa_cfg->sdt_state = GET_DUMP;
+		if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
+			ioa_cfg->sdt_state = GET_DUMP;
+	}
 
 	rc = ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_ABBREV);
 
@@ -4907,7 +4909,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
 	struct ipr_ioa_cfg *ioa_cfg;
 	struct ipr_resource_entry *res;
 	struct ipr_cmd_pkt *cmd_pkt;
-	u32 ioasc;
+	u32 ioasc, int_reg;
 	int op_found = 0;
 
 	ENTER;
@@ -4920,7 +4922,17 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
 	 */
 	if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead)
 		return FAILED;
-	if (!res || !ipr_is_gscsi(res))
+	if (!res)
+		return FAILED;
+
+	/*
+	 * If we are aborting a timed out op, chances are that the timeout was caused
+	 * by a still not detected EEH error. In such cases, reading a register will
+	 * trigger the EEH recovery infrastructure.
+	 */
+	int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
+
+	if (!ipr_is_gscsi(res))
 		return FAILED;
 
 	list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index d77891e..b6d7a5c 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1511,14 +1511,14 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
                 /* kmap_atomic() ensures addressability of the user buffer.*/
                 /* local_irq_save() protects the KM_IRQ0 address slot.     */
                 local_irq_save(flags);
-                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
+                buffer = kmap_atomic(sg_page(sg)) + sg->offset;
                 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
                     buffer[2] == 'P' && buffer[3] == 'P') {
-                        kunmap_atomic(buffer - sg->offset, KM_IRQ0);
+                        kunmap_atomic(buffer - sg->offset);
                         local_irq_restore(flags);
                         return 1;
                 }
-                kunmap_atomic(buffer - sg->offset, KM_IRQ0);
+                kunmap_atomic(buffer - sg->offset);
                 local_irq_restore(flags);
 	}
 	return 0;
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 1a65d65..d4bf9c1 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -58,7 +58,6 @@
 #include "host.h"
 #include "isci.h"
 #include "port.h"
-#include "host.h"
 #include "probe_roms.h"
 #include "remote_device.h"
 #include "request.h"
@@ -650,15 +649,13 @@ static void isci_host_start_complete(struct isci_host *ihost, enum sci_status co
 
 int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time)
 {
-	struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
+	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+	struct isci_host *ihost = ha->lldd_ha;
 
 	if (test_bit(IHOST_START_PENDING, &ihost->flags))
 		return 0;
 
-	/* todo: use sas_flush_discovery once it is upstream */
-	scsi_flush_work(shost);
-
-	scsi_flush_work(shost);
+	sas_drain_work(ha);
 
 	dev_dbg(&ihost->pdev->dev,
 		"%s: ihost->status = %d, time = %ld\n",
@@ -1491,6 +1488,15 @@ sci_controller_set_interrupt_coalescence(struct isci_host *ihost,
 static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm)
 {
 	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+	u32 val;
+
+	/* enable clock gating for power control of the scu unit */
+	val = readl(&ihost->smu_registers->clock_gating_control);
+	val &= ~(SMU_CGUCR_GEN_BIT(REGCLK_ENABLE) |
+		 SMU_CGUCR_GEN_BIT(TXCLK_ENABLE) |
+		 SMU_CGUCR_GEN_BIT(XCLK_ENABLE));
+	val |= SMU_CGUCR_GEN_BIT(IDLE_ENABLE);
+	writel(val, &ihost->smu_registers->clock_gating_control);
 
 	/* set the default interrupt coalescence number and timeout value. */
 	sci_controller_set_interrupt_coalescence(ihost, 0, 0);
@@ -1848,9 +1854,11 @@ static enum sci_status sci_oem_parameters_set(struct isci_host *ihost)
 	if (state == SCIC_RESET ||
 	    state == SCIC_INITIALIZING ||
 	    state == SCIC_INITIALIZED) {
+		u8 oem_version = pci_info->orom ? pci_info->orom->hdr.version :
+			ISCI_ROM_VER_1_0;
 
 		if (sci_oem_parameters_validate(&ihost->oem_parameters,
-						pci_info->orom->hdr.version))
+						oem_version))
 			return SCI_FAILURE_INVALID_PARAMETER_VALUE;
 
 		return SCI_SUCCESS;
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 5477f0f..adbad69 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -187,6 +187,7 @@ struct isci_host {
 	int id; /* unique within a given pci device */
 	struct isci_phy phys[SCI_MAX_PHYS];
 	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
+	struct asd_sas_port sas_ports[SCI_MAX_PORTS];
 	struct sas_ha_struct sas_ha;
 
 	spinlock_t state_lock;
@@ -393,24 +394,6 @@ static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
 #define sci_controller_clear_invalid_phy(controller, phy) \
 	((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))
 
-static inline struct device *sciphy_to_dev(struct isci_phy *iphy)
-{
-
-	if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
-		return NULL;
-
-	return &iphy->isci_port->isci_host->pdev->dev;
-}
-
-static inline struct device *sciport_to_dev(struct isci_port *iport)
-{
-
-	if (!iport || !iport->isci_host)
-		return NULL;
-
-	return &iport->isci_host->pdev->dev;
-}
-
 static inline struct device *scirdev_to_dev(struct isci_remote_device *idev)
 {
 	if (!idev || !idev->isci_port || !idev->isci_port->isci_host)
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 17c4c2c..a98280d 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -60,6 +60,7 @@
 #include <linux/efi.h>
 #include <asm/string.h>
 #include <scsi/scsi_host.h>
+#include "host.h"
 #include "isci.h"
 #include "task.h"
 #include "probe_roms.h"
@@ -154,7 +155,6 @@ static struct scsi_host_template isci_sht = {
 	.queuecommand			= sas_queuecommand,
 	.target_alloc			= sas_target_alloc,
 	.slave_configure		= sas_slave_configure,
-	.slave_destroy			= sas_slave_destroy,
 	.scan_finished			= isci_host_scan_finished,
 	.scan_start			= isci_host_scan_start,
 	.change_queue_depth		= sas_change_queue_depth,
@@ -166,9 +166,9 @@ static struct scsi_host_template isci_sht = {
 	.sg_tablesize			= SG_ALL,
 	.max_sectors			= SCSI_DEFAULT_MAX_SECTORS,
 	.use_clustering			= ENABLE_CLUSTERING,
-	.eh_device_reset_handler	= sas_eh_device_reset_handler,
-	.eh_bus_reset_handler		= isci_bus_reset_handler,
-	.slave_alloc			= sas_slave_alloc,
+	.eh_abort_handler		= sas_eh_abort_handler,
+	.eh_device_reset_handler        = sas_eh_device_reset_handler,
+	.eh_bus_reset_handler           = sas_eh_bus_reset_handler,
 	.target_destroy			= sas_target_destroy,
 	.ioctl				= sas_ioctl,
 	.shost_attrs			= isci_host_attrs,
@@ -194,6 +194,9 @@ static struct sas_domain_function_template isci_transport_ops  = {
 	.lldd_lu_reset		= isci_task_lu_reset,
 	.lldd_query_task	= isci_task_query_task,
 
+	/* ata recovery called from ata-eh */
+	.lldd_ata_check_ready	= isci_ata_check_ready,
+
 	/* Port and Adapter management */
 	.lldd_clear_nexus_port	= isci_task_clear_nexus_port,
 	.lldd_clear_nexus_ha	= isci_task_clear_nexus_ha,
@@ -242,18 +245,13 @@ static int isci_register_sas_ha(struct isci_host *isci_host)
 	if (!sas_ports)
 		return -ENOMEM;
 
-	/*----------------- Libsas Initialization Stuff----------------------
-	 * Set various fields in the sas_ha struct:
-	 */
-
 	sas_ha->sas_ha_name = DRV_NAME;
 	sas_ha->lldd_module = THIS_MODULE;
 	sas_ha->sas_addr    = &isci_host->phys[0].sas_addr[0];
 
-	/* set the array of phy and port structs.  */
 	for (i = 0; i < SCI_MAX_PHYS; i++) {
 		sas_phys[i] = &isci_host->phys[i].sas_phy;
-		sas_ports[i] = &isci_host->ports[i].sas_port;
+		sas_ports[i] = &isci_host->sas_ports[i];
 	}
 
 	sas_ha->sas_phy  = sas_phys;
@@ -528,6 +526,13 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
 			goto err_host_alloc;
 		}
 		pci_info->hosts[i] = h;
+
+		/* turn on DIF support */
+		scsi_host_set_prot(h->shost,
+				   SHOST_DIF_TYPE1_PROTECTION |
+				   SHOST_DIF_TYPE2_PROTECTION |
+				   SHOST_DIF_TYPE3_PROTECTION);
+		scsi_host_set_guard(h->shost, SHOST_DIX_GUARD_CRC);
 	}
 
 	err = isci_setup_interrupts(pdev);
@@ -551,9 +556,9 @@ static void __devexit isci_pci_remove(struct pci_dev *pdev)
 	int i;
 
 	for_each_isci_host(i, ihost, pdev) {
+		wait_for_start(ihost);
 		isci_unregister(ihost);
 		isci_host_deinit(ihost);
-		sci_controller_disable_interrupts(ihost);
 	}
 }
 
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index fe18acf..fab3586 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -59,6 +59,16 @@
 #include "scu_event_codes.h"
 #include "probe_roms.h"
 
+#undef C
+#define C(a) (#a)
+static const char *phy_state_name(enum sci_phy_states state)
+{
+	static const char * const strings[] = PHY_STATES;
+
+	return strings[state];
+}
+#undef C
+
 /* Maximum arbitration wait time in micro-seconds */
 #define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME  (700)
 
@@ -67,6 +77,19 @@ enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy)
 	return iphy->max_negotiated_speed;
 }
 
+static struct isci_host *phy_to_host(struct isci_phy *iphy)
+{
+	struct isci_phy *table = iphy - iphy->phy_index;
+	struct isci_host *ihost = container_of(table, typeof(*ihost), phys[0]);
+
+	return ihost;
+}
+
+static struct device *sciphy_to_dev(struct isci_phy *iphy)
+{
+	return &phy_to_host(iphy)->pdev->dev;
+}
+
 static enum sci_status
 sci_phy_transport_layer_initialization(struct isci_phy *iphy,
 				       struct scu_transport_layer_registers __iomem *reg)
@@ -446,8 +469,8 @@ enum sci_status sci_phy_start(struct isci_phy *iphy)
 	enum sci_phy_states state = iphy->sm.current_state_id;
 
 	if (state != SCI_PHY_STOPPED) {
-		dev_dbg(sciphy_to_dev(iphy),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
+			__func__, phy_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -472,8 +495,8 @@ enum sci_status sci_phy_stop(struct isci_phy *iphy)
 	case SCI_PHY_READY:
 		break;
 	default:
-		dev_dbg(sciphy_to_dev(iphy),
-			"%s: in wrong state: %d\n", __func__, state);
+		dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
+			__func__, phy_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -486,8 +509,8 @@ enum sci_status sci_phy_reset(struct isci_phy *iphy)
 	enum sci_phy_states state = iphy->sm.current_state_id;
 
 	if (state != SCI_PHY_READY) {
-		dev_dbg(sciphy_to_dev(iphy),
-			"%s: in wrong state: %d\n", __func__, state);
+		dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
+			__func__, phy_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -536,8 +559,8 @@ enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy)
 		return SCI_SUCCESS;
 	}
 	default:
-		dev_dbg(sciphy_to_dev(iphy),
-			"%s: in wrong state: %d\n", __func__, state);
+		dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
+			__func__, phy_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -591,6 +614,60 @@ static void sci_phy_complete_link_training(struct isci_phy *iphy,
 	sci_change_state(&iphy->sm, next_state);
 }
 
+static const char *phy_event_name(u32 event_code)
+{
+	switch (scu_get_event_code(event_code)) {
+	case SCU_EVENT_PORT_SELECTOR_DETECTED:
+		return "port selector";
+	case SCU_EVENT_SENT_PORT_SELECTION:
+		return "port selection";
+	case SCU_EVENT_HARD_RESET_TRANSMITTED:
+		return "tx hard reset";
+	case SCU_EVENT_HARD_RESET_RECEIVED:
+		return "rx hard reset";
+	case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
+		return "identify timeout";
+	case SCU_EVENT_LINK_FAILURE:
+		return "link fail";
+	case SCU_EVENT_SATA_SPINUP_HOLD:
+		return "sata spinup hold";
+	case SCU_EVENT_SAS_15_SSC:
+	case SCU_EVENT_SAS_15:
+		return "sas 1.5";
+	case SCU_EVENT_SAS_30_SSC:
+	case SCU_EVENT_SAS_30:
+		return "sas 3.0";
+	case SCU_EVENT_SAS_60_SSC:
+	case SCU_EVENT_SAS_60:
+		return "sas 6.0";
+	case SCU_EVENT_SATA_15_SSC:
+	case SCU_EVENT_SATA_15:
+		return "sata 1.5";
+	case SCU_EVENT_SATA_30_SSC:
+	case SCU_EVENT_SATA_30:
+		return "sata 3.0";
+	case SCU_EVENT_SATA_60_SSC:
+	case SCU_EVENT_SATA_60:
+		return "sata 6.0";
+	case SCU_EVENT_SAS_PHY_DETECTED:
+		return "sas detect";
+	case SCU_EVENT_SATA_PHY_DETECTED:
+		return "sata detect";
+	default:
+		return "unknown";
+	}
+}
+
+#define phy_event_dbg(iphy, state, code) \
+	dev_dbg(sciphy_to_dev(iphy), "phy-%d:%d: %s event: %s (%x)\n", \
+		phy_to_host(iphy)->id, iphy->phy_index, \
+		phy_state_name(state), phy_event_name(code), code)
+
+#define phy_event_warn(iphy, state, code) \
+	dev_warn(sciphy_to_dev(iphy), "phy-%d:%d: %s event: %s (%x)\n", \
+		phy_to_host(iphy)->id, iphy->phy_index, \
+		phy_state_name(state), phy_event_name(code), code)
+
 enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 {
 	enum sci_phy_states state = iphy->sm.current_state_id;
@@ -607,11 +684,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			iphy->is_in_link_training = true;
 			break;
 		default:
-			dev_dbg(sciphy_to_dev(iphy),
-				"%s: PHY starting substate machine received "
-				"unexpected event_code %x\n",
-				__func__,
-				event_code);
+			phy_event_dbg(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 		return SCI_SUCCESS;
@@ -648,11 +721,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: PHY starting substate machine received "
-				 "unexpected event_code %x\n",
-				 __func__, event_code);
-
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 			break;
 		}
@@ -677,10 +746,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: PHY starting substate machine received "
-				 "unexpected event_code %x\n",
-				 __func__, event_code);
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 		return SCI_SUCCESS;
@@ -691,11 +757,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				"%s: PHY starting substate machine received unexpected "
-				"event_code %x\n",
-				__func__,
-				event_code);
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 		return SCI_SUCCESS;
@@ -719,11 +781,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			break;
 
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: PHY starting substate machine received "
-				 "unexpected event_code %x\n",
-				 __func__, event_code);
-
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 		return SCI_SUCCESS;
@@ -751,12 +809,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			sci_phy_start_sas_link_training(iphy);
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: PHY starting substate machine received "
-				 "unexpected event_code %x\n",
-				 __func__,
-				 event_code);
-
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 		return SCI_SUCCESS;
@@ -793,11 +846,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			sci_phy_start_sas_link_training(iphy);
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: PHY starting substate machine received "
-				 "unexpected event_code %x\n",
-				 __func__, event_code);
-
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 
@@ -815,12 +864,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			break;
 
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: PHY starting substate machine received "
-				 "unexpected event_code %x\n",
-				 __func__,
-				 event_code);
-
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE;
 		}
 		return SCI_SUCCESS;
@@ -838,10 +882,7 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 				iphy->bcn_received_while_port_unassigned = true;
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%sP SCIC PHY 0x%p ready state machine received "
-				 "unexpected event_code %x\n",
-				 __func__, iphy, event_code);
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE_INVALID_STATE;
 		}
 		return SCI_SUCCESS;
@@ -852,18 +893,14 @@ enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
 			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
 			break;
 		default:
-			dev_warn(sciphy_to_dev(iphy),
-				 "%s: SCIC PHY 0x%p resetting state machine received "
-				 "unexpected event_code %x\n",
-				 __func__, iphy, event_code);
-
+			phy_event_warn(iphy, state, event_code);
 			return SCI_FAILURE_INVALID_STATE;
 			break;
 		}
 		return SCI_SUCCESS;
 	default:
-		dev_dbg(sciphy_to_dev(iphy),
-			"%s: in wrong state: %d\n", __func__, state);
+		dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
+			__func__, phy_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -956,8 +993,8 @@ enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index)
 		return result;
 	}
 	default:
-		dev_dbg(sciphy_to_dev(iphy),
-			"%s: in wrong state: %d\n", __func__, state);
+		dev_dbg(sciphy_to_dev(iphy), "%s: in wrong state: %s\n",
+			__func__, phy_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -1299,7 +1336,6 @@ void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
 	sas_addr = cpu_to_be64(sci_sas_addr);
 	memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
 
-	iphy->isci_port = NULL;
 	iphy->sas_phy.enabled = 0;
 	iphy->sas_phy.id = index;
 	iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
@@ -1333,13 +1369,13 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
 {
 	int ret = 0;
 	struct isci_phy *iphy = sas_phy->lldd_phy;
-	struct isci_port *iport = iphy->isci_port;
+	struct asd_sas_port *port = sas_phy->port;
 	struct isci_host *ihost = sas_phy->ha->lldd_ha;
 	unsigned long flags;
 
 	dev_dbg(&ihost->pdev->dev,
 		"%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
-		__func__, sas_phy, func, buf, iphy, iport);
+		__func__, sas_phy, func, buf, iphy, port);
 
 	switch (func) {
 	case PHY_FUNC_DISABLE:
@@ -1356,11 +1392,10 @@ int isci_phy_control(struct asd_sas_phy *sas_phy,
 		break;
 
 	case PHY_FUNC_HARD_RESET:
-		if (!iport)
+		if (!port)
 			return -ENODEV;
 
-		/* Perform the port reset. */
-		ret = isci_port_perform_hard_reset(ihost, iport, iphy);
+		ret = isci_port_perform_hard_reset(ihost, port->lldd_port, iphy);
 
 		break;
 	case PHY_FUNC_GET_EVENTS: {
diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h
index 67699c8..0e45833 100644
--- a/drivers/scsi/isci/phy.h
+++ b/drivers/scsi/isci/phy.h
@@ -103,7 +103,6 @@ struct isci_phy {
 	struct scu_transport_layer_registers __iomem *transport_layer_registers;
 	struct scu_link_layer_registers __iomem *link_layer_registers;
 	struct asd_sas_phy sas_phy;
-	struct isci_port *isci_port;
 	u8 sas_addr[SAS_ADDR_SIZE];
 	union {
 		struct sas_identify_frame iaf;
@@ -344,101 +343,65 @@ enum sci_phy_counter_id {
 	SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR
 };
 
-enum sci_phy_states {
-	/**
-	 * Simply the initial state for the base domain state machine.
-	 */
-	SCI_PHY_INITIAL,
-
-	/**
-	 * This state indicates that the phy has successfully been stopped.
-	 * In this state no new IO operations are permitted on this phy.
-	 * This state is entered from the INITIAL state.
-	 * This state is entered from the STARTING state.
-	 * This state is entered from the READY state.
-	 * This state is entered from the RESETTING state.
-	 */
-	SCI_PHY_STOPPED,
-
-	/**
-	 * This state indicates that the phy is in the process of becomming
-	 * ready.  In this state no new IO operations are permitted on this phy.
-	 * This state is entered from the STOPPED state.
-	 * This state is entered from the READY state.
-	 * This state is entered from the RESETTING state.
-	 */
-	SCI_PHY_STARTING,
-
-	/**
-	 * Initial state
-	 */
-	SCI_PHY_SUB_INITIAL,
-
-	/**
-	 * Wait state for the hardware OSSP event type notification
-	 */
-	SCI_PHY_SUB_AWAIT_OSSP_EN,
-
-	/**
-	 * Wait state for the PHY speed notification
-	 */
-	SCI_PHY_SUB_AWAIT_SAS_SPEED_EN,
-
-	/**
-	 * Wait state for the IAF Unsolicited frame notification
-	 */
-	SCI_PHY_SUB_AWAIT_IAF_UF,
-
-	/**
-	 * Wait state for the request to consume power
-	 */
-	SCI_PHY_SUB_AWAIT_SAS_POWER,
-
-	/**
-	 * Wait state for request to consume power
-	 */
-	SCI_PHY_SUB_AWAIT_SATA_POWER,
-
-	/**
-	 * Wait state for the SATA PHY notification
-	 */
-	SCI_PHY_SUB_AWAIT_SATA_PHY_EN,
-
-	/**
-	 * Wait for the SATA PHY speed notification
-	 */
-	SCI_PHY_SUB_AWAIT_SATA_SPEED_EN,
-
-	/**
-	 * Wait state for the SIGNATURE FIS unsolicited frame notification
-	 */
-	SCI_PHY_SUB_AWAIT_SIG_FIS_UF,
-
-	/**
-	 * Exit state for this state machine
-	 */
-	SCI_PHY_SUB_FINAL,
-
-	/**
-	 * This state indicates the the phy is now ready.  Thus, the user
-	 * is able to perform IO operations utilizing this phy as long as it
-	 * is currently part of a valid port.
-	 * This state is entered from the STARTING state.
-	 */
-	SCI_PHY_READY,
-
-	/**
-	 * This state indicates that the phy is in the process of being reset.
-	 * In this state no new IO operations are permitted on this phy.
-	 * This state is entered from the READY state.
-	 */
-	SCI_PHY_RESETTING,
-
-	/**
-	 * Simply the final state for the base phy state machine.
-	 */
-	SCI_PHY_FINAL,
-};
+/**
+ * enum sci_phy_states - phy state machine states
+ * @SCI_PHY_INITIAL: Simply the initial state for the base domain state
+ *		     machine.
+ * @SCI_PHY_STOPPED: phy has successfully been stopped.  In this state
+ *		     no new IO operations are permitted on this phy.
+ * @SCI_PHY_STARTING: the phy is in the process of becomming ready.  In
+ *		      this state no new IO operations are permitted on
+ *		      this phy.
+ * @SCI_PHY_SUB_INITIAL: Initial state
+ * @SCI_PHY_SUB_AWAIT_OSSP_EN: Wait state for the hardware OSSP event
+ *			       type notification
+ * @SCI_PHY_SUB_AWAIT_SAS_SPEED_EN: Wait state for the PHY speed
+ *				    notification
+ * @SCI_PHY_SUB_AWAIT_IAF_UF: Wait state for the IAF Unsolicited frame
+ *			      notification
+ * @SCI_PHY_SUB_AWAIT_SAS_POWER: Wait state for the request to consume
+ *				 power
+ * @SCI_PHY_SUB_AWAIT_SATA_POWER: Wait state for request to consume
+ *				  power
+ * @SCI_PHY_SUB_AWAIT_SATA_PHY_EN: Wait state for the SATA PHY
+ *				   notification
+ * @SCI_PHY_SUB_AWAIT_SATA_SPEED_EN: Wait for the SATA PHY speed
+ *				     notification
+ * @SCI_PHY_SUB_AWAIT_SIG_FIS_UF: Wait state for the SIGNATURE FIS
+ *				  unsolicited frame notification
+ * @SCI_PHY_SUB_FINAL: Exit state for this state machine
+ * @SCI_PHY_READY: phy is now ready.  Thus, the user is able to perform
+ *		   IO operations utilizing this phy as long as it is
+ *		   currently part of a valid port.  This state is
+ *		   entered from the STARTING state.
+ * @SCI_PHY_RESETTING: phy is in the process of being reset.  In this
+ *		       state no new IO operations are permitted on this
+ *		       phy.  This state is entered from the READY state.
+ * @SCI_PHY_FINAL: Simply the final state for the base phy state
+ *		   machine.
+ */
+#define PHY_STATES {\
+	C(PHY_INITIAL),\
+	C(PHY_STOPPED),\
+	C(PHY_STARTING),\
+	C(PHY_SUB_INITIAL),\
+	C(PHY_SUB_AWAIT_OSSP_EN),\
+	C(PHY_SUB_AWAIT_SAS_SPEED_EN),\
+	C(PHY_SUB_AWAIT_IAF_UF),\
+	C(PHY_SUB_AWAIT_SAS_POWER),\
+	C(PHY_SUB_AWAIT_SATA_POWER),\
+	C(PHY_SUB_AWAIT_SATA_PHY_EN),\
+	C(PHY_SUB_AWAIT_SATA_SPEED_EN),\
+	C(PHY_SUB_AWAIT_SIG_FIS_UF),\
+	C(PHY_SUB_FINAL),\
+	C(PHY_READY),\
+	C(PHY_RESETTING),\
+	C(PHY_FINAL),\
+	}
+#undef C
+#define C(a) SCI_##a
+enum sci_phy_states PHY_STATES;
+#undef C
 
 void sci_phy_construct(
 	struct isci_phy *iphy,
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index 7c6ac58..5fada73 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -60,18 +60,29 @@
 #define SCIC_SDS_PORT_HARD_RESET_TIMEOUT  (1000)
 #define SCU_DUMMY_INDEX    (0xFFFF)
 
-static void isci_port_change_state(struct isci_port *iport, enum isci_status status)
+#undef C
+#define C(a) (#a)
+const char *port_state_name(enum sci_port_states state)
 {
-	unsigned long flags;
+	static const char * const strings[] = PORT_STATES;
+
+	return strings[state];
+}
+#undef C
+
+static struct device *sciport_to_dev(struct isci_port *iport)
+{
+	int i = iport->physical_port_index;
+	struct isci_port *table;
+	struct isci_host *ihost;
+
+	if (i == SCIC_SDS_DUMMY_PORT)
+		i = SCI_MAX_PORTS+1;
 
-	dev_dbg(&iport->isci_host->pdev->dev,
-		"%s: iport = %p, state = 0x%x\n",
-		__func__, iport, status);
+	table = iport - i;
+	ihost = container_of(table, typeof(*ihost), ports[0]);
 
-	/* XXX pointless lock */
-	spin_lock_irqsave(&iport->state_lock, flags);
-	iport->status = status;
-	spin_unlock_irqrestore(&iport->state_lock, flags);
+	return &ihost->pdev->dev;
 }
 
 static void sci_port_get_protocols(struct isci_port *iport, struct sci_phy_proto *proto)
@@ -165,18 +176,12 @@ static void isci_port_link_up(struct isci_host *isci_host,
 	struct sci_port_properties properties;
 	unsigned long success = true;
 
-	BUG_ON(iphy->isci_port != NULL);
-
-	iphy->isci_port = iport;
-
 	dev_dbg(&isci_host->pdev->dev,
 		"%s: isci_port = %p\n",
 		__func__, iport);
 
 	spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
 
-	isci_port_change_state(iphy->isci_port, isci_starting);
-
 	sci_port_get_properties(iport, &properties);
 
 	if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
@@ -258,7 +263,6 @@ static void isci_port_link_down(struct isci_host *isci_host,
 					__func__, isci_device);
 				set_bit(IDEV_GONE, &isci_device->flags);
 			}
-			isci_port_change_state(isci_port, isci_stopping);
 		}
 	}
 
@@ -269,52 +273,10 @@ static void isci_port_link_down(struct isci_host *isci_host,
 	isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
 					   PHYE_LOSS_OF_SIGNAL);
 
-	isci_phy->isci_port = NULL;
-
 	dev_dbg(&isci_host->pdev->dev,
 		"%s: isci_port = %p - Done\n", __func__, isci_port);
 }
 
-
-/**
- * isci_port_ready() - This function is called by the sci core when a link
- *    becomes ready.
- * @isci_host: This parameter specifies the isci host object.
- * @port: This parameter specifies the sci port with the active link.
- *
- */
-static void isci_port_ready(struct isci_host *isci_host, struct isci_port *isci_port)
-{
-	dev_dbg(&isci_host->pdev->dev,
-		"%s: isci_port = %p\n", __func__, isci_port);
-
-	complete_all(&isci_port->start_complete);
-	isci_port_change_state(isci_port, isci_ready);
-	return;
-}
-
-/**
- * isci_port_not_ready() - This function is called by the sci core when a link
- *    is not ready. All remote devices on this link will be removed if they are
- *    in the stopping state.
- * @isci_host: This parameter specifies the isci host object.
- * @port: This parameter specifies the sci port with the active link.
- *
- */
-static void isci_port_not_ready(struct isci_host *isci_host, struct isci_port *isci_port)
-{
-	dev_dbg(&isci_host->pdev->dev,
-		"%s: isci_port = %p\n", __func__, isci_port);
-}
-
-static void isci_port_stop_complete(struct isci_host *ihost,
-				    struct isci_port *iport,
-				    enum sci_status completion_status)
-{
-	dev_dbg(&ihost->pdev->dev, "Port stop complete\n");
-}
-
-
 static bool is_port_ready_state(enum sci_port_states state)
 {
 	switch (state) {
@@ -353,7 +315,9 @@ static void port_state_machine_change(struct isci_port *iport,
 static void isci_port_hard_reset_complete(struct isci_port *isci_port,
 					  enum sci_status completion_status)
 {
-	dev_dbg(&isci_port->isci_host->pdev->dev,
+	struct isci_host *ihost = isci_port->owning_controller;
+
+	dev_dbg(&ihost->pdev->dev,
 		"%s: isci_port = %p, completion_status=%x\n",
 		     __func__, isci_port, completion_status);
 
@@ -364,23 +328,24 @@ static void isci_port_hard_reset_complete(struct isci_port *isci_port,
 
 		/* The reset failed.  The port state is now SCI_PORT_FAILED. */
 		if (isci_port->active_phy_mask == 0) {
+			int phy_idx = isci_port->last_active_phy;
+			struct isci_phy *iphy = &ihost->phys[phy_idx];
 
 			/* Generate the link down now to the host, since it
 			 * was intercepted by the hard reset state machine when
 			 * it really happened.
 			 */
-			isci_port_link_down(isci_port->isci_host,
-					    &isci_port->isci_host->phys[
-						   isci_port->last_active_phy],
-					    isci_port);
+			isci_port_link_down(ihost, iphy, isci_port);
 		}
 		/* Advance the port state so that link state changes will be
-		* noticed.
-		*/
+		 * noticed.
+		 */
 		port_state_machine_change(isci_port, SCI_PORT_SUB_WAITING);
 
 	}
-	complete_all(&isci_port->hard_reset_complete);
+	clear_bit(IPORT_RESET_PENDING, &isci_port->state);
+	wake_up(&ihost->eventq);
+
 }
 
 /* This method will return a true value if the specified phy can be assigned to
@@ -835,10 +800,9 @@ static void port_timeout(unsigned long data)
 			__func__,
 			iport);
 	} else if (current_state == SCI_PORT_STOPPING) {
-		/* if the port is still stopping then the stop has not completed */
-		isci_port_stop_complete(iport->owning_controller,
-					iport,
-					SCI_FAILURE_TIMEOUT);
+		dev_dbg(sciport_to_dev(iport),
+			"%s: port%d: stop complete timeout\n",
+			__func__, iport->physical_port_index);
 	} else {
 		/* The port is in the ready state and we have a timer
 		 * reporting a timeout this should not happen.
@@ -1003,7 +967,8 @@ static void sci_port_ready_substate_operational_enter(struct sci_base_state_mach
 	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
 	struct isci_host *ihost = iport->owning_controller;
 
-	isci_port_ready(ihost, iport);
+	dev_dbg(&ihost->pdev->dev, "%s: port%d ready\n",
+		__func__, iport->physical_port_index);
 
 	for (index = 0; index < SCI_MAX_PHYS; index++) {
 		if (iport->phy_table[index]) {
@@ -1069,7 +1034,8 @@ static void sci_port_ready_substate_operational_exit(struct sci_base_state_machi
 	 */
 	sci_port_abort_dummy_request(iport);
 
-	isci_port_not_ready(ihost, iport);
+	dev_dbg(&ihost->pdev->dev, "%s: port%d !ready\n",
+		__func__, iport->physical_port_index);
 
 	if (iport->ready_exit)
 		sci_port_invalidate_dummy_remote_node(iport);
@@ -1081,7 +1047,8 @@ static void sci_port_ready_substate_configuring_enter(struct sci_base_state_mach
 	struct isci_host *ihost = iport->owning_controller;
 
 	if (iport->active_phy_mask == 0) {
-		isci_port_not_ready(ihost, iport);
+		dev_dbg(&ihost->pdev->dev, "%s: port%d !ready\n",
+			__func__, iport->physical_port_index);
 
 		port_state_machine_change(iport, SCI_PORT_SUB_WAITING);
 	} else
@@ -1097,8 +1064,8 @@ enum sci_status sci_port_start(struct isci_port *iport)
 
 	state = iport->sm.current_state_id;
 	if (state != SCI_PORT_STOPPED) {
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -1172,8 +1139,8 @@ enum sci_status sci_port_stop(struct isci_port *iport)
 					  SCI_PORT_STOPPING);
 		return SCI_SUCCESS;
 	default:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -1187,8 +1154,8 @@ static enum sci_status sci_port_hard_reset(struct isci_port *iport, u32 timeout)
 
 	state = iport->sm.current_state_id;
 	if (state != SCI_PORT_SUB_OPERATIONAL) {
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -1282,8 +1249,8 @@ enum sci_status sci_port_add_phy(struct isci_port *iport,
 					  SCI_PORT_SUB_CONFIGURING);
 		return SCI_SUCCESS;
 	default:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -1332,8 +1299,8 @@ enum sci_status sci_port_remove_phy(struct isci_port *iport,
 					  SCI_PORT_SUB_CONFIGURING);
 		return SCI_SUCCESS;
 	default:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -1375,8 +1342,8 @@ enum sci_status sci_port_link_up(struct isci_port *iport,
 		sci_port_general_link_up_handler(iport, iphy, PF_RESUME);
 		return SCI_SUCCESS;
 	default:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -1405,8 +1372,8 @@ enum sci_status sci_port_link_down(struct isci_port *iport,
 		sci_port_deactivate_phy(iport, iphy, false);
 		return SCI_SUCCESS;
 	default:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -1425,8 +1392,8 @@ enum sci_status sci_port_start_io(struct isci_port *iport,
 		iport->started_request_count++;
 		return SCI_SUCCESS;
 	default:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -1440,8 +1407,8 @@ enum sci_status sci_port_complete_io(struct isci_port *iport,
 	state = iport->sm.current_state_id;
 	switch (state) {
 	case SCI_PORT_STOPPED:
-		dev_warn(sciport_to_dev(iport),
-			 "%s: in wrong state: %d\n", __func__, state);
+		dev_warn(sciport_to_dev(iport), "%s: in wrong state: %s\n",
+			 __func__, port_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	case SCI_PORT_STOPPING:
 		sci_port_decrement_request_count(iport);
@@ -1547,7 +1514,8 @@ static void sci_port_ready_state_enter(struct sci_base_state_machine *sm)
 	if (prev_state  == SCI_PORT_RESETTING)
 		isci_port_hard_reset_complete(iport, SCI_SUCCESS);
 	else
-		isci_port_not_ready(ihost, iport);
+		dev_dbg(&ihost->pdev->dev, "%s: port%d !ready\n",
+			__func__, iport->physical_port_index);
 
 	/* Post and suspend the dummy remote node context for this port. */
 	sci_port_post_dummy_remote_node(iport);
@@ -1644,22 +1612,7 @@ void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
 {
 	INIT_LIST_HEAD(&iport->remote_dev_list);
 	INIT_LIST_HEAD(&iport->domain_dev_list);
-	spin_lock_init(&iport->state_lock);
-	init_completion(&iport->start_complete);
 	iport->isci_host = ihost;
-	isci_port_change_state(iport, isci_freed);
-}
-
-/**
- * isci_port_get_state() - This function gets the status of the port object.
- * @isci_port: This parameter points to the isci_port object
- *
- * status of the object as a isci_status enum.
- */
-enum isci_status isci_port_get_state(
-	struct isci_port *isci_port)
-{
-	return isci_port->status;
 }
 
 void sci_port_broadcast_change_received(struct isci_port *iport, struct isci_phy *iphy)
@@ -1670,6 +1623,11 @@ void sci_port_broadcast_change_received(struct isci_port *iport, struct isci_phy
 	isci_port_bc_change_received(ihost, iport, iphy);
 }
 
+static void wait_port_reset(struct isci_host *ihost, struct isci_port *iport)
+{
+	wait_event(ihost->eventq, !test_bit(IPORT_RESET_PENDING, &iport->state));
+}
+
 int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
 				 struct isci_phy *iphy)
 {
@@ -1680,9 +1638,8 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
 	dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
 		__func__, iport);
 
-	init_completion(&iport->hard_reset_complete);
-
 	spin_lock_irqsave(&ihost->scic_lock, flags);
+	set_bit(IPORT_RESET_PENDING, &iport->state);
 
 	#define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
 	status = sci_port_hard_reset(iport, ISCI_PORT_RESET_TIMEOUT);
@@ -1690,7 +1647,7 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
 	spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
 	if (status == SCI_SUCCESS) {
-		wait_for_completion(&iport->hard_reset_complete);
+		wait_port_reset(ihost, iport);
 
 		dev_dbg(&ihost->pdev->dev,
 			"%s: iport = %p; hard reset completion\n",
@@ -1704,6 +1661,8 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
 				__func__, iport, iport->hard_reset_status);
 		}
 	} else {
+		clear_bit(IPORT_RESET_PENDING, &iport->state);
+		wake_up(&ihost->eventq);
 		ret = TMF_RESP_FUNC_FAILED;
 
 		dev_err(&ihost->pdev->dev,
@@ -1726,24 +1685,80 @@ int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *ipor
 	return ret;
 }
 
-/**
- * isci_port_deformed() - This function is called by libsas when a port becomes
- *    inactive.
- * @phy: This parameter specifies the libsas phy with the inactive port.
- *
- */
+int isci_ata_check_ready(struct domain_device *dev)
+{
+	struct isci_port *iport = dev->port->lldd_port;
+	struct isci_host *ihost = dev_to_ihost(dev);
+	struct isci_remote_device *idev;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	idev = isci_lookup_device(dev);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (!idev)
+		goto out;
+
+	if (test_bit(IPORT_RESET_PENDING, &iport->state))
+		goto out;
+
+	rc = !!iport->active_phy_mask;
+ out:
+	isci_put_device(idev);
+
+	return rc;
+}
+
 void isci_port_deformed(struct asd_sas_phy *phy)
 {
-	pr_debug("%s: sas_phy = %p\n", __func__, phy);
+	struct isci_host *ihost = phy->ha->lldd_ha;
+	struct isci_port *iport = phy->port->lldd_port;
+	unsigned long flags;
+	int i;
+
+	/* we got a port notification on a port that was subsequently
+	 * torn down and libsas is just now catching up
+	 */
+	if (!iport)
+		return;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+		if (iport->active_phy_mask & 1 << i)
+			break;
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (i >= SCI_MAX_PHYS)
+		dev_dbg(&ihost->pdev->dev, "%s: port: %ld\n",
+			__func__, (long) (iport - &ihost->ports[0]));
 }
 
-/**
- * isci_port_formed() - This function is called by libsas when a port becomes
- *    active.
- * @phy: This parameter specifies the libsas phy with the active port.
- *
- */
 void isci_port_formed(struct asd_sas_phy *phy)
 {
-	pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port);
+	struct isci_host *ihost = phy->ha->lldd_ha;
+	struct isci_phy *iphy = to_iphy(phy);
+	struct asd_sas_port *port = phy->port;
+	struct isci_port *iport;
+	unsigned long flags;
+	int i;
+
+	/* initial ports are formed as the driver is still initializing,
+	 * wait for that process to complete
+	 */
+	wait_for_start(ihost);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	for (i = 0; i < SCI_MAX_PORTS; i++) {
+		iport = &ihost->ports[i];
+		if (iport->active_phy_mask & 1 << iphy->phy_index)
+			break;
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (i >= SCI_MAX_PORTS)
+		iport = NULL;
+
+	port->lldd_port = iport;
 }
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h
index 0811609..6b56240 100644
--- a/drivers/scsi/isci/port.h
+++ b/drivers/scsi/isci/port.h
@@ -95,14 +95,11 @@ enum isci_status {
  * @timer: timeout start/stop operations
  */
 struct isci_port {
-	enum isci_status status;
 	struct isci_host *isci_host;
-	struct asd_sas_port sas_port;
 	struct list_head remote_dev_list;
-	spinlock_t state_lock;
 	struct list_head domain_dev_list;
-	struct completion start_complete;
-	struct completion hard_reset_complete;
+	#define IPORT_RESET_PENDING 0
+	unsigned long state;
 	enum sci_status hard_reset_status;
 	struct sci_base_state_machine sm;
 	bool ready_exit;
@@ -147,70 +144,47 @@ struct sci_port_properties {
 };
 
 /**
- * enum sci_port_states - This enumeration depicts all the states for the
- *    common port state machine.
- *
- *
+ * enum sci_port_states - port state machine states
+ * @SCI_PORT_STOPPED: port has successfully been stopped.  In this state
+ *		      no new IO operations are permitted.  This state is
+ *		      entered from the STOPPING state.
+ * @SCI_PORT_STOPPING: port is in the process of stopping.  In this
+ *		       state no new IO operations are permitted, but
+ *		       existing IO operations are allowed to complete.
+ *		       This state is entered from the READY state.
+ * @SCI_PORT_READY: port is now ready.  Thus, the user is able to
+ *		    perform IO operations on this port. This state is
+ *		    entered from the STARTING state.
+ * @SCI_PORT_SUB_WAITING: port is started and ready but has no active
+ *			  phys.
+ * @SCI_PORT_SUB_OPERATIONAL: port is started and ready and there is at
+ *			      least one phy operational.
+ * @SCI_PORT_SUB_CONFIGURING: port is started and there was an
+ *			      add/remove phy event.  This state is only
+ *			      used in Automatic Port Configuration Mode
+ *			      (APC)
+ * @SCI_PORT_RESETTING: port is in the process of performing a hard
+ *			reset.  Thus, the user is unable to perform IO
+ *			operations on this port.  This state is entered
+ *			from the READY state.
+ * @SCI_PORT_FAILED: port has failed a reset request.  This state is
+ *		     entered when a port reset request times out. This
+ *		     state is entered from the RESETTING state.
  */
-enum sci_port_states {
-	/**
-	 * This state indicates that the port has successfully been stopped.
-	 * In this state no new IO operations are permitted.
-	 * This state is entered from the STOPPING state.
-	 */
-	SCI_PORT_STOPPED,
-
-	/**
-	 * This state indicates that the port is in the process of stopping.
-	 * In this state no new IO operations are permitted, but existing IO
-	 * operations are allowed to complete.
-	 * This state is entered from the READY state.
-	 */
-	SCI_PORT_STOPPING,
-
-	/**
-	 * This state indicates the port is now ready.  Thus, the user is
-	 * able to perform IO operations on this port.
-	 * This state is entered from the STARTING state.
-	 */
-	SCI_PORT_READY,
-
-	/**
-	 * The substate where the port is started and ready but has no
-	 * active phys.
-	 */
-	SCI_PORT_SUB_WAITING,
-
-	/**
-	 * The substate where the port is started and ready and there is
-	 * at least one phy operational.
-	 */
-	SCI_PORT_SUB_OPERATIONAL,
-
-	/**
-	 * The substate where the port is started and there was an
-	 * add/remove phy event.  This state is only used in Automatic
-	 * Port Configuration Mode (APC)
-	 */
-	SCI_PORT_SUB_CONFIGURING,
-
-	/**
-	 * This state indicates the port is in the process of performing a hard
-	 * reset.  Thus, the user is unable to perform IO operations on this
-	 * port.
-	 * This state is entered from the READY state.
-	 */
-	SCI_PORT_RESETTING,
-
-	/**
-	 * This state indicates the port has failed a reset request.  This state
-	 * is entered when a port reset request times out.
-	 * This state is entered from the RESETTING state.
-	 */
-	SCI_PORT_FAILED,
-
-
-};
+#define PORT_STATES {\
+	C(PORT_STOPPED),\
+	C(PORT_STOPPING),\
+	C(PORT_READY),\
+	C(PORT_SUB_WAITING),\
+	C(PORT_SUB_OPERATIONAL),\
+	C(PORT_SUB_CONFIGURING),\
+	C(PORT_RESETTING),\
+	C(PORT_FAILED),\
+	}
+#undef C
+#define C(a) SCI_##a
+enum sci_port_states PORT_STATES;
+#undef C
 
 static inline void sci_port_decrement_request_count(struct isci_port *iport)
 {
@@ -296,9 +270,6 @@ void sci_port_get_attached_sas_address(
 	struct isci_port *iport,
 	struct sci_sas_address *sas_address);
 
-enum isci_status isci_port_get_state(
-	struct isci_port *isci_port);
-
 void isci_port_formed(struct asd_sas_phy *);
 void isci_port_deformed(struct asd_sas_phy *);
 
@@ -309,4 +280,5 @@ void isci_port_init(
 
 int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
 				 struct isci_phy *iphy);
+int isci_ata_check_ready(struct domain_device *dev);
 #endif /* !defined(_ISCI_PORT_H_) */
diff --git a/drivers/scsi/isci/registers.h b/drivers/scsi/isci/registers.h
index eaa541a..7eb0ccd 100644
--- a/drivers/scsi/isci/registers.h
+++ b/drivers/scsi/isci/registers.h
@@ -370,6 +370,27 @@ struct scu_iit_entry {
 		>> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT \
 	)
 
+/* ***************************************************************************** */
+#define SMU_CLOCK_GATING_CONTROL_IDLE_ENABLE_SHIFT    (0)
+#define SMU_CLOCK_GATING_CONTROL_IDLE_ENABLE_MASK     (0x00000001)
+#define SMU_CLOCK_GATING_CONTROL_XCLK_ENABLE_SHIFT    (1)
+#define SMU_CLOCK_GATING_CONTROL_XCLK_ENABLE_MASK     (0x00000002)
+#define SMU_CLOCK_GATING_CONTROL_TXCLK_ENABLE_SHIFT   (2)
+#define SMU_CLOCK_GATING_CONTROL_TXCLK_ENABLE_MASK    (0x00000004)
+#define SMU_CLOCK_GATING_CONTROL_REGCLK_ENABLE_SHIFT  (3)
+#define SMU_CLOCK_GATING_CONTROL_REGCLK_ENABLE_MASK   (0x00000008)
+#define SMU_CLOCK_GATING_CONTROL_IDLE_TIMEOUT_SHIFT   (16)
+#define SMU_CLOCK_GATING_CONTROL_IDLE_TIMEOUT_MASK    (0x000F0000)
+#define SMU_CLOCK_GATING_CONTROL_FORCE_IDLE_SHIFT     (31)
+#define SMU_CLOCK_GATING_CONTROL_FORCE_IDLE_MASK      (0x80000000)
+#define SMU_CLOCK_GATING_CONTROL_RESERVED_MASK        (0x7FF0FFF0)
+
+#define SMU_CGUCR_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_CLOCK_GATING_CONTROL_##name, value)
+
+#define SMU_CGUCR_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_CLOCK_GATING_CONTROL_##name)
+
 /* -------------------------------------------------------------------------- */
 
 #define SMU_CONTROL_STATUS_TASK_CONTEXT_RANGE_ENABLE_SHIFT      (0)
@@ -992,8 +1013,10 @@ struct smu_registers {
 	u32 mmr_address_window;
 /* 0x00A4 SMDW */
 	u32 mmr_data_window;
-	u32 reserved_A8;
-	u32 reserved_AC;
+/* 0x00A8 CGUCR */
+	u32 clock_gating_control;
+/* 0x00AC CGUPC */
+	u32 clock_gating_performance;
 /* A whole bunch of reserved space */
 	u32 reserved_Bx[4];
 	u32 reserved_Cx[4];
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
index dd74b6c..8f501b0 100644
--- a/drivers/scsi/isci/remote_device.c
+++ b/drivers/scsi/isci/remote_device.c
@@ -62,6 +62,16 @@
 #include "scu_event_codes.h"
 #include "task.h"
 
+#undef C
+#define C(a) (#a)
+const char *dev_state_name(enum sci_remote_device_states state)
+{
+	static const char * const strings[] = REMOTE_DEV_STATES;
+
+	return strings[state];
+}
+#undef C
+
 /**
  * isci_remote_device_not_ready() - This function is called by the ihost when
  *    the remote device is not ready. We mark the isci device as ready (not
@@ -167,8 +177,8 @@ enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
 	case SCI_DEV_FAILED:
 	case SCI_DEV_FINAL:
 	default:
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	case SCI_DEV_STOPPED:
 		return SCI_SUCCESS;
@@ -226,8 +236,8 @@ enum sci_status sci_remote_device_reset(struct isci_remote_device *idev)
 	case SCI_DEV_RESETTING:
 	case SCI_DEV_FINAL:
 	default:
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	case SCI_DEV_READY:
 	case SCI_STP_DEV_IDLE:
@@ -246,8 +256,8 @@ enum sci_status sci_remote_device_reset_complete(struct isci_remote_device *idev
 	enum sci_remote_device_states state = sm->current_state_id;
 
 	if (state != SCI_DEV_RESETTING) {
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -262,8 +272,8 @@ enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
 	enum sci_remote_device_states state = sm->current_state_id;
 
 	if (state != SCI_STP_DEV_CMD) {
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -287,8 +297,8 @@ enum sci_status sci_remote_device_frame_handler(struct isci_remote_device *idev,
 	case SCI_SMP_DEV_IDLE:
 	case SCI_DEV_FINAL:
 	default:
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		/* Return the frame back to the controller */
 		sci_controller_release_frame(ihost, frame_index);
 		return SCI_FAILURE_INVALID_STATE;
@@ -502,8 +512,8 @@ enum sci_status sci_remote_device_start_io(struct isci_host *ihost,
 	case SCI_DEV_RESETTING:
 	case SCI_DEV_FINAL:
 	default:
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	case SCI_DEV_READY:
 		/* attempt to start an io request for this device object. The remote
@@ -637,8 +647,8 @@ enum sci_status sci_remote_device_complete_io(struct isci_host *ihost,
 	case SCI_DEV_FAILED:
 	case SCI_DEV_FINAL:
 	default:
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	case SCI_DEV_READY:
 	case SCI_STP_DEV_AWAIT_RESET:
@@ -721,8 +731,8 @@ enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
 	case SCI_DEV_RESETTING:
 	case SCI_DEV_FINAL:
 	default:
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	case SCI_STP_DEV_IDLE:
 	case SCI_STP_DEV_CMD:
@@ -853,8 +863,8 @@ static enum sci_status sci_remote_device_destruct(struct isci_remote_device *ide
 	struct isci_host *ihost;
 
 	if (state != SCI_DEV_STOPPED) {
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -1204,8 +1214,8 @@ static enum sci_status sci_remote_device_start(struct isci_remote_device *idev,
 	enum sci_status status;
 
 	if (state != SCI_DEV_STOPPED) {
-		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
-			 __func__, state);
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
+			 __func__, dev_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 
@@ -1308,7 +1318,6 @@ void isci_remote_device_release(struct kref *kref)
 	clear_bit(IDEV_STOP_PENDING, &idev->flags);
 	clear_bit(IDEV_IO_READY, &idev->flags);
 	clear_bit(IDEV_GONE, &idev->flags);
-	clear_bit(IDEV_EH, &idev->flags);
 	smp_mb__before_clear_bit();
 	clear_bit(IDEV_ALLOCATED, &idev->flags);
 	wake_up(&ihost->eventq);
@@ -1381,34 +1390,17 @@ void isci_remote_device_gone(struct domain_device *dev)
  *
  * status, zero indicates success.
  */
-int isci_remote_device_found(struct domain_device *domain_dev)
+int isci_remote_device_found(struct domain_device *dev)
 {
-	struct isci_host *isci_host = dev_to_ihost(domain_dev);
-	struct isci_port *isci_port;
-	struct isci_phy *isci_phy;
-	struct asd_sas_port *sas_port;
-	struct asd_sas_phy *sas_phy;
+	struct isci_host *isci_host = dev_to_ihost(dev);
+	struct isci_port *isci_port = dev->port->lldd_port;
 	struct isci_remote_device *isci_device;
 	enum sci_status status;
 
 	dev_dbg(&isci_host->pdev->dev,
-		"%s: domain_device = %p\n", __func__, domain_dev);
-
-	wait_for_start(isci_host);
-
-	sas_port = domain_dev->port;
-	sas_phy = list_first_entry(&sas_port->phy_list, struct asd_sas_phy,
-				   port_phy_el);
-	isci_phy = to_iphy(sas_phy);
-	isci_port = isci_phy->isci_port;
-
-	/* we are being called for a device on this port,
-	 * so it has to come up eventually
-	 */
-	wait_for_completion(&isci_port->start_complete);
+		"%s: domain_device = %p\n", __func__, dev);
 
-	if ((isci_stopping == isci_port_get_state(isci_port)) ||
-	    (isci_stopped == isci_port_get_state(isci_port)))
+	if (!isci_port)
 		return -ENODEV;
 
 	isci_device = isci_remote_device_alloc(isci_host, isci_port);
@@ -1419,7 +1411,7 @@ int isci_remote_device_found(struct domain_device *domain_dev)
 	INIT_LIST_HEAD(&isci_device->node);
 
 	spin_lock_irq(&isci_host->scic_lock);
-	isci_device->domain_dev = domain_dev;
+	isci_device->domain_dev = dev;
 	isci_device->isci_port = isci_port;
 	list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
 
@@ -1432,7 +1424,7 @@ int isci_remote_device_found(struct domain_device *domain_dev)
 
 	if (status == SCI_SUCCESS) {
 		/* device came up, advertise it to the world */
-		domain_dev->lldd_dev = isci_device;
+		dev->lldd_dev = isci_device;
 	} else
 		isci_put_device(isci_device);
 	spin_unlock_irq(&isci_host->scic_lock);
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h
index 483ee50..58637ee 100644
--- a/drivers/scsi/isci/remote_device.h
+++ b/drivers/scsi/isci/remote_device.h
@@ -82,10 +82,9 @@ struct isci_remote_device {
 	#define IDEV_START_PENDING 0
 	#define IDEV_STOP_PENDING 1
 	#define IDEV_ALLOCATED 2
-	#define IDEV_EH 3
-	#define IDEV_GONE 4
-	#define IDEV_IO_READY 5
-	#define IDEV_IO_NCQERROR 6
+	#define IDEV_GONE 3
+	#define IDEV_IO_READY 4
+	#define IDEV_IO_NCQERROR 5
 	unsigned long flags;
 	struct kref kref;
 	struct isci_port *isci_port;
@@ -180,122 +179,101 @@ enum sci_status sci_remote_device_reset_complete(
 /**
  * enum sci_remote_device_states - This enumeration depicts all the states
  *    for the common remote device state machine.
+ * @SCI_DEV_INITIAL: Simply the initial state for the base remote device
+ * state machine.
  *
+ * @SCI_DEV_STOPPED: This state indicates that the remote device has
+ * successfully been stopped.  In this state no new IO operations are
+ * permitted.  This state is entered from the INITIAL state.  This state
+ * is entered from the STOPPING state.
  *
+ * @SCI_DEV_STARTING: This state indicates the the remote device is in
+ * the process of becoming ready (i.e. starting).  In this state no new
+ * IO operations are permitted.  This state is entered from the STOPPED
+ * state.
+ *
+ * @SCI_DEV_READY: This state indicates the remote device is now ready.
+ * Thus, the user is able to perform IO operations on the remote device.
+ * This state is entered from the STARTING state.
+ *
+ * @SCI_STP_DEV_IDLE: This is the idle substate for the stp remote
+ * device.  When there are no active IO for the device it is is in this
+ * state.
+ *
+ * @SCI_STP_DEV_CMD: This is the command state for for the STP remote
+ * device.  This state is entered when the device is processing a
+ * non-NCQ command.  The device object will fail any new start IO
+ * requests until this command is complete.
+ *
+ * @SCI_STP_DEV_NCQ: This is the NCQ state for the STP remote device.
+ * This state is entered when the device is processing an NCQ reuqest.
+ * It will remain in this state so long as there is one or more NCQ
+ * requests being processed.
+ *
+ * @SCI_STP_DEV_NCQ_ERROR: This is the NCQ error state for the STP
+ * remote device.  This state is entered when an SDB error FIS is
+ * received by the device object while in the NCQ state.  The device
+ * object will only accept a READ LOG command while in this state.
+ *
+ * @SCI_STP_DEV_ATAPI_ERROR: This is the ATAPI error state for the STP
+ * ATAPI remote device.  This state is entered when ATAPI device sends
+ * error status FIS without data while the device object is in CMD
+ * state.  A suspension event is expected in this state.  The device
+ * object will resume right away.
+ *
+ * @SCI_STP_DEV_AWAIT_RESET: This is the READY substate indicates the
+ * device is waiting for the RESET task coming to be recovered from
+ * certain hardware specific error.
+ *
+ * @SCI_SMP_DEV_IDLE: This is the ready operational substate for the
+ * remote device.  This is the normal operational state for a remote
+ * device.
+ *
+ * @SCI_SMP_DEV_CMD: This is the suspended state for the remote device.
+ * This is the state that the device is placed in when a RNC suspend is
+ * received by the SCU hardware.
+ *
+ * @SCI_DEV_STOPPING: This state indicates that the remote device is in
+ * the process of stopping.  In this state no new IO operations are
+ * permitted, but existing IO operations are allowed to complete.  This
+ * state is entered from the READY state.  This state is entered from
+ * the FAILED state.
+ *
+ * @SCI_DEV_FAILED: This state indicates that the remote device has
+ * failed.  In this state no new IO operations are permitted.  This
+ * state is entered from the INITIALIZING state.  This state is entered
+ * from the READY state.
+ *
+ * @SCI_DEV_RESETTING: This state indicates the device is being reset.
+ * In this state no new IO operations are permitted.  This state is
+ * entered from the READY state.
+ *
+ * @SCI_DEV_FINAL: Simply the final state for the base remote device
+ * state machine.
  */
-enum sci_remote_device_states {
-	/**
-	 * Simply the initial state for the base remote device state machine.
-	 */
-	SCI_DEV_INITIAL,
-
-	/**
-	 * This state indicates that the remote device has successfully been
-	 * stopped.  In this state no new IO operations are permitted.
-	 * This state is entered from the INITIAL state.
-	 * This state is entered from the STOPPING state.
-	 */
-	SCI_DEV_STOPPED,
-
-	/**
-	 * This state indicates the the remote device is in the process of
-	 * becoming ready (i.e. starting).  In this state no new IO operations
-	 * are permitted.
-	 * This state is entered from the STOPPED state.
-	 */
-	SCI_DEV_STARTING,
-
-	/**
-	 * This state indicates the remote device is now ready.  Thus, the user
-	 * is able to perform IO operations on the remote device.
-	 * This state is entered from the STARTING state.
-	 */
-	SCI_DEV_READY,
-
-	/**
-	 * This is the idle substate for the stp remote device.  When there are no
-	 * active IO for the device it is is in this state.
-	 */
-	SCI_STP_DEV_IDLE,
-
-	/**
-	 * This is the command state for for the STP remote device.  This state is
-	 * entered when the device is processing a non-NCQ command.  The device object
-	 * will fail any new start IO requests until this command is complete.
-	 */
-	SCI_STP_DEV_CMD,
-
-	/**
-	 * This is the NCQ state for the STP remote device.  This state is entered
-	 * when the device is processing an NCQ reuqest.  It will remain in this state
-	 * so long as there is one or more NCQ requests being processed.
-	 */
-	SCI_STP_DEV_NCQ,
-
-	/**
-	 * This is the NCQ error state for the STP remote device.  This state is
-	 * entered when an SDB error FIS is received by the device object while in the
-	 * NCQ state.  The device object will only accept a READ LOG command while in
-	 * this state.
-	 */
-	SCI_STP_DEV_NCQ_ERROR,
-
-	/**
-	 * This is the ATAPI error state for the STP ATAPI remote device.
-	 * This state is entered when ATAPI device sends error status FIS
-	 * without data while the device object is in CMD state.
-	 * A suspension event is expected in this state.
-	 * The device object will resume right away.
-	 */
-	SCI_STP_DEV_ATAPI_ERROR,
-
-	/**
-	 * This is the READY substate indicates the device is waiting for the RESET task
-	 * coming to be recovered from certain hardware specific error.
-	 */
-	SCI_STP_DEV_AWAIT_RESET,
-
-	/**
-	 * This is the ready operational substate for the remote device.  This is the
-	 * normal operational state for a remote device.
-	 */
-	SCI_SMP_DEV_IDLE,
-
-	/**
-	 * This is the suspended state for the remote device.  This is the state that
-	 * the device is placed in when a RNC suspend is received by the SCU hardware.
-	 */
-	SCI_SMP_DEV_CMD,
-
-	/**
-	 * This state indicates that the remote device is in the process of
-	 * stopping.  In this state no new IO operations are permitted, but
-	 * existing IO operations are allowed to complete.
-	 * This state is entered from the READY state.
-	 * This state is entered from the FAILED state.
-	 */
-	SCI_DEV_STOPPING,
-
-	/**
-	 * This state indicates that the remote device has failed.
-	 * In this state no new IO operations are permitted.
-	 * This state is entered from the INITIALIZING state.
-	 * This state is entered from the READY state.
-	 */
-	SCI_DEV_FAILED,
-
-	/**
-	 * This state indicates the device is being reset.
-	 * In this state no new IO operations are permitted.
-	 * This state is entered from the READY state.
-	 */
-	SCI_DEV_RESETTING,
-
-	/**
-	 * Simply the final state for the base remote device state machine.
-	 */
-	SCI_DEV_FINAL,
-};
+#define REMOTE_DEV_STATES {\
+	C(DEV_INITIAL),\
+	C(DEV_STOPPED),\
+	C(DEV_STARTING),\
+	C(DEV_READY),\
+	C(STP_DEV_IDLE),\
+	C(STP_DEV_CMD),\
+	C(STP_DEV_NCQ),\
+	C(STP_DEV_NCQ_ERROR),\
+	C(STP_DEV_ATAPI_ERROR),\
+	C(STP_DEV_AWAIT_RESET),\
+	C(SMP_DEV_IDLE),\
+	C(SMP_DEV_CMD),\
+	C(DEV_STOPPING),\
+	C(DEV_FAILED),\
+	C(DEV_RESETTING),\
+	C(DEV_FINAL),\
+	}
+#undef C
+#define C(a) SCI_##a
+enum sci_remote_device_states REMOTE_DEV_STATES;
+#undef C
+const char *dev_state_name(enum sci_remote_device_states state);
 
 static inline struct isci_remote_device *rnc_to_dev(struct sci_remote_node_context *rnc)
 {
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c
index 748e833..3a94634 100644
--- a/drivers/scsi/isci/remote_node_context.c
+++ b/drivers/scsi/isci/remote_node_context.c
@@ -60,18 +60,15 @@
 #include "scu_event_codes.h"
 #include "scu_task_context.h"
 
+#undef C
+#define C(a) (#a)
+const char *rnc_state_name(enum scis_sds_remote_node_context_states state)
+{
+	static const char * const strings[] = RNC_STATES;
 
-/**
- *
- * @sci_rnc: The RNC for which the is posted request is being made.
- *
- * This method will return true if the RNC is not in the initial state.  In all
- * other states the RNC is considered active and this will return true. The
- * destroy request of the state machine drives the RNC back to the initial
- * state.  If the state machine changes then this routine will also have to be
- * changed. bool true if the state machine is not in the initial state false if
- * the state machine is in the initial state
- */
+	return strings[state];
+}
+#undef C
 
 /**
  *
diff --git a/drivers/scsi/isci/remote_node_context.h b/drivers/scsi/isci/remote_node_context.h
index 41580ad..a241e0f 100644
--- a/drivers/scsi/isci/remote_node_context.h
+++ b/drivers/scsi/isci/remote_node_context.h
@@ -85,61 +85,50 @@ struct sci_remote_node_context;
 typedef void (*scics_sds_remote_node_context_callback)(void *);
 
 /**
- * This is the enumeration of the remote node context states.
+ * enum sci_remote_node_context_states
+ * @SCI_RNC_INITIAL initial state for a remote node context.  On a resume
+ * request the remote node context will transition to the posting state.
+ *
+ * @SCI_RNC_POSTING: transition state that posts the RNi to the hardware. Once
+ * the RNC is posted the remote node context will be made ready.
+ *
+ * @SCI_RNC_INVALIDATING: transition state that will post an RNC invalidate to
+ * the hardware.  Once the invalidate is complete the remote node context will
+ * transition to the posting state.
+ *
+ * @SCI_RNC_RESUMING: transition state that will post an RNC resume to the
+ * hardare.  Once the event notification of resume complete is received the
+ * remote node context will transition to the ready state.
+ *
+ * @SCI_RNC_READY: state that the remote node context must be in to accept io
+ * request operations.
+ *
+ * @SCI_RNC_TX_SUSPENDED: state that the remote node context transitions to when
+ * it gets a TX suspend notification from the hardware.
+ *
+ * @SCI_RNC_TX_RX_SUSPENDED: state that the remote node context transitions to
+ * when it gets a TX RX suspend notification from the hardware.
+ *
+ * @SCI_RNC_AWAIT_SUSPENSION: wait state for the remote node context that waits
+ * for a suspend notification from the hardware.  This state is entered when
+ * either there is a request to supend the remote node context or when there is
+ * a TC completion where the remote node will be suspended by the hardware.
  */
-enum scis_sds_remote_node_context_states {
-	/**
-	 * This state is the initial state for a remote node context.  On a resume
-	 * request the remote node context will transition to the posting state.
-	 */
-	SCI_RNC_INITIAL,
-
-	/**
-	 * This is a transition state that posts the RNi to the hardware. Once the RNC
-	 * is posted the remote node context will be made ready.
-	 */
-	SCI_RNC_POSTING,
-
-	/**
-	 * This is a transition state that will post an RNC invalidate to the
-	 * hardware.  Once the invalidate is complete the remote node context will
-	 * transition to the posting state.
-	 */
-	SCI_RNC_INVALIDATING,
-
-	/**
-	 * This is a transition state that will post an RNC resume to the hardare.
-	 * Once the event notification of resume complete is received the remote node
-	 * context will transition to the ready state.
-	 */
-	SCI_RNC_RESUMING,
-
-	/**
-	 * This is the state that the remote node context must be in to accept io
-	 * request operations.
-	 */
-	SCI_RNC_READY,
-
-	/**
-	 * This is the state that the remote node context transitions to when it gets
-	 * a TX suspend notification from the hardware.
-	 */
-	SCI_RNC_TX_SUSPENDED,
-
-	/**
-	 * This is the state that the remote node context transitions to when it gets
-	 * a TX RX suspend notification from the hardware.
-	 */
-	SCI_RNC_TX_RX_SUSPENDED,
-
-	/**
-	 * This state is a wait state for the remote node context that waits for a
-	 * suspend notification from the hardware.  This state is entered when either
-	 * there is a request to supend the remote node context or when there is a TC
-	 * completion where the remote node will be suspended by the hardware.
-	 */
-	SCI_RNC_AWAIT_SUSPENSION
-};
+#define RNC_STATES {\
+	C(RNC_INITIAL),\
+	C(RNC_POSTING),\
+	C(RNC_INVALIDATING),\
+	C(RNC_RESUMING),\
+	C(RNC_READY),\
+	C(RNC_TX_SUSPENDED),\
+	C(RNC_TX_RX_SUSPENDED),\
+	C(RNC_AWAIT_SUSPENSION),\
+	}
+#undef C
+#define C(a) SCI_##a
+enum scis_sds_remote_node_context_states RNC_STATES;
+#undef C
+const char *rnc_state_name(enum scis_sds_remote_node_context_states state);
 
 /**
  *
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 192cb48..2def1e3 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -53,6 +53,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <scsi/scsi_cmnd.h>
 #include "isci.h"
 #include "task.h"
 #include "request.h"
@@ -60,6 +61,16 @@
 #include "scu_event_codes.h"
 #include "sas.h"
 
+#undef C
+#define C(a) (#a)
+const char *req_state_name(enum sci_base_request_states state)
+{
+	static const char * const strings[] = REQUEST_STATES;
+
+	return strings[state];
+}
+#undef C
+
 static struct scu_sgl_element_pair *to_sgl_element_pair(struct isci_request *ireq,
 							int idx)
 {
@@ -264,6 +275,141 @@ static void scu_ssp_reqeust_construct_task_context(
 	task_context->response_iu_lower = lower_32_bits(dma_addr);
 }
 
+static u8 scu_bg_blk_size(struct scsi_device *sdp)
+{
+	switch (sdp->sector_size) {
+	case 512:
+		return 0;
+	case 1024:
+		return 1;
+	case 4096:
+		return 3;
+	default:
+		return 0xff;
+	}
+}
+
+static u32 scu_dif_bytes(u32 len, u32 sector_size)
+{
+	return (len >> ilog2(sector_size)) * 8;
+}
+
+static void scu_ssp_ireq_dif_insert(struct isci_request *ireq, u8 type, u8 op)
+{
+	struct scu_task_context *tc = ireq->tc;
+	struct scsi_cmnd *scmd = ireq->ttype_ptr.io_task_ptr->uldd_task;
+	u8 blk_sz = scu_bg_blk_size(scmd->device);
+
+	tc->block_guard_enable = 1;
+	tc->blk_prot_en = 1;
+	tc->blk_sz = blk_sz;
+	/* DIF write insert */
+	tc->blk_prot_func = 0x2;
+
+	tc->transfer_length_bytes += scu_dif_bytes(tc->transfer_length_bytes,
+						   scmd->device->sector_size);
+
+	/* always init to 0, used by hw */
+	tc->interm_crc_val = 0;
+
+	tc->init_crc_seed = 0;
+	tc->app_tag_verify = 0;
+	tc->app_tag_gen = 0;
+	tc->ref_tag_seed_verify = 0;
+
+	/* always init to same as bg_blk_sz */
+	tc->UD_bytes_immed_val = scmd->device->sector_size;
+
+	tc->reserved_DC_0 = 0;
+
+	/* always init to 8 */
+	tc->DIF_bytes_immed_val = 8;
+
+	tc->reserved_DC_1 = 0;
+	tc->bgc_blk_sz = scmd->device->sector_size;
+	tc->reserved_E0_0 = 0;
+	tc->app_tag_gen_mask = 0;
+
+	/** setup block guard control **/
+	tc->bgctl = 0;
+
+	/* DIF write insert */
+	tc->bgctl_f.op = 0x2;
+
+	tc->app_tag_verify_mask = 0;
+
+	/* must init to 0 for hw */
+	tc->blk_guard_err = 0;
+
+	tc->reserved_E8_0 = 0;
+
+	if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2))
+		tc->ref_tag_seed_gen = scsi_get_lba(scmd) & 0xffffffff;
+	else if (type & SCSI_PROT_DIF_TYPE3)
+		tc->ref_tag_seed_gen = 0;
+}
+
+static void scu_ssp_ireq_dif_strip(struct isci_request *ireq, u8 type, u8 op)
+{
+	struct scu_task_context *tc = ireq->tc;
+	struct scsi_cmnd *scmd = ireq->ttype_ptr.io_task_ptr->uldd_task;
+	u8 blk_sz = scu_bg_blk_size(scmd->device);
+
+	tc->block_guard_enable = 1;
+	tc->blk_prot_en = 1;
+	tc->blk_sz = blk_sz;
+	/* DIF read strip */
+	tc->blk_prot_func = 0x1;
+
+	tc->transfer_length_bytes += scu_dif_bytes(tc->transfer_length_bytes,
+						   scmd->device->sector_size);
+
+	/* always init to 0, used by hw */
+	tc->interm_crc_val = 0;
+
+	tc->init_crc_seed = 0;
+	tc->app_tag_verify = 0;
+	tc->app_tag_gen = 0;
+
+	if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2))
+		tc->ref_tag_seed_verify = scsi_get_lba(scmd) & 0xffffffff;
+	else if (type & SCSI_PROT_DIF_TYPE3)
+		tc->ref_tag_seed_verify = 0;
+
+	/* always init to same as bg_blk_sz */
+	tc->UD_bytes_immed_val = scmd->device->sector_size;
+
+	tc->reserved_DC_0 = 0;
+
+	/* always init to 8 */
+	tc->DIF_bytes_immed_val = 8;
+
+	tc->reserved_DC_1 = 0;
+	tc->bgc_blk_sz = scmd->device->sector_size;
+	tc->reserved_E0_0 = 0;
+	tc->app_tag_gen_mask = 0;
+
+	/** setup block guard control **/
+	tc->bgctl = 0;
+
+	/* DIF read strip */
+	tc->bgctl_f.crc_verify = 1;
+	tc->bgctl_f.op = 0x1;
+	if ((type & SCSI_PROT_DIF_TYPE1) || (type & SCSI_PROT_DIF_TYPE2)) {
+		tc->bgctl_f.ref_tag_chk = 1;
+		tc->bgctl_f.app_f_detect = 1;
+	} else if (type & SCSI_PROT_DIF_TYPE3)
+		tc->bgctl_f.app_ref_f_detect = 1;
+
+	tc->app_tag_verify_mask = 0;
+
+	/* must init to 0 for hw */
+	tc->blk_guard_err = 0;
+
+	tc->reserved_E8_0 = 0;
+	tc->ref_tag_seed_gen = 0;
+}
+
 /**
  * This method is will fill in the SCU Task Context for a SSP IO request.
  * @sci_req:
@@ -274,6 +420,10 @@ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
 						      u32 len)
 {
 	struct scu_task_context *task_context = ireq->tc;
+	struct sas_task *sas_task = ireq->ttype_ptr.io_task_ptr;
+	struct scsi_cmnd *scmd = sas_task->uldd_task;
+	u8 prot_type = scsi_get_prot_type(scmd);
+	u8 prot_op = scsi_get_prot_op(scmd);
 
 	scu_ssp_reqeust_construct_task_context(ireq, task_context);
 
@@ -296,6 +446,13 @@ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
 
 	if (task_context->transfer_length_bytes > 0)
 		sci_request_build_sgl(ireq);
+
+	if (prot_type != SCSI_PROT_DIF_TYPE0) {
+		if (prot_op == SCSI_PROT_READ_STRIP)
+			scu_ssp_ireq_dif_strip(ireq, prot_type, prot_op);
+		else if (prot_op == SCSI_PROT_WRITE_INSERT)
+			scu_ssp_ireq_dif_insert(ireq, prot_type, prot_op);
+	}
 }
 
 /**
@@ -519,18 +676,12 @@ sci_io_request_construct_sata(struct isci_request *ireq,
 	if (test_bit(IREQ_TMF, &ireq->flags)) {
 		struct isci_tmf *tmf = isci_request_access_tmf(ireq);
 
-		if (tmf->tmf_code == isci_tmf_sata_srst_high ||
-		    tmf->tmf_code == isci_tmf_sata_srst_low) {
-			scu_stp_raw_request_construct_task_context(ireq);
-			return SCI_SUCCESS;
-		} else {
-			dev_err(&ireq->owning_controller->pdev->dev,
-				"%s: Request 0x%p received un-handled SAT "
-				"management protocol 0x%x.\n",
-				__func__, ireq, tmf->tmf_code);
+		dev_err(&ireq->owning_controller->pdev->dev,
+			"%s: Request 0x%p received un-handled SAT "
+			"management protocol 0x%x.\n",
+			__func__, ireq, tmf->tmf_code);
 
-			return SCI_FAILURE;
-		}
+		return SCI_FAILURE;
 	}
 
 	if (!sas_protocol_ata(task->task_proto)) {
@@ -627,34 +778,6 @@ static enum sci_status sci_io_request_construct_basic_sata(struct isci_request *
 	return status;
 }
 
-enum sci_status sci_task_request_construct_sata(struct isci_request *ireq)
-{
-	enum sci_status status = SCI_SUCCESS;
-
-	/* check for management protocols */
-	if (test_bit(IREQ_TMF, &ireq->flags)) {
-		struct isci_tmf *tmf = isci_request_access_tmf(ireq);
-
-		if (tmf->tmf_code == isci_tmf_sata_srst_high ||
-		    tmf->tmf_code == isci_tmf_sata_srst_low) {
-			scu_stp_raw_request_construct_task_context(ireq);
-		} else {
-			dev_err(&ireq->owning_controller->pdev->dev,
-				"%s: Request 0x%p received un-handled SAT "
-				"Protocol 0x%x.\n",
-				__func__, ireq, tmf->tmf_code);
-
-			return SCI_FAILURE;
-		}
-	}
-
-	if (status != SCI_SUCCESS)
-		return status;
-	sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
-
-	return status;
-}
-
 /**
  * sci_req_tx_bytes - bytes transferred when reply underruns request
  * @ireq: request that was terminated early
@@ -756,9 +879,6 @@ sci_io_request_terminate(struct isci_request *ireq)
 	case SCI_REQ_STP_PIO_WAIT_FRAME:
 	case SCI_REQ_STP_PIO_DATA_IN:
 	case SCI_REQ_STP_PIO_DATA_OUT:
-	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
-	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
-	case SCI_REQ_STP_SOFT_RESET_WAIT_D2H:
 	case SCI_REQ_ATAPI_WAIT_H2D:
 	case SCI_REQ_ATAPI_WAIT_PIO_SETUP:
 	case SCI_REQ_ATAPI_WAIT_D2H:
@@ -800,7 +920,8 @@ enum sci_status sci_request_complete(struct isci_request *ireq)
 
 	state = ireq->sm.current_state_id;
 	if (WARN_ONCE(state != SCI_REQ_COMPLETED,
-		      "isci: request completion from wrong state (%d)\n", state))
+		      "isci: request completion from wrong state (%s)\n",
+		      req_state_name(state)))
 		return SCI_FAILURE_INVALID_STATE;
 
 	if (ireq->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX)
@@ -821,8 +942,8 @@ enum sci_status sci_io_request_event_handler(struct isci_request *ireq,
 	state = ireq->sm.current_state_id;
 
 	if (state != SCI_REQ_STP_PIO_DATA_IN) {
-		dev_warn(&ihost->pdev->dev, "%s: (%x) in wrong state %d\n",
-			 __func__, event_code, state);
+		dev_warn(&ihost->pdev->dev, "%s: (%x) in wrong state %s\n",
+			 __func__, event_code, req_state_name(state));
 
 		return SCI_FAILURE_INVALID_STATE;
 	}
@@ -1304,9 +1425,9 @@ sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req,
 			struct page *page = sg_page(sg);
 
 			copy_len = min_t(int, total_len, sg_dma_len(sg));
-			kaddr = kmap_atomic(page, KM_IRQ0);
+			kaddr = kmap_atomic(page);
 			memcpy(kaddr + sg->offset, src_addr, copy_len);
-			kunmap_atomic(kaddr, KM_IRQ0);
+			kunmap_atomic(kaddr);
 			total_len -= copy_len;
 			src_addr += copy_len;
 			sg = sg_next(sg);
@@ -1654,7 +1775,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
 		sci_unsolicited_frame_control_get_header(&ihost->uf_control,
 							 frame_index,
 							 &frame_header);
-		kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
+		kaddr = kmap_atomic(sg_page(sg));
 		rsp = kaddr + sg->offset;
 		sci_swab32_cpy(rsp, frame_header, 1);
 
@@ -1691,7 +1812,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
 			ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
 			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
 		}
-		kunmap_atomic(kaddr, KM_IRQ0);
+		kunmap_atomic(kaddr);
 
 		sci_controller_release_frame(ihost, frame_index);
 
@@ -1938,59 +2059,6 @@ sci_io_request_frame_handler(struct isci_request *ireq,
 		return status;
 	}
 
-	case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: {
-		struct dev_to_host_fis *frame_header;
-		u32 *frame_buffer;
-
-		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
-								       frame_index,
-								       (void **)&frame_header);
-		if (status != SCI_SUCCESS) {
-			dev_err(&ihost->pdev->dev,
-				"%s: SCIC IO Request 0x%p could not get frame "
-				"header for frame index %d, status %x\n",
-				__func__,
-				stp_req,
-				frame_index,
-				status);
-			return status;
-		}
-
-		switch (frame_header->fis_type) {
-		case FIS_REGD2H:
-			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
-								      frame_index,
-								      (void **)&frame_buffer);
-
-			sci_controller_copy_sata_response(&ireq->stp.rsp,
-							       frame_header,
-							       frame_buffer);
-
-			/* The command has completed with error */
-			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
-			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
-			break;
-
-		default:
-			dev_warn(&ihost->pdev->dev,
-				 "%s: IO Request:0x%p Frame Id:%d protocol "
-				 "violation occurred\n",
-				 __func__,
-				 stp_req,
-				 frame_index);
-
-			ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
-			ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
-			break;
-		}
-
-		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-
-		/* Frame has been decoded return it to the controller */
-		sci_controller_release_frame(ihost, frame_index);
-
-		return status;
-	}
 	case SCI_REQ_ATAPI_WAIT_PIO_SETUP: {
 		struct sas_task *task = isci_request_access_task(ireq);
 
@@ -2088,57 +2156,6 @@ static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq
 	return status;
 }
 
-static enum sci_status
-stp_request_soft_reset_await_h2d_asserted_tc_event(struct isci_request *ireq,
-						   u32 completion_code)
-{
-	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
-	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
-		ireq->scu_status = SCU_TASK_DONE_GOOD;
-		ireq->sci_status = SCI_SUCCESS;
-		sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG);
-		break;
-
-	default:
-		/*
-		 * All other completion status cause the IO to be complete.
-		 * If a NAK was received, then it is up to the user to retry
-		 * the request.
-		 */
-		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
-		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
-		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-		break;
-	}
-
-	return SCI_SUCCESS;
-}
-
-static enum sci_status
-stp_request_soft_reset_await_h2d_diagnostic_tc_event(struct isci_request *ireq,
-						     u32 completion_code)
-{
-	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
-	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
-		ireq->scu_status = SCU_TASK_DONE_GOOD;
-		ireq->sci_status = SCI_SUCCESS;
-		sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_D2H);
-		break;
-
-	default:
-		/* All other completion status cause the IO to be complete.  If
-		 * a NAK was received, then it is up to the user to retry the
-		 * request.
-		 */
-		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
-		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
-		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
-		break;
-	}
-
-	return SCI_SUCCESS;
-}
-
 static enum sci_status atapi_raw_completion(struct isci_request *ireq, u32 completion_code,
 						  enum sci_base_request_states next)
 {
@@ -2284,14 +2301,6 @@ sci_io_request_tc_completion(struct isci_request *ireq,
 	case SCI_REQ_STP_PIO_DATA_OUT:
 		return pio_data_out_tx_done_tc_event(ireq, completion_code);
 
-	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
-		return stp_request_soft_reset_await_h2d_asserted_tc_event(ireq,
-									  completion_code);
-
-	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
-		return stp_request_soft_reset_await_h2d_diagnostic_tc_event(ireq,
-									    completion_code);
-
 	case SCI_REQ_ABORTING:
 		return request_aborting_state_tc_event(ireq,
 						       completion_code);
@@ -2308,12 +2317,8 @@ sci_io_request_tc_completion(struct isci_request *ireq,
 		return atapi_data_tc_completion_handler(ireq, completion_code);
 
 	default:
-		dev_warn(&ihost->pdev->dev,
-			 "%s: SCIC IO Request given task completion "
-			 "notification %x while in wrong state %d\n",
-			 __func__,
-			 completion_code,
-			 state);
+		dev_warn(&ihost->pdev->dev, "%s: %x in wrong state %s\n",
+			 __func__, completion_code, req_state_name(state));
 		return SCI_FAILURE_INVALID_STATE;
 	}
 }
@@ -3023,10 +3028,10 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
 		dma_unmap_sg(&ihost->pdev->dev, sg, 1, DMA_TO_DEVICE);
 
 		/* need to swab it back in case the command buffer is re-used */
-		kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
+		kaddr = kmap_atomic(sg_page(sg));
 		smp_req = kaddr + sg->offset;
 		sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
-		kunmap_atomic(kaddr, KM_IRQ0);
+		kunmap_atomic(kaddr);
 		break;
 	}
 	default:
@@ -3065,10 +3070,6 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
 	 */
 	if (!task && dev->dev_type == SAS_END_DEV) {
 		state = SCI_REQ_TASK_WAIT_TC_COMP;
-	} else if (!task &&
-		   (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high ||
-		    isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) {
-		state = SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED;
 	} else if (task && task->task_proto == SAS_PROTOCOL_SMP) {
 		state = SCI_REQ_SMP_WAIT_RESP;
 	} else if (task && sas_protocol_ata(task->task_proto) &&
@@ -3125,31 +3126,6 @@ static void sci_stp_request_started_pio_await_h2d_completion_enter(struct sci_ba
 	ireq->target_device->working_request = ireq;
 }
 
-static void sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(struct sci_base_state_machine *sm)
-{
-	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
-
-	ireq->target_device->working_request = ireq;
-}
-
-static void sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(struct sci_base_state_machine *sm)
-{
-	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
-	struct scu_task_context *tc = ireq->tc;
-	struct host_to_dev_fis *h2d_fis;
-	enum sci_status status;
-
-	/* Clear the SRST bit */
-	h2d_fis = &ireq->stp.cmd;
-	h2d_fis->control = 0;
-
-	/* Clear the TC control bit */
-	tc->control_frame = 0;
-
-	status = sci_controller_continue_io(ireq);
-	WARN_ONCE(status != SCI_SUCCESS, "isci: continue io failure\n");
-}
-
 static const struct sci_base_state sci_request_state_table[] = {
 	[SCI_REQ_INIT] = { },
 	[SCI_REQ_CONSTRUCTED] = { },
@@ -3168,13 +3144,6 @@ static const struct sci_base_state sci_request_state_table[] = {
 	[SCI_REQ_STP_PIO_DATA_OUT] = { },
 	[SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { },
 	[SCI_REQ_STP_UDMA_WAIT_D2H] = { },
-	[SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED] = {
-		.enter_state = sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
-	},
-	[SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG] = {
-		.enter_state = sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
-	},
-	[SCI_REQ_STP_SOFT_RESET_WAIT_D2H] = { },
 	[SCI_REQ_TASK_WAIT_TC_COMP] = { },
 	[SCI_REQ_TASK_WAIT_TC_RESP] = { },
 	[SCI_REQ_SMP_WAIT_RESP] = { },
@@ -3311,7 +3280,7 @@ sci_io_request_construct_smp(struct device *dev,
 	u8 req_len;
 	u32 cmd;
 
-	kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
+	kaddr = kmap_atomic(sg_page(sg));
 	smp_req = kaddr + sg->offset;
 	/*
 	 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
@@ -3337,7 +3306,7 @@ sci_io_request_construct_smp(struct device *dev,
 	req_len = smp_req->req_len;
 	sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
 	cmd = *(u32 *) smp_req;
-	kunmap_atomic(kaddr, KM_IRQ0);
+	kunmap_atomic(kaddr);
 
 	if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
 		return SCI_FAILURE;
@@ -3649,8 +3618,7 @@ int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *ide
 		/* Cause this task to be scheduled in the SCSI error
 		 * handler thread.
 		 */
-		isci_execpath_callback(ihost, task,
-				       sas_task_abort);
+		sas_task_abort(task);
 
 		/* Change the status, since we are holding
 		 * the I/O until it is managed by the SCSI
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
index be38933..057f237 100644
--- a/drivers/scsi/isci/request.h
+++ b/drivers/scsi/isci/request.h
@@ -182,138 +182,103 @@ static inline struct isci_request *to_ireq(struct isci_stp_request *stp_req)
 }
 
 /**
- * enum sci_base_request_states - This enumeration depicts all the states for
- *    the common request state machine.
+ * enum sci_base_request_states - request state machine states
  *
+ * @SCI_REQ_INIT: Simply the initial state for the base request state machine.
  *
+ * @SCI_REQ_CONSTRUCTED: This state indicates that the request has been
+ * constructed.  This state is entered from the INITIAL state.
+ *
+ * @SCI_REQ_STARTED: This state indicates that the request has been started.
+ * This state is entered from the CONSTRUCTED state.
+ *
+ * @SCI_REQ_STP_UDMA_WAIT_TC_COMP:
+ * @SCI_REQ_STP_UDMA_WAIT_D2H:
+ * @SCI_REQ_STP_NON_DATA_WAIT_H2D:
+ * @SCI_REQ_STP_NON_DATA_WAIT_D2H:
+ *
+ * @SCI_REQ_STP_PIO_WAIT_H2D: While in this state the IO request object is
+ * waiting for the TC completion notification for the H2D Register FIS
+ *
+ * @SCI_REQ_STP_PIO_WAIT_FRAME: While in this state the IO request object is
+ * waiting for either a PIO Setup FIS or a D2H register FIS.  The type of frame
+ * received is based on the result of the prior frame and line conditions.
+ *
+ * @SCI_REQ_STP_PIO_DATA_IN: While in this state the IO request object is
+ * waiting for a DATA frame from the device.
+ *
+ * @SCI_REQ_STP_PIO_DATA_OUT: While in this state the IO request object is
+ * waiting to transmit the next data frame to the device.
+ *
+ * @SCI_REQ_ATAPI_WAIT_H2D: While in this state the IO request object is
+ * waiting for the TC completion notification for the H2D Register FIS
+ *
+ * @SCI_REQ_ATAPI_WAIT_PIO_SETUP: While in this state the IO request object is
+ * waiting for either a PIO Setup.
+ *
+ * @SCI_REQ_ATAPI_WAIT_D2H: The non-data IO transit to this state in this state
+ * after receiving TC completion. While in this state IO request object is
+ * waiting for D2H status frame as UF.
+ *
+ * @SCI_REQ_ATAPI_WAIT_TC_COMP: When transmitting raw frames hardware reports
+ * task context completion after every frame submission, so in the
+ * non-accelerated case we need to expect the completion for the "cdb" frame.
+ *
+ * @SCI_REQ_TASK_WAIT_TC_COMP: The AWAIT_TC_COMPLETION sub-state indicates that
+ * the started raw task management request is waiting for the transmission of
+ * the initial frame (i.e. command, task, etc.).
+ *
+ * @SCI_REQ_TASK_WAIT_TC_RESP: This sub-state indicates that the started task
+ * management request is waiting for the reception of an unsolicited frame
+ * (i.e.  response IU).
+ *
+ * @SCI_REQ_SMP_WAIT_RESP: This sub-state indicates that the started task
+ * management request is waiting for the reception of an unsolicited frame
+ * (i.e.  response IU).
+ *
+ * @SCI_REQ_SMP_WAIT_TC_COMP: The AWAIT_TC_COMPLETION sub-state indicates that
+ * the started SMP request is waiting for the transmission of the initial frame
+ * (i.e.  command, task, etc.).
+ *
+ * @SCI_REQ_COMPLETED: This state indicates that the request has completed.
+ * This state is entered from the STARTED state. This state is entered from the
+ * ABORTING state.
+ *
+ * @SCI_REQ_ABORTING: This state indicates that the request is in the process
+ * of being terminated/aborted.  This state is entered from the CONSTRUCTED
+ * state.  This state is entered from the STARTED state.
+ *
+ * @SCI_REQ_FINAL: Simply the final state for the base request state machine.
  */
-enum sci_base_request_states {
-	/*
-	 * Simply the initial state for the base request state machine.
-	 */
-	SCI_REQ_INIT,
-
-	/*
-	 * This state indicates that the request has been constructed.
-	 * This state is entered from the INITIAL state.
-	 */
-	SCI_REQ_CONSTRUCTED,
-
-	/*
-	 * This state indicates that the request has been started. This state
-	 * is entered from the CONSTRUCTED state.
-	 */
-	SCI_REQ_STARTED,
-
-	SCI_REQ_STP_UDMA_WAIT_TC_COMP,
-	SCI_REQ_STP_UDMA_WAIT_D2H,
-
-	SCI_REQ_STP_NON_DATA_WAIT_H2D,
-	SCI_REQ_STP_NON_DATA_WAIT_D2H,
-
-	SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED,
-	SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG,
-	SCI_REQ_STP_SOFT_RESET_WAIT_D2H,
-
-	/*
-	 * While in this state the IO request object is waiting for the TC
-	 * completion notification for the H2D Register FIS
-	 */
-	SCI_REQ_STP_PIO_WAIT_H2D,
-
-	/*
-	 * While in this state the IO request object is waiting for either a
-	 * PIO Setup FIS or a D2H register FIS.  The type of frame received is
-	 * based on the result of the prior frame and line conditions.
-	 */
-	SCI_REQ_STP_PIO_WAIT_FRAME,
-
-	/*
-	 * While in this state the IO request object is waiting for a DATA
-	 * frame from the device.
-	 */
-	SCI_REQ_STP_PIO_DATA_IN,
-
-	/*
-	 * While in this state the IO request object is waiting to transmit
-	 * the next data frame to the device.
-	 */
-	SCI_REQ_STP_PIO_DATA_OUT,
-
-	/*
-	 * While in this state the IO request object is waiting for the TC
-	 * completion notification for the H2D Register FIS
-	 */
-	SCI_REQ_ATAPI_WAIT_H2D,
-
-	/*
-	 * While in this state the IO request object is waiting for either a
-	 * PIO Setup.
-	 */
-	SCI_REQ_ATAPI_WAIT_PIO_SETUP,
-
-	/*
-	 * The non-data IO transit to this state in this state after receiving
-	 * TC completion. While in this state IO request object is waiting for
-	 * D2H status frame as UF.
-	 */
-	SCI_REQ_ATAPI_WAIT_D2H,
-
-	/*
-	 * When transmitting raw frames hardware reports task context completion
-	 * after every frame submission, so in the non-accelerated case we need
-	 * to expect the completion for the "cdb" frame.
-	 */
-	SCI_REQ_ATAPI_WAIT_TC_COMP,
-
-	/*
-	 * The AWAIT_TC_COMPLETION sub-state indicates that the started raw
-	 * task management request is waiting for the transmission of the
-	 * initial frame (i.e. command, task, etc.).
-	 */
-	SCI_REQ_TASK_WAIT_TC_COMP,
-
-	/*
-	 * This sub-state indicates that the started task management request
-	 * is waiting for the reception of an unsolicited frame
-	 * (i.e. response IU).
-	 */
-	SCI_REQ_TASK_WAIT_TC_RESP,
-
-	/*
-	 * This sub-state indicates that the started task management request
-	 * is waiting for the reception of an unsolicited frame
-	 * (i.e. response IU).
-	 */
-	SCI_REQ_SMP_WAIT_RESP,
-
-	/*
-	 * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP
-	 * request is waiting for the transmission of the initial frame
-	 * (i.e. command, task, etc.).
-	 */
-	SCI_REQ_SMP_WAIT_TC_COMP,
-
-	/*
-	 * This state indicates that the request has completed.
-	 * This state is entered from the STARTED state. This state is entered
-	 * from the ABORTING state.
-	 */
-	SCI_REQ_COMPLETED,
-
-	/*
-	 * This state indicates that the request is in the process of being
-	 * terminated/aborted.
-	 * This state is entered from the CONSTRUCTED state.
-	 * This state is entered from the STARTED state.
-	 */
-	SCI_REQ_ABORTING,
-
-	/*
-	 * Simply the final state for the base request state machine.
-	 */
-	SCI_REQ_FINAL,
-};
+#define REQUEST_STATES {\
+	C(REQ_INIT),\
+	C(REQ_CONSTRUCTED),\
+	C(REQ_STARTED),\
+	C(REQ_STP_UDMA_WAIT_TC_COMP),\
+	C(REQ_STP_UDMA_WAIT_D2H),\
+	C(REQ_STP_NON_DATA_WAIT_H2D),\
+	C(REQ_STP_NON_DATA_WAIT_D2H),\
+	C(REQ_STP_PIO_WAIT_H2D),\
+	C(REQ_STP_PIO_WAIT_FRAME),\
+	C(REQ_STP_PIO_DATA_IN),\
+	C(REQ_STP_PIO_DATA_OUT),\
+	C(REQ_ATAPI_WAIT_H2D),\
+	C(REQ_ATAPI_WAIT_PIO_SETUP),\
+	C(REQ_ATAPI_WAIT_D2H),\
+	C(REQ_ATAPI_WAIT_TC_COMP),\
+	C(REQ_TASK_WAIT_TC_COMP),\
+	C(REQ_TASK_WAIT_TC_RESP),\
+	C(REQ_SMP_WAIT_RESP),\
+	C(REQ_SMP_WAIT_TC_COMP),\
+	C(REQ_COMPLETED),\
+	C(REQ_ABORTING),\
+	C(REQ_FINAL),\
+	}
+#undef C
+#define C(a) SCI_##a
+enum sci_base_request_states REQUEST_STATES;
+#undef C
+const char *req_state_name(enum sci_base_request_states state);
 
 enum sci_status sci_request_start(struct isci_request *ireq);
 enum sci_status sci_io_request_terminate(struct isci_request *ireq);
@@ -446,10 +411,7 @@ sci_task_request_construct(struct isci_host *ihost,
 			    struct isci_remote_device *idev,
 			    u16 io_tag,
 			    struct isci_request *ireq);
-enum sci_status
-sci_task_request_construct_ssp(struct isci_request *ireq);
-enum sci_status
-sci_task_request_construct_sata(struct isci_request *ireq);
+enum sci_status sci_task_request_construct_ssp(struct isci_request *ireq);
 void sci_smp_request_copy_response(struct isci_request *ireq);
 
 static inline int isci_task_is_ncq_recovery(struct sas_task *task)
diff --git a/drivers/scsi/isci/scu_task_context.h b/drivers/scsi/isci/scu_task_context.h
index 7df87d9..869a979 100644
--- a/drivers/scsi/isci/scu_task_context.h
+++ b/drivers/scsi/isci/scu_task_context.h
@@ -866,9 +866,9 @@ struct scu_task_context {
 	struct transport_snapshot snapshot; /* read only set to 0 */
 
 	/* OFFSET 0x5C */
-	u32 block_protection_enable:1;
-	u32 block_size:2;
-	u32 block_protection_function:2;
+	u32 blk_prot_en:1;
+	u32 blk_sz:2;
+	u32 blk_prot_func:2;
 	u32 reserved_5C_0:9;
 	u32 active_sgl_element:2;  /* read only set to 0 */
 	u32 sgl_exhausted:1;  /* read only set to 0 */
@@ -896,33 +896,56 @@ struct scu_task_context {
 	u32 reserved_C4_CC[3];
 
 	/* OFFSET 0xD0 */
-	u32 intermediate_crc_value:16;
-	u32 initial_crc_seed:16;
+	u32 interm_crc_val:16;
+	u32 init_crc_seed:16;
 
 	/* OFFSET 0xD4 */
-	u32 application_tag_for_verify:16;
-	u32 application_tag_for_generate:16;
+	u32 app_tag_verify:16;
+	u32 app_tag_gen:16;
 
 	/* OFFSET 0xD8 */
-	u32 reference_tag_seed_for_verify_function;
+	u32 ref_tag_seed_verify;
 
 	/* OFFSET 0xDC */
-	u32 reserved_DC;
+	u32 UD_bytes_immed_val:13;
+	u32 reserved_DC_0:3;
+	u32 DIF_bytes_immed_val:4;
+	u32 reserved_DC_1:12;
 
 	/* OFFSET 0xE0 */
-	u32 reserved_E0_0:16;
-	u32 application_tag_mask_for_generate:16;
+	u32 bgc_blk_sz:13;
+	u32 reserved_E0_0:3;
+	u32 app_tag_gen_mask:16;
 
 	/* OFFSET 0xE4 */
-	u32 block_protection_control:16;
-	u32 application_tag_mask_for_verify:16;
+	union {
+		u16 bgctl;
+		struct {
+			u16 crc_verify:1;
+			u16 app_tag_chk:1;
+			u16 ref_tag_chk:1;
+			u16 op:2;
+			u16 legacy:1;
+			u16 invert_crc_seed:1;
+			u16 ref_tag_gen:1;
+			u16 fixed_ref_tag:1;
+			u16 invert_crc:1;
+			u16 app_ref_f_detect:1;
+			u16 uninit_dif_check_err:1;
+			u16 uninit_dif_bypass:1;
+			u16 app_f_detect:1;
+			u16 reserved_0:2;
+		} bgctl_f;
+	};
+
+	u16 app_tag_verify_mask;
 
 	/* OFFSET 0xE8 */
-	u32 block_protection_error:8;
+	u32 blk_guard_err:8;
 	u32 reserved_E8_0:24;
 
 	/* OFFSET 0xEC */
-	u32 reference_tag_seed_for_verify;
+	u32 ref_tag_seed_gen;
 
 	/* OFFSET 0xF0 */
 	u32 intermediate_crc_valid_snapshot:16;
@@ -937,6 +960,6 @@ struct scu_task_context {
 	/* OFFSET 0xFC */
 	u32 reference_tag_seed_for_generate_function_snapshot;
 
-};
+} __packed;
 
 #endif /* _SCU_TASK_CONTEXT_H_ */
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index f5a3f7d..374254e 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -96,8 +96,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
 			__func__, task, response, status);
 
 		task->lldd_task = NULL;
-
-		isci_execpath_callback(ihost, task, task->task_done);
+		task->task_done(task);
 		break;
 
 	case isci_perform_aborted_io_completion:
@@ -117,8 +116,7 @@ static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
 			"%s: Error - task = %p, response=%d, "
 			"status=%d\n",
 			__func__, task, response, status);
-
-		isci_execpath_callback(ihost, task, sas_task_abort);
+		sas_task_abort(task);
 		break;
 
 	default:
@@ -249,46 +247,6 @@ int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
 	return 0;
 }
 
-static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq)
-{
-	struct isci_tmf *isci_tmf;
-	enum sci_status status;
-
-	if (!test_bit(IREQ_TMF, &ireq->flags))
-		return SCI_FAILURE;
-
-	isci_tmf = isci_request_access_tmf(ireq);
-
-	switch (isci_tmf->tmf_code) {
-
-	case isci_tmf_sata_srst_high:
-	case isci_tmf_sata_srst_low: {
-		struct host_to_dev_fis *fis = &ireq->stp.cmd;
-
-		memset(fis, 0, sizeof(*fis));
-
-		fis->fis_type  =  0x27;
-		fis->flags     &= ~0x80;
-		fis->flags     &= 0xF0;
-		if (isci_tmf->tmf_code == isci_tmf_sata_srst_high)
-			fis->control |= ATA_SRST;
-		else
-			fis->control &= ~ATA_SRST;
-		break;
-	}
-	/* other management commnd go here... */
-	default:
-		return SCI_FAILURE;
-	}
-
-	/* core builds the protocol specific request
-	 *  based on the h2d fis.
-	 */
-	status = sci_task_request_construct_sata(ireq);
-
-	return status;
-}
-
 static struct isci_request *isci_task_request_build(struct isci_host *ihost,
 						    struct isci_remote_device *idev,
 						    u16 tag, struct isci_tmf *isci_tmf)
@@ -328,13 +286,6 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost,
 			return NULL;
 	}
 
-	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
-		isci_tmf->proto = SAS_PROTOCOL_SATA;
-		status = isci_sata_management_task_request_build(ireq);
-
-		if (status != SCI_SUCCESS)
-			return NULL;
-	}
 	return ireq;
 }
 
@@ -873,53 +824,20 @@ static int isci_task_send_lu_reset_sas(
 	return ret;
 }
 
-static int isci_task_send_lu_reset_sata(struct isci_host *ihost,
-				 struct isci_remote_device *idev, u8 *lun)
-{
-	int ret = TMF_RESP_FUNC_FAILED;
-	struct isci_tmf tmf;
-
-	/* Send the soft reset to the target */
-	#define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */
-	isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL);
-
-	ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS);
-
-	if (ret != TMF_RESP_FUNC_COMPLETE) {
-		dev_dbg(&ihost->pdev->dev,
-			 "%s: Assert SRST failed (%p) = %x",
-			 __func__, idev, ret);
-
-		/* Return the failure so that the LUN reset is escalated
-		 * to a target reset.
-		 */
-	}
-	return ret;
-}
-
-/**
- * isci_task_lu_reset() - This function is one of the SAS Domain Template
- *    functions. This is one of the Task Management functoins called by libsas,
- *    to reset the given lun. Note the assumption that while this call is
- *    executing, no I/O will be sent by the host to the device.
- * @lun: This parameter specifies the lun to be reset.
- *
- * status, zero indicates success.
- */
-int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
+int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
 {
-	struct isci_host *isci_host = dev_to_ihost(domain_device);
+	struct isci_host *isci_host = dev_to_ihost(dev);
 	struct isci_remote_device *isci_device;
 	unsigned long flags;
 	int ret;
 
 	spin_lock_irqsave(&isci_host->scic_lock, flags);
-	isci_device = isci_lookup_device(domain_device);
+	isci_device = isci_lookup_device(dev);
 	spin_unlock_irqrestore(&isci_host->scic_lock, flags);
 
 	dev_dbg(&isci_host->pdev->dev,
 		"%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
-		 __func__, domain_device, isci_host, isci_device);
+		 __func__, dev, isci_host, isci_device);
 
 	if (!isci_device) {
 		/* If the device is gone, stop the escalations. */
@@ -928,11 +846,11 @@ int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
 		ret = TMF_RESP_FUNC_COMPLETE;
 		goto out;
 	}
-	set_bit(IDEV_EH, &isci_device->flags);
 
 	/* Send the task management part of the reset. */
-	if (sas_protocol_ata(domain_device->tproto)) {
-		ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun);
+	if (dev_is_sata(dev)) {
+		sas_ata_schedule_reset(dev);
+		ret = TMF_RESP_FUNC_COMPLETE;
 	} else
 		ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
 
@@ -1062,9 +980,6 @@ int isci_task_abort_task(struct sas_task *task)
 		"%s: dev = %p, task = %p, old_request == %p\n",
 		__func__, isci_device, task, old_request);
 
-	if (isci_device)
-		set_bit(IDEV_EH, &isci_device->flags);
-
 	/* Device reset conditions signalled in task_state_flags are the
 	 * responsbility of libsas to observe at the start of the error
 	 * handler thread.
@@ -1332,29 +1247,35 @@ isci_task_request_complete(struct isci_host *ihost,
 }
 
 static int isci_reset_device(struct isci_host *ihost,
+			     struct domain_device *dev,
 			     struct isci_remote_device *idev)
 {
-	struct sas_phy *phy = sas_find_local_phy(idev->domain_dev);
-	enum sci_status status;
-	unsigned long flags;
 	int rc;
+	unsigned long flags;
+	enum sci_status status;
+	struct sas_phy *phy = sas_get_local_phy(dev);
+	struct isci_port *iport = dev->port->lldd_port;
 
 	dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);
 
 	spin_lock_irqsave(&ihost->scic_lock, flags);
 	status = sci_remote_device_reset(idev);
-	if (status != SCI_SUCCESS) {
-		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
+	if (status != SCI_SUCCESS) {
 		dev_dbg(&ihost->pdev->dev,
 			 "%s: sci_remote_device_reset(%p) returned %d!\n",
 			 __func__, idev, status);
-
-		return TMF_RESP_FUNC_FAILED;
+		rc = TMF_RESP_FUNC_FAILED;
+		goto out;
 	}
-	spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
-	rc = sas_phy_reset(phy, true);
+	if (scsi_is_sas_phy_local(phy)) {
+		struct isci_phy *iphy = &ihost->phys[phy->number];
+
+		rc = isci_port_perform_hard_reset(ihost, iport, iphy);
+	} else
+		rc = sas_phy_reset(phy, !dev_is_sata(dev));
 
 	/* Terminate in-progress I/O now. */
 	isci_remote_device_nuke_requests(ihost, idev);
@@ -1371,7 +1292,8 @@ static int isci_reset_device(struct isci_host *ihost,
 	}
 
 	dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev);
-
+ out:
+	sas_put_local_phy(phy);
 	return rc;
 }
 
@@ -1386,35 +1308,15 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev)
 	idev = isci_lookup_device(dev);
 	spin_unlock_irqrestore(&ihost->scic_lock, flags);
 
-	if (!idev || !test_bit(IDEV_EH, &idev->flags)) {
-		ret = TMF_RESP_FUNC_COMPLETE;
-		goto out;
-	}
-
-	ret = isci_reset_device(ihost, idev);
- out:
-	isci_put_device(idev);
-	return ret;
-}
-
-int isci_bus_reset_handler(struct scsi_cmnd *cmd)
-{
-	struct domain_device *dev = sdev_to_domain_dev(cmd->device);
-	struct isci_host *ihost = dev_to_ihost(dev);
-	struct isci_remote_device *idev;
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&ihost->scic_lock, flags);
-	idev = isci_lookup_device(dev);
-	spin_unlock_irqrestore(&ihost->scic_lock, flags);
-
 	if (!idev) {
+		/* XXX: need to cleanup any ireqs targeting this
+		 * domain_device
+		 */
 		ret = TMF_RESP_FUNC_COMPLETE;
 		goto out;
 	}
 
-	ret = isci_reset_device(ihost, idev);
+	ret = isci_reset_device(ihost, dev, idev);
  out:
 	isci_put_device(idev);
 	return ret;
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index 1b27b37..7b6d0e3 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -86,8 +86,6 @@ enum isci_tmf_function_codes {
 	isci_tmf_func_none      = 0,
 	isci_tmf_ssp_task_abort = TMF_ABORT_TASK,
 	isci_tmf_ssp_lun_reset  = TMF_LU_RESET,
-	isci_tmf_sata_srst_high = TMF_LU_RESET + 0x100, /* Non SCSI */
-	isci_tmf_sata_srst_low  = TMF_LU_RESET + 0x101  /* Non SCSI */
 };
 /**
  * struct isci_tmf - This class represents the task management object which
@@ -210,8 +208,6 @@ int isci_queuecommand(
 	struct scsi_cmnd *scsi_cmd,
 	void (*donefunc)(struct scsi_cmnd *));
 
-int isci_bus_reset_handler(struct scsi_cmnd *cmd);
-
 /**
  * enum isci_completion_selection - This enum defines the possible actions to
  *    take with respect to a given request's notification back to libsas.
@@ -321,40 +317,4 @@ isci_task_set_completion_status(
 	return task_notification_selection;
 
 }
-/**
-* isci_execpath_callback() - This function is called from the task
-* execute path when the task needs to callback libsas about the submit-time
-* task failure.  The callback occurs either through the task's done function
-* or through sas_task_abort.  In the case of regular non-discovery SATA/STP I/O
-* requests, libsas takes the host lock before calling execute task.  Therefore
-* in this situation the host lock must be managed before calling the func.
-*
-* @ihost: This parameter is the controller to which the I/O request was sent.
-* @task: This parameter is the I/O request.
-* @func: This parameter is the function to call in the correct context.
-* @status: This parameter is the status code for the completed task.
-*
-*/
-static inline void isci_execpath_callback(struct isci_host *ihost,
-					  struct sas_task  *task,
-					  void (*func)(struct sas_task *))
-{
-	struct domain_device *dev = task->dev;
-
-	if (dev_is_sata(dev) && task->uldd_task) {
-		unsigned long flags;
-
-		/* Since we are still in the submit path, and since
-		 * libsas takes the host lock on behalf of SATA
-		 * devices before I/O starts (in the non-discovery case),
-		 * we need to unlock before we can call the callback function.
-		 */
-		raw_local_irq_save(flags);
-		spin_unlock(dev->sata_dev.ap->lock);
-		func(task);
-		spin_lock(dev->sata_dev.ap->lock);
-		raw_local_irq_restore(flags);
-	} else
-		func(task);
-}
 #endif /* !defined(_SCI_TASK_H_) */
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index db47158..453a740 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -684,10 +684,8 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
 				       int buflen)
 {
 	struct iscsi_conn *conn = cls_conn->dd_data;
-	struct iscsi_session *session = conn->session;
 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
 	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
-	int value;
 
 	switch(param) {
 	case ISCSI_PARAM_HDRDGST_EN:
@@ -699,16 +697,7 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
 			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
 		break;
 	case ISCSI_PARAM_MAX_R2T:
-		sscanf(buf, "%d", &value);
-		if (value <= 0 || !is_power_of_2(value))
-			return -EINVAL;
-		if (session->max_r2t == value)
-			break;
-		iscsi_tcp_r2tpool_free(session);
-		iscsi_set_param(cls_conn, param, buf, buflen);
-		if (iscsi_tcp_r2tpool_alloc(session))
-			return -ENOMEM;
-		break;
+		return iscsi_tcp_set_max_r2t(conn, buf);
 	default:
 		return iscsi_set_param(cls_conn, param, buf, buflen);
 	}
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 1d1b0c9..8e561e6 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -337,6 +337,13 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
 			schedule_delayed_work(&disc->disc_work, delay);
 		} else
 			fc_disc_done(disc, DISC_EV_FAILED);
+	} else if (PTR_ERR(fp) == -FC_EX_CLOSED) {
+		/*
+		 * if discovery fails due to lport reset, clear
+		 * pending flag so that subsequent discovery can
+		 * continue
+		 */
+		disc->pending = 0;
 	}
 }
 
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index e17a28d..c2384d5 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -56,8 +56,7 @@ struct fc_seq *fc_elsct_send(struct fc_lport *lport, u32 did,
 		rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type);
 	else {
 		/* CT requests */
-		rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type);
-		did = FC_FID_DIR_SERV;
+		rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type, &did);
 	}
 
 	if (rc) {
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 4d70d96..630291f 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -1642,9 +1642,10 @@ static void fc_exch_recv_bls(struct fc_exch_mgr *mp, struct fc_frame *fp)
 		case FC_RCTL_ACK_0:
 			break;
 		default:
-			FC_EXCH_DBG(ep, "BLS rctl %x - %s received",
-				    fh->fh_r_ctl,
-				    fc_exch_rctl_name(fh->fh_r_ctl));
+			if (ep)
+				FC_EXCH_DBG(ep, "BLS rctl %x - %s received",
+					    fh->fh_r_ctl,
+					    fc_exch_rctl_name(fh->fh_r_ctl));
 			break;
 		}
 		fc_frame_free(fp);
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index f607314..f735730 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -485,11 +485,11 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 
 	if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) {
 		copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents,
-						    &offset, KM_SOFTIRQ0, NULL);
+						    &offset, NULL);
 	} else {
 		crc = crc32(~0, (u8 *) fh, sizeof(*fh));
 		copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents,
-						    &offset, KM_SOFTIRQ0, &crc);
+						    &offset, &crc);
 		buf = fc_frame_payload_get(fp, 0);
 		if (len % 4)
 			crc = crc32(crc, buf + len, 4 - (len % 4));
@@ -650,10 +650,10 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
 			 * The scatterlist item may be bigger than PAGE_SIZE,
 			 * but we must not cross pages inside the kmap.
 			 */
-			page_addr = kmap_atomic(page, KM_SOFTIRQ0);
+			page_addr = kmap_atomic(page);
 			memcpy(data, (char *)page_addr + (off & ~PAGE_MASK),
 			       sg_bytes);
-			kunmap_atomic(page_addr, KM_SOFTIRQ0);
+			kunmap_atomic(page_addr);
 			data += sg_bytes;
 		}
 		offset += sg_bytes;
@@ -1074,8 +1074,7 @@ static int fc_fcp_pkt_send(struct fc_lport *lport, struct fc_fcp_pkt *fsp)
 	fsp->cdb_cmd.fc_dl = htonl(fsp->data_len);
 	fsp->cdb_cmd.fc_flags = fsp->req_flags & ~FCP_CFL_LEN_MASK;
 
-	int_to_scsilun(fsp->cmd->device->lun,
-		       (struct scsi_lun *)fsp->cdb_cmd.fc_lun);
+	int_to_scsilun(fsp->cmd->device->lun, &fsp->cdb_cmd.fc_lun);
 	memcpy(fsp->cdb_cmd.fc_cdb, fsp->cmd->cmnd, fsp->cmd->cmd_len);
 
 	spin_lock_irqsave(&si->scsi_queue_lock, flags);
@@ -1257,7 +1256,7 @@ static int fc_lun_reset(struct fc_lport *lport, struct fc_fcp_pkt *fsp,
 
 	fsp->cdb_cmd.fc_dl = htonl(fsp->data_len);
 	fsp->cdb_cmd.fc_tm_flags = FCP_TMF_LUN_RESET;
-	int_to_scsilun(lun, (struct scsi_lun *)fsp->cdb_cmd.fc_lun);
+	int_to_scsilun(lun, &fsp->cdb_cmd.fc_lun);
 
 	fsp->wait_for_comp = 1;
 	init_completion(&fsp->tm_done);
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c
index 1bf9841..8d65a51a 100644
--- a/drivers/scsi/libfc/fc_libfc.c
+++ b/drivers/scsi/libfc/fc_libfc.c
@@ -105,14 +105,13 @@ module_exit(libfc_exit);
  * @sg: pointer to the pointer of the SG list.
  * @nents: pointer to the remaining number of entries in the SG list.
  * @offset: pointer to the current offset in the SG list.
- * @km_type: dedicated page table slot type for kmap_atomic.
  * @crc: pointer to the 32-bit crc value.
  *	 If crc is NULL, CRC is not calculated.
  */
 u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
 			     struct scatterlist *sg,
 			     u32 *nents, size_t *offset,
-			     enum km_type km_type, u32 *crc)
+			     u32 *crc)
 {
 	size_t remaining = len;
 	u32 copy_len = 0;
@@ -142,12 +141,11 @@ u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
 		off = *offset + sg->offset;
 		sg_bytes = min(sg_bytes,
 			       (size_t)(PAGE_SIZE - (off & ~PAGE_MASK)));
-		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT),
-					km_type);
+		page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT));
 		if (crc)
 			*crc = crc32(*crc, buf, sg_bytes);
 		memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes);
-		kunmap_atomic(page_addr, km_type);
+		kunmap_atomic(page_addr);
 		buf += sg_bytes;
 		*offset += sg_bytes;
 		remaining -= sg_bytes;
diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h
index c7d0712..c2830cc 100644
--- a/drivers/scsi/libfc/fc_libfc.h
+++ b/drivers/scsi/libfc/fc_libfc.h
@@ -134,6 +134,6 @@ extern void fc_fc4_conf_lport_params(struct fc_lport *, enum fc_fh_type);
 u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
 			     struct scatterlist *sg,
 			     u32 *nents, size_t *offset,
-			     enum km_type km_type, u32 *crc);
+			     u32 *crc);
 
 #endif /* _FC_LIBFC_H_ */
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 83750eb..bd5d31d 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -116,6 +116,8 @@ static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state);
 static void fc_lport_enter_scr(struct fc_lport *);
 static void fc_lport_enter_ready(struct fc_lport *);
 static void fc_lport_enter_logo(struct fc_lport *);
+static void fc_lport_enter_fdmi(struct fc_lport *lport);
+static void fc_lport_enter_ms(struct fc_lport *, enum fc_lport_state);
 
 static const char *fc_lport_state_names[] = {
 	[LPORT_ST_DISABLED] = "disabled",
@@ -126,6 +128,11 @@ static const char *fc_lport_state_names[] = {
 	[LPORT_ST_RSPN_ID] =  "RSPN_ID",
 	[LPORT_ST_RFT_ID] =   "RFT_ID",
 	[LPORT_ST_RFF_ID] =   "RFF_ID",
+	[LPORT_ST_FDMI] =     "FDMI",
+	[LPORT_ST_RHBA] =     "RHBA",
+	[LPORT_ST_RPA] =      "RPA",
+	[LPORT_ST_DHBA] =     "DHBA",
+	[LPORT_ST_DPRT] =     "DPRT",
 	[LPORT_ST_SCR] =      "SCR",
 	[LPORT_ST_READY] =    "Ready",
 	[LPORT_ST_LOGO] =     "LOGO",
@@ -183,11 +190,14 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
 		if (lport->state == LPORT_ST_DNS) {
 			lport->dns_rdata = rdata;
 			fc_lport_enter_ns(lport, LPORT_ST_RNN_ID);
+		} else if (lport->state == LPORT_ST_FDMI) {
+			lport->ms_rdata = rdata;
+			fc_lport_enter_ms(lport, LPORT_ST_DHBA);
 		} else {
 			FC_LPORT_DBG(lport, "Received an READY event "
 				     "on port (%6.6x) for the directory "
 				     "server, but the lport is not "
-				     "in the DNS state, it's in the "
+				     "in the DNS or FDMI state, it's in the "
 				     "%d state", rdata->ids.port_id,
 				     lport->state);
 			lport->tt.rport_logoff(rdata);
@@ -196,7 +206,10 @@ static void fc_lport_rport_callback(struct fc_lport *lport,
 	case RPORT_EV_LOGO:
 	case RPORT_EV_FAILED:
 	case RPORT_EV_STOP:
-		lport->dns_rdata = NULL;
+		if (rdata->ids.port_id == FC_FID_DIR_SERV)
+			lport->dns_rdata = NULL;
+		else if (rdata->ids.port_id == FC_FID_MGMT_SERV)
+			lport->ms_rdata = NULL;
 		break;
 	case RPORT_EV_NONE:
 		break;
@@ -1148,7 +1161,10 @@ static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
 			fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
 			break;
 		case LPORT_ST_RFF_ID:
-			fc_lport_enter_scr(lport);
+			if (lport->fdmi_enabled)
+				fc_lport_enter_fdmi(lport);
+			else
+				fc_lport_enter_scr(lport);
 			break;
 		default:
 			/* should have already been caught by state checks */
@@ -1163,6 +1179,85 @@ err:
 }
 
 /**
+ * fc_lport_ms_resp() - Handle response to a management server
+ *			exchange
+ * @sp:	    current sequence in exchange
+ * @fp:	    response frame
+ * @lp_arg: Fibre Channel host port instance
+ *
+ * Locking Note: This function will be called without the lport lock
+ * held, but it will lock, call an _enter_* function or fc_lport_error()
+ * and then unlock the lport.
+ */
+static void fc_lport_ms_resp(struct fc_seq *sp, struct fc_frame *fp,
+			     void *lp_arg)
+{
+	struct fc_lport *lport = lp_arg;
+	struct fc_frame_header *fh;
+	struct fc_ct_hdr *ct;
+
+	FC_LPORT_DBG(lport, "Received a ms %s\n", fc_els_resp_type(fp));
+
+	if (fp == ERR_PTR(-FC_EX_CLOSED))
+		return;
+
+	mutex_lock(&lport->lp_mutex);
+
+	if (lport->state < LPORT_ST_RHBA || lport->state > LPORT_ST_DPRT) {
+		FC_LPORT_DBG(lport, "Received a management server response, "
+			     "but in state %s\n", fc_lport_state(lport));
+		if (IS_ERR(fp))
+			goto err;
+		goto out;
+	}
+
+	if (IS_ERR(fp)) {
+		fc_lport_error(lport, fp);
+		goto err;
+	}
+
+	fh = fc_frame_header_get(fp);
+	ct = fc_frame_payload_get(fp, sizeof(*ct));
+
+	if (fh && ct && fh->fh_type == FC_TYPE_CT &&
+	    ct->ct_fs_type == FC_FST_MGMT &&
+	    ct->ct_fs_subtype == FC_FDMI_SUBTYPE) {
+		FC_LPORT_DBG(lport, "Received a management server response, "
+				    "reason=%d explain=%d\n",
+				    ct->ct_reason,
+				    ct->ct_explan);
+
+		switch (lport->state) {
+		case LPORT_ST_RHBA:
+			if (ntohs(ct->ct_cmd) == FC_FS_ACC)
+				fc_lport_enter_ms(lport, LPORT_ST_RPA);
+			else /* Error Skip RPA */
+				fc_lport_enter_scr(lport);
+			break;
+		case LPORT_ST_RPA:
+			fc_lport_enter_scr(lport);
+			break;
+		case LPORT_ST_DPRT:
+			fc_lport_enter_ms(lport, LPORT_ST_RHBA);
+			break;
+		case LPORT_ST_DHBA:
+			fc_lport_enter_ms(lport, LPORT_ST_DPRT);
+			break;
+		default:
+			/* should have already been caught by state checks */
+			break;
+		}
+	} else {
+		/* Invalid Frame? */
+		fc_lport_error(lport, fp);
+	}
+out:
+	fc_frame_free(fp);
+err:
+	mutex_unlock(&lport->lp_mutex);
+}
+
+/**
  * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request
  * @sp:	    current sequence in SCR exchange
  * @fp:	    response frame
@@ -1339,6 +1434,123 @@ err:
 }
 
 /**
+ * fc_lport_enter_ms() - management server commands
+ * @lport: Fibre Channel local port to register
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state)
+{
+	struct fc_frame *fp;
+	enum fc_fdmi_req cmd;
+	int size = sizeof(struct fc_ct_hdr);
+	size_t len;
+	int numattrs;
+
+	FC_LPORT_DBG(lport, "Entered %s state from %s state\n",
+		     fc_lport_state_names[state],
+		     fc_lport_state(lport));
+
+	fc_lport_state_enter(lport, state);
+
+	switch (state) {
+	case LPORT_ST_RHBA:
+		cmd = FC_FDMI_RHBA;
+		/* Number of HBA Attributes */
+		numattrs = 10;
+		len = sizeof(struct fc_fdmi_rhba);
+		len -= sizeof(struct fc_fdmi_attr_entry);
+		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
+		len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
+		len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
+		len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
+		len += FC_FDMI_HBA_ATTR_MODEL_LEN;
+		len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
+		len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
+
+		size += len;
+		break;
+	case LPORT_ST_RPA:
+		cmd = FC_FDMI_RPA;
+		/* Number of Port Attributes */
+		numattrs = 6;
+		len = sizeof(struct fc_fdmi_rpa);
+		len -= sizeof(struct fc_fdmi_attr_entry);
+		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
+		len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
+		len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
+		len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
+		len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
+		len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
+		len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
+
+		size += len;
+		break;
+	case LPORT_ST_DPRT:
+		cmd = FC_FDMI_DPRT;
+		len = sizeof(struct fc_fdmi_dprt);
+		size += len;
+		break;
+	case LPORT_ST_DHBA:
+		cmd = FC_FDMI_DHBA;
+		len = sizeof(struct fc_fdmi_dhba);
+		size += len;
+		break;
+	default:
+		fc_lport_error(lport, NULL);
+		return;
+	}
+
+	FC_LPORT_DBG(lport, "Cmd=0x%x Len %d size %d\n",
+			     cmd, (int)len, size);
+	fp = fc_frame_alloc(lport, size);
+	if (!fp) {
+		fc_lport_error(lport, fp);
+		return;
+	}
+
+	if (!lport->tt.elsct_send(lport, FC_FID_MGMT_SERV, fp, cmd,
+				  fc_lport_ms_resp,
+				  lport, 3 * lport->r_a_tov))
+		fc_lport_error(lport, fp);
+}
+
+/**
+ * fc_rport_enter_fdmi() - Create a fc_rport for the management server
+ * @lport: The local port requesting a remote port for the management server
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static void fc_lport_enter_fdmi(struct fc_lport *lport)
+{
+	struct fc_rport_priv *rdata;
+
+	FC_LPORT_DBG(lport, "Entered FDMI state from %s state\n",
+		     fc_lport_state(lport));
+
+	fc_lport_state_enter(lport, LPORT_ST_FDMI);
+
+	mutex_lock(&lport->disc.disc_mutex);
+	rdata = lport->tt.rport_create(lport, FC_FID_MGMT_SERV);
+	mutex_unlock(&lport->disc.disc_mutex);
+	if (!rdata)
+		goto err;
+
+	rdata->ops = &fc_lport_rport_ops;
+	lport->tt.rport_login(rdata);
+	return;
+
+err:
+	fc_lport_error(lport, NULL);
+}
+
+/**
  * fc_lport_timeout() - Handler for the retry_work timer
  * @work: The work struct of the local port
  */
@@ -1371,6 +1583,15 @@ static void fc_lport_timeout(struct work_struct *work)
 	case LPORT_ST_RFF_ID:
 		fc_lport_enter_ns(lport, lport->state);
 		break;
+	case LPORT_ST_FDMI:
+		fc_lport_enter_fdmi(lport);
+		break;
+	case LPORT_ST_RHBA:
+	case LPORT_ST_RPA:
+	case LPORT_ST_DHBA:
+	case LPORT_ST_DPRT:
+		fc_lport_enter_ms(lport, lport->state);
+		break;
 	case LPORT_ST_SCR:
 		fc_lport_enter_scr(lport);
 		break;
@@ -1698,7 +1919,7 @@ static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp,
 
 	job->reply->reply_payload_rcv_len +=
 		fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents,
-					 &info->offset, KM_BIO_SRC_IRQ, NULL);
+					 &info->offset, NULL);
 
 	if (fr_eof(fp) == FC_EOF_T &&
 	    (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 143bbe4..82c3fd4 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1909,6 +1909,16 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 	ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc);
 
 	spin_lock(&session->lock);
+	task = (struct iscsi_task *)sc->SCp.ptr;
+	if (!task) {
+		/*
+		 * Raced with completion. Blk layer has taken ownership
+		 * so let timeout code complete it now.
+		 */
+		rc = BLK_EH_HANDLED;
+		goto done;
+	}
+
 	if (session->state != ISCSI_STATE_LOGGED_IN) {
 		/*
 		 * We are probably in the middle of iscsi recovery so let
@@ -1925,16 +1935,6 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 		goto done;
 	}
 
-	task = (struct iscsi_task *)sc->SCp.ptr;
-	if (!task) {
-		/*
-		 * Raced with completion. Just reset timer, and let it
-		 * complete normally
-		 */
-		rc = BLK_EH_RESET_TIMER;
-		goto done;
-	}
-
 	/*
 	 * If we have sent (at least queued to the network layer) a pdu or
 	 * recvd one for the task since the last timeout ask for
@@ -2807,6 +2807,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
 	kfree(session->username);
 	kfree(session->username_in);
 	kfree(session->targetname);
+	kfree(session->targetalias);
 	kfree(session->initiatorname);
 	kfree(session->ifacename);
 
@@ -3200,7 +3201,7 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
 		sscanf(buf, "%d", &session->initial_r2t_en);
 		break;
 	case ISCSI_PARAM_MAX_R2T:
-		sscanf(buf, "%d", &session->max_r2t);
+		sscanf(buf, "%hu", &session->max_r2t);
 		break;
 	case ISCSI_PARAM_IMM_DATA_EN:
 		sscanf(buf, "%d", &session->imm_data_en);
@@ -3233,6 +3234,8 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
 		return iscsi_switch_str_param(&session->password_in, buf);
 	case ISCSI_PARAM_TARGET_NAME:
 		return iscsi_switch_str_param(&session->targetname, buf);
+	case ISCSI_PARAM_TARGET_ALIAS:
+		return iscsi_switch_str_param(&session->targetalias, buf);
 	case ISCSI_PARAM_TPGT:
 		sscanf(buf, "%d", &session->tpgt);
 		break;
@@ -3299,6 +3302,9 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
 	case ISCSI_PARAM_TARGET_NAME:
 		len = sprintf(buf, "%s\n", session->targetname);
 		break;
+	case ISCSI_PARAM_TARGET_ALIAS:
+		len = sprintf(buf, "%s\n", session->targetalias);
+		break;
 	case ISCSI_PARAM_TPGT:
 		len = sprintf(buf, "%d\n", session->tpgt);
 		break;
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 5715a3d..552e8a2 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -135,7 +135,7 @@ static void iscsi_tcp_segment_map(struct iscsi_segment *segment, int recv)
 
 	if (recv) {
 		segment->atomic_mapped = true;
-		segment->sg_mapped = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
+		segment->sg_mapped = kmap_atomic(sg_page(sg));
 	} else {
 		segment->atomic_mapped = false;
 		/* the xmit path can sleep with the page mapped so use kmap */
@@ -149,7 +149,7 @@ void iscsi_tcp_segment_unmap(struct iscsi_segment *segment)
 {
 	if (segment->sg_mapped) {
 		if (segment->atomic_mapped)
-			kunmap_atomic(segment->sg_mapped, KM_SOFTIRQ0);
+			kunmap_atomic(segment->sg_mapped);
 		else
 			kunmap(sg_page(segment->sg));
 		segment->sg_mapped = NULL;
@@ -1170,6 +1170,24 @@ void iscsi_tcp_r2tpool_free(struct iscsi_session *session)
 }
 EXPORT_SYMBOL_GPL(iscsi_tcp_r2tpool_free);
 
+int iscsi_tcp_set_max_r2t(struct iscsi_conn *conn, char *buf)
+{
+	struct iscsi_session *session = conn->session;
+	unsigned short r2ts = 0;
+
+	sscanf(buf, "%hu", &r2ts);
+	if (session->max_r2t == r2ts)
+		return 0;
+
+	if (!r2ts || !is_power_of_2(r2ts))
+		return -EINVAL;
+
+	session->max_r2t = r2ts;
+	iscsi_tcp_r2tpool_free(session);
+	return iscsi_tcp_r2tpool_alloc(session);
+}
+EXPORT_SYMBOL_GPL(iscsi_tcp_set_max_r2t);
+
 void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
 			      struct iscsi_stats *stats)
 {
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index db9238f..bc0cecc 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -23,6 +23,8 @@
 
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
+#include <linux/async.h>
+#include <linux/export.h>
 
 #include <scsi/sas_ata.h>
 #include "sas_internal.h"
@@ -93,22 +95,47 @@ static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts)
 static void sas_ata_task_done(struct sas_task *task)
 {
 	struct ata_queued_cmd *qc = task->uldd_task;
-	struct domain_device *dev;
+	struct domain_device *dev = task->dev;
 	struct task_status_struct *stat = &task->task_status;
 	struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf;
-	struct sas_ha_struct *sas_ha;
+	struct sas_ha_struct *sas_ha = dev->port->ha;
 	enum ata_completion_errors ac;
 	unsigned long flags;
 	struct ata_link *link;
+	struct ata_port *ap;
+
+	spin_lock_irqsave(&dev->done_lock, flags);
+	if (test_bit(SAS_HA_FROZEN, &sas_ha->state))
+		task = NULL;
+	else if (qc && qc->scsicmd)
+		ASSIGN_SAS_TASK(qc->scsicmd, NULL);
+	spin_unlock_irqrestore(&dev->done_lock, flags);
+
+	/* check if libsas-eh got to the task before us */
+	if (unlikely(!task))
+		return;
 
 	if (!qc)
 		goto qc_already_gone;
 
-	dev = qc->ap->private_data;
-	sas_ha = dev->port->ha;
-	link = &dev->sata_dev.ap->link;
+	ap = qc->ap;
+	link = &ap->link;
+
+	spin_lock_irqsave(ap->lock, flags);
+	/* check if we lost the race with libata/sas_ata_post_internal() */
+	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) {
+		spin_unlock_irqrestore(ap->lock, flags);
+		if (qc->scsicmd)
+			goto qc_already_gone;
+		else {
+			/* if eh is not involved and the port is frozen then the
+			 * ata internal abort process has taken responsibility
+			 * for this sas_task
+			 */
+			return;
+		}
+	}
 
-	spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
 	if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
 	    ((stat->stat == SAM_STAT_CHECK_CONDITION &&
 	      dev->sata_dev.command_set == ATAPI_COMMAND_SET))) {
@@ -121,10 +148,6 @@ static void sas_ata_task_done(struct sas_task *task)
 			if (unlikely(link->eh_info.err_mask))
 				qc->flags |= ATA_QCFLAG_FAILED;
 		}
-
-		dev->sata_dev.sstatus = resp->sstatus;
-		dev->sata_dev.serror = resp->serror;
-		dev->sata_dev.scontrol = resp->scontrol;
 	} else {
 		ac = sas_to_ata_err(stat);
 		if (ac) {
@@ -144,24 +167,8 @@ static void sas_ata_task_done(struct sas_task *task)
 	}
 
 	qc->lldd_task = NULL;
-	if (qc->scsicmd)
-		ASSIGN_SAS_TASK(qc->scsicmd, NULL);
 	ata_qc_complete(qc);
-	spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
-
-	/*
-	 * If the sas_task has an ata qc, a scsi_cmnd and the aborted
-	 * flag is set, then we must have come in via the libsas EH
-	 * functions.  When we exit this function, we need to put the
-	 * scsi_cmnd on the list of finished errors.  The ata_qc_complete
-	 * call cleans up the libata side of things but we're protected
-	 * from the scsi_cmnd going away because the scsi_cmnd is owned
-	 * by the EH, making libata's call to scsi_done a NOP.
-	 */
-	spin_lock_irqsave(&task->task_state_lock, flags);
-	if (qc->scsicmd && task->task_state_flags & SAS_TASK_STATE_ABORTED)
-		scsi_eh_finish_cmd(qc->scsicmd, &sas_ha->eh_done_q);
-	spin_unlock_irqrestore(&task->task_state_lock, flags);
+	spin_unlock_irqrestore(ap->lock, flags);
 
 qc_already_gone:
 	list_del_init(&task->list);
@@ -170,23 +177,30 @@ qc_already_gone:
 
 static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 {
-	int res;
+	unsigned long flags;
 	struct sas_task *task;
-	struct domain_device *dev = qc->ap->private_data;
+	struct scatterlist *sg;
+	int ret = AC_ERR_SYSTEM;
+	unsigned int si, xfer = 0;
+	struct ata_port *ap = qc->ap;
+	struct domain_device *dev = ap->private_data;
 	struct sas_ha_struct *sas_ha = dev->port->ha;
 	struct Scsi_Host *host = sas_ha->core.shost;
 	struct sas_internal *i = to_sas_internal(host->transportt);
-	struct scatterlist *sg;
-	unsigned int xfer = 0;
-	unsigned int si;
+
+	/* TODO: audit callers to ensure they are ready for qc_issue to
+	 * unconditionally re-enable interrupts
+	 */
+	local_irq_save(flags);
+	spin_unlock(ap->lock);
 
 	/* If the device fell off, no sense in issuing commands */
-	if (dev->gone)
-		return AC_ERR_SYSTEM;
+	if (test_bit(SAS_DEV_GONE, &dev->state))
+		goto out;
 
 	task = sas_alloc_task(GFP_ATOMIC);
 	if (!task)
-		return AC_ERR_SYSTEM;
+		goto out;
 	task->dev = dev;
 	task->task_proto = SAS_PROTOCOL_STP;
 	task->task_done = sas_ata_task_done;
@@ -231,21 +245,24 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
 		ASSIGN_SAS_TASK(qc->scsicmd, task);
 
 	if (sas_ha->lldd_max_execute_num < 2)
-		res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
+		ret = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
 	else
-		res = sas_queue_up(task);
+		ret = sas_queue_up(task);
 
 	/* Examine */
-	if (res) {
-		SAS_DPRINTK("lldd_execute_task returned: %d\n", res);
+	if (ret) {
+		SAS_DPRINTK("lldd_execute_task returned: %d\n", ret);
 
 		if (qc->scsicmd)
 			ASSIGN_SAS_TASK(qc->scsicmd, NULL);
 		sas_free_task(task);
-		return AC_ERR_SYSTEM;
+		ret = AC_ERR_SYSTEM;
 	}
 
-	return 0;
+ out:
+	spin_lock(ap->lock);
+	local_irq_restore(flags);
+	return ret;
 }
 
 static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc)
@@ -256,83 +273,222 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc)
 	return true;
 }
 
-static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
-			       unsigned long deadline)
+static struct sas_internal *dev_to_sas_internal(struct domain_device *dev)
+{
+	return to_sas_internal(dev->port->ha->core.shost->transportt);
+}
+
+static void sas_get_ata_command_set(struct domain_device *dev);
+
+int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
 {
+	if (phy->attached_tproto & SAS_PROTOCOL_STP)
+		dev->tproto = phy->attached_tproto;
+	if (phy->attached_sata_dev)
+		dev->tproto |= SATA_DEV;
+
+	if (phy->attached_dev_type == SATA_PENDING)
+		dev->dev_type = SATA_PENDING;
+	else {
+		int res;
+
+		dev->dev_type = SATA_DEV;
+		res = sas_get_report_phy_sata(dev->parent, phy->phy_id,
+					      &dev->sata_dev.rps_resp);
+		if (res) {
+			SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
+				    "0x%x\n", SAS_ADDR(dev->parent->sas_addr),
+				    phy->phy_id, res);
+			return res;
+		}
+		memcpy(dev->frame_rcvd, &dev->sata_dev.rps_resp.rps.fis,
+		       sizeof(struct dev_to_host_fis));
+		/* TODO switch to ata_dev_classify() */
+		sas_get_ata_command_set(dev);
+	}
+	return 0;
+}
+
+static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy)
+{
+	int res;
+
+	/* we weren't pending, so successfully end the reset sequence now */
+	if (dev->dev_type != SATA_PENDING)
+		return 1;
+
+	/* hmmm, if this succeeds do we need to repost the domain_device to the
+	 * lldd so it can pick up new parameters?
+	 */
+	res = sas_get_ata_info(dev, phy);
+	if (res)
+		return 0; /* retry */
+	else
+		return 1;
+}
+
+static int smp_ata_check_ready(struct ata_link *link)
+{
+	int res;
 	struct ata_port *ap = link->ap;
 	struct domain_device *dev = ap->private_data;
-	struct sas_internal *i =
-		to_sas_internal(dev->port->ha->core.shost->transportt);
-	int res = TMF_RESP_FUNC_FAILED;
-	int ret = 0;
+	struct domain_device *ex_dev = dev->parent;
+	struct sas_phy *phy = sas_get_local_phy(dev);
+	struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy->number];
 
-	if (i->dft->lldd_I_T_nexus_reset)
-		res = i->dft->lldd_I_T_nexus_reset(dev);
+	res = sas_ex_phy_discover(ex_dev, phy->number);
+	sas_put_local_phy(phy);
 
-	if (res != TMF_RESP_FUNC_COMPLETE) {
-		SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __func__);
-		ret = -EAGAIN;
+	/* break the wait early if the expander is unreachable,
+	 * otherwise keep polling
+	 */
+	if (res == -ECOMM)
+		return res;
+	if (res != SMP_RESP_FUNC_ACC)
+		return 0;
+
+	switch (ex_phy->attached_dev_type) {
+	case SATA_PENDING:
+		return 0;
+	case SAS_END_DEV:
+		if (ex_phy->attached_sata_dev)
+			return sas_ata_clear_pending(dev, ex_phy);
+	default:
+		return -ENODEV;
 	}
+}
 
-	switch (dev->sata_dev.command_set) {
-		case ATA_COMMAND_SET:
-			SAS_DPRINTK("%s: Found ATA device.\n", __func__);
-			*class = ATA_DEV_ATA;
-			break;
-		case ATAPI_COMMAND_SET:
-			SAS_DPRINTK("%s: Found ATAPI device.\n", __func__);
-			*class = ATA_DEV_ATAPI;
-			break;
-		default:
-			SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
-				    __func__,
-				    dev->sata_dev.command_set);
-			*class = ATA_DEV_UNKNOWN;
-			break;
+static int local_ata_check_ready(struct ata_link *link)
+{
+	struct ata_port *ap = link->ap;
+	struct domain_device *dev = ap->private_data;
+	struct sas_internal *i = dev_to_sas_internal(dev);
+
+	if (i->dft->lldd_ata_check_ready)
+		return i->dft->lldd_ata_check_ready(dev);
+	else {
+		/* lldd's that don't implement 'ready' checking get the
+		 * old default behavior of not coordinating reset
+		 * recovery with libata
+		 */
+		return 1;
 	}
+}
 
-	ap->cbl = ATA_CBL_SATA;
-	return ret;
+static int sas_ata_printk(const char *level, const struct domain_device *ddev,
+			  const char *fmt, ...)
+{
+	struct ata_port *ap = ddev->sata_dev.ap;
+	struct device *dev = &ddev->rphy->dev;
+	struct va_format vaf;
+	va_list args;
+	int r;
+
+	va_start(args, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	r = printk("%ssas: ata%u: %s: %pV",
+		   level, ap->print_id, dev_name(dev), &vaf);
+
+	va_end(args);
+
+	return r;
 }
 
-static int sas_ata_soft_reset(struct ata_link *link, unsigned int *class,
-			       unsigned long deadline)
+static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class,
+			      unsigned long deadline)
 {
+	int ret = 0, res;
+	struct sas_phy *phy;
 	struct ata_port *ap = link->ap;
+	int (*check_ready)(struct ata_link *link);
 	struct domain_device *dev = ap->private_data;
-	struct sas_internal *i =
-		to_sas_internal(dev->port->ha->core.shost->transportt);
-	int res = TMF_RESP_FUNC_FAILED;
-	int ret = 0;
+	struct sas_internal *i = dev_to_sas_internal(dev);
 
-	if (i->dft->lldd_ata_soft_reset)
-		res = i->dft->lldd_ata_soft_reset(dev);
+	res = i->dft->lldd_I_T_nexus_reset(dev);
+	if (res == -ENODEV)
+		return res;
 
-	if (res != TMF_RESP_FUNC_COMPLETE) {
-		SAS_DPRINTK("%s: Unable to soft reset\n", __func__);
-		ret = -EAGAIN;
-	}
+	if (res != TMF_RESP_FUNC_COMPLETE)
+		sas_ata_printk(KERN_DEBUG, dev, "Unable to reset ata device?\n");
+
+	phy = sas_get_local_phy(dev);
+	if (scsi_is_sas_phy_local(phy))
+		check_ready = local_ata_check_ready;
+	else
+		check_ready = smp_ata_check_ready;
+	sas_put_local_phy(phy);
+
+	ret = ata_wait_after_reset(link, deadline, check_ready);
+	if (ret && ret != -EAGAIN)
+		sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret);
 
+	/* XXX: if the class changes during the reset the upper layer
+	 * should be informed, if the device has gone away we assume
+	 * libsas will eventually delete it
+	 */
 	switch (dev->sata_dev.command_set) {
 	case ATA_COMMAND_SET:
-		SAS_DPRINTK("%s: Found ATA device.\n", __func__);
 		*class = ATA_DEV_ATA;
 		break;
 	case ATAPI_COMMAND_SET:
-		SAS_DPRINTK("%s: Found ATAPI device.\n", __func__);
 		*class = ATA_DEV_ATAPI;
 		break;
-	default:
-		SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
-			    __func__, dev->sata_dev.command_set);
-		*class = ATA_DEV_UNKNOWN;
-		break;
 	}
 
 	ap->cbl = ATA_CBL_SATA;
 	return ret;
 }
 
+/*
+ * notify the lldd to forget the sas_task for this internal ata command
+ * that bypasses scsi-eh
+ */
+static void sas_ata_internal_abort(struct sas_task *task)
+{
+	struct sas_internal *si = dev_to_sas_internal(task->dev);
+	unsigned long flags;
+	int res;
+
+	spin_lock_irqsave(&task->task_state_lock, flags);
+	if (task->task_state_flags & SAS_TASK_STATE_ABORTED ||
+	    task->task_state_flags & SAS_TASK_STATE_DONE) {
+		spin_unlock_irqrestore(&task->task_state_lock, flags);
+		SAS_DPRINTK("%s: Task %p already finished.\n", __func__,
+			    task);
+		goto out;
+	}
+	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+	res = si->dft->lldd_abort_task(task);
+
+	spin_lock_irqsave(&task->task_state_lock, flags);
+	if (task->task_state_flags & SAS_TASK_STATE_DONE ||
+	    res == TMF_RESP_FUNC_COMPLETE) {
+		spin_unlock_irqrestore(&task->task_state_lock, flags);
+		goto out;
+	}
+
+	/* XXX we are not prepared to deal with ->lldd_abort_task()
+	 * failures.  TODO: lldds need to unconditionally forget about
+	 * aborted ata tasks, otherwise we (likely) leak the sas task
+	 * here
+	 */
+	SAS_DPRINTK("%s: Task %p leaked.\n", __func__, task);
+
+	if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
+		task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+	return;
+ out:
+	list_del_init(&task->list);
+	sas_free_task(task);
+}
+
 static void sas_ata_post_internal(struct ata_queued_cmd *qc)
 {
 	if (qc->flags & ATA_QCFLAG_FAILED)
@@ -340,30 +496,35 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
 
 	if (qc->err_mask) {
 		/*
-		 * Find the sas_task and kill it.  By this point,
-		 * libata has decided to kill the qc, so we needn't
-		 * bother with sas_ata_task_done.  But we still
-		 * ought to abort the task.
+		 * Find the sas_task and kill it.  By this point, libata
+		 * has decided to kill the qc and has frozen the port.
+		 * In this state sas_ata_task_done() will no longer free
+		 * the sas_task, so we need to notify the lldd (via
+		 * ->lldd_abort_task) that the task is dead and free it
+		 *  ourselves.
 		 */
 		struct sas_task *task = qc->lldd_task;
-		unsigned long flags;
 
 		qc->lldd_task = NULL;
-		if (task) {
-			/* Should this be a AT(API) device reset? */
-			spin_lock_irqsave(&task->task_state_lock, flags);
-			task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
-			spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-			task->uldd_task = NULL;
-			__sas_task_abort(task);
-		}
+		if (!task)
+			return;
+		task->uldd_task = NULL;
+		sas_ata_internal_abort(task);
 	}
 }
 
+
+static void sas_ata_set_dmamode(struct ata_port *ap, struct ata_device *ata_dev)
+{
+	struct domain_device *dev = ap->private_data;
+	struct sas_internal *i = dev_to_sas_internal(dev);
+
+	if (i->dft->lldd_ata_set_dmamode)
+		i->dft->lldd_ata_set_dmamode(dev);
+}
+
 static struct ata_port_operations sas_sata_ops = {
 	.prereset		= ata_std_prereset,
-	.softreset		= sas_ata_soft_reset,
 	.hardreset		= sas_ata_hard_reset,
 	.postreset		= ata_std_postreset,
 	.error_handler		= ata_std_error_handler,
@@ -374,6 +535,7 @@ static struct ata_port_operations sas_sata_ops = {
 	.qc_fill_rtf		= sas_ata_qc_fill_rtf,
 	.port_start		= ata_sas_port_start,
 	.port_stop		= ata_sas_port_stop,
+	.set_dmamode		= sas_ata_set_dmamode,
 };
 
 static struct ata_port_info sata_port_info = {
@@ -384,11 +546,10 @@ static struct ata_port_info sata_port_info = {
 	.port_ops = &sas_sata_ops
 };
 
-int sas_ata_init_host_and_port(struct domain_device *found_dev,
-			       struct scsi_target *starget)
+int sas_ata_init_host_and_port(struct domain_device *found_dev)
 {
-	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
-	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+	struct sas_ha_struct *ha = found_dev->port->ha;
+	struct Scsi_Host *shost = ha->core.shost;
 	struct ata_port *ap;
 
 	ata_host_init(&found_dev->sata_dev.ata_host,
@@ -406,6 +567,8 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
 	ap->private_data = found_dev;
 	ap->cbl = ATA_CBL_SATA;
 	ap->scsi_host = shost;
+	/* publish initialized ata port */
+	smp_wmb();
 	found_dev->sata_dev.ap = ap;
 
 	return 0;
@@ -436,168 +599,14 @@ void sas_ata_task_abort(struct sas_task *task)
 	complete(waiting);
 }
 
-static void sas_task_timedout(unsigned long _task)
-{
-	struct sas_task *task = (void *) _task;
-	unsigned long flags;
-
-	spin_lock_irqsave(&task->task_state_lock, flags);
-	if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
-		task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-	spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-	complete(&task->completion);
-}
-
-static void sas_disc_task_done(struct sas_task *task)
-{
-	if (!del_timer(&task->timer))
-		return;
-	complete(&task->completion);
-}
-
-#define SAS_DEV_TIMEOUT 10
-
-/**
- * sas_execute_task -- Basic task processing for discovery
- * @task: the task to be executed
- * @buffer: pointer to buffer to do I/O
- * @size: size of @buffer
- * @dma_dir: DMA direction.  DMA_xxx
- */
-static int sas_execute_task(struct sas_task *task, void *buffer, int size,
-			    enum dma_data_direction dma_dir)
-{
-	int res = 0;
-	struct scatterlist *scatter = NULL;
-	struct task_status_struct *ts = &task->task_status;
-	int num_scatter = 0;
-	int retries = 0;
-	struct sas_internal *i =
-		to_sas_internal(task->dev->port->ha->core.shost->transportt);
-
-	if (dma_dir != DMA_NONE) {
-		scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
-		if (!scatter)
-			goto out;
-
-		sg_init_one(scatter, buffer, size);
-		num_scatter = 1;
-	}
-
-	task->task_proto = task->dev->tproto;
-	task->scatter = scatter;
-	task->num_scatter = num_scatter;
-	task->total_xfer_len = size;
-	task->data_dir = dma_dir;
-	task->task_done = sas_disc_task_done;
-	if (dma_dir != DMA_NONE &&
-	    sas_protocol_ata(task->task_proto)) {
-		task->num_scatter = dma_map_sg(task->dev->port->ha->dev,
-					       task->scatter,
-					       task->num_scatter,
-					       task->data_dir);
-	}
-
-	for (retries = 0; retries < 5; retries++) {
-		task->task_state_flags = SAS_TASK_STATE_PENDING;
-		init_completion(&task->completion);
-
-		task->timer.data = (unsigned long) task;
-		task->timer.function = sas_task_timedout;
-		task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
-		add_timer(&task->timer);
-
-		res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
-		if (res) {
-			del_timer(&task->timer);
-			SAS_DPRINTK("executing SAS discovery task failed:%d\n",
-				    res);
-			goto ex_err;
-		}
-		wait_for_completion(&task->completion);
-		res = -ECOMM;
-		if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
-			int res2;
-			SAS_DPRINTK("task aborted, flags:0x%x\n",
-				    task->task_state_flags);
-			res2 = i->dft->lldd_abort_task(task);
-			SAS_DPRINTK("came back from abort task\n");
-			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
-				if (res2 == TMF_RESP_FUNC_COMPLETE)
-					continue; /* Retry the task */
-				else
-					goto ex_err;
-			}
-		}
-		if (task->task_status.stat == SAM_STAT_BUSY ||
-			   task->task_status.stat == SAM_STAT_TASK_SET_FULL ||
-			   task->task_status.stat == SAS_QUEUE_FULL) {
-			SAS_DPRINTK("task: q busy, sleeping...\n");
-			schedule_timeout_interruptible(HZ);
-		} else if (task->task_status.stat == SAM_STAT_CHECK_CONDITION) {
-			struct scsi_sense_hdr shdr;
-
-			if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
-						  &shdr)) {
-				SAS_DPRINTK("couldn't normalize sense\n");
-				continue;
-			}
-			if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
-			    (shdr.sense_key == 2 && shdr.asc == 4 &&
-			     shdr.ascq == 1)) {
-				SAS_DPRINTK("device %016llx LUN: %016llx "
-					    "powering up or not ready yet, "
-					    "sleeping...\n",
-					    SAS_ADDR(task->dev->sas_addr),
-					    SAS_ADDR(task->ssp_task.LUN));
-
-				schedule_timeout_interruptible(5*HZ);
-			} else if (shdr.sense_key == 1) {
-				res = 0;
-				break;
-			} else if (shdr.sense_key == 5) {
-				break;
-			} else {
-				SAS_DPRINTK("dev %016llx LUN: %016llx "
-					    "sense key:0x%x ASC:0x%x ASCQ:0x%x"
-					    "\n",
-					    SAS_ADDR(task->dev->sas_addr),
-					    SAS_ADDR(task->ssp_task.LUN),
-					    shdr.sense_key,
-					    shdr.asc, shdr.ascq);
-			}
-		} else if (task->task_status.resp != SAS_TASK_COMPLETE ||
-			   task->task_status.stat != SAM_STAT_GOOD) {
-			SAS_DPRINTK("task finished with resp:0x%x, "
-				    "stat:0x%x\n",
-				    task->task_status.resp,
-				    task->task_status.stat);
-			goto ex_err;
-		} else {
-			res = 0;
-			break;
-		}
-	}
-ex_err:
-	if (dma_dir != DMA_NONE) {
-		if (sas_protocol_ata(task->task_proto))
-			dma_unmap_sg(task->dev->port->ha->dev,
-				     task->scatter, task->num_scatter,
-				     task->data_dir);
-		kfree(scatter);
-	}
-out:
-	return res;
-}
-
-/* ---------- SATA ---------- */
-
 static void sas_get_ata_command_set(struct domain_device *dev)
 {
 	struct dev_to_host_fis *fis =
 		(struct dev_to_host_fis *) dev->frame_rcvd;
 
+	if (dev->dev_type == SATA_PENDING)
+		return;
+
 	if ((fis->sector_count == 1 && /* ATA */
 	     fis->lbal         == 1 &&
 	     fis->lbam         == 0 &&
@@ -636,224 +645,152 @@ static void sas_get_ata_command_set(struct domain_device *dev)
 		dev->sata_dev.command_set = ATAPI_COMMAND_SET;
 }
 
-/**
- * sas_issue_ata_cmd -- Basic SATA command processing for discovery
- * @dev: the device to send the command to
- * @command: the command register
- * @features: the features register
- * @buffer: pointer to buffer to do I/O
- * @size: size of @buffer
- * @dma_dir: DMA direction.  DMA_xxx
- */
-static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
-			     u8 features, void *buffer, int size,
-			     enum dma_data_direction dma_dir)
-{
-	int res = 0;
-	struct sas_task *task;
-	struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
-		&dev->frame_rcvd[0];
-
-	res = -ENOMEM;
-	task = sas_alloc_task(GFP_KERNEL);
-	if (!task)
-		goto out;
-
-	task->dev = dev;
-
-	task->ata_task.fis.fis_type = 0x27;
-	task->ata_task.fis.command = command;
-	task->ata_task.fis.features = features;
-	task->ata_task.fis.device = d2h_fis->device;
-	task->ata_task.retry_count = 1;
-
-	res = sas_execute_task(task, buffer, size, dma_dir);
-
-	sas_free_task(task);
-out:
-	return res;
-}
-
-#define ATA_IDENTIFY_DEV         0xEC
-#define ATA_IDENTIFY_PACKET_DEV  0xA1
-#define ATA_SET_FEATURES         0xEF
-#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
-
-/**
- * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
- * @dev: STP/SATA device of interest (ATA/ATAPI)
- *
- * The LLDD has already been notified of this device, so that we can
- * send FISes to it.  Here we try to get IDENTIFY DEVICE or IDENTIFY
- * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
- * performance for this device.
- */
-static int sas_discover_sata_dev(struct domain_device *dev)
+void sas_probe_sata(struct asd_sas_port *port)
 {
-	int     res;
-	__le16  *identify_x;
-	u8      command;
+	struct domain_device *dev, *n;
+	int err;
 
-	identify_x = kzalloc(512, GFP_KERNEL);
-	if (!identify_x)
-		return -ENOMEM;
-
-	if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
-		dev->sata_dev.identify_device = identify_x;
-		command = ATA_IDENTIFY_DEV;
-	} else {
-		dev->sata_dev.identify_packet_device = identify_x;
-		command = ATA_IDENTIFY_PACKET_DEV;
-	}
+	mutex_lock(&port->ha->disco_mutex);
+	list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
+		if (!dev_is_sata(dev))
+			continue;
 
-	res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
-				DMA_FROM_DEVICE);
-	if (res)
-		goto out_err;
-
-	/* lives on the media? */
-	if (le16_to_cpu(identify_x[0]) & 4) {
-		/* incomplete response */
-		SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
-			    "dev %llx\n", SAS_ADDR(dev->sas_addr));
-		if (!(identify_x[83] & cpu_to_le16(1<<6)))
-			goto cont1;
-		res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
-					ATA_FEATURE_PUP_STBY_SPIN_UP,
-					NULL, 0, DMA_NONE);
-		if (res)
-			goto cont1;
-
-		schedule_timeout_interruptible(5*HZ); /* More time? */
-		res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
-					DMA_FROM_DEVICE);
-		if (res)
-			goto out_err;
+		err = sas_ata_init_host_and_port(dev);
+		if (err)
+			sas_fail_probe(dev, __func__, err);
+		else
+			ata_sas_async_port_init(dev->sata_dev.ap);
 	}
-cont1:
-	/* XXX Hint: register this SATA device with SATL.
-	   When this returns, dev->sata_dev->lu is alive and
-	   present.
-	sas_satl_register_dev(dev);
-	*/
+	mutex_unlock(&port->ha->disco_mutex);
 
-	sas_fill_in_rphy(dev, dev->rphy);
+	list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
+		if (!dev_is_sata(dev))
+			continue;
 
-	return 0;
-out_err:
-	dev->sata_dev.identify_packet_device = NULL;
-	dev->sata_dev.identify_device = NULL;
-	kfree(identify_x);
-	return res;
-}
+		sas_ata_wait_eh(dev);
 
-static int sas_discover_sata_pm(struct domain_device *dev)
-{
-	return -ENODEV;
+		/* if libata could not bring the link up, don't surface
+		 * the device
+		 */
+		if (ata_dev_disabled(sas_to_ata_dev(dev)))
+			sas_fail_probe(dev, __func__, -ENODEV);
+	}
 }
 
 /**
  * sas_discover_sata -- discover an STP/SATA domain device
  * @dev: pointer to struct domain_device of interest
  *
- * First we notify the LLDD of this device, so we can send frames to
- * it.  Then depending on the type of device we call the appropriate
- * discover functions.  Once device discover is done, we notify the
- * LLDD so that it can fine-tune its parameters for the device, by
- * removing it and then adding it.  That is, the second time around,
- * the driver would have certain fields, that it is looking at, set.
- * Finally we initialize the kobj so that the device can be added to
- * the system at registration time.  Devices directly attached to a HA
- * port, have no parents.  All other devices do, and should have their
- * "parent" pointer set appropriately before calling this function.
+ * Devices directly attached to a HA port, have no parents.  All other
+ * devices do, and should have their "parent" pointer set appropriately
+ * before calling this function.
  */
 int sas_discover_sata(struct domain_device *dev)
 {
 	int res;
 
+	if (dev->dev_type == SATA_PM)
+		return -ENODEV;
+
 	sas_get_ata_command_set(dev);
+	sas_fill_in_rphy(dev, dev->rphy);
 
 	res = sas_notify_lldd_dev_found(dev);
 	if (res)
 		return res;
 
-	switch (dev->dev_type) {
-	case SATA_DEV:
-		res = sas_discover_sata_dev(dev);
-		break;
-	case SATA_PM:
-		res = sas_discover_sata_pm(dev);
-		break;
-	default:
-		break;
-	}
-	sas_notify_lldd_dev_gone(dev);
-	if (!res) {
-		sas_notify_lldd_dev_found(dev);
-		res = sas_rphy_add(dev->rphy);
-	}
-
-	return res;
+	sas_discover_event(dev->port, DISCE_PROBE);
+	return 0;
 }
 
-void sas_ata_strategy_handler(struct Scsi_Host *shost)
+static void async_sas_ata_eh(void *data, async_cookie_t cookie)
 {
-	struct scsi_device *sdev;
+	struct domain_device *dev = data;
+	struct ata_port *ap = dev->sata_dev.ap;
+	struct sas_ha_struct *ha = dev->port->ha;
 
-	shost_for_each_device(sdev, shost) {
-		struct domain_device *ddev = sdev_to_domain_dev(sdev);
-		struct ata_port *ap = ddev->sata_dev.ap;
+	/* hold a reference over eh since we may be racing with final
+	 * remove once all commands are completed
+	 */
+	kref_get(&dev->kref);
+	sas_ata_printk(KERN_DEBUG, dev, "dev error handler\n");
+	ata_scsi_port_error_handler(ha->core.shost, ap);
+	sas_put_device(dev);
+}
 
-		if (!dev_is_sata(ddev))
-			continue;
+static bool sas_ata_dev_eh_valid(struct domain_device *dev)
+{
+	struct ata_port *ap;
 
-		ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler");
-		ata_scsi_port_error_handler(shost, ap);
-	}
+	if (!dev_is_sata(dev))
+		return false;
+	ap = dev->sata_dev.ap;
+	/* consume fully initialized ata ports */
+	smp_rmb();
+	return !!ap;
 }
 
-int sas_ata_timed_out(struct scsi_cmnd *cmd, struct sas_task *task,
-		      enum blk_eh_timer_return *rtn)
+void sas_ata_strategy_handler(struct Scsi_Host *shost)
 {
-	struct domain_device *ddev = cmd_to_domain_dev(cmd);
+	struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+	LIST_HEAD(async);
+	int i;
+
+	/* it's ok to defer revalidation events during ata eh, these
+	 * disks are in one of three states:
+	 * 1/ present for initial domain discovery, and these
+	 *    resets will cause bcn flutters
+	 * 2/ hot removed, we'll discover that after eh fails
+	 * 3/ hot added after initial discovery, lost the race, and need
+	 *    to catch the next train.
+	 */
+	sas_disable_revalidation(sas_ha);
 
-	if (!dev_is_sata(ddev) || task)
-		return 0;
+	spin_lock_irq(&sas_ha->phy_port_lock);
+	for (i = 0; i < sas_ha->num_phys; i++) {
+		struct asd_sas_port *port = sas_ha->sas_port[i];
+		struct domain_device *dev;
 
-	/* we're a sata device with no task, so this must be a libata
-	 * eh timeout.  Ideally should hook into libata timeout
-	 * handling, but there's no point, it just wants to activate
-	 * the eh thread */
-	*rtn = BLK_EH_NOT_HANDLED;
-	return 1;
+		spin_lock(&port->dev_list_lock);
+		list_for_each_entry(dev, &port->dev_list, dev_list_node) {
+			if (!sas_ata_dev_eh_valid(dev))
+				continue;
+			async_schedule_domain(async_sas_ata_eh, dev, &async);
+		}
+		spin_unlock(&port->dev_list_lock);
+	}
+	spin_unlock_irq(&sas_ha->phy_port_lock);
+
+	async_synchronize_full_domain(&async);
+
+	sas_enable_revalidation(sas_ha);
 }
 
-int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
-	       struct list_head *done_q)
+void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
+		struct list_head *done_q)
 {
-	int rtn = 0;
 	struct scsi_cmnd *cmd, *n;
-	struct ata_port *ap;
+	struct domain_device *eh_dev;
 
 	do {
 		LIST_HEAD(sata_q);
-
-		ap = NULL;
+		eh_dev = NULL;
 
 		list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
 			struct domain_device *ddev = cmd_to_domain_dev(cmd);
 
 			if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd))
 				continue;
-			if (ap && ap != ddev->sata_dev.ap)
+			if (eh_dev && eh_dev != ddev)
 				continue;
-			ap = ddev->sata_dev.ap;
-			rtn = 1;
+			eh_dev = ddev;
 			list_move(&cmd->eh_entry, &sata_q);
 		}
 
 		if (!list_empty(&sata_q)) {
-			ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata cmd error handler\n");
+			struct ata_port *ap = eh_dev->sata_dev.ap;
+
+			sas_ata_printk(KERN_DEBUG, eh_dev, "cmd error handler\n");
 			ata_scsi_cmd_error_handler(shost, ap, &sata_q);
 			/*
 			 * ata's error handler may leave the cmd on the list
@@ -869,7 +806,36 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
 			while (!list_empty(&sata_q))
 				list_del_init(sata_q.next);
 		}
-	} while (ap);
+	} while (eh_dev);
+}
+
+void sas_ata_schedule_reset(struct domain_device *dev)
+{
+	struct ata_eh_info *ehi;
+	struct ata_port *ap;
+	unsigned long flags;
+
+	if (!dev_is_sata(dev))
+		return;
+
+	ap = dev->sata_dev.ap;
+	ehi = &ap->link.eh_info;
+
+	spin_lock_irqsave(ap->lock, flags);
+	ehi->err_mask |= AC_ERR_TIMEOUT;
+	ehi->action |= ATA_EH_RESET;
+	ata_port_schedule_eh(ap);
+	spin_unlock_irqrestore(ap->lock, flags);
+}
+EXPORT_SYMBOL_GPL(sas_ata_schedule_reset);
+
+void sas_ata_wait_eh(struct domain_device *dev)
+{
+	struct ata_port *ap;
+
+	if (!dev_is_sata(dev))
+		return;
 
-	return rtn;
+	ap = dev->sata_dev.ap;
+	ata_port_wait_eh(ap);
 }
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 54a5199..a29c5cc 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -30,29 +30,30 @@
 
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_sas.h>
+#include <scsi/sas_ata.h>
 #include "../scsi_sas_internal.h"
 
 /* ---------- Basic task processing for discovery purposes ---------- */
 
 void sas_init_dev(struct domain_device *dev)
 {
-        INIT_LIST_HEAD(&dev->siblings);
-        INIT_LIST_HEAD(&dev->dev_list_node);
-        switch (dev->dev_type) {
-        case SAS_END_DEV:
-                break;
-        case EDGE_DEV:
-        case FANOUT_DEV:
-                INIT_LIST_HEAD(&dev->ex_dev.children);
-                break;
-        case SATA_DEV:
-        case SATA_PM:
-        case SATA_PM_PORT:
-                INIT_LIST_HEAD(&dev->sata_dev.children);
-                break;
-        default:
-                break;
-        }
+	switch (dev->dev_type) {
+	case SAS_END_DEV:
+		break;
+	case EDGE_DEV:
+	case FANOUT_DEV:
+		INIT_LIST_HEAD(&dev->ex_dev.children);
+		mutex_init(&dev->ex_dev.cmd_mutex);
+		break;
+	case SATA_DEV:
+	case SATA_PM:
+	case SATA_PM_PORT:
+	case SATA_PENDING:
+		INIT_LIST_HEAD(&dev->sata_dev.children);
+		break;
+	default:
+		break;
+	}
 }
 
 /* ---------- Domain device discovery ---------- */
@@ -68,19 +69,18 @@ void sas_init_dev(struct domain_device *dev)
  */
 static int sas_get_port_device(struct asd_sas_port *port)
 {
-	unsigned long flags;
 	struct asd_sas_phy *phy;
 	struct sas_rphy *rphy;
 	struct domain_device *dev;
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	dev = sas_alloc_device();
 	if (!dev)
 		return -ENOMEM;
 
-	spin_lock_irqsave(&port->phy_list_lock, flags);
+	spin_lock_irq(&port->phy_list_lock);
 	if (list_empty(&port->phy_list)) {
-		spin_unlock_irqrestore(&port->phy_list_lock, flags);
-		kfree(dev);
+		spin_unlock_irq(&port->phy_list_lock);
+		sas_put_device(dev);
 		return -ENODEV;
 	}
 	phy = container_of(port->phy_list.next, struct asd_sas_phy, port_phy_el);
@@ -88,7 +88,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
 	memcpy(dev->frame_rcvd, phy->frame_rcvd, min(sizeof(dev->frame_rcvd),
 					     (size_t)phy->frame_rcvd_size));
 	spin_unlock(&phy->frame_rcvd_lock);
-	spin_unlock_irqrestore(&port->phy_list_lock, flags);
+	spin_unlock_irq(&port->phy_list_lock);
 
 	if (dev->frame_rcvd[0] == 0x34 && port->oob_mode == SATA_OOB_MODE) {
 		struct dev_to_host_fis *fis =
@@ -130,9 +130,14 @@ static int sas_get_port_device(struct asd_sas_port *port)
 	}
 
 	if (!rphy) {
-		kfree(dev);
+		sas_put_device(dev);
 		return -ENODEV;
 	}
+
+	spin_lock_irq(&port->phy_list_lock);
+	list_for_each_entry(phy, &port->phy_list, port_phy_el)
+		sas_phy_set_target(phy, dev);
+	spin_unlock_irq(&port->phy_list_lock);
 	rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;
 	memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);
 	sas_fill_in_rphy(dev, rphy);
@@ -147,11 +152,17 @@ static int sas_get_port_device(struct asd_sas_port *port)
 	memset(port->disc.eeds_a, 0, SAS_ADDR_SIZE);
 	memset(port->disc.eeds_b, 0, SAS_ADDR_SIZE);
 	port->disc.max_level = 0;
+	sas_device_set_phy(dev, port->port);
 
 	dev->rphy = rphy;
-	spin_lock_irq(&port->dev_list_lock);
-	list_add_tail(&dev->dev_list_node, &port->dev_list);
-	spin_unlock_irq(&port->dev_list_lock);
+
+	if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV)
+		list_add_tail(&dev->disco_list_node, &port->disco_list);
+	else {
+		spin_lock_irq(&port->dev_list_lock);
+		list_add_tail(&dev->dev_list_node, &port->dev_list);
+		spin_unlock_irq(&port->dev_list_lock);
+	}
 
 	return 0;
 }
@@ -173,6 +184,7 @@ int sas_notify_lldd_dev_found(struct domain_device *dev)
 			       dev_name(sas_ha->dev),
 			       SAS_ADDR(dev->sas_addr), res);
 		}
+		kref_get(&dev->kref);
 	}
 	return res;
 }
@@ -184,12 +196,40 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
 	struct Scsi_Host *shost = sas_ha->core.shost;
 	struct sas_internal *i = to_sas_internal(shost->transportt);
 
-	if (i->dft->lldd_dev_gone)
+	if (i->dft->lldd_dev_gone) {
 		i->dft->lldd_dev_gone(dev);
+		sas_put_device(dev);
+	}
 }
 
-/* ---------- Common/dispatchers ---------- */
+static void sas_probe_devices(struct work_struct *work)
+{
+	struct domain_device *dev, *n;
+	struct sas_discovery_event *ev =
+		container_of(work, struct sas_discovery_event, work);
+	struct asd_sas_port *port = ev->port;
+
+	clear_bit(DISCE_PROBE, &port->disc.pending);
+
+	/* devices must be domain members before link recovery and probe */
+	list_for_each_entry(dev, &port->disco_list, disco_list_node) {
+		spin_lock_irq(&port->dev_list_lock);
+		list_add_tail(&dev->dev_list_node, &port->dev_list);
+		spin_unlock_irq(&port->dev_list_lock);
+	}
+
+	sas_probe_sata(port);
+
+	list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
+		int err;
 
+		err = sas_rphy_add(dev->rphy);
+		if (err)
+			sas_fail_probe(dev, __func__, err);
+		else
+			list_del_init(&dev->disco_list_node);
+	}
+}
 
 /**
  * sas_discover_end_dev -- discover an end device (SSP, etc)
@@ -203,22 +243,36 @@ int sas_discover_end_dev(struct domain_device *dev)
 
 	res = sas_notify_lldd_dev_found(dev);
 	if (res)
-		goto out_err2;
-
-	res = sas_rphy_add(dev->rphy);
-	if (res)
-		goto out_err;
+		return res;
+	sas_discover_event(dev->port, DISCE_PROBE);
 
 	return 0;
-
-out_err:
-	sas_notify_lldd_dev_gone(dev);
-out_err2:
-	return res;
 }
 
 /* ---------- Device registration and unregistration ---------- */
 
+void sas_free_device(struct kref *kref)
+{
+	struct domain_device *dev = container_of(kref, typeof(*dev), kref);
+
+	if (dev->parent)
+		sas_put_device(dev->parent);
+
+	sas_port_put_phy(dev->phy);
+	dev->phy = NULL;
+
+	/* remove the phys and ports, everything else should be gone */
+	if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV)
+		kfree(dev->ex_dev.ex_phy);
+
+	if (dev_is_sata(dev) && dev->sata_dev.ap) {
+		ata_sas_port_destroy(dev->sata_dev.ap);
+		dev->sata_dev.ap = NULL;
+	}
+
+	kfree(dev);
+}
+
 static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_device *dev)
 {
 	sas_notify_lldd_dev_gone(dev);
@@ -230,34 +284,86 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d
 	spin_lock_irq(&port->dev_list_lock);
 	list_del_init(&dev->dev_list_node);
 	spin_unlock_irq(&port->dev_list_lock);
+
+	sas_put_device(dev);
 }
 
-void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
+static void sas_destruct_devices(struct work_struct *work)
 {
-	if (dev->rphy) {
+	struct domain_device *dev, *n;
+	struct sas_discovery_event *ev =
+		container_of(work, struct sas_discovery_event, work);
+	struct asd_sas_port *port = ev->port;
+
+	clear_bit(DISCE_DESTRUCT, &port->disc.pending);
+
+	list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) {
+		list_del_init(&dev->disco_list_node);
+
 		sas_remove_children(&dev->rphy->dev);
 		sas_rphy_delete(dev->rphy);
 		dev->rphy = NULL;
+		sas_unregister_common_dev(port, dev);
 	}
-	if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) {
-		/* remove the phys and ports, everything else should be gone */
-		kfree(dev->ex_dev.ex_phy);
-		dev->ex_dev.ex_phy = NULL;
+}
+
+void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
+{
+	if (!test_bit(SAS_DEV_DESTROY, &dev->state) &&
+	    !list_empty(&dev->disco_list_node)) {
+		/* this rphy never saw sas_rphy_add */
+		list_del_init(&dev->disco_list_node);
+		sas_rphy_free(dev->rphy);
+		dev->rphy = NULL;
+		sas_unregister_common_dev(port, dev);
+	}
+
+	if (dev->rphy && !test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) {
+		sas_rphy_unlink(dev->rphy);
+		list_move_tail(&dev->disco_list_node, &port->destroy_list);
+		sas_discover_event(dev->port, DISCE_DESTRUCT);
 	}
-	sas_unregister_common_dev(port, dev);
 }
 
-void sas_unregister_domain_devices(struct asd_sas_port *port)
+void sas_unregister_domain_devices(struct asd_sas_port *port, int gone)
 {
 	struct domain_device *dev, *n;
 
-	list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node)
+	list_for_each_entry_safe_reverse(dev, n, &port->dev_list, dev_list_node) {
+		if (gone)
+			set_bit(SAS_DEV_GONE, &dev->state);
+		sas_unregister_dev(port, dev);
+	}
+
+	list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node)
+		sas_unregister_dev(port, dev);
+	list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node)
 		sas_unregister_dev(port, dev);
 
 	port->port->rphy = NULL;
 
 }
 
+void sas_device_set_phy(struct domain_device *dev, struct sas_port *port)
+{
+	struct sas_ha_struct *ha;
+	struct sas_phy *new_phy;
+
+	if (!dev)
+		return;
+
+	ha = dev->port->ha;
+	new_phy = sas_port_get_phy(port);
+
+	/* pin and record last seen phy */
+	spin_lock_irq(&ha->phy_port_lock);
+	if (new_phy) {
+		sas_port_put_phy(dev->phy);
+		dev->phy = new_phy;
+	}
+	spin_unlock_irq(&ha->phy_port_lock);
+}
+
 /* ---------- Discovery and Revalidation ---------- */
 
 /**
@@ -277,8 +383,7 @@ static void sas_discover_domain(struct work_struct *work)
 		container_of(work, struct sas_discovery_event, work);
 	struct asd_sas_port *port = ev->port;
 
-	sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock,
-			&port->disc.pending);
+	clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending);
 
 	if (port->port_dev)
 		return;
@@ -318,11 +423,12 @@ static void sas_discover_domain(struct work_struct *work)
 		sas_rphy_free(dev->rphy);
 		dev->rphy = NULL;
 
+		list_del_init(&dev->disco_list_node);
 		spin_lock_irq(&port->dev_list_lock);
 		list_del_init(&dev->dev_list_node);
 		spin_unlock_irq(&port->dev_list_lock);
 
-		kfree(dev); /* not kobject_register-ed yet */
+		sas_put_device(dev);
 		port->port_dev = NULL;
 	}
 
@@ -336,21 +442,51 @@ static void sas_revalidate_domain(struct work_struct *work)
 	struct sas_discovery_event *ev =
 		container_of(work, struct sas_discovery_event, work);
 	struct asd_sas_port *port = ev->port;
+	struct sas_ha_struct *ha = port->ha;
+
+	/* prevent revalidation from finding sata links in recovery */
+	mutex_lock(&ha->disco_mutex);
+	if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) {
+		SAS_DPRINTK("REVALIDATION DEFERRED on port %d, pid:%d\n",
+			    port->id, task_pid_nr(current));
+		goto out;
+	}
 
-	sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock,
-			&port->disc.pending);
+	clear_bit(DISCE_REVALIDATE_DOMAIN, &port->disc.pending);
 
 	SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
 		    task_pid_nr(current));
+
 	if (port->port_dev)
 		res = sas_ex_revalidate_domain(port->port_dev);
 
 	SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
 		    port->id, task_pid_nr(current), res);
+ out:
+	mutex_unlock(&ha->disco_mutex);
 }
 
 /* ---------- Events ---------- */
 
+static void sas_chain_work(struct sas_ha_struct *ha, struct work_struct *work)
+{
+	/* chained work is not subject to SA_HA_DRAINING or SAS_HA_REGISTERED */
+	scsi_queue_work(ha->core.shost, work);
+}
+
+static void sas_chain_event(int event, unsigned long *pending,
+			    struct work_struct *work,
+			    struct sas_ha_struct *ha)
+{
+	if (!test_and_set_bit(event, pending)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&ha->state_lock, flags);
+		sas_chain_work(ha, work);
+		spin_unlock_irqrestore(&ha->state_lock, flags);
+	}
+}
+
 int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
 {
 	struct sas_discovery *disc;
@@ -361,8 +497,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
 
 	BUG_ON(ev >= DISC_NUM_EVENTS);
 
-	sas_queue_event(ev, &disc->disc_event_lock, &disc->pending,
-			&disc->disc_work[ev].work, port->ha);
+	sas_chain_event(ev, &disc->pending, &disc->disc_work[ev].work, port->ha);
 
 	return 0;
 }
@@ -380,9 +515,10 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
 	static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
 		[DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
 		[DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
+		[DISCE_PROBE] = sas_probe_devices,
+		[DISCE_DESTRUCT] = sas_destruct_devices,
 	};
 
-	spin_lock_init(&disc->disc_event_lock);
 	disc->pending = 0;
 	for (i = 0; i < DISC_NUM_EVENTS; i++) {
 		INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c
index 9db30fb..16639bb 100644
--- a/drivers/scsi/libsas/sas_event.c
+++ b/drivers/scsi/libsas/sas_event.c
@@ -22,15 +22,103 @@
  *
  */
 
+#include <linux/export.h>
 #include <scsi/scsi_host.h>
 #include "sas_internal.h"
 #include "sas_dump.h"
 
+void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work)
+{
+	if (!test_bit(SAS_HA_REGISTERED, &ha->state))
+		return;
+
+	if (test_bit(SAS_HA_DRAINING, &ha->state))
+		list_add(&work->entry, &ha->defer_q);
+	else
+		scsi_queue_work(ha->core.shost, work);
+}
+
+static void sas_queue_event(int event, unsigned long *pending,
+			    struct work_struct *work,
+			    struct sas_ha_struct *ha)
+{
+	if (!test_and_set_bit(event, pending)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&ha->state_lock, flags);
+		sas_queue_work(ha, work);
+		spin_unlock_irqrestore(&ha->state_lock, flags);
+	}
+}
+
+
+void __sas_drain_work(struct sas_ha_struct *ha)
+{
+	struct workqueue_struct *wq = ha->core.shost->work_q;
+	struct work_struct *w, *_w;
+
+	set_bit(SAS_HA_DRAINING, &ha->state);
+	/* flush submitters */
+	spin_lock_irq(&ha->state_lock);
+	spin_unlock_irq(&ha->state_lock);
+
+	drain_workqueue(wq);
+
+	spin_lock_irq(&ha->state_lock);
+	clear_bit(SAS_HA_DRAINING, &ha->state);
+	list_for_each_entry_safe(w, _w, &ha->defer_q, entry) {
+		list_del_init(&w->entry);
+		sas_queue_work(ha, w);
+	}
+	spin_unlock_irq(&ha->state_lock);
+}
+
+int sas_drain_work(struct sas_ha_struct *ha)
+{
+	int err;
+
+	err = mutex_lock_interruptible(&ha->drain_mutex);
+	if (err)
+		return err;
+	if (test_bit(SAS_HA_REGISTERED, &ha->state))
+		__sas_drain_work(ha);
+	mutex_unlock(&ha->drain_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(sas_drain_work);
+
+void sas_disable_revalidation(struct sas_ha_struct *ha)
+{
+	mutex_lock(&ha->disco_mutex);
+	set_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state);
+	mutex_unlock(&ha->disco_mutex);
+}
+
+void sas_enable_revalidation(struct sas_ha_struct *ha)
+{
+	int i;
+
+	mutex_lock(&ha->disco_mutex);
+	clear_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state);
+	for (i = 0; i < ha->num_phys; i++) {
+		struct asd_sas_port *port = ha->sas_port[i];
+		const int ev = DISCE_REVALIDATE_DOMAIN;
+		struct sas_discovery *d = &port->disc;
+
+		if (!test_and_clear_bit(ev, &d->pending))
+			continue;
+
+		sas_queue_event(ev, &d->pending, &d->disc_work[ev].work, ha);
+	}
+	mutex_unlock(&ha->disco_mutex);
+}
+
 static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event)
 {
 	BUG_ON(event >= HA_NUM_EVENTS);
 
-	sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending,
+	sas_queue_event(event, &sas_ha->pending,
 			&sas_ha->ha_events[event].work, sas_ha);
 }
 
@@ -40,7 +128,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
 
 	BUG_ON(event >= PORT_NUM_EVENTS);
 
-	sas_queue_event(event, &ha->event_lock, &phy->port_events_pending,
+	sas_queue_event(event, &phy->port_events_pending,
 			&phy->port_events[event].work, ha);
 }
 
@@ -50,7 +138,7 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
 
 	BUG_ON(event >= PHY_NUM_EVENTS);
 
-	sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending,
+	sas_queue_event(event, &phy->phy_events_pending,
 			&phy->phy_events[event].work, ha);
 }
 
@@ -62,8 +150,6 @@ int sas_init_events(struct sas_ha_struct *sas_ha)
 
 	int i;
 
-	spin_lock_init(&sas_ha->event_lock);
-
 	for (i = 0; i < HA_NUM_EVENTS; i++) {
 		INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]);
 		sas_ha->ha_events[i].ha = sas_ha;
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 1b831c5..0ab3796 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -28,6 +28,7 @@
 
 #include "sas_internal.h"
 
+#include <scsi/sas_ata.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_sas.h>
 #include "../scsi_sas_internal.h"
@@ -50,14 +51,14 @@ static void smp_task_timedout(unsigned long _task)
 		task->task_state_flags |= SAS_TASK_STATE_ABORTED;
 	spin_unlock_irqrestore(&task->task_state_lock, flags);
 
-	complete(&task->completion);
+	complete(&task->slow_task->completion);
 }
 
 static void smp_task_done(struct sas_task *task)
 {
-	if (!del_timer(&task->timer))
+	if (!del_timer(&task->slow_task->timer))
 		return;
-	complete(&task->completion);
+	complete(&task->slow_task->completion);
 }
 
 /* Give it some long enough timeout. In seconds. */
@@ -71,11 +72,18 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
 	struct sas_internal *i =
 		to_sas_internal(dev->port->ha->core.shost->transportt);
 
+	mutex_lock(&dev->ex_dev.cmd_mutex);
 	for (retry = 0; retry < 3; retry++) {
-		task = sas_alloc_task(GFP_KERNEL);
-		if (!task)
-			return -ENOMEM;
+		if (test_bit(SAS_DEV_GONE, &dev->state)) {
+			res = -ECOMM;
+			break;
+		}
 
+		task = sas_alloc_slow_task(GFP_KERNEL);
+		if (!task) {
+			res = -ENOMEM;
+			break;
+		}
 		task->dev = dev;
 		task->task_proto = dev->tproto;
 		sg_init_one(&task->smp_task.smp_req, req, req_size);
@@ -83,44 +91,50 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
 
 		task->task_done = smp_task_done;
 
-		task->timer.data = (unsigned long) task;
-		task->timer.function = smp_task_timedout;
-		task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
-		add_timer(&task->timer);
+		task->slow_task->timer.data = (unsigned long) task;
+		task->slow_task->timer.function = smp_task_timedout;
+		task->slow_task->timer.expires = jiffies + SMP_TIMEOUT*HZ;
+		add_timer(&task->slow_task->timer);
 
 		res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
 
 		if (res) {
-			del_timer(&task->timer);
+			del_timer(&task->slow_task->timer);
 			SAS_DPRINTK("executing SMP task failed:%d\n", res);
-			goto ex_err;
+			break;
 		}
 
-		wait_for_completion(&task->completion);
+		wait_for_completion(&task->slow_task->completion);
 		res = -ECOMM;
 		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
 			SAS_DPRINTK("smp task timed out or aborted\n");
 			i->dft->lldd_abort_task(task);
 			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
 				SAS_DPRINTK("SMP task aborted and not done\n");
-				goto ex_err;
+				break;
 			}
 		}
 		if (task->task_status.resp == SAS_TASK_COMPLETE &&
 		    task->task_status.stat == SAM_STAT_GOOD) {
 			res = 0;
 			break;
-		} if (task->task_status.resp == SAS_TASK_COMPLETE &&
-		      task->task_status.stat == SAS_DATA_UNDERRUN) {
+		}
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		    task->task_status.stat == SAS_DATA_UNDERRUN) {
 			/* no error, but return the number of bytes of
 			 * underrun */
 			res = task->task_status.residual;
 			break;
-		} if (task->task_status.resp == SAS_TASK_COMPLETE &&
-		      task->task_status.stat == SAS_DATA_OVERRUN) {
+		}
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		    task->task_status.stat == SAS_DATA_OVERRUN) {
 			res = -EMSGSIZE;
 			break;
-		} else {
+		}
+		if (task->task_status.resp == SAS_TASK_UNDELIVERED &&
+		    task->task_status.stat == SAS_DEVICE_UNKNOWN)
+			break;
+		else {
 			SAS_DPRINTK("%s: task to dev %016llx response: 0x%x "
 				    "status 0x%x\n", __func__,
 				    SAS_ADDR(dev->sas_addr),
@@ -130,11 +144,10 @@ static int smp_execute_task(struct domain_device *dev, void *req, int req_size,
 			task = NULL;
 		}
 	}
-ex_err:
+	mutex_unlock(&dev->ex_dev.cmd_mutex);
+
 	BUG_ON(retry == 3 && task != NULL);
-	if (task != NULL) {
-		sas_free_task(task);
-	}
+	sas_free_task(task);
 	return res;
 }
 
@@ -153,19 +166,49 @@ static inline void *alloc_smp_resp(int size)
 	return kzalloc(size, GFP_KERNEL);
 }
 
-/* ---------- Expander configuration ---------- */
+static char sas_route_char(struct domain_device *dev, struct ex_phy *phy)
+{
+	switch (phy->routing_attr) {
+	case TABLE_ROUTING:
+		if (dev->ex_dev.t2t_supp)
+			return 'U';
+		else
+			return 'T';
+	case DIRECT_ROUTING:
+		return 'D';
+	case SUBTRACTIVE_ROUTING:
+		return 'S';
+	default:
+		return '?';
+	}
+}
+
+static enum sas_dev_type to_dev_type(struct discover_resp *dr)
+{
+	/* This is detecting a failure to transmit initial dev to host
+	 * FIS as described in section J.5 of sas-2 r16
+	 */
+	if (dr->attached_dev_type == NO_DEVICE && dr->attached_sata_dev &&
+	    dr->linkrate >= SAS_LINK_RATE_1_5_GBPS)
+		return SATA_PENDING;
+	else
+		return dr->attached_dev_type;
+}
 
-static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
-			   void *disc_resp)
+static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
 {
+	enum sas_dev_type dev_type;
+	enum sas_linkrate linkrate;
+	u8 sas_addr[SAS_ADDR_SIZE];
+	struct smp_resp *resp = rsp;
+	struct discover_resp *dr = &resp->disc;
 	struct expander_device *ex = &dev->ex_dev;
 	struct ex_phy *phy = &ex->ex_phy[phy_id];
-	struct smp_resp *resp = disc_resp;
-	struct discover_resp *dr = &resp->disc;
 	struct sas_rphy *rphy = dev->rphy;
-	int rediscover = (phy->phy != NULL);
+	bool new_phy = !phy->phy;
+	char *type;
 
-	if (!rediscover) {
+	if (new_phy) {
 		phy->phy = sas_phy_alloc(&rphy->dev, phy_id);
 
 		/* FIXME: error_handling */
@@ -184,8 +227,13 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
 		break;
 	}
 
+	/* check if anything important changed to squelch debug */
+	dev_type = phy->attached_dev_type;
+	linkrate  = phy->linkrate;
+	memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
+
+	phy->attached_dev_type = to_dev_type(dr);
 	phy->phy_id = phy_id;
-	phy->attached_dev_type = dr->attached_dev_type;
 	phy->linkrate = dr->linkrate;
 	phy->attached_sata_host = dr->attached_sata_host;
 	phy->attached_sata_dev  = dr->attached_sata_dev;
@@ -200,9 +248,11 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
 	phy->last_da_index = -1;
 
 	phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr);
-	phy->phy->identify.device_type = phy->attached_dev_type;
+	phy->phy->identify.device_type = dr->attached_dev_type;
 	phy->phy->identify.initiator_port_protocols = phy->attached_iproto;
 	phy->phy->identify.target_port_protocols = phy->attached_tproto;
+	if (!phy->attached_tproto && dr->attached_sata_dev)
+		phy->phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
 	phy->phy->identify.phy_identifier = phy_id;
 	phy->phy->minimum_linkrate_hw = dr->hmin_linkrate;
 	phy->phy->maximum_linkrate_hw = dr->hmax_linkrate;
@@ -210,20 +260,76 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
 	phy->phy->maximum_linkrate = dr->pmax_linkrate;
 	phy->phy->negotiated_linkrate = phy->linkrate;
 
-	if (!rediscover)
+	if (new_phy)
 		if (sas_phy_add(phy->phy)) {
 			sas_phy_free(phy->phy);
 			return;
 		}
 
-	SAS_DPRINTK("ex %016llx phy%02d:%c attached: %016llx\n",
+	switch (phy->attached_dev_type) {
+	case SATA_PENDING:
+		type = "stp pending";
+		break;
+	case NO_DEVICE:
+		type = "no device";
+		break;
+	case SAS_END_DEV:
+		if (phy->attached_iproto) {
+			if (phy->attached_tproto)
+				type = "host+target";
+			else
+				type = "host";
+		} else {
+			if (dr->attached_sata_dev)
+				type = "stp";
+			else
+				type = "ssp";
+		}
+		break;
+	case EDGE_DEV:
+	case FANOUT_DEV:
+		type = "smp";
+		break;
+	default:
+		type = "unknown";
+	}
+
+	/* this routine is polled by libata error recovery so filter
+	 * unimportant messages
+	 */
+	if (new_phy || phy->attached_dev_type != dev_type ||
+	    phy->linkrate != linkrate ||
+	    SAS_ADDR(phy->attached_sas_addr) != SAS_ADDR(sas_addr))
+		/* pass */;
+	else
+		return;
+
+	SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n",
 		    SAS_ADDR(dev->sas_addr), phy->phy_id,
-		    phy->routing_attr == TABLE_ROUTING ? 'T' :
-		    phy->routing_attr == DIRECT_ROUTING ? 'D' :
-		    phy->routing_attr == SUBTRACTIVE_ROUTING ? 'S' : '?',
-		    SAS_ADDR(phy->attached_sas_addr));
+		    sas_route_char(dev, phy), phy->linkrate,
+		    SAS_ADDR(phy->attached_sas_addr), type);
+}
+
+/* check if we have an existing attached ata device on this expander phy */
+struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
+{
+	struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy_id];
+	struct domain_device *dev;
+	struct sas_rphy *rphy;
 
-	return;
+	if (!ex_phy->port)
+		return NULL;
+
+	rphy = ex_phy->port->rphy;
+	if (!rphy)
+		return NULL;
+
+	dev = sas_find_dev_by_rphy(rphy);
+
+	if (dev && dev_is_sata(dev))
+		return dev;
+
+	return NULL;
 }
 
 #define DISCOVER_REQ_SIZE  16
@@ -232,39 +338,25 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
 static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
 				      u8 *disc_resp, int single)
 {
-	int i, res;
+	struct discover_resp *dr;
+	int res;
 
 	disc_req[9] = single;
-	for (i = 1 ; i < 3; i++) {
-		struct discover_resp *dr;
 
-		res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
-				       disc_resp, DISCOVER_RESP_SIZE);
-		if (res)
-			return res;
-		/* This is detecting a failure to transmit initial
-		 * dev to host FIS as described in section G.5 of
-		 * sas-2 r 04b */
-		dr = &((struct smp_resp *)disc_resp)->disc;
-		if (memcmp(dev->sas_addr, dr->attached_sas_addr,
-			  SAS_ADDR_SIZE) == 0) {
-			sas_printk("Found loopback topology, just ignore it!\n");
-			return 0;
-		}
-		if (!(dr->attached_dev_type == 0 &&
-		      dr->attached_sata_dev))
-			break;
-		/* In order to generate the dev to host FIS, we
-		 * send a link reset to the expander port */
-		sas_smp_phy_control(dev, single, PHY_FUNC_LINK_RESET, NULL);
-		/* Wait for the reset to trigger the negotiation */
-		msleep(500);
+	res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
+			       disc_resp, DISCOVER_RESP_SIZE);
+	if (res)
+		return res;
+	dr = &((struct smp_resp *)disc_resp)->disc;
+	if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) {
+		sas_printk("Found loopback topology, just ignore it!\n");
+		return 0;
 	}
 	sas_set_ex_phy(dev, single, disc_resp);
 	return 0;
 }
 
-static int sas_ex_phy_discover(struct domain_device *dev, int single)
+int sas_ex_phy_discover(struct domain_device *dev, int single)
 {
 	struct expander_device *ex = &dev->ex_dev;
 	int  res = 0;
@@ -569,9 +661,8 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
 #define RPS_REQ_SIZE  16
 #define RPS_RESP_SIZE 60
 
-static int sas_get_report_phy_sata(struct domain_device *dev,
-					  int phy_id,
-					  struct smp_resp *rps_resp)
+int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
+			    struct smp_resp *rps_resp)
 {
 	int res;
 	u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
@@ -657,10 +748,11 @@ static struct domain_device *sas_ex_discover_end_dev(
 	if (phy->attached_sata_host || phy->attached_sata_ps)
 		return NULL;
 
-	child = kzalloc(sizeof(*child), GFP_KERNEL);
+	child = sas_alloc_device();
 	if (!child)
 		return NULL;
 
+	kref_get(&parent->kref);
 	child->parent = parent;
 	child->port   = parent->port;
 	child->iproto = phy->attached_iproto;
@@ -676,24 +768,13 @@ static struct domain_device *sas_ex_discover_end_dev(
 		}
 	}
 	sas_ex_get_linkrate(parent, child, phy);
+	sas_device_set_phy(child, phy->port);
 
 #ifdef CONFIG_SCSI_SAS_ATA
 	if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) {
-		child->dev_type = SATA_DEV;
-		if (phy->attached_tproto & SAS_PROTOCOL_STP)
-			child->tproto = phy->attached_tproto;
-		if (phy->attached_sata_dev)
-			child->tproto |= SATA_DEV;
-		res = sas_get_report_phy_sata(parent, phy_id,
-					      &child->sata_dev.rps_resp);
-		if (res) {
-			SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
-				    "0x%x\n", SAS_ADDR(parent->sas_addr),
-				    phy_id, res);
+		res = sas_get_ata_info(child, phy);
+		if (res)
 			goto out_free;
-		}
-		memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
-		       sizeof(struct dev_to_host_fis));
 
 		rphy = sas_end_device_alloc(phy->port);
 		if (unlikely(!rphy))
@@ -703,9 +784,7 @@ static struct domain_device *sas_ex_discover_end_dev(
 
 		child->rphy = rphy;
 
-		spin_lock_irq(&parent->port->dev_list_lock);
-		list_add_tail(&child->dev_list_node, &parent->port->dev_list);
-		spin_unlock_irq(&parent->port->dev_list_lock);
+		list_add_tail(&child->disco_list_node, &parent->port->disco_list);
 
 		res = sas_discover_sata(child);
 		if (res) {
@@ -729,9 +808,7 @@ static struct domain_device *sas_ex_discover_end_dev(
 		child->rphy = rphy;
 		sas_fill_in_rphy(child, rphy);
 
-		spin_lock_irq(&parent->port->dev_list_lock);
-		list_add_tail(&child->dev_list_node, &parent->port->dev_list);
-		spin_unlock_irq(&parent->port->dev_list_lock);
+		list_add_tail(&child->disco_list_node, &parent->port->disco_list);
 
 		res = sas_discover_end_dev(child);
 		if (res) {
@@ -755,6 +832,7 @@ static struct domain_device *sas_ex_discover_end_dev(
 	sas_rphy_free(child->rphy);
 	child->rphy = NULL;
 
+	list_del(&child->disco_list_node);
 	spin_lock_irq(&parent->port->dev_list_lock);
 	list_del(&child->dev_list_node);
 	spin_unlock_irq(&parent->port->dev_list_lock);
@@ -762,7 +840,7 @@ static struct domain_device *sas_ex_discover_end_dev(
 	sas_port_delete(phy->port);
  out_err:
 	phy->port = NULL;
-	kfree(child);
+	sas_put_device(child);
 	return NULL;
 }
 
@@ -809,7 +887,7 @@ static struct domain_device *sas_ex_discover_expander(
 			    phy->attached_phy_id);
 		return NULL;
 	}
-	child = kzalloc(sizeof(*child), GFP_KERNEL);
+	child = sas_alloc_device();
 	if (!child)
 		return NULL;
 
@@ -835,6 +913,7 @@ static struct domain_device *sas_ex_discover_expander(
 	child->rphy = rphy;
 	edev = rphy_to_expander_device(rphy);
 	child->dev_type = phy->attached_dev_type;
+	kref_get(&parent->kref);
 	child->parent = parent;
 	child->port = port;
 	child->iproto = phy->attached_iproto;
@@ -858,7 +937,7 @@ static struct domain_device *sas_ex_discover_expander(
 		spin_lock_irq(&parent->port->dev_list_lock);
 		list_del(&child->dev_list_node);
 		spin_unlock_irq(&parent->port->dev_list_lock);
-		kfree(child);
+		sas_put_device(child);
 		return NULL;
 	}
 	list_add_tail(&child->siblings, &parent->ex_dev.children);
@@ -908,7 +987,8 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
 
 	if (ex_phy->attached_dev_type != SAS_END_DEV &&
 	    ex_phy->attached_dev_type != FANOUT_DEV &&
-	    ex_phy->attached_dev_type != EDGE_DEV) {
+	    ex_phy->attached_dev_type != EDGE_DEV &&
+	    ex_phy->attached_dev_type != SATA_PENDING) {
 		SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx "
 			    "phy 0x%x\n", ex_phy->attached_dev_type,
 			    SAS_ADDR(dev->sas_addr),
@@ -934,6 +1014,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
 
 	switch (ex_phy->attached_dev_type) {
 	case SAS_END_DEV:
+	case SATA_PENDING:
 		child = sas_ex_discover_end_dev(dev, phy_id);
 		break;
 	case FANOUT_DEV:
@@ -1128,32 +1209,25 @@ static void sas_print_parent_topology_bug(struct domain_device *child,
 						 struct ex_phy *parent_phy,
 						 struct ex_phy *child_phy)
 {
-	static const char ra_char[] = {
-		[DIRECT_ROUTING] = 'D',
-		[SUBTRACTIVE_ROUTING] = 'S',
-		[TABLE_ROUTING] = 'T',
-	};
 	static const char *ex_type[] = {
 		[EDGE_DEV] = "edge",
 		[FANOUT_DEV] = "fanout",
 	};
 	struct domain_device *parent = child->parent;
 
-	sas_printk("%s ex %016llx (T2T supp:%d) phy 0x%x <--> %s ex %016llx "
-		   "(T2T supp:%d) phy 0x%x has %c:%c routing link!\n",
+	sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx "
+		   "phy 0x%x has %c:%c routing link!\n",
 
 		   ex_type[parent->dev_type],
 		   SAS_ADDR(parent->sas_addr),
-		   parent->ex_dev.t2t_supp,
 		   parent_phy->phy_id,
 
 		   ex_type[child->dev_type],
 		   SAS_ADDR(child->sas_addr),
-		   child->ex_dev.t2t_supp,
 		   child_phy->phy_id,
 
-		   ra_char[parent_phy->routing_attr],
-		   ra_char[child_phy->routing_attr]);
+		   sas_route_char(parent, parent_phy),
+		   sas_route_char(child, child_phy));
 }
 
 static int sas_check_eeds(struct domain_device *child,
@@ -1610,8 +1684,8 @@ static int sas_get_phy_change_count(struct domain_device *dev,
 	return res;
 }
 
-static int sas_get_phy_attached_sas_addr(struct domain_device *dev,
-					 int phy_id, u8 *attached_sas_addr)
+static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
+				    u8 *sas_addr, enum sas_dev_type *type)
 {
 	int res;
 	struct smp_resp *disc_resp;
@@ -1623,10 +1697,11 @@ static int sas_get_phy_attached_sas_addr(struct domain_device *dev,
 	dr = &disc_resp->disc;
 
 	res = sas_get_phy_discover(dev, phy_id, disc_resp);
-	if (!res) {
-		memcpy(attached_sas_addr,disc_resp->disc.attached_sas_addr,8);
-		if (dr->attached_dev_type == 0)
-			memset(attached_sas_addr, 0, 8);
+	if (res == 0) {
+		memcpy(sas_addr, disc_resp->disc.attached_sas_addr, 8);
+		*type = to_dev_type(dr);
+		if (*type == 0)
+			memset(sas_addr, 0, 8);
 	}
 	kfree(disc_resp);
 	return res;
@@ -1748,7 +1823,7 @@ static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_devi
 	struct domain_device *child, *n;
 
 	list_for_each_entry_safe(child, n, &ex->children, siblings) {
-		child->gone = 1;
+		set_bit(SAS_DEV_GONE, &child->state);
 		if (child->dev_type == EDGE_DEV ||
 		    child->dev_type == FANOUT_DEV)
 			sas_unregister_ex_tree(port, child);
@@ -1763,27 +1838,28 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent,
 {
 	struct expander_device *ex_dev = &parent->ex_dev;
 	struct ex_phy *phy = &ex_dev->ex_phy[phy_id];
-	struct domain_device *child, *n;
+	struct domain_device *child, *n, *found = NULL;
 	if (last) {
 		list_for_each_entry_safe(child, n,
 			&ex_dev->children, siblings) {
 			if (SAS_ADDR(child->sas_addr) ==
 			    SAS_ADDR(phy->attached_sas_addr)) {
-				child->gone = 1;
+				set_bit(SAS_DEV_GONE, &child->state);
 				if (child->dev_type == EDGE_DEV ||
 				    child->dev_type == FANOUT_DEV)
 					sas_unregister_ex_tree(parent->port, child);
 				else
 					sas_unregister_dev(parent->port, child);
+				found = child;
 				break;
 			}
 		}
-		parent->gone = 1;
 		sas_disable_routing(parent, phy->attached_sas_addr);
 	}
 	memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
 	if (phy->port) {
 		sas_port_delete_phy(phy->port, phy->phy);
+		sas_device_set_phy(found, phy->port);
 		if (phy->port->num_phys == 0)
 			sas_port_delete(phy->port);
 		phy->port = NULL;
@@ -1874,39 +1950,71 @@ out:
 	return res;
 }
 
+static bool dev_type_flutter(enum sas_dev_type new, enum sas_dev_type old)
+{
+	if (old == new)
+		return true;
+
+	/* treat device directed resets as flutter, if we went
+	 * SAS_END_DEV to SATA_PENDING the link needs recovery
+	 */
+	if ((old == SATA_PENDING && new == SAS_END_DEV) ||
+	    (old == SAS_END_DEV && new == SATA_PENDING))
+		return true;
+
+	return false;
+}
+
 static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
 {
 	struct expander_device *ex = &dev->ex_dev;
 	struct ex_phy *phy = &ex->ex_phy[phy_id];
-	u8 attached_sas_addr[8];
+	enum sas_dev_type type = NO_DEVICE;
+	u8 sas_addr[8];
 	int res;
 
-	res = sas_get_phy_attached_sas_addr(dev, phy_id, attached_sas_addr);
+	res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type);
 	switch (res) {
 	case SMP_RESP_NO_PHY:
 		phy->phy_state = PHY_NOT_PRESENT;
 		sas_unregister_devs_sas_addr(dev, phy_id, last);
-		goto out; break;
+		return res;
 	case SMP_RESP_PHY_VACANT:
 		phy->phy_state = PHY_VACANT;
 		sas_unregister_devs_sas_addr(dev, phy_id, last);
-		goto out; break;
+		return res;
 	case SMP_RESP_FUNC_ACC:
 		break;
 	}
 
-	if (SAS_ADDR(attached_sas_addr) == 0) {
+	if (SAS_ADDR(sas_addr) == 0) {
 		phy->phy_state = PHY_EMPTY;
 		sas_unregister_devs_sas_addr(dev, phy_id, last);
-	} else if (SAS_ADDR(attached_sas_addr) ==
-		   SAS_ADDR(phy->attached_sas_addr)) {
-		SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n",
-			    SAS_ADDR(dev->sas_addr), phy_id);
+		return res;
+	} else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
+		   dev_type_flutter(type, phy->attached_dev_type)) {
+		struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
+		char *action = "";
+
 		sas_ex_phy_discover(dev, phy_id);
-	} else
-		res = sas_discover_new(dev, phy_id);
-out:
-	return res;
+
+		if (ata_dev && phy->attached_dev_type == SATA_PENDING)
+			action = ", needs recovery";
+		SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter%s\n",
+			    SAS_ADDR(dev->sas_addr), phy_id, action);
+		return res;
+	}
+
+	/* delete the old link */
+	if (SAS_ADDR(phy->attached_sas_addr) &&
+	    SAS_ADDR(sas_addr) != SAS_ADDR(phy->attached_sas_addr)) {
+		SAS_DPRINTK("ex %016llx phy 0x%x replace %016llx\n",
+			    SAS_ADDR(dev->sas_addr), phy_id,
+			    SAS_ADDR(phy->attached_sas_addr));
+		sas_unregister_devs_sas_addr(dev, phy_id, last);
+	}
+
+	return sas_discover_new(dev, phy_id);
 }
 
 /**
diff --git a/drivers/scsi/libsas/sas_host_smp.c b/drivers/scsi/libsas/sas_host_smp.c
index bb8f492..d247925 100644
--- a/drivers/scsi/libsas/sas_host_smp.c
+++ b/drivers/scsi/libsas/sas_host_smp.c
@@ -187,11 +187,14 @@ static void sas_phy_control(struct sas_ha_struct *sas_ha, u8 phy_id,
 	struct sas_internal *i =
 		to_sas_internal(sas_ha->core.shost->transportt);
 	struct sas_phy_linkrates rates;
+	struct asd_sas_phy *asd_phy;
 
 	if (phy_id >= sas_ha->num_phys) {
 		resp_data[2] = SMP_RESP_NO_PHY;
 		return;
 	}
+
+	asd_phy = sas_ha->sas_phy[phy_id];
 	switch (phy_op) {
 	case PHY_FUNC_NOP:
 	case PHY_FUNC_LINK_RESET:
@@ -210,7 +213,13 @@ static void sas_phy_control(struct sas_ha_struct *sas_ha, u8 phy_id,
 	rates.minimum_linkrate = min;
 	rates.maximum_linkrate = max;
 
-	if (i->dft->lldd_control_phy(sas_ha->sas_phy[phy_id], phy_op, &rates))
+	/* filter reset requests through libata eh */
+	if (phy_op == PHY_FUNC_LINK_RESET && sas_try_ata_reset(asd_phy) == 0) {
+		resp_data[2] = SMP_RESP_FUNC_ACC;
+		return;
+	}
+
+	if (i->dft->lldd_control_phy(asd_phy, phy_op, &rates))
 		resp_data[2] = SMP_RESP_FUNC_FAILED;
 	else
 		resp_data[2] = SMP_RESP_FUNC_ACC;
@@ -246,9 +255,9 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
 	}
 
 	local_irq_disable();
-	buf = kmap_atomic(bio_page(req->bio), KM_USER0) + bio_offset(req->bio);
+	buf = kmap_atomic(bio_page(req->bio));
 	memcpy(req_data, buf, blk_rq_bytes(req));
-	kunmap_atomic(buf - bio_offset(req->bio), KM_USER0);
+	kunmap_atomic(buf - bio_offset(req->bio));
 	local_irq_enable();
 
 	if (req_data[0] != SMP_REQUEST)
@@ -361,10 +370,10 @@ int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
 	}
 
 	local_irq_disable();
-	buf = kmap_atomic(bio_page(rsp->bio), KM_USER0) + bio_offset(rsp->bio);
+	buf = kmap_atomic(bio_page(rsp->bio));
 	memcpy(buf, resp_data, blk_rq_bytes(rsp));
 	flush_kernel_dcache_page(bio_page(rsp->bio));
-	kunmap_atomic(buf - bio_offset(rsp->bio), KM_USER0);
+	kunmap_atomic(buf - bio_offset(rsp->bio));
 	local_irq_enable();
 
  out:
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index d81c3b1..57e7ac9 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/spinlock.h>
+#include <scsi/sas_ata.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_transport.h>
@@ -47,18 +48,37 @@ struct sas_task *sas_alloc_task(gfp_t flags)
 		INIT_LIST_HEAD(&task->list);
 		spin_lock_init(&task->task_state_lock);
 		task->task_state_flags = SAS_TASK_STATE_PENDING;
-		init_timer(&task->timer);
-		init_completion(&task->completion);
 	}
 
 	return task;
 }
 EXPORT_SYMBOL_GPL(sas_alloc_task);
 
+struct sas_task *sas_alloc_slow_task(gfp_t flags)
+{
+	struct sas_task *task = sas_alloc_task(flags);
+	struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags);
+
+	if (!task || !slow) {
+		if (task)
+			kmem_cache_free(sas_task_cache, task);
+		kfree(slow);
+		return NULL;
+	}
+
+	task->slow_task = slow;
+	init_timer(&slow->timer);
+	init_completion(&slow->completion);
+
+	return task;
+}
+EXPORT_SYMBOL_GPL(sas_alloc_slow_task);
+
 void sas_free_task(struct sas_task *task)
 {
 	if (task) {
 		BUG_ON(!list_empty(&task->list));
+		kfree(task->slow_task);
 		kmem_cache_free(sas_task_cache, task);
 	}
 }
@@ -97,14 +117,14 @@ void sas_hae_reset(struct work_struct *work)
 		container_of(work, struct sas_ha_event, work);
 	struct sas_ha_struct *ha = ev->ha;
 
-	sas_begin_event(HAE_RESET, &ha->event_lock,
-			&ha->pending);
+	clear_bit(HAE_RESET, &ha->pending);
 }
 
 int sas_register_ha(struct sas_ha_struct *sas_ha)
 {
 	int error = 0;
 
+	mutex_init(&sas_ha->disco_mutex);
 	spin_lock_init(&sas_ha->phy_port_lock);
 	sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr);
 
@@ -113,8 +133,10 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
 	else if (sas_ha->lldd_queue_size == -1)
 		sas_ha->lldd_queue_size = 128; /* Sanity */
 
-	sas_ha->state = SAS_HA_REGISTERED;
+	set_bit(SAS_HA_REGISTERED, &sas_ha->state);
 	spin_lock_init(&sas_ha->state_lock);
+	mutex_init(&sas_ha->drain_mutex);
+	INIT_LIST_HEAD(&sas_ha->defer_q);
 
 	error = sas_register_phys(sas_ha);
 	if (error) {
@@ -144,6 +166,7 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
 	}
 
 	INIT_LIST_HEAD(&sas_ha->eh_done_q);
+	INIT_LIST_HEAD(&sas_ha->eh_ata_q);
 
 	return 0;
 
@@ -156,17 +179,23 @@ Undo_phys:
 
 int sas_unregister_ha(struct sas_ha_struct *sas_ha)
 {
-	unsigned long flags;
-
-	/* Set the state to unregistered to avoid further
-	 * events to be queued */
-	spin_lock_irqsave(&sas_ha->state_lock, flags);
-	sas_ha->state = SAS_HA_UNREGISTERED;
-	spin_unlock_irqrestore(&sas_ha->state_lock, flags);
-	scsi_flush_work(sas_ha->core.shost);
+	/* Set the state to unregistered to avoid further unchained
+	 * events to be queued, and flush any in-progress drainers
+	 */
+	mutex_lock(&sas_ha->drain_mutex);
+	spin_lock_irq(&sas_ha->state_lock);
+	clear_bit(SAS_HA_REGISTERED, &sas_ha->state);
+	spin_unlock_irq(&sas_ha->state_lock);
+	__sas_drain_work(sas_ha);
+	mutex_unlock(&sas_ha->drain_mutex);
 
 	sas_unregister_ports(sas_ha);
 
+	/* flush unregistration work */
+	mutex_lock(&sas_ha->drain_mutex);
+	__sas_drain_work(sas_ha);
+	mutex_unlock(&sas_ha->drain_mutex);
+
 	if (sas_ha->lldd_max_execute_num > 1) {
 		sas_shutdown_queue(sas_ha);
 		sas_ha->lldd_max_execute_num = 1;
@@ -190,15 +219,75 @@ static int sas_get_linkerrors(struct sas_phy *phy)
 	return sas_smp_get_phy_events(phy);
 }
 
-int sas_phy_enable(struct sas_phy *phy, int enable)
+int sas_try_ata_reset(struct asd_sas_phy *asd_phy)
+{
+	struct domain_device *dev = NULL;
+
+	/* try to route user requested link resets through libata */
+	if (asd_phy->port)
+		dev = asd_phy->port->port_dev;
+
+	/* validate that dev has been probed */
+	if (dev)
+		dev = sas_find_dev_by_rphy(dev->rphy);
+
+	if (dev && dev_is_sata(dev)) {
+		sas_ata_schedule_reset(dev);
+		sas_ata_wait_eh(dev);
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
+/**
+ * transport_sas_phy_reset - reset a phy and permit libata to manage the link
+ *
+ * phy reset request via sysfs in host workqueue context so we know we
+ * can block on eh and safely traverse the domain_device topology
+ */
+static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
+{
+	enum phy_func reset_type;
+
+	if (hard_reset)
+		reset_type = PHY_FUNC_HARD_RESET;
+	else
+		reset_type = PHY_FUNC_LINK_RESET;
+
+	if (scsi_is_sas_phy_local(phy)) {
+		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
+		struct sas_internal *i =
+			to_sas_internal(sas_ha->core.shost->transportt);
+
+		if (!hard_reset && sas_try_ata_reset(asd_phy) == 0)
+			return 0;
+		return i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
+	} else {
+		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
+		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
+		struct domain_device *ata_dev = sas_ex_to_ata(ddev, phy->number);
+
+		if (ata_dev && !hard_reset) {
+			sas_ata_schedule_reset(ata_dev);
+			sas_ata_wait_eh(ata_dev);
+			return 0;
+		} else
+			return sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
+	}
+}
+
+static int sas_phy_enable(struct sas_phy *phy, int enable)
 {
 	int ret;
-	enum phy_func command;
+	enum phy_func cmd;
 
 	if (enable)
-		command = PHY_FUNC_LINK_RESET;
+		cmd = PHY_FUNC_LINK_RESET;
 	else
-		command = PHY_FUNC_DISABLE;
+		cmd = PHY_FUNC_DISABLE;
 
 	if (scsi_is_sas_phy_local(phy)) {
 		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
@@ -207,25 +296,35 @@ int sas_phy_enable(struct sas_phy *phy, int enable)
 		struct sas_internal *i =
 			to_sas_internal(sas_ha->core.shost->transportt);
 
-		if (!enable) {
-			sas_phy_disconnected(asd_phy);
-			sas_ha->notify_phy_event(asd_phy, PHYE_LOSS_OF_SIGNAL);
-		}
-		ret = i->dft->lldd_control_phy(asd_phy, command, NULL);
+		if (enable)
+			ret = transport_sas_phy_reset(phy, 0);
+		else
+			ret = i->dft->lldd_control_phy(asd_phy, cmd, NULL);
 	} else {
 		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
 		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
-		ret = sas_smp_phy_control(ddev, phy->number, command, NULL);
+
+		if (enable)
+			ret = transport_sas_phy_reset(phy, 0);
+		else
+			ret = sas_smp_phy_control(ddev, phy->number, cmd, NULL);
 	}
 	return ret;
 }
 
+static bool force_hard_reset;
+module_param(force_hard_reset, bool, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(force_hard_reset, "clear sata affiliations on every reset");
+
 int sas_phy_reset(struct sas_phy *phy, int hard_reset)
 {
 	int ret;
 	enum phy_func reset_type;
 
-	if (hard_reset)
+	if (!phy->enabled)
+		return -ENODEV;
+
+	if (hard_reset || force_hard_reset)
 		reset_type = PHY_FUNC_HARD_RESET;
 	else
 		reset_type = PHY_FUNC_LINK_RESET;
@@ -285,9 +384,101 @@ int sas_set_phy_speed(struct sas_phy *phy,
 	return ret;
 }
 
+static void sas_phy_release(struct sas_phy *phy)
+{
+	kfree(phy->hostdata);
+	phy->hostdata = NULL;
+}
+
+static void phy_reset_work(struct work_struct *work)
+{
+	struct sas_phy_data *d = container_of(work, typeof(*d), reset_work);
+
+	d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);
+}
+
+static void phy_enable_work(struct work_struct *work)
+{
+	struct sas_phy_data *d = container_of(work, typeof(*d), enable_work);
+
+	d->enable_result = sas_phy_enable(d->phy, d->enable);
+}
+
+static int sas_phy_setup(struct sas_phy *phy)
+{
+	struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL);
+
+	if (!d)
+		return -ENOMEM;
+
+	mutex_init(&d->event_lock);
+	INIT_WORK(&d->reset_work, phy_reset_work);
+	INIT_WORK(&d->enable_work, phy_enable_work);
+	d->phy = phy;
+	phy->hostdata = d;
+
+	return 0;
+}
+
+static int queue_phy_reset(struct sas_phy *phy, int hard_reset)
+{
+	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+	struct sas_phy_data *d = phy->hostdata;
+	int rc;
+
+	if (!d)
+		return -ENOMEM;
+
+	/* libsas workqueue coordinates ata-eh reset with discovery */
+	mutex_lock(&d->event_lock);
+	d->reset_result = 0;
+	d->hard_reset = hard_reset;
+
+	spin_lock_irq(&ha->state_lock);
+	sas_queue_work(ha, &d->reset_work);
+	spin_unlock_irq(&ha->state_lock);
+
+	rc = sas_drain_work(ha);
+	if (rc == 0)
+		rc = d->reset_result;
+	mutex_unlock(&d->event_lock);
+
+	return rc;
+}
+
+static int queue_phy_enable(struct sas_phy *phy, int enable)
+{
+	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+	struct sas_phy_data *d = phy->hostdata;
+	int rc;
+
+	if (!d)
+		return -ENOMEM;
+
+	/* libsas workqueue coordinates ata-eh reset with discovery */
+	mutex_lock(&d->event_lock);
+	d->enable_result = 0;
+	d->enable = enable;
+
+	spin_lock_irq(&ha->state_lock);
+	sas_queue_work(ha, &d->enable_work);
+	spin_unlock_irq(&ha->state_lock);
+
+	rc = sas_drain_work(ha);
+	if (rc == 0)
+		rc = d->enable_result;
+	mutex_unlock(&d->event_lock);
+
+	return rc;
+}
+
 static struct sas_function_template sft = {
-	.phy_enable = sas_phy_enable,
-	.phy_reset = sas_phy_reset,
+	.phy_enable = queue_phy_enable,
+	.phy_reset = queue_phy_reset,
+	.phy_setup = sas_phy_setup,
+	.phy_release = sas_phy_release,
 	.set_phy_speed = sas_set_phy_speed,
 	.get_linkerrors = sas_get_linkerrors,
 	.smp_handler = sas_smp_handler,
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 14e21b5..f05c638 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -30,6 +30,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_transport_sas.h>
 #include <scsi/libsas.h>
+#include <scsi/sas_ata.h>
 
 #define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__)
 
@@ -38,6 +39,18 @@
 #define TO_SAS_TASK(_scsi_cmd)  ((void *)(_scsi_cmd)->host_scribble)
 #define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
 
+struct sas_phy_data {
+	/* let reset be performed in sas_queue_work() context */
+	struct sas_phy *phy;
+	struct mutex event_lock;
+	int hard_reset;
+	int reset_result;
+	struct work_struct reset_work;
+	int enable;
+	int enable_result;
+	struct work_struct enable_work;
+};
+
 void sas_scsi_recover_host(struct Scsi_Host *shost);
 
 int sas_show_class(enum sas_class class, char *buf);
@@ -56,6 +69,9 @@ enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *);
 int  sas_init_queue(struct sas_ha_struct *sas_ha);
 int  sas_init_events(struct sas_ha_struct *sas_ha);
 void sas_shutdown_queue(struct sas_ha_struct *sas_ha);
+void sas_disable_revalidation(struct sas_ha_struct *ha);
+void sas_enable_revalidation(struct sas_ha_struct *ha);
+void __sas_drain_work(struct sas_ha_struct *ha);
 
 void sas_deform_port(struct asd_sas_phy *phy, int gone);
 
@@ -64,6 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work);
 void sas_porte_link_reset_err(struct work_struct *work);
 void sas_porte_timer_event(struct work_struct *work);
 void sas_porte_hard_reset(struct work_struct *work);
+void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work);
 
 int sas_notify_lldd_dev_found(struct domain_device *);
 void sas_notify_lldd_dev_gone(struct domain_device *);
@@ -72,10 +89,17 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id,
 			enum phy_func phy_func, struct sas_phy_linkrates *);
 int sas_smp_get_phy_events(struct sas_phy *phy);
 
+void sas_device_set_phy(struct domain_device *dev, struct sas_port *port);
 struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
-
+struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
+int sas_ex_phy_discover(struct domain_device *dev, int single);
+int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
+			    struct smp_resp *rps_resp);
+int sas_try_ata_reset(struct asd_sas_phy *phy);
 void sas_hae_reset(struct work_struct *work);
 
+void sas_free_device(struct kref *kref);
+
 #ifdef CONFIG_SCSI_SAS_HOST_SMP
 extern int sas_smp_host_handler(struct Scsi_Host *shost, struct request *req,
 				struct request *rsp);
@@ -90,36 +114,13 @@ static inline int sas_smp_host_handler(struct Scsi_Host *shost,
 }
 #endif
 
-static inline void sas_queue_event(int event, spinlock_t *lock,
-				   unsigned long *pending,
-				   struct work_struct *work,
-				   struct sas_ha_struct *sas_ha)
+static inline void sas_fail_probe(struct domain_device *dev, const char *func, int err)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(lock, flags);
-	if (test_bit(event, pending)) {
-		spin_unlock_irqrestore(lock, flags);
-		return;
-	}
-	__set_bit(event, pending);
-	spin_unlock_irqrestore(lock, flags);
-
-	spin_lock_irqsave(&sas_ha->state_lock, flags);
-	if (sas_ha->state != SAS_HA_UNREGISTERED) {
-		scsi_queue_work(sas_ha->core.shost, work);
-	}
-	spin_unlock_irqrestore(&sas_ha->state_lock, flags);
-}
-
-static inline void sas_begin_event(int event, spinlock_t *lock,
-				   unsigned long *pending)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(lock, flags);
-	__clear_bit(event, pending);
-	spin_unlock_irqrestore(lock, flags);
+	SAS_DPRINTK("%s: for %s device %16llx returned %d\n",
+		    func, dev->parent ? "exp-attached" :
+					    "direct-attached",
+		    SAS_ADDR(dev->sas_addr), err);
+	sas_unregister_dev(dev->port, dev);
 }
 
 static inline void sas_fill_in_rphy(struct domain_device *dev,
@@ -132,6 +133,7 @@ static inline void sas_fill_in_rphy(struct domain_device *dev,
 	case SATA_DEV:
 		/* FIXME: need sata device type */
 	case SAS_END_DEV:
+	case SATA_PENDING:
 		rphy->identify.device_type = SAS_END_DEVICE;
 		break;
 	case EDGE_DEV:
@@ -146,6 +148,22 @@ static inline void sas_fill_in_rphy(struct domain_device *dev,
 	}
 }
 
+static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_device *dev)
+{
+	struct sas_phy *phy = p->phy;
+
+	if (dev) {
+		if (dev_is_sata(dev))
+			phy->identify.device_type = SAS_END_DEVICE;
+		else
+			phy->identify.device_type = dev->dev_type;
+		phy->identify.target_port_protocols = dev->tproto;
+	} else {
+		phy->identify.device_type = SAS_PHY_UNUSED;
+		phy->identify.target_port_protocols = 0;
+	}
+}
+
 static inline void sas_add_parent_port(struct domain_device *dev, int phy_id)
 {
 	struct expander_device *ex = &dev->ex_dev;
@@ -161,4 +179,23 @@ static inline void sas_add_parent_port(struct domain_device *dev, int phy_id)
 	sas_port_add_phy(ex->parent_port, ex_phy->phy);
 }
 
+static inline struct domain_device *sas_alloc_device(void)
+{
+	struct domain_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+
+	if (dev) {
+		INIT_LIST_HEAD(&dev->siblings);
+		INIT_LIST_HEAD(&dev->dev_list_node);
+		INIT_LIST_HEAD(&dev->disco_list_node);
+		kref_init(&dev->kref);
+		spin_lock_init(&dev->done_lock);
+	}
+	return dev;
+}
+
+static inline void sas_put_device(struct domain_device *dev)
+{
+	kref_put(&dev->kref, sas_free_device);
+}
+
 #endif /* _SAS_INTERNAL_H_ */
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
index e0f5018..dcfd4a9 100644
--- a/drivers/scsi/libsas/sas_phy.c
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -36,8 +36,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work)
 		container_of(work, struct asd_sas_event, work);
 	struct asd_sas_phy *phy = ev->phy;
 
-	sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
-			&phy->phy_events_pending);
+	clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending);
 	phy->error = 0;
 	sas_deform_port(phy, 1);
 }
@@ -48,8 +47,7 @@ static void sas_phye_oob_done(struct work_struct *work)
 		container_of(work, struct asd_sas_event, work);
 	struct asd_sas_phy *phy = ev->phy;
 
-	sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock,
-			&phy->phy_events_pending);
+	clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending);
 	phy->error = 0;
 }
 
@@ -63,8 +61,7 @@ static void sas_phye_oob_error(struct work_struct *work)
 	struct sas_internal *i =
 		to_sas_internal(sas_ha->core.shost->transportt);
 
-	sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock,
-			&phy->phy_events_pending);
+	clear_bit(PHYE_OOB_ERROR, &phy->phy_events_pending);
 
 	sas_deform_port(phy, 1);
 
@@ -95,8 +92,7 @@ static void sas_phye_spinup_hold(struct work_struct *work)
 	struct sas_internal *i =
 		to_sas_internal(sas_ha->core.shost->transportt);
 
-	sas_begin_event(PHYE_SPINUP_HOLD, &phy->ha->event_lock,
-			&phy->phy_events_pending);
+	clear_bit(PHYE_SPINUP_HOLD, &phy->phy_events_pending);
 
 	phy->error = 0;
 	i->dft->lldd_control_phy(phy, PHY_FUNC_RELEASE_SPINUP_HOLD, NULL);
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 42fd1f2..eb19c01 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -104,13 +104,11 @@ static void sas_form_port(struct asd_sas_phy *phy)
 
 	/* add the phy to the port */
 	list_add_tail(&phy->port_phy_el, &port->phy_list);
+	sas_phy_set_target(phy, port->port_dev);
 	phy->port = port;
 	port->num_phys++;
 	port->phy_mask |= (1U << phy->id);
 
-	if (!port->phy)
-		port->phy = phy->phy;
-
 	if (*(u64 *)port->attached_sas_addr == 0) {
 		port->class = phy->class;
 		memcpy(port->attached_sas_addr, phy->attached_sas_addr,
@@ -125,7 +123,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
 	spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
 
 	if (!port->port) {
-		port->port = sas_port_alloc(phy->phy->dev.parent, port->id);
+		port->port = sas_port_alloc(phy->phy->dev.parent, phy->id);
 		BUG_ON(!port->port);
 		sas_port_add(port->port);
 	}
@@ -170,13 +168,13 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
 		dev->pathways--;
 
 	if (port->num_phys == 1) {
-		if (dev && gone)
-			dev->gone = 1;
-		sas_unregister_domain_devices(port);
+		sas_unregister_domain_devices(port, gone);
 		sas_port_delete(port->port);
 		port->port = NULL;
-	} else
+	} else {
 		sas_port_delete_phy(port->port, phy->phy);
+		sas_device_set_phy(dev, port->port);
+	}
 
 	if (si->dft->lldd_port_deformed)
 		si->dft->lldd_port_deformed(phy);
@@ -185,6 +183,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
 	spin_lock(&port->phy_list_lock);
 
 	list_del_init(&phy->port_phy_el);
+	sas_phy_set_target(phy, NULL);
 	phy->port = NULL;
 	port->num_phys--;
 	port->phy_mask &= ~(1U << phy->id);
@@ -213,8 +212,7 @@ void sas_porte_bytes_dmaed(struct work_struct *work)
 		container_of(work, struct asd_sas_event, work);
 	struct asd_sas_phy *phy = ev->phy;
 
-	sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock,
-			&phy->port_events_pending);
+	clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending);
 
 	sas_form_port(phy);
 }
@@ -227,8 +225,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work)
 	unsigned long flags;
 	u32 prim;
 
-	sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock,
-			&phy->port_events_pending);
+	clear_bit(PORTE_BROADCAST_RCVD, &phy->port_events_pending);
 
 	spin_lock_irqsave(&phy->sas_prim_lock, flags);
 	prim = phy->sas_prim;
@@ -244,8 +241,7 @@ void sas_porte_link_reset_err(struct work_struct *work)
 		container_of(work, struct asd_sas_event, work);
 	struct asd_sas_phy *phy = ev->phy;
 
-	sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
-			&phy->port_events_pending);
+	clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending);
 
 	sas_deform_port(phy, 1);
 }
@@ -256,8 +252,7 @@ void sas_porte_timer_event(struct work_struct *work)
 		container_of(work, struct asd_sas_event, work);
 	struct asd_sas_phy *phy = ev->phy;
 
-	sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
-			&phy->port_events_pending);
+	clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending);
 
 	sas_deform_port(phy, 1);
 }
@@ -268,8 +263,7 @@ void sas_porte_hard_reset(struct work_struct *work)
 		container_of(work, struct asd_sas_event, work);
 	struct asd_sas_phy *phy = ev->phy;
 
-	sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
-			&phy->port_events_pending);
+	clear_bit(PORTE_HARD_RESET, &phy->port_events_pending);
 
 	sas_deform_port(phy, 1);
 }
@@ -282,6 +276,8 @@ static void sas_init_port(struct asd_sas_port *port,
 	memset(port, 0, sizeof(*port));
 	port->id = i;
 	INIT_LIST_HEAD(&port->dev_list);
+	INIT_LIST_HEAD(&port->disco_list);
+	INIT_LIST_HEAD(&port->destroy_list);
 	spin_lock_init(&port->phy_list_lock);
 	INIT_LIST_HEAD(&port->phy_list);
 	port->ha = sas_ha;
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index b6e233d..9716f2e 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -49,27 +49,12 @@
 #include <linux/scatterlist.h>
 #include <linux/libata.h>
 
-/* ---------- SCSI Host glue ---------- */
-
-static void sas_scsi_task_done(struct sas_task *task)
+/* record final status and free the task */
+static void sas_end_task(struct scsi_cmnd *sc, struct sas_task *task)
 {
 	struct task_status_struct *ts = &task->task_status;
-	struct scsi_cmnd *sc = task->uldd_task;
 	int hs = 0, stat = 0;
 
-	if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
-		/* Aborted tasks will be completed by the error handler */
-		SAS_DPRINTK("task done but aborted\n");
-		return;
-	}
-
-	if (unlikely(!sc)) {
-		SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
-		list_del_init(&task->list);
-		sas_free_task(task);
-		return;
-	}
-
 	if (ts->resp == SAS_TASK_UNDELIVERED) {
 		/* transport error */
 		hs = DID_NO_CONNECT;
@@ -124,10 +109,41 @@ static void sas_scsi_task_done(struct sas_task *task)
 			break;
 		}
 	}
-	ASSIGN_SAS_TASK(sc, NULL);
+
 	sc->result = (hs << 16) | stat;
+	ASSIGN_SAS_TASK(sc, NULL);
 	list_del_init(&task->list);
 	sas_free_task(task);
+}
+
+static void sas_scsi_task_done(struct sas_task *task)
+{
+	struct scsi_cmnd *sc = task->uldd_task;
+	struct domain_device *dev = task->dev;
+	struct sas_ha_struct *ha = dev->port->ha;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->done_lock, flags);
+	if (test_bit(SAS_HA_FROZEN, &ha->state))
+		task = NULL;
+	else
+		ASSIGN_SAS_TASK(sc, NULL);
+	spin_unlock_irqrestore(&dev->done_lock, flags);
+
+	if (unlikely(!task)) {
+		/* task will be completed by the error handler */
+		SAS_DPRINTK("task done but aborted\n");
+		return;
+	}
+
+	if (unlikely(!sc)) {
+		SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
+		list_del_init(&task->list);
+		sas_free_task(task);
+		return;
+	}
+
+	sas_end_task(sc, task);
 	sc->scsi_done(sc);
 }
 
@@ -192,17 +208,15 @@ int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 	int res = 0;
 
 	/* If the device fell off, no sense in issuing commands */
-	if (dev->gone) {
+	if (test_bit(SAS_DEV_GONE, &dev->state)) {
 		cmd->result = DID_BAD_TARGET << 16;
 		goto out_done;
 	}
 
 	if (dev_is_sata(dev)) {
-		unsigned long flags;
-
-		spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
+		spin_lock_irq(dev->sata_dev.ap->lock);
 		res = ata_sas_queuecmd(cmd, dev->sata_dev.ap);
-		spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
+		spin_unlock_irq(dev->sata_dev.ap->lock);
 		return res;
 	}
 
@@ -235,24 +249,38 @@ out_done:
 
 static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
 {
-	struct sas_task *task = TO_SAS_TASK(cmd);
 	struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
+	struct sas_task *task = TO_SAS_TASK(cmd);
+
+	/* At this point, we only get called following an actual abort
+	 * of the task, so we should be guaranteed not to be racing with
+	 * any completions from the LLD.  Task is freed after this.
+	 */
+	sas_end_task(cmd, task);
 
-	/* remove the aborted task flag to allow the task to be
-	 * completed now. At this point, we only get called following
-	 * an actual abort of the task, so we should be guaranteed not
-	 * to be racing with any completions from the LLD (hence we
-	 * don't need the task state lock to clear the flag) */
-	task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
-	/* Now call task_done.  However, task will be free'd after
-	 * this */
-	task->task_done(task);
 	/* now finish the command and move it on to the error
 	 * handler done list, this also takes it off the
-	 * error handler pending list */
+	 * error handler pending list.
+	 */
 	scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
 }
 
+static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
+{
+	struct domain_device *dev = cmd_to_domain_dev(cmd);
+	struct sas_ha_struct *ha = dev->port->ha;
+	struct sas_task *task = TO_SAS_TASK(cmd);
+
+	if (!dev_is_sata(dev)) {
+		sas_eh_finish_cmd(cmd);
+		return;
+	}
+
+	/* report the timeout to libata */
+	sas_end_task(cmd, task);
+	list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
+}
+
 static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
 {
 	struct scsi_cmnd *cmd, *n;
@@ -260,7 +288,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd
 	list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
 		if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
 		    cmd->device->lun == my_cmd->device->lun)
-			sas_eh_finish_cmd(cmd);
+			sas_eh_defer_cmd(cmd);
 	}
 }
 
@@ -295,6 +323,7 @@ enum task_disposition {
 	TASK_IS_DONE,
 	TASK_IS_ABORTED,
 	TASK_IS_AT_LU,
+	TASK_IS_NOT_AT_HA,
 	TASK_IS_NOT_AT_LU,
 	TASK_ABORT_FAILED,
 };
@@ -311,19 +340,18 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task)
 		struct scsi_core *core = &ha->core;
 		struct sas_task *t, *n;
 
+		mutex_lock(&core->task_queue_flush);
 		spin_lock_irqsave(&core->task_queue_lock, flags);
-		list_for_each_entry_safe(t, n, &core->task_queue, list) {
+		list_for_each_entry_safe(t, n, &core->task_queue, list)
 			if (task == t) {
 				list_del_init(&t->list);
-				spin_unlock_irqrestore(&core->task_queue_lock,
-						       flags);
-				SAS_DPRINTK("%s: task 0x%p aborted from "
-					    "task_queue\n",
-					    __func__, task);
-				return TASK_IS_ABORTED;
+				break;
 			}
-		}
 		spin_unlock_irqrestore(&core->task_queue_lock, flags);
+		mutex_unlock(&core->task_queue_flush);
+
+		if (task == t)
+			return TASK_IS_NOT_AT_HA;
 	}
 
 	for (i = 0; i < 5; i++) {
@@ -411,39 +439,59 @@ static int sas_recover_I_T(struct domain_device *dev)
 	return res;
 }
 
-/* Find the sas_phy that's attached to this device */
-struct sas_phy *sas_find_local_phy(struct domain_device *dev)
+/* take a reference on the last known good phy for this device */
+struct sas_phy *sas_get_local_phy(struct domain_device *dev)
 {
-	struct domain_device *pdev = dev->parent;
-	struct ex_phy *exphy = NULL;
-	int i;
+	struct sas_ha_struct *ha = dev->port->ha;
+	struct sas_phy *phy;
+	unsigned long flags;
 
-	/* Directly attached device */
-	if (!pdev)
-		return dev->port->phy;
+	/* a published domain device always has a valid phy, it may be
+	 * stale, but it is never NULL
+	 */
+	BUG_ON(!dev->phy);
 
-	/* Otherwise look in the expander */
-	for (i = 0; i < pdev->ex_dev.num_phys; i++)
-		if (!memcmp(dev->sas_addr,
-			    pdev->ex_dev.ex_phy[i].attached_sas_addr,
-			    SAS_ADDR_SIZE)) {
-			exphy = &pdev->ex_dev.ex_phy[i];
-			break;
-		}
+	spin_lock_irqsave(&ha->phy_port_lock, flags);
+	phy = dev->phy;
+	get_device(&phy->dev);
+	spin_unlock_irqrestore(&ha->phy_port_lock, flags);
+
+	return phy;
+}
+EXPORT_SYMBOL_GPL(sas_get_local_phy);
+
+int sas_eh_abort_handler(struct scsi_cmnd *cmd)
+{
+	int res;
+	struct sas_task *task = TO_SAS_TASK(cmd);
+	struct Scsi_Host *host = cmd->device->host;
+	struct sas_internal *i = to_sas_internal(host->transportt);
+
+	if (current != host->ehandler)
+		return FAILED;
+
+	if (!i->dft->lldd_abort_task)
+		return FAILED;
+
+	res = i->dft->lldd_abort_task(task);
+	if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
+		return SUCCESS;
 
-	BUG_ON(!exphy);
-	return exphy->phy;
+	return FAILED;
 }
-EXPORT_SYMBOL_GPL(sas_find_local_phy);
+EXPORT_SYMBOL_GPL(sas_eh_abort_handler);
 
 /* Attempt to send a LUN reset message to a device */
 int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
 {
-	struct domain_device *dev = cmd_to_domain_dev(cmd);
-	struct sas_internal *i =
-		to_sas_internal(dev->port->ha->core.shost->transportt);
-	struct scsi_lun lun;
 	int res;
+	struct scsi_lun lun;
+	struct Scsi_Host *host = cmd->device->host;
+	struct domain_device *dev = cmd_to_domain_dev(cmd);
+	struct sas_internal *i = to_sas_internal(host->transportt);
+
+	if (current != host->ehandler)
+		return FAILED;
 
 	int_to_scsilun(cmd->device->lun, &lun);
 
@@ -457,19 +505,22 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
 	return FAILED;
 }
 
-/* Attempt to send a phy (bus) reset */
 int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 {
-	struct domain_device *dev = cmd_to_domain_dev(cmd);
-	struct sas_phy *phy = sas_find_local_phy(dev);
 	int res;
+	struct Scsi_Host *host = cmd->device->host;
+	struct domain_device *dev = cmd_to_domain_dev(cmd);
+	struct sas_internal *i = to_sas_internal(host->transportt);
 
-	res = sas_phy_reset(phy, 1);
-	if (res)
-		SAS_DPRINTK("Bus reset of %s failed 0x%x\n",
-			    kobject_name(&phy->dev.kobj),
-			    res);
-	if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
+	if (current != host->ehandler)
+		return FAILED;
+
+	if (!i->dft->lldd_I_T_nexus_reset)
+		return FAILED;
+
+	res = i->dft->lldd_I_T_nexus_reset(dev);
+	if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE ||
+	    res == -ENODEV)
 		return SUCCESS;
 
 	return FAILED;
@@ -495,9 +546,7 @@ try_bus_reset:
 	return FAILED;
 }
 
-static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
-				    struct list_head *work_q,
-				    struct list_head *done_q)
+static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head *work_q)
 {
 	struct scsi_cmnd *cmd, *n;
 	enum task_disposition res = TASK_IS_DONE;
@@ -505,13 +554,28 @@ static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
 	struct sas_internal *i = to_sas_internal(shost->transportt);
 	unsigned long flags;
 	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+	LIST_HEAD(done);
 
-Again:
+	/* clean out any commands that won the completion vs eh race */
 	list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
-		struct sas_task *task = TO_SAS_TASK(cmd);
+		struct domain_device *dev = cmd_to_domain_dev(cmd);
+		struct sas_task *task;
+
+		spin_lock_irqsave(&dev->done_lock, flags);
+		/* by this point the lldd has either observed
+		 * SAS_HA_FROZEN and is leaving the task alone, or has
+		 * won the race with eh and decided to complete it
+		 */
+		task = TO_SAS_TASK(cmd);
+		spin_unlock_irqrestore(&dev->done_lock, flags);
 
 		if (!task)
-			continue;
+			list_move_tail(&cmd->eh_entry, &done);
+	}
+
+ Again:
+	list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
+		struct sas_task *task = TO_SAS_TASK(cmd);
 
 		list_del_init(&cmd->eh_entry);
 
@@ -531,15 +595,23 @@ Again:
 		cmd->eh_eflags = 0;
 
 		switch (res) {
+		case TASK_IS_NOT_AT_HA:
+			SAS_DPRINTK("%s: task 0x%p is not at ha: %s\n",
+				    __func__, task,
+				    cmd->retries ? "retry" : "aborted");
+			if (cmd->retries)
+				cmd->retries--;
+			sas_eh_finish_cmd(cmd);
+			continue;
 		case TASK_IS_DONE:
 			SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
 				    task);
-			sas_eh_finish_cmd(cmd);
+			sas_eh_defer_cmd(cmd);
 			continue;
 		case TASK_IS_ABORTED:
 			SAS_DPRINTK("%s: task 0x%p is aborted\n",
 				    __func__, task);
-			sas_eh_finish_cmd(cmd);
+			sas_eh_defer_cmd(cmd);
 			continue;
 		case TASK_IS_AT_LU:
 			SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
@@ -550,7 +622,7 @@ Again:
 					    "recovered\n",
 					    SAS_ADDR(task->dev),
 					    cmd->device->lun);
-				sas_eh_finish_cmd(cmd);
+				sas_eh_defer_cmd(cmd);
 				sas_scsi_clear_queue_lu(work_q, cmd);
 				goto Again;
 			}
@@ -560,7 +632,8 @@ Again:
 			SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n",
 				    task);
 			tmf_resp = sas_recover_I_T(task->dev);
-			if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
+			if (tmf_resp == TMF_RESP_FUNC_COMPLETE ||
+			    tmf_resp == -ENODEV) {
 				struct domain_device *dev = task->dev;
 				SAS_DPRINTK("I_T %016llx recovered\n",
 					    SAS_ADDR(task->dev->sas_addr));
@@ -607,13 +680,16 @@ Again:
 			goto clear_q;
 		}
 	}
-	return list_empty(work_q);
-clear_q:
+ out:
+	list_splice_tail(&done, work_q);
+	list_splice_tail_init(&ha->eh_ata_q, work_q);
+	return;
+
+ clear_q:
 	SAS_DPRINTK("--- Exit %s -- clear_q\n", __func__);
 	list_for_each_entry_safe(cmd, n, work_q, eh_entry)
 		sas_eh_finish_cmd(cmd);
-
-	return list_empty(work_q);
+	goto out;
 }
 
 void sas_scsi_recover_host(struct Scsi_Host *shost)
@@ -627,12 +703,17 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
 	shost->host_eh_scheduled = 0;
 	spin_unlock_irqrestore(shost->host_lock, flags);
 
-	SAS_DPRINTK("Enter %s\n", __func__);
+	SAS_DPRINTK("Enter %s busy: %d failed: %d\n",
+		    __func__, shost->host_busy, shost->host_failed);
 	/*
 	 * Deal with commands that still have SAS tasks (i.e. they didn't
-	 * complete via the normal sas_task completion mechanism)
+	 * complete via the normal sas_task completion mechanism),
+	 * SAS_HA_FROZEN gives eh dominion over all sas_task completion.
 	 */
-	if (sas_eh_handle_sas_errors(shost, &eh_work_q, &ha->eh_done_q))
+	set_bit(SAS_HA_FROZEN, &ha->state);
+	sas_eh_handle_sas_errors(shost, &eh_work_q);
+	clear_bit(SAS_HA_FROZEN, &ha->state);
+	if (list_empty(&eh_work_q))
 		goto out;
 
 	/*
@@ -641,59 +722,26 @@ void sas_scsi_recover_host(struct Scsi_Host *shost)
 	 * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any
 	 * command we see here has no sas_task and is thus unknown to the HA.
 	 */
-	if (!sas_ata_eh(shost, &eh_work_q, &ha->eh_done_q))
-		if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q))
-			scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q);
+	sas_ata_eh(shost, &eh_work_q, &ha->eh_done_q);
+	if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q))
+		scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q);
 
 out:
+	if (ha->lldd_max_execute_num > 1)
+		wake_up_process(ha->core.queue_thread);
+
 	/* now link into libata eh --- if we have any ata devices */
 	sas_ata_strategy_handler(shost);
 
 	scsi_eh_flush_done_q(&ha->eh_done_q);
 
-	SAS_DPRINTK("--- Exit %s\n", __func__);
-	return;
+	SAS_DPRINTK("--- Exit %s: busy: %d failed: %d\n",
+		    __func__, shost->host_busy, shost->host_failed);
 }
 
 enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
 {
-	struct sas_task *task = TO_SAS_TASK(cmd);
-	unsigned long flags;
-	enum blk_eh_timer_return rtn;
-
-	if (sas_ata_timed_out(cmd, task, &rtn))
-		return rtn;
-
-	if (!task) {
-		cmd->request->timeout /= 2;
-		SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n",
-			    cmd, task, (cmd->request->timeout ?
-			    "BLK_EH_RESET_TIMER" : "BLK_EH_NOT_HANDLED"));
-		if (!cmd->request->timeout)
-			return BLK_EH_NOT_HANDLED;
-		return BLK_EH_RESET_TIMER;
-	}
-
-	spin_lock_irqsave(&task->task_state_lock, flags);
-	BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED);
-	if (task->task_state_flags & SAS_TASK_STATE_DONE) {
-		spin_unlock_irqrestore(&task->task_state_lock, flags);
-		SAS_DPRINTK("command 0x%p, task 0x%p, timed out: "
-			    "BLK_EH_HANDLED\n", cmd, task);
-		return BLK_EH_HANDLED;
-	}
-	if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) {
-		spin_unlock_irqrestore(&task->task_state_lock, flags);
-		SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: "
-			    "BLK_EH_RESET_TIMER\n",
-			    cmd, task);
-		return BLK_EH_RESET_TIMER;
-	}
-	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-	spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-	SAS_DPRINTK("command 0x%p, task 0x%p, timed out: BLK_EH_NOT_HANDLED\n",
-		    cmd, task);
+	scmd_printk(KERN_DEBUG, cmd, "command %p timed out\n", cmd);
 
 	return BLK_EH_NOT_HANDLED;
 }
@@ -737,27 +785,15 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
 	return found_dev;
 }
 
-static inline struct domain_device *sas_find_target(struct scsi_target *starget)
-{
-	struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
-
-	return sas_find_dev_by_rphy(rphy);
-}
-
 int sas_target_alloc(struct scsi_target *starget)
 {
-	struct domain_device *found_dev = sas_find_target(starget);
-	int res;
+	struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
+	struct domain_device *found_dev = sas_find_dev_by_rphy(rphy);
 
 	if (!found_dev)
 		return -ENODEV;
 
-	if (dev_is_sata(found_dev)) {
-		res = sas_ata_init_host_and_port(found_dev, starget);
-		if (res)
-			return res;
-	}
-
+	kref_get(&found_dev->kref);
 	starget->hostdata = found_dev;
 	return 0;
 }
@@ -797,14 +833,6 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
 	return 0;
 }
 
-void sas_slave_destroy(struct scsi_device *scsi_dev)
-{
-	struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
-
-	if (dev_is_sata(dev))
-		sas_to_ata_dev(dev)->class = ATA_DEV_NONE;
-}
-
 int sas_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
 {
 	struct domain_device *dev = sdev_to_domain_dev(sdev);
@@ -871,9 +899,11 @@ static void sas_queue(struct sas_ha_struct *sas_ha)
 	int res;
 	struct sas_internal *i = to_sas_internal(core->shost->transportt);
 
+	mutex_lock(&core->task_queue_flush);
 	spin_lock_irqsave(&core->task_queue_lock, flags);
 	while (!kthread_should_stop() &&
-	       !list_empty(&core->task_queue)) {
+	       !list_empty(&core->task_queue) &&
+	       !test_bit(SAS_HA_FROZEN, &sas_ha->state)) {
 
 		can_queue = sas_ha->lldd_queue_size - core->task_queue_size;
 		if (can_queue >= 0) {
@@ -909,6 +939,7 @@ static void sas_queue(struct sas_ha_struct *sas_ha)
 		}
 	}
 	spin_unlock_irqrestore(&core->task_queue_lock, flags);
+	mutex_unlock(&core->task_queue_flush);
 }
 
 /**
@@ -935,6 +966,7 @@ int sas_init_queue(struct sas_ha_struct *sas_ha)
 	struct scsi_core *core = &sas_ha->core;
 
 	spin_lock_init(&core->task_queue_lock);
+	mutex_init(&core->task_queue_flush);
 	core->task_queue_size = 0;
 	INIT_LIST_HEAD(&core->task_queue);
 
@@ -972,49 +1004,6 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
 }
 
 /*
- * Call the LLDD task abort routine directly.  This function is intended for
- * use by upper layers that need to tell the LLDD to abort a task.
- */
-int __sas_task_abort(struct sas_task *task)
-{
-	struct sas_internal *si =
-		to_sas_internal(task->dev->port->ha->core.shost->transportt);
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&task->task_state_lock, flags);
-	if (task->task_state_flags & SAS_TASK_STATE_ABORTED ||
-	    task->task_state_flags & SAS_TASK_STATE_DONE) {
-		spin_unlock_irqrestore(&task->task_state_lock, flags);
-		SAS_DPRINTK("%s: Task %p already finished.\n", __func__,
-			    task);
-		return 0;
-	}
-	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-	spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-	if (!si->dft->lldd_abort_task)
-		return -ENODEV;
-
-	res = si->dft->lldd_abort_task(task);
-
-	spin_lock_irqsave(&task->task_state_lock, flags);
-	if ((task->task_state_flags & SAS_TASK_STATE_DONE) ||
-	    (res == TMF_RESP_FUNC_COMPLETE))
-	{
-		spin_unlock_irqrestore(&task->task_state_lock, flags);
-		task->task_done(task);
-		return 0;
-	}
-
-	if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
-		task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
-	spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-	return -EAGAIN;
-}
-
-/*
  * Tell an upper layer that it needs to initiate an abort for a given task.
  * This should only ever be called by an LLDD.
  */
@@ -1024,9 +1013,13 @@ void sas_task_abort(struct sas_task *task)
 
 	/* Escape for libsas internal commands */
 	if (!sc) {
-		if (!del_timer(&task->timer))
+		struct sas_task_slow *slow = task->slow_task;
+
+		if (!slow)
+			return;
+		if (!del_timer(&slow->timer))
 			return;
-		task->timer.function(task->timer.data);
+		slow->timer.function(slow->timer.data);
 		return;
 	}
 
@@ -1043,27 +1036,15 @@ void sas_task_abort(struct sas_task *task)
 	}
 }
 
-int sas_slave_alloc(struct scsi_device *scsi_dev)
-{
-	struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
-
-	if (dev_is_sata(dev))
-		return ata_sas_port_init(dev->sata_dev.ap);
-
-	return 0;
-}
-
 void sas_target_destroy(struct scsi_target *starget)
 {
-	struct domain_device *found_dev = sas_find_target(starget);
+	struct domain_device *found_dev = starget->hostdata;
 
 	if (!found_dev)
 		return;
 
-	if (dev_is_sata(found_dev))
-		ata_sas_port_destroy(found_dev->sata_dev.ap);
-
-	return;
+	starget->hostdata = NULL;
+	sas_put_device(found_dev);
 }
 
 static void sas_parse_addr(u8 *sas_addr, const char *p)
@@ -1108,16 +1089,12 @@ EXPORT_SYMBOL_GPL(sas_request_addr);
 EXPORT_SYMBOL_GPL(sas_queuecommand);
 EXPORT_SYMBOL_GPL(sas_target_alloc);
 EXPORT_SYMBOL_GPL(sas_slave_configure);
-EXPORT_SYMBOL_GPL(sas_slave_destroy);
 EXPORT_SYMBOL_GPL(sas_change_queue_depth);
 EXPORT_SYMBOL_GPL(sas_change_queue_type);
 EXPORT_SYMBOL_GPL(sas_bios_param);
-EXPORT_SYMBOL_GPL(__sas_task_abort);
 EXPORT_SYMBOL_GPL(sas_task_abort);
 EXPORT_SYMBOL_GPL(sas_phy_reset);
-EXPORT_SYMBOL_GPL(sas_phy_enable);
 EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
 EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
-EXPORT_SYMBOL_GPL(sas_slave_alloc);
 EXPORT_SYMBOL_GPL(sas_target_destroy);
 EXPORT_SYMBOL_GPL(sas_ioctl);
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 825f930..5fc044f 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -534,6 +534,7 @@ struct lpfc_hba {
 	void (*lpfc_scsi_prep_cmnd)
 		(struct lpfc_vport *, struct lpfc_scsi_buf *,
 		 struct lpfc_nodelist *);
+
 	/* IOCB interface function jump table entries */
 	int (*__lpfc_sli_issue_iocb)
 		(struct lpfc_hba *, uint32_t,
@@ -541,8 +542,6 @@ struct lpfc_hba {
 	void (*__lpfc_sli_release_iocbq)(struct lpfc_hba *,
 			 struct lpfc_iocbq *);
 	int (*lpfc_hba_down_post)(struct lpfc_hba *phba);
-
-
 	IOCB_t * (*lpfc_get_iocb_from_iocbq)
 		(struct lpfc_iocbq *);
 	void (*lpfc_scsi_cmd_iocb_cmpl)
@@ -551,10 +550,12 @@ struct lpfc_hba {
 	/* MBOX interface function jump table entries */
 	int (*lpfc_sli_issue_mbox)
 		(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
+
 	/* Slow-path IOCB process function jump table entries */
 	void (*lpfc_sli_handle_slow_ring_event)
 		(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		 uint32_t mask);
+
 	/* INIT device interface function jump table entries */
 	int (*lpfc_sli_hbq_to_firmware)
 		(struct lpfc_hba *, uint32_t, struct hbq_dmabuf *);
@@ -573,6 +574,10 @@ struct lpfc_hba {
 	int (*lpfc_selective_reset)
 		(struct lpfc_hba *);
 
+	int (*lpfc_bg_scsi_prep_dma_buf)
+		(struct lpfc_hba *, struct lpfc_scsi_buf *);
+	/* Add new entries here */
+
 	/* SLI4 specific HBA data structure */
 	struct lpfc_sli4_hba sli4_hba;
 
@@ -838,6 +843,7 @@ struct lpfc_hba {
 	struct dentry *debug_writeGuard; /* inject write guard_tag errors */
 	struct dentry *debug_writeApp;   /* inject write app_tag errors */
 	struct dentry *debug_writeRef;   /* inject write ref_tag errors */
+	struct dentry *debug_readGuard;  /* inject read guard_tag errors */
 	struct dentry *debug_readApp;    /* inject read app_tag errors */
 	struct dentry *debug_readRef;    /* inject read ref_tag errors */
 
@@ -845,10 +851,11 @@ struct lpfc_hba {
 	uint32_t lpfc_injerr_wgrd_cnt;
 	uint32_t lpfc_injerr_wapp_cnt;
 	uint32_t lpfc_injerr_wref_cnt;
+	uint32_t lpfc_injerr_rgrd_cnt;
 	uint32_t lpfc_injerr_rapp_cnt;
 	uint32_t lpfc_injerr_rref_cnt;
 	sector_t lpfc_injerr_lba;
-#define LPFC_INJERR_LBA_OFF	(sector_t)0xffffffffffffffff
+#define LPFC_INJERR_LBA_OFF	(sector_t)(-1)
 
 	struct dentry *debug_slow_ring_trc;
 	struct lpfc_debugfs_trc *slow_ring_trc;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index f6697cb..296ad5b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -353,7 +353,7 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
 	struct lpfc_hba   *phba = vport->phba;
 	uint32_t if_type;
 	uint8_t sli_family;
-	char fwrev[32];
+	char fwrev[FW_REV_STR_SIZE];
 	int len;
 
 	lpfc_decode_firmware_rev(phba, fwrev, 1);
@@ -922,11 +922,15 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
 	rc = lpfc_sli4_pdev_status_reg_wait(phba);
 
 	if (rc == -EPERM) {
-		/* no privilage for reset, restore if needed */
-		if (before_fc_flag & FC_OFFLINE_MODE)
-			goto out;
+		/* no privilage for reset */
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"3150 No privilage to perform the requested "
+				"access: x%x\n", reg_val);
 	} else if (rc == -EIO) {
 		/* reset failed, there is nothing more we can do */
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"3153 Fail to perform the requested "
+				"access: x%x\n", reg_val);
 		return rc;
 	}
 
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 56a86ba..141e4b4 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -589,7 +589,10 @@ lpfc_bsg_rport_els(struct fc_bsg_job *job)
 	}
 	cmdiocbq->iocb.un.elsreq64.bdl.bdeSize =
 		(request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
-	cmdiocbq->iocb.ulpContext = rpi;
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		cmdiocbq->iocb.ulpContext = phba->sli4_hba.rpi_ids[rpi];
+	else
+		cmdiocbq->iocb.ulpContext = rpi;
 	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
 	cmdiocbq->context1 = NULL;
 	cmdiocbq->context2 = NULL;
@@ -1768,7 +1771,7 @@ lpfc_sli4_bsg_set_internal_loopback(struct lpfc_hba *phba)
 	bf_set(lpfc_mbx_set_diag_state_link_type,
 	       &link_diag_loopback->u.req, phba->sli4_hba.lnk_info.lnk_tp);
 	bf_set(lpfc_mbx_set_diag_lpbk_type, &link_diag_loopback->u.req,
-	       LPFC_DIAG_LOOPBACK_TYPE_SERDES);
+	       LPFC_DIAG_LOOPBACK_TYPE_INTERNAL);
 
 	mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO);
 	if ((mbxstatus != MBX_SUCCESS) || (pmboxq->u.mb.mbxStatus)) {
@@ -3977,7 +3980,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 			case COMN_OPCODE_GET_CNTL_ADDL_ATTRIBUTES:
 				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
 						"3106 Handled SLI_CONFIG "
-						"subsys_fcoe, opcode:x%x\n",
+						"subsys_comn, opcode:x%x\n",
 						opcode);
 				rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job,
 							nemb_mse, dmabuf);
@@ -3985,7 +3988,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 			default:
 				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
 						"3107 Reject SLI_CONFIG "
-						"subsys_fcoe, opcode:x%x\n",
+						"subsys_comn, opcode:x%x\n",
 						opcode);
 				rc = -EPERM;
 				break;
@@ -4556,7 +4559,12 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
 							+ sizeof(MAILBOX_t));
 		}
 	} else if (phba->sli_rev == LPFC_SLI_REV4) {
-		if (pmb->mbxCommand == MBX_DUMP_MEMORY) {
+		/* Let type 4 (well known data) through because the data is
+		 * returned in varwords[4-8]
+		 * otherwise check the recieve length and fetch the buffer addr
+		 */
+		if ((pmb->mbxCommand == MBX_DUMP_MEMORY) &&
+			(pmb->un.varDmp.type != DMP_WELL_KNOWN)) {
 			/* rebuild the command for sli4 using our own buffers
 			* like we do for biu diags
 			*/
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 26924b7..330dd71 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -462,3 +462,4 @@ int lpfc_issue_unreg_vfi(struct lpfc_vport *);
 int lpfc_selective_reset(struct lpfc_hba *);
 int lpfc_sli4_read_config(struct lpfc_hba *phba);
 int lpfc_scsi_buf_update(struct lpfc_hba *phba);
+void lpfc_sli4_node_prep(struct lpfc_hba *phba);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 707081d..93e96b3 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1076,7 +1076,7 @@ int
 lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
 	size_t size)
 {
-	char fwrev[16];
+	char fwrev[FW_REV_STR_SIZE];
 	int n;
 
 	lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
@@ -1834,7 +1834,7 @@ lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
 	uint8_t *fwname;
 
 	if (phba->sli_rev == LPFC_SLI_REV4)
-		sprintf(fwrevision, "%s", vp->rev.opFwName);
+		snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);
 	else if (vp->rev.rBit) {
 		if (psli->sli_flag & LPFC_SLI_ACTIVE)
 			rev = vp->rev.sli2FwRev;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 3587a3f..22e17be 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1019,6 +1019,8 @@ lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
 		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt);
 	else if (dent == phba->debug_writeRef)
 		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt);
+	else if (dent == phba->debug_readGuard)
+		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rgrd_cnt);
 	else if (dent == phba->debug_readApp)
 		cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt);
 	else if (dent == phba->debug_readRef)
@@ -1057,6 +1059,8 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
 		phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
 	else if (dent == phba->debug_writeRef)
 		phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
+	else if (dent == phba->debug_readGuard)
+		phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp;
 	else if (dent == phba->debug_readApp)
 		phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
 	else if (dent == phba->debug_readRef)
@@ -3978,6 +3982,17 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
 			goto debug_failed;
 		}
 
+		snprintf(name, sizeof(name), "readGuardInjErr");
+		phba->debug_readGuard =
+			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
+			phba->hba_debugfs_root,
+			phba, &lpfc_debugfs_op_dif_err);
+		if (!phba->debug_readGuard) {
+			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+				"0808 Cannot create debugfs readGuard\n");
+			goto debug_failed;
+		}
+
 		snprintf(name, sizeof(name), "readAppInjErr");
 		phba->debug_readApp =
 			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
@@ -4318,6 +4333,10 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
 			debugfs_remove(phba->debug_writeRef); /* writeRef */
 			phba->debug_writeRef = NULL;
 		}
+		if (phba->debug_readGuard) {
+			debugfs_remove(phba->debug_readGuard); /* readGuard */
+			phba->debug_readGuard = NULL;
+		}
 		if (phba->debug_readApp) {
 			debugfs_remove(phba->debug_readApp); /* readApp */
 			phba->debug_readApp = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 7afc757..8db2fb3 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1526,7 +1526,6 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 			memcpy(&ndlp->active_rrqs.xri_bitmap,
 				&rrq.xri_bitmap,
 				sizeof(ndlp->active_rrqs.xri_bitmap));
-		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 		/* Since we are swapping the ndlp passed in with the new one
 		 * and the did has already been swapped, copy over the
 		 * state and names.
@@ -1536,6 +1535,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 		memcpy(&new_ndlp->nlp_nodename, &ndlp->nlp_nodename,
 			sizeof(struct lpfc_name));
 		new_ndlp->nlp_state = ndlp->nlp_state;
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 		/* Fix up the rport accordingly */
 		rport = ndlp->rport;
 		if (rport) {
@@ -7172,7 +7172,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 			goto out;
 		/* FDISC failed */
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
-				 "0126 FDISC failed. (%d/%d)\n",
+				 "0126 FDISC failed. (x%x/x%x)\n",
 				 irsp->ulpStatus, irsp->un.ulpWord[4]);
 		goto fdisc_failed;
 	}
@@ -7283,6 +7283,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	int rc;
 
 	vport->port_state = LPFC_FDISC;
+	vport->fc_myDID = 0;
 	cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
 	elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
 				     ELS_CMD_FDISC);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 678a4b1..343d87b 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -2977,9 +2977,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
 				"topology\n");
 				/* Get Loop Map information */
 		if (bf_get(lpfc_mbx_read_top_il, la)) {
-			spin_lock_irq(shost->host_lock);
+			spin_lock(shost->host_lock);
 			vport->fc_flag |= FC_LBIT;
-			spin_unlock_irq(shost->host_lock);
+			spin_unlock(shost->host_lock);
 		}
 
 		vport->fc_myDID = bf_get(lpfc_mbx_read_top_alpa_granted, la);
@@ -3029,9 +3029,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la)
 				phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
 		}
 		vport->fc_myDID = phba->fc_pref_DID;
-		spin_lock_irq(shost->host_lock);
+		spin_lock(shost->host_lock);
 		vport->fc_flag |= FC_LBIT;
-		spin_unlock_irq(shost->host_lock);
+		spin_unlock(shost->host_lock);
 	}
 	spin_unlock_irq(&phba->hbalock);
 
@@ -5332,6 +5332,10 @@ lpfc_filter_by_rpi(struct lpfc_nodelist *ndlp, void *param)
 {
 	uint16_t *rpi = param;
 
+	/* check for active node */
+	if (!NLP_CHK_NODE_ACT(ndlp))
+		return 0;
+
 	return ndlp->nlp_rpi == *rpi;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 7245bea..5f280b5 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2010 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2011 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  *                                                                 *
@@ -70,6 +70,7 @@
 /* vendor ID used in SCSI netlink calls */
 #define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX)
 
+#define FW_REV_STR_SIZE	32
 /* Common Transport structures and definitions */
 
 union CtRevisionId {
@@ -2567,6 +2568,8 @@ typedef struct {
 
 #define  DMP_MEM_REG             0x1
 #define  DMP_NV_PARAMS           0x2
+#define  DMP_LMSD                0x3 /* Link Module Serial Data */
+#define  DMP_WELL_KNOWN          0x4
 
 #define  DMP_REGION_VPD          0xe
 #define  DMP_VPD_SIZE            0x400  /* maximum amount of VPD */
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index e5bfa7f..9e2b9b2 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -321,6 +321,10 @@ struct lpfc_cqe {
 #define CQE_STATUS_CMD_REJECT		0xb
 #define CQE_STATUS_FCP_TGT_LENCHECK	0xc
 #define CQE_STATUS_NEED_BUFF_ENTRY	0xf
+#define CQE_STATUS_DI_ERROR		0x16
+
+/* Used when mapping CQE status to IOCB */
+#define LPFC_IOCB_STATUS_MASK		0xf
 
 /* Status returned by hardware (valid only if status = CQE_STATUS_SUCCESS). */
 #define CQE_HW_STATUS_NO_ERR		0x0
@@ -348,6 +352,21 @@ struct lpfc_wcqe_complete {
 #define lpfc_wcqe_c_hw_status_WORD	word0
 	uint32_t total_data_placed;
 	uint32_t parameter;
+#define lpfc_wcqe_c_bg_edir_SHIFT	5
+#define lpfc_wcqe_c_bg_edir_MASK	0x00000001
+#define lpfc_wcqe_c_bg_edir_WORD	parameter
+#define lpfc_wcqe_c_bg_tdpv_SHIFT	3
+#define lpfc_wcqe_c_bg_tdpv_MASK	0x00000001
+#define lpfc_wcqe_c_bg_tdpv_WORD	parameter
+#define lpfc_wcqe_c_bg_re_SHIFT		2
+#define lpfc_wcqe_c_bg_re_MASK		0x00000001
+#define lpfc_wcqe_c_bg_re_WORD		parameter
+#define lpfc_wcqe_c_bg_ae_SHIFT		1
+#define lpfc_wcqe_c_bg_ae_MASK		0x00000001
+#define lpfc_wcqe_c_bg_ae_WORD		parameter
+#define lpfc_wcqe_c_bg_ge_SHIFT		0
+#define lpfc_wcqe_c_bg_ge_MASK		0x00000001
+#define lpfc_wcqe_c_bg_ge_WORD		parameter
 	uint32_t word3;
 #define lpfc_wcqe_c_valid_SHIFT		lpfc_cqe_valid_SHIFT
 #define lpfc_wcqe_c_valid_MASK		lpfc_cqe_valid_MASK
@@ -359,8 +378,8 @@ struct lpfc_wcqe_complete {
 #define lpfc_wcqe_c_pv_MASK		0x00000001
 #define lpfc_wcqe_c_pv_WORD		word3
 #define lpfc_wcqe_c_priority_SHIFT	24
-#define lpfc_wcqe_c_priority_MASK		0x00000007
-#define lpfc_wcqe_c_priority_WORD		word3
+#define lpfc_wcqe_c_priority_MASK	0x00000007
+#define lpfc_wcqe_c_priority_WORD	word3
 #define lpfc_wcqe_c_code_SHIFT		lpfc_cqe_code_SHIFT
 #define lpfc_wcqe_c_code_MASK		lpfc_cqe_code_MASK
 #define lpfc_wcqe_c_code_WORD		lpfc_cqe_code_WORD
@@ -715,12 +734,20 @@ struct lpfc_register {
 #define lpfc_eqcq_doorbell_eqci_SHIFT		9
 #define lpfc_eqcq_doorbell_eqci_MASK		0x0001
 #define lpfc_eqcq_doorbell_eqci_WORD		word0
-#define lpfc_eqcq_doorbell_cqid_SHIFT		0
-#define lpfc_eqcq_doorbell_cqid_MASK		0x03FF
-#define lpfc_eqcq_doorbell_cqid_WORD		word0
-#define lpfc_eqcq_doorbell_eqid_SHIFT		0
-#define lpfc_eqcq_doorbell_eqid_MASK		0x01FF
-#define lpfc_eqcq_doorbell_eqid_WORD		word0
+#define lpfc_eqcq_doorbell_cqid_lo_SHIFT	0
+#define lpfc_eqcq_doorbell_cqid_lo_MASK		0x03FF
+#define lpfc_eqcq_doorbell_cqid_lo_WORD		word0
+#define lpfc_eqcq_doorbell_cqid_hi_SHIFT	11
+#define lpfc_eqcq_doorbell_cqid_hi_MASK		0x001F
+#define lpfc_eqcq_doorbell_cqid_hi_WORD		word0
+#define lpfc_eqcq_doorbell_eqid_lo_SHIFT	0
+#define lpfc_eqcq_doorbell_eqid_lo_MASK		0x01FF
+#define lpfc_eqcq_doorbell_eqid_lo_WORD		word0
+#define lpfc_eqcq_doorbell_eqid_hi_SHIFT	11
+#define lpfc_eqcq_doorbell_eqid_hi_MASK		0x001F
+#define lpfc_eqcq_doorbell_eqid_hi_WORD		word0
+#define LPFC_CQID_HI_FIELD_SHIFT		10
+#define LPFC_EQID_HI_FIELD_SHIFT		9
 
 #define LPFC_BMBX			0x0160
 #define lpfc_bmbx_addr_SHIFT		2
@@ -3313,7 +3340,11 @@ struct xmit_bls_rsp64_wqe {
 	uint32_t rsrvd4;
 	struct wqe_did	wqe_dest;
 	struct wqe_common wqe_com; /* words 6-11 */
-	uint32_t rsvd_12_15[4];
+	uint32_t word12;
+#define xmit_bls_rsp64_temprpi_SHIFT  0
+#define xmit_bls_rsp64_temprpi_MASK   0x0000ffff
+#define xmit_bls_rsp64_temprpi_WORD   word12
+	uint32_t rsvd_13_15[3];
 };
 
 struct wqe_rctl_dfctl {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index dfea2da..b38f99f 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -32,6 +32,7 @@
 #include <linux/aer.h>
 #include <linux/slab.h>
 #include <linux/firmware.h>
+#include <linux/miscdevice.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -1474,8 +1475,12 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
 				phba->sli4_hba.u.if_type2.STATUSregaddr,
 				&portstat_reg.word0);
 		/* consider PCI bus read error as pci_channel_offline */
-		if (pci_rd_rc1 == -EIO)
+		if (pci_rd_rc1 == -EIO) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3151 PCI bus read access failure: x%x\n",
+				readl(phba->sli4_hba.u.if_type2.STATUSregaddr));
 			return;
+		}
 		reg_err1 = readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
 		reg_err2 = readl(phba->sli4_hba.u.if_type2.ERR2regaddr);
 		if (bf_get(lpfc_sliport_status_oti, &portstat_reg)) {
@@ -1525,6 +1530,9 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba)
 			}
 			/* fall through for not able to recover */
 		}
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3152 Unrecoverable error, bring the port "
+				"offline\n");
 		lpfc_sli4_offline_eratt(phba);
 		break;
 	case LPFC_SLI_INTF_IF_TYPE_1:
@@ -2333,13 +2341,20 @@ lpfc_cleanup(struct lpfc_vport *vport)
 			continue;
 		}
 
+		/* take care of nodes in unused state before the state
+		 * machine taking action.
+		 */
+		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
+			lpfc_nlp_put(ndlp);
+			continue;
+		}
+
 		if (ndlp->nlp_type & NLP_FABRIC)
 			lpfc_disc_state_machine(vport, ndlp, NULL,
 					NLP_EVT_DEVICE_RECOVERY);
 
 		lpfc_disc_state_machine(vport, ndlp, NULL,
 					     NLP_EVT_DEVICE_RM);
-
 	}
 
 	/* At this point, ALL ndlp's should be gone
@@ -2513,6 +2528,42 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba)
 }
 
 /**
+ * lpfc_sli4_node_prep - Assign RPIs for active nodes.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * Allocate RPIs for all active remote nodes. This is needed whenever
+ * an SLI4 adapter is reset and the driver is not unloading. Its purpose
+ * is to fixup the temporary rpi assignments.
+ **/
+void
+lpfc_sli4_node_prep(struct lpfc_hba *phba)
+{
+	struct lpfc_nodelist  *ndlp, *next_ndlp;
+	struct lpfc_vport **vports;
+	int i;
+
+	if (phba->sli_rev != LPFC_SLI_REV4)
+		return;
+
+	vports = lpfc_create_vport_work_array(phba);
+	if (vports != NULL) {
+		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
+			if (vports[i]->load_flag & FC_UNLOADING)
+				continue;
+
+			list_for_each_entry_safe(ndlp, next_ndlp,
+						 &vports[i]->fc_nodes,
+						 nlp_listp) {
+				if (NLP_CHK_NODE_ACT(ndlp))
+					ndlp->nlp_rpi =
+						lpfc_sli4_alloc_rpi(phba);
+			}
+		}
+	}
+	lpfc_destroy_vport_work_array(phba, vports);
+}
+
+/**
  * lpfc_online - Initialize and bring a HBA online
  * @phba: pointer to lpfc hba data structure.
  *
@@ -2653,6 +2704,15 @@ lpfc_offline_prep(struct lpfc_hba * phba)
 				}
 				spin_lock_irq(shost->host_lock);
 				ndlp->nlp_flag &= ~NLP_NPR_ADISC;
+
+				/*
+				 * Whenever an SLI4 port goes offline, free the
+				 * RPI.  A new RPI when the adapter port comes
+				 * back online.
+				 */
+				if (phba->sli_rev == LPFC_SLI_REV4)
+					lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi);
+
 				spin_unlock_irq(shost->host_lock);
 				lpfc_unreg_rpi(vports[i], ndlp);
 			}
@@ -4327,6 +4387,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 	uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0};
 	struct lpfc_mqe *mqe;
 	int longs, sli_family;
+	int sges_per_segment;
 
 	/* Before proceed, wait for POST done and device ready */
 	rc = lpfc_sli4_post_status_check(phba);
@@ -4390,6 +4451,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 	phba->fc_map[1] = LPFC_FCOE_FCF_MAP1;
 	phba->fc_map[2] = LPFC_FCOE_FCF_MAP2;
 
+	/* With BlockGuard we can have multiple SGEs per Data Segemnt */
+	sges_per_segment = 1;
+	if (phba->cfg_enable_bg)
+		sges_per_segment = 2;
+
 	/*
 	 * Since the sg_tablesize is module parameter, the sg_dma_buf_size
 	 * used to create the sg_dma_buf_pool must be dynamically calculated.
@@ -4398,7 +4464,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 	 * sgl sizes of must be a power of 2.
 	 */
 	buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) +
-		    ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)));
+		    (((phba->cfg_sg_seg_cnt * sges_per_segment) + 2) *
+		    sizeof(struct sli4_sge)));
 
 	sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf);
 	max_buf_size = LPFC_SLI4_MAX_BUF_SIZE;
@@ -4415,6 +4482,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
 	default:
 		break;
 	}
+
 	for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE;
 	     dma_buf_size < max_buf_size && buf_size > dma_buf_size;
 	     dma_buf_size = dma_buf_size << 1)
@@ -7223,19 +7291,17 @@ lpfc_pci_function_reset(struct lpfc_hba *phba)
 					rc = -ENODEV;
 					goto out;
 				}
-				if (bf_get(lpfc_sliport_status_rdy, &reg_data))
-					break;
-				if (bf_get(lpfc_sliport_status_rn, &reg_data)) {
+				if (bf_get(lpfc_sliport_status_rn, &reg_data))
 					reset_again++;
+				if (bf_get(lpfc_sliport_status_rdy, &reg_data))
 					break;
-				}
 			}
 
 			/*
 			 * If the port responds to the init request with
 			 * reset needed, delay for a bit and restart the loop.
 			 */
-			if (reset_again) {
+			if (reset_again && (rdy_chk < 1000)) {
 				msleep(10);
 				reset_again = 0;
 				continue;
@@ -8112,6 +8178,9 @@ lpfc_unset_hba(struct lpfc_hba *phba)
 	vport->load_flag |= FC_UNLOADING;
 	spin_unlock_irq(shost->host_lock);
 
+	kfree(phba->vpi_bmask);
+	kfree(phba->vpi_ids);
+
 	lpfc_stop_hba_timers(phba);
 
 	phba->pport->work_port_events = 0;
@@ -8644,6 +8713,9 @@ lpfc_pci_remove_one_s3(struct pci_dev *pdev)
 	/* Final cleanup of txcmplq and reset the HBA */
 	lpfc_sli_brdrestart(phba);
 
+	kfree(phba->vpi_bmask);
+	kfree(phba->vpi_ids);
+
 	lpfc_stop_hba_timers(phba);
 	spin_lock_irq(&phba->hbalock);
 	list_del_init(&vport->listentry);
@@ -9058,7 +9130,7 @@ lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *phba)
 int
 lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
 {
-	char fwrev[32];
+	char fwrev[FW_REV_STR_SIZE];
 	struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data;
 	struct list_head dma_buffer_list;
 	int i, rc = 0;
@@ -10012,6 +10084,36 @@ lpfc_io_resume(struct pci_dev *pdev)
 	return;
 }
 
+/**
+ * lpfc_mgmt_open - method called when 'lpfcmgmt' is opened from userspace
+ * @inode: pointer to the inode representing the lpfcmgmt device
+ * @filep: pointer to the file representing the open lpfcmgmt device
+ *
+ * This routine puts a reference count on the lpfc module whenever the
+ * character device is opened
+ **/
+static int
+lpfc_mgmt_open(struct inode *inode, struct file *filep)
+{
+	try_module_get(THIS_MODULE);
+	return 0;
+}
+
+/**
+ * lpfc_mgmt_release - method called when 'lpfcmgmt' is closed in userspace
+ * @inode: pointer to the inode representing the lpfcmgmt device
+ * @filep: pointer to the file representing the open lpfcmgmt device
+ *
+ * This routine removes a reference count from the lpfc module when the
+ * character device is closed
+ **/
+static int
+lpfc_mgmt_release(struct inode *inode, struct file *filep)
+{
+	module_put(THIS_MODULE);
+	return 0;
+}
+
 static struct pci_device_id lpfc_id_table[] = {
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_VIPER,
 		PCI_ANY_ID, PCI_ANY_ID, },
@@ -10124,6 +10226,17 @@ static struct pci_driver lpfc_driver = {
 	.err_handler    = &lpfc_err_handler,
 };
 
+static const struct file_operations lpfc_mgmt_fop = {
+	.open = lpfc_mgmt_open,
+	.release = lpfc_mgmt_release,
+};
+
+static struct miscdevice lpfc_mgmt_dev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "lpfcmgmt",
+	.fops = &lpfc_mgmt_fop,
+};
+
 /**
  * lpfc_init - lpfc module initialization routine
  *
@@ -10144,6 +10257,11 @@ lpfc_init(void)
 	printk(LPFC_MODULE_DESC "\n");
 	printk(LPFC_COPYRIGHT "\n");
 
+	error = misc_register(&lpfc_mgmt_dev);
+	if (error)
+		printk(KERN_ERR "Could not register lpfcmgmt device, "
+			"misc_register returned with status %d", error);
+
 	if (lpfc_enable_npiv) {
 		lpfc_transport_functions.vport_create = lpfc_vport_create;
 		lpfc_transport_functions.vport_delete = lpfc_vport_delete;
@@ -10180,6 +10298,7 @@ lpfc_init(void)
 static void __exit
 lpfc_exit(void)
 {
+	misc_deregister(&lpfc_mgmt_dev);
 	pci_unregister_driver(&lpfc_driver);
 	fc_release_transport(lpfc_transport_template);
 	if (lpfc_enable_npiv)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index e8bb005..7b6b2aa 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -48,6 +48,10 @@ static int
 lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		 struct lpfc_name *nn, struct lpfc_name *pn)
 {
+	/* First, we MUST have a RPI registered */
+	if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED))
+		return 0;
+
 	/* Compare the ADISC rsp WWNN / WWPN matches our internal node
 	 * table entry for that node.
 	 */
@@ -385,6 +389,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	if (!mbox)
 		goto out;
 
+	/* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		lpfc_unreg_rpi(vport, ndlp);
+
 	rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
 			    (uint8_t *) sp, mbox, ndlp->nlp_rpi);
 	if (rc) {
@@ -445,11 +453,43 @@ out:
 	return 0;
 }
 
+/**
+ * lpfc_mbx_cmpl_resume_rpi - Resume RPI completion routine
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox object
+ *
+ * This routine is invoked to issue a completion to a rcv'ed
+ * ADISC or PDISC after the paused RPI has been resumed.
+ **/
+static void
+lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+	struct lpfc_vport *vport;
+	struct lpfc_iocbq *elsiocb;
+	struct lpfc_nodelist *ndlp;
+	uint32_t cmd;
+
+	elsiocb = (struct lpfc_iocbq *)mboxq->context1;
+	ndlp = (struct lpfc_nodelist *) mboxq->context2;
+	vport = mboxq->vport;
+	cmd = elsiocb->drvrTimeout;
+
+	if (cmd == ELS_CMD_ADISC) {
+		lpfc_els_rsp_adisc_acc(vport, elsiocb, ndlp);
+	} else {
+		lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,
+			ndlp, NULL);
+	}
+	kfree(elsiocb);
+	mempool_free(mboxq, phba->mbox_mem_pool);
+}
+
 static int
 lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 		struct lpfc_iocbq *cmdiocb)
 {
 	struct Scsi_Host   *shost = lpfc_shost_from_vport(vport);
+	struct lpfc_iocbq  *elsiocb;
 	struct lpfc_dmabuf *pcmd;
 	struct serv_parm   *sp;
 	struct lpfc_name   *pnn, *ppn;
@@ -475,12 +515,43 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 
 	icmd = &cmdiocb->iocb;
 	if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
+
+		/*
+		 * As soon as  we send ACC, the remote NPort can
+		 * start sending us data. Thus, for SLI4 we must
+		 * resume the RPI before the ACC goes out.
+		 */
+		if (vport->phba->sli_rev == LPFC_SLI_REV4) {
+			elsiocb = kmalloc(sizeof(struct lpfc_iocbq),
+				GFP_KERNEL);
+			if (elsiocb) {
+
+				/* Save info from cmd IOCB used in rsp */
+				memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb,
+					sizeof(struct lpfc_iocbq));
+
+				/* Save the ELS cmd */
+				elsiocb->drvrTimeout = cmd;
+
+				lpfc_sli4_resume_rpi(ndlp,
+					lpfc_mbx_cmpl_resume_rpi, elsiocb);
+				goto out;
+			}
+		}
+
 		if (cmd == ELS_CMD_ADISC) {
 			lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
 		} else {
-			lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp,
-					 NULL);
+			lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
+				ndlp, NULL);
 		}
+out:
+		/* If we are authenticated, move to the proper state */
+		if (ndlp->nlp_type & NLP_FCP_TARGET)
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
+		else
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
+
 		return 1;
 	}
 	/* Reject this request because invalid parameters */
@@ -1229,7 +1300,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
 	}
 
 	if (phba->sli_rev == LPFC_SLI_REV4) {
-		rc = lpfc_sli4_resume_rpi(ndlp);
+		rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);
 		if (rc) {
 			/* Stay in state and retry. */
 			ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c60f5d0..efc055b 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2011 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2012 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -1280,31 +1280,45 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc)
 }
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
-/*
- * Given a scsi cmnd, determine the BlockGuard tags to be used with it
+
+#define BG_ERR_INIT	1
+#define BG_ERR_TGT	2
+#define BG_ERR_SWAP	3
+#define BG_ERR_CHECK	4
+
+/**
+ * lpfc_bg_err_inject - Determine if we should inject an error
+ * @phba: The Hba for which this call is being executed.
  * @sc: The SCSI command to examine
  * @reftag: (out) BlockGuard reference tag for transmitted data
  * @apptag: (out) BlockGuard application tag for transmitted data
  * @new_guard (in) Value to replace CRC with if needed
  *
- * Returns (1) if error injection was performed, (0) otherwise
- */
+ * Returns (1) if error injection is detected by Initiator
+ * Returns (2) if error injection is detected by Target
+ * Returns (3) if swapping CSUM->CRC is required for error injection
+ * Returns (4) disabling Guard/Ref/App checking is required for error injection
+ **/
 static int
 lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		uint32_t *reftag, uint16_t *apptag, uint32_t new_guard)
 {
 	struct scatterlist *sgpe; /* s/g prot entry */
 	struct scatterlist *sgde; /* s/g data entry */
-	struct scsi_dif_tuple *src;
+	struct scsi_dif_tuple *src = NULL;
 	uint32_t op = scsi_get_prot_op(sc);
 	uint32_t blksize;
 	uint32_t numblks;
 	sector_t lba;
 	int rc = 0;
+	int blockoff = 0;
 
 	if (op == SCSI_PROT_NORMAL)
 		return 0;
 
+	sgpe = scsi_prot_sglist(sc);
+	sgde = scsi_sglist(sc);
+
 	lba = scsi_get_lba(sc);
 	if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) {
 		blksize = lpfc_cmd_blksize(sc);
@@ -1314,142 +1328,296 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		if ((phba->lpfc_injerr_lba < lba) ||
 			(phba->lpfc_injerr_lba >= (lba + numblks)))
 			return 0;
+		if (sgpe) {
+			blockoff = phba->lpfc_injerr_lba - lba;
+			numblks = sg_dma_len(sgpe) /
+				sizeof(struct scsi_dif_tuple);
+			if (numblks < blockoff)
+				blockoff = numblks;
+			src = (struct scsi_dif_tuple *)sg_virt(sgpe);
+			src += blockoff;
+		}
 	}
 
-	sgpe = scsi_prot_sglist(sc);
-	sgde = scsi_sglist(sc);
-
 	/* Should we change the Reference Tag */
 	if (reftag) {
-		/*
-		 * If we are SCSI_PROT_WRITE_STRIP, the protection data is
-		 * being stripped from the wire, thus it doesn't matter.
-		 */
-		if ((op == SCSI_PROT_WRITE_PASS) ||
-			(op == SCSI_PROT_WRITE_INSERT)) {
-			if (phba->lpfc_injerr_wref_cnt) {
+		if (phba->lpfc_injerr_wref_cnt) {
+			switch (op) {
+			case SCSI_PROT_WRITE_PASS:
+				if (blockoff && src) {
+					/* Insert error in middle of the IO */
+
+					lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9076 BLKGRD: Injecting reftag error: "
+					"write lba x%lx + x%x oldrefTag x%x\n",
+					(unsigned long)lba, blockoff,
+					src->ref_tag);
 
+					/*
+					 * NOTE, this will change ref tag in
+					 * the memory location forever!
+					 */
+					src->ref_tag = 0xDEADBEEF;
+					phba->lpfc_injerr_wref_cnt--;
+					phba->lpfc_injerr_lba =
+						LPFC_INJERR_LBA_OFF;
+					rc = BG_ERR_CHECK;
+					break;
+				}
+				/* Drop thru */
+			case SCSI_PROT_WRITE_STRIP:
+				/*
+				 * For WRITE_STRIP and WRITE_PASS,
+				 * force the error on data
+				 * being copied from SLI-Host to SLI-Port.
+				 */
+				*reftag = 0xDEADBEEF;
+				phba->lpfc_injerr_wref_cnt--;
+				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
+				rc = BG_ERR_INIT;
+
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9077 BLKGRD: Injecting reftag error: "
+					"write lba x%lx\n", (unsigned long)lba);
+				break;
+			case SCSI_PROT_WRITE_INSERT:
+				/*
+				 * For WRITE_INSERT, force the
+				 * error to be sent on the wire. It should be
+				 * detected by the Target.
+				 */
 				/* DEADBEEF will be the reftag on the wire */
 				*reftag = 0xDEADBEEF;
 				phba->lpfc_injerr_wref_cnt--;
 				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
-				rc = 1;
+				rc = BG_ERR_TGT;
 
 				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-					"9081 BLKGRD: Injecting reftag error: "
+					"9078 BLKGRD: Injecting reftag error: "
 					"write lba x%lx\n", (unsigned long)lba);
+				break;
 			}
-		} else {
-			if (phba->lpfc_injerr_rref_cnt) {
+		}
+		if (phba->lpfc_injerr_rref_cnt) {
+			switch (op) {
+			case SCSI_PROT_READ_INSERT:
+				/*
+				 * For READ_INSERT, it doesn't make sense
+				 * to change the reftag.
+				 */
+				break;
+			case SCSI_PROT_READ_STRIP:
+			case SCSI_PROT_READ_PASS:
+				/*
+				 * For READ_STRIP and READ_PASS, force the
+				 * error on data being read off the wire. It
+				 * should force an IO error to the driver.
+				 */
 				*reftag = 0xDEADBEEF;
 				phba->lpfc_injerr_rref_cnt--;
 				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
-				rc = 1;
+				rc = BG_ERR_INIT;
 
 				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-					"9076 BLKGRD: Injecting reftag error: "
+					"9079 BLKGRD: Injecting reftag error: "
 					"read lba x%lx\n", (unsigned long)lba);
+				break;
 			}
 		}
 	}
 
 	/* Should we change the Application Tag */
 	if (apptag) {
-		/*
-		 * If we are SCSI_PROT_WRITE_STRIP, the protection data is
-		 * being stripped from the wire, thus it doesn't matter.
-		 */
-		if ((op == SCSI_PROT_WRITE_PASS) ||
-			(op == SCSI_PROT_WRITE_INSERT)) {
-			if (phba->lpfc_injerr_wapp_cnt) {
+		if (phba->lpfc_injerr_wapp_cnt) {
+			switch (op) {
+			case SCSI_PROT_WRITE_PASS:
+				if (blockoff && src) {
+					/* Insert error in middle of the IO */
+
+					lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9080 BLKGRD: Injecting apptag error: "
+					"write lba x%lx + x%x oldappTag x%x\n",
+					(unsigned long)lba, blockoff,
+					src->app_tag);
+
+					/*
+					 * NOTE, this will change app tag in
+					 * the memory location forever!
+					 */
+					src->app_tag = 0xDEAD;
+					phba->lpfc_injerr_wapp_cnt--;
+					phba->lpfc_injerr_lba =
+						LPFC_INJERR_LBA_OFF;
+					rc = BG_ERR_CHECK;
+					break;
+				}
+				/* Drop thru */
+			case SCSI_PROT_WRITE_STRIP:
+				/*
+				 * For WRITE_STRIP and WRITE_PASS,
+				 * force the error on data
+				 * being copied from SLI-Host to SLI-Port.
+				 */
+				*apptag = 0xDEAD;
+				phba->lpfc_injerr_wapp_cnt--;
+				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
+				rc = BG_ERR_INIT;
 
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"0812 BLKGRD: Injecting apptag error: "
+					"write lba x%lx\n", (unsigned long)lba);
+				break;
+			case SCSI_PROT_WRITE_INSERT:
+				/*
+				 * For WRITE_INSERT, force the
+				 * error to be sent on the wire. It should be
+				 * detected by the Target.
+				 */
 				/* DEAD will be the apptag on the wire */
 				*apptag = 0xDEAD;
 				phba->lpfc_injerr_wapp_cnt--;
 				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
-				rc = 1;
+				rc = BG_ERR_TGT;
 
 				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-					"9077 BLKGRD: Injecting apptag error: "
+					"0813 BLKGRD: Injecting apptag error: "
 					"write lba x%lx\n", (unsigned long)lba);
+				break;
 			}
-		} else {
-			if (phba->lpfc_injerr_rapp_cnt) {
+		}
+		if (phba->lpfc_injerr_rapp_cnt) {
+			switch (op) {
+			case SCSI_PROT_READ_INSERT:
+				/*
+				 * For READ_INSERT, it doesn't make sense
+				 * to change the apptag.
+				 */
+				break;
+			case SCSI_PROT_READ_STRIP:
+			case SCSI_PROT_READ_PASS:
+				/*
+				 * For READ_STRIP and READ_PASS, force the
+				 * error on data being read off the wire. It
+				 * should force an IO error to the driver.
+				 */
 				*apptag = 0xDEAD;
 				phba->lpfc_injerr_rapp_cnt--;
 				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
-				rc = 1;
+				rc = BG_ERR_INIT;
 
 				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-					"9078 BLKGRD: Injecting apptag error: "
+					"0814 BLKGRD: Injecting apptag error: "
 					"read lba x%lx\n", (unsigned long)lba);
+				break;
 			}
 		}
 	}
 
+
 	/* Should we change the Guard Tag */
+	if (new_guard) {
+		if (phba->lpfc_injerr_wgrd_cnt) {
+			switch (op) {
+			case SCSI_PROT_WRITE_PASS:
+				if (blockoff && src) {
+					/* Insert error in middle of the IO */
+
+					lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"0815 BLKGRD: Injecting guard error: "
+					"write lba x%lx + x%x oldgrdTag x%x\n",
+					(unsigned long)lba, blockoff,
+					src->guard_tag);
 
-	/*
-	 * If we are SCSI_PROT_WRITE_INSERT, the protection data is
-	 * being on the wire is being fully generated on the HBA.
-	 * The host cannot change it or force an error.
-	 */
-	if (((op == SCSI_PROT_WRITE_STRIP) ||
-		(op == SCSI_PROT_WRITE_PASS)) &&
-		phba->lpfc_injerr_wgrd_cnt) {
-		if (sgpe) {
-			src = (struct scsi_dif_tuple *)sg_virt(sgpe);
-			/*
-			 * Just inject an error in the first
-			 * prot block.
-			 */
-			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-				"9079 BLKGRD: Injecting guard error: "
-				"write lba x%lx oldGuard x%x refTag x%x\n",
-				(unsigned long)lba, src->guard_tag,
-				src->ref_tag);
+					/*
+					 * NOTE, this will change guard tag in
+					 * the memory location forever!
+					 */
+					src->guard_tag = 0xDEAD;
+					phba->lpfc_injerr_wgrd_cnt--;
+					phba->lpfc_injerr_lba =
+						LPFC_INJERR_LBA_OFF;
+					rc = BG_ERR_CHECK;
+					break;
+				}
+				/* Drop thru */
+			case SCSI_PROT_WRITE_STRIP:
+				/*
+				 * For WRITE_STRIP and WRITE_PASS,
+				 * force the error on data
+				 * being copied from SLI-Host to SLI-Port.
+				 */
+				phba->lpfc_injerr_wgrd_cnt--;
+				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
 
-			src->guard_tag = (uint16_t)new_guard;
-			phba->lpfc_injerr_wgrd_cnt--;
-			phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
-			rc = 1;
+				rc = BG_ERR_SWAP;
+				/* Signals the caller to swap CRC->CSUM */
 
-		} else {
-			blksize = lpfc_cmd_blksize(sc);
-			/*
-			 * Jump past the first data block
-			 * and inject an error in the
-			 * prot data. The prot data is already
-			 * embedded after the regular data.
-			 */
-			src = (struct scsi_dif_tuple *)
-					(sg_virt(sgde) + blksize);
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"0816 BLKGRD: Injecting guard error: "
+					"write lba x%lx\n", (unsigned long)lba);
+				break;
+			case SCSI_PROT_WRITE_INSERT:
+				/*
+				 * For WRITE_INSERT, force the
+				 * error to be sent on the wire. It should be
+				 * detected by the Target.
+				 */
+				phba->lpfc_injerr_wgrd_cnt--;
+				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
 
-			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-				"9080 BLKGRD: Injecting guard error: "
-				"write lba x%lx oldGuard x%x refTag x%x\n",
-				(unsigned long)lba, src->guard_tag,
-				src->ref_tag);
-
-			src->guard_tag = (uint16_t)new_guard;
-			phba->lpfc_injerr_wgrd_cnt--;
-			phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
-			rc = 1;
+				rc = BG_ERR_SWAP;
+				/* Signals the caller to swap CRC->CSUM */
+
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"0817 BLKGRD: Injecting guard error: "
+					"write lba x%lx\n", (unsigned long)lba);
+				break;
+			}
+		}
+		if (phba->lpfc_injerr_rgrd_cnt) {
+			switch (op) {
+			case SCSI_PROT_READ_INSERT:
+				/*
+				 * For READ_INSERT, it doesn't make sense
+				 * to change the guard tag.
+				 */
+				break;
+			case SCSI_PROT_READ_STRIP:
+			case SCSI_PROT_READ_PASS:
+				/*
+				 * For READ_STRIP and READ_PASS, force the
+				 * error on data being read off the wire. It
+				 * should force an IO error to the driver.
+				 */
+				*apptag = 0xDEAD;
+				phba->lpfc_injerr_rgrd_cnt--;
+				phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
+
+				rc = BG_ERR_SWAP;
+				/* Signals the caller to swap CRC->CSUM */
+
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"0818 BLKGRD: Injecting guard error: "
+					"read lba x%lx\n", (unsigned long)lba);
+			}
 		}
 	}
+
 	return rc;
 }
 #endif
 
-/*
- * Given a scsi cmnd, determine the BlockGuard opcodes to be used with it
+/**
+ * lpfc_sc_to_bg_opcodes - Determine the BlockGuard opcodes to be used with
+ * the specified SCSI command.
+ * @phba: The Hba for which this call is being executed.
  * @sc: The SCSI command to examine
  * @txopt: (out) BlockGuard operation for transmitted data
  * @rxopt: (out) BlockGuard operation for received data
  *
  * Returns: zero on success; non-zero if tx and/or rx op cannot be determined
  *
- */
+ **/
 static int
 lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		uint8_t *txop, uint8_t *rxop)
@@ -1519,8 +1687,88 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 	return ret;
 }
 
-/*
- * This function sets up buffer list for protection groups of
+#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+/**
+ * lpfc_bg_err_opcodes - reDetermine the BlockGuard opcodes to be used with
+ * the specified SCSI command in order to force a guard tag error.
+ * @phba: The Hba for which this call is being executed.
+ * @sc: The SCSI command to examine
+ * @txopt: (out) BlockGuard operation for transmitted data
+ * @rxopt: (out) BlockGuard operation for received data
+ *
+ * Returns: zero on success; non-zero if tx and/or rx op cannot be determined
+ *
+ **/
+static int
+lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
+		uint8_t *txop, uint8_t *rxop)
+{
+	uint8_t guard_type = scsi_host_get_guard(sc->device->host);
+	uint8_t ret = 0;
+
+	if (guard_type == SHOST_DIX_GUARD_IP) {
+		switch (scsi_get_prot_op(sc)) {
+		case SCSI_PROT_READ_INSERT:
+		case SCSI_PROT_WRITE_STRIP:
+			*txop = BG_OP_IN_CRC_OUT_NODIF;
+			*rxop = BG_OP_IN_NODIF_OUT_CRC;
+			break;
+
+		case SCSI_PROT_READ_STRIP:
+		case SCSI_PROT_WRITE_INSERT:
+			*txop = BG_OP_IN_NODIF_OUT_CSUM;
+			*rxop = BG_OP_IN_CSUM_OUT_NODIF;
+			break;
+
+		case SCSI_PROT_READ_PASS:
+		case SCSI_PROT_WRITE_PASS:
+			*txop = BG_OP_IN_CRC_OUT_CRC;
+			*rxop = BG_OP_IN_CRC_OUT_CRC;
+			break;
+
+		case SCSI_PROT_NORMAL:
+		default:
+			break;
+
+		}
+	} else {
+		switch (scsi_get_prot_op(sc)) {
+		case SCSI_PROT_READ_STRIP:
+		case SCSI_PROT_WRITE_INSERT:
+			*txop = BG_OP_IN_NODIF_OUT_CSUM;
+			*rxop = BG_OP_IN_CSUM_OUT_NODIF;
+			break;
+
+		case SCSI_PROT_READ_PASS:
+		case SCSI_PROT_WRITE_PASS:
+			*txop = BG_OP_IN_CSUM_OUT_CRC;
+			*rxop = BG_OP_IN_CRC_OUT_CSUM;
+			break;
+
+		case SCSI_PROT_READ_INSERT:
+		case SCSI_PROT_WRITE_STRIP:
+			*txop = BG_OP_IN_CSUM_OUT_NODIF;
+			*rxop = BG_OP_IN_NODIF_OUT_CSUM;
+			break;
+
+		case SCSI_PROT_NORMAL:
+		default:
+			break;
+		}
+	}
+
+	return ret;
+}
+#endif
+
+/**
+ * lpfc_bg_setup_bpl - Setup BlockGuard BPL with no protection data
+ * @phba: The Hba for which this call is being executed.
+ * @sc: pointer to scsi command we're working on
+ * @bpl: pointer to buffer list for protection groups
+ * @datacnt: number of segments of data that have been dma mapped
+ *
+ * This function sets up BPL buffer list for protection groups of
  * type LPFC_PG_TYPE_NO_DIF
  *
  * This is usually used when the HBA is instructed to generate
@@ -1539,12 +1787,11 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
  *                                |more Data BDE's ... (opt)|
  *                                +-------------------------+
  *
- * @sc: pointer to scsi command we're working on
- * @bpl: pointer to buffer list for protection groups
- * @datacnt: number of segments of data that have been dma mapped
  *
  * Note: Data s/g buffers have been dma mapped
- */
+ *
+ * Returns the number of BDEs added to the BPL.
+ **/
 static int
 lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		struct ulp_bde64 *bpl, int datasegcnt)
@@ -1555,6 +1802,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 	dma_addr_t physaddr;
 	int i = 0, num_bde = 0, status;
 	int datadir = sc->sc_data_direction;
+	uint32_t rc;
+	uint32_t checking = 1;
 	uint32_t reftag;
 	unsigned blksize;
 	uint8_t txop, rxop;
@@ -1565,11 +1814,16 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
 	/* extract some info from the scsi command for pde*/
 	blksize = lpfc_cmd_blksize(sc);
-	reftag = scsi_get_lba(sc) & 0xffffffff;
+	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
-	/* reftag is the only error we can inject here */
-	lpfc_bg_err_inject(phba, sc, &reftag, 0, 0);
+	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1);
+	if (rc) {
+		if (rc == BG_ERR_SWAP)
+			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop);
+		if (rc == BG_ERR_CHECK)
+			checking = 0;
+	}
 #endif
 
 	/* setup PDE5 with what we have */
@@ -1592,8 +1846,8 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 	bf_set(pde6_optx, pde6, txop);
 	bf_set(pde6_oprx, pde6, rxop);
 	if (datadir == DMA_FROM_DEVICE) {
-		bf_set(pde6_ce, pde6, 1);
-		bf_set(pde6_re, pde6, 1);
+		bf_set(pde6_ce, pde6, checking);
+		bf_set(pde6_re, pde6, checking);
 	}
 	bf_set(pde6_ai, pde6, 1);
 	bf_set(pde6_ae, pde6, 0);
@@ -1627,9 +1881,16 @@ out:
 	return num_bde;
 }
 
-/*
- * This function sets up buffer list for protection groups of
- * type LPFC_PG_TYPE_DIF_BUF
+/**
+ * lpfc_bg_setup_bpl_prot - Setup BlockGuard BPL with protection data
+ * @phba: The Hba for which this call is being executed.
+ * @sc: pointer to scsi command we're working on
+ * @bpl: pointer to buffer list for protection groups
+ * @datacnt: number of segments of data that have been dma mapped
+ * @protcnt: number of segment of protection data that have been dma mapped
+ *
+ * This function sets up BPL buffer list for protection groups of
+ * type LPFC_PG_TYPE_DIF
  *
  * This is usually used when DIFs are in their own buffers,
  * separate from the data. The HBA can then by instructed
@@ -1654,14 +1915,11 @@ out:
  *                                    |          ...            |
  *                                    +-------------------------+
  *
- * @sc: pointer to scsi command we're working on
- * @bpl: pointer to buffer list for protection groups
- * @datacnt: number of segments of data that have been dma mapped
- * @protcnt: number of segment of protection data that have been dma mapped
- *
  * Note: It is assumed that both data and protection s/g buffers have been
  *       mapped for DMA
- */
+ *
+ * Returns the number of BDEs added to the BPL.
+ **/
 static int
 lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		struct ulp_bde64 *bpl, int datacnt, int protcnt)
@@ -1681,6 +1939,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 	int datadir = sc->sc_data_direction;
 	unsigned char pgdone = 0, alldone = 0;
 	unsigned blksize;
+	uint32_t rc;
+	uint32_t checking = 1;
 	uint32_t reftag;
 	uint8_t txop, rxop;
 	int num_bde = 0;
@@ -1690,7 +1950,355 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
 	if (!sgpe || !sgde) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
-				"9020 Invalid s/g entry: data=0x%p prot=0x%p\n",
+				"9020 Invalid s/g entry: data=0x%p prot=0x%p\n",
+				sgpe, sgde);
+		return 0;
+	}
+
+	status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
+	if (status)
+		goto out;
+
+	/* extract some info from the scsi command */
+	blksize = lpfc_cmd_blksize(sc);
+	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */
+
+#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1);
+	if (rc) {
+		if (rc == BG_ERR_SWAP)
+			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop);
+		if (rc == BG_ERR_CHECK)
+			checking = 0;
+	}
+#endif
+
+	split_offset = 0;
+	do {
+		/* setup PDE5 with what we have */
+		pde5 = (struct lpfc_pde5 *) bpl;
+		memset(pde5, 0, sizeof(struct lpfc_pde5));
+		bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
+
+		/* Endianness conversion if necessary for PDE5 */
+		pde5->word0 = cpu_to_le32(pde5->word0);
+		pde5->reftag = cpu_to_le32(reftag);
+
+		/* advance bpl and increment bde count */
+		num_bde++;
+		bpl++;
+		pde6 = (struct lpfc_pde6 *) bpl;
+
+		/* setup PDE6 with the rest of the info */
+		memset(pde6, 0, sizeof(struct lpfc_pde6));
+		bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR);
+		bf_set(pde6_optx, pde6, txop);
+		bf_set(pde6_oprx, pde6, rxop);
+		bf_set(pde6_ce, pde6, checking);
+		bf_set(pde6_re, pde6, checking);
+		bf_set(pde6_ai, pde6, 1);
+		bf_set(pde6_ae, pde6, 0);
+		bf_set(pde6_apptagval, pde6, 0);
+
+		/* Endianness conversion if necessary for PDE6 */
+		pde6->word0 = cpu_to_le32(pde6->word0);
+		pde6->word1 = cpu_to_le32(pde6->word1);
+		pde6->word2 = cpu_to_le32(pde6->word2);
+
+		/* advance bpl and increment bde count */
+		num_bde++;
+		bpl++;
+
+		/* setup the first BDE that points to protection buffer */
+		protphysaddr = sg_dma_address(sgpe) + protgroup_offset;
+		protgroup_len = sg_dma_len(sgpe) - protgroup_offset;
+
+		/* must be integer multiple of the DIF block length */
+		BUG_ON(protgroup_len % 8);
+
+		pde7 = (struct lpfc_pde7 *) bpl;
+		memset(pde7, 0, sizeof(struct lpfc_pde7));
+		bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR);
+
+		pde7->addrHigh = le32_to_cpu(putPaddrHigh(protphysaddr));
+		pde7->addrLow = le32_to_cpu(putPaddrLow(protphysaddr));
+
+		protgrp_blks = protgroup_len / 8;
+		protgrp_bytes = protgrp_blks * blksize;
+
+		/* check if this pde is crossing the 4K boundary; if so split */
+		if ((pde7->addrLow & 0xfff) + protgroup_len > 0x1000) {
+			protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff);
+			protgroup_offset += protgroup_remainder;
+			protgrp_blks = protgroup_remainder / 8;
+			protgrp_bytes = protgrp_blks * blksize;
+		} else {
+			protgroup_offset = 0;
+			curr_prot++;
+		}
+
+		num_bde++;
+
+		/* setup BDE's for data blocks associated with DIF data */
+		pgdone = 0;
+		subtotal = 0; /* total bytes processed for current prot grp */
+		while (!pgdone) {
+			if (!sgde) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9065 BLKGRD:%s Invalid data segment\n",
+						__func__);
+				return 0;
+			}
+			bpl++;
+			dataphysaddr = sg_dma_address(sgde) + split_offset;
+			bpl->addrLow = le32_to_cpu(putPaddrLow(dataphysaddr));
+			bpl->addrHigh = le32_to_cpu(putPaddrHigh(dataphysaddr));
+
+			remainder = sg_dma_len(sgde) - split_offset;
+
+			if ((subtotal + remainder) <= protgrp_bytes) {
+				/* we can use this whole buffer */
+				bpl->tus.f.bdeSize = remainder;
+				split_offset = 0;
+
+				if ((subtotal + remainder) == protgrp_bytes)
+					pgdone = 1;
+			} else {
+				/* must split this buffer with next prot grp */
+				bpl->tus.f.bdeSize = protgrp_bytes - subtotal;
+				split_offset += bpl->tus.f.bdeSize;
+			}
+
+			subtotal += bpl->tus.f.bdeSize;
+
+			if (datadir == DMA_TO_DEVICE)
+				bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+			else
+				bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+			bpl->tus.w = le32_to_cpu(bpl->tus.w);
+
+			num_bde++;
+			curr_data++;
+
+			if (split_offset)
+				break;
+
+			/* Move to the next s/g segment if possible */
+			sgde = sg_next(sgde);
+
+		}
+
+		if (protgroup_offset) {
+			/* update the reference tag */
+			reftag += protgrp_blks;
+			bpl++;
+			continue;
+		}
+
+		/* are we done ? */
+		if (curr_prot == protcnt) {
+			alldone = 1;
+		} else if (curr_prot < protcnt) {
+			/* advance to next prot buffer */
+			sgpe = sg_next(sgpe);
+			bpl++;
+
+			/* update the reference tag */
+			reftag += protgrp_blks;
+		} else {
+			/* if we're here, we have a bug */
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+				"9054 BLKGRD: bug in %s\n", __func__);
+		}
+
+	} while (!alldone);
+out:
+
+	return num_bde;
+}
+
+/**
+ * lpfc_bg_setup_sgl - Setup BlockGuard SGL with no protection data
+ * @phba: The Hba for which this call is being executed.
+ * @sc: pointer to scsi command we're working on
+ * @sgl: pointer to buffer list for protection groups
+ * @datacnt: number of segments of data that have been dma mapped
+ *
+ * This function sets up SGL buffer list for protection groups of
+ * type LPFC_PG_TYPE_NO_DIF
+ *
+ * This is usually used when the HBA is instructed to generate
+ * DIFs and insert them into data stream (or strip DIF from
+ * incoming data stream)
+ *
+ * The buffer list consists of just one protection group described
+ * below:
+ *                                +-------------------------+
+ *   start of prot group  -->     |         DI_SEED         |
+ *                                +-------------------------+
+ *                                |         Data SGE        |
+ *                                +-------------------------+
+ *                                |more Data SGE's ... (opt)|
+ *                                +-------------------------+
+ *
+ *
+ * Note: Data s/g buffers have been dma mapped
+ *
+ * Returns the number of SGEs added to the SGL.
+ **/
+static int
+lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
+		struct sli4_sge *sgl, int datasegcnt)
+{
+	struct scatterlist *sgde = NULL; /* s/g data entry */
+	struct sli4_sge_diseed *diseed = NULL;
+	dma_addr_t physaddr;
+	int i = 0, num_sge = 0, status;
+	int datadir = sc->sc_data_direction;
+	uint32_t reftag;
+	unsigned blksize;
+	uint8_t txop, rxop;
+	uint32_t rc;
+	uint32_t checking = 1;
+	uint32_t dma_len;
+	uint32_t dma_offset = 0;
+
+	status  = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
+	if (status)
+		goto out;
+
+	/* extract some info from the scsi command for pde*/
+	blksize = lpfc_cmd_blksize(sc);
+	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */
+
+#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1);
+	if (rc) {
+		if (rc == BG_ERR_SWAP)
+			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop);
+		if (rc == BG_ERR_CHECK)
+			checking = 0;
+	}
+#endif
+
+	/* setup DISEED with what we have */
+	diseed = (struct sli4_sge_diseed *) sgl;
+	memset(diseed, 0, sizeof(struct sli4_sge_diseed));
+	bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DISEED);
+
+	/* Endianness conversion if necessary */
+	diseed->ref_tag = cpu_to_le32(reftag);
+	diseed->ref_tag_tran = diseed->ref_tag;
+
+	/* setup DISEED with the rest of the info */
+	bf_set(lpfc_sli4_sge_dif_optx, diseed, txop);
+	bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop);
+	if (datadir == DMA_FROM_DEVICE) {
+		bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
+		bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
+	}
+	bf_set(lpfc_sli4_sge_dif_ai, diseed, 1);
+	bf_set(lpfc_sli4_sge_dif_me, diseed, 0);
+
+	/* Endianness conversion if necessary for DISEED */
+	diseed->word2 = cpu_to_le32(diseed->word2);
+	diseed->word3 = cpu_to_le32(diseed->word3);
+
+	/* advance bpl and increment sge count */
+	num_sge++;
+	sgl++;
+
+	/* assumption: caller has already run dma_map_sg on command data */
+	scsi_for_each_sg(sc, sgde, datasegcnt, i) {
+		physaddr = sg_dma_address(sgde);
+		dma_len = sg_dma_len(sgde);
+		sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr));
+		sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr));
+		if ((i + 1) == datasegcnt)
+			bf_set(lpfc_sli4_sge_last, sgl, 1);
+		else
+			bf_set(lpfc_sli4_sge_last, sgl, 0);
+		bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
+		bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA);
+
+		sgl->sge_len = cpu_to_le32(dma_len);
+		dma_offset += dma_len;
+
+		sgl++;
+		num_sge++;
+	}
+
+out:
+	return num_sge;
+}
+
+/**
+ * lpfc_bg_setup_sgl_prot - Setup BlockGuard SGL with protection data
+ * @phba: The Hba for which this call is being executed.
+ * @sc: pointer to scsi command we're working on
+ * @sgl: pointer to buffer list for protection groups
+ * @datacnt: number of segments of data that have been dma mapped
+ * @protcnt: number of segment of protection data that have been dma mapped
+ *
+ * This function sets up SGL buffer list for protection groups of
+ * type LPFC_PG_TYPE_DIF
+ *
+ * This is usually used when DIFs are in their own buffers,
+ * separate from the data. The HBA can then by instructed
+ * to place the DIFs in the outgoing stream.  For read operations,
+ * The HBA could extract the DIFs and place it in DIF buffers.
+ *
+ * The buffer list for this type consists of one or more of the
+ * protection groups described below:
+ *                                    +-------------------------+
+ *   start of first prot group  -->   |         DISEED          |
+ *                                    +-------------------------+
+ *                                    |      DIF (Prot SGE)     |
+ *                                    +-------------------------+
+ *                                    |        Data SGE         |
+ *                                    +-------------------------+
+ *                                    |more Data SGE's ... (opt)|
+ *                                    +-------------------------+
+ *   start of new  prot group  -->    |         DISEED          |
+ *                                    +-------------------------+
+ *                                    |          ...            |
+ *                                    +-------------------------+
+ *
+ * Note: It is assumed that both data and protection s/g buffers have been
+ *       mapped for DMA
+ *
+ * Returns the number of SGEs added to the SGL.
+ **/
+static int
+lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
+		struct sli4_sge *sgl, int datacnt, int protcnt)
+{
+	struct scatterlist *sgde = NULL; /* s/g data entry */
+	struct scatterlist *sgpe = NULL; /* s/g prot entry */
+	struct sli4_sge_diseed *diseed = NULL;
+	dma_addr_t dataphysaddr, protphysaddr;
+	unsigned short curr_data = 0, curr_prot = 0;
+	unsigned int split_offset;
+	unsigned int protgroup_len, protgroup_offset = 0, protgroup_remainder;
+	unsigned int protgrp_blks, protgrp_bytes;
+	unsigned int remainder, subtotal;
+	int status;
+	unsigned char pgdone = 0, alldone = 0;
+	unsigned blksize;
+	uint32_t reftag;
+	uint8_t txop, rxop;
+	uint32_t dma_len;
+	uint32_t rc;
+	uint32_t checking = 1;
+	uint32_t dma_offset = 0;
+	int num_sge = 0;
+
+	sgpe = scsi_prot_sglist(sc);
+	sgde = scsi_sglist(sc);
+
+	if (!sgpe || !sgde) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+				"9082 Invalid s/g entry: data=0x%p prot=0x%p\n",
 				sgpe, sgde);
 		return 0;
 	}
@@ -1701,48 +2309,44 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
 	/* extract some info from the scsi command */
 	blksize = lpfc_cmd_blksize(sc);
-	reftag = scsi_get_lba(sc) & 0xffffffff;
+	reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */
 
 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS
-	/* reftag / guard tag are the only errors we can inject here */
-	lpfc_bg_err_inject(phba, sc, &reftag, 0, 0xDEAD);
+	rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1);
+	if (rc) {
+		if (rc == BG_ERR_SWAP)
+			lpfc_bg_err_opcodes(phba, sc, &txop, &rxop);
+		if (rc == BG_ERR_CHECK)
+			checking = 0;
+	}
 #endif
 
 	split_offset = 0;
 	do {
-		/* setup PDE5 with what we have */
-		pde5 = (struct lpfc_pde5 *) bpl;
-		memset(pde5, 0, sizeof(struct lpfc_pde5));
-		bf_set(pde5_type, pde5, LPFC_PDE5_DESCRIPTOR);
-
-		/* Endianness conversion if necessary for PDE5 */
-		pde5->word0 = cpu_to_le32(pde5->word0);
-		pde5->reftag = cpu_to_le32(reftag);
-
-		/* advance bpl and increment bde count */
-		num_bde++;
-		bpl++;
-		pde6 = (struct lpfc_pde6 *) bpl;
-
-		/* setup PDE6 with the rest of the info */
-		memset(pde6, 0, sizeof(struct lpfc_pde6));
-		bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR);
-		bf_set(pde6_optx, pde6, txop);
-		bf_set(pde6_oprx, pde6, rxop);
-		bf_set(pde6_ce, pde6, 1);
-		bf_set(pde6_re, pde6, 1);
-		bf_set(pde6_ai, pde6, 1);
-		bf_set(pde6_ae, pde6, 0);
-		bf_set(pde6_apptagval, pde6, 0);
-
-		/* Endianness conversion if necessary for PDE6 */
-		pde6->word0 = cpu_to_le32(pde6->word0);
-		pde6->word1 = cpu_to_le32(pde6->word1);
-		pde6->word2 = cpu_to_le32(pde6->word2);
-
-		/* advance bpl and increment bde count */
-		num_bde++;
-		bpl++;
+		/* setup DISEED with what we have */
+		diseed = (struct sli4_sge_diseed *) sgl;
+		memset(diseed, 0, sizeof(struct sli4_sge_diseed));
+		bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DISEED);
+
+		/* Endianness conversion if necessary */
+		diseed->ref_tag = cpu_to_le32(reftag);
+		diseed->ref_tag_tran = diseed->ref_tag;
+
+		/* setup DISEED with the rest of the info */
+		bf_set(lpfc_sli4_sge_dif_optx, diseed, txop);
+		bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop);
+		bf_set(lpfc_sli4_sge_dif_ce, diseed, checking);
+		bf_set(lpfc_sli4_sge_dif_re, diseed, checking);
+		bf_set(lpfc_sli4_sge_dif_ai, diseed, 1);
+		bf_set(lpfc_sli4_sge_dif_me, diseed, 0);
+
+		/* Endianness conversion if necessary for DISEED */
+		diseed->word2 = cpu_to_le32(diseed->word2);
+		diseed->word3 = cpu_to_le32(diseed->word3);
+
+		/* advance sgl and increment bde count */
+		num_sge++;
+		sgl++;
 
 		/* setup the first BDE that points to protection buffer */
 		protphysaddr = sg_dma_address(sgpe) + protgroup_offset;
@@ -1751,19 +2355,19 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 		/* must be integer multiple of the DIF block length */
 		BUG_ON(protgroup_len % 8);
 
-		pde7 = (struct lpfc_pde7 *) bpl;
-		memset(pde7, 0, sizeof(struct lpfc_pde7));
-		bf_set(pde7_type, pde7, LPFC_PDE7_DESCRIPTOR);
-
-		pde7->addrHigh = le32_to_cpu(putPaddrHigh(protphysaddr));
-		pde7->addrLow = le32_to_cpu(putPaddrLow(protphysaddr));
+		/* Now setup DIF SGE */
+		sgl->word2 = 0;
+		bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DIF);
+		sgl->addr_hi = le32_to_cpu(putPaddrHigh(protphysaddr));
+		sgl->addr_lo = le32_to_cpu(putPaddrLow(protphysaddr));
+		sgl->word2 = cpu_to_le32(sgl->word2);
 
 		protgrp_blks = protgroup_len / 8;
 		protgrp_bytes = protgrp_blks * blksize;
 
-		/* check if this pde is crossing the 4K boundary; if so split */
-		if ((pde7->addrLow & 0xfff) + protgroup_len > 0x1000) {
-			protgroup_remainder = 0x1000 - (pde7->addrLow & 0xfff);
+		/* check if DIF SGE is crossing the 4K boundary; if so split */
+		if ((sgl->addr_lo & 0xfff) + protgroup_len > 0x1000) {
+			protgroup_remainder = 0x1000 - (sgl->addr_lo & 0xfff);
 			protgroup_offset += protgroup_remainder;
 			protgrp_blks = protgroup_remainder / 8;
 			protgrp_bytes = protgrp_blks * blksize;
@@ -1772,47 +2376,48 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 			curr_prot++;
 		}
 
-		num_bde++;
+		num_sge++;
 
-		/* setup BDE's for data blocks associated with DIF data */
+		/* setup SGE's for data blocks associated with DIF data */
 		pgdone = 0;
 		subtotal = 0; /* total bytes processed for current prot grp */
 		while (!pgdone) {
 			if (!sgde) {
 				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-					"9065 BLKGRD:%s Invalid data segment\n",
+					"9086 BLKGRD:%s Invalid data segment\n",
 						__func__);
 				return 0;
 			}
-			bpl++;
+			sgl++;
 			dataphysaddr = sg_dma_address(sgde) + split_offset;
-			bpl->addrLow = le32_to_cpu(putPaddrLow(dataphysaddr));
-			bpl->addrHigh = le32_to_cpu(putPaddrHigh(dataphysaddr));
 
 			remainder = sg_dma_len(sgde) - split_offset;
 
 			if ((subtotal + remainder) <= protgrp_bytes) {
 				/* we can use this whole buffer */
-				bpl->tus.f.bdeSize = remainder;
+				dma_len = remainder;
 				split_offset = 0;
 
 				if ((subtotal + remainder) == protgrp_bytes)
 					pgdone = 1;
 			} else {
 				/* must split this buffer with next prot grp */
-				bpl->tus.f.bdeSize = protgrp_bytes - subtotal;
-				split_offset += bpl->tus.f.bdeSize;
+				dma_len = protgrp_bytes - subtotal;
+				split_offset += dma_len;
 			}
 
-			subtotal += bpl->tus.f.bdeSize;
+			subtotal += dma_len;
 
-			if (datadir == DMA_TO_DEVICE)
-				bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
-			else
-				bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
-			bpl->tus.w = le32_to_cpu(bpl->tus.w);
+			sgl->addr_lo = cpu_to_le32(putPaddrLow(dataphysaddr));
+			sgl->addr_hi = cpu_to_le32(putPaddrHigh(dataphysaddr));
+			bf_set(lpfc_sli4_sge_last, sgl, 0);
+			bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
+			bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA);
 
-			num_bde++;
+			sgl->sge_len = cpu_to_le32(dma_len);
+			dma_offset += dma_len;
+
+			num_sge++;
 			curr_data++;
 
 			if (split_offset)
@@ -1820,45 +2425,50 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
 
 			/* Move to the next s/g segment if possible */
 			sgde = sg_next(sgde);
-
 		}
 
 		if (protgroup_offset) {
 			/* update the reference tag */
 			reftag += protgrp_blks;
-			bpl++;
+			sgl++;
 			continue;
 		}
 
 		/* are we done ? */
 		if (curr_prot == protcnt) {
+			bf_set(lpfc_sli4_sge_last, sgl, 1);
 			alldone = 1;
 		} else if (curr_prot < protcnt) {
 			/* advance to next prot buffer */
 			sgpe = sg_next(sgpe);
-			bpl++;
+			sgl++;
 
 			/* update the reference tag */
 			reftag += protgrp_blks;
 		} else {
 			/* if we're here, we have a bug */
 			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
-				"9054 BLKGRD: bug in %s\n", __func__);
+				"9085 BLKGRD: bug in %s\n", __func__);
 		}
 
 	} while (!alldone);
+
 out:
 
-	return num_bde;
+	return num_sge;
 }
 
-/*
+/**
+ * lpfc_prot_group_type - Get prtotection group type of SCSI command
+ * @phba: The Hba for which this call is being executed.
+ * @sc: pointer to scsi command we're working on
+ *
  * Given a SCSI command that supports DIF, determine composition of protection
  * groups involved in setting up buffer lists
  *
- * Returns:
- *			      for DIF (for both read and write)
- * */
+ * Returns: Protection group type (with or without DIF)
+ *
+ **/
 static int
 lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc)
 {
@@ -1885,13 +2495,17 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc)
 	return ret;
 }
 
-/*
+/**
+ * lpfc_bg_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec
+ * @phba: The Hba for which this call is being executed.
+ * @lpfc_cmd: The scsi buffer which is going to be prep'ed.
+ *
  * This is the protection/DIF aware version of
  * lpfc_scsi_prep_dma_buf(). It may be a good idea to combine the
  * two functions eventually, but for now, it's here
- */
+ **/
 static int
-lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba,
+lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba,
 		struct lpfc_scsi_buf *lpfc_cmd)
 {
 	struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
@@ -2147,7 +2761,21 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
 		cmd->sense_buffer[8] = 0;     /* Information descriptor type */
 		cmd->sense_buffer[9] = 0xa;   /* Additional descriptor length */
 		cmd->sense_buffer[10] = 0x80; /* Validity bit */
-		bghm /= cmd->device->sector_size;
+
+		/* bghm is a "on the wire" FC frame based count */
+		switch (scsi_get_prot_op(cmd)) {
+		case SCSI_PROT_READ_INSERT:
+		case SCSI_PROT_WRITE_STRIP:
+			bghm /= cmd->device->sector_size;
+			break;
+		case SCSI_PROT_READ_STRIP:
+		case SCSI_PROT_WRITE_INSERT:
+		case SCSI_PROT_READ_PASS:
+		case SCSI_PROT_WRITE_PASS:
+			bghm /= (cmd->device->sector_size +
+				sizeof(struct scsi_dif_tuple));
+			break;
+		}
 
 		failing_sector = scsi_get_lba(cmd);
 		failing_sector += bghm;
@@ -2292,6 +2920,180 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
 }
 
 /**
+ * lpfc_bg_scsi_adjust_dl - Adjust SCSI data length for BlockGuard
+ * @phba: The Hba for which this call is being executed.
+ * @lpfc_cmd: The scsi buffer which is going to be adjusted.
+ *
+ * Adjust the data length to account for how much data
+ * is actually on the wire.
+ *
+ * returns the adjusted data length
+ **/
+static int
+lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba,
+		struct lpfc_scsi_buf *lpfc_cmd)
+{
+	struct scsi_cmnd *sc = lpfc_cmd->pCmd;
+	int diflen, fcpdl;
+	unsigned blksize;
+
+	fcpdl = scsi_bufflen(sc);
+
+	/* Check if there is protection data on the wire */
+	if (sc->sc_data_direction == DMA_FROM_DEVICE) {
+		/* Read */
+		if (scsi_get_prot_op(sc) ==  SCSI_PROT_READ_INSERT)
+			return fcpdl;
+
+	} else {
+		/* Write */
+		if (scsi_get_prot_op(sc) ==  SCSI_PROT_WRITE_STRIP)
+			return fcpdl;
+	}
+
+	/* If protection data on the wire, adjust the count accordingly */
+	blksize = lpfc_cmd_blksize(sc);
+	diflen = (fcpdl / blksize) * 8;
+	fcpdl += diflen;
+	return fcpdl;
+}
+
+/**
+ * lpfc_bg_scsi_prep_dma_buf_s4 - DMA mapping for scsi buffer to SLI4 IF spec
+ * @phba: The Hba for which this call is being executed.
+ * @lpfc_cmd: The scsi buffer which is going to be mapped.
+ *
+ * This is the protection/DIF aware version of
+ * lpfc_scsi_prep_dma_buf(). It may be a good idea to combine the
+ * two functions eventually, but for now, it's here
+ **/
+static int
+lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba,
+		struct lpfc_scsi_buf *lpfc_cmd)
+{
+	struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
+	struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
+	struct sli4_sge *sgl = (struct sli4_sge *)(lpfc_cmd->fcp_bpl);
+	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
+	uint32_t num_bde = 0;
+	int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction;
+	int prot_group_type = 0;
+	int fcpdl;
+
+	/*
+	 * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd
+	 *  fcp_rsp regions to the first data bde entry
+	 */
+	if (scsi_sg_count(scsi_cmnd)) {
+		/*
+		 * The driver stores the segment count returned from pci_map_sg
+		 * because this a count of dma-mappings used to map the use_sg
+		 * pages.  They are not guaranteed to be the same for those
+		 * architectures that implement an IOMMU.
+		 */
+		datasegcnt = dma_map_sg(&phba->pcidev->dev,
+					scsi_sglist(scsi_cmnd),
+					scsi_sg_count(scsi_cmnd), datadir);
+		if (unlikely(!datasegcnt))
+			return 1;
+
+		sgl += 1;
+		/* clear the last flag in the fcp_rsp map entry */
+		sgl->word2 = le32_to_cpu(sgl->word2);
+		bf_set(lpfc_sli4_sge_last, sgl, 0);
+		sgl->word2 = cpu_to_le32(sgl->word2);
+
+		sgl += 1;
+		lpfc_cmd->seg_cnt = datasegcnt;
+		if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9087 BLKGRD: %s: Too many sg segments"
+					" from dma_map_sg.  Config %d, seg_cnt"
+					" %d\n",
+					__func__, phba->cfg_sg_seg_cnt,
+					lpfc_cmd->seg_cnt);
+			scsi_dma_unmap(scsi_cmnd);
+			return 1;
+		}
+
+		prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd);
+
+		switch (prot_group_type) {
+		case LPFC_PG_TYPE_NO_DIF:
+			num_bde = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl,
+					datasegcnt);
+			/* we should have 2 or more entries in buffer list */
+			if (num_bde < 2)
+				goto err;
+			break;
+		case LPFC_PG_TYPE_DIF_BUF:{
+			/*
+			 * This type indicates that protection buffers are
+			 * passed to the driver, so that needs to be prepared
+			 * for DMA
+			 */
+			protsegcnt = dma_map_sg(&phba->pcidev->dev,
+					scsi_prot_sglist(scsi_cmnd),
+					scsi_prot_sg_count(scsi_cmnd), datadir);
+			if (unlikely(!protsegcnt)) {
+				scsi_dma_unmap(scsi_cmnd);
+				return 1;
+			}
+
+			lpfc_cmd->prot_seg_cnt = protsegcnt;
+			if (lpfc_cmd->prot_seg_cnt
+			    > phba->cfg_prot_sg_seg_cnt) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_BG,
+					"9088 BLKGRD: %s: Too many prot sg "
+					"segments from dma_map_sg.  Config %d,"
+						"prot_seg_cnt %d\n", __func__,
+						phba->cfg_prot_sg_seg_cnt,
+						lpfc_cmd->prot_seg_cnt);
+				dma_unmap_sg(&phba->pcidev->dev,
+					     scsi_prot_sglist(scsi_cmnd),
+					     scsi_prot_sg_count(scsi_cmnd),
+					     datadir);
+				scsi_dma_unmap(scsi_cmnd);
+				return 1;
+			}
+
+			num_bde = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl,
+					datasegcnt, protsegcnt);
+			/* we should have 3 or more entries in buffer list */
+			if (num_bde < 3)
+				goto err;
+			break;
+		}
+		case LPFC_PG_TYPE_INVALID:
+		default:
+			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+					"9083 Unexpected protection group %i\n",
+					prot_group_type);
+			return 1;
+		}
+	}
+
+	fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd);
+
+	fcp_cmnd->fcpDl = be32_to_cpu(fcpdl);
+
+	/*
+	 * Due to difference in data length between DIF/non-DIF paths,
+	 * we need to set word 4 of IOCB here
+	 */
+	iocb_cmd->un.fcpi.fcpi_parm = fcpdl;
+	lpfc_cmd->cur_iocbq.iocb_flag |= LPFC_IO_DIF;
+
+	return 0;
+err:
+	lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+			"9084 Could not setup all needed BDE's"
+			"prot_group_type=%d, num_bde=%d\n",
+			prot_group_type, num_bde);
+	return 1;
+}
+
+/**
  * lpfc_scsi_prep_dma_buf - Wrapper function for DMA mapping of scsi buffer
  * @phba: The Hba for which this call is being executed.
  * @lpfc_cmd: The scsi buffer which is going to be mapped.
@@ -2310,6 +3112,25 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
 }
 
 /**
+ * lpfc_bg_scsi_prep_dma_buf - Wrapper function for DMA mapping of scsi buffer
+ * using BlockGuard.
+ * @phba: The Hba for which this call is being executed.
+ * @lpfc_cmd: The scsi buffer which is going to be mapped.
+ *
+ * This routine wraps the actual DMA mapping function pointer from the
+ * lpfc_hba struct.
+ *
+ * Return codes:
+ *	1 - Error
+ *	0 - Success
+ **/
+static inline int
+lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
+{
+	return phba->lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);
+}
+
+/**
  * lpfc_send_scsi_error_event - Posts an event when there is SCSI error
  * @phba: Pointer to hba context object.
  * @vport: Pointer to vport object.
@@ -3072,12 +3893,14 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
 	case LPFC_PCI_DEV_LP:
 		phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3;
 		phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3;
+		phba->lpfc_bg_scsi_prep_dma_buf = lpfc_bg_scsi_prep_dma_buf_s3;
 		phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3;
 		phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s3;
 		break;
 	case LPFC_PCI_DEV_OC:
 		phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4;
 		phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4;
+		phba->lpfc_bg_scsi_prep_dma_buf = lpfc_bg_scsi_prep_dma_buf_s4;
 		phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4;
 		phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf_s4;
 		break;
@@ -3250,8 +4073,7 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 	ndlp = rdata->pnode;
 
 	if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) &&
-		(!(phba->sli3_options & LPFC_SLI3_BG_ENABLED) ||
-		(phba->sli_rev == LPFC_SLI_REV4))) {
+		(!(phba->sli3_options & LPFC_SLI3_BG_ENABLED))) {
 
 		lpfc_printf_log(phba, KERN_ERR, LOG_BG,
 				"9058 BLKGRD: ERROR: rcvd protected cmd:%02x"
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 23a2759..e0e4d8d 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -293,7 +293,9 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm)
 	}
 	bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released);
 	bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT);
-	bf_set(lpfc_eqcq_doorbell_eqid, &doorbell, q->queue_id);
+	bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell,
+			(q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT));
+	bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id);
 	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
 	/* PCI read to flush PCI pipeline on re-arming for INTx mode */
 	if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM))
@@ -372,7 +374,9 @@ lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm)
 		bf_set(lpfc_eqcq_doorbell_arm, &doorbell, 1);
 	bf_set(lpfc_eqcq_doorbell_num_released, &doorbell, released);
 	bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_COMPLETION);
-	bf_set(lpfc_eqcq_doorbell_cqid, &doorbell, q->queue_id);
+	bf_set(lpfc_eqcq_doorbell_cqid_hi, &doorbell,
+			(q->queue_id >> LPFC_CQID_HI_FIELD_SHIFT));
+	bf_set(lpfc_eqcq_doorbell_cqid_lo, &doorbell, q->queue_id);
 	writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr);
 	return released;
 }
@@ -554,81 +558,6 @@ __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
 }
 
 /**
- * __lpfc_set_rrq_active - set RRQ active bit in the ndlp's xri_bitmap.
- * @phba: Pointer to HBA context object.
- * @ndlp: nodelist pointer for this target.
- * @xritag: xri used in this exchange.
- * @rxid: Remote Exchange ID.
- * @send_rrq: Flag used to determine if we should send rrq els cmd.
- *
- * This function is called with hbalock held.
- * The active bit is set in the ndlp's active rrq xri_bitmap. Allocates an
- * rrq struct and adds it to the active_rrq_list.
- *
- * returns  0 for rrq slot for this xri
- *         < 0  Were not able to get rrq mem or invalid parameter.
- **/
-static int
-__lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
-		uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
-{
-	struct lpfc_node_rrq *rrq;
-	int empty;
-	uint32_t did = 0;
-
-
-	if (!ndlp)
-		return -EINVAL;
-
-	if (!phba->cfg_enable_rrq)
-		return -EINVAL;
-
-	if (phba->pport->load_flag & FC_UNLOADING) {
-		phba->hba_flag &= ~HBA_RRQ_ACTIVE;
-		goto out;
-	}
-	did = ndlp->nlp_DID;
-
-	/*
-	 * set the active bit even if there is no mem available.
-	 */
-	if (NLP_CHK_FREE_REQ(ndlp))
-		goto out;
-
-	if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING))
-		goto out;
-
-	if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap))
-		goto out;
-
-	rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
-	if (rrq) {
-		rrq->send_rrq = send_rrq;
-		rrq->xritag = xritag;
-		rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
-		rrq->ndlp = ndlp;
-		rrq->nlp_DID = ndlp->nlp_DID;
-		rrq->vport = ndlp->vport;
-		rrq->rxid = rxid;
-		empty = list_empty(&phba->active_rrq_list);
-		rrq->send_rrq = send_rrq;
-		list_add_tail(&rrq->list, &phba->active_rrq_list);
-		if (!(phba->hba_flag & HBA_RRQ_ACTIVE)) {
-			phba->hba_flag |= HBA_RRQ_ACTIVE;
-			if (empty)
-				lpfc_worker_wake_up(phba);
-		}
-		return 0;
-	}
-out:
-	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-			"2921 Can't set rrq active xri:0x%x rxid:0x%x"
-			" DID:0x%x Send:%d\n",
-			xritag, rxid, did, send_rrq);
-	return -EINVAL;
-}
-
-/**
  * lpfc_clr_rrq_active - Clears RRQ active bit in xri_bitmap.
  * @phba: Pointer to HBA context object.
  * @xritag: xri used in this exchange.
@@ -856,15 +785,68 @@ lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
  **/
 int
 lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
-			uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
+		    uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
 {
-	int ret;
 	unsigned long iflags;
+	struct lpfc_node_rrq *rrq;
+	int empty;
+
+	if (!ndlp)
+		return -EINVAL;
+
+	if (!phba->cfg_enable_rrq)
+		return -EINVAL;
 
 	spin_lock_irqsave(&phba->hbalock, iflags);
-	ret = __lpfc_set_rrq_active(phba, ndlp, xritag, rxid, send_rrq);
+	if (phba->pport->load_flag & FC_UNLOADING) {
+		phba->hba_flag &= ~HBA_RRQ_ACTIVE;
+		goto out;
+	}
+
+	/*
+	 * set the active bit even if there is no mem available.
+	 */
+	if (NLP_CHK_FREE_REQ(ndlp))
+		goto out;
+
+	if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING))
+		goto out;
+
+	if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap))
+		goto out;
+
 	spin_unlock_irqrestore(&phba->hbalock, iflags);
-	return ret;
+	rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
+	if (!rrq) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+				"3155 Unable to allocate RRQ xri:0x%x rxid:0x%x"
+				" DID:0x%x Send:%d\n",
+				xritag, rxid, ndlp->nlp_DID, send_rrq);
+		return -EINVAL;
+	}
+	rrq->send_rrq = send_rrq;
+	rrq->xritag = xritag;
+	rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
+	rrq->ndlp = ndlp;
+	rrq->nlp_DID = ndlp->nlp_DID;
+	rrq->vport = ndlp->vport;
+	rrq->rxid = rxid;
+	rrq->send_rrq = send_rrq;
+	spin_lock_irqsave(&phba->hbalock, iflags);
+	empty = list_empty(&phba->active_rrq_list);
+	list_add_tail(&rrq->list, &phba->active_rrq_list);
+	phba->hba_flag |= HBA_RRQ_ACTIVE;
+	if (empty)
+		lpfc_worker_wake_up(phba);
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+	return 0;
+out:
+	spin_unlock_irqrestore(&phba->hbalock, iflags);
+	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+			"2921 Can't set rrq active xri:0x%x rxid:0x%x"
+			" DID:0x%x Send:%d\n",
+			xritag, rxid, ndlp->nlp_DID, send_rrq);
+	return -EINVAL;
 }
 
 /**
@@ -5596,6 +5578,8 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba)
 		for (i = 0; i < count; i++)
 			phba->sli4_hba.rpi_ids[i] = base + i;
 
+		lpfc_sli4_node_prep(phba);
+
 		/* VPIs. */
 		count = phba->sli4_hba.max_cfg_param.max_vpi;
 		base = phba->sli4_hba.max_cfg_param.vpi_base;
@@ -7555,6 +7539,8 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
 
 	sgl  = (struct sli4_sge *)sglq->sgl;
 	icmd = &piocbq->iocb;
+	if (icmd->ulpCommand == CMD_XMIT_BLS_RSP64_CX)
+		return sglq->sli4_xritag;
 	if (icmd->un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
 		numBdes = icmd->un.genreq64.bdl.bdeSize /
 				sizeof(struct ulp_bde64);
@@ -7756,6 +7742,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 			if (pcmd && (*pcmd == ELS_CMD_FLOGI ||
 				*pcmd == ELS_CMD_SCR ||
+				*pcmd == ELS_CMD_FDISC ||
 				*pcmd == ELS_CMD_PLOGI)) {
 				bf_set(els_req64_sp, &wqe->els_req, 1);
 				bf_set(els_req64_sid, &wqe->els_req,
@@ -7763,7 +7750,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 				bf_set(wqe_ct, &wqe->els_req.wqe_com, 1);
 				bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
 					phba->vpi_ids[phba->pport->vpi]);
-			} else if (iocbq->context1) {
+			} else if (pcmd && iocbq->context1) {
 				bf_set(wqe_ct, &wqe->els_req.wqe_com, 0);
 				bf_set(wqe_ctxt_tag, &wqe->els_req.wqe_com,
 					phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
@@ -7830,12 +7817,16 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS);
 		/* Always open the exchange */
 		bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0);
-		bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1);
 		bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE);
 		bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com,
 		       LPFC_WQE_LENLOC_WORD4);
 		bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0);
 		bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU);
+		if (iocbq->iocb_flag & LPFC_IO_DIF) {
+			iocbq->iocb_flag &= ~LPFC_IO_DIF;
+			bf_set(wqe_dif, &wqe->generic.wqe_com, 1);
+		}
+		bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1);
 		break;
 	case CMD_FCP_IREAD64_CR:
 		/* word3 iocb=iotag wqe=payload_offset_len */
@@ -7849,12 +7840,16 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS);
 		/* Always open the exchange */
 		bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0);
-		bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1);
 		bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ);
 		bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com,
 		       LPFC_WQE_LENLOC_WORD4);
 		bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0);
 		bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU);
+		if (iocbq->iocb_flag & LPFC_IO_DIF) {
+			iocbq->iocb_flag &= ~LPFC_IO_DIF;
+			bf_set(wqe_dif, &wqe->generic.wqe_com, 1);
+		}
+		bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1);
 		break;
 	case CMD_FCP_ICMND64_CR:
 		/* word3 iocb=IO_TAG wqe=reserved */
@@ -7982,6 +7977,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		xritag = 0;
 		break;
 	case CMD_XMIT_BLS_RSP64_CX:
+		ndlp = (struct lpfc_nodelist *)iocbq->context1;
 		/* As BLS ABTS RSP WQE is very different from other WQEs,
 		 * we re-construct this WQE here based on information in
 		 * iocbq from scratch.
@@ -8008,8 +8004,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
 		}
 		bf_set(xmit_bls_rsp64_seqcnthi, &wqe->xmit_bls_rsp, 0xffff);
 		bf_set(wqe_xmit_bls_pt, &wqe->xmit_bls_rsp.wqe_dest, 0x1);
+
+		/* Use CT=VPI */
+		bf_set(wqe_els_did, &wqe->xmit_bls_rsp.wqe_dest,
+			ndlp->nlp_DID);
+		bf_set(xmit_bls_rsp64_temprpi, &wqe->xmit_bls_rsp,
+			iocbq->iocb.ulpContext);
+		bf_set(wqe_ct, &wqe->xmit_bls_rsp.wqe_com, 1);
 		bf_set(wqe_ctxt_tag, &wqe->xmit_bls_rsp.wqe_com,
-		       iocbq->iocb.ulpContext);
+			phba->vpi_ids[phba->pport->vpi]);
 		bf_set(wqe_qosd, &wqe->xmit_bls_rsp.wqe_com, 1);
 		bf_set(wqe_lenloc, &wqe->xmit_bls_rsp.wqe_com,
 		       LPFC_WQE_LENLOC_NONE);
@@ -8073,8 +8076,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
 
 	if (piocb->sli4_xritag == NO_XRI) {
 		if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
-		    piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN ||
-		    piocb->iocb.ulpCommand == CMD_XMIT_BLS_RSP64_CX)
+		    piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
 			sglq = NULL;
 		else {
 			if (pring->txq_cnt) {
@@ -8384,10 +8386,13 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba,
 {
 	struct lpfc_vport *vport;
 
-	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
 		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
 				"3115 Node Context not found, driver "
 				"ignoring abts err event\n");
+		return;
+	}
+
 	vport = ndlp->vport;
 	lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
 			"3116 Port generated FCP XRI ABORT event on "
@@ -10653,12 +10658,14 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
 			      struct lpfc_wcqe_complete *wcqe)
 {
 	unsigned long iflags;
+	uint32_t status;
 	size_t offset = offsetof(struct lpfc_iocbq, iocb);
 
 	memcpy((char *)pIocbIn + offset, (char *)pIocbOut + offset,
 	       sizeof(struct lpfc_iocbq) - offset);
 	/* Map WCQE parameters into irspiocb parameters */
-	pIocbIn->iocb.ulpStatus = bf_get(lpfc_wcqe_c_status, wcqe);
+	status = bf_get(lpfc_wcqe_c_status, wcqe);
+	pIocbIn->iocb.ulpStatus = (status & LPFC_IOCB_STATUS_MASK);
 	if (pIocbOut->iocb_flag & LPFC_IO_FCP)
 		if (pIocbIn->iocb.ulpStatus == IOSTAT_FCP_RSP_ERROR)
 			pIocbIn->iocb.un.fcpi.fcpi_parm =
@@ -10671,6 +10678,44 @@ lpfc_sli4_iocb_param_transfer(struct lpfc_hba *phba,
 		pIocbIn->iocb.un.genreq64.bdl.bdeSize = wcqe->total_data_placed;
 	}
 
+	/* Convert BG errors for completion status */
+	if (status == CQE_STATUS_DI_ERROR) {
+		pIocbIn->iocb.ulpStatus = IOSTAT_LOCAL_REJECT;
+
+		if (bf_get(lpfc_wcqe_c_bg_edir, wcqe))
+			pIocbIn->iocb.un.ulpWord[4] = IOERR_RX_DMA_FAILED;
+		else
+			pIocbIn->iocb.un.ulpWord[4] = IOERR_TX_DMA_FAILED;
+
+		pIocbIn->iocb.unsli3.sli3_bg.bgstat = 0;
+		if (bf_get(lpfc_wcqe_c_bg_ge, wcqe)) /* Guard Check failed */
+			pIocbIn->iocb.unsli3.sli3_bg.bgstat |=
+				BGS_GUARD_ERR_MASK;
+		if (bf_get(lpfc_wcqe_c_bg_ae, wcqe)) /* App Tag Check failed */
+			pIocbIn->iocb.unsli3.sli3_bg.bgstat |=
+				BGS_APPTAG_ERR_MASK;
+		if (bf_get(lpfc_wcqe_c_bg_re, wcqe)) /* Ref Tag Check failed */
+			pIocbIn->iocb.unsli3.sli3_bg.bgstat |=
+				BGS_REFTAG_ERR_MASK;
+
+		/* Check to see if there was any good data before the error */
+		if (bf_get(lpfc_wcqe_c_bg_tdpv, wcqe)) {
+			pIocbIn->iocb.unsli3.sli3_bg.bgstat |=
+				BGS_HI_WATER_MARK_PRESENT_MASK;
+			pIocbIn->iocb.unsli3.sli3_bg.bghm =
+				wcqe->total_data_placed;
+		}
+
+		/*
+		* Set ALL the error bits to indicate we don't know what
+		* type of error it is.
+		*/
+		if (!pIocbIn->iocb.unsli3.sli3_bg.bgstat)
+			pIocbIn->iocb.unsli3.sli3_bg.bgstat |=
+				(BGS_REFTAG_ERR_MASK | BGS_APPTAG_ERR_MASK |
+				BGS_GUARD_ERR_MASK);
+	}
+
 	/* Pick up HBA exchange busy condition */
 	if (bf_get(lpfc_wcqe_c_xb, wcqe)) {
 		spin_lock_irqsave(&phba->hbalock, iflags);
@@ -14042,6 +14087,13 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba,
 {
 	if (cmd_iocbq)
 		lpfc_sli_release_iocbq(phba, cmd_iocbq);
+
+	/* Failure means BLS ABORT RSP did not get delivered to remote node*/
+	if (rsp_iocbq && rsp_iocbq->iocb.ulpStatus)
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+			"3154 BLS ABORT RSP failed, data:  x%x/x%x\n",
+			rsp_iocbq->iocb.ulpStatus,
+			rsp_iocbq->iocb.un.ulpWord[4]);
 }
 
 /**
@@ -14748,7 +14800,8 @@ lpfc_sli4_remove_rpis(struct lpfc_hba *phba)
  * provided rpi via a bitmask.
  **/
 int
-lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp)
+lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp,
+	void (*cmpl)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *arg)
 {
 	LPFC_MBOXQ_t *mboxq;
 	struct lpfc_hba *phba = ndlp->phba;
@@ -14761,6 +14814,13 @@ lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp)
 
 	/* Post all rpi memory regions to the port. */
 	lpfc_resume_rpi(mboxq, ndlp);
+	if (cmpl) {
+		mboxq->mbox_cmpl = cmpl;
+		mboxq->context1 = arg;
+		mboxq->context2 = ndlp;
+	} else
+		mboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+	mboxq->vport = ndlp->vport;
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
 	if (rc == MBX_NOT_FINISHED) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 29c13b6..3290b8e 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -69,6 +69,7 @@ struct lpfc_iocbq {
 #define LPFC_USE_FCPWQIDX	0x80    /* Submit to specified FCPWQ index */
 #define DSS_SECURITY_OP		0x100	/* security IO */
 #define LPFC_IO_ON_Q		0x200	/* The IO is still on the TXCMPLQ */
+#define LPFC_IO_DIF		0x400	/* T10 DIF IO */
 
 #define LPFC_FIP_ELS_ID_MASK	0xc000	/* ELS_ID range 0-3, non-shifted mask */
 #define LPFC_FIP_ELS_ID_SHIFT	14
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 3f266e2..c19d139 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -633,7 +633,8 @@ void lpfc_sli4_free_rpi(struct lpfc_hba *, int);
 void lpfc_sli4_remove_rpis(struct lpfc_hba *);
 void lpfc_sli4_async_event_proc(struct lpfc_hba *);
 void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *);
-int lpfc_sli4_resume_rpi(struct lpfc_nodelist *);
+int lpfc_sli4_resume_rpi(struct lpfc_nodelist *,
+			void (*)(struct lpfc_hba *, LPFC_MBOXQ_t *), void *);
 void lpfc_sli4_fcp_xri_abort_event_proc(struct lpfc_hba *);
 void lpfc_sli4_els_xri_abort_event_proc(struct lpfc_hba *);
 void lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *,
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index dd044d01..f2a2602 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.28"
+#define LPFC_DRIVER_VERSION "8.3.29"
 #define LPFC_DRIVER_NAME		"lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME	"lpfc:fp"
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 15eefa1..4d39a9f 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -670,10 +670,10 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
 			struct scatterlist *sg;
 
 			sg = scsi_sglist(cmd);
-			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
+			buf = kmap_atomic(sg_page(sg)) + sg->offset;
 
 			memset(buf, 0, cmd->cmnd[4]);
-			kunmap_atomic(buf - sg->offset, KM_IRQ0);
+			kunmap_atomic(buf - sg->offset);
 
 			cmd->result = (DID_OK << 16);
 			cmd->scsi_done(cmd);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 0b2c955..82fa6ce 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -2575,6 +2575,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)
 
 	ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
 	    GFP_KERNEL, ioc->chain_pages);
+	if (!ioc->chain_lookup) {
+		printk(MPT2SAS_ERR_FMT "chain_lookup: get_free_pages failed, "
+		    "sz(%d)\n", ioc->name, (int)sz);
+		goto out;
+	}
 	ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
 	    ioc->request_sz, 16, 0);
 	if (!ioc->chain_dma_pool) {
@@ -4548,7 +4553,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
 		printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n",
 		    ioc->name, __func__);
 		r = 0;
-		goto out;
+		goto out_unlocked;
 	}
 
 	if (mpt2sas_fwfault_debug)
@@ -4604,6 +4609,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
 	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 	mutex_unlock(&ioc->reset_in_progress_mutex);
 
+ out_unlocked:
 	dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
 	    __func__));
 	return r;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 36ea0b2..2b4d376 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -149,7 +149,7 @@ _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
 			desc = "raid_config";
 			break;
 		case MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING:
-			desc = "driver_mappping";
+			desc = "driver_mapping";
 			break;
 		}
 		break;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 193e33e..d953a57 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -5744,7 +5744,7 @@ _scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
 }
 
 /**
- * _scsih_sas_broadcast_primative_event - handle broadcast events
+ * _scsih_sas_broadcast_primitive_event - handle broadcast events
  * @ioc: per adapter object
  * @fw_event: The fw_event_work object
  * Context: user.
@@ -5752,7 +5752,7 @@ _scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
  * Return nothing.
  */
 static void
-_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
+_scsih_sas_broadcast_primitive_event(struct MPT2SAS_ADAPTER *ioc,
     struct fw_event_work *fw_event)
 {
 	struct scsi_cmnd *scmd;
@@ -7263,7 +7263,7 @@ _firmware_event_work(struct work_struct *work)
 		    fw_event);
 		break;
 	case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
-		_scsih_sas_broadcast_primative_event(ioc,
+		_scsih_sas_broadcast_primitive_event(ioc,
 		    fw_event);
 		break;
 	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 6f58919..cc59dff 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -60,7 +60,6 @@ static struct scsi_host_template mvs_sht = {
 	.queuecommand		= sas_queuecommand,
 	.target_alloc		= sas_target_alloc,
 	.slave_configure	= sas_slave_configure,
-	.slave_destroy		= sas_slave_destroy,
 	.scan_finished		= mvs_scan_finished,
 	.scan_start		= mvs_scan_start,
 	.change_queue_depth	= sas_change_queue_depth,
@@ -74,7 +73,6 @@ static struct scsi_host_template mvs_sht = {
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_device_reset_handler = sas_eh_device_reset_handler,
 	.eh_bus_reset_handler	= sas_eh_bus_reset_handler,
-	.slave_alloc		= sas_slave_alloc,
 	.target_destroy		= sas_target_destroy,
 	.ioctl			= sas_ioctl,
 	.shost_attrs		= mvst_host_attrs,
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index a4884a5..7d46c1a 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -308,7 +308,7 @@ int mvs_scan_finished(struct Scsi_Host *shost, unsigned long time)
 	if (mvs_prv->scan_finished == 0)
 		return 0;
 
-	scsi_flush_work(shost);
+	sas_drain_work(sha);
 	return 1;
 }
 
@@ -893,9 +893,6 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
 
 	mvi = ((struct mvs_device *)task->dev->lldd_dev)->mvi_info;
 
-	if ((dev->dev_type == SATA_DEV) && (dev->sata_dev.ap != NULL))
-		spin_unlock_irq(dev->sata_dev.ap->lock);
-
 	spin_lock_irqsave(&mvi->lock, flags);
 	rc = mvs_task_prep(task, mvi, is_tmf, tmf, &pass);
 	if (rc)
@@ -906,9 +903,6 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
 				(MVS_CHIP_SLOT_SZ - 1));
 	spin_unlock_irqrestore(&mvi->lock, flags);
 
-	if ((dev->dev_type == SATA_DEV) && (dev->sata_dev.ap != NULL))
-		spin_lock_irq(dev->sata_dev.ap->lock);
-
 	return rc;
 }
 
@@ -1371,9 +1365,9 @@ void mvs_dev_gone(struct domain_device *dev)
 
 static void mvs_task_done(struct sas_task *task)
 {
-	if (!del_timer(&task->timer))
+	if (!del_timer(&task->slow_task->timer))
 		return;
-	complete(&task->completion);
+	complete(&task->slow_task->completion);
 }
 
 static void mvs_tmf_timedout(unsigned long data)
@@ -1381,7 +1375,7 @@ static void mvs_tmf_timedout(unsigned long data)
 	struct sas_task *task = (struct sas_task *)data;
 
 	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-	complete(&task->completion);
+	complete(&task->slow_task->completion);
 }
 
 #define MVS_TASK_TIMEOUT 20
@@ -1392,7 +1386,7 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev,
 	struct sas_task *task = NULL;
 
 	for (retry = 0; retry < 3; retry++) {
-		task = sas_alloc_task(GFP_KERNEL);
+		task = sas_alloc_slow_task(GFP_KERNEL);
 		if (!task)
 			return -ENOMEM;
 
@@ -1402,20 +1396,20 @@ static int mvs_exec_internal_tmf_task(struct domain_device *dev,
 		memcpy(&task->ssp_task, parameter, para_len);
 		task->task_done = mvs_task_done;
 
-		task->timer.data = (unsigned long) task;
-		task->timer.function = mvs_tmf_timedout;
-		task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ;
-		add_timer(&task->timer);
+		task->slow_task->timer.data = (unsigned long) task;
+		task->slow_task->timer.function = mvs_tmf_timedout;
+		task->slow_task->timer.expires = jiffies + MVS_TASK_TIMEOUT*HZ;
+		add_timer(&task->slow_task->timer);
 
 		res = mvs_task_exec(task, 1, GFP_KERNEL, NULL, 1, tmf);
 
 		if (res) {
-			del_timer(&task->timer);
+			del_timer(&task->slow_task->timer);
 			mv_printk("executing internel task failed:%d\n", res);
 			goto ex_err;
 		}
 
-		wait_for_completion(&task->completion);
+		wait_for_completion(&task->slow_task->completion);
 		res = TMF_RESP_FUNC_FAILED;
 		/* Even TMF timed out, return direct. */
 		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
@@ -1480,10 +1474,11 @@ static int mvs_debug_issue_ssp_tmf(struct domain_device *dev,
 static int mvs_debug_I_T_nexus_reset(struct domain_device *dev)
 {
 	int rc;
-	struct sas_phy *phy = sas_find_local_phy(dev);
+	struct sas_phy *phy = sas_get_local_phy(dev);
 	int reset_type = (dev->dev_type == SATA_DEV ||
 			(dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
 	rc = sas_phy_reset(phy, reset_type);
+	sas_put_local_phy(phy);
 	msleep(2000);
 	return rc;
 }
@@ -1885,11 +1880,11 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
 	case SAS_PROTOCOL_SMP: {
 			struct scatterlist *sg_resp = &task->smp_task.smp_resp;
 			tstat->stat = SAM_STAT_GOOD;
-			to = kmap_atomic(sg_page(sg_resp), KM_IRQ0);
+			to = kmap_atomic(sg_page(sg_resp));
 			memcpy(to + sg_resp->offset,
 				slot->response + sizeof(struct mvs_err_info),
 				sg_dma_len(sg_resp));
-			kunmap_atomic(to, KM_IRQ0);
+			kunmap_atomic(to);
 			break;
 		}
 
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index b31a8e3..d4ed9eb 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -69,10 +69,10 @@
 #ifndef SCSI_OSD_MAJOR
 #  define SCSI_OSD_MAJOR 260
 #endif
-#define SCSI_OSD_MAX_MINOR 64
+#define SCSI_OSD_MAX_MINOR MINORMASK
 
 static const char osd_name[] = "osd";
-static const char *osd_version_string = "open-osd 0.2.0";
+static const char *osd_version_string = "open-osd 0.2.1";
 
 MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
 MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index b7b92f7..86e2b3e 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -338,26 +338,25 @@ update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, int number)
 }
 
 /**
- * bar4_shift - function is called to shift BAR base address
- * @pm8001_ha : our hba card information
+ * pm8001_bar4_shift - function is called to shift BAR base address
+ * @pm8001_ha : our hba card infomation
  * @shiftValue : shifting value in memory bar.
  */
-static int bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
+int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue)
 {
 	u32 regVal;
-	u32 max_wait_count;
+	unsigned long start;
 
 	/* program the inbound AXI translation Lower Address */
 	pm8001_cw32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW, shiftValue);
 
 	/* confirm the setting is written */
-	max_wait_count = 1 * 1000 * 1000;  /* 1 sec */
+	start = jiffies + HZ; /* 1 sec */
 	do {
-		udelay(1);
 		regVal = pm8001_cr32(pm8001_ha, 1, SPC_IBW_AXI_TRANSLATION_LOW);
-	} while ((regVal != shiftValue) && (--max_wait_count));
+	} while ((regVal != shiftValue) && time_before(jiffies, start));
 
-	if (!max_wait_count) {
+	if (regVal != shiftValue) {
 		PM8001_INIT_DBG(pm8001_ha,
 			pm8001_printk("TIMEOUT:SPC_IBW_AXI_TRANSLATION_LOW"
 			" = 0x%x\n", regVal));
@@ -375,6 +374,7 @@ static void __devinit
 mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
 {
 	u32 value, offset, i;
+	unsigned long flags;
 
 #define SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR 0x00030000
 #define SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR 0x00040000
@@ -388,16 +388,23 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
     * Using shifted destination address 0x3_0000:0x1074 + 0x4000*N (N=0:3)
     * Using shifted destination address 0x4_0000:0x1074 + 0x4000*(N-4) (N=4:7)
     */
-	if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR))
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+	if (-1 == pm8001_bar4_shift(pm8001_ha,
+				SAS2_SETTINGS_LOCAL_PHY_0_3_SHIFT_ADDR)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		return;
+	}
 
 	for (i = 0; i < 4; i++) {
 		offset = SAS2_SETTINGS_LOCAL_PHY_0_3_OFFSET + 0x4000 * i;
 		pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
 	}
 	/* shift membase 3 for SAS2_SETTINGS_LOCAL_PHY 4 - 7 */
-	if (-1 == bar4_shift(pm8001_ha, SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR))
+	if (-1 == pm8001_bar4_shift(pm8001_ha,
+				SAS2_SETTINGS_LOCAL_PHY_4_7_SHIFT_ADDR)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		return;
+	}
 	for (i = 4; i < 8; i++) {
 		offset = SAS2_SETTINGS_LOCAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
 		pm8001_cw32(pm8001_ha, 2, offset, 0x80001501);
@@ -421,7 +428,8 @@ mpi_set_phys_g3_with_ssc(struct pm8001_hba_info *pm8001_ha, u32 SSCbit)
 	pm8001_cw32(pm8001_ha, 2, 0xd8, 0x8000C016);
 
 	/*set the shifted destination address to 0x0 to avoid error operation */
-	bar4_shift(pm8001_ha, 0x0);
+	pm8001_bar4_shift(pm8001_ha, 0x0);
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 	return;
 }
 
@@ -437,6 +445,7 @@ mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,
 	u32 offset;
 	u32 value;
 	u32 i;
+	unsigned long flags;
 
 #define OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR 0x00030000
 #define OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR 0x00040000
@@ -445,24 +454,30 @@ mpi_set_open_retry_interval_reg(struct pm8001_hba_info *pm8001_ha,
 #define OPEN_RETRY_INTERVAL_REG_MASK 0x0000FFFF
 
 	value = interval & OPEN_RETRY_INTERVAL_REG_MASK;
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
 	/* shift bar and set the OPEN_REJECT(RETRY) interval time of PHY 0 -3.*/
-	if (-1 == bar4_shift(pm8001_ha,
-			     OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR))
+	if (-1 == pm8001_bar4_shift(pm8001_ha,
+			     OPEN_RETRY_INTERVAL_PHY_0_3_SHIFT_ADDR)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		return;
+	}
 	for (i = 0; i < 4; i++) {
 		offset = OPEN_RETRY_INTERVAL_PHY_0_3_OFFSET + 0x4000 * i;
 		pm8001_cw32(pm8001_ha, 2, offset, value);
 	}
 
-	if (-1 == bar4_shift(pm8001_ha,
-			     OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR))
+	if (-1 == pm8001_bar4_shift(pm8001_ha,
+			     OPEN_RETRY_INTERVAL_PHY_4_7_SHIFT_ADDR)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		return;
+	}
 	for (i = 4; i < 8; i++) {
 		offset = OPEN_RETRY_INTERVAL_PHY_4_7_OFFSET + 0x4000 * (i-4);
 		pm8001_cw32(pm8001_ha, 2, offset, value);
 	}
 	/*set the shifted destination address to 0x0 to avoid error operation */
-	bar4_shift(pm8001_ha, 0x0);
+	pm8001_bar4_shift(pm8001_ha, 0x0);
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 	return;
 }
 
@@ -607,7 +622,8 @@ static int __devinit pm8001_chip_init(struct pm8001_hba_info *pm8001_ha)
 	update_inbnd_queue_table(pm8001_ha, 0);
 	update_outbnd_queue_table(pm8001_ha, 0);
 	mpi_set_phys_g3_with_ssc(pm8001_ha, 0);
-	mpi_set_open_retry_interval_reg(pm8001_ha, 7);
+	/* 7->130ms, 34->500ms, 119->1.5s */
+	mpi_set_open_retry_interval_reg(pm8001_ha, 119);
 	/* notify firmware update finished and check initialization status */
 	if (0 == mpi_init_check(pm8001_ha)) {
 		PM8001_INIT_DBG(pm8001_ha,
@@ -688,8 +704,11 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
 		PM8001_INIT_DBG(pm8001_ha,
 			pm8001_printk("Firmware is ready for reset .\n"));
 	} else {
-	/* Trigger NMI twice via RB6 */
-		if (-1 == bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {
+		unsigned long flags;
+		/* Trigger NMI twice via RB6 */
+		spin_lock_irqsave(&pm8001_ha->lock, flags);
+		if (-1 == pm8001_bar4_shift(pm8001_ha, RB6_ACCESS_REG)) {
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			PM8001_FAIL_DBG(pm8001_ha,
 				pm8001_printk("Shift Bar4 to 0x%x failed\n",
 					RB6_ACCESS_REG));
@@ -715,8 +734,10 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha)
 			PM8001_FAIL_DBG(pm8001_ha,
 				pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
 				pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3)));
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			return -1;
 		}
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 	}
 	return 0;
 }
@@ -733,6 +754,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 	u32	regVal, toggleVal;
 	u32	max_wait_count;
 	u32	regVal1, regVal2, regVal3;
+	unsigned long flags;
 
 	/* step1: Check FW is ready for soft reset */
 	if (soft_reset_ready_check(pm8001_ha) != 0) {
@@ -743,7 +765,9 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 	/* step 2: clear NMI status register on AAP1 and IOP, write the same
 	value to clear */
 	/* map 0x60000 to BAR4(0x20), BAR2(win) */
-	if (-1 == bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+	if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_AAP1_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_FAIL_DBG(pm8001_ha,
 			pm8001_printk("Shift Bar4 to 0x%x failed\n",
 			MBIC_AAP1_ADDR_BASE));
@@ -754,7 +778,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 		pm8001_printk("MBIC - NMI Enable VPE0 (IOP)= 0x%x\n", regVal));
 	pm8001_cw32(pm8001_ha, 2, MBIC_NMI_ENABLE_VPE0_IOP, 0x0);
 	/* map 0x70000 to BAR4(0x20), BAR2(win) */
-	if (-1 == bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {
+	if (-1 == pm8001_bar4_shift(pm8001_ha, MBIC_IOP_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_FAIL_DBG(pm8001_ha,
 			pm8001_printk("Shift Bar4 to 0x%x failed\n",
 			MBIC_IOP_ADDR_BASE));
@@ -796,7 +821,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 
 	/* read required registers for confirmming */
 	/* map 0x0700000 to BAR4(0x20), BAR2(win) */
-	if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
+	if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_FAIL_DBG(pm8001_ha,
 			pm8001_printk("Shift Bar4 to 0x%x failed\n",
 			GSM_ADDR_BASE));
@@ -862,7 +888,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 	/* step 5: delay 10 usec */
 	udelay(10);
 	/* step 5-b: set GPIO-0 output control to tristate anyway */
-	if (-1 == bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {
+	if (-1 == pm8001_bar4_shift(pm8001_ha, GPIO_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_INIT_DBG(pm8001_ha,
 				pm8001_printk("Shift Bar4 to 0x%x failed\n",
 				GPIO_ADDR_BASE));
@@ -878,7 +905,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 
 	/* Step 6: Reset the IOP and AAP1 */
 	/* map 0x00000 to BAR4(0x20), BAR2(win) */
-	if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
+	if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_FAIL_DBG(pm8001_ha,
 			pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
 			SPC_TOP_LEVEL_ADDR_BASE));
@@ -915,7 +943,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 
 	/* step 11: reads and sets the GSM Configuration and Reset Register */
 	/* map 0x0700000 to BAR4(0x20), BAR2(win) */
-	if (-1 == bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
+	if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_FAIL_DBG(pm8001_ha,
 			pm8001_printk("SPC Shift Bar4 to 0x%x failed\n",
 			GSM_ADDR_BASE));
@@ -968,7 +997,8 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 
 	/* step 13: bring the IOP and AAP1 out of reset */
 	/* map 0x00000 to BAR4(0x20), BAR2(win) */
-	if (-1 == bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
+	if (-1 == pm8001_bar4_shift(pm8001_ha, SPC_TOP_LEVEL_ADDR_BASE)) {
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 		PM8001_FAIL_DBG(pm8001_ha,
 			pm8001_printk("Shift Bar4 to 0x%x failed\n",
 			SPC_TOP_LEVEL_ADDR_BASE));
@@ -1010,6 +1040,7 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 				pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
 				pm8001_cr32(pm8001_ha, 0,
 				MSGU_SCRATCH_PAD_3)));
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			return -1;
 		}
 
@@ -1039,9 +1070,12 @@ pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature)
 				pm8001_printk("SCRATCH_PAD3 value = 0x%x\n",
 				pm8001_cr32(pm8001_ha, 0,
 				MSGU_SCRATCH_PAD_3)));
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 			return -1;
 		}
 	}
+	pm8001_bar4_shift(pm8001_ha, 0);
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
 
 	PM8001_INIT_DBG(pm8001_ha,
 		pm8001_printk("SPC soft reset Complete\n"));
@@ -1157,8 +1191,8 @@ pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha,
 	msi_index = int_vec_idx * MSIX_TABLE_ELEMENT_SIZE;
 	msi_index += MSIX_TABLE_BASE;
 	pm8001_cw32(pm8001_ha, 0,  msi_index, MSIX_INTERRUPT_DISABLE);
-
 }
+
 /**
  * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt
  * @pm8001_ha: our hba card information
@@ -1388,24 +1422,191 @@ static void pm8001_work_fn(struct work_struct *work)
 	struct pm8001_device *pm8001_dev;
 	struct domain_device *dev;
 
+	/*
+	 * So far, all users of this stash an associated structure here.
+	 * If we get here, and this pointer is null, then the action
+	 * was cancelled. This nullification happens when the device
+	 * goes away.
+	 */
+	pm8001_dev = pw->data; /* Most stash device structure */
+	if ((pm8001_dev == NULL)
+	 || ((pw->handler != IO_XFER_ERROR_BREAK)
+	  && (pm8001_dev->dev_type == NO_DEVICE))) {
+		kfree(pw);
+		return;
+	}
+
 	switch (pw->handler) {
+	case IO_XFER_ERROR_BREAK:
+	{	/* This one stashes the sas_task instead */
+		struct sas_task *t = (struct sas_task *)pm8001_dev;
+		u32 tag;
+		struct pm8001_ccb_info *ccb;
+		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
+		unsigned long flags, flags1;
+		struct task_status_struct *ts;
+		int i;
+
+		if (pm8001_query_task(t) == TMF_RESP_FUNC_SUCC)
+			break; /* Task still on lu */
+		spin_lock_irqsave(&pm8001_ha->lock, flags);
+
+		spin_lock_irqsave(&t->task_state_lock, flags1);
+		if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) {
+			spin_unlock_irqrestore(&t->task_state_lock, flags1);
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			break; /* Task got completed by another */
+		}
+		spin_unlock_irqrestore(&t->task_state_lock, flags1);
+
+		/* Search for a possible ccb that matches the task */
+		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
+			ccb = &pm8001_ha->ccb_info[i];
+			tag = ccb->ccb_tag;
+			if ((tag != 0xFFFFFFFF) && (ccb->task == t))
+				break;
+		}
+		if (!ccb) {
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			break; /* Task got freed by another */
+		}
+		ts = &t->task_status;
+		ts->resp = SAS_TASK_COMPLETE;
+		/* Force the midlayer to retry */
+		ts->stat = SAS_QUEUE_FULL;
+		pm8001_dev = ccb->device;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		spin_lock_irqsave(&t->task_state_lock, flags1);
+		t->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+		t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+		t->task_state_flags |= SAS_TASK_STATE_DONE;
+		if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+			spin_unlock_irqrestore(&t->task_state_lock, flags1);
+			PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p"
+				" done with event 0x%x resp 0x%x stat 0x%x but"
+				" aborted by upper layer!\n",
+				t, pw->handler, ts->resp, ts->stat));
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+		} else {
+			spin_unlock_irqrestore(&t->task_state_lock, flags1);
+			pm8001_ccb_task_free(pm8001_ha, t, ccb, tag);
+			mb();/* in order to force CPU ordering */
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			t->task_done(t);
+		}
+	}	break;
+	case IO_XFER_OPEN_RETRY_TIMEOUT:
+	{	/* This one stashes the sas_task instead */
+		struct sas_task *t = (struct sas_task *)pm8001_dev;
+		u32 tag;
+		struct pm8001_ccb_info *ccb;
+		struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
+		unsigned long flags, flags1;
+		int i, ret = 0;
+
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+
+		ret = pm8001_query_task(t);
+
+		PM8001_IO_DBG(pm8001_ha,
+			switch (ret) {
+			case TMF_RESP_FUNC_SUCC:
+				pm8001_printk("...Task on lu\n");
+				break;
+
+			case TMF_RESP_FUNC_COMPLETE:
+				pm8001_printk("...Task NOT on lu\n");
+				break;
+
+			default:
+				pm8001_printk("...query task failed!!!\n");
+				break;
+			});
+
+		spin_lock_irqsave(&pm8001_ha->lock, flags);
+
+		spin_lock_irqsave(&t->task_state_lock, flags1);
+
+		if (unlikely((t->task_state_flags & SAS_TASK_STATE_DONE))) {
+			spin_unlock_irqrestore(&t->task_state_lock, flags1);
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */
+				(void)pm8001_abort_task(t);
+			break; /* Task got completed by another */
+		}
+
+		spin_unlock_irqrestore(&t->task_state_lock, flags1);
+
+		/* Search for a possible ccb that matches the task */
+		for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
+			ccb = &pm8001_ha->ccb_info[i];
+			tag = ccb->ccb_tag;
+			if ((tag != 0xFFFFFFFF) && (ccb->task == t))
+				break;
+		}
+		if (!ccb) {
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			if (ret == TMF_RESP_FUNC_SUCC) /* task on lu */
+				(void)pm8001_abort_task(t);
+			break; /* Task got freed by another */
+		}
+
+		pm8001_dev = ccb->device;
+		dev = pm8001_dev->sas_device;
+
+		switch (ret) {
+		case TMF_RESP_FUNC_SUCC: /* task on lu */
+			ccb->open_retry = 1; /* Snub completion */
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			ret = pm8001_abort_task(t);
+			ccb->open_retry = 0;
+			switch (ret) {
+			case TMF_RESP_FUNC_SUCC:
+			case TMF_RESP_FUNC_COMPLETE:
+				break;
+			default: /* device misbehavior */
+				ret = TMF_RESP_FUNC_FAILED;
+				PM8001_IO_DBG(pm8001_ha,
+					pm8001_printk("...Reset phy\n"));
+				pm8001_I_T_nexus_reset(dev);
+				break;
+			}
+			break;
+
+		case TMF_RESP_FUNC_COMPLETE: /* task not on lu */
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			/* Do we need to abort the task locally? */
+			break;
+
+		default: /* device misbehavior */
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			ret = TMF_RESP_FUNC_FAILED;
+			PM8001_IO_DBG(pm8001_ha,
+				pm8001_printk("...Reset phy\n"));
+			pm8001_I_T_nexus_reset(dev);
+		}
+
+		if (ret == TMF_RESP_FUNC_FAILED)
+			t = NULL;
+		pm8001_open_reject_retry(pm8001_ha, t, pm8001_dev);
+		PM8001_IO_DBG(pm8001_ha, pm8001_printk("...Complete\n"));
+	}	break;
 	case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
-		pm8001_dev = pw->data;
 		dev = pm8001_dev->sas_device;
 		pm8001_I_T_nexus_reset(dev);
 		break;
 	case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
-		pm8001_dev = pw->data;
 		dev = pm8001_dev->sas_device;
 		pm8001_I_T_nexus_reset(dev);
 		break;
 	case IO_DS_IN_ERROR:
-		pm8001_dev = pw->data;
 		dev = pm8001_dev->sas_device;
 		pm8001_I_T_nexus_reset(dev);
 		break;
 	case IO_DS_NON_OPERATIONAL:
-		pm8001_dev = pw->data;
 		dev = pm8001_dev->sas_device;
 		pm8001_I_T_nexus_reset(dev);
 		break;
@@ -1460,6 +1661,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
 	status = le32_to_cpu(psspPayload->status);
 	tag = le32_to_cpu(psspPayload->tag);
 	ccb = &pm8001_ha->ccb_info[tag];
+	if ((status == IO_ABORTED) && ccb->open_retry) {
+		/* Being completed by another */
+		ccb->open_retry = 0;
+		return;
+	}
 	pm8001_dev = ccb->device;
 	param = le32_to_cpu(psspPayload->param);
 
@@ -1515,6 +1721,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
 			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
 		ts->resp = SAS_TASK_COMPLETE;
 		ts->stat = SAS_OPEN_REJECT;
+		/* Force the midlayer to retry */
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
 		break;
 	case IO_XFER_ERROR_PHY_NOT_READY:
 		PM8001_IO_DBG(pm8001_ha,
@@ -1719,9 +1927,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
 	case IO_XFER_ERROR_BREAK:
 		PM8001_IO_DBG(pm8001_ha,
 			pm8001_printk("IO_XFER_ERROR_BREAK\n"));
-		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAS_INTERRUPTED;
-		break;
+		pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK);
+		return;
 	case IO_XFER_ERROR_PHY_NOT_READY:
 		PM8001_IO_DBG(pm8001_ha,
 			pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n"));
@@ -1800,10 +2007,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)
 	case IO_XFER_OPEN_RETRY_TIMEOUT:
 		PM8001_IO_DBG(pm8001_ha,
 			pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n"));
-		ts->resp = SAS_TASK_COMPLETE;
-		ts->stat = SAS_OPEN_REJECT;
-		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
-		break;
+		pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT);
+		return;
 	case IO_XFER_ERROR_UNEXPECTED_PHASE:
 		PM8001_IO_DBG(pm8001_ha,
 			pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n"));
@@ -3532,7 +3737,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		break;
 	case OPC_OUB_DEREG_DEV:
 		PM8001_MSG_DBG(pm8001_ha,
-			pm8001_printk("unresgister the deviece\n"));
+			pm8001_printk("unregister the device\n"));
 		mpi_dereg_resp(pm8001_ha, piomb);
 		break;
 	case OPC_OUB_GET_DEV_HANDLE:
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index c21a216..36efaa7 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -62,7 +62,6 @@ static struct scsi_host_template pm8001_sht = {
 	.queuecommand		= sas_queuecommand,
 	.target_alloc		= sas_target_alloc,
 	.slave_configure	= sas_slave_configure,
-	.slave_destroy		= sas_slave_destroy,
 	.scan_finished		= pm8001_scan_finished,
 	.scan_start		= pm8001_scan_start,
 	.change_queue_depth	= sas_change_queue_depth,
@@ -76,7 +75,6 @@ static struct scsi_host_template pm8001_sht = {
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_device_reset_handler = sas_eh_device_reset_handler,
 	.eh_bus_reset_handler	= sas_eh_bus_reset_handler,
-	.slave_alloc		= sas_slave_alloc,
 	.target_destroy		= sas_target_destroy,
 	.ioctl			= sas_ioctl,
 	.shost_attrs		= pm8001_host_attrs,
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index fb3dc99..6b5b4a2 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -166,6 +166,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
 	struct pm8001_hba_info *pm8001_ha = NULL;
 	struct sas_phy_linkrates *rates;
 	DECLARE_COMPLETION_ONSTACK(completion);
+	unsigned long flags;
 	pm8001_ha = sas_phy->ha->lldd_ha;
 	pm8001_ha->phy[phy_id].enable_completion = &completion;
 	switch (func) {
@@ -209,8 +210,29 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
 	case PHY_FUNC_DISABLE:
 		PM8001_CHIP_DISP->phy_stop_req(pm8001_ha, phy_id);
 		break;
+	case PHY_FUNC_GET_EVENTS:
+		spin_lock_irqsave(&pm8001_ha->lock, flags);
+		if (-1 == pm8001_bar4_shift(pm8001_ha,
+					(phy_id < 4) ? 0x30000 : 0x40000)) {
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			return -EINVAL;
+		}
+		{
+			struct sas_phy *phy = sas_phy->phy;
+			uint32_t *qp = (uint32_t *)(((char *)
+				pm8001_ha->io_mem[2].memvirtaddr)
+				+ 0x1034 + (0x4000 * (phy_id & 3)));
+
+			phy->invalid_dword_count = qp[0];
+			phy->running_disparity_error_count = qp[1];
+			phy->loss_of_dword_sync_count = qp[3];
+			phy->phy_reset_problem_count = qp[4];
+		}
+		pm8001_bar4_shift(pm8001_ha, 0);
+		spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+		return 0;
 	default:
-		rc = -ENOSYS;
+		rc = -EOPNOTSUPP;
 	}
 	msleep(300);
 	return rc;
@@ -234,12 +256,14 @@ void pm8001_scan_start(struct Scsi_Host *shost)
 
 int pm8001_scan_finished(struct Scsi_Host *shost, unsigned long time)
 {
+	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+
 	/* give the phy enabling interrupt event time to come in (1s
 	* is empirically about all it takes) */
 	if (time < HZ)
 		return 0;
 	/* Wait for discovery to finish */
-	scsi_flush_work(shost);
+	sas_drain_work(ha);
 	return 1;
 }
 
@@ -340,7 +364,7 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
 	struct pm8001_ccb_info *ccb;
 	u32 tag = 0xdeadbeef, rc, n_elem = 0;
 	u32 n = num;
-	unsigned long flags = 0, flags_libsas = 0;
+	unsigned long flags = 0;
 
 	if (!dev->port) {
 		struct task_status_struct *tsm = &t->task_status;
@@ -364,11 +388,7 @@ static int pm8001_task_exec(struct sas_task *task, const int num,
 				ts->stat = SAS_PHY_DOWN;
 
 				spin_unlock_irqrestore(&pm8001_ha->lock, flags);
-				spin_unlock_irqrestore(dev->sata_dev.ap->lock,
-						flags_libsas);
 				t->task_done(t);
-				spin_lock_irqsave(dev->sata_dev.ap->lock,
-					flags_libsas);
 				spin_lock_irqsave(&pm8001_ha->lock, flags);
 				if (n > 1)
 					t = list_entry(t->list.next,
@@ -516,6 +536,7 @@ void pm8001_ccb_task_free(struct pm8001_hba_info *pm8001_ha,
 	task->lldd_task = NULL;
 	ccb->task = NULL;
 	ccb->ccb_tag = 0xFFFFFFFF;
+	ccb->open_retry = 0;
 	pm8001_ccb_free(pm8001_ha, ccb_idx);
 }
 
@@ -615,7 +636,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev)
 	wait_for_completion(&completion);
 	if (dev->dev_type == SAS_END_DEV)
 		msleep(50);
-	pm8001_ha->flags |= PM8001F_RUN_TIME ;
+	pm8001_ha->flags = PM8001F_RUN_TIME;
 	return 0;
 found_out:
 	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
@@ -629,9 +650,9 @@ int pm8001_dev_found(struct domain_device *dev)
 
 static void pm8001_task_done(struct sas_task *task)
 {
-	if (!del_timer(&task->timer))
+	if (!del_timer(&task->slow_task->timer))
 		return;
-	complete(&task->completion);
+	complete(&task->slow_task->completion);
 }
 
 static void pm8001_tmf_timedout(unsigned long data)
@@ -639,7 +660,7 @@ static void pm8001_tmf_timedout(unsigned long data)
 	struct sas_task *task = (struct sas_task *)data;
 
 	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-	complete(&task->completion);
+	complete(&task->slow_task->completion);
 }
 
 #define PM8001_TASK_TIMEOUT 20
@@ -670,21 +691,21 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev,
 		task->task_proto = dev->tproto;
 		memcpy(&task->ssp_task, parameter, para_len);
 		task->task_done = pm8001_task_done;
-		task->timer.data = (unsigned long)task;
-		task->timer.function = pm8001_tmf_timedout;
-		task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ;
-		add_timer(&task->timer);
+		task->slow_task->timer.data = (unsigned long)task;
+		task->slow_task->timer.function = pm8001_tmf_timedout;
+		task->slow_task->timer.expires = jiffies + PM8001_TASK_TIMEOUT*HZ;
+		add_timer(&task->slow_task->timer);
 
 		res = pm8001_task_exec(task, 1, GFP_KERNEL, 1, tmf);
 
 		if (res) {
-			del_timer(&task->timer);
+			del_timer(&task->slow_task->timer);
 			PM8001_FAIL_DBG(pm8001_ha,
 				pm8001_printk("Executing internal task "
 				"failed\n"));
 			goto ex_err;
 		}
-		wait_for_completion(&task->completion);
+		wait_for_completion(&task->slow_task->completion);
 		res = -TMF_RESP_FUNC_FAILED;
 		/* Even TMF timed out, return direct. */
 		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
@@ -751,10 +772,10 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
 		task->dev = dev;
 		task->task_proto = dev->tproto;
 		task->task_done = pm8001_task_done;
-		task->timer.data = (unsigned long)task;
-		task->timer.function = pm8001_tmf_timedout;
-		task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ;
-		add_timer(&task->timer);
+		task->slow_task->timer.data = (unsigned long)task;
+		task->slow_task->timer.function = pm8001_tmf_timedout;
+		task->slow_task->timer.expires = jiffies + PM8001_TASK_TIMEOUT * HZ;
+		add_timer(&task->slow_task->timer);
 
 		res = pm8001_tag_alloc(pm8001_ha, &ccb_tag);
 		if (res)
@@ -768,13 +789,13 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha,
 			pm8001_dev, flag, task_tag, ccb_tag);
 
 		if (res) {
-			del_timer(&task->timer);
+			del_timer(&task->slow_task->timer);
 			PM8001_FAIL_DBG(pm8001_ha,
 				pm8001_printk("Executing internal task "
 				"failed\n"));
 			goto ex_err;
 		}
-		wait_for_completion(&task->completion);
+		wait_for_completion(&task->slow_task->completion);
 		res = TMF_RESP_FUNC_FAILED;
 		/* Even TMF timed out, return direct. */
 		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
@@ -860,6 +881,77 @@ static int pm8001_issue_ssp_tmf(struct domain_device *dev,
 		tmf);
 }
 
+/* retry commands by ha, by task and/or by device */
+void pm8001_open_reject_retry(
+	struct pm8001_hba_info *pm8001_ha,
+	struct sas_task *task_to_close,
+	struct pm8001_device *device_to_close)
+{
+	int i;
+	unsigned long flags;
+
+	if (pm8001_ha == NULL)
+		return;
+
+	spin_lock_irqsave(&pm8001_ha->lock, flags);
+
+	for (i = 0; i < PM8001_MAX_CCB; i++) {
+		struct sas_task *task;
+		struct task_status_struct *ts;
+		struct pm8001_device *pm8001_dev;
+		unsigned long flags1;
+		u32 tag;
+		struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i];
+
+		pm8001_dev = ccb->device;
+		if (!pm8001_dev || (pm8001_dev->dev_type == NO_DEVICE))
+			continue;
+		if (!device_to_close) {
+			uintptr_t d = (uintptr_t)pm8001_dev
+					- (uintptr_t)&pm8001_ha->devices;
+			if (((d % sizeof(*pm8001_dev)) != 0)
+			 || ((d / sizeof(*pm8001_dev)) >= PM8001_MAX_DEVICES))
+				continue;
+		} else if (pm8001_dev != device_to_close)
+			continue;
+		tag = ccb->ccb_tag;
+		if (!tag || (tag == 0xFFFFFFFF))
+			continue;
+		task = ccb->task;
+		if (!task || !task->task_done)
+			continue;
+		if (task_to_close && (task != task_to_close))
+			continue;
+		ts = &task->task_status;
+		ts->resp = SAS_TASK_COMPLETE;
+		/* Force the midlayer to retry */
+		ts->stat = SAS_OPEN_REJECT;
+		ts->open_rej_reason = SAS_OREJ_RSVD_RETRY;
+		if (pm8001_dev)
+			pm8001_dev->running_req--;
+		spin_lock_irqsave(&task->task_state_lock, flags1);
+		task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+		task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+		task->task_state_flags |= SAS_TASK_STATE_DONE;
+		if (unlikely((task->task_state_flags
+				& SAS_TASK_STATE_ABORTED))) {
+			spin_unlock_irqrestore(&task->task_state_lock,
+				flags1);
+			pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+		} else {
+			spin_unlock_irqrestore(&task->task_state_lock,
+				flags1);
+			pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
+			mb();/* in order to force CPU ordering */
+			spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+			task->task_done(task);
+			spin_lock_irqsave(&pm8001_ha->lock, flags);
+		}
+	}
+
+	spin_unlock_irqrestore(&pm8001_ha->lock, flags);
+}
+
 /**
   * Standard mandates link reset for ATA  (type 0) and hard reset for
   * SSP (type 1) , only for RECOVERY
@@ -875,12 +967,14 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev)
 
 	pm8001_dev = dev->lldd_dev;
 	pm8001_ha = pm8001_find_ha_by_dev(dev);
-	phy = sas_find_local_phy(dev);
+	phy = sas_get_local_phy(dev);
 
 	if (dev_is_sata(dev)) {
 		DECLARE_COMPLETION_ONSTACK(completion_setstate);
-		if (scsi_is_sas_phy_local(phy))
-			return 0;
+		if (scsi_is_sas_phy_local(phy)) {
+			rc = 0;
+			goto out;
+		}
 		rc = sas_phy_reset(phy, 1);
 		msleep(2000);
 		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
@@ -889,12 +983,14 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev)
 		rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
 			pm8001_dev, 0x01);
 		wait_for_completion(&completion_setstate);
-	} else{
-	rc = sas_phy_reset(phy, 1);
-	msleep(2000);
+	} else {
+		rc = sas_phy_reset(phy, 1);
+		msleep(2000);
 	}
 	PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n",
 		pm8001_dev->device_id, rc));
+ out:
+	sas_put_local_phy(phy);
 	return rc;
 }
 
@@ -906,10 +1002,11 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun)
 	struct pm8001_device *pm8001_dev = dev->lldd_dev;
 	struct pm8001_hba_info *pm8001_ha = pm8001_find_ha_by_dev(dev);
 	if (dev_is_sata(dev)) {
-		struct sas_phy *phy = sas_find_local_phy(dev);
+		struct sas_phy *phy = sas_get_local_phy(dev);
 		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev ,
 			dev, 1, 0);
 		rc = sas_phy_reset(phy, 1);
+		sas_put_local_phy(phy);
 		rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
 			pm8001_dev, 0x01);
 		msleep(2000);
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 93959fe..1100820 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -235,6 +235,7 @@ struct pm8001_ccb_info {
 	struct pm8001_device	*device;
 	struct pm8001_prd	buf_prd[PM8001_MAX_DMA_SG];
 	struct fw_control_ex	*fw_control_context;
+	u8			open_retry;
 };
 
 struct mpi_mem {
@@ -484,10 +485,15 @@ void pm8001_dev_gone(struct domain_device *dev);
 int pm8001_lu_reset(struct domain_device *dev, u8 *lun);
 int pm8001_I_T_nexus_reset(struct domain_device *dev);
 int pm8001_query_task(struct sas_task *task);
+void pm8001_open_reject_retry(
+	struct pm8001_hba_info *pm8001_ha,
+	struct sas_task *task_to_close,
+	struct pm8001_device *device_to_close);
 int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,
 	dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo,
 	u32 mem_size, u32 align);
 
+int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue);
 
 /* ctl shared API */
 extern struct device_attribute *pm8001_host_attrs[];
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
index ca496c7..e1d150f 100644
--- a/drivers/scsi/pmcraid.h
+++ b/drivers/scsi/pmcraid.h
@@ -857,11 +857,11 @@ static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
 	{0x01180600, IOASC_LOG_LEVEL_HARD,
 	 "Recovered Error, soft media error, sector reassignment suggested"},
 	{0x015D0000, IOASC_LOG_LEVEL_HARD,
-	 "Recovered Error, failure prediction thresold exceeded"},
+	 "Recovered Error, failure prediction threshold exceeded"},
 	{0x015D9200, IOASC_LOG_LEVEL_HARD,
-	 "Recovered Error, soft Cache Card Battery error thresold"},
+	 "Recovered Error, soft Cache Card Battery error threshold"},
 	{0x015D9200, IOASC_LOG_LEVEL_HARD,
-	 "Recovered Error, soft Cache Card Battery error thresold"},
+	 "Recovered Error, soft Cache Card Battery error threshold"},
 	{0x02048000, IOASC_LOG_LEVEL_HARD,
 	 "Not Ready, IOA Reset Required"},
 	{0x02408500, IOASC_LOG_LEVEL_HARD,
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index a2f1b30..5926f5a 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -356,7 +356,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
 		else if (start == (ha->flt_region_boot * 4) ||
 		    start == (ha->flt_region_fw * 4))
 			valid = 1;
-		else if (IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
+		else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)
+			|| IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
 			valid = 1;
 		if (!valid) {
 			ql_log(ql_log_warn, vha, 0x7065,
@@ -627,144 +628,6 @@ static struct bin_attribute sysfs_reset_attr = {
 };
 
 static ssize_t
-qla2x00_sysfs_write_edc(struct file *filp, struct kobject *kobj,
-			struct bin_attribute *bin_attr,
-			char *buf, loff_t off, size_t count)
-{
-	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
-	    struct device, kobj)));
-	struct qla_hw_data *ha = vha->hw;
-	uint16_t dev, adr, opt, len;
-	int rval;
-
-	ha->edc_data_len = 0;
-
-	if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
-		return -EINVAL;
-
-	if (!ha->edc_data) {
-		ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
-		    &ha->edc_data_dma);
-		if (!ha->edc_data) {
-			ql_log(ql_log_warn, vha, 0x7073,
-			    "Unable to allocate memory for EDC write.\n");
-			return -ENOMEM;
-		}
-	}
-
-	dev = le16_to_cpup((void *)&buf[0]);
-	adr = le16_to_cpup((void *)&buf[2]);
-	opt = le16_to_cpup((void *)&buf[4]);
-	len = le16_to_cpup((void *)&buf[6]);
-
-	if (!(opt & BIT_0))
-		if (len == 0 || len > DMA_POOL_SIZE || len > count - 8)
-			return -EINVAL;
-
-	memcpy(ha->edc_data, &buf[8], len);
-
-	rval = qla2x00_write_sfp(vha, ha->edc_data_dma, ha->edc_data,
-	    dev, adr, len, opt);
-	if (rval != QLA_SUCCESS) {
-		ql_log(ql_log_warn, vha, 0x7074,
-		    "Unable to write EDC (%x) %02x:%04x:%02x:%02x:%02hhx\n",
-		    rval, dev, adr, opt, len, buf[8]);
-		return -EIO;
-	}
-
-	return count;
-}
-
-static struct bin_attribute sysfs_edc_attr = {
-	.attr = {
-		.name = "edc",
-		.mode = S_IWUSR,
-	},
-	.size = 0,
-	.write = qla2x00_sysfs_write_edc,
-};
-
-static ssize_t
-qla2x00_sysfs_write_edc_status(struct file *filp, struct kobject *kobj,
-			struct bin_attribute *bin_attr,
-			char *buf, loff_t off, size_t count)
-{
-	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
-	    struct device, kobj)));
-	struct qla_hw_data *ha = vha->hw;
-	uint16_t dev, adr, opt, len;
-	int rval;
-
-	ha->edc_data_len = 0;
-
-	if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
-		return -EINVAL;
-
-	if (!ha->edc_data) {
-		ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
-		    &ha->edc_data_dma);
-		if (!ha->edc_data) {
-			ql_log(ql_log_warn, vha, 0x708c,
-			    "Unable to allocate memory for EDC status.\n");
-			return -ENOMEM;
-		}
-	}
-
-	dev = le16_to_cpup((void *)&buf[0]);
-	adr = le16_to_cpup((void *)&buf[2]);
-	opt = le16_to_cpup((void *)&buf[4]);
-	len = le16_to_cpup((void *)&buf[6]);
-
-	if (!(opt & BIT_0))
-		if (len == 0 || len > DMA_POOL_SIZE)
-			return -EINVAL;
-
-	memset(ha->edc_data, 0, len);
-	rval = qla2x00_read_sfp(vha, ha->edc_data_dma, ha->edc_data,
-			dev, adr, len, opt);
-	if (rval != QLA_SUCCESS) {
-		ql_log(ql_log_info, vha, 0x7075,
-		    "Unable to write EDC status (%x) %02x:%04x:%02x:%02x.\n",
-		    rval, dev, adr, opt, len);
-		return -EIO;
-	}
-
-	ha->edc_data_len = len;
-
-	return count;
-}
-
-static ssize_t
-qla2x00_sysfs_read_edc_status(struct file *filp, struct kobject *kobj,
-			   struct bin_attribute *bin_attr,
-			   char *buf, loff_t off, size_t count)
-{
-	struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
-	    struct device, kobj)));
-	struct qla_hw_data *ha = vha->hw;
-
-	if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0)
-		return 0;
-
-	if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count)
-		return -EINVAL;
-
-	memcpy(buf, ha->edc_data, ha->edc_data_len);
-
-	return ha->edc_data_len;
-}
-
-static struct bin_attribute sysfs_edc_status_attr = {
-	.attr = {
-		.name = "edc_status",
-		.mode = S_IRUSR | S_IWUSR,
-	},
-	.size = 0,
-	.write = qla2x00_sysfs_write_edc_status,
-	.read = qla2x00_sysfs_read_edc_status,
-};
-
-static ssize_t
 qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj,
 		       struct bin_attribute *bin_attr,
 		       char *buf, loff_t off, size_t count)
@@ -879,8 +742,6 @@ static struct sysfs_entry {
 	{ "vpd", &sysfs_vpd_attr, 1 },
 	{ "sfp", &sysfs_sfp_attr, 1 },
 	{ "reset", &sysfs_reset_attr, },
-	{ "edc", &sysfs_edc_attr, 2 },
-	{ "edc_status", &sysfs_edc_status_attr, 2 },
 	{ "xgmac_stats", &sysfs_xgmac_stats_attr, 3 },
 	{ "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 },
 	{ NULL },
@@ -898,7 +759,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
 			continue;
 		if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
 			continue;
-		if (iter->is4GBp_only == 3 && !(IS_QLA8XXX_TYPE(vha->hw)))
+		if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw)))
 			continue;
 
 		ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
@@ -926,7 +787,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
 			continue;
 		if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
 			continue;
-		if (iter->is4GBp_only == 3 && !!(IS_QLA8XXX_TYPE(vha->hw)))
+		if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw)))
 			continue;
 
 		sysfs_remove_bin_file(&host->shost_gendev.kobj,
@@ -1036,8 +897,7 @@ qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
 	    vha->device_flags & DFLG_NO_CABLE)
 		len = snprintf(buf, PAGE_SIZE, "Link Down\n");
 	else if (atomic_read(&vha->loop_state) != LOOP_READY ||
-	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+	    qla2x00_reset_active(vha))
 		len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
 	else {
 		len = snprintf(buf, PAGE_SIZE, "Link Up - ");
@@ -1232,7 +1092,7 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev,
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n",
@@ -1279,7 +1139,7 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
@@ -1294,7 +1154,7 @@ qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr,
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
@@ -1317,7 +1177,7 @@ qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr,
 {
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
-	if (!IS_QLA8XXX_TYPE(vha->hw))
+	if (!IS_CNA_CAPABLE(vha->hw))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id);
@@ -1329,7 +1189,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev,
 {
 	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
 
-	if (!IS_QLA8XXX_TYPE(vha->hw))
+	if (!IS_CNA_CAPABLE(vha->hw))
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -1359,14 +1219,13 @@ qla2x00_thermal_temp_show(struct device *dev,
 		return snprintf(buf, PAGE_SIZE, "\n");
 
 	temp = frac = 0;
-	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+	if (qla2x00_reset_active(vha))
 		ql_log(ql_log_warn, vha, 0x707b,
 		    "ISP reset active.\n");
 	else if (!vha->hw->flags.eeh_busy)
 		rval = qla2x00_get_thermal_temp(vha, &temp, &frac);
 	if (rval != QLA_SUCCESS)
-		temp = frac = 0;
+		return snprintf(buf, PAGE_SIZE, "\n");
 
 	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", temp, frac);
 }
@@ -1379,8 +1238,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
 	int rval = QLA_FUNCTION_FAILED;
 	uint16_t state[5];
 
-	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+	if (qla2x00_reset_active(vha))
 		ql_log(ql_log_warn, vha, 0x707c,
 		    "ISP reset active.\n");
 	else if (!vha->hw->flags.eeh_busy)
@@ -1496,6 +1354,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost)
 	case PORT_SPEED_10GB:
 		speed = FC_PORTSPEED_10GBIT;
 		break;
+	case PORT_SPEED_16GB:
+		speed = FC_PORTSPEED_16GBIT;
+		break;
 	}
 	fc_host_speed(shost) = speed;
 }
@@ -1646,10 +1507,14 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
 	 * final cleanup of firmware resources (PCBs and XCBs).
 	 */
 	if (fcport->loop_id != FC_NO_LOOP_ID &&
-	    !test_bit(UNLOADING, &fcport->vha->dpc_flags))
-		fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
-			fcport->loop_id, fcport->d_id.b.domain,
-			fcport->d_id.b.area, fcport->d_id.b.al_pa);
+	    !test_bit(UNLOADING, &fcport->vha->dpc_flags)) {
+		if (IS_FWI2_CAPABLE(fcport->vha->hw))
+			fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
+			    fcport->loop_id, fcport->d_id.b.domain,
+			    fcport->d_id.b.area, fcport->d_id.b.al_pa);
+		else
+			qla2x00_port_logout(fcport->vha, fcport);
+	}
 }
 
 static int
@@ -1693,9 +1558,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
 	if (IS_FWI2_CAPABLE(ha)) {
 		rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma);
 	} else if (atomic_read(&base_vha->loop_state) == LOOP_READY &&
-		    !test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) &&
-		    !test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
-		    !ha->dpc_active) {
+	    !qla2x00_reset_active(vha) && !ha->dpc_active) {
 		/* Must be in a 'READY' state for statistics retrieval. */
 		rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
 						stats, stats_dma);
@@ -1894,6 +1757,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
 			break;
 		}
 	}
+
 	if (qos) {
 		ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0,
 			qos);
@@ -2091,7 +1955,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
 	fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
 	fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
 
-	if (IS_QLA8XXX_TYPE(ha))
+	if (IS_CNA_CAPABLE(ha))
 		speed = FC_PORTSPEED_10GBIT;
 	else if (IS_QLA25XX(ha))
 		speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index b1d0f93..f74cc06 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -11,29 +11,36 @@
 #include <linux/delay.h>
 
 /* BSG support for ELS/CT pass through */
-inline srb_t *
-qla2x00_get_ctx_bsg_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size)
+void
+qla2x00_bsg_job_done(void *data, void *ptr, int res)
 {
-	srb_t *sp;
+	srb_t *sp = (srb_t *)ptr;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
+
+	bsg_job->reply->result = res;
+	bsg_job->job_done(bsg_job);
+	sp->free(vha, sp);
+}
+
+void
+qla2x00_bsg_sp_free(void *data, void *ptr)
+{
+	srb_t *sp = (srb_t *)ptr;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
 	struct qla_hw_data *ha = vha->hw;
-	struct srb_ctx *ctx;
 
-	sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
-	if (!sp)
-		goto done;
-	ctx = kzalloc(size, GFP_KERNEL);
-	if (!ctx) {
-		mempool_free(sp, ha->srb_mempool);
-		sp = NULL;
-		goto done;
-	}
+	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
 
-	memset(sp, 0, sizeof(*sp));
-	sp->fcport = fcport;
-	sp->ctx = ctx;
-	ctx->iocbs = 1;
-done:
-	return sp;
+	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
+	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+
+	if (sp->type == SRB_CT_CMD ||
+	    sp->type == SRB_ELS_CMD_HST)
+		kfree(sp->fcport);
+	mempool_free(sp, vha->hw->srb_mempool);
 }
 
 int
@@ -101,20 +108,11 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
 	uint32_t len;
 	uint32_t oper;
 
-	bsg_job->reply->reply_payload_rcv_len = 0;
-
 	if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA82XX(ha))) {
 		ret = -EINVAL;
 		goto exit_fcp_prio_cfg;
 	}
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ret = -EBUSY;
-		goto exit_fcp_prio_cfg;
-	}
-
 	/* Get the sub command */
 	oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
 
@@ -224,6 +222,7 @@ exit_fcp_prio_cfg:
 	bsg_job->job_done(bsg_job);
 	return ret;
 }
+
 static int
 qla2x00_process_els(struct fc_bsg_job *bsg_job)
 {
@@ -237,7 +236,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	int req_sg_cnt, rsp_sg_cnt;
 	int rval =  (DRIVER_ERROR << 16);
 	uint16_t nextlid = 0;
-	struct srb_ctx *els;
 
 	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
 		rport = bsg_job->rport;
@@ -344,20 +342,21 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	}
 
 	/* Alloc SRB structure */
-	sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx));
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp) {
 		rval = -ENOMEM;
 		goto done_unmap_sg;
 	}
 
-	els = sp->ctx;
-	els->type =
+	sp->type =
 		(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
 		SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
-	els->name =
+	sp->name =
 		(bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
 		"bsg_els_rpt" : "bsg_els_hst");
-	els->u.bsg_job = bsg_job;
+	sp->u.bsg_job = bsg_job;
+	sp->free = qla2x00_bsg_sp_free;
+	sp->done = qla2x00_bsg_job_done;
 
 	ql_dbg(ql_dbg_user, vha, 0x700a,
 	    "bsg rqst type: %s els type: %x - loop-id=%x "
@@ -369,7 +368,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job)
 	if (rval != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x700e,
 		    "qla2x00_start_sp failed = %d\n", rval);
-		kfree(sp->ctx);
 		mempool_free(sp, ha->srb_mempool);
 		rval = -EIO;
 		goto done_unmap_sg;
@@ -416,7 +414,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 	uint16_t loop_id;
 	struct fc_port *fcport;
 	char  *type = "FC_BSG_HST_CT";
-	struct srb_ctx *ct;
 
 	req_sg_cnt =
 		dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
@@ -493,19 +490,20 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 	fcport->loop_id = loop_id;
 
 	/* Alloc SRB structure */
-	sp = qla2x00_get_ctx_bsg_sp(vha, fcport, sizeof(struct srb_ctx));
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp) {
 		ql_log(ql_log_warn, vha, 0x7015,
-		    "qla2x00_get_ctx_bsg_sp failed.\n");
+		    "qla2x00_get_sp failed.\n");
 		rval = -ENOMEM;
 		goto done_free_fcport;
 	}
 
-	ct = sp->ctx;
-	ct->type = SRB_CT_CMD;
-	ct->name = "bsg_ct";
-	ct->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
-	ct->u.bsg_job = bsg_job;
+	sp->type = SRB_CT_CMD;
+	sp->name = "bsg_ct";
+	sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
+	sp->u.bsg_job = bsg_job;
+	sp->free = qla2x00_bsg_sp_free;
+	sp->done = qla2x00_bsg_job_done;
 
 	ql_dbg(ql_dbg_user, vha, 0x7016,
 	    "bsg rqst type: %s else type: %x - "
@@ -518,7 +516,6 @@ qla2x00_process_ct(struct fc_bsg_job *bsg_job)
 	if (rval != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x7017,
 		    "qla2x00_start_sp failed=%d.\n", rval);
-		kfree(sp->ctx);
 		mempool_free(sp, ha->srb_mempool);
 		rval = -EIO;
 		goto done_free_fcport;
@@ -547,7 +544,7 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
 	int rval = 0;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		goto done_set_internal;
 
 	new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
@@ -589,7 +586,7 @@ qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config,
 	uint16_t new_config[4];
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA81XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		goto done_reset_internal;
 
 	memset(new_config, 0 , sizeof(new_config));
@@ -646,13 +643,6 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 	dma_addr_t rsp_data_dma;
 	uint32_t rsp_data_len;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x7018, "Abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!vha->flags.online) {
 		ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
 		return -EIO;
@@ -721,7 +711,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 
 	if ((ha->current_topology == ISP_CFG_F ||
 	    (atomic_read(&vha->loop_state) == LOOP_DOWN) ||
-	    (IS_QLA81XX(ha) &&
+	    ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) &&
 	    le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
 	    && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
 		elreq.options == EXTERNAL_LOOPBACK) {
@@ -731,13 +721,12 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 		command_sent = INT_DEF_LB_ECHO_CMD;
 		rval = qla2x00_echo_test(vha, &elreq, response);
 	} else {
-		if (IS_QLA81XX(ha)) {
+		if (IS_QLA81XX(ha) || IS_QLA8031(ha)) {
 			memset(config, 0, sizeof(config));
 			memset(new_config, 0, sizeof(new_config));
 			if (qla81xx_get_port_config(vha, config)) {
 				ql_log(ql_log_warn, vha, 0x701f,
 				    "Get port config failed.\n");
-				bsg_job->reply->reply_payload_rcv_len = 0;
 				bsg_job->reply->result = (DID_ERROR << 16);
 				rval = -EPERM;
 				goto done_free_dma_req;
@@ -745,14 +734,12 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 
 			if (elreq.options != EXTERNAL_LOOPBACK) {
 				ql_dbg(ql_dbg_user, vha, 0x7020,
-				    "Internal: curent port config = %x\n",
+				    "Internal: current port config = %x\n",
 				    config[0]);
 				if (qla81xx_set_internal_loopback(vha, config,
 					new_config)) {
 					ql_log(ql_log_warn, vha, 0x7024,
 					    "Internal loopback failed.\n");
-					bsg_job->reply->reply_payload_rcv_len =
-						0;
 					bsg_job->reply->result =
 						(DID_ERROR << 16);
 					rval = -EPERM;
@@ -764,8 +751,6 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 				 */
 				if (qla81xx_reset_internal_loopback(vha,
 					config, 1)) {
-					bsg_job->reply->reply_payload_rcv_len =
-						0;
 					bsg_job->reply->result =
 						(DID_ERROR << 16);
 					rval = -EPERM;
@@ -802,7 +787,6 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 					    "MPI reset failed.\n");
 				}
 
-				bsg_job->reply->reply_payload_rcv_len = 0;
 				bsg_job->reply->result = (DID_ERROR << 16);
 				rval = -EIO;
 				goto done_free_dma_req;
@@ -827,7 +811,6 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
 		fw_sts_ptr += sizeof(response);
 		*fw_sts_ptr = command_sent;
 		rval = 0;
-		bsg_job->reply->reply_payload_rcv_len = 0;
 		bsg_job->reply->result = (DID_ERROR << 16);
 	} else {
 		ql_dbg(ql_dbg_user, vha, 0x702d,
@@ -874,13 +857,6 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
 	int rval = 0;
 	uint32_t flag;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-	    test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x702e, "Abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!IS_QLA84XX(ha)) {
 		ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
 		return -EINVAL;
@@ -893,7 +869,7 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
 	if (rval) {
 		ql_log(ql_log_warn, vha, 0x7030,
 		    "Vendor request 84xx reset failed.\n");
-		rval = bsg_job->reply->reply_payload_rcv_len = 0;
+		rval = 0;
 		bsg_job->reply->result = (DID_ERROR << 16);
 
 	} else {
@@ -922,11 +898,6 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
 	uint32_t flag;
 	uint32_t fw_ver;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags))
-		return -EBUSY;
-
 	if (!IS_QLA84XX(ha)) {
 		ql_dbg(ql_dbg_user, vha, 0x7032,
 		    "Not 84xx, exiting.\n");
@@ -997,9 +968,8 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
 		ql_log(ql_log_warn, vha, 0x7037,
 		    "Vendor request 84xx updatefw failed.\n");
 
-		rval = bsg_job->reply->reply_payload_rcv_len = 0;
+		rval = 0;
 		bsg_job->reply->result = (DID_ERROR << 16);
-
 	} else {
 		ql_dbg(ql_dbg_user, vha, 0x7038,
 		    "Vendor request 84xx updatefw completed.\n");
@@ -1036,14 +1006,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
 	uint32_t data_len = 0;
 	uint32_t dma_direction = DMA_NONE;
 
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x7039,
-		    "Abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!IS_QLA84XX(ha)) {
 		ql_log(ql_log_warn, vha, 0x703a,
 		    "Not 84xx, exiting.\n");
@@ -1193,7 +1155,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
 		ql_log(ql_log_warn, vha, 0x7043,
 		    "Vendor request 84xx mgmt failed.\n");
 
-		rval = bsg_job->reply->reply_payload_rcv_len = 0;
+		rval = 0;
 		bsg_job->reply->result = (DID_ERROR << 16);
 
 	} else {
@@ -1244,15 +1206,6 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	uint8_t *rsp_ptr = NULL;
 
-	bsg_job->reply->reply_payload_rcv_len = 0;
-
-	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
-		test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
-		test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
-		ql_log(ql_log_warn, vha, 0x7045, "abort active or needed.\n");
-		return -EBUSY;
-	}
-
 	if (!IS_IIDMA_CAPABLE(vha->hw)) {
 		ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
 		return -EINVAL;
@@ -1345,8 +1298,6 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
 	int valid = 0;
 	struct qla_hw_data *ha = vha->hw;
 
-	bsg_job->reply->reply_payload_rcv_len = 0;
-
 	if (unlikely(pci_channel_offline(ha->pdev)))
 		return -EINVAL;
 
@@ -1372,7 +1323,7 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
 		    start == (ha->flt_region_fw * 4))
 			valid = 1;
 		else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
-		    IS_QLA8XXX_TYPE(ha))
+		    IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
 			valid = 1;
 		if (!valid) {
 			ql_log(ql_log_warn, vha, 0x7058,
@@ -1658,6 +1609,9 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
 	struct Scsi_Host *host;
 	scsi_qla_host_t *vha;
 
+	/* In case no data transferred. */
+	bsg_job->reply->reply_payload_rcv_len = 0;
+
 	if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
 		rport = bsg_job->rport;
 		fcport = *(fc_port_t **) rport->dd_data;
@@ -1668,6 +1622,15 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
 		vha = shost_priv(host);
 	}
 
+	if (qla2x00_reset_active(vha)) {
+		ql_dbg(ql_dbg_user, vha, 0x709f,
+		    "BSG: ISP abort active/needed -- cmd=%d.\n",
+		    bsg_job->request->msgcode);
+		bsg_job->reply->result = (DID_ERROR << 16);
+		bsg_job->job_done(bsg_job);
+		return -EBUSY;
+	}
+
 	ql_dbg(ql_dbg_user, vha, 0x7000,
 	    "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
 
@@ -1687,6 +1650,7 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
 	case FC_BSG_RPT_CT:
 	default:
 		ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
+		bsg_job->reply->result = ret;
 		break;
 	}
 	return ret;
@@ -1701,7 +1665,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
 	int cnt, que;
 	unsigned long flags;
 	struct req_que *req;
-	struct srb_ctx *sp_bsg;
 
 	/* find the bsg job from the active list of commands */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1713,11 +1676,9 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
 		for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
 			sp = req->outstanding_cmds[cnt];
 			if (sp) {
-				sp_bsg = sp->ctx;
-
-				if (((sp_bsg->type == SRB_CT_CMD) ||
-					(sp_bsg->type == SRB_ELS_CMD_HST))
-					&& (sp_bsg->u.bsg_job == bsg_job)) {
+				if (((sp->type == SRB_CT_CMD) ||
+					(sp->type == SRB_ELS_CMD_HST))
+					&& (sp->u.bsg_job == bsg_job)) {
 					spin_unlock_irqrestore(&ha->hardware_lock, flags);
 					if (ha->isp_ops->abort_command(sp)) {
 						ql_log(ql_log_warn, vha, 0x7089,
@@ -1747,7 +1708,6 @@ done:
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	if (bsg_job->request->msgcode == FC_BSG_HST_CT)
 		kfree(sp->fcport);
-	kfree(sp->ctx);
 	mempool_free(sp, ha->srb_mempool);
 	return 0;
 }
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 7c54624..897731b 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,22 +11,27 @@
  * ----------------------------------------------------------------------
  * |             Level            |   Last Value Used  |     Holes	|
  * ----------------------------------------------------------------------
- * | Module Init and Probe        |       0x0116       | 0xfa           |
- * | Mailbox commands             |       0x112b       |		|
- * | Device Discovery             |       0x2084       |		|
- * | Queue Command and IO tracing |       0x302f       | 0x3008,0x302d, |
- * |                              |                    | 0x302e         |
+ * | Module Init and Probe        |       0x0120       | 0x4b,0xba,0xfa |
+ * | Mailbox commands             |       0x113e       | 0x112c-0x112e  |
+ * |                              |                    | 0x113a         |
+ * | Device Discovery             |       0x2086       | 0x2020-0x2022  |
+ * | Queue Command and IO tracing |       0x302f       | 0x3006,0x3008  |
+ * |                              |                    | 0x302d-0x302e  |
  * | DPC Thread                   |       0x401c       |		|
- * | Async Events                 |       0x5057       | 0x5052		|
- * | Timer Routines               |       0x6011       | 0x600e,0x600f  |
- * | User Space Interactions      |       0x709e       |		|
+ * | Async Events                 |       0x505d       | 0x502b-0x502f  |
+ * |                              |                    | 0x5047,0x5052  |
+ * | Timer Routines               |       0x6011       | 0x600e-0x600f  |
+ * | User Space Interactions      |       0x709f       | 0x7018,0x702e, |
+ * |                              |                    | 0x7039,0x7045, |
+ * |                              |                    | 0x7073-0x7075, |
+ * |                              |                    | 0x708c         |
  * | Task Management              |       0x803c       | 0x8025-0x8026  |
  * |                              |                    | 0x800b,0x8039  |
  * | AER/EEH                      |       0x900f       |		|
  * | Virtual Port                 |       0xa007       |		|
- * | ISP82XX Specific             |       0xb052       |    		|
- * | MultiQ                       |       0xc00b       |		|
- * | Misc                         |       0xd00b       |		|
+ * | ISP82XX Specific             |       0xb054       | 0xb053         |
+ * | MultiQ                       |       0xc00c       |		|
+ * | Misc                         |       0xd010       |		|
  * ----------------------------------------------------------------------
  */
 
@@ -84,7 +89,7 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
 	WRT_REG_WORD(&reg->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 
-	dwords = GID_LIST_SIZE / 4;
+	dwords = qla2x00_gid_list_size(ha) / 4;
 	for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
 	    cnt += dwords, addr += dwords) {
 		if (cnt + dwords > ram_dwords)
@@ -259,7 +264,7 @@ qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
 	WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 
-	words = GID_LIST_SIZE / 2;
+	words = qla2x00_gid_list_size(ha) / 2;
 	for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
 	    cnt += words, addr += words) {
 		if (cnt + words > ram_words)
@@ -374,6 +379,77 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
 }
 
 static inline void *
+qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
+{
+	struct qla2xxx_mqueue_chain *q;
+	struct qla2xxx_mqueue_header *qh;
+	struct req_que *req;
+	struct rsp_que *rsp;
+	int que;
+
+	if (!ha->mqenable)
+		return ptr;
+
+	/* Request queues */
+	for (que = 1; que < ha->max_req_queues; que++) {
+		req = ha->req_q_map[que];
+		if (!req)
+			break;
+
+		/* Add chain. */
+		q = ptr;
+		*last_chain = &q->type;
+		q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
+		q->chain_size = htonl(
+		    sizeof(struct qla2xxx_mqueue_chain) +
+		    sizeof(struct qla2xxx_mqueue_header) +
+		    (req->length * sizeof(request_t)));
+		ptr += sizeof(struct qla2xxx_mqueue_chain);
+
+		/* Add header. */
+		qh = ptr;
+		qh->queue = __constant_htonl(TYPE_REQUEST_QUEUE);
+		qh->number = htonl(que);
+		qh->size = htonl(req->length * sizeof(request_t));
+		ptr += sizeof(struct qla2xxx_mqueue_header);
+
+		/* Add data. */
+		memcpy(ptr, req->ring, req->length * sizeof(request_t));
+		ptr += req->length * sizeof(request_t);
+	}
+
+	/* Response queues */
+	for (que = 1; que < ha->max_rsp_queues; que++) {
+		rsp = ha->rsp_q_map[que];
+		if (!rsp)
+			break;
+
+		/* Add chain. */
+		q = ptr;
+		*last_chain = &q->type;
+		q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
+		q->chain_size = htonl(
+		    sizeof(struct qla2xxx_mqueue_chain) +
+		    sizeof(struct qla2xxx_mqueue_header) +
+		    (rsp->length * sizeof(response_t)));
+		ptr += sizeof(struct qla2xxx_mqueue_chain);
+
+		/* Add header. */
+		qh = ptr;
+		qh->queue = __constant_htonl(TYPE_RESPONSE_QUEUE);
+		qh->number = htonl(que);
+		qh->size = htonl(rsp->length * sizeof(response_t));
+		ptr += sizeof(struct qla2xxx_mqueue_header);
+
+		/* Add data. */
+		memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t));
+		ptr += rsp->length * sizeof(response_t);
+	}
+
+	return ptr;
+}
+
+static inline void *
 qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
 {
 	uint32_t cnt, que_idx;
@@ -381,7 +457,7 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
 	struct qla2xxx_mq_chain *mq = ptr;
 	struct device_reg_25xxmq __iomem *reg;
 
-	if (!ha->mqenable)
+	if (!ha->mqenable || IS_QLA83XX(ha))
 		return ptr;
 
 	mq = ptr;
@@ -1321,12 +1397,16 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 	nxt = qla24xx_copy_eft(ha, nxt);
 
 	/* Chain entries -- started with MQ. */
-	qla25xx_copy_fce(ha, nxt_chain, &last_chain);
+	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
+	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
 	if (last_chain) {
 		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
 		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
 	}
 
+	/* Adjust valid length. */
+	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
+
 qla25xx_fw_dump_failed_0:
 	qla2xxx_dump_post_process(base_vha, rval);
 
@@ -1635,12 +1715,16 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
 	nxt = qla24xx_copy_eft(ha, nxt);
 
 	/* Chain entries -- started with MQ. */
-	qla25xx_copy_fce(ha, nxt_chain, &last_chain);
+	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
+	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
 	if (last_chain) {
 		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
 		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
 	}
 
+	/* Adjust valid length. */
+	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
+
 qla81xx_fw_dump_failed_0:
 	qla2xxx_dump_post_process(base_vha, rval);
 
@@ -1649,6 +1733,507 @@ qla81xx_fw_dump_failed:
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
+void
+qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
+{
+	int		rval;
+	uint32_t	cnt, reg_data;
+	uint32_t	risc_address;
+	struct qla_hw_data *ha = vha->hw;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	uint32_t __iomem *dmp_reg;
+	uint32_t	*iter_reg;
+	uint16_t __iomem *mbx_reg;
+	unsigned long	flags;
+	struct qla83xx_fw_dump *fw;
+	uint32_t	ext_mem_cnt;
+	void		*nxt, *nxt_chain;
+	uint32_t	*last_chain = NULL;
+	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
+
+	risc_address = ext_mem_cnt = 0;
+	flags = 0;
+
+	if (!hardware_locked)
+		spin_lock_irqsave(&ha->hardware_lock, flags);
+
+	if (!ha->fw_dump) {
+		ql_log(ql_log_warn, vha, 0xd00c,
+		    "No buffer available for dump!!!\n");
+		goto qla83xx_fw_dump_failed;
+	}
+
+	if (ha->fw_dumped) {
+		ql_log(ql_log_warn, vha, 0xd00d,
+		    "Firmware has been previously dumped (%p) -- ignoring "
+		    "request...\n", ha->fw_dump);
+		goto qla83xx_fw_dump_failed;
+	}
+	fw = &ha->fw_dump->isp.isp83;
+	qla2xxx_prep_dump(ha, ha->fw_dump);
+
+	fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
+
+	/* Pause RISC. */
+	rval = qla24xx_pause_risc(reg);
+	if (rval != QLA_SUCCESS)
+		goto qla83xx_fw_dump_failed_0;
+
+	WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
+	dmp_reg = &reg->iobase_window;
+	reg_data = RD_REG_DWORD(dmp_reg);
+	WRT_REG_DWORD(dmp_reg, 0);
+
+	dmp_reg = &reg->unused_4_1[0];
+	reg_data = RD_REG_DWORD(dmp_reg);
+	WRT_REG_DWORD(dmp_reg, 0);
+
+	WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
+	dmp_reg = &reg->unused_4_1[2];
+	reg_data = RD_REG_DWORD(dmp_reg);
+	WRT_REG_DWORD(dmp_reg, 0);
+
+	/* select PCR and disable ecc checking and correction */
+	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
+	RD_REG_DWORD(&reg->iobase_addr);
+	WRT_REG_DWORD(&reg->iobase_select, 0x60000000);	/* write to F0h = PCR */
+
+	/* Host/Risc registers. */
+	iter_reg = fw->host_risc_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7040, 16, iter_reg);
+
+	/* PCIe registers. */
+	WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
+	RD_REG_DWORD(&reg->iobase_addr);
+	WRT_REG_DWORD(&reg->iobase_window, 0x01);
+	dmp_reg = &reg->iobase_c4;
+	fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
+	fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
+	fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
+	fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
+
+	WRT_REG_DWORD(&reg->iobase_window, 0x00);
+	RD_REG_DWORD(&reg->iobase_window);
+
+	/* Host interface registers. */
+	dmp_reg = &reg->flash_addr;
+	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
+		fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+	/* Disable interrupts. */
+	WRT_REG_DWORD(&reg->ictrl, 0);
+	RD_REG_DWORD(&reg->ictrl);
+
+	/* Shadow registers. */
+	WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
+	RD_REG_DWORD(&reg->iobase_addr);
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
+	fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
+	fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
+	fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
+	fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
+	fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
+	fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
+	fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
+	fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
+	fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
+	fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
+	fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+	/* RISC I/O register. */
+	WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
+	fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
+
+	/* Mailbox registers. */
+	mbx_reg = &reg->mailbox0;
+	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
+		fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
+
+	/* Transfer sequence registers. */
+	iter_reg = fw->xseq_gp_reg;
+	iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
+	qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
+
+	iter_reg = fw->xseq_0_reg;
+	iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
+	qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
+
+	qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
+
+	qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg);
+
+	/* Receive sequence registers. */
+	iter_reg = fw->rseq_gp_reg;
+	iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
+	qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
+
+	iter_reg = fw->rseq_0_reg;
+	iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
+	qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
+
+	qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
+	qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
+	qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg);
+
+	/* Auxiliary sequence registers. */
+	iter_reg = fw->aseq_gp_reg;
+	iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg);
+	qla24xx_read_window(reg, 0xB170, 16, iter_reg);
+
+	iter_reg = fw->aseq_0_reg;
+	iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
+	qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
+
+	qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
+	qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
+	qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg);
+
+	/* Command DMA registers. */
+	iter_reg = fw->cmd_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg);
+	qla24xx_read_window(reg, 0x71F0, 16, iter_reg);
+
+	/* Queues. */
+	iter_reg = fw->req0_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
+	dmp_reg = &reg->iobase_q;
+	for (cnt = 0; cnt < 7; cnt++)
+		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+	iter_reg = fw->resp0_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
+	dmp_reg = &reg->iobase_q;
+	for (cnt = 0; cnt < 7; cnt++)
+		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+	iter_reg = fw->req1_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
+	dmp_reg = &reg->iobase_q;
+	for (cnt = 0; cnt < 7; cnt++)
+		*iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+	/* Transmit DMA registers. */
+	iter_reg = fw->xmt0_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7610, 16, iter_reg);
+
+	iter_reg = fw->xmt1_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7630, 16, iter_reg);
+
+	iter_reg = fw->xmt2_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7650, 16, iter_reg);
+
+	iter_reg = fw->xmt3_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7670, 16, iter_reg);
+
+	iter_reg = fw->xmt4_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7690, 16, iter_reg);
+
+	qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
+
+	/* Receive DMA registers. */
+	iter_reg = fw->rcvt0_data_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7710, 16, iter_reg);
+
+	iter_reg = fw->rcvt1_data_dma_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
+	qla24xx_read_window(reg, 0x7730, 16, iter_reg);
+
+	/* RISC registers. */
+	iter_reg = fw->risc_gp_reg;
+	iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
+	qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
+
+	/* Local memory controller registers. */
+	iter_reg = fw->lmc_reg;
+	iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
+	qla24xx_read_window(reg, 0x3070, 16, iter_reg);
+
+	/* Fibre Protocol Module registers. */
+	iter_reg = fw->fpm_hdw_reg;
+	iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x40F0, 16, iter_reg);
+
+	/* RQ0 Array registers. */
+	iter_reg = fw->rq0_array_reg;
+	iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x5CF0, 16, iter_reg);
+
+	/* RQ1 Array registers. */
+	iter_reg = fw->rq1_array_reg;
+	iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x5DF0, 16, iter_reg);
+
+	/* RP0 Array registers. */
+	iter_reg = fw->rp0_array_reg;
+	iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x5EF0, 16, iter_reg);
+
+	/* RP1 Array registers. */
+	iter_reg = fw->rp1_array_reg;
+	iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x5FF0, 16, iter_reg);
+
+	iter_reg = fw->at0_array_reg;
+	iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x70F0, 16, iter_reg);
+
+	/* I/O Queue Control registers. */
+	qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg);
+
+	/* Frame Buffer registers. */
+	iter_reg = fw->fb_hdw_reg;
+	iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg);
+	iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg);
+	qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
+
+	/* Multi queue registers */
+	nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
+	    &last_chain);
+
+	rval = qla24xx_soft_reset(ha);
+	if (rval != QLA_SUCCESS) {
+		ql_log(ql_log_warn, vha, 0xd00e,
+		    "SOFT RESET FAILED, forcing continuation of dump!!!\n");
+		rval = QLA_SUCCESS;
+
+		ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n");
+
+		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
+		RD_REG_DWORD(&reg->hccr);
+
+		WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+		RD_REG_DWORD(&reg->hccr);
+
+		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
+		RD_REG_DWORD(&reg->hccr);
+
+		for (cnt = 30000; cnt && (RD_REG_WORD(&reg->mailbox0)); cnt--)
+			udelay(5);
+
+		if (!cnt) {
+			nxt = fw->code_ram;
+			nxt += sizeof(fw->code_ram),
+			nxt += (ha->fw_memory_size - 0x100000 + 1);
+			goto copy_queue;
+		} else
+			ql_log(ql_log_warn, vha, 0xd010,
+			    "bigger hammer success?\n");
+	}
+
+	rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
+	    &nxt);
+	if (rval != QLA_SUCCESS)
+		goto qla83xx_fw_dump_failed_0;
+
+copy_queue:
+	nxt = qla2xxx_copy_queues(ha, nxt);
+
+	nxt = qla24xx_copy_eft(ha, nxt);
+
+	/* Chain entries -- started with MQ. */
+	nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
+	nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
+	if (last_chain) {
+		ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
+		*last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
+	}
+
+	/* Adjust valid length. */
+	ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
+
+qla83xx_fw_dump_failed_0:
+	qla2xxx_dump_post_process(base_vha, rval);
+
+qla83xx_fw_dump_failed:
+	if (!hardware_locked)
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
 /****************************************************************************/
 /*                         Driver Debug Functions.                          */
 /****************************************************************************/
@@ -1781,13 +2366,13 @@ ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
 	vaf.va = &va;
 
 	switch (level) {
-	case 0: /* FATAL LOG */
+	case ql_log_fatal: /* FATAL LOG */
 		pr_crit("%s%pV", pbuf, &vaf);
 		break;
-	case 1:
+	case ql_log_warn:
 		pr_err("%s%pV", pbuf, &vaf);
 		break;
-	case 2:
+	case ql_log_info:
 		pr_warn("%s%pV", pbuf, &vaf);
 		break;
 	default:
@@ -1836,13 +2421,13 @@ ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
 	vaf.va = &va;
 
 	switch (level) {
-	case 0: /* FATAL LOG */
+	case ql_log_fatal: /* FATAL LOG */
 		pr_crit("%s%pV", pbuf, &vaf);
 		break;
-	case 1:
+	case ql_log_warn:
 		pr_err("%s%pV", pbuf, &vaf);
 		break;
-	case 2:
+	case ql_log_info:
 		pr_warn("%s%pV", pbuf, &vaf);
 		break;
 	default:
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
index 5f1b6d9..2157bdf 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -165,6 +165,54 @@ struct qla81xx_fw_dump {
 	uint32_t ext_mem[1];
 };
 
+struct qla83xx_fw_dump {
+	uint32_t host_status;
+	uint32_t host_risc_reg[48];
+	uint32_t pcie_regs[4];
+	uint32_t host_reg[32];
+	uint32_t shadow_reg[11];
+	uint32_t risc_io_reg;
+	uint16_t mailbox_reg[32];
+	uint32_t xseq_gp_reg[256];
+	uint32_t xseq_0_reg[48];
+	uint32_t xseq_1_reg[16];
+	uint32_t xseq_2_reg[16];
+	uint32_t rseq_gp_reg[256];
+	uint32_t rseq_0_reg[32];
+	uint32_t rseq_1_reg[16];
+	uint32_t rseq_2_reg[16];
+	uint32_t rseq_3_reg[16];
+	uint32_t aseq_gp_reg[256];
+	uint32_t aseq_0_reg[32];
+	uint32_t aseq_1_reg[16];
+	uint32_t aseq_2_reg[16];
+	uint32_t aseq_3_reg[16];
+	uint32_t cmd_dma_reg[64];
+	uint32_t req0_dma_reg[15];
+	uint32_t resp0_dma_reg[15];
+	uint32_t req1_dma_reg[15];
+	uint32_t xmt0_dma_reg[32];
+	uint32_t xmt1_dma_reg[32];
+	uint32_t xmt2_dma_reg[32];
+	uint32_t xmt3_dma_reg[32];
+	uint32_t xmt4_dma_reg[32];
+	uint32_t xmt_data_dma_reg[16];
+	uint32_t rcvt0_data_dma_reg[32];
+	uint32_t rcvt1_data_dma_reg[32];
+	uint32_t risc_gp_reg[128];
+	uint32_t lmc_reg[128];
+	uint32_t fpm_hdw_reg[256];
+	uint32_t rq0_array_reg[256];
+	uint32_t rq1_array_reg[256];
+	uint32_t rp0_array_reg[256];
+	uint32_t rp1_array_reg[256];
+	uint32_t queue_control_reg[16];
+	uint32_t fb_hdw_reg[432];
+	uint32_t at0_array_reg[128];
+	uint32_t code_ram[0x2400];
+	uint32_t ext_mem[1];
+};
+
 #define EFT_NUM_BUFFERS		4
 #define EFT_BYTES_PER_BUFFER	0x4000
 #define EFT_SIZE		((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS))
@@ -192,9 +240,23 @@ struct qla2xxx_mq_chain {
 	uint32_t qregs[4 * QLA_MQ_SIZE];
 };
 
+struct qla2xxx_mqueue_header {
+	uint32_t queue;
+#define TYPE_REQUEST_QUEUE	0x1
+#define TYPE_RESPONSE_QUEUE	0x2
+	uint32_t number;
+	uint32_t size;
+};
+
+struct qla2xxx_mqueue_chain {
+	uint32_t type;
+	uint32_t chain_size;
+};
+
 #define DUMP_CHAIN_VARIANT	0x80000000
 #define DUMP_CHAIN_FCE		0x7FFFFAF0
 #define DUMP_CHAIN_MQ		0x7FFFFAF1
+#define DUMP_CHAIN_QUEUE	0x7FFFFAF2
 #define DUMP_CHAIN_LAST		0x80000000
 
 struct qla2xxx_fw_dump {
@@ -228,6 +290,7 @@ struct qla2xxx_fw_dump {
 		struct qla24xx_fw_dump isp24;
 		struct qla25xx_fw_dump isp25;
 		struct qla81xx_fw_dump isp81;
+		struct qla83xx_fw_dump isp83;
 	} isp;
 };
 
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index a6a4eeb..a244303 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -44,6 +44,7 @@
  * ISP2100 HBAs.
  */
 #define MAILBOX_REGISTER_COUNT_2100	8
+#define MAILBOX_REGISTER_COUNT_2200	24
 #define MAILBOX_REGISTER_COUNT		32
 
 #define QLA2200A_RISC_ROM_VER	4
@@ -124,17 +125,17 @@
  * Fibre Channel device definitions.
  */
 #define WWN_SIZE		8	/* Size of WWPN, WWN & WWNN */
-#define MAX_FIBRE_DEVICES	512
+#define MAX_FIBRE_DEVICES_2100	512
+#define MAX_FIBRE_DEVICES_2400	2048
+#define MAX_FIBRE_DEVICES_LOOP	128
+#define MAX_FIBRE_DEVICES_MAX	MAX_FIBRE_DEVICES_2400
 #define MAX_FIBRE_LUNS  	0xFFFF
-#define	MAX_RSCN_COUNT		32
 #define	MAX_HOST_COUNT		16
 
 /*
  * Host adapter default definitions.
  */
 #define MAX_BUSES		1  /* We only have one bus today */
-#define MAX_TARGETS_2100	MAX_FIBRE_DEVICES
-#define MAX_TARGETS_2200	MAX_FIBRE_DEVICES
 #define MIN_LUNS		8
 #define MAX_LUNS		MAX_FIBRE_LUNS
 #define MAX_CMDS_PER_LUN	255
@@ -201,20 +202,12 @@ struct sd_dif_tuple {
 /*
  * SCSI Request Block
  */
-typedef struct srb {
-	atomic_t ref_count;
-	struct fc_port *fcport;
-	uint32_t handle;
-
+struct srb_cmd {
 	struct scsi_cmnd *cmd;		/* Linux SCSI command pkt */
-
-	uint16_t flags;
-
 	uint32_t request_sense_length;
 	uint8_t *request_sense_ptr;
-
 	void *ctx;
-} srb_t;
+};
 
 /*
  * SRB flag definitions
@@ -253,10 +246,7 @@ struct srb_iocb {
 	} u;
 
 	struct timer_list timer;
-
-	void (*done)(srb_t *);
-	void (*free)(srb_t *);
-	void (*timeout)(srb_t *);
+	void (*timeout)(void *);
 };
 
 /* Values for srb_ctx type */
@@ -267,16 +257,37 @@ struct srb_iocb {
 #define SRB_CT_CMD	5
 #define SRB_ADISC_CMD	6
 #define SRB_TM_CMD	7
+#define SRB_SCSI_CMD	8
 
-struct srb_ctx {
+typedef struct srb {
+	atomic_t ref_count;
+	struct fc_port *fcport;
+	uint32_t handle;
+	uint16_t flags;
 	uint16_t type;
 	char *name;
 	int iocbs;
 	union {
-		struct srb_iocb *iocb_cmd;
+		struct srb_iocb iocb_cmd;
 		struct fc_bsg_job *bsg_job;
+		struct srb_cmd scmd;
 	} u;
-};
+	void (*done)(void *, void *, int);
+	void (*free)(void *, void *);
+} srb_t;
+
+#define GET_CMD_SP(sp) (sp->u.scmd.cmd)
+#define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd)
+#define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx)
+
+#define GET_CMD_SENSE_LEN(sp) \
+	(sp->u.scmd.request_sense_length)
+#define SET_CMD_SENSE_LEN(sp, len) \
+	(sp->u.scmd.request_sense_length = len)
+#define GET_CMD_SENSE_PTR(sp) \
+	(sp->u.scmd.request_sense_ptr)
+#define SET_CMD_SENSE_PTR(sp, ptr) \
+	(sp->u.scmd.request_sense_ptr = ptr)
 
 struct msg_echo_lb {
 	dma_addr_t send_dma;
@@ -652,8 +663,10 @@ typedef struct {
 #define MBC_DIAGNOSTIC_LOOP_BACK	0x45	/* Diagnostic loop back. */
 #define MBC_ONLINE_SELF_TEST		0x46	/* Online self-test. */
 #define MBC_ENHANCED_GET_PORT_DATABASE	0x47	/* Get port database + login */
+#define MBC_CONFIGURE_VF		0x4b	/* Configure VFs */
 #define MBC_RESET_LINK_STATUS		0x52	/* Reset Link Error Status */
 #define MBC_IOCB_COMMAND_A64		0x54	/* Execute IOCB command (64) */
+#define MBC_PORT_LOGOUT			0x56	/* Port Logout request */
 #define MBC_SEND_RNID_ELS		0x57	/* Send RNID ELS request */
 #define MBC_SET_RNID_PARAMS		0x59	/* Set RNID parameters */
 #define MBC_GET_RNID_PARAMS		0x5a	/* Data Rate */
@@ -1708,6 +1721,7 @@ typedef struct fc_port {
 
 	uint16_t vp_idx;
 	uint8_t fc4_type;
+	uint8_t scan_state;
 } fc_port_t;
 
 /*
@@ -1760,7 +1774,6 @@ static const char * const port_state_str[] = {
 
 #define	GID_PT_CMD	0x1A1
 #define	GID_PT_REQ_SIZE	(16 + 4)
-#define	GID_PT_RSP_SIZE	(16 + (MAX_FIBRE_DEVICES * 4))
 
 #define	GPN_ID_CMD	0x112
 #define	GPN_ID_REQ_SIZE	(16 + 4)
@@ -2050,7 +2063,9 @@ struct ct_sns_rsp {
 		} ga_nxt;
 
 		struct {
-			struct ct_sns_gid_pt_data entries[MAX_FIBRE_DEVICES];
+			/* Assume the largest number of targets for the union */
+			struct ct_sns_gid_pt_data
+			    entries[MAX_FIBRE_DEVICES_MAX];
 		} gid_pt;
 
 		struct {
@@ -2111,7 +2126,11 @@ struct ct_sns_pkt {
 
 #define	GID_PT_SNS_SCMD_LEN	6
 #define	GID_PT_SNS_CMD_SIZE	28
-#define	GID_PT_SNS_DATA_SIZE	(MAX_FIBRE_DEVICES * 4 + 16)
+/*
+ * Assume MAX_FIBRE_DEVICES_2100 as these defines are only used with older
+ * adapters.
+ */
+#define	GID_PT_SNS_DATA_SIZE	(MAX_FIBRE_DEVICES_2100 * 4 + 16)
 
 #define	GPN_ID_SNS_SCMD_LEN	6
 #define	GPN_ID_SNS_CMD_SIZE	28
@@ -2159,7 +2178,6 @@ struct gid_list_info {
 	uint16_t loop_id;	/* ISP23XX         -- 6 bytes. */
 	uint16_t reserved_1;	/* ISP24XX         -- 8 bytes. */
 };
-#define GID_LIST_SIZE (sizeof(struct gid_list_info) * MAX_FIBRE_DEVICES)
 
 /* NPIV */
 typedef struct vport_info {
@@ -2260,6 +2278,7 @@ struct isp_operations {
 #define QLA_MIDX_DEFAULT	0
 #define QLA_MIDX_RSP_Q		1
 #define QLA_PCI_MSIX_CONTROL	0xa2
+#define QLA_83XX_PCI_MSIX_CONTROL	0x92
 
 struct scsi_qla_host;
 
@@ -2340,7 +2359,7 @@ struct qla_statistics {
 #define QLA_MQ_SIZE 32
 #define QLA_MAX_QUEUES 256
 #define ISP_QUE_REG(ha, id) \
-	((ha->mqenable) ? \
+	((ha->mqenable || IS_QLA83XX(ha)) ? \
 	((void *)(ha->mqiobase) +\
 	(QLA_QUE_PAGE * id)) :\
 	((void *)(ha->iobase)))
@@ -2460,6 +2479,7 @@ struct qla_hw_data {
 #define MIN_IOBASE_LEN          0x100
 /* Multi queue data structs */
 	device_reg_t __iomem *mqiobase;
+	device_reg_t __iomem *msixbase;
 	uint16_t        msix_count;
 	uint8_t         mqenable;
 	struct req_que **req_q_map;
@@ -2484,6 +2504,7 @@ struct qla_hw_data {
 	atomic_t	loop_down_timer;         /* loop down timer */
 	uint8_t		link_down_timeout;       /* link down timeout */
 	uint16_t	max_loop_id;
+	uint16_t	max_fibre_devices;	/* Maximum number of targets */
 
 	uint16_t	fb_rev;
 	uint16_t	min_external_loopid;    /* First external loop Id */
@@ -2493,6 +2514,7 @@ struct qla_hw_data {
 #define PORT_SPEED_2GB  0x01
 #define PORT_SPEED_4GB  0x03
 #define PORT_SPEED_8GB  0x04
+#define PORT_SPEED_16GB 0x05
 #define PORT_SPEED_10GB	0x13
 	uint16_t	link_data_rate;         /* F/W operating speed */
 
@@ -2514,6 +2536,8 @@ struct qla_hw_data {
 #define PCI_DEVICE_ID_QLOGIC_ISP2532    0x2532
 #define PCI_DEVICE_ID_QLOGIC_ISP8432    0x8432
 #define PCI_DEVICE_ID_QLOGIC_ISP8001	0x8001
+#define PCI_DEVICE_ID_QLOGIC_ISP8031	0x8031
+#define PCI_DEVICE_ID_QLOGIC_ISP2031	0x2031
 	uint32_t	device_type;
 #define DT_ISP2100                      BIT_0
 #define DT_ISP2200                      BIT_1
@@ -2530,7 +2554,9 @@ struct qla_hw_data {
 #define DT_ISP8432                      BIT_12
 #define DT_ISP8001			BIT_13
 #define DT_ISP8021			BIT_14
-#define DT_ISP_LAST			(DT_ISP8021 << 1)
+#define DT_ISP2031			BIT_15
+#define DT_ISP8031			BIT_16
+#define DT_ISP_LAST			(DT_ISP8031 << 1)
 
 #define DT_T10_PI                       BIT_25
 #define DT_IIDMA                        BIT_26
@@ -2554,26 +2580,30 @@ struct qla_hw_data {
 #define IS_QLA2532(ha)  (DT_MASK(ha) & DT_ISP2532)
 #define IS_QLA8432(ha)  (DT_MASK(ha) & DT_ISP8432)
 #define IS_QLA8001(ha)	(DT_MASK(ha) & DT_ISP8001)
+#define IS_QLA81XX(ha)	(IS_QLA8001(ha))
 #define IS_QLA82XX(ha)	(DT_MASK(ha) & DT_ISP8021)
+#define IS_QLA2031(ha)	(DT_MASK(ha) & DT_ISP2031)
+#define IS_QLA8031(ha)	(DT_MASK(ha) & DT_ISP8031)
 
 #define IS_QLA23XX(ha)  (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
 			IS_QLA6312(ha) || IS_QLA6322(ha))
 #define IS_QLA24XX(ha)  (IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA54XX(ha)  (IS_QLA5422(ha) || IS_QLA5432(ha))
 #define IS_QLA25XX(ha)  (IS_QLA2532(ha))
+#define IS_QLA83XX(ha)	(IS_QLA2031(ha) || IS_QLA8031(ha))
 #define IS_QLA84XX(ha)  (IS_QLA8432(ha))
 #define IS_QLA24XX_TYPE(ha)     (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
 				IS_QLA84XX(ha))
-#define IS_QLA81XX(ha)		(IS_QLA8001(ha))
-#define IS_QLA8XXX_TYPE(ha)	(IS_QLA81XX(ha) || IS_QLA82XX(ha))
+#define IS_CNA_CAPABLE(ha)	(IS_QLA81XX(ha) || IS_QLA82XX(ha) || \
+				IS_QLA8031(ha))
 #define IS_QLA2XXX_MIDTYPE(ha)	(IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
 				IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
-				IS_QLA82XX(ha))
-#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha))
-#define IS_NOPOLLING_TYPE(ha)	((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
-				(ha)->flags.msix_enabled)
-#define IS_FAC_REQUIRED(ha)	(IS_QLA81XX(ha))
-#define IS_NOCACHE_VPD_TYPE(ha)	(IS_QLA81XX(ha))
+				IS_QLA82XX(ha) || IS_QLA83XX(ha))
+#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha))
+#define IS_NOPOLLING_TYPE(ha)	((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
+			IS_QLA83XX(ha)) && (ha)->flags.msix_enabled)
+#define IS_FAC_REQUIRED(ha)	(IS_QLA81XX(ha) || IS_QLA83XX(ha))
+#define IS_NOCACHE_VPD_TYPE(ha)	(IS_QLA81XX(ha) || IS_QLA83XX(ha))
 #define IS_ALOGIO_CAPABLE(ha)	(IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
 
 #define IS_T10_PI_CAPABLE(ha)   ((ha)->device_type & DT_T10_PI)
@@ -2582,6 +2612,8 @@ struct qla_hw_data {
 #define IS_ZIO_SUPPORTED(ha)    ((ha)->device_type & DT_ZIO_SUPPORTED)
 #define IS_OEM_001(ha)          ((ha)->device_type & DT_OEM_001)
 #define HAS_EXTENDED_IDS(ha)    ((ha)->device_type & DT_EXTENDED_IDS)
+#define IS_CT6_SUPPORTED(ha)	((ha)->device_type & DT_CT6_SUPPORTED)
+#define IS_MQUE_CAPABLE(ha)	((ha)->mqenable || IS_QLA83XX(ha))
 
 	/* HBA serial number */
 	uint8_t		serial0;
@@ -2620,10 +2652,6 @@ struct qla_hw_data {
 	void		*sfp_data;
 	dma_addr_t	sfp_data_dma;
 
-	uint8_t		*edc_data;
-	dma_addr_t	edc_data_dma;
-	uint16_t	edc_data_len;
-
 #define XGMAC_DATA_SIZE	4096
 	void		*xgmac_data;
 	dma_addr_t	xgmac_data_dma;
@@ -2652,6 +2680,8 @@ struct qla_hw_data {
 	void		*async_pd;
 	dma_addr_t	async_pd_dma;
 
+	void		*swl;
+
 	/* These are used by mailbox operations. */
 	volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
 
@@ -2673,6 +2703,8 @@ struct qla_hw_data {
 	uint16_t	fw_minor_version;
 	uint16_t	fw_subminor_version;
 	uint16_t	fw_attributes;
+	uint16_t	fw_attributes_h;
+	uint16_t	fw_attributes_ext[2];
 	uint32_t	fw_memory_size;
 	uint32_t	fw_transfer_size;
 	uint32_t	fw_srisc_address;
@@ -2850,7 +2882,6 @@ typedef struct scsi_qla_host {
 	volatile struct {
 		uint32_t	init_done		:1;
 		uint32_t	online			:1;
-		uint32_t	rscn_queue_overflow	:1;
 		uint32_t	reset_active		:1;
 
 		uint32_t	management_server_logged_in :1;
@@ -2904,11 +2935,6 @@ typedef struct scsi_qla_host {
 
 
 
-	/* RSCN queue. */
-	uint32_t rscn_queue[MAX_RSCN_COUNT];
-	uint8_t rscn_in_ptr;
-	uint8_t rscn_out_ptr;
-
 	/* Timeout timers. */
 	uint8_t         loop_down_abort_time;    /* port down timer */
 	atomic_t        loop_down_timer;         /* loop down timer */
@@ -3004,7 +3030,6 @@ typedef struct scsi_qla_host {
 #define QLA_ABORTED			0x105
 #define QLA_SUSPENDED			0x106
 #define QLA_BUSY			0x107
-#define QLA_RSCNS_HANDLED		0x108
 #define QLA_ALREADY_REGISTERED		0x109
 
 #define NVRAM_DELAY()		udelay(10)
@@ -3020,6 +3045,7 @@ typedef struct scsi_qla_host {
 #define OPTROM_SIZE_25XX	0x200000
 #define OPTROM_SIZE_81XX	0x400000
 #define OPTROM_SIZE_82XX	0x800000
+#define OPTROM_SIZE_83XX	0x1000000
 
 #define OPTROM_BURST_SIZE	0x1000
 #define OPTROM_BURST_DWORDS	(OPTROM_BURST_SIZE / 4)
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index 0b4c2b7..499c74e 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -114,7 +114,7 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
 {
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
+	if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		goto out;
 	if (!ha->fce)
 		goto out;
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index aa69486..6d7d775 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1327,6 +1327,11 @@ struct qla_flt_header {
 #define FLT_REG_GOLD_FW		0x2f
 #define FLT_REG_FCP_PRIO_0	0x87
 #define FLT_REG_FCP_PRIO_1	0x88
+#define FLT_REG_FCOE_FW		0xA4
+#define FLT_REG_FCOE_VPD_0	0xA9
+#define FLT_REG_FCOE_NVRAM_0	0xAA
+#define FLT_REG_FCOE_VPD_1	0xAB
+#define FLT_REG_FCOE_NVRAM_1	0xAC
 
 struct qla_flt_region {
 	uint32_t code;
@@ -1494,6 +1499,11 @@ struct access_chip_rsp_84xx {
 #define MBC_GET_XGMAC_STATS	0x7a
 #define MBC_GET_DCBX_PARAMS	0x51
 
+/*
+ * ISP83xx mailbox commands
+ */
+#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
+
 /* Flash access control option field bit definitions */
 #define FAC_OPT_FORCE_SEMAPHORE		BIT_15
 #define FAC_OPT_REQUESTOR_ID		BIT_14
@@ -1875,4 +1885,7 @@ struct qla_fcp_prio_cfg {
 #define FA_NPIV_CONF0_ADDR_81	0xD1000
 #define FA_NPIV_CONF1_ADDR_81	0xD2000
 
+/* 83XX Flash locations -- occupies second 8MB region. */
+#define FA_FLASH_LAYOUT_ADDR_83	0xFC400
+
 #endif
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 408679b..9f06580 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -71,8 +71,6 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
     uint16_t *);
 extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
     uint16_t *);
-extern void qla2x00_async_tm_cmd_done(struct scsi_qla_host *, fc_port_t *,
-	struct srb_iocb *);
 extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
 extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
 
@@ -156,8 +154,7 @@ extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *);
 extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
 extern scsi_qla_host_t * qla24xx_create_vhost(struct fc_vport *);
 
-extern void qla2x00_sp_compl(struct qla_hw_data *, srb_t *);
-
+extern void qla2x00_sp_free_dma(void *, void *);
 extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
 
 extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
@@ -205,8 +202,7 @@ extern int
 qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
 
 extern int
-qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
-    uint16_t *, uint32_t *, uint8_t *, uint32_t *, uint8_t *);
+qla2x00_get_fw_version(scsi_qla_host_t *);
 
 extern int
 qla2x00_get_fw_options(scsi_qla_host_t *, uint16_t *);
@@ -371,6 +367,9 @@ qla81xx_get_port_config(scsi_qla_host_t *, uint16_t *);
 extern int
 qla81xx_set_port_config(scsi_qla_host_t *, uint16_t *);
 
+extern int
+qla2x00_port_logout(scsi_qla_host_t *, struct fc_port *);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
@@ -409,8 +408,10 @@ extern void qla2x00_beacon_blink(struct scsi_qla_host *);
 extern int qla24xx_beacon_on(struct scsi_qla_host *);
 extern int qla24xx_beacon_off(struct scsi_qla_host *);
 extern void qla24xx_beacon_blink(struct scsi_qla_host *);
+extern void qla83xx_beacon_blink(struct scsi_qla_host *);
 extern int qla82xx_beacon_on(struct scsi_qla_host *);
 extern int qla82xx_beacon_off(struct scsi_qla_host *);
+extern int qla83xx_write_remote_reg(struct scsi_qla_host *, uint32_t, uint32_t);
 
 extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
     uint32_t, uint32_t);
@@ -541,6 +542,10 @@ extern int qla82xx_restart_isp(scsi_qla_host_t *);
 
 /* IOCB related functions */
 extern int qla82xx_start_scsi(srb_t *);
+extern void qla2x00_sp_free(void *, void *);
+extern void qla2x00_sp_timeout(unsigned long);
+extern void qla2x00_bsg_job_done(void *, void *, int);
+extern void qla2x00_bsg_sp_free(void *, void *);
 
 /* Interrupt related */
 extern irqreturn_t qla82xx_intr_handler(int, void *);
@@ -576,6 +581,8 @@ extern void qla82xx_start_iocbs(scsi_qla_host_t *);
 extern int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *);
 extern int qla82xx_check_md_needed(scsi_qla_host_t *);
 extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *);
+extern int qla81xx_set_led_config(scsi_qla_host_t *, uint16_t *);
+extern int qla81xx_get_led_config(scsi_qla_host_t *, uint16_t *);
 extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int);
 extern char *qdev_state(uint32_t);
 extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *);
@@ -589,6 +596,9 @@ extern int qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *,
 extern int qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t,
 	uint16_t *, uint16_t *);
 
+/* 83xx related functions */
+extern void qla83xx_fw_dump(scsi_qla_host_t *, int);
+
 /* Minidump related functions */
 extern int qla82xx_md_get_template_size(scsi_qla_host_t *);
 extern int qla82xx_md_get_template(scsi_qla_host_t *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 4aea4ae..3128f80 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -240,6 +240,12 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
 	return (rval);
 }
 
+static inline int
+qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
+{
+	return vha->hw->max_fibre_devices * 4 + 16;
+}
+
 /**
  * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
  * @ha: HA context
@@ -261,20 +267,21 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 
 	struct ct_sns_gid_pt_data *gid_data;
 	struct qla_hw_data *ha = vha->hw;
+	uint16_t gid_pt_rsp_size;
 
 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
 		return qla2x00_sns_gid_pt(vha, list);
 
 	gid_data = NULL;
-
+	gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
 	/* Issue GID_PT */
 	/* Prepare common MS IOCB */
 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GID_PT_REQ_SIZE,
-	    GID_PT_RSP_SIZE);
+	    gid_pt_rsp_size);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
-	    GID_PT_RSP_SIZE);
+	    gid_pt_rsp_size);
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare CT arguments -- port_type */
@@ -292,7 +299,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		/* Set port IDs in switch info list. */
-		for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+		for (i = 0; i < ha->max_fibre_devices; i++) {
 			gid_data = &ct_rsp->rsp.gid_pt.entries[i];
 			list[i].d_id.b.domain = gid_data->port_id[0];
 			list[i].d_id.b.area = gid_data->port_id[1];
@@ -313,7 +320,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 		 * single call.  Return a failed status, and let GA_NXT handle
 		 * the overload.
 		 */
-		if (i == MAX_FIBRE_DEVICES)
+		if (i == ha->max_fibre_devices)
 			rval = QLA_FUNCTION_FAILED;
 	}
 
@@ -330,7 +337,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 int
 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 {
-	int		rval;
+	int		rval = QLA_SUCCESS;
 	uint16_t	i;
 
 	ms_iocb_entry_t	*ms_pkt;
@@ -341,7 +348,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
 		return qla2x00_sns_gpn_id(vha, list);
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Issue GPN_ID */
 		/* Prepare common MS IOCB */
 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GPN_ID_REQ_SIZE,
@@ -364,9 +371,11 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 			/*EMPTY*/
 			ql_dbg(ql_dbg_disc, vha, 0x2056,
 			    "GPN_ID issue IOCB failed (%d).\n", rval);
+			break;
 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
 		    "GPN_ID") != QLA_SUCCESS) {
 			rval = QLA_FUNCTION_FAILED;
+			break;
 		} else {
 			/* Save portname */
 			memcpy(list[i].port_name,
@@ -391,7 +400,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 int
 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 {
-	int		rval;
+	int		rval = QLA_SUCCESS;
 	uint16_t	i;
 	struct qla_hw_data *ha = vha->hw;
 	ms_iocb_entry_t	*ms_pkt;
@@ -401,7 +410,7 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
 		return qla2x00_sns_gnn_id(vha, list);
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Issue GNN_ID */
 		/* Prepare common MS IOCB */
 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GNN_ID_REQ_SIZE,
@@ -424,9 +433,11 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 			/*EMPTY*/
 			ql_dbg(ql_dbg_disc, vha, 0x2057,
 			    "GNN_ID issue IOCB failed (%d).\n", rval);
+			break;
 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
 		    "GNN_ID") != QLA_SUCCESS) {
 			rval = QLA_FUNCTION_FAILED;
+			break;
 		} else {
 			/* Save nodename */
 			memcpy(list[i].node_name,
@@ -735,7 +746,7 @@ qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
 static int
 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
 {
-	int		rval;
+	int		rval = QLA_SUCCESS;
 	struct qla_hw_data *ha = vha->hw;
 	struct sns_cmd_pkt	*sns_cmd;
 
@@ -814,11 +825,14 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 	uint16_t	i;
 	uint8_t		*entry;
 	struct sns_cmd_pkt	*sns_cmd;
+	uint16_t gid_pt_sns_data_size;
+
+	gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
 
 	/* Issue GID_PT. */
 	/* Prepare SNS command request. */
 	sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
-	    GID_PT_SNS_DATA_SIZE);
+	    gid_pt_sns_data_size);
 
 	/* Prepare SNS command arguments -- port_type. */
 	sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
@@ -839,7 +853,7 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		/* Set port IDs in switch info list. */
-		for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+		for (i = 0; i < ha->max_fibre_devices; i++) {
 			entry = &sns_cmd->p.gid_data[(i * 4) + 16];
 			list[i].d_id.b.domain = entry[1];
 			list[i].d_id.b.area = entry[2];
@@ -858,7 +872,7 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 		 * single call.  Return a failed status, and let GA_NXT handle
 		 * the overload.
 		 */
-		if (i == MAX_FIBRE_DEVICES)
+		if (i == ha->max_fibre_devices)
 			rval = QLA_FUNCTION_FAILED;
 	}
 
@@ -877,12 +891,12 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
 static int
 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 {
-	int		rval;
+	int		rval = QLA_SUCCESS;
 	struct qla_hw_data *ha = vha->hw;
 	uint16_t	i;
 	struct sns_cmd_pkt	*sns_cmd;
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Issue GPN_ID */
 		/* Prepare SNS command request. */
 		sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
@@ -933,12 +947,12 @@ qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 static int
 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
 {
-	int		rval;
+	int		rval = QLA_SUCCESS;
 	struct qla_hw_data *ha = vha->hw;
 	uint16_t	i;
 	struct sns_cmd_pkt	*sns_cmd;
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Issue GNN_ID */
 		/* Prepare SNS command request. */
 		sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
@@ -1107,20 +1121,26 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
 static int
 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
 {
-	int ret;
+	int ret, rval;
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	struct qla_hw_data *ha = vha->hw;
 	ret = QLA_SUCCESS;
 	if (vha->flags.management_server_logged_in)
 		return ret;
 
-	ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
-	    mb, BIT_1|BIT_0);
-	if (mb[0] != MBS_COMMAND_COMPLETE) {
-		ql_dbg(ql_dbg_disc, vha, 0x2024,
-		    "Failed management_server login: loopid=%x mb[0]=%x "
-		    "mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
-		    vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6], mb[7]);
+	rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
+	    0xfa, mb, BIT_1|BIT_0);
+	if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
+		if (rval == QLA_MEMORY_ALLOC_FAILED)
+			ql_dbg(ql_dbg_disc, vha, 0x2085,
+			    "Failed management_server login: loopid=%x "
+			    "rval=%d\n", vha->mgmt_svr_loop_id, rval);
+		else
+			ql_dbg(ql_dbg_disc, vha, 0x2024,
+			    "Failed management_server login: loopid=%x "
+			    "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
+			    vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
+			    mb[7]);
 		ret = QLA_FUNCTION_FAILED;
 	} else
 		vha->flags.management_server_logged_in = 1;
@@ -1547,7 +1567,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
 	eiter = (struct ct_fdmi_port_attr *) (entries + size);
 	eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
 	eiter->len = __constant_cpu_to_be16(4 + 4);
-	if (IS_QLA8XXX_TYPE(ha))
+	if (IS_CNA_CAPABLE(ha))
 		eiter->a.sup_speed = __constant_cpu_to_be32(
 		    FDMI_PORT_SPEED_10GB);
 	else if (IS_QLA25XX(ha))
@@ -1594,6 +1614,10 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha)
 		eiter->a.cur_speed =
 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_10GB);
 		break;
+	case PORT_SPEED_16GB:
+		eiter->a.cur_speed =
+		    __constant_cpu_to_be32(FDMI_PORT_SPEED_16GB);
+		break;
 	default:
 		eiter->a.cur_speed =
 		    __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
@@ -1724,7 +1748,7 @@ qla2x00_fdmi_register(scsi_qla_host_t *vha)
 int
 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 {
-	int		rval;
+	int		rval = QLA_SUCCESS;
 	uint16_t	i;
 	struct qla_hw_data *ha = vha->hw;
 	ms_iocb_entry_t	*ms_pkt;
@@ -1734,7 +1758,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 	if (!IS_IIDMA_CAPABLE(ha))
 		return QLA_FUNCTION_FAILED;
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Issue GFPN_ID */
 		/* Prepare common MS IOCB */
 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, GFPN_ID_REQ_SIZE,
@@ -1757,9 +1781,11 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
 			/*EMPTY*/
 			ql_dbg(ql_dbg_disc, vha, 0x2023,
 			    "GFPN_ID issue IOCB failed (%d).\n", rval);
+			break;
 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
 		    "GFPN_ID") != QLA_SUCCESS) {
 			rval = QLA_FUNCTION_FAILED;
+			break;
 		} else {
 			/* Save fabric portname */
 			memcpy(list[i].fabric_port_name,
@@ -1846,7 +1872,7 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
 	if (rval)
 		return rval;
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Issue GFPN_ID */
 		/* Prepare common MS IOCB */
 		ms_pkt = qla24xx_prep_ms_fm_iocb(vha, GPSC_REQ_SIZE,
@@ -1947,7 +1973,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
 	struct qla_hw_data *ha = vha->hw;
 	uint8_t fcp_scsi_features = 0;
 
-	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
+	for (i = 0; i < ha->max_fibre_devices; i++) {
 		/* Set default FC4 Type as UNKNOWN so the default is to
 		 * Process this port */
 		list[i].fc4_type = FC4_TYPE_UNKNOWN;
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 1fa067e..b946564 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -29,7 +29,6 @@ static int qla2x00_configure_loop(scsi_qla_host_t *);
 static int qla2x00_configure_local_loop(scsi_qla_host_t *);
 static int qla2x00_configure_fabric(scsi_qla_host_t *);
 static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *);
-static int qla2x00_device_resync(scsi_qla_host_t *);
 static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *,
     uint16_t *);
 
@@ -41,11 +40,10 @@ static int qla25xx_init_queues(struct qla_hw_data *);
 
 /* SRB Extensions ---------------------------------------------------------- */
 
-static void
-qla2x00_ctx_sp_timeout(unsigned long __data)
+void
+qla2x00_sp_timeout(unsigned long __data)
 {
 	srb_t *sp = (srb_t *)__data;
-	struct srb_ctx *ctx;
 	struct srb_iocb *iocb;
 	fc_port_t *fcport = sp->fcport;
 	struct qla_hw_data *ha = fcport->vha->hw;
@@ -55,79 +53,25 @@ qla2x00_ctx_sp_timeout(unsigned long __data)
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	req = ha->req_q_map[0];
 	req->outstanding_cmds[sp->handle] = NULL;
-	ctx = sp->ctx;
-	iocb = ctx->u.iocb_cmd;
+	iocb = &sp->u.iocb_cmd;
 	iocb->timeout(sp);
-	iocb->free(sp);
+	sp->free(fcport->vha, sp);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
-static void
-qla2x00_ctx_sp_free(srb_t *sp)
+void
+qla2x00_sp_free(void *data, void *ptr)
 {
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *iocb = ctx->u.iocb_cmd;
-	struct scsi_qla_host *vha = sp->fcport->vha;
+	srb_t *sp = (srb_t *)ptr;
+	struct srb_iocb *iocb = &sp->u.iocb_cmd;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
 
 	del_timer(&iocb->timer);
-	kfree(iocb);
-	kfree(ctx);
-	mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
+	mempool_free(sp, vha->hw->srb_mempool);
 
 	QLA_VHA_MARK_NOT_BUSY(vha);
 }
 
-inline srb_t *
-qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
-    unsigned long tmo)
-{
-	srb_t *sp = NULL;
-	struct qla_hw_data *ha = vha->hw;
-	struct srb_ctx *ctx;
-	struct srb_iocb *iocb;
-	uint8_t bail;
-
-	QLA_VHA_MARK_BUSY(vha, bail);
-	if (bail)
-		return NULL;
-
-	sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
-	if (!sp)
-		goto done;
-	ctx = kzalloc(size, GFP_KERNEL);
-	if (!ctx) {
-		mempool_free(sp, ha->srb_mempool);
-		sp = NULL;
-		goto done;
-	}
-	iocb = kzalloc(sizeof(struct srb_iocb), GFP_KERNEL);
-	if (!iocb) {
-		mempool_free(sp, ha->srb_mempool);
-		sp = NULL;
-		kfree(ctx);
-		goto done;
-	}
-
-	memset(sp, 0, sizeof(*sp));
-	sp->fcport = fcport;
-	sp->ctx = ctx;
-	ctx->iocbs = 1;
-	ctx->u.iocb_cmd = iocb;
-	iocb->free = qla2x00_ctx_sp_free;
-
-	init_timer(&iocb->timer);
-	if (!tmo)
-		goto done;
-	iocb->timer.expires = jiffies + tmo * HZ;
-	iocb->timer.data = (unsigned long)sp;
-	iocb->timer.function = qla2x00_ctx_sp_timeout;
-	add_timer(&iocb->timer);
-done:
-	if (!sp)
-		QLA_VHA_MARK_NOT_BUSY(vha);
-	return sp;
-}
-
 /* Asynchronous Login/Logout Routines -------------------------------------- */
 
 static inline unsigned long
@@ -149,19 +93,19 @@ qla2x00_get_async_timeout(struct scsi_qla_host *vha)
 }
 
 static void
-qla2x00_async_iocb_timeout(srb_t *sp)
+qla2x00_async_iocb_timeout(void *data)
 {
+	srb_t *sp = (srb_t *)data;
 	fc_port_t *fcport = sp->fcport;
-	struct srb_ctx *ctx = sp->ctx;
 
 	ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
 	    "Async-%s timeout - hdl=%x portid=%02x%02x%02x.\n",
-	    ctx->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
+	    sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
 	    fcport->d_id.b.al_pa);
 
 	fcport->flags &= ~FCF_ASYNC_SENT;
-	if (ctx->type == SRB_LOGIN_CMD) {
-		struct srb_iocb *lio = ctx->u.iocb_cmd;
+	if (sp->type == SRB_LOGIN_CMD) {
+		struct srb_iocb *lio = &sp->u.iocb_cmd;
 		qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
 		/* Retry as needed. */
 		lio->u.logio.data[0] = MBS_COMMAND_ERROR;
@@ -173,14 +117,16 @@ qla2x00_async_iocb_timeout(srb_t *sp)
 }
 
 static void
-qla2x00_async_login_ctx_done(srb_t *sp)
+qla2x00_async_login_sp_done(void *data, void *ptr, int res)
 {
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *lio = ctx->u.iocb_cmd;
-
-	qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport,
-		lio->u.logio.data);
-	lio->free(sp);
+	srb_t *sp = (srb_t *)ptr;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+
+	if (!test_bit(UNLOADING, &vha->dpc_flags))
+		qla2x00_post_async_login_done_work(sp->fcport->vha, sp->fcport,
+		    lio->u.logio.data);
+	sp->free(sp->fcport->vha, sp);
 }
 
 int
@@ -188,22 +134,21 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
     uint16_t *data)
 {
 	srb_t *sp;
-	struct srb_ctx *ctx;
 	struct srb_iocb *lio;
 	int rval;
 
 	rval = QLA_FUNCTION_FAILED;
-	sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
-	    qla2x00_get_async_timeout(vha) + 2);
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp)
 		goto done;
 
-	ctx = sp->ctx;
-	ctx->type = SRB_LOGIN_CMD;
-	ctx->name = "login";
-	lio = ctx->u.iocb_cmd;
+	sp->type = SRB_LOGIN_CMD;
+	sp->name = "login";
+	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+	lio = &sp->u.iocb_cmd;
 	lio->timeout = qla2x00_async_iocb_timeout;
-	lio->done = qla2x00_async_login_ctx_done;
+	sp->done = qla2x00_async_login_sp_done;
 	lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
 	if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
 		lio->u.logio.flags |= SRB_LOGIN_RETRIED;
@@ -219,42 +164,43 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
 	return rval;
 
 done_free_sp:
-	lio->free(sp);
+	sp->free(fcport->vha, sp);
 done:
 	return rval;
 }
 
 static void
-qla2x00_async_logout_ctx_done(srb_t *sp)
+qla2x00_async_logout_sp_done(void *data, void *ptr, int res)
 {
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *lio = ctx->u.iocb_cmd;
-
-	qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport,
-	    lio->u.logio.data);
-	lio->free(sp);
+	srb_t *sp = (srb_t *)ptr;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+
+	if (!test_bit(UNLOADING, &vha->dpc_flags))
+		qla2x00_post_async_logout_done_work(sp->fcport->vha, sp->fcport,
+		    lio->u.logio.data);
+	sp->free(sp->fcport->vha, sp);
 }
 
 int
 qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
 {
 	srb_t *sp;
-	struct srb_ctx *ctx;
 	struct srb_iocb *lio;
 	int rval;
 
 	rval = QLA_FUNCTION_FAILED;
-	sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
-	    qla2x00_get_async_timeout(vha) + 2);
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp)
 		goto done;
 
-	ctx = sp->ctx;
-	ctx->type = SRB_LOGOUT_CMD;
-	ctx->name = "logout";
-	lio = ctx->u.iocb_cmd;
+	sp->type = SRB_LOGOUT_CMD;
+	sp->name = "logout";
+	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+	lio = &sp->u.iocb_cmd;
 	lio->timeout = qla2x00_async_iocb_timeout;
-	lio->done = qla2x00_async_logout_ctx_done;
+	sp->done = qla2x00_async_logout_sp_done;
 	rval = qla2x00_start_sp(sp);
 	if (rval != QLA_SUCCESS)
 		goto done_free_sp;
@@ -266,20 +212,22 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
 	return rval;
 
 done_free_sp:
-	lio->free(sp);
+	sp->free(fcport->vha, sp);
 done:
 	return rval;
 }
 
 static void
-qla2x00_async_adisc_ctx_done(srb_t *sp)
+qla2x00_async_adisc_sp_done(void *data, void *ptr, int res)
 {
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *lio = ctx->u.iocb_cmd;
-
-	qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport,
-	    lio->u.logio.data);
-	lio->free(sp);
+	srb_t *sp = (srb_t *)ptr;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+
+	if (!test_bit(UNLOADING, &vha->dpc_flags))
+		qla2x00_post_async_adisc_done_work(sp->fcport->vha, sp->fcport,
+		    lio->u.logio.data);
+	sp->free(sp->fcport->vha, sp);
 }
 
 int
@@ -287,22 +235,21 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
     uint16_t *data)
 {
 	srb_t *sp;
-	struct srb_ctx *ctx;
 	struct srb_iocb *lio;
 	int rval;
 
 	rval = QLA_FUNCTION_FAILED;
-	sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
-	    qla2x00_get_async_timeout(vha) + 2);
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp)
 		goto done;
 
-	ctx = sp->ctx;
-	ctx->type = SRB_ADISC_CMD;
-	ctx->name = "adisc";
-	lio = ctx->u.iocb_cmd;
+	sp->type = SRB_ADISC_CMD;
+	sp->name = "adisc";
+	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+	lio = &sp->u.iocb_cmd;
 	lio->timeout = qla2x00_async_iocb_timeout;
-	lio->done = qla2x00_async_adisc_ctx_done;
+	sp->done = qla2x00_async_adisc_sp_done;
 	if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
 		lio->u.logio.flags |= SRB_LOGIN_RETRIED;
 	rval = qla2x00_start_sp(sp);
@@ -316,46 +263,62 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
 	return rval;
 
 done_free_sp:
-	lio->free(sp);
+	sp->free(fcport->vha, sp);
 done:
 	return rval;
 }
 
 static void
-qla2x00_async_tm_cmd_ctx_done(srb_t *sp)
+qla2x00_async_tm_cmd_done(void *data, void *ptr, int res)
 {
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *iocb = (struct srb_iocb *)ctx->u.iocb_cmd;
+	srb_t *sp = (srb_t *)ptr;
+	struct srb_iocb *iocb = &sp->u.iocb_cmd;
+	struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
+	uint32_t flags;
+	uint16_t lun;
+	int rval;
+
+	if (!test_bit(UNLOADING, &vha->dpc_flags)) {
+		flags = iocb->u.tmf.flags;
+		lun = (uint16_t)iocb->u.tmf.lun;
+
+		/* Issue Marker IOCB */
+		rval = qla2x00_marker(vha, vha->hw->req_q_map[0],
+			vha->hw->rsp_q_map[0], sp->fcport->loop_id, lun,
+			flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
 
-	qla2x00_async_tm_cmd_done(sp->fcport->vha, sp->fcport, iocb);
-	iocb->free(sp);
+		if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) {
+			ql_dbg(ql_dbg_taskm, vha, 0x8030,
+			    "TM IOCB failed (%x).\n", rval);
+		}
+	}
+	sp->free(sp->fcport->vha, sp);
 }
 
 int
-qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
+qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t tm_flags, uint32_t lun,
 	uint32_t tag)
 {
 	struct scsi_qla_host *vha = fcport->vha;
 	srb_t *sp;
-	struct srb_ctx *ctx;
 	struct srb_iocb *tcf;
 	int rval;
 
 	rval = QLA_FUNCTION_FAILED;
-	sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_ctx),
-	    qla2x00_get_async_timeout(vha) + 2);
+	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
 	if (!sp)
 		goto done;
 
-	ctx = sp->ctx;
-	ctx->type = SRB_TM_CMD;
-	ctx->name = "tmf";
-	tcf = ctx->u.iocb_cmd;
-	tcf->u.tmf.flags = flags;
+	sp->type = SRB_TM_CMD;
+	sp->name = "tmf";
+	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
+
+	tcf = &sp->u.iocb_cmd;
+	tcf->u.tmf.flags = tm_flags;
 	tcf->u.tmf.lun = lun;
 	tcf->u.tmf.data = tag;
 	tcf->timeout = qla2x00_async_iocb_timeout;
-	tcf->done = qla2x00_async_tm_cmd_ctx_done;
+	sp->done = qla2x00_async_tm_cmd_done;
 
 	rval = qla2x00_start_sp(sp);
 	if (rval != QLA_SUCCESS)
@@ -368,7 +331,7 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
 	return rval;
 
 done_free_sp:
-	tcf->free(sp);
+	sp->free(fcport->vha, sp);
 done:
 	return rval;
 }
@@ -387,6 +350,13 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
 		 * requests.
 		 */
 		rval = qla2x00_get_port_database(vha, fcport, 0);
+		if (rval == QLA_NOT_LOGGED_IN) {
+			fcport->flags &= ~FCF_ASYNC_SENT;
+			fcport->flags |= FCF_LOGIN_NEEDED;
+			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+			break;
+		}
+
 		if (rval != QLA_SUCCESS) {
 			qla2x00_post_async_logout_work(vha, fcport, NULL);
 			qla2x00_post_async_login_work(vha, fcport, NULL);
@@ -452,30 +422,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
 	return;
 }
 
-void
-qla2x00_async_tm_cmd_done(struct scsi_qla_host *vha, fc_port_t *fcport,
-    struct srb_iocb *iocb)
-{
-	int rval;
-	uint32_t flags;
-	uint16_t lun;
-
-	flags = iocb->u.tmf.flags;
-	lun = (uint16_t)iocb->u.tmf.lun;
-
-	/* Issue Marker IOCB */
-	rval = qla2x00_marker(vha, vha->hw->req_q_map[0],
-		vha->hw->rsp_q_map[0], fcport->loop_id, lun,
-		flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
-
-	if ((rval != QLA_SUCCESS) || iocb->u.tmf.data) {
-		ql_dbg(ql_dbg_taskm, vha, 0x8030,
-		    "TM IOCB failed (%x).\n", rval);
-	}
-
-	return;
-}
-
 /****************************************************************************/
 /*                QLogic ISP2x00 Hardware Support Functions.                */
 /****************************************************************************/
@@ -969,6 +915,9 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha)
 {
 	uint16_t mb[4] = {0x1010, 0, 1, 0};
 
+	if (!IS_QLA81XX(vha->hw))
+		return QLA_SUCCESS;
+
 	return qla81xx_write_mpi_register(vha, mb);
 }
 
@@ -1262,7 +1211,9 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
 		mem_size = (ha->fw_memory_size - 0x11000 + 1) *
 		    sizeof(uint16_t);
 	} else if (IS_FWI2_CAPABLE(ha)) {
-		if (IS_QLA81XX(ha))
+		if (IS_QLA83XX(ha))
+			fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem);
+		else if (IS_QLA81XX(ha))
 			fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem);
 		else if (IS_QLA25XX(ha))
 			fixed_size = offsetof(struct qla25xx_fw_dump, ext_mem);
@@ -1270,10 +1221,20 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
 			fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem);
 		mem_size = (ha->fw_memory_size - 0x100000 + 1) *
 		    sizeof(uint32_t);
-		if (ha->mqenable)
-			mq_size = sizeof(struct qla2xxx_mq_chain);
+		if (ha->mqenable) {
+			if (!IS_QLA83XX(ha))
+				mq_size = sizeof(struct qla2xxx_mq_chain);
+			/*
+			 * Allocate maximum buffer size for all queues.
+			 * Resizing must be done at end-of-dump processing.
+			 */
+			mq_size += ha->max_req_queues *
+			    (req->length * sizeof(request_t));
+			mq_size += ha->max_rsp_queues *
+			    (rsp->length * sizeof(response_t));
+		}
 		/* Allocate memory for Fibre Channel Event Buffer. */
-		if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
+		if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 			goto try_eft;
 
 		tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
@@ -1484,17 +1445,8 @@ enable_82xx_npiv:
 				fw_major_version = ha->fw_major_version;
 				if (IS_QLA82XX(ha))
 					qla82xx_check_md_needed(vha);
-				else {
-					rval = qla2x00_get_fw_version(vha,
-					    &ha->fw_major_version,
-					    &ha->fw_minor_version,
-					    &ha->fw_subminor_version,
-					    &ha->fw_attributes,
-					    &ha->fw_memory_size,
-					    ha->mpi_version,
-					    &ha->mpi_capabilities,
-					    ha->phy_version);
-				}
+				else
+					rval = qla2x00_get_fw_version(vha);
 				if (rval != QLA_SUCCESS)
 					goto failed;
 				ha->flags.npiv_supported = 0;
@@ -1535,6 +1487,9 @@ enable_82xx_npiv:
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	}
 
+	if (IS_QLA83XX(ha))
+		goto skip_fac_check;
+
 	if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
 		uint32_t size;
 
@@ -1547,6 +1502,11 @@ enable_82xx_npiv:
 			    "Unsupported FAC firmware (%d.%02d.%02d).\n",
 			    ha->fw_major_version, ha->fw_minor_version,
 			    ha->fw_subminor_version);
+skip_fac_check:
+			if (IS_QLA83XX(ha)) {
+				ha->flags.fac_supported = 0;
+				rval = QLA_SUCCESS;
+			}
 		}
 	}
 failed:
@@ -1725,7 +1685,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
 	struct req_que *req = ha->req_q_map[0];
 	struct rsp_que *rsp = ha->rsp_q_map[0];
 
-/* Setup ring parameters in initialization control block. */
+	/* Setup ring parameters in initialization control block. */
 	icb = (struct init_cb_24xx *)ha->init_cb;
 	icb->request_q_outpointer = __constant_cpu_to_le16(0);
 	icb->response_q_inpointer = __constant_cpu_to_le16(0);
@@ -1736,7 +1696,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
 	icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma));
 	icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma));
 
-	if (ha->mqenable) {
+	if (ha->mqenable || IS_QLA83XX(ha)) {
 		icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS);
 		icb->rid = __constant_cpu_to_le16(rid);
 		if (ha->flags.msix_enabled) {
@@ -1756,7 +1716,8 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
 				__constant_cpu_to_le32(BIT_18);
 
 		/* Use Disable MSIX Handshake mode for capable adapters */
-		if (IS_MSIX_NACK_CAPABLE(ha)) {
+		if ((ha->fw_attributes & BIT_6) && (IS_MSIX_NACK_CAPABLE(ha)) &&
+		    (ha->flags.msix_enabled)) {
 			icb->firmware_options_2 &=
 				__constant_cpu_to_le32(~BIT_22);
 			ha->flags.disable_msix_handshake = 1;
@@ -1800,7 +1761,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req;
 	struct rsp_que *rsp;
-	struct scsi_qla_host *vp;
 	struct mid_init_cb_24xx *mid_init_cb =
 	    (struct mid_init_cb_24xx *) ha->init_cb;
 
@@ -1831,11 +1791,6 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
 	}
 
 	spin_lock(&ha->vport_slock);
-	/* Clear RSCN queue. */
-	list_for_each_entry(vp, &ha->vp_list, list) {
-		vp->rscn_in_ptr = 0;
-		vp->rscn_out_ptr = 0;
-	}
 
 	spin_unlock(&ha->vport_slock);
 
@@ -2028,7 +1983,7 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
 	    &loop_id, &al_pa, &area, &domain, &topo, &sw_cap);
 	if (rval != QLA_SUCCESS) {
 		if (LOOP_TRANSITION(vha) || atomic_read(&ha->loop_down_timer) ||
-		    IS_QLA8XXX_TYPE(ha) ||
+		    IS_CNA_CAPABLE(ha) ||
 		    (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
 			ql_dbg(ql_dbg_disc, vha, 0x2008,
 			    "Loop is in a transition state.\n");
@@ -2120,7 +2075,7 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
 	uint16_t index;
 	struct qla_hw_data *ha = vha->hw;
 	int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
-	    !IS_QLA8XXX_TYPE(ha);
+	    !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha);
 
 	if (memcmp(model, BINZERO, len) != 0) {
 		strncpy(ha->model_number, model, len);
@@ -2596,13 +2551,11 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
 	if (ha->current_topology == ISP_CFG_FL &&
 	    (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
 
-		vha->flags.rscn_queue_overflow = 1;
 		set_bit(RSCN_UPDATE, &flags);
 
 	} else if (ha->current_topology == ISP_CFG_F &&
 	    (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
 
-		vha->flags.rscn_queue_overflow = 1;
 		set_bit(RSCN_UPDATE, &flags);
 		clear_bit(LOCAL_LOOP_UPDATE, &flags);
 
@@ -2612,7 +2565,6 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
 	} else if (!vha->flags.online ||
 	    (test_bit(ABORT_ISP_ACTIVE, &flags))) {
 
-		vha->flags.rscn_queue_overflow = 1;
 		set_bit(RSCN_UPDATE, &flags);
 		set_bit(LOCAL_LOOP_UPDATE, &flags);
 	}
@@ -2622,8 +2574,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
 			ql_dbg(ql_dbg_disc, vha, 0x2015,
 			    "Loop resync needed, failing.\n");
 			rval = QLA_FUNCTION_FAILED;
-		}
-		else
+		} else
 			rval = qla2x00_configure_local_loop(vha);
 	}
 
@@ -2662,8 +2613,6 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
 			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
 		if (test_bit(RSCN_UPDATE, &save_flags)) {
 			set_bit(RSCN_UPDATE, &vha->dpc_flags);
-			if (!IS_ALOGIO_CAPABLE(ha))
-				vha->flags.rscn_queue_overflow = 1;
 		}
 	}
 
@@ -2699,7 +2648,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
 
 	found_devs = 0;
 	new_fcport = NULL;
-	entries = MAX_FIBRE_DEVICES;
+	entries = MAX_FIBRE_DEVICES_LOOP;
 
 	ql_dbg(ql_dbg_disc, vha, 0x2016,
 	    "Getting FCAL position map.\n");
@@ -2707,7 +2656,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
 		qla2x00_get_fcal_position_map(vha, NULL);
 
 	/* Get list of logged in devices. */
-	memset(ha->gid_list, 0, GID_LIST_SIZE);
+	memset(ha->gid_list, 0, qla2x00_gid_list_size(ha));
 	rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma,
 	    &entries);
 	if (rval != QLA_SUCCESS)
@@ -2971,7 +2920,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
 static int
 qla2x00_configure_fabric(scsi_qla_host_t *vha)
 {
-	int	rval, rval2;
+	int	rval;
 	fc_port_t	*fcport, *fcptemp;
 	uint16_t	next_loopid;
 	uint16_t	mb[MAILBOX_REGISTER_COUNT];
@@ -2995,12 +2944,6 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
 	}
 	vha->device_flags |= SWITCH_FOUND;
 
-	/* Mark devices that need re-synchronization. */
-	rval2 = qla2x00_device_resync(vha);
-	if (rval2 == QLA_RSCNS_HANDLED) {
-		/* No point doing the scan, just continue. */
-		return (QLA_SUCCESS);
-	}
 	do {
 		/* FDMI support. */
 		if (ql2xfdmienable &&
@@ -3012,8 +2955,12 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
 			loop_id = NPH_SNS;
 		else
 			loop_id = SIMPLE_NAME_SERVER;
-		ha->isp_ops->fabric_login(vha, loop_id, 0xff, 0xff,
-		    0xfc, mb, BIT_1 | BIT_0);
+		rval = ha->isp_ops->fabric_login(vha, loop_id, 0xff, 0xff,
+		    0xfc, mb, BIT_1|BIT_0);
+		if (rval != QLA_SUCCESS) {
+			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
+			return rval;
+		}
 		if (mb[0] != MBS_COMMAND_COMPLETE) {
 			ql_dbg(ql_dbg_disc, vha, 0x2042,
 			    "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x "
@@ -3044,6 +2991,13 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
 			}
 		}
 
+#define QLA_FCPORT_SCAN		1
+#define QLA_FCPORT_FOUND	2
+
+		list_for_each_entry(fcport, &vha->vp_fcports, list) {
+			fcport->scan_state = QLA_FCPORT_SCAN;
+		}
+
 		rval = qla2x00_find_all_fabric_devs(vha, &new_fcports);
 		if (rval != QLA_SUCCESS)
 			break;
@@ -3059,7 +3013,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
 			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
 				continue;
 
-			if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
+			if (fcport->scan_state == QLA_FCPORT_SCAN &&
+			    atomic_read(&fcport->state) == FCS_ONLINE) {
 				qla2x00_mark_device_lost(vha, fcport,
 				    ql2xplogiabsentdevice, 0);
 				if (fcport->loop_id != FC_NO_LOOP_ID &&
@@ -3184,20 +3139,21 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
 	rval = QLA_SUCCESS;
 
 	/* Try GID_PT to get device list, else GAN. */
-	swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_KERNEL);
+	if (!ha->swl)
+		ha->swl = kcalloc(ha->max_fibre_devices, sizeof(sw_info_t),
+		    GFP_KERNEL);
+	swl = ha->swl;
 	if (!swl) {
 		/*EMPTY*/
 		ql_dbg(ql_dbg_disc, vha, 0x2054,
 		    "GID_PT allocations failed, fallback on GA_NXT.\n");
 	} else {
+		memset(swl, 0, ha->max_fibre_devices * sizeof(sw_info_t));
 		if (qla2x00_gid_pt(vha, swl) != QLA_SUCCESS) {
-			kfree(swl);
 			swl = NULL;
 		} else if (qla2x00_gpn_id(vha, swl) != QLA_SUCCESS) {
-			kfree(swl);
 			swl = NULL;
 		} else if (qla2x00_gnn_id(vha, swl) != QLA_SUCCESS) {
-			kfree(swl);
 			swl = NULL;
 		} else if (ql2xiidmaenable &&
 		    qla2x00_gfpn_id(vha, swl) == QLA_SUCCESS) {
@@ -3215,7 +3171,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
 	if (new_fcport == NULL) {
 		ql_log(ql_log_warn, vha, 0x205e,
 		    "Failed to allocate memory for fcport.\n");
-		kfree(swl);
 		return (QLA_MEMORY_ALLOC_FAILED);
 	}
 	new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
@@ -3332,6 +3287,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
 			    WWN_SIZE))
 				continue;
 
+			fcport->scan_state = QLA_FCPORT_FOUND;
+
 			found++;
 
 			/* Update port state. */
@@ -3368,6 +3325,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
 			fcport->flags |= FCF_LOGIN_NEEDED;
 			if (fcport->loop_id != FC_NO_LOOP_ID &&
 			    (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
+			    (fcport->flags & FCF_ASYNC_SENT) == 0 &&
 			    fcport->port_type != FCT_INITIATOR &&
 			    fcport->port_type != FCT_BROADCAST) {
 				ha->isp_ops->fabric_logout(vha, fcport->loop_id,
@@ -3390,14 +3348,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
 		if (new_fcport == NULL) {
 			ql_log(ql_log_warn, vha, 0x2066,
 			    "Memory allocation failed for fcport.\n");
-			kfree(swl);
 			return (QLA_MEMORY_ALLOC_FAILED);
 		}
 		new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
 		new_fcport->d_id.b24 = nxt_d_id.b24;
 	}
 
-	kfree(swl);
 	kfree(new_fcport);
 
 	return (rval);
@@ -3470,6 +3426,9 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
 
 		/* If not in use then it is free to use. */
 		if (!found) {
+			ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
+			    "Assigning new loopid=%x, portid=%x.\n",
+			    dev->loop_id, dev->d_id.b24);
 			break;
 		}
 
@@ -3488,110 +3447,6 @@ qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
 }
 
 /*
- * qla2x00_device_resync
- *	Marks devices in the database that needs resynchronization.
- *
- * Input:
- *	ha = adapter block pointer.
- *
- * Context:
- *	Kernel context.
- */
-static int
-qla2x00_device_resync(scsi_qla_host_t *vha)
-{
-	int	rval;
-	uint32_t mask;
-	fc_port_t *fcport;
-	uint32_t rscn_entry;
-	uint8_t rscn_out_iter;
-	uint8_t format;
-	port_id_t d_id = {};
-
-	rval = QLA_RSCNS_HANDLED;
-
-	while (vha->rscn_out_ptr != vha->rscn_in_ptr ||
-	    vha->flags.rscn_queue_overflow) {
-
-		rscn_entry = vha->rscn_queue[vha->rscn_out_ptr];
-		format = MSB(MSW(rscn_entry));
-		d_id.b.domain = LSB(MSW(rscn_entry));
-		d_id.b.area = MSB(LSW(rscn_entry));
-		d_id.b.al_pa = LSB(LSW(rscn_entry));
-
-		ql_dbg(ql_dbg_disc, vha, 0x2020,
-		    "RSCN queue entry[%d] = [%02x/%02x%02x%02x].\n",
-		    vha->rscn_out_ptr, format, d_id.b.domain, d_id.b.area,
-		    d_id.b.al_pa);
-
-		vha->rscn_out_ptr++;
-		if (vha->rscn_out_ptr == MAX_RSCN_COUNT)
-			vha->rscn_out_ptr = 0;
-
-		/* Skip duplicate entries. */
-		for (rscn_out_iter = vha->rscn_out_ptr;
-		    !vha->flags.rscn_queue_overflow &&
-		    rscn_out_iter != vha->rscn_in_ptr;
-		    rscn_out_iter = (rscn_out_iter ==
-			(MAX_RSCN_COUNT - 1)) ? 0: rscn_out_iter + 1) {
-
-			if (rscn_entry != vha->rscn_queue[rscn_out_iter])
-				break;
-
-			ql_dbg(ql_dbg_disc, vha, 0x2021,
-			    "Skipping duplicate RSCN queue entry found at "
-			    "[%d].\n", rscn_out_iter);
-
-			vha->rscn_out_ptr = rscn_out_iter;
-		}
-
-		/* Queue overflow, set switch default case. */
-		if (vha->flags.rscn_queue_overflow) {
-			ql_dbg(ql_dbg_disc, vha, 0x2022,
-			    "device_resync: rscn overflow.\n");
-
-			format = 3;
-			vha->flags.rscn_queue_overflow = 0;
-		}
-
-		switch (format) {
-		case 0:
-			mask = 0xffffff;
-			break;
-		case 1:
-			mask = 0xffff00;
-			break;
-		case 2:
-			mask = 0xff0000;
-			break;
-		default:
-			mask = 0x0;
-			d_id.b24 = 0;
-			vha->rscn_out_ptr = vha->rscn_in_ptr;
-			break;
-		}
-
-		rval = QLA_SUCCESS;
-
-		list_for_each_entry(fcport, &vha->vp_fcports, list) {
-			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 ||
-			    (fcport->d_id.b24 & mask) != d_id.b24 ||
-			    fcport->port_type == FCT_BROADCAST)
-				continue;
-
-			if (atomic_read(&fcport->state) == FCS_ONLINE) {
-				if (format != 3 ||
-				    fcport->port_type != FCT_INITIATOR) {
-					qla2x00_mark_device_lost(vha, fcport,
-					    0, 0);
-				}
-			}
-		}
-	}
-	return (rval);
-}
-
-/*
  * qla2x00_fabric_dev_login
  *	Login fabric target device and update FC port database.
  *
@@ -3644,6 +3499,9 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
 		} else {
 			qla2x00_update_fcport(vha, fcport);
 		}
+	} else {
+		/* Retry Login. */
+		qla2x00_mark_device_lost(vha, fcport, 1, 0);
 	}
 
 	return (rval);
@@ -3684,9 +3542,12 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport,
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa);
 
 		/* Login fcport on switch. */
-		ha->isp_ops->fabric_login(vha, fcport->loop_id,
+		rval = ha->isp_ops->fabric_login(vha, fcport->loop_id,
 		    fcport->d_id.b.domain, fcport->d_id.b.area,
 		    fcport->d_id.b.al_pa, mb, BIT_0);
+		if (rval != QLA_SUCCESS) {
+			return rval;
+		}
 		if (mb[0] == MBS_PORT_ID_USED) {
 			/*
 			 * Device has another loop ID.  The firmware team
@@ -4100,15 +3961,8 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
 			ha->isp_abort_cnt = 0;
 			clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
 
-			if (IS_QLA81XX(ha))
-				qla2x00_get_fw_version(vha,
-				    &ha->fw_major_version,
-				    &ha->fw_minor_version,
-				    &ha->fw_subminor_version,
-				    &ha->fw_attributes, &ha->fw_memory_size,
-				    ha->mpi_version, &ha->mpi_capabilities,
-				    ha->phy_version);
-
+			if (IS_QLA81XX(ha) || IS_QLA8031(ha))
+				qla2x00_get_fw_version(vha);
 			if (ha->fce) {
 				ha->flags.fce_enabled = 1;
 				memset(ha->fce, 0,
@@ -4974,7 +4828,6 @@ try_blob_fw:
 
 	ql_log(ql_log_info, vha, 0x009a, "Update operational firmware.\n");
 	ha->flags.running_gold_fw = 1;
-
 	return rval;
 }
 
@@ -5009,6 +4862,7 @@ int
 qla24xx_configure_vhba(scsi_qla_host_t *vha)
 {
 	int rval = QLA_SUCCESS;
+	int rval2;
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	struct qla_hw_data *ha = vha->hw;
 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
@@ -5033,12 +4887,18 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
 	vha->flags.management_server_logged_in = 0;
 
 	/* Login to SNS first */
-	ha->isp_ops->fabric_login(vha, NPH_SNS, 0xff, 0xff, 0xfc, mb, BIT_1);
-	if (mb[0] != MBS_COMMAND_COMPLETE) {
-		ql_dbg(ql_dbg_init, vha, 0x0103,
-		    "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x "
-		    "mb[6]=%x mb[7]=%x.\n",
-		    NPH_SNS, mb[0], mb[1], mb[2], mb[6], mb[7]);
+	rval2 = ha->isp_ops->fabric_login(vha, NPH_SNS, 0xff, 0xff, 0xfc, mb,
+	    BIT_1);
+	if (rval2 != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
+		if (rval2 == QLA_MEMORY_ALLOC_FAILED)
+			ql_dbg(ql_dbg_init, vha, 0x0120,
+			    "Failed SNS login: loop_id=%x, rval2=%d\n",
+			    NPH_SNS, rval2);
+		else
+			ql_dbg(ql_dbg_init, vha, 0x0103,
+			    "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x "
+			    "mb[2]=%x mb[6]=%x mb[7]=%x.\n",
+			    NPH_SNS, mb[0], mb[1], mb[2], mb[6], mb[7]);
 		return (QLA_FUNCTION_FAILED);
 	}
 
@@ -5214,10 +5074,10 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
 		nv->reset_delay = 5;
 		nv->max_luns_per_target = __constant_cpu_to_le16(128);
 		nv->port_down_retry_count = __constant_cpu_to_le16(30);
-		nv->link_down_timeout = __constant_cpu_to_le16(30);
+		nv->link_down_timeout = __constant_cpu_to_le16(180);
 		nv->enode_mac[0] = 0x00;
-		nv->enode_mac[1] = 0x02;
-		nv->enode_mac[2] = 0x03;
+		nv->enode_mac[1] = 0xC0;
+		nv->enode_mac[2] = 0xDD;
 		nv->enode_mac[3] = 0x04;
 		nv->enode_mac[4] = 0x05;
 		nv->enode_mac[5] = 0x06 + ha->port_no;
@@ -5248,9 +5108,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
 	memcpy(icb->enode_mac, nv->enode_mac, sizeof(icb->enode_mac));
 	/* Some boards (with valid NVRAMs) still have NULL enode_mac!! */
 	if (!memcmp(icb->enode_mac, "\0\0\0\0\0\0", sizeof(icb->enode_mac))) {
-		icb->enode_mac[0] = 0x01;
-		icb->enode_mac[1] = 0x02;
-		icb->enode_mac[2] = 0x03;
+		icb->enode_mac[0] = 0x00;
+		icb->enode_mac[1] = 0xC0;
+		icb->enode_mac[2] = 0xDD;
 		icb->enode_mac[3] = 0x04;
 		icb->enode_mac[4] = 0x05;
 		icb->enode_mac[5] = 0x06 + ha->port_no;
@@ -5353,6 +5213,10 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
 	if (ql2xloginretrycount)
 		ha->login_retry_count = ql2xloginretrycount;
 
+	/* if not running MSI-X we need handshaking on interrupts */
+	if (!vha->hw->flags.msix_enabled && IS_QLA83XX(ha))
+		icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_22);
+
 	/* Enable ZIO. */
 	if (!vha->flags.init_done) {
 		ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 9902834..6e45764 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -72,16 +72,19 @@ static inline void
 qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
 {
 	struct dsd_dma *dsd_ptr, *tdsd_ptr;
+	struct crc_context *ctx;
+
+	ctx = (struct crc_context *)GET_CMD_CTX_SP(sp);
 
 	/* clean up allocated prev pool */
 	list_for_each_entry_safe(dsd_ptr, tdsd_ptr,
-	    &((struct crc_context *)sp->ctx)->dsd_list, list) {
+	    &ctx->dsd_list, list) {
 		dma_pool_free(ha->dl_dma_pool, dsd_ptr->dsd_addr,
 		    dsd_ptr->dsd_list_dma);
 		list_del(&dsd_ptr->list);
 		kfree(dsd_ptr);
 	}
-	INIT_LIST_HEAD(&((struct crc_context *)sp->ctx)->dsd_list);
+	INIT_LIST_HEAD(&ctx->dsd_list);
 }
 
 static inline void
@@ -113,8 +116,7 @@ qla2x00_hba_err_chk_enabled(srb_t *sp)
 		return 0;
 	 *
 	 */
-
-	switch (scsi_get_prot_op(sp->cmd)) {
+	switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
 	case SCSI_PROT_READ_STRIP:
 	case SCSI_PROT_WRITE_INSERT:
 		if (ql2xenablehba_err_chk >= 1)
@@ -131,3 +133,57 @@ qla2x00_hba_err_chk_enabled(srb_t *sp)
 	}
 	return 0;
 }
+
+static inline int
+qla2x00_reset_active(scsi_qla_host_t *vha)
+{
+	scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);
+
+	/* Test appropriate base-vha and vha flags. */
+	return test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) ||
+	    test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+	    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
+	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
+}
+
+static inline srb_t *
+qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
+{
+	srb_t *sp = NULL;
+	struct qla_hw_data *ha = vha->hw;
+	uint8_t bail;
+
+	QLA_VHA_MARK_BUSY(vha, bail);
+	if (unlikely(bail))
+		return NULL;
+
+	sp = mempool_alloc(ha->srb_mempool, flag);
+	if (!sp)
+		goto done;
+
+	memset(sp, 0, sizeof(*sp));
+	sp->fcport = fcport;
+	sp->iocbs = 1;
+done:
+	if (!sp)
+		QLA_VHA_MARK_NOT_BUSY(vha);
+	return sp;
+}
+
+static inline void
+qla2x00_init_timer(srb_t *sp, unsigned long tmo)
+{
+	init_timer(&sp->u.iocb_cmd.timer);
+	sp->u.iocb_cmd.timer.expires = jiffies + tmo * HZ;
+	sp->u.iocb_cmd.timer.data = (unsigned long)sp;
+	sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
+	add_timer(&sp->u.iocb_cmd.timer);
+	sp->free = qla2x00_sp_free;
+}
+
+static inline int
+qla2x00_gid_list_size(struct qla_hw_data *ha)
+{
+	return sizeof(struct gid_list_info) * ha->max_fibre_devices;
+}
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 55a9676..eac9509 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -22,18 +22,19 @@ static inline uint16_t
 qla2x00_get_cmd_direction(srb_t *sp)
 {
 	uint16_t cflags;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 
 	cflags = 0;
 
 	/* Set transfer direction */
-	if (sp->cmd->sc_data_direction == DMA_TO_DEVICE) {
+	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
 		cflags = CF_WRITE;
 		sp->fcport->vha->hw->qla_stats.output_bytes +=
-		    scsi_bufflen(sp->cmd);
-	} else if (sp->cmd->sc_data_direction == DMA_FROM_DEVICE) {
+		    scsi_bufflen(cmd);
+	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		cflags = CF_READ;
 		sp->fcport->vha->hw->qla_stats.input_bytes +=
-		    scsi_bufflen(sp->cmd);
+		    scsi_bufflen(cmd);
 	}
 	return (cflags);
 }
@@ -143,12 +144,13 @@ qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req)
 static inline int
 qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
 {
-	uint8_t	guard = scsi_host_get_guard(sp->cmd->device->host);
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+	uint8_t	guard = scsi_host_get_guard(cmd->device->host);
 
 	/* We only support T10 DIF right now */
 	if (guard != SHOST_DIX_GUARD_CRC) {
 		ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3007,
-		    "Unsupported guard: %d for cmd=%p.\n", guard, sp->cmd);
+		    "Unsupported guard: %d for cmd=%p.\n", guard, cmd);
 		return 0;
 	}
 
@@ -156,7 +158,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
 	*fw_prot_opts = 0;
 
 	/* Translate SCSI opcode to a protection opcode */
-	switch (scsi_get_prot_op(sp->cmd)) {
+	switch (scsi_get_prot_op(cmd)) {
 	case SCSI_PROT_READ_STRIP:
 		*fw_prot_opts |= PO_MODE_DIF_REMOVE;
 		break;
@@ -180,7 +182,7 @@ qla24xx_configure_prot_mode(srb_t *sp, uint16_t *fw_prot_opts)
 		break;
 	}
 
-	return scsi_prot_sg_count(sp->cmd);
+	return scsi_prot_sg_count(cmd);
 }
 
 /*
@@ -201,7 +203,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
 	struct scatterlist *sg;
 	int i;
 
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 
 	/* Update entry type to indicate Command Type 2 IOCB */
 	*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -259,7 +261,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
 	struct scatterlist *sg;
 	int i;
 
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 
 	/* Update entry type to indicate Command Type 3 IOCB */
 	*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -333,7 +335,7 @@ qla2x00_start_scsi(srb_t *sp)
 	vha = sp->fcport->vha;
 	ha = vha->hw;
 	reg = &ha->iobase->isp;
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 	req = ha->req_q_map[0];
 	rsp = ha->rsp_q_map[0];
 	/* So we know we haven't pci_map'ed anything yet */
@@ -391,7 +393,7 @@ qla2x00_start_scsi(srb_t *sp)
 	req->current_outstanding_cmd = handle;
 	req->outstanding_cmds[handle] = sp;
 	sp->handle = handle;
-	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
+	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
 	req->cnt -= req_cnt;
 
 	cmd_pkt = (cmd_entry_t *)req->ring_ptr;
@@ -403,7 +405,7 @@ qla2x00_start_scsi(srb_t *sp)
 
 	/* Set target ID and LUN number*/
 	SET_TARGET_ID(ha, cmd_pkt->target, sp->fcport->loop_id);
-	cmd_pkt->lun = cpu_to_le16(sp->cmd->device->lun);
+	cmd_pkt->lun = cpu_to_le16(cmd->device->lun);
 
 	/* Update tagged queuing modifier */
 	if (scsi_populate_tag_msg(cmd, tag)) {
@@ -473,7 +475,6 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
 {
 	struct qla_hw_data *ha = vha->hw;
 	device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
-	struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
 
 	if (IS_QLA82XX(ha)) {
 		qla82xx_start_iocbs(vha);
@@ -487,9 +488,9 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
 			req->ring_ptr++;
 
 		/* Set chip new ring index. */
-		if (ha->mqenable) {
-			WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
-			RD_REG_DWORD(&ioreg->hccr);
+		if (ha->mqenable || IS_QLA83XX(ha)) {
+			WRT_REG_DWORD(req->req_q_in, req->ring_index);
+			RD_REG_DWORD_RELAXED(&ha->iobase->isp24.hccr);
 		} else if (IS_FWI2_CAPABLE(ha)) {
 			WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
 			RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
@@ -609,7 +610,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
 	struct dsd_dma *dsd_ptr;
 	struct ct6_dsd *ctx;
 
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 
 	/* Update entry type to indicate Command Type 3 IOCB */
 	*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -636,7 +637,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
 	}
 
 	cur_seg = scsi_sglist(cmd);
-	ctx = sp->ctx;
+	ctx = GET_CMD_CTX_SP(sp);
 
 	while (tot_dsds) {
 		avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ?
@@ -725,7 +726,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 	int i;
 	struct req_que *req;
 
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 
 	/* Update entry type to indicate Command Type 3 IOCB */
 	*((uint32_t *)(&cmd_pkt->entry_type)) =
@@ -745,12 +746,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 		cmd_pkt->task_mgmt_flags =
 		    __constant_cpu_to_le16(TMF_WRITE_DATA);
 		sp->fcport->vha->hw->qla_stats.output_bytes +=
-		    scsi_bufflen(sp->cmd);
+		    scsi_bufflen(cmd);
 	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		cmd_pkt->task_mgmt_flags =
 		    __constant_cpu_to_le16(TMF_READ_DATA);
 		sp->fcport->vha->hw->qla_stats.input_bytes +=
-		    scsi_bufflen(sp->cmd);
+		    scsi_bufflen(cmd);
 	}
 
 	/* One DSD is available in the Command Type 3 IOCB */
@@ -797,7 +798,7 @@ static inline void
 qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt,
     unsigned int protcnt)
 {
-	struct scsi_cmnd *cmd = sp->cmd;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
 
 	switch (scsi_get_prot_type(cmd)) {
@@ -952,16 +953,16 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp,
 	struct qla2_sgx sgx;
 	dma_addr_t	sle_dma;
 	uint32_t	sle_dma_len, tot_prot_dma_len = 0;
-	struct scsi_cmnd *cmd = sp->cmd;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 
 	prot_int = cmd->device->sector_size;
 
 	memset(&sgx, 0, sizeof(struct qla2_sgx));
-	sgx.tot_bytes = scsi_bufflen(sp->cmd);
-	sgx.cur_sg = scsi_sglist(sp->cmd);
+	sgx.tot_bytes = scsi_bufflen(cmd);
+	sgx.cur_sg = scsi_sglist(cmd);
 	sgx.sp = sp;
 
-	sg_prot = scsi_prot_sglist(sp->cmd);
+	sg_prot = scsi_prot_sglist(cmd);
 
 	while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) {
 
@@ -995,7 +996,7 @@ alloc_and_fill:
 			}
 
 			list_add_tail(&dsd_ptr->list,
-			    &((struct crc_context *)sp->ctx)->dsd_list);
+			    &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
 
 			sp->flags |= SRB_CRC_CTX_DSD_VALID;
 
@@ -1044,11 +1045,12 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
 	uint32_t *cur_dsd = dsd;
 	int	i;
 	uint16_t	used_dsds = tot_dsds;
-	scsi_qla_host_t *vha = shost_priv(sp->cmd->device->host);
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
 
 	uint8_t		*cp;
 
-	scsi_for_each_sg(sp->cmd, sg, tot_dsds, i) {
+	scsi_for_each_sg(cmd, sg, tot_dsds, i) {
 		dma_addr_t	sle_dma;
 
 		/* Allocate additional continuation packets? */
@@ -1078,7 +1080,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
 			}
 
 			list_add_tail(&dsd_ptr->list,
-			    &((struct crc_context *)sp->ctx)->dsd_list);
+			    &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
 
 			sp->flags |= SRB_CRC_CTX_DSD_VALID;
 
@@ -1091,17 +1093,16 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd,
 		sle_dma = sg_dma_address(sg);
 		ql_dbg(ql_dbg_io, vha, 0x300a,
 		    "sg entry %d - addr=0x%x 0x%x, " "len=%d for cmd=%p.\n",
-		    i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg),
-		    sp->cmd);
+		    i, LSD(sle_dma), MSD(sle_dma), sg_dma_len(sg), cmd);
 		*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
 		*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
 		*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
 		avail_dsds--;
 
-		if (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_PASS) {
+		if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
 			cp = page_address(sg_page(sg)) + sg->offset;
 			ql_dbg(ql_dbg_io, vha, 0x300b,
-			    "User data buffer=%p for cmd=%p.\n", cp, sp->cmd);
+			    "User data buffer=%p for cmd=%p.\n", cp, cmd);
 		}
 	}
 	/* Null termination */
@@ -1128,8 +1129,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
 	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 	uint8_t		*cp;
 
-
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 	scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) {
 		dma_addr_t	sle_dma;
 
@@ -1160,7 +1160,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
 			}
 
 			list_add_tail(&dsd_ptr->list,
-			    &((struct crc_context *)sp->ctx)->dsd_list);
+			    &((struct crc_context *)sp->u.scmd.ctx)->dsd_list);
 
 			sp->flags |= SRB_CRC_CTX_DSD_VALID;
 
@@ -1171,7 +1171,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
 			cur_dsd = (uint32_t *)next_dsd;
 		}
 		sle_dma = sg_dma_address(sg);
-		if (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_PASS) {
+		if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
 			ql_dbg(ql_dbg_io, vha, 0x3027,
 			    "%s(): %p, sg_entry %d - "
 			    "addr=0x%x0x%x, len=%d.\n",
@@ -1182,7 +1182,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
 		*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
 		*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
 
-		if (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_PASS) {
+		if (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_PASS) {
 			cp = page_address(sg_page(sg)) + sg->offset;
 			ql_dbg(ql_dbg_io, vha, 0x3028,
 			    "%s(): Protection Data buffer = %p.\n", __func__,
@@ -1228,7 +1228,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
 	dma_addr_t		crc_ctx_dma;
 	char			tag[2];
 
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 
 	sgc = 0;
 	/* Update entry type to indicate Command Type CRC_2 IOCB */
@@ -1256,15 +1256,15 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
 		    __constant_cpu_to_le16(CF_READ_DATA);
 	}
 
-	if ((scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_INSERT) ||
-	    (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_STRIP) ||
-	    (scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_STRIP) ||
-	    (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_INSERT))
+	if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) ||
+	    (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP) ||
+	    (scsi_get_prot_op(cmd) == SCSI_PROT_READ_STRIP) ||
+	    (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_INSERT))
 		bundling = 0;
 
 	/* Allocate CRC context from global pool */
-	crc_ctx_pkt = sp->ctx = dma_pool_alloc(ha->dl_dma_pool,
-	    GFP_ATOMIC, &crc_ctx_dma);
+	crc_ctx_pkt = sp->u.scmd.ctx =
+	    dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
 
 	if (!crc_ctx_pkt)
 		goto crc_queuing_error;
@@ -1310,7 +1310,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
 	else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
 		fcp_cmnd->additional_cdb_len |= 2;
 
-	int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
+	int_to_scsilun(cmd->device->lun, &fcp_cmnd->lun);
 	memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
 	cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
 	cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
@@ -1345,7 +1345,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
 	blk_size = cmd->device->sector_size;
 	dif_bytes = (data_bytes / blk_size) * 8;
 
-	switch (scsi_get_prot_op(sp->cmd)) {
+	switch (scsi_get_prot_op(GET_CMD_SP(sp))) {
 	case SCSI_PROT_READ_INSERT:
 	case SCSI_PROT_WRITE_STRIP:
 	    total_bytes = data_bytes;
@@ -1445,7 +1445,7 @@ qla24xx_start_scsi(srb_t *sp)
 	uint16_t	tot_dsds;
 	struct req_que *req = NULL;
 	struct rsp_que *rsp = NULL;
-	struct scsi_cmnd *cmd = sp->cmd;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	struct scsi_qla_host *vha = sp->fcport->vha;
 	struct qla_hw_data *ha = vha->hw;
 	char		tag[2];
@@ -1510,7 +1510,7 @@ qla24xx_start_scsi(srb_t *sp)
 	req->current_outstanding_cmd = handle;
 	req->outstanding_cmds[handle] = sp;
 	sp->handle = handle;
-	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
+	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
 	req->cnt -= req_cnt;
 
 	cmd_pkt = (struct cmd_type_7 *)req->ring_ptr;
@@ -1529,7 +1529,7 @@ qla24xx_start_scsi(srb_t *sp)
 	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
 	cmd_pkt->vp_index = sp->fcport->vp_idx;
 
-	int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+	int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
 	host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
 	/* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */
@@ -1611,7 +1611,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
 	uint16_t		fw_prot_opts = 0;
 	struct req_que		*req = NULL;
 	struct rsp_que		*rsp = NULL;
-	struct scsi_cmnd	*cmd = sp->cmd;
+	struct scsi_cmnd	*cmd = GET_CMD_SP(sp);
 	struct scsi_qla_host	*vha = sp->fcport->vha;
 	struct qla_hw_data	*ha = vha->hw;
 	struct cmd_type_crc_2	*cmd_pkt;
@@ -1728,7 +1728,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
 	req->current_outstanding_cmd = handle;
 	req->outstanding_cmds[handle] = sp;
 	sp->handle = handle;
-	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
+	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
 	req->cnt -= req_cnt;
 
 	/* Fill-in common area */
@@ -1744,7 +1744,7 @@ qla24xx_dif_start_scsi(srb_t *sp)
 	cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
 	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
 
-	int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+	int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
 	host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
 	/* Total Data and protection segment(s) */
@@ -1797,7 +1797,7 @@ queuing_error:
 
 static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
 {
-	struct scsi_cmnd *cmd = sp->cmd;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	struct qla_hw_data *ha = sp->fcport->vha->hw;
 	int affinity = cmd->request->cpu;
 
@@ -1818,7 +1818,6 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
 	uint32_t index, handle;
 	request_t *pkt;
 	uint16_t cnt, req_cnt;
-	struct srb_ctx *ctx;
 
 	pkt = NULL;
 	req_cnt = 1;
@@ -1848,15 +1847,13 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
 	sp->handle = handle;
 
 	/* Adjust entry-counts as needed. */
-	if (sp->ctx) {
-		ctx = sp->ctx;
-		req_cnt = ctx->iocbs;
-	}
+	if (sp->type != SRB_SCSI_CMD)
+		req_cnt = sp->iocbs;
 
 skip_cmd_array:
 	/* Check for room on request queue. */
 	if (req->cnt < req_cnt) {
-		if (ha->mqenable)
+		if (ha->mqenable || IS_QLA83XX(ha))
 			cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
 		else if (IS_QLA82XX(ha))
 			cnt = RD_REG_DWORD(&reg->isp82.req_q_out);
@@ -1889,8 +1886,7 @@ queuing_error:
 static void
 qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
 {
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *lio = ctx->u.iocb_cmd;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
 
 	logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
 	logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
@@ -1909,8 +1905,7 @@ static void
 qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
 {
 	struct qla_hw_data *ha = sp->fcport->vha->hw;
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *lio = ctx->u.iocb_cmd;
+	struct srb_iocb *lio = &sp->u.iocb_cmd;
 	uint16_t opts;
 
 	mbx->entry_type = MBX_IOCB_TYPE;
@@ -1999,8 +1994,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
 	struct fc_port *fcport = sp->fcport;
 	scsi_qla_host_t *vha = fcport->vha;
 	struct qla_hw_data *ha = vha->hw;
-	struct srb_ctx *ctx = sp->ctx;
-	struct srb_iocb *iocb = ctx->u.iocb_cmd;
+	struct srb_iocb *iocb = &sp->u.iocb_cmd;
 	struct req_que *req = vha->req;
 
 	flags = iocb->u.tmf.flags;
@@ -2027,7 +2021,7 @@ qla24xx_tm_iocb(srb_t *sp, struct tsk_mgmt_entry *tsk)
 static void
 qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
 {
-	struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
 
         els_iocb->entry_type = ELS_IOCB_TYPE;
         els_iocb->entry_count = 1;
@@ -2041,7 +2035,7 @@ qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb)
         els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt);
 
 	els_iocb->opcode =
-	    (((struct srb_ctx *)sp->ctx)->type == SRB_ELS_CMD_RPT) ?
+	    sp->type == SRB_ELS_CMD_RPT ?
 	    bsg_job->request->rqst_data.r_els.els_code :
 	    bsg_job->request->rqst_data.h_els.command_code;
         els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
@@ -2078,7 +2072,7 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb)
 	uint16_t tot_dsds;
 	scsi_qla_host_t *vha = sp->fcport->vha;
 	struct qla_hw_data *ha = vha->hw;
-	struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
 	int loop_iterartion = 0;
 	int cont_iocb_prsnt = 0;
 	int entry_count = 1;
@@ -2155,7 +2149,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb)
 	uint16_t tot_dsds;
         scsi_qla_host_t *vha = sp->fcport->vha;
 	struct qla_hw_data *ha = vha->hw;
-	struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job;
+	struct fc_bsg_job *bsg_job = sp->u.bsg_job;
 	int loop_iterartion = 0;
 	int cont_iocb_prsnt = 0;
 	int entry_count = 1;
@@ -2245,12 +2239,12 @@ qla82xx_start_scsi(srb_t *sp)
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req = NULL;
 	struct rsp_que *rsp = NULL;
-	char		tag[2];
+	char tag[2];
 
 	/* Setup device pointers. */
 	ret = 0;
 	reg = &ha->iobase->isp82;
-	cmd = sp->cmd;
+	cmd = GET_CMD_SP(sp);
 	req = vha->req;
 	rsp = ha->rsp_q_map[0];
 
@@ -2354,12 +2348,14 @@ sufficient_dsds:
 		if (req->cnt < (req_cnt + 2))
 			goto queuing_error;
 
-		ctx = sp->ctx = mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
-		if (!sp->ctx) {
+		ctx = sp->u.scmd.ctx =
+		    mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
+		if (!ctx) {
 			ql_log(ql_log_fatal, vha, 0x3010,
 			    "Failed to allocate ctx for cmd=%p.\n", cmd);
 			goto queuing_error;
 		}
+
 		memset(ctx, 0, sizeof(struct ct6_dsd));
 		ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool,
 			GFP_ATOMIC, &ctx->fcp_cmnd_dma);
@@ -2410,12 +2406,12 @@ sufficient_dsds:
 		if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds))
 			goto queuing_error_fcp_cmnd;
 
-		int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+		int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
 		host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
 		/* build FCP_CMND IU */
 		memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
-		int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun);
+		int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
 		ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
 
 		if (cmd->sc_data_direction == DMA_TO_DEVICE)
@@ -2495,9 +2491,9 @@ sufficient_dsds:
 		cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
 		cmd_pkt->vp_index = sp->fcport->vp_idx;
 
-		int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+		int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
 		host_to_fcp_swap((uint8_t *)&cmd_pkt->lun,
-			sizeof(cmd_pkt->lun));
+		    sizeof(cmd_pkt->lun));
 
 		/*
 		 * Update tagged queuing modifier -- default is TSK_SIMPLE (0).
@@ -2538,7 +2534,7 @@ sufficient_dsds:
 	req->current_outstanding_cmd = handle;
 	req->outstanding_cmds[handle] = sp;
 	sp->handle = handle;
-	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
+	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
 	req->cnt -= req_cnt;
 	wmb();
 
@@ -2584,9 +2580,9 @@ queuing_error:
 	if (tot_dsds)
 		scsi_dma_unmap(cmd);
 
-	if (sp->ctx) {
-		mempool_free(sp->ctx, ha->ctx_mempool);
-		sp->ctx = NULL;
+	if (sp->u.scmd.ctx) {
+		mempool_free(sp->u.scmd.ctx, ha->ctx_mempool);
+		sp->u.scmd.ctx = NULL;
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
@@ -2599,7 +2595,6 @@ qla2x00_start_sp(srb_t *sp)
 	int rval;
 	struct qla_hw_data *ha = sp->fcport->vha->hw;
 	void *pkt;
-	struct srb_ctx *ctx = sp->ctx;
 	unsigned long flags;
 
 	rval = QLA_FUNCTION_FAILED;
@@ -2612,7 +2607,7 @@ qla2x00_start_sp(srb_t *sp)
 	}
 
 	rval = QLA_SUCCESS;
-	switch (ctx->type) {
+	switch (sp->type) {
 	case SRB_LOGIN_CMD:
 		IS_FWI2_CAPABLE(ha) ?
 		    qla24xx_login_iocb(sp, pkt) :
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index e804585..f79844c 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -44,8 +44,8 @@ qla2100_intr_handler(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-		    "%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0x505d,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return (IRQ_NONE);
 	}
 
@@ -141,8 +141,8 @@ qla2300_intr_handler(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-		    "%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0x5058,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return (IRQ_NONE);
 	}
 
@@ -289,7 +289,7 @@ qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
 		mb[cnt] = RD_REG_WORD(wptr);
 
 	ql_dbg(ql_dbg_async, vha, 0x5021,
-	    "Inter-Driver Commucation %s -- "
+	    "Inter-Driver Communication %s -- "
 	    "%04x %04x %04x %04x %04x %04x %04x.\n",
 	    event[aen & 0xff], mb[0], mb[1], mb[2], mb[3],
 	    mb[4], mb[5], mb[6]);
@@ -318,7 +318,7 @@ void
 qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 {
 #define LS_UNKNOWN	2
-	static char	*link_speeds[] = { "1", "2", "?", "4", "8", "10" };
+	static char *link_speeds[] = { "1", "2", "?", "4", "8", "16", "10" };
 	char		*link_speed;
 	uint16_t	handle_cnt;
 	uint16_t	cnt, mbx;
@@ -328,12 +328,11 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
 	struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
 	uint32_t	rscn_entry, host_pid;
-	uint8_t		rscn_queue_index;
 	unsigned long	flags;
 
 	/* Setup to process RIO completion. */
 	handle_cnt = 0;
-	if (IS_QLA8XXX_TYPE(ha))
+	if (IS_CNA_CAPABLE(ha))
 		goto skip_rio;
 	switch (mb[0]) {
 	case MBA_SCSI_COMPLETION:
@@ -405,7 +404,8 @@ skip_rio:
 		break;
 
 	case MBA_SYSTEM_ERR:		/* System Error */
-		mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox7) : 0;
+		mbx = (IS_QLA81XX(ha) || IS_QLA83XX(ha)) ?
+			RD_REG_WORD(&reg24->mailbox7) : 0;
 		ql_log(ql_log_warn, vha, 0x5003,
 		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
 		    "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx);
@@ -418,6 +418,7 @@ skip_rio:
 				    "Unrecoverable Hardware Error: adapter "
 				    "marked OFFLINE!\n");
 				vha->flags.online = 0;
+				vha->device_flags |= DFLG_DEV_FAILED;
 			} else {
 				/* Check to see if MPI timeout occurred */
 				if ((mbx & MBX_3) && (ha->flags.port0))
@@ -431,6 +432,7 @@ skip_rio:
 			    "Unrecoverable Hardware Error: adapter marked "
 			    "OFFLINE!\n");
 			vha->flags.online = 0;
+			vha->device_flags |= DFLG_DEV_FAILED;
 		} else
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		break;
@@ -482,10 +484,10 @@ skip_rio:
 			ha->link_data_rate = PORT_SPEED_1GB;
 		} else {
 			link_speed = link_speeds[LS_UNKNOWN];
-			if (mb[1] < 5)
+			if (mb[1] < 6)
 				link_speed = link_speeds[mb[1]];
 			else if (mb[1] == 0x13)
-				link_speed = link_speeds[5];
+				link_speed = link_speeds[6];
 			ha->link_data_rate = mb[1];
 		}
 
@@ -497,7 +499,8 @@ skip_rio:
 		break;
 
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
-		mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
+		mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha))
+			? RD_REG_WORD(&reg24->mailbox4) : 0;
 		mbx = IS_QLA82XX(ha) ? RD_REG_WORD(&reg82->mailbox_out[4]) : mbx;
 		ql_dbg(ql_dbg_async, vha, 0x500b,
 		    "LOOP DOWN detected (%x %x %x %x).\n",
@@ -547,7 +550,7 @@ skip_rio:
 		if (IS_QLA2100(ha))
 			break;
 
-		if (IS_QLA8XXX_TYPE(ha)) {
+		if (IS_QLA81XX(ha) || IS_QLA82XX(ha) || IS_QLA8031(ha)) {
 			ql_dbg(ql_dbg_async, vha, 0x500d,
 			    "DCBX Completed -- %04x %04x %04x.\n",
 			    mb[1], mb[2], mb[3]);
@@ -681,8 +684,6 @@ skip_rio:
 
 		qla2x00_mark_all_devices_lost(vha, 1);
 
-		vha->flags.rscn_queue_overflow = 1;
-
 		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
 		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
 		break;
@@ -711,15 +712,6 @@ skip_rio:
 
 		/* Ignore reserved bits from RSCN-payload. */
 		rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
-		rscn_queue_index = vha->rscn_in_ptr + 1;
-		if (rscn_queue_index == MAX_RSCN_COUNT)
-			rscn_queue_index = 0;
-		if (rscn_queue_index != vha->rscn_out_ptr) {
-			vha->rscn_queue[vha->rscn_in_ptr] = rscn_entry;
-			vha->rscn_in_ptr = rscn_queue_index;
-		} else {
-			vha->flags.rscn_queue_overflow = 1;
-		}
 
 		atomic_set(&vha->loop_down_timer, 0);
 		vha->flags.management_server_logged_in = 0;
@@ -809,6 +801,10 @@ skip_rio:
 	case MBA_IDC_TIME_EXT:
 		qla81xx_idc_event(vha, mb[0], mb[1]);
 		break;
+	default:
+		ql_dbg(ql_dbg_async, vha, 0x5057,
+		    "Unknown AEN:%04x %04x %04x %04x\n",
+		    mb[0], mb[1], mb[2], mb[3]);
 	}
 
 	if (!vha->vp_idx && ha->num_vhosts)
@@ -845,8 +841,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
 		req->outstanding_cmds[index] = NULL;
 
 		/* Save ISP completion status */
-		sp->cmd->result = DID_OK << 16;
-		qla2x00_sp_compl(ha, sp);
+		sp->done(ha, sp, DID_OK << 16);
 	} else {
 		ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n");
 
@@ -903,7 +898,6 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	fc_port_t *fcport;
 	srb_t *sp;
 	struct srb_iocb *lio;
-	struct srb_ctx *ctx;
 	uint16_t *data;
 	uint16_t status;
 
@@ -911,9 +905,8 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	if (!sp)
 		return;
 
-	ctx = sp->ctx;
-	lio = ctx->u.iocb_cmd;
-	type = ctx->name;
+	lio = &sp->u.iocb_cmd;
+	type = sp->name;
 	fcport = sp->fcport;
 	data = lio->u.logio.data;
 
@@ -937,7 +930,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	}
 
 	status = le16_to_cpu(mbx->status);
-	if (status == 0x30 && ctx->type == SRB_LOGIN_CMD &&
+	if (status == 0x30 && sp->type == SRB_LOGIN_CMD &&
 	    le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE)
 		status = 0;
 	if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
@@ -948,7 +941,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 		    le16_to_cpu(mbx->mb1));
 
 		data[0] = MBS_COMMAND_COMPLETE;
-		if (ctx->type == SRB_LOGIN_CMD) {
+		if (sp->type == SRB_LOGIN_CMD) {
 			fcport->port_type = FCT_TARGET;
 			if (le16_to_cpu(mbx->mb1) & BIT_0)
 				fcport->port_type = FCT_INITIATOR;
@@ -979,7 +972,7 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	    le16_to_cpu(mbx->mb7));
 
 logio_done:
-	lio->done(sp);
+	sp->done(vha, sp, 0);
 }
 
 static void
@@ -988,29 +981,18 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 {
 	const char func[] = "CT_IOCB";
 	const char *type;
-	struct qla_hw_data *ha = vha->hw;
 	srb_t *sp;
-	struct srb_ctx *sp_bsg;
 	struct fc_bsg_job *bsg_job;
 	uint16_t comp_status;
+	int res;
 
 	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
 	if (!sp)
 		return;
 
-	sp_bsg = sp->ctx;
-	bsg_job = sp_bsg->u.bsg_job;
+	bsg_job = sp->u.bsg_job;
 
-	type = NULL;
-	switch (sp_bsg->type) {
-	case SRB_CT_CMD:
-		type = "ct pass-through";
-		break;
-	default:
-		ql_log(ql_log_warn, vha, 0x5047,
-		    "Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type);
-		return;
-	}
+	type = "ct pass-through";
 
 	comp_status = le16_to_cpu(pkt->comp_status);
 
@@ -1022,7 +1004,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 
 	if (comp_status != CS_COMPLETE) {
 		if (comp_status == CS_DATA_UNDERRUN) {
-			bsg_job->reply->result = DID_OK << 16;
+			res = DID_OK << 16;
 			bsg_job->reply->reply_payload_rcv_len =
 			    le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
 
@@ -1035,30 +1017,19 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 			ql_log(ql_log_warn, vha, 0x5049,
 			    "CT pass-through-%s error "
 			    "comp_status-status=0x%x.\n", type, comp_status);
-			bsg_job->reply->result = DID_ERROR << 16;
+			res = DID_ERROR << 16;
 			bsg_job->reply->reply_payload_rcv_len = 0;
 		}
 		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
 		    (uint8_t *)pkt, sizeof(*pkt));
 	} else {
-		bsg_job->reply->result =  DID_OK << 16;
+		res = DID_OK << 16;
 		bsg_job->reply->reply_payload_rcv_len =
 		    bsg_job->reply_payload.payload_len;
 		bsg_job->reply_len = 0;
 	}
 
-	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
-	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
-
-	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
-	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
-
-	if (sp_bsg->type == SRB_ELS_CMD_HST || sp_bsg->type == SRB_CT_CMD)
-		kfree(sp->fcport);
-
-	kfree(sp->ctx);
-	mempool_free(sp, ha->srb_mempool);
-	bsg_job->job_done(bsg_job);
+	sp->done(vha, sp, res);
 }
 
 static void
@@ -1067,22 +1038,20 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 {
 	const char func[] = "ELS_CT_IOCB";
 	const char *type;
-	struct qla_hw_data *ha = vha->hw;
 	srb_t *sp;
-	struct srb_ctx *sp_bsg;
 	struct fc_bsg_job *bsg_job;
 	uint16_t comp_status;
 	uint32_t fw_status[3];
 	uint8_t* fw_sts_ptr;
+	int res;
 
 	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
 	if (!sp)
 		return;
-	sp_bsg = sp->ctx;
-	bsg_job = sp_bsg->u.bsg_job;
+	bsg_job = sp->u.bsg_job;
 
 	type = NULL;
-	switch (sp_bsg->type) {
+	switch (sp->type) {
 	case SRB_ELS_CMD_RPT:
 	case SRB_ELS_CMD_HST:
 		type = "els";
@@ -1091,8 +1060,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 		type = "ct pass-through";
 		break;
 	default:
-		ql_log(ql_log_warn, vha, 0x503e,
-		    "Unrecognized SRB: (%p) type=%d.\n", sp, sp_bsg->type);
+		ql_dbg(ql_dbg_user, vha, 0x503e,
+		    "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
 		return;
 	}
 
@@ -1108,11 +1077,11 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 
 	if (comp_status != CS_COMPLETE) {
 		if (comp_status == CS_DATA_UNDERRUN) {
-			bsg_job->reply->result = DID_OK << 16;
+			res = DID_OK << 16;
 			bsg_job->reply->reply_payload_rcv_len =
-				le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
+			    le16_to_cpu(((struct els_sts_entry_24xx *)pkt)->total_byte_count);
 
-			ql_log(ql_log_info, vha, 0x503f,
+			ql_dbg(ql_dbg_user, vha, 0x503f,
 			    "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
 			    "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.\n",
 			    type, sp->handle, comp_status, fw_status[1], fw_status[2],
@@ -1122,7 +1091,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
 		}
 		else {
-			ql_log(ql_log_info, vha, 0x5040,
+			ql_dbg(ql_dbg_user, vha, 0x5040,
 			    "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
 			    "error subcode 1=0x%x error subcode 2=0x%x.\n",
 			    type, sp->handle, comp_status,
@@ -1130,32 +1099,21 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
 				pkt)->error_subcode_1),
 			    le16_to_cpu(((struct els_sts_entry_24xx *)
 				    pkt)->error_subcode_2));
-			bsg_job->reply->result = DID_ERROR << 16;
+			res = DID_ERROR << 16;
 			bsg_job->reply->reply_payload_rcv_len = 0;
 			fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
 			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
 		}
-		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5056,
+		ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056,
 				(uint8_t *)pkt, sizeof(*pkt));
 	}
 	else {
-		bsg_job->reply->result =  DID_OK << 16;
+		res =  DID_OK << 16;
 		bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
 		bsg_job->reply_len = 0;
 	}
 
-	dma_unmap_sg(&ha->pdev->dev,
-	    bsg_job->request_payload.sg_list,
-	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
-	dma_unmap_sg(&ha->pdev->dev,
-	    bsg_job->reply_payload.sg_list,
-	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
-	if ((sp_bsg->type == SRB_ELS_CMD_HST) ||
-	    (sp_bsg->type == SRB_CT_CMD))
-		kfree(sp->fcport);
-	kfree(sp->ctx);
-	mempool_free(sp, ha->srb_mempool);
-	bsg_job->job_done(bsg_job);
+	sp->done(vha, sp, res);
 }
 
 static void
@@ -1167,7 +1125,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 	fc_port_t *fcport;
 	srb_t *sp;
 	struct srb_iocb *lio;
-	struct srb_ctx *ctx;
 	uint16_t *data;
 	uint32_t iop[2];
 
@@ -1175,9 +1132,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 	if (!sp)
 		return;
 
-	ctx = sp->ctx;
-	lio = ctx->u.iocb_cmd;
-	type = ctx->name;
+	lio = &sp->u.iocb_cmd;
+	type = sp->name;
 	fcport = sp->fcport;
 	data = lio->u.logio.data;
 
@@ -1185,7 +1141,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 	data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
 		QLA_LOGIO_LOGIN_RETRIED : 0;
 	if (logio->entry_status) {
-		ql_log(ql_log_warn, vha, 0x5034,
+		ql_log(ql_log_warn, fcport->vha, 0x5034,
 		    "Async-%s error entry - hdl=%x"
 		    "portid=%02x%02x%02x entry-status=%x.\n",
 		    type, sp->handle, fcport->d_id.b.domain,
@@ -1198,14 +1154,14 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 	}
 
 	if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
-		ql_dbg(ql_dbg_async, vha, 0x5036,
+		ql_dbg(ql_dbg_async, fcport->vha, 0x5036,
 		    "Async-%s complete - hdl=%x portid=%02x%02x%02x "
 		    "iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain,
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
 		    le32_to_cpu(logio->io_parameter[0]));
 
 		data[0] = MBS_COMMAND_COMPLETE;
-		if (ctx->type != SRB_LOGIN_CMD)
+		if (sp->type != SRB_LOGIN_CMD)
 			goto logio_done;
 
 		iop[0] = le32_to_cpu(logio->io_parameter[0]);
@@ -1239,7 +1195,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 		break;
 	}
 
-	ql_dbg(ql_dbg_async, vha, 0x5037,
+	ql_dbg(ql_dbg_async, fcport->vha, 0x5037,
 	    "Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x "
 	    "iop0=%x iop1=%x.\n", type, sp->handle, fcport->d_id.b.domain,
 	    fcport->d_id.b.area, fcport->d_id.b.al_pa,
@@ -1248,7 +1204,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 	    le32_to_cpu(logio->io_parameter[1]));
 
 logio_done:
-	lio->done(sp);
+	sp->done(vha, sp, 0);
 }
 
 static void
@@ -1260,7 +1216,6 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	fc_port_t *fcport;
 	srb_t *sp;
 	struct srb_iocb *iocb;
-	struct srb_ctx *ctx;
 	struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
 	int error = 1;
 
@@ -1268,30 +1223,29 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 	if (!sp)
 		return;
 
-	ctx = sp->ctx;
-	iocb = ctx->u.iocb_cmd;
-	type = ctx->name;
+	iocb = &sp->u.iocb_cmd;
+	type = sp->name;
 	fcport = sp->fcport;
 
 	if (sts->entry_status) {
-		ql_log(ql_log_warn, vha, 0x5038,
+		ql_log(ql_log_warn, fcport->vha, 0x5038,
 		    "Async-%s error - hdl=%x entry-status(%x).\n",
 		    type, sp->handle, sts->entry_status);
 	} else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
-		ql_log(ql_log_warn, vha, 0x5039,
+		ql_log(ql_log_warn, fcport->vha, 0x5039,
 		    "Async-%s error - hdl=%x completion status(%x).\n",
 		    type, sp->handle, sts->comp_status);
 	} else if (!(le16_to_cpu(sts->scsi_status) &
 	    SS_RESPONSE_INFO_LEN_VALID)) {
-		ql_log(ql_log_warn, vha, 0x503a,
+		ql_log(ql_log_warn, fcport->vha, 0x503a,
 		    "Async-%s error - hdl=%x no response info(%x).\n",
 		    type, sp->handle, sts->scsi_status);
 	} else if (le32_to_cpu(sts->rsp_data_len) < 4) {
-		ql_log(ql_log_warn, vha, 0x503b,
+		ql_log(ql_log_warn, fcport->vha, 0x503b,
 		    "Async-%s error - hdl=%x not enough response(%d).\n",
 		    type, sp->handle, sts->rsp_data_len);
 	} else if (sts->data[3]) {
-		ql_log(ql_log_warn, vha, 0x503c,
+		ql_log(ql_log_warn, fcport->vha, 0x503c,
 		    "Async-%s error - hdl=%x response(%x).\n",
 		    type, sp->handle, sts->data[3]);
 	} else {
@@ -1304,7 +1258,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 		    (uint8_t *)sts, sizeof(*sts));
 	}
 
-	iocb->done(sp);
+	sp->done(vha, sp, 0);
 }
 
 /**
@@ -1390,25 +1344,32 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
 
 static inline void
 qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
-    uint32_t sense_len, struct rsp_que *rsp)
+		     uint32_t sense_len, struct rsp_que *rsp, int res)
 {
 	struct scsi_qla_host *vha = sp->fcport->vha;
-	struct scsi_cmnd *cp = sp->cmd;
+	struct scsi_cmnd *cp = GET_CMD_SP(sp);
+	uint32_t track_sense_len;
 
 	if (sense_len >= SCSI_SENSE_BUFFERSIZE)
 		sense_len = SCSI_SENSE_BUFFERSIZE;
 
-	sp->request_sense_length = sense_len;
-	sp->request_sense_ptr = cp->sense_buffer;
-	if (sp->request_sense_length > par_sense_len)
+	SET_CMD_SENSE_LEN(sp, sense_len);
+	SET_CMD_SENSE_PTR(sp, cp->sense_buffer);
+	track_sense_len = sense_len;
+
+	if (sense_len > par_sense_len)
 		sense_len = par_sense_len;
 
 	memcpy(cp->sense_buffer, sense_data, sense_len);
 
-	sp->request_sense_ptr += sense_len;
-	sp->request_sense_length -= sense_len;
-	if (sp->request_sense_length != 0)
+	SET_CMD_SENSE_PTR(sp, cp->sense_buffer + sense_len);
+	track_sense_len -= sense_len;
+	SET_CMD_SENSE_LEN(sp, track_sense_len);
+
+	if (track_sense_len != 0) {
 		rsp->status_srb = sp;
+		cp->result = res;
+	}
 
 	if (sense_len) {
 		ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c,
@@ -1436,7 +1397,7 @@ static inline int
 qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
 {
 	struct scsi_qla_host *vha = sp->fcport->vha;
-	struct scsi_cmnd *cmd = sp->cmd;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 	uint8_t		*ap = &sts24->data[12];
 	uint8_t		*ep = &sts24->data[20];
 	uint32_t	e_ref_tag, a_ref_tag;
@@ -1580,6 +1541,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 	uint16_t que;
 	struct req_que *req;
 	int logit = 1;
+	int res = 0;
 
 	sts = (sts_entry_t *) pkt;
 	sts24 = (struct sts_entry_24xx *) pkt;
@@ -1619,7 +1581,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 		qla2xxx_wake_dpc(vha);
 		return;
 	}
-	cp = sp->cmd;
+	cp = GET_CMD_SP(sp);
 	if (cp == NULL) {
 		ql_dbg(ql_dbg_io, vha, 0x3018,
 		    "Command already returned (0x%x/%p).\n",
@@ -1668,11 +1630,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 			par_sense_len -= rsp_info_len;
 		}
 		if (rsp_info_len > 3 && rsp_info[3]) {
-			ql_dbg(ql_dbg_io, vha, 0x3019,
+			ql_dbg(ql_dbg_io, fcport->vha, 0x3019,
 			    "FCP I/O protocol failure (0x%x/0x%x).\n",
 			    rsp_info_len, rsp_info[3]);
 
-			cp->result = DID_BUS_BUSY << 16;
+			res = DID_BUS_BUSY << 16;
 			goto out;
 		}
 	}
@@ -1689,7 +1651,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 	case CS_COMPLETE:
 	case CS_QUEUE_FULL:
 		if (scsi_status == 0) {
-			cp->result = DID_OK << 16;
+			res = DID_OK << 16;
 			break;
 		}
 		if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
@@ -1699,19 +1661,19 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 			if (!lscsi_status &&
 			    ((unsigned)(scsi_bufflen(cp) - resid) <
 			     cp->underflow)) {
-				ql_dbg(ql_dbg_io, vha, 0x301a,
+				ql_dbg(ql_dbg_io, fcport->vha, 0x301a,
 				    "Mid-layer underflow "
 				    "detected (0x%x of 0x%x bytes).\n",
 				    resid, scsi_bufflen(cp));
 
-				cp->result = DID_ERROR << 16;
+				res = DID_ERROR << 16;
 				break;
 			}
 		}
-		cp->result = DID_OK << 16 | lscsi_status;
+		res = DID_OK << 16 | lscsi_status;
 
 		if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
-			ql_dbg(ql_dbg_io, vha, 0x301b,
+			ql_dbg(ql_dbg_io, fcport->vha, 0x301b,
 			    "QUEUE FULL detected.\n");
 			break;
 		}
@@ -1724,7 +1686,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 			break;
 
 		qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len,
-		    rsp);
+		    rsp, res);
 		break;
 
 	case CS_DATA_UNDERRUN:
@@ -1733,36 +1695,36 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 		scsi_set_resid(cp, resid);
 		if (scsi_status & SS_RESIDUAL_UNDER) {
 			if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
-				ql_dbg(ql_dbg_io, vha, 0x301d,
+				ql_dbg(ql_dbg_io, fcport->vha, 0x301d,
 				    "Dropped frame(s) detected "
 				    "(0x%x of 0x%x bytes).\n",
 				    resid, scsi_bufflen(cp));
 
-				cp->result = DID_ERROR << 16 | lscsi_status;
+				res = DID_ERROR << 16 | lscsi_status;
 				goto check_scsi_status;
 			}
 
 			if (!lscsi_status &&
 			    ((unsigned)(scsi_bufflen(cp) - resid) <
 			    cp->underflow)) {
-				ql_dbg(ql_dbg_io, vha, 0x301e,
+				ql_dbg(ql_dbg_io, fcport->vha, 0x301e,
 				    "Mid-layer underflow "
 				    "detected (0x%x of 0x%x bytes).\n",
 				    resid, scsi_bufflen(cp));
 
-				cp->result = DID_ERROR << 16;
+				res = DID_ERROR << 16;
 				break;
 			}
 		} else {
-			ql_dbg(ql_dbg_io, vha, 0x301f,
+			ql_dbg(ql_dbg_io, fcport->vha, 0x301f,
 			    "Dropped frame(s) detected (0x%x "
 			    "of 0x%x bytes).\n", resid, scsi_bufflen(cp));
 
-			cp->result = DID_ERROR << 16 | lscsi_status;
+			res = DID_ERROR << 16 | lscsi_status;
 			goto check_scsi_status;
 		}
 
-		cp->result = DID_OK << 16 | lscsi_status;
+		res = DID_OK << 16 | lscsi_status;
 		logit = 0;
 
 check_scsi_status:
@@ -1772,7 +1734,7 @@ check_scsi_status:
 		 */
 		if (lscsi_status != 0) {
 			if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
-				ql_dbg(ql_dbg_io, vha, 0x3020,
+				ql_dbg(ql_dbg_io, fcport->vha, 0x3020,
 				    "QUEUE FULL detected.\n");
 				logit = 1;
 				break;
@@ -1785,7 +1747,7 @@ check_scsi_status:
 				break;
 
 			qla2x00_handle_sense(sp, sense_data, par_sense_len,
-			    sense_len, rsp);
+			    sense_len, rsp, res);
 		}
 		break;
 
@@ -1802,7 +1764,7 @@ check_scsi_status:
 		 * while we try to recover so instruct the mid layer
 		 * to requeue until the class decides how to handle this.
 		 */
-		cp->result = DID_TRANSPORT_DISRUPTED << 16;
+		res = DID_TRANSPORT_DISRUPTED << 16;
 
 		if (comp_status == CS_TIMEOUT) {
 			if (IS_FWI2_CAPABLE(ha))
@@ -1812,7 +1774,7 @@ check_scsi_status:
 				break;
 		}
 
-		ql_dbg(ql_dbg_io, vha, 0x3021,
+		ql_dbg(ql_dbg_io, fcport->vha, 0x3021,
 		    "Port down status: port-state=0x%x.\n",
 		    atomic_read(&fcport->state));
 
@@ -1821,25 +1783,25 @@ check_scsi_status:
 		break;
 
 	case CS_ABORTED:
-		cp->result = DID_RESET << 16;
+		res = DID_RESET << 16;
 		break;
 
 	case CS_DIF_ERROR:
 		logit = qla2x00_handle_dif_error(sp, sts24);
 		break;
 	default:
-		cp->result = DID_ERROR << 16;
+		res = DID_ERROR << 16;
 		break;
 	}
 
 out:
 	if (logit)
-		ql_dbg(ql_dbg_io, vha, 0x3022,
+		ql_dbg(ql_dbg_io, fcport->vha, 0x3022,
 		    "FCP command status: 0x%x-0x%x (0x%x) "
 		    "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x "
 		    "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x "
 		    "rsp_info=0x%x resid=0x%x fw_resid=0x%x.\n",
-		    comp_status, scsi_status, cp->result, vha->host_no,
+		    comp_status, scsi_status, res, vha->host_no,
 		    cp->device->id, cp->device->lun, fcport->d_id.b.domain,
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id,
 		    cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
@@ -1848,7 +1810,7 @@ out:
 		    resid_len, fw_resid_len);
 
 	if (rsp->status_srb == NULL)
-		qla2x00_sp_compl(ha, sp);
+		sp->done(ha, sp, res);
 }
 
 /**
@@ -1861,84 +1823,52 @@ out:
 static void
 qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
 {
-	uint8_t		sense_sz = 0;
+	uint8_t	sense_sz = 0;
 	struct qla_hw_data *ha = rsp->hw;
 	struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
-	srb_t		*sp = rsp->status_srb;
+	srb_t *sp = rsp->status_srb;
 	struct scsi_cmnd *cp;
+	uint32_t sense_len;
+	uint8_t *sense_ptr;
 
-	if (sp != NULL && sp->request_sense_length != 0) {
-		cp = sp->cmd;
-		if (cp == NULL) {
-			ql_log(ql_log_warn, vha, 0x3025,
-			    "cmd is NULL: already returned to OS (sp=%p).\n",
-			    sp);
+	if (!sp || !GET_CMD_SENSE_LEN(sp))
+		return;
 
-			rsp->status_srb = NULL;
-			return;
-		}
+	sense_len = GET_CMD_SENSE_LEN(sp);
+	sense_ptr = GET_CMD_SENSE_PTR(sp);
 
-		if (sp->request_sense_length > sizeof(pkt->data)) {
-			sense_sz = sizeof(pkt->data);
-		} else {
-			sense_sz = sp->request_sense_length;
-		}
+	cp = GET_CMD_SP(sp);
+	if (cp == NULL) {
+		ql_log(ql_log_warn, vha, 0x3025,
+		    "cmd is NULL: already returned to OS (sp=%p).\n", sp);
 
-		/* Move sense data. */
-		if (IS_FWI2_CAPABLE(ha))
-			host_to_fcp_swap(pkt->data, sizeof(pkt->data));
-		memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
-		ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
-			sp->request_sense_ptr, sense_sz);
-
-		sp->request_sense_ptr += sense_sz;
-		sp->request_sense_length -= sense_sz;
-
-		/* Place command on done queue. */
-		if (sp->request_sense_length == 0) {
-			rsp->status_srb = NULL;
-			qla2x00_sp_compl(ha, sp);
-		}
+		rsp->status_srb = NULL;
+		return;
 	}
-}
 
-static int
-qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp)
-{
-	struct qla_hw_data *ha = vha->hw;
-	struct srb_ctx *ctx;
+	if (sense_len > sizeof(pkt->data))
+		sense_sz = sizeof(pkt->data);
+	else
+		sense_sz = sense_len;
 
-	if (!sp->ctx)
-		return 1;
+	/* Move sense data. */
+	if (IS_FWI2_CAPABLE(ha))
+		host_to_fcp_swap(pkt->data, sizeof(pkt->data));
+	memcpy(sense_ptr, pkt->data, sense_sz);
+	ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
+		sense_ptr, sense_sz);
 
-	ctx = sp->ctx;
+	sense_len -= sense_sz;
+	sense_ptr += sense_sz;
 
-	if (ctx->type == SRB_LOGIN_CMD ||
-	    ctx->type == SRB_LOGOUT_CMD ||
-	    ctx->type == SRB_TM_CMD) {
-		ctx->u.iocb_cmd->done(sp);
-		return 0;
-	} else if (ctx->type == SRB_ADISC_CMD) {
-		ctx->u.iocb_cmd->free(sp);
-		return 0;
-	} else {
-		struct fc_bsg_job *bsg_job;
-
-		bsg_job = ctx->u.bsg_job;
-		if (ctx->type == SRB_ELS_CMD_HST ||
-		    ctx->type == SRB_CT_CMD)
-			kfree(sp->fcport);
-
-		bsg_job->reply->reply_data.ctels_reply.status =
-		    FC_CTELS_STATUS_OK;
-		bsg_job->reply->result = DID_ERROR << 16;
-		bsg_job->reply->reply_payload_rcv_len = 0;
-		kfree(sp->ctx);
-		mempool_free(sp, ha->srb_mempool);
-		bsg_job->job_done(bsg_job);
-		return 0;
+	SET_CMD_SENSE_PTR(sp, sense_ptr);
+	SET_CMD_SENSE_LEN(sp, sense_len);
+
+	/* Place command on done queue. */
+	if (sense_len == 0) {
+		rsp->status_srb = NULL;
+		sp->done(ha, sp, cp->result);
 	}
-	return 1;
 }
 
 /**
@@ -1953,53 +1883,34 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
 	struct qla_hw_data *ha = vha->hw;
 	const char func[] = "ERROR-IOCB";
 	uint16_t que = MSW(pkt->handle);
-	struct req_que *req = ha->req_q_map[que];
-
-	if (pkt->entry_status & RF_INV_E_ORDER)
-		ql_dbg(ql_dbg_async, vha, 0x502a,
-		    "Invalid Entry Order.\n");
-	else if (pkt->entry_status & RF_INV_E_COUNT)
-		ql_dbg(ql_dbg_async, vha, 0x502b,
-		    "Invalid Entry Count.\n");
-	else if (pkt->entry_status & RF_INV_E_PARAM)
-		ql_dbg(ql_dbg_async, vha, 0x502c,
-		    "Invalid Entry Parameter.\n");
-	else if (pkt->entry_status & RF_INV_E_TYPE)
-		ql_dbg(ql_dbg_async, vha, 0x502d,
-		    "Invalid Entry Type.\n");
-	else if (pkt->entry_status & RF_BUSY)
-		ql_dbg(ql_dbg_async, vha, 0x502e,
-		    "Busy.\n");
-	else
-		ql_dbg(ql_dbg_async, vha, 0x502f,
-		    "UNKNOWN flag error.\n");
+	struct req_que *req = NULL;
+	int res = DID_ERROR << 16;
+
+	ql_dbg(ql_dbg_async, vha, 0x502a,
+	    "type of error status in response: 0x%x\n", pkt->entry_status);
+
+	if (que >= ha->max_req_queues || !ha->req_q_map[que])
+		goto fatal;
+
+	req = ha->req_q_map[que];
+
+	if (pkt->entry_status & RF_BUSY)
+		res = DID_BUS_BUSY << 16;
 
 	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
 	if (sp) {
-		if (qla2x00_free_sp_ctx(vha, sp)) {
-			if (pkt->entry_status &
-			    (RF_INV_E_ORDER | RF_INV_E_COUNT |
-			     RF_INV_E_PARAM | RF_INV_E_TYPE)) {
-				sp->cmd->result = DID_ERROR << 16;
-			} else if (pkt->entry_status & RF_BUSY) {
-				sp->cmd->result = DID_BUS_BUSY << 16;
-			} else {
-				sp->cmd->result = DID_ERROR << 16;
-			}
-			qla2x00_sp_compl(ha, sp);
-		}
-	} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
-		COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
-		|| pkt->entry_type == COMMAND_TYPE_6) {
-		ql_log(ql_log_warn, vha, 0x5030,
-		    "Error entry - invalid handle.\n");
-
-		if (IS_QLA82XX(ha))
-			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
-		else
-			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
-		qla2xxx_wake_dpc(vha);
+		sp->done(ha, sp, res);
+		return;
 	}
+fatal:
+	ql_log(ql_log_warn, vha, 0x5030,
+	    "Error entry - invalid handle/queue.\n");
+
+	if (IS_QLA82XX(ha))
+		set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+	else
+		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+	qla2xxx_wake_dpc(vha);
 }
 
 /**
@@ -2090,7 +2001,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 			break;
                 case CT_IOCB_TYPE:
 			qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
-			clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
 			break;
                 case ELS_IOCB_TYPE:
 			qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
@@ -2128,7 +2038,7 @@ qla2xxx_check_risc_status(scsi_qla_host_t *vha)
 	struct qla_hw_data *ha = vha->hw;
 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
-	if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
+	if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		return;
 
 	rval = QLA_SUCCESS;
@@ -2169,7 +2079,7 @@ done:
 }
 
 /**
- * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
+ * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP24xx.
  * @irq:
  * @dev_id: SCSI driver HA context
  *
@@ -2193,8 +2103,8 @@ qla24xx_intr_handler(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-		    "%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0x5059,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return IRQ_NONE;
 	}
 
@@ -2277,8 +2187,8 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-		"%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0x505a,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return IRQ_NONE;
 	}
 	ha = rsp->hw;
@@ -2307,8 +2217,8 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-			"%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0x505b,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return IRQ_NONE;
 	}
 	ha = rsp->hw;
@@ -2341,8 +2251,8 @@ qla24xx_msix_default(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-			"%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0x505c,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return IRQ_NONE;
 	}
 	ha = rsp->hw;
@@ -2531,8 +2441,14 @@ msix_failed:
 	}
 
 	/* Enable MSI-X vector for response queue update for queue 0 */
-	if (ha->mqiobase &&  (ha->max_rsp_queues > 1 || ha->max_req_queues > 1))
-		ha->mqenable = 1;
+	if (IS_QLA83XX(ha)) {
+		if (ha->msixbase && ha->mqiobase &&
+		    (ha->max_rsp_queues > 1 || ha->max_req_queues > 1))
+			ha->mqenable = 1;
+	} else
+		if (ha->mqiobase
+		    && (ha->max_rsp_queues > 1 || ha->max_req_queues > 1))
+			ha->mqenable = 1;
 	ql_dbg(ql_dbg_multiq, vha, 0xc005,
 	    "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.\n",
 	    ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues);
@@ -2553,8 +2469,8 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
 	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 
 	/* If possible, enable MSI-X. */
-	if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
-		!IS_QLA8432(ha) && !IS_QLA8XXX_TYPE(ha))
+	if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
+		!IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha))
 		goto skip_msi;
 
 	if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
@@ -2616,7 +2532,7 @@ clear_risc_ints:
 	 * FIXME: Noted that 8014s were being dropped during NK testing.
 	 * Timing deltas during MSI-X/INTa transitions?
 	 */
-	if (IS_QLA81XX(ha) || IS_QLA82XX(ha))
+	if (IS_QLA81XX(ha) || IS_QLA82XX(ha) || IS_QLA83XX(ha))
 		goto fail;
 	spin_lock_irq(&ha->hardware_lock);
 	if (IS_FWI2_CAPABLE(ha)) {
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 34344d3..b4a2339 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -46,17 +46,17 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	struct qla_hw_data *ha = vha->hw;
 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
-	ql_dbg(ql_dbg_mbx, base_vha, 0x1000, "Entered %s.\n", __func__);
+	ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
 
 	if (ha->pdev->error_state > pci_channel_io_frozen) {
-		ql_log(ql_log_warn, base_vha, 0x1001,
+		ql_log(ql_log_warn, vha, 0x1001,
 		    "error_state is greater than pci_channel_io_frozen, "
 		    "exiting.\n");
 		return QLA_FUNCTION_TIMEOUT;
 	}
 
 	if (vha->device_flags & DFLG_DEV_FAILED) {
-		ql_log(ql_log_warn, base_vha, 0x1002,
+		ql_log(ql_log_warn, vha, 0x1002,
 		    "Device in failed state, exiting.\n");
 		return QLA_FUNCTION_TIMEOUT;
 	}
@@ -69,7 +69,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 
 
 	if (ha->flags.pci_channel_io_perm_failure) {
-		ql_log(ql_log_warn, base_vha, 0x1003,
+		ql_log(ql_log_warn, vha, 0x1003,
 		    "Perm failure on EEH timeout MBX, exiting.\n");
 		return QLA_FUNCTION_TIMEOUT;
 	}
@@ -77,7 +77,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	if (ha->flags.isp82xx_fw_hung) {
 		/* Setting Link-Down error */
 		mcp->mb[0] = MBS_LINK_DOWN_ERROR;
-		ql_log(ql_log_warn, base_vha, 0x1004,
+		ql_log(ql_log_warn, vha, 0x1004,
 		    "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
 		return QLA_FUNCTION_TIMEOUT;
 	}
@@ -89,8 +89,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	 */
 	if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
 		/* Timeout occurred. Return error. */
-		ql_log(ql_log_warn, base_vha, 0x1005,
-		    "Cmd access timeout, Exiting.\n");
+		ql_log(ql_log_warn, vha, 0x1005,
+		    "Cmd access timeout, cmd=0x%x, Exiting.\n",
+		    mcp->mb[0]);
 		return QLA_FUNCTION_TIMEOUT;
 	}
 
@@ -98,7 +99,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	/* Save mailbox command for debug */
 	ha->mcp = mcp;
 
-	ql_dbg(ql_dbg_mbx, base_vha, 0x1006,
+	ql_dbg(ql_dbg_mbx, vha, 0x1006,
 	    "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -127,28 +128,28 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		iptr++;
 	}
 
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1111,
+	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
 	    "Loaded MBX registers (displayed in bytes) =.\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1112,
+	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1112,
 	    (uint8_t *)mcp->mb, 16);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1113,
+	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1113,
 	    ".\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1114,
+	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1114,
 	    ((uint8_t *)mcp->mb + 0x10), 16);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1115,
+	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1115,
 	    ".\n");
-	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1116,
+	ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1116,
 	    ((uint8_t *)mcp->mb + 0x20), 8);
-	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1117,
+	ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
 	    "I/O Address = %p.\n", optr);
-	ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x100e);
+	ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x100e);
 
 	/* Issue set host interrupt command to send cmd out. */
 	ha->flags.mbox_int = 0;
 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 
 	/* Unlock mbx registers and wait for interrupt */
-	ql_dbg(ql_dbg_mbx, base_vha, 0x100f,
+	ql_dbg(ql_dbg_mbx, vha, 0x100f,
 	    "Going to unlock irq & waiting for interrupts. "
 	    "jiffies=%lx.\n", jiffies);
 
@@ -163,7 +164,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 				spin_unlock_irqrestore(&ha->hardware_lock,
 					flags);
 				ha->flags.mbox_busy = 0;
-				ql_dbg(ql_dbg_mbx, base_vha, 0x1010,
+				ql_dbg(ql_dbg_mbx, vha, 0x1010,
 				    "Pending mailbox timeout, exiting.\n");
 				rval = QLA_FUNCTION_TIMEOUT;
 				goto premature_exit;
@@ -180,7 +181,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
 	} else {
-		ql_dbg(ql_dbg_mbx, base_vha, 0x1011,
+		ql_dbg(ql_dbg_mbx, vha, 0x1011,
 		    "Cmd=%x Polling Mode.\n", command);
 
 		if (IS_QLA82XX(ha)) {
@@ -189,7 +190,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 				spin_unlock_irqrestore(&ha->hardware_lock,
 					flags);
 				ha->flags.mbox_busy = 0;
-				ql_dbg(ql_dbg_mbx, base_vha, 0x1012,
+				ql_dbg(ql_dbg_mbx, vha, 0x1012,
 				    "Pending mailbox timeout, exiting.\n");
 				rval = QLA_FUNCTION_TIMEOUT;
 				goto premature_exit;
@@ -214,7 +215,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 			    command == MBC_LOAD_RISC_RAM_EXTENDED))
 				msleep(10);
 		} /* while */
-		ql_dbg(ql_dbg_mbx, base_vha, 0x1013,
+		ql_dbg(ql_dbg_mbx, vha, 0x1013,
 		    "Waited %d sec.\n",
 		    (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
 	}
@@ -223,7 +224,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	if (ha->flags.mbox_int) {
 		uint16_t *iptr2;
 
-		ql_dbg(ql_dbg_mbx, base_vha, 0x1014,
+		ql_dbg(ql_dbg_mbx, vha, 0x1014,
 		    "Cmd=%x completed.\n", command);
 
 		/* Got interrupt. Clear the flag. */
@@ -236,7 +237,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 			mcp->mb[0] = MBS_LINK_DOWN_ERROR;
 			ha->mcp = NULL;
 			rval = QLA_FUNCTION_FAILED;
-			ql_log(ql_log_warn, base_vha, 0x1015,
+			ql_log(ql_log_warn, vha, 0x1015,
 			    "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
 			goto premature_exit;
 		}
@@ -268,13 +269,19 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 			mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
 			ictrl = RD_REG_WORD(&reg->isp.ictrl);
 		}
-		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1119,
+		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
 		    "MBX Command timeout for cmd %x.\n", command);
-		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111a,
+		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111a,
 		    "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
-		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111b,
+		ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111b,
 		    "mb[0] = 0x%x.\n", mb0);
-		ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1019);
+		ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
+
+		/*
+		 * Attempt to capture a firmware dump for further analysis
+		 * of the current firmware state
+		 */
+		ha->isp_ops->fw_dump(vha, 0);
 
 		rval = QLA_FUNCTION_TIMEOUT;
 	}
@@ -285,7 +292,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 	ha->mcp = NULL;
 
 	if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
-		ql_dbg(ql_dbg_mbx, base_vha, 0x101a,
+		ql_dbg(ql_dbg_mbx, vha, 0x101a,
 		    "Checking for additional resp interrupt.\n");
 
 		/* polling mode for non isp_abort commands. */
@@ -297,7 +304,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 		if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
 		    ha->flags.eeh_busy) {
 			/* not in dpc. schedule it for dpc to take over. */
-			ql_dbg(ql_dbg_mbx, base_vha, 0x101b,
+			ql_dbg(ql_dbg_mbx, vha, 0x101b,
 			    "Timeout, schedule isp_abort_needed.\n");
 
 			if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
@@ -313,15 +320,16 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 					    CRB_NIU_XG_PAUSE_CTL_P1);
 				}
 				ql_log(ql_log_info, base_vha, 0x101c,
-				    "Mailbox cmd timeout occured. "
-				    "Scheduling ISP abort eeh_busy=0x%x.\n",
-					ha->flags.eeh_busy);
+				    "Mailbox cmd timeout occured, cmd=0x%x, "
+				    "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
+				    "abort.\n", command, mcp->mb[0],
+				    ha->flags.eeh_busy);
 				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 				qla2xxx_wake_dpc(vha);
 			}
 		} else if (!abort_active) {
 			/* call abort directly since we are in the DPC thread */
-			ql_dbg(ql_dbg_mbx, base_vha, 0x101d,
+			ql_dbg(ql_dbg_mbx, vha, 0x101d,
 			    "Timeout, calling abort_isp.\n");
 
 			if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
@@ -337,19 +345,22 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
 					    CRB_NIU_XG_PAUSE_CTL_P1);
 				}
 				ql_log(ql_log_info, base_vha, 0x101e,
-				    "Mailbox cmd timeout occured. "
-				    "Scheduling ISP abort.\n");
-
+				    "Mailbox cmd timeout occured, cmd=0x%x, "
+				    "mb[0]=0x%x. Scheduling ISP abort ",
+				    command, mcp->mb[0]);
 				set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
 				clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+				/* Allow next mbx cmd to come in. */
+				complete(&ha->mbx_cmd_comp);
 				if (ha->isp_ops->abort_isp(vha)) {
 					/* Failed. retry later. */
 					set_bit(ISP_ABORT_NEEDED,
 					    &vha->dpc_flags);
 				}
 				clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
-				ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
+				ql_dbg(ql_dbg_mbx, vha, 0x101f,
 				    "Finished abort_isp.\n");
+				goto mbx_done;
 			}
 		}
 	}
@@ -358,10 +369,11 @@ premature_exit:
 	/* Allow next mbx cmd to come in. */
 	complete(&ha->mbx_cmd_comp);
 
+mbx_done:
 	if (rval) {
 		ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
-		    "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, cmd=%x ****.\n",
-		    mcp->mb[0], mcp->mb[1], mcp->mb[2], command);
+		    "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
+		    mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
 	} else {
 		ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
 	}
@@ -451,7 +463,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
 		mcp->mb[1] = MSW(risc_addr);
 		mcp->mb[2] = LSW(risc_addr);
 		mcp->mb[3] = 0;
-		if (IS_QLA81XX(ha)) {
+		if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
 			struct nvram_81xx *nv = ha->nvram;
 			mcp->mb[4] = (nv->enhanced_features &
 			    EXTENDED_BB_CREDITS);
@@ -504,21 +516,22 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
  *	Kernel context.
  */
 int
-qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
-    uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
-    uint32_t *mpi_caps, uint8_t *phy)
+qla2x00_get_fw_version(scsi_qla_host_t *vha)
 {
 	int		rval;
 	mbx_cmd_t	mc;
 	mbx_cmd_t	*mcp = &mc;
+	struct qla_hw_data *ha = vha->hw;
 
 	ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
 
 	mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (IS_QLA81XX(vha->hw))
+	if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
 		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
+	if (IS_QLA83XX(vha->hw))
+		mcp->in_mb |= MBX_17|MBX_16|MBX_15;
 	mcp->flags = 0;
 	mcp->tov = MBX_TOV_SECONDS;
 	rval = qla2x00_mailbox_command(vha, mcp);
@@ -526,23 +539,37 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
 		goto failed;
 
 	/* Return mailbox data. */
-	*major = mcp->mb[1];
-	*minor = mcp->mb[2];
-	*subminor = mcp->mb[3];
-	*attributes = mcp->mb[6];
+	ha->fw_major_version = mcp->mb[1];
+	ha->fw_minor_version = mcp->mb[2];
+	ha->fw_subminor_version = mcp->mb[3];
+	ha->fw_attributes = mcp->mb[6];
 	if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
-		*memory = 0x1FFFF;			/* Defaults to 128KB. */
+		ha->fw_memory_size = 0x1FFFF;		/* Defaults to 128KB. */
 	else
-		*memory = (mcp->mb[5] << 16) | mcp->mb[4];
-	if (IS_QLA81XX(vha->hw)) {
-		mpi[0] = mcp->mb[10] & 0xff;
-		mpi[1] = mcp->mb[11] >> 8;
-		mpi[2] = mcp->mb[11] & 0xff;
-		*mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
-		phy[0] = mcp->mb[8] & 0xff;
-		phy[1] = mcp->mb[9] >> 8;
-		phy[2] = mcp->mb[9] & 0xff;
+		ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
+	if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
+		ha->mpi_version[0] = mcp->mb[10] & 0xff;
+		ha->mpi_version[1] = mcp->mb[11] >> 8;
+		ha->mpi_version[2] = mcp->mb[11] & 0xff;
+		ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
+		ha->phy_version[0] = mcp->mb[8] & 0xff;
+		ha->phy_version[1] = mcp->mb[9] >> 8;
+		ha->phy_version[2] = mcp->mb[9] & 0xff;
+	}
+	if (IS_QLA83XX(ha)) {
+		if (mcp->mb[6] & BIT_15) {
+			ha->fw_attributes_h = mcp->mb[15];
+			ha->fw_attributes_ext[0] = mcp->mb[16];
+			ha->fw_attributes_ext[1] = mcp->mb[17];
+			ql_dbg(ql_dbg_mbx, vha, 0x1139,
+			    "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
+			    __func__, mcp->mb[15], mcp->mb[6]);
+		} else
+			ql_dbg(ql_dbg_mbx, vha, 0x112f,
+			    "%s: FwAttributes [Upper]  invalid, MB6:%04x\n",
+			    __func__, mcp->mb[6]);
 	}
+
 failed:
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
@@ -855,6 +882,7 @@ qla2x00_abort_command(srb_t *sp)
 	scsi_qla_host_t *vha = fcport->vha;
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req = vha->req;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
 
 	ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
 
@@ -877,7 +905,7 @@ qla2x00_abort_command(srb_t *sp)
 		mcp->mb[1] = fcport->loop_id << 8;
 	mcp->mb[2] = (uint16_t)handle;
 	mcp->mb[3] = (uint16_t)(handle >> 16);
-	mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
+	mcp->mb[6] = (uint16_t)cmd->device->lun;
 	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->tov = MBX_TOV_SECONDS;
@@ -1024,7 +1052,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
 	mcp->mb[9] = vha->vp_idx;
 	mcp->out_mb = MBX_9|MBX_0;
 	mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (IS_QLA8XXX_TYPE(vha->hw))
+	if (IS_CNA_CAPABLE(vha->hw))
 		mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
 	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
@@ -1048,7 +1076,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
 	} else {
 		ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
 
-		if (IS_QLA8XXX_TYPE(vha->hw)) {
+		if (IS_CNA_CAPABLE(vha->hw)) {
 			vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
 			vha->fcoe_fcf_idx = mcp->mb[10];
 			vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
@@ -1159,7 +1187,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
 	mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
 	mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
+	if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
 		mcp->mb[1] = BIT_0;
 		mcp->mb[10] = MSW(ha->ex_init_cb_dma);
 		mcp->mb[11] = LSW(ha->ex_init_cb_dma);
@@ -1168,7 +1196,11 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
 		mcp->mb[14] = sizeof(*ha->ex_init_cb);
 		mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
 	}
-	mcp->in_mb = MBX_0;
+	/* 1 and 2 should normally be captured. */
+	mcp->in_mb = MBX_2|MBX_1|MBX_0;
+	if (IS_QLA83XX(ha))
+		/* mb3 is additional info about the installed SFP. */
+		mcp->in_mb  |= MBX_3;
 	mcp->buf_size = size;
 	mcp->flags = MBX_DMA_OUT;
 	mcp->tov = MBX_TOV_SECONDS;
@@ -1177,7 +1209,8 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
 		ql_dbg(ql_dbg_mbx, vha, 0x104d,
-		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+		    "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
+		    rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
 	} else {
 		/*EMPTY*/
 		ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
@@ -1256,6 +1289,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
 		goto gpd_error_out;
 
 	if (IS_FWI2_CAPABLE(ha)) {
+		uint64_t zero = 0;
 		pd24 = (struct port_database_24xx *) pd;
 
 		/* Check for logged in state. */
@@ -1269,6 +1303,14 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
 			goto gpd_error_out;
 		}
 
+		if (fcport->loop_id == FC_NO_LOOP_ID ||
+		    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
+		     memcmp(fcport->port_name, pd24->port_name, 8))) {
+			/* We lost the device mid way. */
+			rval = QLA_NOT_LOGGED_IN;
+			goto gpd_error_out;
+		}
+
 		/* Names are little-endian. */
 		memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
 		memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
@@ -1285,6 +1327,8 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
 		else
 			fcport->port_type = FCT_TARGET;
 	} else {
+		uint64_t zero = 0;
+
 		/* Check for logged in state. */
 		if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
 		    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
@@ -1297,6 +1341,14 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
 			goto gpd_error_out;
 		}
 
+		if (fcport->loop_id == FC_NO_LOOP_ID ||
+		    (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
+		     memcmp(fcport->port_name, pd->port_name, 8))) {
+			/* We lost the device mid way. */
+			rval = QLA_NOT_LOGGED_IN;
+			goto gpd_error_out;
+		}
+
 		/* Names are little-endian. */
 		memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
 		memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
@@ -1477,7 +1529,7 @@ qla2x00_lip_reset(scsi_qla_host_t *vha)
 
 	ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
 
-	if (IS_QLA8XXX_TYPE(vha->hw)) {
+	if (IS_CNA_CAPABLE(vha->hw)) {
 		/* Logout across all FCFs. */
 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
 		mcp->mb[1] = BIT_1;
@@ -1618,7 +1670,8 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
 	lg->port_id[1] = area;
 	lg->port_id[2] = domain;
 	lg->vp_index = vha->vp_idx;
-	rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
+	rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
+	    (ha->r_a_tov / 10 * 2) + 2);
 	if (rval != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_mbx, vha, 0x1063,
 		    "Failed to issue login IOCB (%x).\n", rval);
@@ -1881,8 +1934,8 @@ qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
 	lg->port_id[1] = area;
 	lg->port_id[2] = domain;
 	lg->vp_index = vha->vp_idx;
-
-	rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
+	rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
+	    (ha->r_a_tov / 10 * 2) + 2);
 	if (rval != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_mbx, vha, 0x106f,
 		    "Failed to issue logout IOCB (%x).\n", rval);
@@ -2090,7 +2143,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (IS_QLA81XX(vha->hw))
+	if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
 		mcp->in_mb |= MBX_12;
 	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
@@ -2117,7 +2170,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
 			*orig_iocb_cnt = mcp->mb[10];
 		if (vha->hw->flags.npiv_supported && max_npiv_vports)
 			*max_npiv_vports = mcp->mb[11];
-		if (IS_QLA81XX(vha->hw) && max_fcfs)
+		if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
 			*max_fcfs = mcp->mb[12];
 	}
 
@@ -2581,7 +2634,8 @@ qla2x00_stop_firmware(scsi_qla_host_t *vha)
 	ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
 
 	mcp->mb[0] = MBC_STOP_FIRMWARE;
-	mcp->out_mb = MBX_0;
+	mcp->mb[1] = 0;
+	mcp->out_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->tov = 5;
 	mcp->flags = 0;
@@ -2681,7 +2735,8 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
 
 	ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
 
-	if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw))
+	if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
+	    !IS_QLA83XX(vha->hw))
 		return QLA_FUNCTION_FAILED;
 
 	if (unlikely(pci_channel_offline(vha->hw->pdev)))
@@ -2823,7 +2878,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
 	mcp->mb[0] = MBC_PORT_PARAMS;
 	mcp->mb[1] = loop_id;
 	mcp->mb[2] = BIT_0;
-	if (IS_QLA8XXX_TYPE(vha->hw))
+	if (IS_CNA_CAPABLE(vha->hw))
 		mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
 	else
 		mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
@@ -3293,6 +3348,8 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
 	mcp->mb[12] = req->qos;
 	mcp->mb[11] = req->vp_idx;
 	mcp->mb[13] = req->rid;
+	if (IS_QLA83XX(ha))
+		mcp->mb[15] = 0;
 
 	reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
 		QLA_QUE_PAGE * req->id);
@@ -3306,12 +3363,21 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
 			MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->flags = MBX_DMA_OUT;
-	mcp->tov = 60;
+	mcp->tov = MBX_TOV_SECONDS * 2;
+
+	if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
+		mcp->in_mb |= MBX_1;
+	if (IS_QLA83XX(ha)) {
+		mcp->out_mb |= MBX_15;
+		/* debug q create issue in SR-IOV */
+		mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
+	}
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	if (!(req->options & BIT_0)) {
 		WRT_REG_DWORD(&reg->req_q_in, 0);
-		WRT_REG_DWORD(&reg->req_q_out, 0);
+		if (!IS_QLA83XX(ha))
+			WRT_REG_DWORD(&reg->req_q_out, 0);
 	}
 	req->req_q_in = &reg->req_q_in;
 	req->req_q_out = &reg->req_q_out;
@@ -3349,6 +3415,8 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
 	mcp->mb[5] = rsp->length;
 	mcp->mb[14] = rsp->msix->entry;
 	mcp->mb[13] = rsp->rid;
+	if (IS_QLA83XX(ha))
+		mcp->mb[15] = 0;
 
 	reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
 		QLA_QUE_PAGE * rsp->id);
@@ -3362,12 +3430,23 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
 			|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->flags = MBX_DMA_OUT;
-	mcp->tov = 60;
+	mcp->tov = MBX_TOV_SECONDS * 2;
+
+	if (IS_QLA81XX(ha)) {
+		mcp->out_mb |= MBX_12|MBX_11|MBX_10;
+		mcp->in_mb |= MBX_1;
+	} else if (IS_QLA83XX(ha)) {
+		mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
+		mcp->in_mb |= MBX_1;
+		/* debug q create issue in SR-IOV */
+		mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
+	}
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	if (!(rsp->options & BIT_0)) {
 		WRT_REG_DWORD(&reg->rsp_q_out, 0);
-		WRT_REG_DWORD(&reg->rsp_q_in, 0);
+		if (!IS_QLA83XX(ha))
+			WRT_REG_DWORD(&reg->rsp_q_in, 0);
 	}
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -3419,7 +3498,7 @@ qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
 
 	ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
 
-	if (!IS_QLA81XX(vha->hw))
+	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
 		return QLA_FUNCTION_FAILED;
 
 	mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
@@ -3449,7 +3528,7 @@ qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 
-	if (!IS_QLA81XX(vha->hw))
+	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
 		return QLA_FUNCTION_FAILED;
 
 	ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
@@ -3481,7 +3560,7 @@ qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 
-	if (!IS_QLA81XX(vha->hw))
+	if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
 		return QLA_FUNCTION_FAILED;
 
 	ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
@@ -3636,7 +3715,7 @@ qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
 
 	ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
 
-	if (!IS_QLA8XXX_TYPE(vha->hw))
+	if (!IS_CNA_CAPABLE(vha->hw))
 		return QLA_FUNCTION_FAILED;
 
 	mcp->mb[0] = MBC_GET_XGMAC_STATS;
@@ -3675,7 +3754,7 @@ qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
 
 	ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
 
-	if (!IS_QLA8XXX_TYPE(vha->hw))
+	if (!IS_CNA_CAPABLE(vha->hw))
 		return QLA_FUNCTION_FAILED;
 
 	mcp->mb[0] = MBC_GET_DCBX_PARAMS;
@@ -3770,7 +3849,7 @@ qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
 
 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
-	if (IS_QLA8XXX_TYPE(vha->hw))
+	if (IS_CNA_CAPABLE(vha->hw))
 		mcp->out_mb |= MBX_2;
 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
 
@@ -3808,7 +3887,7 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
 	memset(mcp->mb, 0 , sizeof(mcp->mb));
 	mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
 	mcp->mb[1] = mreq->options | BIT_6;	/* BIT_6 specifies 64bit address */
-	if (IS_QLA8XXX_TYPE(ha)) {
+	if (IS_CNA_CAPABLE(ha)) {
 		mcp->mb[1] |= BIT_15;
 		mcp->mb[2] = vha->fcoe_fcf_idx;
 	}
@@ -3826,13 +3905,14 @@ qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
 
 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
 	    MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
-	if (IS_QLA8XXX_TYPE(ha))
+	if (IS_CNA_CAPABLE(ha))
 		mcp->out_mb |= MBX_2;
 
 	mcp->in_mb = MBX_0;
-	if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
+	if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
+	    IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
 		mcp->in_mb |= MBX_1;
-	if (IS_QLA8XXX_TYPE(ha))
+	if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
 		mcp->in_mb |= MBX_3;
 
 	mcp->tov = MBX_TOV_SECONDS;
@@ -3971,6 +4051,7 @@ qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
 
 	return rval;
 }
+
 int
 qla2x00_get_data_rate(scsi_qla_host_t *vha)
 {
@@ -3988,6 +4069,8 @@ qla2x00_get_data_rate(scsi_qla_host_t *vha)
 	mcp->mb[1] = 0;
 	mcp->out_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
+	if (IS_QLA83XX(ha))
+		mcp->in_mb |= MBX_3;
 	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(vha, mcp);
@@ -4013,7 +4096,7 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
 
 	ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
 
-	if (!IS_QLA81XX(ha))
+	if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
 		return QLA_FUNCTION_FAILED;
 	mcp->mb[0] = MBC_GET_PORT_CONFIG;
 	mcp->out_mb = MBX_0;
@@ -4294,6 +4377,90 @@ qla82xx_md_get_template(scsi_qla_host_t *vha)
 }
 
 int
+qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
+{
+	int rval;
+	struct qla_hw_data *ha = vha->hw;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
+		return QLA_FUNCTION_FAILED;
+
+	ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__);
+
+	memset(mcp, 0, sizeof(mbx_cmd_t));
+	mcp->mb[0] = MBC_SET_LED_CONFIG;
+	mcp->mb[1] = led_cfg[0];
+	mcp->mb[2] = led_cfg[1];
+	if (IS_QLA8031(ha)) {
+		mcp->mb[3] = led_cfg[2];
+		mcp->mb[4] = led_cfg[3];
+		mcp->mb[5] = led_cfg[4];
+		mcp->mb[6] = led_cfg[5];
+	}
+
+	mcp->out_mb = MBX_2|MBX_1|MBX_0;
+	if (IS_QLA8031(ha))
+		mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
+	mcp->in_mb = MBX_0;
+	mcp->tov = 30;
+	mcp->flags = 0;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1134,
+		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+	} else {
+		ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+int
+qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
+{
+	int rval;
+	struct qla_hw_data *ha = vha->hw;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
+		return QLA_FUNCTION_FAILED;
+
+	ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__);
+
+	memset(mcp, 0, sizeof(mbx_cmd_t));
+	mcp->mb[0] = MBC_GET_LED_CONFIG;
+
+	mcp->out_mb = MBX_0;
+	mcp->in_mb = MBX_2|MBX_1|MBX_0;
+	if (IS_QLA8031(ha))
+		mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
+	mcp->tov = 30;
+	mcp->flags = 0;
+
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1137,
+		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+	} else {
+		led_cfg[0] = mcp->mb[1];
+		led_cfg[1] = mcp->mb[2];
+		if (IS_QLA8031(ha)) {
+			led_cfg[2] = mcp->mb[3];
+			led_cfg[3] = mcp->mb[4];
+			led_cfg[4] = mcp->mb[5];
+			led_cfg[5] = mcp->mb[6];
+		}
+		ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+int
 qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
 {
 	int rval;
@@ -4316,7 +4483,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
 
 	mcp->out_mb = MBX_7|MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 
 	rval = qla2x00_mailbox_command(vha, mcp);
@@ -4330,3 +4497,75 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
 
 	return rval;
 }
+
+int
+qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
+{
+	int rval;
+	struct qla_hw_data *ha = vha->hw;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (!IS_QLA83XX(ha))
+		return QLA_FUNCTION_FAILED;
+
+	ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__);
+
+	mcp->mb[0] = MBC_WRITE_REMOTE_REG;
+	mcp->mb[1] = LSW(reg);
+	mcp->mb[2] = MSW(reg);
+	mcp->mb[3] = LSW(data);
+	mcp->mb[4] = MSW(data);
+	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+
+	mcp->in_mb = MBX_1|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(vha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		ql_dbg(ql_dbg_mbx, vha, 0x1131,
+		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+	} else {
+		ql_dbg(ql_dbg_mbx, vha, 0x1132,
+		    "Done %s.\n", __func__);
+	}
+
+	return rval;
+}
+
+int
+qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
+{
+	int rval;
+	struct qla_hw_data *ha = vha->hw;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
+		ql_dbg(ql_dbg_mbx, vha, 0x113b,
+		    "Implicit LOGO Unsupported.\n");
+		return QLA_FUNCTION_FAILED;
+	}
+
+
+	ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n",  __func__);
+
+	/* Perform Implicit LOGO. */
+	mcp->mb[0] = MBC_PORT_LOGOUT;
+	mcp->mb[1] = fcport->loop_id;
+	mcp->mb[10] = BIT_15;
+	mcp->out_mb = MBX_10|MBX_1|MBX_0;
+	mcp->in_mb = MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(vha, mcp);
+	if (rval != QLA_SUCCESS)
+		ql_dbg(ql_dbg_mbx, vha, 0x113d,
+		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
+	else
+		ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__);
+
+	return rval;
+}
+
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index f488cc6..aa062a1 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -479,7 +479,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
 	host->max_channel = MAX_BUSES - 1;
 	host->max_lun = ql2xmaxlun;
 	host->unique_id = host->host_no;
-	host->max_id = MAX_TARGETS_2200;
+	host->max_id = ha->max_fibre_devices;
 	host->transportt = qla2xxx_transport_vport_template;
 
 	ql_dbg(ql_dbg_vport, vha, 0xa007,
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 1cd46cd..f052853 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -908,27 +908,37 @@ qla82xx_wait_rom_done(struct qla_hw_data *ha)
 	return 0;
 }
 
+int
+qla82xx_md_rw_32(struct qla_hw_data *ha, uint32_t off, u32 data, uint8_t flag)
+{
+	uint32_t  off_value, rval = 0;
+
+	WRT_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase),
+	    (off & 0xFFFF0000));
+
+	/* Read back value to make sure write has gone through */
+	RD_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase));
+	off_value  = (off & 0x0000FFFF);
+
+	if (flag)
+		WRT_REG_DWORD((void *)
+		    (off_value + CRB_INDIRECT_2M + ha->nx_pcibase),
+		    data);
+	else
+		rval = RD_REG_DWORD((void *)
+		    (off_value + CRB_INDIRECT_2M + ha->nx_pcibase));
+
+	return rval;
+}
+
 static int
 qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)
 {
-	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
+	/* Dword reads to flash. */
+	qla82xx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW, (addr & 0xFFFF0000), 1);
+	*valp = qla82xx_md_rw_32(ha, MD_DIRECT_ROM_READ_BASE +
+	    (addr & 0x0000FFFF), 0, 0);
 
-	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);
-	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
-	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);
-	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0xb);
-	qla82xx_wait_rom_busy(ha);
-	if (qla82xx_wait_rom_done(ha)) {
-		ql_log(ql_log_fatal, vha, 0x00ba,
-		    "Error waiting for rom done.\n");
-		return -1;
-	}
-	/* Reset abyte_cnt and dummy_byte_cnt */
-	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
-	udelay(10);
-	cond_resched();
-	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);
-	*valp = qla82xx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);
 	return 0;
 }
 
@@ -1165,19 +1175,6 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
 		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
 	else
 		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
-
-	/* reset ms */
-	val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
-	val |= (1 << 1);
-	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
-	msleep(20);
-
-	/* unreset ms */
-	val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
-	val &= ~(1 << 1);
-	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
-	msleep(20);
-
 	qla82xx_rom_unlock(ha);
 
 	/* Read the signature value from the flash.
@@ -2053,8 +2050,8 @@ qla82xx_intr_handler(int irq, void *dev_id)
 
 	rsp = (struct rsp_que *) dev_id;
 	if (!rsp) {
-		printk(KERN_INFO
-			"%s(): NULL response queue pointer.\n", __func__);
+		ql_log(ql_log_info, NULL, 0xb054,
+		    "%s: NULL response queue pointer.\n", __func__);
 		return IRQ_NONE;
 	}
 	ha = rsp->hw;
@@ -3149,12 +3146,7 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha)
 	fw_minor_version = ha->fw_minor_version;
 	fw_subminor_version = ha->fw_subminor_version;
 
-	rval = qla2x00_get_fw_version(vha, &ha->fw_major_version,
-	    &ha->fw_minor_version, &ha->fw_subminor_version,
-	    &ha->fw_attributes, &ha->fw_memory_size,
-	    ha->mpi_version, &ha->mpi_capabilities,
-	    ha->phy_version);
-
+	rval = qla2x00_get_fw_version(vha);
 	if (rval != QLA_SUCCESS)
 		return rval;
 
@@ -3163,7 +3155,6 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha)
 			if (fw_major_version != ha->fw_major_version ||
 			    fw_minor_version != ha->fw_minor_version ||
 			    fw_subminor_version != ha->fw_subminor_version) {
-
 				ql_log(ql_log_info, vha, 0xb02d,
 				    "Firmware version differs "
 				    "Previous version: %d:%d:%d - "
@@ -3392,7 +3383,7 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
 					    QLA82XX_CRB_PEG_NET_3 + 0x3c),
 				    qla82xx_rd_32(ha,
 					    QLA82XX_CRB_PEG_NET_4 + 0x3c));
-				if (LSW(MSB(halt_status)) == 0x67)
+				if (((halt_status & 0x1fffff00) >> 8) == 0x67)
 					ql_log(ql_log_warn, vha, 0xb052,
 					    "Firmware aborted with "
 					    "error code 0x00006700. Device is "
@@ -3627,7 +3618,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
 			for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
 				sp = req->outstanding_cmds[cnt];
 				if (sp) {
-					if (!sp->ctx ||
+					if (!sp->u.scmd.ctx ||
 					    (sp->flags & SRB_FCP_CMND_DMA_VALID)) {
 						spin_unlock_irqrestore(
 						    &ha->hardware_lock, flags);
@@ -3658,29 +3649,6 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
 }
 
 /* Minidump related functions */
-int
-qla82xx_md_rw_32(struct qla_hw_data *ha, uint32_t off, u32 data, uint8_t flag)
-{
-	uint32_t  off_value, rval = 0;
-
-	WRT_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase),
-	    (off & 0xFFFF0000));
-
-	/* Read back value to make sure write has gone through */
-	RD_REG_DWORD((void *)(CRB_WINDOW_2M + ha->nx_pcibase));
-	off_value  = (off & 0x0000FFFF);
-
-	if (flag)
-		WRT_REG_DWORD((void *)
-		    (off_value + CRB_INDIRECT_2M + ha->nx_pcibase),
-		    data);
-	else
-		rval = RD_REG_DWORD((void *)
-		    (off_value + CRB_INDIRECT_2M + ha->nx_pcibase));
-
-	return rval;
-}
-
 static int
 qla82xx_minidump_process_control(scsi_qla_host_t *vha,
 	qla82xx_md_entry_hdr_t *entry_hdr, uint32_t **d_ptr)
@@ -4130,8 +4098,9 @@ qla82xx_md_collect(scsi_qla_host_t *vha)
 	data_ptr = (uint32_t *)ha->md_dump;
 
 	if (ha->fw_dumped) {
-		ql_log(ql_log_info, vha, 0xb037,
-		    "Firmware dump available to retrive\n");
+		ql_log(ql_log_warn, vha, 0xb037,
+		    "Firmware has been previously dumped (%p) "
+		    "-- ignoring request.\n", ha->fw_dump);
 		goto md_failed;
 	}
 
@@ -4174,7 +4143,7 @@ qla82xx_md_collect(scsi_qla_host_t *vha)
 
 	total_data_size = ha->md_dump_size;
 
-	ql_dbg(ql_log_info, vha, 0xb03d,
+	ql_dbg(ql_dbg_p3p, vha, 0xb03d,
 	    "Total minidump data_size 0x%x to be captured\n", total_data_size);
 
 	/* Check whether template obtained is valid */
@@ -4297,7 +4266,7 @@ skip_nxt_entry:
 	}
 
 	if (data_collected != total_data_size) {
-		ql_dbg(ql_log_warn, vha, 0xb043,
+		ql_dbg(ql_dbg_p3p, vha, 0xb043,
 		    "MiniDump data mismatch: Data collected: [0x%x],"
 		    "total_data_size:[0x%x]\n",
 		    data_collected, total_data_size);
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index 57a226b..4ac50e2 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -888,7 +888,8 @@ struct ct6_dsd {
 };
 
 #define MBC_TOGGLE_INTERRUPT	0x10
-#define MBC_SET_LED_CONFIG	0x125
+#define MBC_SET_LED_CONFIG	0x125	/* FCoE specific LED control */
+#define MBC_GET_LED_CONFIG	0x126	/* FCoE specific LED control */
 
 /* Flash  offset */
 #define FLT_REG_BOOTLOAD_82XX	0x72
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4ed1e4a..094af74 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -304,7 +304,6 @@ static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
 	struct req_que **, struct rsp_que **);
 static void qla2x00_free_fw_dump(struct qla_hw_data *);
 static void qla2x00_mem_free(struct qla_hw_data *);
-static void qla2x00_sp_free_dma(srb_t *);
 
 /* -------------------------------------------------------------------------- */
 static int qla2x00_alloc_queues(struct qla_hw_data *ha)
@@ -559,28 +558,75 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str)
 	return str;
 }
 
-static inline srb_t *
-qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
-	struct scsi_cmnd *cmd)
+void
+qla2x00_sp_free_dma(void *vha, void *ptr)
 {
-	srb_t *sp;
-	struct qla_hw_data *ha = vha->hw;
+	srb_t *sp = (srb_t *)ptr;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+	struct qla_hw_data *ha = sp->fcport->vha->hw;
+	void *ctx = GET_CMD_CTX_SP(sp);
 
-	sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
-	if (!sp) {
-		ql_log(ql_log_warn, vha, 0x3006,
-		    "Memory allocation failed for sp.\n");
-		return sp;
+	if (sp->flags & SRB_DMA_VALID) {
+		scsi_dma_unmap(cmd);
+		sp->flags &= ~SRB_DMA_VALID;
 	}
 
-	atomic_set(&sp->ref_count, 1);
-	sp->fcport = fcport;
-	sp->cmd = cmd;
-	sp->flags = 0;
-	CMD_SP(cmd) = (void *)sp;
-	sp->ctx = NULL;
+	if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
+		dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
+		    scsi_prot_sg_count(cmd), cmd->sc_data_direction);
+		sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
+	}
 
-	return sp;
+	if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
+		/* List assured to be having elements */
+		qla2x00_clean_dsd_pool(ha, sp);
+		sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
+	}
+
+	if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
+		dma_pool_free(ha->dl_dma_pool, ctx,
+		    ((struct crc_context *)ctx)->crc_ctx_dma);
+		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
+	}
+
+	if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
+		struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
+
+		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
+			ctx1->fcp_cmnd_dma);
+		list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
+		ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
+		ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
+		mempool_free(ctx1, ha->ctx_mempool);
+		ctx1 = NULL;
+	}
+
+	CMD_SP(cmd) = NULL;
+	mempool_free(sp, ha->srb_mempool);
+}
+
+static void
+qla2x00_sp_compl(void *data, void *ptr, int res)
+{
+	struct qla_hw_data *ha = (struct qla_hw_data *)data;
+	srb_t *sp = (srb_t *)ptr;
+	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
+
+	cmd->result = res;
+
+	if (atomic_read(&sp->ref_count) == 0) {
+		ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
+		    "SP reference-count to ZERO -- sp=%p cmd=%p.\n",
+		    sp, GET_CMD_SP(sp));
+		if (ql2xextended_error_logging & ql_dbg_io)
+			BUG();
+		return;
+	}
+	if (!atomic_dec_and_test(&sp->ref_count))
+		return;
+
+	qla2x00_sp_free_dma(ha, sp);
+	cmd->scsi_done(cmd);
 }
 
 static int
@@ -625,6 +671,12 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 			cmd->result = DID_NO_CONNECT << 16;
 			goto qc24_fail_command;
 	}
+
+	if (!fcport) {
+		cmd->result = DID_NO_CONNECT << 16;
+		goto qc24_fail_command;
+	}
+
 	if (atomic_read(&fcport->state) != FCS_ONLINE) {
 		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
 			atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
@@ -638,10 +690,17 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 		goto qc24_target_busy;
 	}
 
-	sp = qla2x00_get_new_sp(base_vha, fcport, cmd);
+	sp = qla2x00_get_sp(base_vha, fcport, GFP_ATOMIC);
 	if (!sp)
 		goto qc24_host_busy;
 
+	sp->u.scmd.cmd = cmd;
+	sp->type = SRB_SCSI_CMD;
+	atomic_set(&sp->ref_count, 1);
+	CMD_SP(cmd) = (void *)sp;
+	sp->free = qla2x00_sp_free_dma;
+	sp->done = qla2x00_sp_compl;
+
 	rval = ha->isp_ops->start_scsi(sp);
 	if (rval != QLA_SUCCESS) {
 		ql_dbg(ql_dbg_io, vha, 0x3013,
@@ -652,8 +711,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 	return 0;
 
 qc24_host_busy_free_sp:
-	qla2x00_sp_free_dma(sp);
-	mempool_free(sp, ha->srb_mempool);
+	qla2x00_sp_free_dma(ha, sp);
 
 qc24_host_busy:
 	return SCSI_MLQUEUE_HOST_BUSY;
@@ -877,6 +935,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	if (ha->isp_ops->abort_command(sp)) {
+		ret = FAILED;
 		ql_dbg(ql_dbg_taskm, vha, 0x8003,
 		    "Abort command mbx failed cmd=%p.\n", cmd);
 	} else {
@@ -886,7 +945,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	}
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	qla2x00_sp_compl(ha, sp);
+	sp->done(ha, sp, 0);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	/* Did the command return during mailbox execution? */
@@ -918,6 +977,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req;
 	srb_t *sp;
+	struct scsi_cmnd *cmd;
 
 	status = QLA_SUCCESS;
 
@@ -928,28 +988,29 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
 		sp = req->outstanding_cmds[cnt];
 		if (!sp)
 			continue;
-		if ((sp->ctx) && !IS_PROT_IO(sp))
+		if (sp->type != SRB_SCSI_CMD)
 			continue;
 		if (vha->vp_idx != sp->fcport->vha->vp_idx)
 			continue;
 		match = 0;
+		cmd = GET_CMD_SP(sp);
 		switch (type) {
 		case WAIT_HOST:
 			match = 1;
 			break;
 		case WAIT_TARGET:
-			match = sp->cmd->device->id == t;
+			match = cmd->device->id == t;
 			break;
 		case WAIT_LUN:
-			match = (sp->cmd->device->id == t &&
-				sp->cmd->device->lun == l);
+			match = (cmd->device->id == t &&
+				cmd->device->lun == l);
 			break;
 		}
 		if (!match)
 			continue;
 
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
-		status = qla2x00_eh_wait_on_command(sp->cmd);
+		status = qla2x00_eh_wait_on_command(cmd);
 		spin_lock_irqsave(&ha->hardware_lock, flags);
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -1124,7 +1185,6 @@ static int
 qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
 {
 	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
-	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
 	struct qla_hw_data *ha = vha->hw;
 	int ret = FAILED;
 	unsigned int id, lun;
@@ -1133,15 +1193,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
 	id = cmd->device->id;
 	lun = cmd->device->lun;
 
-	if (!fcport) {
-		return ret;
-	}
-
-	ret = fc_block_scsi_eh(cmd);
-	if (ret != 0)
-		return ret;
-	ret = FAILED;
-
 	ql_log(ql_log_info, vha, 0x8018,
 	    "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
 
@@ -1222,7 +1273,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 		}
 	}
 
-	if (ha->flags.enable_lip_full_login && !IS_QLA8XXX_TYPE(ha)) {
+	if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) {
 		ret = qla2x00_full_login_lip(vha);
 		if (ret != QLA_SUCCESS) {
 			ql_dbg(ql_dbg_taskm, vha, 0x802d,
@@ -1252,7 +1303,6 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
 	int que, cnt;
 	unsigned long flags;
 	srb_t *sp;
-	struct srb_ctx *ctx;
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req;
 
@@ -1265,31 +1315,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
 			sp = req->outstanding_cmds[cnt];
 			if (sp) {
 				req->outstanding_cmds[cnt] = NULL;
-				if (!sp->ctx ||
-					(sp->flags & SRB_FCP_CMND_DMA_VALID) ||
-					IS_PROT_IO(sp)) {
-					sp->cmd->result = res;
-					qla2x00_sp_compl(ha, sp);
-				} else {
-					ctx = sp->ctx;
-					if (ctx->type == SRB_ELS_CMD_RPT ||
-					    ctx->type == SRB_ELS_CMD_HST ||
-					    ctx->type == SRB_CT_CMD) {
-						struct fc_bsg_job *bsg_job =
-						    ctx->u.bsg_job;
-						if (bsg_job->request->msgcode
-						    == FC_BSG_HST_CT)
-							kfree(sp->fcport);
-						bsg_job->req->errors = 0;
-						bsg_job->reply->result = res;
-						bsg_job->job_done(bsg_job);
-						kfree(sp->ctx);
-						mempool_free(sp,
-							ha->srb_mempool);
-					} else {
-						ctx->u.iocb_cmd->free(sp);
-					}
-				}
+				sp->done(vha, sp, res);
 			}
 		}
 	}
@@ -1491,9 +1517,6 @@ qla2x00_iospace_config(struct qla_hw_data *ha)
 	uint16_t msix;
 	int cpus;
 
-	if (IS_QLA82XX(ha))
-		return qla82xx_iospace_config(ha);
-
 	if (pci_request_selected_regions(ha->pdev, ha->bars,
 	    QLA2XXX_DRIVER_NAME)) {
 		ql_log_pci(ql_log_fatal, ha->pdev, 0x0011,
@@ -1596,6 +1619,96 @@ iospace_error_exit:
 }
 
 
+static int
+qla83xx_iospace_config(struct qla_hw_data *ha)
+{
+	uint16_t msix;
+	int cpus;
+
+	if (pci_request_selected_regions(ha->pdev, ha->bars,
+	    QLA2XXX_DRIVER_NAME)) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0x0117,
+		    "Failed to reserve PIO/MMIO regions (%s), aborting.\n",
+		    pci_name(ha->pdev));
+
+		goto iospace_error_exit;
+	}
+
+	/* Use MMIO operations for all accesses. */
+	if (!(pci_resource_flags(ha->pdev, 0) & IORESOURCE_MEM)) {
+		ql_log_pci(ql_log_warn, ha->pdev, 0x0118,
+		    "Invalid pci I/O region size (%s).\n",
+		    pci_name(ha->pdev));
+		goto iospace_error_exit;
+	}
+	if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
+		ql_log_pci(ql_log_warn, ha->pdev, 0x0119,
+		    "Invalid PCI mem region size (%s), aborting\n",
+			pci_name(ha->pdev));
+		goto iospace_error_exit;
+	}
+
+	ha->iobase = ioremap(pci_resource_start(ha->pdev, 0), MIN_IOBASE_LEN);
+	if (!ha->iobase) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0x011a,
+		    "Cannot remap MMIO (%s), aborting.\n",
+		    pci_name(ha->pdev));
+		goto iospace_error_exit;
+	}
+
+	/* 64bit PCI BAR - BAR2 will correspoond to region 4 */
+	/* 83XX 26XX always use MQ type access for queues
+	 * - mbar 2, a.k.a region 4 */
+	ha->max_req_queues = ha->max_rsp_queues = 1;
+	ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 4),
+			pci_resource_len(ha->pdev, 4));
+
+	if (!ha->mqiobase) {
+		ql_log_pci(ql_log_fatal, ha->pdev, 0x011d,
+		    "BAR2/region4 not enabled\n");
+		goto mqiobase_exit;
+	}
+
+	ha->msixbase = ioremap(pci_resource_start(ha->pdev, 2),
+			pci_resource_len(ha->pdev, 2));
+	if (ha->msixbase) {
+		/* Read MSIX vector size of the board */
+		pci_read_config_word(ha->pdev,
+		    QLA_83XX_PCI_MSIX_CONTROL, &msix);
+		ha->msix_count = msix;
+		/* Max queues are bounded by available msix vectors */
+		/* queue 0 uses two msix vectors */
+		if (ql2xmultique_tag) {
+			cpus = num_online_cpus();
+			ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
+				(cpus + 1) : (ha->msix_count - 1);
+			ha->max_req_queues = 2;
+		} else if (ql2xmaxqueues > 1) {
+			ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
+						QLA_MQ_SIZE : ql2xmaxqueues;
+			ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc00c,
+			    "QoS mode set, max no of request queues:%d.\n",
+			    ha->max_req_queues);
+			ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b,
+			    "QoS mode set, max no of request queues:%d.\n",
+			    ha->max_req_queues);
+		}
+		ql_log_pci(ql_log_info, ha->pdev, 0x011c,
+		    "MSI-X vector count: %d.\n", msix);
+	} else
+		ql_log_pci(ql_log_info, ha->pdev, 0x011e,
+		    "BAR 1 not enabled.\n");
+
+mqiobase_exit:
+	ha->msix_count = ha->max_rsp_queues + 1;
+	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011f,
+	    "MSIX Count:%d.\n", ha->msix_count);
+	return 0;
+
+iospace_error_exit:
+	return -ENOMEM;
+}
+
 static struct isp_operations qla2100_isp_ops = {
 	.pci_config		= qla2100_pci_config,
 	.reset_chip		= qla2x00_reset_chip,
@@ -1772,7 +1885,7 @@ static struct isp_operations qla81xx_isp_ops = {
 	.fw_dump		= qla81xx_fw_dump,
 	.beacon_on		= qla24xx_beacon_on,
 	.beacon_off		= qla24xx_beacon_off,
-	.beacon_blink		= qla24xx_beacon_blink,
+	.beacon_blink		= qla83xx_beacon_blink,
 	.read_optrom		= qla25xx_read_optrom_data,
 	.write_optrom		= qla24xx_write_optrom_data,
 	.get_flash_version	= qla24xx_get_flash_version,
@@ -1818,6 +1931,43 @@ static struct isp_operations qla82xx_isp_ops = {
 	.iospace_config     	= qla82xx_iospace_config,
 };
 
+static struct isp_operations qla83xx_isp_ops = {
+	.pci_config		= qla25xx_pci_config,
+	.reset_chip		= qla24xx_reset_chip,
+	.chip_diag		= qla24xx_chip_diag,
+	.config_rings		= qla24xx_config_rings,
+	.reset_adapter		= qla24xx_reset_adapter,
+	.nvram_config		= qla81xx_nvram_config,
+	.update_fw_options	= qla81xx_update_fw_options,
+	.load_risc		= qla81xx_load_risc,
+	.pci_info_str		= qla24xx_pci_info_str,
+	.fw_version_str		= qla24xx_fw_version_str,
+	.intr_handler		= qla24xx_intr_handler,
+	.enable_intrs		= qla24xx_enable_intrs,
+	.disable_intrs		= qla24xx_disable_intrs,
+	.abort_command		= qla24xx_abort_command,
+	.target_reset		= qla24xx_abort_target,
+	.lun_reset		= qla24xx_lun_reset,
+	.fabric_login		= qla24xx_login_fabric,
+	.fabric_logout		= qla24xx_fabric_logout,
+	.calc_req_entries	= NULL,
+	.build_iocbs		= NULL,
+	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
+	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
+	.read_nvram		= NULL,
+	.write_nvram		= NULL,
+	.fw_dump		= qla83xx_fw_dump,
+	.beacon_on		= qla24xx_beacon_on,
+	.beacon_off		= qla24xx_beacon_off,
+	.beacon_blink		= qla83xx_beacon_blink,
+	.read_optrom		= qla25xx_read_optrom_data,
+	.write_optrom		= qla24xx_write_optrom_data,
+	.get_flash_version	= qla24xx_get_flash_version,
+	.start_scsi		= qla24xx_dif_start_scsi,
+	.abort_isp		= qla2x00_abort_isp,
+	.iospace_config		= qla83xx_iospace_config,
+};
+
 static inline void
 qla2x00_set_isp_flags(struct qla_hw_data *ha)
 {
@@ -1912,6 +2062,22 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
 		/* Initialize 82XX ISP flags */
 		qla82xx_init_flags(ha);
 		break;
+	case PCI_DEVICE_ID_QLOGIC_ISP2031:
+		ha->device_type |= DT_ISP2031;
+		ha->device_type |= DT_ZIO_SUPPORTED;
+		ha->device_type |= DT_FWI2;
+		ha->device_type |= DT_IIDMA;
+		ha->device_type |= DT_T10_PI;
+		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+		break;
+	case PCI_DEVICE_ID_QLOGIC_ISP8031:
+		ha->device_type |= DT_ISP8031;
+		ha->device_type |= DT_ZIO_SUPPORTED;
+		ha->device_type |= DT_FWI2;
+		ha->device_type |= DT_IIDMA;
+		ha->device_type |= DT_T10_PI;
+		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+		break;
 	}
 
 	if (IS_QLA82XX(ha))
@@ -1969,7 +2135,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	char pci_info[30];
 	char fw_str[30];
 	struct scsi_host_template *sht;
-	int bars, max_id, mem_only = 0;
+	int bars, mem_only = 0;
 	uint16_t req_length = 0, rsp_length = 0;
 	struct req_que *req = NULL;
 	struct rsp_que *rsp = NULL;
@@ -1983,7 +2149,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001 ||
-	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021) {
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021 ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031) {
 		bars = pci_select_bars(pdev, IORESOURCE_MEM);
 		mem_only = 1;
 		ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
@@ -2023,9 +2191,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	qla2x00_set_isp_flags(ha);
 
 	/* Set EEH reset type to fundamental if required by hba */
-	if ( IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha)) {
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha))
 		pdev->needs_freset = 1;
-	}
 
 	ha->prev_topology = 0;
 	ha->init_cb_size = sizeof(init_cb_t);
@@ -2033,9 +2200,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	ha->optrom_size = OPTROM_SIZE_2300;
 
 	/* Assign ISP specific operations. */
-	max_id = MAX_TARGETS_2200;
 	if (IS_QLA2100(ha)) {
-		max_id = MAX_TARGETS_2100;
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2100;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
 		req_length = REQUEST_ENTRY_CNT_2100;
 		rsp_length = RESPONSE_ENTRY_CNT_2100;
@@ -2047,7 +2213,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->nvram_data_off = ~0;
 		ha->isp_ops = &qla2100_isp_ops;
 	} else if (IS_QLA2200(ha)) {
-		ha->mbx_count = MAILBOX_REGISTER_COUNT;
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2100;
+		ha->mbx_count = MAILBOX_REGISTER_COUNT_2200;
 		req_length = REQUEST_ENTRY_CNT_2200;
 		rsp_length = RESPONSE_ENTRY_CNT_2100;
 		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
@@ -2058,6 +2225,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->nvram_data_off = ~0;
 		ha->isp_ops = &qla2100_isp_ops;
 	} else if (IS_QLA23XX(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2100;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		req_length = REQUEST_ENTRY_CNT_2200;
 		rsp_length = RESPONSE_ENTRY_CNT_2300;
@@ -2071,6 +2239,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->nvram_data_off = ~0;
 		ha->isp_ops = &qla2300_isp_ops;
 	} else if (IS_QLA24XX_TYPE(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		req_length = REQUEST_ENTRY_CNT_24XX;
 		rsp_length = RESPONSE_ENTRY_CNT_2300;
@@ -2085,6 +2254,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
 		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
 	} else if (IS_QLA25XX(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		req_length = REQUEST_ENTRY_CNT_24XX;
 		rsp_length = RESPONSE_ENTRY_CNT_2300;
@@ -2099,6 +2269,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
 		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
 	} else if (IS_QLA81XX(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		req_length = REQUEST_ENTRY_CNT_24XX;
 		rsp_length = RESPONSE_ENTRY_CNT_2300;
@@ -2113,6 +2284,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->nvram_conf_off = ~0;
 		ha->nvram_data_off = ~0;
 	} else if (IS_QLA82XX(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		req_length = REQUEST_ENTRY_CNT_82XX;
 		rsp_length = RESPONSE_ENTRY_CNT_82XX;
@@ -2126,14 +2298,31 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
 		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
 		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
+	} else if (IS_QLA83XX(ha)) {
+		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
+		ha->mbx_count = MAILBOX_REGISTER_COUNT;
+		req_length = REQUEST_ENTRY_CNT_24XX;
+		rsp_length = RESPONSE_ENTRY_CNT_2300;
+		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
+		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
+		ha->gid_list_info_size = 8;
+		ha->optrom_size = OPTROM_SIZE_83XX;
+		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
+		ha->isp_ops = &qla83xx_isp_ops;
+		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX;
+		ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX;
+		ha->nvram_conf_off = ~0;
+		ha->nvram_data_off = ~0;
 	}
+
 	ql_dbg_pci(ql_dbg_init, pdev, 0x001e,
 	    "mbx_count=%d, req_length=%d, "
 	    "rsp_length=%d, max_loop_id=%d, init_cb_size=%d, "
-	    "gid_list_info_size=%d, optrom_size=%d, nvram_npiv_size=%d, .\n",
+	    "gid_list_info_size=%d, optrom_size=%d, nvram_npiv_size=%d, "
+	    "max_fibre_devices=%d.\n",
 	    ha->mbx_count, req_length, rsp_length, ha->max_loop_id,
 	    ha->init_cb_size, ha->gid_list_info_size, ha->optrom_size,
-	    ha->nvram_npiv_size);
+	    ha->nvram_npiv_size, ha->max_fibre_devices);
 	ql_dbg_pci(ql_dbg_init, pdev, 0x001f,
 	    "isp_ops=%p, flash_conf_off=%d, "
 	    "flash_data_off=%d, nvram_conf_off=%d, nvram_data_off=%d.\n",
@@ -2207,7 +2396,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	    "mgmt_svr_loop_id=%d, sg_tablesize=%d.\n",
 	    host->can_queue, base_vha->req,
 	    base_vha->mgmt_svr_loop_id, host->sg_tablesize);
-	host->max_id = max_id;
+	host->max_id = ha->max_fibre_devices;
 	host->this_id = 255;
 	host->cmd_per_lun = 3;
 	host->unique_id = host->host_no;
@@ -2254,7 +2443,7 @@ que_init:
 	req->req_q_out = &ha->iobase->isp24.req_q_out;
 	rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in;
 	rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out;
-	if (ha->mqenable) {
+	if (ha->mqenable || IS_QLA83XX(ha)) {
 		req->req_q_in = &ha->mqiobase->isp25mq.req_q_in;
 		req->req_q_out = &ha->mqiobase->isp25mq.req_q_out;
 		rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in;
@@ -2555,6 +2744,9 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
 		if (ha->mqiobase)
 			iounmap(ha->mqiobase);
+
+		if (IS_QLA83XX(ha) && ha->msixbase)
+			iounmap(ha->msixbase);
 	}
 
 	pci_release_selected_regions(ha->pdev, ha->bars);
@@ -2754,8 +2946,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
 	if (!ha->init_cb)
 		goto fail;
 
-	ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,
-		&ha->gid_list_dma, GFP_KERNEL);
+	ha->gid_list = dma_alloc_coherent(&ha->pdev->dev,
+		qla2x00_gid_list_size(ha), &ha->gid_list_dma, GFP_KERNEL);
 	if (!ha->gid_list)
 		goto fail_free_init_cb;
 
@@ -2896,7 +3088,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
 		ha->npiv_info = NULL;
 
 	/* Get consistent memory allocated for EX-INIT-CB. */
-	if (IS_QLA8XXX_TYPE(ha)) {
+	if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)) {
 		ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
 		    &ha->ex_init_cb_dma);
 		if (!ha->ex_init_cb)
@@ -2970,7 +3162,8 @@ fail_free_srb_mempool:
 	mempool_destroy(ha->srb_mempool);
 	ha->srb_mempool = NULL;
 fail_free_gid_list:
-	dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
+	dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
+	ha->gid_list,
 	ha->gid_list_dma);
 	ha->gid_list = NULL;
 	ha->gid_list_dma = 0;
@@ -3048,9 +3241,6 @@ qla2x00_mem_free(struct qla_hw_data *ha)
 	if (ha->sfp_data)
 		dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
 
-	if (ha->edc_data)
-		dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma);
-
 	if (ha->ms_iocb)
 		dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
 
@@ -3065,8 +3255,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
 		dma_pool_destroy(ha->s_dma_pool);
 
 	if (ha->gid_list)
-		dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
-		ha->gid_list_dma);
+		dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
+		ha->gid_list, ha->gid_list_dma);
 
 	if (IS_QLA82XX(ha)) {
 		if (!list_empty(&ha->gbl_dsd_list)) {
@@ -3098,6 +3288,7 @@ qla2x00_mem_free(struct qla_hw_data *ha)
 	vfree(ha->optrom_buffer);
 	kfree(ha->nvram);
 	kfree(ha->npiv_info);
+	kfree(ha->swl);
 
 	ha->srb_mempool = NULL;
 	ha->ctx_mempool = NULL;
@@ -3664,75 +3855,6 @@ qla2x00_rst_aen(scsi_qla_host_t *vha)
 	}
 }
 
-static void
-qla2x00_sp_free_dma(srb_t *sp)
-{
-	struct scsi_cmnd *cmd = sp->cmd;
-	struct qla_hw_data *ha = sp->fcport->vha->hw;
-
-	if (sp->flags & SRB_DMA_VALID) {
-		scsi_dma_unmap(cmd);
-		sp->flags &= ~SRB_DMA_VALID;
-	}
-
-	if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
-		dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
-		    scsi_prot_sg_count(cmd), cmd->sc_data_direction);
-		sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
-	}
-
-	if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
-		/* List assured to be having elements */
-		qla2x00_clean_dsd_pool(ha, sp);
-		sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
-	}
-
-	if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
-		dma_pool_free(ha->dl_dma_pool, sp->ctx,
-		    ((struct crc_context *)sp->ctx)->crc_ctx_dma);
-		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
-	}
-
-	if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
-		struct ct6_dsd *ctx = sp->ctx;
-		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd,
-			ctx->fcp_cmnd_dma);
-		list_splice(&ctx->dsd_list, &ha->gbl_dsd_list);
-		ha->gbl_dsd_inuse -= ctx->dsd_use_cnt;
-		ha->gbl_dsd_avail += ctx->dsd_use_cnt;
-		mempool_free(sp->ctx, ha->ctx_mempool);
-		sp->ctx = NULL;
-	}
-
-	CMD_SP(cmd) = NULL;
-}
-
-static void
-qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
-{
-	struct scsi_cmnd *cmd = sp->cmd;
-
-	qla2x00_sp_free_dma(sp);
-	mempool_free(sp, ha->srb_mempool);
-	cmd->scsi_done(cmd);
-}
-
-void
-qla2x00_sp_compl(struct qla_hw_data *ha, srb_t *sp)
-{
-	if (atomic_read(&sp->ref_count) == 0) {
-		ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
-		    "SP reference-count to ZERO -- sp=%p cmd=%p.\n",
-		    sp, sp->cmd);
-		if (ql2xextended_error_logging & ql_dbg_io)
-			BUG();
-		return;
-	}
-	if (!atomic_dec_and_test(&sp->ref_count))
-		return;
-	qla2x00_sp_final_compl(ha, sp);
-}
-
 /**************************************************************************
 *   qla2x00_timer
 *
@@ -3803,7 +3925,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
 					sp = req->outstanding_cmds[index];
 					if (!sp)
 						continue;
-					if (sp->ctx && !IS_PROT_IO(sp))
+					if (sp->type != SRB_SCSI_CMD)
 						continue;
 					sfcp = sp->fcport;
 					if (!(sfcp->flags & FCF_FCP2_DEVICE))
@@ -3892,7 +4014,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
 
 /* Firmware interface routines. */
 
-#define FW_BLOBS	8
+#define FW_BLOBS	10
 #define FW_ISP21XX	0
 #define FW_ISP22XX	1
 #define FW_ISP2300	2
@@ -3901,6 +4023,8 @@ qla2x00_timer(scsi_qla_host_t *vha)
 #define FW_ISP25XX	5
 #define FW_ISP81XX	6
 #define FW_ISP82XX	7
+#define FW_ISP2031	8
+#define FW_ISP8031	9
 
 #define FW_FILE_ISP21XX	"ql2100_fw.bin"
 #define FW_FILE_ISP22XX	"ql2200_fw.bin"
@@ -3910,6 +4034,8 @@ qla2x00_timer(scsi_qla_host_t *vha)
 #define FW_FILE_ISP25XX	"ql2500_fw.bin"
 #define FW_FILE_ISP81XX	"ql8100_fw.bin"
 #define FW_FILE_ISP82XX	"ql8200_fw.bin"
+#define FW_FILE_ISP2031	"ql2600_fw.bin"
+#define FW_FILE_ISP8031	"ql8300_fw.bin"
 
 static DEFINE_MUTEX(qla_fw_lock);
 
@@ -3922,6 +4048,8 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
 	{ .name = FW_FILE_ISP25XX, },
 	{ .name = FW_FILE_ISP81XX, },
 	{ .name = FW_FILE_ISP82XX, },
+	{ .name = FW_FILE_ISP2031, },
+	{ .name = FW_FILE_ISP8031, },
 };
 
 struct fw_blob *
@@ -3947,6 +4075,10 @@ qla2x00_request_firmware(scsi_qla_host_t *vha)
 		blob = &qla_fw_blobs[FW_ISP81XX];
 	} else if (IS_QLA82XX(ha)) {
 		blob = &qla_fw_blobs[FW_ISP82XX];
+	} else if (IS_QLA2031(ha)) {
+		blob = &qla_fw_blobs[FW_ISP2031];
+	} else if (IS_QLA8031(ha)) {
+		blob = &qla_fw_blobs[FW_ISP8031];
 	}
 
 	mutex_lock(&qla_fw_lock);
@@ -4268,6 +4400,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2031) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8001) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) },
 	{ 0 },
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 16bc728..3c13c0a 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -568,6 +568,9 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
 	else if (IS_QLA82XX(ha)) {
 		*start = FA_FLASH_LAYOUT_ADDR_82;
 		goto end;
+	} else if (IS_QLA83XX(ha)) {
+		*start = FA_FLASH_LAYOUT_ADDR_83;
+		goto end;
 	}
 	/* Begin with first PCI expansion ROM header. */
 	buf = (uint8_t *)req->ring;
@@ -721,13 +724,22 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 		    le32_to_cpu(region->size));
 
 		switch (le32_to_cpu(region->code) & 0xff) {
+		case FLT_REG_FCOE_FW:
+			if (!IS_QLA8031(ha))
+				break;
+			ha->flt_region_fw = start;
+			break;
 		case FLT_REG_FW:
+			if (IS_QLA8031(ha))
+				break;
 			ha->flt_region_fw = start;
 			break;
 		case FLT_REG_BOOT_CODE:
 			ha->flt_region_boot = start;
 			break;
 		case FLT_REG_VPD_0:
+			if (IS_QLA8031(ha))
+				break;
 			ha->flt_region_vpd_nvram = start;
 			if (IS_QLA82XX(ha))
 				break;
@@ -735,16 +747,20 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 				ha->flt_region_vpd = start;
 			break;
 		case FLT_REG_VPD_1:
-			if (IS_QLA82XX(ha))
+			if (IS_QLA82XX(ha) || IS_QLA8031(ha))
 				break;
 			if (!ha->flags.port0)
 				ha->flt_region_vpd = start;
 			break;
 		case FLT_REG_NVRAM_0:
+			if (IS_QLA8031(ha))
+				break;
 			if (ha->flags.port0)
 				ha->flt_region_nvram = start;
 			break;
 		case FLT_REG_NVRAM_1:
+			if (IS_QLA8031(ha))
+				break;
 			if (!ha->flags.port0)
 				ha->flt_region_nvram = start;
 			break;
@@ -785,6 +801,31 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 		case FLT_REG_VPD_82XX:
 			ha->flt_region_vpd = start;
 			break;
+		case FLT_REG_FCOE_VPD_0:
+			if (!IS_QLA8031(ha))
+				break;
+			ha->flt_region_vpd_nvram = start;
+			if (ha->flags.port0)
+				ha->flt_region_vpd = start;
+			break;
+		case FLT_REG_FCOE_VPD_1:
+			if (!IS_QLA8031(ha))
+				break;
+			if (!ha->flags.port0)
+				ha->flt_region_vpd = start;
+			break;
+		case FLT_REG_FCOE_NVRAM_0:
+			if (!IS_QLA8031(ha))
+				break;
+			if (ha->flags.port0)
+				ha->flt_region_nvram = start;
+			break;
+		case FLT_REG_FCOE_NVRAM_1:
+			if (!IS_QLA8031(ha))
+				break;
+			if (!ha->flags.port0)
+				ha->flt_region_nvram = start;
+			break;
 		}
 	}
 	goto done;
@@ -804,15 +845,12 @@ no_flash_data:
 	    def_npiv_conf0[def] : def_npiv_conf1[def];
 done:
 	ql_dbg(ql_dbg_init, vha, 0x004a,
-	    "FLT[%s]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x.\n",
-	    loc, ha->flt_region_boot,
-	    ha->flt_region_fw, ha->flt_region_vpd_nvram,
-	    ha->flt_region_vpd);
-	ql_dbg(ql_dbg_init, vha, 0x004b,
-	    "nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x.\n",
-	    ha->flt_region_nvram,
-	    ha->flt_region_fdt, ha->flt_region_flt,
-	    ha->flt_region_npiv_conf, ha->flt_region_fcp_prio);
+	    "FLT[%s]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram=0x%x "
+	    "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x.\n",
+	    loc, ha->flt_region_boot, ha->flt_region_fw,
+	    ha->flt_region_vpd_nvram, ha->flt_region_vpd, ha->flt_region_nvram,
+	    ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_npiv_conf,
+	    ha->flt_region_fcp_prio);
 }
 
 static void
@@ -948,7 +986,8 @@ qla2xxx_get_flash_info(scsi_qla_host_t *vha)
 	uint32_t flt_addr;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA8XXX_TYPE(ha))
+	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
+	    !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha))
 		return QLA_SUCCESS;
 
 	ret = qla2xxx_find_flt_start(vha, &flt_addr);
@@ -974,7 +1013,8 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
 	struct qla_npiv_entry *entry;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA8XXX_TYPE(ha))
+	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
+	    !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha))
 		return;
 
 	ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
@@ -1144,8 +1184,8 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
 	struct qla_hw_data *ha = vha->hw;
 
 	/* Prepare burst-capable write on supported ISPs. */
-	if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
-	    dwords > OPTROM_BURST_DWORDS) {
+	if ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha)) &&
+	    !(faddr & 0xfff) && dwords > OPTROM_BURST_DWORDS) {
 		optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,
 		    &optrom_dma, GFP_KERNEL);
 		if (!optrom) {
@@ -1619,6 +1659,71 @@ qla24xx_beacon_blink(struct scsi_qla_host *vha)
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
+void
+qla83xx_beacon_blink(struct scsi_qla_host *vha)
+{
+	uint32_t led_select_value;
+	struct qla_hw_data *ha = vha->hw;
+	uint16_t led_cfg[6];
+	uint16_t orig_led_cfg[6];
+
+	if (!IS_QLA83XX(ha) && !IS_QLA81XX(ha))
+		return;
+
+	if (IS_QLA2031(ha) && ha->beacon_blink_led) {
+		if (ha->flags.port0)
+			led_select_value = 0x00201320;
+		else
+			led_select_value = 0x00201328;
+
+		qla83xx_write_remote_reg(vha, led_select_value, 0x40002000);
+		qla83xx_write_remote_reg(vha, led_select_value + 4, 0x40002000);
+		msleep(1000);
+		qla83xx_write_remote_reg(vha, led_select_value, 0x40004000);
+		qla83xx_write_remote_reg(vha, led_select_value + 4, 0x40004000);
+	} else if ((IS_QLA8031(ha) || IS_QLA81XX(ha)) && ha->beacon_blink_led) {
+		int rval;
+
+		/* Save Current */
+		rval = qla81xx_get_led_config(vha, orig_led_cfg);
+		/* Do the blink */
+		if (rval == QLA_SUCCESS) {
+			if (IS_QLA81XX(ha)) {
+				led_cfg[0] = 0x4000;
+				led_cfg[1] = 0x2000;
+				led_cfg[2] = 0;
+				led_cfg[3] = 0;
+				led_cfg[4] = 0;
+				led_cfg[5] = 0;
+			} else {
+				led_cfg[0] = 0x4000;
+				led_cfg[1] = 0x4000;
+				led_cfg[2] = 0x4000;
+				led_cfg[3] = 0x2000;
+				led_cfg[4] = 0;
+				led_cfg[5] = 0x2000;
+			}
+			rval = qla81xx_set_led_config(vha, led_cfg);
+			msleep(1000);
+			if (IS_QLA81XX(ha)) {
+				led_cfg[0] = 0x4000;
+				led_cfg[1] = 0x2000;
+				led_cfg[2] = 0;
+			} else {
+				led_cfg[0] = 0x4000;
+				led_cfg[1] = 0x2000;
+				led_cfg[2] = 0x4000;
+				led_cfg[3] = 0x4000;
+				led_cfg[4] = 0;
+				led_cfg[5] = 0x2000;
+			}
+			rval = qla81xx_set_led_config(vha, led_cfg);
+		}
+		/* On exit, restore original (presumes no status change) */
+		qla81xx_set_led_config(vha, orig_led_cfg);
+	}
+}
+
 int
 qla24xx_beacon_on(struct scsi_qla_host *vha)
 {
@@ -1630,6 +1735,9 @@ qla24xx_beacon_on(struct scsi_qla_host *vha)
 	if (IS_QLA82XX(ha))
 		return QLA_SUCCESS;
 
+	if (IS_QLA8031(ha) || IS_QLA81XX(ha))
+		goto skip_gpio; /* let blink handle it */
+
 	if (ha->beacon_blink_led == 0) {
 		/* Enable firmware for update */
 		ha->fw_options[1] |= ADD_FO1_DISABLE_GPIO_LED_CTRL;
@@ -1644,6 +1752,9 @@ qla24xx_beacon_on(struct scsi_qla_host *vha)
 			return QLA_FUNCTION_FAILED;
 		}
 
+		if (IS_QLA2031(ha))
+			goto skip_gpio;
+
 		spin_lock_irqsave(&ha->hardware_lock, flags);
 		gpio_data = RD_REG_DWORD(&reg->gpiod);
 
@@ -1658,6 +1769,7 @@ qla24xx_beacon_on(struct scsi_qla_host *vha)
 	/* So all colors blink together. */
 	ha->beacon_color_state = 0;
 
+skip_gpio:
 	/* Let the per HBA timer kick off the blinking process. */
 	ha->beacon_blink_led = 1;
 
@@ -1676,6 +1788,13 @@ qla24xx_beacon_off(struct scsi_qla_host *vha)
 		return QLA_SUCCESS;
 
 	ha->beacon_blink_led = 0;
+
+	if (IS_QLA2031(ha))
+		goto set_fw_options;
+
+	if (IS_QLA8031(ha) || IS_QLA81XX(ha))
+		return QLA_SUCCESS;
+
 	ha->beacon_color_state = QLA_LED_ALL_ON;
 
 	ha->isp_ops->beacon_blink(vha);	/* Will flip to all off. */
@@ -1690,6 +1809,7 @@ qla24xx_beacon_off(struct scsi_qla_host *vha)
 	RD_REG_DWORD(&reg->gpiod);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
+set_fw_options:
 	ha->fw_options[1] &= ~ADD_FO1_DISABLE_GPIO_LED_CTRL;
 
 	if (qla2x00_set_fw_options(vha, ha->fw_options) != QLA_SUCCESS) {
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 23f33a6..29d780c 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.07.12-k"
+#define QLA2XXX_VERSION      "8.03.07.13-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	3
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index bfe6854..776714d 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -150,8 +150,6 @@
 #define QL4_SESS_RECOVERY_TMO		120	/* iSCSI session */
 						/* recovery timeout */
 
-#define MSB(x) ((uint8_t)((uint16_t)(x) >> 8))
-#define LSW(x) ((uint16_t)(x))
 #define LSDW(x) ((u32)((u64)(x)))
 #define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))
 
@@ -223,6 +221,15 @@ struct srb {
 	uint16_t reserved2;
 };
 
+/* Mailbox request block structure */
+struct mrb {
+	struct scsi_qla_host *ha;
+	struct mbox_cmd_iocb *mbox;
+	uint32_t mbox_cmd;
+	uint16_t iocb_cnt;		/* Number of used iocbs */
+	uint32_t pid;
+};
+
 /*
  * Asynchronous Event Queue structure
  */
@@ -303,7 +310,28 @@ struct ql4_tuple_ddb {
 #define DF_ISNS_DISCOVERED	2	/* Device was discovered via iSNS */
 #define DF_FO_MASKED		3
 
+enum qla4_work_type {
+	QLA4_EVENT_AEN,
+	QLA4_EVENT_PING_STATUS,
+};
 
+struct qla4_work_evt {
+	struct list_head list;
+	enum qla4_work_type type;
+	union {
+		struct {
+			enum iscsi_host_event_code code;
+			uint32_t data_size;
+			uint8_t data[0];
+		} aen;
+		struct {
+			uint32_t status;
+			uint32_t pid;
+			uint32_t data_size;
+			uint8_t data[0];
+		} ping;
+	} u;
+};
 
 struct ql82xx_hw_data {
 	/* Offsets for flash/nvram access (set to ~0 if not used). */
@@ -674,6 +702,15 @@ struct scsi_qla_host {
 	uint16_t sec_ddb_idx;
 	int is_reset;
 	uint16_t temperature;
+
+	/* event work list */
+	struct list_head work_list;
+	spinlock_t work_lock;
+
+	/* mbox iocb */
+#define MAX_MRB		128
+	struct mrb *active_mrb_array[MAX_MRB];
+	uint32_t mrb_index;
 };
 
 struct ql4_task_data {
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 7825c14..210cd1d 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -331,6 +331,10 @@ struct qla_flt_region {
 /*  Mailbox command definitions */
 #define MBOX_CMD_ABOUT_FW			0x0009
 #define MBOX_CMD_PING				0x000B
+#define PING_IPV6_PROTOCOL_ENABLE		0x1
+#define PING_IPV6_LINKLOCAL_ADDR		0x4
+#define PING_IPV6_ADDR0				0x8
+#define PING_IPV6_ADDR1				0xC
 #define MBOX_CMD_ENABLE_INTRS			0x0010
 #define INTR_DISABLE				0
 #define INTR_ENABLE				1
@@ -396,6 +400,10 @@ struct qla_flt_region {
 #define FW_ADDSTATE_DHCPv4_LEASE_EXPIRED	0x0008
 #define FW_ADDSTATE_LINK_UP			0x0010
 #define FW_ADDSTATE_ISNS_SVC_ENABLED		0x0020
+#define FW_ADDSTATE_LINK_SPEED_10MBPS		0x0100
+#define FW_ADDSTATE_LINK_SPEED_100MBPS		0x0200
+#define FW_ADDSTATE_LINK_SPEED_1GBPS		0x0400
+#define FW_ADDSTATE_LINK_SPEED_10GBPS		0x0800
 
 #define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS	0x006B
 #define IPV6_DEFAULT_DDB_ENTRY			0x0001
@@ -918,6 +926,8 @@ struct qla4_header {
 #define ET_CMND_T3		 0x19
 #define ET_PASSTHRU0		 0x3A
 #define ET_PASSTHRU_STATUS	 0x3C
+#define ET_MBOX_CMD		0x38
+#define ET_MBOX_STATUS		0x39
 
 	uint8_t entryStatus;
 	uint8_t systemDefined;
@@ -1118,6 +1128,20 @@ struct passthru_status {
 	uint8_t res4[16];	/* 30-3F */
 };
 
+struct mbox_cmd_iocb {
+	struct qla4_header hdr;	/* 00-03 */
+	uint32_t handle;	/* 04-07 */
+	uint32_t in_mbox[8];	/* 08-25 */
+	uint32_t res1[6];	/* 26-3F */
+};
+
+struct mbox_status_iocb {
+	struct qla4_header hdr;	/* 00-03 */
+	uint32_t handle;	/* 04-07 */
+	uint32_t out_mbox[8];	/* 08-25 */
+	uint32_t res1[6];	/* 26-3F */
+};
+
 /*
  * ISP queue - response queue entry definition.
  */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index d0dd4b3..954ba91 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -181,6 +181,13 @@ int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
 int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
 		       struct ddb_entry *ddb_entry, uint32_t state);
 void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset);
+int qla4xxx_post_aen_work(struct scsi_qla_host *ha, uint32_t aen_code,
+			  uint32_t data_size, uint8_t *data);
+int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
+		      uint32_t payload_size, uint32_t pid, uint8_t *ipaddr);
+int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
+			       uint32_t status, uint32_t pid,
+			       uint32_t data_size, uint8_t *data);
 
 /* BSG Functions */
 int qla4xxx_bsg_request(struct bsg_job *bsg_job);
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 90614f3..90ee5d8 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -86,6 +86,7 @@ static void qla4xxx_init_response_q_entries(struct scsi_qla_host *ha)
 int qla4xxx_init_rings(struct scsi_qla_host *ha)
 {
 	unsigned long flags = 0;
+	int i;
 
 	/* Initialize request queue. */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -125,6 +126,10 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)
 
 	qla4xxx_init_response_q_entries(ha);
 
+	/* Initialize mabilbox active array */
+	for (i = 0; i < MAX_MRB; i++)
+		ha->active_mrb_array[i] = NULL;
+
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	return QLA_SUCCESS;
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index 4106693..c70651d 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -445,3 +445,95 @@ queuing_error:
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	return ret;
 }
+
+static struct mrb *qla4xxx_get_new_mrb(struct scsi_qla_host *ha)
+{
+	struct mrb *mrb;
+
+	mrb = kzalloc(sizeof(*mrb), GFP_KERNEL);
+	if (!mrb)
+		return mrb;
+
+	mrb->ha = ha;
+	return mrb;
+}
+
+int qla4xxx_send_mbox_iocb(struct scsi_qla_host *ha, struct mrb *mrb,
+			   uint32_t *in_mbox)
+{
+	int rval = QLA_SUCCESS;
+	uint32_t i;
+	unsigned long flags;
+	uint32_t index = 0;
+
+	/* Acquire hardware specific lock */
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+
+	/* Get pointer to the queue entry for the marker */
+	rval = qla4xxx_get_req_pkt(ha, (struct queue_entry **) &(mrb->mbox));
+	if (rval != QLA_SUCCESS)
+		goto exit_mbox_iocb;
+
+	index = ha->mrb_index;
+	/* get valid mrb index*/
+	for (i = 0; i < MAX_MRB; i++) {
+		index++;
+		if (index == MAX_MRB)
+			index = 1;
+		if (ha->active_mrb_array[index] == NULL) {
+			ha->mrb_index = index;
+			break;
+		}
+	}
+
+	mrb->iocb_cnt = 1;
+	ha->active_mrb_array[index] = mrb;
+	mrb->mbox->handle = index;
+	mrb->mbox->hdr.entryType = ET_MBOX_CMD;
+	mrb->mbox->hdr.entryCount = mrb->iocb_cnt;
+	memcpy(mrb->mbox->in_mbox, in_mbox, 32);
+	mrb->mbox_cmd = in_mbox[0];
+	wmb();
+
+	ha->isp_ops->queue_iocb(ha);
+exit_mbox_iocb:
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	return rval;
+}
+
+int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
+		      uint32_t payload_size, uint32_t pid, uint8_t *ipaddr)
+{
+	uint32_t in_mbox[8];
+	struct mrb *mrb = NULL;
+	int rval = QLA_SUCCESS;
+
+	memset(in_mbox, 0, sizeof(in_mbox));
+
+	mrb = qla4xxx_get_new_mrb(ha);
+	if (!mrb) {
+		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: fail to get new mrb\n",
+				  __func__));
+		rval = QLA_ERROR;
+		goto exit_ping;
+	}
+
+	in_mbox[0] = MBOX_CMD_PING;
+	in_mbox[1] = options;
+	memcpy(&in_mbox[2], &ipaddr[0], 4);
+	memcpy(&in_mbox[3], &ipaddr[4], 4);
+	memcpy(&in_mbox[4], &ipaddr[8], 4);
+	memcpy(&in_mbox[5], &ipaddr[12], 4);
+	in_mbox[6] = payload_size;
+
+	mrb->pid = pid;
+	rval = qla4xxx_send_mbox_iocb(ha, mrb, in_mbox);
+
+	if (rval != QLA_SUCCESS)
+		goto exit_ping;
+
+	return rval;
+exit_ping:
+	kfree(mrb);
+	return rval;
+}
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 9582886..7c9f28b 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -385,6 +385,71 @@ static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha,
 	queue_work(ha->task_wq, &task_data->task_work);
 }
 
+static struct mrb *qla4xxx_del_mrb_from_active_array(struct scsi_qla_host *ha,
+						     uint32_t index)
+{
+	struct mrb *mrb = NULL;
+
+	/* validate handle and remove from active array */
+	if (index >= MAX_MRB)
+		return mrb;
+
+	mrb = ha->active_mrb_array[index];
+	ha->active_mrb_array[index] = NULL;
+	if (!mrb)
+		return mrb;
+
+	/* update counters */
+	ha->req_q_count += mrb->iocb_cnt;
+	ha->iocb_cnt -= mrb->iocb_cnt;
+
+	return mrb;
+}
+
+static void qla4xxx_mbox_status_entry(struct scsi_qla_host *ha,
+				      struct mbox_status_iocb *mbox_sts_entry)
+{
+	struct mrb *mrb;
+	uint32_t status;
+	uint32_t data_size;
+
+	mrb = qla4xxx_del_mrb_from_active_array(ha,
+					le32_to_cpu(mbox_sts_entry->handle));
+
+	if (mrb == NULL) {
+		ql4_printk(KERN_WARNING, ha, "%s: mrb[%d] is null\n", __func__,
+			   mbox_sts_entry->handle);
+		return;
+	}
+
+	switch (mrb->mbox_cmd) {
+	case MBOX_CMD_PING:
+		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: mbox_cmd = 0x%x, "
+				  "mbox_sts[0] = 0x%x, mbox_sts[6] = 0x%x\n",
+				  __func__, mrb->mbox_cmd,
+				  mbox_sts_entry->out_mbox[0],
+				  mbox_sts_entry->out_mbox[6]));
+
+		if (mbox_sts_entry->out_mbox[0] == MBOX_STS_COMMAND_COMPLETE)
+			status = QLA_SUCCESS;
+		else
+			status = QLA_ERROR;
+
+		data_size = sizeof(mbox_sts_entry->out_mbox);
+
+		qla4xxx_post_ping_evt_work(ha, status, mrb->pid, data_size,
+					(uint8_t *) mbox_sts_entry->out_mbox);
+		break;
+
+	default:
+		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: invalid mbox_cmd = "
+				  "0x%x\n", __func__, mrb->mbox_cmd));
+	}
+
+	kfree(mrb);
+	return;
+}
+
 /**
  * qla4xxx_process_response_queue - process response queue completions
  * @ha: Pointer to host adapter structure.
@@ -461,6 +526,13 @@ void qla4xxx_process_response_queue(struct scsi_qla_host *ha)
 				      "ignoring\n", ha->host_no, __func__));
 			break;
 
+		case ET_MBOX_STATUS:
+			DEBUG2(ql4_printk(KERN_INFO, ha,
+					  "%s: mbox status IOCB\n", __func__));
+			qla4xxx_mbox_status_entry(ha,
+					(struct mbox_status_iocb *)sts_entry);
+			break;
+
 		default:
 			/*
 			 * Invalid entry in response queue, reset RISC
@@ -576,6 +648,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 				set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
 
 			ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__);
+			qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKUP,
+					      sizeof(mbox_sts),
+					      (uint8_t *) mbox_sts);
 			break;
 
 		case MBOX_ASTS_LINK_DOWN:
@@ -584,6 +659,9 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
 				set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
 
 			ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__);
+			qla4xxx_post_aen_work(ha, ISCSI_EVENT_LINKDOWN,
+					      sizeof(mbox_sts),
+					      (uint8_t *) mbox_sts);
 			break;
 
 		case MBOX_ASTS_HEARTBEAT:
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index e1e66a4..eaf2185 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -661,6 +661,8 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
 	}
 	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 	memset(&mbox_sts, 0, sizeof(mbox_sts));
+	if (fw_ddb_entry)
+		memset(fw_ddb_entry, 0, sizeof(struct dev_db_entry));
 
 	mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
 	mbox_cmd[1] = (uint32_t) fw_ddb_index;
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 78f1111..af8dcf6 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -860,11 +860,8 @@ qla4_8xxx_rom_lock(struct scsi_qla_host *ha)
 		done = qla4_8xxx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));
 		if (done == 1)
 			break;
-		if (timeout >= qla4_8xxx_rom_lock_timeout) {
-			ql4_printk(KERN_WARNING, ha,
-			    "%s: Failed to acquire rom lock", __func__);
+		if (timeout >= qla4_8xxx_rom_lock_timeout)
 			return -1;
-		}
 
 		timeout++;
 
@@ -1015,18 +1012,6 @@ qla4_8xxx_pinit_from_rom(struct scsi_qla_host *ha, int verbose)
 	else
 		qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
 
-	/* reset ms */
-	val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
-	val |= (1 << 1);
-	qla4_8xxx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
-
-	msleep(20);
-	/* unreset ms */
-	val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
-	val &= ~(1 << 1);
-	qla4_8xxx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
-	msleep(20);
-
 	qla4_8xxx_rom_unlock(ha);
 
 	/* Read the signature value from the flash.
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index dc45ac9..dc7500e 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -623,6 +623,7 @@ struct crb_addr_pair {
 
 #define ADDR_ERROR	((unsigned long) 0xffffffff)
 #define MAX_CTL_CHECK	1000
+#define QLA82XX_FWERROR_CODE(code)	((code >> 8) & 0x1fffff)
 
 /***************************************************************************
  *		PCI related defines.
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index ce6d3b7..877c0e2 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -118,6 +118,10 @@ static void qla4xxx_task_cleanup(struct iscsi_task *);
 static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session);
 static void qla4xxx_conn_get_stats(struct iscsi_cls_conn *cls_conn,
 				   struct iscsi_stats *stats);
+static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
+			     uint32_t iface_type, uint32_t payload_size,
+			     uint32_t pid, struct sockaddr *dst_addr);
+
 /*
  * SCSI host template entry points
  */
@@ -194,10 +198,91 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
 	.set_iface_param	= qla4xxx_iface_set_param,
 	.get_iface_param	= qla4xxx_get_iface_param,
 	.bsg_request		= qla4xxx_bsg_request,
+	.send_ping		= qla4xxx_send_ping,
 };
 
 static struct scsi_transport_template *qla4xxx_scsi_transport;
 
+static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,
+			     uint32_t iface_type, uint32_t payload_size,
+			     uint32_t pid, struct sockaddr *dst_addr)
+{
+	struct scsi_qla_host *ha = to_qla_host(shost);
+	struct sockaddr_in *addr;
+	struct sockaddr_in6 *addr6;
+	uint32_t options = 0;
+	uint8_t ipaddr[IPv6_ADDR_LEN];
+	int rval;
+
+	memset(ipaddr, 0, IPv6_ADDR_LEN);
+	/* IPv4 to IPv4 */
+	if ((iface_type == ISCSI_IFACE_TYPE_IPV4) &&
+	    (dst_addr->sa_family == AF_INET)) {
+		addr = (struct sockaddr_in *)dst_addr;
+		memcpy(ipaddr, &addr->sin_addr.s_addr, IP_ADDR_LEN);
+		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv4 Ping src: %pI4 "
+				  "dest: %pI4\n", __func__,
+				  &ha->ip_config.ip_address, ipaddr));
+		rval = qla4xxx_ping_iocb(ha, options, payload_size, pid,
+					 ipaddr);
+		if (rval)
+			rval = -EINVAL;
+	} else if ((iface_type == ISCSI_IFACE_TYPE_IPV6) &&
+		   (dst_addr->sa_family == AF_INET6)) {
+		/* IPv6 to IPv6 */
+		addr6 = (struct sockaddr_in6 *)dst_addr;
+		memcpy(ipaddr, &addr6->sin6_addr.in6_u.u6_addr8, IPv6_ADDR_LEN);
+
+		options |= PING_IPV6_PROTOCOL_ENABLE;
+
+		/* Ping using LinkLocal address */
+		if ((iface_num == 0) || (iface_num == 1)) {
+			DEBUG2(ql4_printk(KERN_INFO, ha, "%s: LinkLocal Ping "
+					  "src: %pI6 dest: %pI6\n", __func__,
+					  &ha->ip_config.ipv6_link_local_addr,
+					  ipaddr));
+			options |= PING_IPV6_LINKLOCAL_ADDR;
+			rval = qla4xxx_ping_iocb(ha, options, payload_size,
+						 pid, ipaddr);
+		} else {
+			ql4_printk(KERN_WARNING, ha, "%s: iface num = %d "
+				   "not supported\n", __func__, iface_num);
+			rval = -ENOSYS;
+			goto exit_send_ping;
+		}
+
+		/*
+		 * If ping using LinkLocal address fails, try ping using
+		 * IPv6 address
+		 */
+		if (rval != QLA_SUCCESS) {
+			options &= ~PING_IPV6_LINKLOCAL_ADDR;
+			if (iface_num == 0) {
+				options |= PING_IPV6_ADDR0;
+				DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv6 "
+						  "Ping src: %pI6 "
+						  "dest: %pI6\n", __func__,
+						  &ha->ip_config.ipv6_addr0,
+						  ipaddr));
+			} else if (iface_num == 1) {
+				options |= PING_IPV6_ADDR1;
+				DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv6 "
+						  "Ping src: %pI6 "
+						  "dest: %pI6\n", __func__,
+						  &ha->ip_config.ipv6_addr1,
+						  ipaddr));
+			}
+			rval = qla4xxx_ping_iocb(ha, options, payload_size,
+						 pid, ipaddr);
+			if (rval)
+				rval = -EINVAL;
+		}
+	} else
+		rval = -ENOSYS;
+exit_send_ping:
+	return rval;
+}
+
 static umode_t ql4_attr_is_visible(int param_type, int param)
 {
 	switch (param_type) {
@@ -206,6 +291,8 @@ static umode_t ql4_attr_is_visible(int param_type, int param)
 		case ISCSI_HOST_PARAM_HWADDRESS:
 		case ISCSI_HOST_PARAM_IPADDRESS:
 		case ISCSI_HOST_PARAM_INITIATOR_NAME:
+		case ISCSI_HOST_PARAM_PORT_STATE:
+		case ISCSI_HOST_PARAM_PORT_SPEED:
 			return S_IRUGO;
 		default:
 			return 0;
@@ -548,6 +635,43 @@ static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc)
 	return ret;
 }
 
+static void qla4xxx_set_port_speed(struct Scsi_Host *shost)
+{
+	struct scsi_qla_host *ha = to_qla_host(shost);
+	struct iscsi_cls_host *ihost = shost_priv(shost);
+	uint32_t speed = ISCSI_PORT_SPEED_UNKNOWN;
+
+	qla4xxx_get_firmware_state(ha);
+
+	switch (ha->addl_fw_state & 0x0F00) {
+	case FW_ADDSTATE_LINK_SPEED_10MBPS:
+		speed = ISCSI_PORT_SPEED_10MBPS;
+		break;
+	case FW_ADDSTATE_LINK_SPEED_100MBPS:
+		speed = ISCSI_PORT_SPEED_100MBPS;
+		break;
+	case FW_ADDSTATE_LINK_SPEED_1GBPS:
+		speed = ISCSI_PORT_SPEED_1GBPS;
+		break;
+	case FW_ADDSTATE_LINK_SPEED_10GBPS:
+		speed = ISCSI_PORT_SPEED_10GBPS;
+		break;
+	}
+	ihost->port_speed = speed;
+}
+
+static void qla4xxx_set_port_state(struct Scsi_Host *shost)
+{
+	struct scsi_qla_host *ha = to_qla_host(shost);
+	struct iscsi_cls_host *ihost = shost_priv(shost);
+	uint32_t state = ISCSI_PORT_STATE_DOWN;
+
+	if (test_bit(AF_LINK_UP, &ha->flags))
+		state = ISCSI_PORT_STATE_UP;
+
+	ihost->port_state = state;
+}
+
 static int qla4xxx_host_get_param(struct Scsi_Host *shost,
 				  enum iscsi_host_param param, char *buf)
 {
@@ -564,6 +688,14 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
 	case ISCSI_HOST_PARAM_INITIATOR_NAME:
 		len = sprintf(buf, "%s\n", ha->name_string);
 		break;
+	case ISCSI_HOST_PARAM_PORT_STATE:
+		qla4xxx_set_port_state(shost);
+		len = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost));
+		break;
+	case ISCSI_HOST_PARAM_PORT_SPEED:
+		qla4xxx_set_port_speed(shost);
+		len = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));
+		break;
 	default:
 		return -ENOSYS;
 	}
@@ -1552,6 +1684,8 @@ static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha,
 			(char *)ha->name_string, buflen);
 	iscsi_set_param(cls_conn, ISCSI_PARAM_PERSISTENT_ADDRESS,
 			(char *)ip_addr, buflen);
+	iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_ALIAS,
+			(char *)fw_ddb_entry->iscsi_alias, buflen);
 }
 
 void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha,
@@ -1666,6 +1800,9 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
 	memcpy(sess->initiatorname, ha->name_string,
 	       min(sizeof(ha->name_string), sizeof(sess->initiatorname)));
 
+	iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_ALIAS,
+			(char *)fw_ddb_entry->iscsi_alias, 0);
+
 exit_session_conn_param:
 	if (fw_ddb_entry)
 		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
@@ -2113,7 +2250,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
 				halt_status = qla4_8xxx_rd_32(ha,
 						QLA82XX_PEG_HALT_STATUS1);
 
-				if (LSW(MSB(halt_status)) == 0x67)
+				if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
 					ql4_printk(KERN_ERR, ha, "%s:"
 						   " Firmware aborted with"
 						   " error code 0x00006700."
@@ -2230,6 +2367,10 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
 		}
 	}
 
+	/* Process any deferred work. */
+	if (!list_empty(&ha->work_list))
+		start_dpc++;
+
 	/* Wakeup the dpc routine for this adapter, if needed. */
 	if (start_dpc ||
 	     test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
@@ -2795,6 +2936,109 @@ void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
 		queue_work(ha->dpc_thread, &ha->dpc_work);
 }
 
+static struct qla4_work_evt *
+qla4xxx_alloc_work(struct scsi_qla_host *ha, uint32_t data_size,
+		   enum qla4_work_type type)
+{
+	struct qla4_work_evt *e;
+	uint32_t size = sizeof(struct qla4_work_evt) + data_size;
+
+	e = kzalloc(size, GFP_ATOMIC);
+	if (!e)
+		return NULL;
+
+	INIT_LIST_HEAD(&e->list);
+	e->type = type;
+	return e;
+}
+
+static void qla4xxx_post_work(struct scsi_qla_host *ha,
+			     struct qla4_work_evt *e)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ha->work_lock, flags);
+	list_add_tail(&e->list, &ha->work_list);
+	spin_unlock_irqrestore(&ha->work_lock, flags);
+	qla4xxx_wake_dpc(ha);
+}
+
+int qla4xxx_post_aen_work(struct scsi_qla_host *ha,
+			  enum iscsi_host_event_code aen_code,
+			  uint32_t data_size, uint8_t *data)
+{
+	struct qla4_work_evt *e;
+
+	e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_AEN);
+	if (!e)
+		return QLA_ERROR;
+
+	e->u.aen.code = aen_code;
+	e->u.aen.data_size = data_size;
+	memcpy(e->u.aen.data, data, data_size);
+
+	qla4xxx_post_work(ha, e);
+
+	return QLA_SUCCESS;
+}
+
+int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
+			       uint32_t status, uint32_t pid,
+			       uint32_t data_size, uint8_t *data)
+{
+	struct qla4_work_evt *e;
+
+	e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_PING_STATUS);
+	if (!e)
+		return QLA_ERROR;
+
+	e->u.ping.status = status;
+	e->u.ping.pid = pid;
+	e->u.ping.data_size = data_size;
+	memcpy(e->u.ping.data, data, data_size);
+
+	qla4xxx_post_work(ha, e);
+
+	return QLA_SUCCESS;
+}
+
+void qla4xxx_do_work(struct scsi_qla_host *ha)
+{
+	struct qla4_work_evt *e, *tmp;
+	unsigned long flags;
+	LIST_HEAD(work);
+
+	spin_lock_irqsave(&ha->work_lock, flags);
+	list_splice_init(&ha->work_list, &work);
+	spin_unlock_irqrestore(&ha->work_lock, flags);
+
+	list_for_each_entry_safe(e, tmp, &work, list) {
+		list_del_init(&e->list);
+
+		switch (e->type) {
+		case QLA4_EVENT_AEN:
+			iscsi_post_host_event(ha->host_no,
+					      &qla4xxx_iscsi_transport,
+					      e->u.aen.code,
+					      e->u.aen.data_size,
+					      e->u.aen.data);
+			break;
+		case QLA4_EVENT_PING_STATUS:
+			iscsi_ping_comp_event(ha->host_no,
+					      &qla4xxx_iscsi_transport,
+					      e->u.ping.status,
+					      e->u.ping.pid,
+					      e->u.ping.data_size,
+					      e->u.ping.data);
+			break;
+		default:
+			ql4_printk(KERN_WARNING, ha, "event type: 0x%x not "
+				   "supported", e->type);
+		}
+		kfree(e);
+	}
+}
+
 /**
  * qla4xxx_do_dpc - dpc routine
  * @data: in our case pointer to adapter structure
@@ -2826,6 +3070,9 @@ static void qla4xxx_do_dpc(struct work_struct *work)
 		return;
 	}
 
+	/* post events to application */
+	qla4xxx_do_work(ha);
+
 	if (is_qla8022(ha)) {
 		if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
 			qla4_8xxx_idc_lock(ha);
@@ -3341,9 +3588,8 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])
 		/* Check Boot Mode */
 		val = rd_nvram_byte(ha, addr);
 		if (!(val & 0x07)) {
-			DEBUG2(ql4_printk(KERN_ERR, ha,
-					  "%s: Failed Boot options : 0x%x\n",
-					  __func__, val));
+			DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Adapter boot "
+					  "options : 0x%x\n", __func__, val));
 			ret = QLA_ERROR;
 			goto exit_boot_info;
 		}
@@ -3388,9 +3634,8 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])
 		}
 		/* Check Boot Mode */
 		if (!(buf[1] & 0x07)) {
-			DEBUG2(ql4_printk(KERN_INFO, ha,
-					  "Failed: Boot options : 0x%x\n",
-					  buf[1]));
+			DEBUG2(ql4_printk(KERN_INFO, ha, "Firmware boot options"
+					  " : 0x%x\n", buf[1]));
 			ret = QLA_ERROR;
 			goto exit_boot_info_free;
 		}
@@ -3411,12 +3656,11 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])
 			  " target ID %d\n", __func__, ddb_index[0],
 			  ddb_index[1]));
 
-	ha->pri_ddb_idx = ddb_index[0];
-	ha->sec_ddb_idx = ddb_index[1];
-
 exit_boot_info_free:
 	dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma);
 exit_boot_info:
+	ha->pri_ddb_idx = ddb_index[0];
+	ha->sec_ddb_idx = ddb_index[1];
 	return ret;
 }
 
@@ -3497,8 +3741,8 @@ static int qla4xxx_get_boot_target(struct scsi_qla_host *ha,
 
 	if (qla4xxx_bootdb_by_index(ha, fw_ddb_entry,
 				   fw_ddb_entry_dma, ddb_index)) {
-		DEBUG2(ql4_printk(KERN_ERR, ha,
-				  "%s: Flash DDB read Failed\n", __func__));
+		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: No Flash DDB found at "
+				  "index [%d]\n", __func__, ddb_index));
 		ret = QLA_ERROR;
 		goto exit_boot_target;
 	}
@@ -3576,8 +3820,8 @@ static int qla4xxx_get_boot_info(struct scsi_qla_host *ha)
 	ddb_index[1] = 0xffff;
 	ret = get_fw_boot_info(ha, ddb_index);
 	if (ret != QLA_SUCCESS) {
-		DEBUG2(ql4_printk(KERN_ERR, ha,
-				  "%s: Failed to set boot info.\n", __func__));
+		DEBUG2(ql4_printk(KERN_INFO, ha,
+				"%s: No boot target configured.\n", __func__));
 		return ret;
 	}
 
@@ -3590,8 +3834,8 @@ static int qla4xxx_get_boot_info(struct scsi_qla_host *ha)
 	rval = qla4xxx_get_boot_target(ha, &(ha->boot_tgt.boot_pri_sess),
 				      ddb_index[0]);
 	if (rval != QLA_SUCCESS) {
-		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Failed to get "
-				  "primary target\n", __func__));
+		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Primary boot target not "
+				  "configured\n", __func__));
 	} else
 		ret = QLA_SUCCESS;
 
@@ -3602,8 +3846,8 @@ sec_target:
 	rval = qla4xxx_get_boot_target(ha, &(ha->boot_tgt.boot_sec_sess),
 				      ddb_index[1]);
 	if (rval != QLA_SUCCESS) {
-		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Failed to get "
-				  "secondary target\n", __func__));
+		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Secondary boot target not"
+				  " configured\n", __func__));
 	} else
 		ret = QLA_SUCCESS;
 
@@ -4038,6 +4282,10 @@ static void qla4xxx_build_st_list(struct scsi_qla_host *ha,
 		if (ret == QLA_ERROR)
 			break;
 
+		/* Ignore DDB if invalid state (unassigned) */
+		if (state == DDB_DS_UNASSIGNED)
+			goto continue_next_st;
+
 		/* Check if ST, add to the list_st */
 		if (strlen((char *) fw_ddb_entry->iscsi_name) != 0)
 			goto continue_next_st;
@@ -4397,6 +4645,9 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
 
 	spin_lock_init(&ha->hardware_lock);
 
+	/* Initialize work list */
+	INIT_LIST_HEAD(&ha->work_list);
+
 	/* Allocate dma buffers */
 	if (qla4xxx_mem_alloc(ha)) {
 		ql4_printk(KERN_WARNING, ha,
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index 133989b..7f20b7f 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION	"5.02.00-k12"
+#define QLA4XXX_DRIVER_VERSION	"5.02.00-k14"
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2aeb2e9..07322ec 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -782,12 +782,6 @@ static void scsi_done(struct scsi_cmnd *cmd)
 	blk_complete_request(cmd->request);
 }
 
-/* Move this to a header if it becomes more generally useful */
-static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
-{
-	return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
-}
-
 /**
  * scsi_finish_command - cleanup and pass command back to upper layer
  * @cmd: the command
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 6888b2c..5918561 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -126,6 +126,7 @@ static const char * scsi_debug_version_date = "20100324";
 #define SCSI_DEBUG_OPT_TRANSPORT_ERR   16
 #define SCSI_DEBUG_OPT_DIF_ERR   32
 #define SCSI_DEBUG_OPT_DIX_ERR   64
+#define SCSI_DEBUG_OPT_MAC_TIMEOUT  128
 /* When "every_nth" > 0 then modulo "every_nth" commands:
  *   - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
  *   - a RECOVERED_ERROR is simulated on successful read and write
@@ -1778,7 +1779,7 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
 	scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) {
 		int len = min(psgl->length, resid);
 
-		paddr = kmap_atomic(sg_page(psgl), KM_IRQ0) + psgl->offset;
+		paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
 		memcpy(paddr, dif_storep + dif_offset(sector), len);
 
 		sector += len >> 3;
@@ -1788,7 +1789,7 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
 			sector = do_div(tmp_sec, sdebug_store_sectors);
 		}
 		resid -= len;
-		kunmap_atomic(paddr, KM_IRQ0);
+		kunmap_atomic(paddr);
 	}
 
 	dix_reads++;
@@ -1881,12 +1882,12 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 	BUG_ON(scsi_sg_count(SCpnt) == 0);
 	BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
 
-	paddr = kmap_atomic(sg_page(psgl), KM_IRQ1) + psgl->offset;
+	paddr = kmap_atomic(sg_page(psgl)) + psgl->offset;
 	ppage_offset = 0;
 
 	/* For each data page */
 	scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) {
-		daddr = kmap_atomic(sg_page(dsgl), KM_IRQ0) + dsgl->offset;
+		daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset;
 
 		/* For each sector-sized chunk in data page */
 		for (j = 0 ; j < dsgl->length ; j += scsi_debug_sector_size) {
@@ -1895,10 +1896,10 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 			 * protection page advance to the next one
 			 */
 			if (ppage_offset >= psgl->length) {
-				kunmap_atomic(paddr, KM_IRQ1);
+				kunmap_atomic(paddr);
 				psgl = sg_next(psgl);
 				BUG_ON(psgl == NULL);
-				paddr = kmap_atomic(sg_page(psgl), KM_IRQ1)
+				paddr = kmap_atomic(sg_page(psgl))
 					+ psgl->offset;
 				ppage_offset = 0;
 			}
@@ -1971,10 +1972,10 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 			ppage_offset += sizeof(struct sd_dif_tuple);
 		}
 
-		kunmap_atomic(daddr, KM_IRQ0);
+		kunmap_atomic(daddr);
 	}
 
-	kunmap_atomic(paddr, KM_IRQ1);
+	kunmap_atomic(paddr);
 
 	dix_writes++;
 
@@ -1982,8 +1983,8 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
 
 out:
 	dif_errors++;
-	kunmap_atomic(daddr, KM_IRQ0);
-	kunmap_atomic(paddr, KM_IRQ1);
+	kunmap_atomic(daddr);
+	kunmap_atomic(paddr);
 	return ret;
 }
 
@@ -2220,7 +2221,7 @@ static int resp_get_lba_status(struct scsi_cmnd * scmd,
 	mapped = map_state(lba, &num);
 
 	memset(arr, 0, SDEBUG_GET_LBA_STATUS_LEN);
-	put_unaligned_be32(16, &arr[0]);	/* Parameter Data Length */
+	put_unaligned_be32(20, &arr[0]);	/* Parameter Data Length */
 	put_unaligned_be64(lba, &arr[8]);	/* LBA */
 	put_unaligned_be32(num, &arr[16]);	/* Number of blocks */
 	arr[20] = !mapped;			/* mapped = 0, unmapped = 1 */
@@ -2303,7 +2304,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
 
 	offset = 0;
 	for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) {
-		kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
+		kaddr = (unsigned char *)kmap_atomic(sg_page(sg));
 		if (!kaddr)
 			goto out;
 
@@ -2311,7 +2312,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
 			*(kaddr + sg->offset + j) ^= *(buf + offset + j);
 
 		offset += sg->length;
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 	ret = 0;
 out:
@@ -3615,6 +3616,9 @@ int scsi_debug_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t done)
 			scsi_debug_every_nth = -1;
 		if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
 			return 0; /* ignore command causing timeout */
+		else if (SCSI_DEBUG_OPT_MAC_TIMEOUT & scsi_debug_opts &&
+			 scsi_medium_access_command(SCpnt))
+			return 0; /* time out reads and writes */
 		else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
 			inj_recovered = 1; /* to reads and writes below */
 		else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 5f84a14..2cfcbff 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -30,6 +30,7 @@
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_host.h>
@@ -141,11 +142,11 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)
 	else if (host->hostt->eh_timed_out)
 		rtn = host->hostt->eh_timed_out(scmd);
 
+	scmd->result |= DID_TIME_OUT << 16;
+
 	if (unlikely(rtn == BLK_EH_NOT_HANDLED &&
-		     !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
-		scmd->result |= DID_TIME_OUT << 16;
+		     !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)))
 		rtn = BLK_EH_HANDLED;
-	}
 
 	return rtn;
 }
@@ -366,6 +367,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
 			return TARGET_ERROR;
 
 	case ILLEGAL_REQUEST:
+		if (sshdr.asc == 0x20 || /* Invalid command operation code */
+		    sshdr.asc == 0x21 || /* Logical block address out of range */
+		    sshdr.asc == 0x24 || /* Invalid field in cdb */
+		    sshdr.asc == 0x26) { /* Parameter value invalid */
+			return TARGET_ERROR;
+		}
+		return SUCCESS;
+
 	default:
 		return SUCCESS;
 	}
@@ -770,6 +779,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
 			     int cmnd_size, int timeout, unsigned sense_bytes)
 {
 	struct scsi_device *sdev = scmd->device;
+	struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd);
 	struct Scsi_Host *shost = sdev->host;
 	DECLARE_COMPLETION_ONSTACK(done);
 	unsigned long timeleft;
@@ -824,6 +834,10 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
 	}
 
 	scsi_eh_restore_cmnd(scmd, &ses);
+
+	if (sdrv->eh_action)
+		rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn);
+
 	return rtn;
 }
 
@@ -1540,7 +1554,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 			 * Need to modify host byte to signal a
 			 * permanent target failure
 			 */
-			scmd->result |= (DID_TARGET_FAILURE << 16);
+			set_host_byte(scmd, DID_TARGET_FAILURE);
 			rtn = SUCCESS;
 		}
 		/* if rtn == FAILED, we have no sense information;
@@ -1560,7 +1574,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
 	case RESERVATION_CONFLICT:
 		sdev_printk(KERN_INFO, scmd->device,
 			    "reservation conflict\n");
-		scmd->result |= (DID_NEXUS_FAILURE << 16);
+		set_host_byte(scmd, DID_NEXUS_FAILURE);
 		return SUCCESS; /* causes immediate i/o error */
 	default:
 		return FAILED;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index b2c95db..694f2bf 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -68,6 +68,17 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
 
 struct kmem_cache *scsi_sdb_cache;
 
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+
+int scsi_register_acpi_bus_type(struct acpi_bus_type *bus)
+{
+        bus->bus = &scsi_bus_type;
+        return register_acpi_bus_type(bus);
+}
+EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type);
+#endif
+
 /*
  * When to reinvoke queueing after a resource shortage. It's 3 msecs to
  * not change behaviour from the previous unplug mechanism, experimentation
@@ -682,11 +693,11 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
 		error = -ENOLINK;
 		break;
 	case DID_TARGET_FAILURE:
-		cmd->result |= (DID_OK << 16);
+		set_host_byte(cmd, DID_OK);
 		error = -EREMOTEIO;
 		break;
 	case DID_NEXUS_FAILURE:
-		cmd->result |= (DID_OK << 16);
+		set_host_byte(cmd, DID_OK);
 		error = -EBADE;
 		break;
 	default:
@@ -880,6 +891,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 				    cmd->cmnd[0] == WRITE_SAME)) {
 				description = "Discard failure";
 				action = ACTION_FAIL;
+				error = -EREMOTEIO;
 			} else
 				action = ACTION_FAIL;
 			break;
@@ -2567,7 +2579,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
 	if (*len > sg_len)
 		*len = sg_len;
 
-	return kmap_atomic(page, KM_BIO_SRC_IRQ);
+	return kmap_atomic(page);
 }
 EXPORT_SYMBOL(scsi_kmap_atomic_sg);
 
@@ -2577,6 +2589,6 @@ EXPORT_SYMBOL(scsi_kmap_atomic_sg);
  */
 void scsi_kunmap_atomic_sg(void *virt)
 {
-	kunmap_atomic(virt, KM_BIO_SRC_IRQ);
+	kunmap_atomic(virt);
 }
 EXPORT_SYMBOL(scsi_kunmap_atomic_sg);
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index bf8bf79..c467064 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -7,6 +7,7 @@
 
 #include <linux/pm_runtime.h>
 #include <linux/export.h>
+#include <linux/async.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -92,6 +93,19 @@ static int scsi_bus_resume_common(struct device *dev)
 	return err;
 }
 
+static int scsi_bus_prepare(struct device *dev)
+{
+	if (scsi_is_sdev_device(dev)) {
+		/* sd probing uses async_schedule.  Wait until it finishes. */
+		async_synchronize_full();
+
+	} else if (scsi_is_host_device(dev)) {
+		/* Wait until async scanning is finished */
+		scsi_complete_async_scans();
+	}
+	return 0;
+}
+
 static int scsi_bus_suspend(struct device *dev)
 {
 	return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
@@ -110,6 +124,7 @@ static int scsi_bus_poweroff(struct device *dev)
 #else /* CONFIG_PM_SLEEP */
 
 #define scsi_bus_resume_common		NULL
+#define scsi_bus_prepare		NULL
 #define scsi_bus_suspend		NULL
 #define scsi_bus_freeze			NULL
 #define scsi_bus_poweroff		NULL
@@ -218,6 +233,7 @@ void scsi_autopm_put_host(struct Scsi_Host *shost)
 #endif /* CONFIG_PM_RUNTIME */
 
 const struct dev_pm_ops scsi_bus_pm_ops = {
+	.prepare =		scsi_bus_prepare,
 	.suspend =		scsi_bus_suspend,
 	.resume =		scsi_bus_resume_common,
 	.freeze =		scsi_bus_freeze,
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 68eadd1..be4fa6d 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -109,6 +109,7 @@ extern void scsi_exit_procfs(void);
 #endif /* CONFIG_PROC_FS */
 
 /* scsi_scan.c */
+extern int scsi_complete_async_scans(void);
 extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
 				   unsigned int, unsigned int, int);
 extern void scsi_forget_host(struct Scsi_Host *);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 89da43f..01b0374 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1295,6 +1295,7 @@ EXPORT_SYMBOL(int_to_scsilun);
  *   LUNs even if it's older than SCSI-3.
  *   If BLIST_NOREPORTLUN is set, return 1 always.
  *   If BLIST_NOLUN is set, return 0 always.
+ *   If starget->no_report_luns is set, return 1 always.
  *
  * Return:
  *     0: scan completed (or no memory, so further scanning is futile)
@@ -1321,6 +1322,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
 	 * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set.
 	 * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does
 	 * support more than 8 LUNs.
+	 * Don't attempt if the target doesn't support REPORT LUNS.
 	 */
 	if (bflags & BLIST_NOREPORTLUN)
 		return 1;
@@ -1332,6 +1334,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
 		return 1;
 	if (bflags & BLIST_NOLUN)
 		return 0;
+	if (starget->no_report_luns)
+		return 1;
 
 	if (!(sdev = scsi_device_lookup_by_target(starget, 0))) {
 		sdev = scsi_alloc_sdev(starget, 0, NULL);
@@ -1815,6 +1819,7 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
 	}
 	spin_unlock(&async_scan_lock);
 
+	scsi_autopm_put_host(shost);
 	scsi_host_put(shost);
 	kfree(data);
 }
@@ -1841,7 +1846,6 @@ static int do_scan_async(void *_data)
 
 	do_scsi_scan_host(shost);
 	scsi_finish_async_scan(data);
-	scsi_autopm_put_host(shost);
 	return 0;
 }
 
@@ -1869,7 +1873,7 @@ void scsi_scan_host(struct Scsi_Host *shost)
 	p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
 	if (IS_ERR(p))
 		do_scan_async(data);
-	/* scsi_autopm_put_host(shost) is called in do_scan_async() */
+	/* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
 }
 EXPORT_SYMBOL(scsi_scan_host);
 
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index f59d4a0..80fbe2a 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -313,7 +313,7 @@ static void fc_scsi_scan_rport(struct work_struct *work);
 #define FC_STARGET_NUM_ATTRS 	3
 #define FC_RPORT_NUM_ATTRS	10
 #define FC_VPORT_NUM_ATTRS	9
-#define FC_HOST_NUM_ATTRS	22
+#define FC_HOST_NUM_ATTRS	29
 
 struct fc_internal {
 	struct scsi_transport_template t;
@@ -399,6 +399,20 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
 	fc_host->max_npiv_vports = 0;
 	memset(fc_host->serial_number, 0,
 		sizeof(fc_host->serial_number));
+	memset(fc_host->manufacturer, 0,
+		sizeof(fc_host->manufacturer));
+	memset(fc_host->model, 0,
+		sizeof(fc_host->model));
+	memset(fc_host->model_description, 0,
+		sizeof(fc_host->model_description));
+	memset(fc_host->hardware_version, 0,
+		sizeof(fc_host->hardware_version));
+	memset(fc_host->driver_version, 0,
+		sizeof(fc_host->driver_version));
+	memset(fc_host->firmware_version, 0,
+		sizeof(fc_host->firmware_version));
+	memset(fc_host->optionrom_version, 0,
+		sizeof(fc_host->optionrom_version));
 
 	fc_host->port_id = -1;
 	fc_host->port_type = FC_PORTTYPE_UNKNOWN;
@@ -1513,6 +1527,13 @@ fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
 fc_private_host_rd_attr(max_npiv_vports, "%u\n", 20);
 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
+fc_private_host_rd_attr(manufacturer, "%s\n", FC_SERIAL_NUMBER_SIZE + 1);
+fc_private_host_rd_attr(model, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1);
+fc_private_host_rd_attr(model_description, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1);
+fc_private_host_rd_attr(hardware_version, "%s\n", FC_VERSION_STRING_SIZE + 1);
+fc_private_host_rd_attr(driver_version, "%s\n", FC_VERSION_STRING_SIZE + 1);
+fc_private_host_rd_attr(firmware_version, "%s\n", FC_VERSION_STRING_SIZE + 1);
+fc_private_host_rd_attr(optionrom_version, "%s\n", FC_VERSION_STRING_SIZE + 1);
 
 
 /* Dynamic Host Attributes */
@@ -2208,6 +2229,13 @@ fc_attach_transport(struct fc_function_template *ft)
 		SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
 	}
 	SETUP_HOST_ATTRIBUTE_RD(serial_number);
+	SETUP_HOST_ATTRIBUTE_RD(manufacturer);
+	SETUP_HOST_ATTRIBUTE_RD(model);
+	SETUP_HOST_ATTRIBUTE_RD(model_description);
+	SETUP_HOST_ATTRIBUTE_RD(hardware_version);
+	SETUP_HOST_ATTRIBUTE_RD(driver_version);
+	SETUP_HOST_ATTRIBUTE_RD(firmware_version);
+	SETUP_HOST_ATTRIBUTE_RD(optionrom_version);
 
 	SETUP_HOST_ATTRIBUTE_RD(port_id);
 	SETUP_HOST_ATTRIBUTE_RD(port_type);
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index cfd4914..a20f181 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1476,6 +1476,66 @@ void iscsi_conn_login_event(struct iscsi_cls_conn *conn,
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_login_event);
 
+void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport,
+			   enum iscsi_host_event_code code, uint32_t data_size,
+			   uint8_t *data)
+{
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+	struct iscsi_uevent *ev;
+	int len = NLMSG_SPACE(sizeof(*ev) + data_size);
+
+	skb = alloc_skb(len, GFP_KERNEL);
+	if (!skb) {
+		printk(KERN_ERR "gracefully ignored host event (%d):%d OOM\n",
+		       host_no, code);
+		return;
+	}
+
+	nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
+	ev = NLMSG_DATA(nlh);
+	ev->transport_handle = iscsi_handle(transport);
+	ev->type = ISCSI_KEVENT_HOST_EVENT;
+	ev->r.host_event.host_no = host_no;
+	ev->r.host_event.code = code;
+	ev->r.host_event.data_size = data_size;
+
+	if (data_size)
+		memcpy((char *)ev + sizeof(*ev), data, data_size);
+
+	iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(iscsi_post_host_event);
+
+void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport,
+			   uint32_t status, uint32_t pid, uint32_t data_size,
+			   uint8_t *data)
+{
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+	struct iscsi_uevent *ev;
+	int len = NLMSG_SPACE(sizeof(*ev) + data_size);
+
+	skb = alloc_skb(len, GFP_KERNEL);
+	if (!skb) {
+		printk(KERN_ERR "gracefully ignored ping comp: OOM\n");
+		return;
+	}
+
+	nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0);
+	ev = NLMSG_DATA(nlh);
+	ev->transport_handle = iscsi_handle(transport);
+	ev->type = ISCSI_KEVENT_PING_COMP;
+	ev->r.ping_comp.host_no = host_no;
+	ev->r.ping_comp.status = status;
+	ev->r.ping_comp.pid = pid;
+	ev->r.ping_comp.data_size = data_size;
+	memcpy((char *)ev + sizeof(*ev), data, data_size);
+
+	iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(iscsi_ping_comp_event);
+
 static int
 iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi,
 		    void *payload, int size)
@@ -1915,6 +1975,33 @@ iscsi_set_iface_params(struct iscsi_transport *transport,
 }
 
 static int
+iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev)
+{
+	struct Scsi_Host *shost;
+	struct sockaddr *dst_addr;
+	int err;
+
+	if (!transport->send_ping)
+		return -ENOSYS;
+
+	shost = scsi_host_lookup(ev->u.iscsi_ping.host_no);
+	if (!shost) {
+		printk(KERN_ERR "iscsi_ping could not find host no %u\n",
+		       ev->u.iscsi_ping.host_no);
+		return -ENODEV;
+	}
+
+	dst_addr = (struct sockaddr *)((char *)ev + sizeof(*ev));
+	err = transport->send_ping(shost, ev->u.iscsi_ping.iface_num,
+				   ev->u.iscsi_ping.iface_type,
+				   ev->u.iscsi_ping.payload_size,
+				   ev->u.iscsi_ping.pid,
+				   dst_addr);
+	scsi_host_put(shost);
+	return err;
+}
+
+static int
 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 {
 	int err = 0;
@@ -1941,7 +2028,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 	switch (nlh->nlmsg_type) {
 	case ISCSI_UEVENT_CREATE_SESSION:
 		err = iscsi_if_create_session(priv, ep, ev,
-					      NETLINK_CREDS(skb)->pid,
+					      NETLINK_CB(skb).pid,
 					      ev->u.c_session.initial_cmdsn,
 					      ev->u.c_session.cmds_max,
 					      ev->u.c_session.queue_depth);
@@ -1954,7 +2041,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 		}
 
 		err = iscsi_if_create_session(priv, ep, ev,
-					NETLINK_CREDS(skb)->pid,
+					NETLINK_CB(skb).pid,
 					ev->u.c_bound_session.initial_cmdsn,
 					ev->u.c_bound_session.cmds_max,
 					ev->u.c_bound_session.queue_depth);
@@ -2059,6 +2146,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
 		err = iscsi_set_iface_params(transport, ev,
 					     nlmsg_attrlen(nlh, sizeof(*ev)));
 		break;
+	case ISCSI_UEVENT_PING:
+		err = iscsi_send_ping(transport, ev);
+		break;
 	default:
 		err = -ENOSYS;
 		break;
@@ -2110,7 +2200,7 @@ iscsi_if_rx(struct sk_buff *skb)
 				break;
 			err = iscsi_if_send_reply(group, nlh->nlmsg_seq,
 				nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
-		} while (err < 0 && err != -ECONNREFUSED);
+		} while (err < 0 && err != -ECONNREFUSED && err != -ESRCH);
 		skb_pull(skb, rlen);
 	}
 	mutex_unlock(&rx_queue_mutex);
@@ -2476,12 +2566,16 @@ iscsi_host_attr(netdev, ISCSI_HOST_PARAM_NETDEV_NAME);
 iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS);
 iscsi_host_attr(ipaddress, ISCSI_HOST_PARAM_IPADDRESS);
 iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME);
+iscsi_host_attr(port_state, ISCSI_HOST_PARAM_PORT_STATE);
+iscsi_host_attr(port_speed, ISCSI_HOST_PARAM_PORT_SPEED);
 
 static struct attribute *iscsi_host_attrs[] = {
 	&dev_attr_host_netdev.attr,
 	&dev_attr_host_hwaddress.attr,
 	&dev_attr_host_ipaddress.attr,
 	&dev_attr_host_initiatorname.attr,
+	&dev_attr_host_port_state.attr,
+	&dev_attr_host_port_speed.attr,
 	NULL,
 };
 
@@ -2501,6 +2595,10 @@ static umode_t iscsi_host_attr_is_visible(struct kobject *kobj,
 		param = ISCSI_HOST_PARAM_IPADDRESS;
 	else if (attr == &dev_attr_host_initiatorname.attr)
 		param = ISCSI_HOST_PARAM_INITIATOR_NAME;
+	else if (attr == &dev_attr_host_port_state.attr)
+		param = ISCSI_HOST_PARAM_PORT_STATE;
+	else if (attr == &dev_attr_host_port_speed.attr)
+		param = ISCSI_HOST_PARAM_PORT_SPEED;
 	else {
 		WARN_ONCE(1, "Invalid host attr");
 		return 0;
@@ -2514,6 +2612,61 @@ static struct attribute_group iscsi_host_group = {
 	.is_visible = iscsi_host_attr_is_visible,
 };
 
+/* convert iscsi_port_speed values to ascii string name */
+static const struct {
+	enum iscsi_port_speed	value;
+	char			*name;
+} iscsi_port_speed_names[] = {
+	{ISCSI_PORT_SPEED_UNKNOWN,	"Unknown" },
+	{ISCSI_PORT_SPEED_10MBPS,	"10 Mbps" },
+	{ISCSI_PORT_SPEED_100MBPS,	"100 Mbps" },
+	{ISCSI_PORT_SPEED_1GBPS,	"1 Gbps" },
+	{ISCSI_PORT_SPEED_10GBPS,	"10 Gbps" },
+};
+
+char *iscsi_get_port_speed_name(struct Scsi_Host *shost)
+{
+	int i;
+	char *speed = "Unknown!";
+	struct iscsi_cls_host *ihost = shost->shost_data;
+	uint32_t port_speed = ihost->port_speed;
+
+	for (i = 0; i < ARRAY_SIZE(iscsi_port_speed_names); i++) {
+		if (iscsi_port_speed_names[i].value & port_speed) {
+			speed = iscsi_port_speed_names[i].name;
+			break;
+		}
+	}
+	return speed;
+}
+EXPORT_SYMBOL_GPL(iscsi_get_port_speed_name);
+
+/* convert iscsi_port_state values to ascii string name */
+static const struct {
+	enum iscsi_port_state	value;
+	char			*name;
+} iscsi_port_state_names[] = {
+	{ISCSI_PORT_STATE_DOWN,		"LINK DOWN" },
+	{ISCSI_PORT_STATE_UP,		"LINK UP" },
+};
+
+char *iscsi_get_port_state_name(struct Scsi_Host *shost)
+{
+	int i;
+	char *state = "Unknown!";
+	struct iscsi_cls_host *ihost = shost->shost_data;
+	uint32_t port_state = ihost->port_state;
+
+	for (i = 0; i < ARRAY_SIZE(iscsi_port_state_names); i++) {
+		if (iscsi_port_state_names[i].value & port_state) {
+			state = iscsi_port_state_names[i].name;
+			break;
+		}
+	}
+	return state;
+}
+EXPORT_SYMBOL_GPL(iscsi_get_port_state_name);
+
 static int iscsi_session_match(struct attribute_container *cont,
 			   struct device *dev)
 {
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 9d9330a..f7565fc 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -615,6 +615,7 @@ do_sas_phy_reset(struct device *dev, size_t count, int hard_reset)
 	error = i->f->phy_reset(phy, hard_reset);
 	if (error)
 		return error;
+	phy->enabled = 1;
 	return count;
 };
 
@@ -652,9 +653,21 @@ sas_phy_linkerror_attr(running_disparity_error_count);
 sas_phy_linkerror_attr(loss_of_dword_sync_count);
 sas_phy_linkerror_attr(phy_reset_problem_count);
 
+static int sas_phy_setup(struct transport_container *tc, struct device *dev,
+			 struct device *cdev)
+{
+	struct sas_phy *phy = dev_to_phy(dev);
+	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+	struct sas_internal *i = to_sas_internal(shost->transportt);
+
+	if (i->f->phy_setup)
+		i->f->phy_setup(phy);
+
+	return 0;
+}
 
 static DECLARE_TRANSPORT_CLASS(sas_phy_class,
-		"sas_phy", NULL, NULL, NULL);
+		"sas_phy", sas_phy_setup, NULL, NULL);
 
 static int sas_phy_match(struct attribute_container *cont, struct device *dev)
 {
@@ -678,7 +691,11 @@ static int sas_phy_match(struct attribute_container *cont, struct device *dev)
 static void sas_phy_release(struct device *dev)
 {
 	struct sas_phy *phy = dev_to_phy(dev);
+	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+	struct sas_internal *i = to_sas_internal(shost->transportt);
 
+	if (i->f->phy_release)
+		i->f->phy_release(phy);
 	put_device(dev->parent);
 	kfree(phy);
 }
@@ -1044,6 +1061,29 @@ int scsi_is_sas_port(const struct device *dev)
 EXPORT_SYMBOL(scsi_is_sas_port);
 
 /**
+ * sas_port_get_phy - try to take a reference on a port member
+ * @port: port to check
+ */
+struct sas_phy *sas_port_get_phy(struct sas_port *port)
+{
+	struct sas_phy *phy;
+
+	mutex_lock(&port->phy_list_mutex);
+	if (list_empty(&port->phy_list))
+		phy = NULL;
+	else {
+		struct list_head *ent = port->phy_list.next;
+
+		phy = list_entry(ent, typeof(*phy), port_siblings);
+		get_device(&phy->dev);
+	}
+	mutex_unlock(&port->phy_list_mutex);
+
+	return phy;
+}
+EXPORT_SYMBOL(sas_port_get_phy);
+
+/**
  * sas_port_add_phy - add another phy to a port to form a wide port
  * @port:	port to add the phy to
  * @phy:	phy to add
@@ -1603,6 +1643,20 @@ sas_rphy_delete(struct sas_rphy *rphy)
 EXPORT_SYMBOL(sas_rphy_delete);
 
 /**
+ * sas_rphy_unlink  -  unlink SAS remote PHY
+ * @rphy:	SAS remote phy to unlink from its parent port
+ *
+ * Removes port reference to an rphy
+ */
+void sas_rphy_unlink(struct sas_rphy *rphy)
+{
+	struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
+
+	parent->rphy = NULL;
+}
+EXPORT_SYMBOL(sas_rphy_unlink);
+
+/**
  * sas_rphy_remove  -  remove SAS remote PHY
  * @rphy:	SAS remote phy to remove
  *
@@ -1612,7 +1666,6 @@ void
 sas_rphy_remove(struct sas_rphy *rphy)
 {
 	struct device *dev = &rphy->dev;
-	struct sas_port *parent = dev_to_sas_port(dev->parent);
 
 	switch (rphy->identify.device_type) {
 	case SAS_END_DEVICE:
@@ -1626,10 +1679,9 @@ sas_rphy_remove(struct sas_rphy *rphy)
 		break;
 	}
 
+	sas_rphy_unlink(rphy);
 	transport_remove_device(dev);
 	device_del(dev);
-
-	parent->rphy = NULL;
 }
 EXPORT_SYMBOL(sas_rphy_remove);
 
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index c691fb5..09e3df4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -107,6 +107,7 @@ static int sd_suspend(struct device *, pm_message_t state);
 static int sd_resume(struct device *);
 static void sd_rescan(struct device *);
 static int sd_done(struct scsi_cmnd *);
+static int sd_eh_action(struct scsi_cmnd *, unsigned char *, int, int);
 static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
 static void scsi_disk_release(struct device *cdev);
 static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
@@ -346,6 +347,31 @@ sd_store_provisioning_mode(struct device *dev, struct device_attribute *attr,
 	return count;
 }
 
+static ssize_t
+sd_show_max_medium_access_timeouts(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct scsi_disk *sdkp = to_scsi_disk(dev);
+
+	return snprintf(buf, 20, "%u\n", sdkp->max_medium_access_timeouts);
+}
+
+static ssize_t
+sd_store_max_medium_access_timeouts(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct scsi_disk *sdkp = to_scsi_disk(dev);
+	int err;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	err = kstrtouint(buf, 10, &sdkp->max_medium_access_timeouts);
+
+	return err ? err : count;
+}
+
 static struct device_attribute sd_disk_attrs[] = {
 	__ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
 	       sd_store_cache_type),
@@ -360,6 +386,9 @@ static struct device_attribute sd_disk_attrs[] = {
 	__ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL),
 	__ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode,
 	       sd_store_provisioning_mode),
+	__ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR,
+	       sd_show_max_medium_access_timeouts,
+	       sd_store_max_medium_access_timeouts),
 	__ATTR_NULL,
 };
 
@@ -382,6 +411,7 @@ static struct scsi_driver sd_template = {
 	},
 	.rescan			= sd_rescan,
 	.done			= sd_done,
+	.eh_action		= sd_eh_action,
 };
 
 /*
@@ -497,6 +527,8 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 		max(sdkp->physical_block_size,
 		    sdkp->unmap_granularity * logical_block_size);
 
+	sdkp->provisioning_mode = mode;
+
 	switch (mode) {
 
 	case SD_LBP_DISABLE:
@@ -524,8 +556,6 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 
 	q->limits.max_discard_sectors = max_blocks * (logical_block_size >> 9);
 	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
-
-	sdkp->provisioning_mode = mode;
 }
 
 /**
@@ -1313,6 +1343,55 @@ static const struct block_device_operations sd_fops = {
 	.unlock_native_capacity	= sd_unlock_native_capacity,
 };
 
+/**
+ *	sd_eh_action - error handling callback
+ *	@scmd:		sd-issued command that has failed
+ *	@eh_cmnd:	The command that was sent during error handling
+ *	@eh_cmnd_len:	Length of eh_cmnd in bytes
+ *	@eh_disp:	The recovery disposition suggested by the midlayer
+ *
+ *	This function is called by the SCSI midlayer upon completion of
+ *	an error handling command (TEST UNIT READY, START STOP UNIT,
+ *	etc.) The command sent to the device by the error handler is
+ *	stored in eh_cmnd. The result of sending the eh command is
+ *	passed in eh_disp.
+ **/
+static int sd_eh_action(struct scsi_cmnd *scmd, unsigned char *eh_cmnd,
+			int eh_cmnd_len, int eh_disp)
+{
+	struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk);
+
+	if (!scsi_device_online(scmd->device) ||
+	    !scsi_medium_access_command(scmd))
+		return eh_disp;
+
+	/*
+	 * The device has timed out executing a medium access command.
+	 * However, the TEST UNIT READY command sent during error
+	 * handling completed successfully. Either the device is in the
+	 * process of recovering or has it suffered an internal failure
+	 * that prevents access to the storage medium.
+	 */
+	if (host_byte(scmd->result) == DID_TIME_OUT && eh_disp == SUCCESS &&
+	    eh_cmnd_len && eh_cmnd[0] == TEST_UNIT_READY)
+		sdkp->medium_access_timed_out++;
+
+	/*
+	 * If the device keeps failing read/write commands but TEST UNIT
+	 * READY always completes successfully we assume that medium
+	 * access is no longer possible and take the device offline.
+	 */
+	if (sdkp->medium_access_timed_out >= sdkp->max_medium_access_timeouts) {
+		scmd_printk(KERN_ERR, scmd,
+			    "Medium access timeout failure. Offlining disk!\n");
+		scsi_device_set_state(scmd->device, SDEV_OFFLINE);
+
+		return FAILED;
+	}
+
+	return eh_disp;
+}
+
 static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
 {
 	u64 start_lba = blk_rq_pos(scmd->request);
@@ -1402,6 +1481,8 @@ static int sd_done(struct scsi_cmnd *SCpnt)
 	    (!sense_valid || sense_deferred))
 		goto out;
 
+	sdkp->medium_access_timed_out = 0;
+
 	switch (sshdr.sense_key) {
 	case HARDWARE_ERROR:
 	case MEDIUM_ERROR:
@@ -2349,7 +2430,7 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp)
 	 * some USB ones crash on receiving them, and the pages
 	 * we currently ask for are for SPC-3 and beyond
 	 */
-	if (sdp->scsi_level > SCSI_SPC_2)
+	if (sdp->scsi_level > SCSI_SPC_2 && !sdp->skip_vpd_pages)
 		return 1;
 	return 0;
 }
@@ -2523,6 +2604,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
 	sdkp->RCD = 0;
 	sdkp->ATO = 0;
 	sdkp->first_scan = 1;
+	sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS;
 
 	sd_revalidate_disk(gd);
 
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 4163f29..f703f48 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -20,6 +20,7 @@
  */
 #define SD_MAX_RETRIES		5
 #define SD_PASSTHROUGH_RETRIES	1
+#define SD_MAX_MEDIUM_TIMEOUTS	2
 
 /*
  * Size of the initial data buffer for mode and read capacity data
@@ -59,6 +60,8 @@ struct scsi_disk {
 	u32		unmap_alignment;
 	u32		index;
 	unsigned int	physical_block_size;
+	unsigned int	max_medium_access_timeouts;
+	unsigned int	medium_access_timed_out;
 	u8		media_present;
 	u8		write_prot;
 	u8		protection_type;/* Data Integrity Field */
@@ -88,6 +91,38 @@ static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
 		    (sdsk)->disk->disk_name, ##a) :			\
 	sdev_printk(prefix, (sdsk)->device, fmt, ##a)
 
+static inline int scsi_medium_access_command(struct scsi_cmnd *scmd)
+{
+	switch (scmd->cmnd[0]) {
+	case READ_6:
+	case READ_10:
+	case READ_12:
+	case READ_16:
+	case SYNCHRONIZE_CACHE:
+	case VERIFY:
+	case VERIFY_12:
+	case VERIFY_16:
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_12:
+	case WRITE_16:
+	case WRITE_SAME:
+	case WRITE_SAME_16:
+	case UNMAP:
+		return 1;
+	case VARIABLE_LENGTH_CMD:
+		switch (scmd->cmnd[9]) {
+		case READ_32:
+		case VERIFY_32:
+		case WRITE_32:
+		case WRITE_SAME_32:
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 /*
  * A DIF-capable target device can be formatted with different
  * protection schemes.  Currently 0 through 3 are defined:
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 0cb39ff..e981d97 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -392,7 +392,7 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
 		virt = bio->bi_integrity->bip_sector & 0xffffffff;
 
 		bip_for_each_vec(iv, bio->bi_integrity, i) {
-			sdt = kmap_atomic(iv->bv_page, KM_USER0)
+			sdt = kmap_atomic(iv->bv_page)
 				+ iv->bv_offset;
 
 			for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) {
@@ -405,7 +405,7 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
 				phys++;
 			}
 
-			kunmap_atomic(sdt, KM_USER0);
+			kunmap_atomic(sdt);
 		}
 
 		bio->bi_flags |= BIO_MAPPED_INTEGRITY;
@@ -414,7 +414,7 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s
 	return 0;
 
 error:
-	kunmap_atomic(sdt, KM_USER0);
+	kunmap_atomic(sdt);
 	sd_printk(KERN_ERR, sdkp, "%s: virt %u, phys %u, ref %u, app %4x\n",
 		  __func__, virt, phys, be32_to_cpu(sdt->ref_tag),
 		  be16_to_cpu(sdt->app_tag));
@@ -453,13 +453,13 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
 		virt = bio->bi_integrity->bip_sector & 0xffffffff;
 
 		bip_for_each_vec(iv, bio->bi_integrity, i) {
-			sdt = kmap_atomic(iv->bv_page, KM_USER0)
+			sdt = kmap_atomic(iv->bv_page)
 				+ iv->bv_offset;
 
 			for (j = 0 ; j < iv->bv_len ; j += tuple_sz, sdt++) {
 
 				if (sectors == 0) {
-					kunmap_atomic(sdt, KM_USER0);
+					kunmap_atomic(sdt);
 					return;
 				}
 
@@ -474,7 +474,7 @@ void sd_dif_complete(struct scsi_cmnd *scmd, unsigned int good_bytes)
 				sectors--;
 			}
 
-			kunmap_atomic(sdt, KM_USER0);
+			kunmap_atomic(sdt);
 		}
 	}
 }
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9b28f39..9262cdf 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -1177,6 +1177,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp)
 static int st_open(struct inode *inode, struct file *filp)
 {
 	int i, retval = (-EIO);
+	int resumed = 0;
 	struct scsi_tape *STp;
 	struct st_partstat *STps;
 	int dev = TAPE_NR(inode);
@@ -1211,6 +1212,11 @@ static int st_open(struct inode *inode, struct file *filp)
 	write_unlock(&st_dev_arr_lock);
 	STp->rew_at_close = STp->autorew_dev = (iminor(inode) & 0x80) == 0;
 
+	if (scsi_autopm_get_device(STp->device) < 0) {
+		retval = -EIO;
+		goto err_out;
+	}
+	resumed = 1;
 	if (!scsi_block_when_processing_errors(STp->device)) {
 		retval = (-ENXIO);
 		goto err_out;
@@ -1258,6 +1264,8 @@ static int st_open(struct inode *inode, struct file *filp)
 	normalize_buffer(STp->buffer);
 	STp->in_use = 0;
 	scsi_tape_put(STp);
+	if (resumed)
+		scsi_autopm_put_device(STp->device);
 	mutex_unlock(&st_mutex);
 	return retval;
 
@@ -1391,6 +1399,7 @@ static int st_release(struct inode *inode, struct file *filp)
 	write_lock(&st_dev_arr_lock);
 	STp->in_use = 0;
 	write_unlock(&st_dev_arr_lock);
+	scsi_autopm_put_device(STp->device);
 	scsi_tape_put(STp);
 
 	return result;
@@ -4154,6 +4163,7 @@ static int st_probe(struct device *dev)
 		if (error)
 			goto out_free_tape;
 	}
+	scsi_autopm_put_device(SDp);
 
 	sdev_printk(KERN_NOTICE, SDp,
 		    "Attached scsi tape %s\n", tape_name(tpnt));
@@ -4201,6 +4211,7 @@ static int st_remove(struct device *dev)
 	struct scsi_tape *tpnt;
 	int i, j, mode;
 
+	scsi_autopm_get_device(SDp);
 	write_lock(&st_dev_arr_lock);
 	for (i = 0; i < st_dev_max; i++) {
 		tpnt = scsi_tapes[i];
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
new file mode 100644
index 0000000..44c7a48
--- /dev/null
+++ b/drivers/scsi/storvsc_drv.c
@@ -0,0 +1,1544 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/hyperv.h>
+#include <linux/mempool.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_devinfo.h>
+#include <scsi/scsi_dbg.h>
+
+/*
+ * All wire protocol details (storage protocol between the guest and the host)
+ * are consolidated here.
+ *
+ * Begin protocol definitions.
+ */
+
+/*
+ * Version history:
+ * V1 Beta: 0.1
+ * V1 RC < 2008/1/31: 1.0
+ * V1 RC > 2008/1/31:  2.0
+ * Win7: 4.2
+ */
+
+#define VMSTOR_CURRENT_MAJOR  4
+#define VMSTOR_CURRENT_MINOR  2
+
+
+/*  Packet structure describing virtual storage requests. */
+enum vstor_packet_operation {
+	VSTOR_OPERATION_COMPLETE_IO		= 1,
+	VSTOR_OPERATION_REMOVE_DEVICE		= 2,
+	VSTOR_OPERATION_EXECUTE_SRB		= 3,
+	VSTOR_OPERATION_RESET_LUN		= 4,
+	VSTOR_OPERATION_RESET_ADAPTER		= 5,
+	VSTOR_OPERATION_RESET_BUS		= 6,
+	VSTOR_OPERATION_BEGIN_INITIALIZATION	= 7,
+	VSTOR_OPERATION_END_INITIALIZATION	= 8,
+	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
+	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
+	VSTOR_OPERATION_ENUMERATE_BUS		= 11,
+	VSTOR_OPERATION_MAXIMUM			= 11
+};
+
+/*
+ * Platform neutral description of a scsi request -
+ * this remains the same across the write regardless of 32/64 bit
+ * note: it's patterned off the SCSI_PASS_THROUGH structure
+ */
+#define STORVSC_MAX_CMD_LEN			0x10
+#define STORVSC_SENSE_BUFFER_SIZE		0x12
+#define STORVSC_MAX_BUF_LEN_WITH_PADDING	0x14
+
+struct vmscsi_request {
+	u16 length;
+	u8 srb_status;
+	u8 scsi_status;
+
+	u8  port_number;
+	u8  path_id;
+	u8  target_id;
+	u8  lun;
+
+	u8  cdb_length;
+	u8  sense_info_length;
+	u8  data_in;
+	u8  reserved;
+
+	u32 data_transfer_length;
+
+	union {
+		u8 cdb[STORVSC_MAX_CMD_LEN];
+		u8 sense_data[STORVSC_SENSE_BUFFER_SIZE];
+		u8 reserved_array[STORVSC_MAX_BUF_LEN_WITH_PADDING];
+	};
+} __attribute((packed));
+
+
+/*
+ * This structure is sent during the intialization phase to get the different
+ * properties of the channel.
+ */
+struct vmstorage_channel_properties {
+	u16 protocol_version;
+	u8  path_id;
+	u8 target_id;
+
+	/* Note: port number is only really known on the client side */
+	u32  port_number;
+	u32  flags;
+	u32   max_transfer_bytes;
+
+	/*
+	 * This id is unique for each channel and will correspond with
+	 * vendor specific data in the inquiry data.
+	 */
+
+	u64  unique_id;
+} __packed;
+
+/*  This structure is sent during the storage protocol negotiations. */
+struct vmstorage_protocol_version {
+	/* Major (MSW) and minor (LSW) version numbers. */
+	u16 major_minor;
+
+	/*
+	 * Revision number is auto-incremented whenever this file is changed
+	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
+	 * definitely indicate incompatibility--but it does indicate mismatched
+	 * builds.
+	 * This is only used on the windows side. Just set it to 0.
+	 */
+	u16 revision;
+} __packed;
+
+/* Channel Property Flags */
+#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
+#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
+
+struct vstor_packet {
+	/* Requested operation type */
+	enum vstor_packet_operation operation;
+
+	/*  Flags - see below for values */
+	u32 flags;
+
+	/* Status of the request returned from the server side. */
+	u32 status;
+
+	/* Data payload area */
+	union {
+		/*
+		 * Structure used to forward SCSI commands from the
+		 * client to the server.
+		 */
+		struct vmscsi_request vm_srb;
+
+		/* Structure used to query channel properties. */
+		struct vmstorage_channel_properties storage_channel_properties;
+
+		/* Used during version negotiations. */
+		struct vmstorage_protocol_version version;
+	};
+} __packed;
+
+/*
+ * Packet Flags:
+ *
+ * This flag indicates that the server should send back a completion for this
+ * packet.
+ */
+
+#define REQUEST_COMPLETION_FLAG	0x1
+
+/* Matches Windows-end */
+enum storvsc_request_type {
+	WRITE_TYPE = 0,
+	READ_TYPE,
+	UNKNOWN_TYPE,
+};
+
+/*
+ * SRB status codes and masks; a subset of the codes used here.
+ */
+
+#define SRB_STATUS_AUTOSENSE_VALID	0x80
+#define SRB_STATUS_INVALID_LUN	0x20
+#define SRB_STATUS_SUCCESS	0x01
+#define SRB_STATUS_ERROR	0x04
+
+/*
+ * This is the end of Protocol specific defines.
+ */
+
+
+/*
+ * We setup a mempool to allocate request structures for this driver
+ * on a per-lun basis. The following define specifies the number of
+ * elements in the pool.
+ */
+
+#define STORVSC_MIN_BUF_NR				64
+static int storvsc_ringbuffer_size = (20 * PAGE_SIZE);
+
+module_param(storvsc_ringbuffer_size, int, S_IRUGO);
+MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
+
+#define STORVSC_MAX_IO_REQUESTS				128
+
+/*
+ * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
+ * reality, the path/target is not used (ie always set to 0) so our
+ * scsi host adapter essentially has 1 bus with 1 target that contains
+ * up to 256 luns.
+ */
+#define STORVSC_MAX_LUNS_PER_TARGET			64
+#define STORVSC_MAX_TARGETS				1
+#define STORVSC_MAX_CHANNELS				1
+
+
+
+struct storvsc_cmd_request {
+	struct list_head entry;
+	struct scsi_cmnd *cmd;
+
+	unsigned int bounce_sgl_count;
+	struct scatterlist *bounce_sgl;
+
+	struct hv_device *device;
+
+	/* Synchronize the request/response if needed */
+	struct completion wait_event;
+
+	unsigned char *sense_buffer;
+	struct hv_multipage_buffer data_buffer;
+	struct vstor_packet vstor_packet;
+};
+
+
+/* A storvsc device is a device object that contains a vmbus channel */
+struct storvsc_device {
+	struct hv_device *device;
+
+	bool	 destroy;
+	bool	 drain_notify;
+	atomic_t num_outstanding_req;
+	struct Scsi_Host *host;
+
+	wait_queue_head_t waiting_to_drain;
+
+	/*
+	 * Each unique Port/Path/Target represents 1 channel ie scsi
+	 * controller. In reality, the pathid, targetid is always 0
+	 * and the port is set by us
+	 */
+	unsigned int port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+
+	/* Used for vsc/vsp channel reset process */
+	struct storvsc_cmd_request init_request;
+	struct storvsc_cmd_request reset_request;
+};
+
+struct stor_mem_pools {
+	struct kmem_cache *request_pool;
+	mempool_t *request_mempool;
+};
+
+struct hv_host_device {
+	struct hv_device *dev;
+	unsigned int port;
+	unsigned char path;
+	unsigned char target;
+};
+
+struct storvsc_scan_work {
+	struct work_struct work;
+	struct Scsi_Host *host;
+	uint lun;
+};
+
+static void storvsc_bus_scan(struct work_struct *work)
+{
+	struct storvsc_scan_work *wrk;
+	int id, order_id;
+
+	wrk = container_of(work, struct storvsc_scan_work, work);
+	for (id = 0; id < wrk->host->max_id; ++id) {
+		if (wrk->host->reverse_ordering)
+			order_id = wrk->host->max_id - id - 1;
+		else
+			order_id = id;
+
+		scsi_scan_target(&wrk->host->shost_gendev, 0,
+				order_id, SCAN_WILD_CARD, 1);
+	}
+	kfree(wrk);
+}
+
+static void storvsc_remove_lun(struct work_struct *work)
+{
+	struct storvsc_scan_work *wrk;
+	struct scsi_device *sdev;
+
+	wrk = container_of(work, struct storvsc_scan_work, work);
+	if (!scsi_host_get(wrk->host))
+		goto done;
+
+	sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun);
+
+	if (sdev) {
+		scsi_remove_device(sdev);
+		scsi_device_put(sdev);
+	}
+	scsi_host_put(wrk->host);
+
+done:
+	kfree(wrk);
+}
+
+/*
+ * Major/minor macros.  Minor version is in LSB, meaning that earlier flat
+ * version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1).
+ */
+
+static inline u16 storvsc_get_version(u8 major, u8 minor)
+{
+	u16 version;
+
+	version = ((major << 8) | minor);
+	return version;
+}
+
+/*
+ * We can get incoming messages from the host that are not in response to
+ * messages that we have sent out. An example of this would be messages
+ * received by the guest to notify dynamic addition/removal of LUNs. To
+ * deal with potential race conditions where the driver may be in the
+ * midst of being unloaded when we might receive an unsolicited message
+ * from the host, we have implemented a mechanism to gurantee sequential
+ * consistency:
+ *
+ * 1) Once the device is marked as being destroyed, we will fail all
+ *    outgoing messages.
+ * 2) We permit incoming messages when the device is being destroyed,
+ *    only to properly account for messages already sent out.
+ */
+
+static inline struct storvsc_device *get_out_stor_device(
+					struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+
+	stor_device = hv_get_drvdata(device);
+
+	if (stor_device && stor_device->destroy)
+		stor_device = NULL;
+
+	return stor_device;
+}
+
+
+static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
+{
+	dev->drain_notify = true;
+	wait_event(dev->waiting_to_drain,
+		   atomic_read(&dev->num_outstanding_req) == 0);
+	dev->drain_notify = false;
+}
+
+static inline struct storvsc_device *get_in_stor_device(
+					struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+
+	stor_device = hv_get_drvdata(device);
+
+	if (!stor_device)
+		goto get_in_err;
+
+	/*
+	 * If the device is being destroyed; allow incoming
+	 * traffic only to cleanup outstanding requests.
+	 */
+
+	if (stor_device->destroy  &&
+		(atomic_read(&stor_device->num_outstanding_req) == 0))
+		stor_device = NULL;
+
+get_in_err:
+	return stor_device;
+
+}
+
+static void destroy_bounce_buffer(struct scatterlist *sgl,
+				  unsigned int sg_count)
+{
+	int i;
+	struct page *page_buf;
+
+	for (i = 0; i < sg_count; i++) {
+		page_buf = sg_page((&sgl[i]));
+		if (page_buf != NULL)
+			__free_page(page_buf);
+	}
+
+	kfree(sgl);
+}
+
+static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
+{
+	int i;
+
+	/* No need to check */
+	if (sg_count < 2)
+		return -1;
+
+	/* We have at least 2 sg entries */
+	for (i = 0; i < sg_count; i++) {
+		if (i == 0) {
+			/* make sure 1st one does not have hole */
+			if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
+				return i;
+		} else if (i == sg_count - 1) {
+			/* make sure last one does not have hole */
+			if (sgl[i].offset != 0)
+				return i;
+		} else {
+			/* make sure no hole in the middle */
+			if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
+				return i;
+		}
+	}
+	return -1;
+}
+
+static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
+						unsigned int sg_count,
+						unsigned int len,
+						int write)
+{
+	int i;
+	int num_pages;
+	struct scatterlist *bounce_sgl;
+	struct page *page_buf;
+	unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
+
+	num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
+
+	bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
+	if (!bounce_sgl)
+		return NULL;
+
+	for (i = 0; i < num_pages; i++) {
+		page_buf = alloc_page(GFP_ATOMIC);
+		if (!page_buf)
+			goto cleanup;
+		sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0);
+	}
+
+	return bounce_sgl;
+
+cleanup:
+	destroy_bounce_buffer(bounce_sgl, num_pages);
+	return NULL;
+}
+
+/* Assume the original sgl has enough room */
+static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
+					    struct scatterlist *bounce_sgl,
+					    unsigned int orig_sgl_count,
+					    unsigned int bounce_sgl_count)
+{
+	int i;
+	int j = 0;
+	unsigned long src, dest;
+	unsigned int srclen, destlen, copylen;
+	unsigned int total_copied = 0;
+	unsigned long bounce_addr = 0;
+	unsigned long dest_addr = 0;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	for (i = 0; i < orig_sgl_count; i++) {
+		dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])))
+					+ orig_sgl[i].offset;
+		dest = dest_addr;
+		destlen = orig_sgl[i].length;
+
+		if (bounce_addr == 0)
+			bounce_addr =
+			(unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])));
+
+		while (destlen) {
+			src = bounce_addr + bounce_sgl[j].offset;
+			srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+
+			copylen = min(srclen, destlen);
+			memcpy((void *)dest, (void *)src, copylen);
+
+			total_copied += copylen;
+			bounce_sgl[j].offset += copylen;
+			destlen -= copylen;
+			dest += copylen;
+
+			if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+				/* full */
+				kunmap_atomic((void *)bounce_addr);
+				j++;
+
+				/*
+				 * It is possible that the number of elements
+				 * in the bounce buffer may not be equal to
+				 * the number of elements in the original
+				 * scatter list. Handle this correctly.
+				 */
+
+				if (j == bounce_sgl_count) {
+					/*
+					 * We are done; cleanup and return.
+					 */
+					kunmap_atomic((void *)(dest_addr -
+							orig_sgl[i].offset));
+					local_irq_restore(flags);
+					return total_copied;
+				}
+
+				/* if we need to use another bounce buffer */
+				if (destlen || i != orig_sgl_count - 1)
+					bounce_addr =
+					(unsigned long)kmap_atomic(
+					sg_page((&bounce_sgl[j])));
+			} else if (destlen == 0 && i == orig_sgl_count - 1) {
+				/* unmap the last bounce that is < PAGE_SIZE */
+				kunmap_atomic((void *)bounce_addr);
+			}
+		}
+
+		kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset));
+	}
+
+	local_irq_restore(flags);
+
+	return total_copied;
+}
+
+/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
+static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
+					  struct scatterlist *bounce_sgl,
+					  unsigned int orig_sgl_count)
+{
+	int i;
+	int j = 0;
+	unsigned long src, dest;
+	unsigned int srclen, destlen, copylen;
+	unsigned int total_copied = 0;
+	unsigned long bounce_addr = 0;
+	unsigned long src_addr = 0;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	for (i = 0; i < orig_sgl_count; i++) {
+		src_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])))
+				+ orig_sgl[i].offset;
+		src = src_addr;
+		srclen = orig_sgl[i].length;
+
+		if (bounce_addr == 0)
+			bounce_addr =
+			(unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])));
+
+		while (srclen) {
+			/* assume bounce offset always == 0 */
+			dest = bounce_addr + bounce_sgl[j].length;
+			destlen = PAGE_SIZE - bounce_sgl[j].length;
+
+			copylen = min(srclen, destlen);
+			memcpy((void *)dest, (void *)src, copylen);
+
+			total_copied += copylen;
+			bounce_sgl[j].length += copylen;
+			srclen -= copylen;
+			src += copylen;
+
+			if (bounce_sgl[j].length == PAGE_SIZE) {
+				/* full..move to next entry */
+				kunmap_atomic((void *)bounce_addr);
+				j++;
+
+				/* if we need to use another bounce buffer */
+				if (srclen || i != orig_sgl_count - 1)
+					bounce_addr =
+					(unsigned long)kmap_atomic(
+					sg_page((&bounce_sgl[j])));
+
+			} else if (srclen == 0 && i == orig_sgl_count - 1) {
+				/* unmap the last bounce that is < PAGE_SIZE */
+				kunmap_atomic((void *)bounce_addr);
+			}
+		}
+
+		kunmap_atomic((void *)(src_addr - orig_sgl[i].offset));
+	}
+
+	local_irq_restore(flags);
+
+	return total_copied;
+}
+
+static int storvsc_channel_init(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+	struct storvsc_cmd_request *request;
+	struct vstor_packet *vstor_packet;
+	int ret, t;
+
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return -ENODEV;
+
+	request = &stor_device->init_request;
+	vstor_packet = &request->vstor_packet;
+
+	/*
+	 * Now, initiate the vsc/vsp initialization protocol on the open
+	 * channel
+	 */
+	memset(request, 0, sizeof(struct storvsc_cmd_request));
+	init_completion(&request->wait_event);
+	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+
+	/* reuse the packet for version range supported */
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+	vstor_packet->version.major_minor =
+		storvsc_get_version(VMSTOR_CURRENT_MAJOR, VMSTOR_CURRENT_MINOR);
+
+	/*
+	 * The revision number is only used in Windows; set it to 0.
+	 */
+	vstor_packet->version.revision = 0;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+	vstor_packet->storage_channel_properties.port_number =
+					stor_device->port_number;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+	stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
+	stor_device->target_id
+		= vstor_packet->storage_channel_properties.target_id;
+
+	memset(vstor_packet, 0, sizeof(struct vstor_packet));
+	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
+	}
+
+	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
+	    vstor_packet->status != 0)
+		goto cleanup;
+
+
+cleanup:
+	return ret;
+}
+
+
+static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
+{
+	struct scsi_cmnd *scmnd = cmd_request->cmd;
+	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
+	void (*scsi_done_fn)(struct scsi_cmnd *);
+	struct scsi_sense_hdr sense_hdr;
+	struct vmscsi_request *vm_srb;
+	struct storvsc_scan_work *wrk;
+	struct stor_mem_pools *memp = scmnd->device->hostdata;
+
+	vm_srb = &cmd_request->vstor_packet.vm_srb;
+	if (cmd_request->bounce_sgl_count) {
+		if (vm_srb->data_in == READ_TYPE)
+			copy_from_bounce_buffer(scsi_sglist(scmnd),
+					cmd_request->bounce_sgl,
+					scsi_sg_count(scmnd),
+					cmd_request->bounce_sgl_count);
+		destroy_bounce_buffer(cmd_request->bounce_sgl,
+					cmd_request->bounce_sgl_count);
+	}
+
+	/*
+	 * If there is an error; offline the device since all
+	 * error recovery strategies would have already been
+	 * deployed on the host side.
+	 */
+	if (vm_srb->srb_status == SRB_STATUS_ERROR)
+		scmnd->result = DID_TARGET_FAILURE << 16;
+	else
+		scmnd->result = vm_srb->scsi_status;
+
+	/*
+	 * If the LUN is invalid; remove the device.
+	 */
+	if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) {
+		struct storvsc_device *stor_dev;
+		struct hv_device *dev = host_dev->dev;
+		struct Scsi_Host *host;
+
+		stor_dev = get_in_stor_device(dev);
+		host = stor_dev->host;
+
+		wrk = kmalloc(sizeof(struct storvsc_scan_work),
+				GFP_ATOMIC);
+		if (!wrk) {
+			scmnd->result = DID_TARGET_FAILURE << 16;
+		} else {
+			wrk->host = host;
+			wrk->lun = vm_srb->lun;
+			INIT_WORK(&wrk->work, storvsc_remove_lun);
+			schedule_work(&wrk->work);
+		}
+	}
+
+	if (scmnd->result) {
+		if (scsi_normalize_sense(scmnd->sense_buffer,
+				SCSI_SENSE_BUFFERSIZE, &sense_hdr))
+			scsi_print_sense_hdr("storvsc", &sense_hdr);
+	}
+
+	scsi_set_resid(scmnd,
+		cmd_request->data_buffer.len -
+		vm_srb->data_transfer_length);
+
+	scsi_done_fn = scmnd->scsi_done;
+
+	scmnd->host_scribble = NULL;
+	scmnd->scsi_done = NULL;
+
+	scsi_done_fn(scmnd);
+
+	mempool_free(cmd_request, memp->request_mempool);
+}
+
+static void storvsc_on_io_completion(struct hv_device *device,
+				  struct vstor_packet *vstor_packet,
+				  struct storvsc_cmd_request *request)
+{
+	struct storvsc_device *stor_device;
+	struct vstor_packet *stor_pkt;
+
+	stor_device = hv_get_drvdata(device);
+	stor_pkt = &request->vstor_packet;
+
+	/*
+	 * The current SCSI handling on the host side does
+	 * not correctly handle:
+	 * INQUIRY command with page code parameter set to 0x80
+	 * MODE_SENSE command with cmd[2] == 0x1c
+	 *
+	 * Setup srb and scsi status so this won't be fatal.
+	 * We do this so we can distinguish truly fatal failues
+	 * (srb status == 0x4) and off-line the device in that case.
+	 */
+
+	if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
+	   (stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) {
+		vstor_packet->vm_srb.scsi_status = 0;
+		vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS;
+	}
+
+
+	/* Copy over the status...etc */
+	stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
+	stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status;
+	stor_pkt->vm_srb.sense_info_length =
+	vstor_packet->vm_srb.sense_info_length;
+
+	if (vstor_packet->vm_srb.scsi_status != 0 ||
+		vstor_packet->vm_srb.srb_status != SRB_STATUS_SUCCESS){
+		dev_warn(&device->device,
+			 "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
+			 stor_pkt->vm_srb.cdb[0],
+			 vstor_packet->vm_srb.scsi_status,
+			 vstor_packet->vm_srb.srb_status);
+	}
+
+	if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
+		/* CHECK_CONDITION */
+		if (vstor_packet->vm_srb.srb_status &
+			SRB_STATUS_AUTOSENSE_VALID) {
+			/* autosense data available */
+			dev_warn(&device->device,
+				 "stor pkt %p autosense data valid - len %d\n",
+				 request,
+				 vstor_packet->vm_srb.sense_info_length);
+
+			memcpy(request->sense_buffer,
+			       vstor_packet->vm_srb.sense_data,
+			       vstor_packet->vm_srb.sense_info_length);
+
+		}
+	}
+
+	stor_pkt->vm_srb.data_transfer_length =
+	vstor_packet->vm_srb.data_transfer_length;
+
+	storvsc_command_completion(request);
+
+	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
+		stor_device->drain_notify)
+		wake_up(&stor_device->waiting_to_drain);
+
+
+}
+
+static void storvsc_on_receive(struct hv_device *device,
+			     struct vstor_packet *vstor_packet,
+			     struct storvsc_cmd_request *request)
+{
+	struct storvsc_scan_work *work;
+	struct storvsc_device *stor_device;
+
+	switch (vstor_packet->operation) {
+	case VSTOR_OPERATION_COMPLETE_IO:
+		storvsc_on_io_completion(device, vstor_packet, request);
+		break;
+
+	case VSTOR_OPERATION_REMOVE_DEVICE:
+	case VSTOR_OPERATION_ENUMERATE_BUS:
+		stor_device = get_in_stor_device(device);
+		work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
+		if (!work)
+			return;
+
+		INIT_WORK(&work->work, storvsc_bus_scan);
+		work->host = stor_device->host;
+		schedule_work(&work->work);
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void storvsc_on_channel_callback(void *context)
+{
+	struct hv_device *device = (struct hv_device *)context;
+	struct storvsc_device *stor_device;
+	u32 bytes_recvd;
+	u64 request_id;
+	unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)];
+	struct storvsc_cmd_request *request;
+	int ret;
+
+
+	stor_device = get_in_stor_device(device);
+	if (!stor_device)
+		return;
+
+	do {
+		ret = vmbus_recvpacket(device->channel, packet,
+				       ALIGN(sizeof(struct vstor_packet), 8),
+				       &bytes_recvd, &request_id);
+		if (ret == 0 && bytes_recvd > 0) {
+
+			request = (struct storvsc_cmd_request *)
+					(unsigned long)request_id;
+
+			if ((request == &stor_device->init_request) ||
+			    (request == &stor_device->reset_request)) {
+
+				memcpy(&request->vstor_packet, packet,
+				       sizeof(struct vstor_packet));
+				complete(&request->wait_event);
+			} else {
+				storvsc_on_receive(device,
+						(struct vstor_packet *)packet,
+						request);
+			}
+		} else {
+			break;
+		}
+	} while (1);
+
+	return;
+}
+
+static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
+{
+	struct vmstorage_channel_properties props;
+	int ret;
+
+	memset(&props, 0, sizeof(struct vmstorage_channel_properties));
+
+	ret = vmbus_open(device->channel,
+			 ring_size,
+			 ring_size,
+			 (void *)&props,
+			 sizeof(struct vmstorage_channel_properties),
+			 storvsc_on_channel_callback, device);
+
+	if (ret != 0)
+		return ret;
+
+	ret = storvsc_channel_init(device);
+
+	return ret;
+}
+
+static int storvsc_dev_remove(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+	unsigned long flags;
+
+	stor_device = hv_get_drvdata(device);
+
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
+	stor_device->destroy = true;
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+
+	/*
+	 * At this point, all outbound traffic should be disable. We
+	 * only allow inbound traffic (responses) to proceed so that
+	 * outstanding requests can be completed.
+	 */
+
+	storvsc_wait_to_drain(stor_device);
+
+	/*
+	 * Since we have already drained, we don't need to busy wait
+	 * as was done in final_release_stor_device()
+	 * Note that we cannot set the ext pointer to NULL until
+	 * we have drained - to drain the outgoing packets, we need to
+	 * allow incoming packets.
+	 */
+	spin_lock_irqsave(&device->channel->inbound_lock, flags);
+	hv_set_drvdata(device, NULL);
+	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
+
+	/* Close the channel */
+	vmbus_close(device->channel);
+
+	kfree(stor_device);
+	return 0;
+}
+
+static int storvsc_do_io(struct hv_device *device,
+			      struct storvsc_cmd_request *request)
+{
+	struct storvsc_device *stor_device;
+	struct vstor_packet *vstor_packet;
+	int ret = 0;
+
+	vstor_packet = &request->vstor_packet;
+	stor_device = get_out_stor_device(device);
+
+	if (!stor_device)
+		return -ENODEV;
+
+
+	request->device  = device;
+
+
+	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
+
+	vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
+
+
+	vstor_packet->vm_srb.sense_info_length = STORVSC_SENSE_BUFFER_SIZE;
+
+
+	vstor_packet->vm_srb.data_transfer_length =
+	request->data_buffer.len;
+
+	vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
+
+	if (request->data_buffer.len) {
+		ret = vmbus_sendpacket_multipagebuffer(device->channel,
+				&request->data_buffer,
+				vstor_packet,
+				sizeof(struct vstor_packet),
+				(unsigned long)request);
+	} else {
+		ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	}
+
+	if (ret != 0)
+		return ret;
+
+	atomic_inc(&stor_device->num_outstanding_req);
+
+	return ret;
+}
+
+static int storvsc_device_alloc(struct scsi_device *sdevice)
+{
+	struct stor_mem_pools *memp;
+	int number = STORVSC_MIN_BUF_NR;
+
+	memp = kzalloc(sizeof(struct stor_mem_pools), GFP_KERNEL);
+	if (!memp)
+		return -ENOMEM;
+
+	memp->request_pool =
+		kmem_cache_create(dev_name(&sdevice->sdev_dev),
+				sizeof(struct storvsc_cmd_request), 0,
+				SLAB_HWCACHE_ALIGN, NULL);
+
+	if (!memp->request_pool)
+		goto err0;
+
+	memp->request_mempool = mempool_create(number, mempool_alloc_slab,
+						mempool_free_slab,
+						memp->request_pool);
+
+	if (!memp->request_mempool)
+		goto err1;
+
+	sdevice->hostdata = memp;
+
+	return 0;
+
+err1:
+	kmem_cache_destroy(memp->request_pool);
+
+err0:
+	kfree(memp);
+	return -ENOMEM;
+}
+
+static void storvsc_device_destroy(struct scsi_device *sdevice)
+{
+	struct stor_mem_pools *memp = sdevice->hostdata;
+
+	mempool_destroy(memp->request_mempool);
+	kmem_cache_destroy(memp->request_pool);
+	kfree(memp);
+	sdevice->hostdata = NULL;
+}
+
+static int storvsc_device_configure(struct scsi_device *sdevice)
+{
+	scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
+				STORVSC_MAX_IO_REQUESTS);
+
+	blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
+
+	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
+
+	return 0;
+}
+
+static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
+			   sector_t capacity, int *info)
+{
+	sector_t nsect = capacity;
+	sector_t cylinders = nsect;
+	int heads, sectors_pt;
+
+	/*
+	 * We are making up these values; let us keep it simple.
+	 */
+	heads = 0xff;
+	sectors_pt = 0x3f;      /* Sectors per track */
+	sector_div(cylinders, heads * sectors_pt);
+	if ((sector_t)(cylinders + 1) * heads * sectors_pt < nsect)
+		cylinders = 0xffff;
+
+	info[0] = heads;
+	info[1] = sectors_pt;
+	info[2] = (int)cylinders;
+
+	return 0;
+}
+
+static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
+{
+	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
+	struct hv_device *device = host_dev->dev;
+
+	struct storvsc_device *stor_device;
+	struct storvsc_cmd_request *request;
+	struct vstor_packet *vstor_packet;
+	int ret, t;
+
+
+	stor_device = get_out_stor_device(device);
+	if (!stor_device)
+		return FAILED;
+
+	request = &stor_device->reset_request;
+	vstor_packet = &request->vstor_packet;
+
+	init_completion(&request->wait_event);
+
+	vstor_packet->operation = VSTOR_OPERATION_RESET_BUS;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+	vstor_packet->vm_srb.path_id = stor_device->path_id;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)&stor_device->reset_request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0)
+		return FAILED;
+
+	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+	if (t == 0)
+		return TIMEOUT_ERROR;
+
+
+	/*
+	 * At this point, all outstanding requests in the adapter
+	 * should have been flushed out and return to us
+	 */
+
+	return SUCCESS;
+}
+
+static bool storvsc_scsi_cmd_ok(struct scsi_cmnd *scmnd)
+{
+	bool allowed = true;
+	u8 scsi_op = scmnd->cmnd[0];
+
+	switch (scsi_op) {
+	/*
+	 * smartd sends this command and the host does not handle
+	 * this. So, don't send it.
+	 */
+	case SET_WINDOW:
+		scmnd->result = ILLEGAL_REQUEST << 16;
+		allowed = false;
+		break;
+	default:
+		break;
+	}
+	return allowed;
+}
+
+static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
+{
+	int ret;
+	struct hv_host_device *host_dev = shost_priv(host);
+	struct hv_device *dev = host_dev->dev;
+	struct storvsc_cmd_request *cmd_request;
+	unsigned int request_size = 0;
+	int i;
+	struct scatterlist *sgl;
+	unsigned int sg_count = 0;
+	struct vmscsi_request *vm_srb;
+	struct stor_mem_pools *memp = scmnd->device->hostdata;
+
+	if (!storvsc_scsi_cmd_ok(scmnd)) {
+		scmnd->scsi_done(scmnd);
+		return 0;
+	}
+
+	request_size = sizeof(struct storvsc_cmd_request);
+
+	cmd_request = mempool_alloc(memp->request_mempool,
+				       GFP_ATOMIC);
+
+	/*
+	 * We might be invoked in an interrupt context; hence
+	 * mempool_alloc() can fail.
+	 */
+	if (!cmd_request)
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+
+	memset(cmd_request, 0, sizeof(struct storvsc_cmd_request));
+
+	/* Setup the cmd request */
+	cmd_request->cmd = scmnd;
+
+	scmnd->host_scribble = (unsigned char *)cmd_request;
+
+	vm_srb = &cmd_request->vstor_packet.vm_srb;
+
+
+	/* Build the SRB */
+	switch (scmnd->sc_data_direction) {
+	case DMA_TO_DEVICE:
+		vm_srb->data_in = WRITE_TYPE;
+		break;
+	case DMA_FROM_DEVICE:
+		vm_srb->data_in = READ_TYPE;
+		break;
+	default:
+		vm_srb->data_in = UNKNOWN_TYPE;
+		break;
+	}
+
+
+	vm_srb->port_number = host_dev->port;
+	vm_srb->path_id = scmnd->device->channel;
+	vm_srb->target_id = scmnd->device->id;
+	vm_srb->lun = scmnd->device->lun;
+
+	vm_srb->cdb_length = scmnd->cmd_len;
+
+	memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
+
+	cmd_request->sense_buffer = scmnd->sense_buffer;
+
+
+	cmd_request->data_buffer.len = scsi_bufflen(scmnd);
+	if (scsi_sg_count(scmnd)) {
+		sgl = (struct scatterlist *)scsi_sglist(scmnd);
+		sg_count = scsi_sg_count(scmnd);
+
+		/* check if we need to bounce the sgl */
+		if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
+			cmd_request->bounce_sgl =
+				create_bounce_buffer(sgl, scsi_sg_count(scmnd),
+						     scsi_bufflen(scmnd),
+						     vm_srb->data_in);
+			if (!cmd_request->bounce_sgl) {
+				ret = SCSI_MLQUEUE_HOST_BUSY;
+				goto queue_error;
+			}
+
+			cmd_request->bounce_sgl_count =
+				ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
+					PAGE_SHIFT;
+
+			if (vm_srb->data_in == WRITE_TYPE)
+				copy_to_bounce_buffer(sgl,
+					cmd_request->bounce_sgl,
+					scsi_sg_count(scmnd));
+
+			sgl = cmd_request->bounce_sgl;
+			sg_count = cmd_request->bounce_sgl_count;
+		}
+
+		cmd_request->data_buffer.offset = sgl[0].offset;
+
+		for (i = 0; i < sg_count; i++)
+			cmd_request->data_buffer.pfn_array[i] =
+				page_to_pfn(sg_page((&sgl[i])));
+
+	} else if (scsi_sglist(scmnd)) {
+		cmd_request->data_buffer.offset =
+			virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
+		cmd_request->data_buffer.pfn_array[0] =
+			virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
+	}
+
+	/* Invokes the vsc to start an IO */
+	ret = storvsc_do_io(dev, cmd_request);
+
+	if (ret == -EAGAIN) {
+		/* no more space */
+
+		if (cmd_request->bounce_sgl_count) {
+			destroy_bounce_buffer(cmd_request->bounce_sgl,
+					cmd_request->bounce_sgl_count);
+
+			ret = SCSI_MLQUEUE_DEVICE_BUSY;
+			goto queue_error;
+		}
+	}
+
+	return 0;
+
+queue_error:
+	mempool_free(cmd_request, memp->request_mempool);
+	scmnd->host_scribble = NULL;
+	return ret;
+}
+
+static struct scsi_host_template scsi_driver = {
+	.module	=		THIS_MODULE,
+	.name =			"storvsc_host_t",
+	.bios_param =		storvsc_get_chs,
+	.queuecommand =		storvsc_queuecommand,
+	.eh_host_reset_handler =	storvsc_host_reset_handler,
+	.slave_alloc =		storvsc_device_alloc,
+	.slave_destroy =	storvsc_device_destroy,
+	.slave_configure =	storvsc_device_configure,
+	.cmd_per_lun =		1,
+	/* 64 max_queue * 1 target */
+	.can_queue =		STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
+	.this_id =		-1,
+	/* no use setting to 0 since ll_blk_rw reset it to 1 */
+	/* currently 32 */
+	.sg_tablesize =		MAX_MULTIPAGE_BUFFER_COUNT,
+	.use_clustering =	DISABLE_CLUSTERING,
+	/* Make sure we dont get a sg segment crosses a page boundary */
+	.dma_boundary =		PAGE_SIZE-1,
+};
+
+enum {
+	SCSI_GUID,
+	IDE_GUID,
+};
+
+static const struct hv_vmbus_device_id id_table[] = {
+	/* SCSI guid */
+	{ VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
+		       0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
+	  .driver_data = SCSI_GUID },
+	/* IDE guid */
+	{ VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
+	  .driver_data = IDE_GUID },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(vmbus, id_table);
+
+static int storvsc_probe(struct hv_device *device,
+			const struct hv_vmbus_device_id *dev_id)
+{
+	int ret;
+	struct Scsi_Host *host;
+	struct hv_host_device *host_dev;
+	bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false);
+	int target = 0;
+	struct storvsc_device *stor_device;
+
+	host = scsi_host_alloc(&scsi_driver,
+			       sizeof(struct hv_host_device));
+	if (!host)
+		return -ENOMEM;
+
+	host_dev = shost_priv(host);
+	memset(host_dev, 0, sizeof(struct hv_host_device));
+
+	host_dev->port = host->host_no;
+	host_dev->dev = device;
+
+
+	stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
+	if (!stor_device) {
+		ret = -ENOMEM;
+		goto err_out0;
+	}
+
+	stor_device->destroy = false;
+	init_waitqueue_head(&stor_device->waiting_to_drain);
+	stor_device->device = device;
+	stor_device->host = host;
+	hv_set_drvdata(device, stor_device);
+
+	stor_device->port_number = host->host_no;
+	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
+	if (ret)
+		goto err_out1;
+
+	host_dev->path = stor_device->path_id;
+	host_dev->target = stor_device->target_id;
+
+	/* max # of devices per target */
+	host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
+	/* max # of targets per channel */
+	host->max_id = STORVSC_MAX_TARGETS;
+	/* max # of channels */
+	host->max_channel = STORVSC_MAX_CHANNELS - 1;
+	/* max cmd length */
+	host->max_cmd_len = STORVSC_MAX_CMD_LEN;
+
+	/* Register the HBA and start the scsi bus scan */
+	ret = scsi_add_host(host, &device->device);
+	if (ret != 0)
+		goto err_out2;
+
+	if (!dev_is_ide) {
+		scsi_scan_host(host);
+	} else {
+		target = (device->dev_instance.b[5] << 8 |
+			 device->dev_instance.b[4]);
+		ret = scsi_add_device(host, 0, target, 0);
+		if (ret) {
+			scsi_remove_host(host);
+			goto err_out2;
+		}
+	}
+	return 0;
+
+err_out2:
+	/*
+	 * Once we have connected with the host, we would need to
+	 * to invoke storvsc_dev_remove() to rollback this state and
+	 * this call also frees up the stor_device; hence the jump around
+	 * err_out1 label.
+	 */
+	storvsc_dev_remove(device);
+	goto err_out0;
+
+err_out1:
+	kfree(stor_device);
+
+err_out0:
+	scsi_host_put(host);
+	return ret;
+}
+
+static int storvsc_remove(struct hv_device *dev)
+{
+	struct storvsc_device *stor_device = hv_get_drvdata(dev);
+	struct Scsi_Host *host = stor_device->host;
+
+	scsi_remove_host(host);
+	storvsc_dev_remove(dev);
+	scsi_host_put(host);
+
+	return 0;
+}
+
+static struct hv_driver storvsc_drv = {
+	.name = KBUILD_MODNAME,
+	.id_table = id_table,
+	.probe = storvsc_probe,
+	.remove = storvsc_remove,
+};
+
+static int __init storvsc_drv_init(void)
+{
+	u32 max_outstanding_req_per_channel;
+
+	/*
+	 * Divide the ring buffer data size (which is 1 page less
+	 * than the ring buffer size since that page is reserved for
+	 * the ring buffer indices) by the max request size (which is
+	 * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
+	 */
+	max_outstanding_req_per_channel =
+		((storvsc_ringbuffer_size - PAGE_SIZE) /
+		ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
+		sizeof(struct vstor_packet) + sizeof(u64),
+		sizeof(u64)));
+
+	if (max_outstanding_req_per_channel <
+	    STORVSC_MAX_IO_REQUESTS)
+		return -EINVAL;
+
+	return vmbus_driver_register(&storvsc_drv);
+}
+
+static void __exit storvsc_drv_exit(void)
+{
+	vmbus_driver_unregister(&storvsc_drv);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION(HV_DRV_VERSION);
+MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver");
+module_init(storvsc_drv_init);
+module_exit(storvsc_drv_exit);
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
new file mode 100644
index 0000000..efccd72
--- /dev/null
+++ b/drivers/scsi/virtio_scsi.c
@@ -0,0 +1,594 @@
+/*
+ * Virtio SCSI HBA driver
+ *
+ * Copyright IBM Corp. 2010
+ * Copyright Red Hat, Inc. 2011
+ *
+ * Authors:
+ *  Stefan Hajnoczi   <stefanha@linux.vnet.ibm.com>
+ *  Paolo Bonzini   <pbonzini@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+
+#define VIRTIO_SCSI_MEMPOOL_SZ 64
+
+/* Command queue element */
+struct virtio_scsi_cmd {
+	struct scsi_cmnd *sc;
+	struct completion *comp;
+	union {
+		struct virtio_scsi_cmd_req       cmd;
+		struct virtio_scsi_ctrl_tmf_req  tmf;
+		struct virtio_scsi_ctrl_an_req   an;
+	} req;
+	union {
+		struct virtio_scsi_cmd_resp      cmd;
+		struct virtio_scsi_ctrl_tmf_resp tmf;
+		struct virtio_scsi_ctrl_an_resp  an;
+		struct virtio_scsi_event         evt;
+	} resp;
+} ____cacheline_aligned_in_smp;
+
+/* Driver instance state */
+struct virtio_scsi {
+	/* Protects ctrl_vq, req_vq and sg[] */
+	spinlock_t vq_lock;
+
+	struct virtio_device *vdev;
+	struct virtqueue *ctrl_vq;
+	struct virtqueue *event_vq;
+	struct virtqueue *req_vq;
+
+	/* For sglist construction when adding commands to the virtqueue.  */
+	struct scatterlist sg[];
+};
+
+static struct kmem_cache *virtscsi_cmd_cache;
+static mempool_t *virtscsi_cmd_pool;
+
+static inline struct Scsi_Host *virtio_scsi_host(struct virtio_device *vdev)
+{
+	return vdev->priv;
+}
+
+static void virtscsi_compute_resid(struct scsi_cmnd *sc, u32 resid)
+{
+	if (!resid)
+		return;
+
+	if (!scsi_bidi_cmnd(sc)) {
+		scsi_set_resid(sc, resid);
+		return;
+	}
+
+	scsi_in(sc)->resid = min(resid, scsi_in(sc)->length);
+	scsi_out(sc)->resid = resid - scsi_in(sc)->resid;
+}
+
+/**
+ * virtscsi_complete_cmd - finish a scsi_cmd and invoke scsi_done
+ *
+ * Called with vq_lock held.
+ */
+static void virtscsi_complete_cmd(void *buf)
+{
+	struct virtio_scsi_cmd *cmd = buf;
+	struct scsi_cmnd *sc = cmd->sc;
+	struct virtio_scsi_cmd_resp *resp = &cmd->resp.cmd;
+
+	dev_dbg(&sc->device->sdev_gendev,
+		"cmd %p response %u status %#02x sense_len %u\n",
+		sc, resp->response, resp->status, resp->sense_len);
+
+	sc->result = resp->status;
+	virtscsi_compute_resid(sc, resp->resid);
+	switch (resp->response) {
+	case VIRTIO_SCSI_S_OK:
+		set_host_byte(sc, DID_OK);
+		break;
+	case VIRTIO_SCSI_S_OVERRUN:
+		set_host_byte(sc, DID_ERROR);
+		break;
+	case VIRTIO_SCSI_S_ABORTED:
+		set_host_byte(sc, DID_ABORT);
+		break;
+	case VIRTIO_SCSI_S_BAD_TARGET:
+		set_host_byte(sc, DID_BAD_TARGET);
+		break;
+	case VIRTIO_SCSI_S_RESET:
+		set_host_byte(sc, DID_RESET);
+		break;
+	case VIRTIO_SCSI_S_BUSY:
+		set_host_byte(sc, DID_BUS_BUSY);
+		break;
+	case VIRTIO_SCSI_S_TRANSPORT_FAILURE:
+		set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
+		break;
+	case VIRTIO_SCSI_S_TARGET_FAILURE:
+		set_host_byte(sc, DID_TARGET_FAILURE);
+		break;
+	case VIRTIO_SCSI_S_NEXUS_FAILURE:
+		set_host_byte(sc, DID_NEXUS_FAILURE);
+		break;
+	default:
+		scmd_printk(KERN_WARNING, sc, "Unknown response %d",
+			    resp->response);
+		/* fall through */
+	case VIRTIO_SCSI_S_FAILURE:
+		set_host_byte(sc, DID_ERROR);
+		break;
+	}
+
+	WARN_ON(resp->sense_len > VIRTIO_SCSI_SENSE_SIZE);
+	if (sc->sense_buffer) {
+		memcpy(sc->sense_buffer, resp->sense,
+		       min_t(u32, resp->sense_len, VIRTIO_SCSI_SENSE_SIZE));
+		if (resp->sense_len)
+			set_driver_byte(sc, DRIVER_SENSE);
+	}
+
+	mempool_free(cmd, virtscsi_cmd_pool);
+	sc->scsi_done(sc);
+}
+
+static void virtscsi_vq_done(struct virtqueue *vq, void (*fn)(void *buf))
+{
+	struct Scsi_Host *sh = virtio_scsi_host(vq->vdev);
+	struct virtio_scsi *vscsi = shost_priv(sh);
+	void *buf;
+	unsigned long flags;
+	unsigned int len;
+
+	spin_lock_irqsave(&vscsi->vq_lock, flags);
+
+	do {
+		virtqueue_disable_cb(vq);
+		while ((buf = virtqueue_get_buf(vq, &len)) != NULL)
+			fn(buf);
+	} while (!virtqueue_enable_cb(vq));
+
+	spin_unlock_irqrestore(&vscsi->vq_lock, flags);
+}
+
+static void virtscsi_req_done(struct virtqueue *vq)
+{
+	virtscsi_vq_done(vq, virtscsi_complete_cmd);
+};
+
+static void virtscsi_complete_free(void *buf)
+{
+	struct virtio_scsi_cmd *cmd = buf;
+
+	if (cmd->comp)
+		complete_all(cmd->comp);
+	mempool_free(cmd, virtscsi_cmd_pool);
+}
+
+static void virtscsi_ctrl_done(struct virtqueue *vq)
+{
+	virtscsi_vq_done(vq, virtscsi_complete_free);
+};
+
+static void virtscsi_event_done(struct virtqueue *vq)
+{
+	virtscsi_vq_done(vq, virtscsi_complete_free);
+};
+
+static void virtscsi_map_sgl(struct scatterlist *sg, unsigned int *p_idx,
+			     struct scsi_data_buffer *sdb)
+{
+	struct sg_table *table = &sdb->table;
+	struct scatterlist *sg_elem;
+	unsigned int idx = *p_idx;
+	int i;
+
+	for_each_sg(table->sgl, sg_elem, table->nents, i)
+		sg_set_buf(&sg[idx++], sg_virt(sg_elem), sg_elem->length);
+
+	*p_idx = idx;
+}
+
+/**
+ * virtscsi_map_cmd - map a scsi_cmd to a virtqueue scatterlist
+ * @vscsi	: virtio_scsi state
+ * @cmd		: command structure
+ * @out_num	: number of read-only elements
+ * @in_num	: number of write-only elements
+ * @req_size	: size of the request buffer
+ * @resp_size	: size of the response buffer
+ *
+ * Called with vq_lock held.
+ */
+static void virtscsi_map_cmd(struct virtio_scsi *vscsi,
+			     struct virtio_scsi_cmd *cmd,
+			     unsigned *out_num, unsigned *in_num,
+			     size_t req_size, size_t resp_size)
+{
+	struct scsi_cmnd *sc = cmd->sc;
+	struct scatterlist *sg = vscsi->sg;
+	unsigned int idx = 0;
+
+	if (sc) {
+		struct Scsi_Host *shost = virtio_scsi_host(vscsi->vdev);
+		BUG_ON(scsi_sg_count(sc) > shost->sg_tablesize);
+
+		/* TODO: check feature bit and fail if unsupported?  */
+		BUG_ON(sc->sc_data_direction == DMA_BIDIRECTIONAL);
+	}
+
+	/* Request header.  */
+	sg_set_buf(&sg[idx++], &cmd->req, req_size);
+
+	/* Data-out buffer.  */
+	if (sc && sc->sc_data_direction != DMA_FROM_DEVICE)
+		virtscsi_map_sgl(sg, &idx, scsi_out(sc));
+
+	*out_num = idx;
+
+	/* Response header.  */
+	sg_set_buf(&sg[idx++], &cmd->resp, resp_size);
+
+	/* Data-in buffer */
+	if (sc && sc->sc_data_direction != DMA_TO_DEVICE)
+		virtscsi_map_sgl(sg, &idx, scsi_in(sc));
+
+	*in_num = idx - *out_num;
+}
+
+static int virtscsi_kick_cmd(struct virtio_scsi *vscsi, struct virtqueue *vq,
+			     struct virtio_scsi_cmd *cmd,
+			     size_t req_size, size_t resp_size, gfp_t gfp)
+{
+	unsigned int out_num, in_num;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&vscsi->vq_lock, flags);
+
+	virtscsi_map_cmd(vscsi, cmd, &out_num, &in_num, req_size, resp_size);
+
+	ret = virtqueue_add_buf(vq, vscsi->sg, out_num, in_num, cmd, gfp);
+	if (ret >= 0)
+		virtqueue_kick(vq);
+
+	spin_unlock_irqrestore(&vscsi->vq_lock, flags);
+	return ret;
+}
+
+static int virtscsi_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
+{
+	struct virtio_scsi *vscsi = shost_priv(sh);
+	struct virtio_scsi_cmd *cmd;
+	int ret;
+
+	dev_dbg(&sc->device->sdev_gendev,
+		"cmd %p CDB: %#02x\n", sc, sc->cmnd[0]);
+
+	ret = SCSI_MLQUEUE_HOST_BUSY;
+	cmd = mempool_alloc(virtscsi_cmd_pool, GFP_ATOMIC);
+	if (!cmd)
+		goto out;
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->sc = sc;
+	cmd->req.cmd = (struct virtio_scsi_cmd_req){
+		.lun[0] = 1,
+		.lun[1] = sc->device->id,
+		.lun[2] = (sc->device->lun >> 8) | 0x40,
+		.lun[3] = sc->device->lun & 0xff,
+		.tag = (unsigned long)sc,
+		.task_attr = VIRTIO_SCSI_S_SIMPLE,
+		.prio = 0,
+		.crn = 0,
+	};
+
+	BUG_ON(sc->cmd_len > VIRTIO_SCSI_CDB_SIZE);
+	memcpy(cmd->req.cmd.cdb, sc->cmnd, sc->cmd_len);
+
+	if (virtscsi_kick_cmd(vscsi, vscsi->req_vq, cmd,
+			      sizeof cmd->req.cmd, sizeof cmd->resp.cmd,
+			      GFP_ATOMIC) >= 0)
+		ret = 0;
+
+out:
+	return ret;
+}
+
+static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
+{
+	DECLARE_COMPLETION_ONSTACK(comp);
+	int ret;
+
+	cmd->comp = &comp;
+	ret = virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd,
+			       sizeof cmd->req.tmf, sizeof cmd->resp.tmf,
+			       GFP_NOIO);
+	if (ret < 0)
+		return FAILED;
+
+	wait_for_completion(&comp);
+	if (cmd->resp.tmf.response != VIRTIO_SCSI_S_OK &&
+	    cmd->resp.tmf.response != VIRTIO_SCSI_S_FUNCTION_SUCCEEDED)
+		return FAILED;
+
+	return SUCCESS;
+}
+
+static int virtscsi_device_reset(struct scsi_cmnd *sc)
+{
+	struct virtio_scsi *vscsi = shost_priv(sc->device->host);
+	struct virtio_scsi_cmd *cmd;
+
+	sdev_printk(KERN_INFO, sc->device, "device reset\n");
+	cmd = mempool_alloc(virtscsi_cmd_pool, GFP_NOIO);
+	if (!cmd)
+		return FAILED;
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->sc = sc;
+	cmd->req.tmf = (struct virtio_scsi_ctrl_tmf_req){
+		.type = VIRTIO_SCSI_T_TMF,
+		.subtype = VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET,
+		.lun[0] = 1,
+		.lun[1] = sc->device->id,
+		.lun[2] = (sc->device->lun >> 8) | 0x40,
+		.lun[3] = sc->device->lun & 0xff,
+	};
+	return virtscsi_tmf(vscsi, cmd);
+}
+
+static int virtscsi_abort(struct scsi_cmnd *sc)
+{
+	struct virtio_scsi *vscsi = shost_priv(sc->device->host);
+	struct virtio_scsi_cmd *cmd;
+
+	scmd_printk(KERN_INFO, sc, "abort\n");
+	cmd = mempool_alloc(virtscsi_cmd_pool, GFP_NOIO);
+	if (!cmd)
+		return FAILED;
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->sc = sc;
+	cmd->req.tmf = (struct virtio_scsi_ctrl_tmf_req){
+		.type = VIRTIO_SCSI_T_TMF,
+		.subtype = VIRTIO_SCSI_T_TMF_ABORT_TASK,
+		.lun[0] = 1,
+		.lun[1] = sc->device->id,
+		.lun[2] = (sc->device->lun >> 8) | 0x40,
+		.lun[3] = sc->device->lun & 0xff,
+		.tag = (unsigned long)sc,
+	};
+	return virtscsi_tmf(vscsi, cmd);
+}
+
+static struct scsi_host_template virtscsi_host_template = {
+	.module = THIS_MODULE,
+	.name = "Virtio SCSI HBA",
+	.proc_name = "virtio_scsi",
+	.queuecommand = virtscsi_queuecommand,
+	.this_id = -1,
+	.eh_abort_handler = virtscsi_abort,
+	.eh_device_reset_handler = virtscsi_device_reset,
+
+	.can_queue = 1024,
+	.dma_boundary = UINT_MAX,
+	.use_clustering = ENABLE_CLUSTERING,
+};
+
+#define virtscsi_config_get(vdev, fld) \
+	({ \
+		typeof(((struct virtio_scsi_config *)0)->fld) __val; \
+		vdev->config->get(vdev, \
+				  offsetof(struct virtio_scsi_config, fld), \
+				  &__val, sizeof(__val)); \
+		__val; \
+	})
+
+#define virtscsi_config_set(vdev, fld, val) \
+	(void)({ \
+		typeof(((struct virtio_scsi_config *)0)->fld) __val = (val); \
+		vdev->config->set(vdev, \
+				  offsetof(struct virtio_scsi_config, fld), \
+				  &__val, sizeof(__val)); \
+	})
+
+static int virtscsi_init(struct virtio_device *vdev,
+			 struct virtio_scsi *vscsi)
+{
+	int err;
+	struct virtqueue *vqs[3];
+	vq_callback_t *callbacks[] = {
+		virtscsi_ctrl_done,
+		virtscsi_event_done,
+		virtscsi_req_done
+	};
+	const char *names[] = {
+		"control",
+		"event",
+		"request"
+	};
+
+	/* Discover virtqueues and write information to configuration.  */
+	err = vdev->config->find_vqs(vdev, 3, vqs, callbacks, names);
+	if (err)
+		return err;
+
+	vscsi->ctrl_vq = vqs[0];
+	vscsi->event_vq = vqs[1];
+	vscsi->req_vq = vqs[2];
+
+	virtscsi_config_set(vdev, cdb_size, VIRTIO_SCSI_CDB_SIZE);
+	virtscsi_config_set(vdev, sense_size, VIRTIO_SCSI_SENSE_SIZE);
+	return 0;
+}
+
+static int __devinit virtscsi_probe(struct virtio_device *vdev)
+{
+	struct Scsi_Host *shost;
+	struct virtio_scsi *vscsi;
+	int err;
+	u32 sg_elems;
+	u32 cmd_per_lun;
+
+	/* We need to know how many segments before we allocate.
+	 * We need an extra sg elements at head and tail.
+	 */
+	sg_elems = virtscsi_config_get(vdev, seg_max) ?: 1;
+
+	/* Allocate memory and link the structs together.  */
+	shost = scsi_host_alloc(&virtscsi_host_template,
+		sizeof(*vscsi) + sizeof(vscsi->sg[0]) * (sg_elems + 2));
+
+	if (!shost)
+		return -ENOMEM;
+
+	shost->sg_tablesize = sg_elems;
+	vscsi = shost_priv(shost);
+	vscsi->vdev = vdev;
+	vdev->priv = shost;
+
+	/* Random initializations.  */
+	spin_lock_init(&vscsi->vq_lock);
+	sg_init_table(vscsi->sg, sg_elems + 2);
+
+	err = virtscsi_init(vdev, vscsi);
+	if (err)
+		goto virtscsi_init_failed;
+
+	cmd_per_lun = virtscsi_config_get(vdev, cmd_per_lun) ?: 1;
+	shost->cmd_per_lun = min_t(u32, cmd_per_lun, shost->can_queue);
+	shost->max_sectors = virtscsi_config_get(vdev, max_sectors) ?: 0xFFFF;
+	shost->max_lun = virtscsi_config_get(vdev, max_lun) + 1;
+	shost->max_id = virtscsi_config_get(vdev, max_target) + 1;
+	shost->max_channel = 0;
+	shost->max_cmd_len = VIRTIO_SCSI_CDB_SIZE;
+	err = scsi_add_host(shost, &vdev->dev);
+	if (err)
+		goto scsi_add_host_failed;
+
+	scsi_scan_host(shost);
+
+	return 0;
+
+scsi_add_host_failed:
+	vdev->config->del_vqs(vdev);
+virtscsi_init_failed:
+	scsi_host_put(shost);
+	return err;
+}
+
+static void virtscsi_remove_vqs(struct virtio_device *vdev)
+{
+	/* Stop all the virtqueues. */
+	vdev->config->reset(vdev);
+
+	vdev->config->del_vqs(vdev);
+}
+
+static void __devexit virtscsi_remove(struct virtio_device *vdev)
+{
+	struct Scsi_Host *shost = virtio_scsi_host(vdev);
+
+	scsi_remove_host(shost);
+
+	virtscsi_remove_vqs(vdev);
+	scsi_host_put(shost);
+}
+
+#ifdef CONFIG_PM
+static int virtscsi_freeze(struct virtio_device *vdev)
+{
+	virtscsi_remove_vqs(vdev);
+	return 0;
+}
+
+static int virtscsi_restore(struct virtio_device *vdev)
+{
+	struct Scsi_Host *sh = virtio_scsi_host(vdev);
+	struct virtio_scsi *vscsi = shost_priv(sh);
+
+	return virtscsi_init(vdev, vscsi);
+}
+#endif
+
+static struct virtio_device_id id_table[] = {
+	{ VIRTIO_ID_SCSI, VIRTIO_DEV_ANY_ID },
+	{ 0 },
+};
+
+static struct virtio_driver virtio_scsi_driver = {
+	.driver.name = KBUILD_MODNAME,
+	.driver.owner = THIS_MODULE,
+	.id_table = id_table,
+	.probe = virtscsi_probe,
+#ifdef CONFIG_PM
+	.freeze = virtscsi_freeze,
+	.restore = virtscsi_restore,
+#endif
+	.remove = __devexit_p(virtscsi_remove),
+};
+
+static int __init init(void)
+{
+	int ret = -ENOMEM;
+
+	virtscsi_cmd_cache = KMEM_CACHE(virtio_scsi_cmd, 0);
+	if (!virtscsi_cmd_cache) {
+		printk(KERN_ERR "kmem_cache_create() for "
+				"virtscsi_cmd_cache failed\n");
+		goto error;
+	}
+
+
+	virtscsi_cmd_pool =
+		mempool_create_slab_pool(VIRTIO_SCSI_MEMPOOL_SZ,
+					 virtscsi_cmd_cache);
+	if (!virtscsi_cmd_pool) {
+		printk(KERN_ERR "mempool_create() for"
+				"virtscsi_cmd_pool failed\n");
+		goto error;
+	}
+	ret = register_virtio_driver(&virtio_scsi_driver);
+	if (ret < 0)
+		goto error;
+
+	return 0;
+
+error:
+	if (virtscsi_cmd_pool) {
+		mempool_destroy(virtscsi_cmd_pool);
+		virtscsi_cmd_pool = NULL;
+	}
+	if (virtscsi_cmd_cache) {
+		kmem_cache_destroy(virtscsi_cmd_cache);
+		virtscsi_cmd_cache = NULL;
+	}
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	unregister_virtio_driver(&virtio_scsi_driver);
+	mempool_destroy(virtscsi_cmd_pool);
+	kmem_cache_destroy(virtscsi_cmd_cache);
+}
+module_init(init);
+module_exit(fini);
+
+MODULE_DEVICE_TABLE(virtio, id_table);
+MODULE_DESCRIPTION("Virtio SCSI HBA driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/sh/intc/balancing.c b/drivers/sh/intc/balancing.c
index cec7a96..bc78080 100644
--- a/drivers/sh/intc/balancing.c
+++ b/drivers/sh/intc/balancing.c
@@ -9,7 +9,7 @@
  */
 #include "internals.h"
 
-static unsigned long dist_handle[NR_IRQS];
+static unsigned long dist_handle[INTC_NR_IRQS];
 
 void intc_balancing_enable(unsigned int irq)
 {
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index e53e449..2fde897 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -42,7 +42,7 @@ unsigned int nr_intc_controllers;
  * - this needs to be at least 2 for 5-bit priorities on 7780
  */
 static unsigned int default_prio_level = 2;	/* 2 - 16 */
-static unsigned int intc_prio_level[NR_IRQS];	/* for now */
+static unsigned int intc_prio_level[INTC_NR_IRQS];	/* for now */
 
 unsigned int intc_get_dfl_prio_level(void)
 {
diff --git a/drivers/sh/intc/handle.c b/drivers/sh/intc/handle.c
index 057ce56..f461d53 100644
--- a/drivers/sh/intc/handle.c
+++ b/drivers/sh/intc/handle.c
@@ -13,7 +13,7 @@
 #include <linux/spinlock.h>
 #include "internals.h"
 
-static unsigned long ack_handle[NR_IRQS];
+static unsigned long ack_handle[INTC_NR_IRQS];
 
 static intc_enum __init intc_grp_id(struct intc_desc *desc,
 				    intc_enum enum_id)
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
index c7ec49f..93cec21 100644
--- a/drivers/sh/intc/virq.c
+++ b/drivers/sh/intc/virq.c
@@ -17,7 +17,7 @@
 #include <linux/export.h>
 #include "internals.h"
 
-static struct intc_map_entry intc_irq_xlate[NR_IRQS];
+static struct intc_map_entry intc_irq_xlate[INTC_NR_IRQS];
 
 struct intc_virq_list {
 	unsigned int irq;
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c
index 182e9c8..dae8be2 100644
--- a/drivers/spi/spi-nuc900.c
+++ b/drivers/spi/spi-nuc900.c
@@ -360,8 +360,6 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev)
 	}
 
 	hw = spi_master_get_devdata(master);
-	memset(hw, 0, sizeof(struct nuc900_spi));
-
 	hw->master = spi_master_get(master);
 	hw->pdata  = pdev->dev.platform_data;
 	hw->dev = &pdev->dev;
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index 2f9cb43..81847c9 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -29,7 +29,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
-#include <linux/workqueue.h>
+#include <linux/kthread.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -41,6 +41,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
 #include <linux/pm_runtime.h>
+#include <linux/sched.h>
 
 /*
  * This macro is used to define some register default values.
@@ -330,12 +331,13 @@ struct vendor_data {
  * @clk: outgoing clock "SPICLK" for the SPI bus
  * @master: SPI framework hookup
  * @master_info: controller-specific data from machine setup
- * @workqueue: a workqueue on which any spi_message request is queued
- * @pump_messages: work struct for scheduling work to the workqueue
+ * @kworker: thread struct for message pump
+ * @kworker_task: pointer to task for message pump kworker thread
+ * @pump_messages: work struct for scheduling work to the message pump
  * @queue_lock: spinlock to syncronise access to message queue
  * @queue: message queue
- * @busy: workqueue is busy
- * @running: workqueue is running
+ * @busy: message pump is busy
+ * @running: message pump is running
  * @pump_transfers: Tasklet used in Interrupt Transfer mode
  * @cur_msg: Pointer to current spi_message being processed
  * @cur_transfer: Pointer to current spi_transfer
@@ -365,9 +367,10 @@ struct pl022 {
 	struct clk			*clk;
 	struct spi_master		*master;
 	struct pl022_ssp_controller	*master_info;
-	/* Driver message queue */
-	struct workqueue_struct		*workqueue;
-	struct work_struct		pump_messages;
+	/* Driver message pump */
+	struct kthread_worker		kworker;
+	struct task_struct		*kworker_task;
+	struct kthread_work		pump_messages;
 	spinlock_t			queue_lock;
 	struct list_head		queue;
 	bool				busy;
@@ -504,7 +507,7 @@ static void giveback(struct pl022 *pl022)
 	pl022->cur_msg = NULL;
 	pl022->cur_transfer = NULL;
 	pl022->cur_chip = NULL;
-	queue_work(pl022->workqueue, &pl022->pump_messages);
+	queue_kthread_work(&pl022->kworker, &pl022->pump_messages);
 	spin_unlock_irqrestore(&pl022->queue_lock, flags);
 
 	msg->state = NULL;
@@ -1494,8 +1497,8 @@ out:
 }
 
 /**
- * pump_messages - Workqueue function which processes spi message queue
- * @data: pointer to private data of SSP driver
+ * pump_messages - kthread work function which processes spi message queue
+ * @work: pointer to kthread work struct contained in the pl022 private struct
  *
  * This function checks if there is any spi message in the queue that
  * needs processing and delegate control to appropriate function
@@ -1503,7 +1506,7 @@ out:
  * based on the kind of the transfer
  *
  */
-static void pump_messages(struct work_struct *work)
+static void pump_messages(struct kthread_work *work)
 {
 	struct pl022 *pl022 =
 		container_of(work, struct pl022, pump_messages);
@@ -1556,7 +1559,7 @@ static void pump_messages(struct work_struct *work)
 	if (!was_busy)
 		/*
 		 * We enable the core voltage and clocks here, then the clocks
-		 * and core will be disabled when this workqueue is run again
+		 * and core will be disabled when this thread is run again
 		 * and there is no more work to be done.
 		 */
 		pm_runtime_get_sync(&pl022->adev->dev);
@@ -1572,6 +1575,8 @@ static void pump_messages(struct work_struct *work)
 
 static int __init init_queue(struct pl022 *pl022)
 {
+	struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+
 	INIT_LIST_HEAD(&pl022->queue);
 	spin_lock_init(&pl022->queue_lock);
 
@@ -1581,11 +1586,29 @@ static int __init init_queue(struct pl022 *pl022)
 	tasklet_init(&pl022->pump_transfers, pump_transfers,
 			(unsigned long)pl022);
 
-	INIT_WORK(&pl022->pump_messages, pump_messages);
-	pl022->workqueue = create_singlethread_workqueue(
+	init_kthread_worker(&pl022->kworker);
+	pl022->kworker_task = kthread_run(kthread_worker_fn,
+					&pl022->kworker,
 					dev_name(pl022->master->dev.parent));
-	if (pl022->workqueue == NULL)
-		return -EBUSY;
+	if (IS_ERR(pl022->kworker_task)) {
+		dev_err(&pl022->adev->dev,
+			"failed to create message pump task\n");
+		return -ENOMEM;
+	}
+	init_kthread_work(&pl022->pump_messages, pump_messages);
+
+	/*
+	 * Board config will indicate if this controller should run the
+	 * message pump with high (realtime) priority to reduce the transfer
+	 * latency on the bus by minimising the delay between a transfer
+	 * request and the scheduling of the message pump thread. Without this
+	 * setting the message pump thread will remain at default priority.
+	 */
+	if (pl022->master_info->rt) {
+		dev_info(&pl022->adev->dev,
+			"will run message pump with realtime priority\n");
+		sched_setscheduler(pl022->kworker_task, SCHED_FIFO, &param);
+	}
 
 	return 0;
 }
@@ -1608,7 +1631,7 @@ static int start_queue(struct pl022 *pl022)
 	pl022->next_msg_cs_active = false;
 	spin_unlock_irqrestore(&pl022->queue_lock, flags);
 
-	queue_work(pl022->workqueue, &pl022->pump_messages);
+	queue_kthread_work(&pl022->kworker, &pl022->pump_messages);
 
 	return 0;
 }
@@ -1646,16 +1669,20 @@ static int destroy_queue(struct pl022 *pl022)
 	int status;
 
 	status = stop_queue(pl022);
-	/* we are unloading the module or failing to load (only two calls
+
+	/*
+	 * We are unloading the module or failing to load (only two calls
 	 * to this routine), and neither call can handle a return value.
-	 * However, destroy_workqueue calls flush_workqueue, and that will
-	 * block until all work is done.  If the reason that stop_queue
-	 * timed out is that the work will never finish, then it does no
-	 * good to call destroy_workqueue, so return anyway. */
+	 * However, flush_kthread_worker will block until all work is done.
+	 * If the reason that stop_queue timed out is that the work will never
+	 * finish, then it does no good to call flush/stop thread, so
+	 * return anyway.
+	 */
 	if (status != 0)
 		return status;
 
-	destroy_workqueue(pl022->workqueue);
+	flush_kthread_worker(&pl022->kworker);
+	kthread_stop(pl022->kworker_task);
 
 	return 0;
 }
@@ -1802,7 +1829,7 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg)
 
 	list_add_tail(&msg->queue, &pl022->queue);
 	if (pl022->running && !pl022->busy)
-		queue_work(pl022->workqueue, &pl022->pump_messages);
+		queue_kthread_work(&pl022->kworker, &pl022->pump_messages);
 
 	spin_unlock_irqrestore(&pl022->queue_lock, flags);
 	return 0;
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index dcf7e10..b899af6 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -20,10 +20,12 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/workqueue.h>
+#include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
 
 #include <mach/dma.h>
@@ -153,6 +155,7 @@ struct s3c64xx_spi_dma_data {
  * @tx_dmach: Controller's DMA channel for Tx.
  * @sfr_start: BUS address of SPI controller regs.
  * @regs: Pointer to ioremap'ed controller registers.
+ * @irq: interrupt
  * @xfer_completion: To indicate completion of xfer task.
  * @cur_mode: Stores the active configuration of the controller.
  * @cur_bpw: Stores the active bits per word settings.
@@ -780,6 +783,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
 	while (!acquire_dma(sdd))
 		msleep(10);
 
+	pm_runtime_get_sync(&sdd->pdev->dev);
+
 	spin_lock_irqsave(&sdd->lock, flags);
 
 	while (!list_empty(&sdd->queue)
@@ -808,6 +813,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
 	/* Free DMA channels */
 	sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
 	sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
+
+	pm_runtime_put(&sdd->pdev->dev);
 }
 
 static int s3c64xx_spi_transfer(struct spi_device *spi,
@@ -890,6 +897,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
 		goto setup_exit;
 	}
 
+	pm_runtime_get_sync(&sdd->pdev->dev);
+
 	/* Check if we can provide the requested rate */
 	if (!sci->clk_from_cmu) {
 		u32 psr, speed;
@@ -922,6 +931,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
 			err = -EINVAL;
 	}
 
+	pm_runtime_put(&sdd->pdev->dev);
+
 setup_exit:
 
 	/* setup() returns with device de-selected */
@@ -930,6 +941,33 @@ setup_exit:
 	return err;
 }
 
+static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
+{
+	struct s3c64xx_spi_driver_data *sdd = data;
+	struct spi_master *spi = sdd->master;
+	unsigned int val;
+
+	val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+	val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR |
+		S3C64XX_SPI_PND_RX_UNDERRUN_CLR |
+		S3C64XX_SPI_PND_TX_OVERRUN_CLR |
+		S3C64XX_SPI_PND_TX_UNDERRUN_CLR;
+
+	writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR);
+
+	if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR)
+		dev_err(&spi->dev, "RX overrun\n");
+	if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR)
+		dev_err(&spi->dev, "RX underrun\n");
+	if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR)
+		dev_err(&spi->dev, "TX overrun\n");
+	if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR)
+		dev_err(&spi->dev, "TX underrun\n");
+
+	return IRQ_HANDLED;
+}
+
 static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
 {
 	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
@@ -970,7 +1008,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
 	struct s3c64xx_spi_driver_data *sdd;
 	struct s3c64xx_spi_info *sci;
 	struct spi_master *master;
-	int ret;
+	int ret, irq;
 	char clk_name[16];
 
 	if (pdev->id < 0) {
@@ -1006,6 +1044,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
 		return -ENXIO;
 	}
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq);
+		return irq;
+	}
+
 	master = spi_alloc_master(&pdev->dev,
 				sizeof(struct s3c64xx_spi_driver_data));
 	if (master == NULL) {
@@ -1100,10 +1144,21 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
 	INIT_WORK(&sdd->work, s3c64xx_spi_work);
 	INIT_LIST_HEAD(&sdd->queue);
 
+	ret = request_irq(irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n",
+			irq, ret);
+		goto err8;
+	}
+
+	writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN |
+	       S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
+	       sdd->regs + S3C64XX_SPI_INT_EN);
+
 	if (spi_register_master(master)) {
 		dev_err(&pdev->dev, "cannot register SPI master\n");
 		ret = -EBUSY;
-		goto err8;
+		goto err9;
 	}
 
 	dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
@@ -1113,8 +1168,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
 					mem_res->end, mem_res->start,
 					sdd->rx_dma.dmach, sdd->tx_dma.dmach);
 
+	pm_runtime_enable(&pdev->dev);
+
 	return 0;
 
+err9:
+	free_irq(irq, sdd);
 err8:
 	destroy_workqueue(sdd->workqueue);
 err7:
@@ -1144,6 +1203,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
 	struct resource	*mem_res;
 	unsigned long flags;
 
+	pm_runtime_disable(&pdev->dev);
+
 	spin_lock_irqsave(&sdd->lock, flags);
 	sdd->state |= SUSPND;
 	spin_unlock_irqrestore(&sdd->lock, flags);
@@ -1153,6 +1214,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
 
 	spi_unregister_master(master);
 
+	writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
+
+	free_irq(platform_get_irq(pdev, 0), sdd);
+
 	destroy_workqueue(sdd->workqueue);
 
 	clk_disable(sdd->src_clk);
@@ -1174,9 +1239,9 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
+static int s3c64xx_spi_suspend(struct device *dev)
 {
-	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 	unsigned long flags;
 
@@ -1196,9 +1261,10 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int s3c64xx_spi_resume(struct platform_device *pdev)
+static int s3c64xx_spi_resume(struct device *dev)
 {
-	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
+	struct platform_device *pdev = to_platform_device(dev);
+	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
 	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
 	struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
 	unsigned long flags;
@@ -1217,19 +1283,45 @@ static int s3c64xx_spi_resume(struct platform_device *pdev)
 
 	return 0;
 }
-#else
-#define s3c64xx_spi_suspend	NULL
-#define s3c64xx_spi_resume	NULL
 #endif /* CONFIG_PM */
 
+#ifdef CONFIG_PM_RUNTIME
+static int s3c64xx_spi_runtime_suspend(struct device *dev)
+{
+	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
+
+	clk_disable(sdd->clk);
+	clk_disable(sdd->src_clk);
+
+	return 0;
+}
+
+static int s3c64xx_spi_runtime_resume(struct device *dev)
+{
+	struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
+	struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
+
+	clk_enable(sdd->src_clk);
+	clk_enable(sdd->clk);
+
+	return 0;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops s3c64xx_spi_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume)
+	SET_RUNTIME_PM_OPS(s3c64xx_spi_runtime_suspend,
+			   s3c64xx_spi_runtime_resume, NULL)
+};
+
 static struct platform_driver s3c64xx_spi_driver = {
 	.driver = {
 		.name	= "s3c64xx-spi",
 		.owner = THIS_MODULE,
+		.pm = &s3c64xx_spi_pm,
 	},
 	.remove = s3c64xx_spi_remove,
-	.suspend = s3c64xx_spi_suspend,
-	.resume = s3c64xx_spi_resume,
 };
 MODULE_ALIAS("platform:s3c64xx-spi");
 
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index e5a2e0e..b58fef7 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -13,6 +13,9 @@
 #include <linux/ssb/ssb_driver_chipcommon.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
+#endif
 
 #include "ssb_private.h"
 
@@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc,
 	u32 pmuctl, tmp, pllctl;
 	unsigned int i;
 
-	if ((bus->chip_id == 0x5354) && !crystalfreq) {
-		/* The 5354 crystal freq is 25MHz */
-		crystalfreq = 25000;
-	}
 	if (crystalfreq)
 		e = pmu0_plltab_find_entry(crystalfreq);
 	if (!e)
@@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
 	u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
 
 	if (bus->bustype == SSB_BUSTYPE_SSB) {
-		/* TODO: The user may override the crystal frequency. */
+#ifdef CONFIG_BCM47XX
+		char buf[20];
+		if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
+			crystalfreq = simple_strtoul(buf, NULL, 0);
+#endif
 	}
 
 	switch (bus->chip_id) {
@@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc)
 		ssb_pmu1_pllinit_r0(cc, crystalfreq);
 		break;
 	case 0x4328:
+		ssb_pmu0_pllinit_r0(cc, crystalfreq);
+		break;
 	case 0x5354:
+		if (crystalfreq == 0)
+			crystalfreq = 25000;
 		ssb_pmu0_pllinit_r0(cc, crystalfreq);
 		break;
 	case 0x4322:
@@ -607,3 +614,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
 
 EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
 EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
+
+u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
+{
+	struct ssb_bus *bus = cc->dev->bus;
+
+	switch (bus->chip_id) {
+	case 0x5354:
+		/* 5354 chip uses a non programmable PLL of frequency 240MHz */
+		return 240000000;
+	default:
+		ssb_printk(KERN_ERR PFX
+			   "ERROR: PMU cpu clock unknown for device %04X\n",
+			   bus->chip_id);
+		return 0;
+	}
+}
+
+u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
+{
+	struct ssb_bus *bus = cc->dev->bus;
+
+	switch (bus->chip_id) {
+	case 0x5354:
+		return 120000000;
+	default:
+		ssb_printk(KERN_ERR PFX
+			   "ERROR: PMU controlclock unknown for device %04X\n",
+			   bus->chip_id);
+		return 0;
+	}
+}
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index ced5015..7e2ddc0 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
 	struct ssb_bus *bus = mcore->dev->bus;
 	u32 pll_type, n, m, rate = 0;
 
+	if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
+		return ssb_pmu_get_cpu_clock(&bus->chipco);
+
 	if (bus->extif.dev) {
 		ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
 	} else if (bus->chipco.dev) {
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index bb6317f..df0f145 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -140,19 +140,6 @@ static void ssb_device_put(struct ssb_device *dev)
 		put_device(dev->dev);
 }
 
-static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
-{
-	if (drv)
-		get_driver(&drv->drv);
-	return drv;
-}
-
-static inline void ssb_driver_put(struct ssb_driver *drv)
-{
-	if (drv)
-		put_driver(&drv->drv);
-}
-
 static int ssb_device_resume(struct device *dev)
 {
 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
@@ -250,11 +237,9 @@ int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx)
 			ssb_device_put(sdev);
 			continue;
 		}
-		sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
-		if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
-			ssb_device_put(sdev);
+		sdrv = drv_to_ssb_drv(sdev->dev->driver);
+		if (SSB_WARN_ON(!sdrv->remove))
 			continue;
-		}
 		sdrv->remove(sdev);
 		ctx->device_frozen[i] = 1;
 	}
@@ -293,7 +278,6 @@ int ssb_devices_thaw(struct ssb_freeze_context *ctx)
 				   dev_name(sdev->dev));
 			result = err;
 		}
-		ssb_driver_put(sdrv);
 		ssb_device_put(sdev);
 	}
 
@@ -1094,6 +1078,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
 	u32 plltype;
 	u32 clkctl_n, clkctl_m;
 
+	if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
+		return ssb_pmu_get_controlclock(&bus->chipco);
+
 	if (ssb_extif_available(&bus->extif))
 		ssb_extif_get_clockcontrol(&bus->extif, &plltype,
 					   &clkctl_n, &clkctl_m);
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 973223f..befa89e 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -523,7 +523,13 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
 {
 	int i;
-	u16 v;
+	u16 v, o;
+	u16 pwr_info_offset[] = {
+		SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
+		SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
+	};
+	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
+			ARRAY_SIZE(out->core_pwr_info));
 
 	/* extract the MAC address */
 	for (i = 0; i < 3; i++) {
@@ -607,6 +613,38 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
 	memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
 	       sizeof(out->antenna_gain.ghz5));
 
+	/* Extract cores power info info */
+	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
+		o = pwr_info_offset[i];
+		SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+			SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
+		SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
+			SSB_SPROM8_2G_MAXP, 0);
+
+		SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
+
+		SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+			SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
+		SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
+			SSB_SPROM8_5G_MAXP, 0);
+		SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
+			SSB_SPROM8_5GH_MAXP, 0);
+		SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
+			SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
+
+		SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
+		SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
+	}
+
 	/* Extract FEM info */
 	SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
 		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 3e84487..266c7c5 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -318,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
 			bus->chip_package = 0;
 		}
 	}
+	ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
+		   "package 0x%02X\n", bus->chip_id, bus->chip_rev,
+		   bus->chip_package);
 	if (!bus->nr_devices)
 		bus->nr_devices = chipid_to_nrcores(bus->chip_id);
 	if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 7765301..a305550 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -207,4 +207,8 @@ static inline void b43_pci_ssb_bridge_exit(void)
 }
 #endif /* CONFIG_SSB_B43_PCI_BRIDGE */
 
+/* driver_chipcommon_pmu.c */
+extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
+extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
+
 #endif /* LINUX_SSB_PRIVATE_H_ */
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 9e63472..c37dbc5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -76,8 +76,6 @@ source "drivers/staging/vt6655/Kconfig"
 
 source "drivers/staging/vt6656/Kconfig"
 
-source "drivers/staging/hv/Kconfig"
-
 source "drivers/staging/vme/Kconfig"
 
 source "drivers/staging/sep/Kconfig"
@@ -88,6 +86,8 @@ source "drivers/staging/zram/Kconfig"
 
 source "drivers/staging/zcache/Kconfig"
 
+source "drivers/staging/zsmalloc/Kconfig"
+
 source "drivers/staging/wlags49_h2/Kconfig"
 
 source "drivers/staging/wlags49_h25/Kconfig"
@@ -128,4 +128,8 @@ source "drivers/staging/omapdrm/Kconfig"
 
 source "drivers/staging/android/Kconfig"
 
+source "drivers/staging/telephony/Kconfig"
+
+source "drivers/staging/ramster/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 943e148..035a035 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -29,13 +29,12 @@ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)	+= quatech_usb2/
 obj-$(CONFIG_OCTEON_ETHERNET)	+= octeon/
 obj-$(CONFIG_VT6655)		+= vt6655/
 obj-$(CONFIG_VT6656)		+= vt6656/
-obj-$(CONFIG_HYPERV)		+= hv/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_DX_SEP)            += sep/
 obj-$(CONFIG_IIO)		+= iio/
 obj-$(CONFIG_ZRAM)		+= zram/
-obj-$(CONFIG_XVMALLOC)		+= zram/
 obj-$(CONFIG_ZCACHE)		+= zcache/
+obj-$(CONFIG_ZSMALLOC)		+= zsmalloc/
 obj-$(CONFIG_WLAGS49_H2)	+= wlags49_h2/
 obj-$(CONFIG_WLAGS49_H25)	+= wlags49_h25/
 obj-$(CONFIG_FB_SM7XX)		+= sm7xx/
@@ -55,3 +54,5 @@ obj-$(CONFIG_INTEL_MEI)		+= mei/
 obj-$(CONFIG_MFD_NVEC)		+= nvec/
 obj-$(CONFIG_DRM_OMAP)		+= omapdrm/
 obj-$(CONFIG_ANDROID)		+= android/
+obj-$(CONFIG_PHONE)		+= telephony/
+obj-$(CONFIG_RAMSTER)		+= ramster/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index fef3580..f3b7c75 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -102,6 +102,32 @@ config ANDROID_LOW_MEMORY_KILLER
 
 source "drivers/staging/android/switch/Kconfig"
 
+config ANDROID_INTF_ALARM
+	bool "Android alarm driver"
+	depends on RTC_CLASS
+	default n
+	help
+	  Provides non-wakeup and rtc backed wakeup alarms based on rtc or
+	  elapsed realtime, and a non-wakeup alarm on the monotonic clock.
+	  Also provides an interface to set the wall time which must be used
+	  for elapsed realtime to work.
+
+config ANDROID_INTF_ALARM_DEV
+	bool "Android alarm device"
+	depends on ANDROID_INTF_ALARM
+	default y
+	help
+	  Exports the alarm interface to user-space.
+
+config ANDROID_ALARM_OLDDRV_COMPAT
+	bool "Android Alarm compatability with old drivers"
+	depends on ANDROID_INTF_ALARM
+	default n
+	help
+	  Provides preprocessor alias to aid compatability with
+	  older out-of-tree drivers that use the Android Alarm
+	  in-kernel API. This will be removed eventually.
+
 endif # if ANDROID
 
 endmenu
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 5fcc24f..785f269 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
 obj-$(CONFIG_ANDROID_SWITCH)		+= switch/
+obj-$(CONFIG_ANDROID_INTF_ALARM)	+= alarm.o
+obj-$(CONFIG_ANDROID_INTF_ALARM_DEV)	+= alarm-dev.o
diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO
index e59c5be..b15fb0d 100644
--- a/drivers/staging/android/TODO
+++ b/drivers/staging/android/TODO
@@ -3,7 +3,7 @@ TODO:
 	- sparse fixes
 	- rename files to be not so "generic"
 	- make sure things build as modules properly
-	- add proper arch dependancies as needed
+	- add proper arch dependencies as needed
 	- audit userspace interfaces to make sure they are sane
 
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c
new file mode 100644
index 0000000..03efb34
--- /dev/null
+++ b/drivers/staging/android/alarm-dev.c
@@ -0,0 +1,297 @@
+/* drivers/rtc/alarm-dev.c
+ *
+ * Copyright (C) 2007-2009 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include "android_alarm.h"
+
+/* XXX - Hack out wakelocks, while they are out of tree */
+struct wake_lock {
+	int i;
+};
+#define wake_lock(x)
+#define wake_lock_timeout(x, y)
+#define wake_unlock(x)
+#define WAKE_LOCK_SUSPEND 0
+#define wake_lock_init(x, y, z) ((x)->i = 1)
+#define wake_lock_destroy(x)
+
+#define ANDROID_ALARM_PRINT_INFO (1U << 0)
+#define ANDROID_ALARM_PRINT_IO (1U << 1)
+#define ANDROID_ALARM_PRINT_INT (1U << 2)
+
+
+static int debug_mask = ANDROID_ALARM_PRINT_INFO;
+module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define pr_alarm(debug_level_mask, args...) \
+	do { \
+		if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \
+			pr_info(args); \
+		} \
+	} while (0)
+
+#define ANDROID_ALARM_WAKEUP_MASK ( \
+	ANDROID_ALARM_RTC_WAKEUP_MASK | \
+	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
+
+/* support old usespace code */
+#define ANDROID_ALARM_SET_OLD               _IOW('a', 2, time_t) /* set alarm */
+#define ANDROID_ALARM_SET_AND_WAIT_OLD      _IOW('a', 3, time_t)
+
+static int alarm_opened;
+static DEFINE_SPINLOCK(alarm_slock);
+static struct wake_lock alarm_wake_lock;
+static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
+static uint32_t alarm_pending;
+static uint32_t alarm_enabled;
+static uint32_t wait_pending;
+
+static struct android_alarm alarms[ANDROID_ALARM_TYPE_COUNT];
+
+static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int rv = 0;
+	unsigned long flags;
+	struct timespec new_alarm_time;
+	struct timespec new_rtc_time;
+	struct timespec tmp_time;
+	enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
+	uint32_t alarm_type_mask = 1U << alarm_type;
+
+	if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
+		return -EINVAL;
+
+	if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
+		if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+			return -EPERM;
+		if (file->private_data == NULL &&
+		    cmd != ANDROID_ALARM_SET_RTC) {
+			spin_lock_irqsave(&alarm_slock, flags);
+			if (alarm_opened) {
+				spin_unlock_irqrestore(&alarm_slock, flags);
+				return -EBUSY;
+			}
+			alarm_opened = 1;
+			file->private_data = (void *)1;
+			spin_unlock_irqrestore(&alarm_slock, flags);
+		}
+	}
+
+	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
+	case ANDROID_ALARM_CLEAR(0):
+		spin_lock_irqsave(&alarm_slock, flags);
+		pr_alarm(IO, "alarm %d clear\n", alarm_type);
+		android_alarm_try_to_cancel(&alarms[alarm_type]);
+		if (alarm_pending) {
+			alarm_pending &= ~alarm_type_mask;
+			if (!alarm_pending && !wait_pending)
+				wake_unlock(&alarm_wake_lock);
+		}
+		alarm_enabled &= ~alarm_type_mask;
+		spin_unlock_irqrestore(&alarm_slock, flags);
+		break;
+
+	case ANDROID_ALARM_SET_OLD:
+	case ANDROID_ALARM_SET_AND_WAIT_OLD:
+		if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) {
+			rv = -EFAULT;
+			goto err1;
+		}
+		new_alarm_time.tv_nsec = 0;
+		goto from_old_alarm_set;
+
+	case ANDROID_ALARM_SET_AND_WAIT(0):
+	case ANDROID_ALARM_SET(0):
+		if (copy_from_user(&new_alarm_time, (void __user *)arg,
+		    sizeof(new_alarm_time))) {
+			rv = -EFAULT;
+			goto err1;
+		}
+from_old_alarm_set:
+		spin_lock_irqsave(&alarm_slock, flags);
+		pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type,
+			new_alarm_time.tv_sec, new_alarm_time.tv_nsec);
+		alarm_enabled |= alarm_type_mask;
+		android_alarm_start_range(&alarms[alarm_type],
+			timespec_to_ktime(new_alarm_time),
+			timespec_to_ktime(new_alarm_time));
+		spin_unlock_irqrestore(&alarm_slock, flags);
+		if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0)
+		    && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)
+			break;
+		/* fall though */
+	case ANDROID_ALARM_WAIT:
+		spin_lock_irqsave(&alarm_slock, flags);
+		pr_alarm(IO, "alarm wait\n");
+		if (!alarm_pending && wait_pending) {
+			wake_unlock(&alarm_wake_lock);
+			wait_pending = 0;
+		}
+		spin_unlock_irqrestore(&alarm_slock, flags);
+		rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
+		if (rv)
+			goto err1;
+		spin_lock_irqsave(&alarm_slock, flags);
+		rv = alarm_pending;
+		wait_pending = 1;
+		alarm_pending = 0;
+		spin_unlock_irqrestore(&alarm_slock, flags);
+		break;
+	case ANDROID_ALARM_SET_RTC:
+		if (copy_from_user(&new_rtc_time, (void __user *)arg,
+		    sizeof(new_rtc_time))) {
+			rv = -EFAULT;
+			goto err1;
+		}
+		rv = android_alarm_set_rtc(new_rtc_time);
+		spin_lock_irqsave(&alarm_slock, flags);
+		alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
+		wake_up(&alarm_wait_queue);
+		spin_unlock_irqrestore(&alarm_slock, flags);
+		if (rv < 0)
+			goto err1;
+		break;
+	case ANDROID_ALARM_GET_TIME(0):
+		switch (alarm_type) {
+		case ANDROID_ALARM_RTC_WAKEUP:
+		case ANDROID_ALARM_RTC:
+			getnstimeofday(&tmp_time);
+			break;
+		case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
+		case ANDROID_ALARM_ELAPSED_REALTIME:
+			tmp_time =
+				ktime_to_timespec(alarm_get_elapsed_realtime());
+			break;
+		case ANDROID_ALARM_TYPE_COUNT:
+		case ANDROID_ALARM_SYSTEMTIME:
+			ktime_get_ts(&tmp_time);
+			break;
+		}
+		if (copy_to_user((void __user *)arg, &tmp_time,
+		    sizeof(tmp_time))) {
+			rv = -EFAULT;
+			goto err1;
+		}
+		break;
+
+	default:
+		rv = -EINVAL;
+		goto err1;
+	}
+err1:
+	return rv;
+}
+
+static int alarm_open(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+static int alarm_release(struct inode *inode, struct file *file)
+{
+	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&alarm_slock, flags);
+	if (file->private_data != 0) {
+		for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
+			uint32_t alarm_type_mask = 1U << i;
+			if (alarm_enabled & alarm_type_mask) {
+				pr_alarm(INFO, "alarm_release: clear alarm, "
+					"pending %d\n",
+					!!(alarm_pending & alarm_type_mask));
+				alarm_enabled &= ~alarm_type_mask;
+			}
+			spin_unlock_irqrestore(&alarm_slock, flags);
+			android_alarm_cancel(&alarms[i]);
+			spin_lock_irqsave(&alarm_slock, flags);
+		}
+		if (alarm_pending | wait_pending) {
+			if (alarm_pending)
+				pr_alarm(INFO, "alarm_release: clear "
+					"pending alarms %x\n", alarm_pending);
+			wake_unlock(&alarm_wake_lock);
+			wait_pending = 0;
+			alarm_pending = 0;
+		}
+		alarm_opened = 0;
+	}
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	return 0;
+}
+
+static void alarm_triggered(struct android_alarm *alarm)
+{
+	unsigned long flags;
+	uint32_t alarm_type_mask = 1U << alarm->type;
+
+	pr_alarm(INT, "alarm_triggered type %d\n", alarm->type);
+	spin_lock_irqsave(&alarm_slock, flags);
+	if (alarm_enabled & alarm_type_mask) {
+		wake_lock_timeout(&alarm_wake_lock, 5 * HZ);
+		alarm_enabled &= ~alarm_type_mask;
+		alarm_pending |= alarm_type_mask;
+		wake_up(&alarm_wait_queue);
+	}
+	spin_unlock_irqrestore(&alarm_slock, flags);
+}
+
+static const struct file_operations alarm_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = alarm_ioctl,
+	.open = alarm_open,
+	.release = alarm_release,
+};
+
+static struct miscdevice alarm_device = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "alarm",
+	.fops = &alarm_fops,
+};
+
+static int __init alarm_dev_init(void)
+{
+	int err;
+	int i;
+
+	err = misc_register(&alarm_device);
+	if (err)
+		return err;
+
+	for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++)
+		android_alarm_init(&alarms[i], i, alarm_triggered);
+	wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm");
+
+	return 0;
+}
+
+static void  __exit alarm_dev_exit(void)
+{
+	misc_deregister(&alarm_device);
+	wake_lock_destroy(&alarm_wake_lock);
+}
+
+module_init(alarm_dev_init);
+module_exit(alarm_dev_exit);
+
diff --git a/drivers/staging/android/alarm.c b/drivers/staging/android/alarm.c
new file mode 100644
index 0000000..c68950b
--- /dev/null
+++ b/drivers/staging/android/alarm.c
@@ -0,0 +1,601 @@
+/* drivers/rtc/alarm.c
+ *
+ * Copyright (C) 2007-2009 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include "android_alarm.h"
+
+/* XXX - Hack out wakelocks, while they are out of tree */
+struct wake_lock {
+	int i;
+};
+#define wake_lock(x)
+#define wake_lock_timeout(x, y)
+#define wake_unlock(x)
+#define WAKE_LOCK_SUSPEND 0
+#define wake_lock_init(x, y, z) ((x)->i = 1)
+#define wake_lock_destroy(x)
+
+#define ANDROID_ALARM_PRINT_ERROR (1U << 0)
+#define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1)
+#define ANDROID_ALARM_PRINT_TSET (1U << 2)
+#define ANDROID_ALARM_PRINT_CALL (1U << 3)
+#define ANDROID_ALARM_PRINT_SUSPEND (1U << 4)
+#define ANDROID_ALARM_PRINT_INT (1U << 5)
+#define ANDROID_ALARM_PRINT_FLOW (1U << 6)
+
+static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \
+			ANDROID_ALARM_PRINT_INIT_STATUS;
+module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define pr_alarm(debug_level_mask, args...) \
+	do { \
+		if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \
+			pr_info(args); \
+		} \
+	} while (0)
+
+#define ANDROID_ALARM_WAKEUP_MASK ( \
+	ANDROID_ALARM_RTC_WAKEUP_MASK | \
+	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
+
+/* support old usespace code */
+#define ANDROID_ALARM_SET_OLD               _IOW('a', 2, time_t) /* set alarm */
+#define ANDROID_ALARM_SET_AND_WAIT_OLD      _IOW('a', 3, time_t)
+
+struct alarm_queue {
+	struct rb_root alarms;
+	struct rb_node *first;
+	struct hrtimer timer;
+	ktime_t delta;
+	bool stopped;
+	ktime_t stopped_time;
+};
+
+static struct rtc_device *alarm_rtc_dev;
+static DEFINE_SPINLOCK(alarm_slock);
+static DEFINE_MUTEX(alarm_setrtc_mutex);
+static struct wake_lock alarm_rtc_wake_lock;
+static struct platform_device *alarm_platform_dev;
+struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT];
+static bool suspended;
+
+static void update_timer_locked(struct alarm_queue *base, bool head_removed)
+{
+	struct android_alarm *alarm;
+	bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] ||
+			base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP];
+
+	if (base->stopped) {
+		pr_alarm(FLOW, "changed alarm while setting the wall time\n");
+		return;
+	}
+
+	if (is_wakeup && !suspended && head_removed)
+		wake_unlock(&alarm_rtc_wake_lock);
+
+	if (!base->first)
+		return;
+
+	alarm = container_of(base->first, struct android_alarm, node);
+
+	pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n",
+		alarm->type, alarm->function, ktime_to_ns(alarm->expires));
+
+	if (is_wakeup && suspended) {
+		pr_alarm(FLOW, "changed alarm while suspened\n");
+		wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ);
+		return;
+	}
+
+	hrtimer_try_to_cancel(&base->timer);
+	base->timer.node.expires = ktime_add(base->delta, alarm->expires);
+	base->timer._softexpires = ktime_add(base->delta, alarm->softexpires);
+	hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS);
+}
+
+static void alarm_enqueue_locked(struct android_alarm *alarm)
+{
+	struct alarm_queue *base = &alarms[alarm->type];
+	struct rb_node **link = &base->alarms.rb_node;
+	struct rb_node *parent = NULL;
+	struct android_alarm *entry;
+	int leftmost = 1;
+	bool was_first = false;
+
+	pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n",
+		alarm->type, alarm->function, ktime_to_ns(alarm->expires));
+
+	if (base->first == &alarm->node) {
+		base->first = rb_next(&alarm->node);
+		was_first = true;
+	}
+	if (!RB_EMPTY_NODE(&alarm->node)) {
+		rb_erase(&alarm->node, &base->alarms);
+		RB_CLEAR_NODE(&alarm->node);
+	}
+
+	while (*link) {
+		parent = *link;
+		entry = rb_entry(parent, struct android_alarm, node);
+		/*
+		* We dont care about collisions. Nodes with
+		* the same expiry time stay together.
+		*/
+		if (alarm->expires.tv64 < entry->expires.tv64) {
+			link = &(*link)->rb_left;
+		} else {
+			link = &(*link)->rb_right;
+			leftmost = 0;
+		}
+	}
+	if (leftmost)
+		base->first = &alarm->node;
+	if (leftmost || was_first)
+		update_timer_locked(base, was_first);
+
+	rb_link_node(&alarm->node, parent, link);
+	rb_insert_color(&alarm->node, &base->alarms);
+}
+
+/**
+ * android_alarm_init - initialize an alarm
+ * @alarm:	the alarm to be initialized
+ * @type:	the alarm type to be used
+ * @function:	alarm callback function
+ */
+void android_alarm_init(struct android_alarm *alarm,
+	enum android_alarm_type type, void (*function)(struct android_alarm *))
+{
+	RB_CLEAR_NODE(&alarm->node);
+	alarm->type = type;
+	alarm->function = function;
+
+	pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function);
+}
+
+
+/**
+ * android_alarm_start_range - (re)start an alarm
+ * @alarm:	the alarm to be added
+ * @start:	earliest expiry time
+ * @end:	expiry time
+ */
+void android_alarm_start_range(struct android_alarm *alarm, ktime_t start,
+								ktime_t end)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&alarm_slock, flags);
+	alarm->softexpires = start;
+	alarm->expires = end;
+	alarm_enqueue_locked(alarm);
+	spin_unlock_irqrestore(&alarm_slock, flags);
+}
+
+/**
+ * android_alarm_try_to_cancel - try to deactivate an alarm
+ * @alarm:	alarm to stop
+ *
+ * Returns:
+ *  0 when the alarm was not active
+ *  1 when the alarm was active
+ * -1 when the alarm may currently be excuting the callback function and
+ *    cannot be stopped (it may also be inactive)
+ */
+int android_alarm_try_to_cancel(struct android_alarm *alarm)
+{
+	struct alarm_queue *base = &alarms[alarm->type];
+	unsigned long flags;
+	bool first = false;
+	int ret = 0;
+
+	spin_lock_irqsave(&alarm_slock, flags);
+	if (!RB_EMPTY_NODE(&alarm->node)) {
+		pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n",
+			alarm->type, alarm->function,
+			ktime_to_ns(alarm->expires));
+		ret = 1;
+		if (base->first == &alarm->node) {
+			base->first = rb_next(&alarm->node);
+			first = true;
+		}
+		rb_erase(&alarm->node, &base->alarms);
+		RB_CLEAR_NODE(&alarm->node);
+		if (first)
+			update_timer_locked(base, true);
+	} else
+		pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n",
+			alarm->type, alarm->function);
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	if (!ret && hrtimer_callback_running(&base->timer))
+		ret = -1;
+	return ret;
+}
+
+/**
+ * android_alarm_cancel - cancel an alarm and wait for the handler to finish.
+ * @alarm:	the alarm to be cancelled
+ *
+ * Returns:
+ *  0 when the alarm was not active
+ *  1 when the alarm was active
+ */
+int android_alarm_cancel(struct android_alarm *alarm)
+{
+	for (;;) {
+		int ret = android_alarm_try_to_cancel(alarm);
+		if (ret >= 0)
+			return ret;
+		cpu_relax();
+	}
+}
+
+/**
+ * alarm_set_rtc - set the kernel and rtc walltime
+ * @new_time:	timespec value containing the new time
+ */
+int android_alarm_set_rtc(struct timespec new_time)
+{
+	int i;
+	int ret;
+	unsigned long flags;
+	struct rtc_time rtc_new_rtc_time;
+	struct timespec tmp_time;
+
+	rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time);
+
+	pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n",
+		new_time.tv_sec, new_time.tv_nsec,
+		rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min,
+		rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1,
+		rtc_new_rtc_time.tm_mday,
+		rtc_new_rtc_time.tm_year + 1900);
+
+	mutex_lock(&alarm_setrtc_mutex);
+	spin_lock_irqsave(&alarm_slock, flags);
+	wake_lock(&alarm_rtc_wake_lock);
+	getnstimeofday(&tmp_time);
+	for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
+		hrtimer_try_to_cancel(&alarms[i].timer);
+		alarms[i].stopped = true;
+		alarms[i].stopped_time = timespec_to_ktime(tmp_time);
+	}
+	alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
+		alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
+		ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta,
+			timespec_to_ktime(timespec_sub(tmp_time, new_time)));
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	ret = do_settimeofday(&new_time);
+	spin_lock_irqsave(&alarm_slock, flags);
+	for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
+		alarms[i].stopped = false;
+		update_timer_locked(&alarms[i], false);
+	}
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	if (ret < 0) {
+		pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n");
+		goto err;
+	}
+	if (!alarm_rtc_dev) {
+		pr_alarm(ERROR,
+			"alarm_set_rtc: no RTC, time will be lost on reboot\n");
+		goto err;
+	}
+	ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);
+	if (ret < 0)
+		pr_alarm(ERROR, "alarm_set_rtc: "
+			"Failed to set RTC, time will be lost on reboot\n");
+err:
+	wake_unlock(&alarm_rtc_wake_lock);
+	mutex_unlock(&alarm_setrtc_mutex);
+	return ret;
+}
+
+/**
+ * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+ktime_t alarm_get_elapsed_realtime(void)
+{
+	ktime_t now;
+	unsigned long flags;
+	struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME];
+
+	spin_lock_irqsave(&alarm_slock, flags);
+	now = base->stopped ? base->stopped_time : ktime_get_real();
+	now = ktime_sub(now, base->delta);
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	return now;
+}
+
+static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer)
+{
+	struct alarm_queue *base;
+	struct android_alarm *alarm;
+	unsigned long flags;
+	ktime_t now;
+
+	spin_lock_irqsave(&alarm_slock, flags);
+
+	base = container_of(timer, struct alarm_queue, timer);
+	now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer);
+	now = ktime_sub(now, base->delta);
+
+	pr_alarm(INT, "alarm_timer_triggered type %ld at %lld\n",
+		base - alarms, ktime_to_ns(now));
+
+	while (base->first) {
+		alarm = container_of(base->first, struct android_alarm, node);
+		if (alarm->softexpires.tv64 > now.tv64) {
+			pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n",
+				alarm->function, ktime_to_ns(alarm->expires),
+				ktime_to_ns(alarm->softexpires));
+			break;
+		}
+		base->first = rb_next(&alarm->node);
+		rb_erase(&alarm->node, &base->alarms);
+		RB_CLEAR_NODE(&alarm->node);
+		pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n",
+			alarm->type, alarm->function,
+			ktime_to_ns(alarm->expires),
+			ktime_to_ns(alarm->softexpires));
+		spin_unlock_irqrestore(&alarm_slock, flags);
+		alarm->function(alarm);
+		spin_lock_irqsave(&alarm_slock, flags);
+	}
+	if (!base->first)
+		pr_alarm(FLOW, "no more alarms of type %ld\n", base - alarms);
+	update_timer_locked(base, true);
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	return HRTIMER_NORESTART;
+}
+
+static void alarm_triggered_func(void *p)
+{
+	struct rtc_device *rtc = alarm_rtc_dev;
+	if (!(rtc->irq_data & RTC_AF))
+		return;
+	pr_alarm(INT, "rtc alarm triggered\n");
+	wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ);
+}
+
+static int alarm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	int                 err = 0;
+	unsigned long       flags;
+	struct rtc_wkalrm   rtc_alarm;
+	struct rtc_time     rtc_current_rtc_time;
+	unsigned long       rtc_current_time;
+	unsigned long       rtc_alarm_time;
+	struct timespec     rtc_delta;
+	struct timespec     wall_time;
+	struct alarm_queue *wakeup_queue = NULL;
+	struct alarm_queue *tmp_queue = NULL;
+
+	pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event);
+
+	spin_lock_irqsave(&alarm_slock, flags);
+	suspended = true;
+	spin_unlock_irqrestore(&alarm_slock, flags);
+
+	hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer);
+	hrtimer_cancel(&alarms[
+			ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer);
+
+	tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP];
+	if (tmp_queue->first)
+		wakeup_queue = tmp_queue;
+	tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP];
+	if (tmp_queue->first && (!wakeup_queue ||
+				hrtimer_get_expires(&tmp_queue->timer).tv64 <
+				hrtimer_get_expires(&wakeup_queue->timer).tv64))
+		wakeup_queue = tmp_queue;
+	if (wakeup_queue) {
+		rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time);
+		getnstimeofday(&wall_time);
+		rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time);
+		set_normalized_timespec(&rtc_delta,
+					wall_time.tv_sec - rtc_current_time,
+					wall_time.tv_nsec);
+
+		rtc_alarm_time = timespec_sub(ktime_to_timespec(
+			hrtimer_get_expires(&wakeup_queue->timer)),
+			rtc_delta).tv_sec;
+
+		rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time);
+		rtc_alarm.enabled = 1;
+		rtc_set_alarm(alarm_rtc_dev, &rtc_alarm);
+		rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time);
+		rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time);
+		pr_alarm(SUSPEND,
+			"rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n",
+			rtc_alarm_time, rtc_current_time,
+			rtc_delta.tv_sec, rtc_delta.tv_nsec);
+		if (rtc_current_time + 1 >= rtc_alarm_time) {
+			pr_alarm(SUSPEND, "alarm about to go off\n");
+			memset(&rtc_alarm, 0, sizeof(rtc_alarm));
+			rtc_alarm.enabled = 0;
+			rtc_set_alarm(alarm_rtc_dev, &rtc_alarm);
+
+			spin_lock_irqsave(&alarm_slock, flags);
+			suspended = false;
+			wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ);
+			update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP],
+									false);
+			update_timer_locked(&alarms[
+				ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false);
+			err = -EBUSY;
+			spin_unlock_irqrestore(&alarm_slock, flags);
+		}
+	}
+	return err;
+}
+
+static int alarm_resume(struct platform_device *pdev)
+{
+	struct rtc_wkalrm alarm;
+	unsigned long       flags;
+
+	pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev);
+
+	memset(&alarm, 0, sizeof(alarm));
+	alarm.enabled = 0;
+	rtc_set_alarm(alarm_rtc_dev, &alarm);
+
+	spin_lock_irqsave(&alarm_slock, flags);
+	suspended = false;
+	update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false);
+	update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP],
+									false);
+	spin_unlock_irqrestore(&alarm_slock, flags);
+
+	return 0;
+}
+
+static struct rtc_task alarm_rtc_task = {
+	.func = alarm_triggered_func
+};
+
+static int rtc_alarm_add_device(struct device *dev,
+				struct class_interface *class_intf)
+{
+	int err;
+	struct rtc_device *rtc = to_rtc_device(dev);
+
+	mutex_lock(&alarm_setrtc_mutex);
+
+	if (alarm_rtc_dev) {
+		err = -EBUSY;
+		goto err1;
+	}
+
+	alarm_platform_dev =
+		platform_device_register_simple("alarm", -1, NULL, 0);
+	if (IS_ERR(alarm_platform_dev)) {
+		err = PTR_ERR(alarm_platform_dev);
+		goto err2;
+	}
+	err = rtc_irq_register(rtc, &alarm_rtc_task);
+	if (err)
+		goto err3;
+	alarm_rtc_dev = rtc;
+	pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name);
+	mutex_unlock(&alarm_setrtc_mutex);
+
+	return 0;
+
+err3:
+	platform_device_unregister(alarm_platform_dev);
+err2:
+err1:
+	mutex_unlock(&alarm_setrtc_mutex);
+	return err;
+}
+
+static void rtc_alarm_remove_device(struct device *dev,
+				    struct class_interface *class_intf)
+{
+	if (dev == &alarm_rtc_dev->dev) {
+		pr_alarm(INIT_STATUS, "lost rtc device for alarms");
+		rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task);
+		platform_device_unregister(alarm_platform_dev);
+		alarm_rtc_dev = NULL;
+	}
+}
+
+static struct class_interface rtc_alarm_interface = {
+	.add_dev = &rtc_alarm_add_device,
+	.remove_dev = &rtc_alarm_remove_device,
+};
+
+static struct platform_driver alarm_driver = {
+	.suspend = alarm_suspend,
+	.resume = alarm_resume,
+	.driver = {
+		.name = "alarm"
+	}
+};
+
+static int __init alarm_late_init(void)
+{
+	unsigned long   flags;
+	struct timespec tmp_time, system_time;
+
+	/* this needs to run after the rtc is read at boot */
+	spin_lock_irqsave(&alarm_slock, flags);
+	/* We read the current rtc and system time so we can later calulate
+	 * elasped realtime to be (boot_systemtime + rtc - boot_rtc) ==
+	 * (rtc - (boot_rtc - boot_systemtime))
+	 */
+	getnstimeofday(&tmp_time);
+	ktime_get_ts(&system_time);
+	alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
+		alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
+			timespec_to_ktime(timespec_sub(tmp_time, system_time));
+
+	spin_unlock_irqrestore(&alarm_slock, flags);
+	return 0;
+}
+
+static int __init alarm_driver_init(void)
+{
+	int err;
+	int i;
+
+	for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) {
+		hrtimer_init(&alarms[i].timer,
+				CLOCK_REALTIME, HRTIMER_MODE_ABS);
+		alarms[i].timer.function = alarm_timer_triggered;
+	}
+	hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer,
+		     CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered;
+	err = platform_driver_register(&alarm_driver);
+	if (err < 0)
+		goto err1;
+	wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc");
+	rtc_alarm_interface.class = rtc_class;
+	err = class_interface_register(&rtc_alarm_interface);
+	if (err < 0)
+		goto err2;
+
+	return 0;
+
+err2:
+	wake_lock_destroy(&alarm_rtc_wake_lock);
+	platform_driver_unregister(&alarm_driver);
+err1:
+	return err;
+}
+
+static void  __exit alarm_exit(void)
+{
+	class_interface_unregister(&rtc_alarm_interface);
+	wake_lock_destroy(&alarm_rtc_wake_lock);
+	platform_driver_unregister(&alarm_driver);
+}
+
+late_initcall(alarm_late_init);
+module_init(alarm_driver_init);
+module_exit(alarm_exit);
+
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
new file mode 100644
index 0000000..6eecbde
--- /dev/null
+++ b/drivers/staging/android/android_alarm.h
@@ -0,0 +1,121 @@
+/* include/linux/android_alarm.h
+ *
+ * Copyright (C) 2006-2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _LINUX_ANDROID_ALARM_H
+#define _LINUX_ANDROID_ALARM_H
+
+#include <linux/ioctl.h>
+#include <linux/time.h>
+
+enum android_alarm_type {
+	/* return code bit numbers or set alarm arg */
+	ANDROID_ALARM_RTC_WAKEUP,
+	ANDROID_ALARM_RTC,
+	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+	ANDROID_ALARM_ELAPSED_REALTIME,
+	ANDROID_ALARM_SYSTEMTIME,
+
+	ANDROID_ALARM_TYPE_COUNT,
+
+	/* return code bit numbers */
+	/* ANDROID_ALARM_TIME_CHANGE = 16 */
+};
+
+#ifdef __KERNEL__
+
+#include <linux/ktime.h>
+#include <linux/rbtree.h>
+
+/*
+ * The alarm interface is similar to the hrtimer interface but adds support
+ * for wakeup from suspend. It also adds an elapsed realtime clock that can
+ * be used for periodic timers that need to keep runing while the system is
+ * suspended and not be disrupted when the wall time is set.
+ */
+
+/**
+ * struct alarm - the basic alarm structure
+ * @node:	red black tree node for time ordered insertion
+ * @type:	alarm type. rtc/elapsed-realtime/systemtime, wakeup/non-wakeup.
+ * @softexpires: the absolute earliest expiry time of the alarm.
+ * @expires:	the absolute expiry time.
+ * @function:	alarm expiry callback function
+ *
+ * The alarm structure must be initialized by alarm_init()
+ *
+ */
+
+struct android_alarm {
+	struct rb_node		node;
+	enum android_alarm_type type;
+	ktime_t			softexpires;
+	ktime_t			expires;
+	void			(*function)(struct android_alarm *);
+};
+
+void android_alarm_init(struct android_alarm *alarm,
+	enum android_alarm_type type, void (*function)(struct android_alarm *));
+void android_alarm_start_range(struct android_alarm *alarm, ktime_t start,
+								ktime_t end);
+int android_alarm_try_to_cancel(struct android_alarm *alarm);
+int android_alarm_cancel(struct android_alarm *alarm);
+ktime_t alarm_get_elapsed_realtime(void);
+
+/* set rtc while preserving elapsed realtime */
+int android_alarm_set_rtc(const struct timespec ts);
+
+#ifdef CONFIG_ANDROID_ALARM_OLDDRV_COMPAT
+/*
+ * Some older drivers depend on the old API,
+ * so provide compatability macros for now.
+ */
+#define alarm android_alarm
+#define alarm_init(x, y, z) android_alarm_init(x, y, z)
+#define alarm_start_range(x, y, z) android_alarm_start_range(x, y, z)
+#define alarm_try_to_cancel(x) android_alarm_try_to_cancel(x)
+#define alarm_cancel(x) android_alarm_cancel(x)
+#define alarm_set_rtc(x) android_alarm_set_rtc(x)
+#endif
+
+
+#endif
+
+enum android_alarm_return_flags {
+	ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
+	ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
+	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
+				1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+	ANDROID_ALARM_ELAPSED_REALTIME_MASK =
+				1U << ANDROID_ALARM_ELAPSED_REALTIME,
+	ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
+	ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
+};
+
+/* Disable alarm */
+#define ANDROID_ALARM_CLEAR(type)           _IO('a', 0 | ((type) << 4))
+
+/* Ack last alarm and wait for next */
+#define ANDROID_ALARM_WAIT                  _IO('a', 1)
+
+#define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size)
+/* Set alarm */
+#define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)
+#define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec)
+#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)
+#define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)
+#define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))
+#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4)
+
+#endif
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 99052bf..9f1f27e 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -315,7 +315,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
 	get_file(asma->file);
 
 	/*
-	 * XXX - Reworked to use shmem_zero_setup() instead of 
+	 * XXX - Reworked to use shmem_zero_setup() instead of
 	 * shmem_set_file while we're in staging. -jstultz
 	 */
 	if (vma->vm_flags & VM_SHARED) {
@@ -680,7 +680,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	return ret;
 }
 
-static struct file_operations ashmem_fops = {
+static const struct file_operations ashmem_fops = {
 	.owner = THIS_MODULE,
 	.open = ashmem_open,
 	.release = ashmem_release,
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index f0b7e66..094e18c 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -258,7 +258,7 @@ struct binder_ref {
 };
 
 struct binder_buffer {
-	struct list_head entry; /* free and allocated entries by addesss */
+	struct list_head entry; /* free and allocated entries by address */
 	struct rb_node rb_node; /* free entry by size or allocated entry */
 				/* by address */
 	unsigned free:1;
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index ffc2d04..0d2367f 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -60,7 +60,11 @@ struct logger_reader {
 };
 
 /* logger_offset - returns index 'n' into the log via (optimized) modulus */
-#define logger_offset(n)	((n) & (log->size - 1))
+size_t logger_offset(struct logger_log *log, size_t n)
+{
+	return n & (log->size-1);
+}
+
 
 /*
  * file_get_log - Given a file structure, return the associated log
@@ -89,20 +93,24 @@ static inline struct logger_log *file_get_log(struct file *file)
  * get_entry_len - Grabs the length of the payload of the next entry starting
  * from 'off'.
  *
+ * An entry length is 2 bytes (16 bits) in host endian order.
+ * In the log, the length does not include the size of the log entry structure.
+ * This function returns the size including the log entry structure.
+ *
  * Caller needs to hold log->mutex.
  */
 static __u32 get_entry_len(struct logger_log *log, size_t off)
 {
 	__u16 val;
 
-	switch (log->size - off) {
-	case 1:
-		memcpy(&val, log->buffer + off, 1);
-		memcpy(((char *) &val) + 1, log->buffer, 1);
-		break;
-	default:
-		memcpy(&val, log->buffer + off, 2);
-	}
+	/* copy 2 bytes from buffer, in memcpy order, */
+	/* handling possible wrap at end of buffer */
+
+	((__u8 *)&val)[0] = log->buffer[off];
+	if (likely(off+1 < log->size))
+		((__u8 *)&val)[1] = log->buffer[off+1];
+	else
+		((__u8 *)&val)[1] = log->buffer[0];
 
 	return sizeof(struct logger_entry) + val;
 }
@@ -137,7 +145,7 @@ static ssize_t do_read_log_to_user(struct logger_log *log,
 		if (copy_to_user(buf + len, log->buffer, count - len))
 			return -EFAULT;
 
-	reader->r_off = logger_offset(reader->r_off + count);
+	reader->r_off = logger_offset(log, reader->r_off + count);
 
 	return count;
 }
@@ -164,9 +172,10 @@ static ssize_t logger_read(struct file *file, char __user *buf,
 
 start:
 	while (1) {
+		mutex_lock(&log->mutex);
+
 		prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE);
 
-		mutex_lock(&log->mutex);
 		ret = (log->w_off == reader->r_off);
 		mutex_unlock(&log->mutex);
 		if (!ret)
@@ -225,7 +234,7 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
 
 	do {
 		size_t nr = get_entry_len(log, off);
-		off = logger_offset(off + nr);
+		off = logger_offset(log, off + nr);
 		count += nr;
 	} while (count < len);
 
@@ -233,16 +242,28 @@ static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
 }
 
 /*
- * clock_interval - is a < c < b in mod-space? Put another way, does the line
- * from a to b cross c?
+ * is_between - is a < c < b, accounting for wrapping of a, b, and c
+ *    positions in the buffer
+ *
+ * That is, if a<b, check for c between a and b
+ * and if a>b, check for c outside (not between) a and b
+ *
+ * |------- a xxxxxxxx b --------|
+ *               c^
+ *
+ * |xxxxx b --------- a xxxxxxxxx|
+ *    c^
+ *  or                    c^
  */
-static inline int clock_interval(size_t a, size_t b, size_t c)
+static inline int is_between(size_t a, size_t b, size_t c)
 {
-	if (b < a) {
-		if (a < c || b >= c)
+	if (a < b) {
+		/* is c between a and b? */
+		if (a < c && c <= b)
 			return 1;
 	} else {
-		if (a < c && b >= c)
+		/* is c outside of b through a? */
+		if (c <= b || a < c)
 			return 1;
 	}
 
@@ -260,14 +281,14 @@ static inline int clock_interval(size_t a, size_t b, size_t c)
 static void fix_up_readers(struct logger_log *log, size_t len)
 {
 	size_t old = log->w_off;
-	size_t new = logger_offset(old + len);
+	size_t new = logger_offset(log, old + len);
 	struct logger_reader *reader;
 
-	if (clock_interval(old, new, log->head))
+	if (is_between(old, new, log->head))
 		log->head = get_next_entry(log, log->head, len);
 
 	list_for_each_entry(reader, &log->readers, list)
-		if (clock_interval(old, new, reader->r_off))
+		if (is_between(old, new, reader->r_off))
 			reader->r_off = get_next_entry(log, reader->r_off, len);
 }
 
@@ -286,7 +307,7 @@ static void do_write_log(struct logger_log *log, const void *buf, size_t count)
 	if (count != len)
 		memcpy(log->buffer, buf + len, count - len);
 
-	log->w_off = logger_offset(log->w_off + count);
+	log->w_off = logger_offset(log, log->w_off + count);
 
 }
 
@@ -309,9 +330,15 @@ static ssize_t do_write_log_from_user(struct logger_log *log,
 
 	if (count != len)
 		if (copy_from_user(log->buffer, buf + len, count - len))
+			/*
+			 * Note that by not updating w_off, this abandons the
+			 * portion of the new entry that *was* successfully
+			 * copied, just above.  This is intentional to avoid
+			 * message corruption from missing fragments.
+			 */
 			return -EFAULT;
 
-	log->w_off = logger_offset(log->w_off + count);
+	log->w_off = logger_offset(log, log->w_off + count);
 
 	return count;
 }
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index efc7dc1..cf4c6f7 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -1,16 +1,17 @@
 /* drivers/misc/lowmemorykiller.c
  *
  * The lowmemorykiller driver lets user-space specify a set of memory thresholds
- * where processes with a range of oom_adj values will get killed. Specify the
- * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
- * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
- * files take a comma separated list of numbers in ascending order.
+ * where processes with a range of oom_score_adj values will get killed. Specify
+ * the minimum oom_score_adj values in
+ * /sys/module/lowmemorykiller/parameters/adj and the number of free pages in
+ * /sys/module/lowmemorykiller/parameters/minfree. Both files take a comma
+ * separated list of numbers in ascending order.
  *
  * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
  * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill
- * processes with a oom_adj value of 8 or higher when the free memory drops
- * below 4096 pages and kill processes with a oom_adj value of 0 or higher
- * when the free memory drops below 1024 pages.
+ * processes with a oom_score_adj value of 8 or higher when the free memory
+ * drops below 4096 pages and kill processes with a oom_score_adj value of 0 or
+ * higher when the free memory drops below 1024 pages.
  *
  * The driver considers memory used for caches to be free, but if a large
  * percentage of the cached memory is locked this can be very inaccurate
@@ -34,6 +35,7 @@
 #include <linux/mm.h>
 #include <linux/oom.h>
 #include <linux/sched.h>
+#include <linux/rcupdate.h>
 #include <linux/profile.h>
 #include <linux/notifier.h>
 
@@ -82,14 +84,14 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data)
 
 static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 {
-	struct task_struct *p;
+	struct task_struct *tsk;
 	struct task_struct *selected = NULL;
 	int rem = 0;
 	int tasksize;
 	int i;
-	int min_adj = OOM_ADJUST_MAX + 1;
+	int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
 	int selected_tasksize = 0;
-	int selected_oom_adj;
+	int selected_oom_score_adj;
 	int array_size = ARRAY_SIZE(lowmem_adj);
 	int other_free = global_page_state(NR_FREE_PAGES);
 	int other_file = global_page_state(NR_FILE_PAGES) -
@@ -115,64 +117,63 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 	for (i = 0; i < array_size; i++) {
 		if (other_free < lowmem_minfree[i] &&
 		    other_file < lowmem_minfree[i]) {
-			min_adj = lowmem_adj[i];
+			min_score_adj = lowmem_adj[i];
 			break;
 		}
 	}
 	if (sc->nr_to_scan > 0)
 		lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n",
 				sc->nr_to_scan, sc->gfp_mask, other_free,
-				other_file, min_adj);
+				other_file, min_score_adj);
 	rem = global_page_state(NR_ACTIVE_ANON) +
 		global_page_state(NR_ACTIVE_FILE) +
 		global_page_state(NR_INACTIVE_ANON) +
 		global_page_state(NR_INACTIVE_FILE);
-	if (sc->nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) {
+	if (sc->nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) {
 		lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n",
 			     sc->nr_to_scan, sc->gfp_mask, rem);
 		return rem;
 	}
-	selected_oom_adj = min_adj;
-
-	read_lock(&tasklist_lock);
-	for_each_process(p) {
-		struct mm_struct *mm;
-		struct signal_struct *sig;
-		int oom_adj;
-
-		task_lock(p);
-		mm = p->mm;
-		sig = p->signal;
-		if (!mm || !sig) {
-			task_unlock(p);
+	selected_oom_score_adj = min_score_adj;
+
+	rcu_read_lock();
+	for_each_process(tsk) {
+		struct task_struct *p;
+		int oom_score_adj;
+
+		if (tsk->flags & PF_KTHREAD)
 			continue;
-		}
-		oom_adj = sig->oom_adj;
-		if (oom_adj < min_adj) {
+
+		p = find_lock_task_mm(tsk);
+		if (!p)
+			continue;
+
+		oom_score_adj = p->signal->oom_score_adj;
+		if (oom_score_adj < min_score_adj) {
 			task_unlock(p);
 			continue;
 		}
-		tasksize = get_mm_rss(mm);
+		tasksize = get_mm_rss(p->mm);
 		task_unlock(p);
 		if (tasksize <= 0)
 			continue;
 		if (selected) {
-			if (oom_adj < selected_oom_adj)
+			if (oom_score_adj < selected_oom_score_adj)
 				continue;
-			if (oom_adj == selected_oom_adj &&
+			if (oom_score_adj == selected_oom_score_adj &&
 			    tasksize <= selected_tasksize)
 				continue;
 		}
 		selected = p;
 		selected_tasksize = tasksize;
-		selected_oom_adj = oom_adj;
+		selected_oom_score_adj = oom_score_adj;
 		lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n",
-			     p->pid, p->comm, oom_adj, tasksize);
+			     p->pid, p->comm, oom_score_adj, tasksize);
 	}
 	if (selected) {
 		lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n",
 			     selected->pid, selected->comm,
-			     selected_oom_adj, selected_tasksize);
+			     selected_oom_score_adj, selected_tasksize);
 		/*
 		 * If CONFIG_PROFILING is off, then task_handoff_register()
 		 * is a nop. In that case we don't want to stall the killer
@@ -183,12 +184,12 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 		lowmem_deathpending_timeout = jiffies + HZ;
 		task_handoff_register(&task_nb);
 #endif
-		force_sig(SIGKILL, selected);
+		send_sig(SIGKILL, selected, 0);
 		rem -= selected_tasksize;
 	}
 	lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
 		     sc->nr_to_scan, sc->gfp_mask, rem);
-	read_unlock(&tasklist_lock);
+	rcu_read_unlock();
 	return rem;
 }
 
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 6d4d679..fabd398 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -351,7 +351,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
 		       "%lx\n", res, pdev->num_resources, res ? res->flags : 0);
 		return -ENXIO;
 	}
-	buffer_size = res->end - res->start + 1;
+	buffer_size = resource_size(res);
 	start = res->start;
 	printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
 	       start, buffer_size);
@@ -411,15 +411,14 @@ static int __init ram_console_late_init(void)
 	if (ram_console_old_log == NULL)
 		return 0;
 #ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT
-	ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL);
+	ram_console_old_log = kmemdup(ram_console_old_log_init_buffer,
+					ram_console_old_log_size, GFP_KERNEL);
 	if (ram_console_old_log == NULL) {
 		printk(KERN_ERR
 		       "ram_console: failed to allocate buffer for old log\n");
 		ram_console_old_log_size = 0;
 		return 0;
 	}
-	memcpy(ram_console_old_log,
-	       ram_console_old_log_init_buffer, ram_console_old_log_size);
 #endif
 	entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL);
 	if (!entry) {
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index a64481c..bc723ef 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -29,9 +29,9 @@ struct timed_gpio_data {
 	struct timed_output_dev dev;
 	struct hrtimer timer;
 	spinlock_t lock;
-	unsigned 	gpio;
-	int 		max_timeout;
-	u8 		active_low;
+	unsigned gpio;
+	int max_timeout;
+	u8 active_low;
 };
 
 static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer)
diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c
index 179707b..cf30592 100644
--- a/drivers/staging/bcm/Bcmchar.c
+++ b/drivers/staging/bcm/Bcmchar.c
@@ -728,14 +728,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
 		if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
 			return -EINVAL;
 
-		pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
-		if (!pvBuffer)
-			return -ENOMEM;
-
-		if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
-			kfree(pvBuffer);
-			return -EFAULT;
-		}
+		pvBuffer = memdup_user(IoBuffer.InputBuffer,
+				       IoBuffer.InputLength);
+		if (IS_ERR(pvBuffer))
+			return PTR_ERR(pvBuffer);
 
 		down(&Adapter->LowPowerModeSync);
 		Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
@@ -1140,15 +1136,10 @@ cntrlEnd:
 		if (IoBuffer.InputLength < sizeof(ULONG) * 2)
 			return -EINVAL;
 
-		pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
-		if (!pvBuffer)
-			return -ENOMEM;
-
-		/* Get WrmBuffer structure */
-		if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
-			kfree(pvBuffer);
-			return -EFAULT;
-		}
+		pvBuffer = memdup_user(IoBuffer.InputBuffer,
+				       IoBuffer.InputLength);
+		if (IS_ERR(pvBuffer))
+			return PTR_ERR(pvBuffer);
 
 		pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
 
@@ -1302,20 +1293,18 @@ cntrlEnd:
 		/*
 		 * Deny the access if the offset crosses the cal area limit.
 		 */
+		if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
+			return STATUS_FAILURE;
 
-		if ((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) {
+		if (stNVMReadWrite.uiOffset > Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes) {
 			/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */
 			return STATUS_FAILURE;
 		}
 
-		pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
-		if (!pReadData)
-			return -ENOMEM;
-
-		if (copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) {
-			kfree(pReadData);
-			return -EFAULT;
-		}
+		pReadData = memdup_user(stNVMReadWrite.pBuffer,
+					stNVMReadWrite.uiNumBytes);
+		if (IS_ERR(pReadData))
+			return PTR_ERR(pReadData);
 
 		do_gettimeofday(&tv0);
 		if (IOCTL_BCM_NVM_READ == cmd) {
diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c
index c0ee95a..522d005 100644
--- a/drivers/staging/bcm/CmHost.c
+++ b/drivers/staging/bcm/CmHost.c
@@ -1,431 +1,359 @@
 /************************************************************
-*			CMHOST.C
-*	This file contains the routines for handling Connection
-*	Management.
-************************************************************/
+ * CMHOST.C
+ * This file contains the routines for handling Connection
+ * Management.
+ ************************************************************/
 
-//#define CONN_MSG
+/* #define CONN_MSG */
 #include "headers.h"
 
-typedef enum _E_CLASSIFIER_ACTION
-{
+enum E_CLASSIFIER_ACTION {
 	eInvalidClassifierAction,
 	eAddClassifier,
 	eReplaceClassifier,
 	eDeleteClassifier
-}E_CLASSIFIER_ACTION;
+};
 
-static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid);
+static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid);
 
 /************************************************************
-* Function	  -	SearchSfid
-*
-* Description -	This routinue would search QOS queues having
-*				specified SFID as input parameter.
-*
-* Parameters  -	Adapter: Pointer to the Adapter structure
-*			   	uiSfid : Given SFID for matching
-*
-* Returns	  - Queue index for this SFID(If matched)
-				Else Invalid Queue Index(If Not matched)
-************************************************************/
-INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid)
+ * Function - SearchSfid
+ *
+ * Description - This routinue would search QOS queues having
+ *  specified SFID as input parameter.
+ *
+ * Parameters -	Adapter: Pointer to the Adapter structure
+ *  uiSfid : Given SFID for matching
+ *
+ * Returns - Queue index for this SFID(If matched)
+ *  Else Invalid Queue Index(If Not matched)
+ ************************************************************/
+int SearchSfid(PMINI_ADAPTER Adapter, UINT uiSfid)
 {
-	INT 	iIndex=0;
-	for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--)
-		if(Adapter->PackInfo[iIndex].ulSFID==uiSfid)
-			return iIndex;
+	int i;
+
+	for (i = (NO_OF_QUEUES-1); i >= 0; i--)
+		if (Adapter->PackInfo[i].ulSFID == uiSfid)
+			return i;
+
 	return NO_OF_QUEUES+1;
 }
 
 /***************************************************************
-* Function	  -	SearchFreeSfid
-*
-* Description -	This routinue would search Free available SFID.
-*
-* Parameter   -	Adapter: Pointer to the Adapter structure
-*
-* Returns	  - Queue index for the free SFID
-*				Else returns Invalid Index.
-****************************************************************/
-static INT SearchFreeSfid(PMINI_ADAPTER Adapter)
+ * Function -SearchFreeSfid
+ *
+ * Description - This routinue would search Free available SFID.
+ *
+ * Parameter - Adapter: Pointer to the Adapter structure
+ *
+ * Returns - Queue index for the free SFID
+ *  Else returns Invalid Index.
+ ****************************************************************/
+static int SearchFreeSfid(PMINI_ADAPTER Adapter)
 {
-	UINT 	uiIndex=0;
+	int i;
+
+	for (i = 0; i < (NO_OF_QUEUES-1); i++)
+		if (Adapter->PackInfo[i].ulSFID == 0)
+			return i;
 
-	for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++)
-		if(Adapter->PackInfo[uiIndex].ulSFID==0)
-			return uiIndex;
 	return NO_OF_QUEUES+1;
 }
 
 /*
-Function:				SearchClsid
-Description:			This routinue would search Classifier  having specified ClassifierID as input parameter
-Input parameters:		PMINI_ADAPTER Adapter - Adapter Context
-                        unsigned int uiSfid   - The SF in which the classifier is to searched
-						B_UINT16  uiClassifierID - The classifier ID to be searched
-Return:					int :Classifier table index of matching entry
-*/
-
-static int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16  uiClassifierID)
+ * Function: SearchClsid
+ * Description:	This routinue would search Classifier  having specified ClassifierID as input parameter
+ * Input parameters: PMINI_ADAPTER Adapter - Adapter Context
+ *  unsigned int uiSfid   - The SF in which the classifier is to searched
+ *  B_UINT16  uiClassifierID - The classifier ID to be searched
+ * Return: int :Classifier table index of matching entry
+ */
+static int SearchClsid(PMINI_ADAPTER Adapter, ULONG ulSFID, B_UINT16  uiClassifierID)
 {
-	unsigned int uiClassifierIndex = 0;
-	for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
-	{
-		if((Adapter->astClassifierTable[uiClassifierIndex].bUsed) &&
-			(Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex == uiClassifierID)&&
-			(Adapter->astClassifierTable[uiClassifierIndex].ulSFID == ulSFID))
-			return uiClassifierIndex;
+	int i;
+
+	for (i = 0; i < MAX_CLASSIFIERS; i++) {
+		if ((Adapter->astClassifierTable[i].bUsed) &&
+			(Adapter->astClassifierTable[i].uiClassifierRuleIndex == uiClassifierID) &&
+			(Adapter->astClassifierTable[i].ulSFID == ulSFID))
+			return i;
 	}
+
 	return MAX_CLASSIFIERS+1;
 }
 
-/**
-@ingroup ctrl_pkt_functions
-This routinue would search Free available Classifier entry in classifier table.
-@return free Classifier Entry index in classifier table for specified SF
-*/
-static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/
-						)
+/*
+ * @ingroup ctrl_pkt_functions
+ * This routinue would search Free available Classifier entry in classifier table.
+ * @return free Classifier Entry index in classifier table for specified SF
+ */
+static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/)
 {
-	unsigned int uiClassifierIndex = 0;
-	for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
-	{
-		if(!Adapter->astClassifierTable[uiClassifierIndex].bUsed)
-			return uiClassifierIndex;
+	int i;
+
+	for (i = 0; i < MAX_CLASSIFIERS; i++) {
+		if (!Adapter->astClassifierTable[i].bUsed)
+			return i;
 	}
+
 	return MAX_CLASSIFIERS+1;
 }
 
 static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
 {
-	//deleting all the packet held in the SF
-	flush_queue(Adapter,uiSearchRuleIndex);
+	/* deleting all the packet held in the SF */
+	flush_queue(Adapter, uiSearchRuleIndex);
 
-	//Deleting the all classifiers for this SF
-	DeleteAllClassifiersForSF(Adapter,uiSearchRuleIndex);
+	/* Deleting the all classifiers for this SF */
+	DeleteAllClassifiersForSF(Adapter, uiSearchRuleIndex);
 
-	//Resetting only MIBS related entries in the SF
+	/* Resetting only MIBS related entries in the SF */
 	memset((PVOID)&Adapter->PackInfo[uiSearchRuleIndex], 0, sizeof(S_MIBS_SERVICEFLOW_TABLE));
 }
 
 static inline VOID
-CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry ,
-			B_UINT8 u8IpAddressLen , B_UINT8 *pu8IpAddressMaskSrc ,
-			BOOLEAN bIpVersion6 , E_IPADDR_CONTEXT eIpAddrContext)
+CopyIpAddrToClassifier(S_CLASSIFIER_RULE *pstClassifierEntry,
+		B_UINT8 u8IpAddressLen, B_UINT8 *pu8IpAddressMaskSrc,
+		BOOLEAN bIpVersion6, E_IPADDR_CONTEXT eIpAddrContext)
 {
-	UINT	ucLoopIndex=0;
-	UINT    nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS;
-	UCHAR   *ptrClassifierIpAddress = NULL;
-	UCHAR   *ptrClassifierIpMask = NULL;
-    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+	int i = 0;
+	UINT nSizeOfIPAddressInBytes = IP_LENGTH_OF_ADDRESS;
+	UCHAR *ptrClassifierIpAddress = NULL;
+	UCHAR *ptrClassifierIpMask = NULL;
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
 
-	if(bIpVersion6)
-	{
+	if (bIpVersion6)
 		nSizeOfIPAddressInBytes = IPV6_ADDRESS_SIZEINBYTES;
-	}
-	//Destination Ip Address
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Address Range Length:0x%X ",
-				u8IpAddressLen);
-	if((bIpVersion6?(IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2):
-			(TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen)
-	{
+
+	/* Destination Ip Address */
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Address Range Length:0x%X ", u8IpAddressLen);
+	if ((bIpVersion6 ? (IPV6_ADDRESS_SIZEINBYTES * MAX_IP_RANGE_LENGTH * 2) :
+			(TOTAL_MASKED_ADDRESS_IN_BYTES)) >= u8IpAddressLen) {
 		/*
-		//checking both the mask and address togethor in Classification.
-		//So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2
-		//(nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask)
-		*/
-		if(eIpAddrContext == eDestIpAddress)
-		{
-			pstClassifierEntry->ucIPDestinationAddressLength =
-					u8IpAddressLen/(nSizeOfIPAddressInBytes * 2);
-			if(bIpVersion6)
-			{
-				ptrClassifierIpAddress =
-					pstClassifierEntry->stDestIpAddress.ucIpv6Address;
-				ptrClassifierIpMask =
-					pstClassifierEntry->stDestIpAddress.ucIpv6Mask;
-			}
-			else
-			{
-				ptrClassifierIpAddress =
-					pstClassifierEntry->stDestIpAddress.ucIpv4Address;
-				ptrClassifierIpMask =
-					pstClassifierEntry->stDestIpAddress.ucIpv4Mask;
-			}
-		}
-		else if(eIpAddrContext == eSrcIpAddress)
-		{
-			pstClassifierEntry->ucIPSourceAddressLength =
-					u8IpAddressLen/(nSizeOfIPAddressInBytes * 2);
-			if(bIpVersion6)
-			{
-				ptrClassifierIpAddress =
-					pstClassifierEntry->stSrcIpAddress.ucIpv6Address;
-				ptrClassifierIpMask =
-					pstClassifierEntry->stSrcIpAddress.ucIpv6Mask;
+		 * checking both the mask and address togethor in Classification.
+		 * So length will be : TotalLengthInBytes/nSizeOfIPAddressInBytes * 2
+		 * (nSizeOfIPAddressInBytes for address and nSizeOfIPAddressInBytes for mask)
+		 */
+		if (eIpAddrContext == eDestIpAddress) {
+			pstClassifierEntry->ucIPDestinationAddressLength = u8IpAddressLen/(nSizeOfIPAddressInBytes * 2);
+			if (bIpVersion6) {
+				ptrClassifierIpAddress = pstClassifierEntry->stDestIpAddress.ucIpv6Address;
+				ptrClassifierIpMask = pstClassifierEntry->stDestIpAddress.ucIpv6Mask;
+			} else {
+				ptrClassifierIpAddress = pstClassifierEntry->stDestIpAddress.ucIpv4Address;
+				ptrClassifierIpMask = pstClassifierEntry->stDestIpAddress.ucIpv4Mask;
 			}
-			else
-			{
-				ptrClassifierIpAddress =
-					pstClassifierEntry->stSrcIpAddress.ucIpv4Address;
-				ptrClassifierIpMask =
-					pstClassifierEntry->stSrcIpAddress.ucIpv4Mask;
+		} else if (eIpAddrContext == eSrcIpAddress) {
+			pstClassifierEntry->ucIPSourceAddressLength = u8IpAddressLen/(nSizeOfIPAddressInBytes * 2);
+			if (bIpVersion6) {
+				ptrClassifierIpAddress = pstClassifierEntry->stSrcIpAddress.ucIpv6Address;
+				ptrClassifierIpMask = pstClassifierEntry->stSrcIpAddress.ucIpv6Mask;
+			} else {
+				ptrClassifierIpAddress = pstClassifierEntry->stSrcIpAddress.ucIpv4Address;
+				ptrClassifierIpMask = pstClassifierEntry->stSrcIpAddress.ucIpv4Mask;
 			}
 		}
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Address Length:0x%X \n",
-				pstClassifierEntry->ucIPDestinationAddressLength);
-		while((u8IpAddressLen>= nSizeOfIPAddressInBytes) &&
-				(ucLoopIndex < MAX_IP_RANGE_LENGTH))
-		{
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Address Length:0x%X\n", pstClassifierEntry->ucIPDestinationAddressLength);
+		while ((u8IpAddressLen >= nSizeOfIPAddressInBytes) && (i < MAX_IP_RANGE_LENGTH)) {
 			memcpy(ptrClassifierIpAddress +
-				(ucLoopIndex * nSizeOfIPAddressInBytes),
-				(pu8IpAddressMaskSrc+(ucLoopIndex*nSizeOfIPAddressInBytes*2)),
+				(i * nSizeOfIPAddressInBytes),
+				(pu8IpAddressMaskSrc+(i*nSizeOfIPAddressInBytes*2)),
 				nSizeOfIPAddressInBytes);
-			if(!bIpVersion6)
-			{
-				if(eIpAddrContext == eSrcIpAddress)
-				{
-					pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]=
-						ntohl(pstClassifierEntry->stSrcIpAddress.
-								ulIpv4Addr[ucLoopIndex]);
-					BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[ucLoopIndex]);
-				}
-				else if(eIpAddrContext == eDestIpAddress)
-				{
-					pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]=						ntohl(pstClassifierEntry->stDestIpAddress.
-								ulIpv4Addr[ucLoopIndex]);
-					BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Addr[ucLoopIndex]);
+
+			if (!bIpVersion6) {
+				if (eIpAddrContext == eSrcIpAddress) {
+					pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[i] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[i]);
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Src Ip Address:0x%luX ",
+							pstClassifierEntry->stSrcIpAddress.ulIpv4Addr[i]);
+				} else if (eIpAddrContext == eDestIpAddress) {
+					pstClassifierEntry->stDestIpAddress.ulIpv4Addr[i] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Addr[i]);
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dest Ip Address:0x%luX ",
+							pstClassifierEntry->stDestIpAddress.ulIpv4Addr[i]);
 				}
 			}
-			u8IpAddressLen-=nSizeOfIPAddressInBytes;
-			if(u8IpAddressLen >= nSizeOfIPAddressInBytes)
-			{
+			u8IpAddressLen -= nSizeOfIPAddressInBytes;
+			if (u8IpAddressLen >= nSizeOfIPAddressInBytes) {
 				memcpy(ptrClassifierIpMask +
-					(ucLoopIndex * nSizeOfIPAddressInBytes),
+					(i * nSizeOfIPAddressInBytes),
 					(pu8IpAddressMaskSrc+nSizeOfIPAddressInBytes +
-					(ucLoopIndex*nSizeOfIPAddressInBytes*2)),
+						(i*nSizeOfIPAddressInBytes*2)),
 					nSizeOfIPAddressInBytes);
-				if(!bIpVersion6)
-				{
-					if(eIpAddrContext == eSrcIpAddress)
-					{
-						pstClassifierEntry->stSrcIpAddress.
-											ulIpv4Mask[ucLoopIndex]=
-								ntohl(pstClassifierEntry->stSrcIpAddress.
-											ulIpv4Mask[ucLoopIndex]);
-						BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Src Ip Mask Address:0x%luX ",pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[ucLoopIndex]);
-					}
-					else if(eIpAddrContext == eDestIpAddress)
-					{
-						pstClassifierEntry->stDestIpAddress.
-										ulIpv4Mask[ucLoopIndex] =
-									ntohl(pstClassifierEntry->stDestIpAddress.
-											ulIpv4Mask[ucLoopIndex]);
-						BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Dest Ip Mask Address:0x%luX ",pstClassifierEntry->stDestIpAddress.ulIpv4Mask[ucLoopIndex]);
+
+				if (!bIpVersion6) {
+					if (eIpAddrContext == eSrcIpAddress) {
+						pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[i] =
+							ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[i]);
+						BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Src Ip Mask Address:0x%luX ",
+								pstClassifierEntry->stSrcIpAddress.ulIpv4Mask[i]);
+					} else if (eIpAddrContext == eDestIpAddress) {
+						pstClassifierEntry->stDestIpAddress.ulIpv4Mask[i] =
+							ntohl(pstClassifierEntry->stDestIpAddress.ulIpv4Mask[i]);
+						BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dest Ip Mask Address:0x%luX ",
+								pstClassifierEntry->stDestIpAddress.ulIpv4Mask[i]);
 					}
 				}
-				u8IpAddressLen-=nSizeOfIPAddressInBytes;
-			}
-			if(0==u8IpAddressLen)
-			{
-				pstClassifierEntry->bDestIpValid=TRUE;
+				u8IpAddressLen -= nSizeOfIPAddressInBytes;
 			}
-			ucLoopIndex++;
+			if (u8IpAddressLen == 0)
+				pstClassifierEntry->bDestIpValid = TRUE;
+
+			i++;
 		}
-		if(bIpVersion6)
-		{
-			//Restore EndianNess of Struct
-			for(ucLoopIndex =0 ; ucLoopIndex < MAX_IP_RANGE_LENGTH * 4 ;
-					ucLoopIndex++)
-			{
-				if(eIpAddrContext == eSrcIpAddress)
-				{
-					pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[ucLoopIndex]=
-							ntohl(pstClassifierEntry->stSrcIpAddress.
-							ulIpv6Addr[ucLoopIndex]);
-					pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[ucLoopIndex]= 							ntohl(pstClassifierEntry->stSrcIpAddress.
-							ulIpv6Mask[ucLoopIndex]);
-				}
-				else if(eIpAddrContext == eDestIpAddress)
-				{
-					pstClassifierEntry->stDestIpAddress.ulIpv6Addr[ucLoopIndex]= 							ntohl(pstClassifierEntry->stDestIpAddress.
-							ulIpv6Addr[ucLoopIndex]);
-					pstClassifierEntry->stDestIpAddress.ulIpv6Mask[ucLoopIndex]= 							ntohl(pstClassifierEntry->stDestIpAddress.
-							ulIpv6Mask[ucLoopIndex]);
+		if (bIpVersion6) {
+			/* Restore EndianNess of Struct */
+			for (i = 0; i < MAX_IP_RANGE_LENGTH * 4; i++) {
+				if (eIpAddrContext == eSrcIpAddress) {
+					pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[i] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Addr[i]);
+					pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[i] = ntohl(pstClassifierEntry->stSrcIpAddress.ulIpv6Mask[i]);
+				} else if (eIpAddrContext == eDestIpAddress) {
+					pstClassifierEntry->stDestIpAddress.ulIpv6Addr[i] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Addr[i]);
+					pstClassifierEntry->stDestIpAddress.ulIpv6Mask[i] = ntohl(pstClassifierEntry->stDestIpAddress.ulIpv6Mask[i]);
 				}
 			}
 		}
 	}
 }
 
-
-void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter,B_UINT16 TID,BOOLEAN bFreeAll)
+void ClearTargetDSXBuffer(PMINI_ADAPTER Adapter, B_UINT16 TID, BOOLEAN bFreeAll)
 {
-    ULONG ulIndex;
-	for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable; ulIndex++)
-	{
-		if(Adapter->astTargetDsxBuffer[ulIndex].valid)
+	int i;
+
+	for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) {
+		if (Adapter->astTargetDsxBuffer[i].valid)
 			continue;
-        if ((bFreeAll) || (Adapter->astTargetDsxBuffer[ulIndex].tid == TID)){
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n",
-				TID, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer);
-			Adapter->astTargetDsxBuffer[ulIndex].valid=1;
-			Adapter->astTargetDsxBuffer[ulIndex].tid=0;
+
+		if ((bFreeAll) || (Adapter->astTargetDsxBuffer[i].tid == TID)) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "ClearTargetDSXBuffer: found tid %d buffer cleared %lx\n",
+					TID, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer);
+			Adapter->astTargetDsxBuffer[i].valid = 1;
+			Adapter->astTargetDsxBuffer[i].tid = 0;
 			Adapter->ulFreeTargetBufferCnt++;
-      	}
+		}
 	}
 }
 
-/**
-@ingroup ctrl_pkt_functions
-copy classifier rule into the specified SF index
-*/
-static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLTypes  *psfCSType,UINT uiSearchRuleIndex,UINT nClassifierIndex)
+/*
+ * @ingroup ctrl_pkt_functions
+ * copy classifier rule into the specified SF index
+ */
+static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter, stConvergenceSLTypes  *psfCSType, UINT uiSearchRuleIndex, UINT nClassifierIndex)
 {
 	S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
-	//VOID *pvPhsContext = NULL;
-	UINT	ucLoopIndex=0;
-	//UCHAR   ucProtocolLength=0;
-	//ULONG   ulPhsStatus;
-
+	/* VOID *pvPhsContext = NULL; */
+	int i;
+	/* UCHAR ucProtocolLength=0; */
+	/* ULONG ulPhsStatus; */
 
-	if(Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 ||
+	if (Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value == 0 ||
 		nClassifierIndex > (MAX_CLASSIFIERS-1))
 		return;
 
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Storing Classifier Rule Index : %X",
+			ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex));
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Storing Classifier Rule Index : %X",ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex));
-
-	if(nClassifierIndex > MAX_CLASSIFIERS-1)
+	if (nClassifierIndex > MAX_CLASSIFIERS-1)
 		return;
 
 	pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
-	if(pstClassifierEntry)
-	{
-		//Store if Ipv6
-		pstClassifierEntry->bIpv6Protocol =
-		(Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE;
-
-		//Destinaiton Port
-		pstClassifierEntry->ucDestPortRangeLength=psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength/4;
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Length:0x%X ",pstClassifierEntry->ucDestPortRangeLength);
-		if(	MAX_PORT_RANGE >= psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength)
-		{
-			for(ucLoopIndex=0;ucLoopIndex<(pstClassifierEntry->ucDestPortRangeLength);ucLoopIndex++)
-			{
-				pstClassifierEntry->usDestPortRangeLo[ucLoopIndex] =
-					*((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+ucLoopIndex));
-				pstClassifierEntry->usDestPortRangeHi[ucLoopIndex] =
-					*((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+ucLoopIndex));
-				pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]);
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Destination Port Range Lo:0x%X ",pstClassifierEntry->usDestPortRangeLo[ucLoopIndex]);
-				pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usDestPortRangeHi[ucLoopIndex]);
+	if (pstClassifierEntry) {
+		/* Store if Ipv6 */
+		pstClassifierEntry->bIpv6Protocol = (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : FALSE;
+
+		/* Destinaiton Port */
+		pstClassifierEntry->ucDestPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength / 4;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Length:0x%X ", pstClassifierEntry->ucDestPortRangeLength);
+
+		if (psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength <= MAX_PORT_RANGE) {
+			for (i = 0; i < (pstClassifierEntry->ucDestPortRangeLength); i++) {
+				pstClassifierEntry->usDestPortRangeLo[i] = *((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+i));
+				pstClassifierEntry->usDestPortRangeHi[i] =
+					*((PUSHORT)(psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange+2+i));
+				pstClassifierEntry->usDestPortRangeLo[i] = ntohs(pstClassifierEntry->usDestPortRangeLo[i]);
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Destination Port Range Lo:0x%X ",
+						pstClassifierEntry->usDestPortRangeLo[i]);
+				pstClassifierEntry->usDestPortRangeHi[i] = ntohs(pstClassifierEntry->usDestPortRangeHi[i]);
 			}
+		} else {
+			pstClassifierEntry->ucDestPortRangeLength = 0;
 		}
-		else
-		{
-			pstClassifierEntry->ucDestPortRangeLength=0;
-		}
-		//Source Port
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Length:0x%X ",psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
-		if(MAX_PORT_RANGE >=
-		psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength)
-		{
-			pstClassifierEntry->ucSrcPortRangeLength =
-				psfCSType->cCPacketClassificationRule.
-						u8ProtocolSourcePortRangeLength/4;
-			for(ucLoopIndex = 0; ucLoopIndex <
-				(pstClassifierEntry->ucSrcPortRangeLength); ucLoopIndex++)
-			{
-				pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] =
-						*((PUSHORT)(psfCSType->cCPacketClassificationRule.
-							u8ProtocolSourcePortRange+ucLoopIndex));
-				pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex] =
-						*((PUSHORT)(psfCSType->cCPacketClassificationRule.
-							u8ProtocolSourcePortRange+2+ucLoopIndex));
-				pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex] =
-					ntohs(pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]);
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Source Port Range Lo:0x%X ",pstClassifierEntry->usSrcPortRangeLo[ucLoopIndex]);
-				pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]=ntohs(pstClassifierEntry->usSrcPortRangeHi[ucLoopIndex]);
+
+		/* Source Port */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Source Port Range Length:0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+		if (psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength <= MAX_PORT_RANGE) {
+			pstClassifierEntry->ucSrcPortRangeLength = psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength/4;
+			for (i = 0; i < (pstClassifierEntry->ucSrcPortRangeLength); i++) {
+				pstClassifierEntry->usSrcPortRangeLo[i] =
+					*((PUSHORT)(psfCSType->cCPacketClassificationRule.
+							u8ProtocolSourcePortRange+i));
+				pstClassifierEntry->usSrcPortRangeHi[i] =
+					*((PUSHORT)(psfCSType->cCPacketClassificationRule.
+							u8ProtocolSourcePortRange+2+i));
+				pstClassifierEntry->usSrcPortRangeLo[i] =
+					ntohs(pstClassifierEntry->usSrcPortRangeLo[i]);
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Source Port Range Lo:0x%X ",
+						pstClassifierEntry->usSrcPortRangeLo[i]);
+				pstClassifierEntry->usSrcPortRangeHi[i] = ntohs(pstClassifierEntry->usSrcPortRangeHi[i]);
 			}
 		}
-		//Destination Ip Address and Mask
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Destination Parameters : ");
-
+		/* Destination Ip Address and Mask */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Destination Parameters : ");
 		CopyIpAddrToClassifier(pstClassifierEntry,
-		   psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength,
-		   psfCSType->cCPacketClassificationRule.u8IPDestinationAddress,
-		   (Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?
-			TRUE:FALSE, eDestIpAddress);
+				psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength,
+				psfCSType->cCPacketClassificationRule.u8IPDestinationAddress,
+				(Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ?
+			TRUE : FALSE, eDestIpAddress);
 
-		//Source Ip Address and Mask
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Ip Source Parameters : ");
+		/* Source Ip Address and Mask */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Ip Source Parameters : ");
 
 		CopyIpAddrToClassifier(pstClassifierEntry,
-	   	psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength,
-		psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress,
-		(Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6)?TRUE:FALSE,
-		eSrcIpAddress);
-
-		//TOS
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"TOS Length:0x%X ",psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
-		if(3 == psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength)
-		{
-			pstClassifierEntry->ucIPTypeOfServiceLength =
-				psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength;
-			pstClassifierEntry->ucTosLow =
-				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0];
-			pstClassifierEntry->ucTosHigh =
-				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1];
-			pstClassifierEntry->ucTosMask =
-				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2];
+				psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength,
+				psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress,
+				(Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion == IPV6) ? TRUE : FALSE,
+				eSrcIpAddress);
+
+		/* TOS */
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "TOS Length:0x%X ", psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+		if (psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength == 3) {
+			pstClassifierEntry->ucIPTypeOfServiceLength = psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength;
+			pstClassifierEntry->ucTosLow = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0];
+			pstClassifierEntry->ucTosHigh = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1];
+			pstClassifierEntry->ucTosMask = psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2];
 			pstClassifierEntry->bTOSValid = TRUE;
 		}
-		if(psfCSType->cCPacketClassificationRule.u8Protocol == 0)
-		{
-			//we didn't get protocol field filled in by the BS
-			pstClassifierEntry->ucProtocolLength=0;
-		}
-		else
-		{
-			pstClassifierEntry->ucProtocolLength=1;// 1 valid protocol
+		if (psfCSType->cCPacketClassificationRule.u8Protocol == 0) {
+			/* we didn't get protocol field filled in by the BS */
+			pstClassifierEntry->ucProtocolLength = 0;
+		} else {
+			pstClassifierEntry->ucProtocolLength = 1; /* 1 valid protocol */
 		}
 
-		pstClassifierEntry->ucProtocol[0] =
-			psfCSType->cCPacketClassificationRule.u8Protocol;
-
-		pstClassifierEntry->u8ClassifierRulePriority =
-			psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority;
-
-		//store the classifier rule ID and set this classifier entry as valid
-		pstClassifierEntry->ucDirection =
-			Adapter->PackInfo[uiSearchRuleIndex].ucDirection;
-		pstClassifierEntry->uiClassifierRuleIndex = ntohs(psfCSType->
-				cCPacketClassificationRule.u16PacketClassificationRuleIndex);
-		pstClassifierEntry->usVCID_Value =
-			Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
-		pstClassifierEntry->ulSFID =
-			Adapter->PackInfo[uiSearchRuleIndex].ulSFID;
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Index %d Dir: %d, Index: %d, Vcid: %d\n",
-			uiSearchRuleIndex, pstClassifierEntry->ucDirection,
-			pstClassifierEntry->uiClassifierRuleIndex,
-			pstClassifierEntry->usVCID_Value);
-
-		if(psfCSType->cCPacketClassificationRule.u8AssociatedPHSI)
-		{
+		pstClassifierEntry->ucProtocol[0] = psfCSType->cCPacketClassificationRule.u8Protocol;
+		pstClassifierEntry->u8ClassifierRulePriority = psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority;
+
+		/* store the classifier rule ID and set this classifier entry as valid */
+		pstClassifierEntry->ucDirection = Adapter->PackInfo[uiSearchRuleIndex].ucDirection;
+		pstClassifierEntry->uiClassifierRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+		pstClassifierEntry->usVCID_Value = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
+		pstClassifierEntry->ulSFID = Adapter->PackInfo[uiSearchRuleIndex].ulSFID;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Index %d Dir: %d, Index: %d, Vcid: %d\n",
+				uiSearchRuleIndex, pstClassifierEntry->ucDirection,
+				pstClassifierEntry->uiClassifierRuleIndex,
+				pstClassifierEntry->usVCID_Value);
+
+		if (psfCSType->cCPacketClassificationRule.u8AssociatedPHSI)
 			pstClassifierEntry->u8AssociatedPHSI = psfCSType->cCPacketClassificationRule.u8AssociatedPHSI;
-		}
 
-		//Copy ETH CS Parameters
+		/* Copy ETH CS Parameters */
 		pstClassifierEntry->ucEthCSSrcMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddressLength);
-		memcpy(pstClassifierEntry->au8EThCSSrcMAC,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress,MAC_ADDRESS_SIZE);
-		memcpy(pstClassifierEntry->au8EThCSSrcMACMask,psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE);
+		memcpy(pstClassifierEntry->au8EThCSSrcMAC, psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress, MAC_ADDRESS_SIZE);
+		memcpy(pstClassifierEntry->au8EThCSSrcMACMask, psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE);
 		pstClassifierEntry->ucEthCSDestMACLen = (psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-		memcpy(pstClassifierEntry->au8EThCSDestMAC,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress,MAC_ADDRESS_SIZE);
-		memcpy(pstClassifierEntry->au8EThCSDestMACMask,psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress+MAC_ADDRESS_SIZE,MAC_ADDRESS_SIZE);
+		memcpy(pstClassifierEntry->au8EThCSDestMAC, psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress, MAC_ADDRESS_SIZE);
+		memcpy(pstClassifierEntry->au8EThCSDestMACMask, psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress + MAC_ADDRESS_SIZE, MAC_ADDRESS_SIZE);
 		pstClassifierEntry->ucEtherTypeLen = (psfCSType->cCPacketClassificationRule.u8EthertypeLength);
-		memcpy(pstClassifierEntry->au8EthCSEtherType,psfCSType->cCPacketClassificationRule.u8Ethertype,NUM_ETHERTYPE_BYTES);
+		memcpy(pstClassifierEntry->au8EthCSEtherType, psfCSType->cCPacketClassificationRule.u8Ethertype, NUM_ETHERTYPE_BYTES);
 		memcpy(pstClassifierEntry->usUserPriority, &psfCSType->cCPacketClassificationRule.u16UserPriority, 2);
 		pstClassifierEntry->usVLANID = ntohs(psfCSType->cCPacketClassificationRule.u16VLANID);
 		pstClassifierEntry->usValidityBitMap = ntohs(psfCSType->cCPacketClassificationRule.u16ValidityBitMap);
@@ -434,244 +362,199 @@ static inline VOID CopyClassifierRuleToSF(PMINI_ADAPTER Adapter,stConvergenceSLT
 	}
 }
 
-
-/**
-@ingroup ctrl_pkt_functions
-*/
-static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex,UINT nClassifierIndex)
+/*
+ * @ingroup ctrl_pkt_functions
+ */
+static inline VOID DeleteClassifierRuleFromSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex, UINT nClassifierIndex)
 {
 	S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
-	B_UINT16  u16PacketClassificationRuleIndex;
-	USHORT	  usVCID;
-	//VOID *pvPhsContext = NULL;
-	//ULONG ulPhsStatus;
+	B_UINT16 u16PacketClassificationRuleIndex;
+	USHORT usVCID;
+	/* VOID *pvPhsContext = NULL; */
+	/*ULONG ulPhsStatus; */
 
 	usVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
 
-	if(nClassifierIndex > MAX_CLASSIFIERS-1)
+	if (nClassifierIndex > MAX_CLASSIFIERS-1)
 		return;
 
-	if(usVCID == 0)
+	if (usVCID == 0)
 		return;
 
 	u16PacketClassificationRuleIndex = Adapter->astClassifierTable[nClassifierIndex].uiClassifierRuleIndex;
-
-
 	pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
-	if(pstClassifierEntry)
-	{
+	if (pstClassifierEntry) {
 		pstClassifierEntry->bUsed = FALSE;
 		pstClassifierEntry->uiClassifierRuleIndex = 0;
-		memset(pstClassifierEntry,0,sizeof(S_CLASSIFIER_RULE));
+		memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_RULE));
 
-		//Delete the PHS Rule for this classifier
-		PhsDeleteClassifierRule(
-				&Adapter->stBCMPhsContext,
-				usVCID,
-				u16PacketClassificationRuleIndex);
+		/* Delete the PHS Rule for this classifier */
+		PhsDeleteClassifierRule(&Adapter->stBCMPhsContext, usVCID, u16PacketClassificationRuleIndex);
 	}
 }
 
-/**
-@ingroup ctrl_pkt_functions
-*/
-VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter,UINT uiSearchRuleIndex)
+/*
+ * @ingroup ctrl_pkt_functions
+ */
+VOID DeleteAllClassifiersForSF(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex)
 {
 	S_CLASSIFIER_RULE *pstClassifierEntry = NULL;
-	UINT nClassifierIndex;
-	//B_UINT16  u16PacketClassificationRuleIndex;
-	USHORT	  ulVCID;
-	//VOID	  *pvPhsContext = NULL;
-	//ULONG	   ulPhsStatus;
+	int i;
+	/* B_UINT16  u16PacketClassificationRuleIndex; */
+	USHORT ulVCID;
+	/* VOID *pvPhsContext = NULL; */
+	/* ULONG ulPhsStatus; */
 
 	ulVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
 
-	if(ulVCID == 0)
+	if (ulVCID == 0)
 		return;
 
+	for (i = 0; i < MAX_CLASSIFIERS; i++) {
+		if (Adapter->astClassifierTable[i].usVCID_Value == ulVCID) {
+			pstClassifierEntry = &Adapter->astClassifierTable[i];
 
-	for(nClassifierIndex =0 ; nClassifierIndex < MAX_CLASSIFIERS ; nClassifierIndex++)
-	{
-		if(Adapter->astClassifierTable[nClassifierIndex].usVCID_Value == ulVCID)
-		{
-			pstClassifierEntry = &Adapter->astClassifierTable[nClassifierIndex];
-			if(pstClassifierEntry->bUsed)
-			{
-				DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex);
-			}
+			if (pstClassifierEntry->bUsed)
+				DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, i);
 		}
 	}
 
-	//Delete All Phs Rules Associated with this SF
-	PhsDeleteSFRules(
-			&Adapter->stBCMPhsContext,
-			ulVCID);
-
+	/* Delete All Phs Rules Associated with this SF */
+	PhsDeleteSFRules(&Adapter->stBCMPhsContext, ulVCID);
 }
 
-
-/**
-This routinue  copies the Connection Management
-related data into the Adapter structure.
-@ingroup ctrl_pkt_functions
-*/
-
-static VOID CopyToAdapter( register PMINI_ADAPTER Adapter,		/**<Pointer to the Adapter structure*/
-					register pstServiceFlowParamSI psfLocalSet,	/**<Pointer to the ServiceFlowParamSI structure*/
-					register UINT uiSearchRuleIndex,			/**<Index of Queue, to which this data belongs*/
-					register UCHAR ucDsxType,
-					stLocalSFAddIndicationAlt *pstAddIndication)
-{
-	//UCHAR   ucProtocolLength=0;
-	ULONG	ulSFID;
-	UINT    nClassifierIndex = 0;
-	E_CLASSIFIER_ACTION eClassifierAction = eInvalidClassifierAction;
-	B_UINT16  u16PacketClassificationRuleIndex=0;
-	UINT     nIndex=0;
+/*
+ * This routinue  copies the Connection Management
+ * related data into the Adapter structure.
+ * @ingroup ctrl_pkt_functions
+ */
+static VOID CopyToAdapter(register PMINI_ADAPTER Adapter, /* <Pointer to the Adapter structure */
+			register pstServiceFlowParamSI psfLocalSet, /* <Pointer to the ServiceFlowParamSI structure */
+			register UINT uiSearchRuleIndex, /* <Index of Queue, to which this data belongs */
+			register UCHAR ucDsxType,
+			stLocalSFAddIndicationAlt *pstAddIndication) {
+
+	/* UCHAR ucProtocolLength = 0; */
+	ULONG ulSFID;
+	UINT nClassifierIndex = 0;
+	enum E_CLASSIFIER_ACTION eClassifierAction = eInvalidClassifierAction;
+	B_UINT16 u16PacketClassificationRuleIndex = 0;
+	int i;
 	stConvergenceSLTypes *psfCSType = NULL;
 	S_PHS_RULE sPhsRule;
 	USHORT uVCID = Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value;
 	UINT UGIValue = 0;
 
-
-	Adapter->PackInfo[uiSearchRuleIndex].bValid=TRUE;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s: SFID= %x ",__FUNCTION__, ntohl(psfLocalSet->u32SFID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Updating Queue %d",uiSearchRuleIndex);
+	Adapter->PackInfo[uiSearchRuleIndex].bValid = TRUE;
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Search Rule Index = %d\n", uiSearchRuleIndex);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s: SFID= %x ", __func__, ntohl(psfLocalSet->u32SFID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Updating Queue %d", uiSearchRuleIndex);
 
 	ulSFID = ntohl(psfLocalSet->u32SFID);
-	//Store IP Version used
-	//Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF
+	/* Store IP Version used */
+	/* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */
 
 	Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = 0;
 	Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0;
 
-	/*Enable IP/ETh CS Support As Required*/
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : u8CSSpecification : %X\n",psfLocalSet->u8CSSpecification);
-	switch(psfLocalSet->u8CSSpecification)
+	/* Enable IP/ETh CS Support As Required */
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "CopyToAdapter : u8CSSpecification : %X\n", psfLocalSet->u8CSSpecification);
+	switch (psfLocalSet->u8CSSpecification) {
+	case eCSPacketIPV4:
 	{
-		case eCSPacketIPV4:
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
-			break;
-		}
-		case eCSPacketIPV6:
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
-			break;
-		}
-
-		case eCS802_3PacketEthernet:
-		case eCS802_1QPacketVLAN:
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
-			break;
-		}
-
-		case eCSPacketIPV4Over802_1QVLAN:
-		case eCSPacketIPV4Over802_3Ethernet:
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
-			Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
-			break;
-		}
-
-		case eCSPacketIPV6Over802_1QVLAN:
-		case eCSPacketIPV6Over802_3Ethernet:
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
-			Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
-			break;
-		}
-
-		default:
-		{
-            BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error in value of CS Classification.. setting default to IP CS\n");
-			Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
-			break;
-		}
+		Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
+		break;
+	}
+	case eCSPacketIPV6:
+	{
+		Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
+		break;
+	}
+	case eCS802_3PacketEthernet:
+	case eCS802_1QPacketVLAN:
+	{
+		Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
+		break;
+	}
+	case eCSPacketIPV4Over802_1QVLAN:
+	case eCSPacketIPV4Over802_3Ethernet:
+	{
+		Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
+		Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
+		break;
+	}
+	case eCSPacketIPV6Over802_1QVLAN:
+	case eCSPacketIPV6Over802_3Ethernet:
+	{
+		Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV6_CS;
+		Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = ETH_CS_802_3;
+		break;
+	}
+	default:
+	{
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error in value of CS Classification.. setting default to IP CS\n");
+		Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport = IPV4_CS;
+		break;
+	}
 	}
 
-    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Queue No : %X ETH CS Support :  %X  , IP CS Support : %X   \n",
-		uiSearchRuleIndex,
-		Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport,
-		Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "CopyToAdapter : Queue No : %X ETH CS Support :  %X  , IP CS Support : %X\n",
+			uiSearchRuleIndex,
+			Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport,
+			Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport);
 
-	//Store IP Version used
-	//Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF
-	if(Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport == IPV6_CS)
-	{
+	/* Store IP Version used */
+	/* Get The Version Of IP used (IPv6 or IPv4) from CSSpecification field of SF */
+	if (Adapter->PackInfo[uiSearchRuleIndex].bIPCSSupport == IPV6_CS)
 		Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV6;
-	}
 	else
-	{
 		Adapter->PackInfo[uiSearchRuleIndex].ucIpVersion = IPV4;
-	}
 
 	/* To ensure that the ETH CS code doesn't gets executed if the BS doesn't supports ETH CS */
-	if(!Adapter->bETHCSEnabled)
+	if (!Adapter->bETHCSEnabled)
 		Adapter->PackInfo[uiSearchRuleIndex].bEthCSSupport = 0;
 
-	if(psfLocalSet->u8ServiceClassNameLength > 0 &&
-			psfLocalSet->u8ServiceClassNameLength < 32)
-	{
-		memcpy(Adapter->PackInfo[uiSearchRuleIndex].ucServiceClassName,
-			psfLocalSet->u8ServiceClassName,
-			psfLocalSet->u8ServiceClassNameLength);
-	}
-	Adapter->PackInfo[uiSearchRuleIndex].u8QueueType =
-			psfLocalSet->u8ServiceFlowSchedulingType;
+	if (psfLocalSet->u8ServiceClassNameLength > 0 && psfLocalSet->u8ServiceClassNameLength < 32)
+		memcpy(Adapter->PackInfo[uiSearchRuleIndex].ucServiceClassName,	psfLocalSet->u8ServiceClassName, psfLocalSet->u8ServiceClassNameLength);
 
-	if(Adapter->PackInfo[uiSearchRuleIndex].u8QueueType==BE &&
-			Adapter->PackInfo[uiSearchRuleIndex].ucDirection)
-	{
-		Adapter->usBestEffortQueueIndex=uiSearchRuleIndex;
-	}
+	Adapter->PackInfo[uiSearchRuleIndex].u8QueueType = psfLocalSet->u8ServiceFlowSchedulingType;
+
+	if (Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == BE && Adapter->PackInfo[uiSearchRuleIndex].ucDirection)
+		Adapter->usBestEffortQueueIndex = uiSearchRuleIndex;
 
 	Adapter->PackInfo[uiSearchRuleIndex].ulSFID = ntohl(psfLocalSet->u32SFID);
 
 	Adapter->PackInfo[uiSearchRuleIndex].u8TrafficPriority = psfLocalSet->u8TrafficPriority;
 
-	//copy all the classifier in the Service Flow param  structure
-	for(nIndex=0; nIndex<psfLocalSet->u8TotalClassifiers; nIndex++)
-	{
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex);
-		psfCSType =  &psfLocalSet->cConvergenceSLTypes[nIndex];
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Classifier index =%d",nIndex);
-
-		if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority)
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE;
-		}
+	/* copy all the classifier in the Service Flow param  structure */
+	for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", i);
+		psfCSType = &psfLocalSet->cConvergenceSLTypes[i];
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Classifier index =%d", i);
 
-		if(psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority)
-		{
-			Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority=TRUE;
-		}
+		if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority)
+			Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority = TRUE;
 
+		if (psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority)
+			Adapter->PackInfo[uiSearchRuleIndex].bClassifierPriority = TRUE;
 
-		if(ucDsxType== DSA_ACK)
-		{
+		if (ucDsxType == DSA_ACK) {
 			eClassifierAction = eAddClassifier;
-		}
-		else if(ucDsxType == DSC_ACK)
-		{
-			switch(psfCSType->u8ClassfierDSCAction)
-			{
-			case 0://DSC Add Classifier
+		} else if (ucDsxType == DSC_ACK) {
+			switch (psfCSType->u8ClassfierDSCAction) {
+			case 0: /* DSC Add Classifier */
 			{
 				eClassifierAction = eAddClassifier;
 			}
 			break;
-			case 1://DSC Replace Classifier
+			case 1: /* DSC Replace Classifier */
 			{
 				eClassifierAction = eReplaceClassifier;
 			}
 			break;
-			case 2://DSC Delete Classifier
+			case 2: /* DSC Delete Classifier */
 			{
 				eClassifierAction = eDeleteClassifier;
-
 			}
 			break;
 			default:
@@ -683,163 +566,133 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter,		/**<Pointer to the A
 
 		u16PacketClassificationRuleIndex = ntohs(psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
 
-		switch(eClassifierAction)
-		{
+		switch (eClassifierAction) {
 		case eAddClassifier:
 		{
-			//Get a Free Classifier Index From Classifier table for this SF to add the Classifier
-			//Contained in this message
-			nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex);
+			/* Get a Free Classifier Index From Classifier table for this SF to add the Classifier */
+			/* Contained in this message */
+			nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex);
 
-			if(nClassifierIndex > MAX_CLASSIFIERS)
-			{
+			if (nClassifierIndex > MAX_CLASSIFIERS) {
 				nClassifierIndex = SearchFreeClsid(Adapter);
-				if(nClassifierIndex > MAX_CLASSIFIERS)
-				{
-					//Failed To get a free Entry
-					BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Failed To get a free Classifier Entry");
+				if (nClassifierIndex > MAX_CLASSIFIERS) {
+					/* Failed To get a free Entry */
+					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error Failed To get a free Classifier Entry");
 					break;
 				}
-				//Copy the Classifier Rule for this service flow into our Classifier table maintained per SF.
-				CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex);
-			}
-
-			else
-			{
-				//This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"CopyToAdapter : Error The Specified Classifier Already Exists \
-						and attempted To Add Classifier with Same PCRI : 0x%x\n", u16PacketClassificationRuleIndex);
+				/* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */
+				CopyClassifierRuleToSF(Adapter, psfCSType, uiSearchRuleIndex, nClassifierIndex);
+			} else {
+				/* This Classifier Already Exists and it is invalid to Add Classifier with existing PCRI */
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,
+						"CopyToAdapter: Error The Specified Classifier Already Exists and attempted To Add Classifier with Same PCRI : 0x%x\n",
+						u16PacketClassificationRuleIndex);
 			}
 		}
 		break;
-
 		case eReplaceClassifier:
 		{
-				//Get the Classifier Index From Classifier table for this SF and replace existing  Classifier
-				//with the new classifier Contained in this message
-			nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex);
-			if(nClassifierIndex > MAX_CLASSIFIERS)
-			{
-				//Failed To search the classifier
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be replaced failed");
+			/* Get the Classifier Index From Classifier table for this SF and replace existing  Classifier */
+			/* with the new classifier Contained in this message */
+			nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex);
+			if (nClassifierIndex > MAX_CLASSIFIERS) {
+				/* Failed To search the classifier */
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error Search for Classifier To be replaced failed");
 				break;
 			}
-			//Copy the Classifier Rule for this service flow into our Classifier table maintained per SF.
-			CopyClassifierRuleToSF(Adapter,psfCSType,uiSearchRuleIndex,nClassifierIndex);
+			/* Copy the Classifier Rule for this service flow into our Classifier table maintained per SF. */
+			CopyClassifierRuleToSF(Adapter, psfCSType, uiSearchRuleIndex, nClassifierIndex);
 		}
 		break;
-
 		case eDeleteClassifier:
 		{
-				//Get the Classifier Index From Classifier table for this SF and replace existing  Classifier
-				//with the new classifier Contained in this message
-			nClassifierIndex = SearchClsid(Adapter,ulSFID,u16PacketClassificationRuleIndex);
-			if(nClassifierIndex > MAX_CLASSIFIERS)
-			{
-				//Failed To search the classifier
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Error Search for Classifier To be deleted failed");
+			/* Get the Classifier Index From Classifier table for this SF and replace existing  Classifier */
+			/* with the new classifier Contained in this message */
+			nClassifierIndex = SearchClsid(Adapter, ulSFID, u16PacketClassificationRuleIndex);
+			if (nClassifierIndex > MAX_CLASSIFIERS)	{
+				/* Failed To search the classifier */
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Error Search for Classifier To be deleted failed");
 				break;
 			}
 
-			//Delete This classifier
-			DeleteClassifierRuleFromSF(Adapter,uiSearchRuleIndex,nClassifierIndex);
+			/* Delete This classifier */
+			DeleteClassifierRuleFromSF(Adapter, uiSearchRuleIndex, nClassifierIndex);
 		}
 		break;
-
 		default:
 		{
-			//Invalid Action for classifier
+			/* Invalid Action for classifier */
 			break;
 		}
 		}
 	}
 
-	//Repeat parsing Classification Entries to process PHS Rules
-	for(nIndex=0; nIndex < psfLocalSet->u8TotalClassifiers; nIndex++)
-	{
-		psfCSType =  &psfLocalSet->cConvergenceSLTypes[nIndex];
-
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n",
-				psfCSType->u8PhsDSCAction );
+	/* Repeat parsing Classification Entries to process PHS Rules */
+	for (i = 0; i < psfLocalSet->u8TotalClassifiers; i++) {
+		psfCSType = &psfLocalSet->cConvergenceSLTypes[i];
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "psfCSType->u8PhsDSCAction : 0x%x\n", psfCSType->u8PhsDSCAction);
 
-		switch (psfCSType->u8PhsDSCAction)
-		{
+		switch (psfCSType->u8PhsDSCAction) {
 		case eDeleteAllPHSRules:
 		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Deleting All PHS Rules For VCID: 0x%X\n",uVCID);
-
-			//Delete All the PHS rules for this Service flow
-
-			PhsDeleteSFRules(
-				&Adapter->stBCMPhsContext,
-				uVCID);
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Deleting All PHS Rules For VCID: 0x%X\n", uVCID);
 
+			/* Delete All the PHS rules for this Service flow */
+			PhsDeleteSFRules(&Adapter->stBCMPhsContext, uVCID);
 			break;
 		}
 		case eDeletePHSRule:
 		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"PHS DSC Action = Delete PHS Rule \n");
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "PHS DSC Action = Delete PHS Rule\n");
+
+			if (psfCSType->cPhsRule.u8PHSI)
+				PhsDeletePHSRule(&Adapter->stBCMPhsContext, uVCID, psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
 
-			if(psfCSType->cPhsRule.u8PHSI)
-			{
-				PhsDeletePHSRule(
-					&Adapter->stBCMPhsContext,
-					uVCID,
-					psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
-			}
-			else
-			{
-				//BCM_DEBUG_PRINT(CONN_MSG,("Error CPHSRule.PHSI is ZERO \n"));
-			}
 			break;
 		}
-		default :
+		default:
 		{
-			if(ucDsxType == DSC_ACK)
-			{
-				//BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC \n",psfCSType->cPhsRule.u8PHSI));
-				break; //FOr DSC ACK Case PHS DSC Action must be in valid set
+			if (ucDsxType == DSC_ACK) {
+				/* BCM_DEBUG_PRINT(CONN_MSG,("Invalid PHS DSC Action For DSC\n",psfCSType->cPhsRule.u8PHSI)); */
+				break; /* FOr DSC ACK Case PHS DSC Action must be in valid set */
 			}
 		}
-		//Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified
-		//No Break Here . Intentionally!
+		/* Proceed To Add PHS rule for DSA_ACK case even if PHS DSC action is unspecified */
+		/* No Break Here . Intentionally! */
 
 		case eAddPHSRule:
 		case eSetPHSRule:
 		{
-			if(psfCSType->cPhsRule.u8PHSI)
-			{
-				//Apply This PHS Rule to all classifiers whose Associated PHSI Match
+			if (psfCSType->cPhsRule.u8PHSI)	{
+				/* Apply This PHS Rule to all classifiers whose Associated PHSI Match */
 				unsigned int uiClassifierIndex = 0;
-				if(pstAddIndication->u8Direction == UPLINK_DIR )
-				{
-					for(uiClassifierIndex=0;uiClassifierIndex<MAX_CLASSIFIERS;uiClassifierIndex++)
-					{
-						if((Adapter->astClassifierTable[uiClassifierIndex].bUsed) &&
+				if (pstAddIndication->u8Direction == UPLINK_DIR) {
+					for (uiClassifierIndex = 0; uiClassifierIndex < MAX_CLASSIFIERS; uiClassifierIndex++) {
+						if ((Adapter->astClassifierTable[uiClassifierIndex].bUsed) &&
 							(Adapter->astClassifierTable[uiClassifierIndex].ulSFID == Adapter->PackInfo[uiSearchRuleIndex].ulSFID) &&
-							(Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI == psfCSType->cPhsRule.u8PHSI))
-						{
-							BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Adding  PHS Rule For  Classifier : 0x%x cPhsRule.u8PHSI : 0x%x\n",
-								Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex,
-								psfCSType->cPhsRule.u8PHSI);
-							//Update The PHS Rule for this classifier as Associated PHSI id defined
-
-							//Copy the PHS Rule
-							sPhsRule.u8PHSI =  psfCSType->cPhsRule.u8PHSI;
-							sPhsRule.u8PHSFLength =  psfCSType->cPhsRule.u8PHSFLength;
+							(Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI == psfCSType->cPhsRule.u8PHSI)) {
+							BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,
+									"Adding PHS Rule For Classifier: 0x%x cPhsRule.u8PHSI: 0x%x\n",
+									Adapter->astClassifierTable[uiClassifierIndex].uiClassifierRuleIndex,
+									psfCSType->cPhsRule.u8PHSI);
+							/* Update The PHS Rule for this classifier as Associated PHSI id defined */
+
+							/* Copy the PHS Rule */
+							sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI;
+							sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength;
 							sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength;
 							sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS;
 							sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV;
-							memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS);
-							memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS);
+							memcpy(sPhsRule.u8PHSF, psfCSType->cPhsRule.u8PHSF, MAX_PHS_LENGTHS);
+							memcpy(sPhsRule.u8PHSM, psfCSType->cPhsRule.u8PHSM, MAX_PHS_LENGTHS);
 							sPhsRule.u8RefCnt = 0;
 							sPhsRule.bUnclassifiedPHSRule = FALSE;
 							sPhsRule.PHSModifiedBytes = 0;
 							sPhsRule.PHSModifiedNumPackets = 0;
 							sPhsRule.PHSErrorNumPackets = 0;
 
-							//bPHSRuleAssociated = TRUE;
-							//Store The PHS Rule for this classifier
+							/* bPHSRuleAssociated = TRUE; */
+							/* Store The PHS Rule for this classifier */
 
 							PhsUpdateClassifierRule(
 								&Adapter->stBCMPhsContext,
@@ -848,184 +701,157 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter,		/**<Pointer to the A
 								&sPhsRule,
 								Adapter->astClassifierTable[uiClassifierIndex].u8AssociatedPHSI);
 
-							//Update PHS Rule For the Classifier
-							if(sPhsRule.u8PHSI)
-							{
+							/* Update PHS Rule For the Classifier */
+							if (sPhsRule.u8PHSI) {
 								Adapter->astClassifierTable[uiClassifierIndex].u32PHSRuleID = sPhsRule.u8PHSI;
-								memcpy(&Adapter->astClassifierTable[uiClassifierIndex].sPhsRule,&sPhsRule,sizeof(S_PHS_RULE));
+								memcpy(&Adapter->astClassifierTable[uiClassifierIndex].sPhsRule, &sPhsRule, sizeof(S_PHS_RULE));
 							}
-
 						}
 					}
+				} else {
+					/* Error PHS Rule specified in signaling could not be applied to any classifier */
+
+					/* Copy the PHS Rule */
+					sPhsRule.u8PHSI = psfCSType->cPhsRule.u8PHSI;
+					sPhsRule.u8PHSFLength = psfCSType->cPhsRule.u8PHSFLength;
+					sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength;
+					sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS;
+					sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV;
+					memcpy(sPhsRule.u8PHSF, psfCSType->cPhsRule.u8PHSF, MAX_PHS_LENGTHS);
+					memcpy(sPhsRule.u8PHSM, psfCSType->cPhsRule.u8PHSM, MAX_PHS_LENGTHS);
+					sPhsRule.u8RefCnt = 0;
+					sPhsRule.bUnclassifiedPHSRule = TRUE;
+					sPhsRule.PHSModifiedBytes = 0;
+					sPhsRule.PHSModifiedNumPackets = 0;
+					sPhsRule.PHSErrorNumPackets = 0;
+					/* Store The PHS Rule for this classifier */
+
+					/*
+					 * Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule,
+					 * clsid will be zero hence we can't have multiple PHS rules for the same SF.
+					 * To support multiple PHS rule, passing u8PHSI.
+					 */
+					PhsUpdateClassifierRule(
+						&Adapter->stBCMPhsContext,
+						uVCID,
+						sPhsRule.u8PHSI,
+						&sPhsRule,
+						sPhsRule.u8PHSI);
 				}
-				else
-				{
-					//Error PHS Rule specified in signaling could not be applied to any classifier
-
-						//Copy the PHS Rule
-						sPhsRule.u8PHSI =  psfCSType->cPhsRule.u8PHSI;
-						sPhsRule.u8PHSFLength =  psfCSType->cPhsRule.u8PHSFLength;
-						sPhsRule.u8PHSMLength = psfCSType->cPhsRule.u8PHSMLength;
-						sPhsRule.u8PHSS = psfCSType->cPhsRule.u8PHSS;
-						sPhsRule.u8PHSV = psfCSType->cPhsRule.u8PHSV;
-						memcpy(sPhsRule.u8PHSF,psfCSType->cPhsRule.u8PHSF,MAX_PHS_LENGTHS);
-						memcpy(sPhsRule.u8PHSM,psfCSType->cPhsRule.u8PHSM,MAX_PHS_LENGTHS);
-						sPhsRule.u8RefCnt = 0;
-						sPhsRule.bUnclassifiedPHSRule = TRUE;
-						sPhsRule.PHSModifiedBytes = 0;
-						sPhsRule.PHSModifiedNumPackets = 0;
-						sPhsRule.PHSErrorNumPackets = 0;
-						//Store The PHS Rule for this classifier
-
-						/*
-							Passing the argument u8PHSI instead of clsid. Because for DL with no classifier rule,
-							clsid will be zero hence we can't have multiple PHS rules for the same SF.
-							To support multiple PHS rule, passing u8PHSI.
-						*/
-
-						PhsUpdateClassifierRule(
-							&Adapter->stBCMPhsContext,
-							uVCID,
-							sPhsRule.u8PHSI,
-							&sPhsRule,
-							sPhsRule.u8PHSI);
-
-				}
-
 			}
 		}
 		break;
 		}
 	}
 
-	if(psfLocalSet->u32MaxSustainedTrafficRate == 0	)
-	{
-		//No Rate Limit . Set Max Sustained Traffic Rate to Maximum
-		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =
-			WIMAX_MAX_ALLOWED_RATE;
-
-	}
-	else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) >
-			WIMAX_MAX_ALLOWED_RATE)
-	{
-		//Too large Allowed Rate specified. Limiting to Wi Max  Allowed rate
-		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =
-			WIMAX_MAX_ALLOWED_RATE;
-	}
-	else
-	{
-		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =
-			ntohl(psfLocalSet->u32MaxSustainedTrafficRate);
+	if (psfLocalSet->u32MaxSustainedTrafficRate == 0) {
+		/* No Rate Limit . Set Max Sustained Traffic Rate to Maximum */
+		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE;
+	} else if (ntohl(psfLocalSet->u32MaxSustainedTrafficRate) > WIMAX_MAX_ALLOWED_RATE) {
+		/* Too large Allowed Rate specified. Limiting to Wi Max  Allowed rate */
+		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate = WIMAX_MAX_ALLOWED_RATE;
+	} else {
+		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate =  ntohl(psfLocalSet->u32MaxSustainedTrafficRate);
 	}
 
 	Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = ntohl(psfLocalSet->u32MaximumLatency);
-
-	if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency == 0) /* 0 should be treated as infinite */
+	if (Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency == 0) /* 0 should be treated as infinite */
 		Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency = MAX_LATENCY_ALLOWED;
 
+	if ((Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == ERTPS ||
+			Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == UGS))
+		UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval);
 
-	if(( Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == ERTPS ||
-			Adapter->PackInfo[uiSearchRuleIndex].u8QueueType == UGS ) )
-			UGIValue = ntohs(psfLocalSet->u16UnsolicitedGrantInterval);
-
-	if(UGIValue == 0)
+	if (UGIValue == 0)
 		UGIValue = DEFAULT_UG_INTERVAL;
 
 	/*
-	For UGI based connections...
-	DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host...
-	The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput...
-	In case of non-UGI based connection, 200 frames worth of data is the max token count at host...
-	*/
-
+	 * For UGI based connections...
+	 * DEFAULT_UGI_FACTOR*UGIInterval worth of data is the max token count at host...
+	 * The extra amount of token is to ensure that a large amount of jitter won't have loss in throughput...
+	 * In case of non-UGI based connection, 200 frames worth of data is the max token count at host...
+	 */
 	Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize =
-        (DEFAULT_UGI_FACTOR*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000;
+		(DEFAULT_UGI_FACTOR*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000;
 
-	if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize < WIMAX_MAX_MTU*8)
-	{
+	if (Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize < WIMAX_MAX_MTU*8) {
 		UINT UGIFactor = 0;
 		/* Special Handling to ensure the biggest size of packet can go out from host to FW as follows:
-		1. Any packet from Host to FW can go out in different packet size.
-		2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped.
-		3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer
-		*/
+		 * 1. Any packet from Host to FW can go out in different packet size.
+		 * 2. So in case the Bucket count is smaller than MTU, the packets of size (Size > TokenCount), will get dropped.
+		 * 3. We can allow packets of MaxSize from Host->FW that can go out from FW in multiple SDUs by fragmentation at Wimax Layer
+		 */
 		UGIFactor = (Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency/UGIValue + 1);
 
-		if(UGIFactor > DEFAULT_UGI_FACTOR)
-    		Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize =
-    		(UGIFactor*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000;
+		if (UGIFactor > DEFAULT_UGI_FACTOR)
+			Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize =
+				(UGIFactor*Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate*UGIValue)/1000;
 
-		if(Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize > WIMAX_MAX_MTU*8)
+		if (Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize > WIMAX_MAX_MTU*8)
 			Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize = WIMAX_MAX_MTU*8;
 	}
 
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "LAT: %d, UGI: %d\n", Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency, UGIValue);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x",
+			Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate,
+			ntohl(psfLocalSet->u32MaxSustainedTrafficRate),
+			Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize);
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"LAT: %d, UGI: %d \n", Adapter->PackInfo[uiSearchRuleIndex].uiMaxLatency, UGIValue);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiMaxAllowedRate: 0x%x, u32MaxSustainedTrafficRate: 0x%x ,uiMaxBucketSize: 0x%x",
-		Adapter->PackInfo[uiSearchRuleIndex].uiMaxAllowedRate,
-		ntohl(psfLocalSet->u32MaxSustainedTrafficRate),
-		Adapter->PackInfo[uiSearchRuleIndex].uiMaxBucketSize);
-
-	//copy the extended SF Parameters to Support MIBS
-	CopyMIBSExtendedSFParameters(Adapter,psfLocalSet,uiSearchRuleIndex);
+	/* copy the extended SF Parameters to Support MIBS */
+	CopyMIBSExtendedSFParameters(Adapter, psfLocalSet, uiSearchRuleIndex);
 
-	//store header suppression enabled flag per SF
+	/* store header suppression enabled flag per SF */
 	Adapter->PackInfo[uiSearchRuleIndex].bHeaderSuppressionEnabled =
-			!(psfLocalSet->u8RequesttransmissionPolicy &
-				MASK_DISABLE_HEADER_SUPPRESSION);
+		!(psfLocalSet->u8RequesttransmissionPolicy &
+			MASK_DISABLE_HEADER_SUPPRESSION);
 
 	kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication);
 	Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication;
 
-	//Re Sort the SF list in PackInfo according to Traffic Priority
+	/* Re Sort the SF list in PackInfo according to Traffic Priority */
 	SortPackInfo(Adapter);
 
 	/* Re Sort the Classifier Rules table and re - arrange
-		according to Classifier Rule Priority */
+	 * according to Classifier Rule Priority
+	 */
 	SortClassifiers(Adapter);
-
 	DumpPhsRules(&Adapter->stBCMPhsContext);
-
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"%s <=====", __FUNCTION__);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s <=====", __func__);
 }
 
-
 /***********************************************************************
-* Function	  -	DumpCmControlPacket
-*
-* Description -	This routinue Dumps the Contents of the AddIndication
-*				Structure in the Connection Management Control Packet
-*
-* Parameter   -	pvBuffer: Pointer to the buffer containing the
-*				AddIndication data.
-*
-* Returns	  - None
-*************************************************************************/
+ * Function - DumpCmControlPacket
+ *
+ * Description - This routinue Dumps the Contents of the AddIndication
+ *  Structure in the Connection Management Control Packet
+ *
+ * Parameter - pvBuffer: Pointer to the buffer containing the
+ *  AddIndication data.
+ *
+ * Returns - None
+ *************************************************************************/
 static VOID DumpCmControlPacket(PVOID pvBuffer)
 {
-	UINT 					uiLoopIndex;
-	UINT                    nIndex;
-	stLocalSFAddIndicationAlt  *pstAddIndication;
-	UINT                    nCurClassifierCnt;
-    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+	int uiLoopIndex;
+	int nIndex;
+	stLocalSFAddIndicationAlt *pstAddIndication;
+	UINT nCurClassifierCnt;
+	PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
 
 	pstAddIndication = (stLocalSFAddIndicationAlt *)pvBuffer;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>");
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Type		: 0x%X",pstAddIndication->u8Type);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Direction	: 0x%X",pstAddIndication->u8Direction);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID		: 0x%X",ntohs(pstAddIndication->u16CID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID		: 0x%X",ntohs(pstAddIndication->u16VCID));
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " AuthorizedSet--->");
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32SFID		: 0x%X",htonl(pstAddIndication->sfAuthorizedSet.u32SFID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16CID		: 0x%X",htons(pstAddIndication->sfAuthorizedSet.u16CID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceClassNameLength	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName		: 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X",
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "======>");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TID: 0x%X", ntohs(pstAddIndication->u16TID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", ntohs(pstAddIndication->u16CID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VCID: 0x%X", ntohs(pstAddIndication->u16VCID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " AuthorizedSet--->");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", htonl(pstAddIndication->sfAuthorizedSet.u32SFID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", htons(pstAddIndication->sfAuthorizedSet.u16CID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8ServiceClassNameLength);
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x%X ,0x%X , 0x%X, 0x%X, 0x%X, 0x%X",
 			pstAddIndication->sfAuthorizedSet.u8ServiceClassName[0],
 			pstAddIndication->sfAuthorizedSet.u8ServiceClassName[1],
 			pstAddIndication->sfAuthorizedSet.u8ServiceClassName[2],
@@ -1033,207 +859,170 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
 			pstAddIndication->sfAuthorizedSet.u8ServiceClassName[4],
 			pstAddIndication->sfAuthorizedSet.u8ServiceClassName[5]);
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8MBSService		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8MBSService);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8QosParamSet		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8QosParamSet);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority	: 0x%X, %p",
-		pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaxSustainedTrafficRate	: 0x%X 0x%p",
-		pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate,
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%X", pstAddIndication->sfAuthorizedSet.u8MBSService);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%X", pstAddIndication->sfAuthorizedSet.u8QosParamSet);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%X, %p",
+			pstAddIndication->sfAuthorizedSet.u8TrafficPriority, &pstAddIndication->sfAuthorizedSet.u8TrafficPriority);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxSustainedTrafficRate: 0x%X 0x%p",
+			pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate,
 			&pstAddIndication->sfAuthorizedSet.u32MaxSustainedTrafficRate);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst			: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter				: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u32ToleratedJitter);
-    BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaximumLatency				: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u32MaximumLatency);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize				: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8SDUSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16TargetSAID			: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16TargetSAID);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ARQEnable				: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8ARQEnable);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQWindowSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQRetryRxTimeOut	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQSyncLossTimeOut	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ARQDeliverInOrder		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQRxPurgeTimeOut	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQBlockSize			: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16ARQBlockSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8CSSpecification		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8CSSpecification);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TypeOfDataDeliveryService	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16SDUInterArrivalTime	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16TimeBase				: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16TimeBase);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8PagingPreference		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8PagingPreference);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16UnsolicitedPollingInterval		: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "sfAuthorizedSet.u8HARQChannelMapping %x  %x %x ",
-				*(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
-				*(unsigned int*)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4],
-			*(USHORT*) &pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficIndicationPreference	: 0x%X",
-		pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " Total Classifiers Received		: 0x%X",pstAddIndication->sfAuthorizedSet.u8TotalClassifiers);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate	: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParam[0]);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8ServiceFlowSchedulingType);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAuthorizedSet.u32ToleratedJitter);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAuthorizedSet.u32MaximumLatency);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8FixedLengthVSVariableLengthSDUIndicator);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X",	pstAddIndication->sfAuthorizedSet.u8SDUSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%X", pstAddIndication->sfAuthorizedSet.u16TargetSAID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQEnable);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQWindowSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryTxTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRetryRxTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockLifeTime);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQSyncLossTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfAuthorizedSet.u8ARQDeliverInOrder);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQRxPurgeTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAuthorizedSet.u16ARQBlockSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%X",	pstAddIndication->sfAuthorizedSet.u8CSSpecification);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8TypeOfDataDeliveryService);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAuthorizedSet.u16SDUInterArrivalTime);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAuthorizedSet.u16TimeBase);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAuthorizedSet.u8PagingPreference);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval);
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x  %x %x ",
+			*(unsigned int *)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping,
+			*(unsigned int *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[4],
+			*(USHORT *)&pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping[8]);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%X",
+			pstAddIndication->sfAuthorizedSet.u8TrafficIndicationPreference);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAuthorizedSet.u8TotalClassifiers);
 
 	nCurClassifierCnt = pstAddIndication->sfAuthorizedSet.u8TotalClassifiers;
-
-	if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
-	{
+	if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
 		nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
-	}
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead);
-	if(!pstAddIndication->sfAuthorizedSet.bValid)
-		pstAddIndication->sfAuthorizedSet.bValid=1;
-	for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++)
-	{
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "pstAddIndication->sfAuthorizedSet.bValid %d", pstAddIndication->sfAuthorizedSet.bValid);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "pstAddIndication->sfAuthorizedSet.u16MacOverhead %x", pstAddIndication->sfAuthorizedSet.u16MacOverhead);
+	if (!pstAddIndication->sfAuthorizedSet.bValid)
+		pstAddIndication->sfAuthorizedSet.bValid = 1;
+	for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {
 		stConvergenceSLTypes *psfCSType = NULL;
 		psfCSType =  &pstAddIndication->sfAuthorizedSet.cConvergenceSLTypes[nIndex];
 
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "psfCSType = %p", psfCSType);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "CCPacketClassificationRuleSI====>");
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ClassifierRulePriority		:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPTypeOfServiceLength			:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPTypeOfService[3]			:0x%X ,0x%X ,0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
-
-		for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Protocol : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8Protocol);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPMaskedSourceAddressLength	:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
-
-		for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPMaskedSourceAddress[32]	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPDestinationAddressLength : 0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
-
-		for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPDestinationAddress[32] : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolSourcePortRangeLength:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolDestPortRangeLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetDestMacAddressLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetSourceMACAddressLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthertypeLength	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8EthertypeLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Ethertype[3] : 0x%02X ,0x%02X ,0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8Ethertype[0],
-			psfCSType->cCPacketClassificationRule.u8Ethertype[1],
-			psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16UserPriority		: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u16UserPriority);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16VLANID			: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u16VLANID);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8AssociatedPHSI	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16PacketClassificationRuleIndex : 0x%X ",
-			psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificClassifierParamLength	: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificClassifierParam[1]		: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "psfCSType = %p", psfCSType);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "CCPacketClassificationRuleSI====>");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPTypeOfServiceLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ",
+					psfCSType->cCPacketClassificationRule.u8Protocol);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ",
+					psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ",
+					psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength:0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x%02X ,0x%02X ,0x%02X ,0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: 0x %02X %02X %02X %02X %02X %02X",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: 0x %02X %02X %02X %02X %02X %02X",
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X ,0x%02X ,0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8Ethertype[0],
+				psfCSType->cCPacketClassificationRule.u8Ethertype[1],
+				psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
 #ifdef VERSION_D5
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPv6FlowLableLength				:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPv6FlowLable[6] : 0x %02X %02X %02X %02X %02X %02X ",
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ",
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
 #endif
 	}
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "bValid		: 0x%02X",pstAddIndication->sfAuthorizedSet.bValid);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "AdmittedSet--->");
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32SFID		: 0x%X",pstAddIndication->sfAdmittedSet.u32SFID);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16CID		: 0x%X",pstAddIndication->sfAdmittedSet.u16CID);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceClassNameLength	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceClassName			: 0x %02X %02X %02X %02X %02X %02X",
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%02X", pstAddIndication->sfAuthorizedSet.bValid);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "AdmittedSet--->");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfAdmittedSet.u32SFID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfAdmittedSet.u16CID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X",
+			pstAddIndication->sfAdmittedSet.u8ServiceClassNameLength);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X",
 			pstAddIndication->sfAdmittedSet.u8ServiceClassName[0],
 			pstAddIndication->sfAdmittedSet.u8ServiceClassName[1],
 			pstAddIndication->sfAdmittedSet.u8ServiceClassName[2],
@@ -1241,429 +1030,338 @@ static VOID DumpCmControlPacket(PVOID pvBuffer)
 			pstAddIndication->sfAdmittedSet.u8ServiceClassName[4],
 			pstAddIndication->sfAdmittedSet.u8ServiceClassName[5]);
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8MBSService				: 0x%02X",
-			pstAddIndication->sfAdmittedSet.u8MBSService);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8QosParamSet				: 0x%02X",
-			pstAddIndication->sfAdmittedSet.u8QosParamSet);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficPriority			: 0x%02X",
-			pstAddIndication->sfAdmittedSet.u8TrafficPriority);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaxTrafficBurst			: 0x%X",
-			pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MinReservedTrafficRate	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificQoSParamLength	: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificQoSParam		: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceFlowSchedulingType		: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32ToleratedJitter				: 0x%X",
-		pstAddIndication->sfAdmittedSet.u32ToleratedJitter);
-    BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaximumLatency				: 0x%X",
-		pstAddIndication->sfAdmittedSet.u32MaximumLatency);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8SDUSize			: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8SDUSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16TargetSAID		: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u16TargetSAID);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ARQEnable			: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8ARQEnable);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQWindowSize		: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQWindowSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQRetryTxTimeOut	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQRetryRxTimeOut	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQBlockLifeTime		: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQSyncLossTimeOut	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ARQDeliverInOrder		: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQRxPurgeTimeOut	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16ARQBlockSize			: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16ARQBlockSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8CSSpecification		: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8CSSpecification);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TypeOfDataDeliveryService	: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16SDUInterArrivalTime	: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16TimeBase				: 0x%X",
-		pstAddIndication->sfAdmittedSet.u16TimeBase);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8PagingPreference		: 0x%X",
-		pstAddIndication->sfAdmittedSet.u8PagingPreference);
-
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficIndicationPreference	: 0x%02X",
-		pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " Total Classifiers Received		: 0x%X",pstAddIndication->sfAdmittedSet.u8TotalClassifiers);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfAdmittedSet.u8MBSService);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfAdmittedSet.u8QosParamSet);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfAdmittedSet.u8TrafficPriority);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X",
+			pstAddIndication->sfAdmittedSet.u32MinReservedTrafficRate);
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X",
+			pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParamLength);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X",
+			pstAddIndication->sfAdmittedSet.u8VendorSpecificQoSParam[0]);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X",
+			pstAddIndication->sfAdmittedSet.u8ServiceFlowSchedulingType);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfAdmittedSet.u32ToleratedJitter);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X", pstAddIndication->sfAdmittedSet.u32MaximumLatency);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X",
+			pstAddIndication->sfAdmittedSet.u8FixedLengthVSVariableLengthSDUIndicator);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%02X", pstAddIndication->sfAdmittedSet.u8SDUSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TargetSAID: 0x%02X", pstAddIndication->sfAdmittedSet.u16TargetSAID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQEnable: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQEnable);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQWindowSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQWindowSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryTxTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRetryRxTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockLifeTime);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQSyncLossTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ARQDeliverInOrder: 0x%02X", pstAddIndication->sfAdmittedSet.u8ARQDeliverInOrder);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQRxPurgeTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16ARQBlockSize: 0x%X", pstAddIndication->sfAdmittedSet.u16ARQBlockSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8CSSpecification: 0x%02X", pstAddIndication->sfAdmittedSet.u8CSSpecification);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TypeOfDataDeliveryService: 0x%02X",
+			pstAddIndication->sfAdmittedSet.u8TypeOfDataDeliveryService);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfAdmittedSet.u16SDUInterArrivalTime);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16TimeBase: 0x%X", pstAddIndication->sfAdmittedSet.u16TimeBase);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference: 0x%X", pstAddIndication->sfAdmittedSet.u8PagingPreference);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference: 0x%02X",
+			pstAddIndication->sfAdmittedSet.u8TrafficIndicationPreference);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfAdmittedSet.u8TotalClassifiers);
 
 	nCurClassifierCnt = pstAddIndication->sfAdmittedSet.u8TotalClassifiers;
-
-	if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
-	{
+	if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
 		nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
-	}
-
-
-	for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++)
-	{
 
+	for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++) {
 		stConvergenceSLTypes *psfCSType = NULL;
-		psfCSType =  &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex];
 
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " CCPacketClassificationRuleSI====>");
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ClassifierRulePriority	:0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPTypeOfServiceLength		:0x%02X",
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPTypeOfService[3]		:0x%02X %02X %02X",
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
-		for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Protocol: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8Protocol);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPMaskedSourceAddressLength	:0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
-
-		for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPMaskedSourceAddress[32] : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPDestinationAddressLength	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
-
-		for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPDestinationAddress[32] : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolSourcePortRangeLength	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolSourcePortRange[4] : 0x %02X %02X %02X %02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolDestPortRangeLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ProtocolDestPortRange[4] : 0x %02X %02X %02X %02X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetDestMacAddressLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetDestMacAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetSourceMACAddressLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetSourceMACAddress[6] : 0x %02X %02X %02X %02X %02X %02X",
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthertypeLength  	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8EthertypeLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8Ethertype[3]		: 0x%02X %02X %02X",
-			psfCSType->cCPacketClassificationRule.u8Ethertype[0],
-			psfCSType->cCPacketClassificationRule.u8Ethertype[1],
-			psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16UserPriority 	: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u16UserPriority);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16VLANID			: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u16VLANID);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8AssociatedPHSI	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16PacketClassificationRuleIndex	: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificClassifierParamLength	: 0x%02X",
-			psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificClassifierParam[1] 	: 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
+		psfCSType =  &pstAddIndication->sfAdmittedSet.cConvergenceSLTypes[nIndex];
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ClassifierRulePriority: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfServiceLength: 0x%02X",
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPTypeOfService[3]: 0x%02X %02X %02X",
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
+		for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%02X ",
+					psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddress[32]: 0x%02X ",
+					psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRangeLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolSourcePortRange[4]: 0x %02X %02X %02X %02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRangeLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolDestPortRange[4]: 0x %02X %02X %02X %02X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetDestMacAddress[6]: 0x %02X %02X %02X %02X %02X %02X",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: 0x %02X %02X %02X %02X %02X %02X",
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthertypeLength: 0x%02X ", psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Ethertype[3]: 0x%02X %02X %02X",
+				psfCSType->cCPacketClassificationRule.u8Ethertype[0],
+				psfCSType->cCPacketClassificationRule.u8Ethertype[1],
+				psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UserPriority: 0x%X ", psfCSType->cCPacketClassificationRule.u16UserPriority);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8AssociatedPHSI: 0x%02X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16PacketClassificationRuleIndex: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParamLength: 0x%02X",
+				psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificClassifierParam[1]: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
 #ifdef VERSION_D5
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPv6FlowLableLength				: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPv6FlowLable[6]	: 0x %02X %02X %02X %02X %02X %02X ",
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLableLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPv6FlowLable[6]: 0x %02X %02X %02X %02X %02X %02X ",
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
 #endif
 	}
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "bValid		: 0x%X",pstAddIndication->sfAdmittedSet.bValid);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " ActiveSet--->");
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32SFID		: 0x%X",pstAddIndication->sfActiveSet.u32SFID);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u16CID		: 0x%X",pstAddIndication->sfActiveSet.u16CID);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceClassNameLength	: 0x%X",
-		pstAddIndication->sfActiveSet.u8ServiceClassNameLength);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceClassName		: 0x %02X %02X %02X %02X %02X %02X",
-		pstAddIndication->sfActiveSet.u8ServiceClassName[0],
-		pstAddIndication->sfActiveSet.u8ServiceClassName[1],
-		pstAddIndication->sfActiveSet.u8ServiceClassName[2],
-		pstAddIndication->sfActiveSet.u8ServiceClassName[3],
-		pstAddIndication->sfActiveSet.u8ServiceClassName[4],
-		pstAddIndication->sfActiveSet.u8ServiceClassName[5]);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8MBSService				: 0x%02X",
-		pstAddIndication->sfActiveSet.u8MBSService);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8QosParamSet				: 0x%02X",
-		pstAddIndication->sfActiveSet.u8QosParamSet);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8TrafficPriority			: 0x%02X",
-		pstAddIndication->sfActiveSet.u8TrafficPriority);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaxTrafficBurst			: 0x%X",
-		pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MinReservedTrafficRate	: 0x%X",
-		pstAddIndication->sfActiveSet.u32MinReservedTrafficRate);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificQoSParamLength	: 0x%02X",
-		pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8VendorSpecificQoSParam		: 0x%02X",
-		pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8ServiceFlowSchedulingType		: 0x%02X",
-		pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32ToleratedJitter				: 0x%X",
-		pstAddIndication->sfActiveSet.u32ToleratedJitter);
-    BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u32MaximumLatency				: 0x%X",
-		pstAddIndication->sfActiveSet.u32MaximumLatency);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X",
-	   pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8SDUSize				: 0x%X",
-		pstAddIndication->sfActiveSet.u8SDUSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16TargetSAID			: 0x%X",
-		pstAddIndication->sfActiveSet.u16TargetSAID);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ARQEnable			: 0x%X",
-		pstAddIndication->sfActiveSet.u8ARQEnable);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQWindowSize		: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQWindowSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQRetryTxTimeOut	: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQRetryRxTimeOut	: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQBlockLifeTime	: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQBlockLifeTime);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQSyncLossTimeOut	: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ARQDeliverInOrder	: 0x%X",
-		pstAddIndication->sfActiveSet.u8ARQDeliverInOrder);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQRxPurgeTimeOut	: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16ARQBlockSize		: 0x%X",
-		pstAddIndication->sfActiveSet.u16ARQBlockSize);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8CSSpecification		: 0x%X",
-		pstAddIndication->sfActiveSet.u8CSSpecification);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8TypeOfDataDeliveryService	: 0x%X",
-		pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16SDUInterArrivalTime	: 0x%X",
-		pstAddIndication->sfActiveSet.u16SDUInterArrivalTime);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16TimeBase			: 0x%X",
-		pstAddIndication->sfActiveSet.u16TimeBase);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8PagingPreference		: 0x%X",
-		pstAddIndication->sfActiveSet.u8PagingPreference);
-
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8TrafficIndicationPreference	: 0x%X",
-		pstAddIndication->sfActiveSet.u8TrafficIndicationPreference);
-
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " Total Classifiers Received		: 0x%X",pstAddIndication->sfActiveSet.u8TotalClassifiers);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "bValid: 0x%X", pstAddIndication->sfAdmittedSet.bValid);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " ActiveSet--->");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32SFID: 0x%X", pstAddIndication->sfActiveSet.u32SFID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16CID: 0x%X", pstAddIndication->sfActiveSet.u16CID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassNameLength: 0x%X", pstAddIndication->sfActiveSet.u8ServiceClassNameLength);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceClassName: 0x %02X %02X %02X %02X %02X %02X",
+			pstAddIndication->sfActiveSet.u8ServiceClassName[0],
+			pstAddIndication->sfActiveSet.u8ServiceClassName[1],
+			pstAddIndication->sfActiveSet.u8ServiceClassName[2],
+			pstAddIndication->sfActiveSet.u8ServiceClassName[3],
+			pstAddIndication->sfActiveSet.u8ServiceClassName[4],
+			pstAddIndication->sfActiveSet.u8ServiceClassName[5]);
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8MBSService: 0x%02X", pstAddIndication->sfActiveSet.u8MBSService);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8QosParamSet: 0x%02X", pstAddIndication->sfActiveSet.u8QosParamSet);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority: 0x%02X", pstAddIndication->sfActiveSet.u8TrafficPriority);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst: 0x%X", pstAddIndication->sfActiveSet.u32MaxTrafficBurst);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate: 0x%X",
+			pstAddIndication->sfActiveSet.u32MinReservedTrafficRate);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength: 0x%02X",
+			pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam: 0x%02X",
+			pstAddIndication->sfActiveSet.u8VendorSpecificQoSParam[0]);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ServiceFlowSchedulingType: 0x%02X",
+			pstAddIndication->sfActiveSet.u8ServiceFlowSchedulingType);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32ToleratedJitter: 0x%X", pstAddIndication->sfActiveSet.u32ToleratedJitter);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaximumLatency: 0x%X",	pstAddIndication->sfActiveSet.u32MaximumLatency);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8FixedLengthVSVariableLengthSDUIndicator: 0x%02X",
+			pstAddIndication->sfActiveSet.u8FixedLengthVSVariableLengthSDUIndicator);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8SDUSize: 0x%X",	pstAddIndication->sfActiveSet.u8SDUSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TargetSAID: 0x%X", pstAddIndication->sfActiveSet.u16TargetSAID);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQEnable: 0x%X", pstAddIndication->sfActiveSet.u8ARQEnable);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQWindowSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQWindowSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryTxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryTxTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRetryRxTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRetryRxTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockLifeTime: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockLifeTime);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQSyncLossTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQSyncLossTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ARQDeliverInOrder: 0x%X", pstAddIndication->sfActiveSet.u8ARQDeliverInOrder);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQRxPurgeTimeOut: 0x%X", pstAddIndication->sfActiveSet.u16ARQRxPurgeTimeOut);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16ARQBlockSize: 0x%X", pstAddIndication->sfActiveSet.u16ARQBlockSize);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8CSSpecification: 0x%X", pstAddIndication->sfActiveSet.u8CSSpecification);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TypeOfDataDeliveryService: 0x%X",
+			pstAddIndication->sfActiveSet.u8TypeOfDataDeliveryService);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16SDUInterArrivalTime: 0x%X", pstAddIndication->sfActiveSet.u16SDUInterArrivalTime);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16TimeBase: 0x%X", pstAddIndication->sfActiveSet.u16TimeBase);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference: 0x%X", pstAddIndication->sfActiveSet.u8PagingPreference);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference: 0x%X",
+			pstAddIndication->sfActiveSet.u8TrafficIndicationPreference);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " Total Classifiers Received: 0x%X", pstAddIndication->sfActiveSet.u8TotalClassifiers);
 
 	nCurClassifierCnt = pstAddIndication->sfActiveSet.u8TotalClassifiers;
-
-	if(nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
-	{
+	if (nCurClassifierCnt > MAX_CLASSIFIERS_IN_SF)
 		nCurClassifierCnt = MAX_CLASSIFIERS_IN_SF;
-	}
-
-	for(nIndex = 0 ; nIndex < nCurClassifierCnt ; nIndex++)
-	{
 
+	for (nIndex = 0; nIndex < nCurClassifierCnt; nIndex++)	{
 		stConvergenceSLTypes *psfCSType = NULL;
-		psfCSType =  &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex];
-
 
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " CCPacketClassificationRuleSI====>");
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ClassifierRulePriority		:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8IPTypeOfServiceLength		:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8IPTypeOfService[3]			:0x%X ,0x%X ,0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
-			psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
-		for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8Protocol	: 0x%X ",
-			psfCSType->cCPacketClassificationRule.u8Protocol);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPMaskedSourceAddressLength	:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
-
-		for(uiLoopIndex=0; uiLoopIndex < 32; uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPMaskedSourceAddress[32]:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8IPDestinationAddressLength : 0x%02X ",
-			psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
-
-		for(uiLoopIndex=0;uiLoopIndex<32;uiLoopIndex++)
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8IPDestinationAddress[32]:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ProtocolSourcePortRangeLength:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ProtocolSourcePortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
-			psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ProtocolDestPortRangeLength:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8ProtocolDestPortRange[4]:0x%X ,0x%X ,0x%X ,0x%X ",
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
-			psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8EthernetDestMacAddressLength:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8EthernetDestMacAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8EthernetSourceMACAddressLength:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  "u8EthernetSourceMACAddress[6]:0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X",
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
-			psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8EthertypeLength              :0x%X ",
-			psfCSType->cCPacketClassificationRule.u8EthertypeLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8Ethertype[3]                 :0x%X ,0x%X ,0x%X ",
-			psfCSType->cCPacketClassificationRule.u8Ethertype[0],
-			psfCSType->cCPacketClassificationRule.u8Ethertype[1],
-			psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16UserPriority                :0x%X ",
-			psfCSType->cCPacketClassificationRule.u16UserPriority);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16VLANID                      :0x%X ",
-			psfCSType->cCPacketClassificationRule.u16VLANID);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8AssociatedPHSI               :0x%X ",
-			psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u16PacketClassificationRuleIndex:0x%X ",
-			psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
-
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8VendorSpecificClassifierParamLength:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8VendorSpecificClassifierParam[1]:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
+		psfCSType =  &pstAddIndication->sfActiveSet.cConvergenceSLTypes[nIndex];
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " CCPacketClassificationRuleSI====>");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ClassifierRulePriority: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ClassifierRulePriority);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfServiceLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfServiceLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPTypeOfService[3]: 0x%X ,0x%X ,0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0],
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1],
+				psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 1; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol: 0x%X ", psfCSType->cCPacketClassificationRule.u8Protocol);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddressLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddressLength);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPMaskedSourceAddress[32]: 0x%X ",
+					psfCSType->cCPacketClassificationRule.u8IPMaskedSourceAddress[uiLoopIndex]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8IPDestinationAddressLength: 0x%02X ",
+				psfCSType->cCPacketClassificationRule.u8IPDestinationAddressLength);
+
+		for (uiLoopIndex = 0; uiLoopIndex < 32; uiLoopIndex++)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPDestinationAddress[32]:0x%X ",
+					psfCSType->cCPacketClassificationRule.u8IPDestinationAddress[uiLoopIndex]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRangeLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRangeLength);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolSourcePortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[0],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[1],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[2],
+				psfCSType->cCPacketClassificationRule.u8ProtocolSourcePortRange[3]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRangeLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRangeLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8ProtocolDestPortRange[4]: 0x%X ,0x%X ,0x%X ,0x%X ",
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[0],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[1],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[2],
+				psfCSType->cCPacketClassificationRule.u8ProtocolDestPortRange[3]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddressLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetDestMacAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[0],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[1],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[2],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[3],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[4],
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddress[5]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthernetSourceMACAddressLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8EthernetDestMacAddressLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8EthernetSourceMACAddress[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X",
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[0],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[1],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[2],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[3],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[4],
+				psfCSType->cCPacketClassificationRule.u8EthernetSourceMACAddress[5]);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8EthertypeLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8EthertypeLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Ethertype[3]: 0x%X ,0x%X ,0x%X ",
+				psfCSType->cCPacketClassificationRule.u8Ethertype[0],
+				psfCSType->cCPacketClassificationRule.u8Ethertype[1],
+				psfCSType->cCPacketClassificationRule.u8Ethertype[2]);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16UserPriority: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u16UserPriority);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16VLANID: 0x%X ", psfCSType->cCPacketClassificationRule.u16VLANID);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8AssociatedPHSI: 0x%X ", psfCSType->cCPacketClassificationRule.u8AssociatedPHSI);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u16PacketClassificationRuleIndex:0x%X ",
+				psfCSType->cCPacketClassificationRule.u16PacketClassificationRuleIndex);
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParamLength:0x%X ",
+				psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParamLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8VendorSpecificClassifierParam[1]:0x%X ",
+				psfCSType->cCPacketClassificationRule.u8VendorSpecificClassifierParam[0]);
 #ifdef VERSION_D5
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8IPv6FlowLableLength				:0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " u8IPv6FlowLable[6]	    :0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ",
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
-			psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLableLength: 0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLableLength);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8IPv6FlowLable[6]: 0x%X ,0x%X ,0x%X ,0x%X ,0x%X ,0x%X ",
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[0],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[1],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[2],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[3],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[4],
+				psfCSType->cCPacketClassificationRule.u8IPv6FlowLable[5]);
 #endif
 	}
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL,  " bValid			: 0x%X",pstAddIndication->sfActiveSet.bValid);
-
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " bValid: 0x%X", pstAddIndication->sfActiveSet.bValid);
 }
 
-static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet,PUCHAR pucDestBuffer)
+static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet, PUCHAR pucDestBuffer)
 {
 	UINT  nBytesToRead = sizeof(stServiceFlowParamSI);
 
-	if(ulAddrSFParamSet == 0 || NULL == pucDestBuffer)
-	{
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Got Param address as 0!!");
+	if (ulAddrSFParamSet == 0 || NULL == pucDestBuffer) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Got Param address as 0!!");
 		return 0;
 	}
 	ulAddrSFParamSet = ntohl(ulAddrSFParamSet);
 
-	//Read out the SF Param Set At the indicated Location
-	if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
+	/* Read out the SF Param Set At the indicated Location */
+	if (rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0)
 		return STATUS_FAILURE;
 
 	return 1;
 }
 
-
-static ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG  ulAddrSFParamSet)
+static ULONG StoreSFParam(PMINI_ADAPTER Adapter, PUCHAR pucSrcBuffer, ULONG ulAddrSFParamSet)
 {
-    UINT	nBytesToWrite = sizeof(stServiceFlowParamSI);
+	UINT nBytesToWrite = sizeof(stServiceFlowParamSI);
 	int ret = 0;
 
-	if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
-	{
+	if (ulAddrSFParamSet == 0 || NULL == pucSrcBuffer)
 		return 0;
-	}
 
 	ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite);
 	if (ret < 0) {
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "%s:%d WRM failed",__FUNCTION__, __LINE__);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed", __func__, __LINE__);
 		return ret;
 	}
 	return 1;
 }
 
-ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength)
+ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter, PVOID pvBuffer, UINT *puBufferLength)
 {
 	stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL;
-	stLocalSFAddIndication *  pstAddIndication = NULL;
+	stLocalSFAddIndication *pstAddIndication = NULL;
 	stLocalSFDeleteRequest *pstDeletionRequest;
 	UINT uiSearchRuleIndex;
 	ULONG ulSFID;
@@ -1671,52 +1369,47 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
 	pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer);
 
 	/*
-	*	In case of DSD Req By MS, we should immediately delete this SF so that
-	*	we can stop the further classifying the pkt for this SF.
-	*/
-	if(pstAddIndicationAlt->u8Type == DSD_REQ)
-	{
+	 * In case of DSD Req By MS, we should immediately delete this SF so that
+	 * we can stop the further classifying the pkt for this SF.
+	 */
+	if (pstAddIndicationAlt->u8Type == DSD_REQ) {
 		pstDeletionRequest = (stLocalSFDeleteRequest *)pvBuffer;
 
 		ulSFID = ntohl(pstDeletionRequest->u32SFID);
-		uiSearchRuleIndex=SearchSfid(Adapter,ulSFID);
+		uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);
 
-		if(uiSearchRuleIndex < NO_OF_QUEUES)
-		{
-			deleteSFBySfid(Adapter,uiSearchRuleIndex);
+		if (uiSearchRuleIndex < NO_OF_QUEUES) {
+			deleteSFBySfid(Adapter, uiSearchRuleIndex);
 			Adapter->u32TotalDSD++;
 		}
 		return 1;
 	}
 
-
-	if(	(pstAddIndicationAlt->u8Type == DSD_RSP) ||
-		(pstAddIndicationAlt->u8Type == DSD_ACK))
-	{
-		//No Special handling send the message as it is
+	if ((pstAddIndicationAlt->u8Type == DSD_RSP) ||
+		(pstAddIndicationAlt->u8Type == DSD_ACK)) {
+		/* No Special handling send the message as it is */
 		return 1;
 	}
-	// For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver!
+	/* For DSA_REQ, only up to "psfAuthorizedSet" parameter should be accessed by driver! */
 
-	pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
-	if(NULL==pstAddIndication)
+	pstAddIndication = kmalloc(sizeof(*pstAddIndication), GFP_KERNEL);
+	if (pstAddIndication == NULL)
 		return 0;
 
 	/* AUTHORIZED SET */
 	pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)
 			GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
-	if(!pstAddIndication->psfAuthorizedSet)
+	if (!pstAddIndication->psfAuthorizedSet)
 		return 0;
 
-	if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet,
-				(ULONG)pstAddIndication->psfAuthorizedSet)!= 1)
+	if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAuthorizedSet,
+				(ULONG)pstAddIndication->psfAuthorizedSet) != 1)
 		return 0;
 
 	/* this can't possibly be right */
 	pstAddIndication->psfAuthorizedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAuthorizedSet);
 
-	if(pstAddIndicationAlt->u8Type == DSA_REQ)
-	{
+	if (pstAddIndicationAlt->u8Type == DSA_REQ) {
 		stLocalSFAddRequest AddRequest;
 
 		AddRequest.u8Type = pstAddIndicationAlt->u8Type;
@@ -1724,18 +1417,17 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
 		AddRequest.u16TID = pstAddIndicationAlt->u16TID;
 		AddRequest.u16CID = pstAddIndicationAlt->u16CID;
 		AddRequest.u16VCID = pstAddIndicationAlt->u16VCID;
-		AddRequest.psfParameterSet =pstAddIndication->psfAuthorizedSet ;
+		AddRequest.psfParameterSet = pstAddIndication->psfAuthorizedSet;
 		(*puBufferLength) = sizeof(stLocalSFAddRequest);
-		memcpy(pvBuffer,&AddRequest,sizeof(stLocalSFAddRequest));
+		memcpy(pvBuffer, &AddRequest, sizeof(stLocalSFAddRequest));
 		return 1;
 	}
 
-	// Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt
-
-	//We need to extract the structure from the buffer and pack it differently
+	/* Since it's not DSA_REQ, we can access all field in pstAddIndicationAlt */
+	/* We need to extract the structure from the buffer and pack it differently */
 
 	pstAddIndication->u8Type = pstAddIndicationAlt->u8Type;
-	pstAddIndication->eConnectionDir= pstAddIndicationAlt->u8Direction ;
+	pstAddIndication->eConnectionDir = pstAddIndicationAlt->u8Direction;
 	pstAddIndication->u16TID = pstAddIndicationAlt->u16TID;
 	pstAddIndication->u16CID = pstAddIndicationAlt->u16CID;
 	pstAddIndication->u16VCID = pstAddIndicationAlt->u16VCID;
@@ -1744,20 +1436,19 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
 	/* ADMITTED SET */
 	pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)
 		GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
-	if(!pstAddIndication->psfAdmittedSet)
+	if (!pstAddIndication->psfAdmittedSet)
 		return 0;
-	if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfAdmittedSet,(ULONG)pstAddIndication->psfAdmittedSet) != 1)
+	if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfAdmittedSet, (ULONG)pstAddIndication->psfAdmittedSet) != 1)
 		return 0;
 
 	pstAddIndication->psfAdmittedSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfAdmittedSet);
 
-
 	/* ACTIVE SET */
 	pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)
 		GetNextTargetBufferLocation(Adapter, pstAddIndicationAlt->u16TID);
-	if(!pstAddIndication->psfActiveSet)
+	if (!pstAddIndication->psfActiveSet)
 		return 0;
-	if(StoreSFParam(Adapter,(PUCHAR)&pstAddIndicationAlt->sfActiveSet,(ULONG)pstAddIndication->psfActiveSet) != 1)
+	if (StoreSFParam(Adapter, (PUCHAR)&pstAddIndicationAlt->sfActiveSet, (ULONG)pstAddIndication->psfActiveSet) != 1)
 		return 0;
 
 	pstAddIndication->psfActiveSet = (stServiceFlowParamSI *)ntohl((ULONG)pstAddIndication->psfActiveSet);
@@ -1768,47 +1459,41 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p
 	return 1;
 }
 
-
 static inline stLocalSFAddIndicationAlt
-*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter,register PVOID pvBuffer)
+*RestoreCmControlResponseMessage(register PMINI_ADAPTER Adapter, register PVOID pvBuffer)
 {
-	ULONG ulStatus=0;
+	ULONG ulStatus = 0;
 	stLocalSFAddIndication *pstAddIndication = NULL;
 	stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL;
-	pstAddIndication = (stLocalSFAddIndication *)(pvBuffer);
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>" );
+	pstAddIndication = (stLocalSFAddIndication *)(pvBuffer);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>");
 	if ((pstAddIndication->u8Type == DSD_REQ) ||
 		(pstAddIndication->u8Type == DSD_RSP) ||
 		(pstAddIndication->u8Type == DSD_ACK))
-	{
 		return (stLocalSFAddIndicationAlt *)pvBuffer;
-	}
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage ");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage ");
 	/*
-	//Need to Allocate memory to contain the SUPER Large structures
-	//Our driver can't create these structures on Stack :(
-	*/
-	pstAddIndicationDest=kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL);
-
-	if(pstAddIndicationDest)
-	{
-		memset(pstAddIndicationDest,0,sizeof(stLocalSFAddIndicationAlt));
-	}
-	else
-	{
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure ");
+	 * Need to Allocate memory to contain the SUPER Large structures
+	 * Our driver can't create these structures on Stack :(
+	 */
+	pstAddIndicationDest = kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL);
+
+	if (pstAddIndicationDest) {
+		memset(pstAddIndicationDest, 0, sizeof(stLocalSFAddIndicationAlt));
+	} else {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure ");
 		return NULL;
 	}
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-u8Type : 0x%X",pstAddIndication->u8Type);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-u8Direction : 0x%X",pstAddIndication->eConnectionDir);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-u8TID : 0x%X",ntohs(pstAddIndication->u16TID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-u8CID : 0x%X",ntohs(pstAddIndication->u16CID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-u16VCID : 0x%X",ntohs(pstAddIndication->u16VCID));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-autorized set loc : %p",pstAddIndication->psfAuthorizedSet);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-admitted set loc : %p",pstAddIndication->psfAdmittedSet);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "AddIndication-Active set loc : %p",pstAddIndication->psfActiveSet);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Type : 0x%X", pstAddIndication->u8Type);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8Direction : 0x%X", pstAddIndication->eConnectionDir);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8TID : 0x%X", ntohs(pstAddIndication->u16TID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u8CID : 0x%X", ntohs(pstAddIndication->u16CID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-u16VCID : 0x%X", ntohs(pstAddIndication->u16VCID));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-autorized set loc : %p", pstAddIndication->psfAuthorizedSet);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-admitted set loc : %p", pstAddIndication->psfAdmittedSet);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "AddIndication-Active set loc : %p", pstAddIndication->psfActiveSet);
 
 	pstAddIndicationDest->u8Type = pstAddIndication->u8Type;
 	pstAddIndicationDest->u8Direction = pstAddIndication->eConnectionDir;
@@ -1817,42 +1502,39 @@ static inline stLocalSFAddIndicationAlt
 	pstAddIndicationDest->u16VCID = pstAddIndication->u16VCID;
 	pstAddIndicationDest->u8CC = pstAddIndication->u8CC;
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Restoring Active Set ");
-	ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfActiveSet, (PUCHAR)&pstAddIndicationDest->sfActiveSet);
-	if(ulStatus != 1)
-	{
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Restoring Active Set ");
+	ulStatus = RestoreSFParam(Adapter, (ULONG)pstAddIndication->psfActiveSet, (PUCHAR)&pstAddIndicationDest->sfActiveSet);
+	if (ulStatus != 1)
 		goto failed_restore_sf_param;
-	}
-	if(pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
+
+	if (pstAddIndicationDest->sfActiveSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
 		pstAddIndicationDest->sfActiveSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF;
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Restoring Admitted Set ");
-	ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAdmittedSet,(PUCHAR)&pstAddIndicationDest->sfAdmittedSet);
-	if(ulStatus != 1)
-	{
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Restoring Admitted Set ");
+	ulStatus = RestoreSFParam(Adapter, (ULONG)pstAddIndication->psfAdmittedSet, (PUCHAR)&pstAddIndicationDest->sfAdmittedSet);
+	if (ulStatus != 1)
 		goto failed_restore_sf_param;
-	}
-	if(pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
+
+	if (pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
 		pstAddIndicationDest->sfAdmittedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF;
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Restoring Authorized Set ");
-	ulStatus=RestoreSFParam(Adapter,(ULONG)pstAddIndication->psfAuthorizedSet,(PUCHAR)&pstAddIndicationDest->sfAuthorizedSet);
-	if(ulStatus != 1)
-	{
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Restoring Authorized Set ");
+	ulStatus = RestoreSFParam(Adapter, (ULONG)pstAddIndication->psfAuthorizedSet, (PUCHAR)&pstAddIndicationDest->sfAuthorizedSet);
+	if (ulStatus != 1)
 		goto failed_restore_sf_param;
-	}
-	if(pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
+
+	if (pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers > MAX_CLASSIFIERS_IN_SF)
 		pstAddIndicationDest->sfAuthorizedSet.u8TotalClassifiers = MAX_CLASSIFIERS_IN_SF;
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dumping the whole raw packet");
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " pstAddIndicationDest->sfActiveSet size  %zx %p", sizeof(*pstAddIndicationDest), pstAddIndicationDest);
-	//BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, sizeof(*pstAddIndicationDest));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Dumping the whole raw packet");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " pstAddIndicationDest->sfActiveSet size  %zx %p", sizeof(*pstAddIndicationDest), pstAddIndicationDest);
+	/* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, (unsigned char *)pstAddIndicationDest, sizeof(*pstAddIndicationDest)); */
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================");
 	return pstAddIndicationDest;
 failed_restore_sf_param:
 	kfree(pstAddIndicationDest);
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" );
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====");
 	return NULL;
 }
 
@@ -1860,7 +1542,7 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter)
 {
 	ULONG ulTargetDsxBuffersBase = 0;
 	ULONG ulCntTargetBuffers;
-	ULONG ulIndex=0;
+	ULONG i;
 	int Status;
 
 	if (!Adapter) {
@@ -1868,411 +1550,348 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter)
 		return 0;
 	}
 
-	if(Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer)
+	if (Adapter->astTargetDsxBuffer[0].ulTargetDsxBuffer)
 		return 1;
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %zx ",sizeof(stServiceFlowParamSI));
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ",DSX_MESSAGE_EXCHANGE_BUFFER);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Size of Each DSX Buffer(Also size of ServiceFlowParamSI): %zx ", sizeof(stServiceFlowParamSI));
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Reading DSX buffer From Target location %x ", DSX_MESSAGE_EXCHANGE_BUFFER);
 
- 	Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER,
-					(PUINT)&ulTargetDsxBuffersBase, sizeof(UINT));
-	if(Status < 0)
-	{
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "RDM failed!!");
+	Status = rdmalt(Adapter, DSX_MESSAGE_EXCHANGE_BUFFER, (PUINT)&ulTargetDsxBuffersBase, sizeof(UINT));
+	if (Status < 0) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "RDM failed!!");
 		return 0;
 	}
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX  Target Buffer : 0x%lx",ulTargetDsxBuffersBase);
-
-   	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Tgt Buffer is Now %lx :",ulTargetDsxBuffersBase);
-
-	ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE/sizeof(stServiceFlowParamSI);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Base Address Of DSX  Target Buffer : 0x%lx", ulTargetDsxBuffersBase);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "Tgt Buffer is Now %lx :", ulTargetDsxBuffersBase);
+	ulCntTargetBuffers = DSX_MESSAGE_EXCHANGE_BUFFER_SIZE / sizeof(stServiceFlowParamSI);
 
 	Adapter->ulTotalTargetBuffersAvailable =
 		ulCntTargetBuffers > MAX_TARGET_DSX_BUFFERS ?
 		MAX_TARGET_DSX_BUFFERS : ulCntTargetBuffers;
 
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Total Target DSX Buffer setup %lx ",Adapter->ulTotalTargetBuffersAvailable);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " Total Target DSX Buffer setup %lx ", Adapter->ulTotalTargetBuffersAvailable);
 
-	for(ulIndex=0; ulIndex < Adapter->ulTotalTargetBuffersAvailable ; ulIndex++)
-	{
-		Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer = ulTargetDsxBuffersBase;
-		Adapter->astTargetDsxBuffer[ulIndex].valid=1;
-		Adapter->astTargetDsxBuffer[ulIndex].tid=0;
-		ulTargetDsxBuffersBase+=sizeof(stServiceFlowParamSI);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "  Target DSX Buffer %lx setup at 0x%lx",
-			ulIndex, Adapter->astTargetDsxBuffer[ulIndex].ulTargetDsxBuffer);
+	for (i = 0; i < Adapter->ulTotalTargetBuffersAvailable; i++) {
+		Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer = ulTargetDsxBuffersBase;
+		Adapter->astTargetDsxBuffer[i].valid = 1;
+		Adapter->astTargetDsxBuffer[i].tid = 0;
+		ulTargetDsxBuffersBase += sizeof(stServiceFlowParamSI);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "  Target DSX Buffer %lx setup at 0x%lx",
+				i, Adapter->astTargetDsxBuffer[i].ulTargetDsxBuffer);
 	}
 	Adapter->ulCurrentTargetBuffer = 0;
 	Adapter->ulFreeTargetBufferCnt = Adapter->ulTotalTargetBuffersAvailable;
 	return 1;
 }
 
-static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid)
+static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter, B_UINT16 tid)
 {
-	ULONG  ulTargetDSXBufferAddress;
-	ULONG  ulTargetDsxBufferIndexToUse,ulMaxTry;
+	ULONG ulTargetDSXBufferAddress;
+	ULONG ulTargetDsxBufferIndexToUse, ulMaxTry;
 
-	if((Adapter->ulTotalTargetBuffersAvailable == 0)||
-			(Adapter->ulFreeTargetBufferCnt == 0))
-	{
-        ClearTargetDSXBuffer(Adapter,tid,FALSE);
+	if ((Adapter->ulTotalTargetBuffersAvailable == 0) || (Adapter->ulFreeTargetBufferCnt == 0)) {
+		ClearTargetDSXBuffer(Adapter, tid, FALSE);
 		return 0;
 	}
 
-    ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer;
-    ulMaxTry = Adapter->ulTotalTargetBuffersAvailable;
-	while((ulMaxTry)&&(Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1))
-	{
-		 ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%
-					Adapter->ulTotalTargetBuffersAvailable;
-		 ulMaxTry--;
+	ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer;
+	ulMaxTry = Adapter->ulTotalTargetBuffersAvailable;
+	while ((ulMaxTry) && (Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) {
+		ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1) % Adapter->ulTotalTargetBuffersAvailable;
+		ulMaxTry--;
 	}
 
-	if(ulMaxTry==0)
-	{
-		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ",Adapter->ulFreeTargetBufferCnt);
-		ClearTargetDSXBuffer(Adapter,tid,FALSE);
+	if (ulMaxTry == 0) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", Adapter->ulFreeTargetBufferCnt);
+		ClearTargetDSXBuffer(Adapter, tid, FALSE);
 		return 0;
 	}
 
-
-	ulTargetDSXBufferAddress =
-		Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer;
-	Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid=0;
-	Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid=tid;
+	ulTargetDSXBufferAddress = Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer;
+	Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid = 0;
+	Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid = tid;
 	Adapter->ulFreeTargetBufferCnt--;
-
-
-	ulTargetDsxBufferIndexToUse =
-		(ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable;
+	ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable;
 	Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse;
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n",
-		ulTargetDSXBufferAddress,tid);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", ulTargetDSXBufferAddress, tid);
+
 	return ulTargetDSXBufferAddress;
 }
 
-
-INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter)
+int AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter)
 {
 	/*
-	//Need to Allocate memory to contain the SUPER Large structures
-	//Our driver can't create these structures on Stack
-	*/
-	Adapter->caDsxReqResp=kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL);
-	if(!Adapter->caDsxReqResp)
+	 * Need to Allocate memory to contain the SUPER Large structures
+	 * Our driver can't create these structures on Stack
+	 */
+	Adapter->caDsxReqResp = kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL);
+	if (!Adapter->caDsxReqResp)
 		return -ENOMEM;
+
 	return 0;
 }
 
-INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter)
+int FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter)
 {
 	kfree(Adapter->caDsxReqResp);
 	return 0;
-
 }
-/**
-@ingroup ctrl_pkt_functions
-This routinue would process the Control responses
-for the Connection Management.
-@return	  - Queue index for the free SFID else returns Invalid Index.
-*/
-BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,  /**<Pointer to the Adapter structure*/
-											PVOID pvBuffer /**Starting Address of the Buffer, that contains the AddIndication Data*/
-											)
+
+/*
+ * @ingroup ctrl_pkt_functions
+ * This routinue would process the Control responses
+ * for the Connection Management.
+ * @return - Queue index for the free SFID else returns Invalid Index.
+ */
+BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,  /* <Pointer to the Adapter structure */
+				PVOID pvBuffer /* Starting Address of the Buffer, that contains the AddIndication Data */)
 {
-	stServiceFlowParamSI			*psfLocalSet=NULL;
-	stLocalSFAddIndicationAlt 	 	*pstAddIndication = NULL;
-	stLocalSFChangeIndicationAlt 	*pstChangeIndication = NULL;
-	PLEADER							pLeader=NULL;
+	stServiceFlowParamSI *psfLocalSet = NULL;
+	stLocalSFAddIndicationAlt *pstAddIndication = NULL;
+	stLocalSFChangeIndicationAlt *pstChangeIndication = NULL;
+	PLEADER pLeader = NULL;
+
 	/*
-	//Otherwise the message contains a target address from where we need to
-	//read out the rest of the service flow param structure
-	*/
-	if((pstAddIndication = RestoreCmControlResponseMessage(Adapter,pvBuffer))
-			== NULL)
-	{
-		ClearTargetDSXBuffer(Adapter,((stLocalSFAddIndication *)pvBuffer)->u16TID, FALSE);
-		BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message");
+	 * Otherwise the message contains a target address from where we need to
+	 * read out the rest of the service flow param structure
+	 */
+	pstAddIndication = RestoreCmControlResponseMessage(Adapter, pvBuffer);
+	if (pstAddIndication == NULL) {
+		ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndication *)pvBuffer)->u16TID, FALSE);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Error in restoring Service Flow param structure from DSx message");
 		return FALSE;
 	}
 
 	DumpCmControlPacket(pstAddIndication);
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>");
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "====>");
 	pLeader = (PLEADER)Adapter->caDsxReqResp;
 
-	pLeader->Status =CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ;
+	pLeader->Status = CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ;
 	pLeader->Vcid = 0;
 
-	ClearTargetDSXBuffer(Adapter,pstAddIndication->u16TID,FALSE);
-    BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n",pstAddIndication->u16TID);
-	switch(pstAddIndication->u8Type)
+	ClearTargetDSXBuffer(Adapter, pstAddIndication->u16TID, FALSE);
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "### TID RECEIVED %d\n", pstAddIndication->u16TID);
+	switch (pstAddIndication->u8Type) {
+	case DSA_REQ:
 	{
-		case DSA_REQ:
-		{
-			pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n");
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength );
-			*((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))
-						= *pstAddIndication;
-			((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
-
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,  " VCID = %x", ntohs(pstAddIndication->u16VCID));
-			CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
-			kfree(pstAddIndication);
-		}
-		break;
-		case DSA_RSP:
-		{
-			pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d",
+		pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n");
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength);
+		*((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
+			= *pstAddIndication;
+		((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP;
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID));
+		CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
+		kfree(pstAddIndication);
+	}
+	break;
+	case DSA_RSP:
+	{
+		pLeader->PLength = sizeof(stLocalSFAddIndicationAlt);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d",
 				pLeader->PLength);
-			*((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))
-						= *pstAddIndication;
-			((stLocalSFAddIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
+		*((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))
+			= *pstAddIndication;
+		((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK;
 
-		}//no break here..we should go down.
-		case DSA_ACK:
-		{
-			UINT uiSearchRuleIndex=0;
+	} /* no break here..we should go down. */
+	case DSA_ACK:
+	{
+		UINT uiSearchRuleIndex = 0;
 
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "VCID:0x%X",
 				ntohs(pstAddIndication->u16VCID));
-            uiSearchRuleIndex=SearchFreeSfid(Adapter);
-            BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"uiSearchRuleIndex:0x%X ",
+		uiSearchRuleIndex = SearchFreeSfid(Adapter);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "uiSearchRuleIndex:0x%X ",
 				uiSearchRuleIndex);
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Direction:0x%X ",
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Direction:0x%X ",
 				pstAddIndication->u8Direction);
-			if((uiSearchRuleIndex< NO_OF_QUEUES) )
-			{
-				Adapter->PackInfo[uiSearchRuleIndex].ucDirection =
-					pstAddIndication->u8Direction;
-                BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ",
+		if ((uiSearchRuleIndex < NO_OF_QUEUES)) {
+			Adapter->PackInfo[uiSearchRuleIndex].ucDirection =
+				pstAddIndication->u8Direction;
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "bValid:0x%X ",
 					pstAddIndication->sfActiveSet.bValid);
-				if(pstAddIndication->sfActiveSet.bValid==TRUE)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE;
-				}
-				if(pstAddIndication->sfAuthorizedSet.bValid==TRUE)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE;
-				}
-				if(pstAddIndication->sfAdmittedSet.bValid==TRUE)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE;
-				}
-				if(FALSE == pstAddIndication->sfActiveSet.bValid)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-					Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
-					if(pstAddIndication->sfAdmittedSet.bValid)
-					{
-						psfLocalSet = &pstAddIndication->sfAdmittedSet;
-					}
-					else if(pstAddIndication->sfAuthorizedSet.bValid)
-					{
-						psfLocalSet = &pstAddIndication->sfAuthorizedSet;
-					}
-				}
-				else
-				{
-					psfLocalSet = &pstAddIndication->sfActiveSet;
-					Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE;
-				}
-
-				if(!psfLocalSet)
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No set is valid\n");
-					Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
-                    Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
-					Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
-					kfree(pstAddIndication);
-				}
+			if (pstAddIndication->sfActiveSet.bValid == TRUE)
+				Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE;
+
+			if (pstAddIndication->sfAuthorizedSet.bValid == TRUE)
+				Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE;
+
+			if (pstAddIndication->sfAdmittedSet.bValid == TRUE)
+				Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE;
+
+			if (pstAddIndication->sfActiveSet.bValid == FALSE) {
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+				Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
+				if (pstAddIndication->sfAdmittedSet.bValid)
+					psfLocalSet = &pstAddIndication->sfAdmittedSet;
+				else if (pstAddIndication->sfAuthorizedSet.bValid)
+					psfLocalSet = &pstAddIndication->sfAuthorizedSet;
+			} else {
+				psfLocalSet = &pstAddIndication->sfActiveSet;
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE;
+			}
 
-				else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0))
-				{
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK");
-					Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value =
-						ntohs(pstAddIndication->u16VCID);
-					Adapter->PackInfo[uiSearchRuleIndex].usCID =
-						ntohs(pstAddIndication->u16CID);
-
-					if(UPLINK_DIR == pstAddIndication->u8Direction)
-						atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT);
-					CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex,
-								DSA_ACK, pstAddIndication);
-					// don't free pstAddIndication
-
-					/* Inside CopyToAdapter, Sorting of all the SFs take place.
-					    Hence any access to the newly added SF through uiSearchRuleIndex is invalid.
-					    SHOULD BE STRICTLY AVOIDED.
-					*/
-//					*(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID;
-					memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4);
-
-					if(pstAddIndication->sfActiveSet.bValid == TRUE)
-					{
-						if(UPLINK_DIR == pstAddIndication->u8Direction)
-						{
-							if(!Adapter->LinkUpStatus)
-							{
-								netif_carrier_on(Adapter->dev);
-								netif_start_queue(Adapter->dev);
-								Adapter->LinkUpStatus = 1;
-								if (netif_msg_link(Adapter))
-									pr_info(PFX "%s: link up\n", Adapter->dev->name);
-								atomic_set(&Adapter->TxPktAvail, 1);
-								wake_up(&Adapter->tx_packet_wait_queue);
-								Adapter->liTimeSinceLastNetEntry = get_seconds();
-							}
+			if (!psfLocalSet) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No set is valid\n");
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+				Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE;
+				Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0;
+				kfree(pstAddIndication);
+			} else if (psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) {
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSA ACK");
+				Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstAddIndication->u16VCID);
+				Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstAddIndication->u16CID);
+
+				if (UPLINK_DIR == pstAddIndication->u8Direction)
+					atomic_set(&Adapter->PackInfo[uiSearchRuleIndex].uiPerSFTxResourceCount, DEFAULT_PERSFCOUNT);
+
+				CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSA_ACK, pstAddIndication);
+				/* don't free pstAddIndication */
+
+				/* Inside CopyToAdapter, Sorting of all the SFs take place.
+				 * Hence any access to the newly added SF through uiSearchRuleIndex is invalid.
+				 * SHOULD BE STRICTLY AVOIDED.
+				 */
+				/* *(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID; */
+				memcpy((((PUCHAR)pvBuffer)+1), &psfLocalSet->u32SFID, 4);
+
+				if (pstAddIndication->sfActiveSet.bValid == TRUE) {
+					if (UPLINK_DIR == pstAddIndication->u8Direction) {
+						if (!Adapter->LinkUpStatus) {
+							netif_carrier_on(Adapter->dev);
+							netif_start_queue(Adapter->dev);
+							Adapter->LinkUpStatus = 1;
+							if (netif_msg_link(Adapter))
+								pr_info(PFX "%s: link up\n", Adapter->dev->name);
+							atomic_set(&Adapter->TxPktAvail, 1);
+							wake_up(&Adapter->tx_packet_wait_queue);
+							Adapter->liTimeSinceLastNetEntry = get_seconds();
 						}
 					}
 				}
-
-				else
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
-                    Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE;
-					Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0;
-					kfree(pstAddIndication);
-				}
-			}
-			else
-			{
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
+			} else {
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+				Adapter->PackInfo[uiSearchRuleIndex].bValid = FALSE;
+				Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = 0;
 				kfree(pstAddIndication);
-				return FALSE;
 			}
-		}
-		break;
-		case DSC_REQ:
-		{
-			pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
-			pstChangeIndication	= (stLocalSFChangeIndicationAlt*)pstAddIndication;
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength);
-
-			*((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
-			((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
-
-			CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID");
 			kfree(pstAddIndication);
+			return FALSE;
 		}
-		break;
-		case DSC_RSP:
-		{
-			pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
-			pstChangeIndication	= (stLocalSFChangeIndicationAlt*)pstAddIndication;
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength);
-			*((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
-			((stLocalSFChangeIndicationAlt*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
-		}
-		case DSC_ACK:
-		{
-			UINT uiSearchRuleIndex=0;
-
-			pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
-			uiSearchRuleIndex=SearchSfid(Adapter,ntohl(pstChangeIndication->sfActiveSet.u32SFID));
-			if(uiSearchRuleIndex > NO_OF_QUEUES-1)
-			{
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received");
-			}
-			if((uiSearchRuleIndex < NO_OF_QUEUES))
-			{
-				Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction;
-				if(pstChangeIndication->sfActiveSet.bValid==TRUE)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bActiveSet=TRUE;
-				}
-				if(pstChangeIndication->sfAuthorizedSet.bValid==TRUE)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet=TRUE;
-				}
-				if(pstChangeIndication->sfAdmittedSet.bValid==TRUE)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet=TRUE;
-				}
+	}
+	break;
+	case DSC_REQ:
+	{
+		pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
+		pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength);
 
-				if(FALSE==pstChangeIndication->sfActiveSet.bValid)
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
-					Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
-					if(pstChangeIndication->sfAdmittedSet.bValid)
-					{
-						psfLocalSet = &pstChangeIndication->sfAdmittedSet;
-					}
-					else if(pstChangeIndication->sfAuthorizedSet.bValid)
-					{
-						psfLocalSet = &pstChangeIndication->sfAuthorizedSet;
-					}
-				}
+		*((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
+		((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP;
 
-				else
-				{
-					psfLocalSet = &pstChangeIndication->sfActiveSet;
-					Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE;
-				}
-				if(psfLocalSet->bValid && (pstChangeIndication->u8CC == 0))
-				{
-					Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value =
-						ntohs(pstChangeIndication->u16VCID);
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n",
-							pstChangeIndication->u8CC, psfLocalSet->bValid);
-					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID));
-					Adapter->PackInfo[uiSearchRuleIndex].usCID =
-						ntohs(pstChangeIndication->u16CID);
-					CopyToAdapter(Adapter,psfLocalSet,uiSearchRuleIndex,
-								DSC_ACK, pstAddIndication);
-
-					*(PULONG)(((PUCHAR)pvBuffer)+1)=psfLocalSet->u32SFID;
-				}
-				else if(pstChangeIndication->u8CC == 6)
-				{
-					deleteSFBySfid(Adapter,uiSearchRuleIndex);
-					kfree(pstAddIndication);
-				}
+		CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
+		kfree(pstAddIndication);
+	}
+	break;
+	case DSC_RSP:
+	{
+		pLeader->PLength = sizeof(stLocalSFChangeIndicationAlt);
+		pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength);
+		*((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication;
+		((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK;
+	}
+	case DSC_ACK:
+	{
+		UINT uiSearchRuleIndex = 0;
+
+		pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication;
+		uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID));
+		if (uiSearchRuleIndex > NO_OF_QUEUES-1)
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received");
+
+		if ((uiSearchRuleIndex < NO_OF_QUEUES)) {
+			Adapter->PackInfo[uiSearchRuleIndex].ucDirection = pstChangeIndication->u8Direction;
+			if (pstChangeIndication->sfActiveSet.bValid == TRUE)
+				Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE;
+
+			if (pstChangeIndication->sfAuthorizedSet.bValid == TRUE)
+				Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE;
+
+			if (pstChangeIndication->sfAdmittedSet.bValid == TRUE)
+				Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE;
+
+			if (pstChangeIndication->sfActiveSet.bValid == FALSE) {
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
+				Adapter->PackInfo[uiSearchRuleIndex].bActivateRequestSent = FALSE;
+
+				if (pstChangeIndication->sfAdmittedSet.bValid)
+					psfLocalSet = &pstChangeIndication->sfAdmittedSet;
+				else if (pstChangeIndication->sfAuthorizedSet.bValid)
+					psfLocalSet = &pstChangeIndication->sfAuthorizedSet;
+			} else {
+				psfLocalSet = &pstChangeIndication->sfActiveSet;
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE;
 			}
-			else
-			{
-				BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
+
+			if (psfLocalSet->bValid && (pstChangeIndication->u8CC == 0)) {
+				Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pstChangeIndication->u16VCID);
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "CC field is %d bvalid = %d\n",
+						pstChangeIndication->u8CC, psfLocalSet->bValid);
+				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "VCID= %d\n", ntohs(pstChangeIndication->u16VCID));
+				Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pstChangeIndication->u16CID);
+				CopyToAdapter(Adapter, psfLocalSet, uiSearchRuleIndex, DSC_ACK, pstAddIndication);
+
+				*(PULONG)(((PUCHAR)pvBuffer)+1) = psfLocalSet->u32SFID;
+			} else if (pstChangeIndication->u8CC == 6) {
+				deleteSFBySfid(Adapter, uiSearchRuleIndex);
 				kfree(pstAddIndication);
-				return FALSE;
 			}
+		} else {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID");
+			kfree(pstAddIndication);
+			return FALSE;
 		}
-		break;
-		case DSD_REQ:
-		{
-			UINT uiSearchRuleIndex;
-			ULONG ulSFID;
-
-			pLeader->PLength = sizeof(stLocalSFDeleteIndication);
-			*((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication*)pstAddIndication);
+	}
+	break;
+	case DSD_REQ:
+	{
+		UINT uiSearchRuleIndex;
+		ULONG ulSFID;
 
-			ulSFID = ntohl(((stLocalSFDeleteIndication*)pstAddIndication)->u32SFID);
-			uiSearchRuleIndex=SearchSfid(Adapter,ulSFID);
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x",uiSearchRuleIndex);
+		pLeader->PLength = sizeof(stLocalSFDeleteIndication);
+		*((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *((stLocalSFDeleteIndication *)pstAddIndication);
 
-			if(uiSearchRuleIndex < NO_OF_QUEUES)
-			{
-				//Delete All Classifiers Associated with this SFID
-				deleteSFBySfid(Adapter,uiSearchRuleIndex);
-				Adapter->u32TotalDSD++;
-			}
+		ulSFID = ntohl(((stLocalSFDeleteIndication *)pstAddIndication)->u32SFID);
+		uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD - Removing connection %x", uiSearchRuleIndex);
 
-			BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC");
-			((stLocalSFDeleteIndication*)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP;
-			CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp);
-		}
-		case DSD_RSP:
-		{
-			//Do nothing as SF has already got Deleted
+		if (uiSearchRuleIndex < NO_OF_QUEUES) {
+			/* Delete All Classifiers Associated with this SFID */
+			deleteSFBySfid(Adapter, uiSearchRuleIndex);
+			Adapter->u32TotalDSD++;
 		}
-		break;
+
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSD RESPONSE TO MAC");
+		((stLocalSFDeleteIndication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSD_RSP;
+		CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp);
+	}
+	case DSD_RSP:
+	{
+		/* Do nothing as SF has already got Deleted */
+	}
+	break;
 	case DSD_ACK:
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
-			break;
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "DSD ACK Rcd, let App handle it\n");
+		break;
 	default:
 		kfree(pstAddIndication);
-		return FALSE ;
+		return FALSE;
 	}
 	return TRUE;
 }
@@ -2280,78 +1899,67 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,  /**<Pointer to the Adap
 int get_dsx_sf_data_to_application(PMINI_ADAPTER Adapter, UINT uiSFId, void __user *user_buffer)
 {
 	int status = 0;
-	struct _packet_info *psSfInfo=NULL;
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status);
+	struct _packet_info *psSfInfo = NULL;
+
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d", status);
 	status = SearchSfid(Adapter, uiSFId);
 	if (status >= NO_OF_QUEUES) {
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID %d not present in queue !!!", uiSFId );
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID %d not present in queue !!!", uiSFId);
 		return -EINVAL;
 	}
-	BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d",status);
-	psSfInfo=&Adapter->PackInfo[status];
-	if(psSfInfo->pstSFIndication && copy_to_user(user_buffer,
-		psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt)))
-	{
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId );
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d", status);
+	psSfInfo = &Adapter->PackInfo[status];
+	if (psSfInfo->pstSFIndication && copy_to_user(user_buffer,
+							psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) {
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId);
 		status = -EFAULT;
 		return status;
 	}
 	return STATUS_SUCCESS;
 }
 
-VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter,PUINT puiBuffer)
+VOID OverrideServiceFlowParams(PMINI_ADAPTER Adapter, PUINT puiBuffer)
 {
-	B_UINT32 u32NumofSFsinMsg    = ntohl(*(puiBuffer + 1));
+	B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1));
 	stIM_SFHostNotify *pHostInfo = NULL;
-	UINT uiSearchRuleIndex       = 0;
-	ULONG ulSFID                 = 0;
+	UINT uiSearchRuleIndex = 0;
+	ULONG ulSFID = 0;
 
-	puiBuffer+=2;
+	puiBuffer += 2;
+	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32NumofSFsinMsg: 0x%x\n", u32NumofSFsinMsg);
 
-	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32NumofSFsinMsg: 0x%x\n",u32NumofSFsinMsg);
-
-	while(u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES)
-	{
+	while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) {
 		u32NumofSFsinMsg--;
 		pHostInfo = (stIM_SFHostNotify *)puiBuffer;
 		puiBuffer = (PUINT)(pHostInfo + 1);
 
 		ulSFID = ntohl(pHostInfo->SFID);
-		uiSearchRuleIndex=SearchSfid(Adapter,ulSFID);
-		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"SFID: 0x%lx\n",ulSFID);
+		uiSearchRuleIndex = SearchSfid(Adapter, ulSFID);
+		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SFID: 0x%lx\n", ulSFID);
 
-		if(uiSearchRuleIndex >= NO_OF_QUEUES || uiSearchRuleIndex == HiPriority)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"The SFID <%lx> doesn't exist in host entry or is Invalid\n", ulSFID);
+		if (uiSearchRuleIndex >= NO_OF_QUEUES || uiSearchRuleIndex == HiPriority) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "The SFID <%lx> doesn't exist in host entry or is Invalid\n", ulSFID);
 			continue;
 		}
 
-		if(pHostInfo->RetainSF == FALSE)
-		{
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"Going to Delete SF");
-			deleteSFBySfid(Adapter,uiSearchRuleIndex);
-		}
-		else
-		{
-
+		if (pHostInfo->RetainSF == FALSE) {
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Going to Delete SF");
+			deleteSFBySfid(Adapter, uiSearchRuleIndex);
+		} else {
 			Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value = ntohs(pHostInfo->VCID);
 			Adapter->PackInfo[uiSearchRuleIndex].usCID = ntohs(pHostInfo->newCID);
-			Adapter->PackInfo[uiSearchRuleIndex].bActive=FALSE;
+			Adapter->PackInfo[uiSearchRuleIndex].bActive = FALSE;
 
-			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL,"pHostInfo->QoSParamSet: 0x%x\n",pHostInfo->QoSParamSet);
+			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "pHostInfo->QoSParamSet: 0x%x\n", pHostInfo->QoSParamSet);
 
-			if(pHostInfo->QoSParamSet & 0x1)
-				Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet =TRUE;
-			if(pHostInfo->QoSParamSet & 0x2)
-				Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet =TRUE;
-			if(pHostInfo->QoSParamSet & 0x4)
-			{
-				Adapter->PackInfo[uiSearchRuleIndex].bActiveSet =TRUE;
-				Adapter->PackInfo[uiSearchRuleIndex].bActive=TRUE;
+			if (pHostInfo->QoSParamSet & 0x1)
+				Adapter->PackInfo[uiSearchRuleIndex].bAuthorizedSet = TRUE;
+			if (pHostInfo->QoSParamSet & 0x2)
+				Adapter->PackInfo[uiSearchRuleIndex].bAdmittedSet = TRUE;
+			if (pHostInfo->QoSParamSet & 0x4) {
+				Adapter->PackInfo[uiSearchRuleIndex].bActiveSet = TRUE;
+				Adapter->PackInfo[uiSearchRuleIndex].bActive = TRUE;
 			}
 		}
 	}
 }
-
-
-
diff --git a/drivers/staging/bcm/led_control.h b/drivers/staging/bcm/led_control.h
index 0711ac2..ed8fbc0 100644
--- a/drivers/staging/bcm/led_control.h
+++ b/drivers/staging/bcm/led_control.h
@@ -4,11 +4,11 @@
 /*************************TYPE DEF**********************/
 #define NUM_OF_LEDS 4
 
-#define DSD_START_OFFSET                     0x0200
-#define EEPROM_VERSION_OFFSET           	 0x020E
-#define EEPROM_HW_PARAM_POINTER_ADDRESS 	 0x0218
-#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5 0x0220
-#define GPIO_SECTION_START_OFFSET        	 0x03
+#define DSD_START_OFFSET			0x0200
+#define EEPROM_VERSION_OFFSET			0x020E
+#define EEPROM_HW_PARAM_POINTER_ADDRESS		0x0218
+#define EEPROM_HW_PARAM_POINTER_ADDRRES_MAP5	0x0220
+#define GPIO_SECTION_START_OFFSET		0x03
 
 #define COMPATIBILITY_SECTION_LENGTH         42
 #define COMPATIBILITY_SECTION_LENGTH_MAP5    84
@@ -18,27 +18,27 @@
 #define EEPROM_MAP5_MINORVERSION             0
 
 
-#define MAX_NUM_OF_BLINKS 					10
-#define NUM_OF_GPIO_PINS 					16
+#define MAX_NUM_OF_BLINKS			10
+#define NUM_OF_GPIO_PINS			16
 
-#define DISABLE_GPIO_NUM 					0xFF
-#define EVENT_SIGNALED 						1
+#define DISABLE_GPIO_NUM			0xFF
+#define EVENT_SIGNALED				1
 
-#define MAX_FILE_NAME_BUFFER_SIZE 			100
+#define MAX_FILE_NAME_BUFFER_SIZE		100
 
-#define TURN_ON_LED(GPIO, index) do{ \
+#define TURN_ON_LED(GPIO, index) do { \
 							UINT gpio_val = GPIO; \
 							(Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
-							wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG, &gpio_val ,sizeof(gpio_val)) : \
-							wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
-						}while(0);
+							wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val)) : \
+							wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)); \
+						} while (0);
 
 #define TURN_OFF_LED(GPIO, index)  do { \
 							UINT gpio_val = GPIO; \
 							(Adapter->LEDInfo.LEDState[index].BitPolarity == 1) ? \
-							wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG,&gpio_val ,sizeof(gpio_val)) : \
-							wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG,&gpio_val ,sizeof(gpio_val));  \
-						}while(0);
+							wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, &gpio_val, sizeof(gpio_val)) : \
+							wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, &gpio_val, sizeof(gpio_val));  \
+						} while (0);
 
 #define B_ULONG32 unsigned long
 
@@ -50,7 +50,7 @@ typedef enum _LEDColors{
 	BLUE_LED = 2,
 	YELLOW_LED = 3,
 	GREEN_LED = 4
-} LEDColors; 				/*Enumerated values of different LED types*/
+} LEDColors;	/*Enumerated values of different LED types*/
 
 typedef enum LedEvents {
 	SHUTDOWN_EXIT = 0x00,
@@ -62,43 +62,39 @@ typedef enum LedEvents {
 	LOWPOWER_MODE_ENTER = 0x20,
 	IDLEMODE_CONTINUE = 0x40,
 	IDLEMODE_EXIT = 0x80,
-	LED_THREAD_INACTIVE = 0x100,  //Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold.
-	LED_THREAD_ACTIVE = 0x200    //Makes the LED Thread Active back.
-} LedEventInfo_t;			/*Enumerated values of different driver states*/
-
-#define DRIVER_HALT 0xff
-
-
-/*Structure which stores the information of different LED types
- *  and corresponding LED state information of driver states*/
-typedef struct LedStateInfo_t
-{
+	LED_THREAD_INACTIVE = 0x100,  /* Makes the LED thread Inactivce. It wil be equivallent to putting the thread on hold. */
+	LED_THREAD_ACTIVE = 0x200,    /* Makes the LED Thread Active back. */
+	DRIVER_HALT = 0xff
+} LedEventInfo_t;	/* Enumerated values of different driver states */
+
+/*
+ * Structure which stores the information of different LED types
+ * and corresponding LED state information of driver states
+ */
+typedef struct LedStateInfo_t {
 	UCHAR LED_Type; /* specify GPIO number - use 0xFF if not used */
 	UCHAR LED_On_State; /* Bits set or reset for different states */
 	UCHAR LED_Blink_State; /* Bits set or reset for blinking LEDs for different states */
 	UCHAR GPIO_Num;
-	UCHAR 			BitPolarity;				/*To represent whether H/W is normal polarity or reverse
-											  polarity*/
-}LEDStateInfo, *pLEDStateInfo;
+	UCHAR BitPolarity; /* To represent whether H/W is normal polarity or reverse polarity */
+} LEDStateInfo, *pLEDStateInfo;
 
 
-typedef struct _LED_INFO_STRUCT
-{
+typedef struct _LED_INFO_STRUCT {
 	LEDStateInfo	LEDState[NUM_OF_LEDS];
-	BOOLEAN 		bIdleMode_tx_from_host; /*Variable to notify whether driver came out
-											from idlemode due to Host or target*/
+	BOOLEAN		bIdleMode_tx_from_host; /* Variable to notify whether driver came out from idlemode due to Host or target*/
 	BOOLEAN			bIdle_led_off;
 	wait_queue_head_t   notify_led_event;
 	wait_queue_head_t	idleModeSyncEvent;
- 	struct task_struct  *led_cntrl_threadid;
-    int                 led_thread_running;
+	struct task_struct  *led_cntrl_threadid;
+	int                 led_thread_running;
 	BOOLEAN			bLedInitDone;
 
 } LED_INFO_STRUCT, *PLED_INFO_STRUCT;
-//LED Thread state.
-#define BCM_LED_THREAD_DISABLED			 	 0 //LED Thread is not running.
-#define BCM_LED_THREAD_RUNNING_ACTIVELY  	 1 //LED thread is running.
-#define BCM_LED_THREAD_RUNNING_INACTIVELY	 2 //LED thread has been put on hold
+/* LED Thread state. */
+#define BCM_LED_THREAD_DISABLED		0 /* LED Thread is not running. */
+#define BCM_LED_THREAD_RUNNING_ACTIVELY	1 /* LED thread is running. */
+#define BCM_LED_THREAD_RUNNING_INACTIVELY 2 /*LED thread has been put on hold*/
 
 
 
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 4c77e50..12c691d 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -765,8 +765,9 @@ config COMEDI_ADV_PCI_DIO
 	default N
 	---help---
 	  Enable support for Advantech PCI DIO cards
-	  PCI-1730, PCI-1733, PCI-1734, PCI-1736UP, PCI-1750, PCI-1751,
-	  PCI-1752, PCI-1753/E, PCI-1754, PCI-1756 and PCI-1762
+	  PCI-1730, PCI-1733, PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U,
+	  PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754, PCI-1756,
+	  PCI-1760 and PCI-1762
 
 	  To compile this driver as a module, choose M here: the module will be
 	  called adv_pci_dio.
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 537e585..7af068f 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -8,16 +8,16 @@
 /*
 Driver: adv_pci_dio
 Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1735U,
-	PCI-1736UP, PCI-1750, PCI-1751, PCI-1752, PCI-1753/E,
-	PCI-1754, PCI-1756, PCI-1762
+	PCI-1736UP, PCI-1739U, PCI-1750, PCI-1751, PCI-1752,
+	PCI-1753/E, PCI-1754, PCI-1756, PCI-1760, PCI-1762
 Author: Michal Dobes <dobes@tesnet.cz>
 Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
-  PCI-1734, PCI-1735U, PCI-1736UP, PCI-1750,
+  PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
   PCI-1751, PCI-1752, PCI-1753,
   PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
   PCI-1760, PCI-1762
 Status: untested
-Updated: Tue, 04 May 2010 13:00:00 +0000
+Updated: Mon, 09 Jan 2012 12:40:46 +0000
 
 This driver supports now only insn interface for DI/DO/DIO.
 
@@ -51,6 +51,7 @@ Configuration options:
 /* hardware types of the cards */
 enum hw_cards_id {
 	TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736,
+	TYPE_PCI1739,
 	TYPE_PCI1750,
 	TYPE_PCI1751,
 	TYPE_PCI1752,
@@ -109,6 +110,12 @@ enum hw_io_access {
 #define PCI1736_BOARDID    4	/* R:   Board I/D switch for 1736UP */
 #define PCI1736_MAINREG    0	/* Normal register (2) doesn't work */
 
+/* Advantech PCI-1739U */
+#define PCI1739_DIO	   0	/* R/W: begin of 8255 registers block */
+#define PCI1739_ICR	  32	/* W:   Interrupt control register */
+#define PCI1739_ISR	  32	/* R:   Interrupt status register */
+#define PCI1739_BOARDID	   8    /* R:   Board I/D switch for 1739U */
+
 /*  Advantech PCI-1750 */
 #define PCI1750_IDI	   0	/* R:   Isolated digital input  0-15 */
 #define PCI1750_IDO	   0	/* W:   Isolated digital output 0-15 */
@@ -262,6 +269,7 @@ static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1734) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1735) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1736) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1739) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1750) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1751) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1752) },
@@ -316,6 +324,14 @@ static const struct dio_boardtype boardtypes[] = {
 	 {4, PCI1736_BOARDID, 1, SDF_INTERNAL},
 	 { {0, 0, 0, 0} },
 	 IO_8b},
+	{"pci1739", PCI_VENDOR_ID_ADVANTECH, 0x1739, PCIDIO_MAINREG,
+	 TYPE_PCI1739,
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
+	 { {48, PCI1739_DIO, 2, 0}, {0, 0, 0, 0} },
+	 {0, 0, 0, 0},
+	 { {0, 0, 0, 0} },
+	 IO_8b},
 	{"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
 	 TYPE_PCI1750,
 	 { {0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0} },
@@ -883,6 +899,11 @@ static int pci_dio_reset(struct comedi_device *dev)
 		outb(0, dev->iobase + PCI1736_3_INT_RF);
 		break;
 
+	case TYPE_PCI1739:
+		/* disable & clear interrupts */
+		outb(0x88, dev->iobase + PCI1739_ICR);
+		break;
+
 	case TYPE_PCI1750:
 	case TYPE_PCI1751:
 		/* disable & clear interrupts */
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index 5cce1b5..b85c836 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -720,12 +720,20 @@ static int dt2801_dio_insn_config(struct comedi_device *dev,
 		which = 1;
 
 	/* configure */
-	if (data[0]) {
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
 		s->io_bits = 0xff;
 		dt2801_writecmd(dev, DT_C_SET_DIGOUT);
-	} else {
+		break;
+	case INSN_CONFIG_DIO_INPUT:
 		s->io_bits = 0;
 		dt2801_writecmd(dev, DT_C_SET_DIGIN);
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+	default:
+		return -EINVAL;
 	}
 	dt2801_writedata(dev, which);
 
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 32d9c42..e86ab58 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -527,7 +527,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
 		 * 11x -> Gain =  0.5
 		 */
 	case DT9812_GAIN_0PT5:
-		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 ||
+		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 |
 		    F020_MASK_ADC0CF_AMP0GN1;
 		break;
 	case DT9812_GAIN_1:
@@ -540,7 +540,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN1;
 		break;
 	case DT9812_GAIN_8:
-		rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 ||
+		rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 |
 		    F020_MASK_ADC0CF_AMP0GN0;
 		break;
 	case DT9812_GAIN_16:
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index b692fea..b0bc6bb 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -2098,23 +2098,29 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
 
 	CALL_PDEBUG("In me4000_dio_insn_config()\n");
 
-	if (data[0] == INSN_CONFIG_DIO_QUERY) {
+	switch (data[0]) {
+	default:
+		return -EINVAL;
+	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
 		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
+	case INSN_CONFIG_DIO_INPUT:
+	case INSN_CONFIG_DIO_OUTPUT:
+		break;
 	}
 
 	/*
 	 * The input or output configuration of each digital line is
 	 * configured by a special insn_config instruction.  chanspec
 	 * contains the channel to be changed, and data[0] contains the
-	 * value COMEDI_INPUT or COMEDI_OUTPUT.
+	 * value INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
 	 * On the ME-4000 it is only possible to switch port wise (8 bit)
 	 */
 
 	tmp = me4000_inl(dev, info->dio_context.ctrl_reg);
 
-	if (data[0] == COMEDI_OUTPUT) {
+	if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
 		if (chan < 8) {
 			s->io_bits |= 0xFF;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 045a4c0..1df8fcb 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -30,7 +30,7 @@ Status: works
 Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
   PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
   PXI-6503, PCI-6533, PCI-6534
-Updated: Sun, 21 Apr 2002 21:03:38 -0700
+Updated: Mon, 09 Jan 2012 14:27:23 +0000
 
 The DIO-96 appears as four 8255 subdevices.  See the 8255
 driver notes for details.
@@ -42,6 +42,11 @@ supports simple digital I/O; no handshaking is supported.
 
 DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
 
+The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
+scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
+scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
+trailing edge.
+
 This driver could be easily modified to support AT-MIO32HS and
 AT-MIO96.
 
@@ -436,6 +441,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
 		comedi_error(dev, "failed to reserve mite dma channel.");
 		return -EBUSY;
 	}
+	devpriv->di_mite_chan->dir = COMEDI_INPUT;
 	writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
 	       secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
 	       devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
@@ -482,6 +488,21 @@ void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s)
 	comedi_event(dev, s);
 }
 
+static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
+{
+	unsigned long irq_flags;
+	int count;
+
+	spin_lock_irqsave(&dev->spinlock, irq_flags);
+	spin_lock(&devpriv->mite_channel_lock);
+	if (devpriv->di_mite_chan)
+		mite_sync_input_dma(devpriv->di_mite_chan, s->async);
+	spin_unlock(&devpriv->mite_channel_lock);
+	count = s->async->buf_write_count - s->async->buf_read_count;
+	spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+	return count;
+}
+
 static irqreturn_t nidio_interrupt(int irq, void *d)
 {
 	struct comedi_device *dev = d;
@@ -497,7 +518,6 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 	int status;
 	int work = 0;
 	unsigned int m_status = 0;
-	unsigned long irq_flags;
 
 	/* interrupcions parasites */
 	if (dev->attached == 0) {
@@ -505,6 +525,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 		return IRQ_NONE;
 	}
 
+	/* Lock to avoid race with comedi_poll */
+	spin_lock(&dev->spinlock);
+
 	status = readb(devpriv->mite->daq_io_addr +
 		       Interrupt_And_Window_Status);
 	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
@@ -518,7 +541,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 	/* printk("buf[4096]=%08x\n",
 	       *(unsigned int *)(async->prealloc_buf+4096)); */
 
-	spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
+	spin_lock(&devpriv->mite_channel_lock);
 	if (devpriv->di_mite_chan)
 		m_status = mite_get_status(devpriv->di_mite_chan);
 #ifdef MITE_DEBUG
@@ -543,7 +566,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 			disable_irq(dev->irq);
 		}
 	}
-	spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
+	spin_unlock(&devpriv->mite_channel_lock);
 
 	while (status & DataLeft) {
 		work++;
@@ -645,6 +668,8 @@ out:
 		       Master_DMA_And_Interrupt_Control);
 	}
 #endif
+
+	spin_unlock(&dev->spinlock);
 	return IRQ_HANDLED;
 }
 
@@ -825,8 +850,8 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev,
 	} else {
 		/* TRIG_EXT */
 		/* should be level/edge, hi/lo specification here */
-		if (cmd->scan_begin_arg != 0) {
-			cmd->scan_begin_arg = 0;
+		if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
+			cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
 			err++;
 		}
 	}
@@ -941,7 +966,13 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		writeb(0, devpriv->mite->daq_io_addr + Sequence);
 		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
 		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
-		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
+		if (!(cmd->scan_begin_arg & CR_INVERT)) {
+			/* Leading Edge pulse mode */
+			writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
+		} else {
+			/* Trailing Edge pulse mode */
+			writeb(2, devpriv->mite->daq_io_addr + LinePolarities);
+		}
 		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
 		writel(1, devpriv->mite->daq_io_addr + StartDelay);
 		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
@@ -1005,17 +1036,24 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int retval;
+	unsigned long flags;
 
 	retval = ni_pcidio_request_di_mite_channel(dev);
 	if (retval)
 		return retval;
 
-	devpriv->di_mite_chan->dir = COMEDI_INPUT;
+	/* write alloc the entire buffer */
+	comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
 
-	mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+	spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->di_mite_chan) {
+		mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+		mite_dma_arm(devpriv->di_mite_chan);
+	} else
+		retval = -EIO;
+	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 
-	mite_dma_arm(devpriv->di_mite_chan);
-	return 0;
+	return retval;
 }
 
 static int ni_pcidio_inttrig(struct comedi_device *dev,
@@ -1244,6 +1282,7 @@ static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		s->len_chanlist = 32;	/* XXX */
 		s->buf_change = &ni_pcidio_change;
 		s->async_dma_dir = DMA_BIDIRECTIONAL;
+		s->poll = &ni_pcidio_poll;
 
 		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
 		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 0f0d995..27baefa 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -29,14 +29,15 @@ Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
   PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
   PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
   PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
-  PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225,
-  PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
+  PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224,
+  PCI-6225, PXI-6225, PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PXIe-6251,
+  PCI-6254, PCI-6259, PCIe-6259,
   PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
   PCI-6711, PXI-6711, PCI-6713, PXI-6713,
   PXI-6071E, PCI-6070E, PXI-6070E,
   PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
   PCI-6143, PXI-6143
-Updated: Wed, 03 Dec 2008 10:51:47 +0000
+Updated: Mon, 09 Jan 2012 14:52:48 +0000
 
 These boards are almost identical to the AT-MIO E series, except that
 they use the PCI bus instead of ISA (i.e., AT).  See the notes for
@@ -182,6 +183,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = {
 	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717f)},
 	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x71bc)},
 	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x717d)},
+	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x72e8)},
 	{0}
 };
 
@@ -1046,6 +1048,25 @@ static const struct ni_board_struct ni_boards[] = {
 	 .has_8255 = 0,
 	 },
 	{
+	 .device_id = 0x72e8,
+	 .name = "pxie-6251",
+	 .n_adchan = 16,
+	 .adbits = 16,
+	 .ai_fifo_depth = 4095,
+	 .gainlkup = ai_gain_628x,
+	 .ai_speed = 800,
+	 .n_aochan = 2,
+	 .aobits = 16,
+	 .ao_fifo_depth = 8191,
+	 .ao_range_table = &range_ni_M_625x_ao,
+	 .reg_type = ni_reg_625x,
+	 .ao_unipolar = 0,
+	 .ao_speed = 357,
+	 .num_p0_dio_channels = 8,
+	 .caldac = {caldac_none},
+	 .has_8255 = 0,
+	 },
+	{
 	 .device_id = 0x70b7,
 	 .name = "pci-6254",
 	 .n_adchan = 32,
diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c
index 5acf39e..eeddee9 100644
--- a/drivers/staging/crystalhd/crystalhd_hw.c
+++ b/drivers/staging/crystalhd/crystalhd_hw.c
@@ -868,8 +868,7 @@ static enum BC_STATUS crystalhd_stop_tx_dma_engine(struct crystalhd_hw *hw)
 
 	BCMLOG(BCMLOG_DBG, "Stopping TX DMA Engine..\n");
 
-	/* FIXME: jarod: invert dma_ctrl and check bit? or are there missing parens? */
-	if (!dma_cntrl & DMA_START_BIT) {
+	if (!(dma_cntrl & DMA_START_BIT)) {
 		BCMLOG(BCMLOG_DBG, "Already Stopped\n");
 		return BC_STS_SUCCESS;
 	}
diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h
index 4d61723..e0aa361 100644
--- a/drivers/staging/crystalhd/crystalhd_misc.h
+++ b/drivers/staging/crystalhd/crystalhd_misc.h
@@ -203,26 +203,30 @@ enum _chd_log_levels {
 	BCMLOG_ENTER_LEAVE	= 0x00000008,	/* stack tracking */
 };
 
-#define BCMLOG_ENTER				\
-if (g_linklog_level & BCMLOG_ENTER_LEAVE) {	\
-	printk(KERN_DEBUG "Entered %s\n", __func__);	\
-}
-
-#define BCMLOG_LEAVE				\
-if (g_linklog_level & BCMLOG_ENTER_LEAVE) {	\
-	printk(KERN_DEBUG "Leaving %s\n", __func__);	\
-}
-
-#define BCMLOG(trace, fmt, args...)		\
-if (g_linklog_level & trace) {			\
-	printk(fmt, ##args);			\
-}
-
-#define BCMLOG_ERR(fmt, args...)					\
-do {									\
-	if (g_linklog_level & BCMLOG_ERROR) {				\
-		printk(KERN_ERR "*ERR*:%s:%d: "fmt, __FILE__, __LINE__, ##args);	\
-	}								\
-} while (0);
+#define BCMLOG_ENTER						\
+do {								\
+	if (g_linklog_level & BCMLOG_ENTER_LEAVE)		\
+		printk(KERN_DEBUG "Entered %s\n", __func__);	\
+} while (0)
+
+#define BCMLOG_LEAVE						\
+do {								\
+	if (g_linklog_level & BCMLOG_ENTER_LEAVE)		\
+		printk(KERN_DEBUG "Leaving %s\n", __func__);	\
+} while (0)							\
+
+#define BCMLOG(trace, fmt, args...)	\
+do {					\
+	if (g_linklog_level & trace)	\
+		printk(fmt, ##args);	\
+} while (0)
+
+
+#define BCMLOG_ERR(fmt, args...)				\
+do {								\
+	if (g_linklog_level & BCMLOG_ERROR)			\
+		printk(KERN_ERR "*ERR*:%s:%d: "fmt,		\
+				__FILE__, __LINE__, ##args);	\
+} while (0)
 
 #endif
diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README
index 3458aa7..8265723 100644
--- a/drivers/staging/et131x/README
+++ b/drivers/staging/et131x/README
@@ -11,6 +11,6 @@ TODO:
 	- Use of kmem_cache seems a bit unusual
 
 Please send patches to:
-	Greg Kroah-Hartman <gregkh@suse.de>
+	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 	Mark Einon <mark.einon@gmail.com>
 
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
index 7faeada..71aaad3 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
@@ -29,10 +29,10 @@
 #define FT1000_PROC "ft1000"
 #define MAX_FILE_LEN 255
 
-#define PUTM_TO_PAGE(len,page,args...) \
+#define PUTM_TO_PAGE(len, page, args...) \
 	len += snprintf(page+len, PAGE_SIZE - len, args)
 
-#define PUTX_TO_PAGE(len,page,message,size,var) \
+#define PUTX_TO_PAGE(len, page, message, size, var) \
 	len += snprintf(page+len, PAGE_SIZE - len, message); \
 	for(i = 0; i < (size - 1); i++) \
 	{ \
@@ -40,7 +40,7 @@
 	} \
 	len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i])
 
-#define PUTD_TO_PAGE(len,page,message,size,var) \
+#define PUTD_TO_PAGE(len, page, message, size, var) \
 	len += snprintf(page+len, PAGE_SIZE - len, message); \
 	for(i = 0; i < (size - 1); i++) \
 	{ \
diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig
deleted file mode 100644
index 60ac479..0000000
--- a/drivers/staging/hv/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-config HYPERV_STORAGE
-	tristate "Microsoft Hyper-V virtual storage driver"
-	depends on HYPERV && SCSI
-	help
-	 Select this option to enable the Hyper-V virtual storage driver.
diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
deleted file mode 100644
index af95a6b..0000000
--- a/drivers/staging/hv/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
-
-hv_storvsc-y := storvsc_drv.o
diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
deleted file mode 100644
index dea7d92..0000000
--- a/drivers/staging/hv/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
-TODO:
-	- audit the scsi driver
-
-Please send patches for this code to Greg Kroah-Hartman <gregkh@suse.de>,
-Haiyang Zhang <haiyangz@microsoft.com>, and K. Y. Srinivasan <kys@microsoft.com>
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
deleted file mode 100644
index eb853f7..0000000
--- a/drivers/staging/hv/storvsc_drv.c
+++ /dev/null
@@ -1,1586 +0,0 @@
-/*
- * Copyright (c) 2009, Microsoft Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *   K. Y. Srinivasan <kys@microsoft.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/sched.h>
-#include <linux/completion.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/hyperv.h>
-#include <linux/mempool.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_host.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsi_eh.h>
-#include <scsi/scsi_devinfo.h>
-#include <scsi/scsi_dbg.h>
-
-
-#define STORVSC_MIN_BUF_NR				64
-#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
-static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
-
-module_param(storvsc_ringbuffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
-
-/* to alert the user that structure sizes may be mismatched even though the */
-/* protocol versions match. */
-
-
-#define REVISION_STRING(REVISION_) #REVISION_
-#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)				\
-	do {								\
-		char *revision_string					\
-			= REVISION_STRING($Rev : 6 $) + 6;		\
-		RESULT_LVALUE_ = 0;					\
-		while (*revision_string >= '0'				\
-			&& *revision_string <= '9') {			\
-			RESULT_LVALUE_ *= 10;				\
-			RESULT_LVALUE_ += *revision_string - '0';	\
-			revision_string++;				\
-		}							\
-	} while (0)
-
-/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
-/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
-#define VMSTOR_PROTOCOL_MAJOR(VERSION_)		(((VERSION_) >> 8) & 0xff)
-#define VMSTOR_PROTOCOL_MINOR(VERSION_)		(((VERSION_))      & 0xff)
-#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
-						 (((MINOR_) & 0xff)))
-#define VMSTOR_INVALID_PROTOCOL_VERSION		(-1)
-
-/* Version history: */
-/* V1 Beta                    0.1 */
-/* V1 RC < 2008/1/31          1.0 */
-/* V1 RC > 2008/1/31          2.0 */
-#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(4, 2)
-
-
-
-
-/*  This will get replaced with the max transfer length that is possible on */
-/*  the host adapter. */
-/*  The max transfer length will be published when we offer a vmbus channel. */
-#define MAX_TRANSFER_LENGTH	0x40000
-#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) +	\
-			sizeof(struct vstor_packet) +		\
-			sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
-
-
-/*  Packet structure describing virtual storage requests. */
-enum vstor_packet_operation {
-	VSTOR_OPERATION_COMPLETE_IO		= 1,
-	VSTOR_OPERATION_REMOVE_DEVICE		= 2,
-	VSTOR_OPERATION_EXECUTE_SRB		= 3,
-	VSTOR_OPERATION_RESET_LUN		= 4,
-	VSTOR_OPERATION_RESET_ADAPTER		= 5,
-	VSTOR_OPERATION_RESET_BUS		= 6,
-	VSTOR_OPERATION_BEGIN_INITIALIZATION	= 7,
-	VSTOR_OPERATION_END_INITIALIZATION	= 8,
-	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
-	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
-	VSTOR_OPERATION_ENUMERATE_BUS		= 11,
-	VSTOR_OPERATION_MAXIMUM			= 11
-};
-
-/*
- * Platform neutral description of a scsi request -
- * this remains the same across the write regardless of 32/64 bit
- * note: it's patterned off the SCSI_PASS_THROUGH structure
- */
-#define CDB16GENERIC_LENGTH			0x10
-
-#ifndef SENSE_BUFFER_SIZE
-#define SENSE_BUFFER_SIZE			0x12
-#endif
-
-#define MAX_DATA_BUF_LEN_WITH_PADDING		0x14
-
-struct vmscsi_request {
-	unsigned short length;
-	unsigned char srb_status;
-	unsigned char scsi_status;
-
-	unsigned char port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-	unsigned char lun;
-
-	unsigned char cdb_length;
-	unsigned char sense_info_length;
-	unsigned char data_in;
-	unsigned char reserved;
-
-	unsigned int data_transfer_length;
-
-	union {
-		unsigned char cdb[CDB16GENERIC_LENGTH];
-		unsigned char sense_data[SENSE_BUFFER_SIZE];
-		unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
-	};
-} __attribute((packed));
-
-
-/*
- * This structure is sent during the intialization phase to get the different
- * properties of the channel.
- */
-struct vmstorage_channel_properties {
-	unsigned short protocol_version;
-	unsigned char path_id;
-	unsigned char target_id;
-
-	/* Note: port number is only really known on the client side */
-	unsigned int port_number;
-	unsigned int flags;
-	unsigned int max_transfer_bytes;
-
-	/*  This id is unique for each channel and will correspond with */
-	/*  vendor specific data in the inquirydata */
-	unsigned long long unique_id;
-} __packed;
-
-/*  This structure is sent during the storage protocol negotiations. */
-struct vmstorage_protocol_version {
-	/* Major (MSW) and minor (LSW) version numbers. */
-	unsigned short major_minor;
-
-	/*
-	 * Revision number is auto-incremented whenever this file is changed
-	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
-	 * definitely indicate incompatibility--but it does indicate mismatched
-	 * builds.
-	 */
-	unsigned short revision;
-} __packed;
-
-/* Channel Property Flags */
-#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
-#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
-
-struct vstor_packet {
-	/* Requested operation type */
-	enum vstor_packet_operation operation;
-
-	/*  Flags - see below for values */
-	unsigned int flags;
-
-	/* Status of the request returned from the server side. */
-	unsigned int status;
-
-	/* Data payload area */
-	union {
-		/*
-		 * Structure used to forward SCSI commands from the
-		 * client to the server.
-		 */
-		struct vmscsi_request vm_srb;
-
-		/* Structure used to query channel properties. */
-		struct vmstorage_channel_properties storage_channel_properties;
-
-		/* Used during version negotiations. */
-		struct vmstorage_protocol_version version;
-	};
-} __packed;
-
-/* Packet flags */
-/*
- * This flag indicates that the server should send back a completion for this
- * packet.
- */
-#define REQUEST_COMPLETION_FLAG	0x1
-
-/*  This is the set of flags that the vsc can set in any packets it sends */
-#define VSC_LEGAL_FLAGS		(REQUEST_COMPLETION_FLAG)
-
-
-/* Defines */
-
-#define STORVSC_MAX_IO_REQUESTS				128
-
-/*
- * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
- * reality, the path/target is not used (ie always set to 0) so our
- * scsi host adapter essentially has 1 bus with 1 target that contains
- * up to 256 luns.
- */
-#define STORVSC_MAX_LUNS_PER_TARGET			64
-#define STORVSC_MAX_TARGETS				1
-#define STORVSC_MAX_CHANNELS				1
-#define STORVSC_MAX_CMD_LEN				16
-
-/* Matches Windows-end */
-enum storvsc_request_type {
-	WRITE_TYPE,
-	READ_TYPE,
-	UNKNOWN_TYPE,
-};
-
-
-struct hv_storvsc_request {
-	struct hv_device *device;
-
-	/* Synchronize the request/response if needed */
-	struct completion wait_event;
-
-	unsigned char *sense_buffer;
-	void *context;
-	void (*on_io_completion)(struct hv_storvsc_request *request);
-	struct hv_multipage_buffer data_buffer;
-
-	struct vstor_packet vstor_packet;
-};
-
-
-/* A storvsc device is a device object that contains a vmbus channel */
-struct storvsc_device {
-	struct hv_device *device;
-
-	bool	 destroy;
-	bool	 drain_notify;
-	atomic_t num_outstanding_req;
-	struct Scsi_Host *host;
-
-	wait_queue_head_t waiting_to_drain;
-
-	/*
-	 * Each unique Port/Path/Target represents 1 channel ie scsi
-	 * controller. In reality, the pathid, targetid is always 0
-	 * and the port is set by us
-	 */
-	unsigned int port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-
-	/* Used for vsc/vsp channel reset process */
-	struct hv_storvsc_request init_request;
-	struct hv_storvsc_request reset_request;
-};
-
-struct stor_mem_pools {
-	struct kmem_cache *request_pool;
-	mempool_t *request_mempool;
-};
-
-struct hv_host_device {
-	struct hv_device *dev;
-	unsigned int port;
-	unsigned char path;
-	unsigned char target;
-};
-
-struct storvsc_cmd_request {
-	struct list_head entry;
-	struct scsi_cmnd *cmd;
-
-	unsigned int bounce_sgl_count;
-	struct scatterlist *bounce_sgl;
-
-	struct hv_storvsc_request request;
-};
-
-struct storvsc_scan_work {
-	struct work_struct work;
-	struct Scsi_Host *host;
-	uint lun;
-};
-
-static void storvsc_bus_scan(struct work_struct *work)
-{
-	struct storvsc_scan_work *wrk;
-	int id, order_id;
-
-	wrk = container_of(work, struct storvsc_scan_work, work);
-	for (id = 0; id < wrk->host->max_id; ++id) {
-		if (wrk->host->reverse_ordering)
-			order_id = wrk->host->max_id - id - 1;
-		else
-			order_id = id;
-
-		scsi_scan_target(&wrk->host->shost_gendev, 0,
-				order_id, SCAN_WILD_CARD, 1);
-	}
-	kfree(wrk);
-}
-
-static void storvsc_remove_lun(struct work_struct *work)
-{
-	struct storvsc_scan_work *wrk;
-	struct scsi_device *sdev;
-
-	wrk = container_of(work, struct storvsc_scan_work, work);
-	if (!scsi_host_get(wrk->host))
-		goto done;
-
-	sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun);
-
-	if (sdev) {
-		scsi_remove_device(sdev);
-		scsi_device_put(sdev);
-	}
-	scsi_host_put(wrk->host);
-
-done:
-	kfree(wrk);
-}
-
-static inline struct storvsc_device *get_out_stor_device(
-					struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = hv_get_drvdata(device);
-
-	if (stor_device && stor_device->destroy)
-		stor_device = NULL;
-
-	return stor_device;
-}
-
-
-static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
-{
-	dev->drain_notify = true;
-	wait_event(dev->waiting_to_drain,
-		   atomic_read(&dev->num_outstanding_req) == 0);
-	dev->drain_notify = false;
-}
-
-static inline struct storvsc_device *get_in_stor_device(
-					struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = hv_get_drvdata(device);
-
-	if (!stor_device)
-		goto get_in_err;
-
-	/*
-	 * If the device is being destroyed; allow incoming
-	 * traffic only to cleanup outstanding requests.
-	 */
-
-	if (stor_device->destroy  &&
-		(atomic_read(&stor_device->num_outstanding_req) == 0))
-		stor_device = NULL;
-
-get_in_err:
-	return stor_device;
-
-}
-
-static int storvsc_channel_init(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-	struct hv_storvsc_request *request;
-	struct vstor_packet *vstor_packet;
-	int ret, t;
-
-	stor_device = get_out_stor_device(device);
-	if (!stor_device)
-		return -ENODEV;
-
-	request = &stor_device->init_request;
-	vstor_packet = &request->vstor_packet;
-
-	/*
-	 * Now, initiate the vsc/vsp initialization protocol on the open
-	 * channel
-	 */
-	memset(request, 0, sizeof(struct hv_storvsc_request));
-	init_completion(&request->wait_event);
-	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-
-	/* reuse the packet for version range supported */
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
-	FILL_VMSTOR_REVISION(vstor_packet->version.revision);
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-	vstor_packet->storage_channel_properties.port_number =
-					stor_device->port_number;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-	stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
-	stor_device->target_id
-		= vstor_packet->storage_channel_properties.target_id;
-
-	memset(vstor_packet, 0, sizeof(struct vstor_packet));
-	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-
-	if (ret != 0)
-		goto cleanup;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0)
-		goto cleanup;
-
-
-cleanup:
-	return ret;
-}
-
-static void storvsc_on_io_completion(struct hv_device *device,
-				  struct vstor_packet *vstor_packet,
-				  struct hv_storvsc_request *request)
-{
-	struct storvsc_device *stor_device;
-	struct vstor_packet *stor_pkt;
-
-	stor_device = hv_get_drvdata(device);
-	stor_pkt = &request->vstor_packet;
-
-	/*
-	 * The current SCSI handling on the host side does
-	 * not correctly handle:
-	 * INQUIRY command with page code parameter set to 0x80
-	 * MODE_SENSE command with cmd[2] == 0x1c
-	 *
-	 * Setup srb and scsi status so this won't be fatal.
-	 * We do this so we can distinguish truly fatal failues
-	 * (srb status == 0x4) and off-line the device in that case.
-	 */
-
-	if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) ||
-		(stor_pkt->vm_srb.cdb[0] == MODE_SENSE)) {
-		vstor_packet->vm_srb.scsi_status = 0;
-		vstor_packet->vm_srb.srb_status = 0x1;
-	}
-
-
-	/* Copy over the status...etc */
-	stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
-	stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status;
-	stor_pkt->vm_srb.sense_info_length =
-	vstor_packet->vm_srb.sense_info_length;
-
-	if (vstor_packet->vm_srb.scsi_status != 0 ||
-		vstor_packet->vm_srb.srb_status != 1){
-		dev_warn(&device->device,
-			 "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
-			 stor_pkt->vm_srb.cdb[0],
-			 vstor_packet->vm_srb.scsi_status,
-			 vstor_packet->vm_srb.srb_status);
-	}
-
-	if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
-		/* CHECK_CONDITION */
-		if (vstor_packet->vm_srb.srb_status & 0x80) {
-			/* autosense data available */
-			dev_warn(&device->device,
-				 "stor pkt %p autosense data valid - len %d\n",
-				 request,
-				 vstor_packet->vm_srb.sense_info_length);
-
-			memcpy(request->sense_buffer,
-			       vstor_packet->vm_srb.sense_data,
-			       vstor_packet->vm_srb.sense_info_length);
-
-		}
-	}
-
-	stor_pkt->vm_srb.data_transfer_length =
-	vstor_packet->vm_srb.data_transfer_length;
-
-	request->on_io_completion(request);
-
-	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
-		stor_device->drain_notify)
-		wake_up(&stor_device->waiting_to_drain);
-
-
-}
-
-static void storvsc_on_receive(struct hv_device *device,
-			     struct vstor_packet *vstor_packet,
-			     struct hv_storvsc_request *request)
-{
-	struct storvsc_scan_work *work;
-	struct storvsc_device *stor_device;
-
-	switch (vstor_packet->operation) {
-	case VSTOR_OPERATION_COMPLETE_IO:
-		storvsc_on_io_completion(device, vstor_packet, request);
-		break;
-
-	case VSTOR_OPERATION_REMOVE_DEVICE:
-	case VSTOR_OPERATION_ENUMERATE_BUS:
-		stor_device = get_in_stor_device(device);
-		work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC);
-		if (!work)
-			return;
-
-		INIT_WORK(&work->work, storvsc_bus_scan);
-		work->host = stor_device->host;
-		schedule_work(&work->work);
-		break;
-
-	default:
-		break;
-	}
-}
-
-static void storvsc_on_channel_callback(void *context)
-{
-	struct hv_device *device = (struct hv_device *)context;
-	struct storvsc_device *stor_device;
-	u32 bytes_recvd;
-	u64 request_id;
-	unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)];
-	struct hv_storvsc_request *request;
-	int ret;
-
-
-	stor_device = get_in_stor_device(device);
-	if (!stor_device)
-		return;
-
-	do {
-		ret = vmbus_recvpacket(device->channel, packet,
-				       ALIGN(sizeof(struct vstor_packet), 8),
-				       &bytes_recvd, &request_id);
-		if (ret == 0 && bytes_recvd > 0) {
-
-			request = (struct hv_storvsc_request *)
-					(unsigned long)request_id;
-
-			if ((request == &stor_device->init_request) ||
-			    (request == &stor_device->reset_request)) {
-
-				memcpy(&request->vstor_packet, packet,
-				       sizeof(struct vstor_packet));
-				complete(&request->wait_event);
-			} else {
-				storvsc_on_receive(device,
-						(struct vstor_packet *)packet,
-						request);
-			}
-		} else {
-			break;
-		}
-	} while (1);
-
-	return;
-}
-
-static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
-{
-	struct vmstorage_channel_properties props;
-	int ret;
-
-	memset(&props, 0, sizeof(struct vmstorage_channel_properties));
-
-	/* Open the channel */
-	ret = vmbus_open(device->channel,
-			 ring_size,
-			 ring_size,
-			 (void *)&props,
-			 sizeof(struct vmstorage_channel_properties),
-			 storvsc_on_channel_callback, device);
-
-	if (ret != 0)
-		return ret;
-
-	ret = storvsc_channel_init(device);
-
-	return ret;
-}
-
-static int storvsc_dev_remove(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-	unsigned long flags;
-
-	stor_device = hv_get_drvdata(device);
-
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	stor_device->destroy = true;
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
-
-	/*
-	 * At this point, all outbound traffic should be disable. We
-	 * only allow inbound traffic (responses) to proceed so that
-	 * outstanding requests can be completed.
-	 */
-
-	storvsc_wait_to_drain(stor_device);
-
-	/*
-	 * Since we have already drained, we don't need to busy wait
-	 * as was done in final_release_stor_device()
-	 * Note that we cannot set the ext pointer to NULL until
-	 * we have drained - to drain the outgoing packets, we need to
-	 * allow incoming packets.
-	 */
-	spin_lock_irqsave(&device->channel->inbound_lock, flags);
-	hv_set_drvdata(device, NULL);
-	spin_unlock_irqrestore(&device->channel->inbound_lock, flags);
-
-	/* Close the channel */
-	vmbus_close(device->channel);
-
-	kfree(stor_device);
-	return 0;
-}
-
-static int storvsc_do_io(struct hv_device *device,
-			      struct hv_storvsc_request *request)
-{
-	struct storvsc_device *stor_device;
-	struct vstor_packet *vstor_packet;
-	int ret = 0;
-
-	vstor_packet = &request->vstor_packet;
-	stor_device = get_out_stor_device(device);
-
-	if (!stor_device)
-		return -ENODEV;
-
-
-	request->device  = device;
-
-
-	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
-
-	vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
-
-
-	vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE;
-
-
-	vstor_packet->vm_srb.data_transfer_length =
-	request->data_buffer.len;
-
-	vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
-
-	if (request->data_buffer.len) {
-		ret = vmbus_sendpacket_multipagebuffer(device->channel,
-				&request->data_buffer,
-				vstor_packet,
-				sizeof(struct vstor_packet),
-				(unsigned long)request);
-	} else {
-		ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	}
-
-	if (ret != 0)
-		return ret;
-
-	atomic_inc(&stor_device->num_outstanding_req);
-
-	return ret;
-}
-
-static void storvsc_get_ide_info(struct hv_device *dev, int *target, int *path)
-{
-	*target =
-		dev->dev_instance.b[5] << 8 | dev->dev_instance.b[4];
-
-	*path =
-		dev->dev_instance.b[3] << 24 |
-		dev->dev_instance.b[2] << 16 |
-		dev->dev_instance.b[1] << 8  | dev->dev_instance.b[0];
-}
-
-
-static int storvsc_device_alloc(struct scsi_device *sdevice)
-{
-	struct stor_mem_pools *memp;
-	int number = STORVSC_MIN_BUF_NR;
-
-	memp = kzalloc(sizeof(struct stor_mem_pools), GFP_KERNEL);
-	if (!memp)
-		return -ENOMEM;
-
-	memp->request_pool =
-		kmem_cache_create(dev_name(&sdevice->sdev_dev),
-				sizeof(struct storvsc_cmd_request), 0,
-				SLAB_HWCACHE_ALIGN, NULL);
-
-	if (!memp->request_pool)
-		goto err0;
-
-	memp->request_mempool = mempool_create(number, mempool_alloc_slab,
-						mempool_free_slab,
-						memp->request_pool);
-
-	if (!memp->request_mempool)
-		goto err1;
-
-	sdevice->hostdata = memp;
-
-	return 0;
-
-err1:
-	kmem_cache_destroy(memp->request_pool);
-
-err0:
-	kfree(memp);
-	return -ENOMEM;
-}
-
-static void storvsc_device_destroy(struct scsi_device *sdevice)
-{
-	struct stor_mem_pools *memp = sdevice->hostdata;
-
-	mempool_destroy(memp->request_mempool);
-	kmem_cache_destroy(memp->request_pool);
-	kfree(memp);
-	sdevice->hostdata = NULL;
-}
-
-static int storvsc_device_configure(struct scsi_device *sdevice)
-{
-	scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
-				STORVSC_MAX_IO_REQUESTS);
-
-	blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
-
-	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
-
-	return 0;
-}
-
-static void destroy_bounce_buffer(struct scatterlist *sgl,
-				  unsigned int sg_count)
-{
-	int i;
-	struct page *page_buf;
-
-	for (i = 0; i < sg_count; i++) {
-		page_buf = sg_page((&sgl[i]));
-		if (page_buf != NULL)
-			__free_page(page_buf);
-	}
-
-	kfree(sgl);
-}
-
-static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
-{
-	int i;
-
-	/* No need to check */
-	if (sg_count < 2)
-		return -1;
-
-	/* We have at least 2 sg entries */
-	for (i = 0; i < sg_count; i++) {
-		if (i == 0) {
-			/* make sure 1st one does not have hole */
-			if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
-				return i;
-		} else if (i == sg_count - 1) {
-			/* make sure last one does not have hole */
-			if (sgl[i].offset != 0)
-				return i;
-		} else {
-			/* make sure no hole in the middle */
-			if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
-				return i;
-		}
-	}
-	return -1;
-}
-
-static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
-						unsigned int sg_count,
-						unsigned int len,
-						int write)
-{
-	int i;
-	int num_pages;
-	struct scatterlist *bounce_sgl;
-	struct page *page_buf;
-	unsigned int buf_len = ((write == WRITE_TYPE) ? 0 : PAGE_SIZE);
-
-	num_pages = ALIGN(len, PAGE_SIZE) >> PAGE_SHIFT;
-
-	bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
-	if (!bounce_sgl)
-		return NULL;
-
-	for (i = 0; i < num_pages; i++) {
-		page_buf = alloc_page(GFP_ATOMIC);
-		if (!page_buf)
-			goto cleanup;
-		sg_set_page(&bounce_sgl[i], page_buf, buf_len, 0);
-	}
-
-	return bounce_sgl;
-
-cleanup:
-	destroy_bounce_buffer(bounce_sgl, num_pages);
-	return NULL;
-}
-
-
-/* Assume the original sgl has enough room */
-static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
-					    struct scatterlist *bounce_sgl,
-					    unsigned int orig_sgl_count,
-					    unsigned int bounce_sgl_count)
-{
-	int i;
-	int j = 0;
-	unsigned long src, dest;
-	unsigned int srclen, destlen, copylen;
-	unsigned int total_copied = 0;
-	unsigned long bounce_addr = 0;
-	unsigned long dest_addr = 0;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	for (i = 0; i < orig_sgl_count; i++) {
-		dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
-					KM_IRQ0) + orig_sgl[i].offset;
-		dest = dest_addr;
-		destlen = orig_sgl[i].length;
-
-		if (bounce_addr == 0)
-			bounce_addr =
-			(unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])),
-							KM_IRQ0);
-
-		while (destlen) {
-			src = bounce_addr + bounce_sgl[j].offset;
-			srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
-
-			copylen = min(srclen, destlen);
-			memcpy((void *)dest, (void *)src, copylen);
-
-			total_copied += copylen;
-			bounce_sgl[j].offset += copylen;
-			destlen -= copylen;
-			dest += copylen;
-
-			if (bounce_sgl[j].offset == bounce_sgl[j].length) {
-				/* full */
-				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
-				j++;
-
-				/*
-				 * It is possible that the number of elements
-				 * in the bounce buffer may not be equal to
-				 * the number of elements in the original
-				 * scatter list. Handle this correctly.
-				 */
-
-				if (j == bounce_sgl_count) {
-					/*
-					 * We are done; cleanup and return.
-					 */
-					kunmap_atomic((void *)(dest_addr -
-							orig_sgl[i].offset),
-							KM_IRQ0);
-					local_irq_restore(flags);
-					return total_copied;
-				}
-
-				/* if we need to use another bounce buffer */
-				if (destlen || i != orig_sgl_count - 1)
-					bounce_addr =
-					(unsigned long)kmap_atomic(
-					sg_page((&bounce_sgl[j])), KM_IRQ0);
-			} else if (destlen == 0 && i == orig_sgl_count - 1) {
-				/* unmap the last bounce that is < PAGE_SIZE */
-				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
-			}
-		}
-
-		kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset),
-			      KM_IRQ0);
-	}
-
-	local_irq_restore(flags);
-
-	return total_copied;
-}
-
-
-/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
-static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
-					  struct scatterlist *bounce_sgl,
-					  unsigned int orig_sgl_count)
-{
-	int i;
-	int j = 0;
-	unsigned long src, dest;
-	unsigned int srclen, destlen, copylen;
-	unsigned int total_copied = 0;
-	unsigned long bounce_addr = 0;
-	unsigned long src_addr = 0;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	for (i = 0; i < orig_sgl_count; i++) {
-		src_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
-				KM_IRQ0) + orig_sgl[i].offset;
-		src = src_addr;
-		srclen = orig_sgl[i].length;
-
-		if (bounce_addr == 0)
-			bounce_addr =
-			(unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])),
-						KM_IRQ0);
-
-		while (srclen) {
-			/* assume bounce offset always == 0 */
-			dest = bounce_addr + bounce_sgl[j].length;
-			destlen = PAGE_SIZE - bounce_sgl[j].length;
-
-			copylen = min(srclen, destlen);
-			memcpy((void *)dest, (void *)src, copylen);
-
-			total_copied += copylen;
-			bounce_sgl[j].length += copylen;
-			srclen -= copylen;
-			src += copylen;
-
-			if (bounce_sgl[j].length == PAGE_SIZE) {
-				/* full..move to next entry */
-				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
-				j++;
-
-				/* if we need to use another bounce buffer */
-				if (srclen || i != orig_sgl_count - 1)
-					bounce_addr =
-					(unsigned long)kmap_atomic(
-					sg_page((&bounce_sgl[j])), KM_IRQ0);
-
-			} else if (srclen == 0 && i == orig_sgl_count - 1) {
-				/* unmap the last bounce that is < PAGE_SIZE */
-				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
-			}
-		}
-
-		kunmap_atomic((void *)(src_addr - orig_sgl[i].offset), KM_IRQ0);
-	}
-
-	local_irq_restore(flags);
-
-	return total_copied;
-}
-
-
-static int storvsc_remove(struct hv_device *dev)
-{
-	struct storvsc_device *stor_device = hv_get_drvdata(dev);
-	struct Scsi_Host *host = stor_device->host;
-
-	scsi_remove_host(host);
-
-	scsi_host_put(host);
-
-	storvsc_dev_remove(dev);
-
-	return 0;
-}
-
-
-static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
-			   sector_t capacity, int *info)
-{
-	sector_t nsect = capacity;
-	sector_t cylinders = nsect;
-	int heads, sectors_pt;
-
-	/*
-	 * We are making up these values; let us keep it simple.
-	 */
-	heads = 0xff;
-	sectors_pt = 0x3f;      /* Sectors per track */
-	sector_div(cylinders, heads * sectors_pt);
-	if ((sector_t)(cylinders + 1) * heads * sectors_pt < nsect)
-		cylinders = 0xffff;
-
-	info[0] = heads;
-	info[1] = sectors_pt;
-	info[2] = (int)cylinders;
-
-	return 0;
-}
-
-static int storvsc_host_reset(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-	struct hv_storvsc_request *request;
-	struct vstor_packet *vstor_packet;
-	int ret, t;
-
-
-	stor_device = get_out_stor_device(device);
-	if (!stor_device)
-		return FAILED;
-
-	request = &stor_device->reset_request;
-	vstor_packet = &request->vstor_packet;
-
-	init_completion(&request->wait_event);
-
-	vstor_packet->operation = VSTOR_OPERATION_RESET_BUS;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-	vstor_packet->vm_srb.path_id = stor_device->path_id;
-
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)&stor_device->reset_request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0)
-		return FAILED;
-
-	t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
-	if (t == 0)
-		return TIMEOUT_ERROR;
-
-
-	/*
-	 * At this point, all outstanding requests in the adapter
-	 * should have been flushed out and return to us
-	 */
-
-	return SUCCESS;
-}
-
-
-/*
- * storvsc_host_reset_handler - Reset the scsi HBA
- */
-static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
-{
-	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
-	struct hv_device *dev = host_dev->dev;
-
-	return storvsc_host_reset(dev);
-}
-
-
-/*
- * storvsc_command_completion - Command completion processing
- */
-static void storvsc_command_completion(struct hv_storvsc_request *request)
-{
-	struct storvsc_cmd_request *cmd_request =
-		(struct storvsc_cmd_request *)request->context;
-	struct scsi_cmnd *scmnd = cmd_request->cmd;
-	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
-	void (*scsi_done_fn)(struct scsi_cmnd *);
-	struct scsi_sense_hdr sense_hdr;
-	struct vmscsi_request *vm_srb;
-	struct storvsc_scan_work *wrk;
-	struct stor_mem_pools *memp = scmnd->device->hostdata;
-
-	vm_srb = &request->vstor_packet.vm_srb;
-	if (cmd_request->bounce_sgl_count) {
-		if (vm_srb->data_in == READ_TYPE)
-			copy_from_bounce_buffer(scsi_sglist(scmnd),
-					cmd_request->bounce_sgl,
-					scsi_sg_count(scmnd),
-					cmd_request->bounce_sgl_count);
-		destroy_bounce_buffer(cmd_request->bounce_sgl,
-					cmd_request->bounce_sgl_count);
-	}
-
-	/*
-	 * If there is an error; offline the device since all
-	 * error recovery strategies would have already been
-	 * deployed on the host side.
-	 */
-	if (vm_srb->srb_status == 0x4)
-		scmnd->result = DID_TARGET_FAILURE << 16;
-	else
-		scmnd->result = vm_srb->scsi_status;
-
-	/*
-	 * If the LUN is invalid; remove the device.
-	 */
-	if (vm_srb->srb_status == 0x20) {
-		struct storvsc_device *stor_dev;
-		struct hv_device *dev = host_dev->dev;
-		struct Scsi_Host *host;
-
-		stor_dev = get_in_stor_device(dev);
-		host = stor_dev->host;
-
-		wrk = kmalloc(sizeof(struct storvsc_scan_work),
-				GFP_ATOMIC);
-		if (!wrk) {
-			scmnd->result = DID_TARGET_FAILURE << 16;
-		} else {
-			wrk->host = host;
-			wrk->lun = vm_srb->lun;
-			INIT_WORK(&wrk->work, storvsc_remove_lun);
-			schedule_work(&wrk->work);
-		}
-	}
-
-	if (scmnd->result) {
-		if (scsi_normalize_sense(scmnd->sense_buffer,
-				SCSI_SENSE_BUFFERSIZE, &sense_hdr))
-			scsi_print_sense_hdr("storvsc", &sense_hdr);
-	}
-
-	scsi_set_resid(scmnd,
-		request->data_buffer.len -
-		vm_srb->data_transfer_length);
-
-	scsi_done_fn = scmnd->scsi_done;
-
-	scmnd->host_scribble = NULL;
-	scmnd->scsi_done = NULL;
-
-	scsi_done_fn(scmnd);
-
-	mempool_free(cmd_request, memp->request_mempool);
-}
-
-static bool storvsc_check_scsi_cmd(struct scsi_cmnd *scmnd)
-{
-	bool allowed = true;
-	u8 scsi_op = scmnd->cmnd[0];
-
-	switch (scsi_op) {
-	/* smartd sends this command, which will offline the device */
-	case SET_WINDOW:
-		scmnd->result = ILLEGAL_REQUEST << 16;
-		allowed = false;
-		break;
-	default:
-		break;
-	}
-	return allowed;
-}
-
-/*
- * storvsc_queuecommand - Initiate command processing
- */
-static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
-{
-	int ret;
-	struct hv_host_device *host_dev = shost_priv(host);
-	struct hv_device *dev = host_dev->dev;
-	struct hv_storvsc_request *request;
-	struct storvsc_cmd_request *cmd_request;
-	unsigned int request_size = 0;
-	int i;
-	struct scatterlist *sgl;
-	unsigned int sg_count = 0;
-	struct vmscsi_request *vm_srb;
-	struct stor_mem_pools *memp = scmnd->device->hostdata;
-
-	if (storvsc_check_scsi_cmd(scmnd) == false) {
-		scmnd->scsi_done(scmnd);
-		return 0;
-	}
-
-	/* If retrying, no need to prep the cmd */
-	if (scmnd->host_scribble) {
-
-		cmd_request =
-			(struct storvsc_cmd_request *)scmnd->host_scribble;
-
-		goto retry_request;
-	}
-
-	request_size = sizeof(struct storvsc_cmd_request);
-
-	cmd_request = mempool_alloc(memp->request_mempool,
-				       GFP_ATOMIC);
-	if (!cmd_request)
-		return SCSI_MLQUEUE_DEVICE_BUSY;
-
-	memset(cmd_request, 0, sizeof(struct storvsc_cmd_request));
-
-	/* Setup the cmd request */
-	cmd_request->bounce_sgl_count = 0;
-	cmd_request->bounce_sgl = NULL;
-	cmd_request->cmd = scmnd;
-
-	scmnd->host_scribble = (unsigned char *)cmd_request;
-
-	request = &cmd_request->request;
-	vm_srb = &request->vstor_packet.vm_srb;
-
-
-	/* Build the SRB */
-	switch (scmnd->sc_data_direction) {
-	case DMA_TO_DEVICE:
-		vm_srb->data_in = WRITE_TYPE;
-		break;
-	case DMA_FROM_DEVICE:
-		vm_srb->data_in = READ_TYPE;
-		break;
-	default:
-		vm_srb->data_in = UNKNOWN_TYPE;
-		break;
-	}
-
-	request->on_io_completion = storvsc_command_completion;
-	request->context = cmd_request;/* scmnd; */
-
-	vm_srb->port_number = host_dev->port;
-	vm_srb->path_id = scmnd->device->channel;
-	vm_srb->target_id = scmnd->device->id;
-	vm_srb->lun = scmnd->device->lun;
-
-	vm_srb->cdb_length = scmnd->cmd_len;
-
-	memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
-
-	request->sense_buffer = scmnd->sense_buffer;
-
-
-	request->data_buffer.len = scsi_bufflen(scmnd);
-	if (scsi_sg_count(scmnd)) {
-		sgl = (struct scatterlist *)scsi_sglist(scmnd);
-		sg_count = scsi_sg_count(scmnd);
-
-		/* check if we need to bounce the sgl */
-		if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
-			cmd_request->bounce_sgl =
-				create_bounce_buffer(sgl, scsi_sg_count(scmnd),
-						     scsi_bufflen(scmnd),
-						     vm_srb->data_in);
-			if (!cmd_request->bounce_sgl) {
-				scmnd->host_scribble = NULL;
-				mempool_free(cmd_request,
-						memp->request_mempool);
-
-				return SCSI_MLQUEUE_HOST_BUSY;
-			}
-
-			cmd_request->bounce_sgl_count =
-				ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
-					PAGE_SHIFT;
-
-			if (vm_srb->data_in == WRITE_TYPE)
-				copy_to_bounce_buffer(sgl,
-					cmd_request->bounce_sgl,
-					scsi_sg_count(scmnd));
-
-			sgl = cmd_request->bounce_sgl;
-			sg_count = cmd_request->bounce_sgl_count;
-		}
-
-		request->data_buffer.offset = sgl[0].offset;
-
-		for (i = 0; i < sg_count; i++)
-			request->data_buffer.pfn_array[i] =
-				page_to_pfn(sg_page((&sgl[i])));
-
-	} else if (scsi_sglist(scmnd)) {
-		request->data_buffer.offset =
-			virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
-		request->data_buffer.pfn_array[0] =
-			virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
-	}
-
-retry_request:
-	/* Invokes the vsc to start an IO */
-	ret = storvsc_do_io(dev, &cmd_request->request);
-
-	if (ret == -EAGAIN) {
-		/* no more space */
-
-		if (cmd_request->bounce_sgl_count)
-			destroy_bounce_buffer(cmd_request->bounce_sgl,
-					cmd_request->bounce_sgl_count);
-
-		mempool_free(cmd_request, memp->request_mempool);
-
-		scmnd->host_scribble = NULL;
-
-		ret = SCSI_MLQUEUE_DEVICE_BUSY;
-	}
-
-	return ret;
-}
-
-/* Scsi driver */
-static struct scsi_host_template scsi_driver = {
-	.module	=		THIS_MODULE,
-	.name =			"storvsc_host_t",
-	.bios_param =		storvsc_get_chs,
-	.queuecommand =		storvsc_queuecommand,
-	.eh_host_reset_handler =	storvsc_host_reset_handler,
-	.slave_alloc =		storvsc_device_alloc,
-	.slave_destroy =	storvsc_device_destroy,
-	.slave_configure =	storvsc_device_configure,
-	.cmd_per_lun =		1,
-	/* 64 max_queue * 1 target */
-	.can_queue =		STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
-	.this_id =		-1,
-	/* no use setting to 0 since ll_blk_rw reset it to 1 */
-	/* currently 32 */
-	.sg_tablesize =		MAX_MULTIPAGE_BUFFER_COUNT,
-	.use_clustering =	DISABLE_CLUSTERING,
-	/* Make sure we dont get a sg segment crosses a page boundary */
-	.dma_boundary =		PAGE_SIZE-1,
-};
-
-enum {
-	SCSI_GUID,
-	IDE_GUID,
-};
-
-static const struct hv_vmbus_device_id id_table[] = {
-	/* SCSI guid */
-	{ VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
-		       0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f)
-	  .driver_data = SCSI_GUID },
-	/* IDE guid */
-	{ VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-		       0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5)
-	  .driver_data = IDE_GUID },
-	{ },
-};
-
-MODULE_DEVICE_TABLE(vmbus, id_table);
-
-
-/*
- * storvsc_probe - Add a new device for this driver
- */
-
-static int storvsc_probe(struct hv_device *device,
-			const struct hv_vmbus_device_id *dev_id)
-{
-	int ret;
-	struct Scsi_Host *host;
-	struct hv_host_device *host_dev;
-	bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false);
-	int path = 0;
-	int target = 0;
-	struct storvsc_device *stor_device;
-
-	host = scsi_host_alloc(&scsi_driver,
-			       sizeof(struct hv_host_device));
-	if (!host)
-		return -ENOMEM;
-
-	host_dev = shost_priv(host);
-	memset(host_dev, 0, sizeof(struct hv_host_device));
-
-	host_dev->port = host->host_no;
-	host_dev->dev = device;
-
-
-	stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
-	if (!stor_device) {
-		ret = -ENOMEM;
-		goto err_out0;
-	}
-
-	stor_device->destroy = false;
-	init_waitqueue_head(&stor_device->waiting_to_drain);
-	stor_device->device = device;
-	stor_device->host = host;
-	hv_set_drvdata(device, stor_device);
-
-	stor_device->port_number = host->host_no;
-	ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
-	if (ret)
-		goto err_out1;
-
-	if (dev_is_ide)
-		storvsc_get_ide_info(device, &target, &path);
-
-	host_dev->path = stor_device->path_id;
-	host_dev->target = stor_device->target_id;
-
-	/* max # of devices per target */
-	host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
-	/* max # of targets per channel */
-	host->max_id = STORVSC_MAX_TARGETS;
-	/* max # of channels */
-	host->max_channel = STORVSC_MAX_CHANNELS - 1;
-	/* max cmd length */
-	host->max_cmd_len = STORVSC_MAX_CMD_LEN;
-
-	/* Register the HBA and start the scsi bus scan */
-	ret = scsi_add_host(host, &device->device);
-	if (ret != 0)
-		goto err_out2;
-
-	if (!dev_is_ide) {
-		scsi_scan_host(host);
-		return 0;
-	}
-	ret = scsi_add_device(host, 0, target, 0);
-	if (ret) {
-		scsi_remove_host(host);
-		goto err_out2;
-	}
-	return 0;
-
-err_out2:
-	/*
-	 * Once we have connected with the host, we would need to
-	 * to invoke storvsc_dev_remove() to rollback this state and
-	 * this call also frees up the stor_device; hence the jump around
-	 * err_out1 label.
-	 */
-	storvsc_dev_remove(device);
-	goto err_out0;
-
-err_out1:
-	kfree(stor_device);
-
-err_out0:
-	scsi_host_put(host);
-	return ret;
-}
-
-/* The one and only one */
-
-static struct hv_driver storvsc_drv = {
-	.name = KBUILD_MODNAME,
-	.id_table = id_table,
-	.probe = storvsc_probe,
-	.remove = storvsc_remove,
-};
-
-static int __init storvsc_drv_init(void)
-{
-	u32 max_outstanding_req_per_channel;
-
-	/*
-	 * Divide the ring buffer data size (which is 1 page less
-	 * than the ring buffer size since that page is reserved for
-	 * the ring buffer indices) by the max request size (which is
-	 * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
-	 */
-	max_outstanding_req_per_channel =
-		((storvsc_ringbuffer_size - PAGE_SIZE) /
-		ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
-		sizeof(struct vstor_packet) + sizeof(u64),
-		sizeof(u64)));
-
-	if (max_outstanding_req_per_channel <
-	    STORVSC_MAX_IO_REQUESTS)
-		return -EINVAL;
-
-	return vmbus_driver_register(&storvsc_drv);
-}
-
-static void __exit storvsc_drv_exit(void)
-{
-	vmbus_driver_unregister(&storvsc_drv);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_VERSION(HV_DRV_VERSION);
-MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver");
-module_init(storvsc_drv_init);
-module_exit(storvsc_drv_exit);
diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
new file mode 100644
index 0000000..0d21a27
--- /dev/null
+++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
@@ -0,0 +1,241 @@
+/* Industrialio event test code.
+ *
+ * Copyright (c) 2011-2012 Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is primarily intended as an example application.
+ * Reads the current buffer setup from sysfs and starts a short capture
+ * from the specified device, pretty printing the result after appropriate
+ * conversion.
+ *
+ * Usage:
+ *	iio_event_monitor <device_name>
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <unistd.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "iio_utils.h"
+#include "../events.h"
+
+static const char * const iio_chan_type_name_spec[] = {
+	[IIO_VOLTAGE] = "voltage",
+	[IIO_CURRENT] = "current",
+	[IIO_POWER] = "power",
+	[IIO_ACCEL] = "accel",
+	[IIO_ANGL_VEL] = "anglvel",
+	[IIO_MAGN] = "magn",
+	[IIO_LIGHT] = "illuminance",
+	[IIO_INTENSITY] = "intensity",
+	[IIO_PROXIMITY] = "proximity",
+	[IIO_TEMP] = "temp",
+	[IIO_INCLI] = "incli",
+	[IIO_ROT] = "rot",
+	[IIO_ANGL] = "angl",
+	[IIO_TIMESTAMP] = "timestamp",
+	[IIO_CAPACITANCE] = "capacitance",
+};
+
+static const char * const iio_ev_type_text[] = {
+	[IIO_EV_TYPE_THRESH] = "thresh",
+	[IIO_EV_TYPE_MAG] = "mag",
+	[IIO_EV_TYPE_ROC] = "roc",
+	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
+	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
+};
+
+static const char * const iio_ev_dir_text[] = {
+	[IIO_EV_DIR_EITHER] = "either",
+	[IIO_EV_DIR_RISING] = "rising",
+	[IIO_EV_DIR_FALLING] = "falling"
+};
+
+static const char * const iio_modifier_names[] = {
+	[IIO_MOD_X] = "x",
+	[IIO_MOD_Y] = "y",
+	[IIO_MOD_Z] = "z",
+	[IIO_MOD_LIGHT_BOTH] = "both",
+	[IIO_MOD_LIGHT_IR] = "ir",
+};
+
+static bool event_is_known(struct iio_event_data *event)
+{
+	enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
+	enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
+	enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
+	enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
+
+	switch (type) {
+	case IIO_VOLTAGE:
+	case IIO_CURRENT:
+	case IIO_POWER:
+	case IIO_ACCEL:
+	case IIO_ANGL_VEL:
+	case IIO_MAGN:
+	case IIO_LIGHT:
+	case IIO_INTENSITY:
+	case IIO_PROXIMITY:
+	case IIO_TEMP:
+	case IIO_INCLI:
+	case IIO_ROT:
+	case IIO_ANGL:
+	case IIO_TIMESTAMP:
+	case IIO_CAPACITANCE:
+		break;
+	default:
+		return false;
+	}
+
+	switch (mod) {
+	case IIO_NO_MOD:
+	case IIO_MOD_X:
+	case IIO_MOD_Y:
+	case IIO_MOD_Z:
+	case IIO_MOD_LIGHT_BOTH:
+	case IIO_MOD_LIGHT_IR:
+		break;
+	default:
+		return false;
+	}
+
+	switch (ev_type) {
+	case IIO_EV_TYPE_THRESH:
+	case IIO_EV_TYPE_MAG:
+	case IIO_EV_TYPE_ROC:
+	case IIO_EV_TYPE_THRESH_ADAPTIVE:
+	case IIO_EV_TYPE_MAG_ADAPTIVE:
+		break;
+	default:
+		return false;
+	}
+
+	switch (dir) {
+	case IIO_EV_DIR_EITHER:
+	case IIO_EV_DIR_RISING:
+	case IIO_EV_DIR_FALLING:
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static void print_event(struct iio_event_data *event)
+{
+	enum iio_chan_type type = IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event->id);
+	enum iio_modifier mod = IIO_EVENT_CODE_EXTRACT_MODIFIER(event->id);
+	enum iio_event_type ev_type = IIO_EVENT_CODE_EXTRACT_TYPE(event->id);
+	enum iio_event_direction dir = IIO_EVENT_CODE_EXTRACT_DIR(event->id);
+	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event->id);
+	int chan2 = IIO_EVENT_CODE_EXTRACT_CHAN2(event->id);
+	bool diff = IIO_EVENT_CODE_EXTRACT_DIFF(event->id);
+
+	if (!event_is_known(event)) {
+		printf("Unknown event: time: %lld, id: %llx\n",
+				event->timestamp, event->id);
+		return;
+	}
+
+	printf("Event: time: %lld, ", event->timestamp);
+
+	if (mod != IIO_NO_MOD) {
+		printf("type: %s(%s), ",
+			iio_chan_type_name_spec[type],
+			iio_modifier_names[mod]);
+	} else {
+		printf("type: %s, ",
+			iio_chan_type_name_spec[type]);
+	}
+
+	if (diff && chan >= 0 && chan2 >= 0)
+		printf("channel: %d-%d, ", chan, chan2);
+	else if (chan >= 0)
+		printf("channel: %d, ", chan);
+
+	printf("evtype: %s, direction: %s\n",
+		iio_ev_type_text[ev_type],
+		iio_ev_dir_text[dir]);
+}
+
+int main(int argc, char **argv)
+{
+	struct iio_event_data event;
+	const char *device_name;
+	char *chrdev_name;
+	int ret;
+	int dev_num;
+	int fd, event_fd;
+
+	if (argc <= 1) {
+		printf("Usage: %s <device_name>\n", argv[0]);
+		return -1;
+	}
+
+	device_name = argv[1];
+
+	dev_num = find_type_by_name(device_name, "iio:device");
+	if (dev_num >= 0) {
+		printf("Found IIO device with name %s with device number %d\n",
+			device_name, dev_num);
+		ret = asprintf(&chrdev_name, "/dev/iio:device%d", dev_num);
+		if (ret < 0) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+	} else {
+		/* If we can't find a IIO device by name assume device_name is a
+		   IIO chrdev */
+		chrdev_name = strdup(device_name);
+	}
+
+	fd = open(chrdev_name, 0);
+	if (fd == -1) {
+		fprintf(stdout, "Failed to open %s\n", chrdev_name);
+		ret = -errno;
+		goto error_free_chrdev_name;
+	}
+
+	ret = ioctl(fd, IIO_GET_EVENT_FD_IOCTL, &event_fd);
+
+	close(fd);
+
+	if (ret == -1 || event_fd == -1) {
+		fprintf(stdout, "Failed to retrieve event fd\n");
+		ret = -errno;
+		goto error_free_chrdev_name;
+	}
+
+	while (true) {
+		ret = read(event_fd, &event, sizeof(event));
+		if (ret == -1) {
+			if (errno == EAGAIN) {
+				printf("nothing available\n");
+				continue;
+			} else {
+				perror("Failed to read event from device");
+				ret = -errno;
+				break;
+			}
+		}
+
+		print_event(&event);
+	}
+
+	close(event_fd);
+error_free_chrdev_name:
+	free(chrdev_name);
+error_ret:
+	return ret;
+}
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
index 1340aea..657710b 100644
--- a/drivers/staging/iio/Makefile
+++ b/drivers/staging/iio/Makefile
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_IIO) += industrialio.o
-industrialio-y := industrialio-core.o
+industrialio-y := industrialio-core.o industrialio-event.o
 industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
 industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
 
diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c
index 26c610f..97f9e6b 100644
--- a/drivers/staging/iio/accel/adis16201_ring.c
+++ b/drivers/staging/iio/accel/adis16201_ring.c
@@ -115,9 +115,7 @@ int adis16201_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
 	ring->scan_timestamp = true;
-	ring->access = &ring_sw_access_funcs;
 	indio_dev->setup_ops = &adis16201_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c
index 064640d..6a8963d 100644
--- a/drivers/staging/iio/accel/adis16203_ring.c
+++ b/drivers/staging/iio/accel/adis16203_ring.c
@@ -117,9 +117,7 @@ int adis16203_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
 	ring->scan_timestamp = true;
-	ring->access = &ring_sw_access_funcs;
 	indio_dev->setup_ops = &adis16203_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c
index 4081179..5c8ab73 100644
--- a/drivers/staging/iio/accel/adis16204_ring.c
+++ b/drivers/staging/iio/accel/adis16204_ring.c
@@ -112,8 +112,6 @@ int adis16204_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
-	ring->access = &ring_sw_access_funcs;
 	ring->scan_timestamp = true;
 	indio_dev->setup_ops = &adis16204_ring_setup_ops;
 
diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c
index 2a6fd334..57254b6 100644
--- a/drivers/staging/iio/accel/adis16209_ring.c
+++ b/drivers/staging/iio/accel/adis16209_ring.c
@@ -113,8 +113,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
-	ring->access = &ring_sw_access_funcs;
 	ring->scan_timestamp = true;
 	indio_dev->setup_ops = &adis16209_ring_setup_ops;
 
diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c
index e23622d..43ba84e 100644
--- a/drivers/staging/iio/accel/adis16240_ring.c
+++ b/drivers/staging/iio/accel/adis16240_ring.c
@@ -110,8 +110,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
-	ring->access = &ring_sw_access_funcs;
 	ring->scan_timestamp = true;
 	indio_dev->setup_ops = &adis16240_ring_setup_ops;
 
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
index 2db383f..ae5f225 100644
--- a/drivers/staging/iio/accel/lis3l02dq.h
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -187,12 +187,10 @@ void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
 #ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
 #define lis3l02dq_free_buf iio_sw_rb_free
 #define lis3l02dq_alloc_buf iio_sw_rb_allocate
-#define lis3l02dq_access_funcs ring_sw_access_funcs
 #endif
 #ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
 #define lis3l02dq_free_buf iio_kfifo_free
 #define lis3l02dq_alloc_buf iio_kfifo_allocate
-#define lis3l02dq_access_funcs kfifo_access_funcs
 #endif
 irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
 #define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 98c5c92..ca0a1fe 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -406,8 +406,6 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
 		return -ENOMEM;
 
 	indio_dev->buffer = buffer;
-	/* Effectively select the buffer implementation */
-	indio_dev->buffer->access = &lis3l02dq_access_funcs;
 
 	buffer->scan_timestamp = true;
 	indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
index d9decea..592eabd 100644
--- a/drivers/staging/iio/adc/Kconfig
+++ b/drivers/staging/iio/adc/Kconfig
@@ -193,4 +193,13 @@ config MAX1363_RING_BUFFER
 	  Say yes here to include ring buffer support in the MAX1363
 	  ADC driver.
 
+config LPC32XX_ADC
+	tristate "NXP LPC32XX ADC"
+	depends on ARCH_LPC32XX && !TOUCHSCREEN_LPC32XX
+	help
+	  Say yes here to build support for the integrated ADC inside the
+	  LPC32XX SoC. Note that this feature uses the same hardware as the
+	  touchscreen driver, so you can only select one of the two drivers
+	  (lpc32xx_adc or lpc32xx_ts). Provides direct access via sysfs.
+
 endmenu
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
index ceee7f3..f83ab95 100644
--- a/drivers/staging/iio/adc/Makefile
+++ b/drivers/staging/iio/adc/Makefile
@@ -37,3 +37,4 @@ obj-$(CONFIG_AD7192) += ad7192.o
 obj-$(CONFIG_ADT7310) += adt7310.o
 obj-$(CONFIG_ADT7410) += adt7410.o
 obj-$(CONFIG_AD7280) += ad7280a.o
+obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index 45f4504..9fd6d63 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -561,8 +561,6 @@ static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &ad7192_trigger_handler,
 						 IRQF_ONESHOT,
@@ -824,25 +822,20 @@ static struct attribute *ad7192_attributes[] = {
 	NULL
 };
 
-static umode_t ad7192_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7192_state *st = iio_priv(indio_dev);
-
-	umode_t mode = attr->mode;
-
-	if ((st->devid != ID_AD7195) &&
-		(attr == &iio_dev_attr_ac_excitation_en.dev_attr.attr))
-		mode = 0;
-
-	return mode;
-}
-
 static const struct attribute_group ad7192_attribute_group = {
 	.attrs = ad7192_attributes,
-	.is_visible = ad7192_attr_is_visible,
+};
+
+static struct attribute *ad7195_attributes[] = {
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_in_v_m_v_scale_available.dev_attr.attr,
+	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
+	&iio_dev_attr_bridge_switch_en.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group ad7195_attribute_group = {
+	.attrs = ad7195_attributes,
 };
 
 static int ad7192_read_raw(struct iio_dev *indio_dev,
@@ -972,6 +965,15 @@ static const struct iio_info ad7192_info = {
 	.driver_module = THIS_MODULE,
 };
 
+static const struct iio_info ad7195_info = {
+	.read_raw = &ad7192_read_raw,
+	.write_raw = &ad7192_write_raw,
+	.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
+	.attrs = &ad7195_attribute_group,
+	.validate_trigger = ad7192_validate_trigger,
+	.driver_module = THIS_MODULE,
+};
+
 #define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si)		\
 	{ .type = IIO_VOLTAGE,						\
 	  .differential = 1,						\
@@ -1064,7 +1066,10 @@ static int __devinit ad7192_probe(struct spi_device *spi)
 	indio_dev->channels = ad7192_channels;
 	indio_dev->num_channels = ARRAY_SIZE(ad7192_channels);
 	indio_dev->available_scan_masks = st->available_scan_masks;
-	indio_dev->info = &ad7192_info;
+	if (st->devid == ID_AD7195)
+		indio_dev->info = &ad7195_info;
+	else
+		indio_dev->info = &ad7192_info;
 
 	for (i = 0; i < indio_dev->num_channels; i++)
 		st->available_scan_masks[i] = (1 << i) | (1 <<
diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c
index 0a13616..81d6b61 100644
--- a/drivers/staging/iio/adc/ad7291.c
+++ b/drivers/staging/iio/adc/ad7291.c
@@ -321,7 +321,7 @@ static int ad7291_read_event_value(struct iio_dev *indio_dev,
 
 	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
 	case IIO_VOLTAGE:
-		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]
+		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]
 			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			   IIO_EV_DIR_RISING)];
 
@@ -359,7 +359,7 @@ static int ad7291_write_event_value(struct iio_dev *indio_dev,
 	case IIO_VOLTAGE:
 		if (val > AD7291_VALUE_MASK || val < 0)
 			return -EINVAL;
-		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_NUM(event_code)]
+		reg = ad7291_limit_regs[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]
 			[!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			   IIO_EV_DIR_RISING)];
 		return ad7291_i2c_write(chip, reg, val);
@@ -386,7 +386,7 @@ static int ad7291_read_event_config(struct iio_dev *indio_dev,
 	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
 	case IIO_VOLTAGE:
 		if (chip->c_mask &
-		    (1 << (15 - IIO_EVENT_CODE_EXTRACT_NUM(event_code))))
+		    (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))
 			return 1;
 		else
 			return 0;
@@ -418,12 +418,12 @@ static int ad7291_write_event_config(struct iio_dev *indio_dev,
 	switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
 	case IIO_VOLTAGE:
 		if ((!state) && (chip->c_mask & (1 << (15 -
-				IIO_EVENT_CODE_EXTRACT_NUM(event_code)))))
-			chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_NUM
+				IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))
+			chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
 							(event_code)));
 		else if (state && (!(chip->c_mask & (1 << (15 -
-				IIO_EVENT_CODE_EXTRACT_NUM(event_code))))))
-			chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_NUM
+				IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))))
+			chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
 							(event_code)));
 		else
 			break;
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index d1a12dd..feeb0ee 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -131,9 +131,6 @@ int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
-
 	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
 						 &ad7298_trigger_handler,
 						 IRQF_ONESHOT,
diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c
index 4e298b2..35a8576 100644
--- a/drivers/staging/iio/adc/ad7476_ring.c
+++ b/drivers/staging/iio/adc/ad7476_ring.c
@@ -98,8 +98,6 @@ int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc
 		= iio_alloc_pollfunc(NULL,
 				     &ad7476_trigger_handler,
diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c
index ddb7ef9..97e8d3d 100644
--- a/drivers/staging/iio/adc/ad7606_core.c
+++ b/drivers/staging/iio/adc/ad7606_core.c
@@ -197,7 +197,7 @@ static IIO_DEVICE_ATTR(oversampling_ratio, S_IRUGO | S_IWUSR,
 		       ad7606_store_oversampling_ratio, 0);
 static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64");
 
-static struct attribute *ad7606_attributes[] = {
+static struct attribute *ad7606_attributes_os_and_range[] = {
 	&iio_dev_attr_in_voltage_range.dev_attr.attr,
 	&iio_const_attr_in_voltage_range_available.dev_attr.attr,
 	&iio_dev_attr_oversampling_ratio.dev_attr.attr,
@@ -205,34 +205,28 @@ static struct attribute *ad7606_attributes[] = {
 	NULL,
 };
 
-static umode_t ad7606_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_priv(indio_dev);
+static const struct attribute_group ad7606_attribute_group_os_and_range = {
+	.attrs = ad7606_attributes_os_and_range,
+};
 
-	umode_t mode = attr->mode;
-
-	if (!(gpio_is_valid(st->pdata->gpio_os0) &&
-	      gpio_is_valid(st->pdata->gpio_os1) &&
-	      gpio_is_valid(st->pdata->gpio_os2)) &&
-	    (attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr ||
-	     attr ==
-	     &iio_const_attr_oversampling_ratio_available.dev_attr.attr))
-		mode = 0;
-	else if (!gpio_is_valid(st->pdata->gpio_range) &&
-		 (attr == &iio_dev_attr_in_voltage_range.dev_attr.attr ||
-		  attr ==
-		  &iio_const_attr_in_voltage_range_available.dev_attr.attr))
-		mode = 0;
-
-	return mode;
-}
+static struct attribute *ad7606_attributes_os[] = {
+	&iio_dev_attr_oversampling_ratio.dev_attr.attr,
+	&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
+	NULL,
+};
 
-static const struct attribute_group ad7606_attribute_group = {
-	.attrs = ad7606_attributes,
-	.is_visible = ad7606_attr_is_visible,
+static const struct attribute_group ad7606_attribute_group_os = {
+	.attrs = ad7606_attributes_os,
+};
+
+static struct attribute *ad7606_attributes_range[] = {
+	&iio_dev_attr_in_voltage_range.dev_attr.attr,
+	&iio_const_attr_in_voltage_range_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad7606_attribute_group_range = {
+	.attrs = ad7606_attributes_range,
 };
 
 #define AD7606_CHANNEL(num)				\
@@ -435,10 +429,27 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 };
 
-static const struct iio_info ad7606_info = {
+static const struct iio_info ad7606_info_no_os_or_range = {
 	.driver_module = THIS_MODULE,
 	.read_raw = &ad7606_read_raw,
-	.attrs = &ad7606_attribute_group,
+};
+
+static const struct iio_info ad7606_info_os_and_range = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7606_read_raw,
+	.attrs = &ad7606_attribute_group_os_and_range,
+};
+
+static const struct iio_info ad7606_info_os = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7606_read_raw,
+	.attrs = &ad7606_attribute_group_os,
+};
+
+static const struct iio_info ad7606_info_range = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7606_read_raw,
+	.attrs = &ad7606_attribute_group_range,
 };
 
 struct iio_dev *ad7606_probe(struct device *dev, int irq,
@@ -483,7 +494,19 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
 	st->chip_info = &ad7606_chip_info_tbl[id];
 
 	indio_dev->dev.parent = dev;
-	indio_dev->info = &ad7606_info;
+	if (gpio_is_valid(st->pdata->gpio_os0) &&
+	    gpio_is_valid(st->pdata->gpio_os1) &&
+	    gpio_is_valid(st->pdata->gpio_os2)) {
+		if (gpio_is_valid(st->pdata->gpio_range))
+			indio_dev->info = &ad7606_info_os_and_range;
+		else
+			indio_dev->info = &ad7606_info_os;
+	} else {
+		if (gpio_is_valid(st->pdata->gpio_range))
+			indio_dev->info = &ad7606_info_range;
+		else
+			indio_dev->info = &ad7606_info_no_os_or_range;
+	}
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->name = st->chip_info->name;
 	indio_dev->channels = st->chip_info->channels;
diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c
index e8f94a1..1ef9fbc 100644
--- a/drivers/staging/iio/adc/ad7606_ring.c
+++ b/drivers/staging/iio/adc/ad7606_ring.c
@@ -110,8 +110,6 @@ int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		goto error_ret;
 	}
 
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
 						 &ad7606_trigger_handler_th_bh,
 						 0,
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c
index 6a058b1..84ecde1 100644
--- a/drivers/staging/iio/adc/ad7793.c
+++ b/drivers/staging/iio/adc/ad7793.c
@@ -427,8 +427,6 @@ static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &ad7793_trigger_handler,
 						 IRQF_ONESHOT,
diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c
index 85076cd..d180907 100644
--- a/drivers/staging/iio/adc/ad7887_ring.c
+++ b/drivers/staging/iio/adc/ad7887_ring.c
@@ -131,8 +131,6 @@ int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
 						 &ad7887_trigger_handler,
 						 IRQF_ONESHOT,
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c
index d5b581d..a845866 100644
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -256,7 +256,7 @@ static int ad799x_write_event_value(struct iio_dev *indio_dev,
 	struct ad799x_state *st = iio_priv(indio_dev);
 	int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			   IIO_EV_DIR_FALLING);
-	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 
 	mutex_lock(&indio_dev->mlock);
 	ret = ad799x_i2c_write16(st,
@@ -275,7 +275,7 @@ static int ad799x_read_event_value(struct iio_dev *indio_dev,
 	struct ad799x_state *st = iio_priv(indio_dev);
 	int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			   IIO_EV_DIR_FALLING);
-	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 	u16 valin;
 
 	mutex_lock(&indio_dev->mlock);
diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c
index 5dded9e..28e9a41 100644
--- a/drivers/staging/iio/adc/ad799x_ring.c
+++ b/drivers/staging/iio/adc/ad799x_ring.c
@@ -141,8 +141,6 @@ int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
 						 &ad799x_trigger_handler,
 						 IRQF_ONESHOT,
diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
index eec2f32..caf57c1 100644
--- a/drivers/staging/iio/adc/adt7310.c
+++ b/drivers/staging/iio/adc/adt7310.c
@@ -725,32 +725,19 @@ static struct attribute *adt7310_event_int_attributes[] = {
 	&iio_dev_attr_fault_queue.dev_attr.attr,
 	&iio_dev_attr_t_alarm_high.dev_attr.attr,
 	&iio_dev_attr_t_alarm_low.dev_attr.attr,
-	&iio_dev_attr_t_hyst.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute *adt7310_event_ct_attributes[] = {
-	&iio_dev_attr_event_mode.dev_attr.attr,
-	&iio_dev_attr_available_event_modes.dev_attr.attr,
-	&iio_dev_attr_fault_queue.dev_attr.attr,
 	&iio_dev_attr_t_crit.dev_attr.attr,
 	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
-static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
-	{
-		.attrs = adt7310_event_int_attributes,
-		.name = "events",
-	}, {
-		.attrs = adt7310_event_ct_attributes,
-		.name = "events",
-	}
+static struct attribute_group adt7310_event_attribute_group = {
+	.attrs = adt7310_event_int_attributes,
+	.name = "events",
 };
 
 static const struct iio_info adt7310_info = {
 	.attrs = &adt7310_attribute_group,
-	.event_attrs = adt7310_event_attribute_group,
+	.event_attrs = &adt7310_event_attribute_group,
 	.driver_module = THIS_MODULE,
 };
 
diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
index c62248c..dff3e8c 100644
--- a/drivers/staging/iio/adc/adt7410.c
+++ b/drivers/staging/iio/adc/adt7410.c
@@ -693,32 +693,19 @@ static struct attribute *adt7410_event_int_attributes[] = {
 	&iio_dev_attr_fault_queue.dev_attr.attr,
 	&iio_dev_attr_t_alarm_high.dev_attr.attr,
 	&iio_dev_attr_t_alarm_low.dev_attr.attr,
-	&iio_dev_attr_t_hyst.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute *adt7410_event_ct_attributes[] = {
-	&iio_dev_attr_event_mode.dev_attr.attr,
-	&iio_dev_attr_available_event_modes.dev_attr.attr,
-	&iio_dev_attr_fault_queue.dev_attr.attr,
 	&iio_dev_attr_t_crit.dev_attr.attr,
 	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
-static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
-	{
-		.attrs = adt7410_event_int_attributes,
-		.name = "events",
-	}, {
-		.attrs = adt7410_event_ct_attributes,
-		.name = "events",
-	}
+static struct attribute_group adt7410_event_attribute_group = {
+	.attrs = adt7410_event_int_attributes,
+	.name = "events",
 };
 
 static const struct iio_info adt7410_info = {
 	.attrs = &adt7410_attribute_group,
-	.event_attrs = adt7410_event_attribute_group,
+	.event_attrs = &adt7410_event_attribute_group,
 	.driver_module = THIS_MODULE,
 };
 
diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c
new file mode 100644
index 0000000..dfc9033
--- /dev/null
+++ b/drivers/staging/iio/adc/lpc32xx_adc.c
@@ -0,0 +1,237 @@
+/*
+ *  lpc32xx_adc.c - Support for ADC in LPC32XX
+ *
+ *  3-channel, 10-bit ADC
+ *
+ *  Copyright (C) 2011, 2012 Roland Stigge <stigge@antcom.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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/completion.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+/*
+ * LPC32XX registers definitions
+ */
+#define LPC32XX_ADC_SELECT(x)	((x) + 0x04)
+#define LPC32XX_ADC_CTRL(x)	((x) + 0x08)
+#define LPC32XX_ADC_VALUE(x)	((x) + 0x48)
+
+/* Bit definitions for LPC32XX_ADC_SELECT: */
+#define AD_REFm         0x00000200 /* constant, always write this value! */
+#define AD_REFp		0x00000080 /* constant, always write this value! */
+#define AD_IN		0x00000010 /* multiple of this is the */
+				   /* channel number: 0, 1, 2 */
+#define AD_INTERNAL	0x00000004 /* constant, always write this value! */
+
+/* Bit definitions for LPC32XX_ADC_CTRL: */
+#define AD_STROBE	0x00000002
+#define AD_PDN_CTRL	0x00000004
+
+/* Bit definitions for LPC32XX_ADC_VALUE: */
+#define ADC_VALUE_MASK	0x000003FF
+
+#define MOD_NAME "lpc32xx-adc"
+
+struct lpc32xx_adc_info {
+	void __iomem *adc_base;
+	struct clk *clk;
+	struct completion completion;
+
+	u32 value;
+};
+
+static int lpc32xx_read_raw(struct iio_dev *indio_dev,
+				struct iio_chan_spec const *chan,
+				int *val,
+				int *val2,
+				long mask)
+{
+	struct lpc32xx_adc_info *info = iio_priv(indio_dev);
+
+	if (mask == 0) {
+		mutex_lock(&indio_dev->mlock);
+		clk_enable(info->clk);
+		/* Measurement setup */
+		__raw_writel(AD_INTERNAL | (chan->address) | AD_REFp | AD_REFm,
+			LPC32XX_ADC_SELECT(info->adc_base));
+		/* Trigger conversion */
+		__raw_writel(AD_PDN_CTRL | AD_STROBE,
+			LPC32XX_ADC_CTRL(info->adc_base));
+		wait_for_completion(&info->completion); /* set by ISR */
+		clk_disable(info->clk);
+		*val = info->value;
+		mutex_unlock(&indio_dev->mlock);
+
+		return IIO_VAL_INT;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_info lpc32xx_adc_iio_info = {
+	.read_raw = &lpc32xx_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+#define LPC32XX_ADC_CHANNEL(_index) {		\
+	.type = IIO_VOLTAGE,			\
+	.indexed = 1,				\
+	.channel = _index,			\
+	.address = AD_IN * _index,		\
+	.scan_index = _index,			\
+}
+
+static struct iio_chan_spec lpc32xx_adc_iio_channels[] = {
+	LPC32XX_ADC_CHANNEL(0),
+	LPC32XX_ADC_CHANNEL(1),
+	LPC32XX_ADC_CHANNEL(2),
+};
+
+static irqreturn_t lpc32xx_adc_isr(int irq, void *dev_id)
+{
+	struct lpc32xx_adc_info *info = (struct lpc32xx_adc_info *) dev_id;
+
+	/* Read value and clear irq */
+	info->value = __raw_readl(LPC32XX_ADC_VALUE(info->adc_base)) &
+				ADC_VALUE_MASK;
+	complete(&info->completion);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit lpc32xx_adc_probe(struct platform_device *pdev)
+{
+	struct lpc32xx_adc_info *info = NULL;
+	struct resource *res;
+	int retval = -ENODEV;
+	struct iio_dev *iodev = NULL;
+	int irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get platform I/O memory\n");
+		retval = -EBUSY;
+		goto errout1;
+	}
+
+	iodev = iio_allocate_device(sizeof(struct lpc32xx_adc_info));
+	if (!iodev) {
+		dev_err(&pdev->dev, "failed allocating iio device\n");
+		retval = -ENOMEM;
+		goto errout1;
+	}
+
+	info = iio_priv(iodev);
+
+	info->adc_base = ioremap(res->start, res->end - res->start + 1);
+	if (!info->adc_base) {
+		dev_err(&pdev->dev, "failed mapping memory\n");
+		retval = -EBUSY;
+		goto errout2;
+	}
+
+	info->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(info->clk)) {
+		dev_err(&pdev->dev, "failed getting clock\n");
+		goto errout3;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if ((irq < 0) || (irq >= NR_IRQS)) {
+		dev_err(&pdev->dev, "failed getting interrupt resource\n");
+		retval = -EINVAL;
+		goto errout4;
+	}
+
+	retval = request_irq(irq, lpc32xx_adc_isr, 0, MOD_NAME, info);
+	if (retval < 0) {
+		dev_err(&pdev->dev, "failed requesting interrupt\n");
+		goto errout4;
+	}
+
+	platform_set_drvdata(pdev, iodev);
+
+	init_completion(&info->completion);
+
+	iodev->name = MOD_NAME;
+	iodev->dev.parent = &pdev->dev;
+	iodev->info = &lpc32xx_adc_iio_info;
+	iodev->modes = INDIO_DIRECT_MODE;
+	iodev->channels = lpc32xx_adc_iio_channels;
+	iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels);
+
+	retval = iio_device_register(iodev);
+	if (retval)
+		goto errout5;
+
+	dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
+
+	return 0;
+
+errout5:
+	free_irq(irq, iodev);
+errout4:
+	clk_put(info->clk);
+errout3:
+	iounmap(info->adc_base);
+errout2:
+	iio_free_device(iodev);
+errout1:
+	return retval;
+}
+
+static int __devexit lpc32xx_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *iodev = platform_get_drvdata(pdev);
+	struct lpc32xx_adc_info *info = iio_priv(iodev);
+	int irq = platform_get_irq(pdev, 0);
+
+	iio_device_unregister(iodev);
+	free_irq(irq, iodev);
+	platform_set_drvdata(pdev, NULL);
+	clk_put(info->clk);
+	iounmap(info->adc_base);
+	iio_free_device(iodev);
+
+	return 0;
+}
+
+static struct platform_driver lpc32xx_adc_driver = {
+	.probe		= lpc32xx_adc_probe,
+	.remove		= __devexit_p(lpc32xx_adc_remove),
+	.driver		= {
+		.name	= MOD_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(lpc32xx_adc_driver);
+
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("LPC32XX ADC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
index b92cb4a..3a5bd20 100644
--- a/drivers/staging/iio/adc/max1363_core.c
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -543,9 +543,9 @@ static int max1363_read_thresh(struct iio_dev *indio_dev,
 {
 	struct max1363_state *st = iio_priv(indio_dev);
 	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
-		*val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)];
+		*val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)];
 	else
-		*val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)];
+		*val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)];
 	return 0;
 }
 
@@ -568,10 +568,10 @@ static int max1363_write_thresh(struct iio_dev *indio_dev,
 
 	switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
 	case IIO_EV_DIR_FALLING:
-		st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val;
+		st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val;
 		break;
 	case IIO_EV_DIR_RISING:
-		st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val;
+		st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val;
 		break;
 	}
 
@@ -622,7 +622,7 @@ static int max1363_read_event_config(struct iio_dev *indio_dev,
 	struct max1363_state *st = iio_priv(indio_dev);
 
 	int val;
-	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 	mutex_lock(&indio_dev->mlock);
 	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
 		val = (1 << number) & st->mask_low;
@@ -775,7 +775,7 @@ static int max1363_write_event_config(struct iio_dev *indio_dev,
 	int ret = 0;
 	struct max1363_state *st = iio_priv(indio_dev);
 	u16 unifiedmask;
-	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 
 	mutex_lock(&indio_dev->mlock);
 	unifiedmask = st->mask_low | st->mask_high;
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
index f730b3f..d0a60a3 100644
--- a/drivers/staging/iio/adc/max1363_ring.c
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -116,8 +116,6 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
 	}
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->setup_ops = &max1363_ring_setup_ops;
 
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index b73007d..e4a08dc 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -167,7 +167,7 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
 	u16 value;
 	u8 sens, timeout;
 	struct ad7150_chip_info *chip = iio_priv(indio_dev);
-	int chan = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			IIO_EV_DIR_RISING);
 
@@ -279,7 +279,7 @@ static int ad7150_read_event_value(struct iio_dev *indio_dev,
 				   u64 event_code,
 				   int *val)
 {
-	int chan = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 	struct ad7150_chip_info *chip = iio_priv(indio_dev);
 	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			IIO_EV_DIR_RISING);
@@ -309,7 +309,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev,
 {
 	int ret;
 	struct ad7150_chip_info *chip = iio_priv(indio_dev);
-	int chan = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
 			IIO_EV_DIR_RISING);
 
@@ -347,7 +347,7 @@ static ssize_t ad7150_show_timeout(struct device *dev,
 	u8 value;
 
 	/* use the event code for consistency reasons */
-	int chan = IIO_EVENT_CODE_EXTRACT_NUM(this_attr->address);
+	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
 	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address)
 			== IIO_EV_DIR_RISING);
 
@@ -373,7 +373,7 @@ static ssize_t ad7150_store_timeout(struct device *dev,
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad7150_chip_info *chip = iio_priv(indio_dev);
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int chan = IIO_EVENT_CODE_EXTRACT_NUM(this_attr->address);
+	int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
 	int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) ==
 			IIO_EV_DIR_RISING);
 	u8 data;
diff --git a/drivers/staging/iio/dac/ad5360.c b/drivers/staging/iio/dac/ad5360.c
index 710b256..cec3693 100644
--- a/drivers/staging/iio/dac/ad5360.c
+++ b/drivers/staging/iio/dac/ad5360.c
@@ -439,8 +439,8 @@ static int __devinit ad5360_alloc_channels(struct iio_dev *indio_dev)
 	struct iio_chan_spec *channels;
 	unsigned int i;
 
-	channels = kcalloc(sizeof(struct iio_chan_spec),
-			st->chip_info->num_channels, GFP_KERNEL);
+	channels = kcalloc(st->chip_info->num_channels,
+			   sizeof(struct iio_chan_spec), GFP_KERNEL);
 
 	if (!channels)
 		return -ENOMEM;
diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c
index eff97ae0..4c50716 100644
--- a/drivers/staging/iio/dac/ad5380.c
+++ b/drivers/staging/iio/dac/ad5380.c
@@ -363,8 +363,8 @@ static int __devinit ad5380_alloc_channels(struct iio_dev *indio_dev)
 	struct iio_chan_spec *channels;
 	unsigned int i;
 
-	channels = kcalloc(sizeof(struct iio_chan_spec),
-			st->chip_info->num_channels, GFP_KERNEL);
+	channels = kcalloc(st->chip_info->num_channels,
+			   sizeof(struct iio_chan_spec), GFP_KERNEL);
 
 	if (!channels)
 		return -ENOMEM;
diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c
index 693e748..e439bae 100644
--- a/drivers/staging/iio/dac/ad5446.c
+++ b/drivers/staging/iio/dac/ad5446.c
@@ -149,30 +149,8 @@ static struct attribute *ad5446_attributes[] = {
 	NULL,
 };
 
-static umode_t ad5446_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5446_state *st = iio_priv(indio_dev);
-
-	umode_t mode = attr->mode;
-
-	if (!st->chip_info->store_pwr_down &&
-		(attr == &iio_dev_attr_out_voltage0_powerdown.dev_attr.attr ||
-		attr == &iio_dev_attr_out_voltage_powerdown_mode.
-		 dev_attr.attr ||
-		attr ==
-		&iio_const_attr_out_voltage_powerdown_mode_available.
-		 dev_attr.attr))
-		mode = 0;
-
-	return mode;
-}
-
 static const struct attribute_group ad5446_attribute_group = {
 	.attrs = ad5446_attributes,
-	.is_visible = ad5446_attr_is_visible,
 };
 
 #define AD5446_CHANNEL(bits, storage, shift) { \
@@ -321,6 +299,12 @@ static const struct iio_info ad5446_info = {
 	.driver_module = THIS_MODULE,
 };
 
+static const struct iio_info ad5446_info_no_pwr_down = {
+	.read_raw = ad5446_read_raw,
+	.write_raw = ad5446_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5446_probe(struct spi_device *spi)
 {
 	struct ad5446_state *st;
@@ -353,7 +337,10 @@ static int __devinit ad5446_probe(struct spi_device *spi)
 	/* Estabilish that the iio_dev is a child of the spi device */
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = spi_get_device_id(spi)->name;
-	indio_dev->info = &ad5446_info;
+	if (st->chip_info->store_pwr_down)
+		indio_dev->info = &ad5446_info;
+	else
+		indio_dev->info = &ad5446_info_no_pwr_down;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = &st->chip_info->channel;
 	indio_dev->num_channels = 1;
diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c
index ce2d619..2415a6e 100644
--- a/drivers/staging/iio/dac/ad5686.c
+++ b/drivers/staging/iio/dac/ad5686.c
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/regulator/consumer.h>
-#include <linux/module.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c
index 5e67104..38a2de0 100644
--- a/drivers/staging/iio/dds/ad9834.c
+++ b/drivers/staging/iio/dds/ad9834.c
@@ -281,29 +281,27 @@ static struct attribute *ad9834_attributes[] = {
 	NULL,
 };
 
-static umode_t ad9834_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad9834_state *st = iio_priv(indio_dev);
-
-	umode_t mode = attr->mode;
-
-	if (((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) &&
-		((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) ||
-		(attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) ||
-		(attr ==
-		&iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr) ||
-		(attr == &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr)))
-		mode = 0;
-
-	return mode;
-}
+static struct attribute *ad9833_attributes[] = {
+	&iio_dev_attr_dds0_freq0.dev_attr.attr,
+	&iio_dev_attr_dds0_freq1.dev_attr.attr,
+	&iio_const_attr_dds0_freq_scale.dev_attr.attr,
+	&iio_dev_attr_dds0_phase0.dev_attr.attr,
+	&iio_dev_attr_dds0_phase1.dev_attr.attr,
+	&iio_const_attr_dds0_phase_scale.dev_attr.attr,
+	&iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
+	&iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
+	&iio_dev_attr_dds0_out_enable.dev_attr.attr,
+	&iio_dev_attr_dds0_out0_wavetype.dev_attr.attr,
+	&iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr,
+	NULL,
+};
 
 static const struct attribute_group ad9834_attribute_group = {
 	.attrs = ad9834_attributes,
-	.is_visible = ad9834_attr_is_visible,
+};
+
+static const struct attribute_group ad9833_attribute_group = {
+	.attrs = ad9833_attributes,
 };
 
 static const struct iio_info ad9834_info = {
@@ -311,6 +309,11 @@ static const struct iio_info ad9834_info = {
 	.driver_module = THIS_MODULE,
 };
 
+static const struct iio_info ad9833_info = {
+	.attrs = &ad9833_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9834_probe(struct spi_device *spi)
 {
 	struct ad9834_platform_data *pdata = spi->dev.platform_data;
@@ -344,7 +347,15 @@ static int __devinit ad9834_probe(struct spi_device *spi)
 	st->reg = reg;
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = spi_get_device_id(spi)->name;
-	indio_dev->info = &ad9834_info;
+	switch (st->devid) {
+	case ID_AD9833:
+	case ID_AD9837:
+		indio_dev->info = &ad9833_info;
+		break;
+	default:
+		indio_dev->info = &ad9834_info;
+		break;
+	}
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default messages */
diff --git a/drivers/staging/iio/events.h b/drivers/staging/iio/events.h
index bfb6340..c25f0e3 100644
--- a/drivers/staging/iio/events.h
+++ b/drivers/staging/iio/events.h
@@ -96,8 +96,10 @@ enum iio_event_direction {
 
 /* Event code number extraction depends on which type of event we have.
  * Perhaps review this function in the future*/
-#define IIO_EVENT_CODE_EXTRACT_NUM(mask) ((__s16)(mask & 0xFFFF))
+#define IIO_EVENT_CODE_EXTRACT_CHAN(mask) ((__s16)(mask & 0xFFFF))
+#define IIO_EVENT_CODE_EXTRACT_CHAN2(mask) ((__s16)(((mask) >> 16) & 0xFFFF))
 
 #define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 40) & 0xFF)
+#define IIO_EVENT_CODE_EXTRACT_DIFF(mask) (((mask) >> 55) & 0x1)
 
 #endif
diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c
index 699a615..711f151 100644
--- a/drivers/staging/iio/gyro/adis16260_ring.c
+++ b/drivers/staging/iio/gyro/adis16260_ring.c
@@ -115,8 +115,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
-	ring->access = &ring_sw_access_funcs;
 	ring->scan_timestamp = true;
 	indio_dev->setup_ops = &adis16260_ring_setup_ops;
 
diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h
index 107cfb1..c9dfcba 100644
--- a/drivers/staging/iio/iio_core.h
+++ b/drivers/staging/iio/iio_core.h
@@ -49,4 +49,8 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 
 #endif
 
+int iio_device_register_eventset(struct iio_dev *indio_dev);
+void iio_device_unregister_eventset(struct iio_dev *indio_dev);
+int iio_event_getfd(struct iio_dev *indio_dev);
+
 #endif
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index d6a1c0e..bb4daf7 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -142,8 +142,6 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
 	}
 
 	indio_dev->buffer = buffer;
-	/* Tell the core how to access the buffer */
-	buffer->access = &kfifo_access_funcs;
 
 	/* Enable timestamps by default */
 	buffer->scan_timestamp = true;
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 9a2ca55..cd82b56 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -607,9 +607,6 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 	if (!indio_dev->buffer)
 		return -ENOMEM;
 
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
-
 	/* Ring buffer functions - here trigger setup related */
 	indio_dev->setup_ops = &ad5933_ring_setup_ops;
 
diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c
index ac22de5..8daa038 100644
--- a/drivers/staging/iio/imu/adis16400_ring.c
+++ b/drivers/staging/iio/imu/adis16400_ring.c
@@ -187,8 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 	indio_dev->buffer = ring;
-	/* Effectively select the ring buffer implementation */
-	ring->access = &ring_sw_access_funcs;
 	ring->scan_timestamp = true;
 	indio_dev->setup_ops = &adis16400_ring_setup_ops;
 
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 19f897f..e4824fe 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -100,71 +100,6 @@ const struct iio_chan_spec
 	return NULL;
 }
 
-/**
- * struct iio_detected_event_list - list element for events that have occurred
- * @list:		linked list header
- * @ev:			the event itself
- */
-struct iio_detected_event_list {
-	struct list_head		list;
-	struct iio_event_data		ev;
-};
-
-/**
- * struct iio_event_interface - chrdev interface for an event line
- * @dev:		device assocated with event interface
- * @wait:		wait queue to allow blocking reads of events
- * @event_list_lock:	mutex to protect the list of detected events
- * @det_events:		list of detected events
- * @max_events:		maximum number of events before new ones are dropped
- * @current_events:	number of events in detected list
- * @flags:		file operations related flags including busy flag.
- */
-struct iio_event_interface {
-	wait_queue_head_t			wait;
-	struct mutex				event_list_lock;
-	struct list_head			det_events;
-	int					max_events;
-	int					current_events;
-	struct list_head dev_attr_list;
-	unsigned long flags;
-	struct attribute_group			group;
-};
-
-int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
-{
-	struct iio_event_interface *ev_int = indio_dev->event_interface;
-	struct iio_detected_event_list *ev;
-	int ret = 0;
-
-	/* Does anyone care? */
-	mutex_lock(&ev_int->event_list_lock);
-	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
-		if (ev_int->current_events == ev_int->max_events) {
-			mutex_unlock(&ev_int->event_list_lock);
-			return 0;
-		}
-		ev = kmalloc(sizeof(*ev), GFP_KERNEL);
-		if (ev == NULL) {
-			ret = -ENOMEM;
-			mutex_unlock(&ev_int->event_list_lock);
-			goto error_ret;
-		}
-		ev->ev.id = ev_code;
-		ev->ev.timestamp = timestamp;
-
-		list_add_tail(&ev->list, &ev_int->det_events);
-		ev_int->current_events++;
-		mutex_unlock(&ev_int->event_list_lock);
-		wake_up_interruptible(&ev_int->wait);
-	} else
-		mutex_unlock(&ev_int->event_list_lock);
-
-error_ret:
-	return ret;
-}
-EXPORT_SYMBOL(iio_push_event);
-
 /* This turns up an awful lot */
 ssize_t iio_read_const_attr(struct device *dev,
 			    struct device_attribute *attr,
@@ -174,110 +109,6 @@ ssize_t iio_read_const_attr(struct device *dev,
 }
 EXPORT_SYMBOL(iio_read_const_attr);
 
-static ssize_t iio_event_chrdev_read(struct file *filep,
-				     char __user *buf,
-				     size_t count,
-				     loff_t *f_ps)
-{
-	struct iio_event_interface *ev_int = filep->private_data;
-	struct iio_detected_event_list *el;
-	size_t len = sizeof(el->ev);
-	int ret;
-
-	if (count < len)
-		return -EINVAL;
-
-	mutex_lock(&ev_int->event_list_lock);
-	if (list_empty(&ev_int->det_events)) {
-		if (filep->f_flags & O_NONBLOCK) {
-			ret = -EAGAIN;
-			goto error_mutex_unlock;
-		}
-		mutex_unlock(&ev_int->event_list_lock);
-		/* Blocking on device; waiting for something to be there */
-		ret = wait_event_interruptible(ev_int->wait,
-					       !list_empty(&ev_int
-							   ->det_events));
-		if (ret)
-			goto error_ret;
-		/* Single access device so no one else can get the data */
-		mutex_lock(&ev_int->event_list_lock);
-	}
-
-	el = list_first_entry(&ev_int->det_events,
-			      struct iio_detected_event_list,
-			      list);
-	if (copy_to_user(buf, &(el->ev), len)) {
-		ret = -EFAULT;
-		goto error_mutex_unlock;
-	}
-	list_del(&el->list);
-	ev_int->current_events--;
-	mutex_unlock(&ev_int->event_list_lock);
-	kfree(el);
-
-	return len;
-
-error_mutex_unlock:
-	mutex_unlock(&ev_int->event_list_lock);
-error_ret:
-
-	return ret;
-}
-
-static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
-{
-	struct iio_event_interface *ev_int = filep->private_data;
-	struct iio_detected_event_list *el, *t;
-
-	mutex_lock(&ev_int->event_list_lock);
-	clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
-	/*
-	 * In order to maintain a clean state for reopening,
-	 * clear out any awaiting events. The mask will prevent
-	 * any new __iio_push_event calls running.
-	 */
-	list_for_each_entry_safe(el, t, &ev_int->det_events, list) {
-		list_del(&el->list);
-		kfree(el);
-	}
-	ev_int->current_events = 0;
-	mutex_unlock(&ev_int->event_list_lock);
-
-	return 0;
-}
-
-static const struct file_operations iio_event_chrdev_fileops = {
-	.read =  iio_event_chrdev_read,
-	.release = iio_event_chrdev_release,
-	.owner = THIS_MODULE,
-	.llseek = noop_llseek,
-};
-
-static int iio_event_getfd(struct iio_dev *indio_dev)
-{
-	struct iio_event_interface *ev_int = indio_dev->event_interface;
-	int fd;
-
-	if (ev_int == NULL)
-		return -ENODEV;
-
-	mutex_lock(&ev_int->event_list_lock);
-	if (test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
-		mutex_unlock(&ev_int->event_list_lock);
-		return -EBUSY;
-	}
-	mutex_unlock(&ev_int->event_list_lock);
-	fd = anon_inode_getfd("iio:event",
-				&iio_event_chrdev_fileops, ev_int, O_RDONLY);
-	if (fd < 0) {
-		mutex_lock(&ev_int->event_list_lock);
-		clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
-		mutex_unlock(&ev_int->event_list_lock);
-	}
-	return fd;
-}
-
 static int __init iio_init(void)
 {
 	int ret;
@@ -726,295 +557,6 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
 	kfree(indio_dev->chan_attr_group.attrs);
 }
 
-static const char * const iio_ev_type_text[] = {
-	[IIO_EV_TYPE_THRESH] = "thresh",
-	[IIO_EV_TYPE_MAG] = "mag",
-	[IIO_EV_TYPE_ROC] = "roc",
-	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
-	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
-};
-
-static const char * const iio_ev_dir_text[] = {
-	[IIO_EV_DIR_EITHER] = "either",
-	[IIO_EV_DIR_RISING] = "rising",
-	[IIO_EV_DIR_FALLING] = "falling"
-};
-
-static ssize_t iio_ev_state_store(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	bool val;
-
-	ret = strtobool(buf, &val);
-	if (ret < 0)
-		return ret;
-
-	ret = indio_dev->info->write_event_config(indio_dev,
-						  this_attr->address,
-						  val);
-	return (ret < 0) ? ret : len;
-}
-
-static ssize_t iio_ev_state_show(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int val = indio_dev->info->read_event_config(indio_dev,
-						     this_attr->address);
-
-	if (val < 0)
-		return val;
-	else
-		return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t iio_ev_value_show(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int val, ret;
-
-	ret = indio_dev->info->read_event_value(indio_dev,
-						this_attr->address, &val);
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t iio_ev_value_store(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	unsigned long val;
-	int ret;
-
-	if (!indio_dev->info->write_event_value)
-		return -EINVAL;
-
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
-						 val);
-	if (ret < 0)
-		return ret;
-
-	return len;
-}
-
-static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
-				      struct iio_chan_spec const *chan)
-{
-	int ret = 0, i, attrcount = 0;
-	u64 mask = 0;
-	char *postfix;
-	if (!chan->event_mask)
-		return 0;
-
-	for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
-		postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
-				    iio_ev_type_text[i/IIO_EV_DIR_MAX],
-				    iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
-		if (postfix == NULL) {
-			ret = -ENOMEM;
-			goto error_ret;
-		}
-		if (chan->modified)
-			mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
-						  i/IIO_EV_DIR_MAX,
-						  i%IIO_EV_DIR_MAX);
-		else if (chan->differential)
-			mask = IIO_EVENT_CODE(chan->type,
-					      0, 0,
-					      i%IIO_EV_DIR_MAX,
-					      i/IIO_EV_DIR_MAX,
-					      0,
-					      chan->channel,
-					      chan->channel2);
-		else
-			mask = IIO_UNMOD_EVENT_CODE(chan->type,
-						    chan->channel,
-						    i/IIO_EV_DIR_MAX,
-						    i%IIO_EV_DIR_MAX);
-
-		ret = __iio_add_chan_devattr(postfix,
-					     chan,
-					     &iio_ev_state_show,
-					     iio_ev_state_store,
-					     mask,
-					     0,
-					     &indio_dev->dev,
-					     &indio_dev->event_interface->
-					     dev_attr_list);
-		kfree(postfix);
-		if (ret)
-			goto error_ret;
-		attrcount++;
-		postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
-				    iio_ev_type_text[i/IIO_EV_DIR_MAX],
-				    iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
-		if (postfix == NULL) {
-			ret = -ENOMEM;
-			goto error_ret;
-		}
-		ret = __iio_add_chan_devattr(postfix, chan,
-					     iio_ev_value_show,
-					     iio_ev_value_store,
-					     mask,
-					     0,
-					     &indio_dev->dev,
-					     &indio_dev->event_interface->
-					     dev_attr_list);
-		kfree(postfix);
-		if (ret)
-			goto error_ret;
-		attrcount++;
-	}
-	ret = attrcount;
-error_ret:
-	return ret;
-}
-
-static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev)
-{
-	struct iio_dev_attr *p, *n;
-	list_for_each_entry_safe(p, n,
-				 &indio_dev->event_interface->
-				 dev_attr_list, l) {
-		kfree(p->dev_attr.attr.name);
-		kfree(p);
-	}
-}
-
-static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
-{
-	int j, ret, attrcount = 0;
-
-	INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list);
-	/* Dynically created from the channels array */
-	for (j = 0; j < indio_dev->num_channels; j++) {
-		ret = iio_device_add_event_sysfs(indio_dev,
-						 &indio_dev->channels[j]);
-		if (ret < 0)
-			goto error_clear_attrs;
-		attrcount += ret;
-	}
-	return attrcount;
-
-error_clear_attrs:
-	__iio_remove_event_config_attrs(indio_dev);
-
-	return ret;
-}
-
-static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)
-{
-	int j;
-
-	for (j = 0; j < indio_dev->num_channels; j++)
-		if (indio_dev->channels[j].event_mask != 0)
-			return true;
-	return false;
-}
-
-static void iio_setup_ev_int(struct iio_event_interface *ev_int)
-{
-	mutex_init(&ev_int->event_list_lock);
-	/* discussion point - make this variable? */
-	ev_int->max_events = 10;
-	ev_int->current_events = 0;
-	INIT_LIST_HEAD(&ev_int->det_events);
-	init_waitqueue_head(&ev_int->wait);
-}
-
-static const char *iio_event_group_name = "events";
-static int iio_device_register_eventset(struct iio_dev *indio_dev)
-{
-	struct iio_dev_attr *p;
-	int ret = 0, attrcount_orig = 0, attrcount, attrn;
-	struct attribute **attr;
-
-	if (!(indio_dev->info->event_attrs ||
-	      iio_check_for_dynamic_events(indio_dev)))
-		return 0;
-
-	indio_dev->event_interface =
-		kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL);
-	if (indio_dev->event_interface == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-
-	iio_setup_ev_int(indio_dev->event_interface);
-	if (indio_dev->info->event_attrs != NULL) {
-		attr = indio_dev->info->event_attrs->attrs;
-		while (*attr++ != NULL)
-			attrcount_orig++;
-	}
-	attrcount = attrcount_orig;
-	if (indio_dev->channels) {
-		ret = __iio_add_event_config_attrs(indio_dev);
-		if (ret < 0)
-			goto error_free_setup_event_lines;
-		attrcount += ret;
-	}
-
-	indio_dev->event_interface->group.name = iio_event_group_name;
-	indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1,
-							  sizeof(indio_dev->event_interface->group.attrs[0]),
-							  GFP_KERNEL);
-	if (indio_dev->event_interface->group.attrs == NULL) {
-		ret = -ENOMEM;
-		goto error_free_setup_event_lines;
-	}
-	if (indio_dev->info->event_attrs)
-		memcpy(indio_dev->event_interface->group.attrs,
-		       indio_dev->info->event_attrs->attrs,
-		       sizeof(indio_dev->event_interface->group.attrs[0])
-		       *attrcount_orig);
-	attrn = attrcount_orig;
-	/* Add all elements from the list. */
-	list_for_each_entry(p,
-			    &indio_dev->event_interface->dev_attr_list,
-			    l)
-		indio_dev->event_interface->group.attrs[attrn++] =
-			&p->dev_attr.attr;
-	indio_dev->groups[indio_dev->groupcounter++] =
-		&indio_dev->event_interface->group;
-
-	return 0;
-
-error_free_setup_event_lines:
-	__iio_remove_event_config_attrs(indio_dev);
-	kfree(indio_dev->event_interface);
-error_ret:
-
-	return ret;
-}
-
-static void iio_device_unregister_eventset(struct iio_dev *indio_dev)
-{
-	if (indio_dev->event_interface == NULL)
-		return;
-	__iio_remove_event_config_attrs(indio_dev);
-	kfree(indio_dev->event_interface->group.attrs);
-	kfree(indio_dev->event_interface);
-}
-
 static void iio_dev_release(struct device *device)
 {
 	struct iio_dev *indio_dev = container_of(device, struct iio_dev, dev);
diff --git a/drivers/staging/iio/industrialio-event.c b/drivers/staging/iio/industrialio-event.c
new file mode 100644
index 0000000..5fdf739
--- /dev/null
+++ b/drivers/staging/iio/industrialio-event.c
@@ -0,0 +1,453 @@
+/* Industrial I/O event handling
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Based on elements of hwmon and input subsystems.
+ */
+
+#include <linux/anon_inodes.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/kfifo.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include "iio.h"
+#include "iio_core.h"
+#include "sysfs.h"
+#include "events.h"
+
+/**
+ * struct iio_event_interface - chrdev interface for an event line
+ * @wait:		wait queue to allow blocking reads of events
+ * @det_events:		list of detected events
+ * @dev_attr_list:	list of event interface sysfs attribute
+ * @flags:		file operations related flags including busy flag.
+ * @group:		event interface sysfs attribute group
+ */
+struct iio_event_interface {
+	wait_queue_head_t	wait;
+	DECLARE_KFIFO(det_events, struct iio_event_data, 16);
+
+	struct list_head	dev_attr_list;
+	unsigned long		flags;
+	struct attribute_group	group;
+};
+
+int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp)
+{
+	struct iio_event_interface *ev_int = indio_dev->event_interface;
+	struct iio_event_data ev;
+	int copied;
+
+	/* Does anyone care? */
+	spin_lock(&ev_int->wait.lock);
+	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
+
+		ev.id = ev_code;
+		ev.timestamp = timestamp;
+
+		copied = kfifo_put(&ev_int->det_events, &ev);
+		if (copied != 0)
+			wake_up_locked_poll(&ev_int->wait, POLLIN);
+	}
+	spin_unlock(&ev_int->wait.lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(iio_push_event);
+
+/**
+ * iio_event_poll() - poll the event queue to find out if it has data
+ */
+static unsigned int iio_event_poll(struct file *filep,
+			     struct poll_table_struct *wait)
+{
+	struct iio_event_interface *ev_int = filep->private_data;
+	unsigned int events = 0;
+
+	poll_wait(filep, &ev_int->wait, wait);
+
+	spin_lock(&ev_int->wait.lock);
+	if (!kfifo_is_empty(&ev_int->det_events))
+		events = POLLIN | POLLRDNORM;
+	spin_unlock(&ev_int->wait.lock);
+
+	return events;
+}
+
+static ssize_t iio_event_chrdev_read(struct file *filep,
+				     char __user *buf,
+				     size_t count,
+				     loff_t *f_ps)
+{
+	struct iio_event_interface *ev_int = filep->private_data;
+	unsigned int copied;
+	int ret;
+
+	if (count < sizeof(struct iio_event_data))
+		return -EINVAL;
+
+	spin_lock(&ev_int->wait.lock);
+	if (kfifo_is_empty(&ev_int->det_events)) {
+		if (filep->f_flags & O_NONBLOCK) {
+			ret = -EAGAIN;
+			goto error_unlock;
+		}
+		/* Blocking on device; waiting for something to be there */
+		ret = wait_event_interruptible_locked(ev_int->wait,
+					!kfifo_is_empty(&ev_int->det_events));
+		if (ret)
+			goto error_unlock;
+		/* Single access device so no one else can get the data */
+	}
+
+	ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied);
+
+error_unlock:
+	spin_unlock(&ev_int->wait.lock);
+
+	return ret ? ret : copied;
+}
+
+static int iio_event_chrdev_release(struct inode *inode, struct file *filep)
+{
+	struct iio_event_interface *ev_int = filep->private_data;
+
+	spin_lock(&ev_int->wait.lock);
+	__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
+	/*
+	 * In order to maintain a clean state for reopening,
+	 * clear out any awaiting events. The mask will prevent
+	 * any new __iio_push_event calls running.
+	 */
+	kfifo_reset_out(&ev_int->det_events);
+	spin_unlock(&ev_int->wait.lock);
+
+	return 0;
+}
+
+static const struct file_operations iio_event_chrdev_fileops = {
+	.read =  iio_event_chrdev_read,
+	.poll =  iio_event_poll,
+	.release = iio_event_chrdev_release,
+	.owner = THIS_MODULE,
+	.llseek = noop_llseek,
+};
+
+int iio_event_getfd(struct iio_dev *indio_dev)
+{
+	struct iio_event_interface *ev_int = indio_dev->event_interface;
+	int fd;
+
+	if (ev_int == NULL)
+		return -ENODEV;
+
+	spin_lock(&ev_int->wait.lock);
+	if (__test_and_set_bit(IIO_BUSY_BIT_POS, &ev_int->flags)) {
+		spin_unlock(&ev_int->wait.lock);
+		return -EBUSY;
+	}
+	spin_unlock(&ev_int->wait.lock);
+	fd = anon_inode_getfd("iio:event",
+				&iio_event_chrdev_fileops, ev_int, O_RDONLY);
+	if (fd < 0) {
+		spin_lock(&ev_int->wait.lock);
+		__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
+		spin_unlock(&ev_int->wait.lock);
+	}
+	return fd;
+}
+
+static const char * const iio_ev_type_text[] = {
+	[IIO_EV_TYPE_THRESH] = "thresh",
+	[IIO_EV_TYPE_MAG] = "mag",
+	[IIO_EV_TYPE_ROC] = "roc",
+	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
+	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
+};
+
+static const char * const iio_ev_dir_text[] = {
+	[IIO_EV_DIR_EITHER] = "either",
+	[IIO_EV_DIR_RISING] = "rising",
+	[IIO_EV_DIR_FALLING] = "falling"
+};
+
+static ssize_t iio_ev_state_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	bool val;
+
+	ret = strtobool(buf, &val);
+	if (ret < 0)
+		return ret;
+
+	ret = indio_dev->info->write_event_config(indio_dev,
+						  this_attr->address,
+						  val);
+	return (ret < 0) ? ret : len;
+}
+
+static ssize_t iio_ev_state_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val = indio_dev->info->read_event_config(indio_dev,
+						     this_attr->address);
+
+	if (val < 0)
+		return val;
+	else
+		return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t iio_ev_value_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val, ret;
+
+	ret = indio_dev->info->read_event_value(indio_dev,
+						this_attr->address, &val);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t iio_ev_value_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long val;
+	int ret;
+
+	if (!indio_dev->info->write_event_value)
+		return -EINVAL;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
+						 val);
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+
+static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
+				      struct iio_chan_spec const *chan)
+{
+	int ret = 0, i, attrcount = 0;
+	u64 mask = 0;
+	char *postfix;
+	if (!chan->event_mask)
+		return 0;
+
+	for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
+		postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
+				    iio_ev_type_text[i/IIO_EV_DIR_MAX],
+				    iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
+		if (postfix == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+		if (chan->modified)
+			mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
+						  i/IIO_EV_DIR_MAX,
+						  i%IIO_EV_DIR_MAX);
+		else if (chan->differential)
+			mask = IIO_EVENT_CODE(chan->type,
+					      0, 0,
+					      i%IIO_EV_DIR_MAX,
+					      i/IIO_EV_DIR_MAX,
+					      0,
+					      chan->channel,
+					      chan->channel2);
+		else
+			mask = IIO_UNMOD_EVENT_CODE(chan->type,
+						    chan->channel,
+						    i/IIO_EV_DIR_MAX,
+						    i%IIO_EV_DIR_MAX);
+
+		ret = __iio_add_chan_devattr(postfix,
+					     chan,
+					     &iio_ev_state_show,
+					     iio_ev_state_store,
+					     mask,
+					     0,
+					     &indio_dev->dev,
+					     &indio_dev->event_interface->
+					     dev_attr_list);
+		kfree(postfix);
+		if (ret)
+			goto error_ret;
+		attrcount++;
+		postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
+				    iio_ev_type_text[i/IIO_EV_DIR_MAX],
+				    iio_ev_dir_text[i%IIO_EV_DIR_MAX]);
+		if (postfix == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+		ret = __iio_add_chan_devattr(postfix, chan,
+					     iio_ev_value_show,
+					     iio_ev_value_store,
+					     mask,
+					     0,
+					     &indio_dev->dev,
+					     &indio_dev->event_interface->
+					     dev_attr_list);
+		kfree(postfix);
+		if (ret)
+			goto error_ret;
+		attrcount++;
+	}
+	ret = attrcount;
+error_ret:
+	return ret;
+}
+
+static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev)
+{
+	struct iio_dev_attr *p, *n;
+	list_for_each_entry_safe(p, n,
+				 &indio_dev->event_interface->
+				 dev_attr_list, l) {
+		kfree(p->dev_attr.attr.name);
+		kfree(p);
+	}
+}
+
+static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
+{
+	int j, ret, attrcount = 0;
+
+	INIT_LIST_HEAD(&indio_dev->event_interface->dev_attr_list);
+	/* Dynically created from the channels array */
+	for (j = 0; j < indio_dev->num_channels; j++) {
+		ret = iio_device_add_event_sysfs(indio_dev,
+						 &indio_dev->channels[j]);
+		if (ret < 0)
+			goto error_clear_attrs;
+		attrcount += ret;
+	}
+	return attrcount;
+
+error_clear_attrs:
+	__iio_remove_event_config_attrs(indio_dev);
+
+	return ret;
+}
+
+static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)
+{
+	int j;
+
+	for (j = 0; j < indio_dev->num_channels; j++)
+		if (indio_dev->channels[j].event_mask != 0)
+			return true;
+	return false;
+}
+
+static void iio_setup_ev_int(struct iio_event_interface *ev_int)
+{
+	INIT_KFIFO(ev_int->det_events);
+	init_waitqueue_head(&ev_int->wait);
+}
+
+static const char *iio_event_group_name = "events";
+int iio_device_register_eventset(struct iio_dev *indio_dev)
+{
+	struct iio_dev_attr *p;
+	int ret = 0, attrcount_orig = 0, attrcount, attrn;
+	struct attribute **attr;
+
+	if (!(indio_dev->info->event_attrs ||
+	      iio_check_for_dynamic_events(indio_dev)))
+		return 0;
+
+	indio_dev->event_interface =
+		kzalloc(sizeof(struct iio_event_interface), GFP_KERNEL);
+	if (indio_dev->event_interface == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	iio_setup_ev_int(indio_dev->event_interface);
+	if (indio_dev->info->event_attrs != NULL) {
+		attr = indio_dev->info->event_attrs->attrs;
+		while (*attr++ != NULL)
+			attrcount_orig++;
+	}
+	attrcount = attrcount_orig;
+	if (indio_dev->channels) {
+		ret = __iio_add_event_config_attrs(indio_dev);
+		if (ret < 0)
+			goto error_free_setup_event_lines;
+		attrcount += ret;
+	}
+
+	indio_dev->event_interface->group.name = iio_event_group_name;
+	indio_dev->event_interface->group.attrs = kcalloc(attrcount + 1,
+							  sizeof(indio_dev->event_interface->group.attrs[0]),
+							  GFP_KERNEL);
+	if (indio_dev->event_interface->group.attrs == NULL) {
+		ret = -ENOMEM;
+		goto error_free_setup_event_lines;
+	}
+	if (indio_dev->info->event_attrs)
+		memcpy(indio_dev->event_interface->group.attrs,
+		       indio_dev->info->event_attrs->attrs,
+		       sizeof(indio_dev->event_interface->group.attrs[0])
+		       *attrcount_orig);
+	attrn = attrcount_orig;
+	/* Add all elements from the list. */
+	list_for_each_entry(p,
+			    &indio_dev->event_interface->dev_attr_list,
+			    l)
+		indio_dev->event_interface->group.attrs[attrn++] =
+			&p->dev_attr.attr;
+	indio_dev->groups[indio_dev->groupcounter++] =
+		&indio_dev->event_interface->group;
+
+	return 0;
+
+error_free_setup_event_lines:
+	__iio_remove_event_config_attrs(indio_dev);
+	kfree(indio_dev->event_interface);
+error_ret:
+
+	return ret;
+}
+
+void iio_device_unregister_eventset(struct iio_dev *indio_dev)
+{
+	if (indio_dev->event_interface == NULL)
+		return;
+	__iio_remove_event_config_attrs(indio_dev);
+	kfree(indio_dev->event_interface->group.attrs);
+	kfree(indio_dev->event_interface);
+}
diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c
index e1e9c06..9f3bd59 100644
--- a/drivers/staging/iio/kfifo_buf.c
+++ b/drivers/staging/iio/kfifo_buf.c
@@ -59,21 +59,6 @@ static struct attribute_group iio_kfifo_attribute_group = {
 	.name = "buffer",
 };
 
-struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
-{
-	struct iio_kfifo *kf;
-
-	kf = kzalloc(sizeof *kf, GFP_KERNEL);
-	if (!kf)
-		return NULL;
-	kf->update_needed = true;
-	iio_buffer_init(&kf->buffer);
-	kf->buffer.attrs = &iio_kfifo_attribute_group;
-
-	return &kf->buffer;
-}
-EXPORT_SYMBOL(iio_kfifo_allocate);
-
 static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r)
 {
 	return r->bytes_per_datum;
@@ -104,12 +89,6 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length)
 	return 0;
 }
 
-void iio_kfifo_free(struct iio_buffer *r)
-{
-	kfree(iio_to_kfifo(r));
-}
-EXPORT_SYMBOL(iio_kfifo_free);
-
 static int iio_store_to_kfifo(struct iio_buffer *r,
 			      u8 *data,
 			      s64 timestamp)
@@ -137,7 +116,7 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r,
 	return copied;
 }
 
-const struct iio_buffer_access_funcs kfifo_access_funcs = {
+static const struct iio_buffer_access_funcs kfifo_access_funcs = {
 	.store_to = &iio_store_to_kfifo,
 	.read_first_n = &iio_read_first_n_kfifo,
 	.request_update = &iio_request_update_kfifo,
@@ -146,6 +125,27 @@ const struct iio_buffer_access_funcs kfifo_access_funcs = {
 	.get_length = &iio_get_length_kfifo,
 	.set_length = &iio_set_length_kfifo,
 };
-EXPORT_SYMBOL(kfifo_access_funcs);
+
+struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
+{
+	struct iio_kfifo *kf;
+
+	kf = kzalloc(sizeof *kf, GFP_KERNEL);
+	if (!kf)
+		return NULL;
+	kf->update_needed = true;
+	iio_buffer_init(&kf->buffer);
+	kf->buffer.attrs = &iio_kfifo_attribute_group;
+	kf->buffer.access = &kfifo_access_funcs;
+
+	return &kf->buffer;
+}
+EXPORT_SYMBOL(iio_kfifo_allocate);
+
+void iio_kfifo_free(struct iio_buffer *r)
+{
+	kfree(iio_to_kfifo(r));
+}
+EXPORT_SYMBOL(iio_kfifo_free);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/kfifo_buf.h b/drivers/staging/iio/kfifo_buf.h
index cc2bd9a..9f7da01 100644
--- a/drivers/staging/iio/kfifo_buf.h
+++ b/drivers/staging/iio/kfifo_buf.h
@@ -3,8 +3,6 @@
 #include "iio.h"
 #include "buffer.h"
 
-extern const struct iio_buffer_access_funcs kfifo_access_funcs;
-
 struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev);
 void iio_kfifo_free(struct iio_buffer *r);
 
diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c
index 849d6a5..38ec52b 100644
--- a/drivers/staging/iio/light/isl29018.c
+++ b/drivers/staging/iio/light/isl29018.c
@@ -592,11 +592,18 @@ static const struct i2c_device_id isl29018_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, isl29018_id);
 
+static const struct of_device_id isl29018_of_match[] = {
+	{ .compatible = "invn,isl29018", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, isl29018_of_match);
+
 static struct i2c_driver isl29018_driver = {
 	.class	= I2C_CLASS_HWMON,
 	.driver	 = {
 			.name = "isl29018",
 			.owner = THIS_MODULE,
+			.of_match_table = isl29018_of_match,
 		    },
 	.probe	 = isl29018_probe,
 	.remove	 = __devexit_p(isl29018_remove),
diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c
index 3158f12..d5ddac3 100644
--- a/drivers/staging/iio/magnetometer/ak8975.c
+++ b/drivers/staging/iio/magnetometer/ak8975.c
@@ -564,9 +564,17 @@ static const struct i2c_device_id ak8975_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, ak8975_id);
 
+static const struct of_device_id ak8975_of_match[] = {
+	{ .compatible = "asahi-kasei,ak8975", },
+	{ .compatible = "ak8975", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ak8975_of_match);
+
 static struct i2c_driver ak8975_driver = {
 	.driver = {
 		.name	= "ak8975",
+		.of_match_table = ak8975_of_match,
 	},
 	.probe		= ak8975_probe,
 	.remove		= __devexit_p(ak8975_remove),
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index f29f2b2..c5c522b 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -144,8 +144,6 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 		return ret;
 	}
 
-	/* Effectively select the ring buffer implementation */
-	indio_dev->buffer->access = &ring_sw_access_funcs;
 	indio_dev->setup_ops = &ade7758_ring_setup_ops;
 
 	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
index 3e24ec4..eeac0da 100644
--- a/drivers/staging/iio/ring_sw.c
+++ b/drivers/staging/iio/ring_sw.c
@@ -329,6 +329,16 @@ static struct attribute_group iio_ring_attribute_group = {
 	.name = "buffer",
 };
 
+static const struct iio_buffer_access_funcs ring_sw_access_funcs = {
+	.store_to = &iio_store_to_sw_rb,
+	.read_first_n = &iio_read_first_n_sw_rb,
+	.request_update = &iio_request_update_sw_rb,
+	.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
+	.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
+	.get_length = &iio_get_length_sw_rb,
+	.set_length = &iio_set_length_sw_rb,
+};
+
 struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
 {
 	struct iio_buffer *buf;
@@ -341,6 +351,7 @@ struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
 	buf = &ring->buf;
 	iio_buffer_init(buf);
 	buf->attrs = &iio_ring_attribute_group;
+	buf->access = &ring_sw_access_funcs;
 
 	return buf;
 }
@@ -352,16 +363,5 @@ void iio_sw_rb_free(struct iio_buffer *r)
 }
 EXPORT_SYMBOL(iio_sw_rb_free);
 
-const struct iio_buffer_access_funcs ring_sw_access_funcs = {
-	.store_to = &iio_store_to_sw_rb,
-	.read_first_n = &iio_read_first_n_sw_rb,
-	.request_update = &iio_request_update_sw_rb,
-	.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
-	.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
-	.get_length = &iio_get_length_sw_rb,
-	.set_length = &iio_set_length_sw_rb,
-};
-EXPORT_SYMBOL(ring_sw_access_funcs);
-
 MODULE_DESCRIPTION("Industrialio I/O software ring buffer");
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
index e6a6e2c..7556e21 100644
--- a/drivers/staging/iio/ring_sw.h
+++ b/drivers/staging/iio/ring_sw.h
@@ -25,11 +25,6 @@
 #define _IIO_RING_SW_H_
 #include "buffer.h"
 
-/**
- * ring_sw_access_funcs - access functions for a software ring buffer
- **/
-extern const struct iio_buffer_access_funcs ring_sw_access_funcs;
-
 struct iio_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
 void iio_sw_rb_free(struct iio_buffer *ring);
 #endif /* _IIO_RING_SW_H_ */
diff --git a/drivers/staging/keucr/TODO b/drivers/staging/keucr/TODO
index 1c48e40..d6da656 100644
--- a/drivers/staging/keucr/TODO
+++ b/drivers/staging/keucr/TODO
@@ -9,4 +9,4 @@ TODO:
 	- smcommon.h & smilsub.c: use kernel hweight8(), hweight16()
 
 Please send any patches for this driver to Al Cho <acho@novell.com> and
-Greg Kroah-Hartman <gregkh@suse.de>.
+Greg Kroah-Hartman <gregkh@linuxfoundation.org>.
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index 127f952..c85c5b6 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -107,7 +107,7 @@ void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
 	Wait until unlinking of all currently active capture URBs has been
 	finished.
 */
-static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
 {
 	int timeout = HZ;
 	unsigned int i;
@@ -134,7 +134,7 @@ static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
 void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
 {
 	line6_unlink_audio_in_urbs(line6pcm);
-	wait_clear_audio_in_urbs(line6pcm);
+	line6_wait_clear_audio_in_urbs(line6pcm);
 }
 
 /*
@@ -193,25 +193,6 @@ void line6_capture_check_period(struct snd_line6_pcm *line6pcm, int length)
 	}
 }
 
-int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm)
-{
-	/* We may be invoked multiple times in a row so allocate once only */
-	if (line6pcm->buffer_in)
-		return 0;
-
-	line6pcm->buffer_in =
-		kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
-			line6pcm->max_packet_size, GFP_KERNEL);
-
-	if (!line6pcm->buffer_in) {
-		dev_err(line6pcm->line6->ifcdev,
-			"cannot malloc capture buffer\n");
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
 void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm)
 {
 	kfree(line6pcm->buffer_in);
@@ -273,9 +254,9 @@ static void audio_in_callback(struct urb *urb)
 		line6pcm->prev_fsize = fsize;
 
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-		if (!(line6pcm->flags & MASK_PCM_IMPULSE))
+		if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
 #endif
-			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags)
+			if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags)
 			    && (fsize > 0))
 				line6_capture_copy(line6pcm, fbuf, fsize);
 	}
@@ -291,9 +272,9 @@ static void audio_in_callback(struct urb *urb)
 		submit_audio_in_urb(line6pcm);
 
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-		if (!(line6pcm->flags & MASK_PCM_IMPULSE))
+		if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE))
 #endif
-			if (test_bit(BIT_PCM_ALSA_CAPTURE, &line6pcm->flags))
+			if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags))
 				line6_capture_check_period(line6pcm, length);
 	}
 }
@@ -341,17 +322,17 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
 	}
 	/* -- [FD] end */
 
-	if ((line6pcm->flags & MASK_CAPTURE) == 0) {
-		ret = line6_alloc_capture_buffer(line6pcm);
+	ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
 
-		if (ret < 0)
-			return ret;
-	}
+	if (ret < 0)
+		return ret;
 
 	ret = snd_pcm_lib_malloc_pages(substream,
 				       params_buffer_bytes(hw_params));
-	if (ret < 0)
+	if (ret < 0) {
+		line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
 		return ret;
+	}
 
 	line6pcm->period_in = params_period_bytes(hw_params);
 	return 0;
@@ -361,12 +342,7 @@ static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
 static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-	if ((line6pcm->flags & MASK_CAPTURE) == 0) {
-		line6_unlink_wait_clear_audio_in_urbs(line6pcm);
-		line6_free_capture_buffer(line6pcm);
-	}
-
+	line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER);
 	return snd_pcm_lib_free_pages(substream);
 }
 
@@ -380,7 +356,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 #ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_RESUME:
 #endif
-		err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_CAPTURE);
+		err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
 
 		if (err < 0)
 			return err;
@@ -391,7 +367,7 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 #ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 #endif
-		err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_CAPTURE);
+		err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM);
 
 		if (err < 0)
 			return err;
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
index 366cbaa..4157bcb 100644
--- a/drivers/staging/line6/capture.h
+++ b/drivers/staging/line6/capture.h
@@ -19,7 +19,6 @@
 
 extern struct snd_pcm_ops snd_line6_capture_ops;
 
-extern int line6_alloc_capture_buffer(struct snd_line6_pcm *line6pcm);
 extern void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf,
 			       int fsize);
 extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
@@ -30,6 +29,7 @@ extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
 						  *line6pcm);
+extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
 extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
 
 #endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index 6a1959e..e8023af 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -1346,7 +1346,7 @@ static void __exit line6_exit(void)
 		if (line6pcm == NULL)
 			continue;
 
-		line6_pcm_stop(line6pcm, ~0);
+		line6_pcm_release(line6pcm, ~0);
 	}
 
 	usb_deregister(&line6_driver);
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index 37675e6..90d2d44 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -52,9 +52,9 @@ static ssize_t pcm_set_impulse_volume(struct device *dev,
 	line6pcm->impulse_volume = value;
 
 	if (value > 0)
-		line6_pcm_start(line6pcm, MASK_PCM_IMPULSE);
+		line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_IMPULSE);
 	else
-		line6_pcm_stop(line6pcm, MASK_PCM_IMPULSE);
+		line6_pcm_release(line6pcm, LINE6_BITS_PCM_IMPULSE);
 
 	return count;
 }
@@ -92,29 +92,43 @@ static bool test_flags(unsigned long flags0, unsigned long flags1,
 	return ((flags0 & mask) == 0) && ((flags1 & mask) != 0);
 }
 
-int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels)
+int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels)
 {
 	unsigned long flags_old =
 	    __sync_fetch_and_or(&line6pcm->flags, channels);
 	unsigned long flags_new = flags_old | channels;
+	unsigned long flags_final = flags_old;
 	int err = 0;
 	
 	line6pcm->prev_fbuf = NULL;
 
-	if (test_flags(flags_old, flags_new, MASK_CAPTURE)) {
+	if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) {
+		/* We may be invoked multiple times in a row so allocate once only */
+		if (!line6pcm->buffer_in) {
+			line6pcm->buffer_in =
+				kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+					line6pcm->max_packet_size, GFP_KERNEL);
+
+			if (!line6pcm->buffer_in) {
+				dev_err(line6pcm->line6->ifcdev,
+					"cannot malloc capture buffer\n");
+				err = -ENOMEM;
+				goto pcm_acquire_error;
+			}
+
+			flags_final |= channels & LINE6_BITS_CAPTURE_BUFFER;
+		}
+	}
+
+	if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_STREAM)) {
 		/*
 		   Waiting for completion of active URBs in the stop handler is
 		   a bug, we therefore report an error if capturing is restarted
 		   too soon.
 		 */
-		if (line6pcm->active_urb_in | line6pcm->unlink_urb_in)
+		if (line6pcm->active_urb_in | line6pcm->unlink_urb_in) {
+			dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
 			return -EBUSY;
-
-		if (!(flags_new & MASK_PCM_ALSA_CAPTURE)) {
-			err = line6_alloc_capture_buffer(line6pcm);
-
-			if (err < 0)
-				goto pcm_start_error;
 		}
 
 		line6pcm->count_in = 0;
@@ -122,55 +136,78 @@ int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels)
 		err = line6_submit_audio_in_all_urbs(line6pcm);
 
 		if (err < 0)
-			goto pcm_start_error;
+			goto pcm_acquire_error;
+
+		flags_final |= channels & LINE6_BITS_CAPTURE_STREAM;
 	}
 
-	if (test_flags(flags_old, flags_new, MASK_PLAYBACK)) {
-		/*
-		   See comment above regarding PCM restart.
-		 */
-		if (line6pcm->active_urb_out | line6pcm->unlink_urb_out)
-			return -EBUSY;
+	if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) {
+		/* We may be invoked multiple times in a row so allocate once only */
+		if (!line6pcm->buffer_out) {
+			line6pcm->buffer_out =
+				kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
+					line6pcm->max_packet_size, GFP_KERNEL);
+
+			if (!line6pcm->buffer_out) {
+				dev_err(line6pcm->line6->ifcdev,
+					"cannot malloc playback buffer\n");
+				err = -ENOMEM;
+				goto pcm_acquire_error;
+			}
 
-		if (!(flags_new & MASK_PCM_ALSA_PLAYBACK)) {
-			err = line6_alloc_playback_buffer(line6pcm);
+			flags_final |= channels & LINE6_BITS_PLAYBACK_BUFFER;
+		}
+	}
 
-			if (err < 0)
-				goto pcm_start_error;
+	if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_STREAM)) {
+		/*
+		  See comment above regarding PCM restart.
+		*/
+		if (line6pcm->active_urb_out | line6pcm->unlink_urb_out) {
+			dev_err(line6pcm->line6->ifcdev, "Device not yet ready\n");
+			return -EBUSY;
 		}
 
 		line6pcm->count_out = 0;
 		err = line6_submit_audio_out_all_urbs(line6pcm);
 
 		if (err < 0)
-			goto pcm_start_error;
+			goto pcm_acquire_error;
+
+		flags_final |= channels & LINE6_BITS_PLAYBACK_STREAM;
 	}
 
 	return 0;
 
-pcm_start_error:
-	__sync_fetch_and_and(&line6pcm->flags, ~channels);
+pcm_acquire_error:
+	/*
+	   If not all requested resources/streams could be obtained, release
+	   those which were successfully obtained (if any).
+	*/
+	line6_pcm_release(line6pcm, flags_final & channels);
 	return err;
 }
 
-int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels)
+int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
 {
 	unsigned long flags_old =
 	    __sync_fetch_and_and(&line6pcm->flags, ~channels);
 	unsigned long flags_new = flags_old & ~channels;
 
-	if (test_flags(flags_new, flags_old, MASK_CAPTURE)) {
+	if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
 		line6_unlink_audio_in_urbs(line6pcm);
 
-		if (!(flags_old & MASK_PCM_ALSA_CAPTURE))
-			line6_free_capture_buffer(line6pcm);
+	if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) {
+		line6_wait_clear_audio_in_urbs(line6pcm);
+		line6_free_capture_buffer(line6pcm);
 	}
 
-	if (test_flags(flags_new, flags_old, MASK_PLAYBACK)) {
+	if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))
 		line6_unlink_audio_out_urbs(line6pcm);
 
-		if (!(flags_old & MASK_PCM_ALSA_PLAYBACK))
-			line6_free_playback_buffer(line6pcm);
+	if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) {
+		line6_wait_clear_audio_out_urbs(line6pcm);
+		line6_free_playback_buffer(line6pcm);
 	}
 
 	return 0;
@@ -185,7 +222,7 @@ int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
 	unsigned long flags;
 
 	spin_lock_irqsave(&line6pcm->lock_trigger, flags);
-	clear_bit(BIT_PREPARED, &line6pcm->flags);
+	clear_bit(LINE6_INDEX_PREPARED, &line6pcm->flags);
 
 	snd_pcm_group_for_each_entry(s, substream) {
 		switch (s->stream) {
@@ -498,13 +535,13 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
 
 	switch (substream->stream) {
 	case SNDRV_PCM_STREAM_PLAYBACK:
-		if ((line6pcm->flags & MASK_PLAYBACK) == 0)
+		if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0)
 			line6_unlink_wait_clear_audio_out_urbs(line6pcm);
 
 		break;
 
 	case SNDRV_PCM_STREAM_CAPTURE:
-		if ((line6pcm->flags & MASK_CAPTURE) == 0)
+		if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0)
 			line6_unlink_wait_clear_audio_in_urbs(line6pcm);
 
 		break;
@@ -513,7 +550,7 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
 		MISSING_CASE;
 	}
 
-	if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
+	if (!test_and_set_bit(LINE6_INDEX_PREPARED, &line6pcm->flags)) {
 		line6pcm->count_out = 0;
 		line6pcm->pos_out = 0;
 		line6pcm->pos_out_done = 0;
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
index 55d8297..5210ec8 100644
--- a/drivers/staging/line6/pcm.h
+++ b/drivers/staging/line6/pcm.h
@@ -46,57 +46,131 @@
 		(line6pcm->pcm->streams[stream].substream)
 
 /*
-	PCM mode bits and masks.
-	"ALSA": operations triggered by applications via ALSA
-	"MONITOR": software monitoring
-	"IMPULSE": optional impulse response operation
+	PCM mode bits.
+
+	There are several features of the Line6 USB driver which require PCM
+	data to be exchanged with the device:
+	*) PCM playback and capture via ALSA
+	*) software monitoring (for devices without hardware monitoring)
+	*) optional impulse response measurement
+	However, from the device's point of view, there is just a single
+	capture and playback stream, which must be shared between these
+	subsystems. It is therefore necessary to maintain the state of the
+	subsystems with respect to PCM usage. We define several constants of
+	the form LINE6_BIT_PCM_<subsystem>_<direction>_<resource> with the
+	following meanings:
+	*) <subsystem> is one of
+	-) ALSA: PCM playback and capture via ALSA
+	-) MONITOR: software monitoring
+	-) IMPULSE: optional impulse response measurement
+	*) <direction> is one of
+	-) PLAYBACK: audio output (from host to device)
+	-) CAPTURE: audio input (from device to host)
+	*) <resource> is one of
+	-) BUFFER: buffer required by PCM data stream
+	-) STREAM: actual PCM data stream
+
+	The subsystems call line6_pcm_acquire() to acquire the (shared)
+	resources needed for a particular operation (e.g., allocate the buffer
+	for ALSA playback or start the capture stream for software monitoring).
+	When a resource is no longer needed, it is released by calling
+	line6_pcm_release(). Buffer allocation and stream startup are handled
+	separately to allow the ALSA kernel driver to perform them at
+	appropriate places (since the callback which starts a PCM stream is not
+	allowed to sleep).
 */
 enum {
-	/* individual bits: */
-	BIT_PCM_ALSA_PLAYBACK,
-	BIT_PCM_ALSA_CAPTURE,
-	BIT_PCM_MONITOR_PLAYBACK,
-	BIT_PCM_MONITOR_CAPTURE,
+	/* individual bit indices: */
+	LINE6_INDEX_PCM_ALSA_PLAYBACK_BUFFER,
+	LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM,
+	LINE6_INDEX_PCM_ALSA_CAPTURE_BUFFER,
+	LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM,
+	LINE6_INDEX_PCM_MONITOR_PLAYBACK_BUFFER,
+	LINE6_INDEX_PCM_MONITOR_PLAYBACK_STREAM,
+	LINE6_INDEX_PCM_MONITOR_CAPTURE_BUFFER,
+	LINE6_INDEX_PCM_MONITOR_CAPTURE_STREAM,
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-	BIT_PCM_IMPULSE_PLAYBACK,
-	BIT_PCM_IMPULSE_CAPTURE,
+	LINE6_INDEX_PCM_IMPULSE_PLAYBACK_BUFFER,
+	LINE6_INDEX_PCM_IMPULSE_PLAYBACK_STREAM,
+	LINE6_INDEX_PCM_IMPULSE_CAPTURE_BUFFER,
+	LINE6_INDEX_PCM_IMPULSE_CAPTURE_STREAM,
 #endif
-	BIT_PAUSE_PLAYBACK,
-	BIT_PREPARED,
-
-	/* individual masks: */
-/* *INDENT-OFF* */
-	MASK_PCM_ALSA_PLAYBACK    = 1 << BIT_PCM_ALSA_PLAYBACK,
-	MASK_PCM_ALSA_CAPTURE     = 1 << BIT_PCM_ALSA_CAPTURE,
-	MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK,
-	MASK_PCM_MONITOR_CAPTURE  = 1 << BIT_PCM_MONITOR_CAPTURE,
+	LINE6_INDEX_PAUSE_PLAYBACK,
+	LINE6_INDEX_PREPARED,
+
+	/* individual bit masks: */
+	LINE6_BIT(PCM_ALSA_PLAYBACK_BUFFER),
+	LINE6_BIT(PCM_ALSA_PLAYBACK_STREAM),
+	LINE6_BIT(PCM_ALSA_CAPTURE_BUFFER),
+	LINE6_BIT(PCM_ALSA_CAPTURE_STREAM),
+	LINE6_BIT(PCM_MONITOR_PLAYBACK_BUFFER),
+	LINE6_BIT(PCM_MONITOR_PLAYBACK_STREAM),
+	LINE6_BIT(PCM_MONITOR_CAPTURE_BUFFER),
+	LINE6_BIT(PCM_MONITOR_CAPTURE_STREAM),
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-	MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK,
-	MASK_PCM_IMPULSE_CAPTURE  = 1 << BIT_PCM_IMPULSE_CAPTURE,
+	LINE6_BIT(PCM_IMPULSE_PLAYBACK_BUFFER),
+	LINE6_BIT(PCM_IMPULSE_PLAYBACK_STREAM),
+	LINE6_BIT(PCM_IMPULSE_CAPTURE_BUFFER),
+	LINE6_BIT(PCM_IMPULSE_CAPTURE_STREAM),
 #endif
-	MASK_PAUSE_PLAYBACK       = 1 << BIT_PAUSE_PLAYBACK,
-	MASK_PREPARED             = 1 << BIT_PREPARED,
-/* *INDENT-ON* */
+	LINE6_BIT(PAUSE_PLAYBACK),
+	LINE6_BIT(PREPARED),
 
-	/* combined masks (by operation): */
-	MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE,
-	MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE,
+	/* combined bit masks (by operation): */
+	LINE6_BITS_PCM_ALSA_BUFFER =
+	    LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
+	    LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER,
+
+	LINE6_BITS_PCM_ALSA_STREAM =
+	    LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
+	    LINE6_BIT_PCM_ALSA_CAPTURE_STREAM,
+
+	LINE6_BITS_PCM_MONITOR =
+	    LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER |
+	    LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM |
+	    LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER |
+	    LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
+
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+	LINE6_BITS_PCM_IMPULSE =
+	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
+	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
+	    LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
+	    LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM,
+#endif
+
+	/* combined bit masks (by direction): */
+	LINE6_BITS_PLAYBACK_BUFFER =
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_BUFFER |
+#endif
+	    LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER |
+	    LINE6_BIT_PCM_MONITOR_PLAYBACK_BUFFER ,
+
+	LINE6_BITS_PLAYBACK_STREAM =
+#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
+	    LINE6_BIT_PCM_IMPULSE_PLAYBACK_STREAM |
+#endif
+	    LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM |
+	    LINE6_BIT_PCM_MONITOR_PLAYBACK_STREAM ,
+
+	LINE6_BITS_CAPTURE_BUFFER =
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-	MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE,
+	    LINE6_BIT_PCM_IMPULSE_CAPTURE_BUFFER |
 #endif
+	    LINE6_BIT_PCM_ALSA_CAPTURE_BUFFER |
+	    LINE6_BIT_PCM_MONITOR_CAPTURE_BUFFER ,
 
-	/* combined masks (by direction): */
+	LINE6_BITS_CAPTURE_STREAM =
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-	MASK_PLAYBACK =
-	    MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK |
-	    MASK_PCM_IMPULSE_PLAYBACK,
-	MASK_CAPTURE =
-	    MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE |
-	    MASK_PCM_IMPULSE_CAPTURE
-#else
-	MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK,
-	MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE
+	    LINE6_BIT_PCM_IMPULSE_CAPTURE_STREAM |
 #endif
+	    LINE6_BIT_PCM_ALSA_CAPTURE_STREAM |
+	    LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM,
+	
+	LINE6_BITS_STREAM =
+	    LINE6_BITS_PLAYBACK_STREAM |
+	    LINE6_BITS_CAPTURE_STREAM
 };
 
 struct line6_pcm_properties {
@@ -290,7 +364,7 @@ struct snd_line6_pcm {
 #endif
 
 	/**
-		 Several status bits (see BIT_*).
+		 Several status bits (see LINE6_BIT_*).
 	*/
 	unsigned long flags;
 
@@ -302,16 +376,7 @@ extern int line6_init_pcm(struct usb_line6 *line6,
 extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
 extern int snd_line6_prepare(struct snd_pcm_substream *substream);
 extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm);
-extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels);
-extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels);
-
-#define PRINT_FRAME_DIFF(op) {						\
-	static int diff_prev = 1000;					\
-	int diff = line6pcm->last_frame_out - line6pcm->last_frame_in;	\
-	if ((diff != diff_prev) && (abs(diff) < 100)) {			\
-		printk(KERN_INFO "%s frame diff = %d\n", op, diff);	\
-		diff_prev = diff;					\
-	}								\
-}
+extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels);
+extern int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels);
 
 #endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
index 4152db2..a0ab9d0 100644
--- a/drivers/staging/line6/playback.c
+++ b/drivers/staging/line6/playback.c
@@ -166,7 +166,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 		struct usb_iso_packet_descriptor *fout =
 		    &urb_out->iso_frame_desc[i];
 
-		if (line6pcm->flags & MASK_CAPTURE)
+		if (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM)
 			fsize = line6pcm->prev_fsize;
 
 		if (fsize == 0) {
@@ -196,8 +196,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 	urb_out->transfer_buffer_length = urb_size;
 	urb_out->context = line6pcm;
 
-	if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags) &&
-	    !test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
+	if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags) &&
+	    !test_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags)) {
 		struct snd_pcm_runtime *runtime =
 		    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
 
@@ -238,10 +238,10 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 
 	if (line6pcm->prev_fbuf != NULL) {
 #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
-		if (line6pcm->flags & MASK_PCM_IMPULSE) {
+		if (line6pcm->flags & LINE6_BITS_PCM_IMPULSE) {
 			create_impulse_test_signal(line6pcm, urb_out,
 						   bytes_per_frame);
-			if (line6pcm->flags & MASK_PCM_ALSA_CAPTURE) {
+			if (line6pcm->flags & LINE6_BIT_PCM_ALSA_CAPTURE_STREAM) {
 				line6_capture_copy(line6pcm,
 						   urb_out->transfer_buffer,
 						   urb_out->
@@ -254,8 +254,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 			if (!
 			    (line6pcm->line6->
 			     properties->capabilities & LINE6_BIT_HWMON)
-&& (line6pcm->flags & MASK_PLAYBACK)
-&& (line6pcm->flags & MASK_CAPTURE))
+			    && (line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM)
+			    && (line6pcm->flags & LINE6_BITS_CAPTURE_STREAM))
 				add_monitor_signal(urb_out, line6pcm->prev_fbuf,
 						   line6pcm->volume_monitor,
 						   bytes_per_frame);
@@ -321,7 +321,7 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 /*
 	Wait until unlinking of all currently active playback URBs has been finished.
 */
-static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 {
 	int timeout = HZ;
 	unsigned int i;
@@ -348,26 +348,7 @@ static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 {
 	line6_unlink_audio_out_urbs(line6pcm);
-	wait_clear_audio_out_urbs(line6pcm);
-}
-
-int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm)
-{
-	/* We may be invoked multiple times in a row so allocate once only */
-	if (line6pcm->buffer_out)
-		return 0;
-
-	line6pcm->buffer_out =
-		kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS *
-			line6pcm->max_packet_size, GFP_KERNEL);
-
-	if (!line6pcm->buffer_out) {
-		dev_err(line6pcm->line6->ifcdev,
-			"cannot malloc playback buffer\n");
-		return -ENOMEM;
-	}
-
-	return 0;
+	line6_wait_clear_audio_out_urbs(line6pcm);
 }
 
 void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm)
@@ -407,7 +388,7 @@ static void audio_out_callback(struct urb *urb)
 
 	spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
 
-	if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) {
+	if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) {
 		struct snd_pcm_runtime *runtime = substream->runtime;
 		line6pcm->pos_out_done +=
 		    length / line6pcm->properties->bytes_per_frame;
@@ -432,7 +413,7 @@ static void audio_out_callback(struct urb *urb)
 	if (!shutdown) {
 		submit_audio_out_urb(line6pcm);
 
-		if (test_bit(BIT_PCM_ALSA_PLAYBACK, &line6pcm->flags)) {
+		if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) {
 			line6pcm->bytes_out += length;
 			if (line6pcm->bytes_out >= line6pcm->period_out) {
 				line6pcm->bytes_out %= line6pcm->period_out;
@@ -484,17 +465,17 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,
 	}
 	/* -- [FD] end */
 
-	if ((line6pcm->flags & MASK_PLAYBACK) == 0) {
-		ret = line6_alloc_playback_buffer(line6pcm);
+	ret = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
 
-		if (ret < 0)
-			return ret;
-	}
+	if (ret < 0)
+		return ret;
 
 	ret = snd_pcm_lib_malloc_pages(substream,
 				       params_buffer_bytes(hw_params));
-	if (ret < 0)
+	if (ret < 0) {
+		line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
 		return ret;
+	}
 
 	line6pcm->period_out = params_period_bytes(hw_params);
 	return 0;
@@ -504,12 +485,7 @@ static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream,
 static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
-
-	if ((line6pcm->flags & MASK_PLAYBACK) == 0) {
-		line6_unlink_wait_clear_audio_out_urbs(line6pcm);
-		line6_free_playback_buffer(line6pcm);
-	}
-
+	line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_BUFFER);
 	return snd_pcm_lib_free_pages(substream);
 }
 
@@ -523,7 +499,7 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 #ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_RESUME:
 #endif
-		err = line6_pcm_start(line6pcm, MASK_PCM_ALSA_PLAYBACK);
+		err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
 
 		if (err < 0)
 			return err;
@@ -534,7 +510,7 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 #ifdef CONFIG_PM
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 #endif
-		err = line6_pcm_stop(line6pcm, MASK_PCM_ALSA_PLAYBACK);
+		err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM);
 
 		if (err < 0)
 			return err;
@@ -542,11 +518,11 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd)
 		break;
 
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+		set_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);
 		break;
 
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+		clear_bit(LINE6_INDEX_PAUSE_PLAYBACK, &line6pcm->flags);
 		break;
 
 	default:
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
index 02487ff..743bd6f 100644
--- a/drivers/staging/line6/playback.h
+++ b/drivers/staging/line6/playback.h
@@ -29,13 +29,13 @@
 
 extern struct snd_pcm_ops snd_line6_playback_ops;
 
-extern int line6_alloc_playback_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
 						   *line6pcm);
+extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
 
 #endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
index f310578..b754f69 100644
--- a/drivers/staging/line6/toneport.c
+++ b/drivers/staging/line6/toneport.c
@@ -207,9 +207,9 @@ static int snd_toneport_monitor_put(struct snd_kcontrol *kcontrol,
 	line6pcm->volume_monitor = ucontrol->value.integer.value[0];
 
 	if (line6pcm->volume_monitor > 0)
-		line6_pcm_start(line6pcm, MASK_PCM_MONITOR);
+		line6_pcm_acquire(line6pcm, LINE6_BITS_PCM_MONITOR);
 	else
-		line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
+		line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
 
 	return 1;
 }
@@ -264,7 +264,7 @@ static void toneport_start_pcm(unsigned long arg)
 {
 	struct usb_line6_toneport *toneport = (struct usb_line6_toneport *)arg;
 	struct usb_line6 *line6 = &toneport->line6;
-	line6_pcm_start(line6->line6pcm, MASK_PCM_MONITOR);
+	line6_pcm_acquire(line6->line6pcm, LINE6_BITS_PCM_MONITOR);
 }
 
 /* control definition */
@@ -320,7 +320,9 @@ static void toneport_setup(struct usb_line6_toneport *toneport)
 	/* initialize source select: */
 	switch (usbdev->descriptor.idProduct) {
 	case LINE6_DEVID_TONEPORT_UX1:
+	case LINE6_DEVID_TONEPORT_UX2:
 	case LINE6_DEVID_PODSTUDIO_UX1:
+	case LINE6_DEVID_PODSTUDIO_UX2:
 		toneport_send_cmd(usbdev,
 				  toneport_source_info[toneport->source].code,
 				  0x0000);
@@ -363,7 +365,9 @@ static int toneport_try_init(struct usb_interface *interface,
 	/* register source select control: */
 	switch (usbdev->descriptor.idProduct) {
 	case LINE6_DEVID_TONEPORT_UX1:
+	case LINE6_DEVID_TONEPORT_UX2:
 	case LINE6_DEVID_PODSTUDIO_UX1:
+	case LINE6_DEVID_PODSTUDIO_UX2:
 		err =
 		    snd_ctl_add(line6->card,
 				snd_ctl_new1(&toneport_control_source,
@@ -442,7 +446,7 @@ void line6_toneport_disconnect(struct usb_interface *interface)
 		struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
 
 		if (line6pcm != NULL) {
-			line6_pcm_stop(line6pcm, MASK_PCM_MONITOR);
+			line6_pcm_release(line6pcm, LINE6_BITS_PCM_MONITOR);
 			line6_pcm_disconnect(line6pcm);
 		}
 	}
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
index aff9e5c..353d59d 100644
--- a/drivers/staging/line6/usbdefs.h
+++ b/drivers/staging/line6/usbdefs.h
@@ -39,31 +39,29 @@
 #define LINE6_DEVID_TONEPORT_UX2  0x4142
 #define LINE6_DEVID_VARIAX        0x534d
 
-enum {
-	LINE6_ID_BASSPODXT,
-	LINE6_ID_BASSPODXTLIVE,
-	LINE6_ID_BASSPODXTPRO,
-	LINE6_ID_GUITARPORT,
-	LINE6_ID_POCKETPOD,
-	LINE6_ID_PODHD300,
-	LINE6_ID_PODHD500,
-	LINE6_ID_PODSTUDIO_GX,
-	LINE6_ID_PODSTUDIO_UX1,
-	LINE6_ID_PODSTUDIO_UX2,
-	LINE6_ID_PODX3,
-	LINE6_ID_PODX3LIVE,
-	LINE6_ID_PODXT,
-	LINE6_ID_PODXTLIVE,
-	LINE6_ID_PODXTPRO,
-	LINE6_ID_TONEPORT_GX,
-	LINE6_ID_TONEPORT_UX1,
-	LINE6_ID_TONEPORT_UX2,
-	LINE6_ID_VARIAX
-};
-
-#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_ID_ ## x
+#define LINE6_BIT(x) LINE6_BIT_ ## x = 1 << LINE6_INDEX_ ## x
 
 enum {
+	LINE6_INDEX_BASSPODXT,
+	LINE6_INDEX_BASSPODXTLIVE,
+	LINE6_INDEX_BASSPODXTPRO,
+	LINE6_INDEX_GUITARPORT,
+	LINE6_INDEX_POCKETPOD,
+	LINE6_INDEX_PODHD300,
+	LINE6_INDEX_PODHD500,
+	LINE6_INDEX_PODSTUDIO_GX,
+	LINE6_INDEX_PODSTUDIO_UX1,
+	LINE6_INDEX_PODSTUDIO_UX2,
+	LINE6_INDEX_PODX3,
+	LINE6_INDEX_PODX3LIVE,
+	LINE6_INDEX_PODXT,
+	LINE6_INDEX_PODXTLIVE,
+	LINE6_INDEX_PODXTPRO,
+	LINE6_INDEX_TONEPORT_GX,
+	LINE6_INDEX_TONEPORT_UX1,
+	LINE6_INDEX_TONEPORT_UX2,
+	LINE6_INDEX_VARIAX,
+
 	LINE6_BIT(BASSPODXT),
 	LINE6_BIT(BASSPODXTLIVE),
 	LINE6_BIT(BASSPODXTPRO),
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index 8ff5f38..3d439b7 100644
--- a/drivers/staging/media/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
@@ -3825,6 +3825,7 @@ static int easycap_usb_probe(struct usb_interface *intf,
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 			pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
 			if (!pdata_urb) {
+				usb_free_urb(purb);
 				SAM("ERROR: Could not allocate struct data_urb.\n");
 				return -ENOMEM;
 			}
diff --git a/drivers/staging/mei/TODO b/drivers/staging/mei/TODO
index 7d9a13b..fc26601 100644
--- a/drivers/staging/mei/TODO
+++ b/drivers/staging/mei/TODO
@@ -3,5 +3,8 @@ TODO:
 Upon Unstaging:
 	- move mei.h to include/linux/mei.h
 	- Documentation/ioctl/ioctl-number.txt
+	- move mei.txt under Documentation/mei/
+	- move mei-amt-version.c under Documentation/mei
+	- add hostprogs-y for mei-amt-version.c
 	- drop mei_version.h
 	- Updated MAINTAINERS
diff --git a/drivers/staging/mei/hw.h b/drivers/staging/mei/hw.h
index 9b9008c..b08c901 100644
--- a/drivers/staging/mei/hw.h
+++ b/drivers/staging/mei/hw.h
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c
index 4ac3696..393da4b 100644
--- a/drivers/staging/mei/init.c
+++ b/drivers/staging/mei/init.c
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c
index eb5df7f..484be56a 100644
--- a/drivers/staging/mei/interface.c
+++ b/drivers/staging/mei/interface.c
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -215,26 +215,17 @@ int mei_count_full_read_slots(struct mei_device *dev)
  * @buffer: message buffer will be written
  * @buffer_length: message size will be read
  */
-void mei_read_slots(struct mei_device *dev,
-		    unsigned char *buffer, unsigned long buffer_length)
+void mei_read_slots(struct mei_device *dev, unsigned char *buffer,
+		    unsigned long buffer_length)
 {
-	u32 i = 0;
-	unsigned char temp_buf[sizeof(u32)];
+	u32 *reg_buf = (u32 *)buffer;
 
-	while (buffer_length >= sizeof(u32)) {
-		((u32 *) buffer)[i] = mei_mecbrw_read(dev);
-
-		dev_dbg(&dev->pdev->dev,
-				"buffer[%d]= %d\n",
-				i, ((u32 *) buffer)[i]);
-
-		i++;
-		buffer_length -= sizeof(u32);
-	}
+	for (; buffer_length >= sizeof(u32); buffer_length -= sizeof(u32))
+		*reg_buf++ = mei_mecbrw_read(dev);
 
 	if (buffer_length > 0) {
-		*((u32 *) &temp_buf) = mei_mecbrw_read(dev);
-		memcpy(&buffer[i * 4], temp_buf, buffer_length);
+		u32 reg = mei_mecbrw_read(dev);
+		memcpy(reg_buf, &reg, buffer_length);
 	}
 
 	dev->host_hw_state |= H_IG;
diff --git a/drivers/staging/mei/interface.h b/drivers/staging/mei/interface.h
index aeae511..e5bfb18 100644
--- a/drivers/staging/mei/interface.h
+++ b/drivers/staging/mei/interface.h
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -33,7 +33,8 @@
 
 
 void mei_read_slots(struct mei_device *dev,
-		     unsigned char *buffer, unsigned long buffer_length);
+		     unsigned char *buffer,
+		     unsigned long buffer_length);
 
 int mei_write_message(struct mei_device *dev,
 			     struct mei_msg_hdr *header,
diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c
index 3544fee..3c21c93 100644
--- a/drivers/staging/mei/interrupt.c
+++ b/drivers/staging/mei/interrupt.c
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -123,8 +123,7 @@ static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list,
 	BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
 	BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
 
-	buffer = (unsigned char *) (dev->iamthif_msg_buf +
-			dev->iamthif_msg_buf_index);
+	buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
 	BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
 
 	mei_read_slots(dev, buffer, mei_hdr->length);
@@ -206,9 +205,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
 		cl = (struct mei_cl *)cb_pos->file_private;
 		if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
 			cl->reading_state = MEI_READING;
-			buffer = (unsigned char *)
-				(cb_pos->response_buffer.data +
-				cb_pos->information);
+			buffer = cb_pos->response_buffer.data + cb_pos->information;
 
 			if (cb_pos->response_buffer.size <
 					mei_hdr->length + cb_pos->information) {
@@ -247,8 +244,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
 quit:
 	dev_dbg(&dev->pdev->dev, "message read\n");
 	if (!buffer) {
-		mei_read_slots(dev, (unsigned char *) dev->rd_msg_buf,
-						mei_hdr->length);
+		mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
 		dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n",
 				*(u32 *) dev->rd_msg_buf);
 	}
@@ -632,13 +628,11 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
 	struct hbm_host_stop_request *host_stop_req;
 	int res;
 
-	unsigned char *buffer;
 
 	/* read the message to our buffer */
-	buffer = (unsigned char *) dev->rd_msg_buf;
 	BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
-	mei_read_slots(dev, buffer, mei_hdr->length);
-	mei_msg = (struct mei_bus_message *) buffer;
+	mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
+	mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
 
 	switch (*(u8 *) mei_msg) {
 	case HOST_START_RES_CMD:
@@ -1423,7 +1417,7 @@ void mei_timer(struct work_struct *work)
 
 	if (dev->iamthif_stall_timer) {
 		if (--dev->iamthif_stall_timer == 0) {
-			dev_dbg(&dev->pdev->dev, "reseting because of hang to amthi.\n");
+			dev_dbg(&dev->pdev->dev, "resetting because of hang to amthi.\n");
 			mei_reset(dev, 1);
 			dev->iamthif_msg_buf_size = 0;
 			dev->iamthif_msg_buf_index = 0;
diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c
index 0752ead..a3fbac9 100644
--- a/drivers/staging/mei/iorw.c
+++ b/drivers/staging/mei/iorw.c
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c
index 1e1a9f9..22afc92 100644
--- a/drivers/staging/mei/main.c
+++ b/drivers/staging/mei/main.c
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/mei/mei-amt-version.c b/drivers/staging/mei/mei-amt-version.c
new file mode 100644
index 0000000..be04934
--- /dev/null
+++ b/drivers/staging/mei/mei-amt-version.c
@@ -0,0 +1,479 @@
+/******************************************************************************
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Intel MEI Interface Header
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *	Intel Corporation.
+ *	linux-mei@linux.intel.com
+ *	http://www.intel.com
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <bits/wordsize.h>
+#include "mei.h"
+
+/*****************************************************************************
+ * Intel Management Enginin Interface
+ *****************************************************************************/
+
+#define mei_msg(_me, fmt, ARGS...) do {         \
+	if (_me->verbose)                       \
+		fprintf(stderr, fmt, ##ARGS);	\
+} while (0)
+
+#define mei_err(_me, fmt, ARGS...) do {         \
+	fprintf(stderr, "Error: " fmt, ##ARGS); \
+} while (0)
+
+struct mei {
+	uuid_le guid;
+	bool initialized;
+	bool verbose;
+	unsigned int buf_size;
+	unsigned char prot_ver;
+	int fd;
+};
+
+static void mei_deinit(struct mei *cl)
+{
+	if (cl->fd != -1)
+		close(cl->fd);
+	cl->fd = -1;
+	cl->buf_size = 0;
+	cl->prot_ver = 0;
+	cl->initialized = false;
+}
+
+static bool mei_init(struct mei *me, const uuid_le *guid,
+		unsigned char req_protocol_version, bool verbose)
+{
+	int result;
+	struct mei_client *cl;
+	struct mei_connect_client_data data;
+
+	mei_deinit(me);
+
+	me->verbose = verbose;
+
+	me->fd = open("/dev/mei", O_RDWR);
+	if (me->fd == -1) {
+		mei_err(me, "Cannot establish a handle to the Intel MEI driver\n");
+		goto err;
+	}
+	memcpy(&me->guid, guid, sizeof(*guid));
+	memset(&data, 0, sizeof(data));
+	me->initialized = true;
+
+	memcpy(&data.in_client_uuid, &me->guid, sizeof(me->guid));
+	result = ioctl(me->fd, IOCTL_MEI_CONNECT_CLIENT, &data);
+	if (result) {
+		mei_err(me, "IOCTL_MEI_CONNECT_CLIENT receive message. err=%d\n", result);
+		goto err;
+	}
+	cl = &data.out_client_properties;
+	mei_msg(me, "max_message_length %d\n", cl->max_msg_length);
+	mei_msg(me, "protocol_version %d\n", cl->protocol_version);
+
+	if ((req_protocol_version > 0) &&
+	     (cl->protocol_version != req_protocol_version)) {
+		mei_err(me, "Intel MEI protocol version not supported\n");
+		goto err;
+	}
+
+	me->buf_size = cl->max_msg_length;
+	me->prot_ver = cl->protocol_version;
+
+	return true;
+err:
+	mei_deinit(me);
+	return false;
+}
+
+static ssize_t mei_recv_msg(struct mei *me, unsigned char *buffer,
+			ssize_t len, unsigned long timeout)
+{
+	ssize_t rc;
+
+	mei_msg(me, "call read length = %zd\n", len);
+
+	rc = read(me->fd, buffer, len);
+	if (rc < 0) {
+		mei_err(me, "read failed with status %zd %s\n",
+				rc, strerror(errno));
+		mei_deinit(me);
+	} else {
+		mei_msg(me, "read succeeded with result %zd\n", rc);
+	}
+	return rc;
+}
+
+static ssize_t mei_send_msg(struct mei *me, const unsigned char *buffer,
+			ssize_t len, unsigned long timeout)
+{
+	struct timeval tv;
+	ssize_t written;
+	ssize_t rc;
+	fd_set set;
+
+	tv.tv_sec = timeout / 1000;
+	tv.tv_usec = (timeout % 1000) * 1000000;
+
+	mei_msg(me, "call write length = %zd\n", len);
+
+	written = write(me->fd, buffer, len);
+	if (written < 0) {
+		rc = -errno;
+		mei_err(me, "write failed with status %zd %s\n",
+			written, strerror(errno));
+		goto out;
+	}
+
+	FD_ZERO(&set);
+	FD_SET(me->fd, &set);
+	rc = select(me->fd + 1 , &set, NULL, NULL, &tv);
+	if (rc > 0 && FD_ISSET(me->fd, &set)) {
+		mei_msg(me, "write success\n");
+	} else if (rc == 0) {
+		mei_err(me, "write failed on timeout with status\n");
+		goto out;
+	} else { /* rc < 0 */
+		mei_err(me, "write failed on select with status %zd\n", rc);
+		goto out;
+	}
+
+	rc = written;
+out:
+	if (rc < 0)
+		mei_deinit(me);
+
+	return rc;
+}
+
+/***************************************************************************
+ * Intel Advanced Management Technolgy ME Client
+ ***************************************************************************/
+
+#define AMT_MAJOR_VERSION 1
+#define AMT_MINOR_VERSION 1
+
+#define AMT_STATUS_SUCCESS                0x0
+#define AMT_STATUS_INTERNAL_ERROR         0x1
+#define AMT_STATUS_NOT_READY              0x2
+#define AMT_STATUS_INVALID_AMT_MODE       0x3
+#define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4
+
+#define AMT_STATUS_HOST_IF_EMPTY_RESPONSE  0x4000
+#define AMT_STATUS_SDK_RESOURCES      0x1004
+
+
+#define AMT_BIOS_VERSION_LEN   65
+#define AMT_VERSIONS_NUMBER    50
+#define AMT_UNICODE_STRING_LEN 20
+
+struct amt_unicode_string {
+	uint16_t length;
+	char string[AMT_UNICODE_STRING_LEN];
+} __attribute__((packed));
+
+struct amt_version_type {
+	struct amt_unicode_string description;
+	struct amt_unicode_string version;
+} __attribute__((packed));
+
+struct amt_version {
+	uint8_t major;
+	uint8_t minor;
+} __attribute__((packed));
+
+struct amt_code_versions {
+	uint8_t bios[AMT_BIOS_VERSION_LEN];
+	uint32_t count;
+	struct amt_version_type versions[AMT_VERSIONS_NUMBER];
+} __attribute__((packed));
+
+/***************************************************************************
+ * Intel Advanced Management Technolgy Host Interface
+ ***************************************************************************/
+
+struct amt_host_if_msg_header {
+	struct amt_version version;
+	uint16_t _reserved;
+	uint32_t command;
+	uint32_t length;
+} __attribute__((packed));
+
+struct amt_host_if_resp_header {
+	struct amt_host_if_msg_header header;
+	uint32_t status;
+	unsigned char data[0];
+} __attribute__((packed));
+
+const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,  \
+				0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c);
+
+#define AMT_HOST_IF_CODE_VERSIONS_REQUEST  0x0400001A
+#define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A
+
+const struct amt_host_if_msg_header CODE_VERSION_REQ = {
+	.version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION},
+	._reserved = 0,
+	.command = AMT_HOST_IF_CODE_VERSIONS_REQUEST,
+	.length = 0
+};
+
+
+struct amt_host_if {
+	struct mei mei_cl;
+	unsigned long send_timeout;
+	bool initialized;
+};
+
+
+bool amt_host_if_init(struct amt_host_if *acmd,
+		      unsigned long send_timeout, bool verbose)
+{
+	acmd->send_timeout = (send_timeout) ? send_timeout : 20000;
+	acmd->initialized = mei_init(&acmd->mei_cl, &MEI_IAMTHIF, 0, verbose);
+	return acmd->initialized;
+}
+
+void amt_host_if_deinit(struct amt_host_if *acmd)
+{
+	mei_deinit(&acmd->mei_cl);
+	acmd->initialized = false;
+}
+
+uint32_t amt_verify_code_versions(const struct amt_host_if_resp_header *resp)
+{
+	uint32_t status = AMT_STATUS_SUCCESS;
+	struct amt_code_versions *code_ver;
+	size_t code_ver_len;
+	uint32_t ver_type_cnt;
+	uint32_t len;
+	uint32_t i;
+
+	code_ver = (struct amt_code_versions *)resp->data;
+	/* length - sizeof(status) */
+	code_ver_len = resp->header.length - sizeof(uint32_t);
+	ver_type_cnt = code_ver_len -
+			sizeof(code_ver->bios) -
+			sizeof(code_ver->count);
+	if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) {
+		status = AMT_STATUS_INTERNAL_ERROR;
+		goto out;
+	}
+
+	for (i = 0; i < code_ver->count; i++) {
+		len = code_ver->versions[i].description.length;
+
+		if (len > AMT_UNICODE_STRING_LEN) {
+			status = AMT_STATUS_INTERNAL_ERROR;
+			goto out;
+		}
+
+		len = code_ver->versions[i].version.length;
+		if (code_ver->versions[i].version.string[len] != '\0' ||
+		    len != strlen(code_ver->versions[i].version.string)) {
+			status = AMT_STATUS_INTERNAL_ERROR;
+			goto out;
+		}
+	}
+out:
+	return status;
+}
+
+uint32_t amt_verify_response_header(uint32_t command,
+				const struct amt_host_if_msg_header *resp_hdr,
+				uint32_t response_size)
+{
+	if (response_size < sizeof(struct amt_host_if_resp_header)) {
+		return AMT_STATUS_INTERNAL_ERROR;
+	} else if (response_size != (resp_hdr->length +
+				sizeof(struct amt_host_if_msg_header))) {
+		return AMT_STATUS_INTERNAL_ERROR;
+	} else if (resp_hdr->command != command) {
+		return AMT_STATUS_INTERNAL_ERROR;
+	} else if (resp_hdr->_reserved != 0) {
+		return AMT_STATUS_INTERNAL_ERROR;
+	} else if (resp_hdr->version.major != AMT_MAJOR_VERSION ||
+		   resp_hdr->version.minor < AMT_MINOR_VERSION) {
+		return AMT_STATUS_INTERNAL_ERROR;
+	}
+	return AMT_STATUS_SUCCESS;
+}
+
+static uint32_t amt_host_if_call(struct amt_host_if *acmd,
+			const unsigned char *command, ssize_t command_sz,
+			uint8_t **read_buf, uint32_t rcmd,
+			unsigned int expected_sz)
+{
+	uint32_t in_buf_sz;
+	uint32_t out_buf_sz;
+	ssize_t written;
+	uint32_t status;
+	struct amt_host_if_resp_header *msg_hdr;
+
+	in_buf_sz = acmd->mei_cl.buf_size;
+	*read_buf = (uint8_t *)malloc(sizeof(uint8_t) * in_buf_sz);
+	if (*read_buf == NULL)
+		return AMT_STATUS_SDK_RESOURCES;
+	memset(*read_buf, 0, in_buf_sz);
+	msg_hdr = (struct amt_host_if_resp_header *)*read_buf;
+
+	written = mei_send_msg(&acmd->mei_cl,
+				command, command_sz, acmd->send_timeout);
+	if (written != command_sz)
+		return AMT_STATUS_INTERNAL_ERROR;
+
+	out_buf_sz = mei_recv_msg(&acmd->mei_cl, *read_buf, in_buf_sz, 2000);
+	if (out_buf_sz <= 0)
+		return AMT_STATUS_HOST_IF_EMPTY_RESPONSE;
+
+	status = msg_hdr->status;
+	if (status != AMT_STATUS_SUCCESS)
+		return status;
+
+	status = amt_verify_response_header(rcmd,
+				&msg_hdr->header, out_buf_sz);
+	if (status != AMT_STATUS_SUCCESS)
+		return status;
+
+	if (expected_sz && expected_sz != out_buf_sz)
+		return AMT_STATUS_INTERNAL_ERROR;
+
+	return AMT_STATUS_SUCCESS;
+}
+
+
+uint32_t amt_get_code_versions(struct amt_host_if *cmd,
+			       struct amt_code_versions *versions)
+{
+	struct amt_host_if_resp_header *response = NULL;
+	uint32_t status;
+
+	status = amt_host_if_call(cmd,
+			(const unsigned char *)&CODE_VERSION_REQ,
+			sizeof(CODE_VERSION_REQ),
+			(uint8_t **)&response,
+			AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0);
+
+	if (status != AMT_STATUS_SUCCESS)
+		goto out;
+
+	status = amt_verify_code_versions(response);
+	if (status != AMT_STATUS_SUCCESS)
+		goto out;
+
+	memcpy(versions, response->data, sizeof(struct amt_code_versions));
+out:
+	if (response != NULL)
+		free(response);
+
+	return status;
+}
+
+/************************** end of amt_host_if_command ***********************/
+int main(int argc, char **argv)
+{
+	struct amt_code_versions ver;
+	struct amt_host_if acmd;
+	unsigned int i;
+	uint32_t status;
+	int ret;
+	bool verbose;
+
+	verbose = (argc > 1 && strcmp(argv[1], "-v") == 0);
+
+	if (!amt_host_if_init(&acmd, 5000, verbose)) {
+		ret = 1;
+		goto out;
+	}
+
+	status = amt_get_code_versions(&acmd, &ver);
+
+	switch (status) {
+	case AMT_STATUS_HOST_IF_EMPTY_RESPONSE:
+		printf("Intel AMT: DISABLED\n");
+		ret = 0;
+		break;
+	case AMT_STATUS_SUCCESS:
+		printf("Intel AMT: ENABLED\n");
+		for (i = 0; i < ver.count; i++) {
+			printf("%s:\t%s\n", ver.versions[i].description.string,
+				ver.versions[i].version.string);
+		}
+		ret = 0;
+		break;
+	default:
+		printf("An error has occurred\n");
+		ret = 1;
+		break;
+	}
+
+out:
+	return ret;
+}
diff --git a/drivers/staging/mei/mei.h b/drivers/staging/mei/mei.h
index 6da7c4f..b09b11c 100644
--- a/drivers/staging/mei/mei.h
+++ b/drivers/staging/mei/mei.h
@@ -1,63 +1,68 @@
-/*
-
-  Intel Management Engine Interface (Intel MEI) Linux driver
-  Intel MEI Interface Header
-
-  This file is provided under a dual BSD/GPLv2 license.  When using or
-  redistributing this file, you may do so under either license.
-
-  GPL LICENSE SUMMARY
-
-  Copyright(c) 2003-2011 Intel Corporation. All rights reserved.
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of version 2 of the GNU General Public License as
-  published by the Free Software Foundation.
-
-  This program is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  General Public License for more details.
-
-  Contact Information:
-	  Intel Corporation.
-	  linux-mei@linux.intel.com
-	  http://www.intel.com
-
-
-  BSD LICENSE
-
-  Copyright(c) 2003-2011 Intel Corporation. All rights reserved.
-  All rights reserved.
-
-  Redistribution and use in source and binary forms, with or without
-  modification, are permitted provided that the following conditions
-  are met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in
-      the documentation and/or other materials provided with the
-      distribution.
-    * Neither the name of Intel Corporation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*/
-
+/******************************************************************************
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Intel MEI Interface Header
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *	Intel Corporation.
+ *	linux-mei@linux.intel.com
+ *	http://www.intel.com
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
 
 #ifndef _LINUX_MEI_H
 #define _LINUX_MEI_H
diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h
index 82bacfc..0d937b0 100644
--- a/drivers/staging/mei/mei_dev.h
+++ b/drivers/staging/mei/mei_dev.h
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -30,6 +30,8 @@
 #define MEI_WD_PARAMS_SIZE             4
 #define MEI_WD_STATE_INDEPENDENCE_MSG_SENT       (1 << 0)
 
+#define MEI_RD_MSG_BUF_SIZE           (128 * sizeof(u32))
+
 /*
  * MEI PCI Device object
  */
@@ -125,7 +127,7 @@ enum mei_cb_major_types {
  */
 struct mei_message_data {
 	u32 size;
-	char *data;
+	unsigned char *data;
 } __packed;
 
 
@@ -219,7 +221,7 @@ struct mei_device {
 	bool need_reset;
 
 	u32 extra_write_index;
-	u32 rd_msg_buf[128];	/* used for control messages */
+	unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE];	/* control messages */
 	u32 wr_msg_buf[128];	/* used for control messages */
 	u32 ext_msg_buf[8];	/* for control responses */
 	u32 rd_msg_hdr;
diff --git a/drivers/staging/mei/mei_version.h b/drivers/staging/mei/mei_version.h
index 075bad8..21955e7 100644
--- a/drivers/staging/mei/mei_version.h
+++ b/drivers/staging/mei/mei_version.h
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c
index 8094941..f397835 100644
--- a/drivers/staging/mei/wd.c
+++ b/drivers/staging/mei/wd.c
@@ -1,7 +1,7 @@
 /*
  *
  * Intel Management Engine Interface (Intel MEI) Linux driver
- * Copyright (c) 2003-2011, Intel Corporation.
+ * Copyright (c) 2003-2012, Intel Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig
index 86a8b8c..731301f 100644
--- a/drivers/staging/nvec/Kconfig
+++ b/drivers/staging/nvec/Kconfig
@@ -7,21 +7,21 @@ config MFD_NVEC
 
 config KEYBOARD_NVEC
 	bool "Keyboard on nVidia compliant EC"
-	depends on MFD_NVEC && INPUT=y
+	depends on MFD_NVEC && INPUT
 	help
 	  Say Y here to enable support for a keyboard connected to 
 	  a nVidia compliant embedded controller.
 
 config SERIO_NVEC_PS2
 	bool "PS2 on nVidia EC"
-	depends on MFD_NVEC && MOUSE_PS2
+	depends on MFD_NVEC && SERIO
 	help
 	  Say Y here to enable support for a Touchpad / Mouse connected
 	  to a nVidia compliant embedded controller.
 
 config NVEC_POWER
 	bool "NVEC charger and battery"
-	depends on MFD_NVEC && POWER_SUPPLY=y
+	depends on MFD_NVEC && POWER_SUPPLY
 	help
 	  Say Y to enable support for battery and charger interface for
 	  nVidia compliant embedded controllers.
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index fafdfa2..3c60088 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -49,7 +49,7 @@
 #define I2C_CNFG_DEBOUNCE_CNT_SHIFT	12
 
 #define I2C_SL_CNFG		0x20
-#define I2C_SL_NEWL		(1<<2)
+#define I2C_SL_NEWSL		(1<<2)
 #define I2C_SL_NACK		(1<<1)
 #define I2C_SL_RESP		(1<<0)
 #define I2C_SL_IRQ		(1<<3)
@@ -687,7 +687,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec)
 
 	clk_set_rate(nvec->i2c_clk, 8 * 80000);
 
-	writel(I2C_SL_NEWL, nvec->base + I2C_SL_CNFG);
+	writel(I2C_SL_NEWSL, nvec->base + I2C_SL_CNFG);
 	writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT);
 
 	writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1);
@@ -701,7 +701,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec)
 static void nvec_disable_i2c_slave(struct nvec_chip *nvec)
 {
 	disable_irq(nvec->irq);
-	writel(I2C_SL_NEWL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG);
+	writel(I2C_SL_NEWSL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG);
 	clk_disable(nvec->i2c_clk);
 }
 
@@ -784,11 +784,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
 	nvec->i2c_clk = i2c_clk;
 	nvec->rx = &nvec->msg_pool[0];
 
-	/* Set the gpio to low when we've got something to say */
-	err = gpio_request(nvec->gpio, "nvec gpio");
-	if (err < 0)
-		dev_err(nvec->dev, "couldn't request gpio\n");
-
 	ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list);
 
 	init_completion(&nvec->sync_write);
@@ -802,6 +797,12 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
 	INIT_WORK(&nvec->tx_work, nvec_request_master);
 	nvec->wq = alloc_workqueue("nvec", WQ_NON_REENTRANT, 2);
 
+	err = gpio_request_one(nvec->gpio, GPIOF_OUT_INIT_HIGH, "nvec gpio");
+	if (err < 0) {
+		dev_err(nvec->dev, "couldn't request gpio\n");
+		goto failed;
+	}
+
 	err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec);
 	if (err) {
 		dev_err(nvec->dev, "couldn't request irq\n");
@@ -813,8 +814,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev)
 
 	clk_enable(i2c_clk);
 
-	gpio_direction_output(nvec->gpio, 1);
-	gpio_set_value(nvec->gpio, 1);
 
 	/* enable event reporting */
 	nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING,
diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c
index 742f5cc..14a6f68 100644
--- a/drivers/staging/nvec/nvec_ps2.c
+++ b/drivers/staging/nvec/nvec_ps2.c
@@ -21,10 +21,18 @@
 
 #include "nvec.h"
 
-#define START_STREAMING	{'\x06', '\x03', '\x04'}
+#define START_STREAMING	{'\x06', '\x03', '\x06'}
 #define STOP_STREAMING	{'\x06', '\x04'}
 #define SEND_COMMAND	{'\x06', '\x01', '\xf4', '\x01'}
 
+#ifdef NVEC_PS2_DEBUG
+#define NVEC_PHD(str, buf, len) \
+	print_hex_dump(KERN_DEBUG, str, DUMP_PREFIX_NONE, \
+			16, 1, buf, len, false)
+#else
+#define NVEC_PHD(str, buf, len)
+#endif
+
 static const unsigned char MOUSE_RESET[] = {'\x06', '\x01', '\xff', '\x03'};
 
 struct nvec_ps2 {
@@ -67,18 +75,18 @@ static int nvec_ps2_notifier(struct notifier_block *nb,
 	case NVEC_PS2_EVT:
 		for (i = 0; i < msg[1]; i++)
 			serio_interrupt(ps2_dev.ser_dev, msg[2 + i], 0);
+		NVEC_PHD("ps/2 mouse event: ", &msg[2], msg[1]);
 		return NOTIFY_STOP;
 
 	case NVEC_PS2:
-		if (msg[2] == 1)
+		if (msg[2] == 1) {
 			for (i = 0; i < (msg[1] - 2); i++)
 				serio_interrupt(ps2_dev.ser_dev, msg[i + 4], 0);
-		else if (msg[1] != 2) {	/* !ack */
-			print_hex_dump(KERN_WARNING, "unhandled mouse event: ",
-				DUMP_PREFIX_NONE, 16, 1,
-				msg, msg[1] + 2, true);
+			NVEC_PHD("ps/2 mouse reply: ", &msg[4], msg[1] - 2);
 		}
 
+		else if (msg[1] != 2) /* !ack */
+			NVEC_PHD("unhandled mouse event: ", msg, msg[1] + 2);
 		return NOTIFY_STOP;
 	}
 
@@ -90,10 +98,10 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev)
 	struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
 	struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);
 
-	ser_dev->id.type = SERIO_8042;
+	ser_dev->id.type = SERIO_PS_PSTHRU;
 	ser_dev->write = ps2_sendcommand;
-	ser_dev->open = ps2_startstreaming;
-	ser_dev->close = ps2_stopstreaming;
+	ser_dev->start = ps2_startstreaming;
+	ser_dev->stop = ps2_stopstreaming;
 
 	strlcpy(ser_dev->name, "nvec mouse", sizeof(ser_dev->name));
 	strlcpy(ser_dev->phys, "nvec", sizeof(ser_dev->phys));
@@ -111,8 +119,35 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+
+	/* disable mouse */
+	nvec_write_async(nvec, "\x06\xf4", 2);
+
+	/* send cancel autoreceive */
+	nvec_write_async(nvec, "\x06\x04", 2);
+
+	return 0;
+}
+
+static int nvec_mouse_resume(struct platform_device *pdev)
+{
+	struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+
+	ps2_startstreaming(ps2_dev.ser_dev);
+
+	/* enable mouse */
+	nvec_write_async(nvec, "\x06\xf5", 2);
+
+	return 0;
+}
+
 static struct platform_driver nvec_mouse_driver = {
 	.probe  = nvec_mouse_probe,
+	.suspend = nvec_mouse_suspend,
+	.resume = nvec_mouse_resume,
 	.driver = {
 		.name = "nvec-mouse",
 		.owner = THIS_MODULE,
diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/staging/omapdrm/omap_gem_helpers.c
index 29275c7..f895363 100644
--- a/drivers/staging/omapdrm/omap_gem_helpers.c
+++ b/drivers/staging/omapdrm/omap_gem_helpers.c
@@ -84,7 +84,7 @@ fail:
 		page_cache_release(pages[i]);
 	}
 	drm_free_large(pages);
-	return ERR_PTR(PTR_ERR(p));
+	return ERR_CAST(p);
 }
 
 /**
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c
index c60911c..cac3207 100644
--- a/drivers/staging/quickstart/quickstart.c
+++ b/drivers/staging/quickstart/quickstart.c
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2007-2010 Angelo Arrifano <miknix@gmail.com>
  *
- *  Information gathered from disassebled dsdt and from here:
+ *  Information gathered from disassembled dsdt and from here:
  *  <http://www.microsoft.com/whdc/system/platform/firmware/DirAppLaunch.mspx>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -23,7 +23,9 @@
  *
  */
 
-#define QUICKSTART_VERSION "1.03"
+#define QUICKSTART_VERSION "1.04"
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -37,118 +39,73 @@ MODULE_AUTHOR("Angelo Arrifano");
 MODULE_DESCRIPTION("ACPI Direct App Launch driver");
 MODULE_LICENSE("GPL");
 
-#define QUICKSTART_ACPI_DEVICE_NAME   "quickstart"
-#define QUICKSTART_ACPI_CLASS         "quickstart"
-#define QUICKSTART_ACPI_HID           "PNP0C32"
-
-#define QUICKSTART_PF_DRIVER_NAME     "quickstart"
-#define QUICKSTART_PF_DEVICE_NAME     "quickstart"
-#define QUICKSTART_PF_DEVATTR_NAME    "pressed_button"
+#define QUICKSTART_ACPI_DEVICE_NAME	"quickstart"
+#define QUICKSTART_ACPI_CLASS		"quickstart"
+#define QUICKSTART_ACPI_HID		"PNP0C32"
 
-#define QUICKSTART_MAX_BTN_NAME_LEN   16
+#define QUICKSTART_PF_DRIVER_NAME	"quickstart"
+#define QUICKSTART_PF_DEVICE_NAME	"quickstart"
 
-/* There will be two events:
-	 * 0x02 - A hot button was pressed while device was off/sleeping.
-	 * 0x80 - A hot button was pressed while device was up. */
-#define QUICKSTART_EVENT_WAKE         0x02
-#define QUICKSTART_EVENT_RUNTIME      0x80
+/*
+ * There will be two events:
+ * 0x02 - A hot button was pressed while device was off/sleeping.
+ * 0x80 - A hot button was pressed while device was up.
+ */
+#define QUICKSTART_EVENT_WAKE		0x02
+#define QUICKSTART_EVENT_RUNTIME	0x80
 
-struct quickstart_btn {
+struct quickstart_button {
 	char *name;
 	unsigned int id;
-	struct quickstart_btn *next;
+	struct list_head list;
 };
 
-static struct quickstart_driver_data {
-	struct quickstart_btn *btn_lst;
-	struct quickstart_btn *pressed;
-} quickstart_data;
-
-/* ACPI driver Structs */
 struct quickstart_acpi {
 	struct acpi_device *device;
-	struct quickstart_btn *btn;
-};
-static int quickstart_acpi_add(struct acpi_device *device);
-static int quickstart_acpi_remove(struct acpi_device *device, int type);
-static const struct acpi_device_id  quickstart_device_ids[] = {
-	{QUICKSTART_ACPI_HID, 0},
-	{"", 0},
+	struct quickstart_button *button;
 };
 
-static struct acpi_driver quickstart_acpi_driver = {
-	.name = "quickstart",
-	.class = QUICKSTART_ACPI_CLASS,
-	.ids = quickstart_device_ids,
-	.ops = {
-			.add = quickstart_acpi_add,
-			.remove = quickstart_acpi_remove,
-		},
-};
+static LIST_HEAD(buttons);
+static struct quickstart_button *pressed;
 
-/* Input device structs */
-struct input_dev *quickstart_input;
+static struct input_dev *quickstart_input;
 
-/* Platform driver structs */
-static ssize_t buttons_show(struct device *dev,
-					struct device_attribute *attr,
-					char *buf);
-static ssize_t pressed_button_show(struct device *dev,
+/* Platform driver functions */
+static ssize_t quickstart_buttons_show(struct device *dev,
 					struct device_attribute *attr,
-					char *buf);
-static ssize_t pressed_button_store(struct device *dev,
-					struct device_attribute *attr,
-					 const char *buf,
-					 size_t count);
-static DEVICE_ATTR(pressed_button, 0666, pressed_button_show,
-					 pressed_button_store);
-static DEVICE_ATTR(buttons, 0444, buttons_show, NULL);
-static struct platform_device *pf_device;
-static struct platform_driver pf_driver = {
-	.driver = {
-		.name = QUICKSTART_PF_DRIVER_NAME,
-		.owner = THIS_MODULE,
-	}
-};
-
-/*
- * Platform driver functions
- */
-static ssize_t buttons_show(struct device *dev,
-					 struct device_attribute *attr,
-					 char *buf)
+					char *buf)
 {
 	int count = 0;
-	struct quickstart_btn *ptr = quickstart_data.btn_lst;
+	struct quickstart_button *b;
 
-	if (!ptr)
+	if (list_empty(&buttons))
 		return snprintf(buf, PAGE_SIZE, "none");
 
-	while (ptr && (count < PAGE_SIZE)) {
-		if (ptr->name) {
-			count += snprintf(buf + count,
-					PAGE_SIZE - count,
-					"%d\t%s\n", ptr->id, ptr->name);
+	list_for_each_entry(b, &buttons, list) {
+		count += snprintf(buf + count, PAGE_SIZE - count, "%u\t%s\n",
+							b->id, b->name);
+
+		if (count >= PAGE_SIZE) {
+			count = PAGE_SIZE;
+			break;
 		}
-		ptr = ptr->next;
 	}
 
 	return count;
 }
 
-static ssize_t pressed_button_show(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+static ssize_t quickstart_pressed_button_show(struct device *dev,
+						struct device_attribute *attr,
+						char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			(quickstart_data.pressed ?
-			 quickstart_data.pressed->name : "none"));
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+					(pressed ? pressed->name : "none"));
 }
 
 
-static ssize_t pressed_button_store(struct device *dev,
-					 struct device_attribute *attr,
-					 const char *buf, size_t count)
+static ssize_t quickstart_pressed_button_store(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf, size_t count)
 {
 	if (count < 2)
 		return -EINVAL;
@@ -156,60 +113,40 @@ static ssize_t pressed_button_store(struct device *dev,
 	if (strncasecmp(buf, "none", 4) != 0)
 		return -EINVAL;
 
-	quickstart_data.pressed = NULL;
+	pressed = NULL;
 	return count;
 }
 
-/* Hotstart Helper functions */
-static int quickstart_btnlst_add(struct quickstart_btn **data)
+/* Helper functions */
+static struct quickstart_button *quickstart_buttons_add(void)
 {
-	struct quickstart_btn **ptr = &quickstart_data.btn_lst;
+	struct quickstart_button *b;
 
-	while (*ptr)
-		ptr = &((*ptr)->next);
+	b = kzalloc(sizeof(*b), GFP_KERNEL);
+	if (!b)
+		return NULL;
 
-	*ptr = kzalloc(sizeof(struct quickstart_btn), GFP_KERNEL);
-	if (!*ptr) {
-		*data = NULL;
-		return -ENOMEM;
-	}
-	*data = *ptr;
+	list_add_tail(&b->list, &buttons);
 
-	return 0;
+	return b;
 }
 
-static void quickstart_btnlst_del(struct quickstart_btn *data)
+static void quickstart_button_del(struct quickstart_button *data)
 {
-	struct quickstart_btn **ptr = &quickstart_data.btn_lst;
-
 	if (!data)
 		return;
 
-	while (*ptr) {
-		if (*ptr == data) {
-			*ptr = (*ptr)->next;
-			kfree(data);
-			return;
-		}
-		ptr = &((*ptr)->next);
-	}
-
-	return;
+	list_del(&data->list);
+	kfree(data->name);
+	kfree(data);
 }
 
-static void quickstart_btnlst_free(void)
+static void quickstart_buttons_free(void)
 {
-	struct quickstart_btn *ptr = quickstart_data.btn_lst;
-	struct quickstart_btn *lptr = NULL;
-
-	while (ptr) {
-		lptr = ptr;
-		ptr = ptr->next;
-		kfree(lptr->name);
-		kfree(lptr);
-	}
+	struct quickstart_button *b, *n;
 
-	return;
+	list_for_each_entry_safe(b, n, &buttons, list)
+		quickstart_button_del(b);
 }
 
 /* ACPI Driver functions */
@@ -220,107 +157,137 @@ static void quickstart_acpi_notify(acpi_handle handle, u32 event, void *data)
 	if (!quickstart)
 		return;
 
-	if (event == QUICKSTART_EVENT_WAKE)
-		quickstart_data.pressed = quickstart->btn;
-	else if (event == QUICKSTART_EVENT_RUNTIME) {
-		input_report_key(quickstart_input, quickstart->btn->id, 1);
+	switch (event) {
+	case QUICKSTART_EVENT_WAKE:
+		pressed = quickstart->button;
+		break;
+	case QUICKSTART_EVENT_RUNTIME:
+		input_report_key(quickstart_input, quickstart->button->id, 1);
 		input_sync(quickstart_input);
-		input_report_key(quickstart_input, quickstart->btn->id, 0);
+		input_report_key(quickstart_input, quickstart->button->id, 0);
 		input_sync(quickstart_input);
+		break;
+	default:
+		pr_err("Unexpected ACPI event notify (%u)\n", event);
+		break;
 	}
-	return;
 }
 
-static void quickstart_acpi_ghid(struct quickstart_acpi *quickstart)
+static int quickstart_acpi_ghid(struct quickstart_acpi *quickstart)
 {
 	acpi_status status;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	uint32_t usageid = 0;
-
-	if (!quickstart)
-		return;
+	int ret = 0;
 
-	/* This returns a buffer telling the button usage ID,
-	 * and triggers pending notify events (The ones before booting). */
-	status = acpi_evaluate_object(quickstart->device->handle,
-					"GHID", NULL, &buffer);
-	if (ACPI_FAILURE(status) || !buffer.pointer) {
-		printk(KERN_ERR "quickstart: %s GHID method failed.\n",
-		       quickstart->btn->name);
-		return;
+	/*
+	 * This returns a buffer telling the button usage ID,
+	 * and triggers pending notify events (The ones before booting).
+	 */
+	status = acpi_evaluate_object(quickstart->device->handle, "GHID", NULL,
+								&buffer);
+	if (ACPI_FAILURE(status)) {
+		pr_err("%s GHID method failed\n", quickstart->button->name);
+		return -EINVAL;
 	}
 
-	if (buffer.length < 8)
-		return;
-
-	/* <<The GHID method can return a BYTE, WORD, or DWORD.
+	/*
+	 * <<The GHID method can return a BYTE, WORD, or DWORD.
 	 * The value must be encoded in little-endian byte
-	 * order (least significant byte first).>> */
-	usageid = *((uint32_t *)(buffer.pointer + (buffer.length - 8)));
-	quickstart->btn->id = usageid;
+	 * order (least significant byte first).>>
+	 */
+	switch (buffer.length) {
+	case 1:
+		quickstart->button->id = *(uint8_t *)buffer.pointer;
+		break;
+	case 2:
+		quickstart->button->id = *(uint16_t *)buffer.pointer;
+		break;
+	case 4:
+		quickstart->button->id = *(uint32_t *)buffer.pointer;
+		break;
+	case 8:
+		quickstart->button->id = *(uint64_t *)buffer.pointer;
+		break;
+	default:
+		pr_err("%s GHID method returned buffer of unexpected length %lu\n",
+				quickstart->button->name,
+				(unsigned long)buffer.length);
+		ret = -EINVAL;
+		break;
+	}
 
 	kfree(buffer.pointer);
+
+	return ret;
 }
 
-static int quickstart_acpi_config(struct quickstart_acpi *quickstart, char *bid)
+static int quickstart_acpi_config(struct quickstart_acpi *quickstart)
 {
-	int len = strlen(bid);
-	int ret;
+	char *bid = acpi_device_bid(quickstart->device);
+	char *name;
 
-	/* Add button to list */
-	ret = quickstart_btnlst_add(&quickstart->btn);
-	if (ret)
-		return ret;
+	name = kmalloc(strlen(bid) + 1, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
 
-	quickstart->btn->name = kzalloc(len + 1, GFP_KERNEL);
-	if (!quickstart->btn->name) {
-		quickstart_btnlst_free();
+	/* Add new button to list */
+	quickstart->button = quickstart_buttons_add();
+	if (!quickstart->button) {
+		kfree(name);
 		return -ENOMEM;
 	}
-	strcpy(quickstart->btn->name, bid);
+
+	quickstart->button->name = name;
+	strcpy(quickstart->button->name, bid);
 
 	return 0;
 }
 
 static int quickstart_acpi_add(struct acpi_device *device)
 {
-	int ret = 0;
-	acpi_status status = AE_OK;
-	struct quickstart_acpi *quickstart = NULL;
+	int ret;
+	acpi_status status;
+	struct quickstart_acpi *quickstart;
 
 	if (!device)
 		return -EINVAL;
 
-	quickstart = kzalloc(sizeof(struct quickstart_acpi), GFP_KERNEL);
+	quickstart = kzalloc(sizeof(*quickstart), GFP_KERNEL);
 	if (!quickstart)
 		return -ENOMEM;
 
 	quickstart->device = device;
+
 	strcpy(acpi_device_name(device), QUICKSTART_ACPI_DEVICE_NAME);
 	strcpy(acpi_device_class(device), QUICKSTART_ACPI_CLASS);
 	device->driver_data = quickstart;
 
 	/* Add button to list and initialize some stuff */
-	ret = quickstart_acpi_config(quickstart, acpi_device_bid(device));
-	if (ret)
+	ret = quickstart_acpi_config(quickstart);
+	if (ret < 0)
 		goto fail_config;
 
-	status = acpi_install_notify_handler(device->handle,
-						ACPI_ALL_NOTIFY,
+	status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY,
 						quickstart_acpi_notify,
 						quickstart);
 	if (ACPI_FAILURE(status)) {
-		printk(KERN_ERR "quickstart: Notify handler install error\n");
+		pr_err("Notify handler install error\n");
 		ret = -ENODEV;
 		goto fail_installnotify;
 	}
 
-	quickstart_acpi_ghid(quickstart);
+	ret = quickstart_acpi_ghid(quickstart);
+	if (ret < 0)
+		goto fail_ghid;
 
 	return 0;
 
+fail_ghid:
+	acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
+						quickstart_acpi_notify);
+
 fail_installnotify:
-	quickstart_btnlst_del(quickstart->btn);
+	quickstart_button_del(quickstart->button);
 
 fail_config:
 
@@ -331,28 +298,54 @@ fail_config:
 
 static int quickstart_acpi_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = 0;
-	struct quickstart_acpi *quickstart = NULL;
+	acpi_status status;
+	struct quickstart_acpi *quickstart;
 
-	if (!device || !acpi_driver_data(device))
+	if (!device)
 		return -EINVAL;
 
 	quickstart = acpi_driver_data(device);
+	if (!quickstart)
+		return -EINVAL;
 
-	status = acpi_remove_notify_handler(device->handle,
-						 ACPI_ALL_NOTIFY,
-					    quickstart_acpi_notify);
+	status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY,
+						quickstart_acpi_notify);
 	if (ACPI_FAILURE(status))
-		printk(KERN_ERR "quickstart: Error removing notify handler\n");
-
+		pr_err("Error removing notify handler\n");
 
 	kfree(quickstart);
 
 	return 0;
 }
 
-/* Module functions */
+/* Platform driver structs */
+static DEVICE_ATTR(pressed_button, 0666, quickstart_pressed_button_show,
+					 quickstart_pressed_button_store);
+static DEVICE_ATTR(buttons, 0444, quickstart_buttons_show, NULL);
+static struct platform_device *pf_device;
+static struct platform_driver pf_driver = {
+	.driver = {
+		.name = QUICKSTART_PF_DRIVER_NAME,
+		.owner = THIS_MODULE,
+	}
+};
+
+static const struct acpi_device_id quickstart_device_ids[] = {
+	{QUICKSTART_ACPI_HID, 0},
+	{"", 0},
+};
+
+static struct acpi_driver quickstart_acpi_driver = {
+	.name = "quickstart",
+	.class = QUICKSTART_ACPI_CLASS,
+	.ids = quickstart_device_ids,
+	.ops = {
+			.add = quickstart_acpi_add,
+			.remove = quickstart_acpi_remove,
+		},
+};
 
+/* Module functions */
 static void quickstart_exit(void)
 {
 	input_unregister_device(quickstart_input);
@@ -366,15 +359,12 @@ static void quickstart_exit(void)
 
 	acpi_bus_unregister_driver(&quickstart_acpi_driver);
 
-	quickstart_btnlst_free();
-
-	return;
+	quickstart_buttons_free();
 }
 
 static int __init quickstart_init_input(void)
 {
-	struct quickstart_btn **ptr = &quickstart_data.btn_lst;
-	int count;
+	struct quickstart_button *b;
 	int ret;
 
 	quickstart_input = input_allocate_device();
@@ -385,11 +375,9 @@ static int __init quickstart_init_input(void)
 	quickstart_input->name = "Quickstart ACPI Buttons";
 	quickstart_input->id.bustype = BUS_HOST;
 
-	while (*ptr) {
-		count++;
+	list_for_each_entry(b, &buttons, list) {
 		set_bit(EV_KEY, quickstart_input->evbit);
-		set_bit((*ptr)->id, quickstart_input->keybit);
-		ptr = &((*ptr)->next);
+		set_bit(b->id, quickstart_input->keybit);
 	}
 
 	ret = input_register_device(quickstart_input);
@@ -415,7 +403,7 @@ static int __init quickstart_init(void)
 		return ret;
 
 	/* If existing bus with no devices */
-	if (!quickstart_data.btn_lst) {
+	if (list_empty(&buttons)) {
 		ret = -ENODEV;
 		goto fail_pfdrv_reg;
 	}
@@ -444,14 +432,12 @@ static int __init quickstart_init(void)
 	if (ret)
 		goto fail_dev_file2;
 
-
 	/* Input device */
 	ret = quickstart_init_input();
 	if (ret)
 		goto fail_input;
 
-	printk(KERN_INFO "quickstart: ACPI Direct App Launch ver %s\n",
-						QUICKSTART_VERSION);
+	pr_info("ACPI Direct App Launch ver %s\n", QUICKSTART_VERSION);
 
 	return 0;
 fail_input:
diff --git a/drivers/staging/ramster/Kconfig b/drivers/staging/ramster/Kconfig
new file mode 100644
index 0000000..b045704
--- /dev/null
+++ b/drivers/staging/ramster/Kconfig
@@ -0,0 +1,13 @@
+config RAMSTER
+	bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem"
+	depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS && !ZCACHE && !XVMALLOC && !HIGHMEM && BROKEN
+	select LZO_COMPRESS
+	select LZO_DECOMPRESS
+	default n
+	help
+	  RAMster allows RAM on other machines in a cluster to be utilized
+	  dynamically and symmetrically instead of swapping to a local swap
+	  disk, thus improving performance on memory-constrained workloads
+	  while minimizing total RAM across the cluster.  RAMster, like
+	  zcache, compresses swap pages into local RAM, but then remotifies
+	  the compressed pages to another node in the RAMster cluster.
diff --git a/drivers/staging/ramster/Makefile b/drivers/staging/ramster/Makefile
new file mode 100644
index 0000000..bcc13c8
--- /dev/null
+++ b/drivers/staging/ramster/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_RAMSTER)	+=	zcache-main.o tmem.o r2net.o xvmalloc.o cluster/
diff --git a/drivers/staging/ramster/TODO b/drivers/staging/ramster/TODO
new file mode 100644
index 0000000..46fcf0c
--- /dev/null
+++ b/drivers/staging/ramster/TODO
@@ -0,0 +1,13 @@
+For this staging driver, RAMster duplicates code from drivers/staging/zcache
+then incorporates changes to the local copy of the code.  For V5, it also
+directly incorporates the soon-to-be-removed drivers/staging/zram/xvmalloc.[ch]
+as all testing has been done with xvmalloc rather than the new zsmalloc.
+Before RAMster can be promoted from staging, the zcache and RAMster drivers
+should be either merged or reorganized to separate out common code.
+
+Until V4, RAMster duplicated code from fs/ocfs2/cluster, but this made
+RAMster incompatible with ocfs2 running in the same kernel and included
+lots of code that could be removed.  As of V5, the ocfs2 code has been
+mined and made RAMster-specific, made to communicate with a userland
+ramster-tools package rather than ocfs2-tools, and can co-exist with ocfs2
+both in the same kernel and in userland on the same machine.
diff --git a/drivers/staging/ramster/cluster/Makefile b/drivers/staging/ramster/cluster/Makefile
new file mode 100644
index 0000000..9c69436
--- /dev/null
+++ b/drivers/staging/ramster/cluster/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_RAMSTER) += ramster_nodemanager.o
+
+ramster_nodemanager-objs := heartbeat.o masklog.o nodemanager.o tcp.o
diff --git a/drivers/staging/ramster/cluster/heartbeat.c b/drivers/staging/ramster/cluster/heartbeat.c
new file mode 100644
index 0000000..0020949
--- /dev/null
+++ b/drivers/staging/ramster/cluster/heartbeat.c
@@ -0,0 +1,464 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004, 2005, 2012 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/configfs.h>
+
+#include "heartbeat.h"
+#include "tcp.h"
+#include "nodemanager.h"
+
+#include "masklog.h"
+
+/*
+ * The first heartbeat pass had one global thread that would serialize all hb
+ * callback calls.  This global serializing sem should only be removed once
+ * we've made sure that all callees can deal with being called concurrently
+ * from multiple hb region threads.
+ */
+static DECLARE_RWSEM(r2hb_callback_sem);
+
+/*
+ * multiple hb threads are watching multiple regions.  A node is live
+ * whenever any of the threads sees activity from the node in its region.
+ */
+static DEFINE_SPINLOCK(r2hb_live_lock);
+static unsigned long r2hb_live_node_bitmap[BITS_TO_LONGS(R2NM_MAX_NODES)];
+
+static struct r2hb_callback {
+	struct list_head list;
+} r2hb_callbacks[R2HB_NUM_CB];
+
+enum r2hb_heartbeat_modes {
+	R2HB_HEARTBEAT_LOCAL		= 0,
+	R2HB_HEARTBEAT_GLOBAL,
+	R2HB_HEARTBEAT_NUM_MODES,
+};
+
+char *r2hb_heartbeat_mode_desc[R2HB_HEARTBEAT_NUM_MODES] = {
+		"local",	/* R2HB_HEARTBEAT_LOCAL */
+		"global",	/* R2HB_HEARTBEAT_GLOBAL */
+};
+
+unsigned int r2hb_dead_threshold = R2HB_DEFAULT_DEAD_THRESHOLD;
+unsigned int r2hb_heartbeat_mode = R2HB_HEARTBEAT_LOCAL;
+
+/* Only sets a new threshold if there are no active regions.
+ *
+ * No locking or otherwise interesting code is required for reading
+ * r2hb_dead_threshold as it can't change once regions are active and
+ * it's not interesting to anyone until then anyway. */
+static void r2hb_dead_threshold_set(unsigned int threshold)
+{
+	if (threshold > R2HB_MIN_DEAD_THRESHOLD) {
+		spin_lock(&r2hb_live_lock);
+		r2hb_dead_threshold = threshold;
+		spin_unlock(&r2hb_live_lock);
+	}
+}
+
+static int r2hb_global_hearbeat_mode_set(unsigned int hb_mode)
+{
+	int ret = -1;
+
+	if (hb_mode < R2HB_HEARTBEAT_NUM_MODES) {
+		spin_lock(&r2hb_live_lock);
+		r2hb_heartbeat_mode = hb_mode;
+		ret = 0;
+		spin_unlock(&r2hb_live_lock);
+	}
+
+	return ret;
+}
+
+void r2hb_exit(void)
+{
+}
+
+int r2hb_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(r2hb_callbacks); i++)
+		INIT_LIST_HEAD(&r2hb_callbacks[i].list);
+
+	memset(r2hb_live_node_bitmap, 0, sizeof(r2hb_live_node_bitmap));
+
+	return 0;
+}
+
+/* if we're already in a callback then we're already serialized by the sem */
+static void r2hb_fill_node_map_from_callback(unsigned long *map,
+					     unsigned bytes)
+{
+	BUG_ON(bytes < (BITS_TO_LONGS(R2NM_MAX_NODES) * sizeof(unsigned long)));
+
+	memcpy(map, &r2hb_live_node_bitmap, bytes);
+}
+
+/*
+ * get a map of all nodes that are heartbeating in any regions
+ */
+void r2hb_fill_node_map(unsigned long *map, unsigned bytes)
+{
+	/* callers want to serialize this map and callbacks so that they
+	 * can trust that they don't miss nodes coming to the party */
+	down_read(&r2hb_callback_sem);
+	spin_lock(&r2hb_live_lock);
+	r2hb_fill_node_map_from_callback(map, bytes);
+	spin_unlock(&r2hb_live_lock);
+	up_read(&r2hb_callback_sem);
+}
+EXPORT_SYMBOL_GPL(r2hb_fill_node_map);
+
+/*
+ * heartbeat configfs bits.  The heartbeat set is a default set under
+ * the cluster set in nodemanager.c.
+ */
+
+/* heartbeat set */
+
+struct r2hb_hb_group {
+	struct config_group hs_group;
+	/* some stuff? */
+};
+
+static struct r2hb_hb_group *to_r2hb_hb_group(struct config_group *group)
+{
+	return group ?
+		container_of(group, struct r2hb_hb_group, hs_group)
+		: NULL;
+}
+
+static struct config_item r2hb_config_item;
+
+static struct config_item *r2hb_hb_group_make_item(struct config_group *group,
+							  const char *name)
+{
+	int ret;
+
+	if (strlen(name) > R2HB_MAX_REGION_NAME_LEN) {
+		ret = -ENAMETOOLONG;
+		goto free;
+	}
+
+	config_item_put(&r2hb_config_item);
+
+	return &r2hb_config_item;
+free:
+	return ERR_PTR(ret);
+}
+
+static void r2hb_hb_group_drop_item(struct config_group *group,
+					   struct config_item *item)
+{
+	if (r2hb_global_heartbeat_active()) {
+		printk(KERN_NOTICE "ramster: Heartbeat %s "
+			"on region %s (%s)\n",
+			"stopped/aborted", config_item_name(item),
+			"no region");
+	}
+
+	config_item_put(item);
+}
+
+struct r2hb_hb_group_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct r2hb_hb_group *, char *);
+	ssize_t (*store)(struct r2hb_hb_group *, const char *, size_t);
+};
+
+static ssize_t r2hb_hb_group_show(struct config_item *item,
+					 struct configfs_attribute *attr,
+					 char *page)
+{
+	struct r2hb_hb_group *reg = to_r2hb_hb_group(to_config_group(item));
+	struct r2hb_hb_group_attribute *r2hb_hb_group_attr =
+		container_of(attr, struct r2hb_hb_group_attribute, attr);
+	ssize_t ret = 0;
+
+	if (r2hb_hb_group_attr->show)
+		ret = r2hb_hb_group_attr->show(reg, page);
+	return ret;
+}
+
+static ssize_t r2hb_hb_group_store(struct config_item *item,
+					  struct configfs_attribute *attr,
+					  const char *page, size_t count)
+{
+	struct r2hb_hb_group *reg = to_r2hb_hb_group(to_config_group(item));
+	struct r2hb_hb_group_attribute *r2hb_hb_group_attr =
+		container_of(attr, struct r2hb_hb_group_attribute, attr);
+	ssize_t ret = -EINVAL;
+
+	if (r2hb_hb_group_attr->store)
+		ret = r2hb_hb_group_attr->store(reg, page, count);
+	return ret;
+}
+
+static ssize_t r2hb_hb_group_threshold_show(struct r2hb_hb_group *group,
+						     char *page)
+{
+	return sprintf(page, "%u\n", r2hb_dead_threshold);
+}
+
+static ssize_t r2hb_hb_group_threshold_store(struct r2hb_hb_group *group,
+						    const char *page,
+						    size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *)page;
+	int err;
+
+	err = kstrtoul(p, 10, &tmp);
+	if (err)
+		return err;
+
+	/* this will validate ranges for us. */
+	r2hb_dead_threshold_set((unsigned int) tmp);
+
+	return count;
+}
+
+static
+ssize_t r2hb_hb_group_mode_show(struct r2hb_hb_group *group,
+				       char *page)
+{
+	return sprintf(page, "%s\n",
+		       r2hb_heartbeat_mode_desc[r2hb_heartbeat_mode]);
+}
+
+static
+ssize_t r2hb_hb_group_mode_store(struct r2hb_hb_group *group,
+					const char *page, size_t count)
+{
+	unsigned int i;
+	int ret;
+	size_t len;
+
+	len = (page[count - 1] == '\n') ? count - 1 : count;
+	if (!len)
+		return -EINVAL;
+
+	for (i = 0; i < R2HB_HEARTBEAT_NUM_MODES; ++i) {
+		if (strnicmp(page, r2hb_heartbeat_mode_desc[i], len))
+			continue;
+
+		ret = r2hb_global_hearbeat_mode_set(i);
+		if (!ret)
+			printk(KERN_NOTICE "ramster: Heartbeat mode "
+						"set to %s\n",
+			       r2hb_heartbeat_mode_desc[i]);
+		return count;
+	}
+
+	return -EINVAL;
+
+}
+
+static struct r2hb_hb_group_attribute r2hb_hb_group_attr_threshold = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "dead_threshold",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2hb_hb_group_threshold_show,
+	.store	= r2hb_hb_group_threshold_store,
+};
+
+static struct r2hb_hb_group_attribute r2hb_hb_group_attr_mode = {
+	.attr   = { .ca_owner = THIS_MODULE,
+		.ca_name = "mode",
+		.ca_mode = S_IRUGO | S_IWUSR },
+	.show   = r2hb_hb_group_mode_show,
+	.store  = r2hb_hb_group_mode_store,
+};
+
+static struct configfs_attribute *r2hb_hb_group_attrs[] = {
+	&r2hb_hb_group_attr_threshold.attr,
+	&r2hb_hb_group_attr_mode.attr,
+	NULL,
+};
+
+static struct configfs_item_operations r2hb_hearbeat_group_item_ops = {
+	.show_attribute		= r2hb_hb_group_show,
+	.store_attribute	= r2hb_hb_group_store,
+};
+
+static struct configfs_group_operations r2hb_hb_group_group_ops = {
+	.make_item	= r2hb_hb_group_make_item,
+	.drop_item	= r2hb_hb_group_drop_item,
+};
+
+static struct config_item_type r2hb_hb_group_type = {
+	.ct_group_ops	= &r2hb_hb_group_group_ops,
+	.ct_item_ops	= &r2hb_hearbeat_group_item_ops,
+	.ct_attrs	= r2hb_hb_group_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* this is just here to avoid touching group in heartbeat.h which the
+ * entire damn world #includes */
+struct config_group *r2hb_alloc_hb_set(void)
+{
+	struct r2hb_hb_group *hs = NULL;
+	struct config_group *ret = NULL;
+
+	hs = kzalloc(sizeof(struct r2hb_hb_group), GFP_KERNEL);
+	if (hs == NULL)
+		goto out;
+
+	config_group_init_type_name(&hs->hs_group, "heartbeat",
+				    &r2hb_hb_group_type);
+
+	ret = &hs->hs_group;
+out:
+	if (ret == NULL)
+		kfree(hs);
+	return ret;
+}
+
+void r2hb_free_hb_set(struct config_group *group)
+{
+	struct r2hb_hb_group *hs = to_r2hb_hb_group(group);
+	kfree(hs);
+}
+
+/* hb callback registration and issuing */
+
+static struct r2hb_callback *hbcall_from_type(enum r2hb_callback_type type)
+{
+	if (type == R2HB_NUM_CB)
+		return ERR_PTR(-EINVAL);
+
+	return &r2hb_callbacks[type];
+}
+
+void r2hb_setup_callback(struct r2hb_callback_func *hc,
+			 enum r2hb_callback_type type,
+			 r2hb_cb_func *func,
+			 void *data,
+			 int priority)
+{
+	INIT_LIST_HEAD(&hc->hc_item);
+	hc->hc_func = func;
+	hc->hc_data = data;
+	hc->hc_priority = priority;
+	hc->hc_type = type;
+	hc->hc_magic = R2HB_CB_MAGIC;
+}
+EXPORT_SYMBOL_GPL(r2hb_setup_callback);
+
+int r2hb_register_callback(const char *region_uuid,
+			   struct r2hb_callback_func *hc)
+{
+	struct r2hb_callback_func *tmp;
+	struct list_head *iter;
+	struct r2hb_callback *hbcall;
+	int ret;
+
+	BUG_ON(hc->hc_magic != R2HB_CB_MAGIC);
+	BUG_ON(!list_empty(&hc->hc_item));
+
+	hbcall = hbcall_from_type(hc->hc_type);
+	if (IS_ERR(hbcall)) {
+		ret = PTR_ERR(hbcall);
+		goto out;
+	}
+
+	down_write(&r2hb_callback_sem);
+
+	list_for_each(iter, &hbcall->list) {
+		tmp = list_entry(iter, struct r2hb_callback_func, hc_item);
+		if (hc->hc_priority < tmp->hc_priority) {
+			list_add_tail(&hc->hc_item, iter);
+			break;
+		}
+	}
+	if (list_empty(&hc->hc_item))
+		list_add_tail(&hc->hc_item, &hbcall->list);
+
+	up_write(&r2hb_callback_sem);
+	ret = 0;
+out:
+	mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n",
+	     ret, __builtin_return_address(0), hc);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(r2hb_register_callback);
+
+void r2hb_unregister_callback(const char *region_uuid,
+			      struct r2hb_callback_func *hc)
+{
+	BUG_ON(hc->hc_magic != R2HB_CB_MAGIC);
+
+	mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n",
+	     __builtin_return_address(0), hc);
+
+	/* XXX Can this happen _with_ a region reference? */
+	if (list_empty(&hc->hc_item))
+		return;
+
+	down_write(&r2hb_callback_sem);
+
+	list_del_init(&hc->hc_item);
+
+	up_write(&r2hb_callback_sem);
+}
+EXPORT_SYMBOL_GPL(r2hb_unregister_callback);
+
+int r2hb_check_node_heartbeating_from_callback(u8 node_num)
+{
+	unsigned long testing_map[BITS_TO_LONGS(R2NM_MAX_NODES)];
+
+	r2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map));
+	if (!test_bit(node_num, testing_map)) {
+		mlog(ML_HEARTBEAT,
+		     "node (%u) does not have heartbeating enabled.\n",
+		     node_num);
+		return 0;
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(r2hb_check_node_heartbeating_from_callback);
+
+void r2hb_stop_all_regions(void)
+{
+}
+EXPORT_SYMBOL_GPL(r2hb_stop_all_regions);
+
+/*
+ * this is just a hack until we get the plumbing which flips file systems
+ * read only and drops the hb ref instead of killing the node dead.
+ */
+int r2hb_global_heartbeat_active(void)
+{
+	return (r2hb_heartbeat_mode == R2HB_HEARTBEAT_GLOBAL);
+}
+EXPORT_SYMBOL(r2hb_global_heartbeat_active);
+
+/* added for RAMster */
+void r2hb_manual_set_node_heartbeating(int node_num)
+{
+	if (node_num < R2NM_MAX_NODES)
+		set_bit(node_num, r2hb_live_node_bitmap);
+}
+EXPORT_SYMBOL(r2hb_manual_set_node_heartbeating);
diff --git a/drivers/staging/ramster/cluster/heartbeat.h b/drivers/staging/ramster/cluster/heartbeat.h
new file mode 100644
index 0000000..6cbc775
--- /dev/null
+++ b/drivers/staging/ramster/cluster/heartbeat.h
@@ -0,0 +1,87 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * heartbeat.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef R2CLUSTER_HEARTBEAT_H
+#define R2CLUSTER_HEARTBEAT_H
+
+#define R2HB_REGION_TIMEOUT_MS		2000
+
+#define R2HB_MAX_REGION_NAME_LEN	32
+
+/* number of changes to be seen as live */
+#define R2HB_LIVE_THRESHOLD	   2
+/* number of equal samples to be seen as dead */
+extern unsigned int r2hb_dead_threshold;
+#define R2HB_DEFAULT_DEAD_THRESHOLD	   31
+/* Otherwise MAX_WRITE_TIMEOUT will be zero... */
+#define R2HB_MIN_DEAD_THRESHOLD	  2
+#define R2HB_MAX_WRITE_TIMEOUT_MS \
+	(R2HB_REGION_TIMEOUT_MS * (r2hb_dead_threshold - 1))
+
+#define R2HB_CB_MAGIC		0x51d1e4ec
+
+/* callback stuff */
+enum r2hb_callback_type {
+	R2HB_NODE_DOWN_CB = 0,
+	R2HB_NODE_UP_CB,
+	R2HB_NUM_CB
+};
+
+struct r2nm_node;
+typedef void (r2hb_cb_func)(struct r2nm_node *, int, void *);
+
+struct r2hb_callback_func {
+	u32			hc_magic;
+	struct list_head	hc_item;
+	r2hb_cb_func		*hc_func;
+	void			*hc_data;
+	int			hc_priority;
+	enum r2hb_callback_type hc_type;
+};
+
+struct config_group *r2hb_alloc_hb_set(void);
+void r2hb_free_hb_set(struct config_group *group);
+
+void r2hb_setup_callback(struct r2hb_callback_func *hc,
+			 enum r2hb_callback_type type,
+			 r2hb_cb_func *func,
+			 void *data,
+			 int priority);
+int r2hb_register_callback(const char *region_uuid,
+			   struct r2hb_callback_func *hc);
+void r2hb_unregister_callback(const char *region_uuid,
+			      struct r2hb_callback_func *hc);
+void r2hb_fill_node_map(unsigned long *map,
+			unsigned bytes);
+void r2hb_exit(void);
+int r2hb_init(void);
+int r2hb_check_node_heartbeating_from_callback(u8 node_num);
+void r2hb_stop_all_regions(void);
+int r2hb_get_all_regions(char *region_uuids, u8 numregions);
+int r2hb_global_heartbeat_active(void);
+void r2hb_manual_set_node_heartbeating(int);
+
+#endif /* R2CLUSTER_HEARTBEAT_H */
diff --git a/drivers/staging/ramster/cluster/masklog.c b/drivers/staging/ramster/cluster/masklog.c
new file mode 100644
index 0000000..c2af3c7
--- /dev/null
+++ b/drivers/staging/ramster/cluster/masklog.c
@@ -0,0 +1,155 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004, 2005, 2012 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+
+#include "masklog.h"
+
+struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK);
+EXPORT_SYMBOL_GPL(mlog_and_bits);
+struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0);
+EXPORT_SYMBOL_GPL(mlog_not_bits);
+
+static ssize_t mlog_mask_show(u64 mask, char *buf)
+{
+	char *state;
+
+	if (__mlog_test_u64(mask, mlog_and_bits))
+		state = "allow";
+	else if (__mlog_test_u64(mask, mlog_not_bits))
+		state = "deny";
+	else
+		state = "off";
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", state);
+}
+
+static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
+{
+	if (!strnicmp(buf, "allow", 5)) {
+		__mlog_set_u64(mask, mlog_and_bits);
+		__mlog_clear_u64(mask, mlog_not_bits);
+	} else if (!strnicmp(buf, "deny", 4)) {
+		__mlog_set_u64(mask, mlog_not_bits);
+		__mlog_clear_u64(mask, mlog_and_bits);
+	} else if (!strnicmp(buf, "off", 3)) {
+		__mlog_clear_u64(mask, mlog_not_bits);
+		__mlog_clear_u64(mask, mlog_and_bits);
+	} else
+		return -EINVAL;
+
+	return count;
+}
+
+struct mlog_attribute {
+	struct attribute attr;
+	u64 mask;
+};
+
+#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr)
+
+#define define_mask(_name) {			\
+	.attr = {				\
+		.name = #_name,			\
+		.mode = S_IRUGO | S_IWUSR,	\
+	},					\
+	.mask = ML_##_name,			\
+}
+
+static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
+	define_mask(TCP),
+	define_mask(MSG),
+	define_mask(SOCKET),
+	define_mask(HEARTBEAT),
+	define_mask(HB_BIO),
+	define_mask(DLMFS),
+	define_mask(DLM),
+	define_mask(DLM_DOMAIN),
+	define_mask(DLM_THREAD),
+	define_mask(DLM_MASTER),
+	define_mask(DLM_RECOVERY),
+	define_mask(DLM_GLUE),
+	define_mask(VOTE),
+	define_mask(CONN),
+	define_mask(QUORUM),
+	define_mask(BASTS),
+	define_mask(CLUSTER),
+	define_mask(ERROR),
+	define_mask(NOTICE),
+	define_mask(KTHREAD),
+};
+
+static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, };
+
+static ssize_t mlog_show(struct kobject *obj, struct attribute *attr,
+			 char *buf)
+{
+	struct mlog_attribute *mlog_attr = to_mlog_attr(attr);
+
+	return mlog_mask_show(mlog_attr->mask, buf);
+}
+
+static ssize_t mlog_store(struct kobject *obj, struct attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct mlog_attribute *mlog_attr = to_mlog_attr(attr);
+
+	return mlog_mask_store(mlog_attr->mask, buf, count);
+}
+
+static const struct sysfs_ops mlog_attr_ops = {
+	.show  = mlog_show,
+	.store = mlog_store,
+};
+
+static struct kobj_type mlog_ktype = {
+	.default_attrs = mlog_attr_ptrs,
+	.sysfs_ops     = &mlog_attr_ops,
+};
+
+static struct kset mlog_kset = {
+	.kobj   = {.ktype = &mlog_ktype},
+};
+
+int mlog_sys_init(struct kset *r2cb_kset)
+{
+	int i = 0;
+
+	while (mlog_attrs[i].attr.mode) {
+		mlog_attr_ptrs[i] = &mlog_attrs[i].attr;
+		i++;
+	}
+	mlog_attr_ptrs[i] = NULL;
+
+	kobject_set_name(&mlog_kset.kobj, "logmask");
+	mlog_kset.kobj.kset = r2cb_kset;
+	return kset_register(&mlog_kset);
+}
+
+void mlog_sys_shutdown(void)
+{
+	kset_unregister(&mlog_kset);
+}
diff --git a/drivers/staging/ramster/cluster/masklog.h b/drivers/staging/ramster/cluster/masklog.h
new file mode 100644
index 0000000..7609e66
--- /dev/null
+++ b/drivers/staging/ramster/cluster/masklog.h
@@ -0,0 +1,220 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005, 2012 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef R2CLUSTER_MASKLOG_H
+#define R2CLUSTER_MASKLOG_H
+
+/*
+ * For now this is a trivial wrapper around printk() that gives the critical
+ * ability to enable sets of debugging output at run-time.  In the future this
+ * will almost certainly be redirected to relayfs so that it can pay a
+ * substantially lower heisenberg tax.
+ *
+ * Callers associate the message with a bitmask and a global bitmask is
+ * maintained with help from /proc.  If any of the bits match the message is
+ * output.
+ *
+ * We must have efficient bit tests on i386 and it seems gcc still emits crazy
+ * code for the 64bit compare.  It emits very good code for the dual unsigned
+ * long tests, though, completely avoiding tests that can never pass if the
+ * caller gives a constant bitmask that fills one of the longs with all 0s.  So
+ * the desire is to have almost all of the calls decided on by comparing just
+ * one of the longs.  This leads to having infrequently given bits that are
+ * frequently matched in the high bits.
+ *
+ * _ERROR and _NOTICE are used for messages that always go to the console and
+ * have appropriate KERN_ prefixes.  We wrap these in our function instead of
+ * just calling printk() so that this can eventually make its way through
+ * relayfs along with the debugging messages.  Everything else gets KERN_DEBUG.
+ * The inline tests and macro dance give GCC the opportunity to quite cleverly
+ * only emit the appropriage printk() when the caller passes in a constant
+ * mask, as is almost always the case.
+ *
+ * All this bitmask nonsense is managed from the files under
+ * /sys/fs/r2cb/logmask/.  Reading the files gives a straightforward
+ * indication of which bits are allowed (allow) or denied (off/deny).
+ *	ENTRY deny
+ *	EXIT deny
+ *	TCP off
+ *	MSG off
+ *	SOCKET off
+ *	ERROR allow
+ *	NOTICE allow
+ *
+ * Writing changes the state of a given bit and requires a strictly formatted
+ * single write() call:
+ *
+ *	write(fd, "allow", 5);
+ *
+ * Echoing allow/deny/off string into the logmask files can flip the bits
+ * on or off as expected; here is the bash script for example:
+ *
+ * log_mask="/sys/fs/r2cb/log_mask"
+ * for node in ENTRY EXIT TCP MSG SOCKET ERROR NOTICE; do
+ *	echo allow >"$log_mask"/"$node"
+ * done
+ *
+ * The debugfs.ramster tool can also flip the bits with the -l option:
+ *
+ * debugfs.ramster -l TCP allow
+ */
+
+/* for task_struct */
+#include <linux/sched.h>
+
+/* bits that are frequently given and infrequently matched in the low word */
+/* NOTE: If you add a flag, you need to also update masklog.c! */
+#define ML_TCP		0x0000000000000001ULL /* net cluster/tcp.c */
+#define ML_MSG		0x0000000000000002ULL /* net network messages */
+#define ML_SOCKET	0x0000000000000004ULL /* net socket lifetime */
+#define ML_HEARTBEAT	0x0000000000000008ULL /* hb all heartbeat tracking */
+#define ML_HB_BIO	0x0000000000000010ULL /* hb io tracing */
+#define ML_DLMFS	0x0000000000000020ULL /* dlm user dlmfs */
+#define ML_DLM		0x0000000000000040ULL /* dlm general debugging */
+#define ML_DLM_DOMAIN	0x0000000000000080ULL /* dlm domain debugging */
+#define ML_DLM_THREAD	0x0000000000000100ULL /* dlm domain thread */
+#define ML_DLM_MASTER	0x0000000000000200ULL /* dlm master functions */
+#define ML_DLM_RECOVERY	0x0000000000000400ULL /* dlm master functions */
+#define ML_DLM_GLUE	0x0000000000000800ULL /* ramster dlm glue layer */
+#define ML_VOTE		0x0000000000001000ULL /* ramster node messaging  */
+#define ML_CONN		0x0000000000002000ULL /* net connection management */
+#define ML_QUORUM	0x0000000000004000ULL /* net connection quorum */
+#define ML_BASTS	0x0000000000008000ULL /* dlmglue asts and basts */
+#define ML_CLUSTER	0x0000000000010000ULL /* cluster stack */
+
+/* bits that are infrequently given and frequently matched in the high word */
+#define ML_ERROR	0x1000000000000000ULL /* sent to KERN_ERR */
+#define ML_NOTICE	0x2000000000000000ULL /* setn to KERN_NOTICE */
+#define ML_KTHREAD	0x4000000000000000ULL /* kernel thread activity */
+
+#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
+#ifndef MLOG_MASK_PREFIX
+#define MLOG_MASK_PREFIX 0
+#endif
+
+/*
+ * When logging is disabled, force the bit test to 0 for anything other
+ * than errors and notices, allowing gcc to remove the code completely.
+ * When enabled, allow all masks.
+ */
+#if defined(CONFIG_RAMSTER_DEBUG_MASKLOG)
+#define ML_ALLOWED_BITS (~0)
+#else
+#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE)
+#endif
+
+#define MLOG_MAX_BITS 64
+
+struct mlog_bits {
+	unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG];
+};
+
+extern struct mlog_bits mlog_and_bits, mlog_not_bits;
+
+#if BITS_PER_LONG == 32
+
+#define __mlog_test_u64(mask, bits)			\
+	((u32)(mask & 0xffffffff) & bits.words[0] ||	\
+	  ((u64)(mask) >> 32) & bits.words[1])
+#define __mlog_set_u64(mask, bits) do {			\
+	bits.words[0] |= (u32)(mask & 0xffffffff);	\
+	bits.words[1] |= (u64)(mask) >> 32;		\
+} while (0)
+#define __mlog_clear_u64(mask, bits) do {		\
+	bits.words[0] &= ~((u32)(mask & 0xffffffff));	\
+	bits.words[1] &= ~((u64)(mask) >> 32);		\
+} while (0)
+#define MLOG_BITS_RHS(mask) {				\
+	{						\
+		[0] = (u32)(mask & 0xffffffff),		\
+		[1] = (u64)(mask) >> 32,		\
+	}						\
+}
+
+#else /* 32bit long above, 64bit long below */
+
+#define __mlog_test_u64(mask, bits)	((mask) & bits.words[0])
+#define __mlog_set_u64(mask, bits) do {		\
+	bits.words[0] |= (mask);		\
+} while (0)
+#define __mlog_clear_u64(mask, bits) do {	\
+	bits.words[0] &= ~(mask);		\
+} while (0)
+#define MLOG_BITS_RHS(mask) { { (mask) } }
+
+#endif
+
+/*
+ * smp_processor_id() "helpfully" screams when called outside preemptible
+ * regions in current kernels.  sles doesn't have the variants that don't
+ * scream.  just do this instead of trying to guess which we're building
+ * against.. *sigh*.
+ */
+#define __mlog_cpu_guess ({		\
+	unsigned long _cpu = get_cpu();	\
+	put_cpu();			\
+	_cpu;				\
+})
+
+/* In the following two macros, the whitespace after the ',' just
+ * before ##args is intentional. Otherwise, gcc 2.95 will eat the
+ * previous token if args expands to nothing.
+ */
+#define __mlog_printk(level, fmt, args...)				\
+	printk(level "(%s,%u,%lu):%s:%d " fmt, current->comm,		\
+	       task_pid_nr(current), __mlog_cpu_guess,			\
+	       __PRETTY_FUNCTION__, __LINE__ , ##args)
+
+#define mlog(mask, fmt, args...) do {					\
+	u64 __m = MLOG_MASK_PREFIX | (mask);				\
+	if ((__m & ML_ALLOWED_BITS) &&					\
+	    __mlog_test_u64(__m, mlog_and_bits) &&			\
+	    !__mlog_test_u64(__m, mlog_not_bits)) {			\
+		if (__m & ML_ERROR)					\
+			__mlog_printk(KERN_ERR, "ERROR: "fmt , ##args);	\
+		else if (__m & ML_NOTICE)				\
+			__mlog_printk(KERN_NOTICE, fmt , ##args);	\
+		else							\
+			__mlog_printk(KERN_INFO, fmt , ##args);		\
+	}								\
+} while (0)
+
+#define mlog_errno(st) do {						\
+	int _st = (st);							\
+	if (_st != -ERESTARTSYS && _st != -EINTR &&			\
+	    _st != AOP_TRUNCATED_PAGE && _st != -ENOSPC)		\
+		mlog(ML_ERROR, "status = %lld\n", (long long)_st);	\
+} while (0)
+
+#define mlog_bug_on_msg(cond, fmt, args...) do {			\
+	if (cond) {							\
+		mlog(ML_ERROR, "bug expression: " #cond "\n");		\
+		mlog(ML_ERROR, fmt, ##args);				\
+		BUG();							\
+	}								\
+} while (0)
+
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+int mlog_sys_init(struct kset *r2cb_subsys);
+void mlog_sys_shutdown(void);
+
+#endif /* R2CLUSTER_MASKLOG_H */
diff --git a/drivers/staging/ramster/cluster/nodemanager.c b/drivers/staging/ramster/cluster/nodemanager.c
new file mode 100644
index 0000000..de0e5c8
--- /dev/null
+++ b/drivers/staging/ramster/cluster/nodemanager.c
@@ -0,0 +1,992 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004, 2005, 2012 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/configfs.h>
+
+#include "tcp.h"
+#include "nodemanager.h"
+#include "heartbeat.h"
+#include "masklog.h"
+
+/* for now we operate under the assertion that there can be only one
+ * cluster active at a time.  Changing this will require trickling
+ * cluster references throughout where nodes are looked up */
+struct r2nm_cluster *r2nm_single_cluster;
+
+char *r2nm_fence_method_desc[R2NM_FENCE_METHODS] = {
+		"reset",	/* R2NM_FENCE_RESET */
+		"panic",	/* R2NM_FENCE_PANIC */
+};
+
+struct r2nm_node *r2nm_get_node_by_num(u8 node_num)
+{
+	struct r2nm_node *node = NULL;
+
+	if (node_num >= R2NM_MAX_NODES || r2nm_single_cluster == NULL)
+		goto out;
+
+	read_lock(&r2nm_single_cluster->cl_nodes_lock);
+	node = r2nm_single_cluster->cl_nodes[node_num];
+	if (node)
+		config_item_get(&node->nd_item);
+	read_unlock(&r2nm_single_cluster->cl_nodes_lock);
+out:
+	return node;
+}
+EXPORT_SYMBOL_GPL(r2nm_get_node_by_num);
+
+int r2nm_configured_node_map(unsigned long *map, unsigned bytes)
+{
+	struct r2nm_cluster *cluster = r2nm_single_cluster;
+
+	BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap)));
+
+	if (cluster == NULL)
+		return -EINVAL;
+
+	read_lock(&cluster->cl_nodes_lock);
+	memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap));
+	read_unlock(&cluster->cl_nodes_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(r2nm_configured_node_map);
+
+static struct r2nm_node *r2nm_node_ip_tree_lookup(struct r2nm_cluster *cluster,
+						  __be32 ip_needle,
+						  struct rb_node ***ret_p,
+						  struct rb_node **ret_parent)
+{
+	struct rb_node **p = &cluster->cl_node_ip_tree.rb_node;
+	struct rb_node *parent = NULL;
+	struct r2nm_node *node, *ret = NULL;
+
+	while (*p) {
+		int cmp;
+
+		parent = *p;
+		node = rb_entry(parent, struct r2nm_node, nd_ip_node);
+
+		cmp = memcmp(&ip_needle, &node->nd_ipv4_address,
+				sizeof(ip_needle));
+		if (cmp < 0)
+			p = &(*p)->rb_left;
+		else if (cmp > 0)
+			p = &(*p)->rb_right;
+		else {
+			ret = node;
+			break;
+		}
+	}
+
+	if (ret_p != NULL)
+		*ret_p = p;
+	if (ret_parent != NULL)
+		*ret_parent = parent;
+
+	return ret;
+}
+
+struct r2nm_node *r2nm_get_node_by_ip(__be32 addr)
+{
+	struct r2nm_node *node = NULL;
+	struct r2nm_cluster *cluster = r2nm_single_cluster;
+
+	if (cluster == NULL)
+		goto out;
+
+	read_lock(&cluster->cl_nodes_lock);
+	node = r2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL);
+	if (node)
+		config_item_get(&node->nd_item);
+	read_unlock(&cluster->cl_nodes_lock);
+
+out:
+	return node;
+}
+EXPORT_SYMBOL_GPL(r2nm_get_node_by_ip);
+
+void r2nm_node_put(struct r2nm_node *node)
+{
+	config_item_put(&node->nd_item);
+}
+EXPORT_SYMBOL_GPL(r2nm_node_put);
+
+void r2nm_node_get(struct r2nm_node *node)
+{
+	config_item_get(&node->nd_item);
+}
+EXPORT_SYMBOL_GPL(r2nm_node_get);
+
+u8 r2nm_this_node(void)
+{
+	u8 node_num = R2NM_MAX_NODES;
+
+	if (r2nm_single_cluster && r2nm_single_cluster->cl_has_local)
+		node_num = r2nm_single_cluster->cl_local_node;
+
+	return node_num;
+}
+EXPORT_SYMBOL_GPL(r2nm_this_node);
+
+/* node configfs bits */
+
+static struct r2nm_cluster *to_r2nm_cluster(struct config_item *item)
+{
+	return item ?
+		container_of(to_config_group(item), struct r2nm_cluster,
+			     cl_group)
+		: NULL;
+}
+
+static struct r2nm_node *to_r2nm_node(struct config_item *item)
+{
+	return item ? container_of(item, struct r2nm_node, nd_item) : NULL;
+}
+
+static void r2nm_node_release(struct config_item *item)
+{
+	struct r2nm_node *node = to_r2nm_node(item);
+	kfree(node);
+}
+
+static ssize_t r2nm_node_num_read(struct r2nm_node *node, char *page)
+{
+	return sprintf(page, "%d\n", node->nd_num);
+}
+
+static struct r2nm_cluster *to_r2nm_cluster_from_node(struct r2nm_node *node)
+{
+	/* through the first node_set .parent
+	 * mycluster/nodes/mynode == r2nm_cluster->r2nm_node_group->r2nm_node */
+	return to_r2nm_cluster(node->nd_item.ci_parent->ci_parent);
+}
+
+enum {
+	R2NM_NODE_ATTR_NUM = 0,
+	R2NM_NODE_ATTR_PORT,
+	R2NM_NODE_ATTR_ADDRESS,
+	R2NM_NODE_ATTR_LOCAL,
+};
+
+static ssize_t r2nm_node_num_write(struct r2nm_node *node, const char *page,
+				   size_t count)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node);
+	unsigned long tmp;
+	char *p = (char *)page;
+	int err;
+
+	err = kstrtoul(p, 10, &tmp);
+	if (err)
+		return err;
+
+	if (tmp >= R2NM_MAX_NODES)
+		return -ERANGE;
+
+	/* once we're in the cl_nodes tree networking can look us up by
+	 * node number and try to use our address and port attributes
+	 * to connect to this node.. make sure that they've been set
+	 * before writing the node attribute? */
+	if (!test_bit(R2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
+	    !test_bit(R2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+		return -EINVAL; /* XXX */
+
+	write_lock(&cluster->cl_nodes_lock);
+	if (cluster->cl_nodes[tmp])
+		p = NULL;
+	else  {
+		cluster->cl_nodes[tmp] = node;
+		node->nd_num = tmp;
+		set_bit(tmp, cluster->cl_nodes_bitmap);
+	}
+	write_unlock(&cluster->cl_nodes_lock);
+	if (p == NULL)
+		return -EEXIST;
+
+	return count;
+}
+static ssize_t r2nm_node_ipv4_port_read(struct r2nm_node *node, char *page)
+{
+	return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port));
+}
+
+static ssize_t r2nm_node_ipv4_port_write(struct r2nm_node *node,
+					 const char *page, size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *)page;
+	int err;
+
+	err = kstrtoul(p, 10, &tmp);
+	if (err)
+		return err;
+
+	if (tmp == 0)
+		return -EINVAL;
+	if (tmp >= (u16)-1)
+		return -ERANGE;
+
+	node->nd_ipv4_port = htons(tmp);
+
+	return count;
+}
+
+static ssize_t r2nm_node_ipv4_address_read(struct r2nm_node *node, char *page)
+{
+	return sprintf(page, "%pI4\n", &node->nd_ipv4_address);
+}
+
+static ssize_t r2nm_node_ipv4_address_write(struct r2nm_node *node,
+					    const char *page,
+					    size_t count)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node);
+	int ret, i;
+	struct rb_node **p, *parent;
+	unsigned int octets[4];
+	__be32 ipv4_addr = 0;
+
+	ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2],
+		     &octets[1], &octets[0]);
+	if (ret != 4)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(octets); i++) {
+		if (octets[i] > 255)
+			return -ERANGE;
+		be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
+	}
+
+	ret = 0;
+	write_lock(&cluster->cl_nodes_lock);
+	if (r2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
+		ret = -EEXIST;
+	else {
+		rb_link_node(&node->nd_ip_node, parent, p);
+		rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
+	}
+	write_unlock(&cluster->cl_nodes_lock);
+	if (ret)
+		return ret;
+
+	memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr));
+
+	return count;
+}
+
+static ssize_t r2nm_node_local_read(struct r2nm_node *node, char *page)
+{
+	return sprintf(page, "%d\n", node->nd_local);
+}
+
+static ssize_t r2nm_node_local_write(struct r2nm_node *node, const char *page,
+				     size_t count)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster_from_node(node);
+	unsigned long tmp;
+	char *p = (char *)page;
+	ssize_t ret;
+	int err;
+
+	err = kstrtoul(p, 10, &tmp);
+	if (err)
+		return err;
+
+	tmp = !!tmp; /* boolean of whether this node wants to be local */
+
+	/* setting local turns on networking rx for now so we require having
+	 * set everything else first */
+	if (!test_bit(R2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
+	    !test_bit(R2NM_NODE_ATTR_NUM, &node->nd_set_attributes) ||
+	    !test_bit(R2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+		return -EINVAL; /* XXX */
+
+	/* the only failure case is trying to set a new local node
+	 * when a different one is already set */
+	if (tmp && tmp == cluster->cl_has_local &&
+	    cluster->cl_local_node != node->nd_num)
+		return -EBUSY;
+
+	/* bring up the rx thread if we're setting the new local node. */
+	if (tmp && !cluster->cl_has_local) {
+		ret = r2net_start_listening(node);
+		if (ret)
+			return ret;
+	}
+
+	if (!tmp && cluster->cl_has_local &&
+	    cluster->cl_local_node == node->nd_num) {
+		r2net_stop_listening(node);
+		cluster->cl_local_node = R2NM_INVALID_NODE_NUM;
+	}
+
+	node->nd_local = tmp;
+	if (node->nd_local) {
+		cluster->cl_has_local = tmp;
+		cluster->cl_local_node = node->nd_num;
+	}
+
+	return count;
+}
+
+struct r2nm_node_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct r2nm_node *, char *);
+	ssize_t (*store)(struct r2nm_node *, const char *, size_t);
+};
+
+static struct r2nm_node_attribute r2nm_node_attr_num = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "num",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_node_num_read,
+	.store	= r2nm_node_num_write,
+};
+
+static struct r2nm_node_attribute r2nm_node_attr_ipv4_port = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "ipv4_port",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_node_ipv4_port_read,
+	.store	= r2nm_node_ipv4_port_write,
+};
+
+static struct r2nm_node_attribute r2nm_node_attr_ipv4_address = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "ipv4_address",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_node_ipv4_address_read,
+	.store	= r2nm_node_ipv4_address_write,
+};
+
+static struct r2nm_node_attribute r2nm_node_attr_local = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "local",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_node_local_read,
+	.store	= r2nm_node_local_write,
+};
+
+static struct configfs_attribute *r2nm_node_attrs[] = {
+	[R2NM_NODE_ATTR_NUM] = &r2nm_node_attr_num.attr,
+	[R2NM_NODE_ATTR_PORT] = &r2nm_node_attr_ipv4_port.attr,
+	[R2NM_NODE_ATTR_ADDRESS] = &r2nm_node_attr_ipv4_address.attr,
+	[R2NM_NODE_ATTR_LOCAL] = &r2nm_node_attr_local.attr,
+	NULL,
+};
+
+static int r2nm_attr_index(struct configfs_attribute *attr)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(r2nm_node_attrs); i++) {
+		if (attr == r2nm_node_attrs[i])
+			return i;
+	}
+	BUG();
+	return 0;
+}
+
+static ssize_t r2nm_node_show(struct config_item *item,
+			      struct configfs_attribute *attr,
+			      char *page)
+{
+	struct r2nm_node *node = to_r2nm_node(item);
+	struct r2nm_node_attribute *r2nm_node_attr =
+		container_of(attr, struct r2nm_node_attribute, attr);
+	ssize_t ret = 0;
+
+	if (r2nm_node_attr->show)
+		ret = r2nm_node_attr->show(node, page);
+	return ret;
+}
+
+static ssize_t r2nm_node_store(struct config_item *item,
+			       struct configfs_attribute *attr,
+			       const char *page, size_t count)
+{
+	struct r2nm_node *node = to_r2nm_node(item);
+	struct r2nm_node_attribute *r2nm_node_attr =
+		container_of(attr, struct r2nm_node_attribute, attr);
+	ssize_t ret;
+	int attr_index = r2nm_attr_index(attr);
+
+	if (r2nm_node_attr->store == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (test_bit(attr_index, &node->nd_set_attributes))
+		return -EBUSY;
+
+	ret = r2nm_node_attr->store(node, page, count);
+	if (ret < count)
+		goto out;
+
+	set_bit(attr_index, &node->nd_set_attributes);
+out:
+	return ret;
+}
+
+static struct configfs_item_operations r2nm_node_item_ops = {
+	.release		= r2nm_node_release,
+	.show_attribute		= r2nm_node_show,
+	.store_attribute	= r2nm_node_store,
+};
+
+static struct config_item_type r2nm_node_type = {
+	.ct_item_ops	= &r2nm_node_item_ops,
+	.ct_attrs	= r2nm_node_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* node set */
+
+struct r2nm_node_group {
+	struct config_group ns_group;
+	/* some stuff? */
+};
+
+#if 0
+static struct r2nm_node_group *to_r2nm_node_group(struct config_group *group)
+{
+	return group ?
+		container_of(group, struct r2nm_node_group, ns_group)
+		: NULL;
+}
+#endif
+
+struct r2nm_cluster_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct r2nm_cluster *, char *);
+	ssize_t (*store)(struct r2nm_cluster *, const char *, size_t);
+};
+
+static ssize_t r2nm_cluster_attr_write(const char *page, ssize_t count,
+					unsigned int *val)
+{
+	unsigned long tmp;
+	char *p = (char *)page;
+	int err;
+
+	err = kstrtoul(p, 10, &tmp);
+	if (err)
+		return err;
+
+	if (tmp == 0)
+		return -EINVAL;
+	if (tmp >= (u32)-1)
+		return -ERANGE;
+
+	*val = tmp;
+
+	return count;
+}
+
+static ssize_t r2nm_cluster_attr_idle_timeout_ms_read(
+	struct r2nm_cluster *cluster, char *page)
+{
+	return sprintf(page, "%u\n", cluster->cl_idle_timeout_ms);
+}
+
+static ssize_t r2nm_cluster_attr_idle_timeout_ms_write(
+	struct r2nm_cluster *cluster, const char *page, size_t count)
+{
+	ssize_t ret;
+	unsigned int val = 0;
+
+	ret =  r2nm_cluster_attr_write(page, count, &val);
+
+	if (ret > 0) {
+		if (cluster->cl_idle_timeout_ms != val
+			&& r2net_num_connected_peers()) {
+			mlog(ML_NOTICE,
+			     "r2net: cannot change idle timeout after "
+			     "the first peer has agreed to it."
+			     "  %d connected peers\n",
+			     r2net_num_connected_peers());
+			ret = -EINVAL;
+		} else if (val <= cluster->cl_keepalive_delay_ms) {
+			mlog(ML_NOTICE, "r2net: idle timeout must be larger "
+			     "than keepalive delay\n");
+			ret = -EINVAL;
+		} else {
+			cluster->cl_idle_timeout_ms = val;
+		}
+	}
+
+	return ret;
+}
+
+static ssize_t r2nm_cluster_attr_keepalive_delay_ms_read(
+	struct r2nm_cluster *cluster, char *page)
+{
+	return sprintf(page, "%u\n", cluster->cl_keepalive_delay_ms);
+}
+
+static ssize_t r2nm_cluster_attr_keepalive_delay_ms_write(
+	struct r2nm_cluster *cluster, const char *page, size_t count)
+{
+	ssize_t ret;
+	unsigned int val = 0;
+
+	ret =  r2nm_cluster_attr_write(page, count, &val);
+
+	if (ret > 0) {
+		if (cluster->cl_keepalive_delay_ms != val
+		    && r2net_num_connected_peers()) {
+			mlog(ML_NOTICE,
+			     "r2net: cannot change keepalive delay after"
+			     " the first peer has agreed to it."
+			     "  %d connected peers\n",
+			     r2net_num_connected_peers());
+			ret = -EINVAL;
+		} else if (val >= cluster->cl_idle_timeout_ms) {
+			mlog(ML_NOTICE, "r2net: keepalive delay must be "
+			     "smaller than idle timeout\n");
+			ret = -EINVAL;
+		} else {
+			cluster->cl_keepalive_delay_ms = val;
+		}
+	}
+
+	return ret;
+}
+
+static ssize_t r2nm_cluster_attr_reconnect_delay_ms_read(
+	struct r2nm_cluster *cluster, char *page)
+{
+	return sprintf(page, "%u\n", cluster->cl_reconnect_delay_ms);
+}
+
+static ssize_t r2nm_cluster_attr_reconnect_delay_ms_write(
+	struct r2nm_cluster *cluster, const char *page, size_t count)
+{
+	return r2nm_cluster_attr_write(page, count,
+					&cluster->cl_reconnect_delay_ms);
+}
+
+static ssize_t r2nm_cluster_attr_fence_method_read(
+	struct r2nm_cluster *cluster, char *page)
+{
+	ssize_t ret = 0;
+
+	if (cluster)
+		ret = sprintf(page, "%s\n",
+			      r2nm_fence_method_desc[cluster->cl_fence_method]);
+	return ret;
+}
+
+static ssize_t r2nm_cluster_attr_fence_method_write(
+	struct r2nm_cluster *cluster, const char *page, size_t count)
+{
+	unsigned int i;
+
+	if (page[count - 1] != '\n')
+		goto bail;
+
+	for (i = 0; i < R2NM_FENCE_METHODS; ++i) {
+		if (count != strlen(r2nm_fence_method_desc[i]) + 1)
+			continue;
+		if (strncasecmp(page, r2nm_fence_method_desc[i], count - 1))
+			continue;
+		if (cluster->cl_fence_method != i) {
+			printk(KERN_INFO "ramster: Changing fence method to %s\n",
+			       r2nm_fence_method_desc[i]);
+			cluster->cl_fence_method = i;
+		}
+		return count;
+	}
+
+bail:
+	return -EINVAL;
+}
+
+static struct r2nm_cluster_attribute r2nm_cluster_attr_idle_timeout_ms = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "idle_timeout_ms",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_cluster_attr_idle_timeout_ms_read,
+	.store	= r2nm_cluster_attr_idle_timeout_ms_write,
+};
+
+static struct r2nm_cluster_attribute r2nm_cluster_attr_keepalive_delay_ms = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "keepalive_delay_ms",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_cluster_attr_keepalive_delay_ms_read,
+	.store	= r2nm_cluster_attr_keepalive_delay_ms_write,
+};
+
+static struct r2nm_cluster_attribute r2nm_cluster_attr_reconnect_delay_ms = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "reconnect_delay_ms",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_cluster_attr_reconnect_delay_ms_read,
+	.store	= r2nm_cluster_attr_reconnect_delay_ms_write,
+};
+
+static struct r2nm_cluster_attribute r2nm_cluster_attr_fence_method = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "fence_method",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= r2nm_cluster_attr_fence_method_read,
+	.store	= r2nm_cluster_attr_fence_method_write,
+};
+
+static struct configfs_attribute *r2nm_cluster_attrs[] = {
+	&r2nm_cluster_attr_idle_timeout_ms.attr,
+	&r2nm_cluster_attr_keepalive_delay_ms.attr,
+	&r2nm_cluster_attr_reconnect_delay_ms.attr,
+	&r2nm_cluster_attr_fence_method.attr,
+	NULL,
+};
+static ssize_t r2nm_cluster_show(struct config_item *item,
+					struct configfs_attribute *attr,
+					char *page)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster(item);
+	struct r2nm_cluster_attribute *r2nm_cluster_attr =
+		container_of(attr, struct r2nm_cluster_attribute, attr);
+	ssize_t ret = 0;
+
+	if (r2nm_cluster_attr->show)
+		ret = r2nm_cluster_attr->show(cluster, page);
+	return ret;
+}
+
+static ssize_t r2nm_cluster_store(struct config_item *item,
+					struct configfs_attribute *attr,
+					const char *page, size_t count)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster(item);
+	struct r2nm_cluster_attribute *r2nm_cluster_attr =
+		container_of(attr, struct r2nm_cluster_attribute, attr);
+	ssize_t ret;
+
+	if (r2nm_cluster_attr->store == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = r2nm_cluster_attr->store(cluster, page, count);
+	if (ret < count)
+		goto out;
+out:
+	return ret;
+}
+
+static struct config_item *r2nm_node_group_make_item(struct config_group *group,
+						     const char *name)
+{
+	struct r2nm_node *node = NULL;
+
+	if (strlen(name) > R2NM_MAX_NAME_LEN)
+		return ERR_PTR(-ENAMETOOLONG);
+
+	node = kzalloc(sizeof(struct r2nm_node), GFP_KERNEL);
+	if (node == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
+	config_item_init_type_name(&node->nd_item, name, &r2nm_node_type);
+	spin_lock_init(&node->nd_lock);
+
+	mlog(ML_CLUSTER, "r2nm: Registering node %s\n", name);
+
+	return &node->nd_item;
+}
+
+static void r2nm_node_group_drop_item(struct config_group *group,
+				      struct config_item *item)
+{
+	struct r2nm_node *node = to_r2nm_node(item);
+	struct r2nm_cluster *cluster =
+				to_r2nm_cluster(group->cg_item.ci_parent);
+
+	r2net_disconnect_node(node);
+
+	if (cluster->cl_has_local &&
+	    (cluster->cl_local_node == node->nd_num)) {
+		cluster->cl_has_local = 0;
+		cluster->cl_local_node = R2NM_INVALID_NODE_NUM;
+		r2net_stop_listening(node);
+	}
+
+	/* XXX call into net to stop this node from trading messages */
+
+	write_lock(&cluster->cl_nodes_lock);
+
+	/* XXX sloppy */
+	if (node->nd_ipv4_address)
+		rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree);
+
+	/* nd_num might be 0 if the node number hasn't been set.. */
+	if (cluster->cl_nodes[node->nd_num] == node) {
+		cluster->cl_nodes[node->nd_num] = NULL;
+		clear_bit(node->nd_num, cluster->cl_nodes_bitmap);
+	}
+	write_unlock(&cluster->cl_nodes_lock);
+
+	mlog(ML_CLUSTER, "r2nm: Unregistered node %s\n",
+	     config_item_name(&node->nd_item));
+
+	config_item_put(item);
+}
+
+static struct configfs_group_operations r2nm_node_group_group_ops = {
+	.make_item	= r2nm_node_group_make_item,
+	.drop_item	= r2nm_node_group_drop_item,
+};
+
+static struct config_item_type r2nm_node_group_type = {
+	.ct_group_ops	= &r2nm_node_group_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* cluster */
+
+static void r2nm_cluster_release(struct config_item *item)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster(item);
+
+	kfree(cluster->cl_group.default_groups);
+	kfree(cluster);
+}
+
+static struct configfs_item_operations r2nm_cluster_item_ops = {
+	.release	= r2nm_cluster_release,
+	.show_attribute		= r2nm_cluster_show,
+	.store_attribute	= r2nm_cluster_store,
+};
+
+static struct config_item_type r2nm_cluster_type = {
+	.ct_item_ops	= &r2nm_cluster_item_ops,
+	.ct_attrs	= r2nm_cluster_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* cluster set */
+
+struct r2nm_cluster_group {
+	struct configfs_subsystem cs_subsys;
+	/* some stuff? */
+};
+
+#if 0
+static struct r2nm_cluster_group *
+to_r2nm_cluster_group(struct config_group *group)
+{
+	return group ?
+		container_of(to_configfs_subsystem(group),
+				struct r2nm_cluster_group, cs_subsys)
+	       : NULL;
+}
+#endif
+
+static struct config_group *
+r2nm_cluster_group_make_group(struct config_group *group,
+							  const char *name)
+{
+	struct r2nm_cluster *cluster = NULL;
+	struct r2nm_node_group *ns = NULL;
+	struct config_group *r2hb_group = NULL, *ret = NULL;
+	void *defs = NULL;
+
+	/* this runs under the parent dir's i_mutex; there can be only
+	 * one caller in here at a time */
+	if (r2nm_single_cluster)
+		return ERR_PTR(-ENOSPC);
+
+	cluster = kzalloc(sizeof(struct r2nm_cluster), GFP_KERNEL);
+	ns = kzalloc(sizeof(struct r2nm_node_group), GFP_KERNEL);
+	defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
+	r2hb_group = r2hb_alloc_hb_set();
+	if (cluster == NULL || ns == NULL || r2hb_group == NULL || defs == NULL)
+		goto out;
+
+	config_group_init_type_name(&cluster->cl_group, name,
+				    &r2nm_cluster_type);
+	config_group_init_type_name(&ns->ns_group, "node",
+				    &r2nm_node_group_type);
+
+	cluster->cl_group.default_groups = defs;
+	cluster->cl_group.default_groups[0] = &ns->ns_group;
+	cluster->cl_group.default_groups[1] = r2hb_group;
+	cluster->cl_group.default_groups[2] = NULL;
+	rwlock_init(&cluster->cl_nodes_lock);
+	cluster->cl_node_ip_tree = RB_ROOT;
+	cluster->cl_reconnect_delay_ms = R2NET_RECONNECT_DELAY_MS_DEFAULT;
+	cluster->cl_idle_timeout_ms    = R2NET_IDLE_TIMEOUT_MS_DEFAULT;
+	cluster->cl_keepalive_delay_ms = R2NET_KEEPALIVE_DELAY_MS_DEFAULT;
+	cluster->cl_fence_method       = R2NM_FENCE_RESET;
+
+	ret = &cluster->cl_group;
+	r2nm_single_cluster = cluster;
+
+out:
+	if (ret == NULL) {
+		kfree(cluster);
+		kfree(ns);
+		r2hb_free_hb_set(r2hb_group);
+		kfree(defs);
+		ret = ERR_PTR(-ENOMEM);
+	}
+
+	return ret;
+}
+
+static void r2nm_cluster_group_drop_item(struct config_group *group,
+						struct config_item *item)
+{
+	struct r2nm_cluster *cluster = to_r2nm_cluster(item);
+	int i;
+	struct config_item *killme;
+
+	BUG_ON(r2nm_single_cluster != cluster);
+	r2nm_single_cluster = NULL;
+
+	for (i = 0; cluster->cl_group.default_groups[i]; i++) {
+		killme = &cluster->cl_group.default_groups[i]->cg_item;
+		cluster->cl_group.default_groups[i] = NULL;
+		config_item_put(killme);
+	}
+
+	config_item_put(item);
+}
+
+static struct configfs_group_operations r2nm_cluster_group_group_ops = {
+	.make_group	= r2nm_cluster_group_make_group,
+	.drop_item	= r2nm_cluster_group_drop_item,
+};
+
+static struct config_item_type r2nm_cluster_group_type = {
+	.ct_group_ops	= &r2nm_cluster_group_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct r2nm_cluster_group r2nm_cluster_group = {
+	.cs_subsys = {
+		.su_group = {
+			.cg_item = {
+				.ci_namebuf = "cluster",
+				.ci_type = &r2nm_cluster_group_type,
+			},
+		},
+	},
+};
+
+int r2nm_depend_item(struct config_item *item)
+{
+	return configfs_depend_item(&r2nm_cluster_group.cs_subsys, item);
+}
+
+void r2nm_undepend_item(struct config_item *item)
+{
+	configfs_undepend_item(&r2nm_cluster_group.cs_subsys, item);
+}
+
+int r2nm_depend_this_node(void)
+{
+	int ret = 0;
+	struct r2nm_node *local_node;
+
+	local_node = r2nm_get_node_by_num(r2nm_this_node());
+	if (!local_node) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = r2nm_depend_item(&local_node->nd_item);
+	r2nm_node_put(local_node);
+
+out:
+	return ret;
+}
+
+void r2nm_undepend_this_node(void)
+{
+	struct r2nm_node *local_node;
+
+	local_node = r2nm_get_node_by_num(r2nm_this_node());
+	BUG_ON(!local_node);
+
+	r2nm_undepend_item(&local_node->nd_item);
+	r2nm_node_put(local_node);
+}
+
+
+static void __exit exit_r2nm(void)
+{
+	/* XXX sync with hb callbacks and shut down hb? */
+	r2net_unregister_hb_callbacks();
+	configfs_unregister_subsystem(&r2nm_cluster_group.cs_subsys);
+
+	r2net_exit();
+	r2hb_exit();
+}
+
+static int __init init_r2nm(void)
+{
+	int ret = -1;
+
+	ret = r2hb_init();
+	if (ret)
+		goto out;
+
+	ret = r2net_init();
+	if (ret)
+		goto out_r2hb;
+
+	ret = r2net_register_hb_callbacks();
+	if (ret)
+		goto out_r2net;
+
+	config_group_init(&r2nm_cluster_group.cs_subsys.su_group);
+	mutex_init(&r2nm_cluster_group.cs_subsys.su_mutex);
+	ret = configfs_register_subsystem(&r2nm_cluster_group.cs_subsys);
+	if (ret) {
+		printk(KERN_ERR "nodemanager: Registration returned %d\n", ret);
+		goto out_callbacks;
+	}
+
+	if (!ret)
+		goto out;
+
+	configfs_unregister_subsystem(&r2nm_cluster_group.cs_subsys);
+out_callbacks:
+	r2net_unregister_hb_callbacks();
+out_r2net:
+	r2net_exit();
+out_r2hb:
+	r2hb_exit();
+out:
+	return ret;
+}
+
+MODULE_AUTHOR("Oracle");
+MODULE_LICENSE("GPL");
+
+module_init(init_r2nm)
+module_exit(exit_r2nm)
diff --git a/drivers/staging/ramster/cluster/nodemanager.h b/drivers/staging/ramster/cluster/nodemanager.h
new file mode 100644
index 0000000..41a04df
--- /dev/null
+++ b/drivers/staging/ramster/cluster/nodemanager.h
@@ -0,0 +1,88 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * nodemanager.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef R2CLUSTER_NODEMANAGER_H
+#define R2CLUSTER_NODEMANAGER_H
+
+#include "ramster_nodemanager.h"
+
+/* This totally doesn't belong here. */
+#include <linux/configfs.h>
+#include <linux/rbtree.h>
+
+enum r2nm_fence_method {
+	R2NM_FENCE_RESET	= 0,
+	R2NM_FENCE_PANIC,
+	R2NM_FENCE_METHODS,	/* Number of fence methods */
+};
+
+struct r2nm_node {
+	spinlock_t		nd_lock;
+	struct config_item	nd_item;
+	char			nd_name[R2NM_MAX_NAME_LEN+1]; /* replace? */
+	__u8			nd_num;
+	/* only one address per node, as attributes, for now. */
+	__be32			nd_ipv4_address;
+	__be16			nd_ipv4_port;
+	struct rb_node		nd_ip_node;
+	/* there can be only one local node for now */
+	int			nd_local;
+
+	unsigned long		nd_set_attributes;
+};
+
+struct r2nm_cluster {
+	struct config_group	cl_group;
+	unsigned		cl_has_local:1;
+	u8			cl_local_node;
+	rwlock_t		cl_nodes_lock;
+	struct r2nm_node	*cl_nodes[R2NM_MAX_NODES];
+	struct rb_root		cl_node_ip_tree;
+	unsigned int		cl_idle_timeout_ms;
+	unsigned int		cl_keepalive_delay_ms;
+	unsigned int		cl_reconnect_delay_ms;
+	enum r2nm_fence_method	cl_fence_method;
+
+	/* part of a hack for disk bitmap.. will go eventually. - zab */
+	unsigned long	cl_nodes_bitmap[BITS_TO_LONGS(R2NM_MAX_NODES)];
+};
+
+extern struct r2nm_cluster *r2nm_single_cluster;
+
+u8 r2nm_this_node(void);
+
+int r2nm_configured_node_map(unsigned long *map, unsigned bytes);
+struct r2nm_node *r2nm_get_node_by_num(u8 node_num);
+struct r2nm_node *r2nm_get_node_by_ip(__be32 addr);
+void r2nm_node_get(struct r2nm_node *node);
+void r2nm_node_put(struct r2nm_node *node);
+
+int r2nm_depend_item(struct config_item *item);
+void r2nm_undepend_item(struct config_item *item);
+int r2nm_depend_this_node(void);
+void r2nm_undepend_this_node(void);
+
+#endif /* R2CLUSTER_NODEMANAGER_H */
diff --git a/drivers/staging/ramster/cluster/ramster_nodemanager.h b/drivers/staging/ramster/cluster/ramster_nodemanager.h
new file mode 100644
index 0000000..49f879d
--- /dev/null
+++ b/drivers/staging/ramster/cluster/ramster_nodemanager.h
@@ -0,0 +1,39 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ramster_nodemanager.h
+ *
+ * Header describing the interface between userspace and the kernel
+ * for the ramster_nodemanager module.
+ *
+ * Copyright (C) 2002, 2004, 2012 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef _RAMSTER_NODEMANAGER_H
+#define _RAMSTER_NODEMANAGER_H
+
+#define R2NM_API_VERSION	5
+
+#define R2NM_MAX_NODES		255
+#define R2NM_INVALID_NODE_NUM	255
+
+/* host name, group name, cluster name all 64 bytes */
+#define R2NM_MAX_NAME_LEN        64    /* __NEW_UTS_LEN */
+
+#endif /* _RAMSTER_NODEMANAGER_H */
diff --git a/drivers/staging/ramster/cluster/tcp.c b/drivers/staging/ramster/cluster/tcp.c
new file mode 100644
index 0000000..3af1b2c
--- /dev/null
+++ b/drivers/staging/ramster/cluster/tcp.c
@@ -0,0 +1,2256 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ *
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * ----
+ *
+ * Callers for this were originally written against a very simple synchronus
+ * API.  This implementation reflects those simple callers.  Some day I'm sure
+ * we'll need to move to a more robust posting/callback mechanism.
+ *
+ * Transmit calls pass in kernel virtual addresses and block copying this into
+ * the socket's tx buffers via a usual blocking sendmsg.  They'll block waiting
+ * for a failed socket to timeout.  TX callers can also pass in a poniter to an
+ * 'int' which gets filled with an errno off the wire in response to the
+ * message they send.
+ *
+ * Handlers for unsolicited messages are registered.  Each socket has a page
+ * that incoming data is copied into.  First the header, then the data.
+ * Handlers are called from only one thread with a reference to this per-socket
+ * page.  This page is destroyed after the handler call, so it can't be
+ * referenced beyond the call.  Handlers may block but are discouraged from
+ * doing so.
+ *
+ * Any framing errors (bad magic, large payload lengths) close a connection.
+ *
+ * Our sock_container holds the state we associate with a socket.  It's current
+ * framing state is held there as well as the refcounting we do around when it
+ * is safe to tear down the socket.  The socket is only finally torn down from
+ * the container when the container loses all of its references -- so as long
+ * as you hold a ref on the container you can trust that the socket is valid
+ * for use with kernel socket APIs.
+ *
+ * Connections are initiated between a pair of nodes when the node with the
+ * higher node number gets a heartbeat callback which indicates that the lower
+ * numbered node has started heartbeating.  The lower numbered node is passive
+ * and only accepts the connection if the higher numbered node is heartbeating.
+ */
+
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/kref.h>
+#include <linux/net.h>
+#include <linux/export.h>
+#include <linux/uaccess.h>
+#include <net/tcp.h>
+
+
+#include "heartbeat.h"
+#include "tcp.h"
+#include "nodemanager.h"
+#define MLOG_MASK_PREFIX ML_TCP
+#include "masklog.h"
+
+#include "tcp_internal.h"
+
+#define SC_NODEF_FMT "node %s (num %u) at %pI4:%u"
+
+/*
+ * In the following two log macros, the whitespace after the ',' just
+ * before ##args is intentional. Otherwise, gcc 2.95 will eat the
+ * previous token if args expands to nothing.
+ */
+#define msglog(hdr, fmt, args...) do {					\
+	typeof(hdr) __hdr = (hdr);					\
+	mlog(ML_MSG, "[mag %u len %u typ %u stat %d sys_stat %d "	\
+	     "key %08x num %u] " fmt,					\
+	be16_to_cpu(__hdr->magic), be16_to_cpu(__hdr->data_len),	\
+	     be16_to_cpu(__hdr->msg_type), be32_to_cpu(__hdr->status),	\
+	     be32_to_cpu(__hdr->sys_status), be32_to_cpu(__hdr->key),	\
+	     be32_to_cpu(__hdr->msg_num) ,  ##args);			\
+} while (0)
+
+#define sclog(sc, fmt, args...) do {					\
+	typeof(sc) __sc = (sc);						\
+	mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p "	\
+	     "pg_off %zu] " fmt, __sc,					\
+	     atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock,	\
+	    __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off ,	\
+	    ##args);							\
+} while (0)
+
+static DEFINE_RWLOCK(r2net_handler_lock);
+static struct rb_root r2net_handler_tree = RB_ROOT;
+
+static struct r2net_node r2net_nodes[R2NM_MAX_NODES];
+
+/* XXX someday we'll need better accounting */
+static struct socket *r2net_listen_sock;
+
+/*
+ * listen work is only queued by the listening socket callbacks on the
+ * r2net_wq.  teardown detaches the callbacks before destroying the workqueue.
+ * quorum work is queued as sock containers are shutdown.. stop_listening
+ * tears down all the node's sock containers, preventing future shutdowns
+ * and queued quroum work, before canceling delayed quorum work and
+ * destroying the work queue.
+ */
+static struct workqueue_struct *r2net_wq;
+static struct work_struct r2net_listen_work;
+
+static struct r2hb_callback_func r2net_hb_up, r2net_hb_down;
+#define R2NET_HB_PRI 0x1
+
+static struct r2net_handshake *r2net_hand;
+static struct r2net_msg *r2net_keep_req, *r2net_keep_resp;
+
+static int r2net_sys_err_translations[R2NET_ERR_MAX] = {
+		[R2NET_ERR_NONE]	= 0,
+		[R2NET_ERR_NO_HNDLR]	= -ENOPROTOOPT,
+		[R2NET_ERR_OVERFLOW]	= -EOVERFLOW,
+		[R2NET_ERR_DIED]	= -EHOSTDOWN,};
+
+/* can't quite avoid *all* internal declarations :/ */
+static void r2net_sc_connect_completed(struct work_struct *work);
+static void r2net_rx_until_empty(struct work_struct *work);
+static void r2net_shutdown_sc(struct work_struct *work);
+static void r2net_listen_data_ready(struct sock *sk, int bytes);
+static void r2net_sc_send_keep_req(struct work_struct *work);
+static void r2net_idle_timer(unsigned long data);
+static void r2net_sc_postpone_idle(struct r2net_sock_container *sc);
+static void r2net_sc_reset_idle_timer(struct r2net_sock_container *sc);
+
+#ifdef CONFIG_DEBUG_FS
+static void r2net_init_nst(struct r2net_send_tracking *nst, u32 msgtype,
+			   u32 msgkey, struct task_struct *task, u8 node)
+{
+	INIT_LIST_HEAD(&nst->st_net_debug_item);
+	nst->st_task = task;
+	nst->st_msg_type = msgtype;
+	nst->st_msg_key = msgkey;
+	nst->st_node = node;
+}
+
+static inline void r2net_set_nst_sock_time(struct r2net_send_tracking *nst)
+{
+	nst->st_sock_time = ktime_get();
+}
+
+static inline void r2net_set_nst_send_time(struct r2net_send_tracking *nst)
+{
+	nst->st_send_time = ktime_get();
+}
+
+static inline void r2net_set_nst_status_time(struct r2net_send_tracking *nst)
+{
+	nst->st_status_time = ktime_get();
+}
+
+static inline void r2net_set_nst_sock_container(struct r2net_send_tracking *nst,
+						struct r2net_sock_container *sc)
+{
+	nst->st_sc = sc;
+}
+
+static inline void r2net_set_nst_msg_id(struct r2net_send_tracking *nst,
+					u32 msg_id)
+{
+	nst->st_id = msg_id;
+}
+
+static inline void r2net_set_sock_timer(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_timer = ktime_get();
+}
+
+static inline void r2net_set_data_ready_time(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_data_ready = ktime_get();
+}
+
+static inline void r2net_set_advance_start_time(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_advance_start = ktime_get();
+}
+
+static inline void r2net_set_advance_stop_time(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_advance_stop = ktime_get();
+}
+
+static inline void r2net_set_func_start_time(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_func_start = ktime_get();
+}
+
+static inline void r2net_set_func_stop_time(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_func_stop = ktime_get();
+}
+
+#else  /* CONFIG_DEBUG_FS */
+# define r2net_init_nst(a, b, c, d, e)
+# define r2net_set_nst_sock_time(a)
+# define r2net_set_nst_send_time(a)
+# define r2net_set_nst_status_time(a)
+# define r2net_set_nst_sock_container(a, b)
+# define r2net_set_nst_msg_id(a, b)
+# define r2net_set_sock_timer(a)
+# define r2net_set_data_ready_time(a)
+# define r2net_set_advance_start_time(a)
+# define r2net_set_advance_stop_time(a)
+# define r2net_set_func_start_time(a)
+# define r2net_set_func_stop_time(a)
+#endif /* CONFIG_DEBUG_FS */
+
+#ifdef CONFIG_RAMSTER_FS_STATS
+static ktime_t r2net_get_func_run_time(struct r2net_sock_container *sc)
+{
+	return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start);
+}
+
+static void r2net_update_send_stats(struct r2net_send_tracking *nst,
+				    struct r2net_sock_container *sc)
+{
+	sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total,
+					   ktime_sub(ktime_get(),
+						     nst->st_status_time));
+	sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total,
+					 ktime_sub(nst->st_status_time,
+						   nst->st_send_time));
+	sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total,
+					    ktime_sub(nst->st_send_time,
+						      nst->st_sock_time));
+	sc->sc_send_count++;
+}
+
+static void r2net_update_recv_stats(struct r2net_sock_container *sc)
+{
+	sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total,
+					    r2net_get_func_run_time(sc));
+	sc->sc_recv_count++;
+}
+
+#else
+
+# define r2net_update_send_stats(a, b)
+
+# define r2net_update_recv_stats(sc)
+
+#endif /* CONFIG_RAMSTER_FS_STATS */
+
+static inline int r2net_reconnect_delay(void)
+{
+	return r2nm_single_cluster->cl_reconnect_delay_ms;
+}
+
+static inline int r2net_keepalive_delay(void)
+{
+	return r2nm_single_cluster->cl_keepalive_delay_ms;
+}
+
+static inline int r2net_idle_timeout(void)
+{
+	return r2nm_single_cluster->cl_idle_timeout_ms;
+}
+
+static inline int r2net_sys_err_to_errno(enum r2net_system_error err)
+{
+	int trans;
+	BUG_ON(err >= R2NET_ERR_MAX);
+	trans = r2net_sys_err_translations[err];
+
+	/* Just in case we mess up the translation table above */
+	BUG_ON(err != R2NET_ERR_NONE && trans == 0);
+	return trans;
+}
+
+struct r2net_node *r2net_nn_from_num(u8 node_num)
+{
+	BUG_ON(node_num >= ARRAY_SIZE(r2net_nodes));
+	return &r2net_nodes[node_num];
+}
+
+static u8 r2net_num_from_nn(struct r2net_node *nn)
+{
+	BUG_ON(nn == NULL);
+	return nn - r2net_nodes;
+}
+
+/* ------------------------------------------------------------ */
+
+static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw)
+{
+	int ret = 0;
+
+	do {
+		if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) {
+			ret = -EAGAIN;
+			break;
+		}
+		spin_lock(&nn->nn_lock);
+		ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id);
+		if (ret == 0)
+			list_add_tail(&nsw->ns_node_item,
+				      &nn->nn_status_list);
+		spin_unlock(&nn->nn_lock);
+	} while (ret == -EAGAIN);
+
+	if (ret == 0)  {
+		init_waitqueue_head(&nsw->ns_wq);
+		nsw->ns_sys_status = R2NET_ERR_NONE;
+		nsw->ns_status = 0;
+	}
+
+	return ret;
+}
+
+static void r2net_complete_nsw_locked(struct r2net_node *nn,
+				      struct r2net_status_wait *nsw,
+				      enum r2net_system_error sys_status,
+				      s32 status)
+{
+	assert_spin_locked(&nn->nn_lock);
+
+	if (!list_empty(&nsw->ns_node_item)) {
+		list_del_init(&nsw->ns_node_item);
+		nsw->ns_sys_status = sys_status;
+		nsw->ns_status = status;
+		idr_remove(&nn->nn_status_idr, nsw->ns_id);
+		wake_up(&nsw->ns_wq);
+	}
+}
+
+static void r2net_complete_nsw(struct r2net_node *nn,
+			       struct r2net_status_wait *nsw,
+			       u64 id, enum r2net_system_error sys_status,
+			       s32 status)
+{
+	spin_lock(&nn->nn_lock);
+	if (nsw == NULL) {
+		if (id > INT_MAX)
+			goto out;
+
+		nsw = idr_find(&nn->nn_status_idr, id);
+		if (nsw == NULL)
+			goto out;
+	}
+
+	r2net_complete_nsw_locked(nn, nsw, sys_status, status);
+
+out:
+	spin_unlock(&nn->nn_lock);
+	return;
+}
+
+static void r2net_complete_nodes_nsw(struct r2net_node *nn)
+{
+	struct r2net_status_wait *nsw, *tmp;
+	unsigned int num_kills = 0;
+
+	assert_spin_locked(&nn->nn_lock);
+
+	list_for_each_entry_safe(nsw, tmp, &nn->nn_status_list, ns_node_item) {
+		r2net_complete_nsw_locked(nn, nsw, R2NET_ERR_DIED, 0);
+		num_kills++;
+	}
+
+	mlog(0, "completed %d messages for node %u\n", num_kills,
+	     r2net_num_from_nn(nn));
+}
+
+static int r2net_nsw_completed(struct r2net_node *nn,
+			       struct r2net_status_wait *nsw)
+{
+	int completed;
+	spin_lock(&nn->nn_lock);
+	completed = list_empty(&nsw->ns_node_item);
+	spin_unlock(&nn->nn_lock);
+	return completed;
+}
+
+/* ------------------------------------------------------------ */
+
+static void sc_kref_release(struct kref *kref)
+{
+	struct r2net_sock_container *sc = container_of(kref,
+					struct r2net_sock_container, sc_kref);
+	BUG_ON(timer_pending(&sc->sc_idle_timeout));
+
+	sclog(sc, "releasing\n");
+
+	if (sc->sc_sock) {
+		sock_release(sc->sc_sock);
+		sc->sc_sock = NULL;
+	}
+
+	r2nm_undepend_item(&sc->sc_node->nd_item);
+	r2nm_node_put(sc->sc_node);
+	sc->sc_node = NULL;
+
+	r2net_debug_del_sc(sc);
+	kfree(sc);
+}
+
+static void sc_put(struct r2net_sock_container *sc)
+{
+	sclog(sc, "put\n");
+	kref_put(&sc->sc_kref, sc_kref_release);
+}
+static void sc_get(struct r2net_sock_container *sc)
+{
+	sclog(sc, "get\n");
+	kref_get(&sc->sc_kref);
+}
+static struct r2net_sock_container *sc_alloc(struct r2nm_node *node)
+{
+	struct r2net_sock_container *sc, *ret = NULL;
+	struct page *page = NULL;
+	int status = 0;
+
+	page = alloc_page(GFP_NOFS);
+	sc = kzalloc(sizeof(*sc), GFP_NOFS);
+	if (sc == NULL || page == NULL)
+		goto out;
+
+	kref_init(&sc->sc_kref);
+	r2nm_node_get(node);
+	sc->sc_node = node;
+
+	/* pin the node item of the remote node */
+	status = r2nm_depend_item(&node->nd_item);
+	if (status) {
+		mlog_errno(status);
+		r2nm_node_put(node);
+		goto out;
+	}
+	INIT_WORK(&sc->sc_connect_work, r2net_sc_connect_completed);
+	INIT_WORK(&sc->sc_rx_work, r2net_rx_until_empty);
+	INIT_WORK(&sc->sc_shutdown_work, r2net_shutdown_sc);
+	INIT_DELAYED_WORK(&sc->sc_keepalive_work, r2net_sc_send_keep_req);
+
+	init_timer(&sc->sc_idle_timeout);
+	sc->sc_idle_timeout.function = r2net_idle_timer;
+	sc->sc_idle_timeout.data = (unsigned long)sc;
+
+	sclog(sc, "alloced\n");
+
+	ret = sc;
+	sc->sc_page = page;
+	r2net_debug_add_sc(sc);
+	sc = NULL;
+	page = NULL;
+
+out:
+	if (page)
+		__free_page(page);
+	kfree(sc);
+
+	return ret;
+}
+
+/* ------------------------------------------------------------ */
+
+static void r2net_sc_queue_work(struct r2net_sock_container *sc,
+				struct work_struct *work)
+{
+	sc_get(sc);
+	if (!queue_work(r2net_wq, work))
+		sc_put(sc);
+}
+static void r2net_sc_queue_delayed_work(struct r2net_sock_container *sc,
+					struct delayed_work *work,
+					int delay)
+{
+	sc_get(sc);
+	if (!queue_delayed_work(r2net_wq, work, delay))
+		sc_put(sc);
+}
+static void r2net_sc_cancel_delayed_work(struct r2net_sock_container *sc,
+					 struct delayed_work *work)
+{
+	if (cancel_delayed_work(work))
+		sc_put(sc);
+}
+
+static atomic_t r2net_connected_peers = ATOMIC_INIT(0);
+
+int r2net_num_connected_peers(void)
+{
+	return atomic_read(&r2net_connected_peers);
+}
+
+static void r2net_set_nn_state(struct r2net_node *nn,
+			       struct r2net_sock_container *sc,
+			       unsigned valid, int err)
+{
+	int was_valid = nn->nn_sc_valid;
+	int was_err = nn->nn_persistent_error;
+	struct r2net_sock_container *old_sc = nn->nn_sc;
+
+	assert_spin_locked(&nn->nn_lock);
+
+	if (old_sc && !sc)
+		atomic_dec(&r2net_connected_peers);
+	else if (!old_sc && sc)
+		atomic_inc(&r2net_connected_peers);
+
+	/* the node num comparison and single connect/accept path should stop
+	 * an non-null sc from being overwritten with another */
+	BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc);
+	mlog_bug_on_msg(err && valid, "err %d valid %u\n", err, valid);
+	mlog_bug_on_msg(valid && !sc, "valid %u sc %p\n", valid, sc);
+
+	if (was_valid && !valid && err == 0)
+		err = -ENOTCONN;
+
+	mlog(ML_CONN, "node %u sc: %p -> %p, valid %u -> %u, err %d -> %d\n",
+	     r2net_num_from_nn(nn), nn->nn_sc, sc, nn->nn_sc_valid, valid,
+	     nn->nn_persistent_error, err);
+
+	nn->nn_sc = sc;
+	nn->nn_sc_valid = valid ? 1 : 0;
+	nn->nn_persistent_error = err;
+
+	/* mirrors r2net_tx_can_proceed() */
+	if (nn->nn_persistent_error || nn->nn_sc_valid)
+		wake_up(&nn->nn_sc_wq);
+
+	if (!was_err && nn->nn_persistent_error) {
+		queue_delayed_work(r2net_wq, &nn->nn_still_up,
+				   msecs_to_jiffies(R2NET_QUORUM_DELAY_MS));
+	}
+
+	if (was_valid && !valid) {
+		printk(KERN_NOTICE "ramster: No longer connected to "
+		       SC_NODEF_FMT "\n",
+			old_sc->sc_node->nd_name, old_sc->sc_node->nd_num,
+			&old_sc->sc_node->nd_ipv4_address,
+			ntohs(old_sc->sc_node->nd_ipv4_port));
+		r2net_complete_nodes_nsw(nn);
+	}
+
+	if (!was_valid && valid) {
+		cancel_delayed_work(&nn->nn_connect_expired);
+		printk(KERN_NOTICE "ramster: %s " SC_NODEF_FMT "\n",
+		       r2nm_this_node() > sc->sc_node->nd_num ?
+		       "Connected to" : "Accepted connection from",
+		       sc->sc_node->nd_name, sc->sc_node->nd_num,
+			&sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port));
+	}
+
+	/* trigger the connecting worker func as long as we're not valid,
+	 * it will back off if it shouldn't connect.  This can be called
+	 * from node config teardown and so needs to be careful about
+	 * the work queue actually being up. */
+	if (!valid && r2net_wq) {
+		unsigned long delay;
+		/* delay if we're within a RECONNECT_DELAY of the
+		 * last attempt */
+		delay = (nn->nn_last_connect_attempt +
+			 msecs_to_jiffies(r2net_reconnect_delay()))
+			- jiffies;
+		if (delay > msecs_to_jiffies(r2net_reconnect_delay()))
+			delay = 0;
+		mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay);
+		queue_delayed_work(r2net_wq, &nn->nn_connect_work, delay);
+
+		/*
+		 * Delay the expired work after idle timeout.
+		 *
+		 * We might have lots of failed connection attempts that run
+		 * through here but we only cancel the connect_expired work when
+		 * a connection attempt succeeds.  So only the first enqueue of
+		 * the connect_expired work will do anything.  The rest will see
+		 * that it's already queued and do nothing.
+		 */
+		delay += msecs_to_jiffies(r2net_idle_timeout());
+		queue_delayed_work(r2net_wq, &nn->nn_connect_expired, delay);
+	}
+
+	/* keep track of the nn's sc ref for the caller */
+	if ((old_sc == NULL) && sc)
+		sc_get(sc);
+	if (old_sc && (old_sc != sc)) {
+		r2net_sc_queue_work(old_sc, &old_sc->sc_shutdown_work);
+		sc_put(old_sc);
+	}
+}
+
+/* see r2net_register_callbacks() */
+static void r2net_data_ready(struct sock *sk, int bytes)
+{
+	void (*ready)(struct sock *sk, int bytes);
+
+	read_lock(&sk->sk_callback_lock);
+	if (sk->sk_user_data) {
+		struct r2net_sock_container *sc = sk->sk_user_data;
+		sclog(sc, "data_ready hit\n");
+		r2net_set_data_ready_time(sc);
+		r2net_sc_queue_work(sc, &sc->sc_rx_work);
+		ready = sc->sc_data_ready;
+	} else {
+		ready = sk->sk_data_ready;
+	}
+	read_unlock(&sk->sk_callback_lock);
+
+	ready(sk, bytes);
+}
+
+/* see r2net_register_callbacks() */
+static void r2net_state_change(struct sock *sk)
+{
+	void (*state_change)(struct sock *sk);
+	struct r2net_sock_container *sc;
+
+	read_lock(&sk->sk_callback_lock);
+	sc = sk->sk_user_data;
+	if (sc == NULL) {
+		state_change = sk->sk_state_change;
+		goto out;
+	}
+
+	sclog(sc, "state_change to %d\n", sk->sk_state);
+
+	state_change = sc->sc_state_change;
+
+	switch (sk->sk_state) {
+
+	/* ignore connecting sockets as they make progress */
+	case TCP_SYN_SENT:
+	case TCP_SYN_RECV:
+		break;
+	case TCP_ESTABLISHED:
+		r2net_sc_queue_work(sc, &sc->sc_connect_work);
+		break;
+	default:
+		printk(KERN_INFO "ramster: Connection to "
+			SC_NODEF_FMT " shutdown, state %d\n",
+			sc->sc_node->nd_name, sc->sc_node->nd_num,
+			&sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port), sk->sk_state);
+		r2net_sc_queue_work(sc, &sc->sc_shutdown_work);
+		break;
+
+	}
+out:
+	read_unlock(&sk->sk_callback_lock);
+	state_change(sk);
+}
+
+/*
+ * we register callbacks so we can queue work on events before calling
+ * the original callbacks.  our callbacks our careful to test user_data
+ * to discover when they've reaced with r2net_unregister_callbacks().
+ */
+static void r2net_register_callbacks(struct sock *sk,
+				     struct r2net_sock_container *sc)
+{
+	write_lock_bh(&sk->sk_callback_lock);
+
+	/* accepted sockets inherit the old listen socket data ready */
+	if (sk->sk_data_ready == r2net_listen_data_ready) {
+		sk->sk_data_ready = sk->sk_user_data;
+		sk->sk_user_data = NULL;
+	}
+
+	BUG_ON(sk->sk_user_data != NULL);
+	sk->sk_user_data = sc;
+	sc_get(sc);
+
+	sc->sc_data_ready = sk->sk_data_ready;
+	sc->sc_state_change = sk->sk_state_change;
+	sk->sk_data_ready = r2net_data_ready;
+	sk->sk_state_change = r2net_state_change;
+
+	mutex_init(&sc->sc_send_lock);
+
+	write_unlock_bh(&sk->sk_callback_lock);
+}
+
+static int r2net_unregister_callbacks(struct sock *sk,
+					struct r2net_sock_container *sc)
+{
+	int ret = 0;
+
+	write_lock_bh(&sk->sk_callback_lock);
+	if (sk->sk_user_data == sc) {
+		ret = 1;
+		sk->sk_user_data = NULL;
+		sk->sk_data_ready = sc->sc_data_ready;
+		sk->sk_state_change = sc->sc_state_change;
+	}
+	write_unlock_bh(&sk->sk_callback_lock);
+
+	return ret;
+}
+
+/*
+ * this is a little helper that is called by callers who have seen a problem
+ * with an sc and want to detach it from the nn if someone already hasn't beat
+ * them to it.  if an error is given then the shutdown will be persistent
+ * and pending transmits will be canceled.
+ */
+static void r2net_ensure_shutdown(struct r2net_node *nn,
+					struct r2net_sock_container *sc,
+				   int err)
+{
+	spin_lock(&nn->nn_lock);
+	if (nn->nn_sc == sc)
+		r2net_set_nn_state(nn, NULL, 0, err);
+	spin_unlock(&nn->nn_lock);
+}
+
+/*
+ * This work queue function performs the blocking parts of socket shutdown.  A
+ * few paths lead here.  set_nn_state will trigger this callback if it sees an
+ * sc detached from the nn.  state_change will also trigger this callback
+ * directly when it sees errors.  In that case we need to call set_nn_state
+ * ourselves as state_change couldn't get the nn_lock and call set_nn_state
+ * itself.
+ */
+static void r2net_shutdown_sc(struct work_struct *work)
+{
+	struct r2net_sock_container *sc =
+		container_of(work, struct r2net_sock_container,
+			     sc_shutdown_work);
+	struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num);
+
+	sclog(sc, "shutting down\n");
+
+	/* drop the callbacks ref and call shutdown only once */
+	if (r2net_unregister_callbacks(sc->sc_sock->sk, sc)) {
+		/* we shouldn't flush as we're in the thread, the
+		 * races with pending sc work structs are harmless */
+		del_timer_sync(&sc->sc_idle_timeout);
+		r2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
+		sc_put(sc);
+		kernel_sock_shutdown(sc->sc_sock, SHUT_RDWR);
+	}
+
+	/* not fatal so failed connects before the other guy has our
+	 * heartbeat can be retried */
+	r2net_ensure_shutdown(nn, sc, 0);
+	sc_put(sc);
+}
+
+/* ------------------------------------------------------------ */
+
+static int r2net_handler_cmp(struct r2net_msg_handler *nmh, u32 msg_type,
+			     u32 key)
+{
+	int ret = memcmp(&nmh->nh_key, &key, sizeof(key));
+
+	if (ret == 0)
+		ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type));
+
+	return ret;
+}
+
+static struct r2net_msg_handler *
+r2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p,
+				struct rb_node **ret_parent)
+{
+	struct rb_node **p = &r2net_handler_tree.rb_node;
+	struct rb_node *parent = NULL;
+	struct r2net_msg_handler *nmh, *ret = NULL;
+	int cmp;
+
+	while (*p) {
+		parent = *p;
+		nmh = rb_entry(parent, struct r2net_msg_handler, nh_node);
+		cmp = r2net_handler_cmp(nmh, msg_type, key);
+
+		if (cmp < 0)
+			p = &(*p)->rb_left;
+		else if (cmp > 0)
+			p = &(*p)->rb_right;
+		else {
+			ret = nmh;
+			break;
+		}
+	}
+
+	if (ret_p != NULL)
+		*ret_p = p;
+	if (ret_parent != NULL)
+		*ret_parent = parent;
+
+	return ret;
+}
+
+static void r2net_handler_kref_release(struct kref *kref)
+{
+	struct r2net_msg_handler *nmh;
+	nmh = container_of(kref, struct r2net_msg_handler, nh_kref);
+
+	kfree(nmh);
+}
+
+static void r2net_handler_put(struct r2net_msg_handler *nmh)
+{
+	kref_put(&nmh->nh_kref, r2net_handler_kref_release);
+}
+
+/* max_len is protection for the handler func.  incoming messages won't
+ * be given to the handler if their payload is longer than the max. */
+int r2net_register_handler(u32 msg_type, u32 key, u32 max_len,
+			   r2net_msg_handler_func *func, void *data,
+			   r2net_post_msg_handler_func *post_func,
+			   struct list_head *unreg_list)
+{
+	struct r2net_msg_handler *nmh = NULL;
+	struct rb_node **p, *parent;
+	int ret = 0;
+
+	if (max_len > R2NET_MAX_PAYLOAD_BYTES) {
+		mlog(0, "max_len for message handler out of range: %u\n",
+			max_len);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!msg_type) {
+		mlog(0, "no message type provided: %u, %p\n", msg_type, func);
+		ret = -EINVAL;
+		goto out;
+
+	}
+	if (!func) {
+		mlog(0, "no message handler provided: %u, %p\n",
+		       msg_type, func);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	nmh = kzalloc(sizeof(struct r2net_msg_handler), GFP_NOFS);
+	if (nmh == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	nmh->nh_func = func;
+	nmh->nh_func_data = data;
+	nmh->nh_post_func = post_func;
+	nmh->nh_msg_type = msg_type;
+	nmh->nh_max_len = max_len;
+	nmh->nh_key = key;
+	/* the tree and list get this ref.. they're both removed in
+	 * unregister when this ref is dropped */
+	kref_init(&nmh->nh_kref);
+	INIT_LIST_HEAD(&nmh->nh_unregister_item);
+
+	write_lock(&r2net_handler_lock);
+	if (r2net_handler_tree_lookup(msg_type, key, &p, &parent))
+		ret = -EEXIST;
+	else {
+		rb_link_node(&nmh->nh_node, parent, p);
+		rb_insert_color(&nmh->nh_node, &r2net_handler_tree);
+		list_add_tail(&nmh->nh_unregister_item, unreg_list);
+
+		mlog(ML_TCP, "registered handler func %p type %u key %08x\n",
+		     func, msg_type, key);
+		/* we've had some trouble with handlers seemingly vanishing. */
+		mlog_bug_on_msg(r2net_handler_tree_lookup(msg_type, key, &p,
+							  &parent) == NULL,
+				"couldn't find handler we *just* registered "
+				"for type %u key %08x\n", msg_type, key);
+	}
+	write_unlock(&r2net_handler_lock);
+	if (ret)
+		goto out;
+
+out:
+	if (ret)
+		kfree(nmh);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(r2net_register_handler);
+
+void r2net_unregister_handler_list(struct list_head *list)
+{
+	struct r2net_msg_handler *nmh, *n;
+
+	write_lock(&r2net_handler_lock);
+	list_for_each_entry_safe(nmh, n, list, nh_unregister_item) {
+		mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n",
+		     nmh->nh_func, nmh->nh_msg_type, nmh->nh_key);
+		rb_erase(&nmh->nh_node, &r2net_handler_tree);
+		list_del_init(&nmh->nh_unregister_item);
+		kref_put(&nmh->nh_kref, r2net_handler_kref_release);
+	}
+	write_unlock(&r2net_handler_lock);
+}
+EXPORT_SYMBOL_GPL(r2net_unregister_handler_list);
+
+static struct r2net_msg_handler *r2net_handler_get(u32 msg_type, u32 key)
+{
+	struct r2net_msg_handler *nmh;
+
+	read_lock(&r2net_handler_lock);
+	nmh = r2net_handler_tree_lookup(msg_type, key, NULL, NULL);
+	if (nmh)
+		kref_get(&nmh->nh_kref);
+	read_unlock(&r2net_handler_lock);
+
+	return nmh;
+}
+
+/* ------------------------------------------------------------ */
+
+static int r2net_recv_tcp_msg(struct socket *sock, void *data, size_t len)
+{
+	int ret;
+	mm_segment_t oldfs;
+	struct kvec vec = {
+		.iov_len = len,
+		.iov_base = data,
+	};
+	struct msghdr msg = {
+		.msg_iovlen = 1,
+		.msg_iov = (struct iovec *)&vec,
+		.msg_flags = MSG_DONTWAIT,
+	};
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+	ret = sock_recvmsg(sock, &msg, len, msg.msg_flags);
+	set_fs(oldfs);
+
+	return ret;
+}
+
+static int r2net_send_tcp_msg(struct socket *sock, struct kvec *vec,
+			      size_t veclen, size_t total)
+{
+	int ret;
+	mm_segment_t oldfs;
+	struct msghdr msg = {
+		.msg_iov = (struct iovec *)vec,
+		.msg_iovlen = veclen,
+	};
+
+	if (sock == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+	ret = sock_sendmsg(sock, &msg, total);
+	set_fs(oldfs);
+	if (ret != total) {
+		mlog(ML_ERROR, "sendmsg returned %d instead of %zu\n", ret,
+		     total);
+		if (ret >= 0)
+			ret = -EPIPE; /* should be smarter, I bet */
+		goto out;
+	}
+
+	ret = 0;
+out:
+	if (ret < 0)
+		mlog(0, "returning error: %d\n", ret);
+	return ret;
+}
+
+static void r2net_sendpage(struct r2net_sock_container *sc,
+			   void *kmalloced_virt,
+			   size_t size)
+{
+	struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num);
+	ssize_t ret;
+
+	while (1) {
+		mutex_lock(&sc->sc_send_lock);
+		ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
+					virt_to_page(kmalloced_virt),
+					(long)kmalloced_virt & ~PAGE_MASK,
+					size, MSG_DONTWAIT);
+		mutex_unlock(&sc->sc_send_lock);
+		if (ret == size)
+			break;
+		if (ret == (ssize_t)-EAGAIN) {
+			mlog(0, "sendpage of size %zu to " SC_NODEF_FMT
+			     " returned EAGAIN\n", size, sc->sc_node->nd_name,
+				sc->sc_node->nd_num,
+				&sc->sc_node->nd_ipv4_address,
+				ntohs(sc->sc_node->nd_ipv4_port));
+			cond_resched();
+			continue;
+		}
+		mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT
+		     " failed with %zd\n", size, sc->sc_node->nd_name,
+			sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port), ret);
+		r2net_ensure_shutdown(nn, sc, 0);
+		break;
+	}
+}
+
+static void r2net_init_msg(struct r2net_msg *msg, u16 data_len,
+				u16 msg_type, u32 key)
+{
+	memset(msg, 0, sizeof(struct r2net_msg));
+	msg->magic = cpu_to_be16(R2NET_MSG_MAGIC);
+	msg->data_len = cpu_to_be16(data_len);
+	msg->msg_type = cpu_to_be16(msg_type);
+	msg->sys_status = cpu_to_be32(R2NET_ERR_NONE);
+	msg->status = 0;
+	msg->key = cpu_to_be32(key);
+}
+
+static int r2net_tx_can_proceed(struct r2net_node *nn,
+				struct r2net_sock_container **sc_ret,
+				int *error)
+{
+	int ret = 0;
+
+	spin_lock(&nn->nn_lock);
+	if (nn->nn_persistent_error) {
+		ret = 1;
+		*sc_ret = NULL;
+		*error = nn->nn_persistent_error;
+	} else if (nn->nn_sc_valid) {
+		kref_get(&nn->nn_sc->sc_kref);
+
+		ret = 1;
+		*sc_ret = nn->nn_sc;
+		*error = 0;
+	}
+	spin_unlock(&nn->nn_lock);
+
+	return ret;
+}
+
+/* Get a map of all nodes to which this node is currently connected to */
+void r2net_fill_node_map(unsigned long *map, unsigned bytes)
+{
+	struct r2net_sock_container *sc;
+	int node, ret;
+
+	BUG_ON(bytes < (BITS_TO_LONGS(R2NM_MAX_NODES) * sizeof(unsigned long)));
+
+	memset(map, 0, bytes);
+	for (node = 0; node < R2NM_MAX_NODES; ++node) {
+		r2net_tx_can_proceed(r2net_nn_from_num(node), &sc, &ret);
+		if (!ret) {
+			set_bit(node, map);
+			sc_put(sc);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(r2net_fill_node_map);
+
+int r2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
+			   size_t caller_veclen, u8 target_node, int *status)
+{
+	int ret = 0;
+	struct r2net_msg *msg = NULL;
+	size_t veclen, caller_bytes = 0;
+	struct kvec *vec = NULL;
+	struct r2net_sock_container *sc = NULL;
+	struct r2net_node *nn = r2net_nn_from_num(target_node);
+	struct r2net_status_wait nsw = {
+		.ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item),
+	};
+	struct r2net_send_tracking nst;
+
+	/* this may be a general bug fix */
+	init_waitqueue_head(&nsw.ns_wq);
+
+	r2net_init_nst(&nst, msg_type, key, current, target_node);
+
+	if (r2net_wq == NULL) {
+		mlog(0, "attempt to tx without r2netd running\n");
+		ret = -ESRCH;
+		goto out;
+	}
+
+	if (caller_veclen == 0) {
+		mlog(0, "bad kvec array length\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	caller_bytes = iov_length((struct iovec *)caller_vec, caller_veclen);
+	if (caller_bytes > R2NET_MAX_PAYLOAD_BYTES) {
+		mlog(0, "total payload len %zu too large\n", caller_bytes);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (target_node == r2nm_this_node()) {
+		ret = -ELOOP;
+		goto out;
+	}
+
+	r2net_debug_add_nst(&nst);
+
+	r2net_set_nst_sock_time(&nst);
+
+	wait_event(nn->nn_sc_wq, r2net_tx_can_proceed(nn, &sc, &ret));
+	if (ret)
+		goto out;
+
+	r2net_set_nst_sock_container(&nst, sc);
+
+	veclen = caller_veclen + 1;
+	vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC);
+	if (vec == NULL) {
+		mlog(0, "failed to %zu element kvec!\n", veclen);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	msg = kmalloc(sizeof(struct r2net_msg), GFP_ATOMIC);
+	if (!msg) {
+		mlog(0, "failed to allocate a r2net_msg!\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	r2net_init_msg(msg, caller_bytes, msg_type, key);
+
+	vec[0].iov_len = sizeof(struct r2net_msg);
+	vec[0].iov_base = msg;
+	memcpy(&vec[1], caller_vec, caller_veclen * sizeof(struct kvec));
+
+	ret = r2net_prep_nsw(nn, &nsw);
+	if (ret)
+		goto out;
+
+	msg->msg_num = cpu_to_be32(nsw.ns_id);
+	r2net_set_nst_msg_id(&nst, nsw.ns_id);
+
+	r2net_set_nst_send_time(&nst);
+
+	/* finally, convert the message header to network byte-order
+	 * and send */
+	mutex_lock(&sc->sc_send_lock);
+	ret = r2net_send_tcp_msg(sc->sc_sock, vec, veclen,
+				 sizeof(struct r2net_msg) + caller_bytes);
+	mutex_unlock(&sc->sc_send_lock);
+	msglog(msg, "sending returned %d\n", ret);
+	if (ret < 0) {
+		mlog(0, "error returned from r2net_send_tcp_msg=%d\n", ret);
+		goto out;
+	}
+
+	/* wait on other node's handler */
+	r2net_set_nst_status_time(&nst);
+	wait_event(nsw.ns_wq, r2net_nsw_completed(nn, &nsw));
+
+	r2net_update_send_stats(&nst, sc);
+
+	/* Note that we avoid overwriting the callers status return
+	 * variable if a system error was reported on the other
+	 * side. Callers beware. */
+	ret = r2net_sys_err_to_errno(nsw.ns_sys_status);
+	if (status && !ret)
+		*status = nsw.ns_status;
+
+	mlog(0, "woken, returning system status %d, user status %d\n",
+	     ret, nsw.ns_status);
+out:
+	r2net_debug_del_nst(&nst); /* must be before dropping sc and node */
+	if (sc)
+		sc_put(sc);
+	kfree(vec);
+	kfree(msg);
+	r2net_complete_nsw(nn, &nsw, 0, 0, 0);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(r2net_send_message_vec);
+
+int r2net_send_message(u32 msg_type, u32 key, void *data, u32 len,
+		       u8 target_node, int *status)
+{
+	struct kvec vec = {
+		.iov_base = data,
+		.iov_len = len,
+	};
+	return r2net_send_message_vec(msg_type, key, &vec, 1,
+				      target_node, status);
+}
+EXPORT_SYMBOL_GPL(r2net_send_message);
+
+static int r2net_send_status_magic(struct socket *sock, struct r2net_msg *hdr,
+				   enum r2net_system_error syserr, int err)
+{
+	struct kvec vec = {
+		.iov_base = hdr,
+		.iov_len = sizeof(struct r2net_msg),
+	};
+
+	BUG_ON(syserr >= R2NET_ERR_MAX);
+
+	/* leave other fields intact from the incoming message, msg_num
+	 * in particular */
+	hdr->sys_status = cpu_to_be32(syserr);
+	hdr->status = cpu_to_be32(err);
+	/* twiddle the magic */
+	hdr->magic = cpu_to_be16(R2NET_MSG_STATUS_MAGIC);
+	hdr->data_len = 0;
+
+	msglog(hdr, "about to send status magic %d\n", err);
+	/* hdr has been in host byteorder this whole time */
+	return r2net_send_tcp_msg(sock, &vec, 1, sizeof(struct r2net_msg));
+}
+
+/*
+ * "data magic" is a long version of "status magic" where the message
+ * payload actually contains data to be passed in reply to certain messages
+ */
+static int r2net_send_data_magic(struct r2net_sock_container *sc,
+			  struct r2net_msg *hdr,
+			  void *data, size_t data_len,
+			  enum r2net_system_error syserr, int err)
+{
+	struct kvec vec[2];
+	int ret;
+
+	vec[0].iov_base = hdr;
+	vec[0].iov_len = sizeof(struct r2net_msg);
+	vec[1].iov_base = data;
+	vec[1].iov_len = data_len;
+
+	BUG_ON(syserr >= R2NET_ERR_MAX);
+
+	/* leave other fields intact from the incoming message, msg_num
+	 * in particular */
+	hdr->sys_status = cpu_to_be32(syserr);
+	hdr->status = cpu_to_be32(err);
+	hdr->magic = cpu_to_be16(R2NET_MSG_DATA_MAGIC);  /* twiddle magic */
+	hdr->data_len = cpu_to_be16(data_len);
+
+	msglog(hdr, "about to send data magic %d\n", err);
+	/* hdr has been in host byteorder this whole time */
+	ret = r2net_send_tcp_msg(sc->sc_sock, vec, 2,
+			sizeof(struct r2net_msg) + data_len);
+	return ret;
+}
+
+/*
+ * called by a message handler to convert an otherwise normal reply
+ * message into a "data magic" message
+ */
+void r2net_force_data_magic(struct r2net_msg *hdr, u16 msgtype, u32 msgkey)
+{
+	hdr->magic = cpu_to_be16(R2NET_MSG_DATA_MAGIC);
+	hdr->msg_type = cpu_to_be16(msgtype);
+	hdr->key = cpu_to_be32(msgkey);
+}
+
+/* this returns -errno if the header was unknown or too large, etc.
+ * after this is called the buffer us reused for the next message */
+static int r2net_process_message(struct r2net_sock_container *sc,
+				 struct r2net_msg *hdr)
+{
+	struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num);
+	int ret = 0, handler_status;
+	enum  r2net_system_error syserr;
+	struct r2net_msg_handler *nmh = NULL;
+	void *ret_data = NULL;
+	int data_magic = 0;
+
+	msglog(hdr, "processing message\n");
+
+	r2net_sc_postpone_idle(sc);
+
+	switch (be16_to_cpu(hdr->magic)) {
+
+	case R2NET_MSG_STATUS_MAGIC:
+		/* special type for returning message status */
+		r2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num),
+						be32_to_cpu(hdr->sys_status),
+						be32_to_cpu(hdr->status));
+		goto out;
+	case R2NET_MSG_KEEP_REQ_MAGIC:
+		r2net_sendpage(sc, r2net_keep_resp, sizeof(*r2net_keep_resp));
+		goto out;
+	case R2NET_MSG_KEEP_RESP_MAGIC:
+		goto out;
+	case R2NET_MSG_MAGIC:
+		break;
+	case R2NET_MSG_DATA_MAGIC:
+		/*
+		 * unlike a normal status magic, a data magic DOES
+		 * (MUST) have a handler, so the control flow is
+		 * a little funky here as a result
+		 */
+		data_magic = 1;
+		break;
+	default:
+		msglog(hdr, "bad magic\n");
+		ret = -EINVAL;
+		goto out;
+		break;
+	}
+
+	/* find a handler for it */
+	handler_status = 0;
+	nmh = r2net_handler_get(be16_to_cpu(hdr->msg_type),
+				be32_to_cpu(hdr->key));
+	if (!nmh) {
+		mlog(ML_TCP, "couldn't find handler for type %u key %08x\n",
+		     be16_to_cpu(hdr->msg_type), be32_to_cpu(hdr->key));
+		syserr = R2NET_ERR_NO_HNDLR;
+		goto out_respond;
+	}
+
+	syserr = R2NET_ERR_NONE;
+
+	if (be16_to_cpu(hdr->data_len) > nmh->nh_max_len)
+		syserr = R2NET_ERR_OVERFLOW;
+
+	if (syserr != R2NET_ERR_NONE)
+		goto out_respond;
+
+	r2net_set_func_start_time(sc);
+	sc->sc_msg_key = be32_to_cpu(hdr->key);
+	sc->sc_msg_type = be16_to_cpu(hdr->msg_type);
+	handler_status = (nmh->nh_func)(hdr, sizeof(struct r2net_msg) +
+					     be16_to_cpu(hdr->data_len),
+					nmh->nh_func_data, &ret_data);
+	if (data_magic) {
+		/*
+		 * handler handled data sent in reply to request
+		 * so complete the transaction
+		 */
+		r2net_complete_nsw(nn, NULL, be32_to_cpu(hdr->msg_num),
+			be32_to_cpu(hdr->sys_status), handler_status);
+		goto out;
+	}
+	/*
+	 * handler changed magic to DATA_MAGIC to reply to request for data,
+	 * implies ret_data points to data to return and handler_status
+	 * is the number of bytes of data
+	 */
+	if (be16_to_cpu(hdr->magic) == R2NET_MSG_DATA_MAGIC) {
+		ret = r2net_send_data_magic(sc, hdr,
+						ret_data, handler_status,
+						syserr, 0);
+		hdr = NULL;
+		mlog(0, "sending data reply %d, syserr %d returned %d\n",
+			handler_status, syserr, ret);
+		r2net_set_func_stop_time(sc);
+
+		r2net_update_recv_stats(sc);
+		goto out;
+	}
+	r2net_set_func_stop_time(sc);
+
+	r2net_update_recv_stats(sc);
+
+out_respond:
+	/* this destroys the hdr, so don't use it after this */
+	mutex_lock(&sc->sc_send_lock);
+	ret = r2net_send_status_magic(sc->sc_sock, hdr, syserr,
+				      handler_status);
+	mutex_unlock(&sc->sc_send_lock);
+	hdr = NULL;
+	mlog(0, "sending handler status %d, syserr %d returned %d\n",
+	     handler_status, syserr, ret);
+
+	if (nmh) {
+		BUG_ON(ret_data != NULL && nmh->nh_post_func == NULL);
+		if (nmh->nh_post_func)
+			(nmh->nh_post_func)(handler_status, nmh->nh_func_data,
+					    ret_data);
+	}
+
+out:
+	if (nmh)
+		r2net_handler_put(nmh);
+	return ret;
+}
+
+static int r2net_check_handshake(struct r2net_sock_container *sc)
+{
+	struct r2net_handshake *hand = page_address(sc->sc_page);
+	struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num);
+
+	if (hand->protocol_version != cpu_to_be64(R2NET_PROTOCOL_VERSION)) {
+		printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " Advertised net "
+		       "protocol version %llu but %llu is required. "
+		       "Disconnecting.\n", sc->sc_node->nd_name,
+			sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port),
+		       (unsigned long long)be64_to_cpu(hand->protocol_version),
+		       R2NET_PROTOCOL_VERSION);
+
+		/* don't bother reconnecting if its the wrong version. */
+		r2net_ensure_shutdown(nn, sc, -ENOTCONN);
+		return -1;
+	}
+
+	/*
+	 * Ensure timeouts are consistent with other nodes, otherwise
+	 * we can end up with one node thinking that the other must be down,
+	 * but isn't. This can ultimately cause corruption.
+	 */
+	if (be32_to_cpu(hand->r2net_idle_timeout_ms) !=
+				r2net_idle_timeout()) {
+		printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " uses a network "
+		       "idle timeout of %u ms, but we use %u ms locally. "
+		       "Disconnecting.\n", sc->sc_node->nd_name,
+			sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port),
+		       be32_to_cpu(hand->r2net_idle_timeout_ms),
+		       r2net_idle_timeout());
+		r2net_ensure_shutdown(nn, sc, -ENOTCONN);
+		return -1;
+	}
+
+	if (be32_to_cpu(hand->r2net_keepalive_delay_ms) !=
+			r2net_keepalive_delay()) {
+		printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " uses a keepalive "
+		       "delay of %u ms, but we use %u ms locally. "
+		       "Disconnecting.\n", sc->sc_node->nd_name,
+			sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port),
+		       be32_to_cpu(hand->r2net_keepalive_delay_ms),
+		       r2net_keepalive_delay());
+		r2net_ensure_shutdown(nn, sc, -ENOTCONN);
+		return -1;
+	}
+
+	if (be32_to_cpu(hand->r2hb_heartbeat_timeout_ms) !=
+			R2HB_MAX_WRITE_TIMEOUT_MS) {
+		printk(KERN_NOTICE "ramster: " SC_NODEF_FMT " uses a heartbeat "
+		       "timeout of %u ms, but we use %u ms locally. "
+		       "Disconnecting.\n", sc->sc_node->nd_name,
+			sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port),
+		       be32_to_cpu(hand->r2hb_heartbeat_timeout_ms),
+		       R2HB_MAX_WRITE_TIMEOUT_MS);
+		r2net_ensure_shutdown(nn, sc, -ENOTCONN);
+		return -1;
+	}
+
+	sc->sc_handshake_ok = 1;
+
+	spin_lock(&nn->nn_lock);
+	/* set valid and queue the idle timers only if it hasn't been
+	 * shut down already */
+	if (nn->nn_sc == sc) {
+		r2net_sc_reset_idle_timer(sc);
+		atomic_set(&nn->nn_timeout, 0);
+		r2net_set_nn_state(nn, sc, 1, 0);
+	}
+	spin_unlock(&nn->nn_lock);
+
+	/* shift everything up as though it wasn't there */
+	sc->sc_page_off -= sizeof(struct r2net_handshake);
+	if (sc->sc_page_off)
+		memmove(hand, hand + 1, sc->sc_page_off);
+
+	return 0;
+}
+
+/* this demuxes the queued rx bytes into header or payload bits and calls
+ * handlers as each full message is read off the socket.  it returns -error,
+ * == 0 eof, or > 0 for progress made.*/
+static int r2net_advance_rx(struct r2net_sock_container *sc)
+{
+	struct r2net_msg *hdr;
+	int ret = 0;
+	void *data;
+	size_t datalen;
+
+	sclog(sc, "receiving\n");
+	r2net_set_advance_start_time(sc);
+
+	if (unlikely(sc->sc_handshake_ok == 0)) {
+		if (sc->sc_page_off < sizeof(struct r2net_handshake)) {
+			data = page_address(sc->sc_page) + sc->sc_page_off;
+			datalen = sizeof(struct r2net_handshake) -
+							sc->sc_page_off;
+			ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen);
+			if (ret > 0)
+				sc->sc_page_off += ret;
+		}
+
+		if (sc->sc_page_off == sizeof(struct r2net_handshake)) {
+			r2net_check_handshake(sc);
+			if (unlikely(sc->sc_handshake_ok == 0))
+				ret = -EPROTO;
+		}
+		goto out;
+	}
+
+	/* do we need more header? */
+	if (sc->sc_page_off < sizeof(struct r2net_msg)) {
+		data = page_address(sc->sc_page) + sc->sc_page_off;
+		datalen = sizeof(struct r2net_msg) - sc->sc_page_off;
+		ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen);
+		if (ret > 0) {
+			sc->sc_page_off += ret;
+			/* only swab incoming here.. we can
+			 * only get here once as we cross from
+			 * being under to over */
+			if (sc->sc_page_off == sizeof(struct r2net_msg)) {
+				hdr = page_address(sc->sc_page);
+				if (be16_to_cpu(hdr->data_len) >
+				    R2NET_MAX_PAYLOAD_BYTES)
+					ret = -EOVERFLOW;
+			}
+		}
+		if (ret <= 0)
+			goto out;
+	}
+
+	if (sc->sc_page_off < sizeof(struct r2net_msg)) {
+		/* oof, still don't have a header */
+		goto out;
+	}
+
+	/* this was swabbed above when we first read it */
+	hdr = page_address(sc->sc_page);
+
+	msglog(hdr, "at page_off %zu\n", sc->sc_page_off);
+
+	/* do we need more payload? */
+	if (sc->sc_page_off - sizeof(struct r2net_msg) <
+					be16_to_cpu(hdr->data_len)) {
+		/* need more payload */
+		data = page_address(sc->sc_page) + sc->sc_page_off;
+		datalen = (sizeof(struct r2net_msg) +
+				be16_to_cpu(hdr->data_len)) -
+				sc->sc_page_off;
+		ret = r2net_recv_tcp_msg(sc->sc_sock, data, datalen);
+		if (ret > 0)
+			sc->sc_page_off += ret;
+		if (ret <= 0)
+			goto out;
+	}
+
+	if (sc->sc_page_off - sizeof(struct r2net_msg) ==
+						be16_to_cpu(hdr->data_len)) {
+		/* we can only get here once, the first time we read
+		 * the payload.. so set ret to progress if the handler
+		 * works out. after calling this the message is toast */
+		ret = r2net_process_message(sc, hdr);
+		if (ret == 0)
+			ret = 1;
+		sc->sc_page_off = 0;
+	}
+
+out:
+	sclog(sc, "ret = %d\n", ret);
+	r2net_set_advance_stop_time(sc);
+	return ret;
+}
+
+/* this work func is triggerd by data ready.  it reads until it can read no
+ * more.  it interprets 0, eof, as fatal.  if data_ready hits while we're doing
+ * our work the work struct will be marked and we'll be called again. */
+static void r2net_rx_until_empty(struct work_struct *work)
+{
+	struct r2net_sock_container *sc =
+		container_of(work, struct r2net_sock_container, sc_rx_work);
+	int ret;
+
+	do {
+		ret = r2net_advance_rx(sc);
+	} while (ret > 0);
+
+	if (ret <= 0 && ret != -EAGAIN) {
+		struct r2net_node *nn = r2net_nn_from_num(sc->sc_node->nd_num);
+		sclog(sc, "saw error %d, closing\n", ret);
+		/* not permanent so read failed handshake can retry */
+		r2net_ensure_shutdown(nn, sc, 0);
+	}
+
+	sc_put(sc);
+}
+
+static int r2net_set_nodelay(struct socket *sock)
+{
+	int ret, val = 1;
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	/*
+	 * Dear unsuspecting programmer,
+	 *
+	 * Don't use sock_setsockopt() for SOL_TCP.  It doesn't check its level
+	 * argument and assumes SOL_SOCKET so, say, your TCP_NODELAY will
+	 * silently turn into SO_DEBUG.
+	 *
+	 * Yours,
+	 * Keeper of hilariously fragile interfaces.
+	 */
+	ret = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY,
+				    (char __user *)&val, sizeof(val));
+
+	set_fs(oldfs);
+	return ret;
+}
+
+static void r2net_initialize_handshake(void)
+{
+	r2net_hand->r2hb_heartbeat_timeout_ms = cpu_to_be32(
+		R2HB_MAX_WRITE_TIMEOUT_MS);
+	r2net_hand->r2net_idle_timeout_ms = cpu_to_be32(r2net_idle_timeout());
+	r2net_hand->r2net_keepalive_delay_ms = cpu_to_be32(
+		r2net_keepalive_delay());
+	r2net_hand->r2net_reconnect_delay_ms = cpu_to_be32(
+		r2net_reconnect_delay());
+}
+
+/* ------------------------------------------------------------ */
+
+/* called when a connect completes and after a sock is accepted.  the
+ * rx path will see the response and mark the sc valid */
+static void r2net_sc_connect_completed(struct work_struct *work)
+{
+	struct r2net_sock_container *sc =
+			container_of(work, struct r2net_sock_container,
+			     sc_connect_work);
+
+	mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n",
+		(unsigned long long)R2NET_PROTOCOL_VERSION,
+		(unsigned long long)be64_to_cpu(r2net_hand->connector_id));
+
+	r2net_initialize_handshake();
+	r2net_sendpage(sc, r2net_hand, sizeof(*r2net_hand));
+	sc_put(sc);
+}
+
+/* this is called as a work_struct func. */
+static void r2net_sc_send_keep_req(struct work_struct *work)
+{
+	struct r2net_sock_container *sc =
+		container_of(work, struct r2net_sock_container,
+			     sc_keepalive_work.work);
+
+	r2net_sendpage(sc, r2net_keep_req, sizeof(*r2net_keep_req));
+	sc_put(sc);
+}
+
+/* socket shutdown does a del_timer_sync against this as it tears down.
+ * we can't start this timer until we've got to the point in sc buildup
+ * where shutdown is going to be involved */
+static void r2net_idle_timer(unsigned long data)
+{
+	struct r2net_sock_container *sc = (struct r2net_sock_container *)data;
+#ifdef CONFIG_DEBUG_FS
+	unsigned long msecs = ktime_to_ms(ktime_get()) -
+		ktime_to_ms(sc->sc_tv_timer);
+#else
+	unsigned long msecs = r2net_idle_timeout();
+#endif
+
+	printk(KERN_NOTICE "ramster: Connection to " SC_NODEF_FMT " has been "
+	       "idle for %lu.%lu secs, shutting it down.\n",
+		sc->sc_node->nd_name, sc->sc_node->nd_num,
+		&sc->sc_node->nd_ipv4_address, ntohs(sc->sc_node->nd_ipv4_port),
+	       msecs / 1000, msecs % 1000);
+
+	/*
+	 * Initialize the nn_timeout so that the next connection attempt
+	 * will continue in r2net_start_connect.
+	 */
+	/* Avoid spurious shutdowns... not sure if this is still necessary */
+	pr_err("ramster_idle_timer, skipping shutdown work\n");
+#if 0
+	/* old code used to do these two lines */
+	atomic_set(&nn->nn_timeout, 1);
+	r2net_sc_queue_work(sc, &sc->sc_shutdown_work);
+#endif
+}
+
+static void r2net_sc_reset_idle_timer(struct r2net_sock_container *sc)
+{
+	r2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
+	r2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work,
+		      msecs_to_jiffies(r2net_keepalive_delay()));
+	r2net_set_sock_timer(sc);
+	mod_timer(&sc->sc_idle_timeout,
+	       jiffies + msecs_to_jiffies(r2net_idle_timeout()));
+}
+
+static void r2net_sc_postpone_idle(struct r2net_sock_container *sc)
+{
+	/* Only push out an existing timer */
+	if (timer_pending(&sc->sc_idle_timeout))
+		r2net_sc_reset_idle_timer(sc);
+}
+
+/* this work func is kicked whenever a path sets the nn state which doesn't
+ * have valid set.  This includes seeing hb come up, losing a connection,
+ * having a connect attempt fail, etc. This centralizes the logic which decides
+ * if a connect attempt should be made or if we should give up and all future
+ * transmit attempts should fail */
+static void r2net_start_connect(struct work_struct *work)
+{
+	struct r2net_node *nn =
+		container_of(work, struct r2net_node, nn_connect_work.work);
+	struct r2net_sock_container *sc = NULL;
+	struct r2nm_node *node = NULL, *mynode = NULL;
+	struct socket *sock = NULL;
+	struct sockaddr_in myaddr = {0, }, remoteaddr = {0, };
+	int ret = 0, stop;
+	unsigned int timeout;
+
+	/* if we're greater we initiate tx, otherwise we accept */
+	if (r2nm_this_node() <= r2net_num_from_nn(nn))
+		goto out;
+
+	/* watch for racing with tearing a node down */
+	node = r2nm_get_node_by_num(r2net_num_from_nn(nn));
+	if (node == NULL) {
+		ret = 0;
+		goto out;
+	}
+
+	mynode = r2nm_get_node_by_num(r2nm_this_node());
+	if (mynode == NULL) {
+		ret = 0;
+		goto out;
+	}
+
+	spin_lock(&nn->nn_lock);
+	/*
+	 * see if we already have one pending or have given up.
+	 * For nn_timeout, it is set when we close the connection
+	 * because of the idle time out. So it means that we have
+	 * at least connected to that node successfully once,
+	 * now try to connect to it again.
+	 */
+	timeout = atomic_read(&nn->nn_timeout);
+	stop = (nn->nn_sc ||
+		(nn->nn_persistent_error &&
+		(nn->nn_persistent_error != -ENOTCONN || timeout == 0)));
+	spin_unlock(&nn->nn_lock);
+	if (stop)
+		goto out;
+
+	nn->nn_last_connect_attempt = jiffies;
+
+	sc = sc_alloc(node);
+	if (sc == NULL) {
+		mlog(0, "couldn't allocate sc\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0) {
+		mlog(0, "can't create socket: %d\n", ret);
+		goto out;
+	}
+	sc->sc_sock = sock; /* freed by sc_kref_release */
+
+	sock->sk->sk_allocation = GFP_ATOMIC;
+
+	myaddr.sin_family = AF_INET;
+	myaddr.sin_addr.s_addr = mynode->nd_ipv4_address;
+	myaddr.sin_port = htons(0); /* any port */
+
+	ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr,
+			      sizeof(myaddr));
+	if (ret) {
+		mlog(ML_ERROR, "bind failed with %d at address %pI4\n",
+		     ret, &mynode->nd_ipv4_address);
+		goto out;
+	}
+
+	ret = r2net_set_nodelay(sc->sc_sock);
+	if (ret) {
+		mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret);
+		goto out;
+	}
+
+	r2net_register_callbacks(sc->sc_sock->sk, sc);
+
+	spin_lock(&nn->nn_lock);
+	/* handshake completion will set nn->nn_sc_valid */
+	r2net_set_nn_state(nn, sc, 0, 0);
+	spin_unlock(&nn->nn_lock);
+
+	remoteaddr.sin_family = AF_INET;
+	remoteaddr.sin_addr.s_addr = node->nd_ipv4_address;
+	remoteaddr.sin_port = node->nd_ipv4_port;
+
+	ret = sc->sc_sock->ops->connect(sc->sc_sock,
+					(struct sockaddr *)&remoteaddr,
+					sizeof(remoteaddr),
+					O_NONBLOCK);
+	if (ret == -EINPROGRESS)
+		ret = 0;
+
+out:
+	if (ret) {
+		printk(KERN_NOTICE "ramster: Connect attempt to " SC_NODEF_FMT
+		       " failed with errno %d\n", sc->sc_node->nd_name,
+			sc->sc_node->nd_num, &sc->sc_node->nd_ipv4_address,
+			ntohs(sc->sc_node->nd_ipv4_port), ret);
+		/* 0 err so that another will be queued and attempted
+		 * from set_nn_state */
+		if (sc)
+			r2net_ensure_shutdown(nn, sc, 0);
+	}
+	if (sc)
+		sc_put(sc);
+	if (node)
+		r2nm_node_put(node);
+	if (mynode)
+		r2nm_node_put(mynode);
+
+	return;
+}
+
+static void r2net_connect_expired(struct work_struct *work)
+{
+	struct r2net_node *nn =
+		container_of(work, struct r2net_node, nn_connect_expired.work);
+
+	spin_lock(&nn->nn_lock);
+	if (!nn->nn_sc_valid) {
+		printk(KERN_NOTICE "ramster: No connection established with "
+		       "node %u after %u.%u seconds, giving up.\n",
+		     r2net_num_from_nn(nn),
+		     r2net_idle_timeout() / 1000,
+		     r2net_idle_timeout() % 1000);
+
+		r2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
+	}
+	spin_unlock(&nn->nn_lock);
+}
+
+static void r2net_still_up(struct work_struct *work)
+{
+}
+
+/* ------------------------------------------------------------ */
+
+void r2net_disconnect_node(struct r2nm_node *node)
+{
+	struct r2net_node *nn = r2net_nn_from_num(node->nd_num);
+
+	/* don't reconnect until it's heartbeating again */
+	spin_lock(&nn->nn_lock);
+	atomic_set(&nn->nn_timeout, 0);
+	r2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
+	spin_unlock(&nn->nn_lock);
+
+	if (r2net_wq) {
+		cancel_delayed_work(&nn->nn_connect_expired);
+		cancel_delayed_work(&nn->nn_connect_work);
+		cancel_delayed_work(&nn->nn_still_up);
+		flush_workqueue(r2net_wq);
+	}
+}
+
+static void r2net_hb_node_down_cb(struct r2nm_node *node, int node_num,
+				  void *data)
+{
+	if (!node)
+		return;
+
+	if (node_num != r2nm_this_node())
+		r2net_disconnect_node(node);
+
+	BUG_ON(atomic_read(&r2net_connected_peers) < 0);
+}
+
+static void r2net_hb_node_up_cb(struct r2nm_node *node, int node_num,
+				void *data)
+{
+	struct r2net_node *nn = r2net_nn_from_num(node_num);
+
+	BUG_ON(!node);
+
+	/* ensure an immediate connect attempt */
+	nn->nn_last_connect_attempt = jiffies -
+		(msecs_to_jiffies(r2net_reconnect_delay()) + 1);
+
+	if (node_num != r2nm_this_node()) {
+		/* believe it or not, accept and node hearbeating testing
+		 * can succeed for this node before we got here.. so
+		 * only use set_nn_state to clear the persistent error
+		 * if that hasn't already happened */
+		spin_lock(&nn->nn_lock);
+		atomic_set(&nn->nn_timeout, 0);
+		if (nn->nn_persistent_error)
+			r2net_set_nn_state(nn, NULL, 0, 0);
+		spin_unlock(&nn->nn_lock);
+	}
+}
+
+void r2net_unregister_hb_callbacks(void)
+{
+	r2hb_unregister_callback(NULL, &r2net_hb_up);
+	r2hb_unregister_callback(NULL, &r2net_hb_down);
+}
+
+int r2net_register_hb_callbacks(void)
+{
+	int ret;
+
+	r2hb_setup_callback(&r2net_hb_down, R2HB_NODE_DOWN_CB,
+			    r2net_hb_node_down_cb, NULL, R2NET_HB_PRI);
+	r2hb_setup_callback(&r2net_hb_up, R2HB_NODE_UP_CB,
+			    r2net_hb_node_up_cb, NULL, R2NET_HB_PRI);
+
+	ret = r2hb_register_callback(NULL, &r2net_hb_up);
+	if (ret == 0)
+		ret = r2hb_register_callback(NULL, &r2net_hb_down);
+
+	if (ret)
+		r2net_unregister_hb_callbacks();
+
+	return ret;
+}
+
+/* ------------------------------------------------------------ */
+
+static int r2net_accept_one(struct socket *sock)
+{
+	int ret, slen;
+	struct sockaddr_in sin;
+	struct socket *new_sock = NULL;
+	struct r2nm_node *node = NULL;
+	struct r2nm_node *local_node = NULL;
+	struct r2net_sock_container *sc = NULL;
+	struct r2net_node *nn;
+
+	BUG_ON(sock == NULL);
+	ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
+			       sock->sk->sk_protocol, &new_sock);
+	if (ret)
+		goto out;
+
+	new_sock->type = sock->type;
+	new_sock->ops = sock->ops;
+	ret = sock->ops->accept(sock, new_sock, O_NONBLOCK);
+	if (ret < 0)
+		goto out;
+
+	new_sock->sk->sk_allocation = GFP_ATOMIC;
+
+	ret = r2net_set_nodelay(new_sock);
+	if (ret) {
+		mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret);
+		goto out;
+	}
+
+	slen = sizeof(sin);
+	ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin,
+				       &slen, 1);
+	if (ret < 0)
+		goto out;
+
+	node = r2nm_get_node_by_ip(sin.sin_addr.s_addr);
+	if (node == NULL) {
+		printk(KERN_NOTICE "ramster: Attempt to connect from unknown "
+		       "node at %pI4:%d\n", &sin.sin_addr.s_addr,
+		       ntohs(sin.sin_port));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (r2nm_this_node() >= node->nd_num) {
+		local_node = r2nm_get_node_by_num(r2nm_this_node());
+		printk(KERN_NOTICE "ramster: Unexpected connect attempt seen "
+		       "at node '%s' (%u, %pI4:%d) from node '%s' (%u, "
+		       "%pI4:%d)\n", local_node->nd_name, local_node->nd_num,
+		       &(local_node->nd_ipv4_address),
+		       ntohs(local_node->nd_ipv4_port), node->nd_name,
+		       node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* this happens all the time when the other node sees our heartbeat
+	 * and tries to connect before we see their heartbeat */
+	if (!r2hb_check_node_heartbeating_from_callback(node->nd_num)) {
+		mlog(ML_CONN, "attempt to connect from node '%s' at "
+		     "%pI4:%d but it isn't heartbeating\n",
+		     node->nd_name, &sin.sin_addr.s_addr,
+		     ntohs(sin.sin_port));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	nn = r2net_nn_from_num(node->nd_num);
+
+	spin_lock(&nn->nn_lock);
+	if (nn->nn_sc)
+		ret = -EBUSY;
+	else
+		ret = 0;
+	spin_unlock(&nn->nn_lock);
+	if (ret) {
+		printk(KERN_NOTICE "ramster: Attempt to connect from node '%s' "
+		       "at %pI4:%d but it already has an open connection\n",
+		       node->nd_name, &sin.sin_addr.s_addr,
+		       ntohs(sin.sin_port));
+		goto out;
+	}
+
+	sc = sc_alloc(node);
+	if (sc == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sc->sc_sock = new_sock;
+	new_sock = NULL;
+
+	spin_lock(&nn->nn_lock);
+	atomic_set(&nn->nn_timeout, 0);
+	r2net_set_nn_state(nn, sc, 0, 0);
+	spin_unlock(&nn->nn_lock);
+
+	r2net_register_callbacks(sc->sc_sock->sk, sc);
+	r2net_sc_queue_work(sc, &sc->sc_rx_work);
+
+	r2net_initialize_handshake();
+	r2net_sendpage(sc, r2net_hand, sizeof(*r2net_hand));
+
+out:
+	if (new_sock)
+		sock_release(new_sock);
+	if (node)
+		r2nm_node_put(node);
+	if (local_node)
+		r2nm_node_put(local_node);
+	if (sc)
+		sc_put(sc);
+	return ret;
+}
+
+static void r2net_accept_many(struct work_struct *work)
+{
+	struct socket *sock = r2net_listen_sock;
+	while (r2net_accept_one(sock) == 0)
+		cond_resched();
+}
+
+static void r2net_listen_data_ready(struct sock *sk, int bytes)
+{
+	void (*ready)(struct sock *sk, int bytes);
+
+	read_lock(&sk->sk_callback_lock);
+	ready = sk->sk_user_data;
+	if (ready == NULL) { /* check for teardown race */
+		ready = sk->sk_data_ready;
+		goto out;
+	}
+
+	/* ->sk_data_ready is also called for a newly established child socket
+	 * before it has been accepted and the acceptor has set up their
+	 * data_ready.. we only want to queue listen work for our listening
+	 * socket */
+	if (sk->sk_state == TCP_LISTEN) {
+		mlog(ML_TCP, "bytes: %d\n", bytes);
+		queue_work(r2net_wq, &r2net_listen_work);
+	}
+
+out:
+	read_unlock(&sk->sk_callback_lock);
+	ready(sk, bytes);
+}
+
+static int r2net_open_listening_sock(__be32 addr, __be16 port)
+{
+	struct socket *sock = NULL;
+	int ret;
+	struct sockaddr_in sin = {
+		.sin_family = PF_INET,
+		.sin_addr = { .s_addr = addr },
+		.sin_port = port,
+	};
+
+	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0) {
+		printk(KERN_ERR "ramster: Error %d while creating socket\n",
+			ret);
+		goto out;
+	}
+
+	sock->sk->sk_allocation = GFP_ATOMIC;
+
+	write_lock_bh(&sock->sk->sk_callback_lock);
+	sock->sk->sk_user_data = sock->sk->sk_data_ready;
+	sock->sk->sk_data_ready = r2net_listen_data_ready;
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+
+	r2net_listen_sock = sock;
+	INIT_WORK(&r2net_listen_work, r2net_accept_many);
+
+	sock->sk->sk_reuse = 1;
+	ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+	if (ret < 0) {
+		printk(KERN_ERR "ramster: Error %d while binding socket at "
+			"%pI4:%u\n", ret, &addr, ntohs(port));
+		goto out;
+	}
+
+	ret = sock->ops->listen(sock, 64);
+	if (ret < 0)
+		printk(KERN_ERR "ramster: Error %d while listening on %pI4:%u\n",
+		       ret, &addr, ntohs(port));
+
+out:
+	if (ret) {
+		r2net_listen_sock = NULL;
+		if (sock)
+			sock_release(sock);
+	}
+	return ret;
+}
+
+/*
+ * called from node manager when we should bring up our network listening
+ * socket.  node manager handles all the serialization to only call this
+ * once and to match it with r2net_stop_listening().  note,
+ * r2nm_this_node() doesn't work yet as we're being called while it
+ * is being set up.
+ */
+int r2net_start_listening(struct r2nm_node *node)
+{
+	int ret = 0;
+
+	BUG_ON(r2net_wq != NULL);
+	BUG_ON(r2net_listen_sock != NULL);
+
+	mlog(ML_KTHREAD, "starting r2net thread...\n");
+	r2net_wq = create_singlethread_workqueue("r2net");
+	if (r2net_wq == NULL) {
+		mlog(ML_ERROR, "unable to launch r2net thread\n");
+		return -ENOMEM; /* ? */
+	}
+
+	ret = r2net_open_listening_sock(node->nd_ipv4_address,
+					node->nd_ipv4_port);
+	if (ret) {
+		destroy_workqueue(r2net_wq);
+		r2net_wq = NULL;
+	}
+
+	return ret;
+}
+
+/* again, r2nm_this_node() doesn't work here as we're involved in
+ * tearing it down */
+void r2net_stop_listening(struct r2nm_node *node)
+{
+	struct socket *sock = r2net_listen_sock;
+	size_t i;
+
+	BUG_ON(r2net_wq == NULL);
+	BUG_ON(r2net_listen_sock == NULL);
+
+	/* stop the listening socket from generating work */
+	write_lock_bh(&sock->sk->sk_callback_lock);
+	sock->sk->sk_data_ready = sock->sk->sk_user_data;
+	sock->sk->sk_user_data = NULL;
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+
+	for (i = 0; i < ARRAY_SIZE(r2net_nodes); i++) {
+		struct r2nm_node *node = r2nm_get_node_by_num(i);
+		if (node) {
+			r2net_disconnect_node(node);
+			r2nm_node_put(node);
+		}
+	}
+
+	/* finish all work and tear down the work queue */
+	mlog(ML_KTHREAD, "waiting for r2net thread to exit....\n");
+	destroy_workqueue(r2net_wq);
+	r2net_wq = NULL;
+
+	sock_release(r2net_listen_sock);
+	r2net_listen_sock = NULL;
+}
+
+void r2net_hb_node_up_manual(int node_num)
+{
+	struct r2nm_node dummy;
+	if (r2nm_single_cluster == NULL)
+		pr_err("ramster: cluster not alive, node_up_manual ignored\n");
+	else {
+		r2hb_manual_set_node_heartbeating(node_num);
+		r2net_hb_node_up_cb(&dummy, node_num, NULL);
+	}
+}
+
+/* ------------------------------------------------------------ */
+
+int r2net_init(void)
+{
+	unsigned long i;
+
+	if (r2net_debugfs_init())
+		return -ENOMEM;
+
+	r2net_hand = kzalloc(sizeof(struct r2net_handshake), GFP_KERNEL);
+	r2net_keep_req = kzalloc(sizeof(struct r2net_msg), GFP_KERNEL);
+	r2net_keep_resp = kzalloc(sizeof(struct r2net_msg), GFP_KERNEL);
+	if (!r2net_hand || !r2net_keep_req || !r2net_keep_resp) {
+		kfree(r2net_hand);
+		kfree(r2net_keep_req);
+		kfree(r2net_keep_resp);
+		return -ENOMEM;
+	}
+
+	r2net_hand->protocol_version = cpu_to_be64(R2NET_PROTOCOL_VERSION);
+	r2net_hand->connector_id = cpu_to_be64(1);
+
+	r2net_keep_req->magic = cpu_to_be16(R2NET_MSG_KEEP_REQ_MAGIC);
+	r2net_keep_resp->magic = cpu_to_be16(R2NET_MSG_KEEP_RESP_MAGIC);
+
+	for (i = 0; i < ARRAY_SIZE(r2net_nodes); i++) {
+		struct r2net_node *nn = r2net_nn_from_num(i);
+
+		atomic_set(&nn->nn_timeout, 0);
+		spin_lock_init(&nn->nn_lock);
+		INIT_DELAYED_WORK(&nn->nn_connect_work, r2net_start_connect);
+		INIT_DELAYED_WORK(&nn->nn_connect_expired,
+				  r2net_connect_expired);
+		INIT_DELAYED_WORK(&nn->nn_still_up, r2net_still_up);
+		/* until we see hb from a node we'll return einval */
+		nn->nn_persistent_error = -ENOTCONN;
+		init_waitqueue_head(&nn->nn_sc_wq);
+		idr_init(&nn->nn_status_idr);
+		INIT_LIST_HEAD(&nn->nn_status_list);
+	}
+
+	return 0;
+}
+
+void r2net_exit(void)
+{
+	kfree(r2net_hand);
+	kfree(r2net_keep_req);
+	kfree(r2net_keep_resp);
+	r2net_debugfs_exit();
+}
diff --git a/drivers/staging/ramster/cluster/tcp.h b/drivers/staging/ramster/cluster/tcp.h
new file mode 100644
index 0000000..9d05833
--- /dev/null
+++ b/drivers/staging/ramster/cluster/tcp.h
@@ -0,0 +1,159 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * tcp.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef R2CLUSTER_TCP_H
+#define R2CLUSTER_TCP_H
+
+#include <linux/socket.h>
+#ifdef __KERNEL__
+#include <net/sock.h>
+#include <linux/tcp.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <linux/inet.h>
+#include <linux/in.h>
+
+struct r2net_msg {
+	__be16 magic;
+	__be16 data_len;
+	__be16 msg_type;
+	__be16 pad1;
+	__be32 sys_status;
+	__be32 status;
+	__be32 key;
+	__be32 msg_num;
+	__u8  buf[0];
+};
+
+typedef int (r2net_msg_handler_func)(struct r2net_msg *msg, u32 len, void *data,
+				     void **ret_data);
+typedef void (r2net_post_msg_handler_func)(int status, void *data,
+					   void *ret_data);
+
+#define R2NET_MAX_PAYLOAD_BYTES  (4096 - sizeof(struct r2net_msg))
+
+/* same as hb delay, we're waiting for another node to recognize our hb */
+#define R2NET_RECONNECT_DELAY_MS_DEFAULT	2000
+
+#define R2NET_KEEPALIVE_DELAY_MS_DEFAULT	2000
+#define R2NET_IDLE_TIMEOUT_MS_DEFAULT		30000
+
+
+/* TODO: figure this out.... */
+static inline int r2net_link_down(int err, struct socket *sock)
+{
+	if (sock) {
+		if (sock->sk->sk_state != TCP_ESTABLISHED &&
+			sock->sk->sk_state != TCP_CLOSE_WAIT)
+			return 1;
+	}
+
+	if (err >= 0)
+		return 0;
+	switch (err) {
+
+	/* ????????????????????????? */
+	case -ERESTARTSYS:
+	case -EBADF:
+	/* When the server has died, an ICMP port unreachable
+	 * message prompts ECONNREFUSED. */
+	case -ECONNREFUSED:
+	case -ENOTCONN:
+	case -ECONNRESET:
+	case -EPIPE:
+		return 1;
+
+	}
+	return 0;
+}
+
+enum {
+	R2NET_DRIVER_UNINITED,
+	R2NET_DRIVER_READY,
+};
+
+int r2net_send_message(u32 msg_type, u32 key, void *data, u32 len,
+		       u8 target_node, int *status);
+int r2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec,
+			   size_t veclen, u8 target_node, int *status);
+
+int r2net_register_handler(u32 msg_type, u32 key, u32 max_len,
+			   r2net_msg_handler_func *func, void *data,
+			   r2net_post_msg_handler_func *post_func,
+			   struct list_head *unreg_list);
+void r2net_unregister_handler_list(struct list_head *list);
+
+void r2net_fill_node_map(unsigned long *map, unsigned bytes);
+
+void r2net_force_data_magic(struct r2net_msg *, u16, u32);
+void r2net_hb_node_up_manual(int);
+struct r2net_node *r2net_nn_from_num(u8);
+
+struct r2nm_node;
+int r2net_register_hb_callbacks(void);
+void r2net_unregister_hb_callbacks(void);
+int r2net_start_listening(struct r2nm_node *node);
+void r2net_stop_listening(struct r2nm_node *node);
+void r2net_disconnect_node(struct r2nm_node *node);
+int r2net_num_connected_peers(void);
+
+int r2net_init(void);
+void r2net_exit(void);
+
+struct r2net_send_tracking;
+struct r2net_sock_container;
+
+#if 0
+int r2net_debugfs_init(void);
+void r2net_debugfs_exit(void);
+void r2net_debug_add_nst(struct r2net_send_tracking *nst);
+void r2net_debug_del_nst(struct r2net_send_tracking *nst);
+void r2net_debug_add_sc(struct r2net_sock_container *sc);
+void r2net_debug_del_sc(struct r2net_sock_container *sc);
+#else
+static inline int r2net_debugfs_init(void)
+{
+	return 0;
+}
+static inline void r2net_debugfs_exit(void)
+{
+}
+static inline void r2net_debug_add_nst(struct r2net_send_tracking *nst)
+{
+}
+static inline void r2net_debug_del_nst(struct r2net_send_tracking *nst)
+{
+}
+static inline void r2net_debug_add_sc(struct r2net_sock_container *sc)
+{
+}
+static inline void r2net_debug_del_sc(struct r2net_sock_container *sc)
+{
+}
+#endif	/* CONFIG_DEBUG_FS */
+
+#endif /* R2CLUSTER_TCP_H */
diff --git a/drivers/staging/ramster/cluster/tcp_internal.h b/drivers/staging/ramster/cluster/tcp_internal.h
new file mode 100644
index 0000000..4d8cc9f
--- /dev/null
+++ b/drivers/staging/ramster/cluster/tcp_internal.h
@@ -0,0 +1,248 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef R2CLUSTER_TCP_INTERNAL_H
+#define R2CLUSTER_TCP_INTERNAL_H
+
+#define R2NET_MSG_MAGIC           ((u16)0xfa55)
+#define R2NET_MSG_STATUS_MAGIC    ((u16)0xfa56)
+#define R2NET_MSG_KEEP_REQ_MAGIC  ((u16)0xfa57)
+#define R2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58)
+/*
+ * "data magic" is a long version of "status magic" where the message
+ * payload actually contains data to be passed in reply to certain messages
+ */
+#define R2NET_MSG_DATA_MAGIC      ((u16)0xfa59)
+
+/* we're delaying our quorum decision so that heartbeat will have timed
+ * out truly dead nodes by the time we come around to making decisions
+ * on their number */
+#define R2NET_QUORUM_DELAY_MS	\
+		((r2hb_dead_threshold + 2) * R2HB_REGION_TIMEOUT_MS)
+
+/*
+ * This version number represents quite a lot, unfortunately.  It not
+ * only represents the raw network message protocol on the wire but also
+ * locking semantics of the file system using the protocol.  It should
+ * be somewhere else, I'm sure, but right now it isn't.
+ *
+ * With version 11, we separate out the filesystem locking portion.  The
+ * filesystem now has a major.minor version it negotiates.  Version 11
+ * introduces this negotiation to the r2dlm protocol, and as such the
+ * version here in tcp_internal.h should not need to be bumped for
+ * filesystem locking changes.
+ *
+ * New in version 11
+ *	- Negotiation of filesystem locking in the dlm join.
+ *
+ * New in version 10:
+ *	- Meta/data locks combined
+ *
+ * New in version 9:
+ *	- All votes removed
+ *
+ * New in version 8:
+ *	- Replace delete inode votes with a cluster lock
+ *
+ * New in version 7:
+ *	- DLM join domain includes the live nodemap
+ *
+ * New in version 6:
+ *	- DLM lockres remote refcount fixes.
+ *
+ * New in version 5:
+ *	- Network timeout checking protocol
+ *
+ * New in version 4:
+ *	- Remove i_generation from lock names for better stat performance.
+ *
+ * New in version 3:
+ *	- Replace dentry votes with a cluster lock
+ *
+ * New in version 2:
+ *	- full 64 bit i_size in the metadata lock lvbs
+ *	- introduction of "rw" lock and pushing meta/data locking down
+ */
+#define R2NET_PROTOCOL_VERSION 11ULL
+struct r2net_handshake {
+	__be64	protocol_version;
+	__be64	connector_id;
+	__be32  r2hb_heartbeat_timeout_ms;
+	__be32  r2net_idle_timeout_ms;
+	__be32  r2net_keepalive_delay_ms;
+	__be32  r2net_reconnect_delay_ms;
+};
+
+struct r2net_node {
+	/* this is never called from int/bh */
+	spinlock_t			nn_lock;
+
+	/* set the moment an sc is allocated and a connect is started */
+	struct r2net_sock_container	*nn_sc;
+	/* _valid is only set after the handshake passes and tx can happen */
+	unsigned			nn_sc_valid:1;
+	/* if this is set tx just returns it */
+	int				nn_persistent_error;
+	/* It is only set to 1 after the idle time out. */
+	atomic_t			nn_timeout;
+
+	/* threads waiting for an sc to arrive wait on the wq for generation
+	 * to increase.  it is increased when a connecting socket succeeds
+	 * or fails or when an accepted socket is attached. */
+	wait_queue_head_t		nn_sc_wq;
+
+	struct idr			nn_status_idr;
+	struct list_head		nn_status_list;
+
+	/* connects are attempted from when heartbeat comes up until either hb
+	 * goes down, the node is unconfigured, no connect attempts succeed
+	 * before R2NET_CONN_IDLE_DELAY, or a connect succeeds.  connect_work
+	 * is queued from set_nn_state both from hb up and from itself if a
+	 * connect attempt fails and so can be self-arming.  shutdown is
+	 * careful to first mark the nn such that no connects will be attempted
+	 * before canceling delayed connect work and flushing the queue. */
+	struct delayed_work		nn_connect_work;
+	unsigned long			nn_last_connect_attempt;
+
+	/* this is queued as nodes come up and is canceled when a connection is
+	 * established.  this expiring gives up on the node and errors out
+	 * transmits */
+	struct delayed_work		nn_connect_expired;
+
+	/* after we give up on a socket we wait a while before deciding
+	 * that it is still heartbeating and that we should do some
+	 * quorum work */
+	struct delayed_work		nn_still_up;
+};
+
+struct r2net_sock_container {
+	struct kref		sc_kref;
+	/* the next two are valid for the life time of the sc */
+	struct socket		*sc_sock;
+	struct r2nm_node	*sc_node;
+
+	/* all of these sc work structs hold refs on the sc while they are
+	 * queued.  they should not be able to ref a freed sc.  the teardown
+	 * race is with r2net_wq destruction in r2net_stop_listening() */
+
+	/* rx and connect work are generated from socket callbacks.  sc
+	 * shutdown removes the callbacks and then flushes the work queue */
+	struct work_struct	sc_rx_work;
+	struct work_struct	sc_connect_work;
+	/* shutdown work is triggered in two ways.  the simple way is
+	 * for a code path calls ensure_shutdown which gets a lock, removes
+	 * the sc from the nn, and queues the work.  in this case the
+	 * work is single-shot.  the work is also queued from a sock
+	 * callback, though, and in this case the work will find the sc
+	 * still on the nn and will call ensure_shutdown itself.. this
+	 * ends up triggering the shutdown work again, though nothing
+	 * will be done in that second iteration.  so work queue teardown
+	 * has to be careful to remove the sc from the nn before waiting
+	 * on the work queue so that the shutdown work doesn't remove the
+	 * sc and rearm itself.
+	 */
+	struct work_struct	sc_shutdown_work;
+
+	struct timer_list	sc_idle_timeout;
+	struct delayed_work	sc_keepalive_work;
+
+	unsigned		sc_handshake_ok:1;
+
+	struct page		*sc_page;
+	size_t			sc_page_off;
+
+	/* original handlers for the sockets */
+	void			(*sc_state_change)(struct sock *sk);
+	void			(*sc_data_ready)(struct sock *sk, int bytes);
+
+	u32			sc_msg_key;
+	u16			sc_msg_type;
+
+#ifdef CONFIG_DEBUG_FS
+	struct list_head        sc_net_debug_item;
+	ktime_t			sc_tv_timer;
+	ktime_t			sc_tv_data_ready;
+	ktime_t			sc_tv_advance_start;
+	ktime_t			sc_tv_advance_stop;
+	ktime_t			sc_tv_func_start;
+	ktime_t			sc_tv_func_stop;
+#endif
+#ifdef CONFIG_RAMSTER_FS_STATS
+	ktime_t			sc_tv_acquiry_total;
+	ktime_t			sc_tv_send_total;
+	ktime_t			sc_tv_status_total;
+	u32			sc_send_count;
+	u32			sc_recv_count;
+	ktime_t			sc_tv_process_total;
+#endif
+	struct mutex		sc_send_lock;
+};
+
+struct r2net_msg_handler {
+	struct rb_node		nh_node;
+	u32			nh_max_len;
+	u32			nh_msg_type;
+	u32			nh_key;
+	r2net_msg_handler_func	*nh_func;
+	r2net_msg_handler_func	*nh_func_data;
+	r2net_post_msg_handler_func
+				*nh_post_func;
+	struct kref		nh_kref;
+	struct list_head	nh_unregister_item;
+};
+
+enum r2net_system_error {
+	R2NET_ERR_NONE = 0,
+	R2NET_ERR_NO_HNDLR,
+	R2NET_ERR_OVERFLOW,
+	R2NET_ERR_DIED,
+	R2NET_ERR_MAX
+};
+
+struct r2net_status_wait {
+	enum r2net_system_error	ns_sys_status;
+	s32			ns_status;
+	int			ns_id;
+	wait_queue_head_t	ns_wq;
+	struct list_head	ns_node_item;
+};
+
+#ifdef CONFIG_DEBUG_FS
+/* just for state dumps */
+struct r2net_send_tracking {
+	struct list_head		st_net_debug_item;
+	struct task_struct		*st_task;
+	struct r2net_sock_container	*st_sc;
+	u32				st_id;
+	u32				st_msg_type;
+	u32				st_msg_key;
+	u8				st_node;
+	ktime_t				st_sock_time;
+	ktime_t				st_send_time;
+	ktime_t				st_status_time;
+};
+#else
+struct r2net_send_tracking {
+	u32	dummy;
+};
+#endif	/* CONFIG_DEBUG_FS */
+
+#endif /* R2CLUSTER_TCP_INTERNAL_H */
diff --git a/drivers/staging/ramster/r2net.c b/drivers/staging/ramster/r2net.c
new file mode 100644
index 0000000..2ee0220
--- /dev/null
+++ b/drivers/staging/ramster/r2net.c
@@ -0,0 +1,401 @@
+/*
+ * r2net.c
+ *
+ * Copyright (c) 2011, Dan Magenheimer, Oracle Corp.
+ *
+ * Ramster_r2net provides an interface between zcache and r2net.
+ *
+ * FIXME: support more than two nodes
+ */
+
+#include <linux/list.h>
+#include "cluster/tcp.h"
+#include "cluster/nodemanager.h"
+#include "tmem.h"
+#include "zcache.h"
+#include "ramster.h"
+
+#define RAMSTER_TESTING
+
+#define RMSTR_KEY	0x77347734
+
+enum {
+	RMSTR_TMEM_PUT_EPH = 100,
+	RMSTR_TMEM_PUT_PERS,
+	RMSTR_TMEM_ASYNC_GET_REQUEST,
+	RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST,
+	RMSTR_TMEM_ASYNC_GET_REPLY,
+	RMSTR_TMEM_FLUSH,
+	RMSTR_TMEM_FLOBJ,
+	RMSTR_TMEM_DESTROY_POOL,
+};
+
+#define RMSTR_R2NET_MAX_LEN \
+		(R2NET_MAX_PAYLOAD_BYTES - sizeof(struct tmem_xhandle))
+
+#include "cluster/tcp_internal.h"
+
+static struct r2nm_node *r2net_target_node;
+static int r2net_target_nodenum;
+
+int r2net_remote_target_node_set(int node_num)
+{
+	int ret = -1;
+
+	r2net_target_node = r2nm_get_node_by_num(node_num);
+	if (r2net_target_node != NULL) {
+		r2net_target_nodenum = node_num;
+		r2nm_node_put(r2net_target_node);
+		ret = 0;
+	}
+	return ret;
+}
+
+/* FIXME following buffer should be per-cpu, protected by preempt_disable */
+static char ramster_async_get_buf[R2NET_MAX_PAYLOAD_BYTES];
+
+static int ramster_remote_async_get_request_handler(struct r2net_msg *msg,
+				u32 len, void *data, void **ret_data)
+{
+	char *pdata;
+	struct tmem_xhandle xh;
+	int found;
+	size_t size = RMSTR_R2NET_MAX_LEN;
+	u16 msgtype = be16_to_cpu(msg->msg_type);
+	bool get_and_free = (msgtype == RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST);
+	unsigned long flags;
+
+	xh = *(struct tmem_xhandle *)msg->buf;
+	if (xh.xh_data_size > RMSTR_R2NET_MAX_LEN)
+		BUG();
+	pdata = ramster_async_get_buf;
+	*(struct tmem_xhandle *)pdata = xh;
+	pdata += sizeof(struct tmem_xhandle);
+	local_irq_save(flags);
+	found = zcache_get(xh.client_id, xh.pool_id, &xh.oid, xh.index,
+				pdata, &size, 1, get_and_free ? 1 : -1);
+	local_irq_restore(flags);
+	if (found < 0) {
+		/* a zero size indicates the get failed */
+		size = 0;
+	}
+	if (size > RMSTR_R2NET_MAX_LEN)
+		BUG();
+	*ret_data = pdata - sizeof(struct tmem_xhandle);
+	/* now make caller (r2net_process_message) handle specially */
+	r2net_force_data_magic(msg, RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY);
+	return size + sizeof(struct tmem_xhandle);
+}
+
+static int ramster_remote_async_get_reply_handler(struct r2net_msg *msg,
+				u32 len, void *data, void **ret_data)
+{
+	char *in = (char *)msg->buf;
+	int datalen = len - sizeof(struct r2net_msg);
+	int ret = -1;
+	struct tmem_xhandle *xh = (struct tmem_xhandle *)in;
+
+	in += sizeof(struct tmem_xhandle);
+	datalen -= sizeof(struct tmem_xhandle);
+	BUG_ON(datalen < 0 || datalen > PAGE_SIZE);
+	ret = zcache_localify(xh->pool_id, &xh->oid, xh->index,
+				in, datalen, xh->extra);
+#ifdef RAMSTER_TESTING
+	if (ret == -EEXIST)
+		pr_err("TESTING ArrgREP, aborted overwrite on racy put\n");
+#endif
+	return ret;
+}
+
+int ramster_remote_put_handler(struct r2net_msg *msg,
+				u32 len, void *data, void **ret_data)
+{
+	struct tmem_xhandle *xh;
+	char *p = (char *)msg->buf;
+	int datalen = len - sizeof(struct r2net_msg) -
+				sizeof(struct tmem_xhandle);
+	u16 msgtype = be16_to_cpu(msg->msg_type);
+	bool ephemeral = (msgtype == RMSTR_TMEM_PUT_EPH);
+	unsigned long flags;
+	int ret;
+
+	xh = (struct tmem_xhandle *)p;
+	p += sizeof(struct tmem_xhandle);
+	zcache_autocreate_pool(xh->client_id, xh->pool_id, ephemeral);
+	local_irq_save(flags);
+	ret = zcache_put(xh->client_id, xh->pool_id, &xh->oid, xh->index,
+				p, datalen, 1, ephemeral ? 1 : -1);
+	local_irq_restore(flags);
+	return ret;
+}
+
+int ramster_remote_flush_handler(struct r2net_msg *msg,
+				u32 len, void *data, void **ret_data)
+{
+	struct tmem_xhandle *xh;
+	char *p = (char *)msg->buf;
+
+	xh = (struct tmem_xhandle *)p;
+	p += sizeof(struct tmem_xhandle);
+	(void)zcache_flush(xh->client_id, xh->pool_id, &xh->oid, xh->index);
+	return 0;
+}
+
+int ramster_remote_flobj_handler(struct r2net_msg *msg,
+				u32 len, void *data, void **ret_data)
+{
+	struct tmem_xhandle *xh;
+	char *p = (char *)msg->buf;
+
+	xh = (struct tmem_xhandle *)p;
+	p += sizeof(struct tmem_xhandle);
+	(void)zcache_flush_object(xh->client_id, xh->pool_id, &xh->oid);
+	return 0;
+}
+
+int ramster_remote_async_get(struct tmem_xhandle *xh, bool free, int remotenode,
+				size_t expect_size, uint8_t expect_cksum,
+				void *extra)
+{
+	int ret = -1, status;
+	struct r2nm_node *node = NULL;
+	struct kvec vec[1];
+	size_t veclen = 1;
+	u32 msg_type;
+
+	node = r2nm_get_node_by_num(remotenode);
+	if (node == NULL)
+		goto out;
+	xh->client_id = r2nm_this_node(); /* which node is getting */
+	xh->xh_data_cksum = expect_cksum;
+	xh->xh_data_size = expect_size;
+	xh->extra = extra;
+	vec[0].iov_len = sizeof(*xh);
+	vec[0].iov_base = xh;
+	if (free)
+		msg_type = RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST;
+	else
+		msg_type = RMSTR_TMEM_ASYNC_GET_REQUEST;
+	ret = r2net_send_message_vec(msg_type, RMSTR_KEY,
+					vec, veclen, remotenode, &status);
+	r2nm_node_put(node);
+	if (ret < 0) {
+		/* FIXME handle bad message possibilities here? */
+		pr_err("UNTESTED ret<0 in ramster_remote_async_get\n");
+	}
+	ret = status;
+out:
+	return ret;
+}
+
+#ifdef RAMSTER_TESTING
+/* leave me here to see if it catches a weird crash */
+static void ramster_check_irq_counts(void)
+{
+	static int last_hardirq_cnt, last_softirq_cnt, last_preempt_cnt;
+	int cur_hardirq_cnt, cur_softirq_cnt, cur_preempt_cnt;
+
+	cur_hardirq_cnt = hardirq_count() >> HARDIRQ_SHIFT;
+	if (cur_hardirq_cnt > last_hardirq_cnt) {
+		last_hardirq_cnt = cur_hardirq_cnt;
+		if (!(last_hardirq_cnt&(last_hardirq_cnt-1)))
+			pr_err("RAMSTER TESTING RRP hardirq_count=%d\n",
+				last_hardirq_cnt);
+	}
+	cur_softirq_cnt = softirq_count() >> SOFTIRQ_SHIFT;
+	if (cur_softirq_cnt > last_softirq_cnt) {
+		last_softirq_cnt = cur_softirq_cnt;
+		if (!(last_softirq_cnt&(last_softirq_cnt-1)))
+			pr_err("RAMSTER TESTING RRP softirq_count=%d\n",
+				last_softirq_cnt);
+	}
+	cur_preempt_cnt = preempt_count() & PREEMPT_MASK;
+	if (cur_preempt_cnt > last_preempt_cnt) {
+		last_preempt_cnt = cur_preempt_cnt;
+		if (!(last_preempt_cnt&(last_preempt_cnt-1)))
+			pr_err("RAMSTER TESTING RRP preempt_count=%d\n",
+				last_preempt_cnt);
+	}
+}
+#endif
+
+int ramster_remote_put(struct tmem_xhandle *xh, char *data, size_t size,
+				bool ephemeral, int *remotenode)
+{
+	int nodenum, ret = -1, status;
+	struct r2nm_node *node = NULL;
+	struct kvec vec[2];
+	size_t veclen = 2;
+	u32 msg_type;
+#ifdef RAMSTER_TESTING
+	struct r2net_node *nn;
+#endif
+
+	BUG_ON(size > RMSTR_R2NET_MAX_LEN);
+	xh->client_id = r2nm_this_node(); /* which node is putting */
+	vec[0].iov_len = sizeof(*xh);
+	vec[0].iov_base = xh;
+	vec[1].iov_len = size;
+	vec[1].iov_base = data;
+	node = r2net_target_node;
+	if (!node)
+		goto out;
+
+	nodenum = r2net_target_nodenum;
+
+	r2nm_node_get(node);
+
+#ifdef RAMSTER_TESTING
+	nn = r2net_nn_from_num(nodenum);
+	WARN_ON_ONCE(nn->nn_persistent_error || !nn->nn_sc_valid);
+#endif
+
+	if (ephemeral)
+		msg_type = RMSTR_TMEM_PUT_EPH;
+	else
+		msg_type = RMSTR_TMEM_PUT_PERS;
+#ifdef RAMSTER_TESTING
+	/* leave me here to see if it catches a weird crash */
+	ramster_check_irq_counts();
+#endif
+
+	ret = r2net_send_message_vec(msg_type, RMSTR_KEY, vec, veclen,
+						nodenum, &status);
+#ifdef RAMSTER_TESTING
+	if (ret != 0) {
+		static unsigned long cnt;
+		cnt++;
+		if (!(cnt&(cnt-1)))
+			pr_err("ramster_remote_put: message failed, "
+				"ret=%d, cnt=%lu\n", ret, cnt);
+		ret = -1;
+	}
+#endif
+	if (ret < 0)
+		ret = -1;
+	else {
+		ret = status;
+		*remotenode = nodenum;
+	}
+
+	r2nm_node_put(node);
+out:
+	return ret;
+}
+
+int ramster_remote_flush(struct tmem_xhandle *xh, int remotenode)
+{
+	int ret = -1, status;
+	struct r2nm_node *node = NULL;
+	struct kvec vec[1];
+	size_t veclen = 1;
+
+	node = r2nm_get_node_by_num(remotenode);
+	BUG_ON(node == NULL);
+	xh->client_id = r2nm_this_node(); /* which node is flushing */
+	vec[0].iov_len = sizeof(*xh);
+	vec[0].iov_base = xh;
+	BUG_ON(irqs_disabled());
+	BUG_ON(in_softirq());
+	ret = r2net_send_message_vec(RMSTR_TMEM_FLUSH, RMSTR_KEY,
+					vec, veclen, remotenode, &status);
+	r2nm_node_put(node);
+	return ret;
+}
+
+int ramster_remote_flush_object(struct tmem_xhandle *xh, int remotenode)
+{
+	int ret = -1, status;
+	struct r2nm_node *node = NULL;
+	struct kvec vec[1];
+	size_t veclen = 1;
+
+	node = r2nm_get_node_by_num(remotenode);
+	BUG_ON(node == NULL);
+	xh->client_id = r2nm_this_node(); /* which node is flobjing */
+	vec[0].iov_len = sizeof(*xh);
+	vec[0].iov_base = xh;
+	ret = r2net_send_message_vec(RMSTR_TMEM_FLOBJ, RMSTR_KEY,
+					vec, veclen, remotenode, &status);
+	r2nm_node_put(node);
+	return ret;
+}
+
+/*
+ * Handler registration
+ */
+
+static LIST_HEAD(r2net_unreg_list);
+
+static void r2net_unregister_handlers(void)
+{
+	r2net_unregister_handler_list(&r2net_unreg_list);
+}
+
+int r2net_register_handlers(void)
+{
+	int status;
+
+	status = r2net_register_handler(RMSTR_TMEM_PUT_EPH, RMSTR_KEY,
+				RMSTR_R2NET_MAX_LEN,
+				ramster_remote_put_handler,
+				NULL, NULL, &r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	status = r2net_register_handler(RMSTR_TMEM_PUT_PERS, RMSTR_KEY,
+				RMSTR_R2NET_MAX_LEN,
+				ramster_remote_put_handler,
+				NULL, NULL, &r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_REQUEST, RMSTR_KEY,
+				RMSTR_R2NET_MAX_LEN,
+				ramster_remote_async_get_request_handler,
+				NULL, NULL,
+				&r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_AND_FREE_REQUEST,
+				RMSTR_KEY, RMSTR_R2NET_MAX_LEN,
+				ramster_remote_async_get_request_handler,
+				NULL, NULL,
+				&r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	status = r2net_register_handler(RMSTR_TMEM_ASYNC_GET_REPLY, RMSTR_KEY,
+				RMSTR_R2NET_MAX_LEN,
+				ramster_remote_async_get_reply_handler,
+				NULL, NULL,
+				&r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	status = r2net_register_handler(RMSTR_TMEM_FLUSH, RMSTR_KEY,
+				RMSTR_R2NET_MAX_LEN,
+				ramster_remote_flush_handler,
+				NULL, NULL,
+				&r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	status = r2net_register_handler(RMSTR_TMEM_FLOBJ, RMSTR_KEY,
+				RMSTR_R2NET_MAX_LEN,
+				ramster_remote_flobj_handler,
+				NULL, NULL,
+				&r2net_unreg_list);
+	if (status)
+		goto bail;
+
+	pr_info("ramster: r2net handlers registered\n");
+
+bail:
+	if (status) {
+		r2net_unregister_handlers();
+		pr_err("ramster: couldn't register r2net handlers\n");
+	}
+	return status;
+}
diff --git a/drivers/staging/ramster/ramster.h b/drivers/staging/ramster/ramster.h
new file mode 100644
index 0000000..0c9455e
--- /dev/null
+++ b/drivers/staging/ramster/ramster.h
@@ -0,0 +1,118 @@
+/*
+ * ramster.h
+ *
+ * Peer-to-peer transcendent memory
+ *
+ * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp.
+ */
+
+#ifndef _RAMSTER_H_
+#define _RAMSTER_H_
+
+/*
+ * format of remote pampd:
+ *   bit 0 == intransit
+ *   bit 1 == is_remote... if this bit is set, then
+ *   bit 2-9 == remotenode
+ *   bit 10-22 == size
+ *   bit 23-30 == cksum
+ */
+#define FAKE_PAMPD_INTRANSIT_BITS	1
+#define FAKE_PAMPD_ISREMOTE_BITS	1
+#define FAKE_PAMPD_REMOTENODE_BITS	8
+#define FAKE_PAMPD_REMOTESIZE_BITS	13
+#define FAKE_PAMPD_CHECKSUM_BITS	8
+
+#define FAKE_PAMPD_INTRANSIT_SHIFT	0
+#define FAKE_PAMPD_ISREMOTE_SHIFT	(FAKE_PAMPD_INTRANSIT_SHIFT + \
+					 FAKE_PAMPD_INTRANSIT_BITS)
+#define FAKE_PAMPD_REMOTENODE_SHIFT	(FAKE_PAMPD_ISREMOTE_SHIFT + \
+					 FAKE_PAMPD_ISREMOTE_BITS)
+#define FAKE_PAMPD_REMOTESIZE_SHIFT	(FAKE_PAMPD_REMOTENODE_SHIFT + \
+					 FAKE_PAMPD_REMOTENODE_BITS)
+#define FAKE_PAMPD_CHECKSUM_SHIFT	(FAKE_PAMPD_REMOTESIZE_SHIFT + \
+					 FAKE_PAMPD_REMOTESIZE_BITS)
+
+#define FAKE_PAMPD_MASK(x)		((1UL << (x)) - 1)
+
+static inline void *pampd_make_remote(int remotenode, size_t size,
+					unsigned char cksum)
+{
+	unsigned long fake_pampd = 0;
+	fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;
+	fake_pampd |= ((unsigned long)remotenode &
+			FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS)) <<
+				FAKE_PAMPD_REMOTENODE_SHIFT;
+	fake_pampd |= ((unsigned long)size &
+			FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS)) <<
+				FAKE_PAMPD_REMOTESIZE_SHIFT;
+	fake_pampd |= ((unsigned long)cksum &
+			FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS)) <<
+				FAKE_PAMPD_CHECKSUM_SHIFT;
+	return (void *)fake_pampd;
+}
+
+static inline unsigned int pampd_remote_node(void *pampd)
+{
+	unsigned long fake_pampd = (unsigned long)pampd;
+	return (fake_pampd >> FAKE_PAMPD_REMOTENODE_SHIFT) &
+		FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTENODE_BITS);
+}
+
+static inline unsigned int pampd_remote_size(void *pampd)
+{
+	unsigned long fake_pampd = (unsigned long)pampd;
+	return (fake_pampd >> FAKE_PAMPD_REMOTESIZE_SHIFT) &
+		FAKE_PAMPD_MASK(FAKE_PAMPD_REMOTESIZE_BITS);
+}
+
+static inline unsigned char pampd_remote_cksum(void *pampd)
+{
+	unsigned long fake_pampd = (unsigned long)pampd;
+	return (fake_pampd >> FAKE_PAMPD_CHECKSUM_SHIFT) &
+		FAKE_PAMPD_MASK(FAKE_PAMPD_CHECKSUM_BITS);
+}
+
+static inline bool pampd_is_remote(void *pampd)
+{
+	unsigned long fake_pampd = (unsigned long)pampd;
+	return (fake_pampd >> FAKE_PAMPD_ISREMOTE_SHIFT) &
+		FAKE_PAMPD_MASK(FAKE_PAMPD_ISREMOTE_BITS);
+}
+
+static inline bool pampd_is_intransit(void *pampd)
+{
+	unsigned long fake_pampd = (unsigned long)pampd;
+	return (fake_pampd >> FAKE_PAMPD_INTRANSIT_SHIFT) &
+		FAKE_PAMPD_MASK(FAKE_PAMPD_INTRANSIT_BITS);
+}
+
+/* note that it is a BUG for intransit to be set without isremote also set */
+static inline void *pampd_mark_intransit(void *pampd)
+{
+	unsigned long fake_pampd = (unsigned long)pampd;
+
+	fake_pampd |= 1UL << FAKE_PAMPD_ISREMOTE_SHIFT;
+	fake_pampd |= 1UL << FAKE_PAMPD_INTRANSIT_SHIFT;
+	return (void *)fake_pampd;
+}
+
+static inline void *pampd_mask_intransit_and_remote(void *marked_pampd)
+{
+	unsigned long pampd = (unsigned long)marked_pampd;
+
+	pampd &= ~(1UL << FAKE_PAMPD_INTRANSIT_SHIFT);
+	pampd &= ~(1UL << FAKE_PAMPD_ISREMOTE_SHIFT);
+	return (void *)pampd;
+}
+
+extern int ramster_remote_async_get(struct tmem_xhandle *,
+				bool, int, size_t, uint8_t, void *extra);
+extern int ramster_remote_put(struct tmem_xhandle *, char *, size_t,
+				bool, int *);
+extern int ramster_remote_flush(struct tmem_xhandle *, int);
+extern int ramster_remote_flush_object(struct tmem_xhandle *, int);
+extern int r2net_register_handlers(void);
+extern int r2net_remote_target_node_set(int);
+
+#endif /* _TMEM_H */
diff --git a/drivers/staging/ramster/tmem.c b/drivers/staging/ramster/tmem.c
new file mode 100644
index 0000000..8f2f689
--- /dev/null
+++ b/drivers/staging/ramster/tmem.c
@@ -0,0 +1,851 @@
+/*
+ * In-kernel transcendent memory (generic implementation)
+ *
+ * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
+ *
+ * The primary purpose of Transcedent Memory ("tmem") is to map object-oriented
+ * "handles" (triples containing a pool id, and object id, and an index), to
+ * pages in a page-accessible memory (PAM).  Tmem references the PAM pages via
+ * an abstract "pampd" (PAM page-descriptor), which can be operated on by a
+ * set of functions (pamops).  Each pampd contains some representation of
+ * PAGE_SIZE bytes worth of data. Tmem must support potentially millions of
+ * pages and must be able to insert, find, and delete these pages at a
+ * potential frequency of thousands per second concurrently across many CPUs,
+ * (and, if used with KVM, across many vcpus across many guests).
+ * Tmem is tracked with a hierarchy of data structures, organized by
+ * the elements in a handle-tuple: pool_id, object_id, and page index.
+ * One or more "clients" (e.g. guests) each provide one or more tmem_pools.
+ * Each pool, contains a hash table of rb_trees of tmem_objs.  Each
+ * tmem_obj contains a radix-tree-like tree of pointers, with intermediate
+ * nodes called tmem_objnodes.  Each leaf pointer in this tree points to
+ * a pampd, which is accessible only through a small set of callbacks
+ * registered by the PAM implementation (see tmem_register_pamops). Tmem
+ * does all memory allocation via a set of callbacks registered by the tmem
+ * host implementation (e.g. see tmem_register_hostops).
+ */
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/atomic.h>
+#include <linux/delay.h>
+
+#include "tmem.h"
+
+/* data structure sentinels used for debugging... see tmem.h */
+#define POOL_SENTINEL 0x87658765
+#define OBJ_SENTINEL 0x12345678
+#define OBJNODE_SENTINEL 0xfedcba09
+
+/*
+ * A tmem host implementation must use this function to register callbacks
+ * for memory allocation.
+ */
+static struct tmem_hostops tmem_hostops;
+
+static void tmem_objnode_tree_init(void);
+
+void tmem_register_hostops(struct tmem_hostops *m)
+{
+	tmem_objnode_tree_init();
+	tmem_hostops = *m;
+}
+
+/*
+ * A tmem host implementation must use this function to register
+ * callbacks for a page-accessible memory (PAM) implementation
+ */
+static struct tmem_pamops tmem_pamops;
+
+void tmem_register_pamops(struct tmem_pamops *m)
+{
+	tmem_pamops = *m;
+}
+
+/*
+ * Oid's are potentially very sparse and tmem_objs may have an indeterminately
+ * short life, being added and deleted at a relatively high frequency.
+ * So an rb_tree is an ideal data structure to manage tmem_objs.  But because
+ * of the potentially huge number of tmem_objs, each pool manages a hashtable
+ * of rb_trees to reduce search, insert, delete, and rebalancing time.
+ * Each hashbucket also has a lock to manage concurrent access.
+ *
+ * The following routines manage tmem_objs.  When any tmem_obj is accessed,
+ * the hashbucket lock must be held.
+ */
+
+/* searches for object==oid in pool, returns locked object if found */
+static struct tmem_obj *tmem_obj_find(struct tmem_hashbucket *hb,
+					struct tmem_oid *oidp)
+{
+	struct rb_node *rbnode;
+	struct tmem_obj *obj;
+
+	rbnode = hb->obj_rb_root.rb_node;
+	while (rbnode) {
+		BUG_ON(RB_EMPTY_NODE(rbnode));
+		obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node);
+		switch (tmem_oid_compare(oidp, &obj->oid)) {
+		case 0: /* equal */
+			goto out;
+		case -1:
+			rbnode = rbnode->rb_left;
+			break;
+		case 1:
+			rbnode = rbnode->rb_right;
+			break;
+		}
+	}
+	obj = NULL;
+out:
+	return obj;
+}
+
+static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *);
+
+/* free an object that has no more pampds in it */
+static void tmem_obj_free(struct tmem_obj *obj, struct tmem_hashbucket *hb)
+{
+	struct tmem_pool *pool;
+
+	BUG_ON(obj == NULL);
+	ASSERT_SENTINEL(obj, OBJ);
+	BUG_ON(obj->pampd_count > 0);
+	pool = obj->pool;
+	BUG_ON(pool == NULL);
+	if (obj->objnode_tree_root != NULL) /* may be "stump" with no leaves */
+		tmem_pampd_destroy_all_in_obj(obj);
+	BUG_ON(obj->objnode_tree_root != NULL);
+	BUG_ON((long)obj->objnode_count != 0);
+	atomic_dec(&pool->obj_count);
+	BUG_ON(atomic_read(&pool->obj_count) < 0);
+	INVERT_SENTINEL(obj, OBJ);
+	obj->pool = NULL;
+	tmem_oid_set_invalid(&obj->oid);
+	rb_erase(&obj->rb_tree_node, &hb->obj_rb_root);
+}
+
+/*
+ * initialize, and insert an tmem_object_root (called only if find failed)
+ */
+static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb,
+					struct tmem_pool *pool,
+					struct tmem_oid *oidp)
+{
+	struct rb_root *root = &hb->obj_rb_root;
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+	struct tmem_obj *this;
+
+	BUG_ON(pool == NULL);
+	atomic_inc(&pool->obj_count);
+	obj->objnode_tree_height = 0;
+	obj->objnode_tree_root = NULL;
+	obj->pool = pool;
+	obj->oid = *oidp;
+	obj->objnode_count = 0;
+	obj->pampd_count = 0;
+	(*tmem_pamops.new_obj)(obj);
+	SET_SENTINEL(obj, OBJ);
+	while (*new) {
+		BUG_ON(RB_EMPTY_NODE(*new));
+		this = rb_entry(*new, struct tmem_obj, rb_tree_node);
+		parent = *new;
+		switch (tmem_oid_compare(oidp, &this->oid)) {
+		case 0:
+			BUG(); /* already present; should never happen! */
+			break;
+		case -1:
+			new = &(*new)->rb_left;
+			break;
+		case 1:
+			new = &(*new)->rb_right;
+			break;
+		}
+	}
+	rb_link_node(&obj->rb_tree_node, parent, new);
+	rb_insert_color(&obj->rb_tree_node, root);
+}
+
+/*
+ * Tmem is managed as a set of tmem_pools with certain attributes, such as
+ * "ephemeral" vs "persistent".  These attributes apply to all tmem_objs
+ * and all pampds that belong to a tmem_pool.  A tmem_pool is created
+ * or deleted relatively rarely (for example, when a filesystem is
+ * mounted or unmounted.
+ */
+
+/* flush all data from a pool and, optionally, free it */
+static void tmem_pool_flush(struct tmem_pool *pool, bool destroy)
+{
+	struct rb_node *rbnode;
+	struct tmem_obj *obj;
+	struct tmem_hashbucket *hb = &pool->hashbucket[0];
+	int i;
+
+	BUG_ON(pool == NULL);
+	for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) {
+		spin_lock(&hb->lock);
+		rbnode = rb_first(&hb->obj_rb_root);
+		while (rbnode != NULL) {
+			obj = rb_entry(rbnode, struct tmem_obj, rb_tree_node);
+			rbnode = rb_next(rbnode);
+			tmem_pampd_destroy_all_in_obj(obj);
+			tmem_obj_free(obj, hb);
+			(*tmem_hostops.obj_free)(obj, pool);
+		}
+		spin_unlock(&hb->lock);
+	}
+	if (destroy)
+		list_del(&pool->pool_list);
+}
+
+/*
+ * A tmem_obj contains a radix-tree-like tree in which the intermediate
+ * nodes are called tmem_objnodes.  (The kernel lib/radix-tree.c implementation
+ * is very specialized and tuned for specific uses and is not particularly
+ * suited for use from this code, though some code from the core algorithms has
+ * been reused, thus the copyright notices below).  Each tmem_objnode contains
+ * a set of pointers which point to either a set of intermediate tmem_objnodes
+ * or a set of of pampds.
+ *
+ * Portions Copyright (C) 2001 Momchil Velikov
+ * Portions Copyright (C) 2001 Christoph Hellwig
+ * Portions Copyright (C) 2005 SGI, Christoph Lameter <clameter@sgi.com>
+ */
+
+struct tmem_objnode_tree_path {
+	struct tmem_objnode *objnode;
+	int offset;
+};
+
+/* objnode height_to_maxindex translation */
+static unsigned long tmem_objnode_tree_h2max[OBJNODE_TREE_MAX_PATH + 1];
+
+static void tmem_objnode_tree_init(void)
+{
+	unsigned int ht, tmp;
+
+	for (ht = 0; ht < ARRAY_SIZE(tmem_objnode_tree_h2max); ht++) {
+		tmp = ht * OBJNODE_TREE_MAP_SHIFT;
+		if (tmp >= OBJNODE_TREE_INDEX_BITS)
+			tmem_objnode_tree_h2max[ht] = ~0UL;
+		else
+			tmem_objnode_tree_h2max[ht] =
+			    (~0UL >> (OBJNODE_TREE_INDEX_BITS - tmp - 1)) >> 1;
+	}
+}
+
+static struct tmem_objnode *tmem_objnode_alloc(struct tmem_obj *obj)
+{
+	struct tmem_objnode *objnode;
+
+	ASSERT_SENTINEL(obj, OBJ);
+	BUG_ON(obj->pool == NULL);
+	ASSERT_SENTINEL(obj->pool, POOL);
+	objnode = (*tmem_hostops.objnode_alloc)(obj->pool);
+	if (unlikely(objnode == NULL))
+		goto out;
+	objnode->obj = obj;
+	SET_SENTINEL(objnode, OBJNODE);
+	memset(&objnode->slots, 0, sizeof(objnode->slots));
+	objnode->slots_in_use = 0;
+	obj->objnode_count++;
+out:
+	return objnode;
+}
+
+static void tmem_objnode_free(struct tmem_objnode *objnode)
+{
+	struct tmem_pool *pool;
+	int i;
+
+	BUG_ON(objnode == NULL);
+	for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++)
+		BUG_ON(objnode->slots[i] != NULL);
+	ASSERT_SENTINEL(objnode, OBJNODE);
+	INVERT_SENTINEL(objnode, OBJNODE);
+	BUG_ON(objnode->obj == NULL);
+	ASSERT_SENTINEL(objnode->obj, OBJ);
+	pool = objnode->obj->pool;
+	BUG_ON(pool == NULL);
+	ASSERT_SENTINEL(pool, POOL);
+	objnode->obj->objnode_count--;
+	objnode->obj = NULL;
+	(*tmem_hostops.objnode_free)(objnode, pool);
+}
+
+/*
+ * lookup index in object and return associated pampd (or NULL if not found)
+ */
+static void **__tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index)
+{
+	unsigned int height, shift;
+	struct tmem_objnode **slot = NULL;
+
+	BUG_ON(obj == NULL);
+	ASSERT_SENTINEL(obj, OBJ);
+	BUG_ON(obj->pool == NULL);
+	ASSERT_SENTINEL(obj->pool, POOL);
+
+	height = obj->objnode_tree_height;
+	if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height])
+		goto out;
+	if (height == 0 && obj->objnode_tree_root) {
+		slot = &obj->objnode_tree_root;
+		goto out;
+	}
+	shift = (height-1) * OBJNODE_TREE_MAP_SHIFT;
+	slot = &obj->objnode_tree_root;
+	while (height > 0) {
+		if (*slot == NULL)
+			goto out;
+		slot = (struct tmem_objnode **)
+			((*slot)->slots +
+			 ((index >> shift) & OBJNODE_TREE_MAP_MASK));
+		shift -= OBJNODE_TREE_MAP_SHIFT;
+		height--;
+	}
+out:
+	return slot != NULL ? (void **)slot : NULL;
+}
+
+static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index)
+{
+	struct tmem_objnode **slot;
+
+	slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index);
+	return slot != NULL ? *slot : NULL;
+}
+
+static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index,
+					void *new_pampd, bool no_free)
+{
+	struct tmem_objnode **slot;
+	void *ret = NULL;
+
+	slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index);
+	if ((slot != NULL) && (*slot != NULL)) {
+		void *old_pampd = *(void **)slot;
+		*(void **)slot = new_pampd;
+		if (!no_free)
+			(*tmem_pamops.free)(old_pampd, obj->pool,
+						NULL, 0, false);
+		ret = new_pampd;
+	}
+	return ret;
+}
+
+static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index,
+					void *pampd)
+{
+	int ret = 0;
+	struct tmem_objnode *objnode = NULL, *newnode, *slot;
+	unsigned int height, shift;
+	int offset = 0;
+
+	/* if necessary, extend the tree to be higher  */
+	if (index > tmem_objnode_tree_h2max[obj->objnode_tree_height]) {
+		height = obj->objnode_tree_height + 1;
+		if (index > tmem_objnode_tree_h2max[height])
+			while (index > tmem_objnode_tree_h2max[height])
+				height++;
+		if (obj->objnode_tree_root == NULL) {
+			obj->objnode_tree_height = height;
+			goto insert;
+		}
+		do {
+			newnode = tmem_objnode_alloc(obj);
+			if (!newnode) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			newnode->slots[0] = obj->objnode_tree_root;
+			newnode->slots_in_use = 1;
+			obj->objnode_tree_root = newnode;
+			obj->objnode_tree_height++;
+		} while (height > obj->objnode_tree_height);
+	}
+insert:
+	slot = obj->objnode_tree_root;
+	height = obj->objnode_tree_height;
+	shift = (height-1) * OBJNODE_TREE_MAP_SHIFT;
+	while (height > 0) {
+		if (slot == NULL) {
+			/* add a child objnode.  */
+			slot = tmem_objnode_alloc(obj);
+			if (!slot) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			if (objnode) {
+
+				objnode->slots[offset] = slot;
+				objnode->slots_in_use++;
+			} else
+				obj->objnode_tree_root = slot;
+		}
+		/* go down a level */
+		offset = (index >> shift) & OBJNODE_TREE_MAP_MASK;
+		objnode = slot;
+		slot = objnode->slots[offset];
+		shift -= OBJNODE_TREE_MAP_SHIFT;
+		height--;
+	}
+	BUG_ON(slot != NULL);
+	if (objnode) {
+		objnode->slots_in_use++;
+		objnode->slots[offset] = pampd;
+	} else
+		obj->objnode_tree_root = pampd;
+	obj->pampd_count++;
+out:
+	return ret;
+}
+
+static void *tmem_pampd_delete_from_obj(struct tmem_obj *obj, uint32_t index)
+{
+	struct tmem_objnode_tree_path path[OBJNODE_TREE_MAX_PATH + 1];
+	struct tmem_objnode_tree_path *pathp = path;
+	struct tmem_objnode *slot = NULL;
+	unsigned int height, shift;
+	int offset;
+
+	BUG_ON(obj == NULL);
+	ASSERT_SENTINEL(obj, OBJ);
+	BUG_ON(obj->pool == NULL);
+	ASSERT_SENTINEL(obj->pool, POOL);
+	height = obj->objnode_tree_height;
+	if (index > tmem_objnode_tree_h2max[height])
+		goto out;
+	slot = obj->objnode_tree_root;
+	if (height == 0 && obj->objnode_tree_root) {
+		obj->objnode_tree_root = NULL;
+		goto out;
+	}
+	shift = (height - 1) * OBJNODE_TREE_MAP_SHIFT;
+	pathp->objnode = NULL;
+	do {
+		if (slot == NULL)
+			goto out;
+		pathp++;
+		offset = (index >> shift) & OBJNODE_TREE_MAP_MASK;
+		pathp->offset = offset;
+		pathp->objnode = slot;
+		slot = slot->slots[offset];
+		shift -= OBJNODE_TREE_MAP_SHIFT;
+		height--;
+	} while (height > 0);
+	if (slot == NULL)
+		goto out;
+	while (pathp->objnode) {
+		pathp->objnode->slots[pathp->offset] = NULL;
+		pathp->objnode->slots_in_use--;
+		if (pathp->objnode->slots_in_use) {
+			if (pathp->objnode == obj->objnode_tree_root) {
+				while (obj->objnode_tree_height > 0 &&
+				  obj->objnode_tree_root->slots_in_use == 1 &&
+				  obj->objnode_tree_root->slots[0]) {
+					struct tmem_objnode *to_free =
+						obj->objnode_tree_root;
+
+					obj->objnode_tree_root =
+							to_free->slots[0];
+					obj->objnode_tree_height--;
+					to_free->slots[0] = NULL;
+					to_free->slots_in_use = 0;
+					tmem_objnode_free(to_free);
+				}
+			}
+			goto out;
+		}
+		tmem_objnode_free(pathp->objnode); /* 0 slots used, free it */
+		pathp--;
+	}
+	obj->objnode_tree_height = 0;
+	obj->objnode_tree_root = NULL;
+
+out:
+	if (slot != NULL)
+		obj->pampd_count--;
+	BUG_ON(obj->pampd_count < 0);
+	return slot;
+}
+
+/* recursively walk the objnode_tree destroying pampds and objnodes */
+static void tmem_objnode_node_destroy(struct tmem_obj *obj,
+					struct tmem_objnode *objnode,
+					unsigned int ht)
+{
+	int i;
+
+	if (ht == 0)
+		return;
+	for (i = 0; i < OBJNODE_TREE_MAP_SIZE; i++) {
+		if (objnode->slots[i]) {
+			if (ht == 1) {
+				obj->pampd_count--;
+				(*tmem_pamops.free)(objnode->slots[i],
+						obj->pool, NULL, 0, true);
+				objnode->slots[i] = NULL;
+				continue;
+			}
+			tmem_objnode_node_destroy(obj, objnode->slots[i], ht-1);
+			tmem_objnode_free(objnode->slots[i]);
+			objnode->slots[i] = NULL;
+		}
+	}
+}
+
+static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj)
+{
+	if (obj->objnode_tree_root == NULL)
+		return;
+	if (obj->objnode_tree_height == 0) {
+		obj->pampd_count--;
+		(*tmem_pamops.free)(obj->objnode_tree_root,
+					obj->pool, NULL, 0, true);
+	} else {
+		tmem_objnode_node_destroy(obj, obj->objnode_tree_root,
+					obj->objnode_tree_height);
+		tmem_objnode_free(obj->objnode_tree_root);
+		obj->objnode_tree_height = 0;
+	}
+	obj->objnode_tree_root = NULL;
+	(*tmem_pamops.free_obj)(obj->pool, obj);
+}
+
+/*
+ * Tmem is operated on by a set of well-defined actions:
+ * "put", "get", "flush", "flush_object", "new pool" and "destroy pool".
+ * (The tmem ABI allows for subpages and exchanges but these operations
+ * are not included in this implementation.)
+ *
+ * These "tmem core" operations are implemented in the following functions.
+ */
+
+/*
+ * "Put" a page, e.g. copy a page from the kernel into newly allocated
+ * PAM space (if such space is available).  Tmem_put is complicated by
+ * a corner case: What if a page with matching handle already exists in
+ * tmem?  To guarantee coherency, one of two actions is necessary: Either
+ * the data for the page must be overwritten, or the page must be
+ * "flushed" so that the data is not accessible to a subsequent "get".
+ * Since these "duplicate puts" are relatively rare, this implementation
+ * always flushes for simplicity.
+ */
+int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index,
+		char *data, size_t size, bool raw, int ephemeral)
+{
+	struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL;
+	void *pampd = NULL, *pampd_del = NULL;
+	int ret = -ENOMEM;
+	struct tmem_hashbucket *hb;
+
+	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
+	spin_lock(&hb->lock);
+	obj = objfound = tmem_obj_find(hb, oidp);
+	if (obj != NULL) {
+		pampd = tmem_pampd_lookup_in_obj(objfound, index);
+		if (pampd != NULL) {
+			/* if found, is a dup put, flush the old one */
+			pampd_del = tmem_pampd_delete_from_obj(obj, index);
+			BUG_ON(pampd_del != pampd);
+			(*tmem_pamops.free)(pampd, pool, oidp, index, true);
+			if (obj->pampd_count == 0) {
+				objnew = obj;
+				objfound = NULL;
+			}
+			pampd = NULL;
+		}
+	} else {
+		obj = objnew = (*tmem_hostops.obj_alloc)(pool);
+		if (unlikely(obj == NULL)) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		tmem_obj_init(obj, hb, pool, oidp);
+	}
+	BUG_ON(obj == NULL);
+	BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound));
+	pampd = (*tmem_pamops.create)(data, size, raw, ephemeral,
+					obj->pool, &obj->oid, index);
+	if (unlikely(pampd == NULL))
+		goto free;
+	ret = tmem_pampd_add_to_obj(obj, index, pampd);
+	if (unlikely(ret == -ENOMEM))
+		/* may have partially built objnode tree ("stump") */
+		goto delete_and_free;
+	goto out;
+
+delete_and_free:
+	(void)tmem_pampd_delete_from_obj(obj, index);
+free:
+	if (pampd)
+		(*tmem_pamops.free)(pampd, pool, NULL, 0, true);
+	if (objnew) {
+		tmem_obj_free(objnew, hb);
+		(*tmem_hostops.obj_free)(objnew, pool);
+	}
+out:
+	spin_unlock(&hb->lock);
+	return ret;
+}
+
+void *tmem_localify_get_pampd(struct tmem_pool *pool, struct tmem_oid *oidp,
+				uint32_t index, struct tmem_obj **ret_obj,
+				void **saved_hb)
+{
+	struct tmem_hashbucket *hb;
+	struct tmem_obj *obj = NULL;
+	void *pampd = NULL;
+
+	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
+	spin_lock(&hb->lock);
+	obj = tmem_obj_find(hb, oidp);
+	if (likely(obj != NULL))
+		pampd = tmem_pampd_lookup_in_obj(obj, index);
+	*ret_obj = obj;
+	*saved_hb = (void *)hb;
+	/* note, hashbucket remains locked */
+	return pampd;
+}
+
+void tmem_localify_finish(struct tmem_obj *obj, uint32_t index,
+			  void *pampd, void *saved_hb, bool delete)
+{
+	struct tmem_hashbucket *hb = (struct tmem_hashbucket *)saved_hb;
+
+	BUG_ON(!spin_is_locked(&hb->lock));
+	if (pampd != NULL) {
+		BUG_ON(obj == NULL);
+		(void)tmem_pampd_replace_in_obj(obj, index, pampd, 1);
+	} else if (delete) {
+		BUG_ON(obj == NULL);
+		(void)tmem_pampd_delete_from_obj(obj, index);
+	}
+	spin_unlock(&hb->lock);
+}
+
+static int tmem_repatriate(void **ppampd, struct tmem_hashbucket *hb,
+				struct tmem_pool *pool, struct tmem_oid *oidp,
+				uint32_t index, bool free, char *data)
+{
+	void *old_pampd = *ppampd, *new_pampd = NULL;
+	bool intransit = false;
+	int ret = 0;
+
+
+	if (!is_ephemeral(pool))
+		new_pampd = (*tmem_pamops.repatriate_preload)(
+				old_pampd, pool, oidp, index, &intransit);
+	if (intransit)
+		ret = -EAGAIN;
+	else if (new_pampd != NULL)
+		*ppampd = new_pampd;
+	/* must release the hb->lock else repatriate can't sleep */
+	spin_unlock(&hb->lock);
+	if (!intransit)
+		ret = (*tmem_pamops.repatriate)(old_pampd, new_pampd, pool,
+						oidp, index, free, data);
+	return ret;
+}
+
+/*
+ * "Get" a page, e.g. if one can be found, copy the tmem page with the
+ * matching handle from PAM space to the kernel.  By tmem definition,
+ * when a "get" is successful on an ephemeral page, the page is "flushed",
+ * and when a "get" is successful on a persistent page, the page is retained
+ * in tmem.  Note that to preserve
+ * coherency, "get" can never be skipped if tmem contains the data.
+ * That is, if a get is done with a certain handle and fails, any
+ * subsequent "get" must also fail (unless of course there is a
+ * "put" done with the same handle).
+
+ */
+int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index,
+		char *data, size_t *size, bool raw, int get_and_free)
+{
+	struct tmem_obj *obj;
+	void *pampd;
+	bool ephemeral = is_ephemeral(pool);
+	int ret = -1;
+	struct tmem_hashbucket *hb;
+	bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral);
+	bool lock_held = 0;
+	void **ppampd;
+
+again:
+	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
+	spin_lock(&hb->lock);
+	lock_held = 1;
+	obj = tmem_obj_find(hb, oidp);
+	if (obj == NULL)
+		goto out;
+	ppampd = __tmem_pampd_lookup_in_obj(obj, index);
+	if (ppampd == NULL)
+		goto out;
+	if (tmem_pamops.is_remote(*ppampd)) {
+		ret = tmem_repatriate(ppampd, hb, pool, oidp,
+					index, free, data);
+		lock_held = 0; /* note hb->lock has been unlocked */
+		if (ret == -EAGAIN) {
+			/* rare I think, but should cond_resched()??? */
+			usleep_range(10, 1000);
+			goto again;
+		} else if (ret != 0) {
+			if (ret != -ENOENT)
+				pr_err("UNTESTED case in tmem_get, ret=%d\n",
+						ret);
+			ret = -1;
+			goto out;
+		}
+		goto out;
+	}
+	if (free)
+		pampd = tmem_pampd_delete_from_obj(obj, index);
+	else
+		pampd = tmem_pampd_lookup_in_obj(obj, index);
+	if (pampd == NULL)
+		goto out;
+	if (free) {
+		if (obj->pampd_count == 0) {
+			tmem_obj_free(obj, hb);
+			(*tmem_hostops.obj_free)(obj, pool);
+			obj = NULL;
+		}
+	}
+	if (free)
+		ret = (*tmem_pamops.get_data_and_free)(
+				data, size, raw, pampd, pool, oidp, index);
+	else
+		ret = (*tmem_pamops.get_data)(
+				data, size, raw, pampd, pool, oidp, index);
+	if (ret < 0)
+		goto out;
+	ret = 0;
+out:
+	if (lock_held)
+		spin_unlock(&hb->lock);
+	return ret;
+}
+
+/*
+ * If a page in tmem matches the handle, "flush" this page from tmem such
+ * that any subsequent "get" does not succeed (unless, of course, there
+ * was another "put" with the same handle).
+ */
+int tmem_flush_page(struct tmem_pool *pool,
+				struct tmem_oid *oidp, uint32_t index)
+{
+	struct tmem_obj *obj;
+	void *pampd;
+	int ret = -1;
+	struct tmem_hashbucket *hb;
+
+	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
+	spin_lock(&hb->lock);
+	obj = tmem_obj_find(hb, oidp);
+	if (obj == NULL)
+		goto out;
+	pampd = tmem_pampd_delete_from_obj(obj, index);
+	if (pampd == NULL)
+		goto out;
+	(*tmem_pamops.free)(pampd, pool, oidp, index, true);
+	if (obj->pampd_count == 0) {
+		tmem_obj_free(obj, hb);
+		(*tmem_hostops.obj_free)(obj, pool);
+	}
+	ret = 0;
+
+out:
+	spin_unlock(&hb->lock);
+	return ret;
+}
+
+/*
+ * If a page in tmem matches the handle, replace the page so that any
+ * subsequent "get" gets the new page.  Returns the new page if
+ * there was a page to replace, else returns NULL.
+ */
+int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp,
+			uint32_t index, void *new_pampd)
+{
+	struct tmem_obj *obj;
+	int ret = -1;
+	struct tmem_hashbucket *hb;
+
+	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
+	spin_lock(&hb->lock);
+	obj = tmem_obj_find(hb, oidp);
+	if (obj == NULL)
+		goto out;
+	new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd, 0);
+	ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj);
+out:
+	spin_unlock(&hb->lock);
+	return ret;
+}
+
+/*
+ * "Flush" all pages in tmem matching this oid.
+ */
+int tmem_flush_object(struct tmem_pool *pool, struct tmem_oid *oidp)
+{
+	struct tmem_obj *obj;
+	struct tmem_hashbucket *hb;
+	int ret = -1;
+
+	hb = &pool->hashbucket[tmem_oid_hash(oidp)];
+	spin_lock(&hb->lock);
+	obj = tmem_obj_find(hb, oidp);
+	if (obj == NULL)
+		goto out;
+	tmem_pampd_destroy_all_in_obj(obj);
+	tmem_obj_free(obj, hb);
+	(*tmem_hostops.obj_free)(obj, pool);
+	ret = 0;
+
+out:
+	spin_unlock(&hb->lock);
+	return ret;
+}
+
+/*
+ * "Flush" all pages (and tmem_objs) from this tmem_pool and disable
+ * all subsequent access to this tmem_pool.
+ */
+int tmem_destroy_pool(struct tmem_pool *pool)
+{
+	int ret = -1;
+
+	if (pool == NULL)
+		goto out;
+	tmem_pool_flush(pool, 1);
+	ret = 0;
+out:
+	return ret;
+}
+
+static LIST_HEAD(tmem_global_pool_list);
+
+/*
+ * Create a new tmem_pool with the provided flag and return
+ * a pool id provided by the tmem host implementation.
+ */
+void tmem_new_pool(struct tmem_pool *pool, uint32_t flags)
+{
+	int persistent = flags & TMEM_POOL_PERSIST;
+	int shared = flags & TMEM_POOL_SHARED;
+	struct tmem_hashbucket *hb = &pool->hashbucket[0];
+	int i;
+
+	for (i = 0; i < TMEM_HASH_BUCKETS; i++, hb++) {
+		hb->obj_rb_root = RB_ROOT;
+		spin_lock_init(&hb->lock);
+	}
+	INIT_LIST_HEAD(&pool->pool_list);
+	atomic_set(&pool->obj_count, 0);
+	SET_SENTINEL(pool, POOL);
+	list_add_tail(&pool->pool_list, &tmem_global_pool_list);
+	pool->persistent = persistent;
+	pool->shared = shared;
+}
diff --git a/drivers/staging/ramster/tmem.h b/drivers/staging/ramster/tmem.h
new file mode 100644
index 0000000..47f1918
--- /dev/null
+++ b/drivers/staging/ramster/tmem.h
@@ -0,0 +1,244 @@
+/*
+ * tmem.h
+ *
+ * Transcendent memory
+ *
+ * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
+ */
+
+#ifndef _TMEM_H_
+#define _TMEM_H_
+
+#include <linux/highmem.h>
+#include <linux/hash.h>
+#include <linux/atomic.h>
+
+/*
+ * These are pre-defined by the Xen<->Linux ABI
+ */
+#define TMEM_PUT_PAGE			4
+#define TMEM_GET_PAGE			5
+#define TMEM_FLUSH_PAGE			6
+#define TMEM_FLUSH_OBJECT		7
+#define TMEM_POOL_PERSIST		1
+#define TMEM_POOL_SHARED		2
+#define TMEM_POOL_PRECOMPRESSED		4
+#define TMEM_POOL_PAGESIZE_SHIFT	4
+#define TMEM_POOL_PAGESIZE_MASK		0xf
+#define TMEM_POOL_RESERVED_BITS		0x00ffff00
+
+/*
+ * sentinels have proven very useful for debugging but can be removed
+ * or disabled before final merge.
+ */
+#define SENTINELS
+#ifdef SENTINELS
+#define DECL_SENTINEL uint32_t sentinel;
+#define SET_SENTINEL(_x, _y) (_x->sentinel = _y##_SENTINEL)
+#define INVERT_SENTINEL(_x, _y) (_x->sentinel = ~_y##_SENTINEL)
+#define ASSERT_SENTINEL(_x, _y) WARN_ON(_x->sentinel != _y##_SENTINEL)
+#define ASSERT_INVERTED_SENTINEL(_x, _y) WARN_ON(_x->sentinel != ~_y##_SENTINEL)
+#else
+#define DECL_SENTINEL
+#define SET_SENTINEL(_x, _y) do { } while (0)
+#define INVERT_SENTINEL(_x, _y) do { } while (0)
+#define ASSERT_SENTINEL(_x, _y) do { } while (0)
+#define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0)
+#endif
+
+#define ASSERT_SPINLOCK(_l)	WARN_ON(!spin_is_locked(_l))
+
+/*
+ * A pool is the highest-level data structure managed by tmem and
+ * usually corresponds to a large independent set of pages such as
+ * a filesystem.  Each pool has an id, and certain attributes and counters.
+ * It also contains a set of hash buckets, each of which contains an rbtree
+ * of objects and a lock to manage concurrency within the pool.
+ */
+
+#define TMEM_HASH_BUCKET_BITS	8
+#define TMEM_HASH_BUCKETS	(1<<TMEM_HASH_BUCKET_BITS)
+
+struct tmem_hashbucket {
+	struct rb_root obj_rb_root;
+	spinlock_t lock;
+};
+
+struct tmem_pool {
+	void *client; /* "up" for some clients, avoids table lookup */
+	struct list_head pool_list;
+	uint32_t pool_id;
+	bool persistent;
+	bool shared;
+	atomic_t obj_count;
+	atomic_t refcount;
+	struct tmem_hashbucket hashbucket[TMEM_HASH_BUCKETS];
+	DECL_SENTINEL
+};
+
+#define is_persistent(_p)  (_p->persistent)
+#define is_ephemeral(_p)   (!(_p->persistent))
+
+/*
+ * An object id ("oid") is large: 192-bits (to ensure, for example, files
+ * in a modern filesystem can be uniquely identified).
+ */
+
+struct tmem_oid {
+	uint64_t oid[3];
+};
+
+struct tmem_xhandle {
+	uint8_t client_id;
+	uint8_t xh_data_cksum;
+	uint16_t xh_data_size;
+	uint16_t pool_id;
+	struct tmem_oid oid;
+	uint32_t index;
+	void *extra;
+};
+
+static inline struct tmem_xhandle tmem_xhandle_fill(uint16_t client_id,
+					struct tmem_pool *pool,
+					struct tmem_oid *oidp,
+					uint32_t index)
+{
+	struct tmem_xhandle xh;
+	xh.client_id = client_id;
+	xh.xh_data_cksum = (uint8_t)-1;
+	xh.xh_data_size = (uint16_t)-1;
+	xh.pool_id = pool->pool_id;
+	xh.oid = *oidp;
+	xh.index = index;
+	return xh;
+}
+
+static inline void tmem_oid_set_invalid(struct tmem_oid *oidp)
+{
+	oidp->oid[0] = oidp->oid[1] = oidp->oid[2] = -1UL;
+}
+
+static inline bool tmem_oid_valid(struct tmem_oid *oidp)
+{
+	return oidp->oid[0] != -1UL || oidp->oid[1] != -1UL ||
+		oidp->oid[2] != -1UL;
+}
+
+static inline int tmem_oid_compare(struct tmem_oid *left,
+					struct tmem_oid *right)
+{
+	int ret;
+
+	if (left->oid[2] == right->oid[2]) {
+		if (left->oid[1] == right->oid[1]) {
+			if (left->oid[0] == right->oid[0])
+				ret = 0;
+			else if (left->oid[0] < right->oid[0])
+				ret = -1;
+			else
+				return 1;
+		} else if (left->oid[1] < right->oid[1])
+			ret = -1;
+		else
+			ret = 1;
+	} else if (left->oid[2] < right->oid[2])
+		ret = -1;
+	else
+		ret = 1;
+	return ret;
+}
+
+static inline unsigned tmem_oid_hash(struct tmem_oid *oidp)
+{
+	return hash_long(oidp->oid[0] ^ oidp->oid[1] ^ oidp->oid[2],
+				TMEM_HASH_BUCKET_BITS);
+}
+
+/*
+ * A tmem_obj contains an identifier (oid), pointers to the parent
+ * pool and the rb_tree to which it belongs, counters, and an ordered
+ * set of pampds, structured in a radix-tree-like tree.  The intermediate
+ * nodes of the tree are called tmem_objnodes.
+ */
+
+struct tmem_objnode;
+
+struct tmem_obj {
+	struct tmem_oid oid;
+	struct tmem_pool *pool;
+	struct rb_node rb_tree_node;
+	struct tmem_objnode *objnode_tree_root;
+	unsigned int objnode_tree_height;
+	unsigned long objnode_count;
+	long pampd_count;
+	/* for current design of ramster, all pages belonging to
+	 * an object reside on the same remotenode and extra is
+	 * used to record the number of the remotenode so a
+	 * flush-object operation can specify it */
+	void *extra; /* for use by pampd implementation */
+	DECL_SENTINEL
+};
+
+#define OBJNODE_TREE_MAP_SHIFT 6
+#define OBJNODE_TREE_MAP_SIZE (1UL << OBJNODE_TREE_MAP_SHIFT)
+#define OBJNODE_TREE_MAP_MASK (OBJNODE_TREE_MAP_SIZE-1)
+#define OBJNODE_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
+#define OBJNODE_TREE_MAX_PATH \
+		(OBJNODE_TREE_INDEX_BITS/OBJNODE_TREE_MAP_SHIFT + 2)
+
+struct tmem_objnode {
+	struct tmem_obj *obj;
+	DECL_SENTINEL
+	void *slots[OBJNODE_TREE_MAP_SIZE];
+	unsigned int slots_in_use;
+};
+
+/* pampd abstract datatype methods provided by the PAM implementation */
+struct tmem_pamops {
+	void *(*create)(char *, size_t, bool, int,
+			struct tmem_pool *, struct tmem_oid *, uint32_t);
+	int (*get_data)(char *, size_t *, bool, void *, struct tmem_pool *,
+				struct tmem_oid *, uint32_t);
+	int (*get_data_and_free)(char *, size_t *, bool, void *,
+				struct tmem_pool *, struct tmem_oid *,
+				uint32_t);
+	void (*free)(void *, struct tmem_pool *,
+				struct tmem_oid *, uint32_t, bool);
+	void (*free_obj)(struct tmem_pool *, struct tmem_obj *);
+	bool (*is_remote)(void *);
+	void *(*repatriate_preload)(void *, struct tmem_pool *,
+					struct tmem_oid *, uint32_t, bool *);
+	int (*repatriate)(void *, void *, struct tmem_pool *,
+				struct tmem_oid *, uint32_t, bool, void *);
+	void (*new_obj)(struct tmem_obj *);
+	int (*replace_in_obj)(void *, struct tmem_obj *);
+};
+extern void tmem_register_pamops(struct tmem_pamops *m);
+
+/* memory allocation methods provided by the host implementation */
+struct tmem_hostops {
+	struct tmem_obj *(*obj_alloc)(struct tmem_pool *);
+	void (*obj_free)(struct tmem_obj *, struct tmem_pool *);
+	struct tmem_objnode *(*objnode_alloc)(struct tmem_pool *);
+	void (*objnode_free)(struct tmem_objnode *, struct tmem_pool *);
+};
+extern void tmem_register_hostops(struct tmem_hostops *m);
+
+/* core tmem accessor functions */
+extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index,
+			char *, size_t, bool, int);
+extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index,
+			char *, size_t *, bool, int);
+extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index,
+			void *);
+extern void *tmem_localify_get_pampd(struct tmem_pool *, struct tmem_oid *,
+				   uint32_t index, struct tmem_obj **,
+				   void **);
+extern void tmem_localify_finish(struct tmem_obj *, uint32_t index,
+				 void *, void *, bool);
+extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *,
+			uint32_t index);
+extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *);
+extern int tmem_destroy_pool(struct tmem_pool *);
+extern void tmem_new_pool(struct tmem_pool *, uint32_t);
+#endif /* _TMEM_H */
diff --git a/drivers/staging/ramster/xvmalloc.c b/drivers/staging/ramster/xvmalloc.c
new file mode 100644
index 0000000..93ba8e9
--- /dev/null
+++ b/drivers/staging/ramster/xvmalloc.c
@@ -0,0 +1,509 @@
+/*
+ * xvmalloc memory allocator
+ *
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifdef CONFIG_ZRAM_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "xvmalloc.h"
+#include "xvmalloc_int.h"
+
+static void stat_inc(u64 *value)
+{
+	*value = *value + 1;
+}
+
+static void stat_dec(u64 *value)
+{
+	*value = *value - 1;
+}
+
+static int test_flag(struct block_header *block, enum blockflags flag)
+{
+	return block->prev & BIT(flag);
+}
+
+static void set_flag(struct block_header *block, enum blockflags flag)
+{
+	block->prev |= BIT(flag);
+}
+
+static void clear_flag(struct block_header *block, enum blockflags flag)
+{
+	block->prev &= ~BIT(flag);
+}
+
+/*
+ * Given <page, offset> pair, provide a dereferencable pointer.
+ * This is called from xv_malloc/xv_free path, so it
+ * needs to be fast.
+ */
+static void *get_ptr_atomic(struct page *page, u16 offset)
+{
+	unsigned char *base;
+
+	base = kmap_atomic(page);
+	return base + offset;
+}
+
+static void put_ptr_atomic(void *ptr)
+{
+	kunmap_atomic(ptr);
+}
+
+static u32 get_blockprev(struct block_header *block)
+{
+	return block->prev & PREV_MASK;
+}
+
+static void set_blockprev(struct block_header *block, u16 new_offset)
+{
+	block->prev = new_offset | (block->prev & FLAGS_MASK);
+}
+
+static struct block_header *BLOCK_NEXT(struct block_header *block)
+{
+	return (struct block_header *)
+		((char *)block + block->size + XV_ALIGN);
+}
+
+/*
+ * Get index of free list containing blocks of maximum size
+ * which is less than or equal to given size.
+ */
+static u32 get_index_for_insert(u32 size)
+{
+	if (unlikely(size > XV_MAX_ALLOC_SIZE))
+		size = XV_MAX_ALLOC_SIZE;
+	size &= ~FL_DELTA_MASK;
+	return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT;
+}
+
+/*
+ * Get index of free list having blocks of size greater than
+ * or equal to requested size.
+ */
+static u32 get_index(u32 size)
+{
+	if (unlikely(size < XV_MIN_ALLOC_SIZE))
+		size = XV_MIN_ALLOC_SIZE;
+	size = ALIGN(size, FL_DELTA);
+	return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT;
+}
+
+/**
+ * find_block - find block of at least given size
+ * @pool: memory pool to search from
+ * @size: size of block required
+ * @page: page containing required block
+ * @offset: offset within the page where block is located.
+ *
+ * Searches two level bitmap to locate block of at least
+ * the given size. If such a block is found, it provides
+ * <page, offset> to identify this block and returns index
+ * in freelist where we found this block.
+ * Otherwise, returns 0 and <page, offset> params are not touched.
+ */
+static u32 find_block(struct xv_pool *pool, u32 size,
+			struct page **page, u32 *offset)
+{
+	ulong flbitmap, slbitmap;
+	u32 flindex, slindex, slbitstart;
+
+	/* There are no free blocks in this pool */
+	if (!pool->flbitmap)
+		return 0;
+
+	/* Get freelist index correspoding to this size */
+	slindex = get_index(size);
+	slbitmap = pool->slbitmap[slindex / BITS_PER_LONG];
+	slbitstart = slindex % BITS_PER_LONG;
+
+	/*
+	 * If freelist is not empty at this index, we found the
+	 * block - head of this list. This is approximate best-fit match.
+	 */
+	if (test_bit(slbitstart, &slbitmap)) {
+		*page = pool->freelist[slindex].page;
+		*offset = pool->freelist[slindex].offset;
+		return slindex;
+	}
+
+	/*
+	 * No best-fit found. Search a bit further in bitmap for a free block.
+	 * Second level bitmap consists of series of 32-bit chunks. Search
+	 * further in the chunk where we expected a best-fit, starting from
+	 * index location found above.
+	 */
+	slbitstart++;
+	slbitmap >>= slbitstart;
+
+	/* Skip this search if we were already at end of this bitmap chunk */
+	if ((slbitstart != BITS_PER_LONG) && slbitmap) {
+		slindex += __ffs(slbitmap) + 1;
+		*page = pool->freelist[slindex].page;
+		*offset = pool->freelist[slindex].offset;
+		return slindex;
+	}
+
+	/* Now do a full two-level bitmap search to find next nearest fit */
+	flindex = slindex / BITS_PER_LONG;
+
+	flbitmap = (pool->flbitmap) >> (flindex + 1);
+	if (!flbitmap)
+		return 0;
+
+	flindex += __ffs(flbitmap) + 1;
+	slbitmap = pool->slbitmap[flindex];
+	slindex = (flindex * BITS_PER_LONG) + __ffs(slbitmap);
+	*page = pool->freelist[slindex].page;
+	*offset = pool->freelist[slindex].offset;
+
+	return slindex;
+}
+
+/*
+ * Insert block at <page, offset> in freelist of given pool.
+ * freelist used depends on block size.
+ */
+static void insert_block(struct xv_pool *pool, struct page *page, u32 offset,
+			struct block_header *block)
+{
+	u32 flindex, slindex;
+	struct block_header *nextblock;
+
+	slindex = get_index_for_insert(block->size);
+	flindex = slindex / BITS_PER_LONG;
+
+	block->link.prev_page = NULL;
+	block->link.prev_offset = 0;
+	block->link.next_page = pool->freelist[slindex].page;
+	block->link.next_offset = pool->freelist[slindex].offset;
+	pool->freelist[slindex].page = page;
+	pool->freelist[slindex].offset = offset;
+
+	if (block->link.next_page) {
+		nextblock = get_ptr_atomic(block->link.next_page,
+					block->link.next_offset);
+		nextblock->link.prev_page = page;
+		nextblock->link.prev_offset = offset;
+		put_ptr_atomic(nextblock);
+		/* If there was a next page then the free bits are set. */
+		return;
+	}
+
+	__set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]);
+	__set_bit(flindex, &pool->flbitmap);
+}
+
+/*
+ * Remove block from freelist. Index 'slindex' identifies the freelist.
+ */
+static void remove_block(struct xv_pool *pool, struct page *page, u32 offset,
+			struct block_header *block, u32 slindex)
+{
+	u32 flindex = slindex / BITS_PER_LONG;
+	struct block_header *tmpblock;
+
+	if (block->link.prev_page) {
+		tmpblock = get_ptr_atomic(block->link.prev_page,
+				block->link.prev_offset);
+		tmpblock->link.next_page = block->link.next_page;
+		tmpblock->link.next_offset = block->link.next_offset;
+		put_ptr_atomic(tmpblock);
+	}
+
+	if (block->link.next_page) {
+		tmpblock = get_ptr_atomic(block->link.next_page,
+				block->link.next_offset);
+		tmpblock->link.prev_page = block->link.prev_page;
+		tmpblock->link.prev_offset = block->link.prev_offset;
+		put_ptr_atomic(tmpblock);
+	}
+
+	/* Is this block is at the head of the freelist? */
+	if (pool->freelist[slindex].page == page
+	   && pool->freelist[slindex].offset == offset) {
+
+		pool->freelist[slindex].page = block->link.next_page;
+		pool->freelist[slindex].offset = block->link.next_offset;
+
+		if (pool->freelist[slindex].page) {
+			struct block_header *tmpblock;
+			tmpblock = get_ptr_atomic(pool->freelist[slindex].page,
+					pool->freelist[slindex].offset);
+			tmpblock->link.prev_page = NULL;
+			tmpblock->link.prev_offset = 0;
+			put_ptr_atomic(tmpblock);
+		} else {
+			/* This freelist bucket is empty */
+			__clear_bit(slindex % BITS_PER_LONG,
+				    &pool->slbitmap[flindex]);
+			if (!pool->slbitmap[flindex])
+				__clear_bit(flindex, &pool->flbitmap);
+		}
+	}
+
+	block->link.prev_page = NULL;
+	block->link.prev_offset = 0;
+	block->link.next_page = NULL;
+	block->link.next_offset = 0;
+}
+
+/*
+ * Allocate a page and add it to freelist of given pool.
+ */
+static int grow_pool(struct xv_pool *pool, gfp_t flags)
+{
+	struct page *page;
+	struct block_header *block;
+
+	page = alloc_page(flags);
+	if (unlikely(!page))
+		return -ENOMEM;
+
+	stat_inc(&pool->total_pages);
+
+	spin_lock(&pool->lock);
+	block = get_ptr_atomic(page, 0);
+
+	block->size = PAGE_SIZE - XV_ALIGN;
+	set_flag(block, BLOCK_FREE);
+	clear_flag(block, PREV_FREE);
+	set_blockprev(block, 0);
+
+	insert_block(pool, page, 0, block);
+
+	put_ptr_atomic(block);
+	spin_unlock(&pool->lock);
+
+	return 0;
+}
+
+/*
+ * Create a memory pool. Allocates freelist, bitmaps and other
+ * per-pool metadata.
+ */
+struct xv_pool *xv_create_pool(void)
+{
+	u32 ovhd_size;
+	struct xv_pool *pool;
+
+	ovhd_size = roundup(sizeof(*pool), PAGE_SIZE);
+	pool = kzalloc(ovhd_size, GFP_KERNEL);
+	if (!pool)
+		return NULL;
+
+	spin_lock_init(&pool->lock);
+
+	return pool;
+}
+EXPORT_SYMBOL_GPL(xv_create_pool);
+
+void xv_destroy_pool(struct xv_pool *pool)
+{
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(xv_destroy_pool);
+
+/**
+ * xv_malloc - Allocate block of given size from pool.
+ * @pool: pool to allocate from
+ * @size: size of block to allocate
+ * @page: page no. that holds the object
+ * @offset: location of object within page
+ *
+ * On success, <page, offset> identifies block allocated
+ * and 0 is returned. On failure, <page, offset> is set to
+ * 0 and -ENOMEM is returned.
+ *
+ * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail.
+ */
+int xv_malloc(struct xv_pool *pool, u32 size, struct page **page,
+		u32 *offset, gfp_t flags)
+{
+	int error;
+	u32 index, tmpsize, origsize, tmpoffset;
+	struct block_header *block, *tmpblock;
+
+	*page = NULL;
+	*offset = 0;
+	origsize = size;
+
+	if (unlikely(!size || size > XV_MAX_ALLOC_SIZE))
+		return -ENOMEM;
+
+	size = ALIGN(size, XV_ALIGN);
+
+	spin_lock(&pool->lock);
+
+	index = find_block(pool, size, page, offset);
+
+	if (!*page) {
+		spin_unlock(&pool->lock);
+		if (flags & GFP_NOWAIT)
+			return -ENOMEM;
+		error = grow_pool(pool, flags);
+		if (unlikely(error))
+			return error;
+
+		spin_lock(&pool->lock);
+		index = find_block(pool, size, page, offset);
+	}
+
+	if (!*page) {
+		spin_unlock(&pool->lock);
+		return -ENOMEM;
+	}
+
+	block = get_ptr_atomic(*page, *offset);
+
+	remove_block(pool, *page, *offset, block, index);
+
+	/* Split the block if required */
+	tmpoffset = *offset + size + XV_ALIGN;
+	tmpsize = block->size - size;
+	tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN);
+	if (tmpsize) {
+		tmpblock->size = tmpsize - XV_ALIGN;
+		set_flag(tmpblock, BLOCK_FREE);
+		clear_flag(tmpblock, PREV_FREE);
+
+		set_blockprev(tmpblock, *offset);
+		if (tmpblock->size >= XV_MIN_ALLOC_SIZE)
+			insert_block(pool, *page, tmpoffset, tmpblock);
+
+		if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) {
+			tmpblock = BLOCK_NEXT(tmpblock);
+			set_blockprev(tmpblock, tmpoffset);
+		}
+	} else {
+		/* This block is exact fit */
+		if (tmpoffset != PAGE_SIZE)
+			clear_flag(tmpblock, PREV_FREE);
+	}
+
+	block->size = origsize;
+	clear_flag(block, BLOCK_FREE);
+
+	put_ptr_atomic(block);
+	spin_unlock(&pool->lock);
+
+	*offset += XV_ALIGN;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xv_malloc);
+
+/*
+ * Free block identified with <page, offset>
+ */
+void xv_free(struct xv_pool *pool, struct page *page, u32 offset)
+{
+	void *page_start;
+	struct block_header *block, *tmpblock;
+
+	offset -= XV_ALIGN;
+
+	spin_lock(&pool->lock);
+
+	page_start = get_ptr_atomic(page, 0);
+	block = (struct block_header *)((char *)page_start + offset);
+
+	/* Catch double free bugs */
+	BUG_ON(test_flag(block, BLOCK_FREE));
+
+	block->size = ALIGN(block->size, XV_ALIGN);
+
+	tmpblock = BLOCK_NEXT(block);
+	if (offset + block->size + XV_ALIGN == PAGE_SIZE)
+		tmpblock = NULL;
+
+	/* Merge next block if its free */
+	if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) {
+		/*
+		 * Blocks smaller than XV_MIN_ALLOC_SIZE
+		 * are not inserted in any free list.
+		 */
+		if (tmpblock->size >= XV_MIN_ALLOC_SIZE) {
+			remove_block(pool, page,
+				    offset + block->size + XV_ALIGN, tmpblock,
+				    get_index_for_insert(tmpblock->size));
+		}
+		block->size += tmpblock->size + XV_ALIGN;
+	}
+
+	/* Merge previous block if its free */
+	if (test_flag(block, PREV_FREE)) {
+		tmpblock = (struct block_header *)((char *)(page_start) +
+						get_blockprev(block));
+		offset = offset - tmpblock->size - XV_ALIGN;
+
+		if (tmpblock->size >= XV_MIN_ALLOC_SIZE)
+			remove_block(pool, page, offset, tmpblock,
+				    get_index_for_insert(tmpblock->size));
+
+		tmpblock->size += block->size + XV_ALIGN;
+		block = tmpblock;
+	}
+
+	/* No used objects in this page. Free it. */
+	if (block->size == PAGE_SIZE - XV_ALIGN) {
+		put_ptr_atomic(page_start);
+		spin_unlock(&pool->lock);
+
+		__free_page(page);
+		stat_dec(&pool->total_pages);
+		return;
+	}
+
+	set_flag(block, BLOCK_FREE);
+	if (block->size >= XV_MIN_ALLOC_SIZE)
+		insert_block(pool, page, offset, block);
+
+	if (offset + block->size + XV_ALIGN != PAGE_SIZE) {
+		tmpblock = BLOCK_NEXT(block);
+		set_flag(tmpblock, PREV_FREE);
+		set_blockprev(tmpblock, offset);
+	}
+
+	put_ptr_atomic(page_start);
+	spin_unlock(&pool->lock);
+}
+EXPORT_SYMBOL_GPL(xv_free);
+
+u32 xv_get_object_size(void *obj)
+{
+	struct block_header *blk;
+
+	blk = (struct block_header *)((char *)(obj) - XV_ALIGN);
+	return blk->size;
+}
+EXPORT_SYMBOL_GPL(xv_get_object_size);
+
+/*
+ * Returns total memory used by allocator (userdata + metadata)
+ */
+u64 xv_get_total_size_bytes(struct xv_pool *pool)
+{
+	return pool->total_pages << PAGE_SHIFT;
+}
+EXPORT_SYMBOL_GPL(xv_get_total_size_bytes);
diff --git a/drivers/staging/ramster/xvmalloc.h b/drivers/staging/ramster/xvmalloc.h
new file mode 100644
index 0000000..5b1a81a
--- /dev/null
+++ b/drivers/staging/ramster/xvmalloc.h
@@ -0,0 +1,30 @@
+/*
+ * xvmalloc memory allocator
+ *
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifndef _XV_MALLOC_H_
+#define _XV_MALLOC_H_
+
+#include <linux/types.h>
+
+struct xv_pool;
+
+struct xv_pool *xv_create_pool(void);
+void xv_destroy_pool(struct xv_pool *pool);
+
+int xv_malloc(struct xv_pool *pool, u32 size, struct page **page,
+			u32 *offset, gfp_t flags);
+void xv_free(struct xv_pool *pool, struct page *page, u32 offset);
+
+u32 xv_get_object_size(void *obj);
+u64 xv_get_total_size_bytes(struct xv_pool *pool);
+
+#endif
diff --git a/drivers/staging/ramster/xvmalloc_int.h b/drivers/staging/ramster/xvmalloc_int.h
new file mode 100644
index 0000000..b5f1f7f
--- /dev/null
+++ b/drivers/staging/ramster/xvmalloc_int.h
@@ -0,0 +1,95 @@
+/*
+ * xvmalloc memory allocator
+ *
+ * Copyright (C) 2008, 2009, 2010  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifndef _XV_MALLOC_INT_H_
+#define _XV_MALLOC_INT_H_
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/* User configurable params */
+
+/* Must be power of two */
+#ifdef CONFIG_64BIT
+#define XV_ALIGN_SHIFT 3
+#else
+#define XV_ALIGN_SHIFT	2
+#endif
+#define XV_ALIGN	(1 << XV_ALIGN_SHIFT)
+#define XV_ALIGN_MASK	(XV_ALIGN - 1)
+
+/* This must be greater than sizeof(link_free) */
+#define XV_MIN_ALLOC_SIZE	32
+#define XV_MAX_ALLOC_SIZE	(PAGE_SIZE - XV_ALIGN)
+
+/*
+ * Free lists are separated by FL_DELTA bytes
+ * This value is 3 for 4k pages and 4 for 64k pages, for any
+ * other page size, a conservative (PAGE_SHIFT - 9) is used.
+ */
+#if PAGE_SHIFT == 16
+#define FL_DELTA_SHIFT 4
+#else
+#define FL_DELTA_SHIFT (PAGE_SHIFT - 9)
+#endif
+#define FL_DELTA	(1 << FL_DELTA_SHIFT)
+#define FL_DELTA_MASK	(FL_DELTA - 1)
+#define NUM_FREE_LISTS	((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \
+				/ FL_DELTA + 1)
+
+#define MAX_FLI		DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG)
+
+/* End of user params */
+
+enum blockflags {
+	BLOCK_FREE,
+	PREV_FREE,
+	__NR_BLOCKFLAGS,
+};
+
+#define FLAGS_MASK	XV_ALIGN_MASK
+#define PREV_MASK	(~FLAGS_MASK)
+
+struct freelist_entry {
+	struct page *page;
+	u16 offset;
+	u16 pad;
+};
+
+struct link_free {
+	struct page *prev_page;
+	struct page *next_page;
+	u16 prev_offset;
+	u16 next_offset;
+};
+
+struct block_header {
+	union {
+		/* This common header must be XV_ALIGN bytes */
+		u8 common[XV_ALIGN];
+		struct {
+			u16 size;
+			u16 prev;
+		};
+	};
+	struct link_free link;
+};
+
+struct xv_pool {
+	ulong flbitmap;
+	ulong slbitmap[MAX_FLI];
+	u64 total_pages;	/* stats */
+	struct freelist_entry freelist[NUM_FREE_LISTS];
+	spinlock_t lock;
+};
+
+#endif
diff --git a/drivers/staging/ramster/zcache-main.c b/drivers/staging/ramster/zcache-main.c
new file mode 100644
index 0000000..36d53ed
--- /dev/null
+++ b/drivers/staging/ramster/zcache-main.c
@@ -0,0 +1,3320 @@
+/*
+ * zcache.c
+ *
+ * Copyright (c) 2010-2012, Dan Magenheimer, Oracle Corp.
+ * Copyright (c) 2010,2011, Nitin Gupta
+ *
+ * Zcache provides an in-kernel "host implementation" for transcendent memory
+ * and, thus indirectly, for cleancache and frontswap.  Zcache includes two
+ * page-accessible memory [1] interfaces, both utilizing lzo1x compression:
+ * 1) "compression buddies" ("zbud") is used for ephemeral pages
+ * 2) xvmalloc is used for persistent pages.
+ * Xvmalloc (based on the TLSF allocator) has very low fragmentation
+ * so maximizes space efficiency, while zbud allows pairs (and potentially,
+ * in the future, more than a pair of) compressed pages to be closely linked
+ * so that reclaiming can be done via the kernel's physical-page-oriented
+ * "shrinker" interface.
+ *
+ * [1] For a definition of page-accessible memory (aka PAM), see:
+ *   http://marc.info/?l=linux-mm&m=127811271605009
+ *  RAMSTER TODO:
+ *   - handle remotifying of buddied pages (see zbud_remotify_zbpg)
+ *   - kernel boot params: nocleancache/nofrontswap don't always work?!?
+ */
+
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/highmem.h>
+#include <linux/list.h>
+#include <linux/lzo.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/atomic.h>
+#include <linux/math64.h>
+#include "tmem.h"
+#include "zcache.h"
+#include "ramster.h"
+#include "cluster/tcp.h"
+
+#include "xvmalloc.h"	/* temporary until change to zsmalloc */
+
+#define	RAMSTER_TESTING
+
+#if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP))
+#error "ramster is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP"
+#endif
+#ifdef CONFIG_CLEANCACHE
+#include <linux/cleancache.h>
+#endif
+#ifdef CONFIG_FRONTSWAP
+#include <linux/frontswap.h>
+#endif
+
+enum ramster_remotify_op {
+	RAMSTER_REMOTIFY_EPH_PUT,
+	RAMSTER_REMOTIFY_PERS_PUT,
+	RAMSTER_REMOTIFY_FLUSH_PAGE,
+	RAMSTER_REMOTIFY_FLUSH_OBJ,
+	RAMSTER_INTRANSIT_PERS
+};
+
+struct ramster_remotify_hdr {
+	enum ramster_remotify_op op;
+	struct list_head list;
+};
+
+#define ZBH_SENTINEL  0x43214321
+#define ZBPG_SENTINEL  0xdeadbeef
+
+#define ZBUD_MAX_BUDS 2
+
+struct zbud_hdr {
+	struct ramster_remotify_hdr rem_op;
+	uint16_t client_id;
+	uint16_t pool_id;
+	struct tmem_oid oid;
+	uint32_t index;
+	uint16_t size; /* compressed size in bytes, zero means unused */
+	DECL_SENTINEL
+};
+
+#define ZVH_SENTINEL  0x43214321
+static const int zv_max_page_size = (PAGE_SIZE / 8) * 7;
+
+struct zv_hdr {
+	struct ramster_remotify_hdr rem_op;
+	uint16_t client_id;
+	uint16_t pool_id;
+	struct tmem_oid oid;
+	uint32_t index;
+	DECL_SENTINEL
+};
+
+struct flushlist_node {
+	struct ramster_remotify_hdr rem_op;
+	struct tmem_xhandle xh;
+};
+
+union {
+	struct ramster_remotify_hdr rem_op;
+	struct zv_hdr zv;
+	struct zbud_hdr zbud;
+	struct flushlist_node flist;
+} remotify_list_node;
+
+static LIST_HEAD(zcache_rem_op_list);
+static DEFINE_SPINLOCK(zcache_rem_op_list_lock);
+
+#if 0
+/* this is more aggressive but may cause other problems? */
+#define ZCACHE_GFP_MASK	(GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN)
+#else
+#define ZCACHE_GFP_MASK \
+	(__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC)
+#endif
+
+#define MAX_POOLS_PER_CLIENT 16
+
+#define MAX_CLIENTS 16
+#define LOCAL_CLIENT ((uint16_t)-1)
+
+MODULE_LICENSE("GPL");
+
+struct zcache_client {
+	struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT];
+	struct xv_pool *xvpool;
+	bool allocated;
+	atomic_t refcount;
+};
+
+static struct zcache_client zcache_host;
+static struct zcache_client zcache_clients[MAX_CLIENTS];
+
+static inline uint16_t get_client_id_from_client(struct zcache_client *cli)
+{
+	BUG_ON(cli == NULL);
+	if (cli == &zcache_host)
+		return LOCAL_CLIENT;
+	return cli - &zcache_clients[0];
+}
+
+static inline bool is_local_client(struct zcache_client *cli)
+{
+	return cli == &zcache_host;
+}
+
+/**********
+ * Compression buddies ("zbud") provides for packing two (or, possibly
+ * in the future, more) compressed ephemeral pages into a single "raw"
+ * (physical) page and tracking them with data structures so that
+ * the raw pages can be easily reclaimed.
+ *
+ * A zbud page ("zbpg") is an aligned page containing a list_head,
+ * a lock, and two "zbud headers".  The remainder of the physical
+ * page is divided up into aligned 64-byte "chunks" which contain
+ * the compressed data for zero, one, or two zbuds.  Each zbpg
+ * resides on: (1) an "unused list" if it has no zbuds; (2) a
+ * "buddied" list if it is fully populated  with two zbuds; or
+ * (3) one of PAGE_SIZE/64 "unbuddied" lists indexed by how many chunks
+ * the one unbuddied zbud uses.  The data inside a zbpg cannot be
+ * read or written unless the zbpg's lock is held.
+ */
+
+struct zbud_page {
+	struct list_head bud_list;
+	spinlock_t lock;
+	struct zbud_hdr buddy[ZBUD_MAX_BUDS];
+	DECL_SENTINEL
+	/* followed by NUM_CHUNK aligned CHUNK_SIZE-byte chunks */
+};
+
+#define CHUNK_SHIFT	6
+#define CHUNK_SIZE	(1 << CHUNK_SHIFT)
+#define CHUNK_MASK	(~(CHUNK_SIZE-1))
+#define NCHUNKS		(((PAGE_SIZE - sizeof(struct zbud_page)) & \
+				CHUNK_MASK) >> CHUNK_SHIFT)
+#define MAX_CHUNK	(NCHUNKS-1)
+
+static struct {
+	struct list_head list;
+	unsigned count;
+} zbud_unbuddied[NCHUNKS];
+/* list N contains pages with N chunks USED and NCHUNKS-N unused */
+/* element 0 is never used but optimizing that isn't worth it */
+static unsigned long zbud_cumul_chunk_counts[NCHUNKS];
+
+struct list_head zbud_buddied_list;
+static unsigned long zcache_zbud_buddied_count;
+
+/* protects the buddied list and all unbuddied lists */
+static DEFINE_SPINLOCK(zbud_budlists_spinlock);
+
+static atomic_t zcache_zbud_curr_raw_pages;
+static atomic_t zcache_zbud_curr_zpages;
+static unsigned long zcache_zbud_curr_zbytes;
+static unsigned long zcache_zbud_cumul_zpages;
+static unsigned long zcache_zbud_cumul_zbytes;
+static unsigned long zcache_compress_poor;
+static unsigned long zcache_policy_percent_exceeded;
+static unsigned long zcache_mean_compress_poor;
+
+/*
+ * RAMster counters
+ * - Remote pages are pages with a local pampd but the data is remote
+ * - Foreign pages are pages stored locally but belonging to another node
+ */
+static atomic_t ramster_remote_pers_pages = ATOMIC_INIT(0);
+static unsigned long ramster_pers_remotify_enable;
+static unsigned long ramster_eph_remotify_enable;
+static unsigned long ramster_eph_pages_remoted;
+static unsigned long ramster_eph_pages_remote_failed;
+static unsigned long ramster_pers_pages_remoted;
+static unsigned long ramster_pers_pages_remote_failed;
+static unsigned long ramster_pers_pages_remote_nomem;
+static unsigned long ramster_remote_objects_flushed;
+static unsigned long ramster_remote_object_flushes_failed;
+static unsigned long ramster_remote_pages_flushed;
+static unsigned long ramster_remote_page_flushes_failed;
+static unsigned long ramster_remote_eph_pages_succ_get;
+static unsigned long ramster_remote_pers_pages_succ_get;
+static unsigned long ramster_remote_eph_pages_unsucc_get;
+static unsigned long ramster_remote_pers_pages_unsucc_get;
+static atomic_t ramster_curr_flnode_count = ATOMIC_INIT(0);
+static unsigned long ramster_curr_flnode_count_max;
+static atomic_t ramster_foreign_eph_pampd_count = ATOMIC_INIT(0);
+static unsigned long ramster_foreign_eph_pampd_count_max;
+static atomic_t ramster_foreign_pers_pampd_count = ATOMIC_INIT(0);
+static unsigned long ramster_foreign_pers_pampd_count_max;
+
+/* forward references */
+static void *zcache_get_free_page(void);
+static void zcache_free_page(void *p);
+
+/*
+ * zbud helper functions
+ */
+
+static inline unsigned zbud_max_buddy_size(void)
+{
+	return MAX_CHUNK << CHUNK_SHIFT;
+}
+
+static inline unsigned zbud_size_to_chunks(unsigned size)
+{
+	BUG_ON(size == 0 || size > zbud_max_buddy_size());
+	return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT;
+}
+
+static inline int zbud_budnum(struct zbud_hdr *zh)
+{
+	unsigned offset = (unsigned long)zh & (PAGE_SIZE - 1);
+	struct zbud_page *zbpg = NULL;
+	unsigned budnum = -1U;
+	int i;
+
+	for (i = 0; i < ZBUD_MAX_BUDS; i++)
+		if (offset == offsetof(typeof(*zbpg), buddy[i])) {
+			budnum = i;
+			break;
+		}
+	BUG_ON(budnum == -1U);
+	return budnum;
+}
+
+static char *zbud_data(struct zbud_hdr *zh, unsigned size)
+{
+	struct zbud_page *zbpg;
+	char *p;
+	unsigned budnum;
+
+	ASSERT_SENTINEL(zh, ZBH);
+	budnum = zbud_budnum(zh);
+	BUG_ON(size == 0 || size > zbud_max_buddy_size());
+	zbpg = container_of(zh, struct zbud_page, buddy[budnum]);
+	ASSERT_SPINLOCK(&zbpg->lock);
+	p = (char *)zbpg;
+	if (budnum == 0)
+		p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) &
+							CHUNK_MASK);
+	else if (budnum == 1)
+		p += PAGE_SIZE - ((size + CHUNK_SIZE - 1) & CHUNK_MASK);
+	return p;
+}
+
+static void zbud_copy_from_pampd(char *data, size_t *size, struct zbud_hdr *zh)
+{
+	struct zbud_page *zbpg;
+	char *p;
+	unsigned budnum;
+
+	ASSERT_SENTINEL(zh, ZBH);
+	budnum = zbud_budnum(zh);
+	zbpg = container_of(zh, struct zbud_page, buddy[budnum]);
+	spin_lock(&zbpg->lock);
+	BUG_ON(zh->size > *size);
+	p = (char *)zbpg;
+	if (budnum == 0)
+		p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) &
+							CHUNK_MASK);
+	else if (budnum == 1)
+		p += PAGE_SIZE - ((zh->size + CHUNK_SIZE - 1) & CHUNK_MASK);
+	/* client should be filled in by caller */
+	memcpy(data, p, zh->size);
+	*size = zh->size;
+	spin_unlock(&zbpg->lock);
+}
+
+/*
+ * zbud raw page management
+ */
+
+static struct zbud_page *zbud_alloc_raw_page(void)
+{
+	struct zbud_page *zbpg = NULL;
+	struct zbud_hdr *zh0, *zh1;
+		zbpg = zcache_get_free_page();
+	if (likely(zbpg != NULL)) {
+		INIT_LIST_HEAD(&zbpg->bud_list);
+		zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1];
+		spin_lock_init(&zbpg->lock);
+		atomic_inc(&zcache_zbud_curr_raw_pages);
+		INIT_LIST_HEAD(&zbpg->bud_list);
+		SET_SENTINEL(zbpg, ZBPG);
+		zh0->size = 0; zh1->size = 0;
+		tmem_oid_set_invalid(&zh0->oid);
+		tmem_oid_set_invalid(&zh1->oid);
+	}
+	return zbpg;
+}
+
+static void zbud_free_raw_page(struct zbud_page *zbpg)
+{
+	struct zbud_hdr *zh0 = &zbpg->buddy[0], *zh1 = &zbpg->buddy[1];
+
+	ASSERT_SENTINEL(zbpg, ZBPG);
+	BUG_ON(!list_empty(&zbpg->bud_list));
+	ASSERT_SPINLOCK(&zbpg->lock);
+	BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid));
+	BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid));
+	INVERT_SENTINEL(zbpg, ZBPG);
+	spin_unlock(&zbpg->lock);
+	atomic_dec(&zcache_zbud_curr_raw_pages);
+	zcache_free_page(zbpg);
+}
+
+/*
+ * core zbud handling routines
+ */
+
+static unsigned zbud_free(struct zbud_hdr *zh)
+{
+	unsigned size;
+
+	ASSERT_SENTINEL(zh, ZBH);
+	BUG_ON(!tmem_oid_valid(&zh->oid));
+	size = zh->size;
+	BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size());
+	zh->size = 0;
+	tmem_oid_set_invalid(&zh->oid);
+	INVERT_SENTINEL(zh, ZBH);
+	zcache_zbud_curr_zbytes -= size;
+	atomic_dec(&zcache_zbud_curr_zpages);
+	return size;
+}
+
+static void zbud_free_and_delist(struct zbud_hdr *zh)
+{
+	unsigned chunks;
+	struct zbud_hdr *zh_other;
+	unsigned budnum = zbud_budnum(zh), size;
+	struct zbud_page *zbpg =
+		container_of(zh, struct zbud_page, buddy[budnum]);
+
+	/* FIXME, should be BUG_ON, pool destruction path doesn't disable
+	 * interrupts tmem_destroy_pool()->tmem_pampd_destroy_all_in_obj()->
+	 * tmem_objnode_node_destroy()-> zcache_pampd_free() */
+	WARN_ON(!irqs_disabled());
+	spin_lock(&zbpg->lock);
+	if (list_empty(&zbpg->bud_list)) {
+		/* ignore zombie page... see zbud_evict_pages() */
+		spin_unlock(&zbpg->lock);
+		return;
+	}
+	size = zbud_free(zh);
+	ASSERT_SPINLOCK(&zbpg->lock);
+	zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0];
+	if (zh_other->size == 0) { /* was unbuddied: unlist and free */
+		chunks = zbud_size_to_chunks(size) ;
+		spin_lock(&zbud_budlists_spinlock);
+		BUG_ON(list_empty(&zbud_unbuddied[chunks].list));
+		list_del_init(&zbpg->bud_list);
+		zbud_unbuddied[chunks].count--;
+		spin_unlock(&zbud_budlists_spinlock);
+		zbud_free_raw_page(zbpg);
+	} else { /* was buddied: move remaining buddy to unbuddied list */
+		chunks = zbud_size_to_chunks(zh_other->size) ;
+		spin_lock(&zbud_budlists_spinlock);
+		list_del_init(&zbpg->bud_list);
+		zcache_zbud_buddied_count--;
+		list_add_tail(&zbpg->bud_list, &zbud_unbuddied[chunks].list);
+		zbud_unbuddied[chunks].count++;
+		spin_unlock(&zbud_budlists_spinlock);
+		spin_unlock(&zbpg->lock);
+	}
+}
+
+static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id,
+					struct tmem_oid *oid,
+					uint32_t index, struct page *page,
+					void *cdata, unsigned size)
+{
+	struct zbud_hdr *zh0, *zh1, *zh = NULL;
+	struct zbud_page *zbpg = NULL, *ztmp;
+	unsigned nchunks;
+	char *to;
+	int i, found_good_buddy = 0;
+
+	nchunks = zbud_size_to_chunks(size) ;
+	for (i = MAX_CHUNK - nchunks + 1; i > 0; i--) {
+		spin_lock(&zbud_budlists_spinlock);
+		if (!list_empty(&zbud_unbuddied[i].list)) {
+			list_for_each_entry_safe(zbpg, ztmp,
+				    &zbud_unbuddied[i].list, bud_list) {
+				if (spin_trylock(&zbpg->lock)) {
+					found_good_buddy = i;
+					goto found_unbuddied;
+				}
+			}
+		}
+		spin_unlock(&zbud_budlists_spinlock);
+	}
+	/* didn't find a good buddy, try allocating a new page */
+	zbpg = zbud_alloc_raw_page();
+	if (unlikely(zbpg == NULL))
+		goto out;
+	/* ok, have a page, now compress the data before taking locks */
+	spin_lock(&zbud_budlists_spinlock);
+	spin_lock(&zbpg->lock);
+	list_add_tail(&zbpg->bud_list, &zbud_unbuddied[nchunks].list);
+	zbud_unbuddied[nchunks].count++;
+	zh = &zbpg->buddy[0];
+	goto init_zh;
+
+found_unbuddied:
+	ASSERT_SPINLOCK(&zbpg->lock);
+	zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1];
+	BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0)));
+	if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */
+		ASSERT_SENTINEL(zh0, ZBH);
+		zh = zh1;
+	} else if (zh1->size != 0) { /* buddy1 in use, buddy0 is vacant */
+		ASSERT_SENTINEL(zh1, ZBH);
+		zh = zh0;
+	} else
+		BUG();
+	list_del_init(&zbpg->bud_list);
+	zbud_unbuddied[found_good_buddy].count--;
+	list_add_tail(&zbpg->bud_list, &zbud_buddied_list);
+	zcache_zbud_buddied_count++;
+
+init_zh:
+	SET_SENTINEL(zh, ZBH);
+	zh->size = size;
+	zh->index = index;
+	zh->oid = *oid;
+	zh->pool_id = pool_id;
+	zh->client_id = client_id;
+	to = zbud_data(zh, size);
+	memcpy(to, cdata, size);
+	spin_unlock(&zbpg->lock);
+	spin_unlock(&zbud_budlists_spinlock);
+	zbud_cumul_chunk_counts[nchunks]++;
+	atomic_inc(&zcache_zbud_curr_zpages);
+	zcache_zbud_cumul_zpages++;
+	zcache_zbud_curr_zbytes += size;
+	zcache_zbud_cumul_zbytes += size;
+out:
+	return zh;
+}
+
+static int zbud_decompress(struct page *page, struct zbud_hdr *zh)
+{
+	struct zbud_page *zbpg;
+	unsigned budnum = zbud_budnum(zh);
+	size_t out_len = PAGE_SIZE;
+	char *to_va, *from_va;
+	unsigned size;
+	int ret = 0;
+
+	zbpg = container_of(zh, struct zbud_page, buddy[budnum]);
+	spin_lock(&zbpg->lock);
+	if (list_empty(&zbpg->bud_list)) {
+		/* ignore zombie page... see zbud_evict_pages() */
+		ret = -EINVAL;
+		goto out;
+	}
+	ASSERT_SENTINEL(zh, ZBH);
+	BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size());
+	to_va = kmap_atomic(page, KM_USER0);
+	size = zh->size;
+	from_va = zbud_data(zh, size);
+	ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len);
+	BUG_ON(ret != LZO_E_OK);
+	BUG_ON(out_len != PAGE_SIZE);
+	kunmap_atomic(to_va, KM_USER0);
+out:
+	spin_unlock(&zbpg->lock);
+	return ret;
+}
+
+/*
+ * The following routines handle shrinking of ephemeral pages by evicting
+ * pages "least valuable" first.
+ */
+
+static unsigned long zcache_evicted_raw_pages;
+static unsigned long zcache_evicted_buddied_pages;
+static unsigned long zcache_evicted_unbuddied_pages;
+
+static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id,
+						uint16_t poolid);
+static void zcache_put_pool(struct tmem_pool *pool);
+
+/*
+ * Flush and free all zbuds in a zbpg, then free the pageframe
+ */
+static void zbud_evict_zbpg(struct zbud_page *zbpg)
+{
+	struct zbud_hdr *zh;
+	int i, j;
+	uint32_t pool_id[ZBUD_MAX_BUDS], client_id[ZBUD_MAX_BUDS];
+	uint32_t index[ZBUD_MAX_BUDS];
+	struct tmem_oid oid[ZBUD_MAX_BUDS];
+	struct tmem_pool *pool;
+	unsigned long flags;
+
+	ASSERT_SPINLOCK(&zbpg->lock);
+	for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) {
+		zh = &zbpg->buddy[i];
+		if (zh->size) {
+			client_id[j] = zh->client_id;
+			pool_id[j] = zh->pool_id;
+			oid[j] = zh->oid;
+			index[j] = zh->index;
+			j++;
+		}
+	}
+	spin_unlock(&zbpg->lock);
+	for (i = 0; i < j; i++) {
+		pool = zcache_get_pool_by_id(client_id[i], pool_id[i]);
+		BUG_ON(pool == NULL);
+		local_irq_save(flags);
+		/* these flushes should dispose of any local storage */
+		tmem_flush_page(pool, &oid[i], index[i]);
+		local_irq_restore(flags);
+		zcache_put_pool(pool);
+	}
+}
+
+/*
+ * Free nr pages.  This code is funky because we want to hold the locks
+ * protecting various lists for as short a time as possible, and in some
+ * circumstances the list may change asynchronously when the list lock is
+ * not held.  In some cases we also trylock not only to avoid waiting on a
+ * page in use by another cpu, but also to avoid potential deadlock due to
+ * lock inversion.
+ */
+static void zbud_evict_pages(int nr)
+{
+	struct zbud_page *zbpg;
+	int i, newly_unused_pages = 0;
+
+
+	/* now try freeing unbuddied pages, starting with least space avail */
+	for (i = 0; i < MAX_CHUNK; i++) {
+retry_unbud_list_i:
+		spin_lock_bh(&zbud_budlists_spinlock);
+		if (list_empty(&zbud_unbuddied[i].list)) {
+			spin_unlock_bh(&zbud_budlists_spinlock);
+			continue;
+		}
+		list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) {
+			if (unlikely(!spin_trylock(&zbpg->lock)))
+				continue;
+			zbud_unbuddied[i].count--;
+			spin_unlock(&zbud_budlists_spinlock);
+			zcache_evicted_unbuddied_pages++;
+			/* want budlists unlocked when doing zbpg eviction */
+			zbud_evict_zbpg(zbpg);
+			newly_unused_pages++;
+			local_bh_enable();
+			if (--nr <= 0)
+				goto evict_unused;
+			goto retry_unbud_list_i;
+		}
+		spin_unlock_bh(&zbud_budlists_spinlock);
+	}
+
+	/* as a last resort, free buddied pages */
+retry_bud_list:
+	spin_lock_bh(&zbud_budlists_spinlock);
+	if (list_empty(&zbud_buddied_list)) {
+		spin_unlock_bh(&zbud_budlists_spinlock);
+		goto evict_unused;
+	}
+	list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) {
+		if (unlikely(!spin_trylock(&zbpg->lock)))
+			continue;
+		zcache_zbud_buddied_count--;
+		spin_unlock(&zbud_budlists_spinlock);
+		zcache_evicted_buddied_pages++;
+		/* want budlists unlocked when doing zbpg eviction */
+		zbud_evict_zbpg(zbpg);
+		newly_unused_pages++;
+		local_bh_enable();
+		if (--nr <= 0)
+			goto evict_unused;
+		goto retry_bud_list;
+	}
+	spin_unlock_bh(&zbud_budlists_spinlock);
+
+evict_unused:
+	return;
+}
+
+static DEFINE_PER_CPU(unsigned char *, zcache_remoteputmem);
+
+static int zbud_remotify_zbud(struct tmem_xhandle *xh, char *data,
+				size_t size)
+{
+	struct tmem_pool *pool;
+	int i, remotenode, ret = -1;
+	unsigned char cksum, *p;
+	unsigned long flags;
+
+	for (p = data, cksum = 0, i = 0; i < size; i++)
+		cksum += *p;
+	ret = ramster_remote_put(xh, data, size, true, &remotenode);
+	if (ret == 0) {
+		/* data was successfully remoted so change the local version
+		 * to point to the remote node where it landed */
+		pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh->pool_id);
+		BUG_ON(pool == NULL);
+		local_irq_save(flags);
+		/* tmem_replace will also free up any local space */
+		(void)tmem_replace(pool, &xh->oid, xh->index,
+			pampd_make_remote(remotenode, size, cksum));
+		local_irq_restore(flags);
+		zcache_put_pool(pool);
+		ramster_eph_pages_remoted++;
+		ret = 0;
+	} else
+		ramster_eph_pages_remote_failed++;
+	return ret;
+}
+
+static int zbud_remotify_zbpg(struct zbud_page *zbpg)
+{
+	struct zbud_hdr *zh1, *zh2 = NULL;
+	struct tmem_xhandle xh1, xh2 = { 0 };
+	char *data1 = NULL, *data2 = NULL;
+	size_t size1 = 0, size2 = 0;
+	int ret = 0;
+	unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem);
+
+	ASSERT_SPINLOCK(&zbpg->lock);
+	if (zbpg->buddy[0].size == 0)
+		zh1 = &zbpg->buddy[1];
+	else if (zbpg->buddy[1].size == 0)
+		zh1 = &zbpg->buddy[0];
+	else {
+		zh1 = &zbpg->buddy[0];
+		zh2 = &zbpg->buddy[1];
+	}
+	/* don't remotify pages that are already remotified */
+	if (zh1->client_id != LOCAL_CLIENT)
+		zh1 = NULL;
+	if ((zh2 != NULL) && (zh2->client_id != LOCAL_CLIENT))
+		zh2 = NULL;
+
+	/* copy the data and metadata so can release lock */
+	if (zh1 != NULL) {
+		xh1.client_id = zh1->client_id;
+		xh1.pool_id = zh1->pool_id;
+		xh1.oid = zh1->oid;
+		xh1.index = zh1->index;
+		size1 = zh1->size;
+		data1 = zbud_data(zh1, size1);
+		memcpy(tmpmem, zbud_data(zh1, size1), size1);
+		data1 = tmpmem;
+		tmpmem += size1;
+	}
+	if (zh2 != NULL) {
+		xh2.client_id = zh2->client_id;
+		xh2.pool_id = zh2->pool_id;
+		xh2.oid = zh2->oid;
+		xh2.index = zh2->index;
+		size2 = zh2->size;
+		memcpy(tmpmem, zbud_data(zh2, size2), size2);
+		data2 = tmpmem;
+	}
+	spin_unlock(&zbpg->lock);
+	preempt_enable();
+
+	/* OK, no locks held anymore, remotify one or both zbuds */
+	if (zh1 != NULL)
+		ret = zbud_remotify_zbud(&xh1, data1, size1);
+	if (zh2 != NULL)
+		ret |= zbud_remotify_zbud(&xh2, data2, size2);
+	return ret;
+}
+
+void zbud_remotify_pages(int nr)
+{
+	struct zbud_page *zbpg;
+	int i, ret;
+
+	/*
+	 * for now just try remotifying unbuddied pages, starting with
+	 * least space avail
+	 */
+	for (i = 0; i < MAX_CHUNK; i++) {
+retry_unbud_list_i:
+		preempt_disable();  /* enable in zbud_remotify_zbpg */
+		spin_lock_bh(&zbud_budlists_spinlock);
+		if (list_empty(&zbud_unbuddied[i].list)) {
+			spin_unlock_bh(&zbud_budlists_spinlock);
+			preempt_enable();
+			continue; /* next i in for loop */
+		}
+		list_for_each_entry(zbpg, &zbud_unbuddied[i].list, bud_list) {
+			if (unlikely(!spin_trylock(&zbpg->lock)))
+				continue; /* next list_for_each_entry */
+			zbud_unbuddied[i].count--;
+			/* want budlists unlocked when doing zbpg remotify */
+			spin_unlock_bh(&zbud_budlists_spinlock);
+			ret = zbud_remotify_zbpg(zbpg);
+			/* preemption is re-enabled in zbud_remotify_zbpg */
+			if (ret == 0) {
+				if (--nr <= 0)
+					goto out;
+				goto retry_unbud_list_i;
+			}
+			/* if fail to remotify any page, quit */
+			pr_err("TESTING zbud_remotify_pages failed on page,"
+				" trying to re-add\n");
+			spin_lock_bh(&zbud_budlists_spinlock);
+			spin_lock(&zbpg->lock);
+			list_add_tail(&zbpg->bud_list, &zbud_unbuddied[i].list);
+			zbud_unbuddied[i].count++;
+			spin_unlock(&zbpg->lock);
+			spin_unlock_bh(&zbud_budlists_spinlock);
+			pr_err("TESTING zbud_remotify_pages failed on page,"
+				" finished re-add\n");
+			goto out;
+		}
+		spin_unlock_bh(&zbud_budlists_spinlock);
+		preempt_enable();
+	}
+
+next_buddied_zbpg:
+	preempt_disable();  /* enable in zbud_remotify_zbpg */
+	spin_lock_bh(&zbud_budlists_spinlock);
+	if (list_empty(&zbud_buddied_list))
+		goto unlock_out;
+	list_for_each_entry(zbpg, &zbud_buddied_list, bud_list) {
+		if (unlikely(!spin_trylock(&zbpg->lock)))
+			continue; /* next list_for_each_entry */
+		zcache_zbud_buddied_count--;
+		/* want budlists unlocked when doing zbpg remotify */
+		spin_unlock_bh(&zbud_budlists_spinlock);
+		ret = zbud_remotify_zbpg(zbpg);
+		/* preemption is re-enabled in zbud_remotify_zbpg */
+		if (ret == 0) {
+			if (--nr <= 0)
+				goto out;
+			goto next_buddied_zbpg;
+		}
+		/* if fail to remotify any page, quit */
+		pr_err("TESTING zbud_remotify_pages failed on BUDDIED page,"
+			" trying to re-add\n");
+		spin_lock_bh(&zbud_budlists_spinlock);
+		spin_lock(&zbpg->lock);
+		list_add_tail(&zbpg->bud_list, &zbud_buddied_list);
+		zcache_zbud_buddied_count++;
+		spin_unlock(&zbpg->lock);
+		spin_unlock_bh(&zbud_budlists_spinlock);
+		pr_err("TESTING zbud_remotify_pages failed on BUDDIED page,"
+			" finished re-add\n");
+		goto out;
+	}
+unlock_out:
+	spin_unlock_bh(&zbud_budlists_spinlock);
+	preempt_enable();
+out:
+	return;
+}
+
+/* the "flush list" asynchronously collects pages to remotely flush */
+#define FLUSH_ENTIRE_OBJECT ((uint32_t)-1)
+static void ramster_flnode_free(struct flushlist_node *,
+				struct tmem_pool *);
+
+static void zcache_remote_flush_page(struct flushlist_node *flnode)
+{
+	struct tmem_xhandle *xh;
+	int remotenode, ret;
+
+	preempt_disable();
+	xh = &flnode->xh;
+	remotenode = flnode->xh.client_id;
+	ret = ramster_remote_flush(xh, remotenode);
+	if (ret >= 0)
+		ramster_remote_pages_flushed++;
+	else
+		ramster_remote_page_flushes_failed++;
+	preempt_enable_no_resched();
+	ramster_flnode_free(flnode, NULL);
+}
+
+static void zcache_remote_flush_object(struct flushlist_node *flnode)
+{
+	struct tmem_xhandle *xh;
+	int remotenode, ret;
+
+	preempt_disable();
+	xh = &flnode->xh;
+	remotenode = flnode->xh.client_id;
+	ret = ramster_remote_flush_object(xh, remotenode);
+	if (ret >= 0)
+		ramster_remote_objects_flushed++;
+	else
+		ramster_remote_object_flushes_failed++;
+	preempt_enable_no_resched();
+	ramster_flnode_free(flnode, NULL);
+}
+
+static void zcache_remote_eph_put(struct zbud_hdr *zbud)
+{
+	/* FIXME */
+}
+
+static void zcache_remote_pers_put(struct zv_hdr *zv)
+{
+	struct tmem_xhandle xh;
+	uint16_t size;
+	bool ephemeral;
+	int remotenode, ret = -1;
+	char *data;
+	struct tmem_pool *pool;
+	unsigned long flags;
+	unsigned char cksum;
+	char *p;
+	int i;
+	unsigned char *tmpmem = __get_cpu_var(zcache_remoteputmem);
+
+	ASSERT_SENTINEL(zv, ZVH);
+	BUG_ON(zv->client_id != LOCAL_CLIENT);
+	local_bh_disable();
+	xh.client_id = zv->client_id;
+	xh.pool_id = zv->pool_id;
+	xh.oid = zv->oid;
+	xh.index = zv->index;
+	size = xv_get_object_size(zv) - sizeof(*zv);
+	BUG_ON(size == 0 || size > zv_max_page_size);
+	data = (char *)zv + sizeof(*zv);
+	for (p = data, cksum = 0, i = 0; i < size; i++)
+		cksum += *p;
+	memcpy(tmpmem, data, size);
+	data = tmpmem;
+	pool = zcache_get_pool_by_id(zv->client_id, zv->pool_id);
+	ephemeral = is_ephemeral(pool);
+	zcache_put_pool(pool);
+	/* now OK to release lock set in caller */
+	spin_unlock(&zcache_rem_op_list_lock);
+	local_bh_enable();
+	preempt_disable();
+	ret = ramster_remote_put(&xh, data, size, ephemeral, &remotenode);
+	preempt_enable_no_resched();
+	if (ret != 0) {
+		/*
+		 * This is some form of a memory leak... if the remote put
+		 * fails, there will never be another attempt to remotify
+		 * this page.  But since we've dropped the zv pointer,
+		 * the page may have been freed or the data replaced
+		 * so we can't just "put it back" in the remote op list.
+		 * Even if we could, not sure where to put it in the list
+		 * because there may be flushes that must be strictly
+		 * ordered vs the put.  So leave this as a FIXME for now.
+		 * But count them so we know if it becomes a problem.
+		 */
+		ramster_pers_pages_remote_failed++;
+		goto out;
+	} else
+		atomic_inc(&ramster_remote_pers_pages);
+	ramster_pers_pages_remoted++;
+	/*
+	 * data was successfully remoted so change the local version to
+	 * point to the remote node where it landed
+	 */
+	local_bh_disable();
+	pool = zcache_get_pool_by_id(LOCAL_CLIENT, xh.pool_id);
+	local_irq_save(flags);
+	(void)tmem_replace(pool, &xh.oid, xh.index,
+			pampd_make_remote(remotenode, size, cksum));
+	local_irq_restore(flags);
+	zcache_put_pool(pool);
+	local_bh_enable();
+out:
+	return;
+}
+
+static void zcache_do_remotify_ops(int nr)
+{
+	struct ramster_remotify_hdr *rem_op;
+	union remotify_list_node *u;
+
+	while (1) {
+		if (!nr)
+			goto out;
+		spin_lock(&zcache_rem_op_list_lock);
+		if (list_empty(&zcache_rem_op_list)) {
+			spin_unlock(&zcache_rem_op_list_lock);
+			goto out;
+		}
+		rem_op = list_first_entry(&zcache_rem_op_list,
+				struct ramster_remotify_hdr, list);
+		list_del_init(&rem_op->list);
+		if (rem_op->op != RAMSTER_REMOTIFY_PERS_PUT)
+			spin_unlock(&zcache_rem_op_list_lock);
+		u = (union remotify_list_node *)rem_op;
+		switch (rem_op->op) {
+		case RAMSTER_REMOTIFY_EPH_PUT:
+BUG();
+			zcache_remote_eph_put((struct zbud_hdr *)rem_op);
+			break;
+		case RAMSTER_REMOTIFY_PERS_PUT:
+			zcache_remote_pers_put((struct zv_hdr *)rem_op);
+			break;
+		case RAMSTER_REMOTIFY_FLUSH_PAGE:
+			zcache_remote_flush_page((struct flushlist_node *)u);
+			break;
+		case RAMSTER_REMOTIFY_FLUSH_OBJ:
+			zcache_remote_flush_object((struct flushlist_node *)u);
+			break;
+		default:
+			BUG();
+		}
+	}
+out:
+	return;
+}
+
+/*
+ * Communicate interface revision with userspace
+ */
+#include "cluster/ramster_nodemanager.h"
+static unsigned long ramster_interface_revision  = R2NM_API_VERSION;
+
+/*
+ * For now, just push over a few pages every few seconds to
+ * ensure that it basically works
+ */
+static struct workqueue_struct *ramster_remotify_workqueue;
+static void ramster_remotify_process(struct work_struct *work);
+static DECLARE_DELAYED_WORK(ramster_remotify_worker,
+		ramster_remotify_process);
+
+static void ramster_remotify_queue_delayed_work(unsigned long delay)
+{
+	if (!queue_delayed_work(ramster_remotify_workqueue,
+				&ramster_remotify_worker, delay))
+		pr_err("ramster_remotify: bad workqueue\n");
+}
+
+
+static int use_frontswap;
+static int use_cleancache;
+static int ramster_remote_target_nodenum = -1;
+static void ramster_remotify_process(struct work_struct *work)
+{
+	static bool remotify_in_progress;
+
+	BUG_ON(irqs_disabled());
+	if (remotify_in_progress)
+		ramster_remotify_queue_delayed_work(HZ);
+	else if (ramster_remote_target_nodenum != -1) {
+		remotify_in_progress = true;
+#ifdef CONFIG_CLEANCACHE
+	if (use_cleancache && ramster_eph_remotify_enable)
+		zbud_remotify_pages(5000); /* FIXME is this a good number? */
+#endif
+#ifdef CONFIG_FRONTSWAP
+	if (use_frontswap && ramster_pers_remotify_enable)
+		zcache_do_remotify_ops(500); /* FIXME is this a good number? */
+#endif
+		remotify_in_progress = false;
+		ramster_remotify_queue_delayed_work(HZ);
+	}
+}
+
+static void ramster_remotify_init(void)
+{
+	unsigned long n = 60UL;
+	ramster_remotify_workqueue =
+		create_singlethread_workqueue("ramster_remotify");
+	ramster_remotify_queue_delayed_work(n * HZ);
+}
+
+
+static void zbud_init(void)
+{
+	int i;
+
+	INIT_LIST_HEAD(&zbud_buddied_list);
+	zcache_zbud_buddied_count = 0;
+	for (i = 0; i < NCHUNKS; i++) {
+		INIT_LIST_HEAD(&zbud_unbuddied[i].list);
+		zbud_unbuddied[i].count = 0;
+	}
+}
+
+#ifdef CONFIG_SYSFS
+/*
+ * These sysfs routines show a nice distribution of how many zbpg's are
+ * currently (and have ever been placed) in each unbuddied list.  It's fun
+ * to watch but can probably go away before final merge.
+ */
+static int zbud_show_unbuddied_list_counts(char *buf)
+{
+	int i;
+	char *p = buf;
+
+	for (i = 0; i < NCHUNKS; i++)
+		p += sprintf(p, "%u ", zbud_unbuddied[i].count);
+	return p - buf;
+}
+
+static int zbud_show_cumul_chunk_counts(char *buf)
+{
+	unsigned long i, chunks = 0, total_chunks = 0, sum_total_chunks = 0;
+	unsigned long total_chunks_lte_21 = 0, total_chunks_lte_32 = 0;
+	unsigned long total_chunks_lte_42 = 0;
+	char *p = buf;
+
+	for (i = 0; i < NCHUNKS; i++) {
+		p += sprintf(p, "%lu ", zbud_cumul_chunk_counts[i]);
+		chunks += zbud_cumul_chunk_counts[i];
+		total_chunks += zbud_cumul_chunk_counts[i];
+		sum_total_chunks += i * zbud_cumul_chunk_counts[i];
+		if (i == 21)
+			total_chunks_lte_21 = total_chunks;
+		if (i == 32)
+			total_chunks_lte_32 = total_chunks;
+		if (i == 42)
+			total_chunks_lte_42 = total_chunks;
+	}
+	p += sprintf(p, "<=21:%lu <=32:%lu <=42:%lu, mean:%lu\n",
+		total_chunks_lte_21, total_chunks_lte_32, total_chunks_lte_42,
+		chunks == 0 ? 0 : sum_total_chunks / chunks);
+	return p - buf;
+}
+#endif
+
+/**********
+ * This "zv" PAM implementation combines the TLSF-based xvMalloc
+ * with lzo1x compression to maximize the amount of data that can
+ * be packed into a physical page.
+ *
+ * Zv represents a PAM page with the index and object (plus a "size" value
+ * necessary for decompression) immediately preceding the compressed data.
+ */
+
+/* rudimentary policy limits */
+/* total number of persistent pages may not exceed this percentage */
+static unsigned int zv_page_count_policy_percent = 75;
+/*
+ * byte count defining poor compression; pages with greater zsize will be
+ * rejected
+ */
+static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7;
+/*
+ * byte count defining poor *mean* compression; pages with greater zsize
+ * will be rejected until sufficient better-compressed pages are accepted
+ * driving the mean below this threshold
+ */
+static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5;
+
+static atomic_t zv_curr_dist_counts[NCHUNKS];
+static atomic_t zv_cumul_dist_counts[NCHUNKS];
+
+
+static struct zv_hdr *zv_create(struct zcache_client *cli, uint32_t pool_id,
+				struct tmem_oid *oid, uint32_t index,
+				void *cdata, unsigned clen)
+{
+	struct page *page;
+	struct zv_hdr *zv = NULL;
+	uint32_t offset;
+	int alloc_size = clen + sizeof(struct zv_hdr);
+	int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT;
+	int ret;
+
+	BUG_ON(!irqs_disabled());
+	BUG_ON(chunks >= NCHUNKS);
+	ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr),
+			&page, &offset, ZCACHE_GFP_MASK);
+	if (unlikely(ret))
+		goto out;
+	atomic_inc(&zv_curr_dist_counts[chunks]);
+	atomic_inc(&zv_cumul_dist_counts[chunks]);
+	zv = kmap_atomic(page, KM_USER0) + offset;
+	zv->index = index;
+	zv->oid = *oid;
+	zv->pool_id = pool_id;
+	SET_SENTINEL(zv, ZVH);
+	INIT_LIST_HEAD(&zv->rem_op.list);
+	zv->client_id = get_client_id_from_client(cli);
+	zv->rem_op.op = RAMSTER_REMOTIFY_PERS_PUT;
+	if (zv->client_id == LOCAL_CLIENT) {
+		spin_lock(&zcache_rem_op_list_lock);
+		list_add_tail(&zv->rem_op.list, &zcache_rem_op_list);
+		spin_unlock(&zcache_rem_op_list_lock);
+	}
+	memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen);
+	kunmap_atomic(zv, KM_USER0);
+out:
+	return zv;
+}
+
+/* similar to zv_create, but just reserve space, no data yet */
+static struct zv_hdr *zv_alloc(struct tmem_pool *pool,
+				struct tmem_oid *oid, uint32_t index,
+				unsigned clen)
+{
+	struct zcache_client *cli = pool->client;
+	struct page *page;
+	struct zv_hdr *zv = NULL;
+	uint32_t offset;
+	int ret;
+
+	BUG_ON(!irqs_disabled());
+	BUG_ON(!is_local_client(pool->client));
+	ret = xv_malloc(cli->xvpool, clen + sizeof(struct zv_hdr),
+			&page, &offset, ZCACHE_GFP_MASK);
+	if (unlikely(ret))
+		goto out;
+	zv = kmap_atomic(page, KM_USER0) + offset;
+	SET_SENTINEL(zv, ZVH);
+	INIT_LIST_HEAD(&zv->rem_op.list);
+	zv->client_id = LOCAL_CLIENT;
+	zv->rem_op.op = RAMSTER_INTRANSIT_PERS;
+	zv->index = index;
+	zv->oid = *oid;
+	zv->pool_id = pool->pool_id;
+	kunmap_atomic(zv, KM_USER0);
+out:
+	return zv;
+}
+
+static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv)
+{
+	unsigned long flags;
+	struct page *page;
+	uint32_t offset;
+	uint16_t size = xv_get_object_size(zv);
+	int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT;
+
+	ASSERT_SENTINEL(zv, ZVH);
+	BUG_ON(chunks >= NCHUNKS);
+	atomic_dec(&zv_curr_dist_counts[chunks]);
+	size -= sizeof(*zv);
+	spin_lock(&zcache_rem_op_list_lock);
+	size = xv_get_object_size(zv) - sizeof(*zv);
+	BUG_ON(size == 0);
+	INVERT_SENTINEL(zv, ZVH);
+	if (!list_empty(&zv->rem_op.list))
+		list_del_init(&zv->rem_op.list);
+	spin_unlock(&zcache_rem_op_list_lock);
+	page = virt_to_page(zv);
+	offset = (unsigned long)zv & ~PAGE_MASK;
+	local_irq_save(flags);
+	xv_free(xvpool, page, offset);
+	local_irq_restore(flags);
+}
+
+static void zv_decompress(struct page *page, struct zv_hdr *zv)
+{
+	size_t clen = PAGE_SIZE;
+	char *to_va;
+	unsigned size;
+	int ret;
+
+	ASSERT_SENTINEL(zv, ZVH);
+	size = xv_get_object_size(zv) - sizeof(*zv);
+	BUG_ON(size == 0);
+	to_va = kmap_atomic(page, KM_USER0);
+	ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv),
+					size, to_va, &clen);
+	kunmap_atomic(to_va, KM_USER0);
+	BUG_ON(ret != LZO_E_OK);
+	BUG_ON(clen != PAGE_SIZE);
+}
+
+static void zv_copy_from_pampd(char *data, size_t *bufsize, struct zv_hdr *zv)
+{
+	unsigned size;
+
+	ASSERT_SENTINEL(zv, ZVH);
+	size = xv_get_object_size(zv) - sizeof(*zv);
+	BUG_ON(size == 0 || size > zv_max_page_size);
+	BUG_ON(size > *bufsize);
+	memcpy(data, (char *)zv + sizeof(*zv), size);
+	*bufsize = size;
+}
+
+static void zv_copy_to_pampd(struct zv_hdr *zv, char *data, size_t size)
+{
+	unsigned zv_size;
+
+	ASSERT_SENTINEL(zv, ZVH);
+	zv_size = xv_get_object_size(zv) - sizeof(*zv);
+	BUG_ON(zv_size != size);
+	BUG_ON(zv_size == 0 || zv_size > zv_max_page_size);
+	memcpy((char *)zv + sizeof(*zv), data, size);
+}
+
+#ifdef CONFIG_SYSFS
+/*
+ * show a distribution of compression stats for zv pages.
+ */
+
+static int zv_curr_dist_counts_show(char *buf)
+{
+	unsigned long i, n, chunks = 0, sum_total_chunks = 0;
+	char *p = buf;
+
+	for (i = 0; i < NCHUNKS; i++) {
+		n = atomic_read(&zv_curr_dist_counts[i]);
+		p += sprintf(p, "%lu ", n);
+		chunks += n;
+		sum_total_chunks += i * n;
+	}
+	p += sprintf(p, "mean:%lu\n",
+		chunks == 0 ? 0 : sum_total_chunks / chunks);
+	return p - buf;
+}
+
+static int zv_cumul_dist_counts_show(char *buf)
+{
+	unsigned long i, n, chunks = 0, sum_total_chunks = 0;
+	char *p = buf;
+
+	for (i = 0; i < NCHUNKS; i++) {
+		n = atomic_read(&zv_cumul_dist_counts[i]);
+		p += sprintf(p, "%lu ", n);
+		chunks += n;
+		sum_total_chunks += i * n;
+	}
+	p += sprintf(p, "mean:%lu\n",
+		chunks == 0 ? 0 : sum_total_chunks / chunks);
+	return p - buf;
+}
+
+/*
+ * setting zv_max_zsize via sysfs causes all persistent (e.g. swap)
+ * pages that don't compress to less than this value (including metadata
+ * overhead) to be rejected.  We don't allow the value to get too close
+ * to PAGE_SIZE.
+ */
+static ssize_t zv_max_zsize_show(struct kobject *kobj,
+				    struct kobj_attribute *attr,
+				    char *buf)
+{
+	return sprintf(buf, "%u\n", zv_max_zsize);
+}
+
+static ssize_t zv_max_zsize_store(struct kobject *kobj,
+				    struct kobj_attribute *attr,
+				    const char *buf, size_t count)
+{
+	unsigned long val;
+	int err;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7))
+		return -EINVAL;
+	zv_max_zsize = val;
+	return count;
+}
+
+/*
+ * setting zv_max_mean_zsize via sysfs causes all persistent (e.g. swap)
+ * pages that don't compress to less than this value (including metadata
+ * overhead) to be rejected UNLESS the mean compression is also smaller
+ * than this value.  In other words, we are load-balancing-by-zsize the
+ * accepted pages.  Again, we don't allow the value to get too close
+ * to PAGE_SIZE.
+ */
+static ssize_t zv_max_mean_zsize_show(struct kobject *kobj,
+				    struct kobj_attribute *attr,
+				    char *buf)
+{
+	return sprintf(buf, "%u\n", zv_max_mean_zsize);
+}
+
+static ssize_t zv_max_mean_zsize_store(struct kobject *kobj,
+				    struct kobj_attribute *attr,
+				    const char *buf, size_t count)
+{
+	unsigned long val;
+	int err;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7))
+		return -EINVAL;
+	zv_max_mean_zsize = val;
+	return count;
+}
+
+/*
+ * setting zv_page_count_policy_percent via sysfs sets an upper bound of
+ * persistent (e.g. swap) pages that will be retained according to:
+ *     (zv_page_count_policy_percent * totalram_pages) / 100)
+ * when that limit is reached, further puts will be rejected (until
+ * some pages have been flushed).  Note that, due to compression,
+ * this number may exceed 100; it defaults to 75 and we set an
+ * arbitary limit of 150.  A poor choice will almost certainly result
+ * in OOM's, so this value should only be changed prudently.
+ */
+static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj,
+						 struct kobj_attribute *attr,
+						 char *buf)
+{
+	return sprintf(buf, "%u\n", zv_page_count_policy_percent);
+}
+
+static ssize_t zv_page_count_policy_percent_store(struct kobject *kobj,
+						  struct kobj_attribute *attr,
+						  const char *buf, size_t count)
+{
+	unsigned long val;
+	int err;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err || (val == 0) || (val > 150))
+		return -EINVAL;
+	zv_page_count_policy_percent = val;
+	return count;
+}
+
+static struct kobj_attribute zcache_zv_max_zsize_attr = {
+		.attr = { .name = "zv_max_zsize", .mode = 0644 },
+		.show = zv_max_zsize_show,
+		.store = zv_max_zsize_store,
+};
+
+static struct kobj_attribute zcache_zv_max_mean_zsize_attr = {
+		.attr = { .name = "zv_max_mean_zsize", .mode = 0644 },
+		.show = zv_max_mean_zsize_show,
+		.store = zv_max_mean_zsize_store,
+};
+
+static struct kobj_attribute zcache_zv_page_count_policy_percent_attr = {
+		.attr = { .name = "zv_page_count_policy_percent",
+			  .mode = 0644 },
+		.show = zv_page_count_policy_percent_show,
+		.store = zv_page_count_policy_percent_store,
+};
+#endif
+
+/*
+ * zcache core code starts here
+ */
+
+/* useful stats not collected by cleancache or frontswap */
+static unsigned long zcache_flush_total;
+static unsigned long zcache_flush_found;
+static unsigned long zcache_flobj_total;
+static unsigned long zcache_flobj_found;
+static unsigned long zcache_failed_eph_puts;
+static unsigned long zcache_nonactive_puts;
+static unsigned long zcache_failed_pers_puts;
+
+/*
+ * Tmem operations assume the poolid implies the invoking client.
+ * Zcache only has one client (the kernel itself): LOCAL_CLIENT.
+ * RAMster has each client numbered by cluster node, and a KVM version
+ * of zcache would have one client per guest and each client might
+ * have a poolid==N.
+ */
+static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid)
+{
+	struct tmem_pool *pool = NULL;
+	struct zcache_client *cli = NULL;
+
+	if (cli_id == LOCAL_CLIENT)
+		cli = &zcache_host;
+	else {
+		if (cli_id >= MAX_CLIENTS)
+			goto out;
+		cli = &zcache_clients[cli_id];
+		if (cli == NULL)
+			goto out;
+		atomic_inc(&cli->refcount);
+	}
+	if (poolid < MAX_POOLS_PER_CLIENT) {
+		pool = cli->tmem_pools[poolid];
+		if (pool != NULL)
+			atomic_inc(&pool->refcount);
+	}
+out:
+	return pool;
+}
+
+static void zcache_put_pool(struct tmem_pool *pool)
+{
+	struct zcache_client *cli = NULL;
+
+	if (pool == NULL)
+		BUG();
+	cli = pool->client;
+	atomic_dec(&pool->refcount);
+	atomic_dec(&cli->refcount);
+}
+
+int zcache_new_client(uint16_t cli_id)
+{
+	struct zcache_client *cli = NULL;
+	int ret = -1;
+
+	if (cli_id == LOCAL_CLIENT)
+		cli = &zcache_host;
+	else if ((unsigned int)cli_id < MAX_CLIENTS)
+		cli = &zcache_clients[cli_id];
+	if (cli == NULL)
+		goto out;
+	if (cli->allocated)
+		goto out;
+	cli->allocated = 1;
+#ifdef CONFIG_FRONTSWAP
+	cli->xvpool = xv_create_pool();
+	if (cli->xvpool == NULL)
+		goto out;
+#endif
+	ret = 0;
+out:
+	return ret;
+}
+
+/* counters for debugging */
+static unsigned long zcache_failed_get_free_pages;
+static unsigned long zcache_failed_alloc;
+static unsigned long zcache_put_to_flush;
+
+/*
+ * for now, used named slabs so can easily track usage; later can
+ * either just use kmalloc, or perhaps add a slab-like allocator
+ * to more carefully manage total memory utilization
+ */
+static struct kmem_cache *zcache_objnode_cache;
+static struct kmem_cache *zcache_obj_cache;
+static struct kmem_cache *ramster_flnode_cache;
+static atomic_t zcache_curr_obj_count = ATOMIC_INIT(0);
+static unsigned long zcache_curr_obj_count_max;
+static atomic_t zcache_curr_objnode_count = ATOMIC_INIT(0);
+static unsigned long zcache_curr_objnode_count_max;
+
+/*
+ * to avoid memory allocation recursion (e.g. due to direct reclaim), we
+ * preload all necessary data structures so the hostops callbacks never
+ * actually do a malloc
+ */
+struct zcache_preload {
+	void *page;
+	struct tmem_obj *obj;
+	int nr;
+	struct tmem_objnode *objnodes[OBJNODE_TREE_MAX_PATH];
+	struct flushlist_node *flnode;
+};
+static DEFINE_PER_CPU(struct zcache_preload, zcache_preloads) = { 0, };
+
+static int zcache_do_preload(struct tmem_pool *pool)
+{
+	struct zcache_preload *kp;
+	struct tmem_objnode *objnode;
+	struct tmem_obj *obj;
+	struct flushlist_node *flnode;
+	void *page;
+	int ret = -ENOMEM;
+
+	if (unlikely(zcache_objnode_cache == NULL))
+		goto out;
+	if (unlikely(zcache_obj_cache == NULL))
+		goto out;
+	preempt_disable();
+	kp = &__get_cpu_var(zcache_preloads);
+	while (kp->nr < ARRAY_SIZE(kp->objnodes)) {
+		preempt_enable_no_resched();
+		objnode = kmem_cache_alloc(zcache_objnode_cache,
+				ZCACHE_GFP_MASK);
+		if (unlikely(objnode == NULL)) {
+			zcache_failed_alloc++;
+			goto out;
+		}
+		preempt_disable();
+		kp = &__get_cpu_var(zcache_preloads);
+		if (kp->nr < ARRAY_SIZE(kp->objnodes))
+			kp->objnodes[kp->nr++] = objnode;
+		else
+			kmem_cache_free(zcache_objnode_cache, objnode);
+	}
+	preempt_enable_no_resched();
+	obj = kmem_cache_alloc(zcache_obj_cache, ZCACHE_GFP_MASK);
+	if (unlikely(obj == NULL)) {
+		zcache_failed_alloc++;
+		goto out;
+	}
+	flnode = kmem_cache_alloc(ramster_flnode_cache, ZCACHE_GFP_MASK);
+	if (unlikely(flnode == NULL)) {
+		zcache_failed_alloc++;
+		goto out;
+	}
+	if (is_ephemeral(pool)) {
+		page = (void *)__get_free_page(ZCACHE_GFP_MASK);
+		if (unlikely(page == NULL)) {
+			zcache_failed_get_free_pages++;
+			kmem_cache_free(zcache_obj_cache, obj);
+			kmem_cache_free(ramster_flnode_cache, flnode);
+			goto out;
+		}
+	}
+	preempt_disable();
+	kp = &__get_cpu_var(zcache_preloads);
+	if (kp->obj == NULL)
+		kp->obj = obj;
+	else
+		kmem_cache_free(zcache_obj_cache, obj);
+	if (kp->flnode == NULL)
+		kp->flnode = flnode;
+	else
+		kmem_cache_free(ramster_flnode_cache, flnode);
+	if (is_ephemeral(pool)) {
+		if (kp->page == NULL)
+			kp->page = page;
+		else
+			free_page((unsigned long)page);
+	}
+	ret = 0;
+out:
+	return ret;
+}
+
+static int ramster_do_preload_flnode_only(struct tmem_pool *pool)
+{
+	struct zcache_preload *kp;
+	struct flushlist_node *flnode;
+	int ret = -ENOMEM;
+
+	BUG_ON(!irqs_disabled());
+	if (unlikely(ramster_flnode_cache == NULL))
+		BUG();
+	kp = &__get_cpu_var(zcache_preloads);
+	flnode = kmem_cache_alloc(ramster_flnode_cache, GFP_ATOMIC);
+	if (unlikely(flnode == NULL) && kp->flnode == NULL)
+		BUG();  /* FIXME handle more gracefully, but how??? */
+	else if (kp->flnode == NULL)
+		kp->flnode = flnode;
+	else
+		kmem_cache_free(ramster_flnode_cache, flnode);
+	return ret;
+}
+
+static void *zcache_get_free_page(void)
+{
+	struct zcache_preload *kp;
+	void *page;
+
+	kp = &__get_cpu_var(zcache_preloads);
+	page = kp->page;
+	BUG_ON(page == NULL);
+	kp->page = NULL;
+	return page;
+}
+
+static void zcache_free_page(void *p)
+{
+	free_page((unsigned long)p);
+}
+
+/*
+ * zcache implementation for tmem host ops
+ */
+
+static struct tmem_objnode *zcache_objnode_alloc(struct tmem_pool *pool)
+{
+	struct tmem_objnode *objnode = NULL;
+	unsigned long count;
+	struct zcache_preload *kp;
+
+	kp = &__get_cpu_var(zcache_preloads);
+	if (kp->nr <= 0)
+		goto out;
+	objnode = kp->objnodes[kp->nr - 1];
+	BUG_ON(objnode == NULL);
+	kp->objnodes[kp->nr - 1] = NULL;
+	kp->nr--;
+	count = atomic_inc_return(&zcache_curr_objnode_count);
+	if (count > zcache_curr_objnode_count_max)
+		zcache_curr_objnode_count_max = count;
+out:
+	return objnode;
+}
+
+static void zcache_objnode_free(struct tmem_objnode *objnode,
+					struct tmem_pool *pool)
+{
+	atomic_dec(&zcache_curr_objnode_count);
+	BUG_ON(atomic_read(&zcache_curr_objnode_count) < 0);
+	kmem_cache_free(zcache_objnode_cache, objnode);
+}
+
+static struct tmem_obj *zcache_obj_alloc(struct tmem_pool *pool)
+{
+	struct tmem_obj *obj = NULL;
+	unsigned long count;
+	struct zcache_preload *kp;
+
+	kp = &__get_cpu_var(zcache_preloads);
+	obj = kp->obj;
+	BUG_ON(obj == NULL);
+	kp->obj = NULL;
+	count = atomic_inc_return(&zcache_curr_obj_count);
+	if (count > zcache_curr_obj_count_max)
+		zcache_curr_obj_count_max = count;
+	return obj;
+}
+
+static void zcache_obj_free(struct tmem_obj *obj, struct tmem_pool *pool)
+{
+	atomic_dec(&zcache_curr_obj_count);
+	BUG_ON(atomic_read(&zcache_curr_obj_count) < 0);
+	kmem_cache_free(zcache_obj_cache, obj);
+}
+
+static struct flushlist_node *ramster_flnode_alloc(struct tmem_pool *pool)
+{
+	struct flushlist_node *flnode = NULL;
+	struct zcache_preload *kp;
+	int count;
+
+	kp = &__get_cpu_var(zcache_preloads);
+	flnode = kp->flnode;
+	BUG_ON(flnode == NULL);
+	kp->flnode = NULL;
+	count = atomic_inc_return(&ramster_curr_flnode_count);
+	if (count > ramster_curr_flnode_count_max)
+		ramster_curr_flnode_count_max = count;
+	return flnode;
+}
+
+static void ramster_flnode_free(struct flushlist_node *flnode,
+				struct tmem_pool *pool)
+{
+	atomic_dec(&ramster_curr_flnode_count);
+	BUG_ON(atomic_read(&ramster_curr_flnode_count) < 0);
+	kmem_cache_free(ramster_flnode_cache, flnode);
+}
+
+static struct tmem_hostops zcache_hostops = {
+	.obj_alloc = zcache_obj_alloc,
+	.obj_free = zcache_obj_free,
+	.objnode_alloc = zcache_objnode_alloc,
+	.objnode_free = zcache_objnode_free,
+};
+
+/*
+ * zcache implementations for PAM page descriptor ops
+ */
+
+
+static inline void dec_and_check(atomic_t *pvar)
+{
+	atomic_dec(pvar);
+	/* later when all accounting is fixed, make this a BUG */
+	WARN_ON_ONCE(atomic_read(pvar) < 0);
+}
+
+static atomic_t zcache_curr_eph_pampd_count = ATOMIC_INIT(0);
+static unsigned long zcache_curr_eph_pampd_count_max;
+static atomic_t zcache_curr_pers_pampd_count = ATOMIC_INIT(0);
+static unsigned long zcache_curr_pers_pampd_count_max;
+
+/* forward reference */
+static int zcache_compress(struct page *from, void **out_va, size_t *out_len);
+
+static int zcache_pampd_eph_create(char *data, size_t size, bool raw,
+				struct tmem_pool *pool, struct tmem_oid *oid,
+				uint32_t index, void **pampd)
+{
+	int ret = -1;
+	void *cdata = data;
+	size_t clen = size;
+	struct zcache_client *cli = pool->client;
+	uint16_t client_id = get_client_id_from_client(cli);
+	struct page *page = NULL;
+	unsigned long count;
+
+	if (!raw) {
+		page = virt_to_page(data);
+		ret = zcache_compress(page, &cdata, &clen);
+		if (ret == 0)
+			goto out;
+		if (clen == 0 || clen > zbud_max_buddy_size()) {
+			zcache_compress_poor++;
+			goto out;
+		}
+	}
+	*pampd = (void *)zbud_create(client_id, pool->pool_id, oid,
+					index, page, cdata, clen);
+	if (*pampd == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	ret = 0;
+	count = atomic_inc_return(&zcache_curr_eph_pampd_count);
+	if (count > zcache_curr_eph_pampd_count_max)
+		zcache_curr_eph_pampd_count_max = count;
+	if (client_id != LOCAL_CLIENT) {
+		count = atomic_inc_return(&ramster_foreign_eph_pampd_count);
+		if (count > ramster_foreign_eph_pampd_count_max)
+			ramster_foreign_eph_pampd_count_max = count;
+	}
+out:
+	return ret;
+}
+
+static int zcache_pampd_pers_create(char *data, size_t size, bool raw,
+				struct tmem_pool *pool, struct tmem_oid *oid,
+				uint32_t index, void **pampd)
+{
+	int ret = -1;
+	void *cdata = data;
+	size_t clen = size;
+	struct zcache_client *cli = pool->client;
+	struct page *page;
+	unsigned long count;
+	unsigned long zv_mean_zsize;
+	struct zv_hdr *zv;
+	long curr_pers_pampd_count;
+	u64 total_zsize;
+#ifdef RAMSTER_TESTING
+	static bool pampd_neg_warned;
+#endif
+
+	curr_pers_pampd_count = atomic_read(&zcache_curr_pers_pampd_count) -
+			atomic_read(&ramster_remote_pers_pages);
+#ifdef RAMSTER_TESTING
+	/* should always be positive, but warn if accounting is off */
+	if (!pampd_neg_warned) {
+		pr_warn("ramster: bad accounting for curr_pers_pampd_count\n");
+		pampd_neg_warned = true;
+	}
+#endif
+	if (curr_pers_pampd_count >
+		    (zv_page_count_policy_percent * totalram_pages) / 100) {
+		zcache_policy_percent_exceeded++;
+		goto out;
+	}
+	if (raw)
+		goto ok_to_create;
+	page = virt_to_page(data);
+	if (zcache_compress(page, &cdata, &clen) == 0)
+		goto out;
+	/* reject if compression is too poor */
+	if (clen > zv_max_zsize) {
+		zcache_compress_poor++;
+		goto out;
+	}
+	/* reject if mean compression is too poor */
+	if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) {
+		total_zsize = xv_get_total_size_bytes(cli->xvpool);
+		zv_mean_zsize = div_u64(total_zsize, curr_pers_pampd_count);
+		if (zv_mean_zsize > zv_max_mean_zsize) {
+			zcache_mean_compress_poor++;
+			goto out;
+		}
+	}
+ok_to_create:
+	*pampd = (void *)zv_create(cli, pool->pool_id, oid, index, cdata, clen);
+	if (*pampd == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	ret = 0;
+	count = atomic_inc_return(&zcache_curr_pers_pampd_count);
+	if (count > zcache_curr_pers_pampd_count_max)
+		zcache_curr_pers_pampd_count_max = count;
+	if (is_local_client(cli))
+		goto out;
+	zv = *(struct zv_hdr **)pampd;
+	count = atomic_inc_return(&ramster_foreign_pers_pampd_count);
+	if (count > ramster_foreign_pers_pampd_count_max)
+		ramster_foreign_pers_pampd_count_max = count;
+out:
+	return ret;
+}
+
+static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
+				struct tmem_pool *pool, struct tmem_oid *oid,
+				uint32_t index)
+{
+	void *pampd = NULL;
+	int ret;
+	bool ephemeral;
+
+	BUG_ON(preemptible());
+	ephemeral = (eph == 1) || ((eph == 0) && is_ephemeral(pool));
+	if (ephemeral)
+		ret = zcache_pampd_eph_create(data, size, raw, pool,
+						oid, index, &pampd);
+	else
+		ret = zcache_pampd_pers_create(data, size, raw, pool,
+						oid, index, &pampd);
+	/* FIXME add some counters here for failed creates? */
+	return pampd;
+}
+
+/*
+ * fill the pageframe corresponding to the struct page with the data
+ * from the passed pampd
+ */
+static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw,
+					void *pampd, struct tmem_pool *pool,
+					struct tmem_oid *oid, uint32_t index)
+{
+	int ret = 0;
+
+	BUG_ON(preemptible());
+	BUG_ON(is_ephemeral(pool)); /* Fix later for shared pools? */
+	BUG_ON(pampd_is_remote(pampd));
+	if (raw)
+		zv_copy_from_pampd(data, bufsize, pampd);
+	else
+		zv_decompress(virt_to_page(data), pampd);
+	return ret;
+}
+
+static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw,
+					void *pampd, struct tmem_pool *pool,
+					struct tmem_oid *oid, uint32_t index)
+{
+	int ret = 0;
+	unsigned long flags;
+	struct zcache_client *cli = pool->client;
+
+	BUG_ON(preemptible());
+	BUG_ON(pampd_is_remote(pampd));
+	if (is_ephemeral(pool)) {
+		local_irq_save(flags);
+		if (raw)
+			zbud_copy_from_pampd(data, bufsize, pampd);
+		else
+			ret = zbud_decompress(virt_to_page(data), pampd);
+		zbud_free_and_delist((struct zbud_hdr *)pampd);
+		local_irq_restore(flags);
+		if (!is_local_client(cli))
+			dec_and_check(&ramster_foreign_eph_pampd_count);
+		dec_and_check(&zcache_curr_eph_pampd_count);
+	} else {
+		if (is_local_client(cli))
+			BUG();
+		if (raw)
+			zv_copy_from_pampd(data, bufsize, pampd);
+		else
+			zv_decompress(virt_to_page(data), pampd);
+		zv_free(cli->xvpool, pampd);
+		if (!is_local_client(cli))
+			dec_and_check(&ramster_foreign_pers_pampd_count);
+		dec_and_check(&zcache_curr_pers_pampd_count);
+		ret = 0;
+	}
+	return ret;
+}
+
+static bool zcache_pampd_is_remote(void *pampd)
+{
+	return pampd_is_remote(pampd);
+}
+
+/*
+ * free the pampd and remove it from any zcache lists
+ * pampd must no longer be pointed to from any tmem data structures!
+ */
+static void zcache_pampd_free(void *pampd, struct tmem_pool *pool,
+			      struct tmem_oid *oid, uint32_t index, bool acct)
+{
+	struct zcache_client *cli = pool->client;
+	bool eph = is_ephemeral(pool);
+	struct zv_hdr *zv;
+
+	BUG_ON(preemptible());
+	if (pampd_is_remote(pampd)) {
+		WARN_ON(acct == false);
+		if (oid == NULL) {
+			/*
+			 * a NULL oid means to ignore this pampd free
+			 * as the remote freeing will be handled elsewhere
+			 */
+		} else if (eph) {
+			/* FIXME remote flush optional but probably good idea */
+			/* FIXME get these working properly again */
+			dec_and_check(&zcache_curr_eph_pampd_count);
+		} else if (pampd_is_intransit(pampd)) {
+			/* did a pers remote get_and_free, so just free local */
+			pampd = pampd_mask_intransit_and_remote(pampd);
+			goto local_pers;
+		} else {
+			struct flushlist_node *flnode =
+				ramster_flnode_alloc(pool);
+
+			flnode->xh.client_id = pampd_remote_node(pampd);
+			flnode->xh.pool_id = pool->pool_id;
+			flnode->xh.oid = *oid;
+			flnode->xh.index = index;
+			flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_PAGE;
+			spin_lock(&zcache_rem_op_list_lock);
+			list_add(&flnode->rem_op.list, &zcache_rem_op_list);
+			spin_unlock(&zcache_rem_op_list_lock);
+			dec_and_check(&zcache_curr_pers_pampd_count);
+			dec_and_check(&ramster_remote_pers_pages);
+		}
+	} else if (eph) {
+		zbud_free_and_delist((struct zbud_hdr *)pampd);
+		if (!is_local_client(pool->client))
+			dec_and_check(&ramster_foreign_eph_pampd_count);
+		if (acct)
+			/* FIXME get these working properly again */
+			dec_and_check(&zcache_curr_eph_pampd_count);
+	} else {
+local_pers:
+		zv = (struct zv_hdr *)pampd;
+		if (!is_local_client(pool->client))
+			dec_and_check(&ramster_foreign_pers_pampd_count);
+		zv_free(cli->xvpool, zv);
+		if (acct)
+			/* FIXME get these working properly again */
+			dec_and_check(&zcache_curr_pers_pampd_count);
+	}
+}
+
+static void zcache_pampd_free_obj(struct tmem_pool *pool,
+					struct tmem_obj *obj)
+{
+	struct flushlist_node *flnode;
+
+	BUG_ON(preemptible());
+	if (obj->extra == NULL)
+		return;
+	BUG_ON(!pampd_is_remote(obj->extra));
+	flnode = ramster_flnode_alloc(pool);
+	flnode->xh.client_id = pampd_remote_node(obj->extra);
+	flnode->xh.pool_id = pool->pool_id;
+	flnode->xh.oid = obj->oid;
+	flnode->xh.index = FLUSH_ENTIRE_OBJECT;
+	flnode->rem_op.op = RAMSTER_REMOTIFY_FLUSH_OBJ;
+	spin_lock(&zcache_rem_op_list_lock);
+	list_add(&flnode->rem_op.list, &zcache_rem_op_list);
+	spin_unlock(&zcache_rem_op_list_lock);
+}
+
+void zcache_pampd_new_obj(struct tmem_obj *obj)
+{
+	obj->extra = NULL;
+}
+
+int zcache_pampd_replace_in_obj(void *new_pampd, struct tmem_obj *obj)
+{
+	int ret = -1;
+
+	if (new_pampd != NULL) {
+		if (obj->extra == NULL)
+			obj->extra = new_pampd;
+		/* enforce that all remote pages in an object reside
+		 * in the same node! */
+		else if (pampd_remote_node(new_pampd) !=
+				pampd_remote_node((void *)(obj->extra)))
+			BUG();
+		ret = 0;
+	}
+	return ret;
+}
+
+/*
+ * Called by the message handler after a (still compressed) page has been
+ * fetched from the remote machine in response to an "is_remote" tmem_get
+ * or persistent tmem_localify.  For a tmem_get, "extra" is the address of
+ * the page that is to be filled to succesfully resolve the tmem_get; for
+ * a (persistent) tmem_localify, "extra" is NULL (as the data is placed only
+ * in the local zcache).  "data" points to "size" bytes of (compressed) data
+ * passed in the message.  In the case of a persistent remote get, if
+ * pre-allocation was successful (see zcache_repatriate_preload), the page
+ * is placed into both local zcache and at "extra".
+ */
+int zcache_localify(int pool_id, struct tmem_oid *oidp,
+			uint32_t index, char *data, size_t size,
+			void *extra)
+{
+	int ret = -ENOENT;
+	unsigned long flags;
+	struct tmem_pool *pool;
+	bool ephemeral, delete = false;
+	size_t clen = PAGE_SIZE;
+	void *pampd, *saved_hb;
+	struct tmem_obj *obj;
+
+	pool = zcache_get_pool_by_id(LOCAL_CLIENT, pool_id);
+	if (unlikely(pool == NULL))
+		/* pool doesn't exist anymore */
+		goto out;
+	ephemeral = is_ephemeral(pool);
+	local_irq_save(flags);  /* FIXME: maybe only disable softirqs? */
+	pampd = tmem_localify_get_pampd(pool, oidp, index, &obj, &saved_hb);
+	if (pampd == NULL) {
+		/* hmmm... must have been a flush while waiting */
+#ifdef RAMSTER_TESTING
+		pr_err("UNTESTED pampd==NULL in zcache_localify\n");
+#endif
+		if (ephemeral)
+			ramster_remote_eph_pages_unsucc_get++;
+		else
+			ramster_remote_pers_pages_unsucc_get++;
+		obj = NULL;
+		goto finish;
+	} else if (unlikely(!pampd_is_remote(pampd))) {
+		/* hmmm... must have been a dup put while waiting */
+#ifdef RAMSTER_TESTING
+		pr_err("UNTESTED dup while waiting in zcache_localify\n");
+#endif
+		if (ephemeral)
+			ramster_remote_eph_pages_unsucc_get++;
+		else
+			ramster_remote_pers_pages_unsucc_get++;
+		obj = NULL;
+		pampd = NULL;
+		ret = -EEXIST;
+		goto finish;
+	} else if (size == 0) {
+		/* no remote data, delete the local is_remote pampd */
+		pampd = NULL;
+		if (ephemeral)
+			ramster_remote_eph_pages_unsucc_get++;
+		else
+			BUG();
+		delete = true;
+		goto finish;
+	}
+	if (!ephemeral && pampd_is_intransit(pampd)) {
+		/* localify to zcache */
+		pampd = pampd_mask_intransit_and_remote(pampd);
+		zv_copy_to_pampd(pampd, data, size);
+	} else {
+		pampd = NULL;
+		obj = NULL;
+	}
+	if (extra != NULL) {
+		/* decompress direct-to-memory to complete remotify */
+		ret = lzo1x_decompress_safe((char *)data, size,
+						(char *)extra, &clen);
+		BUG_ON(ret != LZO_E_OK);
+		BUG_ON(clen != PAGE_SIZE);
+	}
+	if (ephemeral)
+		ramster_remote_eph_pages_succ_get++;
+	else
+		ramster_remote_pers_pages_succ_get++;
+	ret = 0;
+finish:
+	tmem_localify_finish(obj, index, pampd, saved_hb, delete);
+	zcache_put_pool(pool);
+	local_irq_restore(flags);
+out:
+	return ret;
+}
+
+/*
+ * Called on a remote persistent tmem_get to attempt to preallocate
+ * local storage for the data contained in the remote persistent page.
+ * If succesfully preallocated, returns the pampd, marked as remote and
+ * in_transit.  Else returns NULL.  Note that the appropriate tmem data
+ * structure must be locked.
+ */
+static void *zcache_pampd_repatriate_preload(void *pampd,
+						struct tmem_pool *pool,
+						struct tmem_oid *oid,
+						uint32_t index,
+						bool *intransit)
+{
+	int clen = pampd_remote_size(pampd);
+	void *ret_pampd = NULL;
+	unsigned long flags;
+
+	if (!pampd_is_remote(pampd))
+		BUG();
+	if (is_ephemeral(pool))
+		BUG();
+	if (pampd_is_intransit(pampd)) {
+		/*
+		 * to avoid multiple allocations (and maybe a memory leak)
+		 * don't preallocate if already in the process of being
+		 * repatriated
+		 */
+		*intransit = true;
+		goto out;
+	}
+	*intransit = false;
+	local_irq_save(flags);
+	ret_pampd = (void *)zv_alloc(pool, oid, index, clen);
+	if (ret_pampd != NULL) {
+		/*
+		 *  a pampd is marked intransit if it is remote and space has
+		 *  been allocated for it locally (note, only happens for
+		 *  persistent pages, in which case the remote copy is freed)
+		 */
+		ret_pampd = pampd_mark_intransit(ret_pampd);
+		dec_and_check(&ramster_remote_pers_pages);
+	} else
+		ramster_pers_pages_remote_nomem++;
+	local_irq_restore(flags);
+out:
+	return ret_pampd;
+}
+
+/*
+ * Called on a remote tmem_get to invoke a message to fetch the page.
+ * Might sleep so no tmem locks can be held.  "extra" is passed
+ * all the way through the round-trip messaging to zcache_localify.
+ */
+static int zcache_pampd_repatriate(void *fake_pampd, void *real_pampd,
+				   struct tmem_pool *pool,
+				   struct tmem_oid *oid, uint32_t index,
+				   bool free, void *extra)
+{
+	struct tmem_xhandle xh;
+	int ret;
+
+	if (pampd_is_intransit(real_pampd))
+		/* have local space pre-reserved, so free remote copy */
+		free = true;
+	xh = tmem_xhandle_fill(LOCAL_CLIENT, pool, oid, index);
+	/* unreliable request/response for now */
+	ret = ramster_remote_async_get(&xh, free,
+					pampd_remote_node(fake_pampd),
+					pampd_remote_size(fake_pampd),
+					pampd_remote_cksum(fake_pampd),
+					extra);
+#ifdef RAMSTER_TESTING
+	if (ret != 0 && ret != -ENOENT)
+		pr_err("TESTING zcache_pampd_repatriate returns, ret=%d\n",
+			ret);
+#endif
+	return ret;
+}
+
+static struct tmem_pamops zcache_pamops = {
+	.create = zcache_pampd_create,
+	.get_data = zcache_pampd_get_data,
+	.free = zcache_pampd_free,
+	.get_data_and_free = zcache_pampd_get_data_and_free,
+	.free_obj = zcache_pampd_free_obj,
+	.is_remote = zcache_pampd_is_remote,
+	.repatriate_preload = zcache_pampd_repatriate_preload,
+	.repatriate = zcache_pampd_repatriate,
+	.new_obj = zcache_pampd_new_obj,
+	.replace_in_obj = zcache_pampd_replace_in_obj,
+};
+
+/*
+ * zcache compression/decompression and related per-cpu stuff
+ */
+
+#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS
+#define LZO_DSTMEM_PAGE_ORDER 1
+static DEFINE_PER_CPU(unsigned char *, zcache_workmem);
+static DEFINE_PER_CPU(unsigned char *, zcache_dstmem);
+
+static int zcache_compress(struct page *from, void **out_va, size_t *out_len)
+{
+	int ret = 0;
+	unsigned char *dmem = __get_cpu_var(zcache_dstmem);
+	unsigned char *wmem = __get_cpu_var(zcache_workmem);
+	char *from_va;
+
+	BUG_ON(!irqs_disabled());
+	if (unlikely(dmem == NULL || wmem == NULL))
+		goto out;  /* no buffer, so can't compress */
+	from_va = kmap_atomic(from, KM_USER0);
+	mb();
+	ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem);
+	BUG_ON(ret != LZO_E_OK);
+	*out_va = dmem;
+	kunmap_atomic(from_va, KM_USER0);
+	ret = 1;
+out:
+	return ret;
+}
+
+
+static int zcache_cpu_notifier(struct notifier_block *nb,
+				unsigned long action, void *pcpu)
+{
+	int cpu = (long)pcpu;
+	struct zcache_preload *kp;
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+		per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages(
+			GFP_KERNEL | __GFP_REPEAT,
+			LZO_DSTMEM_PAGE_ORDER),
+		per_cpu(zcache_workmem, cpu) =
+			kzalloc(LZO1X_MEM_COMPRESS,
+				GFP_KERNEL | __GFP_REPEAT);
+		per_cpu(zcache_remoteputmem, cpu) =
+			kzalloc(PAGE_SIZE, GFP_KERNEL | __GFP_REPEAT);
+		break;
+	case CPU_DEAD:
+	case CPU_UP_CANCELED:
+		kfree(per_cpu(zcache_remoteputmem, cpu));
+		per_cpu(zcache_remoteputmem, cpu) = NULL;
+		free_pages((unsigned long)per_cpu(zcache_dstmem, cpu),
+				LZO_DSTMEM_PAGE_ORDER);
+		per_cpu(zcache_dstmem, cpu) = NULL;
+		kfree(per_cpu(zcache_workmem, cpu));
+		per_cpu(zcache_workmem, cpu) = NULL;
+		kp = &per_cpu(zcache_preloads, cpu);
+		while (kp->nr) {
+			kmem_cache_free(zcache_objnode_cache,
+					kp->objnodes[kp->nr - 1]);
+			kp->objnodes[kp->nr - 1] = NULL;
+			kp->nr--;
+		}
+		if (kp->obj) {
+			kmem_cache_free(zcache_obj_cache, kp->obj);
+			kp->obj = NULL;
+		}
+		if (kp->flnode) {
+			kmem_cache_free(ramster_flnode_cache, kp->flnode);
+			kp->flnode = NULL;
+		}
+		if (kp->page) {
+			free_page((unsigned long)kp->page);
+			kp->page = NULL;
+		}
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block zcache_cpu_notifier_block = {
+	.notifier_call = zcache_cpu_notifier
+};
+
+#ifdef CONFIG_SYSFS
+#define ZCACHE_SYSFS_RO(_name) \
+	static ssize_t zcache_##_name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+	{ \
+		return sprintf(buf, "%lu\n", zcache_##_name); \
+	} \
+	static struct kobj_attribute zcache_##_name##_attr = { \
+		.attr = { .name = __stringify(_name), .mode = 0444 }, \
+		.show = zcache_##_name##_show, \
+	}
+
+#define ZCACHE_SYSFS_RO_ATOMIC(_name) \
+	static ssize_t zcache_##_name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+	{ \
+	    return sprintf(buf, "%d\n", atomic_read(&zcache_##_name)); \
+	} \
+	static struct kobj_attribute zcache_##_name##_attr = { \
+		.attr = { .name = __stringify(_name), .mode = 0444 }, \
+		.show = zcache_##_name##_show, \
+	}
+
+#define ZCACHE_SYSFS_RO_CUSTOM(_name, _func) \
+	static ssize_t zcache_##_name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+	{ \
+	    return _func(buf); \
+	} \
+	static struct kobj_attribute zcache_##_name##_attr = { \
+		.attr = { .name = __stringify(_name), .mode = 0444 }, \
+		.show = zcache_##_name##_show, \
+	}
+
+ZCACHE_SYSFS_RO(curr_obj_count_max);
+ZCACHE_SYSFS_RO(curr_objnode_count_max);
+ZCACHE_SYSFS_RO(flush_total);
+ZCACHE_SYSFS_RO(flush_found);
+ZCACHE_SYSFS_RO(flobj_total);
+ZCACHE_SYSFS_RO(flobj_found);
+ZCACHE_SYSFS_RO(failed_eph_puts);
+ZCACHE_SYSFS_RO(nonactive_puts);
+ZCACHE_SYSFS_RO(failed_pers_puts);
+ZCACHE_SYSFS_RO(zbud_curr_zbytes);
+ZCACHE_SYSFS_RO(zbud_cumul_zpages);
+ZCACHE_SYSFS_RO(zbud_cumul_zbytes);
+ZCACHE_SYSFS_RO(zbud_buddied_count);
+ZCACHE_SYSFS_RO(evicted_raw_pages);
+ZCACHE_SYSFS_RO(evicted_unbuddied_pages);
+ZCACHE_SYSFS_RO(evicted_buddied_pages);
+ZCACHE_SYSFS_RO(failed_get_free_pages);
+ZCACHE_SYSFS_RO(failed_alloc);
+ZCACHE_SYSFS_RO(put_to_flush);
+ZCACHE_SYSFS_RO(compress_poor);
+ZCACHE_SYSFS_RO(mean_compress_poor);
+ZCACHE_SYSFS_RO(policy_percent_exceeded);
+ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages);
+ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages);
+ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count);
+ZCACHE_SYSFS_RO_ATOMIC(curr_objnode_count);
+ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts,
+			zbud_show_unbuddied_list_counts);
+ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts,
+			zbud_show_cumul_chunk_counts);
+ZCACHE_SYSFS_RO_CUSTOM(zv_curr_dist_counts,
+			zv_curr_dist_counts_show);
+ZCACHE_SYSFS_RO_CUSTOM(zv_cumul_dist_counts,
+			zv_cumul_dist_counts_show);
+
+static struct attribute *zcache_attrs[] = {
+	&zcache_curr_obj_count_attr.attr,
+	&zcache_curr_obj_count_max_attr.attr,
+	&zcache_curr_objnode_count_attr.attr,
+	&zcache_curr_objnode_count_max_attr.attr,
+	&zcache_flush_total_attr.attr,
+	&zcache_flobj_total_attr.attr,
+	&zcache_flush_found_attr.attr,
+	&zcache_flobj_found_attr.attr,
+	&zcache_failed_eph_puts_attr.attr,
+	&zcache_nonactive_puts_attr.attr,
+	&zcache_failed_pers_puts_attr.attr,
+	&zcache_policy_percent_exceeded_attr.attr,
+	&zcache_compress_poor_attr.attr,
+	&zcache_mean_compress_poor_attr.attr,
+	&zcache_zbud_curr_raw_pages_attr.attr,
+	&zcache_zbud_curr_zpages_attr.attr,
+	&zcache_zbud_curr_zbytes_attr.attr,
+	&zcache_zbud_cumul_zpages_attr.attr,
+	&zcache_zbud_cumul_zbytes_attr.attr,
+	&zcache_zbud_buddied_count_attr.attr,
+	&zcache_evicted_raw_pages_attr.attr,
+	&zcache_evicted_unbuddied_pages_attr.attr,
+	&zcache_evicted_buddied_pages_attr.attr,
+	&zcache_failed_get_free_pages_attr.attr,
+	&zcache_failed_alloc_attr.attr,
+	&zcache_put_to_flush_attr.attr,
+	&zcache_zbud_unbuddied_list_counts_attr.attr,
+	&zcache_zbud_cumul_chunk_counts_attr.attr,
+	&zcache_zv_curr_dist_counts_attr.attr,
+	&zcache_zv_cumul_dist_counts_attr.attr,
+	&zcache_zv_max_zsize_attr.attr,
+	&zcache_zv_max_mean_zsize_attr.attr,
+	&zcache_zv_page_count_policy_percent_attr.attr,
+	NULL,
+};
+
+static struct attribute_group zcache_attr_group = {
+	.attrs = zcache_attrs,
+	.name = "zcache",
+};
+
+#define RAMSTER_SYSFS_RO(_name) \
+	static ssize_t ramster_##_name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+	{ \
+		return sprintf(buf, "%lu\n", ramster_##_name); \
+	} \
+	static struct kobj_attribute ramster_##_name##_attr = { \
+		.attr = { .name = __stringify(_name), .mode = 0444 }, \
+		.show = ramster_##_name##_show, \
+	}
+
+#define RAMSTER_SYSFS_RW(_name) \
+	static ssize_t ramster_##_name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+	{ \
+		return sprintf(buf, "%lu\n", ramster_##_name); \
+	} \
+	static ssize_t ramster_##_name##_store(struct kobject *kobj, \
+		struct kobj_attribute *attr, const char *buf, size_t count) \
+	{ \
+		int err; \
+		unsigned long enable; \
+		err = kstrtoul(buf, 10, &enable); \
+		if (err) \
+			return -EINVAL; \
+		ramster_##_name = enable; \
+		return count; \
+	} \
+	static struct kobj_attribute ramster_##_name##_attr = { \
+		.attr = { .name = __stringify(_name), .mode = 0644 }, \
+		.show = ramster_##_name##_show, \
+		.store = ramster_##_name##_store, \
+	}
+
+#define RAMSTER_SYSFS_RO_ATOMIC(_name) \
+	static ssize_t ramster_##_name##_show(struct kobject *kobj, \
+				struct kobj_attribute *attr, char *buf) \
+	{ \
+	    return sprintf(buf, "%d\n", atomic_read(&ramster_##_name)); \
+	} \
+	static struct kobj_attribute ramster_##_name##_attr = { \
+		.attr = { .name = __stringify(_name), .mode = 0444 }, \
+		.show = ramster_##_name##_show, \
+	}
+
+RAMSTER_SYSFS_RO(interface_revision);
+RAMSTER_SYSFS_RO_ATOMIC(remote_pers_pages);
+RAMSTER_SYSFS_RW(pers_remotify_enable);
+RAMSTER_SYSFS_RW(eph_remotify_enable);
+RAMSTER_SYSFS_RO(eph_pages_remoted);
+RAMSTER_SYSFS_RO(eph_pages_remote_failed);
+RAMSTER_SYSFS_RO(pers_pages_remoted);
+RAMSTER_SYSFS_RO(pers_pages_remote_failed);
+RAMSTER_SYSFS_RO(pers_pages_remote_nomem);
+RAMSTER_SYSFS_RO(remote_pages_flushed);
+RAMSTER_SYSFS_RO(remote_page_flushes_failed);
+RAMSTER_SYSFS_RO(remote_objects_flushed);
+RAMSTER_SYSFS_RO(remote_object_flushes_failed);
+RAMSTER_SYSFS_RO(remote_eph_pages_succ_get);
+RAMSTER_SYSFS_RO(remote_eph_pages_unsucc_get);
+RAMSTER_SYSFS_RO(remote_pers_pages_succ_get);
+RAMSTER_SYSFS_RO(remote_pers_pages_unsucc_get);
+RAMSTER_SYSFS_RO_ATOMIC(foreign_eph_pampd_count);
+RAMSTER_SYSFS_RO(foreign_eph_pampd_count_max);
+RAMSTER_SYSFS_RO_ATOMIC(foreign_pers_pampd_count);
+RAMSTER_SYSFS_RO(foreign_pers_pampd_count_max);
+RAMSTER_SYSFS_RO_ATOMIC(curr_flnode_count);
+RAMSTER_SYSFS_RO(curr_flnode_count_max);
+
+#define MANUAL_NODES 8
+static bool ramster_nodes_manual_up[MANUAL_NODES];
+static ssize_t ramster_manual_node_up_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	int i;
+	char *p = buf;
+	for (i = 0; i < MANUAL_NODES; i++)
+		if (ramster_nodes_manual_up[i])
+			p += sprintf(p, "%d ", i);
+	p += sprintf(p, "\n");
+	return p - buf;
+}
+
+static ssize_t ramster_manual_node_up_store(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int err;
+	unsigned long node_num;
+
+	err = kstrtoul(buf, 10, &node_num);
+	if (err) {
+		pr_err("ramster: bad strtoul?\n");
+		return -EINVAL;
+	}
+	if (node_num >= MANUAL_NODES) {
+		pr_err("ramster: bad node_num=%lu?\n", node_num);
+		return -EINVAL;
+	}
+	if (ramster_nodes_manual_up[node_num]) {
+		pr_err("ramster: node %d already up, ignoring\n",
+							(int)node_num);
+	} else {
+		ramster_nodes_manual_up[node_num] = true;
+		r2net_hb_node_up_manual((int)node_num);
+	}
+	return count;
+}
+
+static struct kobj_attribute ramster_manual_node_up_attr = {
+	.attr = { .name = "manual_node_up", .mode = 0644 },
+	.show = ramster_manual_node_up_show,
+	.store = ramster_manual_node_up_store,
+};
+
+static ssize_t ramster_remote_target_nodenum_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *buf)
+{
+	if (ramster_remote_target_nodenum == -1UL)
+		return sprintf(buf, "unset\n");
+	else
+		return sprintf(buf, "%d\n", ramster_remote_target_nodenum);
+}
+
+static ssize_t ramster_remote_target_nodenum_store(struct kobject *kobj,
+		struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int err;
+	unsigned long node_num;
+
+	err = kstrtoul(buf, 10, &node_num);
+	if (err) {
+		pr_err("ramster: bad strtoul?\n");
+		return -EINVAL;
+	} else if (node_num == -1UL) {
+		pr_err("ramster: disabling all remotification, "
+			"data may still reside on remote nodes however\n");
+		return -EINVAL;
+	} else if (node_num >= MANUAL_NODES) {
+		pr_err("ramster: bad node_num=%lu?\n", node_num);
+		return -EINVAL;
+	} else if (!ramster_nodes_manual_up[node_num]) {
+		pr_err("ramster: node %d not up, ignoring setting "
+			"of remotification target\n", (int)node_num);
+	} else if (r2net_remote_target_node_set((int)node_num) >= 0) {
+		pr_info("ramster: node %d set as remotification target\n",
+				(int)node_num);
+		ramster_remote_target_nodenum = (int)node_num;
+	} else {
+		pr_err("ramster: bad num to node node_num=%d?\n",
+				(int)node_num);
+		return -EINVAL;
+	}
+	return count;
+}
+
+static struct kobj_attribute ramster_remote_target_nodenum_attr = {
+	.attr = { .name = "remote_target_nodenum", .mode = 0644 },
+	.show = ramster_remote_target_nodenum_show,
+	.store = ramster_remote_target_nodenum_store,
+};
+
+
+static struct attribute *ramster_attrs[] = {
+	&ramster_interface_revision_attr.attr,
+	&ramster_pers_remotify_enable_attr.attr,
+	&ramster_eph_remotify_enable_attr.attr,
+	&ramster_remote_pers_pages_attr.attr,
+	&ramster_eph_pages_remoted_attr.attr,
+	&ramster_eph_pages_remote_failed_attr.attr,
+	&ramster_pers_pages_remoted_attr.attr,
+	&ramster_pers_pages_remote_failed_attr.attr,
+	&ramster_pers_pages_remote_nomem_attr.attr,
+	&ramster_remote_pages_flushed_attr.attr,
+	&ramster_remote_page_flushes_failed_attr.attr,
+	&ramster_remote_objects_flushed_attr.attr,
+	&ramster_remote_object_flushes_failed_attr.attr,
+	&ramster_remote_eph_pages_succ_get_attr.attr,
+	&ramster_remote_eph_pages_unsucc_get_attr.attr,
+	&ramster_remote_pers_pages_succ_get_attr.attr,
+	&ramster_remote_pers_pages_unsucc_get_attr.attr,
+	&ramster_foreign_eph_pampd_count_attr.attr,
+	&ramster_foreign_eph_pampd_count_max_attr.attr,
+	&ramster_foreign_pers_pampd_count_attr.attr,
+	&ramster_foreign_pers_pampd_count_max_attr.attr,
+	&ramster_curr_flnode_count_attr.attr,
+	&ramster_curr_flnode_count_max_attr.attr,
+	&ramster_manual_node_up_attr.attr,
+	&ramster_remote_target_nodenum_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ramster_attr_group = {
+	.attrs = ramster_attrs,
+	.name = "ramster",
+};
+
+#endif /* CONFIG_SYSFS */
+/*
+ * When zcache is disabled ("frozen"), pools can be created and destroyed,
+ * but all puts (and thus all other operations that require memory allocation)
+ * must fail.  If zcache is unfrozen, accepts puts, then frozen again,
+ * data consistency requires all puts while frozen to be converted into
+ * flushes.
+ */
+static bool zcache_freeze;
+
+/*
+ * zcache shrinker interface (only useful for ephemeral pages, so zbud only)
+ */
+static int shrink_zcache_memory(struct shrinker *shrink,
+				struct shrink_control *sc)
+{
+	int ret = -1;
+	int nr = sc->nr_to_scan;
+	gfp_t gfp_mask = sc->gfp_mask;
+
+	if (nr >= 0) {
+		if (!(gfp_mask & __GFP_FS))
+			/* does this case really need to be skipped? */
+			goto out;
+		zbud_evict_pages(nr);
+	}
+	ret = (int)atomic_read(&zcache_zbud_curr_raw_pages);
+out:
+	return ret;
+}
+
+static struct shrinker zcache_shrinker = {
+	.shrink = shrink_zcache_memory,
+	.seeks = DEFAULT_SEEKS,
+};
+
+/*
+ * zcache shims between cleancache/frontswap ops and tmem
+ */
+
+int zcache_put(int cli_id, int pool_id, struct tmem_oid *oidp,
+			uint32_t index, char *data, size_t size,
+			bool raw, int ephemeral)
+{
+	struct tmem_pool *pool;
+	int ret = -1;
+
+	BUG_ON(!irqs_disabled());
+	pool = zcache_get_pool_by_id(cli_id, pool_id);
+	if (unlikely(pool == NULL))
+		goto out;
+	if (!zcache_freeze && zcache_do_preload(pool) == 0) {
+		/* preload does preempt_disable on success */
+		ret = tmem_put(pool, oidp, index, data, size, raw, ephemeral);
+		if (ret < 0) {
+			if (is_ephemeral(pool))
+				zcache_failed_eph_puts++;
+			else
+				zcache_failed_pers_puts++;
+		}
+		zcache_put_pool(pool);
+		preempt_enable_no_resched();
+	} else {
+		zcache_put_to_flush++;
+		if (atomic_read(&pool->obj_count) > 0)
+			/* the put fails whether the flush succeeds or not */
+			(void)tmem_flush_page(pool, oidp, index);
+		zcache_put_pool(pool);
+	}
+out:
+	return ret;
+}
+
+int zcache_get(int cli_id, int pool_id, struct tmem_oid *oidp,
+			uint32_t index, char *data, size_t *sizep,
+			bool raw, int get_and_free)
+{
+	struct tmem_pool *pool;
+	int ret = -1;
+	bool eph;
+
+	if (!raw) {
+		BUG_ON(irqs_disabled());
+		BUG_ON(in_softirq());
+	}
+	pool = zcache_get_pool_by_id(cli_id, pool_id);
+	eph = is_ephemeral(pool);
+	if (likely(pool != NULL)) {
+		if (atomic_read(&pool->obj_count) > 0)
+			ret = tmem_get(pool, oidp, index, data, sizep,
+					raw, get_and_free);
+		zcache_put_pool(pool);
+	}
+	WARN_ONCE((!eph && (ret != 0)), "zcache_get fails on persistent pool, "
+			  "bad things are very likely to happen soon\n");
+#ifdef RAMSTER_TESTING
+	if (ret != 0 && ret != -1 && !(ret == -EINVAL && is_ephemeral(pool)))
+		pr_err("TESTING zcache_get tmem_get returns ret=%d\n", ret);
+#endif
+	if (ret == -EAGAIN)
+		BUG(); /* FIXME... don't need this anymore??? let's ensure */
+	return ret;
+}
+
+int zcache_flush(int cli_id, int pool_id,
+				struct tmem_oid *oidp, uint32_t index)
+{
+	struct tmem_pool *pool;
+	int ret = -1;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	zcache_flush_total++;
+	pool = zcache_get_pool_by_id(cli_id, pool_id);
+	ramster_do_preload_flnode_only(pool);
+	if (likely(pool != NULL)) {
+		if (atomic_read(&pool->obj_count) > 0)
+			ret = tmem_flush_page(pool, oidp, index);
+		zcache_put_pool(pool);
+	}
+	if (ret >= 0)
+		zcache_flush_found++;
+	local_irq_restore(flags);
+	return ret;
+}
+
+int zcache_flush_object(int cli_id, int pool_id, struct tmem_oid *oidp)
+{
+	struct tmem_pool *pool;
+	int ret = -1;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	zcache_flobj_total++;
+	pool = zcache_get_pool_by_id(cli_id, pool_id);
+	ramster_do_preload_flnode_only(pool);
+	if (likely(pool != NULL)) {
+		if (atomic_read(&pool->obj_count) > 0)
+			ret = tmem_flush_object(pool, oidp);
+		zcache_put_pool(pool);
+	}
+	if (ret >= 0)
+		zcache_flobj_found++;
+	local_irq_restore(flags);
+	return ret;
+}
+
+int zcache_client_destroy_pool(int cli_id, int pool_id)
+{
+	struct tmem_pool *pool = NULL;
+	struct zcache_client *cli = NULL;
+	int ret = -1;
+
+	if (pool_id < 0)
+		goto out;
+	if (cli_id == LOCAL_CLIENT)
+		cli = &zcache_host;
+	else if ((unsigned int)cli_id < MAX_CLIENTS)
+		cli = &zcache_clients[cli_id];
+	if (cli == NULL)
+		goto out;
+	atomic_inc(&cli->refcount);
+	pool = cli->tmem_pools[pool_id];
+	if (pool == NULL)
+		goto out;
+	cli->tmem_pools[pool_id] = NULL;
+	/* wait for pool activity on other cpus to quiesce */
+	while (atomic_read(&pool->refcount) != 0)
+		;
+	atomic_dec(&cli->refcount);
+	local_bh_disable();
+	ret = tmem_destroy_pool(pool);
+	local_bh_enable();
+	kfree(pool);
+	pr_info("ramster: destroyed pool id=%d cli_id=%d\n", pool_id, cli_id);
+out:
+	return ret;
+}
+
+static int zcache_destroy_pool(int pool_id)
+{
+	return zcache_client_destroy_pool(LOCAL_CLIENT, pool_id);
+}
+
+int zcache_new_pool(uint16_t cli_id, uint32_t flags)
+{
+	int poolid = -1;
+	struct tmem_pool *pool;
+	struct zcache_client *cli = NULL;
+
+	if (cli_id == LOCAL_CLIENT)
+		cli = &zcache_host;
+	else if ((unsigned int)cli_id < MAX_CLIENTS)
+		cli = &zcache_clients[cli_id];
+	if (cli == NULL)
+		goto out;
+	atomic_inc(&cli->refcount);
+	pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC);
+	if (pool == NULL) {
+		pr_info("ramster: pool creation failed: out of memory\n");
+		goto out;
+	}
+
+	for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++)
+		if (cli->tmem_pools[poolid] == NULL)
+			break;
+	if (poolid >= MAX_POOLS_PER_CLIENT) {
+		pr_info("ramster: pool creation failed: max exceeded\n");
+		kfree(pool);
+		poolid = -1;
+		goto out;
+	}
+	atomic_set(&pool->refcount, 0);
+	pool->client = cli;
+	pool->pool_id = poolid;
+	tmem_new_pool(pool, flags);
+	cli->tmem_pools[poolid] = pool;
+	if (cli_id == LOCAL_CLIENT)
+		pr_info("ramster: created %s tmem pool, id=%d, local client\n",
+			flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral",
+			poolid);
+	else
+		pr_info("ramster: created %s tmem pool, id=%d, client=%d\n",
+			flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral",
+			poolid, cli_id);
+out:
+	if (cli != NULL)
+		atomic_dec(&cli->refcount);
+	return poolid;
+}
+
+static int zcache_local_new_pool(uint32_t flags)
+{
+	return zcache_new_pool(LOCAL_CLIENT, flags);
+}
+
+int zcache_autocreate_pool(int cli_id, int pool_id, bool ephemeral)
+{
+	struct tmem_pool *pool;
+	struct zcache_client *cli = NULL;
+	uint32_t flags = ephemeral ? 0 : TMEM_POOL_PERSIST;
+	int ret = -1;
+
+	if (cli_id == LOCAL_CLIENT)
+		goto out;
+	if (pool_id >= MAX_POOLS_PER_CLIENT)
+		goto out;
+	else if ((unsigned int)cli_id < MAX_CLIENTS)
+		cli = &zcache_clients[cli_id];
+	if ((ephemeral && !use_cleancache) || (!ephemeral && !use_frontswap))
+		BUG(); /* FIXME, handle more gracefully later */
+	if (!cli->allocated) {
+		if (zcache_new_client(cli_id))
+			BUG(); /* FIXME, handle more gracefully later */
+		cli = &zcache_clients[cli_id];
+	}
+	atomic_inc(&cli->refcount);
+	pool = cli->tmem_pools[pool_id];
+	if (pool != NULL) {
+		if (pool->persistent && ephemeral) {
+			pr_err("zcache_autocreate_pool: type mismatch\n");
+			goto out;
+		}
+		ret = 0;
+		goto out;
+	}
+	pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL);
+	if (pool == NULL) {
+		pr_info("ramster: pool creation failed: out of memory\n");
+		goto out;
+	}
+	atomic_set(&pool->refcount, 0);
+	pool->client = cli;
+	pool->pool_id = pool_id;
+	tmem_new_pool(pool, flags);
+	cli->tmem_pools[pool_id] = pool;
+	pr_info("ramster: AUTOcreated %s tmem poolid=%d, for remote client=%d\n",
+		flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral",
+		pool_id, cli_id);
+	ret = 0;
+out:
+	if (cli == NULL)
+		BUG(); /* FIXME, handle more gracefully later */
+		/* pr_err("zcache_autocreate_pool: failed\n"); */
+	if (cli != NULL)
+		atomic_dec(&cli->refcount);
+	return ret;
+}
+
+/**********
+ * Two kernel functionalities currently can be layered on top of tmem.
+ * These are "cleancache" which is used as a second-chance cache for clean
+ * page cache pages; and "frontswap" which is used for swap pages
+ * to avoid writes to disk.  A generic "shim" is provided here for each
+ * to translate in-kernel semantics to zcache semantics.
+ */
+
+#ifdef CONFIG_CLEANCACHE
+static void zcache_cleancache_put_page(int pool_id,
+					struct cleancache_filekey key,
+					pgoff_t index, struct page *page)
+{
+	u32 ind = (u32) index;
+	struct tmem_oid oid = *(struct tmem_oid *)&key;
+
+#ifdef __PG_WAS_ACTIVE
+	if (!PageWasActive(page)) {
+		zcache_nonactive_puts++;
+		return;
+	}
+#endif
+	if (likely(ind == index)) {
+		char *kva = page_address(page);
+
+		(void)zcache_put(LOCAL_CLIENT, pool_id, &oid, index,
+			kva, PAGE_SIZE, 0, 1);
+	}
+}
+
+static int zcache_cleancache_get_page(int pool_id,
+					struct cleancache_filekey key,
+					pgoff_t index, struct page *page)
+{
+	u32 ind = (u32) index;
+	struct tmem_oid oid = *(struct tmem_oid *)&key;
+	int ret = -1;
+
+	preempt_disable();
+	if (likely(ind == index)) {
+		char *kva = page_address(page);
+		size_t size = PAGE_SIZE;
+
+		ret = zcache_get(LOCAL_CLIENT, pool_id, &oid, index,
+			kva, &size, 0, 0);
+#ifdef __PG_WAS_ACTIVE
+		if (ret == 0)
+			SetPageWasActive(page);
+#endif
+	}
+	preempt_enable();
+	return ret;
+}
+
+static void zcache_cleancache_flush_page(int pool_id,
+					struct cleancache_filekey key,
+					pgoff_t index)
+{
+	u32 ind = (u32) index;
+	struct tmem_oid oid = *(struct tmem_oid *)&key;
+
+	if (likely(ind == index))
+		(void)zcache_flush(LOCAL_CLIENT, pool_id, &oid, ind);
+}
+
+static void zcache_cleancache_flush_inode(int pool_id,
+					struct cleancache_filekey key)
+{
+	struct tmem_oid oid = *(struct tmem_oid *)&key;
+
+	(void)zcache_flush_object(LOCAL_CLIENT, pool_id, &oid);
+}
+
+static void zcache_cleancache_flush_fs(int pool_id)
+{
+	if (pool_id >= 0)
+		(void)zcache_destroy_pool(pool_id);
+}
+
+static int zcache_cleancache_init_fs(size_t pagesize)
+{
+	BUG_ON(sizeof(struct cleancache_filekey) !=
+				sizeof(struct tmem_oid));
+	BUG_ON(pagesize != PAGE_SIZE);
+	return zcache_local_new_pool(0);
+}
+
+static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize)
+{
+	/* shared pools are unsupported and map to private */
+	BUG_ON(sizeof(struct cleancache_filekey) !=
+				sizeof(struct tmem_oid));
+	BUG_ON(pagesize != PAGE_SIZE);
+	return zcache_local_new_pool(0);
+}
+
+static struct cleancache_ops zcache_cleancache_ops = {
+	.put_page = zcache_cleancache_put_page,
+	.get_page = zcache_cleancache_get_page,
+	.invalidate_page = zcache_cleancache_flush_page,
+	.invalidate_inode = zcache_cleancache_flush_inode,
+	.invalidate_fs = zcache_cleancache_flush_fs,
+	.init_shared_fs = zcache_cleancache_init_shared_fs,
+	.init_fs = zcache_cleancache_init_fs
+};
+
+struct cleancache_ops zcache_cleancache_register_ops(void)
+{
+	struct cleancache_ops old_ops =
+		cleancache_register_ops(&zcache_cleancache_ops);
+
+	return old_ops;
+}
+#endif
+
+#ifdef CONFIG_FRONTSWAP
+/* a single tmem poolid is used for all frontswap "types" (swapfiles) */
+static int zcache_frontswap_poolid = -1;
+
+/*
+ * Swizzling increases objects per swaptype, increasing tmem concurrency
+ * for heavy swaploads.  Later, larger nr_cpus -> larger SWIZ_BITS
+ */
+#define SWIZ_BITS		8
+#define SWIZ_MASK		((1 << SWIZ_BITS) - 1)
+#define _oswiz(_type, _ind)	((_type << SWIZ_BITS) | (_ind & SWIZ_MASK))
+#define iswiz(_ind)		(_ind >> SWIZ_BITS)
+
+static inline struct tmem_oid oswiz(unsigned type, u32 ind)
+{
+	struct tmem_oid oid = { .oid = { 0 } };
+	oid.oid[0] = _oswiz(type, ind);
+	return oid;
+}
+
+static int zcache_frontswap_put_page(unsigned type, pgoff_t offset,
+				   struct page *page)
+{
+	u64 ind64 = (u64)offset;
+	u32 ind = (u32)offset;
+	struct tmem_oid oid = oswiz(type, ind);
+	int ret = -1;
+	unsigned long flags;
+	char *kva;
+
+	BUG_ON(!PageLocked(page));
+	if (likely(ind64 == ind)) {
+		local_irq_save(flags);
+		kva = page_address(page);
+		ret = zcache_put(LOCAL_CLIENT, zcache_frontswap_poolid,
+				&oid, iswiz(ind), kva, PAGE_SIZE, 0, 0);
+		local_irq_restore(flags);
+	}
+	return ret;
+}
+
+/* returns 0 if the page was successfully gotten from frontswap, -1 if
+ * was not present (should never happen!) */
+static int zcache_frontswap_get_page(unsigned type, pgoff_t offset,
+				   struct page *page)
+{
+	u64 ind64 = (u64)offset;
+	u32 ind = (u32)offset;
+	struct tmem_oid oid = oswiz(type, ind);
+	int ret = -1;
+
+	preempt_disable(); /* FIXME, remove this? */
+	BUG_ON(!PageLocked(page));
+	if (likely(ind64 == ind)) {
+		char *kva = page_address(page);
+		size_t size = PAGE_SIZE;
+
+		ret = zcache_get(LOCAL_CLIENT, zcache_frontswap_poolid,
+					&oid, iswiz(ind), kva, &size, 0, -1);
+	}
+	preempt_enable(); /* FIXME, remove this? */
+	return ret;
+}
+
+/* flush a single page from frontswap */
+static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset)
+{
+	u64 ind64 = (u64)offset;
+	u32 ind = (u32)offset;
+	struct tmem_oid oid = oswiz(type, ind);
+
+	if (likely(ind64 == ind))
+		(void)zcache_flush(LOCAL_CLIENT, zcache_frontswap_poolid,
+					&oid, iswiz(ind));
+}
+
+/* flush all pages from the passed swaptype */
+static void zcache_frontswap_flush_area(unsigned type)
+{
+	struct tmem_oid oid;
+	int ind;
+
+	for (ind = SWIZ_MASK; ind >= 0; ind--) {
+		oid = oswiz(type, ind);
+		(void)zcache_flush_object(LOCAL_CLIENT,
+						zcache_frontswap_poolid, &oid);
+	}
+}
+
+static void zcache_frontswap_init(unsigned ignored)
+{
+	/* a single tmem poolid is used for all frontswap "types" (swapfiles) */
+	if (zcache_frontswap_poolid < 0)
+		zcache_frontswap_poolid =
+				zcache_local_new_pool(TMEM_POOL_PERSIST);
+}
+
+static struct frontswap_ops zcache_frontswap_ops = {
+	.put_page = zcache_frontswap_put_page,
+	.get_page = zcache_frontswap_get_page,
+	.invalidate_page = zcache_frontswap_flush_page,
+	.invalidate_area = zcache_frontswap_flush_area,
+	.init = zcache_frontswap_init
+};
+
+struct frontswap_ops zcache_frontswap_register_ops(void)
+{
+	struct frontswap_ops old_ops =
+		frontswap_register_ops(&zcache_frontswap_ops);
+
+	return old_ops;
+}
+#endif
+
+/*
+ * frontswap selfshrinking
+ */
+
+#ifdef CONFIG_FRONTSWAP
+/* In HZ, controls frequency of worker invocation. */
+static unsigned int selfshrink_interval __read_mostly = 5;
+
+static void selfshrink_process(struct work_struct *work);
+static DECLARE_DELAYED_WORK(selfshrink_worker, selfshrink_process);
+
+/* Enable/disable with sysfs. */
+static bool frontswap_selfshrinking __read_mostly;
+
+/* Enable/disable with kernel boot option. */
+static bool use_frontswap_selfshrink __initdata = true;
+
+/*
+ * The default values for the following parameters were deemed reasonable
+ * by experimentation, may be workload-dependent, and can all be
+ * adjusted via sysfs.
+ */
+
+/* Control rate for frontswap shrinking. Higher hysteresis is slower. */
+static unsigned int frontswap_hysteresis __read_mostly = 20;
+
+/*
+ * Number of selfshrink worker invocations to wait before observing that
+ * frontswap selfshrinking should commence. Note that selfshrinking does
+ * not use a separate worker thread.
+ */
+static unsigned int frontswap_inertia __read_mostly = 3;
+
+/* Countdown to next invocation of frontswap_shrink() */
+static unsigned long frontswap_inertia_counter;
+
+/*
+ * Invoked by the selfshrink worker thread, uses current number of pages
+ * in frontswap (frontswap_curr_pages()), previous status, and control
+ * values (hysteresis and inertia) to determine if frontswap should be
+ * shrunk and what the new frontswap size should be.  Note that
+ * frontswap_shrink is essentially a partial swapoff that immediately
+ * transfers pages from the "swap device" (frontswap) back into kernel
+ * RAM; despite the name, frontswap "shrinking" is very different from
+ * the "shrinker" interface used by the kernel MM subsystem to reclaim
+ * memory.
+ */
+static void frontswap_selfshrink(void)
+{
+	static unsigned long cur_frontswap_pages;
+	static unsigned long last_frontswap_pages;
+	static unsigned long tgt_frontswap_pages;
+
+	last_frontswap_pages = cur_frontswap_pages;
+	cur_frontswap_pages = frontswap_curr_pages();
+	if (!cur_frontswap_pages ||
+			(cur_frontswap_pages > last_frontswap_pages)) {
+		frontswap_inertia_counter = frontswap_inertia;
+		return;
+	}
+	if (frontswap_inertia_counter && --frontswap_inertia_counter)
+		return;
+	if (cur_frontswap_pages <= frontswap_hysteresis)
+		tgt_frontswap_pages = 0;
+	else
+		tgt_frontswap_pages = cur_frontswap_pages -
+			(cur_frontswap_pages / frontswap_hysteresis);
+	frontswap_shrink(tgt_frontswap_pages);
+}
+
+static int __init ramster_nofrontswap_selfshrink_setup(char *s)
+{
+	use_frontswap_selfshrink = false;
+	return 1;
+}
+
+__setup("noselfshrink", ramster_nofrontswap_selfshrink_setup);
+
+static void selfshrink_process(struct work_struct *work)
+{
+	if (frontswap_selfshrinking && frontswap_enabled) {
+		frontswap_selfshrink();
+		schedule_delayed_work(&selfshrink_worker,
+			selfshrink_interval * HZ);
+	}
+}
+
+static int ramster_enabled;
+
+static int __init ramster_selfshrink_init(void)
+{
+	frontswap_selfshrinking = ramster_enabled && use_frontswap_selfshrink;
+	if (frontswap_selfshrinking)
+		pr_info("ramster: Initializing frontswap "
+					"selfshrinking driver.\n");
+	else
+		return -ENODEV;
+
+	schedule_delayed_work(&selfshrink_worker, selfshrink_interval * HZ);
+
+	return 0;
+}
+
+subsys_initcall(ramster_selfshrink_init);
+#endif
+
+/*
+ * zcache initialization
+ * NOTE FOR NOW ramster MUST BE PROVIDED AS A KERNEL BOOT PARAMETER OR
+ * NOTHING HAPPENS!
+ */
+
+static int ramster_enabled;
+
+static int __init enable_ramster(char *s)
+{
+	ramster_enabled = 1;
+	return 1;
+}
+__setup("ramster", enable_ramster);
+
+/* allow independent dynamic disabling of cleancache and frontswap */
+
+static int use_cleancache = 1;
+
+static int __init no_cleancache(char *s)
+{
+	pr_info("INIT no_cleancache called\n");
+	use_cleancache = 0;
+	return 1;
+}
+
+/*
+ * FIXME: need to guarantee this gets checked before zcache_init is called
+ * What is the correct way to achieve this?
+ */
+early_param("nocleancache", no_cleancache);
+
+static int use_frontswap = 1;
+
+static int __init no_frontswap(char *s)
+{
+	pr_info("INIT no_frontswap called\n");
+	use_frontswap = 0;
+	return 1;
+}
+
+__setup("nofrontswap", no_frontswap);
+
+static int __init zcache_init(void)
+{
+	int ret = 0;
+
+#ifdef CONFIG_SYSFS
+	ret = sysfs_create_group(mm_kobj, &zcache_attr_group);
+	ret = sysfs_create_group(mm_kobj, &ramster_attr_group);
+	if (ret) {
+		pr_err("ramster: can't create sysfs\n");
+		goto out;
+	}
+#endif /* CONFIG_SYSFS */
+#if defined(CONFIG_CLEANCACHE) || defined(CONFIG_FRONTSWAP)
+	if (ramster_enabled) {
+		unsigned int cpu;
+
+		(void)r2net_register_handlers();
+		tmem_register_hostops(&zcache_hostops);
+		tmem_register_pamops(&zcache_pamops);
+		ret = register_cpu_notifier(&zcache_cpu_notifier_block);
+		if (ret) {
+			pr_err("ramster: can't register cpu notifier\n");
+			goto out;
+		}
+		for_each_online_cpu(cpu) {
+			void *pcpu = (void *)(long)cpu;
+			zcache_cpu_notifier(&zcache_cpu_notifier_block,
+				CPU_UP_PREPARE, pcpu);
+		}
+	}
+	zcache_objnode_cache = kmem_cache_create("zcache_objnode",
+				sizeof(struct tmem_objnode), 0, 0, NULL);
+	zcache_obj_cache = kmem_cache_create("zcache_obj",
+				sizeof(struct tmem_obj), 0, 0, NULL);
+	ramster_flnode_cache = kmem_cache_create("ramster_flnode",
+				sizeof(struct flushlist_node), 0, 0, NULL);
+#endif
+#ifdef CONFIG_CLEANCACHE
+	pr_info("INIT ramster_enabled=%d use_cleancache=%d\n",
+					ramster_enabled, use_cleancache);
+	if (ramster_enabled && use_cleancache) {
+		struct cleancache_ops old_ops;
+
+		zbud_init();
+		register_shrinker(&zcache_shrinker);
+		old_ops = zcache_cleancache_register_ops();
+		pr_info("ramster: cleancache enabled using kernel "
+			"transcendent memory and compression buddies\n");
+		if (old_ops.init_fs != NULL)
+			pr_warning("ramster: cleancache_ops overridden");
+	}
+#endif
+#ifdef CONFIG_FRONTSWAP
+	pr_info("INIT ramster_enabled=%d use_frontswap=%d\n",
+					ramster_enabled, use_frontswap);
+	if (ramster_enabled && use_frontswap) {
+		struct frontswap_ops old_ops;
+
+		zcache_new_client(LOCAL_CLIENT);
+		old_ops = zcache_frontswap_register_ops();
+		pr_info("ramster: frontswap enabled using kernel "
+			"transcendent memory and xvmalloc\n");
+		if (old_ops.init != NULL)
+			pr_warning("ramster: frontswap_ops overridden");
+	}
+	if (ramster_enabled && (use_frontswap || use_cleancache))
+		ramster_remotify_init();
+#endif
+out:
+	return ret;
+}
+
+module_init(zcache_init)
diff --git a/drivers/staging/ramster/zcache.h b/drivers/staging/ramster/zcache.h
new file mode 100644
index 0000000..250b121
--- /dev/null
+++ b/drivers/staging/ramster/zcache.h
@@ -0,0 +1,22 @@
+/*
+ * zcache.h
+ *
+ * External zcache functions
+ *
+ * Copyright (c) 2009-2012, Dan Magenheimer, Oracle Corp.
+ */
+
+#ifndef _ZCACHE_H_
+#define _ZCACHE_H_
+
+extern int zcache_put(int, int, struct tmem_oid *, uint32_t,
+			char *, size_t, bool, int);
+extern int zcache_autocreate_pool(int, int, bool);
+extern int zcache_get(int, int, struct tmem_oid *, uint32_t,
+			char *, size_t *, bool, int);
+extern int zcache_flush(int, int, struct tmem_oid *, uint32_t);
+extern int zcache_flush_object(int, int, struct tmem_oid *);
+extern int zcache_localify(int, struct tmem_oid *, uint32_t,
+			char *, size_t, void *);
+
+#endif /* _ZCACHE_H */
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 04c2391..24072f7 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -4144,7 +4144,7 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
 		argv[0] = RadioPowerPath;
 		argv[2] = NULL;
 
-		call_usermodehelper(RadioPowerPath, argv, envp, 1);
+		call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
 	}
 }
 
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
index a7fa9aa..f026b71 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
@@ -208,7 +208,7 @@ static void dm_check_ac_dc_power(struct net_device *dev)
 
 	if (priv->rtllib->state != RTLLIB_LINKED)
 		return;
-	call_usermodehelper(ac_dc_check_script_path, argv, envp, 1);
+	call_usermodehelper(ac_dc_check_script_path, argv, envp, UMH_WAIT_PROC);
 
 	return;
 };
@@ -2296,7 +2296,7 @@ void dm_CheckRfCtrlGPIO(void *data)
 
 		argv[0] = RadioPowerPath;
 		argv[2] = NULL;
-		call_usermodehelper(RadioPowerPath, argv, envp, 1);
+		call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
 	}
 }
 
diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
index 6c5061f..13979b5 100644
--- a/drivers/staging/rtl8192e/rtllib_rx.c
+++ b/drivers/staging/rtl8192e/rtllib_rx.c
@@ -2453,7 +2453,7 @@ static inline void update_network(struct rtllib_network *dst,
 	if (src->wmm_param[0].ac_aci_acm_aifsn ||
 	   src->wmm_param[1].ac_aci_acm_aifsn ||
 	   src->wmm_param[2].ac_aci_acm_aifsn ||
-	   src->wmm_param[1].ac_aci_acm_aifsn)
+	   src->wmm_param[3].ac_aci_acm_aifsn)
 		memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
 
 	dst->SignalStrength = src->SignalStrength;
diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c
index 1637f11..c5a15db 100644
--- a/drivers/staging/rtl8192e/rtllib_softmac.c
+++ b/drivers/staging/rtl8192e/rtllib_softmac.c
@@ -2234,7 +2234,6 @@ inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
 
 			if (!network)
 				return 1;
-			memset(network, 0, sizeof(*network));
 			ieee->state = RTLLIB_LINKED;
 			ieee->assoc_id = aid;
 			ieee->softmac_stats.rx_ass_ok++;
@@ -2259,8 +2258,8 @@ inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
 					ieee->handle_assoc_response(ieee->dev,
 						 (struct rtllib_assoc_response_frame *)header,
 						 network);
-				kfree(network);
 			}
+			kfree(network);
 
 			kfree(ieee->assocresp_ies);
 			ieee->assocresp_ies = NULL;
diff --git a/drivers/staging/rtl8192u/ieee80211/cipher.c b/drivers/staging/rtl8192u/ieee80211/cipher.c
index 69dcc31..d47345c 100644
--- a/drivers/staging/rtl8192u/ieee80211/cipher.c
+++ b/drivers/staging/rtl8192u/ieee80211/cipher.c
@@ -71,8 +71,8 @@ static int crypt(struct crypto_tfm *tfm,
 		u8 *src_p, *dst_p;
 		int in_place;
 
-		scatterwalk_map(&walk_in, 0);
-		scatterwalk_map(&walk_out, 1);
+		scatterwalk_map(&walk_in);
+		scatterwalk_map(&walk_out);
 		src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src);
 		dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst);
 		in_place = scatterwalk_samebuf(&walk_in, &walk_out,
@@ -84,10 +84,10 @@ static int crypt(struct crypto_tfm *tfm,
 
 		prfn(tfm, dst_p, src_p, crfn, enc, info, in_place);
 
-		scatterwalk_done(&walk_in, 0, nbytes);
+		scatterwalk_done(&walk_in, nbytes);
 
 		scatterwalk_copychunks(dst_p, &walk_out, bsize, 1);
-		scatterwalk_done(&walk_out, 1, nbytes);
+		scatterwalk_done(&walk_out, nbytes);
 
 		if (!nbytes)
 			return 0;
diff --git a/drivers/staging/rtl8192u/ieee80211/digest.c b/drivers/staging/rtl8192u/ieee80211/digest.c
index 301ed51..05e7497 100644
--- a/drivers/staging/rtl8192u/ieee80211/digest.c
+++ b/drivers/staging/rtl8192u/ieee80211/digest.c
@@ -39,12 +39,12 @@ static void update(struct crypto_tfm *tfm,
 			unsigned int bytes_from_page = min(l, ((unsigned int)
 							   (PAGE_SIZE)) -
 							   offset);
-			char *p = crypto_kmap(pg, 0) + offset;
+			char *p = kmap_atomic(pg) + offset;
 
 			tfm->__crt_alg->cra_digest.dia_update
 					(crypto_tfm_ctx(tfm), p,
 					 bytes_from_page);
-			crypto_kunmap(p, 0);
+			kunmap_atomic(p);
 			crypto_yield(tfm);
 			offset = 0;
 			pg++;
@@ -75,10 +75,10 @@ static void digest(struct crypto_tfm *tfm,
 	tfm->crt_digest.dit_init(tfm);
 
 	for (i = 0; i < nsg; i++) {
-		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
+		char *p = kmap_atomic(sg[i].page) + sg[i].offset;
 		tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
 						      p, sg[i].length);
-		crypto_kunmap(p, 0);
+		kunmap_atomic(p);
 		crypto_yield(tfm);
 	}
 	crypto_digest_final(tfm, out);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
index c9bdc7f..be2a28c 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
@@ -237,7 +237,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 	#ifdef NOT_YET
 	if (ieee->iw_mode == IW_MODE_MASTER) {
-		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
+		printk(KERN_DEBUG "%s: Master mode not yet supported.\n",
 		       ieee->dev->name);
 		return 0;
 /*
diff --git a/drivers/staging/rtl8192u/ieee80211/internal.h b/drivers/staging/rtl8192u/ieee80211/internal.h
index a7c096e..bebe13a 100644
--- a/drivers/staging/rtl8192u/ieee80211/internal.h
+++ b/drivers/staging/rtl8192u/ieee80211/internal.h
@@ -23,23 +23,6 @@
 #include <asm/kmap_types.h>
 
 
-extern enum km_type crypto_km_types[];
-
-static inline enum km_type crypto_kmap_type(int out)
-{
-	return crypto_km_types[(in_softirq() ? 2 : 0) + out];
-}
-
-static inline void *crypto_kmap(struct page *page, int out)
-{
-	return kmap_atomic(page, crypto_kmap_type(out));
-}
-
-static inline void crypto_kunmap(void *vaddr, int out)
-{
-	kunmap_atomic(vaddr, crypto_kmap_type(out));
-}
-
 static inline void crypto_yield(struct crypto_tfm *tfm)
 {
 	if (!in_softirq())
diff --git a/drivers/staging/rtl8192u/ieee80211/kmap_types.h b/drivers/staging/rtl8192u/ieee80211/kmap_types.h
deleted file mode 100644
index de67bb0..0000000
--- a/drivers/staging/rtl8192u/ieee80211/kmap_types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __KMAP_TYPES_H
-
-#define __KMAP_TYPES_H
-
-
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BH_IRQ,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_TYPE_NR
-};
-
-#define _ASM_KMAP_TYPES_H
-
-#endif
diff --git a/drivers/staging/rtl8192u/ieee80211/scatterwalk.c b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
index 3543a61..8b73f6c 100644
--- a/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
+++ b/drivers/staging/rtl8192u/ieee80211/scatterwalk.c
@@ -13,8 +13,6 @@
  * any later version.
  *
  */
-#include "kmap_types.h"
-
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
@@ -23,13 +21,6 @@
 #include "internal.h"
 #include "scatterwalk.h"
 
-enum km_type crypto_km_types[] = {
-	KM_USER0,
-	KM_USER1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-};
-
 void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
 {
 	if (nbytes <= walk->len_this_page &&
@@ -62,9 +53,9 @@ void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
 	walk->offset = sg->offset;
 }
 
-void scatterwalk_map(struct scatter_walk *walk, int out)
+void scatterwalk_map(struct scatter_walk *walk)
 {
-	walk->data = crypto_kmap(walk->page, out) + walk->offset;
+	walk->data = kmap_atomic(walk->page) + walk->offset;
 }
 
 static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
@@ -103,7 +94,7 @@ void scatterwalk_done(struct scatter_walk *walk, int out, int more)
  * has been verified as multiple of the block size.
  */
 int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
-			   size_t nbytes, int out)
+			   size_t nbytes)
 {
 	if (buf != walk->data) {
 		while (nbytes > walk->len_this_page) {
@@ -111,9 +102,9 @@ int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
 			buf += walk->len_this_page;
 			nbytes -= walk->len_this_page;
 
-			crypto_kunmap(walk->data, out);
+			kunmap_atomic(walk->data);
 			scatterwalk_pagedone(walk, out, 1);
-			scatterwalk_map(walk, out);
+			scatterwalk_map(walk);
 		}
 
 		memcpy_dir(buf, walk->data, nbytes, out);
diff --git a/drivers/staging/rtl8712/Kconfig b/drivers/staging/rtl8712/Kconfig
index ea37473..6a43312 100644
--- a/drivers/staging/rtl8712/Kconfig
+++ b/drivers/staging/rtl8712/Kconfig
@@ -9,13 +9,6 @@ config R8712U
 	This option adds the Realtek RTL8712 USB device such as the D-Link DWA-130.
 	If built as a module, it will be called r8712u.
 
-config R8712_AP
-	bool "Realtek RTL8712U AP code"
-	depends on R8712U
-	default N
-	---help---
-	This option allows the Realtek RTL8712 USB device to be an Access Point.
-
 config R8712_TX_AGGR
 	bool "Realtek RTL8712U Transmit Aggregation code"
 	depends on R8712U && BROKEN
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
index ed85b44..e83665d 100644
--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -140,7 +140,6 @@ struct dvobj_priv {
 	u8   ishighspeed;
 	uint(*inirp_init)(struct _adapter *adapter);
 	uint(*inirp_deinit)(struct _adapter *adapter);
-	struct semaphore usb_suspend_sema;
 	struct usb_device *pusbdev;
 };
 
diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c
index 98a3d68..b22fea5 100644
--- a/drivers/staging/rtl8712/os_intfs.c
+++ b/drivers/staging/rtl8712/os_intfs.c
@@ -330,7 +330,6 @@ u8 r8712_init_drv_sw(struct _adapter *padapter)
 	padapter->stapriv.padapter = padapter;
 	r8712_init_bcmc_stainfo(padapter);
 	r8712_init_pwrctrl_priv(padapter);
-	sema_init(&(padapter->pwrctrlpriv.pnp_pwr_mgnt_sema), 0);
 	mp871xinit(padapter);
 	if (init_default_value(padapter) != _SUCCESS)
 		return _FAIL;
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index 1ee943a..9ba6033 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -72,18 +72,6 @@ static inline struct list_head *get_list_head(struct  __queue *queue)
 #define LIST_CONTAINOR(ptr, type, member) \
 	((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member)))
 
-static inline void _enter_hwio_critical(struct semaphore *prwlock,
-					unsigned long *pirqL)
-{
-	down(prwlock);
-}
-
-static inline void _exit_hwio_critical(struct semaphore *prwlock,
-				       unsigned long *pirqL)
-{
-	up(prwlock);
-}
-
 static inline void list_delete(struct list_head *plist)
 {
 	list_del_init(plist);
@@ -152,11 +140,6 @@ static inline u32 _down_sema(struct semaphore *sema)
 		return _SUCCESS;
 }
 
-static inline void _rtl_rwlock_init(struct semaphore *prwlock)
-{
-	sema_init(prwlock, 1);
-}
-
 static inline void _init_listhead(struct list_head *list)
 {
 	INIT_LIST_HEAD(list);
diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c
index 6d69265..fa6dc9c 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.c
+++ b/drivers/staging/rtl8712/rtl8712_recv.c
@@ -55,8 +55,6 @@ int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter)
 	int alignment = 0;
 	struct sk_buff *pskb = NULL;
 
-	sema_init(&precvpriv->recv_sema, 0);
-	sema_init(&precvpriv->terminate_recvthread_sema, 0);
 	/*init recv_buf*/
 	_init_queue(&precvpriv->free_recv_buf_queue);
 	precvpriv->pallocated_recv_buf = _malloc(NR_RECVBUFF *
diff --git a/drivers/staging/rtl8712/rtl871x_io.c b/drivers/staging/rtl8712/rtl871x_io.c
index ca84ee0..abc1c97 100644
--- a/drivers/staging/rtl8712/rtl871x_io.c
+++ b/drivers/staging/rtl8712/rtl871x_io.c
@@ -131,7 +131,6 @@ uint r8712_alloc_io_queue(struct _adapter *adapter)
 	pio_req = (struct io_req *)(pio_queue->free_ioreqs_buf);
 	for (i = 0; i < NUM_IOREQ; i++) {
 		_init_listhead(&pio_req->list);
-		sema_init(&pio_req->sema, 0);
 		list_insert_tail(&pio_req->list, &pio_queue->free_ioreqs);
 		pio_req++;
 	}
diff --git a/drivers/staging/rtl8712/rtl871x_io.h b/drivers/staging/rtl8712/rtl871x_io.h
index 86308a0..d3d8727 100644
--- a/drivers/staging/rtl8712/rtl871x_io.h
+++ b/drivers/staging/rtl8712/rtl871x_io.h
@@ -117,7 +117,6 @@ struct io_req {
 	u32	command;
 	u32	status;
 	u8	*pbuf;
-	struct semaphore sema;
 	void (*_async_io_callback)(struct _adapter *padater,
 				   struct io_req *pio_req, u8 *cnxt);
 	u8 *cnxt;
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.c b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
index 23e72a0..9fd2ec7 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.c
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.c
@@ -100,7 +100,6 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter,
 {
 	struct pwrctrl_priv *pwrpriv = &(padapter->pwrctrlpriv);
 	struct cmd_priv	*pcmdpriv = &(padapter->cmdpriv);
-	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
 
 	if (pwrpriv->cpwm_tog == ((preportpwrstate->state) & 0x80))
 		return;
@@ -110,8 +109,6 @@ void r8712_cpwm_int_hdl(struct _adapter *padapter,
 	if (pwrpriv->cpwm >= PS_STATE_S2) {
 		if (pwrpriv->alives & CMD_ALIVE)
 			up(&(pcmdpriv->cmd_queue_sema));
-		if (pwrpriv->alives & XMIT_ALIVE)
-			up(&(pxmitpriv->xmit_sema));
 	}
 	pwrpriv->cpwm_tog = (preportpwrstate->state) & 0x80;
 	up(&pwrpriv->lock);
@@ -145,12 +142,12 @@ static void SetPSModeWorkItemCallback(struct work_struct *work)
 				       struct pwrctrl_priv, SetPSModeWorkItem);
 	struct _adapter *padapter = container_of(pwrpriv,
 				    struct _adapter, pwrctrlpriv);
-	_enter_pwrlock(&pwrpriv->lock);
 	if (!pwrpriv->bSleep) {
+		_enter_pwrlock(&pwrpriv->lock);
 		if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
 			r8712_set_rpwm(padapter, PS_STATE_S4);
+		up(&pwrpriv->lock);
 	}
-	up(&pwrpriv->lock);
 }
 
 static void rpwm_workitem_callback(struct work_struct *work)
@@ -160,13 +157,13 @@ static void rpwm_workitem_callback(struct work_struct *work)
 	struct _adapter *padapter = container_of(pwrpriv,
 				    struct _adapter, pwrctrlpriv);
 	u8 cpwm = pwrpriv->cpwm;
-	_enter_pwrlock(&pwrpriv->lock);
 	if (pwrpriv->cpwm != pwrpriv->rpwm) {
+		_enter_pwrlock(&pwrpriv->lock);
 		cpwm = r8712_read8(padapter, SDIO_HCPWM);
 		pwrpriv->rpwm_retry = 1;
 		r8712_set_rpwm(padapter, pwrpriv->rpwm);
+		up(&pwrpriv->lock);
 	}
-	up(&pwrpriv->lock);
 }
 
 static void rpwm_check_handler (void *FunctionContext)
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
index b41ca28..6024c4f 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
@@ -133,7 +133,6 @@ struct	pwrctrl_priv {
 	u8	rpwm_retry;
 	uint	bSetPSModeWorkItemInProgress;
 
-	struct semaphore pnp_pwr_mgnt_sema;
 	spinlock_t pnp_pwr_mgnt_lock;
 	s32	pnp_current_pwr_state;
 	u8	pnp_bstop_trx;
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
index 7069f06..5b03b40 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.c
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -93,7 +93,6 @@ sint _r8712_init_recv_priv(struct recv_priv *precvpriv,
 		precvframe++;
 	}
 	precvpriv->rx_pending_cnt = 1;
-	sema_init(&precvpriv->allrxreturnevt, 0);
 	return r8712_init_recv_priv(precvpriv, padapter);
 }
 
diff --git a/drivers/staging/rtl8712/rtl871x_recv.h b/drivers/staging/rtl8712/rtl871x_recv.h
index cc7a72f..e42e6f0 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.h
+++ b/drivers/staging/rtl8712/rtl871x_recv.h
@@ -85,8 +85,6 @@ using enter_critical section to protect
 */
 struct recv_priv {
 	spinlock_t lock;
-	struct semaphore recv_sema;
-	struct semaphore terminate_recvthread_sema;
 	struct  __queue	free_recv_queue;
 	struct  __queue	recv_pending_queue;
 	u8 *pallocated_frame_buf;
@@ -100,7 +98,6 @@ struct recv_priv {
 	uint  rx_largepacket_crcerr;
 	uint  rx_smallpacket_crcerr;
 	uint  rx_middlepacket_crcerr;
-	struct semaphore allrxreturnevt;
 	u8  rx_pending_cnt;
 	uint	ff_hwaddr;
 	struct tasklet_struct recv_tasklet;
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index 81bde80..1247b3d 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -42,10 +42,8 @@ static void _init_stainfo(struct sta_info *psta)
 	_init_listhead(&psta->hash_list);
 	_r8712_init_sta_xmit_priv(&psta->sta_xmitpriv);
 	_r8712_init_sta_recv_priv(&psta->sta_recvpriv);
-#ifdef CONFIG_R8712_AP
 	_init_listhead(&psta->asoc_list);
 	_init_listhead(&psta->auth_list);
-#endif
 }
 
 u32 _r8712_init_sta_priv(struct	sta_priv *pstapriv)
@@ -72,10 +70,8 @@ u32 _r8712_init_sta_priv(struct	sta_priv *pstapriv)
 				 get_list_head(&pstapriv->free_sta_queue));
 		psta++;
 	}
-#ifdef CONFIG_R8712_AP
 	_init_listhead(&pstapriv->asoc_list);
 	_init_listhead(&pstapriv->auth_list);
-#endif
 	return _SUCCESS;
 }
 
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index 8bbdee7..aa57e77 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -71,8 +71,6 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
 
 	memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
 	spin_lock_init(&pxmitpriv->lock);
-	sema_init(&pxmitpriv->xmit_sema, 0);
-	sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
 	/*
 	Please insert all the queue initializaiton using _init_queue below
 	*/
@@ -121,7 +119,6 @@ sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
 	_r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
 	pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
 	pxmitpriv->txirp_cnt = 1;
-	sema_init(&(pxmitpriv->tx_retevt), 0);
 	/*per AC pending irp*/
 	pxmitpriv->beq_cnt = 0;
 	pxmitpriv->bkq_cnt = 0;
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.h b/drivers/staging/rtl8712/rtl871x_xmit.h
index a034c0f..638b79b 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.h
+++ b/drivers/staging/rtl8712/rtl871x_xmit.h
@@ -202,8 +202,6 @@ struct	hw_txqueue {
 
 struct	xmit_priv {
 	spinlock_t lock;
-	struct semaphore xmit_sema;
-	struct semaphore terminate_xmitthread_sema;
 	struct  __queue	be_pending;
 	struct  __queue	bk_pending;
 	struct  __queue	vi_pending;
@@ -233,7 +231,6 @@ struct	xmit_priv {
 	uint	tx_drop;
 	struct hw_xmit *hwxmits;
 	u8	hwxmit_entry;
-	struct semaphore tx_retevt;/*all tx return event;*/
 	u8	txirp_cnt;
 	struct tasklet_struct xmit_tasklet;
 	_workitem xmit_pipe4_reset_wi;
diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h
index 48d6a14..f8016e9 100644
--- a/drivers/staging/rtl8712/sta_info.h
+++ b/drivers/staging/rtl8712/sta_info.h
@@ -90,7 +90,6 @@ struct sta_info {
 	 * curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO
 	 * sta_info: (AP & STA) CAP/INFO
 	 */
-#ifdef CONFIG_R8712_AP
 	struct list_head asoc_list;
 	struct list_head auth_list;
 	unsigned int expire_to;
@@ -98,7 +97,6 @@ struct sta_info {
 	unsigned int authalg;
 	unsigned char chg_txt[128];
 	unsigned int tx_ra_bitmap;
-#endif
 };
 
 struct	sta_priv {
@@ -111,13 +109,11 @@ struct	sta_priv {
 	struct  __queue sleep_q;
 	struct  __queue wakeup_q;
 	struct _adapter *padapter;
-#ifdef CONFIG_R8712_AP
 	struct list_head asoc_list;
 	struct list_head auth_list;
 	unsigned int auth_to;  /* sec, time to expire in authenticating. */
 	unsigned int assoc_to; /* sec, time to expire before associating. */
 	unsigned int expire_to; /* sec , time to expire after associated. */
-#endif
 };
 
 static inline u32 wifi_mac_hash(u8 *mac)
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 9bade18..fe0e2ff 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -281,7 +281,6 @@ static uint r8712_usb_dvobj_init(struct _adapter *padapter)
 	}
 	if ((r8712_alloc_io_queue(padapter)) == _FAIL)
 		status = _FAIL;
-	sema_init(&(padapter->dvobjpriv.usb_suspend_sema), 0);
 	return status;
 }
 
diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h
index f9d46d2..3ce1dc9 100644
--- a/drivers/staging/rts5139/ms.h
+++ b/drivers/staging/rts5139/ms.h
@@ -249,9 +249,9 @@ int ms_delay_write(struct rts51x_chip *chip);
 #ifdef SUPPORT_MAGIC_GATE
 
 int ms_switch_clock(struct rts51x_chip *chip);
-int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 * data,
+int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data,
 		   int data_len);
-int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 * data,
+int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data,
 		  int data_len);
 int ms_set_rw_reg_addr(struct rts51x_chip *chip, u8 read_start, u8 read_cnt,
 		       u8 write_start, u8 write_cnt);
diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c
index adc0d00..b3e0bb2 100644
--- a/drivers/staging/rts5139/rts51x_chip.c
+++ b/drivers/staging/rts5139/rts51x_chip.c
@@ -541,7 +541,7 @@ int rts51x_get_rsp(struct rts51x_chip *chip, int rsp_len, int timeout)
 	return STATUS_SUCCESS;
 }
 
-int rts51x_get_card_status(struct rts51x_chip *chip, u16 * status)
+int rts51x_get_card_status(struct rts51x_chip *chip, u16 *status)
 {
 	int retval;
 	u16 val;
@@ -577,7 +577,7 @@ int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data)
 	return STATUS_SUCCESS;
 }
 
-int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 * data)
+int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 *data)
 {
 	int retval;
 
@@ -620,7 +620,7 @@ int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask,
 	return STATUS_SUCCESS;
 }
 
-int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 * data)
+int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 *data)
 {
 	int retval;
 	u16 value = 0;
@@ -720,7 +720,7 @@ int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len,
 	return STATUS_SUCCESS;
 }
 
-int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len)
+int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len)
 {
 	int retval;
 
@@ -735,7 +735,7 @@ int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len)
 	return STATUS_SUCCESS;
 }
 
-int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len)
+int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len)
 {
 	int retval;
 
@@ -776,7 +776,7 @@ int rts51x_write_phy_register(struct rts51x_chip *chip, u8 addr, u8 val)
 	return STATUS_SUCCESS;
 }
 
-int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 * val)
+int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 *val)
 {
 	int retval;
 
@@ -921,7 +921,7 @@ void rts51x_trace_msg(struct rts51x_chip *chip, unsigned char *buf, int clear)
 }
 #endif
 
-void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 * status,
+void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status,
 		      u8 status_len)
 {
 	struct sd_info *sd_card = &(chip->sd_card);
diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h
index 321ece7..13fc2a4 100644
--- a/drivers/staging/rts5139/rts51x_chip.h
+++ b/drivers/staging/rts5139/rts51x_chip.h
@@ -857,12 +857,12 @@ static inline u8 *rts51x_get_rsp_data(struct rts51x_chip *chip)
 	return chip->rsp_buf;
 }
 
-int rts51x_get_card_status(struct rts51x_chip *chip, u16 * status);
+int rts51x_get_card_status(struct rts51x_chip *chip, u16 *status);
 int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data);
-int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 * data);
+int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 *data);
 int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask,
 			      u8 data);
-int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 * data);
+int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 *data);
 int rts51x_seq_write_register(struct rts51x_chip *chip, u16 addr, u16 len,
 			      u8 *data);
 int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len,
diff --git a/drivers/staging/rts5139/rts51x_fop.h b/drivers/staging/rts5139/rts51x_fop.h
index 0453f57..94d75f0 100644
--- a/drivers/staging/rts5139/rts51x_fop.h
+++ b/drivers/staging/rts5139/rts51x_fop.h
@@ -48,7 +48,7 @@ int rts51x_open(struct inode *inode, struct file *filp);
 int rts51x_release(struct inode *inode, struct file *filp);
 ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count,
 		    loff_t *f_pos);
-ssize_t rts51x_write(struct file *filp, const char __user * buf, size_t count,
+ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count,
 		     loff_t *f_pos);
 #if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */
 int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c
index e11467a..da9c83b 100644
--- a/drivers/staging/rts5139/rts51x_transport.c
+++ b/drivers/staging/rts5139/rts51x_transport.c
@@ -883,7 +883,7 @@ int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe,
 	return result;
 }
 
-int rts51x_get_epc_status(struct rts51x_chip *chip, u16 * status)
+int rts51x_get_epc_status(struct rts51x_chip *chip, u16 *status)
 {
 	unsigned int pipe = RCV_INTR_PIPE(chip);
 	struct usb_host_endpoint *ep;
diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h
index 8464c48..9dd556e 100644
--- a/drivers/staging/rts5139/rts51x_transport.h
+++ b/drivers/staging/rts5139/rts51x_transport.h
@@ -73,7 +73,7 @@ int rts51x_start_epc_transfer(struct rts51x_chip *chip);
 void rts51x_cancel_epc_transfer(struct rts51x_chip *chip);
 #endif
 
-int rts51x_get_epc_status(struct rts51x_chip *chip, u16 * status);
+int rts51x_get_epc_status(struct rts51x_chip *chip, u16 *status);
 void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip);
 
 #endif /* __RTS51X_TRANSPORT_H */
diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c
index 407cd43..d5969d9 100644
--- a/drivers/staging/rts5139/sd_cprm.c
+++ b/drivers/staging/rts5139/sd_cprm.c
@@ -233,7 +233,7 @@ RTY_SEND_CMD:
 	return STATUS_SUCCESS;
 }
 
-int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 * rsp, u8 rsp_type)
+int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 *rsp, u8 rsp_type)
 {
 	int retval, rsp_len;
 	u16 reg_addr;
diff --git a/drivers/staging/sbe-2t3e3/intr.c b/drivers/staging/sbe-2t3e3/intr.c
index 7ad1a83..1336aab 100644
--- a/drivers/staging/sbe-2t3e3/intr.c
+++ b/drivers/staging/sbe-2t3e3/intr.c
@@ -188,7 +188,7 @@ void dc_intr_rx(struct channel *sc)
 			}
 
 			if (sc->s.LOS) {
-				error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT ||
+				error_mask &= ~(SBE_2T3E3_RX_DESC_DRIBBLING_BIT |
 						SBE_2T3E3_RX_DESC_MII_ERROR);
 			}
 
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig
index 92bf166..185b676 100644
--- a/drivers/staging/sep/Kconfig
+++ b/drivers/staging/sep/Kconfig
@@ -3,7 +3,8 @@ config DX_SEP
 	depends on PCI
 	help
 	  Discretix SEP driver; used for the security processor subsystem
-	  on bard the Intel Mobile Internet Device.
+	  on board the Intel Mobile Internet Device and adds SEP availability
+	  to the kernel crypto infrastructure
 
 	  The driver's name is sep_driver.
 
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile
index 628d5f9..e48a795 100644
--- a/drivers/staging/sep/Makefile
+++ b/drivers/staging/sep/Makefile
@@ -1,2 +1,3 @@
-obj-$(CONFIG_DX_SEP) := sep_driver.o
-
+ccflags-y += -I$(srctree)/$(src)
+obj-$(CONFIG_DX_SEP) += sep_driver.o
+sep_driver-objs := sep_crypto.o sep_main.o
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO
index 8f3b878..3524d0c 100644
--- a/drivers/staging/sep/TODO
+++ b/drivers/staging/sep/TODO
@@ -1,4 +1,3 @@
 Todo's so far (from Alan Cox)
-- Check whether it can be plugged into any of the kernel crypto API
-  interfaces - Crypto API 'glue' is still not ready to submit
-- Clean up un-needed debug prints - Started to work on this
+- Clean up unused ioctls
+- Clean up unused fields in ioctl structures
diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c
new file mode 100644
index 0000000..1cc790e
--- /dev/null
+++ b/drivers/staging/sep/sep_crypto.c
@@ -0,0 +1,4058 @@
+/*
+ *
+ *  sep_crypto.c - Crypto interface structures
+ *
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2010 Discretix. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with
+ *  this program; if not, write to the Free Software Foundation, Inc., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *  Jayant Mangalampalli jayant.mangalampalli@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *  2010.09.14  Upgrade to Medfield
+ *  2011.02.22  Enable Kernel Crypto
+ *
+ */
+
+/* #define DEBUG */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/kdev_t.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/pci.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/list.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+#include <linux/crypto.h>
+#include <crypto/internal/hash.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/sha.h>
+#include <crypto/md5.h>
+#include <crypto/aes.h>
+#include <crypto/des.h>
+#include <crypto/hash.h>
+#include "sep_driver_hw_defs.h"
+#include "sep_driver_config.h"
+#include "sep_driver_api.h"
+#include "sep_dev.h"
+#include "sep_crypto.h"
+
+#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE)
+
+/* Globals for queuing */
+static spinlock_t queue_lock;
+static struct crypto_queue sep_queue;
+
+/* Declare of dequeuer */
+static void sep_dequeuer(void *data);
+
+/* TESTING */
+/**
+ * crypto_sep_dump_message - dump the message that is pending
+ * @sep: SEP device
+ * This will only print dump if DEBUG is set; it does
+ * follow kernel debug print enabling
+ */
+static void crypto_sep_dump_message(struct sep_device *sep, void *msg)
+{
+#if 0
+	u32 *p;
+	u32 *i;
+	int count;
+
+	p = sep->shared_addr;
+	i = (u32 *)msg;
+	for (count = 0; count < 10 * 4; count += 4)
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] Word %d of the message is %x (local)%x\n",
+				current->pid, count/4, *p++, *i++);
+#endif
+}
+
+/**
+ *	sep_do_callback
+ *	@work: pointer to work_struct
+ *	This is what is called by the queue; it is generic so that it
+ *	can be used by any type of operation as each different callback
+ *	function can use the data parameter in its own way
+ */
+static void sep_do_callback(struct work_struct *work)
+{
+	struct sep_work_struct *sep_work = container_of(work,
+		struct sep_work_struct, work);
+	if (sep_work != NULL) {
+		(sep_work->callback)(sep_work->data);
+		kfree(sep_work);
+	} else {
+		pr_debug("sep crypto: do callback - NULL container\n");
+	}
+}
+
+/**
+ *	sep_submit_work
+ *	@work_queue: pointer to struct_workqueue
+ *	@funct: pointer to function to execute
+ *	@data: pointer to data; function will know
+ *		how to use it
+ *	This is a generic API to submit something to
+ *	the queue. The callback function will depend
+ *	on what operation is to be done
+ */
+static int sep_submit_work(struct workqueue_struct *work_queue,
+	void(*funct)(void *),
+	void *data)
+{
+	struct sep_work_struct *sep_work;
+	int result;
+
+	sep_work = kmalloc(sizeof(struct sep_work_struct), GFP_ATOMIC);
+
+	if (sep_work == NULL) {
+		pr_debug("sep crypto: cant allocate work structure\n");
+		return -ENOMEM;
+	}
+
+	sep_work->callback = funct;
+	sep_work->data = data;
+	INIT_WORK(&sep_work->work, sep_do_callback);
+	result = queue_work(work_queue, &sep_work->work);
+	if (!result) {
+		pr_debug("sep_crypto: queue_work failed\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ *	sep_alloc_sg_buf -
+ *	@sep: pointer to struct sep_device
+ *	@size: total size of area
+ *	@block_size: minimum size of chunks
+ *	each page is minimum or modulo this size
+ *	@returns: pointer to struct scatterlist for new
+ *	buffer
+ **/
+static struct scatterlist *sep_alloc_sg_buf(
+	struct sep_device *sep,
+	size_t size,
+	size_t block_size)
+{
+	u32 nbr_pages;
+	u32 ct1;
+	void *buf;
+	size_t current_size;
+	size_t real_page_size;
+
+	struct scatterlist *sg, *sg_temp;
+
+	if (size == 0)
+		return NULL;
+
+	dev_dbg(&sep->pdev->dev, "sep alloc sg buf\n");
+
+	current_size = 0;
+	nbr_pages = 0;
+	real_page_size = PAGE_SIZE - (PAGE_SIZE % block_size);
+	/**
+	 * The size of each page must be modulo of the operation
+	 * block size; increment by the modified page size until
+	 * the total size is reached, then you have the number of
+	 * pages
+	 */
+	while (current_size < size) {
+		current_size += real_page_size;
+		nbr_pages += 1;
+	}
+
+	sg = kmalloc((sizeof(struct scatterlist) * nbr_pages), GFP_ATOMIC);
+	if (!sg) {
+		dev_warn(&sep->pdev->dev, "Cannot allocate page for new sg\n");
+		return NULL;
+	}
+
+	sg_init_table(sg, nbr_pages);
+
+	current_size = 0;
+	sg_temp = sg;
+	for (ct1 = 0; ct1 < nbr_pages; ct1 += 1) {
+		buf = (void *)get_zeroed_page(GFP_ATOMIC);
+		if (!buf) {
+			dev_warn(&sep->pdev->dev,
+				"Cannot allocate page for new buffer\n");
+			kfree(sg);
+			return NULL;
+		}
+
+		sg_set_buf(sg_temp, buf, real_page_size);
+		if ((size - current_size) > real_page_size) {
+			sg_temp->length = real_page_size;
+			current_size += real_page_size;
+		} else {
+			sg_temp->length = (size - current_size);
+			current_size = size;
+		}
+		sg_temp = sg_next(sg);
+	}
+	return sg;
+}
+
+/**
+ *	sep_free_sg_buf -
+ *	@sg: pointer to struct scatterlist; points to area to free
+ */
+static void sep_free_sg_buf(struct scatterlist *sg)
+{
+	struct scatterlist *sg_temp = sg;
+		while (sg_temp) {
+			free_page((unsigned long)sg_virt(sg_temp));
+			sg_temp = sg_next(sg_temp);
+		}
+		kfree(sg);
+}
+
+/**
+ *	sep_copy_sg -
+ *	@sep: pointer to struct sep_device
+ *	@sg_src: pointer to struct scatterlist for source
+ *	@sg_dst: pointer to struct scatterlist for destination
+ *      @size: size (in bytes) of data to copy
+ *
+ *	Copy data from one scatterlist to another; both must
+ *	be the same size
+ */
+static void sep_copy_sg(
+	struct sep_device *sep,
+	struct scatterlist *sg_src,
+	struct scatterlist *sg_dst,
+	size_t size)
+{
+	u32 seg_size;
+	u32 in_offset, out_offset;
+
+	u32 count = 0;
+	struct scatterlist *sg_src_tmp = sg_src;
+	struct scatterlist *sg_dst_tmp = sg_dst;
+	in_offset = 0;
+	out_offset = 0;
+
+	dev_dbg(&sep->pdev->dev, "sep copy sg\n");
+
+	if ((sg_src == NULL) || (sg_dst == NULL) || (size == 0))
+		return;
+
+	dev_dbg(&sep->pdev->dev, "sep copy sg not null\n");
+
+	while (count < size) {
+		if ((sg_src_tmp->length - in_offset) >
+			(sg_dst_tmp->length - out_offset))
+			seg_size = sg_dst_tmp->length - out_offset;
+		else
+			seg_size = sg_src_tmp->length - in_offset;
+
+		if (seg_size > (size - count))
+			seg_size = (size = count);
+
+		memcpy(sg_virt(sg_dst_tmp) + out_offset,
+			sg_virt(sg_src_tmp) + in_offset,
+			seg_size);
+
+		in_offset += seg_size;
+		out_offset += seg_size;
+		count += seg_size;
+
+		if (in_offset >= sg_src_tmp->length) {
+			sg_src_tmp = sg_next(sg_src_tmp);
+			in_offset = 0;
+		}
+
+		if (out_offset >= sg_dst_tmp->length) {
+			sg_dst_tmp = sg_next(sg_dst_tmp);
+			out_offset = 0;
+		}
+	}
+}
+
+/**
+ *	sep_oddball_pages -
+ *	@sep: pointer to struct sep_device
+ *	@sg: pointer to struct scatterlist - buffer to check
+ *	@size: total data size
+ *	@blocksize: minimum block size; must be multiples of this size
+ *	@to_copy: 1 means do copy, 0 means do not copy
+ *	@new_sg: pointer to location to put pointer to new sg area
+ *	@returns: 1 if new scatterlist is needed; 0 if not needed;
+ *		error value if operation failed
+ *
+ *	The SEP device requires all pages to be multiples of the
+ *	minimum block size appropriate for the operation
+ *	This function check all pages; if any are oddball sizes
+ *	(not multiple of block sizes), it creates a new scatterlist.
+ *	If the to_copy parameter is set to 1, then a scatter list
+ *	copy is performed. The pointer to the new scatterlist is
+ *	put into the address supplied by the new_sg parameter; if
+ *	no new scatterlist is needed, then a NULL is put into
+ *	the location at new_sg.
+ *
+ */
+static int sep_oddball_pages(
+	struct sep_device *sep,
+	struct scatterlist *sg,
+	size_t data_size,
+	u32 block_size,
+	struct scatterlist **new_sg,
+	u32 do_copy)
+{
+	struct scatterlist *sg_temp;
+	u32 flag;
+	u32 nbr_pages, page_count;
+
+	dev_dbg(&sep->pdev->dev, "sep oddball\n");
+	if ((sg == NULL) || (data_size == 0) || (data_size < block_size))
+		return 0;
+
+	dev_dbg(&sep->pdev->dev, "sep oddball not null\n");
+	flag = 0;
+	nbr_pages = 0;
+	page_count = 0;
+	sg_temp = sg;
+
+	while (sg_temp) {
+		nbr_pages += 1;
+		sg_temp = sg_next(sg_temp);
+	}
+
+	sg_temp = sg;
+	while ((sg_temp) && (flag == 0)) {
+		page_count += 1;
+		if (sg_temp->length % block_size)
+			flag = 1;
+		else
+			sg_temp = sg_next(sg_temp);
+	}
+
+	/* Do not process if last (or only) page is oddball */
+	if (nbr_pages == page_count)
+		flag = 0;
+
+	if (flag) {
+		dev_dbg(&sep->pdev->dev, "sep oddball processing\n");
+		*new_sg = sep_alloc_sg_buf(sep, data_size, block_size);
+		if (*new_sg == NULL) {
+			dev_warn(&sep->pdev->dev, "cannot allocate new sg\n");
+			return -ENOMEM;
+		}
+
+		if (do_copy)
+			sep_copy_sg(sep, sg, *new_sg, data_size);
+
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/**
+ *	sep_copy_offset_sg -
+ *	@sep: pointer to struct sep_device;
+ *	@sg: pointer to struct scatterlist
+ *	@offset: offset into scatterlist memory
+ *	@dst: place to put data
+ *	@len: length of data
+ *	@returns: number of bytes copies
+ *
+ *	This copies data from scatterlist buffer
+ *	offset from beginning - it is needed for
+ *	handling tail data in hash
+ */
+static size_t sep_copy_offset_sg(
+	struct sep_device *sep,
+	struct scatterlist *sg,
+	u32 offset,
+	void *dst,
+	u32 len)
+{
+	size_t page_start;
+	size_t page_end;
+	size_t offset_within_page;
+	size_t length_within_page;
+	size_t length_remaining;
+	size_t current_offset;
+
+	/* Find which page is beginning of segment */
+	page_start = 0;
+	page_end = sg->length;
+	while ((sg) && (offset > page_end)) {
+		page_start += sg->length;
+		sg = sg_next(sg);
+		if (sg)
+			page_end += sg->length;
+	}
+
+	if (sg == NULL)
+		return -ENOMEM;
+
+	offset_within_page = offset - page_start;
+	if ((sg->length - offset_within_page) >= len) {
+		/* All within this page */
+		memcpy(dst, sg_virt(sg) + offset_within_page, len);
+		return len;
+	} else {
+		/* Scattered multiple pages */
+		current_offset = 0;
+		length_remaining = len;
+		while ((sg) && (current_offset < len)) {
+			length_within_page = sg->length - offset_within_page;
+			if (length_within_page >= length_remaining) {
+				memcpy(dst+current_offset,
+					sg_virt(sg) + offset_within_page,
+					length_remaining);
+				length_remaining = 0;
+				current_offset = len;
+			} else {
+				memcpy(dst+current_offset,
+					sg_virt(sg) + offset_within_page,
+					length_within_page);
+				length_remaining -= length_within_page;
+				current_offset += length_within_page;
+				offset_within_page = 0;
+				sg = sg_next(sg);
+			}
+		}
+
+		if (sg == NULL)
+			return -ENOMEM;
+	}
+	return len;
+}
+
+/**
+ *	partial_overlap -
+ *	@src_ptr: source pointer
+ *	@dst_ptr: destination pointer
+ *	@nbytes: number of bytes
+ *	@returns: 0 for success; -1 for failure
+ *	We cannot have any partial overlap. Total overlap
+ *	where src is the same as dst is okay
+ */
+static int partial_overlap(void *src_ptr, void *dst_ptr, u32 nbytes)
+{
+	/* Check for partial overlap */
+	if (src_ptr != dst_ptr) {
+		if (src_ptr < dst_ptr) {
+			if ((src_ptr + nbytes) > dst_ptr)
+				return -EINVAL;
+		} else {
+			if ((dst_ptr + nbytes) > src_ptr)
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/* Debug - prints only if DEBUG is defined; follows kernel debug model */
+static void sep_dump(struct sep_device *sep, char *stg, void *start, int len)
+{
+#if 0
+	int ct1;
+	u8 *ptt;
+
+	dev_dbg(&sep->pdev->dev,
+		"Dump of %s starting at %08lx for %08x bytes\n",
+		stg, (unsigned long)start, len);
+	for (ct1 = 0; ct1 < len; ct1 += 1) {
+		ptt = (u8 *)(start + ct1);
+		dev_dbg(&sep->pdev->dev, "%02x ", *ptt);
+		if (ct1 % 16 == 15)
+			dev_dbg(&sep->pdev->dev, "\n");
+	}
+	dev_dbg(&sep->pdev->dev, "\n");
+#endif
+}
+
+/* Debug - prints only if DEBUG is defined; follows kernel debug model */
+static void sep_dump_sg(struct sep_device *sep, char *stg,
+			struct scatterlist *sg)
+{
+#if 0
+	int ct1, ct2;
+	u8 *ptt;
+
+	dev_dbg(&sep->pdev->dev, "Dump of scatterlist %s\n", stg);
+
+	ct1 = 0;
+	while (sg) {
+		dev_dbg(&sep->pdev->dev, "page %x\n size %x", ct1,
+			sg->length);
+		dev_dbg(&sep->pdev->dev, "phys addr is %lx",
+			(unsigned long)sg_phys(sg));
+		ptt = sg_virt(sg);
+		for (ct2 = 0; ct2 < sg->length; ct2 += 1) {
+			dev_dbg(&sep->pdev->dev, "byte %x is %02x\n",
+				ct2, (unsigned char)*(ptt + ct2));
+		}
+
+		ct1 += 1;
+		sg = sg_next(sg);
+	}
+	dev_dbg(&sep->pdev->dev, "\n");
+#endif
+}
+
+/* Debug - prints only if DEBUG is defined */
+static void sep_dump_ivs(struct ablkcipher_request *req, char *reason)
+
+	{
+	unsigned char *cptr;
+	struct sep_aes_internal_context *aes_internal;
+	struct sep_des_internal_context *des_internal;
+	int ct1;
+
+	struct this_task_ctx *ta_ctx;
+	struct crypto_ablkcipher *tfm;
+	struct sep_system_ctx *sctx;
+
+	ta_ctx = ablkcipher_request_ctx(req);
+	tfm = crypto_ablkcipher_reqtfm(req);
+	sctx = crypto_ablkcipher_ctx(tfm);
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "IV DUMP - %s\n", reason);
+	if ((ta_ctx->current_request == DES_CBC) &&
+		(ta_ctx->des_opmode == SEP_DES_CBC)) {
+
+		des_internal = (struct sep_des_internal_context *)
+			sctx->des_private_ctx.ctx_buf;
+		/* print vendor */
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"sep - vendor iv for DES\n");
+		cptr = (unsigned char *)des_internal->iv_context;
+		for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"%02x\n", *(cptr + ct1));
+
+		/* print walk */
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"sep - walk from kernel crypto iv for DES\n");
+		cptr = (unsigned char *)ta_ctx->walk.iv;
+		for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"%02x\n", *(cptr + ct1));
+	} else if ((ta_ctx->current_request == AES_CBC) &&
+		(ta_ctx->aes_opmode == SEP_AES_CBC)) {
+
+		aes_internal = (struct sep_aes_internal_context *)
+			sctx->aes_private_ctx.cbuff;
+		/* print vendor */
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"sep - vendor iv for AES\n");
+		cptr = (unsigned char *)aes_internal->aes_ctx_iv;
+		for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"%02x\n", *(cptr + ct1));
+
+		/* print walk */
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"sep - walk from kernel crypto iv for AES\n");
+		cptr = (unsigned char *)ta_ctx->walk.iv;
+		for (ct1 = 0; ct1 < crypto_ablkcipher_ivsize(tfm); ct1 += 1)
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"%02x\n", *(cptr + ct1));
+	}
+}
+
+/**
+ * RFC2451: Weak key check
+ * Returns: 1 (weak), 0 (not weak)
+ */
+static int sep_weak_key(const u8 *key, unsigned int keylen)
+{
+	static const u8 parity[] = {
+	8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8,
+	0, 8, 8, 0, 8, 0, 0, 8, 8,
+	0, 0, 8, 0, 8, 8, 3,
+	0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
+	8, 0, 0, 8, 0, 8, 8, 0, 0,
+	8, 8, 0, 8, 0, 0, 8,
+	0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
+	8, 0, 0, 8, 0, 8, 8, 0, 0,
+	8, 8, 0, 8, 0, 0, 8,
+	8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
+	0, 8, 8, 0, 8, 0, 0, 8, 8,
+	0, 0, 8, 0, 8, 8, 0,
+	0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
+	8, 0, 0, 8, 0, 8, 8, 0, 0,
+	8, 8, 0, 8, 0, 0, 8,
+	8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
+	0, 8, 8, 0, 8, 0, 0, 8, 8,
+	0, 0, 8, 0, 8, 8, 0,
+	8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8,
+	0, 8, 8, 0, 8, 0, 0, 8, 8,
+	0, 0, 8, 0, 8, 8, 0,
+	4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0,
+	8, 5, 0, 8, 0, 8, 8, 0, 0,
+	8, 8, 0, 8, 0, 6, 8,
+	};
+
+	u32 n, w;
+
+	n  = parity[key[0]]; n <<= 4;
+	n |= parity[key[1]]; n <<= 4;
+	n |= parity[key[2]]; n <<= 4;
+	n |= parity[key[3]]; n <<= 4;
+	n |= parity[key[4]]; n <<= 4;
+	n |= parity[key[5]]; n <<= 4;
+	n |= parity[key[6]]; n <<= 4;
+	n |= parity[key[7]];
+	w = 0x88888888L;
+
+	/* 1 in 10^10 keys passes this test */
+	if (!((n - (w >> 3)) & w)) {
+		if (n < 0x41415151) {
+			if (n < 0x31312121) {
+				if (n < 0x14141515) {
+					/* 01 01 01 01 01 01 01 01 */
+					if (n == 0x11111111)
+						goto weak;
+					/* 01 1F 01 1F 01 0E 01 0E */
+					if (n == 0x13131212)
+						goto weak;
+				} else {
+					/* 01 E0 01 E0 01 F1 01 F1 */
+					if (n == 0x14141515)
+						goto weak;
+					/* 01 FE 01 FE 01 FE 01 FE */
+					if (n == 0x16161616)
+						goto weak;
+				}
+			} else {
+				if (n < 0x34342525) {
+					/* 1F 01 1F 01 0E 01 0E 01 */
+					if (n == 0x31312121)
+						goto weak;
+					/* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
+					if (n == 0x33332222)
+						goto weak;
+				} else {
+					/* 1F E0 1F E0 0E F1 0E F1 */
+					if (n == 0x34342525)
+						goto weak;
+					/* 1F FE 1F FE 0E FE 0E FE */
+					if (n == 0x36362626)
+						goto weak;
+				}
+			}
+		} else {
+			if (n < 0x61616161) {
+				if (n < 0x44445555) {
+					/* E0 01 E0 01 F1 01 F1 01 */
+					if (n == 0x41415151)
+						goto weak;
+					/* E0 1F E0 1F F1 0E F1 0E */
+					if (n == 0x43435252)
+						goto weak;
+				} else {
+					/* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
+					if (n == 0x44445555)
+						goto weak;
+					/* E0 FE E0 FE F1 FE F1 FE */
+					if (n == 0x46465656)
+						goto weak;
+				}
+			} else {
+				if (n < 0x64646565) {
+					/* FE 01 FE 01 FE 01 FE 01 */
+					if (n == 0x61616161)
+						goto weak;
+					/* FE 1F FE 1F FE 0E FE 0E */
+					if (n == 0x63636262)
+						goto weak;
+				} else {
+					/* FE E0 FE E0 FE F1 FE F1 */
+					if (n == 0x64646565)
+						goto weak;
+					/* FE FE FE FE FE FE FE FE */
+					if (n == 0x66666666)
+						goto weak;
+				}
+			}
+		}
+	}
+	return 0;
+weak:
+	return 1;
+}
+/**
+ *	sep_sg_nents
+ */
+static u32 sep_sg_nents(struct scatterlist *sg)
+{
+	u32 ct1 = 0;
+	while (sg) {
+		ct1 += 1;
+		sg = sg_next(sg);
+	}
+
+	return ct1;
+}
+
+/**
+ *	sep_start_msg -
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@returns: offset to place for the next word in the message
+ *	Set up pointer in message pool for new message
+ */
+static u32 sep_start_msg(struct this_task_ctx *ta_ctx)
+{
+	u32 *word_ptr;
+	ta_ctx->msg_len_words = 2;
+	ta_ctx->msgptr = ta_ctx->msg;
+	memset(ta_ctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+	ta_ctx->msgptr += sizeof(u32) * 2;
+	word_ptr = (u32 *)ta_ctx->msgptr;
+	*word_ptr = SEP_START_MSG_TOKEN;
+	return sizeof(u32) * 2;
+}
+
+/**
+ *	sep_end_msg -
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@messages_offset: current message offset
+ *	Returns: 0 for success; <0 otherwise
+ *	End message; set length and CRC; and
+ *	send interrupt to the SEP
+ */
+static void sep_end_msg(struct this_task_ctx *ta_ctx, u32 msg_offset)
+{
+	u32 *word_ptr;
+	/* Msg size goes into msg after token */
+	ta_ctx->msg_len_words = msg_offset / sizeof(u32) + 1;
+	word_ptr = (u32 *)ta_ctx->msgptr;
+	word_ptr += 1;
+	*word_ptr = ta_ctx->msg_len_words;
+
+	/* CRC (currently 0) goes at end of msg */
+	word_ptr = (u32 *)(ta_ctx->msgptr + msg_offset);
+	*word_ptr = 0;
+}
+
+/**
+ *	sep_start_inbound_msg -
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@msg_offset: offset to place for the next word in the message
+ *	@returns: 0 for success; error value for failure
+ *	Set up pointer in message pool for inbound message
+ */
+static u32 sep_start_inbound_msg(struct this_task_ctx *ta_ctx, u32 *msg_offset)
+{
+	u32 *word_ptr;
+	u32 token;
+	u32 error = SEP_OK;
+
+	*msg_offset = sizeof(u32) * 2;
+	word_ptr = (u32 *)ta_ctx->msgptr;
+	token = *word_ptr;
+	ta_ctx->msg_len_words = *(word_ptr + 1);
+
+	if (token != SEP_START_MSG_TOKEN) {
+		error = SEP_INVALID_START;
+		goto end_function;
+	}
+
+end_function:
+
+	return error;
+}
+
+/**
+ *	sep_write_msg -
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@in_addr: pointer to start of parameter
+ *	@size: size of parameter to copy (in bytes)
+ *	@max_size: size to move up offset; SEP mesg is in word sizes
+ *	@msg_offset: pointer to current offset (is updated)
+ *	@byte_array: flag ti indicate wheter endian must be changed
+ *	Copies data into the message area from caller
+ */
+static void sep_write_msg(struct this_task_ctx *ta_ctx, void *in_addr,
+	u32 size, u32 max_size, u32 *msg_offset, u32 byte_array)
+{
+	u32 *word_ptr;
+	void *void_ptr;
+	void_ptr = ta_ctx->msgptr + *msg_offset;
+	word_ptr = (u32 *)void_ptr;
+	memcpy(void_ptr, in_addr, size);
+	*msg_offset += max_size;
+
+	/* Do we need to manipulate endian? */
+	if (byte_array) {
+		u32 i;
+		for (i = 0; i < ((size + 3) / 4); i += 1)
+			*(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i));
+	}
+}
+
+/**
+ *	sep_make_header
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@msg_offset: pointer to current offset (is updated)
+ *	@op_code: op code to put into message
+ *	Puts op code into message and updates offset
+ */
+static void sep_make_header(struct this_task_ctx *ta_ctx, u32 *msg_offset,
+			    u32 op_code)
+{
+	u32 *word_ptr;
+
+	*msg_offset = sep_start_msg(ta_ctx);
+	word_ptr = (u32 *)(ta_ctx->msgptr + *msg_offset);
+	*word_ptr = op_code;
+	*msg_offset += sizeof(u32);
+}
+
+
+
+/**
+ *	sep_read_msg -
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@in_addr: pointer to start of parameter
+ *	@size: size of parameter to copy (in bytes)
+ *	@max_size: size to move up offset; SEP mesg is in word sizes
+ *	@msg_offset: pointer to current offset (is updated)
+ *	@byte_array: flag ti indicate wheter endian must be changed
+ *	Copies data out of the message area to caller
+ */
+static void sep_read_msg(struct this_task_ctx *ta_ctx, void *in_addr,
+	u32 size, u32 max_size, u32 *msg_offset, u32 byte_array)
+{
+	u32 *word_ptr;
+	void *void_ptr;
+	void_ptr = ta_ctx->msgptr + *msg_offset;
+	word_ptr = (u32 *)void_ptr;
+
+	/* Do we need to manipulate endian? */
+	if (byte_array) {
+		u32 i;
+		for (i = 0; i < ((size + 3) / 4); i += 1)
+			*(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i));
+	}
+
+	memcpy(in_addr, void_ptr, size);
+	*msg_offset += max_size;
+}
+
+/**
+ *	sep_verify_op -
+ *	@ta_ctx: pointer to struct this_task_ctx
+ *	@op_code: expected op_code
+ *      @msg_offset: pointer to current offset (is updated)
+ *	@returns: 0 for success; error for failure
+ */
+static u32 sep_verify_op(struct this_task_ctx *ta_ctx, u32 op_code,
+			 u32 *msg_offset)
+{
+	u32 error;
+	u32 in_ary[2];
+
+	struct sep_device *sep = ta_ctx->sep_used;
+
+	dev_dbg(&sep->pdev->dev, "dumping return message\n");
+	error = sep_start_inbound_msg(ta_ctx, msg_offset);
+	if (error) {
+		dev_warn(&sep->pdev->dev,
+			"sep_start_inbound_msg error\n");
+		return error;
+	}
+
+	sep_read_msg(ta_ctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2,
+		msg_offset, 0);
+
+	if (in_ary[0] != op_code) {
+		dev_warn(&sep->pdev->dev,
+			"sep got back wrong opcode\n");
+		dev_warn(&sep->pdev->dev,
+			"got back %x; expected %x\n",
+			in_ary[0], op_code);
+		return SEP_WRONG_OPCODE;
+	}
+
+	if (in_ary[1] != SEP_OK) {
+		dev_warn(&sep->pdev->dev,
+			"sep execution error\n");
+		dev_warn(&sep->pdev->dev,
+			"got back %x; expected %x\n",
+			in_ary[1], SEP_OK);
+		return in_ary[0];
+	}
+
+return 0;
+}
+
+/**
+ * sep_read_context -
+ * @ta_ctx: pointer to struct this_task_ctx
+ * @msg_offset: point to current place in SEP msg; is updated
+ * @dst: pointer to place to put the context
+ * @len: size of the context structure (differs for crypro/hash)
+ * This function reads the context from the msg area
+ * There is a special way the vendor needs to have the maximum
+ * length calculated so that the msg_offset is updated properly;
+ * it skips over some words in the msg area depending on the size
+ * of the context
+ */
+static void sep_read_context(struct this_task_ctx *ta_ctx, u32 *msg_offset,
+	void *dst, u32 len)
+{
+	u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32);
+	sep_read_msg(ta_ctx, dst, len, max_length, msg_offset, 0);
+}
+
+/**
+ * sep_write_context -
+ * @ta_ctx: pointer to struct this_task_ctx
+ * @msg_offset: point to current place in SEP msg; is updated
+ * @src: pointer to the current context
+ * @len: size of the context structure (differs for crypro/hash)
+ * This function writes the context to the msg area
+ * There is a special way the vendor needs to have the maximum
+ * length calculated so that the msg_offset is updated properly;
+ * it skips over some words in the msg area depending on the size
+ * of the context
+ */
+static void sep_write_context(struct this_task_ctx *ta_ctx, u32 *msg_offset,
+	void *src, u32 len)
+{
+	u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32);
+	sep_write_msg(ta_ctx, src, len, max_length, msg_offset, 0);
+}
+
+/**
+ * sep_clear_out -
+ * @ta_ctx: pointer to struct this_task_ctx
+ * Clear out crypto related values in sep device structure
+ * to enable device to be used by anyone; either kernel
+ * crypto or userspace app via middleware
+ */
+static void sep_clear_out(struct this_task_ctx *ta_ctx)
+{
+	if (ta_ctx->src_sg_hold) {
+		sep_free_sg_buf(ta_ctx->src_sg_hold);
+		ta_ctx->src_sg_hold = NULL;
+	}
+
+	if (ta_ctx->dst_sg_hold) {
+		sep_free_sg_buf(ta_ctx->dst_sg_hold);
+		ta_ctx->dst_sg_hold = NULL;
+	}
+
+	ta_ctx->src_sg = NULL;
+	ta_ctx->dst_sg = NULL;
+
+	sep_free_dma_table_data_handler(ta_ctx->sep_used, &ta_ctx->dma_ctx);
+
+	if (ta_ctx->i_own_sep) {
+		/**
+		 * The following unlocks the sep and makes it available
+		 * to any other application
+		 * First, null out crypto entries in sep before relesing it
+		 */
+		ta_ctx->sep_used->current_hash_req = NULL;
+		ta_ctx->sep_used->current_cypher_req = NULL;
+		ta_ctx->sep_used->current_request = 0;
+		ta_ctx->sep_used->current_hash_stage = 0;
+		ta_ctx->sep_used->ta_ctx = NULL;
+		ta_ctx->sep_used->in_kernel = 0;
+
+		ta_ctx->call_status.status = 0;
+
+		/* Remove anything confidentail */
+		memset(ta_ctx->sep_used->shared_addr, 0,
+			SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+		sep_queue_status_remove(ta_ctx->sep_used, &ta_ctx->queue_elem);
+
+#ifdef SEP_ENABLE_RUNTIME_PM
+		ta_ctx->sep_used->in_use = 0;
+		pm_runtime_mark_last_busy(&ta_ctx->sep_used->pdev->dev);
+		pm_runtime_put_autosuspend(&ta_ctx->sep_used->pdev->dev);
+#endif
+
+		clear_bit(SEP_WORKING_LOCK_BIT,
+			&ta_ctx->sep_used->in_use_flags);
+		ta_ctx->sep_used->pid_doing_transaction = 0;
+
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"[PID%d] waking up next transaction\n",
+			current->pid);
+
+		clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
+			&ta_ctx->sep_used->in_use_flags);
+		wake_up(&ta_ctx->sep_used->event_transactions);
+
+		ta_ctx->i_own_sep = 0;
+	}
+}
+
+/**
+  * Release crypto infrastructure from EINPROGRESS and
+  * clear sep_dev so that SEP is available to anyone
+  */
+static void sep_crypto_release(struct sep_system_ctx *sctx,
+	struct this_task_ctx *ta_ctx, u32 error)
+{
+	struct ahash_request *hash_req = ta_ctx->current_hash_req;
+	struct ablkcipher_request *cypher_req =
+		ta_ctx->current_cypher_req;
+	struct sep_device *sep = ta_ctx->sep_used;
+
+	sep_clear_out(ta_ctx);
+
+	/**
+	 * This may not yet exist depending when we
+	 * chose to bail out. If it does exist, set
+	 * it to 1
+	 */
+	if (ta_ctx->are_we_done_yet != NULL)
+		*ta_ctx->are_we_done_yet = 1;
+
+	if (cypher_req != NULL) {
+		if ((sctx->key_sent == 1) ||
+			((error != 0) && (error != -EINPROGRESS))) {
+			if (cypher_req->base.complete == NULL) {
+				dev_dbg(&sep->pdev->dev,
+					"release is null for cypher!");
+			} else {
+				cypher_req->base.complete(
+					&cypher_req->base, error);
+			}
+		}
+	}
+
+	if (hash_req != NULL) {
+		if (hash_req->base.complete == NULL) {
+			dev_dbg(&sep->pdev->dev,
+				"release is null for hash!");
+		} else {
+			hash_req->base.complete(
+				&hash_req->base, error);
+		}
+	}
+}
+
+/**
+ *	This is where we grab the sep itself and tell it to do something.
+ *	It will sleep if the sep is currently busy
+ *	and it will return 0 if sep is now ours; error value if there
+ *	were problems
+ */
+static int sep_crypto_take_sep(struct this_task_ctx *ta_ctx)
+{
+	struct sep_device *sep = ta_ctx->sep_used;
+	int result;
+	struct sep_msgarea_hdr *my_msg_header;
+
+	my_msg_header = (struct sep_msgarea_hdr *)ta_ctx->msg;
+
+	/* add to status queue */
+	ta_ctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode,
+		ta_ctx->nbytes, current->pid,
+		current->comm, sizeof(current->comm));
+
+	if (!ta_ctx->queue_elem) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] updating queue"
+			" status error\n", current->pid);
+		return -EINVAL;
+	}
+
+	/* get the device; this can sleep */
+	result = sep_wait_transaction(sep);
+	if (result)
+		return result;
+
+	if (sep_dev->power_save_setup == 1)
+		pm_runtime_get_sync(&sep_dev->pdev->dev);
+
+	/* Copy in the message */
+	memcpy(sep->shared_addr, ta_ctx->msg,
+		SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	/* Copy in the dcb information if there is any */
+	if (ta_ctx->dcb_region) {
+		result = sep_activate_dcb_dmatables_context(sep,
+			&ta_ctx->dcb_region, &ta_ctx->dmatables_region,
+			ta_ctx->dma_ctx);
+		if (result)
+			return result;
+	}
+
+	/* Mark the device so we know how to finish the job in the tasklet */
+	if (ta_ctx->current_hash_req)
+		sep->current_hash_req = ta_ctx->current_hash_req;
+	else
+		sep->current_cypher_req = ta_ctx->current_cypher_req;
+
+	sep->current_request = ta_ctx->current_request;
+	sep->current_hash_stage = ta_ctx->current_hash_stage;
+	sep->ta_ctx = ta_ctx;
+	sep->in_kernel = 1;
+	ta_ctx->i_own_sep = 1;
+
+	/* need to set bit first to avoid race condition with interrupt */
+	set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &ta_ctx->call_status.status);
+
+	result = sep_send_command_handler(sep);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d]: sending command to the sep\n",
+		current->pid);
+
+	if (!result)
+		dev_dbg(&sep->pdev->dev, "[PID%d]: command sent okay\n",
+			current->pid);
+	else {
+		dev_dbg(&sep->pdev->dev, "[PID%d]: cant send command\n",
+			current->pid);
+		clear_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
+			&ta_ctx->call_status.status);
+	}
+
+	return result;
+}
+
+/**
+ * This function sets things up for a crypto data block process
+ * This does all preparation, but does not try to grab the
+ * sep
+ * @req: pointer to struct ablkcipher_request
+ * returns: 0 if all went well, non zero if error
+ */
+static int sep_crypto_block_data(struct ablkcipher_request *req)
+{
+
+	int int_error;
+	u32 msg_offset;
+	static u32 msg[10];
+	void *src_ptr;
+	void *dst_ptr;
+
+	static char small_buf[100];
+	ssize_t copy_result;
+	int result;
+
+	struct scatterlist *new_sg;
+	struct this_task_ctx *ta_ctx;
+	struct crypto_ablkcipher *tfm;
+	struct sep_system_ctx *sctx;
+
+	struct sep_des_internal_context *des_internal;
+	struct sep_aes_internal_context *aes_internal;
+
+	ta_ctx = ablkcipher_request_ctx(req);
+	tfm = crypto_ablkcipher_reqtfm(req);
+	sctx = crypto_ablkcipher_ctx(tfm);
+
+	/* start the walk on scatterlists */
+	ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "sep crypto block data size of %x\n",
+		req->nbytes);
+
+	int_error = ablkcipher_walk_phys(req, &ta_ctx->walk);
+	if (int_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
+			int_error);
+		return -ENOMEM;
+	}
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"crypto block: src is %lx dst is %lx\n",
+		(unsigned long)req->src, (unsigned long)req->dst);
+
+	/* Make sure all pages are even block */
+	int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
+		req->nbytes, ta_ctx->walk.blocksize, &new_sg, 1);
+
+	if (int_error < 0) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page eerror\n");
+		return -ENOMEM;
+	} else if (int_error == 1) {
+		ta_ctx->src_sg = new_sg;
+		ta_ctx->src_sg_hold = new_sg;
+	} else {
+		ta_ctx->src_sg = req->src;
+		ta_ctx->src_sg_hold = NULL;
+	}
+
+	int_error = sep_oddball_pages(ta_ctx->sep_used, req->dst,
+		req->nbytes, ta_ctx->walk.blocksize, &new_sg, 0);
+
+	if (int_error < 0) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
+			int_error);
+		return -ENOMEM;
+	} else if (int_error == 1) {
+		ta_ctx->dst_sg = new_sg;
+		ta_ctx->dst_sg_hold = new_sg;
+	} else {
+		ta_ctx->dst_sg = req->dst;
+		ta_ctx->dst_sg_hold = NULL;
+	}
+
+	/* set nbytes for queue status */
+	ta_ctx->nbytes = req->nbytes;
+
+	/* Key already done; this is for data */
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending data\n");
+
+	sep_dump_sg(ta_ctx->sep_used,
+		"block sg in", ta_ctx->src_sg);
+
+	/* check for valid data and proper spacing */
+	src_ptr = sg_virt(ta_ctx->src_sg);
+	dst_ptr = sg_virt(ta_ctx->dst_sg);
+
+	if (!src_ptr || !dst_ptr ||
+		(ta_ctx->current_cypher_req->nbytes %
+		crypto_ablkcipher_blocksize(tfm))) {
+
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"cipher block size odd\n");
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"cipher block size is %x\n",
+			crypto_ablkcipher_blocksize(tfm));
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"cipher data size is %x\n",
+			ta_ctx->current_cypher_req->nbytes);
+		return -EINVAL;
+	}
+
+	if (partial_overlap(src_ptr, dst_ptr,
+		ta_ctx->current_cypher_req->nbytes)) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"block partial overlap\n");
+		return -EINVAL;
+	}
+
+	/* Put together the message */
+	sep_make_header(ta_ctx, &msg_offset, ta_ctx->block_opcode);
+
+	/* If des, and size is 1 block, put directly in msg */
+	if ((ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) &&
+		(req->nbytes == crypto_ablkcipher_blocksize(tfm))) {
+
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"writing out one block des\n");
+
+		copy_result = sg_copy_to_buffer(
+			ta_ctx->src_sg, sep_sg_nents(ta_ctx->src_sg),
+			small_buf, crypto_ablkcipher_blocksize(tfm));
+
+		if (copy_result != crypto_ablkcipher_blocksize(tfm)) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"des block copy faild\n");
+			return -ENOMEM;
+		}
+
+		/* Put data into message */
+		sep_write_msg(ta_ctx, small_buf,
+			crypto_ablkcipher_blocksize(tfm),
+			crypto_ablkcipher_blocksize(tfm) * 2,
+			&msg_offset, 1);
+
+		/* Put size into message */
+		sep_write_msg(ta_ctx, &req->nbytes,
+			sizeof(u32), sizeof(u32), &msg_offset, 0);
+	} else {
+		/* Otherwise, fill out dma tables */
+		ta_ctx->dcb_input_data.app_in_address = src_ptr;
+		ta_ctx->dcb_input_data.data_in_size = req->nbytes;
+		ta_ctx->dcb_input_data.app_out_address = dst_ptr;
+		ta_ctx->dcb_input_data.block_size =
+			crypto_ablkcipher_blocksize(tfm);
+		ta_ctx->dcb_input_data.tail_block_size = 0;
+		ta_ctx->dcb_input_data.is_applet = 0;
+		ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
+		ta_ctx->dcb_input_data.dst_sg = ta_ctx->dst_sg;
+
+		result = sep_create_dcb_dmatables_context_kernel(
+			ta_ctx->sep_used,
+			&ta_ctx->dcb_region,
+			&ta_ctx->dmatables_region,
+			&ta_ctx->dma_ctx,
+			&ta_ctx->dcb_input_data,
+			1);
+		if (result) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"crypto dma table create failed\n");
+			return -EINVAL;
+		}
+
+		/* Portion of msg is nulled (no data) */
+		msg[0] = (u32)0;
+		msg[1] = (u32)0;
+		msg[2] = (u32)0;
+		msg[3] = (u32)0;
+		msg[4] = (u32)0;
+		sep_write_msg(ta_ctx, (void *)msg, sizeof(u32) * 5,
+			sizeof(u32) * 5, &msg_offset, 0);
+		}
+
+	/**
+	 * Before we write the message, we need to overwrite the
+	 * vendor's IV with the one from our own ablkcipher walk
+	 * iv because this is needed for dm-crypt
+	 */
+	sep_dump_ivs(req, "sending data block to sep\n");
+	if ((ta_ctx->current_request == DES_CBC) &&
+		(ta_ctx->des_opmode == SEP_DES_CBC)) {
+
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"overwrite vendor iv on DES\n");
+		des_internal = (struct sep_des_internal_context *)
+			sctx->des_private_ctx.ctx_buf;
+		memcpy((void *)des_internal->iv_context,
+			ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm));
+	} else if ((ta_ctx->current_request == AES_CBC) &&
+		(ta_ctx->aes_opmode == SEP_AES_CBC)) {
+
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"overwrite vendor iv on AES\n");
+		aes_internal = (struct sep_aes_internal_context *)
+			sctx->aes_private_ctx.cbuff;
+		memcpy((void *)aes_internal->aes_ctx_iv,
+			ta_ctx->walk.iv, crypto_ablkcipher_ivsize(tfm));
+	}
+
+	/* Write context into message */
+	if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
+		sep_write_context(ta_ctx, &msg_offset,
+			&sctx->des_private_ctx,
+			sizeof(struct sep_des_private_context));
+		sep_dump(ta_ctx->sep_used, "ctx to block des",
+			&sctx->des_private_ctx, 40);
+	} else {
+		sep_write_context(ta_ctx, &msg_offset,
+			&sctx->aes_private_ctx,
+			sizeof(struct sep_aes_private_context));
+		sep_dump(ta_ctx->sep_used, "ctx to block aes",
+			&sctx->aes_private_ctx, 20);
+	}
+
+	/* conclude message */
+	sep_end_msg(ta_ctx, msg_offset);
+
+	/* Parent (caller) is now ready to tell the sep to do ahead */
+	return 0;
+}
+
+
+/**
+ * This function sets things up for a crypto key submit process
+ * This does all preparation, but does not try to grab the
+ * sep
+ * @req: pointer to struct ablkcipher_request
+ * returns: 0 if all went well, non zero if error
+ */
+static int sep_crypto_send_key(struct ablkcipher_request *req)
+{
+
+	int int_error;
+	u32 msg_offset;
+	static u32 msg[10];
+
+	u32 max_length;
+	struct this_task_ctx *ta_ctx;
+	struct crypto_ablkcipher *tfm;
+	struct sep_system_ctx *sctx;
+
+	ta_ctx = ablkcipher_request_ctx(req);
+	tfm = crypto_ablkcipher_reqtfm(req);
+	sctx = crypto_ablkcipher_ctx(tfm);
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "sending key\n");
+
+	/* start the walk on scatterlists */
+	ablkcipher_walk_init(&ta_ctx->walk, req->src, req->dst, req->nbytes);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"sep crypto block data size of %x\n", req->nbytes);
+
+	int_error = ablkcipher_walk_phys(req, &ta_ctx->walk);
+	if (int_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
+			int_error);
+		return -ENOMEM;
+	}
+
+	/* check iv */
+	if ((ta_ctx->current_request == DES_CBC) &&
+		(ta_ctx->des_opmode == SEP_DES_CBC)) {
+		if (!ta_ctx->walk.iv) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n");
+			return -EINVAL;
+		}
+
+		memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
+		sep_dump(ta_ctx->sep_used, "iv",
+			ta_ctx->iv, SEP_DES_IV_SIZE_BYTES);
+	}
+
+	if ((ta_ctx->current_request == AES_CBC) &&
+		(ta_ctx->aes_opmode == SEP_AES_CBC)) {
+		if (!ta_ctx->walk.iv) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev, "no iv found\n");
+			return -EINVAL;
+		}
+
+		memcpy(ta_ctx->iv, ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
+		sep_dump(ta_ctx->sep_used, "iv",
+			ta_ctx->iv, SEP_AES_IV_SIZE_BYTES);
+	}
+
+	/* put together message to SEP */
+	/* Start with op code */
+	sep_make_header(ta_ctx, &msg_offset, ta_ctx->init_opcode);
+
+	/* now deal with IV */
+	if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
+		if (ta_ctx->des_opmode == SEP_DES_CBC) {
+			sep_write_msg(ta_ctx, ta_ctx->iv,
+				SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4,
+				&msg_offset, 1);
+			sep_dump(ta_ctx->sep_used, "initial IV",
+				ta_ctx->walk.iv, SEP_DES_IV_SIZE_BYTES);
+		} else {
+			/* Skip if ECB */
+			msg_offset += 4 * sizeof(u32);
+		}
+	} else {
+		max_length = ((SEP_AES_IV_SIZE_BYTES + 3) /
+			sizeof(u32)) * sizeof(u32);
+		if (ta_ctx->aes_opmode == SEP_AES_CBC) {
+			sep_write_msg(ta_ctx, ta_ctx->iv,
+				SEP_AES_IV_SIZE_BYTES, max_length,
+				&msg_offset, 1);
+			sep_dump(ta_ctx->sep_used, "initial IV",
+				ta_ctx->walk.iv, SEP_AES_IV_SIZE_BYTES);
+		} else {
+				/* Skip if ECB */
+				msg_offset += max_length;
+			}
+		}
+
+	/* load the key */
+	if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
+		sep_write_msg(ta_ctx, (void *)&sctx->key.des.key1,
+			sizeof(u32) * 8, sizeof(u32) * 8,
+			&msg_offset, 1);
+
+		msg[0] = (u32)sctx->des_nbr_keys;
+		msg[1] = (u32)ta_ctx->des_encmode;
+		msg[2] = (u32)ta_ctx->des_opmode;
+
+		sep_write_msg(ta_ctx, (void *)msg,
+			sizeof(u32) * 3, sizeof(u32) * 3,
+			&msg_offset, 0);
+	} else {
+		sep_write_msg(ta_ctx, (void *)&sctx->key.aes,
+			sctx->keylen,
+			SEP_AES_MAX_KEY_SIZE_BYTES,
+			&msg_offset, 1);
+
+		msg[0] = (u32)sctx->aes_key_size;
+		msg[1] = (u32)ta_ctx->aes_encmode;
+		msg[2] = (u32)ta_ctx->aes_opmode;
+		msg[3] = (u32)0; /* Secret key is not used */
+		sep_write_msg(ta_ctx, (void *)msg,
+			sizeof(u32) * 4, sizeof(u32) * 4,
+			&msg_offset, 0);
+	}
+
+	/* conclude message */
+	sep_end_msg(ta_ctx, msg_offset);
+
+	/* Parent (caller) is now ready to tell the sep to do ahead */
+	return 0;
+}
+
+
+/* This needs to be run as a work queue as it can be put asleep */
+static void sep_crypto_block(void *data)
+{
+	unsigned long end_time;
+
+	int result;
+
+	struct ablkcipher_request *req;
+	struct this_task_ctx *ta_ctx;
+	struct crypto_ablkcipher *tfm;
+	struct sep_system_ctx *sctx;
+	int are_we_done_yet;
+
+	req = (struct ablkcipher_request *)data;
+	ta_ctx = ablkcipher_request_ctx(req);
+	tfm = crypto_ablkcipher_reqtfm(req);
+	sctx = crypto_ablkcipher_ctx(tfm);
+
+	ta_ctx->are_we_done_yet = &are_we_done_yet;
+
+	pr_debug("sep_crypto_block\n");
+	pr_debug("tfm is %p sctx is %p ta_ctx is %p\n",
+		tfm, sctx, ta_ctx);
+	pr_debug("key_sent is %d\n", sctx->key_sent);
+
+	/* do we need to send the key */
+	if (sctx->key_sent == 0) {
+		are_we_done_yet = 0;
+		result = sep_crypto_send_key(req); /* prep to send key */
+		if (result != 0) {
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"could not prep key %x\n", result);
+			sep_crypto_release(sctx, ta_ctx, result);
+			return;
+		}
+
+		result = sep_crypto_take_sep(ta_ctx);
+		if (result) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"sep_crypto_take_sep for key send failed\n");
+			sep_crypto_release(sctx, ta_ctx, result);
+			return;
+		}
+
+		/* now we sit and wait up to a fixed time for completion */
+		end_time = jiffies + (WAIT_TIME * HZ);
+		while ((time_before(jiffies, end_time)) &&
+			(are_we_done_yet == 0))
+			schedule();
+
+		/* Done waiting; still not done yet? */
+		if (are_we_done_yet == 0) {
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"Send key job never got done\n");
+			sep_crypto_release(sctx, ta_ctx, -EINVAL);
+			return;
+		}
+
+		/* Set the key sent variable so this can be skipped later */
+		sctx->key_sent = 1;
+	}
+
+	/* Key sent (or maybe not if we did not have to), now send block */
+	are_we_done_yet = 0;
+
+	result = sep_crypto_block_data(req);
+
+	if (result != 0) {
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"could prep not send block %x\n", result);
+		sep_crypto_release(sctx, ta_ctx, result);
+		return;
+	}
+
+	result = sep_crypto_take_sep(ta_ctx);
+	if (result) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"sep_crypto_take_sep for block send failed\n");
+		sep_crypto_release(sctx, ta_ctx, result);
+		return;
+	}
+
+	/* now we sit and wait up to a fixed time for completion */
+	end_time = jiffies + (WAIT_TIME * HZ);
+	while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
+		schedule();
+
+	/* Done waiting; still not done yet? */
+	if (are_we_done_yet == 0) {
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"Send block job never got done\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+	/* That's it; entire thing done, get out of queue */
+
+	pr_debug("crypto_block leaving\n");
+	pr_debug("tfm is %p sctx is %p ta_ctx is %p\n", tfm, sctx, ta_ctx);
+}
+
+/**
+ * Post operation (after interrupt) for crypto block
+ */
+static u32 crypto_post_op(struct sep_device *sep)
+{
+	/* HERE */
+	u32 u32_error;
+	u32 msg_offset;
+
+	ssize_t copy_result;
+	static char small_buf[100];
+
+	struct ablkcipher_request *req;
+	struct this_task_ctx *ta_ctx;
+	struct sep_system_ctx *sctx;
+	struct crypto_ablkcipher *tfm;
+
+	struct sep_des_internal_context *des_internal;
+	struct sep_aes_internal_context *aes_internal;
+
+	if (!sep->current_cypher_req)
+		return -EINVAL;
+
+	/* hold req since we need to submit work after clearing sep */
+	req = sep->current_cypher_req;
+
+	ta_ctx = ablkcipher_request_ctx(sep->current_cypher_req);
+	tfm = crypto_ablkcipher_reqtfm(sep->current_cypher_req);
+	sctx = crypto_ablkcipher_ctx(tfm);
+
+	pr_debug("crypto_post op\n");
+	pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n",
+		sctx->key_sent, tfm, sctx, ta_ctx);
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op\n");
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "crypto post_op message dump\n");
+	crypto_sep_dump_message(ta_ctx->sep_used, ta_ctx->msg);
+
+	/* first bring msg from shared area to local area */
+	memcpy(ta_ctx->msg, sep->shared_addr,
+		SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	/* Is this the result of performing init (key to SEP */
+	if (sctx->key_sent == 0) {
+
+		/* Did SEP do it okay */
+		u32_error = sep_verify_op(ta_ctx, ta_ctx->init_opcode,
+			&msg_offset);
+		if (u32_error) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"aes init error %x\n", u32_error);
+			sep_crypto_release(sctx, ta_ctx, u32_error);
+			return u32_error;
+			}
+
+		/* Read Context */
+		if (ta_ctx->init_opcode == SEP_DES_INIT_OPCODE) {
+			sep_read_context(ta_ctx, &msg_offset,
+			&sctx->des_private_ctx,
+			sizeof(struct sep_des_private_context));
+
+			sep_dump(ta_ctx->sep_used, "ctx init des",
+				&sctx->des_private_ctx, 40);
+		} else {
+			sep_read_context(ta_ctx, &msg_offset,
+			&sctx->aes_private_ctx,
+			sizeof(struct sep_aes_private_context));
+
+			sep_dump(ta_ctx->sep_used, "ctx init aes",
+				&sctx->aes_private_ctx, 20);
+		}
+
+		sep_dump_ivs(req, "after sending key to sep\n");
+
+		/* key sent went okay; release sep, and set are_we_done_yet */
+		sctx->key_sent = 1;
+		sep_crypto_release(sctx, ta_ctx, -EINPROGRESS);
+
+	} else {
+
+		/**
+		 * This is the result of a block request
+		 */
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"crypto_post_op block response\n");
+
+		u32_error = sep_verify_op(ta_ctx, ta_ctx->block_opcode,
+			&msg_offset);
+
+		if (u32_error) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"sep block error %x\n", u32_error);
+			sep_crypto_release(sctx, ta_ctx, u32_error);
+			return -EINVAL;
+			}
+
+		if (ta_ctx->block_opcode == SEP_DES_BLOCK_OPCODE) {
+
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"post op for DES\n");
+
+			/* special case for 1 block des */
+			if (sep->current_cypher_req->nbytes ==
+				crypto_ablkcipher_blocksize(tfm)) {
+
+				sep_read_msg(ta_ctx, small_buf,
+					crypto_ablkcipher_blocksize(tfm),
+					crypto_ablkcipher_blocksize(tfm) * 2,
+					&msg_offset, 1);
+
+				dev_dbg(&ta_ctx->sep_used->pdev->dev,
+					"reading in block des\n");
+
+				copy_result = sg_copy_from_buffer(
+					ta_ctx->dst_sg,
+					sep_sg_nents(ta_ctx->dst_sg),
+					small_buf,
+					crypto_ablkcipher_blocksize(tfm));
+
+				if (copy_result !=
+					crypto_ablkcipher_blocksize(tfm)) {
+
+					dev_warn(&ta_ctx->sep_used->pdev->dev,
+						"des block copy faild\n");
+					sep_crypto_release(sctx, ta_ctx,
+						-ENOMEM);
+					return -ENOMEM;
+				}
+			}
+
+			/* Read Context */
+			sep_read_context(ta_ctx, &msg_offset,
+				&sctx->des_private_ctx,
+				sizeof(struct sep_des_private_context));
+		} else {
+
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"post op for AES\n");
+
+			/* Skip the MAC Output */
+			msg_offset += (sizeof(u32) * 4);
+
+			/* Read Context */
+			sep_read_context(ta_ctx, &msg_offset,
+				&sctx->aes_private_ctx,
+				sizeof(struct sep_aes_private_context));
+		}
+
+		sep_dump_sg(ta_ctx->sep_used,
+			"block sg out", ta_ctx->dst_sg);
+
+		/* Copy to correct sg if this block had oddball pages */
+		if (ta_ctx->dst_sg_hold)
+			sep_copy_sg(ta_ctx->sep_used,
+				ta_ctx->dst_sg,
+				ta_ctx->current_cypher_req->dst,
+				ta_ctx->current_cypher_req->nbytes);
+
+		/**
+		 * Copy the iv's back to the walk.iv
+		 * This is required for dm_crypt
+		 */
+		sep_dump_ivs(req, "got data block from sep\n");
+		if ((ta_ctx->current_request == DES_CBC) &&
+			(ta_ctx->des_opmode == SEP_DES_CBC)) {
+
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"returning result iv to walk on DES\n");
+			des_internal = (struct sep_des_internal_context *)
+				sctx->des_private_ctx.ctx_buf;
+			memcpy(ta_ctx->walk.iv,
+				(void *)des_internal->iv_context,
+				crypto_ablkcipher_ivsize(tfm));
+		} else if ((ta_ctx->current_request == AES_CBC) &&
+			(ta_ctx->aes_opmode == SEP_AES_CBC)) {
+
+			dev_dbg(&ta_ctx->sep_used->pdev->dev,
+				"returning result iv to walk on AES\n");
+			aes_internal = (struct sep_aes_internal_context *)
+				sctx->aes_private_ctx.cbuff;
+			memcpy(ta_ctx->walk.iv,
+				(void *)aes_internal->aes_ctx_iv,
+				crypto_ablkcipher_ivsize(tfm));
+		}
+
+		/* finished, release everything */
+		sep_crypto_release(sctx, ta_ctx, 0);
+	}
+	pr_debug("crypto_post_op done\n");
+	pr_debug("key_sent is %d tfm is %p sctx is %p ta_ctx is %p\n",
+		sctx->key_sent, tfm, sctx, ta_ctx);
+
+	return 0;
+}
+
+static u32 hash_init_post_op(struct sep_device *sep)
+{
+	u32 u32_error;
+	u32 msg_offset;
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
+	struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"hash init post op\n");
+
+	/* first bring msg from shared area to local area */
+	memcpy(ta_ctx->msg, sep->shared_addr,
+		SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	u32_error = sep_verify_op(ta_ctx, SEP_HASH_INIT_OPCODE,
+		&msg_offset);
+
+	if (u32_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n",
+			u32_error);
+		sep_crypto_release(sctx, ta_ctx, u32_error);
+		return u32_error;
+		}
+
+	/* Read Context */
+	sep_read_context(ta_ctx, &msg_offset,
+		&sctx->hash_private_ctx,
+		sizeof(struct sep_hash_private_context));
+
+	/* Signal to crypto infrastructure and clear out */
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash init post op done\n");
+	sep_crypto_release(sctx, ta_ctx, 0);
+	return 0;
+}
+
+static u32 hash_update_post_op(struct sep_device *sep)
+{
+	u32 u32_error;
+	u32 msg_offset;
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
+	struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"hash update post op\n");
+
+	/* first bring msg from shared area to local area */
+	memcpy(ta_ctx->msg, sep->shared_addr,
+		SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	u32_error = sep_verify_op(ta_ctx, SEP_HASH_UPDATE_OPCODE,
+		&msg_offset);
+
+	if (u32_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "hash init error %x\n",
+			u32_error);
+		sep_crypto_release(sctx, ta_ctx, u32_error);
+		return u32_error;
+		}
+
+	/* Read Context */
+	sep_read_context(ta_ctx, &msg_offset,
+		&sctx->hash_private_ctx,
+		sizeof(struct sep_hash_private_context));
+
+	/**
+	 * Following is only for finup; if we just completd the
+	 * data portion of finup, we now need to kick off the
+	 * finish portion of finup.
+	 */
+
+	if (ta_ctx->sep_used->current_hash_stage == HASH_FINUP_DATA) {
+
+		/* first reset stage to HASH_FINUP_FINISH */
+		ta_ctx->sep_used->current_hash_stage = HASH_FINUP_FINISH;
+
+		/* now enqueue the finish operation */
+		spin_lock_irq(&queue_lock);
+		u32_error = crypto_enqueue_request(&sep_queue,
+			&ta_ctx->sep_used->current_hash_req->base);
+		spin_unlock_irq(&queue_lock);
+
+		if ((u32_error != 0) && (u32_error != -EINPROGRESS)) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"spe cypher post op cant queue\n");
+			sep_crypto_release(sctx, ta_ctx, u32_error);
+			return u32_error;
+		}
+
+		/* schedule the data send */
+		u32_error = sep_submit_work(ta_ctx->sep_used->workqueue,
+			sep_dequeuer, (void *)&sep_queue);
+
+		if (u32_error) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"cant submit work sep_crypto_block\n");
+			sep_crypto_release(sctx, ta_ctx, -EINVAL);
+			return -EINVAL;
+		}
+	}
+
+	/* Signal to crypto infrastructure and clear out */
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash update post op done\n");
+	sep_crypto_release(sctx, ta_ctx, 0);
+	return 0;
+}
+
+static u32 hash_final_post_op(struct sep_device *sep)
+{
+	int max_length;
+	u32 u32_error;
+	u32 msg_offset;
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
+	struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"hash final post op\n");
+
+	/* first bring msg from shared area to local area */
+	memcpy(ta_ctx->msg, sep->shared_addr,
+		SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	u32_error = sep_verify_op(ta_ctx, SEP_HASH_FINISH_OPCODE,
+		&msg_offset);
+
+	if (u32_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev, "hash finish error %x\n",
+			u32_error);
+		sep_crypto_release(sctx, ta_ctx, u32_error);
+		return u32_error;
+		}
+
+	/* Grab the result */
+	if (ta_ctx->current_hash_req->result == NULL) {
+		/* Oops, null buffer; error out here */
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"hash finish null buffer\n");
+		sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM);
+		return -ENOMEM;
+		}
+
+	max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) /
+		sizeof(u32)) * sizeof(u32);
+
+	sep_read_msg(ta_ctx,
+		ta_ctx->current_hash_req->result,
+		crypto_ahash_digestsize(tfm), max_length,
+		&msg_offset, 0);
+
+	/* Signal to crypto infrastructure and clear out */
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "hash finish post op done\n");
+	sep_crypto_release(sctx, ta_ctx, 0);
+	return 0;
+}
+
+static u32 hash_digest_post_op(struct sep_device *sep)
+{
+	int max_length;
+	u32 u32_error;
+	u32 msg_offset;
+	struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req);
+	struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm);
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(sep->current_hash_req);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"hash digest post op\n");
+
+	/* first bring msg from shared area to local area */
+	memcpy(ta_ctx->msg, sep->shared_addr,
+		SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	u32_error = sep_verify_op(ta_ctx, SEP_HASH_SINGLE_OPCODE,
+		&msg_offset);
+
+	if (u32_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"hash digest finish error %x\n", u32_error);
+
+		sep_crypto_release(sctx, ta_ctx, u32_error);
+		return u32_error;
+		}
+
+	/* Grab the result */
+	if (ta_ctx->current_hash_req->result == NULL) {
+		/* Oops, null buffer; error out here */
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"hash digest finish null buffer\n");
+		sep_crypto_release(sctx, ta_ctx, (u32)-ENOMEM);
+		return -ENOMEM;
+		}
+
+	max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) /
+		sizeof(u32)) * sizeof(u32);
+
+	sep_read_msg(ta_ctx,
+		ta_ctx->current_hash_req->result,
+		crypto_ahash_digestsize(tfm), max_length,
+		&msg_offset, 0);
+
+	/* Signal to crypto infrastructure and clear out */
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"hash digest finish post op done\n");
+
+	sep_crypto_release(sctx, ta_ctx, 0);
+	return 0;
+}
+
+/**
+ * The sep_finish function is the function that is schedule (via tasket)
+ * by the interrupt service routine when the SEP sends and interrupt
+ * This is only called by the interrupt handler as a tasklet.
+ */
+static void sep_finish(unsigned long data)
+{
+	struct sep_device *sep_dev;
+	int res;
+
+	res = 0;
+
+	if (data == 0) {
+		pr_debug("sep_finish called with null data\n");
+		return;
+	}
+
+	sep_dev = (struct sep_device *)data;
+	if (sep_dev == NULL) {
+		pr_debug("sep_finish; sep_dev is NULL\n");
+		return;
+	}
+
+	if (sep_dev->in_kernel == (u32)0) {
+		dev_warn(&sep_dev->pdev->dev,
+			"sep_finish; not in kernel operation\n");
+		return;
+	}
+
+	/* Did we really do a sep command prior to this? */
+	if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
+		&sep_dev->ta_ctx->call_status.status)) {
+
+		dev_warn(&sep_dev->pdev->dev, "[PID%d] sendmsg not called\n",
+			current->pid);
+		return;
+	}
+
+	if (sep_dev->send_ct != sep_dev->reply_ct) {
+		dev_warn(&sep_dev->pdev->dev,
+			"[PID%d] poll; no message came back\n",
+			current->pid);
+		return;
+	}
+
+	/* Check for error (In case time ran out) */
+	if ((res != 0x0) && (res != 0x8)) {
+		dev_warn(&sep_dev->pdev->dev,
+			"[PID%d] poll; poll error GPR3 is %x\n",
+			current->pid, res);
+		return;
+	}
+
+	/* What kind of interrupt from sep was this? */
+	res = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+
+	dev_dbg(&sep_dev->pdev->dev, "[PID%d] GPR2 at crypto finish is %x\n",
+		current->pid, res);
+
+	/* Print request? */
+	if ((res >> 30) & 0x1) {
+		dev_dbg(&sep_dev->pdev->dev, "[PID%d] sep print req\n",
+			current->pid);
+		dev_dbg(&sep_dev->pdev->dev, "[PID%d] contents: %s\n",
+			current->pid,
+			(char *)(sep_dev->shared_addr +
+			SEP_DRIVER_PRINTF_OFFSET_IN_BYTES));
+		return;
+	}
+
+	/* Request for daemon (not currently in POR)? */
+	if (res >> 31) {
+		dev_dbg(&sep_dev->pdev->dev,
+			"[PID%d] sep request; ignoring\n",
+			current->pid);
+		return;
+	}
+
+	/* If we got here, then we have a replay to a sep command */
+
+	dev_dbg(&sep_dev->pdev->dev,
+		"[PID%d] sep reply to command; processing request: %x\n",
+		current->pid, sep_dev->current_request);
+
+	switch (sep_dev->current_request) {
+	case AES_CBC:
+	case AES_ECB:
+	case DES_CBC:
+	case DES_ECB:
+		res = crypto_post_op(sep_dev);
+		break;
+	case SHA1:
+	case MD5:
+	case SHA224:
+	case SHA256:
+		switch (sep_dev->current_hash_stage) {
+		case HASH_INIT:
+			res = hash_init_post_op(sep_dev);
+			break;
+		case HASH_UPDATE:
+		case HASH_FINUP_DATA:
+			res = hash_update_post_op(sep_dev);
+			break;
+		case HASH_FINUP_FINISH:
+		case HASH_FINISH:
+			res = hash_final_post_op(sep_dev);
+			break;
+		case HASH_DIGEST:
+			res = hash_digest_post_op(sep_dev);
+			break;
+		default:
+			pr_debug("sep - invalid stage for hash finish\n");
+		}
+		break;
+	default:
+		pr_debug("sep - invalid request for finish\n");
+	}
+
+	if (res)
+		pr_debug("sep - finish returned error %x\n", res);
+}
+
+static int sep_hash_cra_init(struct crypto_tfm *tfm)
+	{
+	const char *alg_name = crypto_tfm_alg_name(tfm);
+
+	pr_debug("sep_hash_cra_init name is %s\n", alg_name);
+
+	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+		sizeof(struct this_task_ctx));
+	return 0;
+	}
+
+static void sep_hash_cra_exit(struct crypto_tfm *tfm)
+{
+	pr_debug("sep_hash_cra_exit\n");
+}
+
+static void sep_hash_init(void *data)
+{
+	u32 msg_offset;
+	int result;
+	struct ahash_request *req;
+	struct crypto_ahash *tfm;
+	struct this_task_ctx *ta_ctx;
+	struct sep_system_ctx *sctx;
+	unsigned long end_time;
+	int are_we_done_yet;
+
+	req = (struct ahash_request *)data;
+	tfm = crypto_ahash_reqtfm(req);
+	sctx = crypto_ahash_ctx(tfm);
+	ta_ctx = ahash_request_ctx(req);
+	ta_ctx->sep_used = sep_dev;
+
+	ta_ctx->are_we_done_yet = &are_we_done_yet;
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"sep_hash_init\n");
+	ta_ctx->current_hash_stage = HASH_INIT;
+	/* opcode and mode */
+	sep_make_header(ta_ctx, &msg_offset, SEP_HASH_INIT_OPCODE);
+	sep_write_msg(ta_ctx, &ta_ctx->hash_opmode,
+		sizeof(u32), sizeof(u32), &msg_offset, 0);
+	sep_end_msg(ta_ctx, msg_offset);
+
+	are_we_done_yet = 0;
+	result = sep_crypto_take_sep(ta_ctx);
+	if (result) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"sep_hash_init take sep failed\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+	}
+
+	/* now we sit and wait up to a fixed time for completion */
+	end_time = jiffies + (WAIT_TIME * HZ);
+	while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
+		schedule();
+
+	/* Done waiting; still not done yet? */
+	if (are_we_done_yet == 0) {
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"hash init never got done\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+}
+
+static void sep_hash_update(void *data)
+{
+	int int_error;
+	u32 msg_offset;
+	u32 len;
+	struct sep_hash_internal_context *int_ctx;
+	u32 block_size;
+	u32 head_len;
+	u32 tail_len;
+	int are_we_done_yet;
+
+	static u32 msg[10];
+	static char small_buf[100];
+	void *src_ptr;
+	struct scatterlist *new_sg;
+	ssize_t copy_result;
+	struct ahash_request *req;
+	struct crypto_ahash *tfm;
+	struct this_task_ctx *ta_ctx;
+	struct sep_system_ctx *sctx;
+	unsigned long end_time;
+
+	req = (struct ahash_request *)data;
+	tfm = crypto_ahash_reqtfm(req);
+	sctx = crypto_ahash_ctx(tfm);
+	ta_ctx = ahash_request_ctx(req);
+	ta_ctx->sep_used = sep_dev;
+
+	ta_ctx->are_we_done_yet = &are_we_done_yet;
+
+	/* length for queue status */
+	ta_ctx->nbytes = req->nbytes;
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"sep_hash_update\n");
+	ta_ctx->current_hash_stage = HASH_UPDATE;
+	len = req->nbytes;
+
+	block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+	tail_len = req->nbytes % block_size;
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", len);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
+
+	/* Compute header/tail sizes */
+	int_ctx = (struct sep_hash_internal_context *)&sctx->
+		hash_private_ctx.internal_context;
+	head_len = (block_size - int_ctx->prev_update_bytes) % block_size;
+	tail_len = (req->nbytes - head_len) % block_size;
+
+	/* Make sure all pages are even block */
+	int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
+		req->nbytes,
+		block_size, &new_sg, 1);
+
+	if (int_error < 0) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"oddball pages error in crash update\n");
+		sep_crypto_release(sctx, ta_ctx, -ENOMEM);
+		return;
+	} else if (int_error == 1) {
+		ta_ctx->src_sg = new_sg;
+		ta_ctx->src_sg_hold = new_sg;
+	} else {
+		ta_ctx->src_sg = req->src;
+		ta_ctx->src_sg_hold = NULL;
+	}
+
+	src_ptr = sg_virt(ta_ctx->src_sg);
+
+	if ((!req->nbytes) || (!ta_ctx->src_sg)) {
+		/* null data */
+		src_ptr = NULL;
+	}
+
+	sep_dump_sg(ta_ctx->sep_used, "hash block sg in", ta_ctx->src_sg);
+
+	ta_ctx->dcb_input_data.app_in_address = src_ptr;
+	ta_ctx->dcb_input_data.data_in_size =
+		req->nbytes - (head_len + tail_len);
+	ta_ctx->dcb_input_data.app_out_address = NULL;
+	ta_ctx->dcb_input_data.block_size = block_size;
+	ta_ctx->dcb_input_data.tail_block_size = 0;
+	ta_ctx->dcb_input_data.is_applet = 0;
+	ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
+	ta_ctx->dcb_input_data.dst_sg = NULL;
+
+	int_error = sep_create_dcb_dmatables_context_kernel(
+		ta_ctx->sep_used,
+		&ta_ctx->dcb_region,
+		&ta_ctx->dmatables_region,
+		&ta_ctx->dma_ctx,
+		&ta_ctx->dcb_input_data,
+		1);
+	if (int_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"hash update dma table create failed\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+	/* Construct message to SEP */
+	sep_make_header(ta_ctx, &msg_offset, SEP_HASH_UPDATE_OPCODE);
+
+	msg[0] = (u32)0;
+	msg[1] = (u32)0;
+	msg[2] = (u32)0;
+
+	sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
+		&msg_offset, 0);
+
+	/* Handle remainders */
+
+	/* Head */
+	sep_write_msg(ta_ctx, &head_len, sizeof(u32),
+		sizeof(u32), &msg_offset, 0);
+
+	if (head_len) {
+		copy_result = sg_copy_to_buffer(
+			req->src,
+			sep_sg_nents(ta_ctx->src_sg),
+			small_buf, head_len);
+
+		if (copy_result != head_len) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"sg head copy failure in hash block\n");
+			sep_crypto_release(sctx, ta_ctx, -ENOMEM);
+			return;
+		}
+
+		sep_write_msg(ta_ctx, small_buf, head_len,
+			sizeof(u32) * 32, &msg_offset, 1);
+	} else {
+		msg_offset += sizeof(u32) * 32;
+	}
+
+	/* Tail */
+	sep_write_msg(ta_ctx, &tail_len, sizeof(u32),
+		sizeof(u32), &msg_offset, 0);
+
+	if (tail_len) {
+		copy_result = sep_copy_offset_sg(
+			ta_ctx->sep_used,
+			ta_ctx->src_sg,
+			req->nbytes - tail_len,
+			small_buf, tail_len);
+
+		if (copy_result != tail_len) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"sg tail copy failure in hash block\n");
+			sep_crypto_release(sctx, ta_ctx, -ENOMEM);
+			return;
+		}
+
+		sep_write_msg(ta_ctx, small_buf, tail_len,
+			sizeof(u32) * 32, &msg_offset, 1);
+	} else {
+		msg_offset += sizeof(u32) * 32;
+	}
+
+	/* Context */
+	sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx,
+		sizeof(struct sep_hash_private_context));
+
+	sep_end_msg(ta_ctx, msg_offset);
+	are_we_done_yet = 0;
+	int_error = sep_crypto_take_sep(ta_ctx);
+	if (int_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"sep_hash_update take sep failed\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+	}
+
+	/* now we sit and wait up to a fixed time for completion */
+	end_time = jiffies + (WAIT_TIME * HZ);
+	while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
+		schedule();
+
+	/* Done waiting; still not done yet? */
+	if (are_we_done_yet == 0) {
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"hash update never got done\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+}
+
+static void sep_hash_final(void *data)
+{
+	u32 msg_offset;
+	struct ahash_request *req;
+	struct crypto_ahash *tfm;
+	struct this_task_ctx *ta_ctx;
+	struct sep_system_ctx *sctx;
+	int result;
+	unsigned long end_time;
+	int are_we_done_yet;
+
+	req = (struct ahash_request *)data;
+	tfm = crypto_ahash_reqtfm(req);
+	sctx = crypto_ahash_ctx(tfm);
+	ta_ctx = ahash_request_ctx(req);
+	ta_ctx->sep_used = sep_dev;
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"sep_hash_final\n");
+	ta_ctx->current_hash_stage = HASH_FINISH;
+
+	ta_ctx->are_we_done_yet = &are_we_done_yet;
+
+	/* opcode and mode */
+	sep_make_header(ta_ctx, &msg_offset, SEP_HASH_FINISH_OPCODE);
+
+	/* Context */
+	sep_write_context(ta_ctx, &msg_offset, &sctx->hash_private_ctx,
+		sizeof(struct sep_hash_private_context));
+
+	sep_end_msg(ta_ctx, msg_offset);
+	are_we_done_yet = 0;
+	result = sep_crypto_take_sep(ta_ctx);
+	if (result) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"sep_hash_final take sep failed\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+	}
+
+	/* now we sit and wait up to a fixed time for completion */
+	end_time = jiffies + (WAIT_TIME * HZ);
+	while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
+		schedule();
+
+	/* Done waiting; still not done yet? */
+	if (are_we_done_yet == 0) {
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"hash final job never got done\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+}
+
+static void sep_hash_digest(void *data)
+{
+	int int_error;
+	u32 msg_offset;
+	u32 block_size;
+	u32 msg[10];
+	size_t copy_result;
+	int result;
+	int are_we_done_yet;
+	u32 tail_len;
+	static char small_buf[100];
+	struct scatterlist *new_sg;
+	void *src_ptr;
+
+	struct ahash_request *req;
+	struct crypto_ahash *tfm;
+	struct this_task_ctx *ta_ctx;
+	struct sep_system_ctx *sctx;
+	unsigned long end_time;
+
+	req = (struct ahash_request *)data;
+	tfm = crypto_ahash_reqtfm(req);
+	sctx = crypto_ahash_ctx(tfm);
+	ta_ctx = ahash_request_ctx(req);
+	ta_ctx->sep_used = sep_dev;
+
+	dev_dbg(&ta_ctx->sep_used->pdev->dev,
+		"sep_hash_digest\n");
+	ta_ctx->current_hash_stage = HASH_DIGEST;
+
+	ta_ctx->are_we_done_yet = &are_we_done_yet;
+
+	/* length for queue status */
+	ta_ctx->nbytes = req->nbytes;
+
+	block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+	tail_len = req->nbytes % block_size;
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "length is %x\n", req->nbytes);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "block_size is %x\n", block_size);
+	dev_dbg(&ta_ctx->sep_used->pdev->dev, "tail len is %x\n", tail_len);
+
+	/* Make sure all pages are even block */
+	int_error = sep_oddball_pages(ta_ctx->sep_used, req->src,
+		req->nbytes,
+		block_size, &new_sg, 1);
+
+	if (int_error < 0) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"oddball pages error in crash update\n");
+		sep_crypto_release(sctx, ta_ctx, -ENOMEM);
+		return;
+	} else if (int_error == 1) {
+		ta_ctx->src_sg = new_sg;
+		ta_ctx->src_sg_hold = new_sg;
+	} else {
+		ta_ctx->src_sg = req->src;
+		ta_ctx->src_sg_hold = NULL;
+	}
+
+	src_ptr = sg_virt(ta_ctx->src_sg);
+
+	if ((!req->nbytes) || (!ta_ctx->src_sg)) {
+		/* null data */
+		src_ptr = NULL;
+	}
+
+	sep_dump_sg(ta_ctx->sep_used, "hash block sg in", ta_ctx->src_sg);
+
+	ta_ctx->dcb_input_data.app_in_address = src_ptr;
+	ta_ctx->dcb_input_data.data_in_size = req->nbytes - tail_len;
+	ta_ctx->dcb_input_data.app_out_address = NULL;
+	ta_ctx->dcb_input_data.block_size = block_size;
+	ta_ctx->dcb_input_data.tail_block_size = 0;
+	ta_ctx->dcb_input_data.is_applet = 0;
+	ta_ctx->dcb_input_data.src_sg = ta_ctx->src_sg;
+	ta_ctx->dcb_input_data.dst_sg = NULL;
+
+	int_error = sep_create_dcb_dmatables_context_kernel(
+		ta_ctx->sep_used,
+		&ta_ctx->dcb_region,
+		&ta_ctx->dmatables_region,
+		&ta_ctx->dma_ctx,
+		&ta_ctx->dcb_input_data,
+		1);
+	if (int_error) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"hash update dma table create failed\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+	/* Construct message to SEP */
+	sep_make_header(ta_ctx, &msg_offset, SEP_HASH_SINGLE_OPCODE);
+	sep_write_msg(ta_ctx, &ta_ctx->hash_opmode,
+		sizeof(u32), sizeof(u32), &msg_offset, 0);
+
+	msg[0] = (u32)0;
+	msg[1] = (u32)0;
+	msg[2] = (u32)0;
+
+	sep_write_msg(ta_ctx, msg, sizeof(u32) * 3, sizeof(u32) * 3,
+		&msg_offset, 0);
+
+	/* Tail */
+	sep_write_msg(ta_ctx, &tail_len, sizeof(u32),
+		sizeof(u32), &msg_offset, 0);
+
+	if (tail_len) {
+		copy_result = sep_copy_offset_sg(
+			ta_ctx->sep_used,
+			ta_ctx->src_sg,
+			req->nbytes - tail_len,
+			small_buf, tail_len);
+
+		if (copy_result != tail_len) {
+			dev_warn(&ta_ctx->sep_used->pdev->dev,
+				"sg tail copy failure in hash block\n");
+			sep_crypto_release(sctx, ta_ctx, -ENOMEM);
+			return;
+		}
+
+		sep_write_msg(ta_ctx, small_buf, tail_len,
+			sizeof(u32) * 32, &msg_offset, 1);
+	} else {
+		msg_offset += sizeof(u32) * 32;
+	}
+
+	sep_end_msg(ta_ctx, msg_offset);
+
+	are_we_done_yet = 0;
+	result = sep_crypto_take_sep(ta_ctx);
+	if (result) {
+		dev_warn(&ta_ctx->sep_used->pdev->dev,
+			"sep_hash_digest take sep failed\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+	}
+
+	/* now we sit and wait up to a fixed time for completion */
+	end_time = jiffies + (WAIT_TIME * HZ);
+	while ((time_before(jiffies, end_time)) && (are_we_done_yet == 0))
+		schedule();
+
+	/* Done waiting; still not done yet? */
+	if (are_we_done_yet == 0) {
+		dev_dbg(&ta_ctx->sep_used->pdev->dev,
+			"hash digest job never got done\n");
+		sep_crypto_release(sctx, ta_ctx, -EINVAL);
+		return;
+	}
+
+}
+
+/**
+ * This is what is called by each of the API's provided
+ * in the kernel crypto descriptors. It is run in a process
+ * context using the kernel workqueues. Therefore it can
+ * be put to sleep.
+ */
+static void sep_dequeuer(void *data)
+{
+	struct crypto_queue *this_queue;
+	struct crypto_async_request *async_req;
+	struct crypto_async_request *backlog;
+	struct ablkcipher_request *cypher_req;
+	struct ahash_request *hash_req;
+	struct sep_system_ctx *sctx;
+	struct crypto_ahash *hash_tfm;
+	struct this_task_ctx *ta_ctx;
+
+
+	this_queue = (struct crypto_queue *)data;
+
+	spin_lock_irq(&queue_lock);
+	backlog = crypto_get_backlog(this_queue);
+	async_req = crypto_dequeue_request(this_queue);
+	spin_unlock_irq(&queue_lock);
+
+	if (!async_req) {
+		pr_debug("sep crypto queue is empty\n");
+		return;
+	}
+
+	if (backlog) {
+		pr_debug("sep crypto backlog set\n");
+		if (backlog->complete)
+			backlog->complete(backlog, -EINPROGRESS);
+		backlog = NULL;
+	}
+
+	if (!async_req->tfm) {
+		pr_debug("sep crypto queue null tfm\n");
+		return;
+	}
+
+	if (!async_req->tfm->__crt_alg) {
+		pr_debug("sep crypto queue null __crt_alg\n");
+		return;
+	}
+
+	if (!async_req->tfm->__crt_alg->cra_type) {
+		pr_debug("sep crypto queue null cra_type\n");
+		return;
+	}
+
+	/* we have stuff in the queue */
+	if (async_req->tfm->__crt_alg->cra_type !=
+		&crypto_ahash_type) {
+		/* This is for a cypher */
+		pr_debug("sep crypto queue doing cipher\n");
+		cypher_req = container_of(async_req,
+			struct ablkcipher_request,
+			base);
+		if (!cypher_req) {
+			pr_debug("sep crypto queue null cypher_req\n");
+			return;
+		}
+
+		sep_crypto_block((void *)cypher_req);
+		return;
+	} else {
+		/* This is a hash */
+		pr_debug("sep crypto queue doing hash\n");
+		/**
+		 * This is a bit more complex than cipher; we
+		 * need to figure out what type of operation
+		 */
+		hash_req = ahash_request_cast(async_req);
+		if (!hash_req) {
+			pr_debug("sep crypto queue null hash_req\n");
+			return;
+		}
+
+		hash_tfm = crypto_ahash_reqtfm(hash_req);
+		if (!hash_tfm) {
+			pr_debug("sep crypto queue null hash_tfm\n");
+			return;
+		}
+
+
+		sctx = crypto_ahash_ctx(hash_tfm);
+		if (!sctx) {
+			pr_debug("sep crypto queue null sctx\n");
+			return;
+		}
+
+		ta_ctx = ahash_request_ctx(hash_req);
+
+		if (ta_ctx->current_hash_stage == HASH_INIT) {
+			pr_debug("sep crypto queue hash init\n");
+			sep_hash_init((void *)hash_req);
+			return;
+		} else if (ta_ctx->current_hash_stage == HASH_UPDATE) {
+			pr_debug("sep crypto queue hash update\n");
+			sep_hash_update((void *)hash_req);
+			return;
+		} else if (ta_ctx->current_hash_stage == HASH_FINISH) {
+			pr_debug("sep crypto queue hash final\n");
+			sep_hash_final((void *)hash_req);
+			return;
+		} else if (ta_ctx->current_hash_stage == HASH_DIGEST) {
+			pr_debug("sep crypto queue hash digest\n");
+			sep_hash_digest((void *)hash_req);
+			return;
+		} else if (ta_ctx->current_hash_stage == HASH_FINUP_DATA) {
+			pr_debug("sep crypto queue hash digest\n");
+			sep_hash_update((void *)hash_req);
+			return;
+		} else if (ta_ctx->current_hash_stage == HASH_FINUP_FINISH) {
+			pr_debug("sep crypto queue hash digest\n");
+			sep_hash_final((void *)hash_req);
+			return;
+		} else {
+			pr_debug("sep crypto queue hash oops nothing\n");
+			return;
+		}
+	}
+}
+
+static int sep_sha1_init(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing sha1 init\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA1;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA1;
+	ta_ctx->current_hash_stage = HASH_INIT;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha1_update(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing sha1 update\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA1;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA1;
+	ta_ctx->current_hash_stage = HASH_UPDATE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha1_final(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha1 final\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA1;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA1;
+	ta_ctx->current_hash_stage = HASH_FINISH;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha1_digest(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha1 digest\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA1;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA1;
+	ta_ctx->current_hash_stage = HASH_DIGEST;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha1_finup(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha1 finup\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA1;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA1;
+	ta_ctx->current_hash_stage = HASH_FINUP_DATA;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_md5_init(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing md5 init\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = MD5;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_MD5;
+	ta_ctx->current_hash_stage = HASH_INIT;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_md5_update(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing md5 update\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = MD5;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_MD5;
+	ta_ctx->current_hash_stage = HASH_UPDATE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_md5_final(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing md5 final\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = MD5;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_MD5;
+	ta_ctx->current_hash_stage = HASH_FINISH;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_md5_digest(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing md5 digest\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = MD5;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_MD5;
+	ta_ctx->current_hash_stage = HASH_DIGEST;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_md5_finup(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing md5 finup\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = MD5;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_MD5;
+	ta_ctx->current_hash_stage = HASH_FINUP_DATA;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha224_init(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha224 init\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA224;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA224;
+	ta_ctx->current_hash_stage = HASH_INIT;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha224_update(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha224 update\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA224;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA224;
+	ta_ctx->current_hash_stage = HASH_UPDATE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha224_final(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha224 final\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA224;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA224;
+	ta_ctx->current_hash_stage = HASH_FINISH;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha224_digest(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing sha224 digest\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA224;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA224;
+	ta_ctx->current_hash_stage = HASH_DIGEST;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha224_finup(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing sha224 finup\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA224;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA224;
+	ta_ctx->current_hash_stage = HASH_FINUP_DATA;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha256_init(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha256 init\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA256;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA256;
+	ta_ctx->current_hash_stage = HASH_INIT;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha256_update(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha256 update\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA256;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA256;
+	ta_ctx->current_hash_stage = HASH_UPDATE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha256_final(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+	pr_debug("sep - doing sha256 final\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA256;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA256;
+	ta_ctx->current_hash_stage = HASH_FINISH;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha256_digest(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing sha256 digest\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA256;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA256;
+	ta_ctx->current_hash_stage = HASH_DIGEST;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_sha256_finup(struct ahash_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ahash_request_ctx(req);
+
+	pr_debug("sep - doing sha256 finup\n");
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = SHA256;
+	ta_ctx->current_hash_req = req;
+	ta_ctx->current_cypher_req = NULL;
+	ta_ctx->hash_opmode = SEP_HASH_SHA256;
+	ta_ctx->current_hash_stage = HASH_FINUP_DATA;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_crypto_init(struct crypto_tfm *tfm)
+{
+	const char *alg_name = crypto_tfm_alg_name(tfm);
+
+	if (alg_name == NULL)
+		pr_debug("sep_crypto_init alg is NULL\n");
+	else
+		pr_debug("sep_crypto_init alg is %s\n", alg_name);
+
+	tfm->crt_ablkcipher.reqsize = sizeof(struct this_task_ctx);
+	return 0;
+}
+
+static void sep_crypto_exit(struct crypto_tfm *tfm)
+{
+	pr_debug("sep_crypto_exit\n");
+}
+
+static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+	unsigned int keylen)
+{
+	struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm);
+
+	pr_debug("sep aes setkey\n");
+
+	pr_debug("tfm is %p sctx is %p\n", tfm, sctx);
+	switch (keylen) {
+	case SEP_AES_KEY_128_SIZE:
+		sctx->aes_key_size = AES_128;
+		break;
+	case SEP_AES_KEY_192_SIZE:
+		sctx->aes_key_size = AES_192;
+		break;
+	case SEP_AES_KEY_256_SIZE:
+		sctx->aes_key_size = AES_256;
+		break;
+	case SEP_AES_KEY_512_SIZE:
+		sctx->aes_key_size = AES_512;
+		break;
+	default:
+		pr_debug("invalid sep aes key size %x\n",
+			keylen);
+		return -EINVAL;
+	}
+
+	memset(&sctx->key.aes, 0, sizeof(u32) *
+		SEP_AES_MAX_KEY_SIZE_WORDS);
+	memcpy(&sctx->key.aes, key, keylen);
+	sctx->keylen = keylen;
+	/* Indicate to encrypt/decrypt function to send key to SEP */
+	sctx->key_sent = 0;
+
+	return 0;
+}
+
+static int sep_aes_ecb_encrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+
+	pr_debug("sep - doing aes ecb encrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = AES_ECB;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->aes_encmode = SEP_AES_ENCRYPT;
+	ta_ctx->aes_opmode = SEP_AES_ECB;
+	ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_aes_ecb_decrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+
+	pr_debug("sep - doing aes ecb decrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = AES_ECB;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->aes_encmode = SEP_AES_DECRYPT;
+	ta_ctx->aes_opmode = SEP_AES_ECB;
+	ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_aes_cbc_encrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+	struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
+		crypto_ablkcipher_reqtfm(req));
+
+	pr_debug("sep - doing aes cbc encrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n",
+		crypto_ablkcipher_reqtfm(req), sctx, ta_ctx);
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = AES_CBC;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->aes_encmode = SEP_AES_ENCRYPT;
+	ta_ctx->aes_opmode = SEP_AES_CBC;
+	ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_aes_cbc_decrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+	struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(
+		crypto_ablkcipher_reqtfm(req));
+
+	pr_debug("sep - doing aes cbc decrypt\n");
+
+	pr_debug("tfm is %p sctx is %p and ta_ctx is %p\n",
+		crypto_ablkcipher_reqtfm(req), sctx, ta_ctx);
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = AES_CBC;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->aes_encmode = SEP_AES_DECRYPT;
+	ta_ctx->aes_opmode = SEP_AES_CBC;
+	ta_ctx->init_opcode = SEP_AES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_AES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+	unsigned int keylen)
+{
+	struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm);
+	struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm);
+	u32 *flags  = &ctfm->crt_flags;
+
+	pr_debug("sep des setkey\n");
+
+	switch (keylen) {
+	case DES_KEY_SIZE:
+		sctx->des_nbr_keys = DES_KEY_1;
+		break;
+	case DES_KEY_SIZE * 2:
+		sctx->des_nbr_keys = DES_KEY_2;
+		break;
+	case DES_KEY_SIZE * 3:
+		sctx->des_nbr_keys = DES_KEY_3;
+		break;
+	default:
+		pr_debug("invalid key size %x\n",
+			keylen);
+		return -EINVAL;
+	}
+
+	if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) &&
+		(sep_weak_key(key, keylen))) {
+
+		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
+		pr_debug("weak key\n");
+		return -EINVAL;
+	}
+
+	memset(&sctx->key.des, 0, sizeof(struct sep_des_key));
+	memcpy(&sctx->key.des.key1, key, keylen);
+	sctx->keylen = keylen;
+	/* Indicate to encrypt/decrypt function to send key to SEP */
+	sctx->key_sent = 0;
+
+	return 0;
+}
+
+static int sep_des_ebc_encrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+
+	pr_debug("sep - doing des ecb encrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = DES_ECB;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->des_encmode = SEP_DES_ENCRYPT;
+	ta_ctx->des_opmode = SEP_DES_ECB;
+	ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_des_ebc_decrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+
+	pr_debug("sep - doing des ecb decrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = DES_ECB;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->des_encmode = SEP_DES_DECRYPT;
+	ta_ctx->des_opmode = SEP_DES_ECB;
+	ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_des_cbc_encrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+
+	pr_debug("sep - doing des cbc encrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = DES_CBC;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->des_encmode = SEP_DES_ENCRYPT;
+	ta_ctx->des_opmode = SEP_DES_CBC;
+	ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static int sep_des_cbc_decrypt(struct ablkcipher_request *req)
+{
+	int error;
+	int error1;
+	struct this_task_ctx *ta_ctx = ablkcipher_request_ctx(req);
+
+	pr_debug("sep - doing des ecb decrypt\n");
+
+	/* Clear out task context */
+	memset(ta_ctx, 0, sizeof(struct this_task_ctx));
+
+	ta_ctx->sep_used = sep_dev;
+	ta_ctx->current_request = DES_CBC;
+	ta_ctx->current_hash_req = NULL;
+	ta_ctx->current_cypher_req = req;
+	ta_ctx->des_encmode = SEP_DES_DECRYPT;
+	ta_ctx->des_opmode = SEP_DES_CBC;
+	ta_ctx->init_opcode = SEP_DES_INIT_OPCODE;
+	ta_ctx->block_opcode = SEP_DES_BLOCK_OPCODE;
+
+	/* lock necessary so that only one entity touches the queues */
+	spin_lock_irq(&queue_lock);
+	error = crypto_enqueue_request(&sep_queue, &req->base);
+
+	if ((error != 0) && (error != -EINPROGRESS))
+		pr_debug(" sep - crypto enqueue failed: %x\n",
+			error);
+	error1 = sep_submit_work(ta_ctx->sep_used->workqueue,
+		sep_dequeuer, (void *)&sep_queue);
+	if (error1)
+		pr_debug(" sep - workqueue submit failed: %x\n",
+			error1);
+	spin_unlock_irq(&queue_lock);
+	/* We return result of crypto enqueue */
+	return error;
+}
+
+static struct ahash_alg hash_algs[] = {
+{
+	.init		= sep_sha1_init,
+	.update		= sep_sha1_update,
+	.final		= sep_sha1_final,
+	.digest		= sep_sha1_digest,
+	.finup		= sep_sha1_finup,
+	.halg		= {
+		.digestsize	= SHA1_DIGEST_SIZE,
+		.base	= {
+		.cra_name		= "sha1",
+		.cra_driver_name	= "sha1-sep",
+		.cra_priority		= 100,
+		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_ASYNC,
+		.cra_blocksize		= SHA1_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct sep_system_ctx),
+		.cra_alignmask		= 0,
+		.cra_module		= THIS_MODULE,
+		.cra_init		= sep_hash_cra_init,
+		.cra_exit		= sep_hash_cra_exit,
+		}
+	}
+},
+{
+	.init		= sep_md5_init,
+	.update		= sep_md5_update,
+	.final		= sep_md5_final,
+	.digest		= sep_md5_digest,
+	.finup		= sep_md5_finup,
+	.halg		= {
+		.digestsize	= MD5_DIGEST_SIZE,
+		.base	= {
+		.cra_name		= "md5",
+		.cra_driver_name	= "md5-sep",
+		.cra_priority		= 100,
+		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_ASYNC,
+		.cra_blocksize		= SHA1_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct sep_system_ctx),
+		.cra_alignmask		= 0,
+		.cra_module		= THIS_MODULE,
+		.cra_init		= sep_hash_cra_init,
+		.cra_exit		= sep_hash_cra_exit,
+		}
+	}
+},
+{
+	.init		= sep_sha224_init,
+	.update		= sep_sha224_update,
+	.final		= sep_sha224_final,
+	.digest		= sep_sha224_digest,
+	.finup		= sep_sha224_finup,
+	.halg		= {
+		.digestsize	= SHA224_DIGEST_SIZE,
+		.base	= {
+		.cra_name		= "sha224",
+		.cra_driver_name	= "sha224-sep",
+		.cra_priority		= 100,
+		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_ASYNC,
+		.cra_blocksize		= SHA224_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct sep_system_ctx),
+		.cra_alignmask		= 0,
+		.cra_module		= THIS_MODULE,
+		.cra_init		= sep_hash_cra_init,
+		.cra_exit		= sep_hash_cra_exit,
+		}
+	}
+},
+{
+	.init		= sep_sha256_init,
+	.update		= sep_sha256_update,
+	.final		= sep_sha256_final,
+	.digest		= sep_sha256_digest,
+	.finup		= sep_sha256_finup,
+	.halg		= {
+		.digestsize	= SHA256_DIGEST_SIZE,
+		.base	= {
+		.cra_name		= "sha256",
+		.cra_driver_name	= "sha256-sep",
+		.cra_priority		= 100,
+		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
+						CRYPTO_ALG_ASYNC,
+		.cra_blocksize		= SHA256_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct sep_system_ctx),
+		.cra_alignmask		= 0,
+		.cra_module		= THIS_MODULE,
+		.cra_init		= sep_hash_cra_init,
+		.cra_exit		= sep_hash_cra_exit,
+		}
+	}
+}
+};
+
+static struct crypto_alg crypto_algs[] = {
+{
+	.cra_name		= "ecb(aes)",
+	.cra_driver_name	= "ecb-aes-sep",
+	.cra_priority		= 100,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct sep_system_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= sep_crypto_init,
+	.cra_exit		= sep_crypto_exit,
+	.cra_u.ablkcipher = {
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.setkey		= sep_aes_setkey,
+		.encrypt	= sep_aes_ecb_encrypt,
+		.decrypt	= sep_aes_ecb_decrypt,
+	}
+},
+{
+	.cra_name		= "cbc(aes)",
+	.cra_driver_name	= "cbc-aes-sep",
+	.cra_priority		= 100,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= AES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct sep_system_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= sep_crypto_init,
+	.cra_exit		= sep_crypto_exit,
+	.cra_u.ablkcipher = {
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.setkey		= sep_aes_setkey,
+		.encrypt	= sep_aes_cbc_encrypt,
+		.ivsize		= AES_BLOCK_SIZE,
+		.decrypt	= sep_aes_cbc_decrypt,
+	}
+},
+{
+	.cra_name		= "ebc(des)",
+	.cra_driver_name	= "ebc-des-sep",
+	.cra_priority		= 100,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= DES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct sep_system_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= sep_crypto_init,
+	.cra_exit		= sep_crypto_exit,
+	.cra_u.ablkcipher = {
+		.min_keysize	= DES_KEY_SIZE,
+		.max_keysize	= DES_KEY_SIZE,
+		.setkey		= sep_des_setkey,
+		.encrypt	= sep_des_ebc_encrypt,
+		.decrypt	= sep_des_ebc_decrypt,
+	}
+},
+{
+	.cra_name		= "cbc(des)",
+	.cra_driver_name	= "cbc-des-sep",
+	.cra_priority		= 100,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= DES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct sep_system_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= sep_crypto_init,
+	.cra_exit		= sep_crypto_exit,
+	.cra_u.ablkcipher = {
+		.min_keysize	= DES_KEY_SIZE,
+		.max_keysize	= DES_KEY_SIZE,
+		.setkey		= sep_des_setkey,
+		.encrypt	= sep_des_cbc_encrypt,
+		.ivsize		= DES_BLOCK_SIZE,
+		.decrypt	= sep_des_cbc_decrypt,
+	}
+},
+{
+	.cra_name		= "ebc(des3-ede)",
+	.cra_driver_name	= "ebc-des3-ede-sep",
+	.cra_priority		= 100,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= DES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct sep_system_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= sep_crypto_init,
+	.cra_exit		= sep_crypto_exit,
+	.cra_u.ablkcipher = {
+		.min_keysize	= DES3_EDE_KEY_SIZE,
+		.max_keysize	= DES3_EDE_KEY_SIZE,
+		.setkey		= sep_des_setkey,
+		.encrypt	= sep_des_ebc_encrypt,
+		.decrypt	= sep_des_ebc_decrypt,
+	}
+},
+{
+	.cra_name		= "cbc(des3-ede)",
+	.cra_driver_name	= "cbc-des3--ede-sep",
+	.cra_priority		= 100,
+	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+	.cra_blocksize		= DES_BLOCK_SIZE,
+	.cra_ctxsize		= sizeof(struct sep_system_ctx),
+	.cra_alignmask		= 0,
+	.cra_type		= &crypto_ablkcipher_type,
+	.cra_module		= THIS_MODULE,
+	.cra_init		= sep_crypto_init,
+	.cra_exit		= sep_crypto_exit,
+	.cra_u.ablkcipher = {
+		.min_keysize	= DES3_EDE_KEY_SIZE,
+		.max_keysize	= DES3_EDE_KEY_SIZE,
+		.setkey		= sep_des_setkey,
+		.encrypt	= sep_des_cbc_encrypt,
+		.decrypt	= sep_des_cbc_decrypt,
+	}
+}
+};
+
+int sep_crypto_setup(void)
+{
+	int err, i, j, k;
+	tasklet_init(&sep_dev->finish_tasklet, sep_finish,
+		(unsigned long)sep_dev);
+
+	crypto_init_queue(&sep_queue, SEP_QUEUE_LENGTH);
+
+	sep_dev->workqueue = create_singlethread_workqueue(
+		"sep_crypto_workqueue");
+	if (!sep_dev->workqueue) {
+		dev_warn(&sep_dev->pdev->dev, "cant create workqueue\n");
+		return -ENOMEM;
+	}
+
+	i = 0;
+	j = 0;
+
+	spin_lock_init(&queue_lock);
+
+	err = 0;
+
+	for (i = 0; i < ARRAY_SIZE(hash_algs); i++) {
+		err = crypto_register_ahash(&hash_algs[i]);
+		if (err)
+			goto err_algs;
+	}
+
+	err = 0;
+	for (j = 0; j < ARRAY_SIZE(crypto_algs); j++) {
+		err = crypto_register_alg(&crypto_algs[j]);
+		if (err)
+			goto err_crypto_algs;
+	}
+
+	return err;
+
+err_algs:
+	for (k = 0; k < i; k++)
+		crypto_unregister_ahash(&hash_algs[k]);
+	return err;
+
+err_crypto_algs:
+	for (k = 0; k < j; k++)
+		crypto_unregister_alg(&crypto_algs[k]);
+	goto err_algs;
+}
+
+void sep_crypto_takedown(void)
+{
+
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hash_algs); i++)
+		crypto_unregister_ahash(&hash_algs[i]);
+	for (i = 0; i < ARRAY_SIZE(crypto_algs); i++)
+		crypto_unregister_alg(&crypto_algs[i]);
+
+	tasklet_kill(&sep_dev->finish_tasklet);
+}
+
+#endif
diff --git a/drivers/staging/sep/sep_crypto.h b/drivers/staging/sep/sep_crypto.h
new file mode 100644
index 0000000..155c3c9
--- /dev/null
+++ b/drivers/staging/sep/sep_crypto.h
@@ -0,0 +1,359 @@
+/*
+ *
+ *  sep_crypto.h - Crypto interface structures
+ *
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2010 Discretix. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with
+ *  this program; if not, write to the Free Software Foundation, Inc., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *  Jayant Mangalampalli jayant.mangalampalli@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *  2011.02.22  Enable Kernel Crypto
+ *
+ */
+
+/* Constants for SEP (from vendor) */
+#define SEP_START_MSG_TOKEN	0x02558808
+
+#define SEP_DES_IV_SIZE_WORDS	2
+#define SEP_DES_IV_SIZE_BYTES	(SEP_DES_IV_SIZE_WORDS * \
+	sizeof(u32))
+#define SEP_DES_KEY_SIZE_WORDS	2
+#define SEP_DES_KEY_SIZE_BYTES	(SEP_DES_KEY_SIZE_WORDS * \
+	sizeof(u32))
+#define SEP_DES_BLOCK_SIZE	8
+#define SEP_DES_DUMMY_SIZE	16
+
+#define SEP_DES_INIT_OPCODE	0x10
+#define SEP_DES_BLOCK_OPCODE	0x11
+
+#define SEP_AES_BLOCK_SIZE_WORDS 4
+#define SEP_AES_BLOCK_SIZE_BYTES \
+	(SEP_AES_BLOCK_SIZE_WORDS * sizeof(u32))
+
+#define SEP_AES_DUMMY_BLOCK_SIZE 16
+#define SEP_AES_IV_SIZE_WORDS	SEP_AES_BLOCK_SIZE_WORDS
+#define SEP_AES_IV_SIZE_BYTES \
+	(SEP_AES_IV_SIZE_WORDS * sizeof(u32))
+
+#define SEP_AES_KEY_128_SIZE	16
+#define SEP_AES_KEY_192_SIZE	24
+#define SEP_AES_KEY_256_SIZE	32
+#define SEP_AES_KEY_512_SIZE	64
+#define SEP_AES_MAX_KEY_SIZE_WORDS	16
+#define SEP_AES_MAX_KEY_SIZE_BYTES \
+	(SEP_AES_MAX_KEY_SIZE_WORDS * sizeof(u32))
+
+#define SEP_AES_WRAP_MIN_SIZE	8
+#define SEP_AES_WRAP_MAX_SIZE	0x10000000
+
+#define SEP_AES_WRAP_BLOCK_SIZE_WORDS	2
+#define SEP_AES_WRAP_BLOCK_SIZE_BYTES \
+	(SEP_AES_WRAP_BLOCK_SIZE_WORDS * sizeof(u32))
+
+#define SEP_AES_SECRET_RKEK1		0x1
+#define SEP_AES_SECRET_RKEK2		0x2
+
+#define SEP_AES_INIT_OPCODE		0x2
+#define SEP_AES_BLOCK_OPCODE		0x3
+#define SEP_AES_FINISH_OPCODE		0x4
+#define SEP_AES_WRAP_OPCODE		0x6
+#define SEP_AES_UNWRAP_OPCODE		0x7
+#define SEP_AES_XTS_FINISH_OPCODE	0x8
+
+#define SEP_HASH_RESULT_SIZE_WORDS	16
+#define SEP_MD5_DIGEST_SIZE_WORDS	4
+#define SEP_MD5_DIGEST_SIZE_BYTES \
+	(SEP_MD5_DIGEST_SIZE_WORDS * sizeof(u32))
+#define SEP_SHA1_DIGEST_SIZE_WORDS	5
+#define SEP_SHA1_DIGEST_SIZE_BYTES \
+	(SEP_SHA1_DIGEST_SIZE_WORDS * sizeof(u32))
+#define SEP_SHA224_DIGEST_SIZE_WORDS	7
+#define SEP_SHA224_DIGEST_SIZE_BYTES \
+	(SEP_SHA224_DIGEST_SIZE_WORDS * sizeof(u32))
+#define SEP_SHA256_DIGEST_SIZE_WORDS	8
+#define SEP_SHA256_DIGEST_SIZE_BYTES \
+	(SEP_SHA256_DIGEST_SIZE_WORDS * sizeof(u32))
+#define SEP_SHA384_DIGEST_SIZE_WORDS	12
+#define SEP_SHA384_DIGEST_SIZE_BYTES \
+	(SEP_SHA384_DIGEST_SIZE_WORDS * sizeof(u32))
+#define SEP_SHA512_DIGEST_SIZE_WORDS	16
+#define SEP_SHA512_DIGEST_SIZE_BYTES \
+	(SEP_SHA512_DIGEST_SIZE_WORDS * sizeof(u32))
+#define SEP_HASH_BLOCK_SIZE_WORDS	16
+#define SEP_HASH_BLOCK_SIZE_BYTES \
+	(SEP_HASH_BLOCK_SIZE_WORDS * sizeof(u32))
+#define SEP_SHA2_BLOCK_SIZE_WORDS	32
+#define SEP_SHA2_BLOCK_SIZE_BYTES \
+	(SEP_SHA2_BLOCK_SIZE_WORDS * sizeof(u32))
+
+#define SEP_HASH_INIT_OPCODE		0x20
+#define SEP_HASH_UPDATE_OPCODE		0x21
+#define SEP_HASH_FINISH_OPCODE		0x22
+#define SEP_HASH_SINGLE_OPCODE		0x23
+
+#define SEP_HOST_ERROR		0x0b000000
+#define SEP_OK			0x0
+#define SEP_INVALID_START	(SEP_HOST_ERROR + 0x3)
+#define SEP_WRONG_OPCODE	(SEP_HOST_ERROR + 0x1)
+
+#define SEP_TRANSACTION_WAIT_TIME 5
+
+#define SEP_QUEUE_LENGTH	2
+/* Macros */
+#ifndef __LITTLE_ENDIAN
+#define CHG_ENDIAN(val) \
+	(((val) >> 24) | \
+	(((val) & 0x00FF0000) >> 8) | \
+	(((val) & 0x0000FF00) << 8) | \
+	(((val) & 0x000000FF) << 24))
+#else
+#define CHG_ENDIAN(val) val
+#endif
+/* Enums for SEP (from vendor) */
+enum des_numkey {
+	DES_KEY_1 = 1,
+	DES_KEY_2 = 2,
+	DES_KEY_3 = 3,
+	SEP_NUMKEY_OPTIONS,
+	SEP_NUMKEY_LAST = 0x7fffffff,
+};
+
+enum des_enc_mode {
+	SEP_DES_ENCRYPT = 0,
+	SEP_DES_DECRYPT = 1,
+	SEP_DES_ENC_OPTIONS,
+	SEP_DES_ENC_LAST = 0x7fffffff,
+};
+
+enum des_op_mode {
+	SEP_DES_ECB = 0,
+	SEP_DES_CBC = 1,
+	SEP_OP_OPTIONS,
+	SEP_OP_LAST = 0x7fffffff,
+};
+
+enum aes_keysize {
+	AES_128 = 0,
+	AES_192 = 1,
+	AES_256 = 2,
+	AES_512 = 3,
+	AES_SIZE_OPTIONS,
+	AEA_SIZE_LAST = 0x7FFFFFFF,
+};
+
+enum aes_enc_mode {
+	SEP_AES_ENCRYPT = 0,
+	SEP_AES_DECRYPT = 1,
+	SEP_AES_ENC_OPTIONS,
+	SEP_AES_ENC_LAST = 0x7FFFFFFF,
+};
+
+enum aes_op_mode {
+	SEP_AES_ECB = 0,
+	SEP_AES_CBC = 1,
+	SEP_AES_MAC = 2,
+	SEP_AES_CTR = 3,
+	SEP_AES_XCBC = 4,
+	SEP_AES_CMAC = 5,
+	SEP_AES_XTS = 6,
+	SEP_AES_OP_OPTIONS,
+	SEP_AES_OP_LAST = 0x7FFFFFFF,
+};
+
+enum hash_op_mode {
+	SEP_HASH_SHA1 = 0,
+	SEP_HASH_SHA224 = 1,
+	SEP_HASH_SHA256 = 2,
+	SEP_HASH_SHA384 = 3,
+	SEP_HASH_SHA512 = 4,
+	SEP_HASH_MD5 = 5,
+	SEP_HASH_OPTIONS,
+	SEP_HASH_LAST_MODE = 0x7FFFFFFF,
+};
+
+/* Structures for SEP (from vendor) */
+struct sep_des_internal_key {
+	u32 key1[SEP_DES_KEY_SIZE_WORDS];
+	u32 key2[SEP_DES_KEY_SIZE_WORDS];
+	u32 key3[SEP_DES_KEY_SIZE_WORDS];
+};
+
+struct sep_des_internal_context {
+	u32 iv_context[SEP_DES_IV_SIZE_WORDS];
+	struct sep_des_internal_key context_key;
+	enum des_numkey nbr_keys;
+	enum des_enc_mode encryption;
+	enum des_op_mode operation;
+	u8 dummy_block[SEP_DES_DUMMY_SIZE];
+};
+
+struct sep_des_private_context {
+	u32 valid_tag;
+	u32 iv;
+	u8 ctx_buf[sizeof(struct sep_des_internal_context)];
+};
+
+/* This is the structure passed to SEP via msg area */
+struct sep_des_key {
+	u32 key1[SEP_DES_KEY_SIZE_WORDS];
+	u32 key2[SEP_DES_KEY_SIZE_WORDS];
+	u32 key3[SEP_DES_KEY_SIZE_WORDS];
+	u32 pad[SEP_DES_KEY_SIZE_WORDS];
+};
+
+struct sep_aes_internal_context {
+	u32 aes_ctx_iv[SEP_AES_IV_SIZE_WORDS];
+	u32 aes_ctx_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2];
+	enum aes_keysize keysize;
+	enum aes_enc_mode encmode;
+	enum aes_op_mode opmode;
+	u8 secret_key;
+	u32 no_add_blocks;
+	u32 last_block_size;
+	u32 last_block[SEP_AES_BLOCK_SIZE_WORDS];
+	u32 prev_iv[SEP_AES_BLOCK_SIZE_WORDS];
+	u32 remaining_size;
+	union {
+		struct {
+			u32 dkey1[SEP_AES_BLOCK_SIZE_WORDS];
+			u32 dkey2[SEP_AES_BLOCK_SIZE_WORDS];
+			u32 dkey3[SEP_AES_BLOCK_SIZE_WORDS];
+		} cmac_data;
+		struct {
+			u32 xts_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2];
+			u32 temp1[SEP_AES_BLOCK_SIZE_WORDS];
+			u32 temp2[SEP_AES_BLOCK_SIZE_WORDS];
+		} xtx_data;
+	} s_data;
+	u8 dummy_block[SEP_AES_DUMMY_BLOCK_SIZE];
+};
+
+struct sep_aes_private_context {
+	u32 valid_tag;
+	u32 aes_iv;
+	u32 op_mode;
+	u8 cbuff[sizeof(struct sep_aes_internal_context)];
+};
+
+struct sep_hash_internal_context {
+	u32 hash_result[SEP_HASH_RESULT_SIZE_WORDS];
+	enum hash_op_mode hash_opmode;
+	u32 previous_data[SEP_SHA2_BLOCK_SIZE_WORDS];
+	u16 prev_update_bytes;
+	u32 total_proc_128bit[4];
+	u16 op_mode_block_size;
+	u8 dummy_aes_block[SEP_AES_DUMMY_BLOCK_SIZE];
+};
+
+struct sep_hash_private_context {
+	u32 valid_tag;
+	u32 iv;
+	u8 internal_context[sizeof(struct sep_hash_internal_context)];
+};
+
+union key_t {
+	struct sep_des_key des;
+	u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS];
+};
+
+/* Context structures for crypto API */
+/**
+ * Structure for this current task context
+ * This same structure is used for both hash
+ * and crypt in order to reduce duplicate code
+ * for stuff that is done for both hash operations
+ * and crypto operations. We cannot trust that the
+ * system context is not pulled out from under
+ * us during operation to operation, so all
+ * critical stuff such as data pointers must
+ * be in in a context that is exclusive for this
+ * particular task at hand.
+ */
+struct this_task_ctx {
+	struct sep_device *sep_used;
+	u32 done;
+	unsigned char iv[100];
+	enum des_enc_mode des_encmode;
+	enum des_op_mode des_opmode;
+	enum aes_enc_mode aes_encmode;
+	enum aes_op_mode aes_opmode;
+	u32 init_opcode;
+	u32 block_opcode;
+	size_t data_length;
+	size_t ivlen;
+	struct ablkcipher_walk walk;
+	int i_own_sep; /* Do I have custody of the sep? */
+	struct sep_call_status call_status;
+	struct build_dcb_struct_kernel dcb_input_data;
+	struct sep_dma_context *dma_ctx;
+	void *dmatables_region;
+	size_t nbytes;
+	struct sep_dcblock *dcb_region;
+	struct sep_queue_info *queue_elem;
+	int msg_len_words;
+	unsigned char msg[SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES];
+	void *msgptr;
+	struct scatterlist *src_sg;
+	struct scatterlist *dst_sg;
+	struct scatterlist *src_sg_hold;
+	struct scatterlist *dst_sg_hold;
+	struct ahash_request *current_hash_req;
+	struct ablkcipher_request *current_cypher_req;
+	enum type_of_request current_request;
+	int digest_size_words;
+	int digest_size_bytes;
+	int block_size_words;
+	int block_size_bytes;
+	enum hash_op_mode hash_opmode;
+	enum hash_stage current_hash_stage;
+	/**
+	 * Not that this is a pointer. The are_we_done_yet variable is
+	 * allocated by the task function. This way, even if the kernel
+	 * crypto infrastructure has grabbed the task structure out from
+	 * under us, the task function can still see this variable.
+	 */
+	int *are_we_done_yet;
+	unsigned long end_time;
+	};
+
+struct sep_system_ctx {
+	union key_t key;
+	size_t keylen;
+	int key_sent;
+	enum des_numkey des_nbr_keys;
+	enum aes_keysize aes_key_size;
+	unsigned long end_time;
+	struct sep_des_private_context des_private_ctx;
+	struct sep_aes_private_context aes_private_ctx;
+	struct sep_hash_private_context hash_private_ctx;
+	};
+
+/* work queue structures */
+struct sep_work_struct {
+	struct work_struct work;
+	void (*callback)(void *);
+	void *data;
+	};
+
+/* Functions */
+int sep_crypto_setup(void);
+void sep_crypto_takedown(void);
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h
index 696ab0d..5f6a07f 100644
--- a/drivers/staging/sep/sep_dev.h
+++ b/drivers/staging/sep/sep_dev.h
@@ -5,8 +5,8 @@
  *
  *  sep_dev.h - Security Processor Device Structures
  *
- *  Copyright(c) 2009,2010 Intel Corporation. All rights reserved.
- *  Contributions(c) 2009,2010 Discretix. All rights reserved.
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2011 Discretix. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the Free
@@ -28,6 +28,7 @@
  *
  *  CHANGES
  *  2010.09.14  upgrade to Medfield
+ *  2011.02.22  enable kernel crypto
  */
 
 struct sep_device {
@@ -36,33 +37,21 @@ struct sep_device {
 
 	/* character device file */
 	struct cdev sep_cdev;
-	struct cdev sep_daemon_cdev;
-	struct cdev sep_singleton_cdev;
 
 	/* devices (using misc dev) */
 	struct miscdevice miscdev_sep;
-	struct miscdevice miscdev_singleton;
-	struct miscdevice miscdev_daemon;
 
 	/* major / minor numbers of device */
 	dev_t sep_devno;
-	dev_t sep_daemon_devno;
-	dev_t sep_singleton_devno;
-
-	struct mutex sep_mutex;
-	struct mutex ioctl_mutex;
+	/* guards command sent counter */
 	spinlock_t snd_rply_lck;
+	/* guards driver memory usage in fastcall if */
+	struct semaphore sep_doublebuf;
 
 	/* flags to indicate use and lock status of sep */
 	u32 pid_doing_transaction;
 	unsigned long in_use_flags;
 
-	/* request daemon alread open */
-	unsigned long request_daemon_open;
-
-	/* 1 = Moorestown; 0 = Medfield */
-	int mrst;
-
 	/* address of the shared memory allocated during init for SEP driver
 	   (coherent alloc) */
 	dma_addr_t shared_bus;
@@ -74,36 +63,77 @@ struct sep_device {
 	dma_addr_t reg_physical_end;
 	void __iomem *reg_addr;
 
-	/* wait queue head (event) of the driver */
-	wait_queue_head_t event;
-	wait_queue_head_t event_request_daemon;
-	wait_queue_head_t event_mmap;
+	/* wait queue heads of the driver */
+	wait_queue_head_t event_interrupt;
+	wait_queue_head_t event_transactions;
 
-	struct sep_caller_id_entry
-		caller_id_table[SEP_CALLER_ID_TABLE_NUM_ENTRIES];
+	struct list_head sep_queue_status;
+	u32 sep_queue_num;
+	spinlock_t sep_queue_lock;
 
-	/* access flag for singleton device */
-	unsigned long singleton_access_flag;
+	/* Is this in use? */
+	u32 in_use;
+
+	/* indicates whether power save is set up */
+	u32 power_save_setup;
+
+	/* Power state */
+	u32 power_state;
 
 	/* transaction counter that coordinates the
 	   transactions between SEP and HOST */
 	unsigned long send_ct;
 	/* counter for the messages from sep */
 	unsigned long reply_ct;
-	/* counter for the number of bytes allocated in the pool for the
-	   current transaction */
-	long data_pool_bytes_allocated;
 
-	u32 num_of_data_allocations;
+	/* The following are used for kernel crypto client requests */
+	u32 in_kernel; /* Set for kernel client request */
+	struct tasklet_struct	finish_tasklet;
+	enum type_of_request current_request;
+	enum hash_stage	current_hash_stage;
+	struct ahash_request	*current_hash_req;
+	struct ablkcipher_request *current_cypher_req;
+	struct this_task_ctx *ta_ctx;
+	struct workqueue_struct	*workqueue;
+};
 
-	/* number of the lli tables created in the current transaction */
-	u32     num_lli_tables_created;
+extern struct sep_device *sep_dev;
 
-	/* number of data control blocks */
-	u32 nr_dcb_creat;
+/**
+ * SEP message header for a transaction
+ * @reserved: reserved memory (two words)
+ * @token: SEP message token
+ * @msg_len: message length
+ * @opcpde: message opcode
+ */
+struct sep_msgarea_hdr {
+	u32 reserved[2];
+	u32 token;
+	u32 msg_len;
+	u32 opcode;
+};
 
-	struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS];
+/**
+ * sep_queue_data - data to be maintained in status queue for a transaction
+ * @opcode : transaction opcode
+ * @size : message size
+ * @pid: owner process
+ * @name: owner process name
+ */
+struct sep_queue_data {
+	u32 opcode;
+	u32 size;
+	s32 pid;
+	u8 name[TASK_COMM_LEN];
+};
 
+/** sep_queue_info - maintains status info of all transactions
+ * @list: head of list
+ * @sep_queue_data : data for transaction
+ */
+struct sep_queue_info {
+	struct list_head list;
+	struct sep_queue_data data;
 };
 
 static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
deleted file mode 100644
index 6b3d156..0000000
--- a/drivers/staging/sep/sep_driver.c
+++ /dev/null
@@ -1,2932 +0,0 @@
-/*
- *
- *  sep_driver.c - Security Processor Driver main group of functions
- *
- *  Copyright(c) 2009,2010 Intel Corporation. All rights reserved.
- *  Contributions(c) 2009,2010 Discretix. All rights reserved.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  You should have received a copy of the GNU General Public License along with
- *  this program; if not, write to the Free Software Foundation, Inc., 59
- *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- *  CONTACTS:
- *
- *  Mark Allyn		mark.a.allyn@intel.com
- *  Jayant Mangalampalli jayant.mangalampalli@intel.com
- *
- *  CHANGES:
- *
- *  2009.06.26	Initial publish
- *  2010.09.14  Upgrade to Medfield
- *
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/kdev_t.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/wait.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <linux/ioctl.h>
-#include <asm/current.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/pagemap.h>
-#include <asm/cacheflush.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/rar_register.h>
-
-#include "sep_driver_hw_defs.h"
-#include "sep_driver_config.h"
-#include "sep_driver_api.h"
-#include "sep_dev.h"
-
-/*----------------------------------------
-	DEFINES
------------------------------------------*/
-
-#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
-
-/*--------------------------------------------
-	GLOBAL variables
---------------------------------------------*/
-
-/* Keep this a single static object for now to keep the conversion easy */
-
-static struct sep_device *sep_dev;
-
-/**
- *	sep_dump_message - dump the message that is pending
- *	@sep: SEP device
- */
-static void sep_dump_message(struct sep_device *sep)
-{
-	int count;
-	u32 *p = sep->shared_addr;
-	for (count = 0; count < 12 * 4; count += 4)
-		dev_dbg(&sep->pdev->dev, "Word %d of the message is %x\n",
-								count, *p++);
-}
-
-/**
- *	sep_map_and_alloc_shared_area -	allocate shared block
- *	@sep: security processor
- *	@size: size of shared area
- */
-static int sep_map_and_alloc_shared_area(struct sep_device *sep)
-{
-	sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev,
-		sep->shared_size,
-		&sep->shared_bus, GFP_KERNEL);
-
-	if (!sep->shared_addr) {
-		dev_warn(&sep->pdev->dev,
-			"shared memory dma_alloc_coherent failed\n");
-		return -ENOMEM;
-	}
-	dev_dbg(&sep->pdev->dev,
-		"shared_addr %zx bytes @%p (bus %llx)\n",
-				sep->shared_size, sep->shared_addr,
-				(unsigned long long)sep->shared_bus);
-	return 0;
-}
-
-/**
- *	sep_unmap_and_free_shared_area - free shared block
- *	@sep: security processor
- */
-static void sep_unmap_and_free_shared_area(struct sep_device *sep)
-{
-	dma_free_coherent(&sep->pdev->dev, sep->shared_size,
-				sep->shared_addr, sep->shared_bus);
-}
-
-/**
- *	sep_shared_bus_to_virt - convert bus/virt addresses
- *	@sep: pointer to struct sep_device
- *	@bus_address: address to convert
- *
- *	Returns virtual address inside the shared area according
- *	to the bus address.
- */
-static void *sep_shared_bus_to_virt(struct sep_device *sep,
-						dma_addr_t bus_address)
-{
-	return sep->shared_addr + (bus_address - sep->shared_bus);
-}
-
-/**
- *	open function for the singleton driver
- *	@inode_ptr struct inode *
- *	@file_ptr struct file *
- *
- *	Called when the user opens the singleton device interface
- */
-static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr)
-{
-	struct sep_device *sep;
-
-	/*
-	 * Get the SEP device structure and use it for the
-	 * private_data field in filp for other methods
-	 */
-	sep = sep_dev;
-
-	file_ptr->private_data = sep;
-
-	if (test_and_set_bit(0, &sep->singleton_access_flag))
-		return -EBUSY;
-	return 0;
-}
-
-/**
- *	sep_open - device open method
- *	@inode: inode of SEP device
- *	@filp: file handle to SEP device
- *
- *	Open method for the SEP device. Called when userspace opens
- *	the SEP device node.
- *
- *	Returns zero on success otherwise an error code.
- */
-static int sep_open(struct inode *inode, struct file *filp)
-{
-	struct sep_device *sep;
-
-	/*
-	 * Get the SEP device structure and use it for the
-	 * private_data field in filp for other methods
-	 */
-	sep = sep_dev;
-	filp->private_data = sep;
-
-	/* Anyone can open; locking takes place at transaction level */
-	return 0;
-}
-
-/**
- *	sep_singleton_release - close a SEP singleton device
- *	@inode: inode of SEP device
- *	@filp: file handle being closed
- *
- *	Called on the final close of a SEP device. As the open protects against
- *	multiple simultaenous opens that means this method is called when the
- *	final reference to the open handle is dropped.
- */
-static int sep_singleton_release(struct inode *inode, struct file *filp)
-{
-	struct sep_device *sep = filp->private_data;
-
-	clear_bit(0, &sep->singleton_access_flag);
-	return 0;
-}
-
-/**
- *	sep_request_daemon_open - request daemon open method
- *	@inode: inode of SEP device
- *	@filp: file handle to SEP device
- *
- *	Open method for the SEP request daemon. Called when
- *	request daemon in userspace opens the SEP device node.
- *
- *	Returns zero on success otherwise an error code.
- */
-static int sep_request_daemon_open(struct inode *inode, struct file *filp)
-{
-	struct sep_device *sep = sep_dev;
-	int error = 0;
-
-	filp->private_data = sep;
-
-	/* There is supposed to be only one request daemon */
-	if (test_and_set_bit(0, &sep->request_daemon_open))
-		error = -EBUSY;
-	return error;
-}
-
-/**
- *	sep_request_daemon_release - close a SEP daemon
- *	@inode: inode of SEP device
- *	@filp: file handle being closed
- *
- *	Called on the final close of a SEP daemon.
- */
-static int sep_request_daemon_release(struct inode *inode, struct file *filp)
-{
-	struct sep_device *sep = filp->private_data;
-
-	dev_dbg(&sep->pdev->dev, "Request daemon release for pid %d\n",
-		current->pid);
-
-	/* Clear the request_daemon_open flag */
-	clear_bit(0, &sep->request_daemon_open);
-	return 0;
-}
-
-/**
- *	sep_req_daemon_send_reply_command_handler - poke the SEP
- *	@sep: struct sep_device *
- *
- *	This function raises interrupt to SEPm that signals that is has a
- *	new command from HOST
- */
-static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep)
-{
-	unsigned long lck_flags;
-
-	sep_dump_message(sep);
-
-	/* Counters are lockable region */
-	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
-	sep->send_ct++;
-	sep->reply_ct++;
-
-	/* Send the interrupt to SEP */
-	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
-	sep->send_ct++;
-
-	spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-
-	dev_dbg(&sep->pdev->dev,
-		"sep_req_daemon_send_reply send_ct %lx reply_ct %lx\n",
-		sep->send_ct, sep->reply_ct);
-
-	return 0;
-}
-
-
-/**
- *	sep_free_dma_table_data_handler - free DMA table
- *	@sep: pointere to struct sep_device
- *
- *	Handles the request to  free DMA table for synchronic actions
- */
-static int sep_free_dma_table_data_handler(struct sep_device *sep)
-{
-	int count;
-	int dcb_counter;
-	/* Pointer to the current dma_resource struct */
-	struct sep_dma_resource *dma;
-
-	for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) {
-		dma = &sep->dma_res_arr[dcb_counter];
-
-		/* Unmap and free input map array */
-		if (dma->in_map_array) {
-			for (count = 0; count < dma->in_num_pages; count++) {
-				dma_unmap_page(&sep->pdev->dev,
-					dma->in_map_array[count].dma_addr,
-					dma->in_map_array[count].size,
-					DMA_TO_DEVICE);
-			}
-			kfree(dma->in_map_array);
-		}
-
-		/* Unmap output map array, DON'T free it yet */
-		if (dma->out_map_array) {
-			for (count = 0; count < dma->out_num_pages; count++) {
-				dma_unmap_page(&sep->pdev->dev,
-					dma->out_map_array[count].dma_addr,
-					dma->out_map_array[count].size,
-					DMA_FROM_DEVICE);
-			}
-			kfree(dma->out_map_array);
-		}
-
-		/* Free page cache for output */
-		if (dma->in_page_array) {
-			for (count = 0; count < dma->in_num_pages; count++) {
-				flush_dcache_page(dma->in_page_array[count]);
-				page_cache_release(dma->in_page_array[count]);
-			}
-			kfree(dma->in_page_array);
-		}
-
-		if (dma->out_page_array) {
-			for (count = 0; count < dma->out_num_pages; count++) {
-				if (!PageReserved(dma->out_page_array[count]))
-					SetPageDirty(dma->out_page_array[count]);
-				flush_dcache_page(dma->out_page_array[count]);
-				page_cache_release(dma->out_page_array[count]);
-			}
-			kfree(dma->out_page_array);
-		}
-
-		/* Reset all the values */
-		dma->in_page_array = NULL;
-		dma->out_page_array = NULL;
-		dma->in_num_pages = 0;
-		dma->out_num_pages = 0;
-		dma->in_map_array = NULL;
-		dma->out_map_array = NULL;
-		dma->in_map_num_entries = 0;
-		dma->out_map_num_entries = 0;
-	}
-
-	sep->nr_dcb_creat = 0;
-	sep->num_lli_tables_created = 0;
-
-	return 0;
-}
-
-/**
- *	sep_request_daemon_mmap - maps the shared area to user space
- *	@filp: pointer to struct file
- *	@vma: pointer to vm_area_struct
- *
- *	Called by the kernel when the daemon attempts an mmap() syscall
- *	using our handle.
- */
-static int sep_request_daemon_mmap(struct file  *filp,
-	struct vm_area_struct  *vma)
-{
-	struct sep_device *sep = filp->private_data;
-	dma_addr_t bus_address;
-	int error = 0;
-
-	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
-		error = -EINVAL;
-		goto end_function;
-	}
-
-	/* Get physical address */
-	bus_address = sep->shared_bus;
-
-	if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT,
-		vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
-
-		dev_warn(&sep->pdev->dev, "remap_page_range failed\n");
-		error = -EAGAIN;
-		goto end_function;
-	}
-
-end_function:
-	return error;
-}
-
-/**
- *	sep_request_daemon_poll - poll implementation
- *	@sep: struct sep_device * for current SEP device
- *	@filp: struct file * for open file
- *	@wait: poll_table * for poll
- *
- *	Called when our device is part of a poll() or select() syscall
- */
-static unsigned int sep_request_daemon_poll(struct file *filp,
-	poll_table  *wait)
-{
-	u32	mask = 0;
-	/* GPR2 register */
-	u32	retval2;
-	unsigned long lck_flags;
-	struct sep_device *sep = filp->private_data;
-
-	poll_wait(filp, &sep->event_request_daemon, wait);
-
-	dev_dbg(&sep->pdev->dev, "daemon poll: send_ct is %lx reply ct is %lx\n",
-						sep->send_ct, sep->reply_ct);
-
-	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
-	/* Check if the data is ready */
-	if (sep->send_ct == sep->reply_ct) {
-		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-
-		retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
-		dev_dbg(&sep->pdev->dev,
-			"daemon poll: data check (GPR2) is %x\n", retval2);
-
-		/* Check if PRINT request */
-		if ((retval2 >> 30) & 0x1) {
-			dev_dbg(&sep->pdev->dev, "daemon poll: PRINTF request in\n");
-			mask |= POLLIN;
-			goto end_function;
-		}
-		/* Check if NVS request */
-		if (retval2 >> 31) {
-			dev_dbg(&sep->pdev->dev, "daemon poll: NVS request in\n");
-			mask |= POLLPRI | POLLWRNORM;
-		}
-	} else {
-		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-		dev_dbg(&sep->pdev->dev,
-			"daemon poll: no reply received; returning 0\n");
-		mask = 0;
-	}
-end_function:
-	return mask;
-}
-
-/**
- *	sep_release - close a SEP device
- *	@inode: inode of SEP device
- *	@filp: file handle being closed
- *
- *	Called on the final close of a SEP device.
- */
-static int sep_release(struct inode *inode, struct file *filp)
-{
-	struct sep_device *sep = filp->private_data;
-
-	dev_dbg(&sep->pdev->dev, "Release for pid %d\n", current->pid);
-
-	mutex_lock(&sep->sep_mutex);
-	/* Is this the process that has a transaction open?
-	 * If so, lets reset pid_doing_transaction to 0 and
-	 * clear the in use flags, and then wake up sep_event
-	 * so that other processes can do transactions
-	 */
-	if (sep->pid_doing_transaction == current->pid) {
-		clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags);
-		clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags);
-		sep_free_dma_table_data_handler(sep);
-		wake_up(&sep->event);
-		sep->pid_doing_transaction = 0;
-	}
-
-	mutex_unlock(&sep->sep_mutex);
-	return 0;
-}
-
-/**
- *	sep_mmap -  maps the shared area to user space
- *	@filp: pointer to struct file
- *	@vma: pointer to vm_area_struct
- *
- *	Called on an mmap of our space via the normal SEP device
- */
-static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	dma_addr_t bus_addr;
-	struct sep_device *sep = filp->private_data;
-	unsigned long error = 0;
-
-	/* Set the transaction busy (own the device) */
-	wait_event_interruptible(sep->event,
-		test_and_set_bit(SEP_MMAP_LOCK_BIT,
-		&sep->in_use_flags) == 0);
-
-	if (signal_pending(current)) {
-		error = -EINTR;
-		goto end_function_with_error;
-	}
-	/*
-	 * The pid_doing_transaction indicates that this process
-	 * now owns the facilities to performa a transaction with
-	 * the SEP. While this process is performing a transaction,
-	 * no other process who has the SEP device open can perform
-	 * any transactions. This method allows more than one process
-	 * to have the device open at any given time, which provides
-	 * finer granularity for device utilization by multiple
-	 * processes.
-	 */
-	mutex_lock(&sep->sep_mutex);
-	sep->pid_doing_transaction = current->pid;
-	mutex_unlock(&sep->sep_mutex);
-
-	/* Zero the pools and the number of data pool alocation pointers */
-	sep->data_pool_bytes_allocated = 0;
-	sep->num_of_data_allocations = 0;
-
-	/*
-	 * Check that the size of the mapped range is as the size of the message
-	 * shared area
-	 */
-	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
-		error = -EINVAL;
-		goto end_function_with_error;
-	}
-
-	dev_dbg(&sep->pdev->dev, "shared_addr is %p\n", sep->shared_addr);
-
-	/* Get bus address */
-	bus_addr = sep->shared_bus;
-
-	if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT,
-		vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
-		dev_warn(&sep->pdev->dev, "remap_page_range failed\n");
-		error = -EAGAIN;
-		goto end_function_with_error;
-	}
-	goto end_function;
-
-end_function_with_error:
-	/* Clear the bit */
-	clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags);
-	mutex_lock(&sep->sep_mutex);
-	sep->pid_doing_transaction = 0;
-	mutex_unlock(&sep->sep_mutex);
-
-	/* Raise event for stuck contextes */
-
-	wake_up(&sep->event);
-
-end_function:
-	return error;
-}
-
-/**
- *	sep_poll - poll handler
- *	@filp: pointer to struct file
- *	@wait: pointer to poll_table
- *
- *	Called by the OS when the kernel is asked to do a poll on
- *	a SEP file handle.
- */
-static unsigned int sep_poll(struct file *filp, poll_table *wait)
-{
-	u32 mask = 0;
-	u32 retval = 0;
-	u32 retval2 = 0;
-	unsigned long lck_flags;
-
-	struct sep_device *sep = filp->private_data;
-
-	/* Am I the process that owns the transaction? */
-	mutex_lock(&sep->sep_mutex);
-	if (current->pid != sep->pid_doing_transaction) {
-		dev_dbg(&sep->pdev->dev, "poll; wrong pid\n");
-		mask = POLLERR;
-		mutex_unlock(&sep->sep_mutex);
-		goto end_function;
-	}
-	mutex_unlock(&sep->sep_mutex);
-
-	/* Check if send command or send_reply were activated previously */
-	if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) {
-		mask = POLLERR;
-		goto end_function;
-	}
-
-	/* Add the event to the polling wait table */
-	dev_dbg(&sep->pdev->dev, "poll: calling wait sep_event\n");
-
-	poll_wait(filp, &sep->event, wait);
-
-	dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n",
-		sep->send_ct, sep->reply_ct);
-
-	/* Check if error occurred during poll */
-	retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
-	if (retval2 != 0x0) {
-		dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2);
-		mask |= POLLERR;
-		goto end_function;
-	}
-
-	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
-
-	if (sep->send_ct == sep->reply_ct) {
-		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-		retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
-		dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2)  %x\n",
-			retval);
-
-		/* Check if printf request  */
-		if ((retval >> 30) & 0x1) {
-			dev_dbg(&sep->pdev->dev, "poll: SEP printf request\n");
-			wake_up(&sep->event_request_daemon);
-			goto end_function;
-		}
-
-		/* Check if the this is SEP reply or request */
-		if (retval >> 31) {
-			dev_dbg(&sep->pdev->dev, "poll: SEP request\n");
-			wake_up(&sep->event_request_daemon);
-		} else {
-			dev_dbg(&sep->pdev->dev, "poll: normal return\n");
-			/* In case it is again by send_reply_comand */
-			clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags);
-			sep_dump_message(sep);
-			dev_dbg(&sep->pdev->dev,
-				"poll; SEP reply POLLIN | POLLRDNORM\n");
-			mask |= POLLIN | POLLRDNORM;
-		}
-	} else {
-		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-		dev_dbg(&sep->pdev->dev,
-			"poll; no reply received; returning mask of 0\n");
-		mask = 0;
-	}
-
-end_function:
-	return mask;
-}
-
-/**
- *	sep_time_address - address in SEP memory of time
- *	@sep: SEP device we want the address from
- *
- *	Return the address of the two dwords in memory used for time
- *	setting.
- */
-static u32 *sep_time_address(struct sep_device *sep)
-{
-	return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
-}
-
-/**
- *	sep_set_time - set the SEP time
- *	@sep: the SEP we are setting the time for
- *
- *	Calculates time and sets it at the predefined address.
- *	Called with the SEP mutex held.
- */
-static unsigned long sep_set_time(struct sep_device *sep)
-{
-	struct timeval time;
-	u32 *time_addr;	/* Address of time as seen by the kernel */
-
-
-	do_gettimeofday(&time);
-
-	/* Set value in the SYSTEM MEMORY offset */
-	time_addr = sep_time_address(sep);
-
-	time_addr[0] = SEP_TIME_VAL_TOKEN;
-	time_addr[1] = time.tv_sec;
-
-	dev_dbg(&sep->pdev->dev, "time.tv_sec is %lu\n", time.tv_sec);
-	dev_dbg(&sep->pdev->dev, "time_addr is %p\n", time_addr);
-	dev_dbg(&sep->pdev->dev, "sep->shared_addr is %p\n", sep->shared_addr);
-
-	return time.tv_sec;
-}
-
-/**
- *	sep_set_caller_id_handler - insert caller id entry
- *	@sep: SEP device
- *	@arg: pointer to struct caller_id_struct
- *
- *	Inserts the data into the caller id table. Note that this function
- *	falls under the ioctl lock
- */
-static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg)
-{
-	void __user *hash;
-	int   error = 0;
-	int   i;
-	struct caller_id_struct command_args;
-
-	for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) {
-		if (sep->caller_id_table[i].pid == 0)
-			break;
-	}
-
-	if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) {
-		dev_dbg(&sep->pdev->dev, "no more caller id entries left\n");
-		dev_dbg(&sep->pdev->dev, "maximum number is %d\n",
-					SEP_CALLER_ID_TABLE_NUM_ENTRIES);
-		error = -EUSERS;
-		goto end_function;
-	}
-
-	/* Copy the data */
-	if (copy_from_user(&command_args, (void __user *)arg,
-		sizeof(command_args))) {
-		error = -EFAULT;
-		goto end_function;
-	}
-
-	hash = (void __user *)(unsigned long)command_args.callerIdAddress;
-
-	if (!command_args.pid || !command_args.callerIdSizeInBytes) {
-		error = -EINVAL;
-		goto end_function;
-	}
-
-	dev_dbg(&sep->pdev->dev, "pid is %x\n", command_args.pid);
-	dev_dbg(&sep->pdev->dev, "callerIdSizeInBytes is %x\n",
-		command_args.callerIdSizeInBytes);
-
-	if (command_args.callerIdSizeInBytes >
-					SEP_CALLER_ID_HASH_SIZE_IN_BYTES) {
-		error = -EMSGSIZE;
-		goto end_function;
-	}
-
-	sep->caller_id_table[i].pid = command_args.pid;
-
-	if (copy_from_user(sep->caller_id_table[i].callerIdHash,
-		hash, command_args.callerIdSizeInBytes))
-		error = -EFAULT;
-end_function:
-	return error;
-}
-
-/**
- *	sep_set_current_caller_id - set the caller id
- *	@sep: pointer to struct_sep_device
- *
- *	Set the caller ID (if it exists) to the SEP. Note that this
- *	function falls under the ioctl lock
- */
-static int sep_set_current_caller_id(struct sep_device *sep)
-{
-	int i;
-	u32 *hash_buf_ptr;
-
-	/* Zero the previous value */
-	memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES,
-					0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES);
-
-	for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) {
-		if (sep->caller_id_table[i].pid == current->pid) {
-			dev_dbg(&sep->pdev->dev, "Caller Id found\n");
-
-			memcpy(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES,
-				(void *)(sep->caller_id_table[i].callerIdHash),
-				SEP_CALLER_ID_HASH_SIZE_IN_BYTES);
-			break;
-		}
-	}
-	/* Ensure data is in little endian */
-	hash_buf_ptr = (u32 *)sep->shared_addr +
-		SEP_CALLER_ID_OFFSET_BYTES;
-
-	for (i = 0; i < SEP_CALLER_ID_HASH_SIZE_IN_WORDS; i++)
-		hash_buf_ptr[i] = cpu_to_le32(hash_buf_ptr[i]);
-
-	return 0;
-}
-
-/**
- *	sep_send_command_handler - kick off a command
- *	@sep: SEP being signalled
- *
- *	This function raises interrupt to SEP that signals that is has a new
- *	command from the host
- *
- *      Note that this function does fall under the ioctl lock
- */
-static int sep_send_command_handler(struct sep_device *sep)
-{
-	unsigned long lck_flags;
-	int error = 0;
-
-	if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) {
-		error = -EPROTO;
-		goto end_function;
-	}
-	sep_set_time(sep);
-
-	sep_set_current_caller_id(sep);
-
-	sep_dump_message(sep);
-
-	/* Update counter */
-	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
-	sep->send_ct++;
-	spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-
-	dev_dbg(&sep->pdev->dev,
-		"sep_send_command_handler send_ct %lx reply_ct %lx\n",
-						sep->send_ct, sep->reply_ct);
-
-	/* Send interrupt to SEP */
-	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
-
-end_function:
-	return error;
-}
-
-/**
- *	sep_allocate_data_pool_memory_handler -allocate pool memory
- *	@sep: pointer to struct sep_device
- *	@arg: pointer to struct alloc_struct
- *
- *	This function handles the allocate data pool memory request
- *	This function returns calculates the bus address of the
- *	allocated memory, and the offset of this area from the mapped address.
- *	Therefore, the FVOs in user space can calculate the exact virtual
- *	address of this allocated memory
- */
-static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
-	unsigned long arg)
-{
-	int error = 0;
-	struct alloc_struct command_args;
-
-	/* Holds the allocated buffer address in the system memory pool */
-	u32 *token_addr;
-
-	if (copy_from_user(&command_args, (void __user *)arg,
-					sizeof(struct alloc_struct))) {
-		error = -EFAULT;
-		goto end_function;
-	}
-
-	/* Allocate memory */
-	if ((sep->data_pool_bytes_allocated + command_args.num_bytes) >
-		SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
-		error = -ENOMEM;
-		goto end_function;
-	}
-
-	dev_dbg(&sep->pdev->dev,
-		"data pool bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated);
-	dev_dbg(&sep->pdev->dev,
-		"offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES);
-	/* Set the virtual and bus address */
-	command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES +
-		sep->data_pool_bytes_allocated;
-
-	/* Place in the shared area that is known by the SEP */
-	token_addr = (u32 *)(sep->shared_addr +
-		SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES +
-		(sep->num_of_data_allocations)*2*sizeof(u32));
-
-	token_addr[0] = SEP_DATA_POOL_POINTERS_VAL_TOKEN;
-	token_addr[1] = (u32)sep->shared_bus +
-		SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES +
-		sep->data_pool_bytes_allocated;
-
-	/* Write the memory back to the user space */
-	error = copy_to_user((void *)arg, (void *)&command_args,
-		sizeof(struct alloc_struct));
-	if (error) {
-		error = -EFAULT;
-		goto end_function;
-	}
-
-	/* Update the allocation */
-	sep->data_pool_bytes_allocated += command_args.num_bytes;
-	sep->num_of_data_allocations += 1;
-
-end_function:
-	return error;
-}
-
-/**
- *	sep_lock_kernel_pages - map kernel pages for DMA
- *	@sep: pointer to struct sep_device
- *	@kernel_virt_addr: address of data buffer in kernel
- *	@data_size: size of data
- *	@lli_array_ptr: lli array
- *	@in_out_flag: input into device or output from device
- *
- *	This function locks all the physical pages of the kernel virtual buffer
- *	and construct a basic lli  array, where each entry holds the physical
- *	page address and the size that application data holds in this page
- *	This function is used only during kernel crypto mod calls from within
- *	the kernel (when ioctl is not used)
- */
-static int sep_lock_kernel_pages(struct sep_device *sep,
-	unsigned long kernel_virt_addr,
-	u32 data_size,
-	struct sep_lli_entry **lli_array_ptr,
-	int in_out_flag)
-
-{
-	int error = 0;
-	/* Array of lli */
-	struct sep_lli_entry *lli_array;
-	/* Map array */
-	struct sep_dma_map *map_array;
-
-	dev_dbg(&sep->pdev->dev, "lock kernel pages kernel_virt_addr is %08lx\n",
-				(unsigned long)kernel_virt_addr);
-	dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size);
-
-	lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC);
-	if (!lli_array) {
-		error = -ENOMEM;
-		goto end_function;
-	}
-	map_array = kmalloc(sizeof(struct sep_dma_map), GFP_ATOMIC);
-	if (!map_array) {
-		error = -ENOMEM;
-		goto end_function_with_error;
-	}
-
-	map_array[0].dma_addr =
-		dma_map_single(&sep->pdev->dev, (void *)kernel_virt_addr,
-		data_size, DMA_BIDIRECTIONAL);
-	map_array[0].size = data_size;
-
-
-	/*
-	 * Set the start address of the first page - app data may start not at
-	 * the beginning of the page
-	 */
-	lli_array[0].bus_address = (u32)map_array[0].dma_addr;
-	lli_array[0].block_size = map_array[0].size;
-
-	dev_dbg(&sep->pdev->dev,
-	"lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n",
-		(unsigned long)lli_array[0].bus_address,
-		lli_array[0].block_size);
-
-	/* Set the output parameters */
-	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
-		*lli_array_ptr = lli_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = 1;
-	} else {
-		*lli_array_ptr = lli_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = 1;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1;
-	}
-	goto end_function;
-
-end_function_with_error:
-	kfree(lli_array);
-
-end_function:
-	return error;
-}
-
-/**
- *	sep_lock_user_pages - lock and map user pages for DMA
- *	@sep: pointer to struct sep_device
- *	@app_virt_addr: user memory data buffer
- *	@data_size: size of data buffer
- *	@lli_array_ptr: lli array
- *	@in_out_flag: input or output to device
- *
- *	This function locks all the physical pages of the application
- *	virtual buffer and construct a basic lli  array, where each entry
- *	holds the physical page address and the size that application
- *	data holds in this physical pages
- */
-static int sep_lock_user_pages(struct sep_device *sep,
-	u32 app_virt_addr,
-	u32 data_size,
-	struct sep_lli_entry **lli_array_ptr,
-	int in_out_flag)
-
-{
-	int error = 0;
-	u32 count;
-	int result;
-	/* The the page of the end address of the user space buffer */
-	u32 end_page;
-	/* The page of the start address of the user space buffer */
-	u32 start_page;
-	/* The range in pages */
-	u32 num_pages;
-	/* Array of pointers to page */
-	struct page **page_array;
-	/* Array of lli */
-	struct sep_lli_entry *lli_array;
-	/* Map array */
-	struct sep_dma_map *map_array;
-	/* Direction of the DMA mapping for locked pages */
-	enum dma_data_direction	dir;
-
-	/* Set start and end pages  and num pages */
-	end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
-	start_page = app_virt_addr >> PAGE_SHIFT;
-	num_pages = end_page - start_page + 1;
-
-	dev_dbg(&sep->pdev->dev, "lock user pages app_virt_addr is %x\n", app_virt_addr);
-	dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size);
-	dev_dbg(&sep->pdev->dev, "start_page is %x\n", start_page);
-	dev_dbg(&sep->pdev->dev, "end_page is %x\n", end_page);
-	dev_dbg(&sep->pdev->dev, "num_pages is %x\n", num_pages);
-
-	/* Allocate array of pages structure pointers */
-	page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
-	if (!page_array) {
-		error = -ENOMEM;
-		goto end_function;
-	}
-	map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC);
-	if (!map_array) {
-		dev_warn(&sep->pdev->dev, "kmalloc for map_array failed\n");
-		error = -ENOMEM;
-		goto end_function_with_error1;
-	}
-
-	lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages,
-		GFP_ATOMIC);
-
-	if (!lli_array) {
-		dev_warn(&sep->pdev->dev, "kmalloc for lli_array failed\n");
-		error = -ENOMEM;
-		goto end_function_with_error2;
-	}
-
-	/* Convert the application virtual address into a set of physical */
-	down_read(&current->mm->mmap_sem);
-	result = get_user_pages(current, current->mm, app_virt_addr,
-		num_pages,
-		((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1),
-		0, page_array, NULL);
-
-	up_read(&current->mm->mmap_sem);
-
-	/* Check the number of pages locked - if not all then exit with error */
-	if (result != num_pages) {
-		dev_warn(&sep->pdev->dev,
-			"not all pages locked by get_user_pages\n");
-		error = -ENOMEM;
-		goto end_function_with_error3;
-	}
-
-	dev_dbg(&sep->pdev->dev, "get_user_pages succeeded\n");
-
-	/* Set direction */
-	if (in_out_flag == SEP_DRIVER_IN_FLAG)
-		dir = DMA_TO_DEVICE;
-	else
-		dir = DMA_FROM_DEVICE;
-
-	/*
-	 * Fill the array using page array data and
-	 * map the pages - this action will also flush the cache as needed
-	 */
-	for (count = 0; count < num_pages; count++) {
-		/* Fill the map array */
-		map_array[count].dma_addr =
-			dma_map_page(&sep->pdev->dev, page_array[count],
-			0, PAGE_SIZE, /*dir*/DMA_BIDIRECTIONAL);
-
-		map_array[count].size = PAGE_SIZE;
-
-		/* Fill the lli array entry */
-		lli_array[count].bus_address = (u32)map_array[count].dma_addr;
-		lli_array[count].block_size = PAGE_SIZE;
-
-		dev_warn(&sep->pdev->dev, "lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n",
-			count, (unsigned long)lli_array[count].bus_address,
-			count, lli_array[count].block_size);
-	}
-
-	/* Check the offset for the first page */
-	lli_array[0].bus_address =
-		lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK));
-
-	/* Check that not all the data is in the first page only */
-	if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
-		lli_array[0].block_size = data_size;
-	else
-		lli_array[0].block_size =
-			PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
-
-	dev_dbg(&sep->pdev->dev,
-		"lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n",
-		(unsigned long)lli_array[count].bus_address,
-		lli_array[count].block_size);
-
-	/* Check the size of the last page */
-	if (num_pages > 1) {
-		lli_array[num_pages - 1].block_size =
-			(app_virt_addr + data_size) & (~PAGE_MASK);
-		if (lli_array[num_pages - 1].block_size == 0)
-			lli_array[num_pages - 1].block_size = PAGE_SIZE;
-
-		dev_warn(&sep->pdev->dev,
-			"lli_array[%x].bus_address is "
-			"%08lx, lli_array[%x].block_size is %x\n",
-			num_pages - 1,
-			(unsigned long)lli_array[num_pages - 1].bus_address,
-			num_pages - 1,
-			lli_array[num_pages - 1].block_size);
-	}
-
-	/* Set output params according to the in_out flag */
-	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
-		*lli_array_ptr = lli_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = page_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries =
-								num_pages;
-	} else {
-		*lli_array_ptr = lli_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = num_pages;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_page_array =
-								page_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array;
-		sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries =
-								num_pages;
-	}
-	goto end_function;
-
-end_function_with_error3:
-	/* Free lli array */
-	kfree(lli_array);
-
-end_function_with_error2:
-	kfree(map_array);
-
-end_function_with_error1:
-	/* Free page array */
-	kfree(page_array);
-
-end_function:
-	return error;
-}
-
-/**
- *	u32 sep_calculate_lli_table_max_size - size the LLI table
- *	@sep: pointer to struct sep_device
- *	@lli_in_array_ptr
- *	@num_array_entries
- *	@last_table_flag
- *
- *	This function calculates the size of data that can be inserted into
- *	the lli table from this array, such that either the table is full
- *	(all entries are entered), or there are no more entries in the
- *	lli array
- */
-static u32 sep_calculate_lli_table_max_size(struct sep_device *sep,
-	struct sep_lli_entry *lli_in_array_ptr,
-	u32 num_array_entries,
-	u32 *last_table_flag)
-{
-	u32 counter;
-	/* Table data size */
-	u32 table_data_size = 0;
-	/* Data size for the next table */
-	u32 next_table_data_size;
-
-	*last_table_flag = 0;
-
-	/*
-	 * Calculate the data in the out lli table till we fill the whole
-	 * table or till the data has ended
-	 */
-	for (counter = 0;
-		(counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) &&
-			(counter < num_array_entries); counter++)
-		table_data_size += lli_in_array_ptr[counter].block_size;
-
-	/*
-	 * Check if we reached the last entry,
-	 * meaning this ia the last table to build,
-	 * and no need to check the block alignment
-	 */
-	if (counter == num_array_entries) {
-		/* Set the last table flag */
-		*last_table_flag = 1;
-		goto end_function;
-	}
-
-	/*
-	 * Calculate the data size of the next table.
-	 * Stop if no entries left or if data size is more the DMA restriction
-	 */
-	next_table_data_size = 0;
-	for (; counter < num_array_entries; counter++) {
-		next_table_data_size += lli_in_array_ptr[counter].block_size;
-		if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
-			break;
-	}
-
-	/*
-	 * Check if the next table data size is less then DMA rstriction.
-	 * if it is - recalculate the current table size, so that the next
-	 * table data size will be adaquete for DMA
-	 */
-	if (next_table_data_size &&
-		next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
-
-		table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE -
-			next_table_data_size);
-
-end_function:
-	return table_data_size;
-}
-
-/**
- *	sep_build_lli_table - build an lli array for the given table
- *	@sep: pointer to struct sep_device
- *	@lli_array_ptr: pointer to lli array
- *	@lli_table_ptr: pointer to lli table
- *	@num_processed_entries_ptr: pointer to number of entries
- *	@num_table_entries_ptr: pointer to number of tables
- *	@table_data_size: total data size
- *
- *	Builds ant lli table from the lli_array according to
- *	the given size of data
- */
-static void sep_build_lli_table(struct sep_device *sep,
-	struct sep_lli_entry	*lli_array_ptr,
-	struct sep_lli_entry	*lli_table_ptr,
-	u32 *num_processed_entries_ptr,
-	u32 *num_table_entries_ptr,
-	u32 table_data_size)
-{
-	/* Current table data size */
-	u32 curr_table_data_size;
-	/* Counter of lli array entry */
-	u32 array_counter;
-
-	/* Init current table data size and lli array entry counter */
-	curr_table_data_size = 0;
-	array_counter = 0;
-	*num_table_entries_ptr = 1;
-
-	dev_dbg(&sep->pdev->dev, "build lli table table_data_size is %x\n", table_data_size);
-
-	/* Fill the table till table size reaches the needed amount */
-	while (curr_table_data_size < table_data_size) {
-		/* Update the number of entries in table */
-		(*num_table_entries_ptr)++;
-
-		lli_table_ptr->bus_address =
-			cpu_to_le32(lli_array_ptr[array_counter].bus_address);
-
-		lli_table_ptr->block_size =
-			cpu_to_le32(lli_array_ptr[array_counter].block_size);
-
-		curr_table_data_size += lli_array_ptr[array_counter].block_size;
-
-		dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n",
-								lli_table_ptr);
-		dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n",
-				(unsigned long)lli_table_ptr->bus_address);
-		dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n",
-			lli_table_ptr->block_size);
-
-		/* Check for overflow of the table data */
-		if (curr_table_data_size > table_data_size) {
-			dev_dbg(&sep->pdev->dev,
-				"curr_table_data_size too large\n");
-
-			/* Update the size of block in the table */
-			lli_table_ptr->block_size -=
-			cpu_to_le32((curr_table_data_size - table_data_size));
-
-			/* Update the physical address in the lli array */
-			lli_array_ptr[array_counter].bus_address +=
-			cpu_to_le32(lli_table_ptr->block_size);
-
-			/* Update the block size left in the lli array */
-			lli_array_ptr[array_counter].block_size =
-				(curr_table_data_size - table_data_size);
-		} else
-			/* Advance to the next entry in the lli_array */
-			array_counter++;
-
-		dev_dbg(&sep->pdev->dev,
-			"lli_table_ptr->bus_address is %08lx\n",
-				(unsigned long)lli_table_ptr->bus_address);
-		dev_dbg(&sep->pdev->dev,
-			"lli_table_ptr->block_size is %x\n",
-			lli_table_ptr->block_size);
-
-		/* Move to the next entry in table */
-		lli_table_ptr++;
-	}
-
-	/* Set the info entry to default */
-	lli_table_ptr->bus_address = 0xffffffff;
-	lli_table_ptr->block_size = 0;
-
-	/* Set the output parameter */
-	*num_processed_entries_ptr += array_counter;
-
-}
-
-/**
- *	sep_shared_area_virt_to_bus - map shared area to bus address
- *	@sep: pointer to struct sep_device
- *	@virt_address: virtual address to convert
- *
- *	This functions returns the physical address inside shared area according
- *	to the virtual address. It can be either on the externa RAM device
- *	(ioremapped), or on the system RAM
- *	This implementation is for the external RAM
- */
-static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep,
-	void *virt_address)
-{
-	dev_dbg(&sep->pdev->dev, "sh virt to phys v %p\n", virt_address);
-	dev_dbg(&sep->pdev->dev, "sh virt to phys p %08lx\n",
-		(unsigned long)
-		sep->shared_bus + (virt_address - sep->shared_addr));
-
-	return sep->shared_bus + (size_t)(virt_address - sep->shared_addr);
-}
-
-/**
- *	sep_shared_area_bus_to_virt - map shared area bus address to kernel
- *	@sep: pointer to struct sep_device
- *	@bus_address: bus address to convert
- *
- *	This functions returns the virtual address inside shared area
- *	according to the physical address. It can be either on the
- *	externa RAM device (ioremapped), or on the system RAM
- *	This implementation is for the external RAM
- */
-static void *sep_shared_area_bus_to_virt(struct sep_device *sep,
-	dma_addr_t bus_address)
-{
-	dev_dbg(&sep->pdev->dev, "shared bus to virt b=%lx v=%lx\n",
-		(unsigned long)bus_address, (unsigned long)(sep->shared_addr +
-			(size_t)(bus_address - sep->shared_bus)));
-
-	return sep->shared_addr	+ (size_t)(bus_address - sep->shared_bus);
-}
-
-/**
- *	sep_debug_print_lli_tables - dump LLI table
- *	@sep: pointer to struct sep_device
- *	@lli_table_ptr: pointer to sep_lli_entry
- *	@num_table_entries: number of entries
- *	@table_data_size: total data size
- *
- *	Walk the the list of the print created tables and print all the data
- */
-static void sep_debug_print_lli_tables(struct sep_device *sep,
-	struct sep_lli_entry *lli_table_ptr,
-	unsigned long num_table_entries,
-	unsigned long table_data_size)
-{
-	unsigned long table_count = 1;
-	unsigned long entries_count = 0;
-
-	dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables start\n");
-
-	while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) {
-		dev_dbg(&sep->pdev->dev,
-			"lli table %08lx, table_data_size is %lu\n",
-			table_count, table_data_size);
-		dev_dbg(&sep->pdev->dev, "num_table_entries is %lu\n",
-							num_table_entries);
-
-		/* Print entries of the table (without info entry) */
-		for (entries_count = 0; entries_count < num_table_entries;
-			entries_count++, lli_table_ptr++) {
-
-			dev_dbg(&sep->pdev->dev,
-				"lli_table_ptr address is %08lx\n",
-				(unsigned long) lli_table_ptr);
-
-			dev_dbg(&sep->pdev->dev,
-				"phys address is %08lx block size is %x\n",
-				(unsigned long)lli_table_ptr->bus_address,
-				lli_table_ptr->block_size);
-		}
-		/* Point to the info entry */
-		lli_table_ptr--;
-
-		dev_dbg(&sep->pdev->dev,
-			"phys lli_table_ptr->block_size is %x\n",
-			lli_table_ptr->block_size);
-
-		dev_dbg(&sep->pdev->dev,
-			"phys lli_table_ptr->physical_address is %08lu\n",
-			(unsigned long)lli_table_ptr->bus_address);
-
-
-		table_data_size = lli_table_ptr->block_size & 0xffffff;
-		num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
-
-		dev_dbg(&sep->pdev->dev,
-			"phys table_data_size is %lu num_table_entries is"
-			" %lu bus_address is%lu\n", table_data_size,
-			num_table_entries, (unsigned long)lli_table_ptr->bus_address);
-
-		if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff)
-			lli_table_ptr = (struct sep_lli_entry *)
-				sep_shared_bus_to_virt(sep,
-				(unsigned long)lli_table_ptr->bus_address);
-
-		table_count++;
-	}
-	dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables end\n");
-}
-
-
-/**
- *	sep_prepare_empty_lli_table - create a blank LLI table
- *	@sep: pointer to struct sep_device
- *	@lli_table_addr_ptr: pointer to lli table
- *	@num_entries_ptr: pointer to number of entries
- *	@table_data_size_ptr: point to table data size
- *
- *	This function creates empty lli tables when there is no data
- */
-static void sep_prepare_empty_lli_table(struct sep_device *sep,
-		dma_addr_t *lli_table_addr_ptr,
-		u32 *num_entries_ptr,
-		u32 *table_data_size_ptr)
-{
-	struct sep_lli_entry *lli_table_ptr;
-
-	/* Find the area for new table */
-	lli_table_ptr =
-		(struct sep_lli_entry *)(sep->shared_addr +
-		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
-		sep->num_lli_tables_created * sizeof(struct sep_lli_entry) *
-			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
-	lli_table_ptr->bus_address = 0;
-	lli_table_ptr->block_size = 0;
-
-	lli_table_ptr++;
-	lli_table_ptr->bus_address = 0xFFFFFFFF;
-	lli_table_ptr->block_size = 0;
-
-	/* Set the output parameter value */
-	*lli_table_addr_ptr = sep->shared_bus +
-		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
-		sep->num_lli_tables_created *
-		sizeof(struct sep_lli_entry) *
-		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
-	/* Set the num of entries and table data size for empty table */
-	*num_entries_ptr = 2;
-	*table_data_size_ptr = 0;
-
-	/* Update the number of created tables */
-	sep->num_lli_tables_created++;
-}
-
-/**
- *	sep_prepare_input_dma_table - prepare input DMA mappings
- *	@sep: pointer to struct sep_device
- *	@data_size:
- *	@block_size:
- *	@lli_table_ptr:
- *	@num_entries_ptr:
- *	@table_data_size_ptr:
- *	@is_kva: set for kernel data (kernel cryptio call)
- *
- *	This function prepares only input DMA table for synhronic symmetric
- *	operations (HASH)
- *	Note that all bus addresses that are passed to the SEP
- *	are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_prepare_input_dma_table(struct sep_device *sep,
-	unsigned long app_virt_addr,
-	u32 data_size,
-	u32 block_size,
-	dma_addr_t *lli_table_ptr,
-	u32 *num_entries_ptr,
-	u32 *table_data_size_ptr,
-	bool is_kva)
-{
-	int error = 0;
-	/* Pointer to the info entry of the table - the last entry */
-	struct sep_lli_entry *info_entry_ptr;
-	/* Array of pointers to page */
-	struct sep_lli_entry *lli_array_ptr;
-	/* Points to the first entry to be processed in the lli_in_array */
-	u32 current_entry = 0;
-	/* Num entries in the virtual buffer */
-	u32 sep_lli_entries = 0;
-	/* Lli table pointer */
-	struct sep_lli_entry *in_lli_table_ptr;
-	/* The total data in one table */
-	u32 table_data_size = 0;
-	/* Flag for last table */
-	u32 last_table_flag = 0;
-	/* Number of entries in lli table */
-	u32 num_entries_in_table = 0;
-	/* Next table address */
-	void *lli_table_alloc_addr = 0;
-
-	dev_dbg(&sep->pdev->dev, "prepare intput dma table data_size is %x\n", data_size);
-	dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size);
-
-	/* Initialize the pages pointers */
-	sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL;
-	sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0;
-
-	/* Set the kernel address for first table to be allocated */
-	lli_table_alloc_addr = (void *)(sep->shared_addr +
-		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
-		sep->num_lli_tables_created * sizeof(struct sep_lli_entry) *
-		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
-	if (data_size == 0) {
-		/* Special case  - create meptu table - 2 entries, zero data */
-		sep_prepare_empty_lli_table(sep, lli_table_ptr,
-				num_entries_ptr, table_data_size_ptr);
-		goto update_dcb_counter;
-	}
-
-	/* Check if the pages are in Kernel Virtual Address layout */
-	if (is_kva == true)
-		/* Lock the pages in the kernel */
-		error = sep_lock_kernel_pages(sep, app_virt_addr,
-			data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG);
-	else
-		/*
-		 * Lock the pages of the user buffer
-		 * and translate them to pages
-		 */
-		error = sep_lock_user_pages(sep, app_virt_addr,
-			data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG);
-
-	if (error)
-		goto end_function;
-
-	dev_dbg(&sep->pdev->dev, "output sep_in_num_pages is %x\n",
-		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages);
-
-	current_entry = 0;
-	info_entry_ptr = NULL;
-
-	sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages;
-
-	/* Loop till all the entries in in array are not processed */
-	while (current_entry < sep_lli_entries) {
-
-		/* Set the new input and output tables */
-		in_lli_table_ptr =
-			(struct sep_lli_entry *)lli_table_alloc_addr;
-
-		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
-			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
-		if (lli_table_alloc_addr >
-			((void *)sep->shared_addr +
-			SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
-			SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {
-
-			error = -ENOMEM;
-			goto end_function_error;
-
-		}
-
-		/* Update the number of created tables */
-		sep->num_lli_tables_created++;
-
-		/* Calculate the maximum size of data for input table */
-		table_data_size = sep_calculate_lli_table_max_size(sep,
-			&lli_array_ptr[current_entry],
-			(sep_lli_entries - current_entry),
-			&last_table_flag);
-
-		/*
-		 * If this is not the last table -
-		 * then align it to the block size
-		 */
-		if (!last_table_flag)
-			table_data_size =
-				(table_data_size / block_size) * block_size;
-
-		dev_dbg(&sep->pdev->dev, "output table_data_size is %x\n",
-							table_data_size);
-
-		/* Construct input lli table */
-		sep_build_lli_table(sep, &lli_array_ptr[current_entry],
-			in_lli_table_ptr,
-			&current_entry, &num_entries_in_table, table_data_size);
-
-		if (info_entry_ptr == NULL) {
-
-			/* Set the output parameters to physical addresses */
-			*lli_table_ptr = sep_shared_area_virt_to_bus(sep,
-				in_lli_table_ptr);
-			*num_entries_ptr = num_entries_in_table;
-			*table_data_size_ptr = table_data_size;
-
-			dev_dbg(&sep->pdev->dev,
-				"output lli_table_in_ptr is %08lx\n",
-				(unsigned long)*lli_table_ptr);
-
-		} else {
-			/* Update the info entry of the previous in table */
-			info_entry_ptr->bus_address =
-				sep_shared_area_virt_to_bus(sep,
-							in_lli_table_ptr);
-			info_entry_ptr->block_size =
-				((num_entries_in_table) << 24) |
-				(table_data_size);
-		}
-		/* Save the pointer to the info entry of the current tables */
-		info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
-	}
-	/* Print input tables */
-	sep_debug_print_lli_tables(sep, (struct sep_lli_entry *)
-		sep_shared_area_bus_to_virt(sep, *lli_table_ptr),
-		*num_entries_ptr, *table_data_size_ptr);
-	/* The array of the pages */
-	kfree(lli_array_ptr);
-
-update_dcb_counter:
-	/* Update DCB counter */
-	sep->nr_dcb_creat++;
-	goto end_function;
-
-end_function_error:
-	/* Free all the allocated resources */
-	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array);
-	kfree(lli_array_ptr);
-	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array);
-
-end_function:
-	return error;
-
-}
-/**
- *	sep_construct_dma_tables_from_lli - prepare AES/DES mappings
- *	@sep: pointer to struct sep_device
- *	@lli_in_array:
- *	@sep_in_lli_entries:
- *	@lli_out_array:
- *	@sep_out_lli_entries
- *	@block_size
- *	@lli_table_in_ptr
- *	@lli_table_out_ptr
- *	@in_num_entries_ptr
- *	@out_num_entries_ptr
- *	@table_data_size_ptr
- *
- *	This function creates the input and output DMA tables for
- *	symmetric operations (AES/DES) according to the block
- *	size from LLI arays
- *	Note that all bus addresses that are passed to the SEP
- *	are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_construct_dma_tables_from_lli(
-	struct sep_device *sep,
-	struct sep_lli_entry *lli_in_array,
-	u32	sep_in_lli_entries,
-	struct sep_lli_entry *lli_out_array,
-	u32	sep_out_lli_entries,
-	u32	block_size,
-	dma_addr_t *lli_table_in_ptr,
-	dma_addr_t *lli_table_out_ptr,
-	u32	*in_num_entries_ptr,
-	u32	*out_num_entries_ptr,
-	u32	*table_data_size_ptr)
-{
-	/* Points to the area where next lli table can be allocated */
-	void *lli_table_alloc_addr = 0;
-	/* Input lli table */
-	struct sep_lli_entry *in_lli_table_ptr = NULL;
-	/* Output lli table */
-	struct sep_lli_entry *out_lli_table_ptr = NULL;
-	/* Pointer to the info entry of the table - the last entry */
-	struct sep_lli_entry *info_in_entry_ptr = NULL;
-	/* Pointer to the info entry of the table - the last entry */
-	struct sep_lli_entry *info_out_entry_ptr = NULL;
-	/* Points to the first entry to be processed in the lli_in_array */
-	u32 current_in_entry = 0;
-	/* Points to the first entry to be processed in the lli_out_array */
-	u32 current_out_entry = 0;
-	/* Max size of the input table */
-	u32 in_table_data_size = 0;
-	/* Max size of the output table */
-	u32 out_table_data_size = 0;
-	/* Flag te signifies if this is the last tables build */
-	u32 last_table_flag = 0;
-	/* The data size that should be in table */
-	u32 table_data_size = 0;
-	/* Number of etnries in the input table */
-	u32 num_entries_in_table = 0;
-	/* Number of etnries in the output table */
-	u32 num_entries_out_table = 0;
-
-	/* Initiate to point after the message area */
-	lli_table_alloc_addr = (void *)(sep->shared_addr +
-		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
-		(sep->num_lli_tables_created *
-		(sizeof(struct sep_lli_entry) *
-		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP)));
-
-	/* Loop till all the entries in in array are not processed */
-	while (current_in_entry < sep_in_lli_entries) {
-		/* Set the new input and output tables */
-		in_lli_table_ptr =
-			(struct sep_lli_entry *)lli_table_alloc_addr;
-
-		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
-			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
-		/* Set the first output tables */
-		out_lli_table_ptr =
-			(struct sep_lli_entry *)lli_table_alloc_addr;
-
-		/* Check if the DMA table area limit was overrun */
-		if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) *
-			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) >
-			((void *)sep->shared_addr +
-			SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
-			SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {
-
-			dev_warn(&sep->pdev->dev, "dma table limit overrun\n");
-			return -ENOMEM;
-		}
-
-		/* Update the number of the lli tables created */
-		sep->num_lli_tables_created += 2;
-
-		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
-			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
-
-		/* Calculate the maximum size of data for input table */
-		in_table_data_size =
-			sep_calculate_lli_table_max_size(sep,
-			&lli_in_array[current_in_entry],
-			(sep_in_lli_entries - current_in_entry),
-			&last_table_flag);
-
-		/* Calculate the maximum size of data for output table */
-		out_table_data_size =
-			sep_calculate_lli_table_max_size(sep,
-			&lli_out_array[current_out_entry],
-			(sep_out_lli_entries - current_out_entry),
-			&last_table_flag);
-
-		dev_dbg(&sep->pdev->dev,
-			"construct tables from lli in_table_data_size is %x\n",
-			in_table_data_size);
-
-		dev_dbg(&sep->pdev->dev,
-			"construct tables from lli out_table_data_size is %x\n",
-			out_table_data_size);
-
-		table_data_size = in_table_data_size;
-
-		if (!last_table_flag) {
-			/*
-			 * If this is not the last table,
-			 * then must check where the data is smallest
-			 * and then align it to the block size
-			 */
-			if (table_data_size > out_table_data_size)
-				table_data_size = out_table_data_size;
-
-			/*
-			 * Now calculate the table size so that
-			 * it will be module block size
-			 */
-			table_data_size = (table_data_size / block_size) *
-				block_size;
-		}
-
-		/* Construct input lli table */
-		sep_build_lli_table(sep, &lli_in_array[current_in_entry],
-			in_lli_table_ptr,
-			&current_in_entry,
-			&num_entries_in_table,
-			table_data_size);
-
-		/* Construct output lli table */
-		sep_build_lli_table(sep, &lli_out_array[current_out_entry],
-			out_lli_table_ptr,
-			&current_out_entry,
-			&num_entries_out_table,
-			table_data_size);
-
-		/* If info entry is null - this is the first table built */
-		if (info_in_entry_ptr == NULL) {
-			/* Set the output parameters to physical addresses */
-			*lli_table_in_ptr =
-			sep_shared_area_virt_to_bus(sep, in_lli_table_ptr);
-
-			*in_num_entries_ptr = num_entries_in_table;
-
-			*lli_table_out_ptr =
-				sep_shared_area_virt_to_bus(sep,
-				out_lli_table_ptr);
-
-			*out_num_entries_ptr = num_entries_out_table;
-			*table_data_size_ptr = table_data_size;
-
-			dev_dbg(&sep->pdev->dev,
-			"output lli_table_in_ptr is %08lx\n",
-				(unsigned long)*lli_table_in_ptr);
-			dev_dbg(&sep->pdev->dev,
-			"output lli_table_out_ptr is %08lx\n",
-				(unsigned long)*lli_table_out_ptr);
-		} else {
-			/* Update the info entry of the previous in table */
-			info_in_entry_ptr->bus_address =
-				sep_shared_area_virt_to_bus(sep,
-				in_lli_table_ptr);
-
-			info_in_entry_ptr->block_size =
-				((num_entries_in_table) << 24) |
-				(table_data_size);
-
-			/* Update the info entry of the previous in table */
-			info_out_entry_ptr->bus_address =
-				sep_shared_area_virt_to_bus(sep,
-				out_lli_table_ptr);
-
-			info_out_entry_ptr->block_size =
-				((num_entries_out_table) << 24) |
-				(table_data_size);
-
-			dev_dbg(&sep->pdev->dev,
-				"output lli_table_in_ptr:%08lx %08x\n",
-				(unsigned long)info_in_entry_ptr->bus_address,
-				info_in_entry_ptr->block_size);
-
-			dev_dbg(&sep->pdev->dev,
-				"output lli_table_out_ptr:%08lx  %08x\n",
-				(unsigned long)info_out_entry_ptr->bus_address,
-				info_out_entry_ptr->block_size);
-		}
-
-		/* Save the pointer to the info entry of the current tables */
-		info_in_entry_ptr = in_lli_table_ptr +
-			num_entries_in_table - 1;
-		info_out_entry_ptr = out_lli_table_ptr +
-			num_entries_out_table - 1;
-
-		dev_dbg(&sep->pdev->dev,
-			"output num_entries_out_table is %x\n",
-			(u32)num_entries_out_table);
-		dev_dbg(&sep->pdev->dev,
-			"output info_in_entry_ptr is %lx\n",
-			(unsigned long)info_in_entry_ptr);
-		dev_dbg(&sep->pdev->dev,
-			"output info_out_entry_ptr is %lx\n",
-			(unsigned long)info_out_entry_ptr);
-	}
-
-	/* Print input tables */
-	sep_debug_print_lli_tables(sep,
-	(struct sep_lli_entry *)
-	sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr),
-	*in_num_entries_ptr,
-	*table_data_size_ptr);
-
-	/* Print output tables */
-	sep_debug_print_lli_tables(sep,
-	(struct sep_lli_entry *)
-	sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr),
-	*out_num_entries_ptr,
-	*table_data_size_ptr);
-
-	return 0;
-}
-
-/**
- *	sep_prepare_input_output_dma_table - prepare DMA I/O table
- *	@app_virt_in_addr:
- *	@app_virt_out_addr:
- *	@data_size:
- *	@block_size:
- *	@lli_table_in_ptr:
- *	@lli_table_out_ptr:
- *	@in_num_entries_ptr:
- *	@out_num_entries_ptr:
- *	@table_data_size_ptr:
- *	@is_kva: set for kernel data; used only for kernel crypto module
- *
- *	This function builds input and output DMA tables for synhronic
- *	symmetric operations (AES, DES, HASH). It also checks that each table
- *	is of the modular block size
- *	Note that all bus addresses that are passed to the SEP
- *	are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_prepare_input_output_dma_table(struct sep_device *sep,
-	unsigned long app_virt_in_addr,
-	unsigned long app_virt_out_addr,
-	u32 data_size,
-	u32 block_size,
-	dma_addr_t *lli_table_in_ptr,
-	dma_addr_t *lli_table_out_ptr,
-	u32 *in_num_entries_ptr,
-	u32 *out_num_entries_ptr,
-	u32 *table_data_size_ptr,
-	bool is_kva)
-
-{
-	int error = 0;
-	/* Array of pointers of page */
-	struct sep_lli_entry *lli_in_array;
-	/* Array of pointers of page */
-	struct sep_lli_entry *lli_out_array;
-
-	if (data_size == 0) {
-		/* Prepare empty table for input and output */
-		sep_prepare_empty_lli_table(sep, lli_table_in_ptr,
-			in_num_entries_ptr, table_data_size_ptr);
-
-		sep_prepare_empty_lli_table(sep, lli_table_out_ptr,
-			out_num_entries_ptr, table_data_size_ptr);
-
-		goto update_dcb_counter;
-	}
-
-	/* Initialize the pages pointers */
-	sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL;
-	sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL;
-
-	/* Lock the pages of the buffer and translate them to pages */
-	if (is_kva == true) {
-		error = sep_lock_kernel_pages(sep, app_virt_in_addr,
-			data_size, &lli_in_array, SEP_DRIVER_IN_FLAG);
-
-		if (error) {
-			dev_warn(&sep->pdev->dev,
-				"lock kernel for in failed\n");
-			goto end_function;
-		}
-
-		error = sep_lock_kernel_pages(sep, app_virt_out_addr,
-			data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG);
-
-		if (error) {
-			dev_warn(&sep->pdev->dev,
-				"lock kernel for out failed\n");
-			goto end_function;
-		}
-	}
-
-	else {
-		error = sep_lock_user_pages(sep, app_virt_in_addr,
-				data_size, &lli_in_array, SEP_DRIVER_IN_FLAG);
-		if (error) {
-			dev_warn(&sep->pdev->dev,
-				"sep_lock_user_pages for input virtual buffer failed\n");
-			goto end_function;
-		}
-
-		error = sep_lock_user_pages(sep, app_virt_out_addr,
-			data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG);
-
-		if (error) {
-			dev_warn(&sep->pdev->dev,
-				"sep_lock_user_pages for output virtual buffer failed\n");
-			goto end_function_free_lli_in;
-		}
-	}
-
-	dev_dbg(&sep->pdev->dev, "prep input output dma table sep_in_num_pages is %x\n",
-		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages);
-	dev_dbg(&sep->pdev->dev, "sep_out_num_pages is %x\n",
-		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages);
-	dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n",
-		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
-
-	/* Call the function that creates table from the lli arrays */
-	error = sep_construct_dma_tables_from_lli(sep, lli_in_array,
-		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages,
-		lli_out_array,
-		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages,
-		block_size, lli_table_in_ptr, lli_table_out_ptr,
-		in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
-
-	if (error) {
-		dev_warn(&sep->pdev->dev,
-			"sep_construct_dma_tables_from_lli failed\n");
-		goto end_function_with_error;
-	}
-
-	kfree(lli_out_array);
-	kfree(lli_in_array);
-
-update_dcb_counter:
-	/* Update DCB counter */
-	sep->nr_dcb_creat++;
-
-	goto end_function;
-
-end_function_with_error:
-	kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_map_array);
-	kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_page_array);
-	kfree(lli_out_array);
-
-
-end_function_free_lli_in:
-	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array);
-	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array);
-	kfree(lli_in_array);
-
-end_function:
-
-	return error;
-
-}
-
-/**
- *	sep_prepare_input_output_dma_table_in_dcb - prepare control blocks
- *	@app_in_address: unsigned long; for data buffer in (user space)
- *	@app_out_address: unsigned long; for data buffer out (user space)
- *	@data_in_size: u32; for size of data
- *	@block_size: u32; for block size
- *	@tail_block_size: u32; for size of tail block
- *	@isapplet: bool; to indicate external app
- *	@is_kva: bool; kernel buffer; only used for kernel crypto module
- *
- *	This function prepares the linked DMA tables and puts the
- *	address for the linked list of tables inta a DCB (data control
- *	block) the address of which is known by the SEP hardware
- *	Note that all bus addresses that are passed to the SEP
- *	are in 32 bit format; the SEP is a 32 bit device
- */
-static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
-	unsigned long  app_in_address,
-	unsigned long  app_out_address,
-	u32  data_in_size,
-	u32  block_size,
-	u32  tail_block_size,
-	bool isapplet,
-	bool	is_kva)
-{
-	int error = 0;
-	/* Size of tail */
-	u32 tail_size = 0;
-	/* Address of the created DCB table */
-	struct sep_dcblock *dcb_table_ptr = NULL;
-	/* The physical address of the first input DMA table */
-	dma_addr_t in_first_mlli_address = 0;
-	/* Number of entries in the first input DMA table */
-	u32  in_first_num_entries = 0;
-	/* The physical address of the first output DMA table */
-	dma_addr_t  out_first_mlli_address = 0;
-	/* Number of entries in the first output DMA table */
-	u32  out_first_num_entries = 0;
-	/* Data in the first input/output table */
-	u32  first_data_size = 0;
-
-	if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) {
-		/* No more DCBs to allocate */
-		dev_warn(&sep->pdev->dev, "no more DCBs available\n");
-		error = -ENOSPC;
-		goto end_function;
-	}
-
-	/* Allocate new DCB */
-	dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr +
-		SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES +
-		(sep->nr_dcb_creat * sizeof(struct sep_dcblock)));
-
-	/* Set the default values in the DCB */
-	dcb_table_ptr->input_mlli_address = 0;
-	dcb_table_ptr->input_mlli_num_entries = 0;
-	dcb_table_ptr->input_mlli_data_size = 0;
-	dcb_table_ptr->output_mlli_address = 0;
-	dcb_table_ptr->output_mlli_num_entries = 0;
-	dcb_table_ptr->output_mlli_data_size = 0;
-	dcb_table_ptr->tail_data_size = 0;
-	dcb_table_ptr->out_vr_tail_pt = 0;
-
-	if (isapplet == true) {
-
-		/* Check if there is enough data for DMA operation */
-		if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) {
-			if (is_kva == true) {
-				memcpy(dcb_table_ptr->tail_data,
-					(void *)app_in_address, data_in_size);
-			} else {
-				if (copy_from_user(dcb_table_ptr->tail_data,
-					(void __user *)app_in_address,
-					data_in_size)) {
-					error = -EFAULT;
-					goto end_function;
-				}
-			}
-
-			dcb_table_ptr->tail_data_size = data_in_size;
-
-			/* Set the output user-space address for mem2mem op */
-			if (app_out_address)
-				dcb_table_ptr->out_vr_tail_pt =
-							(aligned_u64)app_out_address;
-
-			/*
-			 * Update both data length parameters in order to avoid
-			 * second data copy and allow building of empty mlli
-			 * tables
-			 */
-			tail_size = 0x0;
-			data_in_size = 0x0;
-
-		} else {
-			if (!app_out_address) {
-				tail_size = data_in_size % block_size;
-				if (!tail_size) {
-					if (tail_block_size == block_size)
-						tail_size = block_size;
-				}
-			} else {
-				tail_size = 0;
-			}
-		}
-		if (tail_size) {
-			if (tail_size > sizeof(dcb_table_ptr->tail_data))
-				return -EINVAL;
-			if (is_kva == true) {
-				memcpy(dcb_table_ptr->tail_data,
-					(void *)(app_in_address + data_in_size -
-					tail_size), tail_size);
-			} else {
-				/* We have tail data - copy it to DCB */
-				if (copy_from_user(dcb_table_ptr->tail_data,
-					(void *)(app_in_address +
-					data_in_size - tail_size), tail_size)) {
-					error = -EFAULT;
-					goto end_function;
-				}
-			}
-			if (app_out_address)
-				/*
-				 * Calculate the output address
-				 * according to tail data size
-				 */
-				dcb_table_ptr->out_vr_tail_pt =
-					(aligned_u64)app_out_address + data_in_size
-					- tail_size;
-
-			/* Save the real tail data size */
-			dcb_table_ptr->tail_data_size = tail_size;
-			/*
-			 * Update the data size without the tail
-			 * data size AKA data for the dma
-			 */
-			data_in_size = (data_in_size - tail_size);
-		}
-	}
-	/* Check if we need to build only input table or input/output */
-	if (app_out_address) {
-		/* Prepare input/output tables */
-		error = sep_prepare_input_output_dma_table(sep,
-			app_in_address,
-			app_out_address,
-			data_in_size,
-			block_size,
-			&in_first_mlli_address,
-			&out_first_mlli_address,
-			&in_first_num_entries,
-			&out_first_num_entries,
-			&first_data_size,
-			is_kva);
-	} else {
-		/* Prepare input tables */
-		error = sep_prepare_input_dma_table(sep,
-			app_in_address,
-			data_in_size,
-			block_size,
-			&in_first_mlli_address,
-			&in_first_num_entries,
-			&first_data_size,
-			is_kva);
-	}
-
-	if (error) {
-		dev_warn(&sep->pdev->dev, "prepare DMA table call failed from prepare DCB call\n");
-		goto end_function;
-	}
-
-	/* Set the DCB values */
-	dcb_table_ptr->input_mlli_address = in_first_mlli_address;
-	dcb_table_ptr->input_mlli_num_entries = in_first_num_entries;
-	dcb_table_ptr->input_mlli_data_size = first_data_size;
-	dcb_table_ptr->output_mlli_address = out_first_mlli_address;
-	dcb_table_ptr->output_mlli_num_entries = out_first_num_entries;
-	dcb_table_ptr->output_mlli_data_size = first_data_size;
-
-end_function:
-	return error;
-
-}
-
-/**
- *	sep_free_dma_tables_and_dcb - free DMA tables and DCBs
- *	@sep: pointer to struct sep_device
- *	@isapplet: indicates external application (used for kernel access)
- *	@is_kva: indicates kernel addresses (only used for kernel crypto)
- *
- *	This function frees the DMA tables and DCB
- */
-static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet,
-	bool is_kva)
-{
-	int i = 0;
-	int error = 0;
-	int error_temp = 0;
-	struct sep_dcblock *dcb_table_ptr;
-	unsigned long pt_hold;
-	void *tail_pt;
-
-	if (isapplet == true) {
-		/* Set pointer to first DCB table */
-		dcb_table_ptr = (struct sep_dcblock *)
-			(sep->shared_addr +
-			SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES);
-
-		/* Go over each DCB and see if tail pointer must be updated */
-		for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) {
-			if (dcb_table_ptr->out_vr_tail_pt) {
-				pt_hold = (unsigned long)dcb_table_ptr->out_vr_tail_pt;
-				tail_pt = (void *)pt_hold;
-				if (is_kva == true) {
-					memcpy(tail_pt,
-						dcb_table_ptr->tail_data,
-						dcb_table_ptr->tail_data_size);
-				} else {
-					error_temp = copy_to_user(
-						tail_pt,
-						dcb_table_ptr->tail_data,
-						dcb_table_ptr->tail_data_size);
-				}
-				if (error_temp) {
-					/* Release the DMA resource */
-					error = -EFAULT;
-					break;
-				}
-			}
-		}
-	}
-	/* Free the output pages, if any */
-	sep_free_dma_table_data_handler(sep);
-
-	return error;
-}
-
-/**
- *	sep_get_static_pool_addr_handler - get static pool address
- *	@sep: pointer to struct sep_device
- *
- *	This function sets the bus and virtual addresses of the static pool
- */
-static int sep_get_static_pool_addr_handler(struct sep_device *sep)
-{
-	u32 *static_pool_addr = NULL;
-
-	static_pool_addr = (u32 *)(sep->shared_addr +
-		SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES);
-
-	static_pool_addr[0] = SEP_STATIC_POOL_VAL_TOKEN;
-	static_pool_addr[1] = (u32)sep->shared_bus +
-		SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
-
-	dev_dbg(&sep->pdev->dev, "static pool segment: physical %x\n",
-		(u32)static_pool_addr[1]);
-
-	return 0;
-}
-
-/**
- *	sep_end_transaction_handler - end transaction
- *	@sep: pointer to struct sep_device
- *
- *	This API handles the end transaction request
- */
-static int sep_end_transaction_handler(struct sep_device *sep)
-{
-	/* Clear the data pool pointers Token */
-	memset((void *)(sep->shared_addr +
-		SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES),
-		0, sep->num_of_data_allocations*2*sizeof(u32));
-
-	/* Check that all the DMA resources were freed */
-	sep_free_dma_table_data_handler(sep);
-
-	clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags);
-
-	/*
-	 * We are now through with the transaction. Let's
-	 * allow other processes who have the device open
-	 * to perform transactions
-	 */
-	mutex_lock(&sep->sep_mutex);
-	sep->pid_doing_transaction = 0;
-	mutex_unlock(&sep->sep_mutex);
-	/* Raise event for stuck contextes */
-	wake_up(&sep->event);
-
-	return 0;
-}
-
-/**
- *	sep_prepare_dcb_handler - prepare a control block
- *	@sep: pointer to struct sep_device
- *	@arg: pointer to user parameters
- *
- *	This function will retrieve the RAR buffer physical addresses, type
- *	& size corresponding to the RAR handles provided in the buffers vector.
- */
-static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg)
-{
-	int error;
-	/* Command arguments */
-	struct build_dcb_struct command_args;
-
-	/* Get the command arguments */
-	if (copy_from_user(&command_args, (void __user *)arg,
-					sizeof(struct build_dcb_struct))) {
-		error = -EFAULT;
-		goto end_function;
-	}
-
-	dev_dbg(&sep->pdev->dev, "prep dcb handler app_in_address is %08llx\n",
-						command_args.app_in_address);
-	dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n",
-						command_args.app_out_address);
-	dev_dbg(&sep->pdev->dev, "data_size is %x\n",
-						command_args.data_in_size);
-	dev_dbg(&sep->pdev->dev, "block_size is %x\n",
-						command_args.block_size);
-	dev_dbg(&sep->pdev->dev, "tail block_size is %x\n",
-						command_args.tail_block_size);
-
-	error = sep_prepare_input_output_dma_table_in_dcb(sep,
-		(unsigned long)command_args.app_in_address,
-		(unsigned long)command_args.app_out_address,
-		command_args.data_in_size, command_args.block_size,
-		command_args.tail_block_size, true, false);
-
-end_function:
-	return error;
-
-}
-
-/**
- *	sep_free_dcb_handler - free control block resources
- *	@sep: pointer to struct sep_device
- *
- *	This function frees the DCB resources and updates the needed
- *	user-space buffers.
- */
-static int sep_free_dcb_handler(struct sep_device *sep)
-{
-	return sep_free_dma_tables_and_dcb(sep, false, false);
-}
-
-/**
- *	sep_rar_prepare_output_msg_handler - prepare an output message
- *	@sep: pointer to struct sep_device
- *	@arg: pointer to user parameters
- *
- *	This function will retrieve the RAR buffer physical addresses, type
- *	& size corresponding to the RAR handles provided in the buffers vector.
- */
-static int sep_rar_prepare_output_msg_handler(struct sep_device *sep,
-	unsigned long arg)
-{
-	int error = 0;
-	/* Command args */
-	struct rar_hndl_to_bus_struct command_args;
-	/* Bus address */
-	dma_addr_t  rar_bus = 0;
-	/* Holds the RAR address in the system memory offset */
-	u32 *rar_addr;
-
-	/* Copy the data */
-	if (copy_from_user(&command_args, (void __user *)arg,
-						sizeof(command_args))) {
-		error = -EFAULT;
-		goto end_function;
-	}
-
-	/* Call to translation function only if user handle is not NULL */
-	if (command_args.rar_handle)
-		return -EOPNOTSUPP;
-	dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", (u32)rar_bus);
-
-	/* Set value in the SYSTEM MEMORY offset */
-	rar_addr = (u32 *)(sep->shared_addr +
-		SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES);
-
-	/* Copy the physical address to the System Area for the SEP */
-	rar_addr[0] = SEP_RAR_VAL_TOKEN;
-	rar_addr[1] = rar_bus;
-
-end_function:
-	return error;
-}
-
-/**
- *	sep_ioctl - ioctl api
- *	@filp: pointer to struct file
- *	@cmd: command
- *	@arg: pointer to argument structure
- *
- *	Implement the ioctl methods available on the SEP device.
- */
-static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
-	int error = 0;
-	struct sep_device *sep = filp->private_data;
-
-	/* Make sure we own this device */
-	mutex_lock(&sep->sep_mutex);
-	if ((current->pid != sep->pid_doing_transaction) &&
-				(sep->pid_doing_transaction != 0)) {
-		dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n");
-		error = -EACCES;
-	}
-	mutex_unlock(&sep->sep_mutex);
-
-	if (error)
-		return error;
-
-	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
-		return -ENOTTY;
-
-	/* Lock to prevent the daemon to interfere with operation */
-	mutex_lock(&sep->ioctl_mutex);
-
-	switch (cmd) {
-	case SEP_IOCSENDSEPCOMMAND:
-		/* Send command to SEP */
-		error = sep_send_command_handler(sep);
-		break;
-	case SEP_IOCALLOCDATAPOLL:
-		/* Allocate data pool */
-		error = sep_allocate_data_pool_memory_handler(sep, arg);
-		break;
-	case SEP_IOCGETSTATICPOOLADDR:
-		/* Inform the SEP the bus address of the static pool */
-		error = sep_get_static_pool_addr_handler(sep);
-		break;
-	case SEP_IOCENDTRANSACTION:
-		error = sep_end_transaction_handler(sep);
-		break;
-	case SEP_IOCRARPREPAREMESSAGE:
-		error = sep_rar_prepare_output_msg_handler(sep, arg);
-		break;
-	case SEP_IOCPREPAREDCB:
-		error = sep_prepare_dcb_handler(sep, arg);
-		break;
-	case SEP_IOCFREEDCB:
-		error = sep_free_dcb_handler(sep);
-		break;
-	default:
-		error = -ENOTTY;
-		break;
-	}
-
-	mutex_unlock(&sep->ioctl_mutex);
-	return error;
-}
-
-/**
- *	sep_singleton_ioctl - ioctl api for singleton interface
- *	@filp: pointer to struct file
- *	@cmd: command
- *	@arg: pointer to argument structure
- *
- *	Implement the additional ioctls for the singleton device
- */
-static long sep_singleton_ioctl(struct file  *filp, u32 cmd, unsigned long arg)
-{
-	long error = 0;
-	struct sep_device *sep = filp->private_data;
-
-	/* Check that the command is for the SEP device */
-	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
-		return -ENOTTY;
-
-	/* Make sure we own this device */
-	mutex_lock(&sep->sep_mutex);
-	if ((current->pid != sep->pid_doing_transaction) &&
-				(sep->pid_doing_transaction != 0)) {
-		dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n");
-		mutex_unlock(&sep->sep_mutex);
-		return -EACCES;
-	}
-
-	mutex_unlock(&sep->sep_mutex);
-
-	switch (cmd) {
-	case SEP_IOCTLSETCALLERID:
-		mutex_lock(&sep->ioctl_mutex);
-		error = sep_set_caller_id_handler(sep, arg);
-		mutex_unlock(&sep->ioctl_mutex);
-		break;
-	default:
-		error = sep_ioctl(filp, cmd, arg);
-		break;
-	}
-	return error;
-}
-
-/**
- *	sep_request_daemon_ioctl - ioctl for daemon
- *	@filp: pointer to struct file
- *	@cmd: command
- *	@arg: pointer to argument structure
- *
- *	Called by the request daemon to perform ioctls on the daemon device
- */
-static long sep_request_daemon_ioctl(struct file *filp, u32 cmd,
-	unsigned long arg)
-{
-
-	long error;
-	struct sep_device *sep = filp->private_data;
-
-	/* Check that the command is for SEP device */
-	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
-		return -ENOTTY;
-
-	/* Only one process can access ioctl at any given time */
-	mutex_lock(&sep->ioctl_mutex);
-
-	switch (cmd) {
-	case SEP_IOCSENDSEPRPLYCOMMAND:
-		/* Send reply command to SEP */
-		error = sep_req_daemon_send_reply_command_handler(sep);
-		break;
-	case SEP_IOCENDTRANSACTION:
-		/*
-		 * End req daemon transaction, do nothing
-		 * will be removed upon update in middleware
-		 * API library
-		 */
-		error = 0;
-		break;
-	default:
-		error = -ENOTTY;
-	}
-	mutex_unlock(&sep->ioctl_mutex);
-	return error;
-}
-
-/**
- *	sep_inthandler - interrupt handler
- *	@irq: interrupt
- *	@dev_id: device id
- */
-static irqreturn_t sep_inthandler(int irq, void *dev_id)
-{
-	irqreturn_t int_error = IRQ_HANDLED;
-	unsigned long lck_flags;
-	u32 reg_val, reg_val2 = 0;
-	struct sep_device *sep = dev_id;
-
-	/* Read the IRR register to check if this is SEP interrupt */
-	reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
-
-	if (reg_val & (0x1 << 13)) {
-		/* Lock and update the counter of reply messages */
-		spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
-		sep->reply_ct++;
-		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
-
-		dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n",
-					sep->send_ct, sep->reply_ct);
-
-		/* Is this printf or daemon request? */
-		reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
-		dev_dbg(&sep->pdev->dev,
-			"SEP Interrupt - reg2 is %08x\n", reg_val2);
-
-		if ((reg_val2 >> 30) & 0x1) {
-			dev_dbg(&sep->pdev->dev, "int: printf request\n");
-			wake_up(&sep->event_request_daemon);
-		} else if (reg_val2 >> 31) {
-			dev_dbg(&sep->pdev->dev, "int: daemon request\n");
-			wake_up(&sep->event_request_daemon);
-		} else {
-			dev_dbg(&sep->pdev->dev, "int: SEP reply\n");
-			wake_up(&sep->event);
-		}
-	} else {
-		dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n");
-		int_error = IRQ_NONE;
-	}
-	if (int_error == IRQ_HANDLED)
-		sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
-
-	return int_error;
-}
-
-/**
- *	sep_reconfig_shared_area - reconfigure shared area
- *	@sep: pointer to struct sep_device
- *
- *	Reconfig the shared area between HOST and SEP - needed in case
- *	the DX_CC_Init function was called before OS loading.
- */
-static int sep_reconfig_shared_area(struct sep_device *sep)
-{
-	int ret_val;
-
-	/* use to limit waiting for SEP */
-	unsigned long end_time;
-
-	/* Send the new SHARED MESSAGE AREA to the SEP */
-	dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n",
-				(unsigned long long)sep->shared_bus);
-
-	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
-
-	/* Poll for SEP response */
-	ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
-
-	end_time = jiffies + (WAIT_TIME * HZ);
-
-	while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) &&
-		(ret_val != sep->shared_bus))
-		ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
-
-	/* Check the return value (register) */
-	if (ret_val != sep->shared_bus) {
-		dev_warn(&sep->pdev->dev, "could not reconfig shared area\n");
-		dev_warn(&sep->pdev->dev, "result was %x\n", ret_val);
-		ret_val = -ENOMEM;
-	} else
-		ret_val = 0;
-
-	dev_dbg(&sep->pdev->dev, "reconfig shared area end\n");
-	return ret_val;
-}
-
-/* File operation for singleton SEP operations */
-static const struct file_operations singleton_file_operations = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = sep_singleton_ioctl,
-	.poll = sep_poll,
-	.open = sep_singleton_open,
-	.release = sep_singleton_release,
-	.mmap = sep_mmap,
-};
-
-/* File operation for daemon operations */
-static const struct file_operations daemon_file_operations = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = sep_request_daemon_ioctl,
-	.poll = sep_request_daemon_poll,
-	.open = sep_request_daemon_open,
-	.release = sep_request_daemon_release,
-	.mmap = sep_request_daemon_mmap,
-};
-
-/* The files operations structure of the driver */
-static const struct file_operations sep_file_operations = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = sep_ioctl,
-	.poll = sep_poll,
-	.open = sep_open,
-	.release = sep_release,
-	.mmap = sep_mmap,
-};
-
-/**
- *	sep_register_driver_with_fs - register misc devices
- *	@sep: pointer to struct sep_device
- *
- *	This function registers the driver with the file system
- */
-static int sep_register_driver_with_fs(struct sep_device *sep)
-{
-	int ret_val;
-
-	sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR;
-	sep->miscdev_sep.name = SEP_DEV_NAME;
-	sep->miscdev_sep.fops = &sep_file_operations;
-
-	sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR;
-	sep->miscdev_singleton.name = SEP_DEV_SINGLETON;
-	sep->miscdev_singleton.fops = &singleton_file_operations;
-
-	sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR;
-	sep->miscdev_daemon.name = SEP_DEV_DAEMON;
-	sep->miscdev_daemon.fops = &daemon_file_operations;
-
-	ret_val = misc_register(&sep->miscdev_sep);
-	if (ret_val) {
-		dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n",
-			ret_val);
-		return ret_val;
-	}
-
-	ret_val = misc_register(&sep->miscdev_singleton);
-	if (ret_val) {
-		dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n",
-			ret_val);
-		misc_deregister(&sep->miscdev_sep);
-		return ret_val;
-	}
-
-	ret_val = misc_register(&sep->miscdev_daemon);
-	if (ret_val) {
-		dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n",
-			ret_val);
-		misc_deregister(&sep->miscdev_sep);
-		misc_deregister(&sep->miscdev_singleton);
-
-		return ret_val;
-	}
-	return ret_val;
-}
-
-
-/**
- *	sep_probe - probe a matching PCI device
- *	@pdev: pci_device
- *	@end: pci_device_id
- *
- *	Attempt to set up and configure a SEP device that has been
- *	discovered by the PCI layer.
- */
-static int __devinit sep_probe(struct pci_dev *pdev,
-	const struct pci_device_id *ent)
-{
-	int error = 0;
-	struct sep_device *sep;
-
-	if (sep_dev != NULL) {
-		dev_warn(&pdev->dev, "only one SEP supported.\n");
-		return -EBUSY;
-	}
-
-	/* Enable the device */
-	error = pci_enable_device(pdev);
-	if (error) {
-		dev_warn(&pdev->dev, "error enabling pci device\n");
-		goto end_function;
-	}
-
-	/* Allocate the sep_device structure for this device */
-	sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC);
-	if (sep_dev == NULL) {
-		dev_warn(&pdev->dev,
-			"can't kmalloc the sep_device structure\n");
-		error = -ENOMEM;
-		goto end_function_disable_device;
-	}
-
-	/*
-	 * We're going to use another variable for actually
-	 * working with the device; this way, if we have
-	 * multiple devices in the future, it would be easier
-	 * to make appropriate changes
-	 */
-	sep = sep_dev;
-
-	sep->pdev = pci_dev_get(pdev);
-
-	init_waitqueue_head(&sep->event);
-	init_waitqueue_head(&sep->event_request_daemon);
-	spin_lock_init(&sep->snd_rply_lck);
-	mutex_init(&sep->sep_mutex);
-	mutex_init(&sep->ioctl_mutex);
-
-	dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, device being prepared\n");
-	dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision);
-
-	/* Set up our register area */
-	sep->reg_physical_addr = pci_resource_start(sep->pdev, 0);
-	if (!sep->reg_physical_addr) {
-		dev_warn(&sep->pdev->dev, "Error getting register start\n");
-		error = -ENODEV;
-		goto end_function_free_sep_dev;
-	}
-
-	sep->reg_physical_end = pci_resource_end(sep->pdev, 0);
-	if (!sep->reg_physical_end) {
-		dev_warn(&sep->pdev->dev, "Error getting register end\n");
-		error = -ENODEV;
-		goto end_function_free_sep_dev;
-	}
-
-	sep->reg_addr = ioremap_nocache(sep->reg_physical_addr,
-		(size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1));
-	if (!sep->reg_addr) {
-		dev_warn(&sep->pdev->dev, "Error getting register virtual\n");
-		error = -ENODEV;
-		goto end_function_free_sep_dev;
-	}
-
-	dev_dbg(&sep->pdev->dev,
-		"Register area start %llx end %llx virtual %p\n",
-		(unsigned long long)sep->reg_physical_addr,
-		(unsigned long long)sep->reg_physical_end,
-		sep->reg_addr);
-
-	/* Allocate the shared area */
-	sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
-		SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES +
-		SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES +
-		SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES +
-		SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
-
-	if (sep_map_and_alloc_shared_area(sep)) {
-		error = -ENOMEM;
-		/* Allocation failed */
-		goto end_function_error;
-	}
-
-	/* Clear ICR register */
-	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
-
-	/* Set the IMR register - open only GPR 2 */
-	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
-
-	/* Read send/receive counters from SEP */
-	sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
-	sep->reply_ct &= 0x3FFFFFFF;
-	sep->send_ct = sep->reply_ct;
-
-	/* Get the interrupt line */
-	error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED,
-		"sep_driver", sep);
-
-	if (error)
-		goto end_function_deallocate_sep_shared_area;
-
-	/* The new chip requires a shared area reconfigure */
-	if (sep->pdev->revision == 4) { /* Only for new chip */
-		error = sep_reconfig_shared_area(sep);
-		if (error)
-			goto end_function_free_irq;
-	}
-	/* Finally magic up the device nodes */
-	/* Register driver with the fs */
-	error = sep_register_driver_with_fs(sep);
-	if (error == 0)
-		/* Success */
-		return 0;
-
-end_function_free_irq:
-	free_irq(pdev->irq, sep);
-
-end_function_deallocate_sep_shared_area:
-	/* De-allocate shared area */
-	sep_unmap_and_free_shared_area(sep);
-
-end_function_error:
-	iounmap(sep->reg_addr);
-
-end_function_free_sep_dev:
-	pci_dev_put(sep_dev->pdev);
-	kfree(sep_dev);
-	sep_dev = NULL;
-
-end_function_disable_device:
-	pci_disable_device(pdev);
-
-end_function:
-	return error;
-}
-
-static void sep_remove(struct pci_dev *pdev)
-{
-	struct sep_device *sep = sep_dev;
-
-	/* Unregister from fs */
-	misc_deregister(&sep->miscdev_sep);
-	misc_deregister(&sep->miscdev_singleton);
-	misc_deregister(&sep->miscdev_daemon);
-
-	/* Free the irq */
-	free_irq(sep->pdev->irq, sep);
-
-	/* Free the shared area  */
-	sep_unmap_and_free_shared_area(sep_dev);
-	iounmap((void *) sep_dev->reg_addr);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = {
-	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)},
-	{0}
-};
-
-MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
-
-/* Field for registering driver to PCI device */
-static struct pci_driver sep_pci_driver = {
-	.name = "sep_sec_driver",
-	.id_table = sep_pci_id_tbl,
-	.probe = sep_probe,
-	.remove = sep_remove
-};
-
-
-/**
- *	sep_init - init function
- *
- *	Module load time. Register the PCI device driver.
- */
-static int __init sep_init(void)
-{
-	return pci_register_driver(&sep_pci_driver);
-}
-
-
-/**
- *	sep_exit - called to unload driver
- *
- *	Drop the misc devices then remove and unmap the various resources
- *	that are not released by the driver remove method.
- */
-static void __exit sep_exit(void)
-{
-	pci_unregister_driver(&sep_pci_driver);
-}
-
-
-module_init(sep_init);
-module_exit(sep_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h
index c3aacfc..8b797d5 100644
--- a/drivers/staging/sep/sep_driver_api.h
+++ b/drivers/staging/sep/sep_driver_api.h
@@ -2,8 +2,8 @@
  *
  *  sep_driver_api.h - Security Processor Driver api definitions
  *
- *  Copyright(c) 2009,2010 Intel Corporation. All rights reserved.
- *  Contributions(c) 2009,2010 Discretix. All rights reserved.
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2011 Discretix. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the Free
@@ -26,6 +26,7 @@
  *  CHANGES:
  *
  *  2010.09.14  Upgrade to Medfield
+ *  2011.02.22  Enable kernel crypto
  *
  */
 
@@ -37,26 +38,32 @@
 #define SEP_DRIVER_SRC_REQ		2
 #define SEP_DRIVER_SRC_PRINTF		3
 
-
-/*-------------------------------------------
-    TYPEDEFS
-----------------------------------------------*/
-
-struct alloc_struct {
-	/* offset from start of shared pool area */
-	u32  offset;
-	/* number of bytes to allocate */
-	u32  num_bytes;
-};
-
-/* command struct for getting caller id value and address */
-struct caller_id_struct {
-	/* pid of the process */
-	u32 pid;
-	/* virtual address of the caller id hash */
-	aligned_u64 callerIdAddress;
-	/* caller id hash size in bytes */
-	u32 callerIdSizeInBytes;
+/* Power state */
+#define SEP_DRIVER_POWERON		1
+#define SEP_DRIVER_POWEROFF		2
+
+/* Following enums are used only for kernel crypto api */
+enum type_of_request {
+	NO_REQUEST,
+	AES_CBC,
+	AES_ECB,
+	DES_CBC,
+	DES_ECB,
+	DES3_ECB,
+	DES3_CBC,
+	SHA1,
+	MD5,
+	SHA224,
+	SHA256
+	};
+
+enum hash_stage {
+	HASH_INIT,
+	HASH_UPDATE,
+	HASH_FINISH,
+	HASH_DIGEST,
+	HASH_FINUP_DATA,
+	HASH_FINUP_FINISH
 };
 
 /*
@@ -83,11 +90,6 @@ struct sep_dcblock {
 	u8	tail_data[68];
 };
 
-struct sep_caller_id_entry {
-	int pid;
-	unsigned char callerIdHash[SEP_CALLER_ID_HASH_SIZE_IN_BYTES];
-};
-
 /*
 	command structure for building dcb block (currently for ext app only
 */
@@ -104,6 +106,33 @@ struct build_dcb_struct {
 	/* the size of the block of the operation - if needed,
 	every table will be modulo this parameter */
 	u32  tail_block_size;
+
+	/* which application calls the driver DX or applet */
+	u32  is_applet;
+};
+
+/*
+	command structure for building dcb block for kernel crypto
+*/
+struct build_dcb_struct_kernel {
+	/* address value of the data in */
+	void *app_in_address;
+	/* size of data in */
+	ssize_t  data_in_size;
+	/* address of the data out */
+	void *app_out_address;
+	/* the size of the block of the operation - if needed,
+	every table will be modulo this parameter */
+	u32  block_size;
+	/* the size of the block of the operation - if needed,
+	every table will be modulo this parameter */
+	u32  tail_block_size;
+
+	/* which application calls the driver DX or applet */
+	u32  is_applet;
+
+	struct scatterlist *src_sg;
+	struct scatterlist *dst_sg;
 };
 
 /**
@@ -147,6 +176,10 @@ struct sep_dma_resource {
 
 	/* number of entries of the output mapp array */
 	u32 out_map_num_entries;
+
+	/* Scatter list for kernel operations */
+	struct scatterlist *src_sg;
+	struct scatterlist *dst_sg;
 };
 
 
@@ -169,47 +202,201 @@ struct sep_lli_entry {
 	u32 block_size;
 };
 
-/*----------------------------------------------------------------
-	IOCTL command defines
-	-----------------------------------------------------------------*/
+/*
+ * header format for each fastcall write operation
+ */
+struct sep_fastcall_hdr {
+	u32 magic;
+	u32 secure_dma;
+	u32 msg_len;
+	u32 num_dcbs;
+};
 
-/* magic number 1 of the sep IOCTL command */
-#define SEP_IOC_MAGIC_NUMBER	                     's'
+/*
+ * structure used in file pointer's private data field
+ * to track the status of the calls to the various
+ * driver interface
+ */
+struct sep_call_status {
+	unsigned long status;
+};
 
-/* sends interrupt to sep that message is ready */
-#define SEP_IOCSENDSEPCOMMAND	 \
-	_IO(SEP_IOC_MAGIC_NUMBER, 0)
+/*
+ * format of dma context buffer used to store all DMA-related
+ * context information of a particular transaction
+ */
+struct sep_dma_context {
+	/* number of data control blocks */
+	u32 nr_dcb_creat;
+	/* number of the lli tables created in the current transaction */
+	u32 num_lli_tables_created;
+	/* size of currently allocated dma tables region */
+	u32 dmatables_len;
+	/* size of input data */
+	u32 input_data_len;
+	/* secure dma use (for imr memory restriced area in output */
+	bool secure_dma;
+	struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS];
+	/* Scatter gather for kernel crypto */
+	struct scatterlist *src_sg;
+	struct scatterlist *dst_sg;
+};
 
-/* sends interrupt to sep that message is ready */
-#define SEP_IOCSENDSEPRPLYCOMMAND	 \
-	_IO(SEP_IOC_MAGIC_NUMBER, 1)
+/*
+ * format for file pointer's private_data field
+ */
+struct sep_private_data {
+	struct sep_queue_info *my_queue_elem;
+	struct sep_device *device;
+	struct sep_call_status call_status;
+	struct sep_dma_context *dma_ctx;
+};
 
-/* allocate memory in data pool */
-#define SEP_IOCALLOCDATAPOLL	\
-	_IOW(SEP_IOC_MAGIC_NUMBER, 2, struct alloc_struct)
 
-/* free dynamic data aalocated during table creation */
-#define SEP_IOCFREEDMATABLEDATA	 \
-	_IO(SEP_IOC_MAGIC_NUMBER, 7)
+/* Functions used by sep_crypto */
 
-/* get the static pool area addersses (physical and virtual) */
-#define SEP_IOCGETSTATICPOOLADDR	\
-	_IO(SEP_IOC_MAGIC_NUMBER, 8)
+/**
+ * sep_queue_status_remove - Removes transaction from status queue
+ * @sep: SEP device
+ * @sep_queue_info: pointer to status queue
+ *
+ * This function will removes information about transaction from the queue.
+ */
+void sep_queue_status_remove(struct sep_device *sep,
+				      struct sep_queue_info **queue_elem);
+/**
+ * sep_queue_status_add - Adds transaction to status queue
+ * @sep: SEP device
+ * @opcode: transaction opcode
+ * @size: input data size
+ * @pid: pid of current process
+ * @name: current process name
+ * @name_len: length of name (current process)
+ *
+ * This function adds information about about transaction started to the status
+ * queue.
+ */
+struct sep_queue_info *sep_queue_status_add(
+						struct sep_device *sep,
+						u32 opcode,
+						u32 size,
+						u32 pid,
+						u8 *name, size_t name_len);
+
+/**
+ *	sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context
+ *      for kernel crypto
+ *	@sep: SEP device
+ *	@dcb_region: DCB region buf to create for current transaction
+ *	@dmatables_region: MLLI/DMA tables buf to create for current transaction
+ *	@dma_ctx: DMA context buf to create for current transaction
+ *	@user_dcb_args: User arguments for DCB/MLLI creation
+ *	@num_dcbs: Number of DCBs to create
+ */
+int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep,
+			struct sep_dcblock **dcb_region,
+			void **dmatables_region,
+			struct sep_dma_context **dma_ctx,
+			const struct build_dcb_struct_kernel *dcb_data,
+			const u32 num_dcbs);
+
+/**
+ *	sep_activate_dcb_dmatables_context - Takes DCB & DMA tables
+ *						contexts into use
+ *	@sep: SEP device
+ *	@dcb_region: DCB region copy
+ *	@dmatables_region: MLLI/DMA tables copy
+ *	@dma_ctx: DMA context for current transaction
+ */
+ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep,
+					struct sep_dcblock **dcb_region,
+					void **dmatables_region,
+					struct sep_dma_context *dma_ctx);
+
+/**
+ * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks
+ * @app_in_address: unsigned long; for data buffer in (user space)
+ * @app_out_address: unsigned long; for data buffer out (user space)
+ * @data_in_size: u32; for size of data
+ * @block_size: u32; for block size
+ * @tail_block_size: u32; for size of tail block
+ * @isapplet: bool; to indicate external app
+ * @is_kva: bool; kernel buffer; only used for kernel crypto module
+ * @secure_dma; indicates whether this is secure_dma using IMR
+ *
+ * This function prepares the linked DMA tables and puts the
+ * address for the linked list of tables inta a DCB (data control
+ * block) the address of which is known by the SEP hardware
+ * Note that all bus addresses that are passed to the SEP
+ * are in 32 bit format; the SEP is a 32 bit device
+ */
+int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
+	unsigned long  app_in_address,
+	unsigned long  app_out_address,
+	u32  data_in_size,
+	u32  block_size,
+	u32  tail_block_size,
+	bool isapplet,
+	bool	is_kva,
+	bool    secure_dma,
+	struct sep_dcblock *dcb_region,
+	void **dmatables_region,
+	struct sep_dma_context **dma_ctx,
+	struct scatterlist *src_sg,
+	struct scatterlist *dst_sg);
+
+/**
+ * sep_free_dma_table_data_handler - free DMA table
+ * @sep: pointere to struct sep_device
+ * @dma_ctx: dma context
+ *
+ * Handles the request to  free DMA table for synchronic actions
+ */
+int sep_free_dma_table_data_handler(struct sep_device *sep,
+					   struct sep_dma_context **dma_ctx);
+/**
+ * sep_send_command_handler - kick off a command
+ * @sep: SEP being signalled
+ *
+ * This function raises interrupt to SEP that signals that is has a new
+ * command from the host
+ *
+ * Note that this function does fall under the ioctl lock
+ */
+int sep_send_command_handler(struct sep_device *sep);
+
+/**
+ *	sep_wait_transaction - Used for synchronizing transactions
+ *	@sep: SEP device
+ */
+int sep_wait_transaction(struct sep_device *sep);
+
+/**
+ * IOCTL command defines
+ */
+/* magic number 1 of the sep IOCTL command */
+#define SEP_IOC_MAGIC_NUMBER	's'
+
+/* sends interrupt to sep that message is ready */
+#define SEP_IOCSENDSEPCOMMAND	 \
+	_IO(SEP_IOC_MAGIC_NUMBER, 0)
 
 /* end transaction command */
 #define SEP_IOCENDTRANSACTION	 \
 	_IO(SEP_IOC_MAGIC_NUMBER, 15)
 
-#define SEP_IOCRARPREPAREMESSAGE	\
-	_IOW(SEP_IOC_MAGIC_NUMBER, 20, struct rar_hndl_to_bus_struct)
-
-#define SEP_IOCTLSETCALLERID	\
-	_IOW(SEP_IOC_MAGIC_NUMBER, 34, struct caller_id_struct)
-
 #define SEP_IOCPREPAREDCB					\
 	_IOW(SEP_IOC_MAGIC_NUMBER, 35, struct build_dcb_struct)
 
 #define SEP_IOCFREEDCB					\
 	_IO(SEP_IOC_MAGIC_NUMBER, 36)
 
+struct sep_device;
+
+#define SEP_IOCPREPAREDCB_SECURE_DMA	\
+	_IOW(SEP_IOC_MAGIC_NUMBER, 38, struct build_dcb_struct)
+
+#define SEP_IOCFREEDCB_SECURE_DMA	\
+	_IO(SEP_IOC_MAGIC_NUMBER, 39)
+
 #endif
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h
index d6bfd24..fa7c0d0 100644
--- a/drivers/staging/sep/sep_driver_config.h
+++ b/drivers/staging/sep/sep_driver_config.h
@@ -2,8 +2,8 @@
  *
  *  sep_driver_config.h - Security Processor Driver configuration
  *
- *  Copyright(c) 2009,2010 Intel Corporation. All rights reserved.
- *  Contributions(c) 2009,2010 Discretix. All rights reserved.
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2011 Discretix. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the Free
@@ -26,6 +26,7 @@
  *  CHANGES:
  *
  *  2010.06.26	Upgrade to Medfield
+ *  2011.02.22  Enable kernel crypto
  *
  */
 
@@ -48,6 +49,8 @@
 /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
 #define SEP_DRIVER_ARM_DEBUG_MODE                       0
 
+/* Critical message area contents for sanity checking */
+#define SEP_START_MSG_TOKEN				0x02558808
 /*-------------------------------------------
 	INTERNAL DATA CONFIGURATION
 	-------------------------------------------*/
@@ -65,21 +68,17 @@
 #define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE		16
 
 /* flag that signifies tah the lock is
-currently held by the process (struct file) */
+currently held by the proccess (struct file) */
 #define SEP_DRIVER_OWN_LOCK_FLAG                        1
 
 /* flag that signifies tah the lock is currently NOT
-held by the process (struct file) */
+held by the proccess (struct file) */
 #define SEP_DRIVER_DISOWN_LOCK_FLAG                     0
 
 /* indicates whether driver has mapped/unmapped shared area */
 #define SEP_REQUEST_DAEMON_MAPPED 1
 #define SEP_REQUEST_DAEMON_UNMAPPED 0
 
-#define SEP_DEV_NAME "sep_sec_driver"
-#define SEP_DEV_SINGLETON "sep_sec_singleton_driver"
-#define SEP_DEV_DAEMON "sep_req_daemon_driver"
-
 /*--------------------------------------------------------
 	SHARED AREA  memory total size is 36K
 	it is divided is following:
@@ -90,7 +89,7 @@ held by the process (struct file) */
 									}
 	DATA_POOL_AREA                          12K        }
 
-	SYNCHRONIC_DMA_TABLES_AREA              5K
+	SYNCHRONIC_DMA_TABLES_AREA              29K
 
 	placeholder until drver changes
 	FLOW_DMA_TABLES_AREA                    4K
@@ -109,6 +108,12 @@ held by the process (struct file) */
 
 
 /*
+	the minimum length of the message - includes 2 reserved fields
+	at the start, then token, message size and opcode fields. all dwords
+*/
+#define SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES			(5*sizeof(u32))
+
+/*
 	the maximum length of the message - the rest of the message shared
 	area will be dedicated to the dma lli tables
 */
@@ -124,7 +129,7 @@ held by the process (struct file) */
 #define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES		(16 * 1024)
 
 /* the size of the message shared area in pages */
-#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES	(1024 * 5)
+#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES	(1024 * 29)
 
 /* Placeholder until driver changes */
 #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES		(1024 * 4)
@@ -132,6 +137,9 @@ held by the process (struct file) */
 /* system data (time, caller id etc') pool */
 #define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES		(1024 * 3)
 
+/* Offset of the sep printf buffer in the message area */
+#define SEP_DRIVER_PRINTF_OFFSET_IN_BYTES			(5888)
+
 /* the size in bytes of the time memory */
 #define SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES			8
 
@@ -223,10 +231,10 @@ held by the process (struct file) */
 #define SEP_ALREADY_INITIALIZED_ERR                           12
 
 /* bit that locks access to the shared area */
-#define SEP_MMAP_LOCK_BIT                                     0
+#define SEP_TRANSACTION_STARTED_LOCK_BIT                      0
 
 /* bit that lock access to the poll  - after send_command */
-#define SEP_SEND_MSG_LOCK_BIT                                 1
+#define SEP_WORKING_LOCK_BIT                                  1
 
 /* the token that defines the static pool address address */
 #define SEP_STATIC_POOL_VAL_TOKEN                             0xABBAABBA
@@ -240,4 +248,51 @@ held by the process (struct file) */
 /* Time limit for SEP to finish */
 #define WAIT_TIME 10
 
+/* Delay for pm runtime suspend (reduces pm thrashing with bursty traffic */
+#define SUSPEND_DELAY 10
+
+/* Number of delays to wait until scu boots after runtime resume */
+#define SCU_DELAY_MAX 50
+
+/* Delay for each iteration (usec) wait for scu boots after runtime resume */
+#define SCU_DELAY_ITERATION 10
+
+
+/*
+ * Bits used in struct sep_call_status to check that
+ * driver's APIs are called in valid order
+ */
+
+/* Bit offset which indicates status of sep_write() */
+#define SEP_FASTCALL_WRITE_DONE_OFFSET		0
+
+/* Bit offset which indicates status of sep_mmap() */
+#define SEP_LEGACY_MMAP_DONE_OFFSET		1
+
+/* Bit offset which indicates status of the SEP_IOCSENDSEPCOMMAND ioctl */
+#define SEP_LEGACY_SENDMSG_DONE_OFFSET		2
+
+/* Bit offset which indicates status of sep_poll() */
+#define SEP_LEGACY_POLL_DONE_OFFSET		3
+
+/* Bit offset which indicates status of the SEP_IOCENDTRANSACTION ioctl */
+#define SEP_LEGACY_ENDTRANSACTION_DONE_OFFSET	4
+
+/*
+ * Used to limit number of concurrent processes
+ * allowed to allocte dynamic buffers in fastcall
+ * interface.
+ */
+#define SEP_DOUBLEBUF_USERS_LIMIT		3
+
+/* Identifier for valid fastcall header */
+#define SEP_FC_MAGIC				0xFFAACCAA
+
+/*
+ * Used for enabling driver runtime power management.
+ * Useful for enabling/disabling it during performance
+ * testing
+ */
+#define SEP_ENABLE_RUNTIME_PM
+
 #endif /* SEP DRIVER CONFIG */
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h
index 300f909..a6a4481 100644
--- a/drivers/staging/sep/sep_driver_hw_defs.h
+++ b/drivers/staging/sep/sep_driver_hw_defs.h
@@ -2,8 +2,8 @@
  *
  *  sep_driver_hw_defs.h - Security Processor Driver hardware definitions
  *
- *  Copyright(c) 2009,2010 Intel Corporation. All rights reserved.
- *  Contributions(c) 2009,2010 Discretix. All rights reserved.
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2011 Discretix. All rights reserved.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms of the GNU General Public License as published by the Free
@@ -26,15 +26,13 @@
  *  CHANGES:
  *
  *  2010.09.20	Upgrade to Medfield
+ *  2011.02.22  Enable kernel crypto
  *
  */
 
 #ifndef SEP_DRIVER_HW_DEFS__H
 #define SEP_DRIVER_HW_DEFS__H
 
-/* PCI ID's */
-#define MFLD_PCI_DEVICE_ID 0x0826
-
 /*----------------------- */
 /* HW Registers Defines.  */
 /*                        */
@@ -42,181 +40,9 @@
 
 
 /* cf registers */
-#define		HW_R0B_ADDR_0_REG_ADDR			0x0000UL
-#define		HW_R0B_ADDR_1_REG_ADDR			0x0004UL
-#define		HW_R0B_ADDR_2_REG_ADDR			0x0008UL
-#define		HW_R0B_ADDR_3_REG_ADDR			0x000cUL
-#define		HW_R0B_ADDR_4_REG_ADDR			0x0010UL
-#define		HW_R0B_ADDR_5_REG_ADDR			0x0014UL
-#define		HW_R0B_ADDR_6_REG_ADDR			0x0018UL
-#define		HW_R0B_ADDR_7_REG_ADDR			0x001cUL
-#define		HW_R0B_ADDR_8_REG_ADDR			0x0020UL
-#define		HW_R2B_ADDR_0_REG_ADDR			0x0080UL
-#define		HW_R2B_ADDR_1_REG_ADDR			0x0084UL
-#define		HW_R2B_ADDR_2_REG_ADDR			0x0088UL
-#define		HW_R2B_ADDR_3_REG_ADDR			0x008cUL
-#define		HW_R2B_ADDR_4_REG_ADDR			0x0090UL
-#define		HW_R2B_ADDR_5_REG_ADDR			0x0094UL
-#define		HW_R2B_ADDR_6_REG_ADDR			0x0098UL
-#define		HW_R2B_ADDR_7_REG_ADDR			0x009cUL
-#define		HW_R2B_ADDR_8_REG_ADDR			0x00a0UL
-#define		HW_R3B_REG_ADDR				0x00C0UL
-#define		HW_R4B_REG_ADDR				0x0100UL
-#define		HW_CSA_ADDR_0_REG_ADDR			0x0140UL
-#define		HW_CSA_ADDR_1_REG_ADDR			0x0144UL
-#define		HW_CSA_ADDR_2_REG_ADDR			0x0148UL
-#define		HW_CSA_ADDR_3_REG_ADDR			0x014cUL
-#define		HW_CSA_ADDR_4_REG_ADDR			0x0150UL
-#define		HW_CSA_ADDR_5_REG_ADDR			0x0154UL
-#define		HW_CSA_ADDR_6_REG_ADDR			0x0158UL
-#define		HW_CSA_ADDR_7_REG_ADDR			0x015cUL
-#define		HW_CSA_ADDR_8_REG_ADDR			0x0160UL
-#define		HW_CSA_REG_ADDR				0x0140UL
-#define		HW_SINB_REG_ADDR			0x0180UL
-#define		HW_SOUTB_REG_ADDR			0x0184UL
-#define		HW_PKI_CONTROL_REG_ADDR			0x01C0UL
-#define		HW_PKI_STATUS_REG_ADDR			0x01C4UL
-#define		HW_PKI_BUSY_REG_ADDR			0x01C8UL
-#define		HW_PKI_A_1025_REG_ADDR			0x01CCUL
-#define		HW_PKI_SDMA_CTL_REG_ADDR		0x01D0UL
-#define		HW_PKI_SDMA_OFFSET_REG_ADDR		0x01D4UL
-#define		HW_PKI_SDMA_POINTERS_REG_ADDR		0x01D8UL
-#define		HW_PKI_SDMA_DLENG_REG_ADDR		0x01DCUL
-#define		HW_PKI_SDMA_EXP_POINTERS_REG_ADDR	0x01E0UL
-#define		HW_PKI_SDMA_RES_POINTERS_REG_ADDR	0x01E4UL
-#define		HW_PKI_CLR_REG_ADDR			0x01E8UL
-#define		HW_PKI_SDMA_BUSY_REG_ADDR		0x01E8UL
-#define		HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR	0x01ECUL
-#define		HW_PKI_SDMA_MUL_BY1_REG_ADDR		0x01F0UL
-#define		HW_PKI_SDMA_RMUL_SEL_REG_ADDR		0x01F4UL
-#define		HW_DES_KEY_0_REG_ADDR			0x0208UL
-#define		HW_DES_KEY_1_REG_ADDR			0x020CUL
-#define		HW_DES_KEY_2_REG_ADDR			0x0210UL
-#define		HW_DES_KEY_3_REG_ADDR			0x0214UL
-#define		HW_DES_KEY_4_REG_ADDR			0x0218UL
-#define		HW_DES_KEY_5_REG_ADDR			0x021CUL
-#define		HW_DES_CONTROL_0_REG_ADDR		0x0220UL
-#define		HW_DES_CONTROL_1_REG_ADDR		0x0224UL
-#define		HW_DES_IV_0_REG_ADDR			0x0228UL
-#define		HW_DES_IV_1_REG_ADDR			0x022CUL
-#define		HW_AES_KEY_0_ADDR_0_REG_ADDR		0x0400UL
-#define		HW_AES_KEY_0_ADDR_1_REG_ADDR		0x0404UL
-#define		HW_AES_KEY_0_ADDR_2_REG_ADDR		0x0408UL
-#define		HW_AES_KEY_0_ADDR_3_REG_ADDR		0x040cUL
-#define		HW_AES_KEY_0_ADDR_4_REG_ADDR		0x0410UL
-#define		HW_AES_KEY_0_ADDR_5_REG_ADDR		0x0414UL
-#define		HW_AES_KEY_0_ADDR_6_REG_ADDR		0x0418UL
-#define		HW_AES_KEY_0_ADDR_7_REG_ADDR		0x041cUL
-#define		HW_AES_KEY_0_REG_ADDR			0x0400UL
-#define		HW_AES_IV_0_ADDR_0_REG_ADDR		0x0440UL
-#define		HW_AES_IV_0_ADDR_1_REG_ADDR		0x0444UL
-#define		HW_AES_IV_0_ADDR_2_REG_ADDR		0x0448UL
-#define		HW_AES_IV_0_ADDR_3_REG_ADDR		0x044cUL
-#define		HW_AES_IV_0_REG_ADDR			0x0440UL
-#define		HW_AES_CTR1_ADDR_0_REG_ADDR		0x0460UL
-#define		HW_AES_CTR1_ADDR_1_REG_ADDR		0x0464UL
-#define		HW_AES_CTR1_ADDR_2_REG_ADDR		0x0468UL
-#define		HW_AES_CTR1_ADDR_3_REG_ADDR		0x046cUL
-#define		HW_AES_CTR1_REG_ADDR			0x0460UL
-#define		HW_AES_SK_REG_ADDR			0x0478UL
-#define		HW_AES_MAC_OK_REG_ADDR			0x0480UL
-#define		HW_AES_PREV_IV_0_ADDR_0_REG_ADDR	0x0490UL
-#define		HW_AES_PREV_IV_0_ADDR_1_REG_ADDR	0x0494UL
-#define		HW_AES_PREV_IV_0_ADDR_2_REG_ADDR	0x0498UL
-#define		HW_AES_PREV_IV_0_ADDR_3_REG_ADDR	0x049cUL
-#define		HW_AES_PREV_IV_0_REG_ADDR		0x0490UL
-#define		HW_AES_CONTROL_REG_ADDR			0x04C0UL
-#define		HW_HASH_H0_REG_ADDR			0x0640UL
-#define		HW_HASH_H1_REG_ADDR			0x0644UL
-#define		HW_HASH_H2_REG_ADDR			0x0648UL
-#define		HW_HASH_H3_REG_ADDR			0x064CUL
-#define		HW_HASH_H4_REG_ADDR			0x0650UL
-#define		HW_HASH_H5_REG_ADDR			0x0654UL
-#define		HW_HASH_H6_REG_ADDR			0x0658UL
-#define		HW_HASH_H7_REG_ADDR			0x065CUL
-#define		HW_HASH_H8_REG_ADDR			0x0660UL
-#define		HW_HASH_H9_REG_ADDR			0x0664UL
-#define		HW_HASH_H10_REG_ADDR			0x0668UL
-#define		HW_HASH_H11_REG_ADDR			0x066CUL
-#define		HW_HASH_H12_REG_ADDR			0x0670UL
-#define		HW_HASH_H13_REG_ADDR			0x0674UL
-#define		HW_HASH_H14_REG_ADDR			0x0678UL
-#define		HW_HASH_H15_REG_ADDR			0x067CUL
-#define		HW_HASH_CONTROL_REG_ADDR		0x07C0UL
-#define		HW_HASH_PAD_EN_REG_ADDR			0x07C4UL
-#define		HW_HASH_PAD_CFG_REG_ADDR		0x07C8UL
-#define		HW_HASH_CUR_LEN_0_REG_ADDR		0x07CCUL
-#define		HW_HASH_CUR_LEN_1_REG_ADDR		0x07D0UL
-#define		HW_HASH_CUR_LEN_2_REG_ADDR		0x07D4UL
-#define		HW_HASH_CUR_LEN_3_REG_ADDR		0x07D8UL
-#define		HW_HASH_PARAM_REG_ADDR			0x07DCUL
-#define		HW_HASH_INT_BUSY_REG_ADDR		0x07E0UL
-#define		HW_HASH_SW_RESET_REG_ADDR		0x07E4UL
-#define		HW_HASH_ENDIANESS_REG_ADDR		0x07E8UL
-#define		HW_HASH_DATA_REG_ADDR			0x07ECUL
-#define		HW_DRNG_CONTROL_REG_ADDR		0x0800UL
-#define		HW_DRNG_VALID_REG_ADDR			0x0804UL
-#define		HW_DRNG_DATA_REG_ADDR			0x0808UL
-#define		HW_RND_SRC_EN_REG_ADDR			0x080CUL
-#define		HW_AES_CLK_ENABLE_REG_ADDR		0x0810UL
-#define		HW_DES_CLK_ENABLE_REG_ADDR		0x0814UL
-#define		HW_HASH_CLK_ENABLE_REG_ADDR		0x0818UL
-#define		HW_PKI_CLK_ENABLE_REG_ADDR		0x081CUL
-#define		HW_CLK_STATUS_REG_ADDR			0x0824UL
-#define		HW_CLK_ENABLE_REG_ADDR			0x0828UL
-#define		HW_DRNG_SAMPLE_REG_ADDR			0x0850UL
-#define		HW_RND_SRC_CTL_REG_ADDR			0x0858UL
-#define		HW_CRYPTO_CTL_REG_ADDR			0x0900UL
-#define		HW_CRYPTO_STATUS_REG_ADDR		0x090CUL
-#define		HW_CRYPTO_BUSY_REG_ADDR			0x0910UL
-#define		HW_AES_BUSY_REG_ADDR			0x0914UL
-#define		HW_DES_BUSY_REG_ADDR			0x0918UL
-#define		HW_HASH_BUSY_REG_ADDR			0x091CUL
-#define		HW_CONTENT_REG_ADDR			0x0924UL
-#define		HW_VERSION_REG_ADDR			0x0928UL
-#define		HW_CONTEXT_ID_REG_ADDR			0x0930UL
-#define		HW_DIN_BUFFER_REG_ADDR			0x0C00UL
-#define		HW_DIN_MEM_DMA_BUSY_REG_ADDR		0x0c20UL
-#define		HW_SRC_LLI_MEM_ADDR_REG_ADDR		0x0c24UL
-#define		HW_SRC_LLI_WORD0_REG_ADDR		0x0C28UL
-#define		HW_SRC_LLI_WORD1_REG_ADDR		0x0C2CUL
-#define		HW_SRAM_SRC_ADDR_REG_ADDR		0x0c30UL
-#define		HW_DIN_SRAM_BYTES_LEN_REG_ADDR		0x0c34UL
-#define		HW_DIN_SRAM_DMA_BUSY_REG_ADDR		0x0C38UL
-#define		HW_WRITE_ALIGN_REG_ADDR			0x0C3CUL
-#define		HW_OLD_DATA_REG_ADDR			0x0C48UL
-#define		HW_WRITE_ALIGN_LAST_REG_ADDR		0x0C4CUL
-#define		HW_DOUT_BUFFER_REG_ADDR			0x0C00UL
-#define		HW_DST_LLI_WORD0_REG_ADDR		0x0D28UL
-#define		HW_DST_LLI_WORD1_REG_ADDR		0x0D2CUL
-#define		HW_DST_LLI_MEM_ADDR_REG_ADDR		0x0D24UL
-#define		HW_DOUT_MEM_DMA_BUSY_REG_ADDR		0x0D20UL
-#define		HW_SRAM_DEST_ADDR_REG_ADDR		0x0D30UL
-#define		HW_DOUT_SRAM_BYTES_LEN_REG_ADDR		0x0D34UL
-#define		HW_DOUT_SRAM_DMA_BUSY_REG_ADDR		0x0D38UL
-#define		HW_READ_ALIGN_REG_ADDR			0x0D3CUL
-#define		HW_READ_LAST_DATA_REG_ADDR		0x0D44UL
-#define		HW_RC4_THRU_CPU_REG_ADDR		0x0D4CUL
-#define		HW_AHB_SINGLE_REG_ADDR			0x0E00UL
-#define		HW_SRAM_DATA_REG_ADDR			0x0F00UL
-#define		HW_SRAM_ADDR_REG_ADDR			0x0F04UL
-#define		HW_SRAM_DATA_READY_REG_ADDR		0x0F08UL
 #define		HW_HOST_IRR_REG_ADDR			0x0A00UL
 #define		HW_HOST_IMR_REG_ADDR			0x0A04UL
 #define		HW_HOST_ICR_REG_ADDR			0x0A08UL
-#define		HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR	0x0A10UL
-#define		HW_HOST_SEP_BUSY_REG_ADDR		0x0A14UL
-#define		HW_HOST_SEP_LCS_REG_ADDR		0x0A18UL
-#define		HW_HOST_CC_SW_RST_REG_ADDR		0x0A40UL
-#define		HW_HOST_SEP_SW_RST_REG_ADDR		0x0A44UL
-#define		HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR	0x0A80UL
-#define		HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR	0x0A84UL
-#define		HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR	0x0A88UL
-#define		HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR	0x0A8cUL
-#define		HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR	0x0A90UL
-#define		HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR	0x0A94UL
-#define		HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR	0x0A98UL
-#define		HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR	0x0A9cUL
 #define		HW_HOST_SEP_HOST_GPR0_REG_ADDR		0x0B00UL
 #define		HW_HOST_SEP_HOST_GPR1_REG_ADDR		0x0B04UL
 #define		HW_HOST_SEP_HOST_GPR2_REG_ADDR		0x0B08UL
@@ -225,9 +51,6 @@
 #define		HW_HOST_HOST_SEP_GPR1_REG_ADDR		0x0B84UL
 #define		HW_HOST_HOST_SEP_GPR2_REG_ADDR		0x0B88UL
 #define		HW_HOST_HOST_SEP_GPR3_REG_ADDR		0x0B8CUL
-#define		HW_HOST_HOST_ENDIAN_REG_ADDR		0x0B90UL
-#define		HW_HOST_HOST_COMM_CLK_EN_REG_ADDR	0x0B94UL
-#define		HW_CLR_SRAM_BUSY_REG_REG_ADDR		0x0F0CUL
-#define		HW_CC_SRAM_BASE_ADDRESS			0x5800UL
+#define		HW_SRAM_DATA_READY_REG_ADDR		0x0F08UL
 
 #endif		/* ifndef HW_DEFS */
diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c
new file mode 100644
index 0000000..ad54c2e
--- /dev/null
+++ b/drivers/staging/sep/sep_main.c
@@ -0,0 +1,4518 @@
+/*
+ *
+ *  sep_main.c - Security Processor Driver main group of functions
+ *
+ *  Copyright(c) 2009-2011 Intel Corporation. All rights reserved.
+ *  Contributions(c) 2009-2011 Discretix. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ *  more details.
+ *
+ *  You should have received a copy of the GNU General Public License along with
+ *  this program; if not, write to the Free Software Foundation, Inc., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *  Jayant Mangalampalli jayant.mangalampalli@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *  2010.09.14  Upgrade to Medfield
+ *  2011.01.21  Move to sep_main.c to allow for sep_crypto.c
+ *  2011.02.22  Enable kernel crypto operation
+ *
+ *  Please note that this driver is based on information in the Discretix
+ *  CryptoCell 5.2 Driver Implementation Guide; the Discretix CryptoCell 5.2
+ *  Integration Intel Medfield appendix; the Discretix CryptoCell 5.2
+ *  Linux Driver Integration Guide; and the Discretix CryptoCell 5.2 System
+ *  Overview and Integration Guide.
+ */
+/* #define DEBUG */
+/* #define SEP_PERF_DEBUG */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/kdev_t.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/ioctl.h>
+#include <asm/current.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/async.h>
+#include <linux/crypto.h>
+#include <crypto/internal/hash.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/sha.h>
+#include <crypto/md5.h>
+#include <crypto/aes.h>
+#include <crypto/des.h>
+#include <crypto/hash.h>
+
+#include "sep_driver_hw_defs.h"
+#include "sep_driver_config.h"
+#include "sep_driver_api.h"
+#include "sep_dev.h"
+#include "sep_crypto.h"
+
+#define CREATE_TRACE_POINTS
+#include "sep_trace_events.h"
+
+/*
+ * Let's not spend cycles iterating over message
+ * area contents if debugging not enabled
+ */
+#ifdef DEBUG
+#define sep_dump_message(sep)	_sep_dump_message(sep)
+#else
+#define sep_dump_message(sep)
+#endif
+
+/**
+ * Currenlty, there is only one SEP device per platform;
+ * In event platforms in the future have more than one SEP
+ * device, this will be a linked list
+ */
+
+struct sep_device *sep_dev;
+
+/**
+ * sep_queue_status_remove - Removes transaction from status queue
+ * @sep: SEP device
+ * @sep_queue_info: pointer to status queue
+ *
+ * This function will removes information about transaction from the queue.
+ */
+void sep_queue_status_remove(struct sep_device *sep,
+				      struct sep_queue_info **queue_elem)
+{
+	unsigned long lck_flags;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove\n",
+		current->pid);
+
+	if (!queue_elem || !(*queue_elem)) {
+		dev_dbg(&sep->pdev->dev, "PID%d %s null\n",
+					current->pid, __func__);
+		return;
+	}
+
+	spin_lock_irqsave(&sep->sep_queue_lock, lck_flags);
+	list_del(&(*queue_elem)->list);
+	sep->sep_queue_num--;
+	spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
+
+	kfree(*queue_elem);
+	*queue_elem = NULL;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove return\n",
+		current->pid);
+	return;
+}
+
+/**
+ * sep_queue_status_add - Adds transaction to status queue
+ * @sep: SEP device
+ * @opcode: transaction opcode
+ * @size: input data size
+ * @pid: pid of current process
+ * @name: current process name
+ * @name_len: length of name (current process)
+ *
+ * This function adds information about about transaction started to the status
+ * queue.
+ */
+struct sep_queue_info *sep_queue_status_add(
+						struct sep_device *sep,
+						u32 opcode,
+						u32 size,
+						u32 pid,
+						u8 *name, size_t name_len)
+{
+	unsigned long lck_flags;
+	struct sep_queue_info *my_elem = NULL;
+
+	my_elem = kzalloc(sizeof(struct sep_queue_info), GFP_KERNEL);
+
+	if (!my_elem)
+		return NULL;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] kzalloc ok\n", current->pid);
+
+	my_elem->data.opcode = opcode;
+	my_elem->data.size = size;
+	my_elem->data.pid = pid;
+
+	if (name_len > TASK_COMM_LEN)
+		name_len = TASK_COMM_LEN;
+
+	memcpy(&my_elem->data.name, name, name_len);
+
+	spin_lock_irqsave(&sep->sep_queue_lock, lck_flags);
+
+	list_add_tail(&my_elem->list, &sep->sep_queue_status);
+	sep->sep_queue_num++;
+
+	spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
+
+	return my_elem;
+}
+
+/**
+ *	sep_allocate_dmatables_region - Allocates buf for the MLLI/DMA tables
+ *	@sep: SEP device
+ *	@dmatables_region: Destination pointer for the buffer
+ *	@dma_ctx: DMA context for the transaction
+ *	@table_count: Number of MLLI/DMA tables to create
+ *	The buffer created will not work as-is for DMA operations,
+ *	it needs to be copied over to the appropriate place in the
+ *	shared area.
+ */
+static int sep_allocate_dmatables_region(struct sep_device *sep,
+					 void **dmatables_region,
+					 struct sep_dma_context *dma_ctx,
+					 const u32 table_count)
+{
+	const size_t new_len =
+		SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1;
+
+	void *tmp_region = NULL;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] dma_ctx = 0x%p\n",
+				current->pid, dma_ctx);
+	dev_dbg(&sep->pdev->dev, "[PID%d] dmatables_region = 0x%p\n",
+				current->pid, dmatables_region);
+
+	if (!dma_ctx || !dmatables_region) {
+		dev_warn(&sep->pdev->dev,
+			"[PID%d] dma context/region uninitialized\n",
+			current->pid);
+		return -EINVAL;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08zX\n",
+				current->pid, new_len);
+	dev_dbg(&sep->pdev->dev, "[PID%d] oldlen = 0x%08X\n", current->pid,
+				dma_ctx->dmatables_len);
+	tmp_region = kzalloc(new_len + dma_ctx->dmatables_len, GFP_KERNEL);
+	if (!tmp_region) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] no mem for dma tables region\n",
+				current->pid);
+		return -ENOMEM;
+	}
+
+	/* Were there any previous tables that need to be preserved ? */
+	if (*dmatables_region) {
+		memcpy(tmp_region, *dmatables_region, dma_ctx->dmatables_len);
+		kfree(*dmatables_region);
+		*dmatables_region = NULL;
+	}
+
+	*dmatables_region = tmp_region;
+
+	dma_ctx->dmatables_len += new_len;
+
+	return 0;
+}
+
+/**
+ *	sep_wait_transaction - Used for synchronizing transactions
+ *	@sep: SEP device
+ */
+int sep_wait_transaction(struct sep_device *sep)
+{
+	int error = 0;
+	DEFINE_WAIT(wait);
+
+	if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
+				&sep->in_use_flags)) {
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] no transactions, returning\n",
+				current->pid);
+		goto end_function_setpid;
+	}
+
+	/*
+	 * Looping needed even for exclusive waitq entries
+	 * due to process wakeup latencies, previous process
+	 * might have already created another transaction.
+	 */
+	for (;;) {
+		/*
+		 * Exclusive waitq entry, so that only one process is
+		 * woken up from the queue at a time.
+		 */
+		prepare_to_wait_exclusive(&sep->event_transactions,
+					  &wait,
+					  TASK_INTERRUPTIBLE);
+		if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT,
+					  &sep->in_use_flags)) {
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] no transactions, breaking\n",
+					current->pid);
+			break;
+		}
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] transactions ongoing, sleeping\n",
+				current->pid);
+		schedule();
+		dev_dbg(&sep->pdev->dev, "[PID%d] woken up\n", current->pid);
+
+		if (signal_pending(current)) {
+			dev_dbg(&sep->pdev->dev, "[PID%d] received signal\n",
+							current->pid);
+			error = -EINTR;
+			goto end_function;
+		}
+	}
+end_function_setpid:
+	/*
+	 * The pid_doing_transaction indicates that this process
+	 * now owns the facilities to performa a transaction with
+	 * the SEP. While this process is performing a transaction,
+	 * no other process who has the SEP device open can perform
+	 * any transactions. This method allows more than one process
+	 * to have the device open at any given time, which provides
+	 * finer granularity for device utilization by multiple
+	 * processes.
+	 */
+	/* Only one process is able to progress here at a time */
+	sep->pid_doing_transaction = current->pid;
+
+end_function:
+	finish_wait(&sep->event_transactions, &wait);
+
+	return error;
+}
+
+/**
+ * sep_check_transaction_owner - Checks if current process owns transaction
+ * @sep: SEP device
+ */
+static inline int sep_check_transaction_owner(struct sep_device *sep)
+{
+	dev_dbg(&sep->pdev->dev, "[PID%d] transaction pid = %d\n",
+		current->pid,
+		sep->pid_doing_transaction);
+
+	if ((sep->pid_doing_transaction == 0) ||
+		(current->pid != sep->pid_doing_transaction)) {
+		return -EACCES;
+	}
+
+	/* We own the transaction */
+	return 0;
+}
+
+#ifdef DEBUG
+
+/**
+ * sep_dump_message - dump the message that is pending
+ * @sep: SEP device
+ * This will only print dump if DEBUG is set; it does
+ * follow kernel debug print enabling
+ */
+static void _sep_dump_message(struct sep_device *sep)
+{
+	int count;
+
+	u32 *p = sep->shared_addr;
+
+	for (count = 0; count < 10 * 4; count += 4)
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] Word %d of the message is %x\n",
+				current->pid, count/4, *p++);
+}
+
+#endif
+
+/**
+ * sep_map_and_alloc_shared_area -allocate shared block
+ * @sep: security processor
+ * @size: size of shared area
+ */
+static int sep_map_and_alloc_shared_area(struct sep_device *sep)
+{
+	sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev,
+		sep->shared_size,
+		&sep->shared_bus, GFP_KERNEL);
+
+	if (!sep->shared_addr) {
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] shared memory dma_alloc_coherent failed\n",
+				current->pid);
+		return -ENOMEM;
+	}
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] shared_addr %zx bytes @%p (bus %llx)\n",
+				current->pid,
+				sep->shared_size, sep->shared_addr,
+				(unsigned long long)sep->shared_bus);
+	return 0;
+}
+
+/**
+ * sep_unmap_and_free_shared_area - free shared block
+ * @sep: security processor
+ */
+static void sep_unmap_and_free_shared_area(struct sep_device *sep)
+{
+	dma_free_coherent(&sep->pdev->dev, sep->shared_size,
+				sep->shared_addr, sep->shared_bus);
+}
+
+#ifdef DEBUG
+
+/**
+ * sep_shared_bus_to_virt - convert bus/virt addresses
+ * @sep: pointer to struct sep_device
+ * @bus_address: address to convert
+ *
+ * Returns virtual address inside the shared area according
+ * to the bus address.
+ */
+static void *sep_shared_bus_to_virt(struct sep_device *sep,
+						dma_addr_t bus_address)
+{
+	return sep->shared_addr + (bus_address - sep->shared_bus);
+}
+
+#endif
+
+/**
+ * sep_open - device open method
+ * @inode: inode of SEP device
+ * @filp: file handle to SEP device
+ *
+ * Open method for the SEP device. Called when userspace opens
+ * the SEP device node.
+ *
+ * Returns zero on success otherwise an error code.
+ */
+static int sep_open(struct inode *inode, struct file *filp)
+{
+	struct sep_device *sep;
+	struct sep_private_data *priv;
+
+	dev_dbg(&sep_dev->pdev->dev, "[PID%d] open\n", current->pid);
+
+	if (filp->f_flags & O_NONBLOCK)
+		return -ENOTSUPP;
+
+	/*
+	 * Get the SEP device structure and use it for the
+	 * private_data field in filp for other methods
+	 */
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	sep = sep_dev;
+	priv->device = sep;
+	filp->private_data = priv;
+
+	dev_dbg(&sep_dev->pdev->dev, "[PID%d] priv is 0x%p\n",
+					current->pid, priv);
+
+	/* Anyone can open; locking takes place at transaction level */
+	return 0;
+}
+
+/**
+ * sep_free_dma_table_data_handler - free DMA table
+ * @sep: pointere to struct sep_device
+ * @dma_ctx: dma context
+ *
+ * Handles the request to  free DMA table for synchronic actions
+ */
+int sep_free_dma_table_data_handler(struct sep_device *sep,
+					   struct sep_dma_context **dma_ctx)
+{
+	int count;
+	int dcb_counter;
+	/* Pointer to the current dma_resource struct */
+	struct sep_dma_resource *dma;
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] sep_free_dma_table_data_handler\n",
+			current->pid);
+
+	if (!dma_ctx || !(*dma_ctx)) {
+		/* No context or context already freed */
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] no DMA context or context already freed\n",
+				current->pid);
+
+		return 0;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] (*dma_ctx)->nr_dcb_creat 0x%x\n",
+					current->pid,
+					(*dma_ctx)->nr_dcb_creat);
+
+	for (dcb_counter = 0;
+	     dcb_counter < (*dma_ctx)->nr_dcb_creat; dcb_counter++) {
+		dma = &(*dma_ctx)->dma_res_arr[dcb_counter];
+
+		/* Unmap and free input map array */
+		if (dma->in_map_array) {
+			for (count = 0; count < dma->in_num_pages; count++) {
+				dma_unmap_page(&sep->pdev->dev,
+					dma->in_map_array[count].dma_addr,
+					dma->in_map_array[count].size,
+					DMA_TO_DEVICE);
+			}
+			kfree(dma->in_map_array);
+		}
+
+		/**
+		 * Output is handled different. If
+		 * this was a secure dma into restricted memory,
+		 * then we skip this step altogether as restricted
+		 * memory is not available to the o/s at all.
+		 */
+		if (((*dma_ctx)->secure_dma == false) &&
+			(dma->out_map_array)) {
+
+			for (count = 0; count < dma->out_num_pages; count++) {
+				dma_unmap_page(&sep->pdev->dev,
+					dma->out_map_array[count].dma_addr,
+					dma->out_map_array[count].size,
+					DMA_FROM_DEVICE);
+			}
+			kfree(dma->out_map_array);
+		}
+
+		/* Free page cache for output */
+		if (dma->in_page_array) {
+			for (count = 0; count < dma->in_num_pages; count++) {
+				flush_dcache_page(dma->in_page_array[count]);
+				page_cache_release(dma->in_page_array[count]);
+			}
+			kfree(dma->in_page_array);
+		}
+
+		/* Again, we do this only for non secure dma */
+		if (((*dma_ctx)->secure_dma == false) &&
+			(dma->out_page_array)) {
+
+			for (count = 0; count < dma->out_num_pages; count++) {
+				if (!PageReserved(dma->out_page_array[count]))
+
+					SetPageDirty(dma->
+					out_page_array[count]);
+
+				flush_dcache_page(dma->out_page_array[count]);
+				page_cache_release(dma->out_page_array[count]);
+			}
+			kfree(dma->out_page_array);
+		}
+
+		/**
+		 * Note that here we use in_map_num_entries because we
+		 * don't have a page array; the page array is generated
+		 * only in the lock_user_pages, which is not called
+		 * for kernel crypto, which is what the sg (scatter gather
+		 * is used for exclusively
+		 */
+		if (dma->src_sg) {
+			dma_unmap_sg(&sep->pdev->dev, dma->src_sg,
+				dma->in_map_num_entries, DMA_TO_DEVICE);
+			dma->src_sg = NULL;
+		}
+
+		if (dma->dst_sg) {
+			dma_unmap_sg(&sep->pdev->dev, dma->dst_sg,
+				dma->in_map_num_entries, DMA_FROM_DEVICE);
+			dma->dst_sg = NULL;
+		}
+
+		/* Reset all the values */
+		dma->in_page_array = NULL;
+		dma->out_page_array = NULL;
+		dma->in_num_pages = 0;
+		dma->out_num_pages = 0;
+		dma->in_map_array = NULL;
+		dma->out_map_array = NULL;
+		dma->in_map_num_entries = 0;
+		dma->out_map_num_entries = 0;
+	}
+
+	(*dma_ctx)->nr_dcb_creat = 0;
+	(*dma_ctx)->num_lli_tables_created = 0;
+
+	kfree(*dma_ctx);
+	*dma_ctx = NULL;
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] sep_free_dma_table_data_handler end\n",
+			current->pid);
+
+	return 0;
+}
+
+/**
+ * sep_end_transaction_handler - end transaction
+ * @sep: pointer to struct sep_device
+ * @dma_ctx: DMA context
+ * @call_status: Call status
+ *
+ * This API handles the end transaction request.
+ */
+static int sep_end_transaction_handler(struct sep_device *sep,
+				       struct sep_dma_context **dma_ctx,
+				       struct sep_call_status *call_status,
+				       struct sep_queue_info **my_queue_elem)
+{
+	dev_dbg(&sep->pdev->dev, "[PID%d] ending transaction\n", current->pid);
+
+	/*
+	 * Extraneous transaction clearing would mess up PM
+	 * device usage counters and SEP would get suspended
+	 * just before we send a command to SEP in the next
+	 * transaction
+	 * */
+	if (sep_check_transaction_owner(sep)) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] not transaction owner\n",
+						current->pid);
+		return 0;
+	}
+
+	/* Update queue status */
+	sep_queue_status_remove(sep, my_queue_elem);
+
+	/* Check that all the DMA resources were freed */
+	if (dma_ctx)
+		sep_free_dma_table_data_handler(sep, dma_ctx);
+
+	/* Reset call status for next transaction */
+	if (call_status)
+		call_status->status = 0;
+
+	/* Clear the message area to avoid next transaction reading
+	 * sensitive results from previous transaction */
+	memset(sep->shared_addr, 0,
+	       SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	/* start suspend delay */
+#ifdef SEP_ENABLE_RUNTIME_PM
+	if (sep->in_use) {
+		sep->in_use = 0;
+		pm_runtime_mark_last_busy(&sep->pdev->dev);
+		pm_runtime_put_autosuspend(&sep->pdev->dev);
+	}
+#endif
+
+	clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags);
+	sep->pid_doing_transaction = 0;
+
+	/* Now it's safe for next process to proceed */
+	dev_dbg(&sep->pdev->dev, "[PID%d] waking up next transaction\n",
+					current->pid);
+	clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, &sep->in_use_flags);
+	wake_up(&sep->event_transactions);
+
+	return 0;
+}
+
+
+/**
+ * sep_release - close a SEP device
+ * @inode: inode of SEP device
+ * @filp: file handle being closed
+ *
+ * Called on the final close of a SEP device.
+ */
+static int sep_release(struct inode *inode, struct file *filp)
+{
+	struct sep_private_data * const private_data = filp->private_data;
+	struct sep_call_status *call_status = &private_data->call_status;
+	struct sep_device *sep = private_data->device;
+	struct sep_dma_context **dma_ctx = &private_data->dma_ctx;
+	struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] release\n", current->pid);
+
+	sep_end_transaction_handler(sep, dma_ctx, call_status,
+		my_queue_elem);
+
+	kfree(filp->private_data);
+
+	return 0;
+}
+
+/**
+ * sep_mmap -  maps the shared area to user space
+ * @filp: pointer to struct file
+ * @vma: pointer to vm_area_struct
+ *
+ * Called on an mmap of our space via the normal SEP device
+ */
+static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct sep_private_data * const private_data = filp->private_data;
+	struct sep_call_status *call_status = &private_data->call_status;
+	struct sep_device *sep = private_data->device;
+	struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
+	dma_addr_t bus_addr;
+	unsigned long error = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_mmap\n", current->pid);
+
+	/* Set the transaction busy (own the device) */
+	/*
+	 * Problem for multithreaded applications is that here we're
+	 * possibly going to sleep while holding a write lock on
+	 * current->mm->mmap_sem, which will cause deadlock for ongoing
+	 * transaction trying to create DMA tables
+	 */
+	error = sep_wait_transaction(sep);
+	if (error)
+		/* Interrupted by signal, don't clear transaction */
+		goto end_function;
+
+	/* Clear the message area to avoid next transaction reading
+	 * sensitive results from previous transaction */
+	memset(sep->shared_addr, 0,
+	       SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES);
+
+	/*
+	 * Check that the size of the mapped range is as the size of the message
+	 * shared area
+	 */
+	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
+		error = -EINVAL;
+		goto end_function_with_error;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] shared_addr is %p\n",
+					current->pid, sep->shared_addr);
+
+	/* Get bus address */
+	bus_addr = sep->shared_bus;
+
+	if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT,
+		vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] remap_page_range failed\n",
+						current->pid);
+		error = -EAGAIN;
+		goto end_function_with_error;
+	}
+
+	/* Update call status */
+	set_bit(SEP_LEGACY_MMAP_DONE_OFFSET, &call_status->status);
+
+	goto end_function;
+
+end_function_with_error:
+	/* Clear our transaction */
+	sep_end_transaction_handler(sep, NULL, call_status,
+		my_queue_elem);
+
+end_function:
+	return error;
+}
+
+/**
+ * sep_poll - poll handler
+ * @filp:	pointer to struct file
+ * @wait:	pointer to poll_table
+ *
+ * Called by the OS when the kernel is asked to do a poll on
+ * a SEP file handle.
+ */
+static unsigned int sep_poll(struct file *filp, poll_table *wait)
+{
+	struct sep_private_data * const private_data = filp->private_data;
+	struct sep_call_status *call_status = &private_data->call_status;
+	struct sep_device *sep = private_data->device;
+	u32 mask = 0;
+	u32 retval = 0;
+	u32 retval2 = 0;
+	unsigned long lock_irq_flag;
+
+	/* Am I the process that owns the transaction? */
+	if (sep_check_transaction_owner(sep)) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] poll pid not owner\n",
+						current->pid);
+		mask = POLLERR;
+		goto end_function;
+	}
+
+	/* Check if send command or send_reply were activated previously */
+	if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
+			  &call_status->status)) {
+		dev_warn(&sep->pdev->dev, "[PID%d] sendmsg not called\n",
+						current->pid);
+		mask = POLLERR;
+		goto end_function;
+	}
+
+
+	/* Add the event to the polling wait table */
+	dev_dbg(&sep->pdev->dev, "[PID%d] poll: calling wait sep_event\n",
+					current->pid);
+
+	poll_wait(filp, &sep->event_interrupt, wait);
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] poll: send_ct is %lx reply ct is %lx\n",
+			current->pid, sep->send_ct, sep->reply_ct);
+
+	/* Check if error occured during poll */
+	retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+	if ((retval2 != 0x0) && (retval2 != 0x8)) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] poll; poll error %x\n",
+						current->pid, retval2);
+		mask |= POLLERR;
+		goto end_function;
+	}
+
+	spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag);
+
+	if (sep->send_ct == sep->reply_ct) {
+		spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
+		retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] poll: data ready check (GPR2)  %x\n",
+				current->pid, retval);
+
+		/* Check if printf request  */
+		if ((retval >> 30) & 0x1) {
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] poll: SEP printf request\n",
+					current->pid);
+			goto end_function;
+		}
+
+		/* Check if the this is SEP reply or request */
+		if (retval >> 31) {
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] poll: SEP request\n",
+					current->pid);
+		} else {
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] poll: normal return\n",
+					current->pid);
+			sep_dump_message(sep);
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] poll; SEP reply POLLIN|POLLRDNORM\n",
+					current->pid);
+			mask |= POLLIN | POLLRDNORM;
+		}
+		set_bit(SEP_LEGACY_POLL_DONE_OFFSET, &call_status->status);
+	} else {
+		spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] poll; no reply; returning mask of 0\n",
+				current->pid);
+		mask = 0;
+	}
+
+end_function:
+	return mask;
+}
+
+/**
+ * sep_time_address - address in SEP memory of time
+ * @sep: SEP device we want the address from
+ *
+ * Return the address of the two dwords in memory used for time
+ * setting.
+ */
+static u32 *sep_time_address(struct sep_device *sep)
+{
+	return sep->shared_addr +
+		SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
+}
+
+/**
+ * sep_set_time - set the SEP time
+ * @sep: the SEP we are setting the time for
+ *
+ * Calculates time and sets it at the predefined address.
+ * Called with the SEP mutex held.
+ */
+static unsigned long sep_set_time(struct sep_device *sep)
+{
+	struct timeval time;
+	u32 *time_addr;	/* Address of time as seen by the kernel */
+
+
+	do_gettimeofday(&time);
+
+	/* Set value in the SYSTEM MEMORY offset */
+	time_addr = sep_time_address(sep);
+
+	time_addr[0] = SEP_TIME_VAL_TOKEN;
+	time_addr[1] = time.tv_sec;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] time.tv_sec is %lu\n",
+					current->pid, time.tv_sec);
+	dev_dbg(&sep->pdev->dev, "[PID%d] time_addr is %p\n",
+					current->pid, time_addr);
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep->shared_addr is %p\n",
+					current->pid, sep->shared_addr);
+
+	return time.tv_sec;
+}
+
+/**
+ * sep_send_command_handler - kick off a command
+ * @sep: SEP being signalled
+ *
+ * This function raises interrupt to SEP that signals that is has a new
+ * command from the host
+ *
+ * Note that this function does fall under the ioctl lock
+ */
+int sep_send_command_handler(struct sep_device *sep)
+{
+	unsigned long lock_irq_flag;
+	u32 *msg_pool;
+	int error = 0;
+
+	/* Basic sanity check; set msg pool to start of shared area */
+	msg_pool = (u32 *)sep->shared_addr;
+	msg_pool += 2;
+
+	/* Look for start msg token */
+	if (*msg_pool != SEP_START_MSG_TOKEN) {
+		dev_warn(&sep->pdev->dev, "start message token not present\n");
+		error = -EPROTO;
+		goto end_function;
+	}
+
+	/* Do we have a reasonable size? */
+	msg_pool += 1;
+	if ((*msg_pool < 2) ||
+		(*msg_pool > SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES)) {
+
+		dev_warn(&sep->pdev->dev, "invalid message size\n");
+		error = -EPROTO;
+		goto end_function;
+	}
+
+	/* Does the command look reasonable? */
+	msg_pool += 1;
+	if (*msg_pool < 2) {
+		dev_warn(&sep->pdev->dev, "invalid message opcode\n");
+		error = -EPROTO;
+		goto end_function;
+	}
+
+#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM)
+	dev_dbg(&sep->pdev->dev, "[PID%d] before pm sync status 0x%X\n",
+					current->pid,
+					sep->pdev->dev.power.runtime_status);
+	sep->in_use = 1; /* device is about to be used */
+	pm_runtime_get_sync(&sep->pdev->dev);
+#endif
+
+	if (test_and_set_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags)) {
+		error = -EPROTO;
+		goto end_function;
+	}
+	sep->in_use = 1; /* device is about to be used */
+	sep_set_time(sep);
+
+	sep_dump_message(sep);
+
+	/* Update counter */
+	spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag);
+	sep->send_ct++;
+	spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] sep_send_command_handler send_ct %lx reply_ct %lx\n",
+			current->pid, sep->send_ct, sep->reply_ct);
+
+	/* Send interrupt to SEP */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
+
+end_function:
+	return error;
+}
+
+/**
+ *	sep_crypto_dma -
+ *	@sep: pointer to struct sep_device
+ *	@sg: pointer to struct scatterlist
+ *	@direction:
+ *	@dma_maps: pointer to place a pointer to array of dma maps
+ *	 This is filled in; anything previous there will be lost
+ *	 The structure for dma maps is sep_dma_map
+ *	@returns number of dma maps on success; negative on error
+ *
+ *	This creates the dma table from the scatterlist
+ *	It is used only for kernel crypto as it works with scatterlists
+ *	representation of data buffers
+ *
+ */
+static int sep_crypto_dma(
+	struct sep_device *sep,
+	struct scatterlist *sg,
+	struct sep_dma_map **dma_maps,
+	enum dma_data_direction direction)
+{
+	struct scatterlist *temp_sg;
+
+	u32 count_segment;
+	u32 count_mapped;
+	struct sep_dma_map *sep_dma;
+	int ct1;
+
+	if (sg->length == 0)
+		return 0;
+
+	/* Count the segments */
+	temp_sg = sg;
+	count_segment = 0;
+	while (temp_sg) {
+		count_segment += 1;
+		temp_sg = scatterwalk_sg_next(temp_sg);
+	}
+	dev_dbg(&sep->pdev->dev,
+		"There are (hex) %x segments in sg\n", count_segment);
+
+	/* DMA map segments */
+	count_mapped = dma_map_sg(&sep->pdev->dev, sg,
+		count_segment, direction);
+
+	dev_dbg(&sep->pdev->dev,
+		"There are (hex) %x maps in sg\n", count_mapped);
+
+	if (count_mapped == 0) {
+		dev_dbg(&sep->pdev->dev, "Cannot dma_map_sg\n");
+		return -ENOMEM;
+	}
+
+	sep_dma = kmalloc(sizeof(struct sep_dma_map) *
+		count_mapped, GFP_ATOMIC);
+
+	if (sep_dma == NULL) {
+		dev_dbg(&sep->pdev->dev, "Cannot allocate dma_maps\n");
+		return -ENOMEM;
+	}
+
+	for_each_sg(sg, temp_sg, count_mapped, ct1) {
+		sep_dma[ct1].dma_addr = sg_dma_address(temp_sg);
+		sep_dma[ct1].size = sg_dma_len(temp_sg);
+		dev_dbg(&sep->pdev->dev, "(all hex) map %x dma %lx len %lx\n",
+			ct1, (unsigned long)sep_dma[ct1].dma_addr,
+			(unsigned long)sep_dma[ct1].size);
+		}
+
+	*dma_maps = sep_dma;
+	return count_mapped;
+
+}
+
+/**
+ *	sep_crypto_lli -
+ *	@sep: pointer to struct sep_device
+ *	@sg: pointer to struct scatterlist
+ *	@data_size: total data size
+ *	@direction:
+ *	@dma_maps: pointer to place a pointer to array of dma maps
+ *	 This is filled in; anything previous there will be lost
+ *	 The structure for dma maps is sep_dma_map
+ *	@lli_maps: pointer to place a pointer to array of lli maps
+ *	 This is filled in; anything previous there will be lost
+ *	 The structure for dma maps is sep_dma_map
+ *	@returns number of dma maps on success; negative on error
+ *
+ *	This creates the LLI table from the scatterlist
+ *	It is only used for kernel crypto as it works exclusively
+ *	with scatterlists (struct scatterlist) representation of
+ *	data buffers
+ */
+static int sep_crypto_lli(
+	struct sep_device *sep,
+	struct scatterlist *sg,
+	struct sep_dma_map **maps,
+	struct sep_lli_entry **llis,
+	u32 data_size,
+	enum dma_data_direction direction)
+{
+
+	int ct1;
+	struct sep_lli_entry *sep_lli;
+	struct sep_dma_map *sep_map;
+
+	int nbr_ents;
+
+	nbr_ents = sep_crypto_dma(sep, sg, maps, direction);
+	if (nbr_ents <= 0) {
+		dev_dbg(&sep->pdev->dev, "crypto_dma failed %x\n",
+			nbr_ents);
+		return nbr_ents;
+	}
+
+	sep_map = *maps;
+
+	sep_lli = kmalloc(sizeof(struct sep_lli_entry) * nbr_ents, GFP_ATOMIC);
+
+	if (sep_lli == NULL) {
+		dev_dbg(&sep->pdev->dev, "Cannot allocate lli_maps\n");
+
+		kfree(*maps);
+		*maps = NULL;
+		return -ENOMEM;
+	}
+
+	for (ct1 = 0; ct1 < nbr_ents; ct1 += 1) {
+		sep_lli[ct1].bus_address = (u32)sep_map[ct1].dma_addr;
+
+		/* Maximum for page is total data size */
+		if (sep_map[ct1].size > data_size)
+			sep_map[ct1].size = data_size;
+
+		sep_lli[ct1].block_size = (u32)sep_map[ct1].size;
+	}
+
+	*llis = sep_lli;
+	return nbr_ents;
+}
+
+/**
+ *	sep_lock_kernel_pages - map kernel pages for DMA
+ *	@sep: pointer to struct sep_device
+ *	@kernel_virt_addr: address of data buffer in kernel
+ *	@data_size: size of data
+ *	@lli_array_ptr: lli array
+ *	@in_out_flag: input into device or output from device
+ *
+ *	This function locks all the physical pages of the kernel virtual buffer
+ *	and construct a basic lli  array, where each entry holds the physical
+ *	page address and the size that application data holds in this page
+ *	This function is used only during kernel crypto mod calls from within
+ *	the kernel (when ioctl is not used)
+ *
+ *	This is used only for kernel crypto. Kernel pages
+ *	are handled differently as they are done via
+ *	scatter gather lists (struct scatterlist)
+ */
+static int sep_lock_kernel_pages(struct sep_device *sep,
+	unsigned long kernel_virt_addr,
+	u32 data_size,
+	struct sep_lli_entry **lli_array_ptr,
+	int in_out_flag,
+	struct sep_dma_context *dma_ctx)
+
+{
+	u32 num_pages;
+	struct scatterlist *sg;
+
+	/* Array of lli */
+	struct sep_lli_entry *lli_array;
+	/* Map array */
+	struct sep_dma_map *map_array;
+
+	enum dma_data_direction direction;
+
+	lli_array = NULL;
+	map_array = NULL;
+
+	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
+		direction = DMA_TO_DEVICE;
+		sg = dma_ctx->src_sg;
+	} else {
+		direction = DMA_FROM_DEVICE;
+		sg = dma_ctx->dst_sg;
+	}
+
+	num_pages = sep_crypto_lli(sep, sg, &map_array, &lli_array,
+		data_size, direction);
+
+	if (num_pages <= 0) {
+		dev_dbg(&sep->pdev->dev, "sep_crypto_lli returned error %x\n",
+			num_pages);
+		return -ENOMEM;
+	}
+
+	/* Put mapped kernel sg into kernel resource array */
+
+	/* Set output params acording to the in_out flag */
+	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
+		*lli_array_ptr = lli_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages =
+								num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array =
+								NULL;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array =
+								map_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries =
+								num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg =
+			dma_ctx->src_sg;
+	} else {
+		*lli_array_ptr = lli_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages =
+								num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array =
+								NULL;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array =
+								map_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
+					out_map_num_entries = num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg =
+			dma_ctx->dst_sg;
+	}
+
+	return 0;
+}
+
+/**
+ * sep_lock_user_pages - lock and map user pages for DMA
+ * @sep: pointer to struct sep_device
+ * @app_virt_addr: user memory data buffer
+ * @data_size: size of data buffer
+ * @lli_array_ptr: lli array
+ * @in_out_flag: input or output to device
+ *
+ * This function locks all the physical pages of the application
+ * virtual buffer and construct a basic lli  array, where each entry
+ * holds the physical page address and the size that application
+ * data holds in this physical pages
+ */
+static int sep_lock_user_pages(struct sep_device *sep,
+	u32 app_virt_addr,
+	u32 data_size,
+	struct sep_lli_entry **lli_array_ptr,
+	int in_out_flag,
+	struct sep_dma_context *dma_ctx)
+
+{
+	int error = 0;
+	u32 count;
+	int result;
+	/* The the page of the end address of the user space buffer */
+	u32 end_page;
+	/* The page of the start address of the user space buffer */
+	u32 start_page;
+	/* The range in pages */
+	u32 num_pages;
+	/* Array of pointers to page */
+	struct page **page_array;
+	/* Array of lli */
+	struct sep_lli_entry *lli_array;
+	/* Map array */
+	struct sep_dma_map *map_array;
+
+	/* Set start and end pages  and num pages */
+	end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
+	start_page = app_virt_addr >> PAGE_SHIFT;
+	num_pages = end_page - start_page + 1;
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] lock user pages app_virt_addr is %x\n",
+			current->pid, app_virt_addr);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n",
+					current->pid, data_size);
+	dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n",
+					current->pid, start_page);
+	dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n",
+					current->pid, end_page);
+	dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n",
+					current->pid, num_pages);
+
+	/* Allocate array of pages structure pointers */
+	page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
+	if (!page_array) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+	map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC);
+	if (!map_array) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] kmalloc for map_array failed\n",
+				current->pid);
+		error = -ENOMEM;
+		goto end_function_with_error1;
+	}
+
+	lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages,
+		GFP_ATOMIC);
+
+	if (!lli_array) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] kmalloc for lli_array failed\n",
+				current->pid);
+		error = -ENOMEM;
+		goto end_function_with_error2;
+	}
+
+	/* Convert the application virtual address into a set of physical */
+	down_read(&current->mm->mmap_sem);
+	result = get_user_pages(current, current->mm, app_virt_addr,
+		num_pages,
+		((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1),
+		0, page_array, NULL);
+
+	up_read(&current->mm->mmap_sem);
+
+	/* Check the number of pages locked - if not all then exit with error */
+	if (result != num_pages) {
+		dev_warn(&sep->pdev->dev,
+			"[PID%d] not all pages locked by get_user_pages, "
+			"result 0x%X, num_pages 0x%X\n",
+				current->pid, result, num_pages);
+		error = -ENOMEM;
+		goto end_function_with_error3;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] get_user_pages succeeded\n",
+					current->pid);
+
+	/*
+	 * Fill the array using page array data and
+	 * map the pages - this action will also flush the cache as needed
+	 */
+	for (count = 0; count < num_pages; count++) {
+		/* Fill the map array */
+		map_array[count].dma_addr =
+			dma_map_page(&sep->pdev->dev, page_array[count],
+			0, PAGE_SIZE, DMA_BIDIRECTIONAL);
+
+		map_array[count].size = PAGE_SIZE;
+
+		/* Fill the lli array entry */
+		lli_array[count].bus_address = (u32)map_array[count].dma_addr;
+		lli_array[count].block_size = PAGE_SIZE;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_array[%x].bus_address is %08lx, "
+			"lli_array[%x].block_size is (hex) %x\n", current->pid,
+			count, (unsigned long)lli_array[count].bus_address,
+			count, lli_array[count].block_size);
+	}
+
+	/* Check the offset for the first page */
+	lli_array[0].bus_address =
+		lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK));
+
+	/* Check that not all the data is in the first page only */
+	if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
+		lli_array[0].block_size = data_size;
+	else
+		lli_array[0].block_size =
+			PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] After check if page 0 has all data\n",
+			current->pid);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_array[0].bus_address is (hex) %08lx, "
+			"lli_array[0].block_size is (hex) %x\n",
+			current->pid,
+			(unsigned long)lli_array[0].bus_address,
+			lli_array[0].block_size);
+
+
+	/* Check the size of the last page */
+	if (num_pages > 1) {
+		lli_array[num_pages - 1].block_size =
+			(app_virt_addr + data_size) & (~PAGE_MASK);
+		if (lli_array[num_pages - 1].block_size == 0)
+			lli_array[num_pages - 1].block_size = PAGE_SIZE;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] After last page size adjustment\n",
+			current->pid);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_array[%x].bus_address is (hex) %08lx, "
+			"lli_array[%x].block_size is (hex) %x\n",
+			current->pid,
+			num_pages - 1,
+			(unsigned long)lli_array[num_pages - 1].bus_address,
+			num_pages - 1,
+			lli_array[num_pages - 1].block_size);
+	}
+
+	/* Set output params acording to the in_out flag */
+	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
+		*lli_array_ptr = lli_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages =
+								num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array =
+								page_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array =
+								map_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries =
+								num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg = NULL;
+	} else {
+		*lli_array_ptr = lli_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages =
+								num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array =
+								page_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array =
+								map_array;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
+					out_map_num_entries = num_pages;
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg = NULL;
+	}
+	goto end_function;
+
+end_function_with_error3:
+	/* Free lli array */
+	kfree(lli_array);
+
+end_function_with_error2:
+	kfree(map_array);
+
+end_function_with_error1:
+	/* Free page array */
+	kfree(page_array);
+
+end_function:
+	return error;
+}
+
+/**
+ *	sep_lli_table_secure_dma - get lli array for IMR addresses
+ *	@sep: pointer to struct sep_device
+ *	@app_virt_addr: user memory data buffer
+ *	@data_size: size of data buffer
+ *	@lli_array_ptr: lli array
+ *	@in_out_flag: not used
+ *	@dma_ctx: pointer to struct sep_dma_context
+ *
+ *	This function creates lli tables for outputting data to
+ *	IMR memory, which is memory that cannot be accessed by the
+ *	the x86 processor.
+ */
+static int sep_lli_table_secure_dma(struct sep_device *sep,
+	u32 app_virt_addr,
+	u32 data_size,
+	struct sep_lli_entry **lli_array_ptr,
+	int in_out_flag,
+	struct sep_dma_context *dma_ctx)
+
+{
+	int error = 0;
+	u32 count;
+	/* The the page of the end address of the user space buffer */
+	u32 end_page;
+	/* The page of the start address of the user space buffer */
+	u32 start_page;
+	/* The range in pages */
+	u32 num_pages;
+	/* Array of lli */
+	struct sep_lli_entry *lli_array;
+
+	/* Set start and end pages  and num pages */
+	end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
+	start_page = app_virt_addr >> PAGE_SHIFT;
+	num_pages = end_page - start_page + 1;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] lock user pages"
+		" app_virt_addr is %x\n", current->pid, app_virt_addr);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n",
+		current->pid, data_size);
+	dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n",
+		current->pid, start_page);
+	dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n",
+		current->pid, end_page);
+	dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n",
+		current->pid, num_pages);
+
+	lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages,
+		GFP_ATOMIC);
+
+	if (!lli_array) {
+		dev_warn(&sep->pdev->dev,
+			"[PID%d] kmalloc for lli_array failed\n",
+			current->pid);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Fill the lli_array
+	 */
+	start_page = start_page << PAGE_SHIFT;
+	for (count = 0; count < num_pages; count++) {
+		/* Fill the lli array entry */
+		lli_array[count].bus_address = start_page;
+		lli_array[count].block_size = PAGE_SIZE;
+
+		start_page += PAGE_SIZE;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_array[%x].bus_address is %08lx, "
+			"lli_array[%x].block_size is (hex) %x\n",
+			current->pid,
+			count, (unsigned long)lli_array[count].bus_address,
+			count, lli_array[count].block_size);
+	}
+
+	/* Check the offset for the first page */
+	lli_array[0].bus_address =
+		lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK));
+
+	/* Check that not all the data is in the first page only */
+	if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
+		lli_array[0].block_size = data_size;
+	else
+		lli_array[0].block_size =
+			PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] After check if page 0 has all data\n"
+		"lli_array[0].bus_address is (hex) %08lx, "
+		"lli_array[0].block_size is (hex) %x\n",
+		current->pid,
+		(unsigned long)lli_array[0].bus_address,
+		lli_array[0].block_size);
+
+	/* Check the size of the last page */
+	if (num_pages > 1) {
+		lli_array[num_pages - 1].block_size =
+			(app_virt_addr + data_size) & (~PAGE_MASK);
+		if (lli_array[num_pages - 1].block_size == 0)
+			lli_array[num_pages - 1].block_size = PAGE_SIZE;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] After last page size adjustment\n"
+			"lli_array[%x].bus_address is (hex) %08lx, "
+			"lli_array[%x].block_size is (hex) %x\n",
+			current->pid, num_pages - 1,
+			(unsigned long)lli_array[num_pages - 1].bus_address,
+			num_pages - 1,
+			lli_array[num_pages - 1].block_size);
+	}
+	*lli_array_ptr = lli_array;
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = num_pages;
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL;
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_num_entries = 0;
+
+	return error;
+}
+
+/**
+ * sep_calculate_lli_table_max_size - size the LLI table
+ * @sep: pointer to struct sep_device
+ * @lli_in_array_ptr
+ * @num_array_entries
+ * @last_table_flag
+ *
+ * This function calculates the size of data that can be inserted into
+ * the lli table from this array, such that either the table is full
+ * (all entries are entered), or there are no more entries in the
+ * lli array
+ */
+static u32 sep_calculate_lli_table_max_size(struct sep_device *sep,
+	struct sep_lli_entry *lli_in_array_ptr,
+	u32 num_array_entries,
+	u32 *last_table_flag)
+{
+	u32 counter;
+	/* Table data size */
+	u32 table_data_size = 0;
+	/* Data size for the next table */
+	u32 next_table_data_size;
+
+	*last_table_flag = 0;
+
+	/*
+	 * Calculate the data in the out lli table till we fill the whole
+	 * table or till the data has ended
+	 */
+	for (counter = 0;
+		(counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) &&
+			(counter < num_array_entries); counter++)
+		table_data_size += lli_in_array_ptr[counter].block_size;
+
+	/*
+	 * Check if we reached the last entry,
+	 * meaning this ia the last table to build,
+	 * and no need to check the block alignment
+	 */
+	if (counter == num_array_entries) {
+		/* Set the last table flag */
+		*last_table_flag = 1;
+		goto end_function;
+	}
+
+	/*
+	 * Calculate the data size of the next table.
+	 * Stop if no entries left or if data size is more the DMA restriction
+	 */
+	next_table_data_size = 0;
+	for (; counter < num_array_entries; counter++) {
+		next_table_data_size += lli_in_array_ptr[counter].block_size;
+		if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
+			break;
+	}
+
+	/*
+	 * Check if the next table data size is less then DMA rstriction.
+	 * if it is - recalculate the current table size, so that the next
+	 * table data size will be adaquete for DMA
+	 */
+	if (next_table_data_size &&
+		next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
+
+		table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE -
+			next_table_data_size);
+
+end_function:
+	return table_data_size;
+}
+
+/**
+ * sep_build_lli_table - build an lli array for the given table
+ * @sep: pointer to struct sep_device
+ * @lli_array_ptr: pointer to lli array
+ * @lli_table_ptr: pointer to lli table
+ * @num_processed_entries_ptr: pointer to number of entries
+ * @num_table_entries_ptr: pointer to number of tables
+ * @table_data_size: total data size
+ *
+ * Builds ant lli table from the lli_array according to
+ * the given size of data
+ */
+static void sep_build_lli_table(struct sep_device *sep,
+	struct sep_lli_entry	*lli_array_ptr,
+	struct sep_lli_entry	*lli_table_ptr,
+	u32 *num_processed_entries_ptr,
+	u32 *num_table_entries_ptr,
+	u32 table_data_size)
+{
+	/* Current table data size */
+	u32 curr_table_data_size;
+	/* Counter of lli array entry */
+	u32 array_counter;
+
+	/* Init current table data size and lli array entry counter */
+	curr_table_data_size = 0;
+	array_counter = 0;
+	*num_table_entries_ptr = 1;
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] build lli table table_data_size: (hex) %x\n",
+			current->pid, table_data_size);
+
+	/* Fill the table till table size reaches the needed amount */
+	while (curr_table_data_size < table_data_size) {
+		/* Update the number of entries in table */
+		(*num_table_entries_ptr)++;
+
+		lli_table_ptr->bus_address =
+			cpu_to_le32(lli_array_ptr[array_counter].bus_address);
+
+		lli_table_ptr->block_size =
+			cpu_to_le32(lli_array_ptr[array_counter].block_size);
+
+		curr_table_data_size += lli_array_ptr[array_counter].block_size;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_table_ptr is %p\n",
+				current->pid, lli_table_ptr);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_table_ptr->bus_address: %08lx\n",
+				current->pid,
+				(unsigned long)lli_table_ptr->bus_address);
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_table_ptr->block_size is (hex) %x\n",
+				current->pid, lli_table_ptr->block_size);
+
+		/* Check for overflow of the table data */
+		if (curr_table_data_size > table_data_size) {
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] curr_table_data_size too large\n",
+					current->pid);
+
+			/* Update the size of block in the table */
+			lli_table_ptr->block_size =
+				cpu_to_le32(lli_table_ptr->block_size) -
+				(curr_table_data_size - table_data_size);
+
+			/* Update the physical address in the lli array */
+			lli_array_ptr[array_counter].bus_address +=
+			cpu_to_le32(lli_table_ptr->block_size);
+
+			/* Update the block size left in the lli array */
+			lli_array_ptr[array_counter].block_size =
+				(curr_table_data_size - table_data_size);
+		} else
+			/* Advance to the next entry in the lli_array */
+			array_counter++;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_table_ptr->bus_address is %08lx\n",
+				current->pid,
+				(unsigned long)lli_table_ptr->bus_address);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli_table_ptr->block_size is (hex) %x\n",
+				current->pid,
+				lli_table_ptr->block_size);
+
+		/* Move to the next entry in table */
+		lli_table_ptr++;
+	}
+
+	/* Set the info entry to default */
+	lli_table_ptr->bus_address = 0xffffffff;
+	lli_table_ptr->block_size = 0;
+
+	/* Set the output parameter */
+	*num_processed_entries_ptr += array_counter;
+
+}
+
+/**
+ * sep_shared_area_virt_to_bus - map shared area to bus address
+ * @sep: pointer to struct sep_device
+ * @virt_address: virtual address to convert
+ *
+ * This functions returns the physical address inside shared area according
+ * to the virtual address. It can be either on the externa RAM device
+ * (ioremapped), or on the system RAM
+ * This implementation is for the external RAM
+ */
+static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep,
+	void *virt_address)
+{
+	dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys v %p\n",
+					current->pid, virt_address);
+	dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys p %08lx\n",
+		current->pid,
+		(unsigned long)
+		sep->shared_bus + (virt_address - sep->shared_addr));
+
+	return sep->shared_bus + (size_t)(virt_address - sep->shared_addr);
+}
+
+/**
+ * sep_shared_area_bus_to_virt - map shared area bus address to kernel
+ * @sep: pointer to struct sep_device
+ * @bus_address: bus address to convert
+ *
+ * This functions returns the virtual address inside shared area
+ * according to the physical address. It can be either on the
+ * externa RAM device (ioremapped), or on the system RAM
+ * This implementation is for the external RAM
+ */
+static void *sep_shared_area_bus_to_virt(struct sep_device *sep,
+	dma_addr_t bus_address)
+{
+	dev_dbg(&sep->pdev->dev, "[PID%d] shared bus to virt b=%lx v=%lx\n",
+		current->pid,
+		(unsigned long)bus_address, (unsigned long)(sep->shared_addr +
+			(size_t)(bus_address - sep->shared_bus)));
+
+	return sep->shared_addr	+ (size_t)(bus_address - sep->shared_bus);
+}
+
+/**
+ * sep_debug_print_lli_tables - dump LLI table
+ * @sep: pointer to struct sep_device
+ * @lli_table_ptr: pointer to sep_lli_entry
+ * @num_table_entries: number of entries
+ * @table_data_size: total data size
+ *
+ * Walk the the list of the print created tables and print all the data
+ */
+static void sep_debug_print_lli_tables(struct sep_device *sep,
+	struct sep_lli_entry *lli_table_ptr,
+	unsigned long num_table_entries,
+	unsigned long table_data_size)
+{
+#ifdef DEBUG
+	unsigned long table_count = 1;
+	unsigned long entries_count = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables start\n",
+					current->pid);
+	if (num_table_entries == 0) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] no table to print\n",
+			current->pid);
+		return;
+	}
+
+	while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) {
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] lli table %08lx, "
+			"table_data_size is (hex) %lx\n",
+				current->pid, table_count, table_data_size);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] num_table_entries is (hex) %lx\n",
+				current->pid, num_table_entries);
+
+		/* Print entries of the table (without info entry) */
+		for (entries_count = 0; entries_count < num_table_entries;
+			entries_count++, lli_table_ptr++) {
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] lli_table_ptr address is %08lx\n",
+				current->pid,
+				(unsigned long) lli_table_ptr);
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] phys address is %08lx "
+				"block size is (hex) %x\n", current->pid,
+				(unsigned long)lli_table_ptr->bus_address,
+				lli_table_ptr->block_size);
+		}
+
+		/* Point to the info entry */
+		lli_table_ptr--;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] phys lli_table_ptr->block_size "
+			"is (hex) %x\n",
+			current->pid,
+			lli_table_ptr->block_size);
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] phys lli_table_ptr->physical_address "
+			"is %08lx\n",
+			current->pid,
+			(unsigned long)lli_table_ptr->bus_address);
+
+
+		table_data_size = lli_table_ptr->block_size & 0xffffff;
+		num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] phys table_data_size is "
+			"(hex) %lx num_table_entries is"
+			" %lx bus_address is%lx\n",
+				current->pid,
+				table_data_size,
+				num_table_entries,
+				(unsigned long)lli_table_ptr->bus_address);
+
+		if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff)
+			lli_table_ptr = (struct sep_lli_entry *)
+				sep_shared_bus_to_virt(sep,
+				(unsigned long)lli_table_ptr->bus_address);
+
+		table_count++;
+	}
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables end\n",
+					current->pid);
+#endif
+}
+
+
+/**
+ * sep_prepare_empty_lli_table - create a blank LLI table
+ * @sep: pointer to struct sep_device
+ * @lli_table_addr_ptr: pointer to lli table
+ * @num_entries_ptr: pointer to number of entries
+ * @table_data_size_ptr: point to table data size
+ * @dmatables_region: Optional buffer for DMA tables
+ * @dma_ctx: DMA context
+ *
+ * This function creates empty lli tables when there is no data
+ */
+static void sep_prepare_empty_lli_table(struct sep_device *sep,
+		dma_addr_t *lli_table_addr_ptr,
+		u32 *num_entries_ptr,
+		u32 *table_data_size_ptr,
+		void **dmatables_region,
+		struct sep_dma_context *dma_ctx)
+{
+	struct sep_lli_entry *lli_table_ptr;
+
+	/* Find the area for new table */
+	lli_table_ptr =
+		(struct sep_lli_entry *)(sep->shared_addr +
+		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
+		dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
+
+	if (dmatables_region && *dmatables_region)
+		lli_table_ptr = *dmatables_region;
+
+	lli_table_ptr->bus_address = 0;
+	lli_table_ptr->block_size = 0;
+
+	lli_table_ptr++;
+	lli_table_ptr->bus_address = 0xFFFFFFFF;
+	lli_table_ptr->block_size = 0;
+
+	/* Set the output parameter value */
+	*lli_table_addr_ptr = sep->shared_bus +
+		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
+		dma_ctx->num_lli_tables_created *
+		sizeof(struct sep_lli_entry) *
+		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+	/* Set the num of entries and table data size for empty table */
+	*num_entries_ptr = 2;
+	*table_data_size_ptr = 0;
+
+	/* Update the number of created tables */
+	dma_ctx->num_lli_tables_created++;
+}
+
+/**
+ * sep_prepare_input_dma_table - prepare input DMA mappings
+ * @sep: pointer to struct sep_device
+ * @data_size:
+ * @block_size:
+ * @lli_table_ptr:
+ * @num_entries_ptr:
+ * @table_data_size_ptr:
+ * @is_kva: set for kernel data (kernel cryptio call)
+ *
+ * This function prepares only input DMA table for synhronic symmetric
+ * operations (HASH)
+ * Note that all bus addresses that are passed to the SEP
+ * are in 32 bit format; the SEP is a 32 bit device
+ */
+static int sep_prepare_input_dma_table(struct sep_device *sep,
+	unsigned long app_virt_addr,
+	u32 data_size,
+	u32 block_size,
+	dma_addr_t *lli_table_ptr,
+	u32 *num_entries_ptr,
+	u32 *table_data_size_ptr,
+	bool is_kva,
+	void **dmatables_region,
+	struct sep_dma_context *dma_ctx
+)
+{
+	int error = 0;
+	/* Pointer to the info entry of the table - the last entry */
+	struct sep_lli_entry *info_entry_ptr;
+	/* Array of pointers to page */
+	struct sep_lli_entry *lli_array_ptr;
+	/* Points to the first entry to be processed in the lli_in_array */
+	u32 current_entry = 0;
+	/* Num entries in the virtual buffer */
+	u32 sep_lli_entries = 0;
+	/* Lli table pointer */
+	struct sep_lli_entry *in_lli_table_ptr;
+	/* The total data in one table */
+	u32 table_data_size = 0;
+	/* Flag for last table */
+	u32 last_table_flag = 0;
+	/* Number of entries in lli table */
+	u32 num_entries_in_table = 0;
+	/* Next table address */
+	void *lli_table_alloc_addr = NULL;
+	void *dma_lli_table_alloc_addr = NULL;
+	void *dma_in_lli_table_ptr = NULL;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] prepare intput dma "
+				 "tbl data size: (hex) %x\n",
+					current->pid, data_size);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] block_size is (hex) %x\n",
+					current->pid, block_size);
+
+	/* Initialize the pages pointers */
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = 0;
+
+	/* Set the kernel address for first table to be allocated */
+	lli_table_alloc_addr = (void *)(sep->shared_addr +
+		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
+		dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) *
+		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
+
+	if (data_size == 0) {
+		if (dmatables_region) {
+			error = sep_allocate_dmatables_region(sep,
+						dmatables_region,
+						dma_ctx,
+						1);
+			if (error)
+				return error;
+		}
+		/* Special case  - create meptu table - 2 entries, zero data */
+		sep_prepare_empty_lli_table(sep, lli_table_ptr,
+				num_entries_ptr, table_data_size_ptr,
+				dmatables_region, dma_ctx);
+		goto update_dcb_counter;
+	}
+
+	/* Check if the pages are in Kernel Virtual Address layout */
+	if (is_kva == true)
+		error = sep_lock_kernel_pages(sep, app_virt_addr,
+			data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG,
+			dma_ctx);
+	else
+		/*
+		 * Lock the pages of the user buffer
+		 * and translate them to pages
+		 */
+		error = sep_lock_user_pages(sep, app_virt_addr,
+			data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG,
+			dma_ctx);
+
+	if (error)
+		goto end_function;
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] output sep_in_num_pages is (hex) %x\n",
+		current->pid,
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages);
+
+	current_entry = 0;
+	info_entry_ptr = NULL;
+
+	sep_lli_entries =
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages;
+
+	dma_lli_table_alloc_addr = lli_table_alloc_addr;
+	if (dmatables_region) {
+		error = sep_allocate_dmatables_region(sep,
+					dmatables_region,
+					dma_ctx,
+					sep_lli_entries);
+		if (error)
+			return error;
+		lli_table_alloc_addr = *dmatables_region;
+	}
+
+	/* Loop till all the entries in in array are processed */
+	while (current_entry < sep_lli_entries) {
+
+		/* Set the new input and output tables */
+		in_lli_table_ptr =
+			(struct sep_lli_entry *)lli_table_alloc_addr;
+		dma_in_lli_table_ptr =
+			(struct sep_lli_entry *)dma_lli_table_alloc_addr;
+
+		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+		dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+		if (dma_lli_table_alloc_addr >
+			((void *)sep->shared_addr +
+			SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
+			SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {
+
+			error = -ENOMEM;
+			goto end_function_error;
+
+		}
+
+		/* Update the number of created tables */
+		dma_ctx->num_lli_tables_created++;
+
+		/* Calculate the maximum size of data for input table */
+		table_data_size = sep_calculate_lli_table_max_size(sep,
+			&lli_array_ptr[current_entry],
+			(sep_lli_entries - current_entry),
+			&last_table_flag);
+
+		/*
+		 * If this is not the last table -
+		 * then allign it to the block size
+		 */
+		if (!last_table_flag)
+			table_data_size =
+				(table_data_size / block_size) * block_size;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] output table_data_size is (hex) %x\n",
+				current->pid,
+				table_data_size);
+
+		/* Construct input lli table */
+		sep_build_lli_table(sep, &lli_array_ptr[current_entry],
+			in_lli_table_ptr,
+			&current_entry, &num_entries_in_table, table_data_size);
+
+		if (info_entry_ptr == NULL) {
+
+			/* Set the output parameters to physical addresses */
+			*lli_table_ptr = sep_shared_area_virt_to_bus(sep,
+				dma_in_lli_table_ptr);
+			*num_entries_ptr = num_entries_in_table;
+			*table_data_size_ptr = table_data_size;
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] output lli_table_in_ptr is %08lx\n",
+				current->pid,
+				(unsigned long)*lli_table_ptr);
+
+		} else {
+			/* Update the info entry of the previous in table */
+			info_entry_ptr->bus_address =
+				sep_shared_area_virt_to_bus(sep,
+							dma_in_lli_table_ptr);
+			info_entry_ptr->block_size =
+				((num_entries_in_table) << 24) |
+				(table_data_size);
+		}
+		/* Save the pointer to the info entry of the current tables */
+		info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
+	}
+	/* Print input tables */
+	if (!dmatables_region) {
+		sep_debug_print_lli_tables(sep, (struct sep_lli_entry *)
+			sep_shared_area_bus_to_virt(sep, *lli_table_ptr),
+			*num_entries_ptr, *table_data_size_ptr);
+	}
+
+	/* The array of the pages */
+	kfree(lli_array_ptr);
+
+update_dcb_counter:
+	/* Update DCB counter */
+	dma_ctx->nr_dcb_creat++;
+	goto end_function;
+
+end_function_error:
+	/* Free all the allocated resources */
+	kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array);
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL;
+	kfree(lli_array_ptr);
+	kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array);
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
+
+end_function:
+	return error;
+
+}
+
+/**
+ * sep_construct_dma_tables_from_lli - prepare AES/DES mappings
+ * @sep: pointer to struct sep_device
+ * @lli_in_array:
+ * @sep_in_lli_entries:
+ * @lli_out_array:
+ * @sep_out_lli_entries
+ * @block_size
+ * @lli_table_in_ptr
+ * @lli_table_out_ptr
+ * @in_num_entries_ptr
+ * @out_num_entries_ptr
+ * @table_data_size_ptr
+ *
+ * This function creates the input and output DMA tables for
+ * symmetric operations (AES/DES) according to the block
+ * size from LLI arays
+ * Note that all bus addresses that are passed to the SEP
+ * are in 32 bit format; the SEP is a 32 bit device
+ */
+static int sep_construct_dma_tables_from_lli(
+	struct sep_device *sep,
+	struct sep_lli_entry *lli_in_array,
+	u32	sep_in_lli_entries,
+	struct sep_lli_entry *lli_out_array,
+	u32	sep_out_lli_entries,
+	u32	block_size,
+	dma_addr_t *lli_table_in_ptr,
+	dma_addr_t *lli_table_out_ptr,
+	u32	*in_num_entries_ptr,
+	u32	*out_num_entries_ptr,
+	u32	*table_data_size_ptr,
+	void	**dmatables_region,
+	struct sep_dma_context *dma_ctx)
+{
+	/* Points to the area where next lli table can be allocated */
+	void *lli_table_alloc_addr = NULL;
+	/*
+	 * Points to the area in shared region where next lli table
+	 * can be allocated
+	 */
+	void *dma_lli_table_alloc_addr = NULL;
+	/* Input lli table in dmatables_region or shared region */
+	struct sep_lli_entry *in_lli_table_ptr = NULL;
+	/* Input lli table location in the shared region */
+	struct sep_lli_entry *dma_in_lli_table_ptr = NULL;
+	/* Output lli table in dmatables_region or shared region */
+	struct sep_lli_entry *out_lli_table_ptr = NULL;
+	/* Output lli table location in the shared region */
+	struct sep_lli_entry *dma_out_lli_table_ptr = NULL;
+	/* Pointer to the info entry of the table - the last entry */
+	struct sep_lli_entry *info_in_entry_ptr = NULL;
+	/* Pointer to the info entry of the table - the last entry */
+	struct sep_lli_entry *info_out_entry_ptr = NULL;
+	/* Points to the first entry to be processed in the lli_in_array */
+	u32 current_in_entry = 0;
+	/* Points to the first entry to be processed in the lli_out_array */
+	u32 current_out_entry = 0;
+	/* Max size of the input table */
+	u32 in_table_data_size = 0;
+	/* Max size of the output table */
+	u32 out_table_data_size = 0;
+	/* Flag te signifies if this is the last tables build */
+	u32 last_table_flag = 0;
+	/* The data size that should be in table */
+	u32 table_data_size = 0;
+	/* Number of etnries in the input table */
+	u32 num_entries_in_table = 0;
+	/* Number of etnries in the output table */
+	u32 num_entries_out_table = 0;
+
+	if (!dma_ctx) {
+		dev_warn(&sep->pdev->dev, "DMA context uninitialized\n");
+		return -EINVAL;
+	}
+
+	/* Initiate to point after the message area */
+	lli_table_alloc_addr = (void *)(sep->shared_addr +
+		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
+		(dma_ctx->num_lli_tables_created *
+		(sizeof(struct sep_lli_entry) *
+		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP)));
+	dma_lli_table_alloc_addr = lli_table_alloc_addr;
+
+	if (dmatables_region) {
+		/* 2 for both in+out table */
+		if (sep_allocate_dmatables_region(sep,
+					dmatables_region,
+					dma_ctx,
+					2*sep_in_lli_entries))
+			return -ENOMEM;
+		lli_table_alloc_addr = *dmatables_region;
+	}
+
+	/* Loop till all the entries in in array are not processed */
+	while (current_in_entry < sep_in_lli_entries) {
+		/* Set the new input and output tables */
+		in_lli_table_ptr =
+			(struct sep_lli_entry *)lli_table_alloc_addr;
+		dma_in_lli_table_ptr =
+			(struct sep_lli_entry *)dma_lli_table_alloc_addr;
+
+		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+		dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+		/* Set the first output tables */
+		out_lli_table_ptr =
+			(struct sep_lli_entry *)lli_table_alloc_addr;
+		dma_out_lli_table_ptr =
+			(struct sep_lli_entry *)dma_lli_table_alloc_addr;
+
+		/* Check if the DMA table area limit was overrun */
+		if ((dma_lli_table_alloc_addr + sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) >
+			((void *)sep->shared_addr +
+			SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
+			SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {
+
+			dev_warn(&sep->pdev->dev, "dma table limit overrun\n");
+			return -ENOMEM;
+		}
+
+		/* Update the number of the lli tables created */
+		dma_ctx->num_lli_tables_created += 2;
+
+		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+		dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
+			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+		/* Calculate the maximum size of data for input table */
+		in_table_data_size =
+			sep_calculate_lli_table_max_size(sep,
+			&lli_in_array[current_in_entry],
+			(sep_in_lli_entries - current_in_entry),
+			&last_table_flag);
+
+		/* Calculate the maximum size of data for output table */
+		out_table_data_size =
+			sep_calculate_lli_table_max_size(sep,
+			&lli_out_array[current_out_entry],
+			(sep_out_lli_entries - current_out_entry),
+			&last_table_flag);
+
+		if (!last_table_flag) {
+			in_table_data_size = (in_table_data_size /
+				block_size) * block_size;
+			out_table_data_size = (out_table_data_size /
+				block_size) * block_size;
+		}
+
+		table_data_size = in_table_data_size;
+		if (table_data_size > out_table_data_size)
+			table_data_size = out_table_data_size;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] construct tables from lli"
+			" in_table_data_size is (hex) %x\n", current->pid,
+			in_table_data_size);
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] construct tables from lli"
+			"out_table_data_size is (hex) %x\n", current->pid,
+			out_table_data_size);
+
+		/* Construct input lli table */
+		sep_build_lli_table(sep, &lli_in_array[current_in_entry],
+			in_lli_table_ptr,
+			&current_in_entry,
+			&num_entries_in_table,
+			table_data_size);
+
+		/* Construct output lli table */
+		sep_build_lli_table(sep, &lli_out_array[current_out_entry],
+			out_lli_table_ptr,
+			&current_out_entry,
+			&num_entries_out_table,
+			table_data_size);
+
+		/* If info entry is null - this is the first table built */
+		if (info_in_entry_ptr == NULL) {
+			/* Set the output parameters to physical addresses */
+			*lli_table_in_ptr =
+			sep_shared_area_virt_to_bus(sep, dma_in_lli_table_ptr);
+
+			*in_num_entries_ptr = num_entries_in_table;
+
+			*lli_table_out_ptr =
+				sep_shared_area_virt_to_bus(sep,
+				dma_out_lli_table_ptr);
+
+			*out_num_entries_ptr = num_entries_out_table;
+			*table_data_size_ptr = table_data_size;
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] output lli_table_in_ptr is %08lx\n",
+				current->pid,
+				(unsigned long)*lli_table_in_ptr);
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] output lli_table_out_ptr is %08lx\n",
+				current->pid,
+				(unsigned long)*lli_table_out_ptr);
+		} else {
+			/* Update the info entry of the previous in table */
+			info_in_entry_ptr->bus_address =
+				sep_shared_area_virt_to_bus(sep,
+				dma_in_lli_table_ptr);
+
+			info_in_entry_ptr->block_size =
+				((num_entries_in_table) << 24) |
+				(table_data_size);
+
+			/* Update the info entry of the previous in table */
+			info_out_entry_ptr->bus_address =
+				sep_shared_area_virt_to_bus(sep,
+				dma_out_lli_table_ptr);
+
+			info_out_entry_ptr->block_size =
+				((num_entries_out_table) << 24) |
+				(table_data_size);
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] output lli_table_in_ptr:%08lx %08x\n",
+				current->pid,
+				(unsigned long)info_in_entry_ptr->bus_address,
+				info_in_entry_ptr->block_size);
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] output lli_table_out_ptr:"
+				"%08lx  %08x\n",
+				current->pid,
+				(unsigned long)info_out_entry_ptr->bus_address,
+				info_out_entry_ptr->block_size);
+		}
+
+		/* Save the pointer to the info entry of the current tables */
+		info_in_entry_ptr = in_lli_table_ptr +
+			num_entries_in_table - 1;
+		info_out_entry_ptr = out_lli_table_ptr +
+			num_entries_out_table - 1;
+
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] output num_entries_out_table is %x\n",
+			current->pid,
+			(u32)num_entries_out_table);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] output info_in_entry_ptr is %lx\n",
+			current->pid,
+			(unsigned long)info_in_entry_ptr);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] output info_out_entry_ptr is %lx\n",
+			current->pid,
+			(unsigned long)info_out_entry_ptr);
+	}
+
+	/* Print input tables */
+	if (!dmatables_region) {
+		sep_debug_print_lli_tables(
+			sep,
+			(struct sep_lli_entry *)
+			sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr),
+			*in_num_entries_ptr,
+			*table_data_size_ptr);
+	}
+
+	/* Print output tables */
+	if (!dmatables_region) {
+		sep_debug_print_lli_tables(
+			sep,
+			(struct sep_lli_entry *)
+			sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr),
+			*out_num_entries_ptr,
+			*table_data_size_ptr);
+	}
+
+	return 0;
+}
+
+/**
+ * sep_prepare_input_output_dma_table - prepare DMA I/O table
+ * @app_virt_in_addr:
+ * @app_virt_out_addr:
+ * @data_size:
+ * @block_size:
+ * @lli_table_in_ptr:
+ * @lli_table_out_ptr:
+ * @in_num_entries_ptr:
+ * @out_num_entries_ptr:
+ * @table_data_size_ptr:
+ * @is_kva: set for kernel data; used only for kernel crypto module
+ *
+ * This function builds input and output DMA tables for synhronic
+ * symmetric operations (AES, DES, HASH). It also checks that each table
+ * is of the modular block size
+ * Note that all bus addresses that are passed to the SEP
+ * are in 32 bit format; the SEP is a 32 bit device
+ */
+static int sep_prepare_input_output_dma_table(struct sep_device *sep,
+	unsigned long app_virt_in_addr,
+	unsigned long app_virt_out_addr,
+	u32 data_size,
+	u32 block_size,
+	dma_addr_t *lli_table_in_ptr,
+	dma_addr_t *lli_table_out_ptr,
+	u32 *in_num_entries_ptr,
+	u32 *out_num_entries_ptr,
+	u32 *table_data_size_ptr,
+	bool is_kva,
+	void **dmatables_region,
+	struct sep_dma_context *dma_ctx)
+
+{
+	int error = 0;
+	/* Array of pointers of page */
+	struct sep_lli_entry *lli_in_array;
+	/* Array of pointers of page */
+	struct sep_lli_entry *lli_out_array;
+
+	if (!dma_ctx) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	if (data_size == 0) {
+		/* Prepare empty table for input and output */
+		if (dmatables_region) {
+			error = sep_allocate_dmatables_region(
+					sep,
+					dmatables_region,
+					dma_ctx,
+					2);
+		  if (error)
+			goto end_function;
+		}
+		sep_prepare_empty_lli_table(sep, lli_table_in_ptr,
+			in_num_entries_ptr, table_data_size_ptr,
+			dmatables_region, dma_ctx);
+
+		sep_prepare_empty_lli_table(sep, lli_table_out_ptr,
+			out_num_entries_ptr, table_data_size_ptr,
+			dmatables_region, dma_ctx);
+
+		goto update_dcb_counter;
+	}
+
+	/* Initialize the pages pointers */
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
+
+	/* Lock the pages of the buffer and translate them to pages */
+	if (is_kva == true) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel input pages\n",
+						current->pid);
+		error = sep_lock_kernel_pages(sep, app_virt_in_addr,
+				data_size, &lli_in_array, SEP_DRIVER_IN_FLAG,
+				dma_ctx);
+		if (error) {
+			dev_warn(&sep->pdev->dev,
+				"[PID%d] sep_lock_kernel_pages for input "
+				"virtual buffer failed\n", current->pid);
+
+			goto end_function;
+		}
+
+		dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel output pages\n",
+						current->pid);
+		error = sep_lock_kernel_pages(sep, app_virt_out_addr,
+				data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG,
+				dma_ctx);
+
+		if (error) {
+			dev_warn(&sep->pdev->dev,
+				"[PID%d] sep_lock_kernel_pages for output "
+				"virtual buffer failed\n", current->pid);
+
+			goto end_function_free_lli_in;
+		}
+
+	}
+
+	else {
+		dev_dbg(&sep->pdev->dev, "[PID%d] Locking user input pages\n",
+						current->pid);
+		error = sep_lock_user_pages(sep, app_virt_in_addr,
+				data_size, &lli_in_array, SEP_DRIVER_IN_FLAG,
+				dma_ctx);
+		if (error) {
+			dev_warn(&sep->pdev->dev,
+				"[PID%d] sep_lock_user_pages for input "
+				"virtual buffer failed\n", current->pid);
+
+			goto end_function;
+		}
+
+		if (dma_ctx->secure_dma == true) {
+			/* secure_dma requires use of non accessible memory */
+			dev_dbg(&sep->pdev->dev, "[PID%d] in secure_dma\n",
+				current->pid);
+			error = sep_lli_table_secure_dma(sep,
+				app_virt_out_addr, data_size, &lli_out_array,
+				SEP_DRIVER_OUT_FLAG, dma_ctx);
+			if (error) {
+				dev_warn(&sep->pdev->dev,
+					"[PID%d] secure dma table setup "
+					" for output virtual buffer failed\n",
+					current->pid);
+
+				goto end_function_free_lli_in;
+			}
+		} else {
+			/* For normal, non-secure dma */
+			dev_dbg(&sep->pdev->dev, "[PID%d] not in secure_dma\n",
+				current->pid);
+
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] Locking user output pages\n",
+				current->pid);
+
+			error = sep_lock_user_pages(sep, app_virt_out_addr,
+				data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG,
+				dma_ctx);
+
+			if (error) {
+				dev_warn(&sep->pdev->dev,
+					"[PID%d] sep_lock_user_pages"
+					" for output virtual buffer failed\n",
+					current->pid);
+
+				goto end_function_free_lli_in;
+			}
+		}
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] After lock; prep input output dma "
+		"table sep_in_num_pages is (hex) %x\n", current->pid,
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_out_num_pages is (hex) %x\n",
+		current->pid,
+		dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP"
+		" is (hex) %x\n", current->pid,
+		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
+
+	/* Call the fucntion that creates table from the lli arrays */
+	dev_dbg(&sep->pdev->dev, "[PID%d] calling create table from lli\n",
+					current->pid);
+	error = sep_construct_dma_tables_from_lli(
+			sep, lli_in_array,
+			dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
+								in_num_pages,
+			lli_out_array,
+			dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].
+								out_num_pages,
+			block_size, lli_table_in_ptr, lli_table_out_ptr,
+			in_num_entries_ptr, out_num_entries_ptr,
+			table_data_size_ptr, dmatables_region, dma_ctx);
+
+	if (error) {
+		dev_warn(&sep->pdev->dev,
+			"[PID%d] sep_construct_dma_tables_from_lli failed\n",
+			current->pid);
+		goto end_function_with_error;
+	}
+
+	kfree(lli_out_array);
+	kfree(lli_in_array);
+
+update_dcb_counter:
+	/* Update DCB counter */
+	dma_ctx->nr_dcb_creat++;
+
+	goto end_function;
+
+end_function_with_error:
+	kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array);
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = NULL;
+	kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array);
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL;
+	kfree(lli_out_array);
+
+
+end_function_free_lli_in:
+	kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array);
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = NULL;
+	kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array);
+	dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL;
+	kfree(lli_in_array);
+
+end_function:
+
+	return error;
+
+}
+
+/**
+ * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks
+ * @app_in_address: unsigned long; for data buffer in (user space)
+ * @app_out_address: unsigned long; for data buffer out (user space)
+ * @data_in_size: u32; for size of data
+ * @block_size: u32; for block size
+ * @tail_block_size: u32; for size of tail block
+ * @isapplet: bool; to indicate external app
+ * @is_kva: bool; kernel buffer; only used for kernel crypto module
+ * @secure_dma; indicates whether this is secure_dma using IMR
+ *
+ * This function prepares the linked DMA tables and puts the
+ * address for the linked list of tables inta a DCB (data control
+ * block) the address of which is known by the SEP hardware
+ * Note that all bus addresses that are passed to the SEP
+ * are in 32 bit format; the SEP is a 32 bit device
+ */
+int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
+	unsigned long  app_in_address,
+	unsigned long  app_out_address,
+	u32  data_in_size,
+	u32  block_size,
+	u32  tail_block_size,
+	bool isapplet,
+	bool	is_kva,
+	bool	secure_dma,
+	struct sep_dcblock *dcb_region,
+	void **dmatables_region,
+	struct sep_dma_context **dma_ctx,
+	struct scatterlist *src_sg,
+	struct scatterlist *dst_sg)
+{
+	int error = 0;
+	/* Size of tail */
+	u32 tail_size = 0;
+	/* Address of the created DCB table */
+	struct sep_dcblock *dcb_table_ptr = NULL;
+	/* The physical address of the first input DMA table */
+	dma_addr_t in_first_mlli_address = 0;
+	/* Number of entries in the first input DMA table */
+	u32  in_first_num_entries = 0;
+	/* The physical address of the first output DMA table */
+	dma_addr_t  out_first_mlli_address = 0;
+	/* Number of entries in the first output DMA table */
+	u32  out_first_num_entries = 0;
+	/* Data in the first input/output table */
+	u32  first_data_size = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] app_in_address %lx\n",
+		current->pid, app_in_address);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] app_out_address %lx\n",
+		current->pid, app_out_address);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] data_in_size %x\n",
+		current->pid, data_in_size);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] block_size %x\n",
+		current->pid, block_size);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] tail_block_size %x\n",
+		current->pid, tail_block_size);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] isapplet %x\n",
+		current->pid, isapplet);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] is_kva %x\n",
+		current->pid, is_kva);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] src_sg %p\n",
+		current->pid, src_sg);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] dst_sg %p\n",
+		current->pid, dst_sg);
+
+	if (!dma_ctx) {
+		dev_warn(&sep->pdev->dev, "[PID%d] no DMA context pointer\n",
+						current->pid);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	if (*dma_ctx) {
+		/* In case there are multiple DCBs for this transaction */
+		dev_dbg(&sep->pdev->dev, "[PID%d] DMA context already set\n",
+						current->pid);
+	} else {
+		*dma_ctx = kzalloc(sizeof(**dma_ctx), GFP_KERNEL);
+		if (!(*dma_ctx)) {
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] Not enough memory for DMA context\n",
+				current->pid);
+		  error = -ENOMEM;
+		  goto end_function;
+		}
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] Created DMA context addr at 0x%p\n",
+			current->pid, *dma_ctx);
+	}
+
+	(*dma_ctx)->secure_dma = secure_dma;
+
+	/* these are for kernel crypto only */
+	(*dma_ctx)->src_sg = src_sg;
+	(*dma_ctx)->dst_sg = dst_sg;
+
+	if ((*dma_ctx)->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) {
+		/* No more DCBs to allocate */
+		dev_dbg(&sep->pdev->dev, "[PID%d] no more DCBs available\n",
+						current->pid);
+		error = -ENOSPC;
+		goto end_function_error;
+	}
+
+	/* Allocate new DCB */
+	if (dcb_region) {
+		dcb_table_ptr = dcb_region;
+	} else {
+		dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr +
+			SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES +
+			((*dma_ctx)->nr_dcb_creat *
+						sizeof(struct sep_dcblock)));
+	}
+
+	/* Set the default values in the DCB */
+	dcb_table_ptr->input_mlli_address = 0;
+	dcb_table_ptr->input_mlli_num_entries = 0;
+	dcb_table_ptr->input_mlli_data_size = 0;
+	dcb_table_ptr->output_mlli_address = 0;
+	dcb_table_ptr->output_mlli_num_entries = 0;
+	dcb_table_ptr->output_mlli_data_size = 0;
+	dcb_table_ptr->tail_data_size = 0;
+	dcb_table_ptr->out_vr_tail_pt = 0;
+
+	if (isapplet == true) {
+
+		/* Check if there is enough data for DMA operation */
+		if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) {
+			if (is_kva == true) {
+				error = -ENODEV;
+				goto end_function_error;
+			} else {
+				if (copy_from_user(dcb_table_ptr->tail_data,
+					(void __user *)app_in_address,
+					data_in_size)) {
+					error = -EFAULT;
+					goto end_function_error;
+				}
+			}
+
+			dcb_table_ptr->tail_data_size = data_in_size;
+
+			/* Set the output user-space address for mem2mem op */
+			if (app_out_address)
+				dcb_table_ptr->out_vr_tail_pt =
+				(aligned_u64)app_out_address;
+
+			/*
+			 * Update both data length parameters in order to avoid
+			 * second data copy and allow building of empty mlli
+			 * tables
+			 */
+			tail_size = 0x0;
+			data_in_size = 0x0;
+
+		} else {
+			if (!app_out_address) {
+				tail_size = data_in_size % block_size;
+				if (!tail_size) {
+					if (tail_block_size == block_size)
+						tail_size = block_size;
+				}
+			} else {
+				tail_size = 0;
+			}
+		}
+		if (tail_size) {
+			if (tail_size > sizeof(dcb_table_ptr->tail_data))
+				return -EINVAL;
+			if (is_kva == true) {
+				error = -ENODEV;
+				goto end_function_error;
+			} else {
+				/* We have tail data - copy it to DCB */
+				if (copy_from_user(dcb_table_ptr->tail_data,
+					(void __user *)(app_in_address +
+					data_in_size - tail_size), tail_size)) {
+					error = -EFAULT;
+					goto end_function_error;
+				}
+			}
+			if (app_out_address)
+				/*
+				 * Calculate the output address
+				 * according to tail data size
+				 */
+				dcb_table_ptr->out_vr_tail_pt =
+					(aligned_u64)app_out_address +
+					data_in_size - tail_size;
+
+			/* Save the real tail data size */
+			dcb_table_ptr->tail_data_size = tail_size;
+			/*
+			 * Update the data size without the tail
+			 * data size AKA data for the dma
+			 */
+			data_in_size = (data_in_size - tail_size);
+		}
+	}
+	/* Check if we need to build only input table or input/output */
+	if (app_out_address) {
+		/* Prepare input/output tables */
+		error = sep_prepare_input_output_dma_table(sep,
+				app_in_address,
+				app_out_address,
+				data_in_size,
+				block_size,
+				&in_first_mlli_address,
+				&out_first_mlli_address,
+				&in_first_num_entries,
+				&out_first_num_entries,
+				&first_data_size,
+				is_kva,
+				dmatables_region,
+				*dma_ctx);
+	} else {
+		/* Prepare input tables */
+		error = sep_prepare_input_dma_table(sep,
+				app_in_address,
+				data_in_size,
+				block_size,
+				&in_first_mlli_address,
+				&in_first_num_entries,
+				&first_data_size,
+				is_kva,
+				dmatables_region,
+				*dma_ctx);
+	}
+
+	if (error) {
+		dev_warn(&sep->pdev->dev,
+			"prepare DMA table call failed "
+			"from prepare DCB call\n");
+		goto end_function_error;
+	}
+
+	/* Set the DCB values */
+	dcb_table_ptr->input_mlli_address = in_first_mlli_address;
+	dcb_table_ptr->input_mlli_num_entries = in_first_num_entries;
+	dcb_table_ptr->input_mlli_data_size = first_data_size;
+	dcb_table_ptr->output_mlli_address = out_first_mlli_address;
+	dcb_table_ptr->output_mlli_num_entries = out_first_num_entries;
+	dcb_table_ptr->output_mlli_data_size = first_data_size;
+
+	goto end_function;
+
+end_function_error:
+	kfree(*dma_ctx);
+	*dma_ctx = NULL;
+
+end_function:
+	return error;
+
+}
+
+
+/**
+ * sep_free_dma_tables_and_dcb - free DMA tables and DCBs
+ * @sep: pointer to struct sep_device
+ * @isapplet: indicates external application (used for kernel access)
+ * @is_kva: indicates kernel addresses (only used for kernel crypto)
+ *
+ * This function frees the DMA tables and DCB
+ */
+static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet,
+	bool is_kva, struct sep_dma_context **dma_ctx)
+{
+	struct sep_dcblock *dcb_table_ptr;
+	unsigned long pt_hold;
+	void *tail_pt;
+
+	int i = 0;
+	int error = 0;
+	int error_temp = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb\n",
+					current->pid);
+
+	if (((*dma_ctx)->secure_dma == false) && (isapplet == true)) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] handling applet\n",
+			current->pid);
+
+		/* Tail stuff is only for non secure_dma */
+		/* Set pointer to first DCB table */
+		dcb_table_ptr = (struct sep_dcblock *)
+			(sep->shared_addr +
+			SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES);
+
+		/**
+		 * Go over each DCB and see if
+		 * tail pointer must be updated
+		 */
+		for (i = 0; dma_ctx && *dma_ctx &&
+			i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) {
+			if (dcb_table_ptr->out_vr_tail_pt) {
+				pt_hold = (unsigned long)dcb_table_ptr->
+					out_vr_tail_pt;
+				tail_pt = (void *)pt_hold;
+				if (is_kva == true) {
+					error = -ENODEV;
+					break;
+				} else {
+					error_temp = copy_to_user(
+						(void __user *)tail_pt,
+						dcb_table_ptr->tail_data,
+						dcb_table_ptr->tail_data_size);
+				}
+				if (error_temp) {
+					/* Release the DMA resource */
+					error = -EFAULT;
+					break;
+				}
+			}
+		}
+	}
+
+	/* Free the output pages, if any */
+	sep_free_dma_table_data_handler(sep, dma_ctx);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb end\n",
+					current->pid);
+
+	return error;
+}
+
+/**
+ * sep_prepare_dcb_handler - prepare a control block
+ * @sep: pointer to struct sep_device
+ * @arg: pointer to user parameters
+ * @secure_dma: indicate whether we are using secure_dma on IMR
+ *
+ * This function will retrieve the RAR buffer physical addresses, type
+ * & size corresponding to the RAR handles provided in the buffers vector.
+ */
+static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg,
+				   bool secure_dma,
+				   struct sep_dma_context **dma_ctx)
+{
+	int error;
+	/* Command arguments */
+	static struct build_dcb_struct command_args;
+
+	/* Get the command arguments */
+	if (copy_from_user(&command_args, (void __user *)arg,
+					sizeof(struct build_dcb_struct))) {
+		error = -EFAULT;
+		goto end_function;
+	}
+
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] prep dcb handler app_in_address is %08llx\n",
+			current->pid, command_args.app_in_address);
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] app_out_address is %08llx\n",
+			current->pid, command_args.app_out_address);
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] data_size is %x\n",
+			current->pid, command_args.data_in_size);
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] block_size is %x\n",
+			current->pid, command_args.block_size);
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] tail block_size is %x\n",
+			current->pid, command_args.tail_block_size);
+	dev_dbg(&sep->pdev->dev,
+		"[PID%d] is_applet is %x\n",
+			current->pid, command_args.is_applet);
+
+	if (!command_args.app_in_address) {
+		dev_warn(&sep->pdev->dev,
+			"[PID%d] null app_in_address\n", current->pid);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	error = sep_prepare_input_output_dma_table_in_dcb(sep,
+			(unsigned long)command_args.app_in_address,
+			(unsigned long)command_args.app_out_address,
+			command_args.data_in_size, command_args.block_size,
+			command_args.tail_block_size,
+			command_args.is_applet, false,
+			secure_dma, NULL, NULL, dma_ctx, NULL, NULL);
+
+end_function:
+	return error;
+
+}
+
+/**
+ * sep_free_dcb_handler - free control block resources
+ * @sep: pointer to struct sep_device
+ *
+ * This function frees the DCB resources and updates the needed
+ * user-space buffers.
+ */
+static int sep_free_dcb_handler(struct sep_device *sep,
+				struct sep_dma_context **dma_ctx)
+{
+	if (!dma_ctx || !(*dma_ctx)) {
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] no dma context defined, nothing to free\n",
+			current->pid);
+		return -EINVAL;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] free dcbs num of DCBs %x\n",
+		current->pid,
+		(*dma_ctx)->nr_dcb_creat);
+
+	return sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx);
+}
+
+/**
+ * sep_ioctl - ioctl handler for sep device
+ * @filp: pointer to struct file
+ * @cmd: command
+ * @arg: pointer to argument structure
+ *
+ * Implement the ioctl methods availble on the SEP device.
+ */
+static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct sep_private_data * const private_data = filp->private_data;
+	struct sep_call_status *call_status = &private_data->call_status;
+	struct sep_device *sep = private_data->device;
+	struct sep_dma_context **dma_ctx = &private_data->dma_ctx;
+	struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
+	int error = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] ioctl cmd 0x%x\n",
+		current->pid, cmd);
+	dev_dbg(&sep->pdev->dev, "[PID%d] dma context addr 0x%p\n",
+		current->pid, *dma_ctx);
+
+	/* Make sure we own this device */
+	error = sep_check_transaction_owner(sep);
+	if (error) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] ioctl pid is not owner\n",
+			current->pid);
+		goto end_function;
+	}
+
+	/* Check that sep_mmap has been called before */
+	if (0 == test_bit(SEP_LEGACY_MMAP_DONE_OFFSET,
+				&call_status->status)) {
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] mmap not called\n", current->pid);
+		error = -EPROTO;
+		goto end_function;
+	}
+
+	/* Check that the command is for SEP device */
+	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) {
+		error = -ENOTTY;
+		goto end_function;
+	}
+
+	switch (cmd) {
+	case SEP_IOCSENDSEPCOMMAND:
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCSENDSEPCOMMAND start\n",
+			current->pid);
+		if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
+				  &call_status->status)) {
+			dev_warn(&sep->pdev->dev,
+				"[PID%d] send msg already done\n",
+				current->pid);
+			error = -EPROTO;
+			goto end_function;
+		}
+		/* Send command to SEP */
+		error = sep_send_command_handler(sep);
+		if (!error)
+			set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
+				&call_status->status);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCSENDSEPCOMMAND end\n",
+			current->pid);
+		break;
+	case SEP_IOCENDTRANSACTION:
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCENDTRANSACTION start\n",
+			current->pid);
+		error = sep_end_transaction_handler(sep, dma_ctx, call_status,
+						    my_queue_elem);
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCENDTRANSACTION end\n",
+			current->pid);
+		break;
+	case SEP_IOCPREPAREDCB:
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCPREPAREDCB start\n",
+			current->pid);
+	case SEP_IOCPREPAREDCB_SECURE_DMA:
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCPREPAREDCB_SECURE_DMA start\n",
+			current->pid);
+		if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET,
+				  &call_status->status)) {
+			dev_warn(&sep->pdev->dev,
+				"[PID%d] dcb prep needed before send msg\n",
+				current->pid);
+			error = -EPROTO;
+			goto end_function;
+		}
+
+		if (!arg) {
+			dev_warn(&sep->pdev->dev,
+				"[PID%d] dcb null arg\n", current->pid);
+			error = EINVAL;
+			goto end_function;
+		}
+
+		if (cmd == SEP_IOCPREPAREDCB) {
+			/* No secure dma */
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] SEP_IOCPREPAREDCB (no secure_dma)\n",
+				current->pid);
+
+			error = sep_prepare_dcb_handler(sep, arg, false,
+				dma_ctx);
+		} else {
+			/* Secure dma */
+			dev_dbg(&sep->pdev->dev,
+				"[PID%d] SEP_IOC_POC (with secure_dma)\n",
+				current->pid);
+
+			error = sep_prepare_dcb_handler(sep, arg, true,
+				dma_ctx);
+		}
+		dev_dbg(&sep->pdev->dev, "[PID%d] dcb's end\n",
+			current->pid);
+		break;
+	case SEP_IOCFREEDCB:
+		dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB start\n",
+			current->pid);
+	case SEP_IOCFREEDCB_SECURE_DMA:
+		dev_dbg(&sep->pdev->dev,
+			"[PID%d] SEP_IOCFREEDCB_SECURE_DMA start\n",
+			current->pid);
+		error = sep_free_dcb_handler(sep, dma_ctx);
+		dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB end\n",
+			current->pid);
+		break;
+	default:
+		error = -ENOTTY;
+		dev_dbg(&sep->pdev->dev, "[PID%d] default end\n",
+			current->pid);
+		break;
+	}
+
+end_function:
+	dev_dbg(&sep->pdev->dev, "[PID%d] ioctl end\n", current->pid);
+
+	return error;
+}
+
+/**
+ * sep_inthandler - interrupt handler for sep device
+ * @irq: interrupt
+ * @dev_id: device id
+ */
+static irqreturn_t sep_inthandler(int irq, void *dev_id)
+{
+	unsigned long lock_irq_flag;
+	u32 reg_val, reg_val2 = 0;
+	struct sep_device *sep = dev_id;
+	irqreturn_t int_error = IRQ_HANDLED;
+
+	/* Are we in power save? */
+#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM)
+	if (sep->pdev->dev.power.runtime_status != RPM_ACTIVE) {
+		dev_dbg(&sep->pdev->dev, "interrupt during pwr save\n");
+		return IRQ_NONE;
+	}
+#endif
+
+	if (test_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags) == 0) {
+		dev_dbg(&sep->pdev->dev, "interrupt while nobody using sep\n");
+		return IRQ_NONE;
+	}
+
+	/* Read the IRR register to check if this is SEP interrupt */
+	reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
+
+	dev_dbg(&sep->pdev->dev, "sep int: IRR REG val: %x\n", reg_val);
+
+	if (reg_val & (0x1 << 13)) {
+
+		/* Lock and update the counter of reply messages */
+		spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag);
+		sep->reply_ct++;
+		spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag);
+
+		dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n",
+					sep->send_ct, sep->reply_ct);
+
+		/* Is this a kernel client request */
+		if (sep->in_kernel) {
+			tasklet_schedule(&sep->finish_tasklet);
+			goto finished_interrupt;
+		}
+
+		/* Is this printf or daemon request? */
+		reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+		dev_dbg(&sep->pdev->dev,
+			"SEP Interrupt - GPR2 is %08x\n", reg_val2);
+
+		clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags);
+
+		if ((reg_val2 >> 30) & 0x1) {
+			dev_dbg(&sep->pdev->dev, "int: printf request\n");
+		} else if (reg_val2 >> 31) {
+			dev_dbg(&sep->pdev->dev, "int: daemon request\n");
+		} else {
+			dev_dbg(&sep->pdev->dev, "int: SEP reply\n");
+			wake_up(&sep->event_interrupt);
+		}
+	} else {
+		dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n");
+		int_error = IRQ_NONE;
+	}
+
+finished_interrupt:
+
+	if (int_error == IRQ_HANDLED)
+		sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
+
+	return int_error;
+}
+
+/**
+ * sep_reconfig_shared_area - reconfigure shared area
+ * @sep: pointer to struct sep_device
+ *
+ * Reconfig the shared area between HOST and SEP - needed in case
+ * the DX_CC_Init function was called before OS loading.
+ */
+static int sep_reconfig_shared_area(struct sep_device *sep)
+{
+	int ret_val;
+
+	/* use to limit waiting for SEP */
+	unsigned long end_time;
+
+	/* Send the new SHARED MESSAGE AREA to the SEP */
+	dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n",
+				(unsigned long long)sep->shared_bus);
+
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
+
+	/* Poll for SEP response */
+	ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
+
+	end_time = jiffies + (WAIT_TIME * HZ);
+
+	while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) &&
+		(ret_val != sep->shared_bus))
+		ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
+
+	/* Check the return value (register) */
+	if (ret_val != sep->shared_bus) {
+		dev_warn(&sep->pdev->dev, "could not reconfig shared area\n");
+		dev_warn(&sep->pdev->dev, "result was %x\n", ret_val);
+		ret_val = -ENOMEM;
+	} else
+		ret_val = 0;
+
+	dev_dbg(&sep->pdev->dev, "reconfig shared area end\n");
+
+	return ret_val;
+}
+
+/**
+ *	sep_activate_dcb_dmatables_context - Takes DCB & DMA tables
+ *						contexts into use
+ *	@sep: SEP device
+ *	@dcb_region: DCB region copy
+ *	@dmatables_region: MLLI/DMA tables copy
+ *	@dma_ctx: DMA context for current transaction
+ */
+ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep,
+					struct sep_dcblock **dcb_region,
+					void **dmatables_region,
+					struct sep_dma_context *dma_ctx)
+{
+	void *dmaregion_free_start = NULL;
+	void *dmaregion_free_end = NULL;
+	void *dcbregion_free_start = NULL;
+	void *dcbregion_free_end = NULL;
+	ssize_t error = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] activating dcb/dma region\n",
+		current->pid);
+
+	if (1 > dma_ctx->nr_dcb_creat) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid number of dcbs to activate 0x%08X\n",
+			 current->pid, dma_ctx->nr_dcb_creat);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	dmaregion_free_start = sep->shared_addr
+				+ SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES;
+	dmaregion_free_end = dmaregion_free_start
+				+ SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1;
+
+	if (dmaregion_free_start
+	     + dma_ctx->dmatables_len > dmaregion_free_end) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+	memcpy(dmaregion_free_start,
+	       *dmatables_region,
+	       dma_ctx->dmatables_len);
+	/* Free MLLI table copy */
+	kfree(*dmatables_region);
+	*dmatables_region = NULL;
+
+	/* Copy thread's DCB  table copy to DCB table region */
+	dcbregion_free_start = sep->shared_addr +
+				SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES;
+	dcbregion_free_end = dcbregion_free_start +
+				(SEP_MAX_NUM_SYNC_DMA_OPS *
+					sizeof(struct sep_dcblock)) - 1;
+
+	if (dcbregion_free_start
+	     + (dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock))
+	     > dcbregion_free_end) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	memcpy(dcbregion_free_start,
+	       *dcb_region,
+	       dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock));
+
+	/* Print the tables */
+	dev_dbg(&sep->pdev->dev, "activate: input table\n");
+	sep_debug_print_lli_tables(sep,
+		(struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep,
+		(*dcb_region)->input_mlli_address),
+		(*dcb_region)->input_mlli_num_entries,
+		(*dcb_region)->input_mlli_data_size);
+
+	dev_dbg(&sep->pdev->dev, "activate: output table\n");
+	sep_debug_print_lli_tables(sep,
+		(struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep,
+		(*dcb_region)->output_mlli_address),
+		(*dcb_region)->output_mlli_num_entries,
+		(*dcb_region)->output_mlli_data_size);
+
+	dev_dbg(&sep->pdev->dev,
+		 "[PID%d] printing activated tables\n", current->pid);
+
+end_function:
+	kfree(*dmatables_region);
+	*dmatables_region = NULL;
+
+	kfree(*dcb_region);
+	*dcb_region = NULL;
+
+	return error;
+}
+
+/**
+ *	sep_create_dcb_dmatables_context - Creates DCB & MLLI/DMA table context
+ *	@sep: SEP device
+ *	@dcb_region: DCB region buf to create for current transaction
+ *	@dmatables_region: MLLI/DMA tables buf to create for current transaction
+ *	@dma_ctx: DMA context buf to create for current transaction
+ *	@user_dcb_args: User arguments for DCB/MLLI creation
+ *	@num_dcbs: Number of DCBs to create
+ *	@secure_dma: Indicate use of IMR restricted memory secure dma
+ */
+static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep,
+			struct sep_dcblock **dcb_region,
+			void **dmatables_region,
+			struct sep_dma_context **dma_ctx,
+			const struct build_dcb_struct __user *user_dcb_args,
+			const u32 num_dcbs, bool secure_dma)
+{
+	int error = 0;
+	int i = 0;
+	struct build_dcb_struct *dcb_args = NULL;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n",
+		current->pid);
+
+	if (!dcb_region || !dma_ctx || !dmatables_region || !user_dcb_args) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid number of dcbs 0x%08X\n",
+			 current->pid, num_dcbs);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	dcb_args = kzalloc(num_dcbs * sizeof(struct build_dcb_struct),
+			   GFP_KERNEL);
+	if (!dcb_args) {
+		dev_warn(&sep->pdev->dev, "[PID%d] no memory for dcb args\n",
+			 current->pid);
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	if (copy_from_user(dcb_args,
+			user_dcb_args,
+			num_dcbs * sizeof(struct build_dcb_struct))) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	/* Allocate thread-specific memory for DCB */
+	*dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock),
+			      GFP_KERNEL);
+	if (!(*dcb_region)) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	/* Prepare DCB and MLLI table into the allocated regions */
+	for (i = 0; i < num_dcbs; i++) {
+		error = sep_prepare_input_output_dma_table_in_dcb(sep,
+				(unsigned long)dcb_args[i].app_in_address,
+				(unsigned long)dcb_args[i].app_out_address,
+				dcb_args[i].data_in_size,
+				dcb_args[i].block_size,
+				dcb_args[i].tail_block_size,
+				dcb_args[i].is_applet,
+				false, secure_dma,
+				*dcb_region, dmatables_region,
+				dma_ctx,
+				NULL,
+				NULL);
+		if (error) {
+			dev_warn(&sep->pdev->dev,
+				 "[PID%d] dma table creation failed\n",
+				 current->pid);
+			goto end_function;
+		}
+
+		if (dcb_args[i].app_in_address != 0)
+			(*dma_ctx)->input_data_len += dcb_args[i].data_in_size;
+	}
+
+end_function:
+	kfree(dcb_args);
+	return error;
+
+}
+
+/**
+ *	sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context
+ *      for kernel crypto
+ *	@sep: SEP device
+ *	@dcb_region: DCB region buf to create for current transaction
+ *	@dmatables_region: MLLI/DMA tables buf to create for current transaction
+ *	@dma_ctx: DMA context buf to create for current transaction
+ *	@user_dcb_args: User arguments for DCB/MLLI creation
+ *	@num_dcbs: Number of DCBs to create
+ *	This does that same thing as sep_create_dcb_dmatables_context
+ *	except that it is used only for the kernel crypto operation. It is
+ *	separate because there is no user data involved; the dcb data structure
+ *	is specific for kernel crypto (build_dcb_struct_kernel)
+ */
+int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep,
+			struct sep_dcblock **dcb_region,
+			void **dmatables_region,
+			struct sep_dma_context **dma_ctx,
+			const struct build_dcb_struct_kernel *dcb_data,
+			const u32 num_dcbs)
+{
+	int error = 0;
+	int i = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n",
+		current->pid);
+
+	if (!dcb_region || !dma_ctx || !dmatables_region || !dcb_data) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid number of dcbs 0x%08X\n",
+			 current->pid, num_dcbs);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] num_dcbs is %d\n",
+		current->pid, num_dcbs);
+
+	/* Allocate thread-specific memory for DCB */
+	*dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock),
+			      GFP_KERNEL);
+	if (!(*dcb_region)) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	/* Prepare DCB and MLLI table into the allocated regions */
+	for (i = 0; i < num_dcbs; i++) {
+		error = sep_prepare_input_output_dma_table_in_dcb(sep,
+				(unsigned long)dcb_data->app_in_address,
+				(unsigned long)dcb_data->app_out_address,
+				dcb_data->data_in_size,
+				dcb_data->block_size,
+				dcb_data->tail_block_size,
+				dcb_data->is_applet,
+				true,
+				false,
+				*dcb_region, dmatables_region,
+				dma_ctx,
+				dcb_data->src_sg,
+				dcb_data->dst_sg);
+		if (error) {
+			dev_warn(&sep->pdev->dev,
+				 "[PID%d] dma table creation failed\n",
+				 current->pid);
+			goto end_function;
+		}
+	}
+
+end_function:
+	return error;
+
+}
+
+/**
+ *	sep_activate_msgarea_context - Takes the message area context into use
+ *	@sep: SEP device
+ *	@msg_region: Message area context buf
+ *	@msg_len: Message area context buffer size
+ */
+static ssize_t sep_activate_msgarea_context(struct sep_device *sep,
+					    void **msg_region,
+					    const size_t msg_len)
+{
+	dev_dbg(&sep->pdev->dev, "[PID%d] activating msg region\n",
+		current->pid);
+
+	if (!msg_region || !(*msg_region) ||
+	    SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES < msg_len) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid act msgarea len 0x%08zX\n",
+			 current->pid, msg_len);
+		return -EINVAL;
+	}
+
+	memcpy(sep->shared_addr, *msg_region, msg_len);
+
+	return 0;
+}
+
+/**
+ *	sep_create_msgarea_context - Creates message area context
+ *	@sep: SEP device
+ *	@msg_region: Msg area region buf to create for current transaction
+ *	@msg_user: Content for msg area region from user
+ *	@msg_len: Message area size
+ */
+static ssize_t sep_create_msgarea_context(struct sep_device *sep,
+					  void **msg_region,
+					  const void __user *msg_user,
+					  const size_t msg_len)
+{
+	int error = 0;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] creating msg region\n",
+		current->pid);
+
+	if (!msg_region ||
+	    !msg_user ||
+	    SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < msg_len ||
+	    SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > msg_len) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid creat msgarea len 0x%08zX\n",
+			 current->pid, msg_len);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	/* Allocate thread-specific memory for message buffer */
+	*msg_region = kzalloc(msg_len, GFP_KERNEL);
+	if (!(*msg_region)) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] no mem for msgarea context\n",
+			 current->pid);
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	/* Copy input data to write() to allocated message buffer */
+	if (copy_from_user(*msg_region, msg_user, msg_len)) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+end_function:
+	if (error && msg_region) {
+		kfree(*msg_region);
+		*msg_region = NULL;
+	}
+
+	return error;
+}
+
+
+/**
+ *	sep_read - Returns results of an operation for fastcall interface
+ *	@filp: File pointer
+ *	@buf_user: User buffer for storing results
+ *	@count_user: User buffer size
+ *	@offset: File offset, not supported
+ *
+ *	The implementation does not support reading in chunks, all data must be
+ *	consumed during a single read system call.
+ */
+static ssize_t sep_read(struct file *filp,
+			char __user *buf_user, size_t count_user,
+			loff_t *offset)
+{
+	struct sep_private_data * const private_data = filp->private_data;
+	struct sep_call_status *call_status = &private_data->call_status;
+	struct sep_device *sep = private_data->device;
+	struct sep_dma_context **dma_ctx = &private_data->dma_ctx;
+	struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem;
+	ssize_t error = 0, error_tmp = 0;
+
+	/* Am I the process that owns the transaction? */
+	error = sep_check_transaction_owner(sep);
+	if (error) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] read pid is not owner\n",
+			current->pid);
+		goto end_function;
+	}
+
+	/* Checks that user has called necessarry apis */
+	if (0 == test_bit(SEP_FASTCALL_WRITE_DONE_OFFSET,
+			&call_status->status)) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] fastcall write not called\n",
+			 current->pid);
+		error = -EPROTO;
+		goto end_function_error;
+	}
+
+	if (!buf_user) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] null user buffer\n",
+			 current->pid);
+		error = -EINVAL;
+		goto end_function_error;
+	}
+
+
+	/* Wait for SEP to finish */
+	wait_event(sep->event_interrupt,
+		   test_bit(SEP_WORKING_LOCK_BIT,
+			    &sep->in_use_flags) == 0);
+
+	sep_dump_message(sep);
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08zX\n",
+		current->pid, count_user);
+
+	/* In case user has allocated bigger buffer */
+	if (count_user > SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
+		count_user = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES;
+
+	if (copy_to_user(buf_user, sep->shared_addr, count_user)) {
+		error = -EFAULT;
+		goto end_function_error;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] read succeeded\n", current->pid);
+	error = count_user;
+
+end_function_error:
+	/* Copy possible tail data to user and free DCB and MLLIs */
+	error_tmp = sep_free_dcb_handler(sep, dma_ctx);
+	if (error_tmp)
+		dev_warn(&sep->pdev->dev, "[PID%d] dcb free failed\n",
+			current->pid);
+
+	/* End the transaction, wakeup pending ones */
+	error_tmp = sep_end_transaction_handler(sep, dma_ctx, call_status,
+		my_queue_elem);
+	if (error_tmp)
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] ending transaction failed\n",
+			 current->pid);
+
+end_function:
+	return error;
+}
+
+/**
+ *	sep_fastcall_args_get - Gets fastcall params from user
+ *	sep: SEP device
+ *	@args: Parameters buffer
+ *	@buf_user: User buffer for operation parameters
+ *	@count_user: User buffer size
+ */
+static inline ssize_t sep_fastcall_args_get(struct sep_device *sep,
+					    struct sep_fastcall_hdr *args,
+					    const char __user *buf_user,
+					    const size_t count_user)
+{
+	ssize_t error = 0;
+	size_t actual_count = 0;
+
+	if (!buf_user) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] null user buffer\n",
+			 current->pid);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	if (count_user < sizeof(struct sep_fastcall_hdr)) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] too small message size 0x%08zX\n",
+			 current->pid, count_user);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+
+	if (copy_from_user(args, buf_user, sizeof(struct sep_fastcall_hdr))) {
+		error = -EFAULT;
+		goto end_function;
+	}
+
+	if (SEP_FC_MAGIC != args->magic) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid fastcall magic 0x%08X\n",
+			 current->pid, args->magic);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr num of DCBs 0x%08X\n",
+		current->pid, args->num_dcbs);
+	dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr msg len 0x%08X\n",
+		current->pid, args->msg_len);
+
+	if (SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < args->msg_len ||
+	    SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > args->msg_len) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] invalid message length\n",
+			 current->pid);
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	actual_count = sizeof(struct sep_fastcall_hdr)
+			+ args->msg_len
+			+ (args->num_dcbs * sizeof(struct build_dcb_struct));
+
+	if (actual_count != count_user) {
+		dev_warn(&sep->pdev->dev,
+			 "[PID%d] inconsistent message "
+			 "sizes 0x%08zX vs 0x%08zX\n",
+			 current->pid, actual_count, count_user);
+		error = -EMSGSIZE;
+		goto end_function;
+	}
+
+end_function:
+	return error;
+}
+
+/**
+ *	sep_write - Starts an operation for fastcall interface
+ *	@filp: File pointer
+ *	@buf_user: User buffer for operation parameters
+ *	@count_user: User buffer size
+ *	@offset: File offset, not supported
+ *
+ *	The implementation does not support writing in chunks,
+ *	all data must be given during a single write system call.
+ */
+static ssize_t sep_write(struct file *filp,
+			 const char __user *buf_user, size_t count_user,
+			 loff_t *offset)
+{
+	struct sep_private_data * const private_data = filp->private_data;
+	struct sep_call_status *call_status = &private_data->call_status;
+	struct sep_device *sep = private_data->device;
+	struct sep_dma_context *dma_ctx = NULL;
+	struct sep_fastcall_hdr call_hdr = {0};
+	void *msg_region = NULL;
+	void *dmatables_region = NULL;
+	struct sep_dcblock *dcb_region = NULL;
+	ssize_t error = 0;
+	struct sep_queue_info *my_queue_elem = NULL;
+	bool my_secure_dma; /* are we using secure_dma (IMR)? */
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] sep dev is 0x%p\n",
+		current->pid, sep);
+	dev_dbg(&sep->pdev->dev, "[PID%d] private_data is 0x%p\n",
+		current->pid, private_data);
+
+	error = sep_fastcall_args_get(sep, &call_hdr, buf_user, count_user);
+	if (error)
+		goto end_function;
+
+	buf_user += sizeof(struct sep_fastcall_hdr);
+
+	if (call_hdr.secure_dma == 0)
+		my_secure_dma = false;
+	else
+		my_secure_dma = true;
+
+	/*
+	 * Controlling driver memory usage by limiting amount of
+	 * buffers created. Only SEP_DOUBLEBUF_USERS_LIMIT number
+	 * of threads can progress further at a time
+	 */
+	dev_dbg(&sep->pdev->dev, "[PID%d] waiting for double buffering "
+				 "region access\n", current->pid);
+	error = down_interruptible(&sep->sep_doublebuf);
+	dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region start\n",
+					current->pid);
+	if (error) {
+		/* Signal received */
+		goto end_function_error;
+	}
+
+
+	/*
+	 * Prepare contents of the shared area regions for
+	 * the operation into temporary buffers
+	 */
+	if (0 < call_hdr.num_dcbs) {
+		error = sep_create_dcb_dmatables_context(sep,
+				&dcb_region,
+				&dmatables_region,
+				&dma_ctx,
+				(const struct build_dcb_struct __user *)
+					buf_user,
+				call_hdr.num_dcbs, my_secure_dma);
+		if (error)
+			goto end_function_error_doublebuf;
+
+		buf_user += call_hdr.num_dcbs * sizeof(struct build_dcb_struct);
+	}
+
+	error = sep_create_msgarea_context(sep,
+					   &msg_region,
+					   buf_user,
+					   call_hdr.msg_len);
+	if (error)
+		goto end_function_error_doublebuf;
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] updating queue status\n",
+							current->pid);
+	my_queue_elem = sep_queue_status_add(sep,
+				((struct sep_msgarea_hdr *)msg_region)->opcode,
+				(dma_ctx) ? dma_ctx->input_data_len : 0,
+				     current->pid,
+				     current->comm, sizeof(current->comm));
+
+	if (!my_queue_elem) {
+		dev_dbg(&sep->pdev->dev, "[PID%d] updating queue"
+					"status error\n", current->pid);
+		error = -ENOMEM;
+		goto end_function_error_doublebuf;
+	}
+
+	/* Wait until current process gets the transaction */
+	error = sep_wait_transaction(sep);
+
+	if (error) {
+		/* Interrupted by signal, don't clear transaction */
+		dev_dbg(&sep->pdev->dev, "[PID%d] interrupted by signal\n",
+			current->pid);
+		sep_queue_status_remove(sep, &my_queue_elem);
+		goto end_function_error_doublebuf;
+	}
+
+	dev_dbg(&sep->pdev->dev, "[PID%d] saving queue element\n",
+		current->pid);
+	private_data->my_queue_elem = my_queue_elem;
+
+	/* Activate shared area regions for the transaction */
+	error = sep_activate_msgarea_context(sep, &msg_region,
+					     call_hdr.msg_len);
+	if (error)
+		goto end_function_error_clear_transact;
+
+	sep_dump_message(sep);
+
+	if (0 < call_hdr.num_dcbs) {
+		error = sep_activate_dcb_dmatables_context(sep,
+				&dcb_region,
+				&dmatables_region,
+				dma_ctx);
+		if (error)
+			goto end_function_error_clear_transact;
+	}
+
+	/* Send command to SEP */
+	error = sep_send_command_handler(sep);
+	if (error)
+		goto end_function_error_clear_transact;
+
+	/* Store DMA context for the transaction */
+	private_data->dma_ctx = dma_ctx;
+	/* Update call status */
+	set_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, &call_status->status);
+	error = count_user;
+
+	up(&sep->sep_doublebuf);
+	dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n",
+		current->pid);
+
+	goto end_function;
+
+end_function_error_clear_transact:
+	sep_end_transaction_handler(sep, &dma_ctx, call_status,
+						&private_data->my_queue_elem);
+
+end_function_error_doublebuf:
+	up(&sep->sep_doublebuf);
+	dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n",
+		current->pid);
+
+end_function_error:
+	if (dma_ctx)
+		sep_free_dma_table_data_handler(sep, &dma_ctx);
+
+end_function:
+	kfree(dcb_region);
+	kfree(dmatables_region);
+	kfree(msg_region);
+
+	return error;
+}
+/**
+ *	sep_seek - Handler for seek system call
+ *	@filp: File pointer
+ *	@offset: File offset
+ *	@origin: Options for offset
+ *
+ *	Fastcall interface does not support seeking, all reads
+ *	and writes are from/to offset zero
+ */
+static loff_t sep_seek(struct file *filp, loff_t offset, int origin)
+{
+	return -ENOSYS;
+}
+
+
+
+/**
+ * sep_file_operations - file operation on sep device
+ * @sep_ioctl:	ioctl handler from user space call
+ * @sep_poll:	poll handler
+ * @sep_open:	handles sep device open request
+ * @sep_release:handles sep device release request
+ * @sep_mmap:	handles memory mapping requests
+ * @sep_read:	handles read request on sep device
+ * @sep_write:	handles write request on sep device
+ * @sep_seek:	handles seek request on sep device
+ */
+static const struct file_operations sep_file_operations = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = sep_ioctl,
+	.poll = sep_poll,
+	.open = sep_open,
+	.release = sep_release,
+	.mmap = sep_mmap,
+	.read = sep_read,
+	.write = sep_write,
+	.llseek = sep_seek,
+};
+
+/**
+ * sep_sysfs_read - read sysfs entry per gives arguments
+ * @filp: file pointer
+ * @kobj: kobject pointer
+ * @attr: binary file attributes
+ * @buf: read to this buffer
+ * @pos: offset to read
+ * @count: amount of data to read
+ *
+ * This function is to read sysfs entries for sep driver per given arguments.
+ */
+static ssize_t
+sep_sysfs_read(struct file *filp, struct kobject *kobj,
+		struct bin_attribute *attr,
+		char *buf, loff_t pos, size_t count)
+{
+	unsigned long lck_flags;
+	size_t nleft = count;
+	struct sep_device *sep = sep_dev;
+	struct sep_queue_info *queue_elem = NULL;
+	u32 queue_num = 0;
+	u32 i = 1;
+
+	spin_lock_irqsave(&sep->sep_queue_lock, lck_flags);
+
+	queue_num = sep->sep_queue_num;
+	if (queue_num > SEP_DOUBLEBUF_USERS_LIMIT)
+		queue_num = SEP_DOUBLEBUF_USERS_LIMIT;
+
+
+	if (count < sizeof(queue_num)
+			+ (queue_num * sizeof(struct sep_queue_data))) {
+		spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
+		return -EINVAL;
+	}
+
+	memcpy(buf, &queue_num, sizeof(queue_num));
+	buf += sizeof(queue_num);
+	nleft -= sizeof(queue_num);
+
+	list_for_each_entry(queue_elem, &sep->sep_queue_status, list) {
+		if (i++ > queue_num)
+			break;
+
+		memcpy(buf, &queue_elem->data, sizeof(queue_elem->data));
+		nleft -= sizeof(queue_elem->data);
+		buf += sizeof(queue_elem->data);
+	}
+	spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags);
+
+	return count - nleft;
+}
+
+/**
+ * bin_attributes - defines attributes for queue_status
+ * @attr: attributes (name & permissions)
+ * @read: function pointer to read this file
+ * @size: maxinum size of binary attribute
+ */
+static const struct bin_attribute queue_status = {
+	.attr = {.name = "queue_status", .mode = 0444},
+	.read = sep_sysfs_read,
+	.size = sizeof(u32)
+		+ (SEP_DOUBLEBUF_USERS_LIMIT * sizeof(struct sep_queue_data)),
+};
+
+/**
+ * sep_register_driver_with_fs - register misc devices
+ * @sep: pointer to struct sep_device
+ *
+ * This function registers the driver with the file system
+ */
+static int sep_register_driver_with_fs(struct sep_device *sep)
+{
+	int ret_val;
+
+	sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR;
+	sep->miscdev_sep.name = SEP_DEV_NAME;
+	sep->miscdev_sep.fops = &sep_file_operations;
+
+	ret_val = misc_register(&sep->miscdev_sep);
+	if (ret_val) {
+		dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n",
+			ret_val);
+		return ret_val;
+	}
+
+	ret_val = device_create_bin_file(sep->miscdev_sep.this_device,
+								&queue_status);
+	if (ret_val) {
+		dev_warn(&sep->pdev->dev, "sysfs attribute1 fails for SEP %x\n",
+			ret_val);
+		return ret_val;
+	}
+
+	return ret_val;
+}
+
+
+/**
+ *sep_probe - probe a matching PCI device
+ *@pdev:	pci_device
+ *@ent:	pci_device_id
+ *
+ *Attempt to set up and configure a SEP device that has been
+ *discovered by the PCI layer. Allocates all required resources.
+ */
+static int __devinit sep_probe(struct pci_dev *pdev,
+	const struct pci_device_id *ent)
+{
+	int error = 0;
+	struct sep_device *sep = NULL;
+
+	if (sep_dev != NULL) {
+		dev_dbg(&pdev->dev, "only one SEP supported.\n");
+		return -EBUSY;
+	}
+
+	/* Enable the device */
+	error = pci_enable_device(pdev);
+	if (error) {
+		dev_warn(&pdev->dev, "error enabling pci device\n");
+		goto end_function;
+	}
+
+	/* Allocate the sep_device structure for this device */
+	sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC);
+	if (sep_dev == NULL) {
+		dev_warn(&pdev->dev,
+			"can't kmalloc the sep_device structure\n");
+		error = -ENOMEM;
+		goto end_function_disable_device;
+	}
+
+	/*
+	 * We're going to use another variable for actually
+	 * working with the device; this way, if we have
+	 * multiple devices in the future, it would be easier
+	 * to make appropriate changes
+	 */
+	sep = sep_dev;
+
+	sep->pdev = pci_dev_get(pdev);
+
+	init_waitqueue_head(&sep->event_transactions);
+	init_waitqueue_head(&sep->event_interrupt);
+	spin_lock_init(&sep->snd_rply_lck);
+	spin_lock_init(&sep->sep_queue_lock);
+	sema_init(&sep->sep_doublebuf, SEP_DOUBLEBUF_USERS_LIMIT);
+
+	INIT_LIST_HEAD(&sep->sep_queue_status);
+
+	dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, "
+		"device being prepared\n");
+
+	/* Set up our register area */
+	sep->reg_physical_addr = pci_resource_start(sep->pdev, 0);
+	if (!sep->reg_physical_addr) {
+		dev_warn(&sep->pdev->dev, "Error getting register start\n");
+		error = -ENODEV;
+		goto end_function_free_sep_dev;
+	}
+
+	sep->reg_physical_end = pci_resource_end(sep->pdev, 0);
+	if (!sep->reg_physical_end) {
+		dev_warn(&sep->pdev->dev, "Error getting register end\n");
+		error = -ENODEV;
+		goto end_function_free_sep_dev;
+	}
+
+	sep->reg_addr = ioremap_nocache(sep->reg_physical_addr,
+		(size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1));
+	if (!sep->reg_addr) {
+		dev_warn(&sep->pdev->dev, "Error getting register virtual\n");
+		error = -ENODEV;
+		goto end_function_free_sep_dev;
+	}
+
+	dev_dbg(&sep->pdev->dev,
+		"Register area start %llx end %llx virtual %p\n",
+		(unsigned long long)sep->reg_physical_addr,
+		(unsigned long long)sep->reg_physical_end,
+		sep->reg_addr);
+
+	/* Allocate the shared area */
+	sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
+		SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES +
+		SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES +
+		SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES +
+		SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
+
+	if (sep_map_and_alloc_shared_area(sep)) {
+		error = -ENOMEM;
+		/* Allocation failed */
+		goto end_function_error;
+	}
+
+	/* Clear ICR register */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+
+	/* Set the IMR register - open only GPR 2 */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+	/* Read send/receive counters from SEP */
+	sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+	sep->reply_ct &= 0x3FFFFFFF;
+	sep->send_ct = sep->reply_ct;
+
+	/* Get the interrupt line */
+	error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED,
+		"sep_driver", sep);
+
+	if (error)
+		goto end_function_deallocate_sep_shared_area;
+
+	/* The new chip requires a shared area reconfigure */
+	error = sep_reconfig_shared_area(sep);
+	if (error)
+		goto end_function_free_irq;
+
+	sep->in_use = 1;
+
+	/* Finally magic up the device nodes */
+	/* Register driver with the fs */
+	error = sep_register_driver_with_fs(sep);
+
+	if (error) {
+		dev_err(&sep->pdev->dev, "error registering dev file\n");
+		goto end_function_free_irq;
+	}
+
+	sep->in_use = 0; /* through touching the device */
+#ifdef SEP_ENABLE_RUNTIME_PM
+	pm_runtime_put_noidle(&sep->pdev->dev);
+	pm_runtime_allow(&sep->pdev->dev);
+	pm_runtime_set_autosuspend_delay(&sep->pdev->dev,
+		SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&sep->pdev->dev);
+	pm_runtime_mark_last_busy(&sep->pdev->dev);
+	sep->power_save_setup = 1;
+#endif
+	/* register kernel crypto driver */
+#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE)
+	error = sep_crypto_setup();
+	if (error) {
+		dev_err(&sep->pdev->dev, "crypto setup failed\n");
+		goto end_function_free_irq;
+	}
+#endif
+	goto end_function;
+
+end_function_free_irq:
+	free_irq(pdev->irq, sep);
+
+end_function_deallocate_sep_shared_area:
+	/* De-allocate shared area */
+	sep_unmap_and_free_shared_area(sep);
+
+end_function_error:
+	iounmap(sep->reg_addr);
+
+end_function_free_sep_dev:
+	pci_dev_put(sep_dev->pdev);
+	kfree(sep_dev);
+	sep_dev = NULL;
+
+end_function_disable_device:
+	pci_disable_device(pdev);
+
+end_function:
+	return error;
+}
+
+/**
+ * sep_remove -	handles removing device from pci subsystem
+ * @pdev:	pointer to pci device
+ *
+ * This function will handle removing our sep device from pci subsystem on exit
+ * or unloading this module. It should free up all used resources, and unmap if
+ * any memory regions mapped.
+ */
+static void sep_remove(struct pci_dev *pdev)
+{
+	struct sep_device *sep = sep_dev;
+
+	/* Unregister from fs */
+	misc_deregister(&sep->miscdev_sep);
+
+	/* Unregister from kernel crypto */
+#if defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE)
+	sep_crypto_takedown();
+#endif
+	/* Free the irq */
+	free_irq(sep->pdev->irq, sep);
+
+	/* Free the shared area  */
+	sep_unmap_and_free_shared_area(sep_dev);
+	iounmap(sep_dev->reg_addr);
+
+#ifdef SEP_ENABLE_RUNTIME_PM
+	if (sep->in_use) {
+		sep->in_use = 0;
+		pm_runtime_forbid(&sep->pdev->dev);
+		pm_runtime_get_noresume(&sep->pdev->dev);
+	}
+#endif
+	pci_dev_put(sep_dev->pdev);
+	kfree(sep_dev);
+	sep_dev = NULL;
+}
+
+/* Initialize struct pci_device_id for our driver */
+static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0826)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x08e9)},
+ 	{0}
+};
+
+/* Export our pci_device_id structure to user space */
+MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
+
+#ifdef SEP_ENABLE_RUNTIME_PM
+
+/**
+ * sep_pm_resume - rsume routine while waking up from S3 state
+ * @dev:	pointer to sep device
+ *
+ * This function is to be used to wake up sep driver while system awakes from S3
+ * state i.e. suspend to ram. The RAM in intact.
+ * Notes - revisit with more understanding of pm, ICR/IMR & counters.
+ */
+static int sep_pci_resume(struct device *dev)
+{
+	struct sep_device *sep = sep_dev;
+
+	dev_dbg(&sep->pdev->dev, "pci resume called\n");
+
+	if (sep->power_state == SEP_DRIVER_POWERON)
+		return 0;
+
+	/* Clear ICR register */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+
+	/* Set the IMR register - open only GPR 2 */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+	/* Read send/receive counters from SEP */
+	sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+	sep->reply_ct &= 0x3FFFFFFF;
+	sep->send_ct = sep->reply_ct;
+
+	sep->power_state = SEP_DRIVER_POWERON;
+
+	return 0;
+}
+
+/**
+ * sep_pm_suspend - suspend routine while going to S3 state
+ * @dev:	pointer to sep device
+ *
+ * This function is to be used to suspend sep driver while system goes to S3
+ * state i.e. suspend to ram. The RAM in intact and ON during this suspend.
+ * Notes - revisit with more understanding of pm, ICR/IMR
+ */
+static int sep_pci_suspend(struct device *dev)
+{
+	struct sep_device *sep = sep_dev;
+
+	dev_dbg(&sep->pdev->dev, "pci suspend called\n");
+	if (sep->in_use == 1)
+		return -EAGAIN;
+
+	sep->power_state = SEP_DRIVER_POWEROFF;
+
+	/* Clear ICR register */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+
+	/* Set the IMR to block all */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0xFFFFFFFF);
+
+	return 0;
+}
+
+/**
+ * sep_pm_runtime_resume - runtime resume routine
+ * @dev:	pointer to sep device
+ *
+ * Notes - revisit with more understanding of pm, ICR/IMR & counters
+ */
+static int sep_pm_runtime_resume(struct device *dev)
+{
+
+	u32 retval2;
+	u32 delay_count;
+	struct sep_device *sep = sep_dev;
+
+	dev_dbg(&sep->pdev->dev, "pm runtime resume called\n");
+
+	/**
+	 * Wait until the SCU boot is ready
+	 * This is done by iterating SCU_DELAY_ITERATION (10
+	 * microseconds each) up to SCU_DELAY_MAX (50) times.
+	 * This bit can be set in a random time that is less
+	 * than 500 microseconds after each power resume
+	 */
+	retval2 = 0;
+	delay_count = 0;
+	while ((!retval2) && (delay_count < SCU_DELAY_MAX)) {
+		retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+		retval2 &= 0x00000008;
+		if (!retval2) {
+			udelay(SCU_DELAY_ITERATION);
+			delay_count += 1;
+		}
+	}
+
+	if (!retval2) {
+		dev_warn(&sep->pdev->dev, "scu boot bit not set at resume\n");
+		return -EINVAL;
+	}
+
+	/* Clear ICR register */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+
+	/* Set the IMR register - open only GPR 2 */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+	/* Read send/receive counters from SEP */
+	sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+	sep->reply_ct &= 0x3FFFFFFF;
+	sep->send_ct = sep->reply_ct;
+
+	return 0;
+}
+
+/**
+ * sep_pm_runtime_suspend - runtime suspend routine
+ * @dev:	pointer to sep device
+ *
+ * Notes - revisit with more understanding of pm
+ */
+static int sep_pm_runtime_suspend(struct device *dev)
+{
+	struct sep_device *sep = sep_dev;
+
+	dev_dbg(&sep->pdev->dev, "pm runtime suspend called\n");
+
+	/* Clear ICR register */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+	return 0;
+}
+
+/**
+ * sep_pm - power management for sep driver
+ * @sep_pm_runtime_resume:	resume- no communication with cpu & main memory
+ * @sep_pm_runtime_suspend:	suspend- no communication with cpu & main memory
+ * @sep_pci_suspend:		suspend - main memory is still ON
+ * @sep_pci_resume:		resume - main meory is still ON
+ */
+static const struct dev_pm_ops sep_pm = {
+	.runtime_resume = sep_pm_runtime_resume,
+	.runtime_suspend = sep_pm_runtime_suspend,
+	.resume = sep_pci_resume,
+	.suspend = sep_pci_suspend,
+};
+#endif /* SEP_ENABLE_RUNTIME_PM */
+
+/**
+ * sep_pci_driver - registers this device with pci subsystem
+ * @name:	name identifier for this driver
+ * @sep_pci_id_tbl:	pointer to struct pci_device_id table
+ * @sep_probe:	pointer to probe function in PCI driver
+ * @sep_remove:	pointer to remove function in PCI driver
+ */
+static struct pci_driver sep_pci_driver = {
+#ifdef SEP_ENABLE_RUNTIME_PM
+	.driver = {
+		.pm = &sep_pm,
+	},
+#endif
+	.name = "sep_sec_driver",
+	.id_table = sep_pci_id_tbl,
+	.probe = sep_probe,
+	.remove = sep_remove
+};
+
+/**
+ * sep_init - init function
+ *
+ * Module load time. Register the PCI device driver.
+ */
+
+static int __init sep_init(void)
+{
+	return pci_register_driver(&sep_pci_driver);
+}
+
+
+/**
+ * sep_exit - called to unload driver
+ *
+ * Unregister the driver The device will perform all the cleanup required.
+ */
+static void __exit sep_exit(void)
+{
+	pci_unregister_driver(&sep_pci_driver);
+}
+
+
+module_init(sep_init);
+module_exit(sep_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_trace_events.h b/drivers/staging/sep/sep_trace_events.h
new file mode 100644
index 0000000..2b053a9
--- /dev/null
+++ b/drivers/staging/sep/sep_trace_events.h
@@ -0,0 +1,188 @@
+/*
+ * If TRACE_SYSTEM is defined, that will be the directory created
+ * in the ftrace directory under /sys/kernel/debug/tracing/events/<system>
+ *
+ * The define_trace.h below will also look for a file name of
+ * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here.
+ * In this case, it would look for sample.h
+ *
+ * If the header name will be different than the system name
+ * (as in this case), then you can override the header name that
+ * define_trace.h will look up by defining TRACE_INCLUDE_FILE
+ *
+ * This file is called trace-events-sample.h but we want the system
+ * to be called "sample". Therefore we must define the name of this
+ * file:
+ *
+ * #define TRACE_INCLUDE_FILE trace-events-sample
+ *
+ * As we do an the bottom of this file.
+ *
+ * Notice that TRACE_SYSTEM should be defined outside of #if
+ * protection, just like TRACE_INCLUDE_FILE.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sep
+
+/*
+ * Notice that this file is not protected like a normal header.
+ * We also must allow for rereading of this file. The
+ *
+ *  || defined(TRACE_HEADER_MULTI_READ)
+ *
+ * serves this purpose.
+ */
+#if !defined(_TRACE_SEP_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SEP_EVENTS_H
+
+#ifdef SEP_PERF_DEBUG
+#define SEP_TRACE_FUNC_IN() trace_sep_func_start(__func__, 0)
+#define SEP_TRACE_FUNC_OUT(branch) trace_sep_func_end(__func__, branch)
+#define SEP_TRACE_EVENT(branch) trace_sep_misc_event(__func__, branch)
+#else
+#define SEP_TRACE_FUNC_IN()
+#define SEP_TRACE_FUNC_OUT(branch)
+#define SEP_TRACE_EVENT(branch)
+#endif
+
+
+/*
+ * All trace headers should include tracepoint.h, until we finally
+ * make it into a standard header.
+ */
+#include <linux/tracepoint.h>
+
+/*
+ * The TRACE_EVENT macro is broken up into 5 parts.
+ *
+ * name: name of the trace point. This is also how to enable the tracepoint.
+ *   A function called trace_foo_bar() will be created.
+ *
+ * proto: the prototype of the function trace_foo_bar()
+ *   Here it is trace_foo_bar(char *foo, int bar).
+ *
+ * args:  must match the arguments in the prototype.
+ *    Here it is simply "foo, bar".
+ *
+ * struct:  This defines the way the data will be stored in the ring buffer.
+ *    There are currently two types of elements. __field and __array.
+ *    a __field is broken up into (type, name). Where type can be any
+ *    type but an array.
+ *    For an array. there are three fields. (type, name, size). The
+ *    type of elements in the array, the name of the field and the size
+ *    of the array.
+ *
+ *    __array( char, foo, 10) is the same as saying   char foo[10].
+ *
+ * fast_assign: This is a C like function that is used to store the items
+ *    into the ring buffer.
+ *
+ * printk: This is a way to print out the data in pretty print. This is
+ *    useful if the system crashes and you are logging via a serial line,
+ *    the data can be printed to the console using this "printk" method.
+ *
+ * Note, that for both the assign and the printk, __entry is the handler
+ * to the data structure in the ring buffer, and is defined by the
+ * TP_STRUCT__entry.
+ */
+TRACE_EVENT(sep_func_start,
+
+	TP_PROTO(const char *name, int branch),
+
+	TP_ARGS(name, branch),
+
+	TP_STRUCT__entry(
+		__array(char,	name,    20)
+		__field(int,	branch)
+	),
+
+	TP_fast_assign(
+		strncpy(__entry->name, name, 20);
+		__entry->branch	= branch;
+	),
+
+	TP_printk("func_start %s %d", __entry->name, __entry->branch)
+);
+
+TRACE_EVENT(sep_func_end,
+
+	TP_PROTO(const char *name, int branch),
+
+	TP_ARGS(name, branch),
+
+	TP_STRUCT__entry(
+		__array(char,	name,    20)
+		__field(int,	branch)
+	),
+
+	TP_fast_assign(
+		strncpy(__entry->name, name, 20);
+		__entry->branch	= branch;
+	),
+
+	TP_printk("func_end %s %d", __entry->name, __entry->branch)
+);
+
+TRACE_EVENT(sep_misc_event,
+
+	TP_PROTO(const char *name, int branch),
+
+	TP_ARGS(name, branch),
+
+	TP_STRUCT__entry(
+		__array(char,	name,    20)
+		__field(int,	branch)
+	),
+
+	TP_fast_assign(
+		strncpy(__entry->name, name, 20);
+		__entry->branch	= branch;
+	),
+
+	TP_printk("misc_event %s %d", __entry->name, __entry->branch)
+);
+
+
+#endif
+
+/***** NOTICE! The #if protection ends here. *****/
+
+
+/*
+ * There are several ways I could have done this. If I left out the
+ * TRACE_INCLUDE_PATH, then it would default to the kernel source
+ * include/trace/events directory.
+ *
+ * I could specify a path from the define_trace.h file back to this
+ * file.
+ *
+ * #define TRACE_INCLUDE_PATH ../../samples/trace_events
+ *
+ * But the safest and easiest way to simply make it use the directory
+ * that the file is in is to add in the Makefile:
+ *
+ * CFLAGS_trace-events-sample.o := -I$(src)
+ *
+ * This will make sure the current path is part of the include
+ * structure for our file so that define_trace.h can find it.
+ *
+ * I could have made only the top level directory the include:
+ *
+ * CFLAGS_trace-events-sample.o := -I$(PWD)
+ *
+ * And then let the path to this directory be the TRACE_INCLUDE_PATH:
+ *
+ * #define TRACE_INCLUDE_PATH samples/trace_events
+ *
+ * But then if something defines "samples" or "trace_events" as a macro
+ * then we could risk that being converted too, and give us an unexpected
+ * result.
+ */
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_PATH .
+/*
+ * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal
+ */
+#define TRACE_INCLUDE_FILE sep_trace_events
+#include <trace/define_trace.h>
diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README
index b83bba1..cb04a87 100644
--- a/drivers/staging/slicoss/README
+++ b/drivers/staging/slicoss/README
@@ -42,7 +42,7 @@ TODO:
 
 
 Please send patches to:
-        Greg Kroah-Hartman <gregkh@suse.de>
+        Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 and Cc: Lior Dotan <liodot@gmail.com> and Christopher Harrer
 <charrer@alacritech.com> as well as they are also able to test out any
 changes.
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
index ae0035f..83c582e 100644
--- a/drivers/staging/sm7xx/smtcfb.c
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -41,7 +41,6 @@
 
 #ifdef CONFIG_PM
 #include <linux/pm.h>
-#include <linux/module.h>
 #endif
 
 #include "smtcfb.h"
@@ -443,7 +442,7 @@ static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
 }
 
 #ifdef __BIG_ENDIAN
-static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t
+static ssize_t smtcfb_read(struct fb_info *info, char __user *buf, size_t
 				count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h
index c5e6989..ab95af2 100644
--- a/drivers/staging/sm7xx/smtcfb.h
+++ b/drivers/staging/sm7xx/smtcfb.h
@@ -38,7 +38,7 @@
 #define dac_reg	(0x3c8)
 #define dac_val	(0x3c9)
 
-extern char *smtc_RegBaseAddress;
+extern char __iomem *smtc_RegBaseAddress;
 #define smtc_mmiowb(dat, reg)	writeb(dat, smtc_RegBaseAddress + reg)
 #define smtc_mmioww(dat, reg)	writew(dat, smtc_RegBaseAddress + reg)
 #define smtc_mmiowl(dat, reg)	writel(dat, smtc_RegBaseAddress + reg)
diff --git a/drivers/staging/telephony/Kconfig b/drivers/staging/telephony/Kconfig
new file mode 100644
index 0000000..b5f78b6
--- /dev/null
+++ b/drivers/staging/telephony/Kconfig
@@ -0,0 +1,47 @@
+#
+# Telephony device configuration
+#
+
+menuconfig PHONE
+	tristate "Telephony support"
+	depends on HAS_IOMEM
+	---help---
+	  Say Y here if you have a telephony card, which for example allows
+	  you to use a regular phone for voice-over-IP applications.
+
+	  Note: this has nothing to do with modems.  You do not need to say Y
+	  here in order to be able to use a modem under Linux.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called phonedev.
+
+if PHONE
+
+config PHONE_IXJ
+	tristate "QuickNet Internet LineJack/PhoneJack support"
+	depends on ISA || PCI
+	---help---
+	  Say M if you have a telephony card manufactured by Quicknet
+	  Technologies, Inc.  These include the Internet PhoneJACK and
+	  Internet LineJACK Telephony Cards. You will get a module called
+	  ixj.
+
+	  For the ISA versions of these products, you can configure the
+	  cards using the isapnp tools (pnpdump/isapnp) or you can use the
+	  isapnp support.  Please read <file:Documentation/telephony/ixj.txt>.
+
+	  For more information on these cards, see Quicknet's web site at:
+	  <http://www.quicknet.net/>.
+
+	  If you do not have any Quicknet telephony cards, you can safely
+	  say N here.
+
+config PHONE_IXJ_PCMCIA
+	tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support"
+	depends on PHONE_IXJ && PCMCIA
+	help
+	  Say Y here to configure in PCMCIA service support for the Quicknet
+	  cards manufactured by Quicknet Technologies, Inc.  This changes the
+	  card initialization code to work with the card manager daemon.
+
+endif # PHONE
diff --git a/drivers/staging/telephony/Makefile b/drivers/staging/telephony/Makefile
new file mode 100644
index 0000000..1206615
--- /dev/null
+++ b/drivers/staging/telephony/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for drivers/telephony
+#
+
+obj-$(CONFIG_PHONE) += phonedev.o
+obj-$(CONFIG_PHONE_IXJ) += ixj.o
+obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
diff --git a/drivers/staging/telephony/TODO b/drivers/staging/telephony/TODO
new file mode 100644
index 0000000..d47dec3
--- /dev/null
+++ b/drivers/staging/telephony/TODO
@@ -0,0 +1,10 @@
+TODO
+. Determine if the boards are still in use
+  and move this module back to drivers/telephony if necessary
+. Coding style cleanups
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
+cc Joe Perches <joe@perches.com> if the module should be reactivated.
+
+If no module activity occurs before version 3.6 is released, this
+module should be removed.
diff --git a/drivers/staging/telephony/ixj-ver.h b/drivers/staging/telephony/ixj-ver.h
new file mode 100644
index 0000000..2031ac6
--- /dev/null
+++ b/drivers/staging/telephony/ixj-ver.h
@@ -0,0 +1,4 @@
+/* configuration management identifiers */
+#define IXJ_VER_MAJOR 1
+#define IXJ_VER_MINOR 0
+#define IXJ_BLD_VER   1
diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c
new file mode 100644
index 0000000..d5f923b
--- /dev/null
+++ b/drivers/staging/telephony/ixj.c
@@ -0,0 +1,10552 @@
+/****************************************************************************
+ *    ixj.c
+ *
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
+ *
+ *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
+ *
+ *    This program is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU General Public License
+ *    as published by the Free Software Foundation; either version
+ *    2 of the License, or (at your option) any later version.
+ *
+ * Author:          Ed Okerson, <eokerson@quicknet.net>
+ *
+ * Contributors:    Greg Herlein, <gherlein@quicknet.net>
+ *                  David W. Erhart, <derhart@quicknet.net>
+ *                  John Sellers, <jsellers@quicknet.net>
+ *                  Mike Preston, <mpreston@quicknet.net>
+ *    
+ * Fixes:           David Huggins-Daines, <dhd@cepstral.com>
+ *                  Fabio Ferrari, <fabio.ferrari@digitro.com.br>
+ *                  Artis Kugevics, <artis@mt.lv>
+ *                  Daniele Bellucci, <bellucda@tiscali.it>
+ *
+ * More information about the hardware related to this driver can be found  
+ * at our website:    http://www.quicknet.net
+ *
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *    
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ ***************************************************************************/
+
+/*
+ * Revision 4.8  2003/07/09 19:39:00  Daniele Bellucci
+ * Audit some copy_*_user and minor cleanup.
+ *
+ * Revision 4.7  2001/08/13 06:19:33  craigs
+ * Added additional changes from Alan Cox and John Anderson for
+ * 2.2 to 2.4 cleanup and bounds checking
+ *
+ * Revision 4.6  2001/08/13 01:05:05  craigs
+ * Really fixed PHONE_QUERY_CODEC problem this time
+ *
+ * Revision 4.5  2001/08/13 00:11:03  craigs
+ * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson
+ *
+ * Revision 4.4  2001/08/07 07:58:12  craigs
+ * Changed back to three digit version numbers
+ * Added tagbuild target to allow automatic and easy tagging of versions
+ *
+ * Revision 4.3  2001/08/07 07:24:47  craigs
+ * Added ixj-ver.h to allow easy configuration management of driver
+ * Added display of version number in /prox/ixj
+ *
+ * Revision 4.2  2001/08/06 07:07:19  craigs
+ * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original
+ * behaviour of returning int rather than short *
+ *
+ * Revision 4.1  2001/08/05 00:17:37  craigs
+ * More changes for correct PCMCIA installation
+ * Start of changes for backward Linux compatibility
+ *
+ * Revision 4.0  2001/08/04 12:33:12  craigs
+ * New version using GNU autoconf
+ *
+ * Revision 3.105  2001/07/20 23:14:32  eokerson
+ * More work on CallerID generation when using ring cadences.
+ *
+ * Revision 3.104  2001/07/06 01:33:55  eokerson
+ * Some bugfixes from Robert Vojta <vojta@ipex.cz> and a few mods to the Makefile.
+ *
+ * Revision 3.103  2001/07/05 19:20:16  eokerson
+ * Updated HOWTO
+ * Changed mic gain to 30dB on Internet LineJACK mic/speaker port.
+ *
+ * Revision 3.102  2001/07/03 23:51:21  eokerson
+ * Un-mute mic on Internet LineJACK when in speakerphone mode.
+ *
+ * Revision 3.101  2001/07/02 19:26:56  eokerson
+ * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data
+ *
+ * Revision 3.100  2001/07/02 19:18:27  eokerson
+ * Changed driver to make dynamic allocation possible.  We now pass IXJ * between functions instead of array indexes.
+ * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering.
+ * Fixed speaker mode on Internet LineJACK.
+ *
+ * Revision 3.99  2001/05/09 14:11:16  eokerson
+ * Fixed kmalloc error in ixj_build_filter_cadence.  Thanks David Chan <cat@waulogy.stanford.edu>.
+ *
+ * Revision 3.98  2001/05/08 19:55:33  eokerson
+ * Fixed POTS hookstate detection while it is connected to PSTN port.
+ *
+ * Revision 3.97  2001/05/08 00:01:04  eokerson
+ * Fixed kernel oops when sending caller ID data.
+ *
+ * Revision 3.96  2001/05/04 23:09:30  eokerson
+ * Now uses one kernel timer for each card, instead of one for the entire driver.
+ *
+ * Revision 3.95  2001/04/25 22:06:47  eokerson
+ * Fixed squawking at beginning of some G.723.1 calls.
+ *
+ * Revision 3.94  2001/04/03 23:42:00  eokerson
+ * Added linear volume ioctls
+ * Added raw filter load ioctl
+ *
+ * Revision 3.93  2001/02/27 01:00:06  eokerson
+ * Fixed blocking in CallerID.
+ * Reduced size of ixj structure for smaller driver footprint.
+ *
+ * Revision 3.92  2001/02/20 22:02:59  eokerson
+ * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels.
+ * Improved PSTN ring detection.
+ * Fixed wink generation on POTS ports.
+ *
+ * Revision 3.91  2001/02/13 00:55:44  eokerson
+ * Turn AEC back on after changing frame sizes.
+ *
+ * Revision 3.90  2001/02/12 16:42:00  eokerson
+ * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW.
+ *
+ * Revision 3.89  2001/02/12 15:41:16  eokerson
+ * Fix from Artis Kugevics - Tone gains were not being set correctly.
+ *
+ * Revision 3.88  2001/02/05 23:25:42  eokerson
+ * Fixed lockup bugs with deregister.
+ *
+ * Revision 3.87  2001/01/29 21:00:39  eokerson
+ * Fix from Fabio Ferrari <fabio.ferrari@digitro.com.br> to properly handle EAGAIN and EINTR during non-blocking write.
+ * Updated copyright date.
+ *
+ * Revision 3.86  2001/01/23 23:53:46  eokerson
+ * Fixes to G.729 compatibility.
+ *
+ * Revision 3.85  2001/01/23 21:30:36  eokerson
+ * Added verbage about cards supported.
+ * Removed commands that put the card in low power mode at some times that it should not be in low power mode.
+ *
+ * Revision 3.84  2001/01/22 23:32:10  eokerson
+ * Some bugfixes from David Huggins-Daines, <dhd@cepstral.com> and other cleanups.
+ *
+ * Revision 3.83  2001/01/19 14:51:41  eokerson
+ * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails.
+ *
+ * Revision 3.82  2001/01/19 00:34:49  eokerson
+ * Added verbosity to write overlap errors.
+ *
+ * Revision 3.81  2001/01/18 23:56:54  eokerson
+ * Fixed PSTN line test functions.
+ *
+ * Revision 3.80  2001/01/18 22:29:27  eokerson
+ * Updated AEC/AGC values for different cards.
+ *
+ * Revision 3.79  2001/01/17 02:58:54  eokerson
+ * Fixed AEC reset after Caller ID.
+ * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames.
+ *
+ * Revision 3.78  2001/01/16 19:43:09  eokerson
+ * Added support for Linux 2.4.x kernels.
+ *
+ * Revision 3.77  2001/01/09 04:00:52  eokerson
+ * Linetest will now test the line, even if it has previously succeeded.
+ *
+ * Revision 3.76  2001/01/08 19:27:00  eokerson
+ * Fixed problem with standard cable on Internet PhoneCARD.
+ *
+ * Revision 3.75  2000/12/22 16:52:14  eokerson
+ * Modified to allow hookstate detection on the POTS port when the PSTN port is selected.
+ *
+ * Revision 3.74  2000/12/08 22:41:50  eokerson
+ * Added capability for G729B.
+ *
+ * Revision 3.73  2000/12/07 23:35:16  eokerson
+ * Added capability to have different ring pattern before CallerID data.
+ * Added hookstate checks in CallerID routines to stop FSK.
+ *
+ * Revision 3.72  2000/12/06 19:31:31  eokerson
+ * Modified signal behavior to only send one signal per event.
+ *
+ * Revision 3.71  2000/12/06 03:23:08  eokerson
+ * Fixed CallerID on Call Waiting.
+ *
+ * Revision 3.70  2000/12/04 21:29:37  eokerson
+ * Added checking to Smart Cable gain functions.
+ *
+ * Revision 3.69  2000/12/04 21:05:20  eokerson
+ * Changed ixjdebug levels.
+ * Added ioctls to change gains in Internet Phone CARD Smart Cable.
+ *
+ * Revision 3.68  2000/12/04 00:17:21  craigs
+ * Changed mixer voice gain to +6dB rather than 0dB
+ *
+ * Revision 3.67  2000/11/30 21:25:51  eokerson
+ * Fixed write signal errors.
+ *
+ * Revision 3.66  2000/11/29 22:42:44  eokerson
+ * Fixed PSTN ring detect problems.
+ *
+ * Revision 3.65  2000/11/29 07:31:55  craigs
+ * Added new 425Hz filter co-efficients
+ * Added card-specific DTMF prescaler initialisation
+ *
+ * Revision 3.64  2000/11/28 14:03:32  craigs
+ * Changed certain mixer initialisations to be 0dB rather than 12dB
+ * Added additional information to /proc/ixj
+ *
+ * Revision 3.63  2000/11/28 11:38:41  craigs
+ * Added display of AEC modes in AUTO and AGC mode
+ *
+ * Revision 3.62  2000/11/28 04:05:44  eokerson
+ * Improved PSTN ring detection routine.
+ *
+ * Revision 3.61  2000/11/27 21:53:12  eokerson
+ * Fixed flash detection.
+ *
+ * Revision 3.60  2000/11/27 15:57:29  eokerson
+ * More work on G.729 load routines.
+ *
+ * Revision 3.59  2000/11/25 21:55:12  eokerson
+ * Fixed errors in G.729 load routine.
+ *
+ * Revision 3.58  2000/11/25 04:08:29  eokerson
+ * Added board locks around G.729 and TS85 load routines.
+ *
+ * Revision 3.57  2000/11/24 05:35:17  craigs
+ * Added ability to retrieve mixer values on LineJACK
+ * Added complete initialisation of all mixer values at startup
+ * Fixed spelling mistake
+ *
+ * Revision 3.56  2000/11/23 02:52:11  robertj
+ * Added cvs change log keyword.
+ * Fixed bug in capabilities list when using G.729 module.
+ *
+ */
+
+#include "ixj-ver.h"
+
+#define PERFMON_STATS
+#define IXJDEBUG 0
+#define MAXRINGS 5
+
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>	/* printk() */
+#include <linux/fs.h>		/* everything... */
+#include <linux/errno.h>	/* error codes */
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/poll.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <linux/isapnp.h>
+
+#include "ixj.h"
+
+#define TYPE(inode) (iminor(inode) >> 4)
+#define NUM(inode) (iminor(inode) & 0xf)
+
+static DEFINE_MUTEX(ixj_mutex);
+static int ixjdebug;
+static int hertz = HZ;
+static int samplerate = 100;
+
+module_param(ixjdebug, int, 0);
+
+static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = {
+	{ PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, ixj_pci_tbl);
+
+/************************************************************************
+*
+* ixjdebug meanings are now bit mapped instead of level based
+* Values can be or'ed together to turn on multiple messages
+*
+* bit  0 (0x0001) = any failure
+* bit  1 (0x0002) = general messages
+* bit  2 (0x0004) = POTS ringing related
+* bit  3 (0x0008) = PSTN events
+* bit  4 (0x0010) = PSTN Cadence state details
+* bit  5 (0x0020) = Tone detection triggers
+* bit  6 (0x0040) = Tone detection cadence details
+* bit  7 (0x0080) = ioctl tracking
+* bit  8 (0x0100) = signal tracking
+* bit  9 (0x0200) = CallerID generation details
+*
+************************************************************************/
+
+#ifdef IXJ_DYN_ALLOC
+
+static IXJ *ixj[IXJMAX];
+#define	get_ixj(b)	ixj[(b)]
+
+/*
+ *	Allocate a free IXJ device
+ */
+ 
+static IXJ *ixj_alloc()
+{
+	for(cnt=0; cnt<IXJMAX; cnt++)
+	{
+		if(ixj[cnt] == NULL || !ixj[cnt]->DSPbase)
+		{
+			j = kmalloc(sizeof(IXJ), GFP_KERNEL);
+			if (j == NULL)
+				return NULL;
+			ixj[cnt] = j;
+			return j;
+		}
+	}
+	return NULL;
+}
+
+static void ixj_fsk_free(IXJ *j)
+{
+	kfree(j->fskdata);
+	j->fskdata = NULL;
+}
+
+static void ixj_fsk_alloc(IXJ *j)
+{
+	if(!j->fskdata) {
+		j->fskdata = kmalloc(8000, GFP_KERNEL);
+		if (!j->fskdata) {
+			if(ixjdebug & 0x0200) {
+				printk("IXJ phone%d - allocate failed\n", j->board);
+			}
+			return;
+		} else {
+			j->fsksize = 8000;
+			if(ixjdebug & 0x0200) {
+				printk("IXJ phone%d - allocate succeeded\n", j->board);
+			}
+		}
+	}
+}
+
+#else
+
+static IXJ ixj[IXJMAX];
+#define	get_ixj(b)	(&ixj[(b)])
+
+/*
+ *	Allocate a free IXJ device
+ */
+ 
+static IXJ *ixj_alloc(void)
+{
+	int cnt;
+	for(cnt=0; cnt<IXJMAX; cnt++) {
+		if(!ixj[cnt].DSPbase)
+			return &ixj[cnt];
+	}
+	return NULL;
+}
+
+static inline void ixj_fsk_free(IXJ *j) {;}
+
+static inline void ixj_fsk_alloc(IXJ *j)
+{
+	j->fsksize = 8000;
+}
+
+#endif
+
+#ifdef PERFMON_STATS
+#define ixj_perfmon(x)	((x)++)
+#else
+#define ixj_perfmon(x)	do { } while(0)
+#endif
+
+static int ixj_convert_loaded;
+
+static int ixj_WriteDSPCommand(unsigned short, IXJ *j);
+
+/************************************************************************
+*
+* These are function definitions to allow external modules to register
+* enhanced functionality call backs.
+*
+************************************************************************/
+
+static int Stub(IXJ * J, unsigned long arg)
+{
+	return 0;
+}
+
+static IXJ_REGFUNC ixj_PreRead = &Stub;
+static IXJ_REGFUNC ixj_PostRead = &Stub;
+static IXJ_REGFUNC ixj_PreWrite = &Stub;
+static IXJ_REGFUNC ixj_PostWrite = &Stub;
+
+static void ixj_read_frame(IXJ *j);
+static void ixj_write_frame(IXJ *j);
+static void ixj_init_timer(IXJ *j);
+static void ixj_add_timer(IXJ *	j);
+static void ixj_timeout(unsigned long ptr);
+static int read_filters(IXJ *j);
+static int LineMonitor(IXJ *j);
+static int ixj_fasync(int fd, struct file *, int mode);
+static int ixj_set_port(IXJ *j, int arg);
+static int ixj_set_pots(IXJ *j, int arg);
+static int ixj_hookstate(IXJ *j);
+static int ixj_record_start(IXJ *j);
+static void ixj_record_stop(IXJ *j);
+static void set_rec_volume(IXJ *j, int volume);
+static int get_rec_volume(IXJ *j);
+static int set_rec_codec(IXJ *j, int rate);
+static void ixj_vad(IXJ *j, int arg);
+static int ixj_play_start(IXJ *j);
+static void ixj_play_stop(IXJ *j);
+static int ixj_set_tone_on(unsigned short arg, IXJ *j);
+static int ixj_set_tone_off(unsigned short, IXJ *j);
+static int ixj_play_tone(IXJ *j, char tone);
+static void ixj_aec_start(IXJ *j, int level);
+static int idle(IXJ *j);
+static void ixj_ring_on(IXJ *j);
+static void ixj_ring_off(IXJ *j);
+static void aec_stop(IXJ *j);
+static void ixj_ringback(IXJ *j);
+static void ixj_busytone(IXJ *j);
+static void ixj_dialtone(IXJ *j);
+static void ixj_cpt_stop(IXJ *j);
+static char daa_int_read(IXJ *j);
+static char daa_CR_read(IXJ *j, int cr);
+static int daa_set_mode(IXJ *j, int mode);
+static int ixj_linetest(IXJ *j);
+static int ixj_daa_write(IXJ *j);
+static int ixj_daa_cid_read(IXJ *j);
+static void DAA_Coeff_US(IXJ *j);
+static void DAA_Coeff_UK(IXJ *j);
+static void DAA_Coeff_France(IXJ *j);
+static void DAA_Coeff_Germany(IXJ *j);
+static void DAA_Coeff_Australia(IXJ *j);
+static void DAA_Coeff_Japan(IXJ *j);
+static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
+static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp);
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp);
+/* Serial Control Interface funtions */
+static int SCI_Control(IXJ *j, int control);
+static int SCI_Prepare(IXJ *j);
+static int SCI_WaitHighSCI(IXJ *j);
+static int SCI_WaitLowSCI(IXJ *j);
+static DWORD PCIEE_GetSerialNumber(WORD wAddress);
+static int ixj_PCcontrol_wait(IXJ *j);
+static void ixj_pre_cid(IXJ *j);
+static void ixj_write_cid(IXJ *j);
+static void ixj_write_cid_bit(IXJ *j, int bit);
+static int set_base_frame(IXJ *j, int size);
+static int set_play_codec(IXJ *j, int rate);
+static void set_rec_depth(IXJ *j, int depth);
+static int ixj_mixer(long val, IXJ *j);
+
+/************************************************************************
+CT8020/CT8021 Host Programmers Model
+Host address	Function					Access
+DSPbase +
+0-1		Aux Software Status Register (reserved)		Read Only
+2-3		Software Status Register			Read Only
+4-5		Aux Software Control Register (reserved)	Read Write
+6-7		Software Control Register			Read Write
+8-9		Hardware Status Register			Read Only
+A-B		Hardware Control Register			Read Write
+C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
+E-F Host Receive (Read) Data Buffer Access Port (buffer input)	Read Only
+************************************************************************/
+
+static inline void ixj_read_HSR(IXJ *j)
+{
+	j->hsr.bytes.low = inb_p(j->DSPbase + 8);
+	j->hsr.bytes.high = inb_p(j->DSPbase + 9);
+}
+
+static inline int IsControlReady(IXJ *j)
+{
+	ixj_read_HSR(j);
+	return j->hsr.bits.controlrdy ? 1 : 0;
+}
+
+static inline int IsPCControlReady(IXJ *j)
+{
+	j->pccr1.byte = inb_p(j->XILINXbase + 3);
+	return j->pccr1.bits.crr ? 1 : 0;
+}
+
+static inline int IsStatusReady(IXJ *j)
+{
+	ixj_read_HSR(j);
+	return j->hsr.bits.statusrdy ? 1 : 0;
+}
+
+static inline int IsRxReady(IXJ *j)
+{
+	ixj_read_HSR(j);
+	ixj_perfmon(j->rxreadycheck);
+	return j->hsr.bits.rxrdy ? 1 : 0;
+}
+
+static inline int IsTxReady(IXJ *j)
+{
+	ixj_read_HSR(j);
+	ixj_perfmon(j->txreadycheck);
+	return j->hsr.bits.txrdy ? 1 : 0;
+}
+
+static inline void set_play_volume(IXJ *j, int volume)
+{
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume);
+	ixj_WriteDSPCommand(0xCF02, j);
+	ixj_WriteDSPCommand(volume, j);
+}
+
+static int set_play_volume_linear(IXJ *j, int volume)
+{
+	int newvolume, dspplaymax;
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume);
+	if(volume > 100 || volume < 0) {
+		return -1;
+	}
+
+	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dspplaymax = 0x380;
+		break;
+	case QTI_LINEJACK:
+		if(j->port == PORT_PSTN) {
+			dspplaymax = 0x48;
+		} else {
+			dspplaymax = 0x100;
+		}
+		break;
+	case QTI_PHONEJACK_LITE:
+		dspplaymax = 0x380;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dspplaymax = 0x6C;
+		break;
+	case QTI_PHONECARD:
+		dspplaymax = 0x50;
+		break;
+	default:
+		return -1;
+	}
+	newvolume = (dspplaymax * volume) / 100;
+	set_play_volume(j, newvolume);
+	return 0;
+}
+
+static inline void set_play_depth(IXJ *j, int depth)
+{
+	if (depth > 60)
+		depth = 60;
+	if (depth < 0)
+		depth = 0;
+	ixj_WriteDSPCommand(0x5280 + depth, j);
+}
+
+static inline int get_play_volume(IXJ *j)
+{
+	ixj_WriteDSPCommand(0xCF00, j);
+	return j->ssr.high << 8 | j->ssr.low;
+}
+
+static int get_play_volume_linear(IXJ *j)
+{
+	int volume, newvolume, dspplaymax;
+
+	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dspplaymax = 0x380;
+		break;
+	case QTI_LINEJACK:
+		if(j->port == PORT_PSTN) {
+			dspplaymax = 0x48;
+		} else {
+			dspplaymax = 0x100;
+		}
+		break;
+	case QTI_PHONEJACK_LITE:
+		dspplaymax = 0x380;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dspplaymax = 0x6C;
+		break;
+	case QTI_PHONECARD:
+		dspplaymax = 100;
+		break;
+	default:
+		return -1;
+	}
+	volume = get_play_volume(j);
+	newvolume = (volume * 100) / dspplaymax;
+	if(newvolume > 100)
+		newvolume = 100;
+	return newvolume;
+}
+
+static inline BYTE SLIC_GetState(IXJ *j)
+{
+	if (j->cardtype == QTI_PHONECARD) {
+		j->pccr1.byte = 0;
+		j->psccr.bits.dev = 3;
+		j->psccr.bits.rw = 1;
+		outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
+		ixj_PCcontrol_wait(j);
+		j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
+		ixj_PCcontrol_wait(j);
+		if (j->pslic.bits.powerdown)
+			return PLD_SLIC_STATE_OC;
+		else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)
+			return PLD_SLIC_STATE_ACTIVE;
+		else
+			return PLD_SLIC_STATE_RINGING;
+	} else {
+		j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
+	}
+	return j->pld_slicr.bits.state;
+}
+
+static bool SLIC_SetState(BYTE byState, IXJ *j)
+{
+	bool fRetVal = false;
+
+	if (j->cardtype == QTI_PHONECARD) {
+		if (j->flags.pcmciasct) {
+			switch (byState) {
+			case PLD_SLIC_STATE_TIPOPEN:
+			case PLD_SLIC_STATE_OC:
+				j->pslic.bits.powerdown = 1;
+				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
+				fRetVal = true;
+				break;
+			case PLD_SLIC_STATE_RINGING:
+				if (j->readers || j->writers) {
+					j->pslic.bits.powerdown = 0;
+					j->pslic.bits.ring0 = 1;
+					j->pslic.bits.ring1 = 0;
+					fRetVal = true;
+				}
+				break;
+			case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
+
+			case PLD_SLIC_STATE_STANDBY:
+			case PLD_SLIC_STATE_ACTIVE:
+				if (j->readers || j->writers) {
+					j->pslic.bits.powerdown = 0;
+				} else {
+					j->pslic.bits.powerdown = 1;
+				}
+				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
+				fRetVal = true;
+				break;
+			case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
+
+			case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
+
+			default:
+				fRetVal = false;
+				break;
+			}
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 0;
+			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+			ixj_PCcontrol_wait(j);
+		}
+	} else {
+		/* Set the C1, C2, C3 & B2EN signals. */
+		switch (byState) {
+		case PLD_SLIC_STATE_OC:
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_RINGING:
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 1;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_ACTIVE:
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
+
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_TIPOPEN:
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_STANDBY:
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 1;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
+
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
+
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = true;
+			break;
+		default:
+			fRetVal = false;
+			break;
+		}
+	}
+
+	return fRetVal;
+}
+
+static int ixj_wink(IXJ *j)
+{
+	BYTE slicnow;
+
+	slicnow = SLIC_GetState(j);
+
+	j->pots_winkstart = jiffies;
+	SLIC_SetState(PLD_SLIC_STATE_OC, j);
+
+	msleep(jiffies_to_msecs(j->winktime));
+
+	SLIC_SetState(slicnow, j);
+	return 0;
+}
+
+static void ixj_init_timer(IXJ *j)
+{
+	init_timer(&j->timer);
+	j->timer.function = ixj_timeout;
+	j->timer.data = (unsigned long)j;
+}
+
+static void ixj_add_timer(IXJ *j)
+{
+	j->timer.expires = jiffies + (hertz / samplerate);
+	add_timer(&j->timer);
+}
+
+static void ixj_tone_timeout(IXJ *j)
+{
+	IXJ_TONE ti;
+
+	j->tone_state++;
+	if (j->tone_state == 3) {
+		j->tone_state = 0;
+		if (j->cadence_t) {
+			j->tone_cadence_state++;
+			if (j->tone_cadence_state >= j->cadence_t->elements_used) {
+				switch (j->cadence_t->termination) {
+				case PLAY_ONCE:
+					ixj_cpt_stop(j);
+					break;
+				case REPEAT_LAST_ELEMENT:
+					j->tone_cadence_state--;
+					ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
+					break;
+				case REPEAT_ALL:
+					j->tone_cadence_state = 0;
+					if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
+						ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
+						ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
+						ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
+						ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
+						ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
+						ixj_init_tone(j, &ti);
+					}
+					ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j);
+					ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j);
+					ixj_play_tone(j, j->cadence_t->ce[0].index);
+					break;
+				}
+			} else {
+				if (j->cadence_t->ce[j->tone_cadence_state].gain0) {
+					ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
+					ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
+					ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
+					ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
+					ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
+					ixj_init_tone(j, &ti);
+				}
+				ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j);
+				ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j);
+				ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
+			}
+		}
+	}
+}
+
+static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir)
+{
+	if(j->ixj_signals[event]) {
+		if(ixjdebug & 0x0100)
+			printk("Sending signal for event %d\n", event);
+			/* Send apps notice of change */
+		/* see config.h for macro definition */
+		kill_fasync(&(j->async_queue), j->ixj_signals[event], dir);
+	}
+}
+
+static void ixj_pstn_state(IXJ *j)
+{
+	int var;
+	union XOPXR0 XR0, daaint;
+
+	var = 10;
+
+	XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg;
+	daaint.reg = 0;
+	XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
+
+	j->pld_scrr.byte = inb_p(j->XILINXbase);
+	if (j->pld_scrr.bits.daaflag) {
+		daa_int_read(j);
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
+			if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+				daaint.bitreg.RING = 1;
+				if(ixjdebug & 0x0008) {
+					printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+				}
+			} else {
+				daa_set_mode(j, SOP_PU_RESET);
+			}
+		}
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
+			daaint.bitreg.Caller_ID = 1;
+			j->pstn_cid_intr = 1;
+			j->pstn_cid_received = jiffies;
+			if(ixjdebug & 0x0008) {
+				printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+			}
+		}
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
+			daaint.bitreg.Cadence = 1;
+			if(ixjdebug & 0x0008) {
+				printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+			}
+		}
+		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) {
+			daaint.bitreg.VDD_OK = 1;
+			daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK;
+		}
+	}
+	daa_CR_read(j, 1);
+	if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+		daaint.bitreg.RMR = 1;
+		daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
+		if(ixjdebug & 0x0008) {
+                        printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr);
+		}
+		j->pstn_prev_rmr = j->pstn_last_rmr;
+		j->pstn_last_rmr = jiffies;
+	}
+	switch(j->daa_mode) {
+		case SOP_PU_SLEEP:
+			if (daaint.bitreg.RING) {
+				if (!j->flags.pstn_ringing) {
+					if (j->daa_mode != SOP_PU_RINGING) {
+						j->pstn_ring_int = jiffies;
+						daa_set_mode(j, SOP_PU_RINGING);
+					}
+				}
+			}
+			break;
+		case SOP_PU_RINGING:
+			if (daaint.bitreg.RMR) {
+				if (ixjdebug & 0x0008) {
+					printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+				}
+				if (daaint.bitreg.SI_1) {                /* Rising edge of RMR */
+					j->flags.pstn_rmr = 1;
+					j->pstn_ring_start = jiffies;
+					j->pstn_ring_stop = 0;
+					j->ex.bits.pstn_ring = 0;
+					if (j->cadence_f[4].state == 0) {
+						j->cadence_f[4].state = 1;
+						j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000);
+						j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000);
+						j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000);
+					} else if (j->cadence_f[4].state == 2) {
+						if((time_after(jiffies, j->cadence_f[4].off1min) &&
+						    time_before(jiffies, j->cadence_f[4].off1max))) {
+							if (j->cadence_f[4].on2) {
+								j->cadence_f[4].state = 3;
+								j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000));
+								j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].off1);
+							}
+							j->cadence_f[4].state = 0;
+						}
+					} else if (j->cadence_f[4].state == 4) {
+						if((time_after(jiffies, j->cadence_f[4].off2min) &&
+						    time_before(jiffies, j->cadence_f[4].off2max))) {
+							if (j->cadence_f[4].on3) {
+								j->cadence_f[4].state = 5;
+								j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000));
+								j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].off2);
+							}
+							j->cadence_f[4].state = 0;
+						}
+					} else if (j->cadence_f[4].state == 6) {
+						if((time_after(jiffies, j->cadence_f[4].off3min) &&
+						    time_before(jiffies, j->cadence_f[4].off3max))) {
+							j->cadence_f[4].state = 7;
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].off3);
+							}
+							j->cadence_f[4].state = 0;
+						}
+					} else {
+						j->cadence_f[4].state = 0;
+					}
+				} else {                                /* Falling edge of RMR */
+					j->pstn_ring_start = 0;
+					j->pstn_ring_stop = jiffies;
+					if (j->cadence_f[4].state == 1) {
+						if(!j->cadence_f[4].on1) {
+							j->cadence_f[4].state = 7;
+						} else if((time_after(jiffies, j->cadence_f[4].on1min) &&
+					          time_before(jiffies, j->cadence_f[4].on1max))) {
+							if (j->cadence_f[4].off1) {
+								j->cadence_f[4].state = 2;
+								j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000));
+								j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].on1);
+							}
+							j->cadence_f[4].state = 0;
+						}
+					} else if (j->cadence_f[4].state == 3) {
+						if((time_after(jiffies, j->cadence_f[4].on2min) &&
+						    time_before(jiffies, j->cadence_f[4].on2max))) {
+							if (j->cadence_f[4].off2) {
+								j->cadence_f[4].state = 4;
+								j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000));
+								j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							if (ixjdebug & 0x0008) {
+								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+										j->cadence_f[4].on2);
+							}
+							j->cadence_f[4].state = 0;
+						}
+					} else if (j->cadence_f[4].state == 5) {
+						if((time_after(jiffies, j->cadence_f[4].on3min) &&
+						    time_before(jiffies, j->cadence_f[4].on3max))) {
+							if (j->cadence_f[4].off3) {
+								j->cadence_f[4].state = 6;
+								j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000));
+								j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000));
+								j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000));
+							} else {
+								j->cadence_f[4].state = 7;
+							}
+						} else {
+							j->cadence_f[4].state = 0;
+						}
+					} else {
+						if (ixjdebug & 0x0008) {
+							printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+									j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+									j->cadence_f[4].on3);
+						}
+						j->cadence_f[4].state = 0;
+					}
+				}
+				if (ixjdebug & 0x0010) {
+					printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+				}
+				if (ixjdebug & 0x0010) {
+					switch(j->cadence_f[4].state) {
+						case 1:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max);
+							break;
+						case 2:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max);
+							break;
+						case 3:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max);
+							break;
+						case 4:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max);
+							break;
+						case 5:
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max);
+							break;
+						case 6:	
+							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+						j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max);
+							break;
+					}
+				}
+			}
+			if (j->cadence_f[4].state == 7) {
+				j->cadence_f[4].state = 0;
+				j->pstn_ring_stop = jiffies;
+				j->ex.bits.pstn_ring = 1;
+				ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN);
+				if(ixjdebug & 0x0008) {
+					printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies);
+				}
+			}
+			if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) ||
+			   (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) {
+				if(ixjdebug & 0x0008) {
+					printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies);
+					printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int);
+					printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop);
+				}
+				j->pstn_ring_stop = j->pstn_ring_int = 0;
+				daa_set_mode(j, SOP_PU_SLEEP);
+			} 
+			outb_p(j->pld_scrw.byte, j->XILINXbase);
+			if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) {
+				ixj_daa_cid_read(j);
+				j->ex.bits.caller_id = 1;
+				ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN);
+				j->pstn_cid_intr = 0;
+			}
+			if (daaint.bitreg.Cadence) {
+				if(ixjdebug & 0x0008) {
+					printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board);
+				}
+				daa_set_mode(j, SOP_PU_SLEEP);
+				j->ex.bits.pstn_ring = 0;
+			}
+			break;
+		case SOP_PU_CONVERSATION:
+			if (daaint.bitreg.VDD_OK) {
+				if(!daaint.bitreg.SI_0) {
+					if (!j->pstn_winkstart) {
+						if(ixjdebug & 0x0008) {
+							printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies);
+						}
+						j->pstn_winkstart = jiffies;
+					} 
+				} else {
+					if (j->pstn_winkstart) {
+						if(ixjdebug & 0x0008) {
+							printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies);
+						}
+						j->pstn_winkstart = 0;
+					}
+				}
+			}
+			if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) {
+				if(ixjdebug & 0x0008) {
+					printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies);
+				}
+				daa_set_mode(j, SOP_PU_SLEEP);
+				j->pstn_winkstart = 0;
+				j->ex.bits.pstn_wink = 1;
+				ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN);
+			}
+			break;
+	}
+}
+
+static void ixj_timeout(unsigned long ptr)
+{
+	int board;
+	unsigned long jifon;
+	IXJ *j = (IXJ *)ptr;
+	board = j->board;
+
+	if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) {
+		ixj_perfmon(j->timerchecks);
+		j->hookstate = ixj_hookstate(j);
+		if (j->tone_state) {
+			if (!(j->hookstate)) {
+				ixj_cpt_stop(j);
+				if (j->m_hook) {
+					j->m_hook = 0;
+					j->ex.bits.hookstate = 1;
+					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+				}
+				clear_bit(board, &j->busyflags);
+				ixj_add_timer(j);
+				return;
+			}
+			if (j->tone_state == 1)
+				jifon = ((hertz * j->tone_on_time) * 25 / 100000);
+			else
+				jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000);
+			if (time_before(jiffies, j->tone_start_jif + jifon)) {
+				if (j->tone_state == 1) {
+					ixj_play_tone(j, j->tone_index);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
+					}
+				} else {
+					ixj_play_tone(j, 0);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
+					}
+				}
+			} else {
+				ixj_tone_timeout(j);
+				if (j->flags.dialtone) {
+					ixj_dialtone(j);
+				}
+				if (j->flags.busytone) {
+					ixj_busytone(j);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
+					}
+				}
+				if (j->flags.ringback) {
+					ixj_ringback(j);
+					if (j->dsp.low == 0x20) {
+						clear_bit(board, &j->busyflags);
+						ixj_add_timer(j);
+						return;
+					}
+				}
+				if (!j->tone_state) {
+					ixj_cpt_stop(j);
+				}
+			}
+		}
+		if (!(j->tone_state && j->dsp.low == 0x20)) {
+			if (IsRxReady(j)) {
+				ixj_read_frame(j);
+			}
+			if (IsTxReady(j)) {
+				ixj_write_frame(j);
+			}
+		}
+		if (j->flags.cringing) {
+			if (j->hookstate & 1) {
+				j->flags.cringing = 0;
+				ixj_ring_off(j);
+			} else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) {
+				switch(j->cadence_f[5].state) {
+					case 0:
+						j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000));
+						if (time_before(jiffies, j->cadence_f[5].on1dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_on(j);
+						}
+						j->cadence_f[5].state = 1;
+						break;
+					case 1:
+						if (time_after(jiffies, j->cadence_f[5].on1dot)) {
+							j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000));
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_off(j);
+							j->cadence_f[5].state = 2;
+						}
+						break;
+					case 2:
+						if (time_after(jiffies, j->cadence_f[5].off1dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_on(j);
+							if (j->cadence_f[5].on2) {
+								j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 3;
+							} else {
+								j->cadence_f[5].state = 7;
+							}
+						}
+						break;
+					case 3:
+						if (time_after(jiffies, j->cadence_f[5].on2dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_off(j);
+							if (j->cadence_f[5].off2) {
+								j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 4;
+							} else {
+								j->cadence_f[5].state = 7;
+							}
+						}
+						break;
+					case 4:
+						if (time_after(jiffies, j->cadence_f[5].off2dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_on(j);
+							if (j->cadence_f[5].on3) {
+								j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 5;
+							} else {
+								j->cadence_f[5].state = 7;
+							}
+						}
+						break;
+					case 5:
+						if (time_after(jiffies, j->cadence_f[5].on3dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							ixj_ring_off(j);
+							if (j->cadence_f[5].off3) {
+								j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000));
+								j->cadence_f[5].state = 6;
+							} else {
+								j->cadence_f[5].state = 7;
+							}
+						}
+						break;
+					case 6:
+						if (time_after(jiffies, j->cadence_f[5].off3dot)) {
+							if(ixjdebug & 0x0004) {
+								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+							}
+							j->cadence_f[5].state = 7;
+						}
+						break;
+					case 7:
+						if(ixjdebug & 0x0004) {
+							printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+						}
+						j->flags.cidring = 1;
+						j->cadence_f[5].state = 0;
+						break;
+				}
+				if (j->flags.cidring && !j->flags.cidsent) {
+					j->flags.cidsent = 1;
+					if(j->fskdcnt) {
+						SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+						ixj_pre_cid(j);
+					}
+					j->flags.cidring = 0;
+				}
+				clear_bit(board, &j->busyflags);
+				ixj_add_timer(j);
+				return;
+			} else {
+				if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) {
+					if (j->flags.cidring && !j->flags.cidsent) {
+						j->flags.cidsent = 1;
+						if(j->fskdcnt) {
+							SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+							ixj_pre_cid(j);
+						}
+						j->flags.cidring = 0;
+					}
+					j->ring_cadence_t--;
+					if (j->ring_cadence_t == -1)
+						j->ring_cadence_t = 15;
+					j->ring_cadence_jif = jiffies;
+
+					if (j->ring_cadence & 1 << j->ring_cadence_t) {
+						if(j->flags.cidsent && j->cadence_f[5].en_filter)
+							j->flags.firstring = 1;
+						else
+							ixj_ring_on(j);
+					} else {
+						ixj_ring_off(j);
+						if(!j->flags.cidsent)
+							j->flags.cidring = 1;
+					}
+				}
+				clear_bit(board, &j->busyflags);
+				ixj_add_timer(j);
+				return;
+			}
+		}
+		if (!j->flags.ringing) {
+			if (j->hookstate) { /* & 1) { */
+				if (j->dsp.low != 0x20 &&
+				    SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
+					SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
+				}
+				LineMonitor(j);
+				read_filters(j);
+				ixj_WriteDSPCommand(0x511B, j);
+				j->proc_load = j->ssr.high << 8 | j->ssr.low;
+				if (!j->m_hook && (j->hookstate & 1)) {
+					j->m_hook = j->ex.bits.hookstate = 1;
+					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+				}
+			} else {
+				if (j->ex.bits.dtmf_ready) {
+					j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+				}
+				if (j->m_hook) {
+					j->m_hook = 0;
+					j->ex.bits.hookstate = 1;
+					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+				}
+			}
+		}
+		if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) {
+			ixj_pstn_state(j);
+		}
+		if (j->ex.bytes) {
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
+		}
+		clear_bit(board, &j->busyflags);
+	}
+	ixj_add_timer(j);
+}
+
+static int ixj_status_wait(IXJ *j)
+{
+	unsigned long jif;
+
+	jif = jiffies + ((60 * hertz) / 100);
+	while (!IsStatusReady(j)) {
+		ixj_perfmon(j->statuswait);
+		if (time_after(jiffies, jif)) {
+			ixj_perfmon(j->statuswaitfail);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int ixj_PCcontrol_wait(IXJ *j)
+{
+	unsigned long jif;
+
+	jif = jiffies + ((60 * hertz) / 100);
+	while (!IsPCControlReady(j)) {
+		ixj_perfmon(j->pcontrolwait);
+		if (time_after(jiffies, jif)) {
+			ixj_perfmon(j->pcontrolwaitfail);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
+{
+	BYTES bytes;
+	unsigned long jif;
+
+	atomic_inc(&j->DSPWrite);
+	if(atomic_read(&j->DSPWrite) > 1) {
+		printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd);
+		return -1;
+	}
+	bytes.high = (cmd & 0xFF00) >> 8;
+	bytes.low = cmd & 0x00FF;
+	jif = jiffies + ((60 * hertz) / 100);
+	while (!IsControlReady(j)) {
+		ixj_perfmon(j->iscontrolready);
+		if (time_after(jiffies, jif)) {
+			ixj_perfmon(j->iscontrolreadyfail);
+			atomic_dec(&j->DSPWrite);
+			if(atomic_read(&j->DSPWrite) > 0) {
+				printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd);
+				while(atomic_read(&j->DSPWrite) > 0) {
+					atomic_dec(&j->DSPWrite);
+				}
+			}
+			return -1;
+		}
+	}
+	outb(bytes.low, j->DSPbase + 6);
+	outb(bytes.high, j->DSPbase + 7);
+
+	if (ixj_status_wait(j)) {
+		j->ssr.low = 0xFF;
+		j->ssr.high = 0xFF;
+		atomic_dec(&j->DSPWrite);
+		if(atomic_read(&j->DSPWrite) > 0) {
+			printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd);
+			while(atomic_read(&j->DSPWrite) > 0) {
+				atomic_dec(&j->DSPWrite);
+			}
+		}
+		return -1;
+	}
+/* Read Software Status Register */
+	j->ssr.low = inb_p(j->DSPbase + 2);
+	j->ssr.high = inb_p(j->DSPbase + 3);
+	atomic_dec(&j->DSPWrite);
+	if(atomic_read(&j->DSPWrite) > 0) {
+		printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd);
+		while(atomic_read(&j->DSPWrite) > 0) {
+			atomic_dec(&j->DSPWrite);
+		}
+	}
+	return 0;
+}
+
+/***************************************************************************
+*
+*  General Purpose IO Register read routine
+*
+***************************************************************************/
+static inline int ixj_gpio_read(IXJ *j)
+{
+	if (ixj_WriteDSPCommand(0x5143, j))
+		return -1;
+
+	j->gpio.bytes.low = j->ssr.low;
+	j->gpio.bytes.high = j->ssr.high;
+
+	return 0;
+}
+
+static inline void LED_SetState(int state, IXJ *j)
+{
+	if (j->cardtype == QTI_LINEJACK) {
+		j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
+		j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
+		j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
+		j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
+
+		outb(j->pld_scrw.byte, j->XILINXbase);
+	}
+}
+
+/*********************************************************************
+*  GPIO Pins are configured as follows on the Quicknet Internet
+*  PhoneJACK Telephony Cards
+* 
+* POTS Select        GPIO_6=0 GPIO_7=0
+* Mic/Speaker Select GPIO_6=0 GPIO_7=1
+* Handset Select     GPIO_6=1 GPIO_7=0
+*
+* SLIC Active        GPIO_1=0 GPIO_2=1 GPIO_5=0
+* SLIC Ringing       GPIO_1=1 GPIO_2=1 GPIO_5=0
+* SLIC Open Circuit  GPIO_1=0 GPIO_2=0 GPIO_5=0
+*
+* Hook Switch changes reported on GPIO_3
+*********************************************************************/
+static int ixj_set_port(IXJ *j, int arg)
+{
+	if (j->cardtype == QTI_PHONEJACK_LITE) {
+		if (arg != PORT_POTS)
+			return 10;
+		else
+			return 0;
+	}
+	switch (arg) {
+	case PORT_POTS:
+		j->port = PORT_POTS;
+		switch (j->cardtype) {
+		case QTI_PHONECARD:
+			if (j->flags.pcmciasct == 1)
+				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
+			else
+				return 11;
+			break;
+		case QTI_PHONEJACK_PCI:
+			j->pld_slicw.pcib.mic = 0;
+			j->pld_slicw.pcib.spk = 0;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			break;
+		case QTI_LINEJACK:
+			ixj_set_pots(j, 0);			/* Disconnect POTS/PSTN relay */
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
+									   Software Control Register */
+				return 2;
+			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+			outb(j->pld_scrw.byte, j->XILINXbase);
+			j->pld_clock.byte = 0;
+			outb(j->pld_clock.byte, j->XILINXbase + 0x04);
+			j->pld_slicw.bits.rly1 = 1;
+			j->pld_slicw.bits.spken = 0;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			ixj_mixer(0x1200, j);	/* Turn Off MIC switch on mixer left */
+			ixj_mixer(0x1401, j);	/* Turn On Mono1 switch on mixer left */
+			ixj_mixer(0x1300, j);       /* Turn Off MIC switch on mixer right */
+			ixj_mixer(0x1501, j);       /* Turn On Mono1 switch on mixer right */
+			ixj_mixer(0x0E80, j);	/*Mic mute */
+			ixj_mixer(0x0F00, j);	/* Set mono out (SLIC) to 0dB */
+			ixj_mixer(0x0080, j);	/* Mute Master Left volume */
+			ixj_mixer(0x0180, j);	/* Mute Master Right volume */
+			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*			SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
+			break;
+		case QTI_PHONEJACK:
+			j->gpio.bytes.high = 0x0B;
+			j->gpio.bits.gpio6 = 0;
+			j->gpio.bits.gpio7 = 0;
+			ixj_WriteDSPCommand(j->gpio.word, j);
+			break;
+		}
+		break;
+	case PORT_PSTN:
+		if (j->cardtype == QTI_LINEJACK) {
+			ixj_WriteDSPCommand(0xC534, j);	/* Write CODEC config to Software Control Register */
+
+			j->pld_slicw.bits.rly3 = 0;
+			j->pld_slicw.bits.rly1 = 1;
+			j->pld_slicw.bits.spken = 0;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			j->port = PORT_PSTN;
+		} else {
+			return 4;
+		}
+		break;
+	case PORT_SPEAKER:
+		j->port = PORT_SPEAKER;
+		switch (j->cardtype) {
+		case QTI_PHONECARD:
+			if (j->flags.pcmciasct) {
+				SLIC_SetState(PLD_SLIC_STATE_OC, j);
+			}
+			break;
+		case QTI_PHONEJACK_PCI:
+			j->pld_slicw.pcib.mic = 1;
+			j->pld_slicw.pcib.spk = 1;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			break;
+		case QTI_LINEJACK:
+			ixj_set_pots(j, 0);			/* Disconnect POTS/PSTN relay */
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
+									   Software Control Register */
+				return 2;
+			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+			outb(j->pld_scrw.byte, j->XILINXbase);
+			j->pld_clock.byte = 0;
+			outb(j->pld_clock.byte, j->XILINXbase + 0x04);
+			j->pld_slicw.bits.rly1 = 1;
+			j->pld_slicw.bits.spken = 1;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			ixj_mixer(0x1201, j);	/* Turn On MIC switch on mixer left */
+			ixj_mixer(0x1400, j);	/* Turn Off Mono1 switch on mixer left */
+			ixj_mixer(0x1301, j);       /* Turn On MIC switch on mixer right */
+			ixj_mixer(0x1500, j);       /* Turn Off Mono1 switch on mixer right */
+			ixj_mixer(0x0E06, j);	/*Mic un-mute 0dB */
+			ixj_mixer(0x0F80, j);	/* Mute mono out (SLIC) */
+			ixj_mixer(0x0000, j);	/* Set Master Left volume to 0dB */
+			ixj_mixer(0x0100, j);	/* Set Master Right volume to 0dB */
+			break;
+		case QTI_PHONEJACK:
+			j->gpio.bytes.high = 0x0B;
+			j->gpio.bits.gpio6 = 0;
+			j->gpio.bits.gpio7 = 1;
+			ixj_WriteDSPCommand(j->gpio.word, j);
+			break;
+		}
+		break;
+	case PORT_HANDSET:
+		if (j->cardtype != QTI_PHONEJACK) {
+			return 5;
+		} else {
+			j->gpio.bytes.high = 0x0B;
+			j->gpio.bits.gpio6 = 1;
+			j->gpio.bits.gpio7 = 0;
+			ixj_WriteDSPCommand(j->gpio.word, j);
+			j->port = PORT_HANDSET;
+		}
+		break;
+	default:
+		return 6;
+		break;
+	}
+	return 0;
+}
+
+static int ixj_set_pots(IXJ *j, int arg)
+{
+	if (j->cardtype == QTI_LINEJACK) {
+		if (arg) {
+			if (j->port == PORT_PSTN) {
+				j->pld_slicw.bits.rly1 = 0;
+				outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+				j->flags.pots_pstn = 1;
+				return 1;
+			} else {
+				j->flags.pots_pstn = 0;
+				return 0;
+			}
+		} else {
+			j->pld_slicw.bits.rly1 = 1;
+			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			j->flags.pots_pstn = 0;
+			return 1;
+		}
+	} else {
+		return 0;
+	}
+}
+
+static void ixj_ring_on(IXJ *j)
+{
+	if (j->dsp.low == 0x20)	/* Internet PhoneJACK */
+	 {
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", 	j->board);
+
+		j->gpio.bytes.high = 0x0B;
+		j->gpio.bytes.low = 0x00;
+		j->gpio.bits.gpio1 = 1;
+		j->gpio.bits.gpio2 = 1;
+		j->gpio.bits.gpio5 = 0;
+		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring signal */
+	} else			/* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */
+	{
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
+
+		SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
+	}
+}
+
+static int ixj_siadc(IXJ *j, int val)
+{
+	if(j->cardtype == QTI_PHONECARD){
+		if(j->flags.pcmciascp){
+			if(val == -1)
+				return j->siadc.bits.rxg;
+
+			if(val < 0 || val > 0x1F)
+				return -1;
+
+			j->siadc.bits.hom = 0;				/* Handset Out Mute */
+			j->siadc.bits.lom = 0;				/* Line Out Mute */
+			j->siadc.bits.rxg = val;			/*(0xC000 - 0x41C8) / 0x4EF;    RX PGA Gain */
+			j->psccr.bits.addr = 6;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->siadc.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+			return j->siadc.bits.rxg;
+		}
+	}
+	return -1;
+}
+
+static int ixj_sidac(IXJ *j, int val)
+{
+	if(j->cardtype == QTI_PHONECARD){
+		if(j->flags.pcmciascp){
+			if(val == -1)
+				return j->sidac.bits.txg;
+
+			if(val < 0 || val > 0x1F)
+				return -1;
+
+			j->sidac.bits.srm = 1;				/* Speaker Right Mute */
+			j->sidac.bits.slm = 1;				/* Speaker Left Mute */
+			j->sidac.bits.txg = val;			/* (0xC000 - 0x45E4) / 0x5D3;	 TX PGA Gain */
+			j->psccr.bits.addr = 7;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->sidac.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+			return j->sidac.bits.txg;
+		}
+	}
+	return -1;
+}
+
+static int ixj_pcmcia_cable_check(IXJ *j)
+{
+	j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
+	if (!j->flags.pcmciastate) {
+		j->pccr2.byte = inb_p(j->XILINXbase + 0x02);
+		if (j->pccr1.bits.drf || j->pccr2.bits.rstc) {
+			j->flags.pcmciastate = 4;
+			return 0;
+		}
+		if (j->pccr1.bits.ed) {
+			j->pccr1.bits.ed = 0;
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 1;
+			outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
+			ixj_PCcontrol_wait(j);
+			j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
+			j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0;
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 0;
+			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+			ixj_PCcontrol_wait(j);
+			return j->pslic.bits.led2 ? 1 : 0;
+		} else if (j->flags.pcmciasct) {
+			return j->r_hook;
+		} else {
+			return 1;
+		}
+	} else if (j->flags.pcmciastate == 4) {
+		if (!j->pccr1.bits.drf) {
+			j->flags.pcmciastate = 3;
+		}
+		return 0;
+	} else if (j->flags.pcmciastate == 3) {
+		j->pccr2.bits.pwr = 0;
+		j->pccr2.bits.rstc = 1;
+		outb(j->pccr2.byte, j->XILINXbase + 0x02);
+		j->checkwait = jiffies + (hertz * 2);
+		j->flags.incheck = 1;
+		j->flags.pcmciastate = 2;
+		return 0;
+	} else if (j->flags.pcmciastate == 2) {
+		if (j->flags.incheck) {
+			if (time_before(jiffies, j->checkwait)) {
+				return 0;
+			} else {
+				j->flags.incheck = 0;
+			}
+		}
+		j->pccr2.bits.pwr = 0;
+		j->pccr2.bits.rstc = 0;
+		outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+		j->flags.pcmciastate = 1;
+		return 0;
+	} else if (j->flags.pcmciastate == 1) {
+		j->flags.pcmciastate = 0;
+		if (!j->pccr1.bits.drf) {
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 1;
+			outb_p(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+			j->flags.pcmciascp = 1;		/* Set Cable Present Flag */
+
+			j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;		/* Get Cable Type */
+
+			if (j->flags.pcmciasct == 3) {
+				j->flags.pcmciastate = 4;
+				return 0;
+			} else if (j->flags.pcmciasct == 0) {
+				j->pccr2.bits.pwr = 1;
+				j->pccr2.bits.rstc = 0;
+				outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+				j->port = PORT_SPEAKER;
+			} else {
+				j->port = PORT_POTS;
+			}
+			j->sic1.bits.cpd = 0;				/* Chip Power Down */
+			j->sic1.bits.mpd = 0;				/* MIC Bias Power Down */
+			j->sic1.bits.hpd = 0;				/* Handset Bias Power Down */
+			j->sic1.bits.lpd = 0;				/* Line Bias Power Down */
+			j->sic1.bits.spd = 1;				/* Speaker Drive Power Down */
+			j->psccr.bits.addr = 1;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->sic1.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+
+			j->sic2.bits.al = 0;				/* Analog Loopback DAC analog -> ADC analog */
+			j->sic2.bits.dl2 = 0;				/* Digital Loopback DAC -> ADC one bit */
+			j->sic2.bits.dl1 = 0;				/* Digital Loopback ADC -> DAC one bit */
+			j->sic2.bits.pll = 0;				/* 1 = div 10, 0 = div 5 */
+			j->sic2.bits.hpd = 0;				/* HPF disable */
+			j->psccr.bits.addr = 2;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->sic2.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+
+			j->psccr.bits.addr = 3;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(0x00, j->XILINXbase + 0x00);		/* PLL Divide N1 */
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+
+			j->psccr.bits.addr = 4;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(0x09, j->XILINXbase + 0x00);		/* PLL Multiply M1 */
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+
+			j->sirxg.bits.lig = 1;				/* Line In Gain */
+			j->sirxg.bits.lim = 1;				/* Line In Mute */
+			j->sirxg.bits.mcg = 0;				/* MIC In Gain was 3 */
+			j->sirxg.bits.mcm = 0;				/* MIC In Mute */
+			j->sirxg.bits.him = 0;				/* Handset In Mute */
+			j->sirxg.bits.iir = 1;				/* IIR */
+			j->psccr.bits.addr = 5;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->sirxg.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+
+			ixj_siadc(j, 0x17);
+			ixj_sidac(j, 0x1D);
+
+			j->siaatt.bits.sot = 0;
+			j->psccr.bits.addr = 9;				/* R/W Smart Cable Register Address */
+			j->psccr.bits.rw = 0;				/* Read / Write flag */
+			j->psccr.bits.dev = 0;
+			outb(j->siaatt.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(j);
+
+			if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) {
+				j->psccr.byte = j->pslic.byte = 0;
+				j->pslic.bits.powerdown = 1;
+				j->psccr.bits.dev = 3;
+				j->psccr.bits.rw = 0;
+				outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+				ixj_PCcontrol_wait(j);
+			}
+		}
+		return 0;
+	} else {
+		j->flags.pcmciascp = 0;
+		return 0;
+	}
+	return 0;
+}
+
+static int ixj_hookstate(IXJ *j)
+{
+	int fOffHook = 0;
+
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		ixj_gpio_read(j);
+		fOffHook = j->gpio.bits.gpio3read ? 1 : 0;
+		break;
+	case QTI_LINEJACK:
+	case QTI_PHONEJACK_LITE:
+	case QTI_PHONEJACK_PCI:
+		SLIC_GetState(j);
+		if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) {
+			fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0;
+			if(fOffHook != j->p_hook) {
+				if(!j->checkwait) {
+					j->checkwait = jiffies;
+				} 
+				if(time_before(jiffies, j->checkwait + 2)) {
+					fOffHook ^= 1;
+				} else {
+					j->checkwait = 0;
+				}
+				j->p_hook = fOffHook;
+	 			printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies);
+			}
+		} else {
+			if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
+			    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
+				if (j->flags.ringing || j->flags.cringing) {
+					if (!in_interrupt()) {
+						msleep(20);
+					}
+					SLIC_GetState(j);
+					if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
+						ixj_ring_on(j);
+					}
+				}
+				if (j->cardtype == QTI_PHONEJACK_PCI) {
+					j->pld_scrr.byte = inb_p(j->XILINXbase);
+					fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
+				} else
+					fOffHook = j->pld_slicr.bits.det ? 1 : 0;
+			}
+		}
+		break;
+	case QTI_PHONECARD:
+		fOffHook = ixj_pcmcia_cable_check(j);
+		break;
+	}
+	if (j->r_hook != fOffHook) {
+		j->r_hook = fOffHook;
+		if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) {
+			j->ex.bits.hookstate = 1;
+			ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+		} else if (!fOffHook) {
+			j->flash_end = jiffies + ((60 * hertz) / 100);
+		}
+	}
+	if (fOffHook) {
+		if(time_before(jiffies, j->flash_end)) {
+			j->ex.bits.flash = 1;
+			j->flash_end = 0;
+			ixj_kill_fasync(j, SIG_FLASH, POLL_IN);
+		}
+	} else {
+		if(time_before(jiffies, j->flash_end)) {
+			fOffHook = 1;
+		}
+	}
+
+	if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
+		fOffHook |= 2;
+
+	if (j->port == PORT_SPEAKER) {
+		if(j->cardtype == QTI_PHONECARD) {
+			if(j->flags.pcmciascp && j->flags.pcmciasct) {
+				fOffHook |= 2;
+			}
+		} else {
+			fOffHook |= 2;
+		}
+	}
+
+	if (j->port == PORT_HANDSET)
+		fOffHook |= 2;
+
+	return fOffHook;
+}
+
+static void ixj_ring_off(IXJ *j)
+{
+	if (j->dsp.low == 0x20)	/* Internet PhoneJACK */
+	 {
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Ring Off\n");
+		j->gpio.bytes.high = 0x0B;
+		j->gpio.bytes.low = 0x00;
+		j->gpio.bits.gpio1 = 0;
+		j->gpio.bits.gpio2 = 1;
+		j->gpio.bits.gpio5 = 0;
+		ixj_WriteDSPCommand(j->gpio.word, j);
+	} else			/* Internet LineJACK */
+	{
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Ring Off\n");
+
+		if(!j->flags.cidplay)
+			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+
+		SLIC_GetState(j);
+	}
+}
+
+static void ixj_ring_start(IXJ *j)
+{
+	j->flags.cringing = 1;
+	if (ixjdebug & 0x0004)
+		printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board);
+	if (ixj_hookstate(j) & 1) {
+		if (j->port == PORT_POTS)
+			ixj_ring_off(j);
+		j->flags.cringing = 0;
+		if (ixjdebug & 0x0004)
+			printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board);
+	} else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) {
+		j->ring_cadence_jif = jiffies;
+		j->flags.cidsent = j->flags.cidring = 0;
+		j->cadence_f[5].state = 0;
+		if(j->cadence_f[5].on1)
+			ixj_ring_on(j);
+	} else {
+		j->ring_cadence_jif = jiffies;
+		j->ring_cadence_t = 15;
+		if (j->ring_cadence & 1 << j->ring_cadence_t) {
+			ixj_ring_on(j);
+		} else {
+			ixj_ring_off(j);
+		}
+		j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0;
+	}
+}
+
+static int ixj_ring(IXJ *j)
+{
+	char cntr;
+	unsigned long jif;
+
+	j->flags.ringing = 1;
+	if (ixj_hookstate(j) & 1) {
+		ixj_ring_off(j);
+		j->flags.ringing = 0;
+		return 1;
+	}
+	for (cntr = 0; cntr < j->maxrings; cntr++) {
+		jif = jiffies + (1 * hertz);
+		ixj_ring_on(j);
+		while (time_before(jiffies, jif)) {
+			if (ixj_hookstate(j) & 1) {
+				ixj_ring_off(j);
+				j->flags.ringing = 0;
+				return 1;
+			}
+			schedule_timeout_interruptible(1);
+			if (signal_pending(current))
+				break;
+		}
+		jif = jiffies + (3 * hertz);
+		ixj_ring_off(j);
+		while (time_before(jiffies, jif)) {
+			if (ixj_hookstate(j) & 1) {
+				msleep(10);
+				if (ixj_hookstate(j) & 1) {
+					j->flags.ringing = 0;
+					return 1;
+				}
+			}
+			schedule_timeout_interruptible(1);
+			if (signal_pending(current))
+				break;
+		}
+	}
+	ixj_ring_off(j);
+	j->flags.ringing = 0;
+	return 0;
+}
+
+static int ixj_open(struct phone_device *p, struct file *file_p)
+{
+	IXJ *j = get_ixj(p->board);
+	file_p->private_data = j;
+
+	if (!j->DSPbase)
+		return -ENODEV;
+
+        if (file_p->f_mode & FMODE_READ) {
+		if(!j->readers) {
+	                j->readers++;
+        	} else {
+                	return -EBUSY;
+		}
+        }
+
+	if (file_p->f_mode & FMODE_WRITE) {
+		if(!j->writers) {
+			j->writers++;
+		} else {
+			if (file_p->f_mode & FMODE_READ){
+				j->readers--;
+			}
+			return -EBUSY;
+		}
+	}
+
+	if (j->cardtype == QTI_PHONECARD) {
+		j->pslic.bits.powerdown = 0;
+		j->psccr.bits.dev = 3;
+		j->psccr.bits.rw = 0;
+		outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+		ixj_PCcontrol_wait(j);
+	}
+
+	j->flags.cidplay = 0;
+	j->flags.cidcw_ack = 0;
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Opening board %d\n", p->board);
+
+	j->framesread = j->frameswritten = 0;
+	return 0;
+}
+
+static int ixj_release(struct inode *inode, struct file *file_p)
+{
+	IXJ_TONE ti;
+	int cnt;
+	IXJ *j = file_p->private_data;
+	int board = j->p.board;
+
+	/*
+	 *    Set up locks to ensure that only one process is talking to the DSP at a time.
+	 *    This is necessary to keep the DSP from locking up.
+	 */
+	while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
+		schedule_timeout_interruptible(1);
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Closing board %d\n", NUM(inode));
+
+	if (j->cardtype == QTI_PHONECARD)
+		ixj_set_port(j, PORT_SPEAKER);
+	else
+		ixj_set_port(j, PORT_POTS);
+
+	aec_stop(j);
+	ixj_play_stop(j);
+	ixj_record_stop(j);
+	set_play_volume(j, 0x100);
+	set_rec_volume(j, 0x100);
+	ixj_ring_off(j);
+
+	/* Restore the tone table to default settings. */
+	ti.tone_index = 10;
+	ti.gain0 = 1;
+	ti.freq0 = hz941;
+	ti.gain1 = 0;
+	ti.freq1 = hz1209;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 11;
+	ti.gain0 = 1;
+	ti.freq0 = hz941;
+	ti.gain1 = 0;
+	ti.freq1 = hz1336;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 12;
+	ti.gain0 = 1;
+	ti.freq0 = hz941;
+	ti.gain1 = 0;
+	ti.freq1 = hz1477;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 13;
+	ti.gain0 = 1;
+	ti.freq0 = hz800;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 14;
+	ti.gain0 = 1;
+	ti.freq0 = hz1000;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 15;
+	ti.gain0 = 1;
+	ti.freq0 = hz1250;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 16;
+	ti.gain0 = 1;
+	ti.freq0 = hz950;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 17;
+	ti.gain0 = 1;
+	ti.freq0 = hz1100;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 18;
+	ti.gain0 = 1;
+	ti.freq0 = hz1400;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 19;
+	ti.gain0 = 1;
+	ti.freq0 = hz1500;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 20;
+	ti.gain0 = 1;
+	ti.freq0 = hz1600;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 21;
+	ti.gain0 = 1;
+	ti.freq0 = hz1800;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 22;
+	ti.gain0 = 1;
+	ti.freq0 = hz2100;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 23;
+	ti.gain0 = 1;
+	ti.freq0 = hz1300;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 24;
+	ti.gain0 = 1;
+	ti.freq0 = hz2450;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 25;
+	ti.gain0 = 1;
+	ti.freq0 = hz350;
+	ti.gain1 = 0;
+	ti.freq1 = hz440;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 26;
+	ti.gain0 = 1;
+	ti.freq0 = hz440;
+	ti.gain1 = 0;
+	ti.freq1 = hz480;
+	ixj_init_tone(j, &ti);
+	ti.tone_index = 27;
+	ti.gain0 = 1;
+	ti.freq0 = hz480;
+	ti.gain1 = 0;
+	ti.freq1 = hz620;
+	ixj_init_tone(j, &ti);
+
+	set_rec_depth(j, 2);	/* Set Record Channel Limit to 2 frames */
+
+	set_play_depth(j, 2);	/* Set Playback Channel Limit to 2 frames */
+
+	j->ex.bits.dtmf_ready = 0;
+	j->dtmf_state = 0;
+	j->dtmf_wp = j->dtmf_rp = 0;
+	j->rec_mode = j->play_mode = -1;
+	j->flags.ringing = 0;
+	j->maxrings = MAXRINGS;
+	j->ring_cadence = USA_RING_CADENCE;
+	if(j->cadence_f[5].enable) {
+		j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0;
+	}
+	j->drybuffer = 0;
+	j->winktime = 320;
+	j->flags.dtmf_oob = 0;
+	for (cnt = 0; cnt < 4; cnt++)
+		j->cadence_f[cnt].enable = 0;
+
+	idle(j);
+
+	if(j->cardtype == QTI_PHONECARD) {
+		SLIC_SetState(PLD_SLIC_STATE_OC, j);
+	}
+
+	if (file_p->f_mode & FMODE_READ)
+		j->readers--;
+	if (file_p->f_mode & FMODE_WRITE)
+		j->writers--;
+
+	if (j->read_buffer && !j->readers) {
+		kfree(j->read_buffer);
+		j->read_buffer = NULL;
+		j->read_buffer_size = 0;
+	}
+	if (j->write_buffer && !j->writers) {
+		kfree(j->write_buffer);
+		j->write_buffer = NULL;
+		j->write_buffer_size = 0;
+	}
+	j->rec_codec = j->play_codec = 0;
+	j->rec_frame_size = j->play_frame_size = 0;
+	j->flags.cidsent = j->flags.cidring = 0;
+
+	if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
+		ixj_set_port(j, PORT_PSTN);
+		daa_set_mode(j, SOP_PU_SLEEP);
+		ixj_set_pots(j, 1);
+	}
+	ixj_WriteDSPCommand(0x0FE3, j);	/* Put the DSP in 1/5 power mode. */
+
+	/* Set up the default signals for events */
+	for (cnt = 0; cnt < 35; cnt++)
+		j->ixj_signals[cnt] = SIGIO;
+
+	/* Set the excetion signal enable flags */
+	j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
+	j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
+	j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
+
+	file_p->private_data = NULL;
+	clear_bit(board, &j->busyflags);
+	return 0;
+}
+
+static int read_filters(IXJ *j)
+{
+	unsigned short fc, cnt, trg;
+	int var;
+
+	trg = 0;
+	if (ixj_WriteDSPCommand(0x5144, j)) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Read Frame Counter failed!\n");
+		}
+		return -1;
+	}
+	fc = j->ssr.high << 8 | j->ssr.low;
+	if (fc == j->frame_count)
+		return 1;
+
+	j->frame_count = fc;
+
+	if (j->dtmf_proc)
+		return 1;
+
+	var = 10;
+
+	for (cnt = 0; cnt < 4; cnt++) {
+		if (ixj_WriteDSPCommand(0x5154 + cnt, j)) {
+			if(ixjdebug & 0x0001) {
+				printk(KERN_INFO "Select Filter %d failed!\n", cnt);
+			}
+			return -1;
+		}
+		if (ixj_WriteDSPCommand(0x515C, j)) {
+			if(ixjdebug & 0x0001) {
+				printk(KERN_INFO "Read Filter History %d failed!\n", cnt);
+			}
+			return -1;
+		}
+		j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
+
+		if (j->cadence_f[cnt].enable) {
+			if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
+				if (j->cadence_f[cnt].state == 0) {
+					j->cadence_f[cnt].state = 1;
+					j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000));
+					j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000));
+					j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000));
+				} else if (j->cadence_f[cnt].state == 2 &&
+					   (time_after(jiffies, j->cadence_f[cnt].off1min) &&
+					    time_before(jiffies, j->cadence_f[cnt].off1max))) {
+					if (j->cadence_f[cnt].on2) {
+						j->cadence_f[cnt].state = 3;
+						j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000));
+						j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000));
+						j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000));
+					} else {
+						j->cadence_f[cnt].state = 7;
+					}
+				} else if (j->cadence_f[cnt].state == 4 &&
+					   (time_after(jiffies, j->cadence_f[cnt].off2min) &&
+					    time_before(jiffies, j->cadence_f[cnt].off2max))) {
+					if (j->cadence_f[cnt].on3) {
+						j->cadence_f[cnt].state = 5;
+						j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000));
+						j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000));
+						j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000));
+					} else {
+						j->cadence_f[cnt].state = 7;
+					}
+				} else {
+					j->cadence_f[cnt].state = 0;
+				}
+			} else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
+				if (j->cadence_f[cnt].state == 1) {
+					if(!j->cadence_f[cnt].on1) {
+						j->cadence_f[cnt].state = 7;
+					} else if((time_after(jiffies, j->cadence_f[cnt].on1min) &&
+					  time_before(jiffies, j->cadence_f[cnt].on1max))) {
+						if(j->cadence_f[cnt].off1) {
+							j->cadence_f[cnt].state = 2;
+							j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000));
+							j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000));
+							j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000));
+						} else {
+							j->cadence_f[cnt].state = 7;
+						}
+					} else {
+						j->cadence_f[cnt].state = 0;
+					}
+				} else if (j->cadence_f[cnt].state == 3) {
+					if((time_after(jiffies, j->cadence_f[cnt].on2min) &&
+					    time_before(jiffies, j->cadence_f[cnt].on2max))) {
+						if(j->cadence_f[cnt].off2) {
+							j->cadence_f[cnt].state = 4;
+							j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000));
+							j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000));
+							j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000));
+						} else {
+							j->cadence_f[cnt].state = 7;
+						}
+					} else {
+						j->cadence_f[cnt].state = 0;
+					}
+				} else if (j->cadence_f[cnt].state == 5) {
+					if ((time_after(jiffies, j->cadence_f[cnt].on3min) &&
+					    time_before(jiffies, j->cadence_f[cnt].on3max))) {
+						if(j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 6;
+							j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000));
+							j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000));
+							j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000));
+						} else {
+							j->cadence_f[cnt].state = 7;
+						}
+					} else {
+						j->cadence_f[cnt].state = 0;
+					}
+				} else {
+					j->cadence_f[cnt].state = 0;
+				}
+			} else {
+				switch(j->cadence_f[cnt].state) {
+					case 1:
+						if(time_after(jiffies, j->cadence_f[cnt].on1dot) &&
+						   !j->cadence_f[cnt].off1 &&
+						   !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
+						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 7;
+						}
+						break;
+					case 3:
+						if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
+						   !j->cadence_f[cnt].off2 &&
+						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 7;
+						}
+						break;
+					case 5:
+						if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
+						   !j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 7;
+						}
+						break;
+				}
+			}
+
+			if (ixjdebug & 0x0040) {
+				printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies);
+				switch(j->cadence_f[cnt].state) {
+					case 0:
+						printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board);
+						break;
+					case 1:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board,
+					j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max);
+						break;
+					case 2:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, 
+															j->cadence_f[cnt].off1max);
+						break;
+					case 3:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min,
+															j->cadence_f[cnt].on2max);
+						break;
+					case 4:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min,
+															j->cadence_f[cnt].off2max);
+						break;
+					case 5:
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min,
+															j->cadence_f[cnt].on3max);
+						break;
+					case 6:	
+						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min,
+															j->cadence_f[cnt].off3max);
+						break;
+				}
+			} 
+		}
+		if (j->cadence_f[cnt].state == 7) {
+			j->cadence_f[cnt].state = 0;
+			if (j->cadence_f[cnt].enable == 1)
+				j->cadence_f[cnt].enable = 0;
+			switch (cnt) {
+			case 0:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies);
+				}
+				j->ex.bits.fc0 = 1;
+				ixj_kill_fasync(j, SIG_FC0, POLL_IN);
+				break;
+			case 1:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies);
+				}
+				j->ex.bits.fc1 = 1;
+				ixj_kill_fasync(j, SIG_FC1, POLL_IN);
+				break;
+			case 2:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies);
+				}
+				j->ex.bits.fc2 = 1;
+				ixj_kill_fasync(j, SIG_FC2, POLL_IN);
+				break;
+			case 3:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies);
+				}
+				j->ex.bits.fc3 = 1;
+				ixj_kill_fasync(j, SIG_FC3, POLL_IN);
+				break;
+			}
+		}
+		if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
+					  (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
+			if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) {
+				trg = 1;
+			} else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) {
+				trg = 0;
+			}
+			switch (cnt) {
+			case 0:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies);
+				}
+				j->ex.bits.f0 = 1;
+				ixj_kill_fasync(j, SIG_F0, POLL_IN);
+				break;
+			case 1:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies);
+				}
+				j->ex.bits.f1 = 1;
+				ixj_kill_fasync(j, SIG_F1, POLL_IN);
+				break;
+			case 2:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies);
+				}
+				j->ex.bits.f2 = 1;
+				ixj_kill_fasync(j, SIG_F2, POLL_IN);
+				break;
+			case 3:
+				if(ixjdebug & 0x0020) {
+					printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies);
+				}
+				j->ex.bits.f3 = 1;
+				ixj_kill_fasync(j, SIG_F3, POLL_IN);
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+static int LineMonitor(IXJ *j)
+{
+	if (j->dtmf_proc) {
+		return -1;
+	}
+	j->dtmf_proc = 1;
+
+	if (ixj_WriteDSPCommand(0x7000, j))		/* Line Monitor */
+		return -1;
+
+	j->dtmf.bytes.high = j->ssr.high;
+	j->dtmf.bytes.low = j->ssr.low;
+	if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) {
+		j->dtmf_state = 1;
+		j->dtmf_current = j->dtmf.bits.digit;
+	}
+	if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)	/* && j->dtmf_wp != j->dtmf_rp) */
+	 {
+		if(!j->cidcw_wait) {
+			j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
+			j->dtmf_wp++;
+			if (j->dtmf_wp == 79)
+				j->dtmf_wp = 0;
+			j->ex.bits.dtmf_ready = 1;
+			if(j->ex_sig.bits.dtmf_ready) {
+				ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN);
+			}
+		}
+		else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) {
+			if(ixjdebug & 0x0020) {
+				printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies);
+			}
+			j->flags.cidcw_ack = 1;
+		}
+		j->dtmf_state = 0;
+	}
+	j->dtmf_proc = 0;
+
+	return 0;
+}
+
+/************************************************************************
+*
+* Functions to allow alaw <-> ulaw conversions.
+*
+************************************************************************/
+
+static void ulaw2alaw(unsigned char *buff, unsigned long len)
+{
+	static unsigned char table_ulaw2alaw[] =
+	{
+		0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, 
+		0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, 
+		0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 
+		0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, 
+		0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, 
+		0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, 
+		0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, 
+		0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, 
+		0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, 
+		0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, 
+		0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, 
+		0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, 
+		0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, 
+		0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, 
+		0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 
+		0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, 
+		0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, 
+		0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, 
+		0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, 
+		0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, 
+		0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, 
+		0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, 
+		0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, 
+		0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, 
+		0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, 
+		0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, 
+		0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, 
+		0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, 
+		0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, 
+		0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, 
+		0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, 
+		0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5
+	};
+
+	while (len--)
+	{
+		*buff = table_ulaw2alaw[*(unsigned char *)buff];
+		buff++;
+	}
+}
+
+static void alaw2ulaw(unsigned char *buff, unsigned long len)
+{
+	static unsigned char table_alaw2ulaw[] =
+	{
+		0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, 
+		0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, 
+		0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, 
+		0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, 
+		0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 
+		0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 
+		0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 
+		0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 
+		0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 
+		0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, 
+		0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, 
+		0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 
+		0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, 
+		0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, 
+		0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, 
+		0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, 
+		0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, 
+		0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, 
+		0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, 
+		0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, 
+		0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 
+		0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 
+		0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 
+		0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 
+		0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 
+		0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, 
+		0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, 
+		0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 
+		0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, 
+		0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, 
+		0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, 
+		0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1
+	};
+
+        while (len--)
+        {
+                *buff = table_alaw2ulaw[*(unsigned char *)buff];
+                buff++;
+	}
+}
+
+static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
+{
+	unsigned long i = *ppos;
+	IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (j->flags.inread)
+		return -EALREADY;
+
+	j->flags.inread = 1;
+
+	add_wait_queue(&j->read_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	mb();
+
+	while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
+		++j->read_wait;
+		if (file_p->f_flags & O_NONBLOCK) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&j->read_q, &wait);
+			j->flags.inread = 0;
+			return -EAGAIN;
+		}
+		if (!ixj_hookstate(j)) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&j->read_q, &wait);
+			j->flags.inread = 0;
+			return 0;
+		}
+		interruptible_sleep_on(&j->read_q);
+		if (signal_pending(current)) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&j->read_q, &wait);
+			j->flags.inread = 0;
+			return -EINTR;
+		}
+	}
+
+	remove_wait_queue(&j->read_q, &wait);
+	set_current_state(TASK_RUNNING);
+	/* Don't ever copy more than the user asks */
+	if(j->rec_codec == ALAW)
+		ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size));
+	i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
+	j->read_buffer_ready = 0;
+	if (i) {
+		j->flags.inread = 0;
+		return -EFAULT;
+	} else {
+		j->flags.inread = 0;
+		return min(length, j->read_buffer_size);
+	}
+}
+
+static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length,
+			  loff_t * ppos)
+{
+	int pre_retval;
+	ssize_t read_retval = 0;
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
+
+	pre_retval = ixj_PreRead(j, 0L);
+	switch (pre_retval) {
+	case NORMAL:
+		read_retval = ixj_read(file_p, buf, length, ppos);
+		ixj_PostRead(j, 0L);
+		break;
+	case NOPOST:
+		read_retval = ixj_read(file_p, buf, length, ppos);
+		break;
+	case POSTONLY:
+		ixj_PostRead(j, 0L);
+		break;
+	default:
+		read_retval = pre_retval;
+	}
+	return read_retval;
+}
+
+static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos)
+{
+	unsigned long i = *ppos;
+	IXJ *j = file_p->private_data;
+
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (j->flags.inwrite)
+		return -EALREADY;
+
+	j->flags.inwrite = 1;
+
+	add_wait_queue(&j->write_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	mb();
+
+
+	while (!j->write_buffers_empty) {
+		++j->write_wait;
+		if (file_p->f_flags & O_NONBLOCK) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&j->write_q, &wait);
+			j->flags.inwrite = 0;
+			return -EAGAIN;
+		}
+		if (!ixj_hookstate(j)) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&j->write_q, &wait);
+			j->flags.inwrite = 0;
+			return 0;
+		}
+		interruptible_sleep_on(&j->write_q);
+		if (signal_pending(current)) {
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&j->write_q, &wait);
+			j->flags.inwrite = 0;
+			return -EINTR;
+		}
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&j->write_q, &wait);
+	if (j->write_buffer_wp + count >= j->write_buffer_end)
+		j->write_buffer_wp = j->write_buffer;
+	i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
+	if (i) {
+		j->flags.inwrite = 0;
+		return -EFAULT;
+	}
+       if(j->play_codec == ALAW)
+               alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size));
+	j->flags.inwrite = 0;
+	return min(count, j->write_buffer_size);
+}
+
+static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos)
+{
+	int pre_retval;
+	ssize_t write_retval = 0;
+
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
+
+	pre_retval = ixj_PreWrite(j, 0L);
+	switch (pre_retval) {
+	case NORMAL:
+		write_retval = ixj_write(file_p, buf, count, ppos);
+		if (write_retval > 0) {
+			ixj_PostWrite(j, 0L);
+			j->write_buffer_wp += write_retval;
+			j->write_buffers_empty--;
+		}
+		break;
+	case NOPOST:
+		write_retval = ixj_write(file_p, buf, count, ppos);
+		if (write_retval > 0) {
+			j->write_buffer_wp += write_retval;
+			j->write_buffers_empty--;
+		}
+		break;
+	case POSTONLY:
+		ixj_PostWrite(j, 0L);
+		break;
+	default:
+		write_retval = pre_retval;
+	}
+	return write_retval;
+}
+
+static void ixj_read_frame(IXJ *j)
+{
+	int cnt, dly;
+
+	if (j->read_buffer) {
+		for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
+			if (!(cnt % 16) && !IsRxReady(j)) {
+				dly = 0;
+				while (!IsRxReady(j)) {
+					if (dly++ > 5) {
+						dly = 0;
+						break;
+					}
+					udelay(10);
+				}
+			}
+			/* Throw away word 0 of the 8021 compressed format to get standard G.729. */
+			if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
+				inb_p(j->DSPbase + 0x0E);
+				inb_p(j->DSPbase + 0x0F);
+			}
+			*(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);
+			*(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);
+		}
+		++j->framesread;
+		if (j->intercom != -1) {
+			if (IsTxReady(get_ixj(j->intercom))) {
+				for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
+					if (!(cnt % 16) && !IsTxReady(j)) {
+						dly = 0;
+						while (!IsTxReady(j)) {
+							if (dly++ > 5) {
+								dly = 0;
+								break;
+							}
+							udelay(10);
+						}
+					}
+					outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C);
+					outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D);
+				}
+				get_ixj(j->intercom)->frameswritten++;
+			}
+		} else {
+			j->read_buffer_ready = 1;
+			wake_up_interruptible(&j->read_q);	/* Wake any blocked readers */
+
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
+
+			if(j->ixj_signals[SIG_READ_READY])
+				ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT);
+		}
+	}
+}
+
+static short fsk[][6][20] =
+{
+	{
+		{
+			0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196,
+			-16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722
+		},
+		{
+			-28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481,
+			-32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876
+		},
+		{
+			-28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715,
+			-16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846
+		},
+		{
+			0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196,
+			16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722
+		},
+		{
+			28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481,
+			32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876
+		},
+		{
+			28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715,
+			16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846
+		}
+	},
+	{
+		{
+			0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126,
+			0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126
+		},
+		{
+			-28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051,
+			28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051
+		},
+		{
+			-28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925,
+			28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925
+		},
+		{
+			0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126,
+			0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126
+		},
+		{
+			28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051,
+			-28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051
+		},
+		{
+			28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925,
+			-28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925
+		}
+	}
+};
+
+
+static void ixj_write_cid_bit(IXJ *j, int bit)
+{
+	while (j->fskcnt < 20) {
+		if(j->fskdcnt < (j->fsksize - 1))
+			j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt];
+
+		j->fskcnt += 3;
+	}
+	j->fskcnt %= 20;
+
+	if (!bit)
+		j->fskz++;
+	if (j->fskz >= 6)
+		j->fskz = 0;
+
+}
+
+static void ixj_write_cid_byte(IXJ *j, char byte)
+{
+	IXJ_CBYTE cb;
+
+		cb.cbyte = byte;
+		ixj_write_cid_bit(j, 0);
+		ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0);
+		ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0);
+		ixj_write_cid_bit(j, 1);
+}
+
+static void ixj_write_cid_seize(IXJ *j)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < 150; cnt++) {
+		ixj_write_cid_bit(j, 0);
+		ixj_write_cid_bit(j, 1);
+	}
+	for (cnt = 0; cnt < 180; cnt++) {
+		ixj_write_cid_bit(j, 1);
+	}
+}
+
+static void ixj_write_cidcw_seize(IXJ *j)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < 80; cnt++) {
+		ixj_write_cid_bit(j, 1);
+	}
+}
+
+static int ixj_write_cid_string(IXJ *j, char *s, int checksum)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < strlen(s); cnt++) {
+		ixj_write_cid_byte(j, s[cnt]);
+		checksum = (checksum + s[cnt]);
+	}
+	return checksum;
+}
+
+static void ixj_pad_fsk(IXJ *j, int pad)
+{
+	int cnt; 
+
+	for (cnt = 0; cnt < pad; cnt++) {
+		if(j->fskdcnt < (j->fsksize - 1))
+			j->fskdata[j->fskdcnt++] = 0x0000;
+	}
+	for (cnt = 0; cnt < 720; cnt++) {
+		if(j->fskdcnt < (j->fsksize - 1))
+			j->fskdata[j->fskdcnt++] = 0x0000;
+	}
+}
+
+static void ixj_pre_cid(IXJ *j)
+{
+	j->cid_play_codec = j->play_codec;
+	j->cid_play_frame_size = j->play_frame_size;
+	j->cid_play_volume = get_play_volume(j);
+	j->cid_play_flag = j->flags.playing;
+
+	j->cid_rec_codec = j->rec_codec;
+	j->cid_rec_volume = get_rec_volume(j);
+	j->cid_rec_flag = j->flags.recording;
+
+	j->cid_play_aec_level = j->aec_level;
+
+	switch(j->baseframe.low) {
+		case 0xA0:
+			j->cid_base_frame_size = 20;
+			break;
+		case 0x50:
+			j->cid_base_frame_size = 10;
+			break;
+		case 0xF0:
+			j->cid_base_frame_size = 30;
+			break;
+	}
+
+	ixj_play_stop(j);
+	ixj_cpt_stop(j);
+
+	j->flags.cidplay = 1;
+
+	set_base_frame(j, 30);
+	set_play_codec(j, LINEAR16);
+	set_play_volume(j, 0x1B);
+	ixj_play_start(j);
+}
+
+static void ixj_post_cid(IXJ *j)
+{
+	ixj_play_stop(j);
+
+	if(j->cidsize > 5000) {
+		SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+	}
+	j->flags.cidplay = 0;
+	if(ixjdebug & 0x0200) {
+		printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies);
+	}
+
+	ixj_fsk_free(j);
+
+	j->fskdcnt = 0;
+	set_base_frame(j, j->cid_base_frame_size);
+	set_play_codec(j, j->cid_play_codec);
+	ixj_aec_start(j, j->cid_play_aec_level);
+	set_play_volume(j, j->cid_play_volume);
+
+	set_rec_codec(j, j->cid_rec_codec);
+	set_rec_volume(j, j->cid_rec_volume);
+
+	if(j->cid_rec_flag)
+		ixj_record_start(j);
+
+	if(j->cid_play_flag)
+		ixj_play_start(j);
+
+	if(j->cid_play_flag) {
+		wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
+	}
+}
+
+static void ixj_write_cid(IXJ *j)
+{
+	char sdmf1[50];
+	char sdmf2[50];
+	char sdmf3[80];
+	char mdmflen, len1, len2, len3;
+	int pad;
+
+	int checksum = 0;
+
+	if (j->dsp.low == 0x20 || j->flags.cidplay)
+		return;
+
+	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+	j->cidsize = j->cidcnt = 0;
+
+	ixj_fsk_alloc(j);
+
+	strcpy(sdmf1, j->cid_send.month);
+	strcat(sdmf1, j->cid_send.day);
+	strcat(sdmf1, j->cid_send.hour);
+	strcat(sdmf1, j->cid_send.min);
+	strcpy(sdmf2, j->cid_send.number);
+	strcpy(sdmf3, j->cid_send.name);
+
+	len1 = strlen(sdmf1);
+	len2 = strlen(sdmf2);
+	len3 = strlen(sdmf3);
+	mdmflen = len1 + len2 + len3 + 6;
+
+	while(1){
+		ixj_write_cid_seize(j);
+
+		ixj_write_cid_byte(j, 0x80);
+		checksum = 0x80;
+		ixj_write_cid_byte(j, mdmflen);
+		checksum = checksum + mdmflen;
+
+		ixj_write_cid_byte(j, 0x01);
+		checksum = checksum + 0x01;
+		ixj_write_cid_byte(j, len1);
+		checksum = checksum + len1;
+		checksum = ixj_write_cid_string(j, sdmf1, checksum);
+		if(ixj_hookstate(j) & 1)
+			break;
+
+		ixj_write_cid_byte(j, 0x02);
+		checksum = checksum + 0x02;
+		ixj_write_cid_byte(j, len2);
+		checksum = checksum + len2;
+		checksum = ixj_write_cid_string(j, sdmf2, checksum);
+		if(ixj_hookstate(j) & 1)
+			break;
+
+		ixj_write_cid_byte(j, 0x07);
+		checksum = checksum + 0x07;
+		ixj_write_cid_byte(j, len3);
+		checksum = checksum + len3;
+		checksum = ixj_write_cid_string(j, sdmf3, checksum);
+		if(ixj_hookstate(j) & 1)
+			break;
+
+		checksum %= 256;
+		checksum ^= 0xFF;
+		checksum += 1;
+
+		ixj_write_cid_byte(j, (char) checksum);
+
+		pad = j->fskdcnt % 240;
+		if (pad) {
+			pad = 240 - pad;
+		}
+		ixj_pad_fsk(j, pad);
+		break;
+	}
+
+	ixj_write_frame(j);
+}
+
+static void ixj_write_cidcw(IXJ *j)
+{
+	IXJ_TONE ti;
+
+	char sdmf1[50];
+	char sdmf2[50];
+	char sdmf3[80];
+	char mdmflen, len1, len2, len3;
+	int pad;
+
+	int checksum = 0;
+
+	if (j->dsp.low == 0x20 || j->flags.cidplay)
+		return;
+
+	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+	j->cidsize = j->cidcnt = 0;
+
+	ixj_fsk_alloc(j);
+
+	j->flags.cidcw_ack = 0;
+
+	ti.tone_index = 23;
+	ti.gain0 = 1;
+	ti.freq0 = hz440;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(j, &ti);
+
+	ixj_set_tone_on(1500, j);
+	ixj_set_tone_off(32, j);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies);
+	}
+	ixj_play_tone(j, 23);
+
+	clear_bit(j->board, &j->busyflags);
+	while(j->tone_state)
+		schedule_timeout_interruptible(1);
+	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
+		schedule_timeout_interruptible(1);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
+	}
+
+	ti.tone_index = 24;
+	ti.gain0 = 1;
+	ti.freq0 = hz2130;
+	ti.gain1 = 0;
+	ti.freq1 = hz2750;
+	ixj_init_tone(j, &ti);
+
+	ixj_set_tone_off(10, j);
+	ixj_set_tone_on(600, j);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies);
+	}
+	ixj_play_tone(j, 24);
+
+	clear_bit(j->board, &j->busyflags);
+	while(j->tone_state)
+		schedule_timeout_interruptible(1);
+	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
+		schedule_timeout_interruptible(1);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
+	}
+
+	j->cidcw_wait = jiffies + ((50 * hertz) / 100);
+
+	clear_bit(j->board, &j->busyflags);
+	while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait))
+		schedule_timeout_interruptible(1);
+	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
+		schedule_timeout_interruptible(1);
+	j->cidcw_wait = 0;
+	if(!j->flags.cidcw_ack) {
+		if(ixjdebug & 0x0200) {
+			printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies);
+		}
+		ixj_post_cid(j);
+		if(j->cid_play_flag) {
+			wake_up_interruptible(&j->write_q);	/* Wake any blocked readers */
+		}
+		return;
+	} else {
+		ixj_pre_cid(j);
+	}
+	j->flags.cidcw_ack = 0;
+	strcpy(sdmf1, j->cid_send.month);
+	strcat(sdmf1, j->cid_send.day);
+	strcat(sdmf1, j->cid_send.hour);
+	strcat(sdmf1, j->cid_send.min);
+	strcpy(sdmf2, j->cid_send.number);
+	strcpy(sdmf3, j->cid_send.name);
+
+	len1 = strlen(sdmf1);
+	len2 = strlen(sdmf2);
+	len3 = strlen(sdmf3);
+	mdmflen = len1 + len2 + len3 + 6;
+
+	ixj_write_cidcw_seize(j);
+
+	ixj_write_cid_byte(j, 0x80);
+	checksum = 0x80;
+	ixj_write_cid_byte(j, mdmflen);
+	checksum = checksum + mdmflen;
+
+	ixj_write_cid_byte(j, 0x01);
+	checksum = checksum + 0x01;
+	ixj_write_cid_byte(j, len1);
+	checksum = checksum + len1;
+	checksum = ixj_write_cid_string(j, sdmf1, checksum);
+
+	ixj_write_cid_byte(j, 0x02);
+	checksum = checksum + 0x02;
+	ixj_write_cid_byte(j, len2);
+	checksum = checksum + len2;
+	checksum = ixj_write_cid_string(j, sdmf2, checksum);
+
+	ixj_write_cid_byte(j, 0x07);
+	checksum = checksum + 0x07;
+	ixj_write_cid_byte(j, len3);
+	checksum = checksum + len3;
+	checksum = ixj_write_cid_string(j, sdmf3, checksum);
+
+	checksum %= 256;
+	checksum ^= 0xFF;
+	checksum += 1;
+
+	ixj_write_cid_byte(j, (char) checksum);
+
+	pad = j->fskdcnt % 240;
+	if (pad) {
+		pad = 240 - pad;
+	}
+	ixj_pad_fsk(j, pad);
+	if(ixjdebug & 0x0200) {
+		printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies);
+	}
+}
+
+static void ixj_write_vmwi(IXJ *j, int msg)
+{
+	char mdmflen;
+	int pad;
+
+	int checksum = 0;
+
+	if (j->dsp.low == 0x20 || j->flags.cidplay)
+		return;
+
+	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+	j->cidsize = j->cidcnt = 0;
+
+	ixj_fsk_alloc(j);
+
+	mdmflen = 3;
+
+	if (j->port == PORT_POTS)
+		SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+
+	ixj_write_cid_seize(j);
+
+	ixj_write_cid_byte(j, 0x82);
+	checksum = 0x82;
+	ixj_write_cid_byte(j, mdmflen);
+	checksum = checksum + mdmflen;
+
+	ixj_write_cid_byte(j, 0x0B);
+	checksum = checksum + 0x0B;
+	ixj_write_cid_byte(j, 1);
+	checksum = checksum + 1;
+
+	if(msg) {
+		ixj_write_cid_byte(j, 0xFF);
+		checksum = checksum + 0xFF;
+	}
+	else {
+		ixj_write_cid_byte(j, 0x00);
+		checksum = checksum + 0x00;
+	}
+
+	checksum %= 256;
+	checksum ^= 0xFF;
+	checksum += 1;
+
+	ixj_write_cid_byte(j, (char) checksum);
+
+	pad = j->fskdcnt % 240;
+	if (pad) {
+		pad = 240 - pad;
+	}
+	ixj_pad_fsk(j, pad);
+}
+
+static void ixj_write_frame(IXJ *j)
+{
+	int cnt, frame_count, dly;
+	IXJ_WORD dat;
+
+	frame_count = 0;
+	if(j->flags.cidplay) {
+		for(cnt = 0; cnt < 480; cnt++) {
+			if (!(cnt % 16) && !IsTxReady(j)) {
+				dly = 0;
+				while (!IsTxReady(j)) {
+					if (dly++ > 5) {
+						dly = 0;
+						break;
+					}
+					udelay(10);
+				}
+			}
+			dat.word = j->fskdata[j->cidcnt++];
+			outb_p(dat.bytes.low, j->DSPbase + 0x0C);
+			outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+			cnt++;
+		}
+		if(j->cidcnt >= j->fskdcnt) {
+			ixj_post_cid(j);
+		}
+		/* This may seem rude, but if we just played one frame of FSK data for CallerID
+		   and there is real audio data in the buffer, we need to throw it away because 
+		   we just used it's time slot */
+		if (j->write_buffer_rp > j->write_buffer_wp) {
+			j->write_buffer_rp += j->cid_play_frame_size * 2;
+			if (j->write_buffer_rp >= j->write_buffer_end) {
+				j->write_buffer_rp = j->write_buffer;
+			}
+			j->write_buffers_empty++;
+			wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
+
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
+		}
+	} else if (j->write_buffer && j->write_buffers_empty < 1) { 
+		if (j->write_buffer_wp > j->write_buffer_rp) {
+			frame_count =
+			    (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
+		}
+		if (j->write_buffer_rp > j->write_buffer_wp) {
+			frame_count =
+			    (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) +
+			    (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2);
+		}
+		if (frame_count >= 1) {
+			if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) {
+				BYTES blankword;
+
+				switch (j->play_mode) {
+				case PLAYBACK_MODE_ULAW:
+				case PLAYBACK_MODE_ALAW:
+					blankword.low = blankword.high = 0xFF;
+					break;
+				case PLAYBACK_MODE_8LINEAR:
+				case PLAYBACK_MODE_16LINEAR:
+				default:
+					blankword.low = blankword.high = 0x00;
+					break;
+				case PLAYBACK_MODE_8LINEAR_WSS:
+					blankword.low = blankword.high = 0x80;
+					break;
+				}
+				for (cnt = 0; cnt < 16; cnt++) {
+					if (!(cnt % 16) && !IsTxReady(j)) {
+						dly = 0;
+						while (!IsTxReady(j)) {
+							if (dly++ > 5) {
+								dly = 0;
+								break;
+							}
+							udelay(10);
+						}
+					}
+					outb_p((blankword.low), j->DSPbase + 0x0C);
+					outb_p((blankword.high), j->DSPbase + 0x0D);
+				}
+				j->flags.play_first_frame = 0;
+			} else	if (j->play_codec == G723_63 && j->flags.play_first_frame) {
+				for (cnt = 0; cnt < 24; cnt++) {
+					BYTES blankword;
+
+					if(cnt == 12) {
+						blankword.low = 0x02;
+						blankword.high = 0x00;
+					}
+					else {
+						blankword.low = blankword.high = 0x00;
+					}
+					if (!(cnt % 16) && !IsTxReady(j)) {
+						dly = 0;
+						while (!IsTxReady(j)) {
+							if (dly++ > 5) {
+								dly = 0;
+								break;
+							}
+							udelay(10);
+						}
+					}
+					outb_p((blankword.low), j->DSPbase + 0x0C);
+					outb_p((blankword.high), j->DSPbase + 0x0D);
+				}
+				j->flags.play_first_frame = 0;
+			}
+			for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
+				if (!(cnt % 16) && !IsTxReady(j)) {
+					dly = 0;
+					while (!IsTxReady(j)) {
+						if (dly++ > 5) {
+							dly = 0;
+							break;
+						}
+						udelay(10);
+					}
+				}
+			/* Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG  */
+				if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
+					if (j->write_buffer_rp[cnt] == 0 &&
+					    j->write_buffer_rp[cnt + 1] == 0 &&
+					    j->write_buffer_rp[cnt + 2] == 0 &&
+					    j->write_buffer_rp[cnt + 3] == 0 &&
+					    j->write_buffer_rp[cnt + 4] == 0 &&
+					    j->write_buffer_rp[cnt + 5] == 0 &&
+					    j->write_buffer_rp[cnt + 6] == 0 &&
+					    j->write_buffer_rp[cnt + 7] == 0 &&
+					    j->write_buffer_rp[cnt + 8] == 0 &&
+					    j->write_buffer_rp[cnt + 9] == 0) {
+					/* someone is trying to write silence lets make this a type 0 frame. */
+						outb_p(0x00, j->DSPbase + 0x0C);
+						outb_p(0x00, j->DSPbase + 0x0D);
+					} else {
+					/* so all other frames are type 1. */
+						outb_p(0x01, j->DSPbase + 0x0C);
+						outb_p(0x00, j->DSPbase + 0x0D);
+					}
+				}
+				outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
+				outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
+				*(j->write_buffer_rp + cnt) = 0;
+				*(j->write_buffer_rp + cnt + 1) = 0;
+			}
+			j->write_buffer_rp += j->play_frame_size * 2;
+			if (j->write_buffer_rp >= j->write_buffer_end) {
+				j->write_buffer_rp = j->write_buffer;
+			}
+			j->write_buffers_empty++;
+			wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
+
+			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
+
+			++j->frameswritten;
+		}
+	} else {
+		j->drybuffer++;
+	}
+	if(j->ixj_signals[SIG_WRITE_READY]) {
+		ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT);
+	}
+}
+
+static int idle(IXJ *j)
+{
+	if (ixj_WriteDSPCommand(0x0000, j))		/* DSP Idle */
+
+		return 0;
+
+	if (j->ssr.high || j->ssr.low) {
+		return 0;
+	} else {
+		j->play_mode = -1;
+		j->flags.playing = 0;
+		j->rec_mode = -1;
+		j->flags.recording = 0;
+		return 1;
+        }
+}
+
+static int set_base_frame(IXJ *j, int size)
+{
+	unsigned short cmd;
+	int cnt;
+
+	idle(j);
+	j->cid_play_aec_level = j->aec_level;
+	aec_stop(j);
+	for (cnt = 0; cnt < 10; cnt++) {
+		if (idle(j))
+			break;
+	}
+	if (j->ssr.high || j->ssr.low)
+		return -1;
+	if (j->dsp.low != 0x20) {
+		switch (size) {
+		case 30:
+			cmd = 0x07F0;
+			/* Set Base Frame Size to 240 pg9-10 8021 */
+			break;
+		case 20:
+			cmd = 0x07A0;
+			/* Set Base Frame Size to 160 pg9-10 8021 */
+			break;
+		case 10:
+			cmd = 0x0750;
+			/* Set Base Frame Size to 80 pg9-10 8021 */
+			break;
+		default:
+			return -1;
+		}
+	} else {
+		if (size == 30)
+			return size;
+		else
+			return -1;
+	}
+	if (ixj_WriteDSPCommand(cmd, j)) {
+		j->baseframe.high = j->baseframe.low = 0xFF;
+		return -1;
+	} else {
+		j->baseframe.high = j->ssr.high;
+		j->baseframe.low = j->ssr.low;
+		/* If the status returned is 0x0000 (pg9-9 8021) the call failed */
+		if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) {
+			return -1;
+		}
+	}
+	ixj_aec_start(j, j->cid_play_aec_level);
+	return size;
+}
+
+static int set_rec_codec(IXJ *j, int rate)
+{
+	int retval = 0;
+
+	j->rec_codec = rate;
+
+	switch (rate) {
+	case G723_63:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->rec_frame_size = 12;
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G723_53:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->rec_frame_size = 10;
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case TS85:
+		if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
+			j->rec_frame_size = 16;
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case TS48:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->rec_frame_size = 9;
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case TS41:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->rec_frame_size = 8;
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G728:
+		if (j->dsp.low != 0x20) {
+			j->rec_frame_size = 48;
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G729:
+		if (j->dsp.low != 0x20) {
+			if (!j->flags.g729_loaded) {
+				retval = 1;
+				break;
+			}
+			switch (j->baseframe.low) {
+			case 0xA0:
+				j->rec_frame_size = 10;
+				break;
+			case 0x50:
+				j->rec_frame_size = 5;
+				break;
+			default:
+				j->rec_frame_size = 15;
+				break;
+			}
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G729B:
+		if (j->dsp.low != 0x20) {
+			if (!j->flags.g729_loaded) {
+				retval = 1;
+				break;
+			}
+			switch (j->baseframe.low) {
+			case 0xA0:
+				j->rec_frame_size = 12;
+				break;
+			case 0x50:
+				j->rec_frame_size = 6;
+				break;
+			default:
+				j->rec_frame_size = 18;
+				break;
+			}
+			j->rec_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case ULAW:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->rec_frame_size = 80;
+			break;
+		case 0x50:
+			j->rec_frame_size = 40;
+			break;
+		default:
+			j->rec_frame_size = 120;
+			break;
+		}
+		j->rec_mode = 4;
+		break;
+	case ALAW:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->rec_frame_size = 80;
+			break;
+		case 0x50:
+			j->rec_frame_size = 40;
+			break;
+		default:
+			j->rec_frame_size = 120;
+			break;
+		}
+		j->rec_mode = 4;
+		break;
+	case LINEAR16:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->rec_frame_size = 160;
+			break;
+		case 0x50:
+			j->rec_frame_size = 80;
+			break;
+		default:
+			j->rec_frame_size = 240;
+			break;
+		}
+		j->rec_mode = 5;
+		break;
+	case LINEAR8:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->rec_frame_size = 80;
+			break;
+		case 0x50:
+			j->rec_frame_size = 40;
+			break;
+		default:
+			j->rec_frame_size = 120;
+			break;
+		}
+		j->rec_mode = 6;
+		break;
+	case WSS:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->rec_frame_size = 80;
+			break;
+		case 0x50:
+			j->rec_frame_size = 40;
+			break;
+		default:
+			j->rec_frame_size = 120;
+			break;
+		}
+		j->rec_mode = 7;
+		break;
+	default:
+		kfree(j->read_buffer);
+		j->rec_frame_size = 0;
+		j->rec_mode = -1;
+		j->read_buffer = NULL;
+		j->read_buffer_size = 0;
+		retval = 1;
+		break;
+	}
+	return retval;
+}
+
+static int ixj_record_start(IXJ *j)
+{
+	unsigned short cmd = 0x0000;
+
+	if (j->read_buffer) {
+		ixj_record_stop(j);
+	}
+	j->flags.recording = 1;
+	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
+
+	if(ixjdebug & 0x0002)
+		printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
+
+	if (!j->rec_mode) {
+		switch (j->rec_codec) {
+		case G723_63:
+			cmd = 0x5131;
+			break;
+		case G723_53:
+			cmd = 0x5132;
+			break;
+		case TS85:
+			cmd = 0x5130;	/* TrueSpeech 8.5 */
+
+			break;
+		case TS48:
+			cmd = 0x5133;	/* TrueSpeech 4.8 */
+
+			break;
+		case TS41:
+			cmd = 0x5134;	/* TrueSpeech 4.1 */
+
+			break;
+		case G728:
+			cmd = 0x5135;
+			break;
+		case G729:
+		case G729B:
+			cmd = 0x5136;
+			break;
+		default:
+			return 1;
+		}
+		if (ixj_WriteDSPCommand(cmd, j))
+			return -1;
+	}
+	if (!j->read_buffer) {
+		if (!j->read_buffer)
+			j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
+		if (!j->read_buffer) {
+			printk("Read buffer allocation for ixj board %d failed!\n", j->board);
+			return -ENOMEM;
+		}
+	}
+	j->read_buffer_size = j->rec_frame_size * 2;
+
+	if (ixj_WriteDSPCommand(0x5102, j))		/* Set Poll sync mode */
+
+		return -1;
+
+	switch (j->rec_mode) {
+	case 0:
+		cmd = 0x1C03;	/* Record C1 */
+
+		break;
+	case 4:
+		if (j->ver.low == 0x12) {
+			cmd = 0x1E03;	/* Record C1 */
+
+		} else {
+			cmd = 0x1E01;	/* Record C1 */
+
+		}
+		break;
+	case 5:
+		if (j->ver.low == 0x12) {
+			cmd = 0x1E83;	/* Record C1 */
+
+		} else {
+			cmd = 0x1E81;	/* Record C1 */
+
+		}
+		break;
+	case 6:
+		if (j->ver.low == 0x12) {
+			cmd = 0x1F03;	/* Record C1 */
+
+		} else {
+			cmd = 0x1F01;	/* Record C1 */
+
+		}
+		break;
+	case 7:
+		if (j->ver.low == 0x12) {
+			cmd = 0x1F83;	/* Record C1 */
+		} else {
+			cmd = 0x1F81;	/* Record C1 */
+		}
+		break;
+	}
+	if (ixj_WriteDSPCommand(cmd, j))
+		return -1;
+
+	if (j->flags.playing) {
+		ixj_aec_start(j, j->aec_level);
+	}
+	return 0;
+}
+
+static void ixj_record_stop(IXJ *j)
+{
+	if (ixjdebug & 0x0002)
+		printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
+
+	kfree(j->read_buffer);
+	j->read_buffer = NULL;
+	j->read_buffer_size = 0;
+	if (j->rec_mode > -1) {
+		ixj_WriteDSPCommand(0x5120, j);
+		j->rec_mode = -1;
+	}
+	j->flags.recording = 0;
+}
+static void ixj_vad(IXJ *j, int arg)
+{
+	if (arg)
+		ixj_WriteDSPCommand(0x513F, j);
+	else
+		ixj_WriteDSPCommand(0x513E, j);
+}
+
+static void set_rec_depth(IXJ *j, int depth)
+{
+	if (depth > 60)
+		depth = 60;
+	if (depth < 0)
+		depth = 0;
+	ixj_WriteDSPCommand(0x5180 + depth, j);
+}
+
+static void set_dtmf_prescale(IXJ *j, int volume)
+{
+	ixj_WriteDSPCommand(0xCF07, j);
+	ixj_WriteDSPCommand(volume, j);
+}
+
+static int get_dtmf_prescale(IXJ *j)
+{
+	ixj_WriteDSPCommand(0xCF05, j);
+	return j->ssr.high << 8 | j->ssr.low;
+}
+
+static void set_rec_volume(IXJ *j, int volume)
+{
+	if(j->aec_level == AEC_AGC) {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume);
+		ixj_WriteDSPCommand(0xCF96, j);
+		ixj_WriteDSPCommand(volume, j);
+	} else {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume);
+		ixj_WriteDSPCommand(0xCF03, j);
+		ixj_WriteDSPCommand(volume, j);
+	}
+}
+
+static int set_rec_volume_linear(IXJ *j, int volume)
+{
+	int newvolume, dsprecmax;
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume);
+	if(volume > 100 || volume < 0) {
+	  return -1;
+	}
+
+	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dsprecmax = 0x440;
+		break;
+	case QTI_LINEJACK:
+		dsprecmax = 0x180;
+		ixj_mixer(0x0203, j);	/*Voice Left Volume unmute 6db */
+		ixj_mixer(0x0303, j);	/*Voice Right Volume unmute 6db */
+		ixj_mixer(0x0C00, j);	/*Mono1 unmute 12db */
+		break;
+	case QTI_PHONEJACK_LITE:
+		dsprecmax = 0x4C0;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dsprecmax = 0x100;
+		break;
+	case QTI_PHONECARD:
+		dsprecmax = 0x400;
+		break;
+	default:
+		return -1;
+	}
+	newvolume = (dsprecmax * volume) / 100;
+	set_rec_volume(j, newvolume);
+	return 0;
+}
+
+static int get_rec_volume(IXJ *j)
+{
+	if(j->aec_level == AEC_AGC) {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Getting AGC Threshold\n");
+		ixj_WriteDSPCommand(0xCF86, j);
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low);
+		return j->ssr.high << 8 | j->ssr.low;
+	} else {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Getting Record Volume\n");
+		ixj_WriteDSPCommand(0xCF01, j);
+		return j->ssr.high << 8 | j->ssr.low;
+	}
+}
+
+static int get_rec_volume_linear(IXJ *j)
+{
+	int volume, newvolume, dsprecmax;
+
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		dsprecmax = 0x440;
+		break;
+	case QTI_LINEJACK:
+		dsprecmax = 0x180;
+		break;
+	case QTI_PHONEJACK_LITE:
+		dsprecmax = 0x4C0;
+		break;
+	case QTI_PHONEJACK_PCI:
+		dsprecmax = 0x100;
+		break;
+	case QTI_PHONECARD:
+		dsprecmax = 0x400;
+		break;
+	default:
+		return -1;
+	}
+	volume = get_rec_volume(j);
+	newvolume = (volume * 100) / dsprecmax;
+	if(newvolume > 100)
+		newvolume = 100;
+	return newvolume;
+}
+
+static int get_rec_level(IXJ *j)
+{
+	int retval;
+
+	ixj_WriteDSPCommand(0xCF88, j);
+
+	retval = j->ssr.high << 8 | j->ssr.low;
+	retval = (retval * 256) / 240;
+	return retval;
+}
+
+static void ixj_aec_start(IXJ *j, int level)
+{
+	j->aec_level = level;
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level);
+	if (!level) {
+		aec_stop(j);
+	} else {
+		if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+			ixj_WriteDSPCommand(0xE022, j);	/* Move AEC filter buffer */
+
+			ixj_WriteDSPCommand(0x0300, j);
+		}
+		ixj_WriteDSPCommand(0xB001, j);	/* AEC On */
+
+		ixj_WriteDSPCommand(0xE013, j);	/* Advanced AEC C1 */
+
+		switch (level) {
+		case AEC_LOW:
+			ixj_WriteDSPCommand(0x0000, j);	/* Advanced AEC C2 = off */
+
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0xFFFF, j);
+
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0000, j);	/* to off */
+			
+			break;
+
+		case AEC_MED:
+			ixj_WriteDSPCommand(0x0600, j);	/* Advanced AEC C2 = on medium */
+
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0080, j);
+
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0000, j);	/* to off */
+			
+			break;
+
+		case AEC_HIGH:
+			ixj_WriteDSPCommand(0x0C00, j);	/* Advanced AEC C2 = on high */
+
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0080, j);
+
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0000, j);	/* to off */
+			
+			break;
+
+		case AEC_AGC:
+                        /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */
+			ixj_WriteDSPCommand(0x0002, j);	/* Attenuation scaling factor of 2 */
+
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0100, j);	/* Higher Threshold Floor */
+
+			ixj_WriteDSPCommand(0xE012, j);	/* Set Train and Lock */
+
+			if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+				ixj_WriteDSPCommand(0x0224, j);
+			else
+				ixj_WriteDSPCommand(0x1224, j);
+
+			ixj_WriteDSPCommand(0xE014, j);
+			ixj_WriteDSPCommand(0x0003, j);	/* Lock threshold at 3dB */
+
+			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
+
+			/* Now we can set the AGC initial parameters and turn it on */
+			ixj_WriteDSPCommand(0xCF90, j);	/* Set AGC Minimum gain */
+			ixj_WriteDSPCommand(0x0020, j);	/* to 0.125 (-18dB) */
+	
+			ixj_WriteDSPCommand(0xCF91, j);	/* Set AGC Maximum gain */
+			ixj_WriteDSPCommand(0x1000, j);	/* to 16 (24dB) */
+			
+			ixj_WriteDSPCommand(0xCF92, j);	/* Set AGC start gain */
+			ixj_WriteDSPCommand(0x0800, j);	/* to 8 (+18dB) */
+		
+			ixj_WriteDSPCommand(0xCF93, j);	/* Set AGC hold time */
+			ixj_WriteDSPCommand(0x1F40, j);	/* to 2 seconds (units are 250us) */
+			
+			ixj_WriteDSPCommand(0xCF94, j);	/* Set AGC Attack Time Constant */
+			ixj_WriteDSPCommand(0x0005, j);	/* to 8ms */
+			
+			ixj_WriteDSPCommand(0xCF95, j);	/* Set AGC Decay Time Constant */
+			ixj_WriteDSPCommand(0x000D, j);	/* to 4096ms */
+			
+			ixj_WriteDSPCommand(0xCF96, j);	/* Set AGC Attack Threshold */
+			ixj_WriteDSPCommand(0x1200, j);	/* to 25% */
+			
+			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
+			ixj_WriteDSPCommand(0x0001, j);	/* to on */
+			
+			break;
+
+		case AEC_AUTO:
+			ixj_WriteDSPCommand(0x0002, j);	/* Attenuation scaling factor of 2 */
+
+			ixj_WriteDSPCommand(0xE011, j);
+			ixj_WriteDSPCommand(0x0100, j);	/* Higher Threshold Floor */
+
+			ixj_WriteDSPCommand(0xE012, j);	/* Set Train and Lock */
+
+			if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+				ixj_WriteDSPCommand(0x0224, j);
+			else
+				ixj_WriteDSPCommand(0x1224, j);
+
+			ixj_WriteDSPCommand(0xE014, j);
+			ixj_WriteDSPCommand(0x0003, j);	/* Lock threshold at 3dB */
+
+			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
+
+			break;
+		}
+	}
+}
+
+static void aec_stop(IXJ *j)
+{
+	j->aec_level = AEC_OFF;
+	if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+		ixj_WriteDSPCommand(0xE022, j);	/* Move AEC filter buffer back */
+
+		ixj_WriteDSPCommand(0x0700, j);
+	}
+	if (j->play_mode != -1 && j->rec_mode != -1)
+	{
+		ixj_WriteDSPCommand(0xB002, j);	/* AEC Stop */
+	}
+}
+
+static int set_play_codec(IXJ *j, int rate)
+{
+	int retval = 0;
+
+	j->play_codec = rate;
+
+	switch (rate) {
+	case G723_63:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->play_frame_size = 12;
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G723_53:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->play_frame_size = 10;
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case TS85:
+		if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
+			j->play_frame_size = 16;
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case TS48:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->play_frame_size = 9;
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case TS41:
+		if (j->ver.low != 0x12 || ixj_convert_loaded) {
+			j->play_frame_size = 8;
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G728:
+		if (j->dsp.low != 0x20) {
+			j->play_frame_size = 48;
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G729:
+		if (j->dsp.low != 0x20) {
+			if (!j->flags.g729_loaded) {
+				retval = 1;
+				break;
+			}
+			switch (j->baseframe.low) {
+			case 0xA0:
+				j->play_frame_size = 10;
+				break;
+			case 0x50:
+				j->play_frame_size = 5;
+				break;
+			default:
+				j->play_frame_size = 15;
+				break;
+			}
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case G729B:
+		if (j->dsp.low != 0x20) {
+			if (!j->flags.g729_loaded) {
+				retval = 1;
+				break;
+			}
+			switch (j->baseframe.low) {
+			case 0xA0:
+				j->play_frame_size = 12;
+				break;
+			case 0x50:
+				j->play_frame_size = 6;
+				break;
+			default:
+				j->play_frame_size = 18;
+				break;
+			}
+			j->play_mode = 0;
+		} else {
+			retval = 1;
+		}
+		break;
+	case ULAW:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->play_frame_size = 80;
+			break;
+		case 0x50:
+			j->play_frame_size = 40;
+			break;
+		default:
+			j->play_frame_size = 120;
+			break;
+		}
+		j->play_mode = 2;
+		break;
+	case ALAW:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->play_frame_size = 80;
+			break;
+		case 0x50:
+			j->play_frame_size = 40;
+			break;
+		default:
+			j->play_frame_size = 120;
+			break;
+		}
+		j->play_mode = 2;
+		break;
+	case LINEAR16:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->play_frame_size = 160;
+			break;
+		case 0x50:
+			j->play_frame_size = 80;
+			break;
+		default:
+			j->play_frame_size = 240;
+			break;
+		}
+		j->play_mode = 6;
+		break;
+	case LINEAR8:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->play_frame_size = 80;
+			break;
+		case 0x50:
+			j->play_frame_size = 40;
+			break;
+		default:
+			j->play_frame_size = 120;
+			break;
+		}
+		j->play_mode = 4;
+		break;
+	case WSS:
+		switch (j->baseframe.low) {
+		case 0xA0:
+			j->play_frame_size = 80;
+			break;
+		case 0x50:
+			j->play_frame_size = 40;
+			break;
+		default:
+			j->play_frame_size = 120;
+			break;
+		}
+		j->play_mode = 5;
+		break;
+	default:
+		kfree(j->write_buffer);
+		j->play_frame_size = 0;
+		j->play_mode = -1;
+		j->write_buffer = NULL;
+		j->write_buffer_size = 0;
+		retval = 1;
+		break;
+	}
+	return retval;
+}
+
+static int ixj_play_start(IXJ *j)
+{
+	unsigned short cmd = 0x0000;
+
+	if (j->write_buffer) {
+		ixj_play_stop(j);
+	}
+
+	if(ixjdebug & 0x0002)
+		printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
+	j->flags.playing = 1;
+	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
+
+	j->flags.play_first_frame = 1;
+	j->drybuffer = 0;
+
+	if (!j->play_mode) {
+		switch (j->play_codec) {
+		case G723_63:
+			cmd = 0x5231;
+			break;
+		case G723_53:
+			cmd = 0x5232;
+			break;
+		case TS85:
+			cmd = 0x5230;	/* TrueSpeech 8.5 */
+
+			break;
+		case TS48:
+			cmd = 0x5233;	/* TrueSpeech 4.8 */
+
+			break;
+		case TS41:
+			cmd = 0x5234;	/* TrueSpeech 4.1 */
+
+			break;
+		case G728:
+			cmd = 0x5235;
+			break;
+		case G729:
+		case G729B:
+			cmd = 0x5236;
+			break;
+		default:
+			return 1;
+		}
+		if (ixj_WriteDSPCommand(cmd, j))
+			return -1;
+	}
+	j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
+	if (!j->write_buffer) {
+		printk("Write buffer allocation for ixj board %d failed!\n", j->board);
+		return -ENOMEM;
+	}
+/*	j->write_buffers_empty = 2; */
+	j->write_buffers_empty = 1; 
+	j->write_buffer_size = j->play_frame_size * 2;
+	j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
+	j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
+
+	if (ixj_WriteDSPCommand(0x5202, j))		/* Set Poll sync mode */
+
+		return -1;
+
+	switch (j->play_mode) {
+	case 0:
+		cmd = 0x2C03;
+		break;
+	case 2:
+		if (j->ver.low == 0x12) {
+			cmd = 0x2C23;
+		} else {
+			cmd = 0x2C21;
+		}
+		break;
+	case 4:
+		if (j->ver.low == 0x12) {
+			cmd = 0x2C43;
+		} else {
+			cmd = 0x2C41;
+		}
+		break;
+	case 5:
+		if (j->ver.low == 0x12) {
+			cmd = 0x2C53;
+		} else {
+			cmd = 0x2C51;
+		}
+		break;
+	case 6:
+		if (j->ver.low == 0x12) {
+			cmd = 0x2C63;
+		} else {
+			cmd = 0x2C61;
+		}
+		break;
+	}
+	if (ixj_WriteDSPCommand(cmd, j))
+		return -1;
+
+	if (ixj_WriteDSPCommand(0x2000, j))		/* Playback C2 */
+		return -1;
+
+	if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))	/* Playback C3 */
+		return -1;
+
+	if (j->flags.recording) {
+		ixj_aec_start(j, j->aec_level);
+	}
+
+	return 0;
+}
+
+static void ixj_play_stop(IXJ *j)
+{
+	if (ixjdebug & 0x0002)
+		printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
+	kfree(j->write_buffer);
+	j->write_buffer = NULL;
+	j->write_buffer_size = 0;
+	if (j->play_mode > -1) {
+		ixj_WriteDSPCommand(0x5221, j);	/* Stop playback and flush buffers.  8022 reference page 9-40 */
+
+		j->play_mode = -1;
+	}
+	j->flags.playing = 0;
+}
+
+static inline int get_play_level(IXJ *j)
+{
+	int retval;
+
+	ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */
+	return j->ssr.high << 8 | j->ssr.low;
+	retval = j->ssr.high << 8 | j->ssr.low;
+	retval = (retval * 256) / 240;
+	return retval;
+}
+
+static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
+{
+	unsigned int mask = 0;
+
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
+
+	poll_wait(file_p, &(j->poll_q), wait);
+	if (j->read_buffer_ready > 0)
+		mask |= POLLIN | POLLRDNORM;	/* readable */
+	if (j->write_buffers_empty > 0)
+		mask |= POLLOUT | POLLWRNORM;	/* writable */
+	if (j->ex.bytes)
+		mask |= POLLPRI;
+	return mask;
+}
+
+static int ixj_play_tone(IXJ *j, char tone)
+{
+	if (!j->tone_state) {
+		if(ixjdebug & 0x0002) {
+			printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies);
+		}
+		if (j->dsp.low == 0x20) {
+			idle(j);
+		}
+		j->tone_start_jif = jiffies;
+
+		j->tone_state = 1;
+	}
+
+	j->tone_index = tone;
+	if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
+		return -1;
+
+	return 0;
+}
+
+static int ixj_set_tone_on(unsigned short arg, IXJ *j)
+{
+	j->tone_on_time = arg;
+
+	if (ixj_WriteDSPCommand(0x6E04, j))		/* Set Tone On Period */
+
+		return -1;
+
+	if (ixj_WriteDSPCommand(arg, j))
+		return -1;
+
+	return 0;
+}
+
+static int SCI_WaitHighSCI(IXJ *j)
+{
+	int cnt;
+
+	j->pld_scrr.byte = inb_p(j->XILINXbase);
+	if (!j->pld_scrr.bits.sci) {
+		for (cnt = 0; cnt < 10; cnt++) {
+			udelay(32);
+			j->pld_scrr.byte = inb_p(j->XILINXbase);
+
+			if ((j->pld_scrr.bits.sci))
+				return 1;
+		}
+		if (ixjdebug & 0x0001)
+			printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte);
+		return 0;
+	} else
+		return 1;
+}
+
+static int SCI_WaitLowSCI(IXJ *j)
+{
+	int cnt;
+
+	j->pld_scrr.byte = inb_p(j->XILINXbase);
+	if (j->pld_scrr.bits.sci) {
+		for (cnt = 0; cnt < 10; cnt++) {
+			udelay(32);
+			j->pld_scrr.byte = inb_p(j->XILINXbase);
+
+			if (!(j->pld_scrr.bits.sci))
+				return 1;
+		}
+		if (ixjdebug & 0x0001)
+			printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte);
+		return 0;
+	} else
+		return 1;
+}
+
+static int SCI_Control(IXJ *j, int control)
+{
+	switch (control) {
+	case SCI_End:
+		j->pld_scrw.bits.c0 = 0;	/* Set PLD Serial control interface */
+
+		j->pld_scrw.bits.c1 = 0;	/* to no selection */
+
+		break;
+	case SCI_Enable_DAA:
+		j->pld_scrw.bits.c0 = 1;	/* Set PLD Serial control interface */
+
+		j->pld_scrw.bits.c1 = 0;	/* to write to DAA */
+
+		break;
+	case SCI_Enable_Mixer:
+		j->pld_scrw.bits.c0 = 0;	/* Set PLD Serial control interface */
+
+		j->pld_scrw.bits.c1 = 1;	/* to write to mixer */
+
+		break;
+	case SCI_Enable_EEPROM:
+		j->pld_scrw.bits.c0 = 1;	/* Set PLD Serial control interface */
+
+		j->pld_scrw.bits.c1 = 1;	/* to write to EEPROM */
+
+		break;
+	default:
+		return 0;
+		break;
+	}
+	outb_p(j->pld_scrw.byte, j->XILINXbase);
+
+	switch (control) {
+	case SCI_End:
+		return 1;
+		break;
+	case SCI_Enable_DAA:
+	case SCI_Enable_Mixer:
+	case SCI_Enable_EEPROM:
+		if (!SCI_WaitHighSCI(j))
+			return 0;
+		break;
+	default:
+		return 0;
+		break;
+	}
+	return 1;
+}
+
+static int SCI_Prepare(IXJ *j)
+{
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	return 1;
+}
+
+static int ixj_get_mixer(long val, IXJ *j)
+{
+	int reg = (val & 0x1F00) >> 8;
+        return j->mix.vol[reg];
+}
+
+static int ixj_mixer(long val, IXJ *j)
+{
+	BYTES bytes;
+
+	bytes.high = (val & 0x1F00) >> 8;
+	bytes.low = val & 0x00FF;
+
+        /* save mixer value so we can get back later on */
+        j->mix.vol[bytes.high] = bytes.low;
+
+	outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03);	/* Load Mixer Address */
+
+	outb_p(bytes.low, j->XILINXbase + 0x02);	/* Load Mixer Data */
+
+	SCI_Control(j, SCI_Enable_Mixer);
+
+	SCI_Control(j, SCI_End);
+
+	return 0;
+}
+
+static int daa_load(BYTES * p_bytes, IXJ *j)
+{
+	outb_p(p_bytes->high, j->XILINXbase + 0x03);
+	outb_p(p_bytes->low, j->XILINXbase + 0x02);
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+	else
+		return 1;
+}
+
+static int ixj_daa_cr4(IXJ *j, char reg)
+{
+	BYTES bytes;
+
+	switch (j->daa_mode) {
+	case SOP_PU_SLEEP:
+		bytes.high = 0x14;
+		break;
+	case SOP_PU_RINGING:
+		bytes.high = 0x54;
+		break;
+	case SOP_PU_CONVERSATION:
+		bytes.high = 0x94;
+		break;
+	case SOP_PU_PULSEDIALING:
+		bytes.high = 0xD4;
+		break;
+	}
+
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg;
+
+	switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) {
+	case 0:
+		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0;
+		break;
+	case 1:
+		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2;
+		break;
+	case 2:
+		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1;
+		break;
+	case 3:
+		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3;
+		break;
+	}
+
+	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
+
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	return 1;
+}
+
+static char daa_int_read(IXJ *j)
+{
+	BYTES bytes;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	bytes.high = 0x38;
+	bytes.low = 0x00;
+	outb_p(bytes.high, j->XILINXbase + 0x03);
+	outb_p(bytes.low, j->XILINXbase + 0x02);
+
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+	if (bytes.low != ALISDAA_ID_BYTE) {
+		if (ixjdebug & 0x0001)
+			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+		return 0;
+	}
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
+
+	return 1;
+}
+
+static char daa_CR_read(IXJ *j, int cr)
+{
+	IXJ_WORD wdata;
+	BYTES bytes;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	switch (j->daa_mode) {
+	case SOP_PU_SLEEP:
+		bytes.high = 0x30 + cr;
+		break;
+	case SOP_PU_RINGING:
+		bytes.high = 0x70 + cr;
+		break;
+	case SOP_PU_CONVERSATION:
+		bytes.high = 0xB0 + cr;
+		break;
+	case SOP_PU_PULSEDIALING:
+	default:
+		bytes.high = 0xF0 + cr;
+		break;
+	}
+
+	bytes.low = 0x00;
+
+	outb_p(bytes.high, j->XILINXbase + 0x03);
+	outb_p(bytes.low, j->XILINXbase + 0x02);
+
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+	if (bytes.low != ALISDAA_ID_BYTE) {
+		if (ixjdebug & 0x0001)
+			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+		return 0;
+	}
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	wdata.word = inw_p(j->XILINXbase + 0x02);
+
+	switch(cr){
+		case 5:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high;
+			break;
+		case 4:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high;
+			break;
+		case 3:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high;
+			break;
+		case 2:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high;
+			break;
+		case 1:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high;
+			break;
+		case 0:
+			j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high;
+			break;
+		default:
+			return 0;
+	}
+	return 1;
+}
+
+static int ixj_daa_cid_reset(IXJ *j)
+{
+	int i;
+	BYTES bytes;
+
+	if (ixjdebug & 0x0002)
+		printk("DAA Clearing CID ram\n");
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	bytes.high = 0x58;
+	bytes.low = 0x00;
+	outb_p(bytes.high, j->XILINXbase + 0x03);
+	outb_p(bytes.low, j->XILINXbase + 0x02);
+
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	if (!SCI_WaitHighSCI(j))
+		return 0;
+
+	for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) {
+		bytes.high = bytes.low = 0x00;
+		outb_p(bytes.high, j->XILINXbase + 0x03);
+
+		if (i < ALISDAA_CALLERID_SIZE - 1)
+			outb_p(bytes.low, j->XILINXbase + 0x02);
+
+		if (!SCI_Control(j, SCI_Enable_DAA))
+			return 0;
+
+		if (!SCI_WaitHighSCI(j))
+			return 0;
+
+	}
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	if (ixjdebug & 0x0002)
+		printk("DAA CID ram cleared\n");
+
+	return 1;
+}
+
+static int ixj_daa_cid_read(IXJ *j)
+{
+	int i;
+	BYTES bytes;
+	char CID[ALISDAA_CALLERID_SIZE];
+	bool mContinue;
+	char *pIn, *pOut;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	bytes.high = 0x78;
+	bytes.low = 0x00;
+	outb_p(bytes.high, j->XILINXbase + 0x03);
+	outb_p(bytes.low, j->XILINXbase + 0x02);
+
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	if (!SCI_WaitHighSCI(j))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+	if (bytes.low != ALISDAA_ID_BYTE) {
+		if (ixjdebug & 0x0001)
+			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+		return 0;
+	}
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) {
+		bytes.high = bytes.low = 0x00;
+		outb_p(bytes.high, j->XILINXbase + 0x03);
+		outb_p(bytes.low, j->XILINXbase + 0x02);
+
+		if (!SCI_Control(j, SCI_Enable_DAA))
+			return 0;
+
+		if (!SCI_WaitHighSCI(j))
+			return 0;
+
+		CID[i + 0] = inb_p(j->XILINXbase + 0x03);
+		CID[i + 1] = inb_p(j->XILINXbase + 0x02);
+	}
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	pIn = CID;
+	pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
+	mContinue = true;
+	while (mContinue) {
+		if ((pIn[1] & 0x03) == 0x01) {
+			pOut[0] = pIn[0];
+		}
+		if ((pIn[2] & 0x0c) == 0x04) {
+			pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2);
+		}
+		if ((pIn[3] & 0x30) == 0x10) {
+			pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4);
+		}
+		if ((pIn[4] & 0xc0) == 0x40) {
+			pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6);
+		} else {
+			mContinue = false;
+		}
+		pIn += 5, pOut += 4;
+	}
+	memset(&j->cid, 0, sizeof(PHONE_CID));
+	pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
+	pOut += 4;
+	strncpy(j->cid.month, pOut, 2);
+	pOut += 2;
+	strncpy(j->cid.day, pOut, 2);
+	pOut += 2;
+	strncpy(j->cid.hour, pOut, 2);
+	pOut += 2;
+	strncpy(j->cid.min, pOut, 2);
+	pOut += 3;
+	j->cid.numlen = *pOut;
+	pOut += 1;
+	strncpy(j->cid.number, pOut, j->cid.numlen);
+	pOut += j->cid.numlen + 1;
+	j->cid.namelen = *pOut;
+	pOut += 1;
+	strncpy(j->cid.name, pOut, j->cid.namelen);
+
+	ixj_daa_cid_reset(j);
+	return 1;
+}
+
+static char daa_get_version(IXJ *j)
+{
+	BYTES bytes;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	bytes.high = 0x35;
+	bytes.low = 0x00;
+	outb_p(bytes.high, j->XILINXbase + 0x03);
+	outb_p(bytes.low, j->XILINXbase + 0x02);
+
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+	if (bytes.low != ALISDAA_ID_BYTE) {
+		if (ixjdebug & 0x0001)
+			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+		return 0;
+	}
+	if (!SCI_Control(j, SCI_Enable_DAA))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	bytes.high = inb_p(j->XILINXbase + 0x03);
+	bytes.low = inb_p(j->XILINXbase + 0x02);
+	if (ixjdebug & 0x0002)
+		printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low);
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
+	return bytes.high;
+}
+
+static int daa_set_mode(IXJ *j, int mode)
+{
+	/* NOTE:
+	      The DAA *MUST* be in the conversation mode if the
+	      PSTN line is to be seized (PSTN line off-hook).
+	      Taking the PSTN line off-hook while the DAA is in
+	      a mode other than conversation mode will cause a
+	      hardware failure of the ALIS-A part.
+
+	   NOTE:
+	      The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
+	      if the PSTN line is on-hook.  Failure to have the PSTN line
+	      in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
+	      ALIS-A part.
+	*/
+
+	BYTES bytes;
+
+	j->flags.pstn_rmr = 0;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	switch (mode) {
+	case SOP_PU_RESET:
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		j->pld_slicw.bits.rly2 = 0;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		bytes.high = 0x10;
+		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
+			return 0;
+
+		j->daa_mode = SOP_PU_SLEEP;
+		break;
+	case SOP_PU_SLEEP:
+		if(j->daa_mode == SOP_PU_SLEEP)
+		{
+			break;
+		}
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies);
+/*		if(j->daa_mode == SOP_PU_CONVERSATION) */
+		{
+			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+			outb_p(j->pld_scrw.byte, j->XILINXbase);
+			j->pld_slicw.bits.rly2 = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			bytes.high = 0x10;
+			bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+			daa_load(&bytes, j);
+			if (!SCI_Prepare(j))
+				return 0;
+		}
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		j->pld_slicw.bits.rly2 = 0;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		bytes.high = 0x10;
+		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
+			return 0;
+
+		j->daa_mode = SOP_PU_SLEEP;
+		j->flags.pstn_ringing = 0;
+		j->ex.bits.pstn_ring = 0;
+		j->pstn_sleeptil = jiffies + (hertz / 4);
+		wake_up_interruptible(&j->read_q);      /* Wake any blocked readers */
+		wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
+		wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
+ 		break;
+	case SOP_PU_RINGING:
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies);
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		j->pld_slicw.bits.rly2 = 0;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		bytes.high = 0x50;
+		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
+			return 0;
+		j->daa_mode = SOP_PU_RINGING;
+		break;
+	case SOP_PU_CONVERSATION:
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies);
+		bytes.high = 0x90;
+		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
+			return 0;
+		j->pld_slicw.bits.rly2 = 1;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		j->pld_scrw.bits.daafsyncen = 1;	/* Turn on DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		j->daa_mode = SOP_PU_CONVERSATION;
+		j->flags.pstn_ringing = 0;
+		j->ex.bits.pstn_ring = 0;
+		j->pstn_sleeptil = jiffies;
+		j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0;
+		break;
+	case SOP_PU_PULSEDIALING:
+		if (ixjdebug & 0x0008)
+			printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies);
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		j->pld_slicw.bits.rly2 = 0;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		bytes.high = 0xD0;
+		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+		daa_load(&bytes, j);
+		if (!SCI_Prepare(j))
+			return 0;
+		j->daa_mode = SOP_PU_PULSEDIALING;
+		break;
+	default:
+		break;
+	}
+	return 1;
+}
+
+static int ixj_daa_write(IXJ *j)
+{
+	BYTES bytes;
+
+	j->flags.pstncheck = 1;
+
+	daa_set_mode(j, SOP_PU_SLEEP);
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	outb_p(j->pld_scrw.byte, j->XILINXbase);
+
+	bytes.high = 0x14;
+	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg;
+	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg;
+	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	bytes.high = 0x1F;
+	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg;
+	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg;
+	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg;
+	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg;
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Prepare(j))
+		return 0;
+
+	bytes.high = 0x00;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x01;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x02;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x03;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x04;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x05;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x06;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x07;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x08;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x09;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x0A;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x0B;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x0C;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x0D;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x0E;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+	if (!SCI_WaitLowSCI(j))
+		return 0;
+
+	bytes.high = 0x0F;
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2];
+	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1];
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0];
+	bytes.low = 0x00;
+	if (!daa_load(&bytes, j))
+		return 0;
+
+	udelay(32);
+	j->pld_scrr.byte = inb_p(j->XILINXbase);
+	if (!SCI_Control(j, SCI_End))
+		return 0;
+
+	outb_p(j->pld_scrw.byte, j->XILINXbase);
+
+	if (ixjdebug & 0x0002)
+		printk("DAA Coefficients Loaded\n");
+
+	j->flags.pstncheck = 0;
+	return 1;
+}
+
+static int ixj_set_tone_off(unsigned short arg, IXJ *j)
+{
+	j->tone_off_time = arg;
+	if (ixj_WriteDSPCommand(0x6E05, j))		/* Set Tone Off Period */
+
+		return -1;
+	if (ixj_WriteDSPCommand(arg, j))
+		return -1;
+	return 0;
+}
+
+static int ixj_get_tone_on(IXJ *j)
+{
+	if (ixj_WriteDSPCommand(0x6E06, j))		/* Get Tone On Period */
+
+		return -1;
+	return 0;
+}
+
+static int ixj_get_tone_off(IXJ *j)
+{
+	if (ixj_WriteDSPCommand(0x6E07, j))		/* Get Tone Off Period */
+
+		return -1;
+	return 0;
+}
+
+static void ixj_busytone(IXJ *j)
+{
+	j->flags.ringback = 0;
+	j->flags.dialtone = 0;
+	j->flags.busytone = 1;
+	ixj_set_tone_on(0x07D0, j);
+	ixj_set_tone_off(0x07D0, j);
+	ixj_play_tone(j, 27);
+}
+
+static void ixj_dialtone(IXJ *j)
+{
+	j->flags.ringback = 0;
+	j->flags.dialtone = 1;
+	j->flags.busytone = 0;
+	if (j->dsp.low == 0x20) {
+		return;
+	} else {
+		ixj_set_tone_on(0xFFFF, j);
+		ixj_set_tone_off(0x0000, j);
+		ixj_play_tone(j, 25);
+	}
+}
+
+static void ixj_cpt_stop(IXJ *j)
+{
+	if(j->tone_state || j->tone_cadence_state)
+	{
+		j->flags.dialtone = 0;
+		j->flags.busytone = 0;
+		j->flags.ringback = 0;
+		ixj_set_tone_on(0x0001, j);
+		ixj_set_tone_off(0x0000, j);
+		ixj_play_tone(j, 0);
+		j->tone_state = j->tone_cadence_state = 0;
+		if (j->cadence_t) {
+			kfree(j->cadence_t->ce);
+			kfree(j->cadence_t);
+			j->cadence_t = NULL;
+		}
+	}
+	if (j->play_mode == -1 && j->rec_mode == -1)
+		idle(j);
+	if (j->play_mode != -1 && j->dsp.low == 0x20)
+		ixj_play_start(j);
+	if (j->rec_mode != -1 && j->dsp.low == 0x20)
+		ixj_record_start(j);
+}
+
+static void ixj_ringback(IXJ *j)
+{
+	j->flags.busytone = 0;
+	j->flags.dialtone = 0;
+	j->flags.ringback = 1;
+	ixj_set_tone_on(0x0FA0, j);
+	ixj_set_tone_off(0x2EE0, j);
+	ixj_play_tone(j, 26);
+}
+
+static void ixj_testram(IXJ *j)
+{
+	ixj_WriteDSPCommand(0x3001, j);	/* Test External SRAM */
+}
+
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp)
+{
+	ixj_cadence *lcp;
+	IXJ_CADENCE_ELEMENT __user *cep;
+	IXJ_CADENCE_ELEMENT *lcep;
+	IXJ_TONE ti;
+	int err;
+
+	lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL);
+	if (lcp == NULL)
+		return -ENOMEM;
+
+	err = -EFAULT;
+	if (copy_from_user(&lcp->elements_used,
+			   &cp->elements_used, sizeof(int)))
+		goto out;
+	if (copy_from_user(&lcp->termination,
+			   &cp->termination, sizeof(IXJ_CADENCE_TERM)))
+		goto out;
+	if (get_user(cep, &cp->ce))
+		goto out;
+
+	err = -EINVAL;
+	if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT))
+		goto out;
+
+	err = -ENOMEM;
+	lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
+	if (!lcep)
+		goto out;
+
+	err = -EFAULT;
+	if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
+		goto out1;
+
+	if (j->cadence_t) {
+		kfree(j->cadence_t->ce);
+		kfree(j->cadence_t);
+	}
+	lcp->ce = (void *) lcep;
+	j->cadence_t = lcp;
+	j->tone_cadence_state = 0;
+	ixj_set_tone_on(lcp->ce[0].tone_on_time, j);
+	ixj_set_tone_off(lcp->ce[0].tone_off_time, j);
+	if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
+		ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
+		ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
+		ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
+		ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
+		ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
+		ixj_init_tone(j, &ti);
+	}
+	ixj_play_tone(j, lcp->ce[0].index);
+	return 1;
+out1:
+	kfree(lcep);
+out:
+	kfree(lcp);
+	return err;
+}
+
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp)
+{
+	IXJ_FILTER_CADENCE *lcp;
+	lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE));
+	if (IS_ERR(lcp)) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n");
+		}
+		return PTR_ERR(lcp);
+        }
+	if (lcp->filter > 5) {
+		if(ixjdebug & 0x0001) {
+			printk(KERN_INFO "Cadence out of range\n");
+		}
+		kfree(lcp);
+		return -1;
+	}
+	j->cadence_f[lcp->filter].state = 0;
+	j->cadence_f[lcp->filter].enable = lcp->enable;
+	j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter;
+	j->cadence_f[lcp->filter].on1 = lcp->on1;
+	j->cadence_f[lcp->filter].on1min = 0;
+	j->cadence_f[lcp->filter].on1max = 0;
+	j->cadence_f[lcp->filter].off1 = lcp->off1;
+	j->cadence_f[lcp->filter].off1min = 0;
+	j->cadence_f[lcp->filter].off1max = 0;
+	j->cadence_f[lcp->filter].on2 = lcp->on2;
+	j->cadence_f[lcp->filter].on2min = 0;
+	j->cadence_f[lcp->filter].on2max = 0;
+	j->cadence_f[lcp->filter].off2 = lcp->off2;
+	j->cadence_f[lcp->filter].off2min = 0;
+	j->cadence_f[lcp->filter].off2max = 0;
+	j->cadence_f[lcp->filter].on3 = lcp->on3;
+	j->cadence_f[lcp->filter].on3min = 0;
+	j->cadence_f[lcp->filter].on3max = 0;
+	j->cadence_f[lcp->filter].off3 = lcp->off3;
+	j->cadence_f[lcp->filter].off3min = 0;
+	j->cadence_f[lcp->filter].off3max = 0;
+	if(ixjdebug & 0x0002) {
+		printk(KERN_INFO "Cadence %d loaded\n", lcp->filter);
+	}
+	kfree(lcp);
+	return 0;
+}
+
+static void add_caps(IXJ *j)
+{
+	j->caps = 0;
+	j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
+	strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
+	j->caplist[j->caps].captype = vendor;
+	j->caplist[j->caps].handle = j->caps++;
+	j->caplist[j->caps].captype = device;
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK");
+		break;
+	case QTI_LINEJACK:
+		strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK");
+		break;
+	case QTI_PHONEJACK_LITE:
+		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite");
+		break;
+	case QTI_PHONEJACK_PCI:
+		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI");
+		break;
+	case QTI_PHONECARD:
+		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD");
+		break;
+	}
+	j->caplist[j->caps].cap = j->cardtype;
+	j->caplist[j->caps].handle = j->caps++;
+	strcpy(j->caplist[j->caps].desc, "POTS");
+	j->caplist[j->caps].captype = port;
+	j->caplist[j->caps].cap = pots;
+	j->caplist[j->caps].handle = j->caps++;
+
+ 	/* add devices that can do speaker/mic */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+	case QTI_LINEJACK:
+	case QTI_PHONEJACK_PCI:
+	case QTI_PHONECARD:
+		strcpy(j->caplist[j->caps].desc, "SPEAKER");
+		j->caplist[j->caps].captype = port;
+		j->caplist[j->caps].cap = speaker;
+		j->caplist[j->caps].handle = j->caps++;
+        default:
+     		break;
+	}
+
+ 	/* add devices that can do handset */
+	switch (j->cardtype) {
+	case QTI_PHONEJACK:
+		strcpy(j->caplist[j->caps].desc, "HANDSET");
+		j->caplist[j->caps].captype = port;
+		j->caplist[j->caps].cap = handset;
+		j->caplist[j->caps].handle = j->caps++;
+		break;
+        default:
+     		break;
+	}
+
+ 	/* add devices that can do PSTN */
+	switch (j->cardtype) {
+	case QTI_LINEJACK:
+		strcpy(j->caplist[j->caps].desc, "PSTN");
+		j->caplist[j->caps].captype = port;
+		j->caplist[j->caps].cap = pstn;
+		j->caplist[j->caps].handle = j->caps++;
+		break;
+        default:
+     		break;
+	}
+
+	/* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */
+	strcpy(j->caplist[j->caps].desc, "ULAW");
+	j->caplist[j->caps].captype = codec;
+	j->caplist[j->caps].cap = ULAW;
+	j->caplist[j->caps].handle = j->caps++;
+
+	strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit");
+	j->caplist[j->caps].captype = codec;
+	j->caplist[j->caps].cap = LINEAR16;
+	j->caplist[j->caps].handle = j->caps++;
+
+	strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit");
+	j->caplist[j->caps].captype = codec;
+	j->caplist[j->caps].cap = LINEAR8;
+	j->caplist[j->caps].handle = j->caps++;
+
+	strcpy(j->caplist[j->caps].desc, "Windows Sound System");
+	j->caplist[j->caps].captype = codec;
+	j->caplist[j->caps].cap = WSS;
+	j->caplist[j->caps].handle = j->caps++;
+
+	/* software ALAW codec, made from ULAW */
+	strcpy(j->caplist[j->caps].desc, "ALAW");
+	j->caplist[j->caps].captype = codec;
+	j->caplist[j->caps].cap = ALAW;
+	j->caplist[j->caps].handle = j->caps++;
+
+	/* version 12 of the 8020 does the following codecs in a broken way */
+	if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
+		strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G723_63;
+		j->caplist[j->caps].handle = j->caps++;
+
+		strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G723_53;
+		j->caplist[j->caps].handle = j->caps++;
+
+		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = TS48;
+		j->caplist[j->caps].handle = j->caps++;
+
+		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = TS41;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+
+	/* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
+	if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
+		strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = TS85;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+
+	/* 8021 chips can do G728 */
+	if (j->dsp.low == 0x21) {
+		strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G728;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+
+	/* 8021/8022 chips can do G729 if loaded */
+	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
+		strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G729;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
+		strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
+		j->caplist[j->caps].captype = codec;
+		j->caplist[j->caps].cap = G729B;
+		j->caplist[j->caps].handle = j->caps++;
+	}
+}
+
+static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
+{
+	int cnt;
+	int retval = 0;
+	for (cnt = 0; cnt < j->caps; cnt++) {
+		if (pcreq->captype == j->caplist[cnt].captype
+		    && pcreq->cap == j->caplist[cnt].cap) {
+			retval = 1;
+			break;
+		}
+	}
+	return retval;
+}
+
+static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
+{
+	IXJ_TONE ti;
+	IXJ_FILTER jf;
+	IXJ_FILTER_RAW jfr;
+	void __user *argp = (void __user *)arg;
+	struct inode *inode = file_p->f_path.dentry->d_inode;
+	unsigned int minor = iminor(inode);
+	unsigned int raise, mant;
+	int board = NUM(inode);
+
+	IXJ *j = get_ixj(NUM(inode));
+
+	int retval = 0;
+
+	/*
+	 *    Set up locks to ensure that only one process is talking to the DSP at a time.
+	 *    This is necessary to keep the DSP from locking up.
+	 */
+	while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
+		schedule_timeout_interruptible(1);
+	if (ixjdebug & 0x0040)
+		printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+	if (minor >= IXJMAX) {
+		clear_bit(board, &j->busyflags);
+		return -ENODEV;
+	}
+	/*
+	 *    Check ioctls only root can use.
+	 */
+	if (!capable(CAP_SYS_ADMIN)) {
+		switch (cmd) {
+		case IXJCTL_TESTRAM:
+		case IXJCTL_HZ:
+			retval = -EPERM;
+		}
+	}
+	switch (cmd) {
+	case IXJCTL_TESTRAM:
+		ixj_testram(j);
+		retval = (j->ssr.high << 8) + j->ssr.low;
+		break;
+	case IXJCTL_CARDTYPE:
+		retval = j->cardtype;
+		break;
+	case IXJCTL_SERIAL:
+		retval = j->serial;
+		break;
+	case IXJCTL_VERSION:
+		{
+			char arg_str[100];
+			snprintf(arg_str, sizeof(arg_str),
+				"\nDriver version %i.%i.%i", IXJ_VER_MAJOR,
+				IXJ_VER_MINOR, IXJ_BLD_VER);
+			if (copy_to_user(argp, arg_str, strlen(arg_str)))
+				retval = -EFAULT;
+		}
+		break;
+	case PHONE_RING_CADENCE:
+		j->ring_cadence = arg;
+		break;
+	case IXJCTL_CIDCW:
+		if(arg) {
+			if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
+				retval = -EFAULT;
+				break;
+			}
+		} else {
+			memset(&j->cid_send, 0, sizeof(PHONE_CID));
+		}
+		ixj_write_cidcw(j);
+		break;
+        /* Binary compatbility */
+        case OLD_PHONE_RING_START:
+                arg = 0;
+                /* Fall through */
+ 	case PHONE_RING_START:
+		if(arg) {
+			if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
+				retval = -EFAULT;
+				break;
+			}
+			ixj_write_cid(j);
+		} else {
+			memset(&j->cid_send, 0, sizeof(PHONE_CID));
+		}
+		ixj_ring_start(j);
+		break;
+	case PHONE_RING_STOP:
+		j->flags.cringing = 0;
+		if(j->cadence_f[5].enable) {
+			j->cadence_f[5].state = 0;
+		}
+		ixj_ring_off(j);
+		break;
+	case PHONE_RING:
+		retval = ixj_ring(j);
+		break;
+	case PHONE_EXCEPTION:
+		retval = j->ex.bytes;
+		if(j->ex.bits.flash) {
+			j->flash_end = 0;
+			j->ex.bits.flash = 0;
+		}
+		j->ex.bits.pstn_ring = 0;
+		j->ex.bits.caller_id = 0;
+		j->ex.bits.pstn_wink = 0;
+		j->ex.bits.f0 = 0;
+		j->ex.bits.f1 = 0;
+		j->ex.bits.f2 = 0;
+		j->ex.bits.f3 = 0;
+		j->ex.bits.fc0 = 0;
+		j->ex.bits.fc1 = 0;
+		j->ex.bits.fc2 = 0;
+		j->ex.bits.fc3 = 0;
+		j->ex.bits.reserved = 0;
+		break;
+	case PHONE_HOOKSTATE:
+		j->ex.bits.hookstate = 0;
+		retval = j->hookstate;  //j->r_hook;
+		break;
+	case IXJCTL_SET_LED:
+		LED_SetState(arg, j);
+		break;
+	case PHONE_FRAME:
+		retval = set_base_frame(j, arg);
+		break;
+	case PHONE_REC_CODEC:
+		retval = set_rec_codec(j, arg);
+		break;
+	case PHONE_VAD:
+		ixj_vad(j, arg);
+		break;
+	case PHONE_REC_START:
+		ixj_record_start(j);
+		break;
+	case PHONE_REC_STOP:
+		ixj_record_stop(j);
+		break;
+	case PHONE_REC_DEPTH:
+		set_rec_depth(j, arg);
+		break;
+	case PHONE_REC_VOLUME:
+		if(arg == -1) {
+			retval = get_rec_volume(j);
+		}
+		else {
+			set_rec_volume(j, arg);
+			retval = arg;
+		}
+		break;
+	case PHONE_REC_VOLUME_LINEAR:
+		if(arg == -1) {
+			retval = get_rec_volume_linear(j);
+		}
+		else {
+			set_rec_volume_linear(j, arg);
+			retval = arg;
+		}
+		break;
+	case IXJCTL_DTMF_PRESCALE:
+		if(arg == -1) {
+			retval = get_dtmf_prescale(j);
+		}
+		else {
+			set_dtmf_prescale(j, arg);
+			retval = arg;
+		}
+		break;
+	case PHONE_REC_LEVEL:
+		retval = get_rec_level(j);
+		break;
+	case IXJCTL_SC_RXG:
+		retval = ixj_siadc(j, arg);
+		break;
+	case IXJCTL_SC_TXG:
+		retval = ixj_sidac(j, arg);
+		break;
+	case IXJCTL_AEC_START:
+		ixj_aec_start(j, arg);
+		break;
+	case IXJCTL_AEC_STOP:
+		aec_stop(j);
+		break;
+	case IXJCTL_AEC_GET_LEVEL:
+		retval = j->aec_level;
+		break;
+	case PHONE_PLAY_CODEC:
+		retval = set_play_codec(j, arg);
+		break;
+	case PHONE_PLAY_START:
+		retval = ixj_play_start(j);
+		break;
+	case PHONE_PLAY_STOP:
+		ixj_play_stop(j);
+		break;
+	case PHONE_PLAY_DEPTH:
+		set_play_depth(j, arg);
+		break;
+	case PHONE_PLAY_VOLUME:
+		if(arg == -1) {
+			retval = get_play_volume(j);
+		}
+		else {
+			set_play_volume(j, arg);
+			retval = arg;
+		}
+		break;
+	case PHONE_PLAY_VOLUME_LINEAR:
+		if(arg == -1) {
+			retval = get_play_volume_linear(j);
+		}
+		else {
+			set_play_volume_linear(j, arg);
+			retval = arg;
+		}
+		break;
+	case PHONE_PLAY_LEVEL:
+		retval = get_play_level(j);
+		break;
+	case IXJCTL_DSP_TYPE:
+		retval = (j->dsp.high << 8) + j->dsp.low;
+		break;
+	case IXJCTL_DSP_VERSION:
+		retval = (j->ver.high << 8) + j->ver.low;
+		break;
+	case IXJCTL_HZ:
+		hertz = arg;
+		break;
+	case IXJCTL_RATE:
+		if (arg > hertz)
+			retval = -1;
+		else
+			samplerate = arg;
+		break;
+	case IXJCTL_DRYBUFFER_READ:
+		put_user(j->drybuffer, (unsigned long __user *) argp);
+		break;
+	case IXJCTL_DRYBUFFER_CLEAR:
+		j->drybuffer = 0;
+		break;
+	case IXJCTL_FRAMES_READ:
+		put_user(j->framesread, (unsigned long __user *) argp);
+		break;
+	case IXJCTL_FRAMES_WRITTEN:
+		put_user(j->frameswritten, (unsigned long __user *) argp);
+		break;
+	case IXJCTL_READ_WAIT:
+		put_user(j->read_wait, (unsigned long __user *) argp);
+		break;
+	case IXJCTL_WRITE_WAIT:
+		put_user(j->write_wait, (unsigned long __user *) argp);
+		break;
+	case PHONE_MAXRINGS:
+		j->maxrings = arg;
+		break;
+	case PHONE_SET_TONE_ON_TIME:
+		ixj_set_tone_on(arg, j);
+		break;
+	case PHONE_SET_TONE_OFF_TIME:
+		ixj_set_tone_off(arg, j);
+		break;
+	case PHONE_GET_TONE_ON_TIME:
+		if (ixj_get_tone_on(j)) {
+			retval = -1;
+		} else {
+			retval = (j->ssr.high << 8) + j->ssr.low;
+		}
+		break;
+	case PHONE_GET_TONE_OFF_TIME:
+		if (ixj_get_tone_off(j)) {
+			retval = -1;
+		} else {
+			retval = (j->ssr.high << 8) + j->ssr.low;
+		}
+		break;
+	case PHONE_PLAY_TONE:
+		if (!j->tone_state)
+			retval = ixj_play_tone(j, arg);
+		else
+			retval = -1;
+		break;
+	case PHONE_GET_TONE_STATE:
+		retval = j->tone_state;
+		break;
+	case PHONE_DTMF_READY:
+		retval = j->ex.bits.dtmf_ready;
+		break;
+	case PHONE_GET_DTMF:
+		if (ixj_hookstate(j)) {
+			if (j->dtmf_rp != j->dtmf_wp) {
+				retval = j->dtmfbuffer[j->dtmf_rp];
+				j->dtmf_rp++;
+				if (j->dtmf_rp == 79)
+					j->dtmf_rp = 0;
+				if (j->dtmf_rp == j->dtmf_wp) {
+					j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
+				}
+			}
+		}
+		break;
+	case PHONE_GET_DTMF_ASCII:
+		if (ixj_hookstate(j)) {
+			if (j->dtmf_rp != j->dtmf_wp) {
+				switch (j->dtmfbuffer[j->dtmf_rp]) {
+				case 10:
+					retval = 42;	/* '*'; */
+
+					break;
+				case 11:
+					retval = 48;	/*'0'; */
+
+					break;
+				case 12:
+					retval = 35;	/*'#'; */
+
+					break;
+				case 28:
+					retval = 65;	/*'A'; */
+
+					break;
+				case 29:
+					retval = 66;	/*'B'; */
+
+					break;
+				case 30:
+					retval = 67;	/*'C'; */
+
+					break;
+				case 31:
+					retval = 68;	/*'D'; */
+
+					break;
+				default:
+					retval = 48 + j->dtmfbuffer[j->dtmf_rp];
+					break;
+				}
+				j->dtmf_rp++;
+				if (j->dtmf_rp == 79)
+					j->dtmf_rp = 0;
+				if(j->dtmf_rp == j->dtmf_wp)
+				{
+					j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
+				}
+			}
+		}
+		break;
+	case PHONE_DTMF_OOB:
+		j->flags.dtmf_oob = arg;
+		break;
+	case PHONE_DIALTONE:
+		ixj_dialtone(j);
+		break;
+	case PHONE_BUSY:
+		ixj_busytone(j);
+		break;
+	case PHONE_RINGBACK:
+		ixj_ringback(j);
+		break;
+	case PHONE_WINK:
+		if(j->cardtype == QTI_PHONEJACK) 
+			retval = -1;
+		else 
+			retval = ixj_wink(j);
+		break;
+	case PHONE_CPT_STOP:
+		ixj_cpt_stop(j);
+		break;
+        case PHONE_QUERY_CODEC:
+        {
+                struct phone_codec_data pd;
+                int val;
+                int proto_size[] = {
+                        -1,
+                        12, 10, 16, 9, 8, 48, 5,
+                        40, 40, 80, 40, 40, 6
+                };
+                if(copy_from_user(&pd, argp, sizeof(pd))) {
+                        retval = -EFAULT;
+			break;
+		}
+                if(pd.type<1 || pd.type>13) {
+                        retval = -EPROTONOSUPPORT;
+			break;
+		}
+                if(pd.type<G729)
+                        val=proto_size[pd.type];
+                else switch(j->baseframe.low)
+                {
+                        case 0xA0:val=2*proto_size[pd.type];break;
+                        case 0x50:val=proto_size[pd.type];break;
+                        default:val=proto_size[pd.type]*3;break;
+                }
+                pd.buf_min=pd.buf_max=pd.buf_opt=val;
+                if(copy_to_user(argp, &pd, sizeof(pd)))
+                        retval = -EFAULT;
+        	break;
+        }
+	case IXJCTL_DSP_IDLE:
+		idle(j);
+		break;
+	case IXJCTL_MIXER:
+                if ((arg & 0xff) == 0xff)
+			retval = ixj_get_mixer(arg, j);
+                else
+			ixj_mixer(arg, j);
+		break;
+	case IXJCTL_DAA_COEFF_SET:
+		switch (arg) {
+		case DAA_US:
+			DAA_Coeff_US(j);
+			retval = ixj_daa_write(j);
+			break;
+		case DAA_UK:
+			DAA_Coeff_UK(j);
+			retval = ixj_daa_write(j);
+			break;
+		case DAA_FRANCE:
+			DAA_Coeff_France(j);
+			retval = ixj_daa_write(j);
+			break;
+		case DAA_GERMANY:
+			DAA_Coeff_Germany(j);
+			retval = ixj_daa_write(j);
+			break;
+		case DAA_AUSTRALIA:
+			DAA_Coeff_Australia(j);
+			retval = ixj_daa_write(j);
+			break;
+		case DAA_JAPAN:
+			DAA_Coeff_Japan(j);
+			retval = ixj_daa_write(j);
+			break;
+		default:
+			retval = 1;
+			break;
+		}
+		break;
+	case IXJCTL_DAA_AGAIN:
+		ixj_daa_cr4(j, arg | 0x02);
+		break;
+	case IXJCTL_PSTN_LINETEST:
+		retval = ixj_linetest(j);
+		break;
+	case IXJCTL_VMWI:
+		ixj_write_vmwi(j, arg);
+		break;
+	case IXJCTL_CID:
+		if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) 
+			retval = -EFAULT;
+		j->ex.bits.caller_id = 0;
+		break;
+	case IXJCTL_WINK_DURATION:
+		j->winktime = arg;
+		break;
+	case IXJCTL_PORT:
+		if (arg)
+			retval = ixj_set_port(j, arg);
+		else
+			retval = j->port;
+		break;
+	case IXJCTL_POTS_PSTN:
+		retval = ixj_set_pots(j, arg);
+		break;
+	case PHONE_CAPABILITIES:
+		add_caps(j);
+		retval = j->caps;
+		break;
+	case PHONE_CAPABILITIES_LIST:
+		add_caps(j);
+		if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) 
+			retval = -EFAULT;
+		break;
+	case PHONE_CAPABILITIES_CHECK:
+		{
+			struct phone_capability cap;
+			if (copy_from_user(&cap, argp, sizeof(cap))) 
+				retval = -EFAULT;
+			else {
+				add_caps(j);
+				retval = capabilities_check(j, &cap);
+			}
+		}
+		break;
+	case PHONE_PSTN_SET_STATE:
+		daa_set_mode(j, arg);
+		break;
+	case PHONE_PSTN_GET_STATE:
+		retval = j->daa_mode;
+		j->ex.bits.pstn_ring = 0;
+		break;
+	case IXJCTL_SET_FILTER:
+		if (copy_from_user(&jf, argp, sizeof(jf))) 
+			retval = -EFAULT;
+		else
+			retval = ixj_init_filter(j, &jf);
+		break;
+	case IXJCTL_SET_FILTER_RAW:
+		if (copy_from_user(&jfr, argp, sizeof(jfr))) 
+			retval = -EFAULT;
+		else
+			retval = ixj_init_filter_raw(j, &jfr);
+		break;
+	case IXJCTL_GET_FILTER_HIST:
+		if(arg<0||arg>3)
+			retval = -EINVAL;
+		else
+			retval = j->filter_hist[arg];
+		break;
+	case IXJCTL_INIT_TONE:
+		if (copy_from_user(&ti, argp, sizeof(ti)))
+			retval = -EFAULT;
+		else
+			retval = ixj_init_tone(j, &ti);
+		break;
+	case IXJCTL_TONE_CADENCE:
+		retval = ixj_build_cadence(j, argp);
+		break;
+	case IXJCTL_FILTER_CADENCE:
+		retval = ixj_build_filter_cadence(j, argp);
+		break;
+	case IXJCTL_SIGCTL:
+		if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {
+			retval = -EFAULT;
+			break;
+		}
+		j->ixj_signals[j->sigdef.event] = j->sigdef.signal;
+		if(j->sigdef.event < 33) {
+			raise = 1;
+			for(mant = 0; mant < j->sigdef.event; mant++){
+				raise *= 2;
+			}
+			if(j->sigdef.signal)
+				j->ex_sig.bytes |= raise; 
+			else
+				j->ex_sig.bytes &= (raise^0xffff); 
+		}
+		break;
+	case IXJCTL_INTERCOM_STOP:
+		if(arg < 0 || arg >= IXJMAX)
+			return -EINVAL;
+		j->intercom = -1;
+		ixj_record_stop(j);
+		ixj_play_stop(j);
+		idle(j);
+		get_ixj(arg)->intercom = -1;
+		ixj_record_stop(get_ixj(arg));
+		ixj_play_stop(get_ixj(arg));
+		idle(get_ixj(arg));
+		break;
+	case IXJCTL_INTERCOM_START:
+		if(arg < 0 || arg >= IXJMAX)
+			return -EINVAL;
+		j->intercom = arg;
+		ixj_record_start(j);
+		ixj_play_start(j);
+		get_ixj(arg)->intercom = board;
+		ixj_play_start(get_ixj(arg));
+		ixj_record_start(get_ixj(arg));
+		break;
+	}
+	if (ixjdebug & 0x0040)
+		printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+	clear_bit(board, &j->busyflags);
+	return retval;
+}
+
+static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+	mutex_lock(&ixj_mutex);
+	ret = do_ixj_ioctl(file_p, cmd, arg);
+	mutex_unlock(&ixj_mutex);
+	return ret;
+}
+
+static int ixj_fasync(int fd, struct file *file_p, int mode)
+{
+	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
+
+	return fasync_helper(fd, file_p, mode, &j->async_queue);
+}
+
+static const struct file_operations ixj_fops =
+{
+        .owner          = THIS_MODULE,
+        .read           = ixj_enhanced_read,
+        .write          = ixj_enhanced_write,
+        .poll           = ixj_poll,
+        .unlocked_ioctl = ixj_ioctl,
+        .release        = ixj_release,
+        .fasync         = ixj_fasync,
+        .llseek	 = default_llseek,
+};
+
+static int ixj_linetest(IXJ *j)
+{
+	j->flags.pstncheck = 1;	/* Testing */
+	j->flags.pstn_present = 0; /* Assume the line is not there */
+
+	daa_int_read(j);	/*Clear DAA Interrupt flags */
+	/* */
+	/* Hold all relays in the normally de-energized position. */
+	/* */
+
+	j->pld_slicw.bits.rly1 = 0;
+	j->pld_slicw.bits.rly2 = 0;
+	j->pld_slicw.bits.rly3 = 0;
+	outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+	j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+	outb_p(j->pld_scrw.byte, j->XILINXbase);
+	j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
+	if (j->pld_slicr.bits.potspstn) {
+		j->flags.pots_pstn = 1;
+		j->flags.pots_correct = 0;
+		LED_SetState(0x4, j);
+	} else {
+		j->flags.pots_pstn = 0;
+		j->pld_slicw.bits.rly1 = 0;
+		j->pld_slicw.bits.rly2 = 0;
+		j->pld_slicw.bits.rly3 = 1;
+		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+		outb_p(j->pld_scrw.byte, j->XILINXbase);
+		daa_set_mode(j, SOP_PU_CONVERSATION);
+		msleep(1000);
+		daa_int_read(j);
+		daa_set_mode(j, SOP_PU_RESET);
+		if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+			j->flags.pots_correct = 0;	/* Should not be line voltage on POTS port. */
+			LED_SetState(0x4, j);
+			j->pld_slicw.bits.rly3 = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		} else {
+			j->flags.pots_correct = 1;
+			LED_SetState(0x8, j);
+			j->pld_slicw.bits.rly1 = 1;
+			j->pld_slicw.bits.rly2 = 0;
+			j->pld_slicw.bits.rly3 = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+		}
+	}
+	j->pld_slicw.bits.rly3 = 0;
+	outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+	daa_set_mode(j, SOP_PU_CONVERSATION);
+	msleep(1000);
+	daa_int_read(j);
+	daa_set_mode(j, SOP_PU_RESET);
+	if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+		j->pstn_sleeptil = jiffies + (hertz / 4);
+		j->flags.pstn_present = 1;
+	} else {
+		j->flags.pstn_present = 0;
+	}
+	if (j->flags.pstn_present) {
+		if (j->flags.pots_correct) {
+			LED_SetState(0xA, j);
+		} else {
+			LED_SetState(0x6, j);
+		}
+	} else {
+		if (j->flags.pots_correct) {
+			LED_SetState(0x9, j);
+		} else {
+			LED_SetState(0x5, j);
+		}
+	}
+	j->flags.pstncheck = 0;	/* Testing */
+	return j->flags.pstn_present;
+}
+
+static int ixj_selfprobe(IXJ *j)
+{
+	unsigned short cmd;
+	int cnt;
+	BYTES bytes;
+
+        init_waitqueue_head(&j->poll_q);
+        init_waitqueue_head(&j->read_q);
+        init_waitqueue_head(&j->write_q);
+
+	while(atomic_read(&j->DSPWrite) > 0)
+		atomic_dec(&j->DSPWrite);
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Write IDLE to Software Control Register\n");
+	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
+
+	if (ixj_WriteDSPCommand(0x0000, j))		/* Write IDLE to Software Control Register */
+		return -1;
+/* The read values of the SSR should be 0x00 for the IDLE command */
+	if (j->ssr.low || j->ssr.high)
+		return -1;
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Get Device ID Code\n");
+	if (ixj_WriteDSPCommand(0x3400, j))		/* Get Device ID Code */
+		return -1;
+	j->dsp.low = j->ssr.low;
+	j->dsp.high = j->ssr.high;
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Get Device Version Code\n");
+	if (ixj_WriteDSPCommand(0x3800, j))		/* Get Device Version Code */
+		return -1;
+	j->ver.low = j->ssr.low;
+	j->ver.high = j->ssr.high;
+	if (!j->cardtype) {
+		if (j->dsp.low == 0x21) {
+			bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
+			outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
+/* Test for Internet LineJACK or Internet PhoneJACK Lite */
+			bytes.low = inb_p(j->XILINXbase + 0x02);
+			if (bytes.low == bytes.high)	/*  Register is read only on */
+				/*  Internet PhoneJack Lite */
+			 {
+				j->cardtype = QTI_PHONEJACK_LITE;
+				if (!request_region(j->XILINXbase, 4, "ixj control")) {
+					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
+					return -1;
+				}
+				j->pld_slicw.pcib.e1 = 1;
+				outb_p(j->pld_slicw.byte, j->XILINXbase);
+			} else {
+				j->cardtype = QTI_LINEJACK;
+
+				if (!request_region(j->XILINXbase, 8, "ixj control")) {
+					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
+					return -1;
+				}
+			}
+		} else if (j->dsp.low == 0x22) {
+			j->cardtype = QTI_PHONEJACK_PCI;
+			request_region(j->XILINXbase, 4, "ixj control");
+			j->pld_slicw.pcib.e1 = 1;
+			outb_p(j->pld_slicw.byte, j->XILINXbase);
+		} else
+			j->cardtype = QTI_PHONEJACK;
+	} else {
+		switch (j->cardtype) {
+		case QTI_PHONEJACK:
+			if (!j->dsp.low != 0x20) {
+				j->dsp.high = 0x80;
+				j->dsp.low = 0x20;
+				ixj_WriteDSPCommand(0x3800, j);
+				j->ver.low = j->ssr.low;
+				j->ver.high = j->ssr.high;
+			}
+			break;
+		case QTI_LINEJACK:
+			if (!request_region(j->XILINXbase, 8, "ixj control")) {
+				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
+				return -1;
+			}
+			break;
+		case QTI_PHONEJACK_LITE:
+		case QTI_PHONEJACK_PCI:
+			if (!request_region(j->XILINXbase, 4, "ixj control")) {
+				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
+				return -1;
+			}
+			j->pld_slicw.pcib.e1 = 1;
+			outb_p(j->pld_slicw.byte, j->XILINXbase);
+			break;
+		case QTI_PHONECARD:
+			break;
+		}
+	}
+	if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
+		if (ixj_WriteDSPCommand(0xC462, j))		/* Write CODEC config to Software Control Register */
+			return -1;
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
+		if (j->cardtype == QTI_PHONEJACK) {
+			cmd = 0x9FF2;
+		} else {
+			cmd = 0x9FF5;
+		}
+		if (ixj_WriteDSPCommand(cmd, j))	/* Write CODEC timing to Software Control Register */
+			return -1;
+	} else {
+		if (set_base_frame(j, 30) != 30)
+			return -1;
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
+		if (j->cardtype == QTI_PHONECARD) {
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to Software Control Register */
+				return -1;
+		}
+		if (j->cardtype == QTI_LINEJACK) {
+			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to Software Control Register */
+				return -1;
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
+			j->pld_clock.byte = 0;
+			outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
+		}
+	}
+
+	if (j->dsp.low == 0x20) {
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Configure GPIO pins\n");
+		j->gpio.bytes.high = 0x09;
+/*  bytes.low = 0xEF;  0xF7 */
+		j->gpio.bits.gpio1 = 1;
+		j->gpio.bits.gpio2 = 1;
+		j->gpio.bits.gpio3 = 0;
+		j->gpio.bits.gpio4 = 1;
+		j->gpio.bits.gpio5 = 1;
+		j->gpio.bits.gpio6 = 1;
+		j->gpio.bits.gpio7 = 1;
+		ixj_WriteDSPCommand(j->gpio.word, j);	/* Set GPIO pin directions */
+		if (ixjdebug & 0x0002)
+			printk(KERN_INFO "Enable SLIC\n");
+		j->gpio.bytes.high = 0x0B;
+		j->gpio.bytes.low = 0x00;
+		j->gpio.bits.gpio1 = 0;
+		j->gpio.bits.gpio2 = 1;
+		j->gpio.bits.gpio5 = 0;
+		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring stop signal */
+		j->port = PORT_POTS;
+	} else {
+		if (j->cardtype == QTI_LINEJACK) {
+			LED_SetState(0x1, j);
+			msleep(100);
+			LED_SetState(0x2, j);
+			msleep(100);
+			LED_SetState(0x4, j);
+			msleep(100);
+			LED_SetState(0x8, j);
+			msleep(100);
+			LED_SetState(0x0, j);
+			daa_get_version(j);
+			if (ixjdebug & 0x0002)
+				printk("Loading DAA Coefficients\n");
+			DAA_Coeff_US(j);
+			if (!ixj_daa_write(j)) {
+				printk("DAA write failed on board %d\n", j->board);
+				return -1;
+			}
+			if(!ixj_daa_cid_reset(j)) {
+				printk("DAA CID reset failed on board %d\n", j->board);
+				return -1;
+			}
+			j->flags.pots_correct = 0;
+			j->flags.pstn_present = 0;
+			ixj_linetest(j);
+			if (j->flags.pots_correct) {
+				j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+				outb_p(j->pld_scrw.byte, j->XILINXbase);
+				j->pld_slicw.bits.rly1 = 1;
+				j->pld_slicw.bits.spken = 1;
+				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+				SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
+				j->port = PORT_POTS;
+			}
+			ixj_set_port(j, PORT_PSTN);
+			ixj_set_pots(j, 1);
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "Enable Mixer\n");
+			ixj_mixer(0x0000, j);	/*Master Volume Left unmute 0db */
+			ixj_mixer(0x0100, j);	/*Master Volume Right unmute 0db */
+
+			ixj_mixer(0x0203, j);	/*Voice Left Volume unmute 6db */
+			ixj_mixer(0x0303, j);	/*Voice Right Volume unmute 6db */
+
+			ixj_mixer(0x0480, j);	/*FM Left mute */
+			ixj_mixer(0x0580, j);	/*FM Right mute */
+
+			ixj_mixer(0x0680, j);	/*CD Left mute */
+			ixj_mixer(0x0780, j);	/*CD Right mute */
+
+			ixj_mixer(0x0880, j);	/*Line Left mute */
+			ixj_mixer(0x0980, j);	/*Line Right mute */
+
+			ixj_mixer(0x0A80, j);	/*Aux left mute  */
+			ixj_mixer(0x0B80, j);	/*Aux right mute */
+
+			ixj_mixer(0x0C00, j);	/*Mono1 unmute 12db */
+			ixj_mixer(0x0D80, j);	/*Mono2 mute */
+
+			ixj_mixer(0x0E80, j);	/*Mic mute */
+
+			ixj_mixer(0x0F00, j);	/*Mono Out Volume unmute 0db */
+
+			ixj_mixer(0x1000, j);	/*Voice Left and Right out only */
+			ixj_mixer(0x110C, j);
+
+
+			ixj_mixer(0x1200, j);	/*Mono1 switch on mixer left */
+			ixj_mixer(0x1401, j);
+
+			ixj_mixer(0x1300, j);       /*Mono1 switch on mixer right */
+			ixj_mixer(0x1501, j);
+
+			ixj_mixer(0x1700, j);	/*Clock select */
+
+			ixj_mixer(0x1800, j);	/*ADC input from mixer */
+
+			ixj_mixer(0x1901, j);	/*Mic gain 30db */
+
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "Setting Default US Ring Cadence Detection\n");
+			j->cadence_f[4].state = 0;
+			j->cadence_f[4].on1 = 0;	/*Cadence Filter 4 is used for PSTN ring cadence */
+			j->cadence_f[4].off1 = 0;
+			j->cadence_f[4].on2 = 0;
+			j->cadence_f[4].off2 = 0;
+			j->cadence_f[4].on3 = 0;
+			j->cadence_f[4].off3 = 0;	/* These should represent standard US ring pulse. */
+			j->pstn_last_rmr = jiffies;
+
+		} else {
+			if (j->cardtype == QTI_PHONECARD) {
+				ixj_WriteDSPCommand(0xCF07, j);
+				ixj_WriteDSPCommand(0x00B0, j);
+				ixj_set_port(j, PORT_SPEAKER);
+			} else {
+				ixj_set_port(j, PORT_POTS);
+				SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
+			}
+		}
+	}
+
+	j->intercom = -1;
+	j->framesread = j->frameswritten = 0;
+	j->read_wait = j->write_wait = 0;
+	j->rxreadycheck = j->txreadycheck = 0;
+
+	/* initialise the DTMF prescale to a sensible value */
+	if (j->cardtype == QTI_LINEJACK) {
+		set_dtmf_prescale(j, 0x10); 
+	} else {
+		set_dtmf_prescale(j, 0x40); 
+	}
+	set_play_volume(j, 0x100);
+	set_rec_volume(j, 0x100);
+
+	if (ixj_WriteDSPCommand(0x0000, j))		/* Write IDLE to Software Control Register */
+		return -1;
+/* The read values of the SSR should be 0x00 for the IDLE command */
+	if (j->ssr.low || j->ssr.high)
+		return -1;
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Enable Line Monitor\n");
+
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
+
+	if (ixj_WriteDSPCommand(0x7E01, j))		/* Asynchronous Line Monitor */
+		return -1;
+
+	if (ixjdebug & 0x002)
+		printk(KERN_INFO "Enable DTMF Detectors\n");
+
+	if (ixj_WriteDSPCommand(0x5151, j))		/* Enable DTMF detection */
+		return -1;
+
+	if (ixj_WriteDSPCommand(0x6E01, j))		/* Set Asyncronous Tone Generation */
+		return -1;
+
+	set_rec_depth(j, 2);	/* Set Record Channel Limit to 2 frames */
+
+	set_play_depth(j, 2);	/* Set Playback Channel Limit to 2 frames */
+
+	j->ex.bits.dtmf_ready = 0;
+	j->dtmf_state = 0;
+	j->dtmf_wp = j->dtmf_rp = 0;
+	j->rec_mode = j->play_mode = -1;
+	j->flags.ringing = 0;
+	j->maxrings = MAXRINGS;
+	j->ring_cadence = USA_RING_CADENCE;
+	j->drybuffer = 0;
+	j->winktime = 320;
+	j->flags.dtmf_oob = 0;
+	for (cnt = 0; cnt < 4; cnt++)
+		j->cadence_f[cnt].enable = 0;
+	/* must be a device on the specified address */
+	ixj_WriteDSPCommand(0x0FE3, j);	/* Put the DSP in 1/5 power mode. */
+
+	/* Set up the default signals for events */
+	for (cnt = 0; cnt < 35; cnt++)
+		j->ixj_signals[cnt] = SIGIO;
+
+	/* Set the excetion signal enable flags */
+	j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
+	j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
+	j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
+#ifdef IXJ_DYN_ALLOC
+	j->fskdata = NULL;
+#endif
+	j->fskdcnt = 0;
+	j->cidcw_wait = 0;
+ 
+	/* Register with the Telephony for Linux subsystem */
+	j->p.f_op = &ixj_fops;
+	j->p.open = ixj_open;
+	j->p.board = j->board;
+	phone_register_device(&j->p, PHONE_UNIT_ANY);
+
+	ixj_init_timer(j);
+	ixj_add_timer(j);
+	return 0;
+}
+
+/*
+ *	Exported service for pcmcia card handling
+ */
+ 
+IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx)
+{
+	IXJ *j = ixj_alloc();
+
+	j->board = 0;
+
+	j->DSPbase = dsp;
+	j->XILINXbase = xilinx;
+	j->cardtype = QTI_PHONECARD;
+	ixj_selfprobe(j);
+	return j;
+}
+
+EXPORT_SYMBOL(ixj_pcmcia_probe);		/* Fpr PCMCIA */
+
+static int ixj_get_status_proc(char *buf)
+{
+	int len;
+	int cnt;
+	IXJ *j;
+	len = 0;
+	len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
+	len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ));
+	len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS));
+	len += sprintf(buf + len, "\nUsing old telephony API");
+	len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug);
+
+	for (cnt = 0; cnt < IXJMAX; cnt++) {
+		j = get_ixj(cnt);
+		if(j==NULL)
+			continue;
+		if (j->DSPbase) {
+			len += sprintf(buf + len, "\nCard Num %d", cnt);
+			len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
+			if (j->cardtype != QTI_PHONEJACK)
+				len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase);
+			len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low);
+			len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low);
+			len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial);
+			switch (j->cardtype) {
+			case (QTI_PHONEJACK):
+				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK");
+				break;
+			case (QTI_LINEJACK):
+				len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
+				if (j->flags.g729_loaded)
+					len += sprintf(buf + len, " w/G.729 A/B");
+				len += sprintf(buf + len, " Country = %d", j->daa_country);
+				break;
+			case (QTI_PHONEJACK_LITE):
+				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
+				if (j->flags.g729_loaded)
+					len += sprintf(buf + len, " w/G.729 A/B");
+				break;
+			case (QTI_PHONEJACK_PCI):
+				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI");
+				if (j->flags.g729_loaded)
+					len += sprintf(buf + len, " w/G.729 A/B");
+				break;
+			case (QTI_PHONECARD):
+				len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD");
+				if (j->flags.g729_loaded)
+					len += sprintf(buf + len, " w/G.729 A/B");
+				len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : "");
+				if (!j->pccr1.bits.drf)
+					len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct);
+				len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate);
+				break;
+			default:
+				len += sprintf(buf + len, "\nCard Type = %d", j->cardtype);
+				break;
+			}
+			len += sprintf(buf + len, "\nReaders %d", j->readers);
+			len += sprintf(buf + len, "\nWriters %d", j->writers);
+			add_caps(j);
+			len += sprintf(buf + len, "\nCapabilities %d", j->caps);
+			if (j->dsp.low != 0x20)
+				len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
+			if (j->flags.cidsent)
+				len += sprintf(buf + len, "\nCaller ID data sent");
+			else
+				len += sprintf(buf + len, "\nCaller ID data not sent");
+
+			len += sprintf(buf + len, "\nPlay CODEC ");
+			switch (j->play_codec) {
+			case G723_63:
+				len += sprintf(buf + len, "G.723.1 6.3");
+				break;
+			case G723_53:
+				len += sprintf(buf + len, "G.723.1 5.3");
+				break;
+			case TS85:
+				len += sprintf(buf + len, "TrueSpeech 8.5");
+				break;
+			case TS48:
+				len += sprintf(buf + len, "TrueSpeech 4.8");
+				break;
+			case TS41:
+				len += sprintf(buf + len, "TrueSpeech 4.1");
+				break;
+			case G728:
+				len += sprintf(buf + len, "G.728");
+				break;
+			case G729:
+				len += sprintf(buf + len, "G.729");
+				break;
+			case G729B:
+				len += sprintf(buf + len, "G.729B");
+				break;
+			case ULAW:
+				len += sprintf(buf + len, "uLaw");
+				break;
+			case ALAW:
+				len += sprintf(buf + len, "aLaw");
+				break;
+			case LINEAR16:
+				len += sprintf(buf + len, "16 bit Linear");
+				break;
+			case LINEAR8:
+				len += sprintf(buf + len, "8 bit Linear");
+				break;
+			case WSS:
+				len += sprintf(buf + len, "Windows Sound System");
+				break;
+			default:
+				len += sprintf(buf + len, "NO CODEC CHOSEN");
+				break;
+			}
+			len += sprintf(buf + len, "\nRecord CODEC ");
+			switch (j->rec_codec) {
+			case G723_63:
+				len += sprintf(buf + len, "G.723.1 6.3");
+				break;
+			case G723_53:
+				len += sprintf(buf + len, "G.723.1 5.3");
+				break;
+			case TS85:
+				len += sprintf(buf + len, "TrueSpeech 8.5");
+				break;
+			case TS48:
+				len += sprintf(buf + len, "TrueSpeech 4.8");
+				break;
+			case TS41:
+				len += sprintf(buf + len, "TrueSpeech 4.1");
+				break;
+			case G728:
+				len += sprintf(buf + len, "G.728");
+				break;
+			case G729:
+				len += sprintf(buf + len, "G.729");
+				break;
+			case G729B:
+				len += sprintf(buf + len, "G.729B");
+				break;
+			case ULAW:
+				len += sprintf(buf + len, "uLaw");
+				break;
+			case ALAW:
+				len += sprintf(buf + len, "aLaw");
+				break;
+			case LINEAR16:
+				len += sprintf(buf + len, "16 bit Linear");
+				break;
+			case LINEAR8:
+				len += sprintf(buf + len, "8 bit Linear");
+				break;
+			case WSS:
+				len += sprintf(buf + len, "Windows Sound System");
+				break;
+			default:
+				len += sprintf(buf + len, "NO CODEC CHOSEN");
+				break;
+			}
+			len += sprintf(buf + len, "\nAEC ");
+			switch (j->aec_level) {
+			case AEC_OFF:
+				len += sprintf(buf + len, "Off");
+				break;
+			case AEC_LOW:
+				len += sprintf(buf + len, "Low");
+				break;
+			case AEC_MED:
+				len += sprintf(buf + len, "Med");
+				break;
+			case AEC_HIGH:
+				len += sprintf(buf + len, "High");
+				break;
+			case AEC_AUTO:
+				len += sprintf(buf + len, "Auto");
+				break;
+			case AEC_AGC:
+				len += sprintf(buf + len, "AEC/AGC");
+				break;
+			default:
+				len += sprintf(buf + len, "unknown(%i)", j->aec_level);
+				break;
+			}
+
+			len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j));
+			len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j));
+			len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j));
+			
+			len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook);	*/
+
+			if (j->cardtype == QTI_LINEJACK) {
+				len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
+				len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
+				len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck);
+				len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
+				switch (j->daa_mode) {
+				case SOP_PU_SLEEP:
+					len += sprintf(buf + len, "\nDAA PSTN On Hook");
+					break;
+				case SOP_PU_RINGING:
+					len += sprintf(buf + len, "\nDAA PSTN Ringing");
+					len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state);
+					break;
+				case SOP_PU_CONVERSATION:
+					len += sprintf(buf + len, "\nDAA PSTN Off Hook");
+					break;
+				case SOP_PU_PULSEDIALING:
+					len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
+					break;
+				}
+				len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR);
+				len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK);
+				len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg);
+				len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg);
+				len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg);
+				len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg);
+				len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg);
+				len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg);
+				len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg);
+				len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies);
+			}
+			switch (j->port) {
+			case PORT_POTS:
+				len += sprintf(buf + len, "\nPort POTS");
+				break;
+			case PORT_PSTN:
+				len += sprintf(buf + len, "\nPort PSTN");
+				break;
+			case PORT_SPEAKER:
+				len += sprintf(buf + len, "\nPort SPEAKER/MIC");
+				break;
+			case PORT_HANDSET:
+				len += sprintf(buf + len, "\nPort HANDSET");
+				break;
+			}
+			if (j->dsp.low == 0x21 || j->dsp.low == 0x22) {
+				len += sprintf(buf + len, "\nSLIC state ");
+				switch (SLIC_GetState(j)) {
+				case PLD_SLIC_STATE_OC:
+					len += sprintf(buf + len, "OC");
+					break;
+				case PLD_SLIC_STATE_RINGING:
+					len += sprintf(buf + len, "RINGING");
+					break;
+				case PLD_SLIC_STATE_ACTIVE:
+					len += sprintf(buf + len, "ACTIVE");
+					break;
+				case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
+					len += sprintf(buf + len, "OHT");
+					break;
+				case PLD_SLIC_STATE_TIPOPEN:
+					len += sprintf(buf + len, "TIPOPEN");
+					break;
+				case PLD_SLIC_STATE_STANDBY:
+					len += sprintf(buf + len, "STANDBY");
+					break;
+				case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
+					len += sprintf(buf + len, "APR");
+					break;
+				case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
+					len += sprintf(buf + len, "OHTPR");
+					break;
+				default:
+					len += sprintf(buf + len, "%d", SLIC_GetState(j));
+					break;
+				}
+			}
+			len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
+			len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size);
+#ifdef PERFMON_STATS
+			len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
+			len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
+			len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
+			len += sprintf(buf + len, "\nFrames Read %ld", j->framesread);
+			len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten);
+			len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer);
+			len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait);
+			len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait);
+                        len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait);
+                        len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail);
+                        len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait);
+                        len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail);
+                        len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready);
+                        len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail);
+ 
+#endif
+			len += sprintf(buf + len, "\n");
+		}
+	}
+	return len;
+}
+
+static int ixj_read_proc(char *page, char **start, off_t off,
+                              int count, int *eof, void *data)
+{
+        int len = ixj_get_status_proc(page);
+        if (len <= off+count) *eof = 1;
+        *start = page + off;
+        len -= off;
+        if (len>count) len = count;
+        if (len<0) len = 0;
+        return len;
+}
+
+
+static void cleanup(void)
+{
+	int cnt;
+	IXJ *j;
+
+	for (cnt = 0; cnt < IXJMAX; cnt++) {
+		j = get_ixj(cnt);
+		if(j != NULL && j->DSPbase) {
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt);
+			del_timer(&j->timer);
+			if (j->cardtype == QTI_LINEJACK) {
+				j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
+
+				outb_p(j->pld_scrw.byte, j->XILINXbase);
+				j->pld_slicw.bits.rly1 = 0;
+				j->pld_slicw.bits.rly2 = 0;
+				j->pld_slicw.bits.rly3 = 0;
+				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+				LED_SetState(0x0, j);
+				if (ixjdebug & 0x0002)
+					printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
+				release_region(j->XILINXbase, 8);
+			} else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
+				if (ixjdebug & 0x0002)
+					printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
+				release_region(j->XILINXbase, 4);
+			}
+			kfree(j->read_buffer);
+			kfree(j->write_buffer);
+			if (j->dev)
+				pnp_device_detach(j->dev);
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt);
+			phone_unregister_device(&j->p);
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt);
+			release_region(j->DSPbase, 16);
+#ifdef IXJ_DYN_ALLOC
+			if (ixjdebug & 0x0002)
+				printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt);
+			kfree(j);
+			ixj[cnt] = NULL;
+#endif
+		}
+	}
+	if (ixjdebug & 0x0002)
+		printk(KERN_INFO "IXJ: Removing /proc/ixj\n");
+	remove_proc_entry ("ixj", NULL);
+}
+
+/* Typedefs */
+typedef struct {
+	BYTE length;
+	DWORD bits;
+} DATABLOCK;
+
+static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
+{
+	lastLCC = lastLCC & 0xfb;
+	lastLCC = lastLCC | (byData ? 4 : 0);
+	outb(lastLCC, wEEPROMAddress);	/*set data out bit as appropriate */
+
+	mdelay(1);
+	lastLCC = lastLCC | 0x01;
+	outb(lastLCC, wEEPROMAddress);	/*SK rising edge */
+
+	byData = byData << 1;
+	lastLCC = lastLCC & 0xfe;
+	mdelay(1);
+	outb(lastLCC, wEEPROMAddress);	/*after delay, SK falling edge */
+
+}
+
+static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC)
+{
+	mdelay(1);
+	lastLCC = lastLCC | 0x01;
+	outb(lastLCC, wEEPROMAddress);	/*SK rising edge */
+
+	lastLCC = lastLCC & 0xfe;
+	mdelay(1);
+	outb(lastLCC, wEEPROMAddress);	/*after delay, SK falling edge */
+
+	return ((inb(wEEPROMAddress) >> 3) & 1);
+}
+
+static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
+{
+	BYTE lastLCC;
+	WORD wEEPROMAddress = wAddress + 3;
+	DWORD i;
+	BYTE byResult;
+	*pwResult = 0;
+	lastLCC = inb(wEEPROMAddress);
+	lastLCC = lastLCC | 0x02;
+	lastLCC = lastLCC & 0xfe;
+	outb(lastLCC, wEEPROMAddress);	/* CS hi, SK lo */
+
+	mdelay(1);		/* delay */
+
+	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
+	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
+	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0);
+	for (i = 0; i < 8; i++) {
+		PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0);
+		wLoc <<= 1;
+	}
+
+	for (i = 0; i < 16; i++) {
+		byResult = PCIEE_ReadBit(wEEPROMAddress, lastLCC);
+		*pwResult = (*pwResult << 1) | byResult;
+	}
+
+	mdelay(1);		/* another delay */
+
+	lastLCC = lastLCC & 0xfd;
+	outb(lastLCC, wEEPROMAddress);	/* negate CS */
+
+	return 0;
+}
+
+static DWORD PCIEE_GetSerialNumber(WORD wAddress)
+{
+	WORD wLo, wHi;
+	if (PCIEE_ReadWord(wAddress, 62, &wLo))
+		return 0;
+	if (PCIEE_ReadWord(wAddress, 63, &wHi))
+		return 0;
+	return (((DWORD) wHi << 16) | wLo);
+}
+
+static int dspio[IXJMAX + 1] =
+{
+	0,
+};
+static int xio[IXJMAX + 1] =
+{
+	0,
+};
+
+module_param_array(dspio, int, NULL, 0);
+module_param_array(xio, int, NULL, 0);
+MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
+MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
+MODULE_LICENSE("GPL");
+
+static void __exit ixj_exit(void)
+{
+        cleanup();
+}
+
+static IXJ *new_ixj(unsigned long port)
+{
+	IXJ *res;
+	if (!request_region(port, 16, "ixj DSP")) {
+		printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port);
+		return NULL;
+	}
+	res = ixj_alloc();
+	if (!res) {
+		release_region(port, 16);
+		printk(KERN_INFO "ixj: out of memory\n");
+		return NULL;
+	}
+	res->DSPbase = port;
+	return res;
+}
+
+static int __init ixj_probe_isapnp(int *cnt)
+{               
+	int probe = 0;
+	int func = 0x110;
+        struct pnp_dev *dev = NULL, *old_dev = NULL;
+
+	while (1) {
+		do {
+			IXJ *j;
+			int result;
+
+			old_dev = dev;
+			dev = pnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
+					 ISAPNP_FUNCTION(func), old_dev);
+			if (!dev || !dev->card)
+				break;
+			result = pnp_device_attach(dev);
+			if (result < 0) {
+				printk("pnp attach failed %d \n", result);
+				break;
+			}
+			if (pnp_activate_dev(dev) < 0) {
+				printk("pnp activate failed (out of resources?)\n");
+				pnp_device_detach(dev);
+				return -ENOMEM;
+			}
+
+			if (!pnp_port_valid(dev, 0)) {
+				pnp_device_detach(dev);
+				return -ENODEV;
+			}
+
+			j = new_ixj(pnp_port_start(dev, 0));
+			if (!j)
+				break;
+
+			if (func != 0x110)
+				j->XILINXbase = pnp_port_start(dev, 1);	/* get real port */
+
+			switch (func) {
+			case (0x110):
+				j->cardtype = QTI_PHONEJACK;
+				break;
+			case (0x310):
+				j->cardtype = QTI_LINEJACK;
+				break;
+			case (0x410):
+				j->cardtype = QTI_PHONEJACK_LITE;
+				break;
+			}
+			j->board = *cnt;
+			probe = ixj_selfprobe(j);
+			if(!probe) {
+				j->serial = dev->card->serial;
+				j->dev = dev;
+				switch (func) {
+				case 0x110:
+					printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase);
+					break;
+				case 0x310:
+					printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase);
+					break;
+				case 0x410:
+					printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase);
+					break;
+				}
+			}
+			++*cnt;
+		} while (dev);
+		if (func == 0x410)
+			break;
+		if (func == 0x310)
+			func = 0x410;
+		if (func == 0x110)
+			func = 0x310;
+		dev = NULL;
+	}
+	return probe;
+}
+                        
+static int __init ixj_probe_isa(int *cnt)
+{
+	int i, probe;
+
+	/* Use passed parameters for older kernels without PnP */
+	for (i = 0; i < IXJMAX; i++) {
+		if (dspio[i]) {
+			IXJ *j = new_ixj(dspio[i]);
+
+			if (!j)
+				break;
+
+			j->XILINXbase = xio[i];
+			j->cardtype = 0;
+
+			j->board = *cnt;
+			probe = ixj_selfprobe(j);
+			j->dev = NULL;
+			++*cnt;
+		}
+	}
+	return 0;
+}
+
+static int __init ixj_probe_pci(int *cnt)
+{
+	struct pci_dev *pci = NULL;   
+	int i, probe = 0;
+	IXJ *j = NULL;
+
+	for (i = 0; i < IXJMAX - *cnt; i++) {
+		pci = pci_get_device(PCI_VENDOR_ID_QUICKNET,
+				      PCI_DEVICE_ID_QUICKNET_XJ, pci);
+		if (!pci)
+			break;
+
+		if (pci_enable_device(pci))
+			break;
+		j = new_ixj(pci_resource_start(pci, 0));
+		if (!j)
+			break;
+
+		j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
+		j->XILINXbase = j->DSPbase + 0x10;
+		j->cardtype = QTI_PHONEJACK_PCI;
+		j->board = *cnt;
+		probe = ixj_selfprobe(j);
+		if (!probe)
+			printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
+		++*cnt;
+	}
+	pci_dev_put(pci);
+	return probe;
+}
+
+static int __init ixj_init(void)
+{
+	int cnt = 0;
+	int probe = 0;   
+
+	cnt = 0;
+
+	/* These might be no-ops, see above. */
+	if ((probe = ixj_probe_isapnp(&cnt)) < 0) {
+		return probe;
+	}
+	if ((probe = ixj_probe_isa(&cnt)) < 0) {
+		return probe;
+	}
+	if ((probe = ixj_probe_pci(&cnt)) < 0) {
+		return probe;
+	}
+	printk(KERN_INFO "ixj driver initialized.\n");
+	create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
+	return probe;
+}
+
+module_init(ixj_init);
+module_exit(ixj_exit);
+
+static void DAA_Coeff_US(IXJ *j)
+{
+	int i;
+
+	j->daa_country = DAA_US;
+	/*----------------------------------------------- */
+	/* CAO */
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
+		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
+	}
+
+/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
+/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
+/* Bytes for FRX-filter       (08): 03,8F,48,F2,8F,48,70,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
+/* Bytes for FRR-filter       (07): 04,8F,38,7F,9B,EA,B0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
+/* Bytes for AX-filter        (0A): 16,55,DD,CA */
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
+/* Bytes for AR-filter        (09): 52,D3,11,42 */
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
+/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC;
+/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6;
+/* ;  (10K, 0.68uF) */
+	/*  */
+	/* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
+	/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
+
+	/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
+
+	/* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */
+	/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ 
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */
+/* */
+	/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */
+/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */
+
+	/* Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
+/* Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
+/*  */
+	/* ;CR Registers */
+	/* Config. Reg. 0 (filters)       (cr0):FE ; CLK gen. by crystal */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)       (cr1):05 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
+/* Config. Reg. 2 (caller ID)     (cr2):04 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
+/* Config. Reg. 3 (testloops)     (cr3):03 ; SEL Bit==0, HP-disabled */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)   (cr4):02 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+	/* Config. Reg. 5 (Version)       (cr5):02 */
+	/* Config. Reg. 6 (Reserved)      (cr6):00 */
+	/* Config. Reg. 7 (Reserved)      (cr7):00 */
+	/*  */
+	/* ;xr Registers */
+	/* Ext. Reg. 0 (Interrupt Reg.)   (xr0):02 */
+
+	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
+	/* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
+/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
+/* Ext. Reg. 3 (DC Char)          (xr3):32 ; B-Filter Off == 1 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B;		/*0x32; */
+	/* Ext. Reg. 4 (Cadence)          (xr4):00 */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
+/* Ext. Reg. 5 (Ring timer)       (xr5):22 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
+/* Ext. Reg. 6 (Power State)      (xr6):00 */
+	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
+/* Ext. Reg. 7 (Vdd)              (xr7):40 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
+	/*  */
+	/* DTMF Tone 1                     (0B): 11,B3,5A,2C ;   697 Hz   */
+	/*                                       12,33,5A,C3 ;  770 Hz   */
+	/*                                       13,3C,5B,32 ;  852 Hz   */
+	/*                                       1D,1B,5C,CC ;  941 Hz   */
+
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
+/* DTMF Tone 2                     (0C): 32,32,52,B3 ;  1209 Hz   */
+	/*                                       EC,1D,52,22 ;  1336 Hz   */
+	/*                                       AA,AC,51,D2 ;  1477 Hz   */
+	/*                                       9B,3B,51,25 ;  1633 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
+}
+
+static void DAA_Coeff_UK(IXJ *j)
+{
+	int i;
+
+	j->daa_country = DAA_UK;
+	/*----------------------------------------------- */
+	/* CAO */
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
+		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
+	}
+
+/*  Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xCB;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
+/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xA4;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
+/* Bytes for FRX-filter       (08): 07,9B,ED,24,B2,A2,A0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x24;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0xB2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
+/* Bytes for FRR-filter       (07): 0F,92,F2,B2,87,D2,30,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0xB2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
+/* Bytes for AX-filter        (0A): 1B,A5,DD,CA */
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
+/* Bytes for AR-filter        (09): E2,27,10,D6 */
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x8B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xD0;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
+/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xF0;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x0B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
+/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA4;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x8F;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
+/* ; idle */
+	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
+/* Levelmetering Ringing           (0D):AA,35,0F,8E     ; 25Hz 30V less possible? */
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
+/* ;CR Registers */
+	/* Config. Reg. 0 (filters)        (cr0):FF */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+	/* Config. Reg. 5 (Version)        (cr5):02 */
+	/* Config. Reg. 6 (Reserved)       (cr6):00 */
+	/* Config. Reg. 7 (Reserved)       (cr7):00 */
+	/* ;xr Registers */
+	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
+
+	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
+	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
+	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
+/* Ext. Reg. 3 (DC Char)           (xr3):36        ;  */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
+	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
+/* Ext. Reg. 7 (Vdd)               (xr7):46 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;		/* 0x46 ??? Should it be 0x00? */
+	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+	/*                                       12,33,5A,C3    ;  770 Hz   */
+	/*                                       13,3C,5B,32    ;  852 Hz   */
+	/*                                       1D,1B,5C,CC    ;  941 Hz   */
+
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+	/*                                       EC,1D,52,22    ;  1336 Hz   */
+	/*                                       AA,AC,51,D2    ;  1477 Hz   */
+	/*                                       9B,3B,51,25    ;  1633 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
+}
+
+
+static void DAA_Coeff_France(IXJ *j)
+{
+	int i;
+
+	j->daa_country = DAA_FRANCE;
+	/*----------------------------------------------- */
+	/* CAO */
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
+		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
+	}
+
+/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
+/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x2C;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
+/* Bytes for FRX-filter       (08): 07,9A,28,F6,23,4A,B0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF6;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x23;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
+/* Bytes for FRR-filter       (07): 03,8F,F9,2F,9E,FA,20,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9E;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
+/* Bytes for AX-filter        (0A): 16,B5,DD,CA */
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
+/* Bytes for AR-filter        (09): 52,C7,10,D6 */
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
+/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x30;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x78;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
+/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA5;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
+/* ; idle */
+	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
+/* Levelmetering Ringing           (0D):32,45,B5,84     ; 50Hz 20V */
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
+/* ;CR Registers */
+	/* Config. Reg. 0 (filters)        (cr0):FF */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+	/* Config. Reg. 5 (Version)        (cr5):02 */
+	/* Config. Reg. 6 (Reserved)       (cr6):00 */
+	/* Config. Reg. 7 (Reserved)       (cr7):00 */
+	/* ;xr Registers */
+	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
+
+	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
+	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
+	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
+/* Ext. Reg. 3 (DC Char)           (xr3):36        ;  */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
+	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
+/* Ext. Reg. 7 (Vdd)               (xr7):46 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;		/* 0x46 ??? Should it be 0x00? */
+	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+	/*                                       12,33,5A,C3    ;  770 Hz   */
+	/*                                       13,3C,5B,32    ;  852 Hz   */
+	/*                                       1D,1B,5C,CC    ;  941 Hz   */
+
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+	/*                                       EC,1D,52,22    ;  1336 Hz   */
+	/*                                       AA,AC,51,D2    ;  1477 Hz   */
+	/*                                       9B,3B,51,25    ;  1633 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
+}
+
+
+static void DAA_Coeff_Germany(IXJ *j)
+{
+	int i;
+
+	j->daa_country = DAA_GERMANY;
+	/*----------------------------------------------- */
+	/* CAO */
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
+		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
+	}
+
+/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xD2;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
+/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0C;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xD2;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
+/* Bytes for FRX-filter       (08): 07,AA,E2,34,24,89,20,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x24;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
+/* Bytes for FRR-filter       (07): 02,87,FA,37,9A,CA,B0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x37;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9A;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
+/* Bytes for AX-filter        (0A): 72,D5,DD,CA */
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
+/* Bytes for AR-filter        (09): 72,42,13,4B */
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
+/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAD;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
+/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
+/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x26;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBD;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
+/* ;  (10K, 0.68uF) */
+	/* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
+/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
+/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
+/* Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
+/* Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
+/* ;CR Registers */
+	/* Config. Reg. 0 (filters)        (cr0):FF ; all Filters enabled, CLK from ext. source */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 ; Manual Ring, Ring metering enabled */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
+/* Config. Reg. 2 (caller ID)      (cr2):04 ; Analog Gain 0dB, FSC internal */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
+/* Config. Reg. 3 (testloops)      (cr3):00 ; SEL Bit==0, HP-enabled */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+	/* Config. Reg. 5 (Version)        (cr5):02 */
+	/* Config. Reg. 6 (Reserved)       (cr6):00 */
+	/* Config. Reg. 7 (Reserved)       (cr7):00 */
+	/* ;xr Registers */
+	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
+
+	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
+	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
+	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
+/* Ext. Reg. 3 (DC Char)           (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
+	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
+/* Ext. Reg. 7 (Vdd)               (xr7):40 ; VDD=4.25 V */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
+	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+	/*                                       12,33,5A,C3    ;  770 Hz   */
+	/*                                       13,3C,5B,32    ;  852 Hz   */
+	/*                                       1D,1B,5C,CC    ;  941 Hz   */
+
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+	/*                                       EC,1D,52,22    ;  1336 Hz   */
+	/*                                       AA,AC,51,D2    ;  1477 Hz   */
+	/*                                       9B,3B,51,25    ;  1633 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
+}
+
+
+static void DAA_Coeff_Australia(IXJ *j)
+{
+	int i;
+
+	j->daa_country = DAA_AUSTRALIA;
+	/*----------------------------------------------- */
+	/* CAO */
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
+		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
+	}
+
+/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
+/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
+/* Bytes for FRX-filter       (08): 07,96,E2,34,32,9B,30,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
+/* Bytes for FRR-filter       (07): 0F,9A,E9,2F,22,CC,A0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
+/* Bytes for AX-filter        (0A): CB,45,DD,CA */
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
+/* Bytes for AR-filter        (09): 1B,67,10,D6 */
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAF;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
+/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x38;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
+/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x3E;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x2C;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;
+/* ;  idle */
+	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
+/* Levelmetering Ringing           (0D):32,45,B5,84   ; 50Hz 20V */
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
+/* ;CR Registers */
+	/* Config. Reg. 0 (filters)        (cr0):FF */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+	/* Config. Reg. 5 (Version)        (cr5):02 */
+	/* Config. Reg. 6 (Reserved)       (cr6):00 */
+	/* Config. Reg. 7 (Reserved)       (cr7):00 */
+	/* ;xr Registers */
+	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
+
+	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
+	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
+	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
+/* Ext. Reg. 3 (DC Char)           (xr3):2B      ;  */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
+	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
+/* Ext. Reg. 7 (Vdd)               (xr7):40 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
+
+	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;  697 Hz   */
+	/*                                       12,33,5A,C3    ;  770 Hz   */
+	/*                                       13,3C,5B,32    ;  852 Hz   */
+	/*                                       1D,1B,5C,CC    ;  941 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
+
+	/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+	/*                                       EC,1D,52,22    ;  1336 Hz   */
+	/*                                       AA,AC,51,D2    ;  1477 Hz   */
+	/*                                       9B,3B,51,25    ;  1633 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
+}
+
+static void DAA_Coeff_Japan(IXJ *j)
+{
+	int i;
+
+	j->daa_country = DAA_JAPAN;
+	/*----------------------------------------------- */
+	/* CAO */
+	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
+		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
+	}
+
+/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
+/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x34;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
+/* Bytes for FRX-filter       (08): 02,8F,68,77,9C,58,F0,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x77;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x9C;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
+/* Bytes for FRR-filter       (07): 03,8F,38,73,87,EA,20,08 */
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x73;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
+	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
+/* Bytes for AX-filter        (0A): 51,C5,DD,CA */
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
+	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
+/* Bytes for AR-filter        (09): 25,A7,10,D6 */
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAE;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
+/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
+/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x25;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x34;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
+	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;
+/* ;  idle */
+	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
+	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
+/* Levelmetering Ringing           (0D):AA,35,0F,8E    ; 25Hz 30V ????????? */
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
+	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
+	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
+/* ;CR Registers */
+	/* Config. Reg. 0 (filters)        (cr0):FF */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+	/* Config. Reg. 5 (Version)        (cr5):02 */
+	/* Config. Reg. 6 (Reserved)       (cr6):00 */
+	/* Config. Reg. 7 (Reserved)       (cr7):00 */
+	/* ;xr Registers */
+	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
+
+	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
+	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
+	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
+
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
+/* Ext. Reg. 3 (DC Char)           (xr3):22        ;  */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
+	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
+/* Ext. Reg. 7 (Vdd)               (xr7):40 */
+	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
+	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+	/*                                       12,33,5A,C3    ;  770 Hz   */
+	/*                                       13,3C,5B,32    ;  852 Hz   */
+	/*                                       1D,1B,5C,CC    ;  941 Hz   */
+
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+	/*                                       EC,1D,52,22    ;  1336 Hz   */
+	/*                                       AA,AC,51,D2    ;  1477 Hz   */
+	/*                                       9B,3B,51,25    ;  1633 Hz   */
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
+	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
+}
+
+static s16 tone_table[][19] =
+{
+	{			/* f20_50[] 11 */
+		32538,		/* A1 = 1.985962 */
+		 -32325,	/* A2 = -0.986511 */
+		 -343,		/* B2 = -0.010493 */
+		 0,		/* B1 = 0 */
+		 343,		/* B0 = 0.010493 */
+		 32619,		/* A1 = 1.990906 */
+		 -32520,	/* A2 = -0.992462 */
+		 19179,		/* B2 = 0.585327 */
+		 -19178,	/* B1 = -1.170593 */
+		 19179,		/* B0 = 0.585327 */
+		 32723,		/* A1 = 1.997314 */
+		 -32686,	/* A2 = -0.997528 */
+		 9973,		/* B2 = 0.304352 */
+		 -9955,		/* B1 = -0.607605 */
+		 9973,		/* B0 = 0.304352 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f133_200[] 12 */
+		32072,		/* A1 = 1.95752 */
+		 -31896,	/* A2 = -0.973419 */
+		 -435,		/* B2 = -0.013294 */
+		 0,		/* B1 = 0 */
+		 435,		/* B0 = 0.013294 */
+		 32188,		/* A1 = 1.9646 */
+		 -32400,	/* A2 = -0.98877 */
+		 15139,		/* B2 = 0.462036 */
+		 -14882,	/* B1 = -0.908356 */
+		 15139,		/* B0 = 0.462036 */
+		 32473,		/* A1 = 1.981995 */
+		 -32524,	/* A2 = -0.992584 */
+		 23200,		/* B2 = 0.708008 */
+		 -23113,	/* B1 = -1.410706 */
+		 23200,		/* B0 = 0.708008 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f300 13 */
+		31769,		/* A1 = -1.939026 */
+		 -32584,	/* A2 = 0.994385 */
+		 -475,		/* B2 = -0.014522 */
+		 0,		/* B1 = 0.000000 */
+		 475,		/* B0 = 0.014522 */
+		 31789,		/* A1 = -1.940247 */
+		 -32679,	/* A2 = 0.997284 */
+		 17280,		/* B2 = 0.527344 */
+		 -16865,	/* B1 = -1.029358 */
+		 17280,		/* B0 = 0.527344 */
+		 31841,		/* A1 = -1.943481 */
+		 -32681,	/* A2 = 0.997345 */
+		 543,		/* B2 = 0.016579 */
+		 -525,		/* B1 = -0.032097 */
+		 543,		/* B0 = 0.016579 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f300_420[] 14 */
+		30750,		/* A1 = 1.876892 */
+		 -31212,	/* A2 = -0.952515 */
+		 -804,		/* B2 = -0.024541 */
+		 0,		/* B1 = 0 */
+		 804,		/* B0 = 0.024541 */
+		 30686,		/* A1 = 1.872925 */
+		 -32145,	/* A2 = -0.980988 */
+		 14747,		/* B2 = 0.450043 */
+		 -13703,	/* B1 = -0.836395 */
+		 14747,		/* B0 = 0.450043 */
+		 31651,		/* A1 = 1.931824 */
+		 -32321,	/* A2 = -0.986389 */
+		 24425,		/* B2 = 0.745422 */
+		 -23914,	/* B1 = -1.459595 */
+		 24427,		/* B0 = 0.745483 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f330 15 */
+		31613,		/* A1 = -1.929565 */
+		 -32646,	/* A2 = 0.996277 */
+		 -185,		/* B2 = -0.005657 */
+		 0,		/* B1 = 0.000000 */
+		 185,		/* B0 = 0.005657 */
+		 31620,		/* A1 = -1.929932 */
+		 -32713,	/* A2 = 0.998352 */
+		 19253,		/* B2 = 0.587585 */
+		 -18566,	/* B1 = -1.133179 */
+		 19253,		/* B0 = 0.587585 */
+		 31674,		/* A1 = -1.933228 */
+		 -32715,	/* A2 = 0.998413 */
+		 2575,		/* B2 = 0.078590 */
+		 -2495,		/* B1 = -0.152283 */
+		 2575,		/* B0 = 0.078590 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f300_425[] 16 */
+		30741,		/* A1 = 1.876282 */
+		 -31475,	/* A2 = -0.960541 */
+		 -703,		/* B2 = -0.021484 */
+		 0,		/* B1 = 0 */
+		 703,		/* B0 = 0.021484 */
+		 30688,		/* A1 = 1.873047 */
+		 -32248,	/* A2 = -0.984161 */
+		 14542,		/* B2 = 0.443787 */
+		 -13523,	/* B1 = -0.825439 */
+		 14542,		/* B0 = 0.443817 */
+		 31494,		/* A1 = 1.922302 */
+		 -32366,	/* A2 = -0.987762 */
+		 21577,		/* B2 = 0.658508 */
+		 -21013,	/* B1 = -1.282532 */
+		 21577,		/* B0 = 0.658508 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f330_440[] 17 */
+		30627,		/* A1 = 1.869324 */
+		 -31338,	/* A2 = -0.95636 */
+		 -843,		/* B2 = -0.025749 */
+		 0,		/* B1 = 0 */
+		 843,		/* B0 = 0.025749 */
+		 30550,		/* A1 = 1.864685 */
+		 -32221,	/* A2 = -0.983337 */
+		 13594,		/* B2 = 0.414886 */
+		 -12589,	/* B1 = -0.768402 */
+		 13594,		/* B0 = 0.414886 */
+		 31488,		/* A1 = 1.921936 */
+		 -32358,	/* A2 = -0.987518 */
+		 24684,		/* B2 = 0.753296 */
+		 -24029,	/* B1 = -1.466614 */
+		 24684,		/* B0 = 0.753296 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f340 18 */
+		31546,		/* A1 = -1.925476 */
+		 -32646,	/* A2 = 0.996277 */
+		 -445,		/* B2 = -0.013588 */
+		 0,		/* B1 = 0.000000 */
+		 445,		/* B0 = 0.013588 */
+		 31551,		/* A1 = -1.925781 */
+		 -32713,	/* A2 = 0.998352 */
+		 23884,		/* B2 = 0.728882 */
+		 -22979,	/* B1 = -1.402527 */
+		 23884,		/* B0 = 0.728882 */
+		 31606,		/* A1 = -1.929138 */
+		 -32715,	/* A2 = 0.998413 */
+		 863,		/* B2 = 0.026367 */
+		 -835,		/* B1 = -0.050985 */
+		 863,		/* B0 = 0.026367 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f350_400[] 19 */
+		31006,		/* A1 = 1.892517 */
+		 -32029,	/* A2 = -0.977448 */
+		 -461,		/* B2 = -0.014096 */
+		 0,		/* B1 = 0 */
+		 461,		/* B0 = 0.014096 */
+		 30999,		/* A1 = 1.892029 */
+		 -32487,	/* A2 = -0.991455 */
+		 11325,		/* B2 = 0.345612 */
+		 -10682,	/* B1 = -0.651978 */
+		 11325,		/* B0 = 0.345612 */
+		 31441,		/* A1 = 1.919067 */
+		 -32526,	/* A2 = -0.992615 */
+		 24324,		/* B2 = 0.74231 */
+		 -23535,	/* B1 = -1.436523 */
+		 24324,		/* B0 = 0.74231 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f350_440[] */
+		30634,		/* A1 = 1.869751 */
+		 -31533,	/* A2 = -0.962341 */
+		 -680,		/* B2 = -0.020782 */
+		 0,		/* B1 = 0 */
+		 680,		/* B0 = 0.020782 */
+		 30571,		/* A1 = 1.865906 */
+		 -32277,	/* A2 = -0.985016 */
+		 12894,		/* B2 = 0.393524 */
+		 -11945,	/* B1 = -0.729065 */
+		 12894,		/* B0 = 0.393524 */
+		 31367,		/* A1 = 1.91449 */
+		 -32379,	/* A2 = -0.988129 */
+		 23820,		/* B2 = 0.726929 */
+		 -23104,	/* B1 = -1.410217 */
+		 23820,		/* B0 = 0.726929 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f350_450[] */
+		30552,		/* A1 = 1.864807 */
+		 -31434,	/* A2 = -0.95929 */
+		 -690,		/* B2 = -0.021066 */
+		 0,		/* B1 = 0 */
+		 690,		/* B0 = 0.021066 */
+		 30472,		/* A1 = 1.859924 */
+		 -32248,	/* A2 = -0.984161 */
+		 13385,		/* B2 = 0.408478 */
+		 -12357,	/* B1 = -0.754242 */
+		 13385,		/* B0 = 0.408478 */
+		 31358,		/* A1 = 1.914001 */
+		 -32366,	/* A2 = -0.987732 */
+		 26488,		/* B2 = 0.80835 */
+		 -25692,	/* B1 = -1.568176 */
+		 26490,		/* B0 = 0.808411 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f360 */
+		31397,		/* A1 = -1.916321 */
+		 -32623,	/* A2 = 0.995605 */
+		 -117,		/* B2 = -0.003598 */
+		 0,		/* B1 = 0.000000 */
+		 117,		/* B0 = 0.003598 */
+		 31403,		/* A1 = -1.916687 */
+		 -32700,	/* A2 = 0.997925 */
+		 3388,		/* B2 = 0.103401 */
+		 -3240,		/* B1 = -0.197784 */
+		 3388,		/* B0 = 0.103401 */
+		 31463,		/* A1 = -1.920410 */
+		 -32702,	/* A2 = 0.997986 */
+		 13346,		/* B2 = 0.407288 */
+		 -12863,	/* B1 = -0.785126 */
+		 13346,		/* B0 = 0.407288 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f380_420[] */
+		30831,		/* A1 = 1.881775 */
+		 -32064,	/* A2 = -0.978546 */
+		 -367,		/* B2 = -0.01122 */
+		 0,		/* B1 = 0 */
+		 367,		/* B0 = 0.01122 */
+		 30813,		/* A1 = 1.880737 */
+		 -32456,	/* A2 = -0.990509 */
+		 11068,		/* B2 = 0.337769 */
+		 -10338,	/* B1 = -0.631042 */
+		 11068,		/* B0 = 0.337769 */
+		 31214,		/* A1 = 1.905212 */
+		 -32491,	/* A2 = -0.991577 */
+		 16374,		/* B2 = 0.499695 */
+		 -15781,	/* B1 = -0.963196 */
+		 16374,		/* B0 = 0.499695 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f392 */
+		31152,		/* A1 = -1.901428 */
+		 -32613,	/* A2 = 0.995300 */
+		 -314,		/* B2 = -0.009605 */
+		 0,		/* B1 = 0.000000 */
+		 314,		/* B0 = 0.009605 */
+		 31156,		/* A1 = -1.901672 */
+		 -32694,	/* A2 = 0.997742 */
+		 28847,		/* B2 = 0.880371 */
+		 -2734,		/* B1 = -0.166901 */
+		 28847,		/* B0 = 0.880371 */
+		 31225,		/* A1 = -1.905823 */
+		 -32696,	/* A2 = 0.997803 */
+		 462,		/* B2 = 0.014108 */
+		 -442,		/* B1 = -0.027019 */
+		 462,		/* B0 = 0.014108 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f400_425[] */
+		30836,		/* A1 = 1.882141 */
+		 -32296,	/* A2 = -0.985596 */
+		 -324,		/* B2 = -0.009903 */
+		 0,		/* B1 = 0 */
+		 324,		/* B0 = 0.009903 */
+		 30825,		/* A1 = 1.881409 */
+		 -32570,	/* A2 = -0.993958 */
+		 16847,		/* B2 = 0.51416 */
+		 -15792,	/* B1 = -0.963898 */
+		 16847,		/* B0 = 0.51416 */
+		 31106,		/* A1 = 1.89856 */
+		 -32584,	/* A2 = -0.994415 */
+		 9579,		/* B2 = 0.292328 */
+		 -9164,		/* B1 = -0.559357 */
+		 9579,		/* B0 = 0.292328 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f400_440[] */
+		30702,		/* A1 = 1.873962 */
+		 -32134,	/* A2 = -0.980682 */
+		 -517,		/* B2 = -0.015793 */
+		 0,		/* B1 = 0 */
+		 517,		/* B0 = 0.015793 */
+		 30676,		/* A1 = 1.872375 */
+		 -32520,	/* A2 = -0.992462 */
+		 8144,		/* B2 = 0.24855 */
+		 -7596,		/* B1 = -0.463684 */
+		 8144,		/* B0 = 0.24855 */
+		 31084,		/* A1 = 1.897217 */
+		 -32547,	/* A2 = -0.993256 */
+		 22713,		/* B2 = 0.693176 */
+		 -21734,	/* B1 = -1.326599 */
+		 22713,		/* B0 = 0.693176 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f400_450[] */
+		30613,		/* A1 = 1.86853 */
+		 -32031,	/* A2 = -0.977509 */
+		 -618,		/* B2 = -0.018866 */
+		 0,		/* B1 = 0 */
+		 618,		/* B0 = 0.018866 */
+		 30577,		/* A1 = 1.866272 */
+		 -32491,	/* A2 = -0.991577 */
+		 9612,		/* B2 = 0.293335 */
+		 -8935,		/* B1 = -0.54541 */
+		 9612,		/* B0 = 0.293335 */
+		 31071,		/* A1 = 1.896484 */
+		 -32524,	/* A2 = -0.992584 */
+		 21596,		/* B2 = 0.659058 */
+		 -20667,	/* B1 = -1.261414 */
+		 21596,		/* B0 = 0.659058 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f420 */
+		30914,		/* A1 = -1.886841 */
+		 -32584,	/* A2 = 0.994385 */
+		 -426,		/* B2 = -0.013020 */
+		 0,		/* B1 = 0.000000 */
+		 426,		/* B0 = 0.013020 */
+		 30914,		/* A1 = -1.886841 */
+		 -32679,	/* A2 = 0.997314 */
+		 17520,		/* B2 = 0.534668 */
+		 -16471,	/* B1 = -1.005310 */
+		 17520,		/* B0 = 0.534668 */
+		 31004,		/* A1 = -1.892334 */
+		 -32683,	/* A2 = 0.997406 */
+		 819,		/* B2 = 0.025023 */
+		 -780,		/* B1 = -0.047619 */
+		 819,		/* B0 = 0.025023 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+#if 0
+	{			/* f425 */
+		30881,		/* A1 = -1.884827 */
+		 -32603,	/* A2 = 0.994965 */
+		 -496,		/* B2 = -0.015144 */
+		 0,		/* B1 = 0.000000 */
+		 496,		/* B0 = 0.015144 */
+		 30880,		/* A1 = -1.884766 */
+		 -32692,	/* A2 = 0.997711 */
+		 24767,		/* B2 = 0.755859 */
+		 -23290,	/* B1 = -1.421509 */
+		 24767,		/* B0 = 0.755859 */
+		 30967,		/* A1 = -1.890076 */
+		 -32694,	/* A2 = 0.997772 */
+		 728,		/* B2 = 0.022232 */
+		 -691,		/* B1 = -0.042194 */
+		 728,		/* B0 = 0.022232 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+#else
+	{
+		30850,
+		-32534,
+		-504,
+		0,
+		504,
+		30831,
+		-32669,
+		24303,
+		-22080,
+		24303,
+		30994,
+		-32673,
+		1905,
+		-1811,
+		1905,
+		5,
+		129,
+		17,
+		0xff5
+	},
+#endif
+	{			/* f425_450[] */
+		30646,		/* A1 = 1.870544 */
+		 -32327,	/* A2 = -0.986572 */
+		 -287,		/* B2 = -0.008769 */
+		 0,		/* B1 = 0 */
+		 287,		/* B0 = 0.008769 */
+		 30627,		/* A1 = 1.869324 */
+		 -32607,	/* A2 = -0.995087 */
+		 13269,		/* B2 = 0.404968 */
+		 -12376,	/* B1 = -0.755432 */
+		 13269,		/* B0 = 0.404968 */
+		 30924,		/* A1 = 1.887512 */
+		 -32619,	/* A2 = -0.995453 */
+		 19950,		/* B2 = 0.608826 */
+		 -18940,	/* B1 = -1.156006 */
+		 19950,		/* B0 = 0.608826 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f425_475[] */
+		30396,		/* A1 = 1.855225 */
+		 -32014,	/* A2 = -0.97699 */
+		 -395,		/* B2 = -0.012055 */
+		 0,		/* B1 = 0 */
+		 395,		/* B0 = 0.012055 */
+		 30343,		/* A1 = 1.85199 */
+		 -32482,	/* A2 = -0.991302 */
+		 17823,		/* B2 = 0.543945 */
+		 -16431,	/* B1 = -1.002869 */
+		 17823,		/* B0 = 0.543945 */
+		 30872,		/* A1 = 1.884338 */
+		 -32516,	/* A2 = -0.99231 */
+		 18124,		/* B2 = 0.553101 */
+		 -17246,	/* B1 = -1.052673 */
+		 18124,		/* B0 = 0.553101 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f435 */
+		30796,		/* A1 = -1.879639 */
+		 -32603,	/* A2 = 0.994965 */
+		 -254,		/* B2 = -0.007762 */
+		 0,		/* B1 = 0.000000 */
+		 254,		/* B0 = 0.007762 */
+		 30793,		/* A1 = -1.879456 */
+		 -32692,	/* A2 = 0.997711 */
+		 18934,		/* B2 = 0.577820 */
+		 -17751,	/* B1 = -1.083496 */
+		 18934,		/* B0 = 0.577820 */
+		 30882,		/* A1 = -1.884888 */
+		 -32694,	/* A2 = 0.997772 */
+		 1858,		/* B2 = 0.056713 */
+		 -1758,		/* B1 = -0.107357 */
+		 1858,		/* B0 = 0.056713 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f440_450[] */
+		30641,		/* A1 = 1.870239 */
+		 -32458,	/* A2 = -0.99057 */
+		 -155,		/* B2 = -0.004735 */
+		 0,		/* B1 = 0 */
+		 155,		/* B0 = 0.004735 */
+		 30631,		/* A1 = 1.869568 */
+		 -32630,	/* A2 = -0.995789 */
+		 11453,		/* B2 = 0.349548 */
+		 -10666,	/* B1 = -0.651001 */
+		 11453,		/* B0 = 0.349548 */
+		 30810,		/* A1 = 1.880554 */
+		 -32634,	/* A2 = -0.995941 */
+		 12237,		/* B2 = 0.373474 */
+		 -11588,	/* B1 = -0.707336 */
+		 12237,		/* B0 = 0.373474 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f440_480[] */
+		30367,		/* A1 = 1.853455 */
+		 -32147,	/* A2 = -0.981079 */
+		 -495,		/* B2 = -0.015113 */
+		 0,		/* B1 = 0 */
+		 495,		/* B0 = 0.015113 */
+		 30322,		/* A1 = 1.850769 */
+		 -32543,	/* A2 = -0.993134 */
+		 10031,		/* B2 = 0.306152 */
+		 -9252,		/* B1 = -0.564728 */
+		 10031,		/* B0 = 0.306152 */
+		 30770,		/* A1 = 1.878052 */
+		 -32563,	/* A2 = -0.993774 */
+		 22674,		/* B2 = 0.691956 */
+		 -21465,	/* B1 = -1.31012 */
+		 22674,		/* B0 = 0.691956 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f445 */
+		30709,		/* A1 = -1.874329 */
+		 -32603,	/* A2 = 0.994965 */
+		 -83,		/* B2 = -0.002545 */
+		 0,		/* B1 = 0.000000 */
+		 83,		/* B0 = 0.002545 */
+		 30704,		/* A1 = -1.874084 */
+		 -32692,	/* A2 = 0.997711 */
+		 10641,		/* B2 = 0.324738 */
+		 -9947,		/* B1 = -0.607147 */
+		 10641,		/* B0 = 0.324738 */
+		 30796,		/* A1 = -1.879639 */
+		 -32694,	/* A2 = 0.997772 */
+		 10079,		/* B2 = 0.307587 */
+		 9513,		/* B1 = 0.580688 */
+		 10079,		/* B0 = 0.307587 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f450 */
+		30664,		/* A1 = -1.871643 */
+		 -32603,	/* A2 = 0.994965 */
+		 -164,		/* B2 = -0.005029 */
+		 0,		/* B1 = 0.000000 */
+		 164,		/* B0 = 0.005029 */
+		 30661,		/* A1 = -1.871399 */
+		 -32692,	/* A2 = 0.997711 */
+		 15294,		/* B2 = 0.466736 */
+		 -14275,	/* B1 = -0.871307 */
+		 15294,		/* B0 = 0.466736 */
+		 30751,		/* A1 = -1.876953 */
+		 -32694,	/* A2 = 0.997772 */
+		 3548,		/* B2 = 0.108284 */
+		 -3344,		/* B1 = -0.204155 */
+		 3548,		/* B0 = 0.108284 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f452 */
+		30653,		/* A1 = -1.870911 */
+		 -32615,	/* A2 = 0.995361 */
+		 -209,		/* B2 = -0.006382 */
+		 0,		/* B1 = 0.000000 */
+		 209,		/* B0 = 0.006382 */
+		 30647,		/* A1 = -1.870605 */
+		 -32702,	/* A2 = 0.997986 */
+		 18971,		/* B2 = 0.578979 */
+		 -17716,	/* B1 = -1.081299 */
+		 18971,		/* B0 = 0.578979 */
+		 30738,		/* A1 = -1.876099 */
+		 -32702,	/* A2 = 0.998016 */
+		 2967,		/* B2 = 0.090561 */
+		 -2793,		/* B1 = -0.170502 */
+		 2967,		/* B0 = 0.090561 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f475 */
+		30437,		/* A1 = -1.857727 */
+		 -32603,	/* A2 = 0.994965 */
+		 -264,		/* B2 = -0.008062 */
+		 0,		/* B1 = 0.000000 */
+		 264,		/* B0 = 0.008062 */
+		 30430,		/* A1 = -1.857300 */
+		 -32692,	/* A2 = 0.997711 */
+		 21681,		/* B2 = 0.661682 */
+		 -20082,	/* B1 = -1.225708 */
+		 21681,		/* B0 = 0.661682 */
+		 30526,		/* A1 = -1.863220 */
+		 -32694,	/* A2 = 0.997742 */
+		 1559,		/* B2 = 0.047600 */
+		 -1459,		/* B1 = -0.089096 */
+		 1559,		/* B0 = 0.047600 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f480_620[] */
+		28975,		/* A1 = 1.768494 */
+		 -30955,	/* A2 = -0.944672 */
+		 -1026,		/* B2 = -0.03133 */
+		 0,		/* B1 = 0 */
+		 1026,		/* B0 = 0.03133 */
+		 28613,		/* A1 = 1.746399 */
+		 -32089,	/* A2 = -0.979309 */
+		 14214,		/* B2 = 0.433807 */
+		 -12202,	/* B1 = -0.744812 */
+		 14214,		/* B0 = 0.433807 */
+		 30243,		/* A1 = 1.845947 */
+		 -32238,	/* A2 = -0.983856 */
+		 24825,		/* B2 = 0.757629 */
+		 -23402,	/* B1 = -1.428345 */
+		 24825,		/* B0 = 0.757629 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f494 */
+		30257,		/* A1 = -1.846741 */
+		 -32605,	/* A2 = 0.995056 */
+		 -249,		/* B2 = -0.007625 */
+		 0,		/* B1 = 0.000000 */
+		 249,		/* B0 = 0.007625 */
+		 30247,		/* A1 = -1.846191 */
+		 -32694,	/* A2 = 0.997772 */
+		 18088,		/* B2 = 0.552002 */
+		 -16652,	/* B1 = -1.016418 */
+		 18088,		/* B0 = 0.552002 */
+		 30348,		/* A1 = -1.852295 */
+		 -32696,	/* A2 = 0.997803 */
+		 2099,		/* B2 = 0.064064 */
+		 -1953,		/* B1 = -0.119202 */
+		 2099,		/* B0 = 0.064064 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f500 */
+		30202,		/* A1 = -1.843431 */
+		 -32624,	/* A2 = 0.995622 */
+		 -413,		/* B2 = -0.012622 */
+		 0,		/* B1 = 0.000000 */
+		 413,		/* B0 = 0.012622 */
+		 30191,		/* A1 = -1.842721 */
+		 -32714,	/* A2 = 0.998364 */
+		 25954,		/* B2 = 0.792057 */
+		 -23890,	/* B1 = -1.458131 */
+		 25954,		/* B0 = 0.792057 */
+		 30296,		/* A1 = -1.849172 */
+		 -32715,	/* A2 = 0.998397 */
+		 2007,		/* B2 = 0.061264 */
+		 -1860,		/* B1 = -0.113568 */
+		 2007,		/* B0 = 0.061264 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f520 */
+		30001,		/* A1 = -1.831116 */
+		 -32613,	/* A2 = 0.995270 */
+		 -155,		/* B2 = -0.004750 */
+		 0,		/* B1 = 0.000000 */
+		 155,		/* B0 = 0.004750 */
+		 29985,		/* A1 = -1.830200 */
+		 -32710,	/* A2 = 0.998260 */
+		 6584,		/* B2 = 0.200928 */
+		 -6018,		/* B1 = -0.367355 */
+		 6584,		/* B0 = 0.200928 */
+		 30105,		/* A1 = -1.837524 */
+		 -32712,	/* A2 = 0.998291 */
+		 23812,		/* B2 = 0.726685 */
+		 -21936,	/* B1 = -1.338928 */
+		 23812,		/* B0 = 0.726685 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f523 */
+		29964,		/* A1 = -1.828918 */
+		 -32601,	/* A2 = 0.994904 */
+		 -101,		/* B2 = -0.003110 */
+		 0,		/* B1 = 0.000000 */
+		 101,		/* B0 = 0.003110 */
+		 29949,		/* A1 = -1.827942 */
+		 -32700,	/* A2 = 0.997925 */
+		 11041,		/* B2 = 0.336975 */
+		 -10075,	/* B1 = -0.614960 */
+		 11041,		/* B0 = 0.336975 */
+		 30070,		/* A1 = -1.835388 */
+		 -32702,	/* A2 = 0.997986 */
+		 16762,		/* B2 = 0.511536 */
+		 -15437,	/* B1 = -0.942230 */
+		 16762,		/* B0 = 0.511536 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f525 */
+		29936,		/* A1 = -1.827209 */
+		 -32584,	/* A2 = 0.994415 */
+		 -91,		/* B2 = -0.002806 */
+		 0,		/* B1 = 0.000000 */
+		 91,		/* B0 = 0.002806 */
+		 29921,		/* A1 = -1.826233 */
+		 -32688,	/* A2 = 0.997559 */
+		 11449,		/* B2 = 0.349396 */
+		 -10426,	/* B1 = -0.636383 */
+		 11449,		/* B0 = 0.349396 */
+		 30045,		/* A1 = -1.833862 */
+		 -32688,	/* A2 = 0.997589 */
+		 13055,		/* B2 = 0.398407 */
+		 -12028,	/* B1 = -0.734161 */
+		 13055,		/* B0 = 0.398407 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f540_660[] */
+		28499,		/* A1 = 1.739441 */
+		 -31129,	/* A2 = -0.949982 */
+		 -849,		/* B2 = -0.025922 */
+		 0,		/* B1 = 0 */
+		 849,		/* B0 = 0.025922 */
+		 28128,		/* A1 = 1.716797 */
+		 -32130,	/* A2 = -0.98056 */
+		 14556,		/* B2 = 0.444214 */
+		 -12251,	/* B1 = -0.747772 */
+		 14556,		/* B0 = 0.444244 */
+		 29667,		/* A1 = 1.81073 */
+		 -32244,	/* A2 = -0.984039 */
+		 23038,		/* B2 = 0.703064 */
+		 -21358,	/* B1 = -1.303589 */
+		 23040,		/* B0 = 0.703125 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f587 */
+		29271,		/* A1 = -1.786560 */
+		 -32599,	/* A2 = 0.994873 */
+		 -490,		/* B2 = -0.014957 */
+		 0,		/* B1 = 0.000000 */
+		 490,		/* B0 = 0.014957 */
+		 29246,		/* A1 = -1.785095 */
+		 -32700,	/* A2 = 0.997925 */
+		 28961,		/* B2 = 0.883850 */
+		 -25796,	/* B1 = -1.574463 */
+		 28961,		/* B0 = 0.883850 */
+		 29383,		/* A1 = -1.793396 */
+		 -32700,	/* A2 = 0.997955 */
+		 1299,		/* B2 = 0.039650 */
+		 -1169,		/* B1 = -0.071396 */
+		 1299,		/* B0 = 0.039650 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f590 */
+		29230,		/* A1 = -1.784058 */
+		 -32584,	/* A2 = 0.994415 */
+		 -418,		/* B2 = -0.012757 */
+		 0,		/* B1 = 0.000000 */
+		 418,		/* B0 = 0.012757 */
+		 29206,		/* A1 = -1.782593 */
+		 -32688,	/* A2 = 0.997559 */
+		 36556,		/* B2 = 1.115601 */
+		 -32478,	/* B1 = -1.982300 */
+		 36556,		/* B0 = 1.115601 */
+		 29345,		/* A1 = -1.791077 */
+		 -32688,	/* A2 = 0.997589 */
+		 897,		/* B2 = 0.027397 */
+		 -808,		/* B1 = -0.049334 */
+		 897,		/* B0 = 0.027397 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f600 */
+		29116,		/* A1 = -1.777100 */
+		 -32603,	/* A2 = 0.994965 */
+		 -165,		/* B2 = -0.005039 */
+		 0,		/* B1 = 0.000000 */
+		 165,		/* B0 = 0.005039 */
+		 29089,		/* A1 = -1.775452 */
+		 -32708,	/* A2 = 0.998199 */
+		 6963,		/* B2 = 0.212494 */
+		 -6172,		/* B1 = -0.376770 */
+		 6963,		/* B0 = 0.212494 */
+		 29237,		/* A1 = -1.784485 */
+		 -32710,	/* A2 = 0.998230 */
+		 24197,		/* B2 = 0.738464 */
+		 -21657,	/* B1 = -1.321899 */
+		 24197,		/* B0 = 0.738464 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f660 */
+		28376,		/* A1 = -1.731934 */
+		 -32567,	/* A2 = 0.993896 */
+		 -363,		/* B2 = -0.011102 */
+		 0,		/* B1 = 0.000000 */
+		 363,		/* B0 = 0.011102 */
+		 28337,		/* A1 = -1.729614 */
+		 -32683,	/* A2 = 0.997434 */
+		 21766,		/* B2 = 0.664246 */
+		 -18761,	/* B1 = -1.145081 */
+		 21766,		/* B0 = 0.664246 */
+		 28513,		/* A1 = -1.740356 */
+		 -32686,	/* A2 = 0.997498 */
+		 2509,		/* B2 = 0.076584 */
+		 -2196,		/* B1 = -0.134041 */
+		 2509,		/* B0 = 0.076584 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f700 */
+		27844,		/* A1 = -1.699463 */
+		 -32563,	/* A2 = 0.993744 */
+		 -366,		/* B2 = -0.011187 */
+		 0,		/* B1 = 0.000000 */
+		 366,		/* B0 = 0.011187 */
+		 27797,		/* A1 = -1.696655 */
+		 -32686,	/* A2 = 0.997498 */
+		 22748,		/* B2 = 0.694214 */
+		 -19235,	/* B1 = -1.174072 */
+		 22748,		/* B0 = 0.694214 */
+		 27995,		/* A1 = -1.708740 */
+		 -32688,	/* A2 = 0.997559 */
+		 2964,		/* B2 = 0.090477 */
+		 -2546,		/* B1 = -0.155449 */
+		 2964,		/* B0 = 0.090477 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f740 */
+		27297,		/* A1 = -1.666077 */
+		 -32551,	/* A2 = 0.993408 */
+		 -345,		/* B2 = -0.010540 */
+		 0,		/* B1 = 0.000000 */
+		 345,		/* B0 = 0.010540 */
+		 27240,		/* A1 = -1.662598 */
+		 -32683,	/* A2 = 0.997406 */
+		 22560,		/* B2 = 0.688477 */
+		 -18688,	/* B1 = -1.140625 */
+		 22560,		/* B0 = 0.688477 */
+		 27461,		/* A1 = -1.676147 */
+		 -32684,	/* A2 = 0.997467 */
+		 3541,		/* B2 = 0.108086 */
+		 -2985,		/* B1 = -0.182220 */
+		 3541,		/* B0 = 0.108086 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f750 */
+		27155,		/* A1 = -1.657410 */
+		 -32551,	/* A2 = 0.993408 */
+		 -462,		/* B2 = -0.014117 */
+		 0,		/* B1 = 0.000000 */
+		 462,		/* B0 = 0.014117 */
+		 27097,		/* A1 = -1.653870 */
+		 -32683,	/* A2 = 0.997406 */
+		 32495,		/* B2 = 0.991699 */
+		 -26776,	/* B1 = -1.634338 */
+		 32495,		/* B0 = 0.991699 */
+		 27321,		/* A1 = -1.667542 */
+		 -32684,	/* A2 = 0.997467 */
+		 1835,		/* B2 = 0.056007 */
+		 -1539,		/* B1 = -0.093948 */
+		 1835,		/* B0 = 0.056007 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f750_1450[] */
+		19298,		/* A1 = 1.177917 */
+		 -24471,	/* A2 = -0.746796 */
+		 -4152,		/* B2 = -0.126709 */
+		 0,		/* B1 = 0 */
+		 4152,		/* B0 = 0.126709 */
+		 12902,		/* A1 = 0.787476 */
+		 -29091,	/* A2 = -0.887817 */
+		 12491,		/* B2 = 0.38121 */
+		 -1794,		/* B1 = -0.109528 */
+		 12494,		/* B0 = 0.381317 */
+		 26291,		/* A1 = 1.604736 */
+		 -30470,	/* A2 = -0.929901 */
+		 28859,		/* B2 = 0.880737 */
+		 -26084,	/* B1 = -1.592102 */
+		 28861,		/* B0 = 0.880798 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f770 */
+		26867,		/* A1 = -1.639832 */
+		 -32551,	/* A2 = 0.993408 */
+		 -123,		/* B2 = -0.003755 */
+		 0,		/* B1 = 0.000000 */
+		 123,		/* B0 = 0.003755 */
+		 26805,		/* A1 = -1.636108 */
+		 -32683,	/* A2 = 0.997406 */
+		 17297,		/* B2 = 0.527863 */
+		 -14096,	/* B1 = -0.860382 */
+		 17297,		/* B0 = 0.527863 */
+		 27034,		/* A1 = -1.650085 */
+		 -32684,	/* A2 = 0.997467 */
+		 12958,		/* B2 = 0.395477 */
+		 -10756,	/* B1 = -0.656525 */
+		 12958,		/* B0 = 0.395477 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f800 */
+		26413,		/* A1 = -1.612122 */
+		 -32547,	/* A2 = 0.993286 */
+		 -223,		/* B2 = -0.006825 */
+		 0,		/* B1 = 0.000000 */
+		 223,		/* B0 = 0.006825 */
+		 26342,		/* A1 = -1.607849 */
+		 -32686,	/* A2 = 0.997498 */
+		 6391,		/* B2 = 0.195053 */
+		 -5120,		/* B1 = -0.312531 */
+		 6391,		/* B0 = 0.195053 */
+		 26593,		/* A1 = -1.623108 */
+		 -32688,	/* A2 = 0.997559 */
+		 23681,		/* B2 = 0.722717 */
+		 -19328,	/* B1 = -1.179688 */
+		 23681,		/* B0 = 0.722717 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f816 */
+		26168,		/* A1 = -1.597209 */
+		 -32528,	/* A2 = 0.992706 */
+		 -235,		/* B2 = -0.007182 */
+		 0,		/* B1 = 0.000000 */
+		 235,		/* B0 = 0.007182 */
+		 26092,		/* A1 = -1.592590 */
+		 -32675,	/* A2 = 0.997192 */
+		 20823,		/* B2 = 0.635498 */
+		 -16510,	/* B1 = -1.007751 */
+		 20823,		/* B0 = 0.635498 */
+		 26363,		/* A1 = -1.609070 */
+		 -32677,	/* A2 = 0.997253 */
+		 6739,		/* B2 = 0.205688 */
+		 -5459,		/* B1 = -0.333206 */
+		 6739,		/* B0 = 0.205688 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f850 */
+		25641,		/* A1 = -1.565063 */
+		 -32536,	/* A2 = 0.992950 */
+		 -121,		/* B2 = -0.003707 */
+		 0,		/* B1 = 0.000000 */
+		 121,		/* B0 = 0.003707 */
+		 25560,		/* A1 = -1.560059 */
+		 -32684,	/* A2 = 0.997437 */
+		 18341,		/* B2 = 0.559753 */
+		 -14252,	/* B1 = -0.869904 */
+		 18341,		/* B0 = 0.559753 */
+		 25837,		/* A1 = -1.577026 */
+		 -32684,	/* A2 = 0.997467 */
+		 16679,		/* B2 = 0.509003 */
+		 -13232,	/* B1 = -0.807648 */
+		 16679,		/* B0 = 0.509003 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f857_1645[] */
+		16415,		/* A1 = 1.001953 */
+		 -23669,	/* A2 = -0.722321 */
+		 -4549,		/* B2 = -0.138847 */
+		 0,		/* B1 = 0 */
+		 4549,		/* B0 = 0.138847 */
+		 8456,		/* A1 = 0.516174 */
+		 -28996,	/* A2 = -0.884918 */
+		 13753,		/* B2 = 0.419724 */
+		 -12,		/* B1 = -0.000763 */
+		 13757,		/* B0 = 0.419846 */
+		 24632,		/* A1 = 1.503418 */
+		 -30271,	/* A2 = -0.923828 */
+		 29070,		/* B2 = 0.887146 */
+		 -25265,	/* B1 = -1.542114 */
+		 29073,		/* B0 = 0.887268 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f900 */
+		24806,		/* A1 = -1.514099 */
+		 -32501,	/* A2 = 0.991852 */
+		 -326,		/* B2 = -0.009969 */
+		 0,		/* B1 = 0.000000 */
+		 326,		/* B0 = 0.009969 */
+		 24709,		/* A1 = -1.508118 */
+		 -32659,	/* A2 = 0.996674 */
+		 20277,		/* B2 = 0.618835 */
+		 -15182,	/* B1 = -0.926636 */
+		 20277,		/* B0 = 0.618835 */
+		 25022,		/* A1 = -1.527222 */
+		 -32661,	/* A2 = 0.996735 */
+		 4320,		/* B2 = 0.131836 */
+		 -3331,		/* B1 = -0.203339 */
+		 4320,		/* B0 = 0.131836 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f900_1300[] */
+		19776,		/* A1 = 1.207092 */
+		 -27437,	/* A2 = -0.837341 */
+		 -2666,		/* B2 = -0.081371 */
+		 0,		/* B1 = 0 */
+		 2666,		/* B0 = 0.081371 */
+		 16302,		/* A1 = 0.995026 */
+		 -30354,	/* A2 = -0.926361 */
+		 10389,		/* B2 = 0.317062 */
+		 -3327,		/* B1 = -0.203064 */
+		 10389,		/* B0 = 0.317062 */
+		 24299,		/* A1 = 1.483154 */
+		 -30930,	/* A2 = -0.943909 */
+		 25016,		/* B2 = 0.763428 */
+		 -21171,	/* B1 = -1.292236 */
+		 25016,		/* B0 = 0.763428 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f935_1215[] */
+		20554,		/* A1 = 1.254517 */
+		 -28764,	/* A2 = -0.877838 */
+		 -2048,		/* B2 = -0.062515 */
+		 0,		/* B1 = 0 */
+		 2048,		/* B0 = 0.062515 */
+		 18209,		/* A1 = 1.11145 */
+		 -30951,	/* A2 = -0.94458 */
+		 9390,		/* B2 = 0.286575 */
+		 -3955,		/* B1 = -0.241455 */
+		 9390,		/* B0 = 0.286575 */
+		 23902,		/* A1 = 1.458923 */
+		 -31286,	/* A2 = -0.954803 */
+		 23252,		/* B2 = 0.709595 */
+		 -19132,	/* B1 = -1.167725 */
+		 23252,		/* B0 = 0.709595 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f941_1477[] */
+		17543,		/* A1 = 1.07074 */
+		 -26220,	/* A2 = -0.800201 */
+		 -3298,		/* B2 = -0.100647 */
+		 0,		/* B1 = 0 */
+		 3298,		/* B0 = 0.100647 */
+		 12423,		/* A1 = 0.75827 */
+		 -30036,	/* A2 = -0.916626 */
+		 12651,		/* B2 = 0.386078 */
+		 -2444,		/* B1 = -0.14917 */
+		 12653,		/* B0 = 0.386154 */
+		 23518,		/* A1 = 1.435425 */
+		 -30745,	/* A2 = -0.938293 */
+		 27282,		/* B2 = 0.832581 */
+		 -22529,	/* B1 = -1.375122 */
+		 27286,		/* B0 = 0.832703 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f942 */
+		24104,		/* A1 = -1.471252 */
+		 -32507,	/* A2 = 0.992065 */
+		 -351,		/* B2 = -0.010722 */
+		 0,		/* B1 = 0.000000 */
+		 351,		/* B0 = 0.010722 */
+		 23996,		/* A1 = -1.464600 */
+		 -32671,	/* A2 = 0.997040 */
+		 22848,		/* B2 = 0.697266 */
+		 -16639,	/* B1 = -1.015564 */
+		 22848,		/* B0 = 0.697266 */
+		 24332,		/* A1 = -1.485168 */
+		 -32673,	/* A2 = 0.997101 */
+		 4906,		/* B2 = 0.149727 */
+		 -3672,		/* B1 = -0.224174 */
+		 4906,		/* B0 = 0.149727 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f950 */
+		23967,		/* A1 = -1.462830 */
+		 -32507,	/* A2 = 0.992065 */
+		 -518,		/* B2 = -0.015821 */
+		 0,		/* B1 = 0.000000 */
+		 518,		/* B0 = 0.015821 */
+		 23856,		/* A1 = -1.456055 */
+		 -32671,	/* A2 = 0.997040 */
+		 26287,		/* B2 = 0.802246 */
+		 -19031,	/* B1 = -1.161560 */
+		 26287,		/* B0 = 0.802246 */
+		 24195,		/* A1 = -1.476746 */
+		 -32673,	/* A2 = 0.997101 */
+		 2890,		/* B2 = 0.088196 */
+		 -2151,		/* B1 = -0.131317 */
+		 2890,		/* B0 = 0.088196 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f950_1400[] */
+		18294,		/* A1 = 1.116638 */
+		 -26962,	/* A2 = -0.822845 */
+		 -2914,		/* B2 = -0.088936 */
+		 0,		/* B1 = 0 */
+		 2914,		/* B0 = 0.088936 */
+		 14119,		/* A1 = 0.861786 */
+		 -30227,	/* A2 = -0.922455 */
+		 11466,		/* B2 = 0.349945 */
+		 -2833,		/* B1 = -0.172943 */
+		 11466,		/* B0 = 0.349945 */
+		 23431,		/* A1 = 1.430115 */
+		 -30828,	/* A2 = -0.940796 */
+		 25331,		/* B2 = 0.773071 */
+		 -20911,	/* B1 = -1.276367 */
+		 25331,		/* B0 = 0.773071 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f975 */
+		23521,		/* A1 = -1.435608 */
+		 -32489,	/* A2 = 0.991516 */
+		 -193,		/* B2 = -0.005915 */
+		 0,		/* B1 = 0.000000 */
+		 193,		/* B0 = 0.005915 */
+		 23404,		/* A1 = -1.428467 */
+		 -32655,	/* A2 = 0.996582 */
+		 17740,		/* B2 = 0.541412 */
+		 -12567,	/* B1 = -0.767029 */
+		 17740,		/* B0 = 0.541412 */
+		 23753,		/* A1 = -1.449829 */
+		 -32657,	/* A2 = 0.996613 */
+		 9090,		/* B2 = 0.277405 */
+		 -6662,		/* B1 = -0.406647 */
+		 9090,		/* B0 = 0.277405 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1000 */
+		23071,		/* A1 = -1.408203 */
+		 -32489,	/* A2 = 0.991516 */
+		 -293,		/* B2 = -0.008965 */
+		 0,		/* B1 = 0.000000 */
+		 293,		/* B0 = 0.008965 */
+		 22951,		/* A1 = -1.400818 */
+		 -32655,	/* A2 = 0.996582 */
+		 5689,		/* B2 = 0.173645 */
+		 -3951,		/* B1 = -0.241150 */
+		 5689,		/* B0 = 0.173645 */
+		 23307,		/* A1 = -1.422607 */
+		 -32657,	/* A2 = 0.996613 */
+		 18692,		/* B2 = 0.570435 */
+		 -13447,	/* B1 = -0.820770 */
+		 18692,		/* B0 = 0.570435 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1020 */
+		22701,		/* A1 = -1.385620 */
+		 -32474,	/* A2 = 0.991058 */
+		 -292,		/* B2 = -0.008933 */
+		 0,		/*163840      , B1 = 10.000000 */
+		 292,		/* B0 = 0.008933 */
+		 22564,		/* A1 = -1.377258 */
+		 -32655,	/* A2 = 0.996552 */
+		 20756,		/* B2 = 0.633423 */
+		 -14176,	/* B1 = -0.865295 */
+		 20756,		/* B0 = 0.633423 */
+		 22960,		/* A1 = -1.401428 */
+		 -32657,	/* A2 = 0.996613 */
+		 6520,		/* B2 = 0.198990 */
+		 -4619,		/* B1 = -0.281937 */
+		 6520,		/* B0 = 0.198990 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1050 */
+		22142,		/* A1 = -1.351501 */
+		 -32474,	/* A2 = 0.991058 */
+		 -147,		/* B2 = -0.004493 */
+		 0,		/* B1 = 0.000000 */
+		 147,		/* B0 = 0.004493 */
+		 22000,		/* A1 = -1.342834 */
+		 -32655,	/* A2 = 0.996552 */
+		 15379,		/* B2 = 0.469360 */
+		 -10237,	/* B1 = -0.624847 */
+		 15379,		/* B0 = 0.469360 */
+		 22406,		/* A1 = -1.367554 */
+		 -32657,	/* A2 = 0.996613 */
+		 17491,		/* B2 = 0.533783 */
+		 -12096,	/* B1 = -0.738312 */
+		 17491,		/* B0 = 0.533783 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1100_1750[] */
+		12973,		/* A1 = 0.79184 */
+		 -24916,	/* A2 = -0.760376 */
+		 6655,		/* B2 = 0.203102 */
+		 367,		/* B1 = 0.0224 */
+		 6657,		/* B0 = 0.203171 */
+		 5915,		/* A1 = 0.361053 */
+		 -29560,	/* A2 = -0.90213 */
+		 -7777,		/* B2 = -0.23735 */
+		 0,		/* B1 = 0 */
+		 7777,		/* B0 = 0.23735 */
+		 20510,		/* A1 = 1.251892 */
+		 -30260,	/* A2 = -0.923462 */
+		 26662,		/* B2 = 0.81366 */
+		 -20573,	/* B1 = -1.255737 */
+		 26668,		/* B0 = 0.813843 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1140 */
+		20392,		/* A1 = -1.244629 */
+		 -32460,	/* A2 = 0.990601 */
+		 -270,		/* B2 = -0.008240 */
+		 0,		/* B1 = 0.000000 */
+		 270,		/* B0 = 0.008240 */
+		 20218,		/* A1 = -1.234009 */
+		 -32655,	/* A2 = 0.996582 */
+		 21337,		/* B2 = 0.651154 */
+		 -13044,	/* B1 = -0.796143 */
+		 21337,		/* B0 = 0.651154 */
+		 20684,		/* A1 = -1.262512 */
+		 -32657,	/* A2 = 0.996643 */
+		 8572,		/* B2 = 0.261612 */
+		 -5476,		/* B1 = -0.334244 */
+		 8572,		/* B0 = 0.261612 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1200 */
+		19159,		/* A1 = -1.169373 */
+		 -32456,	/* A2 = 0.990509 */
+		 -335,		/* B2 = -0.010252 */
+		 0,		/* B1 = 0.000000 */
+		 335,		/* B0 = 0.010252 */
+		 18966,		/* A1 = -1.157593 */
+		 -32661,	/* A2 = 0.996735 */
+		 6802,		/* B2 = 0.207588 */
+		 -3900,		/* B1 = -0.238098 */
+		 6802,		/* B0 = 0.207588 */
+		 19467,		/* A1 = -1.188232 */
+		 -32661,	/* A2 = 0.996765 */
+		 25035,		/* B2 = 0.764008 */
+		 -15049,	/* B1 = -0.918579 */
+		 25035,		/* B0 = 0.764008 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1209 */
+		18976,		/* A1 = -1.158264 */
+		 -32439,	/* A2 = 0.989990 */
+		 -183,		/* B2 = -0.005588 */
+		 0,		/* B1 = 0.000000 */
+		 183,		/* B0 = 0.005588 */
+		 18774,		/* A1 = -1.145874 */
+		 -32650,	/* A2 = 0.996429 */
+		 15468,		/* B2 = 0.472076 */
+		 -8768,		/* B1 = -0.535217 */
+		 15468,		/* B0 = 0.472076 */
+		 19300,		/* A1 = -1.177979 */
+		 -32652,	/* A2 = 0.996490 */
+		 19840,		/* B2 = 0.605499 */
+		 -11842,	/* B1 = -0.722809 */
+		 19840,		/* B0 = 0.605499 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1330 */
+		16357,		/* A1 = -0.998413 */
+		 -32368,	/* A2 = 0.987793 */
+		 -217,		/* B2 = -0.006652 */
+		 0,		/* B1 = 0.000000 */
+		 217,		/* B0 = 0.006652 */
+		 16107,		/* A1 = -0.983126 */
+		 -32601,	/* A2 = 0.994904 */
+		 11602,		/* B2 = 0.354065 */
+		 -5555,		/* B1 = -0.339111 */
+		 11602,		/* B0 = 0.354065 */
+		 16722,		/* A1 = -1.020630 */
+		 -32603,	/* A2 = 0.994965 */
+		 15574,		/* B2 = 0.475311 */
+		 -8176,		/* B1 = -0.499069 */
+		 15574,		/* B0 = 0.475311 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1336 */
+		16234,		/* A1 = -0.990875 */
+		 32404,		/* A2 = -0.988922 */
+		 -193,		/* B2 = -0.005908 */
+		 0,		/* B1 = 0.000000 */
+		 193,		/* B0 = 0.005908 */
+		 15986,		/* A1 = -0.975769 */
+		 -32632,	/* A2 = 0.995880 */
+		 18051,		/* B2 = 0.550903 */
+		 -8658,		/* B1 = -0.528473 */
+		 18051,		/* B0 = 0.550903 */
+		 16591,		/* A1 = -1.012695 */
+		 -32634,	/* A2 = 0.995941 */
+		 15736,		/* B2 = 0.480240 */
+		 -8125,		/* B1 = -0.495926 */
+		 15736,		/* B0 = 0.480240 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1366 */
+		15564,		/* A1 = -0.949982 */
+		 -32404,	/* A2 = 0.988922 */
+		 -269,		/* B2 = -0.008216 */
+		 0,		/* B1 = 0.000000 */
+		 269,		/* B0 = 0.008216 */
+		 15310,		/* A1 = -0.934479 */
+		 -32632,	/* A2 = 0.995880 */
+		 10815,		/* B2 = 0.330063 */
+		 -4962,		/* B1 = -0.302887 */
+		 10815,		/* B0 = 0.330063 */
+		 15924,		/* A1 = -0.971924 */
+		 -32634,	/* A2 = 0.995941 */
+		 18880,		/* B2 = 0.576172 */
+		 -9364,		/* B1 = -0.571594 */
+		 18880,		/* B0 = 0.576172 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1380 */
+		15247,		/* A1 = -0.930603 */
+		 -32397,	/* A2 = 0.988708 */
+		 -244,		/* B2 = -0.007451 */
+		 0,		/* B1 = 0.000000 */
+		 244,		/* B0 = 0.007451 */
+		 14989,		/* A1 = -0.914886 */
+		 -32627,	/* A2 = 0.995697 */
+		 18961,		/* B2 = 0.578644 */
+		 -8498,		/* B1 = -0.518707 */
+		 18961,		/* B0 = 0.578644 */
+		 15608,		/* A1 = -0.952667 */
+		 -32628,	/* A2 = 0.995758 */
+		 11145,		/* B2 = 0.340134 */
+		 -5430,		/* B1 = -0.331467 */
+		 11145,		/* B0 = 0.340134 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1400 */
+		14780,		/* A1 = -0.902130 */
+		 -32393,	/* A2 = 0.988586 */
+		 -396,		/* B2 = -0.012086 */
+		 0,		/* B1 = 0.000000 */
+		 396,		/* B0 = 0.012086 */
+		 14510,		/* A1 = -0.885651 */
+		 -32630,	/* A2 = 0.995819 */
+		 6326,		/* B2 = 0.193069 */
+		 -2747,		/* B1 = -0.167671 */
+		 6326,		/* B0 = 0.193069 */
+		 15154,		/* A1 = -0.924957 */
+		 -32632,	/* A2 = 0.995850 */
+		 23235,		/* B2 = 0.709076 */
+		 -10983,	/* B1 = -0.670380 */
+		 23235,		/* B0 = 0.709076 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1477 */
+		13005,		/* A1 = -0.793793 */
+		 -32368,	/* A2 = 0.987823 */
+		 -500,		/* B2 = -0.015265 */
+		 0,		/* B1 = 0.000000 */
+		 500,		/* B0 = 0.015265 */
+		 12708,		/* A1 = -0.775665 */
+		 -32615,	/* A2 = 0.995331 */
+		 11420,		/* B2 = 0.348526 */
+		 -4306,		/* B1 = -0.262833 */
+		 11420,		/* B0 = 0.348526 */
+		 13397,		/* A1 = -0.817688 */
+		 -32615,	/* A2 = 0.995361 */
+		 9454,		/* B2 = 0.288528 */
+		 -3981,		/* B1 = -0.243027 */
+		 9454,		/* B0 = 0.288528 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1600 */
+		10046,		/* A1 = -0.613190 */
+		 -32331,	/* A2 = 0.986694 */
+		 -455,		/* B2 = -0.013915 */
+		 0,		/* B1 = 0.000000 */
+		 455,		/* B0 = 0.013915 */
+		 9694,		/* A1 = -0.591705 */
+		 -32601,	/* A2 = 0.994934 */
+		 6023,		/* B2 = 0.183815 */
+		 -1708,		/* B1 = -0.104279 */
+		 6023,		/* B0 = 0.183815 */
+		 10478,		/* A1 = -0.639587 */
+		 -32603,	/* A2 = 0.994965 */
+		 22031,		/* B2 = 0.672333 */
+		 -7342,		/* B1 = -0.448151 */
+		 22031,		/* B0 = 0.672333 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1633_1638[] */
+		9181,		/* A1 = 0.560394 */
+		 -32256,	/* A2 = -0.984375 */
+		 -556,		/* B2 = -0.016975 */
+		 0,		/* B1 = 0 */
+		 556,		/* B0 = 0.016975 */
+		 8757,		/* A1 = 0.534515 */
+		 -32574,	/* A2 = -0.99408 */
+		 8443,		/* B2 = 0.25769 */
+		 -2135,		/* B1 = -0.130341 */
+		 8443,		/* B0 = 0.25769 */
+		 9691,		/* A1 = 0.591522 */
+		 -32574,	/* A2 = -0.99411 */
+		 15446,		/* B2 = 0.471375 */
+		 -4809,		/* B1 = -0.293579 */
+		 15446,		/* B0 = 0.471375 */
+		 7,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1800 */
+		5076,		/* A1 = -0.309875 */
+		 -32304,	/* A2 = 0.985840 */
+		 -508,		/* B2 = -0.015503 */
+		 0,		/* B1 = 0.000000 */
+		 508,		/* B0 = 0.015503 */
+		 4646,		/* A1 = -0.283600 */
+		 -32605,	/* A2 = 0.995026 */
+		 6742,		/* B2 = 0.205780 */
+		 -878,		/* B1 = -0.053635 */
+		 6742,		/* B0 = 0.205780 */
+		 5552,		/* A1 = -0.338928 */
+		 -32605,	/* A2 = 0.995056 */
+		 23667,		/* B2 = 0.722260 */
+		 -4297,		/* B1 = -0.262329 */
+		 23667,		/* B0 = 0.722260 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+	{			/* f1860 */
+		3569,		/* A1 = -0.217865 */
+		 -32292,	/* A2 = 0.985504 */
+		 -239,		/* B2 = -0.007322 */
+		 0,		/* B1 = 0.000000 */
+		 239,		/* B0 = 0.007322 */
+		 3117,		/* A1 = -0.190277 */
+		 -32603,	/* A2 = 0.994965 */
+		 18658,		/* B2 = 0.569427 */
+		 -1557,		/* B1 = -0.095032 */
+		 18658,		/* B0 = 0.569427 */
+		 4054,		/* A1 = -0.247437 */
+		 -32603,	/* A2 = 0.994965 */
+		 18886,		/* B2 = 0.576385 */
+		 -2566,		/* B1 = -0.156647 */
+		 18886,		/* B0 = 0.576385 */
+		 5,		/* Internal filter scaling */
+		 159,		/* Minimum in-band energy threshold */
+		 21,		/* 21/32 in-band to broad-band ratio */
+		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+	},
+};
+static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
+{
+	unsigned short cmd;
+	int cnt, max;
+
+	if (jf->filter > 3) {
+		return -1;
+	}
+	if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))	/* Select Filter */
+
+		return -1;
+	if (!jf->enable) {
+		if (ixj_WriteDSPCommand(0x5152, j))		/* Disable Filter */
+
+			return -1;
+		else
+			return 0;
+	} else {
+		if (ixj_WriteDSPCommand(0x5153, j))		/* Enable Filter */
+
+			return -1;
+		/* Select the filter (f0 - f3) to use. */
+		if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))
+			return -1;
+	}
+	if (jf->freq < 12 && jf->freq > 3) {
+		/* Select the frequency for the selected filter. */
+		if (ixj_WriteDSPCommand(0x5170 + jf->freq, j))
+			return -1;
+	} else if (jf->freq > 11) {
+		/* We need to load a programmable filter set for undefined */
+		/* frequencies.  So we will point the filter to a programmable set. */
+		/* Since there are only 4 filters and 4 programmable sets, we will */
+		/* just point the filter to the same number set and program it for the */
+		/* frequency we want. */
+		if (ixj_WriteDSPCommand(0x5170 + jf->filter, j))
+			return -1;
+		if (j->ver.low != 0x12) {
+			cmd = 0x515B;
+			max = 19;
+		} else {
+			cmd = 0x515E;
+			max = 15;
+		}
+		if (ixj_WriteDSPCommand(cmd, j))
+			return -1;
+		for (cnt = 0; cnt < max; cnt++) {
+			if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j))
+				return -1;
+		}
+	}
+	j->filter_en[jf->filter] = jf->enable;
+	return 0;
+}
+
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr)
+{
+	unsigned short cmd;
+	int cnt, max;
+	if (jfr->filter > 3) {
+		return -1;
+	}
+	if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))	/* Select Filter */
+		return -1;
+
+	if (!jfr->enable) {
+		if (ixj_WriteDSPCommand(0x5152, j))		/* Disable Filter */
+			return -1;
+		else
+			return 0;
+	} else {
+		if (ixj_WriteDSPCommand(0x5153, j))		/* Enable Filter */
+			return -1;
+		/* Select the filter (f0 - f3) to use. */
+		if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))
+			return -1;
+	}
+	/* We need to load a programmable filter set for undefined */
+	/* frequencies.  So we will point the filter to a programmable set. */
+	/* Since there are only 4 filters and 4 programmable sets, we will */
+	/* just point the filter to the same number set and program it for the */
+	/* frequency we want. */
+	if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j))
+		return -1;
+	if (j->ver.low != 0x12) {
+		cmd = 0x515B;
+		max = 19;
+	} else {
+		cmd = 0x515E;
+		max = 15;
+	}
+	if (ixj_WriteDSPCommand(cmd, j))
+		return -1;
+	for (cnt = 0; cnt < max; cnt++) {
+		if (ixj_WriteDSPCommand(jfr->coeff[cnt], j))
+			return -1;
+	}
+	j->filter_en[jfr->filter] = jfr->enable;
+	return 0;
+}
+
+static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
+{
+	int freq0, freq1;
+	unsigned short data;
+	if (ti->freq0) {
+		freq0 = ti->freq0;
+	} else {
+		freq0 = 0x7FFF;
+	}
+
+	if (ti->freq1) {
+		freq1 = ti->freq1;
+	} else {
+		freq1 = 0x7FFF;
+	}
+
+	if(ti->tone_index > 12 && ti->tone_index < 28)
+	{
+		if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j))
+			return -1;
+		if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j))
+			return -1;
+		data = freq0;
+		if (ixj_WriteDSPCommand(data, j))
+			return -1;
+		data = freq1;
+		if (ixj_WriteDSPCommand(data, j))
+			return -1;
+	}
+	return freq0;
+}
+
diff --git a/drivers/staging/telephony/ixj.h b/drivers/staging/telephony/ixj.h
new file mode 100644
index 0000000..2c84113
--- /dev/null
+++ b/drivers/staging/telephony/ixj.h
@@ -0,0 +1,1322 @@
+/******************************************************************************
+ *    ixj.h
+ *
+ *
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
+ *
+ *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
+ *
+ *    This program is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU General Public License
+ *    as published by the Free Software Foundation; either version
+ *    2 of the License, or (at your option) any later version.
+ *
+ * Author:          Ed Okerson, <eokerson@quicknet.net>
+ *    
+ * Contributors:    Greg Herlein, <gherlein@quicknet.net>
+ *                  David W. Erhart, <derhart@quicknet.net>
+ *                  John Sellers, <jsellers@quicknet.net>
+ *                  Mike Preston, <mpreston@quicknet.net>
+ *
+ * More information about the hardware related to this driver can be found
+ * at our website:    http://www.quicknet.net
+ *
+ * Fixes:
+ *
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION 
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ *****************************************************************************/
+#define IXJ_VERSION 3031
+
+#include <linux/types.h>
+
+#include <linux/ixjuser.h>
+#include <linux/phonedev.h>
+
+typedef __u16 WORD;
+typedef __u32 DWORD;
+typedef __u8 BYTE;
+
+#ifndef IXJMAX
+#define IXJMAX 16
+#endif
+
+/******************************************************************************
+*
+*  This structure when unioned with the structures below makes simple byte
+*  access to the registers easier.
+*
+******************************************************************************/
+typedef struct {
+	unsigned char low;
+	unsigned char high;
+} BYTES;
+
+typedef union {
+        BYTES bytes;
+        short word;
+} IXJ_WORD;
+
+typedef struct{
+	unsigned int b0:1;
+	unsigned int b1:1;
+	unsigned int b2:1;
+	unsigned int b3:1;
+	unsigned int b4:1;
+	unsigned int b5:1;
+	unsigned int b6:1;
+	unsigned int b7:1;
+} IXJ_CBITS;
+
+typedef union{
+	IXJ_CBITS cbits;
+	  char  cbyte;
+} IXJ_CBYTE;
+
+/******************************************************************************
+*
+*  This structure represents the Hardware Control Register of the CT8020/8021
+*  The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
+*  Internet LineJACK
+*
+******************************************************************************/
+typedef struct {
+	unsigned int rxrdy:1;
+	unsigned int txrdy:1;
+	unsigned int status:1;
+	unsigned int auxstatus:1;
+	unsigned int rxdma:1;
+	unsigned int txdma:1;
+	unsigned int rxburst:1;
+	unsigned int txburst:1;
+	unsigned int dmadir:1;
+	unsigned int cont:1;
+	unsigned int irqn:1;
+	unsigned int t:5;
+} HCRBIT;
+
+typedef union {
+	HCRBIT bits;
+	BYTES bytes;
+} HCR;
+
+/******************************************************************************
+*
+*  This structure represents the Hardware Status Register of the CT8020/8021
+*  The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
+*  Internet LineJACK
+*
+******************************************************************************/
+typedef struct {
+	unsigned int controlrdy:1;
+	unsigned int auxctlrdy:1;
+	unsigned int statusrdy:1;
+	unsigned int auxstatusrdy:1;
+	unsigned int rxrdy:1;
+	unsigned int txrdy:1;
+	unsigned int restart:1;
+	unsigned int irqn:1;
+	unsigned int rxdma:1;
+	unsigned int txdma:1;
+	unsigned int cohostshutdown:1;
+	unsigned int t:5;
+} HSRBIT;
+
+typedef union {
+	HSRBIT bits;
+	BYTES bytes;
+} HSR;
+
+/******************************************************************************
+*
+*  This structure represents the General Purpose IO Register of the CT8020/8021
+*  The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
+*  Internet LineJACK
+*
+******************************************************************************/
+typedef struct {
+	unsigned int x:1;
+	unsigned int gpio1:1;
+	unsigned int gpio2:1;
+	unsigned int gpio3:1;
+	unsigned int gpio4:1;
+	unsigned int gpio5:1;
+	unsigned int gpio6:1;
+	unsigned int gpio7:1;
+	unsigned int xread:1;
+	unsigned int gpio1read:1;
+	unsigned int gpio2read:1;
+	unsigned int gpio3read:1;
+	unsigned int gpio4read:1;
+	unsigned int gpio5read:1;
+	unsigned int gpio6read:1;
+	unsigned int gpio7read:1;
+} GPIOBIT;
+
+typedef union {
+	GPIOBIT bits;
+	BYTES bytes;
+	unsigned short word;
+} GPIO;
+
+/******************************************************************************
+*
+*  This structure represents the Line Monitor status response
+*
+******************************************************************************/
+typedef struct {
+	unsigned int digit:4;
+	unsigned int cpf_valid:1;
+	unsigned int dtmf_valid:1;
+	unsigned int peak:1;
+	unsigned int z:1;
+	unsigned int f0:1;
+	unsigned int f1:1;
+	unsigned int f2:1;
+	unsigned int f3:1;
+	unsigned int frame:4;
+} LMON;
+
+typedef union {
+	LMON bits;
+	BYTES bytes;
+} DTMF;
+
+typedef struct {
+	unsigned int z:7;
+	unsigned int dtmf_en:1;
+	unsigned int y:4;
+	unsigned int F3:1;
+	unsigned int F2:1;
+	unsigned int F1:1;
+	unsigned int F0:1;
+} CP;
+
+typedef union {
+	CP bits;
+	BYTES bytes;
+} CPTF;
+
+/******************************************************************************
+*
+*  This structure represents the Status Control Register on the Internet
+*  LineJACK
+*
+******************************************************************************/
+typedef struct {
+	unsigned int c0:1;
+	unsigned int c1:1;
+	unsigned int stereo:1;
+	unsigned int daafsyncen:1;
+	unsigned int led1:1;
+	unsigned int led2:1;
+	unsigned int led3:1;
+	unsigned int led4:1;
+} PSCRWI;			/* Internet LineJACK and Internet PhoneJACK Lite */
+
+typedef struct {
+	unsigned int eidp:1;
+	unsigned int eisd:1;
+	unsigned int x:6;
+} PSCRWP;			/* Internet PhoneJACK PCI */
+
+typedef union {
+	PSCRWI bits;
+	PSCRWP pcib;
+	char byte;
+} PLD_SCRW;
+
+typedef struct {
+	unsigned int c0:1;
+	unsigned int c1:1;
+	unsigned int x:1;
+	unsigned int d0ee:1;
+	unsigned int mixerbusy:1;
+	unsigned int sci:1;
+	unsigned int dspflag:1;
+	unsigned int daaflag:1;
+} PSCRRI;
+
+typedef struct {
+	unsigned int eidp:1;
+	unsigned int eisd:1;
+	unsigned int x:4;
+	unsigned int dspflag:1;
+	unsigned int det:1;
+} PSCRRP;
+
+typedef union {
+	PSCRRI bits;
+	PSCRRP pcib;
+	char byte;
+} PLD_SCRR;
+
+/******************************************************************************
+*
+*  These structures represents the SLIC Control Register on the
+*  Internet LineJACK
+*
+******************************************************************************/
+typedef struct {
+	unsigned int c1:1;
+	unsigned int c2:1;
+	unsigned int c3:1;
+	unsigned int b2en:1;
+	unsigned int spken:1;
+	unsigned int rly1:1;
+	unsigned int rly2:1;
+	unsigned int rly3:1;
+} PSLICWRITE;
+
+typedef struct {
+	unsigned int state:3;
+	unsigned int b2en:1;
+	unsigned int spken:1;
+	unsigned int c3:1;
+	unsigned int potspstn:1;
+	unsigned int det:1;
+} PSLICREAD;
+
+typedef struct {
+	unsigned int c1:1;
+	unsigned int c2:1;
+	unsigned int c3:1;
+	unsigned int b2en:1;
+	unsigned int e1:1;
+	unsigned int mic:1;
+	unsigned int spk:1;
+	unsigned int x:1;
+} PSLICPCI;
+
+typedef union {
+	PSLICPCI pcib;
+	PSLICWRITE bits;
+	PSLICREAD slic;
+	char byte;
+} PLD_SLICW;
+
+typedef union {
+	PSLICPCI pcib;
+	PSLICREAD bits;
+	char byte;
+} PLD_SLICR;
+
+/******************************************************************************
+*
+*  These structures represents the Clock Control Register on the
+*  Internet LineJACK
+*
+******************************************************************************/
+typedef struct {
+	unsigned int clk0:1;
+	unsigned int clk1:1;
+	unsigned int clk2:1;
+	unsigned int x0:1;
+	unsigned int slic_e1:1;
+	unsigned int x1:1;
+	unsigned int x2:1;
+	unsigned int x3:1;
+} PCLOCK;
+
+typedef union {
+	PCLOCK bits;
+	char byte;
+} PLD_CLOCK;
+
+/******************************************************************************
+*
+*  These structures deal with the mixer on the Internet LineJACK
+*
+******************************************************************************/
+
+typedef struct {
+	unsigned short vol[10];
+	unsigned int recsrc;
+	unsigned int modcnt;
+	unsigned short micpreamp;
+} MIX;
+
+/******************************************************************************
+*
+*  These structures deal with the control logic on the Internet PhoneCARD
+*
+******************************************************************************/
+typedef struct {
+	unsigned int x0:4;	/* unused bits */
+
+	unsigned int ed:1;	/* Event Detect */
+
+	unsigned int drf:1;	/* SmartCABLE Removal Flag 1=no cable */
+
+	unsigned int dspf:1;	/* DSP Flag 1=DSP Ready */
+
+	unsigned int crr:1;	/* Control Register Ready */
+
+} COMMAND_REG1;
+
+typedef union {
+	COMMAND_REG1 bits;
+	unsigned char byte;
+} PCMCIA_CR1;
+
+typedef struct {
+	unsigned int x0:4;	/* unused bits */
+
+	unsigned int rstc:1;	/* SmartCABLE Reset */
+
+	unsigned int pwr:1;	/* SmartCABLE Power */
+
+	unsigned int x1:2;	/* unused bits */
+
+} COMMAND_REG2;
+
+typedef union {
+	COMMAND_REG2 bits;
+	unsigned char byte;
+} PCMCIA_CR2;
+
+typedef struct {
+	unsigned int addr:5;	/* R/W SmartCABLE Register Address */
+
+	unsigned int rw:1;	/* Read / Write flag */
+
+	unsigned int dev:2;	/* 2 bit SmartCABLE Device Address */
+
+} CONTROL_REG;
+
+typedef union {
+	CONTROL_REG bits;
+	unsigned char byte;
+} PCMCIA_SCCR;
+
+typedef struct {
+	unsigned int hsw:1;
+	unsigned int det:1;
+	unsigned int led2:1;
+	unsigned int led1:1;
+	unsigned int ring1:1;
+	unsigned int ring0:1;
+	unsigned int x:1;
+	unsigned int powerdown:1;
+} PCMCIA_SLIC_REG;
+
+typedef union {
+	PCMCIA_SLIC_REG bits;
+	unsigned char byte;
+} PCMCIA_SLIC;
+
+typedef struct {
+	unsigned int cpd:1;	/* Chip Power Down */
+
+	unsigned int mpd:1;	/* MIC Bias Power Down */
+
+	unsigned int hpd:1;	/* Handset Drive Power Down */
+
+	unsigned int lpd:1;	/* Line Drive Power Down */
+
+	unsigned int spd:1;	/* Speaker Drive Power Down */
+
+	unsigned int x:2;	/* unused bits */
+
+	unsigned int sr:1;	/* Software Reset */
+
+} Si3CONTROL1;
+
+typedef union {
+	Si3CONTROL1 bits;
+	unsigned char byte;
+} Si3C1;
+
+typedef struct {
+	unsigned int al:1;	/* Analog Loopback DAC analog -> ADC analog */
+
+	unsigned int dl2:1;	/* Digital Loopback DAC -> ADC one bit */
+
+	unsigned int dl1:1;	/* Digital Loopback ADC -> DAC one bit */
+
+	unsigned int pll:1;	/* 1 = div 10, 0 = div 5 */
+
+	unsigned int hpd:1;	/* HPF disable */
+
+	unsigned int x:3;	/* unused bits */
+
+} Si3CONTROL2;
+
+typedef union {
+	Si3CONTROL2 bits;
+	unsigned char byte;
+} Si3C2;
+
+typedef struct {
+	unsigned int iir:1;	/* 1 enables IIR, 0 enables FIR */
+
+	unsigned int him:1;	/* Handset Input Mute */
+
+	unsigned int mcm:1;	/* MIC In Mute */
+
+	unsigned int mcg:2;	/* MIC In Gain */
+
+	unsigned int lim:1;	/* Line In Mute */
+
+	unsigned int lig:2;	/* Line In Gain */
+
+} Si3RXGAIN;
+
+typedef union {
+	Si3RXGAIN bits;
+	unsigned char byte;
+} Si3RXG;
+
+typedef struct {
+	unsigned int hom:1;	/* Handset Out Mute */
+
+	unsigned int lom:1;	/* Line Out Mute */
+
+	unsigned int rxg:5;	/* RX PGA Gain */
+
+	unsigned int x:1;	/* unused bit */
+
+} Si3ADCVOLUME;
+
+typedef union {
+	Si3ADCVOLUME bits;
+	unsigned char byte;
+} Si3ADC;
+
+typedef struct {
+	unsigned int srm:1;	/* Speaker Right Mute */
+
+	unsigned int slm:1;	/* Speaker Left Mute */
+
+	unsigned int txg:5;	/* TX PGA Gain */
+
+	unsigned int x:1;	/* unused bit */
+
+} Si3DACVOLUME;
+
+typedef union {
+	Si3DACVOLUME bits;
+	unsigned char byte;
+} Si3DAC;
+
+typedef struct {
+	unsigned int x:5;	/* unused bit */
+
+	unsigned int losc:1;	/* Line Out Short Circuit */
+
+	unsigned int srsc:1;	/* Speaker Right Short Circuit */
+
+	unsigned int slsc:1;	/* Speaker Left Short Circuit */
+
+} Si3STATUSREPORT;
+
+typedef union {
+	Si3STATUSREPORT bits;
+	unsigned char byte;
+} Si3STAT;
+
+typedef struct {
+	unsigned int sot:2;	/* Speaker Out Attenuation */
+
+	unsigned int lot:2;	/* Line Out Attenuation */
+
+	unsigned int x:4;	/* unused bits */
+
+} Si3ANALOGATTN;
+
+typedef union {
+	Si3ANALOGATTN bits;
+	unsigned char byte;
+} Si3AATT;
+
+/******************************************************************************
+*
+*  These structures deal with the DAA on the Internet LineJACK
+*
+******************************************************************************/
+
+typedef struct _DAA_REGS {
+	/*----------------------------------------------- */
+	/* SOP Registers */
+	/* */
+	BYTE bySOP;
+
+	union _SOP_REGS {
+		struct _SOP {
+			union	/* SOP - CR0 Register */
+			 {
+				BYTE reg;
+				struct _CR0_BITREGS {
+					BYTE CLK_EXT:1;		/* cr0[0:0] */
+
+					BYTE RIP:1;	/* cr0[1:1] */
+
+					BYTE AR:1;	/* cr0[2:2] */
+
+					BYTE AX:1;	/* cr0[3:3] */
+
+					BYTE FRR:1;	/* cr0[4:4] */
+
+					BYTE FRX:1;	/* cr0[5:5] */
+
+					BYTE IM:1;	/* cr0[6:6] */
+
+					BYTE TH:1;	/* cr0[7:7] */
+
+				} bitreg;
+			} cr0;
+
+			union	/* SOP - CR1 Register */
+			 {
+				BYTE reg;
+				struct _CR1_REGS {
+					BYTE RM:1;	/* cr1[0:0] */
+
+					BYTE RMR:1;	/* cr1[1:1] */
+
+					BYTE No_auto:1;		/* cr1[2:2] */
+
+					BYTE Pulse:1;	/* cr1[3:3] */
+
+					BYTE P_Tone1:1;		/* cr1[4:4] */
+
+					BYTE P_Tone2:1;		/* cr1[5:5] */
+
+					BYTE E_Tone1:1;		/* cr1[6:6] */
+
+					BYTE E_Tone2:1;		/* cr1[7:7] */
+
+				} bitreg;
+			} cr1;
+
+			union	/* SOP - CR2 Register */
+			 {
+				BYTE reg;
+				struct _CR2_REGS {
+					BYTE Call_II:1;		/* CR2[0:0] */
+
+					BYTE Call_I:1;	/* CR2[1:1] */
+
+					BYTE Call_en:1;		/* CR2[2:2] */
+
+					BYTE Call_pon:1;	/* CR2[3:3] */
+
+					BYTE IDR:1;	/* CR2[4:4] */
+
+					BYTE COT_R:3;	/* CR2[5:7] */
+
+				} bitreg;
+			} cr2;
+
+			union	/* SOP - CR3 Register */
+			 {
+				BYTE reg;
+				struct _CR3_REGS {
+					BYTE DHP_X:1;	/* CR3[0:0] */
+
+					BYTE DHP_R:1;	/* CR3[1:1] */
+
+					BYTE Cal_pctl:1;	/* CR3[2:2] */
+
+					BYTE SEL:1;	/* CR3[3:3] */
+
+					BYTE TestLoops:4;	/* CR3[4:7] */
+
+				} bitreg;
+			} cr3;
+
+			union	/* SOP - CR4 Register */
+			 {
+				BYTE reg;
+				struct _CR4_REGS {
+					BYTE Fsc_en:1;	/* CR4[0:0] */
+
+					BYTE Int_en:1;	/* CR4[1:1] */
+
+					BYTE AGX:2;	/* CR4[2:3] */
+
+					BYTE AGR_R:2;	/* CR4[4:5] */
+
+					BYTE AGR_Z:2;	/* CR4[6:7] */
+
+				} bitreg;
+			} cr4;
+
+			union	/* SOP - CR5 Register */
+			 {
+				BYTE reg;
+				struct _CR5_REGS {
+					BYTE V_0:1;	/* CR5[0:0] */
+
+					BYTE V_1:1;	/* CR5[1:1] */
+
+					BYTE V_2:1;	/* CR5[2:2] */
+
+					BYTE V_3:1;	/* CR5[3:3] */
+
+					BYTE V_4:1;	/* CR5[4:4] */
+
+					BYTE V_5:1;	/* CR5[5:5] */
+
+					BYTE V_6:1;	/* CR5[6:6] */
+
+					BYTE V_7:1;	/* CR5[7:7] */
+
+				} bitreg;
+			} cr5;
+
+			union	/* SOP - CR6 Register */
+			 {
+				BYTE reg;
+				struct _CR6_REGS {
+					BYTE reserved:8;	/* CR6[0:7] */
+
+				} bitreg;
+			} cr6;
+
+			union	/* SOP - CR7 Register */
+			 {
+				BYTE reg;
+				struct _CR7_REGS {
+					BYTE reserved:8;	/* CR7[0:7] */
+
+				} bitreg;
+			} cr7;
+		} SOP;
+
+		BYTE ByteRegs[sizeof(struct _SOP)];
+
+	} SOP_REGS;
+
+	/* DAA_REGS.SOP_REGS.SOP.CR5.reg */
+	/* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */
+	/* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */
+	/* DAA_REGS.SOP_REGS.ByteRegs[5] */
+
+	/*----------------------------------------------- */
+	/* XOP Registers */
+	/* */
+	BYTE byXOP;
+
+	union _XOP_REGS {
+		struct _XOP {
+			union	XOPXR0/* XOP - XR0 Register - Read values */
+			 {
+				BYTE reg;
+				struct _XR0_BITREGS {
+					BYTE SI_0:1;	/* XR0[0:0] - Read */
+
+					BYTE SI_1:1;	/* XR0[1:1] - Read */
+
+					BYTE VDD_OK:1;	/* XR0[2:2] - Read */
+
+					BYTE Caller_ID:1;	/* XR0[3:3] - Read */
+
+					BYTE RING:1;	/* XR0[4:4] - Read */
+
+					BYTE Cadence:1;		/* XR0[5:5] - Read */
+
+					BYTE Wake_up:1;		/* XR0[6:6] - Read */
+
+					BYTE RMR:1;	/* XR0[7:7] - Read */
+
+				} bitreg;
+			} xr0;
+
+			union	/* XOP - XR1 Register */
+			 {
+				BYTE reg;
+				struct _XR1_BITREGS {
+					BYTE M_SI_0:1;	/* XR1[0:0] */
+
+					BYTE M_SI_1:1;	/* XR1[1:1] */
+
+					BYTE M_VDD_OK:1;	/* XR1[2:2] */
+
+					BYTE M_Caller_ID:1;	/* XR1[3:3] */
+
+					BYTE M_RING:1;	/* XR1[4:4] */
+
+					BYTE M_Cadence:1;	/* XR1[5:5] */
+
+					BYTE M_Wake_up:1;	/* XR1[6:6] */
+
+					BYTE unused:1;	/* XR1[7:7] */
+
+				} bitreg;
+			} xr1;
+
+			union	/* XOP - XR2 Register */
+			 {
+				BYTE reg;
+				struct _XR2_BITREGS {
+					BYTE CTO0:1;	/* XR2[0:0] */
+
+					BYTE CTO1:1;	/* XR2[1:1] */
+
+					BYTE CTO2:1;	/* XR2[2:2] */
+
+					BYTE CTO3:1;	/* XR2[3:3] */
+
+					BYTE CTO4:1;	/* XR2[4:4] */
+
+					BYTE CTO5:1;	/* XR2[5:5] */
+
+					BYTE CTO6:1;	/* XR2[6:6] */
+
+					BYTE CTO7:1;	/* XR2[7:7] */
+
+				} bitreg;
+			} xr2;
+
+			union	/* XOP - XR3 Register */
+			 {
+				BYTE reg;
+				struct _XR3_BITREGS {
+					BYTE DCR0:1;	/* XR3[0:0] */
+
+					BYTE DCR1:1;	/* XR3[1:1] */
+
+					BYTE DCI:1;	/* XR3[2:2] */
+
+					BYTE DCU0:1;	/* XR3[3:3] */
+
+					BYTE DCU1:1;	/* XR3[4:4] */
+
+					BYTE B_off:1;	/* XR3[5:5] */
+
+					BYTE AGB0:1;	/* XR3[6:6] */
+
+					BYTE AGB1:1;	/* XR3[7:7] */
+
+				} bitreg;
+			} xr3;
+
+			union	/* XOP - XR4 Register */
+			 {
+				BYTE reg;
+				struct _XR4_BITREGS {
+					BYTE C_0:1;	/* XR4[0:0] */
+
+					BYTE C_1:1;	/* XR4[1:1] */
+
+					BYTE C_2:1;	/* XR4[2:2] */
+
+					BYTE C_3:1;	/* XR4[3:3] */
+
+					BYTE C_4:1;	/* XR4[4:4] */
+
+					BYTE C_5:1;	/* XR4[5:5] */
+
+					BYTE C_6:1;	/* XR4[6:6] */
+
+					BYTE C_7:1;	/* XR4[7:7] */
+
+				} bitreg;
+			} xr4;
+
+			union	/* XOP - XR5 Register */
+			 {
+				BYTE reg;
+				struct _XR5_BITREGS {
+					BYTE T_0:1;	/* XR5[0:0] */
+
+					BYTE T_1:1;	/* XR5[1:1] */
+
+					BYTE T_2:1;	/* XR5[2:2] */
+
+					BYTE T_3:1;	/* XR5[3:3] */
+
+					BYTE T_4:1;	/* XR5[4:4] */
+
+					BYTE T_5:1;	/* XR5[5:5] */
+
+					BYTE T_6:1;	/* XR5[6:6] */
+
+					BYTE T_7:1;	/* XR5[7:7] */
+
+				} bitreg;
+			} xr5;
+
+			union	/* XOP - XR6 Register - Read Values */
+			 {
+				BYTE reg;
+				struct _XR6_BITREGS {
+					BYTE CPS0:1;	/* XR6[0:0] */
+
+					BYTE CPS1:1;	/* XR6[1:1] */
+
+					BYTE unused1:2;		/* XR6[2:3] */
+
+					BYTE CLK_OFF:1;		/* XR6[4:4] */
+
+					BYTE unused2:3;		/* XR6[5:7] */
+
+				} bitreg;
+			} xr6;
+
+			union	/* XOP - XR7 Register */
+			 {
+				BYTE reg;
+				struct _XR7_BITREGS {
+					BYTE unused1:1;		/* XR7[0:0] */
+
+					BYTE Vdd0:1;	/* XR7[1:1] */
+
+					BYTE Vdd1:1;	/* XR7[2:2] */
+
+					BYTE unused2:5;		/* XR7[3:7] */
+
+				} bitreg;
+			} xr7;
+		} XOP;
+
+		BYTE ByteRegs[sizeof(struct _XOP)];
+
+	} XOP_REGS;
+
+	/* DAA_REGS.XOP_REGS.XOP.XR7.reg */
+	/* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */
+	/* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */
+	/* DAA_REGS.XOP_REGS.ByteRegs[7] */
+
+	/*----------------------------------------------- */
+	/* COP Registers */
+	/* */
+	BYTE byCOP;
+
+	union _COP_REGS {
+		struct _COP {
+			BYTE THFilterCoeff_1[8];	/* COP - TH Filter Coefficients,      CODE=0, Part 1 */
+
+			BYTE THFilterCoeff_2[8];	/* COP - TH Filter Coefficients,      CODE=1, Part 2 */
+
+			BYTE THFilterCoeff_3[8];	/* COP - TH Filter Coefficients,      CODE=2, Part 3 */
+
+			BYTE RingerImpendance_1[8];	/* COP - Ringer Impendance Coefficients,  CODE=3, Part 1 */
+
+			BYTE IMFilterCoeff_1[8];	/* COP - IM Filter Coefficients,      CODE=4, Part 1 */
+
+			BYTE IMFilterCoeff_2[8];	/* COP - IM Filter Coefficients,      CODE=5, Part 2 */
+
+			BYTE RingerImpendance_2[8];	/* COP - Ringer Impendance Coefficients,  CODE=6, Part 2 */
+
+			BYTE FRRFilterCoeff[8];		/* COP - FRR Filter Coefficients,      CODE=7 */
+
+			BYTE FRXFilterCoeff[8];		/* COP - FRX Filter Coefficients,      CODE=8 */
+
+			BYTE ARFilterCoeff[4];	/* COP - AR Filter Coefficients,      CODE=9 */
+
+			BYTE AXFilterCoeff[4];	/* COP - AX Filter Coefficients,      CODE=10  */
+
+			BYTE Tone1Coeff[4];	/* COP - Tone1 Coefficients,        CODE=11 */
+
+			BYTE Tone2Coeff[4];	/* COP - Tone2 Coefficients,        CODE=12 */
+
+			BYTE LevelmeteringRinging[4];	/* COP - Levelmetering Ringing,        CODE=13 */
+
+			BYTE CallerID1stTone[8];	/* COP - Caller ID 1st Tone,        CODE=14 */
+
+			BYTE CallerID2ndTone[8];	/* COP - Caller ID 2nd Tone,        CODE=15 */
+
+		} COP;
+
+		BYTE ByteRegs[sizeof(struct _COP)];
+
+	} COP_REGS;
+
+	/* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */
+	/* DAA_REGS.COP_REGS.COP.XR7.bitreg */
+	/* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */
+	/* DAA_REGS.COP_REGS.ByteRegs[57] */
+
+	/*----------------------------------------------- */
+	/* CAO Registers */
+	/* */
+	BYTE byCAO;
+
+	union _CAO_REGS {
+		struct _CAO {
+			BYTE CallerID[512];	/* CAO - Caller ID Bytes */
+
+		} CAO;
+
+		BYTE ByteRegs[sizeof(struct _CAO)];
+	} CAO_REGS;
+
+	union			/* XOP - XR0 Register - Write values */
+	 {
+		BYTE reg;
+		struct _XR0_BITREGSW {
+			BYTE SO_0:1;	/* XR1[0:0] - Write */
+
+			BYTE SO_1:1;	/* XR1[1:1] - Write */
+
+			BYTE SO_2:1;	/* XR1[2:2] - Write */
+
+			BYTE unused:5;	/* XR1[3:7] - Write */
+
+		} bitreg;
+	} XOP_xr0_W;
+
+	union			/* XOP - XR6 Register - Write values */
+	 {
+		BYTE reg;
+		struct _XR6_BITREGSW {
+			BYTE unused1:4;		/* XR6[0:3] */
+
+			BYTE CLK_OFF:1;		/* XR6[4:4] */
+
+			BYTE unused2:3;		/* XR6[5:7] */
+
+		} bitreg;
+	} XOP_xr6_W;
+
+} DAA_REGS;
+
+#define ALISDAA_ID_BYTE      0x81
+#define ALISDAA_CALLERID_SIZE  512
+
+/*------------------------------ */
+/* */
+/*  Misc definitions */
+/* */
+
+/* Power Up Operation */
+#define SOP_PU_SLEEP    0
+#define SOP_PU_RINGING    1
+#define SOP_PU_CONVERSATION  2
+#define SOP_PU_PULSEDIALING  3
+#define SOP_PU_RESET    4
+
+#define ALISDAA_CALLERID_SIZE 512
+
+#define PLAYBACK_MODE_COMPRESSED	0	/*        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
+#define PLAYBACK_MODE_TRUESPEECH_V40	0	/*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
+#define PLAYBACK_MODE_TRUESPEECH	8	/*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */
+#define PLAYBACK_MODE_ULAW		2	/*        Selects: 64 Kbit/sec MuA-law PCM */
+#define PLAYBACK_MODE_ALAW		10	/*        Selects: 64 Kbit/sec A-law PCM */
+#define PLAYBACK_MODE_16LINEAR		6	/*        Selects: 128 Kbit/sec 16-bit linear */
+#define PLAYBACK_MODE_8LINEAR		4	/*        Selects: 64 Kbit/sec 8-bit signed linear */
+#define PLAYBACK_MODE_8LINEAR_WSS	5	/*        Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
+
+#define RECORD_MODE_COMPRESSED		0	/*        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
+#define RECORD_MODE_TRUESPEECH		0	/*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
+#define RECORD_MODE_ULAW		4	/*        Selects: 64 Kbit/sec Mu-law PCM */
+#define RECORD_MODE_ALAW		12	/*        Selects: 64 Kbit/sec A-law PCM */
+#define RECORD_MODE_16LINEAR		5	/*        Selects: 128 Kbit/sec 16-bit linear */
+#define RECORD_MODE_8LINEAR		6	/*        Selects: 64 Kbit/sec 8-bit signed linear */
+#define RECORD_MODE_8LINEAR_WSS		7	/*        Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
+
+enum SLIC_STATES {
+	PLD_SLIC_STATE_OC = 0,
+	PLD_SLIC_STATE_RINGING,
+	PLD_SLIC_STATE_ACTIVE,
+	PLD_SLIC_STATE_OHT,
+	PLD_SLIC_STATE_TIPOPEN,
+	PLD_SLIC_STATE_STANDBY,
+	PLD_SLIC_STATE_APR,
+	PLD_SLIC_STATE_OHTPR
+};
+
+enum SCI_CONTROL {
+	SCI_End = 0,
+	SCI_Enable_DAA,
+	SCI_Enable_Mixer,
+	SCI_Enable_EEPROM
+};
+
+enum Mode {
+	T63, T53, T48, T40
+};
+enum Dir {
+	V3_TO_V4, V4_TO_V3, V4_TO_V5, V5_TO_V4
+};
+
+typedef struct Proc_Info_Tag {
+	enum Mode convert_mode;
+	enum Dir convert_dir;
+	int Prev_Frame_Type;
+	int Current_Frame_Type;
+} Proc_Info_Type;
+
+enum PREVAL {
+	NORMAL = 0,
+	NOPOST,
+	POSTONLY,
+	PREERROR
+};
+
+enum IXJ_EXTENSIONS {
+	G729LOADER = 0,
+	TS85LOADER,
+	PRE_READ,
+	POST_READ,
+	PRE_WRITE,
+	POST_WRITE,
+	PRE_IOCTL,
+	POST_IOCTL
+};
+
+typedef struct {
+	char enable;
+	char en_filter;
+	unsigned int filter;
+	unsigned int state;	/* State 0 when cadence has not started. */
+
+	unsigned int on1;	/* State 1 */
+
+	unsigned long on1min;	/* State 1 - 10% + jiffies */
+ 	unsigned long on1dot;	/* State 1 + jiffies */
+
+	unsigned long on1max;	/* State 1 + 10% + jiffies */
+
+	unsigned int off1;	/* State 2 */
+
+	unsigned long off1min;
+ 	unsigned long off1dot;	/* State 2 + jiffies */
+	unsigned long off1max;
+	unsigned int on2;	/* State 3 */
+
+	unsigned long on2min;
+	unsigned long on2dot;
+	unsigned long on2max;
+	unsigned int off2;	/* State 4 */
+
+	unsigned long off2min;
+ 	unsigned long off2dot;	/* State 4 + jiffies */
+	unsigned long off2max;
+	unsigned int on3;	/* State 5 */
+
+	unsigned long on3min;
+	unsigned long on3dot;
+	unsigned long on3max;
+	unsigned int off3;	/* State 6 */
+
+	unsigned long off3min;
+ 	unsigned long off3dot;	/* State 6 + jiffies */
+	unsigned long off3max;
+} IXJ_CADENCE_F;
+
+typedef struct {
+	unsigned int busytone:1;
+	unsigned int dialtone:1;
+	unsigned int ringback:1;
+	unsigned int ringing:1;
+	unsigned int playing:1;
+	unsigned int recording:1;
+	unsigned int cringing:1;
+	unsigned int play_first_frame:1;
+	unsigned int pstn_present:1;
+	unsigned int pstn_ringing:1;
+	unsigned int pots_correct:1;
+	unsigned int pots_pstn:1;
+	unsigned int g729_loaded:1;
+	unsigned int ts85_loaded:1;
+	unsigned int dtmf_oob:1;	/* DTMF Out-Of-Band */
+
+	unsigned int pcmciascp:1;	/* SmartCABLE Present */
+
+	unsigned int pcmciasct:2;	/* SmartCABLE Type */
+
+	unsigned int pcmciastate:3;	/* SmartCABLE Init State */
+
+	unsigned int inwrite:1;	/* Currently writing */
+
+	unsigned int inread:1;	/* Currently reading */
+
+	unsigned int incheck:1;	/* Currently checking the SmartCABLE */
+
+	unsigned int cidplay:1; /* Currently playing Caller ID */
+
+	unsigned int cidring:1; /* This is the ring for Caller ID */
+
+	unsigned int cidsent:1; /* Caller ID has been sent */
+
+	unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */
+	unsigned int firstring:1; /* First ring cadence is complete */
+	unsigned int pstncheck:1;	/* Currently checking the PSTN Line */
+	unsigned int pstn_rmr:1;
+	unsigned int x:3;	/* unused bits */
+
+} IXJ_FLAGS;
+
+/******************************************************************************
+*
+*  This structure holds the state of all of the Quicknet cards
+*
+******************************************************************************/
+
+typedef struct {
+	int elements_used;
+	IXJ_CADENCE_TERM termination;
+	IXJ_CADENCE_ELEMENT *ce;
+} ixj_cadence;
+
+typedef struct {
+	struct phone_device p;
+	struct timer_list timer;
+	unsigned int board;
+	unsigned int DSPbase;
+	unsigned int XILINXbase;
+	unsigned int serial;
+	atomic_t DSPWrite;
+	struct phone_capability caplist[30];
+	unsigned int caps;
+	struct pnp_dev *dev;
+	unsigned int cardtype;
+	unsigned int rec_codec;
+	unsigned int cid_rec_codec;
+	unsigned int cid_rec_volume;
+	unsigned char cid_rec_flag;
+	signed char rec_mode;
+	unsigned int play_codec;
+	unsigned int cid_play_codec;
+	unsigned int cid_play_volume;
+	unsigned char cid_play_flag;
+	signed char play_mode;
+	IXJ_FLAGS flags;
+	unsigned long busyflags;
+	unsigned int rec_frame_size;
+	unsigned int play_frame_size;
+	unsigned int cid_play_frame_size;
+	unsigned int cid_base_frame_size;
+	unsigned long cidcw_wait;
+	int aec_level;
+	int cid_play_aec_level;
+	int readers, writers;
+        wait_queue_head_t poll_q;
+        wait_queue_head_t read_q;
+	char *read_buffer, *read_buffer_end;
+	char *read_convert_buffer;
+	size_t read_buffer_size;
+	unsigned int read_buffer_ready;
+        wait_queue_head_t write_q;
+	char *write_buffer, *write_buffer_end;
+	char *write_convert_buffer;
+	size_t write_buffer_size;
+	unsigned int write_buffers_empty;
+	unsigned long drybuffer;
+	char *write_buffer_rp, *write_buffer_wp;
+	char dtmfbuffer[80];
+	char dtmf_current;
+	int dtmf_wp, dtmf_rp, dtmf_state, dtmf_proc;
+	int tone_off_time, tone_on_time;
+	struct fasync_struct *async_queue;
+	unsigned long tone_start_jif;
+	char tone_index;
+	char tone_state;
+	char maxrings;
+	ixj_cadence *cadence_t;
+	ixj_cadence *cadence_r;
+	int tone_cadence_state;
+	IXJ_CADENCE_F cadence_f[6];
+	DTMF dtmf;
+	CPTF cptf;
+	BYTES dsp;
+	BYTES ver;
+	BYTES scr;
+	BYTES ssr;
+	BYTES baseframe;
+	HSR hsr;
+	GPIO gpio;
+	PLD_SCRR pld_scrr;
+	PLD_SCRW pld_scrw;
+	PLD_SLICW pld_slicw;
+	PLD_SLICR pld_slicr;
+	PLD_CLOCK pld_clock;
+	PCMCIA_CR1 pccr1;
+	PCMCIA_CR2 pccr2;
+	PCMCIA_SCCR psccr;
+	PCMCIA_SLIC pslic;
+	char pscdd;
+	Si3C1 sic1;
+	Si3C2 sic2;
+	Si3RXG sirxg;
+	Si3ADC siadc;
+	Si3DAC sidac;
+	Si3STAT sistat;
+	Si3AATT siaatt;
+	MIX mix;
+	unsigned short ring_cadence;
+	int ring_cadence_t;
+	unsigned long ring_cadence_jif;
+	unsigned long checkwait;
+	int intercom;
+	int m_hook;
+	int r_hook;
+	int p_hook;
+	char pstn_envelope;
+	char pstn_cid_intr;
+	unsigned char fskz;
+	unsigned char fskphase;
+	unsigned char fskcnt;
+        unsigned int cidsize;
+	unsigned int cidcnt;
+	unsigned long pstn_cid_received;
+	PHONE_CID cid;
+	PHONE_CID cid_send;
+	unsigned long pstn_ring_int;
+	unsigned long pstn_ring_start;
+	unsigned long pstn_ring_stop;
+	unsigned long pstn_winkstart;
+	unsigned long pstn_last_rmr;
+	unsigned long pstn_prev_rmr;
+	unsigned long pots_winkstart;
+	unsigned int winktime;
+	unsigned long flash_end;
+	char port;
+	char hookstate;
+	union telephony_exception ex;
+	union telephony_exception ex_sig;
+	int ixj_signals[35];
+	IXJ_SIGDEF sigdef;
+	char daa_mode;
+	char daa_country;
+	unsigned long pstn_sleeptil;
+	DAA_REGS m_DAAShadowRegs;
+	Proc_Info_Type Info_read;
+	Proc_Info_Type Info_write;
+	unsigned short frame_count;
+	unsigned int filter_hist[4];
+	unsigned char filter_en[6];
+	unsigned short proc_load;
+	unsigned long framesread;
+	unsigned long frameswritten;
+	unsigned long read_wait;
+	unsigned long write_wait;
+	unsigned long timerchecks;
+	unsigned long txreadycheck;
+	unsigned long rxreadycheck;
+	unsigned long statuswait;
+	unsigned long statuswaitfail;
+	unsigned long pcontrolwait;
+	unsigned long pcontrolwaitfail;
+	unsigned long iscontrolready;
+	unsigned long iscontrolreadyfail;
+	unsigned long pstnstatecheck;
+#ifdef IXJ_DYN_ALLOC
+	short *fskdata;
+#else
+	short fskdata[8000];
+#endif
+	int fsksize;
+	int fskdcnt;
+} IXJ;
+
+typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
+
+extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long);
+
diff --git a/drivers/staging/telephony/ixj_pcmcia.c b/drivers/staging/telephony/ixj_pcmcia.c
new file mode 100644
index 0000000..05032e2
--- /dev/null
+++ b/drivers/staging/telephony/ixj_pcmcia.c
@@ -0,0 +1,187 @@
+#include "ixj-ver.h"
+
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/kernel.h>	/* printk() */
+#include <linux/fs.h>		/* everything... */
+#include <linux/errno.h>	/* error codes */
+#include <linux/slab.h>
+
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "ixj.h"
+
+/*
+ *	PCMCIA service support for Quicknet cards
+ */
+ 
+
+typedef struct ixj_info_t {
+	int ndev;
+	struct ixj *port;
+} ixj_info_t;
+
+static void ixj_detach(struct pcmcia_device *p_dev);
+static int ixj_config(struct pcmcia_device * link);
+static void ixj_cs_release(struct pcmcia_device * link);
+
+static int ixj_probe(struct pcmcia_device *p_dev)
+{
+	dev_dbg(&p_dev->dev, "ixj_attach()\n");
+	/* Create new ixj device */
+	p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+	if (!p_dev->priv) {
+		return -ENOMEM;
+	}
+
+	return ixj_config(p_dev);
+}
+
+static void ixj_detach(struct pcmcia_device *link)
+{
+	dev_dbg(&link->dev, "ixj_detach\n");
+
+	ixj_cs_release(link);
+
+        kfree(link->priv);
+}
+
+static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
+{
+	char *str;
+	int i, place;
+	dev_dbg(&link->dev, "ixj_get_serial\n");
+
+	str = link->prod_id[0];
+	if (!str)
+		goto failed;
+	printk("%s", str);
+	str = link->prod_id[1];
+	if (!str)
+		goto failed;
+	printk(" %s", str);
+	str = link->prod_id[2];
+	if (!str)
+		goto failed;
+	place = 1;
+	for (i = strlen(str) - 1; i >= 0; i--) {
+		switch (str[i]) {
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+			j->serial += (str[i] - 48) * place;
+			break;
+		case 'A':
+		case 'B':
+		case 'C':
+		case 'D':
+		case 'E':
+		case 'F':
+			j->serial += (str[i] - 55) * place;
+			break;
+		case 'a':
+		case 'b':
+		case 'c':
+		case 'd':
+		case 'e':
+		case 'f':
+			j->serial += (str[i] - 87) * place;
+			break;
+		}
+		place = place * 0x10;
+	}
+	str = link->prod_id[3];
+	if (!str)
+		goto failed;
+	printk(" version %s\n", str);
+failed:
+	return;
+}
+
+static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data)
+{
+	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+	p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+	p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+	p_dev->io_lines = 3;
+
+	return pcmcia_request_io(p_dev);
+}
+
+static int ixj_config(struct pcmcia_device * link)
+{
+	IXJ *j;
+	ixj_info_t *info;
+
+	info = link->priv;
+	dev_dbg(&link->dev, "ixj_config\n");
+
+	link->config_flags = CONF_AUTO_SET_IO;
+
+	if (pcmcia_loop_config(link, ixj_config_check, NULL))
+		goto failed;
+
+	if (pcmcia_enable_device(link))
+		goto failed;
+
+	/*
+ 	 *	Register the card with the core.
+	 */
+	j = ixj_pcmcia_probe(link->resource[0]->start,
+			     link->resource[0]->start + 0x10);
+
+	info->ndev = 1;
+	ixj_get_serial(link, j);
+	return 0;
+
+failed:
+	ixj_cs_release(link);
+	return -ENODEV;
+}
+
+static void ixj_cs_release(struct pcmcia_device *link)
+{
+	ixj_info_t *info = link->priv;
+	dev_dbg(&link->dev, "ixj_cs_release\n");
+	info->ndev = 0;
+	pcmcia_disable_device(link);
+}
+
+static const struct pcmcia_device_id ixj_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, ixj_ids);
+
+static struct pcmcia_driver ixj_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "ixj_cs",
+	.probe		= ixj_probe,
+	.remove		= ixj_detach,
+	.id_table	= ixj_ids,
+};
+
+static int __init ixj_pcmcia_init(void)
+{
+	return pcmcia_register_driver(&ixj_driver);
+}
+
+static void ixj_pcmcia_exit(void)
+{
+	pcmcia_unregister_driver(&ixj_driver);
+}
+
+module_init(ixj_pcmcia_init);
+module_exit(ixj_pcmcia_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/telephony/phonedev.c b/drivers/staging/telephony/phonedev.c
new file mode 100644
index 0000000..1915af2
--- /dev/null
+++ b/drivers/staging/telephony/phonedev.c
@@ -0,0 +1,167 @@
+/*
+ *            Telephony registration for Linux
+ *
+ *              (c) Copyright 1999 Red Hat 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 Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Author:      Alan Cox, <alan@lxorguk.ukuu.org.uk>
+ *
+ * Fixes:       Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com>
+ *              phone_register_device now works with unit!=PHONE_UNIT_ANY
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/phonedev.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+#include <linux/kmod.h>
+#include <linux/sem.h>
+#include <linux/mutex.h>
+
+#define PHONE_NUM_DEVICES	256
+
+/*
+ *    Active devices 
+ */
+
+static struct phone_device *phone_device[PHONE_NUM_DEVICES];
+static DEFINE_MUTEX(phone_lock);
+
+/*
+ *    Open a phone device.
+ */
+
+static int phone_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = iminor(inode);
+	int err = 0;
+	struct phone_device *p;
+	const struct file_operations *old_fops, *new_fops = NULL;
+
+	if (minor >= PHONE_NUM_DEVICES)
+		return -ENODEV;
+
+	mutex_lock(&phone_lock);
+	p = phone_device[minor];
+	if (p)
+		new_fops = fops_get(p->f_op);
+	if (!new_fops) {
+		mutex_unlock(&phone_lock);
+		request_module("char-major-%d-%d", PHONE_MAJOR, minor);
+		mutex_lock(&phone_lock);
+		p = phone_device[minor];
+		if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL)
+		{
+			err=-ENODEV;
+			goto end;
+		}
+	}
+	old_fops = file->f_op;
+	file->f_op = new_fops;
+	if (p->open)
+		err = p->open(p, file);	/* Tell the device it is open */
+	if (err) {
+		fops_put(file->f_op);
+		file->f_op = fops_get(old_fops);
+	}
+	fops_put(old_fops);
+end:
+	mutex_unlock(&phone_lock);
+	return err;
+}
+
+/*
+ *    Telephony For Linux device drivers request registration here.
+ */
+
+int phone_register_device(struct phone_device *p, int unit)
+{
+	int base;
+	int end;
+	int i;
+
+	base = 0;
+	end = PHONE_NUM_DEVICES - 1;
+
+	if (unit != PHONE_UNIT_ANY) {
+		base = unit;
+		end = unit + 1;  /* enter the loop at least one time */
+	}
+	
+	mutex_lock(&phone_lock);
+	for (i = base; i < end; i++) {
+		if (phone_device[i] == NULL) {
+			phone_device[i] = p;
+			p->minor = i;
+			mutex_unlock(&phone_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&phone_lock);
+	return -ENFILE;
+}
+
+/*
+ *    Unregister an unused Telephony for linux device
+ */
+
+void phone_unregister_device(struct phone_device *pfd)
+{
+	mutex_lock(&phone_lock);
+	if (likely(phone_device[pfd->minor] == pfd))
+		phone_device[pfd->minor] = NULL;
+	mutex_unlock(&phone_lock);
+}
+
+
+static const struct file_operations phone_fops =
+{
+	.owner		= THIS_MODULE,
+	.open		= phone_open,
+	.llseek		= noop_llseek,
+};
+
+/*
+ *	Board init functions
+ */
+ 
+
+/*
+ *    Initialise Telephony for linux
+ */
+
+static int __init telephony_init(void)
+{
+	printk(KERN_INFO "Linux telephony interface: v1.00\n");
+	if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
+		printk("phonedev: unable to get major %d\n", PHONE_MAJOR);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit telephony_exit(void)
+{
+	unregister_chrdev(PHONE_MAJOR, "telephony");
+}
+
+module_init(telephony_init);
+module_exit(telephony_exit);
+
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(phone_register_device);
+EXPORT_SYMBOL(phone_unregister_device);
diff --git a/drivers/staging/tidspbridge/Kconfig b/drivers/staging/tidspbridge/Kconfig
index 21a559e..d660891 100644
--- a/drivers/staging/tidspbridge/Kconfig
+++ b/drivers/staging/tidspbridge/Kconfig
@@ -31,12 +31,6 @@ config TIDSPBRIDGE_MEMPOOL_SIZE
 	  Allocate specified size of memory at booting time to avoid allocation
 	  failure under heavy memory fragmentation after some use time.
 
-config TIDSPBRIDGE_DEBUG
-	bool "Debug Support"
-	depends on TIDSPBRIDGE
-	help
-	  Say Y to enable Bridge debugging capabilities
-
 config TIDSPBRIDGE_RECOVERY
 	bool "Recovery Support"
 	depends on TIDSPBRIDGE
diff --git a/drivers/staging/tidspbridge/Makefile b/drivers/staging/tidspbridge/Makefile
index fd6a276..8c8c92a 100644
--- a/drivers/staging/tidspbridge/Makefile
+++ b/drivers/staging/tidspbridge/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_TIDSPBRIDGE)	+= bridgedriver.o
+obj-$(CONFIG_TIDSPBRIDGE)	+= tidspbridge.o
 
 libgen = gen/gh.o gen/uuidutil.o
 libcore = core/chnl_sm.o core/msg_sm.o core/io_sm.o core/tiomap3430.o \
@@ -13,7 +13,7 @@ libdload = dynload/cload.o dynload/getsection.o dynload/reloc.o \
 		 dynload/tramp.o
 libhw = hw/hw_mmu.o
 
-bridgedriver-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
+tidspbridge-y := $(libgen) $(libservices) $(libcore) $(libpmgr) $(librmgr) \
 			$(libdload) $(libhw)
 
 #Machine dependent
diff --git a/drivers/staging/tidspbridge/core/chnl_sm.c b/drivers/staging/tidspbridge/core/chnl_sm.c
index 6d66e7d..e0c7e4c 100644
--- a/drivers/staging/tidspbridge/core/chnl_sm.c
+++ b/drivers/staging/tidspbridge/core/chnl_sm.c
@@ -50,9 +50,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -123,7 +120,6 @@ int bridge_chnl_add_io_req(struct chnl_object *chnl_obj, void *host_buf,
 				CHNL_IS_OUTPUT(pchnl->chnl_mode))
 			return -EPIPE;
 		/* No other possible states left */
-		DBC_ASSERT(0);
 	}
 
 	dev_obj = dev_get_first();
@@ -190,7 +186,6 @@ func_cont:
 	 * Note: for dma chans dw_dsp_addr contains dsp address
 	 * of SM buffer.
 	 */
-	DBC_ASSERT(chnl_mgr_obj->word_size != 0);
 	/* DSP address */
 	chnl_packet_obj->dsp_tx_addr = dw_dsp_addr / chnl_mgr_obj->word_size;
 	chnl_packet_obj->byte_size = byte_size;
@@ -201,7 +196,6 @@ func_cont:
 			CHNL_IOCSTATCOMPLETE);
 	list_add_tail(&chnl_packet_obj->link, &pchnl->io_requests);
 	pchnl->cio_reqs++;
-	DBC_ASSERT(pchnl->cio_reqs <= pchnl->chnl_packets);
 	/*
 	 * If end of stream, update the channel state to prevent
 	 * more IOR's.
@@ -209,8 +203,6 @@ func_cont:
 	if (is_eos)
 		pchnl->state |= CHNL_STATEEOS;
 
-	/* Legacy DSM Processor-Copy */
-	DBC_ASSERT(pchnl->chnl_type == CHNL_PCPY);
 	/* Request IO from the DSP */
 	io_request_chnl(chnl_mgr_obj->iomgr, pchnl,
 			(CHNL_IS_INPUT(pchnl->chnl_mode) ? IO_INPUT :
@@ -283,7 +275,6 @@ int bridge_chnl_cancel_io(struct chnl_object *chnl_obj)
 		list_add_tail(&chirp->link, &pchnl->io_completions);
 		pchnl->cio_cs++;
 		pchnl->cio_reqs--;
-		DBC_ASSERT(pchnl->cio_reqs >= 0);
 	}
 
 	spin_unlock_bh(&chnl_mgr_obj->chnl_mgr_lock);
@@ -311,8 +302,6 @@ int bridge_chnl_close(struct chnl_object *chnl_obj)
 	status = bridge_chnl_cancel_io(chnl_obj);
 	if (status)
 		return status;
-	/* Assert I/O on this channel is now cancelled: Protects from io_dpc */
-	DBC_ASSERT((pchnl->state & CHNL_STATECANCEL));
 	/* Invalidate channel object: Protects from CHNL_GetIOCompletion() */
 	/* Free the slot in the channel manager: */
 	pchnl->chnl_mgr_obj->channels[pchnl->chnl_id] = NULL;
@@ -358,13 +347,6 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr,
 	struct chnl_mgr *chnl_mgr_obj = NULL;
 	u8 max_channels;
 
-	/* Check DBC requirements: */
-	DBC_REQUIRE(channel_mgr != NULL);
-	DBC_REQUIRE(mgr_attrts != NULL);
-	DBC_REQUIRE(mgr_attrts->max_channels > 0);
-	DBC_REQUIRE(mgr_attrts->max_channels <= CHNL_MAXCHANNELS);
-	DBC_REQUIRE(mgr_attrts->word_size != 0);
-
 	/* Allocate channel manager object */
 	chnl_mgr_obj = kzalloc(sizeof(struct chnl_mgr), GFP_KERNEL);
 	if (chnl_mgr_obj) {
@@ -374,7 +356,6 @@ int bridge_chnl_create(struct chnl_mgr **channel_mgr,
 		 *      mgr_attrts->max_channels = CHNL_MAXCHANNELS =
 		 *                       DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS.
 		 */
-		DBC_ASSERT(mgr_attrts->max_channels == CHNL_MAXCHANNELS);
 		max_channels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY;
 		/* Create array of channels */
 		chnl_mgr_obj->channels = kzalloc(sizeof(struct chnl_object *)
@@ -491,7 +472,6 @@ int bridge_chnl_flush_io(struct chnl_object *chnl_obj, u32 timeout)
 			pchnl->state &= ~CHNL_STATECANCEL;
 		}
 	}
-	DBC_ENSURE(status || list_empty(&pchnl->io_requests));
 	return status;
 }
 
@@ -592,7 +572,6 @@ int bridge_chnl_get_ioc(struct chnl_object *chnl_obj, u32 timeout,
 	omap_mbox_disable_irq(dev_ctxt->mbox, IRQ_RX);
 	if (dequeue_ioc) {
 		/* Dequeue IOC and set chan_ioc; */
-		DBC_ASSERT(!list_empty(&pchnl->io_completions));
 		chnl_packet_obj = list_first_entry(&pchnl->io_completions,
 				struct chnl_irp, link);
 		list_del(&chnl_packet_obj->link);
@@ -705,8 +684,6 @@ int bridge_chnl_idle(struct chnl_object *chnl_obj, u32 timeout,
 	struct chnl_mgr *chnl_mgr_obj;
 	int status = 0;
 
-	DBC_REQUIRE(chnl_obj);
-
 	chnl_mode = chnl_obj->chnl_mode;
 	chnl_mgr_obj = chnl_obj->chnl_mgr_obj;
 
@@ -736,10 +713,7 @@ int bridge_chnl_open(struct chnl_object **chnl,
 	struct chnl_mgr *chnl_mgr_obj = hchnl_mgr;
 	struct chnl_object *pchnl = NULL;
 	struct sync_object *sync_event = NULL;
-	/* Ensure DBC requirements: */
-	DBC_REQUIRE(chnl != NULL);
-	DBC_REQUIRE(pattrs != NULL);
-	DBC_REQUIRE(hchnl_mgr != NULL);
+
 	*chnl = NULL;
 
 	/* Validate Args: */
@@ -761,7 +735,6 @@ int bridge_chnl_open(struct chnl_object **chnl,
 			return status;
 	}
 
-	DBC_ASSERT(ch_id < chnl_mgr_obj->max_channels);
 
 	/* Create channel object: */
 	pchnl = kzalloc(sizeof(struct chnl_object), GFP_KERNEL);
@@ -850,7 +823,6 @@ int bridge_chnl_register_notify(struct chnl_object *chnl_obj,
 {
 	int status = 0;
 
-	DBC_ASSERT(!(event_mask & ~(DSP_STREAMDONE | DSP_STREAMIOCOMPLETION)));
 
 	if (event_mask)
 		status = ntfy_register(chnl_obj->ntfy_obj, hnotification,
@@ -906,8 +878,6 @@ static void free_chirp_list(struct list_head *chirp_list)
 {
 	struct chnl_irp *chirp, *tmp;
 
-	DBC_REQUIRE(chirp_list != NULL);
-
 	list_for_each_entry_safe(chirp, tmp, chirp_list, link) {
 		list_del(&chirp->link);
 		kfree(chirp);
@@ -924,8 +894,6 @@ static int search_free_channel(struct chnl_mgr *chnl_mgr_obj,
 	int status = -ENOSR;
 	u32 i;
 
-	DBC_REQUIRE(chnl_mgr_obj);
-
 	for (i = 0; i < chnl_mgr_obj->max_channels; i++) {
 		if (chnl_mgr_obj->channels[i] == NULL) {
 			status = 0;
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c
index 7eb5617..c7df34e 100644
--- a/drivers/staging/tidspbridge/core/dsp-clock.c
+++ b/drivers/staging/tidspbridge/core/dsp-clock.c
@@ -29,9 +29,6 @@
 #include <dspbridge/dev.h>
 #include "_tiomap.h"
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- This */
 #include <dspbridge/clk.h>
 
diff --git a/drivers/staging/tidspbridge/core/io_sm.c b/drivers/staging/tidspbridge/core/io_sm.c
index 694c0e5..9b50b5b 100644
--- a/drivers/staging/tidspbridge/core/io_sm.c
+++ b/drivers/staging/tidspbridge/core/io_sm.c
@@ -33,9 +33,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/* Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /* Services Layer */
 #include <dspbridge/ntfy.h>
 #include <dspbridge/sync.h>
@@ -114,7 +111,7 @@ struct io_mgr {
 	struct mgr_processorextinfo ext_proc_info;
 	struct cmm_object *cmm_mgr;	/* Shared Mem Mngr */
 	struct work_struct io_workq;	/* workqueue */
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
 	u32 trace_buffer_begin;	/* Trace message start address */
 	u32 trace_buffer_end;	/* Trace message end address */
 	u32 trace_buffer_current;	/* Trace message current address */
@@ -246,7 +243,7 @@ int bridge_io_destroy(struct io_mgr *hio_mgr)
 		/* Free IO DPC object */
 		tasklet_kill(&hio_mgr->dpc_tasklet);
 
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
 		kfree(hio_mgr->msg);
 #endif
 		dsp_wdt_exit();
@@ -386,7 +383,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
 		status = -EFAULT;
 	}
 	if (!status) {
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
 		status =
 		    cod_get_sym_value(cod_man, DSP_TRACESEC_END, &shm0_end);
 #else
@@ -731,7 +728,7 @@ int bridge_io_on_loaded(struct io_mgr *hio_mgr)
 		hmsg_mgr->max_msgs);
 	memset((void *)hio_mgr->shared_mem, 0, sizeof(struct shm));
 
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
 	/* Get the start address of trace buffer */
 	status = cod_get_sym_value(cod_man, SYS_PUTCBEG,
 				   &hio_mgr->trace_buffer_begin);
@@ -910,7 +907,7 @@ void io_dpc(unsigned long ref_data)
 		}
 
 #endif
-#ifdef CONFIG_TIDSPBRIDGE_DEBUG
+#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
 		if (pio_mgr->intr_val & MBX_DBG_SYSPRINTF) {
 			/* Notify DSP Trace message */
 			print_dsp_debug_trace(pio_mgr);
@@ -973,29 +970,16 @@ void io_request_chnl(struct io_mgr *io_manager, struct chnl_object *pchnl,
 	chnl_mgr_obj = io_manager->chnl_mgr;
 	sm = io_manager->shared_mem;
 	if (io_mode == IO_INPUT) {
-		/*
-		 * Assertion fires if CHNL_AddIOReq() called on a stream
-		 * which was cancelled, or attached to a dead board.
-		 */
-		DBC_ASSERT((pchnl->state == CHNL_STATEREADY) ||
-			   (pchnl->state == CHNL_STATEEOS));
 		/* Indicate to the DSP we have a buffer available for input */
 		set_chnl_busy(sm, pchnl->chnl_id);
 		*mbx_val = MBX_PCPY_CLASS;
 	} else if (io_mode == IO_OUTPUT) {
 		/*
-		 * This assertion fails if CHNL_AddIOReq() was called on a
-		 * stream which was cancelled, or attached to a dead board.
-		 */
-		DBC_ASSERT((pchnl->state & ~CHNL_STATEEOS) ==
-			   CHNL_STATEREADY);
-		/*
 		 * Record the fact that we have a buffer available for
 		 * output.
 		 */
 		chnl_mgr_obj->output_mask |= (1 << pchnl->chnl_id);
 	} else {
-		DBC_ASSERT(io_mode);	/* Shouldn't get here. */
 	}
 func_end:
 	return;
@@ -1087,7 +1071,6 @@ static void input_chnl(struct io_mgr *pio_mgr, struct chnl_object *pchnl,
 	dw_arg = sm->arg;
 	if (chnl_id >= CHNL_MAXCHANNELS) {
 		/* Shouldn't be here: would indicate corrupted shm. */
-		DBC_ASSERT(chnl_id);
 		goto func_end;
 	}
 	pchnl = chnl_mgr_obj->channels[chnl_id];
@@ -1683,7 +1666,7 @@ int bridge_io_get_proc_load(struct io_mgr *hio_mgr,
 }
 
 
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
+#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE)
 void print_dsp_debug_trace(struct io_mgr *hio_mgr)
 {
 	u32 ul_new_message_length = 0, ul_gpp_cur_pointer;
diff --git a/drivers/staging/tidspbridge/core/msg_sm.c b/drivers/staging/tidspbridge/core/msg_sm.c
index 94d9e04..ce9557e 100644
--- a/drivers/staging/tidspbridge/core/msg_sm.c
+++ b/drivers/staging/tidspbridge/core/msg_sm.c
@@ -20,9 +20,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c
index dde559d..670de0a 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430.c
@@ -27,9 +27,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/drv.h>
 #include <dspbridge/sync.h>
@@ -256,9 +253,6 @@ static void bad_page_dump(u32 pa, struct page *pg)
 void bridge_drv_entry(struct bridge_drv_interface **drv_intf,
 		   const char *driver_file_name)
 {
-
-	DBC_REQUIRE(driver_file_name != NULL);
-
 	if (strcmp(driver_file_name, "UMA") == 0)
 		*drv_intf = &drv_interface_fxns;
 	else
@@ -399,16 +393,13 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
 	(void)dev_get_symbol(dev_context->dev_obj, SHMBASENAME,
 			     &ul_shm_base_virt);
 	ul_shm_base_virt *= DSPWORDSIZE;
-	DBC_ASSERT(ul_shm_base_virt != 0);
 	/* DSP Virtual address */
 	ul_tlb_base_virt = dev_context->atlb_entry[0].dsp_va;
-	DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
 	ul_shm_offset_virt =
 	    ul_shm_base_virt - (ul_tlb_base_virt * DSPWORDSIZE);
 	/* Kernel logical address */
 	ul_shm_base = dev_context->atlb_entry[0].gpp_va + ul_shm_offset_virt;
 
-	DBC_ASSERT(ul_shm_base != 0);
 	/* 2nd wd is used as sync field */
 	dw_sync_addr = ul_shm_base + SHMSYNCOFFSET;
 	/* Write a signature into the shm base + offset; this will
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
index 02dd439..16a4aaf 100644
--- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
+++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c
@@ -303,7 +303,6 @@ int dsp_peripheral_clk_ctrl(struct bridge_dev_context *dev_context,
 	}
 	/* TODO -- Assert may be a too hard restriction here.. May be we should
 	 * just return with failure when the CLK ID does not match */
-	/* DBC_ASSERT(clk_id_index < MBX_PM_MAX_RESOURCES); */
 	if (clk_id_index == MBX_PM_MAX_RESOURCES) {
 		/* return with a more meaningfull error code */
 		return -EPERM;
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c
index dfb356e..7fda10c 100644
--- a/drivers/staging/tidspbridge/core/tiomap_io.c
+++ b/drivers/staging/tidspbridge/core/tiomap_io.c
@@ -21,9 +21,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- Platform Manager */
 #include <dspbridge/dev.h>
 #include <dspbridge/drv.h>
@@ -68,20 +65,17 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
 		status = dev_get_symbol(dev_context->dev_obj,
 					SHMBASENAME, &ul_shm_base_virt);
 	}
-	DBC_ASSERT(ul_shm_base_virt != 0);
 
 	/* Check if it is a read of Trace section */
 	if (!status && !ul_trace_sec_beg) {
 		status = dev_get_symbol(dev_context->dev_obj,
 					DSP_TRACESEC_BEG, &ul_trace_sec_beg);
 	}
-	DBC_ASSERT(ul_trace_sec_beg != 0);
 
 	if (!status && !ul_trace_sec_end) {
 		status = dev_get_symbol(dev_context->dev_obj,
 					DSP_TRACESEC_END, &ul_trace_sec_end);
 	}
-	DBC_ASSERT(ul_trace_sec_end != 0);
 
 	if (!status) {
 		if ((dsp_addr <= ul_trace_sec_end) &&
@@ -105,19 +99,16 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
 			status = dev_get_symbol(dev_context->dev_obj,
 						DYNEXTBASE, &ul_dyn_ext_base);
 		}
-		DBC_ASSERT(ul_dyn_ext_base != 0);
 
 		if (!status) {
 			status = dev_get_symbol(dev_context->dev_obj,
 						EXTBASE, &ul_ext_base);
 		}
-		DBC_ASSERT(ul_ext_base != 0);
 
 		if (!status) {
 			status = dev_get_symbol(dev_context->dev_obj,
 						EXTEND, &ul_ext_end);
 		}
-		DBC_ASSERT(ul_ext_end != 0);
 
 		/* Trace buffer is right after the shm SEG0,
 		 *  so set the base address to SHMBASE */
@@ -126,8 +117,6 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
 			ul_ext_end = ul_trace_sec_end;
 		}
 
-		DBC_ASSERT(ul_ext_end != 0);
-		DBC_ASSERT(ul_ext_end > ul_ext_base);
 
 		if (ul_ext_end < ul_ext_base)
 			status = -EPERM;
@@ -135,7 +124,6 @@ int read_ext_dsp_data(struct bridge_dev_context *dev_ctxt,
 		if (!status) {
 			ul_tlb_base_virt =
 			    dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
-			DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
 			dw_ext_prog_virt_mem =
 			    dev_context->atlb_entry[0].gpp_va;
 
@@ -271,7 +259,6 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
 			/* Get SHM_BEG  EXT_BEG and EXT_END. */
 			ret = dev_get_symbol(dev_context->dev_obj,
 					     SHMBASENAME, &ul_shm_base_virt);
-		DBC_ASSERT(ul_shm_base_virt != 0);
 		if (dynamic_load) {
 			if (!ret) {
 				if (symbols_reloaded)
@@ -280,7 +267,6 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
 					    (dev_context->dev_obj, DYNEXTBASE,
 					     &ul_ext_base);
 			}
-			DBC_ASSERT(ul_ext_base != 0);
 			if (!ret) {
 				/* DR  OMAPS00013235 : DLModules array may be
 				 * in EXTMEM. It is expected that DYNEXTMEM and
@@ -299,7 +285,6 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
 					    dev_get_symbol
 					    (dev_context->dev_obj, EXTBASE,
 					     &ul_ext_base);
-				DBC_ASSERT(ul_ext_base != 0);
 				if (!ret)
 					ret =
 					    dev_get_symbol
@@ -312,15 +297,12 @@ int write_ext_dsp_data(struct bridge_dev_context *dev_context,
 		if (trace_load)
 			ul_ext_base = ul_shm_base_virt;
 
-		DBC_ASSERT(ul_ext_end != 0);
-		DBC_ASSERT(ul_ext_end > ul_ext_base);
 		if (ul_ext_end < ul_ext_base)
 			ret = -EPERM;
 
 		if (!ret) {
 			ul_tlb_base_virt =
 			    dev_context->atlb_entry[0].dsp_va * DSPWORDSIZE;
-			DBC_ASSERT(ul_tlb_base_virt <= ul_shm_base_virt);
 
 			if (symbols_reloaded) {
 				ret = dev_get_symbol
diff --git a/drivers/staging/tidspbridge/gen/uuidutil.c b/drivers/staging/tidspbridge/gen/uuidutil.c
index ff6ebad..b44656c 100644
--- a/drivers/staging/tidspbridge/gen/uuidutil.c
+++ b/drivers/staging/tidspbridge/gen/uuidutil.c
@@ -23,9 +23,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- This */
 #include <dspbridge/uuidutil.h>
 
@@ -41,8 +38,6 @@ void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid,
 {
 	s32 i;			/* return result from snprintf. */
 
-	DBC_REQUIRE(uuid_obj && sz_uuid);
-
 	i = snprintf(sz_uuid, size,
 		     "%.8X_%.4X_%.4X_%.2X%.2X_%.2X%.2X%.2X%.2X%.2X%.2X",
 		     uuid_obj->data1, uuid_obj->data2, uuid_obj->data3,
@@ -50,8 +45,6 @@ void uuid_uuid_to_string(struct dsp_uuid *uuid_obj, char *sz_uuid,
 		     uuid_obj->data6[0], uuid_obj->data6[1],
 		     uuid_obj->data6[2], uuid_obj->data6[3],
 		     uuid_obj->data6[4], uuid_obj->data6[5]);
-
-	DBC_ENSURE(i != -1);
 }
 
 static s32 uuid_hex_to_bin(char *buf, s32 len)
diff --git a/drivers/staging/tidspbridge/include/dspbridge/dbc.h b/drivers/staging/tidspbridge/include/dspbridge/dbc.h
deleted file mode 100644
index 463760f..0000000
--- a/drivers/staging/tidspbridge/include/dspbridge/dbc.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * dbc.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * "Design by Contract" programming macros.
- *
- * Notes:
- *   Requires that the GT->ERROR function has been defaulted to a valid
- *   error handler for the given execution environment.
- *
- *   Does not require that GT_init() be called.
- *
- * Copyright (C) 2008 Texas Instruments, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef DBC_
-#define DBC_
-
-/* Assertion Macros: */
-#ifdef CONFIG_TIDSPBRIDGE_DEBUG
-
-#define DBC_ASSERT(exp) \
-    if (!(exp)) \
-	pr_err("%s, line %d: Assertion (" #exp ") failed.\n", \
-	__FILE__, __LINE__)
-#define DBC_REQUIRE DBC_ASSERT	/* Function Precondition. */
-#define DBC_ENSURE  DBC_ASSERT	/* Function Postcondition. */
-
-#else
-
-#define DBC_ASSERT(exp) {}
-#define DBC_REQUIRE(exp) {}
-#define DBC_ENSURE(exp) {}
-
-#endif /* DEBUG */
-
-#endif /* DBC_ */
diff --git a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h
index a054dad..903ff12 100644
--- a/drivers/staging/tidspbridge/include/dspbridge/io_sm.h
+++ b/drivers/staging/tidspbridge/include/dspbridge/io_sm.h
@@ -154,8 +154,6 @@ int dump_dsp_stack(struct bridge_dev_context *bridge_context);
 
 void dump_dl_modules(struct bridge_dev_context *bridge_context);
 
-#endif
-#if defined(CONFIG_TIDSPBRIDGE_BACKTRACE) || defined(CONFIG_TIDSPBRIDGE_DEBUG)
 void print_dsp_debug_trace(struct io_mgr *hio_mgr);
 #endif
 
diff --git a/drivers/staging/tidspbridge/pmgr/chnl.c b/drivers/staging/tidspbridge/pmgr/chnl.c
index 245de82..825be20 100644
--- a/drivers/staging/tidspbridge/pmgr/chnl.c
+++ b/drivers/staging/tidspbridge/pmgr/chnl.c
@@ -24,9 +24,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -58,10 +55,6 @@ int chnl_create(struct chnl_mgr **channel_mgr,
 	struct chnl_mgr *hchnl_mgr;
 	struct chnl_mgr_ *chnl_mgr_obj = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(channel_mgr != NULL);
-	DBC_REQUIRE(mgr_attrts != NULL);
-
 	*channel_mgr = NULL;
 
 	/* Validate args: */
@@ -99,8 +92,6 @@ int chnl_create(struct chnl_mgr **channel_mgr,
 		}
 	}
 
-	DBC_ENSURE(status || chnl_mgr_obj);
-
 	return status;
 }
 
@@ -115,8 +106,6 @@ int chnl_destroy(struct chnl_mgr *hchnl_mgr)
 	struct bridge_drv_interface *intf_fxns;
 	int status;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (chnl_mgr_obj) {
 		intf_fxns = chnl_mgr_obj->intf_fxns;
 		/* Let Bridge channel module destroy the chnl_mgr: */
@@ -135,11 +124,7 @@ int chnl_destroy(struct chnl_mgr *hchnl_mgr)
  */
 void chnl_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -151,12 +136,8 @@ bool chnl_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
diff --git a/drivers/staging/tidspbridge/pmgr/cmm.c b/drivers/staging/tidspbridge/pmgr/cmm.c
index e6b2c89..3366e60 100644
--- a/drivers/staging/tidspbridge/pmgr/cmm.c
+++ b/drivers/staging/tidspbridge/pmgr/cmm.c
@@ -35,9 +35,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -244,9 +241,6 @@ int cmm_create(struct cmm_object **ph_cmm_mgr,
 	struct cmm_object *cmm_obj = NULL;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(ph_cmm_mgr != NULL);
-
 	*ph_cmm_mgr = NULL;
 	/* create, zero, and tag a cmm mgr object */
 	cmm_obj = kzalloc(sizeof(struct cmm_object), GFP_KERNEL);
@@ -256,8 +250,6 @@ int cmm_create(struct cmm_object **ph_cmm_mgr,
 	if (mgr_attrts == NULL)
 		mgr_attrts = &cmm_dfltmgrattrs;	/* set defaults */
 
-	/* 4 bytes minimum */
-	DBC_ASSERT(mgr_attrts->min_block_size >= 4);
 	/* save away smallest block allocation for this cmm mgr */
 	cmm_obj->min_block_size = mgr_attrts->min_block_size;
 	cmm_obj->page_size = PAGE_SIZE;
@@ -283,7 +275,6 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force)
 	s32 slot_seg;
 	struct cmm_mnode *node, *tmp;
 
-	DBC_REQUIRE(refs > 0);
 	if (!hcmm_mgr) {
 		status = -EFAULT;
 		return status;
@@ -333,8 +324,6 @@ int cmm_destroy(struct cmm_object *hcmm_mgr, bool force)
  */
 void cmm_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
 }
 
@@ -351,9 +340,6 @@ int cmm_free_buf(struct cmm_object *hcmm_mgr, void *buf_pa, u32 ul_seg_id)
 	struct cmm_allocator *allocator;
 	struct cmm_attrs *pattrs;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(buf_pa != NULL);
-
 	if (ul_seg_id == 0) {
 		pattrs = &cmm_dfltalctattrs;
 		ul_seg_id = pattrs->seg_id;
@@ -392,8 +378,6 @@ int cmm_get_handle(void *hprocessor, struct cmm_object ** ph_cmm_mgr)
 	int status = 0;
 	struct dev_object *hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(ph_cmm_mgr != NULL);
 	if (hprocessor != NULL)
 		status = proc_get_dev_object(hprocessor, &hdev_obj);
 	else
@@ -419,8 +403,6 @@ int cmm_get_info(struct cmm_object *hcmm_mgr,
 	struct cmm_allocator *altr;
 	struct cmm_mnode *curr;
 
-	DBC_REQUIRE(cmm_info_obj != NULL);
-
 	if (!hcmm_mgr) {
 		status = -EFAULT;
 		return status;
@@ -472,12 +454,9 @@ bool cmm_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
 
@@ -499,13 +478,6 @@ int cmm_register_gppsm_seg(struct cmm_object *hcmm_mgr,
 	struct cmm_mnode *new_node;
 	s32 slot_seg;
 
-	DBC_REQUIRE(ul_size > 0);
-	DBC_REQUIRE(sgmt_id != NULL);
-	DBC_REQUIRE(dw_gpp_base_pa != 0);
-	DBC_REQUIRE(gpp_base_va != 0);
-	DBC_REQUIRE((c_factor <= CMM_ADDTODSPPA) &&
-			(c_factor >= CMM_SUBFROMDSPPA));
-
 	dev_dbg(bridge, "%s: dw_gpp_base_pa %x ul_size %x dsp_addr_offset %x "
 			"dw_dsp_base %x ul_dsp_size %x gpp_base_va %x\n",
 			__func__, dw_gpp_base_pa, ul_size, dsp_addr_offset,
@@ -589,7 +561,6 @@ int cmm_un_register_gppsm_seg(struct cmm_object *hcmm_mgr,
 	struct cmm_allocator *psma;
 	u32 ul_id = ul_seg_id;
 
-	DBC_REQUIRE(ul_seg_id > 0);
 	if (!hcmm_mgr)
 		return -EFAULT;
 
@@ -635,8 +606,6 @@ static void un_register_gppsm_seg(struct cmm_allocator *psma)
 {
 	struct cmm_mnode *curr, *tmp;
 
-	DBC_REQUIRE(psma != NULL);
-
 	/* free nodes on free list */
 	list_for_each_entry_safe(curr, tmp, &psma->free_list, link) {
 		list_del(&curr->link);
@@ -664,7 +633,6 @@ static void un_register_gppsm_seg(struct cmm_allocator *psma)
 static s32 get_slot(struct cmm_object *cmm_mgr_obj)
 {
 	s32 slot_seg = -1;	/* neg on failure */
-	DBC_REQUIRE(cmm_mgr_obj != NULL);
 	/* get first available slot in cmm mgr SMSegTab[] */
 	for (slot_seg = 0; slot_seg < CMM_MAXGPPSEGS; slot_seg++) {
 		if (cmm_mgr_obj->pa_gppsm_seg_tab[slot_seg] == NULL)
@@ -687,11 +655,6 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa,
 {
 	struct cmm_mnode *pnode;
 
-	DBC_REQUIRE(cmm_mgr_obj != NULL);
-	DBC_REQUIRE(dw_pa != 0);
-	DBC_REQUIRE(dw_va != 0);
-	DBC_REQUIRE(ul_size != 0);
-
 	/* Check cmm mgr's node freelist */
 	if (list_empty(&cmm_mgr_obj->node_free_list)) {
 		pnode = kzalloc(sizeof(struct cmm_mnode), GFP_KERNEL);
@@ -719,7 +682,6 @@ static struct cmm_mnode *get_node(struct cmm_object *cmm_mgr_obj, u32 dw_pa,
  */
 static void delete_node(struct cmm_object *cmm_mgr_obj, struct cmm_mnode *pnode)
 {
-	DBC_REQUIRE(pnode != NULL);
 	list_add_tail(&pnode->link, &cmm_mgr_obj->node_free_list);
 }
 
@@ -794,9 +756,6 @@ static void add_to_free_list(struct cmm_allocator *allocator,
 static struct cmm_allocator *get_allocator(struct cmm_object *cmm_mgr_obj,
 					   u32 ul_seg_id)
 {
-	DBC_REQUIRE(cmm_mgr_obj != NULL);
-	DBC_REQUIRE((ul_seg_id > 0) && (ul_seg_id <= CMM_MAXGPPSEGS));
-
 	return cmm_mgr_obj->pa_gppsm_seg_tab[ul_seg_id - 1];
 }
 
@@ -818,10 +777,6 @@ int cmm_xlator_create(struct cmm_xlatorobject **xlator,
 	struct cmm_xlator *xlator_object = NULL;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(xlator != NULL);
-	DBC_REQUIRE(hcmm_mgr != NULL);
-
 	*xlator = NULL;
 	if (xlator_attrs == NULL)
 		xlator_attrs = &cmm_dfltxlatorattrs;	/* set defaults */
@@ -851,13 +806,6 @@ void *cmm_xlator_alloc_buf(struct cmm_xlatorobject *xlator, void *va_buf,
 	void *tmp_va_buff;
 	struct cmm_attrs attrs;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(xlator != NULL);
-	DBC_REQUIRE(xlator_obj->cmm_mgr != NULL);
-	DBC_REQUIRE(va_buf != NULL);
-	DBC_REQUIRE(pa_size > 0);
-	DBC_REQUIRE(xlator_obj->seg_id > 0);
-
 	if (xlator_obj) {
 		attrs.seg_id = xlator_obj->seg_id;
 		__raw_writel(0, va_buf);
@@ -887,10 +835,6 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va)
 	int status = -EPERM;
 	void *buf_pa = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(buf_va != NULL);
-	DBC_REQUIRE(xlator_obj->seg_id > 0);
-
 	if (xlator_obj) {
 		/* convert Va to Pa so we can free it. */
 		buf_pa = cmm_xlator_translate(xlator, buf_va, CMM_VA2PA);
@@ -900,7 +844,8 @@ int cmm_xlator_free_buf(struct cmm_xlatorobject *xlator, void *buf_va)
 			if (status) {
 				/* Uh oh, this shouldn't happen. Descriptor
 				 * gone! */
-				DBC_ASSERT(false);	/* CMM is leaking mem */
+				pr_err("%s, line %d: Assertion failed\n",
+				       __FILE__, __LINE__);
 			}
 		}
 	}
@@ -918,10 +863,6 @@ int cmm_xlator_info(struct cmm_xlatorobject *xlator, u8 ** paddr,
 	struct cmm_xlator *xlator_obj = (struct cmm_xlator *)xlator;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(paddr != NULL);
-	DBC_REQUIRE((segm_id > 0) && (segm_id <= CMM_MAXGPPSEGS));
-
 	if (xlator_obj) {
 		if (set_info) {
 			/* set translators virtual address range */
@@ -948,16 +889,11 @@ void *cmm_xlator_translate(struct cmm_xlatorobject *xlator, void *paddr,
 	struct cmm_allocator *allocator = NULL;
 	u32 dw_offset = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(paddr != NULL);
-	DBC_REQUIRE((xtype >= CMM_VA2PA) && (xtype <= CMM_DSPPA2PA));
-
 	if (!xlator_obj)
 		goto loop_cont;
 
 	cmm_mgr_obj = (struct cmm_object *)xlator_obj->cmm_mgr;
 	/* get this translator's default SM allocator */
-	DBC_ASSERT(xlator_obj->seg_id > 0);
 	allocator = cmm_mgr_obj->pa_gppsm_seg_tab[xlator_obj->seg_id - 1];
 	if (!allocator)
 		goto loop_cont;
diff --git a/drivers/staging/tidspbridge/pmgr/cod.c b/drivers/staging/tidspbridge/pmgr/cod.c
index 1a29264..d01fb8e 100644
--- a/drivers/staging/tidspbridge/pmgr/cod.c
+++ b/drivers/staging/tidspbridge/pmgr/cod.c
@@ -30,9 +30,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- Platform Manager */
 /* Include appropriate loader header file */
 #include <dspbridge/dbll.h>
@@ -183,10 +180,6 @@ void cod_close(struct cod_libraryobj *lib)
 {
 	struct cod_manager *hmgr;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(lib != NULL);
-	DBC_REQUIRE(lib->cod_mgr);
-
 	hmgr = lib->cod_mgr;
 	hmgr->fxns.close_fxn(lib->dbll_lib);
 
@@ -208,9 +201,6 @@ int cod_create(struct cod_manager **mgr, char *str_zl_file)
 	struct dbll_attrs zl_attrs;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(mgr != NULL);
-
 	/* assume failure */
 	*mgr = NULL;
 
@@ -263,9 +253,6 @@ int cod_create(struct cod_manager **mgr, char *str_zl_file)
  */
 void cod_delete(struct cod_manager *cod_mgr_obj)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-
 	if (cod_mgr_obj->base_lib) {
 		if (cod_mgr_obj->loaded)
 			cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib,
@@ -288,11 +275,7 @@ void cod_delete(struct cod_manager *cod_mgr_obj)
  */
 void cod_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -305,10 +288,6 @@ int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-	DBC_REQUIRE(plib != NULL);
-
 	*plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;
 
 	return status;
@@ -322,10 +301,6 @@ int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-	DBC_REQUIRE(sz_name != NULL);
-
 	if (usize <= COD_MAXPATHLENGTH)
 		strncpy(sz_name, cod_mgr_obj->sz_zl_file, usize);
 	else
@@ -342,10 +317,6 @@ int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
  */
 int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-	DBC_REQUIRE(entry_pt != NULL);
-
 	*entry_pt = cod_mgr_obj->entry;
 
 	return 0;
@@ -361,10 +332,6 @@ int cod_get_loader(struct cod_manager *cod_mgr_obj,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-	DBC_REQUIRE(loader != NULL);
-
 	*loader = (struct dbll_tar_obj *)cod_mgr_obj->target;
 
 	return status;
@@ -382,13 +349,6 @@ int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
 	struct cod_manager *cod_mgr_obj;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(lib != NULL);
-	DBC_REQUIRE(lib->cod_mgr);
-	DBC_REQUIRE(str_sect != NULL);
-	DBC_REQUIRE(addr != NULL);
-	DBC_REQUIRE(len != NULL);
-
 	*addr = 0;
 	*len = 0;
 	if (lib != NULL) {
@@ -399,8 +359,6 @@ int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
 		status = -ESPIPE;
 	}
 
-	DBC_ENSURE(!status || ((*addr == 0) && (*len == 0)));
-
 	return status;
 }
 
@@ -417,11 +375,6 @@ int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym,
 {
 	struct dbll_sym_val *dbll_sym;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-	DBC_REQUIRE(str_sym != NULL);
-	DBC_REQUIRE(pul_value != NULL);
-
 	dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n",
 		__func__, cod_mgr_obj, str_sym, pul_value);
 	if (cod_mgr_obj->base_lib) {
@@ -451,12 +404,9 @@ bool cod_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0));
 	return ret;
 }
 
@@ -482,14 +432,6 @@ int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[],
 	int status;
 	u32 i;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr_obj);
-	DBC_REQUIRE(num_argc > 0);
-	DBC_REQUIRE(args != NULL);
-	DBC_REQUIRE(args[0] != NULL);
-	DBC_REQUIRE(pfn_write != NULL);
-	DBC_REQUIRE(cod_mgr_obj->base_lib != NULL);
-
 	/*
 	 *  Make sure every argv[] stated in argc has a value, or change argc to
 	 *  reflect true number in NULL terminated argv array.
@@ -538,12 +480,6 @@ int cod_open(struct cod_manager *hmgr, char *sz_coff_path,
 	int status = 0;
 	struct cod_libraryobj *lib = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hmgr);
-	DBC_REQUIRE(sz_coff_path != NULL);
-	DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB);
-	DBC_REQUIRE(lib_obj != NULL);
-
 	*lib_obj = NULL;
 
 	lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
@@ -575,10 +511,6 @@ int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
 	int status = 0;
 	struct dbll_library_obj *lib;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hmgr);
-	DBC_REQUIRE(sz_coff_path != NULL);
-
 	/* if we previously opened a base image, close it now */
 	if (hmgr->base_lib) {
 		if (hmgr->loaded) {
@@ -612,12 +544,6 @@ int cod_read_section(struct cod_libraryobj *lib, char *str_sect,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(lib != NULL);
-	DBC_REQUIRE(lib->cod_mgr);
-	DBC_REQUIRE(str_sect != NULL);
-	DBC_REQUIRE(str_content != NULL);
-
 	if (lib != NULL)
 		status =
 		    lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect,
diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c
index 31da62b..071ee86 100644
--- a/drivers/staging/tidspbridge/pmgr/dbll.c
+++ b/drivers/staging/tidspbridge/pmgr/dbll.c
@@ -21,8 +21,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
 #include <dspbridge/gh.h>
 
 /*  ----------------------------------- OS Adaptation Layer */
@@ -202,9 +200,6 @@ void dbll_close(struct dbll_library_obj *zl_lib)
 {
 	struct dbll_tar_obj *zl_target;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_lib);
-	DBC_REQUIRE(zl_lib->open_ref > 0);
 	zl_target = zl_lib->target_obj;
 	zl_lib->open_ref--;
 	if (zl_lib->open_ref == 0) {
@@ -241,10 +236,6 @@ int dbll_create(struct dbll_tar_obj **target_obj,
 	struct dbll_tar_obj *pzl_target;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pattrs != NULL);
-	DBC_REQUIRE(target_obj != NULL);
-
 	/* Allocate DBL target object */
 	pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL);
 	if (target_obj != NULL) {
@@ -255,8 +246,6 @@ int dbll_create(struct dbll_tar_obj **target_obj,
 			pzl_target->attrs = *pattrs;
 			*target_obj = (struct dbll_tar_obj *)pzl_target;
 		}
-		DBC_ENSURE((!status && *target_obj) ||
-				(status && *target_obj == NULL));
 	}
 
 	return status;
@@ -269,9 +258,6 @@ void dbll_delete(struct dbll_tar_obj *target)
 {
 	struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_target);
-
 	kfree(zl_target);
 
 }
@@ -282,14 +268,10 @@ void dbll_delete(struct dbll_tar_obj *target)
  */
 void dbll_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
 
 	if (refs == 0)
 		gh_exit();
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -302,12 +284,6 @@ bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name,
 	struct dbll_symbol *sym;
 	bool status = false;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_lib);
-	DBC_REQUIRE(name != NULL);
-	DBC_REQUIRE(sym_val != NULL);
-	DBC_REQUIRE(zl_lib->sym_tab != NULL);
-
 	sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name);
 	if (sym != NULL) {
 		*sym_val = &sym->value;
@@ -327,10 +303,6 @@ void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs)
 {
 	struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_target);
-	DBC_REQUIRE(pattrs != NULL);
-
 	if ((pattrs != NULL) && (zl_target != NULL))
 		*pattrs = zl_target->attrs;
 
@@ -347,12 +319,6 @@ bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name,
 	char cname[MAXEXPR + 1];
 	bool status = false;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_lib);
-	DBC_REQUIRE(sym_val != NULL);
-	DBC_REQUIRE(zl_lib->sym_tab != NULL);
-	DBC_REQUIRE(name != NULL);
-
 	cname[0] = '_';
 
 	strncpy(cname + 1, name, sizeof(cname) - 2);
@@ -382,12 +348,6 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr,
 	struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(name != NULL);
-	DBC_REQUIRE(paddr != NULL);
-	DBC_REQUIRE(psize != NULL);
-	DBC_REQUIRE(zl_lib);
-
 	/* If DOFF file is not open, we open it. */
 	if (zl_lib != NULL) {
 		if (zl_lib->fp == NULL) {
@@ -434,8 +394,6 @@ int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr,
  */
 bool dbll_init(void)
 {
-	DBC_REQUIRE(refs >= 0);
-
 	if (refs == 0)
 		gh_init();
 
@@ -456,10 +414,6 @@ int dbll_load(struct dbll_library_obj *lib, dbll_flags flags,
 	s32 err;
 	int status = 0;
 	bool opened_doff = false;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_lib);
-	DBC_REQUIRE(entry != NULL);
-	DBC_REQUIRE(attrs != NULL);
 
 	/*
 	 *  Load if not already loaded.
@@ -558,8 +512,6 @@ int dbll_load(struct dbll_library_obj *lib, dbll_flags flags,
 	if (opened_doff)
 		dof_close(zl_lib);
 
-	DBC_ENSURE(status || zl_lib->load_ref > 0);
-
 	dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n",
 		__func__, lib, flags, entry, status);
 
@@ -577,12 +529,6 @@ int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags,
 	s32 err;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_target);
-	DBC_REQUIRE(zl_target->attrs.fopen != NULL);
-	DBC_REQUIRE(file != NULL);
-	DBC_REQUIRE(lib_obj != NULL);
-
 	zl_lib = zl_target->head;
 	while (zl_lib != NULL) {
 		if (strcmp(zl_lib->file_name, file) == 0) {
@@ -699,8 +645,6 @@ func_cont:
 			dbll_close((struct dbll_library_obj *)zl_lib);
 
 	}
-	DBC_ENSURE((!status && (zl_lib->open_ref > 0) && *lib_obj)
-				|| (status && *lib_obj == NULL));
 
 	dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n",
 		__func__, target, file, lib_obj, status);
@@ -722,12 +666,6 @@ int dbll_read_sect(struct dbll_library_obj *lib, char *name,
 	const struct ldr_section_info *sect = NULL;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_lib);
-	DBC_REQUIRE(name != NULL);
-	DBC_REQUIRE(buf != NULL);
-	DBC_REQUIRE(size != 0);
-
 	/* If DOFF file is not open, we open it. */
 	if (zl_lib != NULL) {
 		if (zl_lib->fp == NULL) {
@@ -788,14 +726,11 @@ void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs)
 	struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
 	s32 err = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(zl_lib);
-	DBC_REQUIRE(zl_lib->load_ref > 0);
 	dev_dbg(bridge, "%s: lib: %p\n", __func__, lib);
 	zl_lib->load_ref--;
 	/* Unload only if reference count is 0 */
 	if (zl_lib->load_ref != 0)
-		goto func_end;
+		return;
 
 	zl_lib->target_obj->attrs = *attrs;
 	if (zl_lib->dload_mod_obj) {
@@ -814,8 +749,6 @@ void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs)
 	/* delete DOFF desc since it holds *lots* of host OS
 	 * resources */
 	dof_close(zl_lib);
-func_end:
-	DBC_ENSURE(zl_lib->load_ref >= 0);
 }
 
 /*
@@ -874,8 +807,6 @@ static u16 name_hash(void *key, u16 max_bucket)
 	u16 hash;
 	char *name = (char *)key;
 
-	DBC_REQUIRE(name != NULL);
-
 	hash = 0;
 
 	while (*name) {
@@ -893,9 +824,6 @@ static u16 name_hash(void *key, u16 max_bucket)
  */
 static bool name_match(void *key, void *sp)
 {
-	DBC_REQUIRE(key != NULL);
-	DBC_REQUIRE(sp != NULL);
-
 	if ((key != NULL) && (sp != NULL)) {
 		if (strcmp((char *)key, ((struct dbll_symbol *)sp)->name) ==
 		    0)
@@ -938,10 +866,7 @@ static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
 	struct dbll_library_obj *lib;
 	int bytes_read = 0;
 
-	DBC_REQUIRE(this != NULL);
 	lib = pstream->lib;
-	DBC_REQUIRE(lib);
-
 	if (lib != NULL) {
 		bytes_read =
 		    (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize,
@@ -960,10 +885,7 @@ static int dbll_set_file_posn(struct dynamic_loader_stream *this,
 	struct dbll_library_obj *lib;
 	int status = 0;		/* Success */
 
-	DBC_REQUIRE(this != NULL);
 	lib = pstream->lib;
-	DBC_REQUIRE(lib);
-
 	if (lib != NULL) {
 		status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos,
 							    SEEK_SET);
@@ -986,10 +908,7 @@ static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
 	struct dbll_sym_val *dbll_sym = NULL;
 	bool status = false;	/* Symbol not found yet */
 
-	DBC_REQUIRE(this != NULL);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
-
 	if (lib != NULL) {
 		if (lib->target_obj->attrs.sym_lookup) {
 			/* Check current lib + base lib + dep lib +
@@ -1015,9 +934,6 @@ static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
 	if (!status && gbl_search)
 		dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name);
 
-	DBC_ASSERT((status && (dbll_sym != NULL))
-		   || (!status && (dbll_sym == NULL)));
-
 	ret_sym = (struct dynload_symbol *)dbll_sym;
 	return ret_sym;
 }
@@ -1034,11 +950,7 @@ static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
 	struct dbll_library_obj *lib;
 	struct dbll_symbol *sym;
 
-	DBC_REQUIRE(this != NULL);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
-	DBC_REQUIRE(lib->sym_tab != NULL);
-
 	sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name);
 
 	ret_sym = (struct dynload_symbol *)&sym->value;
@@ -1059,10 +971,7 @@ static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
 	struct dbll_library_obj *lib;
 	struct dynload_symbol *ret;
 
-	DBC_REQUIRE(this != NULL);
-	DBC_REQUIRE(name);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
 
 	/* Check to see if symbol is already defined in symbol table */
 	if (!(lib->target_obj->attrs.base_image)) {
@@ -1111,10 +1020,7 @@ static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
 	struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
 	struct dbll_library_obj *lib;
 
-	DBC_REQUIRE(this != NULL);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
-
 	/* May not need to do anything */
 }
 
@@ -1127,9 +1033,7 @@ static void *allocate(struct dynamic_loader_sym *this, unsigned memsize)
 	struct dbll_library_obj *lib;
 	void *buf;
 
-	DBC_REQUIRE(this != NULL);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
 
 	buf = kzalloc(memsize, GFP_KERNEL);
 
@@ -1144,9 +1048,7 @@ static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr)
 	struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
 	struct dbll_library_obj *lib;
 
-	DBC_REQUIRE(this != NULL);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
 
 	kfree(mem_ptr);
 }
@@ -1161,9 +1063,7 @@ static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
 	struct dbll_library_obj *lib;
 	char temp_buf[MAXEXPR];
 
-	DBC_REQUIRE(this != NULL);
 	lib = ldr_sym->lib;
-	DBC_REQUIRE(lib);
 	vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args);
 	dev_dbg(bridge, "%s\n", temp_buf);
 }
@@ -1195,9 +1095,7 @@ static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
 	u32 alloc_size = 0;
 	u32 run_addr_flag = 0;
 
-	DBC_REQUIRE(this != NULL);
 	lib = dbll_alloc_obj->lib;
-	DBC_REQUIRE(lib);
 
 	mem_sect_type =
 	    (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
@@ -1206,7 +1104,6 @@ static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
 
 	/* Attempt to extract the segment ID and requirement information from
 	   the name of the section */
-	DBC_REQUIRE(info->name);
 	token_len = strlen((char *)(info->name)) + 1;
 
 	sz_sect_name = kzalloc(token_len, GFP_KERNEL);
@@ -1307,9 +1204,7 @@ static void rmm_dealloc(struct dynamic_loader_allocate *this,
 	    (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
 						 DLOAD_BSS) ? DBLL_BSS :
 	    DBLL_DATA;
-	DBC_REQUIRE(this != NULL);
 	lib = dbll_alloc_obj->lib;
-	DBC_REQUIRE(lib);
 	/* segid was set by alloc function */
 	segid = (u32) info->context;
 	if (mem_sect_type == DBLL_CODE)
@@ -1347,9 +1242,7 @@ static int read_mem(struct dynamic_loader_initialize *this, void *buf,
 	struct dbll_library_obj *lib;
 	int bytes_read = 0;
 
-	DBC_REQUIRE(this != NULL);
 	lib = init_obj->lib;
-	DBC_REQUIRE(lib);
 	/* Need bridge_brd_read function */
 	return bytes_read;
 }
@@ -1368,7 +1261,6 @@ static int write_mem(struct dynamic_loader_initialize *this, void *buf,
 	u32 mem_sect_type;
 	bool ret = true;
 
-	DBC_REQUIRE(this != NULL);
 	lib = init_obj->lib;
 	if (!lib)
 		return false;
@@ -1415,7 +1307,6 @@ static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
 	struct dbll_library_obj *lib;
 	struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
 
-	DBC_REQUIRE(this != NULL);
 	lib = init_obj->lib;
 	pbuf = NULL;
 	/* Pass the NULL pointer to write_mem to get the start address of Shared
@@ -1439,9 +1330,7 @@ static int execute(struct dynamic_loader_initialize *this, ldr_addr start)
 	struct dbll_library_obj *lib;
 	bool ret = true;
 
-	DBC_REQUIRE(this != NULL);
 	lib = init_obj->lib;
-	DBC_REQUIRE(lib);
 	/* Save entry point */
 	if (lib != NULL)
 		lib->entry = (u32) start;
diff --git a/drivers/staging/tidspbridge/pmgr/dev.c b/drivers/staging/tidspbridge/pmgr/dev.c
index 522810b..883765e 100644
--- a/drivers/staging/tidspbridge/pmgr/dev.c
+++ b/drivers/staging/tidspbridge/pmgr/dev.c
@@ -24,9 +24,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- Platform Manager */
 #include <dspbridge/cod.h>
 #include <dspbridge/drv.h>
@@ -106,11 +103,8 @@ u32 dev_brd_write_fxn(void *arb, u32 dsp_add, void *host_buf,
 	u32 ul_written = 0;
 	int status;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(host_buf != NULL);	/* Required of BrdWrite(). */
 	if (dev_obj) {
 		/* Require of BrdWrite() */
-		DBC_ASSERT(dev_obj->bridge_context != NULL);
 		status = (*dev_obj->bridge_interface.brd_write) (
 					dev_obj->bridge_context, host_buf,
 					dsp_add, ul_num_bytes, mem_space);
@@ -143,9 +137,6 @@ int dev_create_device(struct dev_object **device_obj,
 	struct drv_object *hdrv_obj = NULL;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 	int status = 0;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(device_obj != NULL);
-	DBC_REQUIRE(driver_file_name != NULL);
 
 	status = drv_request_bridge_res_dsp((void *)&host_res);
 
@@ -169,7 +160,6 @@ int dev_create_device(struct dev_object **device_obj,
 	/* Create the device object, and pass a handle to the Bridge driver for
 	 * storage. */
 	if (!status) {
-		DBC_ASSERT(drv_fxns);
 		dev_obj = kzalloc(sizeof(struct dev_object), GFP_KERNEL);
 		if (dev_obj) {
 			/* Fill out the rest of the Dev Object structure: */
@@ -191,9 +181,6 @@ int dev_create_device(struct dev_object **device_obj,
 			status = (dev_obj->bridge_interface.dev_create)
 			    (&dev_obj->bridge_context, dev_obj,
 			     host_res);
-			/* Assert bridge_dev_create()'s ensure clause: */
-			DBC_ASSERT(status
-				   || (dev_obj->bridge_context != NULL));
 		} else {
 			status = -ENOMEM;
 		}
@@ -271,7 +258,6 @@ leave:
 		*device_obj = NULL;
 	}
 
-	DBC_ENSURE((!status && *device_obj) || (status && !*device_obj));
 	return status;
 }
 
@@ -287,17 +273,11 @@ int dev_create2(struct dev_object *hdev_obj)
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hdev_obj);
-
 	/* There can be only one Node Manager per DEV object */
-	DBC_ASSERT(!dev_obj->node_mgr);
 	status = node_create_mgr(&dev_obj->node_mgr, hdev_obj);
 	if (status)
 		dev_obj->node_mgr = NULL;
 
-	DBC_ENSURE((!status && dev_obj->node_mgr != NULL)
-		   || (status && dev_obj->node_mgr == NULL));
 	return status;
 }
 
@@ -311,9 +291,6 @@ int dev_destroy2(struct dev_object *hdev_obj)
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hdev_obj);
-
 	if (dev_obj->node_mgr) {
 		if (node_delete_mgr(dev_obj->node_mgr))
 			status = -EPERM;
@@ -322,7 +299,6 @@ int dev_destroy2(struct dev_object *hdev_obj)
 
 	}
 
-	DBC_ENSURE((!status && dev_obj->node_mgr == NULL) || status);
 	return status;
 }
 
@@ -337,8 +313,6 @@ int dev_destroy_device(struct dev_object *hdev_obj)
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (hdev_obj) {
 		if (dev_obj->cod_mgr) {
 			cod_delete(dev_obj->cod_mgr);
@@ -415,9 +389,6 @@ int dev_get_chnl_mgr(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(mgr != NULL);
-
 	if (hdev_obj) {
 		*mgr = dev_obj->chnl_mgr;
 	} else {
@@ -425,7 +396,6 @@ int dev_get_chnl_mgr(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
 	return status;
 }
 
@@ -441,9 +411,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(mgr != NULL);
-
 	if (hdev_obj) {
 		*mgr = dev_obj->cmm_mgr;
 	} else {
@@ -451,7 +418,6 @@ int dev_get_cmm_mgr(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
 	return status;
 }
 
@@ -467,9 +433,6 @@ int dev_get_dmm_mgr(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(mgr != NULL);
-
 	if (hdev_obj) {
 		*mgr = dev_obj->dmm_mgr;
 	} else {
@@ -477,7 +440,6 @@ int dev_get_dmm_mgr(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (mgr != NULL && *mgr == NULL));
 	return status;
 }
 
@@ -492,9 +454,6 @@ int dev_get_cod_mgr(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(cod_mgr != NULL);
-
 	if (hdev_obj) {
 		*cod_mgr = dev_obj->cod_mgr;
 	} else {
@@ -502,7 +461,6 @@ int dev_get_cod_mgr(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (cod_mgr != NULL && *cod_mgr == NULL));
 	return status;
 }
 
@@ -514,9 +472,6 @@ int dev_get_deh_mgr(struct dev_object *hdev_obj,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(deh_manager != NULL);
-	DBC_REQUIRE(hdev_obj);
 	if (hdev_obj) {
 		*deh_manager = hdev_obj->deh_mgr;
 	} else {
@@ -537,9 +492,6 @@ int dev_get_dev_node(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dev_nde != NULL);
-
 	if (hdev_obj) {
 		*dev_nde = dev_obj->dev_node_obj;
 	} else {
@@ -547,7 +499,6 @@ int dev_get_dev_node(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (dev_nde != NULL && *dev_nde == NULL));
 	return status;
 }
 
@@ -578,9 +529,6 @@ int dev_get_intf_fxns(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(if_fxns != NULL);
-
 	if (hdev_obj) {
 		*if_fxns = &dev_obj->bridge_interface;
 	} else {
@@ -588,7 +536,6 @@ int dev_get_intf_fxns(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || ((if_fxns != NULL) && (*if_fxns == NULL)));
 	return status;
 }
 
@@ -600,10 +547,6 @@ int dev_get_io_mgr(struct dev_object *hdev_obj,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(io_man != NULL);
-	DBC_REQUIRE(hdev_obj);
-
 	if (hdev_obj) {
 		*io_man = hdev_obj->iomgr;
 	} else {
@@ -638,10 +581,6 @@ struct dev_object *dev_get_next(struct dev_object *hdev_obj)
  */
 void dev_get_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr **msg_man)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(msg_man != NULL);
-	DBC_REQUIRE(hdev_obj);
-
 	*msg_man = hdev_obj->msg_mgr;
 }
 
@@ -656,9 +595,6 @@ int dev_get_node_manager(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(node_man != NULL);
-
 	if (hdev_obj) {
 		*node_man = dev_obj->node_mgr;
 	} else {
@@ -666,7 +602,6 @@ int dev_get_node_manager(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (node_man != NULL && *node_man == NULL));
 	return status;
 }
 
@@ -679,9 +614,6 @@ int dev_get_symbol(struct dev_object *hdev_obj,
 	int status = 0;
 	struct cod_manager *cod_mgr;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(str_sym != NULL && pul_value != NULL);
-
 	if (hdev_obj) {
 		status = dev_get_cod_mgr(hdev_obj, &cod_mgr);
 		if (cod_mgr)
@@ -706,9 +638,6 @@ int dev_get_bridge_context(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(phbridge_context != NULL);
-
 	if (hdev_obj) {
 		*phbridge_context = dev_obj->bridge_context;
 	} else {
@@ -716,8 +645,6 @@ int dev_get_bridge_context(struct dev_object *hdev_obj,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || ((phbridge_context != NULL) &&
-					     (*phbridge_context == NULL)));
 	return status;
 }
 
@@ -729,16 +656,12 @@ int dev_get_bridge_context(struct dev_object *hdev_obj,
  */
 void dev_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
 
 	if (refs == 0) {
 		cmm_exit();
 		dmm_exit();
 	}
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -750,8 +673,6 @@ bool dev_init(void)
 {
 	bool cmm_ret, dmm_ret, ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (refs == 0) {
 		cmm_ret = cmm_init();
 		dmm_ret = dmm_init();
@@ -771,8 +692,6 @@ bool dev_init(void)
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
 
@@ -841,14 +760,11 @@ int dev_set_chnl_mgr(struct dev_object *hdev_obj,
 	int status = 0;
 	struct dev_object *dev_obj = hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (hdev_obj)
 		dev_obj->chnl_mgr = hmgr;
 	else
 		status = -EFAULT;
 
-	DBC_ENSURE(status || (dev_obj->chnl_mgr == hmgr));
 	return status;
 }
 
@@ -859,9 +775,6 @@ int dev_set_chnl_mgr(struct dev_object *hdev_obj,
  */
 void dev_set_msg_mgr(struct dev_object *hdev_obj, struct msg_mgr *hmgr)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hdev_obj);
-
 	hdev_obj->msg_mgr = hmgr;
 }
 
@@ -879,8 +792,6 @@ int dev_start_device(struct cfg_devnode *dev_node_obj)
 	struct mgr_object *hmgr_obj = NULL;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(refs > 0);
-
 	/* Given all resources, create a device object. */
 	status = dev_create_device(&hdev_obj, bridge_file_name,
 				   dev_node_obj);
@@ -944,9 +855,6 @@ static int init_cod_mgr(struct dev_object *dev_obj)
 	int status = 0;
 	char *sz_dummy_file = "dummy";
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(!dev_obj || (dev_obj->cod_mgr == NULL));
-
 	status = cod_create(&dev_obj->cod_mgr, sz_dummy_file);
 
 	return status;
@@ -976,10 +884,6 @@ int dev_insert_proc_object(struct dev_object *hdev_obj,
 {
 	struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dev_obj);
-	DBC_REQUIRE(proc_obj != 0);
-	DBC_REQUIRE(already_attached != NULL);
 	if (!list_empty(&dev_obj->proc_list))
 		*already_attached = true;
 
@@ -1017,10 +921,6 @@ int dev_remove_proc_object(struct dev_object *hdev_obj, u32 proc_obj)
 	struct list_head *cur_elem;
 	struct dev_object *dev_obj = (struct dev_object *)hdev_obj;
 
-	DBC_REQUIRE(dev_obj);
-	DBC_REQUIRE(proc_obj != 0);
-	DBC_REQUIRE(!list_empty(&dev_obj->proc_list));
-
 	/* Search list for dev_obj: */
 	list_for_each(cur_elem, &dev_obj->proc_list) {
 		if ((u32) cur_elem == proc_obj) {
@@ -1069,10 +969,6 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
     (intf_fxns->pfn = ((drv_fxns->pfn != NULL) ? drv_fxns->pfn : \
     (cast)fxn_not_implemented))
 
-	DBC_REQUIRE(intf_fxns != NULL);
-	DBC_REQUIRE(drv_fxns != NULL);
-	DBC_REQUIRE(MAKEVERSION(drv_fxns->brd_api_major_version,
-			drv_fxns->brd_api_minor_version) <= BRD_API_VERSION);
 	bridge_version = MAKEVERSION(drv_fxns->brd_api_major_version,
 				     drv_fxns->brd_api_minor_version);
 	intf_fxns->brd_api_major_version = drv_fxns->brd_api_major_version;
@@ -1119,33 +1015,5 @@ static void store_interface_fxns(struct bridge_drv_interface *drv_fxns,
 		STORE_FXN(fxn_msg_setqueueid, msg_set_queue_id);
 	}
 	/* Add code for any additional functions in newerBridge versions here */
-	/* Ensure postcondition: */
-	DBC_ENSURE(intf_fxns->dev_create != NULL);
-	DBC_ENSURE(intf_fxns->dev_destroy != NULL);
-	DBC_ENSURE(intf_fxns->dev_cntrl != NULL);
-	DBC_ENSURE(intf_fxns->brd_monitor != NULL);
-	DBC_ENSURE(intf_fxns->brd_start != NULL);
-	DBC_ENSURE(intf_fxns->brd_stop != NULL);
-	DBC_ENSURE(intf_fxns->brd_status != NULL);
-	DBC_ENSURE(intf_fxns->brd_read != NULL);
-	DBC_ENSURE(intf_fxns->brd_write != NULL);
-	DBC_ENSURE(intf_fxns->chnl_create != NULL);
-	DBC_ENSURE(intf_fxns->chnl_destroy != NULL);
-	DBC_ENSURE(intf_fxns->chnl_open != NULL);
-	DBC_ENSURE(intf_fxns->chnl_close != NULL);
-	DBC_ENSURE(intf_fxns->chnl_add_io_req != NULL);
-	DBC_ENSURE(intf_fxns->chnl_get_ioc != NULL);
-	DBC_ENSURE(intf_fxns->chnl_cancel_io != NULL);
-	DBC_ENSURE(intf_fxns->chnl_flush_io != NULL);
-	DBC_ENSURE(intf_fxns->chnl_get_info != NULL);
-	DBC_ENSURE(intf_fxns->chnl_get_mgr_info != NULL);
-	DBC_ENSURE(intf_fxns->chnl_idle != NULL);
-	DBC_ENSURE(intf_fxns->chnl_register_notify != NULL);
-	DBC_ENSURE(intf_fxns->io_create != NULL);
-	DBC_ENSURE(intf_fxns->io_destroy != NULL);
-	DBC_ENSURE(intf_fxns->io_on_loaded != NULL);
-	DBC_ENSURE(intf_fxns->io_get_proc_load != NULL);
-	DBC_ENSURE(intf_fxns->msg_set_queue_id != NULL);
-
 #undef  STORE_FXN
 }
diff --git a/drivers/staging/tidspbridge/pmgr/dmm.c b/drivers/staging/tidspbridge/pmgr/dmm.c
index 8685233..83faff8 100644
--- a/drivers/staging/tidspbridge/pmgr/dmm.c
+++ b/drivers/staging/tidspbridge/pmgr/dmm.c
@@ -28,9 +28,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -123,8 +120,6 @@ int dmm_create(struct dmm_object **dmm_manager,
 {
 	struct dmm_object *dmm_obj = NULL;
 	int status = 0;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dmm_manager != NULL);
 
 	*dmm_manager = NULL;
 	/* create, zero, and tag a cmm mgr object */
@@ -149,7 +144,6 @@ int dmm_destroy(struct dmm_object *dmm_mgr)
 	struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
 	if (dmm_mgr) {
 		status = dmm_delete_tables(dmm_obj);
 		if (!status)
@@ -169,7 +163,6 @@ int dmm_delete_tables(struct dmm_object *dmm_mgr)
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
 	/* Delete all DMM tables */
 	if (dmm_mgr)
 		vfree(virtual_mapping_table);
@@ -186,7 +179,6 @@ int dmm_delete_tables(struct dmm_object *dmm_mgr)
  */
 void dmm_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
 
 	refs--;
 }
@@ -202,8 +194,6 @@ int dmm_get_handle(void *hprocessor, struct dmm_object **dmm_manager)
 	int status = 0;
 	struct dev_object *hdev_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dmm_manager != NULL);
 	if (hprocessor != NULL)
 		status = proc_get_dev_object(hprocessor, &hdev_obj);
 	else
@@ -224,13 +214,9 @@ bool dmm_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	virtual_mapping_table = NULL;
 	table_size = 0;
 
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c
index 767ffe2..2788946 100644
--- a/drivers/staging/tidspbridge/pmgr/dspapi.c
+++ b/drivers/staging/tidspbridge/pmgr/dspapi.c
@@ -24,9 +24,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/ntfy.h>
 
@@ -266,7 +263,6 @@ err:
  */
 void api_exit(void)
 {
-	DBC_REQUIRE(api_c_refs > 0);
 	api_c_refs--;
 
 	if (api_c_refs == 0) {
@@ -284,7 +280,6 @@ void api_exit(void)
 		rmm_exit();
 		drv_exit();
 	}
-	DBC_ENSURE(api_c_refs >= 0);
 }
 
 /*
@@ -382,8 +377,6 @@ int api_init_complete2(void)
 	struct drv_data *drv_datap;
 	u8 dev_type;
 
-	DBC_REQUIRE(api_c_refs > 0);
-
 	/*  Walk the list of DevObjects, get each devnode, and attempting to
 	 *  autostart the board. Note that this requires COF loading, which
 	 *  requires KFILE. */
diff --git a/drivers/staging/tidspbridge/pmgr/io.c b/drivers/staging/tidspbridge/pmgr/io.c
index 65245f3..a56b085 100644
--- a/drivers/staging/tidspbridge/pmgr/io.c
+++ b/drivers/staging/tidspbridge/pmgr/io.c
@@ -23,9 +23,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- Platform Manager */
 #include <dspbridge/dev.h>
 
@@ -50,10 +47,6 @@ int io_create(struct io_mgr **io_man, struct dev_object *hdev_obj,
 	struct io_mgr_ *pio_mgr = NULL;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(io_man != NULL);
-	DBC_REQUIRE(mgr_attrts != NULL);
-
 	*io_man = NULL;
 
 	/* A memory base of 0 implies no memory base: */
@@ -94,8 +87,6 @@ int io_destroy(struct io_mgr *hio_mgr)
 	struct io_mgr_ *pio_mgr = (struct io_mgr_ *)hio_mgr;
 	int status;
 
-	DBC_REQUIRE(refs > 0);
-
 	intf_fxns = pio_mgr->intf_fxns;
 
 	/* Let Bridge channel module destroy the io_mgr: */
@@ -111,11 +102,7 @@ int io_destroy(struct io_mgr *hio_mgr)
  */
 void io_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -127,12 +114,8 @@ bool io_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
diff --git a/drivers/staging/tidspbridge/pmgr/msg.c b/drivers/staging/tidspbridge/pmgr/msg.c
index a691603..077c118 100644
--- a/drivers/staging/tidspbridge/pmgr/msg.c
+++ b/drivers/staging/tidspbridge/pmgr/msg.c
@@ -23,9 +23,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- Bridge Driver */
 #include <dspbridge/dspdefs.h>
 
@@ -53,11 +50,6 @@ int msg_create(struct msg_mgr **msg_man,
 	struct msg_mgr *hmsg_mgr;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(msg_man != NULL);
-	DBC_REQUIRE(msg_callback != NULL);
-	DBC_REQUIRE(hdev_obj != NULL);
-
 	*msg_man = NULL;
 
 	dev_get_intf_fxns(hdev_obj, &intf_fxns);
@@ -90,8 +82,6 @@ void msg_delete(struct msg_mgr *hmsg_mgr)
 	struct msg_mgr_ *msg_mgr_obj = (struct msg_mgr_ *)hmsg_mgr;
 	struct bridge_drv_interface *intf_fxns;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (msg_mgr_obj) {
 		intf_fxns = msg_mgr_obj->intf_fxns;
 
@@ -108,10 +98,7 @@ void msg_delete(struct msg_mgr *hmsg_mgr)
  */
 void msg_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -119,11 +106,7 @@ void msg_exit(void)
  */
 bool msg_mod_init(void)
 {
-	DBC_REQUIRE(refs >= 0);
-
 	refs++;
 
-	DBC_ENSURE(refs >= 0);
-
 	return true;
 }
diff --git a/drivers/staging/tidspbridge/rmgr/dbdcd.c b/drivers/staging/tidspbridge/rmgr/dbdcd.c
index fda2402..8378b7b 100644
--- a/drivers/staging/tidspbridge/rmgr/dbdcd.c
+++ b/drivers/staging/tidspbridge/rmgr/dbdcd.c
@@ -29,8 +29,6 @@
 
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
 
 /*  ----------------------------------- Platform Manager */
 #include <dspbridge/cod.h>
@@ -85,8 +83,6 @@ int dcd_auto_register(struct dcd_manager *hdcd_mgr,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (hdcd_mgr)
 		status = dcd_get_objects(hdcd_mgr, sz_coff_path,
 					 (dcd_registerfxn) dcd_register_object,
@@ -107,8 +103,6 @@ int dcd_auto_unregister(struct dcd_manager *hdcd_mgr,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (hdcd_mgr)
 		status = dcd_get_objects(hdcd_mgr, sz_coff_path,
 					 (dcd_registerfxn) dcd_register_object,
@@ -131,9 +125,6 @@ int dcd_create_manager(char *sz_zl_dll_name,
 	struct dcd_manager *dcd_mgr_obj = NULL;	/* DCD Manager pointer */
 	int status = 0;
 
-	DBC_REQUIRE(refs >= 0);
-	DBC_REQUIRE(dcd_mgr);
-
 	status = cod_create(&cod_mgr, sz_zl_dll_name);
 	if (status)
 		goto func_end;
@@ -156,9 +147,6 @@ int dcd_create_manager(char *sz_zl_dll_name,
 		cod_delete(cod_mgr);
 	}
 
-	DBC_ENSURE((!status) ||
-			((dcd_mgr_obj == NULL) && (status == -ENOMEM)));
-
 func_end:
 	return status;
 }
@@ -173,8 +161,6 @@ int dcd_destroy_manager(struct dcd_manager *hdcd_mgr)
 	struct dcd_manager *dcd_mgr_obj = hdcd_mgr;
 	int status = -EFAULT;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (hdcd_mgr) {
 		/* Delete the COD manager. */
 		cod_delete(dcd_mgr_obj->cod_mgr);
@@ -205,10 +191,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
 	struct dcd_key_elem *dcd_key;
 	int len;
 
-	DBC_REQUIRE(refs >= 0);
-	DBC_REQUIRE(index >= 0);
-	DBC_REQUIRE(uuid_obj != NULL);
-
 	if ((index != 0) && (enum_refs == 0)) {
 		/*
 		 * If an enumeration is being performed on an index greater
@@ -222,7 +204,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
 		 *  "_\0" + length of sz_obj_type string + terminating NULL.
 		 */
 		dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-		DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
 
 		/* Create proper REG key; concatenate DCD_REGKEY with
 		 * obj_type. */
@@ -294,8 +275,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
 		}
 	}
 
-	DBC_ENSURE(uuid_obj || (status == -EPERM));
-
 	return status;
 }
 
@@ -307,7 +286,6 @@ int dcd_enumerate_object(s32 index, enum dsp_dcdobjtype obj_type,
 void dcd_exit(void)
 {
 	struct dcd_key_elem *rv, *rv_tmp;
-	DBC_REQUIRE(refs > 0);
 
 	refs--;
 	if (refs == 0) {
@@ -319,7 +297,6 @@ void dcd_exit(void)
 		}
 	}
 
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -333,12 +310,6 @@ int dcd_get_dep_libs(struct dcd_manager *hdcd_mgr,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hdcd_mgr);
-	DBC_REQUIRE(uuid_obj != NULL);
-	DBC_REQUIRE(dep_lib_uuids != NULL);
-	DBC_REQUIRE(prstnt_dep_libs != NULL);
-
 	status =
 	    get_dep_lib_info(hdcd_mgr, uuid_obj, &num_libs, NULL, dep_lib_uuids,
 			     prstnt_dep_libs, phase);
@@ -356,12 +327,6 @@ int dcd_get_num_dep_libs(struct dcd_manager *hdcd_mgr,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hdcd_mgr);
-	DBC_REQUIRE(num_libs != NULL);
-	DBC_REQUIRE(num_pers_libs != NULL);
-	DBC_REQUIRE(uuid_obj != NULL);
-
 	status = get_dep_lib_info(hdcd_mgr, uuid_obj, num_libs, num_pers_libs,
 				  NULL, NULL, phase);
 
@@ -393,10 +358,6 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
 	u32 dw_key_len;		/* Len of REG key. */
 	char sz_obj_type[MAX_INT2CHAR_LENGTH];	/* str. rep. of obj_type. */
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(obj_def != NULL);
-	DBC_REQUIRE(obj_uuid != NULL);
-
 	sz_uuid = kzalloc(MAXUUIDLEN, GFP_KERNEL);
 	if (!sz_uuid) {
 		status = -ENOMEM;
@@ -411,7 +372,6 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
 	/* Pre-determine final key length. It's length of DCD_REGKEY +
 	 *  "_\0" + length of sz_obj_type string + terminating NULL */
 	dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-	DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
 
 	/* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
 	strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
@@ -470,7 +430,6 @@ int dcd_get_object_def(struct dcd_manager *hdcd_mgr,
 	}
 
 	/* Ensure sz_uuid + 1 is not greater than sizeof sz_sect_name. */
-	DBC_ASSERT((strlen(sz_uuid) + 1) < sizeof(sz_sect_name));
 
 	/* Create section name based on node UUID. A period is
 	 * pre-pended to the UUID string to form the section name.
@@ -553,7 +512,6 @@ int dcd_get_objects(struct dcd_manager *hdcd_mgr,
 	struct dsp_uuid dsp_uuid_obj;
 	s32 object_type;
 
-	DBC_REQUIRE(refs > 0);
 	if (!hdcd_mgr) {
 		status = -EFAULT;
 		goto func_end;
@@ -663,11 +621,6 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
 	int status = 0;
 	struct dcd_key_elem *dcd_key = NULL;
 
-	DBC_REQUIRE(uuid_obj != NULL);
-	DBC_REQUIRE(str_lib_name != NULL);
-	DBC_REQUIRE(buff_size != NULL);
-	DBC_REQUIRE(hdcd_mgr);
-
 	dev_dbg(bridge, "%s: hdcd_mgr %p, uuid_obj %p, str_lib_name %p,"
 		" buff_size %p\n", __func__, hdcd_mgr, uuid_obj, str_lib_name,
 		buff_size);
@@ -677,7 +630,6 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
 	 *  "_\0" + length of sz_obj_type string + terminating NULL.
 	 */
 	dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-	DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
 
 	/* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
 	strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
@@ -705,7 +657,6 @@ int dcd_get_library_name(struct dcd_manager *hdcd_mgr,
 		break;
 	default:
 		status = -EINVAL;
-		DBC_ASSERT(false);
 	}
 	if (!status) {
 		if ((strlen(sz_reg_key) + strlen(sz_obj_type)) <
@@ -790,8 +741,6 @@ bool dcd_init(void)
 	bool init_cod;
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (refs == 0) {
 		/* Initialize required modules. */
 		init_cod = cod_init();
@@ -809,8 +758,6 @@ bool dcd_init(void)
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs == 0)));
-
 	return ret;
 }
 
@@ -832,15 +779,6 @@ int dcd_register_object(struct dsp_uuid *uuid_obj,
 	char sz_obj_type[MAX_INT2CHAR_LENGTH];	/* str. rep. of obj_type. */
 	struct dcd_key_elem *dcd_key = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(uuid_obj != NULL);
-	DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) ||
-		    (obj_type == DSP_DCDPROCESSORTYPE) ||
-		    (obj_type == DSP_DCDLIBRARYTYPE) ||
-		    (obj_type == DSP_DCDCREATELIBTYPE) ||
-		    (obj_type == DSP_DCDEXECUTELIBTYPE) ||
-		    (obj_type == DSP_DCDDELETELIBTYPE));
-
 	dev_dbg(bridge, "%s: object UUID %p, obj_type %d, szPathName %s\n",
 		__func__, uuid_obj, obj_type, psz_path_name);
 
@@ -849,7 +787,6 @@ int dcd_register_object(struct dsp_uuid *uuid_obj,
 	 *  "_\0" + length of sz_obj_type string + terminating NULL.
 	 */
 	dw_key_len = strlen(DCD_REGKEY) + 1 + sizeof(sz_obj_type) + 1;
-	DBC_ASSERT(dw_key_len < DCD_MAXPATHLENGTH);
 
 	/* Create proper REG key; concatenate DCD_REGKEY with obj_type. */
 	strncpy(sz_reg_key, DCD_REGKEY, strlen(DCD_REGKEY) + 1);
@@ -987,15 +924,6 @@ int dcd_unregister_object(struct dsp_uuid *uuid_obj,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(uuid_obj != NULL);
-	DBC_REQUIRE((obj_type == DSP_DCDNODETYPE) ||
-		    (obj_type == DSP_DCDPROCESSORTYPE) ||
-		    (obj_type == DSP_DCDLIBRARYTYPE) ||
-		    (obj_type == DSP_DCDCREATELIBTYPE) ||
-		    (obj_type == DSP_DCDEXECUTELIBTYPE) ||
-		    (obj_type == DSP_DCDDELETELIBTYPE));
-
 	/*
 	 *  When dcd_register_object is called with NULL as pathname,
 	 *  it indicates an unregister object operation.
@@ -1055,12 +983,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
 	s32 entry_id;
 #endif
 
-	DBC_REQUIRE(psz_buf != NULL);
-	DBC_REQUIRE(ul_buf_size != 0);
-	DBC_REQUIRE((obj_type == DSP_DCDNODETYPE)
-		    || (obj_type == DSP_DCDPROCESSORTYPE));
-	DBC_REQUIRE(gen_obj != NULL);
-
 	switch (obj_type) {
 	case DSP_DCDNODETYPE:
 		/*
@@ -1082,7 +1004,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
 		token = strsep(&psz_cur, seps);
 
 		/* ac_name */
-		DBC_REQUIRE(token);
 		token_len = strlen(token);
 		if (token_len > DSP_MAXNAMELEN - 1)
 			token_len = DSP_MAXNAMELEN - 1;
@@ -1167,7 +1088,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
 		token = strsep(&psz_cur, seps);
 
 		/* char *str_create_phase_fxn */
-		DBC_REQUIRE(token);
 		token_len = strlen(token);
 		gen_obj->obj_data.node_obj.str_create_phase_fxn =
 					kzalloc(token_len + 1, GFP_KERNEL);
@@ -1178,7 +1098,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
 		token = strsep(&psz_cur, seps);
 
 		/* char *str_execute_phase_fxn */
-		DBC_REQUIRE(token);
 		token_len = strlen(token);
 		gen_obj->obj_data.node_obj.str_execute_phase_fxn =
 					kzalloc(token_len + 1, GFP_KERNEL);
@@ -1189,7 +1108,6 @@ static int get_attrs_from_buf(char *psz_buf, u32 ul_buf_size,
 		token = strsep(&psz_cur, seps);
 
 		/* char *str_delete_phase_fxn */
-		DBC_REQUIRE(token);
 		token_len = strlen(token);
 		gen_obj->obj_data.node_obj.str_delete_phase_fxn =
 					kzalloc(token_len + 1, GFP_KERNEL);
@@ -1421,12 +1339,6 @@ static int get_dep_lib_info(struct dcd_manager *hdcd_mgr,
 	u16 dep_libs = 0;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-
-	DBC_REQUIRE(hdcd_mgr);
-	DBC_REQUIRE(num_libs != NULL);
-	DBC_REQUIRE(uuid_obj != NULL);
-
 	/*  Initialize to 0 dependent libraries, if only counting number of
 	 *  dependent libraries */
 	if (!get_uuids) {
diff --git a/drivers/staging/tidspbridge/rmgr/disp.c b/drivers/staging/tidspbridge/rmgr/disp.c
index a9aa22f..e510bb2 100644
--- a/drivers/staging/tidspbridge/rmgr/disp.c
+++ b/drivers/staging/tidspbridge/rmgr/disp.c
@@ -24,9 +24,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -96,11 +93,6 @@ int disp_create(struct disp_object **dispatch_obj,
 	int status = 0;
 	u8 dev_type;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dispatch_obj != NULL);
-	DBC_REQUIRE(disp_attrs != NULL);
-	DBC_REQUIRE(hdev_obj != NULL);
-
 	*dispatch_obj = NULL;
 
 	/* Allocate Node Dispatcher object */
@@ -168,8 +160,6 @@ func_cont:
 	else
 		delete_disp(disp_obj);
 
-	DBC_ENSURE((status && *dispatch_obj == NULL) ||
-				(!status && *dispatch_obj));
 	return status;
 }
 
@@ -179,9 +169,6 @@ func_cont:
  */
 void disp_delete(struct disp_object *disp_obj)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(disp_obj);
-
 	delete_disp(disp_obj);
 }
 
@@ -191,11 +178,7 @@ void disp_delete(struct disp_object *disp_obj)
  */
 void disp_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -206,12 +189,9 @@ bool disp_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
 	return ret;
 }
 
@@ -227,10 +207,6 @@ int disp_node_change_priority(struct disp_object *disp_obj,
 	struct rms_command *rms_cmd;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(disp_obj);
-	DBC_REQUIRE(hnode != NULL);
-
 	/* Send message to RMS to change priority */
 	rms_cmd = (struct rms_command *)(disp_obj->buf);
 	rms_cmd->fxn = (rms_word) (rms_fxn);
@@ -276,12 +252,6 @@ int disp_node_create(struct disp_object *disp_obj,
 	struct dsp_nodeinfo node_info;
 	u8 dev_type;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(disp_obj);
-	DBC_REQUIRE(hnode != NULL);
-	DBC_REQUIRE(node_get_type(hnode) != NODE_DEVICE);
-	DBC_REQUIRE(node_env != NULL);
-
 	status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);
 
 	if (status)
@@ -292,11 +262,9 @@ int disp_node_create(struct disp_object *disp_obj,
 			__func__, dev_type);
 		goto func_end;
 	}
-	DBC_REQUIRE(pargs != NULL);
 	node_type = node_get_type(hnode);
 	node_msg_args = pargs->asa.node_msg_args;
 	max = disp_obj->bufsize_rms;	/*Max # of RMS words that can be sent */
-	DBC_ASSERT(max == RMS_COMMANDBUFSIZE);
 	chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size;
 	/* Number of RMS words needed to hold arg data */
 	dw_length =
@@ -457,7 +425,6 @@ int disp_node_create(struct disp_object *disp_obj,
 	}
 	if (!status) {
 		ul_bytes = total * sizeof(rms_word);
-		DBC_ASSERT(ul_bytes < (RMS_COMMANDBUFSIZE * sizeof(rms_word)));
 		status = send_message(disp_obj, node_get_timeout(hnode),
 				      ul_bytes, node_env);
 	}
@@ -480,10 +447,6 @@ int disp_node_delete(struct disp_object *disp_obj,
 	int status = 0;
 	u8 dev_type;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(disp_obj);
-	DBC_REQUIRE(hnode != NULL);
-
 	status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);
 
 	if (!status) {
@@ -521,9 +484,6 @@ int disp_node_run(struct disp_object *disp_obj,
 	struct rms_command *rms_cmd;
 	int status = 0;
 	u8 dev_type;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(disp_obj);
-	DBC_REQUIRE(hnode != NULL);
 
 	status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);
 
@@ -620,7 +580,6 @@ static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
 		 *  1 from total.
 		 */
 		total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1;
-		DBC_REQUIRE(strm_def.sz_device);
 		dw_length = strlen(strm_def.sz_device) + 1;
 
 		/* Number of RMS_WORDS needed to hold device name */
@@ -659,8 +618,6 @@ static int send_message(struct disp_object *disp_obj, u32 timeout,
 	struct chnl_ioc chnl_ioc_obj;
 	int status = 0;
 
-	DBC_REQUIRE(pdw_arg != NULL);
-
 	*pdw_arg = (u32) NULL;
 	intf_fxns = disp_obj->intf_fxns;
 	chnl_obj = disp_obj->chnl_to_dsp;
@@ -703,7 +660,6 @@ static int send_message(struct disp_object *disp_obj, u32 timeout,
 			status = -EPERM;
 		} else {
 			if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
-				DBC_ASSERT(chnl_ioc_obj.buf == pbuf);
 				if (*((int *)chnl_ioc_obj.buf) < 0) {
 					/* Translate DSP's to kernel error */
 					status = -EREMOTEIO;
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
index db8215f..b34dba7 100644
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ b/drivers/staging/tidspbridge/rmgr/drv.c
@@ -24,9 +24,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- This */
 #include <dspbridge/drv.h>
 #include <dspbridge/dev.h>
@@ -172,7 +169,6 @@ void drv_proc_node_update_status(void *node_resource, s32 status)
 {
 	struct node_res_object *node_res_obj =
 	    (struct node_res_object *)node_resource;
-	DBC_ASSERT(node_resource != NULL);
 	node_res_obj->node_allocated = status;
 }
 
@@ -181,7 +177,6 @@ void drv_proc_node_update_heap_status(void *node_resource, s32 status)
 {
 	struct node_res_object *node_res_obj =
 	    (struct node_res_object *)node_resource;
-	DBC_ASSERT(node_resource != NULL);
 	node_res_obj->heap_allocated = status;
 }
 
@@ -308,9 +303,6 @@ int drv_create(struct drv_object **drv_obj)
 	struct drv_object *pdrv_object = NULL;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(drv_obj != NULL);
-	DBC_REQUIRE(refs > 0);
-
 	pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL);
 	if (pdrv_object) {
 		/* Create and Initialize List of device objects */
@@ -336,7 +328,6 @@ int drv_create(struct drv_object **drv_obj)
 		kfree(pdrv_object);
 	}
 
-	DBC_ENSURE(status || pdrv_object);
 	return status;
 }
 
@@ -347,11 +338,7 @@ int drv_create(struct drv_object **drv_obj)
  */
 void drv_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -365,9 +352,6 @@ int drv_destroy(struct drv_object *driver_obj)
 	struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pdrv_object);
-
 	kfree(pdrv_object);
 	/* Update the DRV Object in the driver data */
 	if (drv_datap) {
@@ -389,17 +373,8 @@ int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj,
 			      struct dev_object **device_obj)
 {
 	int status = 0;
-#ifdef CONFIG_TIDSPBRIDGE_DEBUG
-	/* used only for Assertions and debug messages */
-	struct drv_object *pdrv_obj = (struct drv_object *)hdrv_obj;
-#endif
 	struct dev_object *dev_obj;
 	u32 i;
-	DBC_REQUIRE(pdrv_obj);
-	DBC_REQUIRE(device_obj != NULL);
-	DBC_REQUIRE(index >= 0);
-	DBC_REQUIRE(refs > 0);
-	DBC_ASSERT(!(list_empty(&pdrv_obj->dev_list)));
 
 	dev_obj = (struct dev_object *)drv_get_first_dev_object();
 	for (i = 0; i < index; i++) {
@@ -532,13 +507,9 @@ int drv_init(void)
 {
 	s32 ret = 1;		/* function return value */
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
 
@@ -552,10 +523,6 @@ int drv_insert_dev_object(struct drv_object *driver_obj,
 {
 	struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hdev_obj != NULL);
-	DBC_REQUIRE(pdrv_object);
-
 	list_add_tail((struct list_head *)hdev_obj, &pdrv_object->dev_list);
 
 	return 0;
@@ -574,12 +541,6 @@ int drv_remove_dev_object(struct drv_object *driver_obj,
 	struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
 	struct list_head *cur_elem;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pdrv_object);
-	DBC_REQUIRE(hdev_obj != NULL);
-
-	DBC_REQUIRE(!list_empty(&pdrv_object->dev_list));
-
 	/* Search list for p_proc_object: */
 	list_for_each(cur_elem, &pdrv_object->dev_list) {
 		/* If found, remove it. */
@@ -605,9 +566,6 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
 	struct drv_ext *pszdev_node;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(dw_context != 0);
-	DBC_REQUIRE(dev_node_strg != NULL);
-
 	/*
 	 *  Allocate memory to hold the string. This will live until
 	 *  it is freed in the Release resources. Update the driver object
@@ -639,10 +597,6 @@ int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
 		*dev_node_strg = 0;
 	}
 
-	DBC_ENSURE((!status && dev_node_strg != NULL &&
-		    !list_empty(&pdrv_object->dev_node_string)) ||
-		   (status && *dev_node_strg == 0));
-
 	return status;
 }
 
@@ -900,8 +854,6 @@ void *mem_alloc_phys_mem(u32 byte_size, u32 align_mask,
 void mem_free_phys_mem(void *virtual_address, u32 physical_address,
 		       u32 byte_size)
 {
-	DBC_REQUIRE(virtual_address != NULL);
-
 	if (!ext_phys_mem_pool_enabled)
 		dma_free_coherent(NULL, byte_size, virtual_address,
 				  physical_address);
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index 385740b..3cac014 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -16,11 +16,8 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-/*  ----------------------------------- Host OS */
-
 #include <plat/dsp.h>
 
-#include <dspbridge/host_os.h>
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
@@ -33,36 +30,25 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/clk.h>
-#include <dspbridge/sync.h>
 
 /*  ----------------------------------- Platform Manager */
-#include <dspbridge/dspapi-ioctl.h>
 #include <dspbridge/dspapi.h>
 #include <dspbridge/dspdrv.h>
 
 /*  ----------------------------------- Resource Manager */
 #include <dspbridge/pwr.h>
 
-/*  ----------------------------------- This */
-#include <drv_interface.h>
-
 #include <dspbridge/resourcecleanup.h>
-#include <dspbridge/chnl.h>
 #include <dspbridge/proc.h>
 #include <dspbridge/dev.h>
-#include <dspbridge/drv.h>
 
 #ifdef CONFIG_TIDSPBRIDGE_DVFS
 #include <mach-omap2/omap3-opp.h>
 #endif
 
 /*  ----------------------------------- Globals */
-#define DRIVER_NAME  "DspBridge"
 #define DSPBRIDGE_VERSION	"0.3"
 s32 dsp_debug;
 
@@ -131,7 +117,166 @@ MODULE_AUTHOR("Texas Instruments");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DSPBRIDGE_VERSION);
 
-static char *driver_name = DRIVER_NAME;
+/*
+ * This function is called when an application opens handle to the
+ * bridge driver.
+ */
+static int bridge_open(struct inode *ip, struct file *filp)
+{
+	int status = 0;
+	struct process_context *pr_ctxt = NULL;
+
+	/*
+	 * Allocate a new process context and insert it into global
+	 * process context list.
+	 */
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+	if (recover) {
+		if (filp->f_flags & O_NONBLOCK ||
+		    wait_for_completion_interruptible(&bridge_open_comp))
+			return -EBUSY;
+	}
+#endif
+	pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
+	if (!pr_ctxt)
+		return -ENOMEM;
+
+	pr_ctxt->res_state = PROC_RES_ALLOCATED;
+	spin_lock_init(&pr_ctxt->dmm_map_lock);
+	INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
+	spin_lock_init(&pr_ctxt->dmm_rsv_lock);
+	INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
+
+	pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+	if (!pr_ctxt->node_id) {
+		status = -ENOMEM;
+		goto err1;
+	}
+
+	idr_init(pr_ctxt->node_id);
+
+	pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
+	if (!pr_ctxt->stream_id) {
+		status = -ENOMEM;
+		goto err2;
+	}
+
+	idr_init(pr_ctxt->stream_id);
+
+	filp->private_data = pr_ctxt;
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+	atomic_inc(&bridge_cref);
+#endif
+	return 0;
+
+err2:
+	kfree(pr_ctxt->node_id);
+err1:
+	kfree(pr_ctxt);
+	return status;
+}
+
+/*
+ * This function is called when an application closes handle to the bridge
+ * driver.
+ */
+static int bridge_release(struct inode *ip, struct file *filp)
+{
+	int status = 0;
+	struct process_context *pr_ctxt;
+
+	if (!filp->private_data) {
+		status = -EIO;
+		goto err;
+	}
+
+	pr_ctxt = filp->private_data;
+	flush_signals(current);
+	drv_remove_all_resources(pr_ctxt);
+	proc_detach(pr_ctxt);
+	kfree(pr_ctxt->node_id);
+	kfree(pr_ctxt->stream_id);
+	kfree(pr_ctxt);
+
+	filp->private_data = NULL;
+
+err:
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+	if (!atomic_dec_return(&bridge_cref))
+		complete(&bridge_comp);
+#endif
+	return status;
+}
+
+/* This function provides IO interface to the bridge driver. */
+static long bridge_ioctl(struct file *filp, unsigned int code,
+			 unsigned long args)
+{
+	int status;
+	u32 retval = 0;
+	union trapped_args buf_in;
+
+#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
+	if (recover) {
+		status = -EIO;
+		goto err;
+	}
+#endif
+#ifdef CONFIG_PM
+	status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp);
+	if (status != 0)
+		return status;
+#endif
+
+	if (!filp->private_data) {
+		status = -EIO;
+		goto err;
+	}
+
+	status = copy_from_user(&buf_in, (union trapped_args *)args,
+				sizeof(union trapped_args));
+
+	if (!status) {
+		status = api_call_dev_ioctl(code, &buf_in, &retval,
+					    filp->private_data);
+
+		if (!status) {
+			status = retval;
+		} else {
+			dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x "
+				"status 0x%x\n", __func__, code, status);
+			status = -1;
+		}
+
+	}
+
+err:
+	return status;
+}
+
+/* This function maps kernel space memory to user space memory. */
+static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	u32 status;
+
+	vma->vm_flags |= VM_RESERVED | VM_IO;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx "
+		"flags %lx\n", __func__, filp,
+		vma->vm_start, vma->vm_end, vma->vm_page_prot,
+		vma->vm_flags);
+
+	status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+				 vma->vm_end - vma->vm_start,
+				 vma->vm_page_prot);
+	if (status != 0)
+		status = -EAGAIN;
+
+	return status;
+}
 
 static const struct file_operations bridge_fops = {
 	.open = bridge_open,
@@ -211,10 +356,10 @@ void bridge_recover_schedule(void)
 #endif
 #ifdef CONFIG_TIDSPBRIDGE_DVFS
 static int dspbridge_scale_notification(struct notifier_block *op,
-		unsigned long val, void *ptr)
+					unsigned long val, void *ptr)
 {
 	struct omap_dsp_platform_data *pdata =
-		omap_dspbridge_dev->dev.platform_data;
+	    omap_dspbridge_dev->dev.platform_data;
 
 	if (CPUFREQ_POSTCHANGE == val && pdata->dsp_get_opp)
 		pwr_pm_post_scale(PRCM_VDD1, pdata->dsp_get_opp());
@@ -319,7 +464,7 @@ err2:
 err1:
 #ifdef CONFIG_TIDSPBRIDGE_DVFS
 	cpufreq_unregister_notifier(&iva_clk_notifier,
-					CPUFREQ_TRANSITION_NOTIFIER);
+				    CPUFREQ_TRANSITION_NOTIFIER);
 #endif
 	dsp_clk_exit();
 
@@ -345,7 +490,7 @@ static int __devinit omap34_xx_bridge_probe(struct platform_device *pdev)
 		goto err1;
 
 	/* use 2.6 device model */
-	err = alloc_chrdev_region(&dev, 0, 1, driver_name);
+	err = alloc_chrdev_region(&dev, 0, 1, "DspBridge");
 	if (err) {
 		pr_err("%s: Can't get major %d\n", __func__, driver_major);
 		goto err1;
@@ -385,7 +530,6 @@ err1:
 static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
 {
 	dev_t devno;
-	bool ret;
 	int status = 0;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
@@ -398,16 +542,15 @@ static int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_TIDSPBRIDGE_DVFS
 	if (cpufreq_unregister_notifier(&iva_clk_notifier,
-						CPUFREQ_TRANSITION_NOTIFIER))
+					CPUFREQ_TRANSITION_NOTIFIER))
 		pr_err("%s: cpufreq_unregister_notifier failed for iva2_ck\n",
 		       __func__);
 #endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
 
 	if (driver_context) {
 		/* Put the DSP in reset state */
-		ret = dsp_deinit(driver_context);
+		dsp_deinit(driver_context);
 		driver_context = 0;
-		DBC_ASSERT(ret == true);
 	}
 
 	kfree(drv_datap);
@@ -431,7 +574,7 @@ func_cont:
 }
 
 #ifdef CONFIG_PM
-static int BRIDGE_SUSPEND(struct platform_device *pdev, pm_message_t state)
+static int bridge_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	u32 status;
 	u32 command = PWR_EMERGENCYDEEPSLEEP;
@@ -444,7 +587,7 @@ static int BRIDGE_SUSPEND(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int BRIDGE_RESUME(struct platform_device *pdev)
+static int bridge_resume(struct platform_device *pdev)
 {
 	u32 status;
 
@@ -456,9 +599,6 @@ static int BRIDGE_RESUME(struct platform_device *pdev)
 	wake_up(&bridge_suspend_data.suspend_wq);
 	return 0;
 }
-#else
-#define BRIDGE_SUSPEND NULL
-#define BRIDGE_RESUME NULL
 #endif
 
 static struct platform_driver bridge_driver = {
@@ -467,8 +607,10 @@ static struct platform_driver bridge_driver = {
 		   },
 	.probe = omap34_xx_bridge_probe,
 	.remove = __devexit_p(omap34_xx_bridge_remove),
-	.suspend = BRIDGE_SUSPEND,
-	.resume = BRIDGE_RESUME,
+#ifdef CONFIG_PM
+	.suspend = bridge_suspend,
+	.resume = bridge_resume,
+#endif
 };
 
 static int __init bridge_init(void)
@@ -481,170 +623,6 @@ static void __exit bridge_exit(void)
 	platform_driver_unregister(&bridge_driver);
 }
 
-/*
- * This function is called when an application opens handle to the
- * bridge driver.
- */
-static int bridge_open(struct inode *ip, struct file *filp)
-{
-	int status = 0;
-	struct process_context *pr_ctxt = NULL;
-
-	/*
-	 * Allocate a new process context and insert it into global
-	 * process context list.
-	 */
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-	if (recover) {
-		if (filp->f_flags & O_NONBLOCK ||
-			wait_for_completion_interruptible(&bridge_open_comp))
-			return -EBUSY;
-	}
-#endif
-	pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
-	if (!pr_ctxt)
-		return -ENOMEM;
-
-	pr_ctxt->res_state = PROC_RES_ALLOCATED;
-	spin_lock_init(&pr_ctxt->dmm_map_lock);
-	INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
-	spin_lock_init(&pr_ctxt->dmm_rsv_lock);
-	INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
-
-	pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
-	if (!pr_ctxt->node_id) {
-		status = -ENOMEM;
-		goto err1;
-	}
-
-	idr_init(pr_ctxt->node_id);
-
-	pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
-	if (!pr_ctxt->stream_id) {
-		status = -ENOMEM;
-		goto err2;
-	}
-
-	idr_init(pr_ctxt->stream_id);
-
-	filp->private_data = pr_ctxt;
-
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-	atomic_inc(&bridge_cref);
-#endif
-	return 0;
-
-err2:
-	kfree(pr_ctxt->node_id);
-err1:
-	kfree(pr_ctxt);
-	return status;
-}
-
-/*
- * This function is called when an application closes handle to the bridge
- * driver.
- */
-static int bridge_release(struct inode *ip, struct file *filp)
-{
-	int status = 0;
-	struct process_context *pr_ctxt;
-
-	if (!filp->private_data) {
-		status = -EIO;
-		goto err;
-	}
-
-	pr_ctxt = filp->private_data;
-	flush_signals(current);
-	drv_remove_all_resources(pr_ctxt);
-	proc_detach(pr_ctxt);
-	kfree(pr_ctxt->node_id);
-	kfree(pr_ctxt->stream_id);
-	kfree(pr_ctxt);
-
-	filp->private_data = NULL;
-
-err:
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-	if (!atomic_dec_return(&bridge_cref))
-		complete(&bridge_comp);
-#endif
-	return status;
-}
-
-/* This function provides IO interface to the bridge driver. */
-static long bridge_ioctl(struct file *filp, unsigned int code,
-			 unsigned long args)
-{
-	int status;
-	u32 retval = 0;
-	union trapped_args buf_in;
-
-	DBC_REQUIRE(filp != NULL);
-#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
-	if (recover) {
-		status = -EIO;
-		goto err;
-	}
-#endif
-#ifdef CONFIG_PM
-	status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp);
-	if (status != 0)
-		return status;
-#endif
-
-	if (!filp->private_data) {
-		status = -EIO;
-		goto err;
-	}
-
-	status = copy_from_user(&buf_in, (union trapped_args *)args,
-				sizeof(union trapped_args));
-
-	if (!status) {
-		status = api_call_dev_ioctl(code, &buf_in, &retval,
-					     filp->private_data);
-
-		if (!status) {
-			status = retval;
-		} else {
-			dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x "
-				"status 0x%x\n", __func__, code, status);
-			status = -1;
-		}
-
-	}
-
-err:
-	return status;
-}
-
-/* This function maps kernel space memory to user space memory. */
-static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	u32 offset = vma->vm_pgoff << PAGE_SHIFT;
-	u32 status;
-
-	DBC_ASSERT(vma->vm_start < vma->vm_end);
-
-	vma->vm_flags |= VM_RESERVED | VM_IO;
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	dev_dbg(bridge, "%s: vm filp %p offset %x start %lx end %lx page_prot "
-		"%lx flags %lx\n", __func__, filp, offset,
-		vma->vm_start, vma->vm_end, vma->vm_page_prot, vma->vm_flags);
-
-	status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-				 vma->vm_end - vma->vm_start,
-				 vma->vm_page_prot);
-	if (status != 0)
-		status = -EAGAIN;
-
-	return status;
-}
-
 /* To remove all process resources before removing the process from the
  * process context list */
 int drv_remove_all_resources(void *process_ctxt)
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.h b/drivers/staging/tidspbridge/rmgr/drv_interface.h
deleted file mode 100644
index ab07060..0000000
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * drv_interface.h
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#ifndef	_DRV_INTERFACE_H_
-#define _DRV_INTERFACE_H_
-
-/* Prototypes for all functions in this bridge */
-static int __init bridge_init(void);	/* Initialize bridge */
-static void __exit bridge_exit(void);	/* Opposite of initialize */
-static int bridge_open(struct inode *ip, struct file *filp);	/* Open */
-static int bridge_release(struct inode *ip, struct file *filp);	/* Release */
-static long bridge_ioctl(struct file *filp, unsigned int code,
-				unsigned long args);
-static int bridge_mmap(struct file *filp, struct vm_area_struct *vma);
-#endif /* ifndef _DRV_INTERFACE_H_ */
diff --git a/drivers/staging/tidspbridge/rmgr/dspdrv.c b/drivers/staging/tidspbridge/rmgr/dspdrv.c
index 7a6fc73..dc767b1 100644
--- a/drivers/staging/tidspbridge/rmgr/dspdrv.c
+++ b/drivers/staging/tidspbridge/rmgr/dspdrv.c
@@ -23,9 +23,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- Platform Manager */
 #include <dspbridge/drv.h>
 #include <dspbridge/dev.h>
@@ -102,8 +99,6 @@ func_cont:
 	} else {
 		dev_dbg(bridge, "%s: Failed\n", __func__);
 	}			/* End api_init_complete2 */
-	DBC_ENSURE((!status && drv_obj != NULL) ||
-		   (status && drv_obj == NULL));
 	*init_status = status;
 	/* Return the Driver Object */
 	return (u32) drv_obj;
diff --git a/drivers/staging/tidspbridge/rmgr/mgr.c b/drivers/staging/tidspbridge/rmgr/mgr.c
index d635c01..938eea5 100644
--- a/drivers/staging/tidspbridge/rmgr/mgr.c
+++ b/drivers/staging/tidspbridge/rmgr/mgr.c
@@ -26,9 +26,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -62,9 +59,6 @@ int mgr_create(struct mgr_object **mgr_obj,
 	struct mgr_object *pmgr_obj = NULL;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(mgr_obj != NULL);
-	DBC_REQUIRE(refs > 0);
-
 	pmgr_obj = kzalloc(sizeof(struct mgr_object), GFP_KERNEL);
 	if (pmgr_obj) {
 		status = dcd_create_manager(ZLDLLNAME, &pmgr_obj->dcd_mgr);
@@ -92,7 +86,6 @@ int mgr_create(struct mgr_object **mgr_obj,
 		status = -ENOMEM;
 	}
 
-	DBC_ENSURE(status || pmgr_obj);
 	return status;
 }
 
@@ -106,9 +99,6 @@ int mgr_destroy(struct mgr_object *hmgr_obj)
 	struct mgr_object *pmgr_obj = (struct mgr_object *)hmgr_obj;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hmgr_obj);
-
 	/* Free resources */
 	if (hmgr_obj->dcd_mgr)
 		dcd_destroy_manager(hmgr_obj->dcd_mgr);
@@ -140,11 +130,6 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
 	struct mgr_object *pmgr_obj = NULL;
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 
-	DBC_REQUIRE(pndb_props != NULL);
-	DBC_REQUIRE(pu_num_nodes != NULL);
-	DBC_REQUIRE(undb_props_size >= sizeof(struct dsp_ndbprops));
-	DBC_REQUIRE(refs > 0);
-
 	*pu_num_nodes = 0;
 	/* Get the Manager Object from the driver data */
 	if (!drv_datap || !drv_datap->mgr_object) {
@@ -153,7 +138,6 @@ int mgr_enum_node_info(u32 node_id, struct dsp_ndbprops *pndb_props,
 	}
 	pmgr_obj = drv_datap->mgr_object;
 
-	DBC_ASSERT(pmgr_obj);
 	/* Forever loop till we hit failed or no more items in the
 	 * Enumeration. We will exit the loop other than 0; */
 	while (!status) {
@@ -205,11 +189,6 @@ int mgr_enum_processor_info(u32 processor_id,
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 	bool proc_detect = false;
 
-	DBC_REQUIRE(processor_info != NULL);
-	DBC_REQUIRE(pu_num_procs != NULL);
-	DBC_REQUIRE(processor_info_size >= sizeof(struct dsp_processorinfo));
-	DBC_REQUIRE(refs > 0);
-
 	*pu_num_procs = 0;
 
 	/* Retrieve the Object handle from the driver data */
@@ -242,7 +221,6 @@ int mgr_enum_processor_info(u32 processor_id,
 		dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
 		goto func_end;
 	}
-	DBC_ASSERT(pmgr_obj);
 	/* Forever loop till we hit no more items in the
 	 * Enumeration. We will exit the loop other than 0; */
 	while (status1 == 0) {
@@ -310,12 +288,9 @@ func_end:
  */
 void mgr_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
 	refs--;
 	if (refs == 0)
 		dcd_exit();
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -328,16 +303,11 @@ int mgr_get_dcd_handle(struct mgr_object *mgr_handle,
 	int status = -EPERM;
 	struct mgr_object *pmgr_obj = (struct mgr_object *)mgr_handle;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dcd_handle != NULL);
-
 	*dcd_handle = (u32) NULL;
 	if (pmgr_obj) {
 		*dcd_handle = (u32) pmgr_obj->dcd_mgr;
 		status = 0;
 	}
-	DBC_ENSURE((!status && *dcd_handle != (u32) NULL) ||
-		   (status && *dcd_handle == (u32) NULL));
 
 	return status;
 }
@@ -351,8 +321,6 @@ bool mgr_init(void)
 	bool ret = true;
 	bool init_dcd = false;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (refs == 0) {
 		init_dcd = dcd_init();	/*  DCD Module */
 
@@ -363,8 +331,6 @@ bool mgr_init(void)
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
 
@@ -380,8 +346,6 @@ int mgr_wait_for_bridge_events(struct dsp_notification **anotifications,
 	struct sync_object *sync_events[MAX_EVENTS];
 	u32 i;
 
-	DBC_REQUIRE(count < MAX_EVENTS);
-
 	for (i = 0; i < count; i++)
 		sync_events[i] = anotifications[i]->handle;
 
diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c
index 0e70cba..5cff46f 100644
--- a/drivers/staging/tidspbridge/rmgr/nldr.c
+++ b/drivers/staging/tidspbridge/rmgr/nldr.c
@@ -22,8 +22,6 @@
 
 #include <dspbridge/dbdefs.h>
 
-#include <dspbridge/dbc.h>
-
 /* Platform manager */
 #include <dspbridge/cod.h>
 #include <dspbridge/dev.h>
@@ -313,11 +311,6 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref,
 	struct nldr_nodeobject *nldr_node_obj = NULL;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(node_props != NULL);
-	DBC_REQUIRE(nldr_nodeobj != NULL);
-	DBC_REQUIRE(nldr_obj);
-
 	/* Initialize handle in case of failure */
 	*nldr_nodeobj = NULL;
 	/* Allocate node object */
@@ -398,8 +391,6 @@ int nldr_allocate(struct nldr_object *nldr_obj, void *priv_ref,
 	if (status && nldr_node_obj)
 		kfree(nldr_node_obj);
 
-	DBC_ENSURE((!status && *nldr_nodeobj)
-		   || (status && *nldr_nodeobj == NULL));
 	return status;
 }
 
@@ -425,12 +416,6 @@ int nldr_create(struct nldr_object **nldr,
 	struct rmm_segment *rmm_segs = NULL;
 	u16 i;
 	int status = 0;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(nldr != NULL);
-	DBC_REQUIRE(hdev_obj != NULL);
-	DBC_REQUIRE(pattrs != NULL);
-	DBC_REQUIRE(pattrs->ovly != NULL);
-	DBC_REQUIRE(pattrs->write != NULL);
 
 	/* Allocate dynamic loader object */
 	nldr_obj = kzalloc(sizeof(struct nldr_object), GFP_KERNEL);
@@ -440,13 +425,10 @@ int nldr_create(struct nldr_object **nldr,
 		dev_get_cod_mgr(hdev_obj, &cod_mgr);
 		if (cod_mgr) {
 			status = cod_get_loader(cod_mgr, &nldr_obj->dbll);
-			DBC_ASSERT(!status);
 			status = cod_get_base_lib(cod_mgr, &nldr_obj->base_lib);
-			DBC_ASSERT(!status);
 			status =
 			    cod_get_base_name(cod_mgr, sz_zl_file,
 							COD_MAXPATHLENGTH);
-			DBC_ASSERT(!status);
 		}
 		status = 0;
 		/* end lazy status checking */
@@ -547,7 +529,6 @@ int nldr_create(struct nldr_object **nldr,
 		status =
 		    cod_get_base_name(cod_mgr, sz_zl_file, COD_MAXPATHLENGTH);
 		/* lazy check */
-		DBC_ASSERT(!status);
 		/* First count number of overlay nodes */
 		status =
 		    dcd_get_objects(nldr_obj->dcd_mgr, sz_zl_file,
@@ -583,7 +564,6 @@ int nldr_create(struct nldr_object **nldr,
 		*nldr = NULL;
 	}
 	/* FIXME:Temp. Fix. Must be removed */
-	DBC_ENSURE((!status && *nldr) || (status && *nldr == NULL));
 	return status;
 }
 
@@ -595,8 +575,6 @@ void nldr_delete(struct nldr_object *nldr_obj)
 	struct ovly_sect *ovly_section;
 	struct ovly_sect *next;
 	u16 i;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(nldr_obj);
 
 	nldr_obj->ldr_fxns.exit_fxn();
 	if (nldr_obj->rmm)
@@ -649,14 +627,10 @@ void nldr_delete(struct nldr_object *nldr_obj)
  */
 void nldr_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
 
 	if (refs == 0)
 		rmm_exit();
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -671,10 +645,6 @@ int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj,
 	bool status1 = false;
 	s32 i = 0;
 	struct lib_node root = { NULL, 0, NULL };
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(nldr_node_obj);
-	DBC_REQUIRE(addr != NULL);
-	DBC_REQUIRE(str_fxn != NULL);
 
 	nldr_obj = nldr_node_obj->nldr_obj;
 	/* Called from node_create(), node_delete(), or node_run(). */
@@ -690,7 +660,6 @@ int nldr_get_fxn_addr(struct nldr_nodeobject *nldr_node_obj,
 			root = nldr_node_obj->delete_lib;
 			break;
 		default:
-			DBC_ASSERT(false);
 			break;
 		}
 	} else {
@@ -760,7 +729,6 @@ int nldr_get_rmm_manager(struct nldr_object *nldr,
 {
 	int status = 0;
 	struct nldr_object *nldr_obj = nldr;
-	DBC_REQUIRE(rmm_mgr != NULL);
 
 	if (nldr) {
 		*rmm_mgr = nldr_obj->rmm;
@@ -769,8 +737,6 @@ int nldr_get_rmm_manager(struct nldr_object *nldr,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE(!status || (rmm_mgr != NULL && *rmm_mgr == NULL));
-
 	return status;
 }
 
@@ -780,14 +746,11 @@ int nldr_get_rmm_manager(struct nldr_object *nldr,
  */
 bool nldr_init(void)
 {
-	DBC_REQUIRE(refs >= 0);
-
 	if (refs == 0)
 		rmm_init();
 
 	refs++;
 
-	DBC_ENSURE(refs > 0);
 	return true;
 }
 
@@ -801,9 +764,6 @@ int nldr_load(struct nldr_nodeobject *nldr_node_obj,
 	struct dsp_uuid lib_uuid;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(nldr_node_obj);
-
 	nldr_obj = nldr_node_obj->nldr_obj;
 
 	if (nldr_node_obj->dynamic) {
@@ -839,7 +799,6 @@ int nldr_load(struct nldr_nodeobject *nldr_node_obj,
 					break;
 
 				default:
-					DBC_ASSERT(false);
 					break;
 				}
 			}
@@ -863,9 +822,6 @@ int nldr_unload(struct nldr_nodeobject *nldr_node_obj,
 	struct lib_node *root_lib = NULL;
 	s32 i = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(nldr_node_obj);
-
 	if (nldr_node_obj != NULL) {
 		if (nldr_node_obj->dynamic) {
 			if (*nldr_node_obj->phase_split) {
@@ -889,7 +845,6 @@ int nldr_unload(struct nldr_nodeobject *nldr_node_obj,
 					nldr_node_obj->pers_libs = 0;
 					break;
 				default:
-					DBC_ASSERT(false);
 					break;
 				}
 			} else {
@@ -929,7 +884,6 @@ static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info,
 	/* Find the node it belongs to */
 	for (i = 0; i < nldr_obj->ovly_nodes; i++) {
 		node_name = nldr_obj->ovly_table[i].node_name;
-		DBC_REQUIRE(node_name);
 		if (strncmp(node_name, sect_name + 1, strlen(node_name)) == 0) {
 			/* Found the node */
 			break;
@@ -1018,8 +972,6 @@ static int add_ovly_node(struct dsp_uuid *uuid_obj,
 			/* Add node to table */
 			nldr_obj->ovly_table[nldr_obj->ovly_nid].uuid =
 			    *uuid_obj;
-			DBC_REQUIRE(obj_def.obj_data.node_obj.ndb_props.
-				    ac_name);
 			len =
 			    strlen(obj_def.obj_data.node_obj.ndb_props.ac_name);
 			node_name = obj_def.obj_data.node_obj.ndb_props.ac_name;
@@ -1129,7 +1081,6 @@ static void free_sects(struct nldr_object *nldr_obj,
 		ret =
 		    rmm_free(nldr_obj->rmm, 0, ovly_section->sect_run_addr,
 			     ovly_section->size, true);
-		DBC_ASSERT(ret);
 		ovly_section = ovly_section->next_sect;
 		i++;
 	}
@@ -1249,7 +1200,6 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj,
 
 	if (depth > MAXDEPTH) {
 		/* Error */
-		DBC_ASSERT(false);
 	}
 	root->lib = NULL;
 	/* Allocate a buffer for library file name of size DBL_MAXPATHLENGTH */
@@ -1312,7 +1262,6 @@ static int load_lib(struct nldr_nodeobject *nldr_node_obj,
 		    dcd_get_num_dep_libs(nldr_node_obj->nldr_obj->dcd_mgr,
 					 &uuid, &nd_libs, &np_libs, phase);
 	}
-	DBC_ASSERT(nd_libs >= np_libs);
 	if (!status) {
 		if (!(*nldr_node_obj->phase_split))
 			np_libs = 0;
@@ -1474,7 +1423,6 @@ static int load_ovly(struct nldr_nodeobject *nldr_node_obj,
 		}
 	}
 
-	DBC_ASSERT(i < nldr_obj->ovly_nodes);
 
 	if (!po_node) {
 		status = -ENOENT;
@@ -1500,7 +1448,6 @@ static int load_ovly(struct nldr_nodeobject *nldr_node_obj,
 		break;
 
 	default:
-		DBC_ASSERT(false);
 		break;
 	}
 
@@ -1623,9 +1570,6 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size,
 	struct rmm_addr *rmm_addr_obj = (struct rmm_addr *)dsp_address;
 	bool mem_load_req = false;
 	int status = -ENOMEM;	/* Set to fail */
-	DBC_REQUIRE(hnode);
-	DBC_REQUIRE(mem_sect == DBLL_CODE || mem_sect == DBLL_DATA ||
-		    mem_sect == DBLL_BSS);
 	nldr_obj = hnode->nldr_obj;
 	rmm = nldr_obj->rmm;
 	/* Convert size to DSP words */
@@ -1651,7 +1595,6 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size,
 			mem_phase_bit = EXECUTEDATAFLAGBIT;
 			break;
 		default:
-			DBC_ASSERT(false);
 			break;
 		}
 		if (mem_sect == DBLL_CODE)
@@ -1670,11 +1613,9 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size,
 	/* Find an appropriate segment based on mem_sect */
 	if (segid == NULLID) {
 		/* No memory requirements of preferences */
-		DBC_ASSERT(!mem_load_req);
 		goto func_cont;
 	}
 	if (segid <= MAXSEGID) {
-		DBC_ASSERT(segid < nldr_obj->dload_segs);
 		/* Attempt to allocate from segid first. */
 		rmm_addr_obj->segid = segid;
 		status =
@@ -1685,7 +1626,6 @@ static int remote_alloc(void **ref, u16 mem_sect, u32 size,
 		}
 	} else {
 		/* segid > MAXSEGID ==> Internal or external memory */
-		DBC_ASSERT(segid == MEMINTERNALID || segid == MEMEXTERNALID);
 		/*  Check for any internal or external memory segment,
 		 *  depending on segid. */
 		mem_sect_type |= segid == MEMINTERNALID ?
@@ -1736,8 +1676,6 @@ static int remote_free(void **ref, u16 space, u32 dsp_address,
 	u32 word_size;
 	int status = -ENOMEM;	/* Set to fail */
 
-	DBC_REQUIRE(nldr_obj);
-
 	rmm = nldr_obj->rmm;
 
 	/* Convert size to DSP words */
@@ -1761,7 +1699,6 @@ static void unload_lib(struct nldr_nodeobject *nldr_node_obj,
 	struct nldr_object *nldr_obj = nldr_node_obj->nldr_obj;
 	u16 i;
 
-	DBC_ASSERT(root != NULL);
 
 	/* Unload dependent libraries */
 	for (i = 0; i < root->dep_libs; i++)
@@ -1812,7 +1749,6 @@ static void unload_ovly(struct nldr_nodeobject *nldr_node_obj,
 		}
 	}
 
-	DBC_ASSERT(i < nldr_obj->ovly_nodes);
 
 	if (!po_node)
 		/* TODO: Should we print warning here? */
@@ -1839,14 +1775,11 @@ static void unload_ovly(struct nldr_nodeobject *nldr_node_obj,
 		other_alloc = po_node->other_sects;
 		break;
 	default:
-		DBC_ASSERT(false);
 		break;
 	}
-	DBC_ASSERT(ref_count && (*ref_count > 0));
 	if (ref_count && (*ref_count > 0)) {
 		*ref_count -= 1;
 		if (other_ref) {
-			DBC_ASSERT(*other_ref > 0);
 			*other_ref -= 1;
 		}
 	}
@@ -1897,9 +1830,6 @@ int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr,
 	bool status1 = false;
 	s32 i = 0;
 	struct lib_node root = { NULL, 0, NULL };
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(offset_output != NULL);
-	DBC_REQUIRE(sym_name != NULL);
 	pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x,  %s)\n", __func__, (u32) nldr_node,
 			sym_addr, offset_range, (u32) offset_output, sym_name);
 
@@ -1915,7 +1845,6 @@ int nldr_find_addr(struct nldr_nodeobject *nldr_node, u32 sym_addr,
 			root = nldr_node->delete_lib;
 			break;
 		default:
-			DBC_ASSERT(false);
 			break;
 		}
 	} else {
diff --git a/drivers/staging/tidspbridge/rmgr/node.c b/drivers/staging/tidspbridge/rmgr/node.c
index 5dadaa4..1b24589 100644
--- a/drivers/staging/tidspbridge/rmgr/node.c
+++ b/drivers/staging/tidspbridge/rmgr/node.c
@@ -26,9 +26,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/memdefs.h>
 #include <dspbridge/proc.h>
@@ -326,11 +323,6 @@ int node_allocate(struct proc_object *hprocessor,
 
 	void *node_res;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hprocessor != NULL);
-	DBC_REQUIRE(noderes != NULL);
-	DBC_REQUIRE(node_uuid != NULL);
-
 	*noderes = NULL;
 
 	status = proc_get_processor_id(hprocessor, &proc_id);
@@ -673,7 +665,6 @@ func_cont:
 		drv_proc_node_update_heap_status(node_res, true);
 		drv_proc_node_update_status(node_res, true);
 	}
-	DBC_ENSURE((status && *noderes == NULL) || (!status && *noderes));
 func_end:
 	dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p "
 		"node_res: %p status: 0x%x\n", __func__, hprocessor,
@@ -696,11 +687,6 @@ DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize,
 	bool set_info;
 	u32 proc_id;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pbuffer != NULL);
-
-	DBC_REQUIRE(usize > 0);
-
 	if (!pnode)
 		status = -EFAULT;
 	else if (node_get_type(pnode) == NODE_DEVICE)
@@ -714,7 +700,6 @@ DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize,
 
 	status = proc_get_processor_id(pnode->processor, &proc_id);
 	if (proc_id != DSP_UNIT) {
-		DBC_ASSERT(NULL);
 		goto func_end;
 	}
 	/*  If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a
@@ -782,8 +767,6 @@ int node_change_priority(struct node_object *hnode, s32 prio)
 	int status = 0;
 	u32 proc_id;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!hnode || !hnode->node_mgr) {
 		status = -EFAULT;
 	} else {
@@ -854,7 +837,6 @@ int node_connect(struct node_object *node1, u32 stream1,
 	s8 chnl_mode;
 	u32 dw_length;
 	int status = 0;
-	DBC_REQUIRE(refs > 0);
 
 	if (!node1 || !node2)
 		return -EFAULT;
@@ -903,7 +885,6 @@ int node_connect(struct node_object *node1, u32 stream1,
 	if (node1_type != NODE_GPP) {
 		hnode_mgr = node1->node_mgr;
 	} else {
-		DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE);
 		hnode_mgr = node2->node_mgr;
 	}
 
@@ -982,9 +963,6 @@ int node_connect(struct node_object *node1, u32 stream1,
 			goto out_unlock;
 		}
 
-		DBC_ASSERT((node1_type == NODE_GPP) ||
-				(node2_type == NODE_GPP));
-
 		chnl_mode = (node1_type == NODE_GPP) ?
 			CHNL_MODETODSP : CHNL_MODEFROMDSP;
 
@@ -1139,7 +1117,6 @@ int node_create(struct node_object *hnode)
 	    omap_dspbridge_dev->dev.platform_data;
 #endif
 
-	DBC_REQUIRE(refs > 0);
 	if (!pnode) {
 		status = -EFAULT;
 		goto func_end;
@@ -1291,10 +1268,6 @@ int node_create_mgr(struct node_mgr **node_man,
 	int status = 0;
 	u8 dev_type;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(node_man != NULL);
-	DBC_REQUIRE(hdev_obj != NULL);
-
 	*node_man = NULL;
 	/* Allocate Node manager object */
 	node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL);
@@ -1375,8 +1348,6 @@ int node_create_mgr(struct node_mgr **node_man,
 
 	*node_man = node_mgr_obj;
 
-	DBC_ENSURE((status && *node_man == NULL) || (!status && *node_man));
-
 	return status;
 out_err:
 	delete_node_mgr(node_mgr_obj);
@@ -1409,7 +1380,6 @@ int node_delete(struct node_res_object *noderes,
 	void *node_res = noderes;
 
 	struct dsp_processorstate proc_state;
-	DBC_REQUIRE(refs > 0);
 
 	if (!pnode) {
 		status = -EFAULT;
@@ -1554,8 +1524,6 @@ func_end:
  */
 int node_delete_mgr(struct node_mgr *hnode_mgr)
 {
-	DBC_REQUIRE(refs > 0);
-
 	if (!hnode_mgr)
 		return -EFAULT;
 
@@ -1576,10 +1544,6 @@ int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab,
 	struct node_object *hnode;
 	u32 i = 0;
 	int status = 0;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
-	DBC_REQUIRE(pu_num_nodes != NULL);
-	DBC_REQUIRE(pu_allocated != NULL);
 
 	if (!hnode_mgr) {
 		status = -EFAULT;
@@ -1611,11 +1575,7 @@ func_end:
  */
 void node_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -1629,10 +1589,6 @@ int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer,
 	struct node_object *pnode = (struct node_object *)hnode;
 	int status = 0;
 	u32 proc_id;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pbuffer != NULL);
-	DBC_REQUIRE(pnode != NULL);
-	DBC_REQUIRE(pnode->xlator != NULL);
 
 	if (!hnode) {
 		status = -EFAULT;
@@ -1653,7 +1609,6 @@ int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer,
 			status = cmm_xlator_free_buf(pnode->xlator, pbuffer);
 		}
 	} else {
-		DBC_ASSERT(NULL);	/* BUG */
 	}
 func_end:
 	return status;
@@ -1669,9 +1624,6 @@ int node_get_attr(struct node_object *hnode,
 			 struct dsp_nodeattr *pattr, u32 attr_size)
 {
 	struct node_mgr *hnode_mgr;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pattr != NULL);
-	DBC_REQUIRE(attr_size >= sizeof(struct dsp_nodeattr));
 
 	if (!hnode)
 		return -EFAULT;
@@ -1713,9 +1665,6 @@ int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index,
 {
 	enum node_type node_type;
 	int status = -EINVAL;
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dir == DSP_TONODE || dir == DSP_FROMNODE);
-	DBC_REQUIRE(chan_id != NULL);
 
 	if (!hnode) {
 		status = -EFAULT;
@@ -1734,7 +1683,6 @@ int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index,
 			}
 		}
 	} else {
-		DBC_ASSERT(dir == DSP_FROMNODE);
 		if (index < MAX_OUTPUTS(hnode)) {
 			if (hnode->outputs[index].type == HOSTCONNECT) {
 				*chan_id = hnode->outputs[index].dev_id;
@@ -1761,9 +1709,6 @@ int node_get_message(struct node_object *hnode,
 	struct dsp_processorstate proc_state;
 	struct proc_object *hprocessor;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(message != NULL);
-
 	if (!hnode) {
 		status = -EFAULT;
 		goto func_end;
@@ -1831,14 +1776,12 @@ int node_get_nldr_obj(struct node_mgr *hnode_mgr,
 {
 	int status = 0;
 	struct node_mgr *node_mgr_obj = hnode_mgr;
-	DBC_REQUIRE(nldr_ovlyobj != NULL);
 
 	if (!hnode_mgr)
 		status = -EFAULT;
 	else
 		*nldr_ovlyobj = node_mgr_obj->nldr_obj;
 
-	DBC_ENSURE(!status || (nldr_ovlyobj != NULL && *nldr_ovlyobj == NULL));
 	return status;
 }
 
@@ -1852,8 +1795,6 @@ int node_get_strm_mgr(struct node_object *hnode,
 {
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!hnode)
 		status = -EFAULT;
 	else
@@ -1867,8 +1808,6 @@ int node_get_strm_mgr(struct node_object *hnode,
  */
 enum nldr_loadtype node_get_load_type(struct node_object *hnode)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hnode);
 	if (!hnode) {
 		dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode);
 		return -1;
@@ -1884,8 +1823,6 @@ enum nldr_loadtype node_get_load_type(struct node_object *hnode)
  */
 u32 node_get_timeout(struct node_object *hnode)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hnode);
 	if (!hnode) {
 		dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode);
 		return 0;
@@ -1921,8 +1858,6 @@ enum node_type node_get_type(struct node_object *hnode)
  */
 bool node_init(void)
 {
-	DBC_REQUIRE(refs >= 0);
-
 	refs++;
 
 	return true;
@@ -1970,8 +1905,6 @@ int node_pause(struct node_object *hnode)
 	struct dsp_processorstate proc_state;
 	struct proc_object *hprocessor;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!hnode) {
 		status = -EFAULT;
 	} else {
@@ -2054,9 +1987,6 @@ int node_put_message(struct node_object *hnode,
 	struct dsp_processorstate proc_state;
 	struct proc_object *hprocessor;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pmsg != NULL);
-
 	if (!hnode) {
 		status = -EFAULT;
 		goto func_end;
@@ -2146,9 +2076,6 @@ int node_register_notify(struct node_object *hnode, u32 event_mask,
 	struct bridge_drv_interface *intf_fxns;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hnotification != NULL);
-
 	if (!hnode) {
 		status = -EFAULT;
 	} else {
@@ -2207,8 +2134,6 @@ int node_run(struct node_object *hnode)
 	struct dsp_processorstate proc_state;
 	struct proc_object *hprocessor;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!hnode) {
 		status = -EFAULT;
 		goto func_end;
@@ -2287,7 +2212,6 @@ int node_run(struct node_object *hnode)
 						   NODE_GET_PRIORITY(hnode));
 	} else {
 		/* We should never get here */
-		DBC_ASSERT(false);
 	}
 func_cont1:
 	/* Update node state. */
@@ -2326,9 +2250,6 @@ int node_terminate(struct node_object *hnode, int *pstatus)
 	struct deh_mgr *hdeh_mgr;
 	struct dsp_processorstate proc_state;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pstatus != NULL);
-
 	if (!hnode || !hnode->node_mgr) {
 		status = -EFAULT;
 		goto func_end;
@@ -2668,7 +2589,6 @@ static void fill_stream_connect(struct node_object *node1,
 			strm1->connect_type = CONNECTTYPE_GPPOUTPUT;
 	} else {
 		/* GPP == > NODE */
-		DBC_ASSERT(node2 != (struct node_object *)DSP_HGPPNODE);
 		strm_index = node2->num_inputs + node2->num_outputs - 1;
 		strm2 = &(node2->stream_connect[strm_index]);
 		strm2->cb_struct = sizeof(struct dsp_streamconnect);
@@ -2748,9 +2668,6 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr,
 	char *pstr_fxn_name = NULL;
 	struct node_mgr *hnode_mgr = hnode->node_mgr;
 	int status = 0;
-	DBC_REQUIRE(node_get_type(hnode) == NODE_TASK ||
-		    node_get_type(hnode) == NODE_DAISSOCKET ||
-		    node_get_type(hnode) == NODE_MESSAGE);
 
 	switch (phase) {
 	case CREATEPHASE:
@@ -2767,7 +2684,6 @@ static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr,
 		break;
 	default:
 		/* Should never get here */
-		DBC_ASSERT(false);
 		break;
 	}
 
@@ -2787,9 +2703,6 @@ void get_node_info(struct node_object *hnode, struct dsp_nodeinfo *node_info)
 {
 	u32 i;
 
-	DBC_REQUIRE(hnode);
-	DBC_REQUIRE(node_info != NULL);
-
 	node_info->cb_struct = sizeof(struct dsp_nodeinfo);
 	node_info->nb_node_database_props =
 	    hnode->dcd_props.obj_data.node_obj.ndb_props;
@@ -2848,9 +2761,7 @@ static int get_node_props(struct dcd_manager *hdcd_mgr,
 				pmsg_args->max_msgs);
 		} else {
 			/* Copy device name */
-			DBC_REQUIRE(pndb_props->ac_name);
 			len = strlen(pndb_props->ac_name);
-			DBC_ASSERT(len < MAXDEVNAMELEN);
 			hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL);
 			if (hnode->str_dev_name == NULL) {
 				status = -ENOMEM;
@@ -2938,10 +2849,6 @@ int node_get_uuid_props(void *hprocessor,
 	struct dcd_nodeprops dcd_node_props;
 	struct dsp_processorstate proc_state;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hprocessor != NULL);
-	DBC_REQUIRE(node_uuid != NULL);
-
 	if (hprocessor == NULL || node_uuid == NULL) {
 		status = -EFAULT;
 		goto func_end;
@@ -3063,8 +2970,6 @@ static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
 	/* Function interface to Bridge driver*/
 	struct bridge_drv_interface *intf_fxns;
 
-	DBC_REQUIRE(hnode);
-
 	hnode_mgr = hnode->node_mgr;
 
 	ul_size = ul_num_bytes / hnode_mgr->dsp_word_size;
@@ -3106,9 +3011,6 @@ static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
 	/* Function interface to Bridge driver */
 	struct bridge_drv_interface *intf_fxns;
 
-	DBC_REQUIRE(hnode);
-	DBC_REQUIRE(mem_space & DBLL_CODE || mem_space & DBLL_DATA);
-
 	hnode_mgr = hnode->node_mgr;
 
 	ul_timeout = hnode->timeout;
diff --git a/drivers/staging/tidspbridge/rmgr/proc.c b/drivers/staging/tidspbridge/rmgr/proc.c
index 242dd13..b865d64 100644
--- a/drivers/staging/tidspbridge/rmgr/proc.c
+++ b/drivers/staging/tidspbridge/rmgr/proc.c
@@ -25,9 +25,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/ntfy.h>
 #include <dspbridge/sync.h>
@@ -281,9 +278,6 @@ proc_attach(u32 processor_id,
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 	u8 dev_type;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(ph_processor != NULL);
-
 	if (pr_ctxt->processor) {
 		*ph_processor = pr_ctxt->processor;
 		return status;
@@ -382,10 +376,6 @@ proc_attach(u32 processor_id,
 		kfree(p_proc_object);
 	}
 func_end:
-	DBC_ENSURE((status == -EPERM && *ph_processor == NULL) ||
-		   (!status && p_proc_object) ||
-		   (status == 0 && p_proc_object));
-
 	return status;
 }
 
@@ -445,10 +435,6 @@ int proc_auto_start(struct cfg_devnode *dev_node_obj,
 	struct drv_data *drv_datap = dev_get_drvdata(bridge);
 	u8 dev_type;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(dev_node_obj != NULL);
-	DBC_REQUIRE(hdev_obj != NULL);
-
 	/* Create a Dummy PROC Object */
 	if (!drv_datap || !drv_datap->mgr_object) {
 		status = -ENODATA;
@@ -516,8 +502,6 @@ int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg)
 	struct proc_object *p_proc_object = hprocessor;
 	u32 timeout = 0;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (p_proc_object) {
 		/* intercept PWR deep sleep command */
 		if (dw_cmd == BRDIOCTL_DEEPSLEEP) {
@@ -565,8 +549,6 @@ int proc_detach(struct process_context *pr_ctxt)
 	int status = 0;
 	struct proc_object *p_proc_object = NULL;
 
-	DBC_REQUIRE(refs > 0);
-
 	p_proc_object = (struct proc_object *)pr_ctxt->processor;
 
 	if (p_proc_object) {
@@ -607,11 +589,6 @@ int proc_enum_nodes(void *hprocessor, void **node_tab,
 	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
 	struct node_mgr *hnode_mgr = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
-	DBC_REQUIRE(pu_num_nodes != NULL);
-	DBC_REQUIRE(pu_allocated != NULL);
-
 	if (p_proc_object) {
 		if (!(dev_get_node_manager(p_proc_object->dev_obj,
 						       &hnode_mgr))) {
@@ -768,8 +745,6 @@ int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
 	struct process_context *pr_ctxt = (struct process_context *) hprocessor;
 	struct dmm_map_object *map_obj;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!pr_ctxt) {
 		status = -EFAULT;
 		goto err_out;
@@ -810,8 +785,6 @@ int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
 	struct process_context *pr_ctxt = (struct process_context *) hprocessor;
 	struct dmm_map_object *map_obj;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!pr_ctxt) {
 		status = -EFAULT;
 		goto err_out;
@@ -884,10 +857,6 @@ int proc_get_resource_info(void *hprocessor, u32 resource_type,
 	struct rmm_target_obj *rmm = NULL;
 	struct io_mgr *hio_mgr = NULL;	/* IO manager handle */
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(resource_info != NULL);
-	DBC_REQUIRE(resource_info_size >= sizeof(struct dsp_resourceinfo));
-
 	if (!p_proc_object) {
 		status = -EFAULT;
 		goto func_end;
@@ -947,11 +916,7 @@ func_end:
  */
 void proc_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -966,9 +931,6 @@ int proc_get_dev_object(void *hprocessor,
 	int status = -EPERM;
 	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(device_obj != NULL);
-
 	if (p_proc_object) {
 		*device_obj = p_proc_object->dev_obj;
 		status = 0;
@@ -977,9 +939,6 @@ int proc_get_dev_object(void *hprocessor,
 		status = -EFAULT;
 	}
 
-	DBC_ENSURE((!status && *device_obj != NULL) ||
-		   (status && *device_obj == NULL));
-
 	return status;
 }
 
@@ -996,10 +955,6 @@ int proc_get_state(void *hprocessor,
 	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
 	int brd_status;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(proc_state_obj != NULL);
-	DBC_REQUIRE(state_info_size >= sizeof(struct dsp_processorstate));
-
 	if (p_proc_object) {
 		/* First, retrieve BRD state information */
 		status = (*p_proc_object->intf_fxns->brd_status)
@@ -1063,13 +1018,9 @@ bool proc_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
 
@@ -1111,10 +1062,6 @@ int proc_load(void *hprocessor, const s32 argc_index,
 	    omap_dspbridge_dev->dev.platform_data;
 #endif
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(argc_index > 0);
-	DBC_REQUIRE(user_args != NULL);
-
 #ifdef OPT_LOAD_TIME_INSTRUMENTATION
 	do_gettimeofday(&tv1);
 #endif
@@ -1202,8 +1149,6 @@ int proc_load(void *hprocessor, const s32 argc_index,
 			if (status) {
 				status = -EPERM;
 			} else {
-				DBC_ASSERT(p_proc_object->last_coff ==
-					   NULL);
 				/* Allocate memory for pszLastCoff */
 				p_proc_object->last_coff =
 						kzalloc((strlen(user_args[0]) +
@@ -1226,7 +1171,6 @@ int proc_load(void *hprocessor, const s32 argc_index,
 		if (!hmsg_mgr) {
 			status = msg_create(&hmsg_mgr, p_proc_object->dev_obj,
 					    (msg_onexit) node_on_exit);
-			DBC_ASSERT(!status);
 			dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr);
 		}
 	}
@@ -1322,7 +1266,6 @@ int proc_load(void *hprocessor, const s32 argc_index,
 							strlen(pargv0) + 1);
 			else
 				status = -ENOMEM;
-			DBC_ASSERT(brd_state == BRD_LOADED);
 		}
 	}
 
@@ -1331,9 +1274,6 @@ func_end:
 		pr_err("%s: Processor failed to load\n", __func__);
 		proc_stop(p_proc_object);
 	}
-	DBC_ENSURE((!status
-		    && p_proc_object->proc_state == PROC_LOADED)
-		   || status);
 #ifdef OPT_LOAD_TIME_INSTRUMENTATION
 	do_gettimeofday(&tv2);
 	if (tv2.tv_usec < tv1.tv_usec) {
@@ -1443,9 +1383,6 @@ int proc_register_notify(void *hprocessor, u32 event_mask,
 	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
 	struct deh_mgr *hdeh_mgr;
 
-	DBC_REQUIRE(hnotification != NULL);
-	DBC_REQUIRE(refs > 0);
-
 	/* Check processor handle */
 	if (!p_proc_object) {
 		status = -EFAULT;
@@ -1567,7 +1504,6 @@ int proc_start(void *hprocessor)
 	u32 dw_dsp_addr;	/* Loaded code's entry point. */
 	int brd_state;
 
-	DBC_REQUIRE(refs > 0);
 	if (!p_proc_object) {
 		status = -EFAULT;
 		goto func_end;
@@ -1616,7 +1552,6 @@ func_cont:
 		if (!((*p_proc_object->intf_fxns->brd_status)
 				(p_proc_object->bridge_context, &brd_state))) {
 			pr_info("%s: dsp in running state\n", __func__);
-			DBC_ASSERT(brd_state != BRD_HIBERNATION);
 		}
 	} else {
 		pr_err("%s: Failed to start the dsp\n", __func__);
@@ -1624,8 +1559,6 @@ func_cont:
 	}
 
 func_end:
-	DBC_ENSURE((!status && p_proc_object->proc_state ==
-		    PROC_RUNNING) || status);
 	return status;
 }
 
@@ -1644,9 +1577,7 @@ int proc_stop(void *hprocessor)
 	u32 node_tab_size = 1;
 	u32 num_nodes = 0;
 	u32 nodes_allocated = 0;
-	int brd_state;
 
-	DBC_REQUIRE(refs > 0);
 	if (!p_proc_object) {
 		status = -EFAULT;
 		goto func_end;
@@ -1678,11 +1609,6 @@ int proc_stop(void *hprocessor)
 				msg_delete(hmsg_mgr);
 				dev_set_msg_mgr(p_proc_object->dev_obj, NULL);
 			}
-			if (!((*p_proc_object->
-			      intf_fxns->brd_status) (p_proc_object->
-							  bridge_context,
-							  &brd_state)))
-				DBC_ASSERT(brd_state == BRD_STOPPED);
 		}
 	} else {
 		pr_err("%s: Failed to stop the processor\n", __func__);
@@ -1820,10 +1746,6 @@ static int proc_monitor(struct proc_object *proc_obj)
 {
 	int status = -EPERM;
 	struct msg_mgr *hmsg_mgr;
-	int brd_state;
-
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(proc_obj);
 
 	/* This is needed only when Device is loaded when it is
 	 * already 'ACTIVE' */
@@ -1840,13 +1762,8 @@ static int proc_monitor(struct proc_object *proc_obj)
 	if (!((*proc_obj->intf_fxns->brd_monitor)
 			  (proc_obj->bridge_context))) {
 		status = 0;
-		if (!((*proc_obj->intf_fxns->brd_status)
-				  (proc_obj->bridge_context, &brd_state)))
-			DBC_ASSERT(brd_state == BRD_IDLE);
 	}
 
-	DBC_ENSURE((!status && brd_state == BRD_IDLE) ||
-		   status);
 	return status;
 }
 
@@ -1880,8 +1797,6 @@ static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
 {
 	char **pp_envp = new_envp;
 
-	DBC_REQUIRE(new_envp);
-
 	/* Prepend new environ var=value string */
 	*new_envp++ = sz_var;
 
@@ -1906,9 +1821,6 @@ int proc_notify_clients(void *proc, u32 events)
 	int status = 0;
 	struct proc_object *p_proc_object = (struct proc_object *)proc;
 
-	DBC_REQUIRE(p_proc_object);
-	DBC_REQUIRE(is_valid_proc_event(events));
-	DBC_REQUIRE(refs > 0);
 	if (!p_proc_object) {
 		status = -EFAULT;
 		goto func_end;
@@ -1930,9 +1842,6 @@ int proc_notify_all_clients(void *proc, u32 events)
 	int status = 0;
 	struct proc_object *p_proc_object = (struct proc_object *)proc;
 
-	DBC_REQUIRE(is_valid_proc_event(events));
-	DBC_REQUIRE(refs > 0);
-
 	if (!p_proc_object) {
 		status = -EFAULT;
 		goto func_end;
diff --git a/drivers/staging/tidspbridge/rmgr/rmm.c b/drivers/staging/tidspbridge/rmgr/rmm.c
index f3dc0dd..55acfcd 100644
--- a/drivers/staging/tidspbridge/rmgr/rmm.c
+++ b/drivers/staging/tidspbridge/rmgr/rmm.c
@@ -46,9 +46,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- This */
 #include <dspbridge/rmm.h>
 
@@ -101,12 +98,6 @@ int rmm_alloc(struct rmm_target_obj *target, u32 segid, u32 size,
 	u32 addr;
 	int status = 0;
 
-	DBC_REQUIRE(target);
-	DBC_REQUIRE(dsp_address != NULL);
-	DBC_REQUIRE(size > 0);
-	DBC_REQUIRE(reserve || (target->num_segs > 0));
-	DBC_REQUIRE(refs > 0);
-
 	if (!reserve) {
 		if (!alloc_block(target, segid, size, align, dsp_address)) {
 			status = -ENOMEM;
@@ -170,9 +161,6 @@ int rmm_create(struct rmm_target_obj **target_obj,
 	s32 i;
 	int status = 0;
 
-	DBC_REQUIRE(target_obj != NULL);
-	DBC_REQUIRE(num_segs == 0 || seg_tab != NULL);
-
 	/* Allocate DBL target object */
 	target = kzalloc(sizeof(struct rmm_target_obj), GFP_KERNEL);
 
@@ -235,9 +223,6 @@ func_cont:
 
 	}
 
-	DBC_ENSURE((!status && *target_obj)
-		   || (status && *target_obj == NULL));
-
 	return status;
 }
 
@@ -251,8 +236,6 @@ void rmm_delete(struct rmm_target_obj *target)
 	struct rmm_header *next;
 	u32 i;
 
-	DBC_REQUIRE(target);
-
 	kfree(target->seg_tab);
 
 	list_for_each_entry_safe(sect, tmp, &target->ovly_list, list_elem) {
@@ -281,11 +264,7 @@ void rmm_delete(struct rmm_target_obj *target)
  */
 void rmm_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -297,15 +276,6 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size,
 	struct rmm_ovly_sect *sect, *tmp;
 	bool ret = false;
 
-	DBC_REQUIRE(target);
-
-	DBC_REQUIRE(reserved || segid < target->num_segs);
-	DBC_REQUIRE(reserved || (dsp_addr >= target->seg_tab[segid].base &&
-				 (dsp_addr + size) <= (target->seg_tab[segid].
-						   base +
-						   target->seg_tab[segid].
-						   length)));
-
 	/*
 	 *  Free or unreserve memory.
 	 */
@@ -319,7 +289,6 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size,
 		list_for_each_entry_safe(sect, tmp, &target->ovly_list,
 				list_elem) {
 			if (dsp_addr == sect->addr) {
-				DBC_ASSERT(size == sect->size);
 				/* Remove from list */
 				list_del(&sect->list_elem);
 				kfree(sect);
@@ -335,8 +304,6 @@ bool rmm_free(struct rmm_target_obj *target, u32 segid, u32 dsp_addr, u32 size,
  */
 bool rmm_init(void)
 {
-	DBC_REQUIRE(refs >= 0);
-
 	refs++;
 
 	return true;
@@ -354,9 +321,6 @@ bool rmm_stat(struct rmm_target_obj *target, enum dsp_memtype segid,
 	u32 total_free_size = 0;
 	u32 free_blocks = 0;
 
-	DBC_REQUIRE(mem_stat_buf != NULL);
-	DBC_ASSERT(target != NULL);
-
 	if ((u32) segid < target->num_segs) {
 		head = target->free_list[segid];
 
diff --git a/drivers/staging/tidspbridge/rmgr/strm.c b/drivers/staging/tidspbridge/rmgr/strm.c
index 3fae0e9..bd684f1 100644
--- a/drivers/staging/tidspbridge/rmgr/strm.c
+++ b/drivers/staging/tidspbridge/rmgr/strm.c
@@ -24,9 +24,6 @@
 /*  ----------------------------------- DSP/BIOS Bridge */
 #include <dspbridge/dbdefs.h>
 
-/*  ----------------------------------- Trace & Debug */
-#include <dspbridge/dbc.h>
-
 /*  ----------------------------------- OS Adaptation Layer */
 #include <dspbridge/sync.h>
 
@@ -104,9 +101,6 @@ int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize,
 	u32 i;
 	struct strm_object *stream_obj = strmres->stream;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(ap_buffer != NULL);
-
 	if (stream_obj) {
 		/*
 		 * Allocate from segment specified at time of stream open.
@@ -122,7 +116,6 @@ int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize,
 		goto func_end;
 
 	for (i = 0; i < num_bufs; i++) {
-		DBC_ASSERT(stream_obj->xlator != NULL);
 		(void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i],
 					   usize);
 		if (ap_buffer[i] == NULL) {
@@ -156,8 +149,6 @@ int strm_close(struct strm_res_object *strmres,
 	int status = 0;
 	struct strm_object *stream_obj = strmres->stream;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!stream_obj) {
 		status = -EFAULT;
 	} else {
@@ -167,7 +158,6 @@ int strm_close(struct strm_res_object *strmres,
 		status =
 		    (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj,
 						     &chnl_info_obj);
-		DBC_ASSERT(!status);
 
 		if (chnl_info_obj.cio_cs > 0 || chnl_info_obj.cio_reqs > 0)
 			status = -EPIPE;
@@ -180,9 +170,6 @@ int strm_close(struct strm_res_object *strmres,
 
 	idr_remove(pr_ctxt->stream_id, strmres->id);
 func_end:
-	DBC_ENSURE(status == 0 || status == -EFAULT ||
-		   status == -EPIPE || status == -EPERM);
-
 	dev_dbg(bridge, "%s: stream_obj: %p, status 0x%x\n", __func__,
 		stream_obj, status);
 	return status;
@@ -199,10 +186,6 @@ int strm_create(struct strm_mgr **strm_man,
 	struct strm_mgr *strm_mgr_obj;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(strm_man != NULL);
-	DBC_REQUIRE(dev_obj != NULL);
-
 	*strm_man = NULL;
 	/* Allocate STRM manager object */
 	strm_mgr_obj = kzalloc(sizeof(struct strm_mgr), GFP_KERNEL);
@@ -217,7 +200,6 @@ int strm_create(struct strm_mgr **strm_man,
 		if (!status) {
 			(void)dev_get_intf_fxns(dev_obj,
 						&(strm_mgr_obj->intf_fxns));
-			DBC_ASSERT(strm_mgr_obj->intf_fxns != NULL);
 		}
 	}
 
@@ -226,8 +208,6 @@ int strm_create(struct strm_mgr **strm_man,
 	else
 		kfree(strm_mgr_obj);
 
-	DBC_ENSURE((!status && *strm_man) || (status && *strm_man == NULL));
-
 	return status;
 }
 
@@ -238,9 +218,6 @@ int strm_create(struct strm_mgr **strm_man,
  */
 void strm_delete(struct strm_mgr *strm_mgr_obj)
 {
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(strm_mgr_obj);
-
 	kfree(strm_mgr_obj);
 }
 
@@ -251,11 +228,7 @@ void strm_delete(struct strm_mgr *strm_mgr_obj)
  */
 void strm_exit(void)
 {
-	DBC_REQUIRE(refs > 0);
-
 	refs--;
-
-	DBC_ENSURE(refs >= 0);
 }
 
 /*
@@ -270,15 +243,11 @@ int strm_free_buffer(struct strm_res_object *strmres, u8 ** ap_buffer,
 	u32 i = 0;
 	struct strm_object *stream_obj = strmres->stream;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(ap_buffer != NULL);
-
 	if (!stream_obj)
 		status = -EFAULT;
 
 	if (!status) {
 		for (i = 0; i < num_bufs; i++) {
-			DBC_ASSERT(stream_obj->xlator != NULL);
 			status =
 			    cmm_xlator_free_buf(stream_obj->xlator,
 						ap_buffer[i]);
@@ -306,10 +275,6 @@ int strm_get_info(struct strm_object *stream_obj,
 	int status = 0;
 	void *virt_base = NULL;	/* NULL if no SM used */
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(stream_info != NULL);
-	DBC_REQUIRE(stream_info_size >= sizeof(struct stream_info));
-
 	if (!stream_obj) {
 		status = -EFAULT;
 	} else {
@@ -330,7 +295,6 @@ int strm_get_info(struct strm_object *stream_obj,
 
 	if (stream_obj->xlator) {
 		/* We have a translator */
-		DBC_ASSERT(stream_obj->segment_id > 0);
 		cmm_xlator_info(stream_obj->xlator, (u8 **) &virt_base, 0,
 				stream_obj->segment_id, false);
 	}
@@ -370,8 +334,6 @@ int strm_idle(struct strm_object *stream_obj, bool flush_data)
 	struct bridge_drv_interface *intf_fxns;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-
 	if (!stream_obj) {
 		status = -EFAULT;
 	} else {
@@ -396,13 +358,9 @@ bool strm_init(void)
 {
 	bool ret = true;
 
-	DBC_REQUIRE(refs >= 0);
-
 	if (ret)
 		refs++;
 
-	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));
-
 	return ret;
 }
 
@@ -418,9 +376,6 @@ int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes,
 	int status = 0;
 	void *tmp_buf = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(pbuf != NULL);
-
 	if (!stream_obj) {
 		status = -EFAULT;
 	} else {
@@ -471,9 +426,6 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index,
 
 	void *stream_res;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(strmres != NULL);
-	DBC_REQUIRE(pattr != NULL);
 	*strmres = NULL;
 	if (dir != DSP_TONODE && dir != DSP_FROMNODE) {
 		status = -EPERM;
@@ -536,14 +488,12 @@ int strm_open(struct node_object *hnode, u32 dir, u32 index,
 		goto func_cont;
 
 	/* No System DMA */
-	DBC_ASSERT(strm_obj->strm_mode != STRMMODE_LDMA);
 	/* Get the shared mem mgr for this streams dev object */
 	status = dev_get_cmm_mgr(strm_mgr_obj->dev_obj, &hcmm_mgr);
 	if (!status) {
 		/*Allocate a SM addr translator for this strm. */
 		status = cmm_xlator_create(&strm_obj->xlator, hcmm_mgr, NULL);
 		if (!status) {
-			DBC_ASSERT(strm_obj->segment_id > 0);
 			/*  Set translators Virt Addr attributes */
 			status = cmm_xlator_info(strm_obj->xlator,
 						 (u8 **) &pattr->virt_base,
@@ -575,10 +525,6 @@ func_cont:
 				 * strm_mgr_obj->chnl_mgr better be valid or we
 				 * assert here), and then return -EPERM.
 				 */
-				DBC_ASSERT(status == -ENOSR ||
-					   status == -ECHRNG ||
-					   status == -EALREADY ||
-					   status == -EIO);
 				status = -EPERM;
 			}
 		}
@@ -594,12 +540,6 @@ func_cont:
 		(void)delete_strm(strm_obj);
 	}
 
-	/* ensure we return a documented error code */
-	DBC_ENSURE((!status && strm_obj) ||
-		   (*strmres == NULL && (status == -EFAULT ||
-					status == -EPERM
-					|| status == -EINVAL)));
-
 	dev_dbg(bridge, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p "
 		"strmres: %p status: 0x%x\n", __func__,
 		hnode, dir, index, pattr, strmres, status);
@@ -619,11 +559,6 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr,
 	int status = 0;
 	void *tmp_buf = NULL;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(buf_ptr != NULL);
-	DBC_REQUIRE(nbytes != NULL);
-	DBC_REQUIRE(pdw_arg != NULL);
-
 	if (!stream_obj) {
 		status = -EFAULT;
 		goto func_end;
@@ -679,11 +614,6 @@ int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr,
 		*buf_ptr = chnl_ioc_obj.buf;
 	}
 func_end:
-	/* ensure we return a documented return code */
-	DBC_ENSURE(!status || status == -EFAULT ||
-		   status == -ETIME || status == -ESRCH ||
-		   status == -EPERM);
-
 	dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p "
 		"pdw_arg: %p status 0x%x\n", __func__, stream_obj,
 		buf_ptr, nbytes, pdw_arg, status);
@@ -702,9 +632,6 @@ int strm_register_notify(struct strm_object *stream_obj, u32 event_mask,
 	struct bridge_drv_interface *intf_fxns;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(hnotification != NULL);
-
 	if (!stream_obj) {
 		status = -EFAULT;
 	} else if ((event_mask & ~((DSP_STREAMIOCOMPLETION) |
@@ -725,10 +652,7 @@ int strm_register_notify(struct strm_object *stream_obj, u32 event_mask,
 							    notify_type,
 							    hnotification);
 	}
-	/* ensure we return a documented return code */
-	DBC_ENSURE(!status || status == -EFAULT ||
-		   status == -ETIME || status == -ESRCH ||
-		   status == -ENOSYS || status == -EPERM);
+
 	return status;
 }
 
@@ -747,11 +671,6 @@ int strm_select(struct strm_object **strm_tab, u32 strms,
 	u32 i;
 	int status = 0;
 
-	DBC_REQUIRE(refs > 0);
-	DBC_REQUIRE(strm_tab != NULL);
-	DBC_REQUIRE(pmask != NULL);
-	DBC_REQUIRE(strms > 0);
-
 	*pmask = 0;
 	for (i = 0; i < strms; i++) {
 		if (!strm_tab[i]) {
@@ -811,9 +730,6 @@ int strm_select(struct strm_object **strm_tab, u32 strms,
 func_end:
 	kfree(sync_events);
 
-	DBC_ENSURE((!status && (*pmask != 0 || utimeout == 0)) ||
-		   (status && *pmask == 0));
-
 	return status;
 }
 
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h
index d407368..a73e437 100644
--- a/drivers/staging/usbip/stub.h
+++ b/drivers/staging/usbip/stub.h
@@ -35,7 +35,6 @@
 struct stub_device {
 	struct usb_interface *interface;
 	struct usb_device *udev;
-	struct list_head list;
 
 	struct usbip_device ud;
 	__u32 devid;
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 27ac363..1d5b3fc 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -367,15 +367,6 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir)
 	}
 
 	epd = &ep->desc;
-#if 0
-	/* epnum 0 is always control */
-	if (epnum == 0) {
-		if (dir == USBIP_DIR_OUT)
-			return usb_sndctrlpipe(udev, 0);
-		else
-			return usb_rcvctrlpipe(udev, 0);
-	}
-#endif
 	if (usb_endpoint_xfer_control(epd)) {
 		if (dir == USBIP_DIR_OUT)
 			return usb_sndctrlpipe(udev, epnum);
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index d93e7f1..70f23026 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -735,26 +735,25 @@ EXPORT_SYMBOL_GPL(usbip_recv_iso);
  * buffer and iso packets need to be stored and be in propeper endian in urb
  * before calling this function
  */
-int usbip_pad_iso(struct usbip_device *ud, struct urb *urb)
+void usbip_pad_iso(struct usbip_device *ud, struct urb *urb)
 {
 	int np = urb->number_of_packets;
 	int i;
-	int ret;
 	int actualoffset = urb->actual_length;
 
 	if (!usb_pipeisoc(urb->pipe))
-		return 0;
+		return;
 
 	/* if no packets or length of data is 0, then nothing to unpack */
 	if (np == 0 || urb->actual_length == 0)
-		return 0;
+		return;
 
 	/*
 	 * if actual_length is transfer_buffer_length then no padding is
 	 * present.
 	*/
 	if (urb->actual_length == urb->transfer_buffer_length)
-		return 0;
+		return;
 
 	/*
 	 * loop over all packets from last to first (to prevent overwritting
@@ -766,8 +765,6 @@ int usbip_pad_iso(struct usbip_device *ud, struct urb *urb)
 			urb->transfer_buffer + actualoffset,
 			urb->iso_frame_desc[i].actual_length);
 	}
-
-	return ret;
 }
 EXPORT_SYMBOL_GPL(usbip_pad_iso);
 
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index b8f8c48..c7b888c 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -306,7 +306,7 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send);
 void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
 /* some members of urb must be substituted before. */
 int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
-int usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
+void usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
 int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
 
 /* usbip_event.c */
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index 2ee97e2..8d96ab0 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -386,29 +386,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 				dum->port_status[rhport] |=
 					USB_PORT_STAT_ENABLE;
 			}
-#if 0
-			if (dum->driver) {
-				dum->port_status[rhport] |=
-					USB_PORT_STAT_ENABLE;
-				/* give it the best speed we agree on */
-				dum->gadget.speed = dum->driver->speed;
-				dum->gadget.ep0->maxpacket = 64;
-				switch (dum->gadget.speed) {
-				case USB_SPEED_HIGH:
-					dum->port_status[rhport] |=
-						USB_PORT_STAT_HIGH_SPEED;
-					break;
-				case USB_SPEED_LOW:
-					dum->gadget.ep0->maxpacket = 8;
-					dum->port_status[rhport] |=
-						USB_PORT_STAT_LOW_SPEED;
-					break;
-				default:
-					dum->gadget.speed = USB_SPEED_FULL;
-					break;
-				}
-			}
-#endif
 		}
 		((u16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]);
 		((u16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16);
@@ -425,15 +402,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		case USB_PORT_FEAT_SUSPEND:
 			usbip_dbg_vhci_rh(" SetPortFeature: "
 					  "USB_PORT_FEAT_SUSPEND\n");
-#if 0
-			dum->port_status[rhport] |=
-				(1 << USB_PORT_FEAT_SUSPEND);
-			if (dum->driver->suspend) {
-				spin_unlock(&dum->lock);
-				dum->driver->suspend(&dum->gadget);
-				spin_lock(&dum->lock);
-			}
-#endif
 			break;
 		case USB_PORT_FEAT_RESET:
 			usbip_dbg_vhci_rh(" SetPortFeature: "
@@ -444,13 +412,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 					~(USB_PORT_STAT_ENABLE |
 					  USB_PORT_STAT_LOW_SPEED |
 					  USB_PORT_STAT_HIGH_SPEED);
-#if 0
-				if (dum->driver) {
-					dev_dbg(hardware, "disconnect\n");
-					stop_activity(dum, dum->driver);
-				}
-#endif
-
 				/* FIXME test that code path! */
 			}
 			/* 50msec reset signaling */
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index 3f511b4..f5fba732 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -94,8 +94,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 		return;
 
 	/* restore the padding in iso packets */
-	if (usbip_pad_iso(ud, urb) < 0)
-		return;
+	usbip_pad_iso(ud, urb);
 
 	if (usbip_dbg_flag_vhci_rx)
 		usbip_dump_urb(urb);
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
index 9d38cee..c9d65bf 100644
--- a/drivers/staging/vme/vme.h
+++ b/drivers/staging/vme/vme.h
@@ -156,7 +156,7 @@ int vme_irq_request(struct vme_dev *, int, int,
 void vme_irq_free(struct vme_dev *, int, int);
 int vme_irq_generate(struct vme_dev *, int, int);
 
-struct vme_resource * vme_lm_request(struct vme_dev *);
+struct vme_resource *vme_lm_request(struct vme_dev *);
 int vme_lm_count(struct vme_resource *);
 int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32);
 int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *);
diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c
index 7fd5cc5..ef197ef 100644
--- a/drivers/staging/vt6655/ioctl.c
+++ b/drivers/staging/vt6655/ioctl.c
@@ -324,16 +324,16 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
 				pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
 				memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1);
 				memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len);
-				if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
+				if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo))
 					pList->sBSSIDList[ii].byNetType = INFRA;
-				} else {
+				else
 					pList->sBSSIDList[ii].byNetType = ADHOC;
-				}
-				if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
+
+				if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo))
 					pList->sBSSIDList[ii].bWEPOn = true;
-				} else {
+				else
 					pList->sBSSIDList[ii].bWEPOn = false;
-				}
+
 				ii++;
 				if (ii >= pList->uItem)
 					break;
@@ -367,9 +367,9 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
 		netif_stop_queue(pDevice->dev);
 
 		spin_lock_irq(&pDevice->lock);
-		if (pDevice->bRadioOff == false) {
+		if (pDevice->bRadioOff == false)
 			CARDbRadioPowerOff(pDevice);
-		}
+
 		pDevice->bLinkPass = false;
 		memset(pMgmt->abyCurrBSSID, 0, 6);
 		pMgmt->eCurrState = WMAC_STATE_IDLE;
@@ -489,13 +489,12 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq)
 			break;
 		}
 
-		if (sStartAPCmd.wBBPType == PHY80211g) {
+		if (sStartAPCmd.wBBPType == PHY80211g)
 			pMgmt->byAPBBType = PHY_TYPE_11G;
-		} else if (sStartAPCmd.wBBPType == PHY80211a) {
+		else if (sStartAPCmd.wBBPType == PHY80211a)
 			pMgmt->byAPBBType = PHY_TYPE_11A;
-		} else {
+		else
 			pMgmt->byAPBBType = PHY_TYPE_11B;
-		}
 
 		pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid;
 		if (pItemSSID->len > WLAN_SSID_MAXLEN + 1)
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
index ecfda52..b24e531 100644
--- a/drivers/staging/vt6656/iwctl.c
+++ b/drivers/staging/vt6656/iwctl.c
@@ -46,9 +46,6 @@
 
 #include <net/iw_handler.h>
 
-
-/*---------------------  Static Definitions -------------------------*/
-
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 #define SUPPORTED_WIRELESS_EXT                  18
 #else
@@ -63,19 +60,8 @@ static const long frequency_list[] = {
     5700, 5745, 5765, 5785, 5805, 5825
 	};
 
-
-/*---------------------  Static Classes  ----------------------------*/
-
-
-//static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
 
-
-/*---------------------  Static Variables  --------------------------*/
-/*---------------------  Static Functions  --------------------------*/
-
-/*---------------------  Export Variables  --------------------------*/
-
 struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
 {
 	PSDevice pDevice = netdev_priv(dev);
@@ -87,7 +73,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
                pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
 	RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
 	pDevice->wstats.qual.level = ldBm;
-	//pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
 	pDevice->wstats.qual.noise = 0;
 	pDevice->wstats.qual.updated = 1;
 	pDevice->wstats.discard.nwid = 0;
@@ -100,21 +85,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
 	return &pDevice->wstats;
 }
 
-
-
-/*------------------------------------------------------------------*/
-
-
-static int iwctl_commit(struct net_device *dev,
-			      struct iw_request_info *info,
-			      void *wrq,
-			      char *extra)
-{
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n");
-
-	return 0;
-}
-
 /*
  * Wireless Handler : get protocol name
  */
@@ -197,14 +167,12 @@ if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
  }
 
 	 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
-         //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n");
 	bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
 	spin_unlock_irq(&pDevice->lock);
 
 	return 0;
 }
 
-
 /*
  * Wireless Handler : get scan results
  */
@@ -503,7 +471,7 @@ int iwctl_siwmode(struct net_device *dev,
  * Wireless Handler : get operation mode
  */
 
-int iwctl_giwmode(struct net_device *dev,
+void iwctl_giwmode(struct net_device *dev,
              struct iw_request_info *info,
              __u32 *wmode,
              char *extra)
@@ -530,8 +498,6 @@ int iwctl_giwmode(struct net_device *dev,
 	default:
 		*wmode = IW_MODE_ADHOC;
 	}
-
-	return 0;
 }
 
 
@@ -539,7 +505,7 @@ int iwctl_giwmode(struct net_device *dev,
  * Wireless Handler : get capability range
  */
 
-int iwctl_giwrange(struct net_device *dev,
+void iwctl_giwrange(struct net_device *dev,
              struct iw_request_info *info,
              struct iw_point *wrq,
              char *extra)
@@ -634,9 +600,6 @@ int iwctl_giwrange(struct net_device *dev,
 		range->avg_qual.level = 176;	// -80 dBm
 		range->avg_qual.noise = 0;
 	}
-
-
-	return 0;
 }
 
 
@@ -708,9 +671,7 @@ int iwctl_giwap(struct net_device *dev,
 
     memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
 
-//20080123-02,<Modify> by Einsn Liu
  if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
- //   if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA))
         memset(wrq->sa_data, 0, 6);
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
@@ -895,8 +856,7 @@ int iwctl_siwessid(struct net_device *dev,
 /*
  * Wireless Handler : get essid
  */
-
-int iwctl_giwessid(struct net_device *dev,
+void iwctl_giwessid(struct net_device *dev,
              struct iw_request_info *info,
              struct iw_point *wrq,
              char *extra)
@@ -913,14 +873,11 @@ int iwctl_giwessid(struct net_device *dev,
 
 	// Get the current SSID
     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-	//pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
 	memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
 	extra[pItemSSID->len] = '\0';
 
         wrq->length = pItemSSID->len;
 	wrq->flags = 1; // active
-
-	return 0;
 }
 
 /*
@@ -1008,8 +965,7 @@ int iwctl_siwrate(struct net_device *dev,
 /*
  * Wireless Handler : get data rate
  */
-
-int iwctl_giwrate(struct net_device *dev,
+void iwctl_giwrate(struct net_device *dev,
              struct iw_request_info *info,
              struct iw_param *wrq,
              char *extra)
@@ -1047,9 +1003,6 @@ int iwctl_giwrate(struct net_device *dev,
 	    if (pDevice->bFixRate == TRUE)
 	        wrq->fixed = TRUE;
     }
-
-
-	return 0;
 }
 
 
@@ -1057,27 +1010,19 @@ int iwctl_giwrate(struct net_device *dev,
 /*
  * Wireless Handler : set rts threshold
  */
-
 int iwctl_siwrts(struct net_device *dev,
-             struct iw_request_info *info,
-			 struct iw_param *wrq,
-             char *extra)
+		 struct iw_param *wrq)
 {
-	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
-	int rc = 0;
+	PSDevice pDevice = (PSDevice)netdev_priv(dev);
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
+	if ((wrq->value < 0 || wrq->value > 2312) && !wrq->disabled)
+		return -EINVAL;
 
-	{
-	    int rthr = wrq->value;
-	    if(wrq->disabled)
-			rthr = 2312;
-	    if((rthr < 0) || (rthr > 2312)) {
-			rc = -EINVAL;
-    	}else {
-		    pDevice->wRTSThreshold = rthr;
-	    }
-    }
+	else if (wrq->disabled)
+		pDevice->wRTSThreshold = 2312;
+
+	else
+		pDevice->wRTSThreshold = wrq->value;
 
 	return 0;
 }
@@ -1327,55 +1272,6 @@ int iwctl_siwencode(struct net_device *dev,
 	return rc;
 }
 
-/*
- * Wireless Handler : get encode mode
- */
-//2008-0409-06, <Mark> by Einsn Liu
- /*
-int iwctl_giwencode(struct net_device *dev,
-             struct iw_request_info *info,
-             struct iw_point *wrq,
-             char *extra)
-{
-    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
-    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
-    int rc = 0;
-    char abyKey[WLAN_WEP232_KEYLEN];
-	unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX);
-	PSKeyItem   pKey = NULL;
-
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
-
-
-	memset(abyKey, 0, sizeof(abyKey));
-	// Check encryption mode
-	wrq->flags = IW_ENCODE_NOKEY;
-	// Is WEP enabled ???
-	if (pDevice->bEncryptionEnable)
-		wrq->flags |=  IW_ENCODE_ENABLED;
-    else
-		wrq->flags |=  IW_ENCODE_DISABLED;
-
-    if (pMgmt->bShareKeyAlgorithm)
-		wrq->flags |=  IW_ENCODE_RESTRICTED;
-	else
-		wrq->flags |=  IW_ENCODE_OPEN;
-
-	if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
-        wrq->length = pKey->uKeyLength;
-        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
-    }
-    else {
-        rc = -EINVAL;
-        return rc;
-    }
-	wrq->flags |= index;
-	// Copy the key to the user buffer
-	memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
-	return 0;
-}
-*/
-
 int iwctl_giwencode(struct net_device *dev,
 			struct iw_request_info *info,
 			struct iw_point *wrq,
@@ -1562,7 +1458,6 @@ int iwctl_siwauth(struct net_device *dev,
 		wpa_version = wrq->value;
 		if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
 		       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
-			//pDevice->bWPADEVUp = FALSE;
 		}
 		else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
                           PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
@@ -1570,7 +1465,6 @@ int iwctl_siwauth(struct net_device *dev,
 		else {
                           PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
 		}
-		//pDevice->bWPASuppWextEnabled =TRUE;
 		break;
 	case IW_AUTH_CIPHER_PAIRWISE:
 		pairwise = wrq->value;
@@ -1627,11 +1521,6 @@ int iwctl_siwauth(struct net_device *dev,
 		}
 		break;
 	case IW_AUTH_WPA_ENABLED:
-		//pDevice->bWPADEVUp = !! wrq->value;
-		//if(pDevice->bWPADEVUp==TRUE)
-		  // printk("iwctl_siwauth:set WPADEV to enable successful*******\n");
-		//else
-		 //  printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
 		break;
 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
 		break;
@@ -1646,7 +1535,6 @@ int iwctl_siwauth(struct net_device *dev,
 			pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
 			pMgmt->bShareKeyAlgorithm = FALSE;
 			pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
-			//pDevice->bWPADEVUp = FALSE;
 			 PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
 		}
 
@@ -1655,15 +1543,6 @@ int iwctl_siwauth(struct net_device *dev,
 		ret = -EOPNOTSUPP;
 		break;
 	}
-/*
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
-	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE");
-*/
    return ret;
 }
 
@@ -1752,8 +1631,6 @@ int iwctl_siwencodeext(struct net_device *dev,
     u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
     u8 key[64];
     size_t seq_len=0,key_len=0;
-//
-   // int ii;
     u8 *buf;
     size_t blen;
     u8 key_array[64];
@@ -1883,7 +1760,6 @@ int iwctl_siwmlme(struct net_device *dev,
 	PSDevice			pDevice = (PSDevice)netdev_priv(dev);
 	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
-	//u16 reason = cpu_to_le16(mlme->reason_code);
 	int ret = 0;
 
 	if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
@@ -1892,12 +1768,6 @@ int iwctl_siwmlme(struct net_device *dev,
 	}
 	switch(mlme->cmd){
 	case IW_MLME_DEAUTH:
-		//this command seems to be not complete,please test it --einsnliu
-		//printk("iwctl_siwmlme--->send DEAUTH\n");
-		/* bScheduleCommand((void *) pDevice,
-		   WLAN_CMD_DEAUTH,
-		   (PBYTE)&reason); */
-		//break;
 	case IW_MLME_DISASSOC:
 		if(pDevice->bLinkPass == TRUE){
 		  PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
@@ -1916,77 +1786,9 @@ int iwctl_siwmlme(struct net_device *dev,
 
 #endif
 
-/*------------------------------------------------------------------*/
-/*
- * Structures to export the Wireless Handlers
- */
-
-
-/*
-static const iw_handler		iwctl_handler[] =
-{
-	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
-	(iw_handler) iwctl_giwname,     // SIOCGIWNAME
-	(iw_handler) NULL,				// SIOCSIWNWID
-	(iw_handler) iwctl_siwfreq,		// SIOCSIWFREQ
-	(iw_handler) iwctl_giwfreq,		// SIOCGIWFREQ
-	(iw_handler) iwctl_siwmode,		// SIOCSIWMODE
-	(iw_handler) iwctl_giwmode,		// SIOCGIWMODE
-	(iw_handler) NULL,		        // SIOCSIWSENS
-	(iw_handler) iwctl_giwsens,		        // SIOCGIWSENS
-	(iw_handler) NULL, 		        // SIOCSIWRANGE
-	(iw_handler) iwctl_giwrange,		// SIOCGIWRANGE
-	(iw_handler) NULL,         		    // SIOCSIWPRIV
-	(iw_handler) NULL,             		// SIOCGIWPRIV
-	(iw_handler) NULL,             		// SIOCSIWSTATS
-	(iw_handler) NULL,                  // SIOCGIWSTATS
-    (iw_handler) NULL,                  // SIOCSIWSPY
-	(iw_handler) NULL,		            // SIOCGIWSPY
-	(iw_handler) NULL,				    // -- hole --
-	(iw_handler) NULL,				    // -- hole --
-	(iw_handler) iwctl_siwap,		    // SIOCSIWAP
-	(iw_handler) iwctl_giwap,		    // SIOCGIWAP
-	(iw_handler) NULL,				    // -- hole -- 0x16
-	(iw_handler) iwctl_giwaplist,       // SIOCGIWAPLIST
-	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
-	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
-	(iw_handler) iwctl_siwessid,		// SIOCSIWESSID
-	(iw_handler) iwctl_giwessid,		// SIOCGIWESSID
-	(iw_handler) NULL,		// SIOCSIWNICKN
-	(iw_handler) NULL,		// SIOCGIWNICKN
-	(iw_handler) NULL,				    // -- hole --
-	(iw_handler) NULL,				    // -- hole --
-	(iw_handler) iwctl_siwrate,		// SIOCSIWRATE 0x20
-	(iw_handler) iwctl_giwrate,		// SIOCGIWRATE
-	(iw_handler) iwctl_siwrts,		// SIOCSIWRTS
-	(iw_handler) iwctl_giwrts,		// SIOCGIWRTS
-	(iw_handler) iwctl_siwfrag,		// SIOCSIWFRAG
-	(iw_handler) iwctl_giwfrag,		// SIOCGIWFRAG
-	(iw_handler) NULL,		// SIOCSIWTXPOW
-	(iw_handler) NULL,		// SIOCGIWTXPOW
-	(iw_handler) iwctl_siwretry,		// SIOCSIWRETRY
-	(iw_handler) iwctl_giwretry,		// SIOCGIWRETRY
-	(iw_handler) iwctl_siwencode,		// SIOCSIWENCODE
-	(iw_handler) iwctl_giwencode,		// SIOCGIWENCODE
-	(iw_handler) iwctl_siwpower,		// SIOCSIWPOWER
-	(iw_handler) iwctl_giwpower,		// SIOCGIWPOWER
-	(iw_handler) NULL,			// -- hole --
-	(iw_handler) NULL,			// -- hole --
-	(iw_handler) iwctl_siwgenie,    // SIOCSIWGENIE
-	(iw_handler) iwctl_giwgenie,    // SIOCGIWGENIE
-	(iw_handler) iwctl_siwauth,		// SIOCSIWAUTH
-	(iw_handler) iwctl_giwauth,		// SIOCGIWAUTH
-	(iw_handler) iwctl_siwencodeext,		// SIOCSIWENCODEEXT
-	(iw_handler) iwctl_giwencodeext,		// SIOCGIWENCODEEXT
-	(iw_handler) NULL,				// SIOCSIWPMKSA
-	(iw_handler) NULL,				// -- hole --
-
-};
-*/
-
 static const iw_handler		iwctl_handler[] =
 {
-	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
+	(iw_handler) NULL,      /* SIOCSIWCOMMIT */
 	(iw_handler) NULL,      // SIOCGIWNAME
 	(iw_handler) NULL,				// SIOCSIWNWID
 	(iw_handler) NULL,				// SIOCGIWNWID
@@ -2063,13 +1865,9 @@ const struct iw_handler_def	iwctl_handler_def =
 {
 	.get_wireless_stats = &iwctl_get_wireless_stats,
 	.num_standard	= sizeof(iwctl_handler)/sizeof(iw_handler),
-//	.num_private	= sizeof(iwctl_private_handler)/sizeof(iw_handler),
-//	.num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
 	.num_private	= 0,
 	.num_private_args = 0,
 	.standard	= (iw_handler *) iwctl_handler,
-//	.private	= (iw_handler *) iwctl_private_handler,
-//	.private_args	= (struct iw_priv_args *)iwctl_private_args,
 	.private	= NULL,
 	.private_args	= NULL,
 };
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
index 10a240e..0c6e049 100644
--- a/drivers/staging/vt6656/iwctl.h
+++ b/drivers/staging/vt6656/iwctl.h
@@ -46,13 +46,13 @@ int iwctl_siwap(struct net_device *dev,
 			 struct sockaddr *wrq,
              char *extra);
 
-int iwctl_giwrange(struct net_device *dev,
+void iwctl_giwrange(struct net_device *dev,
              struct iw_request_info *info,
              struct iw_point *wrq,
              char *extra);
 
 
-int iwctl_giwmode(struct net_device *dev,
+void iwctl_giwmode(struct net_device *dev,
              struct iw_request_info *info,
              __u32 *wmode,
              char *extra);
@@ -97,7 +97,7 @@ int iwctl_siwessid(struct net_device *dev,
              struct iw_point *wrq,
              char *extra);
 
-int iwctl_giwessid(struct net_device *dev,
+void iwctl_giwessid(struct net_device *dev,
              struct iw_request_info *info,
              struct iw_point *wrq,
              char *extra);
@@ -107,16 +107,13 @@ int iwctl_siwrate(struct net_device *dev,
 			 struct iw_param *wrq,
              char *extra);
 
-int iwctl_giwrate(struct net_device *dev,
+void iwctl_giwrate(struct net_device *dev,
              struct iw_request_info *info,
              struct iw_param *wrq,
              char *extra);
 
 int iwctl_siwrts(struct net_device *dev,
-             struct iw_request_info *info,
-			 struct iw_param *wrq,
-             char *extra);
-
+		 struct iw_param *wrq);
 
 int iwctl_giwrts(struct net_device *dev,
              struct iw_request_info *info,
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 6a708f4..763e028 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -1657,8 +1657,8 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		{
 			char essid[IW_ESSID_MAX_SIZE+1];
 			if (wrq->u.essid.pointer) {
-				rc = iwctl_giwessid(dev, NULL,
-						    &(wrq->u.essid), essid);
+				iwctl_giwessid(dev, NULL,
+					    &(wrq->u.essid), essid);
 				if (copy_to_user(wrq->u.essid.pointer,
 						         essid,
 						         wrq->u.essid.length) )
@@ -1698,14 +1698,13 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 
 	// Get the current bit-rate
 	case SIOCGIWRATE:
-
-		rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
+		iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
 		break;
 
 	// Set the desired RTS threshold
 	case SIOCSIWRTS:
 
-		rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
+		rc = iwctl_siwrts(dev, &(wrq->u.rts));
 		break;
 
 	// Get the current RTS threshold
@@ -1733,7 +1732,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 
 		// Get mode of operation
 	case SIOCGIWMODE:
-		rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
+		iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
 		break;
 
 		// Set WEP keys and mode
@@ -1811,7 +1810,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		{
 			struct iw_range range;
 
-			rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
+			iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
 			if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
 				rc = -EFAULT;
 		}
diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c
index 2fa4f84..5435e82 100644
--- a/drivers/staging/vt6656/wpactl.c
+++ b/drivers/staging/vt6656/wpactl.c
@@ -46,23 +46,18 @@
 
 #define VIAWGET_WPA_MAX_BUF_SIZE 1024
 
-
-
 static const int frequency_list[] = {
 	2412, 2417, 2422, 2427, 2432, 2437, 2442,
 	2447, 2452, 2457, 2462, 2467, 2472, 2484
 };
+
 /*---------------------  Static Classes  ----------------------------*/
 
 /*---------------------  Static Variables  --------------------------*/
-//static int          msglevel                =MSG_LEVEL_DEBUG;
-static int          msglevel                =MSG_LEVEL_INFO;
+static int msglevel = MSG_LEVEL_INFO;
 
 /*---------------------  Static Functions  --------------------------*/
 
-
-
-
 /*---------------------  Export Variables  --------------------------*/
 static void wpadev_setup(struct net_device *dev)
 {
@@ -72,9 +67,9 @@ static void wpadev_setup(struct net_device *dev)
 	dev->addr_len           = ETH_ALEN;
 	dev->tx_queue_len       = 1000;
 
-	memset(dev->broadcast,0xFF, ETH_ALEN);
+	memset(dev->broadcast, 0xFF, ETH_ALEN);
 
-	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
+	dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
 }
 
 /*
@@ -90,45 +85,43 @@ static void wpadev_setup(struct net_device *dev)
  * Return Value:
  *
  */
-
 static int wpa_init_wpadev(PSDevice pDevice)
 {
-    PSDevice wpadev_priv;
+	PSDevice wpadev_priv;
 	struct net_device *dev = pDevice->dev;
-         int ret=0;
+	int ret = 0;
 
 	pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
 	if (pDevice->wpadev == NULL)
 		return -ENOMEM;
 
-    wpadev_priv = netdev_priv(pDevice->wpadev);
-    *wpadev_priv = *pDevice;
+	wpadev_priv = netdev_priv(pDevice->wpadev);
+	*wpadev_priv = *pDevice;
 	memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, ETH_ALEN);
-         pDevice->wpadev->base_addr = dev->base_addr;
+	pDevice->wpadev->base_addr = dev->base_addr;
 	pDevice->wpadev->irq = dev->irq;
 	pDevice->wpadev->mem_start = dev->mem_start;
 	pDevice->wpadev->mem_end = dev->mem_end;
 	ret = register_netdev(pDevice->wpadev);
 	if (ret) {
 		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
-		       dev->name);
+			dev->name);
 		free_netdev(pDevice->wpadev);
 		return -1;
 	}
 
 	if (pDevice->skb == NULL) {
-        pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-        if (pDevice->skb == NULL)
-		    return -ENOMEM;
-    }
+		pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+		if (pDevice->skb == NULL)
+			return -ENOMEM;
+	}
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
-	       dev->name, pDevice->wpadev->name);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
+		dev->name, pDevice->wpadev->name);
 
 	return 0;
 }
 
-
 /*
  * Description:
  *      unregister net_device (wpadev)
@@ -141,29 +134,24 @@ static int wpa_init_wpadev(PSDevice pDevice)
  * Return Value:
  *
  */
-
 static int wpa_release_wpadev(PSDevice pDevice)
 {
-    if (pDevice->skb) {
-        dev_kfree_skb(pDevice->skb);
-        pDevice->skb = NULL;
-    }
+	if (pDevice->skb) {
+		dev_kfree_skb(pDevice->skb);
+		pDevice->skb = NULL;
+	}
 
-    if (pDevice->wpadev) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
-	       pDevice->dev->name, pDevice->wpadev->name);
-	unregister_netdev(pDevice->wpadev);
-	free_netdev(pDevice->wpadev);
-         pDevice->wpadev = NULL;
-    }
+	if (pDevice->wpadev) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+			pDevice->dev->name, pDevice->wpadev->name);
+		unregister_netdev(pDevice->wpadev);
+		free_netdev(pDevice->wpadev);
+		pDevice->wpadev = NULL;
+	}
 
 	return 0;
 }
 
-
-
-
-
 /*
  * Description:
  *      Set enable/disable dev for wpa supplicant deamon
@@ -177,13 +165,11 @@ static int wpa_release_wpadev(PSDevice pDevice)
  * Return Value:
  *
  */
-
 int wpa_set_wpadev(PSDevice pDevice, int val)
 {
 	if (val)
 		return wpa_init_wpadev(pDevice);
-	else
-		return wpa_release_wpadev(pDevice);
+	return wpa_release_wpadev(pDevice);
 }
 
 /*
@@ -199,245 +185,217 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
  * Return Value:
  *
  */
-
  int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
 {
-    struct viawget_wpa_param *param=ctx;
-    PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
-    DWORD   dwKeyIndex = 0;
-    BYTE    abyKey[MAX_KEY_LEN];
-    BYTE    abySeq[MAX_KEY_LEN];
-    QWORD   KeyRSC;
-//    NDIS_802_11_KEY_RSC KeyRSC;
-    BYTE    byKeyDecMode = KEY_CTL_WEP;
+	struct viawget_wpa_param *param = ctx;
+	PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+	DWORD dwKeyIndex = 0;
+	BYTE abyKey[MAX_KEY_LEN];
+	BYTE abySeq[MAX_KEY_LEN];
+	QWORD KeyRSC;
+	BYTE byKeyDecMode = KEY_CTL_WEP;
 	int ret = 0;
-	int uu, ii;
-
+	int uu;
+	int ii;
 
 	if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
 		return -EINVAL;
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n",
+		param->u.wpa_key.alg_name);
 	if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
-        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-        pDevice->bEncryptionEnable = FALSE;
-        pDevice->byKeyIndex = 0;
-        pDevice->bTransmitKey = FALSE;
-        for (uu=0; uu<MAX_KEY_TABLE; uu++) {
-            MACvDisableKeyEntry(pDevice, uu);
-        }
-        return ret;
-    }
+		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+		pDevice->bEncryptionEnable = FALSE;
+		pDevice->byKeyIndex = 0;
+		pDevice->bTransmitKey = FALSE;
+		for (uu=0; uu<MAX_KEY_TABLE; uu++) {
+			MACvDisableKeyEntry(pDevice, uu);
+		}
+		return ret;
+	}
 
 	if (param->u.wpa_key.key && param->u.wpa_key.key_len > sizeof(abyKey))
 		return -EINVAL;
 
-    spin_unlock_irq(&pDevice->lock);
-    if(param->u.wpa_key.key && fcpfkernel) {
-       memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
-     }
-    else {
-	if (param->u.wpa_key.key &&
-	    copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) {
-	    spin_lock_irq(&pDevice->lock);
-	    return -EINVAL;
+	spin_unlock_irq(&pDevice->lock);
+	if (param->u.wpa_key.key && fcpfkernel) {
+		memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
+	} else {
+		if (param->u.wpa_key.key &&
+			copy_from_user(&abyKey[0], param->u.wpa_key.key,
+				param->u.wpa_key.key_len)) {
+			spin_lock_irq(&pDevice->lock);
+			return -EINVAL;
+		}
 	}
-     }
-    spin_lock_irq(&pDevice->lock);
+	spin_lock_irq(&pDevice->lock);
 
-    dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
+	dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
 
 	if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
-        if (dwKeyIndex > 3) {
-            return -EINVAL;
-        }
-        else {
-            if (param->u.wpa_key.set_tx) {
-                pDevice->byKeyIndex = (BYTE)dwKeyIndex;
-                pDevice->bTransmitKey = TRUE;
-		        dwKeyIndex |= (1 << 31);
-            }
-            KeybSetDefaultKey(  pDevice,
-                                &(pDevice->sKey),
-                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
-                                param->u.wpa_key.key_len,
-                                NULL,
-                                abyKey,
-                                KEY_CTL_WEP
-                              );
-
-        }
-        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-        pDevice->bEncryptionEnable = TRUE;
-        return ret;
+		if (dwKeyIndex > 3) {
+			return -EINVAL;
+		} else {
+			if (param->u.wpa_key.set_tx) {
+				pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+				pDevice->bTransmitKey = TRUE;
+				dwKeyIndex |= (1 << 31);
+			}
+			KeybSetDefaultKey(  pDevice,
+					&(pDevice->sKey),
+					dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+					param->u.wpa_key.key_len,
+					NULL,
+					abyKey,
+					KEY_CTL_WEP
+				);
+
+		}
+		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+		pDevice->bEncryptionEnable = TRUE;
+		return ret;
 	}
 
 
 	if (param->u.wpa_key.seq && param->u.wpa_key.seq_len > sizeof(abySeq))
 		return -EINVAL;
 
-    spin_unlock_irq(&pDevice->lock);
-        if(param->u.wpa_key.seq && fcpfkernel) {
-           memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
-        	}
-       else {
-	if (param->u.wpa_key.seq &&
-	    copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) {
-	    spin_lock_irq(&pDevice->lock);
-	    return -EINVAL;
-	}
+	spin_unlock_irq(&pDevice->lock);
+        if (param->u.wpa_key.seq && fcpfkernel) {
+		memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
+	} else {
+		if (param->u.wpa_key.seq &&
+			copy_from_user(&abySeq[0], param->u.wpa_key.seq,
+				param->u.wpa_key.seq_len)) {
+			spin_lock_irq(&pDevice->lock);
+			return -EINVAL;
+		}
 	}
 	spin_lock_irq(&pDevice->lock);
 
 	if (param->u.wpa_key.seq_len > 0) {
 		for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
-		     if (ii < 4)
-			    LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
-			 else
-			    HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
-	         //KeyRSC |= (abySeq[ii] << (ii * 8));
+			if (ii < 4)
+				LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
+			else
+				HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
 		}
 		dwKeyIndex |= 1 << 29;
 	}
 
-    if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
-        return -EINVAL;
-    }
+	if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
+		return -EINVAL;
+	}
 
 	if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
-        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
-    }
+		pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+	}
 
 	if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
-        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
-    }
+		pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+	}
 
 	if (param->u.wpa_key.set_tx)
 		dwKeyIndex |= (1 << 31);
 
 
-    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
-        byKeyDecMode = KEY_CTL_CCMP;
-    else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
-        byKeyDecMode = KEY_CTL_TKIP;
-    else
-        byKeyDecMode = KEY_CTL_WEP;
-
-    // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
-    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
-        if (param->u.wpa_key.key_len == MAX_KEY_LEN)
-            byKeyDecMode = KEY_CTL_TKIP;
-        else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
-            byKeyDecMode = KEY_CTL_WEP;
-        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
-            byKeyDecMode = KEY_CTL_WEP;
-    } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
-        if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
-            byKeyDecMode = KEY_CTL_WEP;
-        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
-            byKeyDecMode = KEY_CTL_WEP;
-    }
-
-    // Check TKIP key length
-    if ((byKeyDecMode == KEY_CTL_TKIP) &&
-        (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
-        // TKIP Key must be 256 bits
-        //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
-        return -EINVAL;
-    }
-    // Check AES key length
-    if ((byKeyDecMode == KEY_CTL_CCMP) &&
-        (param->u.wpa_key.key_len != AES_KEY_LEN)) {
-        // AES Key must be 128 bits
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
-        return -EINVAL;
-    }
+	if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
+		byKeyDecMode = KEY_CTL_CCMP;
+	else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
+		byKeyDecMode = KEY_CTL_TKIP;
+	else
+		byKeyDecMode = KEY_CTL_WEP;
+
+	// Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
+	if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+		if (param->u.wpa_key.key_len == MAX_KEY_LEN)
+			byKeyDecMode = KEY_CTL_TKIP;
+		else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
+			byKeyDecMode = KEY_CTL_WEP;
+		else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
+			byKeyDecMode = KEY_CTL_WEP;
+	} else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+		if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
+			byKeyDecMode = KEY_CTL_WEP;
+		else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
+			byKeyDecMode = KEY_CTL_WEP;
+	}
 
-    if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
-	/* if broadcast, set the key as every key entry's group key */
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
-
-        if ((KeybSetAllGroupKey(pDevice,
-                            &(pDevice->sKey),
-                            dwKeyIndex,
-                            param->u.wpa_key.key_len,
-                            (PQWORD) &(KeyRSC),
-                            (PBYTE)abyKey,
-                            byKeyDecMode
-                            ) == TRUE) &&
-            (KeybSetDefaultKey(pDevice,
-                            &(pDevice->sKey),
-                            dwKeyIndex,
-                            param->u.wpa_key.key_len,
-                            (PQWORD) &(KeyRSC),
-                            (PBYTE)abyKey,
-                            byKeyDecMode
-                            ) == TRUE) ) {
-             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
-
-        } else {
-            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
-            return -EINVAL;
-        }
-
-    } else {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
-        // BSSID not 0xffffffffffff
-        // Pairwise Key can't be WEP
-        if (byKeyDecMode == KEY_CTL_WEP) {
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
-            return -EINVAL;
-        }
-
-        dwKeyIndex |= (1 << 30); // set pairwise key
-        if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
-            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
-            return -EINVAL;
-        }
-        if (KeybSetKey(pDevice,
-                       &(pDevice->sKey),
-                       &param->addr[0],
-                       dwKeyIndex,
-                       param->u.wpa_key.key_len,
-                       (PQWORD) &(KeyRSC),
-                       (PBYTE)abyKey,
-                        byKeyDecMode
-                       ) == TRUE) {
-            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
-
-        } else {
-            // Key Table Full
-	    if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
-                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
-                return -EINVAL;
-
-            } else {
-                // Save Key and configure just before associate/reassociate to BSSID
-                // we do not implement now
-                return -EINVAL;
-            }
-        }
-    } // BSSID not 0xffffffffffff
-    if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
-        pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index;
-        pDevice->bTransmitKey = TRUE;
+	// Check TKIP key length
+	if ((byKeyDecMode == KEY_CTL_TKIP) &&
+		(param->u.wpa_key.key_len != MAX_KEY_LEN)) {
+		// TKIP Key must be 256 bits
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
+		return -EINVAL;
     }
-    pDevice->bEncryptionEnable = TRUE;
+	// Check AES key length
+	if ((byKeyDecMode == KEY_CTL_CCMP) &&
+		(param->u.wpa_key.key_len != AES_KEY_LEN)) {
+		// AES Key must be 128 bits
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
+		return -EINVAL;
+	}
 
-/*
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
-               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
-               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
-               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
-               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3],
-               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4]
-              );
-*/
+	if (is_broadcast_ether_addr(&param->addr[0]) || (param->addr == NULL)) {
+		/* if broadcast, set the key as every key entry's group key */
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
+
+		if ((KeybSetAllGroupKey(pDevice, &(pDevice->sKey), dwKeyIndex,
+							param->u.wpa_key.key_len,
+							(PQWORD) &(KeyRSC),
+							(PBYTE)abyKey,
+							byKeyDecMode
+					) == TRUE) &&
+			(KeybSetDefaultKey(pDevice,
+					&(pDevice->sKey),
+					dwKeyIndex,
+					param->u.wpa_key.key_len,
+					(PQWORD) &(KeyRSC),
+					(PBYTE)abyKey,
+					byKeyDecMode
+				) == TRUE) ) {
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
+		// BSSID not 0xffffffffffff
+		// Pairwise Key can't be WEP
+		if (byKeyDecMode == KEY_CTL_WEP) {
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
+			return -EINVAL;
+		}
+		dwKeyIndex |= (1 << 30); // set pairwise key
+		if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+			//DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
+			return -EINVAL;
+		}
+		if (KeybSetKey(pDevice, &(pDevice->sKey), &param->addr[0],
+				dwKeyIndex, param->u.wpa_key.key_len,
+				(PQWORD) &(KeyRSC), (PBYTE)abyKey, byKeyDecMode
+				) == TRUE) {
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
+		} else {
+			// Key Table Full
+			if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
+				//DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
+				return -EINVAL;
+			} else {
+				// Save Key and configure just before associate/reassociate to BSSID
+				// we do not implement now
+				return -EINVAL;
+			}
+		}
+	} // BSSID not 0xffffffffffff
+	if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
+		pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index;
+		pDevice->bTransmitKey = TRUE;
+	}
+	pDevice->bEncryptionEnable = TRUE;
 
 	return ret;
-
 }
 
 
@@ -454,23 +412,17 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
  * Return Value:
  *
  */
-
-static int wpa_set_wpa(PSDevice pDevice,
-				     struct viawget_wpa_param *param)
+static int wpa_set_wpa(PSDevice pDevice, struct viawget_wpa_param *param)
 {
-
-    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	PSMgmtObject pMgmt = &pDevice->sMgmtObj;
 	int ret = 0;
 
-    pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
-    pMgmt->bShareKeyAlgorithm = FALSE;
+	pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+	pMgmt->bShareKeyAlgorithm = FALSE;
 
-    return ret;
+	return ret;
 }
 
-
-
-
  /*
  * Description:
  *      set disassociate
@@ -484,25 +436,21 @@ static int wpa_set_wpa(PSDevice pDevice,
  * Return Value:
  *
  */
-
-static int wpa_set_disassociate(PSDevice pDevice,
-				     struct viawget_wpa_param *param)
+static int wpa_set_disassociate(PSDevice pDevice, struct viawget_wpa_param *param)
 {
-    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	PSMgmtObject pMgmt = &pDevice->sMgmtObj;
 	int ret = 0;
 
-    spin_lock_irq(&pDevice->lock);
-    if (pDevice->bLinkPass) {
-        if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
-		bScheduleCommand((void *) pDevice, WLAN_CMD_DISASSOCIATE, NULL);
-    }
-    spin_unlock_irq(&pDevice->lock);
+	spin_lock_irq(&pDevice->lock);
+	if (pDevice->bLinkPass) {
+		if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
+			bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+	}
+	spin_unlock_irq(&pDevice->lock);
 
-    return ret;
+	return ret;
 }
 
-
-
 /*
  * Description:
  *      enable scan process
@@ -516,36 +464,30 @@ static int wpa_set_disassociate(PSDevice pDevice,
  * Return Value:
  *
  */
-
-static int wpa_set_scan(PSDevice pDevice,
-			struct viawget_wpa_param *param)
+static int wpa_set_scan(PSDevice pDevice, struct viawget_wpa_param *param)
 {
 	int ret = 0;
 
 /**set ap_scan=1&&scan_ssid=1 under hidden ssid mode**/
-        PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
-        PWLAN_IE_SSID       pItemSSID;
-printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n",
-	     param->u.scan_req.ssid,param->u.scan_req.ssid_len);
+        PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+        PWLAN_IE_SSID pItemSSID;
+	printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n",
+		param->u.scan_req.ssid,param->u.scan_req.ssid_len);
 // Set the SSID
-memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
-pItemSSID->byElementID = WLAN_EID_SSID;
-memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len);
-pItemSSID->len = param->u.scan_req.ssid_len;
-
-    spin_lock_irq(&pDevice->lock);
-    BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
-    /* bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, NULL); */
-    bScheduleCommand((void *) pDevice,
-		     WLAN_CMD_BSSID_SCAN,
-		     pMgmt->abyDesireSSID);
-    spin_unlock_irq(&pDevice->lock);
-
-    return ret;
-}
+	memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+	pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+	pItemSSID->byElementID = WLAN_EID_SSID;
+	memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len);
+	pItemSSID->len = param->u.scan_req.ssid_len;
 
+	spin_lock_irq(&pDevice->lock);
+	BSSvClearBSSList((void *) pDevice, pDevice->bLinkPass);
+	bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN,
+			pMgmt->abyDesireSSID);
+	spin_unlock_irq(&pDevice->lock);
 
+	return ret;
+}
 
 /*
  * Description:
@@ -560,19 +502,15 @@ pItemSSID->len = param->u.scan_req.ssid_len;
  * Return Value:
  *
  */
-
-static int wpa_get_bssid(PSDevice pDevice,
-				     struct viawget_wpa_param *param)
+static int wpa_get_bssid(PSDevice pDevice, struct viawget_wpa_param *param)
 {
-    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
-	int ret = 0;
-	memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6);
+    PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+    int ret = 0;
+    memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID, 6);
 
     return ret;
-
 }
 
-
 /*
  * Description:
  *      get bssid
@@ -586,24 +524,20 @@ static int wpa_get_bssid(PSDevice pDevice,
  * Return Value:
  *
  */
-
-static int wpa_get_ssid(PSDevice pDevice,
-				     struct viawget_wpa_param *param)
+static int wpa_get_ssid(PSDevice pDevice, struct viawget_wpa_param *param)
 {
-    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
-	PWLAN_IE_SSID       pItemSSID;
+	PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+	PWLAN_IE_SSID pItemSSID;
 	int ret = 0;
 
-    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+	pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
 
-	memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len);
+	memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID, pItemSSID->len);
 	param->u.wpa_associate.ssid_len = pItemSSID->len;
 
-    return ret;
+	return ret;
 }
 
-
-
 /*
  * Description:
  *      get scan results
@@ -617,135 +551,114 @@ static int wpa_get_ssid(PSDevice pDevice,
  * Return Value:
  *
  */
-
-static int wpa_get_scan(PSDevice pDevice,
-				     struct viawget_wpa_param *param)
+static int wpa_get_scan(PSDevice pDevice, struct viawget_wpa_param *param)
 {
 	struct viawget_scan_result *scan_buf;
-    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
-    PWLAN_IE_SSID   pItemSSID;
-    PKnownBSS pBSS;
-	PBYTE  pBuf;
+	PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+	PWLAN_IE_SSID pItemSSID;
+	PKnownBSS pBSS;
+	PBYTE pBuf;
 	int ret = 0;
 	u16 count = 0;
-	u16 ii, jj;
-	long ldBm;//James //add
+	u16 ii;
+	u16 jj;
+	long ldBm; //James //add
 
 //******mike:bubble sort by stronger RSSI*****//
+	PBYTE ptempBSS;
 
-    PBYTE ptempBSS;
-
+	ptempBSS = kmalloc(sizeof(KnownBSS), GFP_ATOMIC);
 
+	if (ptempBSS == NULL) {
+		printk("bubble sort kmalloc memory fail@@@\n");
+		ret = -ENOMEM;
+		return ret;
+	}
 
-    ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);
-
-    if (ptempBSS == NULL) {
-
-       printk("bubble sort kmalloc memory fail@@@\n");
-
-        ret = -ENOMEM;
-
-        return ret;
-
-    }
-
-    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-
-	for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) {
-
-		if ((pMgmt->sBSSList[jj].bActive != TRUE) ||
-
-                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) {
-
-                 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));
-
-                 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));
-
-                 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));
-
-              }
-
-         }
-
-    }
-
-  kfree(ptempBSS);
-
- // printk("bubble sort result:\n");
+	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+		for (jj = 0; jj < MAX_BSS_NUM - ii - 1; jj++) {
+			if ((pMgmt->sBSSList[jj].bActive != TRUE)
+				|| ((pMgmt->sBSSList[jj].uRSSI > pMgmt->sBSSList[jj + 1].uRSSI)
+					&& (pMgmt->sBSSList[jj + 1].bActive != FALSE))) {
+				memcpy(ptempBSS,&pMgmt->sBSSList[jj], sizeof(KnownBSS));
+				memcpy(&pMgmt->sBSSList[jj], &pMgmt->sBSSList[jj + 1],
+					sizeof(KnownBSS));
+				memcpy(&pMgmt->sBSSList[jj + 1], ptempBSS, sizeof(KnownBSS));
+			}
+		}
+	}
+	kfree(ptempBSS);
 
 	count = 0;
 	pBSS = &(pMgmt->sBSSList[0]);
-    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
-        pBSS = &(pMgmt->sBSSList[ii]);
-        if (!pBSS->bActive)
-            continue;
-        count++;
-    }
+	for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+		pBSS = &(pMgmt->sBSSList[ii]);
+		if (!pBSS->bActive)
+			continue;
+		count++;
+	}
 
-    pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);
+	pBuf = kcalloc(count, sizeof(struct viawget_scan_result), GFP_ATOMIC);
 
-    if (pBuf == NULL) {
-        ret = -ENOMEM;
-        return ret;
-    }
-    scan_buf = (struct viawget_scan_result *)pBuf;
+	if (pBuf == NULL) {
+		ret = -ENOMEM;
+		return ret;
+	}
+	scan_buf = (struct viawget_scan_result *)pBuf;
 	pBSS = &(pMgmt->sBSSList[0]);
-    for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
-        pBSS = &(pMgmt->sBSSList[ii]);
-        if (pBSS->bActive) {
-            if (jj >= count)
-                break;
-            memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
-            pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
-   		    memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
-   		    scan_buf->ssid_len = pItemSSID->len;
-            scan_buf->freq = frequency_list[pBSS->uChannel-1];
-            scan_buf->caps = pBSS->wCapInfo;    //DavidWang for sharemode
-
-	        RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
-			if(-ldBm<50){
+	for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) {
+		pBSS = &(pMgmt->sBSSList[ii]);
+		if (pBSS->bActive) {
+			if (jj >= count)
+				break;
+			memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
+			pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+			memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
+			scan_buf->ssid_len = pItemSSID->len;
+			scan_buf->freq = frequency_list[pBSS->uChannel-1];
+			scan_buf->caps = pBSS->wCapInfo; // DavidWang for sharemode
+
+			RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+			if (-ldBm < 50)
 				scan_buf->qual = 100;
-			}else  if(-ldBm > 90) {
-				 scan_buf->qual = 0;
-			}else {
+			else if (-ldBm > 90)
+				scan_buf->qual = 0;
+			else
 				scan_buf->qual=(40-(-ldBm-50))*100/40;
-			}
 
 			//James
-            //scan_buf->caps = pBSS->wCapInfo;
-            //scan_buf->qual =
-            scan_buf->noise = 0;
-            scan_buf->level = ldBm;
-
-            //scan_buf->maxrate =
-            if (pBSS->wWPALen != 0) {
-                scan_buf->wpa_ie_len = pBSS->wWPALen;
-                memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
-            }
-            if (pBSS->wRSNLen != 0) {
-                scan_buf->rsn_ie_len = pBSS->wRSNLen;
-                memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
-            }
-            scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
-            jj ++;
-        }
-    }
+			//scan_buf->caps = pBSS->wCapInfo;
+			//scan_buf->qual =
+			scan_buf->noise = 0;
+			scan_buf->level = ldBm;
+
+			//scan_buf->maxrate =
+			if (pBSS->wWPALen != 0) {
+				scan_buf->wpa_ie_len = pBSS->wWPALen;
+				memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
+			}
+			if (pBSS->wRSNLen != 0) {
+				scan_buf->rsn_ie_len = pBSS->wRSNLen;
+				memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
+			}
+			scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
+			jj ++;
+		}
+	}
 
-    if (jj < count)
-        count = jj;
+	if (jj < count)
+		count = jj;
 
-    if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
+	if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count))
 		ret = -EFAULT;
-	}
+
 	param->u.scan_results.scan_count = count;
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count);
 
-    kfree(pBuf);
-    return ret;
+	kfree(pBuf);
+	return ret;
 }
 
-
-
 /*
  * Description:
  *      set associate with AP
@@ -759,25 +672,23 @@ static int wpa_get_scan(PSDevice pDevice,
  * Return Value:
  *
  */
-
-static int wpa_set_associate(PSDevice pDevice,
-				     struct viawget_wpa_param *param)
+static int wpa_set_associate(PSDevice pDevice, struct viawget_wpa_param *param)
 {
-    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
-    PWLAN_IE_SSID   pItemSSID;
-    BYTE    abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-    BYTE    abyWPAIE[64];
-    int ret = 0;
-    BOOL   bwepEnabled=FALSE;
+	PSMgmtObject pMgmt = &pDevice->sMgmtObj;
+	PWLAN_IE_SSID pItemSSID;
+	BYTE abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+	BYTE abyWPAIE[64];
+	int ret = 0;
+	BOOL bwepEnabled=FALSE;
 
 	// set key type & algorithm
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm);  //Davidwang
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm); // Davidwang
 
 	if (param->u.wpa_associate.wpa_ie) {
 		if (param->u.wpa_associate.wpa_ie_len > sizeof(abyWPAIE))
@@ -789,25 +700,25 @@ static int wpa_set_associate(PSDevice pDevice,
 	}
 
 	if (param->u.wpa_associate.mode == 1)
-	    pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+		pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
 	else
-	    pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+		pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
 
 	// set bssid
-    if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
-        memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
-    // set ssid
+	if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
+		memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
+	// set ssid
 	memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
-    pItemSSID->byElementID = WLAN_EID_SSID;
+	pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+	pItemSSID->byElementID = WLAN_EID_SSID;
 	pItemSSID->len = param->u.wpa_associate.ssid_len;
 	memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
 
-    if (param->u.wpa_associate.wpa_ie_len == 0) {
-	    if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
-            pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
-	    else
-            pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+	if (param->u.wpa_associate.wpa_ie_len == 0) {
+		if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
+			pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
+		else
+			pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
 	} else if (abyWPAIE[0] == RSN_INFO_ELEM) {
 		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
 			pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
@@ -817,9 +728,9 @@ static int wpa_set_associate(PSDevice pDevice,
 		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
 			pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
 		else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
-		    pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+			pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
 		else
-		    pMgmt->eAuthenMode = WMAC_AUTH_WPA;
+			pMgmt->eAuthenMode = WMAC_AUTH_WPA;
 	}
 
 	switch (param->u.wpa_associate.pairwise_suite) {
@@ -833,7 +744,6 @@ static int wpa_set_associate(PSDevice pDevice,
 	case CIPHER_WEP104:
 		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
 		bwepEnabled = TRUE;
-	//	printk("****************wpa_set_associate:set CIPHER_WEP40_104\n");
 		break;
 	case CIPHER_NONE:
 		if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
@@ -845,70 +755,64 @@ static int wpa_set_associate(PSDevice pDevice,
 		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
 	}
 
-           pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm;
-         // if ((pMgmt->Roam_dbm > 40)&&(pMgmt->Roam_dbm<80))
-         //    pDevice->bEnableRoaming = TRUE;
-
-	    if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {   //@wep-sharekey
-            pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-            pMgmt->bShareKeyAlgorithm = TRUE;
-             }
-	    else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
-	       if(bwepEnabled==TRUE) {                                                         //@open-wep
-                       pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
-	   	}
-	      else {                                                                                                 //@only open
-            pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+	pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm;
+	if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) { // @wep-sharekey
+		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+		pMgmt->bShareKeyAlgorithm = TRUE;
+	} else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
+		if(bwepEnabled==TRUE) { //@open-wep
+			pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+	   	} else {
+			// @only open
+			pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
 	   	}
-           }
-//mike save old encryption status
+	}
+	// mike save old encryption status
 	pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
 
-    if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
-        pDevice->bEncryptionEnable = TRUE;
-    else
-        pDevice->bEncryptionEnable = FALSE;
-
- if ((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
-      ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bwepEnabled==TRUE)))  {
- //mike re-comment:open-wep && sharekey-wep needn't do initial key!!
-
-     }
- else
-    KeyvInitTable(pDevice,&pDevice->sKey);
+	if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
+		pDevice->bEncryptionEnable = TRUE;
+	else
+		pDevice->bEncryptionEnable = FALSE;
 
-    spin_lock_irq(&pDevice->lock);
-    pDevice->bLinkPass = FALSE;
-    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
-    memset(pMgmt->abyCurrBSSID, 0, 6);
-    pMgmt->eCurrState = WMAC_STATE_IDLE;
-    netif_stop_queue(pDevice->dev);
+	if ((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
+		((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bwepEnabled==TRUE)))  {
+		// mike re-comment:open-wep && sharekey-wep needn't do initial key!!
+	} else {
+		KeyvInitTable(pDevice,&pDevice->sKey);
+	}
 
-/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
-{
-   PKnownBSS       pCurr = NULL;
-    pCurr = BSSpSearchBSSList(pDevice,
-                              pMgmt->abyDesireBSSID,
-                              pMgmt->abyDesireSSID,
-                              pDevice->eConfigPHYMode
-                              );
-
-    if (pCurr == NULL){
-    printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
-    bScheduleCommand((void *) pDevice,
-		     WLAN_CMD_BSSID_SCAN,
-		     pMgmt->abyDesireSSID);
-  }
-}
+	spin_lock_irq(&pDevice->lock);
+	pDevice->bLinkPass = FALSE;
+	ControlvMaskByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PAPEDELAY, LEDSTS_STS, LEDSTS_SLOW);
+	memset(pMgmt->abyCurrBSSID, 0, 6);
+	pMgmt->eCurrState = WMAC_STATE_IDLE;
+	netif_stop_queue(pDevice->dev);
+
+/******* search if ap_scan=2, which is associating request in hidden ssid mode ****/
+	{
+		PKnownBSS pCurr = NULL;
+		pCurr = BSSpSearchBSSList(pDevice,
+					pMgmt->abyDesireBSSID,
+					pMgmt->abyDesireSSID,
+					pDevice->eConfigPHYMode
+			);
+
+		if (pCurr == NULL){
+			printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
+			bScheduleCommand((void *)pDevice,
+					WLAN_CMD_BSSID_SCAN,
+					pMgmt->abyDesireSSID);
+		}
+	}
 /****************************************************************/
 
-    bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
-    spin_unlock_irq(&pDevice->lock);
+	bScheduleCommand((void *)pDevice, WLAN_CMD_SSID, NULL);
+	spin_unlock_irq(&pDevice->lock);
 
-    return ret;
+	return ret;
 }
 
-
 /*
  * Description:
  *      wpa_ioctl main function supported for wpa supplicant
@@ -922,7 +826,6 @@ static int wpa_set_associate(PSDevice pDevice,
  * Return Value:
  *
  */
-
 int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
 {
 	struct viawget_wpa_param *param;
@@ -930,10 +833,10 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
 	int wpa_ioctl = 0;
 
 	if (p->length < sizeof(struct viawget_wpa_param) ||
-	    p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
+		p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
 		return -EINVAL;
 
-	param = kmalloc((int)p->length, (int)GFP_KERNEL);
+	param = kmalloc((int)p->length, GFP_KERNEL);
 	if (param == NULL)
 		return -ENOMEM;
 
@@ -944,63 +847,63 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
 
 	switch (param->cmd) {
 	case VIAWGET_SET_WPA:
-        ret = wpa_set_wpa(pDevice, param);
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
+		ret = wpa_set_wpa(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
 		break;
 
 	case VIAWGET_SET_KEY:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
-	    spin_lock_irq(&pDevice->lock);
-        ret = wpa_set_keys(pDevice, param, FALSE);
-        spin_unlock_irq(&pDevice->lock);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
+		spin_lock_irq(&pDevice->lock);
+		ret = wpa_set_keys(pDevice, param, FALSE);
+		spin_unlock_irq(&pDevice->lock);
 		break;
 
 	case VIAWGET_SET_SCAN:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
-        ret = wpa_set_scan(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
+		ret = wpa_set_scan(pDevice, param);
 		break;
 
 	case VIAWGET_GET_SCAN:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
-        ret = wpa_get_scan(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
+		ret = wpa_get_scan(pDevice, param);
 		wpa_ioctl = 1;
 		break;
 
 	case VIAWGET_GET_SSID:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
-        ret = wpa_get_ssid(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
+		ret = wpa_get_ssid(pDevice, param);
 		wpa_ioctl = 1;
 		break;
 
 	case VIAWGET_GET_BSSID:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
-        ret = wpa_get_bssid(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
+		ret = wpa_get_bssid(pDevice, param);
 		wpa_ioctl = 1;
 		break;
 
 	case VIAWGET_SET_ASSOCIATE:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
-        ret = wpa_set_associate(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
+		ret = wpa_set_associate(pDevice, param);
 		break;
 
 	case VIAWGET_SET_DISASSOCIATE:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
-        ret = wpa_set_disassociate(pDevice, param);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
+		ret = wpa_set_disassociate(pDevice, param);
 		break;
 
 	case VIAWGET_SET_DROP_UNENCRYPT:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
 		break;
 
-    case VIAWGET_SET_DEAUTHENTICATE:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
+	case VIAWGET_SET_DEAUTHENTICATE:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
 		break;
 
 	default:
-	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
-		       param->cmd);
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
+			param->cmd);
+		kfree(param);
 		return -EOPNOTSUPP;
-		break;
 	}
 
 	if ((ret == 0) && wpa_ioctl) {
@@ -1012,7 +915,5 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
 
 out:
 	kfree(param);
-
 	return ret;
 }
-
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index 6675c82..c3bb05d 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -406,6 +406,7 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
 	/* SSID */
 	req->ssid.status = P80211ENUM_msgitem_status_data_ok;
 	req->ssid.data.len = le16_to_cpu(item->ssid.len);
+	req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_BSSID_LEN);
 	memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
 
 	/* supported rates */
diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h
index 35f7b2a..e828fd4 100644
--- a/drivers/staging/xgifb/XGI_main.h
+++ b/drivers/staging/xgifb/XGI_main.h
@@ -7,47 +7,32 @@
 
 #include "XGIfb.h"
 #include "vb_struct.h"
+#include "../../video/sis/sis.h"
 #include "vb_def.h"
 
 #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
 
-#ifndef PCI_VENDOR_ID_XG
-#define PCI_VENDOR_ID_XG          0x18CA
+#ifndef PCI_DEVICE_ID_XGI_41
+#define PCI_DEVICE_ID_XGI_41      0x041
 #endif
-
-#ifndef PCI_DEVICE_ID_XG_40
-#define PCI_DEVICE_ID_XG_40      0x040
-#endif
-#ifndef PCI_DEVICE_ID_XG_41
-#define PCI_DEVICE_ID_XG_41      0x041
-#endif
-#ifndef PCI_DEVICE_ID_XG_42
-#define PCI_DEVICE_ID_XG_42      0x042
+#ifndef PCI_DEVICE_ID_XGI_42
+#define PCI_DEVICE_ID_XGI_42      0x042
 #endif
-#ifndef PCI_DEVICE_ID_XG_20
-#define PCI_DEVICE_ID_XG_20      0x020
-#endif
-#ifndef PCI_DEVICE_ID_XG_27
-#define PCI_DEVICE_ID_XG_27      0x027
+#ifndef PCI_DEVICE_ID_XGI_27
+#define PCI_DEVICE_ID_XGI_27      0x027
 #endif
 
 static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = {
-	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20)},
-	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27)},
-	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40)},
-	{PCI_DEVICE(PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_20)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_27)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_40)},
+	{PCI_DEVICE(PCI_VENDOR_ID_XGI, PCI_DEVICE_ID_XGI_42)},
 	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
 
 /* To be included in fb.h */
-#ifndef FB_ACCEL_XGI_XABRE
-#define FB_ACCEL_XGI_XABRE      41	/* XGI 330 ("Xabre")		*/
-#endif
-
-#define SEQ_DATA                  0x15
-
 #define XGISR			  (xgifb_info->dev_info.P3c4)
 #define XGICR			  (xgifb_info->dev_info.P3d4)
 #define XGIDACA			  (xgifb_info->dev_info.P3c8)
@@ -60,12 +45,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
 #define XGIDAC2A                  XGIPART5
 #define XGIDAC2D                  (XGIPART5 + 1)
 
-#define IND_XGI_PASSWORD          0x05  /* SRs */
-#define IND_XGI_RAMDAC_CONTROL    0x07
-#define IND_XGI_DRAM_SIZE         0x14
-#define IND_XGI_MODULE_ENABLE     0x1E
-#define IND_XGI_PCI_ADDRESS_SET   0x20
-
 #define IND_XGI_SCRATCH_REG_CR30  0x30  /* CRs */
 #define IND_XGI_SCRATCH_REG_CR31  0x31
 #define IND_XGI_SCRATCH_REG_CR32  0x32
@@ -73,10 +52,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
 #define IND_XGI_LCD_PANEL         0x36
 #define IND_XGI_SCRATCH_REG_CR37  0x37
 
-#define IND_XGI_CRT2_WRITE_ENABLE_315 0x2F
-
-#define XGI_PASSWORD              0x86  /* SR05 */
-
 #define XGI_DRAM_SIZE_MASK     0xF0  /*SR14 */
 #define XGI_DRAM_SIZE_1MB      0x00
 #define XGI_DRAM_SIZE_2MB      0x01
@@ -88,37 +63,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
 #define XGI_DRAM_SIZE_128MB    0x07
 #define XGI_DRAM_SIZE_256MB    0x08
 
-#define XGI_ENABLE_2D             0x40  /* SR1E */
-
-#define XGI_MEM_MAP_IO_ENABLE     0x01  /* SR20 */
-#define XGI_PCI_ADDR_ENABLE       0x80
-
-#define XGI_SIMULTANEOUS_VIEW_ENABLE  0x01  /* CR30 */
-#define XGI_VB_OUTPUT_COMPOSITE   0x04
-#define XGI_VB_OUTPUT_SVIDEO      0x08
-#define XGI_VB_OUTPUT_SCART       0x10
-#define XGI_VB_OUTPUT_LCD         0x20
-#define XGI_VB_OUTPUT_CRT2        0x40
-#define XGI_VB_OUTPUT_HIVISION    0x80
-
-#define XGI_VB_OUTPUT_DISABLE     0x20  /* CR31 */
-#define XGI_DRIVER_MODE           0x40
-
-#define XGI_VB_COMPOSITE          0x01  /* CR32 */
-#define XGI_VB_SVIDEO             0x02
-#define XGI_VB_SCART              0x04
-#define XGI_VB_LCD                0x08
-#define XGI_VB_CRT2               0x10
-#define XGI_CRT1                  0x20
-#define XGI_VB_HIVISION           0x40
-#define XGI_VB_YPBPR              0x80
-#define XGI_VB_TV		  (XGI_VB_COMPOSITE | XGI_VB_SVIDEO | \
-				   XGI_VB_SCART | XGI_VB_HIVISION|XGI_VB_YPBPR)
-
-#define XGI_EXTERNAL_CHIP_MASK		   0x0E  /* CR37 */
-#define XGI310_EXTERNAL_CHIP_LVDS          0x02  /* in CR37 << 1 ! */
-#define XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03  /* in CR37 << 1 ! */
-
 /* ------------------- Global Variables ----------------------------- */
 
 /* display status */
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 2502c49..21c0378 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -4,6 +4,8 @@
  * Base on TW's sis fbdev code.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 /* #include <linux/config.h> */
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -55,7 +57,7 @@ static unsigned int refresh_rate;
 #undef XGIFBDEBUG
 
 #ifdef XGIFBDEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#define DPRINTK(fmt, args...) pr_debug("%s: " fmt, __func__ , ## args)
 #else
 #define DPRINTK(fmt, args...)
 #endif
@@ -142,7 +144,7 @@ static inline void dumpVGAReg(void)
 #if 1
 #define DEBUGPRN(x)
 #else
-#define DEBUGPRN(x) printk(KERN_INFO x "\n");
+#define DEBUGPRN(x) pr_info(x "\n");
 #endif
 
 /* --------------- Hardware Access Routines -------------------------- */
@@ -369,15 +371,15 @@ static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
 	XGI_Pr->P3c9 = BaseAddr + 0x19;
 	XGI_Pr->P3da = BaseAddr + 0x2A;
 	/* Digital video interface registers (LCD) */
-	XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
+	XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04;
 	/* 301 TV Encoder registers */
-	XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
+	XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10;
 	/* 301 Macrovision registers */
-	XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
+	XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12;
 	/* 301 VGA2 (and LCD) registers */
-	XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
+	XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14;
 	/* 301 palette address port registers */
-	XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
+	XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
 
 }
 
@@ -424,7 +426,7 @@ static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info,
 		i++;
 	}
 	if (!j)
-		printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
+		pr_info("Invalid mode '%s'\n", name);
 }
 
 static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
@@ -449,7 +451,7 @@ static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
 
 invalid:
 	if (!j)
-		printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
+		pr_info("Invalid VESA mode 0x%x'\n", vesamode);
 }
 
 static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
@@ -526,12 +528,6 @@ static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
 			xres = 1600;
 			yres = 1200;
 			break;
-		/* case LCD_320x480: */ /* TW: FSTN */
-			/*
-			xres =  320;
-			yres =  480;
-			break;
-			*/
 		default:
 			xres = 0;
 			yres = 0;
@@ -692,7 +688,7 @@ static void XGIfb_search_crt2type(const char *name)
 		i++;
 	}
 	if (XGIfb_crt2type < 0)
-		printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
+		pr_info("Invalid CRT2 type: %s\n", name);
 }
 
 static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
@@ -742,7 +738,7 @@ static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
 	if (xgifb_info->rate_idx > 0) {
 		return xgifb_info->rate_idx;
 	} else {
-		printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
+		pr_info("Unsupported rate %d for %dx%d\n",
 		       rate, xres, yres);
 		return 0;
 	}
@@ -811,27 +807,27 @@ static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
 
 	switch (xgifb_info->display2) {
 	case XGIFB_DISP_CRT:
-		cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= XGI_DRIVER_MODE;
+		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= SIS_DRIVER_MODE;
 		break;
 	case XGIFB_DISP_LCD:
-		cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= XGI_DRIVER_MODE;
+		cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= SIS_DRIVER_MODE;
 		break;
 	case XGIFB_DISP_TV:
 		if (xgifb_info->TV_type == TVMODE_HIVISION)
-			cr30 = (XGI_VB_OUTPUT_HIVISION
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_HIVISION
+					| SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
-			cr30 = (XGI_VB_OUTPUT_SVIDEO
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_SVIDEO
+					| SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
-			cr30 = (XGI_VB_OUTPUT_COMPOSITE
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+			cr30 = (SIS_VB_OUTPUT_COMPOSITE
+					| SIS_SIMULTANEOUS_VIEW_ENABLE);
 		else if (xgifb_info->TV_plug == TVPLUG_SCART)
-			cr30 = (XGI_VB_OUTPUT_SCART
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= XGI_DRIVER_MODE;
+			cr30 = (SIS_VB_OUTPUT_SCART
+					| SIS_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= SIS_DRIVER_MODE;
 
 		if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
 			cr31 |= 0x01;
@@ -840,7 +836,7 @@ static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
 		break;
 	default: /* disable CRT2 */
 		cr30 = 0x00;
-		cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
+		cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
 	}
 
 	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
@@ -854,7 +850,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
 	u8 reg;
 	unsigned char doit = 1;
 	/*
-	xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
+	xgifb_reg_set(XGISR,IND_SIS_PASSWORD,SIS_PASSWORD);
 	xgifb_reg_set(XGICR, 0x13, 0x00);
 	xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
 	*test*
@@ -890,7 +886,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
 		reg |= 0x80;
 	xgifb_reg_set(XGICR, 0x17, reg);
 
-	xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
+	xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04);
 
 	if (xgifb_info->display2 == XGIFB_DISP_TV &&
 	    xgifb_info->hasVB == HASVB_301) {
@@ -923,7 +919,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
 				break;
 			}
 			xgifb_reg_or(XGIPART1,
-				     IND_XGI_CRT2_WRITE_ENABLE_315,
+				     SIS_CRT2_WENABLE_315,
 				     0x01);
 
 			if (xgifb_info->TV_type == TVMODE_NTSC) {
@@ -1118,7 +1114,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 	if (!htotal || !vtotal) {
 		DPRINTK("XGIfb: Invalid 'var' information\n");
 		return -EINVAL;
-	} printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
+	} pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
 			var->pixclock, htotal, vtotal);
 
 	if (var->pixclock && htotal && vtotal) {
@@ -1130,7 +1126,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		xgifb_info->refresh_rate = 60;
 	}
 
-	printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
+	pr_debug("Change mode to %dx%dx%d-%dHz\n",
 	       var->xres,
 	       var->yres,
 	       var->bits_per_pixel,
@@ -1158,7 +1154,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		xgifb_info->mode_idx = -1;
 
 	if (xgifb_info->mode_idx < 0) {
-		printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
+		pr_err("Mode %dx%dx%d not supported\n",
 		       var->xres, var->yres, var->bits_per_pixel);
 		xgifb_info->mode_idx = old_mode;
 		return -EINVAL;
@@ -1177,14 +1173,14 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		if (XGISetModeNew(xgifb_info, hw_info,
 				  XGIbios_mode[xgifb_info->mode_idx].mode_no)
 					== 0) {
-			printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
+			pr_err("Setting mode[0x%x] failed\n",
 			       XGIbios_mode[xgifb_info->mode_idx].mode_no);
 			return -EINVAL;
 		}
 		info->fix.line_length = ((info->var.xres_virtual
 				* info->var.bits_per_pixel) >> 6);
 
-		xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+		xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 		xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
 		xgifb_reg_set(XGISR,
@@ -1239,7 +1235,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 			break;
 		default:
 			xgifb_info->video_cmap_len = 16;
-			printk(KERN_ERR "XGIfb: Unsupported depth %d",
+			pr_err("Unsupported depth %d",
 			       xgifb_info->video_bpp);
 			break;
 		}
@@ -1273,7 +1269,7 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
 		break;
 	}
 
-	xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+	xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 	xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
 	xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
@@ -1282,7 +1278,7 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
 	xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
 
 	if (xgifb_info->display2 != XGIFB_DISP_NONE) {
-		xgifb_reg_or(XGIPART1, IND_XGI_CRT2_WRITE_ENABLE_315, 0x01);
+		xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01);
 		xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
 		xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
 		xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
@@ -1387,7 +1383,7 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
 	fix->line_length = xgifb_info->video_linelength;
 	fix->mmio_start = xgifb_info->mmio_base;
 	fix->mmio_len = xgifb_info->mmio_size;
-	fix->accel = FB_ACCEL_XGI_XABRE;
+	fix->accel = FB_ACCEL_SIS_XABRE;
 
 	DEBUGPRN("end of get_fix");
 	return 0;
@@ -1441,7 +1437,7 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 		hrate = (drate * 1000) / htotal;
 		xgifb_info->refresh_rate =
 			(unsigned int) (hrate * 2 / vtotal);
-		printk(KERN_DEBUG
+		pr_debug(
 			"%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
 			"%s: drate=%d, hrate=%d, refresh_rate=%d\n",
 			__func__, var->pixclock, htotal, vtotal,
@@ -1479,7 +1475,7 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 
 	if (!found_mode) {
 
-		printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
+		pr_err("%dx%dx%d is no valid mode\n",
 			var->xres, var->yres, var->bits_per_pixel);
 		search_idx = 0;
 		while (XGIbios_mode[search_idx].mode_no != 0) {
@@ -1498,11 +1494,11 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 		if (found_mode) {
 			var->xres = XGIbios_mode[search_idx].xres;
 			var->yres = XGIbios_mode[search_idx].yres;
-			printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
+			pr_debug("Adapted to mode %dx%dx%d\n",
 				var->xres, var->yres, var->bits_per_pixel);
 
 		} else {
-			printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
+			pr_err("Failed to find similar mode to %dx%dx%d\n",
 				var->xres, var->yres, var->bits_per_pixel);
 			return -EINVAL;
 		}
@@ -1634,9 +1630,9 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
 
 	/* xorg driver sets 32MB * 1 channel */
 	if (xgifb_info->chip == XG27)
-		xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
+		xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
 
-	reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
+	reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
 	switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
 	case XGI_DRAM_SIZE_1MB:
 		xgifb_info->video_size = 0x100000;
@@ -1711,7 +1707,7 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
 	/* xgifb_info->video_size = 0x200000; */ /* 1024x768x16 */
 	/* xgifb_info->video_size = 0x1000000; */ /* benchmark */
 
-	printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
+	pr_info("SR14=%x DramSzie %x ChannelNum %x\n",
 	       reg,
 	       xgifb_info->video_size, ChannelNum);
 	return 0;
@@ -1736,7 +1732,7 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
 
 	cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
 
-	if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
+	if ((cr32 & SIS_CRT1) && !XGIfb_crt1off)
 		XGIfb_crt1off = 0;
 	else {
 		if (cr32 & 0x5F)
@@ -1746,11 +1742,11 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
 	}
 
 	if (!xgifb_info->display2_force) {
-		if (cr32 & XGI_VB_TV)
+		if (cr32 & SIS_VB_TV)
 			xgifb_info->display2 = XGIFB_DISP_TV;
-		else if (cr32 & XGI_VB_LCD)
+		else if (cr32 & SIS_VB_LCD)
 			xgifb_info->display2 = XGIFB_DISP_LCD;
-		else if (cr32 & XGI_VB_CRT2)
+		else if (cr32 & SIS_VB_CRT2)
 			xgifb_info->display2 = XGIFB_DISP_CRT;
 		else
 			xgifb_info->display2 = XGIFB_DISP_NONE;
@@ -1759,14 +1755,14 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
 	if (XGIfb_tvplug != -1)
 		/* PR/TW: Override with option */
 		xgifb_info->TV_plug = XGIfb_tvplug;
-	else if (cr32 & XGI_VB_HIVISION) {
+	else if (cr32 & SIS_VB_HIVISION) {
 		xgifb_info->TV_type = TVMODE_HIVISION;
 		xgifb_info->TV_plug = TVPLUG_SVIDEO;
-	} else if (cr32 & XGI_VB_SVIDEO)
+	} else if (cr32 & SIS_VB_SVIDEO)
 		xgifb_info->TV_plug = TVPLUG_SVIDEO;
-	else if (cr32 & XGI_VB_COMPOSITE)
+	else if (cr32 & SIS_VB_COMPOSITE)
 		xgifb_info->TV_plug = TVPLUG_COMPOSITE;
-	else if (cr32 & XGI_VB_SCART)
+	else if (cr32 & SIS_VB_SCART)
 		xgifb_info->TV_plug = TVPLUG_SCART;
 
 	if (xgifb_info->TV_type == 0) {
@@ -1811,11 +1807,11 @@ static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
 
 	if (!XGIfb_has_VB(xgifb_info)) {
 		reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
-		switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
-		case XGI310_EXTERNAL_CHIP_LVDS:
+		switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
+		case SIS_EXTERNAL_CHIP_LVDS:
 			xgifb_info->hasVB = HASVB_LVDS;
 			break;
-		case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+		case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
 			xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
 			break;
 		default:
@@ -1917,7 +1913,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 	xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
 	hw_info->pjIOAddress = (unsigned char *)xgifb_info->vga_base;
 	/* XGI_Pr.RelIO  = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
-	printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
+	pr_info("Relocate IO address: %lx [%08lx]\n",
 	       (unsigned long)pci_resource_start(pdev, 2),
 	       xgifb_info->dev_info.RelIO);
 
@@ -1933,17 +1929,17 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 
 	XGIRegInit(&xgifb_info->dev_info, (unsigned long)hw_info->pjIOAddress);
 
-	xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
-	reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
+	xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
+	reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD);
 
 	if (reg1 != 0xa1) { /*I/O error */
-		printk("\nXGIfb: I/O error!!!");
+		pr_err("I/O error!!!");
 		ret = -EIO;
 		goto error;
 	}
 
 	switch (xgifb_info->chip_id) {
-	case PCI_DEVICE_ID_XG_20:
+	case PCI_DEVICE_ID_XGI_20:
 		xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
 		CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
 		if (CR48&GPIOG_READ)
@@ -1951,16 +1947,16 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 		else
 			xgifb_info->chip = XG20;
 		break;
-	case PCI_DEVICE_ID_XG_40:
+	case PCI_DEVICE_ID_XGI_40:
 		xgifb_info->chip = XG40;
 		break;
-	case PCI_DEVICE_ID_XG_41:
+	case PCI_DEVICE_ID_XGI_41:
 		xgifb_info->chip = XG41;
 		break;
-	case PCI_DEVICE_ID_XG_42:
+	case PCI_DEVICE_ID_XGI_42:
 		xgifb_info->chip = XG42;
 		break;
-	case PCI_DEVICE_ID_XG_27:
+	case PCI_DEVICE_ID_XGI_27:
 		xgifb_info->chip = XG27;
 		break;
 	default:
@@ -1968,31 +1964,31 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 		goto error;
 	}
 
-	printk("XGIfb:chipid = %x\n", xgifb_info->chip);
+	pr_info("chipid = %x\n", xgifb_info->chip);
 	hw_info->jChipType = xgifb_info->chip;
 
 	if (XGIfb_get_dram_size(xgifb_info)) {
-		printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
+		pr_err("Fatal error: Unable to determine RAM size.\n");
 		ret = -ENODEV;
 		goto error;
 	}
 
 	/* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
 	xgifb_reg_or(XGISR,
-		     IND_XGI_PCI_ADDRESS_SET,
-		     (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
+		     IND_SIS_PCI_ADDRESS_SET,
+		     (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
 	/* Enable 2D accelerator engine */
-	xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
+	xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
 
 	hw_info->ulVideoMemorySize = xgifb_info->video_size;
 
 	if (!request_mem_region(xgifb_info->video_base,
 				xgifb_info->video_size,
 				"XGIfb FB")) {
-		printk("unable request memory size %x",
+		pr_err("unable request memory size %x\n",
 		       xgifb_info->video_size);
-		printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
-		printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
+		pr_err("Fatal error: Unable to reserve frame buffer memory\n");
+		pr_err("Is there another framebuffer driver active?\n");
 		ret = -ENODEV;
 		goto error;
 	}
@@ -2000,7 +1996,7 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 	if (!request_mem_region(xgifb_info->mmio_base,
 				xgifb_info->mmio_size,
 				"XGIfb MMIO")) {
-		printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
+		pr_err("Fatal error: Unable to reserve MMIO region\n");
 		ret = -ENODEV;
 		goto error_0;
 	}
@@ -2010,20 +2006,18 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 	xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
 					    xgifb_info->mmio_size);
 
-	printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+	pr_info("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
 	       xgifb_info->video_base,
 	       xgifb_info->video_vbase,
 	       xgifb_info->video_size / 1024);
 
-	printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
+	pr_info("MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
 	       xgifb_info->mmio_base, xgifb_info->mmio_vbase,
 	       xgifb_info->mmio_size / 1024);
-	printk("XGIfb: XGIInitNew() ...");
+
 	pci_set_drvdata(pdev, xgifb_info);
-	if (XGIInitNew(pdev))
-		printk("OK\n");
-	else
-		printk("Fail\n");
+	if (!XGIInitNew(pdev))
+		pr_err("XGIInitNew() failed!\n");
 
 	xgifb_info->mtrr = (unsigned int) 0;
 
@@ -2033,13 +2027,12 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 		xgifb_info->hasVB = HASVB_NONE;
 	} else if (xgifb_info->chip == XG21) {
 		CR38 = xgifb_reg_get(XGICR, 0x38);
-		if ((CR38&0xE0) == 0xC0) {
+		if ((CR38&0xE0) == 0xC0)
 			xgifb_info->display2 = XGIFB_DISP_LCD;
-		} else if ((CR38&0xE0) == 0x60) {
+		else if ((CR38&0xE0) == 0x60)
 			xgifb_info->hasVB = HASVB_CHRONTEL;
-		} else {
+		else
 			xgifb_info->hasVB = HASVB_NONE;
-		}
 	} else {
 		XGIfb_get_VB_type(xgifb_info);
 	}
@@ -2053,10 +2046,10 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 		reg = xgifb_reg_get(XGIPART4, 0x01);
 		if (reg >= 0xE0) {
 			hw_info->ujVBChipID = VB_CHIP_302LV;
-			printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
+			pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg);
 		} else if (reg >= 0xD0) {
 			hw_info->ujVBChipID = VB_CHIP_301LV;
-			printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
+			pr_info("XGI301LV bridge detected (revision 0x%02x)\n", reg);
 		}
 		/* else if (reg >= 0xB0) {
 			hw_info->ujVBChipID = VB_CHIP_301B;
@@ -2065,17 +2058,17 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 		} */
 		else {
 			hw_info->ujVBChipID = VB_CHIP_301;
-			printk("XGIfb: XGI301 bridge detected\n");
+			pr_info("XGI301 bridge detected\n");
 		}
 		break;
 	case HASVB_302:
 		reg = xgifb_reg_get(XGIPART4, 0x01);
 		if (reg >= 0xE0) {
 			hw_info->ujVBChipID = VB_CHIP_302LV;
-			printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
+			pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg);
 		} else if (reg >= 0xD0) {
 			hw_info->ujVBChipID = VB_CHIP_301LV;
-			printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
+			pr_info("XGI302LV bridge detected (revision 0x%02x)\n", reg);
 		} else if (reg >= 0xB0) {
 			reg1 = xgifb_reg_get(XGIPART4, 0x23);
 
@@ -2083,27 +2076,27 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 
 		} else {
 			hw_info->ujVBChipID = VB_CHIP_302;
-			printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
+			pr_info("XGI302 bridge detected\n");
 		}
 		break;
 	case HASVB_LVDS:
 		hw_info->ulExternalChip = 0x1;
-		printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
+		pr_info("LVDS transmitter detected\n");
 		break;
 	case HASVB_TRUMPION:
 		hw_info->ulExternalChip = 0x2;
-		printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
+		pr_info("Trumpion Zurac LVDS scaler detected\n");
 		break;
 	case HASVB_CHRONTEL:
 		hw_info->ulExternalChip = 0x4;
-		printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
+		pr_info("Chrontel TV encoder detected\n");
 		break;
 	case HASVB_LVDS_CHRONTEL:
 		hw_info->ulExternalChip = 0x5;
-		printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
+		pr_info("LVDS transmitter and Chrontel TV encoder detected\n");
 		break;
 	default:
-		printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
+		pr_info("No or unknown bridge type detected\n");
 		break;
 	}
 
@@ -2117,10 +2110,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 			reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
 			reg &= 0x0f;
 			hw_info->ulCRT2LCDType = XGI310paneltype[reg];
-
-		} else {
-			/* TW: FSTN/DSTN */
-			hw_info->ulCRT2LCDType = LCD_320x480;
 		}
 	}
 
@@ -2147,9 +2136,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 					if (tmp & 0x20) {
 						tmp = xgifb_reg_get(
 							XGIPART1, 0x13);
-						if (tmp & 0x04) {
-							/* XGI_Pr.XGI_UseLCDA = 1; */
-						}
 					}
 				}
 			}
@@ -2222,12 +2208,12 @@ static int __devinit xgifb_probe(struct pci_dev *pdev,
 		break;
 	default:
 		xgifb_info->video_cmap_len = 16;
-		printk(KERN_INFO "XGIfb: Unsupported depth %d",
+		pr_info("Unsupported depth %d\n",
 		       xgifb_info->video_bpp);
 		break;
 	}
 
-	printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
+	pr_info("Default mode is %dx%dx%d (%dHz)\n",
 	       xgifb_info->video_width,
 	       xgifb_info->video_height,
 	       xgifb_info->video_bpp,
@@ -2404,7 +2390,7 @@ MODULE_PARM_DESC(filter,
 static void __exit xgifb_remove_module(void)
 {
 	pci_unregister_driver(&xgifb_driver);
-	printk(KERN_DEBUG "xgifb: Module unloaded\n");
+	pr_debug("Module unloaded\n");
 }
 
 module_exit(xgifb_remove_module);
diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h
index 2c866bb..37bb730 100644
--- a/drivers/staging/xgifb/XGIfb.h
+++ b/drivers/staging/xgifb/XGIfb.h
@@ -3,8 +3,8 @@
 #include <linux/ioctl.h>
 #include <linux/types.h>
 
-#include "vb_struct.h"
 #include "vgatypes.h"
+#include "vb_struct.h"
 
 enum xgifb_display_type {
 	XGIFB_DISP_NONE = 0,
diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h
index 5beeef9..c731793 100644
--- a/drivers/staging/xgifb/vb_def.h
+++ b/drivers/staging/xgifb/vb_def.h
@@ -1,153 +1,48 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/xgi/initdef.h
  * ,v 1.4 2000/12/02 01:16:17 dawes Exp $*/
-#ifndef _INITDEF_
-#define _INITDEF_
+#ifndef _VB_DEF_
+#define _VB_DEF_
+#include "../../video/sis/initdef.h"
 
 #define VB_XGI301C      0x0020 /* for 301C */
-/*end 301b*/
-
-#define VB_YPbPr525p    0x01
-#define VB_YPbPr750p    0x02
 #define VB_YPbPr1080i   0x03
 
 #define LVDSCRT1Len     15
-
-#define SupportCHTV             0x0800
 #define SupportCRT2in301C       0x0100  /* for 301C */
 #define SetCHTVOverScan         0x8000
-#define PanelRGB18Bit           0x0100
-#define PanelRGB24Bit           0x0000
 
-#define Panel320x480            0x07 /*fstn*/
+#define Panel_320x480            0x07 /*fstn*/
 /* [ycchen] 02/12/03 Modify for Multi-Sync. LCD Support */
 #define PanelResInfo            0x1F /* CR36 Panel Type/LCDResInfo */
-#define Panel800x600            0x01
-#define Panel1024x768           0x02
-#define Panel1024x768x75        0x22
-#define Panel1280x1024          0x03
-#define Panel1280x1024x75       0x23
-#define Panel640x480            0x04
-#define Panel1280x960           0x07
-#define Panel1400x1050          0x09
-#define Panel1600x1200          0x0B
+#define Panel_1024x768x75        0x22
+#define Panel_1280x1024x75       0x23
 
 #define PanelRef60Hz            0x00
 #define PanelRef75Hz            0x20
 
-#define CRT2DisplayFlag         0x2000
-
 #define YPbPr525iVCLK           0x03B
 #define YPbPr525iVCLK_2         0x03A
 
 #define XGI_CRT2_PORT_00        (0x00 - 0x030)
-#define XGI_CRT2_PORT_04        (0x04 - 0x030)
-#define XGI_CRT2_PORT_10        (0x10 - 0x30)
-#define XGI_CRT2_PORT_12        (0x12 - 0x30)
-#define XGI_CRT2_PORT_14        (0x14 - 0x30)
-
-#define _PanelType00             0x00
-#define _PanelType01             0x08
-#define _PanelType02             0x10
-#define _PanelType03             0x18
-#define _PanelType04             0x20
-#define _PanelType05             0x28
-#define _PanelType06             0x30
-#define _PanelType07             0x38
-#define _PanelType08             0x40
-#define _PanelType09             0x48
-#define _PanelType0A             0x50
-#define _PanelType0B             0x58
-#define _PanelType0C             0x60
-#define _PanelType0D             0x68
-#define _PanelType0E             0x70
-#define _PanelType0F             0x78
 
 /* =============================================================
    for 310
 ============================================================== */
-/* add LCDDataList for GetLCDPtr */
-#define LCDDataList               (VBIOSTablePointerStart+0x22)
-/*  */
-/* Modify from 310.inc */
-/*  */
-/*  */
-
 #define ModeSoftSetting              0x04
 
-#define BoardTVType                  0x02
-
-#define SoftDRAMType                 0x80    /* DRAMSetting */
-
 /* ---------------- SetMode Stack */
 #define CRT1Len           15
 #define VCLKLen           4
-#define VGA_XGI340        0x0001       /* 340 series */
-
-#define VB_XGI301         0x0001       /* VB Type Info */
-#define VB_XGI301B        0x0002       /* 301 series */
-#define VB_XGI302B        0x0004
-#define VB_NoLCD          0x8000
-#define VB_XGI301LV       0x0008
-#define VB_XGI302LV       0x0010
-#define VB_LVDS_NS        0x0001       /* 3rd party chip */
-
-#define ModeInfoFlag      0x0007
-#define ModeText          0x0000
-#define ModeEGA           0x0002    /* 16 colors mode */
-#define ModeVGA           0x0003    /* 256 colors mode */
-
-#define DACInfoFlag       0x0018
-
-#define MemoryInfoFlag    0x01e0
-#define MemorySizeShift   5
-
-#define Charx8Dot         0x0200
-#define LineCompareOff    0x0400
-#define CRT2Mode          0x0800
-#define HalfDCLK          0x1000
-#define NoSupportSimuTV   0x2000
-#define DoubleScanMode    0x8000
-
-/* -------------- Ext_InfoFlag */
-#define Support16Bpp        0x0005
-#define Support32Bpp        0x0007
 
 #define SupportAllCRT2      0x0078
-#define SupportTV           0x0008
-#define SupportHiVisionTV   0x0010
-#define SupportLCD          0x0020
-#define SupportRAMDAC2      0x0040
 #define NoSupportTV         0x0070
 #define NoSupportHiVisionTV 0x0060
 #define NoSupportLCD        0x0058
-#define SupportTV1024       0x0800 /* 301btest */
-#define SupportYPbPr        0x1000 /* 301lv */
-#define InterlaceMode       0x0080
-#define SyncPP              0x0000
-#define SyncPN              0x4000
-#define SyncNP              0x8000
-#define SyncNN              0xC000
 
 /* -------------- SetMode Stack/Scratch */
-#define SetSimuScanMode     0x0001    /* VBInfo/CR30 & CR31 */
-#define SwitchToCRT2        0x0002
-#define SetCRT2ToTV         0x089C
-#define SetCRT2ToAVIDEO     0x0004
-#define SetCRT2ToSVIDEO     0x0008
-#define SetCRT2ToSCART      0x0010
-#define SetCRT2ToLCD        0x0020
-#define SetCRT2ToRAMDAC     0x0040
-#define SetCRT2ToHiVisionTV 0x0080
-#define SetCRT2ToLCDA       0x0100
-#define SetInSlaveMode      0x0200
-#define SetNotSimuMode      0x0400
-#define SetCRT2ToYPbPr      0x0800
-#define LoadDACFlag         0x1000
-#define DisableCRT2Display  0x2000
-#define DriverMode          0x4000
+#define XGI_SetCRT2ToLCDA   0x0100
 #define SetCRT2ToDualEdge   0x8000
 
-#define ProgrammingCRT2     0x0001       /* Set Flag */
 #define ReserveTVOption     0x0008
 #define GatingCRT           0x0800
 #define DisableChB          0x1000
@@ -155,23 +50,14 @@
 #define DisableChA          0x4000
 #define EnableChA           0x8000
 
-#define SetNTSCTV           0x0000 /* TV Info */
-#define SetPALTV            0x0001
-#define SetNTSCJ            0x0002
-#define SetPALMTV           0x0004
-#define SetPALNTV           0x0008
-#define SetYPbPrMode525i     0x0020
-#define SetYPbPrMode525p     0x0040
-#define SetYPbPrMode750p     0x0080
-#define SetYPbPrMode1080i    0x0100
 #define SetTVLowResolution   0x0400
 #define TVSimuMode           0x0800
 #define RPLLDIV2XO           0x1000
 #define NTSC1024x768         0x2000
 #define SetTVLockMode        0x4000
 
-#define LCDVESATiming        0x0001 /* LCD Info/CR37 */
-#define EnableLVDSDDA        0x0002
+#define XGI_LCDVESATiming    0x0001 /* LCD Info/CR37 */
+#define XGI_EnableLVDSDDA    0x0002
 #define EnableScalingLCD     0x0008
 #define SetPWDEnable         0x0004
 #define SetLCDtoNonExpanding 0x0010
@@ -184,7 +70,7 @@
 #define EnableLCD24bpp       0x0004 /* default */
 #define DisableLCD24bpp      0x0000
 #define LCDPolarity          0x00c0 /* default: SyncNN */
-#define LCDDualLink          0x0100
+#define XGI_LCDDualLink      0x0100
 #define EnableSpectrum       0x0200
 #define PWDEnable            0x0400
 #define EnableVBCLKDRVLOW    0x4000
@@ -206,31 +92,21 @@
 
 #define TVSense              0xc7
 
-#define TVOverScan           0x10               /* CR35 */
-
 #define YPbPrMode            0xe0
 #define YPbPrMode525i        0x00
 #define YPbPrMode525p        0x20
 #define YPbPrMode750p        0x40
 #define YPbPrMode1080i       0x60
 
-
-#define LCDRGB18Bit          0x01               /* CR37 */
-#define LCDNonExpanding      0x10
-#define LCDSync              0x20
-#define LCDSyncBit           0xe0 /* H/V polarity & sync ID */
-
 #define ScalingLCD           0x08
 
-#define EnableDualEdge       0x01 /* CR38 */
-#define SetToLCDA            0x02
 #define SetYPbPr             0x04
 
 /* ---------------------- VUMA Information */
 #define DisplayDeviceFromCMOS 0x10
 
 /* ---------------------- HK Evnet Definition */
-#define ModeSwitchStatus      0xf0
+#define XGI_ModeSwitchStatus  0xf0
 #define ActiveCRT1            0x10
 #define ActiveLCD             0x0020
 #define ActiveTV              0x40
@@ -246,28 +122,13 @@
 /* translated from asm code 301def.h */
 /*  */
 /* --------------------------------------------------------- */
-#define LCDDataLen           8
-#define TVDataLen            12
 #define LVDSCRT1Len_H        8
 #define LVDSCRT1Len_V        7
-#define LVDSDataLen          6
-#define LVDSDesDataLen       6
 #define LCDDesDataLen        6
 #define LVDSDesDataLen2      8
 #define LCDDesDataLen2       8
-#define CHTVRegLen           16
 
-#define StHiTVHT             892
-#define StHiTVVT             1126
-#define StHiTextTVHT         1000
-#define StHiTextTVVT         1126
-#define ExtHiTVHT            2100
-#define ExtHiTVVT            1125
-#define NTSCHT               1716
-#define NTSCVT                525
 #define NTSC1024x768HT       1908
-#define PALHT                1728
-#define PALVT                 625
 
 #define YPbPrTV525iHT        1716 /* YPbPr */
 #define YPbPrTV525iVT         525
@@ -276,22 +137,16 @@
 #define YPbPrTV750pHT        1650
 #define YPbPrTV750pVT         750
 
-#define CRT2Delay1           0x04 /* XGI301 */
-#define CRT2Delay2           0x0A /* 301B,302 */
-
-
 #define VCLK25_175           0x00
 #define VCLK28_322           0x01
 #define VCLK31_5             0x02
 #define VCLK36               0x03
-#define VCLK40               0x04
 #define VCLK43_163           0x05
 #define VCLK44_9             0x06
 #define VCLK49_5             0x07
 #define VCLK50               0x08
 #define VCLK52_406           0x09
 #define VCLK56_25            0x0A
-#define VCLK65               0x0B
 #define VCLK68_179           0x0D
 #define VCLK72_852           0x0E
 #define VCLK75               0x0F
@@ -300,7 +155,6 @@
 #define VCLK83_95            0x13
 #define VCLK86_6             0x15
 #define VCLK94_5             0x16
-#define VCLK108_2            0x19
 #define VCLK113_309          0x1B
 #define VCLK116_406          0x1C
 #define VCLK135_5            0x1E
@@ -327,16 +181,10 @@
 #define VCLK125_999          0x51
 #define VCLK148_5            0x52
 #define VCLK217_325          0x55
-#define YPbPr750pVCLK        0x57
+#define XGI_YPbPr750pVCLK    0x57
 
-#define TVVCLKDIV2           0x3A
-#define TVVCLK               0x3B
-#define HiTVVCLKDIV2         0x3C
-#define HiTVVCLK             0x3D
-#define HiTVSimuVCLK         0x3E
-#define HiTVTextVCLK         0x3F
 #define VCLK39_77            0x40
-#define YPbPr525pVCLK           0x3A
+#define YPbPr525pVCLK        0x3A
 #define NTSC1024VCLK         0x41
 #define VCLK35_2             0x49 /* ; 800x480 */
 #define VCLK122_61           0x4A
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
index 4ccd988..94d5c35 100644
--- a/drivers/staging/xgifb/vb_init.c
+++ b/drivers/staging/xgifb/vb_init.c
@@ -3,8 +3,8 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 
-#include "vgatypes.h"
 #include "XGIfb.h"
+#include "vgatypes.h"
 
 #include "vb_def.h"
 #include "vb_struct.h"
@@ -1268,7 +1268,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
 
 				if (pVBInfo->IF_DEF_HiVision == 1) {
 					if ((temp >> 8) & ActiveHiTV)
-						tempcl |= SetCRT2ToHiVisionTV;
+						tempcl |= SetCRT2ToHiVision;
 				}
 
 				if (pVBInfo->IF_DEF_YPbPr == 1) {
@@ -1287,7 +1287,7 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
 
 		if (pVBInfo->IF_DEF_HiVision == 1) {
 			if ((temp >> 8) & ActiveHiTV)
-				tempcl |= SetCRT2ToHiVisionTV;
+				tempcl |= SetCRT2ToHiVision;
 		}
 
 		if (pVBInfo->IF_DEF_YPbPr == 1) {
@@ -1299,9 +1299,9 @@ static void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
 	tempcl |= SetSimuScanMode;
 	if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
 			|| (temp & ActiveCRT2)))
-		tempcl ^= (SetSimuScanMode | SwitchToCRT2);
+		tempcl ^= (SetSimuScanMode | SwitchCRT2);
 	if ((temp & ActiveLCD) && (temp & ActiveTV))
-		tempcl ^= (SetSimuScanMode | SwitchToCRT2);
+		tempcl ^= (SetSimuScanMode | SwitchCRT2);
 	xgifb_reg_set(pVBInfo->P3d4, 0x30, tempcl);
 
 	CR31Data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
@@ -1516,11 +1516,11 @@ unsigned char XGIInitNew(struct pci_dev *pdev)
 	pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
 	pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
 	pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
-	pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
-	pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
-	pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
-	pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
-	pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+	pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04;
+	pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10;
+	pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12;
+	pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14;
+	pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2;
 	printk("5");
 
 	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c
index 67a316c..2919924 100644
--- a/drivers/staging/xgifb/vb_setmode.c
+++ b/drivers/staging/xgifb/vb_setmode.c
@@ -61,20 +61,20 @@ static const unsigned short XGINew_VGA_DAC[] = {
 void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
 {
 	pVBInfo->SModeIDTable = (struct XGI_StStruct *) XGI330_SModeIDTable;
-	pVBInfo->StandTable = (struct XGI_StandTableStruct *) XGI330_StandTable;
+	pVBInfo->StandTable = (struct SiS_StandTable_S *) XGI330_StandTable;
 	pVBInfo->EModeIDTable = (struct XGI_ExtStruct *) XGI330_EModeIDTable;
 	pVBInfo->RefIndex = (struct XGI_Ext2Struct *) XGI330_RefIndex;
 	pVBInfo->XGINEWUB_CRT1Table
 			= (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
 
-	pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
+	pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI340New_MCLKData;
 	pVBInfo->ECLKData = (struct XGI_ECLKDataStruct *) XGI340_ECLKData;
-	pVBInfo->VCLKData = (struct XGI_VCLKDataStruct *) XGI_VCLKData;
-	pVBInfo->VBVCLKData = (struct XGI_VBVCLKDataStruct *) XGI_VBVCLKData;
+	pVBInfo->VCLKData = (struct SiS_VCLKData *) XGI_VCLKData;
+	pVBInfo->VBVCLKData = (struct SiS_VBVCLKData *) XGI_VBVCLKData;
 	pVBInfo->ScreenOffset = XGI330_ScreenOffset;
-	pVBInfo->StResInfo = (struct XGI_StResInfoStruct *) XGI330_StResInfo;
+	pVBInfo->StResInfo = (struct SiS_StResInfo_S *) XGI330_StResInfo;
 	pVBInfo->ModeResInfo
-			= (struct XGI_ModeResInfoStruct *) XGI330_ModeResInfo;
+			= (struct SiS_ModeResInfo_S *) XGI330_ModeResInfo;
 
 	pVBInfo->pOutputSelect = &XGI330_OutputSelect;
 	pVBInfo->pSoftSetting = &XGI330_SoftSetting;
@@ -138,7 +138,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
 	pVBInfo->UpdateCRT1 = (struct XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table;
 
 	/* 310 customization related */
-	if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
+	if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV))
 		pVBInfo->LCDCapList = XGI_LCDDLCapList;
 	else
 		pVBInfo->LCDCapList = XGI_LCDCapList;
@@ -153,7 +153,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo)
 
 	if (ChipType == XG27) {
 		pVBInfo->MCLKData
-			= (struct XGI_MCLKDataStruct *) XGI27New_MCLKData;
+			= (struct SiS_MCLKData *) XGI27New_MCLKData;
 		pVBInfo->CR40 = XGI27_cr41;
 		pVBInfo->pXGINew_CR97 = &XG27_CR97;
 		pVBInfo->pSR36 = &XG27_SR36;
@@ -208,8 +208,8 @@ static void XGI_SetSeqRegs(unsigned short ModeNo,
 	xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
 	tempah = pVBInfo->StandTable[StandTableIndex].SR[0];
 
-	i = SetCRT2ToLCDA;
-	if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+	i = XGI_SetCRT2ToLCDA;
+	if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 		tempah |= 0x01;
 	} else {
 		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
@@ -263,7 +263,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo,
 		ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
 		if (modeflag & Charx8Dot) { /* ifndef Dot9 */
 			if (i == 0x13) {
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+				if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 					ARdata = 0;
 				} else {
 					if (pVBInfo->VBInfo & (SetCRT2ToTV
@@ -356,11 +356,11 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
 		}
 
 		/* 301b */
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 			tempax |= SupportLCD;
 
-			if (pVBInfo->LCDResInfo != Panel1280x1024) {
-				if (pVBInfo->LCDResInfo != Panel1280x960) {
+			if (pVBInfo->LCDResInfo != Panel_1280x1024) {
+				if (pVBInfo->LCDResInfo != Panel_1280x960) {
 					if (pVBInfo->LCDInfo &
 					    LCDNonExpanding) {
 						if (resinfo >= 9) {
@@ -372,10 +372,10 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
 			}
 		}
 
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
-			if ((pVBInfo->VBType & VB_XGI301LV) &&
+		if (pVBInfo->VBInfo & SetCRT2ToHiVision) { /* for HiTV */
+			if ((pVBInfo->VBType & VB_SIS301LV) &&
 			    (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
-				tempax |= SupportYPbPr;
+				tempax |= SupportYPbPr750p;
 				if (pVBInfo->VBInfo & SetInSlaveMode) {
 					if (resinfo == 4)
 						return 0;
@@ -387,7 +387,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
 						return 0;
 				}
 			} else {
-				tempax |= SupportHiVisionTV;
+				tempax |= SupportHiVision;
 				if (pVBInfo->VBInfo & SetInSlaveMode) {
 					if (resinfo == 4)
 						return 0;
@@ -406,17 +406,17 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
 			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
 					       SetCRT2ToSVIDEO |
 					       SetCRT2ToSCART |
-					       SetCRT2ToYPbPr |
-					       SetCRT2ToHiVisionTV)) {
+					       SetCRT2ToYPbPr525750 |
+					       SetCRT2ToHiVision)) {
 				tempax |= SupportTV;
 
-				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-						| VB_XGI301LV | VB_XGI302LV
+				if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+						| VB_SIS301LV | VB_SIS302LV
 						| VB_XGI301C)) {
 					tempax |= SupportTV1024;
 				}
 
-				if (!(pVBInfo->VBInfo & SetPALTV)) {
+				if (!(pVBInfo->VBInfo & TVSetPAL)) {
 					if (modeflag & NoSupportSimuTV) {
 						if (pVBInfo->VBInfo &
 						    SetInSlaveMode) {
@@ -436,7 +436,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo,
 			if (resinfo > 0x08)
 				return 0; /* 1024x768 */
 
-			if (pVBInfo->LCDResInfo < Panel1024x768) {
+			if (pVBInfo->LCDResInfo < Panel_1024x768) {
 				if (resinfo > 0x07)
 					return 0; /* 800x600 */
 
@@ -1230,23 +1230,23 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
 {
-	unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2,
-					   VCLK65 + 2,
-					   VCLK65 + 2,
-					   VCLK65 + 2 };
-	unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5,
-					   VCLK108_2 + 5,
-					   VCLK108_2 + 5,
-					   VCLK108_2 + 5 };
+	unsigned short LCDXlat1VCLK[4] = { VCLK65_315 + 2,
+					   VCLK65_315 + 2,
+					   VCLK65_315 + 2,
+					   VCLK65_315 + 2 };
+	unsigned short LCDXlat2VCLK[4] = { VCLK108_2_315 + 5,
+					   VCLK108_2_315 + 5,
+					   VCLK108_2_315 + 5,
+					   VCLK108_2_315 + 5 };
 	unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
-	unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2,
-					    VCLK65 + 2,
-					    VCLK65 + 2,
-					    VCLK65 + 2 };
-	unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2,
-					    VCLK65 + 2,
-					    VCLK65 + 2,
-					    VCLK65 + 2 };
+	unsigned short LVDSXlat2VCLK[4] = { VCLK65_315 + 2,
+					    VCLK65_315 + 2,
+					    VCLK65_315 + 2,
+					    VCLK65_315 + 2 };
+	unsigned short LVDSXlat3VCLK[4] = { VCLK65_315 + 2,
+					    VCLK65_315 + 2,
+					    VCLK65_315 + 2,
+					    VCLK65_315 + 2 };
 
 	unsigned short CRT2Index, VCLKIndex;
 	unsigned short modeflag, resinfo;
@@ -1266,36 +1266,36 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
 
 	if (pVBInfo->IF_DEF_LVDS == 0) {
 		CRT2Index = CRT2Index >> 6; /*  for LCD */
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/
-			if (pVBInfo->LCDResInfo != Panel1024x768)
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { /*301b*/
+			if (pVBInfo->LCDResInfo != Panel_1024x768)
 				VCLKIndex = LCDXlat2VCLK[CRT2Index];
 			else
 				VCLKIndex = LCDXlat1VCLK[CRT2Index];
-		} else if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		} else if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 			if (pVBInfo->SetFlag & RPLLDIV2XO) {
-				VCLKIndex = HiTVVCLKDIV2;
+				VCLKIndex = TVCLKBASE_315 + HiTVVCLKDIV2;
 				VCLKIndex += 25;
 			} else {
-				VCLKIndex = HiTVVCLK;
+				VCLKIndex = TVCLKBASE_315 + HiTVVCLK;
 				VCLKIndex += 25;
 			}
 
 			if (pVBInfo->SetFlag & TVSimuMode) {
 				if (modeflag & Charx8Dot) {
-					VCLKIndex = HiTVSimuVCLK;
+					VCLKIndex = TVCLKBASE_315 + HiTVSimuVCLK;
 					VCLKIndex += 25;
 				} else {
-					VCLKIndex = HiTVTextVCLK;
+					VCLKIndex = TVCLKBASE_315 + HiTVTextVCLK;
 					VCLKIndex += 25;
 				}
 			}
 
 			/* 301lv */
-			if ((pVBInfo->VBType & VB_XGI301LV) &&
+			if ((pVBInfo->VBType & VB_SIS301LV) &&
 			    !(pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
-				if (pVBInfo->VBExtInfo == VB_YPbPr750p)
-					VCLKIndex = YPbPr750pVCLK;
-				else if (pVBInfo->VBExtInfo == VB_YPbPr525p)
+				if (pVBInfo->VBExtInfo == YPbPr750p)
+					VCLKIndex = XGI_YPbPr750pVCLK;
+				else if (pVBInfo->VBExtInfo == YPbPr525p)
 					VCLKIndex = YPbPr525pVCLK;
 				else if (pVBInfo->SetFlag & RPLLDIV2XO)
 					VCLKIndex = YPbPr525iVCLK_2;
@@ -1304,10 +1304,10 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
 			}
 		} else if (pVBInfo->VBInfo & SetCRT2ToTV) {
 			if (pVBInfo->SetFlag & RPLLDIV2XO) {
-				VCLKIndex = TVVCLKDIV2;
+				VCLKIndex = TVCLKBASE_315 + TVVCLKDIV2;
 				VCLKIndex += 25;
 			} else {
-				VCLKIndex = TVVCLK;
+				VCLKIndex = TVCLKBASE_315 + TVVCLK;
 				VCLKIndex += 25;
 			}
 		} else { /* for CRT2 */
@@ -1329,11 +1329,11 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
 			VCLKIndex = CRT2Index;
 
 		VCLKIndex = VCLKIndex >> 6;
-		if ((pVBInfo->LCDResInfo == Panel800x600) ||
-		    (pVBInfo->LCDResInfo == Panel320x480))
+		if ((pVBInfo->LCDResInfo == Panel_800x600) ||
+		    (pVBInfo->LCDResInfo == Panel_320x480))
 			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-		else if ((pVBInfo->LCDResInfo == Panel1024x768) ||
-			 (pVBInfo->LCDResInfo == Panel1024x768x75))
+		else if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
+			 (pVBInfo->LCDResInfo == Panel_1024x768x75))
 			VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
 		else
 			VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
@@ -1360,9 +1360,9 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo,
 		xgifb_reg_set(pVBInfo->P3c4, 0x2C,
 				pVBInfo->VCLKData[index].SR2C);
 		xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01);
-	} else if ((pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) && (pVBInfo->VBInfo
-			& SetCRT2ToLCDA)) {
+	} else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo
+			& XGI_SetCRT2ToLCDA)) {
 		vclkindex = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex,
 				RefreshRateTableIndex, HwDeviceExtension,
 				pVBInfo);
@@ -1801,7 +1801,7 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
 					Ext_CRT2CRTC;
 		}
 
-		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+		if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 			if (ModeNo <= 0x13)
 				tempal = pVBInfo->SModeIDTable[ModeIdIndex].
 						St_CRT2CRTC2;
@@ -2128,30 +2128,30 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
 			return &XGI_CetLCDDes1024x768Data[tempal];
 			break;
 		case 3:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-				(pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+				(pVBInfo->VBType & VB_SIS302LV))
 				return &XGI_ExtLCDDLDes1280x1024Data[tempal];
 			else
 				return &XGI_ExtLCDDes1280x1024Data[tempal];
 			break;
 		case 4:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &XGI_StLCDDLDes1280x1024Data[tempal];
 			else
 				return &XGI_StLCDDes1280x1024Data[tempal];
 			break;
 		case 5:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &XGI_CetLCDDLDes1280x1024Data[tempal];
 			else
 				return &XGI_CetLCDDes1280x1024Data[tempal];
 			break;
 		case 6:
 		case 7:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &xgifb_lcddldes_1400x1050[tempal];
 			else
 				return &xgifb_lcddes_1400x1050[tempal];
@@ -2163,15 +2163,15 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
 			return &XGI_CetLCDDes1400x1050Data2[tempal];
 			break;
 		case 10:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &XGI_ExtLCDDLDes1600x1200Data[tempal];
 			else
 				return &XGI_ExtLCDDes1600x1200Data[tempal];
 			break;
 		case 11:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &XGI_StLCDDLDes1600x1200Data[tempal];
 			else
 				return &XGI_StLCDDes1600x1200Data[tempal];
@@ -2188,15 +2188,15 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo,
 			break;
 		case 16:
 		case 17:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &xgifb_lcddldes_1280x1024x75[tempal];
 			else
 				return &xgifb_lcddes_1280x1024x75[tempal];
 			break;
 		case 18:
-			if ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV))
 				return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
 			else
 				return &XGI_CetLCDDes1280x1024x75Data[tempal];
@@ -2364,7 +2364,7 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempbx = 2;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 		LCDPtr = (struct XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx,
 				ModeNo, ModeIdIndex, RefreshRateTableIndex,
 				pVBInfo);
@@ -2374,18 +2374,18 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex,
 		pVBInfo->VT = LCDPtr->LCDVT;
 	}
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 		if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
 				| EnableScalingLCD))) {
-			if ((pVBInfo->LCDResInfo == Panel1024x768) ||
-			    (pVBInfo->LCDResInfo == Panel1024x768x75)) {
+			if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
+			    (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
 				pVBInfo->HDE = 1024;
 				pVBInfo->VDE = 768;
-			} else if ((pVBInfo->LCDResInfo == Panel1280x1024) ||
-				   (pVBInfo->LCDResInfo == Panel1280x1024x75)) {
+			} else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
+				   (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
 				pVBInfo->HDE = 1280;
 				pVBInfo->VDE = 1024;
-			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+			} else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
 				pVBInfo->HDE = 1400;
 				pVBInfo->VDE = 1050;
 			} else {
@@ -2415,7 +2415,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempbx = 0;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 		LCDPtr = (struct XGI_LVDSCRT1HDataStruct *)
 				XGI_GetLcdPtr(tempbx, ModeNo,
 					      ModeIdIndex,
@@ -2430,7 +2430,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempbx = 1;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 		LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *)
 				XGI_GetLcdPtr(
 					tempbx,
@@ -2496,7 +2496,7 @@ static unsigned short XGI_GetLCDCapPtr1(struct vb_device_info *pVBInfo)
 	}
 
 	if (tempbl == 0xFF) {
-		pVBInfo->LCDResInfo = Panel1024x768;
+		pVBInfo->LCDResInfo = Panel_1024x768;
 		pVBInfo->LCDTypeInfo = 0;
 		i = 0;
 	}
@@ -2556,15 +2556,15 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	push2 = tempax;
 
 	/* GetLCDResInfo */
-	if ((pVBInfo->LCDResInfo == Panel1024x768) ||
-	    (pVBInfo->LCDResInfo == Panel1024x768x75)) {
+	if ((pVBInfo->LCDResInfo == Panel_1024x768) ||
+	    (pVBInfo->LCDResInfo == Panel_1024x768x75)) {
 		tempax = 1024;
 		tempbx = 768;
-	} else if ((pVBInfo->LCDResInfo == Panel1280x1024) ||
-		   (pVBInfo->LCDResInfo == Panel1280x1024x75)) {
+	} else if ((pVBInfo->LCDResInfo == Panel_1280x1024) ||
+		   (pVBInfo->LCDResInfo == Panel_1280x1024x75)) {
 		tempax = 1280;
 		tempbx = 1024;
-	} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+	} else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
 		tempax = 1400;
 		tempbx = 1050;
 	} else {
@@ -2682,7 +2682,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	if (tempbx != pVBInfo->VDE)
 		tempax |= 0x40;
 
-	if (pVBInfo->LCDInfo & EnableLVDSDDA)
+	if (pVBInfo->LCDInfo & XGI_EnableLVDSDDA)
 		tempax |= 0x40;
 
 	xgifb_reg_and_or(pVBInfo->Part1Port, 0x1a, 0x07,
@@ -2768,7 +2768,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp1 = temp1 / push3;
 	tempbx = (unsigned short) (temp1 & 0xffff);
 
-	if (pVBInfo->LCDResInfo == Panel1024x768)
+	if (pVBInfo->LCDResInfo == Panel_1024x768)
 		tempbx -= 1;
 
 	tempax = ((tempbx >> 8) & 0xff) << 3;
@@ -2800,7 +2800,7 @@ static void XGI_GetLCDVCLKPtr(unsigned char *di_0, unsigned char *di_1,
 {
 	unsigned short index;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 		index = XGI_GetLCDCapPtr1(pVBInfo);
 
 		if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
@@ -2834,35 +2834,35 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
 		index = XGI_GetLCDCapPtr(pVBInfo);
 		tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
 			return tempal;
 
 		/* {TV} */
 		if (pVBInfo->VBType &
-		    (VB_XGI301B |
-		     VB_XGI302B |
-		     VB_XGI301LV |
-		     VB_XGI302LV |
+		    (VB_SIS301B |
+		     VB_SIS302B |
+		     VB_SIS301LV |
+		     VB_SIS302LV |
 		     VB_XGI301C)) {
-			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-				tempal = HiTVVCLKDIV2;
+			if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+				tempal = TVCLKBASE_315 + HiTVVCLKDIV2;
 				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
-					tempal = HiTVVCLK;
+					tempal = TVCLKBASE_315 + HiTVVCLK;
 				if (pVBInfo->TVInfo & TVSimuMode) {
-					tempal = HiTVSimuVCLK;
+					tempal = TVCLKBASE_315 + HiTVSimuVCLK;
 					if (!(modeflag & Charx8Dot))
-						tempal = HiTVTextVCLK;
+						tempal = TVCLKBASE_315 + HiTVTextVCLK;
 
 				}
 				return tempal;
 			}
 
-			if (pVBInfo->TVInfo & SetYPbPrMode750p) {
-				tempal = YPbPr750pVCLK;
+			if (pVBInfo->TVInfo & TVSetYPbPr750p) {
+				tempal = XGI_YPbPr750pVCLK;
 				return tempal;
 			}
 
-			if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+			if (pVBInfo->TVInfo & TVSetYPbPr525p) {
 				tempal = YPbPr525pVCLK;
 				return tempal;
 			}
@@ -2870,9 +2870,9 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
 			tempal = NTSC1024VCLK;
 
 			if (!(pVBInfo->TVInfo & NTSC1024x768)) {
-				tempal = TVVCLKDIV2;
+				tempal = TVCLKBASE_315 + TVVCLKDIV2;
 				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
-					tempal = TVVCLK;
+					tempal = TVCLKBASE_315 + TVVCLK;
 			}
 
 			if (pVBInfo->VBInfo & SetCRT2ToTV)
@@ -2898,9 +2898,9 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex,
 static void XGI_GetVCLKLen(unsigned char tempal, unsigned char *di_0,
 		unsigned char *di_1, struct vb_device_info *pVBInfo)
 {
-	if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B
-			| VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-		if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) && (pVBInfo->SetFlag
+	if (pVBInfo->VBType & (VB_SIS301 | VB_SIS301B | VB_SIS302B
+			| VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
+		if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) && (pVBInfo->SetFlag
 				& ProgrammingCRT2)) {
 			*di_0 = (unsigned char) XGI_VBVCLKData[tempal].SR2B;
 			*di_1 = XGI_VBVCLKData[tempal].SR2C;
@@ -2926,7 +2926,7 @@ static void XGI_SetCRT2ECLK(unsigned short ModeNo, unsigned short ModeIdIndex,
 	for (i = 0; i < 4; i++) {
 		xgifb_reg_and_or(pVBInfo->P3d4, 0x31, ~0x30,
 				(unsigned short) (0x10 * i));
-		if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+		if ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
 				&& (!(pVBInfo->VBInfo & SetInSlaveMode))) {
 			xgifb_reg_set(pVBInfo->P3c4, 0x2e, di_0);
 			xgifb_reg_set(pVBInfo->P3c4, 0x2f, di_1);
@@ -2942,8 +2942,8 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
 {
 	unsigned short tempcl, tempch, temp, tempbl, tempax;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		tempcl = 0;
 		tempch = 0;
 		temp = xgifb_reg_get(pVBInfo->P3c4, 0x01);
@@ -2987,12 +2987,12 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
 				if (temp & 0x02)
 					tempch |= ActiveSCART;
 
-				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+				if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 					if (temp & 0x01)
 						tempch |= ActiveHiTV;
 				}
 
-				if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+				if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
 					temp = xgifb_reg_get(
 							pVBInfo->Part2Port,
 							0x4d);
@@ -3014,7 +3014,7 @@ static void XGI_UpdateModeInfo(struct xgi_hw_device_info *HwDeviceExtension,
 			}
 		}
 		temp = tempcl;
-		tempbl = ~ModeSwitchStatus;
+		tempbl = ~XGI_ModeSwitchStatus;
 		xgifb_reg_and_or(pVBInfo->P3d4, 0x3d, tempbl, temp);
 
 		if (!(pVBInfo->SetFlag & ReserveTVOption))
@@ -3029,19 +3029,19 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo)
 	unsigned short flag, tempbx, tempah;
 
 	if (pVBInfo->IF_DEF_LVDS == 0) {
-		tempbx = VB_XGI302B;
+		tempbx = VB_SIS302B;
 		flag = xgifb_reg_get(pVBInfo->Part4Port, 0x00);
 		if (flag != 0x02) {
-			tempbx = VB_XGI301;
+			tempbx = VB_SIS301;
 			flag = xgifb_reg_get(pVBInfo->Part4Port, 0x01);
 			if (flag >= 0xB0) {
-				tempbx = VB_XGI301B;
+				tempbx = VB_SIS301B;
 				if (flag >= 0xC0) {
 					tempbx = VB_XGI301C;
 					if (flag >= 0xD0) {
-						tempbx = VB_XGI301LV;
+						tempbx = VB_SIS301LV;
 						if (flag >= 0xE0) {
-							tempbx = VB_XGI302LV;
+							tempbx = VB_SIS302LV;
 							tempah = xgifb_reg_get(
 							    pVBInfo->Part4Port,
 							    0x39);
@@ -3052,7 +3052,7 @@ void XGI_GetVBType(struct vb_device_info *pVBInfo)
 					}
 				}
 
-				if (tempbx & (VB_XGI301B | VB_XGI302B)) {
+				if (tempbx & (VB_SIS301B | VB_SIS302B)) {
 					flag = xgifb_reg_get(
 							pVBInfo->Part4Port,
 							0x23);
@@ -3078,7 +3078,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
 	pVBInfo->SetFlag = 0;
-	pVBInfo->ModeType = modeflag & ModeInfoFlag;
+	pVBInfo->ModeType = modeflag & ModeTypeMask;
 	tempbx = 0;
 
 	if (pVBInfo->VBType & 0xFFFF) {
@@ -3090,7 +3090,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		push = push << 8;
 		tempax = temp << 8;
 		tempbx = tempbx | tempax;
-		temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA
+		temp = (SetCRT2ToDualEdge | SetCRT2ToYPbPr525750 | XGI_SetCRT2ToLCDA
 				| SetInSlaveMode | DisableCRT2Display);
 		temp = 0xFFFF ^ temp;
 		tempbx &= temp;
@@ -3103,9 +3103,9 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 			    (HwDeviceExtension->jChipType >= XG40)) {
 				if (pVBInfo->IF_DEF_LVDS == 0) {
 					if (pVBInfo->VBType &
-					    (VB_XGI302B |
-					     VB_XGI301LV |
-					     VB_XGI302LV |
+					    (VB_SIS302B |
+					     VB_SIS301LV |
+					     VB_SIS302LV |
 					     VB_XGI301C)) {
 						if (temp & EnableDualEdge) {
 							tempbx |=
@@ -3113,7 +3113,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 							if (temp & SetToLCDA)
 								tempbx |=
-								  SetCRT2ToLCDA;
+								  XGI_SetCRT2ToLCDA;
 						}
 					}
 				}
@@ -3123,8 +3123,8 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		if (pVBInfo->IF_DEF_YPbPr == 1) {
 			/* [Billy] 07/05/04 */
 			if (((pVBInfo->IF_DEF_LVDS == 0) &&
-			    ((pVBInfo->VBType & VB_XGI301LV) ||
-			    (pVBInfo->VBType & VB_XGI302LV) ||
+			    ((pVBInfo->VBType & VB_SIS301LV) ||
+			    (pVBInfo->VBType & VB_SIS302LV) ||
 			    (pVBInfo->VBType & VB_XGI301C)))) {
 				if (temp & SetYPbPr) {
 					if (pVBInfo->IF_DEF_HiVision == 1) {
@@ -3134,13 +3134,13 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 								pVBInfo->P3d4,
 								0x35);
 						temp &= YPbPrMode;
-						tempbx |= SetCRT2ToHiVisionTV;
+						tempbx |= SetCRT2ToHiVision;
 
 						if (temp != YPbPrMode1080i) {
 							tempbx &=
-							 (~SetCRT2ToHiVisionTV);
+							 (~SetCRT2ToHiVision);
 							tempbx |=
-							 SetCRT2ToYPbPr;
+							 SetCRT2ToYPbPr525750;
 						}
 					}
 				}
@@ -3172,30 +3172,30 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 		if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
 			if (!(pVBInfo->VBType & VB_NoLCD)) {
-				if (tempbx & SetCRT2ToLCDA) {
+				if (tempbx & XGI_SetCRT2ToLCDA) {
 					if (tempbx & SetSimuScanMode)
 						tempbx &= (~(SetCRT2ToLCD |
 							   SetCRT2ToRAMDAC |
-							   SwitchToCRT2));
+							   SwitchCRT2));
 					else
 						tempbx &= (~(SetCRT2ToLCD |
 							     SetCRT2ToRAMDAC |
 							     SetCRT2ToTV |
-							     SwitchToCRT2));
+							     SwitchCRT2));
 				}
 			}
 		}
 
 		/* shampoo add */
 		/* for driver abnormal */
-		if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
+		if (!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
 			if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
 				if (tempbx & SetCRT2ToRAMDAC) {
 					tempbx &= (0xFF00 |
 						   SetCRT2ToRAMDAC |
-						   SwitchToCRT2 |
+						   SwitchCRT2 |
 						   SetSimuScanMode);
-					tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+					tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
 				}
 			} else {
 				tempbx &= (~(SetCRT2ToRAMDAC |
@@ -3208,37 +3208,37 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 			if (tempbx & SetCRT2ToLCD) {
 				tempbx &= (0xFF00 |
 					   SetCRT2ToLCD |
-					   SwitchToCRT2 |
+					   SwitchCRT2 |
 					   SetSimuScanMode);
-				tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+				tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
 			}
 		}
 
 		if (tempbx & SetCRT2ToSCART) {
 			tempbx &= (0xFF00 |
 				   SetCRT2ToSCART |
-				   SwitchToCRT2 |
+				   SwitchCRT2 |
 				   SetSimuScanMode);
-			tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+			tempbx &= (0x00FF | (~SetCRT2ToYPbPr525750));
 		}
 
 		if (pVBInfo->IF_DEF_YPbPr == 1) {
-			if (tempbx & SetCRT2ToYPbPr)
+			if (tempbx & SetCRT2ToYPbPr525750)
 				tempbx &= (0xFF00 |
-					   SwitchToCRT2 |
+					   SwitchCRT2 |
 					   SetSimuScanMode);
 		}
 
 		if (pVBInfo->IF_DEF_HiVision == 1) {
-			if (tempbx & SetCRT2ToHiVisionTV)
+			if (tempbx & SetCRT2ToHiVision)
 				tempbx &= (0xFF00 |
-					   SetCRT2ToHiVisionTV |
-					   SwitchToCRT2 |
+					   SetCRT2ToHiVision |
+					   SwitchCRT2 |
 					   SetSimuScanMode);
 		}
 
 		if (tempax & DisableCRT2Display) { /* Set Display Device Info */
-			if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
+			if (!(tempbx & (SwitchCRT2 | SetSimuScanMode)))
 				tempbx = DisableCRT2Display;
 		}
 
@@ -3246,7 +3246,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 			if ((!(tempbx & DriverMode)) ||
 			    (!(modeflag & CRT2Mode))) {
 				if (pVBInfo->IF_DEF_LCDA == 1) {
-					if (!(tempbx & SetCRT2ToLCDA))
+					if (!(tempbx & XGI_SetCRT2ToLCDA))
 						tempbx |= (SetInSlaveMode |
 							   SetSimuScanMode);
 				}
@@ -3255,9 +3255,9 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 			/* LCD+TV can't support in slave mode
 			 * (Force LCDA+TV->LCDB) */
 			if ((tempbx & SetInSlaveMode) &&
-			    (tempbx & SetCRT2ToLCDA)) {
+			    (tempbx & XGI_SetCRT2ToLCDA)) {
 				tempbx ^= (SetCRT2ToLCD |
-					  SetCRT2ToLCDA |
+					  XGI_SetCRT2ToLCDA |
 					  SetCRT2ToDualEdge);
 				pVBInfo->SetFlag |= ReserveTVOption;
 			}
@@ -3291,43 +3291,43 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
 			temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
 			tempbx = temp;
-			if (tempbx & SetPALTV) {
+			if (tempbx & TVSetPAL) {
 				tempbx &= (SetCHTVOverScan |
-					   SetPALMTV |
-					   SetPALNTV |
-					   SetPALTV);
-				if (tempbx & SetPALMTV)
+					   TVSetPALM |
+					   TVSetPALN |
+					   TVSetPAL);
+				if (tempbx & TVSetPALM)
 					/* set to NTSC if PAL-M */
-					tempbx &= ~SetPALTV;
+					tempbx &= ~TVSetPAL;
 			} else
 				tempbx &= (SetCHTVOverScan |
-					   SetNTSCJ |
-					   SetPALTV);
+					   TVSetNTSCJ |
+					   TVSetPAL);
 		}
 
 		if (pVBInfo->IF_DEF_LVDS == 0) {
 			if (pVBInfo->VBInfo & SetCRT2ToSCART)
-				tempbx |= SetPALTV;
+				tempbx |= TVSetPAL;
 		}
 
 		if (pVBInfo->IF_DEF_YPbPr == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+			if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
 				index1 = xgifb_reg_get(pVBInfo->P3d4, 0x35);
 				index1 &= YPbPrMode;
 
 				if (index1 == YPbPrMode525i)
-					tempbx |= SetYPbPrMode525i;
+					tempbx |= TVSetYPbPr525i;
 
 				if (index1 == YPbPrMode525p)
-					tempbx = tempbx | SetYPbPrMode525p;
+					tempbx = tempbx | TVSetYPbPr525p;
 				if (index1 == YPbPrMode750p)
-					tempbx = tempbx | SetYPbPrMode750p;
+					tempbx = tempbx | TVSetYPbPr750p;
 			}
 		}
 
 		if (pVBInfo->IF_DEF_HiVision == 1) {
-			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
-				tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
+			if (pVBInfo->VBInfo & SetCRT2ToHiVision)
+				tempbx = tempbx | TVSetHiVision | TVSetPAL;
 		}
 
 		if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
@@ -3335,25 +3335,25 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 			    (!(pVBInfo->VBInfo & SetNotSimuMode)))
 				tempbx |= TVSimuMode;
 
-			if (!(tempbx & SetPALTV) &&
+			if (!(tempbx & TVSetPAL) &&
 			    (modeflag > 13) &&
 			    (resinfo == 8)) /* NTSC 1024x768, */
 				tempbx |= NTSC1024x768;
 
 			tempbx |= RPLLDIV2XO;
 
-			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+			if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 				if (pVBInfo->VBInfo & SetInSlaveMode)
 					tempbx &= (~RPLLDIV2XO);
 			} else {
 				if (tempbx &
-				    (SetYPbPrMode525p | SetYPbPrMode750p))
+				    (TVSetYPbPr525p | TVSetYPbPr750p))
 					tempbx &= (~RPLLDIV2XO);
 				else if (!(pVBInfo->VBType &
-					 (VB_XGI301B |
-					  VB_XGI302B |
-					  VB_XGI301LV |
-					  VB_XGI302LV |
+					 (VB_SIS301B |
+					  VB_SIS302B |
+					  VB_SIS301LV |
+					  VB_SIS302LV |
 					  VB_XGI301C))) {
 					if (tempbx & TVSimuMode)
 						tempbx &= (~RPLLDIV2XO);
@@ -3386,13 +3386,13 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
 	tempbx = temp & 0x0F;
 
 	if (tempbx == 0)
-		tempbx = Panel1024x768; /* default */
+		tempbx = Panel_1024x768; /* default */
 
 	/* LCD75 [2003/8/22] Vicent */
-	if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
+	if ((tempbx == Panel_1024x768) || (tempbx == Panel_1280x1024)) {
 		if (pVBInfo->VBInfo & DriverMode) {
 			tempax = xgifb_reg_get(pVBInfo->P3d4, 0x33);
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+			if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
 				tempax &= 0x0F;
 			else
 				tempax = tempax >> 4;
@@ -3411,7 +3411,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
 
 	/* End of LCD75 */
 
-	if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+	if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
 		return 0;
 
 	tempbx = 0;
@@ -3427,30 +3427,30 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
 	tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
 
 	if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
-		if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
-				& VB_XGI301C)) && (tempax & LCDDualLink)) {
+		if (((pVBInfo->VBType & VB_SIS302LV) || (pVBInfo->VBType
+				& VB_XGI301C)) && (tempax & XGI_LCDDualLink)) {
 			tempbx |= SetLCDDualLink;
 		}
 	}
 
 	if (pVBInfo->IF_DEF_LVDS == 0) {
-		if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo
+		if ((pVBInfo->LCDResInfo == Panel_1400x1050) && (pVBInfo->VBInfo
 				& SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo
 				== 9) && (!(tempbx & EnableScalingLCD)))
-			/* set to center in 1280x1024 LCDB for Panel1400x1050 */
+			/* set to center in 1280x1024 LCDB for Panel_1400x1050 */
 			tempbx |= SetLCDtoNonExpanding;
 	}
 
 	if (pVBInfo->IF_DEF_ExpLink == 1) {
 		if (modeflag & HalfDCLK) {
 			if (!(tempbx & SetLCDtoNonExpanding)) {
-				tempbx |= EnableLVDSDDA;
+				tempbx |= XGI_EnableLVDSDDA;
 			} else {
 				if (ModeNo > 0x13) {
 					if (pVBInfo->LCDResInfo
-							== Panel1024x768) {
+							== Panel_1024x768) {
 						if (resinfo == 4) {/* 512x384 */
-							tempbx |= EnableLVDSDDA;
+							tempbx |= XGI_EnableLVDSDDA;
 						}
 					}
 				}
@@ -3460,9 +3460,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
 
 	if (pVBInfo->VBInfo & SetInSlaveMode) {
 		if (pVBInfo->VBInfo & SetNotSimuMode)
-			tempbx |= LCDVESATiming;
+			tempbx |= XGI_LCDVESATiming;
 	} else {
-		tempbx |= LCDVESATiming;
+		tempbx |= XGI_LCDVESATiming;
 	}
 
 	pVBInfo->LCDInfo = tempbx;
@@ -3477,7 +3477,7 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
 							  SetInSlaveMode |
 							  SetCRT2ToLCD);
 						pVBInfo->VBInfo |=
-							SetCRT2ToLCDA |
+							XGI_SetCRT2ToLCDA |
 							SetCRT2ToDualEdge;
 					}
 				}
@@ -3801,27 +3801,27 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
 
 	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
 		if (pVBInfo->IF_DEF_LVDS == 0) {
-			if (pVBInfo->LCDResInfo == Panel1600x1200) {
-				if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+			if (pVBInfo->LCDResInfo == Panel_1600x1200) {
+				if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
 					if (yres == 1024)
 						yres = 1056;
 				}
 			}
 
-			if (pVBInfo->LCDResInfo == Panel1280x1024) {
+			if (pVBInfo->LCDResInfo == Panel_1280x1024) {
 				if (yres == 400)
 					yres = 405;
 				else if (yres == 350)
 					yres = 360;
 
-				if (pVBInfo->LCDInfo & LCDVESATiming) {
+				if (pVBInfo->LCDInfo & XGI_LCDVESATiming) {
 					if (yres == 360)
 						yres = 375;
 				}
 			}
 
-			if (pVBInfo->LCDResInfo == Panel1024x768) {
-				if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+			if (pVBInfo->LCDResInfo == Panel_1024x768) {
+				if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
 					if (!(pVBInfo->LCDInfo
 							& LCDNonExpanding)) {
 						if (yres == 350)
@@ -3848,7 +3848,7 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
 static unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
 {
 
-	if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+	if ((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) &&
 			(pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
 		return 1;
 
@@ -3918,8 +3918,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 {
 	unsigned short tempax = 0, tempbx, modeflag, resinfo;
 
-	struct XGI_LCDDataStruct *LCDPtr = NULL;
-	struct XGI_TVDataStruct *TVPtr = NULL;
+	struct SiS_LCDData *LCDPtr = NULL;
+	struct SiS_TVData *TVPtr = NULL;
 
 	if (ModeNo <= 0x13) {
 		/* si+St_ResInfo */
@@ -3942,8 +3942,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempbx = 4;
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-		LCDPtr = (struct XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx,
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+		LCDPtr = (struct SiS_LCDData *) XGI_GetLcdPtr(tempbx,
 				ModeNo, ModeIdIndex, RefreshRateTableIndex,
 				pVBInfo);
 
@@ -3954,11 +3954,11 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 		pVBInfo->HT = LCDPtr->LCDHT;
 		pVBInfo->VT = LCDPtr->LCDVT;
 
-		if (pVBInfo->LCDResInfo == Panel1024x768) {
+		if (pVBInfo->LCDResInfo == Panel_1024x768) {
 			tempax = 1024;
 			tempbx = 768;
 
-			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+			if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
 				if (pVBInfo->VGAVDE == 357)
 					tempbx = 527;
 				else if (pVBInfo->VGAVDE == 420)
@@ -3971,10 +3971,10 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 					tempbx = 768;
 			} else
 				tempbx = 768;
-		} else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
+		} else if (pVBInfo->LCDResInfo == Panel_1024x768x75) {
 			tempax = 1024;
 			tempbx = 768;
-		} else if (pVBInfo->LCDResInfo == Panel1280x1024) {
+		} else if (pVBInfo->LCDResInfo == Panel_1280x1024) {
 			tempax = 1280;
 			if (pVBInfo->VGAVDE == 360)
 				tempbx = 768;
@@ -3984,10 +3984,10 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 				tempbx = 864;
 			else
 				tempbx = 1024;
-		} else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
+		} else if (pVBInfo->LCDResInfo == Panel_1280x1024x75) {
 			tempax = 1280;
 			tempbx = 1024;
-		} else if (pVBInfo->LCDResInfo == Panel1280x960) {
+		} else if (pVBInfo->LCDResInfo == Panel_1280x960) {
 			tempax = 1280;
 			if (pVBInfo->VGAVDE == 350)
 				tempbx = 700;
@@ -3997,7 +3997,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 				tempbx = 960;
 			else
 				tempbx = 960;
-		} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+		} else if (pVBInfo->LCDResInfo == Panel_1400x1050) {
 			tempax = 1400;
 			tempbx = 1050;
 
@@ -4005,10 +4005,10 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 				tempax = 1280;
 				tempbx = 1024;
 			}
-		} else if (pVBInfo->LCDResInfo == Panel1600x1200) {
+		} else if (pVBInfo->LCDResInfo == Panel_1600x1200) {
 			tempax = 1600;
 			tempbx = 1200; /* alan 10/14/2003 */
-			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+			if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
 				if (pVBInfo->VGAVDE == 350)
 					tempbx = 875;
 				else if (pVBInfo->VGAVDE == 400)
@@ -4028,7 +4028,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
 		tempbx = 4;
-		TVPtr = (struct XGI_TVDataStruct *) XGI_GetTVPtr(tempbx,
+		TVPtr = (struct SiS_TVData *) XGI_GetTVPtr(tempbx,
 				ModeNo, ModeIdIndex, RefreshRateTableIndex,
 				pVBInfo);
 
@@ -4041,7 +4041,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 		pVBInfo->RVBHRS = TVPtr->RVBHRS;
 		pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
 
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+		if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 			if (resinfo == 0x08)
 				pVBInfo->NewFlickerMode = 0x40;
 			else if (resinfo == 0x09)
@@ -4066,16 +4066,16 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 					}
 				}
 			}
-		} else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-			if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+		} else if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+			if (pVBInfo->TVInfo & TVSetYPbPr750p) {
 				tempax = YPbPrTV750pHT; /* Ext750pTVHT */
 				tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
 			}
 
-			if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+			if (pVBInfo->TVInfo & TVSetYPbPr525p) {
 				tempax = YPbPrTV525pHT; /* Ext525pTVHT */
 				tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
-			} else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+			} else if (pVBInfo->TVInfo & TVSetYPbPr525i) {
 				tempax = YPbPrTV525iHT; /* Ext525iTVHT */
 				tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
 				if (pVBInfo->TVInfo & NTSC1024x768)
@@ -4084,7 +4084,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex,
 		} else {
 			tempax = PALHT;
 			tempbx = PALVT;
-			if (!(pVBInfo->TVInfo & SetPALTV)) {
+			if (!(pVBInfo->TVInfo & TVSetPAL)) {
 				tempax = NTSCHT;
 				tempbx = NTSCVT;
 				if (pVBInfo->TVInfo & NTSC1024x768)
@@ -4109,7 +4109,7 @@ static void XGI_SetCRT2VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
 	XGI_GetVCLKLen(tempal, &di_0, &di_1, pVBInfo);
 	XGI_GetLCDVCLKPtr(&di_0, &di_1, pVBInfo);
 
-	if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 */
+	if (pVBInfo->VBType & VB_SIS301) { /* shampoo 0129 */
 		/* 301 */
 		xgifb_reg_set(pVBInfo->Part4Port, 0x0A, 0x10);
 		xgifb_reg_set(pVBInfo->Part4Port, 0x0B, di_1);
@@ -4139,7 +4139,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeNo,
 	else
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	index = (modeflag & ModeInfoFlag) - ModeEGA;
+	index = (modeflag & ModeTypeMask) - ModeEGA;
 
 	if (index < 0)
 		index = 0;
@@ -4435,7 +4435,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	xgifb_reg_set(pVBInfo->Part1Port, 0x03, temp);
 	tempcx = 0x08;
 
-	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+	if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
 		modeflag |= Charx8Dot;
 
 	tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
@@ -4451,12 +4451,12 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp = (tempbx & 0xFF00) >> 8;
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		if (!(pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)))
+		if (!(pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+				| VB_SIS302LV | VB_XGI301C)))
 			temp += 2;
 
-		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-			if (pVBInfo->VBType & VB_XGI301LV) {
+		if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+			if (pVBInfo->VBType & VB_SIS301LV) {
 				if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
 					if (resinfo == 7)
 						temp -= 2;
@@ -4487,7 +4487,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempax = (tempax / tempcx) - 5;
 	tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 		temp = (tempbx & 0x00FF) - 1;
 		if (!(modeflag & HalfDCLK)) {
 			temp -= 6;
@@ -4513,19 +4513,19 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 			}
 		} else if (!(modeflag & HalfDCLK)) {
 			temp -= 4;
-			if (pVBInfo->LCDResInfo != Panel1280x960 &&
+			if (pVBInfo->LCDResInfo != Panel_1280x960 &&
 			    pVBInfo->VGAHDE >= 800) {
 				temp -= 7;
 				if (pVBInfo->ModeType == ModeEGA &&
 				    pVBInfo->VGAVDE == 1024) {
 					temp += 15;
 					if (pVBInfo->LCDResInfo !=
-						Panel1280x1024)
+						Panel_1280x1024)
 						temp += 7;
 				}
 
 				if (pVBInfo->VGAHDE >= 1280 &&
-				    pVBInfo->LCDResInfo != Panel1280x960 &&
+				    pVBInfo->LCDResInfo != Panel_1280x960 &&
 				    (pVBInfo->LCDInfo & LCDNonExpanding))
 					temp += 28;
 			}
@@ -4619,8 +4619,8 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	push2 = tempbx;
 
 	if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-		if (pVBInfo->LCDResInfo == Panel1024x768) {
-			if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+		if (pVBInfo->LCDResInfo == Panel_1024x768) {
+			if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
 				if (tempbx == 350)
 					tempbx += 5;
 				if (tempbx == 480)
@@ -4669,19 +4669,19 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 		tempbx += tempax;
 	}
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		if (pVBInfo->VBType & VB_XGI301LV) {
-			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+		if (pVBInfo->VBType & VB_SIS301LV) {
+			if (pVBInfo->TVInfo & TVSetHiVision) {
 				tempbx -= 10;
 			} else {
 				if (pVBInfo->TVInfo & TVSimuMode) {
-					if (pVBInfo->TVInfo & SetPALTV) {
+					if (pVBInfo->TVInfo & TVSetPAL) {
 						if (pVBInfo->VBType &
-						    VB_XGI301LV) {
+						    VB_SIS301LV) {
 							if (!(pVBInfo->TVInfo &
-							    (SetYPbPrMode525p |
-							    SetYPbPrMode750p |
-							    SetYPbPrMode1080i)))
+							    (TVSetYPbPr525p |
+							    TVSetYPbPr750p |
+							    TVSetHiVision)))
 								tempbx += 40;
 						} else {
 							tempbx += 40;
@@ -4694,12 +4694,12 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 		}
 	} else {
 		if (pVBInfo->TVInfo & TVSimuMode) {
-			if (pVBInfo->TVInfo & SetPALTV) {
-				if (pVBInfo->VBType & VB_XGI301LV) {
+			if (pVBInfo->TVInfo & TVSetPAL) {
+				if (pVBInfo->VBType & VB_SIS301LV) {
 					if (!(pVBInfo->TVInfo &
-					    (SetYPbPrMode525p |
-					     SetYPbPrMode750p |
-					     SetYPbPrMode1080i)))
+					    (TVSetYPbPr525p |
+					     TVSetYPbPr750p |
+					     TVSetHiVision)))
 						tempbx += 40;
 				} else {
 					tempbx += 40;
@@ -4713,7 +4713,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	tempax += tempbx;
 	push1 = tempax; /* push ax */
 
-	if ((pVBInfo->TVInfo & SetPALTV)) {
+	if ((pVBInfo->TVInfo & TVSetPAL)) {
 		if (tempbx <= 513) {
 			if (tempax >= 513)
 				tempbx = 513;
@@ -4761,7 +4761,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	temp = (temp >> 1) & 0x09;
 
-	if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+	if (pVBInfo->VBType & (VB_SIS301LV | VB_SIS302LV | VB_XGI301C))
 		temp |= 0x01;
 
 	xgifb_reg_set(pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
@@ -4813,13 +4813,13 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	if (pVBInfo->VBInfo & SetCRT2ToSCART)
 		tempax |= 0x0200;
 
-	if (!(pVBInfo->TVInfo & SetPALTV))
+	if (!(pVBInfo->TVInfo & TVSetPAL))
 		tempax |= 0x1000;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision)
 		tempax |= 0x0100;
 
-	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+	if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
 		tempax &= 0xfe00;
 
 	tempax = (tempax & 0xff00) >> 8;
@@ -4827,10 +4827,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	xgifb_reg_set(pVBInfo->Part2Port, 0x0, tempax);
 	TimingPoint = pVBInfo->NTSCTiming;
 
-	if (pVBInfo->TVInfo & SetPALTV)
+	if (pVBInfo->TVInfo & TVSetPAL)
 		TimingPoint = pVBInfo->PALTiming;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 		TimingPoint = pVBInfo->HiTVExtTiming;
 
 		if (pVBInfo->VBInfo & SetInSlaveMode)
@@ -4843,14 +4843,14 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 			TimingPoint = pVBInfo->HiTVTextTiming;
 	}
 
-	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-		if (pVBInfo->TVInfo & SetYPbPrMode525i)
+	if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+		if (pVBInfo->TVInfo & TVSetYPbPr525i)
 			TimingPoint = pVBInfo->YPbPr525iTiming;
 
-		if (pVBInfo->TVInfo & SetYPbPrMode525p)
+		if (pVBInfo->TVInfo & TVSetYPbPr525p)
 			TimingPoint = pVBInfo->YPbPr525pTiming;
 
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+		if (pVBInfo->TVInfo & TVSetYPbPr750p)
 			TimingPoint = pVBInfo->YPbPr750pTiming;
 	}
 
@@ -4868,10 +4868,10 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp &= 0x80;
 	xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0xFF, temp);
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision)
 		tempax = 950;
 
-	if (pVBInfo->TVInfo & SetPALTV)
+	if (pVBInfo->TVInfo & TVSetPAL)
 		tempax = 520;
 	else
 		tempax = 440;
@@ -4884,15 +4884,15 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 		temp = (tempax & 0xFF00) >> 8;
 		temp += (unsigned short) TimingPoint[0];
 
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+				| VB_SIS302LV | VB_XGI301C)) {
 			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
 					| SetCRT2ToSVIDEO | SetCRT2ToSCART
-					| SetCRT2ToYPbPr)) {
+					| SetCRT2ToYPbPr525750)) {
 				tempcx = pVBInfo->VGAHDE;
 				if (tempcx >= 1024) {
 					temp = 0x17; /* NTSC */
-					if (pVBInfo->TVInfo & SetPALTV)
+					if (pVBInfo->TVInfo & TVSetPAL)
 						temp = 0x19; /* PAL */
 				}
 			}
@@ -4903,15 +4903,15 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 		temp = (tempax & 0xFF00) >> 8;
 		temp += TimingPoint[1];
 
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+				| VB_SIS302LV | VB_XGI301C)) {
 			if ((pVBInfo->VBInfo & (SetCRT2ToAVIDEO
 					| SetCRT2ToSVIDEO | SetCRT2ToSCART
-					| SetCRT2ToYPbPr))) {
+					| SetCRT2ToYPbPr525750))) {
 				tempcx = pVBInfo->VGAHDE;
 				if (tempcx >= 1024) {
 					temp = 0x1D; /* NTSC */
-					if (pVBInfo->TVInfo & SetPALTV)
+					if (pVBInfo->TVInfo & TVSetPAL)
 						temp = 0x52; /* PAL */
 				}
 			}
@@ -4936,7 +4936,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	push1 = tempcx; /* push cx */
 	tempcx += 7;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision)
 		tempcx -= 4;
 
 	temp = tempcx & 0x00FF;
@@ -4954,7 +4954,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempbx = push2;
 	tempbx = tempbx + 8;
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 		tempbx = tempbx - 4;
 		tempcx = tempbx;
 	}
@@ -4970,7 +4970,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	xgifb_reg_and_or(pVBInfo->Part2Port, 0x28, 0x0F, temp);
 
 	tempcx += 8;
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision)
 		tempcx -= 4;
 
 	temp = tempcx & 0xFF;
@@ -5005,9 +5005,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
 		if (pVBInfo->VBType &
-		    (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+		    (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
 			if (!(pVBInfo->TVInfo &
-			    (SetYPbPrMode525p | SetYPbPrMode750p)))
+			    (TVSetYPbPr525p | TVSetYPbPr750p)))
 				tempbx = tempbx >> 1;
 		} else
 			tempbx = tempbx >> 1;
@@ -5016,9 +5016,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	tempbx -= 2;
 	temp = tempbx & 0x00FF;
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
-		if (pVBInfo->VBType & VB_XGI301LV) {
-			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
+		if (pVBInfo->VBType & VB_SIS301LV) {
+			if (pVBInfo->TVInfo & TVSetHiVision) {
 				if (pVBInfo->VBInfo & SetInSlaveMode) {
 					if (ModeNo == 0x2f)
 						temp += 1;
@@ -5037,9 +5037,9 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp = (tempcx & 0xFF00) >> 8;
 	temp |= ((tempbx & 0xFF00) >> 8) << 6;
 
-	if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
-		if (pVBInfo->VBType & VB_XGI301LV) {
-			if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+	if (!(pVBInfo->VBInfo & SetCRT2ToHiVision)) {
+		if (pVBInfo->VBType & VB_SIS301LV) {
+			if (pVBInfo->TVInfo & TVSetHiVision) {
 				temp |= 0x10;
 
 				if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
@@ -5054,18 +5054,18 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	xgifb_reg_set(pVBInfo->Part2Port, 0x30, temp);
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) { /* TV gatingno */
 		tempbx = pVBInfo->VDE;
 		tempcx = tempbx - 2;
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
-					| SetYPbPrMode750p)))
+			if (!(pVBInfo->TVInfo & (TVSetYPbPr525p
+					| TVSetYPbPr750p)))
 				tempbx = tempbx >> 1;
 		}
 
-		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
 			temp = 0;
 			if (tempcx & 0x0400)
 				temp |= 0x20;
@@ -5118,8 +5118,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 		/* 301b */
 		tempecx = 8 * 1024;
 
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+				| VB_SIS302LV | VB_XGI301C)) {
 			tempecx = tempecx * 8;
 		}
 
@@ -5133,8 +5133,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 		tempax = (unsigned short) tempeax;
 
 		/* 301b */
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+				| VB_SIS302LV | VB_XGI301C)) {
 			tempcx = ((tempax & 0xFF00) >> 5) >> 8;
 		}
 		/* end 301b */
@@ -5161,7 +5161,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 		temp |= 0x18;
 
 	xgifb_reg_and_or(pVBInfo->Part2Port, 0x46, ~0x1F, temp);
-	if (pVBInfo->TVInfo & SetPALTV) {
+	if (pVBInfo->TVInfo & TVSetPAL) {
 		tempbx = 0x0382;
 		tempcx = 0x007e;
 	} else {
@@ -5178,13 +5178,13 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp = temp << 2;
 	temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
 
-	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+	if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
 		temp |= 0x10;
 
-		if (pVBInfo->TVInfo & SetYPbPrMode525p)
+		if (pVBInfo->TVInfo & TVSetYPbPr525p)
 			temp |= 0x20;
 
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+		if (pVBInfo->TVInfo & TVSetYPbPr750p)
 			temp |= 0x60;
 	}
 
@@ -5192,7 +5192,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp = xgifb_reg_get(pVBInfo->Part2Port, 0x43); /* 301b change */
 	xgifb_reg_set(pVBInfo->Part2Port, 0x43, (unsigned short) (temp - 3));
 
-	if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
+	if (!(pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))) {
 		if (pVBInfo->TVInfo & NTSC1024x768) {
 			TimingPoint = XGI_NTSC1024AdjTime;
 			for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
@@ -5205,12 +5205,12 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	/* [ycchen] 01/14/03 Modify for 301C PALM Support */
 	if (pVBInfo->VBType & VB_XGI301C) {
-		if (pVBInfo->TVInfo & SetPALMTV)
+		if (pVBInfo->TVInfo & TVSetPALM)
 			xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x08,
 					0x08); /* PALM Mode */
 	}
 
-	if (pVBInfo->TVInfo & SetPALMTV) {
+	if (pVBInfo->TVInfo & TVSetPALM) {
 		tempax = (unsigned char) xgifb_reg_get(pVBInfo->Part2Port,
 				0x01);
 		tempax--;
@@ -5219,7 +5219,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex,
 		xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xEF);
 	}
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision) {
 		if (!(pVBInfo->VBInfo & SetInSlaveMode))
 			xgifb_reg_set(pVBInfo->Part2Port, 0x0B, 0x00);
 	}
@@ -5267,11 +5267,11 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	xgifb_reg_and_or(pVBInfo->Part2Port, 0x2B, 0x0F, temp);
 	temp = 0x01;
 
-	if (pVBInfo->LCDResInfo == Panel1280x1024) {
+	if (pVBInfo->LCDResInfo == Panel_1280x1024) {
 		if (pVBInfo->ModeType == ModeEGA) {
 			if (pVBInfo->VGAHDE >= 1024) {
 				temp = 0x02;
-				if (pVBInfo->LCDInfo & LCDVESATiming)
+				if (pVBInfo->LCDInfo & XGI_LCDVESATiming)
 					temp = 0x01;
 			}
 		}
@@ -5305,14 +5305,14 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	tempah = pVBInfo->LCDResInfo;
 	tempah &= PanelResInfo;
 
-	if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) {
+	if ((tempah == Panel_1024x768) || (tempah == Panel_1024x768x75)) {
 		tempbx = 1024;
 		tempcx = 768;
-	} else if ((tempah == Panel1280x1024) ||
-		   (tempah == Panel1280x1024x75)) {
+	} else if ((tempah == Panel_1280x1024) ||
+		   (tempah == Panel_1280x1024x75)) {
 		tempbx = 1280;
 		tempcx = 1024;
-	} else if (tempah == Panel1400x1050) {
+	} else if (tempah == Panel_1400x1050) {
 		tempbx = 1400;
 		tempcx = 1050;
 	} else {
@@ -5375,7 +5375,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 		tempcx = tempcx >> 1;
 	}
 
-	if (pVBInfo->VBType & VB_XGI302LV)
+	if (pVBInfo->VBType & VB_SIS302LV)
 		tempbx += 1;
 
 	if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
@@ -5405,7 +5405,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 		tempcx = tempcx >> 1;
 	}
 
-	if (pVBInfo->VBType & VB_XGI302LV)
+	if (pVBInfo->VBType & VB_SIS302LV)
 		tempbx += 1;
 
 	tempcx += tempbx;
@@ -5422,10 +5422,10 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 	temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
 	xgifb_reg_set(pVBInfo->Part2Port, 0x21, temp);
 
-	if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+	if (!(pVBInfo->LCDInfo & XGI_LCDVESATiming)) {
 		if (pVBInfo->VGAVDE == 525) {
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-					| VB_XGI301LV | VB_XGI302LV
+			if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+					| VB_SIS301LV | VB_SIS302LV
 					| VB_XGI301C)) {
 				temp = 0xC6;
 			} else
@@ -5436,8 +5436,8 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex,
 		}
 
 		if (pVBInfo->VGAVDE == 420) {
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-					| VB_XGI301LV | VB_XGI302LV
+			if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+					| VB_SIS301LV | VB_SIS302LV
 					| VB_XGI301C)) {
 				temp = 0x4F;
 			} else
@@ -5473,18 +5473,18 @@ static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx,
 	else
 		Tap4TimingPtr = xgifb_ntsc_525_tap4_timing; /* NTSC */
 
-	if (pVBInfo->TVInfo & SetPALTV)
+	if (pVBInfo->TVInfo & TVSetPAL)
 		Tap4TimingPtr = PALTap4Timing;
 
-	if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
-		if ((pVBInfo->TVInfo & SetYPbPrMode525i) ||
-			(pVBInfo->TVInfo & SetYPbPrMode525p))
+	if (pVBInfo->VBInfo & SetCRT2ToYPbPr525750) {
+		if ((pVBInfo->TVInfo & TVSetYPbPr525i) ||
+			(pVBInfo->TVInfo & TVSetYPbPr525p))
 			Tap4TimingPtr = xgifb_ntsc_525_tap4_timing;
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+		if (pVBInfo->TVInfo & TVSetYPbPr750p)
 			Tap4TimingPtr = YPbPr750pTap4Timing;
 	}
 
-	if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+	if (pVBInfo->VBInfo & SetCRT2ToHiVision)
 		Tap4TimingPtr = xgifb_tap4_timing;
 
 	i = 0;
@@ -5510,7 +5510,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
 		xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
 
 	if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
-	    (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
+	    (!(pVBInfo->VBInfo & SetCRT2ToHiVision))) {
 		/* Set Vertical Scaling */
 		Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
 		for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
@@ -5520,7 +5520,7 @@ static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo)
 	}
 
 	if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
-	    (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
+	    (!(pVBInfo->VBInfo & SetCRT2ToHiVision)))
 		/* Enable V.Scaling */
 		xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
 	else
@@ -5543,7 +5543,7 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
 	xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
-	if (pVBInfo->TVInfo & SetPALTV) {
+	if (pVBInfo->TVInfo & TVSetPAL) {
 		xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
 		xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
 	} else {
@@ -5554,15 +5554,15 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
 	if (!(pVBInfo->VBInfo & SetCRT2ToTV))
 		return;
 
-	if (pVBInfo->TVInfo & SetPALMTV) {
+	if (pVBInfo->TVInfo & TVSetPALM) {
 		xgifb_reg_set(pVBInfo->Part3Port, 0x13, 0xFA);
 		xgifb_reg_set(pVBInfo->Part3Port, 0x14, 0xC8);
 		xgifb_reg_set(pVBInfo->Part3Port, 0x3D, 0xA8);
 	}
 
-	if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV) || (pVBInfo->VBInfo
-			& SetCRT2ToYPbPr)) {
-		if (pVBInfo->TVInfo & SetYPbPrMode525i)
+	if ((pVBInfo->VBInfo & SetCRT2ToHiVision) || (pVBInfo->VBInfo
+			& SetCRT2ToYPbPr525750)) {
+		if (pVBInfo->TVInfo & TVSetYPbPr525i)
 			return;
 
 		tempdi = pVBInfo->HiTVGroup3Data;
@@ -5572,17 +5572,17 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex,
 				tempdi = pVBInfo->HiTVGroup3Text;
 		}
 
-		if (pVBInfo->TVInfo & SetYPbPrMode525p)
+		if (pVBInfo->TVInfo & TVSetYPbPr525p)
 			tempdi = pVBInfo->Ren525pGroup3;
 
-		if (pVBInfo->TVInfo & SetYPbPrMode750p)
+		if (pVBInfo->TVInfo & TVSetYPbPr750p)
 			tempdi = pVBInfo->Ren750pGroup3;
 
 		for (i = 0; i <= 0x3E; i++)
 			xgifb_reg_set(pVBInfo->Part3Port, i, tempdi[i]);
 
 		if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
-			if (pVBInfo->TVInfo & SetYPbPrMode525p)
+			if (pVBInfo->TVInfo & TVSetYPbPr525p)
 				xgifb_reg_set(pVBInfo->Part3Port, 0x28, 0x3f);
 		}
 	}
@@ -5637,7 +5637,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 	if (XGI_IsLCDDualLink(pVBInfo))
 		tempbx = tempbx >> 1;
 
-	if (tempcx & SetCRT2ToHiVisionTV) {
+	if (tempcx & SetCRT2ToHiVision) {
 		temp = 0;
 		if (tempbx <= 1024)
 			temp = 0xA0;
@@ -5656,7 +5656,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 		}
 	}
 
-	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
+	if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p)) {
 		temp = 0x00;
 		if (pVBInfo->VGAHDE == 1280)
 			temp = 0x40;
@@ -5667,7 +5667,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 	tempebx = pVBInfo->VDE;
 
-	if (tempcx & SetCRT2ToHiVisionTV) {
+	if (tempcx & SetCRT2ToHiVision) {
 		if (!(temp & 0xE000))
 			tempbx = tempbx >> 1;
 	}
@@ -5705,8 +5705,8 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 	xgifb_reg_set(pVBInfo->Part4Port, 0x19, temp);
 
 	/* 301b */
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		temp = 0x0028;
 		xgifb_reg_set(pVBInfo->Part4Port, 0x1C, temp);
 		tempax = pVBInfo->VGAHDE;
@@ -5735,7 +5735,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 		temp = (tempax & 0x00FF);
 		xgifb_reg_set(pVBInfo->Part4Port, 0x1D, temp);
 
-		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVision)) {
 			if (pVBInfo->VGAHDE > 800)
 				xgifb_reg_or(pVBInfo->Part4Port, 0x1E, 0x08);
 
@@ -5744,8 +5744,8 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex,
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
 			if (!(pVBInfo->TVInfo & (NTSC1024x768
-					| SetYPbPrMode525p | SetYPbPrMode750p
-					| SetYPbPrMode1080i))) {
+					| TVSetYPbPr525p | TVSetYPbPr750p
+					| TVSetHiVision))) {
 				temp |= 0x0001;
 				if ((pVBInfo->VBInfo & SetInSlaveMode)
 						&& (!(pVBInfo->TVInfo
@@ -5785,7 +5785,7 @@ static void XGI_SetGroup5(unsigned short ModeNo, unsigned short ModeIdIndex,
 	Pdata = pVBInfo->Part5Port + 1;
 	if (pVBInfo->ModeType == ModeVGA) {
 		if (!(pVBInfo->VBInfo & (SetInSlaveMode | LoadDACFlag
-				| CRT2DisplayFlag))) {
+				| DisableCRT2Display))) {
 			XGINew_EnableCRT2(pVBInfo);
 		}
 	}
@@ -6074,7 +6074,7 @@ static unsigned char XGI_IsLCDON(struct vb_device_info *pVBInfo)
 	tempax = pVBInfo->VBInfo;
 	if (tempax & SetCRT2ToDualEdge)
 		return 0;
-	else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
+	else if (tempax & (DisableCRT2Display | SwitchCRT2 | SetSimuScanMode))
 		return 1;
 
 	return 0;
@@ -6140,15 +6140,15 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
 {
 	unsigned short tempah = 0;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		tempah = 0x3F;
 		if (!(pVBInfo->VBInfo &
 		    (DisableCRT2Display | SetSimuScanMode))) {
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+			if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
 					tempah = 0x7F; /* Disable Channel A */
-					if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+					if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
 						/* Disable Channel B */
 						tempah = 0xBF;
 
@@ -6166,8 +6166,8 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
 		/* disable part4_1f */
 		xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
 
-		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
-			if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+		if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
+			if (((pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
 					|| (XGI_DisableChISLCD(pVBInfo))
 					|| (XGI_IsLCDON(pVBInfo)))
 				/* LVDS Driver power down */
@@ -6175,16 +6175,16 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
 		}
 
 		if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
-				& (DisableCRT2Display | SetCRT2ToLCDA
+				& (DisableCRT2Display | XGI_SetCRT2ToLCDA
 						| SetSimuScanMode))) {
 			if (pVBInfo->SetFlag & GatingCRT)
 				XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
 			XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
 		}
 
-		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+		if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 			if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
-					& SetCRT2ToLCDA))
+					& XGI_SetCRT2ToLCDA))
 				/* Power down */
 				xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
 		}
@@ -6198,7 +6198,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
 		if ((pVBInfo->SetFlag & DisableChB) ||
 		    (pVBInfo->VBInfo &
 			(DisableCRT2Display | SetSimuScanMode)) ||
-		    ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) &&
+		    ((!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) &&
 		    (pVBInfo->VBInfo &
 			(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
 			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
@@ -6206,7 +6206,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
 		if ((pVBInfo->SetFlag & DisableChB) ||
 		    (pVBInfo->VBInfo &
 			(DisableCRT2Display | SetSimuScanMode)) ||
-		    (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) ||
+		    (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) ||
 		    (pVBInfo->VBInfo &
 			(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
 			/* save Part1 index 0 */
@@ -6227,7 +6227,7 @@ static void XGI_DisableBridge(struct xgifb_video_info *xgifb_info,
 			xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
 		}
 
-		if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
+		if (pVBInfo->VBInfo & (DisableCRT2Display | XGI_SetCRT2ToLCDA
 				| SetSimuScanMode))
 			XGI_DisplayOff(xgifb_info, HwDeviceExtension, pVBInfo);
 	}
@@ -6254,15 +6254,15 @@ static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo)
 {
 	unsigned short tempbx = 0;
 
-	if (pVBInfo->TVInfo & SetPALTV)
+	if (pVBInfo->TVInfo & TVSetPAL)
 		tempbx = 2;
-	if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+	if (pVBInfo->TVInfo & TVSetHiVision)
 		tempbx = 4;
-	if (pVBInfo->TVInfo & SetYPbPrMode525i)
+	if (pVBInfo->TVInfo & TVSetYPbPr525i)
 		tempbx = 6;
-	if (pVBInfo->TVInfo & SetYPbPrMode525p)
+	if (pVBInfo->TVInfo & TVSetYPbPr525p)
 		tempbx = 8;
-	if (pVBInfo->TVInfo & SetYPbPrMode750p)
+	if (pVBInfo->TVInfo & TVSetYPbPr750p)
 		tempbx = 10;
 	if (pVBInfo->TVInfo & TVSimuMode)
 		tempbx++;
@@ -6293,23 +6293,23 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
 	*tempcl = 0;
 	*tempch = 0;
 
-	if (pVBInfo->TVInfo & SetPALTV)
+	if (pVBInfo->TVInfo & TVSetPAL)
 		*tempbx = 1;
 
-	if (pVBInfo->TVInfo & SetPALMTV)
+	if (pVBInfo->TVInfo & TVSetPALM)
 		*tempbx = 2;
 
-	if (pVBInfo->TVInfo & SetPALNTV)
+	if (pVBInfo->TVInfo & TVSetPALN)
 		*tempbx = 3;
 
 	if (pVBInfo->TVInfo & NTSC1024x768) {
 		*tempbx = 4;
-		if (pVBInfo->TVInfo & SetPALMTV)
+		if (pVBInfo->TVInfo & TVSetPALM)
 			*tempbx = 5;
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		if ((!(pVBInfo->VBInfo & SetInSlaveMode)) || (pVBInfo->TVInfo
 				& TVSimuMode)) {
 			*tempbx += 8;
@@ -6317,8 +6317,8 @@ static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl,
 		}
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C))
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C))
 		(*tempch)++;
 }
 
@@ -6328,9 +6328,9 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
 
 	unsigned char tempah, tempbl, tempbh;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA
 				| SetCRT2ToTV | SetCRT2ToRAMDAC)) {
 			tempbl = 0;
 			tempbh = 0;
@@ -6338,20 +6338,20 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
 			index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
 			tempbl = pVBInfo->XGI_TVDelayList[index];
 
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-					| VB_XGI301LV | VB_XGI302LV
+			if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+					| VB_SIS301LV | VB_SIS302LV
 					| VB_XGI301C))
 				tempbl = pVBInfo->XGI_TVDelayList2[index];
 
 			if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
 				tempbl = tempbl >> 4;
-			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+			if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 				/* Get LCD Delay */
 				index = XGI_GetLCDCapPtr(pVBInfo);
 				tempbh = pVBInfo->LCDCapList[index].
 						LCD_DelayCompensation;
 
-				if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+				if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA))
 					tempbl = tempbh;
 			}
 
@@ -6365,7 +6365,7 @@ static void XGI_SetDelayComp(struct vb_device_info *pVBInfo)
 				tempah |= tempbl;
 			}
 
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
+			if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { /* Channel A */
 				tempah &= 0x0F;
 				tempah |= tempbh;
 			}
@@ -6475,13 +6475,13 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
 	tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
 
 	if (pVBInfo->VBType &
-	    (VB_XGI301B |
-	     VB_XGI302B |
-	     VB_XGI301LV |
-	     VB_XGI302LV |
+	    (VB_SIS301B |
+	     VB_SIS302B |
+	     VB_SIS301LV |
+	     VB_SIS302LV |
 	     VB_XGI301C)) { /* 301LV/302LV only */
 		if (pVBInfo->VBType &
-		    (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+		    (VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) {
 			/* Set 301LV Capability */
 			xgifb_reg_set(pVBInfo->Part4Port, 0x24,
 					(unsigned char) (tempcx & 0x1F));
@@ -6493,14 +6493,14 @@ static void XGI_SetLCDCap(struct vb_device_info *pVBInfo)
 						| EnablePLLSPLOW)) >> 8));
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		if (pVBInfo->VBInfo & SetCRT2ToLCD)
 			XGI_SetLCDCap_B(tempcx, pVBInfo);
-		else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+		else if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
 			XGI_SetLCDCap_A(tempcx, pVBInfo);
 
-		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
 			if (tempcx & EnableSpectrum)
 				SetSpectrum(pVBInfo);
 		}
@@ -6524,7 +6524,7 @@ static void XGI_SetAntiFlicker(unsigned short ModeNo,
 
 	unsigned char tempah;
 
-	if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+	if (pVBInfo->TVInfo & (TVSetYPbPr525p | TVSetYPbPr750p))
 		return;
 
 	tempbx = XGI_GetTVPtrIndex(pVBInfo);
@@ -6648,8 +6648,8 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex,
 		xgifb_reg_set(pVBInfo->Part2Port, 0x38, filterPtr[index++]);
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		xgifb_reg_set(pVBInfo->Part2Port, 0x48, filterPtr[index++]);
 		xgifb_reg_set(pVBInfo->Part2Port, 0x49, filterPtr[index++]);
 		xgifb_reg_set(pVBInfo->Part2Port, 0x4A, filterPtr[index++]);
@@ -6668,7 +6668,7 @@ static void XGI_OEM310Setting(unsigned short ModeNo,
 {
 	XGI_SetDelayComp(pVBInfo);
 
-	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+	if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))
 		XGI_SetLCDCap(pVBInfo);
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
@@ -6676,7 +6676,7 @@ static void XGI_OEM310Setting(unsigned short ModeNo,
 		XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
 		XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
 
-		if (pVBInfo->VBType & VB_XGI301)
+		if (pVBInfo->VBType & VB_SIS301)
 			XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
 	}
 }
@@ -6732,15 +6732,15 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
 		tempbl = 0xff;
 
 		if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
-				| SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			if ((pVBInfo->VBInfo & SetCRT2ToLCDA) &&
+				| SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
+			if ((pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) &&
 			    (!(pVBInfo->VBInfo & SetSimuScanMode))) {
 				tempbl &= 0xf7;
 				tempah |= 0x01;
 				xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e,
 						tempbl, tempah);
 			} else {
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+				if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 					tempbl &= 0xf7;
 					tempah |= 0x01;
 				}
@@ -6780,7 +6780,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
 	}
 
 	if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD
-			| SetCRT2ToLCDA)) {
+			| XGI_SetCRT2ToLCDA)) {
 		tempah &= (~0x08);
 		if ((pVBInfo->ModeType == ModeVGA) && (!(pVBInfo->VBInfo
 				& SetInSlaveMode))) {
@@ -6807,24 +6807,24 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
 				tempah |= 0x40;
 		}
 
-		if ((pVBInfo->LCDResInfo == Panel1280x1024)
-				|| (pVBInfo->LCDResInfo == Panel1280x1024x75))
+		if ((pVBInfo->LCDResInfo == Panel_1280x1024)
+				|| (pVBInfo->LCDResInfo == Panel_1280x1024x75))
 			tempah |= 0x80;
 
-		if (pVBInfo->LCDResInfo == Panel1280x960)
+		if (pVBInfo->LCDResInfo == Panel_1280x960)
 			tempah |= 0x80;
 
 		xgifb_reg_set(pVBInfo->Part4Port, 0x0C, tempah);
 	}
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		tempah = 0;
 		tempbl = 0xfb;
 
 		if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
 			tempbl = 0xff;
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+			if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
 				tempah |= 0x04; /* shampoo 0129 */
 		}
 
@@ -6849,7 +6849,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
 
 	tempah = 0;
 	tempbl = 0x7f;
-	if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+	if (!(pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)) {
 		tempbl = 0xff;
 		if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
 			tempah |= 0x80;
@@ -6857,7 +6857,7 @@ static void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
 
 	xgifb_reg_and_or(pVBInfo->Part4Port, 0x23, tempbl, tempah);
 
-	if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
 		if (pVBInfo->LCDInfo & SetLCDDualLink) {
 			xgifb_reg_or(pVBInfo->Part4Port, 0x27, 0x20);
 			xgifb_reg_or(pVBInfo->Part4Port, 0x34, 0x10);
@@ -6872,7 +6872,7 @@ static void XGI_CloseCRTC(struct xgi_hw_device_info *HwDeviceExtension,
 
 	tempbx = 0;
 
-	if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+	if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA)
 		tempbx = 0x08A0;
 
 }
@@ -6937,10 +6937,10 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
 		index--;
 
 	if (pVBInfo->SetFlag & ProgrammingCRT2) {
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) {
 			if (pVBInfo->IF_DEF_LVDS == 0) {
-				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
-						| VB_XGI301LV | VB_XGI302LV
+				if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B
+						| VB_SIS301LV | VB_SIS302LV
 						| VB_XGI301C))
 					/* 301b */
 					temp = LCDARefreshIndex[
@@ -6983,7 +6983,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
 			break;
 		temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].
 			Ext_InfoFlag;
-		temp &= ModeInfoFlag;
+		temp &= ModeTypeMask;
 		if (temp < pVBInfo->ModeType)
 			break;
 		i++;
@@ -7163,8 +7163,8 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
 {
 	unsigned short tempah;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
 		if (!(pVBInfo->SetFlag & DisableChA)) {
 			if (pVBInfo->SetFlag & EnableChA) {
 				/* Power on */
@@ -7207,11 +7207,11 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
 				|| (!(pVBInfo->VBInfo & DisableCRT2Display))) {
 			xgifb_reg_and_or(pVBInfo->Part2Port, 0x00, ~0xE0,
 					0x20); /* shampoo 0129 */
-			if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+			if (pVBInfo->VBType & (VB_SIS302LV | VB_XGI301C)) {
 				if (!XGI_DisableChISLCD(pVBInfo)) {
 					if (XGI_EnableChISLCD(pVBInfo) ||
 					    (pVBInfo->VBInfo &
-					    (SetCRT2ToLCD | SetCRT2ToLCDA)))
+					    (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)))
 						/* LVDS PLL power on */
 						xgifb_reg_and(
 							pVBInfo->Part4Port,
@@ -7229,12 +7229,12 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
 			tempah = 0xc0;
 
 			if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+				if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 					if (pVBInfo->VBInfo &
 					    SetCRT2ToDualEdge) {
 						tempah = tempah & 0x40;
 						if (pVBInfo->VBInfo &
-						    SetCRT2ToLCDA)
+						    XGI_SetCRT2ToLCDA)
 							tempah = tempah ^ 0xC0;
 
 						if (pVBInfo->SetFlag &
@@ -7271,7 +7271,7 @@ static void XGI_EnableBridge(struct xgifb_video_info *xgifb_info,
 	} /* 301 */
 	else { /* LVDS */
 		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
-				| SetCRT2ToLCDA))
+				| XGI_SetCRT2ToLCDA))
 			/* enable CRT2 */
 			xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
 
@@ -7311,9 +7311,9 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info,
 	pVBInfo->SetFlag &= temp;
 	pVBInfo->SelectCRT2Rate = 0;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA
+	if (pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV
+			| VB_SIS302LV | VB_XGI301C)) {
+		if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA
 				| SetInSlaveMode)) {
 			pVBInfo->SetFlag |= ProgrammingCRT2;
 		}
@@ -7415,11 +7415,11 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
 	pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
 	pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
 	pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
-	pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
-	pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
-	pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
-	pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
-	pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
+	pVBInfo->Part1Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_04;
+	pVBInfo->Part2Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_10;
+	pVBInfo->Part3Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_12;
+	pVBInfo->Part4Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14;
+	pVBInfo->Part5Port = pVBInfo->BaseAddr + SIS_CRT2_PORT_14 + 2;
 
 	/* for x86 Linux, XG21 LVDS */
 	if (HwDeviceExtension->jChipType == XG21) {
@@ -7452,20 +7452,20 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
 		XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
 		XGI_DisableBridge(xgifb_info, HwDeviceExtension, pVBInfo);
 
-		if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+		if (pVBInfo->VBInfo & (SetSimuScanMode | XGI_SetCRT2ToLCDA)) {
 			XGI_SetCRT1Group(xgifb_info, HwDeviceExtension, ModeNo,
 					ModeIdIndex, pVBInfo);
 
-			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+			if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 				XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
 						HwDeviceExtension, pVBInfo);
 			}
 		} else {
-			if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
+			if (!(pVBInfo->VBInfo & SwitchCRT2)) {
 				XGI_SetCRT1Group(xgifb_info,
 						HwDeviceExtension, ModeNo,
 						ModeIdIndex, pVBInfo);
-				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+				if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) {
 					XGI_SetLCDAGroup(ModeNo, ModeIdIndex,
 							HwDeviceExtension,
 							pVBInfo);
@@ -7473,7 +7473,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
 			}
 		}
 
-		if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+		if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchCRT2)) {
 			switch (HwDeviceExtension->ujVBChipID) {
 			case VB_CHIP_301:
 				XGI_SetCRT2Group301(ModeNo, HwDeviceExtension,
@@ -7504,10 +7504,10 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info,
 
 		if (ModeNo <= 0x13) {
 			pVBInfo->ModeType = pVBInfo->SModeIDTable[ModeIdIndex].
-						St_ModeFlag & ModeInfoFlag;
+						St_ModeFlag & ModeTypeMask;
 		} else {
 			pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex].
-						Ext_ModeFlag & ModeInfoFlag;
+						Ext_ModeFlag & ModeTypeMask;
 		}
 
 		pVBInfo->SetFlag = 0;
diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h
index 6556a0d..a5bd56a 100644
--- a/drivers/staging/xgifb/vb_struct.h
+++ b/drivers/staging/xgifb/vb_struct.h
@@ -1,15 +1,6 @@
 #ifndef _VB_STRUCT_
 #define _VB_STRUCT_
-
-struct XGI_LCDDataStruct {
-	unsigned short RVBHCMAX;
-	unsigned short RVBHCFACT;
-	unsigned short VGAHT;
-	unsigned short VGAVT;
-	unsigned short LCDHT;
-	unsigned short LCDVT;
-};
-
+#include "../../video/sis/vstruct.h"
 
 struct XGI_LVDSCRT1HDataStruct {
 	unsigned char Reg[8];
@@ -19,22 +10,6 @@ struct XGI_LVDSCRT1VDataStruct {
 	unsigned char Reg[7];
 };
 
-struct XGI_TVDataStruct {
-	unsigned short RVBHCMAX;
-	unsigned short RVBHCFACT;
-	unsigned short VGAHT;
-	unsigned short VGAVT;
-	unsigned short TVHDE;
-	unsigned short TVVDE;
-	unsigned short RVBHRS;
-	unsigned char FlickerMode;
-	unsigned short HALFRVBHRS;
-	unsigned char RY1COE;
-	unsigned char RY2COE;
-	unsigned char RY3COE;
-	unsigned char RY4COE;
-};
-
 struct XGI_StStruct {
 	unsigned char St_ModeID;
 	unsigned short St_ModeFlag;
@@ -47,18 +22,6 @@ struct XGI_StStruct {
 	unsigned char VB_StTVYFilterIndex;
 };
 
-struct XGI_StandTableStruct {
-	unsigned char CRT_COLS;
-	unsigned char ROWS;
-	unsigned char CHAR_HEIGHT;
-	unsigned short CRT_LEN;
-	unsigned char SR[4];
-	unsigned char MISC;
-	unsigned char CRTC[0x19];
-	unsigned char ATTR[0x14];
-	unsigned char GRC[9];
-};
-
 struct XGI_ExtStruct {
 	unsigned char Ext_ModeID;
 	unsigned short Ext_ModeFlag;
@@ -85,39 +48,11 @@ struct XGI_Ext2Struct {
 	/* unsigned short ROM_OFFSET; */
 };
 
-
-struct XGI_MCLKDataStruct {
-	unsigned char SR28, SR29, SR2A;
-	unsigned short CLOCK;
-};
-
 struct XGI_ECLKDataStruct {
 	unsigned char SR2E, SR2F, SR30;
 	unsigned short CLOCK;
 };
 
-struct XGI_VCLKDataStruct {
-	unsigned char SR2B, SR2C;
-	unsigned short CLOCK;
-};
-
-struct XGI_VBVCLKDataStruct {
-	unsigned char Part4_A, Part4_B;
-	unsigned short CLOCK;
-};
-
-struct XGI_StResInfoStruct {
-	unsigned short HTotal;
-	unsigned short VTotal;
-};
-
-struct XGI_ModeResInfoStruct {
-	unsigned short HTotal;
-	unsigned short VTotal;
-	unsigned char  XChar;
-	unsigned char  YChar;
-};
-
 /*add for new UNIVGABIOS*/
 struct XGI_LCDDesStruct {
 	unsigned short LCDHDES;
@@ -350,7 +285,7 @@ struct vb_device_info {
 	unsigned char  *pCRT2Data_4_D;
 	unsigned char  *pCRT2Data_4_E;
 	unsigned char  *pCRT2Data_4_10;
-	struct XGI_MCLKDataStruct  *MCLKData;
+	struct SiS_MCLKData  *MCLKData;
 	struct XGI_ECLKDataStruct  *ECLKData;
 
 	unsigned char   *XGI_TVDelayList;
@@ -380,15 +315,15 @@ struct vb_device_info {
 	struct XGI_TimingVStruct  *TimingV;
 
 	struct XGI_StStruct          *SModeIDTable;
-	struct XGI_StandTableStruct  *StandTable;
+	struct SiS_StandTable_S  *StandTable;
 	struct XGI_ExtStruct         *EModeIDTable;
 	struct XGI_Ext2Struct        *RefIndex;
 	/* XGINew_CRT1TableStruct *CRT1Table; */
 	struct XGI_CRT1TableStruct    *XGINEWUB_CRT1Table;
-	struct XGI_VCLKDataStruct    *VCLKData;
-	struct XGI_VBVCLKDataStruct  *VBVCLKData;
-	struct XGI_StResInfoStruct   *StResInfo;
-	struct XGI_ModeResInfoStruct *ModeResInfo;
+	struct SiS_VCLKData    *VCLKData;
+	struct SiS_VBVCLKData  *VBVCLKData;
+	struct SiS_StResInfo_S   *StResInfo;
+	struct SiS_ModeResInfo_S *ModeResInfo;
 	struct XGI_XG21CRT1Struct	  *UpdateCRT1;
 
 	int ram_type;
diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h
index e7946f1..dddf261 100644
--- a/drivers/staging/xgifb/vb_table.h
+++ b/drivers/staging/xgifb/vb_table.h
@@ -1,5 +1,5 @@
 /* yilin modify for xgi20 */
-static struct XGI_MCLKDataStruct XGI340New_MCLKData[] = {
+static struct SiS_MCLKData XGI340New_MCLKData[] = {
 	{0x16, 0x01, 0x01, 166},
 	{0x19, 0x02, 0x01, 124},
 	{0x7C, 0x08, 0x01, 200},
@@ -10,7 +10,7 @@ static struct XGI_MCLKDataStruct XGI340New_MCLKData[] = {
 	{0x5c, 0x23, 0x01, 166}
 };
 
-static struct XGI_MCLKDataStruct XGI27New_MCLKData[] = {
+static struct SiS_MCLKData XGI27New_MCLKData[] = {
 	{0x5c, 0x23, 0x01, 166},
 	{0x19, 0x02, 0x01, 124},
 	{0x7C, 0x08, 0x80, 200},
@@ -296,7 +296,7 @@ static struct XGI_ExtStruct XGI330_EModeIDTable[] = {
 		0x00, 0x00, 0x00, 0x00, 0x00}
 };
 
-static struct XGI_StandTableStruct XGI330_StandTable[] = {
+static struct SiS_StandTable_S XGI330_StandTable[] = {
 /* MD_0_200 */
 	{
 		0x28, 0x18, 0x08, 0x0800,
@@ -2353,109 +2353,109 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = {
 
 /*add for new UNIVGABIOS*/
 static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = {
-	{Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */
-	{Panel1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */
-	{Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */
-	{Panel1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */
-	{Panel1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */
-	{Panel1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */
-	{Panel1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */
-	{Panel1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */
-	{Panel1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */
-	{Panel1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */
-	{Panel1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */
+	{Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */
+	{Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */
+	{Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */
+	{Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */
+	{Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */
+	{Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */
+	{Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */
+	{Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */
+	{Panel_1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */
+	{Panel_1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */
+	{Panel_1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */
 	{PanelRef60Hz, 0x0008, 0x0008, 11}, /* XGI_NoScalingData */
-	{Panel1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */
-	{Panel1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */
-	{Panel1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */
-	{Panel1280x1024x75, 0x0019, 0x0001, 15}, /* XGI_ExtLCD1280x1024x75Data*/
-	{Panel1280x1024x75, 0x0019, 0x0000, 16}, /* XGI_StLCD1280x1024x75Data */
-	{Panel1280x1024x75, 0x0018, 0x0010, 17}, /* XGI_CetLCD1280x1024x75Data*/
+	{Panel_1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */
+	{Panel_1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */
+	{Panel_1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */
+	{Panel_1280x1024x75, 0x0019, 0x0001, 15}, /* XGI_ExtLCD1280x1024x75Data*/
+	{Panel_1280x1024x75, 0x0019, 0x0000, 16}, /* XGI_StLCD1280x1024x75Data */
+	{Panel_1280x1024x75, 0x0018, 0x0010, 17}, /* XGI_CetLCD1280x1024x75Data*/
 	{PanelRef75Hz, 0x0008, 0x0008, 18}, /* XGI_NoScalingDatax75 */
 	{0xFF, 0x0000, 0x0000, 0} /* End of table */
 };
 
 static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = {
-	{Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */
-	{Panel1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */
-	{Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */
-	{Panel1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */
-	{Panel1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */
-	{Panel1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */
-	{Panel1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */
-	{Panel1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */
-	{Panel1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */
-	{Panel1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */
-	{Panel1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */
-	{Panel1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */
+	{Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */
+	{Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */
+	{Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */
+	{Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */
+	{Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */
+	{Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */
+	{Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */
+	{Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */
+	{Panel_1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */
+	{Panel_1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */
+	{Panel_1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */
+	{Panel_1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */
 	{PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */
-	{Panel1024x768x75, 0x0019, 0x0001, 13}, /*XGI_ExtLCDDes1024x768x75Data*/
-	{Panel1024x768x75, 0x0019, 0x0000, 14}, /* XGI_StLCDDes1024x768x75Data*/
-	{Panel1024x768x75, 0x0018, 0x0010, 15}, /*XGI_CetLCDDes1024x768x75Data*/
+	{Panel_1024x768x75, 0x0019, 0x0001, 13}, /*XGI_ExtLCDDes1024x768x75Data*/
+	{Panel_1024x768x75, 0x0019, 0x0000, 14}, /* XGI_StLCDDes1024x768x75Data*/
+	{Panel_1024x768x75, 0x0018, 0x0010, 15}, /*XGI_CetLCDDes1024x768x75Data*/
 	/* XGI_ExtLCDDes1280x1024x75Data */
-	{Panel1280x1024x75, 0x0019, 0x0001, 16},
+	{Panel_1280x1024x75, 0x0019, 0x0001, 16},
 	/* XGI_StLCDDes1280x1024x75Data */
-	{Panel1280x1024x75, 0x0019, 0x0000, 17},
+	{Panel_1280x1024x75, 0x0019, 0x0000, 17},
 	/* XGI_CetLCDDes1280x1024x75Data */
-	{Panel1280x1024x75, 0x0018, 0x0010, 18},
+	{Panel_1280x1024x75, 0x0018, 0x0010, 18},
 	{PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */
 	{0xFF, 0x0000, 0x0000, 0}
 };
 
 static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1[] = {
-	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */
-	{Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */
-	{Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1 */
-	{Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2 */
-	{Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1 */
-	{Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2 */
-	{Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1 */
-	{Panel1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1x75 */
-	{Panel1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2x75 */
-	{Panel1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1x75*/
-	{Panel1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2x75*/
+	{Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */
+	{Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */
+	{Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1 */
+	{Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2 */
+	{Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1 */
+	{Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2 */
+	{Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1 */
+	{Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1x75 */
+	{Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2x75 */
+	{Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1x75*/
+	{Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2x75*/
 	{0xFF, 0x0000, 0x0000, 0}
 };
 
 static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = {
-	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */
-	{Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */
-	{Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */
-	{Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */
-	{Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */
-	{Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */
-	{Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */
+	{Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */
+	{Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */
+	{Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */
+	{Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */
+	{Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */
+	{Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */
+	{Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */
 	{PanelRef60Hz, 0x0008, 0x0008, 7}, /* XGI_LVDSNoScalingData */
-	{Panel1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */
-	{Panel1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */
-	{Panel1280x1024x75, 0x0018, 0x0000, 10}, /* XGI_LVDS1280x1024Data_1x75*/
-	{Panel1280x1024x75, 0x0018, 0x0010, 11},  /*XGI_LVDS1280x1024Data_2x75*/
+	{Panel_1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */
+	{Panel_1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */
+	{Panel_1280x1024x75, 0x0018, 0x0000, 10}, /* XGI_LVDS1280x1024Data_1x75*/
+	{Panel_1280x1024x75, 0x0018, 0x0010, 11},  /*XGI_LVDS1280x1024Data_2x75*/
 	{PanelRef75Hz, 0x0008, 0x0008, 12}, /* XGI_LVDSNoScalingDatax75 */
 	{0xFF, 0x0000, 0x0000, 0}
 };
 
 static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = {
-	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */
-	{Panel1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */
-	{Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */
-	{Panel1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */
-	{Panel1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */
-	{Panel1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */
-	{Panel1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */
-	{Panel1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */
+	{Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */
+	{Panel_1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */
+	{Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */
+	{Panel_1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */
+	{Panel_1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */
+	{Panel_1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */
+	{Panel_1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */
+	{Panel_1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */
 	{PanelRef60Hz, 0x0008, 0x0008, 8},  /* XGI_LVDSNoScalingDesData */
-	{Panel1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */
-	{Panel1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */
-	{Panel1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */
-	{Panel1280x1024x75, 0x0018, 0x0000, 12}, /* XGI_LVDS1280x1024Des_1x75 */
-	{Panel1280x1024x75, 0x0018, 0x0010, 13}, /* XGI_LVDS1280x1024Des_2x75 */
+	{Panel_1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */
+	{Panel_1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */
+	{Panel_1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */
+	{Panel_1280x1024x75, 0x0018, 0x0000, 12}, /* XGI_LVDS1280x1024Des_1x75 */
+	{Panel_1280x1024x75, 0x0018, 0x0010, 13}, /* XGI_LVDS1280x1024Des_2x75 */
 	{PanelRef75Hz, 0x0008, 0x0008, 14}, /* XGI_LVDSNoScalingDesDatax75 */
 	{0xFF, 0x0000, 0x0000, 0}
 };
 
 static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] = {
-	{Panel1024x768, 0x0000, 0x0000, 0}, /* XGI_CH7017LV1024x768 */
-	{Panel1400x1050, 0x0000, 0x0000, 1}, /* XGI_CH7017LV1400x1050 */
+	{Panel_1024x768, 0x0000, 0x0000, 0}, /* XGI_CH7017LV1024x768 */
+	{Panel_1400x1050, 0x0000, 0x0000, 1}, /* XGI_CH7017LV1400x1050 */
 	{0xFF, 0x0000, 0x0000, 0}
 };
 
@@ -2501,225 +2501,225 @@ static unsigned short LCDLenList[] = {
 /* Dual link only */
 static struct XGI330_LCDCapStruct  XGI_LCDDLCapList[] = {
 /* LCDCap1024x768 */
-	{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	{Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315,
 	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024 */
-	{Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA,
-	0x012, 0x70, 0x03, VCLK108_2,
+	{Panel_1280x1024, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2_315,
 	0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1400x1050 */
-	{Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA,
-	0x012, 0x70, 0x03, VCLK108_2,
+	{Panel_1400x1050, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2_315,
 	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1600x1200 */
-	{Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull,
+	{Panel_1600x1200, XGI_LCDDualLink+DefaultLCDCap, LCDToFull,
 	0x012, 0xC0, 0x03, VCLK162,
 	 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1024x768x75 */
-	{Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
+	{Panel_1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
 	 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024x75 */
-	{Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	{Panel_1280x1024x75, XGI_LCDDualLink+DefaultLCDCap, StLCDBToA,
 	0x012, 0x90, 0x03, VCLK135_5,
 	 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCapDefault */
-	{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315,
 	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
 static struct XGI330_LCDCapStruct  XGI_LCDCapList[] = {
 /* LCDCap1024x768 */
-	{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	{Panel_1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315,
 	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024 */
-	{Panel1280x1024, DefaultLCDCap, StLCDBToA,
-	0x012, 0x70, 0x03, VCLK108_2,
+	{Panel_1280x1024, DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2_315,
 	0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1400x1050 */
-	{Panel1400x1050, DefaultLCDCap, StLCDBToA,
-	0x012, 0x70, 0x03, VCLK108_2,
+	{Panel_1400x1050, DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2_315,
 	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1600x1200 */
-	{Panel1600x1200, DefaultLCDCap, LCDToFull,
+	{Panel_1600x1200, DefaultLCDCap, LCDToFull,
 	0x012, 0xC0, 0x03, VCLK162,
 	 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1024x768x75 */
-	{Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
+	{Panel_1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
 	 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024x75 */
-	{Panel1280x1024x75, DefaultLCDCap, StLCDBToA,
+	{Panel_1280x1024x75, DefaultLCDCap, StLCDBToA,
 	0x012, 0x90, 0x03, VCLK135_5,
 	 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCapDefault */
-	{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65_315,
 	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
 	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
 static struct XGI_Ext2Struct XGI330_RefIndex[] = {
-	{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
+	{Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
 	0x00, 0x10, 0x59, 320, 200},/* 00 */
-	{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
+	{Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
 	0x00, 0x10, 0x00, 320, 400},/* 01 */
-	{Support32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175,
+	{Mode32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175,
 	0x04, 0x20, 0x50, 320, 240},/* 02 */
-	{Support32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40,
+	{Mode32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40,
 	0x05, 0x32, 0x51, 400, 300},/* 03 */
-	{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384,
-	VCLK65, 0x06, 0x43, 0x52, 512, 384},/* 04 */
-	{Support32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175,
+	{Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384,
+	VCLK65_315, 0x06, 0x43, 0x52, 512, 384},/* 04 */
+	{Mode32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175,
 	0x00, 0x14, 0x2f, 640, 400},/* 05 */
-	{Support32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175,
+	{Mode32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175,
 	0x04, 0x24, 0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */
-	{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5,
 	0x04, 0x24, 0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */
-	{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5,
 	0x47, 0x24, 0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */
-	{Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36,
+	{Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36,
 	0x8A, 0x24, 0x2e, 640, 480},/* 09 640x480x85Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163,
 	0x00, 0x24, 0x2e, 640, 480},/* 0a 640x480x100Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406,
 	0x00, 0x24, 0x2e, 640, 480},/* 0b 640x480x120Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852,
 	0x00, 0x24, 0x2e, 640, 480},/* 0c 640x480x160Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6,
+	{Mode32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6,
 	0x00, 0x24, 0x2e, 640, 480},/* 0d 640x480x200Hz */
-	{Support32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36,
+	{Mode32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36,
 	0x05, 0x36, 0x6a, 800, 600},/* 0e 800x600x56Hz */
-	{Support32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40,
+	{Mode32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40,
 	0x05, 0x36, 0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */
-	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50,
 	0x48, 0x36, 0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */
-	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5,
 	0x8B, 0x36, 0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25,
 	0x00, 0x36, 0x6a, 800, 600},/* 12 800x600x85Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179,
 	0x00, 0x36, 0x6a, 800, 600},/* 13 800x600x100Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95,
 	0x00, 0x36, 0x6a, 800, 600},/* 14 800x600x120Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406,
 	0x00, 0x36, 0x6a, 800, 600},/* 15 800x600x160Hz */
-	{Support32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9,
+	{Mode32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9,
 	0x00, 0x47, 0x37, 1024, 768},/* 16 1024x768x43Hz */
 	/* 17 1024x768x60Hz (LCD 1024x768x60Hz) */
-	{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60,
-	VCLK65, 0x06, 0x47, 0x37, 1024, 768},
-	{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75,
+	{Mode32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60,
+	VCLK65_315, 0x06, 0x47, 0x37, 1024, 768},
+	{Mode32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75,
 	0x49, 0x47, 0x37, 1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */
-	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75,
 	0x00, 0x47, 0x37, 1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5,
 	0x8C, 0x47, 0x37, 1024, 768},/* 1a 1024x768x85Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309,
 	0x00, 0x47, 0x37, 1024, 768},/* 1b 1024x768x100Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054,
 	0x00, 0x47, 0x37, 1024, 768},/* 1c 1024x768x120Hz */
-	{Support32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2,
+	{Mode32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2_315,
 	0x08, 0x58, 0x7b, 1280, 960},/* 1d 1280x960x60Hz */
-	{Support32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75,
+	{Mode32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75,
 	0x00, 0x58, 0x3a, 1280, 1024},/* 1e 1280x1024x43Hz */
-	{Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2,
+	{Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2_315,
 	0x07, 0x58, 0x3a, 1280, 1024},/*1f 1280x1024x60Hz (LCD 1280x1024x60Hz)*/
-	{Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5,
+	{Mode32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5,
 	0x00, 0x58, 0x3a, 1280, 1024},/*20 1280x1024x75Hz (LCD 1280x1024x75Hz)*/
-	{Support32Bpp + SyncPP, RES1280x1024x85, VCLK157_5,
+	{Mode32Bpp + SyncPP, RES1280x1024x85, VCLK157_5,
 	0x00, 0x58, 0x3a, 1280, 1024},/* 21 1280x1024x85Hz */
 	/* 22 1600x1200x60Hz */
-	{Support32Bpp + SupportLCD + SyncPP + SupportCRT2in301C,
+	{Mode32Bpp + SupportLCD + SyncPP + SupportCRT2in301C,
 	RES1600x1200x60, VCLK162, 0x09, 0x7A, 0x3c, 1600, 1200},
-	{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175,
+	{Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175,
 	0x00, 0x69, 0x3c, 1600, 1200},/* 23 1600x1200x65Hz */
-	{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189,
+	{Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189,
 	0x00, 0x69, 0x3c, 1600, 1200},/* 24 1600x1200x70Hz */
-	{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5,
+	{Mode32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5,
 	0x00, 0x69, 0x3c, 1600, 1200},/* 25 1600x1200x75Hz */
-	{Support32Bpp + SyncPP, RES1600x1200x85, VCLK229_5,
+	{Mode32Bpp + SyncPP, RES1600x1200x85, VCLK229_5,
 	0x00, 0x69, 0x3c, 1600, 1200},/* 26 1600x1200x85Hz */
-	{Support32Bpp + SyncPP, RES1600x1200x100, VCLK269_655,
+	{Mode32Bpp + SyncPP, RES1600x1200x100, VCLK269_655,
 	0x00, 0x69, 0x3c, 1600, 1200},/* 27 1600x1200x100Hz */
-	{Support32Bpp + SyncPP, RES1600x1200x120, VCLK323_586,
+	{Mode32Bpp + SyncPP, RES1600x1200x120, VCLK323_586,
 	0x00, 0x69, 0x3c, 1600, 1200},/* 28 1600x1200x120Hz */
-	{Support32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234,
+	{Mode32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234,
 	0x00, 0x00, 0x68, 1920, 1440},/* 29 1920x1440x60Hz */
-	{Support32Bpp + SyncPN, RES1920x1440x65, VCLK254_817,
+	{Mode32Bpp + SyncPN, RES1920x1440x65, VCLK254_817,
 	0x00, 0x00, 0x68, 1920, 1440},/* 2a 1920x1440x65Hz */
-	{Support32Bpp + SyncPN, RES1920x1440x70, VCLK277_015,
+	{Mode32Bpp + SyncPN, RES1920x1440x70, VCLK277_015,
 	0x00, 0x00, 0x68, 1920, 1440},/* 2b 1920x1440x70Hz */
-	{Support32Bpp + SyncPN, RES1920x1440x75, VCLK291_132,
+	{Mode32Bpp + SyncPN, RES1920x1440x75, VCLK291_132,
 	0x00, 0x00, 0x68, 1920, 1440},/* 2c 1920x1440x75Hz */
-	{Support32Bpp + SyncPN, RES1920x1440x85, VCLK330_615,
+	{Mode32Bpp + SyncPN, RES1920x1440x85, VCLK330_615,
 	0x00, 0x00, 0x68, 1920, 1440},/* 2d 1920x1440x85Hz */
-	{Support16Bpp + SyncPN, RES1920x1440x100, VCLK388_631,
+	{Mode16Bpp + SyncPN, RES1920x1440x100, VCLK388_631,
 	0x00, 0x00, 0x68, 1920, 1440},/* 2e 1920x1440x100Hz */
-	{Support32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952,
+	{Mode32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952,
 	0x00, 0x00, 0x6c, 2048, 1536},/* 2f 2048x1536x60Hz */
-	{Support32Bpp + SyncPN, RES2048x1536x65, VCLK291_766,
+	{Mode32Bpp + SyncPN, RES2048x1536x65, VCLK291_766,
 	0x00, 0x00, 0x6c, 2048, 1536},/* 30 2048x1536x65Hz */
-	{Support32Bpp + SyncPN, RES2048x1536x70, VCLK315_195,
+	{Mode32Bpp + SyncPN, RES2048x1536x70, VCLK315_195,
 	0x00, 0x00, 0x6c, 2048, 1536},/* 31 2048x1536x70Hz */
-	{Support32Bpp + SyncPN, RES2048x1536x75, VCLK340_477,
+	{Mode32Bpp + SyncPN, RES2048x1536x75, VCLK340_477,
 	0x00, 0x00, 0x6c, 2048, 1536},/* 32 2048x1536x75Hz */
-	{Support16Bpp + SyncPN, RES2048x1536x85, VCLK375_847,
+	{Mode16Bpp + SyncPN, RES2048x1536x85, VCLK375_847,
 	0x00, 0x00, 0x6c, 2048, 1536},/* 33 2048x1536x85Hz */
-	{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 +
-	 SyncPP + SupportYPbPr, RES800x480x60, VCLK39_77,
+	{Mode32Bpp + SupportHiVision + SupportRAMDAC2 +
+	 SyncPP + SupportYPbPr750p, RES800x480x60, VCLK39_77,
 	 0x08, 0x00, 0x70, 800, 480},/* 34 800x480x60Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5,
 	0x08, 0x00, 0x70, 800, 480},/* 35 800x480x75Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25,
 	0x08, 0x00, 0x70, 800, 480},/* 36 800x480x85Hz */
-	{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 +
-	 SyncPP + SupportYPbPr, RES1024x576x60, VCLK65,
+	{Mode32Bpp + SupportHiVision + SupportRAMDAC2 +
+	 SyncPP + SupportYPbPr750p, RES1024x576x60, VCLK65_315,
 	 0x09, 0x00, 0x71, 1024, 576},/* 37 1024x576x60Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75,
 	0x09, 0x00, 0x71, 1024, 576},/* 38 1024x576x75Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5,
 	0x09, 0x00, 0x71, 1024, 576},/* 39 1024x576x85Hz */
-	{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 +
-	SyncPP + SupportYPbPr, RES1280x720x60, VCLK108_2,
+	{Mode32Bpp + SupportHiVision + SupportRAMDAC2 +
+	SyncPP + SupportYPbPr750p, RES1280x720x60, VCLK108_2_315,
 	0x0A, 0x00, 0x75, 1280, 720},/* 3a 1280x720x60Hz*/
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5,
 	0x0A, 0x00, 0x75, 1280, 720},/* 3b 1280x720x75Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5,
 	0x0A, 0x00, 0x75, 1280, 720},/* 3c 1280x720x85Hz */
-	{Support32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322,
+	{Mode32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322,
 	0x06, 0x00, 0x31,  720, 480},/* 3d 720x480x60Hz */
-	{Support32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36,
+	{Mode32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36,
 	0x06, 0x00, 0x32, 720, 576},/* 3e 720x576x56Hz */
-	{Support32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I,
+	{Mode32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I,
 	VCLK35_2, 0x00, 0x00, 0x00,  856, 480},/* 3f 856x480x79I */
-	{Support32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2,
+	{Mode32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2,
 	0x00, 0x00, 0x00,  856, 480},/* 40 856x480x60Hz */
-	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60,
 	VCLK79_411, 0x08, 0x48, 0x23, 1280, 768},/* 41 1280x768x60Hz */
-	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60,
+	{Mode32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60,
 	VCLK122_61, 0x08, 0x69, 0x26, 1400, 1050},/* 42 1400x1050x60Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350,
 	0x37, 0x00, 0x20, 1152, 864},/* 43 1152x864x60Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385,
 	0x37, 0x00, 0x20, 1152, 864},/* 44 1152x864x75Hz */
-	{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75,
+	{Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75,
 	VCLK125_999, 0x3A, 0x88, 0x7b, 1280, 960},/* 45 1280x960x75Hz */
-	{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85,
+	{Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85,
 	VCLK148_5, 0x0A, 0x88, 0x7b, 1280, 960},/* 46 1280x960x85Hz */
-	{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120,
+	{Mode32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120,
 	VCLK217_325, 0x3A, 0x88, 0x7b, 1280, 960},/* 47 1280x960x120Hz */
-	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054,
+	{Mode32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054,
 	0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */
 };
 
@@ -2729,7 +2729,7 @@ static unsigned char XGI330_ScreenOffset[] = {
 	0x57, 0x48
 };
 
-static struct XGI_StResInfoStruct XGI330_StResInfo[] = {
+static struct SiS_StResInfo_S XGI330_StResInfo[] = {
 	{640, 400},
 	{640, 350},
 	{720, 400},
@@ -2737,7 +2737,7 @@ static struct XGI_StResInfoStruct XGI330_StResInfo[] = {
 	{640, 480}
 };
 
-static struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] = {
+static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = {
 	{ 320,  200, 8,  8},
 	{ 320,  240, 8,  8},
 	{ 320,  400, 8,  8},
diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h
index 9e166bb..a7208e3 100644
--- a/drivers/staging/xgifb/vgatypes.h
+++ b/drivers/staging/xgifb/vgatypes.h
@@ -2,6 +2,9 @@
 #define _VGATYPES_
 
 #include <linux/ioctl.h>
+#include <linux/fb.h>	/* for struct fb_var_screeninfo for sis.h */
+#include "../../video/sis/vgatypes.h"
+#include "../../video/sis/sis.h"		/* for LCD_TYPE */
 
 #ifndef XGI_VB_CHIP_TYPE
 enum XGI_VB_CHIP_TYPE {
@@ -19,6 +22,12 @@ enum XGI_VB_CHIP_TYPE {
 };
 #endif
 
+
+#define XGI_LCD_TYPE
+/* Since the merge with video/sis the LCD_TYPEs are used from
+ drivers/video/sis/sis.h . Nevertheless we keep this (for the moment) for
+ future reference until the code is merged completely and we are sure
+ nothing of this should be added to the sis.h header */
 #ifndef XGI_LCD_TYPE
 enum XGI_LCD_TYPE {
 	LCD_INVALID = 0,
diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig
index 7fabcb2..5a36fcf 100644
--- a/drivers/staging/zcache/Kconfig
+++ b/drivers/staging/zcache/Kconfig
@@ -1,13 +1,14 @@
 config ZCACHE
 	tristate "Dynamic compression of swap pages and clean pagecache pages"
-	depends on CLEANCACHE || FRONTSWAP
-	select XVMALLOC
-	select LZO_COMPRESS
-	select LZO_DECOMPRESS
+	# X86 dependency is because zsmalloc uses non-portable pte/tlb
+	# functions
+	depends on (CLEANCACHE || FRONTSWAP) && CRYPTO && X86
+	select ZSMALLOC
+	select CRYPTO_LZO
 	default n
 	help
 	  Zcache doubles RAM efficiency while providing a significant
-	  performance boosts on many workloads.  Zcache uses lzo1x
+	  performance boosts on many workloads.  Zcache uses
 	  compression and an in-kernel implementation of transcendent
 	  memory to store clean page cache pages and swap in RAM,
 	  providing a noticeable reduction in disk I/O.
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c
index ef7c52b..ae157a8 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -6,9 +6,10 @@
  *
  * Zcache provides an in-kernel "host implementation" for transcendent memory
  * and, thus indirectly, for cleancache and frontswap.  Zcache includes two
- * page-accessible memory [1] interfaces, both utilizing lzo1x compression:
+ * page-accessible memory [1] interfaces, both utilizing the crypto compression
+ * API:
  * 1) "compression buddies" ("zbud") is used for ephemeral pages
- * 2) xvmalloc is used for persistent pages.
+ * 2) zsmalloc is used for persistent pages.
  * Xvmalloc (based on the TLSF allocator) has very low fragmentation
  * so maximizes space efficiency, while zbud allows pairs (and potentially,
  * in the future, more than a pair of) compressed pages to be closely linked
@@ -23,15 +24,16 @@
 #include <linux/cpu.h>
 #include <linux/highmem.h>
 #include <linux/list.h>
-#include <linux/lzo.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/atomic.h>
 #include <linux/math64.h>
+#include <linux/crypto.h>
+#include <linux/string.h>
 #include "tmem.h"
 
-#include "../zram/xvmalloc.h" /* if built in drivers/staging */
+#include "../zsmalloc/zsmalloc.h"
 
 #if (!defined(CONFIG_CLEANCACHE) && !defined(CONFIG_FRONTSWAP))
 #error "zcache is useless without CONFIG_CLEANCACHE or CONFIG_FRONTSWAP"
@@ -60,7 +62,7 @@ MODULE_LICENSE("GPL");
 
 struct zcache_client {
 	struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT];
-	struct xv_pool *xvpool;
+	struct zs_pool *zspool;
 	bool allocated;
 	atomic_t refcount;
 };
@@ -81,6 +83,38 @@ static inline bool is_local_client(struct zcache_client *cli)
 	return cli == &zcache_host;
 }
 
+/* crypto API for zcache  */
+#define ZCACHE_COMP_NAME_SZ CRYPTO_MAX_ALG_NAME
+static char zcache_comp_name[ZCACHE_COMP_NAME_SZ];
+static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms;
+
+enum comp_op {
+	ZCACHE_COMPOP_COMPRESS,
+	ZCACHE_COMPOP_DECOMPRESS
+};
+
+static inline int zcache_comp_op(enum comp_op op,
+				const u8 *src, unsigned int slen,
+				u8 *dst, unsigned int *dlen)
+{
+	struct crypto_comp *tfm;
+	int ret;
+
+	BUG_ON(!zcache_comp_pcpu_tfms);
+	tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, get_cpu());
+	BUG_ON(!tfm);
+	switch (op) {
+	case ZCACHE_COMPOP_COMPRESS:
+		ret = crypto_comp_compress(tfm, src, slen, dst, dlen);
+		break;
+	case ZCACHE_COMPOP_DECOMPRESS:
+		ret = crypto_comp_decompress(tfm, src, slen, dst, dlen);
+		break;
+	}
+	put_cpu();
+	return ret;
+}
+
 /**********
  * Compression buddies ("zbud") provides for packing two (or, possibly
  * in the future, more) compressed ephemeral pages into a single "raw"
@@ -407,7 +441,7 @@ static int zbud_decompress(struct page *page, struct zbud_hdr *zh)
 {
 	struct zbud_page *zbpg;
 	unsigned budnum = zbud_budnum(zh);
-	size_t out_len = PAGE_SIZE;
+	unsigned int out_len = PAGE_SIZE;
 	char *to_va, *from_va;
 	unsigned size;
 	int ret = 0;
@@ -421,13 +455,14 @@ static int zbud_decompress(struct page *page, struct zbud_hdr *zh)
 	}
 	ASSERT_SENTINEL(zh, ZBH);
 	BUG_ON(zh->size == 0 || zh->size > zbud_max_buddy_size());
-	to_va = kmap_atomic(page, KM_USER0);
+	to_va = kmap_atomic(page);
 	size = zh->size;
 	from_va = zbud_data(zh, size);
-	ret = lzo1x_decompress_safe(from_va, size, to_va, &out_len);
-	BUG_ON(ret != LZO_E_OK);
+	ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, from_va, size,
+				to_va, &out_len);
+	BUG_ON(ret);
 	BUG_ON(out_len != PAGE_SIZE);
-	kunmap_atomic(to_va, KM_USER0);
+	kunmap_atomic(to_va);
 out:
 	spin_unlock(&zbpg->lock);
 	return ret;
@@ -622,8 +657,8 @@ static int zbud_show_cumul_chunk_counts(char *buf)
 #endif
 
 /**********
- * This "zv" PAM implementation combines the TLSF-based xvMalloc
- * with lzo1x compression to maximize the amount of data that can
+ * This "zv" PAM implementation combines the slab-based zsmalloc
+ * with the crypto compression API to maximize the amount of data that can
  * be packed into a physical page.
  *
  * Zv represents a PAM page with the index and object (plus a "size" value
@@ -636,6 +671,7 @@ struct zv_hdr {
 	uint32_t pool_id;
 	struct tmem_oid oid;
 	uint32_t index;
+	size_t size;
 	DECL_SENTINEL
 };
 
@@ -657,72 +693,74 @@ static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5;
 static atomic_t zv_curr_dist_counts[NCHUNKS];
 static atomic_t zv_cumul_dist_counts[NCHUNKS];
 
-static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id,
+static struct zv_hdr *zv_create(struct zs_pool *pool, uint32_t pool_id,
 				struct tmem_oid *oid, uint32_t index,
 				void *cdata, unsigned clen)
 {
-	struct page *page;
-	struct zv_hdr *zv = NULL;
-	uint32_t offset;
-	int alloc_size = clen + sizeof(struct zv_hdr);
-	int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT;
-	int ret;
+	struct zv_hdr *zv;
+	u32 size = clen + sizeof(struct zv_hdr);
+	int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT;
+	void *handle = NULL;
+	char *buf;
 
 	BUG_ON(!irqs_disabled());
 	BUG_ON(chunks >= NCHUNKS);
-	ret = xv_malloc(xvpool, alloc_size,
-			&page, &offset, ZCACHE_GFP_MASK);
-	if (unlikely(ret))
+	handle = zs_malloc(pool, size);
+	if (!handle)
 		goto out;
 	atomic_inc(&zv_curr_dist_counts[chunks]);
 	atomic_inc(&zv_cumul_dist_counts[chunks]);
-	zv = kmap_atomic(page, KM_USER0) + offset;
+	zv = (struct zv_hdr *)((char *)cdata - sizeof(*zv));
 	zv->index = index;
 	zv->oid = *oid;
 	zv->pool_id = pool_id;
+	zv->size = clen;
 	SET_SENTINEL(zv, ZVH);
-	memcpy((char *)zv + sizeof(struct zv_hdr), cdata, clen);
-	kunmap_atomic(zv, KM_USER0);
+	buf = zs_map_object(pool, handle);
+	memcpy(buf, zv, clen + sizeof(*zv));
+	zs_unmap_object(pool, handle);
 out:
-	return zv;
+	return handle;
 }
 
-static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv)
+static void zv_free(struct zs_pool *pool, void *handle)
 {
 	unsigned long flags;
-	struct page *page;
-	uint32_t offset;
-	uint16_t size = xv_get_object_size(zv);
-	int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT;
+	struct zv_hdr *zv;
+	uint16_t size;
+	int chunks;
 
+	zv = zs_map_object(pool, handle);
 	ASSERT_SENTINEL(zv, ZVH);
+	size = zv->size + sizeof(struct zv_hdr);
+	INVERT_SENTINEL(zv, ZVH);
+	zs_unmap_object(pool, handle);
+
+	chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT;
 	BUG_ON(chunks >= NCHUNKS);
 	atomic_dec(&zv_curr_dist_counts[chunks]);
-	size -= sizeof(*zv);
-	BUG_ON(size == 0);
-	INVERT_SENTINEL(zv, ZVH);
-	page = virt_to_page(zv);
-	offset = (unsigned long)zv & ~PAGE_MASK;
+
 	local_irq_save(flags);
-	xv_free(xvpool, page, offset);
+	zs_free(pool, handle);
 	local_irq_restore(flags);
 }
 
-static void zv_decompress(struct page *page, struct zv_hdr *zv)
+static void zv_decompress(struct page *page, void *handle)
 {
-	size_t clen = PAGE_SIZE;
+	unsigned int clen = PAGE_SIZE;
 	char *to_va;
-	unsigned size;
 	int ret;
+	struct zv_hdr *zv;
 
+	zv = zs_map_object(zcache_host.zspool, handle);
+	BUG_ON(zv->size == 0);
 	ASSERT_SENTINEL(zv, ZVH);
-	size = xv_get_object_size(zv) - sizeof(*zv);
-	BUG_ON(size == 0);
-	to_va = kmap_atomic(page, KM_USER0);
-	ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv),
-					size, to_va, &clen);
-	kunmap_atomic(to_va, KM_USER0);
-	BUG_ON(ret != LZO_E_OK);
+	to_va = kmap_atomic(page);
+	ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, (char *)zv + sizeof(*zv),
+				zv->size, to_va, &clen);
+	kunmap_atomic(to_va);
+	zs_unmap_object(zcache_host.zspool, handle);
+	BUG_ON(ret);
 	BUG_ON(clen != PAGE_SIZE);
 }
 
@@ -948,8 +986,8 @@ int zcache_new_client(uint16_t cli_id)
 		goto out;
 	cli->allocated = 1;
 #ifdef CONFIG_FRONTSWAP
-	cli->xvpool = xv_create_pool();
-	if (cli->xvpool == NULL)
+	cli->zspool = zs_create_pool("zcache", ZCACHE_GFP_MASK);
+	if (cli->zspool == NULL)
 		goto out;
 #endif
 	ret = 0;
@@ -1180,7 +1218,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
 		}
 		/* reject if mean compression is too poor */
 		if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) {
-			total_zsize = xv_get_total_size_bytes(cli->xvpool);
+			total_zsize = zs_get_total_size_bytes(cli->zspool);
 			zv_mean_zsize = div_u64(total_zsize,
 						curr_pers_pampd_count);
 			if (zv_mean_zsize > zv_max_mean_zsize) {
@@ -1188,7 +1226,7 @@ static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph,
 				goto out;
 			}
 		}
-		pampd = (void *)zv_create(cli->xvpool, pool->pool_id,
+		pampd = (void *)zv_create(cli->zspool, pool->pool_id,
 						oid, index, cdata, clen);
 		if (pampd == NULL)
 			goto out;
@@ -1246,7 +1284,7 @@ static void zcache_pampd_free(void *pampd, struct tmem_pool *pool,
 		atomic_dec(&zcache_curr_eph_pampd_count);
 		BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0);
 	} else {
-		zv_free(cli->xvpool, (struct zv_hdr *)pampd);
+		zv_free(cli->zspool, pampd);
 		atomic_dec(&zcache_curr_pers_pampd_count);
 		BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0);
 	}
@@ -1285,55 +1323,73 @@ static struct tmem_pamops zcache_pamops = {
  * zcache compression/decompression and related per-cpu stuff
  */
 
-#define LZO_WORKMEM_BYTES LZO1X_1_MEM_COMPRESS
-#define LZO_DSTMEM_PAGE_ORDER 1
-static DEFINE_PER_CPU(unsigned char *, zcache_workmem);
 static DEFINE_PER_CPU(unsigned char *, zcache_dstmem);
+#define ZCACHE_DSTMEM_ORDER 1
 
 static int zcache_compress(struct page *from, void **out_va, size_t *out_len)
 {
 	int ret = 0;
 	unsigned char *dmem = __get_cpu_var(zcache_dstmem);
-	unsigned char *wmem = __get_cpu_var(zcache_workmem);
 	char *from_va;
 
 	BUG_ON(!irqs_disabled());
-	if (unlikely(dmem == NULL || wmem == NULL))
-		goto out;  /* no buffer, so can't compress */
-	from_va = kmap_atomic(from, KM_USER0);
+	if (unlikely(dmem == NULL))
+		goto out;  /* no buffer or no compressor so can't compress */
+	*out_len = PAGE_SIZE << ZCACHE_DSTMEM_ORDER;
+	from_va = kmap_atomic(from);
 	mb();
-	ret = lzo1x_1_compress(from_va, PAGE_SIZE, dmem, out_len, wmem);
-	BUG_ON(ret != LZO_E_OK);
+	ret = zcache_comp_op(ZCACHE_COMPOP_COMPRESS, from_va, PAGE_SIZE, dmem,
+				(unsigned int *)out_len);
+	BUG_ON(ret);
 	*out_va = dmem;
-	kunmap_atomic(from_va, KM_USER0);
+	kunmap_atomic(from_va);
 	ret = 1;
 out:
 	return ret;
 }
 
+static int zcache_comp_cpu_up(int cpu)
+{
+	struct crypto_comp *tfm;
+
+	tfm = crypto_alloc_comp(zcache_comp_name, 0, 0);
+	if (IS_ERR(tfm))
+		return NOTIFY_BAD;
+	*per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = tfm;
+	return NOTIFY_OK;
+}
+
+static void zcache_comp_cpu_down(int cpu)
+{
+	struct crypto_comp *tfm;
+
+	tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu);
+	crypto_free_comp(tfm);
+	*per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = NULL;
+}
 
 static int zcache_cpu_notifier(struct notifier_block *nb,
 				unsigned long action, void *pcpu)
 {
-	int cpu = (long)pcpu;
+	int ret, cpu = (long)pcpu;
 	struct zcache_preload *kp;
 
 	switch (action) {
 	case CPU_UP_PREPARE:
+		ret = zcache_comp_cpu_up(cpu);
+		if (ret != NOTIFY_OK) {
+			pr_err("zcache: can't allocate compressor transform\n");
+			return ret;
+		}
 		per_cpu(zcache_dstmem, cpu) = (void *)__get_free_pages(
-			GFP_KERNEL | __GFP_REPEAT,
-			LZO_DSTMEM_PAGE_ORDER),
-		per_cpu(zcache_workmem, cpu) =
-			kzalloc(LZO1X_MEM_COMPRESS,
-				GFP_KERNEL | __GFP_REPEAT);
+			GFP_KERNEL | __GFP_REPEAT, ZCACHE_DSTMEM_ORDER);
 		break;
 	case CPU_DEAD:
 	case CPU_UP_CANCELED:
+		zcache_comp_cpu_down(cpu);
 		free_pages((unsigned long)per_cpu(zcache_dstmem, cpu),
-				LZO_DSTMEM_PAGE_ORDER);
+			ZCACHE_DSTMEM_ORDER);
 		per_cpu(zcache_dstmem, cpu) = NULL;
-		kfree(per_cpu(zcache_workmem, cpu));
-		per_cpu(zcache_workmem, cpu) = NULL;
 		kp = &per_cpu(zcache_preloads, cpu);
 		while (kp->nr) {
 			kmem_cache_free(zcache_objnode_cache,
@@ -1757,9 +1813,9 @@ static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize)
 static struct cleancache_ops zcache_cleancache_ops = {
 	.put_page = zcache_cleancache_put_page,
 	.get_page = zcache_cleancache_get_page,
-	.flush_page = zcache_cleancache_flush_page,
-	.flush_inode = zcache_cleancache_flush_inode,
-	.flush_fs = zcache_cleancache_flush_fs,
+	.invalidate_page = zcache_cleancache_flush_page,
+	.invalidate_inode = zcache_cleancache_flush_inode,
+	.invalidate_fs = zcache_cleancache_flush_fs,
 	.init_shared_fs = zcache_cleancache_init_shared_fs,
 	.init_fs = zcache_cleancache_init_fs
 };
@@ -1867,8 +1923,8 @@ static void zcache_frontswap_init(unsigned ignored)
 static struct frontswap_ops zcache_frontswap_ops = {
 	.put_page = zcache_frontswap_put_page,
 	.get_page = zcache_frontswap_get_page,
-	.flush_page = zcache_frontswap_flush_page,
-	.flush_area = zcache_frontswap_flush_area,
+	.invalidate_page = zcache_frontswap_flush_page,
+	.invalidate_area = zcache_frontswap_flush_area,
 	.init = zcache_frontswap_init
 };
 
@@ -1918,6 +1974,44 @@ static int __init no_frontswap(char *s)
 
 __setup("nofrontswap", no_frontswap);
 
+static int __init enable_zcache_compressor(char *s)
+{
+	strncpy(zcache_comp_name, s, ZCACHE_COMP_NAME_SZ);
+	zcache_enabled = 1;
+	return 1;
+}
+__setup("zcache=", enable_zcache_compressor);
+
+
+static int zcache_comp_init(void)
+{
+	int ret = 0;
+
+	/* check crypto algorithm */
+	if (*zcache_comp_name != '\0') {
+		ret = crypto_has_comp(zcache_comp_name, 0, 0);
+		if (!ret)
+			pr_info("zcache: %s not supported\n",
+					zcache_comp_name);
+	}
+	if (!ret)
+		strcpy(zcache_comp_name, "lzo");
+	ret = crypto_has_comp(zcache_comp_name, 0, 0);
+	if (!ret) {
+		ret = 1;
+		goto out;
+	}
+	pr_info("zcache: using %s compressor\n", zcache_comp_name);
+
+	/* alloc percpu transforms */
+	ret = 0;
+	zcache_comp_pcpu_tfms = alloc_percpu(struct crypto_comp *);
+	if (!zcache_comp_pcpu_tfms)
+		ret = 1;
+out:
+	return ret;
+}
+
 static int __init zcache_init(void)
 {
 	int ret = 0;
@@ -1940,6 +2034,11 @@ static int __init zcache_init(void)
 			pr_err("zcache: can't register cpu notifier\n");
 			goto out;
 		}
+		ret = zcache_comp_init();
+		if (ret) {
+			pr_err("zcache: compressor initialization failed\n");
+			goto out;
+		}
 		for_each_online_cpu(cpu) {
 			void *pcpu = (void *)(long)cpu;
 			zcache_cpu_notifier(&zcache_cpu_notifier_block,
@@ -1975,7 +2074,7 @@ static int __init zcache_init(void)
 
 		old_ops = zcache_frontswap_register_ops();
 		pr_info("zcache: frontswap enabled using kernel "
-			"transcendent memory and xvmalloc\n");
+			"transcendent memory and zsmalloc\n");
 		if (old_ops.init != NULL)
 			pr_warning("zcache: frontswap_ops overridden");
 	}
diff --git a/drivers/staging/zram/Kconfig b/drivers/staging/zram/Kconfig
index 3bec4db..9d11a4c 100644
--- a/drivers/staging/zram/Kconfig
+++ b/drivers/staging/zram/Kconfig
@@ -1,11 +1,9 @@
-config XVMALLOC
-	bool
-	default n
-
 config ZRAM
 	tristate "Compressed RAM block device support"
-	depends on BLOCK && SYSFS
-	select XVMALLOC
+	# X86 dependency is because zsmalloc uses non-portable pte/tlb
+	# functions
+	depends on BLOCK && SYSFS && X86
+	select ZSMALLOC
 	select LZO_COMPRESS
 	select LZO_DECOMPRESS
 	default n
diff --git a/drivers/staging/zram/Makefile b/drivers/staging/zram/Makefile
index 2a6d321..7f4a301 100644
--- a/drivers/staging/zram/Makefile
+++ b/drivers/staging/zram/Makefile
@@ -1,4 +1,3 @@
 zram-y	:=	zram_drv.o zram_sysfs.o
 
 obj-$(CONFIG_ZRAM)	+=	zram.o
-obj-$(CONFIG_XVMALLOC)	+=	xvmalloc.o
\ No newline at end of file
diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c
deleted file mode 100644
index 1f9c508..0000000
--- a/drivers/staging/zram/xvmalloc.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * xvmalloc memory allocator
- *
- * Copyright (C) 2008, 2009, 2010  Nitin Gupta
- *
- * This code is released using a dual license strategy: BSD/GPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of 3-clause BSD License
- * Released under the terms of GNU General Public License Version 2.0
- */
-
-#ifdef CONFIG_ZRAM_DEBUG
-#define DEBUG
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitops.h>
-#include <linux/errno.h>
-#include <linux/highmem.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "xvmalloc.h"
-#include "xvmalloc_int.h"
-
-static void stat_inc(u64 *value)
-{
-	*value = *value + 1;
-}
-
-static void stat_dec(u64 *value)
-{
-	*value = *value - 1;
-}
-
-static int test_flag(struct block_header *block, enum blockflags flag)
-{
-	return block->prev & BIT(flag);
-}
-
-static void set_flag(struct block_header *block, enum blockflags flag)
-{
-	block->prev |= BIT(flag);
-}
-
-static void clear_flag(struct block_header *block, enum blockflags flag)
-{
-	block->prev &= ~BIT(flag);
-}
-
-/*
- * Given <page, offset> pair, provide a dereferencable pointer.
- * This is called from xv_malloc/xv_free path, so it
- * needs to be fast.
- */
-static void *get_ptr_atomic(struct page *page, u16 offset, enum km_type type)
-{
-	unsigned char *base;
-
-	base = kmap_atomic(page, type);
-	return base + offset;
-}
-
-static void put_ptr_atomic(void *ptr, enum km_type type)
-{
-	kunmap_atomic(ptr, type);
-}
-
-static u32 get_blockprev(struct block_header *block)
-{
-	return block->prev & PREV_MASK;
-}
-
-static void set_blockprev(struct block_header *block, u16 new_offset)
-{
-	block->prev = new_offset | (block->prev & FLAGS_MASK);
-}
-
-static struct block_header *BLOCK_NEXT(struct block_header *block)
-{
-	return (struct block_header *)
-		((char *)block + block->size + XV_ALIGN);
-}
-
-/*
- * Get index of free list containing blocks of maximum size
- * which is less than or equal to given size.
- */
-static u32 get_index_for_insert(u32 size)
-{
-	if (unlikely(size > XV_MAX_ALLOC_SIZE))
-		size = XV_MAX_ALLOC_SIZE;
-	size &= ~FL_DELTA_MASK;
-	return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT;
-}
-
-/*
- * Get index of free list having blocks of size greater than
- * or equal to requested size.
- */
-static u32 get_index(u32 size)
-{
-	if (unlikely(size < XV_MIN_ALLOC_SIZE))
-		size = XV_MIN_ALLOC_SIZE;
-	size = ALIGN(size, FL_DELTA);
-	return (size - XV_MIN_ALLOC_SIZE) >> FL_DELTA_SHIFT;
-}
-
-/**
- * find_block - find block of at least given size
- * @pool: memory pool to search from
- * @size: size of block required
- * @page: page containing required block
- * @offset: offset within the page where block is located.
- *
- * Searches two level bitmap to locate block of at least
- * the given size. If such a block is found, it provides
- * <page, offset> to identify this block and returns index
- * in freelist where we found this block.
- * Otherwise, returns 0 and <page, offset> params are not touched.
- */
-static u32 find_block(struct xv_pool *pool, u32 size,
-			struct page **page, u32 *offset)
-{
-	ulong flbitmap, slbitmap;
-	u32 flindex, slindex, slbitstart;
-
-	/* There are no free blocks in this pool */
-	if (!pool->flbitmap)
-		return 0;
-
-	/* Get freelist index correspoding to this size */
-	slindex = get_index(size);
-	slbitmap = pool->slbitmap[slindex / BITS_PER_LONG];
-	slbitstart = slindex % BITS_PER_LONG;
-
-	/*
-	 * If freelist is not empty at this index, we found the
-	 * block - head of this list. This is approximate best-fit match.
-	 */
-	if (test_bit(slbitstart, &slbitmap)) {
-		*page = pool->freelist[slindex].page;
-		*offset = pool->freelist[slindex].offset;
-		return slindex;
-	}
-
-	/*
-	 * No best-fit found. Search a bit further in bitmap for a free block.
-	 * Second level bitmap consists of series of 32-bit chunks. Search
-	 * further in the chunk where we expected a best-fit, starting from
-	 * index location found above.
-	 */
-	slbitstart++;
-	slbitmap >>= slbitstart;
-
-	/* Skip this search if we were already at end of this bitmap chunk */
-	if ((slbitstart != BITS_PER_LONG) && slbitmap) {
-		slindex += __ffs(slbitmap) + 1;
-		*page = pool->freelist[slindex].page;
-		*offset = pool->freelist[slindex].offset;
-		return slindex;
-	}
-
-	/* Now do a full two-level bitmap search to find next nearest fit */
-	flindex = slindex / BITS_PER_LONG;
-
-	flbitmap = (pool->flbitmap) >> (flindex + 1);
-	if (!flbitmap)
-		return 0;
-
-	flindex += __ffs(flbitmap) + 1;
-	slbitmap = pool->slbitmap[flindex];
-	slindex = (flindex * BITS_PER_LONG) + __ffs(slbitmap);
-	*page = pool->freelist[slindex].page;
-	*offset = pool->freelist[slindex].offset;
-
-	return slindex;
-}
-
-/*
- * Insert block at <page, offset> in freelist of given pool.
- * freelist used depends on block size.
- */
-static void insert_block(struct xv_pool *pool, struct page *page, u32 offset,
-			struct block_header *block)
-{
-	u32 flindex, slindex;
-	struct block_header *nextblock;
-
-	slindex = get_index_for_insert(block->size);
-	flindex = slindex / BITS_PER_LONG;
-
-	block->link.prev_page = NULL;
-	block->link.prev_offset = 0;
-	block->link.next_page = pool->freelist[slindex].page;
-	block->link.next_offset = pool->freelist[slindex].offset;
-	pool->freelist[slindex].page = page;
-	pool->freelist[slindex].offset = offset;
-
-	if (block->link.next_page) {
-		nextblock = get_ptr_atomic(block->link.next_page,
-					block->link.next_offset, KM_USER1);
-		nextblock->link.prev_page = page;
-		nextblock->link.prev_offset = offset;
-		put_ptr_atomic(nextblock, KM_USER1);
-		/* If there was a next page then the free bits are set. */
-		return;
-	}
-
-	__set_bit(slindex % BITS_PER_LONG, &pool->slbitmap[flindex]);
-	__set_bit(flindex, &pool->flbitmap);
-}
-
-/*
- * Remove block from freelist. Index 'slindex' identifies the freelist.
- */
-static void remove_block(struct xv_pool *pool, struct page *page, u32 offset,
-			struct block_header *block, u32 slindex)
-{
-	u32 flindex = slindex / BITS_PER_LONG;
-	struct block_header *tmpblock;
-
-	if (block->link.prev_page) {
-		tmpblock = get_ptr_atomic(block->link.prev_page,
-				block->link.prev_offset, KM_USER1);
-		tmpblock->link.next_page = block->link.next_page;
-		tmpblock->link.next_offset = block->link.next_offset;
-		put_ptr_atomic(tmpblock, KM_USER1);
-	}
-
-	if (block->link.next_page) {
-		tmpblock = get_ptr_atomic(block->link.next_page,
-				block->link.next_offset, KM_USER1);
-		tmpblock->link.prev_page = block->link.prev_page;
-		tmpblock->link.prev_offset = block->link.prev_offset;
-		put_ptr_atomic(tmpblock, KM_USER1);
-	}
-
-	/* Is this block is at the head of the freelist? */
-	if (pool->freelist[slindex].page == page
-	   && pool->freelist[slindex].offset == offset) {
-
-		pool->freelist[slindex].page = block->link.next_page;
-		pool->freelist[slindex].offset = block->link.next_offset;
-
-		if (pool->freelist[slindex].page) {
-			struct block_header *tmpblock;
-			tmpblock = get_ptr_atomic(pool->freelist[slindex].page,
-					pool->freelist[slindex].offset,
-					KM_USER1);
-			tmpblock->link.prev_page = NULL;
-			tmpblock->link.prev_offset = 0;
-			put_ptr_atomic(tmpblock, KM_USER1);
-		} else {
-			/* This freelist bucket is empty */
-			__clear_bit(slindex % BITS_PER_LONG,
-				    &pool->slbitmap[flindex]);
-			if (!pool->slbitmap[flindex])
-				__clear_bit(flindex, &pool->flbitmap);
-		}
-	}
-
-	block->link.prev_page = NULL;
-	block->link.prev_offset = 0;
-	block->link.next_page = NULL;
-	block->link.next_offset = 0;
-}
-
-/*
- * Allocate a page and add it to freelist of given pool.
- */
-static int grow_pool(struct xv_pool *pool, gfp_t flags)
-{
-	struct page *page;
-	struct block_header *block;
-
-	page = alloc_page(flags);
-	if (unlikely(!page))
-		return -ENOMEM;
-
-	stat_inc(&pool->total_pages);
-
-	spin_lock(&pool->lock);
-	block = get_ptr_atomic(page, 0, KM_USER0);
-
-	block->size = PAGE_SIZE - XV_ALIGN;
-	set_flag(block, BLOCK_FREE);
-	clear_flag(block, PREV_FREE);
-	set_blockprev(block, 0);
-
-	insert_block(pool, page, 0, block);
-
-	put_ptr_atomic(block, KM_USER0);
-	spin_unlock(&pool->lock);
-
-	return 0;
-}
-
-/*
- * Create a memory pool. Allocates freelist, bitmaps and other
- * per-pool metadata.
- */
-struct xv_pool *xv_create_pool(void)
-{
-	u32 ovhd_size;
-	struct xv_pool *pool;
-
-	ovhd_size = roundup(sizeof(*pool), PAGE_SIZE);
-	pool = kzalloc(ovhd_size, GFP_KERNEL);
-	if (!pool)
-		return NULL;
-
-	spin_lock_init(&pool->lock);
-
-	return pool;
-}
-EXPORT_SYMBOL_GPL(xv_create_pool);
-
-void xv_destroy_pool(struct xv_pool *pool)
-{
-	kfree(pool);
-}
-EXPORT_SYMBOL_GPL(xv_destroy_pool);
-
-/**
- * xv_malloc - Allocate block of given size from pool.
- * @pool: pool to allocate from
- * @size: size of block to allocate
- * @page: page no. that holds the object
- * @offset: location of object within page
- *
- * On success, <page, offset> identifies block allocated
- * and 0 is returned. On failure, <page, offset> is set to
- * 0 and -ENOMEM is returned.
- *
- * Allocation requests with size > XV_MAX_ALLOC_SIZE will fail.
- */
-int xv_malloc(struct xv_pool *pool, u32 size, struct page **page,
-		u32 *offset, gfp_t flags)
-{
-	int error;
-	u32 index, tmpsize, origsize, tmpoffset;
-	struct block_header *block, *tmpblock;
-
-	*page = NULL;
-	*offset = 0;
-	origsize = size;
-
-	if (unlikely(!size || size > XV_MAX_ALLOC_SIZE))
-		return -ENOMEM;
-
-	size = ALIGN(size, XV_ALIGN);
-
-	spin_lock(&pool->lock);
-
-	index = find_block(pool, size, page, offset);
-
-	if (!*page) {
-		spin_unlock(&pool->lock);
-		if (flags & GFP_NOWAIT)
-			return -ENOMEM;
-		error = grow_pool(pool, flags);
-		if (unlikely(error))
-			return error;
-
-		spin_lock(&pool->lock);
-		index = find_block(pool, size, page, offset);
-	}
-
-	if (!*page) {
-		spin_unlock(&pool->lock);
-		return -ENOMEM;
-	}
-
-	block = get_ptr_atomic(*page, *offset, KM_USER0);
-
-	remove_block(pool, *page, *offset, block, index);
-
-	/* Split the block if required */
-	tmpoffset = *offset + size + XV_ALIGN;
-	tmpsize = block->size - size;
-	tmpblock = (struct block_header *)((char *)block + size + XV_ALIGN);
-	if (tmpsize) {
-		tmpblock->size = tmpsize - XV_ALIGN;
-		set_flag(tmpblock, BLOCK_FREE);
-		clear_flag(tmpblock, PREV_FREE);
-
-		set_blockprev(tmpblock, *offset);
-		if (tmpblock->size >= XV_MIN_ALLOC_SIZE)
-			insert_block(pool, *page, tmpoffset, tmpblock);
-
-		if (tmpoffset + XV_ALIGN + tmpblock->size != PAGE_SIZE) {
-			tmpblock = BLOCK_NEXT(tmpblock);
-			set_blockprev(tmpblock, tmpoffset);
-		}
-	} else {
-		/* This block is exact fit */
-		if (tmpoffset != PAGE_SIZE)
-			clear_flag(tmpblock, PREV_FREE);
-	}
-
-	block->size = origsize;
-	clear_flag(block, BLOCK_FREE);
-
-	put_ptr_atomic(block, KM_USER0);
-	spin_unlock(&pool->lock);
-
-	*offset += XV_ALIGN;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(xv_malloc);
-
-/*
- * Free block identified with <page, offset>
- */
-void xv_free(struct xv_pool *pool, struct page *page, u32 offset)
-{
-	void *page_start;
-	struct block_header *block, *tmpblock;
-
-	offset -= XV_ALIGN;
-
-	spin_lock(&pool->lock);
-
-	page_start = get_ptr_atomic(page, 0, KM_USER0);
-	block = (struct block_header *)((char *)page_start + offset);
-
-	/* Catch double free bugs */
-	BUG_ON(test_flag(block, BLOCK_FREE));
-
-	block->size = ALIGN(block->size, XV_ALIGN);
-
-	tmpblock = BLOCK_NEXT(block);
-	if (offset + block->size + XV_ALIGN == PAGE_SIZE)
-		tmpblock = NULL;
-
-	/* Merge next block if its free */
-	if (tmpblock && test_flag(tmpblock, BLOCK_FREE)) {
-		/*
-		 * Blocks smaller than XV_MIN_ALLOC_SIZE
-		 * are not inserted in any free list.
-		 */
-		if (tmpblock->size >= XV_MIN_ALLOC_SIZE) {
-			remove_block(pool, page,
-				    offset + block->size + XV_ALIGN, tmpblock,
-				    get_index_for_insert(tmpblock->size));
-		}
-		block->size += tmpblock->size + XV_ALIGN;
-	}
-
-	/* Merge previous block if its free */
-	if (test_flag(block, PREV_FREE)) {
-		tmpblock = (struct block_header *)((char *)(page_start) +
-						get_blockprev(block));
-		offset = offset - tmpblock->size - XV_ALIGN;
-
-		if (tmpblock->size >= XV_MIN_ALLOC_SIZE)
-			remove_block(pool, page, offset, tmpblock,
-				    get_index_for_insert(tmpblock->size));
-
-		tmpblock->size += block->size + XV_ALIGN;
-		block = tmpblock;
-	}
-
-	/* No used objects in this page. Free it. */
-	if (block->size == PAGE_SIZE - XV_ALIGN) {
-		put_ptr_atomic(page_start, KM_USER0);
-		spin_unlock(&pool->lock);
-
-		__free_page(page);
-		stat_dec(&pool->total_pages);
-		return;
-	}
-
-	set_flag(block, BLOCK_FREE);
-	if (block->size >= XV_MIN_ALLOC_SIZE)
-		insert_block(pool, page, offset, block);
-
-	if (offset + block->size + XV_ALIGN != PAGE_SIZE) {
-		tmpblock = BLOCK_NEXT(block);
-		set_flag(tmpblock, PREV_FREE);
-		set_blockprev(tmpblock, offset);
-	}
-
-	put_ptr_atomic(page_start, KM_USER0);
-	spin_unlock(&pool->lock);
-}
-EXPORT_SYMBOL_GPL(xv_free);
-
-u32 xv_get_object_size(void *obj)
-{
-	struct block_header *blk;
-
-	blk = (struct block_header *)((char *)(obj) - XV_ALIGN);
-	return blk->size;
-}
-EXPORT_SYMBOL_GPL(xv_get_object_size);
-
-/*
- * Returns total memory used by allocator (userdata + metadata)
- */
-u64 xv_get_total_size_bytes(struct xv_pool *pool)
-{
-	return pool->total_pages << PAGE_SHIFT;
-}
-EXPORT_SYMBOL_GPL(xv_get_total_size_bytes);
diff --git a/drivers/staging/zram/xvmalloc.h b/drivers/staging/zram/xvmalloc.h
deleted file mode 100644
index 5b1a81a..0000000
--- a/drivers/staging/zram/xvmalloc.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * xvmalloc memory allocator
- *
- * Copyright (C) 2008, 2009, 2010  Nitin Gupta
- *
- * This code is released using a dual license strategy: BSD/GPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of 3-clause BSD License
- * Released under the terms of GNU General Public License Version 2.0
- */
-
-#ifndef _XV_MALLOC_H_
-#define _XV_MALLOC_H_
-
-#include <linux/types.h>
-
-struct xv_pool;
-
-struct xv_pool *xv_create_pool(void);
-void xv_destroy_pool(struct xv_pool *pool);
-
-int xv_malloc(struct xv_pool *pool, u32 size, struct page **page,
-			u32 *offset, gfp_t flags);
-void xv_free(struct xv_pool *pool, struct page *page, u32 offset);
-
-u32 xv_get_object_size(void *obj);
-u64 xv_get_total_size_bytes(struct xv_pool *pool);
-
-#endif
diff --git a/drivers/staging/zram/xvmalloc_int.h b/drivers/staging/zram/xvmalloc_int.h
deleted file mode 100644
index b5f1f7f..0000000
--- a/drivers/staging/zram/xvmalloc_int.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * xvmalloc memory allocator
- *
- * Copyright (C) 2008, 2009, 2010  Nitin Gupta
- *
- * This code is released using a dual license strategy: BSD/GPL
- * You can choose the licence that better fits your requirements.
- *
- * Released under the terms of 3-clause BSD License
- * Released under the terms of GNU General Public License Version 2.0
- */
-
-#ifndef _XV_MALLOC_INT_H_
-#define _XV_MALLOC_INT_H_
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-/* User configurable params */
-
-/* Must be power of two */
-#ifdef CONFIG_64BIT
-#define XV_ALIGN_SHIFT 3
-#else
-#define XV_ALIGN_SHIFT	2
-#endif
-#define XV_ALIGN	(1 << XV_ALIGN_SHIFT)
-#define XV_ALIGN_MASK	(XV_ALIGN - 1)
-
-/* This must be greater than sizeof(link_free) */
-#define XV_MIN_ALLOC_SIZE	32
-#define XV_MAX_ALLOC_SIZE	(PAGE_SIZE - XV_ALIGN)
-
-/*
- * Free lists are separated by FL_DELTA bytes
- * This value is 3 for 4k pages and 4 for 64k pages, for any
- * other page size, a conservative (PAGE_SHIFT - 9) is used.
- */
-#if PAGE_SHIFT == 16
-#define FL_DELTA_SHIFT 4
-#else
-#define FL_DELTA_SHIFT (PAGE_SHIFT - 9)
-#endif
-#define FL_DELTA	(1 << FL_DELTA_SHIFT)
-#define FL_DELTA_MASK	(FL_DELTA - 1)
-#define NUM_FREE_LISTS	((XV_MAX_ALLOC_SIZE - XV_MIN_ALLOC_SIZE) \
-				/ FL_DELTA + 1)
-
-#define MAX_FLI		DIV_ROUND_UP(NUM_FREE_LISTS, BITS_PER_LONG)
-
-/* End of user params */
-
-enum blockflags {
-	BLOCK_FREE,
-	PREV_FREE,
-	__NR_BLOCKFLAGS,
-};
-
-#define FLAGS_MASK	XV_ALIGN_MASK
-#define PREV_MASK	(~FLAGS_MASK)
-
-struct freelist_entry {
-	struct page *page;
-	u16 offset;
-	u16 pad;
-};
-
-struct link_free {
-	struct page *prev_page;
-	struct page *next_page;
-	u16 prev_offset;
-	u16 next_offset;
-};
-
-struct block_header {
-	union {
-		/* This common header must be XV_ALIGN bytes */
-		u8 common[XV_ALIGN];
-		struct {
-			u16 size;
-			u16 prev;
-		};
-	};
-	struct link_free link;
-};
-
-struct xv_pool {
-	ulong flbitmap;
-	ulong slbitmap[MAX_FLI];
-	u64 total_pages;	/* stats */
-	struct freelist_entry freelist[NUM_FREE_LISTS];
-	spinlock_t lock;
-};
-
-#endif
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 2a2a92d..685d612 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -40,7 +40,7 @@ static int zram_major;
 struct zram *zram_devices;
 
 /* Module params (documentation at end) */
-unsigned int zram_num_devices;
+static unsigned int num_devices;
 
 static void zram_stat_inc(u32 *v)
 {
@@ -135,13 +135,9 @@ static void zram_set_disksize(struct zram *zram, size_t totalram_bytes)
 
 static void zram_free_page(struct zram *zram, size_t index)
 {
-	u32 clen;
-	void *obj;
+	void *handle = zram->table[index].handle;
 
-	struct page *page = zram->table[index].page;
-	u32 offset = zram->table[index].offset;
-
-	if (unlikely(!page)) {
+	if (unlikely(!handle)) {
 		/*
 		 * No memory is allocated for zero filled pages.
 		 * Simply clear zero page flag.
@@ -154,27 +150,24 @@ static void zram_free_page(struct zram *zram, size_t index)
 	}
 
 	if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
-		clen = PAGE_SIZE;
-		__free_page(page);
+		__free_page(handle);
 		zram_clear_flag(zram, index, ZRAM_UNCOMPRESSED);
 		zram_stat_dec(&zram->stats.pages_expand);
 		goto out;
 	}
 
-	obj = kmap_atomic(page, KM_USER0) + offset;
-	clen = xv_get_object_size(obj) - sizeof(struct zobj_header);
-	kunmap_atomic(obj, KM_USER0);
+	zs_free(zram->mem_pool, handle);
 
-	xv_free(zram->mem_pool, page, offset);
-	if (clen <= PAGE_SIZE / 2)
+	if (zram->table[index].size <= PAGE_SIZE / 2)
 		zram_stat_dec(&zram->stats.good_compress);
 
 out:
-	zram_stat64_sub(zram, &zram->stats.compr_size, clen);
+	zram_stat64_sub(zram, &zram->stats.compr_size,
+			zram->table[index].size);
 	zram_stat_dec(&zram->stats.pages_stored);
 
-	zram->table[index].page = NULL;
-	zram->table[index].offset = 0;
+	zram->table[index].handle = NULL;
+	zram->table[index].size = 0;
 }
 
 static void handle_zero_page(struct bio_vec *bvec)
@@ -182,9 +175,9 @@ static void handle_zero_page(struct bio_vec *bvec)
 	struct page *page = bvec->bv_page;
 	void *user_mem;
 
-	user_mem = kmap_atomic(page, KM_USER0);
+	user_mem = kmap_atomic(page);
 	memset(user_mem + bvec->bv_offset, 0, bvec->bv_len);
-	kunmap_atomic(user_mem, KM_USER0);
+	kunmap_atomic(user_mem);
 
 	flush_dcache_page(page);
 }
@@ -195,12 +188,12 @@ static void handle_uncompressed_page(struct zram *zram, struct bio_vec *bvec,
 	struct page *page = bvec->bv_page;
 	unsigned char *user_mem, *cmem;
 
-	user_mem = kmap_atomic(page, KM_USER0);
-	cmem = kmap_atomic(zram->table[index].page, KM_USER1);
+	user_mem = kmap_atomic(page);
+	cmem = kmap_atomic(zram->table[index].handle);
 
 	memcpy(user_mem + bvec->bv_offset, cmem + offset, bvec->bv_len);
-	kunmap_atomic(cmem, KM_USER1);
-	kunmap_atomic(user_mem, KM_USER0);
+	kunmap_atomic(cmem);
+	kunmap_atomic(user_mem);
 
 	flush_dcache_page(page);
 }
@@ -227,7 +220,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
 	}
 
 	/* Requested page is not present in compressed area */
-	if (unlikely(!zram->table[index].page)) {
+	if (unlikely(!zram->table[index].handle)) {
 		pr_debug("Read before write: sector=%lu, size=%u",
 			 (ulong)(bio->bi_sector), bio->bi_size);
 		handle_zero_page(bvec);
@@ -249,16 +242,15 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
 		}
 	}
 
-	user_mem = kmap_atomic(page, KM_USER0);
+	user_mem = kmap_atomic(page);
 	if (!is_partial_io(bvec))
 		uncmem = user_mem;
 	clen = PAGE_SIZE;
 
-	cmem = kmap_atomic(zram->table[index].page, KM_USER1) +
-		zram->table[index].offset;
+	cmem = zs_map_object(zram->mem_pool, zram->table[index].handle);
 
 	ret = lzo1x_decompress_safe(cmem + sizeof(*zheader),
-				    xv_get_object_size(cmem) - sizeof(*zheader),
+				    zram->table[index].size,
 				    uncmem, &clen);
 
 	if (is_partial_io(bvec)) {
@@ -267,8 +259,8 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
 		kfree(uncmem);
 	}
 
-	kunmap_atomic(cmem, KM_USER1);
-	kunmap_atomic(user_mem, KM_USER0);
+	zs_unmap_object(zram->mem_pool, zram->table[index].handle);
+	kunmap_atomic(user_mem);
 
 	/* Should NEVER happen. Return bio error if it does. */
 	if (unlikely(ret != LZO_E_OK)) {
@@ -290,25 +282,24 @@ static int zram_read_before_write(struct zram *zram, char *mem, u32 index)
 	unsigned char *cmem;
 
 	if (zram_test_flag(zram, index, ZRAM_ZERO) ||
-	    !zram->table[index].page) {
+	    !zram->table[index].handle) {
 		memset(mem, 0, PAGE_SIZE);
 		return 0;
 	}
 
-	cmem = kmap_atomic(zram->table[index].page, KM_USER0) +
-		zram->table[index].offset;
+	cmem = zs_map_object(zram->mem_pool, zram->table[index].handle);
 
 	/* Page is stored uncompressed since it's incompressible */
 	if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
 		memcpy(mem, cmem, PAGE_SIZE);
-		kunmap_atomic(cmem, KM_USER0);
+		kunmap_atomic(cmem);
 		return 0;
 	}
 
 	ret = lzo1x_decompress_safe(cmem + sizeof(*zheader),
-				    xv_get_object_size(cmem) - sizeof(*zheader),
+				    zram->table[index].size,
 				    mem, &clen);
-	kunmap_atomic(cmem, KM_USER0);
+	zs_unmap_object(zram->mem_pool, zram->table[index].handle);
 
 	/* Should NEVER happen. Return bio error if it does. */
 	if (unlikely(ret != LZO_E_OK)) {
@@ -326,6 +317,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 	int ret;
 	u32 store_offset;
 	size_t clen;
+	void *handle;
 	struct zobj_header *zheader;
 	struct page *page, *page_store;
 	unsigned char *user_mem, *cmem, *src, *uncmem = NULL;
@@ -355,11 +347,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 	 * System overwrites unused sectors. Free memory associated
 	 * with this sector now.
 	 */
-	if (zram->table[index].page ||
+	if (zram->table[index].handle ||
 	    zram_test_flag(zram, index, ZRAM_ZERO))
 		zram_free_page(zram, index);
 
-	user_mem = kmap_atomic(page, KM_USER0);
+	user_mem = kmap_atomic(page);
 
 	if (is_partial_io(bvec))
 		memcpy(uncmem + offset, user_mem + bvec->bv_offset,
@@ -368,7 +360,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 		uncmem = user_mem;
 
 	if (page_zero_filled(uncmem)) {
-		kunmap_atomic(user_mem, KM_USER0);
+		kunmap_atomic(user_mem);
 		if (is_partial_io(bvec))
 			kfree(uncmem);
 		zram_stat_inc(&zram->stats.pages_zero);
@@ -380,7 +372,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 	ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen,
 			       zram->compress_workmem);
 
-	kunmap_atomic(user_mem, KM_USER0);
+	kunmap_atomic(user_mem);
 	if (is_partial_io(bvec))
 			kfree(uncmem);
 
@@ -407,26 +399,22 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 		store_offset = 0;
 		zram_set_flag(zram, index, ZRAM_UNCOMPRESSED);
 		zram_stat_inc(&zram->stats.pages_expand);
-		zram->table[index].page = page_store;
-		src = kmap_atomic(page, KM_USER0);
+		handle = page_store;
+		src = kmap_atomic(page);
+		cmem = kmap_atomic(page_store);
 		goto memstore;
 	}
 
-	if (xv_malloc(zram->mem_pool, clen + sizeof(*zheader),
-		      &zram->table[index].page, &store_offset,
-		      GFP_NOIO | __GFP_HIGHMEM)) {
+	handle = zs_malloc(zram->mem_pool, clen + sizeof(*zheader));
+	if (!handle) {
 		pr_info("Error allocating memory for compressed "
 			"page: %u, size=%zu\n", index, clen);
 		ret = -ENOMEM;
 		goto out;
 	}
+	cmem = zs_map_object(zram->mem_pool, handle);
 
 memstore:
-	zram->table[index].offset = store_offset;
-
-	cmem = kmap_atomic(zram->table[index].page, KM_USER1) +
-		zram->table[index].offset;
-
 #if 0
 	/* Back-reference needed for memory defragmentation */
 	if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) {
@@ -438,9 +426,15 @@ memstore:
 
 	memcpy(cmem, src, clen);
 
-	kunmap_atomic(cmem, KM_USER1);
-	if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)))
-		kunmap_atomic(src, KM_USER0);
+	if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) {
+		kunmap_atomic(cmem);
+		kunmap_atomic(src);
+	} else {
+		zs_unmap_object(zram->mem_pool, handle);
+	}
+
+	zram->table[index].handle = handle;
+	zram->table[index].size = clen;
 
 	/* Update stats */
 	zram_stat64_add(zram, &zram->stats.compr_size, clen);
@@ -598,25 +592,20 @@ void __zram_reset_device(struct zram *zram)
 
 	/* Free all pages that are still in this zram device */
 	for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) {
-		struct page *page;
-		u16 offset;
-
-		page = zram->table[index].page;
-		offset = zram->table[index].offset;
-
-		if (!page)
+		void *handle = zram->table[index].handle;
+		if (!handle)
 			continue;
 
 		if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)))
-			__free_page(page);
+			__free_page(handle);
 		else
-			xv_free(zram->mem_pool, page, offset);
+			zs_free(zram->mem_pool, handle);
 	}
 
 	vfree(zram->table);
 	zram->table = NULL;
 
-	xv_destroy_pool(zram->mem_pool);
+	zs_destroy_pool(zram->mem_pool);
 	zram->mem_pool = NULL;
 
 	/* Reset stats */
@@ -674,7 +663,7 @@ int zram_init_device(struct zram *zram)
 	/* zram devices sort of resembles non-rotational disks */
 	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
 
-	zram->mem_pool = xv_create_pool();
+	zram->mem_pool = zs_create_pool("zram", GFP_NOIO | __GFP_HIGHMEM);
 	if (!zram->mem_pool) {
 		pr_err("Error creating memory pool\n");
 		ret = -ENOMEM;
@@ -790,13 +779,18 @@ static void destroy_device(struct zram *zram)
 		blk_cleanup_queue(zram->queue);
 }
 
+unsigned int zram_get_num_devices(void)
+{
+	return num_devices;
+}
+
 static int __init zram_init(void)
 {
 	int ret, dev_id;
 
-	if (zram_num_devices > max_num_devices) {
+	if (num_devices > max_num_devices) {
 		pr_warning("Invalid value for num_devices: %u\n",
-				zram_num_devices);
+				num_devices);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -808,20 +802,20 @@ static int __init zram_init(void)
 		goto out;
 	}
 
-	if (!zram_num_devices) {
+	if (!num_devices) {
 		pr_info("num_devices not specified. Using default: 1\n");
-		zram_num_devices = 1;
+		num_devices = 1;
 	}
 
 	/* Allocate the device array and initialize each one */
-	pr_info("Creating %u devices ...\n", zram_num_devices);
-	zram_devices = kzalloc(zram_num_devices * sizeof(struct zram), GFP_KERNEL);
+	pr_info("Creating %u devices ...\n", num_devices);
+	zram_devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL);
 	if (!zram_devices) {
 		ret = -ENOMEM;
 		goto unregister;
 	}
 
-	for (dev_id = 0; dev_id < zram_num_devices; dev_id++) {
+	for (dev_id = 0; dev_id < num_devices; dev_id++) {
 		ret = create_device(&zram_devices[dev_id], dev_id);
 		if (ret)
 			goto free_devices;
@@ -844,7 +838,7 @@ static void __exit zram_exit(void)
 	int i;
 	struct zram *zram;
 
-	for (i = 0; i < zram_num_devices; i++) {
+	for (i = 0; i < num_devices; i++) {
 		zram = &zram_devices[i];
 
 		destroy_device(zram);
@@ -858,8 +852,8 @@ static void __exit zram_exit(void)
 	pr_debug("Cleanup done!\n");
 }
 
-module_param(zram_num_devices, uint, 0);
-MODULE_PARM_DESC(zram_num_devices, "Number of zram devices");
+module_param(num_devices, uint, 0);
+MODULE_PARM_DESC(num_devices, "Number of zram devices");
 
 module_init(zram_init);
 module_exit(zram_exit);
diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h
index e5cd246..fbe8ac9 100644
--- a/drivers/staging/zram/zram_drv.h
+++ b/drivers/staging/zram/zram_drv.h
@@ -18,7 +18,7 @@
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 
-#include "xvmalloc.h"
+#include "../zsmalloc/zsmalloc.h"
 
 /*
  * Some arbitrary value. This is just to catch
@@ -51,7 +51,7 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
 
 /*
  * NOTE: max_zpage_size must be less than or equal to:
- *   XV_MAX_ALLOC_SIZE - sizeof(struct zobj_header)
+ *   ZS_MAX_ALLOC_SIZE - sizeof(struct zobj_header)
  * otherwise, xv_malloc() would always return failure.
  */
 
@@ -81,8 +81,8 @@ enum zram_pageflags {
 
 /* Allocated for each disk page */
 struct table {
-	struct page *page;
-	u16 offset;
+	void *handle;
+	u16 size;	/* object size (excluding header) */
 	u8 count;	/* object ref count (not yet used) */
 	u8 flags;
 } __attribute__((aligned(4)));
@@ -102,7 +102,7 @@ struct zram_stats {
 };
 
 struct zram {
-	struct xv_pool *mem_pool;
+	struct zs_pool *mem_pool;
 	void *compress_workmem;
 	void *compress_buffer;
 	struct table *table;
@@ -124,7 +124,7 @@ struct zram {
 };
 
 extern struct zram *zram_devices;
-extern unsigned int zram_num_devices;
+unsigned int zram_get_num_devices(void);
 #ifdef CONFIG_SYSFS
 extern struct attribute_group zram_disk_attr_group;
 #endif
diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c
index d521122..a7f3771 100644
--- a/drivers/staging/zram/zram_sysfs.c
+++ b/drivers/staging/zram/zram_sysfs.c
@@ -34,7 +34,7 @@ static struct zram *dev_to_zram(struct device *dev)
 	int i;
 	struct zram *zram = NULL;
 
-	for (i = 0; i < zram_num_devices; i++) {
+	for (i = 0; i < zram_get_num_devices(); i++) {
 		zram = &zram_devices[i];
 		if (disk_to_dev(zram->disk) == dev)
 			break;
@@ -187,7 +187,7 @@ static ssize_t mem_used_total_show(struct device *dev,
 	struct zram *zram = dev_to_zram(dev);
 
 	if (zram->init_done) {
-		val = xv_get_total_size_bytes(zram->mem_pool) +
+		val = zs_get_total_size_bytes(zram->mem_pool) +
 			((u64)(zram->stats.pages_expand) << PAGE_SHIFT);
 	}
 
diff --git a/drivers/staging/zsmalloc/Kconfig b/drivers/staging/zsmalloc/Kconfig
new file mode 100644
index 0000000..8e2c6a0
--- /dev/null
+++ b/drivers/staging/zsmalloc/Kconfig
@@ -0,0 +1,14 @@
+config ZSMALLOC
+	tristate "Memory allocator for compressed pages"
+	# X86 dependency is because of the use of __flush_tlb_one and set_pte
+	# in zsmalloc-main.c.
+	# TODO: convert these to portable functions
+	depends on SPARSEMEM && X86
+	default n
+	help
+	  zsmalloc is a slab-based memory allocator designed to store
+	  compressed RAM pages.  zsmalloc uses virtual memory mapping
+	  in order to reduce fragmentation.  However, this results in a
+	  non-standard allocator interface where a handle, not a pointer, is
+	  returned by an alloc().  This handle must be mapped in order to
+	  access the allocated space.
diff --git a/drivers/staging/zsmalloc/Makefile b/drivers/staging/zsmalloc/Makefile
new file mode 100644
index 0000000..b134848
--- /dev/null
+++ b/drivers/staging/zsmalloc/Makefile
@@ -0,0 +1,3 @@
+zsmalloc-y 		:= zsmalloc-main.o
+
+obj-$(CONFIG_ZSMALLOC)	+= zsmalloc.o
diff --git a/drivers/staging/zsmalloc/zsmalloc-main.c b/drivers/staging/zsmalloc/zsmalloc-main.c
new file mode 100644
index 0000000..455fc2f
--- /dev/null
+++ b/drivers/staging/zsmalloc/zsmalloc-main.c
@@ -0,0 +1,757 @@
+/*
+ * zsmalloc memory allocator
+ *
+ * Copyright (C) 2011  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the license that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifdef CONFIG_ZSMALLOC_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+#include <linux/cpumask.h>
+#include <linux/cpu.h>
+#include <linux/vmalloc.h>
+
+#include "zsmalloc.h"
+#include "zsmalloc_int.h"
+
+/*
+ * A zspage's class index and fullness group
+ * are encoded in its (first)page->mapping
+ */
+#define CLASS_IDX_BITS	28
+#define FULLNESS_BITS	4
+#define CLASS_IDX_MASK	((1 << CLASS_IDX_BITS) - 1)
+#define FULLNESS_MASK	((1 << FULLNESS_BITS) - 1)
+
+/*
+ * Object location (<PFN>, <obj_idx>) is encoded as
+ * as single (void *) handle value.
+ *
+ * Note that object index <obj_idx> is relative to system
+ * page <PFN> it is stored in, so for each sub-page belonging
+ * to a zspage, obj_idx starts with 0.
+ */
+#define _PFN_BITS		(MAX_PHYSMEM_BITS - PAGE_SHIFT)
+#define OBJ_INDEX_BITS	(BITS_PER_LONG - _PFN_BITS)
+#define OBJ_INDEX_MASK	((_AC(1, UL) << OBJ_INDEX_BITS) - 1)
+
+/* per-cpu VM mapping areas for zspage accesses that cross page boundaries */
+static DEFINE_PER_CPU(struct mapping_area, zs_map_area);
+
+static int is_first_page(struct page *page)
+{
+	return test_bit(PG_private, &page->flags);
+}
+
+static int is_last_page(struct page *page)
+{
+	return test_bit(PG_private_2, &page->flags);
+}
+
+static void get_zspage_mapping(struct page *page, unsigned int *class_idx,
+				enum fullness_group *fullness)
+{
+	unsigned long m;
+	BUG_ON(!is_first_page(page));
+
+	m = (unsigned long)page->mapping;
+	*fullness = m & FULLNESS_MASK;
+	*class_idx = (m >> FULLNESS_BITS) & CLASS_IDX_MASK;
+}
+
+static void set_zspage_mapping(struct page *page, unsigned int class_idx,
+				enum fullness_group fullness)
+{
+	unsigned long m;
+	BUG_ON(!is_first_page(page));
+
+	m = ((class_idx & CLASS_IDX_MASK) << FULLNESS_BITS) |
+			(fullness & FULLNESS_MASK);
+	page->mapping = (struct address_space *)m;
+}
+
+static int get_size_class_index(int size)
+{
+	int idx = 0;
+
+	if (likely(size > ZS_MIN_ALLOC_SIZE))
+		idx = DIV_ROUND_UP(size - ZS_MIN_ALLOC_SIZE,
+				ZS_SIZE_CLASS_DELTA);
+
+	return idx;
+}
+
+static enum fullness_group get_fullness_group(struct page *page)
+{
+	int inuse, max_objects;
+	enum fullness_group fg;
+	BUG_ON(!is_first_page(page));
+
+	inuse = page->inuse;
+	max_objects = page->objects;
+
+	if (inuse == 0)
+		fg = ZS_EMPTY;
+	else if (inuse == max_objects)
+		fg = ZS_FULL;
+	else if (inuse <= max_objects / fullness_threshold_frac)
+		fg = ZS_ALMOST_EMPTY;
+	else
+		fg = ZS_ALMOST_FULL;
+
+	return fg;
+}
+
+static void insert_zspage(struct page *page, struct size_class *class,
+				enum fullness_group fullness)
+{
+	struct page **head;
+
+	BUG_ON(!is_first_page(page));
+
+	if (fullness >= _ZS_NR_FULLNESS_GROUPS)
+		return;
+
+	head = &class->fullness_list[fullness];
+	if (*head)
+		list_add_tail(&page->lru, &(*head)->lru);
+
+	*head = page;
+}
+
+static void remove_zspage(struct page *page, struct size_class *class,
+				enum fullness_group fullness)
+{
+	struct page **head;
+
+	BUG_ON(!is_first_page(page));
+
+	if (fullness >= _ZS_NR_FULLNESS_GROUPS)
+		return;
+
+	head = &class->fullness_list[fullness];
+	BUG_ON(!*head);
+	if (list_empty(&(*head)->lru))
+		*head = NULL;
+	else if (*head == page)
+		*head = (struct page *)list_entry((*head)->lru.next,
+					struct page, lru);
+
+	list_del_init(&page->lru);
+}
+
+static enum fullness_group fix_fullness_group(struct zs_pool *pool,
+						struct page *page)
+{
+	int class_idx;
+	struct size_class *class;
+	enum fullness_group currfg, newfg;
+
+	BUG_ON(!is_first_page(page));
+
+	get_zspage_mapping(page, &class_idx, &currfg);
+	newfg = get_fullness_group(page);
+	if (newfg == currfg)
+		goto out;
+
+	class = &pool->size_class[class_idx];
+	remove_zspage(page, class, currfg);
+	insert_zspage(page, class, newfg);
+	set_zspage_mapping(page, class_idx, newfg);
+
+out:
+	return newfg;
+}
+
+/*
+ * We have to decide on how many pages to link together
+ * to form a zspage for each size class. This is important
+ * to reduce wastage due to unusable space left at end of
+ * each zspage which is given as:
+ *	wastage = Zp - Zp % size_class
+ * where Zp = zspage size = k * PAGE_SIZE where k = 1, 2, ...
+ *
+ * For example, for size class of 3/8 * PAGE_SIZE, we should
+ * link together 3 PAGE_SIZE sized pages to form a zspage
+ * since then we can perfectly fit in 8 such objects.
+ */
+static int get_zspage_order(int class_size)
+{
+	int i, max_usedpc = 0;
+	/* zspage order which gives maximum used size per KB */
+	int max_usedpc_order = 1;
+
+	for (i = 1; i <= max_zspage_order; i++) {
+		int zspage_size;
+		int waste, usedpc;
+
+		zspage_size = i * PAGE_SIZE;
+		waste = zspage_size % class_size;
+		usedpc = (zspage_size - waste) * 100 / zspage_size;
+
+		if (usedpc > max_usedpc) {
+			max_usedpc = usedpc;
+			max_usedpc_order = i;
+		}
+	}
+
+	return max_usedpc_order;
+}
+
+/*
+ * A single 'zspage' is composed of many system pages which are
+ * linked together using fields in struct page. This function finds
+ * the first/head page, given any component page of a zspage.
+ */
+static struct page *get_first_page(struct page *page)
+{
+	if (is_first_page(page))
+		return page;
+	else
+		return page->first_page;
+}
+
+static struct page *get_next_page(struct page *page)
+{
+	struct page *next;
+
+	if (is_last_page(page))
+		next = NULL;
+	else if (is_first_page(page))
+		next = (struct page *)page->private;
+	else
+		next = list_entry(page->lru.next, struct page, lru);
+
+	return next;
+}
+
+/* Encode <page, obj_idx> as a single handle value */
+static void *obj_location_to_handle(struct page *page, unsigned long obj_idx)
+{
+	unsigned long handle;
+
+	if (!page) {
+		BUG_ON(obj_idx);
+		return NULL;
+	}
+
+	handle = page_to_pfn(page) << OBJ_INDEX_BITS;
+	handle |= (obj_idx & OBJ_INDEX_MASK);
+
+	return (void *)handle;
+}
+
+/* Decode <page, obj_idx> pair from the given object handle */
+static void obj_handle_to_location(void *handle, struct page **page,
+				unsigned long *obj_idx)
+{
+	unsigned long hval = (unsigned long)handle;
+
+	*page = pfn_to_page(hval >> OBJ_INDEX_BITS);
+	*obj_idx = hval & OBJ_INDEX_MASK;
+}
+
+static unsigned long obj_idx_to_offset(struct page *page,
+				unsigned long obj_idx, int class_size)
+{
+	unsigned long off = 0;
+
+	if (!is_first_page(page))
+		off = page->index;
+
+	return off + obj_idx * class_size;
+}
+
+static void free_zspage(struct page *first_page)
+{
+	struct page *nextp, *tmp;
+
+	BUG_ON(!is_first_page(first_page));
+	BUG_ON(first_page->inuse);
+
+	nextp = (struct page *)page_private(first_page);
+
+	clear_bit(PG_private, &first_page->flags);
+	clear_bit(PG_private_2, &first_page->flags);
+	set_page_private(first_page, 0);
+	first_page->mapping = NULL;
+	first_page->freelist = NULL;
+	reset_page_mapcount(first_page);
+	__free_page(first_page);
+
+	/* zspage with only 1 system page */
+	if (!nextp)
+		return;
+
+	list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) {
+		list_del(&nextp->lru);
+		clear_bit(PG_private_2, &nextp->flags);
+		nextp->index = 0;
+		__free_page(nextp);
+	}
+}
+
+/* Initialize a newly allocated zspage */
+static void init_zspage(struct page *first_page, struct size_class *class)
+{
+	unsigned long off = 0;
+	struct page *page = first_page;
+
+	BUG_ON(!is_first_page(first_page));
+	while (page) {
+		struct page *next_page;
+		struct link_free *link;
+		unsigned int i, objs_on_page;
+
+		/*
+		 * page->index stores offset of first object starting
+		 * in the page. For the first page, this is always 0,
+		 * so we use first_page->index (aka ->freelist) to store
+		 * head of corresponding zspage's freelist.
+		 */
+		if (page != first_page)
+			page->index = off;
+
+		link = (struct link_free *)kmap_atomic(page) +
+						off / sizeof(*link);
+		objs_on_page = (PAGE_SIZE - off) / class->size;
+
+		for (i = 1; i <= objs_on_page; i++) {
+			off += class->size;
+			if (off < PAGE_SIZE) {
+				link->next = obj_location_to_handle(page, i);
+				link += class->size / sizeof(*link);
+			}
+		}
+
+		/*
+		 * We now come to the last (full or partial) object on this
+		 * page, which must point to the first object on the next
+		 * page (if present)
+		 */
+		next_page = get_next_page(page);
+		link->next = obj_location_to_handle(next_page, 0);
+		kunmap_atomic(link);
+		page = next_page;
+		off = (off + class->size) % PAGE_SIZE;
+	}
+}
+
+/*
+ * Allocate a zspage for the given size class
+ */
+static struct page *alloc_zspage(struct size_class *class, gfp_t flags)
+{
+	int i, error;
+	struct page *first_page = NULL;
+
+	/*
+	 * Allocate individual pages and link them together as:
+	 * 1. first page->private = first sub-page
+	 * 2. all sub-pages are linked together using page->lru
+	 * 3. each sub-page is linked to the first page using page->first_page
+	 *
+	 * For each size class, First/Head pages are linked together using
+	 * page->lru. Also, we set PG_private to identify the first page
+	 * (i.e. no other sub-page has this flag set) and PG_private_2 to
+	 * identify the last page.
+	 */
+	error = -ENOMEM;
+	for (i = 0; i < class->zspage_order; i++) {
+		struct page *page, *prev_page;
+
+		page = alloc_page(flags);
+		if (!page)
+			goto cleanup;
+
+		INIT_LIST_HEAD(&page->lru);
+		if (i == 0) {	/* first page */
+			set_bit(PG_private, &page->flags);
+			set_page_private(page, 0);
+			first_page = page;
+			first_page->inuse = 0;
+		}
+		if (i == 1)
+			first_page->private = (unsigned long)page;
+		if (i >= 1)
+			page->first_page = first_page;
+		if (i >= 2)
+			list_add(&page->lru, &prev_page->lru);
+		if (i == class->zspage_order - 1)	/* last page */
+			set_bit(PG_private_2, &page->flags);
+
+		prev_page = page;
+	}
+
+	init_zspage(first_page, class);
+
+	first_page->freelist = obj_location_to_handle(first_page, 0);
+	/* Maximum number of objects we can store in this zspage */
+	first_page->objects = class->zspage_order * PAGE_SIZE / class->size;
+
+	error = 0; /* Success */
+
+cleanup:
+	if (unlikely(error) && first_page) {
+		free_zspage(first_page);
+		first_page = NULL;
+	}
+
+	return first_page;
+}
+
+static struct page *find_get_zspage(struct size_class *class)
+{
+	int i;
+	struct page *page;
+
+	for (i = 0; i < _ZS_NR_FULLNESS_GROUPS; i++) {
+		page = class->fullness_list[i];
+		if (page)
+			break;
+	}
+
+	return page;
+}
+
+
+/*
+ * If this becomes a separate module, register zs_init() with
+ * module_init(), zs_exit with module_exit(), and remove zs_initialized
+*/
+static int zs_initialized;
+
+static int zs_cpu_notifier(struct notifier_block *nb, unsigned long action,
+				void *pcpu)
+{
+	int cpu = (long)pcpu;
+	struct mapping_area *area;
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+		area = &per_cpu(zs_map_area, cpu);
+		if (area->vm)
+			break;
+		area->vm = alloc_vm_area(2 * PAGE_SIZE, area->vm_ptes);
+		if (!area->vm)
+			return notifier_from_errno(-ENOMEM);
+		break;
+	case CPU_DEAD:
+	case CPU_UP_CANCELED:
+		area = &per_cpu(zs_map_area, cpu);
+		if (area->vm)
+			free_vm_area(area->vm);
+		area->vm = NULL;
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block zs_cpu_nb = {
+	.notifier_call = zs_cpu_notifier
+};
+
+static void zs_exit(void)
+{
+	int cpu;
+
+	for_each_online_cpu(cpu)
+		zs_cpu_notifier(NULL, CPU_DEAD, (void *)(long)cpu);
+	unregister_cpu_notifier(&zs_cpu_nb);
+}
+
+static int zs_init(void)
+{
+	int cpu, ret;
+
+	register_cpu_notifier(&zs_cpu_nb);
+	for_each_online_cpu(cpu) {
+		ret = zs_cpu_notifier(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
+		if (notifier_to_errno(ret))
+			goto fail;
+	}
+	return 0;
+fail:
+	zs_exit();
+	return notifier_to_errno(ret);
+}
+
+struct zs_pool *zs_create_pool(const char *name, gfp_t flags)
+{
+	int i, error, ovhd_size;
+	struct zs_pool *pool;
+
+	if (!name)
+		return NULL;
+
+	ovhd_size = roundup(sizeof(*pool), PAGE_SIZE);
+	pool = kzalloc(ovhd_size, GFP_KERNEL);
+	if (!pool)
+		return NULL;
+
+	for (i = 0; i < ZS_SIZE_CLASSES; i++) {
+		int size;
+		struct size_class *class;
+
+		size = ZS_MIN_ALLOC_SIZE + i * ZS_SIZE_CLASS_DELTA;
+		if (size > ZS_MAX_ALLOC_SIZE)
+			size = ZS_MAX_ALLOC_SIZE;
+
+		class = &pool->size_class[i];
+		class->size = size;
+		class->index = i;
+		spin_lock_init(&class->lock);
+		class->zspage_order = get_zspage_order(size);
+
+	}
+
+	/*
+	 * If this becomes a separate module, register zs_init with
+	 * module_init, and remove this block
+	*/
+	if (!zs_initialized) {
+		error = zs_init();
+		if (error)
+			goto cleanup;
+		zs_initialized = 1;
+	}
+
+	pool->flags = flags;
+	pool->name = name;
+
+	error = 0; /* Success */
+
+cleanup:
+	if (error) {
+		zs_destroy_pool(pool);
+		pool = NULL;
+	}
+
+	return pool;
+}
+EXPORT_SYMBOL_GPL(zs_create_pool);
+
+void zs_destroy_pool(struct zs_pool *pool)
+{
+	int i;
+
+	for (i = 0; i < ZS_SIZE_CLASSES; i++) {
+		int fg;
+		struct size_class *class = &pool->size_class[i];
+
+		for (fg = 0; fg < _ZS_NR_FULLNESS_GROUPS; fg++) {
+			if (class->fullness_list[fg]) {
+				pr_info("Freeing non-empty class with size "
+					"%db, fullness group %d\n",
+					class->size, fg);
+			}
+		}
+	}
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(zs_destroy_pool);
+
+/**
+ * zs_malloc - Allocate block of given size from pool.
+ * @pool: pool to allocate from
+ * @size: size of block to allocate
+ * @page: page no. that holds the object
+ * @offset: location of object within page
+ *
+ * On success, <page, offset> identifies block allocated
+ * and 0 is returned. On failure, <page, offset> is set to
+ * 0 and -ENOMEM is returned.
+ *
+ * Allocation requests with size > ZS_MAX_ALLOC_SIZE will fail.
+ */
+void *zs_malloc(struct zs_pool *pool, size_t size)
+{
+	void *obj;
+	struct link_free *link;
+	int class_idx;
+	struct size_class *class;
+
+	struct page *first_page, *m_page;
+	unsigned long m_objidx, m_offset;
+
+	if (unlikely(!size || size > ZS_MAX_ALLOC_SIZE))
+		return NULL;
+
+	class_idx = get_size_class_index(size);
+	class = &pool->size_class[class_idx];
+	BUG_ON(class_idx != class->index);
+
+	spin_lock(&class->lock);
+	first_page = find_get_zspage(class);
+
+	if (!first_page) {
+		spin_unlock(&class->lock);
+		first_page = alloc_zspage(class, pool->flags);
+		if (unlikely(!first_page))
+			return NULL;
+
+		set_zspage_mapping(first_page, class->index, ZS_EMPTY);
+		spin_lock(&class->lock);
+		class->pages_allocated += class->zspage_order;
+	}
+
+	obj = first_page->freelist;
+	obj_handle_to_location(obj, &m_page, &m_objidx);
+	m_offset = obj_idx_to_offset(m_page, m_objidx, class->size);
+
+	link = (struct link_free *)kmap_atomic(m_page) +
+					m_offset / sizeof(*link);
+	first_page->freelist = link->next;
+	memset(link, POISON_INUSE, sizeof(*link));
+	kunmap_atomic(link);
+
+	first_page->inuse++;
+	/* Now move the zspage to another fullness group, if required */
+	fix_fullness_group(pool, first_page);
+	spin_unlock(&class->lock);
+
+	return obj;
+}
+EXPORT_SYMBOL_GPL(zs_malloc);
+
+void zs_free(struct zs_pool *pool, void *obj)
+{
+	struct link_free *link;
+	struct page *first_page, *f_page;
+	unsigned long f_objidx, f_offset;
+
+	int class_idx;
+	struct size_class *class;
+	enum fullness_group fullness;
+
+	if (unlikely(!obj))
+		return;
+
+	obj_handle_to_location(obj, &f_page, &f_objidx);
+	first_page = get_first_page(f_page);
+
+	get_zspage_mapping(first_page, &class_idx, &fullness);
+	class = &pool->size_class[class_idx];
+	f_offset = obj_idx_to_offset(f_page, f_objidx, class->size);
+
+	spin_lock(&class->lock);
+
+	/* Insert this object in containing zspage's freelist */
+	link = (struct link_free *)((unsigned char *)kmap_atomic(f_page)
+							+ f_offset);
+	link->next = first_page->freelist;
+	kunmap_atomic(link);
+	first_page->freelist = obj;
+
+	first_page->inuse--;
+	fullness = fix_fullness_group(pool, first_page);
+
+	if (fullness == ZS_EMPTY)
+		class->pages_allocated -= class->zspage_order;
+
+	spin_unlock(&class->lock);
+
+	if (fullness == ZS_EMPTY)
+		free_zspage(first_page);
+}
+EXPORT_SYMBOL_GPL(zs_free);
+
+void *zs_map_object(struct zs_pool *pool, void *handle)
+{
+	struct page *page;
+	unsigned long obj_idx, off;
+
+	unsigned int class_idx;
+	enum fullness_group fg;
+	struct size_class *class;
+	struct mapping_area *area;
+
+	BUG_ON(!handle);
+
+	obj_handle_to_location(handle, &page, &obj_idx);
+	get_zspage_mapping(get_first_page(page), &class_idx, &fg);
+	class = &pool->size_class[class_idx];
+	off = obj_idx_to_offset(page, obj_idx, class->size);
+
+	area = &get_cpu_var(zs_map_area);
+	if (off + class->size <= PAGE_SIZE) {
+		/* this object is contained entirely within a page */
+		area->vm_addr = kmap_atomic(page);
+	} else {
+		/* this object spans two pages */
+		struct page *nextp;
+
+		nextp = get_next_page(page);
+		BUG_ON(!nextp);
+
+
+		set_pte(area->vm_ptes[0], mk_pte(page, PAGE_KERNEL));
+		set_pte(area->vm_ptes[1], mk_pte(nextp, PAGE_KERNEL));
+
+		/* We pre-allocated VM area so mapping can never fail */
+		area->vm_addr = area->vm->addr;
+	}
+
+	return area->vm_addr + off;
+}
+EXPORT_SYMBOL_GPL(zs_map_object);
+
+void zs_unmap_object(struct zs_pool *pool, void *handle)
+{
+	struct page *page;
+	unsigned long obj_idx, off;
+
+	unsigned int class_idx;
+	enum fullness_group fg;
+	struct size_class *class;
+	struct mapping_area *area;
+
+	BUG_ON(!handle);
+
+	obj_handle_to_location(handle, &page, &obj_idx);
+	get_zspage_mapping(get_first_page(page), &class_idx, &fg);
+	class = &pool->size_class[class_idx];
+	off = obj_idx_to_offset(page, obj_idx, class->size);
+
+	area = &__get_cpu_var(zs_map_area);
+	if (off + class->size <= PAGE_SIZE) {
+		kunmap_atomic(area->vm_addr);
+	} else {
+		set_pte(area->vm_ptes[0], __pte(0));
+		set_pte(area->vm_ptes[1], __pte(0));
+		__flush_tlb_one((unsigned long)area->vm_addr);
+		__flush_tlb_one((unsigned long)area->vm_addr + PAGE_SIZE);
+	}
+	put_cpu_var(zs_map_area);
+}
+EXPORT_SYMBOL_GPL(zs_unmap_object);
+
+u64 zs_get_total_size_bytes(struct zs_pool *pool)
+{
+	int i;
+	u64 npages = 0;
+
+	for (i = 0; i < ZS_SIZE_CLASSES; i++)
+		npages += pool->size_class[i].pages_allocated;
+
+	return npages << PAGE_SHIFT;
+}
+EXPORT_SYMBOL_GPL(zs_get_total_size_bytes);
diff --git a/drivers/staging/zsmalloc/zsmalloc.h b/drivers/staging/zsmalloc/zsmalloc.h
new file mode 100644
index 0000000..949384e
--- /dev/null
+++ b/drivers/staging/zsmalloc/zsmalloc.h
@@ -0,0 +1,31 @@
+/*
+ * zsmalloc memory allocator
+ *
+ * Copyright (C) 2011  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the license that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifndef _ZS_MALLOC_H_
+#define _ZS_MALLOC_H_
+
+#include <linux/types.h>
+
+struct zs_pool;
+
+struct zs_pool *zs_create_pool(const char *name, gfp_t flags);
+void zs_destroy_pool(struct zs_pool *pool);
+
+void *zs_malloc(struct zs_pool *pool, size_t size);
+void zs_free(struct zs_pool *pool, void *obj);
+
+void *zs_map_object(struct zs_pool *pool, void *handle);
+void zs_unmap_object(struct zs_pool *pool, void *handle);
+
+u64 zs_get_total_size_bytes(struct zs_pool *pool);
+
+#endif
diff --git a/drivers/staging/zsmalloc/zsmalloc_int.h b/drivers/staging/zsmalloc/zsmalloc_int.h
new file mode 100644
index 0000000..354a020
--- /dev/null
+++ b/drivers/staging/zsmalloc/zsmalloc_int.h
@@ -0,0 +1,126 @@
+/*
+ * zsmalloc memory allocator
+ *
+ * Copyright (C) 2011  Nitin Gupta
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the license that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ */
+
+#ifndef _ZS_MALLOC_INT_H_
+#define _ZS_MALLOC_INT_H_
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+/*
+ * This must be power of 2 and greater than of equal to sizeof(link_free).
+ * These two conditions ensure that any 'struct link_free' itself doesn't
+ * span more than 1 page which avoids complex case of mapping 2 pages simply
+ * to restore link_free pointer values.
+ */
+#define ZS_ALIGN		8
+
+/* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */
+#define ZS_MIN_ALLOC_SIZE	32
+#define ZS_MAX_ALLOC_SIZE	PAGE_SIZE
+
+/*
+ * On systems with 4K page size, this gives 254 size classes! There is a
+ * trader-off here:
+ *  - Large number of size classes is potentially wasteful as free page are
+ *    spread across these classes
+ *  - Small number of size classes causes large internal fragmentation
+ *  - Probably its better to use specific size classes (empirically
+ *    determined). NOTE: all those class sizes must be set as multiple of
+ *    ZS_ALIGN to make sure link_free itself never has to span 2 pages.
+ *
+ *  ZS_MIN_ALLOC_SIZE and ZS_SIZE_CLASS_DELTA must be multiple of ZS_ALIGN
+ *  (reason above)
+ */
+#define ZS_SIZE_CLASS_DELTA	16
+#define ZS_SIZE_CLASSES		((ZS_MAX_ALLOC_SIZE - ZS_MIN_ALLOC_SIZE) / \
+					ZS_SIZE_CLASS_DELTA + 1)
+
+/*
+ * A single 'zspage' is composed of N discontiguous 0-order (single) pages.
+ * This defines upper limit on N.
+ */
+static const int max_zspage_order = 4;
+
+/*
+ * We do not maintain any list for completely empty or full pages
+ */
+enum fullness_group {
+	ZS_ALMOST_FULL,
+	ZS_ALMOST_EMPTY,
+	_ZS_NR_FULLNESS_GROUPS,
+
+	ZS_EMPTY,
+	ZS_FULL
+};
+
+/*
+ * We assign a page to ZS_ALMOST_EMPTY fullness group when:
+ *	n <= N / f, where
+ * n = number of allocated objects
+ * N = total number of objects zspage can store
+ * f = 1/fullness_threshold_frac
+ *
+ * Similarly, we assign zspage to:
+ *	ZS_ALMOST_FULL	when n > N / f
+ *	ZS_EMPTY	when n == 0
+ *	ZS_FULL		when n == N
+ *
+ * (see: fix_fullness_group())
+ */
+static const int fullness_threshold_frac = 4;
+
+struct mapping_area {
+	struct vm_struct *vm;
+	pte_t *vm_ptes[2];
+	char *vm_addr;
+};
+
+struct size_class {
+	/*
+	 * Size of objects stored in this class. Must be multiple
+	 * of ZS_ALIGN.
+	 */
+	int size;
+	unsigned int index;
+
+	/* Number of PAGE_SIZE sized pages to combine to form a 'zspage' */
+	int zspage_order;
+
+	spinlock_t lock;
+
+	/* stats */
+	u64 pages_allocated;
+
+	struct page *fullness_list[_ZS_NR_FULLNESS_GROUPS];
+};
+
+/*
+ * Placed within free objects to form a singly linked list.
+ * For every zspage, first_page->freelist gives head of this list.
+ *
+ * This must be power of 2 and less than or equal to ZS_ALIGN
+ */
+struct link_free {
+	/* Handle of next free chunk (encodes <PFN, obj_idx>) */
+	void *next;
+};
+
+struct zs_pool {
+	struct size_class size_class[ZS_SIZE_CLASSES];
+
+	gfp_t flags;	/* allocation flags used when growing pool */
+	const char *name;
+};
+
+#endif
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 4426290..bd5f372 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -23,6 +23,7 @@
 #include <linux/crypto.h>
 #include <linux/completion.h>
 #include <linux/module.h>
+#include <linux/idr.h>
 #include <asm/unaligned.h>
 #include <scsi/scsi_device.h>
 #include <scsi/iscsi_proto.h>
@@ -1006,8 +1007,8 @@ done:
 	/*
 	 * The CDB is going to an se_device_t.
 	 */
-	ret = iscsit_get_lun_for_cmd(cmd, hdr->cdb,
-				get_unaligned_le64(&hdr->lun));
+	ret = transport_lookup_cmd_lun(&cmd->se_cmd,
+				       scsilun_to_int(&hdr->lun));
 	if (ret < 0) {
 		if (cmd->se_cmd.scsi_sense_reason == TCM_NON_EXISTENT_LUN) {
 			pr_debug("Responding to non-acl'ed,"
@@ -1363,7 +1364,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf)
 		 * outstanding_r2ts reaches zero, go ahead and send the delayed
 		 * TASK_ABORTED status.
 		 */
-		if (atomic_read(&se_cmd->t_transport_aborted) != 0) {
+		if (se_cmd->transport_state & CMD_T_ABORTED) {
 			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
 				if (--cmd->outstanding_r2ts < 1) {
 					iscsit_stop_dataout_timer(cmd);
@@ -1746,8 +1747,8 @@ static int iscsit_handle_task_mgt_cmd(
 	 * Locate the struct se_lun for all TMRs not related to ERL=2 TASK_REASSIGN
 	 */
 	if (function != ISCSI_TM_FUNC_TASK_REASSIGN) {
-		ret = iscsit_get_lun_for_tmr(cmd,
-				get_unaligned_le64(&hdr->lun));
+		ret = transport_lookup_tmr_lun(&cmd->se_cmd,
+					       scsilun_to_int(&hdr->lun));
 		if (ret < 0) {
 			cmd->se_cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
 			se_tmr->response = ISCSI_TMF_RSP_NO_LUN;
diff --git a/drivers/target/iscsi/iscsi_target_device.c b/drivers/target/iscsi/iscsi_target_device.c
index f63ea35..bcc4098 100644
--- a/drivers/target/iscsi/iscsi_target_device.c
+++ b/drivers/target/iscsi/iscsi_target_device.c
@@ -28,25 +28,6 @@
 #include "iscsi_target_tpg.h"
 #include "iscsi_target_util.h"
 
-int iscsit_get_lun_for_tmr(
-	struct iscsi_cmd *cmd,
-	u64 lun)
-{
-	u32 unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
-
-	return transport_lookup_tmr_lun(&cmd->se_cmd, unpacked_lun);
-}
-
-int iscsit_get_lun_for_cmd(
-	struct iscsi_cmd *cmd,
-	unsigned char *cdb,
-	u64 lun)
-{
-	u32 unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun);
-
-	return transport_lookup_cmd_lun(&cmd->se_cmd, unpacked_lun);
-}
-
 void iscsit_determine_maxcmdsn(struct iscsi_session *sess)
 {
 	struct se_node_acl *se_nacl;
diff --git a/drivers/target/iscsi/iscsi_target_device.h b/drivers/target/iscsi/iscsi_target_device.h
index bef1cad..a0e2df9 100644
--- a/drivers/target/iscsi/iscsi_target_device.h
+++ b/drivers/target/iscsi/iscsi_target_device.h
@@ -1,8 +1,6 @@
 #ifndef ISCSI_TARGET_DEVICE_H
 #define ISCSI_TARGET_DEVICE_H
 
-extern int iscsit_get_lun_for_tmr(struct iscsi_cmd *, u64);
-extern int iscsit_get_lun_for_cmd(struct iscsi_cmd *, unsigned char *, u64);
 extern void iscsit_determine_maxcmdsn(struct iscsi_session *);
 extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *);
 
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index 27901e3..006f605 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -416,7 +416,7 @@ static int iscsit_handle_recovery_datain(
 	struct iscsi_datain_req *dr;
 	struct se_cmd *se_cmd = &cmd->se_cmd;
 
-	if (!atomic_read(&se_cmd->t_transport_complete)) {
+	if (!(se_cmd->transport_state & CMD_T_COMPLETE)) {
 		pr_err("Ignoring ITT: 0x%08x Data SNACK\n",
 				cmd->init_task_tag);
 		return 0;
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 38cb7ce..1ee33a8 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/kthread.h>
 #include <linux/crypto.h>
+#include <linux/idr.h>
 #include <scsi/iscsi_proto.h>
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
index 255ed35..e01da9d 100644
--- a/drivers/target/iscsi/iscsi_target_tmr.c
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -250,7 +250,7 @@ static int iscsit_task_reassign_complete_write(
 	 * so if we have received all DataOUT we can safety ignore Initiator.
 	 */
 	if (cmd->cmd_flags & ICF_GOT_LAST_DATAOUT) {
-		if (!atomic_read(&cmd->se_cmd.t_transport_sent)) {
+		if (!(cmd->se_cmd.transport_state & CMD_T_SENT)) {
 			pr_debug("WRITE ITT: 0x%08x: t_state: %d"
 				" never sent to transport\n",
 				cmd->init_task_tag, cmd->se_cmd.t_state);
@@ -314,7 +314,7 @@ static int iscsit_task_reassign_complete_read(
 		cmd->acked_data_sn = (tmr_req->exp_data_sn - 1);
 	}
 
-	if (!atomic_read(&cmd->se_cmd.t_transport_sent)) {
+	if (!(cmd->se_cmd.transport_state & CMD_T_SENT)) {
 		pr_debug("READ ITT: 0x%08x: t_state: %d never sent to"
 			" transport\n", cmd->init_task_tag,
 			cmd->se_cmd.t_state);
@@ -322,7 +322,7 @@ static int iscsit_task_reassign_complete_read(
 		return 0;
 	}
 
-	if (!atomic_read(&se_cmd->t_transport_complete)) {
+	if (!(se_cmd->transport_state & CMD_T_COMPLETE)) {
 		pr_err("READ ITT: 0x%08x: t_state: %d, never returned"
 			" from transport\n", cmd->init_task_tag,
 			cmd->se_cmd.t_state);
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c
index 0baac5b..977e1cf 100644
--- a/drivers/target/iscsi/iscsi_target_tq.c
+++ b/drivers/target/iscsi/iscsi_target_tq.c
@@ -536,12 +536,6 @@ int iscsi_thread_set_init(void)
 		return -ENOMEM;
 	}
 
-	spin_lock_init(&active_ts_lock);
-	spin_lock_init(&inactive_ts_lock);
-	spin_lock_init(&ts_bitmap_lock);
-	INIT_LIST_HEAD(&active_ts_list);
-	INIT_LIST_HEAD(&inactive_ts_list);
-
 	return 0;
 }
 
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 6e043ee..0700d3b 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -52,8 +52,8 @@
 
 extern struct t10_alua_lu_gp *default_lu_gp;
 
-static struct list_head g_tf_list;
-static struct mutex g_tf_lock;
+static LIST_HEAD(g_tf_list);
+static DEFINE_MUTEX(g_tf_lock);
 
 struct target_core_configfs_attribute {
 	struct configfs_attribute attr;
@@ -3117,8 +3117,6 @@ static int __init target_core_init_configfs(void)
 	config_group_init(&subsys->su_group);
 	mutex_init(&subsys->su_mutex);
 
-	INIT_LIST_HEAD(&g_tf_list);
-	mutex_init(&g_tf_lock);
 	ret = init_se_kmem_caches();
 	if (ret < 0)
 		return ret;
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index edbcabb..0b25b50 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -159,13 +159,8 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 		dev->read_bytes += se_cmd->data_length;
 	spin_unlock_irqrestore(&dev->stats_lock, flags);
 
-	/*
-	 * Add the iscsi_cmd_t to the struct se_lun's cmd list.  This list is used
-	 * for tracking state of struct se_cmds during LUN shutdown events.
-	 */
 	spin_lock_irqsave(&se_lun->lun_cmd_lock, flags);
 	list_add_tail(&se_cmd->se_lun_node, &se_lun->lun_cmd_list);
-	atomic_set(&se_cmd->transport_lun_active, 1);
 	spin_unlock_irqrestore(&se_lun->lun_cmd_lock, flags);
 
 	return 0;
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 8572eae..2ec299e 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -46,6 +46,9 @@
 
 #include "target_core_iblock.h"
 
+#define IBLOCK_MAX_BIO_PER_TASK	 32	/* max # of bios to submit at a time */
+#define IBLOCK_BIO_POOL_SIZE	128
+
 static struct se_subsystem_api iblock_template;
 
 static void iblock_bio_done(struct bio *, int);
@@ -56,51 +59,25 @@ static void iblock_bio_done(struct bio *, int);
  */
 static int iblock_attach_hba(struct se_hba *hba, u32 host_id)
 {
-	struct iblock_hba *ib_host;
-
-	ib_host = kzalloc(sizeof(struct iblock_hba), GFP_KERNEL);
-	if (!ib_host) {
-		pr_err("Unable to allocate memory for"
-				" struct iblock_hba\n");
-		return -ENOMEM;
-	}
-
-	ib_host->iblock_host_id = host_id;
-
-	hba->hba_ptr = ib_host;
-
 	pr_debug("CORE_HBA[%d] - TCM iBlock HBA Driver %s on"
 		" Generic Target Core Stack %s\n", hba->hba_id,
 		IBLOCK_VERSION, TARGET_CORE_MOD_VERSION);
-
-	pr_debug("CORE_HBA[%d] - Attached iBlock HBA: %u to Generic\n",
-		hba->hba_id, ib_host->iblock_host_id);
-
 	return 0;
 }
 
 static void iblock_detach_hba(struct se_hba *hba)
 {
-	struct iblock_hba *ib_host = hba->hba_ptr;
-
-	pr_debug("CORE_HBA[%d] - Detached iBlock HBA: %u from Generic"
-		" Target Core\n", hba->hba_id, ib_host->iblock_host_id);
-
-	kfree(ib_host);
-	hba->hba_ptr = NULL;
 }
 
 static void *iblock_allocate_virtdevice(struct se_hba *hba, const char *name)
 {
 	struct iblock_dev *ib_dev = NULL;
-	struct iblock_hba *ib_host = hba->hba_ptr;
 
 	ib_dev = kzalloc(sizeof(struct iblock_dev), GFP_KERNEL);
 	if (!ib_dev) {
 		pr_err("Unable to allocate struct iblock_dev\n");
 		return NULL;
 	}
-	ib_dev->ibd_host = ib_host;
 
 	pr_debug( "IBLOCK: Allocated ib_dev for %s\n", name);
 
@@ -126,10 +103,8 @@ static struct se_device *iblock_create_virtdevice(
 		return ERR_PTR(ret);
 	}
 	memset(&dev_limits, 0, sizeof(struct se_dev_limits));
-	/*
-	 * These settings need to be made tunable..
-	 */
-	ib_dev->ibd_bio_set = bioset_create(32, 0);
+
+	ib_dev->ibd_bio_set = bioset_create(IBLOCK_BIO_POOL_SIZE, 0);
 	if (!ib_dev->ibd_bio_set) {
 		pr_err("IBLOCK: Unable to create bioset()\n");
 		return ERR_PTR(-ENOMEM);
@@ -155,8 +130,8 @@ static struct se_device *iblock_create_virtdevice(
 	q = bdev_get_queue(bd);
 	limits = &dev_limits.limits;
 	limits->logical_block_size = bdev_logical_block_size(bd);
-	limits->max_hw_sectors = queue_max_hw_sectors(q);
-	limits->max_sectors = queue_max_sectors(q);
+	limits->max_hw_sectors = UINT_MAX;
+	limits->max_sectors = UINT_MAX;
 	dev_limits.hw_queue_depth = q->nr_requests;
 	dev_limits.queue_depth = q->nr_requests;
 
@@ -230,7 +205,7 @@ iblock_alloc_task(unsigned char *cdb)
 		return NULL;
 	}
 
-	atomic_set(&ib_req->ib_bio_cnt, 0);
+	atomic_set(&ib_req->pending, 1);
 	return &ib_req->ib_task;
 }
 
@@ -510,24 +485,35 @@ iblock_get_bio(struct se_task *task, sector_t lba, u32 sg_num)
 	bio->bi_destructor = iblock_bio_destructor;
 	bio->bi_end_io = &iblock_bio_done;
 	bio->bi_sector = lba;
-	atomic_inc(&ib_req->ib_bio_cnt);
+	atomic_inc(&ib_req->pending);
 
 	pr_debug("Set bio->bi_sector: %llu\n", (unsigned long long)bio->bi_sector);
-	pr_debug("Set ib_req->ib_bio_cnt: %d\n",
-			atomic_read(&ib_req->ib_bio_cnt));
+	pr_debug("Set ib_req->pending: %d\n", atomic_read(&ib_req->pending));
 	return bio;
 }
 
+static void iblock_submit_bios(struct bio_list *list, int rw)
+{
+	struct blk_plug plug;
+	struct bio *bio;
+
+	blk_start_plug(&plug);
+	while ((bio = bio_list_pop(list)))
+		submit_bio(rw, bio);
+	blk_finish_plug(&plug);
+}
+
 static int iblock_do_task(struct se_task *task)
 {
 	struct se_cmd *cmd = task->task_se_cmd;
 	struct se_device *dev = cmd->se_dev;
+	struct iblock_req *ibr = IBLOCK_REQ(task);
 	struct bio *bio;
 	struct bio_list list;
 	struct scatterlist *sg;
 	u32 i, sg_num = task->task_sg_nents;
 	sector_t block_lba;
-	struct blk_plug plug;
+	unsigned bio_cnt;
 	int rw;
 
 	if (task->task_data_direction == DMA_TO_DEVICE) {
@@ -572,6 +558,7 @@ static int iblock_do_task(struct se_task *task)
 
 	bio_list_init(&list);
 	bio_list_add(&list, bio);
+	bio_cnt = 1;
 
 	for_each_sg(task->task_sg, sg, task->task_sg_nents, i) {
 		/*
@@ -581,10 +568,16 @@ static int iblock_do_task(struct se_task *task)
 		 */
 		while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
 				!= sg->length) {
+			if (bio_cnt >= IBLOCK_MAX_BIO_PER_TASK) {
+				iblock_submit_bios(&list, rw);
+				bio_cnt = 0;
+			}
+
 			bio = iblock_get_bio(task, block_lba, sg_num);
 			if (!bio)
 				goto fail;
 			bio_list_add(&list, bio);
+			bio_cnt++;
 		}
 
 		/* Always in 512 byte units for Linux/Block */
@@ -592,11 +585,12 @@ static int iblock_do_task(struct se_task *task)
 		sg_num--;
 	}
 
-	blk_start_plug(&plug);
-	while ((bio = bio_list_pop(&list)))
-		submit_bio(rw, bio);
-	blk_finish_plug(&plug);
+	iblock_submit_bios(&list, rw);
 
+	if (atomic_dec_and_test(&ibr->pending)) {
+		transport_complete_task(task,
+				!atomic_read(&ibr->ib_bio_err_cnt));
+	}
 	return 0;
 
 fail:
@@ -648,7 +642,7 @@ static void iblock_bio_done(struct bio *bio, int err)
 
 	bio_put(bio);
 
-	if (!atomic_dec_and_test(&ibr->ib_bio_cnt))
+	if (!atomic_dec_and_test(&ibr->pending))
 		return;
 
 	pr_debug("done[%p] bio: %p task_lba: %llu bio_lba: %llu err=%d\n",
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index 5cf1860..e929370 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -8,7 +8,7 @@
 
 struct iblock_req {
 	struct se_task ib_task;
-	atomic_t ib_bio_cnt;
+	atomic_t pending;
 	atomic_t ib_bio_err_cnt;
 } ____cacheline_aligned;
 
@@ -19,11 +19,6 @@ struct iblock_dev {
 	u32	ibd_flags;
 	struct bio_set	*ibd_bio_set;
 	struct block_device *ibd_bd;
-	struct iblock_hba *ibd_host;
-} ____cacheline_aligned;
-
-struct iblock_hba {
-	int		iblock_host_id;
 } ____cacheline_aligned;
 
 #endif /* TARGET_CORE_IBLOCK_H */
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index b7c7793..6beada8 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -1487,7 +1487,7 @@ static int core_scsi3_decode_spec_i_port(
 	struct se_dev_entry *dest_se_deve = NULL, *local_se_deve;
 	struct t10_pr_registration *dest_pr_reg, *local_pr_reg, *pr_reg_e;
 	struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe;
-	struct list_head tid_dest_list;
+	LIST_HEAD(tid_dest_list);
 	struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
 	struct target_core_fabric_ops *tmp_tf_ops;
 	unsigned char *buf;
@@ -1498,7 +1498,6 @@ static int core_scsi3_decode_spec_i_port(
 	u32 dest_rtpi = 0;
 
 	memset(dest_iport, 0, 64);
-	INIT_LIST_HEAD(&tid_dest_list);
 
 	local_se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun];
 	/*
@@ -2994,7 +2993,7 @@ static int core_scsi3_pro_preempt(
 	struct se_dev_entry *se_deve;
 	struct se_node_acl *pr_reg_nacl;
 	struct se_session *se_sess = cmd->se_sess;
-	struct list_head preempt_and_abort_list;
+	LIST_HEAD(preempt_and_abort_list);
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_reg_n, *pr_res_holder;
 	struct t10_reservation *pr_tmpl = &dev->se_sub_dev->t10_pr;
 	u32 pr_res_mapped_lun = 0;
@@ -3027,7 +3026,6 @@ static int core_scsi3_pro_preempt(
 		cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST;
 		return -EINVAL;
 	}
-	INIT_LIST_HEAD(&preempt_and_abort_list);
 
 	spin_lock(&dev->dev_reservation_lock);
 	pr_res_holder = dev->dev_pr_res_holder;
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index dcb0618..a5c2e41 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -150,7 +150,7 @@ static void core_tmr_drain_tmr_list(
 			continue;
 
 		spin_lock(&cmd->t_state_lock);
-		if (!atomic_read(&cmd->t_transport_active)) {
+		if (!(cmd->transport_state & CMD_T_ACTIVE)) {
 			spin_unlock(&cmd->t_state_lock);
 			continue;
 		}
@@ -255,15 +255,15 @@ static void core_tmr_drain_task_list(
 			cmd->t_task_cdb[0]);
 		pr_debug("LUN_RESET: ITT[0x%08x] - pr_res_key: 0x%016Lx"
 			" t_task_cdbs: %d t_task_cdbs_left: %d"
-			" t_task_cdbs_sent: %d -- t_transport_active: %d"
-			" t_transport_stop: %d t_transport_sent: %d\n",
+			" t_task_cdbs_sent: %d -- CMD_T_ACTIVE: %d"
+			" CMD_T_STOP: %d CMD_T_SENT: %d\n",
 			cmd->se_tfo->get_task_tag(cmd), cmd->pr_res_key,
 			cmd->t_task_list_num,
 			atomic_read(&cmd->t_task_cdbs_left),
 			atomic_read(&cmd->t_task_cdbs_sent),
-			atomic_read(&cmd->t_transport_active),
-			atomic_read(&cmd->t_transport_stop),
-			atomic_read(&cmd->t_transport_sent));
+			(cmd->transport_state & CMD_T_ACTIVE) != 0,
+			(cmd->transport_state & CMD_T_STOP) != 0,
+			(cmd->transport_state & CMD_T_SENT) != 0);
 
 		/*
 		 * If the command may be queued onto a workqueue cancel it now.
@@ -287,19 +287,19 @@ static void core_tmr_drain_task_list(
 		}
 		fe_count = atomic_read(&cmd->t_fe_count);
 
-		if (atomic_read(&cmd->t_transport_active)) {
-			pr_debug("LUN_RESET: got t_transport_active = 1 for"
+		if (!(cmd->transport_state & CMD_T_ACTIVE)) {
+			pr_debug("LUN_RESET: got CMD_T_ACTIVE for"
 				" task: %p, t_fe_count: %d dev: %p\n", task,
 				fe_count, dev);
-			atomic_set(&cmd->t_transport_aborted, 1);
+			cmd->transport_state |= CMD_T_ABORTED;
 			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
 			core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count);
 			continue;
 		}
-		pr_debug("LUN_RESET: Got t_transport_active = 0 for task: %p,"
+		pr_debug("LUN_RESET: Got !CMD_T_ACTIVE for task: %p,"
 			" t_fe_count: %d dev: %p\n", task, fe_count, dev);
-		atomic_set(&cmd->t_transport_aborted, 1);
+		cmd->transport_state |= CMD_T_ABORTED;
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
 		core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, fe_count);
@@ -339,7 +339,7 @@ static void core_tmr_drain_cmd_list(
 		if (prout_cmd == cmd)
 			continue;
 
-		atomic_set(&cmd->t_transport_queue_active, 0);
+		cmd->transport_state &= ~CMD_T_QUEUED;
 		atomic_dec(&qobj->queue_cnt);
 		list_move_tail(&cmd->se_queue_node, &drain_cmd_list);
 	}
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 58cea07..5e2d29d 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -437,7 +437,7 @@ static void transport_all_task_dev_remove_state(struct se_cmd *cmd)
 
 /*	transport_cmd_check_stop():
  *
- *	'transport_off = 1' determines if t_transport_active should be cleared.
+ *	'transport_off = 1' determines if CMD_T_ACTIVE should be cleared.
  *	'transport_off = 2' determines if task_dev_state should be removed.
  *
  *	A non-zero u8 t_state sets cmd->t_state.
@@ -455,12 +455,11 @@ static int transport_cmd_check_stop(
 	 * Determine if IOCTL context caller in requesting the stopping of this
 	 * command for LUN shutdown purposes.
 	 */
-	if (atomic_read(&cmd->transport_lun_stop)) {
-		pr_debug("%s:%d atomic_read(&cmd->transport_lun_stop)"
-			" == TRUE for ITT: 0x%08x\n", __func__, __LINE__,
-			cmd->se_tfo->get_task_tag(cmd));
+	if (cmd->transport_state & CMD_T_LUN_STOP) {
+		pr_debug("%s:%d CMD_T_LUN_STOP for ITT: 0x%08x\n",
+			__func__, __LINE__, cmd->se_tfo->get_task_tag(cmd));
 
-		atomic_set(&cmd->t_transport_active, 0);
+		cmd->transport_state &= ~CMD_T_ACTIVE;
 		if (transport_off == 2)
 			transport_all_task_dev_remove_state(cmd);
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
@@ -472,9 +471,9 @@ static int transport_cmd_check_stop(
 	 * Determine if frontend context caller is requesting the stopping of
 	 * this command for frontend exceptions.
 	 */
-	if (atomic_read(&cmd->t_transport_stop)) {
-		pr_debug("%s:%d atomic_read(&cmd->t_transport_stop) =="
-			" TRUE for ITT: 0x%08x\n", __func__, __LINE__,
+	if (cmd->transport_state & CMD_T_STOP) {
+		pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08x\n",
+			__func__, __LINE__,
 			cmd->se_tfo->get_task_tag(cmd));
 
 		if (transport_off == 2)
@@ -492,7 +491,7 @@ static int transport_cmd_check_stop(
 		return 1;
 	}
 	if (transport_off) {
-		atomic_set(&cmd->t_transport_active, 0);
+		cmd->transport_state &= ~CMD_T_ACTIVE;
 		if (transport_off == 2) {
 			transport_all_task_dev_remove_state(cmd);
 			/*
@@ -540,25 +539,15 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd)
 		return;
 
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
-	if (!atomic_read(&cmd->transport_dev_active)) {
-		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-		goto check_lun;
+	if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
+		cmd->transport_state &= ~CMD_T_DEV_ACTIVE;
+		transport_all_task_dev_remove_state(cmd);
 	}
-	atomic_set(&cmd->transport_dev_active, 0);
-	transport_all_task_dev_remove_state(cmd);
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
-
-check_lun:
 	spin_lock_irqsave(&lun->lun_cmd_lock, flags);
-	if (atomic_read(&cmd->transport_lun_active)) {
-		list_del(&cmd->se_lun_node);
-		atomic_set(&cmd->transport_lun_active, 0);
-#if 0
-		pr_debug("Removed ITT: 0x%08x from LUN LIST[%d]\n"
-			cmd->se_tfo->get_task_tag(cmd), lun->unpacked_lun);
-#endif
-	}
+	if (!list_empty(&cmd->se_lun_node))
+		list_del_init(&cmd->se_lun_node);
 	spin_unlock_irqrestore(&lun->lun_cmd_lock, flags);
 }
 
@@ -585,7 +574,7 @@ static void transport_add_cmd_to_queue(struct se_cmd *cmd, int t_state,
 	if (t_state) {
 		spin_lock_irqsave(&cmd->t_state_lock, flags);
 		cmd->t_state = t_state;
-		atomic_set(&cmd->t_transport_active, 1);
+		cmd->transport_state |= CMD_T_ACTIVE;
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 	}
 
@@ -601,7 +590,7 @@ static void transport_add_cmd_to_queue(struct se_cmd *cmd, int t_state,
 		list_add(&cmd->se_queue_node, &qobj->qobj_list);
 	else
 		list_add_tail(&cmd->se_queue_node, &qobj->qobj_list);
-	atomic_set(&cmd->t_transport_queue_active, 1);
+	cmd->transport_state |= CMD_T_QUEUED;
 	spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
 
 	wake_up_interruptible(&qobj->thread_wq);
@@ -620,8 +609,7 @@ transport_get_cmd_from_queue(struct se_queue_obj *qobj)
 	}
 	cmd = list_first_entry(&qobj->qobj_list, struct se_cmd, se_queue_node);
 
-	atomic_set(&cmd->t_transport_queue_active, 0);
-
+	cmd->transport_state &= ~CMD_T_QUEUED;
 	list_del_init(&cmd->se_queue_node);
 	atomic_dec(&qobj->queue_cnt);
 	spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
@@ -635,20 +623,14 @@ static void transport_remove_cmd_from_queue(struct se_cmd *cmd)
 	unsigned long flags;
 
 	spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
-	if (!atomic_read(&cmd->t_transport_queue_active)) {
+	if (!(cmd->transport_state & CMD_T_QUEUED)) {
 		spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
 		return;
 	}
-	atomic_set(&cmd->t_transport_queue_active, 0);
+	cmd->transport_state &= ~CMD_T_QUEUED;
 	atomic_dec(&qobj->queue_cnt);
 	list_del_init(&cmd->se_queue_node);
 	spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
-
-	if (atomic_read(&cmd->t_transport_queue_active)) {
-		pr_err("ITT: 0x%08x t_transport_queue_active: %d\n",
-			cmd->se_tfo->get_task_tag(cmd),
-			atomic_read(&cmd->t_transport_queue_active));
-	}
 }
 
 /*
@@ -719,7 +701,7 @@ void transport_complete_task(struct se_task *task, int success)
 	}
 
 	if (!success)
-		cmd->t_tasks_failed = 1;
+		cmd->transport_state |= CMD_T_FAILED;
 
 	/*
 	 * Decrement the outstanding t_task_cdbs_left count.  The last
@@ -731,16 +713,16 @@ void transport_complete_task(struct se_task *task, int success)
 		return;
 	}
 
-	if (cmd->t_tasks_failed) {
+	if (cmd->transport_state & CMD_T_FAILED) {
 		cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 		INIT_WORK(&cmd->work, target_complete_failure_work);
 	} else {
-		atomic_set(&cmd->t_transport_complete, 1);
+		cmd->transport_state |= CMD_T_COMPLETE;
 		INIT_WORK(&cmd->work, target_complete_ok_work);
 	}
 
 	cmd->t_state = TRANSPORT_COMPLETE;
-	atomic_set(&cmd->t_transport_active, 1);
+	cmd->transport_state |= CMD_T_ACTIVE;
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
 	queue_work(target_completion_wq, &cmd->work);
@@ -1488,7 +1470,7 @@ void transport_init_se_cmd(
 	init_completion(&cmd->t_transport_stop_comp);
 	init_completion(&cmd->cmd_wait_comp);
 	spin_lock_init(&cmd->t_state_lock);
-	atomic_set(&cmd->transport_dev_active, 1);
+	cmd->transport_state = CMD_T_DEV_ACTIVE;
 
 	cmd->se_tfo = tfo;
 	cmd->se_sess = se_sess;
@@ -1618,7 +1600,7 @@ int transport_handle_cdb_direct(
 		return -EINVAL;
 	}
 	/*
-	 * Set TRANSPORT_NEW_CMD state and cmd->t_transport_active=1 following
+	 * Set TRANSPORT_NEW_CMD state and CMD_T_ACTIVE following
 	 * transport_generic_handle_cdb*() -> transport_add_cmd_to_queue()
 	 * in existing usage to ensure that outstanding descriptors are handled
 	 * correctly during shutdown via transport_wait_for_tasks()
@@ -1627,7 +1609,8 @@ int transport_handle_cdb_direct(
 	 * this to be called for initial descriptor submission.
 	 */
 	cmd->t_state = TRANSPORT_NEW_CMD;
-	atomic_set(&cmd->t_transport_active, 1);
+	cmd->transport_state |= CMD_T_ACTIVE;
+
 	/*
 	 * transport_generic_new_cmd() is already handling QUEUE_FULL,
 	 * so follow TRANSPORT_NEW_CMD processing thread context usage
@@ -1675,6 +1658,8 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
 	 */
 	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess,
 				data_length, data_dir, task_attr, sense);
+	if (flags & TARGET_SCF_UNKNOWN_SIZE)
+		se_cmd->unknown_data_length = 1;
 	/*
 	 * Obtain struct se_cmd->cmd_kref reference and add new cmd to
 	 * se_sess->sess_cmd_list.  A second kref_get here is necessary
@@ -1859,14 +1844,14 @@ static void transport_generic_request_failure(struct se_cmd *cmd)
 		cmd->t_state, cmd->scsi_sense_reason);
 	pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d"
 		" t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --"
-		" t_transport_active: %d t_transport_stop: %d"
-		" t_transport_sent: %d\n", cmd->t_task_list_num,
+		" CMD_T_ACTIVE: %d CMD_T_STOP: %d CMD_T_SENT: %d\n",
+		cmd->t_task_list_num,
 		atomic_read(&cmd->t_task_cdbs_left),
 		atomic_read(&cmd->t_task_cdbs_sent),
 		atomic_read(&cmd->t_task_cdbs_ex_left),
-		atomic_read(&cmd->t_transport_active),
-		atomic_read(&cmd->t_transport_stop),
-		atomic_read(&cmd->t_transport_sent));
+		(cmd->transport_state & CMD_T_ACTIVE) != 0,
+		(cmd->transport_state & CMD_T_STOP) != 0,
+		(cmd->transport_state & CMD_T_SENT) != 0);
 
 	/*
 	 * For SAM Task Attribute emulation for failed struct se_cmd
@@ -2125,7 +2110,7 @@ check_depth:
 
 	if (atomic_read(&cmd->t_task_cdbs_sent) ==
 	    cmd->t_task_list_num)
-		atomic_set(&cmd->t_transport_sent, 1);
+		cmd->transport_state |= CMD_T_SENT;
 
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
@@ -2136,8 +2121,9 @@ check_depth:
 	if (error != 0) {
 		spin_lock_irqsave(&cmd->t_state_lock, flags);
 		task->task_flags &= ~TF_ACTIVE;
+		cmd->transport_state &= ~CMD_T_SENT;
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
-		atomic_set(&cmd->t_transport_sent, 0);
+
 		transport_stop_tasks_for_cmd(cmd);
 		transport_generic_request_failure(cmd);
 	}
@@ -2344,7 +2330,7 @@ static void transport_xor_callback(struct se_cmd *cmd)
 
 	offset = 0;
 	for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) {
-		addr = kmap_atomic(sg_page(sg), KM_USER0);
+		addr = kmap_atomic(sg_page(sg));
 		if (!addr)
 			goto out;
 
@@ -2352,7 +2338,7 @@ static void transport_xor_callback(struct se_cmd *cmd)
 			*(addr + sg->offset + i) ^= *(buf + offset + i);
 
 		offset += sg->length;
-		kunmap_atomic(addr, KM_USER0);
+		kunmap_atomic(addr);
 	}
 
 out:
@@ -2928,7 +2914,7 @@ static int transport_generic_cmd_sequencer(
 		cmd->se_cmd_flags |= SCF_SCSI_NON_DATA_CDB;
 		break;
 	case SYNCHRONIZE_CACHE:
-	case 0x91: /* SYNCHRONIZE_CACHE_16: */
+	case SYNCHRONIZE_CACHE_16:
 		/*
 		 * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE
 		 */
@@ -3045,6 +3031,9 @@ static int transport_generic_cmd_sequencer(
 		goto out_unsupported_cdb;
 	}
 
+	if (cmd->unknown_data_length)
+		cmd->data_length = size;
+
 	if (size != cmd->data_length) {
 		pr_warn("TARGET_CORE[%s]: Expected Transfer Length:"
 			" %u does not match SCSI CDB Length: %u for SAM Opcode:"
@@ -3420,8 +3409,8 @@ static void transport_put_cmd(struct se_cmd *cmd)
 			goto out_busy;
 	}
 
-	if (atomic_read(&cmd->transport_dev_active)) {
-		atomic_set(&cmd->transport_dev_active, 0);
+	if (cmd->transport_state & CMD_T_DEV_ACTIVE) {
+		cmd->transport_state &= ~CMD_T_DEV_ACTIVE;
 		transport_all_task_dev_remove_state(cmd);
 		free_tasks = 1;
 	}
@@ -3859,8 +3848,10 @@ int transport_generic_new_cmd(struct se_cmd *cmd)
 	if (task_cdbs < 0)
 		goto out_fail;
 	else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) {
+		spin_lock_irq(&cmd->t_state_lock);
 		cmd->t_state = TRANSPORT_COMPLETE;
-		atomic_set(&cmd->t_transport_active, 1);
+		cmd->transport_state |= CMD_T_ACTIVE;
+		spin_unlock_irq(&cmd->t_state_lock);
 
 		if (cmd->t_task_cdb[0] == REQUEST_SENSE) {
 			u8 ua_asc = 0, ua_ascq = 0;
@@ -3941,9 +3932,9 @@ static int transport_generic_write_pending(struct se_cmd *cmd)
 
 	/*
 	 * Clear the se_cmd for WRITE_PENDING status in order to set
-	 * cmd->t_transport_active=0 so that transport_generic_handle_data
-	 * can be called from HW target mode interrupt code.  This is safe
-	 * to be called with transport_off=1 before the cmd->se_tfo->write_pending
+	 * CMD_T_ACTIVE so that transport_generic_handle_data can be called
+	 * from HW target mode interrupt code.  This is safe to be called
+	 * with transport_off=1 before the cmd->se_tfo->write_pending
 	 * because the se_cmd->se_lun pointer is not being cleared.
 	 */
 	transport_cmd_check_stop(cmd, 1, 0);
@@ -4129,15 +4120,16 @@ static int transport_lun_wait_for_tasks(struct se_cmd *cmd, struct se_lun *lun)
 	 * be stopped, we can safely ignore this struct se_cmd.
 	 */
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
-	if (atomic_read(&cmd->t_transport_stop)) {
-		atomic_set(&cmd->transport_lun_stop, 0);
-		pr_debug("ConfigFS ITT[0x%08x] - t_transport_stop =="
-			" TRUE, skipping\n", cmd->se_tfo->get_task_tag(cmd));
+	if (cmd->transport_state & CMD_T_STOP) {
+		cmd->transport_state &= ~CMD_T_LUN_STOP;
+
+		pr_debug("ConfigFS ITT[0x%08x] - CMD_T_STOP, skipping\n",
+			 cmd->se_tfo->get_task_tag(cmd));
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 		transport_cmd_check_stop(cmd, 1, 0);
 		return -EPERM;
 	}
-	atomic_set(&cmd->transport_lun_fe_stop, 1);
+	cmd->transport_state |= CMD_T_LUN_FE_STOP;
 	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
 	wake_up_interruptible(&cmd->se_dev->dev_queue_obj.thread_wq);
@@ -4170,9 +4162,8 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun)
 	while (!list_empty(&lun->lun_cmd_list)) {
 		cmd = list_first_entry(&lun->lun_cmd_list,
 		       struct se_cmd, se_lun_node);
-		list_del(&cmd->se_lun_node);
+		list_del_init(&cmd->se_lun_node);
 
-		atomic_set(&cmd->transport_lun_active, 0);
 		/*
 		 * This will notify iscsi_target_transport.c:
 		 * transport_cmd_check_stop() that a LUN shutdown is in
@@ -4183,7 +4174,7 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun)
 			"_lun_stop for  ITT: 0x%08x\n",
 			cmd->se_lun->unpacked_lun,
 			cmd->se_tfo->get_task_tag(cmd));
-		atomic_set(&cmd->transport_lun_stop, 1);
+		cmd->transport_state |= CMD_T_LUN_STOP;
 		spin_unlock(&cmd->t_state_lock);
 
 		spin_unlock_irqrestore(&lun->lun_cmd_lock, lun_flags);
@@ -4213,11 +4204,11 @@ static void __transport_clear_lun_from_sessions(struct se_lun *lun)
 			cmd->se_tfo->get_task_tag(cmd));
 
 		spin_lock_irqsave(&cmd->t_state_lock, cmd_flags);
-		if (!atomic_read(&cmd->transport_dev_active)) {
+		if (!(cmd->transport_state & CMD_T_DEV_ACTIVE)) {
 			spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags);
 			goto check_cond;
 		}
-		atomic_set(&cmd->transport_dev_active, 0);
+		cmd->transport_state &= ~CMD_T_DEV_ACTIVE;
 		transport_all_task_dev_remove_state(cmd);
 		spin_unlock_irqrestore(&cmd->t_state_lock, cmd_flags);
 
@@ -4237,7 +4228,7 @@ check_cond:
 		 * finished accessing it.
 		 */
 		spin_lock_irqsave(&cmd->t_state_lock, cmd_flags);
-		if (atomic_read(&cmd->transport_lun_fe_stop)) {
+		if (cmd->transport_state & CMD_T_LUN_FE_STOP) {
 			pr_debug("SE_LUN[%d] - Detected FE stop for"
 				" struct se_cmd: %p ITT: 0x%08x\n",
 				lun->unpacked_lun,
@@ -4315,8 +4306,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
 	 * transport_clear_lun_from_sessions() once the ConfigFS context caller
 	 * has completed its operation on the struct se_cmd.
 	 */
-	if (atomic_read(&cmd->transport_lun_stop)) {
-
+	if (cmd->transport_state & CMD_T_LUN_STOP) {
 		pr_debug("wait_for_tasks: Stopping"
 			" wait_for_completion(&cmd->t_tasktransport_lun_fe"
 			"_stop_comp); for ITT: 0x%08x\n",
@@ -4344,18 +4334,19 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
 			"stop_comp); for ITT: 0x%08x\n",
 			cmd->se_tfo->get_task_tag(cmd));
 
-		atomic_set(&cmd->transport_lun_stop, 0);
+		cmd->transport_state &= ~CMD_T_LUN_STOP;
 	}
-	if (!atomic_read(&cmd->t_transport_active) ||
-	     atomic_read(&cmd->t_transport_aborted)) {
+
+	if (!(cmd->transport_state & CMD_T_ACTIVE) ||
+	     (cmd->transport_state & CMD_T_ABORTED)) {
 		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 		return false;
 	}
 
-	atomic_set(&cmd->t_transport_stop, 1);
+	cmd->transport_state |= CMD_T_STOP;
 
 	pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08x"
-		" i_state: %d, t_state: %d, t_transport_stop = TRUE\n",
+		" i_state: %d, t_state: %d, CMD_T_STOP\n",
 		cmd, cmd->se_tfo->get_task_tag(cmd),
 		cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
 
@@ -4366,8 +4357,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
 	wait_for_completion(&cmd->t_transport_stop_comp);
 
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
-	atomic_set(&cmd->t_transport_active, 0);
-	atomic_set(&cmd->t_transport_stop, 0);
+	cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
 
 	pr_debug("wait_for_tasks: Stopped wait_for_compltion("
 		"&cmd->t_transport_stop_comp) for ITT: 0x%08x\n",
@@ -4596,7 +4586,7 @@ int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
 {
 	int ret = 0;
 
-	if (atomic_read(&cmd->t_transport_aborted) != 0) {
+	if (cmd->transport_state & CMD_T_ABORTED) {
 		if (!send_status ||
 		     (cmd->se_cmd_flags & SCF_SENT_DELAYED_TAS))
 			return 1;
@@ -4633,7 +4623,7 @@ void transport_send_task_abort(struct se_cmd *cmd)
 	 */
 	if (cmd->data_direction == DMA_TO_DEVICE) {
 		if (cmd->se_tfo->write_pending_status(cmd) != 0) {
-			atomic_inc(&cmd->t_transport_aborted);
+			cmd->transport_state |= CMD_T_ABORTED;
 			smp_mb__after_atomic_inc();
 		}
 	}
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index e05c551..7906b9f 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -113,12 +113,10 @@ struct ft_lport_acl {
  * Commands
  */
 struct ft_cmd {
-	u32 lun;                        /* LUN from request */
 	struct ft_sess *sess;		/* session held for cmd */
 	struct fc_seq *seq;		/* sequence in exchange mgr */
 	struct se_cmd se_cmd;		/* Local TCM I/O descriptor */
 	struct fc_frame *req_frame;
-	unsigned char *cdb;		/* pointer to CDB inside frame */
 	u32 write_data_len;		/* data received on writes */
 	struct work_struct work;
 	/* Local sense buffer */
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 9e7e26c..a766611 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -59,9 +59,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
 	se_cmd = &cmd->se_cmd;
 	pr_debug("%s: cmd %p sess %p seq %p se_cmd %p\n",
 		caller, cmd, cmd->sess, cmd->seq, se_cmd);
-	pr_debug("%s: cmd %p cdb %p\n",
-		caller, cmd, cmd->cdb);
-	pr_debug("%s: cmd %p lun %d\n", caller, cmd, cmd->lun);
 
 	pr_debug("%s: cmd %p data_nents %u len %u se_cmd_flags <0x%x>\n",
 		caller, cmd, se_cmd->t_data_nents,
@@ -81,8 +78,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
 			caller, cmd, ep->sid, ep->did, ep->oxid, ep->rxid,
 			sp->id, ep->esb_stat);
 	}
-	print_hex_dump(KERN_INFO, "ft_dump_cmd ", DUMP_PREFIX_NONE,
-		16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0);
 }
 
 static void ft_free_cmd(struct ft_cmd *cmd)
@@ -407,8 +402,7 @@ static void ft_send_tm(struct ft_cmd *cmd)
 
 	switch (fcp->fc_tm_flags) {
 	case FCP_TMF_LUN_RESET:
-		cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
-		if (transport_lookup_tmr_lun(&cmd->se_cmd, cmd->lun) < 0) {
+		if (transport_lookup_tmr_lun(&cmd->se_cmd, scsilun_to_int(&fcp->fc_lun)) < 0) {
 			/*
 			 * Make sure to clean up newly allocated TMR request
 			 * since "unable to  handle TMR request because failed
@@ -416,7 +410,7 @@ static void ft_send_tm(struct ft_cmd *cmd)
 			 */
 			pr_debug("Failed to get LUN for TMR func %d, "
 				  "se_cmd %p, unpacked_lun %d\n",
-				  tm_func, &cmd->se_cmd, cmd->lun);
+				  tm_func, &cmd->se_cmd, scsilun_to_int(&fcp->fc_lun));
 			ft_dump_cmd(cmd, __func__);
 			sess = cmd->sess;
 			transport_send_check_condition_and_sense(&cmd->se_cmd,
@@ -538,7 +532,6 @@ static void ft_send_work(struct work_struct *work)
 	struct fc_frame_header *fh = fc_frame_header_get(cmd->req_frame);
 	struct fcp_cmnd *fcp;
 	int data_dir = 0;
-	u32 data_len;
 	int task_attr;
 
 	fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
@@ -548,47 +541,6 @@ static void ft_send_work(struct work_struct *work)
 	if (fcp->fc_flags & FCP_CFL_LEN_MASK)
 		goto err;		/* not handling longer CDBs yet */
 
-	if (fcp->fc_tm_flags) {
-		task_attr = FCP_PTA_SIMPLE;
-		data_dir = DMA_NONE;
-		data_len = 0;
-	} else {
-		switch (fcp->fc_flags & (FCP_CFL_RDDATA | FCP_CFL_WRDATA)) {
-		case 0:
-			data_dir = DMA_NONE;
-			break;
-		case FCP_CFL_RDDATA:
-			data_dir = DMA_FROM_DEVICE;
-			break;
-		case FCP_CFL_WRDATA:
-			data_dir = DMA_TO_DEVICE;
-			break;
-		case FCP_CFL_WRDATA | FCP_CFL_RDDATA:
-			goto err;	/* TBD not supported by tcm_fc yet */
-		}
-		/*
-		 * Locate the SAM Task Attr from fc_pri_ta
-		 */
-		switch (fcp->fc_pri_ta & FCP_PTA_MASK) {
-		case FCP_PTA_HEADQ:
-			task_attr = MSG_HEAD_TAG;
-			break;
-		case FCP_PTA_ORDERED:
-			task_attr = MSG_ORDERED_TAG;
-			break;
-		case FCP_PTA_ACA:
-			task_attr = MSG_ACA_TAG;
-			break;
-		case FCP_PTA_SIMPLE: /* Fallthrough */
-		default:
-			task_attr = MSG_SIMPLE_TAG;
-		}
-
-
-		task_attr = fcp->fc_pri_ta & FCP_PTA_MASK;
-		data_len = ntohl(fcp->fc_dl);
-		cmd->cdb = fcp->fc_cdb;
-	}
 	/*
 	 * Check for FCP task management flags
 	 */
@@ -596,15 +548,46 @@ static void ft_send_work(struct work_struct *work)
 		ft_send_tm(cmd);
 		return;
 	}
+
+	switch (fcp->fc_flags & (FCP_CFL_RDDATA | FCP_CFL_WRDATA)) {
+	case 0:
+		data_dir = DMA_NONE;
+		break;
+	case FCP_CFL_RDDATA:
+		data_dir = DMA_FROM_DEVICE;
+		break;
+	case FCP_CFL_WRDATA:
+		data_dir = DMA_TO_DEVICE;
+		break;
+	case FCP_CFL_WRDATA | FCP_CFL_RDDATA:
+		goto err;	/* TBD not supported by tcm_fc yet */
+	}
+	/*
+	 * Locate the SAM Task Attr from fc_pri_ta
+	 */
+	switch (fcp->fc_pri_ta & FCP_PTA_MASK) {
+	case FCP_PTA_HEADQ:
+		task_attr = MSG_HEAD_TAG;
+		break;
+	case FCP_PTA_ORDERED:
+		task_attr = MSG_ORDERED_TAG;
+		break;
+	case FCP_PTA_ACA:
+		task_attr = MSG_ACA_TAG;
+		break;
+	case FCP_PTA_SIMPLE: /* Fallthrough */
+	default:
+		task_attr = MSG_SIMPLE_TAG;
+	}
+
 	fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
-	cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
 	/*
 	 * Use a single se_cmd->cmd_kref as we expect to release se_cmd
 	 * directly from ft_check_stop_free callback in response path.
 	 */
-	target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, cmd->cdb,
-				&cmd->ft_sense_buffer[0], cmd->lun, data_len,
-				task_attr, data_dir, 0);
+	target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb,
+			&cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
+			ntohl(fcp->fc_dl), task_attr, data_dir, 0);
 	pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl);
 	return;
 
diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index d8cabc2..2b693ee 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -146,14 +146,13 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
 					PAGE_SIZE << compound_order(page);
 		} else {
 			BUG_ON(!page);
-			from = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
-					   KM_SOFTIRQ0);
+			from = kmap_atomic(page + (mem_off >> PAGE_SHIFT));
 			page_addr = from;
 			from += mem_off & ~PAGE_MASK;
 			tlen = min(tlen, (size_t)(PAGE_SIZE -
 						(mem_off & ~PAGE_MASK)));
 			memcpy(to, from, tlen);
-			kunmap_atomic(page_addr, KM_SOFTIRQ0);
+			kunmap_atomic(page_addr);
 			to += tlen;
 		}
 
@@ -291,14 +290,13 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
 
 		tlen = min(mem_len, frame_len);
 
-		to = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
-				 KM_SOFTIRQ0);
+		to = kmap_atomic(page + (mem_off >> PAGE_SHIFT));
 		page_addr = to;
 		to += mem_off & ~PAGE_MASK;
 		tlen = min(tlen, (size_t)(PAGE_SIZE -
 					  (mem_off & ~PAGE_MASK)));
 		memcpy(to, from, tlen);
-		kunmap_atomic(page_addr, KM_SOFTIRQ0);
+		kunmap_atomic(page_addr);
 
 		from += tlen;
 		frame_len -= tlen;
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 4c0507c..eff512b 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -86,16 +86,6 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport)
 }
 
 /*
- * Free tport via RCU.
- */
-static void ft_tport_rcu_free(struct rcu_head *rcu)
-{
-	struct ft_tport *tport = container_of(rcu, struct ft_tport, rcu);
-
-	kfree(tport);
-}
-
-/*
  * Delete a target local port.
  * Caller holds ft_lport_lock.
  */
@@ -114,7 +104,7 @@ static void ft_tport_delete(struct ft_tport *tport)
 		tpg->tport = NULL;
 		tport->tpg = NULL;
 	}
-	call_rcu(&tport->rcu, ft_tport_rcu_free);
+	kfree_rcu(tport, rcu);
 }
 
 /*
diff --git a/drivers/telephony/Kconfig b/drivers/telephony/Kconfig
deleted file mode 100644
index b5f78b6..0000000
--- a/drivers/telephony/Kconfig
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Telephony device configuration
-#
-
-menuconfig PHONE
-	tristate "Telephony support"
-	depends on HAS_IOMEM
-	---help---
-	  Say Y here if you have a telephony card, which for example allows
-	  you to use a regular phone for voice-over-IP applications.
-
-	  Note: this has nothing to do with modems.  You do not need to say Y
-	  here in order to be able to use a modem under Linux.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called phonedev.
-
-if PHONE
-
-config PHONE_IXJ
-	tristate "QuickNet Internet LineJack/PhoneJack support"
-	depends on ISA || PCI
-	---help---
-	  Say M if you have a telephony card manufactured by Quicknet
-	  Technologies, Inc.  These include the Internet PhoneJACK and
-	  Internet LineJACK Telephony Cards. You will get a module called
-	  ixj.
-
-	  For the ISA versions of these products, you can configure the
-	  cards using the isapnp tools (pnpdump/isapnp) or you can use the
-	  isapnp support.  Please read <file:Documentation/telephony/ixj.txt>.
-
-	  For more information on these cards, see Quicknet's web site at:
-	  <http://www.quicknet.net/>.
-
-	  If you do not have any Quicknet telephony cards, you can safely
-	  say N here.
-
-config PHONE_IXJ_PCMCIA
-	tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support"
-	depends on PHONE_IXJ && PCMCIA
-	help
-	  Say Y here to configure in PCMCIA service support for the Quicknet
-	  cards manufactured by Quicknet Technologies, Inc.  This changes the
-	  card initialization code to work with the card manager daemon.
-
-endif # PHONE
diff --git a/drivers/telephony/Makefile b/drivers/telephony/Makefile
deleted file mode 100644
index 1206615..0000000
--- a/drivers/telephony/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for drivers/telephony
-#
-
-obj-$(CONFIG_PHONE) += phonedev.o
-obj-$(CONFIG_PHONE_IXJ) += ixj.o
-obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
diff --git a/drivers/telephony/ixj-ver.h b/drivers/telephony/ixj-ver.h
deleted file mode 100644
index 2031ac6..0000000
--- a/drivers/telephony/ixj-ver.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/* configuration management identifiers */
-#define IXJ_VER_MAJOR 1
-#define IXJ_VER_MINOR 0
-#define IXJ_BLD_VER   1
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
deleted file mode 100644
index d5f923b..0000000
--- a/drivers/telephony/ixj.c
+++ /dev/null
@@ -1,10552 +0,0 @@
-/****************************************************************************
- *    ixj.c
- *
- * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
- * including the Internet PhoneJACK, Internet PhoneJACK Lite,
- * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
- * SmartCABLE
- *
- *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
- *
- *    This program is free software; you can redistribute it and/or
- *    modify it under the terms of the GNU General Public License
- *    as published by the Free Software Foundation; either version
- *    2 of the License, or (at your option) any later version.
- *
- * Author:          Ed Okerson, <eokerson@quicknet.net>
- *
- * Contributors:    Greg Herlein, <gherlein@quicknet.net>
- *                  David W. Erhart, <derhart@quicknet.net>
- *                  John Sellers, <jsellers@quicknet.net>
- *                  Mike Preston, <mpreston@quicknet.net>
- *    
- * Fixes:           David Huggins-Daines, <dhd@cepstral.com>
- *                  Fabio Ferrari, <fabio.ferrari@digitro.com.br>
- *                  Artis Kugevics, <artis@mt.lv>
- *                  Daniele Bellucci, <bellucda@tiscali.it>
- *
- * More information about the hardware related to this driver can be found  
- * at our website:    http://www.quicknet.net
- *
- * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *    
- * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
- * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- ***************************************************************************/
-
-/*
- * Revision 4.8  2003/07/09 19:39:00  Daniele Bellucci
- * Audit some copy_*_user and minor cleanup.
- *
- * Revision 4.7  2001/08/13 06:19:33  craigs
- * Added additional changes from Alan Cox and John Anderson for
- * 2.2 to 2.4 cleanup and bounds checking
- *
- * Revision 4.6  2001/08/13 01:05:05  craigs
- * Really fixed PHONE_QUERY_CODEC problem this time
- *
- * Revision 4.5  2001/08/13 00:11:03  craigs
- * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson
- *
- * Revision 4.4  2001/08/07 07:58:12  craigs
- * Changed back to three digit version numbers
- * Added tagbuild target to allow automatic and easy tagging of versions
- *
- * Revision 4.3  2001/08/07 07:24:47  craigs
- * Added ixj-ver.h to allow easy configuration management of driver
- * Added display of version number in /prox/ixj
- *
- * Revision 4.2  2001/08/06 07:07:19  craigs
- * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original
- * behaviour of returning int rather than short *
- *
- * Revision 4.1  2001/08/05 00:17:37  craigs
- * More changes for correct PCMCIA installation
- * Start of changes for backward Linux compatibility
- *
- * Revision 4.0  2001/08/04 12:33:12  craigs
- * New version using GNU autoconf
- *
- * Revision 3.105  2001/07/20 23:14:32  eokerson
- * More work on CallerID generation when using ring cadences.
- *
- * Revision 3.104  2001/07/06 01:33:55  eokerson
- * Some bugfixes from Robert Vojta <vojta@ipex.cz> and a few mods to the Makefile.
- *
- * Revision 3.103  2001/07/05 19:20:16  eokerson
- * Updated HOWTO
- * Changed mic gain to 30dB on Internet LineJACK mic/speaker port.
- *
- * Revision 3.102  2001/07/03 23:51:21  eokerson
- * Un-mute mic on Internet LineJACK when in speakerphone mode.
- *
- * Revision 3.101  2001/07/02 19:26:56  eokerson
- * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data
- *
- * Revision 3.100  2001/07/02 19:18:27  eokerson
- * Changed driver to make dynamic allocation possible.  We now pass IXJ * between functions instead of array indexes.
- * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering.
- * Fixed speaker mode on Internet LineJACK.
- *
- * Revision 3.99  2001/05/09 14:11:16  eokerson
- * Fixed kmalloc error in ixj_build_filter_cadence.  Thanks David Chan <cat@waulogy.stanford.edu>.
- *
- * Revision 3.98  2001/05/08 19:55:33  eokerson
- * Fixed POTS hookstate detection while it is connected to PSTN port.
- *
- * Revision 3.97  2001/05/08 00:01:04  eokerson
- * Fixed kernel oops when sending caller ID data.
- *
- * Revision 3.96  2001/05/04 23:09:30  eokerson
- * Now uses one kernel timer for each card, instead of one for the entire driver.
- *
- * Revision 3.95  2001/04/25 22:06:47  eokerson
- * Fixed squawking at beginning of some G.723.1 calls.
- *
- * Revision 3.94  2001/04/03 23:42:00  eokerson
- * Added linear volume ioctls
- * Added raw filter load ioctl
- *
- * Revision 3.93  2001/02/27 01:00:06  eokerson
- * Fixed blocking in CallerID.
- * Reduced size of ixj structure for smaller driver footprint.
- *
- * Revision 3.92  2001/02/20 22:02:59  eokerson
- * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels.
- * Improved PSTN ring detection.
- * Fixed wink generation on POTS ports.
- *
- * Revision 3.91  2001/02/13 00:55:44  eokerson
- * Turn AEC back on after changing frame sizes.
- *
- * Revision 3.90  2001/02/12 16:42:00  eokerson
- * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW.
- *
- * Revision 3.89  2001/02/12 15:41:16  eokerson
- * Fix from Artis Kugevics - Tone gains were not being set correctly.
- *
- * Revision 3.88  2001/02/05 23:25:42  eokerson
- * Fixed lockup bugs with deregister.
- *
- * Revision 3.87  2001/01/29 21:00:39  eokerson
- * Fix from Fabio Ferrari <fabio.ferrari@digitro.com.br> to properly handle EAGAIN and EINTR during non-blocking write.
- * Updated copyright date.
- *
- * Revision 3.86  2001/01/23 23:53:46  eokerson
- * Fixes to G.729 compatibility.
- *
- * Revision 3.85  2001/01/23 21:30:36  eokerson
- * Added verbage about cards supported.
- * Removed commands that put the card in low power mode at some times that it should not be in low power mode.
- *
- * Revision 3.84  2001/01/22 23:32:10  eokerson
- * Some bugfixes from David Huggins-Daines, <dhd@cepstral.com> and other cleanups.
- *
- * Revision 3.83  2001/01/19 14:51:41  eokerson
- * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails.
- *
- * Revision 3.82  2001/01/19 00:34:49  eokerson
- * Added verbosity to write overlap errors.
- *
- * Revision 3.81  2001/01/18 23:56:54  eokerson
- * Fixed PSTN line test functions.
- *
- * Revision 3.80  2001/01/18 22:29:27  eokerson
- * Updated AEC/AGC values for different cards.
- *
- * Revision 3.79  2001/01/17 02:58:54  eokerson
- * Fixed AEC reset after Caller ID.
- * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames.
- *
- * Revision 3.78  2001/01/16 19:43:09  eokerson
- * Added support for Linux 2.4.x kernels.
- *
- * Revision 3.77  2001/01/09 04:00:52  eokerson
- * Linetest will now test the line, even if it has previously succeeded.
- *
- * Revision 3.76  2001/01/08 19:27:00  eokerson
- * Fixed problem with standard cable on Internet PhoneCARD.
- *
- * Revision 3.75  2000/12/22 16:52:14  eokerson
- * Modified to allow hookstate detection on the POTS port when the PSTN port is selected.
- *
- * Revision 3.74  2000/12/08 22:41:50  eokerson
- * Added capability for G729B.
- *
- * Revision 3.73  2000/12/07 23:35:16  eokerson
- * Added capability to have different ring pattern before CallerID data.
- * Added hookstate checks in CallerID routines to stop FSK.
- *
- * Revision 3.72  2000/12/06 19:31:31  eokerson
- * Modified signal behavior to only send one signal per event.
- *
- * Revision 3.71  2000/12/06 03:23:08  eokerson
- * Fixed CallerID on Call Waiting.
- *
- * Revision 3.70  2000/12/04 21:29:37  eokerson
- * Added checking to Smart Cable gain functions.
- *
- * Revision 3.69  2000/12/04 21:05:20  eokerson
- * Changed ixjdebug levels.
- * Added ioctls to change gains in Internet Phone CARD Smart Cable.
- *
- * Revision 3.68  2000/12/04 00:17:21  craigs
- * Changed mixer voice gain to +6dB rather than 0dB
- *
- * Revision 3.67  2000/11/30 21:25:51  eokerson
- * Fixed write signal errors.
- *
- * Revision 3.66  2000/11/29 22:42:44  eokerson
- * Fixed PSTN ring detect problems.
- *
- * Revision 3.65  2000/11/29 07:31:55  craigs
- * Added new 425Hz filter co-efficients
- * Added card-specific DTMF prescaler initialisation
- *
- * Revision 3.64  2000/11/28 14:03:32  craigs
- * Changed certain mixer initialisations to be 0dB rather than 12dB
- * Added additional information to /proc/ixj
- *
- * Revision 3.63  2000/11/28 11:38:41  craigs
- * Added display of AEC modes in AUTO and AGC mode
- *
- * Revision 3.62  2000/11/28 04:05:44  eokerson
- * Improved PSTN ring detection routine.
- *
- * Revision 3.61  2000/11/27 21:53:12  eokerson
- * Fixed flash detection.
- *
- * Revision 3.60  2000/11/27 15:57:29  eokerson
- * More work on G.729 load routines.
- *
- * Revision 3.59  2000/11/25 21:55:12  eokerson
- * Fixed errors in G.729 load routine.
- *
- * Revision 3.58  2000/11/25 04:08:29  eokerson
- * Added board locks around G.729 and TS85 load routines.
- *
- * Revision 3.57  2000/11/24 05:35:17  craigs
- * Added ability to retrieve mixer values on LineJACK
- * Added complete initialisation of all mixer values at startup
- * Fixed spelling mistake
- *
- * Revision 3.56  2000/11/23 02:52:11  robertj
- * Added cvs change log keyword.
- * Fixed bug in capabilities list when using G.729 module.
- *
- */
-
-#include "ixj-ver.h"
-
-#define PERFMON_STATS
-#define IXJDEBUG 0
-#define MAXRINGS 5
-
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>	/* printk() */
-#include <linux/fs.h>		/* everything... */
-#include <linux/errno.h>	/* error codes */
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/poll.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-#include <linux/isapnp.h>
-
-#include "ixj.h"
-
-#define TYPE(inode) (iminor(inode) >> 4)
-#define NUM(inode) (iminor(inode) & 0xf)
-
-static DEFINE_MUTEX(ixj_mutex);
-static int ixjdebug;
-static int hertz = HZ;
-static int samplerate = 100;
-
-module_param(ixjdebug, int, 0);
-
-static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = {
-	{ PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, ixj_pci_tbl);
-
-/************************************************************************
-*
-* ixjdebug meanings are now bit mapped instead of level based
-* Values can be or'ed together to turn on multiple messages
-*
-* bit  0 (0x0001) = any failure
-* bit  1 (0x0002) = general messages
-* bit  2 (0x0004) = POTS ringing related
-* bit  3 (0x0008) = PSTN events
-* bit  4 (0x0010) = PSTN Cadence state details
-* bit  5 (0x0020) = Tone detection triggers
-* bit  6 (0x0040) = Tone detection cadence details
-* bit  7 (0x0080) = ioctl tracking
-* bit  8 (0x0100) = signal tracking
-* bit  9 (0x0200) = CallerID generation details
-*
-************************************************************************/
-
-#ifdef IXJ_DYN_ALLOC
-
-static IXJ *ixj[IXJMAX];
-#define	get_ixj(b)	ixj[(b)]
-
-/*
- *	Allocate a free IXJ device
- */
- 
-static IXJ *ixj_alloc()
-{
-	for(cnt=0; cnt<IXJMAX; cnt++)
-	{
-		if(ixj[cnt] == NULL || !ixj[cnt]->DSPbase)
-		{
-			j = kmalloc(sizeof(IXJ), GFP_KERNEL);
-			if (j == NULL)
-				return NULL;
-			ixj[cnt] = j;
-			return j;
-		}
-	}
-	return NULL;
-}
-
-static void ixj_fsk_free(IXJ *j)
-{
-	kfree(j->fskdata);
-	j->fskdata = NULL;
-}
-
-static void ixj_fsk_alloc(IXJ *j)
-{
-	if(!j->fskdata) {
-		j->fskdata = kmalloc(8000, GFP_KERNEL);
-		if (!j->fskdata) {
-			if(ixjdebug & 0x0200) {
-				printk("IXJ phone%d - allocate failed\n", j->board);
-			}
-			return;
-		} else {
-			j->fsksize = 8000;
-			if(ixjdebug & 0x0200) {
-				printk("IXJ phone%d - allocate succeeded\n", j->board);
-			}
-		}
-	}
-}
-
-#else
-
-static IXJ ixj[IXJMAX];
-#define	get_ixj(b)	(&ixj[(b)])
-
-/*
- *	Allocate a free IXJ device
- */
- 
-static IXJ *ixj_alloc(void)
-{
-	int cnt;
-	for(cnt=0; cnt<IXJMAX; cnt++) {
-		if(!ixj[cnt].DSPbase)
-			return &ixj[cnt];
-	}
-	return NULL;
-}
-
-static inline void ixj_fsk_free(IXJ *j) {;}
-
-static inline void ixj_fsk_alloc(IXJ *j)
-{
-	j->fsksize = 8000;
-}
-
-#endif
-
-#ifdef PERFMON_STATS
-#define ixj_perfmon(x)	((x)++)
-#else
-#define ixj_perfmon(x)	do { } while(0)
-#endif
-
-static int ixj_convert_loaded;
-
-static int ixj_WriteDSPCommand(unsigned short, IXJ *j);
-
-/************************************************************************
-*
-* These are function definitions to allow external modules to register
-* enhanced functionality call backs.
-*
-************************************************************************/
-
-static int Stub(IXJ * J, unsigned long arg)
-{
-	return 0;
-}
-
-static IXJ_REGFUNC ixj_PreRead = &Stub;
-static IXJ_REGFUNC ixj_PostRead = &Stub;
-static IXJ_REGFUNC ixj_PreWrite = &Stub;
-static IXJ_REGFUNC ixj_PostWrite = &Stub;
-
-static void ixj_read_frame(IXJ *j);
-static void ixj_write_frame(IXJ *j);
-static void ixj_init_timer(IXJ *j);
-static void ixj_add_timer(IXJ *	j);
-static void ixj_timeout(unsigned long ptr);
-static int read_filters(IXJ *j);
-static int LineMonitor(IXJ *j);
-static int ixj_fasync(int fd, struct file *, int mode);
-static int ixj_set_port(IXJ *j, int arg);
-static int ixj_set_pots(IXJ *j, int arg);
-static int ixj_hookstate(IXJ *j);
-static int ixj_record_start(IXJ *j);
-static void ixj_record_stop(IXJ *j);
-static void set_rec_volume(IXJ *j, int volume);
-static int get_rec_volume(IXJ *j);
-static int set_rec_codec(IXJ *j, int rate);
-static void ixj_vad(IXJ *j, int arg);
-static int ixj_play_start(IXJ *j);
-static void ixj_play_stop(IXJ *j);
-static int ixj_set_tone_on(unsigned short arg, IXJ *j);
-static int ixj_set_tone_off(unsigned short, IXJ *j);
-static int ixj_play_tone(IXJ *j, char tone);
-static void ixj_aec_start(IXJ *j, int level);
-static int idle(IXJ *j);
-static void ixj_ring_on(IXJ *j);
-static void ixj_ring_off(IXJ *j);
-static void aec_stop(IXJ *j);
-static void ixj_ringback(IXJ *j);
-static void ixj_busytone(IXJ *j);
-static void ixj_dialtone(IXJ *j);
-static void ixj_cpt_stop(IXJ *j);
-static char daa_int_read(IXJ *j);
-static char daa_CR_read(IXJ *j, int cr);
-static int daa_set_mode(IXJ *j, int mode);
-static int ixj_linetest(IXJ *j);
-static int ixj_daa_write(IXJ *j);
-static int ixj_daa_cid_read(IXJ *j);
-static void DAA_Coeff_US(IXJ *j);
-static void DAA_Coeff_UK(IXJ *j);
-static void DAA_Coeff_France(IXJ *j);
-static void DAA_Coeff_Germany(IXJ *j);
-static void DAA_Coeff_Australia(IXJ *j);
-static void DAA_Coeff_Japan(IXJ *j);
-static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
-static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
-static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp);
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp);
-/* Serial Control Interface funtions */
-static int SCI_Control(IXJ *j, int control);
-static int SCI_Prepare(IXJ *j);
-static int SCI_WaitHighSCI(IXJ *j);
-static int SCI_WaitLowSCI(IXJ *j);
-static DWORD PCIEE_GetSerialNumber(WORD wAddress);
-static int ixj_PCcontrol_wait(IXJ *j);
-static void ixj_pre_cid(IXJ *j);
-static void ixj_write_cid(IXJ *j);
-static void ixj_write_cid_bit(IXJ *j, int bit);
-static int set_base_frame(IXJ *j, int size);
-static int set_play_codec(IXJ *j, int rate);
-static void set_rec_depth(IXJ *j, int depth);
-static int ixj_mixer(long val, IXJ *j);
-
-/************************************************************************
-CT8020/CT8021 Host Programmers Model
-Host address	Function					Access
-DSPbase +
-0-1		Aux Software Status Register (reserved)		Read Only
-2-3		Software Status Register			Read Only
-4-5		Aux Software Control Register (reserved)	Read Write
-6-7		Software Control Register			Read Write
-8-9		Hardware Status Register			Read Only
-A-B		Hardware Control Register			Read Write
-C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
-E-F Host Receive (Read) Data Buffer Access Port (buffer input)	Read Only
-************************************************************************/
-
-static inline void ixj_read_HSR(IXJ *j)
-{
-	j->hsr.bytes.low = inb_p(j->DSPbase + 8);
-	j->hsr.bytes.high = inb_p(j->DSPbase + 9);
-}
-
-static inline int IsControlReady(IXJ *j)
-{
-	ixj_read_HSR(j);
-	return j->hsr.bits.controlrdy ? 1 : 0;
-}
-
-static inline int IsPCControlReady(IXJ *j)
-{
-	j->pccr1.byte = inb_p(j->XILINXbase + 3);
-	return j->pccr1.bits.crr ? 1 : 0;
-}
-
-static inline int IsStatusReady(IXJ *j)
-{
-	ixj_read_HSR(j);
-	return j->hsr.bits.statusrdy ? 1 : 0;
-}
-
-static inline int IsRxReady(IXJ *j)
-{
-	ixj_read_HSR(j);
-	ixj_perfmon(j->rxreadycheck);
-	return j->hsr.bits.rxrdy ? 1 : 0;
-}
-
-static inline int IsTxReady(IXJ *j)
-{
-	ixj_read_HSR(j);
-	ixj_perfmon(j->txreadycheck);
-	return j->hsr.bits.txrdy ? 1 : 0;
-}
-
-static inline void set_play_volume(IXJ *j, int volume)
-{
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume);
-	ixj_WriteDSPCommand(0xCF02, j);
-	ixj_WriteDSPCommand(volume, j);
-}
-
-static int set_play_volume_linear(IXJ *j, int volume)
-{
-	int newvolume, dspplaymax;
-
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume);
-	if(volume > 100 || volume < 0) {
-		return -1;
-	}
-
-	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		dspplaymax = 0x380;
-		break;
-	case QTI_LINEJACK:
-		if(j->port == PORT_PSTN) {
-			dspplaymax = 0x48;
-		} else {
-			dspplaymax = 0x100;
-		}
-		break;
-	case QTI_PHONEJACK_LITE:
-		dspplaymax = 0x380;
-		break;
-	case QTI_PHONEJACK_PCI:
-		dspplaymax = 0x6C;
-		break;
-	case QTI_PHONECARD:
-		dspplaymax = 0x50;
-		break;
-	default:
-		return -1;
-	}
-	newvolume = (dspplaymax * volume) / 100;
-	set_play_volume(j, newvolume);
-	return 0;
-}
-
-static inline void set_play_depth(IXJ *j, int depth)
-{
-	if (depth > 60)
-		depth = 60;
-	if (depth < 0)
-		depth = 0;
-	ixj_WriteDSPCommand(0x5280 + depth, j);
-}
-
-static inline int get_play_volume(IXJ *j)
-{
-	ixj_WriteDSPCommand(0xCF00, j);
-	return j->ssr.high << 8 | j->ssr.low;
-}
-
-static int get_play_volume_linear(IXJ *j)
-{
-	int volume, newvolume, dspplaymax;
-
-	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		dspplaymax = 0x380;
-		break;
-	case QTI_LINEJACK:
-		if(j->port == PORT_PSTN) {
-			dspplaymax = 0x48;
-		} else {
-			dspplaymax = 0x100;
-		}
-		break;
-	case QTI_PHONEJACK_LITE:
-		dspplaymax = 0x380;
-		break;
-	case QTI_PHONEJACK_PCI:
-		dspplaymax = 0x6C;
-		break;
-	case QTI_PHONECARD:
-		dspplaymax = 100;
-		break;
-	default:
-		return -1;
-	}
-	volume = get_play_volume(j);
-	newvolume = (volume * 100) / dspplaymax;
-	if(newvolume > 100)
-		newvolume = 100;
-	return newvolume;
-}
-
-static inline BYTE SLIC_GetState(IXJ *j)
-{
-	if (j->cardtype == QTI_PHONECARD) {
-		j->pccr1.byte = 0;
-		j->psccr.bits.dev = 3;
-		j->psccr.bits.rw = 1;
-		outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
-		ixj_PCcontrol_wait(j);
-		j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
-		ixj_PCcontrol_wait(j);
-		if (j->pslic.bits.powerdown)
-			return PLD_SLIC_STATE_OC;
-		else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)
-			return PLD_SLIC_STATE_ACTIVE;
-		else
-			return PLD_SLIC_STATE_RINGING;
-	} else {
-		j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
-	}
-	return j->pld_slicr.bits.state;
-}
-
-static bool SLIC_SetState(BYTE byState, IXJ *j)
-{
-	bool fRetVal = false;
-
-	if (j->cardtype == QTI_PHONECARD) {
-		if (j->flags.pcmciasct) {
-			switch (byState) {
-			case PLD_SLIC_STATE_TIPOPEN:
-			case PLD_SLIC_STATE_OC:
-				j->pslic.bits.powerdown = 1;
-				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
-				fRetVal = true;
-				break;
-			case PLD_SLIC_STATE_RINGING:
-				if (j->readers || j->writers) {
-					j->pslic.bits.powerdown = 0;
-					j->pslic.bits.ring0 = 1;
-					j->pslic.bits.ring1 = 0;
-					fRetVal = true;
-				}
-				break;
-			case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
-
-			case PLD_SLIC_STATE_STANDBY:
-			case PLD_SLIC_STATE_ACTIVE:
-				if (j->readers || j->writers) {
-					j->pslic.bits.powerdown = 0;
-				} else {
-					j->pslic.bits.powerdown = 1;
-				}
-				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
-				fRetVal = true;
-				break;
-			case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
-
-			case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
-
-			default:
-				fRetVal = false;
-				break;
-			}
-			j->psccr.bits.dev = 3;
-			j->psccr.bits.rw = 0;
-			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-			ixj_PCcontrol_wait(j);
-		}
-	} else {
-		/* Set the C1, C2, C3 & B2EN signals. */
-		switch (byState) {
-		case PLD_SLIC_STATE_OC:
-			j->pld_slicw.bits.c1 = 0;
-			j->pld_slicw.bits.c2 = 0;
-			j->pld_slicw.bits.c3 = 0;
-			j->pld_slicw.bits.b2en = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_RINGING:
-			j->pld_slicw.bits.c1 = 1;
-			j->pld_slicw.bits.c2 = 0;
-			j->pld_slicw.bits.c3 = 0;
-			j->pld_slicw.bits.b2en = 1;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_ACTIVE:
-			j->pld_slicw.bits.c1 = 0;
-			j->pld_slicw.bits.c2 = 1;
-			j->pld_slicw.bits.c3 = 0;
-			j->pld_slicw.bits.b2en = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
-
-			j->pld_slicw.bits.c1 = 1;
-			j->pld_slicw.bits.c2 = 1;
-			j->pld_slicw.bits.c3 = 0;
-			j->pld_slicw.bits.b2en = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_TIPOPEN:
-			j->pld_slicw.bits.c1 = 0;
-			j->pld_slicw.bits.c2 = 0;
-			j->pld_slicw.bits.c3 = 1;
-			j->pld_slicw.bits.b2en = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_STANDBY:
-			j->pld_slicw.bits.c1 = 1;
-			j->pld_slicw.bits.c2 = 0;
-			j->pld_slicw.bits.c3 = 1;
-			j->pld_slicw.bits.b2en = 1;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
-
-			j->pld_slicw.bits.c1 = 0;
-			j->pld_slicw.bits.c2 = 1;
-			j->pld_slicw.bits.c3 = 1;
-			j->pld_slicw.bits.b2en = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
-
-			j->pld_slicw.bits.c1 = 1;
-			j->pld_slicw.bits.c2 = 1;
-			j->pld_slicw.bits.c3 = 1;
-			j->pld_slicw.bits.b2en = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			fRetVal = true;
-			break;
-		default:
-			fRetVal = false;
-			break;
-		}
-	}
-
-	return fRetVal;
-}
-
-static int ixj_wink(IXJ *j)
-{
-	BYTE slicnow;
-
-	slicnow = SLIC_GetState(j);
-
-	j->pots_winkstart = jiffies;
-	SLIC_SetState(PLD_SLIC_STATE_OC, j);
-
-	msleep(jiffies_to_msecs(j->winktime));
-
-	SLIC_SetState(slicnow, j);
-	return 0;
-}
-
-static void ixj_init_timer(IXJ *j)
-{
-	init_timer(&j->timer);
-	j->timer.function = ixj_timeout;
-	j->timer.data = (unsigned long)j;
-}
-
-static void ixj_add_timer(IXJ *j)
-{
-	j->timer.expires = jiffies + (hertz / samplerate);
-	add_timer(&j->timer);
-}
-
-static void ixj_tone_timeout(IXJ *j)
-{
-	IXJ_TONE ti;
-
-	j->tone_state++;
-	if (j->tone_state == 3) {
-		j->tone_state = 0;
-		if (j->cadence_t) {
-			j->tone_cadence_state++;
-			if (j->tone_cadence_state >= j->cadence_t->elements_used) {
-				switch (j->cadence_t->termination) {
-				case PLAY_ONCE:
-					ixj_cpt_stop(j);
-					break;
-				case REPEAT_LAST_ELEMENT:
-					j->tone_cadence_state--;
-					ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
-					break;
-				case REPEAT_ALL:
-					j->tone_cadence_state = 0;
-					if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
-						ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
-						ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
-						ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
-						ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
-						ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-						ixj_init_tone(j, &ti);
-					}
-					ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j);
-					ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j);
-					ixj_play_tone(j, j->cadence_t->ce[0].index);
-					break;
-				}
-			} else {
-				if (j->cadence_t->ce[j->tone_cadence_state].gain0) {
-					ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
-					ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
-					ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
-					ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
-					ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-					ixj_init_tone(j, &ti);
-				}
-				ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j);
-				ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j);
-				ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index);
-			}
-		}
-	}
-}
-
-static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir)
-{
-	if(j->ixj_signals[event]) {
-		if(ixjdebug & 0x0100)
-			printk("Sending signal for event %d\n", event);
-			/* Send apps notice of change */
-		/* see config.h for macro definition */
-		kill_fasync(&(j->async_queue), j->ixj_signals[event], dir);
-	}
-}
-
-static void ixj_pstn_state(IXJ *j)
-{
-	int var;
-	union XOPXR0 XR0, daaint;
-
-	var = 10;
-
-	XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg;
-	daaint.reg = 0;
-	XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
-
-	j->pld_scrr.byte = inb_p(j->XILINXbase);
-	if (j->pld_scrr.bits.daaflag) {
-		daa_int_read(j);
-		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
-			if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
-				daaint.bitreg.RING = 1;
-				if(ixjdebug & 0x0008) {
-					printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
-				}
-			} else {
-				daa_set_mode(j, SOP_PU_RESET);
-			}
-		}
-		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
-			daaint.bitreg.Caller_ID = 1;
-			j->pstn_cid_intr = 1;
-			j->pstn_cid_received = jiffies;
-			if(ixjdebug & 0x0008) {
-				printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
-			}
-		}
-		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
-			daaint.bitreg.Cadence = 1;
-			if(ixjdebug & 0x0008) {
-				printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
-			}
-		}
-		if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) {
-			daaint.bitreg.VDD_OK = 1;
-			daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK;
-		}
-	}
-	daa_CR_read(j, 1);
-	if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
-		daaint.bitreg.RMR = 1;
-		daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
-		if(ixjdebug & 0x0008) {
-                        printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr);
-		}
-		j->pstn_prev_rmr = j->pstn_last_rmr;
-		j->pstn_last_rmr = jiffies;
-	}
-	switch(j->daa_mode) {
-		case SOP_PU_SLEEP:
-			if (daaint.bitreg.RING) {
-				if (!j->flags.pstn_ringing) {
-					if (j->daa_mode != SOP_PU_RINGING) {
-						j->pstn_ring_int = jiffies;
-						daa_set_mode(j, SOP_PU_RINGING);
-					}
-				}
-			}
-			break;
-		case SOP_PU_RINGING:
-			if (daaint.bitreg.RMR) {
-				if (ixjdebug & 0x0008) {
-					printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
-				}
-				if (daaint.bitreg.SI_1) {                /* Rising edge of RMR */
-					j->flags.pstn_rmr = 1;
-					j->pstn_ring_start = jiffies;
-					j->pstn_ring_stop = 0;
-					j->ex.bits.pstn_ring = 0;
-					if (j->cadence_f[4].state == 0) {
-						j->cadence_f[4].state = 1;
-						j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000);
-						j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000);
-						j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000);
-					} else if (j->cadence_f[4].state == 2) {
-						if((time_after(jiffies, j->cadence_f[4].off1min) &&
-						    time_before(jiffies, j->cadence_f[4].off1max))) {
-							if (j->cadence_f[4].on2) {
-								j->cadence_f[4].state = 3;
-								j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000));
-								j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000));
-								j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000));
-							} else {
-								j->cadence_f[4].state = 7;
-							}
-						} else {
-							if (ixjdebug & 0x0008) {
-								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
-										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
-										j->cadence_f[4].off1);
-							}
-							j->cadence_f[4].state = 0;
-						}
-					} else if (j->cadence_f[4].state == 4) {
-						if((time_after(jiffies, j->cadence_f[4].off2min) &&
-						    time_before(jiffies, j->cadence_f[4].off2max))) {
-							if (j->cadence_f[4].on3) {
-								j->cadence_f[4].state = 5;
-								j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000));
-								j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000));
-								j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000));
-							} else {
-								j->cadence_f[4].state = 7;
-							}
-						} else {
-							if (ixjdebug & 0x0008) {
-								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
-										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
-										j->cadence_f[4].off2);
-							}
-							j->cadence_f[4].state = 0;
-						}
-					} else if (j->cadence_f[4].state == 6) {
-						if((time_after(jiffies, j->cadence_f[4].off3min) &&
-						    time_before(jiffies, j->cadence_f[4].off3max))) {
-							j->cadence_f[4].state = 7;
-						} else {
-							if (ixjdebug & 0x0008) {
-								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
-										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
-										j->cadence_f[4].off3);
-							}
-							j->cadence_f[4].state = 0;
-						}
-					} else {
-						j->cadence_f[4].state = 0;
-					}
-				} else {                                /* Falling edge of RMR */
-					j->pstn_ring_start = 0;
-					j->pstn_ring_stop = jiffies;
-					if (j->cadence_f[4].state == 1) {
-						if(!j->cadence_f[4].on1) {
-							j->cadence_f[4].state = 7;
-						} else if((time_after(jiffies, j->cadence_f[4].on1min) &&
-					          time_before(jiffies, j->cadence_f[4].on1max))) {
-							if (j->cadence_f[4].off1) {
-								j->cadence_f[4].state = 2;
-								j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000));
-								j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000));
-								j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000));
-							} else {
-								j->cadence_f[4].state = 7;
-							}
-						} else {
-							if (ixjdebug & 0x0008) {
-								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
-										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
-										j->cadence_f[4].on1);
-							}
-							j->cadence_f[4].state = 0;
-						}
-					} else if (j->cadence_f[4].state == 3) {
-						if((time_after(jiffies, j->cadence_f[4].on2min) &&
-						    time_before(jiffies, j->cadence_f[4].on2max))) {
-							if (j->cadence_f[4].off2) {
-								j->cadence_f[4].state = 4;
-								j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000));
-								j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000));
-								j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000));
-							} else {
-								j->cadence_f[4].state = 7;
-							}
-						} else {
-							if (ixjdebug & 0x0008) {
-								printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
-										j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
-										j->cadence_f[4].on2);
-							}
-							j->cadence_f[4].state = 0;
-						}
-					} else if (j->cadence_f[4].state == 5) {
-						if((time_after(jiffies, j->cadence_f[4].on3min) &&
-						    time_before(jiffies, j->cadence_f[4].on3max))) {
-							if (j->cadence_f[4].off3) {
-								j->cadence_f[4].state = 6;
-								j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000));
-								j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000));
-								j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000));
-							} else {
-								j->cadence_f[4].state = 7;
-							}
-						} else {
-							j->cadence_f[4].state = 0;
-						}
-					} else {
-						if (ixjdebug & 0x0008) {
-							printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
-									j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
-									j->cadence_f[4].on3);
-						}
-						j->cadence_f[4].state = 0;
-					}
-				}
-				if (ixjdebug & 0x0010) {
-					printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
-				}
-				if (ixjdebug & 0x0010) {
-					switch(j->cadence_f[4].state) {
-						case 1:
-							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
-						j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max);
-							break;
-						case 2:
-							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
-						j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max);
-							break;
-						case 3:
-							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
-						j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max);
-							break;
-						case 4:
-							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
-						j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max);
-							break;
-						case 5:
-							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
-						j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max);
-							break;
-						case 6:	
-							printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
-						j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max);
-							break;
-					}
-				}
-			}
-			if (j->cadence_f[4].state == 7) {
-				j->cadence_f[4].state = 0;
-				j->pstn_ring_stop = jiffies;
-				j->ex.bits.pstn_ring = 1;
-				ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN);
-				if(ixjdebug & 0x0008) {
-					printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies);
-				}
-			}
-			if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) ||
-			   (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) {
-				if(ixjdebug & 0x0008) {
-					printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies);
-					printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int);
-					printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop);
-				}
-				j->pstn_ring_stop = j->pstn_ring_int = 0;
-				daa_set_mode(j, SOP_PU_SLEEP);
-			} 
-			outb_p(j->pld_scrw.byte, j->XILINXbase);
-			if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) {
-				ixj_daa_cid_read(j);
-				j->ex.bits.caller_id = 1;
-				ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN);
-				j->pstn_cid_intr = 0;
-			}
-			if (daaint.bitreg.Cadence) {
-				if(ixjdebug & 0x0008) {
-					printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board);
-				}
-				daa_set_mode(j, SOP_PU_SLEEP);
-				j->ex.bits.pstn_ring = 0;
-			}
-			break;
-		case SOP_PU_CONVERSATION:
-			if (daaint.bitreg.VDD_OK) {
-				if(!daaint.bitreg.SI_0) {
-					if (!j->pstn_winkstart) {
-						if(ixjdebug & 0x0008) {
-							printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies);
-						}
-						j->pstn_winkstart = jiffies;
-					} 
-				} else {
-					if (j->pstn_winkstart) {
-						if(ixjdebug & 0x0008) {
-							printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies);
-						}
-						j->pstn_winkstart = 0;
-					}
-				}
-			}
-			if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) {
-				if(ixjdebug & 0x0008) {
-					printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies);
-				}
-				daa_set_mode(j, SOP_PU_SLEEP);
-				j->pstn_winkstart = 0;
-				j->ex.bits.pstn_wink = 1;
-				ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN);
-			}
-			break;
-	}
-}
-
-static void ixj_timeout(unsigned long ptr)
-{
-	int board;
-	unsigned long jifon;
-	IXJ *j = (IXJ *)ptr;
-	board = j->board;
-
-	if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) {
-		ixj_perfmon(j->timerchecks);
-		j->hookstate = ixj_hookstate(j);
-		if (j->tone_state) {
-			if (!(j->hookstate)) {
-				ixj_cpt_stop(j);
-				if (j->m_hook) {
-					j->m_hook = 0;
-					j->ex.bits.hookstate = 1;
-					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
-				}
-				clear_bit(board, &j->busyflags);
-				ixj_add_timer(j);
-				return;
-			}
-			if (j->tone_state == 1)
-				jifon = ((hertz * j->tone_on_time) * 25 / 100000);
-			else
-				jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000);
-			if (time_before(jiffies, j->tone_start_jif + jifon)) {
-				if (j->tone_state == 1) {
-					ixj_play_tone(j, j->tone_index);
-					if (j->dsp.low == 0x20) {
-						clear_bit(board, &j->busyflags);
-						ixj_add_timer(j);
-						return;
-					}
-				} else {
-					ixj_play_tone(j, 0);
-					if (j->dsp.low == 0x20) {
-						clear_bit(board, &j->busyflags);
-						ixj_add_timer(j);
-						return;
-					}
-				}
-			} else {
-				ixj_tone_timeout(j);
-				if (j->flags.dialtone) {
-					ixj_dialtone(j);
-				}
-				if (j->flags.busytone) {
-					ixj_busytone(j);
-					if (j->dsp.low == 0x20) {
-						clear_bit(board, &j->busyflags);
-						ixj_add_timer(j);
-						return;
-					}
-				}
-				if (j->flags.ringback) {
-					ixj_ringback(j);
-					if (j->dsp.low == 0x20) {
-						clear_bit(board, &j->busyflags);
-						ixj_add_timer(j);
-						return;
-					}
-				}
-				if (!j->tone_state) {
-					ixj_cpt_stop(j);
-				}
-			}
-		}
-		if (!(j->tone_state && j->dsp.low == 0x20)) {
-			if (IsRxReady(j)) {
-				ixj_read_frame(j);
-			}
-			if (IsTxReady(j)) {
-				ixj_write_frame(j);
-			}
-		}
-		if (j->flags.cringing) {
-			if (j->hookstate & 1) {
-				j->flags.cringing = 0;
-				ixj_ring_off(j);
-			} else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) {
-				switch(j->cadence_f[5].state) {
-					case 0:
-						j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000));
-						if (time_before(jiffies, j->cadence_f[5].on1dot)) {
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							ixj_ring_on(j);
-						}
-						j->cadence_f[5].state = 1;
-						break;
-					case 1:
-						if (time_after(jiffies, j->cadence_f[5].on1dot)) {
-							j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000));
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							ixj_ring_off(j);
-							j->cadence_f[5].state = 2;
-						}
-						break;
-					case 2:
-						if (time_after(jiffies, j->cadence_f[5].off1dot)) {
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							ixj_ring_on(j);
-							if (j->cadence_f[5].on2) {
-								j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000));
-								j->cadence_f[5].state = 3;
-							} else {
-								j->cadence_f[5].state = 7;
-							}
-						}
-						break;
-					case 3:
-						if (time_after(jiffies, j->cadence_f[5].on2dot)) {
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							ixj_ring_off(j);
-							if (j->cadence_f[5].off2) {
-								j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000));
-								j->cadence_f[5].state = 4;
-							} else {
-								j->cadence_f[5].state = 7;
-							}
-						}
-						break;
-					case 4:
-						if (time_after(jiffies, j->cadence_f[5].off2dot)) {
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							ixj_ring_on(j);
-							if (j->cadence_f[5].on3) {
-								j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000));
-								j->cadence_f[5].state = 5;
-							} else {
-								j->cadence_f[5].state = 7;
-							}
-						}
-						break;
-					case 5:
-						if (time_after(jiffies, j->cadence_f[5].on3dot)) {
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							ixj_ring_off(j);
-							if (j->cadence_f[5].off3) {
-								j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000));
-								j->cadence_f[5].state = 6;
-							} else {
-								j->cadence_f[5].state = 7;
-							}
-						}
-						break;
-					case 6:
-						if (time_after(jiffies, j->cadence_f[5].off3dot)) {
-							if(ixjdebug & 0x0004) {
-								printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-							}
-							j->cadence_f[5].state = 7;
-						}
-						break;
-					case 7:
-						if(ixjdebug & 0x0004) {
-							printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
-						}
-						j->flags.cidring = 1;
-						j->cadence_f[5].state = 0;
-						break;
-				}
-				if (j->flags.cidring && !j->flags.cidsent) {
-					j->flags.cidsent = 1;
-					if(j->fskdcnt) {
-						SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-						ixj_pre_cid(j);
-					}
-					j->flags.cidring = 0;
-				}
-				clear_bit(board, &j->busyflags);
-				ixj_add_timer(j);
-				return;
-			} else {
-				if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) {
-					if (j->flags.cidring && !j->flags.cidsent) {
-						j->flags.cidsent = 1;
-						if(j->fskdcnt) {
-							SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-							ixj_pre_cid(j);
-						}
-						j->flags.cidring = 0;
-					}
-					j->ring_cadence_t--;
-					if (j->ring_cadence_t == -1)
-						j->ring_cadence_t = 15;
-					j->ring_cadence_jif = jiffies;
-
-					if (j->ring_cadence & 1 << j->ring_cadence_t) {
-						if(j->flags.cidsent && j->cadence_f[5].en_filter)
-							j->flags.firstring = 1;
-						else
-							ixj_ring_on(j);
-					} else {
-						ixj_ring_off(j);
-						if(!j->flags.cidsent)
-							j->flags.cidring = 1;
-					}
-				}
-				clear_bit(board, &j->busyflags);
-				ixj_add_timer(j);
-				return;
-			}
-		}
-		if (!j->flags.ringing) {
-			if (j->hookstate) { /* & 1) { */
-				if (j->dsp.low != 0x20 &&
-				    SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
-					SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
-				}
-				LineMonitor(j);
-				read_filters(j);
-				ixj_WriteDSPCommand(0x511B, j);
-				j->proc_load = j->ssr.high << 8 | j->ssr.low;
-				if (!j->m_hook && (j->hookstate & 1)) {
-					j->m_hook = j->ex.bits.hookstate = 1;
-					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
-				}
-			} else {
-				if (j->ex.bits.dtmf_ready) {
-					j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
-				}
-				if (j->m_hook) {
-					j->m_hook = 0;
-					j->ex.bits.hookstate = 1;
-					ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
-				}
-			}
-		}
-		if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) {
-			ixj_pstn_state(j);
-		}
-		if (j->ex.bytes) {
-			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
-		}
-		clear_bit(board, &j->busyflags);
-	}
-	ixj_add_timer(j);
-}
-
-static int ixj_status_wait(IXJ *j)
-{
-	unsigned long jif;
-
-	jif = jiffies + ((60 * hertz) / 100);
-	while (!IsStatusReady(j)) {
-		ixj_perfmon(j->statuswait);
-		if (time_after(jiffies, jif)) {
-			ixj_perfmon(j->statuswaitfail);
-			return -1;
-		}
-	}
-	return 0;
-}
-
-static int ixj_PCcontrol_wait(IXJ *j)
-{
-	unsigned long jif;
-
-	jif = jiffies + ((60 * hertz) / 100);
-	while (!IsPCControlReady(j)) {
-		ixj_perfmon(j->pcontrolwait);
-		if (time_after(jiffies, jif)) {
-			ixj_perfmon(j->pcontrolwaitfail);
-			return -1;
-		}
-	}
-	return 0;
-}
-
-static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
-{
-	BYTES bytes;
-	unsigned long jif;
-
-	atomic_inc(&j->DSPWrite);
-	if(atomic_read(&j->DSPWrite) > 1) {
-		printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd);
-		return -1;
-	}
-	bytes.high = (cmd & 0xFF00) >> 8;
-	bytes.low = cmd & 0x00FF;
-	jif = jiffies + ((60 * hertz) / 100);
-	while (!IsControlReady(j)) {
-		ixj_perfmon(j->iscontrolready);
-		if (time_after(jiffies, jif)) {
-			ixj_perfmon(j->iscontrolreadyfail);
-			atomic_dec(&j->DSPWrite);
-			if(atomic_read(&j->DSPWrite) > 0) {
-				printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd);
-				while(atomic_read(&j->DSPWrite) > 0) {
-					atomic_dec(&j->DSPWrite);
-				}
-			}
-			return -1;
-		}
-	}
-	outb(bytes.low, j->DSPbase + 6);
-	outb(bytes.high, j->DSPbase + 7);
-
-	if (ixj_status_wait(j)) {
-		j->ssr.low = 0xFF;
-		j->ssr.high = 0xFF;
-		atomic_dec(&j->DSPWrite);
-		if(atomic_read(&j->DSPWrite) > 0) {
-			printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd);
-			while(atomic_read(&j->DSPWrite) > 0) {
-				atomic_dec(&j->DSPWrite);
-			}
-		}
-		return -1;
-	}
-/* Read Software Status Register */
-	j->ssr.low = inb_p(j->DSPbase + 2);
-	j->ssr.high = inb_p(j->DSPbase + 3);
-	atomic_dec(&j->DSPWrite);
-	if(atomic_read(&j->DSPWrite) > 0) {
-		printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd);
-		while(atomic_read(&j->DSPWrite) > 0) {
-			atomic_dec(&j->DSPWrite);
-		}
-	}
-	return 0;
-}
-
-/***************************************************************************
-*
-*  General Purpose IO Register read routine
-*
-***************************************************************************/
-static inline int ixj_gpio_read(IXJ *j)
-{
-	if (ixj_WriteDSPCommand(0x5143, j))
-		return -1;
-
-	j->gpio.bytes.low = j->ssr.low;
-	j->gpio.bytes.high = j->ssr.high;
-
-	return 0;
-}
-
-static inline void LED_SetState(int state, IXJ *j)
-{
-	if (j->cardtype == QTI_LINEJACK) {
-		j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
-		j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
-		j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
-		j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
-
-		outb(j->pld_scrw.byte, j->XILINXbase);
-	}
-}
-
-/*********************************************************************
-*  GPIO Pins are configured as follows on the Quicknet Internet
-*  PhoneJACK Telephony Cards
-* 
-* POTS Select        GPIO_6=0 GPIO_7=0
-* Mic/Speaker Select GPIO_6=0 GPIO_7=1
-* Handset Select     GPIO_6=1 GPIO_7=0
-*
-* SLIC Active        GPIO_1=0 GPIO_2=1 GPIO_5=0
-* SLIC Ringing       GPIO_1=1 GPIO_2=1 GPIO_5=0
-* SLIC Open Circuit  GPIO_1=0 GPIO_2=0 GPIO_5=0
-*
-* Hook Switch changes reported on GPIO_3
-*********************************************************************/
-static int ixj_set_port(IXJ *j, int arg)
-{
-	if (j->cardtype == QTI_PHONEJACK_LITE) {
-		if (arg != PORT_POTS)
-			return 10;
-		else
-			return 0;
-	}
-	switch (arg) {
-	case PORT_POTS:
-		j->port = PORT_POTS;
-		switch (j->cardtype) {
-		case QTI_PHONECARD:
-			if (j->flags.pcmciasct == 1)
-				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
-			else
-				return 11;
-			break;
-		case QTI_PHONEJACK_PCI:
-			j->pld_slicw.pcib.mic = 0;
-			j->pld_slicw.pcib.spk = 0;
-			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			break;
-		case QTI_LINEJACK:
-			ixj_set_pots(j, 0);			/* Disconnect POTS/PSTN relay */
-			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
-									   Software Control Register */
-				return 2;
-			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-			outb(j->pld_scrw.byte, j->XILINXbase);
-			j->pld_clock.byte = 0;
-			outb(j->pld_clock.byte, j->XILINXbase + 0x04);
-			j->pld_slicw.bits.rly1 = 1;
-			j->pld_slicw.bits.spken = 0;
-			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			ixj_mixer(0x1200, j);	/* Turn Off MIC switch on mixer left */
-			ixj_mixer(0x1401, j);	/* Turn On Mono1 switch on mixer left */
-			ixj_mixer(0x1300, j);       /* Turn Off MIC switch on mixer right */
-			ixj_mixer(0x1501, j);       /* Turn On Mono1 switch on mixer right */
-			ixj_mixer(0x0E80, j);	/*Mic mute */
-			ixj_mixer(0x0F00, j);	/* Set mono out (SLIC) to 0dB */
-			ixj_mixer(0x0080, j);	/* Mute Master Left volume */
-			ixj_mixer(0x0180, j);	/* Mute Master Right volume */
-			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-/*			SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
-			break;
-		case QTI_PHONEJACK:
-			j->gpio.bytes.high = 0x0B;
-			j->gpio.bits.gpio6 = 0;
-			j->gpio.bits.gpio7 = 0;
-			ixj_WriteDSPCommand(j->gpio.word, j);
-			break;
-		}
-		break;
-	case PORT_PSTN:
-		if (j->cardtype == QTI_LINEJACK) {
-			ixj_WriteDSPCommand(0xC534, j);	/* Write CODEC config to Software Control Register */
-
-			j->pld_slicw.bits.rly3 = 0;
-			j->pld_slicw.bits.rly1 = 1;
-			j->pld_slicw.bits.spken = 0;
-			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			j->port = PORT_PSTN;
-		} else {
-			return 4;
-		}
-		break;
-	case PORT_SPEAKER:
-		j->port = PORT_SPEAKER;
-		switch (j->cardtype) {
-		case QTI_PHONECARD:
-			if (j->flags.pcmciasct) {
-				SLIC_SetState(PLD_SLIC_STATE_OC, j);
-			}
-			break;
-		case QTI_PHONEJACK_PCI:
-			j->pld_slicw.pcib.mic = 1;
-			j->pld_slicw.pcib.spk = 1;
-			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			break;
-		case QTI_LINEJACK:
-			ixj_set_pots(j, 0);			/* Disconnect POTS/PSTN relay */
-			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to
-									   Software Control Register */
-				return 2;
-			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-			outb(j->pld_scrw.byte, j->XILINXbase);
-			j->pld_clock.byte = 0;
-			outb(j->pld_clock.byte, j->XILINXbase + 0x04);
-			j->pld_slicw.bits.rly1 = 1;
-			j->pld_slicw.bits.spken = 1;
-			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			ixj_mixer(0x1201, j);	/* Turn On MIC switch on mixer left */
-			ixj_mixer(0x1400, j);	/* Turn Off Mono1 switch on mixer left */
-			ixj_mixer(0x1301, j);       /* Turn On MIC switch on mixer right */
-			ixj_mixer(0x1500, j);       /* Turn Off Mono1 switch on mixer right */
-			ixj_mixer(0x0E06, j);	/*Mic un-mute 0dB */
-			ixj_mixer(0x0F80, j);	/* Mute mono out (SLIC) */
-			ixj_mixer(0x0000, j);	/* Set Master Left volume to 0dB */
-			ixj_mixer(0x0100, j);	/* Set Master Right volume to 0dB */
-			break;
-		case QTI_PHONEJACK:
-			j->gpio.bytes.high = 0x0B;
-			j->gpio.bits.gpio6 = 0;
-			j->gpio.bits.gpio7 = 1;
-			ixj_WriteDSPCommand(j->gpio.word, j);
-			break;
-		}
-		break;
-	case PORT_HANDSET:
-		if (j->cardtype != QTI_PHONEJACK) {
-			return 5;
-		} else {
-			j->gpio.bytes.high = 0x0B;
-			j->gpio.bits.gpio6 = 1;
-			j->gpio.bits.gpio7 = 0;
-			ixj_WriteDSPCommand(j->gpio.word, j);
-			j->port = PORT_HANDSET;
-		}
-		break;
-	default:
-		return 6;
-		break;
-	}
-	return 0;
-}
-
-static int ixj_set_pots(IXJ *j, int arg)
-{
-	if (j->cardtype == QTI_LINEJACK) {
-		if (arg) {
-			if (j->port == PORT_PSTN) {
-				j->pld_slicw.bits.rly1 = 0;
-				outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-				j->flags.pots_pstn = 1;
-				return 1;
-			} else {
-				j->flags.pots_pstn = 0;
-				return 0;
-			}
-		} else {
-			j->pld_slicw.bits.rly1 = 1;
-			outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			j->flags.pots_pstn = 0;
-			return 1;
-		}
-	} else {
-		return 0;
-	}
-}
-
-static void ixj_ring_on(IXJ *j)
-{
-	if (j->dsp.low == 0x20)	/* Internet PhoneJACK */
-	 {
-		if (ixjdebug & 0x0004)
-			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", 	j->board);
-
-		j->gpio.bytes.high = 0x0B;
-		j->gpio.bytes.low = 0x00;
-		j->gpio.bits.gpio1 = 1;
-		j->gpio.bits.gpio2 = 1;
-		j->gpio.bits.gpio5 = 0;
-		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring signal */
-	} else			/* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */
-	{
-		if (ixjdebug & 0x0004)
-			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
-
-		SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
-	}
-}
-
-static int ixj_siadc(IXJ *j, int val)
-{
-	if(j->cardtype == QTI_PHONECARD){
-		if(j->flags.pcmciascp){
-			if(val == -1)
-				return j->siadc.bits.rxg;
-
-			if(val < 0 || val > 0x1F)
-				return -1;
-
-			j->siadc.bits.hom = 0;				/* Handset Out Mute */
-			j->siadc.bits.lom = 0;				/* Line Out Mute */
-			j->siadc.bits.rxg = val;			/*(0xC000 - 0x41C8) / 0x4EF;    RX PGA Gain */
-			j->psccr.bits.addr = 6;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(j->siadc.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-			return j->siadc.bits.rxg;
-		}
-	}
-	return -1;
-}
-
-static int ixj_sidac(IXJ *j, int val)
-{
-	if(j->cardtype == QTI_PHONECARD){
-		if(j->flags.pcmciascp){
-			if(val == -1)
-				return j->sidac.bits.txg;
-
-			if(val < 0 || val > 0x1F)
-				return -1;
-
-			j->sidac.bits.srm = 1;				/* Speaker Right Mute */
-			j->sidac.bits.slm = 1;				/* Speaker Left Mute */
-			j->sidac.bits.txg = val;			/* (0xC000 - 0x45E4) / 0x5D3;	 TX PGA Gain */
-			j->psccr.bits.addr = 7;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(j->sidac.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-			return j->sidac.bits.txg;
-		}
-	}
-	return -1;
-}
-
-static int ixj_pcmcia_cable_check(IXJ *j)
-{
-	j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
-	if (!j->flags.pcmciastate) {
-		j->pccr2.byte = inb_p(j->XILINXbase + 0x02);
-		if (j->pccr1.bits.drf || j->pccr2.bits.rstc) {
-			j->flags.pcmciastate = 4;
-			return 0;
-		}
-		if (j->pccr1.bits.ed) {
-			j->pccr1.bits.ed = 0;
-			j->psccr.bits.dev = 3;
-			j->psccr.bits.rw = 1;
-			outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
-			ixj_PCcontrol_wait(j);
-			j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
-			j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0;
-			j->psccr.bits.dev = 3;
-			j->psccr.bits.rw = 0;
-			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-			ixj_PCcontrol_wait(j);
-			return j->pslic.bits.led2 ? 1 : 0;
-		} else if (j->flags.pcmciasct) {
-			return j->r_hook;
-		} else {
-			return 1;
-		}
-	} else if (j->flags.pcmciastate == 4) {
-		if (!j->pccr1.bits.drf) {
-			j->flags.pcmciastate = 3;
-		}
-		return 0;
-	} else if (j->flags.pcmciastate == 3) {
-		j->pccr2.bits.pwr = 0;
-		j->pccr2.bits.rstc = 1;
-		outb(j->pccr2.byte, j->XILINXbase + 0x02);
-		j->checkwait = jiffies + (hertz * 2);
-		j->flags.incheck = 1;
-		j->flags.pcmciastate = 2;
-		return 0;
-	} else if (j->flags.pcmciastate == 2) {
-		if (j->flags.incheck) {
-			if (time_before(jiffies, j->checkwait)) {
-				return 0;
-			} else {
-				j->flags.incheck = 0;
-			}
-		}
-		j->pccr2.bits.pwr = 0;
-		j->pccr2.bits.rstc = 0;
-		outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
-		j->flags.pcmciastate = 1;
-		return 0;
-	} else if (j->flags.pcmciastate == 1) {
-		j->flags.pcmciastate = 0;
-		if (!j->pccr1.bits.drf) {
-			j->psccr.bits.dev = 3;
-			j->psccr.bits.rw = 1;
-			outb_p(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-			j->flags.pcmciascp = 1;		/* Set Cable Present Flag */
-
-			j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;		/* Get Cable Type */
-
-			if (j->flags.pcmciasct == 3) {
-				j->flags.pcmciastate = 4;
-				return 0;
-			} else if (j->flags.pcmciasct == 0) {
-				j->pccr2.bits.pwr = 1;
-				j->pccr2.bits.rstc = 0;
-				outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
-				j->port = PORT_SPEAKER;
-			} else {
-				j->port = PORT_POTS;
-			}
-			j->sic1.bits.cpd = 0;				/* Chip Power Down */
-			j->sic1.bits.mpd = 0;				/* MIC Bias Power Down */
-			j->sic1.bits.hpd = 0;				/* Handset Bias Power Down */
-			j->sic1.bits.lpd = 0;				/* Line Bias Power Down */
-			j->sic1.bits.spd = 1;				/* Speaker Drive Power Down */
-			j->psccr.bits.addr = 1;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(j->sic1.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-
-			j->sic2.bits.al = 0;				/* Analog Loopback DAC analog -> ADC analog */
-			j->sic2.bits.dl2 = 0;				/* Digital Loopback DAC -> ADC one bit */
-			j->sic2.bits.dl1 = 0;				/* Digital Loopback ADC -> DAC one bit */
-			j->sic2.bits.pll = 0;				/* 1 = div 10, 0 = div 5 */
-			j->sic2.bits.hpd = 0;				/* HPF disable */
-			j->psccr.bits.addr = 2;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(j->sic2.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-
-			j->psccr.bits.addr = 3;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(0x00, j->XILINXbase + 0x00);		/* PLL Divide N1 */
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-
-			j->psccr.bits.addr = 4;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(0x09, j->XILINXbase + 0x00);		/* PLL Multiply M1 */
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-
-			j->sirxg.bits.lig = 1;				/* Line In Gain */
-			j->sirxg.bits.lim = 1;				/* Line In Mute */
-			j->sirxg.bits.mcg = 0;				/* MIC In Gain was 3 */
-			j->sirxg.bits.mcm = 0;				/* MIC In Mute */
-			j->sirxg.bits.him = 0;				/* Handset In Mute */
-			j->sirxg.bits.iir = 1;				/* IIR */
-			j->psccr.bits.addr = 5;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(j->sirxg.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-
-			ixj_siadc(j, 0x17);
-			ixj_sidac(j, 0x1D);
-
-			j->siaatt.bits.sot = 0;
-			j->psccr.bits.addr = 9;				/* R/W Smart Cable Register Address */
-			j->psccr.bits.rw = 0;				/* Read / Write flag */
-			j->psccr.bits.dev = 0;
-			outb(j->siaatt.byte, j->XILINXbase + 0x00);
-			outb(j->psccr.byte, j->XILINXbase + 0x01);
-			ixj_PCcontrol_wait(j);
-
-			if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) {
-				j->psccr.byte = j->pslic.byte = 0;
-				j->pslic.bits.powerdown = 1;
-				j->psccr.bits.dev = 3;
-				j->psccr.bits.rw = 0;
-				outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-				ixj_PCcontrol_wait(j);
-			}
-		}
-		return 0;
-	} else {
-		j->flags.pcmciascp = 0;
-		return 0;
-	}
-	return 0;
-}
-
-static int ixj_hookstate(IXJ *j)
-{
-	int fOffHook = 0;
-
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		ixj_gpio_read(j);
-		fOffHook = j->gpio.bits.gpio3read ? 1 : 0;
-		break;
-	case QTI_LINEJACK:
-	case QTI_PHONEJACK_LITE:
-	case QTI_PHONEJACK_PCI:
-		SLIC_GetState(j);
-		if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) {
-			fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0;
-			if(fOffHook != j->p_hook) {
-				if(!j->checkwait) {
-					j->checkwait = jiffies;
-				} 
-				if(time_before(jiffies, j->checkwait + 2)) {
-					fOffHook ^= 1;
-				} else {
-					j->checkwait = 0;
-				}
-				j->p_hook = fOffHook;
-	 			printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies);
-			}
-		} else {
-			if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
-			    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
-				if (j->flags.ringing || j->flags.cringing) {
-					if (!in_interrupt()) {
-						msleep(20);
-					}
-					SLIC_GetState(j);
-					if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
-						ixj_ring_on(j);
-					}
-				}
-				if (j->cardtype == QTI_PHONEJACK_PCI) {
-					j->pld_scrr.byte = inb_p(j->XILINXbase);
-					fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
-				} else
-					fOffHook = j->pld_slicr.bits.det ? 1 : 0;
-			}
-		}
-		break;
-	case QTI_PHONECARD:
-		fOffHook = ixj_pcmcia_cable_check(j);
-		break;
-	}
-	if (j->r_hook != fOffHook) {
-		j->r_hook = fOffHook;
-		if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) {
-			j->ex.bits.hookstate = 1;
-			ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
-		} else if (!fOffHook) {
-			j->flash_end = jiffies + ((60 * hertz) / 100);
-		}
-	}
-	if (fOffHook) {
-		if(time_before(jiffies, j->flash_end)) {
-			j->ex.bits.flash = 1;
-			j->flash_end = 0;
-			ixj_kill_fasync(j, SIG_FLASH, POLL_IN);
-		}
-	} else {
-		if(time_before(jiffies, j->flash_end)) {
-			fOffHook = 1;
-		}
-	}
-
-	if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
-		fOffHook |= 2;
-
-	if (j->port == PORT_SPEAKER) {
-		if(j->cardtype == QTI_PHONECARD) {
-			if(j->flags.pcmciascp && j->flags.pcmciasct) {
-				fOffHook |= 2;
-			}
-		} else {
-			fOffHook |= 2;
-		}
-	}
-
-	if (j->port == PORT_HANDSET)
-		fOffHook |= 2;
-
-	return fOffHook;
-}
-
-static void ixj_ring_off(IXJ *j)
-{
-	if (j->dsp.low == 0x20)	/* Internet PhoneJACK */
-	 {
-		if (ixjdebug & 0x0004)
-			printk(KERN_INFO "IXJ Ring Off\n");
-		j->gpio.bytes.high = 0x0B;
-		j->gpio.bytes.low = 0x00;
-		j->gpio.bits.gpio1 = 0;
-		j->gpio.bits.gpio2 = 1;
-		j->gpio.bits.gpio5 = 0;
-		ixj_WriteDSPCommand(j->gpio.word, j);
-	} else			/* Internet LineJACK */
-	{
-		if (ixjdebug & 0x0004)
-			printk(KERN_INFO "IXJ Ring Off\n");
-
-		if(!j->flags.cidplay)
-			SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-
-		SLIC_GetState(j);
-	}
-}
-
-static void ixj_ring_start(IXJ *j)
-{
-	j->flags.cringing = 1;
-	if (ixjdebug & 0x0004)
-		printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board);
-	if (ixj_hookstate(j) & 1) {
-		if (j->port == PORT_POTS)
-			ixj_ring_off(j);
-		j->flags.cringing = 0;
-		if (ixjdebug & 0x0004)
-			printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board);
-	} else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) {
-		j->ring_cadence_jif = jiffies;
-		j->flags.cidsent = j->flags.cidring = 0;
-		j->cadence_f[5].state = 0;
-		if(j->cadence_f[5].on1)
-			ixj_ring_on(j);
-	} else {
-		j->ring_cadence_jif = jiffies;
-		j->ring_cadence_t = 15;
-		if (j->ring_cadence & 1 << j->ring_cadence_t) {
-			ixj_ring_on(j);
-		} else {
-			ixj_ring_off(j);
-		}
-		j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0;
-	}
-}
-
-static int ixj_ring(IXJ *j)
-{
-	char cntr;
-	unsigned long jif;
-
-	j->flags.ringing = 1;
-	if (ixj_hookstate(j) & 1) {
-		ixj_ring_off(j);
-		j->flags.ringing = 0;
-		return 1;
-	}
-	for (cntr = 0; cntr < j->maxrings; cntr++) {
-		jif = jiffies + (1 * hertz);
-		ixj_ring_on(j);
-		while (time_before(jiffies, jif)) {
-			if (ixj_hookstate(j) & 1) {
-				ixj_ring_off(j);
-				j->flags.ringing = 0;
-				return 1;
-			}
-			schedule_timeout_interruptible(1);
-			if (signal_pending(current))
-				break;
-		}
-		jif = jiffies + (3 * hertz);
-		ixj_ring_off(j);
-		while (time_before(jiffies, jif)) {
-			if (ixj_hookstate(j) & 1) {
-				msleep(10);
-				if (ixj_hookstate(j) & 1) {
-					j->flags.ringing = 0;
-					return 1;
-				}
-			}
-			schedule_timeout_interruptible(1);
-			if (signal_pending(current))
-				break;
-		}
-	}
-	ixj_ring_off(j);
-	j->flags.ringing = 0;
-	return 0;
-}
-
-static int ixj_open(struct phone_device *p, struct file *file_p)
-{
-	IXJ *j = get_ixj(p->board);
-	file_p->private_data = j;
-
-	if (!j->DSPbase)
-		return -ENODEV;
-
-        if (file_p->f_mode & FMODE_READ) {
-		if(!j->readers) {
-	                j->readers++;
-        	} else {
-                	return -EBUSY;
-		}
-        }
-
-	if (file_p->f_mode & FMODE_WRITE) {
-		if(!j->writers) {
-			j->writers++;
-		} else {
-			if (file_p->f_mode & FMODE_READ){
-				j->readers--;
-			}
-			return -EBUSY;
-		}
-	}
-
-	if (j->cardtype == QTI_PHONECARD) {
-		j->pslic.bits.powerdown = 0;
-		j->psccr.bits.dev = 3;
-		j->psccr.bits.rw = 0;
-		outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
-		ixj_PCcontrol_wait(j);
-	}
-
-	j->flags.cidplay = 0;
-	j->flags.cidcw_ack = 0;
-
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Opening board %d\n", p->board);
-
-	j->framesread = j->frameswritten = 0;
-	return 0;
-}
-
-static int ixj_release(struct inode *inode, struct file *file_p)
-{
-	IXJ_TONE ti;
-	int cnt;
-	IXJ *j = file_p->private_data;
-	int board = j->p.board;
-
-	/*
-	 *    Set up locks to ensure that only one process is talking to the DSP at a time.
-	 *    This is necessary to keep the DSP from locking up.
-	 */
-	while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
-		schedule_timeout_interruptible(1);
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Closing board %d\n", NUM(inode));
-
-	if (j->cardtype == QTI_PHONECARD)
-		ixj_set_port(j, PORT_SPEAKER);
-	else
-		ixj_set_port(j, PORT_POTS);
-
-	aec_stop(j);
-	ixj_play_stop(j);
-	ixj_record_stop(j);
-	set_play_volume(j, 0x100);
-	set_rec_volume(j, 0x100);
-	ixj_ring_off(j);
-
-	/* Restore the tone table to default settings. */
-	ti.tone_index = 10;
-	ti.gain0 = 1;
-	ti.freq0 = hz941;
-	ti.gain1 = 0;
-	ti.freq1 = hz1209;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 11;
-	ti.gain0 = 1;
-	ti.freq0 = hz941;
-	ti.gain1 = 0;
-	ti.freq1 = hz1336;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 12;
-	ti.gain0 = 1;
-	ti.freq0 = hz941;
-	ti.gain1 = 0;
-	ti.freq1 = hz1477;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 13;
-	ti.gain0 = 1;
-	ti.freq0 = hz800;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 14;
-	ti.gain0 = 1;
-	ti.freq0 = hz1000;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 15;
-	ti.gain0 = 1;
-	ti.freq0 = hz1250;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 16;
-	ti.gain0 = 1;
-	ti.freq0 = hz950;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 17;
-	ti.gain0 = 1;
-	ti.freq0 = hz1100;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 18;
-	ti.gain0 = 1;
-	ti.freq0 = hz1400;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 19;
-	ti.gain0 = 1;
-	ti.freq0 = hz1500;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 20;
-	ti.gain0 = 1;
-	ti.freq0 = hz1600;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 21;
-	ti.gain0 = 1;
-	ti.freq0 = hz1800;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 22;
-	ti.gain0 = 1;
-	ti.freq0 = hz2100;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 23;
-	ti.gain0 = 1;
-	ti.freq0 = hz1300;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 24;
-	ti.gain0 = 1;
-	ti.freq0 = hz2450;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 25;
-	ti.gain0 = 1;
-	ti.freq0 = hz350;
-	ti.gain1 = 0;
-	ti.freq1 = hz440;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 26;
-	ti.gain0 = 1;
-	ti.freq0 = hz440;
-	ti.gain1 = 0;
-	ti.freq1 = hz480;
-	ixj_init_tone(j, &ti);
-	ti.tone_index = 27;
-	ti.gain0 = 1;
-	ti.freq0 = hz480;
-	ti.gain1 = 0;
-	ti.freq1 = hz620;
-	ixj_init_tone(j, &ti);
-
-	set_rec_depth(j, 2);	/* Set Record Channel Limit to 2 frames */
-
-	set_play_depth(j, 2);	/* Set Playback Channel Limit to 2 frames */
-
-	j->ex.bits.dtmf_ready = 0;
-	j->dtmf_state = 0;
-	j->dtmf_wp = j->dtmf_rp = 0;
-	j->rec_mode = j->play_mode = -1;
-	j->flags.ringing = 0;
-	j->maxrings = MAXRINGS;
-	j->ring_cadence = USA_RING_CADENCE;
-	if(j->cadence_f[5].enable) {
-		j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0;
-	}
-	j->drybuffer = 0;
-	j->winktime = 320;
-	j->flags.dtmf_oob = 0;
-	for (cnt = 0; cnt < 4; cnt++)
-		j->cadence_f[cnt].enable = 0;
-
-	idle(j);
-
-	if(j->cardtype == QTI_PHONECARD) {
-		SLIC_SetState(PLD_SLIC_STATE_OC, j);
-	}
-
-	if (file_p->f_mode & FMODE_READ)
-		j->readers--;
-	if (file_p->f_mode & FMODE_WRITE)
-		j->writers--;
-
-	if (j->read_buffer && !j->readers) {
-		kfree(j->read_buffer);
-		j->read_buffer = NULL;
-		j->read_buffer_size = 0;
-	}
-	if (j->write_buffer && !j->writers) {
-		kfree(j->write_buffer);
-		j->write_buffer = NULL;
-		j->write_buffer_size = 0;
-	}
-	j->rec_codec = j->play_codec = 0;
-	j->rec_frame_size = j->play_frame_size = 0;
-	j->flags.cidsent = j->flags.cidring = 0;
-
-	if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
-		ixj_set_port(j, PORT_PSTN);
-		daa_set_mode(j, SOP_PU_SLEEP);
-		ixj_set_pots(j, 1);
-	}
-	ixj_WriteDSPCommand(0x0FE3, j);	/* Put the DSP in 1/5 power mode. */
-
-	/* Set up the default signals for events */
-	for (cnt = 0; cnt < 35; cnt++)
-		j->ixj_signals[cnt] = SIGIO;
-
-	/* Set the excetion signal enable flags */
-	j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
-	j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
-	j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
-
-	file_p->private_data = NULL;
-	clear_bit(board, &j->busyflags);
-	return 0;
-}
-
-static int read_filters(IXJ *j)
-{
-	unsigned short fc, cnt, trg;
-	int var;
-
-	trg = 0;
-	if (ixj_WriteDSPCommand(0x5144, j)) {
-		if(ixjdebug & 0x0001) {
-			printk(KERN_INFO "Read Frame Counter failed!\n");
-		}
-		return -1;
-	}
-	fc = j->ssr.high << 8 | j->ssr.low;
-	if (fc == j->frame_count)
-		return 1;
-
-	j->frame_count = fc;
-
-	if (j->dtmf_proc)
-		return 1;
-
-	var = 10;
-
-	for (cnt = 0; cnt < 4; cnt++) {
-		if (ixj_WriteDSPCommand(0x5154 + cnt, j)) {
-			if(ixjdebug & 0x0001) {
-				printk(KERN_INFO "Select Filter %d failed!\n", cnt);
-			}
-			return -1;
-		}
-		if (ixj_WriteDSPCommand(0x515C, j)) {
-			if(ixjdebug & 0x0001) {
-				printk(KERN_INFO "Read Filter History %d failed!\n", cnt);
-			}
-			return -1;
-		}
-		j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
-
-		if (j->cadence_f[cnt].enable) {
-			if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
-				if (j->cadence_f[cnt].state == 0) {
-					j->cadence_f[cnt].state = 1;
-					j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000));
-					j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000));
-					j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000));
-				} else if (j->cadence_f[cnt].state == 2 &&
-					   (time_after(jiffies, j->cadence_f[cnt].off1min) &&
-					    time_before(jiffies, j->cadence_f[cnt].off1max))) {
-					if (j->cadence_f[cnt].on2) {
-						j->cadence_f[cnt].state = 3;
-						j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000));
-						j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000));
-						j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000));
-					} else {
-						j->cadence_f[cnt].state = 7;
-					}
-				} else if (j->cadence_f[cnt].state == 4 &&
-					   (time_after(jiffies, j->cadence_f[cnt].off2min) &&
-					    time_before(jiffies, j->cadence_f[cnt].off2max))) {
-					if (j->cadence_f[cnt].on3) {
-						j->cadence_f[cnt].state = 5;
-						j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000));
-						j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000));
-						j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000));
-					} else {
-						j->cadence_f[cnt].state = 7;
-					}
-				} else {
-					j->cadence_f[cnt].state = 0;
-				}
-			} else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
-				if (j->cadence_f[cnt].state == 1) {
-					if(!j->cadence_f[cnt].on1) {
-						j->cadence_f[cnt].state = 7;
-					} else if((time_after(jiffies, j->cadence_f[cnt].on1min) &&
-					  time_before(jiffies, j->cadence_f[cnt].on1max))) {
-						if(j->cadence_f[cnt].off1) {
-							j->cadence_f[cnt].state = 2;
-							j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000));
-							j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000));
-							j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000));
-						} else {
-							j->cadence_f[cnt].state = 7;
-						}
-					} else {
-						j->cadence_f[cnt].state = 0;
-					}
-				} else if (j->cadence_f[cnt].state == 3) {
-					if((time_after(jiffies, j->cadence_f[cnt].on2min) &&
-					    time_before(jiffies, j->cadence_f[cnt].on2max))) {
-						if(j->cadence_f[cnt].off2) {
-							j->cadence_f[cnt].state = 4;
-							j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000));
-							j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000));
-							j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000));
-						} else {
-							j->cadence_f[cnt].state = 7;
-						}
-					} else {
-						j->cadence_f[cnt].state = 0;
-					}
-				} else if (j->cadence_f[cnt].state == 5) {
-					if ((time_after(jiffies, j->cadence_f[cnt].on3min) &&
-					    time_before(jiffies, j->cadence_f[cnt].on3max))) {
-						if(j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 6;
-							j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000));
-							j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000));
-							j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000));
-						} else {
-							j->cadence_f[cnt].state = 7;
-						}
-					} else {
-						j->cadence_f[cnt].state = 0;
-					}
-				} else {
-					j->cadence_f[cnt].state = 0;
-				}
-			} else {
-				switch(j->cadence_f[cnt].state) {
-					case 1:
-						if(time_after(jiffies, j->cadence_f[cnt].on1dot) &&
-						   !j->cadence_f[cnt].off1 &&
-						   !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
-						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 7;
-						}
-						break;
-					case 3:
-						if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
-						   !j->cadence_f[cnt].off2 &&
-						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 7;
-						}
-						break;
-					case 5:
-						if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
-						   !j->cadence_f[cnt].off3) {
-							j->cadence_f[cnt].state = 7;
-						}
-						break;
-				}
-			}
-
-			if (ixjdebug & 0x0040) {
-				printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies);
-				switch(j->cadence_f[cnt].state) {
-					case 0:
-						printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board);
-						break;
-					case 1:
-						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board,
-					j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max);
-						break;
-					case 2:
-						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, 
-															j->cadence_f[cnt].off1max);
-						break;
-					case 3:
-						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min,
-															j->cadence_f[cnt].on2max);
-						break;
-					case 4:
-						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min,
-															j->cadence_f[cnt].off2max);
-						break;
-					case 5:
-						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min,
-															j->cadence_f[cnt].on3max);
-						break;
-					case 6:	
-						printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min,
-															j->cadence_f[cnt].off3max);
-						break;
-				}
-			} 
-		}
-		if (j->cadence_f[cnt].state == 7) {
-			j->cadence_f[cnt].state = 0;
-			if (j->cadence_f[cnt].enable == 1)
-				j->cadence_f[cnt].enable = 0;
-			switch (cnt) {
-			case 0:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies);
-				}
-				j->ex.bits.fc0 = 1;
-				ixj_kill_fasync(j, SIG_FC0, POLL_IN);
-				break;
-			case 1:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies);
-				}
-				j->ex.bits.fc1 = 1;
-				ixj_kill_fasync(j, SIG_FC1, POLL_IN);
-				break;
-			case 2:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies);
-				}
-				j->ex.bits.fc2 = 1;
-				ixj_kill_fasync(j, SIG_FC2, POLL_IN);
-				break;
-			case 3:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies);
-				}
-				j->ex.bits.fc3 = 1;
-				ixj_kill_fasync(j, SIG_FC3, POLL_IN);
-				break;
-			}
-		}
-		if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
-					  (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
-			if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) {
-				trg = 1;
-			} else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) {
-				trg = 0;
-			}
-			switch (cnt) {
-			case 0:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies);
-				}
-				j->ex.bits.f0 = 1;
-				ixj_kill_fasync(j, SIG_F0, POLL_IN);
-				break;
-			case 1:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies);
-				}
-				j->ex.bits.f1 = 1;
-				ixj_kill_fasync(j, SIG_F1, POLL_IN);
-				break;
-			case 2:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies);
-				}
-				j->ex.bits.f2 = 1;
-				ixj_kill_fasync(j, SIG_F2, POLL_IN);
-				break;
-			case 3:
-				if(ixjdebug & 0x0020) {
-					printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies);
-				}
-				j->ex.bits.f3 = 1;
-				ixj_kill_fasync(j, SIG_F3, POLL_IN);
-				break;
-			}
-		}
-	}
-	return 0;
-}
-
-static int LineMonitor(IXJ *j)
-{
-	if (j->dtmf_proc) {
-		return -1;
-	}
-	j->dtmf_proc = 1;
-
-	if (ixj_WriteDSPCommand(0x7000, j))		/* Line Monitor */
-		return -1;
-
-	j->dtmf.bytes.high = j->ssr.high;
-	j->dtmf.bytes.low = j->ssr.low;
-	if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) {
-		j->dtmf_state = 1;
-		j->dtmf_current = j->dtmf.bits.digit;
-	}
-	if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)	/* && j->dtmf_wp != j->dtmf_rp) */
-	 {
-		if(!j->cidcw_wait) {
-			j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
-			j->dtmf_wp++;
-			if (j->dtmf_wp == 79)
-				j->dtmf_wp = 0;
-			j->ex.bits.dtmf_ready = 1;
-			if(j->ex_sig.bits.dtmf_ready) {
-				ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN);
-			}
-		}
-		else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) {
-			if(ixjdebug & 0x0020) {
-				printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies);
-			}
-			j->flags.cidcw_ack = 1;
-		}
-		j->dtmf_state = 0;
-	}
-	j->dtmf_proc = 0;
-
-	return 0;
-}
-
-/************************************************************************
-*
-* Functions to allow alaw <-> ulaw conversions.
-*
-************************************************************************/
-
-static void ulaw2alaw(unsigned char *buff, unsigned long len)
-{
-	static unsigned char table_ulaw2alaw[] =
-	{
-		0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, 
-		0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, 
-		0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 
-		0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, 
-		0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, 
-		0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, 
-		0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, 
-		0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, 
-		0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, 
-		0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, 
-		0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, 
-		0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, 
-		0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, 
-		0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, 
-		0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 
-		0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, 
-		0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, 
-		0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, 
-		0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, 
-		0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, 
-		0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, 
-		0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, 
-		0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, 
-		0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, 
-		0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, 
-		0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, 
-		0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, 
-		0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, 
-		0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, 
-		0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, 
-		0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, 
-		0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5
-	};
-
-	while (len--)
-	{
-		*buff = table_ulaw2alaw[*(unsigned char *)buff];
-		buff++;
-	}
-}
-
-static void alaw2ulaw(unsigned char *buff, unsigned long len)
-{
-	static unsigned char table_alaw2ulaw[] =
-	{
-		0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, 
-		0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, 
-		0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, 
-		0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, 
-		0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 
-		0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 
-		0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 
-		0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 
-		0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 
-		0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, 
-		0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, 
-		0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 
-		0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, 
-		0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, 
-		0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, 
-		0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, 
-		0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, 
-		0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, 
-		0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, 
-		0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, 
-		0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 
-		0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 
-		0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 
-		0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 
-		0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 
-		0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, 
-		0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, 
-		0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 
-		0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, 
-		0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, 
-		0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, 
-		0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1
-	};
-
-        while (len--)
-        {
-                *buff = table_alaw2ulaw[*(unsigned char *)buff];
-                buff++;
-	}
-}
-
-static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
-{
-	unsigned long i = *ppos;
-	IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
-	DECLARE_WAITQUEUE(wait, current);
-
-	if (j->flags.inread)
-		return -EALREADY;
-
-	j->flags.inread = 1;
-
-	add_wait_queue(&j->read_q, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	mb();
-
-	while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
-		++j->read_wait;
-		if (file_p->f_flags & O_NONBLOCK) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->read_q, &wait);
-			j->flags.inread = 0;
-			return -EAGAIN;
-		}
-		if (!ixj_hookstate(j)) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->read_q, &wait);
-			j->flags.inread = 0;
-			return 0;
-		}
-		interruptible_sleep_on(&j->read_q);
-		if (signal_pending(current)) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->read_q, &wait);
-			j->flags.inread = 0;
-			return -EINTR;
-		}
-	}
-
-	remove_wait_queue(&j->read_q, &wait);
-	set_current_state(TASK_RUNNING);
-	/* Don't ever copy more than the user asks */
-	if(j->rec_codec == ALAW)
-		ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size));
-	i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
-	j->read_buffer_ready = 0;
-	if (i) {
-		j->flags.inread = 0;
-		return -EFAULT;
-	} else {
-		j->flags.inread = 0;
-		return min(length, j->read_buffer_size);
-	}
-}
-
-static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length,
-			  loff_t * ppos)
-{
-	int pre_retval;
-	ssize_t read_retval = 0;
-	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
-	pre_retval = ixj_PreRead(j, 0L);
-	switch (pre_retval) {
-	case NORMAL:
-		read_retval = ixj_read(file_p, buf, length, ppos);
-		ixj_PostRead(j, 0L);
-		break;
-	case NOPOST:
-		read_retval = ixj_read(file_p, buf, length, ppos);
-		break;
-	case POSTONLY:
-		ixj_PostRead(j, 0L);
-		break;
-	default:
-		read_retval = pre_retval;
-	}
-	return read_retval;
-}
-
-static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos)
-{
-	unsigned long i = *ppos;
-	IXJ *j = file_p->private_data;
-
-	DECLARE_WAITQUEUE(wait, current);
-
-	if (j->flags.inwrite)
-		return -EALREADY;
-
-	j->flags.inwrite = 1;
-
-	add_wait_queue(&j->write_q, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	mb();
-
-
-	while (!j->write_buffers_empty) {
-		++j->write_wait;
-		if (file_p->f_flags & O_NONBLOCK) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->write_q, &wait);
-			j->flags.inwrite = 0;
-			return -EAGAIN;
-		}
-		if (!ixj_hookstate(j)) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->write_q, &wait);
-			j->flags.inwrite = 0;
-			return 0;
-		}
-		interruptible_sleep_on(&j->write_q);
-		if (signal_pending(current)) {
-			set_current_state(TASK_RUNNING);
-			remove_wait_queue(&j->write_q, &wait);
-			j->flags.inwrite = 0;
-			return -EINTR;
-		}
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&j->write_q, &wait);
-	if (j->write_buffer_wp + count >= j->write_buffer_end)
-		j->write_buffer_wp = j->write_buffer;
-	i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
-	if (i) {
-		j->flags.inwrite = 0;
-		return -EFAULT;
-	}
-       if(j->play_codec == ALAW)
-               alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size));
-	j->flags.inwrite = 0;
-	return min(count, j->write_buffer_size);
-}
-
-static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos)
-{
-	int pre_retval;
-	ssize_t write_retval = 0;
-
-	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
-	pre_retval = ixj_PreWrite(j, 0L);
-	switch (pre_retval) {
-	case NORMAL:
-		write_retval = ixj_write(file_p, buf, count, ppos);
-		if (write_retval > 0) {
-			ixj_PostWrite(j, 0L);
-			j->write_buffer_wp += write_retval;
-			j->write_buffers_empty--;
-		}
-		break;
-	case NOPOST:
-		write_retval = ixj_write(file_p, buf, count, ppos);
-		if (write_retval > 0) {
-			j->write_buffer_wp += write_retval;
-			j->write_buffers_empty--;
-		}
-		break;
-	case POSTONLY:
-		ixj_PostWrite(j, 0L);
-		break;
-	default:
-		write_retval = pre_retval;
-	}
-	return write_retval;
-}
-
-static void ixj_read_frame(IXJ *j)
-{
-	int cnt, dly;
-
-	if (j->read_buffer) {
-		for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
-			if (!(cnt % 16) && !IsRxReady(j)) {
-				dly = 0;
-				while (!IsRxReady(j)) {
-					if (dly++ > 5) {
-						dly = 0;
-						break;
-					}
-					udelay(10);
-				}
-			}
-			/* Throw away word 0 of the 8021 compressed format to get standard G.729. */
-			if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
-				inb_p(j->DSPbase + 0x0E);
-				inb_p(j->DSPbase + 0x0F);
-			}
-			*(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);
-			*(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);
-		}
-		++j->framesread;
-		if (j->intercom != -1) {
-			if (IsTxReady(get_ixj(j->intercom))) {
-				for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
-					if (!(cnt % 16) && !IsTxReady(j)) {
-						dly = 0;
-						while (!IsTxReady(j)) {
-							if (dly++ > 5) {
-								dly = 0;
-								break;
-							}
-							udelay(10);
-						}
-					}
-					outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C);
-					outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D);
-				}
-				get_ixj(j->intercom)->frameswritten++;
-			}
-		} else {
-			j->read_buffer_ready = 1;
-			wake_up_interruptible(&j->read_q);	/* Wake any blocked readers */
-
-			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
-
-			if(j->ixj_signals[SIG_READ_READY])
-				ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT);
-		}
-	}
-}
-
-static short fsk[][6][20] =
-{
-	{
-		{
-			0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196,
-			-16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722
-		},
-		{
-			-28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481,
-			-32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876
-		},
-		{
-			-28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715,
-			-16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846
-		},
-		{
-			0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196,
-			16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722
-		},
-		{
-			28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481,
-			32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876
-		},
-		{
-			28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715,
-			16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846
-		}
-	},
-	{
-		{
-			0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126,
-			0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126
-		},
-		{
-			-28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051,
-			28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051
-		},
-		{
-			-28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925,
-			28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925
-		},
-		{
-			0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126,
-			0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126
-		},
-		{
-			28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051,
-			-28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051
-		},
-		{
-			28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925,
-			-28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925
-		}
-	}
-};
-
-
-static void ixj_write_cid_bit(IXJ *j, int bit)
-{
-	while (j->fskcnt < 20) {
-		if(j->fskdcnt < (j->fsksize - 1))
-			j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt];
-
-		j->fskcnt += 3;
-	}
-	j->fskcnt %= 20;
-
-	if (!bit)
-		j->fskz++;
-	if (j->fskz >= 6)
-		j->fskz = 0;
-
-}
-
-static void ixj_write_cid_byte(IXJ *j, char byte)
-{
-	IXJ_CBYTE cb;
-
-		cb.cbyte = byte;
-		ixj_write_cid_bit(j, 0);
-		ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0);
-		ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0);
-		ixj_write_cid_bit(j, 1);
-}
-
-static void ixj_write_cid_seize(IXJ *j)
-{
-	int cnt;
-
-	for (cnt = 0; cnt < 150; cnt++) {
-		ixj_write_cid_bit(j, 0);
-		ixj_write_cid_bit(j, 1);
-	}
-	for (cnt = 0; cnt < 180; cnt++) {
-		ixj_write_cid_bit(j, 1);
-	}
-}
-
-static void ixj_write_cidcw_seize(IXJ *j)
-{
-	int cnt;
-
-	for (cnt = 0; cnt < 80; cnt++) {
-		ixj_write_cid_bit(j, 1);
-	}
-}
-
-static int ixj_write_cid_string(IXJ *j, char *s, int checksum)
-{
-	int cnt;
-
-	for (cnt = 0; cnt < strlen(s); cnt++) {
-		ixj_write_cid_byte(j, s[cnt]);
-		checksum = (checksum + s[cnt]);
-	}
-	return checksum;
-}
-
-static void ixj_pad_fsk(IXJ *j, int pad)
-{
-	int cnt; 
-
-	for (cnt = 0; cnt < pad; cnt++) {
-		if(j->fskdcnt < (j->fsksize - 1))
-			j->fskdata[j->fskdcnt++] = 0x0000;
-	}
-	for (cnt = 0; cnt < 720; cnt++) {
-		if(j->fskdcnt < (j->fsksize - 1))
-			j->fskdata[j->fskdcnt++] = 0x0000;
-	}
-}
-
-static void ixj_pre_cid(IXJ *j)
-{
-	j->cid_play_codec = j->play_codec;
-	j->cid_play_frame_size = j->play_frame_size;
-	j->cid_play_volume = get_play_volume(j);
-	j->cid_play_flag = j->flags.playing;
-
-	j->cid_rec_codec = j->rec_codec;
-	j->cid_rec_volume = get_rec_volume(j);
-	j->cid_rec_flag = j->flags.recording;
-
-	j->cid_play_aec_level = j->aec_level;
-
-	switch(j->baseframe.low) {
-		case 0xA0:
-			j->cid_base_frame_size = 20;
-			break;
-		case 0x50:
-			j->cid_base_frame_size = 10;
-			break;
-		case 0xF0:
-			j->cid_base_frame_size = 30;
-			break;
-	}
-
-	ixj_play_stop(j);
-	ixj_cpt_stop(j);
-
-	j->flags.cidplay = 1;
-
-	set_base_frame(j, 30);
-	set_play_codec(j, LINEAR16);
-	set_play_volume(j, 0x1B);
-	ixj_play_start(j);
-}
-
-static void ixj_post_cid(IXJ *j)
-{
-	ixj_play_stop(j);
-
-	if(j->cidsize > 5000) {
-		SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-	}
-	j->flags.cidplay = 0;
-	if(ixjdebug & 0x0200) {
-		printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies);
-	}
-
-	ixj_fsk_free(j);
-
-	j->fskdcnt = 0;
-	set_base_frame(j, j->cid_base_frame_size);
-	set_play_codec(j, j->cid_play_codec);
-	ixj_aec_start(j, j->cid_play_aec_level);
-	set_play_volume(j, j->cid_play_volume);
-
-	set_rec_codec(j, j->cid_rec_codec);
-	set_rec_volume(j, j->cid_rec_volume);
-
-	if(j->cid_rec_flag)
-		ixj_record_start(j);
-
-	if(j->cid_play_flag)
-		ixj_play_start(j);
-
-	if(j->cid_play_flag) {
-		wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
-	}
-}
-
-static void ixj_write_cid(IXJ *j)
-{
-	char sdmf1[50];
-	char sdmf2[50];
-	char sdmf3[80];
-	char mdmflen, len1, len2, len3;
-	int pad;
-
-	int checksum = 0;
-
-	if (j->dsp.low == 0x20 || j->flags.cidplay)
-		return;
-
-	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
-	j->cidsize = j->cidcnt = 0;
-
-	ixj_fsk_alloc(j);
-
-	strcpy(sdmf1, j->cid_send.month);
-	strcat(sdmf1, j->cid_send.day);
-	strcat(sdmf1, j->cid_send.hour);
-	strcat(sdmf1, j->cid_send.min);
-	strcpy(sdmf2, j->cid_send.number);
-	strcpy(sdmf3, j->cid_send.name);
-
-	len1 = strlen(sdmf1);
-	len2 = strlen(sdmf2);
-	len3 = strlen(sdmf3);
-	mdmflen = len1 + len2 + len3 + 6;
-
-	while(1){
-		ixj_write_cid_seize(j);
-
-		ixj_write_cid_byte(j, 0x80);
-		checksum = 0x80;
-		ixj_write_cid_byte(j, mdmflen);
-		checksum = checksum + mdmflen;
-
-		ixj_write_cid_byte(j, 0x01);
-		checksum = checksum + 0x01;
-		ixj_write_cid_byte(j, len1);
-		checksum = checksum + len1;
-		checksum = ixj_write_cid_string(j, sdmf1, checksum);
-		if(ixj_hookstate(j) & 1)
-			break;
-
-		ixj_write_cid_byte(j, 0x02);
-		checksum = checksum + 0x02;
-		ixj_write_cid_byte(j, len2);
-		checksum = checksum + len2;
-		checksum = ixj_write_cid_string(j, sdmf2, checksum);
-		if(ixj_hookstate(j) & 1)
-			break;
-
-		ixj_write_cid_byte(j, 0x07);
-		checksum = checksum + 0x07;
-		ixj_write_cid_byte(j, len3);
-		checksum = checksum + len3;
-		checksum = ixj_write_cid_string(j, sdmf3, checksum);
-		if(ixj_hookstate(j) & 1)
-			break;
-
-		checksum %= 256;
-		checksum ^= 0xFF;
-		checksum += 1;
-
-		ixj_write_cid_byte(j, (char) checksum);
-
-		pad = j->fskdcnt % 240;
-		if (pad) {
-			pad = 240 - pad;
-		}
-		ixj_pad_fsk(j, pad);
-		break;
-	}
-
-	ixj_write_frame(j);
-}
-
-static void ixj_write_cidcw(IXJ *j)
-{
-	IXJ_TONE ti;
-
-	char sdmf1[50];
-	char sdmf2[50];
-	char sdmf3[80];
-	char mdmflen, len1, len2, len3;
-	int pad;
-
-	int checksum = 0;
-
-	if (j->dsp.low == 0x20 || j->flags.cidplay)
-		return;
-
-	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
-	j->cidsize = j->cidcnt = 0;
-
-	ixj_fsk_alloc(j);
-
-	j->flags.cidcw_ack = 0;
-
-	ti.tone_index = 23;
-	ti.gain0 = 1;
-	ti.freq0 = hz440;
-	ti.gain1 = 0;
-	ti.freq1 = 0;
-	ixj_init_tone(j, &ti);
-
-	ixj_set_tone_on(1500, j);
-	ixj_set_tone_off(32, j);
-	if(ixjdebug & 0x0200) {
-		printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies);
-	}
-	ixj_play_tone(j, 23);
-
-	clear_bit(j->board, &j->busyflags);
-	while(j->tone_state)
-		schedule_timeout_interruptible(1);
-	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
-		schedule_timeout_interruptible(1);
-	if(ixjdebug & 0x0200) {
-		printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
-	}
-
-	ti.tone_index = 24;
-	ti.gain0 = 1;
-	ti.freq0 = hz2130;
-	ti.gain1 = 0;
-	ti.freq1 = hz2750;
-	ixj_init_tone(j, &ti);
-
-	ixj_set_tone_off(10, j);
-	ixj_set_tone_on(600, j);
-	if(ixjdebug & 0x0200) {
-		printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies);
-	}
-	ixj_play_tone(j, 24);
-
-	clear_bit(j->board, &j->busyflags);
-	while(j->tone_state)
-		schedule_timeout_interruptible(1);
-	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
-		schedule_timeout_interruptible(1);
-	if(ixjdebug & 0x0200) {
-		printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
-	}
-
-	j->cidcw_wait = jiffies + ((50 * hertz) / 100);
-
-	clear_bit(j->board, &j->busyflags);
-	while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait))
-		schedule_timeout_interruptible(1);
-	while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0)
-		schedule_timeout_interruptible(1);
-	j->cidcw_wait = 0;
-	if(!j->flags.cidcw_ack) {
-		if(ixjdebug & 0x0200) {
-			printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies);
-		}
-		ixj_post_cid(j);
-		if(j->cid_play_flag) {
-			wake_up_interruptible(&j->write_q);	/* Wake any blocked readers */
-		}
-		return;
-	} else {
-		ixj_pre_cid(j);
-	}
-	j->flags.cidcw_ack = 0;
-	strcpy(sdmf1, j->cid_send.month);
-	strcat(sdmf1, j->cid_send.day);
-	strcat(sdmf1, j->cid_send.hour);
-	strcat(sdmf1, j->cid_send.min);
-	strcpy(sdmf2, j->cid_send.number);
-	strcpy(sdmf3, j->cid_send.name);
-
-	len1 = strlen(sdmf1);
-	len2 = strlen(sdmf2);
-	len3 = strlen(sdmf3);
-	mdmflen = len1 + len2 + len3 + 6;
-
-	ixj_write_cidcw_seize(j);
-
-	ixj_write_cid_byte(j, 0x80);
-	checksum = 0x80;
-	ixj_write_cid_byte(j, mdmflen);
-	checksum = checksum + mdmflen;
-
-	ixj_write_cid_byte(j, 0x01);
-	checksum = checksum + 0x01;
-	ixj_write_cid_byte(j, len1);
-	checksum = checksum + len1;
-	checksum = ixj_write_cid_string(j, sdmf1, checksum);
-
-	ixj_write_cid_byte(j, 0x02);
-	checksum = checksum + 0x02;
-	ixj_write_cid_byte(j, len2);
-	checksum = checksum + len2;
-	checksum = ixj_write_cid_string(j, sdmf2, checksum);
-
-	ixj_write_cid_byte(j, 0x07);
-	checksum = checksum + 0x07;
-	ixj_write_cid_byte(j, len3);
-	checksum = checksum + len3;
-	checksum = ixj_write_cid_string(j, sdmf3, checksum);
-
-	checksum %= 256;
-	checksum ^= 0xFF;
-	checksum += 1;
-
-	ixj_write_cid_byte(j, (char) checksum);
-
-	pad = j->fskdcnt % 240;
-	if (pad) {
-		pad = 240 - pad;
-	}
-	ixj_pad_fsk(j, pad);
-	if(ixjdebug & 0x0200) {
-		printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies);
-	}
-}
-
-static void ixj_write_vmwi(IXJ *j, int msg)
-{
-	char mdmflen;
-	int pad;
-
-	int checksum = 0;
-
-	if (j->dsp.low == 0x20 || j->flags.cidplay)
-		return;
-
-	j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
-	j->cidsize = j->cidcnt = 0;
-
-	ixj_fsk_alloc(j);
-
-	mdmflen = 3;
-
-	if (j->port == PORT_POTS)
-		SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-
-	ixj_write_cid_seize(j);
-
-	ixj_write_cid_byte(j, 0x82);
-	checksum = 0x82;
-	ixj_write_cid_byte(j, mdmflen);
-	checksum = checksum + mdmflen;
-
-	ixj_write_cid_byte(j, 0x0B);
-	checksum = checksum + 0x0B;
-	ixj_write_cid_byte(j, 1);
-	checksum = checksum + 1;
-
-	if(msg) {
-		ixj_write_cid_byte(j, 0xFF);
-		checksum = checksum + 0xFF;
-	}
-	else {
-		ixj_write_cid_byte(j, 0x00);
-		checksum = checksum + 0x00;
-	}
-
-	checksum %= 256;
-	checksum ^= 0xFF;
-	checksum += 1;
-
-	ixj_write_cid_byte(j, (char) checksum);
-
-	pad = j->fskdcnt % 240;
-	if (pad) {
-		pad = 240 - pad;
-	}
-	ixj_pad_fsk(j, pad);
-}
-
-static void ixj_write_frame(IXJ *j)
-{
-	int cnt, frame_count, dly;
-	IXJ_WORD dat;
-
-	frame_count = 0;
-	if(j->flags.cidplay) {
-		for(cnt = 0; cnt < 480; cnt++) {
-			if (!(cnt % 16) && !IsTxReady(j)) {
-				dly = 0;
-				while (!IsTxReady(j)) {
-					if (dly++ > 5) {
-						dly = 0;
-						break;
-					}
-					udelay(10);
-				}
-			}
-			dat.word = j->fskdata[j->cidcnt++];
-			outb_p(dat.bytes.low, j->DSPbase + 0x0C);
-			outb_p(dat.bytes.high, j->DSPbase + 0x0D);
-			cnt++;
-		}
-		if(j->cidcnt >= j->fskdcnt) {
-			ixj_post_cid(j);
-		}
-		/* This may seem rude, but if we just played one frame of FSK data for CallerID
-		   and there is real audio data in the buffer, we need to throw it away because 
-		   we just used it's time slot */
-		if (j->write_buffer_rp > j->write_buffer_wp) {
-			j->write_buffer_rp += j->cid_play_frame_size * 2;
-			if (j->write_buffer_rp >= j->write_buffer_end) {
-				j->write_buffer_rp = j->write_buffer;
-			}
-			j->write_buffers_empty++;
-			wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
-
-			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
-		}
-	} else if (j->write_buffer && j->write_buffers_empty < 1) { 
-		if (j->write_buffer_wp > j->write_buffer_rp) {
-			frame_count =
-			    (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
-		}
-		if (j->write_buffer_rp > j->write_buffer_wp) {
-			frame_count =
-			    (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) +
-			    (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2);
-		}
-		if (frame_count >= 1) {
-			if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) {
-				BYTES blankword;
-
-				switch (j->play_mode) {
-				case PLAYBACK_MODE_ULAW:
-				case PLAYBACK_MODE_ALAW:
-					blankword.low = blankword.high = 0xFF;
-					break;
-				case PLAYBACK_MODE_8LINEAR:
-				case PLAYBACK_MODE_16LINEAR:
-				default:
-					blankword.low = blankword.high = 0x00;
-					break;
-				case PLAYBACK_MODE_8LINEAR_WSS:
-					blankword.low = blankword.high = 0x80;
-					break;
-				}
-				for (cnt = 0; cnt < 16; cnt++) {
-					if (!(cnt % 16) && !IsTxReady(j)) {
-						dly = 0;
-						while (!IsTxReady(j)) {
-							if (dly++ > 5) {
-								dly = 0;
-								break;
-							}
-							udelay(10);
-						}
-					}
-					outb_p((blankword.low), j->DSPbase + 0x0C);
-					outb_p((blankword.high), j->DSPbase + 0x0D);
-				}
-				j->flags.play_first_frame = 0;
-			} else	if (j->play_codec == G723_63 && j->flags.play_first_frame) {
-				for (cnt = 0; cnt < 24; cnt++) {
-					BYTES blankword;
-
-					if(cnt == 12) {
-						blankword.low = 0x02;
-						blankword.high = 0x00;
-					}
-					else {
-						blankword.low = blankword.high = 0x00;
-					}
-					if (!(cnt % 16) && !IsTxReady(j)) {
-						dly = 0;
-						while (!IsTxReady(j)) {
-							if (dly++ > 5) {
-								dly = 0;
-								break;
-							}
-							udelay(10);
-						}
-					}
-					outb_p((blankword.low), j->DSPbase + 0x0C);
-					outb_p((blankword.high), j->DSPbase + 0x0D);
-				}
-				j->flags.play_first_frame = 0;
-			}
-			for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
-				if (!(cnt % 16) && !IsTxReady(j)) {
-					dly = 0;
-					while (!IsTxReady(j)) {
-						if (dly++ > 5) {
-							dly = 0;
-							break;
-						}
-						udelay(10);
-					}
-				}
-			/* Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG  */
-				if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
-					if (j->write_buffer_rp[cnt] == 0 &&
-					    j->write_buffer_rp[cnt + 1] == 0 &&
-					    j->write_buffer_rp[cnt + 2] == 0 &&
-					    j->write_buffer_rp[cnt + 3] == 0 &&
-					    j->write_buffer_rp[cnt + 4] == 0 &&
-					    j->write_buffer_rp[cnt + 5] == 0 &&
-					    j->write_buffer_rp[cnt + 6] == 0 &&
-					    j->write_buffer_rp[cnt + 7] == 0 &&
-					    j->write_buffer_rp[cnt + 8] == 0 &&
-					    j->write_buffer_rp[cnt + 9] == 0) {
-					/* someone is trying to write silence lets make this a type 0 frame. */
-						outb_p(0x00, j->DSPbase + 0x0C);
-						outb_p(0x00, j->DSPbase + 0x0D);
-					} else {
-					/* so all other frames are type 1. */
-						outb_p(0x01, j->DSPbase + 0x0C);
-						outb_p(0x00, j->DSPbase + 0x0D);
-					}
-				}
-				outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
-				outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
-				*(j->write_buffer_rp + cnt) = 0;
-				*(j->write_buffer_rp + cnt + 1) = 0;
-			}
-			j->write_buffer_rp += j->play_frame_size * 2;
-			if (j->write_buffer_rp >= j->write_buffer_end) {
-				j->write_buffer_rp = j->write_buffer;
-			}
-			j->write_buffers_empty++;
-			wake_up_interruptible(&j->write_q);	/* Wake any blocked writers */
-
-			wake_up_interruptible(&j->poll_q);	/* Wake any blocked selects */
-
-			++j->frameswritten;
-		}
-	} else {
-		j->drybuffer++;
-	}
-	if(j->ixj_signals[SIG_WRITE_READY]) {
-		ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT);
-	}
-}
-
-static int idle(IXJ *j)
-{
-	if (ixj_WriteDSPCommand(0x0000, j))		/* DSP Idle */
-
-		return 0;
-
-	if (j->ssr.high || j->ssr.low) {
-		return 0;
-	} else {
-		j->play_mode = -1;
-		j->flags.playing = 0;
-		j->rec_mode = -1;
-		j->flags.recording = 0;
-		return 1;
-        }
-}
-
-static int set_base_frame(IXJ *j, int size)
-{
-	unsigned short cmd;
-	int cnt;
-
-	idle(j);
-	j->cid_play_aec_level = j->aec_level;
-	aec_stop(j);
-	for (cnt = 0; cnt < 10; cnt++) {
-		if (idle(j))
-			break;
-	}
-	if (j->ssr.high || j->ssr.low)
-		return -1;
-	if (j->dsp.low != 0x20) {
-		switch (size) {
-		case 30:
-			cmd = 0x07F0;
-			/* Set Base Frame Size to 240 pg9-10 8021 */
-			break;
-		case 20:
-			cmd = 0x07A0;
-			/* Set Base Frame Size to 160 pg9-10 8021 */
-			break;
-		case 10:
-			cmd = 0x0750;
-			/* Set Base Frame Size to 80 pg9-10 8021 */
-			break;
-		default:
-			return -1;
-		}
-	} else {
-		if (size == 30)
-			return size;
-		else
-			return -1;
-	}
-	if (ixj_WriteDSPCommand(cmd, j)) {
-		j->baseframe.high = j->baseframe.low = 0xFF;
-		return -1;
-	} else {
-		j->baseframe.high = j->ssr.high;
-		j->baseframe.low = j->ssr.low;
-		/* If the status returned is 0x0000 (pg9-9 8021) the call failed */
-		if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) {
-			return -1;
-		}
-	}
-	ixj_aec_start(j, j->cid_play_aec_level);
-	return size;
-}
-
-static int set_rec_codec(IXJ *j, int rate)
-{
-	int retval = 0;
-
-	j->rec_codec = rate;
-
-	switch (rate) {
-	case G723_63:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->rec_frame_size = 12;
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G723_53:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->rec_frame_size = 10;
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case TS85:
-		if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
-			j->rec_frame_size = 16;
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case TS48:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->rec_frame_size = 9;
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case TS41:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->rec_frame_size = 8;
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G728:
-		if (j->dsp.low != 0x20) {
-			j->rec_frame_size = 48;
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G729:
-		if (j->dsp.low != 0x20) {
-			if (!j->flags.g729_loaded) {
-				retval = 1;
-				break;
-			}
-			switch (j->baseframe.low) {
-			case 0xA0:
-				j->rec_frame_size = 10;
-				break;
-			case 0x50:
-				j->rec_frame_size = 5;
-				break;
-			default:
-				j->rec_frame_size = 15;
-				break;
-			}
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G729B:
-		if (j->dsp.low != 0x20) {
-			if (!j->flags.g729_loaded) {
-				retval = 1;
-				break;
-			}
-			switch (j->baseframe.low) {
-			case 0xA0:
-				j->rec_frame_size = 12;
-				break;
-			case 0x50:
-				j->rec_frame_size = 6;
-				break;
-			default:
-				j->rec_frame_size = 18;
-				break;
-			}
-			j->rec_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case ULAW:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->rec_frame_size = 80;
-			break;
-		case 0x50:
-			j->rec_frame_size = 40;
-			break;
-		default:
-			j->rec_frame_size = 120;
-			break;
-		}
-		j->rec_mode = 4;
-		break;
-	case ALAW:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->rec_frame_size = 80;
-			break;
-		case 0x50:
-			j->rec_frame_size = 40;
-			break;
-		default:
-			j->rec_frame_size = 120;
-			break;
-		}
-		j->rec_mode = 4;
-		break;
-	case LINEAR16:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->rec_frame_size = 160;
-			break;
-		case 0x50:
-			j->rec_frame_size = 80;
-			break;
-		default:
-			j->rec_frame_size = 240;
-			break;
-		}
-		j->rec_mode = 5;
-		break;
-	case LINEAR8:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->rec_frame_size = 80;
-			break;
-		case 0x50:
-			j->rec_frame_size = 40;
-			break;
-		default:
-			j->rec_frame_size = 120;
-			break;
-		}
-		j->rec_mode = 6;
-		break;
-	case WSS:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->rec_frame_size = 80;
-			break;
-		case 0x50:
-			j->rec_frame_size = 40;
-			break;
-		default:
-			j->rec_frame_size = 120;
-			break;
-		}
-		j->rec_mode = 7;
-		break;
-	default:
-		kfree(j->read_buffer);
-		j->rec_frame_size = 0;
-		j->rec_mode = -1;
-		j->read_buffer = NULL;
-		j->read_buffer_size = 0;
-		retval = 1;
-		break;
-	}
-	return retval;
-}
-
-static int ixj_record_start(IXJ *j)
-{
-	unsigned short cmd = 0x0000;
-
-	if (j->read_buffer) {
-		ixj_record_stop(j);
-	}
-	j->flags.recording = 1;
-	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
-
-	if(ixjdebug & 0x0002)
-		printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
-
-	if (!j->rec_mode) {
-		switch (j->rec_codec) {
-		case G723_63:
-			cmd = 0x5131;
-			break;
-		case G723_53:
-			cmd = 0x5132;
-			break;
-		case TS85:
-			cmd = 0x5130;	/* TrueSpeech 8.5 */
-
-			break;
-		case TS48:
-			cmd = 0x5133;	/* TrueSpeech 4.8 */
-
-			break;
-		case TS41:
-			cmd = 0x5134;	/* TrueSpeech 4.1 */
-
-			break;
-		case G728:
-			cmd = 0x5135;
-			break;
-		case G729:
-		case G729B:
-			cmd = 0x5136;
-			break;
-		default:
-			return 1;
-		}
-		if (ixj_WriteDSPCommand(cmd, j))
-			return -1;
-	}
-	if (!j->read_buffer) {
-		if (!j->read_buffer)
-			j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
-		if (!j->read_buffer) {
-			printk("Read buffer allocation for ixj board %d failed!\n", j->board);
-			return -ENOMEM;
-		}
-	}
-	j->read_buffer_size = j->rec_frame_size * 2;
-
-	if (ixj_WriteDSPCommand(0x5102, j))		/* Set Poll sync mode */
-
-		return -1;
-
-	switch (j->rec_mode) {
-	case 0:
-		cmd = 0x1C03;	/* Record C1 */
-
-		break;
-	case 4:
-		if (j->ver.low == 0x12) {
-			cmd = 0x1E03;	/* Record C1 */
-
-		} else {
-			cmd = 0x1E01;	/* Record C1 */
-
-		}
-		break;
-	case 5:
-		if (j->ver.low == 0x12) {
-			cmd = 0x1E83;	/* Record C1 */
-
-		} else {
-			cmd = 0x1E81;	/* Record C1 */
-
-		}
-		break;
-	case 6:
-		if (j->ver.low == 0x12) {
-			cmd = 0x1F03;	/* Record C1 */
-
-		} else {
-			cmd = 0x1F01;	/* Record C1 */
-
-		}
-		break;
-	case 7:
-		if (j->ver.low == 0x12) {
-			cmd = 0x1F83;	/* Record C1 */
-		} else {
-			cmd = 0x1F81;	/* Record C1 */
-		}
-		break;
-	}
-	if (ixj_WriteDSPCommand(cmd, j))
-		return -1;
-
-	if (j->flags.playing) {
-		ixj_aec_start(j, j->aec_level);
-	}
-	return 0;
-}
-
-static void ixj_record_stop(IXJ *j)
-{
-	if (ixjdebug & 0x0002)
-		printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
-
-	kfree(j->read_buffer);
-	j->read_buffer = NULL;
-	j->read_buffer_size = 0;
-	if (j->rec_mode > -1) {
-		ixj_WriteDSPCommand(0x5120, j);
-		j->rec_mode = -1;
-	}
-	j->flags.recording = 0;
-}
-static void ixj_vad(IXJ *j, int arg)
-{
-	if (arg)
-		ixj_WriteDSPCommand(0x513F, j);
-	else
-		ixj_WriteDSPCommand(0x513E, j);
-}
-
-static void set_rec_depth(IXJ *j, int depth)
-{
-	if (depth > 60)
-		depth = 60;
-	if (depth < 0)
-		depth = 0;
-	ixj_WriteDSPCommand(0x5180 + depth, j);
-}
-
-static void set_dtmf_prescale(IXJ *j, int volume)
-{
-	ixj_WriteDSPCommand(0xCF07, j);
-	ixj_WriteDSPCommand(volume, j);
-}
-
-static int get_dtmf_prescale(IXJ *j)
-{
-	ixj_WriteDSPCommand(0xCF05, j);
-	return j->ssr.high << 8 | j->ssr.low;
-}
-
-static void set_rec_volume(IXJ *j, int volume)
-{
-	if(j->aec_level == AEC_AGC) {
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume);
-		ixj_WriteDSPCommand(0xCF96, j);
-		ixj_WriteDSPCommand(volume, j);
-	} else {
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume);
-		ixj_WriteDSPCommand(0xCF03, j);
-		ixj_WriteDSPCommand(volume, j);
-	}
-}
-
-static int set_rec_volume_linear(IXJ *j, int volume)
-{
-	int newvolume, dsprecmax;
-
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume);
-	if(volume > 100 || volume < 0) {
-	  return -1;
-	}
-
-	/* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		dsprecmax = 0x440;
-		break;
-	case QTI_LINEJACK:
-		dsprecmax = 0x180;
-		ixj_mixer(0x0203, j);	/*Voice Left Volume unmute 6db */
-		ixj_mixer(0x0303, j);	/*Voice Right Volume unmute 6db */
-		ixj_mixer(0x0C00, j);	/*Mono1 unmute 12db */
-		break;
-	case QTI_PHONEJACK_LITE:
-		dsprecmax = 0x4C0;
-		break;
-	case QTI_PHONEJACK_PCI:
-		dsprecmax = 0x100;
-		break;
-	case QTI_PHONECARD:
-		dsprecmax = 0x400;
-		break;
-	default:
-		return -1;
-	}
-	newvolume = (dsprecmax * volume) / 100;
-	set_rec_volume(j, newvolume);
-	return 0;
-}
-
-static int get_rec_volume(IXJ *j)
-{
-	if(j->aec_level == AEC_AGC) {
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Getting AGC Threshold\n");
-		ixj_WriteDSPCommand(0xCF86, j);
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low);
-		return j->ssr.high << 8 | j->ssr.low;
-	} else {
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Getting Record Volume\n");
-		ixj_WriteDSPCommand(0xCF01, j);
-		return j->ssr.high << 8 | j->ssr.low;
-	}
-}
-
-static int get_rec_volume_linear(IXJ *j)
-{
-	int volume, newvolume, dsprecmax;
-
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		dsprecmax = 0x440;
-		break;
-	case QTI_LINEJACK:
-		dsprecmax = 0x180;
-		break;
-	case QTI_PHONEJACK_LITE:
-		dsprecmax = 0x4C0;
-		break;
-	case QTI_PHONEJACK_PCI:
-		dsprecmax = 0x100;
-		break;
-	case QTI_PHONECARD:
-		dsprecmax = 0x400;
-		break;
-	default:
-		return -1;
-	}
-	volume = get_rec_volume(j);
-	newvolume = (volume * 100) / dsprecmax;
-	if(newvolume > 100)
-		newvolume = 100;
-	return newvolume;
-}
-
-static int get_rec_level(IXJ *j)
-{
-	int retval;
-
-	ixj_WriteDSPCommand(0xCF88, j);
-
-	retval = j->ssr.high << 8 | j->ssr.low;
-	retval = (retval * 256) / 240;
-	return retval;
-}
-
-static void ixj_aec_start(IXJ *j, int level)
-{
-	j->aec_level = level;
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level);
-	if (!level) {
-		aec_stop(j);
-	} else {
-		if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
-			ixj_WriteDSPCommand(0xE022, j);	/* Move AEC filter buffer */
-
-			ixj_WriteDSPCommand(0x0300, j);
-		}
-		ixj_WriteDSPCommand(0xB001, j);	/* AEC On */
-
-		ixj_WriteDSPCommand(0xE013, j);	/* Advanced AEC C1 */
-
-		switch (level) {
-		case AEC_LOW:
-			ixj_WriteDSPCommand(0x0000, j);	/* Advanced AEC C2 = off */
-
-			ixj_WriteDSPCommand(0xE011, j);
-			ixj_WriteDSPCommand(0xFFFF, j);
-
-			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
-			ixj_WriteDSPCommand(0x0000, j);	/* to off */
-			
-			break;
-
-		case AEC_MED:
-			ixj_WriteDSPCommand(0x0600, j);	/* Advanced AEC C2 = on medium */
-
-			ixj_WriteDSPCommand(0xE011, j);
-			ixj_WriteDSPCommand(0x0080, j);
-
-			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
-			ixj_WriteDSPCommand(0x0000, j);	/* to off */
-			
-			break;
-
-		case AEC_HIGH:
-			ixj_WriteDSPCommand(0x0C00, j);	/* Advanced AEC C2 = on high */
-
-			ixj_WriteDSPCommand(0xE011, j);
-			ixj_WriteDSPCommand(0x0080, j);
-
-			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
-			ixj_WriteDSPCommand(0x0000, j);	/* to off */
-			
-			break;
-
-		case AEC_AGC:
-                        /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */
-			ixj_WriteDSPCommand(0x0002, j);	/* Attenuation scaling factor of 2 */
-
-			ixj_WriteDSPCommand(0xE011, j);
-			ixj_WriteDSPCommand(0x0100, j);	/* Higher Threshold Floor */
-
-			ixj_WriteDSPCommand(0xE012, j);	/* Set Train and Lock */
-
-			if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
-				ixj_WriteDSPCommand(0x0224, j);
-			else
-				ixj_WriteDSPCommand(0x1224, j);
-
-			ixj_WriteDSPCommand(0xE014, j);
-			ixj_WriteDSPCommand(0x0003, j);	/* Lock threshold at 3dB */
-
-			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
-
-			/* Now we can set the AGC initial parameters and turn it on */
-			ixj_WriteDSPCommand(0xCF90, j);	/* Set AGC Minimum gain */
-			ixj_WriteDSPCommand(0x0020, j);	/* to 0.125 (-18dB) */
-	
-			ixj_WriteDSPCommand(0xCF91, j);	/* Set AGC Maximum gain */
-			ixj_WriteDSPCommand(0x1000, j);	/* to 16 (24dB) */
-			
-			ixj_WriteDSPCommand(0xCF92, j);	/* Set AGC start gain */
-			ixj_WriteDSPCommand(0x0800, j);	/* to 8 (+18dB) */
-		
-			ixj_WriteDSPCommand(0xCF93, j);	/* Set AGC hold time */
-			ixj_WriteDSPCommand(0x1F40, j);	/* to 2 seconds (units are 250us) */
-			
-			ixj_WriteDSPCommand(0xCF94, j);	/* Set AGC Attack Time Constant */
-			ixj_WriteDSPCommand(0x0005, j);	/* to 8ms */
-			
-			ixj_WriteDSPCommand(0xCF95, j);	/* Set AGC Decay Time Constant */
-			ixj_WriteDSPCommand(0x000D, j);	/* to 4096ms */
-			
-			ixj_WriteDSPCommand(0xCF96, j);	/* Set AGC Attack Threshold */
-			ixj_WriteDSPCommand(0x1200, j);	/* to 25% */
-			
-			ixj_WriteDSPCommand(0xCF97, j);	/* Set AGC Enable */
-			ixj_WriteDSPCommand(0x0001, j);	/* to on */
-			
-			break;
-
-		case AEC_AUTO:
-			ixj_WriteDSPCommand(0x0002, j);	/* Attenuation scaling factor of 2 */
-
-			ixj_WriteDSPCommand(0xE011, j);
-			ixj_WriteDSPCommand(0x0100, j);	/* Higher Threshold Floor */
-
-			ixj_WriteDSPCommand(0xE012, j);	/* Set Train and Lock */
-
-			if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
-				ixj_WriteDSPCommand(0x0224, j);
-			else
-				ixj_WriteDSPCommand(0x1224, j);
-
-			ixj_WriteDSPCommand(0xE014, j);
-			ixj_WriteDSPCommand(0x0003, j);	/* Lock threshold at 3dB */
-
-			ixj_WriteDSPCommand(0xE338, j);	/* Set Echo Suppresser Attenuation to 0dB */
-
-			break;
-		}
-	}
-}
-
-static void aec_stop(IXJ *j)
-{
-	j->aec_level = AEC_OFF;
-	if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
-		ixj_WriteDSPCommand(0xE022, j);	/* Move AEC filter buffer back */
-
-		ixj_WriteDSPCommand(0x0700, j);
-	}
-	if (j->play_mode != -1 && j->rec_mode != -1)
-	{
-		ixj_WriteDSPCommand(0xB002, j);	/* AEC Stop */
-	}
-}
-
-static int set_play_codec(IXJ *j, int rate)
-{
-	int retval = 0;
-
-	j->play_codec = rate;
-
-	switch (rate) {
-	case G723_63:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->play_frame_size = 12;
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G723_53:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->play_frame_size = 10;
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case TS85:
-		if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
-			j->play_frame_size = 16;
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case TS48:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->play_frame_size = 9;
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case TS41:
-		if (j->ver.low != 0x12 || ixj_convert_loaded) {
-			j->play_frame_size = 8;
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G728:
-		if (j->dsp.low != 0x20) {
-			j->play_frame_size = 48;
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G729:
-		if (j->dsp.low != 0x20) {
-			if (!j->flags.g729_loaded) {
-				retval = 1;
-				break;
-			}
-			switch (j->baseframe.low) {
-			case 0xA0:
-				j->play_frame_size = 10;
-				break;
-			case 0x50:
-				j->play_frame_size = 5;
-				break;
-			default:
-				j->play_frame_size = 15;
-				break;
-			}
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case G729B:
-		if (j->dsp.low != 0x20) {
-			if (!j->flags.g729_loaded) {
-				retval = 1;
-				break;
-			}
-			switch (j->baseframe.low) {
-			case 0xA0:
-				j->play_frame_size = 12;
-				break;
-			case 0x50:
-				j->play_frame_size = 6;
-				break;
-			default:
-				j->play_frame_size = 18;
-				break;
-			}
-			j->play_mode = 0;
-		} else {
-			retval = 1;
-		}
-		break;
-	case ULAW:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->play_frame_size = 80;
-			break;
-		case 0x50:
-			j->play_frame_size = 40;
-			break;
-		default:
-			j->play_frame_size = 120;
-			break;
-		}
-		j->play_mode = 2;
-		break;
-	case ALAW:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->play_frame_size = 80;
-			break;
-		case 0x50:
-			j->play_frame_size = 40;
-			break;
-		default:
-			j->play_frame_size = 120;
-			break;
-		}
-		j->play_mode = 2;
-		break;
-	case LINEAR16:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->play_frame_size = 160;
-			break;
-		case 0x50:
-			j->play_frame_size = 80;
-			break;
-		default:
-			j->play_frame_size = 240;
-			break;
-		}
-		j->play_mode = 6;
-		break;
-	case LINEAR8:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->play_frame_size = 80;
-			break;
-		case 0x50:
-			j->play_frame_size = 40;
-			break;
-		default:
-			j->play_frame_size = 120;
-			break;
-		}
-		j->play_mode = 4;
-		break;
-	case WSS:
-		switch (j->baseframe.low) {
-		case 0xA0:
-			j->play_frame_size = 80;
-			break;
-		case 0x50:
-			j->play_frame_size = 40;
-			break;
-		default:
-			j->play_frame_size = 120;
-			break;
-		}
-		j->play_mode = 5;
-		break;
-	default:
-		kfree(j->write_buffer);
-		j->play_frame_size = 0;
-		j->play_mode = -1;
-		j->write_buffer = NULL;
-		j->write_buffer_size = 0;
-		retval = 1;
-		break;
-	}
-	return retval;
-}
-
-static int ixj_play_start(IXJ *j)
-{
-	unsigned short cmd = 0x0000;
-
-	if (j->write_buffer) {
-		ixj_play_stop(j);
-	}
-
-	if(ixjdebug & 0x0002)
-		printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
-
-	j->flags.playing = 1;
-	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
-
-	j->flags.play_first_frame = 1;
-	j->drybuffer = 0;
-
-	if (!j->play_mode) {
-		switch (j->play_codec) {
-		case G723_63:
-			cmd = 0x5231;
-			break;
-		case G723_53:
-			cmd = 0x5232;
-			break;
-		case TS85:
-			cmd = 0x5230;	/* TrueSpeech 8.5 */
-
-			break;
-		case TS48:
-			cmd = 0x5233;	/* TrueSpeech 4.8 */
-
-			break;
-		case TS41:
-			cmd = 0x5234;	/* TrueSpeech 4.1 */
-
-			break;
-		case G728:
-			cmd = 0x5235;
-			break;
-		case G729:
-		case G729B:
-			cmd = 0x5236;
-			break;
-		default:
-			return 1;
-		}
-		if (ixj_WriteDSPCommand(cmd, j))
-			return -1;
-	}
-	j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
-	if (!j->write_buffer) {
-		printk("Write buffer allocation for ixj board %d failed!\n", j->board);
-		return -ENOMEM;
-	}
-/*	j->write_buffers_empty = 2; */
-	j->write_buffers_empty = 1; 
-	j->write_buffer_size = j->play_frame_size * 2;
-	j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
-	j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
-
-	if (ixj_WriteDSPCommand(0x5202, j))		/* Set Poll sync mode */
-
-		return -1;
-
-	switch (j->play_mode) {
-	case 0:
-		cmd = 0x2C03;
-		break;
-	case 2:
-		if (j->ver.low == 0x12) {
-			cmd = 0x2C23;
-		} else {
-			cmd = 0x2C21;
-		}
-		break;
-	case 4:
-		if (j->ver.low == 0x12) {
-			cmd = 0x2C43;
-		} else {
-			cmd = 0x2C41;
-		}
-		break;
-	case 5:
-		if (j->ver.low == 0x12) {
-			cmd = 0x2C53;
-		} else {
-			cmd = 0x2C51;
-		}
-		break;
-	case 6:
-		if (j->ver.low == 0x12) {
-			cmd = 0x2C63;
-		} else {
-			cmd = 0x2C61;
-		}
-		break;
-	}
-	if (ixj_WriteDSPCommand(cmd, j))
-		return -1;
-
-	if (ixj_WriteDSPCommand(0x2000, j))		/* Playback C2 */
-		return -1;
-
-	if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))	/* Playback C3 */
-		return -1;
-
-	if (j->flags.recording) {
-		ixj_aec_start(j, j->aec_level);
-	}
-
-	return 0;
-}
-
-static void ixj_play_stop(IXJ *j)
-{
-	if (ixjdebug & 0x0002)
-		printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
-
-	kfree(j->write_buffer);
-	j->write_buffer = NULL;
-	j->write_buffer_size = 0;
-	if (j->play_mode > -1) {
-		ixj_WriteDSPCommand(0x5221, j);	/* Stop playback and flush buffers.  8022 reference page 9-40 */
-
-		j->play_mode = -1;
-	}
-	j->flags.playing = 0;
-}
-
-static inline int get_play_level(IXJ *j)
-{
-	int retval;
-
-	ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */
-	return j->ssr.high << 8 | j->ssr.low;
-	retval = j->ssr.high << 8 | j->ssr.low;
-	retval = (retval * 256) / 240;
-	return retval;
-}
-
-static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
-{
-	unsigned int mask = 0;
-
-	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
-	poll_wait(file_p, &(j->poll_q), wait);
-	if (j->read_buffer_ready > 0)
-		mask |= POLLIN | POLLRDNORM;	/* readable */
-	if (j->write_buffers_empty > 0)
-		mask |= POLLOUT | POLLWRNORM;	/* writable */
-	if (j->ex.bytes)
-		mask |= POLLPRI;
-	return mask;
-}
-
-static int ixj_play_tone(IXJ *j, char tone)
-{
-	if (!j->tone_state) {
-		if(ixjdebug & 0x0002) {
-			printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies);
-		}
-		if (j->dsp.low == 0x20) {
-			idle(j);
-		}
-		j->tone_start_jif = jiffies;
-
-		j->tone_state = 1;
-	}
-
-	j->tone_index = tone;
-	if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
-		return -1;
-
-	return 0;
-}
-
-static int ixj_set_tone_on(unsigned short arg, IXJ *j)
-{
-	j->tone_on_time = arg;
-
-	if (ixj_WriteDSPCommand(0x6E04, j))		/* Set Tone On Period */
-
-		return -1;
-
-	if (ixj_WriteDSPCommand(arg, j))
-		return -1;
-
-	return 0;
-}
-
-static int SCI_WaitHighSCI(IXJ *j)
-{
-	int cnt;
-
-	j->pld_scrr.byte = inb_p(j->XILINXbase);
-	if (!j->pld_scrr.bits.sci) {
-		for (cnt = 0; cnt < 10; cnt++) {
-			udelay(32);
-			j->pld_scrr.byte = inb_p(j->XILINXbase);
-
-			if ((j->pld_scrr.bits.sci))
-				return 1;
-		}
-		if (ixjdebug & 0x0001)
-			printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte);
-		return 0;
-	} else
-		return 1;
-}
-
-static int SCI_WaitLowSCI(IXJ *j)
-{
-	int cnt;
-
-	j->pld_scrr.byte = inb_p(j->XILINXbase);
-	if (j->pld_scrr.bits.sci) {
-		for (cnt = 0; cnt < 10; cnt++) {
-			udelay(32);
-			j->pld_scrr.byte = inb_p(j->XILINXbase);
-
-			if (!(j->pld_scrr.bits.sci))
-				return 1;
-		}
-		if (ixjdebug & 0x0001)
-			printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte);
-		return 0;
-	} else
-		return 1;
-}
-
-static int SCI_Control(IXJ *j, int control)
-{
-	switch (control) {
-	case SCI_End:
-		j->pld_scrw.bits.c0 = 0;	/* Set PLD Serial control interface */
-
-		j->pld_scrw.bits.c1 = 0;	/* to no selection */
-
-		break;
-	case SCI_Enable_DAA:
-		j->pld_scrw.bits.c0 = 1;	/* Set PLD Serial control interface */
-
-		j->pld_scrw.bits.c1 = 0;	/* to write to DAA */
-
-		break;
-	case SCI_Enable_Mixer:
-		j->pld_scrw.bits.c0 = 0;	/* Set PLD Serial control interface */
-
-		j->pld_scrw.bits.c1 = 1;	/* to write to mixer */
-
-		break;
-	case SCI_Enable_EEPROM:
-		j->pld_scrw.bits.c0 = 1;	/* Set PLD Serial control interface */
-
-		j->pld_scrw.bits.c1 = 1;	/* to write to EEPROM */
-
-		break;
-	default:
-		return 0;
-		break;
-	}
-	outb_p(j->pld_scrw.byte, j->XILINXbase);
-
-	switch (control) {
-	case SCI_End:
-		return 1;
-		break;
-	case SCI_Enable_DAA:
-	case SCI_Enable_Mixer:
-	case SCI_Enable_EEPROM:
-		if (!SCI_WaitHighSCI(j))
-			return 0;
-		break;
-	default:
-		return 0;
-		break;
-	}
-	return 1;
-}
-
-static int SCI_Prepare(IXJ *j)
-{
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	return 1;
-}
-
-static int ixj_get_mixer(long val, IXJ *j)
-{
-	int reg = (val & 0x1F00) >> 8;
-        return j->mix.vol[reg];
-}
-
-static int ixj_mixer(long val, IXJ *j)
-{
-	BYTES bytes;
-
-	bytes.high = (val & 0x1F00) >> 8;
-	bytes.low = val & 0x00FF;
-
-        /* save mixer value so we can get back later on */
-        j->mix.vol[bytes.high] = bytes.low;
-
-	outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03);	/* Load Mixer Address */
-
-	outb_p(bytes.low, j->XILINXbase + 0x02);	/* Load Mixer Data */
-
-	SCI_Control(j, SCI_Enable_Mixer);
-
-	SCI_Control(j, SCI_End);
-
-	return 0;
-}
-
-static int daa_load(BYTES * p_bytes, IXJ *j)
-{
-	outb_p(p_bytes->high, j->XILINXbase + 0x03);
-	outb_p(p_bytes->low, j->XILINXbase + 0x02);
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-	else
-		return 1;
-}
-
-static int ixj_daa_cr4(IXJ *j, char reg)
-{
-	BYTES bytes;
-
-	switch (j->daa_mode) {
-	case SOP_PU_SLEEP:
-		bytes.high = 0x14;
-		break;
-	case SOP_PU_RINGING:
-		bytes.high = 0x54;
-		break;
-	case SOP_PU_CONVERSATION:
-		bytes.high = 0x94;
-		break;
-	case SOP_PU_PULSEDIALING:
-		bytes.high = 0xD4;
-		break;
-	}
-
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg;
-
-	switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) {
-	case 0:
-		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0;
-		break;
-	case 1:
-		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2;
-		break;
-	case 2:
-		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1;
-		break;
-	case 3:
-		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3;
-		break;
-	}
-
-	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
-
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	return 1;
-}
-
-static char daa_int_read(IXJ *j)
-{
-	BYTES bytes;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	bytes.high = 0x38;
-	bytes.low = 0x00;
-	outb_p(bytes.high, j->XILINXbase + 0x03);
-	outb_p(bytes.low, j->XILINXbase + 0x02);
-
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-
-	bytes.high = inb_p(j->XILINXbase + 0x03);
-	bytes.low = inb_p(j->XILINXbase + 0x02);
-	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug & 0x0001)
-			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
-		return 0;
-	}
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	bytes.high = inb_p(j->XILINXbase + 0x03);
-	bytes.low = inb_p(j->XILINXbase + 0x02);
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
-
-	return 1;
-}
-
-static char daa_CR_read(IXJ *j, int cr)
-{
-	IXJ_WORD wdata;
-	BYTES bytes;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	switch (j->daa_mode) {
-	case SOP_PU_SLEEP:
-		bytes.high = 0x30 + cr;
-		break;
-	case SOP_PU_RINGING:
-		bytes.high = 0x70 + cr;
-		break;
-	case SOP_PU_CONVERSATION:
-		bytes.high = 0xB0 + cr;
-		break;
-	case SOP_PU_PULSEDIALING:
-	default:
-		bytes.high = 0xF0 + cr;
-		break;
-	}
-
-	bytes.low = 0x00;
-
-	outb_p(bytes.high, j->XILINXbase + 0x03);
-	outb_p(bytes.low, j->XILINXbase + 0x02);
-
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-
-	bytes.high = inb_p(j->XILINXbase + 0x03);
-	bytes.low = inb_p(j->XILINXbase + 0x02);
-	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug & 0x0001)
-			printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
-		return 0;
-	}
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	wdata.word = inw_p(j->XILINXbase + 0x02);
-
-	switch(cr){
-		case 5:
-			j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high;
-			break;
-		case 4:
-			j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high;
-			break;
-		case 3:
-			j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high;
-			break;
-		case 2:
-			j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high;
-			break;
-		case 1:
-			j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high;
-			break;
-		case 0:
-			j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high;
-			break;
-		default:
-			return 0;
-	}
-	return 1;
-}
-
-static int ixj_daa_cid_reset(IXJ *j)
-{
-	int i;
-	BYTES bytes;
-
-	if (ixjdebug & 0x0002)
-		printk("DAA Clearing CID ram\n");
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	bytes.high = 0x58;
-	bytes.low = 0x00;
-	outb_p(bytes.high, j->XILINXbase + 0x03);
-	outb_p(bytes.low, j->XILINXbase + 0x02);
-
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-
-	if (!SCI_WaitHighSCI(j))
-		return 0;
-
-	for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) {
-		bytes.high = bytes.low = 0x00;
-		outb_p(bytes.high, j->XILINXbase + 0x03);
-
-		if (i < ALISDAA_CALLERID_SIZE - 1)
-			outb_p(bytes.low, j->XILINXbase + 0x02);
-
-		if (!SCI_Control(j, SCI_Enable_DAA))
-			return 0;
-
-		if (!SCI_WaitHighSCI(j))
-			return 0;
-
-	}
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	if (ixjdebug & 0x0002)
-		printk("DAA CID ram cleared\n");
-
-	return 1;
-}
-
-static int ixj_daa_cid_read(IXJ *j)
-{
-	int i;
-	BYTES bytes;
-	char CID[ALISDAA_CALLERID_SIZE];
-	bool mContinue;
-	char *pIn, *pOut;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	bytes.high = 0x78;
-	bytes.low = 0x00;
-	outb_p(bytes.high, j->XILINXbase + 0x03);
-	outb_p(bytes.low, j->XILINXbase + 0x02);
-
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-
-	if (!SCI_WaitHighSCI(j))
-		return 0;
-
-	bytes.high = inb_p(j->XILINXbase + 0x03);
-	bytes.low = inb_p(j->XILINXbase + 0x02);
-	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug & 0x0001)
-			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
-		return 0;
-	}
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) {
-		bytes.high = bytes.low = 0x00;
-		outb_p(bytes.high, j->XILINXbase + 0x03);
-		outb_p(bytes.low, j->XILINXbase + 0x02);
-
-		if (!SCI_Control(j, SCI_Enable_DAA))
-			return 0;
-
-		if (!SCI_WaitHighSCI(j))
-			return 0;
-
-		CID[i + 0] = inb_p(j->XILINXbase + 0x03);
-		CID[i + 1] = inb_p(j->XILINXbase + 0x02);
-	}
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	pIn = CID;
-	pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
-	mContinue = true;
-	while (mContinue) {
-		if ((pIn[1] & 0x03) == 0x01) {
-			pOut[0] = pIn[0];
-		}
-		if ((pIn[2] & 0x0c) == 0x04) {
-			pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2);
-		}
-		if ((pIn[3] & 0x30) == 0x10) {
-			pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4);
-		}
-		if ((pIn[4] & 0xc0) == 0x40) {
-			pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6);
-		} else {
-			mContinue = false;
-		}
-		pIn += 5, pOut += 4;
-	}
-	memset(&j->cid, 0, sizeof(PHONE_CID));
-	pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
-	pOut += 4;
-	strncpy(j->cid.month, pOut, 2);
-	pOut += 2;
-	strncpy(j->cid.day, pOut, 2);
-	pOut += 2;
-	strncpy(j->cid.hour, pOut, 2);
-	pOut += 2;
-	strncpy(j->cid.min, pOut, 2);
-	pOut += 3;
-	j->cid.numlen = *pOut;
-	pOut += 1;
-	strncpy(j->cid.number, pOut, j->cid.numlen);
-	pOut += j->cid.numlen + 1;
-	j->cid.namelen = *pOut;
-	pOut += 1;
-	strncpy(j->cid.name, pOut, j->cid.namelen);
-
-	ixj_daa_cid_reset(j);
-	return 1;
-}
-
-static char daa_get_version(IXJ *j)
-{
-	BYTES bytes;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	bytes.high = 0x35;
-	bytes.low = 0x00;
-	outb_p(bytes.high, j->XILINXbase + 0x03);
-	outb_p(bytes.low, j->XILINXbase + 0x02);
-
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-
-	bytes.high = inb_p(j->XILINXbase + 0x03);
-	bytes.low = inb_p(j->XILINXbase + 0x02);
-	if (bytes.low != ALISDAA_ID_BYTE) {
-		if (ixjdebug & 0x0001)
-			printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
-		return 0;
-	}
-	if (!SCI_Control(j, SCI_Enable_DAA))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	bytes.high = inb_p(j->XILINXbase + 0x03);
-	bytes.low = inb_p(j->XILINXbase + 0x02);
-	if (ixjdebug & 0x0002)
-		printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low);
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
-	return bytes.high;
-}
-
-static int daa_set_mode(IXJ *j, int mode)
-{
-	/* NOTE:
-	      The DAA *MUST* be in the conversation mode if the
-	      PSTN line is to be seized (PSTN line off-hook).
-	      Taking the PSTN line off-hook while the DAA is in
-	      a mode other than conversation mode will cause a
-	      hardware failure of the ALIS-A part.
-
-	   NOTE:
-	      The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
-	      if the PSTN line is on-hook.  Failure to have the PSTN line
-	      in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
-	      ALIS-A part.
-	*/
-
-	BYTES bytes;
-
-	j->flags.pstn_rmr = 0;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	switch (mode) {
-	case SOP_PU_RESET:
-		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
-		j->pld_slicw.bits.rly2 = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		bytes.high = 0x10;
-		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, j);
-		if (!SCI_Prepare(j))
-			return 0;
-
-		j->daa_mode = SOP_PU_SLEEP;
-		break;
-	case SOP_PU_SLEEP:
-		if(j->daa_mode == SOP_PU_SLEEP)
-		{
-			break;
-		}
-		if (ixjdebug & 0x0008)
-			printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies);
-/*		if(j->daa_mode == SOP_PU_CONVERSATION) */
-		{
-			j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-			outb_p(j->pld_scrw.byte, j->XILINXbase);
-			j->pld_slicw.bits.rly2 = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-			bytes.high = 0x10;
-			bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-			daa_load(&bytes, j);
-			if (!SCI_Prepare(j))
-				return 0;
-		}
-		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
-		j->pld_slicw.bits.rly2 = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		bytes.high = 0x10;
-		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, j);
-		if (!SCI_Prepare(j))
-			return 0;
-
-		j->daa_mode = SOP_PU_SLEEP;
-		j->flags.pstn_ringing = 0;
-		j->ex.bits.pstn_ring = 0;
-		j->pstn_sleeptil = jiffies + (hertz / 4);
-		wake_up_interruptible(&j->read_q);      /* Wake any blocked readers */
-		wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
-		wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
- 		break;
-	case SOP_PU_RINGING:
-		if (ixjdebug & 0x0008)
-			printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies);
-		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
-		j->pld_slicw.bits.rly2 = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		bytes.high = 0x50;
-		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, j);
-		if (!SCI_Prepare(j))
-			return 0;
-		j->daa_mode = SOP_PU_RINGING;
-		break;
-	case SOP_PU_CONVERSATION:
-		if (ixjdebug & 0x0008)
-			printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies);
-		bytes.high = 0x90;
-		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, j);
-		if (!SCI_Prepare(j))
-			return 0;
-		j->pld_slicw.bits.rly2 = 1;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		j->pld_scrw.bits.daafsyncen = 1;	/* Turn on DAA Frame Sync */
-
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
-		j->daa_mode = SOP_PU_CONVERSATION;
-		j->flags.pstn_ringing = 0;
-		j->ex.bits.pstn_ring = 0;
-		j->pstn_sleeptil = jiffies;
-		j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0;
-		break;
-	case SOP_PU_PULSEDIALING:
-		if (ixjdebug & 0x0008)
-			printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies);
-		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
-		j->pld_slicw.bits.rly2 = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		bytes.high = 0xD0;
-		bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-		daa_load(&bytes, j);
-		if (!SCI_Prepare(j))
-			return 0;
-		j->daa_mode = SOP_PU_PULSEDIALING;
-		break;
-	default:
-		break;
-	}
-	return 1;
-}
-
-static int ixj_daa_write(IXJ *j)
-{
-	BYTES bytes;
-
-	j->flags.pstncheck = 1;
-
-	daa_set_mode(j, SOP_PU_SLEEP);
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	outb_p(j->pld_scrw.byte, j->XILINXbase);
-
-	bytes.high = 0x14;
-	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg;
-	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg;
-	bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	bytes.high = 0x1F;
-	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg;
-	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg;
-	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg;
-	bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg;
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Prepare(j))
-		return 0;
-
-	bytes.high = 0x00;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x01;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x02;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x03;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x04;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x05;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x06;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x07;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x08;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x09;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x0A;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x0B;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x0C;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x0D;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x0E;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-	if (!SCI_WaitLowSCI(j))
-		return 0;
-
-	bytes.high = 0x0F;
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2];
-	bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1];
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0];
-	bytes.low = 0x00;
-	if (!daa_load(&bytes, j))
-		return 0;
-
-	udelay(32);
-	j->pld_scrr.byte = inb_p(j->XILINXbase);
-	if (!SCI_Control(j, SCI_End))
-		return 0;
-
-	outb_p(j->pld_scrw.byte, j->XILINXbase);
-
-	if (ixjdebug & 0x0002)
-		printk("DAA Coefficients Loaded\n");
-
-	j->flags.pstncheck = 0;
-	return 1;
-}
-
-static int ixj_set_tone_off(unsigned short arg, IXJ *j)
-{
-	j->tone_off_time = arg;
-	if (ixj_WriteDSPCommand(0x6E05, j))		/* Set Tone Off Period */
-
-		return -1;
-	if (ixj_WriteDSPCommand(arg, j))
-		return -1;
-	return 0;
-}
-
-static int ixj_get_tone_on(IXJ *j)
-{
-	if (ixj_WriteDSPCommand(0x6E06, j))		/* Get Tone On Period */
-
-		return -1;
-	return 0;
-}
-
-static int ixj_get_tone_off(IXJ *j)
-{
-	if (ixj_WriteDSPCommand(0x6E07, j))		/* Get Tone Off Period */
-
-		return -1;
-	return 0;
-}
-
-static void ixj_busytone(IXJ *j)
-{
-	j->flags.ringback = 0;
-	j->flags.dialtone = 0;
-	j->flags.busytone = 1;
-	ixj_set_tone_on(0x07D0, j);
-	ixj_set_tone_off(0x07D0, j);
-	ixj_play_tone(j, 27);
-}
-
-static void ixj_dialtone(IXJ *j)
-{
-	j->flags.ringback = 0;
-	j->flags.dialtone = 1;
-	j->flags.busytone = 0;
-	if (j->dsp.low == 0x20) {
-		return;
-	} else {
-		ixj_set_tone_on(0xFFFF, j);
-		ixj_set_tone_off(0x0000, j);
-		ixj_play_tone(j, 25);
-	}
-}
-
-static void ixj_cpt_stop(IXJ *j)
-{
-	if(j->tone_state || j->tone_cadence_state)
-	{
-		j->flags.dialtone = 0;
-		j->flags.busytone = 0;
-		j->flags.ringback = 0;
-		ixj_set_tone_on(0x0001, j);
-		ixj_set_tone_off(0x0000, j);
-		ixj_play_tone(j, 0);
-		j->tone_state = j->tone_cadence_state = 0;
-		if (j->cadence_t) {
-			kfree(j->cadence_t->ce);
-			kfree(j->cadence_t);
-			j->cadence_t = NULL;
-		}
-	}
-	if (j->play_mode == -1 && j->rec_mode == -1)
-		idle(j);
-	if (j->play_mode != -1 && j->dsp.low == 0x20)
-		ixj_play_start(j);
-	if (j->rec_mode != -1 && j->dsp.low == 0x20)
-		ixj_record_start(j);
-}
-
-static void ixj_ringback(IXJ *j)
-{
-	j->flags.busytone = 0;
-	j->flags.dialtone = 0;
-	j->flags.ringback = 1;
-	ixj_set_tone_on(0x0FA0, j);
-	ixj_set_tone_off(0x2EE0, j);
-	ixj_play_tone(j, 26);
-}
-
-static void ixj_testram(IXJ *j)
-{
-	ixj_WriteDSPCommand(0x3001, j);	/* Test External SRAM */
-}
-
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp)
-{
-	ixj_cadence *lcp;
-	IXJ_CADENCE_ELEMENT __user *cep;
-	IXJ_CADENCE_ELEMENT *lcep;
-	IXJ_TONE ti;
-	int err;
-
-	lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL);
-	if (lcp == NULL)
-		return -ENOMEM;
-
-	err = -EFAULT;
-	if (copy_from_user(&lcp->elements_used,
-			   &cp->elements_used, sizeof(int)))
-		goto out;
-	if (copy_from_user(&lcp->termination,
-			   &cp->termination, sizeof(IXJ_CADENCE_TERM)))
-		goto out;
-	if (get_user(cep, &cp->ce))
-		goto out;
-
-	err = -EINVAL;
-	if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT))
-		goto out;
-
-	err = -ENOMEM;
-	lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
-	if (!lcep)
-		goto out;
-
-	err = -EFAULT;
-	if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
-		goto out1;
-
-	if (j->cadence_t) {
-		kfree(j->cadence_t->ce);
-		kfree(j->cadence_t);
-	}
-	lcp->ce = (void *) lcep;
-	j->cadence_t = lcp;
-	j->tone_cadence_state = 0;
-	ixj_set_tone_on(lcp->ce[0].tone_on_time, j);
-	ixj_set_tone_off(lcp->ce[0].tone_off_time, j);
-	if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
-		ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
-		ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
-		ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
-		ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
-		ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-		ixj_init_tone(j, &ti);
-	}
-	ixj_play_tone(j, lcp->ce[0].index);
-	return 1;
-out1:
-	kfree(lcep);
-out:
-	kfree(lcp);
-	return err;
-}
-
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp)
-{
-	IXJ_FILTER_CADENCE *lcp;
-	lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE));
-	if (IS_ERR(lcp)) {
-		if(ixjdebug & 0x0001) {
-			printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n");
-		}
-		return PTR_ERR(lcp);
-        }
-	if (lcp->filter > 5) {
-		if(ixjdebug & 0x0001) {
-			printk(KERN_INFO "Cadence out of range\n");
-		}
-		kfree(lcp);
-		return -1;
-	}
-	j->cadence_f[lcp->filter].state = 0;
-	j->cadence_f[lcp->filter].enable = lcp->enable;
-	j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter;
-	j->cadence_f[lcp->filter].on1 = lcp->on1;
-	j->cadence_f[lcp->filter].on1min = 0;
-	j->cadence_f[lcp->filter].on1max = 0;
-	j->cadence_f[lcp->filter].off1 = lcp->off1;
-	j->cadence_f[lcp->filter].off1min = 0;
-	j->cadence_f[lcp->filter].off1max = 0;
-	j->cadence_f[lcp->filter].on2 = lcp->on2;
-	j->cadence_f[lcp->filter].on2min = 0;
-	j->cadence_f[lcp->filter].on2max = 0;
-	j->cadence_f[lcp->filter].off2 = lcp->off2;
-	j->cadence_f[lcp->filter].off2min = 0;
-	j->cadence_f[lcp->filter].off2max = 0;
-	j->cadence_f[lcp->filter].on3 = lcp->on3;
-	j->cadence_f[lcp->filter].on3min = 0;
-	j->cadence_f[lcp->filter].on3max = 0;
-	j->cadence_f[lcp->filter].off3 = lcp->off3;
-	j->cadence_f[lcp->filter].off3min = 0;
-	j->cadence_f[lcp->filter].off3max = 0;
-	if(ixjdebug & 0x0002) {
-		printk(KERN_INFO "Cadence %d loaded\n", lcp->filter);
-	}
-	kfree(lcp);
-	return 0;
-}
-
-static void add_caps(IXJ *j)
-{
-	j->caps = 0;
-	j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
-	strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
-	j->caplist[j->caps].captype = vendor;
-	j->caplist[j->caps].handle = j->caps++;
-	j->caplist[j->caps].captype = device;
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK");
-		break;
-	case QTI_LINEJACK:
-		strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK");
-		break;
-	case QTI_PHONEJACK_LITE:
-		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite");
-		break;
-	case QTI_PHONEJACK_PCI:
-		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI");
-		break;
-	case QTI_PHONECARD:
-		strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD");
-		break;
-	}
-	j->caplist[j->caps].cap = j->cardtype;
-	j->caplist[j->caps].handle = j->caps++;
-	strcpy(j->caplist[j->caps].desc, "POTS");
-	j->caplist[j->caps].captype = port;
-	j->caplist[j->caps].cap = pots;
-	j->caplist[j->caps].handle = j->caps++;
-
- 	/* add devices that can do speaker/mic */
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-	case QTI_LINEJACK:
-	case QTI_PHONEJACK_PCI:
-	case QTI_PHONECARD:
-		strcpy(j->caplist[j->caps].desc, "SPEAKER");
-		j->caplist[j->caps].captype = port;
-		j->caplist[j->caps].cap = speaker;
-		j->caplist[j->caps].handle = j->caps++;
-        default:
-     		break;
-	}
-
- 	/* add devices that can do handset */
-	switch (j->cardtype) {
-	case QTI_PHONEJACK:
-		strcpy(j->caplist[j->caps].desc, "HANDSET");
-		j->caplist[j->caps].captype = port;
-		j->caplist[j->caps].cap = handset;
-		j->caplist[j->caps].handle = j->caps++;
-		break;
-        default:
-     		break;
-	}
-
- 	/* add devices that can do PSTN */
-	switch (j->cardtype) {
-	case QTI_LINEJACK:
-		strcpy(j->caplist[j->caps].desc, "PSTN");
-		j->caplist[j->caps].captype = port;
-		j->caplist[j->caps].cap = pstn;
-		j->caplist[j->caps].handle = j->caps++;
-		break;
-        default:
-     		break;
-	}
-
-	/* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */
-	strcpy(j->caplist[j->caps].desc, "ULAW");
-	j->caplist[j->caps].captype = codec;
-	j->caplist[j->caps].cap = ULAW;
-	j->caplist[j->caps].handle = j->caps++;
-
-	strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit");
-	j->caplist[j->caps].captype = codec;
-	j->caplist[j->caps].cap = LINEAR16;
-	j->caplist[j->caps].handle = j->caps++;
-
-	strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit");
-	j->caplist[j->caps].captype = codec;
-	j->caplist[j->caps].cap = LINEAR8;
-	j->caplist[j->caps].handle = j->caps++;
-
-	strcpy(j->caplist[j->caps].desc, "Windows Sound System");
-	j->caplist[j->caps].captype = codec;
-	j->caplist[j->caps].cap = WSS;
-	j->caplist[j->caps].handle = j->caps++;
-
-	/* software ALAW codec, made from ULAW */
-	strcpy(j->caplist[j->caps].desc, "ALAW");
-	j->caplist[j->caps].captype = codec;
-	j->caplist[j->caps].cap = ALAW;
-	j->caplist[j->caps].handle = j->caps++;
-
-	/* version 12 of the 8020 does the following codecs in a broken way */
-	if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
-		strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = G723_63;
-		j->caplist[j->caps].handle = j->caps++;
-
-		strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = G723_53;
-		j->caplist[j->caps].handle = j->caps++;
-
-		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = TS48;
-		j->caplist[j->caps].handle = j->caps++;
-
-		strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = TS41;
-		j->caplist[j->caps].handle = j->caps++;
-	}
-
-	/* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
-	if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
-		strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = TS85;
-		j->caplist[j->caps].handle = j->caps++;
-	}
-
-	/* 8021 chips can do G728 */
-	if (j->dsp.low == 0x21) {
-		strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = G728;
-		j->caplist[j->caps].handle = j->caps++;
-	}
-
-	/* 8021/8022 chips can do G729 if loaded */
-	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
-		strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = G729;
-		j->caplist[j->caps].handle = j->caps++;
-	}
-	if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
-		strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
-		j->caplist[j->caps].captype = codec;
-		j->caplist[j->caps].cap = G729B;
-		j->caplist[j->caps].handle = j->caps++;
-	}
-}
-
-static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
-{
-	int cnt;
-	int retval = 0;
-	for (cnt = 0; cnt < j->caps; cnt++) {
-		if (pcreq->captype == j->caplist[cnt].captype
-		    && pcreq->cap == j->caplist[cnt].cap) {
-			retval = 1;
-			break;
-		}
-	}
-	return retval;
-}
-
-static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
-{
-	IXJ_TONE ti;
-	IXJ_FILTER jf;
-	IXJ_FILTER_RAW jfr;
-	void __user *argp = (void __user *)arg;
-	struct inode *inode = file_p->f_path.dentry->d_inode;
-	unsigned int minor = iminor(inode);
-	unsigned int raise, mant;
-	int board = NUM(inode);
-
-	IXJ *j = get_ixj(NUM(inode));
-
-	int retval = 0;
-
-	/*
-	 *    Set up locks to ensure that only one process is talking to the DSP at a time.
-	 *    This is necessary to keep the DSP from locking up.
-	 */
-	while(test_and_set_bit(board, (void *)&j->busyflags) != 0)
-		schedule_timeout_interruptible(1);
-	if (ixjdebug & 0x0040)
-		printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
-	if (minor >= IXJMAX) {
-		clear_bit(board, &j->busyflags);
-		return -ENODEV;
-	}
-	/*
-	 *    Check ioctls only root can use.
-	 */
-	if (!capable(CAP_SYS_ADMIN)) {
-		switch (cmd) {
-		case IXJCTL_TESTRAM:
-		case IXJCTL_HZ:
-			retval = -EPERM;
-		}
-	}
-	switch (cmd) {
-	case IXJCTL_TESTRAM:
-		ixj_testram(j);
-		retval = (j->ssr.high << 8) + j->ssr.low;
-		break;
-	case IXJCTL_CARDTYPE:
-		retval = j->cardtype;
-		break;
-	case IXJCTL_SERIAL:
-		retval = j->serial;
-		break;
-	case IXJCTL_VERSION:
-		{
-			char arg_str[100];
-			snprintf(arg_str, sizeof(arg_str),
-				"\nDriver version %i.%i.%i", IXJ_VER_MAJOR,
-				IXJ_VER_MINOR, IXJ_BLD_VER);
-			if (copy_to_user(argp, arg_str, strlen(arg_str)))
-				retval = -EFAULT;
-		}
-		break;
-	case PHONE_RING_CADENCE:
-		j->ring_cadence = arg;
-		break;
-	case IXJCTL_CIDCW:
-		if(arg) {
-			if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
-				retval = -EFAULT;
-				break;
-			}
-		} else {
-			memset(&j->cid_send, 0, sizeof(PHONE_CID));
-		}
-		ixj_write_cidcw(j);
-		break;
-        /* Binary compatbility */
-        case OLD_PHONE_RING_START:
-                arg = 0;
-                /* Fall through */
- 	case PHONE_RING_START:
-		if(arg) {
-			if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
-				retval = -EFAULT;
-				break;
-			}
-			ixj_write_cid(j);
-		} else {
-			memset(&j->cid_send, 0, sizeof(PHONE_CID));
-		}
-		ixj_ring_start(j);
-		break;
-	case PHONE_RING_STOP:
-		j->flags.cringing = 0;
-		if(j->cadence_f[5].enable) {
-			j->cadence_f[5].state = 0;
-		}
-		ixj_ring_off(j);
-		break;
-	case PHONE_RING:
-		retval = ixj_ring(j);
-		break;
-	case PHONE_EXCEPTION:
-		retval = j->ex.bytes;
-		if(j->ex.bits.flash) {
-			j->flash_end = 0;
-			j->ex.bits.flash = 0;
-		}
-		j->ex.bits.pstn_ring = 0;
-		j->ex.bits.caller_id = 0;
-		j->ex.bits.pstn_wink = 0;
-		j->ex.bits.f0 = 0;
-		j->ex.bits.f1 = 0;
-		j->ex.bits.f2 = 0;
-		j->ex.bits.f3 = 0;
-		j->ex.bits.fc0 = 0;
-		j->ex.bits.fc1 = 0;
-		j->ex.bits.fc2 = 0;
-		j->ex.bits.fc3 = 0;
-		j->ex.bits.reserved = 0;
-		break;
-	case PHONE_HOOKSTATE:
-		j->ex.bits.hookstate = 0;
-		retval = j->hookstate;  //j->r_hook;
-		break;
-	case IXJCTL_SET_LED:
-		LED_SetState(arg, j);
-		break;
-	case PHONE_FRAME:
-		retval = set_base_frame(j, arg);
-		break;
-	case PHONE_REC_CODEC:
-		retval = set_rec_codec(j, arg);
-		break;
-	case PHONE_VAD:
-		ixj_vad(j, arg);
-		break;
-	case PHONE_REC_START:
-		ixj_record_start(j);
-		break;
-	case PHONE_REC_STOP:
-		ixj_record_stop(j);
-		break;
-	case PHONE_REC_DEPTH:
-		set_rec_depth(j, arg);
-		break;
-	case PHONE_REC_VOLUME:
-		if(arg == -1) {
-			retval = get_rec_volume(j);
-		}
-		else {
-			set_rec_volume(j, arg);
-			retval = arg;
-		}
-		break;
-	case PHONE_REC_VOLUME_LINEAR:
-		if(arg == -1) {
-			retval = get_rec_volume_linear(j);
-		}
-		else {
-			set_rec_volume_linear(j, arg);
-			retval = arg;
-		}
-		break;
-	case IXJCTL_DTMF_PRESCALE:
-		if(arg == -1) {
-			retval = get_dtmf_prescale(j);
-		}
-		else {
-			set_dtmf_prescale(j, arg);
-			retval = arg;
-		}
-		break;
-	case PHONE_REC_LEVEL:
-		retval = get_rec_level(j);
-		break;
-	case IXJCTL_SC_RXG:
-		retval = ixj_siadc(j, arg);
-		break;
-	case IXJCTL_SC_TXG:
-		retval = ixj_sidac(j, arg);
-		break;
-	case IXJCTL_AEC_START:
-		ixj_aec_start(j, arg);
-		break;
-	case IXJCTL_AEC_STOP:
-		aec_stop(j);
-		break;
-	case IXJCTL_AEC_GET_LEVEL:
-		retval = j->aec_level;
-		break;
-	case PHONE_PLAY_CODEC:
-		retval = set_play_codec(j, arg);
-		break;
-	case PHONE_PLAY_START:
-		retval = ixj_play_start(j);
-		break;
-	case PHONE_PLAY_STOP:
-		ixj_play_stop(j);
-		break;
-	case PHONE_PLAY_DEPTH:
-		set_play_depth(j, arg);
-		break;
-	case PHONE_PLAY_VOLUME:
-		if(arg == -1) {
-			retval = get_play_volume(j);
-		}
-		else {
-			set_play_volume(j, arg);
-			retval = arg;
-		}
-		break;
-	case PHONE_PLAY_VOLUME_LINEAR:
-		if(arg == -1) {
-			retval = get_play_volume_linear(j);
-		}
-		else {
-			set_play_volume_linear(j, arg);
-			retval = arg;
-		}
-		break;
-	case PHONE_PLAY_LEVEL:
-		retval = get_play_level(j);
-		break;
-	case IXJCTL_DSP_TYPE:
-		retval = (j->dsp.high << 8) + j->dsp.low;
-		break;
-	case IXJCTL_DSP_VERSION:
-		retval = (j->ver.high << 8) + j->ver.low;
-		break;
-	case IXJCTL_HZ:
-		hertz = arg;
-		break;
-	case IXJCTL_RATE:
-		if (arg > hertz)
-			retval = -1;
-		else
-			samplerate = arg;
-		break;
-	case IXJCTL_DRYBUFFER_READ:
-		put_user(j->drybuffer, (unsigned long __user *) argp);
-		break;
-	case IXJCTL_DRYBUFFER_CLEAR:
-		j->drybuffer = 0;
-		break;
-	case IXJCTL_FRAMES_READ:
-		put_user(j->framesread, (unsigned long __user *) argp);
-		break;
-	case IXJCTL_FRAMES_WRITTEN:
-		put_user(j->frameswritten, (unsigned long __user *) argp);
-		break;
-	case IXJCTL_READ_WAIT:
-		put_user(j->read_wait, (unsigned long __user *) argp);
-		break;
-	case IXJCTL_WRITE_WAIT:
-		put_user(j->write_wait, (unsigned long __user *) argp);
-		break;
-	case PHONE_MAXRINGS:
-		j->maxrings = arg;
-		break;
-	case PHONE_SET_TONE_ON_TIME:
-		ixj_set_tone_on(arg, j);
-		break;
-	case PHONE_SET_TONE_OFF_TIME:
-		ixj_set_tone_off(arg, j);
-		break;
-	case PHONE_GET_TONE_ON_TIME:
-		if (ixj_get_tone_on(j)) {
-			retval = -1;
-		} else {
-			retval = (j->ssr.high << 8) + j->ssr.low;
-		}
-		break;
-	case PHONE_GET_TONE_OFF_TIME:
-		if (ixj_get_tone_off(j)) {
-			retval = -1;
-		} else {
-			retval = (j->ssr.high << 8) + j->ssr.low;
-		}
-		break;
-	case PHONE_PLAY_TONE:
-		if (!j->tone_state)
-			retval = ixj_play_tone(j, arg);
-		else
-			retval = -1;
-		break;
-	case PHONE_GET_TONE_STATE:
-		retval = j->tone_state;
-		break;
-	case PHONE_DTMF_READY:
-		retval = j->ex.bits.dtmf_ready;
-		break;
-	case PHONE_GET_DTMF:
-		if (ixj_hookstate(j)) {
-			if (j->dtmf_rp != j->dtmf_wp) {
-				retval = j->dtmfbuffer[j->dtmf_rp];
-				j->dtmf_rp++;
-				if (j->dtmf_rp == 79)
-					j->dtmf_rp = 0;
-				if (j->dtmf_rp == j->dtmf_wp) {
-					j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
-				}
-			}
-		}
-		break;
-	case PHONE_GET_DTMF_ASCII:
-		if (ixj_hookstate(j)) {
-			if (j->dtmf_rp != j->dtmf_wp) {
-				switch (j->dtmfbuffer[j->dtmf_rp]) {
-				case 10:
-					retval = 42;	/* '*'; */
-
-					break;
-				case 11:
-					retval = 48;	/*'0'; */
-
-					break;
-				case 12:
-					retval = 35;	/*'#'; */
-
-					break;
-				case 28:
-					retval = 65;	/*'A'; */
-
-					break;
-				case 29:
-					retval = 66;	/*'B'; */
-
-					break;
-				case 30:
-					retval = 67;	/*'C'; */
-
-					break;
-				case 31:
-					retval = 68;	/*'D'; */
-
-					break;
-				default:
-					retval = 48 + j->dtmfbuffer[j->dtmf_rp];
-					break;
-				}
-				j->dtmf_rp++;
-				if (j->dtmf_rp == 79)
-					j->dtmf_rp = 0;
-				if(j->dtmf_rp == j->dtmf_wp)
-				{
-					j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
-				}
-			}
-		}
-		break;
-	case PHONE_DTMF_OOB:
-		j->flags.dtmf_oob = arg;
-		break;
-	case PHONE_DIALTONE:
-		ixj_dialtone(j);
-		break;
-	case PHONE_BUSY:
-		ixj_busytone(j);
-		break;
-	case PHONE_RINGBACK:
-		ixj_ringback(j);
-		break;
-	case PHONE_WINK:
-		if(j->cardtype == QTI_PHONEJACK) 
-			retval = -1;
-		else 
-			retval = ixj_wink(j);
-		break;
-	case PHONE_CPT_STOP:
-		ixj_cpt_stop(j);
-		break;
-        case PHONE_QUERY_CODEC:
-        {
-                struct phone_codec_data pd;
-                int val;
-                int proto_size[] = {
-                        -1,
-                        12, 10, 16, 9, 8, 48, 5,
-                        40, 40, 80, 40, 40, 6
-                };
-                if(copy_from_user(&pd, argp, sizeof(pd))) {
-                        retval = -EFAULT;
-			break;
-		}
-                if(pd.type<1 || pd.type>13) {
-                        retval = -EPROTONOSUPPORT;
-			break;
-		}
-                if(pd.type<G729)
-                        val=proto_size[pd.type];
-                else switch(j->baseframe.low)
-                {
-                        case 0xA0:val=2*proto_size[pd.type];break;
-                        case 0x50:val=proto_size[pd.type];break;
-                        default:val=proto_size[pd.type]*3;break;
-                }
-                pd.buf_min=pd.buf_max=pd.buf_opt=val;
-                if(copy_to_user(argp, &pd, sizeof(pd)))
-                        retval = -EFAULT;
-        	break;
-        }
-	case IXJCTL_DSP_IDLE:
-		idle(j);
-		break;
-	case IXJCTL_MIXER:
-                if ((arg & 0xff) == 0xff)
-			retval = ixj_get_mixer(arg, j);
-                else
-			ixj_mixer(arg, j);
-		break;
-	case IXJCTL_DAA_COEFF_SET:
-		switch (arg) {
-		case DAA_US:
-			DAA_Coeff_US(j);
-			retval = ixj_daa_write(j);
-			break;
-		case DAA_UK:
-			DAA_Coeff_UK(j);
-			retval = ixj_daa_write(j);
-			break;
-		case DAA_FRANCE:
-			DAA_Coeff_France(j);
-			retval = ixj_daa_write(j);
-			break;
-		case DAA_GERMANY:
-			DAA_Coeff_Germany(j);
-			retval = ixj_daa_write(j);
-			break;
-		case DAA_AUSTRALIA:
-			DAA_Coeff_Australia(j);
-			retval = ixj_daa_write(j);
-			break;
-		case DAA_JAPAN:
-			DAA_Coeff_Japan(j);
-			retval = ixj_daa_write(j);
-			break;
-		default:
-			retval = 1;
-			break;
-		}
-		break;
-	case IXJCTL_DAA_AGAIN:
-		ixj_daa_cr4(j, arg | 0x02);
-		break;
-	case IXJCTL_PSTN_LINETEST:
-		retval = ixj_linetest(j);
-		break;
-	case IXJCTL_VMWI:
-		ixj_write_vmwi(j, arg);
-		break;
-	case IXJCTL_CID:
-		if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) 
-			retval = -EFAULT;
-		j->ex.bits.caller_id = 0;
-		break;
-	case IXJCTL_WINK_DURATION:
-		j->winktime = arg;
-		break;
-	case IXJCTL_PORT:
-		if (arg)
-			retval = ixj_set_port(j, arg);
-		else
-			retval = j->port;
-		break;
-	case IXJCTL_POTS_PSTN:
-		retval = ixj_set_pots(j, arg);
-		break;
-	case PHONE_CAPABILITIES:
-		add_caps(j);
-		retval = j->caps;
-		break;
-	case PHONE_CAPABILITIES_LIST:
-		add_caps(j);
-		if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) 
-			retval = -EFAULT;
-		break;
-	case PHONE_CAPABILITIES_CHECK:
-		{
-			struct phone_capability cap;
-			if (copy_from_user(&cap, argp, sizeof(cap))) 
-				retval = -EFAULT;
-			else {
-				add_caps(j);
-				retval = capabilities_check(j, &cap);
-			}
-		}
-		break;
-	case PHONE_PSTN_SET_STATE:
-		daa_set_mode(j, arg);
-		break;
-	case PHONE_PSTN_GET_STATE:
-		retval = j->daa_mode;
-		j->ex.bits.pstn_ring = 0;
-		break;
-	case IXJCTL_SET_FILTER:
-		if (copy_from_user(&jf, argp, sizeof(jf))) 
-			retval = -EFAULT;
-		else
-			retval = ixj_init_filter(j, &jf);
-		break;
-	case IXJCTL_SET_FILTER_RAW:
-		if (copy_from_user(&jfr, argp, sizeof(jfr))) 
-			retval = -EFAULT;
-		else
-			retval = ixj_init_filter_raw(j, &jfr);
-		break;
-	case IXJCTL_GET_FILTER_HIST:
-		if(arg<0||arg>3)
-			retval = -EINVAL;
-		else
-			retval = j->filter_hist[arg];
-		break;
-	case IXJCTL_INIT_TONE:
-		if (copy_from_user(&ti, argp, sizeof(ti)))
-			retval = -EFAULT;
-		else
-			retval = ixj_init_tone(j, &ti);
-		break;
-	case IXJCTL_TONE_CADENCE:
-		retval = ixj_build_cadence(j, argp);
-		break;
-	case IXJCTL_FILTER_CADENCE:
-		retval = ixj_build_filter_cadence(j, argp);
-		break;
-	case IXJCTL_SIGCTL:
-		if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {
-			retval = -EFAULT;
-			break;
-		}
-		j->ixj_signals[j->sigdef.event] = j->sigdef.signal;
-		if(j->sigdef.event < 33) {
-			raise = 1;
-			for(mant = 0; mant < j->sigdef.event; mant++){
-				raise *= 2;
-			}
-			if(j->sigdef.signal)
-				j->ex_sig.bytes |= raise; 
-			else
-				j->ex_sig.bytes &= (raise^0xffff); 
-		}
-		break;
-	case IXJCTL_INTERCOM_STOP:
-		if(arg < 0 || arg >= IXJMAX)
-			return -EINVAL;
-		j->intercom = -1;
-		ixj_record_stop(j);
-		ixj_play_stop(j);
-		idle(j);
-		get_ixj(arg)->intercom = -1;
-		ixj_record_stop(get_ixj(arg));
-		ixj_play_stop(get_ixj(arg));
-		idle(get_ixj(arg));
-		break;
-	case IXJCTL_INTERCOM_START:
-		if(arg < 0 || arg >= IXJMAX)
-			return -EINVAL;
-		j->intercom = arg;
-		ixj_record_start(j);
-		ixj_play_start(j);
-		get_ixj(arg)->intercom = board;
-		ixj_play_start(get_ixj(arg));
-		ixj_record_start(get_ixj(arg));
-		break;
-	}
-	if (ixjdebug & 0x0040)
-		printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
-	clear_bit(board, &j->busyflags);
-	return retval;
-}
-
-static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg)
-{
-	long ret;
-	mutex_lock(&ixj_mutex);
-	ret = do_ixj_ioctl(file_p, cmd, arg);
-	mutex_unlock(&ixj_mutex);
-	return ret;
-}
-
-static int ixj_fasync(int fd, struct file *file_p, int mode)
-{
-	IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode));
-
-	return fasync_helper(fd, file_p, mode, &j->async_queue);
-}
-
-static const struct file_operations ixj_fops =
-{
-        .owner          = THIS_MODULE,
-        .read           = ixj_enhanced_read,
-        .write          = ixj_enhanced_write,
-        .poll           = ixj_poll,
-        .unlocked_ioctl = ixj_ioctl,
-        .release        = ixj_release,
-        .fasync         = ixj_fasync,
-        .llseek	 = default_llseek,
-};
-
-static int ixj_linetest(IXJ *j)
-{
-	j->flags.pstncheck = 1;	/* Testing */
-	j->flags.pstn_present = 0; /* Assume the line is not there */
-
-	daa_int_read(j);	/*Clear DAA Interrupt flags */
-	/* */
-	/* Hold all relays in the normally de-energized position. */
-	/* */
-
-	j->pld_slicw.bits.rly1 = 0;
-	j->pld_slicw.bits.rly2 = 0;
-	j->pld_slicw.bits.rly3 = 0;
-	outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-	j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-	outb_p(j->pld_scrw.byte, j->XILINXbase);
-	j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
-	if (j->pld_slicr.bits.potspstn) {
-		j->flags.pots_pstn = 1;
-		j->flags.pots_correct = 0;
-		LED_SetState(0x4, j);
-	} else {
-		j->flags.pots_pstn = 0;
-		j->pld_slicw.bits.rly1 = 0;
-		j->pld_slicw.bits.rly2 = 0;
-		j->pld_slicw.bits.rly3 = 1;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-		outb_p(j->pld_scrw.byte, j->XILINXbase);
-		daa_set_mode(j, SOP_PU_CONVERSATION);
-		msleep(1000);
-		daa_int_read(j);
-		daa_set_mode(j, SOP_PU_RESET);
-		if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-			j->flags.pots_correct = 0;	/* Should not be line voltage on POTS port. */
-			LED_SetState(0x4, j);
-			j->pld_slicw.bits.rly3 = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		} else {
-			j->flags.pots_correct = 1;
-			LED_SetState(0x8, j);
-			j->pld_slicw.bits.rly1 = 1;
-			j->pld_slicw.bits.rly2 = 0;
-			j->pld_slicw.bits.rly3 = 0;
-			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		}
-	}
-	j->pld_slicw.bits.rly3 = 0;
-	outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-	daa_set_mode(j, SOP_PU_CONVERSATION);
-	msleep(1000);
-	daa_int_read(j);
-	daa_set_mode(j, SOP_PU_RESET);
-	if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-		j->pstn_sleeptil = jiffies + (hertz / 4);
-		j->flags.pstn_present = 1;
-	} else {
-		j->flags.pstn_present = 0;
-	}
-	if (j->flags.pstn_present) {
-		if (j->flags.pots_correct) {
-			LED_SetState(0xA, j);
-		} else {
-			LED_SetState(0x6, j);
-		}
-	} else {
-		if (j->flags.pots_correct) {
-			LED_SetState(0x9, j);
-		} else {
-			LED_SetState(0x5, j);
-		}
-	}
-	j->flags.pstncheck = 0;	/* Testing */
-	return j->flags.pstn_present;
-}
-
-static int ixj_selfprobe(IXJ *j)
-{
-	unsigned short cmd;
-	int cnt;
-	BYTES bytes;
-
-        init_waitqueue_head(&j->poll_q);
-        init_waitqueue_head(&j->read_q);
-        init_waitqueue_head(&j->write_q);
-
-	while(atomic_read(&j->DSPWrite) > 0)
-		atomic_dec(&j->DSPWrite);
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Write IDLE to Software Control Register\n");
-	ixj_WriteDSPCommand(0x0FE0, j);	/* Put the DSP in full power mode. */
-
-	if (ixj_WriteDSPCommand(0x0000, j))		/* Write IDLE to Software Control Register */
-		return -1;
-/* The read values of the SSR should be 0x00 for the IDLE command */
-	if (j->ssr.low || j->ssr.high)
-		return -1;
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Get Device ID Code\n");
-	if (ixj_WriteDSPCommand(0x3400, j))		/* Get Device ID Code */
-		return -1;
-	j->dsp.low = j->ssr.low;
-	j->dsp.high = j->ssr.high;
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Get Device Version Code\n");
-	if (ixj_WriteDSPCommand(0x3800, j))		/* Get Device Version Code */
-		return -1;
-	j->ver.low = j->ssr.low;
-	j->ver.high = j->ssr.high;
-	if (!j->cardtype) {
-		if (j->dsp.low == 0x21) {
-			bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
-			outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
-/* Test for Internet LineJACK or Internet PhoneJACK Lite */
-			bytes.low = inb_p(j->XILINXbase + 0x02);
-			if (bytes.low == bytes.high)	/*  Register is read only on */
-				/*  Internet PhoneJack Lite */
-			 {
-				j->cardtype = QTI_PHONEJACK_LITE;
-				if (!request_region(j->XILINXbase, 4, "ixj control")) {
-					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
-					return -1;
-				}
-				j->pld_slicw.pcib.e1 = 1;
-				outb_p(j->pld_slicw.byte, j->XILINXbase);
-			} else {
-				j->cardtype = QTI_LINEJACK;
-
-				if (!request_region(j->XILINXbase, 8, "ixj control")) {
-					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
-					return -1;
-				}
-			}
-		} else if (j->dsp.low == 0x22) {
-			j->cardtype = QTI_PHONEJACK_PCI;
-			request_region(j->XILINXbase, 4, "ixj control");
-			j->pld_slicw.pcib.e1 = 1;
-			outb_p(j->pld_slicw.byte, j->XILINXbase);
-		} else
-			j->cardtype = QTI_PHONEJACK;
-	} else {
-		switch (j->cardtype) {
-		case QTI_PHONEJACK:
-			if (!j->dsp.low != 0x20) {
-				j->dsp.high = 0x80;
-				j->dsp.low = 0x20;
-				ixj_WriteDSPCommand(0x3800, j);
-				j->ver.low = j->ssr.low;
-				j->ver.high = j->ssr.high;
-			}
-			break;
-		case QTI_LINEJACK:
-			if (!request_region(j->XILINXbase, 8, "ixj control")) {
-				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
-				return -1;
-			}
-			break;
-		case QTI_PHONEJACK_LITE:
-		case QTI_PHONEJACK_PCI:
-			if (!request_region(j->XILINXbase, 4, "ixj control")) {
-				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
-				return -1;
-			}
-			j->pld_slicw.pcib.e1 = 1;
-			outb_p(j->pld_slicw.byte, j->XILINXbase);
-			break;
-		case QTI_PHONECARD:
-			break;
-		}
-	}
-	if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-		if (ixj_WriteDSPCommand(0xC462, j))		/* Write CODEC config to Software Control Register */
-			return -1;
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
-		if (j->cardtype == QTI_PHONEJACK) {
-			cmd = 0x9FF2;
-		} else {
-			cmd = 0x9FF5;
-		}
-		if (ixj_WriteDSPCommand(cmd, j))	/* Write CODEC timing to Software Control Register */
-			return -1;
-	} else {
-		if (set_base_frame(j, 30) != 30)
-			return -1;
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-		if (j->cardtype == QTI_PHONECARD) {
-			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to Software Control Register */
-				return -1;
-		}
-		if (j->cardtype == QTI_LINEJACK) {
-			if (ixj_WriteDSPCommand(0xC528, j))		/* Write CODEC config to Software Control Register */
-				return -1;
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
-			j->pld_clock.byte = 0;
-			outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
-		}
-	}
-
-	if (j->dsp.low == 0x20) {
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Configure GPIO pins\n");
-		j->gpio.bytes.high = 0x09;
-/*  bytes.low = 0xEF;  0xF7 */
-		j->gpio.bits.gpio1 = 1;
-		j->gpio.bits.gpio2 = 1;
-		j->gpio.bits.gpio3 = 0;
-		j->gpio.bits.gpio4 = 1;
-		j->gpio.bits.gpio5 = 1;
-		j->gpio.bits.gpio6 = 1;
-		j->gpio.bits.gpio7 = 1;
-		ixj_WriteDSPCommand(j->gpio.word, j);	/* Set GPIO pin directions */
-		if (ixjdebug & 0x0002)
-			printk(KERN_INFO "Enable SLIC\n");
-		j->gpio.bytes.high = 0x0B;
-		j->gpio.bytes.low = 0x00;
-		j->gpio.bits.gpio1 = 0;
-		j->gpio.bits.gpio2 = 1;
-		j->gpio.bits.gpio5 = 0;
-		ixj_WriteDSPCommand(j->gpio.word, j);	/* send the ring stop signal */
-		j->port = PORT_POTS;
-	} else {
-		if (j->cardtype == QTI_LINEJACK) {
-			LED_SetState(0x1, j);
-			msleep(100);
-			LED_SetState(0x2, j);
-			msleep(100);
-			LED_SetState(0x4, j);
-			msleep(100);
-			LED_SetState(0x8, j);
-			msleep(100);
-			LED_SetState(0x0, j);
-			daa_get_version(j);
-			if (ixjdebug & 0x0002)
-				printk("Loading DAA Coefficients\n");
-			DAA_Coeff_US(j);
-			if (!ixj_daa_write(j)) {
-				printk("DAA write failed on board %d\n", j->board);
-				return -1;
-			}
-			if(!ixj_daa_cid_reset(j)) {
-				printk("DAA CID reset failed on board %d\n", j->board);
-				return -1;
-			}
-			j->flags.pots_correct = 0;
-			j->flags.pstn_present = 0;
-			ixj_linetest(j);
-			if (j->flags.pots_correct) {
-				j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-				outb_p(j->pld_scrw.byte, j->XILINXbase);
-				j->pld_slicw.bits.rly1 = 1;
-				j->pld_slicw.bits.spken = 1;
-				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-				SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-/*				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
-				j->port = PORT_POTS;
-			}
-			ixj_set_port(j, PORT_PSTN);
-			ixj_set_pots(j, 1);
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "Enable Mixer\n");
-			ixj_mixer(0x0000, j);	/*Master Volume Left unmute 0db */
-			ixj_mixer(0x0100, j);	/*Master Volume Right unmute 0db */
-
-			ixj_mixer(0x0203, j);	/*Voice Left Volume unmute 6db */
-			ixj_mixer(0x0303, j);	/*Voice Right Volume unmute 6db */
-
-			ixj_mixer(0x0480, j);	/*FM Left mute */
-			ixj_mixer(0x0580, j);	/*FM Right mute */
-
-			ixj_mixer(0x0680, j);	/*CD Left mute */
-			ixj_mixer(0x0780, j);	/*CD Right mute */
-
-			ixj_mixer(0x0880, j);	/*Line Left mute */
-			ixj_mixer(0x0980, j);	/*Line Right mute */
-
-			ixj_mixer(0x0A80, j);	/*Aux left mute  */
-			ixj_mixer(0x0B80, j);	/*Aux right mute */
-
-			ixj_mixer(0x0C00, j);	/*Mono1 unmute 12db */
-			ixj_mixer(0x0D80, j);	/*Mono2 mute */
-
-			ixj_mixer(0x0E80, j);	/*Mic mute */
-
-			ixj_mixer(0x0F00, j);	/*Mono Out Volume unmute 0db */
-
-			ixj_mixer(0x1000, j);	/*Voice Left and Right out only */
-			ixj_mixer(0x110C, j);
-
-
-			ixj_mixer(0x1200, j);	/*Mono1 switch on mixer left */
-			ixj_mixer(0x1401, j);
-
-			ixj_mixer(0x1300, j);       /*Mono1 switch on mixer right */
-			ixj_mixer(0x1501, j);
-
-			ixj_mixer(0x1700, j);	/*Clock select */
-
-			ixj_mixer(0x1800, j);	/*ADC input from mixer */
-
-			ixj_mixer(0x1901, j);	/*Mic gain 30db */
-
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "Setting Default US Ring Cadence Detection\n");
-			j->cadence_f[4].state = 0;
-			j->cadence_f[4].on1 = 0;	/*Cadence Filter 4 is used for PSTN ring cadence */
-			j->cadence_f[4].off1 = 0;
-			j->cadence_f[4].on2 = 0;
-			j->cadence_f[4].off2 = 0;
-			j->cadence_f[4].on3 = 0;
-			j->cadence_f[4].off3 = 0;	/* These should represent standard US ring pulse. */
-			j->pstn_last_rmr = jiffies;
-
-		} else {
-			if (j->cardtype == QTI_PHONECARD) {
-				ixj_WriteDSPCommand(0xCF07, j);
-				ixj_WriteDSPCommand(0x00B0, j);
-				ixj_set_port(j, PORT_SPEAKER);
-			} else {
-				ixj_set_port(j, PORT_POTS);
-				SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-/*				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
-			}
-		}
-	}
-
-	j->intercom = -1;
-	j->framesread = j->frameswritten = 0;
-	j->read_wait = j->write_wait = 0;
-	j->rxreadycheck = j->txreadycheck = 0;
-
-	/* initialise the DTMF prescale to a sensible value */
-	if (j->cardtype == QTI_LINEJACK) {
-		set_dtmf_prescale(j, 0x10); 
-	} else {
-		set_dtmf_prescale(j, 0x40); 
-	}
-	set_play_volume(j, 0x100);
-	set_rec_volume(j, 0x100);
-
-	if (ixj_WriteDSPCommand(0x0000, j))		/* Write IDLE to Software Control Register */
-		return -1;
-/* The read values of the SSR should be 0x00 for the IDLE command */
-	if (j->ssr.low || j->ssr.high)
-		return -1;
-
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Enable Line Monitor\n");
-
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
-
-	if (ixj_WriteDSPCommand(0x7E01, j))		/* Asynchronous Line Monitor */
-		return -1;
-
-	if (ixjdebug & 0x002)
-		printk(KERN_INFO "Enable DTMF Detectors\n");
-
-	if (ixj_WriteDSPCommand(0x5151, j))		/* Enable DTMF detection */
-		return -1;
-
-	if (ixj_WriteDSPCommand(0x6E01, j))		/* Set Asyncronous Tone Generation */
-		return -1;
-
-	set_rec_depth(j, 2);	/* Set Record Channel Limit to 2 frames */
-
-	set_play_depth(j, 2);	/* Set Playback Channel Limit to 2 frames */
-
-	j->ex.bits.dtmf_ready = 0;
-	j->dtmf_state = 0;
-	j->dtmf_wp = j->dtmf_rp = 0;
-	j->rec_mode = j->play_mode = -1;
-	j->flags.ringing = 0;
-	j->maxrings = MAXRINGS;
-	j->ring_cadence = USA_RING_CADENCE;
-	j->drybuffer = 0;
-	j->winktime = 320;
-	j->flags.dtmf_oob = 0;
-	for (cnt = 0; cnt < 4; cnt++)
-		j->cadence_f[cnt].enable = 0;
-	/* must be a device on the specified address */
-	ixj_WriteDSPCommand(0x0FE3, j);	/* Put the DSP in 1/5 power mode. */
-
-	/* Set up the default signals for events */
-	for (cnt = 0; cnt < 35; cnt++)
-		j->ixj_signals[cnt] = SIGIO;
-
-	/* Set the excetion signal enable flags */
-	j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
-	j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
-	j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
-#ifdef IXJ_DYN_ALLOC
-	j->fskdata = NULL;
-#endif
-	j->fskdcnt = 0;
-	j->cidcw_wait = 0;
- 
-	/* Register with the Telephony for Linux subsystem */
-	j->p.f_op = &ixj_fops;
-	j->p.open = ixj_open;
-	j->p.board = j->board;
-	phone_register_device(&j->p, PHONE_UNIT_ANY);
-
-	ixj_init_timer(j);
-	ixj_add_timer(j);
-	return 0;
-}
-
-/*
- *	Exported service for pcmcia card handling
- */
- 
-IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx)
-{
-	IXJ *j = ixj_alloc();
-
-	j->board = 0;
-
-	j->DSPbase = dsp;
-	j->XILINXbase = xilinx;
-	j->cardtype = QTI_PHONECARD;
-	ixj_selfprobe(j);
-	return j;
-}
-
-EXPORT_SYMBOL(ixj_pcmcia_probe);		/* Fpr PCMCIA */
-
-static int ixj_get_status_proc(char *buf)
-{
-	int len;
-	int cnt;
-	IXJ *j;
-	len = 0;
-	len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
-	len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ));
-	len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS));
-	len += sprintf(buf + len, "\nUsing old telephony API");
-	len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug);
-
-	for (cnt = 0; cnt < IXJMAX; cnt++) {
-		j = get_ixj(cnt);
-		if(j==NULL)
-			continue;
-		if (j->DSPbase) {
-			len += sprintf(buf + len, "\nCard Num %d", cnt);
-			len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
-			if (j->cardtype != QTI_PHONEJACK)
-				len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase);
-			len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low);
-			len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low);
-			len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial);
-			switch (j->cardtype) {
-			case (QTI_PHONEJACK):
-				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK");
-				break;
-			case (QTI_LINEJACK):
-				len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
-				if (j->flags.g729_loaded)
-					len += sprintf(buf + len, " w/G.729 A/B");
-				len += sprintf(buf + len, " Country = %d", j->daa_country);
-				break;
-			case (QTI_PHONEJACK_LITE):
-				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
-				if (j->flags.g729_loaded)
-					len += sprintf(buf + len, " w/G.729 A/B");
-				break;
-			case (QTI_PHONEJACK_PCI):
-				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI");
-				if (j->flags.g729_loaded)
-					len += sprintf(buf + len, " w/G.729 A/B");
-				break;
-			case (QTI_PHONECARD):
-				len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD");
-				if (j->flags.g729_loaded)
-					len += sprintf(buf + len, " w/G.729 A/B");
-				len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : "");
-				if (!j->pccr1.bits.drf)
-					len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct);
-				len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate);
-				break;
-			default:
-				len += sprintf(buf + len, "\nCard Type = %d", j->cardtype);
-				break;
-			}
-			len += sprintf(buf + len, "\nReaders %d", j->readers);
-			len += sprintf(buf + len, "\nWriters %d", j->writers);
-			add_caps(j);
-			len += sprintf(buf + len, "\nCapabilities %d", j->caps);
-			if (j->dsp.low != 0x20)
-				len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
-			if (j->flags.cidsent)
-				len += sprintf(buf + len, "\nCaller ID data sent");
-			else
-				len += sprintf(buf + len, "\nCaller ID data not sent");
-
-			len += sprintf(buf + len, "\nPlay CODEC ");
-			switch (j->play_codec) {
-			case G723_63:
-				len += sprintf(buf + len, "G.723.1 6.3");
-				break;
-			case G723_53:
-				len += sprintf(buf + len, "G.723.1 5.3");
-				break;
-			case TS85:
-				len += sprintf(buf + len, "TrueSpeech 8.5");
-				break;
-			case TS48:
-				len += sprintf(buf + len, "TrueSpeech 4.8");
-				break;
-			case TS41:
-				len += sprintf(buf + len, "TrueSpeech 4.1");
-				break;
-			case G728:
-				len += sprintf(buf + len, "G.728");
-				break;
-			case G729:
-				len += sprintf(buf + len, "G.729");
-				break;
-			case G729B:
-				len += sprintf(buf + len, "G.729B");
-				break;
-			case ULAW:
-				len += sprintf(buf + len, "uLaw");
-				break;
-			case ALAW:
-				len += sprintf(buf + len, "aLaw");
-				break;
-			case LINEAR16:
-				len += sprintf(buf + len, "16 bit Linear");
-				break;
-			case LINEAR8:
-				len += sprintf(buf + len, "8 bit Linear");
-				break;
-			case WSS:
-				len += sprintf(buf + len, "Windows Sound System");
-				break;
-			default:
-				len += sprintf(buf + len, "NO CODEC CHOSEN");
-				break;
-			}
-			len += sprintf(buf + len, "\nRecord CODEC ");
-			switch (j->rec_codec) {
-			case G723_63:
-				len += sprintf(buf + len, "G.723.1 6.3");
-				break;
-			case G723_53:
-				len += sprintf(buf + len, "G.723.1 5.3");
-				break;
-			case TS85:
-				len += sprintf(buf + len, "TrueSpeech 8.5");
-				break;
-			case TS48:
-				len += sprintf(buf + len, "TrueSpeech 4.8");
-				break;
-			case TS41:
-				len += sprintf(buf + len, "TrueSpeech 4.1");
-				break;
-			case G728:
-				len += sprintf(buf + len, "G.728");
-				break;
-			case G729:
-				len += sprintf(buf + len, "G.729");
-				break;
-			case G729B:
-				len += sprintf(buf + len, "G.729B");
-				break;
-			case ULAW:
-				len += sprintf(buf + len, "uLaw");
-				break;
-			case ALAW:
-				len += sprintf(buf + len, "aLaw");
-				break;
-			case LINEAR16:
-				len += sprintf(buf + len, "16 bit Linear");
-				break;
-			case LINEAR8:
-				len += sprintf(buf + len, "8 bit Linear");
-				break;
-			case WSS:
-				len += sprintf(buf + len, "Windows Sound System");
-				break;
-			default:
-				len += sprintf(buf + len, "NO CODEC CHOSEN");
-				break;
-			}
-			len += sprintf(buf + len, "\nAEC ");
-			switch (j->aec_level) {
-			case AEC_OFF:
-				len += sprintf(buf + len, "Off");
-				break;
-			case AEC_LOW:
-				len += sprintf(buf + len, "Low");
-				break;
-			case AEC_MED:
-				len += sprintf(buf + len, "Med");
-				break;
-			case AEC_HIGH:
-				len += sprintf(buf + len, "High");
-				break;
-			case AEC_AUTO:
-				len += sprintf(buf + len, "Auto");
-				break;
-			case AEC_AGC:
-				len += sprintf(buf + len, "AEC/AGC");
-				break;
-			default:
-				len += sprintf(buf + len, "unknown(%i)", j->aec_level);
-				break;
-			}
-
-			len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j));
-			len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j));
-			len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j));
-			
-			len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook);	*/
-
-			if (j->cardtype == QTI_LINEJACK) {
-				len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
-				len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
-				len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck);
-				len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
-				switch (j->daa_mode) {
-				case SOP_PU_SLEEP:
-					len += sprintf(buf + len, "\nDAA PSTN On Hook");
-					break;
-				case SOP_PU_RINGING:
-					len += sprintf(buf + len, "\nDAA PSTN Ringing");
-					len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state);
-					break;
-				case SOP_PU_CONVERSATION:
-					len += sprintf(buf + len, "\nDAA PSTN Off Hook");
-					break;
-				case SOP_PU_PULSEDIALING:
-					len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
-					break;
-				}
-				len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR);
-				len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK);
-				len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg);
-				len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg);
-				len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg);
-				len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg);
-				len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg);
-				len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg);
-				len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg);
-				len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies);
-			}
-			switch (j->port) {
-			case PORT_POTS:
-				len += sprintf(buf + len, "\nPort POTS");
-				break;
-			case PORT_PSTN:
-				len += sprintf(buf + len, "\nPort PSTN");
-				break;
-			case PORT_SPEAKER:
-				len += sprintf(buf + len, "\nPort SPEAKER/MIC");
-				break;
-			case PORT_HANDSET:
-				len += sprintf(buf + len, "\nPort HANDSET");
-				break;
-			}
-			if (j->dsp.low == 0x21 || j->dsp.low == 0x22) {
-				len += sprintf(buf + len, "\nSLIC state ");
-				switch (SLIC_GetState(j)) {
-				case PLD_SLIC_STATE_OC:
-					len += sprintf(buf + len, "OC");
-					break;
-				case PLD_SLIC_STATE_RINGING:
-					len += sprintf(buf + len, "RINGING");
-					break;
-				case PLD_SLIC_STATE_ACTIVE:
-					len += sprintf(buf + len, "ACTIVE");
-					break;
-				case PLD_SLIC_STATE_OHT:	/* On-hook transmit */
-					len += sprintf(buf + len, "OHT");
-					break;
-				case PLD_SLIC_STATE_TIPOPEN:
-					len += sprintf(buf + len, "TIPOPEN");
-					break;
-				case PLD_SLIC_STATE_STANDBY:
-					len += sprintf(buf + len, "STANDBY");
-					break;
-				case PLD_SLIC_STATE_APR:	/* Active polarity reversal */
-					len += sprintf(buf + len, "APR");
-					break;
-				case PLD_SLIC_STATE_OHTPR:	/* OHT polarity reversal */
-					len += sprintf(buf + len, "OHTPR");
-					break;
-				default:
-					len += sprintf(buf + len, "%d", SLIC_GetState(j));
-					break;
-				}
-			}
-			len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
-			len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size);
-#ifdef PERFMON_STATS
-			len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
-			len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
-			len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
-			len += sprintf(buf + len, "\nFrames Read %ld", j->framesread);
-			len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten);
-			len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer);
-			len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait);
-			len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait);
-                        len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait);
-                        len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail);
-                        len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait);
-                        len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail);
-                        len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready);
-                        len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail);
- 
-#endif
-			len += sprintf(buf + len, "\n");
-		}
-	}
-	return len;
-}
-
-static int ixj_read_proc(char *page, char **start, off_t off,
-                              int count, int *eof, void *data)
-{
-        int len = ixj_get_status_proc(page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
-}
-
-
-static void cleanup(void)
-{
-	int cnt;
-	IXJ *j;
-
-	for (cnt = 0; cnt < IXJMAX; cnt++) {
-		j = get_ixj(cnt);
-		if(j != NULL && j->DSPbase) {
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt);
-			del_timer(&j->timer);
-			if (j->cardtype == QTI_LINEJACK) {
-				j->pld_scrw.bits.daafsyncen = 0;	/* Turn off DAA Frame Sync */
-
-				outb_p(j->pld_scrw.byte, j->XILINXbase);
-				j->pld_slicw.bits.rly1 = 0;
-				j->pld_slicw.bits.rly2 = 0;
-				j->pld_slicw.bits.rly3 = 0;
-				outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-				LED_SetState(0x0, j);
-				if (ixjdebug & 0x0002)
-					printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
-				release_region(j->XILINXbase, 8);
-			} else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
-				if (ixjdebug & 0x0002)
-					printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
-				release_region(j->XILINXbase, 4);
-			}
-			kfree(j->read_buffer);
-			kfree(j->write_buffer);
-			if (j->dev)
-				pnp_device_detach(j->dev);
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt);
-			phone_unregister_device(&j->p);
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt);
-			release_region(j->DSPbase, 16);
-#ifdef IXJ_DYN_ALLOC
-			if (ixjdebug & 0x0002)
-				printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt);
-			kfree(j);
-			ixj[cnt] = NULL;
-#endif
-		}
-	}
-	if (ixjdebug & 0x0002)
-		printk(KERN_INFO "IXJ: Removing /proc/ixj\n");
-	remove_proc_entry ("ixj", NULL);
-}
-
-/* Typedefs */
-typedef struct {
-	BYTE length;
-	DWORD bits;
-} DATABLOCK;
-
-static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
-{
-	lastLCC = lastLCC & 0xfb;
-	lastLCC = lastLCC | (byData ? 4 : 0);
-	outb(lastLCC, wEEPROMAddress);	/*set data out bit as appropriate */
-
-	mdelay(1);
-	lastLCC = lastLCC | 0x01;
-	outb(lastLCC, wEEPROMAddress);	/*SK rising edge */
-
-	byData = byData << 1;
-	lastLCC = lastLCC & 0xfe;
-	mdelay(1);
-	outb(lastLCC, wEEPROMAddress);	/*after delay, SK falling edge */
-
-}
-
-static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC)
-{
-	mdelay(1);
-	lastLCC = lastLCC | 0x01;
-	outb(lastLCC, wEEPROMAddress);	/*SK rising edge */
-
-	lastLCC = lastLCC & 0xfe;
-	mdelay(1);
-	outb(lastLCC, wEEPROMAddress);	/*after delay, SK falling edge */
-
-	return ((inb(wEEPROMAddress) >> 3) & 1);
-}
-
-static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
-{
-	BYTE lastLCC;
-	WORD wEEPROMAddress = wAddress + 3;
-	DWORD i;
-	BYTE byResult;
-	*pwResult = 0;
-	lastLCC = inb(wEEPROMAddress);
-	lastLCC = lastLCC | 0x02;
-	lastLCC = lastLCC & 0xfe;
-	outb(lastLCC, wEEPROMAddress);	/* CS hi, SK lo */
-
-	mdelay(1);		/* delay */
-
-	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
-	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
-	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0);
-	for (i = 0; i < 8; i++) {
-		PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0);
-		wLoc <<= 1;
-	}
-
-	for (i = 0; i < 16; i++) {
-		byResult = PCIEE_ReadBit(wEEPROMAddress, lastLCC);
-		*pwResult = (*pwResult << 1) | byResult;
-	}
-
-	mdelay(1);		/* another delay */
-
-	lastLCC = lastLCC & 0xfd;
-	outb(lastLCC, wEEPROMAddress);	/* negate CS */
-
-	return 0;
-}
-
-static DWORD PCIEE_GetSerialNumber(WORD wAddress)
-{
-	WORD wLo, wHi;
-	if (PCIEE_ReadWord(wAddress, 62, &wLo))
-		return 0;
-	if (PCIEE_ReadWord(wAddress, 63, &wHi))
-		return 0;
-	return (((DWORD) wHi << 16) | wLo);
-}
-
-static int dspio[IXJMAX + 1] =
-{
-	0,
-};
-static int xio[IXJMAX + 1] =
-{
-	0,
-};
-
-module_param_array(dspio, int, NULL, 0);
-module_param_array(xio, int, NULL, 0);
-MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
-MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
-MODULE_LICENSE("GPL");
-
-static void __exit ixj_exit(void)
-{
-        cleanup();
-}
-
-static IXJ *new_ixj(unsigned long port)
-{
-	IXJ *res;
-	if (!request_region(port, 16, "ixj DSP")) {
-		printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port);
-		return NULL;
-	}
-	res = ixj_alloc();
-	if (!res) {
-		release_region(port, 16);
-		printk(KERN_INFO "ixj: out of memory\n");
-		return NULL;
-	}
-	res->DSPbase = port;
-	return res;
-}
-
-static int __init ixj_probe_isapnp(int *cnt)
-{               
-	int probe = 0;
-	int func = 0x110;
-        struct pnp_dev *dev = NULL, *old_dev = NULL;
-
-	while (1) {
-		do {
-			IXJ *j;
-			int result;
-
-			old_dev = dev;
-			dev = pnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
-					 ISAPNP_FUNCTION(func), old_dev);
-			if (!dev || !dev->card)
-				break;
-			result = pnp_device_attach(dev);
-			if (result < 0) {
-				printk("pnp attach failed %d \n", result);
-				break;
-			}
-			if (pnp_activate_dev(dev) < 0) {
-				printk("pnp activate failed (out of resources?)\n");
-				pnp_device_detach(dev);
-				return -ENOMEM;
-			}
-
-			if (!pnp_port_valid(dev, 0)) {
-				pnp_device_detach(dev);
-				return -ENODEV;
-			}
-
-			j = new_ixj(pnp_port_start(dev, 0));
-			if (!j)
-				break;
-
-			if (func != 0x110)
-				j->XILINXbase = pnp_port_start(dev, 1);	/* get real port */
-
-			switch (func) {
-			case (0x110):
-				j->cardtype = QTI_PHONEJACK;
-				break;
-			case (0x310):
-				j->cardtype = QTI_LINEJACK;
-				break;
-			case (0x410):
-				j->cardtype = QTI_PHONEJACK_LITE;
-				break;
-			}
-			j->board = *cnt;
-			probe = ixj_selfprobe(j);
-			if(!probe) {
-				j->serial = dev->card->serial;
-				j->dev = dev;
-				switch (func) {
-				case 0x110:
-					printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase);
-					break;
-				case 0x310:
-					printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase);
-					break;
-				case 0x410:
-					printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase);
-					break;
-				}
-			}
-			++*cnt;
-		} while (dev);
-		if (func == 0x410)
-			break;
-		if (func == 0x310)
-			func = 0x410;
-		if (func == 0x110)
-			func = 0x310;
-		dev = NULL;
-	}
-	return probe;
-}
-                        
-static int __init ixj_probe_isa(int *cnt)
-{
-	int i, probe;
-
-	/* Use passed parameters for older kernels without PnP */
-	for (i = 0; i < IXJMAX; i++) {
-		if (dspio[i]) {
-			IXJ *j = new_ixj(dspio[i]);
-
-			if (!j)
-				break;
-
-			j->XILINXbase = xio[i];
-			j->cardtype = 0;
-
-			j->board = *cnt;
-			probe = ixj_selfprobe(j);
-			j->dev = NULL;
-			++*cnt;
-		}
-	}
-	return 0;
-}
-
-static int __init ixj_probe_pci(int *cnt)
-{
-	struct pci_dev *pci = NULL;   
-	int i, probe = 0;
-	IXJ *j = NULL;
-
-	for (i = 0; i < IXJMAX - *cnt; i++) {
-		pci = pci_get_device(PCI_VENDOR_ID_QUICKNET,
-				      PCI_DEVICE_ID_QUICKNET_XJ, pci);
-		if (!pci)
-			break;
-
-		if (pci_enable_device(pci))
-			break;
-		j = new_ixj(pci_resource_start(pci, 0));
-		if (!j)
-			break;
-
-		j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
-		j->XILINXbase = j->DSPbase + 0x10;
-		j->cardtype = QTI_PHONEJACK_PCI;
-		j->board = *cnt;
-		probe = ixj_selfprobe(j);
-		if (!probe)
-			printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
-		++*cnt;
-	}
-	pci_dev_put(pci);
-	return probe;
-}
-
-static int __init ixj_init(void)
-{
-	int cnt = 0;
-	int probe = 0;   
-
-	cnt = 0;
-
-	/* These might be no-ops, see above. */
-	if ((probe = ixj_probe_isapnp(&cnt)) < 0) {
-		return probe;
-	}
-	if ((probe = ixj_probe_isa(&cnt)) < 0) {
-		return probe;
-	}
-	if ((probe = ixj_probe_pci(&cnt)) < 0) {
-		return probe;
-	}
-	printk(KERN_INFO "ixj driver initialized.\n");
-	create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
-	return probe;
-}
-
-module_init(ixj_init);
-module_exit(ixj_exit);
-
-static void DAA_Coeff_US(IXJ *j)
-{
-	int i;
-
-	j->daa_country = DAA_US;
-	/*----------------------------------------------- */
-	/* CAO */
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
-		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
-	}
-
-/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter       (08): 03,8F,48,F2,8F,48,70,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter       (07): 04,8F,38,7F,9B,EA,B0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter        (0A): 16,55,DD,CA */
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter        (09): 52,D3,11,42 */
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC;
-/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6;
-/* ;  (10K, 0.68uF) */
-	/*  */
-	/* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-	/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
-	/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
-	/* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */
-	/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ 
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */
-/* */
-	/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */
-/*	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */
-
-	/* Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/*  */
-	/* ;CR Registers */
-	/* Config. Reg. 0 (filters)       (cr0):FE ; CLK gen. by crystal */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing)       (cr1):05 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID)     (cr2):04 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops)     (cr3):03 ; SEL Bit==0, HP-disabled */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain)   (cr4):02 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
-	/* Config. Reg. 5 (Version)       (cr5):02 */
-	/* Config. Reg. 6 (Reserved)      (cr6):00 */
-	/* Config. Reg. 7 (Reserved)      (cr7):00 */
-	/*  */
-	/* ;xr Registers */
-	/* Ext. Reg. 0 (Interrupt Reg.)   (xr0):02 */
-
-	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
-	/* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
-/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char)          (xr3):32 ; B-Filter Off == 1 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B;		/*0x32; */
-	/* Ext. Reg. 4 (Cadence)          (xr4):00 */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer)       (xr5):22 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State)      (xr6):00 */
-	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd)              (xr7):40 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
-	/*  */
-	/* DTMF Tone 1                     (0B): 11,B3,5A,2C ;   697 Hz   */
-	/*                                       12,33,5A,C3 ;  770 Hz   */
-	/*                                       13,3C,5B,32 ;  852 Hz   */
-	/*                                       1D,1B,5C,CC ;  941 Hz   */
-
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2                     (0C): 32,32,52,B3 ;  1209 Hz   */
-	/*                                       EC,1D,52,22 ;  1336 Hz   */
-	/*                                       AA,AC,51,D2 ;  1477 Hz   */
-	/*                                       9B,3B,51,25 ;  1633 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-static void DAA_Coeff_UK(IXJ *j)
-{
-	int i;
-
-	j->daa_country = DAA_UK;
-	/*----------------------------------------------- */
-	/* CAO */
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
-		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
-	}
-
-/*  Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xCB;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xA4;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter       (08): 07,9B,ED,24,B2,A2,A0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x24;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0xB2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter       (07): 0F,92,F2,B2,87,D2,30,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0xB2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter        (0A): 1B,A5,DD,CA */
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter        (09): E2,27,10,D6 */
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x8B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xD0;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xF0;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x0B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
-/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA4;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x8F;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
-/* ; idle */
-	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing           (0D):AA,35,0F,8E     ; 25Hz 30V less possible? */
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
-	/* Config. Reg. 0 (filters)        (cr0):FF */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing)        (cr1):05 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID)      (cr2):04 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain)    (cr4):02 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
-	/* Config. Reg. 5 (Version)        (cr5):02 */
-	/* Config. Reg. 6 (Reserved)       (cr6):00 */
-	/* Config. Reg. 7 (Reserved)       (cr7):00 */
-	/* ;xr Registers */
-	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
-
-	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
-	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
-	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char)           (xr3):36        ;  */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-/* Ext. Reg. 4 (Cadence)           (xr4):00 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State)       (xr6):00 */
-	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd)               (xr7):46 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;		/* 0x46 ??? Should it be 0x00? */
-	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
-	/*                                       12,33,5A,C3    ;  770 Hz   */
-	/*                                       13,3C,5B,32    ;  852 Hz   */
-	/*                                       1D,1B,5C,CC    ;  941 Hz   */
-
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
-	/*                                       EC,1D,52,22    ;  1336 Hz   */
-	/*                                       AA,AC,51,D2    ;  1477 Hz   */
-	/*                                       9B,3B,51,25    ;  1633 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-
-static void DAA_Coeff_France(IXJ *j)
-{
-	int i;
-
-	j->daa_country = DAA_FRANCE;
-	/*----------------------------------------------- */
-	/* CAO */
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
-		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
-	}
-
-/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x2C;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter       (08): 07,9A,28,F6,23,4A,B0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF6;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x23;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter       (07): 03,8F,F9,2F,9E,FA,20,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9E;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter        (0A): 16,B5,DD,CA */
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter        (09): 52,C7,10,D6 */
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x30;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x78;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
-/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA5;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
-/* ; idle */
-	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing           (0D):32,45,B5,84     ; 50Hz 20V */
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
-	/* Config. Reg. 0 (filters)        (cr0):FF */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing)        (cr1):05 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID)      (cr2):04 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain)    (cr4):02 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
-	/* Config. Reg. 5 (Version)        (cr5):02 */
-	/* Config. Reg. 6 (Reserved)       (cr6):00 */
-	/* Config. Reg. 7 (Reserved)       (cr7):00 */
-	/* ;xr Registers */
-	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
-
-	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
-	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
-	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char)           (xr3):36        ;  */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-/* Ext. Reg. 4 (Cadence)           (xr4):00 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State)       (xr6):00 */
-	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd)               (xr7):46 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;		/* 0x46 ??? Should it be 0x00? */
-	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
-	/*                                       12,33,5A,C3    ;  770 Hz   */
-	/*                                       13,3C,5B,32    ;  852 Hz   */
-	/*                                       1D,1B,5C,CC    ;  941 Hz   */
-
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
-	/*                                       EC,1D,52,22    ;  1336 Hz   */
-	/*                                       AA,AC,51,D2    ;  1477 Hz   */
-	/*                                       9B,3B,51,25    ;  1633 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-
-static void DAA_Coeff_Germany(IXJ *j)
-{
-	int i;
-
-	j->daa_country = DAA_GERMANY;
-	/*----------------------------------------------- */
-	/* CAO */
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
-		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
-	}
-
-/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xD2;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0C;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xD2;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter       (08): 07,AA,E2,34,24,89,20,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x24;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter       (07): 02,87,FA,37,9A,CA,B0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x37;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9A;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter        (0A): 72,D5,DD,CA */
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter        (09): 72,42,13,4B */
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
-/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAD;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
-/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x26;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBD;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
-/* ;  (10K, 0.68uF) */
-	/* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-/* Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
-	/* Config. Reg. 0 (filters)        (cr0):FF ; all Filters enabled, CLK from ext. source */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing)        (cr1):05 ; Manual Ring, Ring metering enabled */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID)      (cr2):04 ; Analog Gain 0dB, FSC internal */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops)      (cr3):00 ; SEL Bit==0, HP-enabled */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain)    (cr4):02 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
-	/* Config. Reg. 5 (Version)        (cr5):02 */
-	/* Config. Reg. 6 (Reserved)       (cr6):00 */
-	/* Config. Reg. 7 (Reserved)       (cr7):00 */
-	/* ;xr Registers */
-	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
-
-	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
-	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
-	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char)           (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
-/* Ext. Reg. 4 (Cadence)           (xr4):00 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State)       (xr6):00 */
-	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd)               (xr7):40 ; VDD=4.25 V */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
-	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
-	/*                                       12,33,5A,C3    ;  770 Hz   */
-	/*                                       13,3C,5B,32    ;  852 Hz   */
-	/*                                       1D,1B,5C,CC    ;  941 Hz   */
-
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
-	/*                                       EC,1D,52,22    ;  1336 Hz   */
-	/*                                       AA,AC,51,D2    ;  1477 Hz   */
-	/*                                       9B,3B,51,25    ;  1633 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-
-static void DAA_Coeff_Australia(IXJ *j)
-{
-	int i;
-
-	j->daa_country = DAA_AUSTRALIA;
-	/*----------------------------------------------- */
-	/* CAO */
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
-		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
-	}
-
-/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter       (08): 07,96,E2,34,32,9B,30,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter       (07): 0F,9A,E9,2F,22,CC,A0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter        (0A): CB,45,DD,CA */
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter        (09): 1B,67,10,D6 */
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAF;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x38;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
-/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x3E;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x2C;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;
-/* ;  idle */
-	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing           (0D):32,45,B5,84   ; 50Hz 20V */
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
-	/* Config. Reg. 0 (filters)        (cr0):FF */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing)        (cr1):05 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID)      (cr2):04 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain)    (cr4):02 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
-	/* Config. Reg. 5 (Version)        (cr5):02 */
-	/* Config. Reg. 6 (Reserved)       (cr6):00 */
-	/* Config. Reg. 7 (Reserved)       (cr7):00 */
-	/* ;xr Registers */
-	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
-
-	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
-	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
-	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char)           (xr3):2B      ;  */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;
-/* Ext. Reg. 4 (Cadence)           (xr4):00 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State)       (xr6):00 */
-	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd)               (xr7):40 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
-
-	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;  697 Hz   */
-	/*                                       12,33,5A,C3    ;  770 Hz   */
-	/*                                       13,3C,5B,32    ;  852 Hz   */
-	/*                                       1D,1B,5C,CC    ;  941 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
-	/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
-	/*                                       EC,1D,52,22    ;  1336 Hz   */
-	/*                                       AA,AC,51,D2    ;  1477 Hz   */
-	/*                                       9B,3B,51,25    ;  1633 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-static void DAA_Coeff_Japan(IXJ *j)
-{
-	int i;
-
-	j->daa_country = DAA_JAPAN;
-	/*----------------------------------------------- */
-	/* CAO */
-	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
-		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
-	}
-
-/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x34;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
-	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-/* Bytes for FRX-filter       (08): 02,8F,68,77,9C,58,F0,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x77;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x9C;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-/* Bytes for FRR-filter       (07): 03,8F,38,73,87,EA,20,08 */
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x73;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
-	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-/* Bytes for AX-filter        (0A): 51,C5,DD,CA */
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
-	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-/* Bytes for AR-filter        (09): 25,A7,10,D6 */
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
-	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAE;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
-/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x25;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x34;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
-	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;
-/* ;  idle */
-	/* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
-	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-/* Levelmetering Ringing           (0D):AA,35,0F,8E    ; 25Hz 30V ????????? */
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
-	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
-	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/* ;CR Registers */
-	/* Config. Reg. 0 (filters)        (cr0):FF */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-/* Config. Reg. 1 (dialing)        (cr1):05 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-/* Config. Reg. 2 (caller ID)      (cr2):04 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-/* Config. Reg. 4 (analog gain)    (cr4):02 */
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
-	/* Config. Reg. 5 (Version)        (cr5):02 */
-	/* Config. Reg. 6 (Reserved)       (cr6):00 */
-	/* Config. Reg. 7 (Reserved)       (cr7):00 */
-	/* ;xr Registers */
-	/* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
-
-	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	/* SO_1 set to '1' because it is inverted. */
-	/* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		/* RING, Caller ID, VDD_OK */
-	/* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
-
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-/* Ext. Reg. 3 (DC Char)           (xr3):22        ;  */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
-/* Ext. Reg. 4 (Cadence)           (xr4):00 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-/* Ext. Reg. 6 (Power State)       (xr6):00 */
-	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-/* Ext. Reg. 7 (Vdd)               (xr7):40 */
-	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		/* 0x40 ??? Should it be 0x00? */
-	/* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
-	/*                                       12,33,5A,C3    ;  770 Hz   */
-	/*                                       13,3C,5B,32    ;  852 Hz   */
-	/*                                       1D,1B,5C,CC    ;  941 Hz   */
-
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
-	/*                                       EC,1D,52,22    ;  1336 Hz   */
-	/*                                       AA,AC,51,D2    ;  1477 Hz   */
-	/*                                       9B,3B,51,25    ;  1633 Hz   */
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
-	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-}
-
-static s16 tone_table[][19] =
-{
-	{			/* f20_50[] 11 */
-		32538,		/* A1 = 1.985962 */
-		 -32325,	/* A2 = -0.986511 */
-		 -343,		/* B2 = -0.010493 */
-		 0,		/* B1 = 0 */
-		 343,		/* B0 = 0.010493 */
-		 32619,		/* A1 = 1.990906 */
-		 -32520,	/* A2 = -0.992462 */
-		 19179,		/* B2 = 0.585327 */
-		 -19178,	/* B1 = -1.170593 */
-		 19179,		/* B0 = 0.585327 */
-		 32723,		/* A1 = 1.997314 */
-		 -32686,	/* A2 = -0.997528 */
-		 9973,		/* B2 = 0.304352 */
-		 -9955,		/* B1 = -0.607605 */
-		 9973,		/* B0 = 0.304352 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f133_200[] 12 */
-		32072,		/* A1 = 1.95752 */
-		 -31896,	/* A2 = -0.973419 */
-		 -435,		/* B2 = -0.013294 */
-		 0,		/* B1 = 0 */
-		 435,		/* B0 = 0.013294 */
-		 32188,		/* A1 = 1.9646 */
-		 -32400,	/* A2 = -0.98877 */
-		 15139,		/* B2 = 0.462036 */
-		 -14882,	/* B1 = -0.908356 */
-		 15139,		/* B0 = 0.462036 */
-		 32473,		/* A1 = 1.981995 */
-		 -32524,	/* A2 = -0.992584 */
-		 23200,		/* B2 = 0.708008 */
-		 -23113,	/* B1 = -1.410706 */
-		 23200,		/* B0 = 0.708008 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f300 13 */
-		31769,		/* A1 = -1.939026 */
-		 -32584,	/* A2 = 0.994385 */
-		 -475,		/* B2 = -0.014522 */
-		 0,		/* B1 = 0.000000 */
-		 475,		/* B0 = 0.014522 */
-		 31789,		/* A1 = -1.940247 */
-		 -32679,	/* A2 = 0.997284 */
-		 17280,		/* B2 = 0.527344 */
-		 -16865,	/* B1 = -1.029358 */
-		 17280,		/* B0 = 0.527344 */
-		 31841,		/* A1 = -1.943481 */
-		 -32681,	/* A2 = 0.997345 */
-		 543,		/* B2 = 0.016579 */
-		 -525,		/* B1 = -0.032097 */
-		 543,		/* B0 = 0.016579 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f300_420[] 14 */
-		30750,		/* A1 = 1.876892 */
-		 -31212,	/* A2 = -0.952515 */
-		 -804,		/* B2 = -0.024541 */
-		 0,		/* B1 = 0 */
-		 804,		/* B0 = 0.024541 */
-		 30686,		/* A1 = 1.872925 */
-		 -32145,	/* A2 = -0.980988 */
-		 14747,		/* B2 = 0.450043 */
-		 -13703,	/* B1 = -0.836395 */
-		 14747,		/* B0 = 0.450043 */
-		 31651,		/* A1 = 1.931824 */
-		 -32321,	/* A2 = -0.986389 */
-		 24425,		/* B2 = 0.745422 */
-		 -23914,	/* B1 = -1.459595 */
-		 24427,		/* B0 = 0.745483 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f330 15 */
-		31613,		/* A1 = -1.929565 */
-		 -32646,	/* A2 = 0.996277 */
-		 -185,		/* B2 = -0.005657 */
-		 0,		/* B1 = 0.000000 */
-		 185,		/* B0 = 0.005657 */
-		 31620,		/* A1 = -1.929932 */
-		 -32713,	/* A2 = 0.998352 */
-		 19253,		/* B2 = 0.587585 */
-		 -18566,	/* B1 = -1.133179 */
-		 19253,		/* B0 = 0.587585 */
-		 31674,		/* A1 = -1.933228 */
-		 -32715,	/* A2 = 0.998413 */
-		 2575,		/* B2 = 0.078590 */
-		 -2495,		/* B1 = -0.152283 */
-		 2575,		/* B0 = 0.078590 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f300_425[] 16 */
-		30741,		/* A1 = 1.876282 */
-		 -31475,	/* A2 = -0.960541 */
-		 -703,		/* B2 = -0.021484 */
-		 0,		/* B1 = 0 */
-		 703,		/* B0 = 0.021484 */
-		 30688,		/* A1 = 1.873047 */
-		 -32248,	/* A2 = -0.984161 */
-		 14542,		/* B2 = 0.443787 */
-		 -13523,	/* B1 = -0.825439 */
-		 14542,		/* B0 = 0.443817 */
-		 31494,		/* A1 = 1.922302 */
-		 -32366,	/* A2 = -0.987762 */
-		 21577,		/* B2 = 0.658508 */
-		 -21013,	/* B1 = -1.282532 */
-		 21577,		/* B0 = 0.658508 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f330_440[] 17 */
-		30627,		/* A1 = 1.869324 */
-		 -31338,	/* A2 = -0.95636 */
-		 -843,		/* B2 = -0.025749 */
-		 0,		/* B1 = 0 */
-		 843,		/* B0 = 0.025749 */
-		 30550,		/* A1 = 1.864685 */
-		 -32221,	/* A2 = -0.983337 */
-		 13594,		/* B2 = 0.414886 */
-		 -12589,	/* B1 = -0.768402 */
-		 13594,		/* B0 = 0.414886 */
-		 31488,		/* A1 = 1.921936 */
-		 -32358,	/* A2 = -0.987518 */
-		 24684,		/* B2 = 0.753296 */
-		 -24029,	/* B1 = -1.466614 */
-		 24684,		/* B0 = 0.753296 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f340 18 */
-		31546,		/* A1 = -1.925476 */
-		 -32646,	/* A2 = 0.996277 */
-		 -445,		/* B2 = -0.013588 */
-		 0,		/* B1 = 0.000000 */
-		 445,		/* B0 = 0.013588 */
-		 31551,		/* A1 = -1.925781 */
-		 -32713,	/* A2 = 0.998352 */
-		 23884,		/* B2 = 0.728882 */
-		 -22979,	/* B1 = -1.402527 */
-		 23884,		/* B0 = 0.728882 */
-		 31606,		/* A1 = -1.929138 */
-		 -32715,	/* A2 = 0.998413 */
-		 863,		/* B2 = 0.026367 */
-		 -835,		/* B1 = -0.050985 */
-		 863,		/* B0 = 0.026367 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f350_400[] 19 */
-		31006,		/* A1 = 1.892517 */
-		 -32029,	/* A2 = -0.977448 */
-		 -461,		/* B2 = -0.014096 */
-		 0,		/* B1 = 0 */
-		 461,		/* B0 = 0.014096 */
-		 30999,		/* A1 = 1.892029 */
-		 -32487,	/* A2 = -0.991455 */
-		 11325,		/* B2 = 0.345612 */
-		 -10682,	/* B1 = -0.651978 */
-		 11325,		/* B0 = 0.345612 */
-		 31441,		/* A1 = 1.919067 */
-		 -32526,	/* A2 = -0.992615 */
-		 24324,		/* B2 = 0.74231 */
-		 -23535,	/* B1 = -1.436523 */
-		 24324,		/* B0 = 0.74231 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f350_440[] */
-		30634,		/* A1 = 1.869751 */
-		 -31533,	/* A2 = -0.962341 */
-		 -680,		/* B2 = -0.020782 */
-		 0,		/* B1 = 0 */
-		 680,		/* B0 = 0.020782 */
-		 30571,		/* A1 = 1.865906 */
-		 -32277,	/* A2 = -0.985016 */
-		 12894,		/* B2 = 0.393524 */
-		 -11945,	/* B1 = -0.729065 */
-		 12894,		/* B0 = 0.393524 */
-		 31367,		/* A1 = 1.91449 */
-		 -32379,	/* A2 = -0.988129 */
-		 23820,		/* B2 = 0.726929 */
-		 -23104,	/* B1 = -1.410217 */
-		 23820,		/* B0 = 0.726929 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f350_450[] */
-		30552,		/* A1 = 1.864807 */
-		 -31434,	/* A2 = -0.95929 */
-		 -690,		/* B2 = -0.021066 */
-		 0,		/* B1 = 0 */
-		 690,		/* B0 = 0.021066 */
-		 30472,		/* A1 = 1.859924 */
-		 -32248,	/* A2 = -0.984161 */
-		 13385,		/* B2 = 0.408478 */
-		 -12357,	/* B1 = -0.754242 */
-		 13385,		/* B0 = 0.408478 */
-		 31358,		/* A1 = 1.914001 */
-		 -32366,	/* A2 = -0.987732 */
-		 26488,		/* B2 = 0.80835 */
-		 -25692,	/* B1 = -1.568176 */
-		 26490,		/* B0 = 0.808411 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f360 */
-		31397,		/* A1 = -1.916321 */
-		 -32623,	/* A2 = 0.995605 */
-		 -117,		/* B2 = -0.003598 */
-		 0,		/* B1 = 0.000000 */
-		 117,		/* B0 = 0.003598 */
-		 31403,		/* A1 = -1.916687 */
-		 -32700,	/* A2 = 0.997925 */
-		 3388,		/* B2 = 0.103401 */
-		 -3240,		/* B1 = -0.197784 */
-		 3388,		/* B0 = 0.103401 */
-		 31463,		/* A1 = -1.920410 */
-		 -32702,	/* A2 = 0.997986 */
-		 13346,		/* B2 = 0.407288 */
-		 -12863,	/* B1 = -0.785126 */
-		 13346,		/* B0 = 0.407288 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f380_420[] */
-		30831,		/* A1 = 1.881775 */
-		 -32064,	/* A2 = -0.978546 */
-		 -367,		/* B2 = -0.01122 */
-		 0,		/* B1 = 0 */
-		 367,		/* B0 = 0.01122 */
-		 30813,		/* A1 = 1.880737 */
-		 -32456,	/* A2 = -0.990509 */
-		 11068,		/* B2 = 0.337769 */
-		 -10338,	/* B1 = -0.631042 */
-		 11068,		/* B0 = 0.337769 */
-		 31214,		/* A1 = 1.905212 */
-		 -32491,	/* A2 = -0.991577 */
-		 16374,		/* B2 = 0.499695 */
-		 -15781,	/* B1 = -0.963196 */
-		 16374,		/* B0 = 0.499695 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f392 */
-		31152,		/* A1 = -1.901428 */
-		 -32613,	/* A2 = 0.995300 */
-		 -314,		/* B2 = -0.009605 */
-		 0,		/* B1 = 0.000000 */
-		 314,		/* B0 = 0.009605 */
-		 31156,		/* A1 = -1.901672 */
-		 -32694,	/* A2 = 0.997742 */
-		 28847,		/* B2 = 0.880371 */
-		 -2734,		/* B1 = -0.166901 */
-		 28847,		/* B0 = 0.880371 */
-		 31225,		/* A1 = -1.905823 */
-		 -32696,	/* A2 = 0.997803 */
-		 462,		/* B2 = 0.014108 */
-		 -442,		/* B1 = -0.027019 */
-		 462,		/* B0 = 0.014108 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f400_425[] */
-		30836,		/* A1 = 1.882141 */
-		 -32296,	/* A2 = -0.985596 */
-		 -324,		/* B2 = -0.009903 */
-		 0,		/* B1 = 0 */
-		 324,		/* B0 = 0.009903 */
-		 30825,		/* A1 = 1.881409 */
-		 -32570,	/* A2 = -0.993958 */
-		 16847,		/* B2 = 0.51416 */
-		 -15792,	/* B1 = -0.963898 */
-		 16847,		/* B0 = 0.51416 */
-		 31106,		/* A1 = 1.89856 */
-		 -32584,	/* A2 = -0.994415 */
-		 9579,		/* B2 = 0.292328 */
-		 -9164,		/* B1 = -0.559357 */
-		 9579,		/* B0 = 0.292328 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f400_440[] */
-		30702,		/* A1 = 1.873962 */
-		 -32134,	/* A2 = -0.980682 */
-		 -517,		/* B2 = -0.015793 */
-		 0,		/* B1 = 0 */
-		 517,		/* B0 = 0.015793 */
-		 30676,		/* A1 = 1.872375 */
-		 -32520,	/* A2 = -0.992462 */
-		 8144,		/* B2 = 0.24855 */
-		 -7596,		/* B1 = -0.463684 */
-		 8144,		/* B0 = 0.24855 */
-		 31084,		/* A1 = 1.897217 */
-		 -32547,	/* A2 = -0.993256 */
-		 22713,		/* B2 = 0.693176 */
-		 -21734,	/* B1 = -1.326599 */
-		 22713,		/* B0 = 0.693176 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f400_450[] */
-		30613,		/* A1 = 1.86853 */
-		 -32031,	/* A2 = -0.977509 */
-		 -618,		/* B2 = -0.018866 */
-		 0,		/* B1 = 0 */
-		 618,		/* B0 = 0.018866 */
-		 30577,		/* A1 = 1.866272 */
-		 -32491,	/* A2 = -0.991577 */
-		 9612,		/* B2 = 0.293335 */
-		 -8935,		/* B1 = -0.54541 */
-		 9612,		/* B0 = 0.293335 */
-		 31071,		/* A1 = 1.896484 */
-		 -32524,	/* A2 = -0.992584 */
-		 21596,		/* B2 = 0.659058 */
-		 -20667,	/* B1 = -1.261414 */
-		 21596,		/* B0 = 0.659058 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f420 */
-		30914,		/* A1 = -1.886841 */
-		 -32584,	/* A2 = 0.994385 */
-		 -426,		/* B2 = -0.013020 */
-		 0,		/* B1 = 0.000000 */
-		 426,		/* B0 = 0.013020 */
-		 30914,		/* A1 = -1.886841 */
-		 -32679,	/* A2 = 0.997314 */
-		 17520,		/* B2 = 0.534668 */
-		 -16471,	/* B1 = -1.005310 */
-		 17520,		/* B0 = 0.534668 */
-		 31004,		/* A1 = -1.892334 */
-		 -32683,	/* A2 = 0.997406 */
-		 819,		/* B2 = 0.025023 */
-		 -780,		/* B1 = -0.047619 */
-		 819,		/* B0 = 0.025023 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-#if 0
-	{			/* f425 */
-		30881,		/* A1 = -1.884827 */
-		 -32603,	/* A2 = 0.994965 */
-		 -496,		/* B2 = -0.015144 */
-		 0,		/* B1 = 0.000000 */
-		 496,		/* B0 = 0.015144 */
-		 30880,		/* A1 = -1.884766 */
-		 -32692,	/* A2 = 0.997711 */
-		 24767,		/* B2 = 0.755859 */
-		 -23290,	/* B1 = -1.421509 */
-		 24767,		/* B0 = 0.755859 */
-		 30967,		/* A1 = -1.890076 */
-		 -32694,	/* A2 = 0.997772 */
-		 728,		/* B2 = 0.022232 */
-		 -691,		/* B1 = -0.042194 */
-		 728,		/* B0 = 0.022232 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-#else
-	{
-		30850,
-		-32534,
-		-504,
-		0,
-		504,
-		30831,
-		-32669,
-		24303,
-		-22080,
-		24303,
-		30994,
-		-32673,
-		1905,
-		-1811,
-		1905,
-		5,
-		129,
-		17,
-		0xff5
-	},
-#endif
-	{			/* f425_450[] */
-		30646,		/* A1 = 1.870544 */
-		 -32327,	/* A2 = -0.986572 */
-		 -287,		/* B2 = -0.008769 */
-		 0,		/* B1 = 0 */
-		 287,		/* B0 = 0.008769 */
-		 30627,		/* A1 = 1.869324 */
-		 -32607,	/* A2 = -0.995087 */
-		 13269,		/* B2 = 0.404968 */
-		 -12376,	/* B1 = -0.755432 */
-		 13269,		/* B0 = 0.404968 */
-		 30924,		/* A1 = 1.887512 */
-		 -32619,	/* A2 = -0.995453 */
-		 19950,		/* B2 = 0.608826 */
-		 -18940,	/* B1 = -1.156006 */
-		 19950,		/* B0 = 0.608826 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f425_475[] */
-		30396,		/* A1 = 1.855225 */
-		 -32014,	/* A2 = -0.97699 */
-		 -395,		/* B2 = -0.012055 */
-		 0,		/* B1 = 0 */
-		 395,		/* B0 = 0.012055 */
-		 30343,		/* A1 = 1.85199 */
-		 -32482,	/* A2 = -0.991302 */
-		 17823,		/* B2 = 0.543945 */
-		 -16431,	/* B1 = -1.002869 */
-		 17823,		/* B0 = 0.543945 */
-		 30872,		/* A1 = 1.884338 */
-		 -32516,	/* A2 = -0.99231 */
-		 18124,		/* B2 = 0.553101 */
-		 -17246,	/* B1 = -1.052673 */
-		 18124,		/* B0 = 0.553101 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f435 */
-		30796,		/* A1 = -1.879639 */
-		 -32603,	/* A2 = 0.994965 */
-		 -254,		/* B2 = -0.007762 */
-		 0,		/* B1 = 0.000000 */
-		 254,		/* B0 = 0.007762 */
-		 30793,		/* A1 = -1.879456 */
-		 -32692,	/* A2 = 0.997711 */
-		 18934,		/* B2 = 0.577820 */
-		 -17751,	/* B1 = -1.083496 */
-		 18934,		/* B0 = 0.577820 */
-		 30882,		/* A1 = -1.884888 */
-		 -32694,	/* A2 = 0.997772 */
-		 1858,		/* B2 = 0.056713 */
-		 -1758,		/* B1 = -0.107357 */
-		 1858,		/* B0 = 0.056713 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f440_450[] */
-		30641,		/* A1 = 1.870239 */
-		 -32458,	/* A2 = -0.99057 */
-		 -155,		/* B2 = -0.004735 */
-		 0,		/* B1 = 0 */
-		 155,		/* B0 = 0.004735 */
-		 30631,		/* A1 = 1.869568 */
-		 -32630,	/* A2 = -0.995789 */
-		 11453,		/* B2 = 0.349548 */
-		 -10666,	/* B1 = -0.651001 */
-		 11453,		/* B0 = 0.349548 */
-		 30810,		/* A1 = 1.880554 */
-		 -32634,	/* A2 = -0.995941 */
-		 12237,		/* B2 = 0.373474 */
-		 -11588,	/* B1 = -0.707336 */
-		 12237,		/* B0 = 0.373474 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f440_480[] */
-		30367,		/* A1 = 1.853455 */
-		 -32147,	/* A2 = -0.981079 */
-		 -495,		/* B2 = -0.015113 */
-		 0,		/* B1 = 0 */
-		 495,		/* B0 = 0.015113 */
-		 30322,		/* A1 = 1.850769 */
-		 -32543,	/* A2 = -0.993134 */
-		 10031,		/* B2 = 0.306152 */
-		 -9252,		/* B1 = -0.564728 */
-		 10031,		/* B0 = 0.306152 */
-		 30770,		/* A1 = 1.878052 */
-		 -32563,	/* A2 = -0.993774 */
-		 22674,		/* B2 = 0.691956 */
-		 -21465,	/* B1 = -1.31012 */
-		 22674,		/* B0 = 0.691956 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f445 */
-		30709,		/* A1 = -1.874329 */
-		 -32603,	/* A2 = 0.994965 */
-		 -83,		/* B2 = -0.002545 */
-		 0,		/* B1 = 0.000000 */
-		 83,		/* B0 = 0.002545 */
-		 30704,		/* A1 = -1.874084 */
-		 -32692,	/* A2 = 0.997711 */
-		 10641,		/* B2 = 0.324738 */
-		 -9947,		/* B1 = -0.607147 */
-		 10641,		/* B0 = 0.324738 */
-		 30796,		/* A1 = -1.879639 */
-		 -32694,	/* A2 = 0.997772 */
-		 10079,		/* B2 = 0.307587 */
-		 9513,		/* B1 = 0.580688 */
-		 10079,		/* B0 = 0.307587 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f450 */
-		30664,		/* A1 = -1.871643 */
-		 -32603,	/* A2 = 0.994965 */
-		 -164,		/* B2 = -0.005029 */
-		 0,		/* B1 = 0.000000 */
-		 164,		/* B0 = 0.005029 */
-		 30661,		/* A1 = -1.871399 */
-		 -32692,	/* A2 = 0.997711 */
-		 15294,		/* B2 = 0.466736 */
-		 -14275,	/* B1 = -0.871307 */
-		 15294,		/* B0 = 0.466736 */
-		 30751,		/* A1 = -1.876953 */
-		 -32694,	/* A2 = 0.997772 */
-		 3548,		/* B2 = 0.108284 */
-		 -3344,		/* B1 = -0.204155 */
-		 3548,		/* B0 = 0.108284 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f452 */
-		30653,		/* A1 = -1.870911 */
-		 -32615,	/* A2 = 0.995361 */
-		 -209,		/* B2 = -0.006382 */
-		 0,		/* B1 = 0.000000 */
-		 209,		/* B0 = 0.006382 */
-		 30647,		/* A1 = -1.870605 */
-		 -32702,	/* A2 = 0.997986 */
-		 18971,		/* B2 = 0.578979 */
-		 -17716,	/* B1 = -1.081299 */
-		 18971,		/* B0 = 0.578979 */
-		 30738,		/* A1 = -1.876099 */
-		 -32702,	/* A2 = 0.998016 */
-		 2967,		/* B2 = 0.090561 */
-		 -2793,		/* B1 = -0.170502 */
-		 2967,		/* B0 = 0.090561 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f475 */
-		30437,		/* A1 = -1.857727 */
-		 -32603,	/* A2 = 0.994965 */
-		 -264,		/* B2 = -0.008062 */
-		 0,		/* B1 = 0.000000 */
-		 264,		/* B0 = 0.008062 */
-		 30430,		/* A1 = -1.857300 */
-		 -32692,	/* A2 = 0.997711 */
-		 21681,		/* B2 = 0.661682 */
-		 -20082,	/* B1 = -1.225708 */
-		 21681,		/* B0 = 0.661682 */
-		 30526,		/* A1 = -1.863220 */
-		 -32694,	/* A2 = 0.997742 */
-		 1559,		/* B2 = 0.047600 */
-		 -1459,		/* B1 = -0.089096 */
-		 1559,		/* B0 = 0.047600 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f480_620[] */
-		28975,		/* A1 = 1.768494 */
-		 -30955,	/* A2 = -0.944672 */
-		 -1026,		/* B2 = -0.03133 */
-		 0,		/* B1 = 0 */
-		 1026,		/* B0 = 0.03133 */
-		 28613,		/* A1 = 1.746399 */
-		 -32089,	/* A2 = -0.979309 */
-		 14214,		/* B2 = 0.433807 */
-		 -12202,	/* B1 = -0.744812 */
-		 14214,		/* B0 = 0.433807 */
-		 30243,		/* A1 = 1.845947 */
-		 -32238,	/* A2 = -0.983856 */
-		 24825,		/* B2 = 0.757629 */
-		 -23402,	/* B1 = -1.428345 */
-		 24825,		/* B0 = 0.757629 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f494 */
-		30257,		/* A1 = -1.846741 */
-		 -32605,	/* A2 = 0.995056 */
-		 -249,		/* B2 = -0.007625 */
-		 0,		/* B1 = 0.000000 */
-		 249,		/* B0 = 0.007625 */
-		 30247,		/* A1 = -1.846191 */
-		 -32694,	/* A2 = 0.997772 */
-		 18088,		/* B2 = 0.552002 */
-		 -16652,	/* B1 = -1.016418 */
-		 18088,		/* B0 = 0.552002 */
-		 30348,		/* A1 = -1.852295 */
-		 -32696,	/* A2 = 0.997803 */
-		 2099,		/* B2 = 0.064064 */
-		 -1953,		/* B1 = -0.119202 */
-		 2099,		/* B0 = 0.064064 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f500 */
-		30202,		/* A1 = -1.843431 */
-		 -32624,	/* A2 = 0.995622 */
-		 -413,		/* B2 = -0.012622 */
-		 0,		/* B1 = 0.000000 */
-		 413,		/* B0 = 0.012622 */
-		 30191,		/* A1 = -1.842721 */
-		 -32714,	/* A2 = 0.998364 */
-		 25954,		/* B2 = 0.792057 */
-		 -23890,	/* B1 = -1.458131 */
-		 25954,		/* B0 = 0.792057 */
-		 30296,		/* A1 = -1.849172 */
-		 -32715,	/* A2 = 0.998397 */
-		 2007,		/* B2 = 0.061264 */
-		 -1860,		/* B1 = -0.113568 */
-		 2007,		/* B0 = 0.061264 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f520 */
-		30001,		/* A1 = -1.831116 */
-		 -32613,	/* A2 = 0.995270 */
-		 -155,		/* B2 = -0.004750 */
-		 0,		/* B1 = 0.000000 */
-		 155,		/* B0 = 0.004750 */
-		 29985,		/* A1 = -1.830200 */
-		 -32710,	/* A2 = 0.998260 */
-		 6584,		/* B2 = 0.200928 */
-		 -6018,		/* B1 = -0.367355 */
-		 6584,		/* B0 = 0.200928 */
-		 30105,		/* A1 = -1.837524 */
-		 -32712,	/* A2 = 0.998291 */
-		 23812,		/* B2 = 0.726685 */
-		 -21936,	/* B1 = -1.338928 */
-		 23812,		/* B0 = 0.726685 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f523 */
-		29964,		/* A1 = -1.828918 */
-		 -32601,	/* A2 = 0.994904 */
-		 -101,		/* B2 = -0.003110 */
-		 0,		/* B1 = 0.000000 */
-		 101,		/* B0 = 0.003110 */
-		 29949,		/* A1 = -1.827942 */
-		 -32700,	/* A2 = 0.997925 */
-		 11041,		/* B2 = 0.336975 */
-		 -10075,	/* B1 = -0.614960 */
-		 11041,		/* B0 = 0.336975 */
-		 30070,		/* A1 = -1.835388 */
-		 -32702,	/* A2 = 0.997986 */
-		 16762,		/* B2 = 0.511536 */
-		 -15437,	/* B1 = -0.942230 */
-		 16762,		/* B0 = 0.511536 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f525 */
-		29936,		/* A1 = -1.827209 */
-		 -32584,	/* A2 = 0.994415 */
-		 -91,		/* B2 = -0.002806 */
-		 0,		/* B1 = 0.000000 */
-		 91,		/* B0 = 0.002806 */
-		 29921,		/* A1 = -1.826233 */
-		 -32688,	/* A2 = 0.997559 */
-		 11449,		/* B2 = 0.349396 */
-		 -10426,	/* B1 = -0.636383 */
-		 11449,		/* B0 = 0.349396 */
-		 30045,		/* A1 = -1.833862 */
-		 -32688,	/* A2 = 0.997589 */
-		 13055,		/* B2 = 0.398407 */
-		 -12028,	/* B1 = -0.734161 */
-		 13055,		/* B0 = 0.398407 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f540_660[] */
-		28499,		/* A1 = 1.739441 */
-		 -31129,	/* A2 = -0.949982 */
-		 -849,		/* B2 = -0.025922 */
-		 0,		/* B1 = 0 */
-		 849,		/* B0 = 0.025922 */
-		 28128,		/* A1 = 1.716797 */
-		 -32130,	/* A2 = -0.98056 */
-		 14556,		/* B2 = 0.444214 */
-		 -12251,	/* B1 = -0.747772 */
-		 14556,		/* B0 = 0.444244 */
-		 29667,		/* A1 = 1.81073 */
-		 -32244,	/* A2 = -0.984039 */
-		 23038,		/* B2 = 0.703064 */
-		 -21358,	/* B1 = -1.303589 */
-		 23040,		/* B0 = 0.703125 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f587 */
-		29271,		/* A1 = -1.786560 */
-		 -32599,	/* A2 = 0.994873 */
-		 -490,		/* B2 = -0.014957 */
-		 0,		/* B1 = 0.000000 */
-		 490,		/* B0 = 0.014957 */
-		 29246,		/* A1 = -1.785095 */
-		 -32700,	/* A2 = 0.997925 */
-		 28961,		/* B2 = 0.883850 */
-		 -25796,	/* B1 = -1.574463 */
-		 28961,		/* B0 = 0.883850 */
-		 29383,		/* A1 = -1.793396 */
-		 -32700,	/* A2 = 0.997955 */
-		 1299,		/* B2 = 0.039650 */
-		 -1169,		/* B1 = -0.071396 */
-		 1299,		/* B0 = 0.039650 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f590 */
-		29230,		/* A1 = -1.784058 */
-		 -32584,	/* A2 = 0.994415 */
-		 -418,		/* B2 = -0.012757 */
-		 0,		/* B1 = 0.000000 */
-		 418,		/* B0 = 0.012757 */
-		 29206,		/* A1 = -1.782593 */
-		 -32688,	/* A2 = 0.997559 */
-		 36556,		/* B2 = 1.115601 */
-		 -32478,	/* B1 = -1.982300 */
-		 36556,		/* B0 = 1.115601 */
-		 29345,		/* A1 = -1.791077 */
-		 -32688,	/* A2 = 0.997589 */
-		 897,		/* B2 = 0.027397 */
-		 -808,		/* B1 = -0.049334 */
-		 897,		/* B0 = 0.027397 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f600 */
-		29116,		/* A1 = -1.777100 */
-		 -32603,	/* A2 = 0.994965 */
-		 -165,		/* B2 = -0.005039 */
-		 0,		/* B1 = 0.000000 */
-		 165,		/* B0 = 0.005039 */
-		 29089,		/* A1 = -1.775452 */
-		 -32708,	/* A2 = 0.998199 */
-		 6963,		/* B2 = 0.212494 */
-		 -6172,		/* B1 = -0.376770 */
-		 6963,		/* B0 = 0.212494 */
-		 29237,		/* A1 = -1.784485 */
-		 -32710,	/* A2 = 0.998230 */
-		 24197,		/* B2 = 0.738464 */
-		 -21657,	/* B1 = -1.321899 */
-		 24197,		/* B0 = 0.738464 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f660 */
-		28376,		/* A1 = -1.731934 */
-		 -32567,	/* A2 = 0.993896 */
-		 -363,		/* B2 = -0.011102 */
-		 0,		/* B1 = 0.000000 */
-		 363,		/* B0 = 0.011102 */
-		 28337,		/* A1 = -1.729614 */
-		 -32683,	/* A2 = 0.997434 */
-		 21766,		/* B2 = 0.664246 */
-		 -18761,	/* B1 = -1.145081 */
-		 21766,		/* B0 = 0.664246 */
-		 28513,		/* A1 = -1.740356 */
-		 -32686,	/* A2 = 0.997498 */
-		 2509,		/* B2 = 0.076584 */
-		 -2196,		/* B1 = -0.134041 */
-		 2509,		/* B0 = 0.076584 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f700 */
-		27844,		/* A1 = -1.699463 */
-		 -32563,	/* A2 = 0.993744 */
-		 -366,		/* B2 = -0.011187 */
-		 0,		/* B1 = 0.000000 */
-		 366,		/* B0 = 0.011187 */
-		 27797,		/* A1 = -1.696655 */
-		 -32686,	/* A2 = 0.997498 */
-		 22748,		/* B2 = 0.694214 */
-		 -19235,	/* B1 = -1.174072 */
-		 22748,		/* B0 = 0.694214 */
-		 27995,		/* A1 = -1.708740 */
-		 -32688,	/* A2 = 0.997559 */
-		 2964,		/* B2 = 0.090477 */
-		 -2546,		/* B1 = -0.155449 */
-		 2964,		/* B0 = 0.090477 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f740 */
-		27297,		/* A1 = -1.666077 */
-		 -32551,	/* A2 = 0.993408 */
-		 -345,		/* B2 = -0.010540 */
-		 0,		/* B1 = 0.000000 */
-		 345,		/* B0 = 0.010540 */
-		 27240,		/* A1 = -1.662598 */
-		 -32683,	/* A2 = 0.997406 */
-		 22560,		/* B2 = 0.688477 */
-		 -18688,	/* B1 = -1.140625 */
-		 22560,		/* B0 = 0.688477 */
-		 27461,		/* A1 = -1.676147 */
-		 -32684,	/* A2 = 0.997467 */
-		 3541,		/* B2 = 0.108086 */
-		 -2985,		/* B1 = -0.182220 */
-		 3541,		/* B0 = 0.108086 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f750 */
-		27155,		/* A1 = -1.657410 */
-		 -32551,	/* A2 = 0.993408 */
-		 -462,		/* B2 = -0.014117 */
-		 0,		/* B1 = 0.000000 */
-		 462,		/* B0 = 0.014117 */
-		 27097,		/* A1 = -1.653870 */
-		 -32683,	/* A2 = 0.997406 */
-		 32495,		/* B2 = 0.991699 */
-		 -26776,	/* B1 = -1.634338 */
-		 32495,		/* B0 = 0.991699 */
-		 27321,		/* A1 = -1.667542 */
-		 -32684,	/* A2 = 0.997467 */
-		 1835,		/* B2 = 0.056007 */
-		 -1539,		/* B1 = -0.093948 */
-		 1835,		/* B0 = 0.056007 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f750_1450[] */
-		19298,		/* A1 = 1.177917 */
-		 -24471,	/* A2 = -0.746796 */
-		 -4152,		/* B2 = -0.126709 */
-		 0,		/* B1 = 0 */
-		 4152,		/* B0 = 0.126709 */
-		 12902,		/* A1 = 0.787476 */
-		 -29091,	/* A2 = -0.887817 */
-		 12491,		/* B2 = 0.38121 */
-		 -1794,		/* B1 = -0.109528 */
-		 12494,		/* B0 = 0.381317 */
-		 26291,		/* A1 = 1.604736 */
-		 -30470,	/* A2 = -0.929901 */
-		 28859,		/* B2 = 0.880737 */
-		 -26084,	/* B1 = -1.592102 */
-		 28861,		/* B0 = 0.880798 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f770 */
-		26867,		/* A1 = -1.639832 */
-		 -32551,	/* A2 = 0.993408 */
-		 -123,		/* B2 = -0.003755 */
-		 0,		/* B1 = 0.000000 */
-		 123,		/* B0 = 0.003755 */
-		 26805,		/* A1 = -1.636108 */
-		 -32683,	/* A2 = 0.997406 */
-		 17297,		/* B2 = 0.527863 */
-		 -14096,	/* B1 = -0.860382 */
-		 17297,		/* B0 = 0.527863 */
-		 27034,		/* A1 = -1.650085 */
-		 -32684,	/* A2 = 0.997467 */
-		 12958,		/* B2 = 0.395477 */
-		 -10756,	/* B1 = -0.656525 */
-		 12958,		/* B0 = 0.395477 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f800 */
-		26413,		/* A1 = -1.612122 */
-		 -32547,	/* A2 = 0.993286 */
-		 -223,		/* B2 = -0.006825 */
-		 0,		/* B1 = 0.000000 */
-		 223,		/* B0 = 0.006825 */
-		 26342,		/* A1 = -1.607849 */
-		 -32686,	/* A2 = 0.997498 */
-		 6391,		/* B2 = 0.195053 */
-		 -5120,		/* B1 = -0.312531 */
-		 6391,		/* B0 = 0.195053 */
-		 26593,		/* A1 = -1.623108 */
-		 -32688,	/* A2 = 0.997559 */
-		 23681,		/* B2 = 0.722717 */
-		 -19328,	/* B1 = -1.179688 */
-		 23681,		/* B0 = 0.722717 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f816 */
-		26168,		/* A1 = -1.597209 */
-		 -32528,	/* A2 = 0.992706 */
-		 -235,		/* B2 = -0.007182 */
-		 0,		/* B1 = 0.000000 */
-		 235,		/* B0 = 0.007182 */
-		 26092,		/* A1 = -1.592590 */
-		 -32675,	/* A2 = 0.997192 */
-		 20823,		/* B2 = 0.635498 */
-		 -16510,	/* B1 = -1.007751 */
-		 20823,		/* B0 = 0.635498 */
-		 26363,		/* A1 = -1.609070 */
-		 -32677,	/* A2 = 0.997253 */
-		 6739,		/* B2 = 0.205688 */
-		 -5459,		/* B1 = -0.333206 */
-		 6739,		/* B0 = 0.205688 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f850 */
-		25641,		/* A1 = -1.565063 */
-		 -32536,	/* A2 = 0.992950 */
-		 -121,		/* B2 = -0.003707 */
-		 0,		/* B1 = 0.000000 */
-		 121,		/* B0 = 0.003707 */
-		 25560,		/* A1 = -1.560059 */
-		 -32684,	/* A2 = 0.997437 */
-		 18341,		/* B2 = 0.559753 */
-		 -14252,	/* B1 = -0.869904 */
-		 18341,		/* B0 = 0.559753 */
-		 25837,		/* A1 = -1.577026 */
-		 -32684,	/* A2 = 0.997467 */
-		 16679,		/* B2 = 0.509003 */
-		 -13232,	/* B1 = -0.807648 */
-		 16679,		/* B0 = 0.509003 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f857_1645[] */
-		16415,		/* A1 = 1.001953 */
-		 -23669,	/* A2 = -0.722321 */
-		 -4549,		/* B2 = -0.138847 */
-		 0,		/* B1 = 0 */
-		 4549,		/* B0 = 0.138847 */
-		 8456,		/* A1 = 0.516174 */
-		 -28996,	/* A2 = -0.884918 */
-		 13753,		/* B2 = 0.419724 */
-		 -12,		/* B1 = -0.000763 */
-		 13757,		/* B0 = 0.419846 */
-		 24632,		/* A1 = 1.503418 */
-		 -30271,	/* A2 = -0.923828 */
-		 29070,		/* B2 = 0.887146 */
-		 -25265,	/* B1 = -1.542114 */
-		 29073,		/* B0 = 0.887268 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f900 */
-		24806,		/* A1 = -1.514099 */
-		 -32501,	/* A2 = 0.991852 */
-		 -326,		/* B2 = -0.009969 */
-		 0,		/* B1 = 0.000000 */
-		 326,		/* B0 = 0.009969 */
-		 24709,		/* A1 = -1.508118 */
-		 -32659,	/* A2 = 0.996674 */
-		 20277,		/* B2 = 0.618835 */
-		 -15182,	/* B1 = -0.926636 */
-		 20277,		/* B0 = 0.618835 */
-		 25022,		/* A1 = -1.527222 */
-		 -32661,	/* A2 = 0.996735 */
-		 4320,		/* B2 = 0.131836 */
-		 -3331,		/* B1 = -0.203339 */
-		 4320,		/* B0 = 0.131836 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f900_1300[] */
-		19776,		/* A1 = 1.207092 */
-		 -27437,	/* A2 = -0.837341 */
-		 -2666,		/* B2 = -0.081371 */
-		 0,		/* B1 = 0 */
-		 2666,		/* B0 = 0.081371 */
-		 16302,		/* A1 = 0.995026 */
-		 -30354,	/* A2 = -0.926361 */
-		 10389,		/* B2 = 0.317062 */
-		 -3327,		/* B1 = -0.203064 */
-		 10389,		/* B0 = 0.317062 */
-		 24299,		/* A1 = 1.483154 */
-		 -30930,	/* A2 = -0.943909 */
-		 25016,		/* B2 = 0.763428 */
-		 -21171,	/* B1 = -1.292236 */
-		 25016,		/* B0 = 0.763428 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f935_1215[] */
-		20554,		/* A1 = 1.254517 */
-		 -28764,	/* A2 = -0.877838 */
-		 -2048,		/* B2 = -0.062515 */
-		 0,		/* B1 = 0 */
-		 2048,		/* B0 = 0.062515 */
-		 18209,		/* A1 = 1.11145 */
-		 -30951,	/* A2 = -0.94458 */
-		 9390,		/* B2 = 0.286575 */
-		 -3955,		/* B1 = -0.241455 */
-		 9390,		/* B0 = 0.286575 */
-		 23902,		/* A1 = 1.458923 */
-		 -31286,	/* A2 = -0.954803 */
-		 23252,		/* B2 = 0.709595 */
-		 -19132,	/* B1 = -1.167725 */
-		 23252,		/* B0 = 0.709595 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f941_1477[] */
-		17543,		/* A1 = 1.07074 */
-		 -26220,	/* A2 = -0.800201 */
-		 -3298,		/* B2 = -0.100647 */
-		 0,		/* B1 = 0 */
-		 3298,		/* B0 = 0.100647 */
-		 12423,		/* A1 = 0.75827 */
-		 -30036,	/* A2 = -0.916626 */
-		 12651,		/* B2 = 0.386078 */
-		 -2444,		/* B1 = -0.14917 */
-		 12653,		/* B0 = 0.386154 */
-		 23518,		/* A1 = 1.435425 */
-		 -30745,	/* A2 = -0.938293 */
-		 27282,		/* B2 = 0.832581 */
-		 -22529,	/* B1 = -1.375122 */
-		 27286,		/* B0 = 0.832703 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f942 */
-		24104,		/* A1 = -1.471252 */
-		 -32507,	/* A2 = 0.992065 */
-		 -351,		/* B2 = -0.010722 */
-		 0,		/* B1 = 0.000000 */
-		 351,		/* B0 = 0.010722 */
-		 23996,		/* A1 = -1.464600 */
-		 -32671,	/* A2 = 0.997040 */
-		 22848,		/* B2 = 0.697266 */
-		 -16639,	/* B1 = -1.015564 */
-		 22848,		/* B0 = 0.697266 */
-		 24332,		/* A1 = -1.485168 */
-		 -32673,	/* A2 = 0.997101 */
-		 4906,		/* B2 = 0.149727 */
-		 -3672,		/* B1 = -0.224174 */
-		 4906,		/* B0 = 0.149727 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f950 */
-		23967,		/* A1 = -1.462830 */
-		 -32507,	/* A2 = 0.992065 */
-		 -518,		/* B2 = -0.015821 */
-		 0,		/* B1 = 0.000000 */
-		 518,		/* B0 = 0.015821 */
-		 23856,		/* A1 = -1.456055 */
-		 -32671,	/* A2 = 0.997040 */
-		 26287,		/* B2 = 0.802246 */
-		 -19031,	/* B1 = -1.161560 */
-		 26287,		/* B0 = 0.802246 */
-		 24195,		/* A1 = -1.476746 */
-		 -32673,	/* A2 = 0.997101 */
-		 2890,		/* B2 = 0.088196 */
-		 -2151,		/* B1 = -0.131317 */
-		 2890,		/* B0 = 0.088196 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f950_1400[] */
-		18294,		/* A1 = 1.116638 */
-		 -26962,	/* A2 = -0.822845 */
-		 -2914,		/* B2 = -0.088936 */
-		 0,		/* B1 = 0 */
-		 2914,		/* B0 = 0.088936 */
-		 14119,		/* A1 = 0.861786 */
-		 -30227,	/* A2 = -0.922455 */
-		 11466,		/* B2 = 0.349945 */
-		 -2833,		/* B1 = -0.172943 */
-		 11466,		/* B0 = 0.349945 */
-		 23431,		/* A1 = 1.430115 */
-		 -30828,	/* A2 = -0.940796 */
-		 25331,		/* B2 = 0.773071 */
-		 -20911,	/* B1 = -1.276367 */
-		 25331,		/* B0 = 0.773071 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f975 */
-		23521,		/* A1 = -1.435608 */
-		 -32489,	/* A2 = 0.991516 */
-		 -193,		/* B2 = -0.005915 */
-		 0,		/* B1 = 0.000000 */
-		 193,		/* B0 = 0.005915 */
-		 23404,		/* A1 = -1.428467 */
-		 -32655,	/* A2 = 0.996582 */
-		 17740,		/* B2 = 0.541412 */
-		 -12567,	/* B1 = -0.767029 */
-		 17740,		/* B0 = 0.541412 */
-		 23753,		/* A1 = -1.449829 */
-		 -32657,	/* A2 = 0.996613 */
-		 9090,		/* B2 = 0.277405 */
-		 -6662,		/* B1 = -0.406647 */
-		 9090,		/* B0 = 0.277405 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1000 */
-		23071,		/* A1 = -1.408203 */
-		 -32489,	/* A2 = 0.991516 */
-		 -293,		/* B2 = -0.008965 */
-		 0,		/* B1 = 0.000000 */
-		 293,		/* B0 = 0.008965 */
-		 22951,		/* A1 = -1.400818 */
-		 -32655,	/* A2 = 0.996582 */
-		 5689,		/* B2 = 0.173645 */
-		 -3951,		/* B1 = -0.241150 */
-		 5689,		/* B0 = 0.173645 */
-		 23307,		/* A1 = -1.422607 */
-		 -32657,	/* A2 = 0.996613 */
-		 18692,		/* B2 = 0.570435 */
-		 -13447,	/* B1 = -0.820770 */
-		 18692,		/* B0 = 0.570435 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1020 */
-		22701,		/* A1 = -1.385620 */
-		 -32474,	/* A2 = 0.991058 */
-		 -292,		/* B2 = -0.008933 */
-		 0,		/*163840      , B1 = 10.000000 */
-		 292,		/* B0 = 0.008933 */
-		 22564,		/* A1 = -1.377258 */
-		 -32655,	/* A2 = 0.996552 */
-		 20756,		/* B2 = 0.633423 */
-		 -14176,	/* B1 = -0.865295 */
-		 20756,		/* B0 = 0.633423 */
-		 22960,		/* A1 = -1.401428 */
-		 -32657,	/* A2 = 0.996613 */
-		 6520,		/* B2 = 0.198990 */
-		 -4619,		/* B1 = -0.281937 */
-		 6520,		/* B0 = 0.198990 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1050 */
-		22142,		/* A1 = -1.351501 */
-		 -32474,	/* A2 = 0.991058 */
-		 -147,		/* B2 = -0.004493 */
-		 0,		/* B1 = 0.000000 */
-		 147,		/* B0 = 0.004493 */
-		 22000,		/* A1 = -1.342834 */
-		 -32655,	/* A2 = 0.996552 */
-		 15379,		/* B2 = 0.469360 */
-		 -10237,	/* B1 = -0.624847 */
-		 15379,		/* B0 = 0.469360 */
-		 22406,		/* A1 = -1.367554 */
-		 -32657,	/* A2 = 0.996613 */
-		 17491,		/* B2 = 0.533783 */
-		 -12096,	/* B1 = -0.738312 */
-		 17491,		/* B0 = 0.533783 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1100_1750[] */
-		12973,		/* A1 = 0.79184 */
-		 -24916,	/* A2 = -0.760376 */
-		 6655,		/* B2 = 0.203102 */
-		 367,		/* B1 = 0.0224 */
-		 6657,		/* B0 = 0.203171 */
-		 5915,		/* A1 = 0.361053 */
-		 -29560,	/* A2 = -0.90213 */
-		 -7777,		/* B2 = -0.23735 */
-		 0,		/* B1 = 0 */
-		 7777,		/* B0 = 0.23735 */
-		 20510,		/* A1 = 1.251892 */
-		 -30260,	/* A2 = -0.923462 */
-		 26662,		/* B2 = 0.81366 */
-		 -20573,	/* B1 = -1.255737 */
-		 26668,		/* B0 = 0.813843 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1140 */
-		20392,		/* A1 = -1.244629 */
-		 -32460,	/* A2 = 0.990601 */
-		 -270,		/* B2 = -0.008240 */
-		 0,		/* B1 = 0.000000 */
-		 270,		/* B0 = 0.008240 */
-		 20218,		/* A1 = -1.234009 */
-		 -32655,	/* A2 = 0.996582 */
-		 21337,		/* B2 = 0.651154 */
-		 -13044,	/* B1 = -0.796143 */
-		 21337,		/* B0 = 0.651154 */
-		 20684,		/* A1 = -1.262512 */
-		 -32657,	/* A2 = 0.996643 */
-		 8572,		/* B2 = 0.261612 */
-		 -5476,		/* B1 = -0.334244 */
-		 8572,		/* B0 = 0.261612 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1200 */
-		19159,		/* A1 = -1.169373 */
-		 -32456,	/* A2 = 0.990509 */
-		 -335,		/* B2 = -0.010252 */
-		 0,		/* B1 = 0.000000 */
-		 335,		/* B0 = 0.010252 */
-		 18966,		/* A1 = -1.157593 */
-		 -32661,	/* A2 = 0.996735 */
-		 6802,		/* B2 = 0.207588 */
-		 -3900,		/* B1 = -0.238098 */
-		 6802,		/* B0 = 0.207588 */
-		 19467,		/* A1 = -1.188232 */
-		 -32661,	/* A2 = 0.996765 */
-		 25035,		/* B2 = 0.764008 */
-		 -15049,	/* B1 = -0.918579 */
-		 25035,		/* B0 = 0.764008 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1209 */
-		18976,		/* A1 = -1.158264 */
-		 -32439,	/* A2 = 0.989990 */
-		 -183,		/* B2 = -0.005588 */
-		 0,		/* B1 = 0.000000 */
-		 183,		/* B0 = 0.005588 */
-		 18774,		/* A1 = -1.145874 */
-		 -32650,	/* A2 = 0.996429 */
-		 15468,		/* B2 = 0.472076 */
-		 -8768,		/* B1 = -0.535217 */
-		 15468,		/* B0 = 0.472076 */
-		 19300,		/* A1 = -1.177979 */
-		 -32652,	/* A2 = 0.996490 */
-		 19840,		/* B2 = 0.605499 */
-		 -11842,	/* B1 = -0.722809 */
-		 19840,		/* B0 = 0.605499 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1330 */
-		16357,		/* A1 = -0.998413 */
-		 -32368,	/* A2 = 0.987793 */
-		 -217,		/* B2 = -0.006652 */
-		 0,		/* B1 = 0.000000 */
-		 217,		/* B0 = 0.006652 */
-		 16107,		/* A1 = -0.983126 */
-		 -32601,	/* A2 = 0.994904 */
-		 11602,		/* B2 = 0.354065 */
-		 -5555,		/* B1 = -0.339111 */
-		 11602,		/* B0 = 0.354065 */
-		 16722,		/* A1 = -1.020630 */
-		 -32603,	/* A2 = 0.994965 */
-		 15574,		/* B2 = 0.475311 */
-		 -8176,		/* B1 = -0.499069 */
-		 15574,		/* B0 = 0.475311 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1336 */
-		16234,		/* A1 = -0.990875 */
-		 32404,		/* A2 = -0.988922 */
-		 -193,		/* B2 = -0.005908 */
-		 0,		/* B1 = 0.000000 */
-		 193,		/* B0 = 0.005908 */
-		 15986,		/* A1 = -0.975769 */
-		 -32632,	/* A2 = 0.995880 */
-		 18051,		/* B2 = 0.550903 */
-		 -8658,		/* B1 = -0.528473 */
-		 18051,		/* B0 = 0.550903 */
-		 16591,		/* A1 = -1.012695 */
-		 -32634,	/* A2 = 0.995941 */
-		 15736,		/* B2 = 0.480240 */
-		 -8125,		/* B1 = -0.495926 */
-		 15736,		/* B0 = 0.480240 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1366 */
-		15564,		/* A1 = -0.949982 */
-		 -32404,	/* A2 = 0.988922 */
-		 -269,		/* B2 = -0.008216 */
-		 0,		/* B1 = 0.000000 */
-		 269,		/* B0 = 0.008216 */
-		 15310,		/* A1 = -0.934479 */
-		 -32632,	/* A2 = 0.995880 */
-		 10815,		/* B2 = 0.330063 */
-		 -4962,		/* B1 = -0.302887 */
-		 10815,		/* B0 = 0.330063 */
-		 15924,		/* A1 = -0.971924 */
-		 -32634,	/* A2 = 0.995941 */
-		 18880,		/* B2 = 0.576172 */
-		 -9364,		/* B1 = -0.571594 */
-		 18880,		/* B0 = 0.576172 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1380 */
-		15247,		/* A1 = -0.930603 */
-		 -32397,	/* A2 = 0.988708 */
-		 -244,		/* B2 = -0.007451 */
-		 0,		/* B1 = 0.000000 */
-		 244,		/* B0 = 0.007451 */
-		 14989,		/* A1 = -0.914886 */
-		 -32627,	/* A2 = 0.995697 */
-		 18961,		/* B2 = 0.578644 */
-		 -8498,		/* B1 = -0.518707 */
-		 18961,		/* B0 = 0.578644 */
-		 15608,		/* A1 = -0.952667 */
-		 -32628,	/* A2 = 0.995758 */
-		 11145,		/* B2 = 0.340134 */
-		 -5430,		/* B1 = -0.331467 */
-		 11145,		/* B0 = 0.340134 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1400 */
-		14780,		/* A1 = -0.902130 */
-		 -32393,	/* A2 = 0.988586 */
-		 -396,		/* B2 = -0.012086 */
-		 0,		/* B1 = 0.000000 */
-		 396,		/* B0 = 0.012086 */
-		 14510,		/* A1 = -0.885651 */
-		 -32630,	/* A2 = 0.995819 */
-		 6326,		/* B2 = 0.193069 */
-		 -2747,		/* B1 = -0.167671 */
-		 6326,		/* B0 = 0.193069 */
-		 15154,		/* A1 = -0.924957 */
-		 -32632,	/* A2 = 0.995850 */
-		 23235,		/* B2 = 0.709076 */
-		 -10983,	/* B1 = -0.670380 */
-		 23235,		/* B0 = 0.709076 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1477 */
-		13005,		/* A1 = -0.793793 */
-		 -32368,	/* A2 = 0.987823 */
-		 -500,		/* B2 = -0.015265 */
-		 0,		/* B1 = 0.000000 */
-		 500,		/* B0 = 0.015265 */
-		 12708,		/* A1 = -0.775665 */
-		 -32615,	/* A2 = 0.995331 */
-		 11420,		/* B2 = 0.348526 */
-		 -4306,		/* B1 = -0.262833 */
-		 11420,		/* B0 = 0.348526 */
-		 13397,		/* A1 = -0.817688 */
-		 -32615,	/* A2 = 0.995361 */
-		 9454,		/* B2 = 0.288528 */
-		 -3981,		/* B1 = -0.243027 */
-		 9454,		/* B0 = 0.288528 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1600 */
-		10046,		/* A1 = -0.613190 */
-		 -32331,	/* A2 = 0.986694 */
-		 -455,		/* B2 = -0.013915 */
-		 0,		/* B1 = 0.000000 */
-		 455,		/* B0 = 0.013915 */
-		 9694,		/* A1 = -0.591705 */
-		 -32601,	/* A2 = 0.994934 */
-		 6023,		/* B2 = 0.183815 */
-		 -1708,		/* B1 = -0.104279 */
-		 6023,		/* B0 = 0.183815 */
-		 10478,		/* A1 = -0.639587 */
-		 -32603,	/* A2 = 0.994965 */
-		 22031,		/* B2 = 0.672333 */
-		 -7342,		/* B1 = -0.448151 */
-		 22031,		/* B0 = 0.672333 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1633_1638[] */
-		9181,		/* A1 = 0.560394 */
-		 -32256,	/* A2 = -0.984375 */
-		 -556,		/* B2 = -0.016975 */
-		 0,		/* B1 = 0 */
-		 556,		/* B0 = 0.016975 */
-		 8757,		/* A1 = 0.534515 */
-		 -32574,	/* A2 = -0.99408 */
-		 8443,		/* B2 = 0.25769 */
-		 -2135,		/* B1 = -0.130341 */
-		 8443,		/* B0 = 0.25769 */
-		 9691,		/* A1 = 0.591522 */
-		 -32574,	/* A2 = -0.99411 */
-		 15446,		/* B2 = 0.471375 */
-		 -4809,		/* B1 = -0.293579 */
-		 15446,		/* B0 = 0.471375 */
-		 7,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1800 */
-		5076,		/* A1 = -0.309875 */
-		 -32304,	/* A2 = 0.985840 */
-		 -508,		/* B2 = -0.015503 */
-		 0,		/* B1 = 0.000000 */
-		 508,		/* B0 = 0.015503 */
-		 4646,		/* A1 = -0.283600 */
-		 -32605,	/* A2 = 0.995026 */
-		 6742,		/* B2 = 0.205780 */
-		 -878,		/* B1 = -0.053635 */
-		 6742,		/* B0 = 0.205780 */
-		 5552,		/* A1 = -0.338928 */
-		 -32605,	/* A2 = 0.995056 */
-		 23667,		/* B2 = 0.722260 */
-		 -4297,		/* B1 = -0.262329 */
-		 23667,		/* B0 = 0.722260 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-	{			/* f1860 */
-		3569,		/* A1 = -0.217865 */
-		 -32292,	/* A2 = 0.985504 */
-		 -239,		/* B2 = -0.007322 */
-		 0,		/* B1 = 0.000000 */
-		 239,		/* B0 = 0.007322 */
-		 3117,		/* A1 = -0.190277 */
-		 -32603,	/* A2 = 0.994965 */
-		 18658,		/* B2 = 0.569427 */
-		 -1557,		/* B1 = -0.095032 */
-		 18658,		/* B0 = 0.569427 */
-		 4054,		/* A1 = -0.247437 */
-		 -32603,	/* A2 = 0.994965 */
-		 18886,		/* B2 = 0.576385 */
-		 -2566,		/* B1 = -0.156647 */
-		 18886,		/* B0 = 0.576385 */
-		 5,		/* Internal filter scaling */
-		 159,		/* Minimum in-band energy threshold */
-		 21,		/* 21/32 in-band to broad-band ratio */
-		 0x0FF5		/* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
-	},
-};
-static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
-{
-	unsigned short cmd;
-	int cnt, max;
-
-	if (jf->filter > 3) {
-		return -1;
-	}
-	if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))	/* Select Filter */
-
-		return -1;
-	if (!jf->enable) {
-		if (ixj_WriteDSPCommand(0x5152, j))		/* Disable Filter */
-
-			return -1;
-		else
-			return 0;
-	} else {
-		if (ixj_WriteDSPCommand(0x5153, j))		/* Enable Filter */
-
-			return -1;
-		/* Select the filter (f0 - f3) to use. */
-		if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))
-			return -1;
-	}
-	if (jf->freq < 12 && jf->freq > 3) {
-		/* Select the frequency for the selected filter. */
-		if (ixj_WriteDSPCommand(0x5170 + jf->freq, j))
-			return -1;
-	} else if (jf->freq > 11) {
-		/* We need to load a programmable filter set for undefined */
-		/* frequencies.  So we will point the filter to a programmable set. */
-		/* Since there are only 4 filters and 4 programmable sets, we will */
-		/* just point the filter to the same number set and program it for the */
-		/* frequency we want. */
-		if (ixj_WriteDSPCommand(0x5170 + jf->filter, j))
-			return -1;
-		if (j->ver.low != 0x12) {
-			cmd = 0x515B;
-			max = 19;
-		} else {
-			cmd = 0x515E;
-			max = 15;
-		}
-		if (ixj_WriteDSPCommand(cmd, j))
-			return -1;
-		for (cnt = 0; cnt < max; cnt++) {
-			if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j))
-				return -1;
-		}
-	}
-	j->filter_en[jf->filter] = jf->enable;
-	return 0;
-}
-
-static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr)
-{
-	unsigned short cmd;
-	int cnt, max;
-	if (jfr->filter > 3) {
-		return -1;
-	}
-	if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))	/* Select Filter */
-		return -1;
-
-	if (!jfr->enable) {
-		if (ixj_WriteDSPCommand(0x5152, j))		/* Disable Filter */
-			return -1;
-		else
-			return 0;
-	} else {
-		if (ixj_WriteDSPCommand(0x5153, j))		/* Enable Filter */
-			return -1;
-		/* Select the filter (f0 - f3) to use. */
-		if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))
-			return -1;
-	}
-	/* We need to load a programmable filter set for undefined */
-	/* frequencies.  So we will point the filter to a programmable set. */
-	/* Since there are only 4 filters and 4 programmable sets, we will */
-	/* just point the filter to the same number set and program it for the */
-	/* frequency we want. */
-	if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j))
-		return -1;
-	if (j->ver.low != 0x12) {
-		cmd = 0x515B;
-		max = 19;
-	} else {
-		cmd = 0x515E;
-		max = 15;
-	}
-	if (ixj_WriteDSPCommand(cmd, j))
-		return -1;
-	for (cnt = 0; cnt < max; cnt++) {
-		if (ixj_WriteDSPCommand(jfr->coeff[cnt], j))
-			return -1;
-	}
-	j->filter_en[jfr->filter] = jfr->enable;
-	return 0;
-}
-
-static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
-{
-	int freq0, freq1;
-	unsigned short data;
-	if (ti->freq0) {
-		freq0 = ti->freq0;
-	} else {
-		freq0 = 0x7FFF;
-	}
-
-	if (ti->freq1) {
-		freq1 = ti->freq1;
-	} else {
-		freq1 = 0x7FFF;
-	}
-
-	if(ti->tone_index > 12 && ti->tone_index < 28)
-	{
-		if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j))
-			return -1;
-		if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j))
-			return -1;
-		data = freq0;
-		if (ixj_WriteDSPCommand(data, j))
-			return -1;
-		data = freq1;
-		if (ixj_WriteDSPCommand(data, j))
-			return -1;
-	}
-	return freq0;
-}
-
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
deleted file mode 100644
index 2c84113..0000000
--- a/drivers/telephony/ixj.h
+++ /dev/null
@@ -1,1322 +0,0 @@
-/******************************************************************************
- *    ixj.h
- *
- *
- * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
- * including the Internet PhoneJACK, Internet PhoneJACK Lite,
- * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
- * SmartCABLE
- *
- *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
- *
- *    This program is free software; you can redistribute it and/or
- *    modify it under the terms of the GNU General Public License
- *    as published by the Free Software Foundation; either version
- *    2 of the License, or (at your option) any later version.
- *
- * Author:          Ed Okerson, <eokerson@quicknet.net>
- *    
- * Contributors:    Greg Herlein, <gherlein@quicknet.net>
- *                  David W. Erhart, <derhart@quicknet.net>
- *                  John Sellers, <jsellers@quicknet.net>
- *                  Mike Preston, <mpreston@quicknet.net>
- *
- * More information about the hardware related to this driver can be found
- * at our website:    http://www.quicknet.net
- *
- * Fixes:
- *
- * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION 
- * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- *****************************************************************************/
-#define IXJ_VERSION 3031
-
-#include <linux/types.h>
-
-#include <linux/ixjuser.h>
-#include <linux/phonedev.h>
-
-typedef __u16 WORD;
-typedef __u32 DWORD;
-typedef __u8 BYTE;
-
-#ifndef IXJMAX
-#define IXJMAX 16
-#endif
-
-/******************************************************************************
-*
-*  This structure when unioned with the structures below makes simple byte
-*  access to the registers easier.
-*
-******************************************************************************/
-typedef struct {
-	unsigned char low;
-	unsigned char high;
-} BYTES;
-
-typedef union {
-        BYTES bytes;
-        short word;
-} IXJ_WORD;
-
-typedef struct{
-	unsigned int b0:1;
-	unsigned int b1:1;
-	unsigned int b2:1;
-	unsigned int b3:1;
-	unsigned int b4:1;
-	unsigned int b5:1;
-	unsigned int b6:1;
-	unsigned int b7:1;
-} IXJ_CBITS;
-
-typedef union{
-	IXJ_CBITS cbits;
-	  char  cbyte;
-} IXJ_CBYTE;
-
-/******************************************************************************
-*
-*  This structure represents the Hardware Control Register of the CT8020/8021
-*  The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
-*  Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
-	unsigned int rxrdy:1;
-	unsigned int txrdy:1;
-	unsigned int status:1;
-	unsigned int auxstatus:1;
-	unsigned int rxdma:1;
-	unsigned int txdma:1;
-	unsigned int rxburst:1;
-	unsigned int txburst:1;
-	unsigned int dmadir:1;
-	unsigned int cont:1;
-	unsigned int irqn:1;
-	unsigned int t:5;
-} HCRBIT;
-
-typedef union {
-	HCRBIT bits;
-	BYTES bytes;
-} HCR;
-
-/******************************************************************************
-*
-*  This structure represents the Hardware Status Register of the CT8020/8021
-*  The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
-*  Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
-	unsigned int controlrdy:1;
-	unsigned int auxctlrdy:1;
-	unsigned int statusrdy:1;
-	unsigned int auxstatusrdy:1;
-	unsigned int rxrdy:1;
-	unsigned int txrdy:1;
-	unsigned int restart:1;
-	unsigned int irqn:1;
-	unsigned int rxdma:1;
-	unsigned int txdma:1;
-	unsigned int cohostshutdown:1;
-	unsigned int t:5;
-} HSRBIT;
-
-typedef union {
-	HSRBIT bits;
-	BYTES bytes;
-} HSR;
-
-/******************************************************************************
-*
-*  This structure represents the General Purpose IO Register of the CT8020/8021
-*  The CT8020 is used in the Internet PhoneJACK, and the 8021 in the
-*  Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
-	unsigned int x:1;
-	unsigned int gpio1:1;
-	unsigned int gpio2:1;
-	unsigned int gpio3:1;
-	unsigned int gpio4:1;
-	unsigned int gpio5:1;
-	unsigned int gpio6:1;
-	unsigned int gpio7:1;
-	unsigned int xread:1;
-	unsigned int gpio1read:1;
-	unsigned int gpio2read:1;
-	unsigned int gpio3read:1;
-	unsigned int gpio4read:1;
-	unsigned int gpio5read:1;
-	unsigned int gpio6read:1;
-	unsigned int gpio7read:1;
-} GPIOBIT;
-
-typedef union {
-	GPIOBIT bits;
-	BYTES bytes;
-	unsigned short word;
-} GPIO;
-
-/******************************************************************************
-*
-*  This structure represents the Line Monitor status response
-*
-******************************************************************************/
-typedef struct {
-	unsigned int digit:4;
-	unsigned int cpf_valid:1;
-	unsigned int dtmf_valid:1;
-	unsigned int peak:1;
-	unsigned int z:1;
-	unsigned int f0:1;
-	unsigned int f1:1;
-	unsigned int f2:1;
-	unsigned int f3:1;
-	unsigned int frame:4;
-} LMON;
-
-typedef union {
-	LMON bits;
-	BYTES bytes;
-} DTMF;
-
-typedef struct {
-	unsigned int z:7;
-	unsigned int dtmf_en:1;
-	unsigned int y:4;
-	unsigned int F3:1;
-	unsigned int F2:1;
-	unsigned int F1:1;
-	unsigned int F0:1;
-} CP;
-
-typedef union {
-	CP bits;
-	BYTES bytes;
-} CPTF;
-
-/******************************************************************************
-*
-*  This structure represents the Status Control Register on the Internet
-*  LineJACK
-*
-******************************************************************************/
-typedef struct {
-	unsigned int c0:1;
-	unsigned int c1:1;
-	unsigned int stereo:1;
-	unsigned int daafsyncen:1;
-	unsigned int led1:1;
-	unsigned int led2:1;
-	unsigned int led3:1;
-	unsigned int led4:1;
-} PSCRWI;			/* Internet LineJACK and Internet PhoneJACK Lite */
-
-typedef struct {
-	unsigned int eidp:1;
-	unsigned int eisd:1;
-	unsigned int x:6;
-} PSCRWP;			/* Internet PhoneJACK PCI */
-
-typedef union {
-	PSCRWI bits;
-	PSCRWP pcib;
-	char byte;
-} PLD_SCRW;
-
-typedef struct {
-	unsigned int c0:1;
-	unsigned int c1:1;
-	unsigned int x:1;
-	unsigned int d0ee:1;
-	unsigned int mixerbusy:1;
-	unsigned int sci:1;
-	unsigned int dspflag:1;
-	unsigned int daaflag:1;
-} PSCRRI;
-
-typedef struct {
-	unsigned int eidp:1;
-	unsigned int eisd:1;
-	unsigned int x:4;
-	unsigned int dspflag:1;
-	unsigned int det:1;
-} PSCRRP;
-
-typedef union {
-	PSCRRI bits;
-	PSCRRP pcib;
-	char byte;
-} PLD_SCRR;
-
-/******************************************************************************
-*
-*  These structures represents the SLIC Control Register on the
-*  Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
-	unsigned int c1:1;
-	unsigned int c2:1;
-	unsigned int c3:1;
-	unsigned int b2en:1;
-	unsigned int spken:1;
-	unsigned int rly1:1;
-	unsigned int rly2:1;
-	unsigned int rly3:1;
-} PSLICWRITE;
-
-typedef struct {
-	unsigned int state:3;
-	unsigned int b2en:1;
-	unsigned int spken:1;
-	unsigned int c3:1;
-	unsigned int potspstn:1;
-	unsigned int det:1;
-} PSLICREAD;
-
-typedef struct {
-	unsigned int c1:1;
-	unsigned int c2:1;
-	unsigned int c3:1;
-	unsigned int b2en:1;
-	unsigned int e1:1;
-	unsigned int mic:1;
-	unsigned int spk:1;
-	unsigned int x:1;
-} PSLICPCI;
-
-typedef union {
-	PSLICPCI pcib;
-	PSLICWRITE bits;
-	PSLICREAD slic;
-	char byte;
-} PLD_SLICW;
-
-typedef union {
-	PSLICPCI pcib;
-	PSLICREAD bits;
-	char byte;
-} PLD_SLICR;
-
-/******************************************************************************
-*
-*  These structures represents the Clock Control Register on the
-*  Internet LineJACK
-*
-******************************************************************************/
-typedef struct {
-	unsigned int clk0:1;
-	unsigned int clk1:1;
-	unsigned int clk2:1;
-	unsigned int x0:1;
-	unsigned int slic_e1:1;
-	unsigned int x1:1;
-	unsigned int x2:1;
-	unsigned int x3:1;
-} PCLOCK;
-
-typedef union {
-	PCLOCK bits;
-	char byte;
-} PLD_CLOCK;
-
-/******************************************************************************
-*
-*  These structures deal with the mixer on the Internet LineJACK
-*
-******************************************************************************/
-
-typedef struct {
-	unsigned short vol[10];
-	unsigned int recsrc;
-	unsigned int modcnt;
-	unsigned short micpreamp;
-} MIX;
-
-/******************************************************************************
-*
-*  These structures deal with the control logic on the Internet PhoneCARD
-*
-******************************************************************************/
-typedef struct {
-	unsigned int x0:4;	/* unused bits */
-
-	unsigned int ed:1;	/* Event Detect */
-
-	unsigned int drf:1;	/* SmartCABLE Removal Flag 1=no cable */
-
-	unsigned int dspf:1;	/* DSP Flag 1=DSP Ready */
-
-	unsigned int crr:1;	/* Control Register Ready */
-
-} COMMAND_REG1;
-
-typedef union {
-	COMMAND_REG1 bits;
-	unsigned char byte;
-} PCMCIA_CR1;
-
-typedef struct {
-	unsigned int x0:4;	/* unused bits */
-
-	unsigned int rstc:1;	/* SmartCABLE Reset */
-
-	unsigned int pwr:1;	/* SmartCABLE Power */
-
-	unsigned int x1:2;	/* unused bits */
-
-} COMMAND_REG2;
-
-typedef union {
-	COMMAND_REG2 bits;
-	unsigned char byte;
-} PCMCIA_CR2;
-
-typedef struct {
-	unsigned int addr:5;	/* R/W SmartCABLE Register Address */
-
-	unsigned int rw:1;	/* Read / Write flag */
-
-	unsigned int dev:2;	/* 2 bit SmartCABLE Device Address */
-
-} CONTROL_REG;
-
-typedef union {
-	CONTROL_REG bits;
-	unsigned char byte;
-} PCMCIA_SCCR;
-
-typedef struct {
-	unsigned int hsw:1;
-	unsigned int det:1;
-	unsigned int led2:1;
-	unsigned int led1:1;
-	unsigned int ring1:1;
-	unsigned int ring0:1;
-	unsigned int x:1;
-	unsigned int powerdown:1;
-} PCMCIA_SLIC_REG;
-
-typedef union {
-	PCMCIA_SLIC_REG bits;
-	unsigned char byte;
-} PCMCIA_SLIC;
-
-typedef struct {
-	unsigned int cpd:1;	/* Chip Power Down */
-
-	unsigned int mpd:1;	/* MIC Bias Power Down */
-
-	unsigned int hpd:1;	/* Handset Drive Power Down */
-
-	unsigned int lpd:1;	/* Line Drive Power Down */
-
-	unsigned int spd:1;	/* Speaker Drive Power Down */
-
-	unsigned int x:2;	/* unused bits */
-
-	unsigned int sr:1;	/* Software Reset */
-
-} Si3CONTROL1;
-
-typedef union {
-	Si3CONTROL1 bits;
-	unsigned char byte;
-} Si3C1;
-
-typedef struct {
-	unsigned int al:1;	/* Analog Loopback DAC analog -> ADC analog */
-
-	unsigned int dl2:1;	/* Digital Loopback DAC -> ADC one bit */
-
-	unsigned int dl1:1;	/* Digital Loopback ADC -> DAC one bit */
-
-	unsigned int pll:1;	/* 1 = div 10, 0 = div 5 */
-
-	unsigned int hpd:1;	/* HPF disable */
-
-	unsigned int x:3;	/* unused bits */
-
-} Si3CONTROL2;
-
-typedef union {
-	Si3CONTROL2 bits;
-	unsigned char byte;
-} Si3C2;
-
-typedef struct {
-	unsigned int iir:1;	/* 1 enables IIR, 0 enables FIR */
-
-	unsigned int him:1;	/* Handset Input Mute */
-
-	unsigned int mcm:1;	/* MIC In Mute */
-
-	unsigned int mcg:2;	/* MIC In Gain */
-
-	unsigned int lim:1;	/* Line In Mute */
-
-	unsigned int lig:2;	/* Line In Gain */
-
-} Si3RXGAIN;
-
-typedef union {
-	Si3RXGAIN bits;
-	unsigned char byte;
-} Si3RXG;
-
-typedef struct {
-	unsigned int hom:1;	/* Handset Out Mute */
-
-	unsigned int lom:1;	/* Line Out Mute */
-
-	unsigned int rxg:5;	/* RX PGA Gain */
-
-	unsigned int x:1;	/* unused bit */
-
-} Si3ADCVOLUME;
-
-typedef union {
-	Si3ADCVOLUME bits;
-	unsigned char byte;
-} Si3ADC;
-
-typedef struct {
-	unsigned int srm:1;	/* Speaker Right Mute */
-
-	unsigned int slm:1;	/* Speaker Left Mute */
-
-	unsigned int txg:5;	/* TX PGA Gain */
-
-	unsigned int x:1;	/* unused bit */
-
-} Si3DACVOLUME;
-
-typedef union {
-	Si3DACVOLUME bits;
-	unsigned char byte;
-} Si3DAC;
-
-typedef struct {
-	unsigned int x:5;	/* unused bit */
-
-	unsigned int losc:1;	/* Line Out Short Circuit */
-
-	unsigned int srsc:1;	/* Speaker Right Short Circuit */
-
-	unsigned int slsc:1;	/* Speaker Left Short Circuit */
-
-} Si3STATUSREPORT;
-
-typedef union {
-	Si3STATUSREPORT bits;
-	unsigned char byte;
-} Si3STAT;
-
-typedef struct {
-	unsigned int sot:2;	/* Speaker Out Attenuation */
-
-	unsigned int lot:2;	/* Line Out Attenuation */
-
-	unsigned int x:4;	/* unused bits */
-
-} Si3ANALOGATTN;
-
-typedef union {
-	Si3ANALOGATTN bits;
-	unsigned char byte;
-} Si3AATT;
-
-/******************************************************************************
-*
-*  These structures deal with the DAA on the Internet LineJACK
-*
-******************************************************************************/
-
-typedef struct _DAA_REGS {
-	/*----------------------------------------------- */
-	/* SOP Registers */
-	/* */
-	BYTE bySOP;
-
-	union _SOP_REGS {
-		struct _SOP {
-			union	/* SOP - CR0 Register */
-			 {
-				BYTE reg;
-				struct _CR0_BITREGS {
-					BYTE CLK_EXT:1;		/* cr0[0:0] */
-
-					BYTE RIP:1;	/* cr0[1:1] */
-
-					BYTE AR:1;	/* cr0[2:2] */
-
-					BYTE AX:1;	/* cr0[3:3] */
-
-					BYTE FRR:1;	/* cr0[4:4] */
-
-					BYTE FRX:1;	/* cr0[5:5] */
-
-					BYTE IM:1;	/* cr0[6:6] */
-
-					BYTE TH:1;	/* cr0[7:7] */
-
-				} bitreg;
-			} cr0;
-
-			union	/* SOP - CR1 Register */
-			 {
-				BYTE reg;
-				struct _CR1_REGS {
-					BYTE RM:1;	/* cr1[0:0] */
-
-					BYTE RMR:1;	/* cr1[1:1] */
-
-					BYTE No_auto:1;		/* cr1[2:2] */
-
-					BYTE Pulse:1;	/* cr1[3:3] */
-
-					BYTE P_Tone1:1;		/* cr1[4:4] */
-
-					BYTE P_Tone2:1;		/* cr1[5:5] */
-
-					BYTE E_Tone1:1;		/* cr1[6:6] */
-
-					BYTE E_Tone2:1;		/* cr1[7:7] */
-
-				} bitreg;
-			} cr1;
-
-			union	/* SOP - CR2 Register */
-			 {
-				BYTE reg;
-				struct _CR2_REGS {
-					BYTE Call_II:1;		/* CR2[0:0] */
-
-					BYTE Call_I:1;	/* CR2[1:1] */
-
-					BYTE Call_en:1;		/* CR2[2:2] */
-
-					BYTE Call_pon:1;	/* CR2[3:3] */
-
-					BYTE IDR:1;	/* CR2[4:4] */
-
-					BYTE COT_R:3;	/* CR2[5:7] */
-
-				} bitreg;
-			} cr2;
-
-			union	/* SOP - CR3 Register */
-			 {
-				BYTE reg;
-				struct _CR3_REGS {
-					BYTE DHP_X:1;	/* CR3[0:0] */
-
-					BYTE DHP_R:1;	/* CR3[1:1] */
-
-					BYTE Cal_pctl:1;	/* CR3[2:2] */
-
-					BYTE SEL:1;	/* CR3[3:3] */
-
-					BYTE TestLoops:4;	/* CR3[4:7] */
-
-				} bitreg;
-			} cr3;
-
-			union	/* SOP - CR4 Register */
-			 {
-				BYTE reg;
-				struct _CR4_REGS {
-					BYTE Fsc_en:1;	/* CR4[0:0] */
-
-					BYTE Int_en:1;	/* CR4[1:1] */
-
-					BYTE AGX:2;	/* CR4[2:3] */
-
-					BYTE AGR_R:2;	/* CR4[4:5] */
-
-					BYTE AGR_Z:2;	/* CR4[6:7] */
-
-				} bitreg;
-			} cr4;
-
-			union	/* SOP - CR5 Register */
-			 {
-				BYTE reg;
-				struct _CR5_REGS {
-					BYTE V_0:1;	/* CR5[0:0] */
-
-					BYTE V_1:1;	/* CR5[1:1] */
-
-					BYTE V_2:1;	/* CR5[2:2] */
-
-					BYTE V_3:1;	/* CR5[3:3] */
-
-					BYTE V_4:1;	/* CR5[4:4] */
-
-					BYTE V_5:1;	/* CR5[5:5] */
-
-					BYTE V_6:1;	/* CR5[6:6] */
-
-					BYTE V_7:1;	/* CR5[7:7] */
-
-				} bitreg;
-			} cr5;
-
-			union	/* SOP - CR6 Register */
-			 {
-				BYTE reg;
-				struct _CR6_REGS {
-					BYTE reserved:8;	/* CR6[0:7] */
-
-				} bitreg;
-			} cr6;
-
-			union	/* SOP - CR7 Register */
-			 {
-				BYTE reg;
-				struct _CR7_REGS {
-					BYTE reserved:8;	/* CR7[0:7] */
-
-				} bitreg;
-			} cr7;
-		} SOP;
-
-		BYTE ByteRegs[sizeof(struct _SOP)];
-
-	} SOP_REGS;
-
-	/* DAA_REGS.SOP_REGS.SOP.CR5.reg */
-	/* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */
-	/* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */
-	/* DAA_REGS.SOP_REGS.ByteRegs[5] */
-
-	/*----------------------------------------------- */
-	/* XOP Registers */
-	/* */
-	BYTE byXOP;
-
-	union _XOP_REGS {
-		struct _XOP {
-			union	XOPXR0/* XOP - XR0 Register - Read values */
-			 {
-				BYTE reg;
-				struct _XR0_BITREGS {
-					BYTE SI_0:1;	/* XR0[0:0] - Read */
-
-					BYTE SI_1:1;	/* XR0[1:1] - Read */
-
-					BYTE VDD_OK:1;	/* XR0[2:2] - Read */
-
-					BYTE Caller_ID:1;	/* XR0[3:3] - Read */
-
-					BYTE RING:1;	/* XR0[4:4] - Read */
-
-					BYTE Cadence:1;		/* XR0[5:5] - Read */
-
-					BYTE Wake_up:1;		/* XR0[6:6] - Read */
-
-					BYTE RMR:1;	/* XR0[7:7] - Read */
-
-				} bitreg;
-			} xr0;
-
-			union	/* XOP - XR1 Register */
-			 {
-				BYTE reg;
-				struct _XR1_BITREGS {
-					BYTE M_SI_0:1;	/* XR1[0:0] */
-
-					BYTE M_SI_1:1;	/* XR1[1:1] */
-
-					BYTE M_VDD_OK:1;	/* XR1[2:2] */
-
-					BYTE M_Caller_ID:1;	/* XR1[3:3] */
-
-					BYTE M_RING:1;	/* XR1[4:4] */
-
-					BYTE M_Cadence:1;	/* XR1[5:5] */
-
-					BYTE M_Wake_up:1;	/* XR1[6:6] */
-
-					BYTE unused:1;	/* XR1[7:7] */
-
-				} bitreg;
-			} xr1;
-
-			union	/* XOP - XR2 Register */
-			 {
-				BYTE reg;
-				struct _XR2_BITREGS {
-					BYTE CTO0:1;	/* XR2[0:0] */
-
-					BYTE CTO1:1;	/* XR2[1:1] */
-
-					BYTE CTO2:1;	/* XR2[2:2] */
-
-					BYTE CTO3:1;	/* XR2[3:3] */
-
-					BYTE CTO4:1;	/* XR2[4:4] */
-
-					BYTE CTO5:1;	/* XR2[5:5] */
-
-					BYTE CTO6:1;	/* XR2[6:6] */
-
-					BYTE CTO7:1;	/* XR2[7:7] */
-
-				} bitreg;
-			} xr2;
-
-			union	/* XOP - XR3 Register */
-			 {
-				BYTE reg;
-				struct _XR3_BITREGS {
-					BYTE DCR0:1;	/* XR3[0:0] */
-
-					BYTE DCR1:1;	/* XR3[1:1] */
-
-					BYTE DCI:1;	/* XR3[2:2] */
-
-					BYTE DCU0:1;	/* XR3[3:3] */
-
-					BYTE DCU1:1;	/* XR3[4:4] */
-
-					BYTE B_off:1;	/* XR3[5:5] */
-
-					BYTE AGB0:1;	/* XR3[6:6] */
-
-					BYTE AGB1:1;	/* XR3[7:7] */
-
-				} bitreg;
-			} xr3;
-
-			union	/* XOP - XR4 Register */
-			 {
-				BYTE reg;
-				struct _XR4_BITREGS {
-					BYTE C_0:1;	/* XR4[0:0] */
-
-					BYTE C_1:1;	/* XR4[1:1] */
-
-					BYTE C_2:1;	/* XR4[2:2] */
-
-					BYTE C_3:1;	/* XR4[3:3] */
-
-					BYTE C_4:1;	/* XR4[4:4] */
-
-					BYTE C_5:1;	/* XR4[5:5] */
-
-					BYTE C_6:1;	/* XR4[6:6] */
-
-					BYTE C_7:1;	/* XR4[7:7] */
-
-				} bitreg;
-			} xr4;
-
-			union	/* XOP - XR5 Register */
-			 {
-				BYTE reg;
-				struct _XR5_BITREGS {
-					BYTE T_0:1;	/* XR5[0:0] */
-
-					BYTE T_1:1;	/* XR5[1:1] */
-
-					BYTE T_2:1;	/* XR5[2:2] */
-
-					BYTE T_3:1;	/* XR5[3:3] */
-
-					BYTE T_4:1;	/* XR5[4:4] */
-
-					BYTE T_5:1;	/* XR5[5:5] */
-
-					BYTE T_6:1;	/* XR5[6:6] */
-
-					BYTE T_7:1;	/* XR5[7:7] */
-
-				} bitreg;
-			} xr5;
-
-			union	/* XOP - XR6 Register - Read Values */
-			 {
-				BYTE reg;
-				struct _XR6_BITREGS {
-					BYTE CPS0:1;	/* XR6[0:0] */
-
-					BYTE CPS1:1;	/* XR6[1:1] */
-
-					BYTE unused1:2;		/* XR6[2:3] */
-
-					BYTE CLK_OFF:1;		/* XR6[4:4] */
-
-					BYTE unused2:3;		/* XR6[5:7] */
-
-				} bitreg;
-			} xr6;
-
-			union	/* XOP - XR7 Register */
-			 {
-				BYTE reg;
-				struct _XR7_BITREGS {
-					BYTE unused1:1;		/* XR7[0:0] */
-
-					BYTE Vdd0:1;	/* XR7[1:1] */
-
-					BYTE Vdd1:1;	/* XR7[2:2] */
-
-					BYTE unused2:5;		/* XR7[3:7] */
-
-				} bitreg;
-			} xr7;
-		} XOP;
-
-		BYTE ByteRegs[sizeof(struct _XOP)];
-
-	} XOP_REGS;
-
-	/* DAA_REGS.XOP_REGS.XOP.XR7.reg */
-	/* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */
-	/* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */
-	/* DAA_REGS.XOP_REGS.ByteRegs[7] */
-
-	/*----------------------------------------------- */
-	/* COP Registers */
-	/* */
-	BYTE byCOP;
-
-	union _COP_REGS {
-		struct _COP {
-			BYTE THFilterCoeff_1[8];	/* COP - TH Filter Coefficients,      CODE=0, Part 1 */
-
-			BYTE THFilterCoeff_2[8];	/* COP - TH Filter Coefficients,      CODE=1, Part 2 */
-
-			BYTE THFilterCoeff_3[8];	/* COP - TH Filter Coefficients,      CODE=2, Part 3 */
-
-			BYTE RingerImpendance_1[8];	/* COP - Ringer Impendance Coefficients,  CODE=3, Part 1 */
-
-			BYTE IMFilterCoeff_1[8];	/* COP - IM Filter Coefficients,      CODE=4, Part 1 */
-
-			BYTE IMFilterCoeff_2[8];	/* COP - IM Filter Coefficients,      CODE=5, Part 2 */
-
-			BYTE RingerImpendance_2[8];	/* COP - Ringer Impendance Coefficients,  CODE=6, Part 2 */
-
-			BYTE FRRFilterCoeff[8];		/* COP - FRR Filter Coefficients,      CODE=7 */
-
-			BYTE FRXFilterCoeff[8];		/* COP - FRX Filter Coefficients,      CODE=8 */
-
-			BYTE ARFilterCoeff[4];	/* COP - AR Filter Coefficients,      CODE=9 */
-
-			BYTE AXFilterCoeff[4];	/* COP - AX Filter Coefficients,      CODE=10  */
-
-			BYTE Tone1Coeff[4];	/* COP - Tone1 Coefficients,        CODE=11 */
-
-			BYTE Tone2Coeff[4];	/* COP - Tone2 Coefficients,        CODE=12 */
-
-			BYTE LevelmeteringRinging[4];	/* COP - Levelmetering Ringing,        CODE=13 */
-
-			BYTE CallerID1stTone[8];	/* COP - Caller ID 1st Tone,        CODE=14 */
-
-			BYTE CallerID2ndTone[8];	/* COP - Caller ID 2nd Tone,        CODE=15 */
-
-		} COP;
-
-		BYTE ByteRegs[sizeof(struct _COP)];
-
-	} COP_REGS;
-
-	/* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */
-	/* DAA_REGS.COP_REGS.COP.XR7.bitreg */
-	/* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */
-	/* DAA_REGS.COP_REGS.ByteRegs[57] */
-
-	/*----------------------------------------------- */
-	/* CAO Registers */
-	/* */
-	BYTE byCAO;
-
-	union _CAO_REGS {
-		struct _CAO {
-			BYTE CallerID[512];	/* CAO - Caller ID Bytes */
-
-		} CAO;
-
-		BYTE ByteRegs[sizeof(struct _CAO)];
-	} CAO_REGS;
-
-	union			/* XOP - XR0 Register - Write values */
-	 {
-		BYTE reg;
-		struct _XR0_BITREGSW {
-			BYTE SO_0:1;	/* XR1[0:0] - Write */
-
-			BYTE SO_1:1;	/* XR1[1:1] - Write */
-
-			BYTE SO_2:1;	/* XR1[2:2] - Write */
-
-			BYTE unused:5;	/* XR1[3:7] - Write */
-
-		} bitreg;
-	} XOP_xr0_W;
-
-	union			/* XOP - XR6 Register - Write values */
-	 {
-		BYTE reg;
-		struct _XR6_BITREGSW {
-			BYTE unused1:4;		/* XR6[0:3] */
-
-			BYTE CLK_OFF:1;		/* XR6[4:4] */
-
-			BYTE unused2:3;		/* XR6[5:7] */
-
-		} bitreg;
-	} XOP_xr6_W;
-
-} DAA_REGS;
-
-#define ALISDAA_ID_BYTE      0x81
-#define ALISDAA_CALLERID_SIZE  512
-
-/*------------------------------ */
-/* */
-/*  Misc definitions */
-/* */
-
-/* Power Up Operation */
-#define SOP_PU_SLEEP    0
-#define SOP_PU_RINGING    1
-#define SOP_PU_CONVERSATION  2
-#define SOP_PU_PULSEDIALING  3
-#define SOP_PU_RESET    4
-
-#define ALISDAA_CALLERID_SIZE 512
-
-#define PLAYBACK_MODE_COMPRESSED	0	/*        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
-#define PLAYBACK_MODE_TRUESPEECH_V40	0	/*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
-#define PLAYBACK_MODE_TRUESPEECH	8	/*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */
-#define PLAYBACK_MODE_ULAW		2	/*        Selects: 64 Kbit/sec MuA-law PCM */
-#define PLAYBACK_MODE_ALAW		10	/*        Selects: 64 Kbit/sec A-law PCM */
-#define PLAYBACK_MODE_16LINEAR		6	/*        Selects: 128 Kbit/sec 16-bit linear */
-#define PLAYBACK_MODE_8LINEAR		4	/*        Selects: 64 Kbit/sec 8-bit signed linear */
-#define PLAYBACK_MODE_8LINEAR_WSS	5	/*        Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
-
-#define RECORD_MODE_COMPRESSED		0	/*        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
-#define RECORD_MODE_TRUESPEECH		0	/*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
-#define RECORD_MODE_ULAW		4	/*        Selects: 64 Kbit/sec Mu-law PCM */
-#define RECORD_MODE_ALAW		12	/*        Selects: 64 Kbit/sec A-law PCM */
-#define RECORD_MODE_16LINEAR		5	/*        Selects: 128 Kbit/sec 16-bit linear */
-#define RECORD_MODE_8LINEAR		6	/*        Selects: 64 Kbit/sec 8-bit signed linear */
-#define RECORD_MODE_8LINEAR_WSS		7	/*        Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
-
-enum SLIC_STATES {
-	PLD_SLIC_STATE_OC = 0,
-	PLD_SLIC_STATE_RINGING,
-	PLD_SLIC_STATE_ACTIVE,
-	PLD_SLIC_STATE_OHT,
-	PLD_SLIC_STATE_TIPOPEN,
-	PLD_SLIC_STATE_STANDBY,
-	PLD_SLIC_STATE_APR,
-	PLD_SLIC_STATE_OHTPR
-};
-
-enum SCI_CONTROL {
-	SCI_End = 0,
-	SCI_Enable_DAA,
-	SCI_Enable_Mixer,
-	SCI_Enable_EEPROM
-};
-
-enum Mode {
-	T63, T53, T48, T40
-};
-enum Dir {
-	V3_TO_V4, V4_TO_V3, V4_TO_V5, V5_TO_V4
-};
-
-typedef struct Proc_Info_Tag {
-	enum Mode convert_mode;
-	enum Dir convert_dir;
-	int Prev_Frame_Type;
-	int Current_Frame_Type;
-} Proc_Info_Type;
-
-enum PREVAL {
-	NORMAL = 0,
-	NOPOST,
-	POSTONLY,
-	PREERROR
-};
-
-enum IXJ_EXTENSIONS {
-	G729LOADER = 0,
-	TS85LOADER,
-	PRE_READ,
-	POST_READ,
-	PRE_WRITE,
-	POST_WRITE,
-	PRE_IOCTL,
-	POST_IOCTL
-};
-
-typedef struct {
-	char enable;
-	char en_filter;
-	unsigned int filter;
-	unsigned int state;	/* State 0 when cadence has not started. */
-
-	unsigned int on1;	/* State 1 */
-
-	unsigned long on1min;	/* State 1 - 10% + jiffies */
- 	unsigned long on1dot;	/* State 1 + jiffies */
-
-	unsigned long on1max;	/* State 1 + 10% + jiffies */
-
-	unsigned int off1;	/* State 2 */
-
-	unsigned long off1min;
- 	unsigned long off1dot;	/* State 2 + jiffies */
-	unsigned long off1max;
-	unsigned int on2;	/* State 3 */
-
-	unsigned long on2min;
-	unsigned long on2dot;
-	unsigned long on2max;
-	unsigned int off2;	/* State 4 */
-
-	unsigned long off2min;
- 	unsigned long off2dot;	/* State 4 + jiffies */
-	unsigned long off2max;
-	unsigned int on3;	/* State 5 */
-
-	unsigned long on3min;
-	unsigned long on3dot;
-	unsigned long on3max;
-	unsigned int off3;	/* State 6 */
-
-	unsigned long off3min;
- 	unsigned long off3dot;	/* State 6 + jiffies */
-	unsigned long off3max;
-} IXJ_CADENCE_F;
-
-typedef struct {
-	unsigned int busytone:1;
-	unsigned int dialtone:1;
-	unsigned int ringback:1;
-	unsigned int ringing:1;
-	unsigned int playing:1;
-	unsigned int recording:1;
-	unsigned int cringing:1;
-	unsigned int play_first_frame:1;
-	unsigned int pstn_present:1;
-	unsigned int pstn_ringing:1;
-	unsigned int pots_correct:1;
-	unsigned int pots_pstn:1;
-	unsigned int g729_loaded:1;
-	unsigned int ts85_loaded:1;
-	unsigned int dtmf_oob:1;	/* DTMF Out-Of-Band */
-
-	unsigned int pcmciascp:1;	/* SmartCABLE Present */
-
-	unsigned int pcmciasct:2;	/* SmartCABLE Type */
-
-	unsigned int pcmciastate:3;	/* SmartCABLE Init State */
-
-	unsigned int inwrite:1;	/* Currently writing */
-
-	unsigned int inread:1;	/* Currently reading */
-
-	unsigned int incheck:1;	/* Currently checking the SmartCABLE */
-
-	unsigned int cidplay:1; /* Currently playing Caller ID */
-
-	unsigned int cidring:1; /* This is the ring for Caller ID */
-
-	unsigned int cidsent:1; /* Caller ID has been sent */
-
-	unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */
-	unsigned int firstring:1; /* First ring cadence is complete */
-	unsigned int pstncheck:1;	/* Currently checking the PSTN Line */
-	unsigned int pstn_rmr:1;
-	unsigned int x:3;	/* unused bits */
-
-} IXJ_FLAGS;
-
-/******************************************************************************
-*
-*  This structure holds the state of all of the Quicknet cards
-*
-******************************************************************************/
-
-typedef struct {
-	int elements_used;
-	IXJ_CADENCE_TERM termination;
-	IXJ_CADENCE_ELEMENT *ce;
-} ixj_cadence;
-
-typedef struct {
-	struct phone_device p;
-	struct timer_list timer;
-	unsigned int board;
-	unsigned int DSPbase;
-	unsigned int XILINXbase;
-	unsigned int serial;
-	atomic_t DSPWrite;
-	struct phone_capability caplist[30];
-	unsigned int caps;
-	struct pnp_dev *dev;
-	unsigned int cardtype;
-	unsigned int rec_codec;
-	unsigned int cid_rec_codec;
-	unsigned int cid_rec_volume;
-	unsigned char cid_rec_flag;
-	signed char rec_mode;
-	unsigned int play_codec;
-	unsigned int cid_play_codec;
-	unsigned int cid_play_volume;
-	unsigned char cid_play_flag;
-	signed char play_mode;
-	IXJ_FLAGS flags;
-	unsigned long busyflags;
-	unsigned int rec_frame_size;
-	unsigned int play_frame_size;
-	unsigned int cid_play_frame_size;
-	unsigned int cid_base_frame_size;
-	unsigned long cidcw_wait;
-	int aec_level;
-	int cid_play_aec_level;
-	int readers, writers;
-        wait_queue_head_t poll_q;
-        wait_queue_head_t read_q;
-	char *read_buffer, *read_buffer_end;
-	char *read_convert_buffer;
-	size_t read_buffer_size;
-	unsigned int read_buffer_ready;
-        wait_queue_head_t write_q;
-	char *write_buffer, *write_buffer_end;
-	char *write_convert_buffer;
-	size_t write_buffer_size;
-	unsigned int write_buffers_empty;
-	unsigned long drybuffer;
-	char *write_buffer_rp, *write_buffer_wp;
-	char dtmfbuffer[80];
-	char dtmf_current;
-	int dtmf_wp, dtmf_rp, dtmf_state, dtmf_proc;
-	int tone_off_time, tone_on_time;
-	struct fasync_struct *async_queue;
-	unsigned long tone_start_jif;
-	char tone_index;
-	char tone_state;
-	char maxrings;
-	ixj_cadence *cadence_t;
-	ixj_cadence *cadence_r;
-	int tone_cadence_state;
-	IXJ_CADENCE_F cadence_f[6];
-	DTMF dtmf;
-	CPTF cptf;
-	BYTES dsp;
-	BYTES ver;
-	BYTES scr;
-	BYTES ssr;
-	BYTES baseframe;
-	HSR hsr;
-	GPIO gpio;
-	PLD_SCRR pld_scrr;
-	PLD_SCRW pld_scrw;
-	PLD_SLICW pld_slicw;
-	PLD_SLICR pld_slicr;
-	PLD_CLOCK pld_clock;
-	PCMCIA_CR1 pccr1;
-	PCMCIA_CR2 pccr2;
-	PCMCIA_SCCR psccr;
-	PCMCIA_SLIC pslic;
-	char pscdd;
-	Si3C1 sic1;
-	Si3C2 sic2;
-	Si3RXG sirxg;
-	Si3ADC siadc;
-	Si3DAC sidac;
-	Si3STAT sistat;
-	Si3AATT siaatt;
-	MIX mix;
-	unsigned short ring_cadence;
-	int ring_cadence_t;
-	unsigned long ring_cadence_jif;
-	unsigned long checkwait;
-	int intercom;
-	int m_hook;
-	int r_hook;
-	int p_hook;
-	char pstn_envelope;
-	char pstn_cid_intr;
-	unsigned char fskz;
-	unsigned char fskphase;
-	unsigned char fskcnt;
-        unsigned int cidsize;
-	unsigned int cidcnt;
-	unsigned long pstn_cid_received;
-	PHONE_CID cid;
-	PHONE_CID cid_send;
-	unsigned long pstn_ring_int;
-	unsigned long pstn_ring_start;
-	unsigned long pstn_ring_stop;
-	unsigned long pstn_winkstart;
-	unsigned long pstn_last_rmr;
-	unsigned long pstn_prev_rmr;
-	unsigned long pots_winkstart;
-	unsigned int winktime;
-	unsigned long flash_end;
-	char port;
-	char hookstate;
-	union telephony_exception ex;
-	union telephony_exception ex_sig;
-	int ixj_signals[35];
-	IXJ_SIGDEF sigdef;
-	char daa_mode;
-	char daa_country;
-	unsigned long pstn_sleeptil;
-	DAA_REGS m_DAAShadowRegs;
-	Proc_Info_Type Info_read;
-	Proc_Info_Type Info_write;
-	unsigned short frame_count;
-	unsigned int filter_hist[4];
-	unsigned char filter_en[6];
-	unsigned short proc_load;
-	unsigned long framesread;
-	unsigned long frameswritten;
-	unsigned long read_wait;
-	unsigned long write_wait;
-	unsigned long timerchecks;
-	unsigned long txreadycheck;
-	unsigned long rxreadycheck;
-	unsigned long statuswait;
-	unsigned long statuswaitfail;
-	unsigned long pcontrolwait;
-	unsigned long pcontrolwaitfail;
-	unsigned long iscontrolready;
-	unsigned long iscontrolreadyfail;
-	unsigned long pstnstatecheck;
-#ifdef IXJ_DYN_ALLOC
-	short *fskdata;
-#else
-	short fskdata[8000];
-#endif
-	int fsksize;
-	int fskdcnt;
-} IXJ;
-
-typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
-
-extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long);
-
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
deleted file mode 100644
index 05032e2..0000000
--- a/drivers/telephony/ixj_pcmcia.c
+++ /dev/null
@@ -1,187 +0,0 @@
-#include "ixj-ver.h"
-
-#include <linux/module.h>
-
-#include <linux/init.h>
-#include <linux/kernel.h>	/* printk() */
-#include <linux/fs.h>		/* everything... */
-#include <linux/errno.h>	/* error codes */
-#include <linux/slab.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include "ixj.h"
-
-/*
- *	PCMCIA service support for Quicknet cards
- */
- 
-
-typedef struct ixj_info_t {
-	int ndev;
-	struct ixj *port;
-} ixj_info_t;
-
-static void ixj_detach(struct pcmcia_device *p_dev);
-static int ixj_config(struct pcmcia_device * link);
-static void ixj_cs_release(struct pcmcia_device * link);
-
-static int ixj_probe(struct pcmcia_device *p_dev)
-{
-	dev_dbg(&p_dev->dev, "ixj_attach()\n");
-	/* Create new ixj device */
-	p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
-	if (!p_dev->priv) {
-		return -ENOMEM;
-	}
-
-	return ixj_config(p_dev);
-}
-
-static void ixj_detach(struct pcmcia_device *link)
-{
-	dev_dbg(&link->dev, "ixj_detach\n");
-
-	ixj_cs_release(link);
-
-        kfree(link->priv);
-}
-
-static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
-{
-	char *str;
-	int i, place;
-	dev_dbg(&link->dev, "ixj_get_serial\n");
-
-	str = link->prod_id[0];
-	if (!str)
-		goto failed;
-	printk("%s", str);
-	str = link->prod_id[1];
-	if (!str)
-		goto failed;
-	printk(" %s", str);
-	str = link->prod_id[2];
-	if (!str)
-		goto failed;
-	place = 1;
-	for (i = strlen(str) - 1; i >= 0; i--) {
-		switch (str[i]) {
-		case '0':
-		case '1':
-		case '2':
-		case '3':
-		case '4':
-		case '5':
-		case '6':
-		case '7':
-		case '8':
-		case '9':
-			j->serial += (str[i] - 48) * place;
-			break;
-		case 'A':
-		case 'B':
-		case 'C':
-		case 'D':
-		case 'E':
-		case 'F':
-			j->serial += (str[i] - 55) * place;
-			break;
-		case 'a':
-		case 'b':
-		case 'c':
-		case 'd':
-		case 'e':
-		case 'f':
-			j->serial += (str[i] - 87) * place;
-			break;
-		}
-		place = place * 0x10;
-	}
-	str = link->prod_id[3];
-	if (!str)
-		goto failed;
-	printk(" version %s\n", str);
-failed:
-	return;
-}
-
-static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data)
-{
-	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
-	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-	p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
-	p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
-	p_dev->io_lines = 3;
-
-	return pcmcia_request_io(p_dev);
-}
-
-static int ixj_config(struct pcmcia_device * link)
-{
-	IXJ *j;
-	ixj_info_t *info;
-
-	info = link->priv;
-	dev_dbg(&link->dev, "ixj_config\n");
-
-	link->config_flags = CONF_AUTO_SET_IO;
-
-	if (pcmcia_loop_config(link, ixj_config_check, NULL))
-		goto failed;
-
-	if (pcmcia_enable_device(link))
-		goto failed;
-
-	/*
- 	 *	Register the card with the core.
-	 */
-	j = ixj_pcmcia_probe(link->resource[0]->start,
-			     link->resource[0]->start + 0x10);
-
-	info->ndev = 1;
-	ixj_get_serial(link, j);
-	return 0;
-
-failed:
-	ixj_cs_release(link);
-	return -ENODEV;
-}
-
-static void ixj_cs_release(struct pcmcia_device *link)
-{
-	ixj_info_t *info = link->priv;
-	dev_dbg(&link->dev, "ixj_cs_release\n");
-	info->ndev = 0;
-	pcmcia_disable_device(link);
-}
-
-static const struct pcmcia_device_id ixj_ids[] = {
-	PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600),
-	PCMCIA_DEVICE_NULL
-};
-MODULE_DEVICE_TABLE(pcmcia, ixj_ids);
-
-static struct pcmcia_driver ixj_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "ixj_cs",
-	.probe		= ixj_probe,
-	.remove		= ixj_detach,
-	.id_table	= ixj_ids,
-};
-
-static int __init ixj_pcmcia_init(void)
-{
-	return pcmcia_register_driver(&ixj_driver);
-}
-
-static void ixj_pcmcia_exit(void)
-{
-	pcmcia_unregister_driver(&ixj_driver);
-}
-
-module_init(ixj_pcmcia_init);
-module_exit(ixj_pcmcia_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
deleted file mode 100644
index 1915af2..0000000
--- a/drivers/telephony/phonedev.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- *            Telephony registration for Linux
- *
- *              (c) Copyright 1999 Red Hat 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 Free Software Foundation; either version
- *              2 of the License, or (at your option) any later version.
- *
- * Author:      Alan Cox, <alan@lxorguk.ukuu.org.uk>
- *
- * Fixes:       Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com>
- *              phone_register_device now works with unit!=PHONE_UNIT_ANY
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/phonedev.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/kmod.h>
-#include <linux/sem.h>
-#include <linux/mutex.h>
-
-#define PHONE_NUM_DEVICES	256
-
-/*
- *    Active devices 
- */
-
-static struct phone_device *phone_device[PHONE_NUM_DEVICES];
-static DEFINE_MUTEX(phone_lock);
-
-/*
- *    Open a phone device.
- */
-
-static int phone_open(struct inode *inode, struct file *file)
-{
-	unsigned int minor = iminor(inode);
-	int err = 0;
-	struct phone_device *p;
-	const struct file_operations *old_fops, *new_fops = NULL;
-
-	if (minor >= PHONE_NUM_DEVICES)
-		return -ENODEV;
-
-	mutex_lock(&phone_lock);
-	p = phone_device[minor];
-	if (p)
-		new_fops = fops_get(p->f_op);
-	if (!new_fops) {
-		mutex_unlock(&phone_lock);
-		request_module("char-major-%d-%d", PHONE_MAJOR, minor);
-		mutex_lock(&phone_lock);
-		p = phone_device[minor];
-		if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL)
-		{
-			err=-ENODEV;
-			goto end;
-		}
-	}
-	old_fops = file->f_op;
-	file->f_op = new_fops;
-	if (p->open)
-		err = p->open(p, file);	/* Tell the device it is open */
-	if (err) {
-		fops_put(file->f_op);
-		file->f_op = fops_get(old_fops);
-	}
-	fops_put(old_fops);
-end:
-	mutex_unlock(&phone_lock);
-	return err;
-}
-
-/*
- *    Telephony For Linux device drivers request registration here.
- */
-
-int phone_register_device(struct phone_device *p, int unit)
-{
-	int base;
-	int end;
-	int i;
-
-	base = 0;
-	end = PHONE_NUM_DEVICES - 1;
-
-	if (unit != PHONE_UNIT_ANY) {
-		base = unit;
-		end = unit + 1;  /* enter the loop at least one time */
-	}
-	
-	mutex_lock(&phone_lock);
-	for (i = base; i < end; i++) {
-		if (phone_device[i] == NULL) {
-			phone_device[i] = p;
-			p->minor = i;
-			mutex_unlock(&phone_lock);
-			return 0;
-		}
-	}
-	mutex_unlock(&phone_lock);
-	return -ENFILE;
-}
-
-/*
- *    Unregister an unused Telephony for linux device
- */
-
-void phone_unregister_device(struct phone_device *pfd)
-{
-	mutex_lock(&phone_lock);
-	if (likely(phone_device[pfd->minor] == pfd))
-		phone_device[pfd->minor] = NULL;
-	mutex_unlock(&phone_lock);
-}
-
-
-static const struct file_operations phone_fops =
-{
-	.owner		= THIS_MODULE,
-	.open		= phone_open,
-	.llseek		= noop_llseek,
-};
-
-/*
- *	Board init functions
- */
- 
-
-/*
- *    Initialise Telephony for linux
- */
-
-static int __init telephony_init(void)
-{
-	printk(KERN_INFO "Linux telephony interface: v1.00\n");
-	if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
-		printk("phonedev: unable to get major %d\n", PHONE_MAJOR);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static void __exit telephony_exit(void)
-{
-	unregister_chrdev(PHONE_MAJOR, "telephony");
-}
-
-module_init(telephony_init);
-module_exit(telephony_exit);
-
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(phone_register_device);
-EXPORT_SYMBOL(phone_unregister_device);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 220ce7e..fab970d 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -23,6 +23,8 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -39,8 +41,6 @@ MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
 MODULE_LICENSE("GPL");
 
-#define PREFIX "Thermal: "
-
 struct thermal_cooling_device_instance {
 	int id;
 	char name[THERMAL_NAME_LENGTH];
@@ -60,13 +60,11 @@ static LIST_HEAD(thermal_tz_list);
 static LIST_HEAD(thermal_cdev_list);
 static DEFINE_MUTEX(thermal_list_lock);
 
-static unsigned int thermal_event_seqnum;
-
 static int get_idr(struct idr *idr, struct mutex *lock, int *id)
 {
 	int err;
 
-      again:
+again:
 	if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
 		return -ENOMEM;
 
@@ -283,8 +281,7 @@ passive_show(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR(type, 0444, type_show, NULL);
 static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
-static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
-		   passive_store);
+static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
 
 static struct device_attribute trip_point_attrs[] = {
 	__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -313,22 +310,6 @@ static struct device_attribute trip_point_attrs[] = {
 	__ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
 };
 
-#define TRIP_POINT_ATTR_ADD(_dev, _index, result)     \
-do {    \
-	result = device_create_file(_dev,	\
-				&trip_point_attrs[_index * 2]);	\
-	if (result)	\
-		break;	\
-	result = device_create_file(_dev,	\
-			&trip_point_attrs[_index * 2 + 1]);	\
-} while (0)
-
-#define TRIP_POINT_ATTR_REMOVE(_dev, _index)	\
-do {	\
-	device_remove_file(_dev, &trip_point_attrs[_index * 2]);	\
-	device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]);	\
-} while (0)
-
 /* sys I/F for cooling device */
 #define to_cooling_device(_dev)	\
 	container_of(_dev, struct thermal_cooling_device, device)
@@ -835,15 +816,14 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		return 0;
 
 	device_remove_file(&tz->device, &dev->attr);
-      remove_symbol_link:
+remove_symbol_link:
 	sysfs_remove_link(&tz->device.kobj, dev->name);
-      release_idr:
+release_idr:
 	release_idr(&tz->idr, &tz->lock, dev->id);
-      free_mem:
+free_mem:
 	kfree(dev);
 	return result;
 }
-
 EXPORT_SYMBOL(thermal_zone_bind_cooling_device);
 
 /**
@@ -873,14 +853,13 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 
 	return -ENODEV;
 
-      unbind:
+unbind:
 	device_remove_file(&tz->device, &pos->attr);
 	sysfs_remove_link(&tz->device.kobj, pos->name);
 	release_idr(&tz->idr, &tz->lock, pos->id);
 	kfree(pos);
 	return 0;
 }
-
 EXPORT_SYMBOL(thermal_zone_unbind_cooling_device);
 
 static void thermal_release(struct device *dev)
@@ -888,7 +867,8 @@ static void thermal_release(struct device *dev)
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *cdev;
 
-	if (!strncmp(dev_name(dev), "thermal_zone", sizeof "thermal_zone" - 1)) {
+	if (!strncmp(dev_name(dev), "thermal_zone",
+		     sizeof("thermal_zone") - 1)) {
 		tz = to_thermal_zone(dev);
 		kfree(tz);
 	} else {
@@ -908,8 +888,9 @@ static struct class thermal_class = {
  * @devdata:	device private data.
  * @ops:		standard thermal cooling devices callbacks.
  */
-struct thermal_cooling_device *thermal_cooling_device_register(
-     char *type, void *devdata, const struct thermal_cooling_device_ops *ops)
+struct thermal_cooling_device *
+thermal_cooling_device_register(char *type, void *devdata,
+				const struct thermal_cooling_device_ops *ops)
 {
 	struct thermal_cooling_device *cdev;
 	struct thermal_zone_device *pos;
@@ -974,12 +955,11 @@ struct thermal_cooling_device *thermal_cooling_device_register(
 	if (!result)
 		return cdev;
 
-      unregister:
+unregister:
 	release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
 	device_unregister(&cdev->device);
 	return ERR_PTR(result);
 }
-
 EXPORT_SYMBOL(thermal_cooling_device_register);
 
 /**
@@ -1024,7 +1004,6 @@ void thermal_cooling_device_unregister(struct
 	device_unregister(&cdev->device);
 	return;
 }
-
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
 /**
@@ -1044,8 +1023,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 
 	if (tz->ops->get_temp(tz, &temp)) {
 		/* get_temp failed - retry it later */
-		printk(KERN_WARNING PREFIX "failed to read out thermal zone "
-		       "%d\n", tz->id);
+		pr_warn("failed to read out thermal zone %d\n", tz->id);
 		goto leave;
 	}
 
@@ -1060,9 +1038,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 					ret = tz->ops->notify(tz, count,
 							      trip_type);
 				if (!ret) {
-					printk(KERN_EMERG
-					       "Critical temperature reached (%ld C), shutting down.\n",
-					       temp/1000);
+					pr_emerg("Critical temperature reached (%ld C), shutting down\n",
+						 temp/1000);
 					orderly_poweroff(true);
 				}
 			}
@@ -1100,7 +1077,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 
 	tz->last_temperature = temp;
 
-      leave:
+leave:
 	if (tz->passive)
 		thermal_zone_device_set_polling(tz, tz->passive_delay);
 	else if (tz->polling_delay)
@@ -1199,7 +1176,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
 	}
 
 	for (count = 0; count < trips; count++) {
-		TRIP_POINT_ATTR_ADD(&tz->device, count, result);
+		result = device_create_file(&tz->device,
+					    &trip_point_attrs[count * 2]);
+		if (result)
+			break;
+		result = device_create_file(&tz->device,
+					    &trip_point_attrs[count * 2 + 1]);
 		if (result)
 			goto unregister;
 		tz->ops->get_trip_type(tz, count, &trip_type);
@@ -1235,12 +1217,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
 	if (!result)
 		return tz;
 
-      unregister:
+unregister:
 	release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
 	device_unregister(&tz->device);
 	return ERR_PTR(result);
 }
-
 EXPORT_SYMBOL(thermal_zone_device_register);
 
 /**
@@ -1279,9 +1260,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 	if (tz->ops->get_mode)
 		device_remove_file(&tz->device, &dev_attr_mode);
 
-	for (count = 0; count < tz->trips; count++)
-		TRIP_POINT_ATTR_REMOVE(&tz->device, count);
-
+	for (count = 0; count < tz->trips; count++) {
+		device_remove_file(&tz->device,
+				   &trip_point_attrs[count * 2]);
+		device_remove_file(&tz->device,
+				   &trip_point_attrs[count * 2 + 1]);
+	}
 	thermal_remove_hwmon_sysfs(tz);
 	release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
 	idr_destroy(&tz->idr);
@@ -1289,7 +1273,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 	device_unregister(&tz->device);
 	return;
 }
-
 EXPORT_SYMBOL(thermal_zone_device_unregister);
 
 #ifdef CONFIG_NET
@@ -1312,10 +1295,11 @@ int thermal_generate_netlink_event(u32 orig, enum events event)
 	void *msg_header;
 	int size;
 	int result;
+	static unsigned int thermal_event_seqnum;
 
 	/* allocate memory */
-	size = nla_total_size(sizeof(struct thermal_genl_event)) + \
-				nla_total_size(0);
+	size = nla_total_size(sizeof(struct thermal_genl_event)) +
+	       nla_total_size(0);
 
 	skb = genlmsg_new(size, GFP_ATOMIC);
 	if (!skb)
@@ -1331,8 +1315,8 @@ int thermal_generate_netlink_event(u32 orig, enum events event)
 	}
 
 	/* fill the data */
-	attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \
-			sizeof(struct thermal_genl_event));
+	attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT,
+			   sizeof(struct thermal_genl_event));
 
 	if (!attr) {
 		nlmsg_free(skb);
@@ -1359,7 +1343,7 @@ int thermal_generate_netlink_event(u32 orig, enum events event)
 
 	result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC);
 	if (result)
-		printk(KERN_INFO "failed to send netlink event:%d", result);
+		pr_info("failed to send netlink event:%d\n", result);
 
 	return result;
 }
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index b3d1741..830cd62 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -365,7 +365,7 @@ config PPC_EPAPR_HV_BYTECHAN
 
 config PPC_EARLY_DEBUG_EHV_BC
 	bool "Early console (udbg) support for ePAPR hypervisors"
-	depends on PPC_EPAPR_HV_BYTECHAN
+	depends on PPC_EPAPR_HV_BYTECHAN=y
 	help
 	  Select this option to enable early console (a.k.a. "udbg") support
 	  via an ePAPR byte channel.  You also need to choose the byte channel
diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c
index 5fe4631..1560d23 100644
--- a/drivers/tty/hvc/hvc_beat.c
+++ b/drivers/tty/hvc/hvc_beat.c
@@ -113,7 +113,7 @@ static int __init hvc_beat_init(void)
 	if (!firmware_has_feature(FW_FEATURE_BEAT))
 		return -ENODEV;
 
-	hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16);
+	hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16);
 	if (IS_ERR(hp))
 		return PTR_ERR(hp);
 	hvc_beat_dev = hp;
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c
index 61c4a61..0069bb8 100644
--- a/drivers/tty/hvc/hvc_rtas.c
+++ b/drivers/tty/hvc/hvc_rtas.c
@@ -94,7 +94,7 @@ static int __init hvc_rtas_init(void)
 
 	/* Allocate an hvc_struct for the console device we instantiated
 	 * earlier.  Save off hp so that we can return it on exit */
-	hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16);
+	hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16);
 	if (IS_ERR(hp))
 		return PTR_ERR(hp);
 
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c
index b0957e6..4c9b13e 100644
--- a/drivers/tty/hvc/hvc_udbg.c
+++ b/drivers/tty/hvc/hvc_udbg.c
@@ -69,7 +69,7 @@ static int __init hvc_udbg_init(void)
 
 	BUG_ON(hvc_udbg_dev);
 
-	hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16);
+	hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16);
 	if (IS_ERR(hp))
 		return PTR_ERR(hp);
 
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 52fdf60..a1b0a75 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -176,7 +176,7 @@ static int __init xen_hvc_init(void)
 		xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
 	}
 	if (xencons_irq < 0)
-		xencons_irq = 0; /* NO_IRQ */
+		xencons_irq = 0;
 	else
 		irq_set_noprobe(xencons_irq);
 
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index b9040be..df7e7a0 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -1203,7 +1203,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
 {
 	struct hvcs_struct *hvcsd;
 	unsigned long flags;
-	int irq = NO_IRQ;
+	int irq;
 
 	/*
 	 * Is someone trying to close the file associated with this device after
@@ -1264,7 +1264,7 @@ static void hvcs_hangup(struct tty_struct * tty)
 	struct hvcs_struct *hvcsd = tty->driver_data;
 	unsigned long flags;
 	int temp_open_count;
-	int irq = NO_IRQ;
+	int irq;
 
 	spin_lock_irqsave(&hvcsd->lock, flags);
 	/* Preserve this so that we know how many kref refs to put */
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index cdfa3e0..1b5f28b 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -1237,7 +1237,7 @@ static int __init hvsi_console_init(void)
 		hp->state = HVSI_CLOSED;
 		hp->vtermno = *vtermno;
 		hp->virq = irq_create_mapping(NULL, irq[0]);
-		if (hp->virq == NO_IRQ) {
+		if (hp->virq == 0) {
 			printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
 				__func__, irq[0]);
 			continue;
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c
index fd347ff..580da78 100644
--- a/drivers/tty/nozomi.c
+++ b/drivers/tty/nozomi.c
@@ -1602,13 +1602,9 @@ static int ntty_install(struct tty_driver *driver, struct tty_struct *tty)
 	int ret;
 	if (!port || !dc || dc->state != NOZOMI_STATE_READY)
 		return -ENODEV;
-	ret = tty_init_termios(tty);
-	if (ret == 0) {
-		tty_driver_kref_get(driver);
-		tty->count++;
+	ret = tty_standard_install(driver, tty);
+	if (ret == 0)
 		tty->driver_data = port;
-		driver->ttys[tty->index] = tty;
-	}
 	return ret;
 }
 
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index d8653ab..39afd04 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -21,7 +21,6 @@
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/sysctl.h>
 #include <linux/device.h>
 #include <linux/uaccess.h>
 #include <linux/bitops.h>
@@ -55,11 +54,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
 	wake_up_interruptible(&tty->link->write_wait);
 	if (tty->driver->subtype == PTY_TYPE_MASTER) {
 		set_bit(TTY_OTHER_CLOSED, &tty->flags);
-#ifdef CONFIG_UNIX98_PTYS
-		if (tty->driver == ptm_driver)
-			devpts_pty_kill(tty->link);
-#endif
 		tty_unlock();
+		devpts_pty_kill(tty->link);
 		tty_vhangup(tty->link);
 		tty_lock();
 	}
@@ -439,55 +435,9 @@ static inline void legacy_pty_init(void) { }
 
 /* Unix98 devices */
 #ifdef CONFIG_UNIX98_PTYS
-/*
- * sysctl support for setting limits on the number of Unix98 ptys allocated.
- * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
- */
-int pty_limit = NR_UNIX98_PTY_DEFAULT;
-static int pty_limit_min;
-static int pty_limit_max = NR_UNIX98_PTY_MAX;
-static int pty_count;
 
 static struct cdev ptmx_cdev;
 
-static struct ctl_table pty_table[] = {
-	{
-		.procname	= "max",
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.data		= &pty_limit,
-		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= &pty_limit_min,
-		.extra2		= &pty_limit_max,
-	}, {
-		.procname	= "nr",
-		.maxlen		= sizeof(int),
-		.mode		= 0444,
-		.data		= &pty_count,
-		.proc_handler	= proc_dointvec,
-	}, 
-	{}
-};
-
-static struct ctl_table pty_kern_table[] = {
-	{
-		.procname	= "pty",
-		.mode		= 0555,
-		.child		= pty_table,
-	},
-	{}
-};
-
-static struct ctl_table pty_root_table[] = {
-	{
-		.procname	= "kernel",
-		.mode		= 0555,
-		.child		= pty_kern_table,
-	},
-	{}
-};
-
-
 static int pty_unix98_ioctl(struct tty_struct *tty,
 			    unsigned int cmd, unsigned long arg)
 {
@@ -515,10 +465,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty,
 static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver,
 		struct inode *ptm_inode, int idx)
 {
-	struct tty_struct *tty = devpts_get_tty(ptm_inode, idx);
-	if (tty)
-		tty = tty->link;
-	return tty;
+	/* Master must be open via /dev/ptmx */
+	return ERR_PTR(-EIO);
 }
 
 /**
@@ -589,7 +537,6 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
 	 */
 	tty_driver_kref_get(driver);
 	tty->count++;
-	pty_count++;
 	return 0;
 err_free_mem:
 	deinitialize_tty_struct(o_tty);
@@ -603,7 +550,6 @@ err_free_tty:
 
 static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 {
-	pty_count--;
 }
 
 static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
@@ -667,9 +613,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 		return retval;
 
 	/* find a device that is not in use. */
-	tty_lock();
 	index = devpts_new_index(inode);
-	tty_unlock();
 	if (index < 0) {
 		retval = index;
 		goto err_file;
@@ -677,7 +621,7 @@ static int ptmx_open(struct inode *inode, struct file *filp)
 
 	mutex_lock(&tty_mutex);
 	tty_lock();
-	tty = tty_init_dev(ptm_driver, index, 1);
+	tty = tty_init_dev(ptm_driver, index);
 	mutex_unlock(&tty_mutex);
 
 	if (IS_ERR(tty)) {
@@ -704,8 +648,8 @@ err_release:
 	tty_release(inode, filp);
 	return retval;
 out:
-	devpts_kill_index(inode, index);
 	tty_unlock();
+	devpts_kill_index(inode, index);
 err_file:
 	tty_free_file(filp);
 	return retval;
@@ -762,8 +706,6 @@ static void __init unix98_pty_init(void)
 	if (tty_register_driver(pts_driver))
 		panic("Couldn't register Unix98 pts driver");
 
-	register_sysctl_table(pty_root_table);
-
 	/* Now create the /dev/ptmx special device */
 	tty_default_fops(&ptmx_fops);
 	ptmx_fops.open = ptmx_open;
diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c
index 1b37626..f899996 100644
--- a/drivers/tty/serial/21285.c
+++ b/drivers/tty/serial/21285.c
@@ -331,7 +331,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct
 	int ret = 0;
 	if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285)
 		ret = -EINVAL;
-	if (ser->irq != NO_IRQ)
+	if (ser->irq <= 0)
 		ret = -EINVAL;
 	if (ser->baud_base != port->uartclk / 16)
 		ret = -EINVAL;
@@ -360,7 +360,7 @@ static struct uart_ops serial21285_ops = {
 static struct uart_port serial21285_port = {
 	.mapbase	= 0x42000160,
 	.iotype		= UPIO_MEM,
-	.irq		= NO_IRQ,
+	.irq		= 0,
 	.fifosize	= 16,
 	.ops		= &serial21285_ops,
 	.flags		= UPF_BOOT_AUTOCONF,
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
index 9b7336f..917ab84 100644
--- a/drivers/tty/serial/8250/8250.c
+++ b/drivers/tty/serial/8250/8250.c
@@ -38,16 +38,15 @@
 #include <linux/nmi.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#ifdef CONFIG_SPARC
+#include <linux/sunserialcore.h>
+#endif
 
 #include <asm/io.h>
 #include <asm/irq.h>
 
 #include "8250.h"
 
-#ifdef CONFIG_SPARC
-#include "../suncore.h"
-#endif
-
 /*
  * Configuration:
  *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
@@ -86,13 +85,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */
 #define BOTH_EMPTY 	(UART_LSR_TEMT | UART_LSR_THRE)
 
 
-/*
- * We default to IRQ0 for the "no irq" hack.   Some
- * machine types want others as well - they're free
- * to redefine this in their header file.
- */
-#define is_real_interrupt(irq)	((irq) != 0)
-
 #ifdef CONFIG_SERIAL_8250_DETECT_IRQ
 #define CONFIG_SERIAL_DETECT_IRQ 1
 #endif
@@ -1750,7 +1742,7 @@ static void serial8250_backup_timeout(unsigned long data)
 	 * Must disable interrupts or else we risk racing with the interrupt
 	 * based handler.
 	 */
-	if (is_real_interrupt(up->port.irq)) {
+	if (up->port.irq) {
 		ier = serial_in(up, UART_IER);
 		serial_out(up, UART_IER, 0);
 	}
@@ -1775,7 +1767,7 @@ static void serial8250_backup_timeout(unsigned long data)
 	if (!(iir & UART_IIR_NO_INT))
 		serial8250_tx_chars(up);
 
-	if (is_real_interrupt(up->port.irq))
+	if (up->port.irq)
 		serial_out(up, UART_IER, ier);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
@@ -2028,7 +2020,7 @@ static int serial8250_startup(struct uart_port *port)
 		serial_outp(up, UART_LCR, 0);
 	}
 
-	if (is_real_interrupt(up->port.irq)) {
+	if (up->port.irq) {
 		unsigned char iir1;
 		/*
 		 * Test for UARTs that do not reassert THRE when the
@@ -2083,7 +2075,7 @@ static int serial8250_startup(struct uart_port *port)
 	 * hardware interrupt, we use a timer-based system.  The original
 	 * driver used to do this with IRQ0.
 	 */
-	if (!is_real_interrupt(up->port.irq)) {
+	if (!up->port.irq) {
 		up->timer.data = (unsigned long)up;
 		mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
 	} else {
@@ -2099,13 +2091,13 @@ static int serial8250_startup(struct uart_port *port)
 
 	spin_lock_irqsave(&up->port.lock, flags);
 	if (up->port.flags & UPF_FOURPORT) {
-		if (!is_real_interrupt(up->port.irq))
+		if (!up->port.irq)
 			up->port.mctrl |= TIOCM_OUT1;
 	} else
 		/*
 		 * Most PC uarts need OUT2 raised to enable interrupts.
 		 */
-		if (is_real_interrupt(up->port.irq))
+		if (up->port.irq)
 			up->port.mctrl |= TIOCM_OUT2;
 
 	serial8250_set_mctrl(&up->port, up->port.mctrl);
@@ -2223,7 +2215,7 @@ static void serial8250_shutdown(struct uart_port *port)
 
 	del_timer_sync(&up->timer);
 	up->timer.function = serial8250_timeout;
-	if (is_real_interrupt(up->port.irq))
+	if (up->port.irq)
 		serial_unlink_irq_chain(up);
 }
 
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2de9924..76e7764 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1347,4 +1347,17 @@ config SERIAL_AR933X_NR_UARTS
 	  Set this to the number of serial ports you want the driver
 	  to support.
 
+config SERIAL_EFM32_UART
+	tristate "EFM32 UART/USART port."
+	depends on ARCH_EFM32
+	select SERIAL_CORE
+	help
+	  This driver support the USART and UART ports on
+	  Energy Micro's efm32 SoCs.
+
+config SERIAL_EFM32_UART_CONSOLE
+	bool "EFM32 UART/USART console support"
+	depends on SERIAL_EFM32_UART=y
+	select SERIAL_CORE_CONSOLE
+
 endmenu
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index fef32e1..7257c5d 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -61,12 +61,12 @@ obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
 obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
 obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
 obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
+obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
 obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
 obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
 obj-$(CONFIG_SERIAL_TIMBERDALE)	+= timbuart.o
 obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
 obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
-obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
 obj-$(CONFIG_SERIAL_VT8500) += vt8500_serial.o
 obj-$(CONFIG_SERIAL_MRST_MAX3110)	+= mrst_max3110.o
 obj-$(CONFIG_SERIAL_MFD_HSU)	+= mfd.o
@@ -78,3 +78,4 @@ obj-$(CONFIG_SERIAL_LANTIQ)	+= lantiq.o
 obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
 obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
 obj-$(CONFIG_SERIAL_AR933X)   += ar933x_uart.o
+obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
index 1d04c50..e790375 100644
--- a/drivers/tty/serial/altera_uart.c
+++ b/drivers/tty/serial/altera_uart.c
@@ -377,6 +377,26 @@ static int altera_uart_verify_port(struct uart_port *port,
 	return 0;
 }
 
+#ifdef CONFIG_CONSOLE_POLL
+static int altera_uart_poll_get_char(struct uart_port *port)
+{
+	while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
+		 ALTERA_UART_STATUS_RRDY_MSK))
+		cpu_relax();
+
+	return altera_uart_readl(port, ALTERA_UART_RXDATA_REG);
+}
+
+static void altera_uart_poll_put_char(struct uart_port *port, unsigned char c)
+{
+	while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
+		 ALTERA_UART_STATUS_TRDY_MSK))
+		cpu_relax();
+
+	altera_uart_writel(port, c, ALTERA_UART_TXDATA_REG);
+}
+#endif
+
 /*
  *	Define the basic serial functions we support.
  */
@@ -397,35 +417,16 @@ static struct uart_ops altera_uart_ops = {
 	.release_port	= altera_uart_release_port,
 	.config_port	= altera_uart_config_port,
 	.verify_port	= altera_uart_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+	.poll_get_char	= altera_uart_poll_get_char,
+	.poll_put_char	= altera_uart_poll_put_char,
+#endif
 };
 
 static struct altera_uart altera_uart_ports[CONFIG_SERIAL_ALTERA_UART_MAXPORTS];
 
 #if defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
 
-int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp)
-{
-	struct uart_port *port;
-	int i;
-
-	for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS && platp[i].mapbase; i++) {
-		port = &altera_uart_ports[i].port;
-
-		port->line = i;
-		port->type = PORT_ALTERA_UART;
-		port->mapbase = platp[i].mapbase;
-		port->membase = ioremap(port->mapbase, ALTERA_UART_SIZE);
-		port->iotype = SERIAL_IO_MEM;
-		port->irq = platp[i].irq;
-		port->uartclk = platp[i].uartclk;
-		port->flags = UPF_BOOT_AUTOCONF;
-		port->ops = &altera_uart_ops;
-		port->private_data = platp;
-	}
-
-	return 0;
-}
-
 static void altera_uart_console_putc(struct uart_port *port, const char c)
 {
 	while (!(altera_uart_readl(port, ALTERA_UART_STATUS_REG) &
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
new file mode 100644
index 0000000..615e464
--- /dev/null
+++ b/drivers/tty/serial/efm32-uart.c
@@ -0,0 +1,830 @@
+#if defined(CONFIG_SERIAL_EFM32_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/serial_core.h>
+#include <linux/tty_flip.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include <linux/platform_data/efm32-uart.h>
+
+#define DRIVER_NAME "efm32-uart"
+#define DEV_NAME "ttyefm"
+
+#define UARTn_CTRL		0x00
+#define UARTn_CTRL_SYNC		0x0001
+#define UARTn_CTRL_TXBIL		0x1000
+
+#define UARTn_FRAME		0x04
+#define UARTn_FRAME_DATABITS__MASK	0x000f
+#define UARTn_FRAME_DATABITS(n)		((n) - 3)
+#define UARTn_FRAME_PARITY_NONE		0x0000
+#define UARTn_FRAME_PARITY_EVEN		0x0200
+#define UARTn_FRAME_PARITY_ODD		0x0300
+#define UARTn_FRAME_STOPBITS_HALF	0x0000
+#define UARTn_FRAME_STOPBITS_ONE	0x1000
+#define UARTn_FRAME_STOPBITS_TWO	0x3000
+
+#define UARTn_CMD		0x0c
+#define UARTn_CMD_RXEN			0x0001
+#define UARTn_CMD_RXDIS		0x0002
+#define UARTn_CMD_TXEN			0x0004
+#define UARTn_CMD_TXDIS		0x0008
+
+#define UARTn_STATUS		0x10
+#define UARTn_STATUS_TXENS		0x0002
+#define UARTn_STATUS_TXC		0x0020
+#define UARTn_STATUS_TXBL		0x0040
+#define UARTn_STATUS_RXDATAV		0x0080
+
+#define UARTn_CLKDIV		0x14
+
+#define UARTn_RXDATAX		0x18
+#define UARTn_RXDATAX_RXDATA__MASK	0x01ff
+#define UARTn_RXDATAX_PERR		0x4000
+#define UARTn_RXDATAX_FERR		0x8000
+/*
+ * This is a software only flag used for ignore_status_mask and
+ * read_status_mask! It's used for breaks that the hardware doesn't report
+ * explicitly.
+ */
+#define SW_UARTn_RXDATAX_BERR		0x2000
+
+#define UARTn_TXDATA		0x34
+
+#define UARTn_IF		0x40
+#define UARTn_IF_TXC			0x0001
+#define UARTn_IF_TXBL			0x0002
+#define UARTn_IF_RXDATAV		0x0004
+#define UARTn_IF_RXOF			0x0010
+
+#define UARTn_IFS		0x44
+#define UARTn_IFC		0x48
+#define UARTn_IEN		0x4c
+
+#define UARTn_ROUTE		0x54
+#define UARTn_ROUTE_LOCATION__MASK	0x0700
+#define UARTn_ROUTE_LOCATION(n)		(((n) << 8) & UARTn_ROUTE_LOCATION__MASK)
+#define UARTn_ROUTE_RXPEN		0x0001
+#define UARTn_ROUTE_TXPEN		0x0002
+
+struct efm32_uart_port {
+	struct uart_port port;
+	unsigned int txirq;
+	struct clk *clk;
+};
+#define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port)
+#define efm_debug(efm_port, format, arg...)			\
+	dev_dbg(efm_port->port.dev, format, ##arg)
+
+static void efm32_uart_write32(struct efm32_uart_port *efm_port,
+		u32 value, unsigned offset)
+{
+	writel_relaxed(value, efm_port->port.membase + offset);
+}
+
+static u32 efm32_uart_read32(struct efm32_uart_port *efm_port,
+		unsigned offset)
+{
+	return readl_relaxed(efm_port->port.membase + offset);
+}
+
+static unsigned int efm32_uart_tx_empty(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	u32 status = efm32_uart_read32(efm_port, UARTn_STATUS);
+
+	if (status & UARTn_STATUS_TXC)
+		return TIOCSER_TEMT;
+	else
+		return 0;
+}
+
+static void efm32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	/* sorry, neither handshaking lines nor loop functionallity */
+}
+
+static unsigned int efm32_uart_get_mctrl(struct uart_port *port)
+{
+	/* sorry, no handshaking lines available */
+	return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR;
+}
+
+static void efm32_uart_stop_tx(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	u32 ien = efm32_uart_read32(efm_port,  UARTn_IEN);
+
+	efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD);
+	ien &= ~(UARTn_IF_TXC | UARTn_IF_TXBL);
+	efm32_uart_write32(efm_port, ien, UARTn_IEN);
+}
+
+static void efm32_uart_tx_chars(struct efm32_uart_port *efm_port)
+{
+	struct uart_port *port = &efm_port->port;
+	struct circ_buf *xmit = &port->state->xmit;
+
+	while (efm32_uart_read32(efm_port, UARTn_STATUS) &
+			UARTn_STATUS_TXBL) {
+		if (port->x_char) {
+			port->icount.tx++;
+			efm32_uart_write32(efm_port, port->x_char,
+					UARTn_TXDATA);
+			port->x_char = 0;
+			continue;
+		}
+		if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) {
+			port->icount.tx++;
+			efm32_uart_write32(efm_port, xmit->buf[xmit->tail],
+					UARTn_TXDATA);
+			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		} else
+			break;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (!port->x_char && uart_circ_empty(xmit) &&
+			efm32_uart_read32(efm_port, UARTn_STATUS) &
+				UARTn_STATUS_TXC)
+		efm32_uart_stop_tx(port);
+}
+
+static void efm32_uart_start_tx(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	u32 ien;
+
+	efm32_uart_write32(efm_port,
+			UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IFC);
+	ien = efm32_uart_read32(efm_port, UARTn_IEN);
+	efm32_uart_write32(efm_port,
+			ien | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IEN);
+	efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD);
+
+	efm32_uart_tx_chars(efm_port);
+}
+
+static void efm32_uart_stop_rx(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+
+	efm32_uart_write32(efm_port, UARTn_CMD_RXDIS, UARTn_CMD);
+}
+
+static void efm32_uart_enable_ms(struct uart_port *port)
+{
+	/* no handshake lines, no modem status interrupts */
+}
+
+static void efm32_uart_break_ctl(struct uart_port *port, int ctl)
+{
+	/* not possible without fiddling with gpios */
+}
+
+static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port,
+		struct tty_struct *tty)
+{
+	struct uart_port *port = &efm_port->port;
+
+	while (efm32_uart_read32(efm_port, UARTn_STATUS) &
+			UARTn_STATUS_RXDATAV) {
+		u32 rxdata = efm32_uart_read32(efm_port, UARTn_RXDATAX);
+		int flag = 0;
+
+		/*
+		 * This is a reserved bit and I only saw it read as 0. But to be
+		 * sure not to be confused too much by new devices adhere to the
+		 * warning in the reference manual that reserverd bits might
+		 * read as 1 in the future.
+		 */
+		rxdata &= ~SW_UARTn_RXDATAX_BERR;
+
+		port->icount.rx++;
+
+		if ((rxdata & UARTn_RXDATAX_FERR) &&
+				!(rxdata & UARTn_RXDATAX_RXDATA__MASK)) {
+			rxdata |= SW_UARTn_RXDATAX_BERR;
+			port->icount.brk++;
+			if (uart_handle_break(port))
+				continue;
+		} else if (rxdata & UARTn_RXDATAX_PERR)
+			port->icount.parity++;
+		else if (rxdata & UARTn_RXDATAX_FERR)
+			port->icount.frame++;
+
+		rxdata &= port->read_status_mask;
+
+		if (rxdata & SW_UARTn_RXDATAX_BERR)
+			flag = TTY_BREAK;
+		else if (rxdata & UARTn_RXDATAX_PERR)
+			flag = TTY_PARITY;
+		else if (rxdata & UARTn_RXDATAX_FERR)
+			flag = TTY_FRAME;
+		else if (uart_handle_sysrq_char(port,
+					rxdata & UARTn_RXDATAX_RXDATA__MASK))
+			continue;
+
+		if (tty && (rxdata & port->ignore_status_mask) == 0)
+			tty_insert_flip_char(tty,
+					rxdata & UARTn_RXDATAX_RXDATA__MASK, flag);
+	}
+}
+
+static irqreturn_t efm32_uart_rxirq(int irq, void *data)
+{
+	struct efm32_uart_port *efm_port = data;
+	u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF);
+	int handled = IRQ_NONE;
+	struct uart_port *port = &efm_port->port;
+	struct tty_struct *tty;
+
+	spin_lock(&port->lock);
+
+	tty = tty_kref_get(port->state->port.tty);
+
+	if (irqflag & UARTn_IF_RXDATAV) {
+		efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC);
+		efm32_uart_rx_chars(efm_port, tty);
+
+		handled = IRQ_HANDLED;
+	}
+
+	if (irqflag & UARTn_IF_RXOF) {
+		efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC);
+		port->icount.overrun++;
+		if (tty)
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+		handled = IRQ_HANDLED;
+	}
+
+	if (tty) {
+		tty_flip_buffer_push(tty);
+		tty_kref_put(tty);
+	}
+
+	spin_unlock(&port->lock);
+
+	return handled;
+}
+
+static irqreturn_t efm32_uart_txirq(int irq, void *data)
+{
+	struct efm32_uart_port *efm_port = data;
+	u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF);
+
+	/* TXBL doesn't need to be cleared */
+	if (irqflag & UARTn_IF_TXC)
+		efm32_uart_write32(efm_port, UARTn_IF_TXC, UARTn_IFC);
+
+	if (irqflag & (UARTn_IF_TXC | UARTn_IF_TXBL)) {
+		efm32_uart_tx_chars(efm_port);
+		return IRQ_HANDLED;
+	} else
+		return IRQ_NONE;
+}
+
+static int efm32_uart_startup(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	u32 location = 0;
+	struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev);
+	int ret;
+
+	if (pdata)
+		location = UARTn_ROUTE_LOCATION(pdata->location);
+
+	ret = clk_enable(efm_port->clk);
+	if (ret) {
+		efm_debug(efm_port, "failed to enable clk\n");
+		goto err_clk_enable;
+	}
+	port->uartclk = clk_get_rate(efm_port->clk);
+
+	/* Enable pins at configured location */
+	efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN,
+			UARTn_ROUTE);
+
+	ret = request_irq(port->irq, efm32_uart_rxirq, 0,
+			DRIVER_NAME, efm_port);
+	if (ret) {
+		efm_debug(efm_port, "failed to register rxirq\n");
+		goto err_request_irq_rx;
+	}
+
+	/* disable all irqs */
+	efm32_uart_write32(efm_port, 0, UARTn_IEN);
+
+	ret = request_irq(efm_port->txirq, efm32_uart_txirq, 0,
+			DRIVER_NAME, efm_port);
+	if (ret) {
+		efm_debug(efm_port, "failed to register txirq\n");
+		free_irq(port->irq, efm_port);
+err_request_irq_rx:
+
+		clk_disable(efm_port->clk);
+	} else {
+		efm32_uart_write32(efm_port,
+				UARTn_IF_RXDATAV | UARTn_IF_RXOF, UARTn_IEN);
+		efm32_uart_write32(efm_port, UARTn_CMD_RXEN, UARTn_CMD);
+	}
+
+err_clk_enable:
+	return ret;
+}
+
+static void efm32_uart_shutdown(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+
+	efm32_uart_write32(efm_port, 0, UARTn_IEN);
+	free_irq(port->irq, efm_port);
+
+	clk_disable(efm_port->clk);
+}
+
+static void efm32_uart_set_termios(struct uart_port *port,
+		struct ktermios *new, struct ktermios *old)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	unsigned long flags;
+	unsigned baud;
+	u32 clkdiv;
+	u32 frame = 0;
+
+	/* no modem control lines */
+	new->c_cflag &= ~(CRTSCTS | CMSPAR);
+
+	baud = uart_get_baud_rate(port, new, old,
+			DIV_ROUND_CLOSEST(port->uartclk, 16 * 8192),
+			DIV_ROUND_CLOSEST(port->uartclk, 16));
+
+	switch (new->c_cflag & CSIZE) {
+	case CS5:
+		frame |= UARTn_FRAME_DATABITS(5);
+		break;
+	case CS6:
+		frame |= UARTn_FRAME_DATABITS(6);
+		break;
+	case CS7:
+		frame |= UARTn_FRAME_DATABITS(7);
+		break;
+	case CS8:
+		frame |= UARTn_FRAME_DATABITS(8);
+		break;
+	}
+
+	if (new->c_cflag & CSTOPB)
+		/* the receiver only verifies the first stop bit */
+		frame |= UARTn_FRAME_STOPBITS_TWO;
+	else
+		frame |= UARTn_FRAME_STOPBITS_ONE;
+
+	if (new->c_cflag & PARENB) {
+		if (new->c_cflag & PARODD)
+			frame |= UARTn_FRAME_PARITY_ODD;
+		else
+			frame |= UARTn_FRAME_PARITY_EVEN;
+	} else
+		frame |= UARTn_FRAME_PARITY_NONE;
+
+	/*
+	 * the 6 lowest bits of CLKDIV are dc, bit 6 has value 0.25.
+	 * port->uartclk <= 14e6, so 4 * port->uartclk doesn't overflow.
+	 */
+	clkdiv = (DIV_ROUND_CLOSEST(4 * port->uartclk, 16 * baud) - 4) << 6;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	efm32_uart_write32(efm_port,
+			UARTn_CMD_TXDIS | UARTn_CMD_RXDIS, UARTn_CMD);
+
+	port->read_status_mask = UARTn_RXDATAX_RXDATA__MASK;
+	if (new->c_iflag & INPCK)
+		port->read_status_mask |=
+			UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR;
+	if (new->c_iflag & (BRKINT | PARMRK))
+		port->read_status_mask |= SW_UARTn_RXDATAX_BERR;
+
+	port->ignore_status_mask = 0;
+	if (new->c_iflag & IGNPAR)
+		port->ignore_status_mask |=
+			UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR;
+	if (new->c_iflag & IGNBRK)
+		port->ignore_status_mask |= SW_UARTn_RXDATAX_BERR;
+
+	uart_update_timeout(port, new->c_cflag, baud);
+
+	efm32_uart_write32(efm_port, UARTn_CTRL_TXBIL, UARTn_CTRL);
+	efm32_uart_write32(efm_port, frame, UARTn_FRAME);
+	efm32_uart_write32(efm_port, clkdiv, UARTn_CLKDIV);
+
+	efm32_uart_write32(efm_port, UARTn_CMD_TXEN | UARTn_CMD_RXEN,
+			UARTn_CMD);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *efm32_uart_type(struct uart_port *port)
+{
+	return port->type == PORT_EFMUART ? "efm32-uart" : NULL;
+}
+
+static void efm32_uart_release_port(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+
+	clk_unprepare(efm_port->clk);
+	clk_put(efm_port->clk);
+	iounmap(port->membase);
+}
+
+static int efm32_uart_request_port(struct uart_port *port)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	int ret;
+
+	port->membase = ioremap(port->mapbase, 60);
+	if (!efm_port->port.membase) {
+		ret = -ENOMEM;
+		efm_debug(efm_port, "failed to remap\n");
+		goto err_ioremap;
+	}
+
+	efm_port->clk = clk_get(port->dev, NULL);
+	if (IS_ERR(efm_port->clk)) {
+		ret = PTR_ERR(efm_port->clk);
+		efm_debug(efm_port, "failed to get clock\n");
+		goto err_clk_get;
+	}
+
+	ret = clk_prepare(efm_port->clk);
+	if (ret) {
+		clk_put(efm_port->clk);
+err_clk_get:
+
+		iounmap(port->membase);
+err_ioremap:
+		return ret;
+	}
+	return 0;
+}
+
+static void efm32_uart_config_port(struct uart_port *port, int type)
+{
+	if (type & UART_CONFIG_TYPE &&
+			!efm32_uart_request_port(port))
+		port->type = PORT_EFMUART;
+}
+
+static int efm32_uart_verify_port(struct uart_port *port,
+		struct serial_struct *serinfo)
+{
+	int ret = 0;
+
+	if (serinfo->type != PORT_UNKNOWN && serinfo->type != PORT_EFMUART)
+		ret = -EINVAL;
+
+	return ret;
+}
+
+static struct uart_ops efm32_uart_pops = {
+	.tx_empty = efm32_uart_tx_empty,
+	.set_mctrl = efm32_uart_set_mctrl,
+	.get_mctrl = efm32_uart_get_mctrl,
+	.stop_tx = efm32_uart_stop_tx,
+	.start_tx = efm32_uart_start_tx,
+	.stop_rx = efm32_uart_stop_rx,
+	.enable_ms = efm32_uart_enable_ms,
+	.break_ctl = efm32_uart_break_ctl,
+	.startup = efm32_uart_startup,
+	.shutdown = efm32_uart_shutdown,
+	.set_termios = efm32_uart_set_termios,
+	.type = efm32_uart_type,
+	.release_port = efm32_uart_release_port,
+	.request_port = efm32_uart_request_port,
+	.config_port = efm32_uart_config_port,
+	.verify_port = efm32_uart_verify_port,
+};
+
+static struct efm32_uart_port *efm32_uart_ports[5];
+
+#ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE
+static void efm32_uart_console_putchar(struct uart_port *port, int ch)
+{
+	struct efm32_uart_port *efm_port = to_efm_port(port);
+	unsigned int timeout = 0x400;
+	u32 status;
+
+	while (1) {
+		status = efm32_uart_read32(efm_port, UARTn_STATUS);
+
+		if (status & UARTn_STATUS_TXBL)
+			break;
+		if (!timeout--)
+			return;
+	}
+	efm32_uart_write32(efm_port, ch, UARTn_TXDATA);
+}
+
+static void efm32_uart_console_write(struct console *co, const char *s,
+		unsigned int count)
+{
+	struct efm32_uart_port *efm_port = efm32_uart_ports[co->index];
+	u32 status = efm32_uart_read32(efm_port, UARTn_STATUS);
+	unsigned int timeout = 0x400;
+
+	if (!(status & UARTn_STATUS_TXENS))
+		efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD);
+
+	uart_console_write(&efm_port->port, s, count,
+			efm32_uart_console_putchar);
+
+	/* Wait for the transmitter to become empty */
+	while (1) {
+		u32 status = efm32_uart_read32(efm_port, UARTn_STATUS);
+		if (status & UARTn_STATUS_TXC)
+			break;
+		if (!timeout--)
+			break;
+	}
+
+	if (!(status & UARTn_STATUS_TXENS))
+		efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD);
+}
+
+static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port,
+		int *baud, int *parity, int *bits)
+{
+	u32 ctrl = efm32_uart_read32(efm_port, UARTn_CTRL);
+	u32 route, clkdiv, frame;
+
+	if (ctrl & UARTn_CTRL_SYNC)
+		/* not operating in async mode */
+		return;
+
+	route = efm32_uart_read32(efm_port, UARTn_ROUTE);
+	if (!(route & UARTn_ROUTE_TXPEN))
+		/* tx pin not routed */
+		return;
+
+	clkdiv = efm32_uart_read32(efm_port, UARTn_CLKDIV);
+
+	*baud = DIV_ROUND_CLOSEST(4 * efm_port->port.uartclk,
+			16 * (4 + (clkdiv >> 6)));
+
+	frame = efm32_uart_read32(efm_port, UARTn_FRAME);
+	if (frame & UARTn_FRAME_PARITY_ODD)
+		*parity = 'o';
+	else if (frame & UARTn_FRAME_PARITY_EVEN)
+		*parity = 'e';
+	else
+		*parity = 'n';
+
+	*bits = (frame & UARTn_FRAME_DATABITS__MASK) -
+			UARTn_FRAME_DATABITS(4) + 4;
+
+	efm_debug(efm_port, "get_opts: options=%d%c%d\n",
+			*baud, *parity, *bits);
+}
+
+static int efm32_uart_console_setup(struct console *co, char *options)
+{
+	struct efm32_uart_port *efm_port;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+	int ret;
+
+	if (co->index < 0 || co->index >= ARRAY_SIZE(efm32_uart_ports)) {
+		unsigned i;
+		for (i = 0; i < ARRAY_SIZE(efm32_uart_ports); ++i) {
+			if (efm32_uart_ports[i]) {
+				pr_warn("efm32-console: fall back to console index %u (from %hhi)\n",
+						i, co->index);
+				co->index = i;
+				break;
+			}
+		}
+	}
+
+	efm_port = efm32_uart_ports[co->index];
+	if (!efm_port) {
+		pr_warn("efm32-console: No port at %d\n", co->index);
+		return -ENODEV;
+	}
+
+	ret = clk_prepare(efm_port->clk);
+	if (ret) {
+		dev_warn(efm_port->port.dev,
+				"console: clk_prepare failed: %d\n", ret);
+		return ret;
+	}
+
+	efm_port->port.uartclk = clk_get_rate(efm_port->clk);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	else
+		efm32_uart_console_get_options(efm_port,
+				&baud, &parity, &bits);
+
+	return uart_set_options(&efm_port->port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver efm32_uart_reg;
+
+static struct console efm32_uart_console = {
+	.name = DEV_NAME,
+	.write = efm32_uart_console_write,
+	.device = uart_console_device,
+	.setup = efm32_uart_console_setup,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+	.data = &efm32_uart_reg,
+};
+
+#else
+#define efm32_uart_console (*(struct console *)NULL)
+#endif /* ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE / else */
+
+static struct uart_driver efm32_uart_reg = {
+	.owner = THIS_MODULE,
+	.driver_name = DRIVER_NAME,
+	.dev_name = DEV_NAME,
+	.nr = ARRAY_SIZE(efm32_uart_ports),
+	.cons = &efm32_uart_console,
+};
+
+static int efm32_uart_probe_dt(struct platform_device *pdev,
+		struct efm32_uart_port *efm_port)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	if (!np)
+		return 1;
+
+	ret = of_alias_get_id(np, "serial");
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to get alias id: %d\n", ret);
+		return ret;
+	} else {
+		efm_port->port.line = ret;
+		return 0;
+	}
+
+}
+
+static int __devinit efm32_uart_probe(struct platform_device *pdev)
+{
+	struct efm32_uart_port *efm_port;
+	struct resource *res;
+	int ret;
+
+	efm_port = kzalloc(sizeof(*efm_port), GFP_KERNEL);
+	if (!efm_port) {
+		dev_dbg(&pdev->dev, "failed to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		dev_dbg(&pdev->dev, "failed to determine base address\n");
+		goto err_get_base;
+	}
+
+	if (resource_size(res) < 60) {
+		ret = -EINVAL;
+		dev_dbg(&pdev->dev, "memory resource too small\n");
+		goto err_too_small;
+	}
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret <= 0) {
+		dev_dbg(&pdev->dev, "failed to get rx irq\n");
+		goto err_get_rxirq;
+	}
+
+	efm_port->port.irq = ret;
+
+	ret = platform_get_irq(pdev, 1);
+	if (ret <= 0)
+		ret = efm_port->port.irq + 1;
+
+	efm_port->txirq = ret;
+
+	efm_port->port.dev = &pdev->dev;
+	efm_port->port.mapbase = res->start;
+	efm_port->port.type = PORT_EFMUART;
+	efm_port->port.iotype = UPIO_MEM32;
+	efm_port->port.fifosize = 2;
+	efm_port->port.ops = &efm32_uart_pops;
+	efm_port->port.flags = UPF_BOOT_AUTOCONF;
+
+	ret = efm32_uart_probe_dt(pdev, efm_port);
+	if (ret > 0)
+		/* not created by device tree */
+		efm_port->port.line = pdev->id;
+
+	if (efm_port->port.line >= 0 &&
+			efm_port->port.line < ARRAY_SIZE(efm32_uart_ports))
+		efm32_uart_ports[efm_port->port.line] = efm_port;
+
+	ret = uart_add_one_port(&efm32_uart_reg, &efm_port->port);
+	if (ret) {
+		dev_dbg(&pdev->dev, "failed to add port: %d\n", ret);
+
+		if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports))
+			efm32_uart_ports[pdev->id] = NULL;
+err_get_rxirq:
+err_too_small:
+err_get_base:
+		kfree(efm_port);
+	} else {
+		platform_set_drvdata(pdev, efm_port);
+		dev_dbg(&pdev->dev, "\\o/\n");
+	}
+
+	return ret;
+}
+
+static int __devexit efm32_uart_remove(struct platform_device *pdev)
+{
+	struct efm32_uart_port *efm_port = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	uart_remove_one_port(&efm32_uart_reg, &efm_port->port);
+
+	if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports))
+		efm32_uart_ports[pdev->id] = NULL;
+
+	kfree(efm_port);
+
+	return 0;
+}
+
+static struct of_device_id efm32_uart_dt_ids[] = {
+	{
+		.compatible = "efm32,uart",
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids);
+
+static struct platform_driver efm32_uart_driver = {
+	.probe = efm32_uart_probe,
+	.remove = __devexit_p(efm32_uart_remove),
+
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = efm32_uart_dt_ids,
+	},
+};
+
+static int __init efm32_uart_init(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&efm32_uart_reg);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&efm32_uart_driver);
+	if (ret)
+		uart_unregister_driver(&efm32_uart_reg);
+
+	pr_info("EFM32 UART/USART driver\n");
+
+	return ret;
+}
+module_init(efm32_uart_init);
+
+static void __exit efm32_uart_exit(void)
+{
+	platform_driver_unregister(&efm32_uart_driver);
+	uart_unregister_driver(&efm32_uart_reg);
+}
+
+MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
+MODULE_DESCRIPTION("EFM32 UART/USART driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 0b7fed7..e7fecee 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1508,7 +1508,7 @@ static int serial_imx_probe(struct platform_device *pdev)
 		ret = PTR_ERR(sport->clk);
 		goto unmap;
 	}
-	clk_enable(sport->clk);
+	clk_prepare_enable(sport->clk);
 
 	sport->port.uartclk = clk_get_rate(sport->clk);
 
@@ -1531,8 +1531,8 @@ deinit:
 	if (pdata && pdata->exit)
 		pdata->exit(pdev);
 clkput:
+	clk_disable_unprepare(sport->clk);
 	clk_put(sport->clk);
-	clk_disable(sport->clk);
 unmap:
 	iounmap(sport->port.membase);
 free:
@@ -1552,11 +1552,10 @@ static int serial_imx_remove(struct platform_device *pdev)
 
 	if (sport) {
 		uart_remove_one_port(&imx_reg, &sport->port);
+		clk_disable_unprepare(sport->clk);
 		clk_put(sport->clk);
 	}
 
-	clk_disable(sport->clk);
-
 	if (pdata && pdata->exit)
 		pdata->exit(pdev);
 
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c
index 94a6792..e465dda 100644
--- a/drivers/tty/serial/m32r_sio.c
+++ b/drivers/tty/serial/m32r_sio.c
@@ -70,13 +70,6 @@
 
 #define PASS_LIMIT	256
 
-/*
- * We default to IRQ0 for the "no irq" hack.   Some
- * machine types want others as well - they're free
- * to redefine this in their header file.
- */
-#define is_real_interrupt(irq)	((irq) != 0)
-
 #define BASE_BAUD	115200
 
 /* Standard COM flags */
@@ -640,7 +633,7 @@ static int m32r_sio_startup(struct uart_port *port)
 	 * hardware interrupt, we use a timer-based system.  The original
 	 * driver used to do this with IRQ0.
 	 */
-	if (!is_real_interrupt(up->port.irq)) {
+	if (!up->port.irq) {
 		unsigned int timeout = up->port.timeout;
 
 		timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
@@ -687,7 +680,7 @@ static void m32r_sio_shutdown(struct uart_port *port)
 
 	sio_init();
 
-	if (!is_real_interrupt(up->port.irq))
+	if (!up->port.irq)
 		del_timer_sync(&up->timer);
 	else
 		serial_unlink_irq_chain(up);
diff --git a/drivers/tty/serial/m32r_sio.h b/drivers/tty/serial/m32r_sio.h
deleted file mode 100644
index e9b7e11..0000000
--- a/drivers/tty/serial/m32r_sio.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  m32r_sio.h
- *
- *  Driver for M32R serial ports
- *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
- *  Based on drivers/serial/8250.h.
- *
- *  Copyright (C) 2001  Russell King.
- *  Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.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.
- */
-
-
-struct m32r_sio_probe {
-	struct module	*owner;
-	int		(*pci_init_one)(struct pci_dev *dev);
-	void		(*pci_remove_one)(struct pci_dev *dev);
-	void		(*pnp_init)(void);
-};
-
-int m32r_sio_register_probe(struct m32r_sio_probe *probe);
-void m32r_sio_unregister_probe(struct m32r_sio_probe *probe);
-void m32r_sio_get_irq_map(unsigned int *map);
-void m32r_sio_suspend_port(int line);
-void m32r_sio_resume_port(int line);
-
-struct old_serial_port {
-	unsigned int uart;
-	unsigned int baud_base;
-	unsigned int port;
-	unsigned int irq;
-	unsigned int flags;
-	unsigned char io_type;
-	unsigned char __iomem *iomem_base;
-	unsigned short iomem_reg_shift;
-};
-
-#define _INLINE_ inline
-
-#define PROBE_RSA	(1 << 0)
-#define PROBE_ANY	(~0)
-
-#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
diff --git a/drivers/tty/serial/m32r_sio_reg.h b/drivers/tty/serial/m32r_sio_reg.h
deleted file mode 100644
index 4671473..0000000
--- a/drivers/tty/serial/m32r_sio_reg.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * m32r_sio_reg.h
- *
- * Copyright (C) 1992, 1994 by Theodore Ts'o.
- * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
- *
- * Redistribution of this file is permitted under the terms of the GNU
- * Public License (GPL)
- *
- * These are the UART port assignments, expressed as offsets from the base
- * register.  These assignments should hold for any serial port based on
- * a 8250, 16450, or 16550(A).
- */
-
-#ifndef _M32R_SIO_REG_H
-#define _M32R_SIO_REG_H
-
-
-#ifdef CONFIG_SERIAL_M32R_PLDSIO
-
-#define SIOCR		0x000
-#define SIOMOD0		0x002
-#define SIOMOD1		0x004
-#define SIOSTS		0x006
-#define SIOTRCR		0x008
-#define SIOBAUR		0x00a
-// #define SIORBAUR	0x018
-#define SIOTXB		0x00c
-#define SIORXB		0x00e
-
-#define UART_RX		((unsigned long) PLD_ESIO0RXB)
-				/* In:  Receive buffer (DLAB=0) */
-#define UART_TX		((unsigned long) PLD_ESIO0TXB)
-				/* Out: Transmit buffer (DLAB=0) */
-#define UART_DLL	0	/* Out: Divisor Latch Low (DLAB=1) */
-#define UART_TRG	0	/* (LCR=BF) FCTR bit 7 selects Rx or Tx
-				 * In: Fifo count
-				 * Out: Fifo custom trigger levels
-				 * XR16C85x only */
-
-#define UART_DLM	0	/* Out: Divisor Latch High (DLAB=1) */
-#define UART_IER	((unsigned long) PLD_ESIO0INTCR)
-				/* Out: Interrupt Enable Register */
-#define UART_FCTR	0	/* (LCR=BF) Feature Control Register
-				 * XR16C85x only */
-
-#define UART_IIR	0	/* In:  Interrupt ID Register */
-#define UART_FCR	0	/* Out: FIFO Control Register */
-#define UART_EFR	0	/* I/O: Extended Features Register */
-				/* (DLAB=1, 16C660 only) */
-
-#define UART_LCR	0	/* Out: Line Control Register */
-#define UART_MCR	0	/* Out: Modem Control Register */
-#define UART_LSR	((unsigned long) PLD_ESIO0STS)
-				/* In:  Line Status Register */
-#define UART_MSR	0	/* In:  Modem Status Register */
-#define UART_SCR	0	/* I/O: Scratch Register */
-#define UART_EMSR	0	/* (LCR=BF) Extended Mode Select Register
-				 * FCTR bit 6 selects SCR or EMSR
-				 * XR16c85x only */
-
-#else /* not CONFIG_SERIAL_M32R_PLDSIO */
-
-#define SIOCR		0x000
-#define SIOMOD0		0x004
-#define SIOMOD1		0x008
-#define SIOSTS		0x00c
-#define SIOTRCR		0x010
-#define SIOBAUR		0x014
-#define SIORBAUR	0x018
-#define SIOTXB		0x01c
-#define SIORXB		0x020
-
-#define UART_RX		M32R_SIO0_RXB_PORTL	/* In:  Receive buffer (DLAB=0) */
-#define UART_TX		M32R_SIO0_TXB_PORTL	/* Out: Transmit buffer (DLAB=0) */
-#define UART_DLL	0	/* Out: Divisor Latch Low (DLAB=1) */
-#define UART_TRG	0	/* (LCR=BF) FCTR bit 7 selects Rx or Tx
-				 * In: Fifo count
-				 * Out: Fifo custom trigger levels
-				 * XR16C85x only */
-
-#define UART_DLM	0	/* Out: Divisor Latch High (DLAB=1) */
-#define UART_IER	M32R_SIO0_TRCR_PORTL	/* Out: Interrupt Enable Register */
-#define UART_FCTR	0	/* (LCR=BF) Feature Control Register
-				 * XR16C85x only */
-
-#define UART_IIR	0	/* In:  Interrupt ID Register */
-#define UART_FCR	0	/* Out: FIFO Control Register */
-#define UART_EFR	0	/* I/O: Extended Features Register */
-				/* (DLAB=1, 16C660 only) */
-
-#define UART_LCR	0	/* Out: Line Control Register */
-#define UART_MCR	0	/* Out: Modem Control Register */
-#define UART_LSR	M32R_SIO0_STS_PORTL	/* In:  Line Status Register */
-#define UART_MSR	0	/* In:  Modem Status Register */
-#define UART_SCR	0	/* I/O: Scratch Register */
-#define UART_EMSR	0	/* (LCR=BF) Extended Mode Select Register
-				 * FCTR bit 6 selects SCR or EMSR
-				 * XR16c85x only */
-
-#endif /* CONFIG_SERIAL_M32R_PLDSIO */
-
-#define UART_EMPTY	(UART_LSR_TEMT | UART_LSR_THRE)
-
-/*
- * These are the definitions for the Line Control Register
- *
- * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
- * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
- */
-#define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
-#define UART_LCR_SBC	0x40	/* Set break control */
-#define UART_LCR_SPAR	0x20	/* Stick parity (?) */
-#define UART_LCR_EPAR	0x10	/* Even parity select */
-#define UART_LCR_PARITY	0x08	/* Parity Enable */
-#define UART_LCR_STOP	0x04	/* Stop bits: 0=1 stop bit, 1= 2 stop bits */
-#define UART_LCR_WLEN5  0x00	/* Wordlength: 5 bits */
-#define UART_LCR_WLEN6  0x01	/* Wordlength: 6 bits */
-#define UART_LCR_WLEN7  0x02	/* Wordlength: 7 bits */
-#define UART_LCR_WLEN8  0x03	/* Wordlength: 8 bits */
-
-/*
- * These are the definitions for the Line Status Register
- */
-#define UART_LSR_TEMT	0x02	/* Transmitter empty */
-#define UART_LSR_THRE	0x01	/* Transmit-hold-register empty */
-#define UART_LSR_BI	0x00	/* Break interrupt indicator */
-#define UART_LSR_FE	0x80	/* Frame error indicator */
-#define UART_LSR_PE	0x40	/* Parity error indicator */
-#define UART_LSR_OE	0x20	/* Overrun error indicator */
-#define UART_LSR_DR	0x04	/* Receiver data ready */
-
-/*
- * These are the definitions for the Interrupt Identification Register
- */
-#define UART_IIR_NO_INT	0x01	/* No interrupts pending */
-#define UART_IIR_ID	0x06	/* Mask for the interrupt ID */
-
-#define UART_IIR_MSI	0x00	/* Modem status interrupt */
-#define UART_IIR_THRI	0x02	/* Transmitter holding register empty */
-#define UART_IIR_RDI	0x04	/* Receiver data interrupt */
-#define UART_IIR_RLSI	0x06	/* Receiver line status interrupt */
-
-/*
- * These are the definitions for the Interrupt Enable Register
- */
-#define UART_IER_MSI	0x00	/* Enable Modem status interrupt */
-#define UART_IER_RLSI	0x08	/* Enable receiver line status interrupt */
-#define UART_IER_THRI	0x03	/* Enable Transmitter holding register int. */
-#define UART_IER_RDI	0x04	/* Enable receiver data interrupt */
-
-#endif /* _M32R_SIO_REG_H */
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 1093a88..e9a770d 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -507,7 +507,7 @@ static int __init mpc512x_psc_fifoc_init(void)
 
 	psc_fifoc_irq = irq_of_parse_and_map(np, 0);
 	of_node_put(np);
-	if (psc_fifoc_irq == NO_IRQ) {
+	if (psc_fifoc_irq == 0) {
 		pr_err("%s: Can't get FIFOC irq\n", __func__);
 		iounmap(psc_fifoc);
 		return -ENODEV;
@@ -1354,7 +1354,7 @@ static int __devinit mpc52xx_uart_of_probe(struct platform_device *op)
 	}
 
 	psc_ops->get_irq(port, op->dev.of_node);
-	if (port->irq == NO_IRQ) {
+	if (port->irq == 0) {
 		dev_dbg(&op->dev, "Could not get irq\n");
 		return -EINVAL;
 	}
diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c
index 06f6aef..c61d950 100644
--- a/drivers/tty/serial/mux.c
+++ b/drivers/tty/serial/mux.c
@@ -499,7 +499,7 @@ static int __init mux_probe(struct parisc_device *dev)
 		port->membase	= ioremap_nocache(port->mapbase, MUX_LINE_OFFSET);
 		port->iotype	= UPIO_MEM;
 		port->type	= PORT_MUX;
-		port->irq	= NO_IRQ;
+		port->irq	= 0;
 		port->uartclk	= 0;
 		port->fifosize	= MUX_FIFO_SIZE;
 		port->ops	= &mux_pops;
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
index 17ae657..aa4d07b 100644
--- a/drivers/tty/serial/pch_uart.c
+++ b/drivers/tty/serial/pch_uart.c
@@ -29,6 +29,7 @@
 #include <linux/nmi.h>
 #include <linux/delay.h>
 
+#include <linux/debugfs.h>
 #include <linux/dmaengine.h>
 #include <linux/pch_dma.h>
 
@@ -144,6 +145,8 @@ enum {
 #define PCH_UART_DLL		0x00
 #define PCH_UART_DLM		0x01
 
+#define PCH_UART_BRCSR		0x0E
+
 #define PCH_UART_IID_RLS	(PCH_UART_IIR_REI)
 #define PCH_UART_IID_RDR	(PCH_UART_IIR_RRI)
 #define PCH_UART_IID_RDR_TO	(PCH_UART_IIR_RRI | PCH_UART_IIR_TOI)
@@ -243,6 +246,8 @@ struct eg20t_port {
 	int				tx_dma_use;
 	void				*rx_buf_virt;
 	dma_addr_t			rx_buf_dma;
+
+	struct dentry	*debugfs;
 };
 
 /**
@@ -292,23 +297,73 @@ static const int trigger_level_64[4] = { 1, 16, 32, 56 };
 static const int trigger_level_16[4] = { 1, 4, 8, 14 };
 static const int trigger_level_1[4] = { 1, 1, 1, 1 };
 
-static void pch_uart_hal_request(struct pci_dev *pdev, int fifosize,
-				 int base_baud)
-{
-	struct eg20t_port *priv = pci_get_drvdata(pdev);
+#ifdef CONFIG_DEBUG_FS
 
-	priv->trigger_level = 1;
-	priv->fcr = 0;
+#define PCH_REGS_BUFSIZE	1024
+static int pch_show_regs_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
 }
 
-static unsigned int get_msr(struct eg20t_port *priv, void __iomem *base)
+static ssize_t port_show_regs(struct file *file, char __user *user_buf,
+				size_t count, loff_t *ppos)
 {
-	unsigned int msr = ioread8(base + UART_MSR);
-	priv->dmsr |= msr & PCH_UART_MSR_DELTA;
+	struct eg20t_port *priv = file->private_data;
+	char *buf;
+	u32 len = 0;
+	ssize_t ret;
+	unsigned char lcr;
+
+	buf = kzalloc(PCH_REGS_BUFSIZE, GFP_KERNEL);
+	if (!buf)
+		return 0;
+
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"PCH EG20T port[%d] regs:\n", priv->port.line);
+
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"=================================\n");
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"IER: \t0x%02x\n", ioread8(priv->membase + UART_IER));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"IIR: \t0x%02x\n", ioread8(priv->membase + UART_IIR));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"LCR: \t0x%02x\n", ioread8(priv->membase + UART_LCR));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"MCR: \t0x%02x\n", ioread8(priv->membase + UART_MCR));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"LSR: \t0x%02x\n", ioread8(priv->membase + UART_LSR));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"MSR: \t0x%02x\n", ioread8(priv->membase + UART_MSR));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"BRCSR: \t0x%02x\n",
+			ioread8(priv->membase + PCH_UART_BRCSR));
 
-	return msr;
+	lcr = ioread8(priv->membase + UART_LCR);
+	iowrite8(PCH_UART_LCR_DLAB, priv->membase + UART_LCR);
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"DLL: \t0x%02x\n", ioread8(priv->membase + UART_DLL));
+	len += snprintf(buf + len, PCH_REGS_BUFSIZE - len,
+			"DLM: \t0x%02x\n", ioread8(priv->membase + UART_DLM));
+	iowrite8(lcr, priv->membase + UART_LCR);
+
+	if (len > PCH_REGS_BUFSIZE)
+		len = PCH_REGS_BUFSIZE;
+
+	ret =  simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+	return ret;
 }
 
+static const struct file_operations port_regs_ops = {
+	.owner		= THIS_MODULE,
+	.open		= pch_show_regs_open,
+	.read		= port_show_regs,
+	.llseek		= default_llseek,
+};
+#endif	/* CONFIG_DEBUG_FS */
+
 static void pch_uart_hal_enable_interrupt(struct eg20t_port *priv,
 					  unsigned int flag)
 {
@@ -442,8 +497,9 @@ static int pch_uart_hal_set_fifo(struct eg20t_port *priv,
 
 static u8 pch_uart_hal_get_modem(struct eg20t_port *priv)
 {
-	priv->dmsr = 0;
-	return get_msr(priv, priv->membase);
+	unsigned int msr = ioread8(priv->membase + UART_MSR);
+	priv->dmsr = msr & PCH_UART_MSR_DELTA;
+	return (u8)msr;
 }
 
 static void pch_uart_hal_write(struct eg20t_port *priv,
@@ -524,7 +580,7 @@ static int push_rx(struct eg20t_port *priv, const unsigned char *buf,
 
 static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf)
 {
-	int ret;
+	int ret = 0;
 	struct uart_port *port = &priv->port;
 
 	if (port->x_char) {
@@ -533,8 +589,6 @@ static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf)
 		buf[0] = port->x_char;
 		port->x_char = 0;
 		ret = 1;
-	} else {
-		ret = 0;
 	}
 
 	return ret;
@@ -1032,14 +1086,12 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
 static unsigned int pch_uart_tx_empty(struct uart_port *port)
 {
 	struct eg20t_port *priv;
-	int ret;
+
 	priv = container_of(port, struct eg20t_port, port);
 	if (priv->tx_empty)
-		ret = TIOCSER_TEMT;
+		return TIOCSER_TEMT;
 	else
-		ret = 0;
-
-	return ret;
+		return 0;
 }
 
 /* Returns the current state of modem control inputs. */
@@ -1273,9 +1325,8 @@ static void pch_uart_set_termios(struct uart_port *port,
 		else
 			parity = PCH_UART_HAL_PARITY_EVEN;
 
-	} else {
+	} else
 		parity = PCH_UART_HAL_PARITY_NONE;
-	}
 
 	/* Only UART0 has auto hardware flow function */
 	if ((termios->c_cflag & CRTSCTS) && (priv->fifo_size == 256))
@@ -1447,7 +1498,6 @@ static void
 pch_console_write(struct console *co, const char *s, unsigned int count)
 {
 	struct eg20t_port *priv;
-
 	unsigned long flags;
 	u8 ier;
 	int locked = 1;
@@ -1554,6 +1604,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
 	int port_type;
 	struct pch_uart_driver_data *board;
 	const char *board_name;
+	char name[32];	/* for debugfs file name */
 
 	board = &drv_dat[id->driver_data];
 	port_type = board->port_type;
@@ -1614,7 +1665,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
 	spin_lock_init(&priv->port.lock);
 
 	pci_set_drvdata(pdev, priv);
-	pch_uart_hal_request(pdev, fifosize, base_baud);
+	priv->trigger_level = 1;
+	priv->fcr = 0;
 
 #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE
 	pch_uart_ports[board->line_no] = priv;
@@ -1623,6 +1675,12 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
 	if (ret < 0)
 		goto init_port_hal_free;
 
+#ifdef CONFIG_DEBUG_FS
+	snprintf(name, sizeof(name), "uart%d_regs", board->line_no);
+	priv->debugfs = debugfs_create_file(name, S_IFREG | S_IRUGO,
+				NULL, priv, &port_regs_ops);
+#endif
+
 	return priv;
 
 init_port_hal_free:
@@ -1639,6 +1697,11 @@ init_port_alloc_err:
 
 static void pch_uart_exit_port(struct eg20t_port *priv)
 {
+
+#ifdef CONFIG_DEBUG_FS
+	if (priv->debugfs)
+		debugfs_remove(priv->debugfs);
+#endif
 	uart_remove_one_port(&pch_uart_driver, &priv->port);
 	pci_set_drvdata(priv->pdev, NULL);
 	free_page((unsigned long)priv->rxbuf.buf);
@@ -1646,9 +1709,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv)
 
 static void pch_uart_pci_remove(struct pci_dev *pdev)
 {
-	struct eg20t_port *priv;
-
-	priv = (struct eg20t_port *)pci_get_drvdata(pdev);
+	struct eg20t_port *priv = pci_get_drvdata(pdev);
 
 	pci_disable_msi(pdev);
 
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index e9c2dfe4..08ebe90 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1506,7 +1506,7 @@ no_dma:
 	 * fixed up interrupt info, but we use the device-tree directly
 	 * here due to early probing so we need the fixup too.
 	 */
-	if (uap->port.irq == NO_IRQ &&
+	if (uap->port.irq == 0 &&
 	    np->parent && np->parent->parent &&
 	    of_device_is_compatible(np->parent->parent, "gatwick")) {
 		/* IRQs on gatwick are offset by 64 */
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index a60523f..c1a871e 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -22,7 +22,7 @@
 #include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
 
 #include "sirfsoc_uart.h"
 
@@ -673,12 +673,12 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
 	port->irq = res->start;
 
 	if (sirfport->hw_flow_ctrl) {
-		sirfport->pmx = pinmux_get(&pdev->dev, NULL);
-		ret = IS_ERR(sirfport->pmx);
+		sirfport->p = pinctrl_get(&pdev->dev, NULL);
+		ret = IS_ERR(sirfport->p);
 		if (ret)
-			goto pmx_err;
+			goto pin_err;
 
-		pinmux_enable(sirfport->pmx);
+		pinctrl_enable(sirfport->p);
 	}
 
 	port->ops = &sirfsoc_uart_ops;
@@ -696,10 +696,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
 port_err:
 	platform_set_drvdata(pdev, NULL);
 	if (sirfport->hw_flow_ctrl) {
-		pinmux_disable(sirfport->pmx);
-		pinmux_put(sirfport->pmx);
+		pinctrl_disable(sirfport->p);
+		pinctrl_put(sirfport->p);
 	}
-pmx_err:
+pin_err:
 irq_err:
 	devm_iounmap(&pdev->dev, port->membase);
 err:
@@ -712,8 +712,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
 	struct uart_port *port = &sirfport->port;
 	platform_set_drvdata(pdev, NULL);
 	if (sirfport->hw_flow_ctrl) {
-		pinmux_disable(sirfport->pmx);
-		pinmux_put(sirfport->pmx);
+		pinctrl_disable(sirfport->p);
+		pinctrl_put(sirfport->p);
 	}
 	devm_iounmap(&pdev->dev, port->membase);
 	uart_remove_one_port(&sirfsoc_uart_drv, port);
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h
index fc64260..6e207fd 100644
--- a/drivers/tty/serial/sirfsoc_uart.h
+++ b/drivers/tty/serial/sirfsoc_uart.h
@@ -162,7 +162,7 @@ struct sirfsoc_uart_port {
 	unsigned char			ms_enabled;
 
 	struct uart_port		port;
-	struct pinmux			*pmx;
+	struct pinctrl			*p;
 };
 
 /* Hardware Flow Control */
diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c
index 238c7df..4e1b551 100644
--- a/drivers/tty/serial/sn_console.c
+++ b/drivers/tty/serial/sn_console.c
@@ -461,12 +461,12 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
 	struct tty_struct *tty;
 
 	if (!port) {
-		printk(KERN_ERR "sn_receive_chars - port NULL so can't receieve\n");
+		printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n");
 		return;
 	}
 
 	if (!port->sc_ops) {
-		printk(KERN_ERR "sn_receive_chars - port->sc_ops  NULL so can't receieve\n");
+		printk(KERN_ERR "sn_receive_chars - port->sc_ops  NULL so can't receive\n");
 		return;
 	}
 
diff --git a/drivers/tty/serial/suncore.c b/drivers/tty/serial/suncore.c
index 6381a02..6e4ac8d 100644
--- a/drivers/tty/serial/suncore.c
+++ b/drivers/tty/serial/suncore.c
@@ -17,11 +17,11 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/serial_core.h>
+#include <linux/sunserialcore.h>
 #include <linux/init.h>
 
 #include <asm/prom.h>
 
-#include "suncore.h"
 
 static int sunserial_current_minor = 64;
 
diff --git a/drivers/tty/serial/suncore.h b/drivers/tty/serial/suncore.h
deleted file mode 100644
index db20579..0000000
--- a/drivers/tty/serial/suncore.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* suncore.h
- *
- * Generic SUN serial/kbd/ms layer.  Based entirely
- * upon drivers/sbus/char/sunserial.h which is:
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- *
- * Port to new UART layer is:
- *
- * Copyright (C) 2002 David S. Miller (davem@redhat.com)
- */
-
-#ifndef _SERIAL_SUN_H
-#define _SERIAL_SUN_H
-
-/* Serial keyboard defines for L1-A processing... */
-#define SUNKBD_RESET		0xff
-#define SUNKBD_L1		0x01
-#define SUNKBD_UP		0x80
-#define SUNKBD_A		0x4d
-
-extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *);
-extern int suncore_mouse_baud_detection(unsigned char, int);
-
-extern int sunserial_register_minors(struct uart_driver *, int);
-extern void sunserial_unregister_minors(struct uart_driver *, int);
-
-extern int sunserial_console_match(struct console *, struct device_node *,
-				   struct uart_driver *, int, bool);
-extern void sunserial_console_termios(struct console *,
-				      struct device_node *);
-
-#endif /* !(_SERIAL_SUN_H) */
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c
index c0b7246..3ba5d28 100644
--- a/drivers/tty/serial/sunhv.c
+++ b/drivers/tty/serial/sunhv.c
@@ -29,8 +29,7 @@
 #endif
 
 #include <linux/serial_core.h>
-
-#include "suncore.h"
+#include <linux/sunserialcore.h>
 
 #define CON_BREAK	((long)-1)
 #define CON_HUP		((long)-2)
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
index b5fa2a5..62dacd0 100644
--- a/drivers/tty/serial/sunsab.c
+++ b/drivers/tty/serial/sunsab.c
@@ -43,8 +43,8 @@
 #endif
 
 #include <linux/serial_core.h>
+#include <linux/sunserialcore.h>
 
-#include "suncore.h"
 #include "sunsab.h"
 
 struct uart_sunsab_port {
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c
index ad0f8f5..d3ca6da 100644
--- a/drivers/tty/serial/sunsu.c
+++ b/drivers/tty/serial/sunsu.c
@@ -47,8 +47,7 @@
 #endif
 
 #include <linux/serial_core.h>
-
-#include "suncore.h"
+#include <linux/sunserialcore.h>
 
 /* We are on a NS PC87303 clocked with 24.0 MHz, which results
  * in a UART clock of 1.8462 MHz.
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c
index 8e916e7..da44158 100644
--- a/drivers/tty/serial/sunzilog.c
+++ b/drivers/tty/serial/sunzilog.c
@@ -43,8 +43,8 @@
 #endif
 
 #include <linux/serial_core.h>
+#include <linux/sunserialcore.h>
 
-#include "suncore.h"
 #include "sunzilog.h"
 
 /* On 32-bit sparcs we need to delay after register accesses
@@ -1397,7 +1397,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up)
 #endif
 }
 
-static int zilog_irq = -1;
+static int zilog_irq;
 
 static int __devinit zs_probe(struct platform_device *op)
 {
@@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct platform_device *op)
 
 	rp = sunzilog_chip_regs[inst];
 
-	if (zilog_irq == -1)
+	if (!zilog_irq)
 		zilog_irq = op->archdata.irqs[0];
 
 	up = &sunzilog_port_table[inst * 2];
@@ -1580,7 +1580,7 @@ static int __init sunzilog_init(void)
 	if (err)
 		goto out_unregister_uart;
 
-	if (zilog_irq != -1) {
+	if (!zilog_irq) {
 		struct uart_sunzilog_port *up = sunzilog_irq_chain;
 		err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
 				  "zs", sunzilog_irq_chain);
@@ -1621,7 +1621,7 @@ static void __exit sunzilog_exit(void)
 {
 	platform_driver_unregister(&zs_driver);
 
-	if (zilog_irq != -1) {
+	if (!zilog_irq) {
 		struct uart_sunzilog_port *up = sunzilog_irq_chain;
 
 		/* Disable Interrupts */
@@ -1637,7 +1637,7 @@ static void __exit sunzilog_exit(void)
 		}
 
 		free_irq(zilog_irq, sunzilog_irq_chain);
-		zilog_irq = -1;
+		zilog_irq = 0;
 	}
 
 	if (sunzilog_reg.nr) {
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 2ebe606..f99b0c9 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -1360,7 +1360,7 @@ static int ucc_uart_probe(struct platform_device *ofdev)
 	}
 
 	qe_port->port.irq = irq_of_parse_and_map(np, 0);
-	if (qe_port->port.irq == NO_IRQ) {
+	if (qe_port->port.irq == 0) {
 		dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n",
 		       qe_port->ucc_num + 1);
 		ret = -EINVAL;
diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c
index 83148e7..cf0d948 100644
--- a/drivers/tty/serial/vr41xx_siu.c
+++ b/drivers/tty/serial/vr41xx_siu.c
@@ -61,7 +61,7 @@
 static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = {
 	[0 ... SIU_PORTS_MAX-1] = {
 		.lock	= __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock),
-		.irq	= -1,
+		.irq	= 0,
 	},
 };
 
@@ -171,7 +171,7 @@ static inline unsigned int siu_check_type(struct uart_port *port)
 {
 	if (port->line == 0)
 		return PORT_VR41XX_SIU;
-	if (port->line == 1 && port->irq != -1)
+	if (port->line == 1 && port->irq)
 		return PORT_VR41XX_DSIU;
 
 	return PORT_UNKNOWN;
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 18b48cd..01a1ff4 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -3924,7 +3924,7 @@ static void tdma_reset(struct slgt_info *info)
  */
 static void enable_loopback(struct slgt_info *info)
 {
-	/* SCR (serial control) BIT2=looopback enable */
+	/* SCR (serial control) BIT2=loopback enable */
 	wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2));
 
 	if (info->params.mode != MGSL_MODE_ASYNC) {
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 7867b7c..8db9125 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -322,11 +322,16 @@ static void send_sig_all(int sig)
 {
 	struct task_struct *p;
 
+	read_lock(&tasklist_lock);
 	for_each_process(p) {
-		if (p->mm && !is_global_init(p))
-			/* Not swapper, init nor kernel thread */
-			force_sig(sig, p);
+		if (p->flags & PF_KTHREAD)
+			continue;
+		if (is_global_init(p))
+			continue;
+
+		force_sig(sig, p);
 	}
+	read_unlock(&tasklist_lock);
 }
 
 static void sysrq_handle_term(int key)
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index e41b9bb..ea7ebe2 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1271,6 +1271,19 @@ int tty_init_termios(struct tty_struct *tty)
 }
 EXPORT_SYMBOL_GPL(tty_init_termios);
 
+int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+	int ret = tty_init_termios(tty);
+	if (ret)
+		return ret;
+
+	tty_driver_kref_get(driver);
+	tty->count++;
+	driver->ttys[tty->index] = tty;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tty_standard_install);
+
 /**
  *	tty_driver_install_tty() - install a tty entry in the driver
  *	@driver: the driver for the tty
@@ -1286,21 +1299,8 @@ EXPORT_SYMBOL_GPL(tty_init_termios);
 static int tty_driver_install_tty(struct tty_driver *driver,
 						struct tty_struct *tty)
 {
-	int idx = tty->index;
-	int ret;
-
-	if (driver->ops->install) {
-		ret = driver->ops->install(driver, tty);
-		return ret;
-	}
-
-	if (tty_init_termios(tty) == 0) {
-		tty_driver_kref_get(driver);
-		tty->count++;
-		driver->ttys[idx] = tty;
-		return 0;
-	}
-	return -ENOMEM;
+	return driver->ops->install ? driver->ops->install(driver, tty) :
+		tty_standard_install(driver, tty);
 }
 
 /**
@@ -1365,7 +1365,6 @@ static int tty_reopen(struct tty_struct *tty)
  *	@driver: tty driver we are opening a device on
  *	@idx: device index
  *	@ret_tty: returned tty structure
- *	@first_ok: ok to open a new device (used by ptmx)
  *
  *	Prepare a tty device. This may not be a "new" clean device but
  *	could also be an active device. The pty drivers require special
@@ -1385,18 +1384,11 @@ static int tty_reopen(struct tty_struct *tty)
  * relaxed for the (most common) case of reopening a tty.
  */
 
-struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
-								int first_ok)
+struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
 {
 	struct tty_struct *tty;
 	int retval;
 
-	/* Check if pty master is being opened multiple times */
-	if (driver->subtype == PTY_TYPE_MASTER &&
-		(driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) {
-		return ERR_PTR(-EIO);
-	}
-
 	/*
 	 * First time open is complex, especially for PTY devices.
 	 * This code guarantees that either everything succeeds and the
@@ -1797,11 +1789,11 @@ int tty_release(struct inode *inode, struct file *filp)
 	 * the slots and preserving the termios structure.
 	 */
 	release_tty(tty, idx);
+	tty_unlock();
 
 	/* Make this pty number available for reallocation */
 	if (devpts)
 		devpts_kill_index(inode, idx);
-	tty_unlock();
 	return 0;
 }
 
@@ -1950,7 +1942,7 @@ retry_open:
 		if (retval)
 			tty = ERR_PTR(retval);
 	} else
-		tty = tty_init_dev(driver, index, 0);
+		tty = tty_init_dev(driver, index);
 
 	mutex_unlock(&tty_mutex);
 	if (driver)
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 75823a1..0b0afc8 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -76,6 +76,7 @@ config USB_ARCH_HAS_EHCI
 	default y if MICROBLAZE
 	default y if SPARC_LEON
 	default y if ARCH_MMP
+	default y if MACH_LOONGSON1
 	default PCI
 
 # some non-PCI HCDs implement xHCI
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index d2b3cff..b27bbb9 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -31,6 +31,8 @@
 #define DRIVER_AUTHOR "Oliver Neukum"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management"
 
+#define HUAWEI_VENDOR_ID	0x12D1
+
 static const struct usb_device_id wdm_ids[] = {
 	{
 		.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
@@ -38,6 +40,20 @@ static const struct usb_device_id wdm_ids[] = {
 		.bInterfaceClass = USB_CLASS_COMM,
 		.bInterfaceSubClass = USB_CDC_SUBCLASS_DMM
 	},
+	{
+		/* 
+		 * Huawei E392, E398 and possibly other Qualcomm based modems
+		 * embed the Qualcomm QMI protocol inside CDC on CDC ECM like
+		 * control interfaces.  Userspace access to this is required
+		 * to configure the accompanying data interface
+		 */
+		.match_flags        = USB_DEVICE_ID_MATCH_VENDOR |
+					USB_DEVICE_ID_MATCH_INT_INFO,
+		.idVendor           = HUAWEI_VENDOR_ID,
+		.bInterfaceClass    = USB_CLASS_VENDOR_SPEC,
+		.bInterfaceSubClass = 1,
+		.bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */
+	},
 	{ }
 };
 
@@ -54,6 +70,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
 #define WDM_POLL_RUNNING	6
 #define WDM_RESPONDING		7
 #define WDM_SUSPENDING		8
+#define WDM_RESETTING		9
 
 #define WDM_MAX			16
 
@@ -82,7 +99,6 @@ struct wdm_device {
 	u16			bufsize;
 	u16			wMaxCommand;
 	u16			wMaxPacketSize;
-	u16			bMaxPacketSize0;
 	__le16			inum;
 	int			reslength;
 	int			length;
@@ -162,11 +178,9 @@ static void wdm_int_callback(struct urb *urb)
 	int rv = 0;
 	int status = urb->status;
 	struct wdm_device *desc;
-	struct usb_ctrlrequest *req;
 	struct usb_cdc_notification *dr;
 
 	desc = urb->context;
-	req = desc->irq;
 	dr = (struct usb_cdc_notification *)desc->sbuf;
 
 	if (status) {
@@ -213,24 +227,6 @@ static void wdm_int_callback(struct urb *urb)
 		goto exit;
 	}
 
-	req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
-	req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
-	req->wValue = 0;
-	req->wIndex = desc->inum;
-	req->wLength = cpu_to_le16(desc->wMaxCommand);
-
-	usb_fill_control_urb(
-		desc->response,
-		interface_to_usbdev(desc->intf),
-		/* using common endpoint 0 */
-		usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
-		(unsigned char *)req,
-		desc->inbuf,
-		desc->wMaxCommand,
-		wdm_in_callback,
-		desc
-	);
-	desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	spin_lock(&desc->iuspin);
 	clear_bit(WDM_READ, &desc->flags);
 	set_bit(WDM_RESPONDING, &desc->flags);
@@ -279,14 +275,8 @@ static void free_urbs(struct wdm_device *desc)
 
 static void cleanup(struct wdm_device *desc)
 {
-	usb_free_coherent(interface_to_usbdev(desc->intf),
-			  desc->wMaxPacketSize,
-			  desc->sbuf,
-			  desc->validity->transfer_dma);
-	usb_free_coherent(interface_to_usbdev(desc->intf),
-			  desc->bMaxPacketSize0,
-			  desc->inbuf,
-			  desc->response->transfer_dma);
+	kfree(desc->sbuf);
+	kfree(desc->inbuf);
 	kfree(desc->orq);
 	kfree(desc->irq);
 	kfree(desc->ubuf);
@@ -351,6 +341,10 @@ static ssize_t wdm_write
 	else
 		if (test_bit(WDM_IN_USE, &desc->flags))
 			r = -EAGAIN;
+
+	if (test_bit(WDM_RESETTING, &desc->flags))
+		r = -EIO;
+
 	if (r < 0) {
 		kfree(buf);
 		goto out;
@@ -430,6 +424,10 @@ retry:
 			rv = -ENODEV;
 			goto err;
 		}
+		if (test_bit(WDM_RESETTING, &desc->flags)) {
+			rv = -EIO;
+			goto err;
+		}
 		usb_mark_last_busy(interface_to_usbdev(desc->intf));
 		if (rv < 0) {
 			rv = -ERESTARTSYS;
@@ -631,7 +629,6 @@ static void wdm_rxwork(struct work_struct *work)
 static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	int rv = -EINVAL;
-	struct usb_device *udev = interface_to_usbdev(intf);
 	struct wdm_device *desc;
 	struct usb_host_interface *iface;
 	struct usb_endpoint_descriptor *ep;
@@ -692,7 +689,6 @@ next_desc:
 		goto err;
 
 	desc->wMaxPacketSize = usb_endpoint_maxp(ep);
-	desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0;
 
 	desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
 	if (!desc->orq)
@@ -717,19 +713,13 @@ next_desc:
 	if (!desc->ubuf)
 		goto err;
 
-	desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf),
-					desc->wMaxPacketSize,
-					GFP_KERNEL,
-					&desc->validity->transfer_dma);
+	desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL);
 	if (!desc->sbuf)
 		goto err;
 
-	desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf),
-					 desc->wMaxCommand,
-					 GFP_KERNEL,
-					 &desc->response->transfer_dma);
+	desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL);
 	if (!desc->inbuf)
-		goto err2;
+		goto err;
 
 	usb_fill_int_urb(
 		desc->validity,
@@ -741,30 +731,39 @@ next_desc:
 		desc,
 		ep->bInterval
 	);
-	desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE);
+	desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
+	desc->irq->wValue = 0;
+	desc->irq->wIndex = desc->inum;
+	desc->irq->wLength = cpu_to_le16(desc->wMaxCommand);
+
+	usb_fill_control_urb(
+		desc->response,
+		interface_to_usbdev(intf),
+		/* using common endpoint 0 */
+		usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0),
+		(unsigned char *)desc->irq,
+		desc->inbuf,
+		desc->wMaxCommand,
+		wdm_in_callback,
+		desc
+	);
 
 	usb_set_intfdata(intf, desc);
 	rv = usb_register_dev(intf, &wdm_class);
 	if (rv < 0)
-		goto err3;
+		goto err2;
 	else
-		dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n",
-			intf->minor - WDM_MINOR_BASE);
+		dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev));
 out:
 	return rv;
-err3:
-	usb_set_intfdata(intf, NULL);
-	usb_free_coherent(interface_to_usbdev(desc->intf),
-			  desc->bMaxPacketSize0,
-			desc->inbuf,
-			desc->response->transfer_dma);
 err2:
-	usb_free_coherent(interface_to_usbdev(desc->intf),
-			  desc->wMaxPacketSize,
-			  desc->sbuf,
-			  desc->validity->transfer_dma);
+	usb_set_intfdata(intf, NULL);
 err:
 	free_urbs(desc);
+	kfree(desc->inbuf);
+	kfree(desc->sbuf);
 	kfree(desc->ubuf);
 	kfree(desc->orq);
 	kfree(desc->irq);
@@ -869,10 +868,6 @@ static int wdm_pre_reset(struct usb_interface *intf)
 {
 	struct wdm_device *desc = usb_get_intfdata(intf);
 
-	mutex_lock(&desc->rlock);
-	mutex_lock(&desc->wlock);
-	kill_urbs(desc);
-
 	/*
 	 * we notify everybody using poll of
 	 * an exceptional situation
@@ -880,9 +875,16 @@ static int wdm_pre_reset(struct usb_interface *intf)
 	 * message from the device is lost
 	 */
 	spin_lock_irq(&desc->iuspin);
+	set_bit(WDM_RESETTING, &desc->flags);	/* inform read/write */
+	set_bit(WDM_READ, &desc->flags);	/* unblock read */
+	clear_bit(WDM_IN_USE, &desc->flags);	/* unblock write */
 	desc->rerr = -EINTR;
 	spin_unlock_irq(&desc->iuspin);
 	wake_up_all(&desc->wait);
+	mutex_lock(&desc->rlock);
+	mutex_lock(&desc->wlock);
+	kill_urbs(desc);
+	cancel_work_sync(&desc->rxwork);
 	return 0;
 }
 
@@ -891,6 +893,7 @@ static int wdm_post_reset(struct usb_interface *intf)
 	struct wdm_device *desc = usb_get_intfdata(intf);
 	int rv;
 
+	clear_bit(WDM_RESETTING, &desc->flags);
 	rv = recover_from_urb_loss(desc);
 	mutex_unlock(&desc->wlock);
 	mutex_unlock(&desc->rlock);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index d40ff95..f8e2d6d 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -71,10 +71,7 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
 	list_add_tail(&dynid->node, &dynids->list);
 	spin_unlock(&dynids->lock);
 
-	if (get_driver(driver)) {
-		retval = driver_attach(driver);
-		put_driver(driver);
-	}
+	retval = driver_attach(driver);
 
 	if (retval)
 		return retval;
@@ -132,43 +129,39 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count)
 }
 static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
 
-static int usb_create_newid_file(struct usb_driver *usb_drv)
+static int usb_create_newid_files(struct usb_driver *usb_drv)
 {
 	int error = 0;
 
 	if (usb_drv->no_dynamic_id)
 		goto exit;
 
-	if (usb_drv->probe != NULL)
+	if (usb_drv->probe != NULL) {
 		error = driver_create_file(&usb_drv->drvwrap.driver,
 					   &driver_attr_new_id);
+		if (error == 0) {
+			error = driver_create_file(&usb_drv->drvwrap.driver,
+					&driver_attr_remove_id);
+			if (error)
+				driver_remove_file(&usb_drv->drvwrap.driver,
+						&driver_attr_new_id);
+		}
+	}
 exit:
 	return error;
 }
 
-static void usb_remove_newid_file(struct usb_driver *usb_drv)
+static void usb_remove_newid_files(struct usb_driver *usb_drv)
 {
 	if (usb_drv->no_dynamic_id)
 		return;
 
-	if (usb_drv->probe != NULL)
+	if (usb_drv->probe != NULL) {
 		driver_remove_file(&usb_drv->drvwrap.driver,
-				   &driver_attr_new_id);
-}
-
-static int
-usb_create_removeid_file(struct usb_driver *drv)
-{
-	int error = 0;
-	if (drv->probe != NULL)
-		error = driver_create_file(&drv->drvwrap.driver,
 				&driver_attr_remove_id);
-	return error;
-}
-
-static void usb_remove_removeid_file(struct usb_driver *drv)
-{
-	driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id);
+		driver_remove_file(&usb_drv->drvwrap.driver,
+				   &driver_attr_new_id);
+	}
 }
 
 static void usb_free_dynids(struct usb_driver *usb_drv)
@@ -183,22 +176,12 @@ static void usb_free_dynids(struct usb_driver *usb_drv)
 	spin_unlock(&usb_drv->dynids.lock);
 }
 #else
-static inline int usb_create_newid_file(struct usb_driver *usb_drv)
-{
-	return 0;
-}
-
-static void usb_remove_newid_file(struct usb_driver *usb_drv)
-{
-}
-
-static int
-usb_create_removeid_file(struct usb_driver *drv)
+static inline int usb_create_newid_files(struct usb_driver *usb_drv)
 {
 	return 0;
 }
 
-static void usb_remove_removeid_file(struct usb_driver *drv)
+static void usb_remove_newid_files(struct usb_driver *usb_drv)
 {
 }
 
@@ -875,22 +858,16 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
 
 	usbfs_update_special();
 
-	retval = usb_create_newid_file(new_driver);
+	retval = usb_create_newid_files(new_driver);
 	if (retval)
 		goto out_newid;
 
-	retval = usb_create_removeid_file(new_driver);
-	if (retval)
-		goto out_removeid;
-
 	pr_info("%s: registered new interface driver %s\n",
 			usbcore_name, new_driver->name);
 
 out:
 	return retval;
 
-out_removeid:
-	usb_remove_newid_file(new_driver);
 out_newid:
 	driver_unregister(&new_driver->drvwrap.driver);
 
@@ -917,10 +894,9 @@ void usb_deregister(struct usb_driver *driver)
 	pr_info("%s: deregistering interface driver %s\n",
 			usbcore_name, driver->name);
 
-	usb_remove_removeid_file(driver);
-	usb_remove_newid_file(driver);
-	usb_free_dynids(driver);
+	usb_remove_newid_files(driver);
 	driver_unregister(&driver->drvwrap.driver);
+	usb_free_dynids(driver);
 
 	usbfs_update_special();
 }
@@ -958,13 +934,8 @@ void usb_rebind_intf(struct usb_interface *intf)
 	int rc;
 
 	/* Delayed unbind of an existing driver */
-	if (intf->dev.driver) {
-		struct usb_driver *driver =
-				to_usb_driver(intf->dev.driver);
-
-		dev_dbg(&intf->dev, "forced unbind\n");
-		usb_driver_release_interface(driver, intf);
-	}
+	if (intf->dev.driver)
+		usb_forced_unbind_intf(intf);
 
 	/* Try to rebind the interface */
 	if (!intf->dev.power.is_prepared) {
@@ -977,15 +948,13 @@ void usb_rebind_intf(struct usb_interface *intf)
 
 #ifdef CONFIG_PM
 
-#define DO_UNBIND	0
-#define DO_REBIND	1
-
-/* Unbind drivers for @udev's interfaces that don't support suspend/resume,
- * or rebind interfaces that have been unbound, according to @action.
+/* Unbind drivers for @udev's interfaces that don't support suspend/resume
+ * There is no check for reset_resume here because it can be determined
+ * only during resume whether reset_resume is needed.
  *
  * The caller must hold @udev's device lock.
  */
-static void do_unbind_rebind(struct usb_device *udev, int action)
+static void unbind_no_pm_drivers_interfaces(struct usb_device *udev)
 {
 	struct usb_host_config	*config;
 	int			i;
@@ -996,23 +965,53 @@ static void do_unbind_rebind(struct usb_device *udev, int action)
 	if (config) {
 		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
 			intf = config->interface[i];
-			switch (action) {
-			case DO_UNBIND:
-				if (intf->dev.driver) {
-					drv = to_usb_driver(intf->dev.driver);
-					if (!drv->suspend || !drv->resume)
-						usb_forced_unbind_intf(intf);
-				}
-				break;
-			case DO_REBIND:
-				if (intf->needs_binding)
-					usb_rebind_intf(intf);
-				break;
+
+			if (intf->dev.driver) {
+				drv = to_usb_driver(intf->dev.driver);
+				if (!drv->suspend || !drv->resume)
+					usb_forced_unbind_intf(intf);
 			}
 		}
 	}
 }
 
+/* Unbind drivers for @udev's interfaces that failed to support reset-resume.
+ * These interfaces have the needs_binding flag set by usb_resume_interface().
+ *
+ * The caller must hold @udev's device lock.
+ */
+static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev)
+{
+	struct usb_host_config	*config;
+	int			i;
+	struct usb_interface	*intf;
+
+	config = udev->actconfig;
+	if (config) {
+		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+			intf = config->interface[i];
+			if (intf->dev.driver && intf->needs_binding)
+				usb_forced_unbind_intf(intf);
+		}
+	}
+}
+
+static void do_rebind_interfaces(struct usb_device *udev)
+{
+	struct usb_host_config	*config;
+	int			i;
+	struct usb_interface	*intf;
+
+	config = udev->actconfig;
+	if (config) {
+		for (i = 0; i < config->desc.bNumInterfaces; ++i) {
+			intf = config->interface[i];
+			if (intf->needs_binding)
+				usb_rebind_intf(intf);
+		}
+	}
+}
+
 static int usb_suspend_device(struct usb_device *udev, pm_message_t msg)
 {
 	struct usb_device_driver	*udriver;
@@ -1302,35 +1301,48 @@ int usb_suspend(struct device *dev, pm_message_t msg)
 {
 	struct usb_device	*udev = to_usb_device(dev);
 
-	do_unbind_rebind(udev, DO_UNBIND);
+	unbind_no_pm_drivers_interfaces(udev);
+
+	/* From now on we are sure all drivers support suspend/resume
+	 * but not necessarily reset_resume()
+	 * so we may still need to unbind and rebind upon resume
+	 */
 	choose_wakeup(udev, msg);
 	return usb_suspend_both(udev, msg);
 }
 
 /* The device lock is held by the PM core */
+int usb_resume_complete(struct device *dev)
+{
+	struct usb_device *udev = to_usb_device(dev);
+
+	/* For PM complete calls, all we do is rebind interfaces
+	 * whose needs_binding flag is set
+	 */
+	if (udev->state != USB_STATE_NOTATTACHED)
+		do_rebind_interfaces(udev);
+	return 0;
+}
+
+/* The device lock is held by the PM core */
 int usb_resume(struct device *dev, pm_message_t msg)
 {
 	struct usb_device	*udev = to_usb_device(dev);
 	int			status;
 
-	/* For PM complete calls, all we do is rebind interfaces */
-	if (msg.event == PM_EVENT_ON) {
-		if (udev->state != USB_STATE_NOTATTACHED)
-			do_unbind_rebind(udev, DO_REBIND);
-		status = 0;
-
-	/* For all other calls, take the device back to full power and
+	/* For all calls, take the device back to full power and
 	 * tell the PM core in case it was autosuspended previously.
-	 * Unbind the interfaces that will need rebinding later.
+	 * Unbind the interfaces that will need rebinding later,
+	 * because they fail to support reset_resume.
+	 * (This can't be done in usb_resume_interface()
+	 * above because it doesn't own the right set of locks.)
 	 */
-	} else {
-		status = usb_resume_both(udev, msg);
-		if (status == 0) {
-			pm_runtime_disable(dev);
-			pm_runtime_set_active(dev);
-			pm_runtime_enable(dev);
-			do_unbind_rebind(udev, DO_REBIND);
-		}
+	status = usb_resume_both(udev, msg);
+	if (status == 0) {
+		pm_runtime_disable(dev);
+		pm_runtime_set_active(dev);
+		pm_runtime_enable(dev);
+		unbind_no_reset_resume_drivers_interfaces(udev);
 	}
 
 	/* Avoid PM error messages for devices disconnected while suspended
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index d136b8f..81e2c0d 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -187,7 +187,10 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 		return -ENODEV;
 	dev->current_state = PCI_D0;
 
-	if (!dev->irq) {
+	/* The xHCI driver supports MSI and MSI-X,
+	 * so don't fail if the BIOS doesn't provide a legacy IRQ.
+	 */
+	if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
 		dev_err(&dev->dev,
 			"Found HC with no IRQ.  Check BIOS/PCI %s setup!\n",
 			pci_name(dev));
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index eb19cba..e128232 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2447,8 +2447,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
 			&& device_can_wakeup(&hcd->self.root_hub->dev))
 		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
 
-	/* enable irqs just before we start the controller */
-	if (usb_hcd_is_primary_hcd(hcd)) {
+	/* enable irqs just before we start the controller,
+	 * if the BIOS provides legacy PCI irqs.
+	 */
+	if (usb_hcd_is_primary_hcd(hcd) && irqnum) {
 		retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
 		if (retval)
 			goto err_request_irq;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a0613d8..d4f0624 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -62,6 +62,8 @@ struct usb_hub {
 							resumed */
 	unsigned long		removed_bits[1]; /* ports with a "removed"
 							device present */
+	unsigned long		wakeup_bits[1];	/* ports that have signaled
+							remote wakeup */
 #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */
 #error event_bits[] is too short!
 #endif
@@ -411,6 +413,29 @@ void usb_kick_khubd(struct usb_device *hdev)
 		kick_khubd(hub);
 }
 
+/*
+ * Let the USB core know that a USB 3.0 device has sent a Function Wake Device
+ * Notification, which indicates it had initiated remote wakeup.
+ *
+ * USB 3.0 hubs do not report the port link state change from U3 to U0 when the
+ * device initiates resume, so the USB core will not receive notice of the
+ * resume through the normal hub interrupt URB.
+ */
+void usb_wakeup_notification(struct usb_device *hdev,
+		unsigned int portnum)
+{
+	struct usb_hub *hub;
+
+	if (!hdev)
+		return;
+
+	hub = hdev_to_hub(hdev);
+	if (hub) {
+		set_bit(portnum, hub->wakeup_bits);
+		kick_khubd(hub);
+	}
+}
+EXPORT_SYMBOL_GPL(usb_wakeup_notification);
 
 /* completion function, fires on port status changes and various faults */
 static void hub_irq(struct urb *urb)
@@ -807,12 +832,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 			clear_port_feature(hub->hdev, port1,
 					USB_PORT_FEAT_C_ENABLE);
 		}
-		if (portchange & USB_PORT_STAT_C_LINK_STATE) {
-			need_debounce_delay = true;
-			clear_port_feature(hub->hdev, port1,
-					USB_PORT_FEAT_C_PORT_LINK_STATE);
-		}
-
 		if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
 				hub_is_superspeed(hub->hdev)) {
 			need_debounce_delay = true;
@@ -834,12 +853,19 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 				set_bit(port1, hub->change_bits);
 
 		} else if (portstatus & USB_PORT_STAT_ENABLE) {
+			bool port_resumed = (portstatus &
+					USB_PORT_STAT_LINK_STATE) ==
+				USB_SS_PORT_LS_U0;
 			/* The power session apparently survived the resume.
 			 * If there was an overcurrent or suspend change
 			 * (i.e., remote wakeup request), have khubd
-			 * take care of it.
+			 * take care of it.  Look at the port link state
+			 * for USB 3.0 hubs, since they don't have a suspend
+			 * change bit, and they don't set the port link change
+			 * bit on device-initiated resume.
 			 */
-			if (portchange)
+			if (portchange || (hub_is_superspeed(hub->hdev) &&
+						port_resumed))
 				set_bit(port1, hub->change_bits);
 
 		} else if (udev->persist_enabled) {
@@ -1289,14 +1315,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	desc = intf->cur_altsetting;
 	hdev = interface_to_usbdev(intf);
 
-	/* Hubs have proper suspend/resume support.  USB 3.0 device suspend is
-	 * different from USB 2.0/1.1 device suspend, and unfortunately we
-	 * don't support it yet.  So leave autosuspend disabled for USB 3.0
-	 * external hubs for now.  Enable autosuspend for USB 3.0 roothubs,
-	 * since that isn't a "real" hub.
-	 */
-	if (!hub_is_superspeed(hdev) || !hdev->parent)
-		usb_enable_autosuspend(hdev);
+	/* Hubs have proper suspend/resume support. */
+	usb_enable_autosuspend(hdev);
 
 	if (hdev->level == MAX_TOPO_LEVEL) {
 		dev_err(&intf->dev,
@@ -1838,6 +1858,37 @@ fail:
 	return err;
 }
 
+static void set_usb_port_removable(struct usb_device *udev)
+{
+	struct usb_device *hdev = udev->parent;
+	struct usb_hub *hub;
+	u8 port = udev->portnum;
+	u16 wHubCharacteristics;
+	bool removable = true;
+
+	if (!hdev)
+		return;
+
+	hub = hdev_to_hub(udev->parent);
+
+	wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
+
+	if (!(wHubCharacteristics & HUB_CHAR_COMPOUND))
+		return;
+
+	if (hub_is_superspeed(hdev)) {
+		if (hub->descriptor->u.ss.DeviceRemovable & (1 << port))
+			removable = false;
+	} else {
+		if (hub->descriptor->u.hs.DeviceRemovable[port / 8] & (1 << (port % 8)))
+			removable = false;
+	}
+
+	if (removable)
+		udev->removable = USB_DEVICE_REMOVABLE;
+	else
+		udev->removable = USB_DEVICE_FIXED;
+}
 
 /**
  * usb_new_device - perform initial device setup (usbcore-internal)
@@ -1896,6 +1947,15 @@ int usb_new_device(struct usb_device *udev)
 	announce_device(udev);
 
 	device_enable_async_suspend(&udev->dev);
+
+	/*
+	 * check whether the hub marks this port as non-removable. Do it
+	 * now so that platform-specific data can override it in
+	 * device_add()
+	 */
+	if (udev->parent)
+		set_usb_port_removable(udev);
+
 	/* Register the device.  The device driver is responsible
 	 * for configuring the device and invoking the add-device
 	 * notifier chain (used by usbfs and possibly others).
@@ -2381,11 +2441,27 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
 	 * we don't explicitly enable it here.
 	 */
 	if (udev->do_remote_wakeup) {
-		status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
-				USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
-				USB_DEVICE_REMOTE_WAKEUP, 0,
-				NULL, 0,
-				USB_CTRL_SET_TIMEOUT);
+		if (!hub_is_superspeed(hub->hdev)) {
+			status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+					USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
+					USB_DEVICE_REMOTE_WAKEUP, 0,
+					NULL, 0,
+					USB_CTRL_SET_TIMEOUT);
+		} else {
+			/* Assume there's only one function on the USB 3.0
+			 * device and enable remote wake for the first
+			 * interface. FIXME if the interface association
+			 * descriptor shows there's more than one function.
+			 */
+			status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+					USB_REQ_SET_FEATURE,
+					USB_RECIP_INTERFACE,
+					USB_INTRF_FUNC_SUSPEND,
+					USB_INTRF_FUNC_SUSPEND_RW |
+					USB_INTRF_FUNC_SUSPEND_LP,
+					NULL, 0,
+					USB_CTRL_SET_TIMEOUT);
+		}
 		if (status) {
 			dev_dbg(&udev->dev, "won't remote wakeup, status %d\n",
 					status);
@@ -2675,6 +2751,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 	struct usb_hub		*hub = usb_get_intfdata (intf);
 	struct usb_device	*hdev = hub->hdev;
 	unsigned		port1;
+	int			status;
 
 	/* Warn if children aren't already suspended */
 	for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -2687,6 +2764,17 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
 				return -EBUSY;
 		}
 	}
+	if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) {
+		/* Enable hub to send remote wakeup for all ports. */
+		for (port1 = 1; port1 <= hdev->maxchild; port1++) {
+			status = set_port_feature(hdev,
+					port1 |
+					USB_PORT_FEAT_REMOTE_WAKE_CONNECT |
+					USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT |
+					USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT,
+					USB_PORT_FEAT_REMOTE_WAKE_MASK);
+		}
+	}
 
 	dev_dbg(&intf->dev, "%s\n", __func__);
 
@@ -3420,6 +3508,46 @@ done:
 		hcd->driver->relinquish_port(hcd, port1);
 }
 
+/* Returns 1 if there was a remote wakeup and a connect status change. */
+static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
+		u16 portstatus, u16 portchange)
+{
+	struct usb_device *hdev;
+	struct usb_device *udev;
+	int connect_change = 0;
+	int ret;
+
+	hdev = hub->hdev;
+	udev = hdev->children[port-1];
+	if (!hub_is_superspeed(hdev)) {
+		if (!(portchange & USB_PORT_STAT_C_SUSPEND))
+			return 0;
+		clear_port_feature(hdev, port, USB_PORT_FEAT_C_SUSPEND);
+	} else {
+		if (!udev || udev->state != USB_STATE_SUSPENDED ||
+				 (portstatus & USB_PORT_STAT_LINK_STATE) !=
+				 USB_SS_PORT_LS_U0)
+			return 0;
+	}
+
+	if (udev) {
+		/* TRSMRCY = 10 msec */
+		msleep(10);
+
+		usb_lock_device(udev);
+		ret = usb_remote_wakeup(udev);
+		usb_unlock_device(udev);
+		if (ret < 0)
+			connect_change = 1;
+	} else {
+		ret = -ENODEV;
+		hub_port_disable(hub, port, 1);
+	}
+	dev_dbg(hub->intfdev, "resume on port %d, status %d\n",
+			port, ret);
+	return connect_change;
+}
+
 static void hub_events(void)
 {
 	struct list_head *tmp;
@@ -3432,7 +3560,7 @@ static void hub_events(void)
 	u16 portstatus;
 	u16 portchange;
 	int i, ret;
-	int connect_change;
+	int connect_change, wakeup_change;
 
 	/*
 	 *  We restart the list every time to avoid a deadlock with
@@ -3511,8 +3639,9 @@ static void hub_events(void)
 			if (test_bit(i, hub->busy_bits))
 				continue;
 			connect_change = test_bit(i, hub->change_bits);
+			wakeup_change = test_and_clear_bit(i, hub->wakeup_bits);
 			if (!test_and_clear_bit(i, hub->event_bits) &&
-					!connect_change)
+					!connect_change && !wakeup_change)
 				continue;
 
 			ret = hub_port_status(hub, i,
@@ -3553,31 +3682,10 @@ static void hub_events(void)
 				}
 			}
 
-			if (portchange & USB_PORT_STAT_C_SUSPEND) {
-				struct usb_device *udev;
+			if (hub_handle_remote_wakeup(hub, i,
+						portstatus, portchange))
+				connect_change = 1;
 
-				clear_port_feature(hdev, i,
-					USB_PORT_FEAT_C_SUSPEND);
-				udev = hdev->children[i-1];
-				if (udev) {
-					/* TRSMRCY = 10 msec */
-					msleep(10);
-
-					usb_lock_device(udev);
-					ret = usb_remote_wakeup(hdev->
-							children[i-1]);
-					usb_unlock_device(udev);
-					if (ret < 0)
-						connect_change = 1;
-				} else {
-					ret = -ENODEV;
-					hub_port_disable(hub, i, 1);
-				}
-				dev_dbg (hub_dev,
-					"resume on port %d, status %d\n",
-					i, ret);
-			}
-			
 			if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
 				u16 status = 0;
 				u16 unused;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 9e186f3..06c175a 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -454,7 +454,6 @@ static const struct super_operations usbfs_ops = {
 static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
-	struct dentry *root;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -462,19 +461,11 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_op = &usbfs_ops;
 	sb->s_time_gran = 1;
 	inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		dbg("%s: could not get inode!",__func__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root) {
 		dbg("%s: could not get root dentry!",__func__);
-		iput(inode);
 		return -ENOMEM;
 	}
-	sb->s_root = root;
 	return 0;
 }
 
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 9e491ca..566d9f9 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -230,6 +230,28 @@ show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL);
 
+static ssize_t
+show_removable(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_device *udev;
+	char *state;
+
+	udev = to_usb_device(dev);
+
+	switch (udev->removable) {
+	case USB_DEVICE_REMOVABLE:
+		state = "removable";
+		break;
+	case USB_DEVICE_FIXED:
+		state = "fixed";
+		break;
+	default:
+		state = "unknown";
+	}
+
+	return sprintf(buf, "%s\n", state);
+}
+static DEVICE_ATTR(removable, S_IRUGO, show_removable, NULL);
 
 #ifdef	CONFIG_PM
 
@@ -626,6 +648,7 @@ static struct attribute *dev_attrs[] = {
 	&dev_attr_avoid_reset_quirk.attr,
 	&dev_attr_authorized.attr,
 	&dev_attr_remove.attr,
+	&dev_attr_removable.attr,
 	NULL,
 };
 static struct attribute_group dev_attr_grp = {
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 909625b..f4f20c7 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -403,20 +403,17 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 	 * cause problems in HCDs if they get it wrong.
 	 */
 	{
-	unsigned int	orig_flags = urb->transfer_flags;
 	unsigned int	allowed;
 	static int pipetypes[4] = {
 		PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
 	};
 
 	/* Check that the pipe's type matches the endpoint's type */
-	if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) {
-		dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
+	if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
+		dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
 			usb_pipetype(urb->pipe), pipetypes[xfertype]);
-		return -EPIPE;		/* The most suitable error code :-) */
-	}
 
-	/* enforce simple/standard policy */
+	/* Check against a simple/standard policy */
 	allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK |
 			URB_FREE_BUFFER);
 	switch (xfertype) {
@@ -435,14 +432,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 		allowed |= URB_ISO_ASAP;
 		break;
 	}
-	urb->transfer_flags &= allowed;
+	allowed &= urb->transfer_flags;
 
-	/* fail if submitter gave bogus flags */
-	if (urb->transfer_flags != orig_flags) {
-		dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n",
-			orig_flags, urb->transfer_flags);
-		return -EINVAL;
-	}
+	/* warn if submitter gave bogus flags */
+	if (allowed != urb->transfer_flags)
+		dev_WARN(&dev->dev, "BOGUS urb flags, %x --> %x\n",
+			urb->transfer_flags, allowed);
 	}
 #endif
 	/*
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 8ca9f99..c74ba7b 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -274,7 +274,7 @@ static int usb_dev_prepare(struct device *dev)
 static void usb_dev_complete(struct device *dev)
 {
 	/* Currently used only for rebinding interfaces */
-	usb_resume(dev, PMSG_ON);	/* FIXME: change to PMSG_COMPLETE */
+	usb_resume_complete(dev);
 }
 
 static int usb_dev_suspend(struct device *dev)
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 45e8479..71648dc 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -56,6 +56,7 @@ extern void usb_major_cleanup(void);
 
 extern int usb_suspend(struct device *dev, pm_message_t msg);
 extern int usb_resume(struct device *dev, pm_message_t msg);
+extern int usb_resume_complete(struct device *dev);
 
 extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg);
 extern int usb_port_resume(struct usb_device *dev, pm_message_t msg);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 64e1f7c..c68e427 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -171,14 +171,4 @@ MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer");
 
-static int __devinit dwc3_pci_init(void)
-{
-	return pci_register_driver(&dwc3_pci_driver);
-}
-module_init(dwc3_pci_init);
-
-static void __exit dwc3_pci_exit(void)
-{
-	pci_unregister_driver(&dwc3_pci_driver);
-}
-module_exit(dwc3_pci_exit);
+module_pci_driver(dwc3_pci_driver);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7ecb68a..85ae4b4 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -137,7 +137,7 @@ choice
 
 config USB_AT91
 	tristate "Atmel AT91 USB Device Port"
-	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45
+	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91SAM9G45
 	help
 	   Many Atmel AT91 processors (such as the AT91RM2000) have a
 	   full speed USB Device Port with support for five configurable
@@ -150,7 +150,7 @@ config USB_AT91
 config USB_ATMEL_USBA
 	tristate "Atmel USBA"
 	select USB_GADGET_DUALSPEED
-	depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+	depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
 	help
 	  USBA is the integrated high-speed USB Device controller on
 	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index f63dc6c..d825b24 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1063,13 +1063,9 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent)
 				  &simple_dir_operations,
 				  &simple_dir_inode_operations,
 				  &data->perms);
-	if (unlikely(!inode))
+	sb->s_root = d_make_root(inode);
+	if (unlikely(!sb->s_root))
 		goto Enomem;
-	sb->s_root = d_alloc_root(inode);
-	if (unlikely(!sb->s_root)) {
-		iput(inode);
-		goto Enomem;
-	}
 
 	/* EP0 file */
 	if (unlikely(!ffs_sb_create_file(sb, "ep0", ffs,
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index ae04266..c95eea4 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -2059,10 +2059,8 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
 	if (!inode)
 		goto Enomem;
 	inode->i_op = &simple_dir_inode_operations;
-	if (!(sb->s_root = d_alloc_root (inode))) {
-		iput(inode);
+	if (!(sb->s_root = d_make_root (inode)))
 		goto Enomem;
-	}
 
 	/* the ep0 file is named after the controller we expect;
 	 * user mode code can use it for sanity checks, like we do.
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index d6d74d2..fd9109d 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -107,7 +107,7 @@ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
 			HCC_PER_PORT_CHANGE_EVENT(params) ? " ppce" : "",
 			HCC_HW_PREFETCH(params) ? " hw prefetch" : "",
 			HCC_32FRAME_PERIODIC_LIST(params) ?
-				" 32 peridic list" : "");
+				" 32 periodic list" : "");
 	}
 }
 #else
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index c26a82e..10e008a 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -323,7 +323,9 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	int retval;
 	struct fsl_usb2_platform_data *pdata;
+	struct device *dev;
 
+	dev = hcd->self.controller;
 	pdata = hcd->self.controller->platform_data;
 	ehci->big_endian_desc = pdata->big_endian_desc;
 	ehci->big_endian_mmio = pdata->big_endian_mmio;
@@ -353,6 +355,16 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
 
 	ehci_reset(ehci);
 
+	if (of_device_is_compatible(dev->parent->of_node,
+				    "fsl,mpc5121-usb2-dr")) {
+		/*
+		 * set SBUSCFG:AHBBRST so that control msgs don't
+		 * fail when doing heavy PATA writes.
+		 */
+		ehci_writel(ehci, SBUSCFG_INCR8,
+			    hcd->regs + FSL_SOC_USB_SBUSCFG);
+	}
+
 	retval = ehci_fsl_reinit(ehci);
 	return retval;
 }
@@ -476,6 +488,8 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev)
 	ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE,
 		    hcd->regs + FSL_SOC_USB_ISIPHYCTRL);
 
+	ehci_writel(ehci, SBUSCFG_INCR8, hcd->regs + FSL_SOC_USB_SBUSCFG);
+
 	/* restore EHCI registers */
 	ehci_writel(ehci, pdata->pm_command, &ehci->regs->command);
 	ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable);
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index bdf43e2..6d5a94e 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -19,6 +19,8 @@
 #define _EHCI_FSL_H
 
 /* offsets for the non-ehci registers in the FSL SOC USB controller */
+#define FSL_SOC_USB_SBUSCFG	0x90
+#define SBUSCFG_INCR8		0x02	/* INCR8, specified */
 #define FSL_SOC_USB_ULPIVP	0x170
 #define FSL_SOC_USB_PORTSC1	0x184
 #define PORT_PTS_MSK		(3<<30)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index a007a9f..4918b0c 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1376,6 +1376,11 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_mv_driver
 #endif
 
+#ifdef CONFIG_MACH_LOONGSON1
+#include "ehci-ls1x.c"
+#define PLATFORM_DRIVER		ehci_ls1x_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 77bbb23..01011dd 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -107,7 +107,7 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci)
 	ehci->owned_ports = 0;
 }
 
-static int ehci_port_change(struct ehci_hcd *ehci)
+static int __maybe_unused ehci_port_change(struct ehci_hcd *ehci)
 {
 	int i = HCS_N_PORTS(ehci->hcs_params);
 
@@ -1076,7 +1076,8 @@ error_exit:
 	return retval;
 }
 
-static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
+static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd,
+		int portnum)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
 
@@ -1085,7 +1086,8 @@ static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
 	set_owner(ehci, --portnum, PORT_OWNER);
 }
 
-static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum)
+static int __maybe_unused ehci_port_handed_over(struct usb_hcd *hcd,
+		int portnum)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
 	u32 __iomem		*reg;
diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c
new file mode 100644
index 0000000..a283e59
--- /dev/null
+++ b/drivers/usb/host/ehci-ls1x.c
@@ -0,0 +1,159 @@
+/*
+ *  Bus Glue for Loongson LS1X built-in EHCI controller.
+ *
+ *  Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+
+#include <linux/platform_device.h>
+
+static int ehci_ls1x_reset(struct usb_hcd *hcd)
+{
+	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+	int ret;
+
+	ehci->caps = hcd->regs;
+
+	ret = ehci_setup(hcd);
+	if (ret)
+		return ret;
+
+	ehci_port_power(ehci, 0);
+
+	return 0;
+}
+
+static const struct hc_driver ehci_ls1x_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "LOONGSON1 EHCI",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset			= ehci_ls1x_reset,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+	.endpoint_reset		= ehci_endpoint_reset,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number	= ehci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd;
+	struct resource *res;
+	int irq;
+	int ret;
+
+	pr_debug("initializing loongson1 ehci USB Controller\n");
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res) {
+		dev_err(&pdev->dev,
+			"Found HC with no IRQ. Check %s setup!\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+	irq = res->start;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev,
+			"Found HC with no register addr. Check %s setup!\n",
+			dev_name(&pdev->dev));
+		return -ENODEV;
+	}
+
+	hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev,
+				dev_name(&pdev->dev));
+	if (!hcd)
+		return -ENOMEM;
+	hcd->rsrc_start	= res->start;
+	hcd->rsrc_len	= resource_size(res);
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_dbg(&pdev->dev, "controller already in use\n");
+		ret = -EBUSY;
+		goto err_put_hcd;
+	}
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (hcd->regs == NULL) {
+		dev_dbg(&pdev->dev, "error mapping memory\n");
+		ret = -EFAULT;
+		goto err_release_region;
+	}
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret)
+		goto err_iounmap;
+
+	return ret;
+
+err_iounmap:
+	iounmap(hcd->regs);
+err_release_region:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+	usb_put_hcd(hcd);
+	return ret;
+}
+
+static int ehci_hcd_ls1x_remove(struct platform_device *pdev)
+{
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	return 0;
+}
+
+static struct platform_driver ehci_ls1x_driver = {
+	.probe = ehci_hcd_ls1x_probe,
+	.remove = ehci_hcd_ls1x_remove,
+	.shutdown = usb_hcd_platform_shutdown,
+	.driver = {
+		.name = "ls1x-ehci",
+		.owner	= THIS_MODULE,
+	},
+};
+
+MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci");
diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c
index 6d75334..ec98ece 100644
--- a/drivers/usb/host/imx21-dbg.c
+++ b/drivers/usb/host/imx21-dbg.c
@@ -239,7 +239,7 @@ static int debug_status_show(struct seq_file *s, void *v)
 		"ETDs allocated: %d/%d (max=%d)\n"
 		"ETDs in use sw: %d\n"
 		"ETDs in use hw: %d\n"
-		"DMEM alocated: %d/%d (max=%d)\n"
+		"DMEM allocated: %d/%d (max=%d)\n"
 		"DMEM blocks: %d\n"
 		"Queued waiting for ETD: %d\n"
 		"Queued waiting for DMEM: %d\n",
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index 4bde4f9..e1004fb 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -16,29 +16,115 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <mach/assabet.h>
-#include <mach/badge4.h>
 #include <asm/hardware/sa1111.h>
 
 #ifndef CONFIG_SA1111
 #error "This file is SA-1111 bus glue.  CONFIG_SA1111 must be defined."
 #endif
 
-extern int usb_disabled(void);
+#define USB_STATUS	0x0118
+#define USB_RESET	0x011c
+#define USB_IRQTEST	0x0120
+
+#define USB_RESET_FORCEIFRESET	(1 << 0)
+#define USB_RESET_FORCEHCRESET	(1 << 1)
+#define USB_RESET_CLKGENRESET	(1 << 2)
+#define USB_RESET_SIMSCALEDOWN	(1 << 3)
+#define USB_RESET_USBINTTEST	(1 << 4)
+#define USB_RESET_SLEEPSTBYEN	(1 << 5)
+#define USB_RESET_PWRSENSELOW	(1 << 6)
+#define USB_RESET_PWRCTRLLOW	(1 << 7)
+
+#define USB_STATUS_IRQHCIRMTWKUP  (1 <<  7)
+#define USB_STATUS_IRQHCIBUFFACC  (1 <<  8)
+#define USB_STATUS_NIRQHCIM       (1 <<  9)
+#define USB_STATUS_NHCIMFCLR      (1 << 10)
+#define USB_STATUS_USBPWRSENSE    (1 << 11)
 
-/*-------------------------------------------------------------------------*/
+#if 0
+static void dump_hci_status(struct usb_hcd *hcd, const char *label)
+{
+	unsigned long status = sa1111_readl(hcd->regs + USB_STATUS);
+
+	dbg("%s USB_STATUS = { %s%s%s%s%s}", label,
+	     ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
+	     ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
+	     ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
+	     ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "),
+	     ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : ""));
+}
+#endif
 
-static void sa1111_start_hc(struct sa1111_dev *dev)
+static int ohci_sa1111_reset(struct usb_hcd *hcd)
 {
-	unsigned int usb_rst = 0;
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+	ohci_hcd_init(ohci);
+	return ohci_init(ohci);
+}
 
-	printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n",
-	       __FILE__);
+static int __devinit ohci_sa1111_start(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	int ret;
 
-#ifdef CONFIG_SA1100_BADGE4
-	if (machine_is_badge4()) {
-		badge4_set_5V(BADGE4_5V_USB, 1);
+	ret = ohci_run(ohci);
+	if (ret < 0) {
+		ohci_err(ohci, "can't start\n");
+		ohci_stop(hcd);
 	}
+	return ret;
+}
+
+static const struct hc_driver ohci_sa1111_hc_driver = {
+	.description =		hcd_name,
+	.product_desc =		"SA-1111 OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq =			ohci_irq,
+	.flags =		HCD_USB11 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.reset =		ohci_sa1111_reset,
+	.start =		ohci_sa1111_start,
+	.stop =			ohci_stop,
+	.shutdown =		ohci_shutdown,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue =		ohci_urb_enqueue,
+	.urb_dequeue =		ohci_urb_dequeue,
+	.endpoint_disable =	ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number =	ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data =	ohci_hub_status_data,
+	.hub_control =		ohci_hub_control,
+#ifdef	CONFIG_PM
+	.bus_suspend =		ohci_bus_suspend,
+	.bus_resume =		ohci_bus_resume,
 #endif
+	.start_port_reset =	ohci_start_port_reset,
+};
+
+static int sa1111_start_hc(struct sa1111_dev *dev)
+{
+	unsigned int usb_rst = 0;
+	int ret;
+
+	dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n");
 
 	if (machine_is_xp860() ||
 	    machine_has_neponset() ||
@@ -51,220 +137,121 @@ static void sa1111_start_hc(struct sa1111_dev *dev)
 	 * host controller in reset.
 	 */
 	sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET,
-		      dev->mapbase + SA1111_USB_RESET);
+		      dev->mapbase + USB_RESET);
 
 	/*
 	 * Now, carefully enable the USB clock, and take
 	 * the USB host controller out of reset.
 	 */
-	sa1111_enable_device(dev);
-	udelay(11);
-	sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET);
+	ret = sa1111_enable_device(dev);
+	if (ret == 0) {
+		udelay(11);
+		sa1111_writel(usb_rst, dev->mapbase + USB_RESET);
+	}
+
+	return ret;
 }
 
 static void sa1111_stop_hc(struct sa1111_dev *dev)
 {
 	unsigned int usb_rst;
-	printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n",
-	       __FILE__);
+
+	dev_dbg(&dev->dev, "stopping SA-1111 OHCI USB Controller\n");
 
 	/*
 	 * Put the USB host controller into reset.
 	 */
-	usb_rst = sa1111_readl(dev->mapbase + SA1111_USB_RESET);
+	usb_rst = sa1111_readl(dev->mapbase + USB_RESET);
 	sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET,
-		      dev->mapbase + SA1111_USB_RESET);
+		      dev->mapbase + USB_RESET);
 
 	/*
 	 * Stop the USB clock.
 	 */
 	sa1111_disable_device(dev);
-
-#ifdef CONFIG_SA1100_BADGE4
-	if (machine_is_badge4()) {
-		/* Disable power to the USB bus */
-		badge4_set_5V(BADGE4_5V_USB, 0);
-	}
-#endif
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-#if 0
-static void dump_hci_status(struct usb_hcd *hcd, const char *label)
-{
-	unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS);
-
-	dbg ("%s USB_STATUS = { %s%s%s%s%s}", label,
-	     ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
-	     ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
-	     ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
-	     ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "),
-	     ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : ""));
 }
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-/* configure so an HC device and id are always provided */
-/* always called with process context; sleeping is OK */
-
 
 /**
- * usb_hcd_sa1111_probe - initialize SA-1111-based HCDs
- * Context: !in_interrupt()
+ * ohci_hcd_sa1111_probe - initialize SA-1111-based HCDs
  *
  * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- * Store this function in the HCD's struct pci_driver as probe().
+ * then invokes the start() method for the HCD associated with it.
  */
-int usb_hcd_sa1111_probe (const struct hc_driver *driver,
-			  struct sa1111_dev *dev)
+static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev)
 {
 	struct usb_hcd *hcd;
-	int retval;
+	int ret;
 
-	hcd = usb_create_hcd (driver, &dev->dev, "sa1111");
+	if (usb_disabled())
+		return -ENODEV;
+
+	hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111");
 	if (!hcd)
 		return -ENOMEM;
+
 	hcd->rsrc_start = dev->res.start;
 	hcd->rsrc_len = resource_size(&dev->res);
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		dbg("request_mem_region failed");
-		retval = -EBUSY;
+		ret = -EBUSY;
 		goto err1;
 	}
+
 	hcd->regs = dev->mapbase;
 
-	sa1111_start_hc(dev);
-	ohci_hcd_init(hcd_to_ohci(hcd));
+	ret = sa1111_start_hc(dev);
+	if (ret)
+		goto err2;
 
-	retval = usb_add_hcd(hcd, dev->irq[1], 0);
-	if (retval == 0)
-		return retval;
+	ret = usb_add_hcd(hcd, dev->irq[1], 0);
+	if (ret == 0)
+		return ret;
 
 	sa1111_stop_hc(dev);
+ err2:
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
  err1:
 	usb_put_hcd(hcd);
-	return retval;
+	return ret;
 }
 
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
 /**
- * usb_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs
+ * ohci_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs
  * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_hcd_sa1111_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
  *
+ * Reverses the effect of ohci_hcd_sa1111_probe(), first invoking
+ * the HCD's stop() method.
  */
-void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev)
+static int ohci_hcd_sa1111_remove(struct sa1111_dev *dev)
 {
+	struct usb_hcd *hcd = sa1111_get_drvdata(dev);
+
 	usb_remove_hcd(hcd);
 	sa1111_stop_hc(dev);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
-}
-
-/*-------------------------------------------------------------------------*/
 
-static int __devinit
-ohci_sa1111_start (struct usb_hcd *hcd)
-{
-	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
-
-	if ((ret = ohci_init(ohci)) < 0)
-		return ret;
-
-	if ((ret = ohci_run (ohci)) < 0) {
-		err ("can't start %s", hcd->self.bus_name);
-		ohci_stop (hcd);
-		return ret;
-	}
 	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static const struct hc_driver ohci_sa1111_hc_driver = {
-	.description =		hcd_name,
-	.product_desc =		"SA-1111 OHCI",
-	.hcd_priv_size =	sizeof(struct ohci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq =			ohci_irq,
-	.flags =		HCD_USB11 | HCD_MEMORY,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.start =		ohci_sa1111_start,
-	.stop =			ohci_stop,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue =		ohci_urb_enqueue,
-	.urb_dequeue =		ohci_urb_dequeue,
-	.endpoint_disable =	ohci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number =	ohci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data =	ohci_hub_status_data,
-	.hub_control =		ohci_hub_control,
-#ifdef	CONFIG_PM
-	.bus_suspend =		ohci_bus_suspend,
-	.bus_resume =		ohci_bus_resume,
-#endif
-	.start_port_reset =	ohci_start_port_reset,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_sa1111_drv_probe(struct sa1111_dev *dev)
-{
-	int ret;
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	ret = usb_hcd_sa1111_probe(&ohci_sa1111_hc_driver, dev);
-	return ret;
-}
-
-static int ohci_hcd_sa1111_drv_remove(struct sa1111_dev *dev)
+static void ohci_hcd_sa1111_shutdown(struct sa1111_dev *dev)
 {
 	struct usb_hcd *hcd = sa1111_get_drvdata(dev);
 
-	usb_hcd_sa1111_remove(hcd, dev);
-	return 0;
+	if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+		hcd->driver->shutdown(hcd);
+		sa1111_stop_hc(dev);
+	}
 }
 
 static struct sa1111_driver ohci_hcd_sa1111_driver = {
 	.drv = {
 		.name	= "sa1111-ohci",
+		.owner	= THIS_MODULE,
 	},
 	.devid		= SA1111_DEVID_USB,
-	.probe		= ohci_hcd_sa1111_drv_probe,
-	.remove		= ohci_hcd_sa1111_drv_remove,
+	.probe		= ohci_hcd_sa1111_probe,
+	.remove		= ohci_hcd_sa1111_remove,
+	.shutdown	= ohci_hcd_sa1111_shutdown,
 };
-
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 6b5eb10..e37dea8 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -565,6 +565,9 @@ static int uhci_start(struct usb_hcd *hcd)
 	struct dentry __maybe_unused *dentry;
 
 	hcd->uses_new_polling = 1;
+	/* Accept arbitrarily long scatter-gather lists */
+	if (!(hcd->driver->flags & HCD_LOCAL_MEM))
+		hcd->self.sg_tablesize = ~0;
 
 	spin_lock_init(&uhci->lock);
 	setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout,
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 35e257f..673ad12 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -93,7 +93,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 	 */
 	memset(port_removable, 0, sizeof(port_removable));
 	for (i = 0; i < ports; i++) {
-		portsc = xhci_readl(xhci, xhci->usb3_ports[i]);
+		portsc = xhci_readl(xhci, xhci->usb2_ports[i]);
 		/* If a device is removable, PORTSC reports a 0, same as in the
 		 * hub descriptor DeviceRemovable bits.
 		 */
@@ -422,6 +422,32 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
 	xhci_writel(xhci, temp, port_array[port_id]);
 }
 
+void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,
+		__le32 __iomem **port_array, int port_id, u16 wake_mask)
+{
+	u32 temp;
+
+	temp = xhci_readl(xhci, port_array[port_id]);
+	temp = xhci_port_state_to_neutral(temp);
+
+	if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT)
+		temp |= PORT_WKCONN_E;
+	else
+		temp &= ~PORT_WKCONN_E;
+
+	if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT)
+		temp |= PORT_WKDISC_E;
+	else
+		temp &= ~PORT_WKDISC_E;
+
+	if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT)
+		temp |= PORT_WKOC_E;
+	else
+		temp &= ~PORT_WKOC_E;
+
+	xhci_writel(xhci, temp, port_array[port_id]);
+}
+
 /* Test and clear port RWC bit */
 void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
 				int port_id, u32 port_bit)
@@ -448,6 +474,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	int slot_id;
 	struct xhci_bus_state *bus_state;
 	u16 link_state = 0;
+	u16 wake_mask = 0;
 
 	max_ports = xhci_get_ports(hcd, &port_array);
 	bus_state = &xhci->bus_state[hcd_index(hcd)];
@@ -593,6 +620,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	case SetPortFeature:
 		if (wValue == USB_PORT_FEAT_LINK_STATE)
 			link_state = (wIndex & 0xff00) >> 3;
+		if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK)
+			wake_mask = wIndex & 0xff00;
 		wIndex &= 0xff;
 		if (!wIndex || wIndex > max_ports)
 			goto error;
@@ -703,6 +732,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			temp = xhci_readl(xhci, port_array[wIndex]);
 			xhci_dbg(xhci, "set port reset, actual port %d status  = 0x%x\n", wIndex, temp);
 			break;
+		case USB_PORT_FEAT_REMOTE_WAKE_MASK:
+			xhci_set_remote_wake_mask(xhci, port_array,
+					wIndex, wake_mask);
+			temp = xhci_readl(xhci, port_array[wIndex]);
+			xhci_dbg(xhci, "set port remote wake mask, "
+					"actual port %d status  = 0x%x\n",
+					wIndex, temp);
+			break;
 		case USB_PORT_FEAT_BH_PORT_RESET:
 			temp |= PORT_WR;
 			xhci_writel(xhci, temp, port_array[wIndex]);
@@ -883,6 +920,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 			t2 |= PORT_LINK_STROBE | XDEV_U3;
 			set_bit(port_index, &bus_state->bus_suspended);
 		}
+		/* USB core sets remote wake mask for USB 3.0 hubs,
+		 * including the USB 3.0 roothub, but only if CONFIG_USB_SUSPEND
+		 * is enabled, so also enable remote wake here.
+		 */
 		if (hcd->self.root_hub->do_remote_wakeup) {
 			if (t1 & PORT_CONNECT) {
 				t2 |= PORT_WKOC_E | PORT_WKDISC_E;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 36cbe22..6b70e7f 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -2141,7 +2141,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 	unsigned int	val, val2;
 	u64		val_64;
 	struct xhci_segment	*seg;
-	u32 page_size;
+	u32 page_size, temp;
 	int i;
 
 	page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
@@ -2324,6 +2324,15 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
 	INIT_LIST_HEAD(&xhci->lpm_failed_devs);
 
+	/* Enable USB 3.0 device notifications for function remote wake, which
+	 * is necessary for allowing USB 3.0 devices to do remote wakeup from
+	 * U3 (device suspend).
+	 */
+	temp = xhci_readl(xhci, &xhci->op_regs->dev_notification);
+	temp &= ~DEV_NOTE_MASK;
+	temp |= DEV_NOTE_FWAKE;
+	xhci_writel(xhci, temp, &xhci->op_regs->dev_notification);
+
 	return 0;
 
 fail:
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b62037b..3a03324 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1237,6 +1237,26 @@ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
 	return num_similar_speed_ports;
 }
 
+static void handle_device_notification(struct xhci_hcd *xhci,
+		union xhci_trb *event)
+{
+	u32 slot_id;
+	struct usb_device *udev;
+
+	slot_id = TRB_TO_SLOT_ID(event->generic.field[3]);
+	if (!xhci->devs[slot_id]) {
+		xhci_warn(xhci, "Device Notification event for "
+				"unused slot %u\n", slot_id);
+		return;
+	}
+
+	xhci_dbg(xhci, "Device Wake Notification event for slot ID %u\n",
+			slot_id);
+	udev = xhci->devs[slot_id]->udev;
+	if (udev && udev->parent)
+		usb_wakeup_notification(udev->parent, udev->portnum);
+}
+
 static void handle_port_status(struct xhci_hcd *xhci,
 		union xhci_trb *event)
 {
@@ -1321,20 +1341,21 @@ static void handle_port_status(struct xhci_hcd *xhci,
 		}
 
 		if (DEV_SUPERSPEED(temp)) {
-			xhci_dbg(xhci, "resume SS port %d\n", port_id);
+			xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
+			/* Set a flag to say the port signaled remote wakeup,
+			 * so we can tell the difference between the end of
+			 * device and host initiated resume.
+			 */
+			bus_state->port_remote_wakeup |= 1 << faked_port_index;
+			xhci_test_and_clear_bit(xhci, port_array,
+					faked_port_index, PORT_PLC);
 			xhci_set_link_state(xhci, port_array, faked_port_index,
 						XDEV_U0);
-			slot_id = xhci_find_slot_id_by_port(hcd, xhci,
-					faked_port_index + 1);
-			if (!slot_id) {
-				xhci_dbg(xhci, "slot_id is zero\n");
-				goto cleanup;
-			}
-			xhci_ring_device(xhci, slot_id);
-			xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
-			/* Clear PORT_PLC */
-			xhci_test_and_clear_bit(xhci, port_array,
-						faked_port_index, PORT_PLC);
+			/* Need to wait until the next link state change
+			 * indicates the device is actually in U0.
+			 */
+			bogus_port_status = true;
+			goto cleanup;
 		} else {
 			xhci_dbg(xhci, "resume HS port %d\n", port_id);
 			bus_state->resume_done[faked_port_index] = jiffies +
@@ -1345,6 +1366,32 @@ static void handle_port_status(struct xhci_hcd *xhci,
 		}
 	}
 
+	if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
+			DEV_SUPERSPEED(temp)) {
+		xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
+		/* We've just brought the device into U0 through either the
+		 * Resume state after a device remote wakeup, or through the
+		 * U3Exit state after a host-initiated resume.  If it's a device
+		 * initiated remote wake, don't pass up the link state change,
+		 * so the roothub behavior is consistent with external
+		 * USB 3.0 hub behavior.
+		 */
+		slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+				faked_port_index + 1);
+		if (slot_id && xhci->devs[slot_id])
+			xhci_ring_device(xhci, slot_id);
+		if (bus_state->port_remote_wakeup && (1 << faked_port_index)) {
+			bus_state->port_remote_wakeup &=
+				~(1 << faked_port_index);
+			xhci_test_and_clear_bit(xhci, port_array,
+					faked_port_index, PORT_PLC);
+			usb_wakeup_notification(hcd->self.root_hub,
+					faked_port_index + 1);
+			bogus_port_status = true;
+			goto cleanup;
+		}
+	}
+
 	if (hcd->speed != HCD_USB3)
 		xhci_test_and_clear_bit(xhci, port_array, faked_port_index,
 					PORT_PLC);
@@ -2277,6 +2324,9 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
 		else
 			update_ptrs = 0;
 		break;
+	case TRB_TYPE(TRB_DEV_NOTE):
+		handle_device_notification(xhci, event);
+		break;
 	default:
 		if ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK) >=
 		    TRB_TYPE(48))
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6bbe3c3..c939f5f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -352,6 +352,11 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
 		/* hcd->irq is -1, we have MSI */
 		return 0;
 
+	if (!pdev->irq) {
+		xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
+		return -EINVAL;
+	}
+
 	/* fall back to legacy interrupt*/
 	ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
 			hcd->irq_descr, hcd);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index fb99c83..0f49369 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1344,6 +1344,7 @@ struct xhci_bus_state {
 	/* ports suspend status arrays - max 31 ports for USB2, 15 for USB3 */
 	u32			port_c_suspend;
 	u32			suspended_ports;
+	u32			port_remote_wakeup;
 	unsigned long		resume_done[USB_MAXCHILDREN];
 };
 
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 8dbf51a..90721b4 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -284,7 +284,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
 
 	if (result != size) {
 		dbg("%s - Unable to send config request, "
-				"request=0x%x size=%d result=%d\n",
+				"request=0x%x size=%d result=%d",
 				__func__, request, size, result);
 		if (result > 0)
 			result = -EPROTO;
@@ -338,7 +338,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
 
 	if ((size > 2 && result != size) || result < 0) {
 		dbg("%s - Unable to send request, "
-				"request=0x%x size=%d result=%d\n",
+				"request=0x%x size=%d result=%d",
 				__func__, request, size, result);
 		if (result > 0)
 			result = -EPROTO;
@@ -681,13 +681,13 @@ static void cp210x_set_termios(struct tty_struct *tty,
 		default:
 			dbg("cp210x driver does not "
 					"support the number of bits requested,"
-					" using 8 bit mode\n");
+					" using 8 bit mode");
 				bits |= BITS_DATA_8;
 				break;
 		}
 		if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
 			dbg("Number of data bits requested "
-					"not supported by device\n");
+					"not supported by device");
 	}
 
 	if ((cflag     & (PARENB|PARODD|CMSPAR)) !=
@@ -714,8 +714,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
 			}
 		}
 		if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
-			dbg("Parity mode not supported "
-					"by device\n");
+			dbg("Parity mode not supported by device");
 	}
 
 	if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
@@ -730,7 +729,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
 		}
 		if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
 			dbg("Number of stop bits requested "
-					"not supported by device\n");
+					"not supported by device");
 	}
 
 	if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 3bdeafa..5ae86b3 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -800,7 +800,7 @@ send:
 		cypress_write_int_callback, port, priv->write_urb_interval);
 	result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);
 	if (result) {
-		dev_err(&port->dev,
+		dev_err_console(port,
 				"%s - failed submitting write urb, error %d\n",
 							__func__, result);
 		priv->write_urb_in_use = 0;
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index b23bebd..2b1da0c 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -995,7 +995,7 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
 	/* return length of new data written, or error */
 	spin_unlock_irqrestore(&priv->dp_port_lock, flags);
 	if (ret < 0)
-		dev_err(&port->dev,
+		dev_err_console(port,
 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
 			__func__, ret, priv->dp_port_num);
 	dbg("digi_write: returning %d", ret);
@@ -1065,7 +1065,7 @@ static void digi_write_bulk_callback(struct urb *urb)
 
 	spin_unlock(&priv->dp_port_lock);
 	if (ret && ret != -EPERM)
-		dev_err(&port->dev,
+		dev_err_console(port,
 			"%s: usb_submit_urb failed, ret=%d, port=%d\n",
 			__func__, ret, priv->dp_port_num);
 }
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index f740357..2a2fa2d 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -217,7 +217,7 @@ retry:
 	clear_bit(i, &port->write_urbs_free);
 	result = usb_submit_urb(urb, GFP_ATOMIC);
 	if (result) {
-		dev_err(&port->dev, "%s - error submitting urb: %d\n",
+		dev_err_console(port, "%s - error submitting urb: %d\n",
 						__func__, result);
 		set_bit(i, &port->write_urbs_free);
 		spin_lock_irqsave(&port->lock, flags);
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 0497575..616b078 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -1286,7 +1286,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial,
 	count = fifo->count;
 	buffer = kmalloc(count+2, GFP_ATOMIC);
 	if (buffer == NULL) {
-		dev_err(&edge_port->port->dev,
+		dev_err_console(edge_port->port,
 				"%s - no more kernel memory...\n", __func__);
 		edge_port->write_in_progress = false;
 		goto exit_send;
@@ -1331,7 +1331,7 @@ static void send_more_port_data(struct edgeport_serial *edge_serial,
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status) {
 		/* something went wrong */
-		dev_err(&edge_port->port->dev,
+		dev_err_console(edge_port->port,
 			"%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n",
 				__func__, status);
 		edge_port->write_in_progress = false;
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 5818bfc..58a3697 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1817,7 +1817,7 @@ static void edge_bulk_out_callback(struct urb *urb)
 		    __func__, status);
 		return;
 	default:
-		dev_err(&urb->dev->dev, "%s - nonzero write bulk status "
+		dev_err_console(port, "%s - nonzero write bulk status "
 			"received: %d\n", __func__, status);
 	}
 
@@ -2111,7 +2111,7 @@ static void edge_send(struct tty_struct *tty)
 	/* send the data out the bulk port */
 	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 	if (result) {
-		dev_err(&port->dev,
+		dev_err_console(port,
 			"%s - failed submitting write urb, error %d\n",
 				__func__, result);
 		edge_port->ep_write_urb_in_use = 0;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 4554ee4..4fb29b4 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -1294,7 +1294,7 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
 		urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
 					       GFP_KERNEL);
 		if (urb->transfer_buffer == NULL) {
-			dev_err(&port->dev, "%s no more kernel memory...\n",
+			dev_err_console(port, "%s no more kernel memory...\n",
 				__func__);
 			goto exit;
 		}
@@ -1315,7 +1315,7 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
 	/* send it down the pipe */
 	status = usb_submit_urb(urb, GFP_ATOMIC);
 	if (status) {
-		dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
+		dev_err_console(port, "%s - usb_submit_urb(write bulk) failed "
 			"with status = %d\n", __func__, status);
 		bytes_sent = status;
 		goto exit;
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 03b5e24..19b11ce 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -1509,7 +1509,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
 		    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
 
 		if (urb->transfer_buffer == NULL) {
-			dev_err(&port->dev, "%s no more kernel memory...\n",
+			dev_err_console(port, "%s no more kernel memory...\n",
 				__func__);
 			goto exit;
 		}
@@ -1535,7 +1535,7 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
 
 	if (status) {
 		mos7840_port->busy[i] = 0;
-		dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
+		dev_err_console(port, "%s - usb_submit_urb(write bulk) failed "
 			"with status = %d\n", __func__, status);
 		bytes_sent = status;
 		goto exit;
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 8b8d58a..033e8af 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -254,7 +254,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
 	result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
 	if (result) {
 		set_bit(0, &wport->write_urbs_free);
-		dev_err(&port->dev,
+		dev_err_console(port,
 			"%s - failed submitting write urb, error %d\n",
 			__func__, result);
 	} else
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 39ed1f4..b54afce 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -788,7 +788,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff),
@@ -803,7 +802,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
-	/* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) },
@@ -828,7 +826,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	/* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
@@ -836,7 +833,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff),
@@ -846,7 +842,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) },
@@ -865,8 +860,6 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0095, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0098, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0099, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff),
 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) },
@@ -887,28 +880,18 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
@@ -1083,127 +1066,27 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1403, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1404, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1405, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1406, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1407, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1408, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1409, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1410, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1411, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1412, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1413, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1414, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1415, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1416, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1417, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1418, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1419, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1420, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1421, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1422, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1423, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1427, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1429, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1430, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1431, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1432, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1433, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1434, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1435, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1436, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1437, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1438, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1439, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1440, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1441, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1442, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1443, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1444, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1445, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1446, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1447, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1448, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1449, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1450, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1451, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1452, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1453, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1454, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1455, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1456, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1457, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1458, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1459, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1460, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1461, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1462, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1463, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1464, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1465, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1466, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1467, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1468, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1469, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1470, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1471, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1472, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1473, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1474, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1475, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1476, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1477, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1478, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1479, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1480, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1482, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1483, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1484, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1485, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1486, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1487, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1488, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1489, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1490, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1491, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1492, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1493, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1494, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1495, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1496, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1497, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1498, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1499, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1500, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1501, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1502, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1503, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1504, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1505, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1506, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1507, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1508, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1509, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1510, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
+	  0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
-	  0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
+	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
+
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index e287fd3..343e626 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -302,7 +302,7 @@ static void send_data(struct work_struct *work)
 	if (count != 0) {
 		allow = kmalloc(1, GFP_KERNEL);
 		if (!allow) {
-			dev_err(&port->dev, "%s(): kmalloc failed\n",
+			dev_err_console(port, "%s(): kmalloc failed\n",
 					__func__);
 			return;
 		}
@@ -334,7 +334,7 @@ static void send_data(struct work_struct *work)
 	port->write_urb->transfer_buffer_length = count;
 	result = usb_submit_urb(port->write_urb, GFP_NOIO);
 	if (result != 0) {
-		dev_err(&port->dev, "%s(): usb_submit_urb() failed"
+		dev_err_console(port, "%s(): usb_submit_urb() failed"
 			       " with error %d\n", __func__, result);
 		priv->flags.write_urb_in_use = 0;
 	}
@@ -938,7 +938,7 @@ static void oti6858_write_bulk_callback(struct urb *urb)
 		port->write_urb->transfer_buffer_length = 1;
 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 		if (result) {
-			dev_err(&port->dev, "%s(): usb_submit_urb() failed,"
+			dev_err_console(port, "%s(): usb_submit_urb() failed,"
 					" error %d\n", __func__, result);
 		} else {
 			return;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 8468eb7..91d0dc6 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1248,7 +1248,6 @@ static void ti_bulk_out_callback(struct urb *urb)
 {
 	struct ti_port *tport = urb->context;
 	struct usb_serial_port *port = tport->tp_port;
-	struct device *dev = &urb->dev->dev;
 	int status = urb->status;
 
 	dbg("%s - port %d", __func__, port->number);
@@ -1266,7 +1265,7 @@ static void ti_bulk_out_callback(struct urb *urb)
 		wake_up_interruptible(&tport->tp_write_wait);
 		return;
 	default:
-		dev_err(dev, "%s - nonzero urb status, %d\n",
+		dev_err_console(port, "%s - nonzero urb status, %d\n",
 			__func__, status);
 		tport->tp_tdev->td_urb_error = 1;
 		wake_up_interruptible(&tport->tp_write_wait);
@@ -1335,7 +1334,7 @@ static void ti_send(struct ti_port *tport)
 
 	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 	if (result) {
-		dev_err(&port->dev, "%s - submit write urb failed, %d\n",
+		dev_err_console(port, "%s - submit write urb failed, %d\n",
 							__func__, result);
 		tport->tp_write_urb_in_use = 0;
 		/* TODO: reschedule ti_send */
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 611b206..1e30cc9 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -214,15 +214,14 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
 	if (!try_module_get(serial->type->driver.owner))
 		goto error_module_get;
 
-	/* perform the standard setup */
-	retval = tty_init_termios(tty);
-	if (retval)
-		goto error_init_termios;
-
 	retval = usb_autopm_get_interface(serial->interface);
 	if (retval)
 		goto error_get_interface;
 
+	retval = tty_standard_install(driver, tty);
+	if (retval)
+		goto error_init_termios;
+
 	mutex_unlock(&serial->disc_mutex);
 
 	/* allow the driver to update the settings */
@@ -231,14 +230,11 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
 
 	tty->driver_data = port;
 
-	/* Final install (we use the default method) */
-	tty_driver_kref_get(driver);
-	tty->count++;
-	driver->ttys[idx] = tty;
 	return retval;
 
- error_get_interface:
  error_init_termios:
+	usb_autopm_put_interface(serial->interface);
+ error_get_interface:
 	module_put(serial->type->driver.owner);
  error_module_get:
  error_no_port:
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 7e0acf5..007cf3a 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -740,7 +740,7 @@ static int whiteheat_write(struct tty_struct *tty,
 		urb->transfer_buffer_length = bytes;
 		result = usb_submit_urb(urb, GFP_ATOMIC);
 		if (result) {
-			dev_err(&port->dev,
+			dev_err_console(port,
 				"%s - failed submitting write urb, error %d\n",
 				__func__, result);
 			sent = result;
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 51af2fe..bab8c8f 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -1276,6 +1276,7 @@ static struct usb_driver alauda_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	alauda_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(alauda_driver);
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c
index 387cbd47..5fe451d 100644
--- a/drivers/usb/storage/cypress_atacb.c
+++ b/drivers/usb/storage/cypress_atacb.c
@@ -272,6 +272,7 @@ static struct usb_driver cypress_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	cypress_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(cypress_driver);
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index 15d41f2..35e9c51 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -751,6 +751,7 @@ static struct usb_driver datafab_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	datafab_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(datafab_driver);
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index a6ade40..30532d9 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -2407,6 +2407,7 @@ static struct usb_driver ene_ub6250_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	ene_ub6250_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(ene_ub6250_driver);
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
index fa16157..042cf9e 100644
--- a/drivers/usb/storage/freecom.c
+++ b/drivers/usb/storage/freecom.c
@@ -553,6 +553,7 @@ static struct usb_driver freecom_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	freecom_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(freecom_driver);
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index bd55027..31fa24e 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1566,6 +1566,7 @@ static struct usb_driver isd200_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	isd200_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(isd200_driver);
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index a19211b..e3b9738 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -677,6 +677,7 @@ static struct usb_driver jumpshot_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	jumpshot_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(jumpshot_driver);
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c
index e720f8e..a8708ea 100644
--- a/drivers/usb/storage/karma.c
+++ b/drivers/usb/storage/karma.c
@@ -230,6 +230,7 @@ static struct usb_driver karma_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	karma_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(karma_driver);
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index d75155c..886567a 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -312,6 +312,7 @@ static struct usb_driver onetouch_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	onetouch_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(onetouch_driver);
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
index d32f720..b1c2fe8 100644
--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -1100,6 +1100,7 @@ static struct usb_driver realtek_cr_driver = {
 	.id_table = realtek_cr_ids,
 	.soft_unbind = 1,
 	.supports_autosuspend = 1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(realtek_cr_driver);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 13b8bcd..a324a5d 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -78,8 +78,6 @@ static const char* host_info(struct Scsi_Host *host)
 
 static int slave_alloc (struct scsi_device *sdev)
 {
-	struct us_data *us = host_to_us(sdev->host);
-
 	/*
 	 * Set the INQUIRY transfer length to 36.  We don't use any of
 	 * the extra data and many devices choke if asked for more or
@@ -104,18 +102,6 @@ static int slave_alloc (struct scsi_device *sdev)
 	 */
 	blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
 
-	/*
-	 * The UFI spec treates the Peripheral Qualifier bits in an
-	 * INQUIRY result as reserved and requires devices to set them
-	 * to 0.  However the SCSI spec requires these bits to be set
-	 * to 3 to indicate when a LUN is not present.
-	 *
-	 * Let the scanning code know if this target merely sets
-	 * Peripheral Device Type to 0x1f to indicate no LUN.
-	 */
-	if (us->subclass == USB_SC_UFI)
-		sdev->sdev_target->pdt_1f_for_no_lun = 1;
-
 	return 0;
 }
 
@@ -197,6 +183,9 @@ static int slave_configure(struct scsi_device *sdev)
 		 * page x08, so we will skip it. */
 		sdev->skip_ms_page_8 = 1;
 
+		/* Some devices don't handle VPD pages correctly */
+		sdev->skip_vpd_pages = 1;
+
 		/* Some disks return the total number of blocks in response
 		 * to READ CAPACITY rather than the highest block number.
 		 * If this device makes that mistake, tell the sd driver. */
@@ -217,16 +206,6 @@ static int slave_configure(struct scsi_device *sdev)
 		if (sdev->scsi_level > SCSI_SPC_2)
 			us->fflags |= US_FL_SANE_SENSE;
 
-		/* Some devices report a SCSI revision level above 2 but are
-		 * unable to handle the REPORT LUNS command (for which
-		 * support is mandatory at level 3).  Since we already have
-		 * a Get-Max-LUN request, we won't lose much by setting the
-		 * revision level down to 2.  The only devices that would be
-		 * affected are those with sparse LUNs. */
-		if (sdev->scsi_level > SCSI_2)
-			sdev->sdev_target->scsi_level =
-					sdev->scsi_level = SCSI_2;
-
 		/* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
 		 * Hardware Error) when any low-level error occurs,
 		 * recoverable or not.  Setting this flag tells the SCSI
@@ -283,6 +262,33 @@ static int slave_configure(struct scsi_device *sdev)
 	return 0;
 }
 
+static int target_alloc(struct scsi_target *starget)
+{
+	struct us_data *us = host_to_us(dev_to_shost(starget->dev.parent));
+
+	/*
+	 * Some USB drives don't support REPORT LUNS, even though they
+	 * report a SCSI revision level above 2.  Tell the SCSI layer
+	 * not to issue that command; it will perform a normal sequential
+	 * scan instead.
+	 */
+	starget->no_report_luns = 1;
+
+	/*
+	 * The UFI spec treats the Peripheral Qualifier bits in an
+	 * INQUIRY result as reserved and requires devices to set them
+	 * to 0.  However the SCSI spec requires these bits to be set
+	 * to 3 to indicate when a LUN is not present.
+	 *
+	 * Let the scanning code know if this target merely sets
+	 * Peripheral Device Type to 0x1f to indicate no LUN.
+	 */
+	if (us->subclass == USB_SC_UFI)
+		starget->pdt_1f_for_no_lun = 1;
+
+	return 0;
+}
+
 /* queue a command */
 /* This is always called with scsi_lock(host) held */
 static int queuecommand_lck(struct scsi_cmnd *srb,
@@ -546,6 +552,7 @@ struct scsi_host_template usb_stor_host_template = {
 
 	.slave_alloc =			slave_alloc,
 	.slave_configure =		slave_configure,
+	.target_alloc =			target_alloc,
 
 	/* lots of sg segments can be handled */
 	.sg_tablesize =			SCSI_MAX_SG_CHAIN_SEGMENTS,
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 425df7d..3252a62 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -1787,6 +1787,7 @@ static struct usb_driver sddr09_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	sddr09_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(sddr09_driver);
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index e4ca5fc..c144078 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -1006,6 +1006,7 @@ static struct usb_driver sddr55_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	sddr55_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(sddr55_driver);
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 1369d25..fa1ceeb 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -1863,6 +1863,7 @@ static struct usb_driver usbat_driver = {
 	.post_reset =	usb_stor_post_reset,
 	.id_table =	usbat_usb_ids,
 	.soft_unbind =	1,
+	.no_dynamic_id = 1,
 };
 
 module_usb_driver(usbat_driver);
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index a33ead5..8ec8a6e 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -13,7 +13,9 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/usb/hcd.h>
 #include <linux/usb/storage.h>
+#include <linux/usb/uas.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_dbg.h>
@@ -22,49 +24,6 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 
-/* Common header for all IUs */
-struct iu {
-	__u8 iu_id;
-	__u8 rsvd1;
-	__be16 tag;
-};
-
-enum {
-	IU_ID_COMMAND		= 0x01,
-	IU_ID_STATUS		= 0x03,
-	IU_ID_RESPONSE		= 0x04,
-	IU_ID_TASK_MGMT		= 0x05,
-	IU_ID_READ_READY	= 0x06,
-	IU_ID_WRITE_READY	= 0x07,
-};
-
-struct command_iu {
-	__u8 iu_id;
-	__u8 rsvd1;
-	__be16 tag;
-	__u8 prio_attr;
-	__u8 rsvd5;
-	__u8 len;
-	__u8 rsvd7;
-	struct scsi_lun lun;
-	__u8 cdb[16];	/* XXX: Overflow-checking tools may misunderstand */
-};
-
-/*
- * Also used for the Read Ready and Write Ready IUs since they have the
- * same first four bytes
- */
-struct sense_iu {
-	__u8 iu_id;
-	__u8 rsvd1;
-	__be16 tag;
-	__be16 status_qual;
-	__u8 status;
-	__u8 rsvd7[7];
-	__be16 len;
-	__u8 sense[SCSI_SENSE_BUFFERSIZE];
-};
-
 /*
  * The r00-r01c specs define this version of the SENSE IU data structure.
  * It's still in use by several different firmware releases.
@@ -79,18 +38,6 @@ struct sense_iu_old {
 	__u8 sense[SCSI_SENSE_BUFFERSIZE];
 };
 
-enum {
-	CMD_PIPE_ID		= 1,
-	STATUS_PIPE_ID		= 2,
-	DATA_IN_PIPE_ID		= 3,
-	DATA_OUT_PIPE_ID	= 4,
-
-	UAS_SIMPLE_TAG		= 0,
-	UAS_HEAD_TAG		= 1,
-	UAS_ORDERED_TAG		= 2,
-	UAS_ACA			= 4,
-};
-
 struct uas_dev_info {
 	struct usb_interface *intf;
 	struct usb_device *udev;
@@ -98,6 +45,8 @@ struct uas_dev_info {
 	unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe;
 	unsigned use_streams:1;
 	unsigned uas_sense_old:1;
+	struct scsi_cmnd *cmnd;
+	struct urb *status_urb; /* used only if stream support is available */
 };
 
 enum {
@@ -109,6 +58,9 @@ enum {
 	SUBMIT_DATA_OUT_URB	= (1 << 5),
 	ALLOC_CMD_URB		= (1 << 6),
 	SUBMIT_CMD_URB		= (1 << 7),
+	COMPLETED_DATA_IN	= (1 << 8),
+	COMPLETED_DATA_OUT	= (1 << 9),
+	DATA_COMPLETES_CMD	= (1 << 10),
 };
 
 /* Overrides scsi_pointer */
@@ -116,6 +68,7 @@ struct uas_cmd_info {
 	unsigned int state;
 	unsigned int stream;
 	struct urb *cmd_urb;
+	/* status_urb is used only if stream support isn't available */
 	struct urb *status_urb;
 	struct urb *data_in_urb;
 	struct urb *data_out_urb;
@@ -125,33 +78,43 @@ struct uas_cmd_info {
 /* I hate forward declarations, but I actually have a loop */
 static int uas_submit_urbs(struct scsi_cmnd *cmnd,
 				struct uas_dev_info *devinfo, gfp_t gfp);
+static void uas_do_work(struct work_struct *work);
 
+static DECLARE_WORK(uas_work, uas_do_work);
 static DEFINE_SPINLOCK(uas_work_lock);
 static LIST_HEAD(uas_work_list);
 
 static void uas_do_work(struct work_struct *work)
 {
 	struct uas_cmd_info *cmdinfo;
+	struct uas_cmd_info *temp;
 	struct list_head list;
+	int err;
 
 	spin_lock_irq(&uas_work_lock);
 	list_replace_init(&uas_work_list, &list);
 	spin_unlock_irq(&uas_work_lock);
 
-	list_for_each_entry(cmdinfo, &list, list) {
+	list_for_each_entry_safe(cmdinfo, temp, &list, list) {
 		struct scsi_pointer *scp = (void *)cmdinfo;
 		struct scsi_cmnd *cmnd = container_of(scp,
 							struct scsi_cmnd, SCp);
-		uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
+		err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
+		if (err) {
+			list_del(&cmdinfo->list);
+			spin_lock_irq(&uas_work_lock);
+			list_add_tail(&cmdinfo->list, &uas_work_list);
+			spin_unlock_irq(&uas_work_lock);
+			schedule_work(&uas_work);
+		}
 	}
 }
 
-static DECLARE_WORK(uas_work, uas_do_work);
-
 static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
 {
 	struct sense_iu *sense_iu = urb->transfer_buffer;
 	struct scsi_device *sdev = cmnd->device;
+	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
 	if (urb->actual_length > 16) {
 		unsigned len = be16_to_cpup(&sense_iu->len);
@@ -169,16 +132,15 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd)
 	}
 
 	cmnd->result = sense_iu->status;
-	if (sdev->current_cmnd)
-		sdev->current_cmnd = NULL;
-	cmnd->scsi_done(cmnd);
-	usb_free_urb(urb);
+	if (!(cmdinfo->state & DATA_COMPLETES_CMD))
+		cmnd->scsi_done(cmnd);
 }
 
 static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
 {
 	struct sense_iu_old *sense_iu = urb->transfer_buffer;
 	struct scsi_device *sdev = cmnd->device;
+	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
 	if (urb->actual_length > 8) {
 		unsigned len = be16_to_cpup(&sense_iu->len) - 2;
@@ -196,10 +158,8 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd)
 	}
 
 	cmnd->result = sense_iu->status;
-	if (sdev->current_cmnd)
-		sdev->current_cmnd = NULL;
-	cmnd->scsi_done(cmnd);
-	usb_free_urb(urb);
+	if (!(cmdinfo->state & DATA_COMPLETES_CMD))
+		cmnd->scsi_done(cmnd);
 }
 
 static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
@@ -208,7 +168,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
 	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 	int err;
 
-	cmdinfo->state = direction | SUBMIT_STATUS_URB;
+	cmdinfo->state = direction;
 	err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
 	if (err) {
 		spin_lock(&uas_work_lock);
@@ -221,27 +181,61 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd,
 static void uas_stat_cmplt(struct urb *urb)
 {
 	struct iu *iu = urb->transfer_buffer;
-	struct scsi_device *sdev = urb->context;
-	struct uas_dev_info *devinfo = sdev->hostdata;
+	struct Scsi_Host *shost = urb->context;
+	struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
 	struct scsi_cmnd *cmnd;
+	struct uas_cmd_info *cmdinfo;
 	u16 tag;
+	int ret;
 
 	if (urb->status) {
 		dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status);
-		usb_free_urb(urb);
+		if (devinfo->use_streams)
+			usb_free_urb(urb);
 		return;
 	}
 
 	tag = be16_to_cpup(&iu->tag) - 1;
-	if (sdev->current_cmnd)
-		cmnd = sdev->current_cmnd;
+	if (tag == 0)
+		cmnd = devinfo->cmnd;
 	else
-		cmnd = scsi_find_tag(sdev, tag);
-	if (!cmnd)
+		cmnd = scsi_host_find_tag(shost, tag - 1);
+	if (!cmnd) {
+		if (devinfo->use_streams) {
+			usb_free_urb(urb);
+			return;
+		}
+		ret = usb_submit_urb(urb, GFP_ATOMIC);
+		if (ret)
+			dev_err(&urb->dev->dev, "failed submit status urb\n");
 		return;
+	}
+	cmdinfo = (void *)&cmnd->SCp;
 
 	switch (iu->iu_id) {
 	case IU_ID_STATUS:
+		if (devinfo->cmnd == cmnd)
+			devinfo->cmnd = NULL;
+
+		if (!(cmdinfo->state & COMPLETED_DATA_IN) &&
+				cmdinfo->data_in_urb) {
+		       if (devinfo->use_streams) {
+			       cmdinfo->state |= DATA_COMPLETES_CMD;
+			       usb_unlink_urb(cmdinfo->data_in_urb);
+		       } else {
+			       usb_free_urb(cmdinfo->data_in_urb);
+		       }
+		}
+		if (!(cmdinfo->state & COMPLETED_DATA_OUT) &&
+				cmdinfo->data_out_urb) {
+			if (devinfo->use_streams) {
+				cmdinfo->state |= DATA_COMPLETES_CMD;
+				usb_unlink_urb(cmdinfo->data_in_urb);
+			} else {
+				usb_free_urb(cmdinfo->data_out_urb);
+			}
+		}
+
 		if (urb->actual_length < 16)
 			devinfo->uas_sense_old = 1;
 		if (devinfo->uas_sense_old)
@@ -259,29 +253,70 @@ static void uas_stat_cmplt(struct urb *urb)
 		scmd_printk(KERN_ERR, cmnd,
 			"Bogus IU (%d) received on status pipe\n", iu->iu_id);
 	}
+
+	if (devinfo->use_streams) {
+		usb_free_urb(urb);
+		return;
+	}
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret)
+		dev_err(&urb->dev->dev, "failed submit status urb\n");
 }
 
-static void uas_data_cmplt(struct urb *urb)
+static void uas_data_out_cmplt(struct urb *urb)
 {
-	struct scsi_data_buffer *sdb = urb->context;
+	struct scsi_cmnd *cmnd = urb->context;
+	struct scsi_data_buffer *sdb = scsi_out(cmnd);
+	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+
+	cmdinfo->state |= COMPLETED_DATA_OUT;
+
 	sdb->resid = sdb->length - urb->actual_length;
 	usb_free_urb(urb);
+
+	if (cmdinfo->state & DATA_COMPLETES_CMD)
+		cmnd->scsi_done(cmnd);
+}
+
+static void uas_data_in_cmplt(struct urb *urb)
+{
+	struct scsi_cmnd *cmnd = urb->context;
+	struct scsi_data_buffer *sdb = scsi_in(cmnd);
+	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
+
+	cmdinfo->state |= COMPLETED_DATA_IN;
+
+	sdb->resid = sdb->length - urb->actual_length;
+	usb_free_urb(urb);
+
+	if (cmdinfo->state & DATA_COMPLETES_CMD)
+		cmnd->scsi_done(cmnd);
 }
 
 static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
-				unsigned int pipe, u16 stream_id,
-				struct scsi_data_buffer *sdb,
-				enum dma_data_direction dir)
+		unsigned int pipe, struct scsi_cmnd *cmnd,
+		enum dma_data_direction dir)
 {
+	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 	struct usb_device *udev = devinfo->udev;
 	struct urb *urb = usb_alloc_urb(0, gfp);
+	struct scsi_data_buffer *sdb;
+	usb_complete_t complete_fn;
+	u16 stream_id = cmdinfo->stream;
 
 	if (!urb)
 		goto out;
-	usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt,
-									sdb);
-	if (devinfo->use_streams)
-		urb->stream_id = stream_id;
+	if (dir == DMA_FROM_DEVICE) {
+		sdb = scsi_in(cmnd);
+		complete_fn = uas_data_in_cmplt;
+	} else {
+		sdb = scsi_out(cmnd);
+		complete_fn = uas_data_out_cmplt;
+	}
+	usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length,
+			complete_fn, cmnd);
+	urb->stream_id = stream_id;
 	urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0;
 	urb->sg = sdb->table.sgl;
  out:
@@ -289,7 +324,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
 }
 
 static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
-					struct scsi_cmnd *cmnd, u16 stream_id)
+		struct Scsi_Host *shost, u16 stream_id)
 {
 	struct usb_device *udev = devinfo->udev;
 	struct urb *urb = usb_alloc_urb(0, gfp);
@@ -303,7 +338,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp,
 		goto free;
 
 	usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu),
-						uas_stat_cmplt, cmnd->device);
+						uas_stat_cmplt, shost);
 	urb->stream_id = stream_id;
 	urb->transfer_flags |= URB_FREE_BUFFER;
  out:
@@ -334,7 +369,10 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp,
 		goto free;
 
 	iu->iu_id = IU_ID_COMMAND;
-	iu->tag = cpu_to_be16(stream_id);
+	if (blk_rq_tagged(cmnd->request))
+		iu->tag = cpu_to_be16(cmnd->request->tag + 2);
+	else
+		iu->tag = cpu_to_be16(1);
 	iu->prio_attr = UAS_SIMPLE_TAG;
 	iu->len = len;
 	int_to_scsilun(sdev->lun, &iu->lun);
@@ -362,8 +400,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
 	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 
 	if (cmdinfo->state & ALLOC_STATUS_URB) {
-		cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd,
-							  cmdinfo->stream);
+		cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp,
+				cmnd->device->host, cmdinfo->stream);
 		if (!cmdinfo->status_urb)
 			return SCSI_MLQUEUE_DEVICE_BUSY;
 		cmdinfo->state &= ~ALLOC_STATUS_URB;
@@ -380,8 +418,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
 
 	if (cmdinfo->state & ALLOC_DATA_IN_URB) {
 		cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp,
-					devinfo->data_in_pipe, cmdinfo->stream,
-					scsi_in(cmnd), DMA_FROM_DEVICE);
+					devinfo->data_in_pipe, cmnd,
+					DMA_FROM_DEVICE);
 		if (!cmdinfo->data_in_urb)
 			return SCSI_MLQUEUE_DEVICE_BUSY;
 		cmdinfo->state &= ~ALLOC_DATA_IN_URB;
@@ -398,8 +436,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd,
 
 	if (cmdinfo->state & ALLOC_DATA_OUT_URB) {
 		cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp,
-					devinfo->data_out_pipe, cmdinfo->stream,
-					scsi_out(cmnd), DMA_TO_DEVICE);
+					devinfo->data_out_pipe, cmnd,
+					DMA_TO_DEVICE);
 		if (!cmdinfo->data_out_urb)
 			return SCSI_MLQUEUE_DEVICE_BUSY;
 		cmdinfo->state &= ~ALLOC_DATA_OUT_URB;
@@ -444,13 +482,13 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
 
 	BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
 
-	if (!cmdinfo->status_urb && sdev->current_cmnd)
+	if (devinfo->cmnd)
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 
 	if (blk_rq_tagged(cmnd->request)) {
-		cmdinfo->stream = cmnd->request->tag + 1;
+		cmdinfo->stream = cmnd->request->tag + 2;
 	} else {
-		sdev->current_cmnd = cmnd;
+		devinfo->cmnd = cmnd;
 		cmdinfo->stream = 1;
 	}
 
@@ -472,7 +510,8 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd,
 	}
 
 	if (!devinfo->use_streams) {
-		cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
+		cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB |
+				ALLOC_STATUS_URB | SUBMIT_STATUS_URB);
 		cmdinfo->stream = 0;
 	}
 
@@ -551,7 +590,7 @@ static int uas_slave_configure(struct scsi_device *sdev)
 {
 	struct uas_dev_info *devinfo = sdev->hostdata;
 	scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
-	scsi_activate_tcq(sdev, devinfo->qdepth - 1);
+	scsi_activate_tcq(sdev, devinfo->qdepth - 2);
 	return 0;
 }
 
@@ -589,22 +628,34 @@ static int uas_is_interface(struct usb_host_interface *intf)
 		intf->desc.bInterfaceProtocol == USB_PR_UAS);
 }
 
+static int uas_isnt_supported(struct usb_device *udev)
+{
+	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+
+	dev_warn(&udev->dev, "The driver for the USB controller %s does not "
+			"support scatter-gather which is\n",
+			hcd->driver->description);
+	dev_warn(&udev->dev, "required by the UAS driver. Please try an"
+			"alternative USB controller if you wish to use UAS.\n");
+	return -ENODEV;
+}
+
 static int uas_switch_interface(struct usb_device *udev,
 						struct usb_interface *intf)
 {
 	int i;
-
-	if (uas_is_interface(intf->cur_altsetting))
-		return 0;
+	int sg_supported = udev->bus->sg_tablesize != 0;
 
 	for (i = 0; i < intf->num_altsetting; i++) {
 		struct usb_host_interface *alt = &intf->altsetting[i];
-		if (alt == intf->cur_altsetting)
-			continue;
-		if (uas_is_interface(alt))
+
+		if (uas_is_interface(alt)) {
+			if (!sg_supported)
+				return uas_isnt_supported(udev);
 			return usb_set_interface(udev,
 						alt->desc.bInterfaceNumber,
 						alt->desc.bAlternateSetting);
+		}
 	}
 
 	return -ENODEV;
@@ -619,6 +670,7 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo)
 	unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints;
 
 	devinfo->uas_sense_old = 0;
+	devinfo->cmnd = NULL;
 
 	for (i = 0; i < n_endpoints; i++) {
 		unsigned char *extra = endpoint[i].extra;
@@ -670,6 +722,40 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo)
 	}
 }
 
+static int uas_alloc_status_urb(struct uas_dev_info *devinfo,
+		struct Scsi_Host *shost)
+{
+	if (devinfo->use_streams) {
+		devinfo->status_urb = NULL;
+		return 0;
+	}
+
+	devinfo->status_urb = uas_alloc_sense_urb(devinfo, GFP_KERNEL,
+			shost, 0);
+	if (!devinfo->status_urb)
+		goto err_s_urb;
+
+	if (usb_submit_urb(devinfo->status_urb, GFP_KERNEL))
+		goto err_submit_urb;
+
+	return 0;
+err_submit_urb:
+	usb_free_urb(devinfo->status_urb);
+err_s_urb:
+	return -ENOMEM;
+}
+
+static void uas_free_streams(struct uas_dev_info *devinfo)
+{
+	struct usb_device *udev = devinfo->udev;
+	struct usb_host_endpoint *eps[3];
+
+	eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
+	eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
+	eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
+	usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
+}
+
 /*
  * XXX: What I'd like to do here is register a SCSI host for each USB host in
  * the system.  Follow usb-storage's design of registering a SCSI host for
@@ -699,18 +785,33 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	shost->max_id = 1;
 	shost->sg_tablesize = udev->bus->sg_tablesize;
 
-	result = scsi_add_host(shost, &intf->dev);
+	devinfo->intf = intf;
+	devinfo->udev = udev;
+	uas_configure_endpoints(devinfo);
+
+	result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2);
 	if (result)
 		goto free;
+
+	result = scsi_add_host(shost, &intf->dev);
+	if (result)
+		goto deconfig_eps;
+
 	shost->hostdata[0] = (unsigned long)devinfo;
 
-	devinfo->intf = intf;
-	devinfo->udev = udev;
-	uas_configure_endpoints(devinfo);
+	result = uas_alloc_status_urb(devinfo, shost);
+	if (result)
+		goto err_alloc_status;
 
 	scsi_scan_host(shost);
 	usb_set_intfdata(intf, shost);
 	return result;
+
+err_alloc_status:
+	scsi_remove_host(shost);
+	shost = NULL;
+deconfig_eps:
+	uas_free_streams(devinfo);
  free:
 	kfree(devinfo);
 	if (shost)
@@ -732,18 +833,13 @@ static int uas_post_reset(struct usb_interface *intf)
 
 static void uas_disconnect(struct usb_interface *intf)
 {
-	struct usb_device *udev = interface_to_usbdev(intf);
-	struct usb_host_endpoint *eps[3];
 	struct Scsi_Host *shost = usb_get_intfdata(intf);
 	struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
 
 	scsi_remove_host(shost);
-
-	eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
-	eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
-	eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
-	usb_free_streams(intf, eps, 3, GFP_KERNEL);
-
+	usb_kill_urb(devinfo->status_urb);
+	usb_free_urb(devinfo->status_urb);
+	uas_free_streams(devinfo);
 	kfree(devinfo);
 }
 
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3dd7da9..58f5677 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -125,6 +125,9 @@ static struct us_unusual_dev us_unusual_dev_list[] = {
 	{ }		/* Terminating entry */
 };
 
+static struct us_unusual_dev for_dynamic_ids =
+		USUAL_DEV(USB_SC_SCSI, USB_PR_BULK, 0);
+
 #undef UNUSUAL_DEV
 #undef COMPLIANT_DEV
 #undef USUAL_DEV
@@ -1027,8 +1030,10 @@ EXPORT_SYMBOL_GPL(usb_stor_disconnect);
 static int storage_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id)
 {
+	struct us_unusual_dev *unusual_dev;
 	struct us_data *us;
 	int result;
+	int size;
 
 	/*
 	 * If libusual is configured, let it decide whether a standard
@@ -1047,8 +1052,19 @@ static int storage_probe(struct usb_interface *intf,
 	 * table, so we use the index of the id entry to find the
 	 * corresponding unusual_devs entry.
 	 */
-	result = usb_stor_probe1(&us, intf, id,
-			(id - usb_storage_usb_ids) + us_unusual_dev_list);
+
+	size = ARRAY_SIZE(us_unusual_dev_list);
+	if (id >= usb_storage_usb_ids && id < usb_storage_usb_ids + size) {
+		unusual_dev = (id - usb_storage_usb_ids) + us_unusual_dev_list;
+	} else {
+		unusual_dev = &for_dynamic_ids;
+
+		US_DEBUGP("%s %s 0x%04x 0x%04x\n", "Use Bulk-Only transport",
+			"with the Transparent SCSI protocol for dynamic id:",
+			id->idVendor, id->idProduct);
+	}
+
+	result = usb_stor_probe1(&us, intf, id, unusual_dev);
 	if (result)
 		return result;
 
@@ -1074,7 +1090,6 @@ static struct usb_driver usb_storage_driver = {
 	.id_table =	usb_storage_usb_ids,
 	.supports_autosuspend = 1,
 	.soft_unbind =	1,
-	.no_dynamic_id = 1,
 };
 
 static int __init usb_stor_init(void)
diff --git a/drivers/uwb/allocator.c b/drivers/uwb/allocator.c
index e45e673..6e3e713 100644
--- a/drivers/uwb/allocator.c
+++ b/drivers/uwb/allocator.c
@@ -334,10 +334,8 @@ int uwb_rsv_find_best_allocation(struct uwb_rsv *rsv, struct uwb_mas_bm *availab
 
 
 	/* fill the not available vector from the available bm */
-	for (bit_index = 0; bit_index < UWB_NUM_MAS; bit_index++) {
-		if (!test_bit(bit_index, available->bm))
-			ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL;
-	}
+	for_each_clear_bit(bit_index, available->bm, UWB_NUM_MAS)
+		ai->bm[bit_index] = UWB_RSV_MAS_NOT_AVAIL;
 
 	if (ai->max_interval == 1) {
 		get_row_descriptors(ai);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c14c42b..bdb2d64 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -937,9 +937,9 @@ static int set_bit_to_user(int nr, void __user *addr)
 	if (r < 0)
 		return r;
 	BUG_ON(r != 1);
-	base = kmap_atomic(page, KM_USER0);
+	base = kmap_atomic(page);
 	set_bit(bit, base);
-	kunmap_atomic(base, KM_USER0);
+	kunmap_atomic(base);
 	set_page_dirty_lock(page);
 	put_page(page);
 	return 0;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6ca0c40..8951cbd 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1123,6 +1123,18 @@ config FB_RIVA_BACKLIGHT
 	help
 	  Say Y here if you want to control the backlight of your display.
 
+config FB_I740
+	tristate "Intel740 support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	select FB_DDC
+	help
+	  This driver supports graphics cards based on Intel740 chip.
+
 config FB_I810
 	tristate "Intel 810/815 support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
@@ -2411,7 +2423,7 @@ config FB_PUV3_UNIGFX
 
 source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
-
+source "drivers/video/exynos/Kconfig"
 source "drivers/video/backlight/Kconfig"
 
 if VT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1426068..9356add 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/
 
+obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
+
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
 obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
@@ -37,6 +39,7 @@ obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
 
+obj-$(CONFIG_FB_I740)		  += i740fb.o
 obj-$(CONFIG_FB_MATROX)		  += matrox/
 obj-$(CONFIG_FB_RIVA)		  += riva/
 obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index e40c00f..d99505b 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -421,24 +421,18 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
 		var->red.length = var->green.length = var->blue.length
 			= var->bits_per_pixel;
 		break;
-	case 15:
 	case 16:
 		if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {
 			/* RGB:565 mode */
 			var->red.offset = 11;
 			var->blue.offset = 0;
-			var->green.length = 6;
-		} else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) {
-			var->red.offset = 10;
-			var->blue.offset = 0;
-			var->green.length = 5;
 		} else {
-			/* BGR:555 mode */
+			/* BGR:565 mode */
 			var->red.offset = 0;
-			var->blue.offset = 10;
-			var->green.length = 5;
+			var->blue.offset = 11;
 		}
 		var->green.offset = 5;
+		var->green.length = 6;
 		var->red.length = var->blue.length = 5;
 		break;
 	case 32:
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index de9da67..befcbd8 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -477,7 +477,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
 	u32 sys_clksrc;
 
 	/* Allocate new device private */
-	fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL);
+	fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device),
+			     GFP_KERNEL);
 	if (!fbdev) {
 		print_err("fail to allocate device private record");
 		return -ENOMEM;
@@ -498,8 +499,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
 	au1100fb_fix.mmio_start = regs_res->start;
 	au1100fb_fix.mmio_len = resource_size(regs_res);
 
-	if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
-				DRIVER_NAME)) {
+	if (!devm_request_mem_region(au1100fb_fix.mmio_start,
+				     au1100fb_fix.mmio_len,
+				     DRIVER_NAME)) {
 		print_err("fail to lock memory region at 0x%08lx",
 				au1100fb_fix.mmio_start);
 		return -EBUSY;
@@ -514,8 +516,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
 	fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
 		  	(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
 
-	fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
-					&fbdev->fb_phys, GFP_KERNEL);
+	fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev,
+					    PAGE_ALIGN(fbdev->fb_len),
+					    &fbdev->fb_phys, GFP_KERNEL);
 	if (!fbdev->fb_mem) {
 		print_err("fail to allocate frambuffer (size: %dK))",
 			  fbdev->fb_len / 1024);
@@ -557,14 +560,14 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
 	fbdev->info.fbops = &au1100fb_ops;
 	fbdev->info.fix = au1100fb_fix;
 
-	if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+	fbdev->info.pseudo_palette =
+		devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL);
+	if (!fbdev->info.pseudo_palette)
 		return -ENOMEM;
-	}
 
 	if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
 		print_err("Fail to allocate colormap (%d entries)",
 			   AU1100_LCD_NBR_PALETTE_ENTRIES);
-		kfree(fbdev->info.pseudo_palette);
 		return -EFAULT;
 	}
 
@@ -582,9 +585,6 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
 	return 0;
 
 failed:
-	if (fbdev->regs) {
-		release_mem_region(fbdev->regs_phys, fbdev->regs_len);
-	}
 	if (fbdev->fb_mem) {
 		dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
 				     fbdev->fb_phys);
@@ -592,10 +592,9 @@ failed:
 	if (fbdev->info.cmap.len != 0) {
 		fb_dealloc_cmap(&fbdev->info.cmap);
 	}
-	kfree(fbdev);
 	platform_set_drvdata(dev, NULL);
 
-	return 0;
+	return -ENODEV;
 }
 
 int au1100fb_drv_remove(struct platform_device *dev)
@@ -615,14 +614,7 @@ int au1100fb_drv_remove(struct platform_device *dev)
 	/* Clean up all probe data */
 	unregister_framebuffer(&fbdev->info);
 
-	release_mem_region(fbdev->regs_phys, fbdev->regs_len);
-
-	dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem,
-			  fbdev->fb_phys);
-
 	fb_dealloc_cmap(&fbdev->info.cmap);
-	kfree(fbdev->info.pseudo_palette);
-	kfree((void*)fbdev);
 
 	return 0;
 }
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 04e4479..3e9a773 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
 		/* Allocate the framebuffer to the maximum screen size */
 		fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
 
-		fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
+		fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev,
 				PAGE_ALIGN(fbdev->fb_len),
 				&fbdev->fb_phys, GFP_KERNEL);
 		if (!fbdev->fb_mem) {
@@ -1788,9 +1788,6 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
 
 failed:
 	/* NOTE: This only does the current plane/window that failed; others are still active */
-	if (fbdev->fb_mem)
-		dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
-				fbdev->fb_mem, fbdev->fb_phys);
 	if (fbi) {
 		if (fbi->cmap.len != 0)
 			fb_dealloc_cmap(&fbi->cmap);
@@ -1817,10 +1814,6 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev)
 
 		/* Clean up all probe data */
 		unregister_framebuffer(fbi);
-		if (fbdev->fb_mem)
-			dma_free_noncoherent(&dev->dev,
-					PAGE_ALIGN(fbdev->fb_len),
-					fbdev->fb_mem, fbdev->fb_phys);
 		if (fbi->cmap.len != 0)
 			fb_dealloc_cmap(&fbi->cmap);
 		kfree(fbi->pseudo_palette);
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index a1376dc..915943a 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -187,7 +187,8 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	data = kzalloc(sizeof(struct pm860x_backlight_data), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
+			    GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 	strncpy(name, res->name, MFD_NAME_SIZE);
@@ -200,7 +201,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
 	data->port = pdata->flags;
 	if (data->port < 0) {
 		dev_err(&pdev->dev, "wrong platform data is assigned");
-		kfree(data);
 		return -EINVAL;
 	}
 
@@ -211,7 +211,6 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
 					&pm860x_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		kfree(data);
 		return PTR_ERR(bl);
 	}
 	bl->props.brightness = MAX_BRIGHTNESS;
@@ -247,17 +246,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
 	return 0;
 out:
 	backlight_device_unregister(bl);
-	kfree(data);
 	return ret;
 }
 
 static int pm860x_backlight_remove(struct platform_device *pdev)
 {
 	struct backlight_device *bl = platform_get_drvdata(pdev);
-	struct pm860x_backlight_data *data = bl_get_data(bl);
 
 	backlight_device_unregister(bl);
-	kfree(data);
 	return 0;
 }
 
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 681b369..ed68fde5 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -334,6 +334,27 @@ config BACKLIGHT_AAT2870
 	  If you have a AnalogicTech AAT2870 say Y to enable the
 	  backlight driver.
 
+config BACKLIGHT_LP855X
+	tristate "Backlight driver for TI LP855X"
+	depends on BACKLIGHT_CLASS_DEVICE && I2C
+	help
+	  This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556
+	  backlight driver.
+
+config BACKLIGHT_OT200
+	tristate "Backlight driver for ot200 visualisation device"
+	depends on BACKLIGHT_CLASS_DEVICE && CS5535_MFGPT
+	help
+	  To compile this driver as a module, choose M here: the module will be
+	  called ot200_bl.
+
+config BACKLIGHT_PANDORA
+	tristate "Backlight driver for Pandora console"
+	depends on TWL4030_CORE
+	help
+	  If you have a Pandora console, say Y to enable the
+	  backlight driver.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index af5cf65..8071eb6 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -22,7 +22,9 @@ obj-$(CONFIG_BACKLIGHT_GENERIC)	+= generic_bl.o
 obj-$(CONFIG_BACKLIGHT_HP700)	+= jornada720_bl.o
 obj-$(CONFIG_BACKLIGHT_HP680)	+= hp680_bl.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO)	+= locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LP855X)	+= lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_OMAP1)	+= omap1_bl.o
+obj-$(CONFIG_BACKLIGHT_PANDORA)	+= pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
 obj-$(CONFIG_BACKLIGHT_PWM)	+= pwm_bl.o
@@ -38,4 +40,4 @@ obj-$(CONFIG_BACKLIGHT_ADP8870)	+= adp8870_bl.o
 obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)	+= pcf50633-backlight.o
 obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
-
+obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index 331f1ef..7ff7522 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -145,7 +145,9 @@ static int aat2870_bl_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	aat2870_bl = kzalloc(sizeof(struct aat2870_bl_driver_data), GFP_KERNEL);
+	aat2870_bl = devm_kzalloc(&pdev->dev,
+				  sizeof(struct aat2870_bl_driver_data),
+				  GFP_KERNEL);
 	if (!aat2870_bl) {
 		dev_err(&pdev->dev,
 			"Failed to allocate memory for aat2870 backlight\n");
@@ -162,7 +164,7 @@ static int aat2870_bl_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev,
 			"Failed allocate memory for backlight device\n");
 		ret = PTR_ERR(bd);
-		goto out_kfree;
+		goto out;
 	}
 
 	aat2870_bl->pdev = pdev;
@@ -199,8 +201,6 @@ static int aat2870_bl_probe(struct platform_device *pdev)
 
 out_bl_dev_unregister:
 	backlight_device_unregister(bd);
-out_kfree:
-	kfree(aat2870_bl);
 out:
 	return ret;
 }
@@ -215,7 +215,6 @@ static int aat2870_bl_remove(struct platform_device *pdev)
 	backlight_update_status(bd);
 
 	backlight_device_unregister(bd);
-	kfree(aat2870_bl);
 
 	return 0;
 }
diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
index 2e630bf..4911ea7 100644
--- a/drivers/video/backlight/adp5520_bl.c
+++ b/drivers/video/backlight/adp5520_bl.c
@@ -289,7 +289,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 	struct adp5520_bl *data;
 	int ret = 0;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
@@ -298,7 +298,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 
 	if (data->pdata  == NULL) {
 		dev_err(&pdev->dev, "missing platform data\n");
-		kfree(data);
 		return -ENODEV;
 	}
 
@@ -314,7 +313,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 				       &adp5520_bl_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		kfree(data);
 		return PTR_ERR(bl);
 	}
 
@@ -326,7 +324,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register sysfs\n");
 		backlight_device_unregister(bl);
-		kfree(data);
 	}
 
 	platform_set_drvdata(pdev, bl);
@@ -348,7 +345,6 @@ static int __devexit adp5520_bl_remove(struct platform_device *pdev)
 				&adp5520_bl_attr_group);
 
 	backlight_device_unregister(bl);
-	kfree(data);
 
 	return 0;
 }
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 378276c..550dbf0 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -819,17 +819,7 @@ static struct i2c_driver adp8860_driver = {
 	.id_table = adp8860_id,
 };
 
-static int __init adp8860_init(void)
-{
-	return i2c_add_driver(&adp8860_driver);
-}
-module_init(adp8860_init);
-
-static void __exit adp8860_exit(void)
-{
-	i2c_del_driver(&adp8860_driver);
-}
-module_exit(adp8860_exit);
+module_i2c_driver(adp8860_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 6735059..9be58c6 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -991,17 +991,7 @@ static struct i2c_driver adp8870_driver = {
 	.id_table = adp8870_id,
 };
 
-static int __init adp8870_init(void)
-{
-	return i2c_add_driver(&adp8870_driver);
-}
-module_init(adp8870_init);
-
-static void __exit adp8870_exit(void)
-{
-	i2c_del_driver(&adp8870_driver);
-}
-module_exit(adp8870_exit);
+module_i2c_driver(adp8870_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c
index 7838a23..7bdadc7 100644
--- a/drivers/video/backlight/ams369fg06.c
+++ b/drivers/video/backlight/ams369fg06.c
@@ -629,18 +629,7 @@ static struct spi_driver ams369fg06_driver = {
 	.resume		= ams369fg06_resume,
 };
 
-static int __init ams369fg06_init(void)
-{
-	return spi_register_driver(&ams369fg06_driver);
-}
-
-static void __exit ams369fg06_exit(void)
-{
-	spi_unregister_driver(&ams369fg06_driver);
-}
-
-module_init(ams369fg06_init);
-module_exit(ams369fg06_exit);
+module_spi_driver(ams369fg06_driver);
 
 MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
 MODULE_DESCRIPTION("ams369fg06 LCD Driver");
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index c6533ba..6dab13f 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -629,17 +629,7 @@ static struct spi_driver corgi_lcd_driver = {
 	.resume		= corgi_lcd_resume,
 };
 
-static int __init corgi_lcd_init(void)
-{
-	return spi_register_driver(&corgi_lcd_driver);
-}
-module_init(corgi_lcd_init);
-
-static void __exit corgi_lcd_exit(void)
-{
-	spi_unregister_driver(&corgi_lcd_driver);
-}
-module_exit(corgi_lcd_exit);
+module_spi_driver(corgi_lcd_driver);
 
 MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 6c8c540..22489eb 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -212,7 +212,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
 			      &gpio_bar);
 	gpio_bar &= ~0x3F;
 
-	crp = kzalloc(sizeof(*crp), GFP_KERNEL);
+	crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL);
 	if (!crp) {
 		lcd_device_unregister(ldp);
 		backlight_device_unregister(bdp);
@@ -243,7 +243,6 @@ static int cr_backlight_remove(struct platform_device *pdev)
 	backlight_device_unregister(crp->cr_backlight_device);
 	lcd_device_unregister(crp->cr_lcd_device);
 	pci_dev_put(lpc_dev);
-	kfree(crp);
 
 	return 0;
 }
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c
index abb4a06..30e1968 100644
--- a/drivers/video/backlight/da903x_bl.c
+++ b/drivers/video/backlight/da903x_bl.c
@@ -110,7 +110,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
 	struct backlight_properties props;
 	int max_brightness;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
@@ -124,7 +124,6 @@ static int da903x_backlight_probe(struct platform_device *pdev)
 	default:
 		dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
 				pdev->id);
-		kfree(data);
 		return -EINVAL;
 	}
 
@@ -143,7 +142,6 @@ static int da903x_backlight_probe(struct platform_device *pdev)
 				       &da903x_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		kfree(data);
 		return PTR_ERR(bl);
 	}
 
@@ -157,10 +155,8 @@ static int da903x_backlight_probe(struct platform_device *pdev)
 static int da903x_backlight_remove(struct platform_device *pdev)
 {
 	struct backlight_device *bl = platform_get_drvdata(pdev);
-	struct da903x_backlight_data *data = bl_get_data(bl);
 
 	backlight_device_unregister(bl);
-	kfree(data);
 	return 0;
 }
 
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 27d1d7a..6022b67 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -274,18 +274,7 @@ static struct spi_driver l4f00242t03_driver = {
 	.shutdown	= l4f00242t03_shutdown,
 };
 
-static __init int l4f00242t03_init(void)
-{
-	return spi_register_driver(&l4f00242t03_driver);
-}
-
-static __exit void l4f00242t03_exit(void)
-{
-	spi_unregister_driver(&l4f00242t03_driver);
-}
-
-module_init(l4f00242t03_init);
-module_exit(l4f00242t03_exit);
+module_spi_driver(l4f00242t03_driver);
 
 MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
 MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c
index 78dafc0..efd352b 100644
--- a/drivers/video/backlight/ld9040.c
+++ b/drivers/video/backlight/ld9040.c
@@ -856,18 +856,7 @@ static struct spi_driver ld9040_driver = {
 	.resume		= ld9040_resume,
 };
 
-static int __init ld9040_init(void)
-{
-	return spi_register_driver(&ld9040_driver);
-}
-
-static void __exit ld9040_exit(void)
-{
-	spi_unregister_driver(&ld9040_driver);
-}
-
-module_init(ld9040_init);
-module_exit(ld9040_exit);
+module_spi_driver(ld9040_driver);
 
 MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
 MODULE_DESCRIPTION("ld9040 LCD Driver");
diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c
index 4ec78cf..4161f9e 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -226,18 +226,7 @@ static struct spi_driver lms283gf05_driver = {
 	.remove		= __devexit_p(lms283gf05_remove),
 };
 
-static __init int lms283gf05_init(void)
-{
-	return spi_register_driver(&lms283gf05_driver);
-}
-
-static __exit void lms283gf05_exit(void)
-{
-	spi_unregister_driver(&lms283gf05_driver);
-}
-
-module_init(lms283gf05_init);
-module_exit(lms283gf05_exit);
+module_spi_driver(lms283gf05_driver);
 
 MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
 MODULE_DESCRIPTION("LCD283GF05 LCD");
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
new file mode 100644
index 0000000..d32c097
--- /dev/null
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -0,0 +1,322 @@
+/*
+ * TI LP855x Backlight Driver
+ *
+ *			Copyright (C) 2011 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/lp855x.h>
+
+/* Registers */
+#define BRIGHTNESS_CTRL		(0x00)
+#define DEVICE_CTRL		(0x01)
+
+#define BUF_SIZE		(20)
+#define DEFAULT_BL_NAME		"lcd-backlight"
+
+struct lp855x {
+	const char *chipid;
+	struct i2c_client *client;
+	struct backlight_device *bl;
+	struct device *dev;
+	struct mutex xfer_lock;
+	struct lp855x_platform_data *pdata;
+};
+
+static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
+{
+	int ret;
+
+	mutex_lock(&lp->xfer_lock);
+	ret = i2c_smbus_read_byte_data(lp->client, reg);
+	if (ret < 0) {
+		mutex_unlock(&lp->xfer_lock);
+		dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+		return ret;
+	}
+	mutex_unlock(&lp->xfer_lock);
+
+	*data = (u8)ret;
+	return 0;
+}
+
+static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
+{
+	int ret;
+
+	mutex_lock(&lp->xfer_lock);
+	ret = i2c_smbus_write_byte_data(lp->client, reg, data);
+	mutex_unlock(&lp->xfer_lock);
+
+	return ret;
+}
+
+static int lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
+{
+	const char *id = lp->chipid;
+	u8 start, end;
+
+	if (strstr(id, "lp8550") || strstr(id, "lp8551")
+	    || strstr(id, "lp8552") || strstr(id, "lp8553")) {
+		start = EEPROM_START;
+		end = EEPROM_END;
+	} else if (strstr(id, "lp8556")) {
+		start = EPROM_START;
+		end = EPROM_END;
+	}
+
+	return (addr >= start && addr <= end) ? 1 : 0;
+}
+
+static int lp855x_init_registers(struct lp855x *lp)
+{
+	u8 val, addr;
+	int i, ret;
+	struct lp855x_platform_data *pd = lp->pdata;
+
+	val = pd->initial_brightness;
+	ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+	if (ret)
+		return ret;
+
+	val = pd->device_control;
+	ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
+	if (ret)
+		return ret;
+
+	if (pd->load_new_rom_data && pd->size_program) {
+		for (i = 0; i < pd->size_program; i++) {
+			addr = pd->rom_data[i].addr;
+			val = pd->rom_data[i].val;
+			if (!lp855x_is_valid_rom_area(lp, addr))
+				continue;
+
+			ret = lp855x_write_byte(lp, addr, val);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int lp855x_bl_update_status(struct backlight_device *bl)
+{
+	struct lp855x *lp = bl_get_data(bl);
+	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		bl->props.brightness = 0;
+
+	if (mode == PWM_BASED) {
+		struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+		int br = bl->props.brightness;
+		int max_br = bl->props.max_brightness;
+
+		if (pd->pwm_set_intensity)
+			pd->pwm_set_intensity(br, max_br);
+
+	} else if (mode == REGISTER_BASED) {
+		u8 val = bl->props.brightness;
+		lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+	}
+
+	return 0;
+}
+
+static int lp855x_bl_get_brightness(struct backlight_device *bl)
+{
+	struct lp855x *lp = bl_get_data(bl);
+	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+	if (mode == PWM_BASED) {
+		struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+		int max_br = bl->props.max_brightness;
+
+		if (pd->pwm_get_intensity)
+			bl->props.brightness = pd->pwm_get_intensity(max_br);
+
+	} else if (mode == REGISTER_BASED) {
+		u8 val = 0;
+
+		lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
+		bl->props.brightness = val;
+	}
+
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops lp855x_bl_ops = {
+	.options = BL_CORE_SUSPENDRESUME,
+	.update_status = lp855x_bl_update_status,
+	.get_brightness = lp855x_bl_get_brightness,
+};
+
+static int lp855x_backlight_register(struct lp855x *lp)
+{
+	struct backlight_device *bl;
+	struct backlight_properties props;
+	struct lp855x_platform_data *pdata = lp->pdata;
+	char *name = pdata->name ? : DEFAULT_BL_NAME;
+
+	props.type = BACKLIGHT_PLATFORM;
+	props.brightness = pdata->initial_brightness;
+	props.max_brightness =
+		(pdata->max_brightness < pdata->initial_brightness) ?
+		255 : pdata->max_brightness;
+
+	bl = backlight_device_register(name, lp->dev, lp,
+				       &lp855x_bl_ops, &props);
+	if (IS_ERR(bl))
+		return PTR_ERR(bl);
+
+	lp->bl = bl;
+
+	return 0;
+}
+
+static void lp855x_backlight_unregister(struct lp855x *lp)
+{
+	if (lp->bl)
+		backlight_device_unregister(lp->bl);
+}
+
+static ssize_t lp855x_get_chip_id(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct lp855x *lp = dev_get_drvdata(dev);
+	return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipid);
+}
+
+static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct lp855x *lp = dev_get_drvdata(dev);
+	enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+	char *strmode = NULL;
+
+	if (mode == PWM_BASED)
+		strmode = "pwm based";
+	else if (mode == REGISTER_BASED)
+		strmode = "register based";
+
+	return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
+}
+
+static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
+static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
+
+static struct attribute *lp855x_attributes[] = {
+	&dev_attr_chip_id.attr,
+	&dev_attr_bl_ctl_mode.attr,
+	NULL,
+};
+
+static const struct attribute_group lp855x_attr_group = {
+	.attrs = lp855x_attributes,
+};
+
+static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+	struct lp855x *lp;
+	struct lp855x_platform_data *pdata = cl->dev.platform_data;
+	enum lp855x_brightness_ctrl_mode mode;
+	int ret;
+
+	if (!pdata) {
+		dev_err(&cl->dev, "no platform data supplied\n");
+		return -EINVAL;
+	}
+
+	if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+		return -EIO;
+
+	lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
+	if (!lp)
+		return -ENOMEM;
+
+	mode = pdata->mode;
+	lp->client = cl;
+	lp->dev = &cl->dev;
+	lp->pdata = pdata;
+	lp->chipid = id->name;
+	i2c_set_clientdata(cl, lp);
+
+	mutex_init(&lp->xfer_lock);
+
+	ret = lp855x_init_registers(lp);
+	if (ret) {
+		dev_err(lp->dev, "i2c communication err: %d", ret);
+		if (mode == REGISTER_BASED)
+			goto err_dev;
+	}
+
+	ret = lp855x_backlight_register(lp);
+	if (ret) {
+		dev_err(lp->dev,
+			"failed to register backlight. err: %d\n", ret);
+		goto err_dev;
+	}
+
+	ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
+	if (ret) {
+		dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
+		goto err_sysfs;
+	}
+
+	backlight_update_status(lp->bl);
+	return 0;
+
+err_sysfs:
+	lp855x_backlight_unregister(lp);
+err_dev:
+	return ret;
+}
+
+static int __devexit lp855x_remove(struct i2c_client *cl)
+{
+	struct lp855x *lp = i2c_get_clientdata(cl);
+
+	lp->bl->props.brightness = 0;
+	backlight_update_status(lp->bl);
+	sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
+	lp855x_backlight_unregister(lp);
+
+	return 0;
+}
+
+static const struct i2c_device_id lp855x_ids[] = {
+	{"lp8550", LP8550},
+	{"lp8551", LP8551},
+	{"lp8552", LP8552},
+	{"lp8553", LP8553},
+	{"lp8556", LP8556},
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lp855x_ids);
+
+static struct i2c_driver lp855x_driver = {
+	.driver = {
+		   .name = "lp855x",
+		   },
+	.probe = lp855x_probe,
+	.remove = __devexit_p(lp855x_remove),
+	.id_table = lp855x_ids,
+};
+
+module_i2c_driver(lp855x_driver);
+
+MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
+MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c
index cca43c0..333949f 100644
--- a/drivers/video/backlight/ltv350qv.c
+++ b/drivers/video/backlight/ltv350qv.c
@@ -321,17 +321,7 @@ static struct spi_driver ltv350qv_driver = {
 	.resume		= ltv350qv_resume,
 };
 
-static int __init ltv350qv_init(void)
-{
-	return spi_register_driver(&ltv350qv_driver);
-}
-
-static void __exit ltv350qv_exit(void)
-{
-	spi_unregister_driver(&ltv350qv_driver);
-}
-module_init(ltv350qv_init);
-module_exit(ltv350qv_exit);
+module_spi_driver(ltv350qv_driver);
 
 MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index c915e3b..e833ac7 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -129,7 +129,8 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	data = kzalloc(sizeof(struct max8925_backlight_data), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
+			    GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 	strncpy(name, res->name, MAX8925_NAME_SIZE);
@@ -143,7 +144,6 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
 					&max8925_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		kfree(data);
 		return PTR_ERR(bl);
 	}
 	bl->props.brightness = MAX_BRIGHTNESS;
@@ -165,17 +165,14 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
 	return 0;
 out:
 	backlight_device_unregister(bl);
-	kfree(data);
 	return ret;
 }
 
 static int __devexit max8925_backlight_remove(struct platform_device *pdev)
 {
 	struct backlight_device *bl = platform_get_drvdata(pdev);
-	struct max8925_backlight_data *data = bl_get_data(bl);
 
 	backlight_device_unregister(bl);
-	kfree(data);
 	return 0;
 }
 
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c
index d8cde27..0175bfb 100644
--- a/drivers/video/backlight/omap1_bl.c
+++ b/drivers/video/backlight/omap1_bl.c
@@ -141,7 +141,8 @@ static int omapbl_probe(struct platform_device *pdev)
 	if (!pdata)
 		return -ENXIO;
 
-	bl = kzalloc(sizeof(struct omap_backlight), GFP_KERNEL);
+	bl = devm_kzalloc(&pdev->dev, sizeof(struct omap_backlight),
+			  GFP_KERNEL);
 	if (unlikely(!bl))
 		return -ENOMEM;
 
@@ -150,10 +151,8 @@ static int omapbl_probe(struct platform_device *pdev)
 	props.max_brightness = OMAPBL_MAX_INTENSITY;
 	dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
 					&props);
-	if (IS_ERR(dev)) {
-		kfree(bl);
+	if (IS_ERR(dev))
 		return PTR_ERR(dev);
-	}
 
 	bl->powermode = FB_BLANK_POWERDOWN;
 	bl->current_intensity = 0;
@@ -177,10 +176,8 @@ static int omapbl_probe(struct platform_device *pdev)
 static int omapbl_remove(struct platform_device *pdev)
 {
 	struct backlight_device *dev = platform_get_drvdata(pdev);
-	struct omap_backlight *bl = dev_get_drvdata(&dev->dev);
 
 	backlight_device_unregister(dev);
-	kfree(bl);
 
 	return 0;
 }
diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c
new file mode 100644
index 0000000..f519d55
--- /dev/null
+++ b/drivers/video/backlight/ot200_bl.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 Bachmann electronic GmbH
+ *	Christian Gmeiner <christian.gmeiner@gmail.com>
+ *
+ * Backlight driver for ot200 visualisation device from
+ * Bachmann electronic GmbH.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/gpio.h>
+#include <linux/cs5535.h>
+
+static struct cs5535_mfgpt_timer *pwm_timer;
+
+/* this array defines the mapping of brightness in % to pwm frequency */
+static const u8 dim_table[101] = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+				  2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+				  4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,
+				  10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 16,
+				  17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28,
+				  30, 31, 33, 35, 37, 39, 41, 43, 45, 47, 50,
+				  53, 55, 58, 61, 65, 68, 72, 75, 79, 84, 88,
+				  93, 97, 103, 108, 114, 120, 126, 133, 140,
+				  147, 155, 163};
+
+struct ot200_backlight_data {
+	int current_brightness;
+};
+
+#define GPIO_DIMM	27
+#define SCALE		1
+#define CMP1MODE	0x2	/* compare on GE; output high on compare
+				 * greater than or equal */
+#define PWM_SETUP	(SCALE | CMP1MODE << 6 | MFGPT_SETUP_CNTEN)
+#define MAX_COMP2	163
+
+static int ot200_backlight_update_status(struct backlight_device *bl)
+{
+	struct ot200_backlight_data *data = bl_get_data(bl);
+	int brightness = bl->props.brightness;
+
+	if (bl->props.state & BL_CORE_FBBLANK)
+		brightness = 0;
+
+	/* enable or disable PWM timer */
+	if (brightness == 0)
+		cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, 0);
+	else if (data->current_brightness == 0) {
+		cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+		cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP,
+			MFGPT_SETUP_CNTEN);
+	}
+
+	/* apply new brightness value */
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+		MAX_COMP2 - dim_table[brightness]);
+	data->current_brightness = brightness;
+
+	return 0;
+}
+
+static int ot200_backlight_get_brightness(struct backlight_device *bl)
+{
+	struct ot200_backlight_data *data = bl_get_data(bl);
+	return data->current_brightness;
+}
+
+static const struct backlight_ops ot200_backlight_ops = {
+	.update_status	= ot200_backlight_update_status,
+	.get_brightness	= ot200_backlight_get_brightness,
+};
+
+static int ot200_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_device *bl;
+	struct ot200_backlight_data *data;
+	struct backlight_properties props;
+	int retval = 0;
+
+	/* request gpio */
+	if (gpio_request(GPIO_DIMM, "ot200 backlight dimmer") < 0) {
+		dev_err(&pdev->dev, "failed to request GPIO %d\n", GPIO_DIMM);
+		return -ENODEV;
+	}
+
+	/* request timer */
+	pwm_timer = cs5535_mfgpt_alloc_timer(7, MFGPT_DOMAIN_ANY);
+	if (!pwm_timer) {
+		dev_err(&pdev->dev, "MFGPT 7 not available\n");
+		retval = -ENODEV;
+		goto error_mfgpt_alloc;
+	}
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		retval = -ENOMEM;
+		goto error_kzalloc;
+	}
+
+	/* setup gpio */
+	cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_ENABLE);
+	cs5535_gpio_set(GPIO_DIMM, GPIO_OUTPUT_AUX1);
+
+	/* setup timer */
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1, 0);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP2, MAX_COMP2);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, PWM_SETUP);
+
+	data->current_brightness = 100;
+	props.max_brightness = 100;
+	props.brightness = 100;
+	props.type = BACKLIGHT_RAW;
+
+	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data,
+					&ot200_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		retval = PTR_ERR(bl);
+		goto error_backlight_device_register;
+	}
+
+	platform_set_drvdata(pdev, bl);
+
+	return 0;
+
+error_backlight_device_register:
+	kfree(data);
+error_kzalloc:
+	cs5535_mfgpt_free_timer(pwm_timer);
+error_mfgpt_alloc:
+	gpio_free(GPIO_DIMM);
+	return retval;
+}
+
+static int ot200_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	struct ot200_backlight_data *data = bl_get_data(bl);
+
+	backlight_device_unregister(bl);
+
+	/* on module unload set brightness to 100% */
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
+	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_CMP1,
+		MAX_COMP2 - dim_table[100]);
+
+	cs5535_mfgpt_free_timer(pwm_timer);
+	gpio_free(GPIO_DIMM);
+
+	kfree(data);
+	return 0;
+}
+
+static struct platform_driver ot200_backlight_driver = {
+	.driver		= {
+		.name	= "ot200-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ot200_backlight_probe,
+	.remove		= ot200_backlight_remove,
+};
+
+module_platform_driver(ot200_backlight_driver);
+
+MODULE_DESCRIPTION("backlight driver for ot200 visualisation device");
+MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ot200-backlight");
diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c
new file mode 100644
index 0000000..4ec3074
--- /dev/null
+++ b/drivers/video/backlight/pandora_bl.c
@@ -0,0 +1,171 @@
+/*
+ * Backlight driver for Pandora handheld.
+ * Pandora uses TWL4030 PWM0 -> TPS61161 combo for control backlight.
+ * Based on pwm_bl.c
+ *
+ * Copyright 2009,2012 Gražvydas Ignotas <notasas@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/i2c/twl.h>
+#include <linux/err.h>
+
+#define TWL_PWM0_ON		0x00
+#define TWL_PWM0_OFF		0x01
+
+#define TWL_INTBR_GPBR1		0x0c
+#define TWL_INTBR_PMBR1		0x0d
+
+#define TWL_PMBR1_PWM0_MUXMASK	0x0c
+#define TWL_PMBR1_PWM0		0x04
+#define PWM0_CLK_ENABLE		BIT(0)
+#define PWM0_ENABLE		BIT(2)
+
+/* range accepted by hardware */
+#define MIN_VALUE 9
+#define MAX_VALUE 63
+#define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE)
+
+#define PANDORABL_WAS_OFF BL_CORE_DRIVER1
+
+static int pandora_backlight_update_status(struct backlight_device *bl)
+{
+	int brightness = bl->props.brightness;
+	u8 r;
+
+	if (bl->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+	if (bl->props.state & BL_CORE_FBBLANK)
+		brightness = 0;
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	if ((unsigned int)brightness > MAX_USER_VALUE)
+		brightness = MAX_USER_VALUE;
+
+	if (brightness == 0) {
+		if (bl->props.state & PANDORABL_WAS_OFF)
+			goto done;
+
+		/* first disable PWM0 output, then clock */
+		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+		r &= ~PWM0_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+		r &= ~PWM0_CLK_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+		goto done;
+	}
+
+	if (bl->props.state & PANDORABL_WAS_OFF) {
+		/*
+		 * set PWM duty cycle to max. TPS61161 seems to use this
+		 * to calibrate it's PWM sensitivity when it starts.
+		 */
+		twl_i2c_write_u8(TWL4030_MODULE_PWM0, MAX_VALUE,
+					TWL_PWM0_OFF);
+
+		/* first enable clock, then PWM0 out */
+		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_GPBR1);
+		r &= ~PWM0_ENABLE;
+		r |= PWM0_CLK_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+		r |= PWM0_ENABLE;
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_GPBR1);
+
+		/*
+		 * TI made it very easy to enable digital control, so easy that
+		 * it often triggers unintentionally and disabes PWM control,
+		 * so wait until 1 wire mode detection window ends.
+		 */
+		usleep_range(2000, 10000);
+	}
+
+	twl_i2c_write_u8(TWL4030_MODULE_PWM0, MIN_VALUE + brightness,
+				TWL_PWM0_OFF);
+
+done:
+	if (brightness != 0)
+		bl->props.state &= ~PANDORABL_WAS_OFF;
+	else
+		bl->props.state |= PANDORABL_WAS_OFF;
+
+	return 0;
+}
+
+static int pandora_backlight_get_brightness(struct backlight_device *bl)
+{
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops pandora_backlight_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= pandora_backlight_update_status,
+	.get_brightness	= pandora_backlight_get_brightness,
+};
+
+static int pandora_backlight_probe(struct platform_device *pdev)
+{
+	struct backlight_properties props;
+	struct backlight_device *bl;
+	u8 r;
+
+	memset(&props, 0, sizeof(props));
+	props.max_brightness = MAX_USER_VALUE;
+	props.type = BACKLIGHT_RAW;
+	bl = backlight_device_register(pdev->name, &pdev->dev,
+			NULL, &pandora_backlight_ops, &props);
+	if (IS_ERR(bl)) {
+		dev_err(&pdev->dev, "failed to register backlight\n");
+		return PTR_ERR(bl);
+	}
+
+	platform_set_drvdata(pdev, bl);
+
+	/* 64 cycle period, ON position 0 */
+	twl_i2c_write_u8(TWL4030_MODULE_PWM0, 0x80, TWL_PWM0_ON);
+
+	bl->props.state |= PANDORABL_WAS_OFF;
+	bl->props.brightness = MAX_USER_VALUE;
+	backlight_update_status(bl);
+
+	/* enable PWM function in pin mux */
+	twl_i2c_read_u8(TWL4030_MODULE_INTBR, &r, TWL_INTBR_PMBR1);
+	r &= ~TWL_PMBR1_PWM0_MUXMASK;
+	r |= TWL_PMBR1_PWM0;
+	twl_i2c_write_u8(TWL4030_MODULE_INTBR, r, TWL_INTBR_PMBR1);
+
+	return 0;
+}
+
+static int pandora_backlight_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bl = platform_get_drvdata(pdev);
+	backlight_device_unregister(bl);
+	return 0;
+}
+
+static struct platform_driver pandora_backlight_driver = {
+	.driver		= {
+		.name	= "pandora-backlight",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pandora_backlight_probe,
+	.remove		= pandora_backlight_remove,
+};
+
+module_platform_driver(pandora_backlight_driver);
+
+MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("Pandora Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pandora-backlight");
diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c
index 13e88b7..c65853c 100644
--- a/drivers/video/backlight/pcf50633-backlight.c
+++ b/drivers/video/backlight/pcf50633-backlight.c
@@ -101,14 +101,13 @@ static const struct backlight_ops pcf50633_bl_ops = {
 
 static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
 {
-	int ret;
 	struct pcf50633_bl *pcf_bl;
 	struct device *parent = pdev->dev.parent;
 	struct pcf50633_platform_data *pcf50633_data = parent->platform_data;
 	struct pcf50633_bl_platform_data *pdata = pcf50633_data->backlight_data;
 	struct backlight_properties bl_props;
 
-	pcf_bl = kzalloc(sizeof(*pcf_bl), GFP_KERNEL);
+	pcf_bl = devm_kzalloc(&pdev->dev, sizeof(*pcf_bl), GFP_KERNEL);
 	if (!pcf_bl)
 		return -ENOMEM;
 
@@ -129,10 +128,8 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
 	pcf_bl->bl = backlight_device_register(pdev->name, &pdev->dev, pcf_bl,
 						&pcf50633_bl_ops, &bl_props);
 
-	if (IS_ERR(pcf_bl->bl)) {
-		ret = PTR_ERR(pcf_bl->bl);
-		goto err_free;
-	}
+	if (IS_ERR(pcf_bl->bl))
+		return PTR_ERR(pcf_bl->bl);
 
 	platform_set_drvdata(pdev, pcf_bl);
 
@@ -145,11 +142,6 @@ static int __devinit pcf50633_bl_probe(struct platform_device *pdev)
 	backlight_update_status(pcf_bl->bl);
 
 	return 0;
-
-err_free:
-	kfree(pcf_bl);
-
-	return ret;
 }
 
 static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
@@ -160,8 +152,6 @@ static int __devexit pcf50633_bl_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 
-	kfree(pcf_bl);
-
 	return 0;
 }
 
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 7496d04..342b7d7 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -102,7 +102,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 			return ret;
 	}
 
-	pb = kzalloc(sizeof(*pb), GFP_KERNEL);
+	pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
 	if (!pb) {
 		dev_err(&pdev->dev, "no memory for state\n");
 		ret = -ENOMEM;
@@ -121,7 +121,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 	if (IS_ERR(pb->pwm)) {
 		dev_err(&pdev->dev, "unable to request PWM for backlight\n");
 		ret = PTR_ERR(pb->pwm);
-		goto err_pwm;
+		goto err_alloc;
 	} else
 		dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
@@ -144,8 +144,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
 err_bl:
 	pwm_free(pb->pwm);
-err_pwm:
-	kfree(pb);
 err_alloc:
 	if (data->exit)
 		data->exit(&pdev->dev);
@@ -162,7 +160,6 @@ static int pwm_backlight_remove(struct platform_device *pdev)
 	pwm_config(pb->pwm, 0, pb->period);
 	pwm_disable(pb->pwm);
 	pwm_free(pb->pwm);
-	kfree(pb);
 	if (data->exit)
 		data->exit(&pdev->dev);
 	return 0;
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
index e132157..9b0092e 100644
--- a/drivers/video/backlight/s6e63m0.c
+++ b/drivers/video/backlight/s6e63m0.c
@@ -909,18 +909,7 @@ static struct spi_driver s6e63m0_driver = {
 	.resume		= s6e63m0_resume,
 };
 
-static int __init s6e63m0_init(void)
-{
-	return spi_register_driver(&s6e63m0_driver);
-}
-
-static void __exit s6e63m0_exit(void)
-{
-	spi_unregister_driver(&s6e63m0_driver);
-}
-
-module_init(s6e63m0_init);
-module_exit(s6e63m0_exit);
+module_spi_driver(s6e63m0_driver);
 
 MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
 MODULE_DESCRIPTION("S6E63M0 LCD Driver");
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c
index 1997e12..2368b8e 100644
--- a/drivers/video/backlight/tdo24m.c
+++ b/drivers/video/backlight/tdo24m.c
@@ -459,17 +459,7 @@ static struct spi_driver tdo24m_driver = {
 	.resume		= tdo24m_resume,
 };
 
-static int __init tdo24m_init(void)
-{
-	return spi_register_driver(&tdo24m_driver);
-}
-module_init(tdo24m_init);
-
-static void __exit tdo24m_exit(void)
-{
-	spi_unregister_driver(&tdo24m_driver);
-}
-module_exit(tdo24m_exit);
+module_spi_driver(tdo24m_driver);
 
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
 MODULE_DESCRIPTION("Driver for Toppoly TDO24M LCD Panel");
diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
index 425a736..2b241ab 100644
--- a/drivers/video/backlight/tosa_bl.c
+++ b/drivers/video/backlight/tosa_bl.c
@@ -181,18 +181,7 @@ static struct i2c_driver tosa_bl_driver = {
 	.id_table	= tosa_bl_id,
 };
 
-static int __init tosa_bl_init(void)
-{
-	return i2c_add_driver(&tosa_bl_driver);
-}
-
-static void __exit tosa_bl_exit(void)
-{
-	i2c_del_driver(&tosa_bl_driver);
-}
-
-module_init(tosa_bl_init);
-module_exit(tosa_bl_exit);
+module_i2c_driver(tosa_bl_driver);
 
 MODULE_AUTHOR("Dmitry Baryshkov");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c
index 772f601..a2161f6 100644
--- a/drivers/video/backlight/tosa_lcd.c
+++ b/drivers/video/backlight/tosa_lcd.c
@@ -285,18 +285,7 @@ static struct spi_driver tosa_lcd_driver = {
 	.resume		= tosa_lcd_resume,
 };
 
-static int __init tosa_lcd_init(void)
-{
-	return spi_register_driver(&tosa_lcd_driver);
-}
-
-static void __exit tosa_lcd_exit(void)
-{
-	spi_unregister_driver(&tosa_lcd_driver);
-}
-
-module_init(tosa_lcd_init);
-module_exit(tosa_lcd_exit);
+module_spi_driver(tosa_lcd_driver);
 
 MODULE_AUTHOR("Dmitry Baryshkov");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
index b49063c..b617fae 100644
--- a/drivers/video/backlight/vgg2432a4.c
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -262,20 +262,7 @@ static struct spi_driver vgg2432a4_driver = {
 	.resume		= vgg2432a4_resume,
 };
 
-/* Device driver initialisation */
-
-static int __init vgg2432a4_init(void)
-{
-	return spi_register_driver(&vgg2432a4_driver);
-}
-
-static void __exit vgg2432a4_exit(void)
-{
-	spi_unregister_driver(&vgg2432a4_driver);
-}
-
-module_init(vgg2432a4_init);
-module_exit(vgg2432a4_exit);
+module_spi_driver(vgg2432a4_driver);
 
 MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
 MODULE_DESCRIPTION("VGG2432A4 LCD Driver");
diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c
index 4e915f5..5d365de 100644
--- a/drivers/video/backlight/wm831x_bl.c
+++ b/drivers/video/backlight/wm831x_bl.c
@@ -186,7 +186,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
@@ -200,7 +200,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
 				       &wm831x_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		kfree(data);
 		return PTR_ERR(bl);
 	}
 
@@ -211,7 +210,6 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
 	/* Disable the DCDC if it was started so we can bootstrap */
 	wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, WM831X_DC4_ENA, 0);
 
-
 	backlight_update_status(bl);
 
 	return 0;
@@ -220,10 +218,8 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
 static int wm831x_backlight_remove(struct platform_device *pdev)
 {
 	struct backlight_device *bl = platform_get_drvdata(pdev);
-	struct wm831x_backlight_data *data = bl_get_data(bl);
 
 	backlight_device_unregister(bl);
-	kfree(data);
 	return 0;
 }
 
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c
index bea53c1..befbc80 100644
--- a/drivers/video/bf537-lq035.c
+++ b/drivers/video/bf537-lq035.c
@@ -383,23 +383,19 @@ static int __devinit request_ports(void)
 	}
 
 #if (defined(UD) && defined(LBR))
-	if (gpio_request(UD, KBUILD_MODNAME)) {
+	if (gpio_request_one(UD, GPIOF_OUT_INIT_LOW, KBUILD_MODNAME)) {
 		pr_err("requesting GPIO %d failed\n", UD);
 		return -EBUSY;
 	}
 
-	if (gpio_request(LBR, KBUILD_MODNAME)) {
+	if (gpio_request_one(LBR, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) {
 		pr_err("requesting GPIO %d failed\n", LBR);
 		gpio_free(UD);
 		return -EBUSY;
 	}
-
-	gpio_direction_output(UD, 0);
-	gpio_direction_output(LBR, 1);
-
 #endif
 
-	if (gpio_request(MOD, KBUILD_MODNAME)) {
+	if (gpio_request_one(MOD, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) {
 		pr_err("requesting GPIO %d failed\n", MOD);
 #if (defined(UD) && defined(LBR))
 		gpio_free(LBR);
@@ -408,8 +404,6 @@ static int __devinit request_ports(void)
 		return -EBUSY;
 	}
 
-	gpio_direction_output(MOD, 1);
-
 	SSYNC();
 	return 0;
 }
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 46b03f5..dc2f004 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -240,7 +240,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi)
 	u16 eppi_req_18[] = EPPI0_18;
 	u16 disp = fbi->mach_info->disp;
 
-	if (gpio_request(disp, DRIVER_NAME)) {
+	if (gpio_request_one(disp, GPIOF_OUT_INIT_HIGH, DRIVER_NAME)) {
 		printk(KERN_ERR "Requesting GPIO %d failed\n", disp);
 		return -EFAULT;
 	}
@@ -263,8 +263,6 @@ static int request_ports(struct bfin_bf54xfb_info *fbi)
 		}
 	}
 
-	gpio_direction_output(disp, 1);
-
 	return 0;
 }
 
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index c633068..86922ac 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -365,10 +365,10 @@ static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev,
 	 * Drive PPI_FS3 Low
 	 */
 	if (ANOMALY_05000400) {
-		int ret = gpio_request(P_IDENT(P_PPI0_FS3), "PPI_FS3");
+		int ret = gpio_request_one(P_IDENT(P_PPI0_FS3),
+					GPIOF_OUT_INIT_LOW, "PPI_FS3");
 		if (ret)
 			return ret;
-		gpio_direction_output(P_IDENT(P_PPI0_FS3), 0);
 	}
 
 	if (ppi16)
@@ -716,14 +716,14 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev)
 	}
 
 	if (info->disp_info->use_bl) {
-		ret = gpio_request(info->disp_info->gpio_bl, "LQ035 Backlight");
+		ret = gpio_request_one(info->disp_info->gpio_bl,
+					GPIOF_OUT_INIT_LOW, "LQ035 Backlight");
 
 		if (ret) {
 			dev_err(&pdev->dev, "failed to request GPIO %d\n",
 				info->disp_info->gpio_bl);
 			goto out9;
 		}
-		gpio_direction_output(info->disp_info->gpio_bl, 0);
 	}
 
 	ret = register_framebuffer(fbinfo);
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c
index 811dd7f..c992814 100644
--- a/drivers/video/bfin_adv7393fb.c
+++ b/drivers/video/bfin_adv7393fb.c
@@ -411,12 +411,13 @@ static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client,
 
 	/* Workaround "PPI Does Not Start Properly In Specific Mode" */
 	if (ANOMALY_05000400) {
-		if (gpio_request(P_IDENT(P_PPI0_FS3), "PPI0_FS3")) {
+		ret = gpio_request_one(P_IDENT(P_PPI0_FS3), GPIOF_OUT_INIT_LOW,
+					"PPI0_FS3")
+		if (ret) {
 			dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n");
 			ret = -EBUSY;
 			goto out_8;
 		}
-		gpio_direction_output(P_IDENT(P_PPI0_FS3), 0);
 	}
 
 	if (peripheral_request_list(ppi_pins, DRIVER_NAME)) {
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 29577bf..dd80386 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -32,6 +32,7 @@
 #include <linux/console.h>
 #include <linux/slab.h>
 #include <video/da8xx-fb.h>
+#include <asm/div64.h>
 
 #define DRIVER_NAME "da8xx_lcdc"
 
@@ -161,6 +162,7 @@ struct da8xx_fb_par {
 	int			vsync_timeout;
 #ifdef CONFIG_CPU_FREQ
 	struct notifier_block	freq_transition;
+	unsigned int		lcd_fck_rate;
 #endif
 	void (*panel_power_ctrl)(int);
 };
@@ -174,7 +176,6 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
 	.activate = 0,
 	.height = -1,
 	.width = -1,
-	.pixclock = 46666,	/* 46us - AUO display */
 	.accel_flags = 0,
 	.left_margin = LEFT_MARGIN,
 	.right_margin = RIGHT_MARGIN,
@@ -840,11 +841,13 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
 	struct da8xx_fb_par *par;
 
 	par = container_of(nb, struct da8xx_fb_par, freq_transition);
-	if (val == CPUFREQ_PRECHANGE) {
-		lcd_disable_raster();
-	} else if (val == CPUFREQ_POSTCHANGE) {
-		lcd_calc_clk_divider(par);
-		lcd_enable_raster();
+	if (val == CPUFREQ_POSTCHANGE) {
+		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
+			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
+			lcd_disable_raster();
+			lcd_calc_clk_divider(par);
+			lcd_enable_raster();
+		}
 	}
 
 	return 0;
@@ -1048,6 +1051,22 @@ static struct fb_ops da8xx_fb_ops = {
 	.fb_blank = cfb_blank,
 };
 
+/* Calculate and return pixel clock period in pico seconds */
+static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
+{
+	unsigned int lcd_clk, div;
+	unsigned int configured_pix_clk;
+	unsigned long long pix_clk_period_picosec = 1000000000000ULL;
+
+	lcd_clk = clk_get_rate(par->lcdc_clk);
+	div = lcd_clk / par->pxl_clk;
+	configured_pix_clk = (lcd_clk / div);
+
+	do_div(pix_clk_period_picosec, configured_pix_clk);
+
+	return pix_clk_period_picosec;
+}
+
 static int __devinit fb_probe(struct platform_device *device)
 {
 	struct da8xx_lcdc_platform_data *fb_pdata =
@@ -1137,6 +1156,9 @@ static int __devinit fb_probe(struct platform_device *device)
 
 	par = da8xx_fb_info->par;
 	par->lcdc_clk = fb_clk;
+#ifdef CONFIG_CPU_FREQ
+	par->lcd_fck_rate = clk_get_rate(fb_clk);
+#endif
 	par->pxl_clk = lcdc_info->pxl_clk;
 	if (fb_pdata->panel_power_ctrl) {
 		par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
@@ -1209,6 +1231,7 @@ static int __devinit fb_probe(struct platform_device *device)
 
 	da8xx_fb_var.hsync_len = lcdc_info->hsw;
 	da8xx_fb_var.vsync_len = lcdc_info->vsw;
+	da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
 
 	/* Initialize fbinfo */
 	da8xx_fb_info->flags = FBINFO_FLAG_DEFAULT;
@@ -1264,8 +1287,8 @@ static int __devinit fb_probe(struct platform_device *device)
 irq_freq:
 #ifdef CONFIG_CPU_FREQ
 	lcd_da8xx_cpufreq_deregister(par);
-#endif
 err_cpu_freq:
+#endif
 	unregister_framebuffer(da8xx_fb_info);
 
 err_dealloc_cmap:
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
new file mode 100644
index 0000000..1b035b2
--- /dev/null
+++ b/drivers/video/exynos/Kconfig
@@ -0,0 +1,37 @@
+#
+# Exynos Video configuration
+#
+
+menuconfig EXYNOS_VIDEO
+	bool "Exynos Video driver support"
+	help
+	  This enables support for EXYNOS Video device.
+
+if EXYNOS_VIDEO
+
+#
+# MIPI DSI driver
+#
+
+config EXYNOS_MIPI_DSI
+	bool "EXYNOS MIPI DSI driver support."
+	depends on ARCH_S5PV210 || ARCH_EXYNOS
+	help
+	  This enables support for MIPI-DSI device.
+
+config EXYNOS_LCD_S6E8AX0
+	bool "S6E8AX0 MIPI AMOLED LCD Driver"
+	depends on (EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE)
+	default n
+	help
+	  If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its
+	  LCD control driver.
+
+config EXYNOS_DP
+	bool "EXYNOS DP driver support"
+	depends on ARCH_EXYNOS
+	default n
+	help
+	  This enables support for DP device.
+
+endif # EXYNOS_VIDEO
diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile
new file mode 100644
index 0000000..ec7772e
--- /dev/null
+++ b/drivers/video/exynos/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the exynos video drivers.
+#
+
+obj-$(CONFIG_EXYNOS_MIPI_DSI)		+= exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
+				     	exynos_mipi_dsi_lowlevel.o
+obj-$(CONFIG_EXYNOS_LCD_S6E8AX0)	+= s6e8ax0.o
+obj-$(CONFIG_EXYNOS_DP)			+= exynos_dp_core.o exynos_dp_reg.o
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
new file mode 100644
index 0000000..2a4481c
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -0,0 +1,1058 @@
+/*
+ * Samsung SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <video/exynos_dp.h>
+
+#include <plat/cpu.h>
+
+#include "exynos_dp_core.h"
+
+static int exynos_dp_init_dp(struct exynos_dp_device *dp)
+{
+	exynos_dp_reset(dp);
+
+	/* SW defined function Normal operation */
+	exynos_dp_enable_sw_function(dp);
+
+	exynos_dp_config_interrupt(dp);
+	exynos_dp_init_analog_func(dp);
+
+	exynos_dp_init_hpd(dp);
+	exynos_dp_init_aux(dp);
+
+	return 0;
+}
+
+static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
+{
+	int timeout_loop = 0;
+
+	exynos_dp_init_hpd(dp);
+
+	udelay(200);
+
+	while (exynos_dp_get_plug_in_status(dp) != 0) {
+		timeout_loop++;
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "failed to get hpd plug status\n");
+			return -ETIMEDOUT;
+		}
+		udelay(10);
+	}
+
+	return 0;
+}
+
+static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
+{
+	int i;
+	unsigned char sum = 0;
+
+	for (i = 0; i < EDID_BLOCK_LENGTH; i++)
+		sum = sum + edid_data[i];
+
+	return sum;
+}
+
+static int exynos_dp_read_edid(struct exynos_dp_device *dp)
+{
+	unsigned char edid[EDID_BLOCK_LENGTH * 2];
+	unsigned int extend_block = 0;
+	unsigned char sum;
+	unsigned char test_vector;
+	int retval;
+
+	/*
+	 * EDID device address is 0x50.
+	 * However, if necessary, you must have set upper address
+	 * into E-EDID in I2C device, 0x30.
+	 */
+
+	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
+	exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+				EDID_EXTENSION_FLAG,
+				&extend_block);
+
+	if (extend_block > 0) {
+		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
+
+		/* Read EDID data */
+		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+						EDID_HEADER_PATTERN,
+						EDID_BLOCK_LENGTH,
+						&edid[EDID_HEADER_PATTERN]);
+		if (retval != 0) {
+			dev_err(dp->dev, "EDID Read failed!\n");
+			return -EIO;
+		}
+		sum = exynos_dp_calc_edid_check_sum(edid);
+		if (sum != 0) {
+			dev_err(dp->dev, "EDID bad checksum!\n");
+			return -EIO;
+		}
+
+		/* Read additional EDID data */
+		retval = exynos_dp_read_bytes_from_i2c(dp,
+				I2C_EDID_DEVICE_ADDR,
+				EDID_BLOCK_LENGTH,
+				EDID_BLOCK_LENGTH,
+				&edid[EDID_BLOCK_LENGTH]);
+		if (retval != 0) {
+			dev_err(dp->dev, "EDID Read failed!\n");
+			return -EIO;
+		}
+		sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]);
+		if (sum != 0) {
+			dev_err(dp->dev, "EDID bad checksum!\n");
+			return -EIO;
+		}
+
+		exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST,
+					&test_vector);
+		if (test_vector & DPCD_TEST_EDID_READ) {
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_EDID_CHECKSUM,
+				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_RESPONSE,
+				DPCD_TEST_EDID_CHECKSUM_WRITE);
+		}
+	} else {
+		dev_info(dp->dev, "EDID data does not include any extensions.\n");
+
+		/* Read EDID data */
+		retval = exynos_dp_read_bytes_from_i2c(dp,
+				I2C_EDID_DEVICE_ADDR,
+				EDID_HEADER_PATTERN,
+				EDID_BLOCK_LENGTH,
+				&edid[EDID_HEADER_PATTERN]);
+		if (retval != 0) {
+			dev_err(dp->dev, "EDID Read failed!\n");
+			return -EIO;
+		}
+		sum = exynos_dp_calc_edid_check_sum(edid);
+		if (sum != 0) {
+			dev_err(dp->dev, "EDID bad checksum!\n");
+			return -EIO;
+		}
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_TEST_REQUEST,
+			&test_vector);
+		if (test_vector & DPCD_TEST_EDID_READ) {
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_EDID_CHECKSUM,
+				edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TEST_RESPONSE,
+				DPCD_TEST_EDID_CHECKSUM_WRITE);
+		}
+	}
+
+	dev_err(dp->dev, "EDID Read success!\n");
+	return 0;
+}
+
+static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
+{
+	u8 buf[12];
+	int i;
+	int retval;
+
+	/* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */
+	exynos_dp_read_bytes_from_dpcd(dp,
+		DPCD_ADDR_DPCD_REV,
+		12, buf);
+
+	/* Read EDID */
+	for (i = 0; i < 3; i++) {
+		retval = exynos_dp_read_edid(dp);
+		if (retval == 0)
+			break;
+	}
+
+	return retval;
+}
+
+static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
+						bool enable)
+{
+	u8 data;
+
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data);
+
+	if (enable)
+		exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
+			DPCD_ENHANCED_FRAME_EN |
+			DPCD_LANE_COUNT_SET(data));
+	else
+		exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET,
+			DPCD_LANE_COUNT_SET(data));
+}
+
+static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
+{
+	u8 data;
+	int retval;
+
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
+	retval = DPCD_ENHANCED_FRAME_CAP(data);
+
+	return retval;
+}
+
+static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp)
+{
+	u8 data;
+
+	data = exynos_dp_is_enhanced_mode_available(dp);
+	exynos_dp_enable_rx_to_enhanced_mode(dp, data);
+	exynos_dp_enable_enhanced_mode(dp, data);
+}
+
+static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
+{
+	exynos_dp_set_training_pattern(dp, DP_NONE);
+
+	exynos_dp_write_byte_to_dpcd(dp,
+		DPCD_ADDR_TRAINING_PATTERN_SET,
+		DPCD_TRAINING_PATTERN_DISABLED);
+}
+
+static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
+					int pre_emphasis, int lane)
+{
+	switch (lane) {
+	case 0:
+		exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis);
+		break;
+	case 1:
+		exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis);
+		break;
+
+	case 2:
+		exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis);
+		break;
+
+	case 3:
+		exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis);
+		break;
+	}
+}
+
+static void exynos_dp_link_start(struct exynos_dp_device *dp)
+{
+	u8 buf[5];
+	int lane;
+	int lane_count;
+
+	lane_count = dp->link_train.lane_count;
+
+	dp->link_train.lt_state = CLOCK_RECOVERY;
+	dp->link_train.eq_loop = 0;
+
+	for (lane = 0; lane < lane_count; lane++)
+		dp->link_train.cr_loop[lane] = 0;
+
+	/* Set sink to D0 (Sink Not Ready) mode. */
+	exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
+				DPCD_SET_POWER_STATE_D0);
+
+	/* Set link rate and count as you want to establish*/
+	exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
+	exynos_dp_set_lane_count(dp, dp->link_train.lane_count);
+
+	/* Setup RX configuration */
+	buf[0] = dp->link_train.link_rate;
+	buf[1] = dp->link_train.lane_count;
+	exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
+				2, buf);
+
+	/* Set TX pre-emphasis to minimum */
+	for (lane = 0; lane < lane_count; lane++)
+		exynos_dp_set_lane_lane_pre_emphasis(dp,
+			PRE_EMPHASIS_LEVEL_0, lane);
+
+	/* Set training pattern 1 */
+	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
+
+	/* Set RX training pattern */
+	buf[0] = DPCD_SCRAMBLING_DISABLED |
+		 DPCD_TRAINING_PATTERN_1;
+	exynos_dp_write_byte_to_dpcd(dp,
+		DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
+
+	for (lane = 0; lane < lane_count; lane++)
+		buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
+			    DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
+	exynos_dp_write_bytes_to_dpcd(dp,
+		DPCD_ADDR_TRAINING_PATTERN_SET,
+		lane_count, buf);
+}
+
+static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
+{
+	int shift = (lane & 1) * 4;
+	u8 link_value = link_status[lane>>1];
+
+	return (link_value >> shift) & 0xf;
+}
+
+static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
+{
+	int lane;
+	u8 lane_status;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = exynos_dp_get_lane_status(link_status, lane);
+		if ((lane_status & DPCD_LANE_CR_DONE) == 0)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
+{
+	int lane;
+	u8 lane_align;
+	u8 lane_status;
+
+	lane_align = link_status[2];
+	if ((lane_align == DPCD_INTERLANE_ALIGN_DONE) == 0)
+		return -EINVAL;
+
+	for (lane = 0; lane < lane_count; lane++) {
+		lane_status = exynos_dp_get_lane_status(link_status, lane);
+		lane_status &= DPCD_CHANNEL_EQ_BITS;
+		if (lane_status != DPCD_CHANNEL_EQ_BITS)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
+							int lane)
+{
+	int shift = (lane & 1) * 4;
+	u8 link_value = adjust_request[lane>>1];
+
+	return (link_value >> shift) & 0x3;
+}
+
+static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
+					u8 adjust_request[2],
+					int lane)
+{
+	int shift = (lane & 1) * 4;
+	u8 link_value = adjust_request[lane>>1];
+
+	return ((link_value >> shift) & 0xc) >> 2;
+}
+
+static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
+					u8 training_lane_set, int lane)
+{
+	switch (lane) {
+	case 0:
+		exynos_dp_set_lane0_link_training(dp, training_lane_set);
+		break;
+	case 1:
+		exynos_dp_set_lane1_link_training(dp, training_lane_set);
+		break;
+
+	case 2:
+		exynos_dp_set_lane2_link_training(dp, training_lane_set);
+		break;
+
+	case 3:
+		exynos_dp_set_lane3_link_training(dp, training_lane_set);
+		break;
+	}
+}
+
+static unsigned int exynos_dp_get_lane_link_training(
+				struct exynos_dp_device *dp,
+				int lane)
+{
+	u32 reg;
+
+	switch (lane) {
+	case 0:
+		reg = exynos_dp_get_lane0_link_training(dp);
+		break;
+	case 1:
+		reg = exynos_dp_get_lane1_link_training(dp);
+		break;
+	case 2:
+		reg = exynos_dp_get_lane2_link_training(dp);
+		break;
+	case 3:
+		reg = exynos_dp_get_lane3_link_training(dp);
+		break;
+	}
+
+	return reg;
+}
+
+static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
+{
+	if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) {
+		/* set to reduced bit rate */
+		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
+		dev_err(dp->dev, "set to bandwidth %.2x\n",
+			dp->link_train.link_rate);
+		dp->link_train.lt_state = START;
+	} else {
+		exynos_dp_training_pattern_dis(dp);
+		/* set enhanced mode if available */
+		exynos_dp_set_enhanced_mode(dp);
+		dp->link_train.lt_state = FAILED;
+	}
+}
+
+static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
+				u8 adjust_request[2])
+{
+	int lane;
+	int lane_count;
+	u8 voltage_swing;
+	u8 pre_emphasis;
+	u8 training_lane;
+
+	lane_count = dp->link_train.lane_count;
+	for (lane = 0; lane < lane_count; lane++) {
+		voltage_swing = exynos_dp_get_adjust_request_voltage(
+						adjust_request, lane);
+		pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+						adjust_request, lane);
+		training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+				DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+		if (voltage_swing == VOLTAGE_LEVEL_3 ||
+		   pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+			training_lane |= DPCD_MAX_SWING_REACHED;
+			training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+		}
+		dp->link_train.training_lane[lane] = training_lane;
+	}
+}
+
+static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
+					u8 voltage_swing)
+{
+	int lane;
+	int lane_count;
+
+	lane_count = dp->link_train.lane_count;
+	for (lane = 0; lane < lane_count; lane++) {
+		if (voltage_swing == VOLTAGE_LEVEL_3 ||
+			dp->link_train.cr_loop[lane] == MAX_CR_LOOP)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
+{
+	u8 data;
+	u8 link_status[6];
+	int lane;
+	int lane_count;
+	u8 buf[5];
+
+	u8 *adjust_request;
+	u8 voltage_swing;
+	u8 pre_emphasis;
+	u8 training_lane;
+
+	udelay(100);
+
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				6, link_status);
+	lane_count = dp->link_train.lane_count;
+
+	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
+		/* set training pattern 2 for EQ */
+		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
+
+		adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
+						- DPCD_ADDR_LANE0_1_STATUS);
+
+		exynos_dp_get_adjust_train(dp, adjust_request);
+
+		buf[0] = DPCD_SCRAMBLING_DISABLED |
+			 DPCD_TRAINING_PATTERN_2;
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_LANE0_SET,
+			buf[0]);
+
+		for (lane = 0; lane < lane_count; lane++) {
+			exynos_dp_set_lane_link_training(dp,
+				dp->link_train.training_lane[lane],
+				lane);
+			buf[lane] = dp->link_train.training_lane[lane];
+			exynos_dp_write_byte_to_dpcd(dp,
+				DPCD_ADDR_TRAINING_LANE0_SET + lane,
+				buf[lane]);
+		}
+		dp->link_train.lt_state = EQUALIZER_TRAINING;
+	} else {
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+			&data);
+		adjust_request[0] = data;
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
+			&data);
+		adjust_request[1] = data;
+
+		for (lane = 0; lane < lane_count; lane++) {
+			training_lane = exynos_dp_get_lane_link_training(
+							dp, lane);
+			voltage_swing = exynos_dp_get_adjust_request_voltage(
+							adjust_request, lane);
+			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+							adjust_request, lane);
+			if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
+			    (DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
+				dp->link_train.cr_loop[lane]++;
+			dp->link_train.training_lane[lane] = training_lane;
+		}
+
+		if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
+			exynos_dp_reduce_link_rate(dp);
+		} else {
+			exynos_dp_get_adjust_train(dp, adjust_request);
+
+			for (lane = 0; lane < lane_count; lane++) {
+				exynos_dp_set_lane_link_training(dp,
+					dp->link_train.training_lane[lane],
+					lane);
+				buf[lane] = dp->link_train.training_lane[lane];
+				exynos_dp_write_byte_to_dpcd(dp,
+					DPCD_ADDR_TRAINING_LANE0_SET + lane,
+					buf[lane]);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
+{
+	u8 link_status[6];
+	int lane;
+	int lane_count;
+	u8 buf[5];
+	u32 reg;
+
+	u8 *adjust_request;
+
+	udelay(400);
+
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				6, link_status);
+	lane_count = dp->link_train.lane_count;
+
+	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
+		adjust_request = link_status + (DPCD_ADDR_ADJUST_REQUEST_LANE0_1
+						- DPCD_ADDR_LANE0_1_STATUS);
+
+		if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
+			/* traing pattern Set to Normal */
+			exynos_dp_training_pattern_dis(dp);
+
+			dev_info(dp->dev, "Link Training success!\n");
+
+			exynos_dp_get_link_bandwidth(dp, &reg);
+			dp->link_train.link_rate = reg;
+			dev_dbg(dp->dev, "final bandwidth = %.2x\n",
+				dp->link_train.link_rate);
+
+			exynos_dp_get_lane_count(dp, &reg);
+			dp->link_train.lane_count = reg;
+			dev_dbg(dp->dev, "final lane count = %.2x\n",
+				dp->link_train.lane_count);
+			/* set enhanced mode if available */
+			exynos_dp_set_enhanced_mode(dp);
+
+			dp->link_train.lt_state = FINISHED;
+		} else {
+			/* not all locked */
+			dp->link_train.eq_loop++;
+
+			if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
+				exynos_dp_reduce_link_rate(dp);
+			} else {
+				exynos_dp_get_adjust_train(dp, adjust_request);
+
+				for (lane = 0; lane < lane_count; lane++) {
+					exynos_dp_set_lane_link_training(dp,
+						dp->link_train.training_lane[lane],
+						lane);
+					buf[lane] = dp->link_train.training_lane[lane];
+					exynos_dp_write_byte_to_dpcd(dp,
+						DPCD_ADDR_TRAINING_LANE0_SET + lane,
+						buf[lane]);
+				}
+			}
+		}
+	} else {
+		exynos_dp_reduce_link_rate(dp);
+	}
+
+	return 0;
+}
+
+static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
+			u8 *bandwidth)
+{
+	u8 data;
+
+	/*
+	 * For DP rev.1.1, Maximum link rate of Main Link lanes
+	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
+	 */
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data);
+	*bandwidth = data;
+}
+
+static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
+			u8 *lane_count)
+{
+	u8 data;
+
+	/*
+	 * For DP rev.1.1, Maximum number of Main Link lanes
+	 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes
+	 */
+	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data);
+	*lane_count = DPCD_MAX_LANE_COUNT(data);
+}
+
+static void exynos_dp_init_training(struct exynos_dp_device *dp,
+			enum link_lane_count_type max_lane,
+			enum link_rate_type max_rate)
+{
+	/*
+	 * MACRO_RST must be applied after the PLL_LOCK to avoid
+	 * the DP inter pair skew issue for at least 10 us
+	 */
+	exynos_dp_reset_macro(dp);
+
+	/* Initialize by reading RX's DPCD */
+	exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
+	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
+
+	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
+	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
+			dp->link_train.link_rate);
+		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
+	}
+
+	if (dp->link_train.lane_count == 0) {
+		dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n",
+			dp->link_train.lane_count);
+		dp->link_train.lane_count = (u8)LANE_COUNT1;
+	}
+
+	/* Setup TX lane count & rate */
+	if (dp->link_train.lane_count > max_lane)
+		dp->link_train.lane_count = max_lane;
+	if (dp->link_train.link_rate > max_rate)
+		dp->link_train.link_rate = max_rate;
+
+	/* All DP analog module power up */
+	exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
+}
+
+static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
+{
+	int retval = 0;
+	int training_finished;
+
+	/* Turn off unnecessary lane */
+	if (dp->link_train.lane_count == 1)
+		exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
+
+	training_finished = 0;
+
+	dp->link_train.lt_state = START;
+
+	/* Process here */
+	while (!training_finished) {
+		switch (dp->link_train.lt_state) {
+		case START:
+			exynos_dp_link_start(dp);
+			break;
+		case CLOCK_RECOVERY:
+			exynos_dp_process_clock_recovery(dp);
+			break;
+		case EQUALIZER_TRAINING:
+			exynos_dp_process_equalizer_training(dp);
+			break;
+		case FINISHED:
+			training_finished = 1;
+			break;
+		case FAILED:
+			return -EREMOTEIO;
+		}
+	}
+
+	return retval;
+}
+
+static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
+				u32 count,
+				u32 bwtype)
+{
+	int i;
+	int retval;
+
+	for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) {
+		exynos_dp_init_training(dp, count, bwtype);
+		retval = exynos_dp_sw_link_training(dp);
+		if (retval == 0)
+			break;
+
+		udelay(100);
+	}
+
+	return retval;
+}
+
+static int exynos_dp_config_video(struct exynos_dp_device *dp,
+			struct video_info *video_info)
+{
+	int retval = 0;
+	int timeout_loop = 0;
+	int done_count = 0;
+
+	exynos_dp_config_video_slave_mode(dp, video_info);
+
+	exynos_dp_set_video_color_format(dp, video_info->color_depth,
+			video_info->color_space,
+			video_info->dynamic_range,
+			video_info->ycbcr_coeff);
+
+	if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
+		dev_err(dp->dev, "PLL is not locked yet.\n");
+		return -EINVAL;
+	}
+
+	for (;;) {
+		timeout_loop++;
+		if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0)
+			break;
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "Timeout of video streamclk ok\n");
+			return -ETIMEDOUT;
+		}
+
+		mdelay(100);
+	}
+
+	/* Set to use the register calculated M/N video */
+	exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);
+
+	/* For video bist, Video timing must be generated by register */
+	exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE);
+
+	/* Disable video mute */
+	exynos_dp_enable_video_mute(dp, 0);
+
+	/* Configure video slave mode */
+	exynos_dp_enable_video_master(dp, 0);
+
+	/* Enable video */
+	exynos_dp_start_video(dp);
+
+	timeout_loop = 0;
+
+	for (;;) {
+		timeout_loop++;
+		if (exynos_dp_is_video_stream_on(dp) == 0) {
+			done_count++;
+			if (done_count > 10)
+				break;
+		} else if (done_count) {
+			done_count = 0;
+		}
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "Timeout of video streamclk ok\n");
+			return -ETIMEDOUT;
+		}
+
+		mdelay(100);
+	}
+
+	if (retval != 0)
+		dev_err(dp->dev, "Video stream is not detected!\n");
+
+	return retval;
+}
+
+static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
+{
+	u8 data;
+
+	if (enable) {
+		exynos_dp_enable_scrambling(dp);
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			&data);
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			(u8)(data & ~DPCD_SCRAMBLING_DISABLED));
+	} else {
+		exynos_dp_disable_scrambling(dp);
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			&data);
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			(u8)(data | DPCD_SCRAMBLING_DISABLED));
+	}
+}
+
+static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
+{
+	struct exynos_dp_device *dp = arg;
+
+	dev_err(dp->dev, "exynos_dp_irq_handler\n");
+	return IRQ_HANDLED;
+}
+
+static int __devinit exynos_dp_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct exynos_dp_device *dp;
+	struct exynos_dp_platdata *pdata;
+
+	int ret = 0;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -EINVAL;
+	}
+
+	dp = kzalloc(sizeof(struct exynos_dp_device), GFP_KERNEL);
+	if (!dp) {
+		dev_err(&pdev->dev, "no memory for device data\n");
+		return -ENOMEM;
+	}
+
+	dp->dev = &pdev->dev;
+
+	dp->clock = clk_get(&pdev->dev, "dp");
+	if (IS_ERR(dp->clock)) {
+		dev_err(&pdev->dev, "failed to get clock\n");
+		ret = PTR_ERR(dp->clock);
+		goto err_dp;
+	}
+
+	clk_enable(dp->clock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get registers\n");
+		ret = -EINVAL;
+		goto err_clock;
+	}
+
+	res = request_mem_region(res->start, resource_size(res),
+				dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request registers region\n");
+		ret = -EINVAL;
+		goto err_clock;
+	}
+
+	dp->res = res;
+
+	dp->reg_base = ioremap(res->start, resource_size(res));
+	if (!dp->reg_base) {
+		dev_err(&pdev->dev, "failed to ioremap\n");
+		ret = -ENOMEM;
+		goto err_req_region;
+	}
+
+	dp->irq = platform_get_irq(pdev, 0);
+	if (!dp->irq) {
+		dev_err(&pdev->dev, "failed to get irq\n");
+		ret = -ENODEV;
+		goto err_ioremap;
+	}
+
+	ret = request_irq(dp->irq, exynos_dp_irq_handler, 0,
+			"exynos-dp", dp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		goto err_ioremap;
+	}
+
+	dp->video_info = pdata->video_info;
+	if (pdata->phy_init)
+		pdata->phy_init();
+
+	exynos_dp_init_dp(dp);
+
+	ret = exynos_dp_detect_hpd(dp);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to detect hpd\n");
+		goto err_irq;
+	}
+
+	exynos_dp_handle_edid(dp);
+
+	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
+				dp->video_info->link_rate);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to do link train\n");
+		goto err_irq;
+	}
+
+	exynos_dp_enable_scramble(dp, 1);
+	exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
+	exynos_dp_enable_enhanced_mode(dp, 1);
+
+	exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
+	exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+
+	exynos_dp_init_video(dp);
+	ret = exynos_dp_config_video(dp, dp->video_info);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to config video\n");
+		goto err_irq;
+	}
+
+	platform_set_drvdata(pdev, dp);
+
+	return 0;
+
+err_irq:
+	free_irq(dp->irq, dp);
+err_ioremap:
+	iounmap(dp->reg_base);
+err_req_region:
+	release_mem_region(res->start, resource_size(res));
+err_clock:
+	clk_put(dp->clock);
+err_dp:
+	kfree(dp);
+
+	return ret;
+}
+
+static int __devexit exynos_dp_remove(struct platform_device *pdev)
+{
+	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
+	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+
+	if (pdata && pdata->phy_exit)
+		pdata->phy_exit();
+
+	free_irq(dp->irq, dp);
+	iounmap(dp->reg_base);
+
+	clk_disable(dp->clock);
+	clk_put(dp->clock);
+
+	release_mem_region(dp->res->start, resource_size(dp->res));
+
+	kfree(dp);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_dp_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
+	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+
+	if (pdata && pdata->phy_exit)
+		pdata->phy_exit();
+
+	clk_disable(dp->clock);
+
+	return 0;
+}
+
+static int exynos_dp_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
+	struct exynos_dp_device *dp = platform_get_drvdata(pdev);
+
+	if (pdata && pdata->phy_init)
+		pdata->phy_init();
+
+	clk_enable(dp->clock);
+
+	exynos_dp_init_dp(dp);
+
+	exynos_dp_detect_hpd(dp);
+	exynos_dp_handle_edid(dp);
+
+	exynos_dp_set_link_train(dp, dp->video_info->lane_count,
+				dp->video_info->link_rate);
+
+	exynos_dp_enable_scramble(dp, 1);
+	exynos_dp_enable_rx_to_enhanced_mode(dp, 1);
+	exynos_dp_enable_enhanced_mode(dp, 1);
+
+	exynos_dp_set_lane_count(dp, dp->video_info->lane_count);
+	exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
+
+	exynos_dp_init_video(dp);
+	exynos_dp_config_video(dp, dp->video_info);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops exynos_dp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
+};
+
+static struct platform_driver exynos_dp_driver = {
+	.probe		= exynos_dp_probe,
+	.remove		= __devexit_p(exynos_dp_remove),
+	.driver		= {
+		.name	= "exynos-dp",
+		.owner	= THIS_MODULE,
+		.pm	= &exynos_dp_pm_ops,
+	},
+};
+
+module_platform_driver(exynos_dp_driver);
+
+MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+MODULE_DESCRIPTION("Samsung SoC DP Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
new file mode 100644
index 0000000..90ceaca
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -0,0 +1,206 @@
+/*
+ * Header file for Samsung DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef _EXYNOS_DP_CORE_H
+#define _EXYNOS_DP_CORE_H
+
+struct link_train {
+	int eq_loop;
+	int cr_loop[4];
+
+	u8 link_rate;
+	u8 lane_count;
+	u8 training_lane[4];
+
+	enum link_training_state lt_state;
+};
+
+struct exynos_dp_device {
+	struct device		*dev;
+	struct resource		*res;
+	struct clk		*clock;
+	unsigned int		irq;
+	void __iomem		*reg_base;
+
+	struct video_info	*video_info;
+	struct link_train	link_train;
+};
+
+/* exynos_dp_reg.c */
+void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_stop_video(struct exynos_dp_device *dp);
+void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_init_interrupt(struct exynos_dp_device *dp);
+void exynos_dp_reset(struct exynos_dp_device *dp);
+void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
+u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
+void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
+				enum analog_power_block block,
+				bool enable);
+void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
+void exynos_dp_init_hpd(struct exynos_dp_device *dp);
+void exynos_dp_reset_aux(struct exynos_dp_device *dp);
+void exynos_dp_init_aux(struct exynos_dp_device *dp);
+int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
+void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
+int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
+int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char data);
+int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char *data);
+int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[]);
+int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[]);
+int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr);
+int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int *data);
+int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char edid[]);
+void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
+void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
+void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
+void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
+void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
+void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
+void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
+void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
+void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
+				 enum pattern_set pattern);
+void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
+void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
+				u32 training_lane);
+u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
+u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
+u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
+u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
+void exynos_dp_reset_macro(struct exynos_dp_device *dp);
+int exynos_dp_init_video(struct exynos_dp_device *dp);
+
+void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
+				u32 color_depth,
+				u32 color_space,
+				u32 dynamic_range,
+				u32 ycbcr_coeff);
+int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
+void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
+			enum clock_recovery_m_value_type type,
+			u32 m_value,
+			u32 n_value);
+void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
+void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
+void exynos_dp_start_video(struct exynos_dp_device *dp);
+int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp);
+void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
+			struct video_info *video_info);
+void exynos_dp_enable_scrambling(struct exynos_dp_device *dp);
+void exynos_dp_disable_scrambling(struct exynos_dp_device *dp);
+
+/* I2C EDID Chip ID, Slave Address */
+#define I2C_EDID_DEVICE_ADDR			0x50
+#define I2C_E_EDID_DEVICE_ADDR			0x30
+
+#define EDID_BLOCK_LENGTH			0x80
+#define EDID_HEADER_PATTERN			0x00
+#define EDID_EXTENSION_FLAG			0x7e
+#define EDID_CHECKSUM				0x7f
+
+/* Definition for DPCD Register */
+#define DPCD_ADDR_DPCD_REV			0x0000
+#define DPCD_ADDR_MAX_LINK_RATE			0x0001
+#define DPCD_ADDR_MAX_LANE_COUNT		0x0002
+#define DPCD_ADDR_LINK_BW_SET			0x0100
+#define DPCD_ADDR_LANE_COUNT_SET		0x0101
+#define DPCD_ADDR_TRAINING_PATTERN_SET		0x0102
+#define DPCD_ADDR_TRAINING_LANE0_SET		0x0103
+#define DPCD_ADDR_LANE0_1_STATUS		0x0202
+#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED	0x0204
+#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1	0x0206
+#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3	0x0207
+#define DPCD_ADDR_TEST_REQUEST			0x0218
+#define DPCD_ADDR_TEST_RESPONSE			0x0260
+#define DPCD_ADDR_TEST_EDID_CHECKSUM		0x0261
+#define DPCD_ADDR_SINK_POWER_STATE		0x0600
+
+/* DPCD_ADDR_MAX_LANE_COUNT */
+#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1)
+#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f)
+
+/* DPCD_ADDR_LANE_COUNT_SET */
+#define DPCD_ENHANCED_FRAME_EN			(0x1 << 7)
+#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f)
+
+/* DPCD_ADDR_TRAINING_PATTERN_SET */
+#define DPCD_SCRAMBLING_DISABLED		(0x1 << 5)
+#define DPCD_SCRAMBLING_ENABLED			(0x0 << 5)
+#define DPCD_TRAINING_PATTERN_2			(0x2 << 0)
+#define DPCD_TRAINING_PATTERN_1			(0x1 << 0)
+#define DPCD_TRAINING_PATTERN_DISABLED		(0x0 << 0)
+
+/* DPCD_ADDR_TRAINING_LANE0_SET */
+#define DPCD_MAX_PRE_EMPHASIS_REACHED		(0x1 << 5)
+#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3)
+#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3)
+#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0	(0x0 << 3)
+#define DPCD_MAX_SWING_REACHED			(0x1 << 2)
+#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0)
+#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3)
+#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0	(0x0 << 0)
+
+/* DPCD_ADDR_LANE0_1_STATUS */
+#define DPCD_LANE_SYMBOL_LOCKED			(0x1 << 2)
+#define DPCD_LANE_CHANNEL_EQ_DONE		(0x1 << 1)
+#define DPCD_LANE_CR_DONE			(0x1 << 0)
+#define DPCD_CHANNEL_EQ_BITS			(DPCD_LANE_CR_DONE|	\
+						 DPCD_LANE_CHANNEL_EQ_DONE|\
+						 DPCD_LANE_SYMBOL_LOCKED)
+
+/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */
+#define DPCD_LINK_STATUS_UPDATED		(0x1 << 7)
+#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED	(0x1 << 6)
+#define DPCD_INTERLANE_ALIGN_DONE		(0x1 << 0)
+
+/* DPCD_ADDR_TEST_REQUEST */
+#define DPCD_TEST_EDID_READ			(0x1 << 2)
+
+/* DPCD_ADDR_TEST_RESPONSE */
+#define DPCD_TEST_EDID_CHECKSUM_WRITE		(0x1 << 2)
+
+/* DPCD_ADDR_SINK_POWER_STATE */
+#define DPCD_SET_POWER_STATE_D0			(0x1 << 0)
+#define DPCD_SET_POWER_STATE_D4			(0x2 << 0)
+
+#endif /* _EXYNOS_DP_CORE_H */
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
new file mode 100644
index 0000000..6548afa
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -0,0 +1,1173 @@
+/*
+ * Samsung DP (Display port) register interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <video/exynos_dp.h>
+
+#include <plat/cpu.h>
+
+#include "exynos_dp_core.h"
+#include "exynos_dp_reg.h"
+
+#define COMMON_INT_MASK_1 (0)
+#define COMMON_INT_MASK_2 (0)
+#define COMMON_INT_MASK_3 (0)
+#define COMMON_INT_MASK_4 (0)
+#define INT_STA_MASK (0)
+
+void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+		reg |= HDCP_VIDEO_MUTE;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+		reg &= ~HDCP_VIDEO_MUTE;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	}
+}
+
+void exynos_dp_stop_video(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	reg &= ~VIDEO_EN;
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+}
+
+void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable)
+		reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
+			LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
+	else
+		reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
+			LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
+
+	writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP);
+}
+
+void exynos_dp_init_interrupt(struct exynos_dp_device *dp)
+{
+	/* Set interrupt pin assertion polarity as high */
+	writel(INT_POL, dp->reg_base + EXYNOS_DP_INT_CTL);
+
+	/* Clear pending regisers */
+	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
+	writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2);
+	writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3);
+	writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
+	writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	/* 0:mask,1: unmask */
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
+	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
+	writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
+}
+
+void exynos_dp_reset(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET);
+
+	exynos_dp_stop_video(dp);
+	exynos_dp_enable_video_mute(dp, 0);
+
+	reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+		AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+		HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+
+	reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
+		SERDES_FIFO_FUNC_EN_N |
+		LS_CLK_DOMAIN_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+
+	udelay(20);
+
+	exynos_dp_lane_swap(dp, 0);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+	writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL);
+	writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL);
+
+	writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L);
+	writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H);
+
+	writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST);
+
+	writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD);
+	writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN);
+
+	writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH);
+	writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
+
+	writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+
+	exynos_dp_init_interrupt(dp);
+}
+
+void exynos_dp_config_interrupt(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	/* 0: mask, 1: unmask */
+	reg = COMMON_INT_MASK_1;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1);
+
+	reg = COMMON_INT_MASK_2;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2);
+
+	reg = COMMON_INT_MASK_3;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3);
+
+	reg = COMMON_INT_MASK_4;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4);
+
+	reg = INT_STA_MASK;
+	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
+}
+
+u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
+	if (reg & PLL_LOCK)
+		return PLL_LOCKED;
+	else
+		return PLL_UNLOCKED;
+}
+
+void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
+		reg |= DP_PLL_PD;
+		writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL);
+		reg &= ~DP_PLL_PD;
+		writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL);
+	}
+}
+
+void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
+				enum analog_power_block block,
+				bool enable)
+{
+	u32 reg;
+
+	switch (block) {
+	case AUX_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= AUX_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~AUX_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH0_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH0_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH0_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH1_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH1_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH1_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH2_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH2_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH2_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case CH3_BLOCK:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= CH3_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~CH3_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case ANALOG_TOTAL:
+		if (enable) {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg |= DP_PHY_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD);
+			reg &= ~DP_PHY_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	case POWER_ALL:
+		if (enable) {
+			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
+				CH1_PD | CH0_PD;
+			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD);
+		} else {
+			writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+void exynos_dp_init_analog_func(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	exynos_dp_set_analog_power_down(dp, POWER_ALL, 0);
+
+	reg = PLL_LOCK_CHG;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL);
+	reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
+	writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL);
+
+	/* Power up PLL */
+	if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED)
+		exynos_dp_set_pll_power_down(dp, 0);
+
+	/* Enable Serdes FIFO function and Link symbol clock domain module */
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+	reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
+		| AUX_FUNC_EN_N);
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+}
+
+void exynos_dp_init_hpd(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = HOTPLUG_CHG | HPD_LOST | PLUG;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4);
+
+	reg = INT_HPD;
+	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	reg &= ~(F_HPD | HPD_CTRL);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+}
+
+void exynos_dp_reset_aux(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	/* Disable AUX channel module */
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+	reg |= AUX_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+}
+
+void exynos_dp_init_aux(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	/* Clear inerrupts related to AUX channel */
+	reg = RPLY_RECEIV | AUX_ERR;
+	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	exynos_dp_reset_aux(dp);
+
+	/* Disable AUX transaction H/W retry */
+	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
+		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ;
+
+	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
+	reg = DEFER_CTRL_EN | DEFER_COUNT(1);
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL);
+
+	/* Enable AUX channel module */
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+	reg &= ~AUX_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
+}
+
+int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	if (reg & HPD_STATUS)
+		return 0;
+
+	return -EINVAL;
+}
+
+void exynos_dp_enable_sw_function(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+	reg &= ~SW_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+}
+
+int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
+{
+	int reg;
+	int retval = 0;
+
+	/* Enable AUX CH operation */
+	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+	reg |= AUX_EN;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+
+	/* Is AUX CH command reply received? */
+	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+	while (!(reg & RPLY_RECEIV))
+		reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+
+	/* Clear interrupt source for AUX CH command reply */
+	writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
+
+	/* Clear interrupt source for AUX CH access error */
+	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+	if (reg & AUX_ERR) {
+		writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA);
+		return -EREMOTEIO;
+	}
+
+	/* Check AUX CH error access status */
+	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA);
+	if ((reg & AUX_STATUS_MASK) != 0) {
+		dev_err(dp->dev, "AUX CH error happens: %d\n\n",
+			reg & AUX_STATUS_MASK);
+		return -EREMOTEIO;
+	}
+
+	return retval;
+}
+
+int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char data)
+{
+	u32 reg;
+	int i;
+	int retval;
+
+	for (i = 0; i < 3; i++) {
+		/* Clear AUX CH data buffer */
+		reg = BUF_CLR;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+		/* Select DPCD device address */
+		reg = AUX_ADDR_7_0(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+		reg = AUX_ADDR_15_8(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+		reg = AUX_ADDR_19_16(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+		/* Write data buffer */
+		reg = (unsigned int)data;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+
+		/*
+		 * Set DisplayPort transaction and write 1 byte
+		 * If bit 3 is 1, DisplayPort transaction.
+		 * If Bit 3 is 0, I2C transaction.
+		 */
+		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+		/* Start AUX transaction */
+		retval = exynos_dp_start_aux_transaction(dp);
+		if (retval == 0)
+			break;
+		else
+			dev_err(dp->dev, "Aux Transaction fail!\n");
+	}
+
+	return retval;
+}
+
+int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned char *data)
+{
+	u32 reg;
+	int i;
+	int retval;
+
+	for (i = 0; i < 10; i++) {
+		/* Clear AUX CH data buffer */
+		reg = BUF_CLR;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+		/* Select DPCD device address */
+		reg = AUX_ADDR_7_0(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+		reg = AUX_ADDR_15_8(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+		reg = AUX_ADDR_19_16(reg_addr);
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+		/*
+		 * Set DisplayPort transaction and read 1 byte
+		 * If bit 3 is 1, DisplayPort transaction.
+		 * If Bit 3 is 0, I2C transaction.
+		 */
+		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+		/* Start AUX transaction */
+		retval = exynos_dp_start_aux_transaction(dp);
+		if (retval == 0)
+			break;
+		else
+			dev_err(dp->dev, "Aux Transaction fail!\n");
+	}
+
+	/* Read data buffer */
+	reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+	*data = (unsigned char)(reg & 0xff);
+
+	return retval;
+}
+
+int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[])
+{
+	u32 reg;
+	unsigned int start_offset;
+	unsigned int cur_data_count;
+	unsigned int cur_data_idx;
+	int i;
+	int retval = 0;
+
+	/* Clear AUX CH data buffer */
+	reg = BUF_CLR;
+	writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+	start_offset = 0;
+	while (start_offset < count) {
+		/* Buffer size of AUX CH is 16 * 4bytes */
+		if ((count - start_offset) > 16)
+			cur_data_count = 16;
+		else
+			cur_data_count = count - start_offset;
+
+		for (i = 0; i < 10; i++) {
+			/* Select DPCD device address */
+			reg = AUX_ADDR_7_0(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+			reg = AUX_ADDR_15_8(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+			reg = AUX_ADDR_19_16(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+			for (cur_data_idx = 0; cur_data_idx < cur_data_count;
+			     cur_data_idx++) {
+				reg = data[start_offset + cur_data_idx];
+				writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0
+							  + 4 * cur_data_idx);
+			}
+
+			/*
+			 * Set DisplayPort transaction and write
+			 * If bit 3 is 1, DisplayPort transaction.
+			 * If Bit 3 is 0, I2C transaction.
+			 */
+			reg = AUX_LENGTH(cur_data_count) |
+				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+			/* Start AUX transaction */
+			retval = exynos_dp_start_aux_transaction(dp);
+			if (retval == 0)
+				break;
+			else
+				dev_err(dp->dev, "Aux Transaction fail!\n");
+		}
+
+		start_offset += cur_data_count;
+	}
+
+	return retval;
+}
+
+int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char data[])
+{
+	u32 reg;
+	unsigned int start_offset;
+	unsigned int cur_data_count;
+	unsigned int cur_data_idx;
+	int i;
+	int retval = 0;
+
+	/* Clear AUX CH data buffer */
+	reg = BUF_CLR;
+	writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+	start_offset = 0;
+	while (start_offset < count) {
+		/* Buffer size of AUX CH is 16 * 4bytes */
+		if ((count - start_offset) > 16)
+			cur_data_count = 16;
+		else
+			cur_data_count = count - start_offset;
+
+		/* AUX CH Request Transaction process */
+		for (i = 0; i < 10; i++) {
+			/* Select DPCD device address */
+			reg = AUX_ADDR_7_0(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+			reg = AUX_ADDR_15_8(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+			reg = AUX_ADDR_19_16(reg_addr + start_offset);
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+			/*
+			 * Set DisplayPort transaction and read
+			 * If bit 3 is 1, DisplayPort transaction.
+			 * If Bit 3 is 0, I2C transaction.
+			 */
+			reg = AUX_LENGTH(cur_data_count) |
+				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ;
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+			/* Start AUX transaction */
+			retval = exynos_dp_start_aux_transaction(dp);
+			if (retval == 0)
+				break;
+			else
+				dev_err(dp->dev, "Aux Transaction fail!\n");
+		}
+
+		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
+		    cur_data_idx++) {
+			reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
+						 + 4 * cur_data_idx);
+			data[start_offset + cur_data_idx] =
+				(unsigned char)reg;
+		}
+
+		start_offset += cur_data_count;
+	}
+
+	return retval;
+}
+
+int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr)
+{
+	u32 reg;
+	int retval;
+
+	/* Set EDID device address */
+	reg = device_addr;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0);
+	writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8);
+	writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16);
+
+	/* Set offset from base address of EDID device */
+	writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+
+	/*
+	 * Set I2C transaction and write address
+	 * If bit 3 is 1, DisplayPort transaction.
+	 * If Bit 3 is 0, I2C transaction.
+	 */
+	reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT |
+		AUX_TX_COMM_WRITE;
+	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+	/* Start AUX transaction */
+	retval = exynos_dp_start_aux_transaction(dp);
+	if (retval != 0)
+		dev_err(dp->dev, "Aux Transaction fail!\n");
+
+	return retval;
+}
+
+int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int *data)
+{
+	u32 reg;
+	int i;
+	int retval;
+
+	for (i = 0; i < 10; i++) {
+		/* Clear AUX CH data buffer */
+		reg = BUF_CLR;
+		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+		/* Select EDID device */
+		retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr);
+		if (retval != 0) {
+			dev_err(dp->dev, "Select EDID device fail!\n");
+			continue;
+		}
+
+		/*
+		 * Set I2C transaction and read data
+		 * If bit 3 is 1, DisplayPort transaction.
+		 * If Bit 3 is 0, I2C transaction.
+		 */
+		reg = AUX_TX_COMM_I2C_TRANSACTION |
+			AUX_TX_COMM_READ;
+		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1);
+
+		/* Start AUX transaction */
+		retval = exynos_dp_start_aux_transaction(dp);
+		if (retval == 0)
+			break;
+		else
+			dev_err(dp->dev, "Aux Transaction fail!\n");
+	}
+
+	/* Read data */
+	if (retval == 0)
+		*data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0);
+
+	return retval;
+}
+
+int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
+				unsigned int device_addr,
+				unsigned int reg_addr,
+				unsigned int count,
+				unsigned char edid[])
+{
+	u32 reg;
+	unsigned int i, j;
+	unsigned int cur_data_idx;
+	unsigned int defer = 0;
+	int retval = 0;
+
+	for (i = 0; i < count; i += 16) {
+		for (j = 0; j < 100; j++) {
+			/* Clear AUX CH data buffer */
+			reg = BUF_CLR;
+			writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL);
+
+			/* Set normal AUX CH command */
+			reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+			reg &= ~ADDR_ONLY;
+			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
+
+			/*
+			 * If Rx sends defer, Tx sends only reads
+			 * request without sending addres
+			 */
+			if (!defer)
+				retval = exynos_dp_select_i2c_device(dp,
+						device_addr, reg_addr + i);
+			else
+				defer = 0;
+
+			if (retval == 0) {
+				/*
+				 * Set I2C transaction and write data
+				 * If bit 3 is 1, DisplayPort transaction.
+				 * If Bit 3 is 0, I2C transaction.
+				 */
+				reg = AUX_LENGTH(16) |
+					AUX_TX_COMM_I2C_TRANSACTION |
+					AUX_TX_COMM_READ;
+				writel(reg, dp->reg_base +
+					EXYNOS_DP_AUX_CH_CTL_1);
+
+				/* Start AUX transaction */
+				retval = exynos_dp_start_aux_transaction(dp);
+				if (retval == 0)
+					break;
+				else
+					dev_err(dp->dev, "Aux Transaction fail!\n");
+			}
+			/* Check if Rx sends defer */
+			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
+			if (reg == AUX_RX_COMM_AUX_DEFER ||
+				reg == AUX_RX_COMM_I2C_DEFER) {
+				dev_err(dp->dev, "Defer: %d\n\n", reg);
+				defer = 1;
+			}
+		}
+
+		for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) {
+			reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0
+						 + 4 * cur_data_idx);
+			edid[i + cur_data_idx] = (unsigned char)reg;
+		}
+	}
+
+	return retval;
+}
+
+void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype)
+{
+	u32 reg;
+
+	reg = bwtype;
+	if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS))
+		writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET);
+}
+
+void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET);
+	*bwtype = reg;
+}
+
+void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count)
+{
+	u32 reg;
+
+	reg = count;
+	writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
+}
+
+void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET);
+	*count = reg;
+}
+
+void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg |= ENHANCED;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg &= ~ENHANCED;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+	}
+}
+
+void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
+				 enum pattern_set pattern)
+{
+	u32 reg;
+
+	switch (pattern) {
+	case PRBS7:
+		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case D10_2:
+		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case TRAINING_PTN1:
+		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case TRAINING_PTN2:
+		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	case DP_NONE:
+		reg = SCRAMBLING_ENABLE |
+			LINK_QUAL_PATTERN_SET_DISABLE |
+			SW_TRAINING_PATTERN_SET_NORMAL;
+		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+		break;
+	default:
+		break;
+	}
+}
+
+void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
+{
+	u32 reg;
+
+	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+}
+
+void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
+					u32 training_lane)
+{
+	u32 reg;
+
+	reg = training_lane;
+	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+}
+
+u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+	return reg;
+}
+
+u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+	return reg;
+}
+
+u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+	return reg;
+}
+
+u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+	return reg;
+}
+
+void exynos_dp_reset_macro(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST);
+	reg |= MACRO_RST;
+	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
+
+	/* 10 us is the minimum reset time. */
+	udelay(10);
+
+	reg &= ~MACRO_RST;
+	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
+}
+
+int exynos_dp_init_video(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
+	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1);
+
+	reg = 0x0;
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+
+	reg = CHA_CRI(4) | CHA_CTRL;
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+
+	reg = 0x0;
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+
+	reg = VID_HRES_TH(2) | VID_VRES_TH(0);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
+
+	return 0;
+}
+
+void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
+			u32 color_depth,
+			u32 color_space,
+			u32 dynamic_range,
+			u32 ycbcr_coeff)
+{
+	u32 reg;
+
+	/* Configure the input color depth, color space, dynamic range */
+	reg = (dynamic_range << IN_D_RANGE_SHIFT) |
+		(color_depth << IN_BPC_SHIFT) |
+		(color_space << IN_COLOR_F_SHIFT);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2);
+
+	/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
+	reg &= ~IN_YC_COEFFI_MASK;
+	if (ycbcr_coeff)
+		reg |= IN_YC_COEFFI_ITU709;
+	else
+		reg |= IN_YC_COEFFI_ITU601;
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3);
+}
+
+int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1);
+
+	if (!(reg & DET_STA)) {
+		dev_dbg(dp->dev, "Input stream clock not detected.\n");
+		return -EINVAL;
+	}
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2);
+	dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
+
+	if (reg & CHA_STA) {
+		dev_dbg(dp->dev, "Input stream clk is changing\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
+		enum clock_recovery_m_value_type type,
+		u32 m_value,
+		u32 n_value)
+{
+	u32 reg;
+
+	if (type == REGISTER_M) {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg |= FIX_M_VID;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg = m_value & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0);
+		reg = (m_value >> 8) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1);
+		reg = (m_value >> 16) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2);
+
+		reg = n_value & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0);
+		reg = (n_value >> 8) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1);
+		reg = (n_value >> 16) & 0xff;
+		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2);
+	} else  {
+		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+		reg &= ~FIX_M_VID;
+		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4);
+
+		writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0);
+		writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1);
+		writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2);
+	}
+}
+
+void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type)
+{
+	u32 reg;
+
+	if (type == VIDEO_TIMING_FROM_CAPTURE) {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+		reg &= ~FORMAT_SEL;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+		reg |= FORMAT_SEL;
+		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	}
+}
+
+void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable)
+{
+	u32 reg;
+
+	if (enable) {
+		reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+		reg &= ~VIDEO_MODE_MASK;
+		reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
+		writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+	} else {
+		reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+		reg &= ~VIDEO_MODE_MASK;
+		reg |= VIDEO_MODE_SLAVE_MODE;
+		writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+	}
+}
+
+void exynos_dp_start_video(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+	reg |= VIDEO_EN;
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1);
+}
+
+int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3);
+	if (!(reg & STRM_VALID)) {
+		dev_dbg(dp->dev, "Input video stream is not detected.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp,
+			struct video_info *video_info)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+	reg |= MASTER_VID_FUNC_EN_N;
+	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	reg &= ~INTERACE_SCAN_CFG;
+	reg |= (video_info->interlaced << 2);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	reg &= ~VSYNC_POLARITY_CFG;
+	reg |= (video_info->v_sync_polarity << 1);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+
+	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+	reg &= ~HSYNC_POLARITY_CFG;
+	reg |= (video_info->h_sync_polarity << 0);
+	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10);
+
+	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
+	writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
+}
+
+void exynos_dp_enable_scrambling(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+	reg &= ~SCRAMBLING_DISABLE;
+	writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+}
+
+void exynos_dp_disable_scrambling(struct exynos_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+	reg |= SCRAMBLING_DISABLE;
+	writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET);
+}
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
new file mode 100644
index 0000000..42f608e
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -0,0 +1,335 @@
+/*
+ * Register definition file for Samsung DP driver
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _EXYNOS_DP_REG_H
+#define _EXYNOS_DP_REG_H
+
+#define EXYNOS_DP_TX_SW_RESET			0x14
+#define EXYNOS_DP_FUNC_EN_1			0x18
+#define EXYNOS_DP_FUNC_EN_2			0x1C
+#define EXYNOS_DP_VIDEO_CTL_1			0x20
+#define EXYNOS_DP_VIDEO_CTL_2			0x24
+#define EXYNOS_DP_VIDEO_CTL_3			0x28
+
+#define EXYNOS_DP_VIDEO_CTL_8			0x3C
+#define EXYNOS_DP_VIDEO_CTL_10			0x44
+
+#define EXYNOS_DP_LANE_MAP			0x35C
+
+#define EXYNOS_DP_AUX_HW_RETRY_CTL		0x390
+
+#define EXYNOS_DP_COMMON_INT_STA_1		0x3C4
+#define EXYNOS_DP_COMMON_INT_STA_2		0x3C8
+#define EXYNOS_DP_COMMON_INT_STA_3		0x3CC
+#define EXYNOS_DP_COMMON_INT_STA_4		0x3D0
+#define EXYNOS_DP_INT_STA			0x3DC
+#define EXYNOS_DP_COMMON_INT_MASK_1		0x3E0
+#define EXYNOS_DP_COMMON_INT_MASK_2		0x3E4
+#define EXYNOS_DP_COMMON_INT_MASK_3		0x3E8
+#define EXYNOS_DP_COMMON_INT_MASK_4		0x3EC
+#define EXYNOS_DP_INT_STA_MASK			0x3F8
+#define EXYNOS_DP_INT_CTL			0x3FC
+
+#define EXYNOS_DP_SYS_CTL_1			0x600
+#define EXYNOS_DP_SYS_CTL_2			0x604
+#define EXYNOS_DP_SYS_CTL_3			0x608
+#define EXYNOS_DP_SYS_CTL_4			0x60C
+
+#define EXYNOS_DP_PKT_SEND_CTL			0x640
+#define EXYNOS_DP_HDCP_CTL			0x648
+
+#define EXYNOS_DP_LINK_BW_SET			0x680
+#define EXYNOS_DP_LANE_COUNT_SET		0x684
+#define EXYNOS_DP_TRAINING_PTN_SET		0x688
+#define EXYNOS_DP_LN0_LINK_TRAINING_CTL		0x68C
+#define EXYNOS_DP_LN1_LINK_TRAINING_CTL		0x690
+#define EXYNOS_DP_LN2_LINK_TRAINING_CTL		0x694
+#define EXYNOS_DP_LN3_LINK_TRAINING_CTL		0x698
+
+#define EXYNOS_DP_DEBUG_CTL			0x6C0
+#define EXYNOS_DP_HPD_DEGLITCH_L		0x6C4
+#define EXYNOS_DP_HPD_DEGLITCH_H		0x6C8
+#define EXYNOS_DP_LINK_DEBUG_CTL		0x6E0
+
+#define EXYNOS_DP_M_VID_0			0x700
+#define EXYNOS_DP_M_VID_1			0x704
+#define EXYNOS_DP_M_VID_2			0x708
+#define EXYNOS_DP_N_VID_0			0x70C
+#define EXYNOS_DP_N_VID_1			0x710
+#define EXYNOS_DP_N_VID_2			0x714
+
+#define EXYNOS_DP_PLL_CTL			0x71C
+#define EXYNOS_DP_PHY_PD			0x720
+#define EXYNOS_DP_PHY_TEST			0x724
+
+#define EXYNOS_DP_VIDEO_FIFO_THRD		0x730
+#define EXYNOS_DP_AUDIO_MARGIN			0x73C
+
+#define EXYNOS_DP_M_VID_GEN_FILTER_TH		0x764
+#define EXYNOS_DP_M_AUD_GEN_FILTER_TH		0x778
+#define EXYNOS_DP_AUX_CH_STA			0x780
+#define EXYNOS_DP_AUX_CH_DEFER_CTL		0x788
+#define EXYNOS_DP_AUX_RX_COMM			0x78C
+#define EXYNOS_DP_BUFFER_DATA_CTL		0x790
+#define EXYNOS_DP_AUX_CH_CTL_1			0x794
+#define EXYNOS_DP_AUX_ADDR_7_0			0x798
+#define EXYNOS_DP_AUX_ADDR_15_8			0x79C
+#define EXYNOS_DP_AUX_ADDR_19_16		0x7A0
+#define EXYNOS_DP_AUX_CH_CTL_2			0x7A4
+
+#define EXYNOS_DP_BUF_DATA_0			0x7C0
+
+#define EXYNOS_DP_SOC_GENERAL_CTL		0x800
+
+/* EXYNOS_DP_TX_SW_RESET */
+#define RESET_DP_TX				(0x1 << 0)
+
+/* EXYNOS_DP_FUNC_EN_1 */
+#define MASTER_VID_FUNC_EN_N			(0x1 << 7)
+#define SLAVE_VID_FUNC_EN_N			(0x1 << 5)
+#define AUD_FIFO_FUNC_EN_N			(0x1 << 4)
+#define AUD_FUNC_EN_N				(0x1 << 3)
+#define HDCP_FUNC_EN_N				(0x1 << 2)
+#define CRC_FUNC_EN_N				(0x1 << 1)
+#define SW_FUNC_EN_N				(0x1 << 0)
+
+/* EXYNOS_DP_FUNC_EN_2 */
+#define SSC_FUNC_EN_N				(0x1 << 7)
+#define AUX_FUNC_EN_N				(0x1 << 2)
+#define SERDES_FIFO_FUNC_EN_N			(0x1 << 1)
+#define LS_CLK_DOMAIN_FUNC_EN_N			(0x1 << 0)
+
+/* EXYNOS_DP_VIDEO_CTL_1 */
+#define VIDEO_EN				(0x1 << 7)
+#define HDCP_VIDEO_MUTE				(0x1 << 6)
+
+/* EXYNOS_DP_VIDEO_CTL_1 */
+#define IN_D_RANGE_MASK				(0x1 << 7)
+#define IN_D_RANGE_SHIFT			(7)
+#define IN_D_RANGE_CEA				(0x1 << 7)
+#define IN_D_RANGE_VESA				(0x0 << 7)
+#define IN_BPC_MASK				(0x7 << 4)
+#define IN_BPC_SHIFT				(4)
+#define IN_BPC_12_BITS				(0x3 << 4)
+#define IN_BPC_10_BITS				(0x2 << 4)
+#define IN_BPC_8_BITS				(0x1 << 4)
+#define IN_BPC_6_BITS				(0x0 << 4)
+#define IN_COLOR_F_MASK				(0x3 << 0)
+#define IN_COLOR_F_SHIFT			(0)
+#define IN_COLOR_F_YCBCR444			(0x2 << 0)
+#define IN_COLOR_F_YCBCR422			(0x1 << 0)
+#define IN_COLOR_F_RGB				(0x0 << 0)
+
+/* EXYNOS_DP_VIDEO_CTL_3 */
+#define IN_YC_COEFFI_MASK			(0x1 << 7)
+#define IN_YC_COEFFI_SHIFT			(7)
+#define IN_YC_COEFFI_ITU709			(0x1 << 7)
+#define IN_YC_COEFFI_ITU601			(0x0 << 7)
+#define VID_CHK_UPDATE_TYPE_MASK		(0x1 << 4)
+#define VID_CHK_UPDATE_TYPE_SHIFT		(4)
+#define VID_CHK_UPDATE_TYPE_1			(0x1 << 4)
+#define VID_CHK_UPDATE_TYPE_0			(0x0 << 4)
+
+/* EXYNOS_DP_VIDEO_CTL_8 */
+#define VID_HRES_TH(x)				(((x) & 0xf) << 4)
+#define VID_VRES_TH(x)				(((x) & 0xf) << 0)
+
+/* EXYNOS_DP_VIDEO_CTL_10 */
+#define FORMAT_SEL				(0x1 << 4)
+#define INTERACE_SCAN_CFG			(0x1 << 2)
+#define VSYNC_POLARITY_CFG			(0x1 << 1)
+#define HSYNC_POLARITY_CFG			(0x1 << 0)
+
+/* EXYNOS_DP_LANE_MAP */
+#define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
+#define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
+#define LANE3_MAP_LOGIC_LANE_2			(0x2 << 6)
+#define LANE3_MAP_LOGIC_LANE_3			(0x3 << 6)
+#define LANE2_MAP_LOGIC_LANE_0			(0x0 << 4)
+#define LANE2_MAP_LOGIC_LANE_1			(0x1 << 4)
+#define LANE2_MAP_LOGIC_LANE_2			(0x2 << 4)
+#define LANE2_MAP_LOGIC_LANE_3			(0x3 << 4)
+#define LANE1_MAP_LOGIC_LANE_0			(0x0 << 2)
+#define LANE1_MAP_LOGIC_LANE_1			(0x1 << 2)
+#define LANE1_MAP_LOGIC_LANE_2			(0x2 << 2)
+#define LANE1_MAP_LOGIC_LANE_3			(0x3 << 2)
+#define LANE0_MAP_LOGIC_LANE_0			(0x0 << 0)
+#define LANE0_MAP_LOGIC_LANE_1			(0x1 << 0)
+#define LANE0_MAP_LOGIC_LANE_2			(0x2 << 0)
+#define LANE0_MAP_LOGIC_LANE_3			(0x3 << 0)
+
+/* EXYNOS_DP_AUX_HW_RETRY_CTL */
+#define AUX_BIT_PERIOD_EXPECTED_DELAY(x)	(((x) & 0x7) << 8)
+#define AUX_HW_RETRY_INTERVAL_MASK		(0x3 << 3)
+#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS	(0x0 << 3)
+#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS	(0x1 << 3)
+#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS	(0x2 << 3)
+#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS	(0x3 << 3)
+#define AUX_HW_RETRY_COUNT_SEL(x)		(((x) & 0x7) << 0)
+
+/* EXYNOS_DP_COMMON_INT_STA_1 */
+#define VSYNC_DET				(0x1 << 7)
+#define PLL_LOCK_CHG				(0x1 << 6)
+#define SPDIF_ERR				(0x1 << 5)
+#define SPDIF_UNSTBL				(0x1 << 4)
+#define VID_FORMAT_CHG				(0x1 << 3)
+#define AUD_CLK_CHG				(0x1 << 2)
+#define VID_CLK_CHG				(0x1 << 1)
+#define SW_INT					(0x1 << 0)
+
+/* EXYNOS_DP_COMMON_INT_STA_2 */
+#define ENC_EN_CHG				(0x1 << 6)
+#define HW_BKSV_RDY				(0x1 << 3)
+#define HW_SHA_DONE				(0x1 << 2)
+#define HW_AUTH_STATE_CHG			(0x1 << 1)
+#define HW_AUTH_DONE				(0x1 << 0)
+
+/* EXYNOS_DP_COMMON_INT_STA_3 */
+#define AFIFO_UNDER				(0x1 << 7)
+#define AFIFO_OVER				(0x1 << 6)
+#define R0_CHK_FLAG				(0x1 << 5)
+
+/* EXYNOS_DP_COMMON_INT_STA_4 */
+#define PSR_ACTIVE				(0x1 << 7)
+#define PSR_INACTIVE				(0x1 << 6)
+#define SPDIF_BI_PHASE_ERR			(0x1 << 5)
+#define HOTPLUG_CHG				(0x1 << 2)
+#define HPD_LOST				(0x1 << 1)
+#define PLUG					(0x1 << 0)
+
+/* EXYNOS_DP_INT_STA */
+#define INT_HPD					(0x1 << 6)
+#define HW_TRAINING_FINISH			(0x1 << 5)
+#define RPLY_RECEIV				(0x1 << 1)
+#define AUX_ERR					(0x1 << 0)
+
+/* EXYNOS_DP_INT_CTL */
+#define SOFT_INT_CTRL				(0x1 << 2)
+#define INT_POL					(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_1 */
+#define DET_STA					(0x1 << 2)
+#define FORCE_DET				(0x1 << 1)
+#define DET_CTRL				(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_2 */
+#define CHA_CRI(x)				(((x) & 0xf) << 4)
+#define CHA_STA					(0x1 << 2)
+#define FORCE_CHA				(0x1 << 1)
+#define CHA_CTRL				(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_3 */
+#define HPD_STATUS				(0x1 << 6)
+#define F_HPD					(0x1 << 5)
+#define HPD_CTRL				(0x1 << 4)
+#define HDCP_RDY				(0x1 << 3)
+#define STRM_VALID				(0x1 << 2)
+#define F_VALID					(0x1 << 1)
+#define VALID_CTRL				(0x1 << 0)
+
+/* EXYNOS_DP_SYS_CTL_4 */
+#define FIX_M_AUD				(0x1 << 4)
+#define ENHANCED				(0x1 << 3)
+#define FIX_M_VID				(0x1 << 2)
+#define M_VID_UPDATE_CTRL			(0x3 << 0)
+
+/* EXYNOS_DP_TRAINING_PTN_SET */
+#define SCRAMBLER_TYPE				(0x1 << 9)
+#define HW_LINK_TRAINING_PATTERN		(0x1 << 8)
+#define SCRAMBLING_DISABLE			(0x1 << 5)
+#define SCRAMBLING_ENABLE			(0x0 << 5)
+#define LINK_QUAL_PATTERN_SET_MASK		(0x3 << 2)
+#define LINK_QUAL_PATTERN_SET_PRBS7		(0x3 << 2)
+#define LINK_QUAL_PATTERN_SET_D10_2		(0x1 << 2)
+#define LINK_QUAL_PATTERN_SET_DISABLE		(0x0 << 2)
+#define SW_TRAINING_PATTERN_SET_MASK		(0x3 << 0)
+#define SW_TRAINING_PATTERN_SET_PTN2		(0x2 << 0)
+#define SW_TRAINING_PATTERN_SET_PTN1		(0x1 << 0)
+#define SW_TRAINING_PATTERN_SET_NORMAL		(0x0 << 0)
+
+/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
+#define PRE_EMPHASIS_SET_SHIFT			(3)
+
+/* EXYNOS_DP_DEBUG_CTL */
+#define PLL_LOCK				(0x1 << 4)
+#define F_PLL_LOCK				(0x1 << 3)
+#define PLL_LOCK_CTRL				(0x1 << 2)
+#define PN_INV					(0x1 << 0)
+
+/* EXYNOS_DP_PLL_CTL */
+#define DP_PLL_PD				(0x1 << 7)
+#define DP_PLL_RESET				(0x1 << 6)
+#define DP_PLL_LOOP_BIT_DEFAULT			(0x1 << 4)
+#define DP_PLL_REF_BIT_1_1250V			(0x5 << 0)
+#define DP_PLL_REF_BIT_1_2500V			(0x7 << 0)
+
+/* EXYNOS_DP_PHY_PD */
+#define DP_PHY_PD				(0x1 << 5)
+#define AUX_PD					(0x1 << 4)
+#define CH3_PD					(0x1 << 3)
+#define CH2_PD					(0x1 << 2)
+#define CH1_PD					(0x1 << 1)
+#define CH0_PD					(0x1 << 0)
+
+/* EXYNOS_DP_PHY_TEST */
+#define MACRO_RST				(0x1 << 5)
+#define CH1_TEST				(0x1 << 1)
+#define CH0_TEST				(0x1 << 0)
+
+/* EXYNOS_DP_AUX_CH_STA */
+#define AUX_BUSY				(0x1 << 4)
+#define AUX_STATUS_MASK				(0xf << 0)
+
+/* EXYNOS_DP_AUX_CH_DEFER_CTL */
+#define DEFER_CTRL_EN				(0x1 << 7)
+#define DEFER_COUNT(x)				(((x) & 0x7f) << 0)
+
+/* EXYNOS_DP_AUX_RX_COMM */
+#define AUX_RX_COMM_I2C_DEFER			(0x2 << 2)
+#define AUX_RX_COMM_AUX_DEFER			(0x2 << 0)
+
+/* EXYNOS_DP_BUFFER_DATA_CTL */
+#define BUF_CLR					(0x1 << 7)
+#define BUF_DATA_COUNT(x)			(((x) & 0x1f) << 0)
+
+/* EXYNOS_DP_AUX_CH_CTL_1 */
+#define AUX_LENGTH(x)				(((x - 1) & 0xf) << 4)
+#define AUX_TX_COMM_MASK			(0xf << 0)
+#define AUX_TX_COMM_DP_TRANSACTION		(0x1 << 3)
+#define AUX_TX_COMM_I2C_TRANSACTION		(0x0 << 3)
+#define AUX_TX_COMM_MOT				(0x1 << 2)
+#define AUX_TX_COMM_WRITE			(0x0 << 0)
+#define AUX_TX_COMM_READ			(0x1 << 0)
+
+/* EXYNOS_DP_AUX_ADDR_7_0 */
+#define AUX_ADDR_7_0(x)				(((x) >> 0) & 0xff)
+
+/* EXYNOS_DP_AUX_ADDR_15_8 */
+#define AUX_ADDR_15_8(x)			(((x) >> 8) & 0xff)
+
+/* EXYNOS_DP_AUX_ADDR_19_16 */
+#define AUX_ADDR_19_16(x)			(((x) >> 16) & 0x0f)
+
+/* EXYNOS_DP_AUX_CH_CTL_2 */
+#define ADDR_ONLY				(0x1 << 1)
+#define AUX_EN					(0x1 << 0)
+
+/* EXYNOS_DP_SOC_GENERAL_CTL */
+#define AUDIO_MODE_SPDIF_MODE			(0x1 << 8)
+#define AUDIO_MODE_MASTER_MODE			(0x0 << 8)
+#define MASTER_VIDEO_INTERLACE_EN		(0x1 << 4)
+#define VIDEO_MASTER_CLK_SEL			(0x1 << 2)
+#define VIDEO_MASTER_MODE_EN			(0x1 << 1)
+#define VIDEO_MODE_MASK				(0x1 << 0)
+#define VIDEO_MODE_SLAVE_MODE			(0x1 << 0)
+#define VIDEO_MODE_MASTER_MODE			(0x0 << 0)
+
+#endif /* _EXYNOS_DP_REG_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
new file mode 100644
index 0000000..557091d
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -0,0 +1,600 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi.c
+ *
+ * Samsung SoC MIPI-DSIM driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/memory.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/notifier.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
+
+#include <video/exynos_mipi_dsim.h>
+
+#include <plat/fb.h>
+
+#include "exynos_mipi_dsi_common.h"
+#include "exynos_mipi_dsi_lowlevel.h"
+
+struct mipi_dsim_ddi {
+	int				bus_id;
+	struct list_head		list;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+};
+
+static LIST_HEAD(dsim_ddi_list);
+
+static DEFINE_MUTEX(mipi_dsim_lock);
+
+static struct mipi_dsim_platform_data *to_dsim_plat(struct platform_device
+							*pdev)
+{
+	return pdev->dev.platform_data;
+}
+
+static struct regulator_bulk_data supplies[] = {
+	{ .supply = "vdd10", },
+	{ .supply = "vdd18", },
+};
+
+static int exynos_mipi_regulator_enable(struct mipi_dsim_device *dsim)
+{
+	int ret;
+
+	mutex_lock(&dsim->lock);
+	ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
+	mutex_unlock(&dsim->lock);
+
+	return ret;
+}
+
+static int exynos_mipi_regulator_disable(struct mipi_dsim_device *dsim)
+{
+	int ret;
+
+	mutex_lock(&dsim->lock);
+	ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+	mutex_unlock(&dsim->lock);
+
+	return ret;
+}
+
+/* update all register settings to MIPI DSI controller. */
+static void exynos_mipi_update_cfg(struct mipi_dsim_device *dsim)
+{
+	/*
+	 * data from Display controller(FIMD) is not transferred in video mode
+	 * but in case of command mode, all settings is not updated to
+	 * registers.
+	 */
+	exynos_mipi_dsi_stand_by(dsim, 0);
+
+	exynos_mipi_dsi_init_dsim(dsim);
+	exynos_mipi_dsi_init_link(dsim);
+
+	exynos_mipi_dsi_set_hs_enable(dsim);
+
+	/* set display timing. */
+	exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
+
+	/*
+	 * data from Display controller(FIMD) is transferred in video mode
+	 * but in case of command mode, all settigs is updated to registers.
+	 */
+	exynos_mipi_dsi_stand_by(dsim, 1);
+}
+
+static int exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device *dsim,
+		int power)
+{
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	switch (power) {
+	case FB_BLANK_POWERDOWN:
+		if (dsim->suspended)
+			return 0;
+
+		if (client_drv && client_drv->suspend)
+			client_drv->suspend(client_dev);
+
+		clk_disable(dsim->clock);
+
+		exynos_mipi_regulator_disable(dsim);
+
+		dsim->suspended = true;
+
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)
+{
+	struct platform_device *pdev = to_platform_device(dsim->dev);
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	switch (power) {
+	case FB_BLANK_UNBLANK:
+		if (!dsim->suspended)
+			return 0;
+
+		/* lcd panel power on. */
+		if (client_drv && client_drv->power_on)
+			client_drv->power_on(client_dev, 1);
+
+		exynos_mipi_regulator_disable(dsim);
+
+		/* enable MIPI-DSI PHY. */
+		if (dsim->pd->phy_enable)
+			dsim->pd->phy_enable(pdev, true);
+
+		clk_enable(dsim->clock);
+
+		exynos_mipi_update_cfg(dsim);
+
+		/* set lcd panel sequence commands. */
+		if (client_drv && client_drv->set_sequence)
+			client_drv->set_sequence(client_dev);
+
+		dsim->suspended = false;
+
+		break;
+	case FB_BLANK_NORMAL:
+		/* TODO. */
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	if (!lcd_dev->name) {
+		pr_err("dsim_lcd_device name is NULL.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
+	if (!dsim_ddi) {
+		pr_err("failed to allocate dsim_ddi object.\n");
+		return -ENOMEM;
+	}
+
+	dsim_ddi->dsim_lcd_dev = lcd_dev;
+
+	mutex_lock(&mipi_dsim_lock);
+	list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
+	mutex_unlock(&mipi_dsim_lock);
+
+	return 0;
+}
+
+struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
+{
+	struct mipi_dsim_ddi *dsim_ddi, *next;
+	struct mipi_dsim_lcd_device *lcd_dev;
+
+	mutex_lock(&mipi_dsim_lock);
+
+	list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
+		if (!dsim_ddi)
+			goto out;
+
+		lcd_dev = dsim_ddi->dsim_lcd_dev;
+		if (!lcd_dev)
+			continue;
+
+		if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
+			/**
+			 * bus_id would be used to identify
+			 * connected bus.
+			 */
+			dsim_ddi->bus_id = lcd_dev->bus_id;
+			mutex_unlock(&mipi_dsim_lock);
+
+			return dsim_ddi;
+		}
+
+		list_del(&dsim_ddi->list);
+		kfree(dsim_ddi);
+	}
+
+out:
+	mutex_unlock(&mipi_dsim_lock);
+
+	return NULL;
+}
+
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	if (!lcd_drv->name) {
+		pr_err("dsim_lcd_driver name is NULL.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
+	if (!dsim_ddi) {
+		pr_err("mipi_dsim_ddi object not found.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi->dsim_lcd_drv = lcd_drv;
+
+	pr_info("registered panel driver(%s) to mipi-dsi driver.\n",
+		lcd_drv->name);
+
+	return 0;
+
+}
+
+struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
+						const char *name)
+{
+	struct mipi_dsim_ddi *dsim_ddi, *next;
+	struct mipi_dsim_lcd_driver *lcd_drv;
+	struct mipi_dsim_lcd_device *lcd_dev;
+	int ret;
+
+	mutex_lock(&dsim->lock);
+
+	list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
+		lcd_drv = dsim_ddi->dsim_lcd_drv;
+		lcd_dev = dsim_ddi->dsim_lcd_dev;
+		if (!lcd_drv || !lcd_dev ||
+			(dsim->id != dsim_ddi->bus_id))
+				continue;
+
+		dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n",
+				lcd_drv->id, lcd_dev->id);
+		dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n",
+				lcd_dev->bus_id, dsim->id);
+
+		if ((strcmp(lcd_drv->name, name) == 0)) {
+			lcd_dev->master = dsim;
+
+			lcd_dev->dev.parent = dsim->dev;
+			dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name);
+
+			ret = device_register(&lcd_dev->dev);
+			if (ret < 0) {
+				dev_err(dsim->dev,
+					"can't register %s, status %d\n",
+					dev_name(&lcd_dev->dev), ret);
+				mutex_unlock(&dsim->lock);
+
+				return NULL;
+			}
+
+			dsim->dsim_lcd_dev = lcd_dev;
+			dsim->dsim_lcd_drv = lcd_drv;
+
+			mutex_unlock(&dsim->lock);
+
+			return dsim_ddi;
+		}
+	}
+
+	mutex_unlock(&dsim->lock);
+
+	return NULL;
+}
+
+/* define MIPI-DSI Master operations. */
+static struct mipi_dsim_master_ops master_ops = {
+	.cmd_read			= exynos_mipi_dsi_rd_data,
+	.cmd_write			= exynos_mipi_dsi_wr_data,
+	.get_dsim_frame_done		= exynos_mipi_dsi_get_frame_done_status,
+	.clear_dsim_frame_done		= exynos_mipi_dsi_clear_frame_done,
+	.set_early_blank_mode		= exynos_mipi_dsi_early_blank_mode,
+	.set_blank_mode			= exynos_mipi_dsi_blank_mode,
+};
+
+static int exynos_mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct mipi_dsim_device *dsim;
+	struct mipi_dsim_config *dsim_config;
+	struct mipi_dsim_platform_data *dsim_pd;
+	struct mipi_dsim_ddi *dsim_ddi;
+	int ret = -EINVAL;
+
+	dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
+	if (!dsim) {
+		dev_err(&pdev->dev, "failed to allocate dsim object.\n");
+		return -ENOMEM;
+	}
+
+	dsim->pd = to_dsim_plat(pdev);
+	dsim->dev = &pdev->dev;
+	dsim->id = pdev->id;
+
+	/* get mipi_dsim_platform_data. */
+	dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
+	if (dsim_pd == NULL) {
+		dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
+		goto err_clock_get;
+	}
+	/* get mipi_dsim_config. */
+	dsim_config = dsim_pd->dsim_config;
+	if (dsim_config == NULL) {
+		dev_err(&pdev->dev, "failed to get dsim config data.\n");
+		goto err_clock_get;
+	}
+
+	dsim->dsim_config = dsim_config;
+	dsim->master_ops = &master_ops;
+
+	mutex_init(&dsim->lock);
+
+	ret = regulator_bulk_get(&pdev->dev, ARRAY_SIZE(supplies), supplies);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to get regulators: %d\n", ret);
+		goto err_clock_get;
+	}
+
+	dsim->clock = clk_get(&pdev->dev, "dsim0");
+	if (IS_ERR(dsim->clock)) {
+		dev_err(&pdev->dev, "failed to get dsim clock source\n");
+		goto err_clock_get;
+	}
+
+	clk_enable(dsim->clock);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get io memory region\n");
+		goto err_platform_get;
+	}
+
+	dsim->res = request_mem_region(res->start, resource_size(res),
+					dev_name(&pdev->dev));
+	if (!dsim->res) {
+		dev_err(&pdev->dev, "failed to request io memory region\n");
+		ret = -ENOMEM;
+		goto err_mem_region;
+	}
+
+	dsim->reg_base = ioremap(res->start, resource_size(res));
+	if (!dsim->reg_base) {
+		dev_err(&pdev->dev, "failed to remap io region\n");
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	mutex_init(&dsim->lock);
+
+	/* bind lcd ddi matched with panel name. */
+	dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
+	if (!dsim_ddi) {
+		dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
+		goto err_bind;
+	}
+
+	dsim->irq = platform_get_irq(pdev, 0);
+	if (dsim->irq < 0) {
+		dev_err(&pdev->dev, "failed to request dsim irq resource\n");
+		ret = -EINVAL;
+		goto err_platform_get_irq;
+	}
+
+	ret = request_irq(dsim->irq, exynos_mipi_dsi_interrupt_handler,
+			IRQF_SHARED, pdev->name, dsim);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "failed to request dsim irq\n");
+		ret = -EINVAL;
+		goto err_bind;
+	}
+
+	init_completion(&dsim_wr_comp);
+	init_completion(&dsim_rd_comp);
+
+	/* enable interrupt */
+	exynos_mipi_dsi_init_interrupt(dsim);
+
+	/* initialize mipi-dsi client(lcd panel). */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->probe)
+		dsim_ddi->dsim_lcd_drv->probe(dsim_ddi->dsim_lcd_dev);
+
+	/* in case that mipi got enabled at bootloader. */
+	if (dsim_pd->enabled)
+		goto out;
+
+	/* lcd panel power on. */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->power_on)
+		dsim_ddi->dsim_lcd_drv->power_on(dsim_ddi->dsim_lcd_dev, 1);
+
+	exynos_mipi_regulator_enable(dsim);
+
+	/* enable MIPI-DSI PHY. */
+	if (dsim->pd->phy_enable)
+		dsim->pd->phy_enable(pdev, true);
+
+	exynos_mipi_update_cfg(dsim);
+
+	/* set lcd panel sequence commands. */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->set_sequence)
+		dsim_ddi->dsim_lcd_drv->set_sequence(dsim_ddi->dsim_lcd_dev);
+
+	dsim->suspended = false;
+
+out:
+	platform_set_drvdata(pdev, dsim);
+
+	dev_dbg(&pdev->dev, "mipi-dsi driver(%s mode) has been probed.\n",
+		(dsim_config->e_interface == DSIM_COMMAND) ?
+			"CPU" : "RGB");
+
+	return 0;
+
+err_bind:
+	iounmap(dsim->reg_base);
+
+err_ioremap:
+	release_mem_region(dsim->res->start, resource_size(dsim->res));
+
+err_mem_region:
+	release_resource(dsim->res);
+
+err_platform_get:
+	clk_disable(dsim->clock);
+	clk_put(dsim->clock);
+err_clock_get:
+	kfree(dsim);
+
+err_platform_get_irq:
+	return ret;
+}
+
+static int __devexit exynos_mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
+	struct mipi_dsim_ddi *dsim_ddi, *next;
+	struct mipi_dsim_lcd_driver *dsim_lcd_drv;
+
+	iounmap(dsim->reg_base);
+
+	clk_disable(dsim->clock);
+	clk_put(dsim->clock);
+
+	release_resource(dsim->res);
+	release_mem_region(dsim->res->start, resource_size(dsim->res));
+
+	list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
+		if (dsim_ddi) {
+			if (dsim->id != dsim_ddi->bus_id)
+				continue;
+
+			dsim_lcd_drv = dsim_ddi->dsim_lcd_drv;
+
+			if (dsim_lcd_drv->remove)
+				dsim_lcd_drv->remove(dsim_ddi->dsim_lcd_dev);
+
+			kfree(dsim_ddi);
+		}
+	}
+
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+	kfree(dsim);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int exynos_mipi_dsi_suspend(struct platform_device *pdev,
+		pm_message_t state)
+{
+	struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	disable_irq(dsim->irq);
+
+	if (dsim->suspended)
+		return 0;
+
+	if (client_drv && client_drv->suspend)
+		client_drv->suspend(client_dev);
+
+	/* enable MIPI-DSI PHY. */
+	if (dsim->pd->phy_enable)
+		dsim->pd->phy_enable(pdev, false);
+
+	clk_disable(dsim->clock);
+
+	exynos_mipi_regulator_disable(dsim);
+
+	dsim->suspended = true;
+
+	return 0;
+}
+
+static int exynos_mipi_dsi_resume(struct platform_device *pdev)
+{
+	struct mipi_dsim_device *dsim = platform_get_drvdata(pdev);
+	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;
+	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev;
+
+	enable_irq(dsim->irq);
+
+	if (!dsim->suspended)
+		return 0;
+
+	/* lcd panel power on. */
+	if (client_drv && client_drv->power_on)
+		client_drv->power_on(client_dev, 1);
+
+	exynos_mipi_regulator_enable(dsim);
+
+	/* enable MIPI-DSI PHY. */
+	if (dsim->pd->phy_enable)
+		dsim->pd->phy_enable(pdev, true);
+
+	clk_enable(dsim->clock);
+
+	exynos_mipi_update_cfg(dsim);
+
+	/* set lcd panel sequence commands. */
+	if (client_drv && client_drv->set_sequence)
+		client_drv->set_sequence(client_dev);
+
+	dsim->suspended = false;
+
+	return 0;
+}
+#else
+#define exynos_mipi_dsi_suspend NULL
+#define exynos_mipi_dsi_resume NULL
+#endif
+
+static struct platform_driver exynos_mipi_dsi_driver = {
+	.probe = exynos_mipi_dsi_probe,
+	.remove = __devexit_p(exynos_mipi_dsi_remove),
+	.suspend = exynos_mipi_dsi_suspend,
+	.resume = exynos_mipi_dsi_resume,
+	.driver = {
+		   .name = "exynos-mipi-dsim",
+		   .owner = THIS_MODULE,
+	},
+};
+
+module_platform_driver(exynos_mipi_dsi_driver);
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
new file mode 100644
index 0000000..14909c1
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -0,0 +1,896 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi_common.c
+ *
+ * Samsung SoC MIPI-DSI common driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/memory.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#include <video/mipi_display.h>
+#include <video/exynos_mipi_dsim.h>
+
+#include <mach/map.h>
+
+#include "exynos_mipi_dsi_regs.h"
+#include "exynos_mipi_dsi_lowlevel.h"
+#include "exynos_mipi_dsi_common.h"
+
+#define MIPI_FIFO_TIMEOUT	msecs_to_jiffies(250)
+#define MIPI_RX_FIFO_READ_DONE  0x30800002
+#define MIPI_MAX_RX_FIFO        20
+#define MHZ			(1000 * 1000)
+#define FIN_HZ			(24 * MHZ)
+
+#define DFIN_PLL_MIN_HZ		(6 * MHZ)
+#define DFIN_PLL_MAX_HZ		(12 * MHZ)
+
+#define DFVCO_MIN_HZ		(500 * MHZ)
+#define DFVCO_MAX_HZ		(1000 * MHZ)
+
+#define TRY_GET_FIFO_TIMEOUT	(5000 * 2)
+#define TRY_FIFO_CLEAR		(10)
+
+/* MIPI-DSIM status types. */
+enum {
+	DSIM_STATE_INIT,	/* should be initialized. */
+	DSIM_STATE_STOP,	/* CPU and LCDC are LP mode. */
+	DSIM_STATE_HSCLKEN,	/* HS clock was enabled. */
+	DSIM_STATE_ULPS
+};
+
+/* define DSI lane types. */
+enum {
+	DSIM_LANE_CLOCK = (1 << 0),
+	DSIM_LANE_DATA0 = (1 << 1),
+	DSIM_LANE_DATA1 = (1 << 2),
+	DSIM_LANE_DATA2 = (1 << 3),
+	DSIM_LANE_DATA3 = (1 << 4)
+};
+
+static unsigned int dpll_table[15] = {
+	100, 120, 170, 220, 270,
+	320, 390, 450, 510, 560,
+	640, 690, 770, 870, 950
+};
+
+irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id)
+{
+	unsigned int intsrc = 0;
+	unsigned int intmsk = 0;
+	struct mipi_dsim_device *dsim = NULL;
+
+	dsim = dev_id;
+	if (!dsim) {
+		dev_dbg(dsim->dev, KERN_ERR "%s:error: wrong parameter\n",
+							__func__);
+		return IRQ_HANDLED;
+	}
+
+	intsrc = exynos_mipi_dsi_read_interrupt(dsim);
+	intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
+
+	intmsk = ~(intmsk) & intsrc;
+
+	switch (intmsk) {
+	case INTMSK_RX_DONE:
+		complete(&dsim_rd_comp);
+		dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n");
+		break;
+	case INTMSK_FIFO_EMPTY:
+		complete(&dsim_wr_comp);
+		dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n");
+		break;
+	default:
+		break;
+	}
+
+	exynos_mipi_dsi_clear_interrupt(dsim, intmsk);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * write long packet to mipi dsi slave
+ * @dsim: mipi dsim device structure.
+ * @data0: packet data to send.
+ * @data1: size of packet data
+ */
+static void exynos_mipi_dsi_long_data_wr(struct mipi_dsim_device *dsim,
+		const unsigned char *data0, unsigned int data_size)
+{
+	unsigned int data_cnt = 0, payload = 0;
+
+	/* in case that data count is more then 4 */
+	for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
+		/*
+		 * after sending 4bytes per one time,
+		 * send remainder data less then 4.
+		 */
+		if ((data_size - data_cnt) < 4) {
+			if ((data_size - data_cnt) == 3) {
+				payload = data0[data_cnt] |
+				    data0[data_cnt + 1] << 8 |
+					data0[data_cnt + 2] << 16;
+			dev_dbg(dsim->dev, "count = 3 payload = %x, %x %x %x\n",
+				payload, data0[data_cnt],
+				data0[data_cnt + 1],
+				data0[data_cnt + 2]);
+			} else if ((data_size - data_cnt) == 2) {
+				payload = data0[data_cnt] |
+					data0[data_cnt + 1] << 8;
+			dev_dbg(dsim->dev,
+				"count = 2 payload = %x, %x %x\n", payload,
+				data0[data_cnt],
+				data0[data_cnt + 1]);
+			} else if ((data_size - data_cnt) == 1) {
+				payload = data0[data_cnt];
+			}
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+		/* send 4bytes per one time. */
+		} else {
+			payload = data0[data_cnt] |
+				data0[data_cnt + 1] << 8 |
+				data0[data_cnt + 2] << 16 |
+				data0[data_cnt + 3] << 24;
+
+			dev_dbg(dsim->dev,
+				"count = 4 payload = %x, %x %x %x %x\n",
+				payload, *(u8 *)(data0 + data_cnt),
+				data0[data_cnt + 1],
+				data0[data_cnt + 2],
+				data0[data_cnt + 3]);
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+		}
+	}
+}
+
+int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	const unsigned char *data0, unsigned int data_size)
+{
+	unsigned int check_rx_ack = 0;
+
+	if (dsim->state == DSIM_STATE_ULPS) {
+		dev_err(dsim->dev, "state is ULPS.\n");
+
+		return -EINVAL;
+	}
+
+	/* FIXME!!! why does it need this delay? */
+	msleep(20);
+
+	mutex_lock(&dsim->lock);
+
+	switch (data_id) {
+	/* short packet types of packet types for command. */
+	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
+	case MIPI_DSI_DCS_SHORT_WRITE:
+	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
+		if (check_rx_ack) {
+			/* process response func should be implemented */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+
+	/* general command */
+	case MIPI_DSI_COLOR_MODE_OFF:
+	case MIPI_DSI_COLOR_MODE_ON:
+	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
+	case MIPI_DSI_TURN_ON_PERIPHERAL:
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0[0], data0[1]);
+		if (check_rx_ack) {
+			/* process response func should be implemented. */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+
+	/* packet types for video data */
+	case MIPI_DSI_V_SYNC_START:
+	case MIPI_DSI_V_SYNC_END:
+	case MIPI_DSI_H_SYNC_START:
+	case MIPI_DSI_H_SYNC_END:
+	case MIPI_DSI_END_OF_TRANSMISSION:
+		mutex_unlock(&dsim->lock);
+		return 0;
+
+	/* long packet type and null packet */
+	case MIPI_DSI_NULL_PACKET:
+	case MIPI_DSI_BLANKING_PACKET:
+		mutex_unlock(&dsim->lock);
+		return 0;
+	case MIPI_DSI_GENERIC_LONG_WRITE:
+	case MIPI_DSI_DCS_LONG_WRITE:
+	{
+		unsigned int size, payload = 0;
+		INIT_COMPLETION(dsim_wr_comp);
+
+		size = data_size * 4;
+
+		/* if data count is less then 4, then send 3bytes data.  */
+		if (data_size < 4) {
+			payload = data0[0] |
+				data0[1] << 8 |
+				data0[2] << 16;
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+
+			dev_dbg(dsim->dev, "count = %d payload = %x,%x %x %x\n",
+				data_size, payload, data0[0],
+				data0[1], data0[2]);
+
+		/* in case that data count is more then 4 */
+		} else
+			exynos_mipi_dsi_long_data_wr(dsim, data0, data_size);
+
+		/* put data into header fifo */
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data_size & 0xff,
+			(data_size & 0xff00) >> 8);
+
+		if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp,
+							MIPI_FIFO_TIMEOUT)) {
+			dev_warn(dsim->dev, "command write timeout.\n");
+			mutex_unlock(&dsim->lock);
+			return -EAGAIN;
+		}
+
+		if (check_rx_ack) {
+			/* process response func should be implemented. */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+	}
+
+	/* packet typo for video data */
+	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
+	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
+	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
+	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
+		if (check_rx_ack) {
+			/* process response func should be implemented. */
+			mutex_unlock(&dsim->lock);
+			return 0;
+		} else {
+			mutex_unlock(&dsim->lock);
+			return -EINVAL;
+		}
+	default:
+		dev_warn(dsim->dev,
+			"data id %x is not supported current DSI spec.\n",
+			data_id);
+
+		mutex_unlock(&dsim->lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&dsim->lock);
+	return 0;
+}
+
+static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
+		unsigned int req_size, unsigned int rx_data, u8 *rx_buf)
+{
+	unsigned int rcv_pkt, i, j;
+	u16 rxsize;
+
+	/* for long packet */
+	rxsize = (u16)((rx_data & 0x00ffff00) >> 8);
+	dev_dbg(dsim->dev, "mipi dsi rx size : %d\n", rxsize);
+	if (rxsize != req_size) {
+		dev_dbg(dsim->dev,
+			"received size mismatch received: %d, requested: %d\n",
+			rxsize, req_size);
+		goto err;
+	}
+
+	for (i = 0; i < (rxsize >> 2); i++) {
+		rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+		dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
+		for (j = 0; j < 4; j++) {
+			rx_buf[(i * 4) + j] =
+					(u8)(rcv_pkt >> (j * 8)) & 0xff;
+			dev_dbg(dsim->dev, "received value : %02x\n",
+					(rcv_pkt >> (j * 8)) & 0xff);
+		}
+	}
+	if (rxsize % 4) {
+		rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+		dev_dbg(dsim->dev, "received pkt : %08x\n", rcv_pkt);
+		for (j = 0; j < (rxsize % 4); j++) {
+			rx_buf[(i * 4) + j] =
+					(u8)(rcv_pkt >> (j * 8)) & 0xff;
+			dev_dbg(dsim->dev, "received value : %02x\n",
+					(rcv_pkt >> (j * 8)) & 0xff);
+		}
+	}
+
+	return rxsize;
+
+err:
+	return -EINVAL;
+}
+
+static unsigned int exynos_mipi_dsi_response_size(unsigned int req_size)
+{
+	switch (req_size) {
+	case 1:
+		return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE;
+	case 2:
+		return MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE;
+	default:
+		return MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE;
+	}
+}
+
+int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	unsigned int data0, unsigned int req_size, u8 *rx_buf)
+{
+	unsigned int rx_data, rcv_pkt, i;
+	u8 response = 0;
+	u16 rxsize;
+
+	if (dsim->state == DSIM_STATE_ULPS) {
+		dev_err(dsim->dev, "state is ULPS.\n");
+
+		return -EINVAL;
+	}
+
+	/* FIXME!!! */
+	msleep(20);
+
+	mutex_lock(&dsim->lock);
+	INIT_COMPLETION(dsim_rd_comp);
+	exynos_mipi_dsi_rd_tx_header(dsim,
+		MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, req_size);
+
+	response = exynos_mipi_dsi_response_size(req_size);
+
+	switch (data_id) {
+	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
+	case MIPI_DSI_DCS_READ:
+		exynos_mipi_dsi_rd_tx_header(dsim,
+			data_id, data0);
+		/* process response func should be implemented. */
+		break;
+	default:
+		dev_warn(dsim->dev,
+			"data id %x is not supported current DSI spec.\n",
+			data_id);
+
+		return -EINVAL;
+	}
+
+	if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp,
+				MIPI_FIFO_TIMEOUT)) {
+		pr_err("RX done interrupt timeout\n");
+		mutex_unlock(&dsim->lock);
+		return 0;
+	}
+
+	msleep(20);
+
+	rx_data = exynos_mipi_dsi_rd_rx_fifo(dsim);
+
+	if ((u8)(rx_data & 0xff) != response) {
+		printk(KERN_ERR
+			"mipi dsi wrong response rx_data : %x, response:%x\n",
+			rx_data, response);
+		goto clear_rx_fifo;
+	}
+
+	if (req_size <= 2) {
+		/* for short packet */
+		for (i = 0; i < req_size; i++)
+			rx_buf[i] = (rx_data >> (8 + (i * 8))) & 0xff;
+		rxsize = req_size;
+	} else {
+		/* for long packet */
+		rxsize = exynos_mipi_dsi_long_data_rd(dsim, req_size, rx_data,
+							rx_buf);
+		if (rxsize != req_size)
+			goto clear_rx_fifo;
+	}
+
+	rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+
+	msleep(20);
+
+	if (rcv_pkt != MIPI_RX_FIFO_READ_DONE) {
+		dev_info(dsim->dev,
+			"Can't found RX FIFO READ DONE FLAG : %x\n", rcv_pkt);
+		goto clear_rx_fifo;
+	}
+
+	mutex_unlock(&dsim->lock);
+
+	return rxsize;
+
+clear_rx_fifo:
+	i = 0;
+	while (1) {
+		rcv_pkt = exynos_mipi_dsi_rd_rx_fifo(dsim);
+		if ((rcv_pkt == MIPI_RX_FIFO_READ_DONE)
+				|| (i > MIPI_MAX_RX_FIFO))
+			break;
+		dev_dbg(dsim->dev,
+				"mipi dsi clear rx fifo : %08x\n", rcv_pkt);
+		i++;
+	}
+	dev_info(dsim->dev,
+		"mipi dsi rx done count : %d, rcv_pkt : %08x\n", i, rcv_pkt);
+
+	mutex_unlock(&dsim->lock);
+
+	return 0;
+}
+
+static int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim,
+				unsigned int enable)
+{
+	int sw_timeout;
+
+	if (enable) {
+		sw_timeout = 1000;
+
+		exynos_mipi_dsi_enable_pll(dsim, 1);
+		while (1) {
+			sw_timeout--;
+			if (exynos_mipi_dsi_is_pll_stable(dsim))
+				return 0;
+			if (sw_timeout == 0)
+				return -EINVAL;
+		}
+	} else
+		exynos_mipi_dsi_enable_pll(dsim, 0);
+
+	return 0;
+}
+
+static unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
+	unsigned int pre_divider, unsigned int main_divider,
+	unsigned int scaler)
+{
+	unsigned long dfin_pll, dfvco, dpll_out;
+	unsigned int i, freq_band = 0xf;
+
+	dfin_pll = (FIN_HZ / pre_divider);
+
+	/******************************************************
+	 *	Serial Clock(=ByteClk X 8)	FreqBand[3:0] *
+	 ******************************************************
+	 *	~ 99.99 MHz			0000
+	 *	100 ~ 119.99 MHz		0001
+	 *	120 ~ 159.99 MHz		0010
+	 *	160 ~ 199.99 MHz		0011
+	 *	200 ~ 239.99 MHz		0100
+	 *	140 ~ 319.99 MHz		0101
+	 *	320 ~ 389.99 MHz		0110
+	 *	390 ~ 449.99 MHz		0111
+	 *	450 ~ 509.99 MHz		1000
+	 *	510 ~ 559.99 MHz		1001
+	 *	560 ~ 639.99 MHz		1010
+	 *	640 ~ 689.99 MHz		1011
+	 *	690 ~ 769.99 MHz		1100
+	 *	770 ~ 869.99 MHz		1101
+	 *	870 ~ 949.99 MHz		1110
+	 *	950 ~ 1000 MHz			1111
+	 ******************************************************/
+	if (dfin_pll < DFIN_PLL_MIN_HZ || dfin_pll > DFIN_PLL_MAX_HZ) {
+		dev_warn(dsim->dev, "fin_pll range should be 6MHz ~ 12MHz\n");
+		exynos_mipi_dsi_enable_afc(dsim, 0, 0);
+	} else {
+		if (dfin_pll < 7 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x1);
+		else if (dfin_pll < 8 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x0);
+		else if (dfin_pll < 9 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x3);
+		else if (dfin_pll < 10 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x2);
+		else if (dfin_pll < 11 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x5);
+		else
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x4);
+	}
+
+	dfvco = dfin_pll * main_divider;
+	dev_dbg(dsim->dev, "dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
+				dfvco, dfin_pll, main_divider);
+	if (dfvco < DFVCO_MIN_HZ || dfvco > DFVCO_MAX_HZ)
+		dev_warn(dsim->dev, "fvco range should be 500MHz ~ 1000MHz\n");
+
+	dpll_out = dfvco / (1 << scaler);
+	dev_dbg(dsim->dev, "dpll_out = %lu, dfvco = %lu, scaler = %d\n",
+		dpll_out, dfvco, scaler);
+
+	for (i = 0; i < ARRAY_SIZE(dpll_table); i++) {
+		if (dpll_out < dpll_table[i] * MHZ) {
+			freq_band = i;
+			break;
+		}
+	}
+
+	dev_dbg(dsim->dev, "freq_band = %d\n", freq_band);
+
+	exynos_mipi_dsi_pll_freq(dsim, pre_divider, main_divider, scaler);
+
+	exynos_mipi_dsi_hs_zero_ctrl(dsim, 0);
+	exynos_mipi_dsi_prep_ctrl(dsim, 0);
+
+	/* Freq Band */
+	exynos_mipi_dsi_pll_freq_band(dsim, freq_band);
+
+	/* Stable time */
+	exynos_mipi_dsi_pll_stable_time(dsim, dsim->dsim_config->pll_stable_time);
+
+	/* Enable PLL */
+	dev_dbg(dsim->dev, "FOUT of mipi dphy pll is %luMHz\n",
+		(dpll_out / MHZ));
+
+	return dpll_out;
+}
+
+static int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
+	unsigned int byte_clk_sel, unsigned int enable)
+{
+	unsigned int esc_div;
+	unsigned long esc_clk_error_rate;
+	unsigned long hs_clk = 0, byte_clk = 0, escape_clk = 0;
+
+	if (enable) {
+		dsim->e_clk_src = byte_clk_sel;
+
+		/* Escape mode clock and byte clock source */
+		exynos_mipi_dsi_set_byte_clock_src(dsim, byte_clk_sel);
+
+		/* DPHY, DSIM Link : D-PHY clock out */
+		if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
+			hs_clk = exynos_mipi_dsi_change_pll(dsim,
+				dsim->dsim_config->p, dsim->dsim_config->m,
+				dsim->dsim_config->s);
+			if (hs_clk == 0) {
+				dev_err(dsim->dev,
+					"failed to get hs clock.\n");
+				return -EINVAL;
+			}
+
+			byte_clk = hs_clk / 8;
+			exynos_mipi_dsi_enable_pll_bypass(dsim, 0);
+			exynos_mipi_dsi_pll_on(dsim, 1);
+		/* DPHY : D-PHY clock out, DSIM link : external clock out */
+		} else if (byte_clk_sel == DSIM_EXT_CLK_DIV8) {
+			dev_warn(dsim->dev, "this project is not support\n");
+			dev_warn(dsim->dev,
+				"external clock source for MIPI DSIM.\n");
+		} else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS) {
+			dev_warn(dsim->dev, "this project is not support\n");
+			dev_warn(dsim->dev,
+				"external clock source for MIPI DSIM\n");
+		}
+
+		/* escape clock divider */
+		esc_div = byte_clk / (dsim->dsim_config->esc_clk);
+		dev_dbg(dsim->dev,
+			"esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
+			esc_div, byte_clk, dsim->dsim_config->esc_clk);
+		if ((byte_clk / esc_div) >= (20 * MHZ) ||
+				(byte_clk / esc_div) >
+					dsim->dsim_config->esc_clk)
+			esc_div += 1;
+
+		escape_clk = byte_clk / esc_div;
+		dev_dbg(dsim->dev,
+			"escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
+			escape_clk, byte_clk, esc_div);
+
+		/* enable escape clock. */
+		exynos_mipi_dsi_enable_byte_clock(dsim, 1);
+
+		/* enable byte clk and escape clock */
+		exynos_mipi_dsi_set_esc_clk_prs(dsim, 1, esc_div);
+		/* escape clock on lane */
+		exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
+			(DSIM_LANE_CLOCK | dsim->data_lane), 1);
+
+		dev_dbg(dsim->dev, "byte clock is %luMHz\n",
+			(byte_clk / MHZ));
+		dev_dbg(dsim->dev, "escape clock that user's need is %lu\n",
+			(dsim->dsim_config->esc_clk / MHZ));
+		dev_dbg(dsim->dev, "escape clock divider is %x\n", esc_div);
+		dev_dbg(dsim->dev, "escape clock is %luMHz\n",
+			((byte_clk / esc_div) / MHZ));
+
+		if ((byte_clk / esc_div) > escape_clk) {
+			esc_clk_error_rate = escape_clk /
+				(byte_clk / esc_div);
+			dev_warn(dsim->dev, "error rate is %lu over.\n",
+				(esc_clk_error_rate / 100));
+		} else if ((byte_clk / esc_div) < (escape_clk)) {
+			esc_clk_error_rate = (byte_clk / esc_div) /
+				escape_clk;
+			dev_warn(dsim->dev, "error rate is %lu under.\n",
+				(esc_clk_error_rate / 100));
+		}
+	} else {
+		exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
+			(DSIM_LANE_CLOCK | dsim->data_lane), 0);
+		exynos_mipi_dsi_set_esc_clk_prs(dsim, 0, 0);
+
+		/* disable escape clock. */
+		exynos_mipi_dsi_enable_byte_clock(dsim, 0);
+
+		if (byte_clk_sel == DSIM_PLL_OUT_DIV8)
+			exynos_mipi_dsi_pll_on(dsim, 0);
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
+{
+	dsim->state = DSIM_STATE_INIT;
+
+	switch (dsim->dsim_config->e_no_data_lane) {
+	case DSIM_DATA_LANE_1:
+		dsim->data_lane = DSIM_LANE_DATA0;
+		break;
+	case DSIM_DATA_LANE_2:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
+		break;
+	case DSIM_DATA_LANE_3:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+			DSIM_LANE_DATA2;
+		break;
+	case DSIM_DATA_LANE_4:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+			DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
+		break;
+	default:
+		dev_info(dsim->dev, "data lane is invalid.\n");
+		return -EINVAL;
+	};
+
+	exynos_mipi_dsi_sw_reset(dsim);
+	exynos_mipi_dsi_func_reset(dsim);
+
+	exynos_mipi_dsi_dp_dn_swap(dsim, 0);
+
+	return 0;
+}
+
+void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim)
+{
+	unsigned int src = 0;
+
+	src = (INTSRC_SFR_FIFO_EMPTY | INTSRC_RX_DATA_DONE);
+	exynos_mipi_dsi_set_interrupt(dsim, src, 1);
+
+	src = 0;
+	src = ~(INTMSK_RX_DONE | INTMSK_FIFO_EMPTY);
+	exynos_mipi_dsi_set_interrupt_mask(dsim, src, 1);
+}
+
+int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	/* enable only frame done interrupt */
+	exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
+
+	return 0;
+}
+
+void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+
+	/* consider Main display and Sub display. */
+
+	exynos_mipi_dsi_set_main_stand_by(dsim, enable);
+}
+
+int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
+	struct mipi_dsim_config *dsim_config)
+{
+	struct mipi_dsim_platform_data *dsim_pd;
+	struct fb_videomode *timing;
+
+	dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
+	timing = (struct fb_videomode *)dsim_pd->lcd_panel_info;
+
+	/* in case of VIDEO MODE (RGB INTERFACE), it sets polarities. */
+	if (dsim_config->e_interface == (u32) DSIM_VIDEO) {
+		if (dsim_config->auto_vertical_cnt == 0) {
+			exynos_mipi_dsi_set_main_disp_vporch(dsim,
+				dsim_config->cmd_allow,
+				timing->upper_margin,
+				timing->lower_margin);
+			exynos_mipi_dsi_set_main_disp_hporch(dsim,
+				timing->left_margin,
+				timing->right_margin);
+			exynos_mipi_dsi_set_main_disp_sync_area(dsim,
+				timing->vsync_len,
+				timing->hsync_len);
+		}
+	}
+
+	exynos_mipi_dsi_set_main_disp_resol(dsim, timing->xres,
+			timing->yres);
+
+	exynos_mipi_dsi_display_config(dsim, dsim_config);
+
+	dev_info(dsim->dev, "lcd panel ==> width = %d, height = %d\n",
+			timing->xres, timing->yres);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim)
+{
+	unsigned int time_out = 100;
+
+	switch (dsim->state) {
+	case DSIM_STATE_INIT:
+		exynos_mipi_dsi_init_fifo_pointer(dsim, 0x1f);
+
+		/* dsi configuration */
+		exynos_mipi_dsi_init_config(dsim);
+		exynos_mipi_dsi_enable_lane(dsim, DSIM_LANE_CLOCK, 1);
+		exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 1);
+
+		/* set clock configuration */
+		exynos_mipi_dsi_set_clock(dsim, dsim->dsim_config->e_byte_clk, 1);
+
+		/* check clock and data lane state are stop state */
+		while (!(exynos_mipi_dsi_is_lane_state(dsim))) {
+			time_out--;
+			if (time_out == 0) {
+				dev_err(dsim->dev,
+					"DSI Master is not stop state.\n");
+				dev_err(dsim->dev,
+					"Check initialization process\n");
+
+				return -EINVAL;
+			}
+		}
+		if (time_out != 0) {
+			dev_info(dsim->dev,
+				"DSI Master driver has been completed.\n");
+			dev_info(dsim->dev, "DSI Master state is stop state\n");
+		}
+
+		dsim->state = DSIM_STATE_STOP;
+
+		/* BTA sequence counters */
+		exynos_mipi_dsi_set_stop_state_counter(dsim,
+			dsim->dsim_config->stop_holding_cnt);
+		exynos_mipi_dsi_set_bta_timeout(dsim,
+			dsim->dsim_config->bta_timeout);
+		exynos_mipi_dsi_set_lpdr_timeout(dsim,
+			dsim->dsim_config->rx_timeout);
+
+		return 0;
+	default:
+		dev_info(dsim->dev, "DSI Master is already init.\n");
+		return 0;
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
+{
+	if (dsim->state != DSIM_STATE_STOP) {
+		dev_warn(dsim->dev, "DSIM is not in stop state.\n");
+		return 0;
+	}
+
+	if (dsim->e_clk_src == DSIM_EXT_CLK_BYPASS) {
+		dev_warn(dsim->dev, "clock source is external bypass.\n");
+		return 0;
+	}
+
+	dsim->state = DSIM_STATE_HSCLKEN;
+
+	 /* set LCDC and CPU transfer mode to HS. */
+	exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
+	exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
+	exynos_mipi_dsi_enable_hs_clock(dsim, 1);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int mode)
+{
+	if (mode) {
+		if (dsim->state != DSIM_STATE_HSCLKEN) {
+			dev_err(dsim->dev, "HS Clock lane is not enabled.\n");
+			return -EINVAL;
+		}
+
+		exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
+	} else {
+		if (dsim->state == DSIM_STATE_INIT || dsim->state ==
+			DSIM_STATE_ULPS) {
+			dev_err(dsim->dev,
+				"DSI Master is not STOP or HSDT state.\n");
+			return -EINVAL;
+		}
+
+		exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
+{
+	return _exynos_mipi_dsi_get_frame_done_status(dsim);
+}
+
+int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
+{
+	_exynos_mipi_dsi_clear_frame_done(dsim);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
+				unsigned int val)
+{
+	int try = TRY_FIFO_CLEAR;
+
+	exynos_mipi_dsi_sw_reset_release(dsim);
+	exynos_mipi_dsi_func_reset(dsim);
+
+	do {
+		if (exynos_mipi_dsi_get_sw_reset_release(dsim)) {
+			exynos_mipi_dsi_init_interrupt(dsim);
+			dev_dbg(dsim->dev, "reset release done.\n");
+			return 0;
+		}
+	} while (--try);
+
+	dev_err(dsim->dev, "failed to clear dsim fifo.\n");
+	return -EAGAIN;
+}
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("Samusung SoC MIPI-DSI common driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/exynos/exynos_mipi_dsi_common.h
new file mode 100644
index 0000000..4125522
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.h
@@ -0,0 +1,46 @@
+/* linux/drivers/video/exynos_mipi_dsi_common.h
+ *
+ * Header file for Samsung SoC MIPI-DSI common driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _EXYNOS_MIPI_DSI_COMMON_H
+#define _EXYNOS_MIPI_DSI_COMMON_H
+
+static DECLARE_COMPLETION(dsim_rd_comp);
+static DECLARE_COMPLETION(dsim_wr_comp);
+
+int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	const unsigned char *data0, unsigned int data_size);
+int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	unsigned int data0, unsigned int req_size, u8 *rx_buf);
+irqreturn_t exynos_mipi_dsi_interrupt_handler(int irq, void *dev_id);
+void exynos_mipi_dsi_init_interrupt(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable);
+int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
+			struct mipi_dsim_config *dsim_info);
+int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int mode);
+int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
+	unsigned int enable);
+int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
+
+extern struct fb_info *registered_fb[FB_MAX] __read_mostly;
+
+int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
+				unsigned int val);
+
+#endif /* _EXYNOS_MIPI_DSI_COMMON_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
new file mode 100644
index 0000000..0ef38ce
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
@@ -0,0 +1,618 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
+ *
+ * Samsung SoC MIPI-DSI lowlevel driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+
+#include <video/exynos_mipi_dsim.h>
+
+#include <mach/map.h>
+
+#include "exynos_mipi_dsi_regs.h"
+
+void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
+
+	reg |= DSIM_FUNCRST;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
+}
+
+void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_SWRST);
+
+	reg |= DSIM_SWRST;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SWRST);
+}
+
+void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	reg |= INTSRC_SW_RST_RELEASE;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim)
+{
+	return (readl(dsim->reg_base + EXYNOS_DSIM_INTSRC)) &
+			INTSRC_SW_RST_RELEASE;
+}
+
+unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_INTMSK);
+
+	return reg;
+}
+
+void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
+		unsigned int mode, unsigned int mask)
+{
+	unsigned int reg = 0;
+
+	if (mask)
+		reg |= mode;
+	else
+		reg &= ~mode;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTMSK);
+}
+
+void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
+		unsigned int cfg)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
+
+	writel(reg & ~(cfg), dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
+	mdelay(10);
+	reg |= cfg;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_FIFOCTRL);
+}
+
+/*
+ * this function set PLL P, M and S value in D-PHY
+ */
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+		unsigned int value)
+{
+	writel(DSIM_AFC_CTL(value), dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
+}
+
+void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+
+	reg &= ~DSIM_MAIN_STAND_BY;
+
+	if (enable)
+		reg |= DSIM_MAIN_STAND_BY;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+}
+
+void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
+	unsigned int width_resol, unsigned int height_resol)
+{
+	unsigned int reg;
+
+	/* standby should be set after configuration so set to not ready*/
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MDRESOL)) &
+		~(DSIM_MAIN_STAND_BY);
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+
+	reg &= ~((0x7ff << 16) | (0x7ff << 0));
+	reg |= DSIM_MAIN_VRESOL(height_resol) | DSIM_MAIN_HRESOL(width_resol);
+
+	reg |= DSIM_MAIN_STAND_BY;
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MDRESOL);
+}
+
+void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
+	unsigned int cmd_allow, unsigned int vfront, unsigned int vback)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MVPORCH)) &
+		~((DSIM_CMD_ALLOW_MASK) | (DSIM_STABLE_VFP_MASK) |
+		(DSIM_MAIN_VBP_MASK));
+
+	reg |= (DSIM_CMD_ALLOW_SHIFT(cmd_allow & 0xf) |
+		DSIM_STABLE_VFP_SHIFT(vfront & 0x7ff) |
+		DSIM_MAIN_VBP_SHIFT(vback & 0x7ff));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MVPORCH);
+}
+
+void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
+	unsigned int front, unsigned int back)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MHPORCH)) &
+		~((DSIM_MAIN_HFP_MASK) | (DSIM_MAIN_HBP_MASK));
+
+	reg |= DSIM_MAIN_HFP_SHIFT(front) | DSIM_MAIN_HBP_SHIFT(back);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MHPORCH);
+}
+
+void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
+	unsigned int vert, unsigned int hori)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_MSYNC)) &
+		~((DSIM_MAIN_VSA_MASK) | (DSIM_MAIN_HSA_MASK));
+
+	reg |= (DSIM_MAIN_VSA_SHIFT(vert & 0x3ff) |
+		DSIM_MAIN_HSA_SHIFT(hori));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_MSYNC);
+}
+
+void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
+	unsigned int vert, unsigned int hori)
+{
+	unsigned int reg;
+
+	reg = (readl(dsim->reg_base + EXYNOS_DSIM_SDRESOL)) &
+		~(DSIM_SUB_STANDY_MASK);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
+
+	reg &= ~(DSIM_SUB_VRESOL_MASK) | ~(DSIM_SUB_HRESOL_MASK);
+	reg |= (DSIM_SUB_VRESOL_SHIFT(vert & 0x7ff) |
+		DSIM_SUB_HRESOL_SHIFT(hori & 0x7ff));
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
+
+	reg |= DSIM_SUB_STANDY_SHIFT(1);
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_SDRESOL);
+}
+
+void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim)
+{
+	struct mipi_dsim_config *dsim_config = dsim->dsim_config;
+
+	unsigned int cfg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
+		~((1 << 28) | (0x1f << 20) | (0x3 << 5));
+
+	cfg =	((DSIM_AUTO_FLUSH(dsim_config->auto_flush)) |
+		(DSIM_EOT_DISABLE(dsim_config->eot_disable)) |
+		(DSIM_AUTO_MODE_SHIFT(dsim_config->auto_vertical_cnt)) |
+		(DSIM_HSE_MODE_SHIFT(dsim_config->hse)) |
+		(DSIM_HFP_MODE_SHIFT(dsim_config->hfp)) |
+		(DSIM_HBP_MODE_SHIFT(dsim_config->hbp)) |
+		(DSIM_HSA_MODE_SHIFT(dsim_config->hsa)) |
+		(DSIM_NUM_OF_DATALANE_SHIFT(dsim_config->e_no_data_lane)));
+
+	writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
+				struct mipi_dsim_config *dsim_config)
+{
+	u32 reg = (readl(dsim->reg_base + EXYNOS_DSIM_CONFIG)) &
+		~((0x3 << 26) | (1 << 25) | (0x3 << 18) | (0x7 << 12) |
+		(0x3 << 16) | (0x7 << 8));
+
+	if (dsim_config->e_interface == DSIM_VIDEO)
+		reg |= (1 << 25);
+	else if (dsim_config->e_interface == DSIM_COMMAND)
+		reg &= ~(1 << 25);
+	else {
+		dev_err(dsim->dev, "unknown lcd type.\n");
+		return;
+	}
+
+	/* main lcd */
+	reg |= ((u8) (dsim_config->e_burst_mode) & 0x3) << 26 |
+		((u8) (dsim_config->e_virtual_ch) & 0x3) << 18 |
+		((u8) (dsim_config->e_pixel_format) & 0x7) << 12;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
+	unsigned int enable)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_CONFIG);
+
+	if (enable)
+		reg |= DSIM_LANE_ENx(lane);
+	else
+		reg &= ~DSIM_LANE_ENx(lane);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+	unsigned int count)
+{
+	unsigned int cfg;
+
+	/* get the data lane number. */
+	cfg = DSIM_NUM_OF_DATALANE_SHIFT(count);
+
+	writel(cfg, dsim->reg_base + EXYNOS_DSIM_CONFIG);
+}
+
+void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
+	unsigned int afc_code)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
+
+	if (enable) {
+		reg |= (1 << 14);
+		reg &= ~(0x7 << 5);
+		reg |= (afc_code & 0x7) << 5;
+	} else
+		reg &= ~(1 << 14);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR);
+}
+
+void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_PLL_BYPASS_SHIFT(0x1));
+
+	reg |= DSIM_PLL_BYPASS_SHIFT(enable);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
+	unsigned int m, unsigned int s)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+
+	reg |= ((p & 0x3f) << 13) | ((m & 0x1ff) << 4) | ((s & 0x7) << 1);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
+		unsigned int freq_band)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(DSIM_FREQ_BAND_SHIFT(0x1f));
+
+	reg |= DSIM_FREQ_BAND_SHIFT(freq_band & 0x1f);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
+		unsigned int pre_divider, unsigned int main_divider,
+		unsigned int scaler)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(0x7ffff << 1);
+
+	reg |= (pre_divider & 0x3f) << 13 | (main_divider & 0x1ff) << 4 |
+		(scaler & 0x7) << 1;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
+	unsigned int lock_time)
+{
+	writel(lock_time, dsim->reg_base + EXYNOS_DSIM_PLLTMR);
+}
+
+void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim, unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(DSIM_PLL_EN_SHIFT(0x1));
+
+	reg |= DSIM_PLL_EN_SHIFT(enable & 0x1);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
+		unsigned int src)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_BYTE_CLK_SRC_SHIFT(0x3));
+
+	reg |= (DSIM_BYTE_CLK_SRC_SHIFT(src));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_BYTE_CLKEN_SHIFT(0x1));
+
+	reg |= DSIM_BYTE_CLKEN_SHIFT(enable);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
+		unsigned int enable, unsigned int prs_val)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_ESC_CLKEN_SHIFT(0x1) | 0xffff);
+
+	reg |= DSIM_ESC_CLKEN_SHIFT(enable);
+	if (enable)
+		reg |= prs_val;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
+		unsigned int lane_sel, unsigned int enable)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+
+	if (enable)
+		reg |= DSIM_LANE_ESC_CLKEN(lane_sel);
+	else
+
+		reg &= ~DSIM_LANE_ESC_CLKEN(lane_sel);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
+		~(DSIM_FORCE_STOP_STATE_SHIFT(0x1));
+
+	reg |= (DSIM_FORCE_STOP_STATE_SHIFT(enable & 0x1));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
+
+	/**
+	 * check clock and data lane states.
+	 * if MIPI-DSI controller was enabled at bootloader then
+	 * TX_READY_HS_CLK is enabled otherwise STOP_STATE_CLK.
+	 * so it should be checked for two case.
+	 */
+	if ((reg & DSIM_STOP_STATE_DAT(0xf)) &&
+			((reg & DSIM_STOP_STATE_CLK) ||
+			 (reg & DSIM_TX_READY_HS_CLK)))
+		return 1;
+
+	return 0;
+}
+
+void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
+		unsigned int cnt_val)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE)) &
+		~(DSIM_STOP_STATE_CNT_SHIFT(0x7ff));
+
+	reg |= (DSIM_STOP_STATE_CNT_SHIFT(cnt_val & 0x7ff));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
+		unsigned int timeout)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
+		~(DSIM_BTA_TOUT_SHIFT(0xff));
+
+	reg |= (DSIM_BTA_TOUT_SHIFT(timeout));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
+}
+
+void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
+		unsigned int timeout)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_TIMEOUT)) &
+		~(DSIM_LPDR_TOUT_SHIFT(0xffff));
+
+	reg |= (DSIM_LPDR_TOUT_SHIFT(timeout));
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_TIMEOUT);
+}
+
+void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int lp)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+
+	reg &= ~DSIM_CMD_LPDT_LP;
+
+	if (lp)
+		reg |= DSIM_CMD_LPDT_LP;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int lp)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+
+	reg &= ~DSIM_TX_LPDT_LP;
+
+	if (lp)
+		reg |= DSIM_TX_LPDT_LP;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_ESCMODE);
+}
+
+void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_CLKCTRL)) &
+		~(DSIM_TX_REQUEST_HSCLK_SHIFT(0x1));
+
+	reg |= DSIM_TX_REQUEST_HSCLK_SHIFT(enable);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_CLKCTRL);
+}
+
+void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
+		unsigned int swap_en)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
+
+	reg &= ~(0x3 << 0);
+	reg |= (swap_en & 0x3) << 0;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PHYACCHR1);
+}
+
+void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
+		unsigned int hs_zero)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(0xf << 28);
+
+	reg |= ((hs_zero & 0xf) << 28);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep)
+{
+	unsigned int reg = (readl(dsim->reg_base + EXYNOS_DSIM_PLLCTRL)) &
+		~(0x7 << 20);
+
+	reg |= ((prep & 0x7) << 20);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PLLCTRL);
+}
+
+unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim)
+{
+	return readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	reg |= src;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src, unsigned int enable)
+{
+	unsigned int reg = 0;
+
+	if (enable)
+		reg |= src;
+	else
+		reg &= ~src;
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_INTSRC);
+}
+
+unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	reg = readl(dsim->reg_base + EXYNOS_DSIM_STATUS);
+
+	return reg & (1 << 31) ? 1 : 0;
+}
+
+unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim)
+{
+	return readl(dsim->reg_base + EXYNOS_DSIM_FIFOCTRL) & ~(0x1f);
+}
+
+void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
+	unsigned int di, unsigned int data0, unsigned int data1)
+{
+	unsigned int reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
+}
+
+void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
+	unsigned int di, unsigned int data0)
+{
+	unsigned int reg = (data0 << 8) | (di << 0);
+
+	writel(reg, dsim->reg_base + EXYNOS_DSIM_PKTHDR);
+}
+
+unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim)
+{
+	return readl(dsim->reg_base + EXYNOS_DSIM_RXFIFO);
+}
+
+unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	return (reg & INTSRC_FRAME_DONE) ? 1 : 0;
+}
+
+void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = readl(dsim->reg_base + EXYNOS_DSIM_INTSRC);
+
+	writel(reg | INTSRC_FRAME_DONE, dsim->reg_base +
+		EXYNOS_DSIM_INTSRC);
+}
+
+void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
+		unsigned int tx_data)
+{
+	writel(tx_data, dsim->reg_base + EXYNOS_DSIM_PAYLOAD);
+}
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
new file mode 100644
index 0000000..8546070
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
@@ -0,0 +1,112 @@
+/* linux/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
+ *
+ * Header file for Samsung SoC MIPI-DSI lowlevel driver.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _EXYNOS_MIPI_DSI_LOWLEVEL_H
+#define _EXYNOS_MIPI_DSI_LOWLEVEL_H
+
+void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_sw_reset_release(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_get_sw_reset_release(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
+	unsigned int mode, unsigned int mask);
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+					unsigned int count);
+void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
+					unsigned int cfg);
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+				unsigned int value);
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+				unsigned int value);
+void exynos_mipi_dsi_set_main_stand_by(struct mipi_dsim_device *dsim,
+		unsigned int enable);
+void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
+		unsigned int width_resol, unsigned int height_resol);
+void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
+	unsigned int cmd_allow, unsigned int vfront, unsigned int vback);
+void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
+			unsigned int front, unsigned int back);
+void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
+				unsigned int vert, unsigned int hori);
+void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
+				unsigned int vert, unsigned int hori);
+void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
+				struct mipi_dsim_config *dsim_config);
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+				unsigned int count);
+void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim, unsigned int lane,
+				unsigned int enable);
+void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim, unsigned int enable,
+				unsigned int afc_code);
+void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+void exynos_mipi_dsi_set_pll_pms(struct mipi_dsim_device *dsim, unsigned int p,
+				unsigned int m, unsigned int s);
+void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
+				unsigned int freq_band);
+void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
+			unsigned int pre_divider, unsigned int main_divider,
+			unsigned int scaler);
+void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
+			unsigned int lock_time);
+void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim,
+					unsigned int enable);
+void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
+					unsigned int src);
+void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
+					unsigned int enable);
+void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
+				unsigned int enable, unsigned int prs_val);
+void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
+				unsigned int lane_sel, unsigned int enable);
+void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
+				unsigned int cnt_val);
+void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
+				unsigned int timeout);
+void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
+				unsigned int timeout);
+void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
+					unsigned int lp);
+void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
+					unsigned int lp);
+void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
+				unsigned int swap_en);
+void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
+				unsigned int hs_zero);
+void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep);
+unsigned int exynos_mipi_dsi_read_interrupt(struct mipi_dsim_device *dsim);
+unsigned int exynos_mipi_dsi_read_interrupt_mask(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src);
+void exynos_mipi_dsi_set_interrupt(struct mipi_dsim_device *dsim,
+					unsigned int src, unsigned int enable);
+unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim);
+unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim);
+unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
+void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim, unsigned int di,
+				unsigned int data0, unsigned int data1);
+void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
+		unsigned int tx_data);
+void exynos_mipi_dsi_rd_tx_header(struct mipi_dsim_device *dsim,
+		unsigned int data0, unsigned int data1);
+unsigned int exynos_mipi_dsi_rd_rx_fifo(struct mipi_dsim_device *dsim);
+
+#endif /* _EXYNOS_MIPI_DSI_LOWLEVEL_H */
diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/exynos/exynos_mipi_dsi_regs.h
new file mode 100644
index 0000000..4227106
--- /dev/null
+++ b/drivers/video/exynos/exynos_mipi_dsi_regs.h
@@ -0,0 +1,149 @@
+/* linux/driver/video/exynos/exynos_mipi_dsi_regs.h
+ *
+ * Register definition file for Samsung MIPI-DSIM driver
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _EXYNOS_MIPI_DSI_REGS_H
+#define _EXYNOS_MIPI_DSI_REGS_H
+
+#define EXYNOS_DSIM_STATUS		0x0	/* Status register */
+#define EXYNOS_DSIM_SWRST		0x4	/* Software reset register */
+#define EXYNOS_DSIM_CLKCTRL		0x8	/* Clock control register */
+#define EXYNOS_DSIM_TIMEOUT		0xc	/* Time out register */
+#define EXYNOS_DSIM_CONFIG		0x10	/* Configuration register */
+#define EXYNOS_DSIM_ESCMODE		0x14	/* Escape mode register */
+
+/* Main display image resolution register */
+#define EXYNOS_DSIM_MDRESOL		0x18
+#define EXYNOS_DSIM_MVPORCH		0x1c	/* Main display Vporch register */
+#define EXYNOS_DSIM_MHPORCH		0x20	/* Main display Hporch register */
+#define EXYNOS_DSIM_MSYNC		0x24	/* Main display sync area register */
+
+/* Sub display image resolution register */
+#define EXYNOS_DSIM_SDRESOL		0x28
+#define EXYNOS_DSIM_INTSRC		0x2c	/* Interrupt source register */
+#define EXYNOS_DSIM_INTMSK		0x30	/* Interrupt mask register */
+#define EXYNOS_DSIM_PKTHDR		0x34	/* Packet Header FIFO register */
+#define EXYNOS_DSIM_PAYLOAD		0x38	/* Payload FIFO register */
+#define EXYNOS_DSIM_RXFIFO		0x3c	/* Read FIFO register */
+#define EXYNOS_DSIM_FIFOTHLD		0x40	/* FIFO threshold level register */
+#define EXYNOS_DSIM_FIFOCTRL		0x44	/* FIFO status and control register */
+
+/* FIFO memory AC characteristic register */
+#define EXYNOS_DSIM_PLLCTRL		0x4c	/* PLL control register */
+#define EXYNOS_DSIM_PLLTMR		0x50	/* PLL timer register */
+#define EXYNOS_DSIM_PHYACCHR		0x54	/* D-PHY AC characteristic register */
+#define EXYNOS_DSIM_PHYACCHR1		0x58	/* D-PHY AC characteristic register1 */
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x)		(((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK		(1 << 8)
+#define DSIM_TX_READY_HS_CLK		(1 << 10)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST			(1 << 16)
+#define DSIM_SWRST			(1 << 0)
+
+/* EXYNOS_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT(x)		((x) << 0)
+#define DSIM_BTA_TOUT_SHIFT(x)		((x) << 16)
+
+/* EXYNOS_DSIM_CLKCTRL */
+#define DSIM_LANE_ESC_CLKEN(x)		(((x) & 0x1f) << 19)
+#define DSIM_BYTE_CLKEN_SHIFT(x)	((x) << 24)
+#define DSIM_BYTE_CLK_SRC_SHIFT(x)	((x) <<	25)
+#define DSIM_PLL_BYPASS_SHIFT(x)	((x) <<	27)
+#define DSIM_ESC_CLKEN_SHIFT(x)		((x) << 28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT(x)	((x) << 31)
+
+/* EXYNOS_DSIM_CONFIG */
+#define DSIM_LANE_ENx(x)		(((x) & 0x1f) << 0)
+#define DSIM_NUM_OF_DATALANE_SHIFT(x)	((x) << 5)
+#define DSIM_HSA_MODE_SHIFT(x)		((x) << 20)
+#define DSIM_HBP_MODE_SHIFT(x)		((x) << 21)
+#define DSIM_HFP_MODE_SHIFT(x)		((x) << 22)
+#define DSIM_HSE_MODE_SHIFT(x)		((x) << 23)
+#define DSIM_AUTO_MODE_SHIFT(x)		((x) << 24)
+#define DSIM_EOT_DISABLE(x)		((x) << 28)
+#define DSIM_AUTO_FLUSH(x)		((x) << 29)
+
+#define DSIM_NUM_OF_DATA_LANE(x)	((x) << DSIM_NUM_OF_DATALANE_SHIFT)
+
+/* EXYNOS_DSIM_ESCMODE */
+#define DSIM_TX_LPDT_LP			(1 << 6)
+#define DSIM_CMD_LPDT_LP		(1 << 7)
+#define DSIM_FORCE_STOP_STATE_SHIFT(x)	((x) << 20)
+#define DSIM_STOP_STATE_CNT_SHIFT(x)	((x) << 21)
+
+/* EXYNOS_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY		(1 << 31)
+#define DSIM_MAIN_VRESOL(x)		(((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x)		(((x) & 0X7ff) << 0)
+
+/* EXYNOS_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT(x)		((x) << 28)
+#define DSIM_STABLE_VFP_SHIFT(x)	((x) << 16)
+#define DSIM_MAIN_VBP_SHIFT(x)		((x) << 0)
+#define DSIM_CMD_ALLOW_MASK		(0xf << 28)
+#define DSIM_STABLE_VFP_MASK		(0x7ff << 16)
+#define DSIM_MAIN_VBP_MASK		(0x7ff << 0)
+
+/* EXYNOS_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT(x)		((x) << 16)
+#define DSIM_MAIN_HBP_SHIFT(x)		((x) << 0)
+#define DSIM_MAIN_HFP_MASK		((0xffff) << 16)
+#define DSIM_MAIN_HBP_MASK		((0xffff) << 0)
+
+/* EXYNOS_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT(x)		((x) << 22)
+#define DSIM_MAIN_HSA_SHIFT(x)		((x) << 0)
+#define DSIM_MAIN_VSA_MASK		((0x3ff) << 22)
+#define DSIM_MAIN_HSA_MASK		((0xffff) << 0)
+
+/* EXYNOS_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT(x)	((x) << 31)
+#define DSIM_SUB_VRESOL_SHIFT(x)	((x) << 16)
+#define DSIM_SUB_HRESOL_SHIFT(x)	((x) << 0)
+#define DSIM_SUB_STANDY_MASK		((0x1) << 31)
+#define DSIM_SUB_VRESOL_MASK		((0x7ff) << 16)
+#define DSIM_SUB_HRESOL_MASK		((0x7ff) << 0)
+
+/* EXYNOS_DSIM_INTSRC */
+#define INTSRC_PLL_STABLE		(1 << 31)
+#define INTSRC_SW_RST_RELEASE		(1 << 30)
+#define INTSRC_SFR_FIFO_EMPTY		(1 << 29)
+#define INTSRC_FRAME_DONE		(1 << 24)
+#define INTSRC_RX_DATA_DONE		(1 << 18)
+
+/* EXYNOS_DSIM_INTMSK */
+#define INTMSK_FIFO_EMPTY		(1 << 29)
+#define INTMSK_BTA			(1 << 25)
+#define INTMSK_FRAME_DONE		(1 << 24)
+#define INTMSK_RX_TIMEOUT		(1 << 21)
+#define INTMSK_BTA_TIMEOUT		(1 << 20)
+#define INTMSK_RX_DONE			(1 << 18)
+#define INTMSK_RX_TE			(1 << 17)
+#define INTMSK_RX_ACK			(1 << 16)
+#define INTMSK_RX_ECC_ERR		(1 << 15)
+#define INTMSK_RX_CRC_ERR		(1 << 14)
+
+/* EXYNOS_DSIM_FIFOCTRL */
+#define SFR_HEADER_EMPTY		(1 << 22)
+
+/* EXYNOS_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)
+
+/* EXYNOS_DSIM_PLLCTRL */
+#define DSIM_PLL_EN_SHIFT(x)		((x) << 23)
+#define DSIM_FREQ_BAND_SHIFT(x)		((x) << 24)
+
+#endif /* _EXYNOS_MIPI_DSI_REGS_H */
diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
new file mode 100644
index 0000000..4aa9ac6
--- /dev/null
+++ b/drivers/video/exynos/s6e8ax0.c
@@ -0,0 +1,898 @@
+/* linux/drivers/video/exynos/s6e8ax0.c
+ *
+ * MIPI-DSI based s6e8ax0 AMOLED lcd 4.65 inch panel driver.
+ *
+ * Inki Dae, <inki.dae@samsung.com>
+ * Donghwa Lee, <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/lcd.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+#include <video/exynos_mipi_dsim.h>
+
+#define LDI_MTP_LENGTH		24
+#define DSIM_PM_STABLE_TIME	10
+#define MIN_BRIGHTNESS		0
+#define MAX_BRIGHTNESS		24
+#define GAMMA_TABLE_COUNT	26
+
+#define POWER_IS_ON(pwr)	((pwr) == FB_BLANK_UNBLANK)
+#define POWER_IS_OFF(pwr)	((pwr) == FB_BLANK_POWERDOWN)
+#define POWER_IS_NRM(pwr)	((pwr) == FB_BLANK_NORMAL)
+
+#define lcd_to_master(a)	(a->dsim_dev->master)
+#define lcd_to_master_ops(a)	((lcd_to_master(a))->master_ops)
+
+enum {
+	DSIM_NONE_STATE = 0,
+	DSIM_RESUME_COMPLETE = 1,
+	DSIM_FRAME_DONE = 2,
+};
+
+struct s6e8ax0 {
+	struct device	*dev;
+	unsigned int			power;
+	unsigned int			id;
+	unsigned int			gamma;
+	unsigned int			acl_enable;
+	unsigned int			cur_acl;
+
+	struct lcd_device	*ld;
+	struct backlight_device	*bd;
+
+	struct mipi_dsim_lcd_device	*dsim_dev;
+	struct lcd_platform_data	*ddi_pd;
+	struct mutex			lock;
+	bool  enabled;
+};
+
+
+static struct regulator_bulk_data supplies[] = {
+	{ .supply = "vdd3", },
+	{ .supply = "vci", },
+};
+
+static void s6e8ax0_regulator_enable(struct s6e8ax0 *lcd)
+{
+	int ret = 0;
+	struct lcd_platform_data *pd = NULL;
+
+	pd = lcd->ddi_pd;
+	mutex_lock(&lcd->lock);
+	if (!lcd->enabled) {
+		ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
+		if (ret)
+			goto out;
+
+		lcd->enabled = true;
+	}
+	msleep(pd->power_on_delay);
+out:
+	mutex_unlock(&lcd->lock);
+}
+
+static void s6e8ax0_regulator_disable(struct s6e8ax0 *lcd)
+{
+	int ret = 0;
+
+	mutex_lock(&lcd->lock);
+	if (lcd->enabled) {
+		ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+		if (ret)
+			goto out;
+
+		lcd->enabled = false;
+	}
+out:
+	mutex_unlock(&lcd->lock);
+}
+
+static const unsigned char s6e8ax0_22_gamma_30[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xf5, 0x00, 0xff, 0xad, 0xaf,
+	0xbA, 0xc3, 0xd8, 0xc5, 0x9f, 0xc6, 0x9e, 0xc1, 0xdc, 0xc0,
+	0x00, 0x61, 0x00, 0x5a, 0x00, 0x74,
+};
+
+static const unsigned char s6e8ax0_22_gamma_50[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xe8, 0x1f, 0xf7, 0xad, 0xc0,
+	0xb5, 0xc4, 0xdc, 0xc4, 0x9e, 0xc6, 0x9c, 0xbb, 0xd8, 0xbb,
+	0x00, 0x70, 0x00, 0x68, 0x00, 0x86,
+};
+
+static const unsigned char s6e8ax0_22_gamma_60[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xde, 0x1f, 0xef, 0xad, 0xc4,
+	0xb3, 0xc3, 0xdd, 0xc4, 0x9e, 0xc6, 0x9c, 0xbc, 0xd6, 0xba,
+	0x00, 0x75, 0x00, 0x6e, 0x00, 0x8d,
+};
+
+static const unsigned char s6e8ax0_22_gamma_70[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xd8, 0x1f, 0xe7, 0xaf, 0xc8,
+	0xb4, 0xc4, 0xdd, 0xc3, 0x9d, 0xc6, 0x9c, 0xbb, 0xd6, 0xb9,
+	0x00, 0x7a, 0x00, 0x72, 0x00, 0x93,
+};
+
+static const unsigned char s6e8ax0_22_gamma_80[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xc9, 0x1f, 0xde, 0xae, 0xc9,
+	0xb1, 0xc3, 0xdd, 0xc2, 0x9d, 0xc5, 0x9b, 0xbc, 0xd6, 0xbb,
+	0x00, 0x7f, 0x00, 0x77, 0x00, 0x99,
+};
+
+static const unsigned char s6e8ax0_22_gamma_90[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xc7, 0x1f, 0xd9, 0xb0, 0xcc,
+	0xb2, 0xc3, 0xdc, 0xc1, 0x9c, 0xc6, 0x9c, 0xbc, 0xd4, 0xb9,
+	0x00, 0x83, 0x00, 0x7b, 0x00, 0x9e,
+};
+
+static const unsigned char s6e8ax0_22_gamma_100[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xbd, 0x80, 0xcd, 0xba, 0xce,
+	0xb3, 0xc4, 0xde, 0xc3, 0x9c, 0xc4, 0x9, 0xb8, 0xd3, 0xb6,
+	0x00, 0x88, 0x00, 0x80, 0x00, 0xa5,
+};
+
+static const unsigned char s6e8ax0_22_gamma_120[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb9, 0x95, 0xc8, 0xb1, 0xcf,
+	0xb2, 0xc6, 0xdf, 0xc5, 0x9b, 0xc3, 0x99, 0xb6, 0xd2, 0xb6,
+	0x00, 0x8f, 0x00, 0x86, 0x00, 0xac,
+};
+
+static const unsigned char s6e8ax0_22_gamma_130[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb7, 0xa0, 0xc7, 0xb1, 0xd0,
+	0xb2, 0xc4, 0xdd, 0xc3, 0x9a, 0xc3, 0x98, 0xb6, 0xd0, 0xb4,
+	0x00, 0x92, 0x00, 0x8a, 0x00, 0xb1,
+};
+
+static const unsigned char s6e8ax0_22_gamma_140[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb7, 0xa0, 0xc5, 0xb2, 0xd0,
+	0xb3, 0xc3, 0xde, 0xc3, 0x9b, 0xc2, 0x98, 0xb6, 0xd0, 0xb4,
+	0x00, 0x95, 0x00, 0x8d, 0x00, 0xb5,
+};
+
+static const unsigned char s6e8ax0_22_gamma_150[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xa0, 0xc2, 0xb2, 0xd0,
+	0xb2, 0xc1, 0xdd, 0xc2, 0x9b, 0xc2, 0x98, 0xb4, 0xcf, 0xb1,
+	0x00, 0x99, 0x00, 0x90, 0x00, 0xba,
+};
+
+static const unsigned char s6e8ax0_22_gamma_160[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xa5, 0xbf, 0xb0, 0xd0,
+	0xb1, 0xc3, 0xde, 0xc2, 0x99, 0xc1, 0x97, 0xb4, 0xce, 0xb1,
+	0x00, 0x9c, 0x00, 0x93, 0x00, 0xbe,
+};
+
+static const unsigned char s6e8ax0_22_gamma_170[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb5, 0xbf, 0xb1, 0xd1,
+	0xb1, 0xc3, 0xde, 0xc3, 0x99, 0xc0, 0x96, 0xb4, 0xce, 0xb1,
+	0x00, 0x9f, 0x00, 0x96, 0x00, 0xc2,
+};
+
+static const unsigned char s6e8ax0_22_gamma_180[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb7, 0xbe, 0xb3, 0xd2,
+	0xb3, 0xc3, 0xde, 0xc2, 0x97, 0xbf, 0x95, 0xb4, 0xcd, 0xb1,
+	0x00, 0xa2, 0x00, 0x99, 0x00, 0xc5,
+};
+
+static const unsigned char s6e8ax0_22_gamma_190[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb9, 0xbe, 0xb2, 0xd2,
+	0xb2, 0xc3, 0xdd, 0xc3, 0x98, 0xbf, 0x95, 0xb2, 0xcc, 0xaf,
+	0x00, 0xa5, 0x00, 0x9c, 0x00, 0xc9,
+};
+
+static const unsigned char s6e8ax0_22_gamma_200[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xaf, 0xb9, 0xbc, 0xb2, 0xd2,
+	0xb1, 0xc4, 0xdd, 0xc3, 0x97, 0xbe, 0x95, 0xb1, 0xcb, 0xae,
+	0x00, 0xa8, 0x00, 0x9f, 0x00, 0xcd,
+};
+
+static const unsigned char s6e8ax0_22_gamma_210[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc1, 0xbd, 0xb1, 0xd1,
+	0xb1, 0xc2, 0xde, 0xc2, 0x97, 0xbe, 0x94, 0xB0, 0xc9, 0xad,
+	0x00, 0xae, 0x00, 0xa4, 0x00, 0xd4,
+};
+
+static const unsigned char s6e8ax0_22_gamma_220[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc7, 0xbd, 0xb1, 0xd1,
+	0xb1, 0xc2, 0xdd, 0xc2, 0x97, 0xbd, 0x94, 0xb0, 0xc9, 0xad,
+	0x00, 0xad, 0x00, 0xa2, 0x00, 0xd3,
+};
+
+static const unsigned char s6e8ax0_22_gamma_230[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xc3, 0xbd, 0xb2, 0xd1,
+	0xb1, 0xc3, 0xdd, 0xc1, 0x96, 0xbd, 0x94, 0xb0, 0xc9, 0xad,
+	0x00, 0xb0, 0x00, 0xa7, 0x00, 0xd7,
+};
+
+static const unsigned char s6e8ax0_22_gamma_240[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb1, 0xcb, 0xbd, 0xb1, 0xd2,
+	0xb1, 0xc3, 0xdD, 0xc2, 0x95, 0xbd, 0x93, 0xaf, 0xc8, 0xab,
+	0x00, 0xb3, 0x00, 0xa9, 0x00, 0xdb,
+};
+
+static const unsigned char s6e8ax0_22_gamma_250[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xcc, 0xbe, 0xb0, 0xd2,
+	0xb0, 0xc3, 0xdD, 0xc2, 0x94, 0xbc, 0x92, 0xae, 0xc8, 0xab,
+	0x00, 0xb6, 0x00, 0xab, 0x00, 0xde,
+};
+
+static const unsigned char s6e8ax0_22_gamma_260[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb3, 0xd0, 0xbe, 0xaf, 0xd1,
+	0xaf, 0xc2, 0xdd, 0xc1, 0x96, 0xbc, 0x93, 0xaf, 0xc8, 0xac,
+	0x00, 0xb7, 0x00, 0xad, 0x00, 0xe0,
+};
+
+static const unsigned char s6e8ax0_22_gamma_270[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb2, 0xcF, 0xbd, 0xb0, 0xd2,
+	0xaf, 0xc2, 0xdc, 0xc1, 0x95, 0xbd, 0x93, 0xae, 0xc6, 0xaa,
+	0x00, 0xba, 0x00, 0xb0, 0x00, 0xe4,
+};
+
+static const unsigned char s6e8ax0_22_gamma_280[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb2, 0xd0, 0xbd, 0xaf, 0xd0,
+	0xad, 0xc4, 0xdd, 0xc3, 0x95, 0xbd, 0x93, 0xac, 0xc5, 0xa9,
+	0x00, 0xbd, 0x00, 0xb2, 0x00, 0xe7,
+};
+
+static const unsigned char s6e8ax0_22_gamma_300[] = {
+	0xfa, 0x01, 0x60, 0x10, 0x60, 0xb5, 0xd3, 0xbd, 0xb1, 0xd2,
+	0xb0, 0xc0, 0xdc, 0xc0, 0x94, 0xba, 0x91, 0xac, 0xc5, 0xa9,
+	0x00, 0xc2, 0x00, 0xb7, 0x00, 0xed,
+};
+
+static const unsigned char *s6e8ax0_22_gamma_table[] = {
+	s6e8ax0_22_gamma_30,
+	s6e8ax0_22_gamma_50,
+	s6e8ax0_22_gamma_60,
+	s6e8ax0_22_gamma_70,
+	s6e8ax0_22_gamma_80,
+	s6e8ax0_22_gamma_90,
+	s6e8ax0_22_gamma_100,
+	s6e8ax0_22_gamma_120,
+	s6e8ax0_22_gamma_130,
+	s6e8ax0_22_gamma_140,
+	s6e8ax0_22_gamma_150,
+	s6e8ax0_22_gamma_160,
+	s6e8ax0_22_gamma_170,
+	s6e8ax0_22_gamma_180,
+	s6e8ax0_22_gamma_190,
+	s6e8ax0_22_gamma_200,
+	s6e8ax0_22_gamma_210,
+	s6e8ax0_22_gamma_220,
+	s6e8ax0_22_gamma_230,
+	s6e8ax0_22_gamma_240,
+	s6e8ax0_22_gamma_250,
+	s6e8ax0_22_gamma_260,
+	s6e8ax0_22_gamma_270,
+	s6e8ax0_22_gamma_280,
+	s6e8ax0_22_gamma_300,
+};
+
+static void s6e8ax0_panel_cond(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+
+	static const unsigned char data_to_send[] = {
+		0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c, 0x7d,
+		0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08,
+		0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xc0,
+		0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc1, 0xff, 0xff, 0xc8
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_cond(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf2, 0x80, 0x03, 0x0d
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+/* Gamma 2.2 Setting (200cd, 7500K, 10MPCD) */
+static void s6e8ax0_gamma_cond(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	unsigned int gamma = lcd->bd->props.brightness;
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+			s6e8ax0_22_gamma_table[gamma],
+			GAMMA_TABLE_COUNT);
+}
+
+static void s6e8ax0_gamma_update(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf7, 0x03
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE_PARAM, data_to_send,
+		ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond1(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xd1, 0xfe, 0x80, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x40,
+		0x0d, 0x00, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond2(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0,
+		0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond3(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe1, 0x10, 0x1c, 0x17, 0x08, 0x1d
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond4(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe2, 0xed, 0x07, 0xc3, 0x13, 0x0d, 0x03
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond5(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x19, 0x33, 0x02
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+static void s6e8ax0_etc_cond6(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe3, 0x40
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE_PARAM,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_cond7(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xe4, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_elvss_set(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xb1, 0x04, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_elvss_nvm_set(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xd9, 0x5c, 0x20, 0x0c, 0x0f, 0x41, 0x00, 0x10, 0x11,
+		0x12, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcb, 0xed,
+		0x64, 0xaf
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_sleep_in(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x10, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_sleep_out(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x11, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_on(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x29, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_off(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0x28, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_apply_level2_key(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xf0, 0x5a, 0x5a
+	};
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_acl_on(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xc0, 0x01
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_acl_off(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	static const unsigned char data_to_send[] = {
+		0xc0, 0x00
+	};
+
+	ops->cmd_write(lcd_to_master(lcd),
+		MIPI_DSI_DCS_SHORT_WRITE,
+		data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+/* Full white 50% reducing setting */
+static void s6e8ax0_acl_ctrl_set(struct s6e8ax0 *lcd)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	/* Full white 50% reducing setting */
+	static const unsigned char cutoff_50[] = {
+		0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
+		0x00, 0x00, 0x04, 0xff,	0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x08, 0x0f, 0x16, 0x1d, 0x24, 0x2a, 0x31, 0x38,
+		0x3f, 0x46
+	};
+	/* Full white 45% reducing setting */
+	static const unsigned char cutoff_45[] = {
+		0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
+		0x00, 0x00, 0x04, 0xff,	0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x07, 0x0d, 0x13, 0x19, 0x1f, 0x25, 0x2b, 0x31,
+		0x37, 0x3d
+	};
+	/* Full white 40% reducing setting */
+	static const unsigned char cutoff_40[] = {
+		0xc1, 0x47, 0x53, 0x13, 0x53, 0x00, 0x00, 0x02, 0xcf,
+		0x00, 0x00, 0x04, 0xff,	0x00, 0x00, 0x00, 0x00, 0x00,
+		0x01, 0x06, 0x0c, 0x11, 0x16, 0x1c, 0x21, 0x26, 0x2b,
+		0x31, 0x36
+	};
+
+	if (lcd->acl_enable) {
+		if (lcd->cur_acl == 0) {
+			if (lcd->gamma == 0 || lcd->gamma == 1) {
+				s6e8ax0_acl_off(lcd);
+				dev_dbg(&lcd->ld->dev,
+					"cur_acl=%d\n", lcd->cur_acl);
+			} else
+				s6e8ax0_acl_on(lcd);
+		}
+		switch (lcd->gamma) {
+		case 0: /* 30cd */
+			s6e8ax0_acl_off(lcd);
+			lcd->cur_acl = 0;
+			break;
+		case 1 ... 3: /* 50cd ~ 90cd */
+			ops->cmd_write(lcd_to_master(lcd),
+				MIPI_DSI_DCS_LONG_WRITE,
+				cutoff_40,
+				ARRAY_SIZE(cutoff_40));
+			lcd->cur_acl = 40;
+			break;
+		case 4 ... 7: /* 120cd ~ 210cd */
+			ops->cmd_write(lcd_to_master(lcd),
+				MIPI_DSI_DCS_LONG_WRITE,
+				cutoff_45,
+				ARRAY_SIZE(cutoff_45));
+			lcd->cur_acl = 45;
+			break;
+		case 8 ... 10: /* 220cd ~ 300cd */
+			ops->cmd_write(lcd_to_master(lcd),
+				MIPI_DSI_DCS_LONG_WRITE,
+				cutoff_50,
+				ARRAY_SIZE(cutoff_50));
+			lcd->cur_acl = 50;
+			break;
+		default:
+			break;
+		}
+	} else {
+		s6e8ax0_acl_off(lcd);
+		lcd->cur_acl = 0;
+		dev_dbg(&lcd->ld->dev, "cur_acl = %d\n", lcd->cur_acl);
+	}
+}
+
+static void s6e8ax0_read_id(struct s6e8ax0 *lcd, u8 *mtp_id)
+{
+	unsigned int ret;
+	unsigned int addr = 0xd1;	/* MTP ID */
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+
+	ret = ops->cmd_read(lcd_to_master(lcd),
+			MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM,
+			addr, 3, mtp_id);
+}
+
+static int s6e8ax0_panel_init(struct s6e8ax0 *lcd)
+{
+	s6e8ax0_apply_level2_key(lcd);
+	s6e8ax0_sleep_out(lcd);
+	msleep(1);
+	s6e8ax0_panel_cond(lcd);
+	s6e8ax0_display_cond(lcd);
+	s6e8ax0_gamma_cond(lcd);
+	s6e8ax0_gamma_update(lcd);
+
+	s6e8ax0_etc_cond1(lcd);
+	s6e8ax0_etc_cond2(lcd);
+	s6e8ax0_etc_cond3(lcd);
+	s6e8ax0_etc_cond4(lcd);
+	s6e8ax0_etc_cond5(lcd);
+	s6e8ax0_etc_cond6(lcd);
+	s6e8ax0_etc_cond7(lcd);
+
+	s6e8ax0_elvss_nvm_set(lcd);
+	s6e8ax0_elvss_set(lcd);
+
+	s6e8ax0_acl_ctrl_set(lcd);
+	s6e8ax0_acl_on(lcd);
+
+	/* if ID3 value is not 33h, branch private elvss mode */
+	msleep(lcd->ddi_pd->power_on_delay);
+
+	return 0;
+}
+
+static int s6e8ax0_update_gamma_ctrl(struct s6e8ax0 *lcd, int brightness)
+{
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+
+	ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
+			s6e8ax0_22_gamma_table[brightness],
+			ARRAY_SIZE(s6e8ax0_22_gamma_table));
+
+	/* update gamma table. */
+	s6e8ax0_gamma_update(lcd);
+	lcd->gamma = brightness;
+
+	return 0;
+}
+
+static int s6e8ax0_gamma_ctrl(struct s6e8ax0 *lcd, int gamma)
+{
+	s6e8ax0_update_gamma_ctrl(lcd, gamma);
+
+	return 0;
+}
+
+static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+{
+	struct s6e8ax0 *lcd = lcd_get_data(ld);
+	struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+	int ret = 0;
+
+	if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+			power != FB_BLANK_NORMAL) {
+		dev_err(lcd->dev, "power value should be 0, 1 or 4.\n");
+		return -EINVAL;
+	}
+
+	if ((power == FB_BLANK_UNBLANK) && ops->set_blank_mode) {
+		/* LCD power on */
+		if ((POWER_IS_ON(power) && POWER_IS_OFF(lcd->power))
+			|| (POWER_IS_ON(power) && POWER_IS_NRM(lcd->power))) {
+			ret = ops->set_blank_mode(lcd_to_master(lcd), power);
+			if (!ret && lcd->power != power)
+				lcd->power = power;
+		}
+	} else if ((power == FB_BLANK_POWERDOWN) && ops->set_early_blank_mode) {
+		/* LCD power off */
+		if ((POWER_IS_OFF(power) && POWER_IS_ON(lcd->power)) ||
+		(POWER_IS_ON(lcd->power) && POWER_IS_NRM(power))) {
+			ret = ops->set_early_blank_mode(lcd_to_master(lcd),
+							power);
+			if (!ret && lcd->power != power)
+				lcd->power = power;
+		}
+	}
+
+	return ret;
+}
+
+static int s6e8ax0_get_power(struct lcd_device *ld)
+{
+	struct s6e8ax0 *lcd = lcd_get_data(ld);
+
+	return lcd->power;
+}
+
+static int s6e8ax0_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+static int s6e8ax0_set_brightness(struct backlight_device *bd)
+{
+	int ret = 0, brightness = bd->props.brightness;
+	struct s6e8ax0 *lcd = bl_get_data(bd);
+
+	if (brightness < MIN_BRIGHTNESS ||
+		brightness > bd->props.max_brightness) {
+		dev_err(lcd->dev, "lcd brightness should be %d to %d.\n",
+			MIN_BRIGHTNESS, MAX_BRIGHTNESS);
+		return -EINVAL;
+	}
+
+	ret = s6e8ax0_gamma_ctrl(lcd, brightness);
+	if (ret) {
+		dev_err(&bd->dev, "lcd brightness setting failed.\n");
+		return -EIO;
+	}
+
+	return ret;
+}
+
+static struct lcd_ops s6e8ax0_lcd_ops = {
+	.set_power = s6e8ax0_set_power,
+	.get_power = s6e8ax0_get_power,
+};
+
+static const struct backlight_ops s6e8ax0_backlight_ops = {
+	.get_brightness = s6e8ax0_get_brightness,
+	.update_status = s6e8ax0_set_brightness,
+};
+
+static void s6e8ax0_power_on(struct mipi_dsim_lcd_device *dsim_dev, int power)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	msleep(lcd->ddi_pd->power_on_delay);
+
+	/* lcd power on */
+	if (power)
+		s6e8ax0_regulator_enable(lcd);
+	else
+		s6e8ax0_regulator_disable(lcd);
+
+	msleep(lcd->ddi_pd->reset_delay);
+
+	/* lcd reset */
+	if (lcd->ddi_pd->reset)
+		lcd->ddi_pd->reset(lcd->ld);
+	msleep(5);
+}
+
+static void s6e8ax0_set_sequence(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	s6e8ax0_panel_init(lcd);
+	s6e8ax0_display_on(lcd);
+
+	lcd->power = FB_BLANK_UNBLANK;
+}
+
+static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd;
+	int ret;
+	u8 mtp_id[3] = {0, };
+
+	lcd = kzalloc(sizeof(struct s6e8ax0), GFP_KERNEL);
+	if (!lcd) {
+		dev_err(&dsim_dev->dev, "failed to allocate s6e8ax0 structure.\n");
+		return -ENOMEM;
+	}
+
+	lcd->dsim_dev = dsim_dev;
+	lcd->ddi_pd = (struct lcd_platform_data *)dsim_dev->platform_data;
+	lcd->dev = &dsim_dev->dev;
+
+	mutex_init(&lcd->lock);
+
+	ret = regulator_bulk_get(lcd->dev, ARRAY_SIZE(supplies), supplies);
+	if (ret) {
+		dev_err(lcd->dev, "Failed to get regulators: %d\n", ret);
+		goto err_lcd_register;
+	}
+
+	lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd,
+			&s6e8ax0_lcd_ops);
+	if (IS_ERR(lcd->ld)) {
+		dev_err(lcd->dev, "failed to register lcd ops.\n");
+		ret = PTR_ERR(lcd->ld);
+		goto err_lcd_register;
+	}
+
+	lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd,
+			&s6e8ax0_backlight_ops, NULL);
+	if (IS_ERR(lcd->bd)) {
+		dev_err(lcd->dev, "failed to register backlight ops.\n");
+		ret = PTR_ERR(lcd->bd);
+		goto err_backlight_register;
+	}
+
+	lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+	lcd->bd->props.brightness = MAX_BRIGHTNESS;
+
+	s6e8ax0_read_id(lcd, mtp_id);
+	if (mtp_id[0] == 0x00)
+		dev_err(lcd->dev, "read id failed\n");
+
+	dev_info(lcd->dev, "Read ID : %x, %x, %x\n",
+			mtp_id[0], mtp_id[1], mtp_id[2]);
+
+	if (mtp_id[2] == 0x33)
+		dev_info(lcd->dev,
+			"ID-3 is 0xff does not support dynamic elvss\n");
+	else
+		dev_info(lcd->dev,
+			"ID-3 is 0x%x support dynamic elvss\n", mtp_id[2]);
+
+	lcd->acl_enable = 1;
+	lcd->cur_acl = 0;
+
+	dev_set_drvdata(&dsim_dev->dev, lcd);
+
+	dev_dbg(lcd->dev, "probed s6e8ax0 panel driver.\n");
+
+	return 0;
+
+err_backlight_register:
+	lcd_device_unregister(lcd->ld);
+
+err_lcd_register:
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+	kfree(lcd);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int s6e8ax0_suspend(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	s6e8ax0_sleep_in(lcd);
+	msleep(lcd->ddi_pd->power_off_delay);
+	s6e8ax0_display_off(lcd);
+
+	s6e8ax0_regulator_disable(lcd);
+
+	return 0;
+}
+
+static int s6e8ax0_resume(struct mipi_dsim_lcd_device *dsim_dev)
+{
+	struct s6e8ax0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+
+	s6e8ax0_sleep_out(lcd);
+	msleep(lcd->ddi_pd->power_on_delay);
+
+	s6e8ax0_regulator_enable(lcd);
+	s6e8ax0_set_sequence(dsim_dev);
+
+	return 0;
+}
+#else
+#define s6e8ax0_suspend		NULL
+#define s6e8ax0_resume		NULL
+#endif
+
+static struct mipi_dsim_lcd_driver s6e8ax0_dsim_ddi_driver = {
+	.name = "s6e8ax0",
+	.id = -1,
+
+	.power_on = s6e8ax0_power_on,
+	.set_sequence = s6e8ax0_set_sequence,
+	.probe = s6e8ax0_probe,
+	.suspend = s6e8ax0_suspend,
+	.resume = s6e8ax0_resume,
+};
+
+static int s6e8ax0_init(void)
+{
+	exynos_mipi_dsi_register_lcd_driver(&s6e8ax0_dsim_ddi_driver);
+
+	return 0;
+}
+
+static void s6e8ax0_exit(void)
+{
+	return;
+}
+
+module_init(s6e8ax0_init);
+module_exit(s6e8ax0_exit);
+
+MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
+MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("MIPI-DSI based s6e8ax0 AMOLED LCD Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/exynos/s6e8ax0.h b/drivers/video/exynos/s6e8ax0.h
new file mode 100644
index 0000000..1f1b270
--- /dev/null
+++ b/drivers/video/exynos/s6e8ax0.h
@@ -0,0 +1,21 @@
+/* linux/drivers/video/backlight/s6e8ax0.h
+ *
+ * MIPI-DSI based s6e8ax0 AMOLED LCD Panel definitions.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Inki Dae, <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _S6E8AX0_H
+#define _S6E8AX0_H
+
+extern void s6e8ax0_init(void);
+
+#endif
+
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index ac9141b..c6ce416 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 	if (ret)
 		return -EINVAL;
 
+	unlink_framebuffer(fb_info);
 	if (fb_info->pixmap.addr &&
 	    (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
 		kfree(fb_info->pixmap.addr);
@@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 	registered_fb[i] = NULL;
 	num_registered_fb--;
 	fb_cleanup_device(fb_info);
-	device_destroy(fb_class, MKDEV(FB_MAJOR, i));
 	event.info = fb_info;
 	fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
 
@@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 	return 0;
 }
 
+int unlink_framebuffer(struct fb_info *fb_info)
+{
+	int i;
+
+	i = fb_info->node;
+	if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
+		return -EINVAL;
+
+	if (fb_info->dev) {
+		device_destroy(fb_class, MKDEV(FB_MAJOR, i));
+		fb_info->dev = NULL;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(unlink_framebuffer);
+
 void remove_conflicting_framebuffers(struct apertures_struct *a,
 				     const char *name, bool primary)
 {
diff --git a/drivers/video/i740_reg.h b/drivers/video/i740_reg.h
new file mode 100644
index 0000000..91bac76
--- /dev/null
+++ b/drivers/video/i740_reg.h
@@ -0,0 +1,309 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin@precisioninsight.com>
+ */
+
+/* I/O register offsets */
+#define SRX VGA_SEQ_I
+#define GRX VGA_GFX_I
+#define ARX VGA_ATT_IW
+#define XRX 0x3D6
+#define MRX 0x3D2
+
+/* VGA Color Palette Registers */
+#define DACMASK		0x3C6
+#define DACSTATE	0x3C7
+#define DACRX		0x3C7
+#define DACWX		0x3C8
+#define DACDATA		0x3C9
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI		0x0C
+#define START_ADDR_LO		0x0D
+#define VERT_SYNC_END		0x11
+#define EXT_VERT_TOTAL		0x30
+#define EXT_VERT_DISPLAY	0x31
+#define EXT_VERT_SYNC_START	0x32
+#define EXT_VERT_BLANK_START	0x33
+#define EXT_HORIZ_TOTAL		0x35
+#define EXT_HORIZ_BLANK		0x39
+#define EXT_START_ADDR		0x40
+#define EXT_START_ADDR_ENABLE	0x80
+#define EXT_OFFSET		0x41
+#define EXT_START_ADDR_HI	0x42
+#define INTERLACE_CNTL		0x70
+#define INTERLACE_ENABLE	0x80
+#define INTERLACE_DISABLE	0x00
+
+/* Miscellaneous Output Register */
+#define MSR_R		0x3CC
+#define MSR_W		0x3C2
+#define IO_ADDR_SELECT	0x01
+
+#define MDA_BASE	0x3B0
+#define CGA_BASE	0x3D0
+
+/* System Configuration Extension Registers (XRX) */
+#define IO_CTNL		0x09
+#define EXTENDED_ATTR_CNTL	0x02
+#define EXTENDED_CRTC_CNTL	0x01
+
+#define ADDRESS_MAPPING	0x0A
+#define PACKED_MODE_ENABLE	0x04
+#define LINEAR_MODE_ENABLE	0x02
+#define PAGE_MAPPING_ENABLE	0x01
+
+#define BITBLT_CNTL	0x20
+#define COLEXP_MODE		0x30
+#define COLEXP_8BPP		0x00
+#define COLEXP_16BPP		0x10
+#define COLEXP_24BPP		0x20
+#define COLEXP_RESERVED		0x30
+#define CHIP_RESET		0x02
+#define BITBLT_STATUS		0x01
+
+#define DISPLAY_CNTL	0x40
+#define VGA_WRAP_MODE		0x02
+#define VGA_WRAP_AT_256KB	0x00
+#define VGA_NO_WRAP		0x02
+#define GUI_MODE		0x01
+#define STANDARD_VGA_MODE	0x00
+#define HIRES_MODE		0x01
+
+#define DRAM_ROW_TYPE	0x50
+#define DRAM_ROW_0		0x07
+#define DRAM_ROW_0_SDRAM	0x00
+#define DRAM_ROW_0_EMPTY	0x07
+#define DRAM_ROW_1		0x38
+#define DRAM_ROW_1_SDRAM	0x00
+#define DRAM_ROW_1_EMPTY	0x38
+#define DRAM_ROW_CNTL_LO 0x51
+#define DRAM_CAS_LATENCY	0x10
+#define DRAM_RAS_TIMING		0x08
+#define DRAM_RAS_PRECHARGE	0x04
+#define DRAM_ROW_CNTL_HI 0x52
+#define DRAM_EXT_CNTL	0x53
+#define DRAM_REFRESH_RATE	0x03
+#define DRAM_REFRESH_DISABLE	0x00
+#define DRAM_REFRESH_60HZ	0x01
+#define DRAM_REFRESH_FAST_TEST	0x02
+#define DRAM_REFRESH_RESERVED	0x03
+#define DRAM_TIMING	0x54
+#define DRAM_ROW_BNDRY_0 0x55
+#define DRAM_ROW_BNDRY_1 0x56
+
+#define DPMS_SYNC_SELECT 0x61
+#define VSYNC_CNTL		0x08
+#define VSYNC_ON		0x00
+#define VSYNC_OFF		0x08
+#define HSYNC_CNTL		0x02
+#define HSYNC_ON		0x00
+#define HSYNC_OFF		0x02
+
+#define PIXPIPE_CONFIG_0 0x80
+#define DAC_8_BIT		0x80
+#define DAC_6_BIT		0x00
+#define HW_CURSOR_ENABLE	0x10
+#define EXTENDED_PALETTE	0x01
+
+#define PIXPIPE_CONFIG_1 0x81
+#define DISPLAY_COLOR_MODE	0x0F
+#define DISPLAY_VGA_MODE	0x00
+#define DISPLAY_8BPP_MODE	0x02
+#define DISPLAY_15BPP_MODE	0x04
+#define DISPLAY_16BPP_MODE	0x05
+#define DISPLAY_24BPP_MODE	0x06
+#define DISPLAY_32BPP_MODE	0x07
+
+#define PIXPIPE_CONFIG_2 0x82
+#define DISPLAY_GAMMA_ENABLE	0x08
+#define DISPLAY_GAMMA_DISABLE	0x00
+#define OVERLAY_GAMMA_ENABLE	0x04
+#define OVERLAY_GAMMA_DISABLE	0x00
+
+#define CURSOR_CONTROL	0xA0
+#define CURSOR_ORIGIN_SCREEN	0x00
+#define CURSOR_ORIGIN_DISPLAY	0x10
+#define CURSOR_MODE		0x07
+#define CURSOR_MODE_DISABLE	0x00
+#define CURSOR_MODE_32_4C_AX	0x01
+#define CURSOR_MODE_128_2C	0x02
+#define CURSOR_MODE_128_1C	0x03
+#define CURSOR_MODE_64_3C	0x04
+#define CURSOR_MODE_64_4C_AX	0x05
+#define CURSOR_MODE_64_4C	0x06
+#define CURSOR_MODE_RESERVED	0x07
+#define CURSOR_BASEADDR_LO 0xA2
+#define CURSOR_BASEADDR_HI 0xA3
+#define CURSOR_X_LO	0xA4
+#define CURSOR_X_HI	0xA5
+#define CURSOR_X_POS		0x00
+#define CURSOR_X_NEG		0x80
+#define CURSOR_Y_LO	0xA6
+#define CURSOR_Y_HI	0xA7
+#define CURSOR_Y_POS		0x00
+#define CURSOR_Y_NEG		0x80
+
+#define VCLK2_VCO_M	0xC8
+#define VCLK2_VCO_N	0xC9
+#define VCLK2_VCO_MN_MSBS 0xCA
+#define VCO_N_MSBS		0x30
+#define VCO_M_MSBS		0x03
+#define VCLK2_VCO_DIV_SEL 0xCB
+#define POST_DIV_SELECT		0x70
+#define POST_DIV_1		0x00
+#define POST_DIV_2		0x10
+#define POST_DIV_4		0x20
+#define POST_DIV_8		0x30
+#define POST_DIV_16		0x40
+#define POST_DIV_32		0x50
+#define VCO_LOOP_DIV_BY_4M	0x00
+#define VCO_LOOP_DIV_BY_16M	0x04
+#define REF_CLK_DIV_BY_5	0x02
+#define REF_DIV_4		0x00
+#define REF_DIV_1		0x01
+
+#define PLL_CNTL	0xCE
+#define PLL_MEMCLK_SEL		0x03
+#define PLL_MEMCLK__66667KHZ	0x00
+#define PLL_MEMCLK__75000KHZ	0x01
+#define PLL_MEMCLK__88889KHZ	0x02
+#define PLL_MEMCLK_100000KHZ	0x03
+
+/* Multimedia Extension Registers (MRX) */
+#define ACQ_CNTL_1	0x02
+#define ACQ_CNTL_2	0x03
+#define FRAME_CAP_MODE		0x01
+#define CONT_CAP_MODE		0x00
+#define SINGLE_CAP_MODE		0x01
+#define ACQ_CNTL_3	0x04
+#define COL_KEY_CNTL_1		0x3C
+#define BLANK_DISP_OVERLAY	0x20
+
+/* FIFOs */
+#define LP_FIFO		0x1000
+#define HP_FIFO		0x2000
+#define INSTPNT		0x3040
+#define LP_FIFO_COUNT	0x3040
+#define HP_FIFO_COUNT	0x3041
+
+/* FIFO Commands */
+#define CLIENT		0xE0000000
+#define CLIENT_2D	0x60000000
+
+/* Command Parser Mode Register */
+#define COMPARS		0x3038
+#define TWO_D_INST_DISABLE		0x08
+#define THREE_D_INST_DISABLE		0x04
+#define STATE_VAR_UPDATE_DISABLE	0x02
+#define PAL_STIP_DISABLE		0x01
+
+/* Interrupt Control Registers */
+#define IER		0x3030
+#define IIR		0x3032
+#define IMR		0x3034
+#define ISR		0x3036
+#define VMIINTB_EVENT		0x2000
+#define GPIO4_INT		0x1000
+#define DISP_FLIP_EVENT		0x0800
+#define DVD_PORT_DMA		0x0400
+#define DISP_VBLANK		0x0200
+#define FIFO_EMPTY_DMA_DONE	0x0100
+#define INST_PARSER_ERROR	0x0080
+#define USER_DEFINED		0x0040
+#define BREAKPOINT		0x0020
+#define DISP_HORIZ_COUNT	0x0010
+#define DISP_VSYNC		0x0008
+#define CAPTURE_HORIZ_COUNT	0x0004
+#define CAPTURE_VSYNC		0x0002
+#define THREE_D_PIPE_FLUSHED	0x0001
+
+/* FIFO Watermark and Burst Length Control Register */
+#define FWATER_BLC	0x00006000
+#define LMI_BURST_LENGTH	0x7F000000
+#define LMI_FIFO_WATERMARK	0x003F0000
+#define AGP_BURST_LENGTH	0x00007F00
+#define AGP_FIFO_WATERMARK	0x0000003F
+
+/* BitBLT Registers */
+#define SRC_DST_PITCH	0x00040000
+#define DST_PITCH		0x1FFF0000
+#define SRC_PITCH		0x00001FFF
+#define COLEXP_BG_COLOR	0x00040004
+#define COLEXP_FG_COLOR	0x00040008
+#define MONO_SRC_CNTL	0x0004000C
+#define MONO_USE_COLEXP		0x00000000
+#define MONO_USE_SRCEXP		0x08000000
+#define MONO_DATA_ALIGN		0x07000000
+#define MONO_BIT_ALIGN		0x01000000
+#define MONO_BYTE_ALIGN		0x02000000
+#define MONO_WORD_ALIGN		0x03000000
+#define MONO_DWORD_ALIGN	0x04000000
+#define MONO_QWORD_ALIGN	0x05000000
+#define MONO_SRC_INIT_DSCRD	0x003F0000
+#define MONO_SRC_RIGHT_CLIP	0x00003F00
+#define MONO_SRC_LEFT_CLIP	0x0000003F
+#define BITBLT_CONTROL	0x00040010
+#define BLTR_STATUS		0x80000000
+#define DYN_DEPTH		0x03000000
+#define DYN_DEPTH_8BPP		0x00000000
+#define DYN_DEPTH_16BPP		0x01000000
+#define DYN_DEPTH_24BPP		0x02000000
+#define DYN_DEPTH_32BPP		0x03000000	/* Unimplemented on the i740 */
+#define DYN_DEPTH_ENABLE	0x00800000
+#define PAT_VERT_ALIGN		0x00700000
+#define SOLID_PAT_SELECT	0x00080000
+#define PAT_IS_IN_COLOR		0x00000000
+#define PAT_IS_MONO		0x00040000
+#define MONO_PAT_TRANSP		0x00020000
+#define COLOR_TRANSP_ROP	0x00000000
+#define COLOR_TRANSP_DST	0x00008000
+#define COLOR_TRANSP_EQ		0x00000000
+#define COLOR_TRANSP_NOT_EQ	0x00010000
+#define COLOR_TRANSP_ENABLE	0x00004000
+#define MONO_SRC_TRANSP		0x00002000
+#define SRC_IS_IN_COLOR		0x00000000
+#define SRC_IS_MONO		0x00001000
+#define SRC_USE_SRC_ADDR	0x00000000
+#define SRC_USE_BLTDATA		0x00000400
+#define BLT_TOP_TO_BOT		0x00000000
+#define BLT_BOT_TO_TOP		0x00000200
+#define BLT_LEFT_TO_RIGHT	0x00000000
+#define BLT_RIGHT_TO_LEFT	0x00000100
+#define BLT_ROP			0x000000FF
+#define BLT_PAT_ADDR	0x00040014
+#define BLT_SRC_ADDR	0x00040018
+#define BLT_DST_ADDR	0x0004001C
+#define BLT_DST_H_W	0x00040020
+#define BLT_DST_HEIGHT		0x1FFF0000
+#define BLT_DST_WIDTH		0x00001FFF
+#define SRCEXP_BG_COLOR	0x00040024
+#define SRCEXP_FG_COLOR	0x00040028
+#define BLTDATA		0x00050000
diff --git a/drivers/video/i740fb.c b/drivers/video/i740fb.c
new file mode 100644
index 0000000..fe574d8
--- /dev/null
+++ b/drivers/video/i740fb.c
@@ -0,0 +1,1337 @@
+/*
+ * i740fb - framebuffer driver for Intel740
+ * Copyright (c) 2011 Ondrej Zary
+ *
+ * Based on old i740fb driver (c) 2001-2002 Andrey Ulanov <drey@rt.mipt.ru>
+ * which was partially based on:
+ *  VGA 16-color framebuffer driver (c) 1999 Ben Pfaff <pfaffben@debian.org>
+ *	and Petr Vandrovec <VANDROVE@vc.cvut.cz>
+ *  i740 driver from XFree86 (c) 1998-1999 Precision Insight, Inc., Cedar Park,
+ *	Texas.
+ *  i740fb by Patrick LERDA, v0.9
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/console.h>
+#include <video/vga.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "i740_reg.h"
+
+static char *mode_option __devinitdata;
+
+#ifdef CONFIG_MTRR
+static int mtrr __devinitdata = 1;
+#endif
+
+struct i740fb_par {
+	unsigned char __iomem *regs;
+	bool has_sgram;
+#ifdef CONFIG_MTRR
+	int mtrr_reg;
+#endif
+	bool ddc_registered;
+	struct i2c_adapter ddc_adapter;
+	struct i2c_algo_bit_data ddc_algo;
+	u32 pseudo_palette[16];
+	struct mutex open_lock;
+	unsigned int ref_count;
+
+	u8 crtc[VGA_CRT_C];
+	u8 atc[VGA_ATT_C];
+	u8 gdc[VGA_GFX_C];
+	u8 seq[VGA_SEQ_C];
+	u8 misc;
+	u8 vss;
+
+	/* i740 specific registers */
+	u8 display_cntl;
+	u8 pixelpipe_cfg0;
+	u8 pixelpipe_cfg1;
+	u8 pixelpipe_cfg2;
+	u8 video_clk2_m;
+	u8 video_clk2_n;
+	u8 video_clk2_mn_msbs;
+	u8 video_clk2_div_sel;
+	u8 pll_cntl;
+	u8 address_mapping;
+	u8 io_cntl;
+	u8 bitblt_cntl;
+	u8 ext_vert_total;
+	u8 ext_vert_disp_end;
+	u8 ext_vert_sync_start;
+	u8 ext_vert_blank_start;
+	u8 ext_horiz_total;
+	u8 ext_horiz_blank;
+	u8 ext_offset;
+	u8 interlace_cntl;
+	u32 lmi_fifo_watermark;
+	u8 ext_start_addr;
+	u8 ext_start_addr_hi;
+};
+
+#define DACSPEED8	203
+#define DACSPEED16	163
+#define DACSPEED24_SG	136
+#define DACSPEED24_SD	128
+#define DACSPEED32	86
+
+static struct fb_fix_screeninfo i740fb_fix __devinitdata = {
+	.id =		"i740fb",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_TRUECOLOR,
+	.xpanstep =	8,
+	.ypanstep =	1,
+	.accel =	FB_ACCEL_NONE,
+};
+
+static inline void i740outb(struct i740fb_par *par, u16 port, u8 val)
+{
+	vga_mm_w(par->regs, port, val);
+}
+static inline u8 i740inb(struct i740fb_par *par, u16 port)
+{
+	return vga_mm_r(par->regs, port);
+}
+static inline void i740outreg(struct i740fb_par *par, u16 port, u8 reg, u8 val)
+{
+	vga_mm_w_fast(par->regs, port, reg, val);
+}
+static inline u8 i740inreg(struct i740fb_par *par, u16 port, u8 reg)
+{
+	vga_mm_w(par->regs, port, reg);
+	return vga_mm_r(par->regs, port+1);
+}
+static inline void i740outreg_mask(struct i740fb_par *par, u16 port, u8 reg,
+				   u8 val, u8 mask)
+{
+	vga_mm_w_fast(par->regs, port, reg, (val & mask)
+		| (i740inreg(par, port, reg) & ~mask));
+}
+
+#define REG_DDC_DRIVE	0x62
+#define REG_DDC_STATE	0x63
+#define DDC_SCL		(1 << 3)
+#define DDC_SDA		(1 << 2)
+
+static void i740fb_ddc_setscl(void *data, int val)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SCL, DDC_SCL);
+	i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SCL : 0, DDC_SCL);
+}
+
+static void i740fb_ddc_setsda(void *data, int val)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SDA, DDC_SDA);
+	i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SDA : 0, DDC_SDA);
+}
+
+static int i740fb_ddc_getscl(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SCL);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SCL);
+}
+
+static int i740fb_ddc_getsda(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SDA);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SDA);
+}
+
+static int __devinit i740fb_setup_ddc_bus(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	strlcpy(par->ddc_adapter.name, info->fix.id,
+		sizeof(par->ddc_adapter.name));
+	par->ddc_adapter.owner		= THIS_MODULE;
+	par->ddc_adapter.class		= I2C_CLASS_DDC;
+	par->ddc_adapter.algo_data	= &par->ddc_algo;
+	par->ddc_adapter.dev.parent	= info->device;
+	par->ddc_algo.setsda		= i740fb_ddc_setsda;
+	par->ddc_algo.setscl		= i740fb_ddc_setscl;
+	par->ddc_algo.getsda		= i740fb_ddc_getsda;
+	par->ddc_algo.getscl		= i740fb_ddc_getscl;
+	par->ddc_algo.udelay		= 10;
+	par->ddc_algo.timeout		= 20;
+	par->ddc_algo.data		= par;
+
+	i2c_set_adapdata(&par->ddc_adapter, par);
+
+	return i2c_bit_add_bus(&par->ddc_adapter);
+}
+
+static int i740fb_open(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	par->ref_count++;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static int i740fb_release(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	if (par->ref_count == 0) {
+		printk(KERN_ERR "fb%d: release called with zero refcount\n",
+			info->node);
+		mutex_unlock(&(par->open_lock));
+		return -EINVAL;
+	}
+
+	par->ref_count--;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static u32 i740_calc_fifo(struct i740fb_par *par, u32 freq, int bpp)
+{
+	/*
+	 * Would like to calculate these values automatically, but a generic
+	 * algorithm does not seem possible.  Note: These FIFO water mark
+	 * values were tested on several cards and seem to eliminate the
+	 * all of the snow and vertical banding, but fine adjustments will
+	 * probably be required for other cards.
+	 */
+
+	u32 wm;
+
+	switch (bpp) {
+	case 8:
+		if	(freq > 200)
+			wm = 0x18120000;
+		else if (freq > 175)
+			wm = 0x16110000;
+		else if (freq > 135)
+			wm = 0x120E0000;
+		else
+			wm = 0x100D0000;
+		break;
+	case 15:
+	case 16:
+		if (par->has_sgram) {
+			if	(freq > 140)
+				wm = 0x2C1D0000;
+			else if (freq > 120)
+				wm = 0x2C180000;
+			else if (freq > 100)
+				wm = 0x24160000;
+			else if (freq >  90)
+				wm = 0x18120000;
+			else if (freq >  50)
+				wm = 0x16110000;
+			else if (freq >  32)
+				wm = 0x13100000;
+			else
+				wm = 0x120E0000;
+		} else {
+			if	(freq > 160)
+				wm = 0x28200000;
+			else if (freq > 140)
+				wm = 0x2A1E0000;
+			else if (freq > 130)
+				wm = 0x2B1A0000;
+			else if (freq > 120)
+				wm = 0x2C180000;
+			else if (freq > 100)
+				wm = 0x24180000;
+			else if (freq >  90)
+				wm = 0x18120000;
+			else if (freq >  50)
+				wm = 0x16110000;
+			else if (freq >  32)
+				wm = 0x13100000;
+			else
+				wm = 0x120E0000;
+		}
+		break;
+	case 24:
+		if (par->has_sgram) {
+			if	(freq > 130)
+				wm = 0x31200000;
+			else if (freq > 120)
+				wm = 0x2E200000;
+			else if (freq > 100)
+				wm = 0x2C1D0000;
+			else if (freq >  80)
+				wm = 0x25180000;
+			else if (freq >  64)
+				wm = 0x24160000;
+			else if (freq >  49)
+				wm = 0x18120000;
+			else if (freq >  32)
+				wm = 0x16110000;
+			else
+				wm = 0x13100000;
+		} else {
+			if	(freq > 120)
+				wm = 0x311F0000;
+			else if (freq > 100)
+				wm = 0x2C1D0000;
+			else if (freq >  80)
+				wm = 0x25180000;
+			else if (freq >  64)
+				wm = 0x24160000;
+			else if (freq >  49)
+				wm = 0x18120000;
+			else if (freq >  32)
+				wm = 0x16110000;
+			else
+				wm = 0x13100000;
+		}
+		break;
+	case 32:
+		if (par->has_sgram) {
+			if	(freq >  80)
+				wm = 0x2A200000;
+			else if (freq >  60)
+				wm = 0x281A0000;
+			else if (freq >  49)
+				wm = 0x25180000;
+			else if (freq >  32)
+				wm = 0x18120000;
+			else
+				wm = 0x16110000;
+		} else {
+			if	(freq >  80)
+				wm = 0x29200000;
+			else if (freq >  60)
+				wm = 0x281A0000;
+			else if (freq >  49)
+				wm = 0x25180000;
+			else if (freq >  32)
+				wm = 0x18120000;
+			else
+				wm = 0x16110000;
+		}
+		break;
+	}
+
+	return wm;
+}
+
+/* clock calculation from i740fb by Patrick LERDA */
+
+#define I740_RFREQ		1000000
+#define TARGET_MAX_N		30
+#define I740_FFIX		(1 << 8)
+#define I740_RFREQ_FIX		(I740_RFREQ / I740_FFIX)
+#define I740_REF_FREQ		(6667 * I740_FFIX / 100)	/* 66.67 MHz */
+#define I740_MAX_VCO_FREQ	(450 * I740_FFIX)		/* 450 MHz */
+
+static void i740_calc_vclk(u32 freq, struct i740fb_par *par)
+{
+	const u32 err_max    = freq / (200  * I740_RFREQ / I740_FFIX);
+	const u32 err_target = freq / (1000 * I740_RFREQ / I740_FFIX);
+	u32 err_best = 512 * I740_FFIX;
+	u32 f_err, f_vco;
+	int m_best = 0, n_best = 0, p_best = 0, d_best = 0;
+	int m, n;
+
+	p_best = min(15, ilog2(I740_MAX_VCO_FREQ / (freq / I740_RFREQ_FIX)));
+	d_best = 0;
+	f_vco = (freq * (1 << p_best)) / I740_RFREQ_FIX;
+	freq = freq / I740_RFREQ_FIX;
+
+	n = 2;
+	do {
+		n++;
+		m = ((f_vco * n) / I740_REF_FREQ + 2) / 4;
+
+		if (m < 3)
+			m = 3;
+
+		{
+			u32 f_out = (((m * I740_REF_FREQ * (4 << 2 * d_best))
+				 / n) + ((1 << p_best) / 2)) / (1 << p_best);
+
+			f_err = (freq - f_out);
+
+			if (abs(f_err) < err_max) {
+				m_best = m;
+				n_best = n;
+				err_best = f_err;
+			}
+		}
+	} while ((abs(f_err) >= err_target) &&
+		 ((n <= TARGET_MAX_N) || (abs(err_best) > err_max)));
+
+	if (abs(f_err) < err_target) {
+		m_best = m;
+		n_best = n;
+	}
+
+	par->video_clk2_m = (m_best - 2) & 0xFF;
+	par->video_clk2_n = (n_best - 2) & 0xFF;
+	par->video_clk2_mn_msbs = ((((n_best - 2) >> 4) & VCO_N_MSBS)
+				 | (((m_best - 2) >> 8) & VCO_M_MSBS));
+	par->video_clk2_div_sel =
+		((p_best << 4) | (d_best ? 4 : 0) | REF_DIV_1);
+}
+
+static int i740fb_decode_var(const struct fb_var_screeninfo *var,
+			     struct i740fb_par *par, struct fb_info *info)
+{
+	/*
+	 * Get the video params out of 'var'.
+	 * If a value doesn't fit, round it up, if it's too big, return -EINVAL.
+	 */
+
+	u32 xres, right, hslen, left, xtotal;
+	u32 yres, lower, vslen, upper, ytotal;
+	u32 vxres, xoffset, vyres, yoffset;
+	u32 bpp, base, dacspeed24, mem;
+	u8 r7;
+	int i;
+
+	dev_dbg(info->device, "decode_var: xres: %i, yres: %i, xres_v: %i, xres_v: %i\n",
+		  var->xres, var->yres, var->xres_virtual, var->xres_virtual);
+	dev_dbg(info->device, "	xoff: %i, yoff: %i, bpp: %i, graysc: %i\n",
+		  var->xoffset, var->yoffset, var->bits_per_pixel,
+		  var->grayscale);
+	dev_dbg(info->device, "	activate: %i, nonstd: %i, vmode: %i\n",
+		  var->activate, var->nonstd, var->vmode);
+	dev_dbg(info->device, "	pixclock: %i, hsynclen:%i, vsynclen:%i\n",
+		  var->pixclock, var->hsync_len, var->vsync_len);
+	dev_dbg(info->device, "	left: %i, right: %i, up:%i, lower:%i\n",
+		  var->left_margin, var->right_margin, var->upper_margin,
+		  var->lower_margin);
+
+
+	bpp = var->bits_per_pixel;
+	switch (bpp) {
+	case 1 ... 8:
+		bpp = 8;
+		if ((1000000 / var->pixclock) > DACSPEED8) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 8bpp)\n",
+				1000000 / var->pixclock, DACSPEED8);
+			return -EINVAL;
+		}
+		break;
+	case 9 ... 15:
+		bpp = 15;
+	case 16:
+		if ((1000000 / var->pixclock) > DACSPEED16) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n",
+				1000000 / var->pixclock, DACSPEED16);
+			return -EINVAL;
+		}
+		break;
+	case 17 ... 24:
+		bpp = 24;
+		dacspeed24 = par->has_sgram ? DACSPEED24_SG : DACSPEED24_SD;
+		if ((1000000 / var->pixclock) > dacspeed24) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 24bpp)\n",
+				1000000 / var->pixclock, dacspeed24);
+			return -EINVAL;
+		}
+		break;
+	case 25 ... 32:
+		bpp = 32;
+		if ((1000000 / var->pixclock) > DACSPEED32) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 32bpp)\n",
+				1000000 / var->pixclock, DACSPEED32);
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	xres = ALIGN(var->xres, 8);
+	vxres = ALIGN(var->xres_virtual, 16);
+	if (vxres < xres)
+		vxres = xres;
+
+	xoffset = ALIGN(var->xoffset, 8);
+	if (xres + xoffset > vxres)
+		xoffset = vxres - xres;
+
+	left = ALIGN(var->left_margin, 8);
+	right = ALIGN(var->right_margin, 8);
+	hslen = ALIGN(var->hsync_len, 8);
+
+	yres = var->yres;
+	vyres = var->yres_virtual;
+	if (yres > vyres)
+		vyres = yres;
+
+	yoffset = var->yoffset;
+	if (yres + yoffset > vyres)
+		yoffset = vyres - yres;
+
+	lower = var->lower_margin;
+	vslen = var->vsync_len;
+	upper = var->upper_margin;
+
+	mem = vxres * vyres * ((bpp + 1) / 8);
+	if (mem > info->screen_size) {
+		dev_err(info->device, "not enough video memory (%d KB requested, %ld KB avaliable)\n",
+			mem >> 10, info->screen_size >> 10);
+		return -ENOMEM;
+	}
+
+	if (yoffset + yres > vyres)
+		yoffset = vyres - yres;
+
+	xtotal = xres + right + hslen + left;
+	ytotal = yres + lower + vslen + upper;
+
+	par->crtc[VGA_CRTC_H_TOTAL] = (xtotal >> 3) - 5;
+	par->crtc[VGA_CRTC_H_DISP] = (xres >> 3) - 1;
+	par->crtc[VGA_CRTC_H_BLANK_START] = ((xres + right) >> 3) - 1;
+	par->crtc[VGA_CRTC_H_SYNC_START] = (xres + right) >> 3;
+	par->crtc[VGA_CRTC_H_SYNC_END] = (((xres + right + hslen) >> 3) & 0x1F)
+		| ((((xres + right + hslen) >> 3) & 0x20) << 2);
+	par->crtc[VGA_CRTC_H_BLANK_END] = ((xres + right + hslen) >> 3 & 0x1F)
+		| 0x80;
+
+	par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
+
+	r7 = 0x10;	/* disable linecompare */
+	if (ytotal & 0x100)
+		r7 |= 0x01;
+	if (ytotal & 0x200)
+		r7 |= 0x20;
+
+	par->crtc[VGA_CRTC_PRESET_ROW] = 0;
+	par->crtc[VGA_CRTC_MAX_SCAN] = 0x40;	/* 1 scanline, no linecmp */
+	if (var->vmode & FB_VMODE_DOUBLE)
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
+	par->crtc[VGA_CRTC_CURSOR_START] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_LO] = 0x00;
+	par->crtc[VGA_CRTC_V_DISP_END] = yres-1;
+	if ((yres-1) & 0x100)
+		r7 |= 0x02;
+	if ((yres-1) & 0x200)
+		r7 |= 0x40;
+
+	par->crtc[VGA_CRTC_V_BLANK_START] = yres + lower - 1;
+	par->crtc[VGA_CRTC_V_SYNC_START] = yres + lower - 1;
+	if ((yres + lower - 1) & 0x100)
+		r7 |= 0x0C;
+	if ((yres + lower - 1) & 0x200) {
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20;
+		r7 |= 0x80;
+	}
+
+	/* disabled IRQ */
+	par->crtc[VGA_CRTC_V_SYNC_END] =
+		((yres + lower - 1 + vslen) & 0x0F) & ~0x10;
+	/* 0x7F for VGA, but some SVGA chips require all 8 bits to be set */
+	par->crtc[VGA_CRTC_V_BLANK_END] = (yres + lower - 1 + vslen) & 0xFF;
+
+	par->crtc[VGA_CRTC_UNDERLINE] = 0x00;
+	par->crtc[VGA_CRTC_MODE] = 0xC3 ;
+	par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
+	par->crtc[VGA_CRTC_OVERFLOW] = r7;
+
+	par->vss = 0x00;	/* 3DA */
+
+	for (i = 0x00; i < 0x10; i++)
+		par->atc[i] = i;
+	par->atc[VGA_ATC_MODE] = 0x81;
+	par->atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */
+	par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+	par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
+
+	par->misc = 0xC3;
+	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+		par->misc &= ~0x40;
+	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+		par->misc &= ~0x80;
+
+	par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
+	par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+	par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+	par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+	par->gdc[VGA_GFX_SR_VALUE] = 0x00;
+	par->gdc[VGA_GFX_SR_ENABLE] = 0x00;
+	par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+	par->gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+	par->gdc[VGA_GFX_PLANE_READ] = 0;
+	par->gdc[VGA_GFX_MODE] = 0x02;
+	par->gdc[VGA_GFX_MISC] = 0x05;
+	par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+	par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+	base = (yoffset * vxres + (xoffset & ~7)) >> 2;
+	switch (bpp) {
+	case 8:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 3;
+		par->ext_offset = vxres >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_8BPP_MODE;
+		par->bitblt_cntl = COLEXP_8BPP;
+		break;
+	case 15: /* 0rrrrrgg gggbbbbb */
+	case 16: /* rrrrrggg gggbbbbb */
+		par->pixelpipe_cfg1 = (var->green.length == 6) ?
+			DISPLAY_16BPP_MODE : DISPLAY_15BPP_MODE;
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 2;
+		par->ext_offset = vxres >> 10;
+		par->bitblt_cntl = COLEXP_16BPP;
+		base *= 2;
+		break;
+	case 24:
+		par->crtc[VGA_CRTC_OFFSET] = (vxres * 3) >> 3;
+		par->ext_offset = (vxres * 3) >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_24BPP_MODE;
+		par->bitblt_cntl = COLEXP_24BPP;
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
+		par->ext_offset = vxres >> 9;
+		par->pixelpipe_cfg1 = DISPLAY_32BPP_MODE;
+		par->bitblt_cntl = COLEXP_RESERVED; /* Unimplemented on i740 */
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr =
+		((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+
+	par->pixelpipe_cfg0 = DAC_8_BIT;
+
+	par->pixelpipe_cfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE;
+	par->io_cntl = EXTENDED_CRTC_CNTL;
+	par->address_mapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE;
+	par->display_cntl = HIRES_MODE;
+
+	/* Set the MCLK freq */
+	par->pll_cntl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */
+
+	/* Calculate the extended CRTC regs */
+	par->ext_vert_total = (ytotal - 2) >> 8;
+	par->ext_vert_disp_end = (yres - 1) >> 8;
+	par->ext_vert_sync_start = (yres + lower) >> 8;
+	par->ext_vert_blank_start = (yres + lower) >> 8;
+	par->ext_horiz_total = ((xtotal >> 3) - 5) >> 8;
+	par->ext_horiz_blank = (((xres + right) >> 3) & 0x40) >> 6;
+
+	par->interlace_cntl = INTERLACE_DISABLE;
+
+	/* Set the overscan color to 0. (NOTE: This only affects >8bpp mode) */
+	par->atc[VGA_ATC_OVERSCAN] = 0;
+
+	/* Calculate VCLK that most closely matches the requested dot clock */
+	i740_calc_vclk((((u32)1e9) / var->pixclock) * (u32)(1e3), par);
+
+	/* Since we program the clocks ourselves, always use VCLK2. */
+	par->misc |= 0x0C;
+
+	/* Calculate the FIFO Watermark and Burst Length. */
+	par->lmi_fifo_watermark =
+		i740_calc_fifo(par, 1000000 / var->pixclock, bpp);
+
+	return 0;
+}
+
+static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset	= var->green.offset = var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 16:
+		switch (var->green.length) {
+		default:
+		case 5:
+			var->red.offset = 10;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length	= 5;
+			var->green.length = 5;
+			var->blue.length = 5;
+			break;
+		case 6:
+			var->red.offset = 11;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length = var->blue.length = 5;
+			break;
+		}
+		break;
+	case 24:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 32:
+		var->transp.offset = 24;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->transp.length = 8;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+
+	if (var->yres > var->yres_virtual)
+		var->yres_virtual = var->yres;
+
+	if (info->monspecs.hfmax && info->monspecs.vfmax &&
+	    info->monspecs.dclkmax && fb_validate_mode(var, info) < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void vga_protect(struct i740fb_par *par)
+{
+	/* disable the display */
+	i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0x20, 0x20);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x00);	/* enable pallete access */
+}
+
+static void vga_unprotect(struct i740fb_par *par)
+{
+	/* reenable display */
+	i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0, 0x20);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x20);	/* disable pallete access */
+}
+
+static int i740fb_set_par(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 itemp;
+	int i;
+
+	i = i740fb_decode_var(&info->var, par, info);
+	if (i)
+		return i;
+
+	memset(info->screen_base, 0, info->screen_size);
+
+	vga_protect(par);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_DISABLE);
+
+	mdelay(1);
+
+	i740outreg(par, XRX, VCLK2_VCO_M, par->video_clk2_m);
+	i740outreg(par, XRX, VCLK2_VCO_N, par->video_clk2_n);
+	i740outreg(par, XRX, VCLK2_VCO_MN_MSBS, par->video_clk2_mn_msbs);
+	i740outreg(par, XRX, VCLK2_VCO_DIV_SEL, par->video_clk2_div_sel);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0,
+			par->pixelpipe_cfg0 & DAC_8_BIT, 0x80);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, 0x3C0, 0x00);
+
+	/* update misc output register */
+	i740outb(par, VGA_MIS_W, par->misc | 0x01);
+
+	/* synchronous reset on */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x01);
+	/* write sequencer registers */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE,
+			par->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+	for (i = 2; i < VGA_SEQ_C; i++)
+		i740outreg(par, VGA_SEQ_I, i, par->seq[i]);
+
+	/* synchronous reset off */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x03);
+
+	/* deprotect CRT registers 0-7 */
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_V_SYNC_END,
+			par->crtc[VGA_CRTC_V_SYNC_END]);
+
+	/* write CRT registers */
+	for (i = 0; i < VGA_CRT_C; i++)
+		i740outreg(par, VGA_CRT_IC, i, par->crtc[i]);
+
+	/* write graphics controller registers */
+	for (i = 0; i < VGA_GFX_C; i++)
+		i740outreg(par, VGA_GFX_I, i, par->gdc[i]);
+
+	/* write attribute controller registers */
+	for (i = 0; i < VGA_ATT_C; i++) {
+		i740inb(par, VGA_IS1_RC);		/* reset flip-flop */
+		i740outb(par, VGA_ATT_IW, i);
+		i740outb(par, VGA_ATT_IW, par->atc[i]);
+	}
+
+	i740inb(par, VGA_IS1_RC);
+	i740outb(par, VGA_ATT_IW, 0x20);
+
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_TOTAL, par->ext_vert_total);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_DISPLAY, par->ext_vert_disp_end);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_SYNC_START,
+			par->ext_vert_sync_start);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_BLANK_START,
+			par->ext_vert_blank_start);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_TOTAL, par->ext_horiz_total);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_BLANK, par->ext_horiz_blank);
+	i740outreg(par, VGA_CRT_IC, EXT_OFFSET, par->ext_offset);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, par->ext_start_addr_hi);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, par->ext_start_addr);
+
+	i740outreg_mask(par, VGA_CRT_IC, INTERLACE_CNTL,
+			par->interlace_cntl, INTERLACE_ENABLE);
+	i740outreg_mask(par, XRX, ADDRESS_MAPPING, par->address_mapping, 0x1F);
+	i740outreg_mask(par, XRX, BITBLT_CNTL, par->bitblt_cntl, COLEXP_MODE);
+	i740outreg_mask(par, XRX, DISPLAY_CNTL,
+			par->display_cntl, VGA_WRAP_MODE | GUI_MODE);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0, 0x9B);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_2, par->pixelpipe_cfg2, 0x0C);
+
+	i740outreg(par, XRX, PLL_CNTL, par->pll_cntl);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_1,
+			par->pixelpipe_cfg1, DISPLAY_COLOR_MODE);
+
+	itemp = readl(par->regs + FWATER_BLC);
+	itemp &= ~(LMI_BURST_LENGTH | LMI_FIFO_WATERMARK);
+	itemp |= par->lmi_fifo_watermark;
+	writel(itemp, par->regs + FWATER_BLC);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_60HZ);
+
+	i740outreg_mask(par, MRX, COL_KEY_CNTL_1, 0, BLANK_DISP_OVERLAY);
+	i740outreg_mask(par, XRX, IO_CTNL,
+			par->io_cntl, EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL);
+
+	if (par->pixelpipe_cfg1 != DISPLAY_8BPP_MODE) {
+		i740outb(par, VGA_PEL_MSK, 0xFF);
+		i740outb(par, VGA_PEL_IW, 0x00);
+		for (i = 0; i < 256; i++) {
+			itemp = (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2;
+			i740outb(par, VGA_PEL_D, itemp);
+			i740outb(par, VGA_PEL_D, itemp);
+			i740outb(par, VGA_PEL_D, itemp);
+		}
+	}
+
+	/* Wait for screen to stabilize. */
+	mdelay(50);
+	vga_unprotect(par);
+
+	info->fix.line_length =
+			info->var.xres_virtual * info->var.bits_per_pixel / 8;
+	if (info->var.bits_per_pixel == 8)
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	return 0;
+}
+
+static int i740fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	u32 r, g, b;
+
+	dev_dbg(info->device, "setcolreg: regno: %i, red=%d, green=%d, blue=%d, transp=%d, bpp=%d\n",
+		regno, red, green, blue, transp, info->var.bits_per_pixel);
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_PSEUDOCOLOR:
+		if (regno >= 256)
+			return -EINVAL;
+		i740outb(info->par, VGA_PEL_IW, regno);
+		i740outb(info->par, VGA_PEL_D, red >> 8);
+		i740outb(info->par, VGA_PEL_D, green >> 8);
+		i740outb(info->par, VGA_PEL_D, blue >> 8);
+		break;
+	case FB_VISUAL_TRUECOLOR:
+		if (regno >= 16)
+			return -EINVAL;
+		r = (red >> (16 - info->var.red.length))
+			<< info->var.red.offset;
+		b = (blue >> (16 - info->var.blue.length))
+			<< info->var.blue.offset;
+		g = (green >> (16 - info->var.green.length))
+			<< info->var.green.offset;
+		((u32 *) info->pseudo_palette)[regno] = r | g | b;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int i740fb_pan_display(struct fb_var_screeninfo *var,
+				 struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 base = (var->yoffset * info->var.xres_virtual
+		 + (var->xoffset & ~7)) >> 2;
+
+	dev_dbg(info->device, "pan_display: xoffset: %i yoffset: %i base: %i\n",
+		var->xoffset, var->yoffset, base);
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		break;
+	case 15:
+	case 16:
+		base *= 2;
+		break;
+	case 24:
+		/*
+		 * The last bit does not seem to have any effect on the start
+		 * address register in 24bpp mode, so...
+		 */
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+	par->ext_start_addr =
+			((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_LO,  base & 0x000000FF);
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_HI,
+			(base & 0x0000FF00) >> 8);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI,
+			(base & 0x3FC00000) >> 22);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR,
+			((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE);
+
+	return 0;
+}
+
+static int i740fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	unsigned char SEQ01;
+	int DPMSSyncSelect;
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+	case FB_BLANK_NORMAL:
+		SEQ01 = 0x00;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_ON;
+		break;
+	case FB_BLANK_VSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_OFF;
+		break;
+	case FB_BLANK_HSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_ON;
+		break;
+	case FB_BLANK_POWERDOWN:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF;
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Turn the screen on/off */
+	i740outb(par, SRX, 0x01);
+	SEQ01 |= i740inb(par, SRX + 1) & ~0x20;
+	i740outb(par, SRX, 0x01);
+	i740outb(par, SRX + 1, SEQ01);
+
+	/* Set the DPMS mode */
+	i740outreg(par, XRX, DPMS_SYNC_SELECT, DPMSSyncSelect);
+
+	/* Let fbcon do a soft blank for us */
+	return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
+}
+
+static struct fb_ops i740fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= i740fb_open,
+	.fb_release	= i740fb_release,
+	.fb_check_var	= i740fb_check_var,
+	.fb_set_par	= i740fb_set_par,
+	.fb_setcolreg	= i740fb_setcolreg,
+	.fb_blank	= i740fb_blank,
+	.fb_pan_display	= i740fb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit i740fb_probe(struct pci_dev *dev,
+				  const struct pci_device_id *ent)
+{
+	struct fb_info *info;
+	struct i740fb_par *par;
+	int ret, tmp;
+	bool found = false;
+	u8 *edid;
+
+	info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
+	if (!info) {
+		dev_err(&(dev->dev), "cannot allocate framebuffer\n");
+		return -ENOMEM;
+	}
+
+	par = info->par;
+	mutex_init(&par->open_lock);
+
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->var.bits_per_pixel = 8;
+	info->fbops = &i740fb_ops;
+	info->pseudo_palette = par->pseudo_palette;
+
+	ret = pci_enable_device(dev);
+	if (ret) {
+		dev_err(info->device, "cannot enable PCI device\n");
+		goto err_enable_device;
+	}
+
+	ret = pci_request_regions(dev, info->fix.id);
+	if (ret) {
+		dev_err(info->device, "error requesting regions\n");
+		goto err_request_regions;
+	}
+
+	info->screen_base = pci_ioremap_bar(dev, 0);
+	if (!info->screen_base) {
+		dev_err(info->device, "error remapping base\n");
+		ret = -ENOMEM;
+		goto err_ioremap_1;
+	}
+
+	par->regs = pci_ioremap_bar(dev, 1);
+	if (!par->regs) {
+		dev_err(info->device, "error remapping MMIO\n");
+		ret = -ENOMEM;
+		goto err_ioremap_2;
+	}
+
+	/* detect memory size */
+	if ((i740inreg(par, XRX, DRAM_ROW_TYPE) & DRAM_ROW_1)
+							== DRAM_ROW_1_SDRAM)
+		i740outb(par, XRX, DRAM_ROW_BNDRY_1);
+	else
+		i740outb(par, XRX, DRAM_ROW_BNDRY_0);
+	info->screen_size = i740inb(par, XRX + 1) * 1024 * 1024;
+	/* detect memory type */
+	tmp = i740inreg(par, XRX, DRAM_ROW_CNTL_LO);
+	par->has_sgram = !((tmp & DRAM_RAS_TIMING) ||
+			   (tmp & DRAM_RAS_PRECHARGE));
+
+	printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node,
+		pci_name(dev), info->screen_size >> 10,
+		par->has_sgram ? "SGRAM" : "SDRAM");
+
+	info->fix = i740fb_fix;
+	info->fix.mmio_start = pci_resource_start(dev, 1);
+	info->fix.mmio_len = pci_resource_len(dev, 1);
+	info->fix.smem_start = pci_resource_start(dev, 0);
+	info->fix.smem_len = info->screen_size;
+	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+	if (i740fb_setup_ddc_bus(info) == 0) {
+		par->ddc_registered = true;
+		edid = fb_ddc_read(&par->ddc_adapter);
+		if (edid) {
+			fb_edid_to_monspecs(edid, &info->monspecs);
+			kfree(edid);
+			if (!info->monspecs.modedb)
+				dev_err(info->device,
+					"error getting mode database\n");
+			else {
+				const struct fb_videomode *m;
+
+				fb_videomode_to_modelist(
+					info->monspecs.modedb,
+					info->monspecs.modedb_len,
+					&info->modelist);
+				m = fb_find_best_display(&info->monspecs,
+							 &info->modelist);
+				if (m) {
+					fb_videomode_to_var(&info->var, m);
+					/* fill all other info->var's fields */
+					if (!i740fb_check_var(&info->var, info))
+						found = true;
+				}
+			}
+		}
+	}
+
+	if (!mode_option && !found)
+		mode_option = "640x480-8@60";
+
+	if (mode_option) {
+		ret = fb_find_mode(&info->var, info, mode_option,
+				   info->monspecs.modedb,
+				   info->monspecs.modedb_len,
+				   NULL, info->var.bits_per_pixel);
+		if (!ret || ret == 4) {
+			dev_err(info->device, "mode %s not found\n",
+				mode_option);
+			ret = -EINVAL;
+		}
+	}
+
+	fb_destroy_modedb(info->monspecs.modedb);
+	info->monspecs.modedb = NULL;
+
+	/* maximize virtual vertical size for fast scrolling */
+	info->var.yres_virtual = info->fix.smem_len * 8 /
+			(info->var.bits_per_pixel * info->var.xres_virtual);
+
+	if (ret == -EINVAL)
+		goto err_find_mode;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret) {
+		dev_err(info->device, "cannot allocate colormap\n");
+		goto err_alloc_cmap;
+	}
+
+	ret = register_framebuffer(info);
+	if (ret) {
+		dev_err(info->device, "error registering framebuffer\n");
+		goto err_reg_framebuffer;
+	}
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+		info->node, info->fix.id);
+	pci_set_drvdata(dev, info);
+#ifdef CONFIG_MTRR
+	if (mtrr) {
+		par->mtrr_reg = -1;
+		par->mtrr_reg = mtrr_add(info->fix.smem_start,
+				info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
+	}
+#endif
+	return 0;
+
+err_reg_framebuffer:
+	fb_dealloc_cmap(&info->cmap);
+err_alloc_cmap:
+err_find_mode:
+	if (par->ddc_registered)
+		i2c_del_adapter(&par->ddc_adapter);
+	pci_iounmap(dev, par->regs);
+err_ioremap_2:
+	pci_iounmap(dev, info->screen_base);
+err_ioremap_1:
+	pci_release_regions(dev);
+err_request_regions:
+/*	pci_disable_device(dev); */
+err_enable_device:
+	framebuffer_release(info);
+	return ret;
+}
+
+static void __devexit i740fb_remove(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+
+	if (info) {
+		struct i740fb_par *par = info->par;
+
+#ifdef CONFIG_MTRR
+		if (par->mtrr_reg >= 0) {
+			mtrr_del(par->mtrr_reg, 0, 0);
+			par->mtrr_reg = -1;
+		}
+#endif
+		unregister_framebuffer(info);
+		fb_dealloc_cmap(&info->cmap);
+		if (par->ddc_registered)
+			i2c_del_adapter(&par->ddc_adapter);
+		pci_iounmap(dev, par->regs);
+		pci_iounmap(dev, info->screen_base);
+		pci_release_regions(dev);
+/*		pci_disable_device(dev); */
+		pci_set_drvdata(dev, NULL);
+		framebuffer_release(info);
+	}
+}
+
+#ifdef CONFIG_PM
+static int i740fb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	/* don't disable console during hibernation and wakeup from it */
+	if (state.event == PM_EVENT_FREEZE || state.event == PM_EVENT_PRETHAW)
+		return 0;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	/* do nothing if framebuffer is not active */
+	if (par->ref_count == 0) {
+		mutex_unlock(&(par->open_lock));
+		console_unlock();
+		return 0;
+	}
+
+	fb_set_suspend(info, 1);
+
+	pci_save_state(dev);
+	pci_disable_device(dev);
+	pci_set_power_state(dev, pci_choose_state(dev, state));
+
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+
+	return 0;
+}
+
+static int i740fb_resume(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	if (par->ref_count == 0)
+		goto fail;
+
+	pci_set_power_state(dev, PCI_D0);
+	pci_restore_state(dev);
+	if (pci_enable_device(dev))
+		goto fail;
+
+	i740fb_set_par(info);
+	fb_set_suspend(info, 0);
+
+fail:
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+	return 0;
+}
+#else
+#define i740fb_suspend NULL
+#define i740fb_resume NULL
+#endif /* CONFIG_PM */
+
+#define I740_ID_PCI 0x00d1
+#define I740_ID_AGP 0x7800
+
+static DEFINE_PCI_DEVICE_TABLE(i740fb_id_table) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_PCI) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_AGP) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, i740fb_id_table);
+
+static struct pci_driver i740fb_driver = {
+	.name		= "i740fb",
+	.id_table	= i740fb_id_table,
+	.probe		= i740fb_probe,
+	.remove		= __devexit_p(i740fb_remove),
+	.suspend	= i740fb_suspend,
+	.resume		= i740fb_resume,
+};
+
+#ifndef MODULE
+static int  __init i740fb_setup(char *options)
+{
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+#ifdef CONFIG_MTRR
+		else if (!strncmp(opt, "mtrr:", 5))
+			mtrr = simple_strtoul(opt + 5, NULL, 0);
+#endif
+		else
+			mode_option = opt;
+	}
+
+	return 0;
+}
+#endif
+
+int __init i740fb_init(void)
+{
+#ifndef MODULE
+	char *option = NULL;
+
+	if (fb_get_options("i740fb", &option))
+		return -ENODEV;
+	i740fb_setup(option);
+#endif
+
+	return pci_register_driver(&i740fb_driver);
+}
+
+static void __exit i740fb_exit(void)
+{
+	pci_unregister_driver(&i740fb_driver);
+}
+
+module_init(i740fb_init);
+module_exit(i740fb_exit);
+
+MODULE_AUTHOR("(c) 2011 Ondrej Zary <linux@rainbow-software.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("fbdev driver for Intel740");
+
+module_param(mode_option, charp, 0444);
+MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
+
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0444);
+MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
+#endif
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index f239f4a..7fcd67e 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -155,14 +155,10 @@ static int setup_vsync(struct panel_info *panel, int init)
 		ret = 0;
 		goto uninit;
 	}
-	ret = gpio_request(gpio, "vsync");
+	ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
 	if (ret)
 		goto err_request_gpio_failed;
 
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
 	ret = irq = gpio_to_irq(gpio);
 	if (ret < 0)
 		goto err_get_irq_num_failed;
@@ -180,7 +176,6 @@ uninit:
 	free_irq(gpio_to_irq(gpio), panel->client_data);
 err_request_irq_failed:
 err_get_irq_num_failed:
-err_gpio_direction_input_failed:
 	gpio_free(gpio);
 err_request_gpio_failed:
 	return ret;
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c
index f9bc932..053eb68 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/msm/mddi_client_toshiba.c
@@ -186,14 +186,10 @@ static int setup_vsync(struct panel_info *panel,
 		ret = 0;
 		goto uninit;
 	}
-	ret = gpio_request(gpio, "vsync");
+	ret = gpio_request_one(gpio, GPIOF_IN, "vsync");
 	if (ret)
 		goto err_request_gpio_failed;
 
-	ret = gpio_direction_input(gpio);
-	if (ret)
-		goto err_gpio_direction_input_failed;
-
 	ret = irq = gpio_to_irq(gpio);
 	if (ret < 0)
 		goto err_get_irq_num_failed;
@@ -210,7 +206,6 @@ uninit:
 	free_irq(gpio_to_irq(gpio), panel);
 err_request_irq_failed:
 err_get_irq_num_failed:
-err_gpio_direction_input_failed:
 	gpio_free(gpio);
 err_request_gpio_failed:
 	return ret;
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 7e8bd8e..e3d3d13 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -22,7 +22,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 #include "omapfb.h"
 
 #define MODULE_NAME	"omapfb-lcd_h3"
@@ -32,20 +32,18 @@ static int innovator1610_panel_init(struct lcd_panel *panel,
 {
 	int r = 0;
 
-	if (gpio_request(14, "lcd_en0")) {
+	/* configure GPIO(14, 15) as outputs */
+	if (gpio_request_one(14, GPIOF_OUT_INIT_LOW, "lcd_en0")) {
 		pr_err(MODULE_NAME ": can't request GPIO 14\n");
 		r = -1;
 		goto exit;
 	}
-	if (gpio_request(15, "lcd_en1")) {
+	if (gpio_request_one(15, GPIOF_OUT_INIT_LOW, "lcd_en1")) {
 		pr_err(MODULE_NAME ": can't request GPIO 15\n");
 		gpio_free(14);
 		r = -1;
 		goto exit;
 	}
-	/* configure GPIO(14, 15) as outputs */
-	gpio_direction_output(14, 0);
-	gpio_direction_output(15, 0);
 exit:
 	return r;
 }
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index 8d546dd..e3880c4 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -609,19 +609,7 @@ static struct spi_driver mipid_spi_driver = {
 	.remove	= __devexit_p(mipid_spi_remove),
 };
 
-static int __init mipid_drv_init(void)
-{
-	spi_register_driver(&mipid_spi_driver);
-
-	return 0;
-}
-module_init(mipid_drv_init);
-
-static void __exit mipid_drv_cleanup(void)
-{
-	spi_unregister_driver(&mipid_spi_driver);
-}
-module_exit(mipid_drv_cleanup);
+module_spi_driver(mipid_spi_driver);
 
 MODULE_DESCRIPTION("MIPI display driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 51a87e1..d26f37a 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -809,18 +809,7 @@ static struct spi_driver acx565akm_spi_driver = {
 	.remove	= __devexit_p(acx565akm_spi_remove),
 };
 
-static int __init acx565akm_init(void)
-{
-	return spi_register_driver(&acx565akm_spi_driver);
-}
-
-static void __exit acx565akm_exit(void)
-{
-	spi_unregister_driver(&acx565akm_spi_driver);
-}
-
-module_init(acx565akm_init);
-module_exit(acx565akm_exit);
+module_spi_driver(acx565akm_spi_driver);
 
 MODULE_AUTHOR("Nokia Corporation");
 MODULE_DESCRIPTION("acx565akm LCD Driver");
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index e0eb35b..0841cc2 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -264,16 +264,6 @@ static struct spi_driver lb035q02_spi_driver = {
 	.remove		= __devexit_p(lb035q02_panel_spi_remove),
 };
 
-static int __init lb035q02_panel_drv_init(void)
-{
-	return spi_register_driver(&lb035q02_spi_driver);
-}
-
-static void __exit lb035q02_panel_drv_exit(void)
-{
-	spi_unregister_driver(&lb035q02_spi_driver);
-}
+module_spi_driver(lb035q02_spi_driver);
 
-module_init(lb035q02_panel_drv_init);
-module_exit(lb035q02_panel_drv_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 0eb31ca..8b38b39 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -350,18 +350,8 @@ static struct spi_driver nec_8048_spi_driver = {
 	},
 };
 
-static int __init nec_8048_lcd_init(void)
-{
-	return spi_register_driver(&nec_8048_spi_driver);
-}
-
-static void __exit nec_8048_lcd_exit(void)
-{
-	return spi_unregister_driver(&nec_8048_spi_driver);
-}
+module_spi_driver(nec_8048_spi_driver);
 
-module_init(nec_8048_lcd_init);
-module_exit(nec_8048_lcd_exit);
 MODULE_AUTHOR("Erik Gilling <konkers@android.com>");
 MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 00c5c61..0f21fa5 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1019,14 +1019,12 @@ static int taal_probe(struct omap_dss_device *dssdev)
 	if (panel_data->use_ext_te) {
 		int gpio = panel_data->ext_te_gpio;
 
-		r = gpio_request(gpio, "taal irq");
+		r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
 		if (r) {
 			dev_err(&dssdev->dev, "GPIO request failed\n");
 			goto err_gpio;
 		}
 
-		gpio_direction_input(gpio);
-
 		r = request_irq(gpio_to_irq(gpio), taal_te_isr,
 				IRQF_TRIGGER_RISING,
 				"taal vsync", dssdev);
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index e6649aa..0ca9644 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -408,17 +408,12 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
 	}
 
 	if (gpio_is_valid(nreset_gpio)) {
-		ret = gpio_request(nreset_gpio, "lcd reset");
+		ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW,
+					"lcd reset");
 		if (ret < 0) {
 			dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
 			goto fail_gpio_req;
 		}
-
-		ret = gpio_direction_output(nreset_gpio, 0);
-		if (ret < 0) {
-			dev_err(&dssdev->dev, "couldn't set GPIO direction\n");
-			goto fail_gpio_direction;
-		}
 	}
 
 	ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
@@ -427,8 +422,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
 
 	return 0;
 
-fail_gpio_direction:
-	gpio_free(nreset_gpio);
 fail_gpio_req:
 	regulator_put(tpo_td043->vcc_reg);
 fail_regulator:
@@ -518,18 +511,7 @@ static struct spi_driver tpo_td043_spi_driver = {
 	.remove	= __devexit_p(tpo_td043_spi_remove),
 };
 
-static int __init tpo_td043_init(void)
-{
-	return spi_register_driver(&tpo_td043_spi_driver);
-}
-
-static void __exit tpo_td043_exit(void)
-{
-	spi_unregister_driver(&tpo_td043_spi_driver);
-}
-
-module_init(tpo_td043_init);
-module_exit(tpo_td043_exit);
+module_spi_driver(tpo_td043_spi_driver);
 
 MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");
 MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 2f58cf9..90df1a6 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1816,6 +1816,8 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
 			     specs->modedb, specs->modedb_len,
 			     NULL, 8);
 	} else if (specs->modedb != NULL) {
+		/* get first mode in database as fallback */
+		modedb = specs->modedb[0];
 		/* get preferred timing */
 		if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
 			int i;
@@ -1826,9 +1828,6 @@ static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,
 					break;
 				}
 			}
-		} else {
-			/* otherwise, get first mode in database */
-			modedb = specs->modedb[0];
 		}
 		var->bits_per_pixel = 8;
 		riva_update_var(var, &modedb);
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 0c63b69..e22bf9d 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -48,7 +48,8 @@
 #undef writel
 #define writel(v, r) do { \
 	printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
-	__raw_writel(v, r); } while (0)
+	__raw_writel(v, r); \
+} while (0)
 #endif /* FB_S3C_DEBUG_REGWRITE */
 
 /* irq_flags bits */
@@ -81,7 +82,9 @@ struct s3c_fb;
  * @palette: Address of palette memory, or 0 if none.
  * @has_prtcon: Set if has PRTCON register.
  * @has_shadowcon: Set if has SHADOWCON register.
+ * @has_blendcon: Set if has BLENDCON register.
  * @has_clksel: Set if VIDCON0 register has CLKSEL bit.
+ * @has_fixvclk: Set if VIDCON1 register has FIXVCLK bits.
  */
 struct s3c_fb_variant {
 	unsigned int	is_2443:1;
@@ -99,7 +102,9 @@ struct s3c_fb_variant {
 
 	unsigned int	has_prtcon:1;
 	unsigned int	has_shadowcon:1;
+	unsigned int	has_blendcon:1;
 	unsigned int	has_clksel:1;
+	unsigned int	has_fixvclk:1;
 };
 
 /**
@@ -186,7 +191,6 @@ struct s3c_fb_vsync {
  * struct s3c_fb - overall hardware state of the hardware
  * @slock: The spinlock protection for this data sturcture.
  * @dev: The device that we bound to, for printing, etc.
- * @regs_res: The resource we claimed for the IO registers.
  * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
  * @lcd_clk: The clk (sclk) feeding pixclk.
  * @regs: The mapped hardware registers.
@@ -202,7 +206,6 @@ struct s3c_fb_vsync {
 struct s3c_fb {
 	spinlock_t		slock;
 	struct device		*dev;
-	struct resource		*regs_res;
 	struct clk		*bus_clk;
 	struct clk		*lcd_clk;
 	void __iomem		*regs;
@@ -692,6 +695,17 @@ static int s3c_fb_set_par(struct fb_info *info)
 	writel(data, regs + sfb->variant.wincon + (win_no * 4));
 	writel(0x0, regs + sfb->variant.winmap + (win_no * 4));
 
+	/* Set alpha value width */
+	if (sfb->variant.has_blendcon) {
+		data = readl(sfb->regs + BLENDCON);
+		data &= ~BLENDCON_NEW_MASK;
+		if (var->transp.length > 4)
+			data |= BLENDCON_NEW_8BIT_ALPHA_VALUE;
+		else
+			data |= BLENDCON_NEW_4BIT_ALPHA_VALUE;
+		writel(data, sfb->regs + BLENDCON);
+	}
+
 	shadow_protect_win(win, 0);
 
 	pm_runtime_put_sync(sfb->dev);
@@ -1346,6 +1360,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 	struct resource *res;
 	int win;
 	int ret = 0;
+	u32 reg;
 
 	platid = platform_get_device_id(pdev);
 	fbdrv = (struct s3c_fb_driverdata *)platid->driver_data;
@@ -1361,7 +1376,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);
+	sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL);
 	if (!sfb) {
 		dev_err(dev, "no memory for framebuffers\n");
 		return -ENOMEM;
@@ -1404,33 +1419,25 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 		goto err_lcd_clk;
 	}
 
-	sfb->regs_res = request_mem_region(res->start, resource_size(res),
-					   dev_name(dev));
-	if (!sfb->regs_res) {
-		dev_err(dev, "failed to claim register region\n");
-		ret = -ENOENT;
-		goto err_lcd_clk;
-	}
-
-	sfb->regs = ioremap(res->start, resource_size(res));
+	sfb->regs = devm_request_and_ioremap(dev, res);
 	if (!sfb->regs) {
 		dev_err(dev, "failed to map registers\n");
 		ret = -ENXIO;
-		goto err_req_region;
+		goto err_lcd_clk;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		dev_err(dev, "failed to acquire irq resource\n");
 		ret = -ENOENT;
-		goto err_ioremap;
+		goto err_lcd_clk;
 	}
 	sfb->irq_no = res->start;
 	ret = request_irq(sfb->irq_no, s3c_fb_irq,
 			  0, "s3c_fb", sfb);
 	if (ret) {
 		dev_err(dev, "irq request failed\n");
-		goto err_ioremap;
+		goto err_lcd_clk;
 	}
 
 	dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
@@ -1444,6 +1451,14 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
 
+	/* set video clock running at under-run */
+	if (sfb->variant.has_fixvclk) {
+		reg = readl(sfb->regs + VIDCON1);
+		reg &= ~VIDCON1_VCLK_MASK;
+		reg |= VIDCON1_VCLK_RUN;
+		writel(reg, sfb->regs + VIDCON1);
+	}
+
 	/* zero all windows before we do anything */
 
 	for (win = 0; win < fbdrv->variant.nr_windows; win++)
@@ -1486,12 +1501,6 @@ err_pm_runtime:
 	pm_runtime_put_sync(sfb->dev);
 	free_irq(sfb->irq_no, sfb);
 
-err_ioremap:
-	iounmap(sfb->regs);
-
-err_req_region:
-	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-
 err_lcd_clk:
 	pm_runtime_disable(sfb->dev);
 
@@ -1505,7 +1514,6 @@ err_bus_clk:
 	clk_put(sfb->bus_clk);
 
 err_sfb:
-	kfree(sfb);
 	return ret;
 }
 
@@ -1529,8 +1537,6 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 
 	free_irq(sfb->irq_no, sfb);
 
-	iounmap(sfb->regs);
-
 	if (!sfb->variant.has_clksel) {
 		clk_disable(sfb->lcd_clk);
 		clk_put(sfb->lcd_clk);
@@ -1539,12 +1545,9 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
-	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-
 	pm_runtime_put_sync(sfb->dev);
 	pm_runtime_disable(sfb->dev);
 
-	kfree(sfb);
 	return 0;
 }
 
@@ -1579,6 +1582,7 @@ static int s3c_fb_resume(struct device *dev)
 	struct s3c_fb_platdata *pd = sfb->pdata;
 	struct s3c_fb_win *win;
 	int win_no;
+	u32 reg;
 
 	clk_enable(sfb->bus_clk);
 
@@ -1589,6 +1593,14 @@ static int s3c_fb_resume(struct device *dev)
 	pd->setup_gpio();
 	writel(pd->vidcon1, sfb->regs + VIDCON1);
 
+	/* set video clock running at under-run */
+	if (sfb->variant.has_fixvclk) {
+		reg = readl(sfb->regs + VIDCON1);
+		reg &= ~VIDCON1_VCLK_MASK;
+		reg |= VIDCON1_VCLK_RUN;
+		writel(reg, sfb->regs + VIDCON1);
+	}
+
 	/* zero all windows before we do anything */
 	for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++)
 		s3c_fb_clear_win(sfb, win_no);
@@ -1819,6 +1831,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = {
 		},
 
 		.has_prtcon	= 1,
+		.has_blendcon	= 1,
 		.has_clksel	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
@@ -1850,7 +1863,9 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = {
 		},
 
 		.has_shadowcon	= 1,
+		.has_blendcon	= 1,
 		.has_clksel	= 1,
+		.has_fixvclk	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1881,6 +1896,8 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = {
 		},
 
 		.has_shadowcon	= 1,
+		.has_blendcon	= 1,
+		.has_fixvclk	= 1,
 	},
 	.win[0]	= &s3c_fb_data_s5p_wins[0],
 	.win[1]	= &s3c_fb_data_s5p_wins[1],
@@ -1944,6 +1961,9 @@ static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = {
 			[1] = 0x2800,
 			[2] = 0x2c00,
 		},
+
+		.has_blendcon	= 1,
+		.has_fixvclk	= 1,
 	},
 	.win[0] = &s3c_fb_data_s5p_wins[0],
 	.win[1] = &s3c_fb_data_s5p_wins[1],
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 98d55d0..30e2dc3 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -173,282 +173,48 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/mutex.h>
 #include <linux/io.h>
 
+#include <video/sa1100fb.h>
+
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <mach/assabet.h>
 #include <mach/shannon.h>
 
 /*
- * debugging?
- */
-#define DEBUG 0
-/*
  * Complain if VAR is out of range.
  */
 #define DEBUG_VAR 1
 
-#undef ASSABET_PAL_VIDEO
-
 #include "sa1100fb.h"
 
-extern void (*sa1100fb_backlight_power)(int on);
-extern void (*sa1100fb_lcd_power)(int on);
-
-static struct sa1100fb_rgb rgb_4 = {
+static const struct sa1100fb_rgb rgb_4 = {
 	.red	= { .offset = 0,  .length = 4, },
 	.green	= { .offset = 0,  .length = 4, },
 	.blue	= { .offset = 0,  .length = 4, },
 	.transp	= { .offset = 0,  .length = 0, },
 };
 
-static struct sa1100fb_rgb rgb_8 = {
+static const struct sa1100fb_rgb rgb_8 = {
 	.red	= { .offset = 0,  .length = 8, },
 	.green	= { .offset = 0,  .length = 8, },
 	.blue	= { .offset = 0,  .length = 8, },
 	.transp	= { .offset = 0,  .length = 0, },
 };
 
-static struct sa1100fb_rgb def_rgb_16 = {
+static const struct sa1100fb_rgb def_rgb_16 = {
 	.red	= { .offset = 11, .length = 5, },
 	.green	= { .offset = 5,  .length = 6, },
 	.blue	= { .offset = 0,  .length = 5, },
 	.transp	= { .offset = 0,  .length = 0, },
 };
 
-#ifdef CONFIG_SA1100_ASSABET
-#ifndef ASSABET_PAL_VIDEO
-/*
- * The assabet uses a sharp LQ039Q2DS54 LCD module.  It is actually
- * takes an RGB666 signal, but we provide it with an RGB565 signal
- * instead (def_rgb_16).
- */
-static struct sa1100fb_mach_info lq039q2ds54_info __initdata = {
-	.pixclock	= 171521,	.bpp		= 16,
-	.xres		= 320,		.yres		= 240,
-
-	.hsync_len	= 5,		.vsync_len	= 1,
-	.left_margin	= 61,		.upper_margin	= 3,
-	.right_margin	= 9,		.lower_margin	= 0,
-
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#else
-static struct sa1100fb_mach_info pal_info __initdata = {
-	.pixclock	= 67797,	.bpp		= 16,
-	.xres		= 640,		.yres		= 512,
-
-	.hsync_len	= 64,		.vsync_len	= 6,
-	.left_margin	= 125,		.upper_margin	= 70,
-	.right_margin	= 115,		.lower_margin	= 36,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-#endif
-
-#ifdef CONFIG_SA1100_H3600
-static struct sa1100fb_mach_info h3600_info __initdata = {
-	.pixclock	= 174757, 	.bpp		= 16,
-	.xres		= 320,		.yres		= 240,
-
-	.hsync_len	= 3,		.vsync_len	= 3,
-	.left_margin	= 12,		.upper_margin	= 10,
-	.right_margin	= 17,		.lower_margin	= 1,
-
-	.cmap_static	= 1,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-
-static struct sa1100fb_rgb h3600_rgb_16 = {
-	.red	= { .offset = 12, .length = 4, },
-	.green	= { .offset = 7,  .length = 4, },
-	.blue	= { .offset = 1,  .length = 4, },
-	.transp	= { .offset = 0,  .length = 0, },
-};
-#endif
-
-#ifdef CONFIG_SA1100_H3100
-static struct sa1100fb_mach_info h3100_info __initdata = {
-	.pixclock	= 406977, 	.bpp		= 4,
-	.xres		= 320,		.yres		= 240,
-
-	.hsync_len	= 26,		.vsync_len	= 41,
-	.left_margin	= 4,		.upper_margin	= 0,
-	.right_margin	= 4,		.lower_margin	= 0,
-
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-	.cmap_greyscale	= 1,
-	.cmap_inverse	= 1,
-
-	.lccr0		= LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#endif
-
-#ifdef CONFIG_SA1100_COLLIE
-static struct sa1100fb_mach_info collie_info __initdata = {
-	.pixclock	= 171521,	.bpp		= 16,
-	.xres		= 320,		.yres		= 240,
-
-	.hsync_len	= 5,		.vsync_len	= 1,
-	.left_margin	= 11,		.upper_margin	= 2,
-	.right_margin	= 30,		.lower_margin	= 0,
-
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#endif
-
-#ifdef LART_GREY_LCD
-static struct sa1100fb_mach_info lart_grey_info __initdata = {
-	.pixclock	= 150000,	.bpp		= 4,
-	.xres		= 320,		.yres		= 240,
-
-	.hsync_len	= 1,		.vsync_len	= 1,
-	.left_margin	= 4,		.upper_margin	= 0,
-	.right_margin	= 2,		.lower_margin	= 0,
-
-	.cmap_greyscale	= 1,
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-	.lccr0		= LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-#ifdef LART_COLOR_LCD
-static struct sa1100fb_mach_info lart_color_info __initdata = {
-	.pixclock	= 150000,	.bpp		= 16,
-	.xres		= 320,		.yres		= 240,
-
-	.hsync_len	= 2,		.vsync_len	= 3,
-	.left_margin	= 69,		.upper_margin	= 14,
-	.right_margin	= 8,		.lower_margin	= 4,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-#ifdef LART_VIDEO_OUT
-static struct sa1100fb_mach_info lart_video_info __initdata = {
-	.pixclock	= 39721,	.bpp		= 16,
-	.xres		= 640,		.yres		= 480,
-
-	.hsync_len	= 95,		.vsync_len	= 2,
-	.left_margin	= 40,		.upper_margin	= 32,
-	.right_margin	= 24,		.lower_margin	= 11,
-
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
-};
-#endif
-
-#ifdef LART_KIT01_LCD
-static struct sa1100fb_mach_info lart_kit01_info __initdata = {
-	.pixclock	= 63291,	.bpp		= 16,
-	.xres		= 640,		.yres		= 480,
-
-	.hsync_len	= 64,		.vsync_len	= 3,
-	.left_margin	= 122,		.upper_margin	= 45,
-	.right_margin	= 10,		.lower_margin	= 10,
-
-	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	.lccr3		= LCCR3_OutEnH | LCCR3_PixFlEdg
-};
-#endif
-
-#ifdef CONFIG_SA1100_SHANNON
-static struct sa1100fb_mach_info shannon_info __initdata = {
-	.pixclock	= 152500,	.bpp		= 8,
-	.xres		= 640,		.yres		= 480,
-
-	.hsync_len	= 4,		.vsync_len	= 3,
-	.left_margin	= 2,		.upper_margin	= 0,
-	.right_margin	= 1,		.lower_margin	= 0,
-
-	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
-	.lccr0		= LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
-	.lccr3		= LCCR3_ACBsDiv(512),
-};
-#endif
-
 
 
-static struct sa1100fb_mach_info * __init
-sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
-{
-	struct sa1100fb_mach_info *inf = NULL;
-
-	/*
-	 *            R        G       B       T
-	 * default  {11,5}, { 5,6}, { 0,5}, { 0,0}
-	 * h3600    {12,4}, { 7,4}, { 1,4}, { 0,0}
-	 * freebird { 8,4}, { 4,4}, { 0,4}, {12,4}
-	 */
-#ifdef CONFIG_SA1100_ASSABET
-	if (machine_is_assabet()) {
-#ifndef ASSABET_PAL_VIDEO
-		inf = &lq039q2ds54_info;
-#else
-		inf = &pal_info;
-#endif
-	}
-#endif
-#ifdef CONFIG_SA1100_H3100
-	if (machine_is_h3100()) {
-		inf = &h3100_info;
-	}
-#endif
-#ifdef CONFIG_SA1100_H3600
-	if (machine_is_h3600()) {
-		inf = &h3600_info;
-		fbi->rgb[RGB_16] = &h3600_rgb_16;
-	}
-#endif
-#ifdef CONFIG_SA1100_COLLIE
-	if (machine_is_collie()) {
-		inf = &collie_info;
-	}
-#endif
-#ifdef CONFIG_SA1100_LART
-	if (machine_is_lart()) {
-#ifdef LART_GREY_LCD
-		inf = &lart_grey_info;
-#endif
-#ifdef LART_COLOR_LCD
-		inf = &lart_color_info;
-#endif
-#ifdef LART_VIDEO_OUT
-		inf = &lart_video_info;
-#endif
-#ifdef LART_KIT01_LCD
-		inf = &lart_kit01_info;
-#endif
-	}
-#endif
-#ifdef CONFIG_SA1100_SHANNON
-	if (machine_is_shannon()) {
-		inf = &shannon_info;
-	}
-#endif
-	return inf;
-}
-
 static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_info *);
 static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state);
 
@@ -533,7 +299,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 	 * is what you poke into the framebuffer to produce the
 	 * colour you requested.
 	 */
-	if (fbi->cmap_inverse) {
+	if (fbi->inf->cmap_inverse) {
 		red   = 0xffff - red;
 		green = 0xffff - green;
 		blue  = 0xffff - blue;
@@ -607,14 +373,14 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 		var->xres = MIN_XRES;
 	if (var->yres < MIN_YRES)
 		var->yres = MIN_YRES;
-	if (var->xres > fbi->max_xres)
-		var->xres = fbi->max_xres;
-	if (var->yres > fbi->max_yres)
-		var->yres = fbi->max_yres;
+	if (var->xres > fbi->inf->xres)
+		var->xres = fbi->inf->xres;
+	if (var->yres > fbi->inf->yres)
+		var->yres = fbi->inf->yres;
 	var->xres_virtual = max(var->xres_virtual, var->xres);
 	var->yres_virtual = max(var->yres_virtual, var->yres);
 
-	DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+	dev_dbg(fbi->dev, "var->bits_per_pixel=%d\n", var->bits_per_pixel);
 	switch (var->bits_per_pixel) {
 	case 4:
 		rgbidx = RGB_4;
@@ -638,16 +404,16 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 	var->blue   = fbi->rgb[rgbidx]->blue;
 	var->transp = fbi->rgb[rgbidx]->transp;
 
-	DPRINTK("RGBT length = %d:%d:%d:%d\n",
+	dev_dbg(fbi->dev, "RGBT length = %d:%d:%d:%d\n",
 		var->red.length, var->green.length, var->blue.length,
 		var->transp.length);
 
-	DPRINTK("RGBT offset = %d:%d:%d:%d\n",
+	dev_dbg(fbi->dev, "RGBT offset = %d:%d:%d:%d\n",
 		var->red.offset, var->green.offset, var->blue.offset,
 		var->transp.offset);
 
 #ifdef CONFIG_CPU_FREQ
-	printk(KERN_DEBUG "dma period = %d ps, clock = %d kHz\n",
+	dev_dbg(fbi->dev, "dma period = %d ps, clock = %d kHz\n",
 		sa1100fb_display_dma_period(var),
 		cpufreq_get(smp_processor_id()));
 #endif
@@ -655,22 +421,10 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 	return 0;
 }
 
-static inline void sa1100fb_set_truecolor(u_int is_true_color)
+static void sa1100fb_set_visual(struct sa1100fb_info *fbi, u32 visual)
 {
-	if (machine_is_assabet()) {
-#if 1		// phase 4 or newer Assabet's
-		if (is_true_color)
-			ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
-		else
-			ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
-#else
-		// older Assabet's
-		if (is_true_color)
-			ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
-		else
-			ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
-#endif
-	}
+	if (fbi->inf->set_visual)
+		fbi->inf->set_visual(visual);
 }
 
 /*
@@ -683,11 +437,11 @@ static int sa1100fb_set_par(struct fb_info *info)
 	struct fb_var_screeninfo *var = &info->var;
 	unsigned long palette_mem_size;
 
-	DPRINTK("set_par\n");
+	dev_dbg(fbi->dev, "set_par\n");
 
 	if (var->bits_per_pixel == 16)
 		fbi->fb.fix.visual = FB_VISUAL_TRUECOLOR;
-	else if (!fbi->cmap_static)
+	else if (!fbi->inf->cmap_static)
 		fbi->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
 	else {
 		/*
@@ -704,7 +458,7 @@ static int sa1100fb_set_par(struct fb_info *info)
 
 	palette_mem_size = fbi->palette_size * sizeof(u16);
 
-	DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
+	dev_dbg(fbi->dev, "palette_mem_size = 0x%08lx\n", palette_mem_size);
 
 	fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
 	fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
@@ -712,7 +466,7 @@ static int sa1100fb_set_par(struct fb_info *info)
 	/*
 	 * Set (any) board control register to handle new color depth
 	 */
-	sa1100fb_set_truecolor(fbi->fb.fix.visual == FB_VISUAL_TRUECOLOR);
+	sa1100fb_set_visual(fbi, fbi->fb.fix.visual);
 	sa1100fb_activate_var(var, fbi);
 
 	return 0;
@@ -728,7 +482,7 @@ sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
 	/*
 	 * Make sure the user isn't doing something stupid.
 	 */
-	if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->cmap_static))
+	if (!kspc && (fbi->fb.var.bits_per_pixel == 16 || fbi->inf->cmap_static))
 		return -EINVAL;
 
 	return gen_set_cmap(cmap, kspc, con, info);
@@ -775,7 +529,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
 	struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
 	int i;
 
-	DPRINTK("sa1100fb_blank: blank=%d\n", blank);
+	dev_dbg(fbi->dev, "sa1100fb_blank: blank=%d\n", blank);
 
 	switch (blank) {
 	case FB_BLANK_POWERDOWN:
@@ -863,43 +617,43 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
 	u_int half_screen_size, yres, pcd;
 	u_long flags;
 
-	DPRINTK("Configuring SA1100 LCD\n");
+	dev_dbg(fbi->dev, "Configuring SA1100 LCD\n");
 
-	DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n",
+	dev_dbg(fbi->dev, "var: xres=%d hslen=%d lm=%d rm=%d\n",
 		var->xres, var->hsync_len,
 		var->left_margin, var->right_margin);
-	DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n",
+	dev_dbg(fbi->dev, "var: yres=%d vslen=%d um=%d bm=%d\n",
 		var->yres, var->vsync_len,
 		var->upper_margin, var->lower_margin);
 
 #if DEBUG_VAR
 	if (var->xres < 16        || var->xres > 1024)
-		printk(KERN_ERR "%s: invalid xres %d\n",
+		dev_err(fbi->dev, "%s: invalid xres %d\n",
 			fbi->fb.fix.id, var->xres);
 	if (var->hsync_len < 1    || var->hsync_len > 64)
-		printk(KERN_ERR "%s: invalid hsync_len %d\n",
+		dev_err(fbi->dev, "%s: invalid hsync_len %d\n",
 			fbi->fb.fix.id, var->hsync_len);
 	if (var->left_margin < 1  || var->left_margin > 255)
-		printk(KERN_ERR "%s: invalid left_margin %d\n",
+		dev_err(fbi->dev, "%s: invalid left_margin %d\n",
 			fbi->fb.fix.id, var->left_margin);
 	if (var->right_margin < 1 || var->right_margin > 255)
-		printk(KERN_ERR "%s: invalid right_margin %d\n",
+		dev_err(fbi->dev, "%s: invalid right_margin %d\n",
 			fbi->fb.fix.id, var->right_margin);
 	if (var->yres < 1         || var->yres > 1024)
-		printk(KERN_ERR "%s: invalid yres %d\n",
+		dev_err(fbi->dev, "%s: invalid yres %d\n",
 			fbi->fb.fix.id, var->yres);
 	if (var->vsync_len < 1    || var->vsync_len > 64)
-		printk(KERN_ERR "%s: invalid vsync_len %d\n",
+		dev_err(fbi->dev, "%s: invalid vsync_len %d\n",
 			fbi->fb.fix.id, var->vsync_len);
 	if (var->upper_margin < 0 || var->upper_margin > 255)
-		printk(KERN_ERR "%s: invalid upper_margin %d\n",
+		dev_err(fbi->dev, "%s: invalid upper_margin %d\n",
 			fbi->fb.fix.id, var->upper_margin);
 	if (var->lower_margin < 0 || var->lower_margin > 255)
-		printk(KERN_ERR "%s: invalid lower_margin %d\n",
+		dev_err(fbi->dev, "%s: invalid lower_margin %d\n",
 			fbi->fb.fix.id, var->lower_margin);
 #endif
 
-	new_regs.lccr0 = fbi->lccr0 |
+	new_regs.lccr0 = fbi->inf->lccr0 |
 		LCCR0_LEN | LCCR0_LDM | LCCR0_BAM |
 		LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0);
 
@@ -914,7 +668,7 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
 	 * the YRES parameter.
 	 */
 	yres = var->yres;
-	if (fbi->lccr0 & LCCR0_Dual)
+	if (fbi->inf->lccr0 & LCCR0_Dual)
 		yres /= 2;
 
 	new_regs.lccr2 =
@@ -924,14 +678,14 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
 		LCCR2_EndFrmDel(var->lower_margin);
 
 	pcd = get_pcd(var->pixclock, cpufreq_get(0));
-	new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->lccr3 |
+	new_regs.lccr3 = LCCR3_PixClkDiv(pcd) | fbi->inf->lccr3 |
 		(var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
 		(var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
 
-	DPRINTK("nlccr0 = 0x%08lx\n", new_regs.lccr0);
-	DPRINTK("nlccr1 = 0x%08lx\n", new_regs.lccr1);
-	DPRINTK("nlccr2 = 0x%08lx\n", new_regs.lccr2);
-	DPRINTK("nlccr3 = 0x%08lx\n", new_regs.lccr3);
+	dev_dbg(fbi->dev, "nlccr0 = 0x%08lx\n", new_regs.lccr0);
+	dev_dbg(fbi->dev, "nlccr1 = 0x%08lx\n", new_regs.lccr1);
+	dev_dbg(fbi->dev, "nlccr2 = 0x%08lx\n", new_regs.lccr2);
+	dev_dbg(fbi->dev, "nlccr3 = 0x%08lx\n", new_regs.lccr3);
 
 	half_screen_size = var->bits_per_pixel;
 	half_screen_size = half_screen_size * var->xres * var->yres / 16;
@@ -951,9 +705,12 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
 	 * Only update the registers if the controller is enabled
 	 * and something has changed.
 	 */
-	if ((LCCR0 != fbi->reg_lccr0)       || (LCCR1 != fbi->reg_lccr1) ||
-	    (LCCR2 != fbi->reg_lccr2)       || (LCCR3 != fbi->reg_lccr3) ||
-	    (DBAR1 != fbi->dbar1) || (DBAR2 != fbi->dbar2))
+	if (readl_relaxed(fbi->base + LCCR0) != fbi->reg_lccr0 ||
+	    readl_relaxed(fbi->base + LCCR1) != fbi->reg_lccr1 ||
+	    readl_relaxed(fbi->base + LCCR2) != fbi->reg_lccr2 ||
+	    readl_relaxed(fbi->base + LCCR3) != fbi->reg_lccr3 ||
+	    readl_relaxed(fbi->base + DBAR1) != fbi->dbar1 ||
+	    readl_relaxed(fbi->base + DBAR2) != fbi->dbar2)
 		sa1100fb_schedule_work(fbi, C_REENABLE);
 
 	return 0;
@@ -967,18 +724,18 @@ static int sa1100fb_activate_var(struct fb_var_screeninfo *var, struct sa1100fb_
  */
 static inline void __sa1100fb_backlight_power(struct sa1100fb_info *fbi, int on)
 {
-	DPRINTK("backlight o%s\n", on ? "n" : "ff");
+	dev_dbg(fbi->dev, "backlight o%s\n", on ? "n" : "ff");
 
-	if (sa1100fb_backlight_power)
-		sa1100fb_backlight_power(on);
+	if (fbi->inf->backlight_power)
+		fbi->inf->backlight_power(on);
 }
 
 static inline void __sa1100fb_lcd_power(struct sa1100fb_info *fbi, int on)
 {
-	DPRINTK("LCD power o%s\n", on ? "n" : "ff");
+	dev_dbg(fbi->dev, "LCD power o%s\n", on ? "n" : "ff");
 
-	if (sa1100fb_lcd_power)
-		sa1100fb_lcd_power(on);
+	if (fbi->inf->lcd_power)
+		fbi->inf->lcd_power(on);
 }
 
 static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
@@ -1008,14 +765,25 @@ static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
 	}
 
 	if (mask) {
+		unsigned long flags;
+
+		/*
+		 * SA-1100 requires the GPIO direction register set
+		 * appropriately for the alternate function.  Hence
+		 * we set it here via bitmask rather than excessive
+		 * fiddling via the GPIO subsystem - and even then
+		 * we'll still have to deal with GAFR.
+		 */
+		local_irq_save(flags);
 		GPDR |= mask;
 		GAFR |= mask;
+		local_irq_restore(flags);
 	}
 }
 
 static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
 {
-	DPRINTK("Enabling LCD controller\n");
+	dev_dbg(fbi->dev, "Enabling LCD controller\n");
 
 	/*
 	 * Make sure the mode bits are present in the first palette entry
@@ -1024,43 +792,46 @@ static void sa1100fb_enable_controller(struct sa1100fb_info *fbi)
 	fbi->palette_cpu[0] |= palette_pbs(&fbi->fb.var);
 
 	/* Sequence from 11.7.10 */
-	LCCR3 = fbi->reg_lccr3;
-	LCCR2 = fbi->reg_lccr2;
-	LCCR1 = fbi->reg_lccr1;
-	LCCR0 = fbi->reg_lccr0 & ~LCCR0_LEN;
-	DBAR1 = fbi->dbar1;
-	DBAR2 = fbi->dbar2;
-	LCCR0 |= LCCR0_LEN;
-
-	if (machine_is_shannon()) {
-		GPDR |= SHANNON_GPIO_DISP_EN;
-		GPSR |= SHANNON_GPIO_DISP_EN;
-	}
-
-	DPRINTK("DBAR1 = 0x%08x\n", DBAR1);
-	DPRINTK("DBAR2 = 0x%08x\n", DBAR2);
-	DPRINTK("LCCR0 = 0x%08x\n", LCCR0);
-	DPRINTK("LCCR1 = 0x%08x\n", LCCR1);
-	DPRINTK("LCCR2 = 0x%08x\n", LCCR2);
-	DPRINTK("LCCR3 = 0x%08x\n", LCCR3);
+	writel_relaxed(fbi->reg_lccr3, fbi->base + LCCR3);
+	writel_relaxed(fbi->reg_lccr2, fbi->base + LCCR2);
+	writel_relaxed(fbi->reg_lccr1, fbi->base + LCCR1);
+	writel_relaxed(fbi->reg_lccr0 & ~LCCR0_LEN, fbi->base + LCCR0);
+	writel_relaxed(fbi->dbar1, fbi->base + DBAR1);
+	writel_relaxed(fbi->dbar2, fbi->base + DBAR2);
+	writel_relaxed(fbi->reg_lccr0 | LCCR0_LEN, fbi->base + LCCR0);
+
+	if (machine_is_shannon())
+		gpio_set_value(SHANNON_GPIO_DISP_EN, 1);
+
+	dev_dbg(fbi->dev, "DBAR1: 0x%08lx\n", readl_relaxed(fbi->base + DBAR1));
+	dev_dbg(fbi->dev, "DBAR2: 0x%08lx\n", readl_relaxed(fbi->base + DBAR2));
+	dev_dbg(fbi->dev, "LCCR0: 0x%08lx\n", readl_relaxed(fbi->base + LCCR0));
+	dev_dbg(fbi->dev, "LCCR1: 0x%08lx\n", readl_relaxed(fbi->base + LCCR1));
+	dev_dbg(fbi->dev, "LCCR2: 0x%08lx\n", readl_relaxed(fbi->base + LCCR2));
+	dev_dbg(fbi->dev, "LCCR3: 0x%08lx\n", readl_relaxed(fbi->base + LCCR3));
 }
 
 static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
 {
 	DECLARE_WAITQUEUE(wait, current);
+	u32 lccr0;
 
-	DPRINTK("Disabling LCD controller\n");
+	dev_dbg(fbi->dev, "Disabling LCD controller\n");
 
-	if (machine_is_shannon()) {
-		GPCR |= SHANNON_GPIO_DISP_EN;
-	}	
+	if (machine_is_shannon())
+		gpio_set_value(SHANNON_GPIO_DISP_EN, 0);
 
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	add_wait_queue(&fbi->ctrlr_wait, &wait);
 
-	LCSR = 0xffffffff;	/* Clear LCD Status Register */
-	LCCR0 &= ~LCCR0_LDM;	/* Enable LCD Disable Done Interrupt */
-	LCCR0 &= ~LCCR0_LEN;	/* Disable LCD Controller */
+	/* Clear LCD Status Register */
+	writel_relaxed(~0, fbi->base + LCSR);
+
+	lccr0 = readl_relaxed(fbi->base + LCCR0);
+	lccr0 &= ~LCCR0_LDM;	/* Enable LCD Disable Done Interrupt */
+	writel_relaxed(lccr0, fbi->base + LCCR0);
+	lccr0 &= ~LCCR0_LEN;	/* Disable LCD Controller */
+	writel_relaxed(lccr0, fbi->base + LCCR0);
 
 	schedule_timeout(20 * HZ / 1000);
 	remove_wait_queue(&fbi->ctrlr_wait, &wait);
@@ -1072,14 +843,15 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
 static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id)
 {
 	struct sa1100fb_info *fbi = dev_id;
-	unsigned int lcsr = LCSR;
+	unsigned int lcsr = readl_relaxed(fbi->base + LCSR);
 
 	if (lcsr & LCSR_LDD) {
-		LCCR0 |= LCCR0_LDM;
+		u32 lccr0 = readl_relaxed(fbi->base + LCCR0) | LCCR0_LDM;
+		writel_relaxed(lccr0, fbi->base + LCCR0);
 		wake_up(&fbi->ctrlr_wait);
 	}
 
-	LCSR = lcsr;
+	writel_relaxed(lcsr, fbi->base + LCSR);
 	return IRQ_HANDLED;
 }
 
@@ -1268,7 +1040,7 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
 	switch (val) {
 	case CPUFREQ_ADJUST:
 	case CPUFREQ_INCOMPATIBLE:
-		printk(KERN_DEBUG "min dma period: %d ps, "
+		dev_dbg(fbi->dev, "min dma period: %d ps, "
 			"new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
 			policy->max);
 		/* todo: fill in min/max values */
@@ -1318,7 +1090,7 @@ static int sa1100fb_resume(struct platform_device *dev)
  *      cache.  Once this area is remapped, all virtual memory
  *      access to the video memory should occur at the new region.
  */
-static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
+static int __devinit sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
 {
 	/*
 	 * We reserve one page for the palette, plus the size
@@ -1344,7 +1116,7 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
 }
 
 /* Fake monspecs to fill in fbinfo structure */
-static struct fb_monspecs monspecs __initdata = {
+static struct fb_monspecs monspecs __devinitdata = {
 	.hfmin	= 30000,
 	.hfmax	= 70000,
 	.vfmin	= 50,
@@ -1352,10 +1124,11 @@ static struct fb_monspecs monspecs __initdata = {
 };
 
 
-static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
+static struct sa1100fb_info * __devinit sa1100fb_init_fbinfo(struct device *dev)
 {
-	struct sa1100fb_mach_info *inf;
+	struct sa1100fb_mach_info *inf = dev->platform_data;
 	struct sa1100fb_info *fbi;
+	unsigned i;
 
 	fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16,
 		      GFP_KERNEL);
@@ -1390,8 +1163,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
 	fbi->rgb[RGB_8]		= &rgb_8;
 	fbi->rgb[RGB_16]	= &def_rgb_16;
 
-	inf = sa1100fb_get_machine_info(fbi);
-
 	/*
 	 * People just don't seem to get this.  We don't support
 	 * anything but correct entries now, so panic if someone
@@ -1402,13 +1173,10 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
 		panic("sa1100fb error: invalid LCCR3 fields set or zero "
 			"pixclock.");
 
-	fbi->max_xres			= inf->xres;
 	fbi->fb.var.xres		= inf->xres;
 	fbi->fb.var.xres_virtual	= inf->xres;
-	fbi->max_yres			= inf->yres;
 	fbi->fb.var.yres		= inf->yres;
 	fbi->fb.var.yres_virtual	= inf->yres;
-	fbi->max_bpp			= inf->bpp;
 	fbi->fb.var.bits_per_pixel	= inf->bpp;
 	fbi->fb.var.pixclock		= inf->pixclock;
 	fbi->fb.var.hsync_len		= inf->hsync_len;
@@ -1419,14 +1187,16 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
 	fbi->fb.var.lower_margin	= inf->lower_margin;
 	fbi->fb.var.sync		= inf->sync;
 	fbi->fb.var.grayscale		= inf->cmap_greyscale;
-	fbi->cmap_inverse		= inf->cmap_inverse;
-	fbi->cmap_static		= inf->cmap_static;
-	fbi->lccr0			= inf->lccr0;
-	fbi->lccr3			= inf->lccr3;
 	fbi->state			= C_STARTUP;
 	fbi->task_state			= (u_char)-1;
-	fbi->fb.fix.smem_len		= fbi->max_xres * fbi->max_yres *
-					  fbi->max_bpp / 8;
+	fbi->fb.fix.smem_len		= inf->xres * inf->yres *
+					  inf->bpp / 8;
+	fbi->inf			= inf;
+
+	/* Copy the RGB bitfield overrides */
+	for (i = 0; i < NR_RGB; i++)
+		if (inf->rgb[i])
+			fbi->rgb[i] = inf->rgb[i];
 
 	init_waitqueue_head(&fbi->ctrlr_wait);
 	INIT_WORK(&fbi->task, sa1100fb_task);
@@ -1438,13 +1208,20 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
 static int __devinit sa1100fb_probe(struct platform_device *pdev)
 {
 	struct sa1100fb_info *fbi;
+	struct resource *res;
 	int ret, irq;
 
+	if (!pdev->dev.platform_data) {
+		dev_err(&pdev->dev, "no platform LCD data\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
+	if (irq < 0 || !res)
 		return -EINVAL;
 
-	if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
+	if (!request_mem_region(res->start, resource_size(res), "LCD"))
 		return -EBUSY;
 
 	fbi = sa1100fb_init_fbinfo(&pdev->dev);
@@ -1452,6 +1229,10 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
 	if (!fbi)
 		goto failed;
 
+	fbi->base = ioremap(res->start, resource_size(res));
+	if (!fbi->base)
+		goto failed;
+
 	/* Initialize video memory */
 	ret = sa1100fb_map_video_memory(fbi);
 	if (ret)
@@ -1459,14 +1240,16 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
 
 	ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi);
 	if (ret) {
-		printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
+		dev_err(&pdev->dev, "request_irq failed: %d\n", ret);
 		goto failed;
 	}
 
-#ifdef ASSABET_PAL_VIDEO
-	if (machine_is_assabet())
-		ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
-#endif
+	if (machine_is_shannon()) {
+		ret = gpio_request_one(SHANNON_GPIO_DISP_EN,
+			GPIOF_OUT_INIT_LOW, "display enable");
+		if (ret)
+			goto err_free_irq;
+	}
 
 	/*
 	 * This makes sure that our colour bitfield
@@ -1478,7 +1261,7 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
 
 	ret = register_framebuffer(&fbi->fb);
 	if (ret < 0)
-		goto err_free_irq;
+		goto err_reg_fb;
 
 #ifdef CONFIG_CPU_FREQ
 	fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
@@ -1490,12 +1273,17 @@ static int __devinit sa1100fb_probe(struct platform_device *pdev)
 	/* This driver cannot be unloaded at the moment */
 	return 0;
 
+ err_reg_fb:
+	if (machine_is_shannon())
+		gpio_free(SHANNON_GPIO_DISP_EN);
  err_free_irq:
 	free_irq(irq, fbi);
  failed:
+	if (fbi)
+		iounmap(fbi->base);
 	platform_set_drvdata(pdev, NULL);
 	kfree(fbi);
-	release_mem_region(0xb0100000, 0x10000);
+	release_mem_region(res->start, resource_size(res));
 	return ret;
 }
 
@@ -1505,6 +1293,7 @@ static struct platform_driver sa1100fb_driver = {
 	.resume		= sa1100fb_resume,
 	.driver		= {
 		.name	= "sa11x0-fb",
+		.owner	= THIS_MODULE,
 	},
 };
 
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index 1c3b459..fc5d429 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -10,44 +10,15 @@
  * for more details.
  */
 
-/*
- * These are the bitfields for each
- * display depth that we support.
- */
-struct sa1100fb_rgb {
-	struct fb_bitfield	red;
-	struct fb_bitfield	green;
-	struct fb_bitfield	blue;
-	struct fb_bitfield	transp;
-};
-
-/*
- * This structure describes the machine which we are running on.
- */
-struct sa1100fb_mach_info {
-	u_long		pixclock;
-
-	u_short		xres;
-	u_short		yres;
-
-	u_char		bpp;
-	u_char		hsync_len;
-	u_char		left_margin;
-	u_char		right_margin;
-
-	u_char		vsync_len;
-	u_char		upper_margin;
-	u_char		lower_margin;
-	u_char		sync;
-
-	u_int		cmap_greyscale:1,
-			cmap_inverse:1,
-			cmap_static:1,
-			unused:29;
-
-	u_int		lccr0;
-	u_int		lccr3;
-};
+#define LCCR0           0x0000          /* LCD Control Reg. 0 */
+#define LCSR            0x0004          /* LCD Status Reg. */
+#define DBAR1           0x0010          /* LCD DMA Base Address Reg. channel 1 */
+#define DCAR1           0x0014          /* LCD DMA Current Address Reg. channel 1 */
+#define DBAR2           0x0018          /* LCD DMA Base Address Reg.  channel 2 */
+#define DCAR2           0x001C          /* LCD DMA Current Address Reg. channel 2 */
+#define LCCR1           0x0020          /* LCD Control Reg. 1 */
+#define LCCR2           0x0024          /* LCD Control Reg. 2 */
+#define LCCR3           0x0028          /* LCD Control Reg. 3 */
 
 /* Shadows for LCD controller registers */
 struct sa1100fb_lcd_reg {
@@ -57,19 +28,11 @@ struct sa1100fb_lcd_reg {
 	unsigned long lccr3;
 };
 
-#define RGB_4	(0)
-#define RGB_8	(1)
-#define RGB_16	(2)
-#define NR_RGB	3
-
 struct sa1100fb_info {
 	struct fb_info		fb;
 	struct device		*dev;
-	struct sa1100fb_rgb	*rgb[NR_RGB];
-
-	u_int			max_bpp;
-	u_int			max_xres;
-	u_int			max_yres;
+	const struct sa1100fb_rgb *rgb[NR_RGB];
+	void __iomem		*base;
 
 	/*
 	 * These are the addresses we mapped
@@ -88,12 +51,6 @@ struct sa1100fb_info {
 	dma_addr_t		dbar1;
 	dma_addr_t		dbar2;
 
-	u_int			lccr0;
-	u_int			lccr3;
-	u_int			cmap_inverse:1,
-				cmap_static:1,
-				unused:30;
-
 	u_int			reg_lccr0;
 	u_int			reg_lccr1;
 	u_int			reg_lccr2;
@@ -109,6 +66,8 @@ struct sa1100fb_info {
 	struct notifier_block	freq_transition;
 	struct notifier_block	freq_policy;
 #endif
+
+	const struct sa1100fb_mach_info *inf;
 };
 
 #define TO_INF(ptr,member)	container_of(ptr,struct sa1100fb_info,member)
@@ -130,15 +89,6 @@ struct sa1100fb_info {
 #define SA1100_NAME	"SA1100"
 
 /*
- *  Debug macros 
- */
-#if DEBUG
-#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __func__ , ## args)
-#else
-#  define DPRINTK(fmt, args...)
-#endif
-
-/*
  * Minimum X and Y resolutions
  */
 #define MIN_XRES	64
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index a197731..a40c05e 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
 	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
 		device_remove_file(info->dev, &fb_device_attrs[i]);
 	device_remove_bin_file(info->dev, &edid_attr);
-
+	unlink_framebuffer(info);
 	usb_set_intfdata(interface, NULL);
 
 	/* if clients still have us open, will be freed on last close */
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e7f69ef..506d16e 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -121,7 +121,7 @@ static int uvesafb_helper_start(void)
 		NULL,
 	};
 
-	return call_usermodehelper(v86d_path, argv, envp, 1);
+	return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
 }
 
 /*
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index 5108136..159f26e 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/via/Makefile
@@ -6,4 +6,7 @@ obj-$(CONFIG_FB_VIA) += viafb.o
 
 viafb-y	:=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \
 	via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \
-	via-core.o via-gpio.o via_modesetting.o via_clock.o
+	via-core.o via-gpio.o via_modesetting.o via_clock.o \
+	via_aux.o via_aux_edid.o via_aux_vt1636.o via_aux_vt1632.o \
+	via_aux_vt1631.o via_aux_vt1625.o via_aux_vt1622.o via_aux_vt1621.o \
+	via_aux_sii164.o via_aux_ch7301.o
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 3ebf20c..c2ecdb5 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -146,8 +146,6 @@ struct tmds_setting_information {
 
 struct lvds_setting_information {
 	int iga_path;
-	int h_active;
-	int v_active;
 	int bpp;
 	int lcd_panel_hres;
 	int lcd_panel_vres;
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index 9138e51..3312c81 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -172,7 +172,8 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
 }
 
 /* DVI Set Mode */
-void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
+void viafb_dvi_set_mode(const struct fb_var_screeninfo *var,
+	u16 cxres, u16 cyres, int iga)
 {
 	struct fb_var_screeninfo dvi_var = *var;
 	struct crt_mode_table *rb_mode;
@@ -185,7 +186,7 @@ void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
 			viafb_fill_var_timing_info(&dvi_var, rb_mode);
 	}
 
-	viafb_fill_crtc_timing(&dvi_var, iga);
+	viafb_fill_crtc_timing(&dvi_var, cxres, cyres, iga);
 }
 
 /* Sense DVI Connector */
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index e2116aa..db75785 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -59,6 +59,7 @@ void viafb_dvi_enable(void);
 bool __devinit viafb_tmds_trasmitter_identify(void);
 void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
 	struct tmds_setting_information *tmds_setting);
-void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga);
+void viafb_dvi_set_mode(const struct fb_var_screeninfo *var,
+	u16 cxres, u16 cyres, int iga);
 
 #endif /* __DVI_H__ */
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index d5aaca9..d35ced7 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1467,28 +1467,31 @@ void viafb_set_vclock(u32 clk, int set_iga)
 	via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
 }
 
-static struct display_timing var_to_timing(const struct fb_var_screeninfo *var)
+static struct display_timing var_to_timing(const struct fb_var_screeninfo *var, u16 cxres, u16 cyres)
 {
 	struct display_timing timing;
+	u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
 
-	timing.hor_addr = var->xres;
-	timing.hor_sync_start = timing.hor_addr + var->right_margin;
+	timing.hor_addr = cxres;
+	timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;
 	timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
-	timing.hor_total = timing.hor_sync_end + var->left_margin;
-	timing.hor_blank_start = timing.hor_addr;
-	timing.hor_blank_end = timing.hor_total;
-	timing.ver_addr = var->yres;
-	timing.ver_sync_start = timing.ver_addr + var->lower_margin;
+	timing.hor_total = timing.hor_sync_end + var->left_margin + dx;
+	timing.hor_blank_start = timing.hor_addr + dx;
+	timing.hor_blank_end = timing.hor_total - dy;
+	timing.ver_addr = cyres;
+	timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;
 	timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
-	timing.ver_total = timing.ver_sync_end + var->upper_margin;
-	timing.ver_blank_start = timing.ver_addr;
-	timing.ver_blank_end = timing.ver_total;
+	timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;
+	timing.ver_blank_start = timing.ver_addr + dy;
+	timing.ver_blank_end = timing.ver_total - dy;
 	return timing;
 }
 
-void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga)
+void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
+	u16 cxres, u16 cyres, int iga)
 {
-	struct display_timing crt_reg = var_to_timing(var);
+	struct display_timing crt_reg = var_to_timing(var,
+		cxres ? cxres : var->xres, cyres ? cyres : var->yres);
 
 	if (iga == IGA1)
 		via_set_primary_timing(&crt_reg);
@@ -1527,11 +1530,7 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
 		viaparinfo->tmds_setting_info->h_active = hres;
 		viaparinfo->tmds_setting_info->v_active = vres;
 
-		viaparinfo->lvds_setting_info->h_active = hres;
-		viaparinfo->lvds_setting_info->v_active = vres;
 		viaparinfo->lvds_setting_info->bpp = bpp;
-		viaparinfo->lvds_setting_info2->h_active = hres;
-		viaparinfo->lvds_setting_info2->v_active = vres;
 		viaparinfo->lvds_setting_info2->bpp = bpp;
 	} else {
 
@@ -1540,16 +1539,11 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
 			viaparinfo->tmds_setting_info->v_active = vres;
 		}
 
-		if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
-			viaparinfo->lvds_setting_info->h_active = hres;
-			viaparinfo->lvds_setting_info->v_active = vres;
+		if (viaparinfo->lvds_setting_info->iga_path == IGA2)
 			viaparinfo->lvds_setting_info->bpp = bpp;
-		}
-		if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
-			viaparinfo->lvds_setting_info2->h_active = hres;
-			viaparinfo->lvds_setting_info2->v_active = vres;
+
+		if (IGA2 == viaparinfo->lvds_setting_info2->iga_path)
 			viaparinfo->lvds_setting_info2->bpp = bpp;
-		}
 	}
 }
 
@@ -1758,13 +1752,13 @@ static void set_display_channel(void)
 	}
 }
 
-static u8 get_sync(struct fb_info *info)
+static u8 get_sync(struct fb_var_screeninfo *var)
 {
 	u8 polarity = 0;
 
-	if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
+	if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
 		polarity |= VIA_HSYNC_NEGATIVE;
-	if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
+	if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
 		polarity |= VIA_VSYNC_NEGATIVE;
 	return polarity;
 }
@@ -1842,7 +1836,7 @@ static void hw_init(void)
 
 int viafb_setmode(int video_bpp, int video_bpp1)
 {
-	int j;
+	int j, cxres = 0, cyres = 0;
 	int port;
 	u32 devices = viaparinfo->shared->iga1_devices
 		| viaparinfo->shared->iga2_devices;
@@ -1891,6 +1885,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 	} else if (viafb_SAMM_ON) {
 		viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
 			viafb_second_xres, viafb_second_yres, viafb_refresh1));
+		cxres = viafbinfo->var.xres;
+		cyres = viafbinfo->var.yres;
 		var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
 	}
 
@@ -1898,9 +1894,9 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 	if (viafb_CRT_ON) {
 		if (viaparinfo->shared->iga2_devices & VIA_CRT
 			&& viafb_SAMM_ON)
-			viafb_fill_crtc_timing(&var2, IGA2);
+			viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);
 		else
-			viafb_fill_crtc_timing(&viafbinfo->var,
+			viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,
 				(viaparinfo->shared->iga1_devices & VIA_CRT)
 				? IGA1 : IGA2);
 
@@ -1918,9 +1914,9 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 	if (viafb_DVI_ON) {
 		if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
 			&& viafb_SAMM_ON)
-			viafb_dvi_set_mode(&var2, IGA2);
+			viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);
 		else
-			viafb_dvi_set_mode(&viafbinfo->var,
+			viafb_dvi_set_mode(&viafbinfo->var, 0, 0,
 				viaparinfo->tmds_setting_info->iga_path);
 	}
 
@@ -1928,7 +1924,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 		if (viafb_SAMM_ON &&
 			(viaparinfo->lvds_setting_info->iga_path == IGA2)) {
 			viaparinfo->lvds_setting_info->bpp = video_bpp1;
-			viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
+			viafb_lcd_set_mode(&var2, cxres, cyres,
+				viaparinfo->lvds_setting_info,
 				&viaparinfo->chip_info->lvds_chip_info);
 		} else {
 			/* IGA1 doesn't have LCD scaling, so set it center. */
@@ -1937,7 +1934,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 				    LCD_CENTERING;
 			}
 			viaparinfo->lvds_setting_info->bpp = video_bpp;
-			viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
+			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
+				viaparinfo->lvds_setting_info,
 				&viaparinfo->chip_info->lvds_chip_info);
 		}
 	}
@@ -1945,7 +1943,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 		if (viafb_SAMM_ON &&
 			(viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
 			viaparinfo->lvds_setting_info2->bpp = video_bpp1;
-			viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
+			viafb_lcd_set_mode(&var2, cxres, cyres,
+				viaparinfo->lvds_setting_info2,
 				&viaparinfo->chip_info->lvds_chip_info2);
 		} else {
 			/* IGA1 doesn't have LCD scaling, so set it center. */
@@ -1954,7 +1953,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 				    LCD_CENTERING;
 			}
 			viaparinfo->lvds_setting_info2->bpp = video_bpp;
-			viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
+			viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
+				viaparinfo->lvds_setting_info2,
 				&viaparinfo->chip_info->lvds_chip_info2);
 		}
 	}
@@ -1976,13 +1976,13 @@ int viafb_setmode(int video_bpp, int video_bpp1)
 			viafb_DeviceStatus = CRT_Device;
 	}
 	device_on();
-	if (!viafb_dual_fb)
-		via_set_sync_polarity(devices, get_sync(viafbinfo));
+	if (!viafb_SAMM_ON)
+		via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
 	else {
 		via_set_sync_polarity(viaparinfo->shared->iga1_devices,
-			get_sync(viafbinfo));
+			get_sync(&viafbinfo->var));
 		via_set_sync_polarity(viaparinfo->shared->iga2_devices,
-			get_sync(viafbinfo1));
+			get_sync(&var2));
 	}
 
 	clock.set_engine_pll_state(VIA_STATE_ON);
@@ -2125,7 +2125,6 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
 	}
 }
 
-/*According var's xres, yres fill var's other timing information*/
 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
 	struct crt_mode_table *mode)
 {
@@ -2134,6 +2133,8 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
 	crt_reg = mode->crtc;
 	var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total)
 		* 1000 / mode->refresh_rate;
+	var->xres = crt_reg.hor_addr;
+	var->yres = crt_reg.ver_addr;
 	var->left_margin =
 	    crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
 	var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 4db5b6e..f8129e4 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -637,7 +637,8 @@ extern int viafb_LCD_ON;
 extern int viafb_DVI_ON;
 extern int viafb_hotplug;
 
-void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga);
+void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
+	u16 cxres, u16 cyres, int iga);
 void viafb_set_vclock(u32 CLK, int set_iga);
 void viafb_load_reg(int timing_value, int viafb_load_reg_num,
 	struct io_register *reg,
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 5f3b4e3..02cfdc8 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -55,8 +55,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
 		      int panel_vres);
 static void via_pitch_alignment_patch_lcd(
 	struct lvds_setting_information *plvds_setting_info,
-				   struct lvds_chip_information
-				   *plvds_chip_info);
+	struct lvds_chip_information *plvds_chip_info, int hres);
 static void lcd_patch_skew_dvp0(struct lvds_setting_information
 			 *plvds_setting_info,
 			 struct lvds_chip_information *plvds_chip_info);
@@ -456,14 +455,13 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
 
 static void via_pitch_alignment_patch_lcd(
 	struct lvds_setting_information *plvds_setting_info,
-				   struct lvds_chip_information
-				   *plvds_chip_info)
+	struct lvds_chip_information *plvds_chip_info, int hres)
 {
 	unsigned char cr13, cr35, cr65, cr66, cr67;
 	unsigned long dwScreenPitch = 0;
 	unsigned long dwPitch;
 
-	dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
+	dwPitch = hres * (plvds_setting_info->bpp >> 3);
 	if (dwPitch & 0x1F) {
 		dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
 		if (plvds_setting_info->iga_path == IGA2) {
@@ -548,13 +546,14 @@ static void lcd_patch_skew(struct lvds_setting_information
 }
 
 /* LCD Set Mode */
-void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
+void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
+	u16 cyres, struct lvds_setting_information *plvds_setting_info,
 	struct lvds_chip_information *plvds_chip_info)
 {
 	int set_iga = plvds_setting_info->iga_path;
 	int mode_bpp = plvds_setting_info->bpp;
-	int set_hres = plvds_setting_info->h_active;
-	int set_vres = plvds_setting_info->v_active;
+	int set_hres = cxres ? cxres : var->xres;
+	int set_vres = cyres ? cyres : var->yres;
 	int panel_hres = plvds_setting_info->lcd_panel_hres;
 	int panel_vres = plvds_setting_info->lcd_panel_vres;
 	u32 clock;
@@ -613,7 +612,8 @@ void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
 		viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
 
 	/* Patch for non 32bit alignment mode */
-	via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
+	via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info,
+		set_hres);
 }
 
 static void integrated_lvds_disable(struct lvds_setting_information
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index 77ca7b8..8f3e4e0 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -76,7 +76,8 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
 				*plvds_chip_info,
 				struct lvds_setting_information
 				*plvds_setting_info);
-void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
+void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
+	u16 cyres, struct lvds_setting_information *plvds_setting_info,
 	struct lvds_chip_information *plvds_chip_info);
 bool __devinit viafb_lvds_trasmitter_identify(void);
 void viafb_init_lvds_output_interface(struct lvds_chip_information
diff --git a/drivers/video/via/via_aux.c b/drivers/video/via/via_aux.c
new file mode 100644
index 0000000..4a0a55c
--- /dev/null
+++ b/drivers/video/via/via_aux.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * infrastructure for devices connected via I2C
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap)
+{
+	struct via_aux_bus *bus;
+
+	if (!adap)
+		return NULL;
+
+	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	bus->adap = adap;
+	INIT_LIST_HEAD(&bus->drivers);
+
+	via_aux_edid_probe(bus);
+	via_aux_vt1636_probe(bus);
+	via_aux_vt1632_probe(bus);
+	via_aux_vt1631_probe(bus);
+	via_aux_vt1625_probe(bus);
+	via_aux_vt1622_probe(bus);
+	via_aux_vt1621_probe(bus);
+	via_aux_sii164_probe(bus);
+	via_aux_ch7301_probe(bus);
+
+	return bus;
+}
+
+void via_aux_free(struct via_aux_bus *bus)
+{
+	struct via_aux_drv *pos, *n;
+
+	if (!bus)
+		return;
+
+	list_for_each_entry_safe(pos, n, &bus->drivers, chain) {
+		if (pos->cleanup)
+			pos->cleanup(pos);
+
+		list_del(&pos->chain);
+		kfree(pos->data);
+		kfree(pos);
+	}
+
+	kfree(bus);
+}
+
+const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus)
+{
+	struct via_aux_drv *pos;
+	const struct fb_videomode *mode = NULL;
+
+	if (!bus)
+		return NULL;
+
+	list_for_each_entry(pos, &bus->drivers, chain) {
+		if (pos->get_preferred_mode)
+			mode = pos->get_preferred_mode(pos);
+	}
+
+	return mode;
+}
diff --git a/drivers/video/via/via_aux.h b/drivers/video/via/via_aux.h
new file mode 100644
index 0000000..a8de3f0
--- /dev/null
+++ b/drivers/video/via/via_aux.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * infrastructure for devices connected via I2C
+ */
+
+#ifndef __VIA_AUX_H__
+#define __VIA_AUX_H__
+
+
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+
+
+struct via_aux_bus {
+	struct i2c_adapter *adap;	/* the I2C device to access the bus */
+	struct list_head drivers;	/* drivers for devices on this bus */
+};
+
+struct via_aux_drv {
+	struct list_head chain;		/* chain to support multiple drivers */
+
+	struct via_aux_bus *bus;	/* the I2C bus used */
+	u8 addr;			/* the I2C slave address */
+
+	const char *name;	/* human readable name of the driver */
+	void *data;		/* private data of this driver */
+
+	void (*cleanup)(struct via_aux_drv *drv);
+	const struct fb_videomode* (*get_preferred_mode)
+		(struct via_aux_drv *drv);
+};
+
+
+struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap);
+void via_aux_free(struct via_aux_bus *bus);
+const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus);
+
+
+static inline bool via_aux_add(struct via_aux_drv *drv)
+{
+	struct via_aux_drv *data = kmalloc(sizeof(*data), GFP_KERNEL);
+
+	if (!data)
+		return false;
+
+	*data = *drv;
+	list_add_tail(&data->chain, &data->bus->drivers);
+	return true;
+}
+
+static inline bool via_aux_read(struct via_aux_drv *drv, u8 start, u8 *buf,
+	u8 len)
+{
+	struct i2c_msg msg[2] = {
+		{.addr = drv->addr, .flags = 0, .len = 1, .buf = &start},
+		{.addr = drv->addr, .flags = I2C_M_RD, .len = len, .buf = buf} };
+
+	return i2c_transfer(drv->bus->adap, msg, 2) == 2;
+}
+
+
+/* probe functions of existing drivers - should only be called in via_aux.c */
+void via_aux_ch7301_probe(struct via_aux_bus *bus);
+void via_aux_edid_probe(struct via_aux_bus *bus);
+void via_aux_sii164_probe(struct via_aux_bus *bus);
+void via_aux_vt1636_probe(struct via_aux_bus *bus);
+void via_aux_vt1632_probe(struct via_aux_bus *bus);
+void via_aux_vt1631_probe(struct via_aux_bus *bus);
+void via_aux_vt1625_probe(struct via_aux_bus *bus);
+void via_aux_vt1622_probe(struct via_aux_bus *bus);
+void via_aux_vt1621_probe(struct via_aux_bus *bus);
+
+
+#endif /* __VIA_AUX_H__ */
diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/via/via_aux_ch7301.c
new file mode 100644
index 0000000..1cbe503
--- /dev/null
+++ b/drivers/video/via/via_aux_ch7301.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for Chrontel CH7301 DVI Transmitter
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "CH7301 DVI Transmitter";
+
+
+static void probe(struct via_aux_bus *bus, u8 addr)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	addr,
+		.name	=	name};
+	u8 tmp;
+
+	if (!via_aux_read(&drv, 0x4B, &tmp, 1) || tmp != 0x17)
+		return;
+
+	printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
+	via_aux_add(&drv);
+}
+
+void via_aux_ch7301_probe(struct via_aux_bus *bus)
+{
+	probe(bus, 0x75);
+	probe(bus, 0x76);
+}
diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/via/via_aux_edid.c
new file mode 100644
index 0000000..754d450
--- /dev/null
+++ b/drivers/video/via/via_aux_edid.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * generic EDID driver
+ */
+
+#include <linux/slab.h>
+#include <linux/fb.h>
+#include "via_aux.h"
+#include "../edid.h"
+
+
+static const char *name = "EDID";
+
+
+static void query_edid(struct via_aux_drv *drv)
+{
+	struct fb_monspecs *spec = drv->data;
+	unsigned char edid[EDID_LENGTH];
+	bool valid = false;
+
+	if (spec) {
+		fb_destroy_modedb(spec->modedb);
+	} else {
+		spec = kmalloc(sizeof(*spec), GFP_KERNEL);
+		if (!spec)
+			return;
+	}
+
+	spec->version = spec->revision = 0;
+	if (via_aux_read(drv, 0x00, edid, EDID_LENGTH)) {
+		fb_edid_to_monspecs(edid, spec);
+		valid = spec->version || spec->revision;
+	}
+
+	if (!valid) {
+		kfree(spec);
+		spec = NULL;
+	} else
+		printk(KERN_DEBUG "EDID: %s %s\n", spec->manufacturer, spec->monitor);
+
+	drv->data = spec;
+}
+
+static const struct fb_videomode *get_preferred_mode(struct via_aux_drv *drv)
+{
+	struct fb_monspecs *spec = drv->data;
+	int i;
+
+	if (!spec || !spec->modedb || !(spec->misc & FB_MISC_1ST_DETAIL))
+		return NULL;
+
+	for (i = 0; i < spec->modedb_len; i++) {
+		if (spec->modedb[i].flag & FB_MODE_IS_FIRST &&
+			spec->modedb[i].flag & FB_MODE_IS_DETAILED)
+			return &spec->modedb[i];
+	}
+
+	return NULL;
+}
+
+static void cleanup(struct via_aux_drv *drv)
+{
+	struct fb_monspecs *spec = drv->data;
+
+	if (spec)
+		fb_destroy_modedb(spec->modedb);
+}
+
+void via_aux_edid_probe(struct via_aux_bus *bus)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	0x50,
+		.name	=	name,
+		.cleanup	=	cleanup,
+		.get_preferred_mode	=	get_preferred_mode};
+
+	query_edid(&drv);
+
+	/* as EDID devices can be connected/disconnected just add the driver */
+	via_aux_add(&drv);
+}
diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/via/via_aux_sii164.c
new file mode 100644
index 0000000..ca1b35f
--- /dev/null
+++ b/drivers/video/via/via_aux_sii164.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for Silicon Image SiI 164 PanelLink Transmitter
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "SiI 164 PanelLink Transmitter";
+
+
+static void probe(struct via_aux_bus *bus, u8 addr)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	addr,
+		.name	=	name};
+	/* check vendor id and device id */
+	const u8 id[] = {0x01, 0x00, 0x06, 0x00}, len = ARRAY_SIZE(id);
+	u8 tmp[len];
+
+	if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
+		return;
+
+	printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
+	via_aux_add(&drv);
+}
+
+void via_aux_sii164_probe(struct via_aux_bus *bus)
+{
+	u8 i;
+
+	for (i = 0x38; i <= 0x3F; i++)
+		probe(bus, i);
+}
diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/via/via_aux_vt1621.c
new file mode 100644
index 0000000..38eca84
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1621.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for VIA VT1621(M) TV Encoder
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "VT1621(M) TV Encoder";
+
+
+void via_aux_vt1621_probe(struct via_aux_bus *bus)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	0x20,
+		.name	=	name};
+	u8 tmp;
+
+	if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x02)
+		return;
+
+	printk(KERN_INFO "viafb: Found %s\n", name);
+	via_aux_add(&drv);
+}
diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/via/via_aux_vt1622.c
new file mode 100644
index 0000000..8c79c68
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1622.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for VIA VT1622(M) Digital TV Encoder
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "VT1622(M) Digital TV Encoder";
+
+
+static void probe(struct via_aux_bus *bus, u8 addr)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	addr,
+		.name	=	name};
+	u8 tmp;
+
+	if (!via_aux_read(&drv, 0x1B, &tmp, 1) ||  tmp != 0x03)
+		return;
+
+	printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
+	via_aux_add(&drv);
+}
+
+void via_aux_vt1622_probe(struct via_aux_bus *bus)
+{
+	probe(bus, 0x20);
+	probe(bus, 0x21);
+}
diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/via/via_aux_vt1625.c
new file mode 100644
index 0000000..03eb301
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1625.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for VIA VT1625(M) HDTV Encoder
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "VT1625(M) HDTV Encoder";
+
+
+static void probe(struct via_aux_bus *bus, u8 addr)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	addr,
+		.name	=	name};
+	u8 tmp;
+
+	if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x50)
+		return;
+
+	printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
+	via_aux_add(&drv);
+}
+
+void via_aux_vt1625_probe(struct via_aux_bus *bus)
+{
+	probe(bus, 0x20);
+	probe(bus, 0x21);
+}
diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/via/via_aux_vt1631.c
new file mode 100644
index 0000000..06e742f
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1631.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for VIA VT1631 LVDS Transmitter
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "VT1631 LVDS Transmitter";
+
+
+void via_aux_vt1631_probe(struct via_aux_bus *bus)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	0x38,
+		.name	=	name};
+	/* check vendor id and device id */
+	const u8 id[] = {0x06, 0x11, 0x91, 0x31}, len = ARRAY_SIZE(id);
+	u8 tmp[len];
+
+	if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
+		return;
+
+	printk(KERN_INFO "viafb: Found %s\n", name);
+	via_aux_add(&drv);
+}
diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/via/via_aux_vt1632.c
new file mode 100644
index 0000000..d24f4cd
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1632.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for VIA VT1632 DVI Transmitter
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "VT1632 DVI Transmitter";
+
+
+static void probe(struct via_aux_bus *bus, u8 addr)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	addr,
+		.name	=	name};
+	/* check vendor id and device id */
+	const u8 id[] = {0x06, 0x11, 0x92, 0x31}, len = ARRAY_SIZE(id);
+	u8 tmp[len];
+
+	if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
+		return;
+
+	printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
+	via_aux_add(&drv);
+}
+
+void via_aux_vt1632_probe(struct via_aux_bus *bus)
+{
+	u8 i;
+
+	for (i = 0x08; i <= 0x0F; i++)
+		probe(bus, i);
+}
diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/via/via_aux_vt1636.c
new file mode 100644
index 0000000..9e015c1
--- /dev/null
+++ b/drivers/video/via/via_aux_vt1636.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.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, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+/*
+ * driver for VIA VT1636 LVDS Transmitter
+ */
+
+#include <linux/slab.h>
+#include "via_aux.h"
+
+
+static const char *name = "VT1636 LVDS Transmitter";
+
+
+void via_aux_vt1636_probe(struct via_aux_bus *bus)
+{
+	struct via_aux_drv drv = {
+		.bus	=	bus,
+		.addr	=	0x40,
+		.name	=	name};
+	/* check vendor id and device id */
+	const u8 id[] = {0x06, 0x11, 0x45, 0x33}, len = ARRAY_SIZE(id);
+	u8 tmp[len];
+
+	if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
+		return;
+
+	printk(KERN_INFO "viafb: Found %s\n", name);
+	via_aux_add(&drv);
+}
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 78f1405..dd53058 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -51,7 +51,7 @@ static void via_i2c_setscl(void *data, int state)
 		val |= 0x01;
 		break;
 	case VIA_PORT_GPIO:
-		val |= 0x80;
+		val |= 0x82;
 		break;
 	default:
 		printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
@@ -67,6 +67,9 @@ static int via_i2c_getscl(void *data)
 	int ret = 0;
 
 	spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
+	if (adap_data->type == VIA_PORT_GPIO)
+		via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
+			0, 0x80);
 	if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
 		ret = 1;
 	spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
@@ -80,6 +83,9 @@ static int via_i2c_getsda(void *data)
 	int ret = 0;
 
 	spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
+	if (adap_data->type == VIA_PORT_GPIO)
+		via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
+			0, 0x40);
 	if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
 		ret = 1;
 	spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
@@ -103,7 +109,7 @@ static void via_i2c_setsda(void *data, int state)
 		val |= 0x01;
 		break;
 	case VIA_PORT_GPIO:
-		val |= 0x40;
+		val |= 0x42;
 		break;
 	default:
 		printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index a13c258..4791165 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/via-core.h>
+#include <linux/via_i2c.h>
 #include <asm/olpc.h>
 
 #define _MASTER_FILE
@@ -1670,12 +1671,23 @@ static void viafb_remove_proc(struct viafb_shared *shared)
 }
 #undef IS_VT1636
 
-static int parse_mode(const char *str, u32 *xres, u32 *yres)
+static int parse_mode(const char *str, u32 devices, u32 *xres, u32 *yres)
 {
+	const struct fb_videomode *mode = NULL;
 	char *ptr;
 
 	if (!str) {
-		if (machine_is_olpc()) {
+		if (devices == VIA_CRT)
+			mode = via_aux_get_preferred_mode(
+				viaparinfo->shared->i2c_26);
+		else if (devices == VIA_DVP1)
+			mode = via_aux_get_preferred_mode(
+				viaparinfo->shared->i2c_31);
+
+		if (mode) {
+			*xres = mode->xres;
+			*yres = mode->yres;
+		} else if (machine_is_olpc()) {
 			*xres = 1200;
 			*yres = 900;
 		} else {
@@ -1729,6 +1741,29 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
 
 #endif
 
+static void __devinit i2c_bus_probe(struct viafb_shared *shared)
+{
+	/* should be always CRT */
+	printk(KERN_INFO "viafb: Probing I2C bus 0x26\n");
+	shared->i2c_26 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26));
+
+	/* seems to be usually DVP1 */
+	printk(KERN_INFO "viafb: Probing I2C bus 0x31\n");
+	shared->i2c_31 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31));
+
+	/* FIXME: what is this? */
+	printk(KERN_INFO "viafb: Probing I2C bus 0x2C\n");
+	shared->i2c_2C = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C));
+
+	printk(KERN_INFO "viafb: Finished I2C bus probing");
+}
+
+static void i2c_bus_free(struct viafb_shared *shared)
+{
+	via_aux_free(shared->i2c_26);
+	via_aux_free(shared->i2c_31);
+	via_aux_free(shared->i2c_2C);
+}
 
 int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
 {
@@ -1762,6 +1797,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
 		&viaparinfo->shared->lvds_setting_info2;
 	viaparinfo->chip_info = &viaparinfo->shared->chip_info;
 
+	i2c_bus_probe(viaparinfo->shared);
 	if (viafb_dual_fb)
 		viafb_SAMM_ON = 1;
 	parse_lcd_port();
@@ -1804,10 +1840,11 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
 			viafb_second_size * 1024 * 1024;
 	}
 
-	parse_mode(viafb_mode, &default_xres, &default_yres);
+	parse_mode(viafb_mode, viaparinfo->shared->iga1_devices,
+		&default_xres, &default_yres);
 	if (viafb_SAMM_ON == 1)
-		parse_mode(viafb_mode1, &viafb_second_xres,
-			&viafb_second_yres);
+		parse_mode(viafb_mode1, viaparinfo->shared->iga2_devices,
+			&viafb_second_xres, &viafb_second_yres);
 
 	default_var.xres = default_xres;
 	default_var.yres = default_yres;
@@ -1915,6 +1952,7 @@ out_fb1_release:
 	if (viafbinfo1)
 		framebuffer_release(viafbinfo1);
 out_fb_release:
+	i2c_bus_free(viaparinfo->shared);
 	framebuffer_release(viafbinfo);
 	return rc;
 }
@@ -1927,6 +1965,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
 	if (viafb_dual_fb)
 		unregister_framebuffer(viafbinfo1);
 	viafb_remove_proc(viaparinfo->shared);
+	i2c_bus_free(viaparinfo->shared);
 	framebuffer_release(viafbinfo);
 	if (viafb_dual_fb)
 		framebuffer_release(viafbinfo1);
@@ -2033,9 +2072,9 @@ int __init viafb_init(void)
 	if (r < 0)
 		return r;
 #endif
-	if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
+	if (parse_mode(viafb_mode, 0, &dummy_x, &dummy_y)
 		|| !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
-		|| parse_mode(viafb_mode1, &dummy_x, &dummy_y)
+		|| parse_mode(viafb_mode1, 0, &dummy_x, &dummy_y)
 		|| !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
 		|| viafb_bpp < 0 || viafb_bpp > 32
 		|| viafb_bpp1 < 0 || viafb_bpp1 > 32
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index d944063..f6b2ddf 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -26,6 +26,7 @@
 #include <linux/fb.h>
 #include <linux/spinlock.h>
 
+#include "via_aux.h"
 #include "ioctl.h"
 #include "share.h"
 #include "chip.h"
@@ -48,6 +49,11 @@ struct viafb_shared {
 	struct proc_dir_entry *iga2_proc_entry;
 	struct viafb_dev *vdev;			/* Global dev info */
 
+	/* I2C busses that may have auxiliary devices */
+	struct via_aux_bus *i2c_26;
+	struct via_aux_bus *i2c_31;
+	struct via_aux_bus *i2c_2C;
+
 	/* All the information will be needed to set engine */
 	struct tmds_setting_information tmds_setting_info;
 	struct lvds_setting_information lvds_setting_info;
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index fcbe742..df600d1 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -13,12 +13,11 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/w1-gpio.h>
+#include <linux/gpio.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
 
-#include <asm/gpio.h>
-
 static void w1_gpio_write_bit_dir(void *data, u8 bit)
 {
 	struct w1_gpio_platform_data *pdata = data;
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c
index 8f4c91f..8f10fd2 100644
--- a/drivers/w1/slaves/w1_bq27000.c
+++ b/drivers/w1/slaves/w1_bq27000.c
@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/power/bq27x00_battery.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
@@ -39,10 +40,10 @@ void w1_bq27000_write(struct device *dev, u8 buf, u8 reg)
 }
 EXPORT_SYMBOL(w1_bq27000_write);
 
-int w1_bq27000_read(struct device *dev, u8 reg)
+static int w1_bq27000_read(struct device *dev, unsigned int reg)
 {
 	u8 val;
-	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+	struct w1_slave *sl = container_of(dev->parent, struct w1_slave, dev);
 
 	if (!dev)
 		return 0;
@@ -52,19 +53,25 @@ int w1_bq27000_read(struct device *dev, u8 reg)
 
 	return val;
 }
-EXPORT_SYMBOL(w1_bq27000_read);
+
+static struct bq27000_platform_data bq27000_battery_info = {
+	.read   = w1_bq27000_read,
+	.name   = "bq27000-battery",
+};
 
 static int w1_bq27000_add_slave(struct w1_slave *sl)
 {
 	int ret;
-	int id = 1;
 	struct platform_device *pdev;
 
-	pdev = platform_device_alloc("bq27000-battery", id);
+	pdev = platform_device_alloc("bq27000-battery", -1);
 	if (!pdev) {
 		ret = -ENOMEM;
 		return ret;
 	}
+	ret = platform_device_add_data(pdev,
+				       &bq27000_battery_info,
+				       sizeof(bq27000_battery_info));
 	pdev->dev.parent = &sl->dev;
 
 	ret = platform_device_add(pdev);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 877b107..df9e8f0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1098,7 +1098,7 @@ config BOOKE_WDT_DEFAULT_TIMEOUT
 	  For Freescale Book-E processors, this is a number between 0 and 63.
 	  For other Book-E processors, this is a number between 0 and 3.
 
-	  The value can be overidden by the wdt_period command-line parameter.
+	  The value can be overridden by the wdt_period command-line parameter.
 
 # PPC64 Architecture
 
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 8464ea1..3c166d3 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -231,7 +231,7 @@ static int __devinit cru_detect(unsigned long map_entry,
 
 	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
 
-	set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE));
+	set_memory_x((unsigned long)bios32_map, 2);
 	asminline_call(&cmn_regs, bios32_entrypoint);
 
 	if (cmn_regs.u1.ral != 0) {
@@ -250,7 +250,8 @@ static int __devinit cru_detect(unsigned long map_entry,
 			cru_rom_addr =
 				ioremap(cru_physical_address, cru_length);
 			if (cru_rom_addr) {
-				set_memory_x((unsigned long)cru_rom_addr, cru_length);
+				set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
+					(cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT);
 				retval = 0;
 			}
 		}
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 8e210aa..dfae030 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -264,7 +264,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
 	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (wdt_mem == NULL) {
 		printk(KERN_INFO MODULE_NAME
-			"failed to get memory region resouce\n");
+			"failed to get memory region resource\n");
 		return -ENOENT;
 	}
 
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 4bc3744..404172f 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -312,18 +312,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 	dev = &pdev->dev;
 	wdt_dev = &pdev->dev;
 
-	/* get the memory region for the watchdog timer */
-
 	wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (wdt_mem == NULL) {
 		dev_err(dev, "no memory resource specified\n");
 		return -ENOENT;
 	}
 
+	wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (wdt_irq == NULL) {
+		dev_err(dev, "no irq resource specified\n");
+		ret = -ENOENT;
+		goto err;
+	}
+
+	/* get the memory region for the watchdog timer */
+
 	size = resource_size(wdt_mem);
 	if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
 		dev_err(dev, "failed to get memory region\n");
-		return -EBUSY;
+		ret = -EBUSY;
+		goto err;
 	}
 
 	wdt_base = ioremap(wdt_mem->start, size);
@@ -335,29 +343,17 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 
 	DBG("probe: mapped wdt_base=%p\n", wdt_base);
 
-	wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (wdt_irq == NULL) {
-		dev_err(dev, "no irq resource specified\n");
-		ret = -ENOENT;
-		goto err_map;
-	}
-
-	ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
-	if (ret != 0) {
-		dev_err(dev, "failed to install irq (%d)\n", ret);
-		goto err_map;
-	}
-
 	wdt_clock = clk_get(&pdev->dev, "watchdog");
 	if (IS_ERR(wdt_clock)) {
 		dev_err(dev, "failed to find watchdog clock source\n");
 		ret = PTR_ERR(wdt_clock);
-		goto err_irq;
+		goto err_map;
 	}
 
 	clk_enable(wdt_clock);
 
-	if (s3c2410wdt_cpufreq_register() < 0) {
+	ret = s3c2410wdt_cpufreq_register();
+	if (ret < 0) {
 		printk(KERN_ERR PFX "failed to register cpufreq\n");
 		goto err_clk;
 	}
@@ -378,12 +374,18 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 							"cannot start\n");
 	}
 
+	ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
+	if (ret != 0) {
+		dev_err(dev, "failed to install irq (%d)\n", ret);
+		goto err_cpufreq;
+	}
+
 	watchdog_set_nowayout(&s3c2410_wdd, nowayout);
 
 	ret = watchdog_register_device(&s3c2410_wdd);
 	if (ret) {
 		dev_err(dev, "cannot register watchdog (%d)\n", ret);
-		goto err_cpufreq;
+		goto err_irq;
 	}
 
 	if (tmr_atboot && started == 0) {
@@ -408,23 +410,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
 
 	return 0;
 
+ err_irq:
+	free_irq(wdt_irq->start, pdev);
+
  err_cpufreq:
 	s3c2410wdt_cpufreq_deregister();
 
  err_clk:
 	clk_disable(wdt_clock);
 	clk_put(wdt_clock);
-
- err_irq:
-	free_irq(wdt_irq->start, pdev);
+	wdt_clock = NULL;
 
  err_map:
 	iounmap(wdt_base);
 
  err_req:
 	release_mem_region(wdt_mem->start, size);
-	wdt_mem = NULL;
 
+ err:
+	wdt_irq = NULL;
+	wdt_mem = NULL;
 	return ret;
 }
 
@@ -432,18 +437,18 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
 {
 	watchdog_unregister_device(&s3c2410_wdd);
 
+	free_irq(wdt_irq->start, dev);
+
 	s3c2410wdt_cpufreq_deregister();
 
 	clk_disable(wdt_clock);
 	clk_put(wdt_clock);
 	wdt_clock = NULL;
 
-	free_irq(wdt_irq->start, dev);
-	wdt_irq = NULL;
-
 	iounmap(wdt_base);
 
 	release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+	wdt_irq = NULL;
 	wdt_mem = NULL;
 	return 0;
 }
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 4dcfced..df80af8 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -8,18 +8,20 @@
 
 static void enable_hotplug_cpu(int cpu)
 {
-	if (!cpu_present(cpu))
+	if (!cpu_present(cpu)) {
 		arch_register_cpu(cpu);
-
-	set_cpu_present(cpu, true);
+		set_cpu_present(cpu, true);
+		(void)cpu_up(cpu);
+	}
 }
 
 static void disable_hotplug_cpu(int cpu)
 {
-	if (cpu_present(cpu))
+	if (cpu_present(cpu)) {
+		(void)cpu_down(cpu);
+		set_cpu_present(cpu, false);
 		arch_unregister_cpu(cpu);
-
-	set_cpu_present(cpu, false);
+	}
 }
 
 static int vcpu_online(unsigned int cpu)
@@ -53,7 +55,6 @@ static void vcpu_hotplug(unsigned int cpu)
 		enable_hotplug_cpu(cpu);
 		break;
 	case 0:
-		(void)cpu_down(cpu);
 		disable_hotplug_cpu(cpu);
 		break;
 	default:
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index ce4fa08..9e14ae6 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -129,9 +129,9 @@ static void do_suspend(void)
 	printk(KERN_DEBUG "suspending xenstore...\n");
 	xs_suspend();
 
-	err = dpm_suspend_noirq(PMSG_FREEZE);
+	err = dpm_suspend_end(PMSG_FREEZE);
 	if (err) {
-		printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err);
+		printk(KERN_ERR "dpm_suspend_end failed: %d\n", err);
 		goto out_resume;
 	}
 
@@ -149,7 +149,7 @@ static void do_suspend(void)
 
 	err = stop_machine(xen_suspend, &si, cpumask_of(0));
 
-	dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
+	dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE);
 
 	if (err) {
 		printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 19e6a20..1afb4fb 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -204,7 +204,8 @@ error:
 
 void *
 xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t flags)
+			   dma_addr_t *dma_handle, gfp_t flags,
+			   struct dma_attrs *attrs)
 {
 	void *ret;
 	int order = get_order(size);
@@ -253,7 +254,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
 
 void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-			  dma_addr_t dev_addr)
+			  dma_addr_t dev_addr, struct dma_attrs *attrs)
 {
 	int order = get_order(size);
 	phys_addr_t phys;
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index d369965..17d9e37 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -242,9 +242,9 @@ __setup("nocleancache", no_cleancache);
 static struct cleancache_ops tmem_cleancache_ops = {
 	.put_page = tmem_cleancache_put_page,
 	.get_page = tmem_cleancache_get_page,
-	.flush_page = tmem_cleancache_flush_page,
-	.flush_inode = tmem_cleancache_flush_inode,
-	.flush_fs = tmem_cleancache_flush_fs,
+	.invalidate_page = tmem_cleancache_flush_page,
+	.invalidate_inode = tmem_cleancache_flush_inode,
+	.invalidate_fs = tmem_cleancache_flush_fs,
 	.init_shared_fs = tmem_cleancache_init_shared_fs,
 	.init_fs = tmem_cleancache_init_fs
 };
@@ -369,8 +369,8 @@ __setup("nofrontswap", no_frontswap);
 static struct frontswap_ops tmem_frontswap_ops = {
 	.put_page = tmem_frontswap_put_page,
 	.get_page = tmem_frontswap_get_page,
-	.flush_page = tmem_frontswap_flush_page,
-	.flush_area = tmem_frontswap_flush_area,
+	.invalidate_page = tmem_frontswap_flush_page,
+	.invalidate_area = tmem_frontswap_flush_area,
 	.init = tmem_frontswap_init
 };
 #endif
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 19834d1..097e536 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -85,19 +85,34 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
 static void pcistub_device_release(struct kref *kref)
 {
 	struct pcistub_device *psdev;
+	struct xen_pcibk_dev_data *dev_data;
 
 	psdev = container_of(kref, struct pcistub_device, kref);
+	dev_data = pci_get_drvdata(psdev->dev);
 
 	dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
 
 	xen_unregister_device_domain_owner(psdev->dev);
 
-	/* Clean-up the device */
+	/* Call the reset function which does not take lock as this
+	 * is called from "unbind" which takes a device_lock mutex.
+	 */
+	__pci_reset_function_locked(psdev->dev);
+	if (pci_load_and_free_saved_state(psdev->dev,
+					  &dev_data->pci_saved_state)) {
+		dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n");
+	} else
+		pci_restore_state(psdev->dev);
+
+	/* Disable the device */
 	xen_pcibk_reset_device(psdev->dev);
+
+	kfree(dev_data);
+	pci_set_drvdata(psdev->dev, NULL);
+
+	/* Clean-up the device */
 	xen_pcibk_config_free_dyn_fields(psdev->dev);
 	xen_pcibk_config_free_dev(psdev->dev);
-	kfree(pci_get_drvdata(psdev->dev));
-	pci_set_drvdata(psdev->dev, NULL);
 
 	psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
 	pci_dev_put(psdev->dev);
@@ -231,7 +246,17 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
 	/* Cleanup our device
 	 * (so it's ready for the next domain)
 	 */
+
+	/* This is OK - we are running from workqueue context
+	 * and want to inhibit the user from fiddling with 'reset'
+	 */
+	pci_reset_function(dev);
+	pci_restore_state(psdev->dev);
+
+	/* This disables the device. */
 	xen_pcibk_reset_device(found_psdev->dev);
+
+	/* And cleanup up our emulated fields. */
 	xen_pcibk_config_free_dyn_fields(found_psdev->dev);
 	xen_pcibk_config_reset_dev(found_psdev->dev);
 
@@ -328,6 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)
 	if (err)
 		goto config_release;
 
+	dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n");
+	__pci_reset_function_locked(dev);
+
+	/* We need the device active to save the state. */
+	dev_dbg(&dev->dev, "save state of device\n");
+	pci_save_state(dev);
+	dev_data->pci_saved_state = pci_store_saved_state(dev);
+	if (!dev_data->pci_saved_state)
+		dev_err(&dev->dev, "Could not store PCI conf saved state!\n");
+
 	/* Now disable the device (this also ensures some private device
 	 * data is setup before we export)
 	 */
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index e9b4011..a7def01 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -41,6 +41,7 @@ struct xen_pcibk_device {
 
 struct xen_pcibk_dev_data {
 	struct list_head config_fields;
+	struct pci_saved_state *pci_saved_state;
 	unsigned int permissive:1;
 	unsigned int warned_on_write:1;
 	unsigned int enable_intx:1;
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 7b0cd87..10b7d3c 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -155,9 +155,8 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
 		goto release_sb;
 	}
 
-	root = d_alloc_root(inode);
+	root = d_make_root(inode);
 	if (!root) {
-		iput(inode);
 		retval = -ENOMEM;
 		goto release_sb;
 	}
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 8e3b36a..06fdcc9 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -483,10 +483,9 @@ static int adfs_fill_super(struct super_block *sb, void *data, int silent)
 
 	sb->s_d_op = &adfs_dentry_operations;
 	root = adfs_iget(sb, &root_obj);
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
 		int i;
-		iput(root);
 		for (i = 0; i < asb->s_map_size; i++)
 			brelse(asb->s_map[i].dm_bh);
 		kfree(asb->s_map);
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 8ba73fe..0782653 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -473,7 +473,7 @@ got_root:
 	root_inode = affs_iget(sb, root_block);
 	if (IS_ERR(root_inode)) {
 		ret = PTR_ERR(root_inode);
-		goto out_error_noinode;
+		goto out_error;
 	}
 
 	if (AFFS_SB(sb)->s_flags & SF_INTL)
@@ -481,7 +481,7 @@ got_root:
 	else
 		sb->s_d_op = &affs_dentry_operations;
 
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
 	if (!sb->s_root) {
 		printk(KERN_ERR "AFFS: Get root inode failed\n");
 		goto out_error;
@@ -494,9 +494,6 @@ got_root:
 	 * Begin the cascaded cleanup ...
 	 */
 out_error:
-	if (root_inode)
-		iput(root_inode);
-out_error_noinode:
 	kfree(sbi->s_bitmap);
 	affs_brelse(root_bh);
 	kfree(sbi->s_prefix);
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 2f213d1..b960ff0 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -365,10 +365,10 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
 		_debug("extract data");
 		if (call->count > 0) {
 			page = call->reply3;
-			buffer = kmap_atomic(page, KM_USER0);
+			buffer = kmap_atomic(page);
 			ret = afs_extract_data(call, skb, last, buffer,
 					       call->count);
-			kunmap_atomic(buffer, KM_USER0);
+			kunmap_atomic(buffer);
 			switch (ret) {
 			case 0:		break;
 			case -EAGAIN:	return 0;
@@ -411,9 +411,9 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call,
 	if (call->count < PAGE_SIZE) {
 		_debug("clear");
 		page = call->reply3;
-		buffer = kmap_atomic(page, KM_USER0);
+		buffer = kmap_atomic(page);
 		memset(buffer + call->count, 0, PAGE_SIZE - call->count);
-		kunmap_atomic(buffer, KM_USER0);
+		kunmap_atomic(buffer);
 	}
 
 	_leave(" = 0 [done]");
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 8f4ce26..298cf89 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -200,9 +200,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
 		if (PageError(page))
 			goto error;
 
-		buf = kmap_atomic(page, KM_USER0);
+		buf = kmap_atomic(page);
 		memcpy(devname, buf, size);
-		kunmap_atomic(buf, KM_USER0);
+		kunmap_atomic(buf);
 		page_cache_release(page);
 		page = NULL;
 	}
diff --git a/fs/afs/super.c b/fs/afs/super.c
index 983ec59..f02b31e 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -301,7 +301,6 @@ static int afs_fill_super(struct super_block *sb,
 {
 	struct afs_super_info *as = sb->s_fs_info;
 	struct afs_fid fid;
-	struct dentry *root = NULL;
 	struct inode *inode = NULL;
 	int ret;
 
@@ -327,18 +326,16 @@ static int afs_fill_super(struct super_block *sb,
 		set_bit(AFS_VNODE_AUTOCELL, &AFS_FS_I(inode)->flags);
 
 	ret = -ENOMEM;
-	root = d_alloc_root(inode);
-	if (!root)
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root)
 		goto error;
 
 	sb->s_d_op = &afs_fs_dentry_operations;
-	sb->s_root = root;
 
 	_leave(" = 0");
 	return 0;
 
 error:
-	iput(inode);
 	_leave(" = %d", ret);
 	return ret;
 }
diff --git a/fs/aio.c b/fs/aio.c
index 969beb0..85798a6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -160,7 +160,7 @@ static int aio_setup_ring(struct kioctx *ctx)
 
 	info->nr = nr_events;		/* trusted copy */
 
-	ring = kmap_atomic(info->ring_pages[0], KM_USER0);
+	ring = kmap_atomic(info->ring_pages[0]);
 	ring->nr = nr_events;	/* user copy */
 	ring->id = ctx->user_id;
 	ring->head = ring->tail = 0;
@@ -168,32 +168,32 @@ static int aio_setup_ring(struct kioctx *ctx)
 	ring->compat_features = AIO_RING_COMPAT_FEATURES;
 	ring->incompat_features = AIO_RING_INCOMPAT_FEATURES;
 	ring->header_length = sizeof(struct aio_ring);
-	kunmap_atomic(ring, KM_USER0);
+	kunmap_atomic(ring);
 
 	return 0;
 }
 
 
 /* aio_ring_event: returns a pointer to the event at the given index from
- * kmap_atomic(, km).  Release the pointer with put_aio_ring_event();
+ * kmap_atomic().  Release the pointer with put_aio_ring_event();
  */
 #define AIO_EVENTS_PER_PAGE	(PAGE_SIZE / sizeof(struct io_event))
 #define AIO_EVENTS_FIRST_PAGE	((PAGE_SIZE - sizeof(struct aio_ring)) / sizeof(struct io_event))
 #define AIO_EVENTS_OFFSET	(AIO_EVENTS_PER_PAGE - AIO_EVENTS_FIRST_PAGE)
 
-#define aio_ring_event(info, nr, km) ({					\
+#define aio_ring_event(info, nr) ({					\
 	unsigned pos = (nr) + AIO_EVENTS_OFFSET;			\
 	struct io_event *__event;					\
 	__event = kmap_atomic(						\
-			(info)->ring_pages[pos / AIO_EVENTS_PER_PAGE], km); \
+			(info)->ring_pages[pos / AIO_EVENTS_PER_PAGE]); \
 	__event += pos % AIO_EVENTS_PER_PAGE;				\
 	__event;							\
 })
 
-#define put_aio_ring_event(event, km) do {	\
+#define put_aio_ring_event(event) do {		\
 	struct io_event *__event = (event);	\
 	(void)__event;				\
-	kunmap_atomic((void *)((unsigned long)__event & PAGE_MASK), km); \
+	kunmap_atomic((void *)((unsigned long)__event & PAGE_MASK)); \
 } while(0)
 
 static void ctx_rcu_free(struct rcu_head *head)
@@ -490,6 +490,8 @@ static void kiocb_batch_free(struct kioctx *ctx, struct kiocb_batch *batch)
 		kmem_cache_free(kiocb_cachep, req);
 		ctx->reqs_active--;
 	}
+	if (unlikely(!ctx->reqs_active && ctx->dead))
+		wake_up_all(&ctx->wait);
 	spin_unlock_irq(&ctx->ctx_lock);
 }
 
@@ -1019,10 +1021,10 @@ int aio_complete(struct kiocb *iocb, long res, long res2)
 	if (kiocbIsCancelled(iocb))
 		goto put_rq;
 
-	ring = kmap_atomic(info->ring_pages[0], KM_IRQ1);
+	ring = kmap_atomic(info->ring_pages[0]);
 
 	tail = info->tail;
-	event = aio_ring_event(info, tail, KM_IRQ0);
+	event = aio_ring_event(info, tail);
 	if (++tail >= info->nr)
 		tail = 0;
 
@@ -1043,8 +1045,8 @@ int aio_complete(struct kiocb *iocb, long res, long res2)
 	info->tail = tail;
 	ring->tail = tail;
 
-	put_aio_ring_event(event, KM_IRQ0);
-	kunmap_atomic(ring, KM_IRQ1);
+	put_aio_ring_event(event);
+	kunmap_atomic(ring);
 
 	pr_debug("added to ring %p at [%lu]\n", iocb, tail);
 
@@ -1089,7 +1091,7 @@ static int aio_read_evt(struct kioctx *ioctx, struct io_event *ent)
 	unsigned long head;
 	int ret = 0;
 
-	ring = kmap_atomic(info->ring_pages[0], KM_USER0);
+	ring = kmap_atomic(info->ring_pages[0]);
 	dprintk("in aio_read_evt h%lu t%lu m%lu\n",
 		 (unsigned long)ring->head, (unsigned long)ring->tail,
 		 (unsigned long)ring->nr);
@@ -1101,18 +1103,18 @@ static int aio_read_evt(struct kioctx *ioctx, struct io_event *ent)
 
 	head = ring->head % info->nr;
 	if (head != ring->tail) {
-		struct io_event *evp = aio_ring_event(info, head, KM_USER1);
+		struct io_event *evp = aio_ring_event(info, head);
 		*ent = *evp;
 		head = (head + 1) % info->nr;
 		smp_mb(); /* finish reading the event before updatng the head */
 		ring->head = head;
 		ret = 1;
-		put_aio_ring_event(evp, KM_USER1);
+		put_aio_ring_event(evp);
 	}
 	spin_unlock(&info->ring_lock);
 
 out:
-	kunmap_atomic(ring, KM_USER0);
+	kunmap_atomic(ring);
 	dprintk("leaving aio_read_evt: %d  h%lu t%lu\n", ret,
 		 (unsigned long)ring->head, (unsigned long)ring->tail);
 	return ret;
diff --git a/fs/attr.c b/fs/attr.c
index 95053ad..ff3746f 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -171,11 +171,18 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
 	struct timespec now;
 	unsigned int ia_valid = attr->ia_valid;
 
+	WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
+
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
 		if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 			return -EPERM;
 	}
 
+	if ((ia_valid & ATTR_SIZE) && IS_I_VERSION(inode)) {
+		if (attr->ia_size != inode->i_size)
+			inode_inc_iversion(inode);
+	}
+
 	if ((ia_valid & ATTR_MODE)) {
 		umode_t amode = attr->ia_mode;
 		/* Flag setting protected by i_mutex */
@@ -245,5 +252,4 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
 
 	return error;
 }
-
 EXPORT_SYMBOL(notify_change);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 450f529..1feb68e 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -124,6 +124,7 @@ start:
 	/* Negative dentry - try next */
 	if (!simple_positive(q)) {
 		spin_unlock(&p->d_lock);
+		lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_);
 		p = q;
 		goto again;
 	}
@@ -186,6 +187,7 @@ again:
 	/* Negative dentry - try next */
 	if (!simple_positive(ret)) {
 		spin_unlock(&p->d_lock);
+		lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_);
 		p = ret;
 		goto again;
 	}
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index e16980b..14c7bc0 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -245,12 +245,9 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
 	if (!ino)
 		goto fail_free;
 	root_inode = autofs4_get_inode(s, S_IFDIR | 0755);
-	if (!root_inode)
-		goto fail_ino;
-
-	root = d_alloc_root(root_inode);
+	root = d_make_root(root_inode);
 	if (!root)
-		goto fail_iput;
+		goto fail_ino;
 	pipe = NULL;
 
 	root->d_fsdata = ino;
@@ -315,9 +312,6 @@ fail_fput:
 fail_dput:
 	dput(root);
 	goto fail_free;
-fail_iput:
-	printk("autofs: get root dentry failed\n");
-	iput(root_inode);
 fail_ino:
 	kfree(ino);
 fail_free:
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 6e6d536..e18da23 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -852,9 +852,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
 		ret = PTR_ERR(root);
 		goto unacquire_priv_sbp;
 	}
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
-		iput(root);
 		befs_error(sb, "get root inode failed");
 		goto unacquire_priv_sbp;
 	}
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index b0391bc..e23dc7c 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -367,9 +367,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
 		ret = PTR_ERR(inode);
 		goto out2;
 	}
-	s->s_root = d_alloc_root(inode);
+	s->s_root = d_make_root(inode);
 	if (!s->s_root) {
-		iput(inode);
 		ret = -ENOMEM;
 		goto out2;
 	}
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index a9198df..88eb813 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/magic.h>
 #include <linux/binfmts.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
@@ -699,7 +700,7 @@ static int bm_fill_super(struct super_block * sb, void * data, int silent)
 		[3] = {"register", &bm_register_operations, S_IWUSR},
 		/* last one */ {""}
 	};
-	int err = simple_fill_super(sb, 0x42494e4d, bm_files);
+	int err = simple_fill_super(sb, BINFMTFS_MAGIC, bm_files);
 	if (!err)
 		sb->s_op = &s_ops;
 	return err;
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index c2183f3..e85c04b 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -357,7 +357,7 @@ static void bio_integrity_generate(struct bio *bio)
 	bix.sector_size = bi->sector_size;
 
 	bio_for_each_segment(bv, bio, i) {
-		void *kaddr = kmap_atomic(bv->bv_page, KM_USER0);
+		void *kaddr = kmap_atomic(bv->bv_page);
 		bix.data_buf = kaddr + bv->bv_offset;
 		bix.data_size = bv->bv_len;
 		bix.prot_buf = prot_buf;
@@ -371,7 +371,7 @@ static void bio_integrity_generate(struct bio *bio)
 		total += sectors * bi->tuple_size;
 		BUG_ON(total > bio->bi_integrity->bip_size);
 
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 }
 
@@ -498,7 +498,7 @@ static int bio_integrity_verify(struct bio *bio)
 	bix.sector_size = bi->sector_size;
 
 	bio_for_each_segment(bv, bio, i) {
-		void *kaddr = kmap_atomic(bv->bv_page, KM_USER0);
+		void *kaddr = kmap_atomic(bv->bv_page);
 		bix.data_buf = kaddr + bv->bv_offset;
 		bix.data_size = bv->bv_len;
 		bix.prot_buf = prot_buf;
@@ -507,7 +507,7 @@ static int bio_integrity_verify(struct bio *bio)
 		ret = bi->verify_fn(&bix);
 
 		if (ret) {
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			return ret;
 		}
 
@@ -517,7 +517,7 @@ static int bio_integrity_verify(struct bio *bio)
 		total += sectors * bi->tuple_size;
 		BUG_ON(total > bio->bi_integrity->bip_size);
 
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 
 	return ret;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 0e575d1..93392fa 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -16,6 +16,7 @@
 #include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/blkpg.h>
+#include <linux/magic.h>
 #include <linux/buffer_head.h>
 #include <linux/swap.h>
 #include <linux/pagevec.h>
@@ -109,7 +110,7 @@ void invalidate_bdev(struct block_device *bdev)
 	/* 99% of the time, we don't need to flush the cleancache on the bdev.
 	 * But, for the strange corners, lets be cautious
 	 */
-	cleancache_flush_inode(mapping);
+	cleancache_invalidate_inode(mapping);
 }
 EXPORT_SYMBOL(invalidate_bdev);
 
@@ -506,7 +507,7 @@ static const struct super_operations bdev_sops = {
 static struct dentry *bd_mount(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
-	return mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, 0x62646576);
+	return mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC);
 }
 
 static struct file_system_type bd_type = {
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index b669a7d..064b29b 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -89,7 +89,6 @@
 #include "disk-io.h"
 #include "transaction.h"
 #include "extent_io.h"
-#include "disk-io.h"
 #include "volumes.h"
 #include "print-tree.h"
 #include "locking.h"
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 14f1c5a..93f4af1 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -120,10 +120,10 @@ static int check_compressed_csum(struct inode *inode,
 		page = cb->compressed_pages[i];
 		csum = ~(u32)0;
 
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		csum = btrfs_csum_data(root, kaddr, csum, PAGE_CACHE_SIZE);
 		btrfs_csum_final(csum, (char *)&csum);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 
 		if (csum != *cb_sum) {
 			printk(KERN_INFO "btrfs csum failed ino %llu "
@@ -521,10 +521,10 @@ static noinline int add_ra_bio_pages(struct inode *inode,
 			if (zero_offset) {
 				int zeros;
 				zeros = PAGE_CACHE_SIZE - zero_offset;
-				userpage = kmap_atomic(page, KM_USER0);
+				userpage = kmap_atomic(page);
 				memset(userpage + zero_offset, 0, zeros);
 				flush_dcache_page(page);
-				kunmap_atomic(userpage, KM_USER0);
+				kunmap_atomic(userpage);
 			}
 		}
 
@@ -991,9 +991,9 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
 		bytes = min(PAGE_CACHE_SIZE - *pg_offset,
 			    PAGE_CACHE_SIZE - buf_offset);
 		bytes = min(bytes, working_bytes);
-		kaddr = kmap_atomic(page_out, KM_USER0);
+		kaddr = kmap_atomic(page_out);
 		memcpy(kaddr + *pg_offset, buf + buf_offset, bytes);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		flush_dcache_page(page_out);
 
 		*pg_offset += bytes;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index fcf77e1..8a57b0d 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2535,10 +2535,10 @@ static int __extent_read_full_page(struct extent_io_tree *tree,
 
 		if (zero_offset) {
 			iosize = PAGE_CACHE_SIZE - zero_offset;
-			userpage = kmap_atomic(page, KM_USER0);
+			userpage = kmap_atomic(page);
 			memset(userpage + zero_offset, 0, iosize);
 			flush_dcache_page(page);
-			kunmap_atomic(userpage, KM_USER0);
+			kunmap_atomic(userpage);
 		}
 	}
 	while (cur <= end) {
@@ -2547,10 +2547,10 @@ static int __extent_read_full_page(struct extent_io_tree *tree,
 			struct extent_state *cached = NULL;
 
 			iosize = PAGE_CACHE_SIZE - pg_offset;
-			userpage = kmap_atomic(page, KM_USER0);
+			userpage = kmap_atomic(page);
 			memset(userpage + pg_offset, 0, iosize);
 			flush_dcache_page(page);
-			kunmap_atomic(userpage, KM_USER0);
+			kunmap_atomic(userpage);
 			set_extent_uptodate(tree, cur, cur + iosize - 1,
 					    &cached, GFP_NOFS);
 			unlock_extent_cached(tree, cur, cur + iosize - 1,
@@ -2596,10 +2596,10 @@ static int __extent_read_full_page(struct extent_io_tree *tree,
 			char *userpage;
 			struct extent_state *cached = NULL;
 
-			userpage = kmap_atomic(page, KM_USER0);
+			userpage = kmap_atomic(page);
 			memset(userpage + pg_offset, 0, iosize);
 			flush_dcache_page(page);
-			kunmap_atomic(userpage, KM_USER0);
+			kunmap_atomic(userpage);
 
 			set_extent_uptodate(tree, cur, cur + iosize - 1,
 					    &cached, GFP_NOFS);
@@ -2745,10 +2745,10 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
 	if (page->index == end_index) {
 		char *userpage;
 
-		userpage = kmap_atomic(page, KM_USER0);
+		userpage = kmap_atomic(page);
 		memset(userpage + pg_offset, 0,
 		       PAGE_CACHE_SIZE - pg_offset);
-		kunmap_atomic(userpage, KM_USER0);
+		kunmap_atomic(userpage);
 		flush_dcache_page(page);
 	}
 	pg_offset = 0;
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index c7fb3a4..078b4fd 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -447,13 +447,13 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
 			sums->bytenr = ordered->start;
 		}
 
-		data = kmap_atomic(bvec->bv_page, KM_USER0);
+		data = kmap_atomic(bvec->bv_page);
 		sector_sum->sum = ~(u32)0;
 		sector_sum->sum = btrfs_csum_data(root,
 						  data + bvec->bv_offset,
 						  sector_sum->sum,
 						  bvec->bv_len);
-		kunmap_atomic(data, KM_USER0);
+		kunmap_atomic(data);
 		btrfs_csum_final(sector_sum->sum,
 				 (char *)&sector_sum->sum);
 		sector_sum->bytenr = disk_bytenr;
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index c2f2059..7f4f302 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -1067,7 +1067,7 @@ int btrfs_write_out_cache(struct btrfs_root *root,
 		spin_unlock(&block_group->lock);
 		ret = 0;
 #ifdef DEBUG
-		printk(KERN_ERR "btrfs: failed to write free space cace "
+		printk(KERN_ERR "btrfs: failed to write free space cache "
 		       "for block group %llu\n", block_group->key.objectid);
 #endif
 	}
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 213ffa8..715dc56 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -438,7 +438,7 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
 					  trans->bytes_reserved);
 	if (ret)
 		goto out;
-	trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
+	trace_btrfs_space_reservation(root->fs_info, "ino_cache", (long)trans,
 				      trans->bytes_reserved, 1);
 again:
 	inode = lookup_free_ino_inode(root, path);
@@ -500,7 +500,7 @@ again:
 out_put:
 	iput(inode);
 out_release:
-	trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
+	trace_btrfs_space_reservation(root->fs_info, "ino_cache", (long)trans,
 				      trans->bytes_reserved, 0);
 	btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
 out:
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 32214fe..a5adfe6 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -173,9 +173,9 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
 			cur_size = min_t(unsigned long, compressed_size,
 				       PAGE_CACHE_SIZE);
 
-			kaddr = kmap_atomic(cpage, KM_USER0);
+			kaddr = kmap_atomic(cpage);
 			write_extent_buffer(leaf, kaddr, ptr, cur_size);
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 
 			i++;
 			ptr += cur_size;
@@ -187,10 +187,10 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
 		page = find_get_page(inode->i_mapping,
 				     start >> PAGE_CACHE_SHIFT);
 		btrfs_set_file_extent_compression(leaf, ei, 0);
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		offset = start & (PAGE_CACHE_SIZE - 1);
 		write_extent_buffer(leaf, kaddr + offset, ptr, size);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		page_cache_release(page);
 	}
 	btrfs_mark_buffer_dirty(leaf);
@@ -422,10 +422,10 @@ again:
 			 * sending it down to disk
 			 */
 			if (offset) {
-				kaddr = kmap_atomic(page, KM_USER0);
+				kaddr = kmap_atomic(page);
 				memset(kaddr + offset, 0,
 				       PAGE_CACHE_SIZE - offset);
-				kunmap_atomic(kaddr, KM_USER0);
+				kunmap_atomic(kaddr);
 			}
 			will_compress = 1;
 		}
@@ -1863,7 +1863,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
 	} else {
 		ret = get_state_private(io_tree, start, &private);
 	}
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	if (ret)
 		goto zeroit;
 
@@ -1872,7 +1872,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
 	if (csum != private)
 		goto zeroit;
 
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 good:
 	return 0;
 
@@ -1884,7 +1884,7 @@ zeroit:
 		       (unsigned long long)private);
 	memset(kaddr + offset, 1, end - start + 1);
 	flush_dcache_page(page);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	if (private == 0)
 		return 0;
 	return -EIO;
@@ -4909,12 +4909,12 @@ static noinline int uncompress_inline(struct btrfs_path *path,
 	ret = btrfs_decompress(compress_type, tmp, page,
 			       extent_offset, inline_size, max_size);
 	if (ret) {
-		char *kaddr = kmap_atomic(page, KM_USER0);
+		char *kaddr = kmap_atomic(page);
 		unsigned long copy_size = min_t(u64,
 				  PAGE_CACHE_SIZE - pg_offset,
 				  max_size - extent_offset);
 		memset(kaddr + pg_offset, 0, copy_size);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 	kfree(tmp);
 	return 0;
@@ -5691,11 +5691,11 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
 			unsigned long flags;
 
 			local_irq_save(flags);
-			kaddr = kmap_atomic(page, KM_IRQ0);
+			kaddr = kmap_atomic(page);
 			csum = btrfs_csum_data(root, kaddr + bvec->bv_offset,
 					       csum, bvec->bv_len);
 			btrfs_csum_final(csum, (char *)&csum);
-			kunmap_atomic(kaddr, KM_IRQ0);
+			kunmap_atomic(kaddr);
 			local_irq_restore(flags);
 
 			flush_dcache_page(bvec->bv_page);
diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c
index a178f5e..743b86f 100644
--- a/fs/btrfs/lzo.c
+++ b/fs/btrfs/lzo.c
@@ -411,9 +411,9 @@ static int lzo_decompress(struct list_head *ws, unsigned char *data_in,
 
 	bytes = min_t(unsigned long, destlen, out_len - start_byte);
 
-	kaddr = kmap_atomic(dest_page, KM_USER0);
+	kaddr = kmap_atomic(dest_page);
 	memcpy(kaddr, workspace->buf + start_byte, bytes);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 out:
 	return ret;
 }
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 9770cc5..1867109 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -591,7 +591,7 @@ static int scrub_fixup_check(struct scrub_bio *sbio, int ix)
 	u64 flags = sbio->spag[ix].flags;
 
 	page = sbio->bio->bi_io_vec[ix].bv_page;
-	buffer = kmap_atomic(page, KM_USER0);
+	buffer = kmap_atomic(page);
 	if (flags & BTRFS_EXTENT_FLAG_DATA) {
 		ret = scrub_checksum_data(sbio->sdev,
 					  sbio->spag + ix, buffer);
@@ -603,7 +603,7 @@ static int scrub_fixup_check(struct scrub_bio *sbio, int ix)
 	} else {
 		WARN_ON(1);
 	}
-	kunmap_atomic(buffer, KM_USER0);
+	kunmap_atomic(buffer);
 
 	return ret;
 }
@@ -792,7 +792,7 @@ static void scrub_checksum(struct btrfs_work *work)
 	}
 	for (i = 0; i < sbio->count; ++i) {
 		page = sbio->bio->bi_io_vec[i].bv_page;
-		buffer = kmap_atomic(page, KM_USER0);
+		buffer = kmap_atomic(page);
 		flags = sbio->spag[i].flags;
 		logical = sbio->logical + i * PAGE_SIZE;
 		ret = 0;
@@ -807,7 +807,7 @@ static void scrub_checksum(struct btrfs_work *work)
 		} else {
 			WARN_ON(1);
 		}
-		kunmap_atomic(buffer, KM_USER0);
+		kunmap_atomic(buffer);
 		if (ret) {
 			ret = scrub_recheck_error(sbio, i);
 			if (!ret) {
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 3ce97b2..81df3fe 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -629,7 +629,6 @@ static int btrfs_fill_super(struct super_block *sb,
 			    void *data, int silent)
 {
 	struct inode *inode;
-	struct dentry *root_dentry;
 	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
 	struct btrfs_key key;
 	int err;
@@ -660,15 +659,12 @@ static int btrfs_fill_super(struct super_block *sb,
 		goto fail_close;
 	}
 
-	root_dentry = d_alloc_root(inode);
-	if (!root_dentry) {
-		iput(inode);
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root) {
 		err = -ENOMEM;
 		goto fail_close;
 	}
 
-	sb->s_root = root_dentry;
-
 	save_mount_options(sb, data);
 	cleancache_init_fs(sb);
 	sb->s_flags |= MS_ACTIVE;
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index faccd47..92c2065 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -370,9 +370,9 @@ static int zlib_decompress(struct list_head *ws, unsigned char *data_in,
 			    PAGE_CACHE_SIZE - buf_offset);
 		bytes = min(bytes, bytes_left);
 
-		kaddr = kmap_atomic(dest_page, KM_USER0);
+		kaddr = kmap_atomic(dest_page);
 		memcpy(kaddr + pg_offset, workspace->buf + buf_offset, bytes);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 
 		pg_offset += bytes;
 		bytes_left -= bytes;
diff --git a/fs/buffer.c b/fs/buffer.c
index 1a30db7..baa075e 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1384,10 +1384,23 @@ static void invalidate_bh_lru(void *arg)
 	}
 	put_cpu_var(bh_lrus);
 }
+
+static bool has_bh_in_lru(int cpu, void *dummy)
+{
+	struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu);
+	int i;
 	
+	for (i = 0; i < BH_LRU_SIZE; i++) {
+		if (b->bhs[i])
+			return 1;
+	}
+
+	return 0;
+}
+
 void invalidate_bh_lrus(void)
 {
-	on_each_cpu(invalidate_bh_lru, NULL, 1);
+	on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL);
 }
 EXPORT_SYMBOL_GPL(invalidate_bh_lrus);
 
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index a0358c2..3f45831 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/file.h>
 #include <linux/fs.h>
-#include <linux/fsnotify.h>
 #include <linux/quotaops.h>
 #include <linux/xattr.h>
 #include <linux/mount.h>
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index e18b183..6e05068 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/file.h>
 #include <linux/fs.h>
-#include <linux/fsnotify.h>
 #include <linux/quotaops.h>
 #include <linux/xattr.h>
 #include <linux/slab.h>
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 00de2c9..256f852 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -655,9 +655,8 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc,
 		dout("open_root_inode success\n");
 		if (ceph_ino(inode) == CEPH_INO_ROOT &&
 		    fsc->sb->s_root == NULL) {
-			root = d_alloc_root(inode);
+			root = d_make_root(inode);
 			if (!root) {
-				iput(inode);
 				root = ERR_PTR(-ENOMEM);
 				goto out;
 			}
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c1b2544..3cc1b25 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -556,6 +556,7 @@ init_cifs_idmap(void)
 
 	/* instruct request_key() to use this special keyring as a cache for
 	 * the results it looks up */
+	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
 	cred->thread_keyring = keyring;
 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
 	root_cred = cred;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b1fd382..5c6eb6e 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -119,12 +119,10 @@ cifs_read_super(struct super_block *sb)
 
 	if (IS_ERR(inode)) {
 		rc = PTR_ERR(inode);
-		inode = NULL;
 		goto out_no_root;
 	}
 
-	sb->s_root = d_alloc_root(inode);
-
+	sb->s_root = d_make_root(inode);
 	if (!sb->s_root) {
 		rc = -ENOMEM;
 		goto out_no_root;
@@ -147,9 +145,6 @@ cifs_read_super(struct super_block *sb)
 
 out_no_root:
 	cERROR(1, "cifs_read_super: get root inode failed");
-	if (inode)
-		iput(inode);
-
 	return rc;
 }
 
@@ -703,7 +698,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
 	 * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
 	 * the cached file length
 	 */
-	if (origin != SEEK_SET || origin != SEEK_CUR) {
+	if (origin != SEEK_SET && origin != SEEK_CUR) {
 		int rc;
 		struct inode *inode = file->f_path.dentry->d_inode;
 
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 5e2e1b3..05156c1 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -208,13 +208,12 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
         if (IS_ERR(root)) {
 		error = PTR_ERR(root);
 		printk("Failure of coda_cnode_make for root: error %d\n", error);
-		root = NULL;
 		goto error;
 	} 
 
 	printk("coda_read_super: rootinode is %ld dev %s\n", 
 	       root->i_ino, root->i_sb->s_id);
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
 		error = -EINVAL;
 		goto error;
@@ -222,9 +221,6 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
 	return 0;
 
 error:
-	if (root)
-		iput(root);
-
 	mutex_lock(&vc->vc_mutex);
 	bdi_destroy(&vc->bdi);
 	vc->vc_sb = NULL;
diff --git a/fs/compat.c b/fs/compat.c
index fa9d721..07880ba 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -131,41 +131,35 @@ asmlinkage long compat_sys_utimes(const char __user *filename, struct compat_tim
 
 static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
 {
-	compat_ino_t ino = stat->ino;
-	typeof(ubuf->st_uid) uid = 0;
-	typeof(ubuf->st_gid) gid = 0;
-	int err;
+	struct compat_stat tmp;
 
-	SET_UID(uid, stat->uid);
-	SET_GID(gid, stat->gid);
+	if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
+		return -EOVERFLOW;
 
-	if ((u64) stat->size > MAX_NON_LFS ||
-	    !old_valid_dev(stat->dev) ||
-	    !old_valid_dev(stat->rdev))
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = old_encode_dev(stat->dev);
+	tmp.st_ino = stat->ino;
+	if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
 		return -EOVERFLOW;
-	if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	if (tmp.st_nlink != stat->nlink)
 		return -EOVERFLOW;
-
-	if (clear_user(ubuf, sizeof(*ubuf)))
-		return -EFAULT;
-
-	err  = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
-	err |= __put_user(ino, &ubuf->st_ino);
-	err |= __put_user(stat->mode, &ubuf->st_mode);
-	err |= __put_user(stat->nlink, &ubuf->st_nlink);
-	err |= __put_user(uid, &ubuf->st_uid);
-	err |= __put_user(gid, &ubuf->st_gid);
-	err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
-	err |= __put_user(stat->size, &ubuf->st_size);
-	err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
-	err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
-	err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
-	err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
-	err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
-	err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
-	err |= __put_user(stat->blksize, &ubuf->st_blksize);
-	err |= __put_user(stat->blocks, &ubuf->st_blocks);
-	return err;
+	SET_UID(tmp.st_uid, stat->uid);
+	SET_GID(tmp.st_gid, stat->gid);
+	tmp.st_rdev = old_encode_dev(stat->rdev);
+	if ((u64) stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime.tv_sec;
+	tmp.st_atime_nsec = stat->atime.tv_nsec;
+	tmp.st_mtime = stat->mtime.tv_sec;
+	tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+	tmp.st_ctime = stat->ctime.tv_sec;
+	tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
+	return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
 asmlinkage long compat_sys_newstat(const char __user * filename,
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index 276e15c..07f6045 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -91,10 +91,9 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent)
 		return -ENOMEM;
 	}
 
-	root = d_alloc_root(inode);
+	root = d_make_root(inode);
 	if (!root) {
 		pr_debug("%s: could not get root dentry!\n",__func__);
-		iput(inode);
 		return -ENOMEM;
 	}
 	config_group_init(&configfs_root_group);
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index a2ee8f9..d013c46 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -257,10 +257,10 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
 
 	/* Do sanity checks on the superblock */
 	if (super.magic != CRAMFS_MAGIC) {
-		/* check for wrong endianess */
+		/* check for wrong endianness */
 		if (super.magic == CRAMFS_MAGIC_WEND) {
 			if (!silent)
-				printk(KERN_ERR "cramfs: wrong endianess\n");
+				printk(KERN_ERR "cramfs: wrong endianness\n");
 			goto out;
 		}
 
@@ -270,7 +270,7 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
 		mutex_unlock(&read_mutex);
 		if (super.magic != CRAMFS_MAGIC) {
 			if (super.magic == CRAMFS_MAGIC_WEND && !silent)
-				printk(KERN_ERR "cramfs: wrong endianess\n");
+				printk(KERN_ERR "cramfs: wrong endianness\n");
 			else if (!silent)
 				printk(KERN_ERR "cramfs: wrong magic\n");
 			goto out;
@@ -318,11 +318,9 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
 	root = get_cramfs_inode(sb, &super.root, 0);
 	if (IS_ERR(root))
 		goto out;
-	sb->s_root = d_alloc_root(root);
-	if (!sb->s_root) {
-		iput(root);
+	sb->s_root = d_make_root(root);
+	if (!sb->s_root)
 		goto out;
-	}
 	return 0;
 out:
 	kfree(sbi);
diff --git a/fs/dcache.c b/fs/dcache.c
index 16a53cc..5e0c7ae 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1423,30 +1423,6 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
 
 EXPORT_SYMBOL(d_instantiate_unique);
 
-/**
- * d_alloc_root - allocate root dentry
- * @root_inode: inode to allocate the root for
- *
- * Allocate a root ("/") dentry for the inode given. The inode is
- * instantiated and returned. %NULL is returned if there is insufficient
- * memory or the inode passed is %NULL.
- */
- 
-struct dentry * d_alloc_root(struct inode * root_inode)
-{
-	struct dentry *res = NULL;
-
-	if (root_inode) {
-		static const struct qstr name = { .name = "/", .len = 1 };
-
-		res = __d_alloc(root_inode->i_sb, &name);
-		if (res)
-			d_instantiate(res, root_inode);
-	}
-	return res;
-}
-EXPORT_SYMBOL(d_alloc_root);
-
 struct dentry *d_make_root(struct inode *root_inode)
 {
 	struct dentry *res = NULL;
@@ -2466,7 +2442,7 @@ static int prepend_path(const struct path *path,
 	bool slash = false;
 	int error = 0;
 
-	br_read_lock(vfsmount_lock);
+	br_read_lock(&vfsmount_lock);
 	while (dentry != root->dentry || vfsmnt != root->mnt) {
 		struct dentry * parent;
 
@@ -2497,7 +2473,7 @@ static int prepend_path(const struct path *path,
 		error = prepend(buffer, buflen, "/", 1);
 
 out:
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 	return error;
 
 global_root:
@@ -2968,7 +2944,7 @@ __setup("dhash_entries=", set_dhash_entries);
 
 static void __init dcache_init_early(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* If hashes are distributed across NUMA nodes, defer
 	 * hash allocation until vmalloc space is available.
@@ -2986,13 +2962,13 @@ static void __init dcache_init_early(void)
 					&d_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << d_hash_shift); loop++)
+	for (loop = 0; loop < (1U << d_hash_shift); loop++)
 		INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
 }
 
 static void __init dcache_init(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* 
 	 * A constructor could be added for stable state like the lists,
@@ -3016,7 +2992,7 @@ static void __init dcache_init(void)
 					&d_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << d_hash_shift); loop++)
+	for (loop = 0; loop < (1U << d_hash_shift); loop++)
 		INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
 }
 
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 956d5dd..b80bc84 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -23,9 +23,13 @@
 #include <linux/debugfs.h>
 #include <linux/fsnotify.h>
 #include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/parser.h>
 #include <linux/magic.h>
 #include <linux/slab.h>
 
+#define DEBUGFS_DEFAULT_MODE	0755
+
 static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
 static bool debugfs_registered;
@@ -125,11 +129,154 @@ static inline int debugfs_positive(struct dentry *dentry)
 	return dentry->d_inode && !d_unhashed(dentry);
 }
 
+struct debugfs_mount_opts {
+	uid_t uid;
+	gid_t gid;
+	umode_t mode;
+};
+
+enum {
+	Opt_uid,
+	Opt_gid,
+	Opt_mode,
+	Opt_err
+};
+
+static const match_table_t tokens = {
+	{Opt_uid, "uid=%u"},
+	{Opt_gid, "gid=%u"},
+	{Opt_mode, "mode=%o"},
+	{Opt_err, NULL}
+};
+
+struct debugfs_fs_info {
+	struct debugfs_mount_opts mount_opts;
+};
+
+static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
+{
+	substring_t args[MAX_OPT_ARGS];
+	int option;
+	int token;
+	char *p;
+
+	opts->mode = DEBUGFS_DEFAULT_MODE;
+
+	while ((p = strsep(&data, ",")) != NULL) {
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_uid:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			opts->uid = option;
+			break;
+		case Opt_gid:
+			if (match_octal(&args[0], &option))
+				return -EINVAL;
+			opts->gid = option;
+			break;
+		case Opt_mode:
+			if (match_octal(&args[0], &option))
+				return -EINVAL;
+			opts->mode = option & S_IALLUGO;
+			break;
+		/*
+		 * We might like to report bad mount options here;
+		 * but traditionally debugfs has ignored all mount options
+		 */
+		}
+	}
+
+	return 0;
+}
+
+static int debugfs_apply_options(struct super_block *sb)
+{
+	struct debugfs_fs_info *fsi = sb->s_fs_info;
+	struct inode *inode = sb->s_root->d_inode;
+	struct debugfs_mount_opts *opts = &fsi->mount_opts;
+
+	inode->i_mode &= ~S_IALLUGO;
+	inode->i_mode |= opts->mode;
+
+	inode->i_uid = opts->uid;
+	inode->i_gid = opts->gid;
+
+	return 0;
+}
+
+static int debugfs_remount(struct super_block *sb, int *flags, char *data)
+{
+	int err;
+	struct debugfs_fs_info *fsi = sb->s_fs_info;
+
+	err = debugfs_parse_options(data, &fsi->mount_opts);
+	if (err)
+		goto fail;
+
+	debugfs_apply_options(sb);
+
+fail:
+	return err;
+}
+
+static int debugfs_show_options(struct seq_file *m, struct dentry *root)
+{
+	struct debugfs_fs_info *fsi = root->d_sb->s_fs_info;
+	struct debugfs_mount_opts *opts = &fsi->mount_opts;
+
+	if (opts->uid != 0)
+		seq_printf(m, ",uid=%u", opts->uid);
+	if (opts->gid != 0)
+		seq_printf(m, ",gid=%u", opts->gid);
+	if (opts->mode != DEBUGFS_DEFAULT_MODE)
+		seq_printf(m, ",mode=%o", opts->mode);
+
+	return 0;
+}
+
+static const struct super_operations debugfs_super_operations = {
+	.statfs		= simple_statfs,
+	.remount_fs	= debugfs_remount,
+	.show_options	= debugfs_show_options,
+};
+
 static int debug_fill_super(struct super_block *sb, void *data, int silent)
 {
 	static struct tree_descr debug_files[] = {{""}};
+	struct debugfs_fs_info *fsi;
+	int err;
+
+	save_mount_options(sb, data);
+
+	fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
+	sb->s_fs_info = fsi;
+	if (!fsi) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	err = debugfs_parse_options(data, &fsi->mount_opts);
+	if (err)
+		goto fail;
+
+	err  =  simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
+	if (err)
+		goto fail;
+
+	sb->s_op = &debugfs_super_operations;
+
+	debugfs_apply_options(sb);
+
+	return 0;
 
-	return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
+fail:
+	kfree(fsi);
+	sb->s_fs_info = NULL;
+	return err;
 }
 
 static struct dentry *debug_mount(struct file_system_type *fs_type,
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index c4e2a58..10f5e0b 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -36,7 +36,61 @@
 #define DEVPTS_DEFAULT_PTMX_MODE 0000
 #define PTMX_MINOR	2
 
-extern int pty_limit;			/* Config limit on Unix98 ptys */
+/*
+ * sysctl support for setting limits on the number of Unix98 ptys allocated.
+ * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly.
+ */
+static int pty_limit = NR_UNIX98_PTY_DEFAULT;
+static int pty_reserve = NR_UNIX98_PTY_RESERVE;
+static int pty_limit_min;
+static int pty_limit_max = INT_MAX;
+static int pty_count;
+
+static struct ctl_table pty_table[] = {
+	{
+		.procname	= "max",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.data		= &pty_limit,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &pty_limit_min,
+		.extra2		= &pty_limit_max,
+	}, {
+		.procname	= "reserve",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.data		= &pty_reserve,
+		.proc_handler	= proc_dointvec_minmax,
+		.extra1		= &pty_limit_min,
+		.extra2		= &pty_limit_max,
+	}, {
+		.procname	= "nr",
+		.maxlen		= sizeof(int),
+		.mode		= 0444,
+		.data		= &pty_count,
+		.proc_handler	= proc_dointvec,
+	},
+	{}
+};
+
+static struct ctl_table pty_kern_table[] = {
+	{
+		.procname	= "pty",
+		.mode		= 0555,
+		.child		= pty_table,
+	},
+	{}
+};
+
+static struct ctl_table pty_root_table[] = {
+	{
+		.procname	= "kernel",
+		.mode		= 0555,
+		.child		= pty_kern_table,
+	},
+	{}
+};
+
 static DEFINE_MUTEX(allocated_ptys_lock);
 
 static struct vfsmount *devpts_mnt;
@@ -49,10 +103,11 @@ struct pts_mount_opts {
 	umode_t mode;
 	umode_t ptmxmode;
 	int newinstance;
+	int max;
 };
 
 enum {
-	Opt_uid, Opt_gid, Opt_mode, Opt_ptmxmode, Opt_newinstance,
+	Opt_uid, Opt_gid, Opt_mode, Opt_ptmxmode, Opt_newinstance,  Opt_max,
 	Opt_err
 };
 
@@ -63,6 +118,7 @@ static const match_table_t tokens = {
 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
 	{Opt_ptmxmode, "ptmxmode=%o"},
 	{Opt_newinstance, "newinstance"},
+	{Opt_max, "max=%d"},
 #endif
 	{Opt_err, NULL}
 };
@@ -109,6 +165,7 @@ static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts)
 	opts->gid     = 0;
 	opts->mode    = DEVPTS_DEFAULT_MODE;
 	opts->ptmxmode = DEVPTS_DEFAULT_PTMX_MODE;
+	opts->max     = NR_UNIX98_PTY_MAX;
 
 	/* newinstance makes sense only on initial mount */
 	if (op == PARSE_MOUNT)
@@ -152,6 +209,12 @@ static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts)
 			if (op == PARSE_MOUNT)
 				opts->newinstance = 1;
 			break;
+		case Opt_max:
+			if (match_int(&args[0], &option) ||
+			    option < 0 || option > NR_UNIX98_PTY_MAX)
+				return -EINVAL;
+			opts->max = option;
+			break;
 #endif
 		default:
 			printk(KERN_ERR "devpts: called with bogus options\n");
@@ -258,6 +321,8 @@ static int devpts_show_options(struct seq_file *seq, struct dentry *root)
 	seq_printf(seq, ",mode=%03o", opts->mode);
 #ifdef CONFIG_DEVPTS_MULTIPLE_INSTANCES
 	seq_printf(seq, ",ptmxmode=%03o", opts->ptmxmode);
+	if (opts->max < NR_UNIX98_PTY_MAX)
+		seq_printf(seq, ",max=%d", opts->max);
 #endif
 
 	return 0;
@@ -309,12 +374,11 @@ devpts_fill_super(struct super_block *s, void *data, int silent)
 	inode->i_fop = &simple_dir_operations;
 	set_nlink(inode, 2);
 
-	s->s_root = d_alloc_root(inode);
+	s->s_root = d_make_root(inode);
 	if (s->s_root)
 		return 0;
 
 	printk(KERN_ERR "devpts: get root dentry failed\n");
-	iput(inode);
 
 fail:
 	return -ENOMEM;
@@ -438,6 +502,12 @@ retry:
 		return -ENOMEM;
 
 	mutex_lock(&allocated_ptys_lock);
+	if (pty_count >= pty_limit -
+			(fsi->mount_opts.newinstance ? pty_reserve : 0)) {
+		mutex_unlock(&allocated_ptys_lock);
+		return -ENOSPC;
+	}
+
 	ida_ret = ida_get_new(&fsi->allocated_ptys, &index);
 	if (ida_ret < 0) {
 		mutex_unlock(&allocated_ptys_lock);
@@ -446,11 +516,12 @@ retry:
 		return -EIO;
 	}
 
-	if (index >= pty_limit) {
+	if (index >= fsi->mount_opts.max) {
 		ida_remove(&fsi->allocated_ptys, index);
 		mutex_unlock(&allocated_ptys_lock);
-		return -EIO;
+		return -ENOSPC;
 	}
+	pty_count++;
 	mutex_unlock(&allocated_ptys_lock);
 	return index;
 }
@@ -462,6 +533,7 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx)
 
 	mutex_lock(&allocated_ptys_lock);
 	ida_remove(&fsi->allocated_ptys, idx);
+	pty_count--;
 	mutex_unlock(&allocated_ptys_lock);
 }
 
@@ -558,11 +630,15 @@ void devpts_pty_kill(struct tty_struct *tty)
 static int __init init_devpts_fs(void)
 {
 	int err = register_filesystem(&devpts_fs_type);
+	struct ctl_table_header *table;
+
 	if (!err) {
+		table = register_sysctl_table(pty_root_table);
 		devpts_mnt = kern_mount(&devpts_fs_type);
 		if (IS_ERR(devpts_mnt)) {
 			err = PTR_ERR(devpts_mnt);
 			unregister_filesystem(&devpts_fs_type);
+			unregister_sysctl_table(table);
 		}
 	}
 	return err;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index b4a6bef..6e0e017 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -550,9 +550,8 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
 	if (IS_ERR(inode))
 		goto out_free;
 
-	s->s_root = d_alloc_root(inode);
+	s->s_root = d_make_root(inode);
 	if (!s->s_root) {
-		iput(inode);
 		rc = -ENOMEM;
 		goto out_free;
 	}
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index a46b3a8..8a1c721 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -350,7 +350,8 @@ static int ecryptfs_write_begin(struct file *file,
 			if (prev_page_end_size
 			    >= i_size_read(page->mapping->host)) {
 				zero_user(page, 0, PAGE_CACHE_SIZE);
-			} else {
+				SetPageUptodate(page);
+			} else if (len < PAGE_CACHE_SIZE) {
 				rc = ecryptfs_decrypt_page(page);
 				if (rc) {
 					printk(KERN_ERR "%s: Error decrypting "
@@ -360,8 +361,8 @@ static int ecryptfs_write_begin(struct file *file,
 					ClearPageUptodate(page);
 					goto out;
 				}
+				SetPageUptodate(page);
 			}
-			SetPageUptodate(page);
 		}
 	}
 	/* If creating a page or more of holes, zero them out via truncate.
@@ -512,6 +513,13 @@ static int ecryptfs_write_end(struct file *file,
 		}
 		goto out;
 	}
+	if (!PageUptodate(page)) {
+		if (copied < PAGE_CACHE_SIZE) {
+			rc = 0;
+			goto out;
+		}
+		SetPageUptodate(page);
+	}
 	/* Fills in zeros if 'to' goes beyond inode size */
 	rc = fill_zeros_to_end_of_page(page, to);
 	if (rc) {
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index cf15282..2dd946b 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -184,7 +184,6 @@ static int ecryptfs_show_options(struct seq_file *m, struct dentry *root)
 const struct super_operations ecryptfs_sops = {
 	.alloc_inode = ecryptfs_alloc_inode,
 	.destroy_inode = ecryptfs_destroy_inode,
-	.drop_inode = generic_drop_inode,
 	.statfs = ecryptfs_statfs,
 	.remount_fs = NULL,
 	.evict_inode = ecryptfs_evict_inode,
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 9811064..e755ec7 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -317,10 +317,9 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
 		goto out_no_fs;
 	}
 
-	s->s_root = d_alloc_root(root);
+	s->s_root = d_make_root(root);
 	if (!(s->s_root)) {
 		printk(KERN_ERR "EFS: get root dentry failed\n");
-		iput(root);
 		ret = -ENOMEM;
 		goto out_no_fs;
 	}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index aabdfc3..c636fc8 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -422,6 +422,31 @@ out_unlock:
 	return error;
 }
 
+/*
+ * As described in commit 0ccf831cb lockdep: annotate epoll
+ * the use of wait queues used by epoll is done in a very controlled
+ * manner. Wake ups can nest inside each other, but are never done
+ * with the same locking. For example:
+ *
+ *   dfd = socket(...);
+ *   efd1 = epoll_create();
+ *   efd2 = epoll_create();
+ *   epoll_ctl(efd1, EPOLL_CTL_ADD, dfd, ...);
+ *   epoll_ctl(efd2, EPOLL_CTL_ADD, efd1, ...);
+ *
+ * When a packet arrives to the device underneath "dfd", the net code will
+ * issue a wake_up() on its poll wake list. Epoll (efd1) has installed a
+ * callback wakeup entry on that queue, and the wake_up() performed by the
+ * "dfd" net code will end up in ep_poll_callback(). At this point epoll
+ * (efd1) notices that it may have some event ready, so it needs to wake up
+ * the waiters on its poll wait list (efd2). So it calls ep_poll_safewake()
+ * that ends up in another wake_up(), after having checked about the
+ * recursion constraints. That are, no more than EP_MAX_POLLWAKE_NESTS, to
+ * avoid stack blasting.
+ *
+ * When CONFIG_DEBUG_LOCK_ALLOC is enabled, make sure lockdep can handle
+ * this special case of epoll.
+ */
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static inline void ep_wake_up_nested(wait_queue_head_t *wqueue,
 				     unsigned long events, int subclass)
diff --git a/fs/exec.c b/fs/exec.c
index 92ce83a..7043408e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1339,13 +1339,13 @@ int remove_arg_zero(struct linux_binprm *bprm)
 			ret = -EFAULT;
 			goto out;
 		}
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 
 		for (; offset < PAGE_SIZE && kaddr[offset];
 				offset++, bprm->p++)
 			;
 
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		put_arg_page(page);
 
 		if (offset == PAGE_SIZE)
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
index 8040583..c61e62a 100644
--- a/fs/exofs/dir.c
+++ b/fs/exofs/dir.c
@@ -597,7 +597,7 @@ int exofs_make_empty(struct inode *inode, struct inode *parent)
 		goto fail;
 	}
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	de = (struct exofs_dir_entry *)kaddr;
 	de->name_len = 1;
 	de->rec_len = cpu_to_le16(EXOFS_DIR_REC_LEN(1));
@@ -611,7 +611,7 @@ int exofs_make_empty(struct inode *inode, struct inode *parent)
 	de->inode_no = cpu_to_le64(parent->i_ino);
 	memcpy(de->name, PARENT_DIR, sizeof(PARENT_DIR));
 	exofs_set_de_type(de, inode);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	err = exofs_commit_chunk(page, 0, chunk_size);
 fail:
 	page_cache_release(page);
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
index 9dbf0c3..fc7161d 100644
--- a/fs/exofs/namei.c
+++ b/fs/exofs/namei.c
@@ -143,9 +143,6 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir,
 {
 	struct inode *inode = old_dentry->d_inode;
 
-	if (inode->i_nlink >= EXOFS_LINK_MAX)
-		return -EMLINK;
-
 	inode->i_ctime = CURRENT_TIME;
 	inode_inc_link_count(inode);
 	ihold(inode);
@@ -156,10 +153,7 @@ static int exofs_link(struct dentry *old_dentry, struct inode *dir,
 static int exofs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
 	struct inode *inode;
-	int err = -EMLINK;
-
-	if (dir->i_nlink >= EXOFS_LINK_MAX)
-		goto out;
+	int err;
 
 	inode_inc_link_count(dir);
 
@@ -275,11 +269,6 @@ static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		if (err)
 			goto out_dir;
 	} else {
-		if (dir_de) {
-			err = -EMLINK;
-			if (new_dir->i_nlink >= EXOFS_LINK_MAX)
-				goto out_dir;
-		}
 		err = exofs_add_link(new_dentry, old_inode);
 		if (err)
 			goto out_dir;
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index d22cd16..735ca06 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -389,7 +389,7 @@ static int exofs_sync_fs(struct super_block *sb, int wait)
 	ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
 	memset(fscb, 0, ios->length);
 	fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
-	fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles);
+	fscb->s_numfiles = cpu_to_le64(sbi->s_numfiles);
 	fscb->s_magic = cpu_to_le16(sb->s_magic);
 	fscb->s_newfs = 0;
 	fscb->s_version = EXOFS_FSCB_VER;
@@ -529,7 +529,8 @@ static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev,
 			     struct osd_dev_info *odi)
 {
 	odi->systemid_len = le32_to_cpu(dt_dev->systemid_len);
-	memcpy(odi->systemid, dt_dev->systemid, odi->systemid_len);
+	if (likely(odi->systemid_len))
+		memcpy(odi->systemid, dt_dev->systemid, OSD_SYSTEMID_LEN);
 
 	odi->osdname_len = le32_to_cpu(dt_dev->osdname_len);
 	odi->osdname = dt_dev->osdname;
@@ -565,7 +566,7 @@ int __alloc_dev_table(struct exofs_sb_info *sbi, unsigned numdevs,
 
 	aoded = kzalloc(sizeof(*aoded), GFP_KERNEL);
 	if (unlikely(!aoded)) {
-		EXOFS_ERR("ERROR: faild allocating Device array[%d]\n",
+		EXOFS_ERR("ERROR: failed allocating Device array[%d]\n",
 			  numdevs);
 		return -ENOMEM;
 	}
@@ -754,6 +755,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_blocksize = EXOFS_BLKSIZE;
 	sb->s_blocksize_bits = EXOFS_BLKSHIFT;
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	sb->s_max_links = EXOFS_LINK_MAX;
 	atomic_set(&sbi->s_curr_pending, 0);
 	sb->s_bdev = NULL;
 	sb->s_dev = 0;
@@ -818,9 +820,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
 		ret = PTR_ERR(root);
 		goto free_sbi;
 	}
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
-		iput(root);
 		EXOFS_ERR("ERROR: get root inode failed\n");
 		ret = -ENOMEM;
 		goto free_sbi;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index d37df35..0f4f5c9 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -645,7 +645,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
 		unlock_page(page);
 		goto fail;
 	}
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memset(kaddr, 0, chunk_size);
 	de = (struct ext2_dir_entry_2 *)kaddr;
 	de->name_len = 1;
@@ -660,7 +660,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
 	de->inode = cpu_to_le32(parent->i_ino);
 	memcpy (de->name, "..\0", 4);
 	ext2_set_de_type (de, inode);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	err = ext2_commit_chunk(page, 0, chunk_size);
 fail:
 	page_cache_release(page);
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index 0804198..dffb865 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -195,9 +195,6 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
 	struct inode *inode = old_dentry->d_inode;
 	int err;
 
-	if (inode->i_nlink >= EXT2_LINK_MAX)
-		return -EMLINK;
-
 	dquot_initialize(dir);
 
 	inode->i_ctime = CURRENT_TIME_SEC;
@@ -217,10 +214,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
 static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
 {
 	struct inode * inode;
-	int err = -EMLINK;
-
-	if (dir->i_nlink >= EXT2_LINK_MAX)
-		goto out;
+	int err;
 
 	dquot_initialize(dir);
 
@@ -346,11 +340,6 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
 			drop_nlink(new_inode);
 		inode_dec_link_count(new_inode);
 	} else {
-		if (dir_de) {
-			err = -EMLINK;
-			if (new_dir->i_nlink >= EXT2_LINK_MAX)
-				goto out_dir;
-		}
 		err = ext2_add_link(new_dentry, old_inode);
 		if (err)
 			goto out_dir;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 0090595..e1025c7 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -919,6 +919,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 	}
 
 	sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);
+	sb->s_max_links = EXT2_LINK_MAX;
 
 	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
 		sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
@@ -1087,9 +1088,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed_mount3;
 	}
 
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
-		iput(root);
 		ext2_msg(sb, KERN_ERR, "error: get root inode failed");
 		ret = -ENOMEM;
 		goto failed_mount3;
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 726c7ef..e0b45b9 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2046,10 +2046,9 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
 		ext3_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck");
 		goto failed_mount3;
 	}
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
 		ext3_msg(sb, KERN_ERR, "error: get root dentry failed");
-		iput(root);
 		ret = -ENOMEM;
 		goto failed_mount3;
 	}
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index f9e2cd8..4bbd07a 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -336,10 +336,10 @@ err_out:
  * Return buffer_head on success or NULL in case of failure.
  */
 struct buffer_head *
-ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
+ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
 {
 	struct ext4_group_desc *desc;
-	struct buffer_head *bh = NULL;
+	struct buffer_head *bh;
 	ext4_fsblk_t bitmap_blk;
 
 	desc = ext4_get_group_desc(sb, block_group, NULL);
@@ -348,9 +348,9 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
 	bitmap_blk = ext4_block_bitmap(sb, desc);
 	bh = sb_getblk(sb, bitmap_blk);
 	if (unlikely(!bh)) {
-		ext4_error(sb, "Cannot read block bitmap - "
-			    "block_group = %u, block_bitmap = %llu",
-			    block_group, bitmap_blk);
+		ext4_error(sb, "Cannot get buffer for block bitmap - "
+			   "block_group = %u, block_bitmap = %llu",
+			   block_group, bitmap_blk);
 		return NULL;
 	}
 
@@ -382,25 +382,50 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
 		return bh;
 	}
 	/*
-	 * submit the buffer_head for read. We can
-	 * safely mark the bitmap as uptodate now.
-	 * We do it here so the bitmap uptodate bit
-	 * get set with buffer lock held.
+	 * submit the buffer_head for reading
 	 */
+	set_buffer_new(bh);
 	trace_ext4_read_block_bitmap_load(sb, block_group);
-	set_bitmap_uptodate(bh);
-	if (bh_submit_read(bh) < 0) {
-		put_bh(bh);
+	bh->b_end_io = ext4_end_bitmap_read;
+	get_bh(bh);
+	submit_bh(READ, bh);
+	return bh;
+}
+
+/* Returns 0 on success, 1 on error */
+int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
+			   struct buffer_head *bh)
+{
+	struct ext4_group_desc *desc;
+
+	if (!buffer_new(bh))
+		return 0;
+	desc = ext4_get_group_desc(sb, block_group, NULL);
+	if (!desc)
+		return 1;
+	wait_on_buffer(bh);
+	if (!buffer_uptodate(bh)) {
 		ext4_error(sb, "Cannot read block bitmap - "
-			    "block_group = %u, block_bitmap = %llu",
-			    block_group, bitmap_blk);
-		return NULL;
+			   "block_group = %u, block_bitmap = %llu",
+			   block_group, (unsigned long long) bh->b_blocknr);
+		return 1;
 	}
+	clear_buffer_new(bh);
+	/* Panic or remount fs read-only if block bitmap is invalid */
 	ext4_valid_block_bitmap(sb, desc, block_group, bh);
-	/*
-	 * file system mounted not to panic on error,
-	 * continue with corrupt bitmap
-	 */
+	return 0;
+}
+
+struct buffer_head *
+ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
+{
+	struct buffer_head *bh;
+
+	bh = ext4_read_block_bitmap_nowait(sb, block_group);
+	if (ext4_wait_block_bitmap(sb, block_group, bh)) {
+		put_bh(bh);
+		return NULL;
+	}
 	return bh;
 }
 
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 164c560..a4a0234 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -91,17 +91,17 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
 		return 0;
 
 	if (filp)
-		ext4_error_file(filp, function, line, bh ? bh->b_blocknr : 0,
+		ext4_error_file(filp, function, line, bh->b_blocknr,
 				"bad entry in directory: %s - offset=%u(%u), "
 				"inode=%u, rec_len=%d, name_len=%d",
-				error_msg, (unsigned) (offset%bh->b_size),
+				error_msg, (unsigned) (offset % bh->b_size),
 				offset, le32_to_cpu(de->inode),
 				rlen, de->name_len);
 	else
-		ext4_error_inode(dir, function, line, bh ? bh->b_blocknr : 0,
+		ext4_error_inode(dir, function, line, bh->b_blocknr,
 				"bad entry in directory: %s - offset=%u(%u), "
 				"inode=%u, rec_len=%d, name_len=%d",
-				error_msg, (unsigned) (offset%bh->b_size),
+				error_msg, (unsigned) (offset % bh->b_size),
 				offset, le32_to_cpu(de->inode),
 				rlen, de->name_len);
 
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 513004f..4076746 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -184,6 +184,7 @@ struct mpage_da_data {
 #define	EXT4_IO_END_UNWRITTEN	0x0001
 #define EXT4_IO_END_ERROR	0x0002
 #define EXT4_IO_END_QUEUED	0x0004
+#define EXT4_IO_END_DIRECT	0x0008
 
 struct ext4_io_page {
 	struct page	*p_page;
@@ -1420,8 +1421,9 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
 #define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
 #define EXT4_FEATURE_INCOMPAT_EA_INODE		0x0400 /* EA in inode */
 #define EXT4_FEATURE_INCOMPAT_DIRDATA		0x1000 /* data in dirent */
-#define EXT4_FEATURE_INCOMPAT_INLINEDATA	0x2000 /* data in inode */
+#define EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM	0x2000 /* use crc32c for bg */
 #define EXT4_FEATURE_INCOMPAT_LARGEDIR		0x4000 /* >2GB or 3-lvl htree */
+#define EXT4_FEATURE_INCOMPAT_INLINEDATA	0x8000 /* data in inode */
 
 #define EXT2_FEATURE_COMPAT_SUPP	EXT4_FEATURE_COMPAT_EXT_ATTR
 #define EXT2_FEATURE_INCOMPAT_SUPP	(EXT4_FEATURE_INCOMPAT_FILETYPE| \
@@ -1794,8 +1796,14 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 						    ext4_group_t block_group,
 						    struct buffer_head ** bh);
 extern int ext4_should_retry_alloc(struct super_block *sb, int *retries);
-struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
-				      ext4_group_t block_group);
+
+extern struct buffer_head *ext4_read_block_bitmap_nowait(struct super_block *sb,
+						ext4_group_t block_group);
+extern int ext4_wait_block_bitmap(struct super_block *sb,
+				  ext4_group_t block_group,
+				  struct buffer_head *bh);
+extern struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
+						  ext4_group_t block_group);
 extern void ext4_init_block_bitmap(struct super_block *sb,
 				   struct buffer_head *bh,
 				   ext4_group_t group,
@@ -1841,6 +1849,7 @@ extern void ext4_check_inodes_bitmap(struct super_block *);
 extern void ext4_mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
 extern int ext4_init_inode_table(struct super_block *sb,
 				 ext4_group_t group, int barrier);
+extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate);
 
 /* mballoc.c */
 extern long ext4_mb_stats;
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index 5802fa1..83b20fc 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -104,6 +104,78 @@
 #define EXT4_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_INIT_BLOCKS(sb))
 #define EXT4_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT4_QUOTA_DEL_BLOCKS(sb))
 
+/**
+ *   struct ext4_journal_cb_entry - Base structure for callback information.
+ *
+ *   This struct is a 'seed' structure for a using with your own callback
+ *   structs. If you are using callbacks you must allocate one of these
+ *   or another struct of your own definition which has this struct
+ *   as it's first element and pass it to ext4_journal_callback_add().
+ */
+struct ext4_journal_cb_entry {
+	/* list information for other callbacks attached to the same handle */
+	struct list_head jce_list;
+
+	/*  Function to call with this callback structure */
+	void (*jce_func)(struct super_block *sb,
+			 struct ext4_journal_cb_entry *jce, int error);
+
+	/* user data goes here */
+};
+
+/**
+ * ext4_journal_callback_add: add a function to call after transaction commit
+ * @handle: active journal transaction handle to register callback on
+ * @func: callback function to call after the transaction has committed:
+ *        @sb: superblock of current filesystem for transaction
+ *        @jce: returned journal callback data
+ *        @rc: journal state at commit (0 = transaction committed properly)
+ * @jce: journal callback data (internal and function private data struct)
+ *
+ * The registered function will be called in the context of the journal thread
+ * after the transaction for which the handle was created has completed.
+ *
+ * No locks are held when the callback function is called, so it is safe to
+ * call blocking functions from within the callback, but the callback should
+ * not block or run for too long, or the filesystem will be blocked waiting for
+ * the next transaction to commit. No journaling functions can be used, or
+ * there is a risk of deadlock.
+ *
+ * There is no guaranteed calling order of multiple registered callbacks on
+ * the same transaction.
+ */
+static inline void ext4_journal_callback_add(handle_t *handle,
+			void (*func)(struct super_block *sb,
+				     struct ext4_journal_cb_entry *jce,
+				     int rc),
+			struct ext4_journal_cb_entry *jce)
+{
+	struct ext4_sb_info *sbi =
+			EXT4_SB(handle->h_transaction->t_journal->j_private);
+
+	/* Add the jce to transaction's private list */
+	jce->jce_func = func;
+	spin_lock(&sbi->s_md_lock);
+	list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list);
+	spin_unlock(&sbi->s_md_lock);
+}
+
+/**
+ * ext4_journal_callback_del: delete a registered callback
+ * @handle: active journal transaction handle on which callback was registered
+ * @jce: registered journal callback entry to unregister
+ */
+static inline void ext4_journal_callback_del(handle_t *handle,
+					     struct ext4_journal_cb_entry *jce)
+{
+	struct ext4_sb_info *sbi =
+			EXT4_SB(handle->h_transaction->t_journal->j_private);
+
+	spin_lock(&sbi->s_md_lock);
+	list_del_init(&jce->jce_list);
+	spin_unlock(&sbi->s_md_lock);
+}
+
 int
 ext4_mark_iloc_dirty(handle_t *handle,
 		     struct inode *inode,
@@ -261,43 +333,45 @@ static inline void ext4_update_inode_fsync_trans(handle_t *handle,
 /* super.c */
 int ext4_force_commit(struct super_block *sb);
 
-static inline int ext4_should_journal_data(struct inode *inode)
+/*
+ * Ext4 inode journal modes
+ */
+#define EXT4_INODE_JOURNAL_DATA_MODE	0x01 /* journal data mode */
+#define EXT4_INODE_ORDERED_DATA_MODE	0x02 /* ordered data mode */
+#define EXT4_INODE_WRITEBACK_DATA_MODE	0x04 /* writeback data mode */
+
+static inline int ext4_inode_journal_mode(struct inode *inode)
 {
 	if (EXT4_JOURNAL(inode) == NULL)
-		return 0;
-	if (!S_ISREG(inode->i_mode))
-		return 1;
-	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
-		return 1;
-	if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
-		return 1;
-	return 0;
+		return EXT4_INODE_WRITEBACK_DATA_MODE;	/* writeback */
+	/* We do not support data journalling with delayed allocation */
+	if (!S_ISREG(inode->i_mode) ||
+	    test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+		return EXT4_INODE_JOURNAL_DATA_MODE;	/* journal data */
+	if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
+	    !test_opt(inode->i_sb, DELALLOC))
+		return EXT4_INODE_JOURNAL_DATA_MODE;	/* journal data */
+	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+		return EXT4_INODE_ORDERED_DATA_MODE;	/* ordered */
+	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+		return EXT4_INODE_WRITEBACK_DATA_MODE;	/* writeback */
+	else
+		BUG();
+}
+
+static inline int ext4_should_journal_data(struct inode *inode)
+{
+	return ext4_inode_journal_mode(inode) & EXT4_INODE_JOURNAL_DATA_MODE;
 }
 
 static inline int ext4_should_order_data(struct inode *inode)
 {
-	if (EXT4_JOURNAL(inode) == NULL)
-		return 0;
-	if (!S_ISREG(inode->i_mode))
-		return 0;
-	if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
-		return 0;
-	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
-		return 1;
-	return 0;
+	return ext4_inode_journal_mode(inode) & EXT4_INODE_ORDERED_DATA_MODE;
 }
 
 static inline int ext4_should_writeback_data(struct inode *inode)
 {
-	if (EXT4_JOURNAL(inode) == NULL)
-		return 1;
-	if (!S_ISREG(inode->i_mode))
-		return 0;
-	if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA))
-		return 0;
-	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
-		return 1;
-	return 0;
+	return ext4_inode_journal_mode(inode) & EXT4_INODE_WRITEBACK_DATA_MODE;
 }
 
 /*
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 25d8c97..b268599 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -92,6 +92,16 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
 	return EXT4_INODES_PER_GROUP(sb);
 }
 
+void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate)
+{
+	if (uptodate) {
+		set_buffer_uptodate(bh);
+		set_bitmap_uptodate(bh);
+	}
+	unlock_buffer(bh);
+	put_bh(bh);
+}
+
 /*
  * Read the inode allocation bitmap for a given block_group, reading
  * into the specified slot in the superblock's bitmap cache.
@@ -147,18 +157,18 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
 		return bh;
 	}
 	/*
-	 * submit the buffer_head for read. We can
-	 * safely mark the bitmap as uptodate now.
-	 * We do it here so the bitmap uptodate bit
-	 * get set with buffer lock held.
+	 * submit the buffer_head for reading
 	 */
 	trace_ext4_load_inode_bitmap(sb, block_group);
-	set_bitmap_uptodate(bh);
-	if (bh_submit_read(bh) < 0) {
+	bh->b_end_io = ext4_end_bitmap_read;
+	get_bh(bh);
+	submit_bh(READ, bh);
+	wait_on_buffer(bh);
+	if (!buffer_uptodate(bh)) {
 		put_bh(bh);
 		ext4_error(sb, "Cannot read inode bitmap - "
-			    "block_group = %u, inode_bitmap = %llu",
-			    block_group, bitmap_blk);
+			   "block_group = %u, inode_bitmap = %llu",
+			   block_group, bitmap_blk);
 		return NULL;
 	}
 	return bh;
@@ -593,94 +603,6 @@ static int find_group_other(struct super_block *sb, struct inode *parent,
 }
 
 /*
- * claim the inode from the inode bitmap. If the group
- * is uninit we need to take the groups's ext4_group_lock
- * and clear the uninit flag. The inode bitmap update
- * and group desc uninit flag clear should be done
- * after holding ext4_group_lock so that ext4_read_inode_bitmap
- * doesn't race with the ext4_claim_inode
- */
-static int ext4_claim_inode(struct super_block *sb,
-			struct buffer_head *inode_bitmap_bh,
-			unsigned long ino, ext4_group_t group, umode_t mode)
-{
-	int free = 0, retval = 0, count;
-	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	struct ext4_group_info *grp = ext4_get_group_info(sb, group);
-	struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
-
-	/*
-	 * We have to be sure that new inode allocation does not race with
-	 * inode table initialization, because otherwise we may end up
-	 * allocating and writing new inode right before sb_issue_zeroout
-	 * takes place and overwriting our new inode with zeroes. So we
-	 * take alloc_sem to prevent it.
-	 */
-	down_read(&grp->alloc_sem);
-	ext4_lock_group(sb, group);
-	if (ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data)) {
-		/* not a free inode */
-		retval = 1;
-		goto err_ret;
-	}
-	ino++;
-	if ((group == 0 && ino < EXT4_FIRST_INO(sb)) ||
-			ino > EXT4_INODES_PER_GROUP(sb)) {
-		ext4_unlock_group(sb, group);
-		up_read(&grp->alloc_sem);
-		ext4_error(sb, "reserved inode or inode > inodes count - "
-			   "block_group = %u, inode=%lu", group,
-			   ino + group * EXT4_INODES_PER_GROUP(sb));
-		return 1;
-	}
-	/* If we didn't allocate from within the initialized part of the inode
-	 * table then we need to initialize up to this inode. */
-	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
-
-		if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
-			gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
-			/* When marking the block group with
-			 * ~EXT4_BG_INODE_UNINIT we don't want to depend
-			 * on the value of bg_itable_unused even though
-			 * mke2fs could have initialized the same for us.
-			 * Instead we calculated the value below
-			 */
-
-			free = 0;
-		} else {
-			free = EXT4_INODES_PER_GROUP(sb) -
-				ext4_itable_unused_count(sb, gdp);
-		}
-
-		/*
-		 * Check the relative inode number against the last used
-		 * relative inode number in this group. if it is greater
-		 * we need to  update the bg_itable_unused count
-		 *
-		 */
-		if (ino > free)
-			ext4_itable_unused_set(sb, gdp,
-					(EXT4_INODES_PER_GROUP(sb) - ino));
-	}
-	count = ext4_free_inodes_count(sb, gdp) - 1;
-	ext4_free_inodes_set(sb, gdp, count);
-	if (S_ISDIR(mode)) {
-		count = ext4_used_dirs_count(sb, gdp) + 1;
-		ext4_used_dirs_set(sb, gdp, count);
-		if (sbi->s_log_groups_per_flex) {
-			ext4_group_t f = ext4_flex_group(sbi, group);
-
-			atomic_inc(&sbi->s_flex_groups[f].used_dirs);
-		}
-	}
-	gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
-err_ret:
-	ext4_unlock_group(sb, group);
-	up_read(&grp->alloc_sem);
-	return retval;
-}
-
-/*
  * There are two policies for allocating an inode.  If the new inode is
  * a directory, then a forward search is made for a block group with both
  * free space and a low directory-to-inode ratio; if that fails, then of
@@ -741,6 +663,11 @@ got_group:
 	if (ret2 == -1)
 		goto out;
 
+	/*
+	 * Normally we will only go through one pass of this loop,
+	 * unless we get unlucky and it turns out the group we selected
+	 * had its last inode grabbed by someone else.
+	 */
 	for (i = 0; i < ngroups; i++, ino = 0) {
 		err = -EIO;
 
@@ -757,51 +684,24 @@ repeat_in_this_group:
 		ino = ext4_find_next_zero_bit((unsigned long *)
 					      inode_bitmap_bh->b_data,
 					      EXT4_INODES_PER_GROUP(sb), ino);
-
-		if (ino < EXT4_INODES_PER_GROUP(sb)) {
-
-			BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
-			err = ext4_journal_get_write_access(handle,
-							    inode_bitmap_bh);
-			if (err)
-				goto fail;
-
-			BUFFER_TRACE(group_desc_bh, "get_write_access");
-			err = ext4_journal_get_write_access(handle,
-								group_desc_bh);
-			if (err)
-				goto fail;
-			if (!ext4_claim_inode(sb, inode_bitmap_bh,
-						ino, group, mode)) {
-				/* we won it */
-				BUFFER_TRACE(inode_bitmap_bh,
-					"call ext4_handle_dirty_metadata");
-				err = ext4_handle_dirty_metadata(handle,
-								 NULL,
-							inode_bitmap_bh);
-				if (err)
-					goto fail;
-				/* zero bit is inode number 1*/
-				ino++;
-				goto got;
-			}
-			/* we lost it */
-			ext4_handle_release_buffer(handle, inode_bitmap_bh);
-			ext4_handle_release_buffer(handle, group_desc_bh);
-
-			if (++ino < EXT4_INODES_PER_GROUP(sb))
-				goto repeat_in_this_group;
+		if (ino >= EXT4_INODES_PER_GROUP(sb)) {
+			if (++group == ngroups)
+				group = 0;
+			continue;
 		}
-
-		/*
-		 * This case is possible in concurrent environment.  It is very
-		 * rare.  We cannot repeat the find_group_xxx() call because
-		 * that will simply return the same blockgroup, because the
-		 * group descriptor metadata has not yet been updated.
-		 * So we just go onto the next blockgroup.
-		 */
-		if (++group == ngroups)
-			group = 0;
+		if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) {
+			ext4_error(sb, "reserved inode found cleared - "
+				   "inode=%lu", ino + 1);
+			continue;
+		}
+		ext4_lock_group(sb, group);
+		ret2 = ext4_test_and_set_bit(ino, inode_bitmap_bh->b_data);
+		ext4_unlock_group(sb, group);
+		ino++;		/* the inode bitmap is zero-based */
+		if (!ret2)
+			goto got; /* we grabbed the inode! */
+		if (ino < EXT4_INODES_PER_GROUP(sb))
+			goto repeat_in_this_group;
 	}
 	err = -ENOSPC;
 	goto out;
@@ -838,6 +738,59 @@ got:
 		if (err)
 			goto fail;
 	}
+
+	BUFFER_TRACE(inode_bitmap_bh, "get_write_access");
+	err = ext4_journal_get_write_access(handle, inode_bitmap_bh);
+	if (err)
+		goto fail;
+
+	BUFFER_TRACE(group_desc_bh, "get_write_access");
+	err = ext4_journal_get_write_access(handle, group_desc_bh);
+	if (err)
+		goto fail;
+
+	/* Update the relevant bg descriptor fields */
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		int free;
+		struct ext4_group_info *grp = ext4_get_group_info(sb, group);
+
+		down_read(&grp->alloc_sem); /* protect vs itable lazyinit */
+		ext4_lock_group(sb, group); /* while we modify the bg desc */
+		free = EXT4_INODES_PER_GROUP(sb) -
+			ext4_itable_unused_count(sb, gdp);
+		if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
+			gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT);
+			free = 0;
+		}
+		/*
+		 * Check the relative inode number against the last used
+		 * relative inode number in this group. if it is greater
+		 * we need to update the bg_itable_unused count
+		 */
+		if (ino > free)
+			ext4_itable_unused_set(sb, gdp,
+					(EXT4_INODES_PER_GROUP(sb) - ino));
+		up_read(&grp->alloc_sem);
+	}
+	ext4_free_inodes_set(sb, gdp, ext4_free_inodes_count(sb, gdp) - 1);
+	if (S_ISDIR(mode)) {
+		ext4_used_dirs_set(sb, gdp, ext4_used_dirs_count(sb, gdp) + 1);
+		if (sbi->s_log_groups_per_flex) {
+			ext4_group_t f = ext4_flex_group(sbi, group);
+
+			atomic_inc(&sbi->s_flex_groups[f].used_dirs);
+		}
+	}
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+		gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp);
+		ext4_unlock_group(sb, group);
+	}
+
+	BUFFER_TRACE(inode_bitmap_bh, "call ext4_handle_dirty_metadata");
+	err = ext4_handle_dirty_metadata(handle, NULL, inode_bitmap_bh);
+	if (err)
+		goto fail;
+
 	BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
 	err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
 	if (err)
@@ -1101,7 +1054,7 @@ unsigned long ext4_count_dirs(struct super_block * sb)
  * where it is called from on active part of filesystem is ext4lazyinit
  * thread, so we do not need any special locks, however we have to prevent
  * inode allocation from the current group, so we take alloc_sem lock, to
- * block ext4_claim_inode until we are finished.
+ * block ext4_new_inode() until we are finished.
  */
 int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
 				 int barrier)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index feaa82f..aafc626 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2482,13 +2482,14 @@ static int ext4_da_write_end(struct file *file,
 	int write_mode = (int)(unsigned long)fsdata;
 
 	if (write_mode == FALL_BACK_TO_NONDELALLOC) {
-		if (ext4_should_order_data(inode)) {
+		switch (ext4_inode_journal_mode(inode)) {
+		case EXT4_INODE_ORDERED_DATA_MODE:
 			return ext4_ordered_write_end(file, mapping, pos,
 					len, copied, page, fsdata);
-		} else if (ext4_should_writeback_data(inode)) {
+		case EXT4_INODE_WRITEBACK_DATA_MODE:
 			return ext4_writeback_write_end(file, mapping, pos,
 					len, copied, page, fsdata);
-		} else {
+		default:
 			BUG();
 		}
 	}
@@ -2795,9 +2796,6 @@ out:
 
 	/* queue the work to convert unwritten extents to written */
 	queue_work(wq, &io_end->work);
-
-	/* XXX: probably should move into the real I/O completion handler */
-	inode_dio_done(inode);
 }
 
 static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
@@ -2921,9 +2919,12 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
 		iocb->private = NULL;
 		EXT4_I(inode)->cur_aio_dio = NULL;
 		if (!is_sync_kiocb(iocb)) {
-			iocb->private = ext4_init_io_end(inode, GFP_NOFS);
-			if (!iocb->private)
+			ext4_io_end_t *io_end =
+				ext4_init_io_end(inode, GFP_NOFS);
+			if (!io_end)
 				return -ENOMEM;
+			io_end->flag |= EXT4_IO_END_DIRECT;
+			iocb->private = io_end;
 			/*
 			 * we save the io structure for current async
 			 * direct IO, so that later ext4_map_blocks()
@@ -3086,18 +3087,25 @@ static const struct address_space_operations ext4_da_aops = {
 
 void ext4_set_aops(struct inode *inode)
 {
-	if (ext4_should_order_data(inode) &&
-		test_opt(inode->i_sb, DELALLOC))
-		inode->i_mapping->a_ops = &ext4_da_aops;
-	else if (ext4_should_order_data(inode))
-		inode->i_mapping->a_ops = &ext4_ordered_aops;
-	else if (ext4_should_writeback_data(inode) &&
-		 test_opt(inode->i_sb, DELALLOC))
-		inode->i_mapping->a_ops = &ext4_da_aops;
-	else if (ext4_should_writeback_data(inode))
-		inode->i_mapping->a_ops = &ext4_writeback_aops;
-	else
+	switch (ext4_inode_journal_mode(inode)) {
+	case EXT4_INODE_ORDERED_DATA_MODE:
+		if (test_opt(inode->i_sb, DELALLOC))
+			inode->i_mapping->a_ops = &ext4_da_aops;
+		else
+			inode->i_mapping->a_ops = &ext4_ordered_aops;
+		break;
+	case EXT4_INODE_WRITEBACK_DATA_MODE:
+		if (test_opt(inode->i_sb, DELALLOC))
+			inode->i_mapping->a_ops = &ext4_da_aops;
+		else
+			inode->i_mapping->a_ops = &ext4_writeback_aops;
+		break;
+	case EXT4_INODE_JOURNAL_DATA_MODE:
 		inode->i_mapping->a_ops = &ext4_journalled_aops;
+		break;
+	default:
+		BUG();
+	}
 }
 
 
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index cb990b2..7e6fab9 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -21,6 +21,7 @@
  * mballoc.c contains the multiblocks allocation routines
  */
 
+#include "ext4_jbd2.h"
 #include "mballoc.h"
 #include <linux/debugfs.h>
 #include <linux/slab.h>
@@ -339,7 +340,7 @@
  */
 static struct kmem_cache *ext4_pspace_cachep;
 static struct kmem_cache *ext4_ac_cachep;
-static struct kmem_cache *ext4_free_ext_cachep;
+static struct kmem_cache *ext4_free_data_cachep;
 
 /* We create slab caches for groupinfo data structures based on the
  * superblock block size.  There will be one per mounted filesystem for
@@ -357,7 +358,8 @@ static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
 					ext4_group_t group);
 static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
 						ext4_group_t group);
-static void release_blocks_on_commit(journal_t *journal, transaction_t *txn);
+static void ext4_free_data_callback(struct super_block *sb,
+				struct ext4_journal_cb_entry *jce, int rc);
 
 static inline void *mb_correct_addr_and_bit(int *bit, void *addr)
 {
@@ -425,7 +427,7 @@ static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
 {
 	char *bb;
 
-	BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
+	BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
 	BUG_ON(max == NULL);
 
 	if (order > e4b->bd_blkbits + 1) {
@@ -436,10 +438,10 @@ static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max)
 	/* at order 0 we see each particular block */
 	if (order == 0) {
 		*max = 1 << (e4b->bd_blkbits + 3);
-		return EXT4_MB_BITMAP(e4b);
+		return e4b->bd_bitmap;
 	}
 
-	bb = EXT4_MB_BUDDY(e4b) + EXT4_SB(e4b->bd_sb)->s_mb_offsets[order];
+	bb = e4b->bd_buddy + EXT4_SB(e4b->bd_sb)->s_mb_offsets[order];
 	*max = EXT4_SB(e4b->bd_sb)->s_mb_maxs[order];
 
 	return bb;
@@ -588,7 +590,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
 			for (j = 0; j < (1 << order); j++) {
 				k = (i * (1 << order)) + j;
 				MB_CHECK_ASSERT(
-					!mb_test_bit(k, EXT4_MB_BITMAP(e4b)));
+					!mb_test_bit(k, e4b->bd_bitmap));
 			}
 			count++;
 		}
@@ -782,7 +784,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 	int groups_per_page;
 	int err = 0;
 	int i;
-	ext4_group_t first_group;
+	ext4_group_t first_group, group;
 	int first_block;
 	struct super_block *sb;
 	struct buffer_head *bhs;
@@ -806,24 +808,23 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 
 	/* allocate buffer_heads to read bitmaps */
 	if (groups_per_page > 1) {
-		err = -ENOMEM;
 		i = sizeof(struct buffer_head *) * groups_per_page;
 		bh = kzalloc(i, GFP_NOFS);
-		if (bh == NULL)
+		if (bh == NULL) {
+			err = -ENOMEM;
 			goto out;
+		}
 	} else
 		bh = &bhs;
 
 	first_group = page->index * blocks_per_page / 2;
 
 	/* read all groups the page covers into the cache */
-	for (i = 0; i < groups_per_page; i++) {
-		struct ext4_group_desc *desc;
-
-		if (first_group + i >= ngroups)
+	for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
+		if (group >= ngroups)
 			break;
 
-		grinfo = ext4_get_group_info(sb, first_group + i);
+		grinfo = ext4_get_group_info(sb, group);
 		/*
 		 * If page is uptodate then we came here after online resize
 		 * which added some new uninitialized group info structs, so
@@ -834,69 +835,21 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 			bh[i] = NULL;
 			continue;
 		}
-
-		err = -EIO;
-		desc = ext4_get_group_desc(sb, first_group + i, NULL);
-		if (desc == NULL)
-			goto out;
-
-		err = -ENOMEM;
-		bh[i] = sb_getblk(sb, ext4_block_bitmap(sb, desc));
-		if (bh[i] == NULL)
+		if (!(bh[i] = ext4_read_block_bitmap_nowait(sb, group))) {
+			err = -ENOMEM;
 			goto out;
-
-		if (bitmap_uptodate(bh[i]))
-			continue;
-
-		lock_buffer(bh[i]);
-		if (bitmap_uptodate(bh[i])) {
-			unlock_buffer(bh[i]);
-			continue;
-		}
-		ext4_lock_group(sb, first_group + i);
-		if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
-			ext4_init_block_bitmap(sb, bh[i],
-						first_group + i, desc);
-			set_bitmap_uptodate(bh[i]);
-			set_buffer_uptodate(bh[i]);
-			ext4_unlock_group(sb, first_group + i);
-			unlock_buffer(bh[i]);
-			continue;
-		}
-		ext4_unlock_group(sb, first_group + i);
-		if (buffer_uptodate(bh[i])) {
-			/*
-			 * if not uninit if bh is uptodate,
-			 * bitmap is also uptodate
-			 */
-			set_bitmap_uptodate(bh[i]);
-			unlock_buffer(bh[i]);
-			continue;
 		}
-		get_bh(bh[i]);
-		/*
-		 * submit the buffer_head for read. We can
-		 * safely mark the bitmap as uptodate now.
-		 * We do it here so the bitmap uptodate bit
-		 * get set with buffer lock held.
-		 */
-		set_bitmap_uptodate(bh[i]);
-		bh[i]->b_end_io = end_buffer_read_sync;
-		submit_bh(READ, bh[i]);
-		mb_debug(1, "read bitmap for group %u\n", first_group + i);
+		mb_debug(1, "read bitmap for group %u\n", group);
 	}
 
 	/* wait for I/O completion */
-	for (i = 0; i < groups_per_page; i++)
-		if (bh[i])
-			wait_on_buffer(bh[i]);
-
-	err = -EIO;
-	for (i = 0; i < groups_per_page; i++)
-		if (bh[i] && !buffer_uptodate(bh[i]))
+	for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
+		if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i])) {
+			err = -EIO;
 			goto out;
+		}
+	}
 
-	err = 0;
 	first_block = page->index * blocks_per_page;
 	for (i = 0; i < blocks_per_page; i++) {
 		int group;
@@ -1250,10 +1203,10 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
 	int order = 1;
 	void *bb;
 
-	BUG_ON(EXT4_MB_BITMAP(e4b) == EXT4_MB_BUDDY(e4b));
+	BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
 	BUG_ON(block >= (1 << (e4b->bd_blkbits + 3)));
 
-	bb = EXT4_MB_BUDDY(e4b);
+	bb = e4b->bd_buddy;
 	while (order <= e4b->bd_blkbits + 1) {
 		block = block >> 1;
 		if (!mb_test_bit(block, bb)) {
@@ -1323,9 +1276,9 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
 
 	/* let's maintain fragments counter */
 	if (first != 0)
-		block = !mb_test_bit(first - 1, EXT4_MB_BITMAP(e4b));
+		block = !mb_test_bit(first - 1, e4b->bd_bitmap);
 	if (first + count < EXT4_SB(sb)->s_mb_maxs[0])
-		max = !mb_test_bit(first + count, EXT4_MB_BITMAP(e4b));
+		max = !mb_test_bit(first + count, e4b->bd_bitmap);
 	if (block && max)
 		e4b->bd_info->bb_fragments--;
 	else if (!block && !max)
@@ -1336,7 +1289,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
 		block = first++;
 		order = 0;
 
-		if (!mb_test_bit(block, EXT4_MB_BITMAP(e4b))) {
+		if (!mb_test_bit(block, e4b->bd_bitmap)) {
 			ext4_fsblk_t blocknr;
 
 			blocknr = ext4_group_first_block_no(sb, e4b->bd_group);
@@ -1347,7 +1300,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
 					      "freeing already freed block "
 					      "(bit %u)", block);
 		}
-		mb_clear_bit(block, EXT4_MB_BITMAP(e4b));
+		mb_clear_bit(block, e4b->bd_bitmap);
 		e4b->bd_info->bb_counters[order]++;
 
 		/* start of the buddy */
@@ -1429,7 +1382,7 @@ static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
 			break;
 
 		next = (block + 1) * (1 << order);
-		if (mb_test_bit(next, EXT4_MB_BITMAP(e4b)))
+		if (mb_test_bit(next, e4b->bd_bitmap))
 			break;
 
 		order = mb_find_order_for_block(e4b, next);
@@ -1466,9 +1419,9 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
 
 	/* let's maintain fragments counter */
 	if (start != 0)
-		mlen = !mb_test_bit(start - 1, EXT4_MB_BITMAP(e4b));
+		mlen = !mb_test_bit(start - 1, e4b->bd_bitmap);
 	if (start + len < EXT4_SB(e4b->bd_sb)->s_mb_maxs[0])
-		max = !mb_test_bit(start + len, EXT4_MB_BITMAP(e4b));
+		max = !mb_test_bit(start + len, e4b->bd_bitmap);
 	if (mlen && max)
 		e4b->bd_info->bb_fragments++;
 	else if (!mlen && !max)
@@ -1511,7 +1464,7 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex)
 	}
 	mb_set_largest_free_order(e4b->bd_sb, e4b->bd_info);
 
-	ext4_set_bits(EXT4_MB_BITMAP(e4b), ex->fe_start, len0);
+	ext4_set_bits(e4b->bd_bitmap, ex->fe_start, len0);
 	mb_check_buddy(e4b);
 
 	return ret;
@@ -1810,7 +1763,7 @@ void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
 					struct ext4_buddy *e4b)
 {
 	struct super_block *sb = ac->ac_sb;
-	void *bitmap = EXT4_MB_BITMAP(e4b);
+	void *bitmap = e4b->bd_bitmap;
 	struct ext4_free_extent ex;
 	int i;
 	int free;
@@ -1870,7 +1823,7 @@ void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
 {
 	struct super_block *sb = ac->ac_sb;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	void *bitmap = EXT4_MB_BITMAP(e4b);
+	void *bitmap = e4b->bd_bitmap;
 	struct ext4_free_extent ex;
 	ext4_fsblk_t first_group_block;
 	ext4_fsblk_t a;
@@ -2522,9 +2475,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
 		proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
 				 &ext4_mb_seq_groups_fops, sb);
 
-	if (sbi->s_journal)
-		sbi->s_journal->j_commit_callback = release_blocks_on_commit;
-
 	return 0;
 
 out_free_locality_groups:
@@ -2637,58 +2587,55 @@ static inline int ext4_issue_discard(struct super_block *sb,
  * This function is called by the jbd2 layer once the commit has finished,
  * so we know we can free the blocks that were released with that commit.
  */
-static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
+static void ext4_free_data_callback(struct super_block *sb,
+				    struct ext4_journal_cb_entry *jce,
+				    int rc)
 {
-	struct super_block *sb = journal->j_private;
+	struct ext4_free_data *entry = (struct ext4_free_data *)jce;
 	struct ext4_buddy e4b;
 	struct ext4_group_info *db;
 	int err, count = 0, count2 = 0;
-	struct ext4_free_data *entry;
-	struct list_head *l, *ltmp;
 
-	list_for_each_safe(l, ltmp, &txn->t_private_list) {
-		entry = list_entry(l, struct ext4_free_data, list);
+	mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
+		 entry->efd_count, entry->efd_group, entry);
 
-		mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
-			 entry->count, entry->group, entry);
+	if (test_opt(sb, DISCARD))
+		ext4_issue_discard(sb, entry->efd_group,
+				   entry->efd_start_cluster, entry->efd_count);
 
-		if (test_opt(sb, DISCARD))
-			ext4_issue_discard(sb, entry->group,
-					   entry->start_cluster, entry->count);
+	err = ext4_mb_load_buddy(sb, entry->efd_group, &e4b);
+	/* we expect to find existing buddy because it's pinned */
+	BUG_ON(err != 0);
 
-		err = ext4_mb_load_buddy(sb, entry->group, &e4b);
-		/* we expect to find existing buddy because it's pinned */
-		BUG_ON(err != 0);
 
-		db = e4b.bd_info;
-		/* there are blocks to put in buddy to make them really free */
-		count += entry->count;
-		count2++;
-		ext4_lock_group(sb, entry->group);
-		/* Take it out of per group rb tree */
-		rb_erase(&entry->node, &(db->bb_free_root));
-		mb_free_blocks(NULL, &e4b, entry->start_cluster, entry->count);
+	db = e4b.bd_info;
+	/* there are blocks to put in buddy to make them really free */
+	count += entry->efd_count;
+	count2++;
+	ext4_lock_group(sb, entry->efd_group);
+	/* Take it out of per group rb tree */
+	rb_erase(&entry->efd_node, &(db->bb_free_root));
+	mb_free_blocks(NULL, &e4b, entry->efd_start_cluster, entry->efd_count);
 
-		/*
-		 * Clear the trimmed flag for the group so that the next
-		 * ext4_trim_fs can trim it.
-		 * If the volume is mounted with -o discard, online discard
-		 * is supported and the free blocks will be trimmed online.
-		 */
-		if (!test_opt(sb, DISCARD))
-			EXT4_MB_GRP_CLEAR_TRIMMED(db);
+	/*
+	 * Clear the trimmed flag for the group so that the next
+	 * ext4_trim_fs can trim it.
+	 * If the volume is mounted with -o discard, online discard
+	 * is supported and the free blocks will be trimmed online.
+	 */
+	if (!test_opt(sb, DISCARD))
+		EXT4_MB_GRP_CLEAR_TRIMMED(db);
 
-		if (!db->bb_free_root.rb_node) {
-			/* No more items in the per group rb tree
-			 * balance refcounts from ext4_mb_free_metadata()
-			 */
-			page_cache_release(e4b.bd_buddy_page);
-			page_cache_release(e4b.bd_bitmap_page);
-		}
-		ext4_unlock_group(sb, entry->group);
-		kmem_cache_free(ext4_free_ext_cachep, entry);
-		ext4_mb_unload_buddy(&e4b);
+	if (!db->bb_free_root.rb_node) {
+		/* No more items in the per group rb tree
+		 * balance refcounts from ext4_mb_free_metadata()
+		 */
+		page_cache_release(e4b.bd_buddy_page);
+		page_cache_release(e4b.bd_bitmap_page);
 	}
+	ext4_unlock_group(sb, entry->efd_group);
+	kmem_cache_free(ext4_free_data_cachep, entry);
+	ext4_mb_unload_buddy(&e4b);
 
 	mb_debug(1, "freed %u blocks in %u structures\n", count, count2);
 }
@@ -2741,9 +2688,9 @@ int __init ext4_init_mballoc(void)
 		return -ENOMEM;
 	}
 
-	ext4_free_ext_cachep = KMEM_CACHE(ext4_free_data,
-					  SLAB_RECLAIM_ACCOUNT);
-	if (ext4_free_ext_cachep == NULL) {
+	ext4_free_data_cachep = KMEM_CACHE(ext4_free_data,
+					   SLAB_RECLAIM_ACCOUNT);
+	if (ext4_free_data_cachep == NULL) {
 		kmem_cache_destroy(ext4_pspace_cachep);
 		kmem_cache_destroy(ext4_ac_cachep);
 		return -ENOMEM;
@@ -2761,7 +2708,7 @@ void ext4_exit_mballoc(void)
 	rcu_barrier();
 	kmem_cache_destroy(ext4_pspace_cachep);
 	kmem_cache_destroy(ext4_ac_cachep);
-	kmem_cache_destroy(ext4_free_ext_cachep);
+	kmem_cache_destroy(ext4_free_data_cachep);
 	ext4_groupinfo_destroy_slabs();
 	ext4_remove_debugfs_entry();
 }
@@ -2911,7 +2858,8 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
 	struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
 	int bsbits, max;
 	ext4_lblk_t end;
-	loff_t size, orig_size, start_off;
+	loff_t size, start_off;
+	loff_t orig_size __maybe_unused;
 	ext4_lblk_t start;
 	struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
 	struct ext4_prealloc_space *pa;
@@ -3321,8 +3269,8 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
 	n = rb_first(&(grp->bb_free_root));
 
 	while (n) {
-		entry = rb_entry(n, struct ext4_free_data, node);
-		ext4_set_bits(bitmap, entry->start_cluster, entry->count);
+		entry = rb_entry(n, struct ext4_free_data, efd_node);
+		ext4_set_bits(bitmap, entry->efd_start_cluster, entry->efd_count);
 		n = rb_next(n);
 	}
 	return;
@@ -4428,9 +4376,9 @@ out:
 static int can_merge(struct ext4_free_data *entry1,
 			struct ext4_free_data *entry2)
 {
-	if ((entry1->t_tid == entry2->t_tid) &&
-	    (entry1->group == entry2->group) &&
-	    ((entry1->start_cluster + entry1->count) == entry2->start_cluster))
+	if ((entry1->efd_tid == entry2->efd_tid) &&
+	    (entry1->efd_group == entry2->efd_group) &&
+	    ((entry1->efd_start_cluster + entry1->efd_count) == entry2->efd_start_cluster))
 		return 1;
 	return 0;
 }
@@ -4452,8 +4400,8 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
 	BUG_ON(e4b->bd_bitmap_page == NULL);
 	BUG_ON(e4b->bd_buddy_page == NULL);
 
-	new_node = &new_entry->node;
-	cluster = new_entry->start_cluster;
+	new_node = &new_entry->efd_node;
+	cluster = new_entry->efd_start_cluster;
 
 	if (!*n) {
 		/* first free block exent. We need to
@@ -4466,10 +4414,10 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
 	}
 	while (*n) {
 		parent = *n;
-		entry = rb_entry(parent, struct ext4_free_data, node);
-		if (cluster < entry->start_cluster)
+		entry = rb_entry(parent, struct ext4_free_data, efd_node);
+		if (cluster < entry->efd_start_cluster)
 			n = &(*n)->rb_left;
-		else if (cluster >= (entry->start_cluster + entry->count))
+		else if (cluster >= (entry->efd_start_cluster + entry->efd_count))
 			n = &(*n)->rb_right;
 		else {
 			ext4_grp_locked_error(sb, group, 0,
@@ -4486,34 +4434,29 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
 	/* Now try to see the extent can be merged to left and right */
 	node = rb_prev(new_node);
 	if (node) {
-		entry = rb_entry(node, struct ext4_free_data, node);
+		entry = rb_entry(node, struct ext4_free_data, efd_node);
 		if (can_merge(entry, new_entry)) {
-			new_entry->start_cluster = entry->start_cluster;
-			new_entry->count += entry->count;
+			new_entry->efd_start_cluster = entry->efd_start_cluster;
+			new_entry->efd_count += entry->efd_count;
 			rb_erase(node, &(db->bb_free_root));
-			spin_lock(&sbi->s_md_lock);
-			list_del(&entry->list);
-			spin_unlock(&sbi->s_md_lock);
-			kmem_cache_free(ext4_free_ext_cachep, entry);
+			ext4_journal_callback_del(handle, &entry->efd_jce);
+			kmem_cache_free(ext4_free_data_cachep, entry);
 		}
 	}
 
 	node = rb_next(new_node);
 	if (node) {
-		entry = rb_entry(node, struct ext4_free_data, node);
+		entry = rb_entry(node, struct ext4_free_data, efd_node);
 		if (can_merge(new_entry, entry)) {
-			new_entry->count += entry->count;
+			new_entry->efd_count += entry->efd_count;
 			rb_erase(node, &(db->bb_free_root));
-			spin_lock(&sbi->s_md_lock);
-			list_del(&entry->list);
-			spin_unlock(&sbi->s_md_lock);
-			kmem_cache_free(ext4_free_ext_cachep, entry);
+			ext4_journal_callback_del(handle, &entry->efd_jce);
+			kmem_cache_free(ext4_free_data_cachep, entry);
 		}
 	}
 	/* Add the extent to transaction's private list */
-	spin_lock(&sbi->s_md_lock);
-	list_add(&new_entry->list, &handle->h_transaction->t_private_list);
-	spin_unlock(&sbi->s_md_lock);
+	ext4_journal_callback_add(handle, ext4_free_data_callback,
+				  &new_entry->efd_jce);
 	return 0;
 }
 
@@ -4691,15 +4634,15 @@ do_more:
 		 * blocks being freed are metadata. these blocks shouldn't
 		 * be used until this transaction is committed
 		 */
-		new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+		new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
 		if (!new_entry) {
 			err = -ENOMEM;
 			goto error_return;
 		}
-		new_entry->start_cluster = bit;
-		new_entry->group  = block_group;
-		new_entry->count = count_clusters;
-		new_entry->t_tid = handle->h_transaction->t_tid;
+		new_entry->efd_start_cluster = bit;
+		new_entry->efd_group = block_group;
+		new_entry->efd_count = count_clusters;
+		new_entry->efd_tid = handle->h_transaction->t_tid;
 
 		ext4_lock_group(sb, block_group);
 		mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index 47705f3..c070618 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -96,21 +96,23 @@ extern u8 mb_enable_debug;
 
 
 struct ext4_free_data {
-	/* this links the free block information from group_info */
-	struct rb_node node;
+	/* MUST be the first member */
+	struct ext4_journal_cb_entry	efd_jce;
+
+	/* ext4_free_data private data starts from here */
 
-	/* this links the free block information from ext4_sb_info */
-	struct list_head list;
+	/* this links the free block information from group_info */
+	struct rb_node			efd_node;
 
 	/* group which free block extent belongs */
-	ext4_group_t group;
+	ext4_group_t			efd_group;
 
 	/* free block extent */
-	ext4_grpblk_t start_cluster;
-	ext4_grpblk_t count;
+	ext4_grpblk_t			efd_start_cluster;
+	ext4_grpblk_t			efd_count;
 
 	/* transaction which freed this extent */
-	tid_t	t_tid;
+	tid_t				efd_tid;
 };
 
 struct ext4_prealloc_space {
@@ -210,8 +212,6 @@ struct ext4_buddy {
 	__u16 bd_blkbits;
 	ext4_group_t bd_group;
 };
-#define EXT4_MB_BITMAP(e4b)	((e4b)->bd_bitmap)
-#define EXT4_MB_BUDDY(e4b)	((e4b)->bd_buddy)
 
 static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
 					struct ext4_free_extent *fex)
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index e7d6bb0..f39f80f 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -471,7 +471,7 @@ int ext4_ext_migrate(struct inode *inode)
 	tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode,
 				   S_IFREG, NULL, goal, owner);
 	if (IS_ERR(tmp_inode)) {
-		retval = PTR_ERR(inode);
+		retval = PTR_ERR(tmp_inode);
 		ext4_journal_stop(handle);
 		return retval;
 	}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2043f48..349d7b3 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -468,7 +468,7 @@ fail2:
 fail:
 	if (*err == ERR_BAD_DX_DIR)
 		ext4_warning(dir->i_sb,
-			     "Corrupt dir inode %ld, running e2fsck is "
+			     "Corrupt dir inode %lu, running e2fsck is "
 			     "recommended.", dir->i_ino);
 	return NULL;
 }
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 4758518..9e1b8eb 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -110,6 +110,8 @@ int ext4_end_io_nolock(ext4_io_end_t *io)
 	if (io->iocb)
 		aio_complete(io->iocb, io->result, 0);
 
+	if (io->flag & EXT4_IO_END_DIRECT)
+		inode_dio_done(inode);
 	/* Wake up anyone waiting on unwritten extent conversion */
 	if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
 		wake_up_all(ext4_ioend_wq(io->inode));
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index f9d948f..3fed79d 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1582,7 +1582,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 	ext4_fsblk_t o_blocks_count;
 	ext4_group_t o_group;
 	ext4_group_t n_group;
-	ext4_grpblk_t offset;
+	ext4_grpblk_t offset, add;
 	unsigned long n_desc_blocks;
 	unsigned long o_desc_blocks;
 	unsigned long desc_blocks;
@@ -1605,7 +1605,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 		return 0;
 
 	ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
-	ext4_get_group_no_and_offset(sb, o_blocks_count, &o_group, &offset);
+	ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
 
 	n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
 			EXT4_DESC_PER_BLOCK(sb);
@@ -1634,10 +1634,12 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 	}
 	brelse(bh);
 
-	if (offset != 0) {
-		/* extend the last group */
-		ext4_grpblk_t add;
-		add = EXT4_BLOCKS_PER_GROUP(sb) - offset;
+	/* extend the last group */
+	if (n_group == o_group)
+		add = n_blocks_count - o_blocks_count;
+	else
+		add = EXT4_BLOCKS_PER_GROUP(sb) - (offset + 1);
+	if (add > 0) {
 		err = ext4_group_extend_no_check(sb, o_blocks_count, add);
 		if (err)
 			goto out;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 502c61f..9c61a87 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -431,6 +431,22 @@ static int block_device_ejected(struct super_block *sb)
 	return bdi->dev == NULL;
 }
 
+static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
+{
+	struct super_block		*sb = journal->j_private;
+	struct ext4_sb_info		*sbi = EXT4_SB(sb);
+	int				error = is_journal_aborted(journal);
+	struct ext4_journal_cb_entry	*jce, *tmp;
+
+	spin_lock(&sbi->s_md_lock);
+	list_for_each_entry_safe(jce, tmp, &txn->t_private_list, jce_list) {
+		list_del_init(&jce->jce_list);
+		spin_unlock(&sbi->s_md_lock);
+		jce->jce_func(sb, jce, error);
+		spin_lock(&sbi->s_md_lock);
+	}
+	spin_unlock(&sbi->s_md_lock);
+}
 
 /* Deal with the reporting of failure conditions on a filesystem such as
  * inconsistencies detected or read IO failures.
@@ -1320,14 +1336,13 @@ enum {
 	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
 	Opt_auto_da_alloc, Opt_noauto_da_alloc, Opt_noload, Opt_nobh, Opt_bh,
 	Opt_commit, Opt_min_batch_time, Opt_max_batch_time,
-	Opt_journal_update, Opt_journal_dev,
-	Opt_journal_checksum, Opt_journal_async_commit,
+	Opt_journal_dev, Opt_journal_checksum, Opt_journal_async_commit,
 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
 	Opt_data_err_abort, Opt_data_err_ignore,
 	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
 	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
 	Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
-	Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
+	Opt_usrquota, Opt_grpquota, Opt_i_version,
 	Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
 	Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
 	Opt_inode_readahead_blks, Opt_journal_ioprio,
@@ -1363,7 +1378,6 @@ static const match_table_t tokens = {
 	{Opt_commit, "commit=%u"},
 	{Opt_min_batch_time, "min_batch_time=%u"},
 	{Opt_max_batch_time, "max_batch_time=%u"},
-	{Opt_journal_update, "journal=update"},
 	{Opt_journal_dev, "journal_dev=%u"},
 	{Opt_journal_checksum, "journal_checksum"},
 	{Opt_journal_async_commit, "journal_async_commit"},
@@ -1389,7 +1403,6 @@ static const match_table_t tokens = {
 	{Opt_nobarrier, "nobarrier"},
 	{Opt_i_version, "i_version"},
 	{Opt_stripe, "stripe=%u"},
-	{Opt_resize, "resize"},
 	{Opt_delalloc, "delalloc"},
 	{Opt_nodelalloc, "nodelalloc"},
 	{Opt_mblk_io_submit, "mblk_io_submit"},
@@ -1499,7 +1512,7 @@ static int clear_qf_name(struct super_block *sb, int qtype)
 static int parse_options(char *options, struct super_block *sb,
 			 unsigned long *journal_devnum,
 			 unsigned int *journal_ioprio,
-			 ext4_fsblk_t *n_blocks_count, int is_remount)
+			 int is_remount)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	char *p;
@@ -1613,19 +1626,6 @@ static int parse_options(char *options, struct super_block *sb,
 			ext4_msg(sb, KERN_ERR, "(no)acl options not supported");
 			break;
 #endif
-		case Opt_journal_update:
-			/* @@@ FIXME */
-			/* Eventually we will want to be able to create
-			   a journal file here.  For now, only allow the
-			   user to specify an existing inode to be the
-			   journal file. */
-			if (is_remount) {
-				ext4_msg(sb, KERN_ERR,
-					 "Cannot specify journal on remount");
-				return 0;
-			}
-			set_opt(sb, UPDATE_JOURNAL);
-			break;
 		case Opt_journal_dev:
 			if (is_remount) {
 				ext4_msg(sb, KERN_ERR,
@@ -1793,17 +1793,6 @@ set_qf_format:
 			break;
 		case Opt_ignore:
 			break;
-		case Opt_resize:
-			if (!is_remount) {
-				ext4_msg(sb, KERN_ERR,
-					"resize option only available "
-					"for remount");
-				return 0;
-			}
-			if (match_int(&args[0], &option) != 0)
-				return 0;
-			*n_blocks_count = option;
-			break;
 		case Opt_nobh:
 			ext4_msg(sb, KERN_WARNING,
 				 "Ignoring deprecated nobh option");
@@ -3240,13 +3229,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
 
 	if (!parse_options((char *) sbi->s_es->s_mount_opts, sb,
-			   &journal_devnum, &journal_ioprio, NULL, 0)) {
+			   &journal_devnum, &journal_ioprio, 0)) {
 		ext4_msg(sb, KERN_WARNING,
 			 "failed to parse options in superblock: %s",
 			 sbi->s_es->s_mount_opts);
 	}
 	if (!parse_options((char *) data, sb, &journal_devnum,
-			   &journal_ioprio, NULL, 0))
+			   &journal_ioprio, 0))
 		goto failed_mount;
 
 	if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
@@ -3694,6 +3683,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
 
+	sbi->s_journal->j_commit_callback = ext4_journal_commit_callback;
+
 	/*
 	 * The journal may have updated the bg summary counts, so we
 	 * need to update the global counters.
@@ -3735,9 +3726,8 @@ no_journal:
 		iput(root);
 		goto failed_mount4;
 	}
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
-		iput(root);
 		ext4_msg(sb, KERN_ERR, "get root dentry failed");
 		ret = -ENOMEM;
 		goto failed_mount4;
@@ -4091,15 +4081,6 @@ static int ext4_load_journal(struct super_block *sb,
 	if (!(journal->j_flags & JBD2_BARRIER))
 		ext4_msg(sb, KERN_INFO, "barriers disabled");
 
-	if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
-		err = jbd2_journal_update_format(journal);
-		if (err)  {
-			ext4_msg(sb, KERN_ERR, "error updating journal");
-			jbd2_journal_destroy(journal);
-			return err;
-		}
-	}
-
 	if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER))
 		err = jbd2_journal_wipe(journal, !really_read_only);
 	if (!err) {
@@ -4386,7 +4367,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 {
 	struct ext4_super_block *es;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	ext4_fsblk_t n_blocks_count = 0;
 	unsigned long old_sb_flags;
 	struct ext4_mount_options old_opts;
 	int enable_quota = 0;
@@ -4419,8 +4399,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	if (!parse_options(data, sb, NULL, &journal_ioprio,
-			   &n_blocks_count, 1)) {
+	if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) {
 		err = -EINVAL;
 		goto restore_opts;
 	}
@@ -4438,8 +4417,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 		set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
 	}
 
-	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
-		n_blocks_count > ext4_blocks_count(es)) {
+	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
 		if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) {
 			err = -EROFS;
 			goto restore_opts;
@@ -4514,8 +4492,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 			if (sbi->s_journal)
 				ext4_clear_journal_err(sb, es);
 			sbi->s_mount_state = le16_to_cpu(es->s_state);
-			if ((err = ext4_group_extend(sb, es, n_blocks_count)))
-				goto restore_opts;
 			if (!ext4_setup_super(sb, es, 0))
 				sb->s_flags &= ~MS_RDONLY;
 			if (EXT4_HAS_INCOMPAT_FEATURE(sb,
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 93a00d8..3369157 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -158,13 +158,10 @@ ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end)
 static inline int
 ext4_xattr_check_block(struct buffer_head *bh)
 {
-	int error;
-
 	if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
 	    BHDR(bh)->h_blocks != cpu_to_le32(1))
 		return -EIO;
-	error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
-	return error;
+	return ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
 }
 
 static inline int
@@ -487,18 +484,19 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
 		ext4_free_blocks(handle, inode, bh, 0, 1,
 				 EXT4_FREE_BLOCKS_METADATA |
 				 EXT4_FREE_BLOCKS_FORGET);
+		unlock_buffer(bh);
 	} else {
 		le32_add_cpu(&BHDR(bh)->h_refcount, -1);
+		if (ce)
+			mb_cache_entry_release(ce);
+		unlock_buffer(bh);
 		error = ext4_handle_dirty_metadata(handle, inode, bh);
 		if (IS_SYNC(inode))
 			ext4_handle_sync(handle);
 		dquot_free_block(inode, 1);
 		ea_bdebug(bh, "refcount now=%d; releasing",
 			  le32_to_cpu(BHDR(bh)->h_refcount));
-		if (ce)
-			mb_cache_entry_release(ce);
 	}
-	unlock_buffer(bh);
 out:
 	ext4_std_error(inode->i_sb, error);
 	return;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 3ab8410..21687e3 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1496,11 +1496,13 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
 	root_inode->i_ino = MSDOS_ROOT_INO;
 	root_inode->i_version = 1;
 	error = fat_read_root(root_inode);
-	if (error < 0)
+	if (error < 0) {
+		iput(root_inode);
 		goto out_fail;
+	}
 	error = -ENOMEM;
 	insert_inode_hash(root_inode);
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
 	if (!sb->s_root) {
 		fat_msg(sb, KERN_ERR, "get root inode failed");
 		goto out_fail;
@@ -1516,8 +1518,6 @@ out_invalid:
 out_fail:
 	if (fat_inode)
 		iput(fat_inode);
-	if (root_inode)
-		iput(root_inode);
 	unload_nls(sbi->nls_io);
 	unload_nls(sbi->nls_disk);
 	if (sbi->options.iocharset != fat_default_iocharset)
diff --git a/fs/file_table.c b/fs/file_table.c
index 20002e3..a305d9e 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -34,7 +34,6 @@ struct files_stat_struct files_stat = {
 	.max_files = NR_FILE
 };
 
-DECLARE_LGLOCK(files_lglock);
 DEFINE_LGLOCK(files_lglock);
 
 /* SLAB cache for file structures */
@@ -204,7 +203,7 @@ EXPORT_SYMBOL(alloc_file);
  * to write to @file, along with access to write through
  * its vfsmount.
  */
-void drop_file_write_access(struct file *file)
+static void drop_file_write_access(struct file *file)
 {
 	struct vfsmount *mnt = file->f_path.mnt;
 	struct dentry *dentry = file->f_path.dentry;
@@ -219,7 +218,6 @@ void drop_file_write_access(struct file *file)
 	mnt_drop_write(mnt);
 	file_release_write(file);
 }
-EXPORT_SYMBOL_GPL(drop_file_write_access);
 
 /* the real guts of fput() - releasing the last reference to file
  */
@@ -422,9 +420,9 @@ static inline void __file_sb_list_add(struct file *file, struct super_block *sb)
  */
 void file_sb_list_add(struct file *file, struct super_block *sb)
 {
-	lg_local_lock(files_lglock);
+	lg_local_lock(&files_lglock);
 	__file_sb_list_add(file, sb);
-	lg_local_unlock(files_lglock);
+	lg_local_unlock(&files_lglock);
 }
 
 /**
@@ -437,9 +435,9 @@ void file_sb_list_add(struct file *file, struct super_block *sb)
 void file_sb_list_del(struct file *file)
 {
 	if (!list_empty(&file->f_u.fu_list)) {
-		lg_local_lock_cpu(files_lglock, file_list_cpu(file));
+		lg_local_lock_cpu(&files_lglock, file_list_cpu(file));
 		list_del_init(&file->f_u.fu_list);
-		lg_local_unlock_cpu(files_lglock, file_list_cpu(file));
+		lg_local_unlock_cpu(&files_lglock, file_list_cpu(file));
 	}
 }
 
@@ -486,7 +484,7 @@ void mark_files_ro(struct super_block *sb)
 	struct file *f;
 
 retry:
-	lg_global_lock(files_lglock);
+	lg_global_lock(&files_lglock);
 	do_file_list_for_each_entry(sb, f) {
 		struct vfsmount *mnt;
 		if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
@@ -503,12 +501,12 @@ retry:
 		file_release_write(f);
 		mnt = mntget(f->f_path.mnt);
 		/* This can sleep, so we can't hold the spinlock. */
-		lg_global_unlock(files_lglock);
+		lg_global_unlock(&files_lglock);
 		mnt_drop_write(mnt);
 		mntput(mnt);
 		goto retry;
 	} while_file_list_for_each_entry;
-	lg_global_unlock(files_lglock);
+	lg_global_unlock(&files_lglock);
 }
 
 void __init files_init(unsigned long mempages)
@@ -526,6 +524,6 @@ void __init files_init(unsigned long mempages)
 	n = (mempages * (PAGE_SIZE / 1024)) / 10;
 	files_stat.max_files = max_t(unsigned long, n, NR_FILE);
 	files_defer_init();
-	lg_lock_init(files_lglock);
+	lg_lock_init(&files_lglock, "files_lglock");
 	percpu_counter_init(&nr_files, 0);
 } 
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 9d1c995..d4fabd2 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -224,9 +224,8 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 		ret = PTR_ERR(root);
 		goto out;
 	}
-	sbp->s_root = d_alloc_root(root);
+	sbp->s_root = d_make_root(root);
 	if (!sbp->s_root) {
-		iput(root);
 		printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
 		goto out_free_ilist;
 	}
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 3426521..fc75f01 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -48,6 +48,8 @@
 #include <linux/spinlock.h>
 #include <linux/stat.h>
 #include <linux/module.h>
+#include <linux/mman.h>
+#include <linux/pagemap.h>
 
 #include "fuse_i.h"
 
@@ -174,6 +176,419 @@ static long cuse_file_compat_ioctl(struct file *file, unsigned int cmd,
 	return fuse_do_ioctl(file, cmd, arg, flags);
 }
 
+struct fuse_dmmap_region {
+	u64 mapid;
+	u64 size;
+	pgoff_t nr_pages;
+	struct page **pages;
+	struct list_head list;
+	atomic_t ref;
+};
+
+/*
+ * fuse_dmmap_vm represents the result of a single mmap() call, which
+ * can be shared by multiple client vmas created by forking.
+ */
+struct fuse_dmmap_vm {
+	atomic_t open_count;
+	struct fuse_dmmap_region *region;
+};
+
+static void fuse_dmmap_region_put(struct fuse_conn *fc,
+				  struct fuse_dmmap_region *fdr)
+{
+	if (atomic_dec_and_lock(&fdr->ref, &fc->lock)) {
+		pgoff_t idx;
+
+		list_del(&fdr->list);
+		spin_unlock(&fc->lock);
+
+		for (idx = 0; idx < fdr->nr_pages; idx++)
+			if (fdr->pages[idx])
+				put_page(fdr->pages[idx]);
+
+		kfree(fdr->pages);
+		kfree(fdr);
+	}
+}
+
+static void fuse_dmmap_vm_open(struct vm_area_struct *vma)
+{
+	struct fuse_dmmap_vm *fdvm = vma->vm_private_data;
+
+	/* vma copied */
+	atomic_inc(&fdvm->open_count);
+}
+
+static void fuse_dmmap_vm_close(struct vm_area_struct *vma)
+{
+	struct fuse_dmmap_vm *fdvm = vma->vm_private_data;
+	struct fuse_file *ff = vma->vm_file->private_data;
+	struct fuse_conn *fc = ff->fc;
+	struct fuse_req *req;
+	struct fuse_munmap_in *inarg;
+
+	if (!atomic_dec_and_test(&fdvm->open_count))
+		return;
+	/*
+	 * Notify server that the mmap region has been unmapped.
+	 * Failing this might lead to resource leak in server, don't
+	 * fail.
+	 */
+	req = fuse_get_req_nofail(fc, vma->vm_file);
+	inarg = &req->misc.munmap_in;
+
+	inarg->fh = ff->fh;
+	inarg->mapid = fdvm->region->mapid;
+	inarg->size = fdvm->region->size;
+
+	req->in.h.opcode = FUSE_MUNMAP;
+	req->in.h.nodeid = ff->nodeid;
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(*inarg);
+	req->in.args[0].value = inarg;
+
+	fuse_request_send(fc, req);
+	fuse_dmmap_region_put(fc, fdvm->region);
+	kfree(fdvm);
+}
+
+static struct page *fuse_dmmap_find_or_create_page(struct fuse_conn *fc,
+					   struct fuse_dmmap_region *fdr,
+					   pgoff_t index)
+{
+	struct page *new_page = NULL;
+	struct page *page;
+
+	BUG_ON(index >= fdr->nr_pages);
+
+	spin_lock(&fc->lock);
+	page = fdr->pages[index];
+	if (!page) {
+		spin_unlock(&fc->lock);
+		/* need to allocate and install a new page */
+		new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
+		if (!new_page)
+			return NULL;
+
+		/* try to install, check whether someone else already did it */
+		spin_lock(&fc->lock);
+		page = fdr->pages[index];
+		if (!page) {
+			page = fdr->pages[index] = new_page;
+			new_page = NULL;
+		}
+	}
+	get_page(page);
+	spin_unlock(&fc->lock);
+
+	if (new_page)
+		put_page(new_page);
+
+	return page;
+}
+
+static int fuse_dmmap_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct fuse_dmmap_vm *fdvm = vma->vm_private_data;
+	struct fuse_dmmap_region *fdr = fdvm->region;
+	struct fuse_file *ff = vma->vm_file->private_data;
+	struct fuse_conn *fc = ff->fc;
+
+	if (vmf->pgoff >= fdr->nr_pages)
+		return VM_FAULT_SIGBUS;
+
+	vmf->page = fuse_dmmap_find_or_create_page(fc, fdr, vmf->pgoff);
+	if (!vmf->page)
+		return VM_FAULT_OOM;
+
+	return 0;
+}
+
+static const struct vm_operations_struct fuse_dmmap_vm_ops = {
+	.open		= fuse_dmmap_vm_open,
+	.close		= fuse_dmmap_vm_close,
+	.fault		= fuse_dmmap_vm_fault,
+};
+
+static struct fuse_dmmap_region *fuse_dmmap_find_locked(struct fuse_conn *fc,
+							u64 mapid)
+{
+	struct fuse_dmmap_region *curr;
+	struct fuse_dmmap_region *fdr = NULL;
+
+	list_for_each_entry(curr, &fc->dmmap_list, list) {
+		if (curr->mapid == mapid) {
+			fdr = curr;
+			atomic_inc(&fdr->ref);
+			break;
+		}
+	}
+
+	return fdr;
+}
+
+static struct fuse_dmmap_region *fuse_dmmap_find(struct fuse_conn *fc,
+						 u64 mapid)
+{
+	struct fuse_dmmap_region *fdr;
+
+	spin_lock(&fc->lock);
+	fdr = fuse_dmmap_find_locked(fc, mapid);
+	spin_unlock(&fc->lock);
+
+	return fdr;
+}
+
+static struct fuse_dmmap_region *fuse_dmmap_get(struct fuse_conn *fc,
+						u64 mapid, u64 size)
+{
+	struct fuse_dmmap_region *fdr;
+	pgoff_t nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	if ((loff_t) (nr_pages << PAGE_SHIFT) < size)
+		return ERR_PTR(-EIO);
+
+	fdr = fuse_dmmap_find(fc, mapid);
+	if (fdr) {
+		if (fdr->size != size) {
+			fuse_dmmap_region_put(fc, fdr);
+			return ERR_PTR(-EIO);
+		}
+	} else {
+		struct fuse_dmmap_region *tmp;
+
+		fdr = kzalloc(sizeof(struct fuse_dmmap_region), GFP_KERNEL);
+		if (!fdr)
+			return ERR_PTR(-ENOMEM);
+
+		atomic_set(&fdr->ref, 1);
+		fdr->mapid = mapid;
+		fdr->size = size;
+		fdr->nr_pages = nr_pages;
+
+		fdr->pages = kzalloc(sizeof(struct page *) * nr_pages,
+				     GFP_KERNEL);
+		if (!fdr->pages) {
+			kfree(fdr);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		spin_lock(&fc->lock);
+		tmp = fuse_dmmap_find_locked(fc, mapid);
+		if (tmp) {
+			kfree(fdr->pages);
+			kfree(fdr);
+			fdr = tmp;
+		} else {
+			list_add(&fdr->list, &fc->dmmap_list);
+		}
+		spin_unlock(&fc->lock);
+	}
+
+	return fdr;
+}
+
+static int cuse_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct fuse_file *ff = file->private_data;
+	struct fuse_conn *fc = ff->fc;
+	struct fuse_dmmap_vm *fdvm;
+	struct fuse_dmmap_region *fdr;
+	struct fuse_req *req = NULL;
+	struct fuse_mmap_in inarg;
+	struct fuse_mmap_out outarg;
+	int err;
+
+	if (fc->no_dmmap)
+		return -ENOSYS;
+
+	req = fuse_get_req(fc);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	/* ask server whether this mmap is okay and what the offset should be */
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.fh = ff->fh;
+	inarg.addr = vma->vm_start;
+	inarg.len = vma->vm_end - vma->vm_start;
+	inarg.prot = ((vma->vm_flags & VM_READ) ? PROT_READ : 0) |
+		     ((vma->vm_flags & VM_WRITE) ? PROT_WRITE : 0) |
+		     ((vma->vm_flags & VM_EXEC) ? PROT_EXEC : 0);
+	inarg.flags = ((vma->vm_flags & VM_GROWSDOWN) ? MAP_GROWSDOWN : 0) |
+		      ((vma->vm_flags & VM_DENYWRITE) ? MAP_DENYWRITE : 0) |
+		      ((vma->vm_flags & VM_EXECUTABLE) ? MAP_EXECUTABLE : 0) |
+		      ((vma->vm_flags & VM_LOCKED) ? MAP_LOCKED : 0);
+	inarg.offset = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
+
+	req->in.h.opcode = FUSE_MMAP;
+	req->in.h.nodeid = ff->nodeid;
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
+	req->out.numargs = 1;
+	req->out.args[0].size = sizeof(outarg);
+	req->out.args[0].value = &outarg;
+
+	fuse_request_send(fc, req);
+	err = req->out.h.error;
+	if (err) {
+		if (err == -ENOSYS)
+			fc->no_dmmap = 1;
+		goto free_req;
+	}
+
+	fdr = fuse_dmmap_get(fc, outarg.mapid, outarg.size);
+	err = PTR_ERR(fdr);
+	if (IS_ERR(fdr))
+		goto free_req;
+
+	err = -ENOMEM;
+	fdvm = kzalloc(sizeof(*fdvm), GFP_KERNEL);
+	if (!fdvm) {
+		fuse_dmmap_region_put(fc, fdr);
+		goto free_req;
+	}
+	atomic_set(&fdvm->open_count, 1);
+	fdvm->region = fdr;
+
+	vma->vm_ops = &fuse_dmmap_vm_ops;
+	vma->vm_private_data = fdvm;
+	vma->vm_flags |= VM_DONTEXPAND;		/* disallow expansion for now */
+	err = 0;
+
+free_req:
+	fuse_put_request(fc, req);
+	return err;
+}
+
+static int fuse_notify_store_to_dmmap(struct fuse_conn *fc,
+				      struct fuse_copy_state *cs,
+				      u64 nodeid, u32 size, u64 pos)
+{
+	struct fuse_dmmap_region *fdr;
+	pgoff_t index;
+	unsigned int off;
+	int err;
+
+	fdr = fuse_dmmap_find(fc, nodeid);
+	if (!fdr)
+		return -ENOENT;
+
+	index = pos >> PAGE_SHIFT;
+	off = pos & ~PAGE_MASK;
+	if (pos > fdr->size)
+		size = 0;
+	else if (size > fdr->size - pos)
+		size = fdr->size - pos;
+
+	while (size) {
+		struct page *page;
+		unsigned int this_num;
+
+		err = -ENOMEM;
+		page = fuse_dmmap_find_or_create_page(fc, fdr, index);
+		if (!page)
+			goto out_iput;
+
+		this_num = min_t(unsigned, size, PAGE_SIZE - off);
+		err = fuse_copy_page(cs, &page, off, this_num, 0);
+		put_page(page);
+
+		if (err)
+			goto out_iput;
+
+		size -= this_num;
+		off = 0;
+		index++;
+	}
+
+	err = 0;
+
+out_iput:
+	fuse_dmmap_region_put(fc, fdr);
+
+	return err;
+}
+
+static void fuse_retrieve_dmmap_end(struct fuse_conn *fc, struct fuse_req *req)
+{
+	release_pages(req->pages, req->num_pages, 0);
+}
+
+static int fuse_notify_retrieve_from_dmmap(struct fuse_conn *fc,
+				struct fuse_notify_retrieve_out *outarg)
+{
+	struct fuse_dmmap_region *fdr;
+	struct fuse_req *req;
+	pgoff_t index;
+	unsigned int num;
+	unsigned int offset;
+	size_t total_len = 0;
+	int err;
+
+	fdr = fuse_dmmap_find(fc, outarg->nodeid);
+	if (!fdr)
+		return -ENOENT;
+
+	req = fuse_get_req(fc);
+	err = PTR_ERR(req);
+	if (IS_ERR(req))
+		goto out_put_region;
+
+	offset = outarg->offset & ~PAGE_MASK;
+
+	req->in.h.opcode = FUSE_NOTIFY_REPLY;
+	req->in.h.nodeid = outarg->nodeid;
+	req->in.numargs = 2;
+	req->in.argpages = 1;
+	req->page_offset = offset;
+	req->end = fuse_retrieve_dmmap_end;
+
+	index = outarg->offset >> PAGE_SHIFT;
+	num = outarg->size;
+	if (outarg->offset > fdr->size)
+		num = 0;
+	else if (outarg->offset + num > fdr->size)
+		num = fdr->size - outarg->offset;
+
+	while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) {
+		struct page *page;
+		unsigned int this_num;
+
+		BUG_ON(index >= fdr->nr_pages);
+		spin_lock(&fc->lock);
+		page = fdr->pages[index];
+		if (!page)
+			page = ZERO_PAGE(0);
+		get_page(page);
+		spin_unlock(&fc->lock);
+
+		this_num = min_t(unsigned, num, PAGE_SIZE - offset);
+		req->pages[req->num_pages] = page;
+		req->num_pages++;
+
+		num -= this_num;
+		total_len += this_num;
+		index++;
+	}
+	req->misc.retrieve_in.offset = outarg->offset;
+	req->misc.retrieve_in.size = total_len;
+	req->in.args[0].size = sizeof(req->misc.retrieve_in);
+	req->in.args[0].value = &req->misc.retrieve_in;
+	req->in.args[1].size = total_len;
+
+	err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
+	if (err)
+		fuse_retrieve_dmmap_end(fc, req);
+
+out_put_region:
+	fuse_dmmap_region_put(fc, fdr);
+
+	return err;
+}
+
+
 static const struct file_operations cuse_frontend_fops = {
 	.owner			= THIS_MODULE,
 	.read			= cuse_read,
@@ -183,7 +598,8 @@ static const struct file_operations cuse_frontend_fops = {
 	.unlocked_ioctl		= cuse_file_ioctl,
 	.compat_ioctl		= cuse_file_compat_ioctl,
 	.poll			= fuse_file_poll,
-	.llseek		= noop_llseek,
+	.llseek			= noop_llseek,
+	.mmap			= cuse_mmap,
 };
 
 
@@ -461,6 +877,12 @@ static void cuse_fc_release(struct fuse_conn *fc)
 	kfree(cc);
 }
 
+static const struct fuse_conn_operations cuse_ops = {
+	.release = cuse_fc_release,
+	.notify_store = fuse_notify_store_to_dmmap,
+	.notify_retrieve = fuse_notify_retrieve_from_dmmap,
+};
+
 /**
  * cuse_channel_open - open method for /dev/cuse
  * @inode: inode for /dev/cuse
@@ -489,7 +911,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file)
 	fuse_conn_init(&cc->fc);
 
 	INIT_LIST_HEAD(&cc->list);
-	cc->fc.release = cuse_fc_release;
+	cc->fc.ops = &cuse_ops;
 
 	cc->fc.connected = 1;
 	cc->fc.blocked = 0;
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 5f3368a..f81a85b 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -201,6 +201,7 @@ struct fuse_req *fuse_get_req_nofail(struct fuse_conn *fc, struct file *file)
 	req->waiting = 1;
 	return req;
 }
+EXPORT_SYMBOL_GPL(fuse_get_req_nofail);
 
 void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req)
 {
@@ -463,8 +464,8 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
 }
 EXPORT_SYMBOL_GPL(fuse_request_send_background);
 
-static int fuse_request_send_notify_reply(struct fuse_conn *fc,
-					  struct fuse_req *req, u64 unique)
+int fuse_request_send_notify_reply(struct fuse_conn *fc,
+				   struct fuse_req *req, u64 unique)
 {
 	int err = -ENODEV;
 
@@ -479,6 +480,7 @@ static int fuse_request_send_notify_reply(struct fuse_conn *fc,
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(fuse_request_send_notify_reply);
 
 /*
  * Called under fc->lock
@@ -813,8 +815,8 @@ static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
  * Copy a page in the request to/from the userspace buffer.  Must be
  * done atomically
  */
-static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
-			  unsigned offset, unsigned count, int zeroing)
+int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
+		   unsigned offset, unsigned count, int zeroing)
 {
 	int err;
 	struct page *page = *pagep;
@@ -838,10 +840,10 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
 			}
 		}
 		if (page) {
-			void *mapaddr = kmap_atomic(page, KM_USER0);
+			void *mapaddr = kmap_atomic(page);
 			void *buf = mapaddr + offset;
 			offset += fuse_copy_do(cs, &buf, &count);
-			kunmap_atomic(mapaddr, KM_USER0);
+			kunmap_atomic(mapaddr);
 		} else
 			offset += fuse_copy_do(cs, NULL, &count);
 	}
@@ -849,6 +851,7 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
 		flush_dcache_page(page);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(fuse_copy_page);
 
 /* Copy pages in the request to/from userspace buffer */
 static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
@@ -1445,15 +1448,7 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
 			     struct fuse_copy_state *cs)
 {
 	struct fuse_notify_store_out outarg;
-	struct inode *inode;
-	struct address_space *mapping;
-	u64 nodeid;
 	int err;
-	pgoff_t index;
-	unsigned int offset;
-	unsigned int num;
-	loff_t file_size;
-	loff_t end;
 
 	err = -EINVAL;
 	if (size < sizeof(outarg))
@@ -1467,137 +1462,18 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
 	if (size - sizeof(outarg) != outarg.size)
 		goto out_finish;
 
-	nodeid = outarg.nodeid;
-
-	down_read(&fc->killsb);
+	err = fc->ops->notify_store(fc, cs, outarg.nodeid, outarg.size,
+				       outarg.offset);
 
-	err = -ENOENT;
-	if (!fc->sb)
-		goto out_up_killsb;
-
-	inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
-	if (!inode)
-		goto out_up_killsb;
-
-	mapping = inode->i_mapping;
-	index = outarg.offset >> PAGE_CACHE_SHIFT;
-	offset = outarg.offset & ~PAGE_CACHE_MASK;
-	file_size = i_size_read(inode);
-	end = outarg.offset + outarg.size;
-	if (end > file_size) {
-		file_size = end;
-		fuse_write_update_size(inode, file_size);
-	}
-
-	num = outarg.size;
-	while (num) {
-		struct page *page;
-		unsigned int this_num;
-
-		err = -ENOMEM;
-		page = find_or_create_page(mapping, index,
-					   mapping_gfp_mask(mapping));
-		if (!page)
-			goto out_iput;
-
-		this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset);
-		err = fuse_copy_page(cs, &page, offset, this_num, 0);
-		if (!err && offset == 0 && (num != 0 || file_size == end))
-			SetPageUptodate(page);
-		unlock_page(page);
-		page_cache_release(page);
-
-		if (err)
-			goto out_iput;
-
-		num -= this_num;
-		offset = 0;
-		index++;
-	}
-
-	err = 0;
-
-out_iput:
-	iput(inode);
-out_up_killsb:
-	up_read(&fc->killsb);
 out_finish:
 	fuse_copy_finish(cs);
 	return err;
 }
 
-static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req)
-{
-	release_pages(req->pages, req->num_pages, 0);
-}
-
-static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
-			 struct fuse_notify_retrieve_out *outarg)
-{
-	int err;
-	struct address_space *mapping = inode->i_mapping;
-	struct fuse_req *req;
-	pgoff_t index;
-	loff_t file_size;
-	unsigned int num;
-	unsigned int offset;
-	size_t total_len = 0;
-
-	req = fuse_get_req(fc);
-	if (IS_ERR(req))
-		return PTR_ERR(req);
-
-	offset = outarg->offset & ~PAGE_CACHE_MASK;
-
-	req->in.h.opcode = FUSE_NOTIFY_REPLY;
-	req->in.h.nodeid = outarg->nodeid;
-	req->in.numargs = 2;
-	req->in.argpages = 1;
-	req->page_offset = offset;
-	req->end = fuse_retrieve_end;
-
-	index = outarg->offset >> PAGE_CACHE_SHIFT;
-	file_size = i_size_read(inode);
-	num = outarg->size;
-	if (outarg->offset > file_size)
-		num = 0;
-	else if (outarg->offset + num > file_size)
-		num = file_size - outarg->offset;
-
-	while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) {
-		struct page *page;
-		unsigned int this_num;
-
-		page = find_get_page(mapping, index);
-		if (!page)
-			break;
-
-		this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset);
-		req->pages[req->num_pages] = page;
-		req->num_pages++;
-
-		num -= this_num;
-		total_len += this_num;
-		index++;
-	}
-	req->misc.retrieve_in.offset = outarg->offset;
-	req->misc.retrieve_in.size = total_len;
-	req->in.args[0].size = sizeof(req->misc.retrieve_in);
-	req->in.args[0].value = &req->misc.retrieve_in;
-	req->in.args[1].size = total_len;
-
-	err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
-	if (err)
-		fuse_retrieve_end(fc, req);
-
-	return err;
-}
-
 static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
 				struct fuse_copy_state *cs)
 {
 	struct fuse_notify_retrieve_out outarg;
-	struct inode *inode;
 	int err;
 
 	err = -EINVAL;
@@ -1610,18 +1486,7 @@ static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
 
 	fuse_copy_finish(cs);
 
-	down_read(&fc->killsb);
-	err = -ENOENT;
-	if (fc->sb) {
-		u64 nodeid = outarg.nodeid;
-
-		inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
-		if (inode) {
-			err = fuse_retrieve(fc, inode, &outarg);
-			iput(inode);
-		}
-	}
-	up_read(&fc->killsb);
+	err = fc->ops->notify_retrieve(fc, &outarg);
 
 	return err;
 
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 4a199fd..a841868 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1887,11 +1887,11 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
 		    in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
 			goto out;
 
-		vaddr = kmap_atomic(pages[0], KM_USER0);
+		vaddr = kmap_atomic(pages[0]);
 		err = fuse_copy_ioctl_iovec(fc, iov_page, vaddr,
 					    transferred, in_iovs + out_iovs,
 					    (flags & FUSE_IOCTL_COMPAT) != 0);
-		kunmap_atomic(vaddr, KM_USER0);
+		kunmap_atomic(vaddr);
 		if (err)
 			goto out;
 
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 572cefc..51b7cb1 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -285,6 +285,7 @@ struct fuse_req {
 		} write;
 		struct fuse_notify_retrieve_in retrieve_in;
 		struct fuse_lk_in lk_in;
+		struct fuse_munmap_in munmap_in;
 	} misc;
 
 	/** page vector */
@@ -312,6 +313,21 @@ struct fuse_req {
 	struct file *stolen_file;
 };
 
+struct fuse_copy_state;
+
+struct fuse_conn_operations {
+	/** Called on final put */
+	void (*release)(struct fuse_conn *);
+
+	/** Called to store data into a mapping */
+	int (*notify_store)(struct fuse_conn *, struct fuse_copy_state *,
+			    u64 nodeid, u32 size, u64 pos);
+
+	/** Called to retrieve data from a mapping */
+	int (*notify_retrieve)(struct fuse_conn *,
+			       struct fuse_notify_retrieve_out *);
+};
+
 /**
  * A Fuse connection.
  *
@@ -469,6 +485,9 @@ struct fuse_conn {
 	/** Is poll not implemented by fs? */
 	unsigned no_poll:1;
 
+	/** Is direct mmap not implemente by fs? */
+	unsigned no_dmmap:1;
+
 	/** Do multi-page cached writes */
 	unsigned big_writes:1;
 
@@ -511,14 +530,17 @@ struct fuse_conn {
 	/** Version counter for attribute changes */
 	u64 attr_version;
 
-	/** Called on final put */
-	void (*release)(struct fuse_conn *);
-
 	/** Super block for this connection. */
 	struct super_block *sb;
 
 	/** Read/write semaphore to hold when accessing sb. */
 	struct rw_semaphore killsb;
+
+	/** List of direct mmaps (currently CUSE only) */
+	struct list_head dmmap_list;
+
+	/** Operations that fuse and cuse can implement differently */
+	const struct fuse_conn_operations *ops;
 };
 
 static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
@@ -778,4 +800,11 @@ int fuse_dev_release(struct inode *inode, struct file *file);
 
 void fuse_write_update_size(struct inode *inode, loff_t pos);
 
+int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
+		   unsigned offset, unsigned count, int zeroing);
+
+int fuse_request_send_notify_reply(struct fuse_conn *fc,
+				   struct fuse_req *req, u64 unique);
+
+
 #endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 64cf8d0..559ab0f 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -541,6 +541,7 @@ void fuse_conn_init(struct fuse_conn *fc)
 	fc->blocked = 1;
 	fc->attr_version = 1;
 	get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
+	INIT_LIST_HEAD(&fc->dmmap_list);
 }
 EXPORT_SYMBOL_GPL(fuse_conn_init);
 
@@ -550,7 +551,7 @@ void fuse_conn_put(struct fuse_conn *fc)
 		if (fc->destroy_req)
 			fuse_request_free(fc->destroy_req);
 		mutex_destroy(&fc->inst_mutex);
-		fc->release(fc);
+		fc->ops->release(fc);
 	}
 }
 EXPORT_SYMBOL_GPL(fuse_conn_put);
@@ -914,6 +915,168 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
 	return 0;
 }
 
+static int fuse_notify_store_to_inode(struct fuse_conn *fc,
+				      struct fuse_copy_state *cs,
+				      u64 nodeid, u32 size, u64 pos)
+{
+	struct inode *inode;
+	struct address_space *mapping;
+	pgoff_t index;
+	unsigned int off;
+	loff_t file_size;
+	loff_t end;
+	int err;
+
+	down_read(&fc->killsb);
+
+	err = -ENOENT;
+	if (!fc->sb)
+		goto out_up_killsb;
+
+	inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
+	if (!inode)
+		goto out_up_killsb;
+
+	mapping = inode->i_mapping;
+	index = pos >> PAGE_CACHE_SHIFT;
+	off = pos & ~PAGE_CACHE_MASK;
+	file_size = i_size_read(inode);
+	end = pos + size;
+	if (end > file_size) {
+		file_size = end;
+		fuse_write_update_size(inode, file_size);
+	}
+
+	while (size) {
+		struct page *page;
+		unsigned int this_num;
+
+		err = -ENOMEM;
+		page = find_or_create_page(mapping, index,
+					   mapping_gfp_mask(mapping));
+		if (!page)
+			goto out_iput;
+
+		this_num = min_t(unsigned, size, PAGE_CACHE_SIZE - off);
+		err = fuse_copy_page(cs, &page, off, this_num, 0);
+		if (!err && off == 0 && (size != 0 || file_size == end))
+			SetPageUptodate(page);
+		unlock_page(page);
+		page_cache_release(page);
+
+		if (err)
+			goto out_iput;
+
+		size -= this_num;
+		off = 0;
+		index++;
+	}
+
+	err = 0;
+
+out_iput:
+	iput(inode);
+out_up_killsb:
+	up_read(&fc->killsb);
+
+	return err;
+}
+
+static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req)
+{
+	release_pages(req->pages, req->num_pages, 0);
+}
+
+static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
+			 struct fuse_notify_retrieve_out *outarg)
+{
+	int err;
+	struct address_space *mapping = inode->i_mapping;
+	struct fuse_req *req;
+	pgoff_t index;
+	loff_t file_size;
+	unsigned int num;
+	unsigned int offset;
+	size_t total_len = 0;
+
+	req = fuse_get_req(fc);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	offset = outarg->offset & ~PAGE_CACHE_MASK;
+
+	req->in.h.opcode = FUSE_NOTIFY_REPLY;
+	req->in.h.nodeid = outarg->nodeid;
+	req->in.numargs = 2;
+	req->in.argpages = 1;
+	req->page_offset = offset;
+	req->end = fuse_retrieve_end;
+
+	index = outarg->offset >> PAGE_CACHE_SHIFT;
+	file_size = i_size_read(inode);
+	num = outarg->size;
+	if (outarg->offset > file_size)
+		num = 0;
+	else if (outarg->offset + num > file_size)
+		num = file_size - outarg->offset;
+
+	while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) {
+		struct page *page;
+		unsigned int this_num;
+
+		page = find_get_page(mapping, index);
+		if (!page)
+			break;
+
+		this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset);
+		req->pages[req->num_pages] = page;
+		req->num_pages++;
+
+		num -= this_num;
+		total_len += this_num;
+		index++;
+	}
+	req->misc.retrieve_in.offset = outarg->offset;
+	req->misc.retrieve_in.size = total_len;
+	req->in.args[0].size = sizeof(req->misc.retrieve_in);
+	req->in.args[0].value = &req->misc.retrieve_in;
+	req->in.args[1].size = total_len;
+
+	err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
+	if (err)
+		fuse_retrieve_end(fc, req);
+
+	return err;
+}
+
+static int fuse_notify_retrieve_from_inode(struct fuse_conn *fc,
+				struct fuse_notify_retrieve_out *outarg)
+{
+	struct inode *inode;
+	int err;
+
+	down_read(&fc->killsb);
+	err = -ENOENT;
+	if (fc->sb) {
+		u64 nodeid = outarg->nodeid;
+
+		inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
+		if (inode) {
+			err = fuse_retrieve(fc, inode, outarg);
+			iput(inode);
+		}
+	}
+	up_read(&fc->killsb);
+
+	return err;
+}
+
+static const struct fuse_conn_operations fuse_default_ops = {
+	.release = fuse_free_conn,
+	.notify_store = fuse_notify_store_to_inode,
+	.notify_retrieve = fuse_notify_retrieve_from_inode,
+};
+
 static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct fuse_conn *fc;
@@ -977,7 +1140,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 		fc->dont_mask = 1;
 	sb->s_flags |= MS_POSIXACL;
 
-	fc->release = fuse_free_conn;
+	fc->ops = &fuse_default_ops;
 	fc->flags = d.flags;
 	fc->user_id = d.user_id;
 	fc->group_id = d.group_id;
@@ -988,14 +1151,9 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 
 	err = -ENOMEM;
 	root = fuse_get_root_inode(sb, d.rootmode);
-	if (!root)
+	root_dentry = d_make_root(root);
+	if (!root_dentry)
 		goto err_put_conn;
-
-	root_dentry = d_alloc_root(root);
-	if (!root_dentry) {
-		iput(root);
-		goto err_put_conn;
-	}
 	/* only now - we want root dentry with NULL ->d_op */
 	sb->s_d_op = &fuse_dentry_operations;
 
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 501e5cb..38b7a74 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -434,12 +434,12 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
 	if (error)
 		return error;
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	if (dsize > (dibh->b_size - sizeof(struct gfs2_dinode)))
 		dsize = (dibh->b_size - sizeof(struct gfs2_dinode));
 	memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
 	memset(kaddr + dsize, 0, PAGE_CACHE_SIZE - dsize);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	flush_dcache_page(page);
 	brelse(dibh);
 	SetPageUptodate(page);
@@ -542,9 +542,9 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
 		page = read_cache_page(mapping, index, __gfs2_readpage, NULL);
 		if (IS_ERR(page))
 			return PTR_ERR(page);
-		p = kmap_atomic(page, KM_USER0);
+		p = kmap_atomic(page);
 		memcpy(buf + copied, p + offset, amt);
-		kunmap_atomic(p, KM_USER0);
+		kunmap_atomic(p);
 		mark_page_accessed(page);
 		page_cache_release(page);
 		copied += amt;
@@ -788,11 +788,11 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
 	unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode);
 
 	BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memcpy(buf + pos, kaddr + pos, copied);
 	memset(kaddr + pos + copied, 0, len - copied);
 	flush_dcache_page(page);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (!PageUptodate(page))
 		SetPageUptodate(page);
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index c5fb359..52db4c4 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -313,6 +313,8 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		return gfs2_get_flags(filp, (u32 __user *)arg);
 	case FS_IOC_SETFLAGS:
 		return gfs2_set_flags(filp, (u32 __user *)arg);
+	case FITRIM:
+		return gfs2_fitrim(filp, (void __user *)arg);
 	}
 	return -ENOTTY;
 }
@@ -772,6 +774,11 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
 	if (bytes == 0)
 		bytes = sdp->sd_sb.sb_bsize;
 
+	error = gfs2_rindex_update(sdp);
+	if (error) {
+		fs_warn(sdp, "rindex update returns %d\n", error);
+		return error;
+	}
 	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
 	error = gfs2_glock_nq(&ip->i_gh);
 	if (unlikely(error))
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 376816f..dab2526 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -29,6 +29,7 @@
 #include <linux/rcupdate.h>
 #include <linux/rculist_bl.h>
 #include <linux/bit_spinlock.h>
+#include <linux/percpu.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -167,14 +168,19 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
 	spin_unlock(&lru_lock);
 }
 
-static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+static void __gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
 {
-	spin_lock(&lru_lock);
 	if (!list_empty(&gl->gl_lru)) {
 		list_del_init(&gl->gl_lru);
 		atomic_dec(&lru_count);
 		clear_bit(GLF_LRU, &gl->gl_flags);
 	}
+}
+
+static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+{
+	spin_lock(&lru_lock);
+	__gfs2_glock_remove_from_lru(gl);
 	spin_unlock(&lru_lock);
 }
 
@@ -217,11 +223,12 @@ void gfs2_glock_put(struct gfs2_glock *gl)
 	struct gfs2_sbd *sdp = gl->gl_sbd;
 	struct address_space *mapping = gfs2_glock2aspace(gl);
 
-	if (atomic_dec_and_test(&gl->gl_ref)) {
+	if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
+		__gfs2_glock_remove_from_lru(gl);
+		spin_unlock(&lru_lock);
 		spin_lock_bucket(gl->gl_hash);
 		hlist_bl_del_rcu(&gl->gl_list);
 		spin_unlock_bucket(gl->gl_hash);
-		gfs2_glock_remove_from_lru(gl);
 		GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
 		GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
 		trace_gfs2_glock_put(gl);
@@ -537,6 +544,11 @@ __acquires(&gl->gl_spin)
 		do_error(gl, 0); /* Fail queued try locks */
 	}
 	gl->gl_req = target;
+	set_bit(GLF_BLOCKING, &gl->gl_flags);
+	if ((gl->gl_req == LM_ST_UNLOCKED) ||
+	    (gl->gl_state == LM_ST_EXCLUSIVE) ||
+	    (lck_flags & (LM_FLAG_TRY|LM_FLAG_TRY_1CB)))
+		clear_bit(GLF_BLOCKING, &gl->gl_flags);
 	spin_unlock(&gl->gl_spin);
 	if (glops->go_xmote_th)
 		glops->go_xmote_th(gl);
@@ -738,6 +750,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
 		return -ENOMEM;
 
 	atomic_inc(&sdp->sd_glock_disposal);
+	gl->gl_sbd = sdp;
 	gl->gl_flags = 0;
 	gl->gl_name = name;
 	atomic_set(&gl->gl_ref, 1);
@@ -746,12 +759,17 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
 	gl->gl_demote_state = LM_ST_EXCLUSIVE;
 	gl->gl_hash = hash;
 	gl->gl_ops = glops;
-	snprintf(gl->gl_strname, GDLM_STRNAME_BYTES, "%8x%16llx", name.ln_type, (unsigned long long)number);
+	gl->gl_dstamp = ktime_set(0, 0);
+	preempt_disable();
+	/* We use the global stats to estimate the initial per-glock stats */
+	gl->gl_stats = this_cpu_ptr(sdp->sd_lkstats)->lkstats[glops->go_type];
+	preempt_enable();
+	gl->gl_stats.stats[GFS2_LKS_DCOUNT] = 0;
+	gl->gl_stats.stats[GFS2_LKS_QCOUNT] = 0;
 	memset(&gl->gl_lksb, 0, sizeof(struct dlm_lksb));
 	gl->gl_lksb.sb_lvbptr = gl->gl_lvb;
 	gl->gl_tchange = jiffies;
 	gl->gl_object = NULL;
-	gl->gl_sbd = sdp;
 	gl->gl_hold_time = GL_GLOCK_DFT_HOLD;
 	INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
 	INIT_WORK(&gl->gl_delete, delete_work_func);
@@ -993,6 +1011,8 @@ fail:
 	}
 	set_bit(GLF_QUEUED, &gl->gl_flags);
 	trace_gfs2_glock_queue(gh, 1);
+	gfs2_glstats_inc(gl, GFS2_LKS_QCOUNT);
+	gfs2_sbstats_inc(gl, GFS2_LKS_QCOUNT);
 	if (likely(insert_pt == NULL)) {
 		list_add_tail(&gh->gh_list, &gl->gl_holders);
 		if (unlikely(gh->gh_flags & LM_FLAG_PRIORITY))
@@ -1652,6 +1672,8 @@ static const char *gflags2str(char *buf, const struct gfs2_glock *gl)
 		*p++ = 'L';
 	if (gl->gl_object)
 		*p++ = 'o';
+	if (test_bit(GLF_BLOCKING, gflags))
+		*p++ = 'b';
 	*p = 0;
 	return buf;
 }
@@ -1708,8 +1730,78 @@ out:
 	return error;
 }
 
+static int gfs2_glstats_seq_show(struct seq_file *seq, void *iter_ptr)
+{
+	struct gfs2_glock *gl = iter_ptr;
+
+	seq_printf(seq, "G: n:%u/%llx rtt:%lld/%lld rttb:%lld/%lld irt:%lld/%lld dcnt: %lld qcnt: %lld\n",
+		   gl->gl_name.ln_type,
+		   (unsigned long long)gl->gl_name.ln_number,
+		   (long long)gl->gl_stats.stats[GFS2_LKS_SRTT],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_SRTTVAR],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_SRTTB],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_SRTTVARB],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_SIRT],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_SIRTVAR],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_DCOUNT],
+		   (long long)gl->gl_stats.stats[GFS2_LKS_QCOUNT]);
+	return 0;
+}
+
+static const char *gfs2_gltype[] = {
+	"type",
+	"reserved",
+	"nondisk",
+	"inode",
+	"rgrp",
+	"meta",
+	"iopen",
+	"flock",
+	"plock",
+	"quota",
+	"journal",
+};
+
+static const char *gfs2_stype[] = {
+	[GFS2_LKS_SRTT]		= "srtt",
+	[GFS2_LKS_SRTTVAR]	= "srttvar",
+	[GFS2_LKS_SRTTB]	= "srttb",
+	[GFS2_LKS_SRTTVARB]	= "srttvarb",
+	[GFS2_LKS_SIRT]		= "sirt",
+	[GFS2_LKS_SIRTVAR]	= "sirtvar",
+	[GFS2_LKS_DCOUNT]	= "dlm",
+	[GFS2_LKS_QCOUNT]	= "queue",
+};
+
+#define GFS2_NR_SBSTATS (ARRAY_SIZE(gfs2_gltype) * ARRAY_SIZE(gfs2_stype))
+
+static int gfs2_sbstats_seq_show(struct seq_file *seq, void *iter_ptr)
+{
+	struct gfs2_glock_iter *gi = seq->private;
+	struct gfs2_sbd *sdp = gi->sdp;
+	unsigned index = gi->hash >> 3;
+	unsigned subindex = gi->hash & 0x07;
+	s64 value;
+	int i;
+
+	if (index == 0 && subindex != 0)
+		return 0;
 
+	seq_printf(seq, "%-10s %8s:", gfs2_gltype[index],
+		   (index == 0) ? "cpu": gfs2_stype[subindex]);
 
+	for_each_possible_cpu(i) {
+                const struct gfs2_pcpu_lkstats *lkstats = per_cpu_ptr(sdp->sd_lkstats, i);
+		if (index == 0) {
+			value = i;
+		} else {
+			value = lkstats->lkstats[index - 1].stats[subindex];
+		}
+		seq_printf(seq, " %15lld", (long long)value);
+	}
+	seq_putc(seq, '\n');
+	return 0;
+}
 
 int __init gfs2_glock_init(void)
 {
@@ -1822,6 +1914,35 @@ static int gfs2_glock_seq_show(struct seq_file *seq, void *iter_ptr)
 	return dump_glock(seq, iter_ptr);
 }
 
+static void *gfs2_sbstats_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	struct gfs2_glock_iter *gi = seq->private;
+
+	gi->hash = *pos;
+	if (*pos >= GFS2_NR_SBSTATS)
+		return NULL;
+	preempt_disable();
+	return SEQ_START_TOKEN;
+}
+
+static void *gfs2_sbstats_seq_next(struct seq_file *seq, void *iter_ptr,
+				   loff_t *pos)
+{
+	struct gfs2_glock_iter *gi = seq->private;
+	(*pos)++;
+	gi->hash++;
+	if (gi->hash >= GFS2_NR_SBSTATS) {
+		preempt_enable();
+		return NULL;
+	}
+	return SEQ_START_TOKEN;
+}
+
+static void gfs2_sbstats_seq_stop(struct seq_file *seq, void *iter_ptr)
+{
+	preempt_enable();
+}
+
 static const struct seq_operations gfs2_glock_seq_ops = {
 	.start = gfs2_glock_seq_start,
 	.next  = gfs2_glock_seq_next,
@@ -1829,7 +1950,21 @@ static const struct seq_operations gfs2_glock_seq_ops = {
 	.show  = gfs2_glock_seq_show,
 };
 
-static int gfs2_debugfs_open(struct inode *inode, struct file *file)
+static const struct seq_operations gfs2_glstats_seq_ops = {
+	.start = gfs2_glock_seq_start,
+	.next  = gfs2_glock_seq_next,
+	.stop  = gfs2_glock_seq_stop,
+	.show  = gfs2_glstats_seq_show,
+};
+
+static const struct seq_operations gfs2_sbstats_seq_ops = {
+	.start = gfs2_sbstats_seq_start,
+	.next  = gfs2_sbstats_seq_next,
+	.stop  = gfs2_sbstats_seq_stop,
+	.show  = gfs2_sbstats_seq_show,
+};
+
+static int gfs2_glocks_open(struct inode *inode, struct file *file)
 {
 	int ret = seq_open_private(file, &gfs2_glock_seq_ops,
 				   sizeof(struct gfs2_glock_iter));
@@ -1841,9 +1976,49 @@ static int gfs2_debugfs_open(struct inode *inode, struct file *file)
 	return ret;
 }
 
-static const struct file_operations gfs2_debug_fops = {
+static int gfs2_glstats_open(struct inode *inode, struct file *file)
+{
+	int ret = seq_open_private(file, &gfs2_glstats_seq_ops,
+				   sizeof(struct gfs2_glock_iter));
+	if (ret == 0) {
+		struct seq_file *seq = file->private_data;
+		struct gfs2_glock_iter *gi = seq->private;
+		gi->sdp = inode->i_private;
+	}
+	return ret;
+}
+
+static int gfs2_sbstats_open(struct inode *inode, struct file *file)
+{
+	int ret = seq_open_private(file, &gfs2_sbstats_seq_ops,
+				   sizeof(struct gfs2_glock_iter));
+	if (ret == 0) {
+		struct seq_file *seq = file->private_data;
+		struct gfs2_glock_iter *gi = seq->private;
+		gi->sdp = inode->i_private;
+	}
+	return ret;
+}
+
+static const struct file_operations gfs2_glocks_fops = {
+	.owner   = THIS_MODULE,
+	.open    = gfs2_glocks_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release_private,
+};
+
+static const struct file_operations gfs2_glstats_fops = {
 	.owner   = THIS_MODULE,
-	.open    = gfs2_debugfs_open,
+	.open    = gfs2_glstats_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release_private,
+};
+
+static const struct file_operations gfs2_sbstats_fops = {
+	.owner   = THIS_MODULE,
+	.open	 = gfs2_sbstats_open,
 	.read    = seq_read,
 	.llseek  = seq_lseek,
 	.release = seq_release_private,
@@ -1857,20 +2032,45 @@ int gfs2_create_debugfs_file(struct gfs2_sbd *sdp)
 	sdp->debugfs_dentry_glocks = debugfs_create_file("glocks",
 							 S_IFREG | S_IRUGO,
 							 sdp->debugfs_dir, sdp,
-							 &gfs2_debug_fops);
+							 &gfs2_glocks_fops);
 	if (!sdp->debugfs_dentry_glocks)
-		return -ENOMEM;
+		goto fail;
+
+	sdp->debugfs_dentry_glstats = debugfs_create_file("glstats",
+							S_IFREG | S_IRUGO,
+							sdp->debugfs_dir, sdp,
+							&gfs2_glstats_fops);
+	if (!sdp->debugfs_dentry_glstats)
+		goto fail;
+
+	sdp->debugfs_dentry_sbstats = debugfs_create_file("sbstats",
+							S_IFREG | S_IRUGO,
+							sdp->debugfs_dir, sdp,
+							&gfs2_sbstats_fops);
+	if (!sdp->debugfs_dentry_sbstats)
+		goto fail;
 
 	return 0;
+fail:
+	gfs2_delete_debugfs_file(sdp);
+	return -ENOMEM;
 }
 
 void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp)
 {
-	if (sdp && sdp->debugfs_dir) {
+	if (sdp->debugfs_dir) {
 		if (sdp->debugfs_dentry_glocks) {
 			debugfs_remove(sdp->debugfs_dentry_glocks);
 			sdp->debugfs_dentry_glocks = NULL;
 		}
+		if (sdp->debugfs_dentry_glstats) {
+			debugfs_remove(sdp->debugfs_dentry_glstats);
+			sdp->debugfs_dentry_glstats = NULL;
+		}
+		if (sdp->debugfs_dentry_sbstats) {
+			debugfs_remove(sdp->debugfs_dentry_sbstats);
+			sdp->debugfs_dentry_sbstats = NULL;
+		}
 		debugfs_remove(sdp->debugfs_dir);
 		sdp->debugfs_dir = NULL;
 	}
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 97742a7..4d546df 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -19,6 +19,8 @@
 #include <linux/rculist_bl.h>
 #include <linux/completion.h>
 #include <linux/rbtree.h>
+#include <linux/ktime.h>
+#include <linux/percpu.h>
 
 #define DIO_WAIT	0x00000010
 #define DIO_METADATA	0x00000020
@@ -205,6 +207,22 @@ struct gfs2_glock_operations {
 };
 
 enum {
+	GFS2_LKS_SRTT = 0,	/* Non blocking smoothed round trip time */
+	GFS2_LKS_SRTTVAR = 1,	/* Non blocking smoothed variance */
+	GFS2_LKS_SRTTB = 2,	/* Blocking smoothed round trip time */
+	GFS2_LKS_SRTTVARB = 3,	/* Blocking smoothed variance */
+	GFS2_LKS_SIRT = 4,	/* Smoothed Inter-request time */
+	GFS2_LKS_SIRTVAR = 5,	/* Smoothed Inter-request variance */
+	GFS2_LKS_DCOUNT = 6,	/* Count of dlm requests */
+	GFS2_LKS_QCOUNT = 7,	/* Count of gfs2_holder queues */
+	GFS2_NR_LKSTATS
+};
+
+struct gfs2_lkstats {
+	s64 stats[GFS2_NR_LKSTATS];
+};
+
+enum {
 	/* States */
 	HIF_HOLDER		= 6,  /* Set for gh that "holds" the glock */
 	HIF_FIRST		= 7,
@@ -238,10 +256,12 @@ enum {
 	GLF_QUEUED			= 12,
 	GLF_LRU				= 13,
 	GLF_OBJECT			= 14, /* Used only for tracing */
+	GLF_BLOCKING			= 15,
 };
 
 struct gfs2_glock {
 	struct hlist_bl_node gl_list;
+	struct gfs2_sbd *gl_sbd;
 	unsigned long gl_flags;		/* GLF_... */
 	struct lm_lockname gl_name;
 	atomic_t gl_ref;
@@ -261,16 +281,14 @@ struct gfs2_glock {
 	struct list_head gl_holders;
 
 	const struct gfs2_glock_operations *gl_ops;
-	char gl_strname[GDLM_STRNAME_BYTES];
+	ktime_t gl_dstamp;
+	struct gfs2_lkstats gl_stats;
 	struct dlm_lksb gl_lksb;
 	char gl_lvb[32];
 	unsigned long gl_tchange;
 	void *gl_object;
 
 	struct list_head gl_lru;
-
-	struct gfs2_sbd *gl_sbd;
-
 	struct list_head gl_ail_list;
 	atomic_t gl_ail_count;
 	atomic_t gl_revokes;
@@ -560,8 +578,14 @@ struct lm_lockstruct {
 	uint32_t *ls_recover_result; /* result of last jid recovery */
 };
 
+struct gfs2_pcpu_lkstats {
+	/* One struct for each glock type */
+	struct gfs2_lkstats lkstats[10];
+};
+
 struct gfs2_sbd {
 	struct super_block *sd_vfs;
+	struct gfs2_pcpu_lkstats __percpu *sd_lkstats;
 	struct kobject sd_kobj;
 	unsigned long sd_flags;	/* SDF_... */
 	struct gfs2_sb_host sd_sb;
@@ -725,8 +749,23 @@ struct gfs2_sbd {
 
 	unsigned long sd_last_warning;
 	struct dentry *debugfs_dir;    /* debugfs directory */
-	struct dentry *debugfs_dentry_glocks; /* for debugfs */
+	struct dentry *debugfs_dentry_glocks;
+	struct dentry *debugfs_dentry_glstats;
+	struct dentry *debugfs_dentry_sbstats;
 };
 
+static inline void gfs2_glstats_inc(struct gfs2_glock *gl, int which)
+{
+	gl->gl_stats.stats[which]++;
+}
+
+static inline void gfs2_sbstats_inc(const struct gfs2_glock *gl, int which)
+{
+	const struct gfs2_sbd *sdp = gl->gl_sbd;
+	preempt_disable();
+	this_cpu_ptr(sdp->sd_lkstats)->lkstats[gl->gl_name.ln_type].stats[which]++;
+	preempt_enable();
+}
+
 #endif /* __INCORE_DOT_H__ */
 
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index a7d611b..cee74c8 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1035,14 +1035,19 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
 	struct buffer_head *bh;
 	struct gfs2_holder ghs[3];
 	struct gfs2_rgrpd *rgd;
-	int error = -EROFS;
+	int error;
 
+	error = gfs2_rindex_update(sdp);
+	if (error)
+		return error;
 	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
 	gfs2_holder_init(ip->i_gl,  LM_ST_EXCLUSIVE, 0, ghs + 1);
 
-	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
-	if (!rgd)
+	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1);
+	if (!rgd) {
+		error = -EROFS;
 		goto out_inodes;
+	}
 	gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
 
 
@@ -1258,7 +1263,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
 		 * this is the case of the target file already existing
 		 * so we unlink before doing the rename
 		 */
-		nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr);
+		nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr, 1);
 		if (nrgd)
 			gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
 	}
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 8944d1e..f8411bd 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -18,14 +18,106 @@
 #include "glock.h"
 #include "util.h"
 #include "sys.h"
+#include "trace_gfs2.h"
 
 extern struct workqueue_struct *gfs2_control_wq;
 
+/**
+ * gfs2_update_stats - Update time based stats
+ * @mv: Pointer to mean/variance structure to update
+ * @sample: New data to include
+ *
+ * @delta is the difference between the current rtt sample and the
+ * running average srtt. We add 1/8 of that to the srtt in order to
+ * update the current srtt estimate. The varience estimate is a bit
+ * more complicated. We subtract the abs value of the @delta from
+ * the current variance estimate and add 1/4 of that to the running
+ * total.
+ *
+ * Note that the index points at the array entry containing the smoothed
+ * mean value, and the variance is always in the following entry
+ *
+ * Reference: TCP/IP Illustrated, vol 2, p. 831,832
+ * All times are in units of integer nanoseconds. Unlike the TCP/IP case,
+ * they are not scaled fixed point.
+ */
+
+static inline void gfs2_update_stats(struct gfs2_lkstats *s, unsigned index,
+				     s64 sample)
+{
+	s64 delta = sample - s->stats[index];
+	s->stats[index] += (delta >> 3);
+	index++;
+	s->stats[index] += ((abs64(delta) - s->stats[index]) >> 2);
+}
+
+/**
+ * gfs2_update_reply_times - Update locking statistics
+ * @gl: The glock to update
+ *
+ * This assumes that gl->gl_dstamp has been set earlier.
+ *
+ * The rtt (lock round trip time) is an estimate of the time
+ * taken to perform a dlm lock request. We update it on each
+ * reply from the dlm.
+ *
+ * The blocking flag is set on the glock for all dlm requests
+ * which may potentially block due to lock requests from other nodes.
+ * DLM requests where the current lock state is exclusive, the
+ * requested state is null (or unlocked) or where the TRY or
+ * TRY_1CB flags are set are classified as non-blocking. All
+ * other DLM requests are counted as (potentially) blocking.
+ */
+static inline void gfs2_update_reply_times(struct gfs2_glock *gl)
+{
+	struct gfs2_pcpu_lkstats *lks;
+	const unsigned gltype = gl->gl_name.ln_type;
+	unsigned index = test_bit(GLF_BLOCKING, &gl->gl_flags) ?
+			 GFS2_LKS_SRTTB : GFS2_LKS_SRTT;
+	s64 rtt;
+
+	preempt_disable();
+	rtt = ktime_to_ns(ktime_sub(ktime_get_real(), gl->gl_dstamp));
+	lks = this_cpu_ptr(gl->gl_sbd->sd_lkstats);
+	gfs2_update_stats(&gl->gl_stats, index, rtt);		/* Local */
+	gfs2_update_stats(&lks->lkstats[gltype], index, rtt);	/* Global */
+	preempt_enable();
+
+	trace_gfs2_glock_lock_time(gl, rtt);
+}
+
+/**
+ * gfs2_update_request_times - Update locking statistics
+ * @gl: The glock to update
+ *
+ * The irt (lock inter-request times) measures the average time
+ * between requests to the dlm. It is updated immediately before
+ * each dlm call.
+ */
+
+static inline void gfs2_update_request_times(struct gfs2_glock *gl)
+{
+	struct gfs2_pcpu_lkstats *lks;
+	const unsigned gltype = gl->gl_name.ln_type;
+	ktime_t dstamp;
+	s64 irt;
+
+	preempt_disable();
+	dstamp = gl->gl_dstamp;
+	gl->gl_dstamp = ktime_get_real();
+	irt = ktime_to_ns(ktime_sub(gl->gl_dstamp, dstamp));
+	lks = this_cpu_ptr(gl->gl_sbd->sd_lkstats);
+	gfs2_update_stats(&gl->gl_stats, GFS2_LKS_SIRT, irt);		/* Local */
+	gfs2_update_stats(&lks->lkstats[gltype], GFS2_LKS_SIRT, irt);	/* Global */
+	preempt_enable();
+}
+ 
 static void gdlm_ast(void *arg)
 {
 	struct gfs2_glock *gl = arg;
 	unsigned ret = gl->gl_state;
 
+	gfs2_update_reply_times(gl);
 	BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED);
 
 	if (gl->gl_lksb.sb_flags & DLM_SBF_VALNOTVALID)
@@ -111,7 +203,7 @@ static int make_mode(const unsigned int lmstate)
 static u32 make_flags(const u32 lkid, const unsigned int gfs_flags,
 		      const int req)
 {
-	u32 lkf = 0;
+	u32 lkf = DLM_LKF_VALBLK;
 
 	if (gfs_flags & LM_FLAG_TRY)
 		lkf |= DLM_LKF_NOQUEUE;
@@ -138,26 +230,43 @@ static u32 make_flags(const u32 lkid, const unsigned int gfs_flags,
 	if (lkid != 0) 
 		lkf |= DLM_LKF_CONVERT;
 
-	lkf |= DLM_LKF_VALBLK;
-
 	return lkf;
 }
 
+static void gfs2_reverse_hex(char *c, u64 value)
+{
+	while (value) {
+		*c-- = hex_asc[value & 0x0f];
+		value >>= 4;
+	}
+}
+
 static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state,
 		     unsigned int flags)
 {
 	struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
 	int req;
 	u32 lkf;
+	char strname[GDLM_STRNAME_BYTES] = "";
 
 	req = make_mode(req_state);
 	lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req);
-
+	gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
+	gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
+	if (gl->gl_lksb.sb_lkid) {
+		gfs2_update_request_times(gl);
+	} else {
+		memset(strname, ' ', GDLM_STRNAME_BYTES - 1);
+		strname[GDLM_STRNAME_BYTES - 1] = '\0';
+		gfs2_reverse_hex(strname + 7, gl->gl_name.ln_type);
+		gfs2_reverse_hex(strname + 23, gl->gl_name.ln_number);
+		gl->gl_dstamp = ktime_get_real();
+	}
 	/*
 	 * Submit the actual lock request.
 	 */
 
-	return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, gl->gl_strname,
+	return dlm_lock(ls->ls_dlm, req, &gl->gl_lksb, lkf, strname,
 			GDLM_STRNAME_BYTES - 1, 0, gdlm_ast, gl, gdlm_bast);
 }
 
@@ -172,6 +281,10 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
 		return;
 	}
 
+	clear_bit(GLF_BLOCKING, &gl->gl_flags);
+	gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
+	gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
+	gfs2_update_request_times(gl);
 	error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK,
 			   NULL, gl);
 	if (error) {
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 756fae9..2b9f0d9 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -19,6 +19,7 @@
 #include <linux/freezer.h>
 #include <linux/bio.h>
 #include <linux/writeback.h>
+#include <linux/list_sort.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -358,7 +359,7 @@ retry:
 	return 0;
 }
 
-static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
+u64 gfs2_log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
 {
 	struct gfs2_journal_extent *je;
 
@@ -467,8 +468,8 @@ static unsigned int current_tail(struct gfs2_sbd *sdp)
 
 void gfs2_log_incr_head(struct gfs2_sbd *sdp)
 {
-	if (sdp->sd_log_flush_head == sdp->sd_log_tail)
-		BUG_ON(sdp->sd_log_flush_head != sdp->sd_log_head);
+	BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) &&
+	       (sdp->sd_log_flush_head != sdp->sd_log_head));
 
 	if (++sdp->sd_log_flush_head == sdp->sd_jdesc->jd_blocks) {
 		sdp->sd_log_flush_head = 0;
@@ -476,99 +477,6 @@ void gfs2_log_incr_head(struct gfs2_sbd *sdp)
 	}
 }
 
-/**
- * gfs2_log_write_endio - End of I/O for a log buffer
- * @bh: The buffer head
- * @uptodate: I/O Status
- *
- */
-
-static void gfs2_log_write_endio(struct buffer_head *bh, int uptodate)
-{
-	struct gfs2_sbd *sdp = bh->b_private;
-	bh->b_private = NULL;
-
-	end_buffer_write_sync(bh, uptodate);
-	if (atomic_dec_and_test(&sdp->sd_log_in_flight))
-		wake_up(&sdp->sd_log_flush_wait);
-}
-
-/**
- * gfs2_log_get_buf - Get and initialize a buffer to use for log control data
- * @sdp: The GFS2 superblock
- *
- * Returns: the buffer_head
- */
-
-struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp)
-{
-	u64 blkno = log_bmap(sdp, sdp->sd_log_flush_head);
-	struct buffer_head *bh;
-
-	bh = sb_getblk(sdp->sd_vfs, blkno);
-	lock_buffer(bh);
-	memset(bh->b_data, 0, bh->b_size);
-	set_buffer_uptodate(bh);
-	clear_buffer_dirty(bh);
-	gfs2_log_incr_head(sdp);
-	atomic_inc(&sdp->sd_log_in_flight);
-	bh->b_private = sdp;
-	bh->b_end_io = gfs2_log_write_endio;
-
-	return bh;
-}
-
-/**
- * gfs2_fake_write_endio - 
- * @bh: The buffer head
- * @uptodate: The I/O Status
- *
- */
-
-static void gfs2_fake_write_endio(struct buffer_head *bh, int uptodate)
-{
-	struct buffer_head *real_bh = bh->b_private;
-	struct gfs2_bufdata *bd = real_bh->b_private;
-	struct gfs2_sbd *sdp = bd->bd_gl->gl_sbd;
-
-	end_buffer_write_sync(bh, uptodate);
-	free_buffer_head(bh);
-	unlock_buffer(real_bh);
-	brelse(real_bh);
-	if (atomic_dec_and_test(&sdp->sd_log_in_flight))
-		wake_up(&sdp->sd_log_flush_wait);
-}
-
-/**
- * gfs2_log_fake_buf - Build a fake buffer head to write metadata buffer to log
- * @sdp: the filesystem
- * @data: the data the buffer_head should point to
- *
- * Returns: the log buffer descriptor
- */
-
-struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
-				      struct buffer_head *real)
-{
-	u64 blkno = log_bmap(sdp, sdp->sd_log_flush_head);
-	struct buffer_head *bh;
-
-	bh = alloc_buffer_head(GFP_NOFS | __GFP_NOFAIL);
-	atomic_set(&bh->b_count, 1);
-	bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock);
-	set_bh_page(bh, real->b_page, bh_offset(real));
-	bh->b_blocknr = blkno;
-	bh->b_size = sdp->sd_sb.sb_bsize;
-	bh->b_bdev = sdp->sd_vfs->s_bdev;
-	bh->b_private = real;
-	bh->b_end_io = gfs2_fake_write_endio;
-
-	gfs2_log_incr_head(sdp);
-	atomic_inc(&sdp->sd_log_in_flight);
-
-	return bh;
-}
-
 static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
 {
 	unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
@@ -592,7 +500,7 @@ static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
 
 static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
 {
-	u64 blkno = log_bmap(sdp, sdp->sd_log_flush_head);
+	u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head);
 	struct buffer_head *bh;
 	struct gfs2_log_header *lh;
 	unsigned int tail;
@@ -659,6 +567,20 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
 	log_write_header(sdp, 0, 0);
 }
 
+static int bd_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+	struct gfs2_bufdata *bda, *bdb;
+
+	bda = list_entry(a, struct gfs2_bufdata, bd_le.le_list);
+	bdb = list_entry(b, struct gfs2_bufdata, bd_le.le_list);
+
+	if (bda->bd_bh->b_blocknr < bdb->bd_bh->b_blocknr)
+		return -1;
+	if (bda->bd_bh->b_blocknr > bdb->bd_bh->b_blocknr)
+		return 1;
+	return 0;
+}
+
 static void gfs2_ordered_write(struct gfs2_sbd *sdp)
 {
 	struct gfs2_bufdata *bd;
@@ -666,6 +588,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp)
 	LIST_HEAD(written);
 
 	gfs2_log_lock(sdp);
+	list_sort(NULL, &sdp->sd_log_le_ordered, &bd_cmp);
 	while (!list_empty(&sdp->sd_log_le_ordered)) {
 		bd = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_bufdata, bd_le.le_list);
 		list_move(&bd->bd_le.le_list, &written);
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index ab06216..ff07454 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -53,10 +53,7 @@ extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
 
 extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks);
 extern void gfs2_log_incr_head(struct gfs2_sbd *sdp);
-
-extern struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp);
-extern struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
-				      struct buffer_head *real);
+extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp, unsigned int lbn);
 extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
 extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
 extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 0301be6..f2ff2af 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -76,7 +76,7 @@ static void maybe_release_space(struct gfs2_bufdata *bd)
 	if (bi->bi_clone == 0)
 		return;
 	if (sdp->sd_args.ar_discard)
-		gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bd->bd_bh, bi);
+		gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bd->bd_bh, bi, 1, NULL);
 	memcpy(bi->bi_clone + bi->bi_offset,
 	       bd->bd_bh->b_data + bi->bi_offset, bi->bi_len);
 	clear_bit(GBF_FULL, &bi->bi_flags);
@@ -143,6 +143,98 @@ static inline __be64 *bh_ptr_end(struct buffer_head *bh)
 	return (__force __be64 *)(bh->b_data + bh->b_size);
 }
 
+/**
+ * gfs2_log_write_endio - End of I/O for a log buffer
+ * @bh: The buffer head
+ * @uptodate: I/O Status
+ *
+ */
+
+static void gfs2_log_write_endio(struct buffer_head *bh, int uptodate)
+{
+	struct gfs2_sbd *sdp = bh->b_private;
+	bh->b_private = NULL;
+
+	end_buffer_write_sync(bh, uptodate);
+	if (atomic_dec_and_test(&sdp->sd_log_in_flight))
+		wake_up(&sdp->sd_log_flush_wait);
+}
+
+/**
+ * gfs2_log_get_buf - Get and initialize a buffer to use for log control data
+ * @sdp: The GFS2 superblock
+ *
+ * tReturns: the buffer_head
+ */
+
+static struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp)
+{
+	u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head);
+	struct buffer_head *bh;
+
+	bh = sb_getblk(sdp->sd_vfs, blkno);
+	lock_buffer(bh);
+	memset(bh->b_data, 0, bh->b_size);
+	set_buffer_uptodate(bh);
+	clear_buffer_dirty(bh);
+	gfs2_log_incr_head(sdp);
+	atomic_inc(&sdp->sd_log_in_flight);
+	bh->b_private = sdp;
+	bh->b_end_io = gfs2_log_write_endio;
+
+	return bh;
+}
+
+/**
+ * gfs2_fake_write_endio - 
+ * @bh: The buffer head
+ * @uptodate: The I/O Status
+ *
+ */
+
+static void gfs2_fake_write_endio(struct buffer_head *bh, int uptodate)
+{
+	struct buffer_head *real_bh = bh->b_private;
+	struct gfs2_bufdata *bd = real_bh->b_private;
+	struct gfs2_sbd *sdp = bd->bd_gl->gl_sbd;
+
+	end_buffer_write_sync(bh, uptodate);
+	free_buffer_head(bh);
+	unlock_buffer(real_bh);
+	brelse(real_bh);
+	if (atomic_dec_and_test(&sdp->sd_log_in_flight))
+		wake_up(&sdp->sd_log_flush_wait);
+}
+
+/**
+ * gfs2_log_fake_buf - Build a fake buffer head to write metadata buffer to log
+ * @sdp: the filesystem
+ * @data: the data the buffer_head should point to
+ *
+ * Returns: the log buffer descriptor
+ */
+
+static struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
+				      struct buffer_head *real)
+{
+	u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head);
+	struct buffer_head *bh;
+
+	bh = alloc_buffer_head(GFP_NOFS | __GFP_NOFAIL);
+	atomic_set(&bh->b_count, 1);
+	bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock);
+	set_bh_page(bh, real->b_page, bh_offset(real));
+	bh->b_blocknr = blkno;
+	bh->b_size = sdp->sd_sb.sb_bsize;
+	bh->b_bdev = sdp->sd_vfs->s_bdev;
+	bh->b_private = real;
+	bh->b_end_io = gfs2_fake_write_endio;
+
+	gfs2_log_incr_head(sdp);
+	atomic_inc(&sdp->sd_log_in_flight);
+
+	return bh;
+}
 
 static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
 {
@@ -553,11 +645,11 @@ static void gfs2_check_magic(struct buffer_head *bh)
 	__be32 *ptr;
 
 	clear_buffer_escaped(bh);
-	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(bh->b_page);
 	ptr = kaddr + bh_offset(bh);
 	if (*ptr == cpu_to_be32(GFS2_MAGIC))
 		set_buffer_escaped(bh);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
@@ -594,10 +686,10 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
 		if (buffer_escaped(bd->bd_bh)) {
 			void *kaddr;
 			bh1 = gfs2_log_get_buf(sdp);
-			kaddr = kmap_atomic(bd->bd_bh->b_page, KM_USER0);
+			kaddr = kmap_atomic(bd->bd_bh->b_page);
 			memcpy(bh1->b_data, kaddr + bh_offset(bd->bd_bh),
 			       bh1->b_size);
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			*(__be32 *)bh1->b_data = 0;
 			clear_buffer_escaped(bd->bd_bh);
 			unlock_buffer(bd->bd_bh);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 6aacf3f..a163ca2 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -68,6 +68,12 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
 	sb->s_fs_info = sdp;
 	sdp->sd_vfs = sb;
+	sdp->sd_lkstats = alloc_percpu(struct gfs2_pcpu_lkstats);
+	if (!sdp->sd_lkstats) {
+		kfree(sdp);
+		return NULL;
+	}
+
 	set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
 	gfs2_tune_init(&sdp->sd_tune);
 
@@ -431,10 +437,9 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr,
 		fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode));
 		return PTR_ERR(inode);
 	}
-	dentry = d_alloc_root(inode);
+	dentry = d_make_root(inode);
 	if (!dentry) {
 		fs_err(sdp, "can't alloc %s dentry\n", name);
-		iput(inode);
 		return -ENOMEM;
 	}
 	*dptr = dentry;
@@ -1216,6 +1221,7 @@ fail_sys:
 	gfs2_sys_fs_del(sdp);
 fail:
 	gfs2_delete_debugfs_file(sdp);
+	free_percpu(sdp->sd_lkstats);
 	kfree(sdp);
 	sb->s_fs_info = NULL;
 	return error;
@@ -1388,6 +1394,7 @@ static void gfs2_kill_sb(struct super_block *sb)
 	shrink_dcache_sb(sb);
 	kill_block_super(sb);
 	gfs2_delete_debugfs_file(sdp);
+	free_percpu(sdp->sd_lkstats);
 	kfree(sdp);
 }
 
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index a45b21b..c0f8904 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -720,12 +720,12 @@ get_a_page:
 
 	gfs2_trans_add_bh(ip->i_gl, bh, 0);
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	if (offset + sizeof(struct gfs2_quota) > PAGE_CACHE_SIZE)
 		nbytes = PAGE_CACHE_SIZE - offset;
 	memcpy(kaddr + offset, ptr, nbytes);
 	flush_dcache_page(page);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	unlock_page(page);
 	page_cache_release(page);
 
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 981bfa3..600e720 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -327,23 +327,31 @@ static inline int rgrp_contains_block(struct gfs2_rgrpd *rgd, u64 block)
  * Returns: The resource group, or NULL if not found
  */
 
-struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk)
+struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact)
 {
-	struct rb_node **newn;
+	struct rb_node *n, *next;
 	struct gfs2_rgrpd *cur;
 
 	spin_lock(&sdp->sd_rindex_spin);
-	newn = &sdp->sd_rindex_tree.rb_node;
-	while (*newn) {
-		cur = rb_entry(*newn, struct gfs2_rgrpd, rd_node);
+	n = sdp->sd_rindex_tree.rb_node;
+	while (n) {
+		cur = rb_entry(n, struct gfs2_rgrpd, rd_node);
+		next = NULL;
 		if (blk < cur->rd_addr)
-			newn = &((*newn)->rb_left);
+			next = n->rb_left;
 		else if (blk >= cur->rd_data0 + cur->rd_data)
-			newn = &((*newn)->rb_right);
-		else {
+			next = n->rb_right;
+		if (next == NULL) {
 			spin_unlock(&sdp->sd_rindex_spin);
+			if (exact) {
+				if (blk < cur->rd_addr)
+					return NULL;
+				if (blk >= cur->rd_data0 + cur->rd_data)
+					return NULL;
+			}
 			return cur;
 		}
+		n = next;
 	}
 	spin_unlock(&sdp->sd_rindex_spin);
 
@@ -805,9 +813,9 @@ void gfs2_rgrp_go_unlock(struct gfs2_holder *gh)
 
 }
 
-void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
+int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
 			     struct buffer_head *bh,
-			     const struct gfs2_bitmap *bi)
+			     const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed)
 {
 	struct super_block *sb = sdp->sd_vfs;
 	struct block_device *bdev = sb->s_bdev;
@@ -818,11 +826,19 @@ void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
 	sector_t nr_sects = 0;
 	int rv;
 	unsigned int x;
+	u32 trimmed = 0;
+	u8 diff;
 
 	for (x = 0; x < bi->bi_len; x++) {
-		const u8 *orig = bh->b_data + bi->bi_offset + x;
-		const u8 *clone = bi->bi_clone + bi->bi_offset + x;
-		u8 diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1));
+		const u8 *clone = bi->bi_clone ? bi->bi_clone : bi->bi_bh->b_data;
+		clone += bi->bi_offset;
+		clone += x;
+		if (bh) {
+			const u8 *orig = bh->b_data + bi->bi_offset + x;
+			diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1));
+		} else {
+			diff = ~(*clone | (*clone >> 1));
+		}
 		diff &= 0x55;
 		if (diff == 0)
 			continue;
@@ -833,11 +849,14 @@ void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
 				if (nr_sects == 0)
 					goto start_new_extent;
 				if ((start + nr_sects) != blk) {
-					rv = blkdev_issue_discard(bdev, start,
-							    nr_sects, GFP_NOFS,
-							    0);
-					if (rv)
-						goto fail;
+					if (nr_sects >= minlen) {
+						rv = blkdev_issue_discard(bdev,
+							start, nr_sects,
+							GFP_NOFS, 0);
+						if (rv)
+							goto fail;
+						trimmed += nr_sects;
+					}
 					nr_sects = 0;
 start_new_extent:
 					start = blk;
@@ -848,15 +867,108 @@ start_new_extent:
 			blk += sects_per_blk;
 		}
 	}
-	if (nr_sects) {
+	if (nr_sects >= minlen) {
 		rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0);
 		if (rv)
 			goto fail;
+		trimmed += nr_sects;
 	}
-	return;
+	if (ptrimmed)
+		*ptrimmed = trimmed;
+	return 0;
+
 fail:
-	fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem", rv);
+	if (sdp->sd_args.ar_discard)
+		fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem", rv);
 	sdp->sd_args.ar_discard = 0;
+	return -EIO;
+}
+
+/**
+ * gfs2_fitrim - Generate discard requests for unused bits of the filesystem
+ * @filp: Any file on the filesystem
+ * @argp: Pointer to the arguments (also used to pass result)
+ *
+ * Returns: 0 on success, otherwise error code
+ */
+
+int gfs2_fitrim(struct file *filp, void __user *argp)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
+	struct request_queue *q = bdev_get_queue(sdp->sd_vfs->s_bdev);
+	struct buffer_head *bh;
+	struct gfs2_rgrpd *rgd;
+	struct gfs2_rgrpd *rgd_end;
+	struct gfs2_holder gh;
+	struct fstrim_range r;
+	int ret = 0;
+	u64 amt;
+	u64 trimmed = 0;
+	unsigned int x;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (!blk_queue_discard(q))
+		return -EOPNOTSUPP;
+
+	ret = gfs2_rindex_update(sdp);
+	if (ret)
+		return ret;
+
+	if (argp == NULL) {
+		r.start = 0;
+		r.len = ULLONG_MAX;
+		r.minlen = 0;
+	} else if (copy_from_user(&r, argp, sizeof(r)))
+		return -EFAULT;
+
+	rgd = gfs2_blk2rgrpd(sdp, r.start, 0);
+	rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0);
+
+	while (1) {
+
+		ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh);
+		if (ret)
+			goto out;
+
+		if (!(rgd->rd_flags & GFS2_RGF_TRIMMED)) {
+			/* Trim each bitmap in the rgrp */
+			for (x = 0; x < rgd->rd_length; x++) {
+				struct gfs2_bitmap *bi = rgd->rd_bits + x;
+				ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt);
+				if (ret) {
+					gfs2_glock_dq_uninit(&gh);
+					goto out;
+				}
+				trimmed += amt;
+			}
+
+			/* Mark rgrp as having been trimmed */
+			ret = gfs2_trans_begin(sdp, RES_RG_HDR, 0);
+			if (ret == 0) {
+				bh = rgd->rd_bits[0].bi_bh;
+				rgd->rd_flags |= GFS2_RGF_TRIMMED;
+				gfs2_trans_add_bh(rgd->rd_gl, bh, 1);
+				gfs2_rgrp_out(rgd, bh->b_data);
+				gfs2_trans_end(sdp);
+			}
+		}
+		gfs2_glock_dq_uninit(&gh);
+
+		if (rgd == rgd_end)
+			break;
+
+		rgd = gfs2_rgrpd_get_next(rgd);
+	}
+
+out:
+	r.len = trimmed << 9;
+	if (argp && copy_to_user(argp, &r, sizeof(r)))
+		return -EFAULT;
+
+	return ret;
 }
 
 /**
@@ -1003,7 +1115,7 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
 	if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal))
 		rgd = begin = ip->i_rgd;
 	else
-		rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal);
+		rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
 
 	if (rgd == NULL)
 		return -EBADSLT;
@@ -1288,7 +1400,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart,
 	u32 length, rgrp_blk, buf_blk;
 	unsigned int buf;
 
-	rgd = gfs2_blk2rgrpd(sdp, bstart);
+	rgd = gfs2_blk2rgrpd(sdp, bstart, 1);
 	if (!rgd) {
 		if (gfs2_consist(sdp))
 			fs_err(sdp, "block = %llu\n", (unsigned long long)bstart);
@@ -1469,7 +1581,7 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta)
 		return;
 	trace_gfs2_block_alloc(ip, bstart, blen, GFS2_BLKST_FREE);
 	rgd->rd_free += blen;
-
+	rgd->rd_flags &= ~GFS2_RGF_TRIMMED;
 	gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
 	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
 
@@ -1562,7 +1674,7 @@ int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
 		return error;
 
 	error = -EINVAL;
-	rgd = gfs2_blk2rgrpd(sdp, no_addr);
+	rgd = gfs2_blk2rgrpd(sdp, no_addr, 1);
 	if (!rgd)
 		goto fail;
 
@@ -1605,7 +1717,7 @@ void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist,
 	if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, block))
 		rgd = ip->i_rgd;
 	else
-		rgd = gfs2_blk2rgrpd(sdp, block);
+		rgd = gfs2_blk2rgrpd(sdp, block, 1);
 	if (!rgd) {
 		fs_err(sdp, "rlist_add: no rgrp for block %llu\n", (unsigned long long)block);
 		return;
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index ceec910..b4b10f4 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -11,6 +11,7 @@
 #define __RGRP_DOT_H__
 
 #include <linux/slab.h>
+#include <linux/uaccess.h>
 
 struct gfs2_rgrpd;
 struct gfs2_sbd;
@@ -18,7 +19,7 @@ struct gfs2_holder;
 
 extern void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd);
 
-extern struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk);
+extern struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact);
 extern struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp);
 extern struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd);
 
@@ -62,8 +63,9 @@ extern void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state);
 extern void gfs2_rlist_free(struct gfs2_rgrp_list *rlist);
 extern u64 gfs2_ri_total(struct gfs2_sbd *sdp);
 extern int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl);
-extern void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
-				    struct buffer_head *bh,
-				    const struct gfs2_bitmap *bi);
+extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
+				   struct buffer_head *bh,
+				   const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed);
+extern int gfs2_fitrim(struct file *filp, void __user *argp);
 
 #endif /* __RGRP_DOT_H__ */
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 4553ce5..f3faf72 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1417,7 +1417,7 @@ static int gfs2_dinode_dealloc(struct gfs2_inode *ip)
 	if (error)
 		goto out;
 
-	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
+	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr, 1);
 	if (!rgd) {
 		gfs2_consist_inode(ip);
 		error = -EIO;
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h
index 5d07609..dfa89cd 100644
--- a/fs/gfs2/trace_gfs2.h
+++ b/fs/gfs2/trace_gfs2.h
@@ -11,6 +11,7 @@
 #include <linux/dlmconstants.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/writeback.h>
+#include <linux/ktime.h>
 #include "incore.h"
 #include "glock.h"
 
@@ -43,7 +44,8 @@
 	{(1UL << GLF_FROZEN),			"F" },		\
 	{(1UL << GLF_QUEUED),			"q" },		\
 	{(1UL << GLF_LRU),			"L" },		\
-	{(1UL << GLF_OBJECT),			"o" })
+	{(1UL << GLF_OBJECT),			"o" },		\
+	{(1UL << GLF_BLOCKING),			"b" })
 
 #ifndef NUMPTY
 #define NUMPTY
@@ -236,6 +238,62 @@ TRACE_EVENT(gfs2_glock_queue,
 		  glock_trace_name(__entry->state))
 );
 
+/* DLM sends a reply to GFS2 */
+TRACE_EVENT(gfs2_glock_lock_time,
+
+	TP_PROTO(const struct gfs2_glock *gl, s64 tdiff),
+
+	TP_ARGS(gl, tdiff),
+
+	TP_STRUCT__entry(
+		__field(	dev_t,	dev		)
+		__field(	u64,	glnum		)
+		__field(	u32,	gltype		)
+		__field(	int,	status		)
+		__field(	char,	flags		)
+		__field(	s64,	tdiff		)
+		__field(	s64,	srtt		)
+		__field(	s64,	srttvar		)
+		__field(	s64,	srttb		)
+		__field(	s64,	srttvarb	)
+		__field(	s64,	sirt		)
+		__field(	s64,	sirtvar		)
+		__field(	s64,	dcount		)
+		__field(	s64,	qcount		)
+	),
+
+	TP_fast_assign(
+		__entry->dev            = gl->gl_sbd->sd_vfs->s_dev;
+		__entry->glnum          = gl->gl_name.ln_number;
+		__entry->gltype         = gl->gl_name.ln_type;
+		__entry->status		= gl->gl_lksb.sb_status;
+		__entry->flags		= gl->gl_lksb.sb_flags;
+		__entry->tdiff		= tdiff;
+		__entry->srtt		= gl->gl_stats.stats[GFS2_LKS_SRTT];
+		__entry->srttvar	= gl->gl_stats.stats[GFS2_LKS_SRTTVAR];
+		__entry->srttb		= gl->gl_stats.stats[GFS2_LKS_SRTTB];
+		__entry->srttvarb	= gl->gl_stats.stats[GFS2_LKS_SRTTVARB];
+		__entry->sirt		= gl->gl_stats.stats[GFS2_LKS_SIRT];
+		__entry->sirtvar	= gl->gl_stats.stats[GFS2_LKS_SIRTVAR];
+		__entry->dcount		= gl->gl_stats.stats[GFS2_LKS_DCOUNT];
+		__entry->qcount		= gl->gl_stats.stats[GFS2_LKS_QCOUNT];
+	),
+
+	TP_printk("%u,%u glock %d:%lld status:%d flags:%02x tdiff:%lld srtt:%lld/%lld srttb:%lld/%lld sirt:%lld/%lld dcnt:%lld qcnt:%lld",
+		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->gltype,
+		  (unsigned long long)__entry->glnum,
+		  __entry->status, __entry->flags,
+		  (long long)__entry->tdiff,
+		  (long long)__entry->srtt,
+		  (long long)__entry->srttvar,
+		  (long long)__entry->srttb,
+		  (long long)__entry->srttvarb,
+		  (long long)__entry->sirt,
+		  (long long)__entry->sirtvar,
+		  (long long)__entry->dcount,
+		  (long long)__entry->qcount)
+);
+
 /* Section 2 - Log/journal
  *
  * Objectives:
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index e963659..2e5ba42 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -251,7 +251,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
 	if (!blks)
 		return 0;
 
-	rgd = gfs2_blk2rgrpd(sdp, bn);
+	rgd = gfs2_blk2rgrpd(sdp, bn, 1);
 	if (!rgd) {
 		gfs2_consist_inode(ip);
 		return -EIO;
@@ -1439,7 +1439,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip)
 	struct gfs2_holder gh;
 	int error;
 
-	rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr);
+	rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1);
 	if (!rgd) {
 		gfs2_consist_inode(ip);
 		return -EIO;
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 8137fb3..7b4c537 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -430,15 +430,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
 
 	sb->s_d_op = &hfs_dentry_operations;
 	res = -ENOMEM;
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
 	if (!sb->s_root)
-		goto bail_iput;
+		goto bail_no_root;
 
 	/* everything's okay */
 	return 0;
 
-bail_iput:
-	iput(root_inode);
 bail_no_root:
 	printk(KERN_ERR "hfs: get root inode failed.\n");
 bail:
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 427682c..ceb1c28 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -465,6 +465,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
 		goto out_put_alloc_file;
 	}
 
+	sb->s_d_op = &hfsplus_dentry_operations;
+	sb->s_root = d_make_root(root);
+	if (!sb->s_root) {
+		err = -ENOMEM;
+		goto out_put_alloc_file;
+	}
+
 	str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
 	str.name = HFSP_HIDDENDIR_NAME;
 	err = hfs_find_init(sbi->cat_tree, &fd);
@@ -515,13 +522,6 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
 		}
 	}
 
-	sb->s_d_op = &hfsplus_dentry_operations;
-	sb->s_root = d_alloc_root(root);
-	if (!sb->s_root) {
-		err = -ENOMEM;
-		goto out_put_hidden_dir;
-	}
-
 	unload_nls(sbi->nls);
 	sbi->nls = nls;
 	return 0;
@@ -529,7 +529,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
 out_put_hidden_dir:
 	iput(sbi->hidden_dir);
 out_put_root:
-	iput(root);
+	dput(sb->s_root);
+	sb->s_root = NULL;
 out_put_alloc_file:
 	iput(sbi->alloc_file);
 out_close_cat_tree:
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index e130bd4..588d458 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -966,9 +966,9 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
 	}
 
 	err = -ENOMEM;
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
 	if (sb->s_root == NULL)
-		goto out_put;
+		goto out;
 
 	return 0;
 
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 3690467..54f6ecc 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -625,11 +625,9 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
 	hpfs_init_inode(root);
 	hpfs_read_inode(root);
 	unlock_new_inode(root);
-	s->s_root = d_alloc_root(root);
-	if (!s->s_root) {
-		iput(root);
+	s->s_root = d_make_root(root);
+	if (!s->s_root)
 		goto bail0;
-	}
 
 	/*
 	 * find the root directory's . pointer & finish filling in the inode
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index d92f4ce..a80e45a 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -726,17 +726,12 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
 
 	err = -ENOMEM;
 	root_inode = get_inode(sb, dget(proc_mnt->mnt_root));
-	if (!root_inode)
-		goto out_mntput;
-
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
 	if (!sb->s_root)
-		goto out_iput;
+		goto out_mntput;
 
 	return 0;
 
- out_iput:
-	iput(root_inode);
  out_mntput:
 	mntput(proc_mnt);
  out:
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 1e85a7a..a8e329f 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -154,10 +154,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 			return addr;
 	}
 
-	start_addr = mm->free_area_cache;
-
-	if (len <= mm->cached_hole_size)
+	if (len > mm->cached_hole_size)
+		start_addr = mm->free_area_cache;
+	else {
 		start_addr = TASK_UNMAPPED_BASE;
+		mm->cached_hole_size = 0;
+	}
 
 full_search:
 	addr = ALIGN(start_addr, huge_page_size(h));
@@ -171,13 +173,18 @@ full_search:
 			 */
 			if (start_addr != TASK_UNMAPPED_BASE) {
 				start_addr = TASK_UNMAPPED_BASE;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
 		}
 
-		if (!vma || addr + len <= vma->vm_start)
+		if (!vma || addr + len <= vma->vm_start) {
+			mm->free_area_cache = addr + len;
 			return addr;
+		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+			mm->cached_hole_size = vma->vm_start - addr;
 		addr = ALIGN(vma->vm_end, huge_page_size(h));
 	}
 }
@@ -831,8 +838,6 @@ bad_val:
 static int
 hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
 {
-	struct inode * inode;
-	struct dentry * root;
 	int ret;
 	struct hugetlbfs_config config;
 	struct hugetlbfs_sb_info *sbinfo;
@@ -865,16 +870,9 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_magic = HUGETLBFS_MAGIC;
 	sb->s_op = &hugetlbfs_ops;
 	sb->s_time_gran = 1;
-	inode = hugetlbfs_get_root(sb, &config);
-	if (!inode)
+	sb->s_root = d_make_root(hugetlbfs_get_root(sb, &config));
+	if (!sb->s_root)
 		goto out_free;
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		iput(inode);
-		goto out_free;
-	}
-	sb->s_root = root;
 	return 0;
 out_free:
 	kfree(sbinfo);
diff --git a/fs/inode.c b/fs/inode.c
index fb10d86..5d25642 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -938,8 +938,7 @@ void lockdep_annotate_inode_mutex_key(struct inode *inode)
 		struct file_system_type *type = inode->i_sb->s_type;
 
 		/* Set new key only if filesystem hasn't already changed it */
-		if (!lockdep_match_class(&inode->i_mutex,
-		    &type->i_mutex_key)) {
+		if (lockdep_match_class(&inode->i_mutex, &type->i_mutex_key)) {
 			/*
 			 * ensure nobody is actually holding i_mutex
 			 */
@@ -1369,17 +1368,6 @@ int generic_delete_inode(struct inode *inode)
 EXPORT_SYMBOL(generic_delete_inode);
 
 /*
- * Normal UNIX filesystem behaviour: delete the
- * inode when the usage count drops to zero, and
- * i_nlink is zero.
- */
-int generic_drop_inode(struct inode *inode)
-{
-	return !inode->i_nlink || inode_unhashed(inode);
-}
-EXPORT_SYMBOL_GPL(generic_drop_inode);
-
-/*
  * Called when we're dropping the last reference
  * to an inode.
  *
@@ -1651,7 +1639,7 @@ __setup("ihash_entries=", set_ihash_entries);
  */
 void __init inode_init_early(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* If hashes are distributed across NUMA nodes, defer
 	 * hash allocation until vmalloc space is available.
@@ -1669,13 +1657,13 @@ void __init inode_init_early(void)
 					&i_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << i_hash_shift); loop++)
+	for (loop = 0; loop < (1U << i_hash_shift); loop++)
 		INIT_HLIST_HEAD(&inode_hashtable[loop]);
 }
 
 void __init inode_init(void)
 {
-	int loop;
+	unsigned int loop;
 
 	/* inode slab cache */
 	inode_cachep = kmem_cache_create("inode_cache",
@@ -1699,7 +1687,7 @@ void __init inode_init(void)
 					&i_hash_mask,
 					0);
 
-	for (loop = 0; loop < (1 << i_hash_shift); loop++)
+	for (loop = 0; loop < (1U << i_hash_shift); loop++)
 		INIT_HLIST_HEAD(&inode_hashtable[loop]);
 }
 
diff --git a/fs/internal.h b/fs/internal.h
index 9962c59..0765acf 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -56,8 +56,7 @@ extern int sb_prepare_remount_readonly(struct super_block *);
 
 extern void __init mnt_init(void);
 
-DECLARE_BRLOCK(vfsmount_lock);
-
+extern struct lglock vfsmount_lock;
 
 /*
  * fs_struct.c
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index bd62c76..29037c3 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -947,9 +947,8 @@ root_found:
 	s->s_d_op = &isofs_dentry_ops[table];
 
 	/* get the root dentry */
-	s->s_root = d_alloc_root(inode);
+	s->s_root = d_make_root(inode);
 	if (!(s->s_root)) {
-		iput(inode);
 		error = -ENOMEM;
 		goto out_no_inode;
 	}
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 59c09f9..e49e81b 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -328,7 +328,7 @@ repeat:
 		new_offset = offset_in_page(jh2bh(jh_in)->b_data);
 	}
 
-	mapped_data = kmap_atomic(new_page, KM_USER0);
+	mapped_data = kmap_atomic(new_page);
 	/*
 	 * Check for escaping
 	 */
@@ -337,7 +337,7 @@ repeat:
 		need_copy_out = 1;
 		do_escape = 1;
 	}
-	kunmap_atomic(mapped_data, KM_USER0);
+	kunmap_atomic(mapped_data);
 
 	/*
 	 * Do we need to do a data copy?
@@ -354,9 +354,9 @@ repeat:
 		}
 
 		jh_in->b_frozen_data = tmp;
-		mapped_data = kmap_atomic(new_page, KM_USER0);
+		mapped_data = kmap_atomic(new_page);
 		memcpy(tmp, mapped_data + new_offset, jh2bh(jh_in)->b_size);
-		kunmap_atomic(mapped_data, KM_USER0);
+		kunmap_atomic(mapped_data);
 
 		new_page = virt_to_page(tmp);
 		new_offset = offset_in_page(tmp);
@@ -368,9 +368,9 @@ repeat:
 	 * copying, we can finally do so.
 	 */
 	if (do_escape) {
-		mapped_data = kmap_atomic(new_page, KM_USER0);
+		mapped_data = kmap_atomic(new_page);
 		*((unsigned int *)(mapped_data + new_offset)) = 0;
-		kunmap_atomic(mapped_data, KM_USER0);
+		kunmap_atomic(mapped_data);
 	}
 
 	set_bh_page(new_bh, new_page, new_offset);
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 7fce94b..b2a7e52 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -718,9 +718,9 @@ done:
 			    "Possible IO failure.\n");
 		page = jh2bh(jh)->b_page;
 		offset = offset_in_page(jh2bh(jh)->b_data);
-		source = kmap_atomic(page, KM_USER0);
+		source = kmap_atomic(page);
 		memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
-		kunmap_atomic(source, KM_USER0);
+		kunmap_atomic(source);
 	}
 	jbd_unlock_bh_state(bh);
 
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index d49d202..253e918 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -722,7 +722,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
 				    transaction->t_tid, stats);
 
 	__jbd2_journal_drop_transaction(journal, transaction);
-	kfree(transaction);
+	jbd2_journal_free_transaction(transaction);
 
 	/* Just in case anybody was waiting for more transactions to be
            checkpointed... */
@@ -797,5 +797,7 @@ void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transact
 	J_ASSERT(journal->j_committing_transaction != transaction);
 	J_ASSERT(journal->j_running_transaction != transaction);
 
+	trace_jbd2_drop_transaction(journal, transaction);
+
 	jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
 }
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 5069b84..0b5b28f 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -286,10 +286,10 @@ static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh)
 	char *addr;
 	__u32 checksum;
 
-	addr = kmap_atomic(page, KM_USER0);
+	addr = kmap_atomic(page);
 	checksum = crc32_be(crc32_sum,
 		(void *)(addr + offset_in_page(bh->b_data)), bh->b_size);
-	kunmap_atomic(addr, KM_USER0);
+	kunmap_atomic(addr);
 
 	return checksum;
 }
@@ -1048,7 +1048,7 @@ restart_loop:
 	jbd_debug(1, "JBD2: commit %d complete, head %d\n",
 		  journal->j_commit_sequence, journal->j_tail_sequence);
 	if (to_free)
-		kfree(commit_transaction);
+		jbd2_journal_free_transaction(commit_transaction);
 
 	wake_up(&journal->j_wait_done_commit);
 }
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index c0a5f9f..80245c9 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -71,7 +71,6 @@ EXPORT_SYMBOL(jbd2_journal_revoke);
 
 EXPORT_SYMBOL(jbd2_journal_init_dev);
 EXPORT_SYMBOL(jbd2_journal_init_inode);
-EXPORT_SYMBOL(jbd2_journal_update_format);
 EXPORT_SYMBOL(jbd2_journal_check_used_features);
 EXPORT_SYMBOL(jbd2_journal_check_available_features);
 EXPORT_SYMBOL(jbd2_journal_set_features);
@@ -96,7 +95,6 @@ EXPORT_SYMBOL(jbd2_journal_release_jbd_inode);
 EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate);
 EXPORT_SYMBOL(jbd2_inode_cache);
 
-static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 static void __journal_abort_soft (journal_t *journal, int errno);
 static int jbd2_journal_create_slab(size_t slab_size);
 
@@ -345,7 +343,7 @@ repeat:
 		new_offset = offset_in_page(jh2bh(jh_in)->b_data);
 	}
 
-	mapped_data = kmap_atomic(new_page, KM_USER0);
+	mapped_data = kmap_atomic(new_page);
 	/*
 	 * Fire data frozen trigger if data already wasn't frozen.  Do this
 	 * before checking for escaping, as the trigger may modify the magic
@@ -364,7 +362,7 @@ repeat:
 		need_copy_out = 1;
 		do_escape = 1;
 	}
-	kunmap_atomic(mapped_data, KM_USER0);
+	kunmap_atomic(mapped_data);
 
 	/*
 	 * Do we need to do a data copy?
@@ -385,9 +383,9 @@ repeat:
 		}
 
 		jh_in->b_frozen_data = tmp;
-		mapped_data = kmap_atomic(new_page, KM_USER0);
+		mapped_data = kmap_atomic(new_page);
 		memcpy(tmp, mapped_data + new_offset, jh2bh(jh_in)->b_size);
-		kunmap_atomic(mapped_data, KM_USER0);
+		kunmap_atomic(mapped_data);
 
 		new_page = virt_to_page(tmp);
 		new_offset = offset_in_page(tmp);
@@ -406,9 +404,9 @@ repeat:
 	 * copying, we can finally do so.
 	 */
 	if (do_escape) {
-		mapped_data = kmap_atomic(new_page, KM_USER0);
+		mapped_data = kmap_atomic(new_page);
 		*((unsigned int *)(mapped_data + new_offset)) = 0;
-		kunmap_atomic(mapped_data, KM_USER0);
+		kunmap_atomic(mapped_data);
 	}
 
 	set_bh_page(new_bh, new_page, new_offset);
@@ -1185,6 +1183,8 @@ void jbd2_journal_update_superblock(journal_t *journal, int wait)
 	} else
 		write_dirty_buffer(bh, WRITE);
 
+	trace_jbd2_update_superblock_end(journal, wait);
+
 out:
 	/* If we have just flushed the log (by marking s_start==0), then
 	 * any future commit will have to be careful to update the
@@ -1550,61 +1550,6 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat,
 EXPORT_SYMBOL(jbd2_journal_clear_features);
 
 /**
- * int jbd2_journal_update_format () - Update on-disk journal structure.
- * @journal: Journal to act on.
- *
- * Given an initialised but unloaded journal struct, poke about in the
- * on-disk structure to update it to the most recent supported version.
- */
-int jbd2_journal_update_format (journal_t *journal)
-{
-	journal_superblock_t *sb;
-	int err;
-
-	err = journal_get_superblock(journal);
-	if (err)
-		return err;
-
-	sb = journal->j_superblock;
-
-	switch (be32_to_cpu(sb->s_header.h_blocktype)) {
-	case JBD2_SUPERBLOCK_V2:
-		return 0;
-	case JBD2_SUPERBLOCK_V1:
-		return journal_convert_superblock_v1(journal, sb);
-	default:
-		break;
-	}
-	return -EINVAL;
-}
-
-static int journal_convert_superblock_v1(journal_t *journal,
-					 journal_superblock_t *sb)
-{
-	int offset, blocksize;
-	struct buffer_head *bh;
-
-	printk(KERN_WARNING
-		"JBD2: Converting superblock from version 1 to 2.\n");
-
-	/* Pre-initialise new fields to zero */
-	offset = ((char *) &(sb->s_feature_compat)) - ((char *) sb);
-	blocksize = be32_to_cpu(sb->s_blocksize);
-	memset(&sb->s_feature_compat, 0, blocksize-offset);
-
-	sb->s_nr_users = cpu_to_be32(1);
-	sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2);
-	journal->j_format_version = 2;
-
-	bh = journal->j_sb_buffer;
-	BUFFER_TRACE(bh, "marking dirty");
-	mark_buffer_dirty(bh);
-	sync_dirty_buffer(bh);
-	return 0;
-}
-
-
-/**
  * int jbd2_journal_flush () - Flush journal
  * @journal: Journal to act on.
  *
@@ -2015,7 +1960,7 @@ static struct kmem_cache *jbd2_journal_head_cache;
 static atomic_t nr_journal_heads = ATOMIC_INIT(0);
 #endif
 
-static int journal_init_jbd2_journal_head_cache(void)
+static int jbd2_journal_init_journal_head_cache(void)
 {
 	int retval;
 
@@ -2033,7 +1978,7 @@ static int journal_init_jbd2_journal_head_cache(void)
 	return retval;
 }
 
-static void jbd2_journal_destroy_jbd2_journal_head_cache(void)
+static void jbd2_journal_destroy_journal_head_cache(void)
 {
 	if (jbd2_journal_head_cache) {
 		kmem_cache_destroy(jbd2_journal_head_cache);
@@ -2321,7 +2266,7 @@ static void __exit jbd2_remove_jbd_stats_proc_entry(void)
 
 struct kmem_cache *jbd2_handle_cache, *jbd2_inode_cache;
 
-static int __init journal_init_handle_cache(void)
+static int __init jbd2_journal_init_handle_cache(void)
 {
 	jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY);
 	if (jbd2_handle_cache == NULL) {
@@ -2356,17 +2301,20 @@ static int __init journal_init_caches(void)
 
 	ret = jbd2_journal_init_revoke_caches();
 	if (ret == 0)
-		ret = journal_init_jbd2_journal_head_cache();
+		ret = jbd2_journal_init_journal_head_cache();
+	if (ret == 0)
+		ret = jbd2_journal_init_handle_cache();
 	if (ret == 0)
-		ret = journal_init_handle_cache();
+		ret = jbd2_journal_init_transaction_cache();
 	return ret;
 }
 
 static void jbd2_journal_destroy_caches(void)
 {
 	jbd2_journal_destroy_revoke_caches();
-	jbd2_journal_destroy_jbd2_journal_head_cache();
+	jbd2_journal_destroy_journal_head_cache();
 	jbd2_journal_destroy_handle_cache();
+	jbd2_journal_destroy_transaction_cache();
 	jbd2_journal_destroy_slabs();
 }
 
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c
index 30b2867..6973705 100644
--- a/fs/jbd2/revoke.c
+++ b/fs/jbd2/revoke.c
@@ -208,17 +208,13 @@ int __init jbd2_journal_init_revoke_caches(void)
 	J_ASSERT(!jbd2_revoke_record_cache);
 	J_ASSERT(!jbd2_revoke_table_cache);
 
-	jbd2_revoke_record_cache = kmem_cache_create("jbd2_revoke_record",
-					   sizeof(struct jbd2_revoke_record_s),
-					   0,
-					   SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
-					   NULL);
+	jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s,
+					SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY);
 	if (!jbd2_revoke_record_cache)
 		goto record_cache_failure;
 
-	jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table",
-					   sizeof(struct jbd2_revoke_table_s),
-					   0, SLAB_TEMPORARY, NULL);
+	jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s,
+					     SLAB_TEMPORARY);
 	if (!jbd2_revoke_table_cache)
 		goto table_cache_failure;
 	return 0;
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 35ae096..c405017 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -33,6 +33,35 @@
 static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh);
 static void __jbd2_journal_unfile_buffer(struct journal_head *jh);
 
+static struct kmem_cache *transaction_cache;
+int __init jbd2_journal_init_transaction_cache(void)
+{
+	J_ASSERT(!transaction_cache);
+	transaction_cache = kmem_cache_create("jbd2_transaction_s",
+					sizeof(transaction_t),
+					0,
+					SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
+					NULL);
+	if (transaction_cache)
+		return 0;
+	return -ENOMEM;
+}
+
+void jbd2_journal_destroy_transaction_cache(void)
+{
+	if (transaction_cache) {
+		kmem_cache_destroy(transaction_cache);
+		transaction_cache = NULL;
+	}
+}
+
+void jbd2_journal_free_transaction(transaction_t *transaction)
+{
+	if (unlikely(ZERO_OR_NULL_PTR(transaction)))
+		return;
+	kmem_cache_free(transaction_cache, transaction);
+}
+
 /*
  * jbd2_get_transaction: obtain a new transaction_t object.
  *
@@ -133,7 +162,8 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
 
 alloc_transaction:
 	if (!journal->j_running_transaction) {
-		new_transaction = kzalloc(sizeof(*new_transaction), gfp_mask);
+		new_transaction = kmem_cache_alloc(transaction_cache,
+						   gfp_mask | __GFP_ZERO);
 		if (!new_transaction) {
 			/*
 			 * If __GFP_FS is not present, then we may be
@@ -162,7 +192,7 @@ repeat:
 	if (is_journal_aborted(journal) ||
 	    (journal->j_errno != 0 && !(journal->j_flags & JBD2_ACK_ERR))) {
 		read_unlock(&journal->j_state_lock);
-		kfree(new_transaction);
+		jbd2_journal_free_transaction(new_transaction);
 		return -EROFS;
 	}
 
@@ -284,7 +314,7 @@ repeat:
 	read_unlock(&journal->j_state_lock);
 
 	lock_map_acquire(&handle->h_lockdep_map);
-	kfree(new_transaction);
+	jbd2_journal_free_transaction(new_transaction);
 	return 0;
 }
 
@@ -783,12 +813,12 @@ done:
 			    "Possible IO failure.\n");
 		page = jh2bh(jh)->b_page;
 		offset = offset_in_page(jh2bh(jh)->b_data);
-		source = kmap_atomic(page, KM_USER0);
+		source = kmap_atomic(page);
 		/* Fire data frozen trigger just before we copy the data */
 		jbd2_buffer_frozen_trigger(jh, source + offset,
 					   jh->b_triggers);
 		memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
-		kunmap_atomic(source, KM_USER0);
+		kunmap_atomic(source);
 
 		/*
 		 * Now that the frozen data is saved off, we need to store
@@ -1949,6 +1979,8 @@ zap_buffer_unlocked:
 	clear_buffer_mapped(bh);
 	clear_buffer_req(bh);
 	clear_buffer_new(bh);
+	clear_buffer_delay(bh);
+	clear_buffer_unwritten(bh);
 	bh->b_bdev = NULL;
 	return may_free;
 }
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index 5b6c9d1..96ed3c9 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -340,7 +340,7 @@ int jffs2_unregister_compressor(struct jffs2_compressor *comp)
 
 	if (comp->usecount) {
 		spin_unlock(&jffs2_compressor_list_lock);
-		printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n");
+		printk(KERN_WARNING "JFFS2: Compressor module is in use. Unregister failed.\n");
 		return -1;
 	}
 	list_del(&comp->list);
diff --git a/fs/jffs2/compr_lzo.c b/fs/jffs2/compr_lzo.c
index af186ee..c553bd6 100644
--- a/fs/jffs2/compr_lzo.c
+++ b/fs/jffs2/compr_lzo.c
@@ -33,7 +33,6 @@ static int __init alloc_workspace(void)
 	lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE));
 
 	if (!lzo_mem || !lzo_compress_buf) {
-		printk(KERN_WARNING "Failed to allocate lzo deflate workspace\n");
 		free_workspace();
 		return -ENOMEM;
 	}
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 5a00102..4e7a138 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -42,14 +42,12 @@ static int __init alloc_workspaces(void)
 {
 	def_strm.workspace = vmalloc(zlib_deflate_workspacesize(MAX_WBITS,
 							MAX_MEM_LEVEL));
-	if (!def_strm.workspace) {
-		printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL));
+	if (!def_strm.workspace)
 		return -ENOMEM;
-	}
+
 	D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)));
 	inf_strm.workspace = vmalloc(zlib_inflate_workspacesize());
 	if (!inf_strm.workspace) {
-		printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize());
 		vfree(def_strm.workspace);
 		return -ENOMEM;
 	}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 2e01238..c0d5c9d 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -561,9 +561,9 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
 	ret = -ENOMEM;
 
 	D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
-	sb->s_root = d_alloc_root(root_i);
+	sb->s_root = d_make_root(root_i);
 	if (!sb->s_root)
-		goto out_root_i;
+		goto out_root;
 
 	sb->s_maxbytes = 0xFFFFFFFF;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -573,8 +573,6 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
 		jffs2_start_garbage_collect_thread(c);
 	return 0;
 
- out_root_i:
-	iput(root_i);
 out_root:
 	jffs2_free_ino_caches(c);
 	jffs2_free_raw_node_refs(c);
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index ab65ee3..1cd3aec 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -76,7 +76,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
 #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
 
 #define jffs2_flash_write(c, ofs, len, retlen, buf) jffs2_flash_direct_write(c, ofs, len, retlen, buf)
-#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
+#define jffs2_flash_read(c, ofs, len, retlen, buf) (mtd_read((c)->mtd, ofs, len, retlen, buf))
 #define jffs2_flush_wbuf_pad(c) ({ do{} while(0); (void)(c), 0; })
 #define jffs2_flush_wbuf_gc(c, i) ({ do{} while(0); (void)(c), (void) i, 0; })
 #define jffs2_write_nand_badblock(c,jeb,bad_offset) (1)
@@ -108,8 +108,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
 
 #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
 
-#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
-#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf))
 #define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len)
 
 /* wbuf.c */
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index f994648..a06d47a 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -96,18 +96,16 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
 #ifndef __ECOS
 	size_t pointlen, try_size;
 
-	if (c->mtd->point) {
-		ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen,
-				(void **)&flashbuf, NULL);
-		if (!ret && pointlen < c->mtd->size) {
-			/* Don't muck about if it won't let us point to the whole flash */
-			D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
-			mtd_unpoint(c->mtd, 0, pointlen);
-			flashbuf = NULL;
-		}
-		if (ret && ret != -EOPNOTSUPP)
-			D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
+	ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen,
+			(void **)&flashbuf, NULL);
+	if (!ret && pointlen < c->mtd->size) {
+		/* Don't muck about if it won't let us point to the whole flash */
+		D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
+		mtd_unpoint(c->mtd, 0, pointlen);
+		flashbuf = NULL;
 	}
+	if (ret && ret != -EOPNOTSUPP)
+		D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
 #endif
 	if (!flashbuf) {
 		/* For NAND it's quicker to read a whole eraseblock at a time,
@@ -368,7 +366,7 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
 
 	if (jffs2_sum_active())
 		jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset);
-	dbg_xattr("scaning xdatum at %#08x (xid=%u, version=%u)\n",
+	dbg_xattr("scanning xdatum at %#08x (xid=%u, version=%u)\n",
 		  ofs, xd->xid, xd->version);
 	return 0;
 }
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 5f7c160..07c91ca 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -220,12 +220,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
 
 	dquot_initialize(dip);
 
-	/* link count overflow on parent directory ? */
-	if (dip->i_nlink == JFS_LINK_MAX) {
-		rc = -EMLINK;
-		goto out1;
-	}
-
 	/*
 	 * search parent directory for entry/freespace
 	 * (dtSearch() returns parent directory page pinned)
@@ -806,9 +800,6 @@ static int jfs_link(struct dentry *old_dentry,
 	jfs_info("jfs_link: %s %s", old_dentry->d_name.name,
 		 dentry->d_name.name);
 
-	if (ip->i_nlink == JFS_LINK_MAX)
-		return -EMLINK;
-
 	dquot_initialize(dir);
 
 	tid = txBegin(ip->i_sb, 0);
@@ -1138,10 +1129,6 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 				rc = -ENOTEMPTY;
 				goto out3;
 			}
-		} else if ((new_dir != old_dir) &&
-			   (new_dir->i_nlink == JFS_LINK_MAX)) {
-			rc = -EMLINK;
-			goto out3;
 		}
 	} else if (new_ip) {
 		IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL);
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 682bca6..b3bb955 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -441,6 +441,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 		return -ENOMEM;
 
 	sb->s_fs_info = sbi;
+	sb->s_max_links = JFS_LINK_MAX;
 	sbi->sb = sb;
 	sbi->uid = sbi->gid = sbi->umask = -1;
 
@@ -521,7 +522,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 		ret = PTR_ERR(inode);
 		goto out_no_rw;
 	}
-	sb->s_root = d_alloc_root(inode);
+	sb->s_root = d_make_root(inode);
 	if (!sb->s_root)
 		goto out_no_root;
 
@@ -539,7 +540,6 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 
 out_no_root:
 	jfs_err("jfs_read_super: get root dentry failed");
-	iput(inode);
 
 out_no_rw:
 	rc = jfs_umount(sb);
diff --git a/fs/libfs.c b/fs/libfs.c
index 5b2dbb3..7c895a7 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -491,11 +491,9 @@ int simple_fill_super(struct super_block *s, unsigned long magic,
 	inode->i_op = &simple_dir_inode_operations;
 	inode->i_fop = &simple_dir_operations;
 	set_nlink(inode, 2);
-	root = d_alloc_root(inode);
-	if (!root) {
-		iput(inode);
+	root = d_make_root(inode);
+	if (!root)
 		return -ENOMEM;
-	}
 	for (i = 0; !files->name || files->name[0]; i++, files++) {
 		if (!files->name)
 			continue;
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c
index f848b52..3ddcbb1 100644
--- a/fs/lockd/clnt4xdr.c
+++ b/fs/lockd/clnt4xdr.c
@@ -598,7 +598,7 @@ static struct rpc_procinfo	nlm4_procedures[] = {
 	PROC(GRANTED_RES,	res,		norep),
 };
 
-struct rpc_version	nlm_version4 = {
+const struct rpc_version nlm_version4 = {
 	.number		= 4,
 	.nrprocs	= ARRAY_SIZE(nlm4_procedures),
 	.procs		= nlm4_procedures,
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 8d4ea83..ba1dc2e 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -62,7 +62,8 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init)
 
 	host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen,
 				   nlm_init->protocol, nlm_version,
-				   nlm_init->hostname, nlm_init->noresvport);
+				   nlm_init->hostname, nlm_init->noresvport,
+				   nlm_init->net);
 	if (host == NULL) {
 		lockd_down();
 		return ERR_PTR(-ENOLCK);
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c
index 180ac34..3d35e3e 100644
--- a/fs/lockd/clntxdr.c
+++ b/fs/lockd/clntxdr.c
@@ -596,19 +596,19 @@ static struct rpc_procinfo	nlm_procedures[] = {
 	PROC(GRANTED_RES,	res,		norep),
 };
 
-static struct rpc_version	nlm_version1 = {
+static const struct rpc_version	nlm_version1 = {
 		.number		= 1,
 		.nrprocs	= ARRAY_SIZE(nlm_procedures),
 		.procs		= nlm_procedures,
 };
 
-static struct rpc_version	nlm_version3 = {
+static const struct rpc_version	nlm_version3 = {
 		.number		= 3,
 		.nrprocs	= ARRAY_SIZE(nlm_procedures),
 		.procs		= nlm_procedures,
 };
 
-static struct rpc_version	*nlm_versions[] = {
+static const struct rpc_version	*nlm_versions[] = {
 	[1] = &nlm_version1,
 	[3] = &nlm_version3,
 #ifdef CONFIG_LOCKD_V4
@@ -618,7 +618,7 @@ static struct rpc_version	*nlm_versions[] = {
 
 static struct rpc_stat		nlm_rpc_stats;
 
-struct rpc_program		nlm_program = {
+const struct rpc_program	nlm_program = {
 		.name		= "lockd",
 		.number		= NLM_PROGRAM,
 		.nrvers		= ARRAY_SIZE(nlm_versions),
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 6f29836..eb75ca7 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -17,6 +17,8 @@
 #include <linux/lockd/lockd.h>
 #include <linux/mutex.h>
 
+#include <linux/sunrpc/svc_xprt.h>
+
 #include <net/ipv6.h>
 
 #define NLMDBG_FACILITY		NLMDBG_HOSTCACHE
@@ -54,6 +56,7 @@ struct nlm_lookup_host_info {
 	const char		*hostname;	/* remote's hostname */
 	const size_t		hostname_len;	/* it's length */
 	const int		noresvport;	/* use non-priv port */
+	struct net		*net;		/* network namespace to bind */
 };
 
 /*
@@ -155,6 +158,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni,
 	INIT_LIST_HEAD(&host->h_reclaim);
 	host->h_nsmhandle  = nsm;
 	host->h_addrbuf    = nsm->sm_addrbuf;
+	host->net	   = ni->net;
 
 out:
 	return host;
@@ -206,7 +210,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
 				     const unsigned short protocol,
 				     const u32 version,
 				     const char *hostname,
-				     int noresvport)
+				     int noresvport,
+				     struct net *net)
 {
 	struct nlm_lookup_host_info ni = {
 		.server		= 0,
@@ -217,6 +222,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
 		.hostname	= hostname,
 		.hostname_len	= strlen(hostname),
 		.noresvport	= noresvport,
+		.net		= net,
 	};
 	struct hlist_head *chain;
 	struct hlist_node *pos;
@@ -231,6 +237,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap,
 
 	chain = &nlm_client_hosts[nlm_hash_address(sap)];
 	hlist_for_each_entry(host, pos, chain, h_hash) {
+		if (host->net != net)
+			continue;
 		if (!rpc_cmp_addr(nlm_addr(host), sap))
 			continue;
 
@@ -318,6 +326,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
 	struct nsm_handle *nsm = NULL;
 	struct sockaddr *src_sap = svc_daddr(rqstp);
 	size_t src_len = rqstp->rq_daddrlen;
+	struct net *net = rqstp->rq_xprt->xpt_net;
 	struct nlm_lookup_host_info ni = {
 		.server		= 1,
 		.sap		= svc_addr(rqstp),
@@ -326,6 +335,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
 		.version	= rqstp->rq_vers,
 		.hostname	= hostname,
 		.hostname_len	= hostname_len,
+		.net		= net,
 	};
 
 	dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__,
@@ -339,6 +349,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
 
 	chain = &nlm_server_hosts[nlm_hash_address(ni.sap)];
 	hlist_for_each_entry(host, pos, chain, h_hash) {
+		if (host->net != net)
+			continue;
 		if (!rpc_cmp_addr(nlm_addr(host), ni.sap))
 			continue;
 
@@ -431,7 +443,7 @@ nlm_bind_host(struct nlm_host *host)
 			.to_retries	= 5U,
 		};
 		struct rpc_create_args args = {
-			.net		= &init_net,
+			.net		= host->net,
 			.protocol	= host->h_proto,
 			.address	= nlm_addr(host),
 			.addrsize	= host->h_addrlen,
@@ -553,12 +565,8 @@ void nlm_host_rebooted(const struct nlm_reboot *info)
 	nsm_release(nsm);
 }
 
-/*
- * Shut down the hosts module.
- * Note that this routine is called only at server shutdown time.
- */
 void
-nlm_shutdown_hosts(void)
+nlm_shutdown_hosts_net(struct net *net)
 {
 	struct hlist_head *chain;
 	struct hlist_node *pos;
@@ -570,6 +578,8 @@ nlm_shutdown_hosts(void)
 	/* First, make all hosts eligible for gc */
 	dprintk("lockd: nuking all hosts...\n");
 	for_each_host(host, pos, chain, nlm_server_hosts) {
+		if (net && host->net != net)
+			continue;
 		host->h_expires = jiffies - 1;
 		if (host->h_rpcclnt) {
 			rpc_shutdown_client(host->h_rpcclnt);
@@ -580,15 +590,29 @@ nlm_shutdown_hosts(void)
 	/* Then, perform a garbage collection pass */
 	nlm_gc_hosts();
 	mutex_unlock(&nlm_host_mutex);
+}
+
+/*
+ * Shut down the hosts module.
+ * Note that this routine is called only at server shutdown time.
+ */
+void
+nlm_shutdown_hosts(void)
+{
+	struct hlist_head *chain;
+	struct hlist_node *pos;
+	struct nlm_host	*host;
+
+	nlm_shutdown_hosts_net(NULL);
 
 	/* complain if any hosts are left */
 	if (nrhosts != 0) {
 		printk(KERN_WARNING "lockd: couldn't shutdown host module!\n");
 		dprintk("lockd: %lu hosts left:\n", nrhosts);
 		for_each_host(host, pos, chain, nlm_server_hosts) {
-			dprintk("       %s (cnt %d use %d exp %ld)\n",
+			dprintk("       %s (cnt %d use %d exp %ld net %p)\n",
 				host->h_name, atomic_read(&host->h_count),
-				host->h_inuse, host->h_expires);
+				host->h_inuse, host->h_expires, host->net);
 		}
 	}
 }
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 65ba36b..7ef14b3 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -47,7 +47,7 @@ struct nsm_res {
 	u32			state;
 };
 
-static struct rpc_program	nsm_program;
+static const struct rpc_program	nsm_program;
 static				LIST_HEAD(nsm_handles);
 static				DEFINE_SPINLOCK(nsm_lock);
 
@@ -62,14 +62,14 @@ static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm)
 	return (struct sockaddr *)&nsm->sm_addr;
 }
 
-static struct rpc_clnt *nsm_create(void)
+static struct rpc_clnt *nsm_create(struct net *net)
 {
 	struct sockaddr_in sin = {
 		.sin_family		= AF_INET,
 		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
 	};
 	struct rpc_create_args args = {
-		.net			= &init_net,
+		.net			= net,
 		.protocol		= XPRT_TRANSPORT_UDP,
 		.address		= (struct sockaddr *)&sin,
 		.addrsize		= sizeof(sin),
@@ -83,7 +83,8 @@ static struct rpc_clnt *nsm_create(void)
 	return rpc_create(&args);
 }
 
-static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
+static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
+			 struct net *net)
 {
 	struct rpc_clnt	*clnt;
 	int		status;
@@ -99,7 +100,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res)
 		.rpc_resp	= res,
 	};
 
-	clnt = nsm_create();
+	clnt = nsm_create(net);
 	if (IS_ERR(clnt)) {
 		status = PTR_ERR(clnt);
 		dprintk("lockd: failed to create NSM upcall transport, "
@@ -149,7 +150,7 @@ int nsm_monitor(const struct nlm_host *host)
 	 */
 	nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
 
-	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res);
+	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host->net);
 	if (unlikely(res.status != 0))
 		status = -EIO;
 	if (unlikely(status < 0)) {
@@ -183,7 +184,7 @@ void nsm_unmonitor(const struct nlm_host *host)
 	 && nsm->sm_monitored && !nsm->sm_sticky) {
 		dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
 
-		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res);
+		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host->net);
 		if (res.status != 0)
 			status = -EIO;
 		if (status < 0)
@@ -534,19 +535,19 @@ static struct rpc_procinfo	nsm_procedures[] = {
 	},
 };
 
-static struct rpc_version	nsm_version1 = {
+static const struct rpc_version nsm_version1 = {
 		.number		= 1,
 		.nrprocs	= ARRAY_SIZE(nsm_procedures),
 		.procs		= nsm_procedures
 };
 
-static struct rpc_version *	nsm_version[] = {
+static const struct rpc_version *nsm_version[] = {
 	[1] = &nsm_version1,
 };
 
 static struct rpc_stat		nsm_stats;
 
-static struct rpc_program	nsm_program = {
+static const struct rpc_program nsm_program = {
 		.name		= "statd",
 		.number		= NSM_PROGRAM,
 		.nrvers		= ARRAY_SIZE(nsm_version),
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
new file mode 100644
index 0000000..ce227e0
--- /dev/null
+++ b/fs/lockd/netns.h
@@ -0,0 +1,12 @@
+#ifndef __LOCKD_NETNS_H__
+#define __LOCKD_NETNS_H__
+
+#include <net/netns/generic.h>
+
+struct lockd_net {
+	unsigned int nlmsvc_users;
+};
+
+extern int lockd_net_id;
+
+#endif
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index c061b9a..f49b9af 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -35,6 +35,8 @@
 #include <linux/lockd/lockd.h>
 #include <linux/nfs.h>
 
+#include "netns.h"
+
 #define NLMDBG_FACILITY		NLMDBG_SVC
 #define LOCKD_BUFSIZE		(1024 + NLMSVC_XDRSIZE)
 #define ALLOWED_SIGS		(sigmask(SIGKILL))
@@ -50,6 +52,8 @@ static struct task_struct	*nlmsvc_task;
 static struct svc_rqst		*nlmsvc_rqst;
 unsigned long			nlmsvc_timeout;
 
+int lockd_net_id;
+
 /*
  * These can be set at insmod time (useful for NFS as root filesystem),
  * and also changed through the sysctl interface.  -- Jamie Lokier, Aug 2003
@@ -189,27 +193,29 @@ lockd(void *vrqstp)
 }
 
 static int create_lockd_listener(struct svc_serv *serv, const char *name,
-				 const int family, const unsigned short port)
+				 struct net *net, const int family,
+				 const unsigned short port)
 {
 	struct svc_xprt *xprt;
 
-	xprt = svc_find_xprt(serv, name, family, 0);
+	xprt = svc_find_xprt(serv, name, net, family, 0);
 	if (xprt == NULL)
-		return svc_create_xprt(serv, name, &init_net, family, port,
+		return svc_create_xprt(serv, name, net, family, port,
 						SVC_SOCK_DEFAULTS);
 	svc_xprt_put(xprt);
 	return 0;
 }
 
-static int create_lockd_family(struct svc_serv *serv, const int family)
+static int create_lockd_family(struct svc_serv *serv, struct net *net,
+			       const int family)
 {
 	int err;
 
-	err = create_lockd_listener(serv, "udp", family, nlm_udpport);
+	err = create_lockd_listener(serv, "udp", net, family, nlm_udpport);
 	if (err < 0)
 		return err;
 
-	return create_lockd_listener(serv, "tcp", family, nlm_tcpport);
+	return create_lockd_listener(serv, "tcp", net, family, nlm_tcpport);
 }
 
 /*
@@ -222,16 +228,16 @@ static int create_lockd_family(struct svc_serv *serv, const int family)
  * Returns zero if all listeners are available; otherwise a
  * negative errno value is returned.
  */
-static int make_socks(struct svc_serv *serv)
+static int make_socks(struct svc_serv *serv, struct net *net)
 {
 	static int warned;
 	int err;
 
-	err = create_lockd_family(serv, PF_INET);
+	err = create_lockd_family(serv, net, PF_INET);
 	if (err < 0)
 		goto out_err;
 
-	err = create_lockd_family(serv, PF_INET6);
+	err = create_lockd_family(serv, net, PF_INET6);
 	if (err < 0 && err != -EAFNOSUPPORT)
 		goto out_err;
 
@@ -245,6 +251,47 @@ out_err:
 	return err;
 }
 
+static int lockd_up_net(struct net *net)
+{
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
+	struct svc_serv *serv = nlmsvc_rqst->rq_server;
+	int error;
+
+	if (ln->nlmsvc_users)
+		return 0;
+
+	error = svc_rpcb_setup(serv, net);
+	if (error)
+		goto err_rpcb;
+
+	error = make_socks(serv, net);
+	if (error < 0)
+		goto err_socks;
+	return 0;
+
+err_socks:
+	svc_rpcb_cleanup(serv, net);
+err_rpcb:
+	return error;
+}
+
+static void lockd_down_net(struct net *net)
+{
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
+	struct svc_serv *serv = nlmsvc_rqst->rq_server;
+
+	if (ln->nlmsvc_users) {
+		if (--ln->nlmsvc_users == 0) {
+			nlm_shutdown_hosts_net(net);
+			svc_shutdown_net(serv, net);
+		}
+	} else {
+		printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n",
+				nlmsvc_task, net);
+		BUG();
+	}
+}
+
 /*
  * Bring up the lockd process if it's not already up.
  */
@@ -252,13 +299,16 @@ int lockd_up(void)
 {
 	struct svc_serv *serv;
 	int		error = 0;
+	struct net *net = current->nsproxy->net_ns;
 
 	mutex_lock(&nlmsvc_mutex);
 	/*
 	 * Check whether we're already up and running.
 	 */
-	if (nlmsvc_rqst)
+	if (nlmsvc_rqst) {
+		error = lockd_up_net(net);
 		goto out;
+	}
 
 	/*
 	 * Sanity check: if there's no pid,
@@ -275,7 +325,7 @@ int lockd_up(void)
 		goto out;
 	}
 
-	error = make_socks(serv);
+	error = make_socks(serv, net);
 	if (error < 0)
 		goto destroy_and_out;
 
@@ -313,8 +363,12 @@ int lockd_up(void)
 destroy_and_out:
 	svc_destroy(serv);
 out:
-	if (!error)
+	if (!error) {
+		struct lockd_net *ln = net_generic(net, lockd_net_id);
+
+		ln->nlmsvc_users++;
 		nlmsvc_users++;
+	}
 	mutex_unlock(&nlmsvc_mutex);
 	return error;
 }
@@ -328,8 +382,10 @@ lockd_down(void)
 {
 	mutex_lock(&nlmsvc_mutex);
 	if (nlmsvc_users) {
-		if (--nlmsvc_users)
+		if (--nlmsvc_users) {
+			lockd_down_net(current->nsproxy->net_ns);
 			goto out;
+		}
 	} else {
 		printk(KERN_ERR "lockd_down: no users! task=%p\n",
 			nlmsvc_task);
@@ -440,7 +496,7 @@ static int param_set_##name(const char *val, struct kernel_param *kp)	\
 	__typeof__(type) num = which_strtol(val, &endp, 0);		\
 	if (endp == val || *endp || num < (min) || num > (max))		\
 		return -EINVAL;						\
-	*((int *) kp->arg) = num;					\
+	*((type *) kp->arg) = num;					\
 	return 0;							\
 }
 
@@ -497,24 +553,55 @@ module_param_call(nlm_tcpport, param_set_port, param_get_int,
 module_param(nsm_use_hostnames, bool, 0644);
 module_param(nlm_max_connections, uint, 0644);
 
+static int lockd_init_net(struct net *net)
+{
+	return 0;
+}
+
+static void lockd_exit_net(struct net *net)
+{
+}
+
+static struct pernet_operations lockd_net_ops = {
+	.init = lockd_init_net,
+	.exit = lockd_exit_net,
+	.id = &lockd_net_id,
+	.size = sizeof(struct lockd_net),
+};
+
+
 /*
  * Initialising and terminating the module.
  */
 
 static int __init init_nlm(void)
 {
+	int err;
+
 #ifdef CONFIG_SYSCTL
+	err = -ENOMEM;
 	nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
-	return nlm_sysctl_table ? 0 : -ENOMEM;
-#else
+	if (nlm_sysctl_table == NULL)
+		goto err_sysctl;
+#endif
+	err = register_pernet_subsys(&lockd_net_ops);
+	if (err)
+		goto err_pernet;
 	return 0;
+
+err_pernet:
+#ifdef CONFIG_SYSCTL
+	unregister_sysctl_table(nlm_sysctl_table);
 #endif
+err_sysctl:
+	return err;
 }
 
 static void __exit exit_nlm(void)
 {
 	/* FIXME: delete all NLM clients */
 	nlm_shutdown_hosts();
+	unregister_pernet_subsys(&lockd_net_ops);
 #ifdef CONFIG_SYSCTL
 	unregister_sysctl_table(nlm_sysctl_table);
 #endif
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
index 3de7a32..bea5d1b 100644
--- a/fs/logfs/dir.c
+++ b/fs/logfs/dir.c
@@ -177,17 +177,17 @@ static struct page *logfs_get_dd_page(struct inode *dir, struct dentry *dentry)
 				(filler_t *)logfs_readpage, NULL);
 		if (IS_ERR(page))
 			return page;
-		dd = kmap_atomic(page, KM_USER0);
+		dd = kmap_atomic(page);
 		BUG_ON(dd->namelen == 0);
 
 		if (name->len != be16_to_cpu(dd->namelen) ||
 				memcmp(name->name, dd->name, name->len)) {
-			kunmap_atomic(dd, KM_USER0);
+			kunmap_atomic(dd);
 			page_cache_release(page);
 			continue;
 		}
 
-		kunmap_atomic(dd, KM_USER0);
+		kunmap_atomic(dd);
 		return page;
 	}
 	return NULL;
@@ -365,9 +365,9 @@ static struct dentry *logfs_lookup(struct inode *dir, struct dentry *dentry,
 		return NULL;
 	}
 	index = page->index;
-	dd = kmap_atomic(page, KM_USER0);
+	dd = kmap_atomic(page);
 	ino = be64_to_cpu(dd->ino);
-	kunmap_atomic(dd, KM_USER0);
+	kunmap_atomic(dd);
 	page_cache_release(page);
 
 	inode = logfs_iget(dir->i_sb, ino);
@@ -402,12 +402,12 @@ static int logfs_write_dir(struct inode *dir, struct dentry *dentry,
 		if (!page)
 			return -ENOMEM;
 
-		dd = kmap_atomic(page, KM_USER0);
+		dd = kmap_atomic(page);
 		memset(dd, 0, sizeof(*dd));
 		dd->ino = cpu_to_be64(inode->i_ino);
 		dd->type = logfs_type(inode);
 		logfs_set_name(dd, &dentry->d_name);
-		kunmap_atomic(dd, KM_USER0);
+		kunmap_atomic(dd);
 
 		err = logfs_write_buf(dir, page, WF_LOCK);
 		unlock_page(page);
@@ -558,9 +558,6 @@ static int logfs_link(struct dentry *old_dentry, struct inode *dir,
 {
 	struct inode *inode = old_dentry->d_inode;
 
-	if (inode->i_nlink >= LOGFS_LINK_MAX)
-		return -EMLINK;
-
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	ihold(inode);
 	inc_nlink(inode);
@@ -579,9 +576,9 @@ static int logfs_get_dd(struct inode *dir, struct dentry *dentry,
 	if (IS_ERR(page))
 		return PTR_ERR(page);
 	*pos = page->index;
-	map = kmap_atomic(page, KM_USER0);
+	map = kmap_atomic(page);
 	memcpy(dd, map, sizeof(*dd));
-	kunmap_atomic(map, KM_USER0);
+	kunmap_atomic(map);
 	page_cache_release(page);
 	return 0;
 }
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c
index 4153e65..e3ab5e5 100644
--- a/fs/logfs/readwrite.c
+++ b/fs/logfs/readwrite.c
@@ -517,9 +517,9 @@ static int indirect_write_alias(struct super_block *sb,
 
 		ino = page->mapping->host->i_ino;
 		logfs_unpack_index(page->index, &bix, &level);
-		child = kmap_atomic(page, KM_USER0);
+		child = kmap_atomic(page);
 		val = child[pos];
-		kunmap_atomic(child, KM_USER0);
+		kunmap_atomic(child);
 		err = write_one_alias(sb, ino, bix, level, pos, val);
 		if (err)
 			return err;
@@ -673,9 +673,9 @@ static void alloc_indirect_block(struct inode *inode, struct page *page,
 	alloc_data_block(inode, page);
 
 	block = logfs_block(page);
-	array = kmap_atomic(page, KM_USER0);
+	array = kmap_atomic(page);
 	initialize_block_counters(page, block, array, page_is_empty);
-	kunmap_atomic(array, KM_USER0);
+	kunmap_atomic(array);
 }
 
 static void block_set_pointer(struct page *page, int index, u64 ptr)
@@ -685,10 +685,10 @@ static void block_set_pointer(struct page *page, int index, u64 ptr)
 	u64 oldptr;
 
 	BUG_ON(!block);
-	array = kmap_atomic(page, KM_USER0);
+	array = kmap_atomic(page);
 	oldptr = be64_to_cpu(array[index]);
 	array[index] = cpu_to_be64(ptr);
-	kunmap_atomic(array, KM_USER0);
+	kunmap_atomic(array);
 	SetPageUptodate(page);
 
 	block->full += !!(ptr & LOGFS_FULLY_POPULATED)
@@ -701,9 +701,9 @@ static u64 block_get_pointer(struct page *page, int index)
 	__be64 *block;
 	u64 ptr;
 
-	block = kmap_atomic(page, KM_USER0);
+	block = kmap_atomic(page);
 	ptr = be64_to_cpu(block[index]);
-	kunmap_atomic(block, KM_USER0);
+	kunmap_atomic(block);
 	return ptr;
 }
 
@@ -850,7 +850,7 @@ static u64 seek_holedata_loop(struct inode *inode, u64 bix, int data)
 		}
 
 		slot = get_bits(bix, SUBLEVEL(level));
-		rblock = kmap_atomic(page, KM_USER0);
+		rblock = kmap_atomic(page);
 		while (slot < LOGFS_BLOCK_FACTOR) {
 			if (data && (rblock[slot] != 0))
 				break;
@@ -861,12 +861,12 @@ static u64 seek_holedata_loop(struct inode *inode, u64 bix, int data)
 			bix &= ~(increment - 1);
 		}
 		if (slot >= LOGFS_BLOCK_FACTOR) {
-			kunmap_atomic(rblock, KM_USER0);
+			kunmap_atomic(rblock);
 			logfs_put_read_page(page);
 			return bix;
 		}
 		bofs = be64_to_cpu(rblock[slot]);
-		kunmap_atomic(rblock, KM_USER0);
+		kunmap_atomic(rblock);
 		logfs_put_read_page(page);
 		if (!bofs) {
 			BUG_ON(data);
@@ -1961,9 +1961,9 @@ int logfs_read_inode(struct inode *inode)
 	if (IS_ERR(page))
 		return PTR_ERR(page);
 
-	di = kmap_atomic(page, KM_USER0);
+	di = kmap_atomic(page);
 	logfs_disk_to_inode(di, inode);
-	kunmap_atomic(di, KM_USER0);
+	kunmap_atomic(di);
 	move_page_to_inode(inode, page);
 	page_cache_release(page);
 	return 0;
@@ -1982,9 +1982,9 @@ static struct page *inode_to_page(struct inode *inode)
 	if (!page)
 		return NULL;
 
-	di = kmap_atomic(page, KM_USER0);
+	di = kmap_atomic(page);
 	logfs_inode_to_disk(inode, di);
-	kunmap_atomic(di, KM_USER0);
+	kunmap_atomic(di);
 	move_inode_to_page(page, inode);
 	return page;
 }
@@ -2041,13 +2041,13 @@ static void logfs_mod_segment_entry(struct super_block *sb, u32 segno,
 
 	if (write)
 		alloc_indirect_block(inode, page, 0);
-	se = kmap_atomic(page, KM_USER0);
+	se = kmap_atomic(page);
 	change_se(se + child_no, arg);
 	if (write) {
 		logfs_set_alias(sb, logfs_block(page), child_no);
 		BUG_ON((int)be32_to_cpu(se[child_no].valid) > super->s_segsize);
 	}
-	kunmap_atomic(se, KM_USER0);
+	kunmap_atomic(se);
 
 	logfs_put_write_page(page);
 }
@@ -2245,10 +2245,10 @@ int logfs_inode_write(struct inode *inode, const void *buf, size_t count,
 	if (!page)
 		return -ENOMEM;
 
-	pagebuf = kmap_atomic(page, KM_USER0);
+	pagebuf = kmap_atomic(page);
 	memcpy(pagebuf, buf, count);
 	flush_dcache_page(page);
-	kunmap_atomic(pagebuf, KM_USER0);
+	kunmap_atomic(pagebuf);
 
 	if (i_size_read(inode) < pos + LOGFS_BLOCKSIZE)
 		i_size_write(inode, pos + LOGFS_BLOCKSIZE);
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c
index ab798ed..e28d090 100644
--- a/fs/logfs/segment.c
+++ b/fs/logfs/segment.c
@@ -543,9 +543,9 @@ void move_page_to_btree(struct page *page)
 		BUG_ON(!item); /* mempool empty */
 		memset(item, 0, sizeof(*item));
 
-		child = kmap_atomic(page, KM_USER0);
+		child = kmap_atomic(page);
 		item->val = child[pos];
-		kunmap_atomic(child, KM_USER0);
+		kunmap_atomic(child);
 		item->child_no = pos;
 		list_add(&item->list, &block->item_list);
 	}
diff --git a/fs/logfs/super.c b/fs/logfs/super.c
index c9ee7f5..7de18c3 100644
--- a/fs/logfs/super.c
+++ b/fs/logfs/super.c
@@ -315,11 +315,9 @@ static int logfs_get_sb_final(struct super_block *sb)
 	if (IS_ERR(rootdir))
 		goto fail;
 
-	sb->s_root = d_alloc_root(rootdir);
-	if (!sb->s_root) {
-		iput(rootdir);
+	sb->s_root = d_make_root(rootdir);
+	if (!sb->s_root)
 		goto fail;
-	}
 
 	/* at that point we know that ->put_super() will be called */
 	super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
@@ -542,6 +540,7 @@ static struct dentry *logfs_get_sb_device(struct logfs_super *super,
 	 * the filesystem incompatible with 32bit systems.
 	 */
 	sb->s_maxbytes	= (1ull << 43) - 1;
+	sb->s_max_links = LOGFS_LINK_MAX;
 	sb->s_op	= &logfs_super_operations;
 	sb->s_flags	= flags | MS_NOATIME;
 
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 085a926..685b2d9 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -335,7 +335,7 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
 		goto fail;
 	}
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memset(kaddr, 0, PAGE_CACHE_SIZE);
 
 	if (sbi->s_version == MINIX_V3) {
@@ -355,7 +355,7 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
 		de->inode = dir->i_ino;
 		strcpy(de->name, "..");
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
 fail:
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index fa8b612..fcb05d2 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -190,24 +190,24 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 		sbi->s_version = MINIX_V1;
 		sbi->s_dirsize = 16;
 		sbi->s_namelen = 14;
-		sbi->s_link_max = MINIX_LINK_MAX;
+		s->s_max_links = MINIX_LINK_MAX;
 	} else if (s->s_magic == MINIX_SUPER_MAGIC2) {
 		sbi->s_version = MINIX_V1;
 		sbi->s_dirsize = 32;
 		sbi->s_namelen = 30;
-		sbi->s_link_max = MINIX_LINK_MAX;
+		s->s_max_links = MINIX_LINK_MAX;
 	} else if (s->s_magic == MINIX2_SUPER_MAGIC) {
 		sbi->s_version = MINIX_V2;
 		sbi->s_nzones = ms->s_zones;
 		sbi->s_dirsize = 16;
 		sbi->s_namelen = 14;
-		sbi->s_link_max = MINIX2_LINK_MAX;
+		s->s_max_links = MINIX2_LINK_MAX;
 	} else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
 		sbi->s_version = MINIX_V2;
 		sbi->s_nzones = ms->s_zones;
 		sbi->s_dirsize = 32;
 		sbi->s_namelen = 30;
-		sbi->s_link_max = MINIX2_LINK_MAX;
+		s->s_max_links = MINIX2_LINK_MAX;
 	} else if ( *(__u16 *)(bh->b_data + 24) == MINIX3_SUPER_MAGIC) {
 		m3s = (struct minix3_super_block *) bh->b_data;
 		s->s_magic = m3s->s_magic;
@@ -221,9 +221,9 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 		sbi->s_dirsize = 64;
 		sbi->s_namelen = 60;
 		sbi->s_version = MINIX_V3;
-		sbi->s_link_max = MINIX2_LINK_MAX;
 		sbi->s_mount_state = MINIX_VALID_FS;
 		sb_set_blocksize(s, m3s->s_blocksize);
+		s->s_max_links = MINIX2_LINK_MAX;
 	} else
 		goto out_no_fs;
 
@@ -254,14 +254,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 	minix_set_bit(0,sbi->s_imap[0]->b_data);
 	minix_set_bit(0,sbi->s_zmap[0]->b_data);
 
-	/* set up enough so that it can read an inode */
-	s->s_op = &minix_sops;
-	root_inode = minix_iget(s, MINIX_ROOT_INO);
-	if (IS_ERR(root_inode)) {
-		ret = PTR_ERR(root_inode);
-		goto out_no_root;
-	}
-
 	/* Apparently minix can create filesystems that allocate more blocks for
 	 * the bitmaps than needed.  We simply ignore that, but verify it didn't
 	 * create one with not enough blocks and bail out if so.
@@ -270,7 +262,7 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 	if (sbi->s_imap_blocks < block) {
 		printk("MINIX-fs: file system does not have enough "
 				"imap blocks allocated.  Refusing to mount\n");
-		goto out_iput;
+		goto out_no_bitmap;
 	}
 
 	block = minix_blocks_needed(
@@ -279,13 +271,21 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 	if (sbi->s_zmap_blocks < block) {
 		printk("MINIX-fs: file system does not have enough "
 				"zmap blocks allocated.  Refusing to mount.\n");
-		goto out_iput;
+		goto out_no_bitmap;
+	}
+
+	/* set up enough so that it can read an inode */
+	s->s_op = &minix_sops;
+	root_inode = minix_iget(s, MINIX_ROOT_INO);
+	if (IS_ERR(root_inode)) {
+		ret = PTR_ERR(root_inode);
+		goto out_no_root;
 	}
 
 	ret = -ENOMEM;
-	s->s_root = d_alloc_root(root_inode);
+	s->s_root = d_make_root(root_inode);
 	if (!s->s_root)
-		goto out_iput;
+		goto out_no_root;
 
 	if (!(s->s_flags & MS_RDONLY)) {
 		if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */
@@ -301,10 +301,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
 
 	return 0;
 
-out_iput:
-	iput(root_inode);
-	goto out_freemap;
-
 out_no_root:
 	if (!silent)
 		printk("MINIX-fs: get root inode failed\n");
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index c889ef0..1ebd118 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -34,7 +34,6 @@ struct minix_sb_info {
 	unsigned long s_max_size;
 	int s_dirsize;
 	int s_namelen;
-	int s_link_max;
 	struct buffer_head ** s_imap;
 	struct buffer_head ** s_zmap;
 	struct buffer_head * s_sbh;
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index 2f76e38..2d0ee17 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -94,9 +94,6 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
 {
 	struct inode *inode = old_dentry->d_inode;
 
-	if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max)
-		return -EMLINK;
-
 	inode->i_ctime = CURRENT_TIME_SEC;
 	inode_inc_link_count(inode);
 	ihold(inode);
@@ -106,10 +103,7 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
 static int minix_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode)
 {
 	struct inode * inode;
-	int err = -EMLINK;
-
-	if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max)
-		goto out;
+	int err;
 
 	inode_inc_link_count(dir);
 
@@ -181,7 +175,6 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
 static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
 			   struct inode * new_dir, struct dentry *new_dentry)
 {
-	struct minix_sb_info * info = minix_sb(old_dir->i_sb);
 	struct inode * old_inode = old_dentry->d_inode;
 	struct inode * new_inode = new_dentry->d_inode;
 	struct page * dir_page = NULL;
@@ -219,11 +212,6 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
 			drop_nlink(new_inode);
 		inode_dec_link_count(new_inode);
 	} else {
-		if (dir_de) {
-			err = -EMLINK;
-			if (new_dir->i_nlink >= info->s_link_max)
-				goto out_dir;
-		}
 		err = minix_add_link(new_dentry, old_inode);
 		if (err)
 			goto out_dir;
diff --git a/fs/namei.c b/fs/namei.c
index 208c6aa..5d1fab5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -462,7 +462,7 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry)
 	mntget(nd->path.mnt);
 
 	rcu_read_unlock();
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 	nd->flags &= ~LOOKUP_RCU;
 	return 0;
 
@@ -520,14 +520,14 @@ static int complete_walk(struct nameidata *nd)
 		if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) {
 			spin_unlock(&dentry->d_lock);
 			rcu_read_unlock();
-			br_read_unlock(vfsmount_lock);
+			br_read_unlock(&vfsmount_lock);
 			return -ECHILD;
 		}
 		BUG_ON(nd->inode != dentry->d_inode);
 		spin_unlock(&dentry->d_lock);
 		mntget(nd->path.mnt);
 		rcu_read_unlock();
-		br_read_unlock(vfsmount_lock);
+		br_read_unlock(&vfsmount_lock);
 	}
 
 	if (likely(!(nd->flags & LOOKUP_JUMPED)))
@@ -694,15 +694,15 @@ int follow_up(struct path *path)
 	struct mount *parent;
 	struct dentry *mountpoint;
 
-	br_read_lock(vfsmount_lock);
+	br_read_lock(&vfsmount_lock);
 	parent = mnt->mnt_parent;
 	if (&parent->mnt == path->mnt) {
-		br_read_unlock(vfsmount_lock);
+		br_read_unlock(&vfsmount_lock);
 		return 0;
 	}
 	mntget(&parent->mnt);
 	mountpoint = dget(mnt->mnt_mountpoint);
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 	dput(path->dentry);
 	path->dentry = mountpoint;
 	mntput(path->mnt);
@@ -960,7 +960,7 @@ failed:
 	if (!(nd->flags & LOOKUP_ROOT))
 		nd->root.mnt = NULL;
 	rcu_read_unlock();
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 	return -ECHILD;
 }
 
@@ -1095,8 +1095,10 @@ static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentr
 	struct dentry *old;
 
 	/* Don't create child dentry for a dead directory. */
-	if (unlikely(IS_DEADDIR(inode)))
+	if (unlikely(IS_DEADDIR(inode))) {
+		dput(dentry);
 		return ERR_PTR(-ENOENT);
+	}
 
 	old = inode->i_op->lookup(inode, dentry, nd);
 	if (unlikely(old)) {
@@ -1254,7 +1256,7 @@ static void terminate_walk(struct nameidata *nd)
 		if (!(nd->flags & LOOKUP_ROOT))
 			nd->root.mnt = NULL;
 		rcu_read_unlock();
-		br_read_unlock(vfsmount_lock);
+		br_read_unlock(&vfsmount_lock);
 	}
 }
 
@@ -1488,7 +1490,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
 		nd->path = nd->root;
 		nd->inode = inode;
 		if (flags & LOOKUP_RCU) {
-			br_read_lock(vfsmount_lock);
+			br_read_lock(&vfsmount_lock);
 			rcu_read_lock();
 			nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
 		} else {
@@ -1501,7 +1503,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
 
 	if (*name=='/') {
 		if (flags & LOOKUP_RCU) {
-			br_read_lock(vfsmount_lock);
+			br_read_lock(&vfsmount_lock);
 			rcu_read_lock();
 			set_root_rcu(nd);
 		} else {
@@ -1514,7 +1516,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
 			struct fs_struct *fs = current->fs;
 			unsigned seq;
 
-			br_read_lock(vfsmount_lock);
+			br_read_lock(&vfsmount_lock);
 			rcu_read_lock();
 
 			do {
@@ -1550,7 +1552,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
 			if (fput_needed)
 				*fp = file;
 			nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
-			br_read_lock(vfsmount_lock);
+			br_read_lock(&vfsmount_lock);
 			rcu_read_lock();
 		} else {
 			path_get(&file->f_path);
@@ -2545,6 +2547,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d
 int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 {
 	int error = may_create(dir, dentry);
+	unsigned max_links = dir->i_sb->s_max_links;
 
 	if (error)
 		return error;
@@ -2557,6 +2560,9 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	if (error)
 		return error;
 
+	if (max_links && dir->i_nlink >= max_links)
+		return -EMLINK;
+
 	error = dir->i_op->mkdir(dir, dentry, mode);
 	if (!error)
 		fsnotify_mkdir(dir, dentry);
@@ -2887,6 +2893,7 @@ SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newn
 int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
 {
 	struct inode *inode = old_dentry->d_inode;
+	unsigned max_links = dir->i_sb->s_max_links;
 	int error;
 
 	if (!inode)
@@ -2917,6 +2924,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
 	/* Make sure we don't allow creating hardlink to an unlinked file */
 	if (inode->i_nlink == 0)
 		error =  -ENOENT;
+	else if (max_links && inode->i_nlink >= max_links)
+		error = -EMLINK;
 	else
 		error = dir->i_op->link(old_dentry, dir, new_dentry);
 	mutex_unlock(&inode->i_mutex);
@@ -3026,6 +3035,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
 {
 	int error = 0;
 	struct inode *target = new_dentry->d_inode;
+	unsigned max_links = new_dir->i_sb->s_max_links;
 
 	/*
 	 * If we are going to change the parent - check write permissions,
@@ -3049,6 +3059,11 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
 	if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry))
 		goto out;
 
+	error = -EMLINK;
+	if (max_links && !target && new_dir != old_dir &&
+	    new_dir->i_nlink >= max_links)
+		goto out;
+
 	if (target)
 		shrink_dcache_parent(new_dentry);
 	error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
@@ -3347,9 +3362,9 @@ retry:
 	if (err)
 		goto fail;
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memcpy(kaddr, symname, len-1);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
 							page, fsdata);
diff --git a/fs/namespace.c b/fs/namespace.c
index e608199..5a6208b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -397,7 +397,7 @@ static int mnt_make_readonly(struct mount *mnt)
 {
 	int ret = 0;
 
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	mnt->mnt.mnt_flags |= MNT_WRITE_HOLD;
 	/*
 	 * After storing MNT_WRITE_HOLD, we'll read the counters. This store
@@ -431,15 +431,15 @@ static int mnt_make_readonly(struct mount *mnt)
 	 */
 	smp_wmb();
 	mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	return ret;
 }
 
 static void __mnt_unmake_readonly(struct mount *mnt)
 {
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	mnt->mnt.mnt_flags &= ~MNT_READONLY;
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 }
 
 int sb_prepare_remount_readonly(struct super_block *sb)
@@ -451,7 +451,7 @@ int sb_prepare_remount_readonly(struct super_block *sb)
 	if (atomic_long_read(&sb->s_remove_count))
 		return -EBUSY;
 
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) {
 		if (!(mnt->mnt.mnt_flags & MNT_READONLY)) {
 			mnt->mnt.mnt_flags |= MNT_WRITE_HOLD;
@@ -473,7 +473,7 @@ int sb_prepare_remount_readonly(struct super_block *sb)
 		if (mnt->mnt.mnt_flags & MNT_WRITE_HOLD)
 			mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 
 	return err;
 }
@@ -522,14 +522,14 @@ struct vfsmount *lookup_mnt(struct path *path)
 {
 	struct mount *child_mnt;
 
-	br_read_lock(vfsmount_lock);
+	br_read_lock(&vfsmount_lock);
 	child_mnt = __lookup_mnt(path->mnt, path->dentry, 1);
 	if (child_mnt) {
 		mnt_add_count(child_mnt, 1);
-		br_read_unlock(vfsmount_lock);
+		br_read_unlock(&vfsmount_lock);
 		return &child_mnt->mnt;
 	} else {
-		br_read_unlock(vfsmount_lock);
+		br_read_unlock(&vfsmount_lock);
 		return NULL;
 	}
 }
@@ -714,9 +714,9 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
 	mnt->mnt.mnt_sb = root->d_sb;
 	mnt->mnt_mountpoint = mnt->mnt.mnt_root;
 	mnt->mnt_parent = mnt;
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	list_add_tail(&mnt->mnt_instance, &root->d_sb->s_mounts);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	return &mnt->mnt;
 }
 EXPORT_SYMBOL_GPL(vfs_kern_mount);
@@ -745,9 +745,9 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
 		mnt->mnt.mnt_root = dget(root);
 		mnt->mnt_mountpoint = mnt->mnt.mnt_root;
 		mnt->mnt_parent = mnt;
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 
 		if (flag & CL_SLAVE) {
 			list_add(&mnt->mnt_slave, &old->mnt_slave_list);
@@ -803,35 +803,36 @@ static void mntput_no_expire(struct mount *mnt)
 {
 put_again:
 #ifdef CONFIG_SMP
-	br_read_lock(vfsmount_lock);
+	br_read_lock(&vfsmount_lock);
 	if (likely(atomic_read(&mnt->mnt_longterm))) {
 		mnt_add_count(mnt, -1);
-		br_read_unlock(vfsmount_lock);
+		br_read_unlock(&vfsmount_lock);
 		return;
 	}
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	mnt_add_count(mnt, -1);
 	if (mnt_get_count(mnt)) {
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 		return;
 	}
 #else
 	mnt_add_count(mnt, -1);
 	if (likely(mnt_get_count(mnt)))
 		return;
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 #endif
 	if (unlikely(mnt->mnt_pinned)) {
 		mnt_add_count(mnt, mnt->mnt_pinned + 1);
 		mnt->mnt_pinned = 0;
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 		acct_auto_close_mnt(&mnt->mnt);
 		goto put_again;
 	}
+
 	list_del(&mnt->mnt_instance);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	mntfree(mnt);
 }
 
@@ -857,21 +858,21 @@ EXPORT_SYMBOL(mntget);
 
 void mnt_pin(struct vfsmount *mnt)
 {
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	real_mount(mnt)->mnt_pinned++;
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 }
 EXPORT_SYMBOL(mnt_pin);
 
 void mnt_unpin(struct vfsmount *m)
 {
 	struct mount *mnt = real_mount(m);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	if (mnt->mnt_pinned) {
 		mnt_add_count(mnt, 1);
 		mnt->mnt_pinned--;
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 }
 EXPORT_SYMBOL(mnt_unpin);
 
@@ -988,12 +989,12 @@ int may_umount_tree(struct vfsmount *m)
 	BUG_ON(!m);
 
 	/* write lock needed for mnt_get_count */
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	for (p = mnt; p; p = next_mnt(p, mnt)) {
 		actual_refs += mnt_get_count(p);
 		minimum_refs += 2;
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 
 	if (actual_refs > minimum_refs)
 		return 0;
@@ -1020,10 +1021,10 @@ int may_umount(struct vfsmount *mnt)
 {
 	int ret = 1;
 	down_read(&namespace_sem);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	if (propagate_mount_busy(real_mount(mnt), 2))
 		ret = 0;
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	up_read(&namespace_sem);
 	return ret;
 }
@@ -1040,13 +1041,13 @@ void release_mounts(struct list_head *head)
 			struct dentry *dentry;
 			struct mount *m;
 
-			br_write_lock(vfsmount_lock);
+			br_write_lock(&vfsmount_lock);
 			dentry = mnt->mnt_mountpoint;
 			m = mnt->mnt_parent;
 			mnt->mnt_mountpoint = mnt->mnt.mnt_root;
 			mnt->mnt_parent = mnt;
 			m->mnt_ghosts--;
-			br_write_unlock(vfsmount_lock);
+			br_write_unlock(&vfsmount_lock);
 			dput(dentry);
 			mntput(&m->mnt);
 		}
@@ -1112,12 +1113,12 @@ static int do_umount(struct mount *mnt, int flags)
 		 * probably don't strictly need the lock here if we examined
 		 * all race cases, but it's a slowpath.
 		 */
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		if (mnt_get_count(mnt) != 2) {
-			br_write_unlock(vfsmount_lock);
+			br_write_unlock(&vfsmount_lock);
 			return -EBUSY;
 		}
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 
 		if (!xchg(&mnt->mnt_expiry_mark, 1))
 			return -EAGAIN;
@@ -1159,7 +1160,7 @@ static int do_umount(struct mount *mnt, int flags)
 	}
 
 	down_write(&namespace_sem);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	event++;
 
 	if (!(flags & MNT_DETACH))
@@ -1171,7 +1172,7 @@ static int do_umount(struct mount *mnt, int flags)
 			umount_tree(mnt, 1, &umount_list);
 		retval = 0;
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	up_write(&namespace_sem);
 	release_mounts(&umount_list);
 	return retval;
@@ -1286,19 +1287,19 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
 			q = clone_mnt(p, p->mnt.mnt_root, flag);
 			if (!q)
 				goto Enomem;
-			br_write_lock(vfsmount_lock);
+			br_write_lock(&vfsmount_lock);
 			list_add_tail(&q->mnt_list, &res->mnt_list);
 			attach_mnt(q, &path);
-			br_write_unlock(vfsmount_lock);
+			br_write_unlock(&vfsmount_lock);
 		}
 	}
 	return res;
 Enomem:
 	if (res) {
 		LIST_HEAD(umount_list);
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		umount_tree(res, 0, &umount_list);
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 		release_mounts(&umount_list);
 	}
 	return NULL;
@@ -1318,9 +1319,9 @@ void drop_collected_mounts(struct vfsmount *mnt)
 {
 	LIST_HEAD(umount_list);
 	down_write(&namespace_sem);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	umount_tree(real_mount(mnt), 0, &umount_list);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	up_write(&namespace_sem);
 	release_mounts(&umount_list);
 }
@@ -1448,7 +1449,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
 	if (err)
 		goto out_cleanup_ids;
 
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 
 	if (IS_MNT_SHARED(dest_mnt)) {
 		for (p = source_mnt; p; p = next_mnt(p, source_mnt))
@@ -1467,7 +1468,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
 		list_del_init(&child->mnt_hash);
 		commit_tree(child);
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 
 	return 0;
 
@@ -1565,10 +1566,10 @@ static int do_change_type(struct path *path, int flag)
 			goto out_unlock;
 	}
 
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
 		change_mnt_propagation(m, type);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 
  out_unlock:
 	up_write(&namespace_sem);
@@ -1617,9 +1618,9 @@ static int do_loopback(struct path *path, char *old_name,
 
 	err = graft_tree(mnt, path);
 	if (err) {
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		umount_tree(mnt, 0, &umount_list);
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 	}
 out2:
 	unlock_mount(path);
@@ -1677,16 +1678,16 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
 	else
 		err = do_remount_sb(sb, flags, data, 0);
 	if (!err) {
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK;
 		mnt->mnt.mnt_flags = mnt_flags;
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 	}
 	up_write(&sb->s_umount);
 	if (!err) {
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		touch_mnt_namespace(mnt->mnt_ns);
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 	}
 	return err;
 }
@@ -1893,9 +1894,9 @@ fail:
 	/* remove m from any expiration list it may be on */
 	if (!list_empty(&mnt->mnt_expire)) {
 		down_write(&namespace_sem);
-		br_write_lock(vfsmount_lock);
+		br_write_lock(&vfsmount_lock);
 		list_del_init(&mnt->mnt_expire);
-		br_write_unlock(vfsmount_lock);
+		br_write_unlock(&vfsmount_lock);
 		up_write(&namespace_sem);
 	}
 	mntput(m);
@@ -1911,11 +1912,11 @@ fail:
 void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list)
 {
 	down_write(&namespace_sem);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 
 	list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list);
 
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	up_write(&namespace_sem);
 }
 EXPORT_SYMBOL(mnt_set_expiry);
@@ -1935,7 +1936,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
 		return;
 
 	down_write(&namespace_sem);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 
 	/* extract from the expiration list every vfsmount that matches the
 	 * following criteria:
@@ -1954,7 +1955,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
 		touch_mnt_namespace(mnt->mnt_ns);
 		umount_tree(mnt, 1, &umounts);
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	up_write(&namespace_sem);
 
 	release_mounts(&umounts);
@@ -2218,9 +2219,9 @@ void mnt_make_shortterm(struct vfsmount *m)
 	struct mount *mnt = real_mount(m);
 	if (atomic_add_unless(&mnt->mnt_longterm, -1, 1))
 		return;
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	atomic_dec(&mnt->mnt_longterm);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 #endif
 }
 
@@ -2249,10 +2250,9 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
 		kfree(new_ns);
 		return ERR_PTR(-ENOMEM);
 	}
-	new_ns->root = new;
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	list_add_tail(&new_ns->list, &new->mnt_list);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 
 	/*
 	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
@@ -2416,9 +2416,9 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry,
 int path_is_under(struct path *path1, struct path *path2)
 {
 	int res;
-	br_read_lock(vfsmount_lock);
+	br_read_lock(&vfsmount_lock);
 	res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 	return res;
 }
 EXPORT_SYMBOL(path_is_under);
@@ -2505,7 +2505,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
 	/* make sure we can reach put_old from new_root */
 	if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new))
 		goto out4;
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	detach_mnt(new_mnt, &parent_path);
 	detach_mnt(root_mnt, &root_parent);
 	/* mount old root on put_old */
@@ -2513,7 +2513,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
 	/* mount new_root on / */
 	attach_mnt(new_mnt, &root_parent);
 	touch_mnt_namespace(current->nsproxy->mnt_ns);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	chroot_fs_refs(&root, &new);
 	error = 0;
 out4:
@@ -2576,7 +2576,7 @@ void __init mnt_init(void)
 	for (u = 0; u < HASH_SIZE; u++)
 		INIT_LIST_HEAD(&mount_hashtable[u]);
 
-	br_lock_init(vfsmount_lock);
+	br_lock_init(&vfsmount_lock);
 
 	err = sysfs_init();
 	if (err)
@@ -2596,9 +2596,9 @@ void put_mnt_ns(struct mnt_namespace *ns)
 	if (!atomic_dec_and_test(&ns->count))
 		return;
 	down_write(&namespace_sem);
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	umount_tree(ns->root, 0, &umount_list);
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	up_write(&namespace_sem);
 	release_mounts(&umount_list);
 	kfree(ns);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 3d1e34f..49df0e7 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -716,13 +716,11 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
         if (!root_inode)
 		goto out_disconnect;
 	DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
         if (!sb->s_root)
-		goto out_no_root;
+		goto out_disconnect;
 	return 0;
 
-out_no_root:
-	iput(root_inode);
 out_disconnect:
 	ncp_lock_server(server);
 	ncp_disconnect(server);
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index dbcd821..ee86cfc 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -64,6 +64,7 @@ config NFS_V4
 	bool "NFS client support for NFS version 4"
 	depends on NFS_FS
 	select SUNRPC_GSS
+	select KEYS
 	help
 	  This option enables support for version 4 of the NFS protocol
 	  (RFC 3530) in the kernel's NFS client.
@@ -130,16 +131,4 @@ config NFS_USE_KERNEL_DNS
 	bool
 	depends on NFS_V4 && !NFS_USE_LEGACY_DNS
 	select DNS_RESOLVER
-	select KEYS
 	default y
-
-config NFS_USE_NEW_IDMAPPER
-	bool "Use the new idmapper upcall routine"
-	depends on NFS_V4 && KEYS
-	help
-	  Say Y here if you want NFS to use the new idmapper upcall functions.
-	  You will need /sbin/request-key (usually provided by the keyutils
-	  package).  For details, read
-	  <file:Documentation/filesystems/nfs/idmapper.txt>.
-
-	  If you are unsure, say N.
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 48cfac3..783ebd5 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -46,7 +46,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Andy Adamson <andros@citi.umich.edu>");
 MODULE_DESCRIPTION("The NFSv4.1 pNFS Block layout driver");
 
-struct dentry *bl_device_pipe;
 wait_queue_head_t bl_wq;
 
 static void print_page(struct page *page)
@@ -1025,10 +1024,127 @@ static const struct rpc_pipe_ops bl_upcall_ops = {
 	.destroy_msg	= bl_pipe_destroy_msg,
 };
 
+static struct dentry *nfs4blocklayout_register_sb(struct super_block *sb,
+					    struct rpc_pipe *pipe)
+{
+	struct dentry *dir, *dentry;
+
+	dir = rpc_d_lookup_sb(sb, NFS_PIPE_DIRNAME);
+	if (dir == NULL)
+		return ERR_PTR(-ENOENT);
+	dentry = rpc_mkpipe_dentry(dir, "blocklayout", NULL, pipe);
+	dput(dir);
+	return dentry;
+}
+
+static void nfs4blocklayout_unregister_sb(struct super_block *sb,
+					  struct rpc_pipe *pipe)
+{
+	if (pipe->dentry)
+		rpc_unlink(pipe->dentry);
+}
+
+static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
+			   void *ptr)
+{
+	struct super_block *sb = ptr;
+	struct net *net = sb->s_fs_info;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+	struct dentry *dentry;
+	int ret = 0;
+
+	if (!try_module_get(THIS_MODULE))
+		return 0;
+
+	if (nn->bl_device_pipe == NULL) {
+		module_put(THIS_MODULE);
+		return 0;
+	}
+
+	switch (event) {
+	case RPC_PIPEFS_MOUNT:
+		dentry = nfs4blocklayout_register_sb(sb, nn->bl_device_pipe);
+		if (IS_ERR(dentry)) {
+			ret = PTR_ERR(dentry);
+			break;
+		}
+		nn->bl_device_pipe->dentry = dentry;
+		break;
+	case RPC_PIPEFS_UMOUNT:
+		if (nn->bl_device_pipe->dentry)
+			nfs4blocklayout_unregister_sb(sb, nn->bl_device_pipe);
+		break;
+	default:
+		ret = -ENOTSUPP;
+		break;
+	}
+	module_put(THIS_MODULE);
+	return ret;
+}
+
+static struct notifier_block nfs4blocklayout_block = {
+	.notifier_call = rpc_pipefs_event,
+};
+
+static struct dentry *nfs4blocklayout_register_net(struct net *net,
+						   struct rpc_pipe *pipe)
+{
+	struct super_block *pipefs_sb;
+	struct dentry *dentry;
+
+	pipefs_sb = rpc_get_sb_net(net);
+	if (!pipefs_sb)
+		return NULL;
+	dentry = nfs4blocklayout_register_sb(pipefs_sb, pipe);
+	rpc_put_sb_net(net);
+	return dentry;
+}
+
+static void nfs4blocklayout_unregister_net(struct net *net,
+					   struct rpc_pipe *pipe)
+{
+	struct super_block *pipefs_sb;
+
+	pipefs_sb = rpc_get_sb_net(net);
+	if (pipefs_sb) {
+		nfs4blocklayout_unregister_sb(pipefs_sb, pipe);
+		rpc_put_sb_net(net);
+	}
+}
+
+static int nfs4blocklayout_net_init(struct net *net)
+{
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+	struct dentry *dentry;
+
+	nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0);
+	if (IS_ERR(nn->bl_device_pipe))
+		return PTR_ERR(nn->bl_device_pipe);
+	dentry = nfs4blocklayout_register_net(net, nn->bl_device_pipe);
+	if (IS_ERR(dentry)) {
+		rpc_destroy_pipe_data(nn->bl_device_pipe);
+		return PTR_ERR(dentry);
+	}
+	nn->bl_device_pipe->dentry = dentry;
+	return 0;
+}
+
+static void nfs4blocklayout_net_exit(struct net *net)
+{
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+	nfs4blocklayout_unregister_net(net, nn->bl_device_pipe);
+	rpc_destroy_pipe_data(nn->bl_device_pipe);
+	nn->bl_device_pipe = NULL;
+}
+
+static struct pernet_operations nfs4blocklayout_net_ops = {
+	.init = nfs4blocklayout_net_init,
+	.exit = nfs4blocklayout_net_exit,
+};
+
 static int __init nfs4blocklayout_init(void)
 {
-	struct vfsmount *mnt;
-	struct path path;
 	int ret;
 
 	dprintk("%s: NFSv4 Block Layout Driver Registering...\n", __func__);
@@ -1038,31 +1154,17 @@ static int __init nfs4blocklayout_init(void)
 		goto out;
 
 	init_waitqueue_head(&bl_wq);
-
-	mnt = rpc_get_mount();
-	if (IS_ERR(mnt)) {
-		ret = PTR_ERR(mnt);
+	ret = rpc_pipefs_notifier_register(&nfs4blocklayout_block);
+	if (ret)
 		goto out_remove;
-	}
-
-	ret = vfs_path_lookup(mnt->mnt_root,
-			      mnt,
-			      NFS_PIPE_DIRNAME, 0, &path);
+	ret = register_pernet_subsys(&nfs4blocklayout_net_ops);
 	if (ret)
-		goto out_putrpc;
-
-	bl_device_pipe = rpc_mkpipe(path.dentry, "blocklayout", NULL,
-				    &bl_upcall_ops, 0);
-	path_put(&path);
-	if (IS_ERR(bl_device_pipe)) {
-		ret = PTR_ERR(bl_device_pipe);
-		goto out_putrpc;
-	}
+		goto out_notifier;
 out:
 	return ret;
 
-out_putrpc:
-	rpc_put_mount();
+out_notifier:
+	rpc_pipefs_notifier_unregister(&nfs4blocklayout_block);
 out_remove:
 	pnfs_unregister_layoutdriver(&blocklayout_type);
 	return ret;
@@ -1073,9 +1175,9 @@ static void __exit nfs4blocklayout_exit(void)
 	dprintk("%s: NFSv4 Block Layout Driver Unregistering...\n",
 	       __func__);
 
+	rpc_pipefs_notifier_unregister(&nfs4blocklayout_block);
+	unregister_pernet_subsys(&nfs4blocklayout_net_ops);
 	pnfs_unregister_layoutdriver(&blocklayout_type);
-	rpc_unlink(bl_device_pipe);
-	rpc_put_mount();
 }
 
 MODULE_ALIAS("nfs-layouttype4-3");
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index e31a2df..0966b39 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -37,6 +37,7 @@
 #include <linux/sunrpc/rpc_pipe_fs.h>
 
 #include "../pnfs.h"
+#include "../netns.h"
 
 #define PAGE_CACHE_SECTORS (PAGE_CACHE_SIZE >> SECTOR_SHIFT)
 #define PAGE_CACHE_SECTOR_SHIFT (PAGE_CACHE_SHIFT - SECTOR_SHIFT)
@@ -50,6 +51,7 @@ struct pnfs_block_dev {
 	struct list_head		bm_node;
 	struct nfs4_deviceid		bm_mdevid;    /* associated devid */
 	struct block_device		*bm_mdev;     /* meta device itself */
+	struct net			*net;
 };
 
 enum exstate4 {
@@ -161,7 +163,6 @@ struct bl_msg_hdr {
 	u16 totallen; /* length of entire message, including hdr itself */
 };
 
-extern struct dentry *bl_device_pipe;
 extern wait_queue_head_t bl_wq;
 
 #define BL_DEVICE_UMOUNT               0x0 /* Umount--delete devices */
diff --git a/fs/nfs/blocklayout/blocklayoutdev.c b/fs/nfs/blocklayout/blocklayoutdev.c
index d08ba91..b48f782 100644
--- a/fs/nfs/blocklayout/blocklayoutdev.c
+++ b/fs/nfs/blocklayout/blocklayoutdev.c
@@ -46,7 +46,7 @@ static int decode_sector_number(__be32 **rp, sector_t *sp)
 
 	*rp = xdr_decode_hyper(*rp, &s);
 	if (s & 0x1ff) {
-		printk(KERN_WARNING "%s: sector not aligned\n", __func__);
+		printk(KERN_WARNING "NFS: %s: sector not aligned\n", __func__);
 		return -1;
 	}
 	*sp = s >> SECTOR_SHIFT;
@@ -120,6 +120,8 @@ nfs4_blk_decode_device(struct nfs_server *server,
 	DECLARE_WAITQUEUE(wq, current);
 	struct bl_dev_msg *reply = &bl_mount_reply;
 	int offset, len, i, rc;
+	struct net *net = server->nfs_client->net;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
 
 	dprintk("%s CREATING PIPEFS MESSAGE\n", __func__);
 	dprintk("%s: deviceid: %s, mincount: %d\n", __func__, dev->dev_id.data,
@@ -146,7 +148,7 @@ nfs4_blk_decode_device(struct nfs_server *server,
 
 	dprintk("%s CALLING USERSPACE DAEMON\n", __func__);
 	add_wait_queue(&bl_wq, &wq);
-	rc = rpc_queue_upcall(bl_device_pipe->d_inode, &msg);
+	rc = rpc_queue_upcall(nn->bl_device_pipe, &msg);
 	if (rc < 0) {
 		remove_wait_queue(&bl_wq, &wq);
 		rv = ERR_PTR(rc);
@@ -181,6 +183,7 @@ nfs4_blk_decode_device(struct nfs_server *server,
 
 	rv->bm_mdev = bd;
 	memcpy(&rv->bm_mdevid, &dev->dev_id, sizeof(struct nfs4_deviceid));
+	rv->net = net;
 	dprintk("%s Created device %s with bd_block_size %u\n",
 		__func__,
 		bd->bd_disk->disk_name,
diff --git a/fs/nfs/blocklayout/blocklayoutdm.c b/fs/nfs/blocklayout/blocklayoutdm.c
index d055c75..a0f588f 100644
--- a/fs/nfs/blocklayout/blocklayoutdm.c
+++ b/fs/nfs/blocklayout/blocklayoutdm.c
@@ -38,7 +38,7 @@
 
 #define NFSDBG_FACILITY         NFSDBG_PNFS_LD
 
-static void dev_remove(dev_t dev)
+static void dev_remove(struct net *net, dev_t dev)
 {
 	struct rpc_pipe_msg msg;
 	struct bl_dev_msg bl_umount_request;
@@ -48,6 +48,7 @@ static void dev_remove(dev_t dev)
 	};
 	uint8_t *dataptr;
 	DECLARE_WAITQUEUE(wq, current);
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
 
 	dprintk("Entering %s\n", __func__);
 
@@ -66,7 +67,7 @@ static void dev_remove(dev_t dev)
 	msg.len = sizeof(bl_msg) + bl_msg.totallen;
 
 	add_wait_queue(&bl_wq, &wq);
-	if (rpc_queue_upcall(bl_device_pipe->d_inode, &msg) < 0) {
+	if (rpc_queue_upcall(nn->bl_device_pipe, &msg) < 0) {
 		remove_wait_queue(&bl_wq, &wq);
 		goto out;
 	}
@@ -90,10 +91,10 @@ static void nfs4_blk_metadev_release(struct pnfs_block_dev *bdev)
 	dprintk("%s Releasing\n", __func__);
 	rv = nfs4_blkdev_put(bdev->bm_mdev);
 	if (rv)
-		printk(KERN_ERR "%s nfs4_blkdev_put returns %d\n",
+		printk(KERN_ERR "NFS: %s nfs4_blkdev_put returns %d\n",
 				__func__, rv);
 
-	dev_remove(bdev->bm_mdev->bd_dev);
+	dev_remove(bdev->net, bdev->bm_mdev->bd_dev);
 }
 
 void bl_free_block_dev(struct pnfs_block_dev *bdev)
diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c
index 1abac09..1f9a603 100644
--- a/fs/nfs/blocklayout/extents.c
+++ b/fs/nfs/blocklayout/extents.c
@@ -147,7 +147,7 @@ static int _preload_range(struct pnfs_inval_markings *marks,
 	count = (int)(end - start) / (int)tree->mtt_step_size;
 
 	/* Pre-malloc what memory we might need */
-	storage = kmalloc(sizeof(*storage) * count, GFP_NOFS);
+	storage = kcalloc(count, sizeof(*storage), GFP_NOFS);
 	if (!storage)
 		return -ENOMEM;
 	for (i = 0; i < count; i++) {
diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c
index c98b439..dded263 100644
--- a/fs/nfs/cache_lib.c
+++ b/fs/nfs/cache_lib.c
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
+#include <net/net_namespace.h>
 
 #include "cache_lib.h"
 
@@ -111,30 +112,54 @@ int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq)
 	return 0;
 }
 
-int nfs_cache_register(struct cache_detail *cd)
+int nfs_cache_register_sb(struct super_block *sb, struct cache_detail *cd)
 {
-	struct vfsmount *mnt;
-	struct path path;
 	int ret;
+	struct dentry *dir;
 
-	mnt = rpc_get_mount();
-	if (IS_ERR(mnt))
-		return PTR_ERR(mnt);
-	ret = vfs_path_lookup(mnt->mnt_root, mnt, "/cache", 0, &path);
-	if (ret)
-		goto err;
-	ret = sunrpc_cache_register_pipefs(path.dentry, cd->name, 0600, cd);
-	path_put(&path);
-	if (!ret)
-		return ret;
-err:
-	rpc_put_mount();
+	dir = rpc_d_lookup_sb(sb, "cache");
+	BUG_ON(dir == NULL);
+	ret = sunrpc_cache_register_pipefs(dir, cd->name, 0600, cd);
+	dput(dir);
 	return ret;
 }
 
-void nfs_cache_unregister(struct cache_detail *cd)
+int nfs_cache_register_net(struct net *net, struct cache_detail *cd)
 {
-	sunrpc_cache_unregister_pipefs(cd);
-	rpc_put_mount();
+	struct super_block *pipefs_sb;
+	int ret = 0;
+
+	pipefs_sb = rpc_get_sb_net(net);
+	if (pipefs_sb) {
+		ret = nfs_cache_register_sb(pipefs_sb, cd);
+		rpc_put_sb_net(net);
+	}
+	return ret;
+}
+
+void nfs_cache_unregister_sb(struct super_block *sb, struct cache_detail *cd)
+{
+	if (cd->u.pipefs.dir)
+		sunrpc_cache_unregister_pipefs(cd);
+}
+
+void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd)
+{
+	struct super_block *pipefs_sb;
+
+	pipefs_sb = rpc_get_sb_net(net);
+	if (pipefs_sb) {
+		nfs_cache_unregister_sb(pipefs_sb, cd);
+		rpc_put_sb_net(net);
+	}
+}
+
+void nfs_cache_init(struct cache_detail *cd)
+{
+	sunrpc_init_cache_detail(cd);
 }
 
+void nfs_cache_destroy(struct cache_detail *cd)
+{
+	sunrpc_destroy_cache_detail(cd);
+}
diff --git a/fs/nfs/cache_lib.h b/fs/nfs/cache_lib.h
index 7cf6caf..317db95 100644
--- a/fs/nfs/cache_lib.h
+++ b/fs/nfs/cache_lib.h
@@ -23,5 +23,11 @@ extern struct nfs_cache_defer_req *nfs_cache_defer_req_alloc(void);
 extern void nfs_cache_defer_req_put(struct nfs_cache_defer_req *dreq);
 extern int nfs_cache_wait_for_upcall(struct nfs_cache_defer_req *dreq);
 
-extern int nfs_cache_register(struct cache_detail *cd);
-extern void nfs_cache_unregister(struct cache_detail *cd);
+extern void nfs_cache_init(struct cache_detail *cd);
+extern void nfs_cache_destroy(struct cache_detail *cd);
+extern int nfs_cache_register_net(struct net *net, struct cache_detail *cd);
+extern void nfs_cache_unregister_net(struct net *net, struct cache_detail *cd);
+extern int nfs_cache_register_sb(struct super_block *sb,
+				 struct cache_detail *cd);
+extern void nfs_cache_unregister_sb(struct super_block *sb,
+				    struct cache_detail *cd);
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 516f337..4a122ae 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -85,7 +85,7 @@ nfs4_callback_svc(void *vrqstp)
 		}
 		if (err < 0) {
 			if (err != preverr) {
-				printk(KERN_WARNING "%s: unexpected error "
+				printk(KERN_WARNING "NFS: %s: unexpected error "
 					"from svc_recv (%d)\n", __func__, err);
 				preverr = err;
 			}
@@ -102,11 +102,11 @@ nfs4_callback_svc(void *vrqstp)
  * Prepare to bring up the NFSv4 callback service
  */
 struct svc_rqst *
-nfs4_callback_up(struct svc_serv *serv)
+nfs4_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
 {
 	int ret;
 
-	ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET,
+	ret = svc_create_xprt(serv, "tcp", xprt->xprt_net, PF_INET,
 				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
 	if (ret <= 0)
 		goto out_err;
@@ -114,7 +114,7 @@ nfs4_callback_up(struct svc_serv *serv)
 	dprintk("NFS: Callback listener port = %u (af %u)\n",
 			nfs_callback_tcpport, PF_INET);
 
-	ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET6,
+	ret = svc_create_xprt(serv, "tcp", xprt->xprt_net, PF_INET6,
 				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
 	if (ret > 0) {
 		nfs_callback_tcpport6 = ret;
@@ -183,7 +183,7 @@ nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
 	 * fore channel connection.
 	 * Returns the input port (0) and sets the svc_serv bc_xprt on success
 	 */
-	ret = svc_create_xprt(serv, "tcp-bc", &init_net, PF_INET, 0,
+	ret = svc_create_xprt(serv, "tcp-bc", xprt->xprt_net, PF_INET, 0,
 			      SVC_SOCK_ANONYMOUS);
 	if (ret < 0) {
 		rqstp = ERR_PTR(ret);
@@ -269,7 +269,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
 					serv, xprt, &rqstp, &callback_svc);
 	if (!minorversion_setup) {
 		/* v4.0 callback setup */
-		rqstp = nfs4_callback_up(serv);
+		rqstp = nfs4_callback_up(serv, xprt);
 		callback_svc = nfs4_callback_svc;
 	}
 
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index c89d3b9..a5527c9 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -38,7 +38,8 @@ enum nfs4_callback_opnum {
 struct cb_process_state {
 	__be32			drc_status;
 	struct nfs_client	*clp;
-	int			slotid;
+	u32			slotid;
+	struct net		*net;
 };
 
 struct cb_compound_hdr_arg {
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 54cea8a..f71978d 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -108,42 +108,62 @@ int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, const nf
 
 #if defined(CONFIG_NFS_V4_1)
 
-static u32 initiate_file_draining(struct nfs_client *clp,
-				  struct cb_layoutrecallargs *args)
+/*
+ * Lookup a layout by filehandle.
+ *
+ * Note: gets a refcount on the layout hdr and on its respective inode.
+ * Caller must put the layout hdr and the inode.
+ *
+ * TODO: keep track of all layouts (and delegations) in a hash table
+ * hashed by filehandle.
+ */
+static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp, struct nfs_fh *fh)
 {
 	struct nfs_server *server;
-	struct pnfs_layout_hdr *lo;
 	struct inode *ino;
-	bool found = false;
-	u32 rv = NFS4ERR_NOMATCHING_LAYOUT;
-	LIST_HEAD(free_me_list);
+	struct pnfs_layout_hdr *lo;
 
-	spin_lock(&clp->cl_lock);
-	rcu_read_lock();
 	list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
 		list_for_each_entry(lo, &server->layouts, plh_layouts) {
-			if (nfs_compare_fh(&args->cbl_fh,
-					   &NFS_I(lo->plh_inode)->fh))
+			if (nfs_compare_fh(fh, &NFS_I(lo->plh_inode)->fh))
 				continue;
 			ino = igrab(lo->plh_inode);
 			if (!ino)
 				continue;
-			found = true;
-			/* Without this, layout can be freed as soon
-			 * as we release cl_lock.
-			 */
 			get_layout_hdr(lo);
-			break;
+			return lo;
 		}
-		if (found)
-			break;
 	}
+
+	return NULL;
+}
+
+static struct pnfs_layout_hdr * get_layout_by_fh(struct nfs_client *clp, struct nfs_fh *fh)
+{
+	struct pnfs_layout_hdr *lo;
+
+	spin_lock(&clp->cl_lock);
+	rcu_read_lock();
+	lo = get_layout_by_fh_locked(clp, fh);
 	rcu_read_unlock();
 	spin_unlock(&clp->cl_lock);
 
-	if (!found)
+	return lo;
+}
+
+static u32 initiate_file_draining(struct nfs_client *clp,
+				  struct cb_layoutrecallargs *args)
+{
+	struct inode *ino;
+	struct pnfs_layout_hdr *lo;
+	u32 rv = NFS4ERR_NOMATCHING_LAYOUT;
+	LIST_HEAD(free_me_list);
+
+	lo = get_layout_by_fh(clp, &args->cbl_fh);
+	if (!lo)
 		return NFS4ERR_NOMATCHING_LAYOUT;
 
+	ino = lo->plh_inode;
 	spin_lock(&ino->i_lock);
 	if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
 	    mark_matching_lsegs_invalid(lo, &free_me_list,
@@ -441,7 +461,7 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
 	int i;
 	__be32 status = htonl(NFS4ERR_BADSESSION);
 
-	clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid);
+	clp = nfs4_find_client_sessionid(cps->net, args->csa_addr, &args->csa_sessionid);
 	if (clp == NULL)
 		goto out;
 
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index d50b274..5466829 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -73,7 +73,7 @@ static __be32 *read_buf(struct xdr_stream *xdr, int nbytes)
 
 	p = xdr_inline_decode(xdr, nbytes);
 	if (unlikely(p == NULL))
-		printk(KERN_WARNING "NFSv4 callback reply buffer overflowed!\n");
+		printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n");
 	return p;
 }
 
@@ -155,7 +155,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound
 		return status;
 	/* We do not like overly long tags! */
 	if (hdr->taglen > CB_OP_TAGLEN_MAXSZ - 12) {
-		printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
+		printk("NFS: NFSv4 CALLBACK %s: client sent tag of length %u\n",
 				__func__, hdr->taglen);
 		return htonl(NFS4ERR_RESOURCE);
 	}
@@ -167,7 +167,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound
 	if (hdr->minorversion <= 1) {
 		hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 */
 	} else {
-		printk(KERN_WARNING "%s: NFSv4 server callback with "
+		printk(KERN_WARNING "NFS: %s: NFSv4 server callback with "
 			"illegal minor version %u!\n",
 			__func__, hdr->minorversion);
 		return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
@@ -759,14 +759,14 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
 	 * Let the state manager know callback processing done.
 	 * A single slot, so highest used slotid is either 0 or -1
 	 */
-	tbl->highest_used_slotid = -1;
+	tbl->highest_used_slotid = NFS4_NO_SLOT;
 	nfs4_check_drain_bc_complete(session);
 	spin_unlock(&tbl->slot_tbl_lock);
 }
 
 static void nfs4_cb_free_slot(struct cb_process_state *cps)
 {
-	if (cps->slotid != -1)
+	if (cps->slotid != NFS4_NO_SLOT)
 		nfs4_callback_free_slot(cps->clp->cl_session);
 }
 
@@ -860,7 +860,8 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
 	struct cb_process_state cps = {
 		.drc_status = 0,
 		.clp = NULL,
-		.slotid = -1,
+		.slotid = NFS4_NO_SLOT,
+		.net = rqstp->rq_xprt->xpt_net,
 	};
 	unsigned int nops = 0;
 
@@ -876,7 +877,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
 		return rpc_garbage_args;
 
 	if (hdr_arg.minorversion == 0) {
-		cps.clp = nfs4_find_client_ident(hdr_arg.cb_ident);
+		cps.clp = nfs4_find_client_ident(rqstp->rq_xprt->xpt_net, hdr_arg.cb_ident);
 		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
 			return rpc_drop_reply;
 	}
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 31778f7..d03264a 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -36,9 +36,12 @@
 #include <linux/inet.h>
 #include <linux/in6.h>
 #include <linux/slab.h>
+#include <linux/idr.h>
 #include <net/ipv6.h>
 #include <linux/nfs_xdr.h>
 #include <linux/sunrpc/bc_xprt.h>
+#include <linux/nsproxy.h>
+#include <linux/pid_namespace.h>
 
 #include <asm/system.h>
 
@@ -49,15 +52,12 @@
 #include "internal.h"
 #include "fscache.h"
 #include "pnfs.h"
+#include "netns.h"
 
 #define NFSDBG_FACILITY		NFSDBG_CLIENT
 
-static DEFINE_SPINLOCK(nfs_client_lock);
-static LIST_HEAD(nfs_client_list);
-static LIST_HEAD(nfs_volume_list);
 static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
 #ifdef CONFIG_NFS_V4
-static DEFINE_IDR(cb_ident_idr); /* Protected by nfs_client_lock */
 
 /*
  * Get a unique NFSv4.0 callback identifier which will be used
@@ -66,15 +66,16 @@ static DEFINE_IDR(cb_ident_idr); /* Protected by nfs_client_lock */
 static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
 {
 	int ret = 0;
+	struct nfs_net *nn = net_generic(clp->net, nfs_net_id);
 
 	if (clp->rpc_ops->version != 4 || minorversion != 0)
 		return ret;
 retry:
-	if (!idr_pre_get(&cb_ident_idr, GFP_KERNEL))
+	if (!idr_pre_get(&nn->cb_ident_idr, GFP_KERNEL))
 		return -ENOMEM;
-	spin_lock(&nfs_client_lock);
-	ret = idr_get_new(&cb_ident_idr, clp, &clp->cl_cb_ident);
-	spin_unlock(&nfs_client_lock);
+	spin_lock(&nn->nfs_client_lock);
+	ret = idr_get_new(&nn->cb_ident_idr, clp, &clp->cl_cb_ident);
+	spin_unlock(&nn->nfs_client_lock);
 	if (ret == -EAGAIN)
 		goto retry;
 	return ret;
@@ -89,7 +90,7 @@ static bool nfs4_disable_idmapping = true;
 /*
  * RPC cruft for NFS
  */
-static struct rpc_version *nfs_version[5] = {
+static const struct rpc_version *nfs_version[5] = {
 	[2]			= &nfs_version2,
 #ifdef CONFIG_NFS_V3
 	[3]			= &nfs_version3,
@@ -99,7 +100,7 @@ static struct rpc_version *nfs_version[5] = {
 #endif
 };
 
-struct rpc_program nfs_program = {
+const struct rpc_program nfs_program = {
 	.name			= "nfs",
 	.number			= NFS_PROGRAM,
 	.nrvers			= ARRAY_SIZE(nfs_version),
@@ -115,11 +116,11 @@ struct rpc_stat nfs_rpcstat = {
 
 #ifdef CONFIG_NFS_V3_ACL
 static struct rpc_stat		nfsacl_rpcstat = { &nfsacl_program };
-static struct rpc_version *	nfsacl_version[] = {
+static const struct rpc_version *nfsacl_version[] = {
 	[3]			= &nfsacl_version3,
 };
 
-struct rpc_program		nfsacl_program = {
+const struct rpc_program nfsacl_program = {
 	.name			= "nfsacl",
 	.number			= NFS_ACL_PROGRAM,
 	.nrvers			= ARRAY_SIZE(nfsacl_version),
@@ -135,6 +136,7 @@ struct nfs_client_initdata {
 	const struct nfs_rpc_ops *rpc_ops;
 	int proto;
 	u32 minorversion;
+	struct net *net;
 };
 
 /*
@@ -171,6 +173,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
 	clp->cl_rpcclient = ERR_PTR(-EINVAL);
 
 	clp->cl_proto = cl_init->proto;
+	clp->net = get_net(cl_init->net);
 
 #ifdef CONFIG_NFS_V4
 	err = nfs_get_cb_ident_idr(clp, cl_init->minorversion);
@@ -233,16 +236,20 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
 }
 
 /* idr_remove_all is not needed as all id's are removed by nfs_put_client */
-void nfs_cleanup_cb_ident_idr(void)
+void nfs_cleanup_cb_ident_idr(struct net *net)
 {
-	idr_destroy(&cb_ident_idr);
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+	idr_destroy(&nn->cb_ident_idr);
 }
 
 /* nfs_client_lock held */
 static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
 {
+	struct nfs_net *nn = net_generic(clp->net, nfs_net_id);
+
 	if (clp->cl_cb_ident)
-		idr_remove(&cb_ident_idr, clp->cl_cb_ident);
+		idr_remove(&nn->cb_ident_idr, clp->cl_cb_ident);
 }
 
 static void pnfs_init_server(struct nfs_server *server)
@@ -260,7 +267,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
 {
 }
 
-void nfs_cleanup_cb_ident_idr(void)
+void nfs_cleanup_cb_ident_idr(struct net *net)
 {
 }
 
@@ -294,6 +301,7 @@ static void nfs_free_client(struct nfs_client *clp)
 
 	nfs4_deviceid_purge_client(clp);
 
+	put_net(clp->net);
 	kfree(clp->cl_hostname);
 	kfree(clp->server_scope);
 	kfree(clp);
@@ -306,15 +314,18 @@ static void nfs_free_client(struct nfs_client *clp)
  */
 void nfs_put_client(struct nfs_client *clp)
 {
+	struct nfs_net *nn;
+
 	if (!clp)
 		return;
 
 	dprintk("--> nfs_put_client({%d})\n", atomic_read(&clp->cl_count));
+	nn = net_generic(clp->net, nfs_net_id);
 
-	if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) {
+	if (atomic_dec_and_lock(&clp->cl_count, &nn->nfs_client_lock)) {
 		list_del(&clp->cl_share_link);
 		nfs_cb_idr_remove_locked(clp);
-		spin_unlock(&nfs_client_lock);
+		spin_unlock(&nn->nfs_client_lock);
 
 		BUG_ON(!list_empty(&clp->cl_superblocks));
 
@@ -462,8 +473,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
 {
 	struct nfs_client *clp;
 	const struct sockaddr *sap = data->addr;
+	struct nfs_net *nn = net_generic(data->net, nfs_net_id);
 
-	list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
+	list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
 	        const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr;
 		/* Don't match clients that failed to initialise properly */
 		if (clp->cl_cons_state < 0)
@@ -501,13 +513,14 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
 {
 	struct nfs_client *clp, *new = NULL;
 	int error;
+	struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
 
 	dprintk("--> nfs_get_client(%s,v%u)\n",
 		cl_init->hostname ?: "", cl_init->rpc_ops->version);
 
 	/* see if the client already exists */
 	do {
-		spin_lock(&nfs_client_lock);
+		spin_lock(&nn->nfs_client_lock);
 
 		clp = nfs_match_client(cl_init);
 		if (clp)
@@ -515,7 +528,7 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
 		if (new)
 			goto install_client;
 
-		spin_unlock(&nfs_client_lock);
+		spin_unlock(&nn->nfs_client_lock);
 
 		new = nfs_alloc_client(cl_init);
 	} while (!IS_ERR(new));
@@ -526,8 +539,8 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
 	/* install a new client and return with it unready */
 install_client:
 	clp = new;
-	list_add(&clp->cl_share_link, &nfs_client_list);
-	spin_unlock(&nfs_client_lock);
+	list_add(&clp->cl_share_link, &nn->nfs_client_list);
+	spin_unlock(&nn->nfs_client_lock);
 
 	error = cl_init->rpc_ops->init_client(clp, timeparms, ip_addr,
 					      authflavour, noresvport);
@@ -542,7 +555,7 @@ install_client:
 	 * - make sure it's ready before returning
 	 */
 found_client:
-	spin_unlock(&nfs_client_lock);
+	spin_unlock(&nn->nfs_client_lock);
 
 	if (new)
 		nfs_free_client(new);
@@ -642,7 +655,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
 {
 	struct rpc_clnt		*clnt = NULL;
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= clp->net,
 		.protocol	= clp->cl_proto,
 		.address	= (struct sockaddr *)&clp->cl_addr,
 		.addrsize	= clp->cl_addrlen,
@@ -696,6 +709,7 @@ static int nfs_start_lockd(struct nfs_server *server)
 		.nfs_version	= clp->rpc_ops->version,
 		.noresvport	= server->flags & NFS_MOUNT_NORESVPORT ?
 					1 : 0,
+		.net		= clp->net,
 	};
 
 	if (nlm_init.nfs_version > 3)
@@ -831,6 +845,7 @@ static int nfs_init_server(struct nfs_server *server,
 		.addrlen = data->nfs_server.addrlen,
 		.rpc_ops = &nfs_v2_clientops,
 		.proto = data->nfs_server.protocol,
+		.net = data->net,
 	};
 	struct rpc_timeout timeparms;
 	struct nfs_client *clp;
@@ -1029,25 +1044,30 @@ static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_serve
 static void nfs_server_insert_lists(struct nfs_server *server)
 {
 	struct nfs_client *clp = server->nfs_client;
+	struct nfs_net *nn = net_generic(clp->net, nfs_net_id);
 
-	spin_lock(&nfs_client_lock);
+	spin_lock(&nn->nfs_client_lock);
 	list_add_tail_rcu(&server->client_link, &clp->cl_superblocks);
-	list_add_tail(&server->master_link, &nfs_volume_list);
+	list_add_tail(&server->master_link, &nn->nfs_volume_list);
 	clear_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
-	spin_unlock(&nfs_client_lock);
+	spin_unlock(&nn->nfs_client_lock);
 
 }
 
 static void nfs_server_remove_lists(struct nfs_server *server)
 {
 	struct nfs_client *clp = server->nfs_client;
+	struct nfs_net *nn;
 
-	spin_lock(&nfs_client_lock);
+	if (clp == NULL)
+		return;
+	nn = net_generic(clp->net, nfs_net_id);
+	spin_lock(&nn->nfs_client_lock);
 	list_del_rcu(&server->client_link);
-	if (clp && list_empty(&clp->cl_superblocks))
+	if (list_empty(&clp->cl_superblocks))
 		set_bit(NFS_CS_STOP_RENEW, &clp->cl_res_state);
 	list_del(&server->master_link);
-	spin_unlock(&nfs_client_lock);
+	spin_unlock(&nn->nfs_client_lock);
 
 	synchronize_rcu();
 }
@@ -1086,6 +1106,8 @@ static struct nfs_server *nfs_alloc_server(void)
 		return NULL;
 	}
 
+	ida_init(&server->openowner_id);
+	ida_init(&server->lockowner_id);
 	pnfs_init_server(server);
 
 	return server;
@@ -1111,6 +1133,8 @@ void nfs_free_server(struct nfs_server *server)
 
 	nfs_put_client(server->nfs_client);
 
+	ida_destroy(&server->lockowner_id);
+	ida_destroy(&server->openowner_id);
 	nfs_free_iostats(server->io_stats);
 	bdi_destroy(&server->backing_dev_info);
 	kfree(server);
@@ -1189,45 +1213,19 @@ error:
 /*
  * NFSv4.0 callback thread helper
  *
- * Find a client by IP address, protocol version, and minorversion
- *
- * Called from the pg_authenticate method. The callback identifier
- * is not used as it has not been decoded.
- *
- * Returns NULL if no such client
- */
-struct nfs_client *
-nfs4_find_client_no_ident(const struct sockaddr *addr)
-{
-	struct nfs_client *clp;
-
-	spin_lock(&nfs_client_lock);
-	list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
-		if (nfs4_cb_match_client(addr, clp, 0) == false)
-			continue;
-		atomic_inc(&clp->cl_count);
-		spin_unlock(&nfs_client_lock);
-		return clp;
-	}
-	spin_unlock(&nfs_client_lock);
-	return NULL;
-}
-
-/*
- * NFSv4.0 callback thread helper
- *
  * Find a client by callback identifier
  */
 struct nfs_client *
-nfs4_find_client_ident(int cb_ident)
+nfs4_find_client_ident(struct net *net, int cb_ident)
 {
 	struct nfs_client *clp;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
 
-	spin_lock(&nfs_client_lock);
-	clp = idr_find(&cb_ident_idr, cb_ident);
+	spin_lock(&nn->nfs_client_lock);
+	clp = idr_find(&nn->cb_ident_idr, cb_ident);
 	if (clp)
 		atomic_inc(&clp->cl_count);
-	spin_unlock(&nfs_client_lock);
+	spin_unlock(&nn->nfs_client_lock);
 	return clp;
 }
 
@@ -1240,13 +1238,14 @@ nfs4_find_client_ident(int cb_ident)
  * Returns NULL if no such client
  */
 struct nfs_client *
-nfs4_find_client_sessionid(const struct sockaddr *addr,
+nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
 			   struct nfs4_sessionid *sid)
 {
 	struct nfs_client *clp;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
 
-	spin_lock(&nfs_client_lock);
-	list_for_each_entry(clp, &nfs_client_list, cl_share_link) {
+	spin_lock(&nn->nfs_client_lock);
+	list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
 		if (nfs4_cb_match_client(addr, clp, 1) == false)
 			continue;
 
@@ -1259,17 +1258,17 @@ nfs4_find_client_sessionid(const struct sockaddr *addr,
 			continue;
 
 		atomic_inc(&clp->cl_count);
-		spin_unlock(&nfs_client_lock);
+		spin_unlock(&nn->nfs_client_lock);
 		return clp;
 	}
-	spin_unlock(&nfs_client_lock);
+	spin_unlock(&nn->nfs_client_lock);
 	return NULL;
 }
 
 #else /* CONFIG_NFS_V4_1 */
 
 struct nfs_client *
-nfs4_find_client_sessionid(const struct sockaddr *addr,
+nfs4_find_client_sessionid(struct net *net, const struct sockaddr *addr,
 			   struct nfs4_sessionid *sid)
 {
 	return NULL;
@@ -1393,7 +1392,7 @@ static int nfs4_set_client(struct nfs_server *server,
 		const char *ip_addr,
 		rpc_authflavor_t authflavour,
 		int proto, const struct rpc_timeout *timeparms,
-		u32 minorversion)
+		u32 minorversion, struct net *net)
 {
 	struct nfs_client_initdata cl_init = {
 		.hostname = hostname,
@@ -1402,6 +1401,7 @@ static int nfs4_set_client(struct nfs_server *server,
 		.rpc_ops = &nfs_v4_clientops,
 		.proto = proto,
 		.minorversion = minorversion,
+		.net = net,
 	};
 	struct nfs_client *clp;
 	int error;
@@ -1453,6 +1453,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
 		.rpc_ops = &nfs_v4_clientops,
 		.proto = ds_proto,
 		.minorversion = mds_clp->cl_minorversion,
+		.net = mds_clp->net,
 	};
 	struct rpc_timeout ds_timeout = {
 		.to_initval = 15 * HZ,
@@ -1580,7 +1581,8 @@ static int nfs4_init_server(struct nfs_server *server,
 			data->auth_flavors[0],
 			data->nfs_server.protocol,
 			&timeparms,
-			data->minorversion);
+			data->minorversion,
+			data->net);
 	if (error < 0)
 		goto error;
 
@@ -1677,7 +1679,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 				data->authflavor,
 				parent_server->client->cl_xprt->prot,
 				parent_server->client->cl_timeout,
-				parent_client->cl_mvops->minor_version);
+				parent_client->cl_mvops->minor_version,
+				parent_client->net);
 	if (error < 0)
 		goto error;
 
@@ -1770,6 +1773,18 @@ out_free_server:
 	return ERR_PTR(error);
 }
 
+void nfs_clients_init(struct net *net)
+{
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+	INIT_LIST_HEAD(&nn->nfs_client_list);
+	INIT_LIST_HEAD(&nn->nfs_volume_list);
+#ifdef CONFIG_NFS_V4
+	idr_init(&nn->cb_ident_idr);
+#endif
+	spin_lock_init(&nn->nfs_client_lock);
+}
+
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *proc_fs_nfs;
 
@@ -1823,13 +1838,15 @@ static int nfs_server_list_open(struct inode *inode, struct file *file)
 {
 	struct seq_file *m;
 	int ret;
+	struct pid_namespace *pid_ns = file->f_dentry->d_sb->s_fs_info;
+	struct net *net = pid_ns->child_reaper->nsproxy->net_ns;
 
 	ret = seq_open(file, &nfs_server_list_ops);
 	if (ret < 0)
 		return ret;
 
 	m = file->private_data;
-	m->private = PDE(inode)->data;
+	m->private = net;
 
 	return 0;
 }
@@ -1839,9 +1856,11 @@ static int nfs_server_list_open(struct inode *inode, struct file *file)
  */
 static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
 {
+	struct nfs_net *nn = net_generic(m->private, nfs_net_id);
+
 	/* lock the list against modification */
-	spin_lock(&nfs_client_lock);
-	return seq_list_start_head(&nfs_client_list, *_pos);
+	spin_lock(&nn->nfs_client_lock);
+	return seq_list_start_head(&nn->nfs_client_list, *_pos);
 }
 
 /*
@@ -1849,7 +1868,9 @@ static void *nfs_server_list_start(struct seq_file *m, loff_t *_pos)
  */
 static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
 {
-	return seq_list_next(v, &nfs_client_list, pos);
+	struct nfs_net *nn = net_generic(p->private, nfs_net_id);
+
+	return seq_list_next(v, &nn->nfs_client_list, pos);
 }
 
 /*
@@ -1857,7 +1878,9 @@ static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos)
  */
 static void nfs_server_list_stop(struct seq_file *p, void *v)
 {
-	spin_unlock(&nfs_client_lock);
+	struct nfs_net *nn = net_generic(p->private, nfs_net_id);
+
+	spin_unlock(&nn->nfs_client_lock);
 }
 
 /*
@@ -1866,9 +1889,10 @@ static void nfs_server_list_stop(struct seq_file *p, void *v)
 static int nfs_server_list_show(struct seq_file *m, void *v)
 {
 	struct nfs_client *clp;
+	struct nfs_net *nn = net_generic(m->private, nfs_net_id);
 
 	/* display header on line 1 */
-	if (v == &nfs_client_list) {
+	if (v == &nn->nfs_client_list) {
 		seq_puts(m, "NV SERVER   PORT USE HOSTNAME\n");
 		return 0;
 	}
@@ -1897,13 +1921,15 @@ static int nfs_volume_list_open(struct inode *inode, struct file *file)
 {
 	struct seq_file *m;
 	int ret;
+	struct pid_namespace *pid_ns = file->f_dentry->d_sb->s_fs_info;
+	struct net *net = pid_ns->child_reaper->nsproxy->net_ns;
 
 	ret = seq_open(file, &nfs_volume_list_ops);
 	if (ret < 0)
 		return ret;
 
 	m = file->private_data;
-	m->private = PDE(inode)->data;
+	m->private = net;
 
 	return 0;
 }
@@ -1913,9 +1939,11 @@ static int nfs_volume_list_open(struct inode *inode, struct file *file)
  */
 static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
 {
+	struct nfs_net *nn = net_generic(m->private, nfs_net_id);
+
 	/* lock the list against modification */
-	spin_lock(&nfs_client_lock);
-	return seq_list_start_head(&nfs_volume_list, *_pos);
+	spin_lock(&nn->nfs_client_lock);
+	return seq_list_start_head(&nn->nfs_volume_list, *_pos);
 }
 
 /*
@@ -1923,7 +1951,9 @@ static void *nfs_volume_list_start(struct seq_file *m, loff_t *_pos)
  */
 static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
 {
-	return seq_list_next(v, &nfs_volume_list, pos);
+	struct nfs_net *nn = net_generic(p->private, nfs_net_id);
+
+	return seq_list_next(v, &nn->nfs_volume_list, pos);
 }
 
 /*
@@ -1931,7 +1961,9 @@ static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos)
  */
 static void nfs_volume_list_stop(struct seq_file *p, void *v)
 {
-	spin_unlock(&nfs_client_lock);
+	struct nfs_net *nn = net_generic(p->private, nfs_net_id);
+
+	spin_unlock(&nn->nfs_client_lock);
 }
 
 /*
@@ -1942,9 +1974,10 @@ static int nfs_volume_list_show(struct seq_file *m, void *v)
 	struct nfs_server *server;
 	struct nfs_client *clp;
 	char dev[8], fsid[17];
+	struct nfs_net *nn = net_generic(m->private, nfs_net_id);
 
 	/* display header on line 1 */
-	if (v == &nfs_volume_list) {
+	if (v == &nn->nfs_volume_list) {
 		seq_puts(m, "NV SERVER   PORT DEV     FSID              FSC\n");
 		return 0;
 	}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index fd9a872..0d71eb6 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -260,10 +260,10 @@ void nfs_readdir_clear_array(struct page *page)
 	struct nfs_cache_array *array;
 	int i;
 
-	array = kmap_atomic(page, KM_USER0);
+	array = kmap_atomic(page);
 	for (i = 0; i < array->size; i++)
 		kfree(array->array[i].string.name);
-	kunmap_atomic(array, KM_USER0);
+	kunmap_atomic(array);
 }
 
 /*
@@ -1429,6 +1429,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 	}
 
 	open_flags = nd->intent.open.flags;
+	attr.ia_valid = 0;
 
 	ctx = create_nfs_open_context(dentry, open_flags);
 	res = ERR_CAST(ctx);
@@ -1437,11 +1438,14 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 
 	if (nd->flags & LOOKUP_CREATE) {
 		attr.ia_mode = nd->intent.open.create_mode;
-		attr.ia_valid = ATTR_MODE;
+		attr.ia_valid |= ATTR_MODE;
 		attr.ia_mode &= ~current_umask();
-	} else {
+	} else
 		open_flags &= ~(O_EXCL | O_CREAT);
-		attr.ia_valid = 0;
+
+	if (open_flags & O_TRUNC) {
+		attr.ia_valid |= ATTR_SIZE;
+		attr.ia_size = 0;
 	}
 
 	/* Open the file on the server */
@@ -1495,6 +1499,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
 	struct inode *inode;
 	struct inode *dir;
 	struct nfs_open_context *ctx;
+	struct iattr attr;
 	int openflags, ret = 0;
 
 	if (nd->flags & LOOKUP_RCU)
@@ -1523,19 +1528,27 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
 	/* We cannot do exclusive creation on a positive dentry */
 	if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
 		goto no_open_dput;
-	/* We can't create new files, or truncate existing ones here */
-	openflags &= ~(O_CREAT|O_EXCL|O_TRUNC);
+	/* We can't create new files here */
+	openflags &= ~(O_CREAT|O_EXCL);
 
 	ctx = create_nfs_open_context(dentry, openflags);
 	ret = PTR_ERR(ctx);
 	if (IS_ERR(ctx))
 		goto out;
+
+	attr.ia_valid = 0;
+	if (openflags & O_TRUNC) {
+		attr.ia_valid |= ATTR_SIZE;
+		attr.ia_size = 0;
+		nfs_wb_all(inode);
+	}
+
 	/*
 	 * Note: we're not holding inode->i_mutex and so may be racing with
 	 * operations that change the directory. We therefore save the
 	 * change attribute *before* we do the RPC call.
 	 */
-	inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, NULL);
+	inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr);
 	if (IS_ERR(inode)) {
 		ret = PTR_ERR(inode);
 		switch (ret) {
@@ -1870,11 +1883,11 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
 	if (!page)
 		return -ENOMEM;
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memcpy(kaddr, symname, pathlen);
 	if (pathlen < PAGE_SIZE)
 		memset(kaddr + pathlen, 0, PAGE_SIZE - pathlen);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	error = NFS_PROTO(dir)->symlink(dir, dentry, page, pathlen, &attr);
 	if (error != 0) {
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index a6e711a..fcd8f1d 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -11,7 +11,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/dns_resolver.h>
 
-ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
+ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
 		struct sockaddr *sa, size_t salen)
 {
 	ssize_t ret;
@@ -20,7 +20,7 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
 
 	ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL);
 	if (ip_len > 0)
-		ret = rpc_pton(ip_addr, ip_len, sa, salen);
+		ret = rpc_pton(net, ip_addr, ip_len, sa, salen);
 	else
 		ret = -ESRCH;
 	kfree(ip_addr);
@@ -40,15 +40,15 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/sunrpc/svcauth.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
 
 #include "dns_resolve.h"
 #include "cache_lib.h"
+#include "netns.h"
 
 #define NFS_DNS_HASHBITS 4
 #define NFS_DNS_HASHTBL_SIZE (1 << NFS_DNS_HASHBITS)
 
-static struct cache_head *nfs_dns_table[NFS_DNS_HASHTBL_SIZE];
-
 struct nfs_dns_ent {
 	struct cache_head h;
 
@@ -224,7 +224,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
 	len = qword_get(&buf, buf1, sizeof(buf1));
 	if (len <= 0)
 		goto out;
-	key.addrlen = rpc_pton(buf1, len,
+	key.addrlen = rpc_pton(cd->net, buf1, len,
 			(struct sockaddr *)&key.addr,
 			sizeof(key.addr));
 
@@ -259,21 +259,6 @@ out:
 	return ret;
 }
 
-static struct cache_detail nfs_dns_resolve = {
-	.owner = THIS_MODULE,
-	.hash_size = NFS_DNS_HASHTBL_SIZE,
-	.hash_table = nfs_dns_table,
-	.name = "dns_resolve",
-	.cache_put = nfs_dns_ent_put,
-	.cache_upcall = nfs_dns_upcall,
-	.cache_parse = nfs_dns_parse,
-	.cache_show = nfs_dns_show,
-	.match = nfs_dns_match,
-	.init = nfs_dns_ent_init,
-	.update = nfs_dns_ent_update,
-	.alloc = nfs_dns_ent_alloc,
-};
-
 static int do_cache_lookup(struct cache_detail *cd,
 		struct nfs_dns_ent *key,
 		struct nfs_dns_ent **item,
@@ -336,8 +321,8 @@ out:
 	return ret;
 }
 
-ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
-		struct sockaddr *sa, size_t salen)
+ssize_t nfs_dns_resolve_name(struct net *net, char *name,
+		size_t namelen, struct sockaddr *sa, size_t salen)
 {
 	struct nfs_dns_ent key = {
 		.hostname = name,
@@ -345,28 +330,118 @@ ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
 	};
 	struct nfs_dns_ent *item = NULL;
 	ssize_t ret;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
 
-	ret = do_cache_lookup_wait(&nfs_dns_resolve, &key, &item);
+	ret = do_cache_lookup_wait(nn->nfs_dns_resolve, &key, &item);
 	if (ret == 0) {
 		if (salen >= item->addrlen) {
 			memcpy(sa, &item->addr, item->addrlen);
 			ret = item->addrlen;
 		} else
 			ret = -EOVERFLOW;
-		cache_put(&item->h, &nfs_dns_resolve);
+		cache_put(&item->h, nn->nfs_dns_resolve);
 	} else if (ret == -ENOENT)
 		ret = -ESRCH;
 	return ret;
 }
 
+int nfs_dns_resolver_cache_init(struct net *net)
+{
+	int err = -ENOMEM;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+	struct cache_detail *cd;
+	struct cache_head **tbl;
+
+	cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL);
+	if (cd == NULL)
+		goto err_cd;
+
+	tbl = kzalloc(NFS_DNS_HASHTBL_SIZE * sizeof(struct cache_head *),
+			GFP_KERNEL);
+	if (tbl == NULL)
+		goto err_tbl;
+
+	cd->owner = THIS_MODULE,
+	cd->hash_size = NFS_DNS_HASHTBL_SIZE,
+	cd->hash_table = tbl,
+	cd->name = "dns_resolve",
+	cd->cache_put = nfs_dns_ent_put,
+	cd->cache_upcall = nfs_dns_upcall,
+	cd->cache_parse = nfs_dns_parse,
+	cd->cache_show = nfs_dns_show,
+	cd->match = nfs_dns_match,
+	cd->init = nfs_dns_ent_init,
+	cd->update = nfs_dns_ent_update,
+	cd->alloc = nfs_dns_ent_alloc,
+
+	nfs_cache_init(cd);
+	err = nfs_cache_register_net(net, cd);
+	if (err)
+		goto err_reg;
+	nn->nfs_dns_resolve = cd;
+	return 0;
+
+err_reg:
+	nfs_cache_destroy(cd);
+	kfree(cd->hash_table);
+err_tbl:
+	kfree(cd);
+err_cd:
+	return err;
+}
+
+void nfs_dns_resolver_cache_destroy(struct net *net)
+{
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+	struct cache_detail *cd = nn->nfs_dns_resolve;
+
+	nfs_cache_unregister_net(net, cd);
+	nfs_cache_destroy(cd);
+	kfree(cd->hash_table);
+	kfree(cd);
+}
+
+static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
+			   void *ptr)
+{
+	struct super_block *sb = ptr;
+	struct net *net = sb->s_fs_info;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+	struct cache_detail *cd = nn->nfs_dns_resolve;
+	int ret = 0;
+
+	if (cd == NULL)
+		return 0;
+
+	if (!try_module_get(THIS_MODULE))
+		return 0;
+
+	switch (event) {
+	case RPC_PIPEFS_MOUNT:
+		ret = nfs_cache_register_sb(sb, cd);
+		break;
+	case RPC_PIPEFS_UMOUNT:
+		nfs_cache_unregister_sb(sb, cd);
+		break;
+	default:
+		ret = -ENOTSUPP;
+		break;
+	}
+	module_put(THIS_MODULE);
+	return ret;
+}
+
+static struct notifier_block nfs_dns_resolver_block = {
+	.notifier_call	= rpc_pipefs_event,
+};
+
 int nfs_dns_resolver_init(void)
 {
-	return nfs_cache_register(&nfs_dns_resolve);
+	return rpc_pipefs_notifier_register(&nfs_dns_resolver_block);
 }
 
 void nfs_dns_resolver_destroy(void)
 {
-	nfs_cache_unregister(&nfs_dns_resolve);
+	rpc_pipefs_notifier_unregister(&nfs_dns_resolver_block);
 }
-
 #endif
diff --git a/fs/nfs/dns_resolve.h b/fs/nfs/dns_resolve.h
index 199bb55..2e4f596 100644
--- a/fs/nfs/dns_resolve.h
+++ b/fs/nfs/dns_resolve.h
@@ -15,12 +15,22 @@ static inline int nfs_dns_resolver_init(void)
 
 static inline void nfs_dns_resolver_destroy(void)
 {}
+
+static inline int nfs_dns_resolver_cache_init(struct net *net)
+{
+	return 0;
+}
+
+static inline void nfs_dns_resolver_cache_destroy(struct net *net)
+{}
 #else
 extern int nfs_dns_resolver_init(void);
 extern void nfs_dns_resolver_destroy(void);
+extern int nfs_dns_resolver_cache_init(struct net *net);
+extern void nfs_dns_resolver_cache_destroy(struct net *net);
 #endif
 
-extern ssize_t nfs_dns_resolve_name(char *name, size_t namelen,
-		struct sockaddr *sa, size_t salen);
+extern ssize_t nfs_dns_resolve_name(struct net *net, char *name,
+		size_t namelen,	struct sockaddr *sa, size_t salen);
 
 #endif
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index c43a452..4fdaaa6 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -530,6 +530,8 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 	if (mapping != dentry->d_inode->i_mapping)
 		goto out_unlock;
 
+	wait_on_page_writeback(page);
+
 	pagelen = nfs_page_length(page);
 	if (pagelen == 0)
 		goto out_unlock;
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index dcb6154..801d6d8 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -49,11 +49,9 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
 {
 	/* The mntroot acts as the dummy root dentry for this superblock */
 	if (sb->s_root == NULL) {
-		sb->s_root = d_alloc_root(inode);
-		if (sb->s_root == NULL) {
-			iput(inode);
+		sb->s_root = d_make_root(inode);
+		if (sb->s_root == NULL)
 			return -ENOMEM;
-		}
 		ihold(inode);
 		/*
 		 * Ensure that this dentry is invisible to d_find_alias().
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 2c05f19..3a6304d 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -39,6 +39,38 @@
 #include <linux/slab.h>
 #include <linux/nfs_idmap.h>
 #include <linux/nfs_fs.h>
+#include <linux/cred.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/nfs4.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/keyctl.h>
+#include <linux/key-type.h>
+#include <linux/rcupdate.h>
+#include <linux/err.h>
+#include <keys/user-type.h>
+
+/* include files needed by legacy idmapper */
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/init.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/sched.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/workqueue.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
+#include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
+#include "internal.h"
+#include "netns.h"
+
+#define NFS_UINT_MAXLEN 11
+#define IDMAP_HASH_SZ          128
+
+/* Default cache timeout is 10 minutes */
+unsigned int nfs_idmap_cache_timeout = 600 * HZ;
+const struct cred *id_resolver_cache;
+
 
 /**
  * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
@@ -142,23 +174,6 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)
 	return snprintf(buf, buflen, "%u", id);
 }
 
-#ifdef CONFIG_NFS_USE_NEW_IDMAPPER
-
-#include <linux/cred.h>
-#include <linux/sunrpc/sched.h>
-#include <linux/nfs4.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/keyctl.h>
-#include <linux/key-type.h>
-#include <linux/rcupdate.h>
-#include <linux/err.h>
-
-#include <keys/user-type.h>
-
-#define NFS_UINT_MAXLEN 11
-
-const struct cred *id_resolver_cache;
-
 struct key_type key_type_id_resolver = {
 	.name		= "id_resolver",
 	.instantiate	= user_instantiate,
@@ -169,13 +184,14 @@ struct key_type key_type_id_resolver = {
 	.read		= user_read,
 };
 
-int nfs_idmap_init(void)
+static int nfs_idmap_init_keyring(void)
 {
 	struct cred *cred;
 	struct key *keyring;
 	int ret = 0;
 
-	printk(KERN_NOTICE "Registering the %s key type\n", key_type_id_resolver.name);
+	printk(KERN_NOTICE "NFS: Registering the %s key type\n",
+		key_type_id_resolver.name);
 
 	cred = prepare_kernel_cred(NULL);
 	if (!cred)
@@ -198,6 +214,7 @@ int nfs_idmap_init(void)
 	if (ret < 0)
 		goto failed_put_key;
 
+	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
 	cred->thread_keyring = keyring;
 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
 	id_resolver_cache = cred;
@@ -210,7 +227,7 @@ failed_put_cred:
 	return ret;
 }
 
-void nfs_idmap_quit(void)
+static void nfs_idmap_quit_keyring(void)
 {
 	key_revoke(id_resolver_cache->thread_keyring);
 	unregister_key_type(&key_type_id_resolver);
@@ -327,62 +344,7 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen,
 	return ret;
 }
 
-int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
-{
-	if (nfs_map_string_to_numeric(name, namelen, uid))
-		return 0;
-	return nfs_idmap_lookup_id(name, namelen, "uid", uid);
-}
-
-int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *gid)
-{
-	if (nfs_map_string_to_numeric(name, namelen, gid))
-		return 0;
-	return nfs_idmap_lookup_id(name, namelen, "gid", gid);
-}
-
-int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
-{
-	int ret = -EINVAL;
-
-	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
-		ret = nfs_idmap_lookup_name(uid, "user", buf, buflen);
-	if (ret < 0)
-		ret = nfs_map_numeric_to_string(uid, buf, buflen);
-	return ret;
-}
-int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen)
-{
-	int ret = -EINVAL;
-
-	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
-		ret = nfs_idmap_lookup_name(gid, "group", buf, buflen);
-	if (ret < 0)
-		ret = nfs_map_numeric_to_string(gid, buf, buflen);
-	return ret;
-}
-
-#else  /* CONFIG_NFS_USE_NEW_IDMAPPER not defined */
-
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/init.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/sched.h>
-#include <linux/sunrpc/clnt.h>
-#include <linux/workqueue.h>
-#include <linux/sunrpc/rpc_pipe_fs.h>
-
-#include <linux/nfs_fs.h>
-
-#include "nfs4_fs.h"
-
-#define IDMAP_HASH_SZ          128
-
-/* Default cache timeout is 10 minutes */
-unsigned int nfs_idmap_cache_timeout = 600 * HZ;
-
+/* idmap classic begins here */
 static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
 {
 	char *endp;
@@ -401,16 +363,16 @@ struct idmap_hashent {
 	unsigned long		ih_expires;
 	__u32			ih_id;
 	size_t			ih_namelen;
-	char			ih_name[IDMAP_NAMESZ];
+	const char		*ih_name;
 };
 
 struct idmap_hashtable {
 	__u8			h_type;
-	struct idmap_hashent	h_entries[IDMAP_HASH_SZ];
+	struct idmap_hashent	*h_entries;
 };
 
 struct idmap {
-	struct dentry		*idmap_dentry;
+	struct rpc_pipe		*idmap_pipe;
 	wait_queue_head_t	idmap_wq;
 	struct idmap_msg	idmap_im;
 	struct mutex		idmap_lock;	/* Serializes upcalls */
@@ -431,10 +393,61 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {
 	.destroy_msg	= idmap_pipe_destroy_msg,
 };
 
+static void __nfs_idmap_unregister(struct rpc_pipe *pipe)
+{
+	if (pipe->dentry)
+		rpc_unlink(pipe->dentry);
+}
+
+static int __nfs_idmap_register(struct dentry *dir,
+				     struct idmap *idmap,
+				     struct rpc_pipe *pipe)
+{
+	struct dentry *dentry;
+
+	dentry = rpc_mkpipe_dentry(dir, "idmap", idmap, pipe);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+	pipe->dentry = dentry;
+	return 0;
+}
+
+static void nfs_idmap_unregister(struct nfs_client *clp,
+				      struct rpc_pipe *pipe)
+{
+	struct net *net = clp->net;
+	struct super_block *pipefs_sb;
+
+	pipefs_sb = rpc_get_sb_net(net);
+	if (pipefs_sb) {
+		__nfs_idmap_unregister(pipe);
+		rpc_put_sb_net(net);
+	}
+}
+
+static int nfs_idmap_register(struct nfs_client *clp,
+				   struct idmap *idmap,
+				   struct rpc_pipe *pipe)
+{
+	struct net *net = clp->net;
+	struct super_block *pipefs_sb;
+	int err = 0;
+
+	pipefs_sb = rpc_get_sb_net(net);
+	if (pipefs_sb) {
+		if (clp->cl_rpcclient->cl_dentry)
+			err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry,
+						   idmap, pipe);
+		rpc_put_sb_net(net);
+	}
+	return err;
+}
+
 int
 nfs_idmap_new(struct nfs_client *clp)
 {
 	struct idmap *idmap;
+	struct rpc_pipe *pipe;
 	int error;
 
 	BUG_ON(clp->cl_idmap != NULL);
@@ -443,14 +456,19 @@ nfs_idmap_new(struct nfs_client *clp)
 	if (idmap == NULL)
 		return -ENOMEM;
 
-	idmap->idmap_dentry = rpc_mkpipe(clp->cl_rpcclient->cl_path.dentry,
-			"idmap", idmap, &idmap_upcall_ops, 0);
-	if (IS_ERR(idmap->idmap_dentry)) {
-		error = PTR_ERR(idmap->idmap_dentry);
+	pipe = rpc_mkpipe_data(&idmap_upcall_ops, 0);
+	if (IS_ERR(pipe)) {
+		error = PTR_ERR(pipe);
 		kfree(idmap);
 		return error;
 	}
-
+	error = nfs_idmap_register(clp, idmap, pipe);
+	if (error) {
+		rpc_destroy_pipe_data(pipe);
+		kfree(idmap);
+		return error;
+	}
+	idmap->idmap_pipe = pipe;
 	mutex_init(&idmap->idmap_lock);
 	mutex_init(&idmap->idmap_im_lock);
 	init_waitqueue_head(&idmap->idmap_wq);
@@ -461,6 +479,28 @@ nfs_idmap_new(struct nfs_client *clp)
 	return 0;
 }
 
+static void
+idmap_alloc_hashtable(struct idmap_hashtable *h)
+{
+	if (h->h_entries != NULL)
+		return;
+	h->h_entries = kcalloc(IDMAP_HASH_SZ,
+			sizeof(*h->h_entries),
+			GFP_KERNEL);
+}
+
+static void
+idmap_free_hashtable(struct idmap_hashtable *h)
+{
+	int i;
+
+	if (h->h_entries == NULL)
+		return;
+	for (i = 0; i < IDMAP_HASH_SZ; i++)
+		kfree(h->h_entries[i].ih_name);
+	kfree(h->h_entries);
+}
+
 void
 nfs_idmap_delete(struct nfs_client *clp)
 {
@@ -468,17 +508,106 @@ nfs_idmap_delete(struct nfs_client *clp)
 
 	if (!idmap)
 		return;
-	rpc_unlink(idmap->idmap_dentry);
+	nfs_idmap_unregister(clp, idmap->idmap_pipe);
+	rpc_destroy_pipe_data(idmap->idmap_pipe);
 	clp->cl_idmap = NULL;
+	idmap_free_hashtable(&idmap->idmap_user_hash);
+	idmap_free_hashtable(&idmap->idmap_group_hash);
 	kfree(idmap);
 }
 
+static int __rpc_pipefs_event(struct nfs_client *clp, unsigned long event,
+			      struct super_block *sb)
+{
+	int err = 0;
+
+	switch (event) {
+	case RPC_PIPEFS_MOUNT:
+		BUG_ON(clp->cl_rpcclient->cl_dentry == NULL);
+		err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry,
+						clp->cl_idmap,
+						clp->cl_idmap->idmap_pipe);
+		break;
+	case RPC_PIPEFS_UMOUNT:
+		if (clp->cl_idmap->idmap_pipe) {
+			struct dentry *parent;
+
+			parent = clp->cl_idmap->idmap_pipe->dentry->d_parent;
+			__nfs_idmap_unregister(clp->cl_idmap->idmap_pipe);
+			/*
+			 * Note: This is a dirty hack. SUNRPC hook has been
+			 * called already but simple_rmdir() call for the
+			 * directory returned with error because of idmap pipe
+			 * inside. Thus now we have to remove this directory
+			 * here.
+			 */
+			if (rpc_rmdir(parent))
+				printk(KERN_ERR "NFS: %s: failed to remove "
+					"clnt dir!\n", __func__);
+		}
+		break;
+	default:
+		printk(KERN_ERR "NFS: %s: unknown event: %ld\n", __func__,
+			event);
+		return -ENOTSUPP;
+	}
+	return err;
+}
+
+static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
+			    void *ptr)
+{
+	struct super_block *sb = ptr;
+	struct nfs_net *nn = net_generic(sb->s_fs_info, nfs_net_id);
+	struct nfs_client *clp;
+	int error = 0;
+
+	spin_lock(&nn->nfs_client_lock);
+	list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) {
+		if (clp->rpc_ops != &nfs_v4_clientops)
+			continue;
+		error = __rpc_pipefs_event(clp, event, sb);
+		if (error)
+			break;
+	}
+	spin_unlock(&nn->nfs_client_lock);
+	return error;
+}
+
+#define PIPEFS_NFS_PRIO		1
+
+static struct notifier_block nfs_idmap_block = {
+	.notifier_call	= rpc_pipefs_event,
+	.priority	= SUNRPC_PIPEFS_NFS_PRIO,
+};
+
+int nfs_idmap_init(void)
+{
+	int ret;
+	ret = nfs_idmap_init_keyring();
+	if (ret != 0)
+		goto out;
+	ret = rpc_pipefs_notifier_register(&nfs_idmap_block);
+	if (ret != 0)
+		nfs_idmap_quit_keyring();
+out:
+	return ret;
+}
+
+void nfs_idmap_quit(void)
+{
+	rpc_pipefs_notifier_unregister(&nfs_idmap_block);
+	nfs_idmap_quit_keyring();
+}
+
 /*
  * Helper routines for manipulating the hashtable
  */
 static inline struct idmap_hashent *
 idmap_name_hash(struct idmap_hashtable* h, const char *name, size_t len)
 {
+	if (h->h_entries == NULL)
+		return NULL;
 	return &h->h_entries[fnvhash32(name, len) % IDMAP_HASH_SZ];
 }
 
@@ -487,6 +616,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
 {
 	struct idmap_hashent *he = idmap_name_hash(h, name, len);
 
+	if (he == NULL)
+		return NULL;
 	if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
 		return NULL;
 	if (time_after(jiffies, he->ih_expires))
@@ -497,6 +628,8 @@ idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
 static inline struct idmap_hashent *
 idmap_id_hash(struct idmap_hashtable* h, __u32 id)
 {
+	if (h->h_entries == NULL)
+		return NULL;
 	return &h->h_entries[fnvhash32(&id, sizeof(id)) % IDMAP_HASH_SZ];
 }
 
@@ -504,6 +637,9 @@ static struct idmap_hashent *
 idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
 {
 	struct idmap_hashent *he = idmap_id_hash(h, id);
+
+	if (he == NULL)
+		return NULL;
 	if (he->ih_id != id || he->ih_namelen == 0)
 		return NULL;
 	if (time_after(jiffies, he->ih_expires))
@@ -519,12 +655,14 @@ idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
 static inline struct idmap_hashent *
 idmap_alloc_name(struct idmap_hashtable *h, char *name, size_t len)
 {
+	idmap_alloc_hashtable(h);
 	return idmap_name_hash(h, name, len);
 }
 
 static inline struct idmap_hashent *
 idmap_alloc_id(struct idmap_hashtable *h, __u32 id)
 {
+	idmap_alloc_hashtable(h);
 	return idmap_id_hash(h, id);
 }
 
@@ -532,9 +670,14 @@ static void
 idmap_update_entry(struct idmap_hashent *he, const char *name,
 		size_t namelen, __u32 id)
 {
+	char *str = kmalloc(namelen + 1, GFP_KERNEL);
+	if (str == NULL)
+		return;
+	kfree(he->ih_name);
 	he->ih_id = id;
-	memcpy(he->ih_name, name, namelen);
-	he->ih_name[namelen] = '\0';
+	memcpy(str, name, namelen);
+	str[namelen] = '\0';
+	he->ih_name = str;
 	he->ih_namelen = namelen;
 	he->ih_expires = jiffies + nfs_idmap_cache_timeout;
 }
@@ -589,7 +732,7 @@ nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h,
 	msg.len = sizeof(*im);
 
 	add_wait_queue(&idmap->idmap_wq, &wq);
-	if (rpc_queue_upcall(idmap->idmap_dentry->d_inode, &msg) < 0) {
+	if (rpc_queue_upcall(idmap->idmap_pipe, &msg) < 0) {
 		remove_wait_queue(&idmap->idmap_wq, &wq);
 		goto out;
 	}
@@ -650,7 +793,7 @@ nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
 
 	add_wait_queue(&idmap->idmap_wq, &wq);
 
-	if (rpc_queue_upcall(idmap->idmap_dentry->d_inode, &msg) < 0) {
+	if (rpc_queue_upcall(idmap->idmap_pipe, &msg) < 0) {
 		remove_wait_queue(&idmap->idmap_wq, &wq);
 		goto out;
 	}
@@ -795,19 +938,27 @@ static unsigned int fnvhash32(const void *buf, size_t buflen)
 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
+	int ret = -EINVAL;
 
 	if (nfs_map_string_to_numeric(name, namelen, uid))
 		return 0;
-	return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid);
+	ret = nfs_idmap_lookup_id(name, namelen, "uid", uid);
+	if (ret < 0)
+		ret = nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid);
+	return ret;
 }
 
-int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
+int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *gid)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
+	int ret = -EINVAL;
 
-	if (nfs_map_string_to_numeric(name, namelen, uid))
+	if (nfs_map_string_to_numeric(name, namelen, gid))
 		return 0;
-	return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid);
+	ret = nfs_idmap_lookup_id(name, namelen, "gid", gid);
+	if (ret < 0)
+		ret = nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, gid);
+	return ret;
 }
 
 int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
@@ -815,22 +966,26 @@ int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, s
 	struct idmap *idmap = server->nfs_client->cl_idmap;
 	int ret = -EINVAL;
 
-	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
-		ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf);
+	if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) {
+		ret = nfs_idmap_lookup_name(uid, "user", buf, buflen);
+		if (ret < 0)
+			ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf);
+	}
 	if (ret < 0)
 		ret = nfs_map_numeric_to_string(uid, buf, buflen);
 	return ret;
 }
-int nfs_map_gid_to_group(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
+int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen)
 {
 	struct idmap *idmap = server->nfs_client->cl_idmap;
 	int ret = -EINVAL;
 
-	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
-		ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf);
+	if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) {
+		ret = nfs_idmap_lookup_name(gid, "group", buf, buflen);
+		if (ret < 0)
+			ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, gid, buf);
+	}
 	if (ret < 0)
-		ret = nfs_map_numeric_to_string(uid, buf, buflen);
+		ret = nfs_map_numeric_to_string(gid, buf, buflen);
 	return ret;
 }
-
-#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f649fba..6c66259 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -51,6 +51,7 @@
 #include "fscache.h"
 #include "dns_resolve.h"
 #include "pnfs.h"
+#include "netns.h"
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
 
@@ -401,7 +402,7 @@ out_no_inode:
 	goto out;
 }
 
-#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE)
+#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
 
 int
 nfs_setattr(struct dentry *dentry, struct iattr *attr)
@@ -423,7 +424,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
 
 	/* Optimization: if the end result is no change, don't RPC */
 	attr->ia_valid &= NFS_VALID_ATTRS;
-	if ((attr->ia_valid & ~ATTR_FILE) == 0)
+	if ((attr->ia_valid & ~(ATTR_FILE|ATTR_OPEN)) == 0)
 		return 0;
 
 	/* Write all dirty data */
@@ -1406,7 +1407,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 	/*
 	 * Big trouble! The inode has become a different object.
 	 */
-	printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
+	printk(KERN_DEBUG "NFS: %s: inode %ld mode changed, %07o to %07o\n",
 			__func__, inode->i_ino, inode->i_mode, fattr->mode);
  out_err:
 	/*
@@ -1552,6 +1553,28 @@ static void nfsiod_stop(void)
 	destroy_workqueue(wq);
 }
 
+int nfs_net_id;
+EXPORT_SYMBOL_GPL(nfs_net_id);
+
+static int nfs_net_init(struct net *net)
+{
+	nfs_clients_init(net);
+	return nfs_dns_resolver_cache_init(net);
+}
+
+static void nfs_net_exit(struct net *net)
+{
+	nfs_dns_resolver_cache_destroy(net);
+	nfs_cleanup_cb_ident_idr(net);
+}
+
+static struct pernet_operations nfs_net_ops = {
+	.init = nfs_net_init,
+	.exit = nfs_net_exit,
+	.id   = &nfs_net_id,
+	.size = sizeof(struct nfs_net),
+};
+
 /*
  * Initialize NFS
  */
@@ -1561,10 +1584,14 @@ static int __init init_nfs_fs(void)
 
 	err = nfs_idmap_init();
 	if (err < 0)
-		goto out9;
+		goto out10;
 
 	err = nfs_dns_resolver_init();
 	if (err < 0)
+		goto out9;
+
+	err = register_pernet_subsys(&nfs_net_ops);
+	if (err < 0)
 		goto out8;
 
 	err = nfs_fscache_register();
@@ -1600,14 +1627,14 @@ static int __init init_nfs_fs(void)
 		goto out0;
 
 #ifdef CONFIG_PROC_FS
-	rpc_proc_register(&nfs_rpcstat);
+	rpc_proc_register(&init_net, &nfs_rpcstat);
 #endif
 	if ((err = register_nfs_fs()) != 0)
 		goto out;
 	return 0;
 out:
 #ifdef CONFIG_PROC_FS
-	rpc_proc_unregister("nfs");
+	rpc_proc_unregister(&init_net, "nfs");
 #endif
 	nfs_destroy_directcache();
 out0:
@@ -1625,10 +1652,12 @@ out5:
 out6:
 	nfs_fscache_unregister();
 out7:
-	nfs_dns_resolver_destroy();
+	unregister_pernet_subsys(&nfs_net_ops);
 out8:
-	nfs_idmap_quit();
+	nfs_dns_resolver_destroy();
 out9:
+	nfs_idmap_quit();
+out10:
 	return err;
 }
 
@@ -1640,12 +1669,12 @@ static void __exit exit_nfs_fs(void)
 	nfs_destroy_inodecache();
 	nfs_destroy_nfspagecache();
 	nfs_fscache_unregister();
+	unregister_pernet_subsys(&nfs_net_ops);
 	nfs_dns_resolver_destroy();
 	nfs_idmap_quit();
 #ifdef CONFIG_PROC_FS
-	rpc_proc_unregister("nfs");
+	rpc_proc_unregister(&init_net, "nfs");
 #endif
-	nfs_cleanup_cb_ident_idr();
 	unregister_nfs_fs();
 	nfs_fs_proc_exit();
 	nfsiod_stop();
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 8102db9..0c3648a 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -123,6 +123,7 @@ struct nfs_parsed_mount_data {
 	} nfs_server;
 
 	struct security_mnt_opts lsm_opts;
+	struct net		*net;
 };
 
 /* mount_clnt.c */
@@ -137,20 +138,22 @@ struct nfs_mount_request {
 	int			noresvport;
 	unsigned int		*auth_flav_len;
 	rpc_authflavor_t	*auth_flavs;
+	struct net		*net;
 };
 
 extern int nfs_mount(struct nfs_mount_request *info);
 extern void nfs_umount(const struct nfs_mount_request *info);
 
 /* client.c */
-extern struct rpc_program nfs_program;
+extern const struct rpc_program nfs_program;
+extern void nfs_clients_init(struct net *net);
 
-extern void nfs_cleanup_cb_ident_idr(void);
+extern void nfs_cleanup_cb_ident_idr(struct net *);
 extern void nfs_put_client(struct nfs_client *);
-extern struct nfs_client *nfs4_find_client_no_ident(const struct sockaddr *);
-extern struct nfs_client *nfs4_find_client_ident(int);
+extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
 extern struct nfs_client *
-nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *);
+nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
+				struct nfs4_sessionid *);
 extern struct nfs_server *nfs_create_server(
 					const struct nfs_parsed_mount_data *,
 					struct nfs_fh *);
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index d4c2d6b..b37ca34 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -67,7 +67,7 @@ enum {
 	MOUNTPROC3_EXPORT	= 5,
 };
 
-static struct rpc_program	mnt_program;
+static const struct rpc_program mnt_program;
 
 /*
  * Defined by OpenGroup XNFS Version 3W, chapter 8
@@ -153,7 +153,7 @@ int nfs_mount(struct nfs_mount_request *info)
 		.rpc_resp	= &result,
 	};
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= info->net,
 		.protocol	= info->protocol,
 		.address	= info->sap,
 		.addrsize	= info->salen,
@@ -225,7 +225,7 @@ void nfs_umount(const struct nfs_mount_request *info)
 		.to_retries = 2,
 	};
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= info->net,
 		.protocol	= IPPROTO_UDP,
 		.address	= info->sap,
 		.addrsize	= info->salen,
@@ -488,19 +488,19 @@ static struct rpc_procinfo mnt3_procedures[] = {
 };
 
 
-static struct rpc_version mnt_version1 = {
+static const struct rpc_version mnt_version1 = {
 	.number		= 1,
 	.nrprocs	= ARRAY_SIZE(mnt_procedures),
 	.procs		= mnt_procedures,
 };
 
-static struct rpc_version mnt_version3 = {
+static const struct rpc_version mnt_version3 = {
 	.number		= 3,
 	.nrprocs	= ARRAY_SIZE(mnt3_procedures),
 	.procs		= mnt3_procedures,
 };
 
-static struct rpc_version *mnt_version[] = {
+static const struct rpc_version *mnt_version[] = {
 	NULL,
 	&mnt_version1,
 	NULL,
@@ -509,7 +509,7 @@ static struct rpc_version *mnt_version[] = {
 
 static struct rpc_stat mnt_stats;
 
-static struct rpc_program mnt_program = {
+static const struct rpc_program mnt_program = {
 	.name		= "mount",
 	.number		= NFS_MNT_PROGRAM,
 	.nrvers		= ARRAY_SIZE(mnt_version),
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 8102391..1807866 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -276,7 +276,10 @@ out:
 	nfs_free_fattr(fattr);
 	nfs_free_fhandle(fh);
 out_nofree:
-	dprintk("<-- nfs_follow_mountpoint() = %p\n", mnt);
+	if (IS_ERR(mnt))
+		dprintk("<-- %s(): error %ld\n", __func__, PTR_ERR(mnt));
+	else
+		dprintk("<-- %s() = %p\n", __func__, mnt);
 	return mnt;
 }
 
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
new file mode 100644
index 0000000..7baad89
--- /dev/null
+++ b/fs/nfs/netns.h
@@ -0,0 +1,20 @@
+#ifndef __NFS_NETNS_H__
+#define __NFS_NETNS_H__
+
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
+struct nfs_net {
+	struct cache_detail *nfs_dns_resolve;
+	struct rpc_pipe *bl_device_pipe;
+	struct list_head nfs_client_list;
+	struct list_head nfs_volume_list;
+#ifdef CONFIG_NFS_V4
+	struct idr cb_ident_idr; /* Protected by nfs_client_lock */
+#endif
+	spinlock_t nfs_client_lock;
+};
+
+extern int nfs_net_id;
+
+#endif
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 792cb13..1f56000 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -1150,7 +1150,7 @@ struct rpc_procinfo	nfs_procedures[] = {
 	PROC(STATFS,	fhandle,	statfsres,	0),
 };
 
-struct rpc_version		nfs_version2 = {
+const struct rpc_version nfs_version2 = {
 	.number			= 2,
 	.nrprocs		= ARRAY_SIZE(nfs_procedures),
 	.procs			= nfs_procedures
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 183c6b1..a77cc9a 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -2461,7 +2461,7 @@ struct rpc_procinfo	nfs3_procedures[] = {
 	PROC(COMMIT,		commit,		commit,		5),
 };
 
-struct rpc_version		nfs_version3 = {
+const struct rpc_version nfs_version3 = {
 	.number			= 3,
 	.nrprocs		= ARRAY_SIZE(nfs3_procedures),
 	.procs			= nfs3_procedures
@@ -2489,7 +2489,7 @@ static struct rpc_procinfo	nfs3_acl_procedures[] = {
 	},
 };
 
-struct rpc_version		nfsacl_version3 = {
+const struct rpc_version nfsacl_version3 = {
 	.number			= 3,
 	.nrprocs		= sizeof(nfs3_acl_procedures)/
 				  sizeof(nfs3_acl_procedures[0]),
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 4d7d0ae..b133b50 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -53,26 +53,25 @@ struct nfs4_minor_version_ops {
 	const struct nfs4_state_maintenance_ops *state_renewal_ops;
 };
 
-/*
- * struct rpc_sequence ensures that RPC calls are sent in the exact
- * order that they appear on the list.
- */
-struct rpc_sequence {
-	struct rpc_wait_queue	wait;	/* RPC call delay queue */
-	spinlock_t lock;		/* Protects the list */
-	struct list_head list;		/* Defines sequence of RPC calls */
+struct nfs_unique_id {
+	struct rb_node rb_node;
+	__u64 id;
 };
 
 #define NFS_SEQID_CONFIRMED 1
 struct nfs_seqid_counter {
-	struct rpc_sequence *sequence;
+	int owner_id;
 	int flags;
 	u32 counter;
+	spinlock_t lock;		/* Protects the list */
+	struct list_head list;		/* Defines sequence of RPC calls */
+	struct rpc_wait_queue	wait;	/* RPC call delay queue */
 };
 
 struct nfs_seqid {
 	struct nfs_seqid_counter *sequence;
 	struct list_head list;
+	struct rpc_task *task;
 };
 
 static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
@@ -81,18 +80,12 @@ static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status
 		seqid->flags |= NFS_SEQID_CONFIRMED;
 }
 
-struct nfs_unique_id {
-	struct rb_node rb_node;
-	__u64 id;
-};
-
 /*
  * NFS4 state_owners and lock_owners are simply labels for ordered
  * sequences of RPC calls. Their sole purpose is to provide once-only
  * semantics by allowing the server to identify replayed requests.
  */
 struct nfs4_state_owner {
-	struct nfs_unique_id so_owner_id;
 	struct nfs_server    *so_server;
 	struct list_head     so_lru;
 	unsigned long        so_expires;
@@ -105,7 +98,6 @@ struct nfs4_state_owner {
 	unsigned long	     so_flags;
 	struct list_head     so_states;
 	struct nfs_seqid_counter so_seqid;
-	struct rpc_sequence  so_sequence;
 };
 
 enum {
@@ -146,8 +138,6 @@ struct nfs4_lock_state {
 #define NFS_LOCK_INITIALIZED 1
 	int			ls_flags;
 	struct nfs_seqid_counter	ls_seqid;
-	struct rpc_sequence	ls_sequence;
-	struct nfs_unique_id	ls_id;
 	nfs4_stateid		ls_stateid;
 	atomic_t		ls_count;
 	struct nfs4_lock_owner	ls_owner;
@@ -233,12 +223,13 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *ser
 	return server->nfs_client->cl_session;
 }
 
+extern bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy);
 extern int nfs4_setup_sequence(const struct nfs_server *server,
 		struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
-		int cache_reply, struct rpc_task *task);
+		struct rpc_task *task);
 extern int nfs41_setup_sequence(struct nfs4_session *session,
 		struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
-		int cache_reply, struct rpc_task *task);
+		struct rpc_task *task);
 extern void nfs4_destroy_session(struct nfs4_session *session);
 extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
 extern int nfs4_proc_create_session(struct nfs_client *);
@@ -269,7 +260,7 @@ static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *ser
 
 static inline int nfs4_setup_sequence(const struct nfs_server *server,
 		struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
-		int cache_reply, struct rpc_task *task)
+		struct rpc_task *task)
 {
 	return 0;
 }
@@ -319,7 +310,7 @@ static inline void nfs4_schedule_session_recovery(struct nfs4_session *session)
 }
 #endif /* CONFIG_NFS_V4_1 */
 
-extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
+extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *, gfp_t);
 extern void nfs4_put_state_owner(struct nfs4_state_owner *);
 extern void nfs4_purge_state_owners(struct nfs_server *);
 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 71ec086..47e8f34 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -33,6 +33,8 @@
 #include <linux/nfs_page.h>
 #include <linux/module.h>
 
+#include <linux/sunrpc/metrics.h>
+
 #include "internal.h"
 #include "nfs4filelayout.h"
 
@@ -173,7 +175,7 @@ static void filelayout_read_prepare(struct rpc_task *task, void *data)
 
 	if (nfs41_setup_sequence(rdata->ds_clp->cl_session,
 				&rdata->args.seq_args, &rdata->res.seq_res,
-				0, task))
+				task))
 		return;
 
 	rpc_call_start(task);
@@ -189,6 +191,13 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)
 	rdata->mds_ops->rpc_call_done(task, data);
 }
 
+static void filelayout_read_count_stats(struct rpc_task *task, void *data)
+{
+	struct nfs_read_data *rdata = (struct nfs_read_data *)data;
+
+	rpc_count_iostats(task, NFS_SERVER(rdata->inode)->client->cl_metrics);
+}
+
 static void filelayout_read_release(void *data)
 {
 	struct nfs_read_data *rdata = (struct nfs_read_data *)data;
@@ -254,7 +263,7 @@ static void filelayout_write_prepare(struct rpc_task *task, void *data)
 
 	if (nfs41_setup_sequence(wdata->ds_clp->cl_session,
 				&wdata->args.seq_args, &wdata->res.seq_res,
-				0, task))
+				task))
 		return;
 
 	rpc_call_start(task);
@@ -268,6 +277,13 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data)
 	wdata->mds_ops->rpc_call_done(task, data);
 }
 
+static void filelayout_write_count_stats(struct rpc_task *task, void *data)
+{
+	struct nfs_write_data *wdata = (struct nfs_write_data *)data;
+
+	rpc_count_iostats(task, NFS_SERVER(wdata->inode)->client->cl_metrics);
+}
+
 static void filelayout_write_release(void *data)
 {
 	struct nfs_write_data *wdata = (struct nfs_write_data *)data;
@@ -288,18 +304,21 @@ static void filelayout_commit_release(void *data)
 struct rpc_call_ops filelayout_read_call_ops = {
 	.rpc_call_prepare = filelayout_read_prepare,
 	.rpc_call_done = filelayout_read_call_done,
+	.rpc_count_stats = filelayout_read_count_stats,
 	.rpc_release = filelayout_read_release,
 };
 
 struct rpc_call_ops filelayout_write_call_ops = {
 	.rpc_call_prepare = filelayout_write_prepare,
 	.rpc_call_done = filelayout_write_call_done,
+	.rpc_count_stats = filelayout_write_count_stats,
 	.rpc_release = filelayout_write_release,
 };
 
 struct rpc_call_ops filelayout_commit_call_ops = {
 	.rpc_call_prepare = filelayout_write_prepare,
 	.rpc_call_done = filelayout_write_call_done,
+	.rpc_count_stats = filelayout_write_count_stats,
 	.rpc_release = filelayout_commit_release,
 };
 
@@ -367,7 +386,8 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
 	idx = nfs4_fl_calc_ds_index(lseg, j);
 	ds = nfs4_fl_prepare_ds(lseg, idx);
 	if (!ds) {
-		printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__);
+		printk(KERN_ERR "NFS: %s: prepare_ds failed, use MDS\n",
+			__func__);
 		set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
 		set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
 		return PNFS_NOT_ATTEMPTED;
@@ -575,7 +595,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo,
 			goto out_err_free;
 		fl->fh_array[i]->size = be32_to_cpup(p++);
 		if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) {
-			printk(KERN_ERR "Too big fh %d received %d\n",
+			printk(KERN_ERR "NFS: Too big fh %d received %d\n",
 			       i, fl->fh_array[i]->size);
 			goto out_err_free;
 		}
@@ -797,7 +817,8 @@ static int filelayout_initiate_commit(struct nfs_write_data *data, int how)
 	idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
 	ds = nfs4_fl_prepare_ds(lseg, idx);
 	if (!ds) {
-		printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__);
+		printk(KERN_ERR "NFS: %s: prepare_ds failed, use MDS\n",
+			__func__);
 		set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
 		set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
 		prepare_to_resend_writes(data);
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 8ae9190..41677f0 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -108,58 +108,40 @@ same_sockaddr(struct sockaddr *addr1, struct sockaddr *addr2)
 	return false;
 }
 
-/*
- * Lookup DS by addresses.  The first matching address returns true.
- * nfs4_ds_cache_lock is held
- */
-static struct nfs4_pnfs_ds *
-_data_server_lookup_locked(struct list_head *dsaddrs)
+bool
+_same_data_server_addrs_locked(const struct list_head *dsaddrs1,
+			       const struct list_head *dsaddrs2)
 {
-	struct nfs4_pnfs_ds *ds;
 	struct nfs4_pnfs_ds_addr *da1, *da2;
 
-	list_for_each_entry(da1, dsaddrs, da_node) {
-		list_for_each_entry(ds, &nfs4_data_server_cache, ds_node) {
-			list_for_each_entry(da2, &ds->ds_addrs, da_node) {
-				if (same_sockaddr(
-					(struct sockaddr *)&da1->da_addr,
-					(struct sockaddr *)&da2->da_addr))
-					return ds;
-			}
-		}
+	/* step through both lists, comparing as we go */
+	for (da1 = list_first_entry(dsaddrs1, typeof(*da1), da_node),
+	     da2 = list_first_entry(dsaddrs2, typeof(*da2), da_node);
+	     da1 != NULL && da2 != NULL;
+	     da1 = list_entry(da1->da_node.next, typeof(*da1), da_node),
+	     da2 = list_entry(da2->da_node.next, typeof(*da2), da_node)) {
+		if (!same_sockaddr((struct sockaddr *)&da1->da_addr,
+				   (struct sockaddr *)&da2->da_addr))
+			return false;
 	}
-	return NULL;
+	if (da1 == NULL && da2 == NULL)
+		return true;
+
+	return false;
 }
 
 /*
- * Compare two lists of addresses.
+ * Lookup DS by addresses.  nfs4_ds_cache_lock is held
  */
-static bool
-_data_server_match_all_addrs_locked(struct list_head *dsaddrs1,
-				    struct list_head *dsaddrs2)
+static struct nfs4_pnfs_ds *
+_data_server_lookup_locked(const struct list_head *dsaddrs)
 {
-	struct nfs4_pnfs_ds_addr *da1, *da2;
-	size_t count1 = 0,
-	       count2 = 0;
-
-	list_for_each_entry(da1, dsaddrs1, da_node)
-		count1++;
-
-	list_for_each_entry(da2, dsaddrs2, da_node) {
-		bool found = false;
-		count2++;
-		list_for_each_entry(da1, dsaddrs1, da_node) {
-			if (same_sockaddr((struct sockaddr *)&da1->da_addr,
-				(struct sockaddr *)&da2->da_addr)) {
-				found = true;
-				break;
-			}
-		}
-		if (!found)
-			return false;
-	}
+	struct nfs4_pnfs_ds *ds;
 
-	return (count1 == count2);
+	list_for_each_entry(ds, &nfs4_data_server_cache, ds_node)
+		if (_same_data_server_addrs_locked(&ds->ds_addrs, dsaddrs))
+			return ds;
+	return NULL;
 }
 
 /*
@@ -356,11 +338,6 @@ nfs4_pnfs_ds_add(struct list_head *dsaddrs, gfp_t gfp_flags)
 		dprintk("%s add new data server %s\n", __func__,
 			ds->ds_remotestr);
 	} else {
-		if (!_data_server_match_all_addrs_locked(&tmp_ds->ds_addrs,
-							 dsaddrs)) {
-			dprintk("%s:  multipath address mismatch: %s != %s",
-				__func__, tmp_ds->ds_remotestr, remotestr);
-		}
 		kfree(remotestr);
 		kfree(ds);
 		atomic_inc(&tmp_ds->ds_count);
@@ -378,7 +355,7 @@ out:
  * Currently only supports ipv4, ipv6 and one multi-path address.
  */
 static struct nfs4_pnfs_ds_addr *
-decode_ds_addr(struct xdr_stream *streamp, gfp_t gfp_flags)
+decode_ds_addr(struct net *net, struct xdr_stream *streamp, gfp_t gfp_flags)
 {
 	struct nfs4_pnfs_ds_addr *da = NULL;
 	char *buf, *portstr;
@@ -457,7 +434,7 @@ decode_ds_addr(struct xdr_stream *streamp, gfp_t gfp_flags)
 
 	INIT_LIST_HEAD(&da->da_node);
 
-	if (!rpc_pton(buf, portstr-buf, (struct sockaddr *)&da->da_addr,
+	if (!rpc_pton(net, buf, portstr-buf, (struct sockaddr *)&da->da_addr,
 		      sizeof(da->da_addr))) {
 		dprintk("%s: error parsing address %s\n", __func__, buf);
 		goto out_free_da;
@@ -554,7 +531,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
 	cnt = be32_to_cpup(p);
 	dprintk("%s stripe count  %d\n", __func__, cnt);
 	if (cnt > NFS4_PNFS_MAX_STRIPE_CNT) {
-		printk(KERN_WARNING "%s: stripe count %d greater than "
+		printk(KERN_WARNING "NFS: %s: stripe count %d greater than "
 		       "supported maximum %d\n", __func__,
 			cnt, NFS4_PNFS_MAX_STRIPE_CNT);
 		goto out_err_free_scratch;
@@ -585,7 +562,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
 	num = be32_to_cpup(p);
 	dprintk("%s ds_num %u\n", __func__, num);
 	if (num > NFS4_PNFS_MAX_MULTI_CNT) {
-		printk(KERN_WARNING "%s: multipath count %d greater than "
+		printk(KERN_WARNING "NFS: %s: multipath count %d greater than "
 			"supported maximum %d\n", __func__,
 			num, NFS4_PNFS_MAX_MULTI_CNT);
 		goto out_err_free_stripe_indices;
@@ -593,7 +570,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
 
 	/* validate stripe indices are all < num */
 	if (max_stripe_index >= num) {
-		printk(KERN_WARNING "%s: stripe index %u >= num ds %u\n",
+		printk(KERN_WARNING "NFS: %s: stripe index %u >= num ds %u\n",
 			__func__, max_stripe_index, num);
 		goto out_err_free_stripe_indices;
 	}
@@ -625,7 +602,8 @@ decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags)
 
 		mp_count = be32_to_cpup(p); /* multipath count */
 		for (j = 0; j < mp_count; j++) {
-			da = decode_ds_addr(&stream, gfp_flags);
+			da = decode_ds_addr(NFS_SERVER(ino)->nfs_client->net,
+					    &stream, gfp_flags);
 			if (da)
 				list_add_tail(&da->da_node, &dsaddrs);
 		}
@@ -686,7 +664,7 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_fl
 
 	new = decode_device(inode, dev, gfp_flags);
 	if (!new) {
-		printk(KERN_WARNING "%s: Could not decode or add device\n",
+		printk(KERN_WARNING "NFS: %s: Could not decode or add device\n",
 			__func__);
 		return NULL;
 	}
@@ -835,7 +813,7 @@ nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
 	struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
 
 	if (ds == NULL) {
-		printk(KERN_ERR "%s: No data server for offset index %d\n",
+		printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
 			__func__, ds_idx);
 		return NULL;
 	}
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index bb80c49..667ea74 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -94,13 +94,14 @@ static int nfs4_validate_fspath(struct dentry *dentry,
 }
 
 static size_t nfs_parse_server_name(char *string, size_t len,
-		struct sockaddr *sa, size_t salen)
+		struct sockaddr *sa, size_t salen, struct nfs_server *server)
 {
 	ssize_t ret;
+	struct net *net = server->client->cl_xprt->xprt_net;
 
-	ret = rpc_pton(string, len, sa, salen);
+	ret = rpc_pton(net, string, len, sa, salen);
 	if (ret == 0) {
-		ret = nfs_dns_resolve_name(string, len, sa, salen);
+		ret = nfs_dns_resolve_name(net, string, len, sa, salen);
 		if (ret < 0)
 			ret = 0;
 	}
@@ -137,7 +138,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
 			continue;
 
 		mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
-				mountdata->addr, addr_bufsize);
+				mountdata->addr, addr_bufsize,
+				NFS_SB(mountdata->sb));
 		if (mountdata->addrlen == 0)
 			continue;
 
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f0c849c..a132837 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -72,6 +72,8 @@
 
 #define NFS4_MAX_LOOP_ON_RECOVER (10)
 
+static unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
+
 struct nfs4_opendata;
 static int _nfs4_proc_open(struct nfs4_opendata *data);
 static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
@@ -82,8 +84,8 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
 			    struct nfs_fattr *fattr, struct iattr *sattr,
 			    struct nfs4_state *state);
 #ifdef CONFIG_NFS_V4_1
-static int nfs41_test_stateid(struct nfs_server *, struct nfs4_state *);
-static int nfs41_free_stateid(struct nfs_server *, struct nfs4_state *);
+static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *);
+static int nfs41_free_stateid(struct nfs_server *, nfs4_stateid *);
 #endif
 /* Prevent leaks of NFSv4 errors into userland */
 static int nfs4_map_errors(int err)
@@ -193,7 +195,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
 	 * when talking to the server, we always send cookie 0
 	 * instead of 1 or 2.
 	 */
-	start = p = kmap_atomic(*readdir->pages, KM_USER0);
+	start = p = kmap_atomic(*readdir->pages);
 	
 	if (cookie == 0) {
 		*p++ = xdr_one;                                  /* next */
@@ -221,7 +223,7 @@ static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
 
 	readdir->pgbase = (char *)p - (char *)start;
 	readdir->count -= readdir->pgbase;
-	kunmap_atomic(start, KM_USER0);
+	kunmap_atomic(start);
 }
 
 static int nfs4_wait_clnt_recover(struct nfs_client *clp)
@@ -360,16 +362,14 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
  * When updating highest_used_slotid there may be "holes" in the bitmap
  * so we need to scan down from highest_used_slotid to 0 looking for the now
  * highest slotid in use.
- * If none found, highest_used_slotid is set to -1.
+ * If none found, highest_used_slotid is set to NFS4_NO_SLOT.
  *
  * Must be called while holding tbl->slot_tbl_lock
  */
 static void
-nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
+nfs4_free_slot(struct nfs4_slot_table *tbl, u32 slotid)
 {
-	int slotid = free_slotid;
-
-	BUG_ON(slotid < 0 || slotid >= NFS4_MAX_SLOT_TABLE);
+	BUG_ON(slotid >= NFS4_MAX_SLOT_TABLE);
 	/* clear used bit in bitmap */
 	__clear_bit(slotid, tbl->used_slots);
 
@@ -379,10 +379,16 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
 		if (slotid < tbl->max_slots)
 			tbl->highest_used_slotid = slotid;
 		else
-			tbl->highest_used_slotid = -1;
+			tbl->highest_used_slotid = NFS4_NO_SLOT;
 	}
-	dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
-		free_slotid, tbl->highest_used_slotid);
+	dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
+		slotid, tbl->highest_used_slotid);
+}
+
+bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy)
+{
+	rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
+	return true;
 }
 
 /*
@@ -390,16 +396,13 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
  */
 static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
 {
-	struct rpc_task *task;
-
 	if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
-		task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
-		if (task)
-			rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
+		rpc_wake_up_first(&ses->fc_slot_table.slot_tbl_waitq,
+				nfs4_set_task_privileged, NULL);
 		return;
 	}
 
-	if (ses->fc_slot_table.highest_used_slotid != -1)
+	if (ses->fc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
 		return;
 
 	dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__);
@@ -412,7 +415,7 @@ static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
 void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
 {
 	if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) ||
-	    ses->bc_slot_table.highest_used_slotid != -1)
+	    ses->bc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
 		return;
 	dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__);
 	complete(&ses->bc_slot_table.complete);
@@ -507,25 +510,25 @@ static int nfs4_sequence_done(struct rpc_task *task,
  * nfs4_find_slot looks for an unset bit in the used_slots bitmap.
  * If found, we mark the slot as used, update the highest_used_slotid,
  * and respectively set up the sequence operation args.
- * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise.
+ * The slot number is returned if found, or NFS4_NO_SLOT otherwise.
  *
  * Note: must be called with under the slot_tbl_lock.
  */
-static u8
+static u32
 nfs4_find_slot(struct nfs4_slot_table *tbl)
 {
-	int slotid;
-	u8 ret_id = NFS4_MAX_SLOT_TABLE;
-	BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
+	u32 slotid;
+	u32 ret_id = NFS4_NO_SLOT;
 
-	dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n",
+	dprintk("--> %s used_slots=%04lx highest_used=%u max_slots=%u\n",
 		__func__, tbl->used_slots[0], tbl->highest_used_slotid,
 		tbl->max_slots);
 	slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots);
 	if (slotid >= tbl->max_slots)
 		goto out;
 	__set_bit(slotid, tbl->used_slots);
-	if (slotid > tbl->highest_used_slotid)
+	if (slotid > tbl->highest_used_slotid ||
+			tbl->highest_used_slotid == NFS4_NO_SLOT)
 		tbl->highest_used_slotid = slotid;
 	ret_id = slotid;
 out:
@@ -534,15 +537,25 @@ out:
 	return ret_id;
 }
 
+static void nfs41_init_sequence(struct nfs4_sequence_args *args,
+		struct nfs4_sequence_res *res, int cache_reply)
+{
+	args->sa_session = NULL;
+	args->sa_cache_this = 0;
+	if (cache_reply)
+		args->sa_cache_this = 1;
+	res->sr_session = NULL;
+	res->sr_slot = NULL;
+}
+
 int nfs41_setup_sequence(struct nfs4_session *session,
 				struct nfs4_sequence_args *args,
 				struct nfs4_sequence_res *res,
-				int cache_reply,
 				struct rpc_task *task)
 {
 	struct nfs4_slot *slot;
 	struct nfs4_slot_table *tbl;
-	u8 slotid;
+	u32 slotid;
 
 	dprintk("--> %s\n", __func__);
 	/* slot already allocated? */
@@ -570,7 +583,7 @@ int nfs41_setup_sequence(struct nfs4_session *session,
 	}
 
 	slotid = nfs4_find_slot(tbl);
-	if (slotid == NFS4_MAX_SLOT_TABLE) {
+	if (slotid == NFS4_NO_SLOT) {
 		rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
 		spin_unlock(&tbl->slot_tbl_lock);
 		dprintk("<-- %s: no free slots\n", __func__);
@@ -582,7 +595,6 @@ int nfs41_setup_sequence(struct nfs4_session *session,
 	slot = tbl->slots + slotid;
 	args->sa_session = session;
 	args->sa_slotid = slotid;
-	args->sa_cache_this = cache_reply;
 
 	dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
 
@@ -602,24 +614,19 @@ EXPORT_SYMBOL_GPL(nfs41_setup_sequence);
 int nfs4_setup_sequence(const struct nfs_server *server,
 			struct nfs4_sequence_args *args,
 			struct nfs4_sequence_res *res,
-			int cache_reply,
 			struct rpc_task *task)
 {
 	struct nfs4_session *session = nfs4_get_session(server);
 	int ret = 0;
 
-	if (session == NULL) {
-		args->sa_session = NULL;
-		res->sr_session = NULL;
+	if (session == NULL)
 		goto out;
-	}
 
 	dprintk("--> %s clp %p session %p sr_slot %td\n",
 		__func__, session->clp, session, res->sr_slot ?
 			res->sr_slot - session->fc_slot_table.slots : -1);
 
-	ret = nfs41_setup_sequence(session, args, res, cache_reply,
-				   task);
+	ret = nfs41_setup_sequence(session, args, res, task);
 out:
 	dprintk("<-- %s status=%d\n", __func__, ret);
 	return ret;
@@ -629,7 +636,6 @@ struct nfs41_call_sync_data {
 	const struct nfs_server *seq_server;
 	struct nfs4_sequence_args *seq_args;
 	struct nfs4_sequence_res *seq_res;
-	int cache_reply;
 };
 
 static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
@@ -639,7 +645,7 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
 	dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);
 
 	if (nfs4_setup_sequence(data->seq_server, data->seq_args,
-				data->seq_res, data->cache_reply, task))
+				data->seq_res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -672,7 +678,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
 				   struct rpc_message *msg,
 				   struct nfs4_sequence_args *args,
 				   struct nfs4_sequence_res *res,
-				   int cache_reply,
 				   int privileged)
 {
 	int ret;
@@ -681,7 +686,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
 		.seq_server = server,
 		.seq_args = args,
 		.seq_res = res,
-		.cache_reply = cache_reply,
 	};
 	struct rpc_task_setup task_setup = {
 		.rpc_client = clnt,
@@ -690,7 +694,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
 		.callback_data = &data
 	};
 
-	res->sr_slot = NULL;
 	if (privileged)
 		task_setup.callback_ops = &nfs41_call_priv_sync_ops;
 	task = rpc_run_task(&task_setup);
@@ -710,10 +713,17 @@ int _nfs4_call_sync_session(struct rpc_clnt *clnt,
 			    struct nfs4_sequence_res *res,
 			    int cache_reply)
 {
-	return nfs4_call_sync_sequence(clnt, server, msg, args, res, cache_reply, 0);
+	nfs41_init_sequence(args, res, cache_reply);
+	return nfs4_call_sync_sequence(clnt, server, msg, args, res, 0);
 }
 
 #else
+static inline
+void nfs41_init_sequence(struct nfs4_sequence_args *args,
+		struct nfs4_sequence_res *res, int cache_reply)
+{
+}
+
 static int nfs4_sequence_done(struct rpc_task *task,
 			       struct nfs4_sequence_res *res)
 {
@@ -728,7 +738,7 @@ int _nfs4_call_sync(struct rpc_clnt *clnt,
 		    struct nfs4_sequence_res *res,
 		    int cache_reply)
 {
-	args->sa_session = res->sr_session = NULL;
+	nfs41_init_sequence(args, res, cache_reply);
 	return rpc_call_sync(clnt, msg, 0);
 }
 
@@ -815,13 +825,13 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
 	p->o_arg.open_flags = flags;
 	p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
 	p->o_arg.clientid = server->nfs_client->cl_clientid;
-	p->o_arg.id = sp->so_owner_id.id;
+	p->o_arg.id = sp->so_seqid.owner_id;
 	p->o_arg.name = &dentry->d_name;
 	p->o_arg.server = server;
 	p->o_arg.bitmask = server->attr_bitmask;
 	p->o_arg.dir_bitmask = server->cache_consistency_bitmask;
 	p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
-	if (flags & O_CREAT) {
+	if (attrs != NULL && attrs->ia_valid != 0) {
 		u32 *s;
 
 		p->o_arg.u.attrs = &p->attrs;
@@ -878,7 +888,7 @@ static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode
 {
 	int ret = 0;
 
-	if (open_mode & O_EXCL)
+	if (open_mode & (O_EXCL|O_TRUNC))
 		goto out;
 	switch (mode & (FMODE_READ|FMODE_WRITE)) {
 		case FMODE_READ:
@@ -1026,7 +1036,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
 	struct nfs4_state *state = opendata->state;
 	struct nfs_inode *nfsi = NFS_I(state->inode);
 	struct nfs_delegation *delegation;
-	int open_mode = opendata->o_arg.open_flags & O_EXCL;
+	int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC);
 	fmode_t fmode = opendata->o_arg.fmode;
 	nfs4_stateid stateid;
 	int ret = -EAGAIN;
@@ -1440,7 +1450,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
 		rcu_read_unlock();
 	}
 	/* Update sequence id. */
-	data->o_arg.id = sp->so_owner_id.id;
+	data->o_arg.id = sp->so_seqid.owner_id;
 	data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
 	if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
 		task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
@@ -1449,7 +1459,7 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
 	data->timestamp = jiffies;
 	if (nfs4_setup_sequence(data->o_arg.server,
 				&data->o_arg.seq_args,
-				&data->o_res.seq_res, 1, task))
+				&data->o_res.seq_res, task))
 		return;
 	rpc_call_start(task);
 	return;
@@ -1551,6 +1561,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
 	};
 	int status;
 
+	nfs41_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1);
 	kref_get(&data->kref);
 	data->rpc_done = 0;
 	data->rpc_status = 0;
@@ -1712,15 +1723,32 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
 }
 
 #if defined(CONFIG_NFS_V4_1)
-static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
+static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *stateid, unsigned int flags)
 {
-	int status;
+	int status = NFS_OK;
 	struct nfs_server *server = NFS_SERVER(state->inode);
 
-	status = nfs41_test_stateid(server, state);
-	if (status == NFS_OK)
-		return 0;
-	nfs41_free_stateid(server, state);
+	if (state->flags & flags) {
+		status = nfs41_test_stateid(server, stateid);
+		if (status != NFS_OK) {
+			nfs41_free_stateid(server, stateid);
+			state->flags &= ~flags;
+		}
+	}
+	return status;
+}
+
+static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
+{
+	int deleg_status, open_status;
+	int deleg_flags = 1 << NFS_DELEGATED_STATE;
+	int open_flags = (1 << NFS_O_RDONLY_STATE) | (1 << NFS_O_WRONLY_STATE) | (1 << NFS_O_RDWR_STATE);
+
+	deleg_status = nfs41_check_expired_stateid(state, &state->stateid, deleg_flags);
+	open_status = nfs41_check_expired_stateid(state,  &state->open_stateid, open_flags);
+
+	if ((deleg_status == NFS_OK) && (open_status == NFS_OK))
+		return NFS_OK;
 	return nfs4_open_expired(sp, state);
 }
 #endif
@@ -1754,7 +1782,8 @@ static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, fmode_t fmode
 
 	/* Protect against reboot recovery conflicts */
 	status = -ENOMEM;
-	if (!(sp = nfs4_get_state_owner(server, cred))) {
+	sp = nfs4_get_state_owner(server, cred, GFP_KERNEL);
+	if (sp == NULL) {
 		dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n");
 		goto out_err;
 	}
@@ -2029,8 +2058,9 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
 	nfs_fattr_init(calldata->res.fattr);
 	calldata->timestamp = jiffies;
 	if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
-				&calldata->arg.seq_args, &calldata->res.seq_res,
-				1, task))
+				&calldata->arg.seq_args,
+				&calldata->res.seq_res,
+				task))
 		return;
 	rpc_call_start(task);
 }
@@ -2074,6 +2104,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
 	calldata = kzalloc(sizeof(*calldata), gfp_mask);
 	if (calldata == NULL)
 		goto out;
+	nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 1);
 	calldata->inode = state->inode;
 	calldata->state = state;
 	calldata->arg.fh = NFS_FH(state->inode);
@@ -2420,6 +2451,10 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 		}
 	}
 
+	/* Deal with open(O_TRUNC) */
+	if (sattr->ia_valid & ATTR_OPEN)
+		sattr->ia_valid &= ~(ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
+
 	status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
 	if (status == 0)
 		nfs_setattr_update_inode(inode, sattr);
@@ -2494,7 +2529,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs4_accessargs args = {
 		.fh = NFS_FH(inode),
-		.bitmask = server->attr_bitmask,
+		.bitmask = server->cache_consistency_bitmask,
 	};
 	struct nfs4_accessres res = {
 		.server = server,
@@ -2712,8 +2747,8 @@ static void nfs4_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
 
 	args->bitmask = server->cache_consistency_bitmask;
 	res->server = server;
-	res->seq_res.sr_slot = NULL;
 	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVE];
+	nfs41_init_sequence(&args->seq_args, &res->seq_res, 1);
 }
 
 static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
@@ -2738,6 +2773,7 @@ static void nfs4_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
 	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME];
 	arg->bitmask = server->attr_bitmask;
 	res->server = server;
+	nfs41_init_sequence(&arg->seq_args, &res->seq_res, 1);
 }
 
 static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
@@ -3232,6 +3268,7 @@ static void nfs4_proc_read_setup(struct nfs_read_data *data, struct rpc_message
 	data->timestamp   = jiffies;
 	data->read_done_cb = nfs4_read_done_cb;
 	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ];
+	nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 0);
 }
 
 /* Reset the the nfs_read_data to send the read to the MDS. */
@@ -3305,6 +3342,7 @@ static void nfs4_proc_write_setup(struct nfs_write_data *data, struct rpc_messag
 	data->timestamp   = jiffies;
 
 	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE];
+	nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
 }
 
 static int nfs4_commit_done_cb(struct rpc_task *task, struct nfs_write_data *data)
@@ -3339,6 +3377,7 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
 		data->write_done_cb = nfs4_commit_done_cb;
 	data->res.server = server;
 	msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
+	nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
 }
 
 struct nfs4_renewdata {
@@ -3575,8 +3614,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
 	}
 	if (npages > 1) {
 		/* for decoding across pages */
-		args.acl_scratch = alloc_page(GFP_KERNEL);
-		if (!args.acl_scratch)
+		res.acl_scratch = alloc_page(GFP_KERNEL);
+		if (!res.acl_scratch)
 			goto out_free;
 	}
 	args.acl_len = npages * PAGE_SIZE;
@@ -3612,8 +3651,8 @@ out_free:
 	for (i = 0; i < npages; i++)
 		if (pages[i])
 			__free_page(pages[i]);
-	if (args.acl_scratch)
-		__free_page(args.acl_scratch);
+	if (res.acl_scratch)
+		__free_page(res.acl_scratch);
 	return ret;
 }
 
@@ -3891,7 +3930,7 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
 
 	if (nfs4_setup_sequence(d_data->res.server,
 				&d_data->args.seq_args,
-				&d_data->res.seq_res, 1, task))
+				&d_data->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -3925,6 +3964,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
 	data = kzalloc(sizeof(*data), GFP_NOFS);
 	if (data == NULL)
 		return -ENOMEM;
+	nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
 	data->args.fhandle = &data->fh;
 	data->args.stateid = &data->stateid;
 	data->args.bitmask = server->attr_bitmask;
@@ -4016,7 +4056,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
 	if (status != 0)
 		goto out;
 	lsp = request->fl_u.nfs4_fl.owner;
-	arg.lock_owner.id = lsp->ls_id.id;
+	arg.lock_owner.id = lsp->ls_seqid.owner_id;
 	arg.lock_owner.s_dev = server->s_dev;
 	status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
 	switch (status) {
@@ -4142,7 +4182,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
 	calldata->timestamp = jiffies;
 	if (nfs4_setup_sequence(calldata->server,
 				&calldata->arg.seq_args,
-				&calldata->res.seq_res, 1, task))
+				&calldata->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -4182,6 +4222,7 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
 		return ERR_PTR(-ENOMEM);
 	}
 
+	nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
 	msg.rpc_argp = &data->arg;
 	msg.rpc_resp = &data->res;
 	task_setup_data.callback_data = data;
@@ -4261,7 +4302,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
 		goto out_free_seqid;
 	p->arg.lock_stateid = &lsp->ls_stateid;
 	p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
-	p->arg.lock_owner.id = lsp->ls_id.id;
+	p->arg.lock_owner.id = lsp->ls_seqid.owner_id;
 	p->arg.lock_owner.s_dev = server->s_dev;
 	p->res.lock_seqid = p->arg.lock_seqid;
 	p->lsp = lsp;
@@ -4297,7 +4338,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
 	data->timestamp = jiffies;
 	if (nfs4_setup_sequence(data->server,
 				&data->arg.seq_args,
-				&data->res.seq_res, 1, task))
+				&data->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 	dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
@@ -4415,6 +4456,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
 			data->arg.reclaim = NFS_LOCK_RECLAIM;
 		task_setup_data.callback_ops = &nfs4_recover_lock_ops;
 	}
+	nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
 	msg.rpc_argp = &data->arg;
 	msg.rpc_resp = &data->res;
 	task_setup_data.callback_data = data;
@@ -4479,15 +4521,34 @@ out:
 }
 
 #if defined(CONFIG_NFS_V4_1)
-static int nfs41_lock_expired(struct nfs4_state *state, struct file_lock *request)
+static int nfs41_check_expired_locks(struct nfs4_state *state)
 {
-	int status;
+	int status, ret = NFS_OK;
+	struct nfs4_lock_state *lsp;
 	struct nfs_server *server = NFS_SERVER(state->inode);
 
-	status = nfs41_test_stateid(server, state);
+	list_for_each_entry(lsp, &state->lock_states, ls_locks) {
+		if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
+			status = nfs41_test_stateid(server, &lsp->ls_stateid);
+			if (status != NFS_OK) {
+				nfs41_free_stateid(server, &lsp->ls_stateid);
+				lsp->ls_flags &= ~NFS_LOCK_INITIALIZED;
+				ret = status;
+			}
+		}
+	};
+
+	return ret;
+}
+
+static int nfs41_lock_expired(struct nfs4_state *state, struct file_lock *request)
+{
+	int status = NFS_OK;
+
+	if (test_bit(LK_STATE_IN_USE, &state->flags))
+		status = nfs41_check_expired_locks(state);
 	if (status == NFS_OK)
-		return 0;
-	nfs41_free_stateid(server, state);
+		return status;
 	return nfs4_lock_expired(state, request);
 }
 #endif
@@ -4523,7 +4584,8 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
 	/* Note: we always want to sleep here! */
 	request->fl_flags = fl_flags | FL_SLEEP;
 	if (do_vfs_lock(request->fl_file, request) < 0)
-		printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __func__);
+		printk(KERN_WARNING "NFS: %s: VFS is out of sync with lock "
+			"manager!\n", __func__);
 out_unlock:
 	up_read(&nfsi->rwsem);
 out:
@@ -4603,8 +4665,8 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
 		err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW);
 		switch (err) {
 			default:
-				printk(KERN_ERR "%s: unhandled error %d.\n",
-						__func__, err);
+				printk(KERN_ERR "NFS: %s: unhandled error "
+					"%d.\n", __func__, err);
 			case 0:
 			case -ESTALE:
 				goto out;
@@ -4678,7 +4740,7 @@ void nfs4_release_lockowner(const struct nfs4_lock_state *lsp)
 	if (!args)
 		return;
 	args->lock_owner.clientid = server->nfs_client->cl_clientid;
-	args->lock_owner.id = lsp->ls_id.id;
+	args->lock_owner.id = lsp->ls_seqid.owner_id;
 	args->lock_owner.s_dev = server->s_dev;
 	msg.rpc_argp = args;
 	rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, args);
@@ -4883,8 +4945,10 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 				clp->cl_rpcclient->cl_auth->au_flavor);
 
 	res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL);
-	if (unlikely(!res.server_scope))
-		return -ENOMEM;
+	if (unlikely(!res.server_scope)) {
+		status = -ENOMEM;
+		goto out;
+	}
 
 	status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
 	if (!status)
@@ -4901,12 +4965,13 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
 			clp->server_scope = NULL;
 		}
 
-		if (!clp->server_scope)
+		if (!clp->server_scope) {
 			clp->server_scope = res.server_scope;
-		else
-			kfree(res.server_scope);
+			goto out;
+		}
 	}
-
+	kfree(res.server_scope);
+out:
 	dprintk("<-- %s status= %d\n", __func__, status);
 	return status;
 }
@@ -4930,7 +4995,7 @@ static void nfs4_get_lease_time_prepare(struct rpc_task *task,
 	   since we're invoked within one */
 	ret = nfs41_setup_sequence(data->clp->cl_session,
 				   &data->args->la_seq_args,
-				   &data->res->lr_seq_res, 0, task);
+				   &data->res->lr_seq_res, task);
 
 	BUG_ON(ret == -EAGAIN);
 	rpc_call_start(task);
@@ -4994,6 +5059,7 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
 	};
 	int status;
 
+	nfs41_init_sequence(&args.la_seq_args, &res.lr_seq_res, 0);
 	dprintk("--> %s\n", __func__);
 	task = rpc_run_task(&task_setup);
 
@@ -5008,37 +5074,53 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
 	return status;
 }
 
+static struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags)
+{
+	return kcalloc(max_slots, sizeof(struct nfs4_slot), gfp_flags);
+}
+
+static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
+		struct nfs4_slot *new,
+		u32 max_slots,
+		u32 ivalue)
+{
+	struct nfs4_slot *old = NULL;
+	u32 i;
+
+	spin_lock(&tbl->slot_tbl_lock);
+	if (new) {
+		old = tbl->slots;
+		tbl->slots = new;
+		tbl->max_slots = max_slots;
+	}
+	tbl->highest_used_slotid = -1;	/* no slot is currently used */
+	for (i = 0; i < tbl->max_slots; i++)
+		tbl->slots[i].seq_nr = ivalue;
+	spin_unlock(&tbl->slot_tbl_lock);
+	kfree(old);
+}
+
 /*
- * Reset a slot table
+ * (re)Initialise a slot table
  */
-static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
-				 int ivalue)
+static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
+				 u32 ivalue)
 {
 	struct nfs4_slot *new = NULL;
-	int i;
-	int ret = 0;
+	int ret = -ENOMEM;
 
 	dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
 		max_reqs, tbl->max_slots);
 
 	/* Does the newly negotiated max_reqs match the existing slot table? */
 	if (max_reqs != tbl->max_slots) {
-		ret = -ENOMEM;
-		new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
-			      GFP_NOFS);
+		new = nfs4_alloc_slots(max_reqs, GFP_NOFS);
 		if (!new)
 			goto out;
-		ret = 0;
-		kfree(tbl->slots);
 	}
-	spin_lock(&tbl->slot_tbl_lock);
-	if (new) {
-		tbl->slots = new;
-		tbl->max_slots = max_reqs;
-	}
-	for (i = 0; i < tbl->max_slots; ++i)
-		tbl->slots[i].seq_nr = ivalue;
-	spin_unlock(&tbl->slot_tbl_lock);
+	ret = 0;
+
+	nfs4_add_and_init_slots(tbl, new, max_reqs, ivalue);
 	dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
 		tbl, tbl->slots, tbl->max_slots);
 out:
@@ -5061,36 +5143,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
 }
 
 /*
- * Initialize slot table
- */
-static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
-		int max_slots, int ivalue)
-{
-	struct nfs4_slot *slot;
-	int ret = -ENOMEM;
-
-	BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
-
-	dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
-
-	slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
-	if (!slot)
-		goto out;
-	ret = 0;
-
-	spin_lock(&tbl->slot_tbl_lock);
-	tbl->max_slots = max_slots;
-	tbl->slots = slot;
-	tbl->highest_used_slotid = -1;  /* no slot is currently used */
-	spin_unlock(&tbl->slot_tbl_lock);
-	dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
-		tbl, tbl->slots, tbl->max_slots);
-out:
-	dprintk("<-- %s: return %d\n", __func__, ret);
-	return ret;
-}
-
-/*
  * Initialize or reset the forechannel and backchannel tables
  */
 static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
@@ -5101,25 +5153,16 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
 	dprintk("--> %s\n", __func__);
 	/* Fore channel */
 	tbl = &ses->fc_slot_table;
-	if (tbl->slots == NULL) {
-		status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
-		if (status) /* -ENOMEM */
-			return status;
-	} else {
-		status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
-		if (status)
-			return status;
-	}
+	status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
+	if (status) /* -ENOMEM */
+		return status;
 	/* Back channel */
 	tbl = &ses->bc_slot_table;
-	if (tbl->slots == NULL) {
-		status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
-		if (status)
-			/* Fore and back channel share a connection so get
-			 * both slot tables or neither */
-			nfs4_destroy_slot_tables(ses);
-	} else
-		status = nfs4_reset_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
+	status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
+	if (status && tbl->slots == NULL)
+		/* Fore and back channel share a connection so get
+		 * both slot tables or neither */
+		nfs4_destroy_slot_tables(ses);
 	return status;
 }
 
@@ -5133,13 +5176,13 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
 		return NULL;
 
 	tbl = &session->fc_slot_table;
-	tbl->highest_used_slotid = -1;
+	tbl->highest_used_slotid = NFS4_NO_SLOT;
 	spin_lock_init(&tbl->slot_tbl_lock);
 	rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, "ForeChannel Slot table");
 	init_completion(&tbl->complete);
 
 	tbl = &session->bc_slot_table;
-	tbl->highest_used_slotid = -1;
+	tbl->highest_used_slotid = NFS4_NO_SLOT;
 	spin_lock_init(&tbl->slot_tbl_lock);
 	rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
 	init_completion(&tbl->complete);
@@ -5184,7 +5227,7 @@ static void nfs4_init_channel_attrs(struct nfs41_create_session_args *args)
 	args->fc_attrs.max_rqst_sz = mxrqst_sz;
 	args->fc_attrs.max_resp_sz = mxresp_sz;
 	args->fc_attrs.max_ops = NFS4_MAX_OPS;
-	args->fc_attrs.max_reqs = session->clp->cl_rpcclient->cl_xprt->max_reqs;
+	args->fc_attrs.max_reqs = max_session_slots;
 
 	dprintk("%s: Fore Channel : max_rqst_sz=%u max_resp_sz=%u "
 		"max_ops=%u max_reqs=%u\n",
@@ -5224,6 +5267,8 @@ static int nfs4_verify_fore_channel_attrs(struct nfs41_create_session_args *args
 		return -EINVAL;
 	if (rcvd->max_reqs == 0)
 		return -EINVAL;
+	if (rcvd->max_reqs > NFS4_MAX_SLOT_TABLE)
+		rcvd->max_reqs = NFS4_MAX_SLOT_TABLE;
 	return 0;
 }
 
@@ -5239,9 +5284,9 @@ static int nfs4_verify_back_channel_attrs(struct nfs41_create_session_args *args
 	if (rcvd->max_resp_sz_cached > sent->max_resp_sz_cached)
 		return -EINVAL;
 	/* These would render the backchannel useless: */
-	if (rcvd->max_ops  == 0)
+	if (rcvd->max_ops != sent->max_ops)
 		return -EINVAL;
-	if (rcvd->max_reqs == 0)
+	if (rcvd->max_reqs != sent->max_reqs)
 		return -EINVAL;
 	return 0;
 }
@@ -5344,7 +5389,7 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
 
 	if (status)
 		printk(KERN_WARNING
-			"Got error %d from the server on DESTROY_SESSION. "
+			"NFS: Got error %d from the server on DESTROY_SESSION. "
 			"Session has been destroyed regardless...\n", status);
 
 	dprintk("<-- nfs4_proc_destroy_session\n");
@@ -5467,7 +5512,7 @@ static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
 	args = task->tk_msg.rpc_argp;
 	res = task->tk_msg.rpc_resp;
 
-	if (nfs41_setup_sequence(clp->cl_session, args, res, 0, task))
+	if (nfs41_setup_sequence(clp->cl_session, args, res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -5499,6 +5544,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_
 		nfs_put_client(clp);
 		return ERR_PTR(-ENOMEM);
 	}
+	nfs41_init_sequence(&calldata->args, &calldata->res, 0);
 	msg.rpc_argp = &calldata->args;
 	msg.rpc_resp = &calldata->res;
 	calldata->clp = clp;
@@ -5560,7 +5606,7 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
 	rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
 	if (nfs41_setup_sequence(calldata->clp->cl_session,
 				&calldata->arg.seq_args,
-				&calldata->res.seq_res, 0, task))
+				&calldata->res.seq_res, task))
 		return;
 
 	rpc_call_start(task);
@@ -5639,6 +5685,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
 	calldata->clp = clp;
 	calldata->arg.one_fs = 0;
 
+	nfs41_init_sequence(&calldata->arg.seq_args, &calldata->res.seq_res, 0);
 	msg.rpc_argp = &calldata->arg;
 	msg.rpc_resp = &calldata->res;
 	task_setup_data.callback_data = calldata;
@@ -5670,7 +5717,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
 	 * to be no way to prevent it completely.
 	 */
 	if (nfs4_setup_sequence(server, &lgp->args.seq_args,
-				&lgp->res.seq_res, 0, task))
+				&lgp->res.seq_res, task))
 		return;
 	if (pnfs_choose_layoutget_stateid(&lgp->args.stateid,
 					  NFS_I(lgp->args.inode)->layout,
@@ -5745,6 +5792,7 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp)
 
 	lgp->res.layoutp = &lgp->args.layout;
 	lgp->res.seq_res.sr_slot = NULL;
+	nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
 	task = rpc_run_task(&task_setup_data);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
@@ -5765,7 +5813,7 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
 
 	dprintk("--> %s\n", __func__);
 	if (nfs41_setup_sequence(lrp->clp->cl_session, &lrp->args.seq_args,
-				&lrp->res.seq_res, 0, task))
+				&lrp->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -5831,6 +5879,7 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp)
 	int status;
 
 	dprintk("--> %s\n", __func__);
+	nfs41_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1);
 	task = rpc_run_task(&task_setup_data);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
@@ -5931,7 +5980,7 @@ static void nfs4_layoutcommit_prepare(struct rpc_task *task, void *calldata)
 	struct nfs_server *server = NFS_SERVER(data->args.inode);
 
 	if (nfs4_setup_sequence(server, &data->args.seq_args,
-				&data->res.seq_res, 1, task))
+				&data->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -6018,6 +6067,7 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
 		data->args.lastbytewritten,
 		data->args.inode->i_ino);
 
+	nfs41_init_sequence(&data->args.seq_args, &data->res.seq_res, 1);
 	task = rpc_run_task(&task_setup_data);
 	if (IS_ERR(task))
 		return PTR_ERR(task);
@@ -6111,11 +6161,12 @@ out_freepage:
 out:
 	return err;
 }
-static int _nfs41_test_stateid(struct nfs_server *server, struct nfs4_state *state)
+
+static int _nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
 {
 	int status;
 	struct nfs41_test_stateid_args args = {
-		.stateid = &state->stateid,
+		.stateid = stateid,
 	};
 	struct nfs41_test_stateid_res res;
 	struct rpc_message msg = {
@@ -6123,28 +6174,31 @@ static int _nfs41_test_stateid(struct nfs_server *server, struct nfs4_state *sta
 		.rpc_argp = &args,
 		.rpc_resp = &res,
 	};
-	args.seq_args.sa_session = res.seq_res.sr_session = NULL;
-	status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 0, 1);
+
+	nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
+	status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
+
+	if (status == NFS_OK)
+		return res.status;
 	return status;
 }
 
-static int nfs41_test_stateid(struct nfs_server *server, struct nfs4_state *state)
+static int nfs41_test_stateid(struct nfs_server *server, nfs4_stateid *stateid)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs41_test_stateid(server, state),
+				_nfs41_test_stateid(server, stateid),
 				&exception);
 	} while (exception.retry);
 	return err;
 }
 
-static int _nfs4_free_stateid(struct nfs_server *server, struct nfs4_state *state)
+static int _nfs4_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
 {
-	int status;
 	struct nfs41_free_stateid_args args = {
-		.stateid = &state->stateid,
+		.stateid = stateid,
 	};
 	struct nfs41_free_stateid_res res;
 	struct rpc_message msg = {
@@ -6153,18 +6207,17 @@ static int _nfs4_free_stateid(struct nfs_server *server, struct nfs4_state *stat
 		.rpc_resp = &res,
 	};
 
-	args.seq_args.sa_session = res.seq_res.sr_session = NULL;
-	status = nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 0, 1);
-	return status;
+	nfs41_init_sequence(&args.seq_args, &res.seq_res, 0);
+	return nfs4_call_sync_sequence(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
 }
 
-static int nfs41_free_stateid(struct nfs_server *server, struct nfs4_state *state)
+static int nfs41_free_stateid(struct nfs_server *server, nfs4_stateid *stateid)
 {
 	struct nfs4_exception exception = { };
 	int err;
 	do {
 		err = nfs4_handle_exception(server,
-				_nfs4_free_stateid(server, state),
+				_nfs4_free_stateid(server, stateid),
 				&exception);
 	} while (exception.retry);
 	return err;
@@ -6321,6 +6374,10 @@ const struct xattr_handler *nfs4_xattr_handlers[] = {
 	NULL
 };
 
+module_param(max_session_slots, ushort, 0644);
+MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
+		"requests the client will negotiate");
+
 /*
  * Local variables:
  *  c-basic-offset: 8
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a53f33b..653bfd7 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -190,30 +190,29 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
 static void nfs4_end_drain_session(struct nfs_client *clp)
 {
 	struct nfs4_session *ses = clp->cl_session;
+	struct nfs4_slot_table *tbl;
 	int max_slots;
 
 	if (ses == NULL)
 		return;
+	tbl = &ses->fc_slot_table;
 	if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
-		spin_lock(&ses->fc_slot_table.slot_tbl_lock);
-		max_slots = ses->fc_slot_table.max_slots;
+		spin_lock(&tbl->slot_tbl_lock);
+		max_slots = tbl->max_slots;
 		while (max_slots--) {
-			struct rpc_task *task;
-
-			task = rpc_wake_up_next(&ses->fc_slot_table.
-						slot_tbl_waitq);
-			if (!task)
+			if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
+						nfs4_set_task_privileged,
+						NULL) == NULL)
 				break;
-			rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
 		}
-		spin_unlock(&ses->fc_slot_table.slot_tbl_lock);
+		spin_unlock(&tbl->slot_tbl_lock);
 	}
 }
 
 static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
 {
 	spin_lock(&tbl->slot_tbl_lock);
-	if (tbl->highest_used_slotid != -1) {
+	if (tbl->highest_used_slotid != NFS4_NO_SLOT) {
 		INIT_COMPLETION(tbl->complete);
 		spin_unlock(&tbl->slot_tbl_lock);
 		return wait_for_completion_interruptible(&tbl->complete);
@@ -317,62 +316,6 @@ out:
 	return cred;
 }
 
-static void nfs_alloc_unique_id_locked(struct rb_root *root,
-				       struct nfs_unique_id *new,
-				       __u64 minval, int maxbits)
-{
-	struct rb_node **p, *parent;
-	struct nfs_unique_id *pos;
-	__u64 mask = ~0ULL;
-
-	if (maxbits < 64)
-		mask = (1ULL << maxbits) - 1ULL;
-
-	/* Ensure distribution is more or less flat */
-	get_random_bytes(&new->id, sizeof(new->id));
-	new->id &= mask;
-	if (new->id < minval)
-		new->id += minval;
-retry:
-	p = &root->rb_node;
-	parent = NULL;
-
-	while (*p != NULL) {
-		parent = *p;
-		pos = rb_entry(parent, struct nfs_unique_id, rb_node);
-
-		if (new->id < pos->id)
-			p = &(*p)->rb_left;
-		else if (new->id > pos->id)
-			p = &(*p)->rb_right;
-		else
-			goto id_exists;
-	}
-	rb_link_node(&new->rb_node, parent, p);
-	rb_insert_color(&new->rb_node, root);
-	return;
-id_exists:
-	for (;;) {
-		new->id++;
-		if (new->id < minval || (new->id & mask) != new->id) {
-			new->id = minval;
-			break;
-		}
-		parent = rb_next(parent);
-		if (parent == NULL)
-			break;
-		pos = rb_entry(parent, struct nfs_unique_id, rb_node);
-		if (new->id < pos->id)
-			break;
-	}
-	goto retry;
-}
-
-static void nfs_free_unique_id(struct rb_root *root, struct nfs_unique_id *id)
-{
-	rb_erase(&id->rb_node, root);
-}
-
 static struct nfs4_state_owner *
 nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
 {
@@ -405,6 +348,7 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
 	struct rb_node **p = &server->state_owners.rb_node,
 		       *parent = NULL;
 	struct nfs4_state_owner *sp;
+	int err;
 
 	while (*p != NULL) {
 		parent = *p;
@@ -421,8 +365,9 @@ nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
 			return sp;
 		}
 	}
-	nfs_alloc_unique_id_locked(&server->openowner_id,
-					&new->so_owner_id, 1, 64);
+	err = ida_get_new(&server->openowner_id, &new->so_seqid.owner_id);
+	if (err)
+		return ERR_PTR(err);
 	rb_link_node(&new->so_server_node, parent, p);
 	rb_insert_color(&new->so_server_node, &server->state_owners);
 	return new;
@@ -435,7 +380,23 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)
 
 	if (!RB_EMPTY_NODE(&sp->so_server_node))
 		rb_erase(&sp->so_server_node, &server->state_owners);
-	nfs_free_unique_id(&server->openowner_id, &sp->so_owner_id);
+	ida_remove(&server->openowner_id, sp->so_seqid.owner_id);
+}
+
+static void
+nfs4_init_seqid_counter(struct nfs_seqid_counter *sc)
+{
+	sc->flags = 0;
+	sc->counter = 0;
+	spin_lock_init(&sc->lock);
+	INIT_LIST_HEAD(&sc->list);
+	rpc_init_wait_queue(&sc->wait, "Seqid_waitqueue");
+}
+
+static void
+nfs4_destroy_seqid_counter(struct nfs_seqid_counter *sc)
+{
+	rpc_destroy_wait_queue(&sc->wait);
 }
 
 /*
@@ -444,19 +405,20 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)
  *
  */
 static struct nfs4_state_owner *
-nfs4_alloc_state_owner(void)
+nfs4_alloc_state_owner(struct nfs_server *server,
+		struct rpc_cred *cred,
+		gfp_t gfp_flags)
 {
 	struct nfs4_state_owner *sp;
 
-	sp = kzalloc(sizeof(*sp),GFP_NOFS);
+	sp = kzalloc(sizeof(*sp), gfp_flags);
 	if (!sp)
 		return NULL;
+	sp->so_server = server;
+	sp->so_cred = get_rpccred(cred);
 	spin_lock_init(&sp->so_lock);
 	INIT_LIST_HEAD(&sp->so_states);
-	rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
-	sp->so_seqid.sequence = &sp->so_sequence;
-	spin_lock_init(&sp->so_sequence.lock);
-	INIT_LIST_HEAD(&sp->so_sequence.list);
+	nfs4_init_seqid_counter(&sp->so_seqid);
 	atomic_set(&sp->so_count, 1);
 	INIT_LIST_HEAD(&sp->so_lru);
 	return sp;
@@ -478,7 +440,7 @@ nfs4_drop_state_owner(struct nfs4_state_owner *sp)
 
 static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
 {
-	rpc_destroy_wait_queue(&sp->so_sequence.wait);
+	nfs4_destroy_seqid_counter(&sp->so_seqid);
 	put_rpccred(sp->so_cred);
 	kfree(sp);
 }
@@ -516,7 +478,8 @@ static void nfs4_gc_state_owners(struct nfs_server *server)
  * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL.
  */
 struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
-					      struct rpc_cred *cred)
+					      struct rpc_cred *cred,
+					      gfp_t gfp_flags)
 {
 	struct nfs_client *clp = server->nfs_client;
 	struct nfs4_state_owner *sp, *new;
@@ -526,20 +489,18 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
 	spin_unlock(&clp->cl_lock);
 	if (sp != NULL)
 		goto out;
-	new = nfs4_alloc_state_owner();
+	new = nfs4_alloc_state_owner(server, cred, gfp_flags);
 	if (new == NULL)
 		goto out;
-	new->so_server = server;
-	new->so_cred = cred;
-	spin_lock(&clp->cl_lock);
-	sp = nfs4_insert_state_owner_locked(new);
-	spin_unlock(&clp->cl_lock);
-	if (sp == new)
-		get_rpccred(cred);
-	else {
-		rpc_destroy_wait_queue(&new->so_sequence.wait);
-		kfree(new);
-	}
+	do {
+		if (ida_pre_get(&server->openowner_id, gfp_flags) == 0)
+			break;
+		spin_lock(&clp->cl_lock);
+		sp = nfs4_insert_state_owner_locked(new);
+		spin_unlock(&clp->cl_lock);
+	} while (sp == ERR_PTR(-EAGAIN));
+	if (sp != new)
+		nfs4_free_state_owner(new);
 out:
 	nfs4_gc_state_owners(server);
 	return sp;
@@ -795,15 +756,11 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
 {
 	struct nfs4_lock_state *lsp;
 	struct nfs_server *server = state->owner->so_server;
-	struct nfs_client *clp = server->nfs_client;
 
 	lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
 	if (lsp == NULL)
 		return NULL;
-	rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue");
-	spin_lock_init(&lsp->ls_sequence.lock);
-	INIT_LIST_HEAD(&lsp->ls_sequence.list);
-	lsp->ls_seqid.sequence = &lsp->ls_sequence;
+	nfs4_init_seqid_counter(&lsp->ls_seqid);
 	atomic_set(&lsp->ls_count, 1);
 	lsp->ls_state = state;
 	lsp->ls_owner.lo_type = type;
@@ -815,25 +772,24 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
 		lsp->ls_owner.lo_u.posix_owner = fl_owner;
 		break;
 	default:
-		kfree(lsp);
-		return NULL;
+		goto out_free;
 	}
-	spin_lock(&clp->cl_lock);
-	nfs_alloc_unique_id_locked(&server->lockowner_id, &lsp->ls_id, 1, 64);
-	spin_unlock(&clp->cl_lock);
+	lsp->ls_seqid.owner_id = ida_simple_get(&server->lockowner_id, 0, 0, GFP_NOFS);
+	if (lsp->ls_seqid.owner_id < 0)
+		goto out_free;
 	INIT_LIST_HEAD(&lsp->ls_locks);
 	return lsp;
+out_free:
+	kfree(lsp);
+	return NULL;
 }
 
 static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
 {
 	struct nfs_server *server = lsp->ls_state->owner->so_server;
-	struct nfs_client *clp = server->nfs_client;
 
-	spin_lock(&clp->cl_lock);
-	nfs_free_unique_id(&server->lockowner_id, &lsp->ls_id);
-	spin_unlock(&clp->cl_lock);
-	rpc_destroy_wait_queue(&lsp->ls_sequence.wait);
+	ida_simple_remove(&server->lockowner_id, lsp->ls_seqid.owner_id);
+	nfs4_destroy_seqid_counter(&lsp->ls_seqid);
 	kfree(lsp);
 }
 
@@ -960,20 +916,28 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_m
 	if (new != NULL) {
 		new->sequence = counter;
 		INIT_LIST_HEAD(&new->list);
+		new->task = NULL;
 	}
 	return new;
 }
 
 void nfs_release_seqid(struct nfs_seqid *seqid)
 {
-	if (!list_empty(&seqid->list)) {
-		struct rpc_sequence *sequence = seqid->sequence->sequence;
+	struct nfs_seqid_counter *sequence;
+
+	if (list_empty(&seqid->list))
+		return;
+	sequence = seqid->sequence;
+	spin_lock(&sequence->lock);
+	list_del_init(&seqid->list);
+	if (!list_empty(&sequence->list)) {
+		struct nfs_seqid *next;
 
-		spin_lock(&sequence->lock);
-		list_del_init(&seqid->list);
-		spin_unlock(&sequence->lock);
-		rpc_wake_up(&sequence->wait);
+		next = list_first_entry(&sequence->list,
+				struct nfs_seqid, list);
+		rpc_wake_up_queued_task(&sequence->wait, next->task);
 	}
+	spin_unlock(&sequence->lock);
 }
 
 void nfs_free_seqid(struct nfs_seqid *seqid)
@@ -989,7 +953,7 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
  */
 static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
 {
-	BUG_ON(list_first_entry(&seqid->sequence->sequence->list, struct nfs_seqid, list) != seqid);
+	BUG_ON(list_first_entry(&seqid->sequence->list, struct nfs_seqid, list) != seqid);
 	switch (status) {
 		case 0:
 			break;
@@ -1040,10 +1004,11 @@ void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
 
 int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
 {
-	struct rpc_sequence *sequence = seqid->sequence->sequence;
+	struct nfs_seqid_counter *sequence = seqid->sequence;
 	int status = 0;
 
 	spin_lock(&sequence->lock);
+	seqid->task = task;
 	if (list_empty(&seqid->list))
 		list_add_tail(&seqid->list, &sequence->list);
 	if (list_first_entry(&sequence->list, struct nfs_seqid, list) == seqid)
@@ -1132,6 +1097,8 @@ void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4
 {
 	struct nfs_client *clp = server->nfs_client;
 
+	if (test_and_clear_bit(NFS_DELEGATED_STATE, &state->flags))
+		nfs_async_inode_return_delegation(state->inode, &state->stateid);
 	nfs4_state_mark_reclaim_nograce(clp, state);
 	nfs4_schedule_state_manager(clp);
 }
@@ -1173,8 +1140,8 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
 			case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
 				goto out;
 			default:
-				printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
-						__func__, status);
+				printk(KERN_ERR "NFS: %s: unhandled error %d. "
+					"Zeroing state\n", __func__, status);
 			case -ENOMEM:
 			case -NFS4ERR_DENIED:
 			case -NFS4ERR_RECLAIM_BAD:
@@ -1220,8 +1187,8 @@ restart:
 				spin_lock(&state->state_lock);
 				list_for_each_entry(lock, &state->lock_states, ls_locks) {
 					if (!(lock->ls_flags & NFS_LOCK_INITIALIZED))
-						printk("%s: Lock reclaim failed!\n",
-							__func__);
+						printk("NFS: %s: Lock reclaim "
+							"failed!\n", __func__);
 				}
 				spin_unlock(&state->state_lock);
 				nfs4_put_open_state(state);
@@ -1230,8 +1197,8 @@ restart:
 		}
 		switch (status) {
 			default:
-				printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
-						__func__, status);
+				printk(KERN_ERR "NFS: %s: unhandled error %d. "
+					"Zeroing state\n", __func__, status);
 			case -ENOENT:
 			case -ENOMEM:
 			case -ESTALE:
@@ -1799,7 +1766,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
 	} while (atomic_read(&clp->cl_count) > 1);
 	return;
 out_error:
-	printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"
+	printk(KERN_WARNING "NFS: state manager failed on NFSv4 server %s"
 			" with error %d\n", clp->cl_hostname, -status);
 	nfs4_end_drain_session(clp);
 	nfs4_clear_state_manager_bit(clp);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 95e92e4..92bc5f4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1023,7 +1023,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const
 	 * Now we backfill the bitmap and the attribute buffer length.
 	 */
 	if (len != ((char *)p - (char *)q) + 4) {
-		printk(KERN_ERR "nfs: Attr length error, %u != %Zu\n",
+		printk(KERN_ERR "NFS: Attr length error, %u != %Zu\n",
 				len, ((char *)p - (char *)q) + 4);
 		BUG();
 	}
@@ -2522,7 +2522,6 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
 
 	xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
 		args->acl_pages, args->acl_pgbase, args->acl_len);
-	xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
 
 	encode_nops(&hdr);
 }
@@ -3561,6 +3560,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st
 	status = 0;
 	if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
 		goto out;
+	status = -EIO;
+	/* Ignore borken servers that return unrequested attrs */
+	if (unlikely(res == NULL))
+		goto out;
 	dprintk("%s: fsroot ", __func__);
 	status = decode_pathname(xdr, &res->fs_path);
 	if (unlikely(status != 0))
@@ -4295,6 +4298,7 @@ xdr_error:
 
 static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 		struct nfs_fattr *fattr, struct nfs_fh *fh,
+		struct nfs4_fs_locations *fs_loc,
 		const struct nfs_server *server)
 {
 	int status;
@@ -4342,9 +4346,7 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
 		goto xdr_error;
 	fattr->valid |= status;
 
-	status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
-						struct nfs4_fs_locations,
-						fattr));
+	status = decode_attr_fs_locations(xdr, bitmap, fs_loc);
 	if (status < 0)
 		goto xdr_error;
 	fattr->valid |= status;
@@ -4408,7 +4410,8 @@ xdr_error:
 }
 
 static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
-		struct nfs_fh *fh, const struct nfs_server *server)
+		struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc,
+		const struct nfs_server *server)
 {
 	__be32 *savep;
 	uint32_t attrlen,
@@ -4427,7 +4430,7 @@ static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fat
 	if (status < 0)
 		goto xdr_error;
 
-	status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server);
+	status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server);
 	if (status < 0)
 		goto xdr_error;
 
@@ -4440,7 +4443,7 @@ xdr_error:
 static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
 		const struct nfs_server *server)
 {
-	return decode_getfattr_generic(xdr, fattr, NULL, server);
+	return decode_getfattr_generic(xdr, fattr, NULL, NULL, server);
 }
 
 /*
@@ -4464,8 +4467,8 @@ static int decode_first_pnfs_layout_type(struct xdr_stream *xdr,
 		return 0;
 	}
 	if (num > 1)
-		printk(KERN_INFO "%s: Warning: Multiple pNFS layout drivers "
-			"per filesystem not supported\n", __func__);
+		printk(KERN_INFO "NFS: %s: Warning: Multiple pNFS layout "
+			"drivers per filesystem not supported\n", __func__);
 
 	/* Decode and set first layout type, move xdr->p past unused types */
 	p = xdr_inline_decode(xdr, num * 4);
@@ -5286,8 +5289,8 @@ static int decode_chan_attrs(struct xdr_stream *xdr,
 	attrs->max_reqs = be32_to_cpup(p++);
 	nr_attrs = be32_to_cpup(p);
 	if (unlikely(nr_attrs > 1)) {
-		printk(KERN_WARNING "%s: Invalid rdma channel attrs count %u\n",
-			__func__, nr_attrs);
+		printk(KERN_WARNING "NFS: %s: Invalid rdma channel attrs "
+			"count %u\n", __func__, nr_attrs);
 		return -EINVAL;
 	}
 	if (nr_attrs == 1) {
@@ -5444,7 +5447,7 @@ static int decode_getdevicelist(struct xdr_stream *xdr,
 	dprintk("%s: num_dev %d\n", __func__, res->num_devs);
 
 	if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) {
-		printk(KERN_ERR "%s too many result dev_num %u\n",
+		printk(KERN_ERR "NFS: %s too many result dev_num %u\n",
 				__func__, res->num_devs);
 		return -EIO;
 	}
@@ -5667,7 +5670,8 @@ static int decode_test_stateid(struct xdr_stream *xdr,
 	if (unlikely(!p))
 		goto out_overflow;
 	res->status = be32_to_cpup(p++);
-	return res->status;
+
+	return status;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
 out:
@@ -6032,6 +6036,10 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
 	struct compound_hdr hdr;
 	int status;
 
+	if (res->acl_scratch != NULL) {
+		void *p = page_address(res->acl_scratch);
+		xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
+	}
 	status = decode_compound_hdr(xdr, &hdr);
 	if (status)
 		goto out;
@@ -6580,8 +6588,9 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
 	if (status)
 		goto out;
 	xdr_enter_page(xdr, PAGE_SIZE);
-	status = decode_getfattr(xdr, &res->fs_locations->fattr,
-				 res->fs_locations->server);
+	status = decode_getfattr_generic(xdr, &res->fs_locations->fattr,
+					 NULL, res->fs_locations,
+					 res->fs_locations->server);
 out:
 	return status;
 }
@@ -6961,7 +6970,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
 		goto out_overflow;
 
 	if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
-					entry->server) < 0)
+				  NULL, entry->server) < 0)
 		goto out_overflow;
 	if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
 		entry->ino = entry->fattr->mounted_on_fileid;
@@ -7109,7 +7118,7 @@ struct rpc_procinfo	nfs4_procedures[] = {
 #endif /* CONFIG_NFS_V4_1 */
 };
 
-struct rpc_version		nfs_version4 = {
+const struct rpc_version nfs_version4 = {
 	.number			= 4,
 	.nrprocs		= ARRAY_SIZE(nfs4_procedures),
 	.procs			= nfs4_procedures
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 55d0128..405a62b 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -582,10 +582,10 @@ objlayout_init(void)
 
 	if (ret)
 		printk(KERN_INFO
-			"%s: Registering OSD pNFS Layout Driver failed: error=%d\n",
+			"NFS: %s: Registering OSD pNFS Layout Driver failed: error=%d\n",
 			__func__, ret);
 	else
-		printk(KERN_INFO "%s: Registered OSD pNFS Layout Driver\n",
+		printk(KERN_INFO "NFS: %s: Registered OSD pNFS Layout Driver\n",
 			__func__);
 	return ret;
 }
@@ -594,7 +594,7 @@ static void __exit
 objlayout_exit(void)
 {
 	pnfs_unregister_layoutdriver(&objlayout_type);
-	printk(KERN_INFO "%s: Unregistered OSD pNFS Layout Driver\n",
+	printk(KERN_INFO "NFS: %s: Unregistered OSD pNFS Layout Driver\n",
 	       __func__);
 }
 
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
index b3c2903..2bd1852 100644
--- a/fs/nfs/objlayout/objlayout.c
+++ b/fs/nfs/objlayout/objlayout.c
@@ -490,9 +490,9 @@ encode_accumulated_error(struct objlayout *objlay, __be32 *p)
 			if (!ioerr->oer_errno)
 				continue;
 
-			printk(KERN_ERR "%s: err[%d]: errno=%d is_write=%d "
-				"dev(%llx:%llx) par=0x%llx obj=0x%llx "
-				"offset=0x%llx length=0x%llx\n",
+			printk(KERN_ERR "NFS: %s: err[%d]: errno=%d "
+				"is_write=%d dev(%llx:%llx) par=0x%llx "
+				"obj=0x%llx offset=0x%llx length=0x%llx\n",
 				__func__, i, ioerr->oer_errno,
 				ioerr->oer_iswrite,
 				_DEVID_LO(&ioerr->oer_component.oid_device_id),
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 5668f7c..77a184e 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -13,6 +13,7 @@
 #include <linux/file.h>
 #include <linux/sched.h>
 #include <linux/sunrpc/clnt.h>
+#include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_page.h>
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 17149a4..a534216 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -101,8 +101,8 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh,
 		goto out_no_driver;
 	if (!(server->nfs_client->cl_exchange_flags &
 		 (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) {
-		printk(KERN_ERR "%s: id %u cl_exchange_flags 0x%x\n", __func__,
-		       id, server->nfs_client->cl_exchange_flags);
+		printk(KERN_ERR "NFS: %s: id %u cl_exchange_flags 0x%x\n",
+			__func__, id, server->nfs_client->cl_exchange_flags);
 		goto out_no_driver;
 	}
 	ld_type = find_pnfs_driver(id);
@@ -122,8 +122,8 @@ set_pnfs_layoutdriver(struct nfs_server *server, const struct nfs_fh *mntfh,
 	server->pnfs_curr_ld = ld_type;
 	if (ld_type->set_layoutdriver
 	    && ld_type->set_layoutdriver(server, mntfh)) {
-		printk(KERN_ERR "%s: Error initializing pNFS layout driver %u.\n",
-				__func__, id);
+		printk(KERN_ERR "NFS: %s: Error initializing pNFS layout "
+			"driver %u.\n", __func__, id);
 		module_put(ld_type->owner);
 		goto out_no_driver;
 	}
@@ -143,11 +143,11 @@ pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
 	struct pnfs_layoutdriver_type *tmp;
 
 	if (ld_type->id == 0) {
-		printk(KERN_ERR "%s id 0 is reserved\n", __func__);
+		printk(KERN_ERR "NFS: %s id 0 is reserved\n", __func__);
 		return status;
 	}
 	if (!ld_type->alloc_lseg || !ld_type->free_lseg) {
-		printk(KERN_ERR "%s Layout driver must provide "
+		printk(KERN_ERR "NFS: %s Layout driver must provide "
 		       "alloc_lseg and free_lseg.\n", __func__);
 		return status;
 	}
@@ -160,7 +160,7 @@ pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *ld_type)
 		dprintk("%s Registering id:%u name:%s\n", __func__, ld_type->id,
 			ld_type->name);
 	} else {
-		printk(KERN_ERR "%s Module with id %d already loaded!\n",
+		printk(KERN_ERR "NFS: %s Module with id %d already loaded!\n",
 			__func__, ld_type->id);
 	}
 	spin_unlock(&pnfs_spinlock);
@@ -590,7 +590,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
 	max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
 	max_pages = max_resp_sz >> PAGE_SHIFT;
 
-	pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags);
+	pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
 	if (!pages)
 		goto out_err_free;
 
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index cfa175c..3c2540d 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -472,7 +472,7 @@ void nfs_read_prepare(struct rpc_task *task, void *calldata)
 
 	if (nfs4_setup_sequence(NFS_SERVER(data->inode),
 				&data->args.seq_args, &data->res.seq_res,
-				0, task))
+				task))
 		return;
 	rpc_call_start(task);
 }
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 3dfa4f1..6708f30 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -52,6 +52,7 @@
 #include <linux/nfs_xdr.h>
 #include <linux/magic.h>
 #include <linux/parser.h>
+#include <linux/nsproxy.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -79,7 +80,7 @@ enum {
 	Opt_cto, Opt_nocto,
 	Opt_ac, Opt_noac,
 	Opt_lock, Opt_nolock,
-	Opt_v2, Opt_v3, Opt_v4,
+	Opt_v2, Opt_v3, Opt_v4, Opt_v4_0, Opt_v4_1,
 	Opt_udp, Opt_tcp, Opt_rdma,
 	Opt_acl, Opt_noacl,
 	Opt_rdirplus, Opt_nordirplus,
@@ -135,6 +136,8 @@ static const match_table_t nfs_mount_option_tokens = {
 	{ Opt_v2, "v2" },
 	{ Opt_v3, "v3" },
 	{ Opt_v4, "v4" },
+	{ Opt_v4_0, "v4.0" },
+	{ Opt_v4_1, "v4.1" },
 	{ Opt_udp, "udp" },
 	{ Opt_tcp, "tcp" },
 	{ Opt_rdma, "rdma" },
@@ -908,6 +911,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
 		data->auth_flavor_len	= 1;
 		data->version		= version;
 		data->minorversion	= 0;
+		data->net		= current->nsproxy->net_ns;
 		security_init_mnt_opts(&data->lsm_opts);
 	}
 	return data;
@@ -1169,6 +1173,16 @@ static int nfs_parse_mount_options(char *raw,
 			mnt->flags &= ~NFS_MOUNT_VER3;
 			mnt->version = 4;
 			break;
+		case Opt_v4_0:
+			mnt->flags &= ~NFS_MOUNT_VER3;
+			mnt->version = 4;
+			mnt->minorversion = 0;
+			break;
+		case Opt_v4_1:
+			mnt->flags &= ~NFS_MOUNT_VER3;
+			mnt->version = 4;
+			mnt->minorversion = 1;
+			break;
 		case Opt_udp:
 			mnt->flags &= ~NFS_MOUNT_TCP;
 			mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1405,7 +1419,7 @@ static int nfs_parse_mount_options(char *raw,
 			if (string == NULL)
 				goto out_nomem;
 			mnt->nfs_server.addrlen =
-				rpc_pton(string, strlen(string),
+				rpc_pton(mnt->net, string, strlen(string),
 					(struct sockaddr *)
 					&mnt->nfs_server.address,
 					sizeof(mnt->nfs_server.address));
@@ -1427,7 +1441,7 @@ static int nfs_parse_mount_options(char *raw,
 			if (string == NULL)
 				goto out_nomem;
 			mnt->mount_server.addrlen =
-				rpc_pton(string, strlen(string),
+				rpc_pton(mnt->net, string, strlen(string),
 					(struct sockaddr *)
 					&mnt->mount_server.address,
 					sizeof(mnt->mount_server.address));
@@ -1516,6 +1530,9 @@ static int nfs_parse_mount_options(char *raw,
 	if (!sloppy && invalid_option)
 		return 0;
 
+	if (mnt->minorversion && mnt->version != 4)
+		goto out_minorversion_mismatch;
+
 	/*
 	 * verify that any proto=/mountproto= options match the address
 	 * familiies in the addr=/mountaddr= options.
@@ -1549,6 +1566,10 @@ out_invalid_address:
 out_invalid_value:
 	printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
 	return 0;
+out_minorversion_mismatch:
+	printk(KERN_INFO "NFS: mount option vers=%u does not support "
+			 "minorversion=%u\n", mnt->version, mnt->minorversion);
+	return 0;
 out_nomem:
 	printk(KERN_INFO "NFS: not enough memory to parse option\n");
 	return 0;
@@ -1622,6 +1643,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
 		.noresvport	= args->flags & NFS_MOUNT_NORESVPORT,
 		.auth_flav_len	= &server_authlist_len,
 		.auth_flavs	= server_authlist,
+		.net		= args->net,
 	};
 	int status;
 
@@ -2663,8 +2685,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
 	if (!s->s_root) {
 		/* initial superblock/root creation */
 		nfs4_fill_super(s);
-		nfs_fscache_get_super_cookie(
-			s, data ? data->fscache_uniq : NULL, NULL);
+		nfs_fscache_get_super_cookie(s, data->fscache_uniq, NULL);
 	}
 
 	mntroot = nfs4_get_root(s, mntfh, dev_name);
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index 978aaeb..ad4d2e7 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -32,7 +32,6 @@ static ctl_table nfs_cb_sysctls[] = {
 		.extra1 = (int *)&nfs_set_port_min,
 		.extra2 = (int *)&nfs_set_port_max,
 	},
-#ifndef CONFIG_NFS_USE_NEW_IDMAPPER
 	{
 		.procname = "idmap_cache_timeout",
 		.data = &nfs_idmap_cache_timeout,
@@ -40,7 +39,6 @@ static ctl_table nfs_cb_sysctls[] = {
 		.mode = 0644,
 		.proc_handler = proc_dointvec_jiffies,
 	},
-#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
 #endif
 	{
 		.procname	= "nfs_mountpoint_timeout",
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 4f9319a..490613b 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -114,7 +114,7 @@ void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
 	struct nfs_server *server = NFS_SERVER(data->dir);
 
 	if (nfs4_setup_sequence(server, &data->args.seq_args,
-				&data->res.seq_res, 1, task))
+				&data->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
@@ -410,7 +410,7 @@ static void nfs_rename_prepare(struct rpc_task *task, void *calldata)
 	struct nfs_server *server = NFS_SERVER(data->old_dir);
 
 	if (nfs4_setup_sequence(server, &data->args.seq_args,
-				&data->res.seq_res, 1, task))
+				&data->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 834f0fe..0b1831d 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1135,7 +1135,7 @@ void nfs_write_prepare(struct rpc_task *task, void *calldata)
 
 	if (nfs4_setup_sequence(NFS_SERVER(data->inode),
 				&data->args.seq_args,
-				&data->res.seq_res, 1, task))
+				&data->res.seq_res, task))
 		return;
 	rpc_call_start(task);
 }
diff --git a/fs/nfsd/current_stateid.h b/fs/nfsd/current_stateid.h
new file mode 100644
index 0000000..4123551
--- /dev/null
+++ b/fs/nfsd/current_stateid.h
@@ -0,0 +1,28 @@
+#ifndef _NFSD4_CURRENT_STATE_H
+#define _NFSD4_CURRENT_STATE_H
+
+#include "state.h"
+#include "xdr4.h"
+
+extern void clear_current_stateid(struct nfsd4_compound_state *cstate);
+/*
+ * functions to set current state id
+ */
+extern void nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *);
+extern void nfsd4_set_openstateid(struct nfsd4_compound_state *, struct nfsd4_open *);
+extern void nfsd4_set_lockstateid(struct nfsd4_compound_state *, struct nfsd4_lock *);
+extern void nfsd4_set_closestateid(struct nfsd4_compound_state *, struct nfsd4_close *);
+
+/*
+ * functions to consume current state id
+ */
+extern void nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *);
+extern void nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *, struct nfsd4_delegreturn *);
+extern void nfsd4_get_freestateid(struct nfsd4_compound_state *, struct nfsd4_free_stateid *);
+extern void nfsd4_get_setattrstateid(struct nfsd4_compound_state *, struct nfsd4_setattr *);
+extern void nfsd4_get_closestateid(struct nfsd4_compound_state *, struct nfsd4_close *);
+extern void nfsd4_get_lockustateid(struct nfsd4_compound_state *, struct nfsd4_locku *);
+extern void nfsd4_get_readstateid(struct nfsd4_compound_state *, struct nfsd4_read *);
+extern void nfsd4_get_writestateid(struct nfsd4_compound_state *, struct nfsd4_write *);
+
+#endif   /* _NFSD4_CURRENT_STATE_H */
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index cf8a6bd..8e9689a 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -87,7 +87,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
 	struct svc_expkey key;
 	struct svc_expkey *ek = NULL;
 
-	if (mlen < 1 || mesg[mlen-1] != '\n')
+	if (mesg[mlen - 1] != '\n')
 		return -EINVAL;
 	mesg[mlen-1] = 0;
 
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 6f3ebb4..0e262f3 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -605,24 +605,24 @@ static struct rpc_version nfs_cb_version4 = {
 	.procs			= nfs4_cb_procedures
 };
 
-static struct rpc_version *nfs_cb_version[] = {
+static const struct rpc_version *nfs_cb_version[] = {
 	&nfs_cb_version4,
 };
 
-static struct rpc_program cb_program;
+static const struct rpc_program cb_program;
 
 static struct rpc_stat cb_stats = {
 	.program		= &cb_program
 };
 
 #define NFS4_CALLBACK 0x40000000
-static struct rpc_program cb_program = {
+static const struct rpc_program cb_program = {
 	.name			= "nfs4_cb",
 	.number			= NFS4_CALLBACK,
 	.nrvers			= ARRAY_SIZE(nfs_cb_version),
 	.version		= nfs_cb_version,
 	.stats			= &cb_stats,
-	.pipe_dir_name		= "/nfsd4_cb",
+	.pipe_dir_name		= "nfsd4_cb",
 };
 
 static int max_cb_time(void)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 896da74..cdb7ca3 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -39,6 +39,7 @@
 #include "cache.h"
 #include "xdr4.h"
 #include "vfs.h"
+#include "current_stateid.h"
 
 #define NFSDDBG_FACILITY		NFSDDBG_PROC
 
@@ -310,9 +311,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
 		return nfserr_inval;
 
-	/* We don't yet support WANT bits: */
-	open->op_share_access &= NFS4_SHARE_ACCESS_MASK;
-
 	open->op_created = 0;
 	/*
 	 * RFC5661 18.51.3
@@ -452,6 +450,10 @@ nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		return nfserr_restorefh;
 
 	fh_dup2(&cstate->current_fh, &cstate->save_fh);
+	if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) {
+		memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
+		SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
+	}
 	return nfs_ok;
 }
 
@@ -463,6 +465,10 @@ nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		return nfserr_nofilehandle;
 
 	fh_dup2(&cstate->save_fh, &cstate->current_fh);
+	if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) {
+		memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t));
+		SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG);
+	}
 	return nfs_ok;
 }
 
@@ -1000,6 +1006,8 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
 typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
 			      void *);
 typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
+typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *);
+typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *);
 
 enum nfsd4_op_flags {
 	ALLOWED_WITHOUT_FH = 1 << 0,	/* No current filehandle required */
@@ -1025,6 +1033,10 @@ enum nfsd4_op_flags {
 	 * the v4.0 case).
 	 */
 	OP_CACHEME = 1 << 6,
+	/*
+	 * These are ops which clear current state id.
+	 */
+	OP_CLEAR_STATEID = 1 << 7,
 };
 
 struct nfsd4_operation {
@@ -1033,6 +1045,8 @@ struct nfsd4_operation {
 	char *op_name;
 	/* Try to get response size before operation */
 	nfsd4op_rsize op_rsize_bop;
+	stateid_setter op_get_currentstateid;
+	stateid_getter op_set_currentstateid;
 };
 
 static struct nfsd4_operation nfsd4_ops[];
@@ -1215,13 +1229,23 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
 		if (op->status)
 			goto encode_op;
 
-		if (opdesc->op_func)
+		if (opdesc->op_func) {
+			if (opdesc->op_get_currentstateid)
+				opdesc->op_get_currentstateid(cstate, &op->u);
 			op->status = opdesc->op_func(rqstp, cstate, &op->u);
-		else
+		} else
 			BUG_ON(op->status == nfs_ok);
 
-		if (!op->status && need_wrongsec_check(rqstp))
-			op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp);
+		if (!op->status) {
+			if (opdesc->op_set_currentstateid)
+				opdesc->op_set_currentstateid(cstate, &op->u);
+
+			if (opdesc->op_flags & OP_CLEAR_STATEID)
+				clear_current_stateid(cstate);
+
+			if (need_wrongsec_check(rqstp))
+				op->status = check_nfsd_access(cstate->current_fh.fh_export, rqstp);
+		}
 
 encode_op:
 		/* Only from SEQUENCE */
@@ -1413,6 +1437,8 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING,
 		.op_name = "OP_CLOSE",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid,
+		.op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid,
 	},
 	[OP_COMMIT] = {
 		.op_func = (nfsd4op_func)nfsd4_commit,
@@ -1422,7 +1448,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 	},
 	[OP_CREATE] = {
 		.op_func = (nfsd4op_func)nfsd4_create,
-		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
+		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID,
 		.op_name = "OP_CREATE",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize,
 	},
@@ -1431,6 +1457,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING,
 		.op_name = "OP_DELEGRETURN",
 		.op_rsize_bop = nfsd4_only_status_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid,
 	},
 	[OP_GETATTR] = {
 		.op_func = (nfsd4op_func)nfsd4_getattr,
@@ -1453,6 +1480,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING,
 		.op_name = "OP_LOCK",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
+		.op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid,
 	},
 	[OP_LOCKT] = {
 		.op_func = (nfsd4op_func)nfsd4_lockt,
@@ -1463,15 +1491,16 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING,
 		.op_name = "OP_LOCKU",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid,
 	},
 	[OP_LOOKUP] = {
 		.op_func = (nfsd4op_func)nfsd4_lookup,
-		.op_flags = OP_HANDLES_WRONGSEC,
+		.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
 		.op_name = "OP_LOOKUP",
 	},
 	[OP_LOOKUPP] = {
 		.op_func = (nfsd4op_func)nfsd4_lookupp,
-		.op_flags = OP_HANDLES_WRONGSEC,
+		.op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
 		.op_name = "OP_LOOKUPP",
 	},
 	[OP_NVERIFY] = {
@@ -1483,6 +1512,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
 		.op_name = "OP_OPEN",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize,
+		.op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid,
 	},
 	[OP_OPEN_CONFIRM] = {
 		.op_func = (nfsd4op_func)nfsd4_open_confirm,
@@ -1495,25 +1525,30 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING,
 		.op_name = "OP_OPEN_DOWNGRADE",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid,
+		.op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid,
 	},
 	[OP_PUTFH] = {
 		.op_func = (nfsd4op_func)nfsd4_putfh,
 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
-				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
+				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
+				| OP_CLEAR_STATEID,
 		.op_name = "OP_PUTFH",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
 	},
 	[OP_PUTPUBFH] = {
 		.op_func = (nfsd4op_func)nfsd4_putrootfh,
 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
-				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
+				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
+				| OP_CLEAR_STATEID,
 		.op_name = "OP_PUTPUBFH",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
 	},
 	[OP_PUTROOTFH] = {
 		.op_func = (nfsd4op_func)nfsd4_putrootfh,
 		.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
-				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
+				| OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING
+				| OP_CLEAR_STATEID,
 		.op_name = "OP_PUTROOTFH",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
 	},
@@ -1522,6 +1557,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING,
 		.op_name = "OP_READ",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid,
 	},
 	[OP_READDIR] = {
 		.op_func = (nfsd4op_func)nfsd4_readdir,
@@ -1576,6 +1612,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_name = "OP_SETATTR",
 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid,
 	},
 	[OP_SETCLIENTID] = {
 		.op_func = (nfsd4op_func)nfsd4_setclientid,
@@ -1600,6 +1637,7 @@ static struct nfsd4_operation nfsd4_ops[] = {
 		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
 		.op_name = "OP_WRITE",
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
+		.op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid,
 	},
 	[OP_RELEASE_LOCKOWNER] = {
 		.op_func = (nfsd4op_func)nfsd4_release_lockowner,
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index e8c98f0..05926a4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -58,11 +58,15 @@ static const stateid_t one_stateid = {
 static const stateid_t zero_stateid = {
 	/* all fields zero */
 };
+static const stateid_t currentstateid = {
+	.si_generation = 1,
+};
 
 static u64 current_sessionid = 1;
 
 #define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t)))
 #define ONE_STATEID(stateid)  (!memcmp((stateid), &one_stateid, sizeof(stateid_t)))
+#define CURRENT_STATEID(stateid) (!memcmp((stateid), &currentstateid, sizeof(stateid_t)))
 
 /* forward declarations */
 static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
@@ -1308,7 +1312,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_r
 	else
 		goto out_err;
 
-	conn->cb_addrlen = rpc_uaddr2sockaddr(se->se_callback_addr_val,
+	conn->cb_addrlen = rpc_uaddr2sockaddr(&init_net, se->se_callback_addr_val,
 					    se->se_callback_addr_len,
 					    (struct sockaddr *)&conn->cb_addr,
 					    sizeof(conn->cb_addr));
@@ -1347,6 +1351,7 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp)
 	slot->sl_opcnt = resp->opcnt;
 	slot->sl_status = resp->cstate.status;
 
+	slot->sl_flags |= NFSD4_SLOT_INITIALIZED;
 	if (nfsd4_not_cached(resp)) {
 		slot->sl_datalen = 0;
 		return;
@@ -1374,15 +1379,12 @@ nfsd4_enc_sequence_replay(struct nfsd4_compoundargs *args,
 	struct nfsd4_op *op;
 	struct nfsd4_slot *slot = resp->cstate.slot;
 
-	dprintk("--> %s resp->opcnt %d cachethis %u \n", __func__,
-		resp->opcnt, resp->cstate.slot->sl_cachethis);
-
 	/* Encode the replayed sequence operation */
 	op = &args->ops[resp->opcnt - 1];
 	nfsd4_encode_operation(resp, op);
 
 	/* Return nfserr_retry_uncached_rep in next operation. */
-	if (args->opcnt > 1 && slot->sl_cachethis == 0) {
+	if (args->opcnt > 1 && !(slot->sl_flags & NFSD4_SLOT_CACHETHIS)) {
 		op = &args->ops[resp->opcnt++];
 		op->status = nfserr_retry_uncached_rep;
 		nfsd4_encode_operation(resp, op);
@@ -1575,16 +1577,11 @@ check_slot_seqid(u32 seqid, u32 slot_seqid, int slot_inuse)
 		else
 			return nfserr_seq_misordered;
 	}
-	/* Normal */
+	/* Note unsigned 32-bit arithmetic handles wraparound: */
 	if (likely(seqid == slot_seqid + 1))
 		return nfs_ok;
-	/* Replay */
 	if (seqid == slot_seqid)
 		return nfserr_replay_cache;
-	/* Wraparound */
-	if (seqid == 1 && (slot_seqid + 1) == 0)
-		return nfs_ok;
-	/* Misordered replay or misordered new request */
 	return nfserr_seq_misordered;
 }
 
@@ -1921,8 +1918,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
 	 * sr_highest_slotid and the sr_target_slot id to maxslots */
 	seq->maxslots = session->se_fchannel.maxreqs;
 
-	status = check_slot_seqid(seq->seqid, slot->sl_seqid, slot->sl_inuse);
+	status = check_slot_seqid(seq->seqid, slot->sl_seqid,
+					slot->sl_flags & NFSD4_SLOT_INUSE);
 	if (status == nfserr_replay_cache) {
+		status = nfserr_seq_misordered;
+		if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
+			goto out;
 		cstate->slot = slot;
 		cstate->session = session;
 		/* Return the cached reply status and set cstate->status
@@ -1938,9 +1939,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
 	conn = NULL;
 
 	/* Success! bump slot seqid */
-	slot->sl_inuse = true;
 	slot->sl_seqid = seq->seqid;
-	slot->sl_cachethis = seq->cachethis;
+	slot->sl_flags |= NFSD4_SLOT_INUSE;
+	if (seq->cachethis)
+		slot->sl_flags |= NFSD4_SLOT_CACHETHIS;
+	else
+		slot->sl_flags &= ~NFSD4_SLOT_CACHETHIS;
 
 	cstate->slot = slot;
 	cstate->session = session;
@@ -2633,8 +2637,6 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
 
 static int share_access_to_flags(u32 share_access)
 {
-	share_access &= ~NFS4_SHARE_WANT_MASK;
-
 	return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
 }
 
@@ -3400,7 +3402,14 @@ __be32
 nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		   struct nfsd4_test_stateid *test_stateid)
 {
-	/* real work is done during encoding */
+	struct nfsd4_test_stateid_id *stateid;
+	struct nfs4_client *cl = cstate->session->se_client;
+
+	nfs4_lock_state();
+	list_for_each_entry(stateid, &test_stateid->ts_stateid_list, ts_id_list)
+		stateid->ts_id_status = nfs4_validate_stateid(cl, &stateid->ts_id_stateid);
+	nfs4_unlock_state();
+
 	return nfs_ok;
 }
 
@@ -3596,7 +3605,9 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
 			cstate->current_fh.fh_dentry->d_name.name);
 
 	/* We don't yet support WANT bits: */
-	od->od_share_access &= NFS4_SHARE_ACCESS_MASK;
+	if (od->od_deleg_want)
+		dprintk("NFSD: %s: od_deleg_want=0x%x ignored\n", __func__,
+			od->od_deleg_want);
 
 	nfs4_lock_state();
 	status = nfs4_preprocess_confirmed_seqid_op(cstate, od->od_seqid,
@@ -4691,3 +4702,104 @@ nfs4_state_shutdown(void)
 	nfs4_unlock_state();
 	nfsd4_destroy_callback_queue();
 }
+
+static void
+get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
+{
+	if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
+		memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
+}
+
+static void
+put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
+{
+	if (cstate->minorversion) {
+		memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t));
+		SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
+	}
+}
+
+void
+clear_current_stateid(struct nfsd4_compound_state *cstate)
+{
+	CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
+}
+
+/*
+ * functions to set current state id
+ */
+void
+nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
+{
+	put_stateid(cstate, &odp->od_stateid);
+}
+
+void
+nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
+{
+	put_stateid(cstate, &open->op_stateid);
+}
+
+void
+nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
+{
+	put_stateid(cstate, &close->cl_stateid);
+}
+
+void
+nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lock)
+{
+	put_stateid(cstate, &lock->lk_resp_stateid);
+}
+
+/*
+ * functions to consume current state id
+ */
+
+void
+nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp)
+{
+	get_stateid(cstate, &odp->od_stateid);
+}
+
+void
+nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, struct nfsd4_delegreturn *drp)
+{
+	get_stateid(cstate, &drp->dr_stateid);
+}
+
+void
+nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, struct nfsd4_free_stateid *fsp)
+{
+	get_stateid(cstate, &fsp->fr_stateid);
+}
+
+void
+nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr)
+{
+	get_stateid(cstate, &setattr->sa_stateid);
+}
+
+void
+nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close)
+{
+	get_stateid(cstate, &close->cl_stateid);
+}
+
+void
+nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku)
+{
+	get_stateid(cstate, &locku->lu_stateid);
+}
+
+void
+nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, struct nfsd4_read *read)
+{
+	get_stateid(cstate, &read->rd_stateid);
+}
+
+void
+nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, struct nfsd4_write *write)
+{
+	get_stateid(cstate, &write->wr_stateid);
+}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 0ec5a1b..a58f206 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -133,22 +133,6 @@ xdr_error:					\
 	}					\
 } while (0)
 
-static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
-{
-	savep->p        = argp->p;
-	savep->end      = argp->end;
-	savep->pagelen  = argp->pagelen;
-	savep->pagelist = argp->pagelist;
-}
-
-static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
-{
-	argp->p        = savep->p;
-	argp->end      = savep->end;
-	argp->pagelen  = savep->pagelen;
-	argp->pagelist = savep->pagelist;
-}
-
 static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
 {
 	/* We want more bytes than seem to be available.
@@ -638,14 +622,18 @@ nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup
 	DECODE_TAIL;
 }
 
-static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
+static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 {
 	__be32 *p;
 	u32 w;
 
 	READ_BUF(4);
 	READ32(w);
-	*x = w;
+	*share_access = w & NFS4_SHARE_ACCESS_MASK;
+	*deleg_want = w & NFS4_SHARE_WANT_MASK;
+	if (deleg_when)
+		*deleg_when = w & NFS4_SHARE_WHEN_MASK;
+
 	switch (w & NFS4_SHARE_ACCESS_MASK) {
 	case NFS4_SHARE_ACCESS_READ:
 	case NFS4_SHARE_ACCESS_WRITE:
@@ -673,6 +661,9 @@ static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *x)
 	w &= ~NFS4_SHARE_WANT_MASK;
 	if (!w)
 		return nfs_ok;
+
+	if (!deleg_when)	/* open_downgrade */
+		return nfserr_inval;
 	switch (w) {
 	case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
 	case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
@@ -719,6 +710,7 @@ static __be32
 nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 {
 	DECODE_HEAD;
+	u32 dummy;
 
 	memset(open->op_bmval, 0, sizeof(open->op_bmval));
 	open->op_iattr.ia_valid = 0;
@@ -727,7 +719,9 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 	/* seqid, share_access, share_deny, clientid, ownerlen */
 	READ_BUF(4);
 	READ32(open->op_seqid);
-	status = nfsd4_decode_share_access(argp, &open->op_share_access);
+	/* decode, yet ignore deleg_when until supported */
+	status = nfsd4_decode_share_access(argp, &open->op_share_access,
+					   &open->op_deleg_want, &dummy);
 	if (status)
 		goto xdr_error;
 	status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
@@ -848,7 +842,8 @@ nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_d
 		return status;
 	READ_BUF(4);
 	READ32(open_down->od_seqid);
-	status = nfsd4_decode_share_access(argp, &open_down->od_share_access);
+	status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
+					   &open_down->od_deleg_want, NULL);
 	if (status)
 		return status;
 	status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
@@ -1385,26 +1380,29 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
 static __be32
 nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
 {
-	unsigned int nbytes;
-	stateid_t si;
 	int i;
-	__be32 *p;
-	__be32 status;
+	__be32 *p, status;
+	struct nfsd4_test_stateid_id *stateid;
 
 	READ_BUF(4);
 	test_stateid->ts_num_ids = ntohl(*p++);
 
-	nbytes = test_stateid->ts_num_ids * sizeof(stateid_t);
-	if (nbytes > (u32)((char *)argp->end - (char *)argp->p))
-		goto xdr_error;
-
-	test_stateid->ts_saved_args = argp;
-	save_buf(argp, &test_stateid->ts_savedp);
+	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
 
 	for (i = 0; i < test_stateid->ts_num_ids; i++) {
-		status = nfsd4_decode_stateid(argp, &si);
+		stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL);
+		if (!stateid) {
+			status = PTR_ERR(stateid);
+			goto out;
+		}
+
+		defer_free(argp, kfree, stateid);
+		INIT_LIST_HEAD(&stateid->ts_id_list);
+		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
+
+		status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
 		if (status)
-			return status;
+			goto out;
 	}
 
 	status = 0;
@@ -3391,30 +3389,17 @@ __be32
 nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
 			  struct nfsd4_test_stateid *test_stateid)
 {
-	struct nfsd4_compoundargs *argp;
-	struct nfs4_client *cl = resp->cstate.session->se_client;
-	stateid_t si;
+	struct nfsd4_test_stateid_id *stateid, *next;
 	__be32 *p;
-	int i;
-	int valid;
-
-	restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp);
-	argp = test_stateid->ts_saved_args;
 
-	RESERVE_SPACE(4);
+	RESERVE_SPACE(4 + (4 * test_stateid->ts_num_ids));
 	*p++ = htonl(test_stateid->ts_num_ids);
-	resp->p = p;
 
-	nfs4_lock_state();
-	for (i = 0; i < test_stateid->ts_num_ids; i++) {
-		nfsd4_decode_stateid(argp, &si);
-		valid = nfs4_validate_stateid(cl, &si);
-		RESERVE_SPACE(4);
-		*p++ = htonl(valid);
-		resp->p = p;
+	list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
+		*p++ = htonl(stateid->ts_id_status);
 	}
-	nfs4_unlock_state();
 
+	ADJUST_ARGS();
 	return nfserr;
 }
 
@@ -3532,7 +3517,7 @@ int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
 	if (length > session->se_fchannel.maxresp_sz)
 		return nfserr_rep_too_big;
 
-	if (slot->sl_cachethis == 1 &&
+	if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
 	    length > session->se_fchannel.maxresp_cached)
 		return nfserr_rep_too_big_to_cache;
 
@@ -3656,8 +3641,7 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
 	if (nfsd4_has_session(cs)) {
 		if (cs->status != nfserr_replay_cache) {
 			nfsd4_store_cache_entry(resp);
-			dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
-			cs->slot->sl_inuse = false;
+			cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
 		}
 		/* Renew the clientid on success and on replay */
 		release_session_client(cs->session);
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 748eda9..64c24af 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -223,7 +223,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
 	if (qword_get(&buf, fo_path, size) < 0)
 		return -EINVAL;
 
-	if (rpc_pton(fo_path, size, sap, salen) == 0)
+	if (rpc_pton(&init_net, fo_path, size, sap, salen) == 0)
 		return -EINVAL;
 
 	return nlmsvc_unlock_all_by_ip(sap);
@@ -722,7 +722,7 @@ static ssize_t __write_ports_addxprt(char *buf)
 	nfsd_serv->sv_nrthreads--;
 	return 0;
 out_close:
-	xprt = svc_find_xprt(nfsd_serv, transport, PF_INET, port);
+	xprt = svc_find_xprt(nfsd_serv, transport, &init_net, PF_INET, port);
 	if (xprt != NULL) {
 		svc_close_xprt(xprt);
 		svc_xprt_put(xprt);
@@ -748,7 +748,7 @@ static ssize_t __write_ports_delxprt(char *buf)
 	if (port < 1 || port > USHRT_MAX || nfsd_serv == NULL)
 		return -EINVAL;
 
-	xprt = svc_find_xprt(nfsd_serv, transport, AF_UNSPEC, port);
+	xprt = svc_find_xprt(nfsd_serv, transport, &init_net, AF_UNSPEC, port);
 	if (xprt == NULL)
 		return -ENOTCONN;
 
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index eda7d7e..28dfad3 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -251,13 +251,13 @@ static void nfsd_shutdown(void)
 	nfsd_up = false;
 }
 
-static void nfsd_last_thread(struct svc_serv *serv)
+static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
 {
 	/* When last nfsd thread exits we need to do some clean-up */
 	nfsd_serv = NULL;
 	nfsd_shutdown();
 
-	svc_rpcb_cleanup(serv);
+	svc_rpcb_cleanup(serv, net);
 
 	printk(KERN_WARNING "nfsd: last server has exited, flushing export "
 			    "cache\n");
@@ -307,33 +307,37 @@ static void set_max_drc(void)
 	dprintk("%s nfsd_drc_max_mem %u \n", __func__, nfsd_drc_max_mem);
 }
 
-int nfsd_create_serv(void)
+static int nfsd_get_default_max_blksize(void)
 {
-	int err = 0;
+	struct sysinfo i;
+	unsigned long long target;
+	unsigned long ret;
+
+	si_meminfo(&i);
+	target = (i.totalram - i.totalhigh) << PAGE_SHIFT;
+	/*
+	 * Aim for 1/4096 of memory per thread This gives 1MB on 4Gig
+	 * machines, but only uses 32K on 128M machines.  Bottom out at
+	 * 8K on 32M and smaller.  Of course, this is only a default.
+	 */
+	target >>= 12;
+
+	ret = NFSSVC_MAXBLKSIZE;
+	while (ret > target && ret >= 8*1024*2)
+		ret /= 2;
+	return ret;
+}
 
+int nfsd_create_serv(void)
+{
 	WARN_ON(!mutex_is_locked(&nfsd_mutex));
 	if (nfsd_serv) {
 		svc_get(nfsd_serv);
 		return 0;
 	}
-	if (nfsd_max_blksize == 0) {
-		/* choose a suitable default */
-		struct sysinfo i;
-		si_meminfo(&i);
-		/* Aim for 1/4096 of memory per thread
-		 * This gives 1MB on 4Gig machines
-		 * But only uses 32K on 128M machines.
-		 * Bottom out at 8K on 32M and smaller.
-		 * Of course, this is only a default.
-		 */
-		nfsd_max_blksize = NFSSVC_MAXBLKSIZE;
-		i.totalram <<= PAGE_SHIFT - 12;
-		while (nfsd_max_blksize > i.totalram &&
-		       nfsd_max_blksize >= 8*1024*2)
-			nfsd_max_blksize /= 2;
-	}
+	if (nfsd_max_blksize == 0)
+		nfsd_max_blksize = nfsd_get_default_max_blksize();
 	nfsd_reset_versions();
-
 	nfsd_serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize,
 				      nfsd_last_thread, nfsd, THIS_MODULE);
 	if (nfsd_serv == NULL)
@@ -341,7 +345,7 @@ int nfsd_create_serv(void)
 
 	set_max_drc();
 	do_gettimeofday(&nfssvc_boot);		/* record boot time */
-	return err;
+	return 0;
 }
 
 int nfsd_nrpools(void)
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index ffb5df1..d8f52a0 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -128,12 +128,14 @@ static inline struct nfs4_delegation *delegstateid(struct nfs4_stid *s)
 		(NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE)
 
 struct nfsd4_slot {
-	bool	sl_inuse;
-	bool	sl_cachethis;
-	u16	sl_opcnt;
 	u32	sl_seqid;
 	__be32	sl_status;
 	u32	sl_datalen;
+	u16	sl_opcnt;
+#define NFSD4_SLOT_INUSE	(1 << 0)
+#define NFSD4_SLOT_CACHETHIS	(1 << 1)
+#define NFSD4_SLOT_INITIALIZED	(1 << 2)
+	u8	sl_flags;
 	char	sl_data[];
 };
 
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c
index a2e2402..6d4521f 100644
--- a/fs/nfsd/stats.c
+++ b/fs/nfsd/stats.c
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/sunrpc/stats.h>
 #include <linux/nfsd/stats.h>
+#include <net/net_namespace.h>
 
 #include "nfsd.h"
 
@@ -94,11 +95,11 @@ static const struct file_operations nfsd_proc_fops = {
 void
 nfsd_stat_init(void)
 {
-	svc_proc_register(&nfsd_svcstats, &nfsd_proc_fops);
+	svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_fops);
 }
 
 void
 nfsd_stat_shutdown(void)
 {
-	svc_proc_unregister("nfsd");
+	svc_proc_unregister(&init_net, "nfsd");
 }
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index edf6d3e..2fc8c15 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -19,7 +19,6 @@
 #include <linux/fcntl.h>
 #include <linux/namei.h>
 #include <linux/delay.h>
-#include <linux/fsnotify.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/xattr.h>
 #include <linux/jhash.h>
@@ -933,7 +932,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 		nfsdstats.io_read += host_err;
 		*count = host_err;
 		err = 0;
-		fsnotify_access(file);
 	} else 
 		err = nfserrno(host_err);
 	return err;
@@ -1035,7 +1033,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 		goto out_nfserr;
 	*cnt = host_err;
 	nfsdstats.io_write += host_err;
-	fsnotify_modify(file);
 
 	/* clear setuid/setgid flag after write */
 	if (inode->i_mode & (S_ISUID | S_ISGID))
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 2364747..7110a08 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -43,6 +43,13 @@
 #define NFSD4_MAX_TAGLEN	128
 #define XDR_LEN(n)                     (((n) + 3) & ~3)
 
+#define CURRENT_STATE_ID_FLAG (1<<0)
+#define SAVED_STATE_ID_FLAG (1<<1)
+
+#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f))
+#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f))
+#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f))
+
 struct nfsd4_compound_state {
 	struct svc_fh		current_fh;
 	struct svc_fh		save_fh;
@@ -54,6 +61,10 @@ struct nfsd4_compound_state {
 	size_t			iovlen;
 	u32			minorversion;
 	u32			status;
+	stateid_t	current_stateid;
+	stateid_t	save_stateid;
+	/* to indicate current and saved state id presents */
+	u32		sid_flags;
 };
 
 static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs)
@@ -222,6 +233,7 @@ struct nfsd4_open {
 	u32		op_seqid;           /* request */
 	u32		op_share_access;    /* request */
 	u32		op_share_deny;      /* request */
+	u32		op_deleg_want;      /* request */
 	stateid_t	op_stateid;         /* response */
 	u32		op_recall;          /* recall */
 	struct nfsd4_change_info  op_cinfo; /* response */
@@ -245,8 +257,9 @@ struct nfsd4_open_confirm {
 struct nfsd4_open_downgrade {
 	stateid_t       od_stateid;
 	u32             od_seqid;
-	u32             od_share_access;
-	u32             od_share_deny;
+	u32             od_share_access;	/* request */
+	u32		od_deleg_want;		/* request */
+	u32             od_share_deny;		/* request */
 };
 
 
@@ -343,10 +356,15 @@ struct nfsd4_saved_compoundargs {
 	struct page **pagelist;
 };
 
+struct nfsd4_test_stateid_id {
+	__be32			ts_id_status;
+	stateid_t		ts_id_stateid;
+	struct list_head	ts_id_list;
+};
+
 struct nfsd4_test_stateid {
 	__be32		ts_num_ids;
-	struct nfsd4_compoundargs *ts_saved_args;
-	struct nfsd4_saved_compoundargs ts_savedp;
+	struct list_head ts_stateid_list;
 };
 
 struct nfsd4_free_stateid {
@@ -503,7 +521,8 @@ static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp)
 
 static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
 {
-	return !resp->cstate.slot->sl_cachethis || nfsd4_is_solo_sequence(resp);
+	return !(resp->cstate.slot->sl_flags & NFSD4_SLOT_CACHETHIS)
+		|| nfsd4_is_solo_sequence(resp);
 }
 
 #define NFS4_SVC_XDRSIZE		sizeof(struct nfsd4_compoundargs)
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index c9b342c..dab5c4c 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -218,11 +218,11 @@ int nilfs_cpfile_get_checkpoint(struct inode *cpfile,
 								 kaddr, 1);
 		mark_buffer_dirty(cp_bh);
 
-		kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(header_bh->b_page);
 		header = nilfs_cpfile_block_get_header(cpfile, header_bh,
 						       kaddr);
 		le64_add_cpu(&header->ch_ncheckpoints, 1);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		mark_buffer_dirty(header_bh);
 		nilfs_mdt_mark_dirty(cpfile);
 	}
@@ -313,7 +313,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
 			continue;
 		}
 
-		kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(cp_bh->b_page);
 		cp = nilfs_cpfile_block_get_checkpoint(
 			cpfile, cno, cp_bh, kaddr);
 		nicps = 0;
@@ -334,7 +334,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
 						cpfile, cp_bh, kaddr, nicps);
 				if (count == 0) {
 					/* make hole */
-					kunmap_atomic(kaddr, KM_USER0);
+					kunmap_atomic(kaddr);
 					brelse(cp_bh);
 					ret =
 					  nilfs_cpfile_delete_checkpoint_block(
@@ -349,18 +349,18 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
 			}
 		}
 
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(cp_bh);
 	}
 
 	if (tnicps > 0) {
-		kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(header_bh->b_page);
 		header = nilfs_cpfile_block_get_header(cpfile, header_bh,
 						       kaddr);
 		le64_add_cpu(&header->ch_ncheckpoints, -(u64)tnicps);
 		mark_buffer_dirty(header_bh);
 		nilfs_mdt_mark_dirty(cpfile);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 
 	brelse(header_bh);
@@ -408,7 +408,7 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
 			continue; /* skip hole */
 		}
 
-		kaddr = kmap_atomic(bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(bh->b_page);
 		cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
 		for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) {
 			if (!nilfs_checkpoint_invalid(cp)) {
@@ -418,7 +418,7 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
 				n++;
 			}
 		}
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(bh);
 	}
 
@@ -451,10 +451,10 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
 		ret = nilfs_cpfile_get_header_block(cpfile, &bh);
 		if (ret < 0)
 			goto out;
-		kaddr = kmap_atomic(bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(bh->b_page);
 		header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr);
 		curr = le64_to_cpu(header->ch_snapshot_list.ssl_next);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(bh);
 		if (curr == 0) {
 			ret = 0;
@@ -472,7 +472,7 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
 			ret = 0; /* No snapshots (started from a hole block) */
 		goto out;
 	}
-	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(bh->b_page);
 	while (n < nci) {
 		cp = nilfs_cpfile_block_get_checkpoint(cpfile, curr, bh, kaddr);
 		curr = ~(__u64)0; /* Terminator */
@@ -488,7 +488,7 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
 
 		next_blkoff = nilfs_cpfile_get_blkoff(cpfile, next);
 		if (curr_blkoff != next_blkoff) {
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			brelse(bh);
 			ret = nilfs_cpfile_get_checkpoint_block(cpfile, next,
 								0, &bh);
@@ -496,12 +496,12 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
 				WARN_ON(ret == -ENOENT);
 				goto out;
 			}
-			kaddr = kmap_atomic(bh->b_page, KM_USER0);
+			kaddr = kmap_atomic(bh->b_page);
 		}
 		curr = next;
 		curr_blkoff = next_blkoff;
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(bh);
 	*cnop = curr;
 	ret = n;
@@ -592,24 +592,24 @@ static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno)
 	ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
 	if (ret < 0)
 		goto out_sem;
-	kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(cp_bh->b_page);
 	cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
 	if (nilfs_checkpoint_invalid(cp)) {
 		ret = -ENOENT;
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		goto out_cp;
 	}
 	if (nilfs_checkpoint_snapshot(cp)) {
 		ret = 0;
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		goto out_cp;
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
 	if (ret < 0)
 		goto out_cp;
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr);
 	list = &header->ch_snapshot_list;
 	curr_bh = header_bh;
@@ -621,13 +621,13 @@ static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno)
 		prev_blkoff = nilfs_cpfile_get_blkoff(cpfile, prev);
 		curr = prev;
 		if (curr_blkoff != prev_blkoff) {
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			brelse(curr_bh);
 			ret = nilfs_cpfile_get_checkpoint_block(cpfile, curr,
 								0, &curr_bh);
 			if (ret < 0)
 				goto out_header;
-			kaddr = kmap_atomic(curr_bh->b_page, KM_USER0);
+			kaddr = kmap_atomic(curr_bh->b_page);
 		}
 		curr_blkoff = prev_blkoff;
 		cp = nilfs_cpfile_block_get_checkpoint(
@@ -635,7 +635,7 @@ static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno)
 		list = &cp->cp_snapshot_list;
 		prev = le64_to_cpu(list->ssl_prev);
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (prev != 0) {
 		ret = nilfs_cpfile_get_checkpoint_block(cpfile, prev, 0,
@@ -647,29 +647,29 @@ static int nilfs_cpfile_set_snapshot(struct inode *cpfile, __u64 cno)
 		get_bh(prev_bh);
 	}
 
-	kaddr = kmap_atomic(curr_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(curr_bh->b_page);
 	list = nilfs_cpfile_block_get_snapshot_list(
 		cpfile, curr, curr_bh, kaddr);
 	list->ssl_prev = cpu_to_le64(cno);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
-	kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(cp_bh->b_page);
 	cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
 	cp->cp_snapshot_list.ssl_next = cpu_to_le64(curr);
 	cp->cp_snapshot_list.ssl_prev = cpu_to_le64(prev);
 	nilfs_checkpoint_set_snapshot(cp);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
-	kaddr = kmap_atomic(prev_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(prev_bh->b_page);
 	list = nilfs_cpfile_block_get_snapshot_list(
 		cpfile, prev, prev_bh, kaddr);
 	list->ssl_next = cpu_to_le64(cno);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr);
 	le64_add_cpu(&header->ch_nsnapshots, 1);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(prev_bh);
 	mark_buffer_dirty(curr_bh);
@@ -710,23 +710,23 @@ static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno)
 	ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
 	if (ret < 0)
 		goto out_sem;
-	kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(cp_bh->b_page);
 	cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
 	if (nilfs_checkpoint_invalid(cp)) {
 		ret = -ENOENT;
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		goto out_cp;
 	}
 	if (!nilfs_checkpoint_snapshot(cp)) {
 		ret = 0;
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		goto out_cp;
 	}
 
 	list = &cp->cp_snapshot_list;
 	next = le64_to_cpu(list->ssl_next);
 	prev = le64_to_cpu(list->ssl_prev);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
 	if (ret < 0)
@@ -750,29 +750,29 @@ static int nilfs_cpfile_clear_snapshot(struct inode *cpfile, __u64 cno)
 		get_bh(prev_bh);
 	}
 
-	kaddr = kmap_atomic(next_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(next_bh->b_page);
 	list = nilfs_cpfile_block_get_snapshot_list(
 		cpfile, next, next_bh, kaddr);
 	list->ssl_prev = cpu_to_le64(prev);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
-	kaddr = kmap_atomic(prev_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(prev_bh->b_page);
 	list = nilfs_cpfile_block_get_snapshot_list(
 		cpfile, prev, prev_bh, kaddr);
 	list->ssl_next = cpu_to_le64(next);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
-	kaddr = kmap_atomic(cp_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(cp_bh->b_page);
 	cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, cp_bh, kaddr);
 	cp->cp_snapshot_list.ssl_next = cpu_to_le64(0);
 	cp->cp_snapshot_list.ssl_prev = cpu_to_le64(0);
 	nilfs_checkpoint_clear_snapshot(cp);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = nilfs_cpfile_block_get_header(cpfile, header_bh, kaddr);
 	le64_add_cpu(&header->ch_nsnapshots, -1);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(next_bh);
 	mark_buffer_dirty(prev_bh);
@@ -829,13 +829,13 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno)
 	ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh);
 	if (ret < 0)
 		goto out;
-	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(bh->b_page);
 	cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
 	if (nilfs_checkpoint_invalid(cp))
 		ret = -ENOENT;
 	else
 		ret = nilfs_checkpoint_snapshot(cp);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(bh);
 
  out:
@@ -912,12 +912,12 @@ int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat)
 	ret = nilfs_cpfile_get_header_block(cpfile, &bh);
 	if (ret < 0)
 		goto out_sem;
-	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(bh->b_page);
 	header = nilfs_cpfile_block_get_header(cpfile, bh, kaddr);
 	cpstat->cs_cno = nilfs_mdt_cno(cpfile);
 	cpstat->cs_ncps = le64_to_cpu(header->ch_ncheckpoints);
 	cpstat->cs_nsss = le64_to_cpu(header->ch_nsnapshots);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(bh);
 
  out_sem:
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index fcc2f86..b5c13f3 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -85,13 +85,13 @@ void nilfs_dat_commit_alloc(struct inode *dat, struct nilfs_palloc_req *req)
 	struct nilfs_dat_entry *entry;
 	void *kaddr;
 
-	kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req->pr_entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	entry->de_start = cpu_to_le64(NILFS_CNO_MIN);
 	entry->de_end = cpu_to_le64(NILFS_CNO_MAX);
 	entry->de_blocknr = cpu_to_le64(0);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	nilfs_palloc_commit_alloc_entry(dat, req);
 	nilfs_dat_commit_entry(dat, req);
@@ -109,13 +109,13 @@ static void nilfs_dat_commit_free(struct inode *dat,
 	struct nilfs_dat_entry *entry;
 	void *kaddr;
 
-	kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req->pr_entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	entry->de_start = cpu_to_le64(NILFS_CNO_MIN);
 	entry->de_end = cpu_to_le64(NILFS_CNO_MIN);
 	entry->de_blocknr = cpu_to_le64(0);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	nilfs_dat_commit_entry(dat, req);
 	nilfs_palloc_commit_free_entry(dat, req);
@@ -136,12 +136,12 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
 	struct nilfs_dat_entry *entry;
 	void *kaddr;
 
-	kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req->pr_entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat));
 	entry->de_blocknr = cpu_to_le64(blocknr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	nilfs_dat_commit_entry(dat, req);
 }
@@ -160,12 +160,12 @@ int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
 		return ret;
 	}
 
-	kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req->pr_entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	start = le64_to_cpu(entry->de_start);
 	blocknr = le64_to_cpu(entry->de_blocknr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (blocknr == 0) {
 		ret = nilfs_palloc_prepare_free_entry(dat, req);
@@ -186,7 +186,7 @@ void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req,
 	sector_t blocknr;
 	void *kaddr;
 
-	kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req->pr_entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	end = start = le64_to_cpu(entry->de_start);
@@ -196,7 +196,7 @@ void nilfs_dat_commit_end(struct inode *dat, struct nilfs_palloc_req *req,
 	}
 	entry->de_end = cpu_to_le64(end);
 	blocknr = le64_to_cpu(entry->de_blocknr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (blocknr == 0)
 		nilfs_dat_commit_free(dat, req);
@@ -211,12 +211,12 @@ void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req)
 	sector_t blocknr;
 	void *kaddr;
 
-	kaddr = kmap_atomic(req->pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req->pr_entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	start = le64_to_cpu(entry->de_start);
 	blocknr = le64_to_cpu(entry->de_blocknr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (start == nilfs_mdt_cno(dat) && blocknr == 0)
 		nilfs_palloc_abort_free_entry(dat, req);
@@ -346,20 +346,20 @@ int nilfs_dat_move(struct inode *dat, __u64 vblocknr, sector_t blocknr)
 		}
 	}
 
-	kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
 	if (unlikely(entry->de_blocknr == cpu_to_le64(0))) {
 		printk(KERN_CRIT "%s: vbn = %llu, [%llu, %llu)\n", __func__,
 		       (unsigned long long)vblocknr,
 		       (unsigned long long)le64_to_cpu(entry->de_start),
 		       (unsigned long long)le64_to_cpu(entry->de_end));
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(entry_bh);
 		return -EINVAL;
 	}
 	WARN_ON(blocknr == 0);
 	entry->de_blocknr = cpu_to_le64(blocknr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(entry_bh);
 	nilfs_mdt_mark_dirty(dat);
@@ -409,7 +409,7 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
 		}
 	}
 
-	kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(entry_bh->b_page);
 	entry = nilfs_palloc_block_get_entry(dat, vblocknr, entry_bh, kaddr);
 	blocknr = le64_to_cpu(entry->de_blocknr);
 	if (blocknr == 0) {
@@ -419,7 +419,7 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
 	*blocknrp = blocknr;
 
  out:
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(entry_bh);
 	return ret;
 }
@@ -440,7 +440,7 @@ ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
 						   0, &entry_bh);
 		if (ret < 0)
 			return ret;
-		kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(entry_bh->b_page);
 		/* last virtual block number in this block */
 		first = vinfo->vi_vblocknr;
 		do_div(first, entries_per_block);
@@ -456,7 +456,7 @@ ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
 			vinfo->vi_end = le64_to_cpu(entry->de_end);
 			vinfo->vi_blocknr = le64_to_cpu(entry->de_blocknr);
 		}
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(entry_bh);
 	}
 
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index ca35b3a..df1a7fb 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -602,7 +602,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
 		unlock_page(page);
 		goto fail;
 	}
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memset(kaddr, 0, chunk_size);
 	de = (struct nilfs_dir_entry *)kaddr;
 	de->name_len = 1;
@@ -617,7 +617,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
 	de->inode = cpu_to_le64(parent->i_ino);
 	memcpy(de->name, "..\0", 4);
 	nilfs_set_de_type(de, inode);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	nilfs_commit_chunk(page, mapping, 0, chunk_size);
 fail:
 	page_cache_release(page);
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
index 684d763..5a48df7 100644
--- a/fs/nilfs2/ifile.c
+++ b/fs/nilfs2/ifile.c
@@ -122,11 +122,11 @@ int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
 		return ret;
 	}
 
-	kaddr = kmap_atomic(req.pr_entry_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(req.pr_entry_bh->b_page);
 	raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
 						 req.pr_entry_bh, kaddr);
 	raw_inode->i_flags = 0;
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(req.pr_entry_bh);
 	brelse(req.pr_entry_bh);
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 800e8d7..f9897d0 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -58,12 +58,12 @@ nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block,
 
 	set_buffer_mapped(bh);
 
-	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(bh->b_page);
 	memset(kaddr + bh_offset(bh), 0, 1 << inode->i_blkbits);
 	if (init_block)
 		init_block(inode, bh, kaddr);
 	flush_dcache_page(bh->b_page);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	set_buffer_uptodate(bh);
 	mark_buffer_dirty(bh);
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c
index 1cd3f62..fce2bbe 100644
--- a/fs/nilfs2/namei.c
+++ b/fs/nilfs2/namei.c
@@ -193,9 +193,6 @@ static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
 	struct nilfs_transaction_info ti;
 	int err;
 
-	if (inode->i_nlink >= NILFS_LINK_MAX)
-		return -EMLINK;
-
 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 	if (err)
 		return err;
@@ -219,9 +216,6 @@ static int nilfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	struct nilfs_transaction_info ti;
 	int err;
 
-	if (dir->i_nlink >= NILFS_LINK_MAX)
-		return -EMLINK;
-
 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
 	if (err)
 		return err;
@@ -400,11 +394,6 @@ static int nilfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		drop_nlink(new_inode);
 		nilfs_mark_inode_dirty(new_inode);
 	} else {
-		if (dir_de) {
-			err = -EMLINK;
-			if (new_dir->i_nlink >= NILFS_LINK_MAX)
-				goto out_dir;
-		}
 		err = nilfs_add_link(new_dentry, old_inode);
 		if (err)
 			goto out_dir;
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 65221a0..3e7b2a0 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -119,11 +119,11 @@ void nilfs_copy_buffer(struct buffer_head *dbh, struct buffer_head *sbh)
 	struct page *spage = sbh->b_page, *dpage = dbh->b_page;
 	struct buffer_head *bh;
 
-	kaddr0 = kmap_atomic(spage, KM_USER0);
-	kaddr1 = kmap_atomic(dpage, KM_USER1);
+	kaddr0 = kmap_atomic(spage);
+	kaddr1 = kmap_atomic(dpage);
 	memcpy(kaddr1 + bh_offset(dbh), kaddr0 + bh_offset(sbh), sbh->b_size);
-	kunmap_atomic(kaddr1, KM_USER1);
-	kunmap_atomic(kaddr0, KM_USER0);
+	kunmap_atomic(kaddr1);
+	kunmap_atomic(kaddr0);
 
 	dbh->b_state = sbh->b_state & NILFS_BUFFER_INHERENT_BITS;
 	dbh->b_blocknr = sbh->b_blocknr;
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index a604ac0..f1626f5 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -493,9 +493,9 @@ static int nilfs_recovery_copy_block(struct the_nilfs *nilfs,
 	if (unlikely(!bh_org))
 		return -EIO;
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memcpy(kaddr + bh_offset(bh_org), bh_org->b_data, bh_org->b_size);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(bh_org);
 	return 0;
 }
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 850a7c0..dc9a913 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -227,9 +227,9 @@ static void nilfs_segbuf_fill_in_data_crc(struct nilfs_segment_buffer *segbuf,
 		crc = crc32_le(crc, bh->b_data, bh->b_size);
 	}
 	list_for_each_entry(bh, &segbuf->sb_payload_buffers, b_assoc_buffers) {
-		kaddr = kmap_atomic(bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(bh->b_page);
 		crc = crc32_le(crc, kaddr + bh_offset(bh), bh->b_size);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 	raw_sum->ss_datasum = cpu_to_le32(crc);
 }
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 0a0aba6..c5b7653 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -111,11 +111,11 @@ static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
 	struct nilfs_sufile_header *header;
 	void *kaddr;
 
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = kaddr + bh_offset(header_bh);
 	le64_add_cpu(&header->sh_ncleansegs, ncleanadd);
 	le64_add_cpu(&header->sh_ndirtysegs, ndirtyadd);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(header_bh);
 }
@@ -319,11 +319,11 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
 	ret = nilfs_sufile_get_header_block(sufile, &header_bh);
 	if (ret < 0)
 		goto out_sem;
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = kaddr + bh_offset(header_bh);
 	ncleansegs = le64_to_cpu(header->sh_ncleansegs);
 	last_alloc = le64_to_cpu(header->sh_last_alloc);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	nsegments = nilfs_sufile_get_nsegments(sufile);
 	maxsegnum = sui->allocmax;
@@ -356,7 +356,7 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
 							   &su_bh);
 		if (ret < 0)
 			goto out_header;
-		kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(su_bh->b_page);
 		su = nilfs_sufile_block_get_segment_usage(
 			sufile, segnum, su_bh, kaddr);
 
@@ -367,14 +367,14 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
 				continue;
 			/* found a clean segment */
 			nilfs_segment_usage_set_dirty(su);
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 
-			kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+			kaddr = kmap_atomic(header_bh->b_page);
 			header = kaddr + bh_offset(header_bh);
 			le64_add_cpu(&header->sh_ncleansegs, -1);
 			le64_add_cpu(&header->sh_ndirtysegs, 1);
 			header->sh_last_alloc = cpu_to_le64(segnum);
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 
 			sui->ncleansegs--;
 			mark_buffer_dirty(header_bh);
@@ -385,7 +385,7 @@ int nilfs_sufile_alloc(struct inode *sufile, __u64 *segnump)
 			goto out_header;
 		}
 
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(su_bh);
 	}
 
@@ -407,16 +407,16 @@ void nilfs_sufile_do_cancel_free(struct inode *sufile, __u64 segnum,
 	struct nilfs_segment_usage *su;
 	void *kaddr;
 
-	kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(su_bh->b_page);
 	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
 	if (unlikely(!nilfs_segment_usage_clean(su))) {
 		printk(KERN_WARNING "%s: segment %llu must be clean\n",
 		       __func__, (unsigned long long)segnum);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		return;
 	}
 	nilfs_segment_usage_set_dirty(su);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	nilfs_sufile_mod_counter(header_bh, -1, 1);
 	NILFS_SUI(sufile)->ncleansegs--;
@@ -433,11 +433,11 @@ void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
 	void *kaddr;
 	int clean, dirty;
 
-	kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(su_bh->b_page);
 	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
 	if (su->su_flags == cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY) &&
 	    su->su_nblocks == cpu_to_le32(0)) {
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		return;
 	}
 	clean = nilfs_segment_usage_clean(su);
@@ -447,7 +447,7 @@ void nilfs_sufile_do_scrap(struct inode *sufile, __u64 segnum,
 	su->su_lastmod = cpu_to_le64(0);
 	su->su_nblocks = cpu_to_le32(0);
 	su->su_flags = cpu_to_le32(1UL << NILFS_SEGMENT_USAGE_DIRTY);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	nilfs_sufile_mod_counter(header_bh, clean ? (u64)-1 : 0, dirty ? 0 : 1);
 	NILFS_SUI(sufile)->ncleansegs -= clean;
@@ -464,12 +464,12 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
 	void *kaddr;
 	int sudirty;
 
-	kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(su_bh->b_page);
 	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
 	if (nilfs_segment_usage_clean(su)) {
 		printk(KERN_WARNING "%s: segment %llu is already clean\n",
 		       __func__, (unsigned long long)segnum);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		return;
 	}
 	WARN_ON(nilfs_segment_usage_error(su));
@@ -477,7 +477,7 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
 
 	sudirty = nilfs_segment_usage_dirty(su);
 	nilfs_segment_usage_set_clean(su);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	mark_buffer_dirty(su_bh);
 
 	nilfs_sufile_mod_counter(header_bh, 1, sudirty ? (u64)-1 : 0);
@@ -525,13 +525,13 @@ int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
 	if (ret < 0)
 		goto out_sem;
 
-	kaddr = kmap_atomic(bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(bh->b_page);
 	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
 	WARN_ON(nilfs_segment_usage_error(su));
 	if (modtime)
 		su->su_lastmod = cpu_to_le64(modtime);
 	su->su_nblocks = cpu_to_le32(nblocks);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(bh);
 	nilfs_mdt_mark_dirty(sufile);
@@ -572,7 +572,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
 	if (ret < 0)
 		goto out_sem;
 
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = kaddr + bh_offset(header_bh);
 	sustat->ss_nsegs = nilfs_sufile_get_nsegments(sufile);
 	sustat->ss_ncleansegs = le64_to_cpu(header->sh_ncleansegs);
@@ -582,7 +582,7 @@ int nilfs_sufile_get_stat(struct inode *sufile, struct nilfs_sustat *sustat)
 	spin_lock(&nilfs->ns_last_segment_lock);
 	sustat->ss_prot_seq = nilfs->ns_prot_seq;
 	spin_unlock(&nilfs->ns_last_segment_lock);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(header_bh);
 
  out_sem:
@@ -598,15 +598,15 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
 	void *kaddr;
 	int suclean;
 
-	kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(su_bh->b_page);
 	su = nilfs_sufile_block_get_segment_usage(sufile, segnum, su_bh, kaddr);
 	if (nilfs_segment_usage_error(su)) {
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		return;
 	}
 	suclean = nilfs_segment_usage_clean(su);
 	nilfs_segment_usage_set_error(su);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (suclean) {
 		nilfs_sufile_mod_counter(header_bh, -1, 0);
@@ -675,7 +675,7 @@ static int nilfs_sufile_truncate_range(struct inode *sufile,
 			/* hole */
 			continue;
 		}
-		kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(su_bh->b_page);
 		su = nilfs_sufile_block_get_segment_usage(
 			sufile, segnum, su_bh, kaddr);
 		su2 = su;
@@ -684,7 +684,7 @@ static int nilfs_sufile_truncate_range(struct inode *sufile,
 			     ~(1UL << NILFS_SEGMENT_USAGE_ERROR)) ||
 			    nilfs_segment_is_active(nilfs, segnum + j)) {
 				ret = -EBUSY;
-				kunmap_atomic(kaddr, KM_USER0);
+				kunmap_atomic(kaddr);
 				brelse(su_bh);
 				goto out_header;
 			}
@@ -696,7 +696,7 @@ static int nilfs_sufile_truncate_range(struct inode *sufile,
 				nc++;
 			}
 		}
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		if (nc > 0) {
 			mark_buffer_dirty(su_bh);
 			ncleaned += nc;
@@ -772,10 +772,10 @@ int nilfs_sufile_resize(struct inode *sufile, __u64 newnsegs)
 		sui->ncleansegs -= nsegs - newnsegs;
 	}
 
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = kaddr + bh_offset(header_bh);
 	header->sh_ncleansegs = cpu_to_le64(sui->ncleansegs);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	mark_buffer_dirty(header_bh);
 	nilfs_mdt_mark_dirty(sufile);
@@ -840,7 +840,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
 			continue;
 		}
 
-		kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
+		kaddr = kmap_atomic(su_bh->b_page);
 		su = nilfs_sufile_block_get_segment_usage(
 			sufile, segnum, su_bh, kaddr);
 		for (j = 0; j < n;
@@ -853,7 +853,7 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
 				si->sui_flags |=
 					(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
 		}
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		brelse(su_bh);
 	}
 	ret = nsegs;
@@ -902,10 +902,10 @@ int nilfs_sufile_read(struct super_block *sb, size_t susize,
 		goto failed;
 
 	sui = NILFS_SUI(sufile);
-	kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
+	kaddr = kmap_atomic(header_bh->b_page);
 	header = kaddr + bh_offset(header_bh);
 	sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	brelse(header_bh);
 
 	sui->allocmax = nilfs_sufile_get_nsegments(sufile) - 1;
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 08e3d4f..1099a76 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -917,9 +917,8 @@ static int nilfs_get_root_dentry(struct super_block *sb,
 	if (root->cno == NILFS_CPTREE_CURRENT_CNO) {
 		dentry = d_find_alias(inode);
 		if (!dentry) {
-			dentry = d_alloc_root(inode);
+			dentry = d_make_root(inode);
 			if (!dentry) {
-				iput(inode);
 				ret = -ENOMEM;
 				goto failed_dentry;
 			}
@@ -1059,6 +1058,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_export_op = &nilfs_export_ops;
 	sb->s_root = NULL;
 	sb->s_time_gran = 1;
+	sb->s_max_links = NILFS_LINK_MAX;
 
 	bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
 	sb->s_bdi = bdi ? : &default_backing_dev_info;
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c
index 3344bdd..89ec7e0 100644
--- a/fs/notify/dnotify/dnotify.c
+++ b/fs/notify/dnotify/dnotify.c
@@ -31,7 +31,6 @@ int dir_notify_enable __read_mostly = 1;
 static struct kmem_cache *dnotify_struct_cache __read_mostly;
 static struct kmem_cache *dnotify_mark_cache __read_mostly;
 static struct fsnotify_group *dnotify_group __read_mostly;
-static DEFINE_MUTEX(dnotify_mark_mutex);
 
 /*
  * dnotify will attach one of these to each inode (i_fsnotify_marks) which
@@ -183,7 +182,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
 		return;
 	dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
 
-	mutex_lock(&dnotify_mark_mutex);
+	mutex_lock(&dnotify_group->mutex);
 
 	spin_lock(&fsn_mark->lock);
 	prev = &dn_mark->dn;
@@ -199,11 +198,11 @@ void dnotify_flush(struct file *filp, fl_owner_t id)
 
 	spin_unlock(&fsn_mark->lock);
 
-	/* nothing else could have found us thanks to the dnotify_mark_mutex */
+	/* nothing else could have found us thanks to the dnotify_group mutex */
 	if (dn_mark->dn == NULL)
 		fsnotify_destroy_mark(fsn_mark);
 
-	mutex_unlock(&dnotify_mark_mutex);
+	mutex_unlock(&dnotify_group->mutex);
 
 	fsnotify_put_mark(fsn_mark);
 }
@@ -326,7 +325,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 	new_dn_mark->dn = NULL;
 
 	/* this is needed to prevent the fcntl/close race described below */
-	mutex_lock(&dnotify_mark_mutex);
+	mutex_lock(&dnotify_group->mutex);
 
 	/* add the new_fsn_mark or find an old one. */
 	fsn_mark = fsnotify_find_inode_mark(dnotify_group, inode);
@@ -348,8 +347,8 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
 
 	/* if (f != filp) means that we lost a race and another task/thread
 	 * actually closed the fd we are still playing with before we grabbed
-	 * the dnotify_mark_mutex and fsn_mark->lock.  Since closing the fd is the
-	 * only time we clean up the marks we need to get our mark off
+	 * the dnotify_group mutex and fsn_mark->lock. Since closing the fd is
+	 * the only time we clean up the marks we need to get our mark off
 	 * the list. */
 	if (f != filp) {
 		/* if we added ourselves, shoot ourselves, it's possible that
@@ -387,7 +386,7 @@ out:
 	if (destroy)
 		fsnotify_destroy_mark(fsn_mark);
 
-	mutex_unlock(&dnotify_mark_mutex);
+	mutex_unlock(&dnotify_group->mutex);
 	fsnotify_put_mark(fsn_mark);
 out_err:
 	if (new_fsn_mark)
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index f35794b..c2ba86a 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -184,13 +184,6 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
 		marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
 		marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
 	} else if (inode_mark) {
-		/*
-		 * if the event is for a child and this inode doesn't care about
-		 * events on the child, don't send it!
-		 */
-		if ((event_mask & FS_EVENT_ON_CHILD) &&
-		    !(inode_mark->mask & FS_EVENT_ON_CHILD))
-			return false;
 		marks_mask = inode_mark->mask;
 		marks_ignored_mask = inode_mark->ignored_mask;
 	} else if (vfsmnt_mark) {
@@ -204,10 +197,21 @@ static bool fanotify_should_send_event(struct fsnotify_group *group,
 	    (marks_ignored_mask & FS_ISDIR))
 		return false;
 
-	if (event_mask & marks_mask & ~marks_ignored_mask)
-		return true;
+	/*
+	 * if the event is for a child and this inode doesn't care about
+	 * events on the child, don't send it!
+	 */
+	if ((event_mask & FS_EVENT_ON_CHILD) &&
+	    !(marks_mask & FS_EVENT_ON_CHILD))
+		return false;
 
-	return false;
+	/*
+	 * It might seem logical to check:
+	 * if (event_mask & marks_mask & ~marks_ignored_mask)
+	 * 	return true;
+	 * but we we know this was true from the caller so just return true.
+	 */
+	return true;
 }
 
 static void fanotify_free_group_priv(struct fsnotify_group *group)
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 3568c8a..d688731 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -64,6 +64,7 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
 	struct dentry *dentry;
 	struct vfsmount *mnt;
 	struct file *new_file;
+	unsigned int flags;
 
 	pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
@@ -85,12 +86,22 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
 	mnt = mntget(event->path.mnt);
 	/* it's possible this event was an overflow event.  in that case dentry and mnt
 	 * are NULL;  That's fine, just don't call dentry open */
-	if (dentry && mnt)
-		new_file = dentry_open(dentry, mnt,
-				       group->fanotify_data.f_flags | FMODE_NONOTIFY,
-				       current_cred());
-	else
+	if (dentry && mnt) {
+		flags = group->fanotify_data.f_flags;
+		new_file = dentry_open(dentry, mnt, flags, current_cred());
+		/*
+		 * Attempt fallback to read-only access if writable was not possible
+		 * in order to at least provide something to the listener.
+		 */
+		if (IS_ERR(new_file) && group->fanotify_data.readonly_fallback) {
+			flags &= ~O_ACCMODE;
+			flags |= O_RDONLY;
+			new_file = dentry_open(dentry, mnt, flags,
+					       current_cred());
+		}
+	} else {
 		new_file = ERR_PTR(-EOVERFLOW);
+	}
 	if (IS_ERR(new_file)) {
 		/*
 		 * we still send an event even if we can't open the file.  this
@@ -210,14 +221,6 @@ static int prepare_for_access_response(struct fsnotify_group *group,
 	re->fd = fd;
 
 	mutex_lock(&group->fanotify_data.access_mutex);
-
-	if (atomic_read(&group->fanotify_data.bypass_perm)) {
-		mutex_unlock(&group->fanotify_data.access_mutex);
-		kmem_cache_free(fanotify_response_event_cache, re);
-		event->response = FAN_ALLOW;
-		return 0;
-	}
-		
 	list_add_tail(&re->list, &group->fanotify_data.access_list);
 	mutex_unlock(&group->fanotify_data.access_mutex);
 
@@ -518,6 +521,7 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
 					    unsigned int flags)
 {
 	__u32 oldmask;
+	int destroy_mark;
 
 	spin_lock(&fsn_mark->lock);
 	if (!(flags & FAN_MARK_IGNORED_MASK)) {
@@ -527,9 +531,10 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
 		oldmask = fsn_mark->ignored_mask;
 		fsnotify_set_mark_ignored_mask_locked(fsn_mark, (oldmask & ~mask));
 	}
+	destroy_mark = (!fsn_mark->mask && !fsn_mark->ignored_mask);
 	spin_unlock(&fsn_mark->lock);
 
-	if (!(oldmask & ~mask))
+	if (destroy_mark)
 		fsnotify_destroy_mark(fsn_mark);
 
 	return mask & oldmask;
@@ -541,17 +546,23 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
 {
 	struct fsnotify_mark *fsn_mark = NULL;
 	__u32 removed;
+	int ret;
 
+	mutex_lock(&group->mutex);
+	ret = -ENOENT;
 	fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
 	if (!fsn_mark)
-		return -ENOENT;
+		goto err;
 
 	removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags);
 	fsnotify_put_mark(fsn_mark);
 	if (removed & real_mount(mnt)->mnt_fsnotify_mask)
 		fsnotify_recalc_vfsmount_mask(mnt);
+	ret = 0;
+err:
+	mutex_unlock(&group->mutex);
 
-	return 0;
+	return ret;
 }
 
 static int fanotify_remove_inode_mark(struct fsnotify_group *group,
@@ -560,18 +571,24 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group,
 {
 	struct fsnotify_mark *fsn_mark = NULL;
 	__u32 removed;
+	int ret;
 
+	mutex_lock(&group->mutex);
+	ret = -ENOENT;
 	fsn_mark = fsnotify_find_inode_mark(group, inode);
 	if (!fsn_mark)
-		return -ENOENT;
+		goto err;
 
 	removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags);
 	/* matches the fsnotify_find_inode_mark() */
 	fsnotify_put_mark(fsn_mark);
 	if (removed & inode->i_fsnotify_mask)
 		fsnotify_recalc_inode_mask(inode);
+	ret = 0;
+err:
+	mutex_unlock(&group->mutex);
 
-	return 0;
+	return ret;
 }
 
 static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
@@ -607,28 +624,35 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 {
 	struct fsnotify_mark *fsn_mark;
 	__u32 added;
-	int ret = 0;
+	int ret;
 
+	mutex_lock(&group->mutex);
 	fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
 	if (!fsn_mark) {
-		if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
-			return -ENOSPC;
+		ret = -ENOSPC;
+		if (atomic_read(&group->num_marks) >
+		    group->fanotify_data.max_marks)
+			goto err;
 
+		ret = -ENOMEM;
 		fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
 		if (!fsn_mark)
-			return -ENOMEM;
+			goto err;
 
 		fsnotify_init_mark(fsn_mark, fanotify_free_mark);
 		ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0);
 		if (ret)
-			goto err;
+			goto err2;
 	}
 	added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
 
 	if (added & ~real_mount(mnt)->mnt_fsnotify_mask)
 		fsnotify_recalc_vfsmount_mask(mnt);
-err:
+	ret = 0;
+err2:
 	fsnotify_put_mark(fsn_mark);
+err:
+	mutex_unlock(&group->mutex);
 	return ret;
 }
 
@@ -638,7 +662,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 {
 	struct fsnotify_mark *fsn_mark;
 	__u32 added;
-	int ret = 0;
+	int ret;
 
 	pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
@@ -652,26 +676,33 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 	    (atomic_read(&inode->i_writecount) > 0))
 		return 0;
 
+	mutex_lock(&group->mutex);
 	fsn_mark = fsnotify_find_inode_mark(group, inode);
 	if (!fsn_mark) {
-		if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
-			return -ENOSPC;
+		ret = -ENOSPC;
+		if (atomic_read(&group->num_marks) >
+		    group->fanotify_data.max_marks)
+			goto err;
 
+		ret = -ENOMEM;
 		fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
 		if (!fsn_mark)
-			return -ENOMEM;
+			goto err;
 
 		fsnotify_init_mark(fsn_mark, fanotify_free_mark);
 		ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0);
 		if (ret)
-			goto err;
+			goto err2;
 	}
 	added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
 
 	if (added & ~inode->i_fsnotify_mask)
 		fsnotify_recalc_inode_mask(inode);
-err:
+	ret = 0;
+err2:
 	fsnotify_put_mark(fsn_mark);
+err:
+	mutex_unlock(&group->mutex);
 	return ret;
 }
 
@@ -713,7 +744,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 	group->fanotify_data.user = user;
 	atomic_inc(&user->fanotify_listeners);
 
-	group->fanotify_data.f_flags = event_f_flags;
+	group->fanotify_data.f_flags = event_f_flags | FMODE_NONOTIFY;
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
 	mutex_init(&group->fanotify_data.access_mutex);
 	init_waitqueue_head(&group->fanotify_data.access_waitq);
@@ -753,6 +784,14 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 		group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
 	}
 
+	fd = -EINVAL;
+	if (flags & FAN_READONLY_FALLBACK) {
+		if ((event_f_flags & O_ACCMODE) == O_RDWR)
+			group->fanotify_data.readonly_fallback = true;
+		else
+			goto out_put_group;
+	}
+
 	fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
 	if (fd < 0)
 		goto out_put_group;
diff --git a/fs/notify/group.c b/fs/notify/group.c
index 63fc294..7558c54 100644
--- a/fs/notify/group.c
+++ b/fs/notify/group.c
@@ -90,6 +90,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
 	 */
 	atomic_set(&group->num_marks, 1);
 
+	mutex_init(&group->mutex);
 	mutex_init(&group->notification_mutex);
 	INIT_LIST_HEAD(&group->notification_list);
 	init_waitqueue_head(&group->notification_waitq);
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index f104d56..b79dac8 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -102,17 +102,6 @@ static DEFINE_SPINLOCK(destroy_lock);
 static LIST_HEAD(destroy_list);
 static DECLARE_WAIT_QUEUE_HEAD(destroy_waitq);
 
-void fsnotify_get_mark(struct fsnotify_mark *mark)
-{
-	atomic_inc(&mark->refcnt);
-}
-
-void fsnotify_put_mark(struct fsnotify_mark *mark)
-{
-	if (atomic_dec_and_test(&mark->refcnt))
-		mark->free_mark(mark);
-}
-
 /*
  * Any time a mark is getting freed we end up here.
  * The caller had better be holding a reference to this mark so we don't actually
@@ -218,7 +207,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
 		      struct fsnotify_group *group, struct inode *inode,
 		      struct vfsmount *mnt, int allow_dups)
 {
-	int ret = 0;
+	int ret;
 
 	BUG_ON(inode && mnt);
 	BUG_ON(!inode && !mnt);
@@ -233,23 +222,20 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
 	spin_lock(&group->mark_lock);
 
 	mark->flags |= FSNOTIFY_MARK_FLAG_ALIVE;
-
 	mark->group = group;
 	list_add(&mark->g_list, &group->marks_list);
-	atomic_inc(&group->num_marks);
 	fsnotify_get_mark(mark); /* for i_list and g_list */
+	atomic_inc(&group->num_marks);
 
-	if (inode) {
+	ret = 0;
+	if (inode)
 		ret = fsnotify_add_inode_mark(mark, group, inode, allow_dups);
-		if (ret)
-			goto err;
-	} else if (mnt) {
+	else if (mnt)
 		ret = fsnotify_add_vfsmount_mark(mark, group, mnt, allow_dups);
-		if (ret)
-			goto err;
-	} else {
+	else
 		BUG();
-	}
+	if (ret)
+		goto err;
 
 	spin_unlock(&group->mark_lock);
 
@@ -261,7 +247,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark,
 	if (inode)
 		__fsnotify_update_child_dentry_flags(inode);
 
-	return ret;
+	return 0;
 err:
 	mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
 	list_del_init(&mark->g_list);
@@ -347,6 +333,10 @@ static int fsnotify_mark_destroy(void *ignored)
 
 		synchronize_srcu(&fsnotify_mark_srcu);
 
+		/*
+		 * at this point we cannot be found via the i_list or g_list so
+		 * drop that reference.
+		 */
 		list_for_each_entry_safe(mark, next, &private_destroy_list, destroy_list) {
 			list_del_init(&mark->destroy_list);
 			fsnotify_put_mark(mark);
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 0b1e885b..fa9c05f 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -94,11 +94,11 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
 			if (file_ofs < init_size)
 				ofs = init_size - file_ofs;
 			local_irq_save(flags);
-			kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
+			kaddr = kmap_atomic(page);
 			memset(kaddr + bh_offset(bh) + ofs, 0,
 					bh->b_size - ofs);
 			flush_dcache_page(page);
-			kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
+			kunmap_atomic(kaddr);
 			local_irq_restore(flags);
 		}
 	} else {
@@ -147,11 +147,11 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
 		/* Should have been verified before we got here... */
 		BUG_ON(!recs);
 		local_irq_save(flags);
-		kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
+		kaddr = kmap_atomic(page);
 		for (i = 0; i < recs; i++)
 			post_read_mst_fixup((NTFS_RECORD*)(kaddr +
 					i * rec_size), rec_size);
-		kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
+		kunmap_atomic(kaddr);
 		local_irq_restore(flags);
 		flush_dcache_page(page);
 		if (likely(page_uptodate && !PageError(page)))
@@ -504,7 +504,7 @@ retry_readpage:
 		/* Race with shrinking truncate. */
 		attr_len = i_size;
 	}
-	addr = kmap_atomic(page, KM_USER0);
+	addr = kmap_atomic(page);
 	/* Copy the data to the page. */
 	memcpy(addr, (u8*)ctx->attr +
 			le16_to_cpu(ctx->attr->data.resident.value_offset),
@@ -512,7 +512,7 @@ retry_readpage:
 	/* Zero the remainder of the page. */
 	memset(addr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
 	flush_dcache_page(page);
-	kunmap_atomic(addr, KM_USER0);
+	kunmap_atomic(addr);
 put_unm_err_out:
 	ntfs_attr_put_search_ctx(ctx);
 unm_err_out:
@@ -746,14 +746,14 @@ lock_retry_remap:
 			unsigned long *bpos, *bend;
 
 			/* Check if the buffer is zero. */
-			kaddr = kmap_atomic(page, KM_USER0);
+			kaddr = kmap_atomic(page);
 			bpos = (unsigned long *)(kaddr + bh_offset(bh));
 			bend = (unsigned long *)((u8*)bpos + blocksize);
 			do {
 				if (unlikely(*bpos))
 					break;
 			} while (likely(++bpos < bend));
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			if (bpos == bend) {
 				/*
 				 * Buffer is zero and sparse, no need to write
@@ -1495,14 +1495,14 @@ retry_writepage:
 		/* Shrinking cannot fail. */
 		BUG_ON(err);
 	}
-	addr = kmap_atomic(page, KM_USER0);
+	addr = kmap_atomic(page);
 	/* Copy the data from the page to the mft record. */
 	memcpy((u8*)ctx->attr +
 			le16_to_cpu(ctx->attr->data.resident.value_offset),
 			addr, attr_len);
 	/* Zero out of bounds area in the page cache page. */
 	memset(addr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
-	kunmap_atomic(addr, KM_USER0);
+	kunmap_atomic(addr);
 	flush_dcache_page(page);
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	/* We are done with the page. */
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index f14fde2..08c9bcd 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1656,12 +1656,12 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
 	attr_size = le32_to_cpu(a->data.resident.value_length);
 	BUG_ON(attr_size != data_size);
 	if (page && !PageUptodate(page)) {
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		memcpy(kaddr, (u8*)a +
 				le16_to_cpu(a->data.resident.value_offset),
 				attr_size);
 		memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		flush_dcache_page(page);
 		SetPageUptodate(page);
 	}
@@ -1806,9 +1806,9 @@ undo_err_out:
 			sizeof(a->data.resident.reserved));
 	/* Copy the data from the page back to the attribute value. */
 	if (page) {
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		memcpy((u8*)a + mp_ofs, kaddr, attr_size);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 	/* Setup the allocated size in the ntfs inode in case it changed. */
 	write_lock_irqsave(&ni->size_lock, flags);
@@ -2540,10 +2540,10 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
 		size = PAGE_CACHE_SIZE;
 		if (idx == end)
 			size = end_ofs;
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		memset(kaddr + start_ofs, val, size - start_ofs);
 		flush_dcache_page(page);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		set_page_dirty(page);
 		page_cache_release(page);
 		balance_dirty_pages_ratelimited(mapping);
@@ -2561,10 +2561,10 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
 					"page (index 0x%lx).", idx);
 			return -ENOMEM;
 		}
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		memset(kaddr, val, PAGE_CACHE_SIZE);
 		flush_dcache_page(page);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		/*
 		 * If the page has buffers, mark them uptodate since buffer
 		 * state and not page state is definitive in 2.6 kernels.
@@ -2598,10 +2598,10 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
 					"(error, index 0x%lx).", idx);
 			return PTR_ERR(page);
 		}
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		memset(kaddr, val, end_ofs);
 		flush_dcache_page(page);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		set_page_dirty(page);
 		page_cache_release(page);
 		balance_dirty_pages_ratelimited(mapping);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index c587e2d..8639169 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -704,7 +704,7 @@ map_buffer_cached:
 				u8 *kaddr;
 				unsigned pofs;
 					
-				kaddr = kmap_atomic(page, KM_USER0);
+				kaddr = kmap_atomic(page);
 				if (bh_pos < pos) {
 					pofs = bh_pos & ~PAGE_CACHE_MASK;
 					memset(kaddr + pofs, 0, pos - bh_pos);
@@ -713,7 +713,7 @@ map_buffer_cached:
 					pofs = end & ~PAGE_CACHE_MASK;
 					memset(kaddr + pofs, 0, bh_end - end);
 				}
-				kunmap_atomic(kaddr, KM_USER0);
+				kunmap_atomic(kaddr);
 				flush_dcache_page(page);
 			}
 			continue;
@@ -1287,9 +1287,9 @@ static inline size_t ntfs_copy_from_user(struct page **pages,
 		len = PAGE_CACHE_SIZE - ofs;
 		if (len > bytes)
 			len = bytes;
-		addr = kmap_atomic(*pages, KM_USER0);
+		addr = kmap_atomic(*pages);
 		left = __copy_from_user_inatomic(addr + ofs, buf, len);
-		kunmap_atomic(addr, KM_USER0);
+		kunmap_atomic(addr);
 		if (unlikely(left)) {
 			/* Do it the slow way. */
 			addr = kmap(*pages);
@@ -1401,10 +1401,10 @@ static inline size_t ntfs_copy_from_user_iovec(struct page **pages,
 		len = PAGE_CACHE_SIZE - ofs;
 		if (len > bytes)
 			len = bytes;
-		addr = kmap_atomic(*pages, KM_USER0);
+		addr = kmap_atomic(*pages);
 		copied = __ntfs_copy_from_user_iovec_inatomic(addr + ofs,
 				*iov, *iov_ofs, len);
-		kunmap_atomic(addr, KM_USER0);
+		kunmap_atomic(addr);
 		if (unlikely(copied != len)) {
 			/* Do it the slow way. */
 			addr = kmap(*pages);
@@ -1691,7 +1691,7 @@ static int ntfs_commit_pages_after_write(struct page **pages,
 	BUG_ON(end > le32_to_cpu(a->length) -
 			le16_to_cpu(a->data.resident.value_offset));
 	kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	/* Copy the received data from the page to the mft record. */
 	memcpy(kattr + pos, kaddr + pos, bytes);
 	/* Update the attribute length if necessary. */
@@ -1713,7 +1713,7 @@ static int ntfs_commit_pages_after_write(struct page **pages,
 		flush_dcache_page(page);
 		SetPageUptodate(page);
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	/* Update initialized_size/i_size if necessary. */
 	read_lock_irqsave(&ni->size_lock, flags);
 	initialized_size = ni->initialized_size;
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index faece71..809c0e6 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -2008,14 +2008,14 @@ typedef struct {
  *
  * When a directory is small enough to fit inside the index root then this
  * is the only attribute describing the directory. When the directory is too
- * large to fit in the index root, on the other hand, two aditional attributes
+ * large to fit in the index root, on the other hand, two additional attributes
  * are present: an index allocation attribute, containing sub-nodes of the B+
  * directory tree (see below), and a bitmap attribute, describing which virtual
  * cluster numbers (vcns) in the index allocation attribute are in use by an
  * index block.
  *
  * NOTE: The root directory (FILE_root) contains an entry for itself. Other
- * dircetories do not contain entries for themselves, though.
+ * directories do not contain entries for themselves, though.
  */
 typedef struct {
 	ATTR_TYPE type;			/* Type of the indexed attribute. Is
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 382857f..862f7ff 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1367,7 +1367,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
 			ntfs_error(vol->sb, "Failed to merge runlists for mft "
 					"bitmap.");
 			if (ntfs_cluster_free_from_rl(vol, rl2)) {
-				ntfs_error(vol->sb, "Failed to dealocate "
+				ntfs_error(vol->sb, "Failed to deallocate "
 						"allocated cluster.%s", es);
 				NVolSetErrors(vol);
 			}
@@ -1805,7 +1805,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
 		ntfs_error(vol->sb, "Failed to merge runlists for mft data "
 				"attribute.");
 		if (ntfs_cluster_free_from_rl(vol, rl2)) {
-			ntfs_error(vol->sb, "Failed to dealocate clusters "
+			ntfs_error(vol->sb, "Failed to deallocate clusters "
 					"from the mft data attribute.%s", es);
 			NVolSetErrors(vol);
 		}
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 5a4a8af..82b52cf 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2475,7 +2475,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
 			nr_free -= PAGE_CACHE_SIZE * 8;
 			continue;
 		}
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		/*
 		 * Subtract the number of set bits. If this
 		 * is the last page and it is partial we don't really care as
@@ -2485,7 +2485,7 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
 		 */
 		nr_free -= bitmap_weight(kaddr,
 					PAGE_CACHE_SIZE * BITS_PER_BYTE);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		page_cache_release(page);
 	}
 	ntfs_debug("Finished reading $Bitmap, last index = 0x%lx.", index - 1);
@@ -2546,7 +2546,7 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
 			nr_free -= PAGE_CACHE_SIZE * 8;
 			continue;
 		}
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		/*
 		 * Subtract the number of set bits. If this
 		 * is the last page and it is partial we don't really care as
@@ -2556,7 +2556,7 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
 		 */
 		nr_free -= bitmap_weight(kaddr,
 					PAGE_CACHE_SIZE * BITS_PER_BYTE);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		page_cache_release(page);
 	}
 	ntfs_debug("Finished reading $MFT/$BITMAP, last index = 0x%lx.",
@@ -2910,9 +2910,10 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
 		ntfs_error(sb, "Failed to load system files.");
 		goto unl_upcase_iput_tmp_ino_err_out_now;
 	}
-	if ((sb->s_root = d_alloc_root(vol->root_ino))) {
-		/* We grab a reference, simulating an ntfs_iget(). */
-		ihold(vol->root_ino);
+
+	/* We grab a reference, simulating an ntfs_iget(). */
+	ihold(vol->root_ino);
+	if ((sb->s_root = d_make_root(vol->root_ino))) {
 		ntfs_debug("Exiting, status successful.");
 		/* Release the default upcase if it has no users. */
 		mutex_lock(&ntfs_lock);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 78b68af..6577432 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -102,7 +102,7 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
 		 * copy, the data is still good. */
 		if (buffer_jbd(buffer_cache_bh)
 		    && ocfs2_inode_is_new(inode)) {
-			kaddr = kmap_atomic(bh_result->b_page, KM_USER0);
+			kaddr = kmap_atomic(bh_result->b_page);
 			if (!kaddr) {
 				mlog(ML_ERROR, "couldn't kmap!\n");
 				goto bail;
@@ -110,7 +110,7 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
 			memcpy(kaddr + (bh_result->b_size * iblock),
 			       buffer_cache_bh->b_data,
 			       bh_result->b_size);
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			set_buffer_uptodate(bh_result);
 		}
 		brelse(buffer_cache_bh);
@@ -236,13 +236,13 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page,
 		return -EROFS;
 	}
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	if (size)
 		memcpy(kaddr, di->id2.i_data.id_data, size);
 	/* Clear the remaining part of the page */
 	memset(kaddr + size, 0, PAGE_CACHE_SIZE - size);
 	flush_dcache_page(page);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	SetPageUptodate(page);
 
@@ -689,7 +689,7 @@ static void ocfs2_clear_page_regions(struct page *page,
 
 	ocfs2_figure_cluster_boundaries(osb, cpos, &cluster_start, &cluster_end);
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 
 	if (from || to) {
 		if (from > cluster_start)
@@ -700,7 +700,7 @@ static void ocfs2_clear_page_regions(struct page *page,
 		memset(kaddr + cluster_start, 0, cluster_end - cluster_start);
 	}
 
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 /*
@@ -1981,9 +1981,9 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos,
 		}
 	}
 
-	kaddr = kmap_atomic(wc->w_target_page, KM_USER0);
+	kaddr = kmap_atomic(wc->w_target_page);
 	memcpy(di->id2.i_data.id_data + pos, kaddr + pos, *copied);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	trace_ocfs2_write_end_inline(
 	     (unsigned long long)OCFS2_I(inode)->ip_blkno,
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index a4e855e..f3f2d95 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -35,6 +35,7 @@
 #include <linux/time.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
+#include <linux/bitmap.h>
 
 #include "heartbeat.h"
 #include "tcp.h"
@@ -282,15 +283,6 @@ struct o2hb_bio_wait_ctxt {
 	int               wc_error;
 };
 
-static int o2hb_pop_count(void *map, int count)
-{
-	int i = -1, pop = 0;
-
-	while ((i = find_next_bit(map, count, i + 1)) < count)
-		pop++;
-	return pop;
-}
-
 static void o2hb_write_timeout(struct work_struct *work)
 {
 	int failed, quorum;
@@ -307,9 +299,9 @@ static void o2hb_write_timeout(struct work_struct *work)
 		spin_lock_irqsave(&o2hb_live_lock, flags);
 		if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
 			set_bit(reg->hr_region_num, o2hb_failed_region_bitmap);
-		failed = o2hb_pop_count(&o2hb_failed_region_bitmap,
+		failed = bitmap_weight(o2hb_failed_region_bitmap,
 					O2NM_MAX_REGIONS);
-		quorum = o2hb_pop_count(&o2hb_quorum_region_bitmap,
+		quorum = bitmap_weight(o2hb_quorum_region_bitmap,
 					O2NM_MAX_REGIONS);
 		spin_unlock_irqrestore(&o2hb_live_lock, flags);
 
@@ -771,7 +763,7 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg)
 	 * If global heartbeat active, unpin all regions if the
 	 * region count > CUT_OFF
 	 */
-	if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
+	if (bitmap_weight(o2hb_quorum_region_bitmap,
 			   O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF)
 		o2hb_region_unpin(NULL);
 unlock:
@@ -956,23 +948,9 @@ out:
 	return changed;
 }
 
-/* This could be faster if we just implmented a find_last_bit, but I
- * don't think the circumstances warrant it. */
-static int o2hb_highest_node(unsigned long *nodes,
-			     int numbits)
+static int o2hb_highest_node(unsigned long *nodes, int numbits)
 {
-	int highest, node;
-
-	highest = numbits;
-	node = -1;
-	while ((node = find_next_bit(nodes, numbits, node + 1)) != -1) {
-		if (node >= numbits)
-			break;
-
-		highest = node;
-	}
-
-	return highest;
+	return find_last_bit(nodes, numbits);
 }
 
 static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
@@ -1833,7 +1811,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
 	live_threshold = O2HB_LIVE_THRESHOLD;
 	if (o2hb_global_heartbeat_active()) {
 		spin_lock(&o2hb_live_lock);
-		if (o2hb_pop_count(&o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1)
+		if (bitmap_weight(o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1)
 			live_threshold <<= 1;
 		spin_unlock(&o2hb_live_lock);
 	}
@@ -2184,7 +2162,7 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
 	if (!o2hb_dependent_users)
 		goto unlock;
 
-	if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
+	if (bitmap_weight(o2hb_quorum_region_bitmap,
 			   O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF)
 		o2hb_region_pin(NULL);
 
@@ -2478,7 +2456,7 @@ static int o2hb_region_inc_user(const char *region_uuid)
 	if (o2hb_dependent_users > 1)
 		goto unlock;
 
-	if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
+	if (bitmap_weight(o2hb_quorum_region_bitmap,
 			   O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF)
 		ret = o2hb_region_pin(NULL);
 
diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c
index abfac0d..3b5825e 100644
--- a/fs/ocfs2/dlmfs/dlmfs.c
+++ b/fs/ocfs2/dlmfs/dlmfs.c
@@ -582,24 +582,14 @@ static int dlmfs_fill_super(struct super_block * sb,
 			    void * data,
 			    int silent)
 {
-	struct inode * inode;
-	struct dentry * root;
-
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = DLMFS_MAGIC;
 	sb->s_op = &dlmfs_ops;
-	inode = dlmfs_get_root_inode(sb);
-	if (!inode)
-		return -ENOMEM;
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		iput(inode);
+	sb->s_root = d_make_root(dlmfs_get_root_inode(sb));
+	if (!sb->s_root)
 		return -ENOMEM;
-	}
-	sb->s_root = root;
 	return 0;
 }
 
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index be24469..a9856e3 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1053,7 +1053,7 @@ static int ocfs2_rename(struct inode *old_dir,
 	handle_t *handle = NULL;
 	struct buffer_head *old_dir_bh = NULL;
 	struct buffer_head *new_dir_bh = NULL;
-	nlink_t old_dir_nlink = old_dir->i_nlink;
+	u32 old_dir_nlink = old_dir->i_nlink;
 	struct ocfs2_dinode *old_di;
 	struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
 	struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 604e12c..337687c 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1154,19 +1154,19 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 	}
 
 	status = ocfs2_mount_volume(sb);
-	if (osb->root_inode)
-		inode = igrab(osb->root_inode);
-
 	if (status < 0)
 		goto read_super_error;
 
+	if (osb->root_inode)
+		inode = igrab(osb->root_inode);
+
 	if (!inode) {
 		status = -EIO;
 		mlog_errno(status);
 		goto read_super_error;
 	}
 
-	root = d_alloc_root(inode);
+	root = d_make_root(inode);
 	if (!root) {
 		status = -ENOMEM;
 		mlog_errno(status);
@@ -1220,9 +1220,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
 read_super_error:
 	brelse(bh);
 
-	if (inode)
-		iput(inode);
-
 	if (osb) {
 		atomic_set(&osb->vol_state, VOLUME_DISABLED);
 		wake_up(&osb->osb_mount_event);
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index 6065bb0..dbc8422 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -539,11 +539,9 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
 		goto out_brelse_bh2;
 	}
 
-	sb->s_root = d_alloc_root(root);
-	if (!sb->s_root) {
-		iput(root);
+	sb->s_root = d_make_root(root);
+	if (!sb->s_root)
 		goto out_brelse_bh2;
-	}
 	printk(KERN_DEBUG "omfs: Mounted volume %s\n", omfs_rb->r_name);
 
 	ret = 0;
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index a88c03b..bc49c97 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -408,13 +408,12 @@ static int openprom_fill_super(struct super_block *s, void *data, int silent)
 	oi->type = op_inode_node;
 	oi->u.node = of_find_node_by_path("/");
 
-	s->s_root = d_alloc_root(root_inode);
+	s->s_root = d_make_root(root_inode);
 	if (!s->s_root)
 		goto out_no_root_dentry;
 	return 0;
 
 out_no_root_dentry:
-	iput(root_inode);
 	ret = -ENOMEM;
 out_no_root:
 	printk("openprom_fill_super: get root inode failed\n");
diff --git a/fs/pipe.c b/fs/pipe.c
index a932ced..25feaa3 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -13,6 +13,7 @@
 #include <linux/fs.h>
 #include <linux/log2.h>
 #include <linux/mount.h>
+#include <linux/magic.h>
 #include <linux/pipe_fs_i.h>
 #include <linux/uio.h>
 #include <linux/highmem.h>
@@ -230,7 +231,7 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
 {
 	if (atomic) {
 		buf->flags |= PIPE_BUF_FLAG_ATOMIC;
-		return kmap_atomic(buf->page, KM_USER0);
+		return kmap_atomic(buf->page);
 	}
 
 	return kmap(buf->page);
@@ -251,7 +252,7 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
 {
 	if (buf->flags & PIPE_BUF_FLAG_ATOMIC) {
 		buf->flags &= ~PIPE_BUF_FLAG_ATOMIC;
-		kunmap_atomic(map_data, KM_USER0);
+		kunmap_atomic(map_data);
 	} else
 		kunmap(buf->page);
 }
@@ -565,14 +566,14 @@ redo1:
 			iov_fault_in_pages_read(iov, chars);
 redo2:
 			if (atomic)
-				src = kmap_atomic(page, KM_USER0);
+				src = kmap_atomic(page);
 			else
 				src = kmap(page);
 
 			error = pipe_iov_copy_from_user(src, iov, chars,
 							atomic);
 			if (atomic)
-				kunmap_atomic(src, KM_USER0);
+				kunmap_atomic(src);
 			else
 				kunmap(page);
 
diff --git a/fs/pnode.c b/fs/pnode.c
index ab5fa9e..bed378d 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -257,12 +257,12 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
 		prev_src_mnt  = child;
 	}
 out:
-	br_write_lock(vfsmount_lock);
+	br_write_lock(&vfsmount_lock);
 	while (!list_empty(&tmp_list)) {
 		child = list_first_entry(&tmp_list, struct mount, mnt_hash);
 		umount_tree(child, 0, &umount_list);
 	}
-	br_write_unlock(vfsmount_lock);
+	br_write_unlock(&vfsmount_lock);
 	release_mounts(&umount_list);
 	return ret;
 }
diff --git a/fs/proc/array.c b/fs/proc/array.c
index c602b8d..a0ce1bfb 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -462,59 +462,70 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 	/* convert nsec -> ticks */
 	start_time = nsec_to_clock_t(start_time);
 
-	seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
-%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
-%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld %lu %lu %lu\n",
-		pid_nr_ns(pid, ns),
-		tcomm,
-		state,
-		ppid,
-		pgid,
-		sid,
-		tty_nr,
-		tty_pgrp,
-		task->flags,
-		min_flt,
-		cmin_flt,
-		maj_flt,
-		cmaj_flt,
-		cputime_to_clock_t(utime),
-		cputime_to_clock_t(stime),
-		cputime_to_clock_t(cutime),
-		cputime_to_clock_t(cstime),
-		priority,
-		nice,
-		num_threads,
-		start_time,
-		vsize,
-		mm ? get_mm_rss(mm) : 0,
-		rsslim,
-		mm ? (permitted ? mm->start_code : 1) : 0,
-		mm ? (permitted ? mm->end_code : 1) : 0,
-		(permitted && mm) ? mm->start_stack : 0,
-		esp,
-		eip,
-		/* The signal information here is obsolete.
-		 * It must be decimal for Linux 2.0 compatibility.
-		 * Use /proc/#/status for real-time signals.
-		 */
-		task->pending.signal.sig[0] & 0x7fffffffUL,
-		task->blocked.sig[0] & 0x7fffffffUL,
-		sigign      .sig[0] & 0x7fffffffUL,
-		sigcatch    .sig[0] & 0x7fffffffUL,
-		wchan,
-		0UL,
-		0UL,
-		task->exit_signal,
-		task_cpu(task),
-		task->rt_priority,
-		task->policy,
-		(unsigned long long)delayacct_blkio_ticks(task),
-		cputime_to_clock_t(gtime),
-		cputime_to_clock_t(cgtime),
-		(mm && permitted) ? mm->start_data : 0,
-		(mm && permitted) ? mm->end_data : 0,
-		(mm && permitted) ? mm->start_brk : 0);
+	seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
+	seq_put_decimal_ll(m, ' ', ppid);
+	seq_put_decimal_ll(m, ' ', pgid);
+	seq_put_decimal_ll(m, ' ', sid);
+	seq_put_decimal_ll(m, ' ', tty_nr);
+	seq_put_decimal_ll(m, ' ', tty_pgrp);
+	seq_put_decimal_ull(m, ' ', task->flags);
+	seq_put_decimal_ull(m, ' ', min_flt);
+	seq_put_decimal_ull(m, ' ', cmin_flt);
+	seq_put_decimal_ull(m, ' ', maj_flt);
+	seq_put_decimal_ull(m, ' ', cmaj_flt);
+	seq_put_decimal_ull(m, ' ', cputime_to_clock_t(utime));
+	seq_put_decimal_ull(m, ' ', cputime_to_clock_t(stime));
+	seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cutime));
+	seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cstime));
+	seq_put_decimal_ll(m, ' ', priority);
+	seq_put_decimal_ll(m, ' ', nice);
+	seq_put_decimal_ll(m, ' ', num_threads);
+	seq_put_decimal_ull(m, ' ', 0);
+	seq_put_decimal_ull(m, ' ', start_time);
+	seq_put_decimal_ull(m, ' ', vsize);
+	seq_put_decimal_ll(m, ' ', mm ? get_mm_rss(mm) : 0);
+	seq_put_decimal_ull(m, ' ', rsslim);
+	seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0);
+	seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0);
+	seq_put_decimal_ull(m, ' ', (permitted && mm) ? mm->start_stack : 0);
+	seq_put_decimal_ull(m, ' ', esp);
+	seq_put_decimal_ull(m, ' ', eip);
+	/* The signal information here is obsolete.
+	 * It must be decimal for Linux 2.0 compatibility.
+	 * Use /proc/#/status for real-time signals.
+	 */
+	seq_put_decimal_ull(m, ' ', task->pending.signal.sig[0] & 0x7fffffffUL);
+	seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
+	seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
+	seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
+	seq_put_decimal_ull(m, ' ', wchan);
+	seq_put_decimal_ull(m, ' ', 0);
+	seq_put_decimal_ull(m, ' ', 0);
+	seq_put_decimal_ll(m, ' ', task->exit_signal);
+	seq_put_decimal_ll(m, ' ', task_cpu(task));
+	seq_put_decimal_ull(m, ' ', task->rt_priority);
+	seq_put_decimal_ull(m, ' ', task->policy);
+	seq_put_decimal_ull(m, ' ', delayacct_blkio_ticks(task));
+	seq_put_decimal_ull(m, ' ', cputime_to_clock_t(gtime));
+	seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cgtime));
+
+	if (mm && permitted) {
+		seq_put_decimal_ull(m, ' ', mm->start_data);
+		seq_put_decimal_ull(m, ' ', mm->end_data);
+		seq_put_decimal_ull(m, ' ', mm->start_brk);
+		seq_put_decimal_ull(m, ' ', mm->arg_start);
+		seq_put_decimal_ull(m, ' ', mm->arg_end);
+		seq_put_decimal_ull(m, ' ', mm->env_start);
+		seq_put_decimal_ull(m, ' ', mm->env_end);
+	} else
+		seq_printf(m, " 0 0 0 0 0 0 0");
+
+	if (permitted)
+		seq_put_decimal_ll(m, ' ', task->exit_code);
+	else
+		seq_put_decimal_ll(m, ' ', 0);
+
+	seq_putc(m, '\n');
 	if (mm)
 		mmput(mm);
 	return 0;
@@ -542,8 +553,143 @@ int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
 		size = task_statm(mm, &shared, &text, &data, &resident);
 		mmput(mm);
 	}
-	seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
-			size, resident, shared, text, data);
+	/*
+	 * For quick read, open code by putting numbers directly
+	 * expected format is
+	 * seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
+	 *               size, resident, shared, text, data);
+	 */
+	seq_put_decimal_ull(m, 0, size);
+	seq_put_decimal_ull(m, ' ', resident);
+	seq_put_decimal_ull(m, ' ', shared);
+	seq_put_decimal_ull(m, ' ', text);
+	seq_put_decimal_ull(m, ' ', 0);
+	seq_put_decimal_ull(m, ' ', text);
+	seq_put_decimal_ull(m, ' ', 0);
+	seq_putc(m, '\n');
 
 	return 0;
 }
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
+static struct pid *
+get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
+{
+	struct task_struct *start, *task;
+	struct pid *pid = NULL;
+
+	read_lock(&tasklist_lock);
+
+	start = pid_task(proc_pid(inode), PIDTYPE_PID);
+	if (!start)
+		goto out;
+
+	/*
+	 * Lets try to continue searching first, this gives
+	 * us significant speedup on children-rich processes.
+	 */
+	if (pid_prev) {
+		task = pid_task(pid_prev, PIDTYPE_PID);
+		if (task && task->real_parent == start &&
+		    !(list_empty(&task->sibling))) {
+			if (list_is_last(&task->sibling, &start->children))
+				goto out;
+			task = list_first_entry(&task->sibling,
+						struct task_struct, sibling);
+			pid = get_pid(task_pid(task));
+			goto out;
+		}
+	}
+
+	/*
+	 * Slow search case.
+	 *
+	 * We might miss some children here if children
+	 * are exited while we were not holding the lock,
+	 * but it was never promised to be accurate that
+	 * much.
+	 *
+	 * "Just suppose that the parent sleeps, but N children
+	 *  exit after we printed their tids. Now the slow paths
+	 *  skips N extra children, we miss N tasks." (c)
+	 *
+	 * So one need to stop or freeze the leader and all
+	 * its children to get a precise result.
+	 */
+	list_for_each_entry(task, &start->children, sibling) {
+		if (pos-- == 0) {
+			pid = get_pid(task_pid(task));
+			break;
+		}
+	}
+
+out:
+	read_unlock(&tasklist_lock);
+	return pid;
+}
+
+static int children_seq_show(struct seq_file *seq, void *v)
+{
+	struct inode *inode = seq->private;
+	pid_t pid;
+
+	pid = pid_nr_ns(v, inode->i_sb->s_fs_info);
+	return seq_printf(seq, "%d ", pid);
+}
+
+static void *children_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	return get_children_pid(seq->private, NULL, *pos);
+}
+
+static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct pid *pid;
+
+	pid = get_children_pid(seq->private, v, *pos + 1);
+	put_pid(v);
+
+	++*pos;
+	return pid;
+}
+
+static void children_seq_stop(struct seq_file *seq, void *v)
+{
+	put_pid(v);
+}
+
+static const struct seq_operations children_seq_ops = {
+	.start	= children_seq_start,
+	.next	= children_seq_next,
+	.stop	= children_seq_stop,
+	.show	= children_seq_show,
+};
+
+static int children_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *m;
+	int ret;
+
+	ret = seq_open(file, &children_seq_ops);
+	if (ret)
+		return ret;
+
+	m = file->private_data;
+	m->private = inode;
+
+	return ret;
+}
+
+int children_seq_release(struct inode *inode, struct file *file)
+{
+	seq_release(inode, file);
+	return 0;
+}
+
+const struct file_operations proc_tid_children_operations = {
+	.open    = children_seq_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = children_seq_release,
+};
+#endif /* CONFIG_CHECKPOINT_RESTORE */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d4548dd..49aa75f 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -801,28 +801,38 @@ static const struct file_operations proc_mem_operations = {
 	.release	= mem_release,
 };
 
+static int environ_open(struct inode *inode, struct file *file)
+{
+	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
+	struct mm_struct *mm;
+
+	if (!task)
+		return -ESRCH;
+
+	mm = mm_for_maps(task);
+	put_task_struct(task);
+
+	if (!mm)
+		return -ENOENT;
+	if (IS_ERR(mm))
+		return PTR_ERR(mm);
+
+	file->private_data = mm;
+
+	return 0;
+}
+
 static ssize_t environ_read(struct file *file, char __user *buf,
 			size_t count, loff_t *ppos)
 {
-	struct task_struct *task = get_proc_task(file->f_dentry->d_inode);
 	char *page;
 	unsigned long src = *ppos;
-	int ret = -ESRCH;
-	struct mm_struct *mm;
-
-	if (!task)
-		goto out_no_task;
+	int ret = 0;
+	struct mm_struct *mm = file->private_data;
 
-	ret = -ENOMEM;
 	page = (char *)__get_free_page(GFP_TEMPORARY);
 	if (!page)
-		goto out;
-
-
-	mm = mm_for_maps(task);
-	ret = PTR_ERR(mm);
-	if (!mm || IS_ERR(mm))
-		goto out_free;
+		return -ENOMEM;
 
 	ret = 0;
 	while (count > 0) {
@@ -836,7 +846,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
 		max_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
 		this_len = (this_len > max_len) ? max_len : this_len;
 
-		retval = access_process_vm(task, (mm->env_start + src),
+		retval = access_remote_vm(mm, (mm->env_start + src),
 			page, this_len, 0);
 
 		if (retval <= 0) {
@@ -856,18 +866,23 @@ static ssize_t environ_read(struct file *file, char __user *buf,
 	}
 	*ppos = src;
 
-	mmput(mm);
-out_free:
 	free_page((unsigned long) page);
-out:
-	put_task_struct(task);
-out_no_task:
 	return ret;
 }
 
+static int environ_release(struct inode *inode, struct file *file)
+{
+	struct mm_struct *mm = file->private_data;
+
+	mmput(mm);
+	return 0;
+}
+
 static const struct file_operations proc_environ_operations = {
+	.open		= environ_open,
 	.read		= environ_read,
 	.llseek		= generic_file_llseek,
+	.release	= environ_release,
 };
 
 static ssize_t oom_adjust_read(struct file *file, char __user *buf,
@@ -3350,6 +3365,9 @@ static const struct pid_entry tid_base_stuff[] = {
 	ONE("stat",      S_IRUGO, proc_tid_stat),
 	ONE("statm",     S_IRUGO, proc_pid_statm),
 	REG("maps",      S_IRUGO, proc_maps_operations),
+#ifdef CONFIG_CHECKPOINT_RESTORE
+	REG("children",  S_IRUGO, proc_tid_children_operations),
+#endif
 #ifdef CONFIG_NUMA
 	REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
 #endif
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 84fd323..8461a7b 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -486,8 +486,6 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
 
 int proc_fill_super(struct super_block *s)
 {
-	struct inode * root_inode;
-
 	s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC;
 	s->s_blocksize = 1024;
 	s->s_blocksize_bits = 10;
@@ -496,19 +494,11 @@ int proc_fill_super(struct super_block *s)
 	s->s_time_gran = 1;
 	
 	pde_get(&proc_root);
-	root_inode = proc_get_inode(s, &proc_root);
-	if (!root_inode)
-		goto out_no_root;
-	root_inode->i_uid = 0;
-	root_inode->i_gid = 0;
-	s->s_root = d_alloc_root(root_inode);
-	if (!s->s_root)
-		goto out_no_root;
-	return 0;
+	s->s_root = d_make_root(proc_get_inode(s, &proc_root));
+	if (s->s_root)
+		return 0;
 
-out_no_root:
 	printk("proc_read_super: get root inode failed\n");
-	iput(root_inode);
 	pde_put(&proc_root);
 	return -ENOMEM;
 }
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 2925775..ef97ba6 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -10,12 +10,15 @@
  */
 
 #include <linux/proc_fs.h>
+struct  ctl_table_header;
 
 extern struct proc_dir_entry proc_root;
 #ifdef CONFIG_PROC_SYSCTL
 extern int proc_sys_init(void);
+extern void sysctl_head_put(struct ctl_table_header *head);
 #else
 static inline void proc_sys_init(void) { }
+static inline void sysctl_head_put(struct ctl_table_header *head) { }
 #endif
 #ifdef CONFIG_NET
 extern int proc_net_init(void);
@@ -53,6 +56,7 @@ extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
 				struct pid *pid, struct task_struct *task);
 extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
 
+extern const struct file_operations proc_tid_children_operations;
 extern const struct file_operations proc_maps_operations;
 extern const struct file_operations proc_numa_maps_operations;
 extern const struct file_operations proc_smaps_operations;
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index d245cb2..699e92b 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -157,7 +157,8 @@ static int kcore_update_ram(void)
 
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 /* calculate vmemmap's address from given system ram pfn and register it */
-int get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
+static int
+get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
 {
 	unsigned long pfn = __pa(ent->addr) >> PAGE_SHIFT;
 	unsigned long nr_pages = ent->size >> PAGE_SHIFT;
@@ -189,7 +190,8 @@ int get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
 
 }
 #else
-int get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
+static int
+get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
 {
 	return 1;
 }
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 27da860..c2c3e4a 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -156,15 +156,15 @@ static struct dentry *proc_ns_dir_lookup(struct inode *dir,
 	if (!ptrace_may_access(task, PTRACE_MODE_READ))
 		goto out;
 
-	last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
-	for (entry = ns_entries; entry <= last; entry++) {
+	last = &ns_entries[ARRAY_SIZE(ns_entries)];
+	for (entry = ns_entries; entry < last; entry++) {
 		if (strlen((*entry)->name) != len)
 			continue;
 		if (!memcmp(dentry->d_name.name, (*entry)->name, len))
 			break;
 	}
 	error = ERR_PTR(-ENOENT);
-	if (entry > last)
+	if (entry == last)
 		goto out;
 
 	error = proc_ns_instantiate(dir, dentry, task, *entry);
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 6d8e6a9..7fcd0d6 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -115,6 +115,8 @@ u64 stable_page_flags(struct page *page)
 		u |= 1 << KPF_COMPOUND_TAIL;
 	if (PageHuge(page))
 		u |= 1 << KPF_HUGE;
+	else if (PageTransCompound(page))
+		u |= 1 << KPF_THP;
 
 	/*
 	 * Caveats on high order pages: page->_count will only be set
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index a6b6217..9c2fea8 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -6,7 +6,10 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/security.h>
+#include <linux/sched.h>
 #include <linux/namei.h>
+#include <linux/mm.h>
+#include <linux/module.h>
 #include "internal.h"
 
 static const struct dentry_operations proc_sys_dentry_operations;
@@ -24,6 +27,371 @@ void proc_sys_poll_notify(struct ctl_table_poll *poll)
 	wake_up_interruptible(&poll->wait);
 }
 
+static struct ctl_table root_table[] = {
+	{
+		.procname = "",
+		.mode = S_IFDIR|S_IRUGO|S_IXUGO,
+	},
+	{ }
+};
+static struct ctl_table_root sysctl_table_root = {
+	.default_set.dir.header = {
+		{{.count = 1,
+		  .nreg = 1,
+		  .ctl_table = root_table }},
+		.ctl_table_arg = root_table,
+		.root = &sysctl_table_root,
+		.set = &sysctl_table_root.default_set,
+	},
+};
+
+static DEFINE_SPINLOCK(sysctl_lock);
+
+static void drop_sysctl_table(struct ctl_table_header *header);
+static int sysctl_follow_link(struct ctl_table_header **phead,
+	struct ctl_table **pentry, struct nsproxy *namespaces);
+static int insert_links(struct ctl_table_header *head);
+static void put_links(struct ctl_table_header *header);
+
+static void sysctl_print_dir(struct ctl_dir *dir)
+{
+	if (dir->header.parent)
+		sysctl_print_dir(dir->header.parent);
+	printk(KERN_CONT "%s/", dir->header.ctl_table[0].procname);
+}
+
+static int namecmp(const char *name1, int len1, const char *name2, int len2)
+{
+	int minlen;
+	int cmp;
+
+	minlen = len1;
+	if (minlen > len2)
+		minlen = len2;
+
+	cmp = memcmp(name1, name2, minlen);
+	if (cmp == 0)
+		cmp = len1 - len2;
+	return cmp;
+}
+
+/* Called under sysctl_lock */
+static struct ctl_table *find_entry(struct ctl_table_header **phead,
+	struct ctl_dir *dir, const char *name, int namelen)
+{
+	struct ctl_table_header *head;
+	struct ctl_table *entry;
+	struct rb_node *node = dir->root.rb_node;
+
+	while (node)
+	{
+		struct ctl_node *ctl_node;
+		const char *procname;
+		int cmp;
+
+		ctl_node = rb_entry(node, struct ctl_node, node);
+		head = ctl_node->header;
+		entry = &head->ctl_table[ctl_node - head->node];
+		procname = entry->procname;
+
+		cmp = namecmp(name, namelen, procname, strlen(procname));
+		if (cmp < 0)
+			node = node->rb_left;
+		else if (cmp > 0)
+			node = node->rb_right;
+		else {
+			*phead = head;
+			return entry;
+		}
+	}
+	return NULL;
+}
+
+static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
+{
+	struct rb_node *node = &head->node[entry - head->ctl_table].node;
+	struct rb_node **p = &head->parent->root.rb_node;
+	struct rb_node *parent = NULL;
+	const char *name = entry->procname;
+	int namelen = strlen(name);
+
+	while (*p) {
+		struct ctl_table_header *parent_head;
+		struct ctl_table *parent_entry;
+		struct ctl_node *parent_node;
+		const char *parent_name;
+		int cmp;
+
+		parent = *p;
+		parent_node = rb_entry(parent, struct ctl_node, node);
+		parent_head = parent_node->header;
+		parent_entry = &parent_head->ctl_table[parent_node - parent_head->node];
+		parent_name = parent_entry->procname;
+
+		cmp = namecmp(name, namelen, parent_name, strlen(parent_name));
+		if (cmp < 0)
+			p = &(*p)->rb_left;
+		else if (cmp > 0)
+			p = &(*p)->rb_right;
+		else {
+			printk(KERN_ERR "sysctl duplicate entry: ");
+			sysctl_print_dir(head->parent);
+			printk(KERN_CONT "/%s\n", entry->procname);
+			return -EEXIST;
+		}
+	}
+
+	rb_link_node(node, parent, p);
+	return 0;
+}
+
+static void erase_entry(struct ctl_table_header *head, struct ctl_table *entry)
+{
+	struct rb_node *node = &head->node[entry - head->ctl_table].node;
+
+	rb_erase(node, &head->parent->root);
+}
+
+static void init_header(struct ctl_table_header *head,
+	struct ctl_table_root *root, struct ctl_table_set *set,
+	struct ctl_node *node, struct ctl_table *table)
+{
+	head->ctl_table = table;
+	head->ctl_table_arg = table;
+	head->used = 0;
+	head->count = 1;
+	head->nreg = 1;
+	head->unregistering = NULL;
+	head->root = root;
+	head->set = set;
+	head->parent = NULL;
+	head->node = node;
+	if (node) {
+		struct ctl_table *entry;
+		for (entry = table; entry->procname; entry++, node++) {
+			rb_init_node(&node->node);
+			node->header = head;
+		}
+	}
+}
+
+static void erase_header(struct ctl_table_header *head)
+{
+	struct ctl_table *entry;
+	for (entry = head->ctl_table; entry->procname; entry++)
+		erase_entry(head, entry);
+}
+
+static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
+{
+	struct ctl_table *entry;
+	int err;
+
+	dir->header.nreg++;
+	header->parent = dir;
+	err = insert_links(header);
+	if (err)
+		goto fail_links;
+	for (entry = header->ctl_table; entry->procname; entry++) {
+		err = insert_entry(header, entry);
+		if (err)
+			goto fail;
+	}
+	return 0;
+fail:
+	erase_header(header);
+	put_links(header);
+fail_links:
+	header->parent = NULL;
+	drop_sysctl_table(&dir->header);
+	return err;
+}
+
+/* called under sysctl_lock */
+static int use_table(struct ctl_table_header *p)
+{
+	if (unlikely(p->unregistering))
+		return 0;
+	p->used++;
+	return 1;
+}
+
+/* called under sysctl_lock */
+static void unuse_table(struct ctl_table_header *p)
+{
+	if (!--p->used)
+		if (unlikely(p->unregistering))
+			complete(p->unregistering);
+}
+
+/* called under sysctl_lock, will reacquire if has to wait */
+static void start_unregistering(struct ctl_table_header *p)
+{
+	/*
+	 * if p->used is 0, nobody will ever touch that entry again;
+	 * we'll eliminate all paths to it before dropping sysctl_lock
+	 */
+	if (unlikely(p->used)) {
+		struct completion wait;
+		init_completion(&wait);
+		p->unregistering = &wait;
+		spin_unlock(&sysctl_lock);
+		wait_for_completion(&wait);
+		spin_lock(&sysctl_lock);
+	} else {
+		/* anything non-NULL; we'll never dereference it */
+		p->unregistering = ERR_PTR(-EINVAL);
+	}
+	/*
+	 * do not remove from the list until nobody holds it; walking the
+	 * list in do_sysctl() relies on that.
+	 */
+	erase_header(p);
+}
+
+static void sysctl_head_get(struct ctl_table_header *head)
+{
+	spin_lock(&sysctl_lock);
+	head->count++;
+	spin_unlock(&sysctl_lock);
+}
+
+void sysctl_head_put(struct ctl_table_header *head)
+{
+	spin_lock(&sysctl_lock);
+	if (!--head->count)
+		kfree_rcu(head, rcu);
+	spin_unlock(&sysctl_lock);
+}
+
+static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
+{
+	if (!head)
+		BUG();
+	spin_lock(&sysctl_lock);
+	if (!use_table(head))
+		head = ERR_PTR(-ENOENT);
+	spin_unlock(&sysctl_lock);
+	return head;
+}
+
+static void sysctl_head_finish(struct ctl_table_header *head)
+{
+	if (!head)
+		return;
+	spin_lock(&sysctl_lock);
+	unuse_table(head);
+	spin_unlock(&sysctl_lock);
+}
+
+static struct ctl_table_set *
+lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
+{
+	struct ctl_table_set *set = &root->default_set;
+	if (root->lookup)
+		set = root->lookup(root, namespaces);
+	return set;
+}
+
+static struct ctl_table *lookup_entry(struct ctl_table_header **phead,
+				      struct ctl_dir *dir,
+				      const char *name, int namelen)
+{
+	struct ctl_table_header *head;
+	struct ctl_table *entry;
+
+	spin_lock(&sysctl_lock);
+	entry = find_entry(&head, dir, name, namelen);
+	if (entry && use_table(head))
+		*phead = head;
+	else
+		entry = NULL;
+	spin_unlock(&sysctl_lock);
+	return entry;
+}
+
+static struct ctl_node *first_usable_entry(struct rb_node *node)
+{
+	struct ctl_node *ctl_node;
+
+	for (;node; node = rb_next(node)) {
+		ctl_node = rb_entry(node, struct ctl_node, node);
+		if (use_table(ctl_node->header))
+			return ctl_node;
+	}
+	return NULL;
+}
+
+static void first_entry(struct ctl_dir *dir,
+	struct ctl_table_header **phead, struct ctl_table **pentry)
+{
+	struct ctl_table_header *head = NULL;
+	struct ctl_table *entry = NULL;
+	struct ctl_node *ctl_node;
+
+	spin_lock(&sysctl_lock);
+	ctl_node = first_usable_entry(rb_first(&dir->root));
+	spin_unlock(&sysctl_lock);
+	if (ctl_node) {
+		head = ctl_node->header;
+		entry = &head->ctl_table[ctl_node - head->node];
+	}
+	*phead = head;
+	*pentry = entry;
+}
+
+static void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry)
+{
+	struct ctl_table_header *head = *phead;
+	struct ctl_table *entry = *pentry;
+	struct ctl_node *ctl_node = &head->node[entry - head->ctl_table];
+
+	spin_lock(&sysctl_lock);
+	unuse_table(head);
+
+	ctl_node = first_usable_entry(rb_next(&ctl_node->node));
+	spin_unlock(&sysctl_lock);
+	head = NULL;
+	if (ctl_node) {
+		head = ctl_node->header;
+		entry = &head->ctl_table[ctl_node - head->node];
+	}
+	*phead = head;
+	*pentry = entry;
+}
+
+void register_sysctl_root(struct ctl_table_root *root)
+{
+}
+
+/*
+ * sysctl_perm does NOT grant the superuser all rights automatically, because
+ * some sysctl variables are readonly even to root.
+ */
+
+static int test_perm(int mode, int op)
+{
+	if (!current_euid())
+		mode >>= 6;
+	else if (in_egroup_p(0))
+		mode >>= 3;
+	if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
+		return 0;
+	return -EACCES;
+}
+
+static int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
+{
+	int mode;
+
+	if (root->permissions)
+		mode = root->permissions(root, current->nsproxy, table);
+	else
+		mode = table->mode;
+
+	return test_perm(mode, op);
+}
+
 static struct inode *proc_sys_make_inode(struct super_block *sb,
 		struct ctl_table_header *head, struct ctl_table *table)
 {
@@ -43,13 +411,12 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
 
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->i_mode = table->mode;
-	if (!table->child) {
+	if (!S_ISDIR(table->mode)) {
 		inode->i_mode |= S_IFREG;
 		inode->i_op = &proc_sys_inode_operations;
 		inode->i_fop = &proc_sys_file_operations;
 	} else {
 		inode->i_mode |= S_IFDIR;
-		clear_nlink(inode);
 		inode->i_op = &proc_sys_dir_operations;
 		inode->i_fop = &proc_sys_dir_file_operations;
 	}
@@ -57,70 +424,42 @@ out:
 	return inode;
 }
 
-static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name)
-{
-	int len;
-	for ( ; p->procname; p++) {
-
-		if (!p->procname)
-			continue;
-
-		len = strlen(p->procname);
-		if (len != name->len)
-			continue;
-
-		if (memcmp(p->procname, name->name, len) != 0)
-			continue;
-
-		/* I have a match */
-		return p;
-	}
-	return NULL;
-}
-
 static struct ctl_table_header *grab_header(struct inode *inode)
 {
-	if (PROC_I(inode)->sysctl)
-		return sysctl_head_grab(PROC_I(inode)->sysctl);
-	else
-		return sysctl_head_next(NULL);
+	struct ctl_table_header *head = PROC_I(inode)->sysctl;
+	if (!head)
+		head = &sysctl_table_root.default_set.dir.header;
+	return sysctl_head_grab(head);
 }
 
 static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
 					struct nameidata *nd)
 {
 	struct ctl_table_header *head = grab_header(dir);
-	struct ctl_table *table = PROC_I(dir)->sysctl_entry;
 	struct ctl_table_header *h = NULL;
 	struct qstr *name = &dentry->d_name;
 	struct ctl_table *p;
 	struct inode *inode;
 	struct dentry *err = ERR_PTR(-ENOENT);
+	struct ctl_dir *ctl_dir;
+	int ret;
 
 	if (IS_ERR(head))
 		return ERR_CAST(head);
 
-	if (table && !table->child) {
-		WARN_ON(1);
-		goto out;
-	}
-
-	table = table ? table->child : head->ctl_table;
-
-	p = find_in_table(table, name);
-	if (!p) {
-		for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) {
-			if (h->attached_to != table)
-				continue;
-			p = find_in_table(h->attached_by, name);
-			if (p)
-				break;
-		}
-	}
+	ctl_dir = container_of(head, struct ctl_dir, header);
 
+	p = lookup_entry(&h, ctl_dir, name->name, name->len);
 	if (!p)
 		goto out;
 
+	if (S_ISLNK(p->mode)) {
+		ret = sysctl_follow_link(&h, &p, current->nsproxy);
+		err = ERR_PTR(ret);
+		if (ret)
+			goto out;
+	}
+
 	err = ERR_PTR(-ENOMEM);
 	inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
 	if (h)
@@ -258,28 +597,45 @@ static int proc_sys_fill_cache(struct file *filp, void *dirent,
 	return !!filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type);
 }
 
+static int proc_sys_link_fill_cache(struct file *filp, void *dirent,
+				    filldir_t filldir,
+				    struct ctl_table_header *head,
+				    struct ctl_table *table)
+{
+	int err, ret = 0;
+	head = sysctl_head_grab(head);
+
+	if (S_ISLNK(table->mode)) {
+		/* It is not an error if we can not follow the link ignore it */
+		err = sysctl_follow_link(&head, &table, current->nsproxy);
+		if (err)
+			goto out;
+	}
+
+	ret = proc_sys_fill_cache(filp, dirent, filldir, head, table);
+out:
+	sysctl_head_finish(head);
+	return ret;
+}
+
 static int scan(struct ctl_table_header *head, ctl_table *table,
 		unsigned long *pos, struct file *file,
 		void *dirent, filldir_t filldir)
 {
+	int res;
 
-	for (; table->procname; table++, (*pos)++) {
-		int res;
-
-		/* Can't do anything without a proc name */
-		if (!table->procname)
-			continue;
-
-		if (*pos < file->f_pos)
-			continue;
+	if ((*pos)++ < file->f_pos)
+		return 0;
 
+	if (unlikely(S_ISLNK(table->mode)))
+		res = proc_sys_link_fill_cache(file, dirent, filldir, head, table);
+	else
 		res = proc_sys_fill_cache(file, dirent, filldir, head, table);
-		if (res)
-			return res;
 
-		file->f_pos = *pos + 1;
-	}
-	return 0;
+	if (res == 0)
+		file->f_pos = *pos;
+
+	return res;
 }
 
 static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir)
@@ -287,20 +643,16 @@ static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir)
 	struct dentry *dentry = filp->f_path.dentry;
 	struct inode *inode = dentry->d_inode;
 	struct ctl_table_header *head = grab_header(inode);
-	struct ctl_table *table = PROC_I(inode)->sysctl_entry;
 	struct ctl_table_header *h = NULL;
+	struct ctl_table *entry;
+	struct ctl_dir *ctl_dir;
 	unsigned long pos;
 	int ret = -EINVAL;
 
 	if (IS_ERR(head))
 		return PTR_ERR(head);
 
-	if (table && !table->child) {
-		WARN_ON(1);
-		goto out;
-	}
-
-	table = table ? table->child : head->ctl_table;
+	ctl_dir = container_of(head, struct ctl_dir, header);
 
 	ret = 0;
 	/* Avoid a switch here: arm builds fail with missing __cmpdi2 */
@@ -318,14 +670,8 @@ static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir)
 	}
 	pos = 2;
 
-	ret = scan(head, table, &pos, filp, dirent, filldir);
-	if (ret)
-		goto out;
-
-	for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) {
-		if (h->attached_to != table)
-			continue;
-		ret = scan(h, h->attached_by, &pos, filp, dirent, filldir);
+	for (first_entry(ctl_dir, &h, &entry); h; next_entry(&h, &entry)) {
+		ret = scan(h, entry, &pos, filp, dirent, filldir);
 		if (ret) {
 			sysctl_head_finish(h);
 			break;
@@ -445,6 +791,21 @@ static int proc_sys_delete(const struct dentry *dentry)
 	return !!PROC_I(dentry->d_inode)->sysctl->unregistering;
 }
 
+static int sysctl_is_seen(struct ctl_table_header *p)
+{
+	struct ctl_table_set *set = p->set;
+	int res;
+	spin_lock(&sysctl_lock);
+	if (p->unregistering)
+		res = 0;
+	else if (!set->is_seen)
+		res = 1;
+	else
+		res = set->is_seen(set);
+	spin_unlock(&sysctl_lock);
+	return res;
+}
+
 static int proc_sys_compare(const struct dentry *parent,
 		const struct inode *pinode,
 		const struct dentry *dentry, const struct inode *inode,
@@ -470,6 +831,753 @@ static const struct dentry_operations proc_sys_dentry_operations = {
 	.d_compare	= proc_sys_compare,
 };
 
+static struct ctl_dir *find_subdir(struct ctl_dir *dir,
+				   const char *name, int namelen)
+{
+	struct ctl_table_header *head;
+	struct ctl_table *entry;
+
+	entry = find_entry(&head, dir, name, namelen);
+	if (!entry)
+		return ERR_PTR(-ENOENT);
+	if (!S_ISDIR(entry->mode))
+		return ERR_PTR(-ENOTDIR);
+	return container_of(head, struct ctl_dir, header);
+}
+
+static struct ctl_dir *new_dir(struct ctl_table_set *set,
+			       const char *name, int namelen)
+{
+	struct ctl_table *table;
+	struct ctl_dir *new;
+	struct ctl_node *node;
+	char *new_name;
+
+	new = kzalloc(sizeof(*new) + sizeof(struct ctl_node) +
+		      sizeof(struct ctl_table)*2 +  namelen + 1,
+		      GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	node = (struct ctl_node *)(new + 1);
+	table = (struct ctl_table *)(node + 1);
+	new_name = (char *)(table + 2);
+	memcpy(new_name, name, namelen);
+	new_name[namelen] = '\0';
+	table[0].procname = new_name;
+	table[0].mode = S_IFDIR|S_IRUGO|S_IXUGO;
+	init_header(&new->header, set->dir.header.root, set, node, table);
+
+	return new;
+}
+
+/**
+ * get_subdir - find or create a subdir with the specified name.
+ * @dir:  Directory to create the subdirectory in
+ * @name: The name of the subdirectory to find or create
+ * @namelen: The length of name
+ *
+ * Takes a directory with an elevated reference count so we know that
+ * if we drop the lock the directory will not go away.  Upon success
+ * the reference is moved from @dir to the returned subdirectory.
+ * Upon error an error code is returned and the reference on @dir is
+ * simply dropped.
+ */
+static struct ctl_dir *get_subdir(struct ctl_dir *dir,
+				  const char *name, int namelen)
+{
+	struct ctl_table_set *set = dir->header.set;
+	struct ctl_dir *subdir, *new = NULL;
+	int err;
+
+	spin_lock(&sysctl_lock);
+	subdir = find_subdir(dir, name, namelen);
+	if (!IS_ERR(subdir))
+		goto found;
+	if (PTR_ERR(subdir) != -ENOENT)
+		goto failed;
+
+	spin_unlock(&sysctl_lock);
+	new = new_dir(set, name, namelen);
+	spin_lock(&sysctl_lock);
+	subdir = ERR_PTR(-ENOMEM);
+	if (!new)
+		goto failed;
+
+	/* Was the subdir added while we dropped the lock? */
+	subdir = find_subdir(dir, name, namelen);
+	if (!IS_ERR(subdir))
+		goto found;
+	if (PTR_ERR(subdir) != -ENOENT)
+		goto failed;
+
+	/* Nope.  Use the our freshly made directory entry. */
+	err = insert_header(dir, &new->header);
+	subdir = ERR_PTR(err);
+	if (err)
+		goto failed;
+	subdir = new;
+found:
+	subdir->header.nreg++;
+failed:
+	if (unlikely(IS_ERR(subdir))) {
+		printk(KERN_ERR "sysctl could not get directory: ");
+		sysctl_print_dir(dir);
+		printk(KERN_CONT "/%*.*s %ld\n",
+			namelen, namelen, name, PTR_ERR(subdir));
+	}
+	drop_sysctl_table(&dir->header);
+	if (new)
+		drop_sysctl_table(&new->header);
+	spin_unlock(&sysctl_lock);
+	return subdir;
+}
+
+static struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir)
+{
+	struct ctl_dir *parent;
+	const char *procname;
+	if (!dir->header.parent)
+		return &set->dir;
+	parent = xlate_dir(set, dir->header.parent);
+	if (IS_ERR(parent))
+		return parent;
+	procname = dir->header.ctl_table[0].procname;
+	return find_subdir(parent, procname, strlen(procname));
+}
+
+static int sysctl_follow_link(struct ctl_table_header **phead,
+	struct ctl_table **pentry, struct nsproxy *namespaces)
+{
+	struct ctl_table_header *head;
+	struct ctl_table_root *root;
+	struct ctl_table_set *set;
+	struct ctl_table *entry;
+	struct ctl_dir *dir;
+	int ret;
+
+	ret = 0;
+	spin_lock(&sysctl_lock);
+	root = (*pentry)->data;
+	set = lookup_header_set(root, namespaces);
+	dir = xlate_dir(set, (*phead)->parent);
+	if (IS_ERR(dir))
+		ret = PTR_ERR(dir);
+	else {
+		const char *procname = (*pentry)->procname;
+		head = NULL;
+		entry = find_entry(&head, dir, procname, strlen(procname));
+		ret = -ENOENT;
+		if (entry && use_table(head)) {
+			unuse_table(*phead);
+			*phead = head;
+			*pentry = entry;
+			ret = 0;
+		}
+	}
+
+	spin_unlock(&sysctl_lock);
+	return ret;
+}
+
+static int sysctl_err(const char *path, struct ctl_table *table, char *fmt, ...)
+{
+	struct va_format vaf;
+	va_list args;
+
+	va_start(args, fmt);
+	vaf.fmt = fmt;
+	vaf.va = &args;
+
+	printk(KERN_ERR "sysctl table check failed: %s/%s %pV\n",
+		path, table->procname, &vaf);
+
+	va_end(args);
+	return -EINVAL;
+}
+
+static int sysctl_check_table(const char *path, struct ctl_table *table)
+{
+	int err = 0;
+	for (; table->procname; table++) {
+		if (table->child)
+			err = sysctl_err(path, table, "Not a file");
+
+		if ((table->proc_handler == proc_dostring) ||
+		    (table->proc_handler == proc_dointvec) ||
+		    (table->proc_handler == proc_dointvec_minmax) ||
+		    (table->proc_handler == proc_dointvec_jiffies) ||
+		    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
+		    (table->proc_handler == proc_dointvec_ms_jiffies) ||
+		    (table->proc_handler == proc_doulongvec_minmax) ||
+		    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
+			if (!table->data)
+				err = sysctl_err(path, table, "No data");
+			if (!table->maxlen)
+				err = sysctl_err(path, table, "No maxlen");
+		}
+		if (!table->proc_handler)
+			err = sysctl_err(path, table, "No proc_handler");
+
+		if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode)
+			err = sysctl_err(path, table, "bogus .mode 0%o",
+				table->mode);
+	}
+	return err;
+}
+
+static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table *table,
+	struct ctl_table_root *link_root)
+{
+	struct ctl_table *link_table, *entry, *link;
+	struct ctl_table_header *links;
+	struct ctl_node *node;
+	char *link_name;
+	int nr_entries, name_bytes;
+
+	name_bytes = 0;
+	nr_entries = 0;
+	for (entry = table; entry->procname; entry++) {
+		nr_entries++;
+		name_bytes += strlen(entry->procname) + 1;
+	}
+
+	links = kzalloc(sizeof(struct ctl_table_header) +
+			sizeof(struct ctl_node)*nr_entries +
+			sizeof(struct ctl_table)*(nr_entries + 1) +
+			name_bytes,
+			GFP_KERNEL);
+
+	if (!links)
+		return NULL;
+
+	node = (struct ctl_node *)(links + 1);
+	link_table = (struct ctl_table *)(node + nr_entries);
+	link_name = (char *)&link_table[nr_entries + 1];
+
+	for (link = link_table, entry = table; entry->procname; link++, entry++) {
+		int len = strlen(entry->procname) + 1;
+		memcpy(link_name, entry->procname, len);
+		link->procname = link_name;
+		link->mode = S_IFLNK|S_IRWXUGO;
+		link->data = link_root;
+		link_name += len;
+	}
+	init_header(links, dir->header.root, dir->header.set, node, link_table);
+	links->nreg = nr_entries;
+
+	return links;
+}
+
+static bool get_links(struct ctl_dir *dir,
+	struct ctl_table *table, struct ctl_table_root *link_root)
+{
+	struct ctl_table_header *head;
+	struct ctl_table *entry, *link;
+
+	/* Are there links available for every entry in table? */
+	for (entry = table; entry->procname; entry++) {
+		const char *procname = entry->procname;
+		link = find_entry(&head, dir, procname, strlen(procname));
+		if (!link)
+			return false;
+		if (S_ISDIR(link->mode) && S_ISDIR(entry->mode))
+			continue;
+		if (S_ISLNK(link->mode) && (link->data == link_root))
+			continue;
+		return false;
+	}
+
+	/* The checks passed.  Increase the registration count on the links */
+	for (entry = table; entry->procname; entry++) {
+		const char *procname = entry->procname;
+		link = find_entry(&head, dir, procname, strlen(procname));
+		head->nreg++;
+	}
+	return true;
+}
+
+static int insert_links(struct ctl_table_header *head)
+{
+	struct ctl_table_set *root_set = &sysctl_table_root.default_set;
+	struct ctl_dir *core_parent = NULL;
+	struct ctl_table_header *links;
+	int err;
+
+	if (head->set == root_set)
+		return 0;
+
+	core_parent = xlate_dir(root_set, head->parent);
+	if (IS_ERR(core_parent))
+		return 0;
+
+	if (get_links(core_parent, head->ctl_table, head->root))
+		return 0;
+
+	core_parent->header.nreg++;
+	spin_unlock(&sysctl_lock);
+
+	links = new_links(core_parent, head->ctl_table, head->root);
+
+	spin_lock(&sysctl_lock);
+	err = -ENOMEM;
+	if (!links)
+		goto out;
+
+	err = 0;
+	if (get_links(core_parent, head->ctl_table, head->root)) {
+		kfree(links);
+		goto out;
+	}
+
+	err = insert_header(core_parent, links);
+	if (err)
+		kfree(links);
+out:
+	drop_sysctl_table(&core_parent->header);
+	return err;
+}
+
+/**
+ * __register_sysctl_table - register a leaf sysctl table
+ * @set: Sysctl tree to register on
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * The members of the &struct ctl_table structure are used as follows:
+ *
+ * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
+ *            enter a sysctl file
+ *
+ * data - a pointer to data for use by proc_handler
+ *
+ * maxlen - the maximum size in bytes of the data
+ *
+ * mode - the file permissions for the /proc/sys file
+ *
+ * child - must be %NULL.
+ *
+ * proc_handler - the text handler routine (described below)
+ *
+ * extra1, extra2 - extra pointers usable by the proc handler routines
+ *
+ * Leaf nodes in the sysctl tree will be represented by a single file
+ * under /proc; non-leaf nodes will be represented by directories.
+ *
+ * There must be a proc_handler routine for any terminal nodes.
+ * Several default handlers are available to cover common cases -
+ *
+ * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
+ * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(),
+ * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
+ *
+ * It is the handler's job to read the input buffer from user memory
+ * and process it. The handler should return 0 on success.
+ *
+ * This routine returns %NULL on a failure to register, and a pointer
+ * to the table header on success.
+ */
+struct ctl_table_header *__register_sysctl_table(
+	struct ctl_table_set *set,
+	const char *path, struct ctl_table *table)
+{
+	struct ctl_table_root *root = set->dir.header.root;
+	struct ctl_table_header *header;
+	const char *name, *nextname;
+	struct ctl_dir *dir;
+	struct ctl_table *entry;
+	struct ctl_node *node;
+	int nr_entries = 0;
+
+	for (entry = table; entry->procname; entry++)
+		nr_entries++;
+
+	header = kzalloc(sizeof(struct ctl_table_header) +
+			 sizeof(struct ctl_node)*nr_entries, GFP_KERNEL);
+	if (!header)
+		return NULL;
+
+	node = (struct ctl_node *)(header + 1);
+	init_header(header, root, set, node, table);
+	if (sysctl_check_table(path, table))
+		goto fail;
+
+	spin_lock(&sysctl_lock);
+	dir = &set->dir;
+	/* Reference moved down the diretory tree get_subdir */
+	dir->header.nreg++;
+	spin_unlock(&sysctl_lock);
+
+	/* Find the directory for the ctl_table */
+	for (name = path; name; name = nextname) {
+		int namelen;
+		nextname = strchr(name, '/');
+		if (nextname) {
+			namelen = nextname - name;
+			nextname++;
+		} else {
+			namelen = strlen(name);
+		}
+		if (namelen == 0)
+			continue;
+
+		dir = get_subdir(dir, name, namelen);
+		if (IS_ERR(dir))
+			goto fail;
+	}
+
+	spin_lock(&sysctl_lock);
+	if (insert_header(dir, header))
+		goto fail_put_dir_locked;
+
+	drop_sysctl_table(&dir->header);
+	spin_unlock(&sysctl_lock);
+
+	return header;
+
+fail_put_dir_locked:
+	drop_sysctl_table(&dir->header);
+	spin_unlock(&sysctl_lock);
+fail:
+	kfree(header);
+	dump_stack();
+	return NULL;
+}
+
+/**
+ * register_sysctl - register a sysctl table
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the table structure
+ *
+ * Register a sysctl table. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See __register_sysctl_table for more details.
+ */
+struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table)
+{
+	return __register_sysctl_table(&sysctl_table_root.default_set,
+					path, table);
+}
+EXPORT_SYMBOL(register_sysctl);
+
+static char *append_path(const char *path, char *pos, const char *name)
+{
+	int namelen;
+	namelen = strlen(name);
+	if (((pos - path) + namelen + 2) >= PATH_MAX)
+		return NULL;
+	memcpy(pos, name, namelen);
+	pos[namelen] = '/';
+	pos[namelen + 1] = '\0';
+	pos += namelen + 1;
+	return pos;
+}
+
+static int count_subheaders(struct ctl_table *table)
+{
+	int has_files = 0;
+	int nr_subheaders = 0;
+	struct ctl_table *entry;
+
+	/* special case: no directory and empty directory */
+	if (!table || !table->procname)
+		return 1;
+
+	for (entry = table; entry->procname; entry++) {
+		if (entry->child)
+			nr_subheaders += count_subheaders(entry->child);
+		else
+			has_files = 1;
+	}
+	return nr_subheaders + has_files;
+}
+
+static int register_leaf_sysctl_tables(const char *path, char *pos,
+	struct ctl_table_header ***subheader, struct ctl_table_set *set,
+	struct ctl_table *table)
+{
+	struct ctl_table *ctl_table_arg = NULL;
+	struct ctl_table *entry, *files;
+	int nr_files = 0;
+	int nr_dirs = 0;
+	int err = -ENOMEM;
+
+	for (entry = table; entry->procname; entry++) {
+		if (entry->child)
+			nr_dirs++;
+		else
+			nr_files++;
+	}
+
+	files = table;
+	/* If there are mixed files and directories we need a new table */
+	if (nr_dirs && nr_files) {
+		struct ctl_table *new;
+		files = kzalloc(sizeof(struct ctl_table) * (nr_files + 1),
+				GFP_KERNEL);
+		if (!files)
+			goto out;
+
+		ctl_table_arg = files;
+		for (new = files, entry = table; entry->procname; entry++) {
+			if (entry->child)
+				continue;
+			*new = *entry;
+			new++;
+		}
+	}
+
+	/* Register everything except a directory full of subdirectories */
+	if (nr_files || !nr_dirs) {
+		struct ctl_table_header *header;
+		header = __register_sysctl_table(set, path, files);
+		if (!header) {
+			kfree(ctl_table_arg);
+			goto out;
+		}
+
+		/* Remember if we need to free the file table */
+		header->ctl_table_arg = ctl_table_arg;
+		**subheader = header;
+		(*subheader)++;
+	}
+
+	/* Recurse into the subdirectories. */
+	for (entry = table; entry->procname; entry++) {
+		char *child_pos;
+
+		if (!entry->child)
+			continue;
+
+		err = -ENAMETOOLONG;
+		child_pos = append_path(path, pos, entry->procname);
+		if (!child_pos)
+			goto out;
+
+		err = register_leaf_sysctl_tables(path, child_pos, subheader,
+						  set, entry->child);
+		pos[0] = '\0';
+		if (err)
+			goto out;
+	}
+	err = 0;
+out:
+	/* On failure our caller will unregister all registered subheaders */
+	return err;
+}
+
+/**
+ * __register_sysctl_paths - register a sysctl table hierarchy
+ * @set: Sysctl tree to register on
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See __register_sysctl_table for more details.
+ */
+struct ctl_table_header *__register_sysctl_paths(
+	struct ctl_table_set *set,
+	const struct ctl_path *path, struct ctl_table *table)
+{
+	struct ctl_table *ctl_table_arg = table;
+	int nr_subheaders = count_subheaders(table);
+	struct ctl_table_header *header = NULL, **subheaders, **subheader;
+	const struct ctl_path *component;
+	char *new_path, *pos;
+
+	pos = new_path = kmalloc(PATH_MAX, GFP_KERNEL);
+	if (!new_path)
+		return NULL;
+
+	pos[0] = '\0';
+	for (component = path; component->procname; component++) {
+		pos = append_path(new_path, pos, component->procname);
+		if (!pos)
+			goto out;
+	}
+	while (table->procname && table->child && !table[1].procname) {
+		pos = append_path(new_path, pos, table->procname);
+		if (!pos)
+			goto out;
+		table = table->child;
+	}
+	if (nr_subheaders == 1) {
+		header = __register_sysctl_table(set, new_path, table);
+		if (header)
+			header->ctl_table_arg = ctl_table_arg;
+	} else {
+		header = kzalloc(sizeof(*header) +
+				 sizeof(*subheaders)*nr_subheaders, GFP_KERNEL);
+		if (!header)
+			goto out;
+
+		subheaders = (struct ctl_table_header **) (header + 1);
+		subheader = subheaders;
+		header->ctl_table_arg = ctl_table_arg;
+
+		if (register_leaf_sysctl_tables(new_path, pos, &subheader,
+						set, table))
+			goto err_register_leaves;
+	}
+
+out:
+	kfree(new_path);
+	return header;
+
+err_register_leaves:
+	while (subheader > subheaders) {
+		struct ctl_table_header *subh = *(--subheader);
+		struct ctl_table *table = subh->ctl_table_arg;
+		unregister_sysctl_table(subh);
+		kfree(table);
+	}
+	kfree(header);
+	header = NULL;
+	goto out;
+}
+
+/**
+ * register_sysctl_table_path - register a sysctl table hierarchy
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See __register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+						struct ctl_table *table)
+{
+	return __register_sysctl_paths(&sysctl_table_root.default_set,
+					path, table);
+}
+EXPORT_SYMBOL(register_sysctl_paths);
+
+/**
+ * register_sysctl_table - register a sysctl table hierarchy
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
+{
+	static const struct ctl_path null_path[] = { {} };
+
+	return register_sysctl_paths(null_path, table);
+}
+EXPORT_SYMBOL(register_sysctl_table);
+
+static void put_links(struct ctl_table_header *header)
+{
+	struct ctl_table_set *root_set = &sysctl_table_root.default_set;
+	struct ctl_table_root *root = header->root;
+	struct ctl_dir *parent = header->parent;
+	struct ctl_dir *core_parent;
+	struct ctl_table *entry;
+
+	if (header->set == root_set)
+		return;
+
+	core_parent = xlate_dir(root_set, parent);
+	if (IS_ERR(core_parent))
+		return;
+
+	for (entry = header->ctl_table; entry->procname; entry++) {
+		struct ctl_table_header *link_head;
+		struct ctl_table *link;
+		const char *name = entry->procname;
+
+		link = find_entry(&link_head, core_parent, name, strlen(name));
+		if (link &&
+		    ((S_ISDIR(link->mode) && S_ISDIR(entry->mode)) ||
+		     (S_ISLNK(link->mode) && (link->data == root)))) {
+			drop_sysctl_table(link_head);
+		}
+		else {
+			printk(KERN_ERR "sysctl link missing during unregister: ");
+			sysctl_print_dir(parent);
+			printk(KERN_CONT "/%s\n", name);
+		}
+	}
+}
+
+static void drop_sysctl_table(struct ctl_table_header *header)
+{
+	struct ctl_dir *parent = header->parent;
+
+	if (--header->nreg)
+		return;
+
+	put_links(header);
+	start_unregistering(header);
+	if (!--header->count)
+		kfree_rcu(header, rcu);
+
+	if (parent)
+		drop_sysctl_table(&parent->header);
+}
+
+/**
+ * unregister_sysctl_table - unregister a sysctl table hierarchy
+ * @header: the header returned from register_sysctl_table
+ *
+ * Unregisters the sysctl table and all children. proc entries may not
+ * actually be removed until they are no longer used by anyone.
+ */
+void unregister_sysctl_table(struct ctl_table_header * header)
+{
+	int nr_subheaders;
+	might_sleep();
+
+	if (header == NULL)
+		return;
+
+	nr_subheaders = count_subheaders(header->ctl_table_arg);
+	if (unlikely(nr_subheaders > 1)) {
+		struct ctl_table_header **subheaders;
+		int i;
+
+		subheaders = (struct ctl_table_header **)(header + 1);
+		for (i = nr_subheaders -1; i >= 0; i--) {
+			struct ctl_table_header *subh = subheaders[i];
+			struct ctl_table *table = subh->ctl_table_arg;
+			unregister_sysctl_table(subh);
+			kfree(table);
+		}
+		kfree(header);
+		return;
+	}
+
+	spin_lock(&sysctl_lock);
+	drop_sysctl_table(header);
+	spin_unlock(&sysctl_lock);
+}
+EXPORT_SYMBOL(unregister_sysctl_table);
+
+void setup_sysctl_set(struct ctl_table_set *set,
+	struct ctl_table_root *root,
+	int (*is_seen)(struct ctl_table_set *))
+{
+	memset(set, 0, sizeof(*set));
+	set->is_seen = is_seen;
+	init_header(&set->dir.header, root, set, NULL, root_table);
+}
+
+void retire_sysctl_set(struct ctl_table_set *set)
+{
+	WARN_ON(!RB_EMPTY_ROOT(&set->dir.root));
+}
+
 int __init proc_sys_init(void)
 {
 	struct proc_dir_entry *proc_sys_root;
@@ -478,5 +1586,6 @@ int __init proc_sys_init(void)
 	proc_sys_root->proc_iops = &proc_sys_dir_operations;
 	proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
 	proc_sys_root->nlink = 0;
-	return 0;
+
+	return sysctl_init();
 }
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 121f77c..6a0c62d 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -89,18 +89,19 @@ static int show_stat(struct seq_file *p, void *v)
 	}
 	sum += arch_irq_stat();
 
-	seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu "
-		"%llu\n",
-		(unsigned long long)cputime64_to_clock_t(user),
-		(unsigned long long)cputime64_to_clock_t(nice),
-		(unsigned long long)cputime64_to_clock_t(system),
-		(unsigned long long)cputime64_to_clock_t(idle),
-		(unsigned long long)cputime64_to_clock_t(iowait),
-		(unsigned long long)cputime64_to_clock_t(irq),
-		(unsigned long long)cputime64_to_clock_t(softirq),
-		(unsigned long long)cputime64_to_clock_t(steal),
-		(unsigned long long)cputime64_to_clock_t(guest),
-		(unsigned long long)cputime64_to_clock_t(guest_nice));
+	seq_puts(p, "cpu ");
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+	seq_putc(p, '\n');
+
 	for_each_online_cpu(i) {
 		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
 		user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
@@ -113,26 +114,24 @@ static int show_stat(struct seq_file *p, void *v)
 		steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
 		guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
 		guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
-		seq_printf(p,
-			"cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu "
-			"%llu\n",
-			i,
-			(unsigned long long)cputime64_to_clock_t(user),
-			(unsigned long long)cputime64_to_clock_t(nice),
-			(unsigned long long)cputime64_to_clock_t(system),
-			(unsigned long long)cputime64_to_clock_t(idle),
-			(unsigned long long)cputime64_to_clock_t(iowait),
-			(unsigned long long)cputime64_to_clock_t(irq),
-			(unsigned long long)cputime64_to_clock_t(softirq),
-			(unsigned long long)cputime64_to_clock_t(steal),
-			(unsigned long long)cputime64_to_clock_t(guest),
-			(unsigned long long)cputime64_to_clock_t(guest_nice));
+		seq_printf(p, "cpu%d", i);
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+		seq_putc(p, '\n');
 	}
 	seq_printf(p, "intr %llu", (unsigned long long)sum);
 
 	/* sum again ? it could be updated? */
 	for_each_irq_nr(j)
-		seq_printf(p, " %u", kstat_irqs(j));
+		seq_put_decimal_ull(p, ' ', kstat_irqs(j));
 
 	seq_printf(p,
 		"\nctxt %llu\n"
@@ -149,7 +148,7 @@ static int show_stat(struct seq_file *p, void *v)
 	seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq);
 
 	for (i = 0; i < NR_SOFTIRQS; i++)
-		seq_printf(p, " %u", per_softirq_sums[i]);
+		seq_put_decimal_ull(p, ' ', per_softirq_sums[i]);
 	seq_putc(p, '\n');
 
 	return 0;
@@ -157,11 +156,14 @@ static int show_stat(struct seq_file *p, void *v)
 
 static int stat_open(struct inode *inode, struct file *file)
 {
-	unsigned size = 4096 * (1 + num_possible_cpus() / 32);
+	unsigned size = 1024 + 128 * num_possible_cpus();
 	char *buf;
 	struct seq_file *m;
 	int res;
 
+	/* minimum size to display an interrupt count : 2 bytes */
+	size += 2 * nr_irqs;
+
 	/* don't ask for more than the kmalloc() max size */
 	if (size > KMALLOC_MAX_SIZE)
 		size = KMALLOC_MAX_SIZE;
@@ -173,7 +175,7 @@ static int stat_open(struct inode *inode, struct file *file)
 	if (!res) {
 		m = file->private_data;
 		m->buf = buf;
-		m->size = size;
+		m->size = ksize(buf);
 	} else
 		kfree(buf);
 	return res;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7dcd2a2..94efa558 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -394,20 +394,11 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 	pte_t *pte;
 	spinlock_t *ptl;
 
-	spin_lock(&walk->mm->page_table_lock);
-	if (pmd_trans_huge(*pmd)) {
-		if (pmd_trans_splitting(*pmd)) {
-			spin_unlock(&walk->mm->page_table_lock);
-			wait_split_huge_page(vma->anon_vma, pmd);
-		} else {
-			smaps_pte_entry(*(pte_t *)pmd, addr,
-					HPAGE_PMD_SIZE, walk);
-			spin_unlock(&walk->mm->page_table_lock);
-			mss->anonymous_thp += HPAGE_PMD_SIZE;
-			return 0;
-		}
-	} else {
+	if (pmd_trans_huge_lock(pmd, vma)) {
+		smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk);
 		spin_unlock(&walk->mm->page_table_lock);
+		mss->anonymous_thp += HPAGE_PMD_SIZE;
+		return 0;
 	}
 	/*
 	 * The mmap_sem held all the way back in m_start() is what
@@ -598,11 +589,18 @@ const struct file_operations proc_clear_refs_operations = {
 	.llseek		= noop_llseek,
 };
 
+typedef struct {
+	u64 pme;
+} pagemap_entry_t;
+
 struct pagemapread {
 	int pos, len;
-	u64 *buffer;
+	pagemap_entry_t *buffer;
 };
 
+#define PAGEMAP_WALK_SIZE	(PMD_SIZE)
+#define PAGEMAP_WALK_MASK	(PMD_MASK)
+
 #define PM_ENTRY_BYTES      sizeof(u64)
 #define PM_STATUS_BITS      3
 #define PM_STATUS_OFFSET    (64 - PM_STATUS_BITS)
@@ -620,10 +618,15 @@ struct pagemapread {
 #define PM_NOT_PRESENT      PM_PSHIFT(PAGE_SHIFT)
 #define PM_END_OF_BUFFER    1
 
-static int add_to_pagemap(unsigned long addr, u64 pfn,
+static inline pagemap_entry_t make_pme(u64 val)
+{
+	return (pagemap_entry_t) { .pme = val };
+}
+
+static int add_to_pagemap(unsigned long addr, pagemap_entry_t *pme,
 			  struct pagemapread *pm)
 {
-	pm->buffer[pm->pos++] = pfn;
+	pm->buffer[pm->pos++] = *pme;
 	if (pm->pos >= pm->len)
 		return PM_END_OF_BUFFER;
 	return 0;
@@ -635,8 +638,10 @@ static int pagemap_pte_hole(unsigned long start, unsigned long end,
 	struct pagemapread *pm = walk->private;
 	unsigned long addr;
 	int err = 0;
+	pagemap_entry_t pme = make_pme(PM_NOT_PRESENT);
+
 	for (addr = start; addr < end; addr += PAGE_SIZE) {
-		err = add_to_pagemap(addr, PM_NOT_PRESENT, pm);
+		err = add_to_pagemap(addr, &pme, pm);
 		if (err)
 			break;
 	}
@@ -649,18 +654,36 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte)
 	return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
 }
 
-static u64 pte_to_pagemap_entry(pte_t pte)
+static void pte_to_pagemap_entry(pagemap_entry_t *pme, pte_t pte)
 {
-	u64 pme = 0;
 	if (is_swap_pte(pte))
-		pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte))
-			| PM_PSHIFT(PAGE_SHIFT) | PM_SWAP;
+		*pme = make_pme(PM_PFRAME(swap_pte_to_pagemap_entry(pte))
+				| PM_PSHIFT(PAGE_SHIFT) | PM_SWAP);
 	else if (pte_present(pte))
-		pme = PM_PFRAME(pte_pfn(pte))
-			| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
-	return pme;
+		*pme = make_pme(PM_PFRAME(pte_pfn(pte))
+				| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme,
+					pmd_t pmd, int offset)
+{
+	/*
+	 * Currently pmd for thp is always present because thp can not be
+	 * swapped-out, migrated, or HWPOISONed (split in such cases instead.)
+	 * This if-check is just to prepare for future implementation.
+	 */
+	if (pmd_present(pmd))
+		*pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset)
+				| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
+}
+#else
+static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme,
+						pmd_t pmd, int offset)
+{
+}
+#endif
+
 static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 			     struct mm_walk *walk)
 {
@@ -668,14 +691,25 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 	struct pagemapread *pm = walk->private;
 	pte_t *pte;
 	int err = 0;
-
-	split_huge_page_pmd(walk->mm, pmd);
+	pagemap_entry_t pme = make_pme(PM_NOT_PRESENT);
 
 	/* find the first VMA at or above 'addr' */
 	vma = find_vma(walk->mm, addr);
-	for (; addr != end; addr += PAGE_SIZE) {
-		u64 pfn = PM_NOT_PRESENT;
 
+	if (pmd_trans_huge_lock(pmd, vma)) {
+		for (; addr != end; addr += PAGE_SIZE) {
+			unsigned long offset = (addr & ~PAGEMAP_WALK_MASK)
+				>> PAGE_SHIFT;
+			thp_pmd_to_pagemap_entry(&pme, *pmd, offset);
+			err = add_to_pagemap(addr, &pme, pm);
+			if (err)
+				break;
+		}
+		spin_unlock(&walk->mm->page_table_lock);
+		return err;
+	}
+
+	for (; addr != end; addr += PAGE_SIZE) {
 		/* check to see if we've left 'vma' behind
 		 * and need a new, higher one */
 		if (vma && (addr >= vma->vm_end))
@@ -686,11 +720,11 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 		if (vma && (vma->vm_start <= addr) &&
 		    !is_vm_hugetlb_page(vma)) {
 			pte = pte_offset_map(pmd, addr);
-			pfn = pte_to_pagemap_entry(*pte);
+			pte_to_pagemap_entry(&pme, *pte);
 			/* unmap before userspace copy */
 			pte_unmap(pte);
 		}
-		err = add_to_pagemap(addr, pfn, pm);
+		err = add_to_pagemap(addr, &pme, pm);
 		if (err)
 			return err;
 	}
@@ -701,13 +735,12 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
 }
 
 #ifdef CONFIG_HUGETLB_PAGE
-static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset)
+static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme,
+					pte_t pte, int offset)
 {
-	u64 pme = 0;
 	if (pte_present(pte))
-		pme = PM_PFRAME(pte_pfn(pte) + offset)
-			| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
-	return pme;
+		*pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset)
+				| PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT);
 }
 
 /* This function walks within one hugetlb entry in the single call */
@@ -717,12 +750,12 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
 {
 	struct pagemapread *pm = walk->private;
 	int err = 0;
-	u64 pfn;
+	pagemap_entry_t pme = make_pme(PM_NOT_PRESENT);
 
 	for (; addr != end; addr += PAGE_SIZE) {
 		int offset = (addr & ~hmask) >> PAGE_SHIFT;
-		pfn = huge_pte_to_pagemap_entry(*pte, offset);
-		err = add_to_pagemap(addr, pfn, pm);
+		huge_pte_to_pagemap_entry(&pme, *pte, offset);
+		err = add_to_pagemap(addr, &pme, pm);
 		if (err)
 			return err;
 	}
@@ -757,8 +790,6 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
  * determine which areas of memory are actually mapped and llseek to
  * skip over unmapped regions.
  */
-#define PAGEMAP_WALK_SIZE	(PMD_SIZE)
-#define PAGEMAP_WALK_MASK	(PMD_MASK)
 static ssize_t pagemap_read(struct file *file, char __user *buf,
 			    size_t count, loff_t *ppos)
 {
@@ -941,24 +972,17 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
 	pte_t *pte;
 
 	md = walk->private;
-	spin_lock(&walk->mm->page_table_lock);
-	if (pmd_trans_huge(*pmd)) {
-		if (pmd_trans_splitting(*pmd)) {
-			spin_unlock(&walk->mm->page_table_lock);
-			wait_split_huge_page(md->vma->anon_vma, pmd);
-		} else {
-			pte_t huge_pte = *(pte_t *)pmd;
-			struct page *page;
-
-			page = can_gather_numa_stats(huge_pte, md->vma, addr);
-			if (page)
-				gather_stats(page, md, pte_dirty(huge_pte),
-						HPAGE_PMD_SIZE/PAGE_SIZE);
-			spin_unlock(&walk->mm->page_table_lock);
-			return 0;
-		}
-	} else {
+
+	if (pmd_trans_huge_lock(pmd, md->vma)) {
+		pte_t huge_pte = *(pte_t *)pmd;
+		struct page *page;
+
+		page = can_gather_numa_stats(huge_pte, md->vma, addr);
+		if (page)
+			gather_stats(page, md, pte_dirty(huge_pte),
+				     HPAGE_PMD_SIZE/PAGE_SIZE);
 		spin_unlock(&walk->mm->page_table_lock);
+		return 0;
 	}
 
 	orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c
index 1241285..5e289a7 100644
--- a/fs/proc_namespace.c
+++ b/fs/proc_namespace.c
@@ -23,12 +23,12 @@ static unsigned mounts_poll(struct file *file, poll_table *wait)
 
 	poll_wait(file, &p->ns->poll, wait);
 
-	br_read_lock(vfsmount_lock);
+	br_read_lock(&vfsmount_lock);
 	if (p->m.poll_event != ns->event) {
 		p->m.poll_event = ns->event;
 		res |= POLLERR | POLLPRI;
 	}
-	br_read_unlock(vfsmount_lock);
+	br_read_unlock(&vfsmount_lock);
 
 	return res;
 }
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index b3b426e..f37c32b 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -278,9 +278,7 @@ fail:
 
 int pstore_fill_super(struct super_block *sb, void *data, int silent)
 {
-	struct inode *inode = NULL;
-	struct dentry *root;
-	int err;
+	struct inode *inode;
 
 	save_mount_options(sb, data);
 
@@ -296,26 +294,17 @@ int pstore_fill_super(struct super_block *sb, void *data, int silent)
 	parse_options(data);
 
 	inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0);
-	if (!inode) {
-		err = -ENOMEM;
-		goto fail;
-	}
-	/* override ramfs "dir" options so we catch unlink(2) */
-	inode->i_op = &pstore_dir_inode_operations;
-
-	root = d_alloc_root(inode);
-	sb->s_root = root;
-	if (!root) {
-		err = -ENOMEM;
-		goto fail;
+	if (inode) {
+		/* override ramfs "dir" options so we catch unlink(2) */
+		inode->i_op = &pstore_dir_inode_operations;
 	}
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root)
+		return -ENOMEM;
 
 	pstore_get_records(0);
 
 	return 0;
-fail:
-	iput(inode);
-	return err;
 }
 
 static struct dentry *pstore_mount(struct file_system_type *fs_type,
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 6b00954..14a0ba0 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -260,15 +260,13 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
  	}
 
 	ret = -ENOMEM;
- 	s->s_root = d_alloc_root(root);
+ 	s->s_root = d_make_root(root);
  	if (s->s_root == NULL)
- 		goto outi;
+ 		goto outb;
 
 	brelse(bh);
 	return 0;
 
-      outi:
-	iput(root);
       outb:
 	kfree(qs->BitMap);
       out:
@@ -288,44 +286,17 @@ static void qnx4_put_super(struct super_block *sb)
 	return;
 }
 
-static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
-{
-	return block_write_full_page(page,qnx4_get_block, wbc);
-}
-
 static int qnx4_readpage(struct file *file, struct page *page)
 {
 	return block_read_full_page(page,qnx4_get_block);
 }
 
-static int qnx4_write_begin(struct file *file, struct address_space *mapping,
-			loff_t pos, unsigned len, unsigned flags,
-			struct page **pagep, void **fsdata)
-{
-	struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
-	int ret;
-
-	*pagep = NULL;
-	ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-				qnx4_get_block,
-				&qnx4_inode->mmu_private);
-	if (unlikely(ret)) {
-		loff_t isize = mapping->host->i_size;
-		if (pos + len > isize)
-			vmtruncate(mapping->host, isize);
-	}
-
-	return ret;
-}
 static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
 {
 	return generic_block_bmap(mapping,block,qnx4_get_block);
 }
 static const struct address_space_operations qnx4_aops = {
 	.readpage	= qnx4_readpage,
-	.writepage	= qnx4_writepage,
-	.write_begin	= qnx4_write_begin,
-	.write_end	= generic_write_end,
 	.bmap		= qnx4_bmap
 };
 
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index 275327b..e8eb878 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -39,10 +39,6 @@ static int qnx4_match(int len, const char *name,
 	} else {
 		namelen = QNX4_SHORT_NAME_MAX;
 	}
-	/* "" means "." ---> so paths like "/usr/lib//libc.a" work */
-	if (!len && (de->di_fname[0] == '.') && (de->di_fname[1] == '\0')) {
-		return 1;
-	}
 	thislen = strlen( de->di_fname );
 	if ( thislen > namelen )
 		thislen = namelen;
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 4674197..8b4f12b 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -71,6 +71,7 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/security.h>
+#include <linux/sched.h>
 #include <linux/kmod.h>
 #include <linux/namei.h>
 #include <linux/capability.h>
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 7898cd6..fc2c438 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -292,11 +292,26 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
 	}
 }
 
+/* Return 1 if 'cmd' will block on frozen filesystem */
+static int quotactl_cmd_write(int cmd)
+{
+	switch (cmd) {
+	case Q_GETFMT:
+	case Q_GETINFO:
+	case Q_SYNC:
+	case Q_XGETQSTAT:
+	case Q_XGETQUOTA:
+	case Q_XQUOTASYNC:
+		return 0;
+	}
+	return 1;
+}
+
 /*
  * look up a superblock on which quota ops will be performed
  * - use the name of a block device to find the superblock thereon
  */
-static struct super_block *quotactl_block(const char __user *special)
+static struct super_block *quotactl_block(const char __user *special, int cmd)
 {
 #ifdef CONFIG_BLOCK
 	struct block_device *bdev;
@@ -309,7 +324,10 @@ static struct super_block *quotactl_block(const char __user *special)
 	putname(tmp);
 	if (IS_ERR(bdev))
 		return ERR_CAST(bdev);
-	sb = get_super(bdev);
+	if (quotactl_cmd_write(cmd))
+		sb = get_super_thawed(bdev);
+	else
+		sb = get_super(bdev);
 	bdput(bdev);
 	if (!sb)
 		return ERR_PTR(-ENODEV);
@@ -361,7 +379,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
 			pathp = &path;
 	}
 
-	sb = quotactl_block(special);
+	sb = quotactl_block(special, cmds);
 	if (IS_ERR(sb)) {
 		ret = PTR_ERR(sb);
 		goto out;
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index aec766a..a1fdabe 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -209,22 +209,19 @@ static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
 int ramfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct ramfs_fs_info *fsi;
-	struct inode *inode = NULL;
-	struct dentry *root;
+	struct inode *inode;
 	int err;
 
 	save_mount_options(sb, data);
 
 	fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
 	sb->s_fs_info = fsi;
-	if (!fsi) {
-		err = -ENOMEM;
-		goto fail;
-	}
+	if (!fsi)
+		return -ENOMEM;
 
 	err = ramfs_parse_options(data, &fsi->mount_opts);
 	if (err)
-		goto fail;
+		return err;
 
 	sb->s_maxbytes		= MAX_LFS_FILESIZE;
 	sb->s_blocksize		= PAGE_CACHE_SIZE;
@@ -234,24 +231,11 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_time_gran		= 1;
 
 	inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
-	if (!inode) {
-		err = -ENOMEM;
-		goto fail;
-	}
-
-	root = d_alloc_root(inode);
-	sb->s_root = root;
-	if (!root) {
-		err = -ENOMEM;
-		goto fail;
-	}
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root)
+		return -ENOMEM;
 
 	return 0;
-fail:
-	kfree(fsi);
-	sb->s_fs_info = NULL;
-	iput(inode);
-	return err;
 }
 
 struct dentry *ramfs_mount(struct file_system_type *fs_type,
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c
index 03d85cb..b43d015 100644
--- a/fs/reiserfs/lbalance.c
+++ b/fs/reiserfs/lbalance.c
@@ -975,7 +975,7 @@ static int leaf_cut_entries(struct buffer_head *bh,
 	   remove */
 	RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
 	RFALSE(I_ENTRY_COUNT(ih) < from + del_count,
-	       "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
+	       "10185: item contains not enough entries: entry_count = %d, from = %d, to delete = %d",
 	       I_ENTRY_COUNT(ih), from, del_count);
 
 	if (del_count == 0)
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 313d39d..77df82f 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -1284,12 +1284,12 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th,
 		 ** -clm
 		 */
 
-		data = kmap_atomic(un_bh->b_page, KM_USER0);
+		data = kmap_atomic(un_bh->b_page);
 		off = ((le_ih_k_offset(&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));
 		memcpy(data + off,
 		       B_I_PITEM(PATH_PLAST_BUFFER(path), &s_ih),
 		       ret_value);
-		kunmap_atomic(data, KM_USER0);
+		kunmap_atomic(data);
 	}
 	/* Perform balancing after all resources have been collected at once. */
 	do_balance(&s_del_balance, NULL, NULL, M_DELETE);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index e12d8b9..208dfd1 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1874,11 +1874,9 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
 		unlock_new_inode(root_inode);
 	}
 
-	s->s_root = d_alloc_root(root_inode);
-	if (!s->s_root) {
-		iput(root_inode);
+	s->s_root = d_make_root(root_inode);
+	if (!s->s_root)
 		goto error;
-	}
 	// define and initialize hash function
 	sbi->s_hash_function = hash_function(s);
 	if (sbi->s_hash_function == NULL) {
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index d7f6e51..8f546bd 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -128,9 +128,9 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
 	if (up_to_date_bh) {
 		unsigned pgoff =
 		    (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
-		char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0);
+		char *kaddr = kmap_atomic(up_to_date_bh->b_page);
 		memset(kaddr + pgoff, 0, blk_size - total_tail);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 
 	REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
diff --git a/fs/romfs/storage.c b/fs/romfs/storage.c
index 71e2b4d..f86f51f 100644
--- a/fs/romfs/storage.c
+++ b/fs/romfs/storage.c
@@ -19,7 +19,7 @@
 #endif
 
 #ifdef CONFIG_ROMFS_ON_MTD
-#define ROMFS_MTD_READ(sb, ...) ((sb)->s_mtd->read((sb)->s_mtd, ##__VA_ARGS__))
+#define ROMFS_MTD_READ(sb, ...) mtd_read((sb)->s_mtd, ##__VA_ARGS__)
 
 /*
  * read data from an romfs image on an MTD device
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index bb36ab7..e64f6b5 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -538,14 +538,12 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent)
 	if (IS_ERR(root))
 		goto error;
 
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root)
-		goto error_i;
+		goto error;
 
 	return 0;
 
-error_i:
-	iput(root);
 error:
 	return -EINVAL;
 error_rsb_inval:
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 4023d6b..46cfb06 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -13,6 +13,22 @@
 #include <asm/uaccess.h>
 #include <asm/page.h>
 
+
+/*
+ * seq_files have a buffer which can may overflow. When this happens a larger
+ * buffer is reallocated and all the data will be printed again.
+ * The overflow state is true when m->count == m->size.
+ */
+static bool seq_overflow(struct seq_file *m)
+{
+	return m->count == m->size;
+}
+
+static void seq_set_overflow(struct seq_file *m)
+{
+	m->count = m->size;
+}
+
 /**
  *	seq_open -	initialize sequential file
  *	@file: file we initialize
@@ -92,7 +108,7 @@ static int traverse(struct seq_file *m, loff_t offset)
 			error = 0;
 			m->count = 0;
 		}
-		if (m->count == m->size)
+		if (seq_overflow(m))
 			goto Eoverflow;
 		if (pos + m->count > offset) {
 			m->from = offset - pos;
@@ -140,9 +156,21 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
 
 	mutex_lock(&m->lock);
 
+	/*
+	 * seq_file->op->..m_start/m_stop/m_next may do special actions
+	 * or optimisations based on the file->f_version, so we want to
+	 * pass the file->f_version to those methods.
+	 *
+	 * seq_file->version is just copy of f_version, and seq_file
+	 * methods can treat it simply as file version.
+	 * It is copied in first and copied out after all operations.
+	 * It is convenient to have it as  part of structure to avoid the
+	 * need of passing another argument to all the seq_file methods.
+	 */
+	m->version = file->f_version;
+
 	/* Don't assume *ppos is where we left it */
 	if (unlikely(*ppos != m->read_pos)) {
-		m->read_pos = *ppos;
 		while ((err = traverse(m, *ppos)) == -EAGAIN)
 			;
 		if (err) {
@@ -152,21 +180,11 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
 			m->index = 0;
 			m->count = 0;
 			goto Done;
+		} else {
+			m->read_pos = *ppos;
 		}
 	}
 
-	/*
-	 * seq_file->op->..m_start/m_stop/m_next may do special actions
-	 * or optimisations based on the file->f_version, so we want to
-	 * pass the file->f_version to those methods.
-	 *
-	 * seq_file->version is just copy of f_version, and seq_file
-	 * methods can treat it simply as file version.
-	 * It is copied in first and copied out after all operations.
-	 * It is convenient to have it as  part of structure to avoid the
-	 * need of passing another argument to all the seq_file methods.
-	 */
-	m->version = file->f_version;
 	/* grab buffer if we didn't have one */
 	if (!m->buf) {
 		m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
@@ -232,7 +250,7 @@ Fill:
 			break;
 		}
 		err = m->op->show(m, p);
-		if (m->count == m->size || err) {
+		if (seq_overflow(m) || err) {
 			m->count = offs;
 			if (likely(err <= 0))
 				break;
@@ -359,7 +377,7 @@ int seq_escape(struct seq_file *m, const char *s, const char *esc)
 			*p++ = '0' + (c & 07);
 			continue;
 		}
-		m->count = m->size;
+		seq_set_overflow(m);
 		return -1;
         }
 	m->count = p - m->buf;
@@ -381,7 +399,7 @@ int seq_printf(struct seq_file *m, const char *f, ...)
 			return 0;
 		}
 	}
-	m->count = m->size;
+	seq_set_overflow(m);
 	return -1;
 }
 EXPORT_SYMBOL(seq_printf);
@@ -510,7 +528,7 @@ int seq_bitmap(struct seq_file *m, const unsigned long *bits,
 			return 0;
 		}
 	}
-	m->count = m->size;
+	seq_set_overflow(m);
 	return -1;
 }
 EXPORT_SYMBOL(seq_bitmap);
@@ -526,7 +544,7 @@ int seq_bitmap_list(struct seq_file *m, const unsigned long *bits,
 			return 0;
 		}
 	}
-	m->count = m->size;
+	seq_set_overflow(m);
 	return -1;
 }
 EXPORT_SYMBOL(seq_bitmap_list);
@@ -637,11 +655,63 @@ int seq_puts(struct seq_file *m, const char *s)
 		m->count += len;
 		return 0;
 	}
-	m->count = m->size;
+	seq_set_overflow(m);
 	return -1;
 }
 EXPORT_SYMBOL(seq_puts);
 
+/*
+ * A helper routine for putting decimal numbers without rich format of printf().
+ * only 'unsigned long long' is supported.
+ * This routine will put one byte delimiter + number into seq_file.
+ * This routine is very quick when you show lots of numbers.
+ * In usual cases, it will be better to use seq_printf(). It's easier to read.
+ */
+int seq_put_decimal_ull(struct seq_file *m, char delimiter,
+			unsigned long long num)
+{
+	int len;
+
+	if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */
+		goto overflow;
+
+	if (delimiter)
+		m->buf[m->count++] = delimiter;
+
+	if (num < 10) {
+		m->buf[m->count++] = num + '0';
+		return 0;
+	}
+
+	len = num_to_str(m->buf + m->count, m->size - m->count, num);
+	if (!len)
+		goto overflow;
+	m->count += len;
+	return 0;
+overflow:
+	seq_set_overflow(m);
+	return -1;
+}
+EXPORT_SYMBOL(seq_put_decimal_ull);
+
+int seq_put_decimal_ll(struct seq_file *m, char delimiter,
+			long long num)
+{
+	if (num < 0) {
+		if (m->count + 3 >= m->size) {
+			seq_set_overflow(m);
+			return -1;
+		}
+		if (delimiter)
+			m->buf[m->count++] = delimiter;
+		num = -num;
+		delimiter = '-';
+	}
+	return seq_put_decimal_ull(m, delimiter, num);
+
+}
+EXPORT_SYMBOL(seq_put_decimal_ll);
+
 /**
  * seq_write - write arbitrary data to buffer
  * @seq: seq_file identifying the buffer to which data should be written
@@ -657,7 +727,7 @@ int seq_write(struct seq_file *seq, const void *data, size_t len)
 		seq->count += len;
 		return 0;
 	}
-	seq->count = seq->size;
+	seq_set_overflow(seq);
 	return -1;
 }
 EXPORT_SYMBOL(seq_write);
diff --git a/fs/splice.c b/fs/splice.c
index 1ec0493..f16402e 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -737,15 +737,12 @@ int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
 		goto out;
 
 	if (buf->page != page) {
-		/*
-		 * Careful, ->map() uses KM_USER0!
-		 */
 		char *src = buf->ops->map(pipe, buf, 1);
-		char *dst = kmap_atomic(page, KM_USER1);
+		char *dst = kmap_atomic(page);
 
 		memcpy(dst + offset, src + buf->offset, this_len);
 		flush_dcache_page(page);
-		kunmap_atomic(dst, KM_USER1);
+		kunmap_atomic(dst);
 		buf->ops->unmap(pipe, buf, src);
 	}
 	ret = pagecache_write_end(file, mapping, sd->pos, this_len, this_len,
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index 38bb1c6..8ca62c2 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -464,10 +464,10 @@ static int squashfs_readpage(struct file *file, struct page *page)
 		if (PageUptodate(push_page))
 			goto skip_page;
 
-		pageaddr = kmap_atomic(push_page, KM_USER0);
+		pageaddr = kmap_atomic(push_page);
 		squashfs_copy_data(pageaddr, buffer, offset, avail);
 		memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
-		kunmap_atomic(pageaddr, KM_USER0);
+		kunmap_atomic(pageaddr);
 		flush_dcache_page(push_page);
 		SetPageUptodate(push_page);
 skip_page:
@@ -484,9 +484,9 @@ skip_page:
 error_out:
 	SetPageError(page);
 out:
-	pageaddr = kmap_atomic(page, KM_USER0);
+	pageaddr = kmap_atomic(page);
 	memset(pageaddr, 0, PAGE_CACHE_SIZE);
-	kunmap_atomic(pageaddr, KM_USER0);
+	kunmap_atomic(pageaddr);
 	flush_dcache_page(page);
 	if (!PageError(page))
 		SetPageUptodate(page);
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index ecaa2f7..970b116 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -316,11 +316,10 @@ check_directory_table:
 	}
 	insert_inode_hash(root);
 
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (sb->s_root == NULL) {
 		ERROR("Root inode create failed\n");
 		err = -ENOMEM;
-		iput(root);
 		goto failed_mount;
 	}
 
diff --git a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
index 1191817..12806df 100644
--- a/fs/squashfs/symlink.c
+++ b/fs/squashfs/symlink.c
@@ -90,14 +90,14 @@ static int squashfs_symlink_readpage(struct file *file, struct page *page)
 			goto error_out;
 		}
 
-		pageaddr = kmap_atomic(page, KM_USER0);
+		pageaddr = kmap_atomic(page);
 		copied = squashfs_copy_data(pageaddr + bytes, entry, offset,
 								length - bytes);
 		if (copied == length - bytes)
 			memset(pageaddr + length, 0, PAGE_CACHE_SIZE - length);
 		else
 			block = entry->next_index;
-		kunmap_atomic(pageaddr, KM_USER0);
+		kunmap_atomic(pageaddr);
 		squashfs_cache_put(entry);
 	}
 
diff --git a/fs/super.c b/fs/super.c
index 6015c02..7fcb135 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -32,6 +32,7 @@
 #include <linux/backing-dev.h>
 #include <linux/rculist_bl.h>
 #include <linux/cleancache.h>
+#include <linux/fsnotify.h>
 #include "internal.h"
 
 
@@ -250,7 +251,7 @@ void deactivate_locked_super(struct super_block *s)
 {
 	struct file_system_type *fs = s->s_type;
 	if (atomic_dec_and_test(&s->s_active)) {
-		cleancache_flush_fs(s);
+		cleancache_invalidate_fs(s);
 		fs->kill_sb(s);
 
 		/* caches are now gone, we can safely kill the shrinker now */
@@ -634,6 +635,28 @@ rescan:
 EXPORT_SYMBOL(get_super);
 
 /**
+ *	get_super_thawed - get thawed superblock of a device
+ *	@bdev: device to get the superblock for
+ *
+ *	Scans the superblock list and finds the superblock of the file system
+ *	mounted on the device. The superblock is returned once it is thawed
+ *	(or immediately if it was not frozen). %NULL is returned if no match
+ *	is found.
+ */
+struct super_block *get_super_thawed(struct block_device *bdev)
+{
+	while (1) {
+		struct super_block *s = get_super(bdev);
+		if (!s || s->s_frozen == SB_UNFROZEN)
+			return s;
+		up_read(&s->s_umount);
+		vfs_check_frozen(s, SB_FREEZE_WRITE);
+		put_super(s);
+	}
+}
+EXPORT_SYMBOL(get_super_thawed);
+
+/**
  * get_active_super - get an active reference to the superblock of a device
  * @bdev: device to get the superblock for
  *
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 7fdf6a7..dd3779c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -22,76 +22,100 @@
 #include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/security.h>
+#include <linux/hash.h>
 #include "sysfs.h"
 
 DEFINE_MUTEX(sysfs_mutex);
 DEFINE_SPINLOCK(sysfs_assoc_lock);
 
+#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb);
+
 static DEFINE_SPINLOCK(sysfs_ino_lock);
 static DEFINE_IDA(sysfs_ino_ida);
 
 /**
- *	sysfs_link_sibling - link sysfs_dirent into sibling list
+ *	sysfs_name_hash
+ *	@ns:   Namespace tag to hash
+ *	@name: Null terminated string to hash
+ *
+ *	Returns 31 bit hash of ns + name (so it fits in an off_t )
+ */
+static unsigned int sysfs_name_hash(const void *ns, const char *name)
+{
+	unsigned long hash = init_name_hash();
+	unsigned int len = strlen(name);
+	while (len--)
+		hash = partial_name_hash(*name++, hash);
+	hash = ( end_name_hash(hash) ^ hash_ptr( (void *)ns, 31 ) );
+	hash &= 0x7fffffffU;
+	/* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
+	if (hash < 1)
+		hash += 2;
+	if (hash >= INT_MAX)
+		hash = INT_MAX - 1;
+	return hash;
+}
+
+static int sysfs_name_compare(unsigned int hash, const void *ns,
+	const char *name, const struct sysfs_dirent *sd)
+{
+	if (hash != sd->s_hash)
+		return hash - sd->s_hash;
+	if (ns != sd->s_ns)
+		return ns - sd->s_ns;
+	return strcmp(name, sd->s_name);
+}
+
+static int sysfs_sd_compare(const struct sysfs_dirent *left,
+			    const struct sysfs_dirent *right)
+{
+	return sysfs_name_compare(left->s_hash, left->s_ns, left->s_name,
+				  right);
+}
+
+/**
+ *	sysfs_link_subling - link sysfs_dirent into sibling rbtree
  *	@sd: sysfs_dirent of interest
  *
- *	Link @sd into its sibling list which starts from
+ *	Link @sd into its sibling rbtree which starts from
  *	sd->s_parent->s_dir.children.
  *
  *	Locking:
  *	mutex_lock(sysfs_mutex)
+ *
+ *	RETURNS:
+ *	0 on susccess -EEXIST on failure.
  */
-static void sysfs_link_sibling(struct sysfs_dirent *sd)
+static int sysfs_link_sibling(struct sysfs_dirent *sd)
 {
-	struct sysfs_dirent *parent_sd = sd->s_parent;
-
-	struct rb_node **p;
-	struct rb_node *parent;
-
-	if (sysfs_type(sd) == SYSFS_DIR)
-		parent_sd->s_dir.subdirs++;
-
-	p = &parent_sd->s_dir.inode_tree.rb_node;
-	parent = NULL;
-	while (*p) {
-		parent = *p;
-#define node	rb_entry(parent, struct sysfs_dirent, inode_node)
-		if (sd->s_ino < node->s_ino) {
-			p = &node->inode_node.rb_left;
-		} else if (sd->s_ino > node->s_ino) {
-			p = &node->inode_node.rb_right;
-		} else {
-			printk(KERN_CRIT "sysfs: inserting duplicate inode '%lx'\n",
-			       (unsigned long) sd->s_ino);
-			BUG();
-		}
-#undef node
-	}
-	rb_link_node(&sd->inode_node, parent, p);
-	rb_insert_color(&sd->inode_node, &parent_sd->s_dir.inode_tree);
-
-	p = &parent_sd->s_dir.name_tree.rb_node;
-	parent = NULL;
-	while (*p) {
-		int c;
-		parent = *p;
-#define node	rb_entry(parent, struct sysfs_dirent, name_node)
-		c = strcmp(sd->s_name, node->s_name);
-		if (c < 0) {
-			p = &node->name_node.rb_left;
-		} else {
-			p = &node->name_node.rb_right;
-		}
-#undef node
+	struct rb_node **node = &sd->s_parent->s_dir.children.rb_node;
+	struct rb_node *parent = NULL;
+
+	while (*node) {
+		struct sysfs_dirent *pos;
+		int result;
+
+		pos = to_sysfs_dirent(*node);
+		parent = *node;
+		result = sysfs_sd_compare(sd, pos);
+		if (result < 0)
+			node = &pos->s_rb.rb_left;
+		else if (result > 0)
+			node = &pos->s_rb.rb_right;
+		else
+			return -EEXIST;
 	}
-	rb_link_node(&sd->name_node, parent, p);
-	rb_insert_color(&sd->name_node, &parent_sd->s_dir.name_tree);
+	/* add new node and rebalance the tree */
+	rb_link_node(&sd->s_rb, parent, node);
+	rb_insert_color(&sd->s_rb, &sd->s_parent->s_dir.children);
+	return 0;
 }
 
 /**
- *	sysfs_unlink_sibling - unlink sysfs_dirent from sibling list
+ *	sysfs_unlink_sibling - unlink sysfs_dirent from sibling rbtree
  *	@sd: sysfs_dirent of interest
  *
- *	Unlink @sd from its sibling list which starts from
+ *	Unlink @sd from its sibling rbtree which starts from
  *	sd->s_parent->s_dir.children.
  *
  *	Locking:
@@ -99,11 +123,7 @@ static void sysfs_link_sibling(struct sysfs_dirent *sd)
  */
 static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
 {
-	if (sysfs_type(sd) == SYSFS_DIR)
-		sd->s_parent->s_dir.subdirs--;
-
-	rb_erase(&sd->inode_node, &sd->s_parent->s_dir.inode_tree);
-	rb_erase(&sd->name_node, &sd->s_parent->s_dir.name_tree);
+	rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children);
 }
 
 /**
@@ -198,7 +218,7 @@ static void sysfs_deactivate(struct sysfs_dirent *sd)
 	rwsem_release(&sd->dep_map, 1, _RET_IP_);
 }
 
-static int sysfs_alloc_ino(ino_t *pino)
+static int sysfs_alloc_ino(unsigned int *pino)
 {
 	int ino, rc;
 
@@ -217,7 +237,7 @@ static int sysfs_alloc_ino(ino_t *pino)
 	return rc;
 }
 
-static void sysfs_free_ino(ino_t ino)
+static void sysfs_free_ino(unsigned int ino)
 {
 	spin_lock(&sysfs_ino_lock);
 	ida_remove(&sysfs_ino_ida, ino);
@@ -402,6 +422,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
 int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
 	struct sysfs_inode_attrs *ps_iattr;
+	int ret;
 
 	if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) {
 		WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
@@ -410,12 +431,12 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 		return -EINVAL;
 	}
 
-	if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name))
-		return -EEXIST;
-
+	sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
 	sd->s_parent = sysfs_get(acxt->parent_sd);
 
-	sysfs_link_sibling(sd);
+	ret = sysfs_link_sibling(sd);
+	if (ret)
+		return ret;
 
 	/* Update timestamps on the parent */
 	ps_iattr = acxt->parent_sd->s_iattr;
@@ -565,8 +586,8 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
 				       const void *ns,
 				       const unsigned char *name)
 {
-	struct rb_node *p = parent_sd->s_dir.name_tree.rb_node;
-	struct sysfs_dirent *found = NULL;
+	struct rb_node *node = parent_sd->s_dir.children.rb_node;
+	unsigned int hash;
 
 	if (!!sysfs_ns_type(parent_sd) != !!ns) {
 		WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
@@ -575,33 +596,21 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
 		return NULL;
 	}
 
-	while (p) {
-		int c;
-#define node	rb_entry(p, struct sysfs_dirent, name_node)
-		c = strcmp(name, node->s_name);
-		if (c < 0) {
-			p = node->name_node.rb_left;
-		} else if (c > 0) {
-			p = node->name_node.rb_right;
-		} else {
-			found = node;
-			p = node->name_node.rb_left;
-		}
-#undef node
-	}
-
-	if (found) {
-		while (found->s_ns != ns) {
-			p = rb_next(&found->name_node);
-			if (!p)
-				return NULL;
-			found = rb_entry(p, struct sysfs_dirent, name_node);
-			if (strcmp(name, found->s_name))
-				return NULL;
-		}
+	hash = sysfs_name_hash(ns, name);
+	while (node) {
+		struct sysfs_dirent *sd;
+		int result;
+
+		sd = to_sysfs_dirent(node);
+		result = sysfs_name_compare(hash, ns, name, sd);
+		if (result < 0)
+			node = node->rb_left;
+		else if (result > 0)
+			node = node->rb_right;
+		else
+			return sd;
 	}
-
-	return found;
+	return NULL;
 }
 
 /**
@@ -804,9 +813,9 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
 
 	pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
 	sysfs_addrm_start(&acxt, dir_sd);
-	pos = rb_first(&dir_sd->s_dir.inode_tree);
+	pos = rb_first(&dir_sd->s_dir.children);
 	while (pos) {
-		struct sysfs_dirent *sd = rb_entry(pos, struct sysfs_dirent, inode_node);
+		struct sysfs_dirent *sd = to_sysfs_dirent(pos);
 		pos = rb_next(pos);
 		if (sysfs_type(sd) != SYSFS_DIR)
 			sysfs_remove_one(&acxt, sd);
@@ -863,6 +872,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
 
 		dup_name = sd->s_name;
 		sd->s_name = new_name;
+		sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
 	}
 
 	/* Move to the appropriate place in the appropriate directories rbtree. */
@@ -919,38 +929,36 @@ static int sysfs_dir_release(struct inode *inode, struct file *filp)
 }
 
 static struct sysfs_dirent *sysfs_dir_pos(const void *ns,
-	struct sysfs_dirent *parent_sd,	ino_t ino, struct sysfs_dirent *pos)
+	struct sysfs_dirent *parent_sd,	loff_t hash, struct sysfs_dirent *pos)
 {
 	if (pos) {
 		int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) &&
 			pos->s_parent == parent_sd &&
-			ino == pos->s_ino;
+			hash == pos->s_hash;
 		sysfs_put(pos);
 		if (!valid)
 			pos = NULL;
 	}
-	if (!pos && (ino > 1) && (ino < INT_MAX)) {
-		struct rb_node *p = parent_sd->s_dir.inode_tree.rb_node;
-		while (p) {
-#define node	rb_entry(p, struct sysfs_dirent, inode_node)
-			if (ino < node->s_ino) {
-				pos = node;
-				p = node->inode_node.rb_left;
-			} else if (ino > node->s_ino) {
-				p = node->inode_node.rb_right;
-			} else {
-				pos = node;
+	if (!pos && (hash > 1) && (hash < INT_MAX)) {
+		struct rb_node *node = parent_sd->s_dir.children.rb_node;
+		while (node) {
+			pos = to_sysfs_dirent(node);
+
+			if (hash < pos->s_hash)
+				node = node->rb_left;
+			else if (hash > pos->s_hash)
+				node = node->rb_right;
+			else
 				break;
-			}
-#undef node
 		}
 	}
+	/* Skip over entries in the wrong namespace */
 	while (pos && pos->s_ns != ns) {
-		struct rb_node *p = rb_next(&pos->inode_node);
-		if (!p)
+		struct rb_node *node = rb_next(&pos->s_rb);
+		if (!node)
 			pos = NULL;
 		else
-			pos = rb_entry(p, struct sysfs_dirent, inode_node);
+			pos = to_sysfs_dirent(node);
 	}
 	return pos;
 }
@@ -960,11 +968,11 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
 {
 	pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
 	if (pos) do {
-		struct rb_node *p = rb_next(&pos->inode_node);
-		if (!p)
+		struct rb_node *node = rb_next(&pos->s_rb);
+		if (!node)
 			pos = NULL;
 		else
-			pos = rb_entry(p, struct sysfs_dirent, inode_node);
+			pos = to_sysfs_dirent(node);
 	} while (pos && pos->s_ns != ns);
 	return pos;
 }
@@ -1006,7 +1014,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
 		len = strlen(name);
 		ino = pos->s_ino;
 		type = dt_type(pos);
-		filp->f_pos = ino;
+		filp->f_pos = pos->s_hash;
 		filp->private_data = sysfs_get(pos);
 
 		mutex_unlock(&sysfs_mutex);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 85eb816..4291fd1 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -216,9 +216,6 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
 					    iattrs->ia_secdata,
 					    iattrs->ia_secdata_len);
 	}
-
-	if (sysfs_type(sd) == SYSFS_DIR)
-		set_nlink(inode, sd->s_dir.subdirs + 2);
 }
 
 int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index e34f0d9..52c3bdb 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -36,7 +36,7 @@ struct sysfs_dirent sysfs_root = {
 	.s_name		= "",
 	.s_count	= ATOMIC_INIT(1),
 	.s_flags	= SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT),
-	.s_mode		= S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+	.s_mode		= S_IFDIR | S_IRUGO | S_IXUGO,
 	.s_ino		= 1,
 };
 
@@ -61,10 +61,9 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
 	}
 
 	/* instantiate and link root dentry */
-	root = d_alloc_root(inode);
+	root = d_make_root(inode);
 	if (!root) {
 		pr_debug("%s: could not get root dentry!\n",__func__);
-		iput(inode);
 		return -ENOMEM;
 	}
 	root->d_fsdata = &sysfs_root;
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 7484a36..6289a00 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -19,10 +19,8 @@ struct sysfs_open_dirent;
 struct sysfs_elem_dir {
 	struct kobject		*kobj;
 
-	unsigned long		subdirs;
-
-	struct rb_root		inode_tree;
-	struct rb_root		name_tree;
+	/* children rbtree starts here and goes through sd->s_rb */
+	struct rb_root		children;
 };
 
 struct sysfs_elem_symlink {
@@ -62,8 +60,7 @@ struct sysfs_dirent {
 	struct sysfs_dirent	*s_parent;
 	const char		*s_name;
 
-	struct rb_node		inode_node;
-	struct rb_node		name_node;
+	struct rb_node		s_rb;
 
 	union {
 		struct completion	*completion;
@@ -71,6 +68,7 @@ struct sysfs_dirent {
 	} u;
 
 	const void		*s_ns; /* namespace tag */
+	unsigned int		s_hash; /* ns + name hash */
 	union {
 		struct sysfs_elem_dir		s_dir;
 		struct sysfs_elem_symlink	s_symlink;
@@ -78,9 +76,9 @@ struct sysfs_dirent {
 		struct sysfs_elem_bin_attr	s_bin_attr;
 	};
 
-	unsigned int		s_flags;
+	unsigned short		s_flags;
 	umode_t 		s_mode;
-	ino_t			s_ino;
+	unsigned int		s_ino;
 	struct sysfs_inode_attrs *s_iattr;
 };
 
@@ -95,11 +93,11 @@ struct sysfs_dirent {
 #define SYSFS_ACTIVE_REF		(SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR)
 
 /* identify any namespace tag on sysfs_dirents */
-#define SYSFS_NS_TYPE_MASK		0xff00
+#define SYSFS_NS_TYPE_MASK		0xf00
 #define SYSFS_NS_TYPE_SHIFT		8
 
 #define SYSFS_FLAG_MASK			~(SYSFS_NS_TYPE_MASK|SYSFS_TYPE_MASK)
-#define SYSFS_FLAG_REMOVED		0x020000
+#define SYSFS_FLAG_REMOVED		0x02000
 
 static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
 {
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index b217797..d7466e2 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -121,9 +121,6 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
 {
 	struct inode *inode = old_dentry->d_inode;
 
-	if (inode->i_nlink >= SYSV_SB(inode->i_sb)->s_link_max)
-		return -EMLINK;
-
 	inode->i_ctime = CURRENT_TIME_SEC;
 	inode_inc_link_count(inode);
 	ihold(inode);
@@ -134,10 +131,8 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
 static int sysv_mkdir(struct inode * dir, struct dentry *dentry, umode_t mode)
 {
 	struct inode * inode;
-	int err = -EMLINK;
+	int err;
 
-	if (dir->i_nlink >= SYSV_SB(dir->i_sb)->s_link_max) 
-		goto out;
 	inode_inc_link_count(dir);
 
 	inode = sysv_new_inode(dir, S_IFDIR|mode);
@@ -251,11 +246,6 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
 			drop_nlink(new_inode);
 		inode_dec_link_count(new_inode);
 	} else {
-		if (dir_de) {
-			err = -EMLINK;
-			if (new_dir->i_nlink >= SYSV_SB(new_dir->i_sb)->s_link_max)
-				goto out_dir;
-		}
 		err = sysv_add_link(new_dentry, old_inode);
 		if (err)
 			goto out_dir;
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index f60c196..7491c33 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -44,7 +44,7 @@ enum {
 	JAN_1_1980 = (10*365 + 2) * 24 * 60 * 60
 };
 
-static void detected_xenix(struct sysv_sb_info *sbi)
+static void detected_xenix(struct sysv_sb_info *sbi, unsigned *max_links)
 {
 	struct buffer_head *bh1 = sbi->s_bh1;
 	struct buffer_head *bh2 = sbi->s_bh2;
@@ -59,7 +59,7 @@ static void detected_xenix(struct sysv_sb_info *sbi)
 		sbd2 = (struct xenix_super_block *) (bh2->b_data - 512);
 	}
 
-	sbi->s_link_max = XENIX_LINK_MAX;
+	*max_links = XENIX_LINK_MAX;
 	sbi->s_fic_size = XENIX_NICINOD;
 	sbi->s_flc_size = XENIX_NICFREE;
 	sbi->s_sbd1 = (char *)sbd1;
@@ -75,7 +75,7 @@ static void detected_xenix(struct sysv_sb_info *sbi)
 	sbi->s_nzones = fs32_to_cpu(sbi, sbd1->s_fsize);
 }
 
-static void detected_sysv4(struct sysv_sb_info *sbi)
+static void detected_sysv4(struct sysv_sb_info *sbi, unsigned *max_links)
 {
 	struct sysv4_super_block * sbd;
 	struct buffer_head *bh1 = sbi->s_bh1;
@@ -86,7 +86,7 @@ static void detected_sysv4(struct sysv_sb_info *sbi)
 	else
 		sbd = (struct sysv4_super_block *) bh2->b_data;
 
-	sbi->s_link_max = SYSV_LINK_MAX;
+	*max_links = SYSV_LINK_MAX;
 	sbi->s_fic_size = SYSV_NICINOD;
 	sbi->s_flc_size = SYSV_NICFREE;
 	sbi->s_sbd1 = (char *)sbd;
@@ -103,7 +103,7 @@ static void detected_sysv4(struct sysv_sb_info *sbi)
 	sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
 }
 
-static void detected_sysv2(struct sysv_sb_info *sbi)
+static void detected_sysv2(struct sysv_sb_info *sbi, unsigned *max_links)
 {
 	struct sysv2_super_block *sbd;
 	struct buffer_head *bh1 = sbi->s_bh1;
@@ -114,7 +114,7 @@ static void detected_sysv2(struct sysv_sb_info *sbi)
 	else
 		sbd = (struct sysv2_super_block *) bh2->b_data;
 
-	sbi->s_link_max = SYSV_LINK_MAX;
+	*max_links = SYSV_LINK_MAX;
 	sbi->s_fic_size = SYSV_NICINOD;
 	sbi->s_flc_size = SYSV_NICFREE;
 	sbi->s_sbd1 = (char *)sbd;
@@ -131,14 +131,14 @@ static void detected_sysv2(struct sysv_sb_info *sbi)
 	sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
 }
 
-static void detected_coherent(struct sysv_sb_info *sbi)
+static void detected_coherent(struct sysv_sb_info *sbi, unsigned *max_links)
 {
 	struct coh_super_block * sbd;
 	struct buffer_head *bh1 = sbi->s_bh1;
 
 	sbd = (struct coh_super_block *) bh1->b_data;
 
-	sbi->s_link_max = COH_LINK_MAX;
+	*max_links = COH_LINK_MAX;
 	sbi->s_fic_size = COH_NICINOD;
 	sbi->s_flc_size = COH_NICFREE;
 	sbi->s_sbd1 = (char *)sbd;
@@ -154,12 +154,12 @@ static void detected_coherent(struct sysv_sb_info *sbi)
 	sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize);
 }
 
-static void detected_v7(struct sysv_sb_info *sbi)
+static void detected_v7(struct sysv_sb_info *sbi, unsigned *max_links)
 {
 	struct buffer_head *bh2 = sbi->s_bh2;
 	struct v7_super_block *sbd = (struct v7_super_block *)bh2->b_data;
 
-	sbi->s_link_max = V7_LINK_MAX;
+	*max_links = V7_LINK_MAX;
 	sbi->s_fic_size = V7_NICINOD;
 	sbi->s_flc_size = V7_NICFREE;
 	sbi->s_sbd1 = (char *)sbd;
@@ -290,7 +290,7 @@ static char *flavour_names[] = {
 	[FSTYPE_AFS]	= "AFS",
 };
 
-static void (*flavour_setup[])(struct sysv_sb_info *) = {
+static void (*flavour_setup[])(struct sysv_sb_info *, unsigned *) = {
 	[FSTYPE_XENIX]	= detected_xenix,
 	[FSTYPE_SYSV4]	= detected_sysv4,
 	[FSTYPE_SYSV2]	= detected_sysv2,
@@ -310,7 +310,7 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
 
 	sbi->s_firstinodezone = 2;
 
-	flavour_setup[sbi->s_type](sbi);
+	flavour_setup[sbi->s_type](sbi, &sb->s_max_links);
 	
 	sbi->s_truncate = 1;
 	sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone;
@@ -341,9 +341,8 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
 		printk("SysV FS: get root inode failed\n");
 		return 0;
 	}
-	sb->s_root = d_alloc_root(root_inode);
+	sb->s_root = d_make_root(root_inode);
 	if (!sb->s_root) {
-		iput(root_inode);
 		printk("SysV FS: get root dentry failed\n");
 		return 0;
 	}
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 0e4b821..11b0767 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -24,7 +24,6 @@ struct sysv_sb_info {
 	char	       s_bytesex;	/* bytesex (le/be/pdp) */
 	char	       s_truncate;	/* if 1: names > SYSV_NAMELEN chars are truncated */
 					/* if 0: they are disallowed (ENAMETOOLONG) */
-	nlink_t        s_link_max;	/* max number of hard links to a file */
 	unsigned int   s_inodes_per_block;	/* number of inodes per block */
 	unsigned int   s_inodes_per_block_1;	/* inodes_per_block - 1 */
 	unsigned int   s_inodes_per_block_bits;	/* log2(inodes_per_block) */
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index f922cba..1934084 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -36,7 +36,7 @@
 
 #ifdef CONFIG_UBIFS_FS_DEBUG
 
-DEFINE_SPINLOCK(dbg_lock);
+static DEFINE_SPINLOCK(dbg_lock);
 
 static const char *get_key_fmt(int fmt)
 {
@@ -221,15 +221,15 @@ const char *dbg_jhead(int jhead)
 
 static void dump_ch(const struct ubifs_ch *ch)
 {
-	printk(KERN_DEBUG "\tmagic          %#x\n", le32_to_cpu(ch->magic));
-	printk(KERN_DEBUG "\tcrc            %#x\n", le32_to_cpu(ch->crc));
-	printk(KERN_DEBUG "\tnode_type      %d (%s)\n", ch->node_type,
+	printk(KERN_ERR "\tmagic          %#x\n", le32_to_cpu(ch->magic));
+	printk(KERN_ERR "\tcrc            %#x\n", le32_to_cpu(ch->crc));
+	printk(KERN_ERR "\tnode_type      %d (%s)\n", ch->node_type,
 	       dbg_ntype(ch->node_type));
-	printk(KERN_DEBUG "\tgroup_type     %d (%s)\n", ch->group_type,
+	printk(KERN_ERR "\tgroup_type     %d (%s)\n", ch->group_type,
 	       dbg_gtype(ch->group_type));
-	printk(KERN_DEBUG "\tsqnum          %llu\n",
+	printk(KERN_ERR "\tsqnum          %llu\n",
 	       (unsigned long long)le64_to_cpu(ch->sqnum));
-	printk(KERN_DEBUG "\tlen            %u\n", le32_to_cpu(ch->len));
+	printk(KERN_ERR "\tlen            %u\n", le32_to_cpu(ch->len));
 }
 
 void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
@@ -240,43 +240,43 @@ void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
 	struct ubifs_dent_node *dent, *pdent = NULL;
 	int count = 2;
 
-	printk(KERN_DEBUG "Dump in-memory inode:");
-	printk(KERN_DEBUG "\tinode          %lu\n", inode->i_ino);
-	printk(KERN_DEBUG "\tsize           %llu\n",
+	printk(KERN_ERR "Dump in-memory inode:");
+	printk(KERN_ERR "\tinode          %lu\n", inode->i_ino);
+	printk(KERN_ERR "\tsize           %llu\n",
 	       (unsigned long long)i_size_read(inode));
-	printk(KERN_DEBUG "\tnlink          %u\n", inode->i_nlink);
-	printk(KERN_DEBUG "\tuid            %u\n", (unsigned int)inode->i_uid);
-	printk(KERN_DEBUG "\tgid            %u\n", (unsigned int)inode->i_gid);
-	printk(KERN_DEBUG "\tatime          %u.%u\n",
+	printk(KERN_ERR "\tnlink          %u\n", inode->i_nlink);
+	printk(KERN_ERR "\tuid            %u\n", (unsigned int)inode->i_uid);
+	printk(KERN_ERR "\tgid            %u\n", (unsigned int)inode->i_gid);
+	printk(KERN_ERR "\tatime          %u.%u\n",
 	       (unsigned int)inode->i_atime.tv_sec,
 	       (unsigned int)inode->i_atime.tv_nsec);
-	printk(KERN_DEBUG "\tmtime          %u.%u\n",
+	printk(KERN_ERR "\tmtime          %u.%u\n",
 	       (unsigned int)inode->i_mtime.tv_sec,
 	       (unsigned int)inode->i_mtime.tv_nsec);
-	printk(KERN_DEBUG "\tctime          %u.%u\n",
+	printk(KERN_ERR "\tctime          %u.%u\n",
 	       (unsigned int)inode->i_ctime.tv_sec,
 	       (unsigned int)inode->i_ctime.tv_nsec);
-	printk(KERN_DEBUG "\tcreat_sqnum    %llu\n", ui->creat_sqnum);
-	printk(KERN_DEBUG "\txattr_size     %u\n", ui->xattr_size);
-	printk(KERN_DEBUG "\txattr_cnt      %u\n", ui->xattr_cnt);
-	printk(KERN_DEBUG "\txattr_names    %u\n", ui->xattr_names);
-	printk(KERN_DEBUG "\tdirty          %u\n", ui->dirty);
-	printk(KERN_DEBUG "\txattr          %u\n", ui->xattr);
-	printk(KERN_DEBUG "\tbulk_read      %u\n", ui->xattr);
-	printk(KERN_DEBUG "\tsynced_i_size  %llu\n",
+	printk(KERN_ERR "\tcreat_sqnum    %llu\n", ui->creat_sqnum);
+	printk(KERN_ERR "\txattr_size     %u\n", ui->xattr_size);
+	printk(KERN_ERR "\txattr_cnt      %u\n", ui->xattr_cnt);
+	printk(KERN_ERR "\txattr_names    %u\n", ui->xattr_names);
+	printk(KERN_ERR "\tdirty          %u\n", ui->dirty);
+	printk(KERN_ERR "\txattr          %u\n", ui->xattr);
+	printk(KERN_ERR "\tbulk_read      %u\n", ui->xattr);
+	printk(KERN_ERR "\tsynced_i_size  %llu\n",
 	       (unsigned long long)ui->synced_i_size);
-	printk(KERN_DEBUG "\tui_size        %llu\n",
+	printk(KERN_ERR "\tui_size        %llu\n",
 	       (unsigned long long)ui->ui_size);
-	printk(KERN_DEBUG "\tflags          %d\n", ui->flags);
-	printk(KERN_DEBUG "\tcompr_type     %d\n", ui->compr_type);
-	printk(KERN_DEBUG "\tlast_page_read %lu\n", ui->last_page_read);
-	printk(KERN_DEBUG "\tread_in_a_row  %lu\n", ui->read_in_a_row);
-	printk(KERN_DEBUG "\tdata_len       %d\n", ui->data_len);
+	printk(KERN_ERR "\tflags          %d\n", ui->flags);
+	printk(KERN_ERR "\tcompr_type     %d\n", ui->compr_type);
+	printk(KERN_ERR "\tlast_page_read %lu\n", ui->last_page_read);
+	printk(KERN_ERR "\tread_in_a_row  %lu\n", ui->read_in_a_row);
+	printk(KERN_ERR "\tdata_len       %d\n", ui->data_len);
 
 	if (!S_ISDIR(inode->i_mode))
 		return;
 
-	printk(KERN_DEBUG "List of directory entries:\n");
+	printk(KERN_ERR "List of directory entries:\n");
 	ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
 
 	lowest_dent_key(c, &key, inode->i_ino);
@@ -284,11 +284,11 @@ void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
 		dent = ubifs_tnc_next_ent(c, &key, &nm);
 		if (IS_ERR(dent)) {
 			if (PTR_ERR(dent) != -ENOENT)
-				printk(KERN_DEBUG "error %ld\n", PTR_ERR(dent));
+				printk(KERN_ERR "error %ld\n", PTR_ERR(dent));
 			break;
 		}
 
-		printk(KERN_DEBUG "\t%d: %s (%s)\n",
+		printk(KERN_ERR "\t%d: %s (%s)\n",
 		       count++, dent->name, get_dent_type(dent->type));
 
 		nm.name = dent->name;
@@ -312,8 +312,8 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 
 	/* If the magic is incorrect, just hexdump the first bytes */
 	if (le32_to_cpu(ch->magic) != UBIFS_NODE_MAGIC) {
-		printk(KERN_DEBUG "Not a node, first %zu bytes:", UBIFS_CH_SZ);
-		print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
+		printk(KERN_ERR "Not a node, first %zu bytes:", UBIFS_CH_SZ);
+		print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 32, 1,
 			       (void *)node, UBIFS_CH_SZ, 1);
 		return;
 	}
@@ -326,7 +326,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 	{
 		const struct ubifs_pad_node *pad = node;
 
-		printk(KERN_DEBUG "\tpad_len        %u\n",
+		printk(KERN_ERR "\tpad_len        %u\n",
 		       le32_to_cpu(pad->pad_len));
 		break;
 	}
@@ -335,50 +335,50 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 		const struct ubifs_sb_node *sup = node;
 		unsigned int sup_flags = le32_to_cpu(sup->flags);
 
-		printk(KERN_DEBUG "\tkey_hash       %d (%s)\n",
+		printk(KERN_ERR "\tkey_hash       %d (%s)\n",
 		       (int)sup->key_hash, get_key_hash(sup->key_hash));
-		printk(KERN_DEBUG "\tkey_fmt        %d (%s)\n",
+		printk(KERN_ERR "\tkey_fmt        %d (%s)\n",
 		       (int)sup->key_fmt, get_key_fmt(sup->key_fmt));
-		printk(KERN_DEBUG "\tflags          %#x\n", sup_flags);
-		printk(KERN_DEBUG "\t  big_lpt      %u\n",
+		printk(KERN_ERR "\tflags          %#x\n", sup_flags);
+		printk(KERN_ERR "\t  big_lpt      %u\n",
 		       !!(sup_flags & UBIFS_FLG_BIGLPT));
-		printk(KERN_DEBUG "\t  space_fixup  %u\n",
+		printk(KERN_ERR "\t  space_fixup  %u\n",
 		       !!(sup_flags & UBIFS_FLG_SPACE_FIXUP));
-		printk(KERN_DEBUG "\tmin_io_size    %u\n",
+		printk(KERN_ERR "\tmin_io_size    %u\n",
 		       le32_to_cpu(sup->min_io_size));
-		printk(KERN_DEBUG "\tleb_size       %u\n",
+		printk(KERN_ERR "\tleb_size       %u\n",
 		       le32_to_cpu(sup->leb_size));
-		printk(KERN_DEBUG "\tleb_cnt        %u\n",
+		printk(KERN_ERR "\tleb_cnt        %u\n",
 		       le32_to_cpu(sup->leb_cnt));
-		printk(KERN_DEBUG "\tmax_leb_cnt    %u\n",
+		printk(KERN_ERR "\tmax_leb_cnt    %u\n",
 		       le32_to_cpu(sup->max_leb_cnt));
-		printk(KERN_DEBUG "\tmax_bud_bytes  %llu\n",
+		printk(KERN_ERR "\tmax_bud_bytes  %llu\n",
 		       (unsigned long long)le64_to_cpu(sup->max_bud_bytes));
-		printk(KERN_DEBUG "\tlog_lebs       %u\n",
+		printk(KERN_ERR "\tlog_lebs       %u\n",
 		       le32_to_cpu(sup->log_lebs));
-		printk(KERN_DEBUG "\tlpt_lebs       %u\n",
+		printk(KERN_ERR "\tlpt_lebs       %u\n",
 		       le32_to_cpu(sup->lpt_lebs));
-		printk(KERN_DEBUG "\torph_lebs      %u\n",
+		printk(KERN_ERR "\torph_lebs      %u\n",
 		       le32_to_cpu(sup->orph_lebs));
-		printk(KERN_DEBUG "\tjhead_cnt      %u\n",
+		printk(KERN_ERR "\tjhead_cnt      %u\n",
 		       le32_to_cpu(sup->jhead_cnt));
-		printk(KERN_DEBUG "\tfanout         %u\n",
+		printk(KERN_ERR "\tfanout         %u\n",
 		       le32_to_cpu(sup->fanout));
-		printk(KERN_DEBUG "\tlsave_cnt      %u\n",
+		printk(KERN_ERR "\tlsave_cnt      %u\n",
 		       le32_to_cpu(sup->lsave_cnt));
-		printk(KERN_DEBUG "\tdefault_compr  %u\n",
+		printk(KERN_ERR "\tdefault_compr  %u\n",
 		       (int)le16_to_cpu(sup->default_compr));
-		printk(KERN_DEBUG "\trp_size        %llu\n",
+		printk(KERN_ERR "\trp_size        %llu\n",
 		       (unsigned long long)le64_to_cpu(sup->rp_size));
-		printk(KERN_DEBUG "\trp_uid         %u\n",
+		printk(KERN_ERR "\trp_uid         %u\n",
 		       le32_to_cpu(sup->rp_uid));
-		printk(KERN_DEBUG "\trp_gid         %u\n",
+		printk(KERN_ERR "\trp_gid         %u\n",
 		       le32_to_cpu(sup->rp_gid));
-		printk(KERN_DEBUG "\tfmt_version    %u\n",
+		printk(KERN_ERR "\tfmt_version    %u\n",
 		       le32_to_cpu(sup->fmt_version));
-		printk(KERN_DEBUG "\ttime_gran      %u\n",
+		printk(KERN_ERR "\ttime_gran      %u\n",
 		       le32_to_cpu(sup->time_gran));
-		printk(KERN_DEBUG "\tUUID           %pUB\n",
+		printk(KERN_ERR "\tUUID           %pUB\n",
 		       sup->uuid);
 		break;
 	}
@@ -386,61 +386,61 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 	{
 		const struct ubifs_mst_node *mst = node;
 
-		printk(KERN_DEBUG "\thighest_inum   %llu\n",
+		printk(KERN_ERR "\thighest_inum   %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->highest_inum));
-		printk(KERN_DEBUG "\tcommit number  %llu\n",
+		printk(KERN_ERR "\tcommit number  %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->cmt_no));
-		printk(KERN_DEBUG "\tflags          %#x\n",
+		printk(KERN_ERR "\tflags          %#x\n",
 		       le32_to_cpu(mst->flags));
-		printk(KERN_DEBUG "\tlog_lnum       %u\n",
+		printk(KERN_ERR "\tlog_lnum       %u\n",
 		       le32_to_cpu(mst->log_lnum));
-		printk(KERN_DEBUG "\troot_lnum      %u\n",
+		printk(KERN_ERR "\troot_lnum      %u\n",
 		       le32_to_cpu(mst->root_lnum));
-		printk(KERN_DEBUG "\troot_offs      %u\n",
+		printk(KERN_ERR "\troot_offs      %u\n",
 		       le32_to_cpu(mst->root_offs));
-		printk(KERN_DEBUG "\troot_len       %u\n",
+		printk(KERN_ERR "\troot_len       %u\n",
 		       le32_to_cpu(mst->root_len));
-		printk(KERN_DEBUG "\tgc_lnum        %u\n",
+		printk(KERN_ERR "\tgc_lnum        %u\n",
 		       le32_to_cpu(mst->gc_lnum));
-		printk(KERN_DEBUG "\tihead_lnum     %u\n",
+		printk(KERN_ERR "\tihead_lnum     %u\n",
 		       le32_to_cpu(mst->ihead_lnum));
-		printk(KERN_DEBUG "\tihead_offs     %u\n",
+		printk(KERN_ERR "\tihead_offs     %u\n",
 		       le32_to_cpu(mst->ihead_offs));
-		printk(KERN_DEBUG "\tindex_size     %llu\n",
+		printk(KERN_ERR "\tindex_size     %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->index_size));
-		printk(KERN_DEBUG "\tlpt_lnum       %u\n",
+		printk(KERN_ERR "\tlpt_lnum       %u\n",
 		       le32_to_cpu(mst->lpt_lnum));
-		printk(KERN_DEBUG "\tlpt_offs       %u\n",
+		printk(KERN_ERR "\tlpt_offs       %u\n",
 		       le32_to_cpu(mst->lpt_offs));
-		printk(KERN_DEBUG "\tnhead_lnum     %u\n",
+		printk(KERN_ERR "\tnhead_lnum     %u\n",
 		       le32_to_cpu(mst->nhead_lnum));
-		printk(KERN_DEBUG "\tnhead_offs     %u\n",
+		printk(KERN_ERR "\tnhead_offs     %u\n",
 		       le32_to_cpu(mst->nhead_offs));
-		printk(KERN_DEBUG "\tltab_lnum      %u\n",
+		printk(KERN_ERR "\tltab_lnum      %u\n",
 		       le32_to_cpu(mst->ltab_lnum));
-		printk(KERN_DEBUG "\tltab_offs      %u\n",
+		printk(KERN_ERR "\tltab_offs      %u\n",
 		       le32_to_cpu(mst->ltab_offs));
-		printk(KERN_DEBUG "\tlsave_lnum     %u\n",
+		printk(KERN_ERR "\tlsave_lnum     %u\n",
 		       le32_to_cpu(mst->lsave_lnum));
-		printk(KERN_DEBUG "\tlsave_offs     %u\n",
+		printk(KERN_ERR "\tlsave_offs     %u\n",
 		       le32_to_cpu(mst->lsave_offs));
-		printk(KERN_DEBUG "\tlscan_lnum     %u\n",
+		printk(KERN_ERR "\tlscan_lnum     %u\n",
 		       le32_to_cpu(mst->lscan_lnum));
-		printk(KERN_DEBUG "\tleb_cnt        %u\n",
+		printk(KERN_ERR "\tleb_cnt        %u\n",
 		       le32_to_cpu(mst->leb_cnt));
-		printk(KERN_DEBUG "\tempty_lebs     %u\n",
+		printk(KERN_ERR "\tempty_lebs     %u\n",
 		       le32_to_cpu(mst->empty_lebs));
-		printk(KERN_DEBUG "\tidx_lebs       %u\n",
+		printk(KERN_ERR "\tidx_lebs       %u\n",
 		       le32_to_cpu(mst->idx_lebs));
-		printk(KERN_DEBUG "\ttotal_free     %llu\n",
+		printk(KERN_ERR "\ttotal_free     %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->total_free));
-		printk(KERN_DEBUG "\ttotal_dirty    %llu\n",
+		printk(KERN_ERR "\ttotal_dirty    %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->total_dirty));
-		printk(KERN_DEBUG "\ttotal_used     %llu\n",
+		printk(KERN_ERR "\ttotal_used     %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->total_used));
-		printk(KERN_DEBUG "\ttotal_dead     %llu\n",
+		printk(KERN_ERR "\ttotal_dead     %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->total_dead));
-		printk(KERN_DEBUG "\ttotal_dark     %llu\n",
+		printk(KERN_ERR "\ttotal_dark     %llu\n",
 		       (unsigned long long)le64_to_cpu(mst->total_dark));
 		break;
 	}
@@ -448,11 +448,11 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 	{
 		const struct ubifs_ref_node *ref = node;
 
-		printk(KERN_DEBUG "\tlnum           %u\n",
+		printk(KERN_ERR "\tlnum           %u\n",
 		       le32_to_cpu(ref->lnum));
-		printk(KERN_DEBUG "\toffs           %u\n",
+		printk(KERN_ERR "\toffs           %u\n",
 		       le32_to_cpu(ref->offs));
-		printk(KERN_DEBUG "\tjhead          %u\n",
+		printk(KERN_ERR "\tjhead          %u\n",
 		       le32_to_cpu(ref->jhead));
 		break;
 	}
@@ -461,40 +461,40 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 		const struct ubifs_ino_node *ino = node;
 
 		key_read(c, &ino->key, &key);
-		printk(KERN_DEBUG "\tkey            %s\n",
+		printk(KERN_ERR "\tkey            %s\n",
 		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
-		printk(KERN_DEBUG "\tcreat_sqnum    %llu\n",
+		printk(KERN_ERR "\tcreat_sqnum    %llu\n",
 		       (unsigned long long)le64_to_cpu(ino->creat_sqnum));
-		printk(KERN_DEBUG "\tsize           %llu\n",
+		printk(KERN_ERR "\tsize           %llu\n",
 		       (unsigned long long)le64_to_cpu(ino->size));
-		printk(KERN_DEBUG "\tnlink          %u\n",
+		printk(KERN_ERR "\tnlink          %u\n",
 		       le32_to_cpu(ino->nlink));
-		printk(KERN_DEBUG "\tatime          %lld.%u\n",
+		printk(KERN_ERR "\tatime          %lld.%u\n",
 		       (long long)le64_to_cpu(ino->atime_sec),
 		       le32_to_cpu(ino->atime_nsec));
-		printk(KERN_DEBUG "\tmtime          %lld.%u\n",
+		printk(KERN_ERR "\tmtime          %lld.%u\n",
 		       (long long)le64_to_cpu(ino->mtime_sec),
 		       le32_to_cpu(ino->mtime_nsec));
-		printk(KERN_DEBUG "\tctime          %lld.%u\n",
+		printk(KERN_ERR "\tctime          %lld.%u\n",
 		       (long long)le64_to_cpu(ino->ctime_sec),
 		       le32_to_cpu(ino->ctime_nsec));
-		printk(KERN_DEBUG "\tuid            %u\n",
+		printk(KERN_ERR "\tuid            %u\n",
 		       le32_to_cpu(ino->uid));
-		printk(KERN_DEBUG "\tgid            %u\n",
+		printk(KERN_ERR "\tgid            %u\n",
 		       le32_to_cpu(ino->gid));
-		printk(KERN_DEBUG "\tmode           %u\n",
+		printk(KERN_ERR "\tmode           %u\n",
 		       le32_to_cpu(ino->mode));
-		printk(KERN_DEBUG "\tflags          %#x\n",
+		printk(KERN_ERR "\tflags          %#x\n",
 		       le32_to_cpu(ino->flags));
-		printk(KERN_DEBUG "\txattr_cnt      %u\n",
+		printk(KERN_ERR "\txattr_cnt      %u\n",
 		       le32_to_cpu(ino->xattr_cnt));
-		printk(KERN_DEBUG "\txattr_size     %u\n",
+		printk(KERN_ERR "\txattr_size     %u\n",
 		       le32_to_cpu(ino->xattr_size));
-		printk(KERN_DEBUG "\txattr_names    %u\n",
+		printk(KERN_ERR "\txattr_names    %u\n",
 		       le32_to_cpu(ino->xattr_names));
-		printk(KERN_DEBUG "\tcompr_type     %#x\n",
+		printk(KERN_ERR "\tcompr_type     %#x\n",
 		       (int)le16_to_cpu(ino->compr_type));
-		printk(KERN_DEBUG "\tdata len       %u\n",
+		printk(KERN_ERR "\tdata len       %u\n",
 		       le32_to_cpu(ino->data_len));
 		break;
 	}
@@ -505,16 +505,16 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 		int nlen = le16_to_cpu(dent->nlen);
 
 		key_read(c, &dent->key, &key);
-		printk(KERN_DEBUG "\tkey            %s\n",
+		printk(KERN_ERR "\tkey            %s\n",
 		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
-		printk(KERN_DEBUG "\tinum           %llu\n",
+		printk(KERN_ERR "\tinum           %llu\n",
 		       (unsigned long long)le64_to_cpu(dent->inum));
-		printk(KERN_DEBUG "\ttype           %d\n", (int)dent->type);
-		printk(KERN_DEBUG "\tnlen           %d\n", nlen);
-		printk(KERN_DEBUG "\tname           ");
+		printk(KERN_ERR "\ttype           %d\n", (int)dent->type);
+		printk(KERN_ERR "\tnlen           %d\n", nlen);
+		printk(KERN_ERR "\tname           ");
 
 		if (nlen > UBIFS_MAX_NLEN)
-			printk(KERN_DEBUG "(bad name length, not printing, "
+			printk(KERN_ERR "(bad name length, not printing, "
 					  "bad or corrupted node)");
 		else {
 			for (i = 0; i < nlen && dent->name[i]; i++)
@@ -530,16 +530,16 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 		int dlen = le32_to_cpu(ch->len) - UBIFS_DATA_NODE_SZ;
 
 		key_read(c, &dn->key, &key);
-		printk(KERN_DEBUG "\tkey            %s\n",
+		printk(KERN_ERR "\tkey            %s\n",
 		       dbg_snprintf_key(c, &key, key_buf, DBG_KEY_BUF_LEN));
-		printk(KERN_DEBUG "\tsize           %u\n",
+		printk(KERN_ERR "\tsize           %u\n",
 		       le32_to_cpu(dn->size));
-		printk(KERN_DEBUG "\tcompr_typ      %d\n",
+		printk(KERN_ERR "\tcompr_typ      %d\n",
 		       (int)le16_to_cpu(dn->compr_type));
-		printk(KERN_DEBUG "\tdata size      %d\n",
+		printk(KERN_ERR "\tdata size      %d\n",
 		       dlen);
-		printk(KERN_DEBUG "\tdata:\n");
-		print_hex_dump(KERN_DEBUG, "\t", DUMP_PREFIX_OFFSET, 32, 1,
+		printk(KERN_ERR "\tdata:\n");
+		print_hex_dump(KERN_ERR, "\t", DUMP_PREFIX_OFFSET, 32, 1,
 			       (void *)&dn->data, dlen, 0);
 		break;
 	}
@@ -547,11 +547,11 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 	{
 		const struct ubifs_trun_node *trun = node;
 
-		printk(KERN_DEBUG "\tinum           %u\n",
+		printk(KERN_ERR "\tinum           %u\n",
 		       le32_to_cpu(trun->inum));
-		printk(KERN_DEBUG "\told_size       %llu\n",
+		printk(KERN_ERR "\told_size       %llu\n",
 		       (unsigned long long)le64_to_cpu(trun->old_size));
-		printk(KERN_DEBUG "\tnew_size       %llu\n",
+		printk(KERN_ERR "\tnew_size       %llu\n",
 		       (unsigned long long)le64_to_cpu(trun->new_size));
 		break;
 	}
@@ -560,17 +560,17 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 		const struct ubifs_idx_node *idx = node;
 
 		n = le16_to_cpu(idx->child_cnt);
-		printk(KERN_DEBUG "\tchild_cnt      %d\n", n);
-		printk(KERN_DEBUG "\tlevel          %d\n",
+		printk(KERN_ERR "\tchild_cnt      %d\n", n);
+		printk(KERN_ERR "\tlevel          %d\n",
 		       (int)le16_to_cpu(idx->level));
-		printk(KERN_DEBUG "\tBranches:\n");
+		printk(KERN_ERR "\tBranches:\n");
 
 		for (i = 0; i < n && i < c->fanout - 1; i++) {
 			const struct ubifs_branch *br;
 
 			br = ubifs_idx_branch(c, idx, i);
 			key_read(c, &br->key, &key);
-			printk(KERN_DEBUG "\t%d: LEB %d:%d len %d key %s\n",
+			printk(KERN_ERR "\t%d: LEB %d:%d len %d key %s\n",
 			       i, le32_to_cpu(br->lnum), le32_to_cpu(br->offs),
 			       le32_to_cpu(br->len),
 			       dbg_snprintf_key(c, &key, key_buf,
@@ -584,20 +584,20 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 	{
 		const struct ubifs_orph_node *orph = node;
 
-		printk(KERN_DEBUG "\tcommit number  %llu\n",
+		printk(KERN_ERR "\tcommit number  %llu\n",
 		       (unsigned long long)
 				le64_to_cpu(orph->cmt_no) & LLONG_MAX);
-		printk(KERN_DEBUG "\tlast node flag %llu\n",
+		printk(KERN_ERR "\tlast node flag %llu\n",
 		       (unsigned long long)(le64_to_cpu(orph->cmt_no)) >> 63);
 		n = (le32_to_cpu(ch->len) - UBIFS_ORPH_NODE_SZ) >> 3;
-		printk(KERN_DEBUG "\t%d orphan inode numbers:\n", n);
+		printk(KERN_ERR "\t%d orphan inode numbers:\n", n);
 		for (i = 0; i < n; i++)
-			printk(KERN_DEBUG "\t  ino %llu\n",
+			printk(KERN_ERR "\t  ino %llu\n",
 			       (unsigned long long)le64_to_cpu(orph->inos[i]));
 		break;
 	}
 	default:
-		printk(KERN_DEBUG "node type %d was not recognized\n",
+		printk(KERN_ERR "node type %d was not recognized\n",
 		       (int)ch->node_type);
 	}
 	spin_unlock(&dbg_lock);
@@ -606,16 +606,16 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
 void dbg_dump_budget_req(const struct ubifs_budget_req *req)
 {
 	spin_lock(&dbg_lock);
-	printk(KERN_DEBUG "Budgeting request: new_ino %d, dirtied_ino %d\n",
+	printk(KERN_ERR "Budgeting request: new_ino %d, dirtied_ino %d\n",
 	       req->new_ino, req->dirtied_ino);
-	printk(KERN_DEBUG "\tnew_ino_d   %d, dirtied_ino_d %d\n",
+	printk(KERN_ERR "\tnew_ino_d   %d, dirtied_ino_d %d\n",
 	       req->new_ino_d, req->dirtied_ino_d);
-	printk(KERN_DEBUG "\tnew_page    %d, dirtied_page %d\n",
+	printk(KERN_ERR "\tnew_page    %d, dirtied_page %d\n",
 	       req->new_page, req->dirtied_page);
-	printk(KERN_DEBUG "\tnew_dent    %d, mod_dent     %d\n",
+	printk(KERN_ERR "\tnew_dent    %d, mod_dent     %d\n",
 	       req->new_dent, req->mod_dent);
-	printk(KERN_DEBUG "\tidx_growth  %d\n", req->idx_growth);
-	printk(KERN_DEBUG "\tdata_growth %d dd_growth     %d\n",
+	printk(KERN_ERR "\tidx_growth  %d\n", req->idx_growth);
+	printk(KERN_ERR "\tdata_growth %d dd_growth     %d\n",
 	       req->data_growth, req->dd_growth);
 	spin_unlock(&dbg_lock);
 }
@@ -623,12 +623,12 @@ void dbg_dump_budget_req(const struct ubifs_budget_req *req)
 void dbg_dump_lstats(const struct ubifs_lp_stats *lst)
 {
 	spin_lock(&dbg_lock);
-	printk(KERN_DEBUG "(pid %d) Lprops statistics: empty_lebs %d, "
+	printk(KERN_ERR "(pid %d) Lprops statistics: empty_lebs %d, "
 	       "idx_lebs  %d\n", current->pid, lst->empty_lebs, lst->idx_lebs);
-	printk(KERN_DEBUG "\ttaken_empty_lebs %d, total_free %lld, "
+	printk(KERN_ERR "\ttaken_empty_lebs %d, total_free %lld, "
 	       "total_dirty %lld\n", lst->taken_empty_lebs, lst->total_free,
 	       lst->total_dirty);
-	printk(KERN_DEBUG "\ttotal_used %lld, total_dark %lld, "
+	printk(KERN_ERR "\ttotal_used %lld, total_dark %lld, "
 	       "total_dead %lld\n", lst->total_used, lst->total_dark,
 	       lst->total_dead);
 	spin_unlock(&dbg_lock);
@@ -644,21 +644,21 @@ void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
 
 	spin_lock(&c->space_lock);
 	spin_lock(&dbg_lock);
-	printk(KERN_DEBUG "(pid %d) Budgeting info: data budget sum %lld, "
+	printk(KERN_ERR "(pid %d) Budgeting info: data budget sum %lld, "
 	       "total budget sum %lld\n", current->pid,
 	       bi->data_growth + bi->dd_growth,
 	       bi->data_growth + bi->dd_growth + bi->idx_growth);
-	printk(KERN_DEBUG "\tbudg_data_growth %lld, budg_dd_growth %lld, "
+	printk(KERN_ERR "\tbudg_data_growth %lld, budg_dd_growth %lld, "
 	       "budg_idx_growth %lld\n", bi->data_growth, bi->dd_growth,
 	       bi->idx_growth);
-	printk(KERN_DEBUG "\tmin_idx_lebs %d, old_idx_sz %llu, "
+	printk(KERN_ERR "\tmin_idx_lebs %d, old_idx_sz %llu, "
 	       "uncommitted_idx %lld\n", bi->min_idx_lebs, bi->old_idx_sz,
 	       bi->uncommitted_idx);
-	printk(KERN_DEBUG "\tpage_budget %d, inode_budget %d, dent_budget %d\n",
+	printk(KERN_ERR "\tpage_budget %d, inode_budget %d, dent_budget %d\n",
 	       bi->page_budget, bi->inode_budget, bi->dent_budget);
-	printk(KERN_DEBUG "\tnospace %u, nospace_rp %u\n",
+	printk(KERN_ERR "\tnospace %u, nospace_rp %u\n",
 	       bi->nospace, bi->nospace_rp);
-	printk(KERN_DEBUG "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
+	printk(KERN_ERR "\tdark_wm %d, dead_wm %d, max_idx_node_sz %d\n",
 	       c->dark_wm, c->dead_wm, c->max_idx_node_sz);
 
 	if (bi != &c->bi)
@@ -669,38 +669,38 @@ void dbg_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi)
 		 */
 		goto out_unlock;
 
-	printk(KERN_DEBUG "\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n",
+	printk(KERN_ERR "\tfreeable_cnt %d, calc_idx_sz %lld, idx_gc_cnt %d\n",
 	       c->freeable_cnt, c->calc_idx_sz, c->idx_gc_cnt);
-	printk(KERN_DEBUG "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, "
+	printk(KERN_ERR "\tdirty_pg_cnt %ld, dirty_zn_cnt %ld, "
 	       "clean_zn_cnt %ld\n", atomic_long_read(&c->dirty_pg_cnt),
 	       atomic_long_read(&c->dirty_zn_cnt),
 	       atomic_long_read(&c->clean_zn_cnt));
-	printk(KERN_DEBUG "\tgc_lnum %d, ihead_lnum %d\n",
+	printk(KERN_ERR "\tgc_lnum %d, ihead_lnum %d\n",
 	       c->gc_lnum, c->ihead_lnum);
 
 	/* If we are in R/O mode, journal heads do not exist */
 	if (c->jheads)
 		for (i = 0; i < c->jhead_cnt; i++)
-			printk(KERN_DEBUG "\tjhead %s\t LEB %d\n",
+			printk(KERN_ERR "\tjhead %s\t LEB %d\n",
 			       dbg_jhead(c->jheads[i].wbuf.jhead),
 			       c->jheads[i].wbuf.lnum);
 	for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
 		bud = rb_entry(rb, struct ubifs_bud, rb);
-		printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum);
+		printk(KERN_ERR "\tbud LEB %d\n", bud->lnum);
 	}
 	list_for_each_entry(bud, &c->old_buds, list)
-		printk(KERN_DEBUG "\told bud LEB %d\n", bud->lnum);
+		printk(KERN_ERR "\told bud LEB %d\n", bud->lnum);
 	list_for_each_entry(idx_gc, &c->idx_gc, list)
-		printk(KERN_DEBUG "\tGC'ed idx LEB %d unmap %d\n",
+		printk(KERN_ERR "\tGC'ed idx LEB %d unmap %d\n",
 		       idx_gc->lnum, idx_gc->unmap);
-	printk(KERN_DEBUG "\tcommit state %d\n", c->cmt_state);
+	printk(KERN_ERR "\tcommit state %d\n", c->cmt_state);
 
 	/* Print budgeting predictions */
 	available = ubifs_calc_available(c, c->bi.min_idx_lebs);
 	outstanding = c->bi.data_growth + c->bi.dd_growth;
 	free = ubifs_get_free_space_nolock(c);
-	printk(KERN_DEBUG "Budgeting predictions:\n");
-	printk(KERN_DEBUG "\tavailable: %lld, outstanding %lld, free %lld\n",
+	printk(KERN_ERR "Budgeting predictions:\n");
+	printk(KERN_ERR "\tavailable: %lld, outstanding %lld, free %lld\n",
 	       available, outstanding, free);
 out_unlock:
 	spin_unlock(&dbg_lock);
@@ -720,11 +720,11 @@ void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
 		dark = ubifs_calc_dark(c, spc);
 
 	if (lp->flags & LPROPS_INDEX)
-		printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d "
+		printk(KERN_ERR "LEB %-7d free %-8d dirty %-8d used %-8d "
 		       "free + dirty %-8d flags %#x (", lp->lnum, lp->free,
 		       lp->dirty, c->leb_size - spc, spc, lp->flags);
 	else
-		printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d "
+		printk(KERN_ERR "LEB %-7d free %-8d dirty %-8d used %-8d "
 		       "free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d "
 		       "flags %#-4x (", lp->lnum, lp->free, lp->dirty,
 		       c->leb_size - spc, spc, dark, dead,
@@ -807,7 +807,7 @@ void dbg_dump_lprops(struct ubifs_info *c)
 	struct ubifs_lprops lp;
 	struct ubifs_lp_stats lst;
 
-	printk(KERN_DEBUG "(pid %d) start dumping LEB properties\n",
+	printk(KERN_ERR "(pid %d) start dumping LEB properties\n",
 	       current->pid);
 	ubifs_get_lp_stats(c, &lst);
 	dbg_dump_lstats(&lst);
@@ -819,7 +819,7 @@ void dbg_dump_lprops(struct ubifs_info *c)
 
 		dbg_dump_lprop(c, &lp);
 	}
-	printk(KERN_DEBUG "(pid %d) finish dumping LEB properties\n",
+	printk(KERN_ERR "(pid %d) finish dumping LEB properties\n",
 	       current->pid);
 }
 
@@ -828,35 +828,35 @@ void dbg_dump_lpt_info(struct ubifs_info *c)
 	int i;
 
 	spin_lock(&dbg_lock);
-	printk(KERN_DEBUG "(pid %d) dumping LPT information\n", current->pid);
-	printk(KERN_DEBUG "\tlpt_sz:        %lld\n", c->lpt_sz);
-	printk(KERN_DEBUG "\tpnode_sz:      %d\n", c->pnode_sz);
-	printk(KERN_DEBUG "\tnnode_sz:      %d\n", c->nnode_sz);
-	printk(KERN_DEBUG "\tltab_sz:       %d\n", c->ltab_sz);
-	printk(KERN_DEBUG "\tlsave_sz:      %d\n", c->lsave_sz);
-	printk(KERN_DEBUG "\tbig_lpt:       %d\n", c->big_lpt);
-	printk(KERN_DEBUG "\tlpt_hght:      %d\n", c->lpt_hght);
-	printk(KERN_DEBUG "\tpnode_cnt:     %d\n", c->pnode_cnt);
-	printk(KERN_DEBUG "\tnnode_cnt:     %d\n", c->nnode_cnt);
-	printk(KERN_DEBUG "\tdirty_pn_cnt:  %d\n", c->dirty_pn_cnt);
-	printk(KERN_DEBUG "\tdirty_nn_cnt:  %d\n", c->dirty_nn_cnt);
-	printk(KERN_DEBUG "\tlsave_cnt:     %d\n", c->lsave_cnt);
-	printk(KERN_DEBUG "\tspace_bits:    %d\n", c->space_bits);
-	printk(KERN_DEBUG "\tlpt_lnum_bits: %d\n", c->lpt_lnum_bits);
-	printk(KERN_DEBUG "\tlpt_offs_bits: %d\n", c->lpt_offs_bits);
-	printk(KERN_DEBUG "\tlpt_spc_bits:  %d\n", c->lpt_spc_bits);
-	printk(KERN_DEBUG "\tpcnt_bits:     %d\n", c->pcnt_bits);
-	printk(KERN_DEBUG "\tlnum_bits:     %d\n", c->lnum_bits);
-	printk(KERN_DEBUG "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
-	printk(KERN_DEBUG "\tLPT head is at %d:%d\n",
+	printk(KERN_ERR "(pid %d) dumping LPT information\n", current->pid);
+	printk(KERN_ERR "\tlpt_sz:        %lld\n", c->lpt_sz);
+	printk(KERN_ERR "\tpnode_sz:      %d\n", c->pnode_sz);
+	printk(KERN_ERR "\tnnode_sz:      %d\n", c->nnode_sz);
+	printk(KERN_ERR "\tltab_sz:       %d\n", c->ltab_sz);
+	printk(KERN_ERR "\tlsave_sz:      %d\n", c->lsave_sz);
+	printk(KERN_ERR "\tbig_lpt:       %d\n", c->big_lpt);
+	printk(KERN_ERR "\tlpt_hght:      %d\n", c->lpt_hght);
+	printk(KERN_ERR "\tpnode_cnt:     %d\n", c->pnode_cnt);
+	printk(KERN_ERR "\tnnode_cnt:     %d\n", c->nnode_cnt);
+	printk(KERN_ERR "\tdirty_pn_cnt:  %d\n", c->dirty_pn_cnt);
+	printk(KERN_ERR "\tdirty_nn_cnt:  %d\n", c->dirty_nn_cnt);
+	printk(KERN_ERR "\tlsave_cnt:     %d\n", c->lsave_cnt);
+	printk(KERN_ERR "\tspace_bits:    %d\n", c->space_bits);
+	printk(KERN_ERR "\tlpt_lnum_bits: %d\n", c->lpt_lnum_bits);
+	printk(KERN_ERR "\tlpt_offs_bits: %d\n", c->lpt_offs_bits);
+	printk(KERN_ERR "\tlpt_spc_bits:  %d\n", c->lpt_spc_bits);
+	printk(KERN_ERR "\tpcnt_bits:     %d\n", c->pcnt_bits);
+	printk(KERN_ERR "\tlnum_bits:     %d\n", c->lnum_bits);
+	printk(KERN_ERR "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
+	printk(KERN_ERR "\tLPT head is at %d:%d\n",
 	       c->nhead_lnum, c->nhead_offs);
-	printk(KERN_DEBUG "\tLPT ltab is at %d:%d\n",
+	printk(KERN_ERR "\tLPT ltab is at %d:%d\n",
 	       c->ltab_lnum, c->ltab_offs);
 	if (c->big_lpt)
-		printk(KERN_DEBUG "\tLPT lsave is at %d:%d\n",
+		printk(KERN_ERR "\tLPT lsave is at %d:%d\n",
 		       c->lsave_lnum, c->lsave_offs);
 	for (i = 0; i < c->lpt_lebs; i++)
-		printk(KERN_DEBUG "\tLPT LEB %d free %d dirty %d tgc %d "
+		printk(KERN_ERR "\tLPT LEB %d free %d dirty %d tgc %d "
 		       "cmt %d\n", i + c->lpt_first, c->ltab[i].free,
 		       c->ltab[i].dirty, c->ltab[i].tgc, c->ltab[i].cmt);
 	spin_unlock(&dbg_lock);
@@ -867,12 +867,12 @@ void dbg_dump_sleb(const struct ubifs_info *c,
 {
 	struct ubifs_scan_node *snod;
 
-	printk(KERN_DEBUG "(pid %d) start dumping scanned data from LEB %d:%d\n",
+	printk(KERN_ERR "(pid %d) start dumping scanned data from LEB %d:%d\n",
 	       current->pid, sleb->lnum, offs);
 
 	list_for_each_entry(snod, &sleb->nodes, list) {
 		cond_resched();
-		printk(KERN_DEBUG "Dumping node at LEB %d:%d len %d\n", sleb->lnum,
+		printk(KERN_ERR "Dumping node at LEB %d:%d len %d\n", sleb->lnum,
 		       snod->offs, snod->len);
 		dbg_dump_node(c, snod->node);
 	}
@@ -887,7 +887,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
 	if (dbg_is_tst_rcvry(c))
 		return;
 
-	printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
+	printk(KERN_ERR "(pid %d) start dumping LEB %d\n",
 	       current->pid, lnum);
 
 	buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
@@ -902,17 +902,17 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
 		goto out;
 	}
 
-	printk(KERN_DEBUG "LEB %d has %d nodes ending at %d\n", lnum,
+	printk(KERN_ERR "LEB %d has %d nodes ending at %d\n", lnum,
 	       sleb->nodes_cnt, sleb->endpt);
 
 	list_for_each_entry(snod, &sleb->nodes, list) {
 		cond_resched();
-		printk(KERN_DEBUG "Dumping node at LEB %d:%d len %d\n", lnum,
+		printk(KERN_ERR "Dumping node at LEB %d:%d len %d\n", lnum,
 		       snod->offs, snod->len);
 		dbg_dump_node(c, snod->node);
 	}
 
-	printk(KERN_DEBUG "(pid %d) finish dumping LEB %d\n",
+	printk(KERN_ERR "(pid %d) finish dumping LEB %d\n",
 	       current->pid, lnum);
 	ubifs_scan_destroy(sleb);
 
@@ -934,7 +934,7 @@ void dbg_dump_znode(const struct ubifs_info *c,
 	else
 		zbr = &c->zroot;
 
-	printk(KERN_DEBUG "znode %p, LEB %d:%d len %d parent %p iip %d level %d"
+	printk(KERN_ERR "znode %p, LEB %d:%d len %d parent %p iip %d level %d"
 	       " child_cnt %d flags %lx\n", znode, zbr->lnum, zbr->offs,
 	       zbr->len, znode->parent, znode->iip, znode->level,
 	       znode->child_cnt, znode->flags);
@@ -944,18 +944,18 @@ void dbg_dump_znode(const struct ubifs_info *c,
 		return;
 	}
 
-	printk(KERN_DEBUG "zbranches:\n");
+	printk(KERN_ERR "zbranches:\n");
 	for (n = 0; n < znode->child_cnt; n++) {
 		zbr = &znode->zbranch[n];
 		if (znode->level > 0)
-			printk(KERN_DEBUG "\t%d: znode %p LEB %d:%d len %d key "
+			printk(KERN_ERR "\t%d: znode %p LEB %d:%d len %d key "
 					  "%s\n", n, zbr->znode, zbr->lnum,
 					  zbr->offs, zbr->len,
 					  dbg_snprintf_key(c, &zbr->key,
 							   key_buf,
 							   DBG_KEY_BUF_LEN));
 		else
-			printk(KERN_DEBUG "\t%d: LNC %p LEB %d:%d len %d key "
+			printk(KERN_ERR "\t%d: LNC %p LEB %d:%d len %d key "
 					  "%s\n", n, zbr->znode, zbr->lnum,
 					  zbr->offs, zbr->len,
 					  dbg_snprintf_key(c, &zbr->key,
@@ -969,16 +969,16 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat)
 {
 	int i;
 
-	printk(KERN_DEBUG "(pid %d) start dumping heap cat %d (%d elements)\n",
+	printk(KERN_ERR "(pid %d) start dumping heap cat %d (%d elements)\n",
 	       current->pid, cat, heap->cnt);
 	for (i = 0; i < heap->cnt; i++) {
 		struct ubifs_lprops *lprops = heap->arr[i];
 
-		printk(KERN_DEBUG "\t%d. LEB %d hpos %d free %d dirty %d "
+		printk(KERN_ERR "\t%d. LEB %d hpos %d free %d dirty %d "
 		       "flags %d\n", i, lprops->lnum, lprops->hpos,
 		       lprops->free, lprops->dirty, lprops->flags);
 	}
-	printk(KERN_DEBUG "(pid %d) finish dumping heap\n", current->pid);
+	printk(KERN_ERR "(pid %d) finish dumping heap\n", current->pid);
 }
 
 void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
@@ -986,15 +986,15 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode,
 {
 	int i;
 
-	printk(KERN_DEBUG "(pid %d) dumping pnode:\n", current->pid);
-	printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n",
+	printk(KERN_ERR "(pid %d) dumping pnode:\n", current->pid);
+	printk(KERN_ERR "\taddress %zx parent %zx cnext %zx\n",
 	       (size_t)pnode, (size_t)parent, (size_t)pnode->cnext);
-	printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n",
+	printk(KERN_ERR "\tflags %lu iip %d level %d num %d\n",
 	       pnode->flags, iip, pnode->level, pnode->num);
 	for (i = 0; i < UBIFS_LPT_FANOUT; i++) {
 		struct ubifs_lprops *lp = &pnode->lprops[i];
 
-		printk(KERN_DEBUG "\t%d: free %d dirty %d flags %d lnum %d\n",
+		printk(KERN_ERR "\t%d: free %d dirty %d flags %d lnum %d\n",
 		       i, lp->free, lp->dirty, lp->flags, lp->lnum);
 	}
 }
@@ -1004,20 +1004,20 @@ void dbg_dump_tnc(struct ubifs_info *c)
 	struct ubifs_znode *znode;
 	int level;
 
-	printk(KERN_DEBUG "\n");
-	printk(KERN_DEBUG "(pid %d) start dumping TNC tree\n", current->pid);
+	printk(KERN_ERR "\n");
+	printk(KERN_ERR "(pid %d) start dumping TNC tree\n", current->pid);
 	znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL);
 	level = znode->level;
-	printk(KERN_DEBUG "== Level %d ==\n", level);
+	printk(KERN_ERR "== Level %d ==\n", level);
 	while (znode) {
 		if (level != znode->level) {
 			level = znode->level;
-			printk(KERN_DEBUG "== Level %d ==\n", level);
+			printk(KERN_ERR "== Level %d ==\n", level);
 		}
 		dbg_dump_znode(c, znode);
 		znode = ubifs_tnc_levelorder_next(c->zroot.znode, znode);
 	}
-	printk(KERN_DEBUG "(pid %d) finish dumping TNC tree\n", current->pid);
+	printk(KERN_ERR "(pid %d) finish dumping TNC tree\n", current->pid);
 }
 
 static int dump_znode(struct ubifs_info *c, struct ubifs_znode *znode,
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index ad1a6fe..9f71765 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -164,9 +164,7 @@ struct ubifs_global_debug_info {
 #define dbg_dump_stack() dump_stack()
 
 #define dbg_err(fmt, ...) do {                                                 \
-	spin_lock(&dbg_lock);                                                  \
 	ubifs_err(fmt, ##__VA_ARGS__);                                         \
-	spin_unlock(&dbg_lock);                                                \
 } while (0)
 
 #define ubifs_dbg_msg(type, fmt, ...) \
@@ -217,7 +215,6 @@ struct ubifs_global_debug_info {
 /* Additional recovery messages */
 #define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
 
-extern spinlock_t dbg_lock;
 extern struct ubifs_global_debug_info ubifs_dbg;
 
 static inline int dbg_is_chk_gen(const struct ubifs_info *c)
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index d6fe1c7..ec9f187 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -566,6 +566,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
 	int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
 	int err, budgeted = 1;
 	struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
+	unsigned int saved_nlink = inode->i_nlink;
 
 	/*
 	 * Budget request settings: deletion direntry, deletion inode (+1 for
@@ -613,7 +614,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
 out_cancel:
 	dir->i_size += sz_change;
 	dir_ui->ui_size = dir->i_size;
-	inc_nlink(inode);
+	set_nlink(inode, saved_nlink);
 	unlock_2_inodes(dir, inode);
 	if (budgeted)
 		ubifs_release_budget(c, &req);
@@ -704,8 +705,7 @@ out_cancel:
 	dir->i_size += sz_change;
 	dir_ui->ui_size = dir->i_size;
 	inc_nlink(dir);
-	inc_nlink(inode);
-	inc_nlink(inode);
+	set_nlink(inode, 2);
 	unlock_2_inodes(dir, inode);
 	if (budgeted)
 		ubifs_release_budget(c, &req);
@@ -977,6 +977,7 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
 			.dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
 	struct timespec time;
+	unsigned int saved_nlink;
 
 	/*
 	 * Budget request settings: deletion direntry, new direntry, removing
@@ -1059,13 +1060,14 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	if (unlink) {
 		/*
 		 * Directories cannot have hard-links, so if this is a
-		 * directory, decrement its @i_nlink twice because an empty
-		 * directory has @i_nlink 2.
+		 * directory, just clear @i_nlink.
 		 */
+		saved_nlink = new_inode->i_nlink;
 		if (is_dir)
+			clear_nlink(new_inode);
+		else
 			drop_nlink(new_inode);
 		new_inode->i_ctime = time;
-		drop_nlink(new_inode);
 	} else {
 		new_dir->i_size += new_sz;
 		ubifs_inode(new_dir)->ui_size = new_dir->i_size;
@@ -1102,9 +1104,7 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
 out_cancel:
 	if (unlink) {
-		if (is_dir)
-			inc_nlink(new_inode);
-		inc_nlink(new_inode);
+		set_nlink(new_inode, saved_nlink);
 	} else {
 		new_dir->i_size -= new_sz;
 		ubifs_inode(new_dir)->ui_size = new_dir->i_size;
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index f9c234b..5c8f6dc 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1042,10 +1042,10 @@ static int ubifs_writepage(struct page *page, struct writeback_control *wbc)
 	 * the page size, the remaining memory is zeroed when mapped, and
 	 * writes to that region are not written out to the file."
 	 */
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memset(kaddr + len, 0, PAGE_CACHE_SIZE - len);
 	flush_dcache_page(page);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	if (i_size > synced_i_size) {
 		err = inode->i_sb->s_op->write_inode(inode, NULL);
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index ee4f43f..2a935b3 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -679,7 +679,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
 			   ret == SCANNED_GARBAGE     ||
 			   ret == SCANNED_A_BAD_PAD_NODE ||
 			   ret == SCANNED_A_CORRUPT_NODE) {
-			dbg_rcvry("found corruption - %d", ret);
+			dbg_rcvry("found corruption (%d) at %d:%d",
+				  ret, lnum, offs);
 			break;
 		} else {
 			dbg_err("unexpected return value %d", ret);
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 63765d5..76e4e05 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2076,15 +2076,13 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 		goto out_umount;
 	}
 
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root)
-		goto out_iput;
+		goto out_umount;
 
 	mutex_unlock(&c->umount_mutex);
 	return 0;
 
-out_iput:
-	iput(root);
 out_umount:
 	ubifs_umount(c);
 out_unlock:
diff --git a/fs/udf/file.c b/fs/udf/file.c
index dca0c38..c088507 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -87,10 +87,10 @@ static int udf_adinicb_write_end(struct file *file,
 	char *kaddr;
 	struct udf_inode_info *iinfo = UDF_I(inode);
 
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr + offset,
 		kaddr + offset, copied);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	return simple_write_end(file, mapping, pos, len, copied, page, fsdata);
 }
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 08bf46e..38de8f2 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -32,8 +32,6 @@
 #include <linux/crc-itu-t.h>
 #include <linux/exportfs.h>
 
-enum { UDF_MAX_LINKS = 0xffff };
-
 static inline int udf_match(int len1, const unsigned char *name1, int len2,
 			    const unsigned char *name2)
 {
@@ -649,10 +647,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 	struct udf_inode_info *dinfo = UDF_I(dir);
 	struct udf_inode_info *iinfo;
 
-	err = -EMLINK;
-	if (dir->i_nlink >= UDF_MAX_LINKS)
-		goto out;
-
 	err = -EIO;
 	inode = udf_new_inode(dir, S_IFDIR | mode, &err);
 	if (!inode)
@@ -1032,9 +1026,6 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
 	struct fileIdentDesc cfi, *fi;
 	int err;
 
-	if (inode->i_nlink >= UDF_MAX_LINKS)
-		return -EMLINK;
-
 	fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
 	if (!fi) {
 		return err;
@@ -1126,10 +1117,6 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
 		if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
 				old_dir->i_ino)
 			goto end_rename;
-
-		retval = -EMLINK;
-		if (!new_inode && new_dir->i_nlink >= UDF_MAX_LINKS)
-			goto end_rename;
 	}
 	if (!nfi) {
 		nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi,
diff --git a/fs/udf/super.c b/fs/udf/super.c
index c09a84d..85067b4 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -75,6 +75,8 @@
 
 #define UDF_DEFAULT_BLOCKSIZE 2048
 
+enum { UDF_MAX_LINKS = 0xffff };
+
 /* These are the "meat" - everything else is stuffing */
 static int udf_fill_super(struct super_block *, void *, int);
 static void udf_put_super(struct super_block *);
@@ -2035,13 +2037,13 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
 	}
 
 	/* Allocate a dentry for the root inode */
-	sb->s_root = d_alloc_root(inode);
+	sb->s_root = d_make_root(inode);
 	if (!sb->s_root) {
 		udf_err(sb, "Couldn't allocate root dentry\n");
-		iput(inode);
 		goto error_out;
 	}
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	sb->s_max_links = UDF_MAX_LINKS;
 	return 0;
 
 error_out:
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 38cac19..a2281ca 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -166,10 +166,6 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
 	int error;
 
 	lock_ufs(dir->i_sb);
-	if (inode->i_nlink >= UFS_LINK_MAX) {
-		unlock_ufs(dir->i_sb);
-		return -EMLINK;
-	}
 
 	inode->i_ctime = CURRENT_TIME_SEC;
 	inode_inc_link_count(inode);
@@ -183,10 +179,7 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
 static int ufs_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
 {
 	struct inode * inode;
-	int err = -EMLINK;
-
-	if (dir->i_nlink >= UFS_LINK_MAX)
-		goto out;
+	int err;
 
 	lock_ufs(dir->i_sb);
 	inode_inc_link_count(dir);
@@ -305,11 +298,6 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
 			drop_nlink(new_inode);
 		inode_dec_link_count(new_inode);
 	} else {
-		if (dir_de) {
-			err = -EMLINK;
-			if (new_dir->i_nlink >= UFS_LINK_MAX)
-				goto out_dir;
-		}
 		err = ufs_add_link(new_dentry, old_inode);
 		if (err)
 			goto out_dir;
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 5246ee3..f636f6b 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1157,16 +1157,17 @@ magic_found:
 			    "fast symlink size (%u)\n", uspi->s_maxsymlinklen);
 		uspi->s_maxsymlinklen = maxsymlen;
 	}
+	sb->s_max_links = UFS_LINK_MAX;
 
 	inode = ufs_iget(sb, UFS_ROOTINO);
 	if (IS_ERR(inode)) {
 		ret = PTR_ERR(inode);
 		goto failed;
 	}
-	sb->s_root = d_alloc_root(inode);
+	sb->s_root = d_make_root(inode);
 	if (!sb->s_root) {
 		ret = -ENOMEM;
-		goto dalloc_failed;
+		goto failed;
 	}
 
 	ufs_setup_cstotal(sb);
@@ -1180,8 +1181,6 @@ magic_found:
 	UFSD("EXIT\n");
 	return 0;
 
-dalloc_failed:
-	iput(inode);
 failed:
 	if (ubh)
 		ubh_brelse_uspi (uspi);
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index cbcb7be..4e268ed 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -139,10 +139,10 @@ xfs_qm_adjust_dqtimers(
 
 	if (!d->d_btimer) {
 		if ((d->d_blk_softlimit &&
-		     (be64_to_cpu(d->d_bcount) >=
+		     (be64_to_cpu(d->d_bcount) >
 		      be64_to_cpu(d->d_blk_softlimit))) ||
 		    (d->d_blk_hardlimit &&
-		     (be64_to_cpu(d->d_bcount) >=
+		     (be64_to_cpu(d->d_bcount) >
 		      be64_to_cpu(d->d_blk_hardlimit)))) {
 			d->d_btimer = cpu_to_be32(get_seconds() +
 					mp->m_quotainfo->qi_btimelimit);
@@ -151,10 +151,10 @@ xfs_qm_adjust_dqtimers(
 		}
 	} else {
 		if ((!d->d_blk_softlimit ||
-		     (be64_to_cpu(d->d_bcount) <
+		     (be64_to_cpu(d->d_bcount) <=
 		      be64_to_cpu(d->d_blk_softlimit))) &&
 		    (!d->d_blk_hardlimit ||
-		    (be64_to_cpu(d->d_bcount) <
+		    (be64_to_cpu(d->d_bcount) <=
 		     be64_to_cpu(d->d_blk_hardlimit)))) {
 			d->d_btimer = 0;
 		}
@@ -162,10 +162,10 @@ xfs_qm_adjust_dqtimers(
 
 	if (!d->d_itimer) {
 		if ((d->d_ino_softlimit &&
-		     (be64_to_cpu(d->d_icount) >=
+		     (be64_to_cpu(d->d_icount) >
 		      be64_to_cpu(d->d_ino_softlimit))) ||
 		    (d->d_ino_hardlimit &&
-		     (be64_to_cpu(d->d_icount) >=
+		     (be64_to_cpu(d->d_icount) >
 		      be64_to_cpu(d->d_ino_hardlimit)))) {
 			d->d_itimer = cpu_to_be32(get_seconds() +
 					mp->m_quotainfo->qi_itimelimit);
@@ -174,10 +174,10 @@ xfs_qm_adjust_dqtimers(
 		}
 	} else {
 		if ((!d->d_ino_softlimit ||
-		     (be64_to_cpu(d->d_icount) <
+		     (be64_to_cpu(d->d_icount) <=
 		      be64_to_cpu(d->d_ino_softlimit)))  &&
 		    (!d->d_ino_hardlimit ||
-		     (be64_to_cpu(d->d_icount) <
+		     (be64_to_cpu(d->d_icount) <=
 		      be64_to_cpu(d->d_ino_hardlimit)))) {
 			d->d_itimer = 0;
 		}
@@ -185,10 +185,10 @@ xfs_qm_adjust_dqtimers(
 
 	if (!d->d_rtbtimer) {
 		if ((d->d_rtb_softlimit &&
-		     (be64_to_cpu(d->d_rtbcount) >=
+		     (be64_to_cpu(d->d_rtbcount) >
 		      be64_to_cpu(d->d_rtb_softlimit))) ||
 		    (d->d_rtb_hardlimit &&
-		     (be64_to_cpu(d->d_rtbcount) >=
+		     (be64_to_cpu(d->d_rtbcount) >
 		      be64_to_cpu(d->d_rtb_hardlimit)))) {
 			d->d_rtbtimer = cpu_to_be32(get_seconds() +
 					mp->m_quotainfo->qi_rtbtimelimit);
@@ -197,10 +197,10 @@ xfs_qm_adjust_dqtimers(
 		}
 	} else {
 		if ((!d->d_rtb_softlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <
+		     (be64_to_cpu(d->d_rtbcount) <=
 		      be64_to_cpu(d->d_rtb_softlimit))) &&
 		    (!d->d_rtb_hardlimit ||
-		     (be64_to_cpu(d->d_rtbcount) <
+		     (be64_to_cpu(d->d_rtbcount) <=
 		      be64_to_cpu(d->d_rtb_hardlimit)))) {
 			d->d_rtbtimer = 0;
 		}
@@ -282,7 +282,7 @@ xfs_qm_dqalloc(
 	 * Return if this type of quotas is turned off while we didn't
 	 * have an inode lock
 	 */
-	if (XFS_IS_THIS_QUOTA_OFF(dqp)) {
+	if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
 		xfs_iunlock(quotip, XFS_ILOCK_EXCL);
 		return (ESRCH);
 	}
@@ -384,7 +384,7 @@ xfs_qm_dqtobp(
 	dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
 
 	xfs_ilock(quotip, XFS_ILOCK_SHARED);
-	if (XFS_IS_THIS_QUOTA_OFF(dqp)) {
+	if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
 		/*
 		 * Return if this type of quotas is turned off while we
 		 * didn't have the quota inode lock.
@@ -672,7 +672,7 @@ xfs_qm_dqget(
 	uint		flags,	  /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
 	xfs_dquot_t	**O_dqpp) /* OUT : locked incore dquot */
 {
-	xfs_dquot_t	*dqp;
+	xfs_dquot_t	*dqp, *dqp1;
 	xfs_dqhash_t	*h;
 	uint		version;
 	int		error;
@@ -699,10 +699,7 @@ xfs_qm_dqget(
 	       type == XFS_DQ_GROUP);
 	if (ip) {
 		ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-		if (type == XFS_DQ_USER)
-			ASSERT(ip->i_udquot == NULL);
-		else
-			ASSERT(ip->i_gdquot == NULL);
+		ASSERT(xfs_inode_dquot(ip, type) == NULL);
 	}
 #endif
 
@@ -768,30 +765,18 @@ restart:
 		 * A dquot could be attached to this inode by now, since
 		 * we had dropped the ilock.
 		 */
-		if (type == XFS_DQ_USER) {
-			if (!XFS_IS_UQUOTA_ON(mp)) {
-				/* inode stays locked on return */
-				xfs_qm_dqdestroy(dqp);
-				return XFS_ERROR(ESRCH);
-			}
-			if (ip->i_udquot) {
+		if (xfs_this_quota_on(mp, type)) {
+			dqp1 = xfs_inode_dquot(ip, type);
+			if (dqp1) {
 				xfs_qm_dqdestroy(dqp);
-				dqp = ip->i_udquot;
+				dqp = dqp1;
 				xfs_dqlock(dqp);
 				goto dqret;
 			}
 		} else {
-			if (!XFS_IS_OQUOTA_ON(mp)) {
-				/* inode stays locked on return */
-				xfs_qm_dqdestroy(dqp);
-				return XFS_ERROR(ESRCH);
-			}
-			if (ip->i_gdquot) {
-				xfs_qm_dqdestroy(dqp);
-				dqp = ip->i_gdquot;
-				xfs_dqlock(dqp);
-				goto dqret;
-			}
+			/* inode stays locked on return */
+			xfs_qm_dqdestroy(dqp);
+			return XFS_ERROR(ESRCH);
 		}
 	}
 
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index a1d91d8..48a795b 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -115,6 +115,32 @@ static inline void xfs_dqunlock_nonotify(struct xfs_dquot *dqp)
 	mutex_unlock(&dqp->q_qlock);
 }
 
+static inline int xfs_this_quota_on(struct xfs_mount *mp, int type)
+{
+	switch (type & XFS_DQ_ALLTYPES) {
+	case XFS_DQ_USER:
+		return XFS_IS_UQUOTA_ON(mp);
+	case XFS_DQ_GROUP:
+	case XFS_DQ_PROJ:
+		return XFS_IS_OQUOTA_ON(mp);
+	default:
+		return 0;
+	}
+}
+
+static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)
+{
+	switch (type & XFS_DQ_ALLTYPES) {
+	case XFS_DQ_USER:
+		return ip->i_udquot;
+	case XFS_DQ_GROUP:
+	case XFS_DQ_PROJ:
+		return ip->i_gdquot;
+	default:
+		return NULL;
+	}
+}
+
 #define XFS_DQ_IS_LOCKED(dqp)	(mutex_is_locked(&((dqp)->q_qlock)))
 #define XFS_DQ_IS_DIRTY(dqp)	((dqp)->dq_flags & XFS_DQ_DIRTY)
 #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
@@ -125,10 +151,6 @@ static inline void xfs_dqunlock_nonotify(struct xfs_dquot *dqp)
 				 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
 				 XFS_DQ_TO_QINF(dqp)->qi_gquotaip)
 
-#define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
-				     (XFS_IS_UQUOTA_ON((d)->q_mount)) : \
-				     (XFS_IS_OQUOTA_ON((d)->q_mount))))
-
 extern int		xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint,
 					uint, struct xfs_dquot	**);
 extern void		xfs_qm_dqdestroy(xfs_dquot_t *);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 15ff539..8a3d8ae 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1981,7 +1981,7 @@ xfs_qm_dqcheck(
 
 	if (!errs && ddq->d_id) {
 		if (ddq->d_blk_softlimit &&
-		    be64_to_cpu(ddq->d_bcount) >=
+		    be64_to_cpu(ddq->d_bcount) >
 				be64_to_cpu(ddq->d_blk_softlimit)) {
 			if (!ddq->d_btimer) {
 				if (flags & XFS_QMOPT_DOWARN)
@@ -1992,7 +1992,7 @@ xfs_qm_dqcheck(
 			}
 		}
 		if (ddq->d_ino_softlimit &&
-		    be64_to_cpu(ddq->d_icount) >=
+		    be64_to_cpu(ddq->d_icount) >
 				be64_to_cpu(ddq->d_ino_softlimit)) {
 			if (!ddq->d_itimer) {
 				if (flags & XFS_QMOPT_DOWARN)
@@ -2003,7 +2003,7 @@ xfs_qm_dqcheck(
 			}
 		}
 		if (ddq->d_rtb_softlimit &&
-		    be64_to_cpu(ddq->d_rtbcount) >=
+		    be64_to_cpu(ddq->d_rtbcount) >
 				be64_to_cpu(ddq->d_rtb_softlimit)) {
 			if (!ddq->d_rtbtimer) {
 				if (flags & XFS_QMOPT_DOWARN)
@@ -3695,7 +3695,7 @@ xlog_do_recover(
 
 	/* Convert superblock from on-disk format */
 	sbp = &log->l_mp->m_sb;
-	xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
+	xfs_sb_from_disk(log->l_mp, XFS_BUF_TO_SBP(bp));
 	ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
 	ASSERT(xfs_sb_good_version(sbp));
 	xfs_buf_relse(bp);
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index d06afbc..1ffead4 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -158,7 +158,7 @@ xfs_uuid_mount(
 
  out_duplicate:
 	mutex_unlock(&xfs_uuid_table_mutex);
-	xfs_warn(mp, "Filesystem has duplicate UUID - can't mount");
+	xfs_warn(mp, "Filesystem has duplicate UUID %pU - can't mount", uuid);
 	return XFS_ERROR(EINVAL);
 }
 
@@ -553,9 +553,11 @@ out_unwind:
 
 void
 xfs_sb_from_disk(
-	xfs_sb_t	*to,
+	struct xfs_mount	*mp,
 	xfs_dsb_t	*from)
 {
+	struct xfs_sb *to = &mp->m_sb;
+
 	to->sb_magicnum = be32_to_cpu(from->sb_magicnum);
 	to->sb_blocksize = be32_to_cpu(from->sb_blocksize);
 	to->sb_dblocks = be64_to_cpu(from->sb_dblocks);
@@ -693,7 +695,7 @@ reread:
 	 * Initialize the mount structure from the superblock.
 	 * But first do some basic consistency checking.
 	 */
-	xfs_sb_from_disk(&mp->m_sb, XFS_BUF_TO_SBP(bp));
+	xfs_sb_from_disk(mp, XFS_BUF_TO_SBP(bp));
 	error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);
 	if (error) {
 		if (loud)
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 19f69e2..c082e44 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -395,7 +395,7 @@ extern void	xfs_set_low_space_thresholds(struct xfs_mount *);
 extern void	xfs_mod_sb(struct xfs_trans *, __int64_t);
 extern int	xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t,
 					xfs_agnumber_t *);
-extern void	xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *);
+extern void	xfs_sb_from_disk(struct xfs_mount *, struct xfs_dsb *);
 extern void	xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t);
 
 #endif	/* __XFS_MOUNT_H__ */
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index c436def..c872fea 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1496,7 +1496,7 @@ xfs_qm_quotacheck(
 	 * quotachecked status, since we won't be doing accounting for
 	 * that type anymore.
 	 */
-	mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
+	mp->m_qflags &= ~XFS_ALL_QUOTA_CHKD;
 	mp->m_qflags |= flags;
 
  error_return:
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index eafbcff..711a86e 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -813,11 +813,11 @@ xfs_qm_export_dquot(
 	     (XFS_IS_OQUOTA_ENFORCED(mp) &&
 			(dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
 	    dst->d_id != 0) {
-		if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
+		if (((int) dst->d_bcount > (int) dst->d_blk_softlimit) &&
 		    (dst->d_blk_softlimit > 0)) {
 			ASSERT(dst->d_btimer != 0);
 		}
-		if (((int) dst->d_icount >= (int) dst->d_ino_softlimit) &&
+		if (((int) dst->d_icount > (int) dst->d_ino_softlimit) &&
 		    (dst->d_ino_softlimit > 0)) {
 			ASSERT(dst->d_itimer != 0);
 		}
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 8a0807e..b50ec5b 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -174,6 +174,8 @@ typedef struct xfs_qoff_logformat {
 #define XFS_UQUOTA_ACTIVE	0x0100  /* uquotas are being turned off */
 #define XFS_PQUOTA_ACTIVE	0x0200  /* pquotas are being turned off */
 #define XFS_GQUOTA_ACTIVE	0x0400  /* gquotas are being turned off */
+#define XFS_ALL_QUOTA_ACTIVE	\
+	(XFS_UQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
 
 /*
  * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index 866de27..e44ef7e 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -118,17 +118,6 @@ xfs_rename(
 	new_parent = (src_dp != target_dp);
 	src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
 
-	if (src_is_directory) {
-		/*
-		 * Check for link count overflow on target_dp
-		 */
-		if (target_ip == NULL && new_parent &&
-		    target_dp->i_d.di_nlink >= XFS_MAXLINK) {
-			error = XFS_ERROR(EMLINK);
-			goto std_return;
-		}
-	}
-
 	xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip,
 				inodes, &num_inodes);
 
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h
index cb6ae71..f429d9d 100644
--- a/fs/xfs/xfs_sb.h
+++ b/fs/xfs/xfs_sb.h
@@ -529,7 +529,6 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp)
 #define	XFS_BB_TO_FSB(mp,bb)	\
 	(((bb) + (XFS_FSB_TO_BB(mp,1) - 1)) >> (mp)->m_blkbb_log)
 #define	XFS_BB_TO_FSBT(mp,bb)	((bb) >> (mp)->m_blkbb_log)
-#define	XFS_BB_FSB_OFFSET(mp,bb) ((bb) & ((mp)->m_bsize - 1))
 
 /*
  * File system block to byte conversions.
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index ee5b695..b1a0488 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -324,10 +324,9 @@ xfs_parseargs(
 		} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
 			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
 		} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
-			mp->m_qflags &= ~(XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
-					  XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
-					  XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
-					  XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD);
+			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
+			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
+			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
 		} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
 			   !strcmp(this_char, MNTOPT_UQUOTA) ||
 			   !strcmp(this_char, MNTOPT_USRQUOTA)) {
@@ -1341,6 +1340,7 @@ xfs_fs_fill_super(
 	sb->s_blocksize = mp->m_sb.sb_blocksize;
 	sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
 	sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
+	sb->s_max_links = XFS_MAXLINK;
 	sb->s_time_gran = 1;
 	set_posix_acl_flag(sb);
 
@@ -1361,10 +1361,10 @@ xfs_fs_fill_super(
 		error = EINVAL;
 		goto out_syncd_stop;
 	}
-	sb->s_root = d_alloc_root(root);
+	sb->s_root = d_make_root(root);
 	if (!sb->s_root) {
 		error = ENOMEM;
-		goto out_iput;
+		goto out_syncd_stop;
 	}
 
 	return 0;
@@ -1383,8 +1383,6 @@ xfs_fs_fill_super(
  out:
 	return -error;
 
- out_iput:
-	iput(root);
  out_syncd_stop:
 	xfs_syncd_stop(mp);
  out_unmount:
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 329b06a..7adcdf1 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1151,8 +1151,8 @@ xfs_trans_add_item(
 {
 	struct xfs_log_item_desc *lidp;
 
-	ASSERT(lip->li_mountp = tp->t_mountp);
-	ASSERT(lip->li_ailp = tp->t_mountp->m_ail);
+	ASSERT(lip->li_mountp == tp->t_mountp);
+	ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
 
 	lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS);
 
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 4d00ee6..c4ba366 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -649,12 +649,12 @@ xfs_trans_dqresv(
 			 * nblks.
 			 */
 			if (hardlimit > 0ULL &&
-			    hardlimit <= nblks + *resbcountp) {
+			    hardlimit < nblks + *resbcountp) {
 				xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
 				goto error_return;
 			}
 			if (softlimit > 0ULL &&
-			    softlimit <= nblks + *resbcountp) {
+			    softlimit < nblks + *resbcountp) {
 				if ((timer != 0 && get_seconds() > timer) ||
 				    (warns != 0 && warns >= warnlimit)) {
 					xfs_quota_warn(mp, dqp,
@@ -677,11 +677,13 @@ xfs_trans_dqresv(
 			if (!softlimit)
 				softlimit = q->qi_isoftlimit;
 
-			if (hardlimit > 0ULL && count >= hardlimit) {
+			if (hardlimit > 0ULL &&
+			    hardlimit < ninos + count) {
 				xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
 				goto error_return;
 			}
-			if (softlimit > 0ULL && count >= softlimit) {
+			if (softlimit > 0ULL &&
+			    softlimit < ninos + count) {
 				if  ((timer != 0 && get_seconds() > timer) ||
 				     (warns != 0 && warns >= warnlimit)) {
 					xfs_quota_warn(mp, dqp,
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 89dbb4a..79c05ac 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -296,8 +296,6 @@ xfs_bumplink(
 	xfs_trans_t *tp,
 	xfs_inode_t *ip)
 {
-	if (ip->i_d.di_nlink >= XFS_MAXLINK)
-		return XFS_ERROR(EMLINK);
 	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
 
 	ASSERT(ip->i_d.di_nlink > 0);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index ebdb888..64981d7 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -917,14 +917,6 @@ xfs_create(
 	xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
 	unlock_dp_on_error = B_TRUE;
 
-	/*
-	 * Check for directory link count overflow.
-	 */
-	if (is_dir && dp->i_d.di_nlink >= XFS_MAXLINK) {
-		error = XFS_ERROR(EMLINK);
-		goto out_trans_cancel;
-	}
-
 	xfs_bmap_init(&free_list, &first_block);
 
 	/*
@@ -1429,14 +1421,6 @@ xfs_link(
 	xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
 
 	/*
-	 * If the source has too many links, we can't make any more to it.
-	 */
-	if (sip->i_d.di_nlink >= XFS_MAXLINK) {
-		error = XFS_ERROR(EMLINK);
-		goto error_return;
-	}
-
-	/*
 	 * If we are using project inheritance, we only allow hard link
 	 * creation in our tree when the project IDs are the same; else
 	 * the tree quota mechanism could be circumvented.
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index bb145e4..3c4e381 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -131,6 +131,9 @@ extern int register_hotplug_dock_device(acpi_handle handle,
 					const struct acpi_dock_ops *ops,
 					void *context);
 extern void unregister_hotplug_dock_device(acpi_handle handle);
+extern int is_registered_hotplug_dock_device(const struct acpi_dock_ops *ops);
+extern struct device **dock_link_device(acpi_handle handle);
+extern struct device **dock_unlink_device(acpi_handle handle);
 #else
 static inline int is_dock_device(acpi_handle handle)
 {
@@ -152,6 +155,14 @@ static inline int register_hotplug_dock_device(acpi_handle handle,
 static inline void unregister_hotplug_dock_device(acpi_handle handle)
 {
 }
+static inline struct device **dock_link_device(acpi_handle handle)
+{
+	return NULL;
+}
+static inline struct device **dock_unlink_device(acpi_handle handle)
+{
+	return NULL;
+}
 #endif
 
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 8cf7e98..9d65047 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -225,6 +225,7 @@ struct acpi_processor_errata {
 	} piix4;
 };
 
+extern void acpi_processor_load_module(struct acpi_processor *pr);
 extern int acpi_processor_preregister_performance(struct
 						  acpi_processor_performance
 						  __percpu *performance);
diff --git a/include/asm-generic/posix_types.h b/include/asm-generic/posix_types.h
index 3dab008..ac21760 100644
--- a/include/asm-generic/posix_types.h
+++ b/include/asm-generic/posix_types.h
@@ -44,8 +44,8 @@ typedef int		__kernel_daddr_t;
 #endif
 
 #ifndef __kernel_uid32_t
-typedef __kernel_uid_t	__kernel_uid32_t;
-typedef __kernel_gid_t	__kernel_gid32_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
 #endif
 
 #ifndef __kernel_old_uid_t
@@ -73,6 +73,12 @@ typedef long		__kernel_ptrdiff_t;
 #endif
 #endif
 
+#ifndef __kernel_fsid_t
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+#endif
+
 /*
  * anything below here should be completely generic
  */
@@ -86,10 +92,6 @@ typedef char *		__kernel_caddr_t;
 typedef unsigned short	__kernel_uid16_t;
 typedef unsigned short	__kernel_gid16_t;
 
-typedef struct {
-	int	val[2];
-} __kernel_fsid_t;
-
 #ifdef __KERNEL__
 
 #undef __FD_SET
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index 49c1704..d9aaac0 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -67,4 +67,5 @@
 
 #define SO_WIFI_STATUS		41
 #define SCM_WIFI_STATUS	SO_WIFI_STATUS
+#define SO_PEEK_OFF		42
 #endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index b5e2e4c..c4ad0b1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -615,30 +615,23 @@
 		*(.init.setup)						\
 		VMLINUX_SYMBOL(__setup_end) = .;
 
-#define INITCALLS							\
-	*(.initcallearly.init)						\
-	VMLINUX_SYMBOL(__early_initcall_end) = .;			\
-  	*(.initcall0.init)						\
-  	*(.initcall0s.init)						\
-  	*(.initcall1.init)						\
-  	*(.initcall1s.init)						\
-  	*(.initcall2.init)						\
-  	*(.initcall2s.init)						\
-  	*(.initcall3.init)						\
-  	*(.initcall3s.init)						\
-  	*(.initcall4.init)						\
-  	*(.initcall4s.init)						\
-  	*(.initcall5.init)						\
-  	*(.initcall5s.init)						\
-	*(.initcallrootfs.init)						\
-  	*(.initcall6.init)						\
-  	*(.initcall6s.init)						\
-  	*(.initcall7.init)						\
-  	*(.initcall7s.init)
+#define INIT_CALLS_LEVEL(level)						\
+		VMLINUX_SYMBOL(__initcall##level##_start) = .;		\
+		*(.initcall##level##.init)				\
+		*(.initcall##level##s.init)				\
 
 #define INIT_CALLS							\
 		VMLINUX_SYMBOL(__initcall_start) = .;			\
-		INITCALLS						\
+		*(.initcallearly.init)					\
+		INIT_CALLS_LEVEL(0)					\
+		INIT_CALLS_LEVEL(1)					\
+		INIT_CALLS_LEVEL(2)					\
+		INIT_CALLS_LEVEL(3)					\
+		INIT_CALLS_LEVEL(4)					\
+		INIT_CALLS_LEVEL(5)					\
+		INIT_CALLS_LEVEL(rootfs)				\
+		INIT_CALLS_LEVEL(6)					\
+		INIT_CALLS_LEVEL(7)					\
 		VMLINUX_SYMBOL(__initcall_end) = .;
 
 #define CON_INITCALL							\
diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index 4fd95a3..3744d2a 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -25,28 +25,6 @@
 #include <linux/scatterlist.h>
 #include <linux/sched.h>
 
-static inline enum km_type crypto_kmap_type(int out)
-{
-	enum km_type type;
-
-	if (in_softirq())
-		type = out * (KM_SOFTIRQ1 - KM_SOFTIRQ0) + KM_SOFTIRQ0;
-	else
-		type = out * (KM_USER1 - KM_USER0) + KM_USER0;
-
-	return type;
-}
-
-static inline void *crypto_kmap(struct page *page, int out)
-{
-	return kmap_atomic(page, crypto_kmap_type(out));
-}
-
-static inline void crypto_kunmap(void *vaddr, int out)
-{
-	kunmap_atomic(vaddr, crypto_kmap_type(out));
-}
-
 static inline void crypto_yield(u32 flags)
 {
 	if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)
@@ -121,15 +99,15 @@ static inline struct page *scatterwalk_page(struct scatter_walk *walk)
 	return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
 }
 
-static inline void scatterwalk_unmap(void *vaddr, int out)
+static inline void scatterwalk_unmap(void *vaddr)
 {
-	crypto_kunmap(vaddr, out);
+	kunmap_atomic(vaddr);
 }
 
 void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
 void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
 			    size_t nbytes, int out);
-void *scatterwalk_map(struct scatter_walk *walk, int out);
+void *scatterwalk_map(struct scatter_walk *walk);
 void scatterwalk_done(struct scatter_walk *walk, int out, int more);
 
 void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 49d94ed..34a7b89 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -761,6 +761,8 @@ struct drm_event_vblank {
 
 #define DRM_CAP_DUMB_BUFFER 0x1
 #define DRM_CAP_VBLANK_HIGH_CRTC 0x2
+#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3
+#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
 
 /* typedef area */
 #ifndef __KERNEL__
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 4cd4be2..2a0872c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -796,6 +796,9 @@ struct drm_mode_config {
 	struct drm_property *scaling_mode_property;
 	struct drm_property *dithering_mode_property;
 	struct drm_property *dirty_info_property;
+
+	/* dumb ioctl parameters */
+	uint32_t preferred_depth, prefer_shadow;
 };
 
 #define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
@@ -807,6 +810,10 @@ struct drm_mode_config {
 #define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
 #define obj_to_plane(x) container_of(x, struct drm_plane, base)
 
+struct drm_prop_enum_list {
+	int type;
+	char *name;
+};
 
 extern void drm_crtc_init(struct drm_device *dev,
 			  struct drm_crtc *crtc,
@@ -904,6 +911,13 @@ extern int drm_connector_attach_property(struct drm_connector *connector,
 				      struct drm_property *property, uint64_t init_val);
 extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
 						const char *name, int num_values);
+extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
+					 const char *name,
+					 const struct drm_prop_enum_list *props,
+					 int num_values);
+struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
+					 const char *name,
+					 uint64_t min, uint64_t max);
 extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
 extern int drm_property_add_enum(struct drm_property *property, int index,
 				 uint64_t value, const char *name);
@@ -919,7 +933,7 @@ extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
 					     struct drm_encoder *encoder);
 extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
 					   struct drm_encoder *encoder);
-extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
+extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
 					 int gamma_size);
 extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
 		uint32_t id, uint32_t type);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 6e3076a..5120b01 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -35,7 +35,6 @@ struct drm_fb_helper;
 #include <linux/kgdb.h>
 
 struct drm_fb_helper_crtc {
-	uint32_t crtc_id;
 	struct drm_mode_set mode_set;
 	struct drm_display_mode *desired_mode;
 };
@@ -74,7 +73,6 @@ struct drm_fb_helper {
 	int connector_count;
 	struct drm_fb_helper_connector **connector_info;
 	struct drm_fb_helper_funcs *funcs;
-	int conn_limit;
 	struct fb_info *fbdev;
 	u32 pseudo_palette[17];
 	struct list_head kernel_fb_list;
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 924f6a4..da929bb 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -296,6 +296,7 @@ typedef struct drm_i915_irq_wait {
 #define I915_PARAM_HAS_EXEC_CONSTANTS	 14
 #define I915_PARAM_HAS_RELAXED_DELTA	 15
 #define I915_PARAM_HAS_GEN7_SOL_RESET	 16
+#define I915_PARAM_HAS_LLC     	 17
 
 typedef struct drm_i915_getparam {
 	int param;
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index b55da40..cb2f0c3 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -804,13 +804,23 @@ struct drm_radeon_gem_create {
 	uint32_t	flags;
 };
 
-#define RADEON_TILING_MACRO       0x1
-#define RADEON_TILING_MICRO       0x2
-#define RADEON_TILING_SWAP_16BIT  0x4
-#define RADEON_TILING_SWAP_32BIT  0x8
-#define RADEON_TILING_SURFACE     0x10 /* this object requires a surface
-					* when mapped - i.e. front buffer */
-#define RADEON_TILING_MICRO_SQUARE 0x20
+#define RADEON_TILING_MACRO				0x1
+#define RADEON_TILING_MICRO				0x2
+#define RADEON_TILING_SWAP_16BIT			0x4
+#define RADEON_TILING_SWAP_32BIT			0x8
+/* this object requires a surface when mapped - i.e. front buffer */
+#define RADEON_TILING_SURFACE				0x10
+#define RADEON_TILING_MICRO_SQUARE			0x20
+#define RADEON_TILING_EG_BANKW_SHIFT			8
+#define RADEON_TILING_EG_BANKW_MASK			0xf
+#define RADEON_TILING_EG_BANKH_SHIFT			12
+#define RADEON_TILING_EG_BANKH_MASK			0xf
+#define RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT	16
+#define RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK		0xf
+#define RADEON_TILING_EG_TILE_SPLIT_SHIFT		24
+#define RADEON_TILING_EG_TILE_SPLIT_MASK		0xf
+#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT	28
+#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK	0xf
 
 struct drm_radeon_gem_set_tiling {
 	uint32_t	handle;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index c94e717..34e35e6 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -3,6 +3,7 @@ header-y += can/
 header-y += caif/
 header-y += dvb/
 header-y += hdlc/
+header-y += hsi/
 header-y += isdn/
 header-y += mmc/
 header-y += nfsd/
@@ -17,6 +18,7 @@ header-y += netfilter_bridge/
 header-y += netfilter_ipv4/
 header-y += netfilter_ipv6/
 header-y += usb/
+header-y += modem_shm/
 header-y += wimax/
 
 objhdr-y += version.h
diff --git a/include/linux/altera_uart.h b/include/linux/altera_uart.h
index a10a907..c022c82 100644
--- a/include/linux/altera_uart.h
+++ b/include/linux/altera_uart.h
@@ -5,8 +5,6 @@
 #ifndef	__ALTUART_H
 #define	__ALTUART_H
 
-#include <linux/init.h>
-
 struct altera_uart_platform_uart {
 	unsigned long mapbase;	/* Physical address base */
 	unsigned int irq;	/* Interrupt vector */
@@ -14,6 +12,4 @@ struct altera_uart_platform_uart {
 	unsigned int bus_shift;	/* Bus shift (address stride) */
 };
 
-int __init early_altera_uart_setup(struct altera_uart_platform_uart *platp);
-
 #endif /* __ALTUART_H */
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 724c69c..a9fab83 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -60,6 +60,9 @@ extern struct bus_type amba_bustype;
 
 int amba_driver_register(struct amba_driver *);
 void amba_driver_unregister(struct amba_driver *);
+struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t);
+void amba_device_put(struct amba_device *);
+int amba_device_add(struct amba_device *, struct resource *);
 int amba_device_register(struct amba_device *, struct resource *);
 void amba_device_unregister(struct amba_device *);
 struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int);
@@ -89,4 +92,37 @@ void amba_release_regions(struct amba_device *);
 #define amba_manf(d)	AMBA_MANF_BITS((d)->periphid)
 #define amba_part(d)	AMBA_PART_BITS((d)->periphid)
 
+#define __AMBA_DEV(busid, data, mask)				\
+	{							\
+		.coherent_dma_mask = mask,			\
+		.init_name = busid,				\
+		.platform_data = data,				\
+	}
+
+/*
+ * APB devices do not themselves have the ability to address memory,
+ * so DMA masks should be zero (much like USB peripheral devices.)
+ * The DMA controller DMA masks should be used instead (much like
+ * USB host controllers in conventional PCs.)
+ */
+#define AMBA_APB_DEVICE(name, busid, id, base, irqs, data)	\
+struct amba_device name##_device = {				\
+	.dev = __AMBA_DEV(busid, data, 0),			\
+	.res = DEFINE_RES_MEM(base, SZ_4K),			\
+	.irq = irqs,						\
+	.periphid = id,						\
+}
+
+/*
+ * AHB devices are DMA capable, so set their DMA masks
+ */
+#define AMBA_AHB_DEVICE(name, busid, id, base, irqs, data)	\
+struct amba_device name##_device = {				\
+	.dev = __AMBA_DEV(busid, data, ~0ULL),			\
+	.res = DEFINE_RES_MEM(base, SZ_4K),			\
+	.dma_mask = ~0ULL,					\
+	.irq = irqs,						\
+	.periphid = id,						\
+}
+
 #endif
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h
index 0101e9c..32a89cf 100644
--- a/include/linux/amba/mmci.h
+++ b/include/linux/amba/mmci.h
@@ -6,6 +6,19 @@
 
 #include <linux/mmc/host.h>
 
+
+/*
+ * These defines is places here due to access is needed from machine
+ * configuration files. The ST Micro version does not have ROD and
+ * reuse the voltage registers for direction settings.
+ */
+#define MCI_ST_DATA2DIREN	(1 << 2)
+#define MCI_ST_CMDDIREN		(1 << 3)
+#define MCI_ST_DATA0DIREN	(1 << 4)
+#define MCI_ST_DATA31DIREN	(1 << 5)
+#define MCI_ST_FBCLKEN		(1 << 7)
+#define MCI_ST_DATA74DIREN	(1 << 8)
+
 /* Just some dummy forwarding */
 struct dma_chan;
 
@@ -18,7 +31,8 @@ struct dma_chan;
  * @ocr_mask: available voltages on the 4 pins from the block, this
  * is ignored if a regulator is used, see the MMC_VDD_* masks in
  * mmc/host.h
- * @vdd_handler: a callback function to translate a MMC_VDD_*
+ * @ios_handler: a callback function to act on specfic ios changes,
+ * used for example to control a levelshifter
  * mask into a value to be binary (or set some other custom bits
  * in MMCIPWR) or:ed and written into the MMCIPWR register of the
  * block.  May also control external power based on the power_mode.
@@ -31,6 +45,8 @@ struct dma_chan;
  * @capabilities: the capabilities of the block as implemented in
  * this platform, signify anything MMC_CAP_* from mmc/host.h
  * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h
+ * @sigdir: a bit field indicating for what bits in the MMC bus the host
+ * should enable signal direction indication.
  * @dma_filter: function used to select an appropriate RX and TX
  * DMA channel to be used for DMA, if and only if you're deploying the
  * generic DMA engine
@@ -46,14 +62,14 @@ struct dma_chan;
 struct mmci_platform_data {
 	unsigned int f_max;
 	unsigned int ocr_mask;
-	u32 (*vdd_handler)(struct device *, unsigned int vdd,
-			   unsigned char power_mode);
+	int (*ios_handler)(struct device *, struct mmc_ios *);
 	unsigned int (*status)(struct device *);
 	int	gpio_wp;
 	int	gpio_cd;
 	bool	cd_invert;
 	unsigned long capabilities;
 	unsigned long capabilities2;
+	u32 sigdir;
 	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
 	void *dma_rx_param;
 	void *dma_tx_param;
diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h
index 572f637..3672f40 100644
--- a/include/linux/amba/pl022.h
+++ b/include/linux/amba/pl022.h
@@ -241,6 +241,8 @@ struct dma_chan;
  * @autosuspend_delay: delay in ms following transfer completion before the
  *     runtime power management system suspends the device. A setting of 0
  *     indicates no delay and the device will be suspended immediately.
+ * @rt: indicates the controller should run the message pump with realtime
+ *     priority to minimise the transfer latency on the bus.
  */
 struct pl022_ssp_controller {
 	u16 bus_id;
@@ -250,6 +252,7 @@ struct pl022_ssp_controller {
 	void *dma_rx_param;
 	void *dma_tx_param;
 	int autosuspend_delay;
+	bool rt;
 };
 
 /**
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 83c209f..b9f65fb 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -136,6 +136,7 @@ struct bcma_device {
 	bool dev_registered;
 
 	u8 core_index;
+	u8 core_unit;
 
 	u32 addr;
 	u32 wrap;
@@ -195,6 +196,7 @@ struct bcma_bus {
 	struct list_head cores;
 	u8 nr_cores;
 	u8 init_done:1;
+	u8 num;
 
 	struct bcma_drv_cc drv_cc;
 	struct bcma_drv_pci drv_pci;
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index a33086a..e72938b 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -181,6 +181,22 @@
 #define BCMA_CC_FLASH_CFG		0x0128
 #define  BCMA_CC_FLASH_CFG_DS		0x0010	/* Data size, 0=8bit, 1=16bit */
 #define BCMA_CC_FLASH_WAITCNT		0x012C
+#define BCMA_CC_SROM_CONTROL		0x0190
+#define  BCMA_CC_SROM_CONTROL_START	0x80000000
+#define  BCMA_CC_SROM_CONTROL_BUSY	0x80000000
+#define  BCMA_CC_SROM_CONTROL_OPCODE	0x60000000
+#define  BCMA_CC_SROM_CONTROL_OP_READ	0x00000000
+#define  BCMA_CC_SROM_CONTROL_OP_WRITE	0x20000000
+#define  BCMA_CC_SROM_CONTROL_OP_WRDIS	0x40000000
+#define  BCMA_CC_SROM_CONTROL_OP_WREN	0x60000000
+#define  BCMA_CC_SROM_CONTROL_OTPSEL	0x00000010
+#define  BCMA_CC_SROM_CONTROL_LOCK	0x00000008
+#define  BCMA_CC_SROM_CONTROL_SIZE_MASK	0x00000006
+#define  BCMA_CC_SROM_CONTROL_SIZE_1K	0x00000000
+#define  BCMA_CC_SROM_CONTROL_SIZE_4K	0x00000002
+#define  BCMA_CC_SROM_CONTROL_SIZE_16K	0x00000004
+#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT	1
+#define  BCMA_CC_SROM_CONTROL_PRESENT	0x00000001
 /* 0x1E0 is defined as shared BCMA_CLKCTLST */
 #define BCMA_CC_HW_WORKAROUND		0x01E4 /* Hardware workaround (rev >= 20) */
 #define BCMA_CC_UART0_DATA		0x0300
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index 3871b66..46c71e2 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -53,6 +53,35 @@ struct pci_dev;
 #define  BCMA_CORE_PCI_SBTOPCI1_MASK		0xFC000000
 #define BCMA_CORE_PCI_SBTOPCI2			0x0108	/* Backplane to PCI translation 2 (sbtopci2) */
 #define  BCMA_CORE_PCI_SBTOPCI2_MASK		0xC0000000
+#define BCMA_CORE_PCI_CONFIG_ADDR		0x0120	/* pcie config space access */
+#define BCMA_CORE_PCI_CONFIG_DATA		0x0124	/* pcie config space access */
+#define BCMA_CORE_PCI_MDIO_CONTROL		0x0128	/* controls the mdio access */
+#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK	0x7f	/* clock to be used on MDIO */
+#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL	0x2
+#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN		0x80	/* Enable preamble sequnce */
+#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE	0x100	/* Tranaction complete */
+#define BCMA_CORE_PCI_MDIO_DATA			0x012c	/* Data to the mdio access */
+#define  BCMA_CORE_PCI_MDIODATA_MASK		0x0000ffff /* data 2 bytes */
+#define  BCMA_CORE_PCI_MDIODATA_TA		0x00020000 /* Turnaround */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD	18	/* Regaddr shift (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD	0x003c0000 /* Regaddr Mask (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD	22	/* Physmedia devaddr shift (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD	0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF	18	/* Regaddr shift */
+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK	0x007c0000 /* Regaddr Mask */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF	23	/* Physmedia devaddr shift */
+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK	0x0f800000 /* Physmedia devaddr Mask */
+#define  BCMA_CORE_PCI_MDIODATA_WRITE		0x10000000 /* write Transaction */
+#define  BCMA_CORE_PCI_MDIODATA_READ		0x20000000 /* Read Transaction */
+#define  BCMA_CORE_PCI_MDIODATA_START		0x40000000 /* start of Transaction */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR	0x0	/* dev address for serdes */
+#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR	0x1F	/* blk address for serdes */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL		0x1d	/* SERDES PLL Dev */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_TX		0x1e	/* SERDES TX Dev */
+#define  BCMA_CORE_PCI_MDIODATA_DEV_RX		0x1f	/* SERDES RX Dev */
+#define BCMA_CORE_PCI_PCIEIND_ADDR		0x0130	/* indirect access to the internal register */
+#define BCMA_CORE_PCI_PCIEIND_DATA		0x0134	/* Data to/from the internal regsiter */
+#define BCMA_CORE_PCI_CLKREQENCTRL		0x0138	/*  >= rev 6, Clkreq rdma control */
 #define BCMA_CORE_PCI_PCICFG0			0x0400	/* PCI config space 0 (rev >= 8) */
 #define BCMA_CORE_PCI_PCICFG1			0x0500	/* PCI config space 1 (rev >= 8) */
 #define BCMA_CORE_PCI_PCICFG2			0x0600	/* PCI config space 2 (rev >= 8) */
@@ -72,20 +101,114 @@ struct pci_dev;
 #define  BCMA_CORE_PCI_SBTOPCI_RC_READL		0x00000010 /* Memory read line */
 #define  BCMA_CORE_PCI_SBTOPCI_RC_READM		0x00000020 /* Memory read multiple */
 
+/* PCIE protocol PHY diagnostic registers */
+#define BCMA_CORE_PCI_PLP_MODEREG		0x200	/* Mode */
+#define BCMA_CORE_PCI_PLP_STATUSREG		0x204	/* Status */
+#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT	0x10	/* Status reg PCIE_PLP_STATUSREG */
+#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG		0x208	/* LTSSM control */
+#define BCMA_CORE_PCI_PLP_LTLINKNUMREG		0x20c	/* Link Training Link number */
+#define BCMA_CORE_PCI_PLP_LTLANENUMREG		0x210	/* Link Training Lane number */
+#define BCMA_CORE_PCI_PLP_LTNFTSREG		0x214	/* Link Training N_FTS */
+#define BCMA_CORE_PCI_PLP_ATTNREG		0x218	/* Attention */
+#define BCMA_CORE_PCI_PLP_ATTNMASKREG		0x21C	/* Attention Mask */
+#define BCMA_CORE_PCI_PLP_RXERRCTR		0x220	/* Rx Error */
+#define BCMA_CORE_PCI_PLP_RXFRMERRCTR		0x224	/* Rx Framing Error */
+#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG	0x228	/* Rx Error threshold */
+#define BCMA_CORE_PCI_PLP_TESTCTRLREG		0x22C	/* Test Control reg */
+#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG	0x230	/* SERDES Control Override */
+#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG		0x234	/* Timing param override */
+#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG		0x238	/* RXTX State Machine Diag */
+#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG		0x23C	/* LTSSM State Machine Diag */
+
+/* PCIE protocol DLLP diagnostic registers */
+#define BCMA_CORE_PCI_DLLP_LCREG		0x100	/* Link Control */
+#define BCMA_CORE_PCI_DLLP_LSREG		0x104	/* Link Status */
+#define BCMA_CORE_PCI_DLLP_LAREG		0x108	/* Link Attention */
+#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP	(1 << 16)
+#define BCMA_CORE_PCI_DLLP_LAMASKREG		0x10C	/* Link Attention Mask */
+#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG	0x110	/* Next Tx Seq Num */
+#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG	0x114	/* Acked Tx Seq Num */
+#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG	0x118	/* Purged Tx Seq Num */
+#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG		0x11C	/* Rx Sequence Number */
+#define BCMA_CORE_PCI_DLLP_LRREG		0x120	/* Link Replay */
+#define BCMA_CORE_PCI_DLLP_LACKTOREG		0x124	/* Link Ack Timeout */
+#define BCMA_CORE_PCI_DLLP_PMTHRESHREG		0x128	/* Power Management Threshold */
+#define BCMA_CORE_PCI_DLLP_RTRYWPREG		0x12C	/* Retry buffer write ptr */
+#define BCMA_CORE_PCI_DLLP_RTRYRPREG		0x130	/* Retry buffer Read ptr */
+#define BCMA_CORE_PCI_DLLP_RTRYPPREG		0x134	/* Retry buffer Purged ptr */
+#define BCMA_CORE_PCI_DLLP_RTRRWREG		0x138	/* Retry buffer Read/Write */
+#define BCMA_CORE_PCI_DLLP_ECTHRESHREG		0x13C	/* Error Count Threshold */
+#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG		0x140	/* TLP Error Counter */
+#define BCMA_CORE_PCI_DLLP_ERRCTRREG		0x144	/* Error Counter */
+#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG		0x148	/* NAK Received Counter */
+#define BCMA_CORE_PCI_DLLP_TESTREG		0x14C	/* Test */
+#define BCMA_CORE_PCI_DLLP_PKTBIST		0x150	/* Packet BIST */
+#define BCMA_CORE_PCI_DLLP_PCIE11		0x154	/* DLLP PCIE 1.1 reg */
+
+/* SERDES RX registers */
+#define BCMA_CORE_PCI_SERDES_RX_CTRL		1	/* Rx cntrl */
+#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE	0x80	/* rxpolarity_force */
+#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY	0x40	/* rxpolarity_value */
+#define BCMA_CORE_PCI_SERDES_RX_TIMER1		2	/* Rx Timer1 */
+#define BCMA_CORE_PCI_SERDES_RX_CDR		6	/* CDR */
+#define BCMA_CORE_PCI_SERDES_RX_CDRBW		7	/* CDR BW */
+
+/* SERDES PLL registers */
+#define BCMA_CORE_PCI_SERDES_PLL_CTRL		1	/* PLL control reg */
+#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN	0x4000	/* bit 14 is FREQDET on */
+
 /* PCIcore specific boardflags */
 #define BCMA_CORE_PCI_BFL_NOPCI			0x00000400 /* Board leaves PCI floating */
 
+/* PCIE Config space accessing MACROS */
+#define BCMA_CORE_PCI_CFG_BUS_SHIFT		24	/* Bus shift */
+#define BCMA_CORE_PCI_CFG_SLOT_SHIFT		19	/* Slot/Device shift */
+#define BCMA_CORE_PCI_CFG_FUN_SHIFT		16	/* Function shift */
+#define BCMA_CORE_PCI_CFG_OFF_SHIFT		0	/* Register shift */
+
+#define BCMA_CORE_PCI_CFG_BUS_MASK		0xff	/* Bus mask */
+#define BCMA_CORE_PCI_CFG_SLOT_MASK		0x1f	/* Slot/Device mask */
+#define BCMA_CORE_PCI_CFG_FUN_MASK		7	/* Function mask */
+#define BCMA_CORE_PCI_CFG_OFF_MASK		0xfff	/* Register mask */
+
+/* PCIE Root Capability Register bits (Host mode only) */
+#define BCMA_CORE_PCI_RC_CRS_VISIBILITY		0x0001
+
+struct bcma_drv_pci;
+
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+struct bcma_drv_pci_host {
+	struct bcma_drv_pci *pdev;
+
+	u32 host_cfg_addr;
+	spinlock_t cfgspace_lock;
+
+	struct pci_controller pci_controller;
+	struct pci_ops pci_ops;
+	struct resource mem_resource;
+	struct resource io_resource;
+};
+#endif
+
 struct bcma_drv_pci {
 	struct bcma_device *core;
 	u8 setup_done:1;
+	u8 hostmode:1;
+
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+	struct bcma_drv_pci_host *host_controller;
+#endif
 };
 
 /* Register access */
 #define pcicore_read32(pc, offset)		bcma_read32((pc)->core, offset)
 #define pcicore_write32(pc, offset, val)	bcma_write32((pc)->core, offset, val)
 
-extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
+extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
 extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
 				 struct bcma_device *core, bool enable);
 
+extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
+extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
+
 #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
diff --git a/include/linux/bcma/bcma_regs.h b/include/linux/bcma/bcma_regs.h
index 9faae2a..5a71d57 100644
--- a/include/linux/bcma/bcma_regs.h
+++ b/include/linux/bcma/bcma_regs.h
@@ -56,4 +56,31 @@
 #define  BCMA_PCI_GPIO_XTAL		0x40	/* PCI config space GPIO 14 for Xtal powerup */
 #define  BCMA_PCI_GPIO_PLL		0x80	/* PCI config space GPIO 15 for PLL powerdown */
 
+/* SiliconBackplane Address Map.
+ * All regions may not exist on all chips.
+ */
+#define BCMA_SOC_SDRAM_BASE		0x00000000U	/* Physical SDRAM */
+#define BCMA_SOC_PCI_MEM		0x08000000U	/* Host Mode sb2pcitranslation0 (64 MB) */
+#define BCMA_SOC_PCI_MEM_SZ		(64 * 1024 * 1024)
+#define BCMA_SOC_PCI_CFG		0x0c000000U	/* Host Mode sb2pcitranslation1 (64 MB) */
+#define BCMA_SOC_SDRAM_SWAPPED		0x10000000U	/* Byteswapped Physical SDRAM */
+#define BCMA_SOC_SDRAM_R2		0x80000000U	/* Region 2 for sdram (512 MB) */
+
+
+#define BCMA_SOC_PCI_DMA		0x40000000U	/* Client Mode sb2pcitranslation2 (1 GB) */
+#define BCMA_SOC_PCI_DMA2		0x80000000U	/* Client Mode sb2pcitranslation2 (1 GB) */
+#define BCMA_SOC_PCI_DMA_SZ		0x40000000U	/* Client Mode sb2pcitranslation2 size in bytes */
+#define BCMA_SOC_PCIE_DMA_L32		0x00000000U	/* PCIE Client Mode sb2pcitranslation2
+							 * (2 ZettaBytes), low 32 bits
+							 */
+#define BCMA_SOC_PCIE_DMA_H32		0x80000000U	/* PCIE Client Mode sb2pcitranslation2
+							 * (2 ZettaBytes), high 32 bits
+							 */
+
+#define BCMA_SOC_PCI1_MEM		0x40000000U	/* Host Mode sb2pcitranslation0 (64 MB) */
+#define BCMA_SOC_PCI1_CFG		0x44000000U	/* Host Mode sb2pcitranslation1 (64 MB) */
+#define BCMA_SOC_PCIE1_DMA_H32		0xc0000000U	/* PCIE Client Mode sb2pcitranslation2
+							 * (2 ZettaBytes), high 32 bits
+							 */
+
 #endif /* LINUX_BCMA_REGS_H_ */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 129a9c0..de5422a 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -101,10 +101,10 @@ static inline int bio_has_allocated_vec(struct bio *bio)
  * I/O completely on that queue (see ide-dma for example)
  */
 #define __bio_kmap_atomic(bio, idx, kmtype)				\
-	(kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page, kmtype) +	\
+	(kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page) +	\
 		bio_iovec_idx((bio), (idx))->bv_offset)
 
-#define __bio_kunmap_atomic(addr, kmtype) kunmap_atomic(addr, kmtype)
+#define __bio_kunmap_atomic(addr, kmtype) kunmap_atomic(addr)
 
 /*
  * merge helpers etc
@@ -317,7 +317,7 @@ static inline char *bvec_kmap_irq(struct bio_vec *bvec, unsigned long *flags)
 	 * balancing is a lot nicer this way
 	 */
 	local_irq_save(*flags);
-	addr = (unsigned long) kmap_atomic(bvec->bv_page, KM_BIO_SRC_IRQ);
+	addr = (unsigned long) kmap_atomic(bvec->bv_page);
 
 	BUG_ON(addr & ~PAGE_MASK);
 
@@ -328,7 +328,7 @@ static inline void bvec_kunmap_irq(char *buffer, unsigned long *flags)
 {
 	unsigned long ptr = (unsigned long) buffer & PAGE_MASK;
 
-	kunmap_atomic((void *) ptr, KM_BIO_SRC_IRQ);
+	kunmap_atomic((void *) ptr);
 	local_irq_restore(*flags);
 }
 
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 94300fe..a3b6b82 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -27,11 +27,22 @@ extern unsigned long __sw_hweight64(__u64 w);
 	     (bit) = find_next_bit((addr), (size), (bit) + 1))
 
 /* same as for_each_set_bit() but use bit as value to start with */
-#define for_each_set_bit_cont(bit, addr, size) \
+#define for_each_set_bit_from(bit, addr, size) \
 	for ((bit) = find_next_bit((addr), (size), (bit));	\
 	     (bit) < (size);					\
 	     (bit) = find_next_bit((addr), (size), (bit) + 1))
 
+#define for_each_clear_bit(bit, addr, size) \
+	for ((bit) = find_first_zero_bit((addr), (size));	\
+	     (bit) < (size);					\
+	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
+
+/* same as for_each_clear_bit() but use bit as value to start with */
+#define for_each_clear_bit_from(bit, addr, size) \
+	for ((bit) = find_next_zero_bit((addr), (size), (bit));	\
+	     (bit) < (size);					\
+	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
+
 static __inline__ int get_bitmask_order(unsigned int count)
 {
 	int order;
diff --git a/include/linux/c2c_genio.h b/include/linux/c2c_genio.h
new file mode 100644
index 0000000..42d22ab
--- /dev/null
+++ b/include/linux/c2c_genio.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland / sjur.brandeland@stericsson.com
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __INC_GENIO_H
+#define __INC_GENIO_H
+#include <linux/types.h>
+
+/**
+ * DOC: C2C GENI/GENO interface.
+ *
+ * This API defines the API for the C2C driver and the GENI/GENO registers.
+ */
+
+/**
+ * enum GENIO_BITS - Definition of special GENIO BITS.
+ * @READY_FOR_IPC_BIT:  Remote side is ready for IPC.
+ * This GENI/GENO bit is triggered when ring-buffer protocol
+ * is enabled from the remote end (modem)
+ *
+ * @READY_FOR_CAIF_BIT: Remote side is ready for CAIF.
+ * This GENI/GENO bit is triggered when CAIF protocol
+ * is enabled from the remote end (modem)
+ */
+enum GENIO_BITS {
+	READY_FOR_CAIF_BIT = 28,
+	READY_FOR_IPC_BIT = 29
+};
+
+/**
+ * genio_subscribe - Subscribe for notifications on bit-change of GENI/O bits.
+ *
+ * @bit:	The GENI/O bit where we want to be called back when it changes.
+ *
+ * @bit_set_cb:	Callback function to be called when the requested GENI/O bit
+ *		is set by the external device (modem).
+ *
+ * @data: Client data to be provided in the callback function.
+ *
+ * Install a callback function for a GENI/O bit. Returns negative upon error.
+ *
+ * The genio driver is expected to handle the 4-state handshake for geni/geno
+ * update, for the bit this function subscribe to. This function may block,
+ * and cannot be called from IRQ context.
+ *
+ * Returns zero on success, and negative upon error.
+ *
+ * Precondition: This function is called after genio_set_shm_addr() and
+ * genio_bit_alloc(). @bit must be defined as as getter in genio_bit_alloc().
+ *
+ * Callback context:
+ *		The "bit_set_cb" callback must be called from the
+ *		IRQ context. The callback function is not allowed to block
+ *		or spend much CPU time in the callback, It must defer
+ *		work to soft-IRQ or work queues.
+ */
+int genio_subscribe(int bit, void (*bit_set_cb)(void *data), void *data);
+
+/**
+ * genio_unsubscribe - Unsubscribe for callback  GENI/O bit.
+ * @bit:       The GENI/O bit to we want release.
+ *
+ * This function may block. It returns zero on success, and negative upon error.
+ *
+ * Precondition: @bit must be defined as as getter in genio_bit_alloc().
+ */
+int genio_unsubscribe(int bit);
+
+/**
+ * genio_bit_alloc - Allocate the usage of GENI/O bits.
+ *
+ * @setter_mask:	Bit-mask defining the bits that can be set by
+ *			genio_set_bit()
+ * @getter_mask:	Bit-mask defining the bits that can be subscribed by
+ *			genio_subscribe().
+ *
+ * The @getter_mask defines the bit for RX direction, i.e. bits that can
+ * be subscribed by the function genio_subscribe().
+ * The @setter_mask defines the bit for TX direction, i.e. bits that can
+ * be set by the function genio_set_bit().
+ * This function may block.
+ *
+ * Returns zero on success, and negative upon error.
+ *
+ * Precondition:
+ * This function cannot be called before ipc_ready_cb() has been called,
+ * and must be called prior to any call on genio_subscribe() or genio_set_bit().
+ *
+ */
+int genio_bit_alloc(u32 setter_mask, u32 getter_mask);
+
+/**
+ * genio_set_shm_addr - Inform remote device about the shared memory address.
+ * @addr:		The shared memory address.
+ * @ipc_ready_cb:	The callback function indicating IPC is ready.
+ *
+ * Description:
+ * Implements the setting of shared memory address involving the
+ * READY_FOR_IPC GENIO bits, and READY_FOR_IPC handshaking.
+ * When handshaking is done ipc_ready_cb is called.
+ * The usage of this bit is during start/restart.
+ * This function may block.
+ *
+ * When the ipc_ready_cb() with @ready=%true, Stream channels can be opened.
+ *
+ * Sequence:
+ * (1) Write the address to the GENO register,
+ *
+ * (2) wait for interrupt on IPC_READY (set to one in GENI register)
+ *
+ * (3) write zero to the GENO register
+ *
+ * (4) wait for interrupt on IPC_READY (set to zero)
+ *
+ * (5) call the callback function for IPC_READY
+ *
+ * Returns zero on success, and negative upon error.
+ *
+ * Precondition:
+ * This function must be called initially upon start, or after remote device
+ * has been reset.
+ */
+int genio_set_shm_addr(u32 addr, void (*ipc_ready_cb) (void));
+
+/**
+ * genio_subscribe_caif_ready - Notify that CAIF channels can be
+ * opened.
+ *
+ * @caif_ready_cb: is called with @ready = %true in the start up sequence,
+ * when the remote side is ready for CAIF enumeration. Upon reset,
+ * caif_ready_cb() will be called with @ready = %false.
+ *
+ * The %READY_FOR_CAIF_BIT is set to %one as long as the
+ * modem is able to run CAIF traffic. Upon modem restart/crash it will
+ * be set back to %zero.
+ * This function may block.
+ *
+ * Returns zero on success, and negative upon error.
+ */
+int genio_subscribe_caif_ready(void (*caif_ready_cb) (bool ready));
+
+/**
+ * genio_register_errhandler - Register an error handler.
+ *
+ * @errhandler: error handler called from driver upon severe errors
+ *		that requires reset of the remote device.
+ */
+void genio_register_errhandler(void (*errhandler)(int errno));
+
+/**
+ * genio_reset() - Reset the C2C driver
+ *
+ * Reset the C2C Driver due to remote device restart.
+ * This shall reset state back to initial state, and should only
+ * be used when remote device (modem) has reset.
+ *
+ * All settings, subscriptions and state information in the driver must
+ * be reset. GENIO client must do all subscriptions again.
+ * This function may block.
+ *
+ * Returns zero on success, and negative upon error.
+ */
+int genio_reset(void);
+
+/**
+ * genio_set_bit() -	Set a single GENI/O bit.
+ *
+ * @bit:	The GENI/O bit to set
+ *
+ * This function is used to signal over GENI/GENO the driver must
+ * perform the 4-state protocol to signal the change to remote device.
+ * This function is non-blocking, and can be called from Soft-IRQ context.
+ *
+ * Returns zero on success, and negative upon error.
+ *
+ * Precondition: @bit must be defined as as setter in genio_bit_alloc().
+ */
+int genio_set_bit(int bit);
+
+/**
+ * genio_power_req() -	Request power on on remote C2C block.
+ *
+ * @state:	1 - power-on request , 0 - power-off request
+ *
+ * This function will request power on of remote C2C block.
+ * This function is non-blocking, and can be called from Soft-IRQ context.
+ *
+ * Returns zero on success, and negative upon error.
+ */
+int genio_power_req(int state);
+
+#endif /*INC_GENIO_H*/
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index a0969fc..5d2efe7 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -92,7 +92,7 @@ void can_bus_off(struct net_device *dev);
 
 void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
 		      unsigned int idx);
-void can_get_echo_skb(struct net_device *dev, unsigned int idx);
+unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx);
 void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 
 struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index e9b6021..5a85b34 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -160,38 +160,6 @@ enum {
 	CGRP_CLONE_CHILDREN,
 };
 
-/* which pidlist file are we talking about? */
-enum cgroup_filetype {
-	CGROUP_FILE_PROCS,
-	CGROUP_FILE_TASKS,
-};
-
-/*
- * A pidlist is a list of pids that virtually represents the contents of one
- * of the cgroup files ("procs" or "tasks"). We keep a list of such pidlists,
- * a pair (one each for procs, tasks) for each pid namespace that's relevant
- * to the cgroup.
- */
-struct cgroup_pidlist {
-	/*
-	 * used to find which pidlist is wanted. doesn't change as long as
-	 * this particular list stays in the list.
-	 */
-	struct { enum cgroup_filetype type; struct pid_namespace *ns; } key;
-	/* array of xids */
-	pid_t *list;
-	/* how many elements the above list has */
-	int length;
-	/* how many files are using the current array */
-	int use_count;
-	/* each of these stored in a list by its cgroup */
-	struct list_head links;
-	/* pointer to the cgroup we belong to, for list removal purposes */
-	struct cgroup *owner;
-	/* protects the other fields */
-	struct rw_semaphore mutex;
-};
-
 struct cgroup {
 	unsigned long flags;		/* "unsigned long" so bitops work */
 
@@ -484,23 +452,18 @@ int cgroup_taskset_size(struct cgroup_taskset *tset);
  */
 
 struct cgroup_subsys {
-	struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
-						  struct cgroup *cgrp);
-	int (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
-	void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp);
-	int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			  struct cgroup_taskset *tset);
-	void (*cancel_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			      struct cgroup_taskset *tset);
-	void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp,
-		       struct cgroup_taskset *tset);
-	void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
-	void (*exit)(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			struct cgroup *old_cgrp, struct task_struct *task);
-	int (*populate)(struct cgroup_subsys *ss,
-			struct cgroup *cgrp);
-	void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cgrp);
-	void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
+	struct cgroup_subsys_state *(*create)(struct cgroup *cgrp);
+	int (*pre_destroy)(struct cgroup *cgrp);
+	void (*destroy)(struct cgroup *cgrp);
+	int (*can_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
+	void (*cancel_attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
+	void (*attach)(struct cgroup *cgrp, struct cgroup_taskset *tset);
+	void (*fork)(struct task_struct *task);
+	void (*exit)(struct cgroup *cgrp, struct cgroup *old_cgrp,
+		     struct task_struct *task);
+	int (*populate)(struct cgroup_subsys *ss, struct cgroup *cgrp);
+	void (*post_clone)(struct cgroup *cgrp);
+	void (*bind)(struct cgroup *root);
 
 	int subsys_id;
 	int active;
@@ -535,7 +498,7 @@ struct cgroup_subsys {
 	struct list_head sibling;
 	/* used when use_id == true */
 	struct idr idr;
-	rwlock_t id_lock;
+	spinlock_t id_lock;
 
 	/* should be defined only by modular subsystems */
 	struct module *module;
@@ -602,11 +565,6 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan);
 int cgroup_attach_task(struct cgroup *, struct task_struct *);
 int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
 
-static inline int cgroup_attach_task_current_cg(struct task_struct *tsk)
-{
-	return cgroup_attach_task_all(current, tsk);
-}
-
 /*
  * CSS ID is ID for cgroup_subsys_state structs under subsys. This only works
  * if cgroup_subsys.use_id == true. It can be used for looking up and scanning.
@@ -669,10 +627,6 @@ static inline int cgroup_attach_task_all(struct task_struct *from,
 {
 	return 0;
 }
-static inline int cgroup_attach_task_current_cg(struct task_struct *t)
-{
-	return 0;
-}
 
 #endif /* !CONFIG_CGROUPS */
 
diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h
index 04ffb2e..42e55de 100644
--- a/include/linux/cleancache.h
+++ b/include/linux/cleancache.h
@@ -28,9 +28,9 @@ struct cleancache_ops {
 			pgoff_t, struct page *);
 	void (*put_page)(int, struct cleancache_filekey,
 			pgoff_t, struct page *);
-	void (*flush_page)(int, struct cleancache_filekey, pgoff_t);
-	void (*flush_inode)(int, struct cleancache_filekey);
-	void (*flush_fs)(int);
+	void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t);
+	void (*invalidate_inode)(int, struct cleancache_filekey);
+	void (*invalidate_fs)(int);
 };
 
 extern struct cleancache_ops
@@ -39,9 +39,9 @@ extern void __cleancache_init_fs(struct super_block *);
 extern void __cleancache_init_shared_fs(char *, struct super_block *);
 extern int  __cleancache_get_page(struct page *);
 extern void __cleancache_put_page(struct page *);
-extern void __cleancache_flush_page(struct address_space *, struct page *);
-extern void __cleancache_flush_inode(struct address_space *);
-extern void __cleancache_flush_fs(struct super_block *);
+extern void __cleancache_invalidate_page(struct address_space *, struct page *);
+extern void __cleancache_invalidate_inode(struct address_space *);
+extern void __cleancache_invalidate_fs(struct super_block *);
 extern int cleancache_enabled;
 
 #ifdef CONFIG_CLEANCACHE
@@ -99,24 +99,24 @@ static inline void cleancache_put_page(struct page *page)
 		__cleancache_put_page(page);
 }
 
-static inline void cleancache_flush_page(struct address_space *mapping,
+static inline void cleancache_invalidate_page(struct address_space *mapping,
 					struct page *page)
 {
 	/* careful... page->mapping is NULL sometimes when this is called */
 	if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping))
-		__cleancache_flush_page(mapping, page);
+		__cleancache_invalidate_page(mapping, page);
 }
 
-static inline void cleancache_flush_inode(struct address_space *mapping)
+static inline void cleancache_invalidate_inode(struct address_space *mapping)
 {
 	if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping))
-		__cleancache_flush_inode(mapping);
+		__cleancache_invalidate_inode(mapping);
 }
 
-static inline void cleancache_flush_fs(struct super_block *sb)
+static inline void cleancache_invalidate_fs(struct super_block *sb)
 {
 	if (cleancache_enabled)
-		__cleancache_flush_fs(sb);
+		__cleancache_invalidate_fs(sb);
 }
 
 #endif /* _LINUX_CLEANCACHE_H */
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index bb2bbdb..51a90b7 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -23,6 +23,7 @@ extern int fragmentation_index(struct zone *zone, unsigned int order);
 extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
 			int order, gfp_t gfp_mask, nodemask_t *mask,
 			bool sync);
+extern int compact_pgdat(pg_data_t *pgdat, int order);
 extern unsigned long compaction_suitable(struct zone *zone, int order);
 
 /* Do not skip compaction more than 64 times */
@@ -33,20 +34,26 @@ extern unsigned long compaction_suitable(struct zone *zone, int order);
  * allocation success. 1 << compact_defer_limit compactions are skipped up
  * to a limit of 1 << COMPACT_MAX_DEFER_SHIFT
  */
-static inline void defer_compaction(struct zone *zone)
+static inline void defer_compaction(struct zone *zone, int order)
 {
 	zone->compact_considered = 0;
 	zone->compact_defer_shift++;
 
+	if (order < zone->compact_order_failed)
+		zone->compact_order_failed = order;
+
 	if (zone->compact_defer_shift > COMPACT_MAX_DEFER_SHIFT)
 		zone->compact_defer_shift = COMPACT_MAX_DEFER_SHIFT;
 }
 
 /* Returns true if compaction should be skipped this time */
-static inline bool compaction_deferred(struct zone *zone)
+static inline bool compaction_deferred(struct zone *zone, int order)
 {
 	unsigned long defer_limit = 1UL << zone->compact_defer_shift;
 
+	if (order < zone->compact_order_failed)
+		return false;
+
 	/* Avoid possible overflow */
 	if (++zone->compact_considered > defer_limit)
 		zone->compact_considered = defer_limit;
@@ -62,16 +69,21 @@ static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
 	return COMPACT_CONTINUE;
 }
 
+static inline int compact_pgdat(pg_data_t *pgdat, int order)
+{
+	return COMPACT_CONTINUE;
+}
+
 static inline unsigned long compaction_suitable(struct zone *zone, int order)
 {
 	return COMPACT_SKIPPED;
 }
 
-static inline void defer_compaction(struct zone *zone)
+static inline void defer_compaction(struct zone *zone, int order)
 {
 }
 
-static inline bool compaction_deferred(struct zone *zone)
+static inline bool compaction_deferred(struct zone *zone, int order)
 {
 	return 1;
 }
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 41c9f65..c7f22d3 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -224,6 +224,7 @@ struct compat_sysinfo;
 struct compat_sysctl_args;
 struct compat_kexec_segment;
 struct compat_mq_attr;
+struct compat_msgbuf;
 
 extern void compat_exit_robust_list(struct task_struct *curr);
 
@@ -234,13 +235,22 @@ asmlinkage long
 compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
 			   compat_size_t __user *len_ptr);
 
+#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
 long compat_sys_semctl(int first, int second, int third, void __user *uptr);
 long compat_sys_msgsnd(int first, int second, int third, void __user *uptr);
 long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
 		int version, void __user *uptr);
-long compat_sys_msgctl(int first, int second, void __user *uptr);
 long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
 		void __user *uptr);
+#else
+long compat_sys_semctl(int semid, int semnum, int cmd, int arg);
+long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
+		size_t msgsz, int msgflg);
+long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
+		size_t msgsz, long msgtyp, int msgflg);
+long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg);
+#endif
+long compat_sys_msgctl(int first, int second, void __user *uptr);
 long compat_sys_shmctl(int first, int second, void __user *uptr);
 long compat_sys_semtimedop(int semid, struct sembuf __user *tsems,
 		unsigned nsems, const struct compat_timespec __user *timeout);
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 3fd17c2..e5834aa 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -87,7 +87,8 @@
  */
 #define __pure				__attribute__((pure))
 #define __aligned(x)			__attribute__((aligned(x)))
-#define __printf(a,b)			__attribute__((format(printf,a,b)))
+#define __printf(a, b)			__attribute__((format(printf, a, b)))
+#define __scanf(a, b)			__attribute__((format(scanf, a, b)))
 #define  noinline			__attribute__((noinline))
 #define __attribute_const__		__attribute__((__const__))
 #define __maybe_unused			__attribute__((unused))
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 3c9c54f..7638407 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -43,6 +43,7 @@
 #define CN_IDX_DRBD			0x8
 #define CN_VAL_DRBD			0x1
 #define CN_KVP_IDX			0x9	/* HyperV KVP */
+#define CN_KVP_VAL			0x1	/* queries from the kernel */
 
 #define CN_NETLINK_USERS		10	/* Highest index + 1 */
 
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 1f65875..6e53b48 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -44,6 +44,13 @@ extern ssize_t arch_cpu_release(const char *, size_t);
 #endif
 struct notifier_block;
 
+#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
+extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env);
+extern ssize_t arch_print_cpu_modalias(struct device *dev,
+				       struct device_attribute *attr,
+				       char *bufptr);
+#endif
+
 /*
  * CPU notifier priorities.
  */
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 4f7a632..be05261 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -27,6 +27,9 @@ typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 extern int nr_cpu_ids;
 #endif
 
+extern unsigned int nr_online_cpus;
+extern unsigned int nr_possible_cpus;
+
 #ifdef CONFIG_CPUMASK_OFFSTACK
 /* Assuming NR_CPUS is huge, a runtime limit is more efficient.  Also,
  * not all bits may be allocated. */
@@ -81,8 +84,10 @@ extern const struct cpumask *const cpu_present_mask;
 extern const struct cpumask *const cpu_active_mask;
 
 #if NR_CPUS > 1
-#define num_online_cpus()	cpumask_weight(cpu_online_mask)
-#define num_possible_cpus()	cpumask_weight(cpu_possible_mask)
+
+#define num_online_cpus()	(nr_online_cpus)
+#define num_possible_cpus()	(nr_possible_cpus)
+
 #define num_present_cpus()	cpumask_weight(cpu_present_mask)
 #define num_active_cpus()	cpumask_weight(cpu_active_mask)
 #define cpu_online(cpu)		cpumask_test_cpu((cpu), cpu_online_mask)
@@ -809,11 +814,10 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu)
 #else /* NR_CPUS > 1 */
 int __first_cpu(const cpumask_t *srcp);
 int __next_cpu(int n, const cpumask_t *srcp);
-int __any_online_cpu(const cpumask_t *mask);
 
 #define first_cpu(src)		__first_cpu(&(src))
 #define next_cpu(n, src)	__next_cpu((n), &(src))
-#define any_online_cpu(mask) __any_online_cpu(&(mask))
+#define any_online_cpu(mask) cpumask_any_and(&mask, cpu_online_mask)
 #define for_each_cpu_mask(cpu, mask)			\
 	for ((cpu) = -1;				\
 		(cpu) = next_cpu((cpu), (mask)),	\
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 391a259..68267b6 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -11,6 +11,8 @@
 extern u32  crc32_le(u32 crc, unsigned char const *p, size_t len);
 extern u32  crc32_be(u32 crc, unsigned char const *p, size_t len);
 
+extern u32  __crc32c_le(u32 crc, unsigned char const *p, size_t len);
+
 #define crc32(seed, data, length)  crc32_le(seed, (unsigned char const *)(data), length)
 
 /*
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 8a94217..48ce547 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -75,6 +75,11 @@
  */
 #define CRYPTO_ALG_INSTANCE		0x00000800
 
+/* Set this bit if the algorithm provided is hardware accelerated but
+ * not available to userspace via instruction set or so.
+ */
+#define CRYPTO_ALG_KERN_DRIVER_ONLY	0x00001000
+
 /*
  * Transform masks and values (for crt_flags).
  */
@@ -309,6 +314,8 @@ struct crypto_alg {
  */
 int crypto_register_alg(struct crypto_alg *alg);
 int crypto_unregister_alg(struct crypto_alg *alg);
+int crypto_register_algs(struct crypto_alg *algs, int count);
+int crypto_unregister_algs(struct crypto_alg *algs, int count);
 
 /*
  * Algorithm query interface.
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index d64a55b..8c33247 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -250,7 +250,6 @@ extern void shrink_dcache_for_umount(struct super_block *);
 extern int d_invalidate(struct dentry *);
 
 /* only used at mount-time */
-extern struct dentry * d_alloc_root(struct inode *);
 extern struct dentry * d_make_root(struct inode *);
 
 /* <clickety>-<click> the ramfs-type tree */
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 98ce812..5862475 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -124,6 +124,8 @@ struct devfreq_governor {
  *		touch this.
  * @being_removed	a flag to mark that this object is being removed in
  *			order to prevent trying to remove the object multiple times.
+ * @min_freq	Limit minimum frequency requested by user (0: none)
+ * @max_freq	Limit maximum frequency requested by user (0: none)
  *
  * This structure stores the devfreq information for a give device.
  *
@@ -149,6 +151,9 @@ struct devfreq {
 	void *data; /* private data for governors */
 
 	bool being_removed;
+
+	unsigned long min_freq;
+	unsigned long max_freq;
 };
 
 #if defined(CONFIG_PM_DEVFREQ)
@@ -200,12 +205,12 @@ struct devfreq_simple_ondemand_data {
 static struct devfreq *devfreq_add_device(struct device *dev,
 					  struct devfreq_dev_profile *profile,
 					  struct devfreq_governor *governor,
-					  void *data);
+					  void *data)
 {
 	return NULL;
 }
 
-static int devfreq_remove_device(struct devfreq *devfreq);
+static int devfreq_remove_device(struct devfreq *devfreq)
 {
 	return 0;
 }
diff --git a/include/linux/device.h b/include/linux/device.h
index b63fb39..f62e216 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -238,8 +238,6 @@ struct device_driver {
 extern int __must_check driver_register(struct device_driver *drv);
 extern void driver_unregister(struct device_driver *drv);
 
-extern struct device_driver *get_driver(struct device_driver *drv);
-extern void put_driver(struct device_driver *drv);
 extern struct device_driver *driver_find(const char *name,
 					 struct bus_type *bus);
 extern int driver_probe_done(void);
@@ -946,14 +944,14 @@ int _dev_info(const struct device *dev, const char *fmt, ...)
 
 #define dev_info(dev, fmt, arg...) _dev_info(dev, fmt, ##arg)
 
-#if defined(DEBUG)
-#define dev_dbg(dev, format, arg...)		\
-	dev_printk(KERN_DEBUG, dev, format, ##arg)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
+#if defined(CONFIG_DYNAMIC_DEBUG)
 #define dev_dbg(dev, format, ...)		     \
 do {						     \
 	dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
 } while (0)
+#elif defined(DEBUG)
+#define dev_dbg(dev, format, arg...)		\
+	dev_printk(KERN_DEBUG, dev, format, ##arg)
 #else
 #define dev_dbg(dev, format, arg...)				\
 ({								\
diff --git a/include/linux/digsig.h b/include/linux/digsig.h
index b01558b..6f85a07 100644
--- a/include/linux/digsig.h
+++ b/include/linux/digsig.h
@@ -30,7 +30,7 @@ enum digest_algo {
 
 struct pubkey_hdr {
 	uint8_t		version;	/* key format version */
-	time_t		timestamp;	/* key made, always 0 for now */
+	uint32_t	timestamp;	/* key made, always 0 for now */
 	uint8_t		algo;
 	uint8_t		nmpi;
 	char		mpi[0];
@@ -38,7 +38,7 @@ struct pubkey_hdr {
 
 struct signature_hdr {
 	uint8_t		version;	/* signature format version */
-	time_t		timestamp;	/* signature made */
+	uint32_t	timestamp;	/* signature made */
 	uint8_t		algo;
 	uint8_t		hash;
 	uint8_t		keyid[8];
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
index 71ad34e..547ab56 100644
--- a/include/linux/dma-attrs.h
+++ b/include/linux/dma-attrs.h
@@ -13,6 +13,8 @@
 enum dma_attr {
 	DMA_ATTR_WRITE_BARRIER,
 	DMA_ATTR_WEAK_ORDERING,
+	DMA_ATTR_WRITE_COMBINE,
+	DMA_ATTR_NON_CONSISTENT,
 	DMA_ATTR_MAX,
 };
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index e13117c..b903a20 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -9,10 +9,15 @@
 #include <linux/scatterlist.h>
 
 struct dma_map_ops {
-	void* (*alloc_coherent)(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t gfp);
-	void (*free_coherent)(struct device *dev, size_t size,
-			      void *vaddr, dma_addr_t dma_handle);
+	void* (*alloc)(struct device *dev, size_t size,
+				dma_addr_t *dma_handle, gfp_t gfp,
+				struct dma_attrs *attrs);
+	void (*free)(struct device *dev, size_t size,
+			      void *vaddr, dma_addr_t dma_handle,
+			      struct dma_attrs *attrs);
+	int (*mmap)(struct device *, struct vm_area_struct *,
+			  void *, dma_addr_t, size_t, struct dma_attrs *attrs);
+
 	dma_addr_t (*map_page)(struct device *dev, struct page *page,
 			       unsigned long offset, size_t size,
 			       enum dma_data_direction dir,
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 0564e3c..7e3c53a 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -15,20 +15,24 @@ struct _ddebug {
 	const char *function;
 	const char *filename;
 	const char *format;
-	unsigned int lineno:24;
+	unsigned int lineno:18;
 	/*
  	 * The flags field controls the behaviour at the callsite.
  	 * The bits here are changed dynamically when the user
 	 * writes commands to <debugfs>/dynamic_debug/control
 	 */
-#define _DPRINTK_FLAGS_PRINT   (1<<0)  /* printk() a message using the format */
+#define _DPRINTK_FLAGS_NONE	0
+#define _DPRINTK_FLAGS_PRINT	(1<<0) /* printk() a message using the format */
 #define _DPRINTK_FLAGS_INCL_MODNAME	(1<<1)
 #define _DPRINTK_FLAGS_INCL_FUNCNAME	(1<<2)
 #define _DPRINTK_FLAGS_INCL_LINENO	(1<<3)
 #define _DPRINTK_FLAGS_INCL_TID		(1<<4)
+#if defined DEBUG
+#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
+#else
 #define _DPRINTK_FLAGS_DEFAULT 0
+#endif
 	unsigned int flags:8;
-	char enabled;
 } __attribute__((aligned(8)));
 
 
@@ -62,21 +66,20 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
 		.format = (fmt),				\
 		.lineno = __LINE__,				\
 		.flags =  _DPRINTK_FLAGS_DEFAULT,		\
-		.enabled = false,				\
 	}
 
 #define dynamic_pr_debug(fmt, ...)				\
 do {								\
 	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);		\
-	if (unlikely(descriptor.enabled))			\
+	if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT))	\
 		__dynamic_pr_debug(&descriptor, pr_fmt(fmt),	\
 				   ##__VA_ARGS__);		\
 } while (0)
 
 #define dynamic_dev_dbg(dev, fmt, ...)				\
 do {								\
-	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);	\
-	if (unlikely(descriptor.enabled))			\
+	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);		\
+	if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT))	\
 		__dynamic_dev_dbg(&descriptor, dev, fmt,	\
 				  ##__VA_ARGS__);		\
 } while (0)
@@ -84,7 +87,7 @@ do {								\
 #define dynamic_netdev_dbg(dev, fmt, ...)			\
 do {								\
 	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);		\
-	if (unlikely(descriptor.enabled))			\
+	if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT))	\
 		__dynamic_netdev_dbg(&descriptor, dev, fmt,	\
 				     ##__VA_ARGS__);		\
 } while (0)
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 05955cf..8a18358 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -140,17 +140,18 @@ static inline void random_ether_addr(u8 *addr)
 }
 
 /**
- * dev_hw_addr_random - Create random MAC and set device flag
+ * eth_hw_addr_random - Generate software assigned random Ethernet and
+ * set device flag
  * @dev: pointer to net_device structure
- * @hwaddr: Pointer to a six-byte array containing the Ethernet address
  *
- * Generate random MAC to be used by a device and set addr_assign_type
- * so the state can be read by sysfs and be used by udev.
+ * Generate a random Ethernet address (MAC) to be used by a net device
+ * and set addr_assign_type so the state can be read by sysfs and be
+ * used by userspace.
  */
-static inline void dev_hw_addr_random(struct net_device *dev, u8 *hwaddr)
+static inline void eth_hw_addr_random(struct net_device *dev)
 {
 	dev->addr_assign_type |= NET_ADDR_RANDOM;
-	random_ether_addr(hwaddr);
+	random_ether_addr(dev->dev_addr);
 }
 
 /**
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h
index 6c6133f..b5fac2b 100644
--- a/include/linux/fanotify.h
+++ b/include/linux/fanotify.h
@@ -36,9 +36,12 @@
 #define FAN_UNLIMITED_QUEUE	0x00000010
 #define FAN_UNLIMITED_MARKS	0x00000020
 
+/* Attempt read-only open if read-write failed. */
+#define FAN_READONLY_FALLBACK  0x00000040
+
 #define FAN_ALL_INIT_FLAGS	(FAN_CLOEXEC | FAN_NONBLOCK | \
 				 FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\
-				 FAN_UNLIMITED_MARKS)
+				 FAN_UNLIMITED_MARKS | FAN_READONLY_FALLBACK)
 
 /* flags used for fanotify_modify_mark() */
 #define FAN_MARK_ADD		0x00000001
diff --git a/include/linux/fb.h b/include/linux/fb.h
index c18122f..a395b8c 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern int unregister_framebuffer(struct fb_info *fb_info);
+extern int unlink_framebuffer(struct fb_info *fb_info);
 extern void remove_conflicting_framebuffers(struct apertures_struct *a,
 				const char *name, bool primary);
 extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
diff --git a/include/linux/file.h b/include/linux/file.h
index 21a7995..58bf158 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -12,7 +12,6 @@
 struct file;
 
 extern void fput(struct file *);
-extern void drop_file_write_access(struct file *file);
 
 struct file_operations;
 struct vfsmount;
diff --git a/include/linux/firewire.h b/include/linux/firewire.h
index 84ccf8e..6f1d738 100644
--- a/include/linux/firewire.h
+++ b/include/linux/firewire.h
@@ -203,18 +203,6 @@ static inline int fw_device_is_shutdown(struct fw_device *device)
 	return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN;
 }
 
-static inline struct fw_device *fw_device_get(struct fw_device *device)
-{
-	get_device(&device->device);
-
-	return device;
-}
-
-static inline void fw_device_put(struct fw_device *device)
-{
-	put_device(&device->device);
-}
-
 int fw_device_enable_phys_dma(struct fw_device *device);
 
 /*
diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h
new file mode 100644
index 0000000..3e46c31
--- /dev/null
+++ b/include/linux/frontswap.h
@@ -0,0 +1,126 @@
+#ifndef _LINUX_FRONTSWAP_H
+#define _LINUX_FRONTSWAP_H
+
+#include <linux/swap.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+
+struct frontswap_ops {
+	void (*init)(unsigned);
+	int (*put_page)(unsigned, pgoff_t, struct page *);
+	int (*get_page)(unsigned, pgoff_t, struct page *);
+	void (*invalidate_page)(unsigned, pgoff_t);
+	void (*invalidate_area)(unsigned);
+};
+
+extern int frontswap_enabled;
+extern struct frontswap_ops
+	frontswap_register_ops(struct frontswap_ops *ops);
+extern void frontswap_shrink(unsigned long);
+extern unsigned long frontswap_curr_pages(void);
+
+extern void __frontswap_init(unsigned type);
+extern int __frontswap_put_page(struct page *page);
+extern int __frontswap_get_page(struct page *page);
+extern void __frontswap_invalidate_page(unsigned, pgoff_t);
+extern void __frontswap_invalidate_area(unsigned);
+
+#ifdef CONFIG_FRONTSWAP
+
+static inline int frontswap_test(struct swap_info_struct *sis, pgoff_t offset)
+{
+	int ret = 0;
+
+	if (frontswap_enabled && sis->frontswap_map)
+		ret = test_bit(offset, sis->frontswap_map);
+	return ret;
+}
+
+static inline void frontswap_set(struct swap_info_struct *sis, pgoff_t offset)
+{
+	if (frontswap_enabled && sis->frontswap_map)
+		set_bit(offset, sis->frontswap_map);
+}
+
+static inline void frontswap_clear(struct swap_info_struct *sis, pgoff_t offset)
+{
+	if (frontswap_enabled && sis->frontswap_map)
+		clear_bit(offset, sis->frontswap_map);
+}
+
+static inline void frontswap_map_set(struct swap_info_struct *p,
+				     unsigned long *map)
+{
+	p->frontswap_map = map;
+}
+
+static inline unsigned long *frontswap_map_get(struct swap_info_struct *p)
+{
+	return p->frontswap_map;
+}
+#else
+/* all inline routines become no-ops and all externs are ignored */
+
+#define frontswap_enabled (0)
+
+static inline int frontswap_test(struct swap_info_struct *sis, pgoff_t offset)
+{
+	return 0;
+}
+
+static inline void frontswap_set(struct swap_info_struct *sis, pgoff_t offset)
+{
+}
+
+static inline void frontswap_clear(struct swap_info_struct *sis, pgoff_t offset)
+{
+}
+
+static inline void frontswap_map_set(struct swap_info_struct *p,
+				     unsigned long *map)
+{
+}
+
+static inline unsigned long *frontswap_map_get(struct swap_info_struct *p)
+{
+	return NULL;
+}
+#endif
+
+static inline int frontswap_put_page(struct page *page)
+{
+	int ret = -1;
+
+	if (frontswap_enabled)
+		ret = __frontswap_put_page(page);
+	return ret;
+}
+
+static inline int frontswap_get_page(struct page *page)
+{
+	int ret = -1;
+
+	if (frontswap_enabled)
+		ret = __frontswap_get_page(page);
+	return ret;
+}
+
+static inline void frontswap_invalidate_page(unsigned type, pgoff_t offset)
+{
+	if (frontswap_enabled)
+		__frontswap_invalidate_page(type, offset);
+}
+
+static inline void frontswap_invalidate_area(unsigned type)
+{
+	if (frontswap_enabled)
+		__frontswap_invalidate_area(type);
+}
+
+static inline void frontswap_init(unsigned type)
+{
+	if (frontswap_enabled)
+		__frontswap_init(type);
+}
+
+#endif /* _LINUX_FRONTSWAP_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 386da09..b89dc4d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1459,6 +1459,7 @@ struct super_block {
 	u8 s_uuid[16];				/* UUID */
 
 	void 			*s_fs_info;	/* Filesystem private info */
+	unsigned int		s_max_links;
 	fmode_t			s_mode;
 
 	/* Granularity of c/m/atime in ns.
@@ -2304,7 +2305,10 @@ extern struct inode * igrab(struct inode *);
 extern ino_t iunique(struct super_block *, ino_t);
 extern int inode_needs_sync(struct inode *inode);
 extern int generic_delete_inode(struct inode *inode);
-extern int generic_drop_inode(struct inode *inode);
+static inline int generic_drop_inode(struct inode *inode)
+{
+	return !inode->i_nlink || inode_unhashed(inode);
+}
 
 extern struct inode *ilookup5_nowait(struct super_block *sb,
 		unsigned long hashval, int (*test)(struct inode *, void *),
@@ -2496,6 +2500,7 @@ extern void get_filesystem(struct file_system_type *fs);
 extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
+extern struct super_block *get_super_thawed(struct block_device *);
 extern struct super_block *get_active_super(struct block_device *bdev);
 extern void drop_super(struct super_block *sb);
 extern void iterate_supers(void (*)(struct super_block *, void *), void *);
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 91d0e0a3..226c791 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -125,6 +125,7 @@ struct fsnotify_group {
 
 	const struct fsnotify_ops *ops;	/* how this group handles things */
 
+	struct mutex mutex;
 	/* needed to send notification to userspace */
 	struct mutex notification_mutex;	/* protect the notification_list */
 	struct list_head notification_list;	/* list of event_holder this group needs to send to userspace */
@@ -168,6 +169,7 @@ struct fsnotify_group {
 			wait_queue_head_t access_waitq;
 			atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
+			bool readonly_fallback;
 			int f_flags;
 			unsigned int max_marks;
 			struct user_struct *user;
@@ -415,8 +417,6 @@ extern void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group);
 extern void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group, unsigned int flags);
 /* run all the marks in a group, and flag them to be freed */
 extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group);
-extern void fsnotify_get_mark(struct fsnotify_mark *mark);
-extern void fsnotify_put_mark(struct fsnotify_mark *mark);
 extern void fsnotify_unmount_inodes(struct list_head *list);
 
 /* put here because inotify does some weird stuff when destroying watches */
@@ -430,6 +430,16 @@ extern struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_ev
 extern int fsnotify_replace_event(struct fsnotify_event_holder *old_holder,
 				  struct fsnotify_event *new_event);
 
+static inline void fsnotify_get_mark(struct fsnotify_mark *mark)
+{
+	atomic_inc(&mark->refcnt);
+}
+
+static inline void fsnotify_put_mark(struct fsnotify_mark *mark)
+{
+	if (atomic_dec_and_test(&mark->refcnt))
+		mark->free_mark(mark);
+}
 #else
 
 static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 8ba2c94..bc18853 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -54,6 +54,7 @@
  * 7.18
  *  - add FUSE_IOCTL_DIR flag
  *  - add FUSE_NOTIFY_DELETE
+ *  - add FUSE_MMAP and FUSE_MUNMAP
  */
 
 #ifndef _LINUX_FUSE_H
@@ -278,6 +279,8 @@ enum fuse_opcode {
 	FUSE_POLL          = 40,
 	FUSE_NOTIFY_REPLY  = 41,
 	FUSE_BATCH_FORGET  = 42,
+	FUSE_MMAP          = 43,
+	FUSE_MUNMAP        = 44,
 
 	/* CUSE specific operations */
 	CUSE_INIT          = 4096,
@@ -571,6 +574,28 @@ struct fuse_notify_poll_wakeup_out {
 	__u64	kh;
 };
 
+struct fuse_mmap_in {
+	__u64	fh;
+	__u64	addr;
+	__u64	len;
+	__u32	prot;
+	__u32	flags;
+	__u64	offset;
+};
+
+struct fuse_mmap_out {
+	__u64	mapid;		/* Mmap ID, same namespace as Inode ID */
+	__u64	size;		/* Size of memory region */
+	__u64	reserved;
+};
+
+struct fuse_munmap_in {
+	__u64	fh;
+	__u64	mapid;
+	__u64	size;		/* Size of memory region */
+	__u64	reserved;
+};
+
 struct fuse_in_header {
 	__u32	len;
 	__u32	opcode;
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index b148087..fa98bdb 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -168,6 +168,7 @@ struct gfs2_rindex {
 #define GFS2_RGF_METAONLY	0x00000002
 #define GFS2_RGF_DATAONLY	0x00000004
 #define GFS2_RGF_NOALLOC	0x00000008
+#define GFS2_RGF_TRIMMED	0x00000010
 
 struct gfs2_rgrp {
 	struct gfs2_meta_header rg_header;
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 3a93f73..6549ed7 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -55,12 +55,12 @@ static inline void kunmap(struct page *page)
 {
 }
 
-static inline void *__kmap_atomic(struct page *page)
+static inline void *kmap_atomic(struct page *page)
 {
 	pagefault_disable();
 	return page_address(page);
 }
-#define kmap_atomic_prot(page, prot)	__kmap_atomic(page)
+#define kmap_atomic_prot(page, prot)	kmap_atomic(page)
 
 static inline void __kunmap_atomic(void *addr)
 {
@@ -109,27 +109,62 @@ static inline void kmap_atomic_idx_pop(void)
 #endif
 
 /*
- * Make both: kmap_atomic(page, idx) and kmap_atomic(page) work.
+ * NOTE:
+ * kmap_atomic() and kunmap_atomic() with two arguments are deprecated.
+ * We only keep them for backward compatibility, any usage of them
+ * are now warned.
  */
-#define kmap_atomic(page, args...) __kmap_atomic(page)
+
+#define PASTE(a, b) a ## b
+#define PASTE2(a, b) PASTE(a, b)
+
+#define NARG_(_2, _1, n, ...) n
+#define NARG(...) NARG_(__VA_ARGS__, 2, 1, :)
+
+static inline void __deprecated *kmap_atomic_deprecated(struct page *page,
+							enum km_type km)
+{
+	return kmap_atomic(page);
+}
+
+#define kmap_atomic1(...) kmap_atomic(__VA_ARGS__)
+#define kmap_atomic2(...) kmap_atomic_deprecated(__VA_ARGS__)
+#define kmap_atomic(...) PASTE2(kmap_atomic, NARG(__VA_ARGS__)(__VA_ARGS__))
+
+static inline void __deprecated __kunmap_atomic_deprecated(void *addr,
+							enum km_type km)
+{
+	__kunmap_atomic(addr);
+}
 
 /*
  * Prevent people trying to call kunmap_atomic() as if it were kunmap()
  * kunmap_atomic() should get the return value of kmap_atomic, not the page.
  */
-#define kunmap_atomic(addr, args...)				\
-do {								\
-	BUILD_BUG_ON(__same_type((addr), struct page *));	\
-	__kunmap_atomic(addr);					\
+#define kunmap_atomic_deprecated(addr, km)                      \
+do {                                                            \
+	BUILD_BUG_ON(__same_type((addr), struct page *));       \
+	__kunmap_atomic_deprecated(addr, km);                   \
 } while (0)
 
+#define kunmap_atomic_withcheck(addr)                           \
+do {                                                            \
+	BUILD_BUG_ON(__same_type((addr), struct page *));       \
+	__kunmap_atomic(addr);                                  \
+} while (0)
+
+#define kunmap_atomic1(...) kunmap_atomic_withcheck(__VA_ARGS__)
+#define kunmap_atomic2(...) kunmap_atomic_deprecated(__VA_ARGS__)
+#define kunmap_atomic(...) PASTE2(kunmap_atomic, NARG(__VA_ARGS__)(__VA_ARGS__))
+/**** End of C pre-processor tricks for deprecated macros ****/
+
 /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
 #ifndef clear_user_highpage
 static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	void *addr = kmap_atomic(page, KM_USER0);
+	void *addr = kmap_atomic(page);
 	clear_user_page(addr, vaddr, page);
-	kunmap_atomic(addr, KM_USER0);
+	kunmap_atomic(addr);
 }
 #endif
 
@@ -180,16 +215,16 @@ alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma,
 
 static inline void clear_highpage(struct page *page)
 {
-	void *kaddr = kmap_atomic(page, KM_USER0);
+	void *kaddr = kmap_atomic(page);
 	clear_page(kaddr);
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 
 static inline void zero_user_segments(struct page *page,
 	unsigned start1, unsigned end1,
 	unsigned start2, unsigned end2)
 {
-	void *kaddr = kmap_atomic(page, KM_USER0);
+	void *kaddr = kmap_atomic(page);
 
 	BUG_ON(end1 > PAGE_SIZE || end2 > PAGE_SIZE);
 
@@ -199,7 +234,7 @@ static inline void zero_user_segments(struct page *page,
 	if (end2 > start2)
 		memset(kaddr + start2, 0, end2 - start2);
 
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 	flush_dcache_page(page);
 }
 
@@ -228,11 +263,11 @@ static inline void copy_user_highpage(struct page *to, struct page *from,
 {
 	char *vfrom, *vto;
 
-	vfrom = kmap_atomic(from, KM_USER0);
-	vto = kmap_atomic(to, KM_USER1);
+	vfrom = kmap_atomic(from);
+	vto = kmap_atomic(to);
 	copy_user_page(vto, vfrom, vaddr, to);
-	kunmap_atomic(vto, KM_USER1);
-	kunmap_atomic(vfrom, KM_USER0);
+	kunmap_atomic(vto);
+	kunmap_atomic(vfrom);
 }
 
 #endif
@@ -241,11 +276,11 @@ static inline void copy_highpage(struct page *to, struct page *from)
 {
 	char *vfrom, *vto;
 
-	vfrom = kmap_atomic(from, KM_USER0);
-	vto = kmap_atomic(to, KM_USER1);
+	vfrom = kmap_atomic(from);
+	vto = kmap_atomic(to);
 	copy_page(vto, vfrom);
-	kunmap_atomic(vto, KM_USER1);
-	kunmap_atomic(vfrom, KM_USER0);
+	kunmap_atomic(vto);
+	kunmap_atomic(vfrom);
 }
 
 #endif /* _LINUX_HIGHMEM_H */
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 219ca4f..d690c0f 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -125,6 +125,7 @@ struct hpet_info {
 #define	HPET_EPI	_IO('h', 0x04)	/* enable periodic */
 #define	HPET_DPI	_IO('h', 0x05)	/* disable periodic */
 #define	HPET_IRQFREQ	_IOW('h', 0x6, unsigned long)	/* IRQFREQ usec */
+#define	HPET_ALLOC_TIMER _IO('h', 0x7)
 
 #define MAX_HPET_TBS	8		/* maximum hpet timer blocks */
 
diff --git a/include/linux/hsi/Kbuild b/include/linux/hsi/Kbuild
new file mode 100644
index 0000000..271a770
--- /dev/null
+++ b/include/linux/hsi/Kbuild
@@ -0,0 +1 @@
+header-y += hsi_char.h
diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h
new file mode 100644
index 0000000..4b17806
--- /dev/null
+++ b/include/linux/hsi/hsi.h
@@ -0,0 +1,410 @@
+/*
+ * HSI core header file.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Carlos Chinea <carlos.chinea@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __LINUX_HSI_H__
+#define __LINUX_HSI_H__
+
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+/* HSI message ttype */
+#define HSI_MSG_READ	0
+#define HSI_MSG_WRITE	1
+
+/* HSI configuration values */
+enum {
+	HSI_MODE_STREAM	= 1,
+	HSI_MODE_FRAME,
+};
+
+enum {
+	HSI_FLOW_SYNC,	/* Synchronized flow */
+	HSI_FLOW_PIPE,	/* Pipelined flow */
+};
+
+enum {
+	HSI_ARB_RR,	/* Round-robin arbitration */
+	HSI_ARB_PRIO,	/* Channel priority arbitration */
+};
+
+#define HSI_MAX_CHANNELS	16
+
+/* HSI message status codes */
+enum {
+	HSI_STATUS_COMPLETED,	/* Message transfer is completed */
+	HSI_STATUS_PENDING,	/* Message pending to be read/write (POLL) */
+	HSI_STATUS_PROCEEDING,	/* Message transfer is ongoing */
+	HSI_STATUS_QUEUED,	/* Message waiting to be served */
+	HSI_STATUS_ERROR,	/* Error when message transfer was ongoing */
+};
+
+/* HSI port event codes */
+enum {
+	HSI_EVENT_START_RX,
+	HSI_EVENT_STOP_RX,
+};
+
+/**
+ * struct hsi_config - Configuration for RX/TX HSI modules
+ * @mode: Bit transmission mode (STREAM or FRAME)
+ * @channels: Number of channels to use [1..16]
+ * @speed: Max bit transmission speed (Kbit/s)
+ * @flow: RX flow type (SYNCHRONIZED or PIPELINE)
+ * @arb_mode: Arbitration mode for TX frame (Round robin, priority)
+ */
+struct hsi_config {
+	unsigned int	mode;
+	unsigned int	channels;
+	unsigned int	speed;
+	union {
+		unsigned int	flow;		/* RX only */
+		unsigned int	arb_mode;	/* TX only */
+	};
+};
+
+/**
+ * struct hsi_board_info - HSI client board info
+ * @name: Name for the HSI device
+ * @hsi_id: HSI controller id where the client sits
+ * @port: Port number in the controller where the client sits
+ * @tx_cfg: HSI TX configuration
+ * @rx_cfg: HSI RX configuration
+ * @platform_data: Platform related data
+ * @archdata: Architecture-dependent device data
+ */
+struct hsi_board_info {
+	const char		*name;
+	unsigned int		hsi_id;
+	unsigned int		port;
+	struct hsi_config	tx_cfg;
+	struct hsi_config	rx_cfg;
+	void			*platform_data;
+	struct dev_archdata	*archdata;
+};
+
+#ifdef CONFIG_HSI_BOARDINFO
+extern int hsi_register_board_info(struct hsi_board_info const *info,
+							unsigned int len);
+#else
+static inline int hsi_register_board_info(struct hsi_board_info const *info,
+							unsigned int len)
+{
+	return 0;
+}
+#endif /* CONFIG_HSI_BOARDINFO */
+
+/**
+ * struct hsi_client - HSI client attached to an HSI port
+ * @device: Driver model representation of the device
+ * @tx_cfg: HSI TX configuration
+ * @rx_cfg: HSI RX configuration
+ * @hsi_start_rx: Called after incoming wake line goes high
+ * @hsi_stop_rx: Called after incoming wake line goes low
+ */
+struct hsi_client {
+	struct device		device;
+	struct hsi_config	tx_cfg;
+	struct hsi_config	rx_cfg;
+	void			(*hsi_start_rx)(struct hsi_client *cl);
+	void			(*hsi_stop_rx)(struct hsi_client *cl);
+	/* private: */
+	unsigned int		pclaimed:1;
+	struct list_head	link;
+};
+
+#define to_hsi_client(dev) container_of(dev, struct hsi_client, device)
+
+static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data)
+{
+	dev_set_drvdata(&cl->device, data);
+}
+
+static inline void *hsi_client_drvdata(struct hsi_client *cl)
+{
+	return dev_get_drvdata(&cl->device);
+}
+
+/**
+ * struct hsi_client_driver - Driver associated to an HSI client
+ * @driver: Driver model representation of the driver
+ */
+struct hsi_client_driver {
+	struct device_driver	driver;
+};
+
+#define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\
+									driver)
+
+int hsi_register_client_driver(struct hsi_client_driver *drv);
+
+static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+
+/**
+ * struct hsi_msg - HSI message descriptor
+ * @link: Free to use by the current descriptor owner
+ * @cl: HSI device client that issues the transfer
+ * @sgt: Head of the scatterlist array
+ * @context: Client context data associated to the transfer
+ * @complete: Transfer completion callback
+ * @destructor: Destructor to free resources when flushing
+ * @status: Status of the transfer when completed
+ * @actual_len: Actual length of data transfered on completion
+ * @channel: Channel were to TX/RX the message
+ * @ttype: Transfer type (TX if set, RX otherwise)
+ * @break_frame: if true HSI will send/receive a break frame. Data buffers are
+ *		ignored in the request.
+ */
+struct hsi_msg {
+	struct list_head	link;
+	struct hsi_client	*cl;
+	struct sg_table		sgt;
+	void			*context;
+
+	void			(*complete)(struct hsi_msg *msg);
+	void			(*destructor)(struct hsi_msg *msg);
+
+	int			status;
+	unsigned int		actual_len;
+	unsigned int		channel;
+	unsigned int		ttype:1;
+	unsigned int		break_frame:1;
+};
+
+struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags);
+void hsi_free_msg(struct hsi_msg *msg);
+
+/**
+ * struct hsi_port - HSI port device
+ * @device: Driver model representation of the device
+ * @tx_cfg: Current TX path configuration
+ * @rx_cfg: Current RX path configuration
+ * @num: Port number
+ * @shared: Set when port can be shared by different clients
+ * @claimed: Reference count of clients which claimed the port
+ * @lock: Serialize port claim
+ * @async: Asynchronous transfer callback
+ * @setup: Callback to set the HSI client configuration
+ * @flush: Callback to clean the HW state and destroy all pending transfers
+ * @start_tx: Callback to inform that a client wants to TX data
+ * @stop_tx: Callback to inform that a client no longer wishes to TX data
+ * @release: Callback to inform that a client no longer uses the port
+ * @clients: List of hsi_clients using the port.
+ * @clock: Lock to serialize access to the clients list.
+ */
+struct hsi_port {
+	struct device			device;
+	struct hsi_config		tx_cfg;
+	struct hsi_config		rx_cfg;
+	unsigned int			num;
+	unsigned int			shared:1;
+	int				claimed;
+	struct mutex			lock;
+	int				(*async)(struct hsi_msg *msg);
+	int				(*setup)(struct hsi_client *cl);
+	int				(*flush)(struct hsi_client *cl);
+	int				(*start_tx)(struct hsi_client *cl);
+	int				(*stop_tx)(struct hsi_client *cl);
+	int				(*release)(struct hsi_client *cl);
+	struct list_head		clients;
+	spinlock_t			clock;
+};
+
+#define to_hsi_port(dev) container_of(dev, struct hsi_port, device)
+#define hsi_get_port(cl) to_hsi_port((cl)->device.parent)
+
+void hsi_event(struct hsi_port *port, unsigned int event);
+int hsi_claim_port(struct hsi_client *cl, unsigned int share);
+void hsi_release_port(struct hsi_client *cl);
+
+static inline int hsi_port_claimed(struct hsi_client *cl)
+{
+	return cl->pclaimed;
+}
+
+static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data)
+{
+	dev_set_drvdata(&port->device, data);
+}
+
+static inline void *hsi_port_drvdata(struct hsi_port *port)
+{
+	return dev_get_drvdata(&port->device);
+}
+
+/**
+ * struct hsi_controller - HSI controller device
+ * @device: Driver model representation of the device
+ * @owner: Pointer to the module owning the controller
+ * @id: HSI controller ID
+ * @num_ports: Number of ports in the HSI controller
+ * @port: Array of HSI ports
+ */
+struct hsi_controller {
+	struct device		device;
+	struct module		*owner;
+	unsigned int		id;
+	unsigned int		num_ports;
+	struct hsi_port		*port;
+};
+
+#define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device)
+
+struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags);
+void hsi_free_controller(struct hsi_controller *hsi);
+int hsi_register_controller(struct hsi_controller *hsi);
+void hsi_unregister_controller(struct hsi_controller *hsi);
+
+static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi,
+								void *data)
+{
+	dev_set_drvdata(&hsi->device, data);
+}
+
+static inline void *hsi_controller_drvdata(struct hsi_controller *hsi)
+{
+	return dev_get_drvdata(&hsi->device);
+}
+
+static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi,
+							unsigned int num)
+{
+	return (num < hsi->num_ports) ? &hsi->port[num] : NULL;
+}
+
+/*
+ * API for HSI clients
+ */
+int hsi_async(struct hsi_client *cl, struct hsi_msg *msg);
+
+/**
+ * hsi_id - Get HSI controller ID associated to a client
+ * @cl: Pointer to a HSI client
+ *
+ * Return the controller id where the client is attached to
+ */
+static inline unsigned int hsi_id(struct hsi_client *cl)
+{
+	return	to_hsi_controller(cl->device.parent->parent)->id;
+}
+
+/**
+ * hsi_port_id - Gets the port number a client is attached to
+ * @cl: Pointer to HSI client
+ *
+ * Return the port number associated to the client
+ */
+static inline unsigned int hsi_port_id(struct hsi_client *cl)
+{
+	return	to_hsi_port(cl->device.parent)->num;
+}
+
+/**
+ * hsi_setup - Configure the client's port
+ * @cl: Pointer to the HSI client
+ *
+ * When sharing ports, clients should either relay on a single
+ * client setup or have the same setup for all of them.
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_setup(struct hsi_client *cl)
+{
+	if (!hsi_port_claimed(cl))
+		return -EACCES;
+	return	hsi_get_port(cl)->setup(cl);
+}
+
+/**
+ * hsi_flush - Flush all pending transactions on the client's port
+ * @cl: Pointer to the HSI client
+ *
+ * This function will destroy all pending hsi_msg in the port and reset
+ * the HW port so it is ready to receive and transmit from a clean state.
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_flush(struct hsi_client *cl)
+{
+	if (!hsi_port_claimed(cl))
+		return -EACCES;
+	return hsi_get_port(cl)->flush(cl);
+}
+
+/**
+ * hsi_async_read - Submit a read transfer
+ * @cl: Pointer to the HSI client
+ * @msg: HSI message descriptor of the transfer
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg)
+{
+	msg->ttype = HSI_MSG_READ;
+	return hsi_async(cl, msg);
+}
+
+/**
+ * hsi_async_write - Submit a write transfer
+ * @cl: Pointer to the HSI client
+ * @msg: HSI message descriptor of the transfer
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg)
+{
+	msg->ttype = HSI_MSG_WRITE;
+	return hsi_async(cl, msg);
+}
+
+/**
+ * hsi_start_tx - Signal the port that the client wants to start a TX
+ * @cl: Pointer to the HSI client
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_start_tx(struct hsi_client *cl)
+{
+	if (!hsi_port_claimed(cl))
+		return -EACCES;
+	return hsi_get_port(cl)->start_tx(cl);
+}
+
+/**
+ * hsi_stop_tx - Signal the port that the client no longer wants to transmit
+ * @cl: Pointer to the HSI client
+ *
+ * Return -errno on failure, 0 on success
+ */
+static inline int hsi_stop_tx(struct hsi_client *cl)
+{
+	if (!hsi_port_claimed(cl))
+		return -EACCES;
+	return hsi_get_port(cl)->stop_tx(cl);
+}
+#endif /* __LINUX_HSI_H__ */
diff --git a/include/linux/hsi/hsi_char.h b/include/linux/hsi/hsi_char.h
new file mode 100644
index 0000000..76160b4
--- /dev/null
+++ b/include/linux/hsi/hsi_char.h
@@ -0,0 +1,63 @@
+/*
+ * Part of the HSI character device driver.
+ *
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Andras Domokos <andras.domokos at nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+
+#ifndef __HSI_CHAR_H
+#define __HSI_CHAR_H
+
+#define HSI_CHAR_MAGIC		'k'
+#define HSC_IOW(num, dtype)	_IOW(HSI_CHAR_MAGIC, num, dtype)
+#define HSC_IOR(num, dtype)	_IOR(HSI_CHAR_MAGIC, num, dtype)
+#define HSC_IOWR(num, dtype)	_IOWR(HSI_CHAR_MAGIC, num, dtype)
+#define HSC_IO(num)		_IO(HSI_CHAR_MAGIC, num)
+
+#define HSC_RESET		HSC_IO(16)
+#define HSC_SET_PM		HSC_IO(17)
+#define HSC_SEND_BREAK		HSC_IO(18)
+#define HSC_SET_RX		HSC_IOW(19, struct hsc_rx_config)
+#define HSC_GET_RX		HSC_IOW(20, struct hsc_rx_config)
+#define HSC_SET_TX		HSC_IOW(21, struct hsc_tx_config)
+#define HSC_GET_TX		HSC_IOW(22, struct hsc_tx_config)
+
+#define HSC_PM_DISABLE		0
+#define HSC_PM_ENABLE		1
+
+#define HSC_MODE_STREAM		1
+#define HSC_MODE_FRAME		2
+#define HSC_FLOW_SYNC		0
+#define HSC_ARB_RR		0
+#define HSC_ARB_PRIO		1
+
+struct hsc_rx_config {
+	uint32_t mode;
+	uint32_t flow;
+	uint32_t channels;
+};
+
+struct hsc_tx_config {
+	uint32_t mode;
+	uint32_t channels;
+	uint32_t speed;
+	uint32_t arb_mode;
+};
+
+#endif /* __HSI_CHAR_H */
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 1b92129..f56cacb 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -113,6 +113,18 @@ extern void __vma_adjust_trans_huge(struct vm_area_struct *vma,
 				    unsigned long start,
 				    unsigned long end,
 				    long adjust_next);
+extern int __pmd_trans_huge_lock(pmd_t *pmd,
+				 struct vm_area_struct *vma);
+/* mmap_sem must be held on entry */
+static inline int pmd_trans_huge_lock(pmd_t *pmd,
+				      struct vm_area_struct *vma)
+{
+	VM_BUG_ON(!rwsem_is_locked(&vma->vm_mm->mmap_sem));
+	if (pmd_trans_huge(*pmd))
+		return __pmd_trans_huge_lock(pmd, vma);
+	else
+		return 0;
+}
 static inline void vma_adjust_trans_huge(struct vm_area_struct *vma,
 					 unsigned long start,
 					 unsigned long end,
@@ -176,6 +188,11 @@ static inline void vma_adjust_trans_huge(struct vm_area_struct *vma,
 					 long adjust_next)
 {
 }
+static inline int pmd_trans_huge_lock(pmd_t *pmd,
+				      struct vm_area_struct *vma)
+{
+	return 0;
+}
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 #endif /* _LINUX_HUGE_MM_H */
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 0ae065a..e57a6c6 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -25,6 +25,147 @@
 #ifndef _HYPERV_H
 #define _HYPERV_H
 
+#include <linux/types.h>
+
+/*
+ * An implementation of HyperV key value pair (KVP) functionality for Linux.
+ *
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
+ *
+ */
+
+/*
+ * Maximum value size - used for both key names and value data, and includes
+ * any applicable NULL terminators.
+ *
+ * Note:  This limit is somewhat arbitrary, but falls easily within what is
+ * supported for all native guests (back to Win 2000) and what is reasonable
+ * for the IC KVP exchange functionality.  Note that Windows Me/98/95 are
+ * limited to 255 character key names.
+ *
+ * MSDN recommends not storing data values larger than 2048 bytes in the
+ * registry.
+ *
+ * Note:  This value is used in defining the KVP exchange message - this value
+ * cannot be modified without affecting the message size and compatibility.
+ */
+
+/*
+ * bytes, including any null terminators
+ */
+#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE          (2048)
+
+
+/*
+ * Maximum key size - the registry limit for the length of an entry name
+ * is 256 characters, including the null terminator
+ */
+
+#define HV_KVP_EXCHANGE_MAX_KEY_SIZE            (512)
+
+/*
+ * In Linux, we implement the KVP functionality in two components:
+ * 1) The kernel component which is packaged as part of the hv_utils driver
+ * is responsible for communicating with the host and responsible for
+ * implementing the host/guest protocol. 2) A user level daemon that is
+ * responsible for data gathering.
+ *
+ * Host/Guest Protocol: The host iterates over an index and expects the guest
+ * to assign a key name to the index and also return the value corresponding to
+ * the key. The host will have atmost one KVP transaction outstanding at any
+ * given point in time. The host side iteration stops when the guest returns
+ * an error. Microsoft has specified the following mapping of key names to
+ * host specified index:
+ *
+ *	Index		Key Name
+ *	0		FullyQualifiedDomainName
+ *	1		IntegrationServicesVersion
+ *	2		NetworkAddressIPv4
+ *	3		NetworkAddressIPv6
+ *	4		OSBuildNumber
+ *	5		OSName
+ *	6		OSMajorVersion
+ *	7		OSMinorVersion
+ *	8		OSVersion
+ *	9		ProcessorArchitecture
+ *
+ * The Windows host expects the Key Name and Key Value to be encoded in utf16.
+ *
+ * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the
+ * data gathering functionality in a user mode daemon. The user level daemon
+ * is also responsible for binding the key name to the index as well. The
+ * kernel and user-level daemon communicate using a connector channel.
+ *
+ * The user mode component first registers with the
+ * the kernel component. Subsequently, the kernel component requests, data
+ * for the specified keys. In response to this message the user mode component
+ * fills in the value corresponding to the specified key. We overload the
+ * sequence field in the cn_msg header to define our KVP message types.
+ *
+ *
+ * The kernel component simply acts as a conduit for communication between the
+ * Windows host and the user-level daemon. The kernel component passes up the
+ * index received from the Host to the user-level daemon. If the index is
+ * valid (supported), the corresponding key as well as its
+ * value (both are strings) is returned. If the index is invalid
+ * (not supported), a NULL key string is returned.
+ */
+
+
+/*
+ * Registry value types.
+ */
+
+#define REG_SZ 1
+
+enum hv_kvp_exchg_op {
+	KVP_OP_GET = 0,
+	KVP_OP_SET,
+	KVP_OP_DELETE,
+	KVP_OP_ENUMERATE,
+	KVP_OP_REGISTER,
+	KVP_OP_COUNT /* Number of operations, must be last. */
+};
+
+enum hv_kvp_exchg_pool {
+	KVP_POOL_EXTERNAL = 0,
+	KVP_POOL_GUEST,
+	KVP_POOL_AUTO,
+	KVP_POOL_AUTO_EXTERNAL,
+	KVP_POOL_AUTO_INTERNAL,
+	KVP_POOL_COUNT /* Number of pools, must be last. */
+};
+
+struct hv_kvp_hdr {
+	__u8 operation;
+	__u8 pool;
+	__u16 pad;
+} __attribute__((packed));
+
+struct hv_kvp_exchg_msg_value {
+	__u32 value_type;
+	__u32 key_size;
+	__u32 value_size;
+	__u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
+	__u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
+} __attribute__((packed));
+
+struct hv_kvp_msg_enumerate {
+	__u32 index;
+	struct hv_kvp_exchg_msg_value data;
+} __attribute__((packed));
+
+struct hv_kvp_msg {
+	struct hv_kvp_hdr	kvp_hdr;
+	union {
+		struct hv_kvp_msg_enumerate     kvp_enum_data;
+		char    kvp_version[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
+	} body;
+} __attribute__((packed));
+
+#ifdef __KERNEL__
 #include <linux/scatterlist.h>
 #include <linux/list.h>
 #include <linux/uuid.h>
@@ -870,4 +1011,9 @@ struct hyperv_service_callback {
 extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *,
 				      struct icmsg_negotiate *, u8 *);
 
+int hv_kvp_init(struct hv_util_service *);
+void hv_kvp_deinit(void);
+void hv_kvp_onchannelcallback(void *);
+
+#endif /* __KERNEL__ */
 #endif /* _HYPERV_H */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 78d3465..5790466 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -666,23 +666,11 @@ struct twl4030_codec_data {
 	unsigned int check_defaults:1;
 	unsigned int reset_registers:1;
 	unsigned int hs_extmute:1;
-	u16 hs_left_step;
-	u16 hs_right_step;
-	u16 hf_left_step;
-	u16 hf_right_step;
 	void (*set_hs_extmute)(int mute);
 };
 
 struct twl4030_vibra_data {
 	unsigned int	coexist;
-
-	/* twl6040 */
-	unsigned int vibldrv_res;	/* left driver resistance */
-	unsigned int vibrdrv_res;	/* right driver resistance */
-	unsigned int viblmotor_res;	/* left motor resistance */
-	unsigned int vibrmotor_res;	/* right motor resistance */
-	int vddvibl_uV;			/* VDDVIBL volt, set 0 for fixed reg */
-	int vddvibr_uV;			/* VDDVIBR volt, set 0 for fixed reg */
 };
 
 struct twl4030_audio_data {
@@ -749,6 +737,13 @@ struct twl4030_platform_data {
 	struct regulator_init_data		*vio6025;
 };
 
+struct twl_regulator_driver_data {
+	int		(*set_voltage)(void *data, int target_uV);
+	int		(*get_voltage)(void *data);
+	void		*data;
+	unsigned long	features;
+};
+
 /*----------------------------------------------------------------------*/
 
 int twl4030_sih_setup(int module);
diff --git a/include/linux/in.h b/include/linux/in.h
index 01129c0..e0337f1 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -111,6 +111,7 @@ struct in_addr {
 #define MCAST_LEAVE_SOURCE_GROUP	47
 #define MCAST_MSFILTER			48
 #define IP_MULTICAST_ALL		49
+#define IP_UNICAST_IF			50
 
 #define MCAST_EXCLUDE	0
 #define MCAST_INCLUDE	1
diff --git a/include/linux/in6.h b/include/linux/in6.h
index 097a34b..5c83d9e 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -271,6 +271,7 @@ struct in6_flowlabel_req {
 #define IPV6_ORIGDSTADDR        74
 #define IPV6_RECVORIGDSTADDR    IPV6_ORIGDSTADDR
 #define IPV6_TRANSPARENT        75
+#define IPV6_UNICAST_IF         76
 
 /*
  * Multicast Routing:
diff --git a/include/linux/input.h b/include/linux/input.h
index 3862e32..a816714 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -114,6 +114,31 @@ struct input_keymap_entry {
 #define EVIOCGUNIQ(len)		_IOC(_IOC_READ, 'E', 0x08, len)		/* get unique identifier */
 #define EVIOCGPROP(len)		_IOC(_IOC_READ, 'E', 0x09, len)		/* get device properties */
 
+/**
+ * EVIOCGMTSLOTS(len) - get MT slot values
+ *
+ * The ioctl buffer argument should be binary equivalent to
+ *
+ * struct input_mt_request_layout {
+ *	__u32 code;
+ *	__s32 values[num_slots];
+ * };
+ *
+ * where num_slots is the (arbitrary) number of MT slots to extract.
+ *
+ * The ioctl size argument (len) is the size of the buffer, which
+ * should satisfy len = (num_slots + 1) * sizeof(__s32).  If len is
+ * too small to fit all available slots, the first num_slots are
+ * returned.
+ *
+ * Before the call, code is set to the wanted ABS_MT event type. On
+ * return, values[] is filled with the slot values for the specified
+ * ABS_MT code.
+ *
+ * If the request code is not an ABS_MT value, -EINVAL is returned.
+ */
+#define EVIOCGMTSLOTS(len)	_IOC(_IOC_READ, 'E', 0x0a, len)
+
 #define EVIOCGKEY(len)		_IOC(_IOC_READ, 'E', 0x18, len)		/* get global key state */
 #define EVIOCGLED(len)		_IOC(_IOC_READ, 'E', 0x19, len)		/* get all LEDs */
 #define EVIOCGSND(len)		_IOC(_IOC_READ, 'E', 0x1a, len)		/* get all sounds status */
@@ -129,6 +154,8 @@ struct input_keymap_entry {
 
 #define EVIOCGRAB		_IOW('E', 0x90, int)			/* Grab/Release device */
 
+#define EVIOCSCLOCKID		_IOW('E', 0xa0, int)			/* Set clockid to be used for timestamps */
+
 /*
  * Device properties and quirks
  */
diff --git a/include/linux/input/cyttsp.h b/include/linux/input/cyttsp.h
new file mode 100644
index 0000000..5af7c66
--- /dev/null
+++ b/include/linux/input/cyttsp.h
@@ -0,0 +1,58 @@
+/*
+ * Header file for:
+ * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers.
+ * For use with Cypress Txx3xx parts.
+ * Supported parts include:
+ * CY8CTST341
+ * CY8CTMA340
+ *
+ * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc.
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@dowhile0.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, and only version 2, as published by the
+ * Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contact Cypress Semiconductor at www.cypress.com (kev@cypress.com)
+ *
+ */
+#ifndef _CYTTSP_H_
+#define _CYTTSP_H_
+
+#define CY_SPI_NAME "cyttsp-spi"
+#define CY_I2C_NAME "cyttsp-i2c"
+/* Active Power state scanning/processing refresh interval */
+#define CY_ACT_INTRVL_DFLT 0x00 /* ms */
+/* touch timeout for the Active power */
+#define CY_TCH_TMOUT_DFLT 0xFF /* ms */
+/* Low Power state scanning/processing refresh interval */
+#define CY_LP_INTRVL_DFLT 0x0A /* ms */
+/* Active distance in pixels for a gesture to be reported */
+#define CY_ACT_DIST_DFLT 0xF8 /* pixels */
+
+struct cyttsp_platform_data {
+	u32 maxx;
+	u32 maxy;
+	bool use_hndshk;
+	u8 act_dist;	/* Active distance */
+	u8 act_intrvl;  /* Active refresh interval; ms */
+	u8 tch_tmout;   /* Active touch timeout; ms */
+	u8 lp_intrvl;   /* Low power refresh interval; ms */
+	int (*init)(void);
+	void (*exit)(void);
+	char *name;
+	s16 irq_gpio;
+	u8 *bl_keys;
+};
+
+#endif /* _CYTTSP_H_ */
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h
index 318bb82..f867375 100644
--- a/include/linux/input/mt.h
+++ b/include/linux/input/mt.h
@@ -48,10 +48,14 @@ static inline void input_mt_slot(struct input_dev *dev, int slot)
 	input_event(dev, EV_ABS, ABS_MT_SLOT, slot);
 }
 
+static inline bool input_is_mt_value(int axis)
+{
+	return axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST;
+}
+
 static inline bool input_is_mt_axis(int axis)
 {
-	return axis == ABS_MT_SLOT ||
-		(axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST);
+	return axis == ABS_MT_SLOT || input_is_mt_value(axis);
 }
 
 void input_mt_report_slot_state(struct input_dev *dev,
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 9d57a71..e885ba2 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -23,12 +23,6 @@ struct resource {
 	struct resource *parent, *sibling, *child;
 };
 
-struct resource_list {
-	struct resource_list *next;
-	struct resource *res;
-	struct pci_dev *dev;
-};
-
 /*
  * IO resources have these defined flags.
  */
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 6318268..8260ef7 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -233,6 +233,11 @@ static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
 	return (struct ipv6hdr *)skb_transport_header(skb);
 }
 
+static inline __u8 ipv6_tclass(const struct ipv6hdr *iph)
+{
+	return (ntohl(*(__be32 *)iph) >> 20) & 0xff;
+}
+
 /* 
    This structure contains results of exthdrs parsing
    as offsets from skb->nh.
@@ -324,6 +329,7 @@ struct ipv6_pinfo {
 				__unused_2:6;
 	__s16			mcast_hops:9;
 #endif
+	int			ucast_oif;
 	int			mcast_oif;
 
 	/* pktoption flags */
@@ -360,7 +366,7 @@ struct ipv6_pinfo {
 				dontfrag:1;
 	__u8			min_hopcount;
 	__u8			tclass;
-	__u8			padding;
+	__u8			rcv_tclass;
 
 	__u32			dst_cookie;
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index bd4272b..5245488 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -9,99 +9,179 @@
  * representation into a hardware irq number that can be mapped back to a
  * Linux irq number without any extra platform support code.
  *
- * irq_domain is expected to be embedded in an interrupt controller's private
- * data structure.
+ * Interrupt controller "domain" data structure. This could be defined as a
+ * irq domain controller. That is, it handles the mapping between hardware
+ * and virtual interrupt numbers for a given interrupt domain. The domain
+ * structure is generally created by the PIC code for a given PIC instance
+ * (though a domain can cover more than one PIC if they have a flat number
+ * model). It's the domain callbacks that are responsible for setting the
+ * irq_chip on a given irq_desc after it's been mapped.
+ *
+ * The host code and data structures are agnostic to whether or not
+ * we use an open firmware device-tree. We do have references to struct
+ * device_node in two places: in irq_find_host() to find the host matching
+ * a given interrupt controller node, and of course as an argument to its
+ * counterpart domain->ops->match() callback. However, those are treated as
+ * generic pointers by the core and the fact that it's actually a device-node
+ * pointer is purely a convention between callers and implementation. This
+ * code could thus be used on other architectures by replacing those two
+ * by some sort of arch-specific void * "token" used to identify interrupt
+ * controllers.
  */
+
 #ifndef _LINUX_IRQDOMAIN_H
 #define _LINUX_IRQDOMAIN_H
 
-#include <linux/irq.h>
-#include <linux/mod_devicetable.h>
+#include <linux/types.h>
+#include <linux/radix-tree.h>
 
-#ifdef CONFIG_IRQ_DOMAIN
 struct device_node;
 struct irq_domain;
+struct of_device_id;
+
+/* Number of irqs reserved for a legacy isa controller */
+#define NUM_ISA_INTERRUPTS	16
+
+/* This type is the placeholder for a hardware interrupt number. It has to
+ * be big enough to enclose whatever representation is used by a given
+ * platform.
+ */
+typedef unsigned long irq_hw_number_t;
 
 /**
  * struct irq_domain_ops - Methods for irq_domain objects
- * @to_irq: (optional) given a local hardware irq number, return the linux
- *          irq number.  If to_irq is not implemented, then the irq_domain
- *          will use this translation: irq = (domain->irq_base + hwirq)
- * @dt_translate: Given a device tree node and interrupt specifier, decode
- *                the hardware irq number and linux irq type value.
+ * @match: Match an interrupt controller device node to a host, returns
+ *         1 on a match
+ * @map: Create or update a mapping between a virtual irq number and a hw
+ *       irq number. This is called only once for a given mapping.
+ * @unmap: Dispose of such a mapping
+ * @xlate: Given a device tree node and interrupt specifier, decode
+ *         the hardware irq number and linux irq type value.
+ *
+ * Functions below are provided by the driver and called whenever a new mapping
+ * is created or an old mapping is disposed. The driver can then proceed to
+ * whatever internal data structures management is required. It also needs
+ * to setup the irq_desc when returning from map().
  */
 struct irq_domain_ops {
-	unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
-
-#ifdef CONFIG_OF
-	int (*dt_translate)(struct irq_domain *d, struct device_node *node,
-			    const u32 *intspec, unsigned int intsize,
-			    unsigned long *out_hwirq, unsigned int *out_type);
-#endif /* CONFIG_OF */
+	int (*match)(struct irq_domain *d, struct device_node *node);
+	int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
+	void (*unmap)(struct irq_domain *d, unsigned int virq);
+	int (*xlate)(struct irq_domain *d, struct device_node *node,
+		     const u32 *intspec, unsigned int intsize,
+		     unsigned long *out_hwirq, unsigned int *out_type);
 };
 
 /**
  * struct irq_domain - Hardware interrupt number translation object
- * @list: Element in global irq_domain list.
+ * @link: Element in global irq_domain list.
+ * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This
+ *               will be one of the IRQ_DOMAIN_MAP_* values.
+ * @revmap_data: Revmap method specific data.
+ * @ops: pointer to irq_domain methods
+ * @host_data: private data pointer for use by owner.  Not touched by irq_domain
+ *             core code.
  * @irq_base: Start of irq_desc range assigned to the irq_domain.  The creator
  *            of the irq_domain is responsible for allocating the array of
  *            irq_desc structures.
  * @nr_irq: Number of irqs managed by the irq domain
  * @hwirq_base: Starting number for hwirqs managed by the irq domain
- * @ops: pointer to irq_domain methods
- * @priv: private data pointer for use by owner.  Not touched by irq_domain
- *        core code.
  * @of_node: (optional) Pointer to device tree nodes associated with the
  *           irq_domain.  Used when decoding device tree interrupt specifiers.
  */
 struct irq_domain {
-	struct list_head list;
-	unsigned int irq_base;
-	unsigned int nr_irq;
-	unsigned int hwirq_base;
+	struct list_head link;
+
+	/* type of reverse mapping_technique */
+	unsigned int revmap_type;
+	union {
+		struct {
+			unsigned int size;
+			unsigned int first_irq;
+			irq_hw_number_t first_hwirq;
+		} legacy;
+		struct {
+			unsigned int size;
+			unsigned int *revmap;
+		} linear;
+		struct radix_tree_root tree;
+	} revmap_data;
 	const struct irq_domain_ops *ops;
-	void *priv;
+	void *host_data;
+	irq_hw_number_t inval_irq;
+
+	/* Optional device node pointer */
 	struct device_node *of_node;
 };
 
-/**
- * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
- *
- * Returns the linux irq number associated with a hardware irq.  By default,
- * the mapping is irq == domain->irq_base + hwirq, but this mapping can
- * be overridden if the irq_domain implements a .to_irq() hook.
- */
-static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
-					     unsigned long hwirq)
+#ifdef CONFIG_IRQ_DOMAIN
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+					 unsigned int size,
+					 unsigned int first_irq,
+					 irq_hw_number_t first_hwirq,
+					 const struct irq_domain_ops *ops,
+					 void *host_data);
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+					 unsigned int size,
+					 const struct irq_domain_ops *ops,
+					 void *host_data);
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+					 const struct irq_domain_ops *ops,
+					 void *host_data);
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+					 const struct irq_domain_ops *ops,
+					 void *host_data);
+
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+extern void irq_set_virq_count(unsigned int count);
+
+static inline struct irq_domain *irq_domain_add_legacy_isa(
+				struct device_node *of_node,
+				const struct irq_domain_ops *ops,
+				void *host_data)
 {
-	if (d->ops->to_irq)
-		return d->ops->to_irq(d, hwirq);
-	if (WARN_ON(hwirq < d->hwirq_base))
-		return 0;
-	return d->irq_base + hwirq - d->hwirq_base;
+	return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
+				     host_data);
 }
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+extern void irq_set_virq_count(unsigned int count);
 
-#define irq_domain_for_each_hwirq(d, hw) \
-	for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
 
-#define irq_domain_for_each_irq(d, hw, irq) \
-	for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
-	     hw < d->hwirq_base + d->nr_irq; \
-	     hw++, irq = irq_domain_to_irq(d, hw))
+extern unsigned int irq_create_mapping(struct irq_domain *host,
+				       irq_hw_number_t hwirq);
+extern void irq_dispose_mapping(unsigned int virq);
+extern unsigned int irq_find_mapping(struct irq_domain *host,
+				     irq_hw_number_t hwirq);
+extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
+extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+				    irq_hw_number_t hwirq);
+extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+					    irq_hw_number_t hwirq);
+extern unsigned int irq_linear_revmap(struct irq_domain *host,
+				      irq_hw_number_t hwirq);
 
-extern void irq_domain_add(struct irq_domain *domain);
-extern void irq_domain_del(struct irq_domain *domain);
+extern const struct irq_domain_ops irq_domain_simple_ops;
 
-extern struct irq_domain_ops irq_domain_simple_ops;
-#endif /* CONFIG_IRQ_DOMAIN */
+/* stock xlate functions */
+int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type);
 
-#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
-extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
+#if defined(CONFIG_OF_IRQ)
 extern void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start);
-#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+#else /* CONFIG_OF_IRQ */
 static inline void irq_domain_generate_simple(const struct of_device_id *match,
 					u64 phys_base, unsigned int irq_start) { }
-#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+#endif /* !CONFIG_OF_IRQ */
+#endif /* CONFIG_IRQ_DOMAIN */
 
 #endif /* _LINUX_IRQDOMAIN_H */
diff --git a/include/linux/ivtv.h b/include/linux/ivtv.h
index 062d20f..42bf725 100644
--- a/include/linux/ivtv.h
+++ b/include/linux/ivtv.h
@@ -58,7 +58,11 @@ struct ivtv_dma_frame {
 	__u32 src_height;
 };
 
-#define IVTV_IOC_DMA_FRAME  _IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtv_dma_frame)
+#define IVTV_IOC_DMA_FRAME		_IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtv_dma_frame)
+
+/* Select the passthrough mode (if the argument is non-zero). In the passthrough
+   mode the output of the encoder is passed immediately into the decoder. */
+#define IVTV_IOC_PASSTHROUGH_MODE	_IOW ('V', BASE_VIDIOC_PRIVATE+1, int)
 
 /* Deprecated defines: applications should use the defines from videodev2.h */
 #define IVTV_SLICED_TYPE_TELETEXT_B     V4L2_MPEG_VBI_IVTV_TELETEXT_B
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 5557bae..46eef77 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1020,6 +1020,11 @@ jbd2_journal_write_metadata_buffer(transaction_t	  *transaction,
 /* Transaction locking */
 extern void		__wait_on_journal (journal_t *);
 
+/* Transaction cache support */
+extern void jbd2_journal_destroy_transaction_cache(void);
+extern int  jbd2_journal_init_transaction_cache(void);
+extern void jbd2_journal_free_transaction(transaction_t *);
+
 /*
  * Journal locking.
  *
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 5ce8b14..f7c6958 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -1,6 +1,38 @@
 #ifndef _LINUX_JUMP_LABEL_H
 #define _LINUX_JUMP_LABEL_H
 
+/*
+ * Jump label support
+ *
+ * Copyright (C) 2009-2012 Jason Baron <jbaron@redhat.com>
+ * Copyright (C) 2011-2012 Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ * Jump labels provide an interface to generate dynamic branches using
+ * self-modifying code. Assuming toolchain and architecture support the result
+ * of a "if (static_branch(&key))" statement is a unconditional branch (which
+ * defaults to false - and the true block is placed out of line).
+ *
+ * However at runtime we can change the 'static' branch target using
+ * jump_label_{inc,dec}(). These function as a 'reference' count on the key
+ * object and for as long as there are references all branches referring to
+ * that particular key will point to the (out of line) true block.
+ *
+ * Since this relies on modifying code the jump_label_{inc,dec}() functions
+ * must be considered absolute slow paths (machine wide synchronization etc.).
+ * OTOH, since the affected branches are unconditional their runtime overhead
+ * will be absolutely minimal, esp. in the default (off) case where the total
+ * effect is a single NOP of appropriate size. The on case will patch in a jump
+ * to the out-of-line block.
+ *
+ * When the control is directly exposed to userspace it is prudent to delay the
+ * decrement to avoid high frequency code modifications which can (and do)
+ * cause significant performance degradation. Struct jump_label_key_deferred and
+ * jump_label_dec_deferred() provide for this.
+ *
+ * Lacking toolchain and or architecture support, it falls back to a simple
+ * conditional branch.
+ */
+
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <linux/workqueue.h>
diff --git a/include/linux/kcmp.h b/include/linux/kcmp.h
new file mode 100644
index 0000000..2dcd1b3
--- /dev/null
+++ b/include/linux/kcmp.h
@@ -0,0 +1,17 @@
+#ifndef _LINUX_KCMP_H
+#define _LINUX_KCMP_H
+
+/* Comparison type */
+enum kcmp_type {
+	KCMP_FILE,
+	KCMP_VM,
+	KCMP_FILES,
+	KCMP_FS,
+	KCMP_SIGHAND,
+	KCMP_IO,
+	KCMP_SYSVSEM,
+
+	KCMP_TYPES,
+};
+
+#endif /* _LINUX_KCMP_H */
diff --git a/include/linux/kernel-page-flags.h b/include/linux/kernel-page-flags.h
index bd92a89..26a6571 100644
--- a/include/linux/kernel-page-flags.h
+++ b/include/linux/kernel-page-flags.h
@@ -30,6 +30,7 @@
 #define KPF_NOPAGE		20
 
 #define KPF_KSM			21
+#define KPF_THP			22
 
 /* kernel hacking assistances
  * WARNING: subject to change, never rely on them!
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index e834342..01ab0aa 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -299,6 +299,8 @@ extern long long simple_strtoll(const char *,char **,unsigned int);
 #define strict_strtoull	kstrtoull
 #define strict_strtoll	kstrtoll
 
+extern int num_to_str(char *buf, int size, unsigned long long num);
+
 /* lib/printf utilities */
 
 extern __printf(2, 3) int sprintf(char *buf, const char * fmt, ...);
@@ -315,10 +317,10 @@ extern __printf(2, 3)
 char *kasprintf(gfp_t gfp, const char *fmt, ...);
 extern char *kvasprintf(gfp_t gfp, const char *fmt, va_list args);
 
-extern int sscanf(const char *, const char *, ...)
-	__attribute__ ((format (scanf, 2, 3)));
-extern int vsscanf(const char *, const char *, va_list)
-	__attribute__ ((format (scanf, 2, 0)));
+extern __scanf(2, 3)
+int sscanf(const char *, const char *, ...);
+extern __scanf(2, 0)
+int vsscanf(const char *, const char *, va_list);
 
 extern int get_option(char **str, int *pint);
 extern char *get_options(const char *str, int nints, int *ints);
@@ -733,13 +735,6 @@ extern int __build_bug_on_failed;
 #define NUMA_BUILD 0
 #endif
 
-/* This helps us avoid #ifdef CONFIG_COMPACTION */
-#ifdef CONFIG_COMPACTION
-#define COMPACTION_BUILD 1
-#else
-#define COMPACTION_BUILD 0
-#endif
-
 /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
diff --git a/include/linux/key.h b/include/linux/key.h
index 5253471..1600ebf 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -155,6 +155,7 @@ struct key {
 #define KEY_FLAG_IN_QUOTA	3	/* set if key consumes quota */
 #define KEY_FLAG_USER_CONSTRUCT	4	/* set if key is being constructed in userspace */
 #define KEY_FLAG_NEGATIVE	5	/* set if key is negative */
+#define KEY_FLAG_ROOT_CAN_CLEAR	6	/* set if key can be cleared by root without permission */
 
 	/* the description string
 	 * - this is used to match a key against search criteria
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 722f477..9efeae6 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -48,11 +48,10 @@ static inline int request_module_nowait(const char *name, ...) { return -ENOSYS;
 struct cred;
 struct file;
 
-enum umh_wait {
-	UMH_NO_WAIT = -1,	/* don't wait at all */
-	UMH_WAIT_EXEC = 0,	/* wait for the exec, but not the process */
-	UMH_WAIT_PROC = 1,	/* wait for the process to complete */
-};
+#define UMH_NO_WAIT	0	/* don't wait at all */
+#define UMH_WAIT_EXEC	1	/* wait for the exec, but not the process */
+#define UMH_WAIT_PROC	2	/* wait for the process to complete */
+#define UMH_KILLABLE	4	/* wait for EXEC/PROC killable */
 
 struct subprocess_info {
 	struct work_struct work;
@@ -60,7 +59,7 @@ struct subprocess_info {
 	char *path;
 	char **argv;
 	char **envp;
-	enum umh_wait wait;
+	int wait;
 	int retval;
 	int (*init)(struct subprocess_info *info, struct cred *new);
 	void (*cleanup)(struct subprocess_info *info);
@@ -78,15 +77,14 @@ void call_usermodehelper_setfns(struct subprocess_info *info,
 		    void *data);
 
 /* Actually execute the sub-process */
-int call_usermodehelper_exec(struct subprocess_info *info, enum umh_wait wait);
+int call_usermodehelper_exec(struct subprocess_info *info, int wait);
 
 /* Free the subprocess_info. This is only needed if you're not going
    to call call_usermodehelper_exec */
 void call_usermodehelper_freeinfo(struct subprocess_info *info);
 
 static inline int
-call_usermodehelper_fns(char *path, char **argv, char **envp,
-			enum umh_wait wait,
+call_usermodehelper_fns(char *path, char **argv, char **envp, int wait,
 			int (*init)(struct subprocess_info *info, struct cred *new),
 			void (*cleanup)(struct subprocess_info *), void *data)
 {
@@ -104,7 +102,7 @@ call_usermodehelper_fns(char *path, char **argv, char **envp,
 }
 
 static inline int
-call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
+call_usermodehelper(char *path, char **argv, char **envp, int wait)
 {
 	return call_usermodehelper_fns(path, argv, envp, wait,
 				       NULL, NULL, NULL);
diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h
index fee6631..35f7237 100644
--- a/include/linux/kmsg_dump.h
+++ b/include/linux/kmsg_dump.h
@@ -15,13 +15,18 @@
 #include <linux/errno.h>
 #include <linux/list.h>
 
+/*
+ * Keep this list arranged in rough order of priority. Anything listed after
+ * KMSG_DUMP_OOPS will not be logged by default unless printk.always_kmsg_dump
+ * is passed to the kernel.
+ */
 enum kmsg_dump_reason {
-	KMSG_DUMP_OOPS,
 	KMSG_DUMP_PANIC,
+	KMSG_DUMP_OOPS,
+	KMSG_DUMP_EMERG,
 	KMSG_DUMP_RESTART,
 	KMSG_DUMP_HALT,
 	KMSG_DUMP_POWEROFF,
-	KMSG_DUMP_EMERG,
 };
 
 /**
diff --git a/include/linux/led-lm3530.h b/include/linux/led-lm3530.h
index 8eb1235..eeae6e7 100644
--- a/include/linux/led-lm3530.h
+++ b/include/linux/led-lm3530.h
@@ -72,6 +72,12 @@ enum lm3530_als_mode {
 	LM3530_INPUT_CEIL,	/* Max of ALS1 and ALS2 */
 };
 
+/* PWM Platform Specific Data */
+struct lm3530_pwm_data {
+	void (*pwm_set_intensity) (int brightness, int max_brightness);
+	int (*pwm_get_intensity) (int max_brightness);
+};
+
 /**
  * struct lm3530_platform_data
  * @mode: mode of operation i.e. Manual, ALS or PWM
@@ -87,6 +93,7 @@ enum lm3530_als_mode {
  * @als_vmin: als input voltage calibrated for max brightness in mV
  * @als_vmax: als input voltage calibrated for min brightness in mV
  * @brt_val: brightness value (0-255)
+ * @pwm_data: PWM control functions (only valid when the mode is PWM)
  */
 struct lm3530_platform_data {
 	enum lm3530_mode mode;
@@ -107,6 +114,8 @@ struct lm3530_platform_data {
 	u32 als_vmax;
 
 	u8 brt_val;
+
+	struct lm3530_pwm_data pwm_data;
 };
 
 #endif	/* _LINUX_LED_LM3530_H__ */
diff --git a/include/linux/leds-lp5521.h b/include/linux/leds-lp5521.h
index fd548d2..3f071ec 100644
--- a/include/linux/leds-lp5521.h
+++ b/include/linux/leds-lp5521.h
@@ -26,15 +26,37 @@
 /* See Documentation/leds/leds-lp5521.txt */
 
 struct lp5521_led_config {
+	char		*name;
 	u8		chan_nr;
 	u8		led_current; /* mA x10, 0 if led is not connected */
 	u8		max_current;
 };
 
+struct lp5521_led_pattern {
+	u8 *r;
+	u8 *g;
+	u8 *b;
+	u8 size_r;
+	u8 size_g;
+	u8 size_b;
+};
+
 #define LP5521_CLOCK_AUTO	0
 #define LP5521_CLOCK_INT	1
 #define LP5521_CLOCK_EXT	2
 
+/* Bits in CONFIG register */
+#define LP5521_PWM_HF			0x40	/* PWM: 0 = 256Hz, 1 = 558Hz */
+#define LP5521_PWRSAVE_EN		0x20	/* 1 = Power save mode */
+#define LP5521_CP_MODE_OFF		0	/* Charge pump (CP) off */
+#define LP5521_CP_MODE_BYPASS		8	/* CP forced to bypass mode */
+#define LP5521_CP_MODE_1X5		0x10	/* CP forced to 1.5x mode */
+#define LP5521_CP_MODE_AUTO		0x18	/* Automatic mode selection */
+#define LP5521_R_TO_BATT		4	/* R out: 0 = CP, 1 = Vbat */
+#define LP5521_CLK_SRC_EXT		0	/* Ext-clk source (CLK_32K) */
+#define LP5521_CLK_INT			1	/* Internal clock */
+#define LP5521_CLK_AUTO			2	/* Automatic clock selection */
+
 struct lp5521_platform_data {
 	struct lp5521_led_config *led_config;
 	u8	num_channels;
@@ -43,6 +65,9 @@ struct lp5521_platform_data {
 	void	(*release_resources)(void);
 	void	(*enable)(bool state);
 	const char *label;
+	u8	update_config;
+	struct lp5521_led_pattern *patterns;
+	int num_patterns;
 };
 
 #endif /* __LINUX_LP5521_H */
diff --git a/include/linux/lglock.h b/include/linux/lglock.h
index 87f402c..5152056 100644
--- a/include/linux/lglock.h
+++ b/include/linux/lglock.h
@@ -23,28 +23,17 @@
 #include <linux/lockdep.h>
 #include <linux/percpu.h>
 #include <linux/cpu.h>
+#include <linux/notifier.h>
 
 /* can make br locks by using local lock for read side, global lock for write */
-#define br_lock_init(name)	name##_lock_init()
-#define br_read_lock(name)	name##_local_lock()
-#define br_read_unlock(name)	name##_local_unlock()
-#define br_write_lock(name)	name##_global_lock_online()
-#define br_write_unlock(name)	name##_global_unlock_online()
+#define br_lock_init(name)	lg_lock_init(name, #name)
+#define br_read_lock(name)	lg_local_lock(name)
+#define br_read_unlock(name)	lg_local_unlock(name)
+#define br_write_lock(name)	lg_global_lock_online(name)
+#define br_write_unlock(name)	lg_global_unlock_online(name)
 
-#define DECLARE_BRLOCK(name)	DECLARE_LGLOCK(name)
 #define DEFINE_BRLOCK(name)	DEFINE_LGLOCK(name)
 
-
-#define lg_lock_init(name)	name##_lock_init()
-#define lg_local_lock(name)	name##_local_lock()
-#define lg_local_unlock(name)	name##_local_unlock()
-#define lg_local_lock_cpu(name, cpu)	name##_local_lock_cpu(cpu)
-#define lg_local_unlock_cpu(name, cpu)	name##_local_unlock_cpu(cpu)
-#define lg_global_lock(name)	name##_global_lock()
-#define lg_global_unlock(name)	name##_global_unlock()
-#define lg_global_lock_online(name) name##_global_lock_online()
-#define lg_global_unlock_online(name) name##_global_unlock_online()
-
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 #define LOCKDEP_INIT_MAP lockdep_init_map
 
@@ -59,142 +48,34 @@
 #define DEFINE_LGLOCK_LOCKDEP(name)
 #endif
 
+struct lglock {
+	arch_spinlock_t __percpu *lock;
+	cpumask_t cpus;	/* XXX need to put on separate cacheline? */
+	spinlock_t cpu_lock;
+	struct notifier_block cpu_notifier;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	struct lock_class_key lock_key;
+	struct lockdep_map    lock_dep_map;
+#endif
+};
+
+#define DEFINE_LGLOCK(name) \
+	DEFINE_PER_CPU(arch_spinlock_t, name ## _lock) = __ARCH_SPIN_LOCK_UNLOCKED; \
+	struct lglock name = { .lock = &name ## _lock, 				\
+			       .cpu_lock = __SPIN_LOCK_UNLOCKED(cpu_lock), 	\
+			       .cpu_notifier.notifier_call = lg_cpu_callback }
+
+/* Only valid for statics */
+void lg_lock_init(struct lglock *lg, char *name);
+void lg_local_lock(struct lglock *lg);
+void lg_local_unlock(struct lglock *lg);
+void lg_local_lock_cpu(struct lglock *lg, int cpu);
+void lg_local_unlock_cpu(struct lglock *lg, int cpu);
+void lg_global_lock_online(struct lglock *lg);
+void lg_global_unlock_online(struct lglock *lg);
+void lg_global_lock(struct lglock *lg);
+void lg_global_unlock(struct lglock *lg);
 
-#define DECLARE_LGLOCK(name)						\
- extern void name##_lock_init(void);					\
- extern void name##_local_lock(void);					\
- extern void name##_local_unlock(void);					\
- extern void name##_local_lock_cpu(int cpu);				\
- extern void name##_local_unlock_cpu(int cpu);				\
- extern void name##_global_lock(void);					\
- extern void name##_global_unlock(void);				\
- extern void name##_global_lock_online(void);				\
- extern void name##_global_unlock_online(void);				\
+int lg_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu);
 
-#define DEFINE_LGLOCK(name)						\
-									\
- DEFINE_SPINLOCK(name##_cpu_lock);					\
- cpumask_t name##_cpus __read_mostly;					\
- DEFINE_PER_CPU(arch_spinlock_t, name##_lock);				\
- DEFINE_LGLOCK_LOCKDEP(name);						\
-									\
- static int								\
- name##_lg_cpu_callback(struct notifier_block *nb,			\
-				unsigned long action, void *hcpu)	\
- {									\
-	switch (action & ~CPU_TASKS_FROZEN) {				\
-	case CPU_UP_PREPARE:						\
-		spin_lock(&name##_cpu_lock);				\
-		cpu_set((unsigned long)hcpu, name##_cpus);		\
-		spin_unlock(&name##_cpu_lock);				\
-		break;							\
-	case CPU_UP_CANCELED: case CPU_DEAD:				\
-		spin_lock(&name##_cpu_lock);				\
-		cpu_clear((unsigned long)hcpu, name##_cpus);		\
-		spin_unlock(&name##_cpu_lock);				\
-	}								\
-	return NOTIFY_OK;						\
- }									\
- static struct notifier_block name##_lg_cpu_notifier = {		\
-	.notifier_call = name##_lg_cpu_callback,			\
- };									\
- void name##_lock_init(void) {						\
-	int i;								\
-	LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \
-	for_each_possible_cpu(i) {					\
-		arch_spinlock_t *lock;					\
-		lock = &per_cpu(name##_lock, i);			\
-		*lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;	\
-	}								\
-	register_hotcpu_notifier(&name##_lg_cpu_notifier);		\
-	get_online_cpus();						\
-	for_each_online_cpu(i)						\
-		cpu_set(i, name##_cpus);				\
-	put_online_cpus();						\
- }									\
- EXPORT_SYMBOL(name##_lock_init);					\
-									\
- void name##_local_lock(void) {						\
-	arch_spinlock_t *lock;						\
-	preempt_disable();						\
-	rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_);	\
-	lock = &__get_cpu_var(name##_lock);				\
-	arch_spin_lock(lock);						\
- }									\
- EXPORT_SYMBOL(name##_local_lock);					\
-									\
- void name##_local_unlock(void) {					\
-	arch_spinlock_t *lock;						\
-	rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_);		\
-	lock = &__get_cpu_var(name##_lock);				\
-	arch_spin_unlock(lock);						\
-	preempt_enable();						\
- }									\
- EXPORT_SYMBOL(name##_local_unlock);					\
-									\
- void name##_local_lock_cpu(int cpu) {					\
-	arch_spinlock_t *lock;						\
-	preempt_disable();						\
-	rwlock_acquire_read(&name##_lock_dep_map, 0, 0, _THIS_IP_);	\
-	lock = &per_cpu(name##_lock, cpu);				\
-	arch_spin_lock(lock);						\
- }									\
- EXPORT_SYMBOL(name##_local_lock_cpu);					\
-									\
- void name##_local_unlock_cpu(int cpu) {				\
-	arch_spinlock_t *lock;						\
-	rwlock_release(&name##_lock_dep_map, 1, _THIS_IP_);		\
-	lock = &per_cpu(name##_lock, cpu);				\
-	arch_spin_unlock(lock);						\
-	preempt_enable();						\
- }									\
- EXPORT_SYMBOL(name##_local_unlock_cpu);				\
-									\
- void name##_global_lock_online(void) {					\
-	int i;								\
-	spin_lock(&name##_cpu_lock);					\
-	rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_);		\
-	for_each_cpu(i, &name##_cpus) {					\
-		arch_spinlock_t *lock;					\
-		lock = &per_cpu(name##_lock, i);			\
-		arch_spin_lock(lock);					\
-	}								\
- }									\
- EXPORT_SYMBOL(name##_global_lock_online);				\
-									\
- void name##_global_unlock_online(void) {				\
-	int i;								\
-	rwlock_release(&name##_lock_dep_map, 1, _RET_IP_);		\
-	for_each_cpu(i, &name##_cpus) {					\
-		arch_spinlock_t *lock;					\
-		lock = &per_cpu(name##_lock, i);			\
-		arch_spin_unlock(lock);					\
-	}								\
-	spin_unlock(&name##_cpu_lock);					\
- }									\
- EXPORT_SYMBOL(name##_global_unlock_online);				\
-									\
- void name##_global_lock(void) {					\
-	int i;								\
-	preempt_disable();						\
-	rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_);		\
-	for_each_possible_cpu(i) {					\
-		arch_spinlock_t *lock;					\
-		lock = &per_cpu(name##_lock, i);			\
-		arch_spin_lock(lock);					\
-	}								\
- }									\
- EXPORT_SYMBOL(name##_global_lock);					\
-									\
- void name##_global_unlock(void) {					\
-	int i;								\
-	rwlock_release(&name##_lock_dep_map, 1, _RET_IP_);		\
-	for_each_possible_cpu(i) {					\
-		arch_spinlock_t *lock;					\
-		lock = &per_cpu(name##_lock, i);			\
-		arch_spin_unlock(lock);					\
-	}								\
-	preempt_enable();						\
- }									\
- EXPORT_SYMBOL(name##_global_unlock);
 #endif
diff --git a/include/linux/libata.h b/include/linux/libata.h
index cafc09a..f60b4eb 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -544,9 +544,6 @@ struct ata_host {
 	struct mutex		eh_mutex;
 	struct task_struct	*eh_owner;
 
-#ifdef CONFIG_ATA_ACPI
-	acpi_handle		acpi_handle;
-#endif
 	struct ata_port		*simplex_claimed;	/* channel owning the DMA */
 	struct ata_port		*ports[0];
 };
@@ -614,7 +611,6 @@ struct ata_device {
 	struct scsi_device	*sdev;		/* attached SCSI device */
 	void			*private_data;
 #ifdef CONFIG_ATA_ACPI
-	acpi_handle		acpi_handle;
 	union acpi_object	*gtf_cache;
 	unsigned int		gtf_filter;
 #endif
@@ -796,7 +792,6 @@ struct ata_port {
 	void			*private_data;
 
 #ifdef CONFIG_ATA_ACPI
-	acpi_handle		acpi_handle;
 	struct ata_acpi_gtm	__acpi_init_gtm; /* use ata_acpi_init_gtm() */
 #endif
 	/* owned by EH */
@@ -996,6 +991,7 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
 extern void ata_sas_port_destroy(struct ata_port *);
 extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
 					   struct ata_port_info *, struct Scsi_Host *);
+extern int ata_sas_async_port_init(struct ata_port *);
 extern int ata_sas_port_init(struct ata_port *);
 extern int ata_sas_port_start(struct ata_port *ap);
 extern void ata_sas_port_stop(struct ata_port *ap);
@@ -1111,6 +1107,8 @@ int ata_acpi_stm(struct ata_port *ap, const struct ata_acpi_gtm *stm);
 int ata_acpi_gtm(struct ata_port *ap, struct ata_acpi_gtm *stm);
 unsigned long ata_acpi_gtm_xfermask(struct ata_device *dev,
 				    const struct ata_acpi_gtm *gtm);
+acpi_handle ata_ap_acpi_handle(struct ata_port *ap);
+acpi_handle ata_dev_acpi_handle(struct ata_device *dev);
 int ata_acpi_cbl_80wire(struct ata_port *ap, const struct ata_acpi_gtm *gtm);
 #else
 static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap)
@@ -1147,6 +1145,7 @@ static inline int ata_acpi_cbl_80wire(struct ata_port *ap,
  * EH - drivers/ata/libata-eh.c
  */
 extern void ata_port_schedule_eh(struct ata_port *ap);
+extern void ata_port_wait_eh(struct ata_port *ap);
 extern int ata_link_abort(struct ata_link *link);
 extern int ata_port_abort(struct ata_port *ap);
 extern int ata_port_freeze(struct ata_port *ap);
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index fbc48f8..11a966e 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -42,6 +42,7 @@ struct nlmclnt_initdata {
 	unsigned short		protocol;
 	u32			nfs_version;
 	int			noresvport;
+	struct net		*net;
 };
 
 /*
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 88a114f..f04ce6a 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -67,6 +67,7 @@ struct nlm_host {
 	struct list_head	h_reclaim;	/* Locks in RECLAIM state */
 	struct nsm_handle	*h_nsmhandle;	/* NSM status handle */
 	char			*h_addrbuf;	/* address eyecatcher */
+	struct net		*net;		/* host net */
 };
 
 /*
@@ -188,7 +189,7 @@ struct nlm_block {
 /*
  * Global variables
  */
-extern struct rpc_program	nlm_program;
+extern const struct rpc_program	nlm_program;
 extern struct svc_procedure	nlmsvc_procedures[];
 #ifdef CONFIG_LOCKD_V4
 extern struct svc_procedure	nlmsvc_procedures4[];
@@ -222,7 +223,8 @@ struct nlm_host  *nlmclnt_lookup_host(const struct sockaddr *sap,
 					const unsigned short protocol,
 					const u32 version,
 					const char *hostname,
-					int noresvport);
+					int noresvport,
+					struct net *net);
 void		  nlmclnt_release_host(struct nlm_host *);
 struct nlm_host  *nlmsvc_lookup_host(const struct svc_rqst *rqstp,
 					const char *hostname,
@@ -232,6 +234,7 @@ struct rpc_clnt * nlm_bind_host(struct nlm_host *);
 void		  nlm_rebind_host(struct nlm_host *);
 struct nlm_host * nlm_get_host(struct nlm_host *);
 void		  nlm_shutdown_hosts(void);
+void		  nlm_shutdown_hosts_net(struct net *net);
 void		  nlm_host_rebooted(const struct nlm_reboot *);
 
 /*
diff --git a/include/linux/lockd/xdr4.h b/include/linux/lockd/xdr4.h
index 7353821..e58c88b 100644
--- a/include/linux/lockd/xdr4.h
+++ b/include/linux/lockd/xdr4.h
@@ -42,6 +42,6 @@ int	nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *);
 int	nlmclt_encode_cancargs(struct rpc_rqst *, u32 *, struct nlm_args *);
 int	nlmclt_encode_unlockargs(struct rpc_rqst *, u32 *, struct nlm_args *);
  */
-extern struct rpc_version nlm_version4;
+extern const struct rpc_version nlm_version4;
 
 #endif /* LOCKD_XDR4_H */
diff --git a/include/linux/lp855x.h b/include/linux/lp855x.h
new file mode 100644
index 0000000..4b124c1
--- /dev/null
+++ b/include/linux/lp855x.h
@@ -0,0 +1,133 @@
+/*
+ * LP855x Backlight Driver
+ *
+ *			Copyright (C) 2011 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _LP855X_H
+#define _LP855X_H
+
+#define BL_CTL_SHFT	(0)
+#define BRT_MODE_SHFT	(1)
+#define BRT_MODE_MASK	(0x06)
+
+/* Enable backlight. Only valid when BRT_MODE=10(I2C only) */
+#define ENABLE_BL	(1)
+#define DISABLE_BL	(0)
+
+#define I2C_CONFIG(id)	id ## _I2C_CONFIG
+#define PWM_CONFIG(id)	id ## _PWM_CONFIG
+
+/* DEVICE CONTROL register - LP8550 */
+#define LP8550_PWM_CONFIG	(LP8550_PWM_ONLY << BRT_MODE_SHFT)
+#define LP8550_I2C_CONFIG	((ENABLE_BL << BL_CTL_SHFT) | \
+				(LP8550_I2C_ONLY << BRT_MODE_SHFT))
+
+/* DEVICE CONTROL register - LP8551 */
+#define LP8551_PWM_CONFIG	LP8550_PWM_CONFIG
+#define LP8551_I2C_CONFIG	LP8550_I2C_CONFIG
+
+/* DEVICE CONTROL register - LP8552 */
+#define LP8552_PWM_CONFIG	LP8550_PWM_CONFIG
+#define LP8552_I2C_CONFIG	LP8550_I2C_CONFIG
+
+/* DEVICE CONTROL register - LP8553 */
+#define LP8553_PWM_CONFIG	LP8550_PWM_CONFIG
+#define LP8553_I2C_CONFIG	LP8550_I2C_CONFIG
+
+/* DEVICE CONTROL register - LP8556 */
+#define LP8556_PWM_CONFIG	(LP8556_PWM_ONLY << BRT_MODE_SHFT)
+#define LP8556_COMB1_CONFIG	(LP8556_COMBINED1 << BRT_MODE_SHFT)
+#define LP8556_I2C_CONFIG	((ENABLE_BL << BL_CTL_SHFT) | \
+				(LP8556_I2C_ONLY << BRT_MODE_SHFT))
+#define LP8556_COMB2_CONFIG	(LP8556_COMBINED2 << BRT_MODE_SHFT)
+
+/* ROM area boundary */
+#define EEPROM_START	(0xA0)
+#define EEPROM_END	(0xA7)
+#define EPROM_START	(0xA0)
+#define EPROM_END	(0xAF)
+
+enum lp855x_chip_id {
+	LP8550,
+	LP8551,
+	LP8552,
+	LP8553,
+	LP8556,
+};
+
+enum lp855x_brightness_ctrl_mode {
+	PWM_BASED = 1,
+	REGISTER_BASED,
+};
+
+enum lp8550_brighntess_source {
+	LP8550_PWM_ONLY,
+	LP8550_I2C_ONLY = 2,
+};
+
+enum lp8551_brighntess_source {
+	LP8551_PWM_ONLY = LP8550_PWM_ONLY,
+	LP8551_I2C_ONLY = LP8550_I2C_ONLY,
+};
+
+enum lp8552_brighntess_source {
+	LP8552_PWM_ONLY = LP8550_PWM_ONLY,
+	LP8552_I2C_ONLY = LP8550_I2C_ONLY,
+};
+
+enum lp8553_brighntess_source {
+	LP8553_PWM_ONLY = LP8550_PWM_ONLY,
+	LP8553_I2C_ONLY = LP8550_I2C_ONLY,
+};
+
+enum lp8556_brightness_source {
+	LP8556_PWM_ONLY,
+	LP8556_COMBINED1,	/* pwm + i2c before the shaper block */
+	LP8556_I2C_ONLY,
+	LP8556_COMBINED2,	/* pwm + i2c after the shaper block */
+};
+
+struct lp855x_pwm_data {
+	void (*pwm_set_intensity) (int brightness, int max_brightness);
+	int (*pwm_get_intensity) (int max_brightness);
+};
+
+struct lp855x_rom_data {
+	u8 addr;
+	u8 val;
+};
+
+/**
+ * struct lp855x_platform_data
+ * @name : Backlight driver name. If it is not defined, default name is set.
+ * @mode : brightness control by pwm or lp855x register
+ * @device_control : value of DEVICE CONTROL register
+ * @initial_brightness : initial value of backlight brightness
+ * @max_brightness : maximum value of backlight brightness
+ * @pwm_data : platform specific pwm generation functions.
+		Only valid when mode is PWM_BASED.
+ * @load_new_rom_data :
+	0 : use default configuration data
+	1 : update values of eeprom or eprom registers on loading driver
+ * @size_program : total size of lp855x_rom_data
+ * @rom_data : list of new eeprom/eprom registers
+ */
+struct lp855x_platform_data {
+	char *name;
+	enum lp855x_brightness_ctrl_mode mode;
+	u8 device_control;
+	int initial_brightness;
+	int max_brightness;
+	struct lp855x_pwm_data pwm_data;
+	u8 load_new_rom_data;
+	int size_program;
+	struct lp855x_rom_data *rom_data;
+};
+
+#endif
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 2d4beab..b4a8d44 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -9,7 +9,6 @@
 #define CRAMFS_MAGIC		0x28cd3d45	/* some random number */
 #define CRAMFS_MAGIC_WEND	0x453dcd28	/* magic number with the wrong endianess */
 #define DEBUGFS_MAGIC          0x64626720
-#define SYSFS_MAGIC		0x62656572
 #define SECURITYFS_MAGIC	0x73636673
 #define SELINUX_MAGIC		0xf97cff8c
 #define RAMFS_MAGIC		0x858458f6	/* some random number */
@@ -27,7 +26,6 @@
 #define HPFS_SUPER_MAGIC	0xf995e849
 #define ISOFS_SUPER_MAGIC	0x9660
 #define JFFS2_SUPER_MAGIC	0x72b6
-#define ANON_INODE_FS_MAGIC	0x09041934
 #define PSTOREFS_MAGIC		0x6165676C
 
 #define MINIX_SUPER_MAGIC	0x137F		/* minix v1 fs, 14 char names */
@@ -40,7 +38,6 @@
 #define NCP_SUPER_MAGIC		0x564c		/* Guess, what 0x564c is :-) */
 #define NFS_SUPER_MAGIC		0x6969
 #define OPENPROM_SUPER_MAGIC	0x9fa1
-#define PROC_SUPER_MAGIC	0x9fa0
 #define QNX4_SUPER_MAGIC	0x002f		/* qnx4 fs detection */
 
 #define REISERFS_SUPER_MAGIC	0x52654973	/* used by gcc */
@@ -51,15 +48,24 @@
 #define REISER2FS_JR_SUPER_MAGIC_STRING	"ReIsEr3Fs"
 
 #define SMB_SUPER_MAGIC		0x517B
-#define USBDEVICE_SUPER_MAGIC	0x9fa2
 #define CGROUP_SUPER_MAGIC	0x27e0eb
 
-#define FUTEXFS_SUPER_MAGIC	0xBAD1DEA
 
 #define STACK_END_MAGIC		0x57AC6E9D
 
+#define V9FS_MAGIC		0x01021997
+
+#define BDEVFS_MAGIC            0x62646576
+#define BINFMTFS_MAGIC          0x42494e4d
 #define DEVPTS_SUPER_MAGIC	0x1cd1
+#define FUTEXFS_SUPER_MAGIC	0xBAD1DEA
+#define PIPEFS_MAGIC            0x50495045
+#define PROC_SUPER_MAGIC	0x9fa0
 #define SOCKFS_MAGIC		0x534F434B
-#define V9FS_MAGIC		0x01021997
+#define SYSFS_MAGIC		0x62656572
+#define USBDEVICE_SUPER_MAGIC	0x9fa2
+#define MTD_INODE_FS_MAGIC      0x11307854
+#define ANON_INODE_FS_MAGIC	0x09041934
+
 
 #endif /* __LINUX_MAGIC_H__ */
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 4d34356..9da7b74 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -299,21 +299,6 @@ static inline void mem_cgroup_iter_break(struct mem_cgroup *root,
 {
 }
 
-static inline int mem_cgroup_get_reclaim_priority(struct mem_cgroup *memcg)
-{
-	return 0;
-}
-
-static inline void mem_cgroup_note_reclaim_priority(struct mem_cgroup *memcg,
-						int priority)
-{
-}
-
-static inline void mem_cgroup_record_reclaim_priority(struct mem_cgroup *memcg,
-						int priority)
-{
-}
-
 static inline bool mem_cgroup_disabled(void)
 {
 	return true;
@@ -396,7 +381,7 @@ static inline void mem_cgroup_replace_page_cache(struct page *oldpage,
 static inline void mem_cgroup_reset_owner(struct page *page)
 {
 }
-#endif /* CONFIG_CGROUP_MEM_CONT */
+#endif /* CONFIG_CGROUP_MEM_RES_CTLR */
 
 #if !defined(CONFIG_CGROUP_MEM_RES_CTLR) || !defined(CONFIG_DEBUG_VM)
 static inline bool
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 9970337..1bfbb11 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -33,13 +33,6 @@
 #define AB5500_1_1	0x21
 #define AB5500_2_0	0x24
 
-/* AB8500 CIDs*/
-#define AB8500_CUT1P0	0x10
-#define AB8500_CUT1P1	0x11
-#define AB8500_CUT2P0	0x20
-#define AB8500_CUT3P0	0x30
-#define AB8500_CUT3P3	0x33
-
 /*
  * AB3100, EVENTA1, A2 and A3 event register flags
  * these are catenated into a single 32-bit flag in the code
diff --git a/include/linux/mfd/abx500/ab8500-gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h
index 488a8c9..2387c20 100644
--- a/include/linux/mfd/abx500/ab8500-gpio.h
+++ b/include/linux/mfd/abx500/ab8500-gpio.h
@@ -10,12 +10,14 @@
 
 /*
  * Platform data to register a block: only the initial gpio/irq number.
+ * Array sizes are large enough to contain all AB8500 and AB9540 GPIO
+ * registers.
  */
 
 struct ab8500_gpio_platform_data {
 	int gpio_base;
 	u32 irq_base;
-	u8  config_reg[7];
+	u8  config_reg[8];
 };
 
 #endif /* _AB8500_GPIO_H */
diff --git a/include/linux/mfd/abx500/ab8500-sysctrl.h b/include/linux/mfd/abx500/ab8500-sysctrl.h
index 10da029..10eb509 100644
--- a/include/linux/mfd/abx500/ab8500-sysctrl.h
+++ b/include/linux/mfd/abx500/ab8500-sysctrl.h
@@ -71,6 +71,13 @@ static inline int ab8500_sysctrl_clear(u16 reg, u8 bits)
 #define AB8500_SWATCTRL			0x230
 #define AB8500_HIQCLKCTRL		0x232
 #define AB8500_VSIMSYSCLKCTRL		0x233
+#define AB9540_SYSCLK12BUFCTRL		0x234
+#define AB9540_SYSCLK12CONFCTRL		0x235
+#define AB9540_SYSCLK12BUFCTRL2		0x236
+#define AB9540_SYSCLK12BUF1VALID	0x237
+#define AB9540_SYSCLK12BUF2VALID	0x238
+#define AB9540_SYSCLK12BUF3VALID	0x239
+#define AB9540_SYSCLK12BUF4VALID	0x23A
 
 /* Bits */
 #define AB8500_TURNONSTATUS_PORNVBAT BIT(0)
@@ -251,4 +258,40 @@ static inline int ab8500_sysctrl_clear(u16 reg, u8 bits)
 #define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ7VALID BIT(6)
 #define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ8VALID BIT(7)
 
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF1ENA BIT(0)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF2ENA BIT(1)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF3ENA BIT(2)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF4ENA BIT(3)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUFENA_MASK 0x0F
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF1STRE BIT(4)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF2STRE BIT(5)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF3STRE BIT(6)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUF4STRE BIT(7)
+#define AB9540_SYSCLK12BUFCTRL_SYSCLK12BUFSTRE_MASK 0xF0
+
+#define AB9540_SYSCLK12CONFCTRL_PLL26TO38ENA BIT(0)
+#define AB9540_SYSCLK12CONFCTRL_SYSCLK12USBMUXSEL BIT(1)
+#define AB9540_SYSCLK12CONFCTRL_INT384MHZMUXSEL_MASK 0x0C
+#define AB9540_SYSCLK12CONFCTRL_INT384MHZMUXSEL_SHIFT 2
+#define AB9540_SYSCLK12CONFCTRL_SYSCLK12BUFMUX BIT(4)
+#define AB9540_SYSCLK12CONFCTRL_SYSCLK12PLLMUX BIT(5)
+#define AB9540_SYSCLK12CONFCTRL_SYSCLK2MUXVALID BIT(6)
+
+#define AB9540_SYSCLK12BUFCTRL2_SYSCLK12BUF1PDENA BIT(0)
+#define AB9540_SYSCLK12BUFCTRL2_SYSCLK12BUF2PDENA BIT(1)
+#define AB9540_SYSCLK12BUFCTRL2_SYSCLK12BUF3PDENA BIT(2)
+#define AB9540_SYSCLK12BUFCTRL2_SYSCLK12BUF4PDENA BIT(3)
+
+#define AB9540_SYSCLK12BUF1VALID_SYSCLK12BUF1VALID_MASK 0xFF
+#define AB9540_SYSCLK12BUF1VALID_SYSCLK12BUF1VALID_SHIFT 0
+
+#define AB9540_SYSCLK12BUF2VALID_SYSCLK12BUF2VALID_MASK 0xFF
+#define AB9540_SYSCLK12BUF2VALID_SYSCLK12BUF2VALID_SHIFT 0
+
+#define AB9540_SYSCLK12BUF3VALID_SYSCLK12BUF3VALID_MASK 0xFF
+#define AB9540_SYSCLK12BUF3VALID_SYSCLK12BUF3VALID_SHIFT 0
+
+#define AB9540_SYSCLK12BUF4VALID_SYSCLK12BUF4VALID_MASK 0xFF
+#define AB9540_SYSCLK12BUF4VALID_SYSCLK12BUF4VALID_SHIFT 0
+
 #endif /* __AB8500_SYSCTRL_H */
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 838c6b4..4b2df29 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -8,6 +8,28 @@
 #define MFD_AB8500_H
 
 #include <linux/device.h>
+/*
+ * AB IC versions
+ *
+ * AB8500_VERSION_AB8500 should be 0xFF but will never be read as need a
+ * non-supported multi-byte I2C access via PRCMU. Set to 0x00 to ease the
+ * print of version string.
+ */
+enum ab8500_version {
+	AB8500_VERSION_AB8500 = 0x0,
+	AB8500_VERSION_AB8505 = 0x1,
+	AB8500_VERSION_AB9540 = 0x2,
+	AB8500_VERSION_AB8540 = 0x3,
+	AB8500_VERSION_UNDEFINED,
+};
+
+/* AB8500 CIDs*/
+#define AB8500_CUTEARLY	0x00
+#define AB8500_CUT1P0	0x10
+#define AB8500_CUT1P1	0x11
+#define AB8500_CUT2P0	0x20
+#define AB8500_CUT3P0	0x30
+#define AB8500_CUT3P3	0x33
 
 /*
  * AB8500 bank addresses
@@ -35,8 +57,11 @@
 
 /*
  * Interrupts
+ * Values used to index into array ab8500_irq_regoffset[] defined in
+ * drivers/mdf/ab8500-core.c
  */
-
+/* Definitions for AB8500 and AB9540 */
+/* ab8500_irq_regoffset[0] -> IT[Source|Latch|Mask]1 */
 #define AB8500_INT_MAIN_EXT_CH_NOT_OK	0
 #define AB8500_INT_UN_PLUG_TV_DET	1
 #define AB8500_INT_PLUG_TV_DET		2
@@ -45,6 +70,7 @@
 #define AB8500_INT_PON_KEY2DB_R		5
 #define AB8500_INT_PON_KEY1DB_F		6
 #define AB8500_INT_PON_KEY1DB_R		7
+/* ab8500_irq_regoffset[1] -> IT[Source|Latch|Mask]2 */
 #define AB8500_INT_BATT_OVV		8
 #define AB8500_INT_MAIN_CH_UNPLUG_DET	10
 #define AB8500_INT_MAIN_CH_PLUG_DET	11
@@ -52,6 +78,7 @@
 #define AB8500_INT_USB_ID_DET_R		13
 #define AB8500_INT_VBUS_DET_F		14
 #define AB8500_INT_VBUS_DET_R		15
+/* ab8500_irq_regoffset[2] -> IT[Source|Latch|Mask]3 */
 #define AB8500_INT_VBUS_CH_DROP_END	16
 #define AB8500_INT_RTC_60S		17
 #define AB8500_INT_RTC_ALARM		18
@@ -59,6 +86,7 @@
 #define AB8500_INT_CH_WD_EXP		21
 #define AB8500_INT_VBUS_OVV		22
 #define AB8500_INT_MAIN_CH_DROP_END	23
+/* ab8500_irq_regoffset[3] -> IT[Source|Latch|Mask]4 */
 #define AB8500_INT_CCN_CONV_ACC		24
 #define AB8500_INT_INT_AUD		25
 #define AB8500_INT_CCEOC		26
@@ -67,6 +95,7 @@
 #define AB8500_INT_LOW_BAT_R		29
 #define AB8500_INT_BUP_CHG_NOT_OK	30
 #define AB8500_INT_BUP_CHG_OK		31
+/* ab8500_irq_regoffset[4] -> IT[Source|Latch|Mask]5 */
 #define AB8500_INT_GP_HW_ADC_CONV_END	32
 #define AB8500_INT_ACC_DETECT_1DB_F	33
 #define AB8500_INT_ACC_DETECT_1DB_R	34
@@ -75,6 +104,7 @@
 #define AB8500_INT_ACC_DETECT_21DB_F	37
 #define AB8500_INT_ACC_DETECT_21DB_R	38
 #define AB8500_INT_GP_SW_ADC_CONV_END	39
+/* ab8500_irq_regoffset[5] -> IT[Source|Latch|Mask]7 */
 #define AB8500_INT_GPIO6R		40
 #define AB8500_INT_GPIO7R		41
 #define AB8500_INT_GPIO8R		42
@@ -83,6 +113,7 @@
 #define AB8500_INT_GPIO11R		45
 #define AB8500_INT_GPIO12R		46
 #define AB8500_INT_GPIO13R		47
+/* ab8500_irq_regoffset[6] -> IT[Source|Latch|Mask]8 */
 #define AB8500_INT_GPIO24R		48
 #define AB8500_INT_GPIO25R		49
 #define AB8500_INT_GPIO36R		50
@@ -91,6 +122,7 @@
 #define AB8500_INT_GPIO39R		53
 #define AB8500_INT_GPIO40R		54
 #define AB8500_INT_GPIO41R		55
+/* ab8500_irq_regoffset[7] -> IT[Source|Latch|Mask]9 */
 #define AB8500_INT_GPIO6F		56
 #define AB8500_INT_GPIO7F		57
 #define AB8500_INT_GPIO8F		58
@@ -99,6 +131,7 @@
 #define AB8500_INT_GPIO11F		61
 #define AB8500_INT_GPIO12F		62
 #define AB8500_INT_GPIO13F		63
+/* ab8500_irq_regoffset[8] -> IT[Source|Latch|Mask]10 */
 #define AB8500_INT_GPIO24F		64
 #define AB8500_INT_GPIO25F		65
 #define AB8500_INT_GPIO36F		66
@@ -107,6 +140,7 @@
 #define AB8500_INT_GPIO39F		69
 #define AB8500_INT_GPIO40F		70
 #define AB8500_INT_GPIO41F		71
+/* ab8500_irq_regoffset[9] -> IT[Source|Latch|Mask]12 */
 #define AB8500_INT_ADP_SOURCE_ERROR	72
 #define AB8500_INT_ADP_SINK_ERROR	73
 #define AB8500_INT_ADP_PROBE_PLUG	74
@@ -114,30 +148,62 @@
 #define AB8500_INT_ADP_SENSE_OFF	76
 #define AB8500_INT_USB_PHY_POWER_ERR	78
 #define AB8500_INT_USB_LINK_STATUS	79
+/* ab8500_irq_regoffset[10] -> IT[Source|Latch|Mask]19 */
 #define AB8500_INT_BTEMP_LOW		80
 #define AB8500_INT_BTEMP_LOW_MEDIUM	81
 #define AB8500_INT_BTEMP_MEDIUM_HIGH	82
 #define AB8500_INT_BTEMP_HIGH		83
+/* ab8500_irq_regoffset[11] -> IT[Source|Latch|Mask]20 */
 #define AB8500_INT_USB_CHARGER_NOT_OK	89
 #define AB8500_INT_ID_WAKEUP_R		90
 #define AB8500_INT_ID_DET_R1R		92
 #define AB8500_INT_ID_DET_R2R		93
 #define AB8500_INT_ID_DET_R3R		94
 #define AB8500_INT_ID_DET_R4R		95
+/* ab8500_irq_regoffset[12] -> IT[Source|Latch|Mask]21 */
 #define AB8500_INT_ID_WAKEUP_F		96
 #define AB8500_INT_ID_DET_R1F		98
 #define AB8500_INT_ID_DET_R2F		99
 #define AB8500_INT_ID_DET_R3F		100
 #define AB8500_INT_ID_DET_R4F		101
 #define AB8500_INT_USB_CHG_DET_DONE	102
+/* ab8500_irq_regoffset[13] -> IT[Source|Latch|Mask]22 */
 #define AB8500_INT_USB_CH_TH_PROT_F	104
 #define AB8500_INT_USB_CH_TH_PROT_R    105
 #define AB8500_INT_MAIN_CH_TH_PROT_F   106
 #define AB8500_INT_MAIN_CH_TH_PROT_R	107
 #define AB8500_INT_USB_CHARGER_NOT_OKF	111
 
+/* Definitions for AB9540 */
+/* ab8500_irq_regoffset[14] -> IT[Source|Latch|Mask]13 */
+#define AB9540_INT_GPIO50R		113
+#define AB9540_INT_GPIO51R		114
+#define AB9540_INT_GPIO52R		115
+#define AB9540_INT_GPIO53R		116
+#define AB9540_INT_GPIO54R		117
+#define AB9540_INT_IEXT_CH_RF_BFN_R	118
+#define AB9540_INT_IEXT_CH_RF_BFN_F	119
+/* ab8500_irq_regoffset[15] -> IT[Source|Latch|Mask]14 */
+#define AB9540_INT_GPIO50F		121
+#define AB9540_INT_GPIO51F		122
+#define AB9540_INT_GPIO52F		123
+#define AB9540_INT_GPIO53F		124
+#define AB9540_INT_GPIO54F		125
+
+/*
+ * AB8500_AB9540_NR_IRQS is used when configuring the IRQ numbers for the
+ * entire platform. This is a "compile time" constant so this must be set to
+ * the largest possible value that may be encountered with different AB SOCs.
+ * Of the currently supported AB devices, AB8500 and AB9540, it is the AB9540
+ * which is larger.
+ */
 #define AB8500_NR_IRQS			112
+#define AB9540_NR_IRQS			128
+/* This is set to the roof of any AB8500 chip variant IRQ counts */
+#define AB8500_MAX_NR_IRQS		AB9540_NR_IRQS
+
 #define AB8500_NUM_IRQ_REGS		14
+#define AB9540_NUM_IRQ_REGS		17
 
 /**
  * struct ab8500 - ab8500 internal structure
@@ -145,6 +211,7 @@
  * @lock: read/write operations lock
  * @irq_lock: genirq bus lock
  * @irq: irq line
+ * @version: chip version id (e.g. ab8500 or ab9540)
  * @chip_id: chip revision id
  * @write: register write
  * @read: register read
@@ -152,6 +219,9 @@
  * @tx_buf: tx buf for SPI
  * @mask: cache of IRQ regs for bus lock
  * @oldmask: cache of previous IRQ regs for bus lock
+ * @mask_size: Actual number of valid entries in mask[], oldmask[] and
+ * irq_reg_offset
+ * @irq_reg_offset: Array of offsets into IRQ registers
  */
 struct ab8500 {
 	struct device	*dev;
@@ -160,6 +230,7 @@ struct ab8500 {
 
 	int		irq_base;
 	int		irq;
+	enum ab8500_version version;
 	u8		chip_id;
 
 	int (*write) (struct ab8500 *a8500, u16 addr, u8 data);
@@ -168,8 +239,10 @@ struct ab8500 {
 	unsigned long	tx_buf[4];
 	unsigned long	rx_buf[4];
 
-	u8 mask[AB8500_NUM_IRQ_REGS];
-	u8 oldmask[AB8500_NUM_IRQ_REGS];
+	u8 *mask;
+	u8 *oldmask;
+	int mask_size;
+	const int *irq_reg_offset;
 };
 
 struct regulator_reg_init;
@@ -195,7 +268,40 @@ struct ab8500_platform_data {
 	struct ab8500_gpio_platform_data *gpio;
 };
 
-extern int __devinit ab8500_init(struct ab8500 *ab8500);
+extern int __devinit ab8500_init(struct ab8500 *ab8500,
+				 enum ab8500_version version);
 extern int __devexit ab8500_exit(struct ab8500 *ab8500);
 
+static inline int is_ab8500(struct ab8500 *ab)
+{
+	return ab->version == AB8500_VERSION_AB8500;
+}
+
+static inline int is_ab8505(struct ab8500 *ab)
+{
+	return ab->version == AB8500_VERSION_AB8505;
+}
+
+static inline int is_ab9540(struct ab8500 *ab)
+{
+	return ab->version == AB8500_VERSION_AB9540;
+}
+
+static inline int is_ab8540(struct ab8500 *ab)
+{
+	return ab->version == AB8500_VERSION_AB8540;
+}
+
+/* include also ab8505, ab9540... */
+static inline int is_ab8500_1p1_or_earlier(struct ab8500 *ab)
+{
+	return (is_ab8500(ab) && (ab->chip_id <= AB8500_CUT1P1));
+}
+
+/* include also ab8505, ab9540... */
+static inline int is_ab8500_2p0_or_earlier(struct ab8500 *ab)
+{
+	return (is_ab8500(ab) && (ab->chip_id <= AB8500_CUT2P0));
+}
+
 #endif /* MFD_AB8500_H */
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h
index 60d27f7..636423b 100644
--- a/include/linux/mfd/db8500-prcmu.h
+++ b/include/linux/mfd/db8500-prcmu.h
@@ -11,6 +11,24 @@
 #define __MFD_DB8500_PRCMU_H
 
 #include <linux/interrupt.h>
+#include <linux/bitops.h>
+
+/*
+ * Registers
+ */
+#define DB8500_PRCM_GPIOCR 0x138
+#define DB8500_PRCM_GPIOCR_DBG_UARTMOD_CMD0	BIT(0)
+#define DB8500_PRCM_GPIOCR_DBG_STM_APE_CMD	BIT(9)
+#define DB8500_PRCM_GPIOCR_DBG_STM_MOD_CMD1	BIT(11)
+#define DB8500_PRCM_GPIOCR_SPI2_SELECT		BIT(23)
+
+#define DB8500_PRCM_LINE_VALUE 0x170
+#define DB8500_PRCM_LINE_VALUE_HSI_CAWAKE0	BIT(3)
+
+#define DB8500_PRCM_DSI_SW_RESET 0x324
+#define DB8500_PRCM_DSI_SW_RESET_DSI0_SW_RESETN BIT(0)
+#define DB8500_PRCM_DSI_SW_RESET_DSI1_SW_RESETN BIT(1)
+#define DB8500_PRCM_DSI_SW_RESET_DSI2_SW_RESETN BIT(2)
 
 /* This portion previously known as <mach/prcmu-fw-defs_v1.h> */
 
@@ -457,6 +475,25 @@ enum hw_acc_dev {
 	NUM_HW_ACC
 };
 
+/**
+ * enum prcmu_power_status - results from set_power_state
+ * @PRCMU_SLEEP_OK: Sleep went ok
+ * @PRCMU_DEEP_SLEEP_OK: DeepSleep went ok
+ * @PRCMU_IDLE_OK: Idle went ok
+ * @PRCMU_DEEPIDLE_OK: DeepIdle went ok
+ * @PRCMU_PRCMU2ARMPENDINGIT_ER: Pending interrupt detected
+ * @PRCMU_ARMPENDINGIT_ER: Pending interrupt detected
+ *
+ */
+enum prcmu_power_status {
+	PRCMU_SLEEP_OK			= 0xf3,
+	PRCMU_DEEP_SLEEP_OK		= 0xf6,
+	PRCMU_IDLE_OK			= 0xf0,
+	PRCMU_DEEPIDLE_OK		= 0xe3,
+	PRCMU_PRCMU2ARMPENDINGIT_ER	= 0x91,
+	PRCMU_ARMPENDINGIT_ER		= 0x93,
+};
+
 /*
  * Definitions for autonomous power management configuration.
  */
@@ -493,6 +530,18 @@ struct prcmu_auto_pm_config {
 	u8 sva_policy;
 };
 
+#define PRCMU_FW_PROJECT_U8500		2
+#define PRCMU_FW_PROJECT_U9500		4
+#define PRCMU_FW_PROJECT_U8500_C2	7
+#define PRCMU_FW_PROJECT_U9500_C2	11
+
+struct prcmu_fw_version {
+	u8 project;
+	u8 api_version;
+	u8 func_version;
+	u8 errata;
+};
+
 #ifdef CONFIG_MFD_DB8500_PRCMU
 
 void db8500_prcmu_early_init(void);
@@ -500,13 +549,9 @@ int prcmu_set_rc_a2p(enum romcode_write);
 enum romcode_read prcmu_get_rc_p2a(void);
 enum ap_pwrst prcmu_get_xp70_current_state(void);
 bool prcmu_has_arm_maxopp(void);
-bool prcmu_is_u8400(void);
-int prcmu_set_ape_opp(u8 opp);
-int prcmu_get_ape_opp(void);
+struct prcmu_fw_version *prcmu_get_fw_version(void);
 int prcmu_request_ape_opp_100_voltage(bool enable);
 int prcmu_release_usb_wakeup_state(void);
-int prcmu_set_ddr_opp(u8 opp);
-int prcmu_get_ddr_opp(void);
 /* NOTE! Use regulator framework instead */
 int prcmu_set_hwacc(u16 hw_acc_dev, u8 state);
 void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
@@ -515,27 +560,26 @@ bool prcmu_is_auto_pm_enabled(void);
 
 int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
 int prcmu_set_clock_divider(u8 clock, u8 divider);
-int prcmu_config_hotdog(u8 threshold);
-int prcmu_config_hotmon(u8 low, u8 high);
-int prcmu_start_temp_sense(u16 cycles32k);
-int prcmu_stop_temp_sense(void);
+int db8500_prcmu_config_hotdog(u8 threshold);
+int db8500_prcmu_config_hotmon(u8 low, u8 high);
+int db8500_prcmu_start_temp_sense(u16 cycles32k);
+int db8500_prcmu_stop_temp_sense(void);
 int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
 int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
 
 void prcmu_ac_wake_req(void);
 void prcmu_ac_sleep_req(void);
-void prcmu_modem_reset(void);
-void prcmu_enable_spi2(void);
-void prcmu_disable_spi2(void);
+void db8500_prcmu_modem_reset(void);
 
-int prcmu_config_a9wdog(u8 num, bool sleep_auto_off);
-int prcmu_enable_a9wdog(u8 id);
-int prcmu_disable_a9wdog(u8 id);
-int prcmu_kick_a9wdog(u8 id);
-int prcmu_load_a9wdog(u8 id, u32 val);
+int db8500_prcmu_config_a9wdog(u8 num, bool sleep_auto_off);
+int db8500_prcmu_enable_a9wdog(u8 id);
+int db8500_prcmu_disable_a9wdog(u8 id);
+int db8500_prcmu_kick_a9wdog(u8 id);
+int db8500_prcmu_load_a9wdog(u8 id, u32 val);
 
 void db8500_prcmu_system_reset(u16 reset_code);
 int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll);
+u8 db8500_prcmu_get_power_state_result(void);
 void db8500_prcmu_enable_wakeups(u32 wakeups);
 int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state);
 int db8500_prcmu_request_clock(u8 clock, bool enable);
@@ -549,6 +593,14 @@ u16 db8500_prcmu_get_reset_code(void);
 bool db8500_prcmu_is_ac_wake_requested(void);
 int db8500_prcmu_set_arm_opp(u8 opp);
 int db8500_prcmu_get_arm_opp(void);
+int db8500_prcmu_set_ape_opp(u8 opp);
+int db8500_prcmu_get_ape_opp(void);
+int db8500_prcmu_set_ddr_opp(u8 opp);
+int db8500_prcmu_get_ddr_opp(void);
+
+u32 db8500_prcmu_read(unsigned int reg);
+void db8500_prcmu_write(unsigned int reg, u32 value);
+void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value);
 
 #else /* !CONFIG_MFD_DB8500_PRCMU */
 
@@ -574,17 +626,17 @@ static inline bool prcmu_has_arm_maxopp(void)
 	return false;
 }
 
-static inline bool prcmu_is_u8400(void)
+static inline struct prcmu_fw_version *prcmu_get_fw_version(void)
 {
-	return false;
+	return NULL;
 }
 
-static inline int prcmu_set_ape_opp(u8 opp)
+static inline int db8500_prcmu_set_ape_opp(u8 opp)
 {
 	return 0;
 }
 
-static inline int prcmu_get_ape_opp(void)
+static inline int db8500_prcmu_get_ape_opp(void)
 {
 	return APE_100_OPP;
 }
@@ -599,12 +651,12 @@ static inline int prcmu_release_usb_wakeup_state(void)
 	return 0;
 }
 
-static inline int prcmu_set_ddr_opp(u8 opp)
+static inline int db8500_prcmu_set_ddr_opp(u8 opp)
 {
 	return 0;
 }
 
-static inline int prcmu_get_ddr_opp(void)
+static inline int db8500_prcmu_get_ddr_opp(void)
 {
 	return DDR_100_OPP;
 }
@@ -613,7 +665,6 @@ static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state)
 {
 	return 0;
 }
-
 static inline void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
 	struct prcmu_auto_pm_config *idle)
 {
@@ -634,22 +685,22 @@ static inline int prcmu_set_clock_divider(u8 clock, u8 divider)
 	return 0;
 }
 
-static inline int prcmu_config_hotdog(u8 threshold)
+static inline int db8500_prcmu_config_hotdog(u8 threshold)
 {
 	return 0;
 }
 
-static inline int prcmu_config_hotmon(u8 low, u8 high)
+static inline int db8500_prcmu_config_hotmon(u8 low, u8 high)
 {
 	return 0;
 }
 
-static inline int prcmu_start_temp_sense(u16 cycles32k)
+static inline int db8500_prcmu_start_temp_sense(u16 cycles32k)
 {
 	return 0;
 }
 
-static inline int prcmu_stop_temp_sense(void)
+static inline int db8500_prcmu_stop_temp_sense(void)
 {
 	return 0;
 }
@@ -668,22 +719,17 @@ static inline void prcmu_ac_wake_req(void) {}
 
 static inline void prcmu_ac_sleep_req(void) {}
 
-static inline void prcmu_modem_reset(void) {}
+static inline void db8500_prcmu_modem_reset(void) {}
 
-static inline int prcmu_enable_spi2(void)
-{
-	return 0;
-}
+static inline void db8500_prcmu_system_reset(u16 reset_code) {}
 
-static inline int prcmu_disable_spi2(void)
+static inline int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
+	bool keep_ap_pll)
 {
 	return 0;
 }
 
-static inline void db8500_prcmu_system_reset(u16 reset_code) {}
-
-static inline int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk,
-	bool keep_ap_pll)
+static inline u8 db8500_prcmu_get_power_state_result(void)
 {
 	return 0;
 }
@@ -729,27 +775,27 @@ static inline u16 db8500_prcmu_get_reset_code(void)
 	return 0;
 }
 
-static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
+static inline int db8500_prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
 {
 	return 0;
 }
 
-static inline int prcmu_enable_a9wdog(u8 id)
+static inline int db8500_prcmu_enable_a9wdog(u8 id)
 {
 	return 0;
 }
 
-static inline int prcmu_disable_a9wdog(u8 id)
+static inline int db8500_prcmu_disable_a9wdog(u8 id)
 {
 	return 0;
 }
 
-static inline int prcmu_kick_a9wdog(u8 id)
+static inline int db8500_prcmu_kick_a9wdog(u8 id)
 {
 	return 0;
 }
 
-static inline int prcmu_load_a9wdog(u8 id, u32 val)
+static inline int db8500_prcmu_load_a9wdog(u8 id, u32 val)
 {
 	return 0;
 }
@@ -769,6 +815,16 @@ static inline int db8500_prcmu_get_arm_opp(void)
 	return 0;
 }
 
+static inline u32 db8500_prcmu_read(unsigned int reg)
+{
+	return 0;
+}
+
+static inline void db8500_prcmu_write(unsigned int reg, u32 value) {}
+
+static inline void db8500_prcmu_write_masked(unsigned int reg, u32 mask,
+	u32 value) {}
+
 #endif /* !CONFIG_MFD_DB8500_PRCMU */
 
 #endif /* __MFD_DB8500_PRCMU_H */
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
index bac942f..b3b5adf 100644
--- a/include/linux/mfd/dbx500-prcmu.h
+++ b/include/linux/mfd/dbx500-prcmu.h
@@ -10,7 +10,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
-#include <asm/mach-types.h>
+#include <linux/err.h>
 
 /* PRCMU Wakeup defines */
 enum prcmu_wakeup_index {
@@ -80,6 +80,29 @@ enum prcmu_wakeup_index {
 #define EPOD_STATE_ON_CLK_OFF	0x03
 #define EPOD_STATE_ON		0x04
 
+/* DB5500 CLKOUT IDs */
+enum {
+	DB5500_CLKOUT0 = 0,
+	DB5500_CLKOUT1,
+};
+
+/* DB5500 CLKOUTx sources */
+enum {
+	DB5500_CLKOUT_REF_CLK_SEL0,
+	DB5500_CLKOUT_RTC_CLK0_SEL0,
+	DB5500_CLKOUT_ULP_CLK_SEL0,
+	DB5500_CLKOUT_STATIC0,
+	DB5500_CLKOUT_REFCLK,
+	DB5500_CLKOUT_ULPCLK,
+	DB5500_CLKOUT_ARMCLK,
+	DB5500_CLKOUT_SYSACC0CLK,
+	DB5500_CLKOUT_SOC0PLLCLK,
+	DB5500_CLKOUT_SOC1PLLCLK,
+	DB5500_CLKOUT_DDRPLLCLK,
+	DB5500_CLKOUT_TVCLK,
+	DB5500_CLKOUT_IRDACLK,
+};
+
 /*
  * CLKOUT sources
  */
@@ -111,6 +134,7 @@ enum prcmu_clock {
 	PRCMU_MSP1CLK,
 	PRCMU_I2CCLK,
 	PRCMU_SDMMCCLK,
+	PRCMU_SPARE1CLK,
 	PRCMU_SLIMCLK,
 	PRCMU_PER1CLK,
 	PRCMU_PER2CLK,
@@ -139,12 +163,20 @@ enum prcmu_clock {
 	PRCMU_IRRCCLK,
 	PRCMU_SIACLK,
 	PRCMU_SVACLK,
+	PRCMU_ACLK,
 	PRCMU_NUM_REG_CLOCKS,
 	PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS,
+	PRCMU_CDCLK,
 	PRCMU_TIMCLK,
 	PRCMU_PLLSOC0,
 	PRCMU_PLLSOC1,
 	PRCMU_PLLDDR,
+	PRCMU_PLLDSI,
+	PRCMU_DSI0CLK,
+	PRCMU_DSI1CLK,
+	PRCMU_DSI0ESCCLK,
+	PRCMU_DSI1ESCCLK,
+	PRCMU_DSI2ESCCLK,
 };
 
 /**
@@ -153,12 +185,14 @@ enum prcmu_clock {
  * @APE_NO_CHANGE: The APE operating point is unchanged
  * @APE_100_OPP: The new APE operating point is ape100opp
  * @APE_50_OPP: 50%
+ * @APE_50_PARTLY_25_OPP: 50%, except some clocks at 25%.
  */
 enum ape_opp {
 	APE_OPP_INIT = 0x00,
 	APE_NO_CHANGE = 0x01,
 	APE_100_OPP = 0x02,
-	APE_50_OPP = 0x03
+	APE_50_OPP = 0x03,
+	APE_50_PARTLY_25_OPP = 0xFF,
 };
 
 /**
@@ -218,9 +252,11 @@ enum ddr_pwrst {
 
 #if defined(CONFIG_UX500_SOC_DB8500) || defined(CONFIG_UX500_SOC_DB5500)
 
+#include <mach/id.h>
+
 static inline void __init prcmu_early_init(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_early_init();
 	else
 		return db8500_prcmu_early_init();
@@ -229,7 +265,7 @@ static inline void __init prcmu_early_init(void)
 static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
 		bool keep_ap_pll)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_set_power_state(state, keep_ulp_clk,
 			keep_ap_pll);
 	else
@@ -237,9 +273,17 @@ static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
 			keep_ap_pll);
 }
 
+static inline u8 prcmu_get_power_state_result(void)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_get_power_state_result();
+}
+
 static inline int prcmu_set_epod(u16 epod_id, u8 epod_state)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return -EINVAL;
 	else
 		return db8500_prcmu_set_epod(epod_id, epod_state);
@@ -247,7 +291,7 @@ static inline int prcmu_set_epod(u16 epod_id, u8 epod_state)
 
 static inline void prcmu_enable_wakeups(u32 wakeups)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		db5500_prcmu_enable_wakeups(wakeups);
 	else
 		db8500_prcmu_enable_wakeups(wakeups);
@@ -260,7 +304,7 @@ static inline void prcmu_disable_wakeups(void)
 
 static inline void prcmu_config_abb_event_readout(u32 abb_events)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		db5500_prcmu_config_abb_event_readout(abb_events);
 	else
 		db8500_prcmu_config_abb_event_readout(abb_events);
@@ -268,7 +312,7 @@ static inline void prcmu_config_abb_event_readout(u32 abb_events)
 
 static inline void prcmu_get_abb_event_buffer(void __iomem **buf)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		db5500_prcmu_get_abb_event_buffer(buf);
 	else
 		db8500_prcmu_get_abb_event_buffer(buf);
@@ -281,20 +325,34 @@ int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
 
 static inline int prcmu_request_clock(u8 clock, bool enable)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_request_clock(clock, enable);
 	else
 		return db8500_prcmu_request_clock(clock, enable);
 }
 
-int prcmu_set_ape_opp(u8 opp);
-int prcmu_get_ape_opp(void);
-int prcmu_set_ddr_opp(u8 opp);
-int prcmu_get_ddr_opp(void);
+unsigned long prcmu_clock_rate(u8 clock);
+long prcmu_round_clock_rate(u8 clock, unsigned long rate);
+int prcmu_set_clock_rate(u8 clock, unsigned long rate);
+
+static inline int prcmu_set_ddr_opp(u8 opp)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_set_ddr_opp(opp);
+}
+static inline int prcmu_get_ddr_opp(void)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_get_ddr_opp();
+}
 
 static inline int prcmu_set_arm_opp(u8 opp)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return -EINVAL;
 	else
 		return db8500_prcmu_set_arm_opp(opp);
@@ -302,15 +360,31 @@ static inline int prcmu_set_arm_opp(u8 opp)
 
 static inline int prcmu_get_arm_opp(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return -EINVAL;
 	else
 		return db8500_prcmu_get_arm_opp();
 }
 
+static inline int prcmu_set_ape_opp(u8 opp)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_set_ape_opp(opp);
+}
+
+static inline int prcmu_get_ape_opp(void)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_get_ape_opp();
+}
+
 static inline void prcmu_system_reset(u16 reset_code)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_system_reset(reset_code);
 	else
 		return db8500_prcmu_system_reset(reset_code);
@@ -318,7 +392,7 @@ static inline void prcmu_system_reset(u16 reset_code)
 
 static inline u16 prcmu_get_reset_code(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_get_reset_code();
 	else
 		return db8500_prcmu_get_reset_code();
@@ -326,10 +400,17 @@ static inline u16 prcmu_get_reset_code(void)
 
 void prcmu_ac_wake_req(void);
 void prcmu_ac_sleep_req(void);
-void prcmu_modem_reset(void);
+static inline void prcmu_modem_reset(void)
+{
+	if (cpu_is_u5500())
+		return;
+	else
+		return db8500_prcmu_modem_reset();
+}
+
 static inline bool prcmu_is_ac_wake_requested(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_is_ac_wake_requested();
 	else
 		return db8500_prcmu_is_ac_wake_requested();
@@ -337,7 +418,7 @@ static inline bool prcmu_is_ac_wake_requested(void)
 
 static inline int prcmu_set_display_clocks(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_set_display_clocks();
 	else
 		return db8500_prcmu_set_display_clocks();
@@ -345,7 +426,7 @@ static inline int prcmu_set_display_clocks(void)
 
 static inline int prcmu_disable_dsipll(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_disable_dsipll();
 	else
 		return db8500_prcmu_disable_dsipll();
@@ -353,7 +434,7 @@ static inline int prcmu_disable_dsipll(void)
 
 static inline int prcmu_enable_dsipll(void)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return db5500_prcmu_enable_dsipll();
 	else
 		return db8500_prcmu_enable_dsipll();
@@ -361,11 +442,107 @@ static inline int prcmu_enable_dsipll(void)
 
 static inline int prcmu_config_esram0_deep_sleep(u8 state)
 {
-	if (machine_is_u5500())
+	if (cpu_is_u5500())
 		return -EINVAL;
 	else
 		return db8500_prcmu_config_esram0_deep_sleep(state);
 }
+
+static inline int prcmu_config_hotdog(u8 threshold)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_config_hotdog(threshold);
+}
+
+static inline int prcmu_config_hotmon(u8 low, u8 high)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_config_hotmon(low, high);
+}
+
+static inline int prcmu_start_temp_sense(u16 cycles32k)
+{
+	if (cpu_is_u5500())
+		return  -EINVAL;
+	else
+		return  db8500_prcmu_start_temp_sense(cycles32k);
+}
+
+static inline int prcmu_stop_temp_sense(void)
+{
+	if (cpu_is_u5500())
+		return  -EINVAL;
+	else
+		return  db8500_prcmu_stop_temp_sense();
+}
+
+static inline u32 prcmu_read(unsigned int reg)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_read(reg);
+}
+
+static inline void prcmu_write(unsigned int reg, u32 value)
+{
+	if (cpu_is_u5500())
+		return;
+	else
+		db8500_prcmu_write(reg, value);
+}
+
+static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value)
+{
+	if (cpu_is_u5500())
+		return;
+	else
+		db8500_prcmu_write_masked(reg, mask, value);
+}
+
+static inline int prcmu_enable_a9wdog(u8 id)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_enable_a9wdog(id);
+}
+
+static inline int prcmu_disable_a9wdog(u8 id)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_disable_a9wdog(id);
+}
+
+static inline int prcmu_kick_a9wdog(u8 id)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_kick_a9wdog(id);
+}
+
+static inline int prcmu_load_a9wdog(u8 id, u32 timeout)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_load_a9wdog(id, timeout);
+}
+
+static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
+{
+	if (cpu_is_u5500())
+		return -EINVAL;
+	else
+		return db8500_prcmu_config_a9wdog(num, sleep_auto_off);
+}
 #else
 
 static inline void __init prcmu_early_init(void) {}
@@ -405,6 +582,21 @@ static inline int prcmu_request_clock(u8 clock, bool enable)
 	return 0;
 }
 
+static inline long prcmu_round_clock_rate(u8 clock, unsigned long rate)
+{
+	return 0;
+}
+
+static inline int prcmu_set_clock_rate(u8 clock, unsigned long rate)
+{
+	return 0;
+}
+
+static inline unsigned long prcmu_clock_rate(u8 clock)
+{
+	return 0;
+}
+
 static inline int prcmu_set_ape_opp(u8 opp)
 {
 	return 0;
@@ -480,14 +672,133 @@ static inline void prcmu_get_abb_event_buffer(void __iomem **buf)
 	*buf = NULL;
 }
 
+static inline int prcmu_config_hotdog(u8 threshold)
+{
+	return 0;
+}
+
+static inline int prcmu_config_hotmon(u8 low, u8 high)
+{
+	return 0;
+}
+
+static inline int prcmu_start_temp_sense(u16 cycles32k)
+{
+	return 0;
+}
+
+static inline int prcmu_stop_temp_sense(void)
+{
+	return 0;
+}
+
+static inline u32 prcmu_read(unsigned int reg)
+{
+	return 0;
+}
+
+static inline void prcmu_write(unsigned int reg, u32 value) {}
+
+static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
+
+#endif
+
+static inline void prcmu_set(unsigned int reg, u32 bits)
+{
+	prcmu_write_masked(reg, bits, bits);
+}
+
+static inline void prcmu_clear(unsigned int reg, u32 bits)
+{
+	prcmu_write_masked(reg, bits, 0);
+}
+
+#if defined(CONFIG_UX500_SOC_DB8500) || defined(CONFIG_UX500_SOC_DB5500)
+
+/**
+ * prcmu_enable_spi2 - Enables pin muxing for SPI2 on OtherAlternateC1.
+ */
+static inline void prcmu_enable_spi2(void)
+{
+	if (cpu_is_u8500())
+		prcmu_set(DB8500_PRCM_GPIOCR, DB8500_PRCM_GPIOCR_SPI2_SELECT);
+}
+
+/**
+ * prcmu_disable_spi2 - Disables pin muxing for SPI2 on OtherAlternateC1.
+ */
+static inline void prcmu_disable_spi2(void)
+{
+	if (cpu_is_u8500())
+		prcmu_clear(DB8500_PRCM_GPIOCR, DB8500_PRCM_GPIOCR_SPI2_SELECT);
+}
+
+/**
+ * prcmu_enable_stm_mod_uart - Enables pin muxing for STMMOD
+ * and UARTMOD on OtherAlternateC3.
+ */
+static inline void prcmu_enable_stm_mod_uart(void)
+{
+	if (cpu_is_u8500()) {
+		prcmu_set(DB8500_PRCM_GPIOCR,
+			(DB8500_PRCM_GPIOCR_DBG_STM_MOD_CMD1 |
+			 DB8500_PRCM_GPIOCR_DBG_UARTMOD_CMD0));
+	}
+}
+
+/**
+ * prcmu_disable_stm_mod_uart - Disables pin muxing for STMMOD
+ * and UARTMOD on OtherAlternateC3.
+ */
+static inline void prcmu_disable_stm_mod_uart(void)
+{
+	if (cpu_is_u8500()) {
+		prcmu_clear(DB8500_PRCM_GPIOCR,
+			(DB8500_PRCM_GPIOCR_DBG_STM_MOD_CMD1 |
+			 DB8500_PRCM_GPIOCR_DBG_UARTMOD_CMD0));
+	}
+}
+
+/**
+ * prcmu_enable_stm_ape - Enables pin muxing for STM APE on OtherAlternateC1.
+ */
+static inline void prcmu_enable_stm_ape(void)
+{
+	if (cpu_is_u8500()) {
+		prcmu_set(DB8500_PRCM_GPIOCR,
+			DB8500_PRCM_GPIOCR_DBG_STM_APE_CMD);
+	}
+}
+
+/**
+ * prcmu_disable_stm_ape - Disables pin muxing for STM APE on OtherAlternateC1.
+ */
+static inline void prcmu_disable_stm_ape(void)
+{
+	if (cpu_is_u8500()) {
+		prcmu_clear(DB8500_PRCM_GPIOCR,
+			DB8500_PRCM_GPIOCR_DBG_STM_APE_CMD);
+	}
+}
+
+#else
+
+static inline void prcmu_enable_spi2(void) {}
+static inline void prcmu_disable_spi2(void) {}
+static inline void prcmu_enable_stm_mod_uart(void) {}
+static inline void prcmu_disable_stm_mod_uart(void) {}
+static inline void prcmu_enable_stm_ape(void) {}
+static inline void prcmu_disable_stm_ape(void) {}
+
 #endif
 
 /* PRCMU QoS APE OPP class */
 #define PRCMU_QOS_APE_OPP 1
 #define PRCMU_QOS_DDR_OPP 2
+#define PRCMU_QOS_ARM_OPP 3
 #define PRCMU_QOS_DEFAULT_VALUE -1
 
-#ifdef CONFIG_UX500_PRCMU_QOS_POWER
+#ifdef CONFIG_DBX500_PRCMU_QOS_POWER
 
 unsigned long prcmu_qos_get_cpufreq_opp_delay(void);
 void prcmu_qos_set_cpufreq_opp_delay(unsigned long);
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index b86ee45..10e038b 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -38,7 +38,8 @@ int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq);
 int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
 
 int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
-		unsigned int mode, unsigned int channel, unsigned int *sample);
+		unsigned int mode, unsigned int channel,
+		u8 ato, bool atox, unsigned int *sample);
 
 #define MC13XXX_IRQ_ADCDONE	0
 #define MC13XXX_IRQ_ADCBISDONE	1
@@ -157,6 +158,18 @@ struct mc13xxx_buttons_platform_data {
 	unsigned short b3on_key;
 };
 
+struct mc13xxx_ts_platform_data {
+	/* Delay between Touchscreen polarization and ADC Conversion.
+	 * Given in clock ticks of a 32 kHz clock which gives a granularity of
+	 * about 30.5ms */
+	u8 ato;
+
+#define MC13783_TS_ATO_FIRST false
+#define MC13783_TS_ATO_EACH  true
+	/* Use the ATO delay only for the first conversion or for each one */
+	bool atox;
+};
+
 struct mc13xxx_platform_data {
 #define MC13XXX_USE_TOUCHSCREEN (1 << 0)
 #define MC13XXX_USE_CODEC	(1 << 1)
@@ -167,6 +180,7 @@ struct mc13xxx_platform_data {
 	struct mc13xxx_regulator_platform_data regulators;
 	struct mc13xxx_leds_platform_data *leds;
 	struct mc13xxx_buttons_platform_data *buttons;
+	struct mc13xxx_ts_platform_data touch;
 };
 
 #define MC13XXX_ADC_MODE_TS		1
diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h
index f88c1cc..a9e8bd1 100644
--- a/include/linux/mfd/mcp.h
+++ b/include/linux/mfd/mcp.h
@@ -10,8 +10,6 @@
 #ifndef MCP_H
 #define MCP_H
 
-#include <mach/dma.h>
-
 struct mcp_ops;
 
 struct mcp {
@@ -21,12 +19,7 @@ struct mcp {
 	int		use_count;
 	unsigned int	sclk_rate;
 	unsigned int	rw_timeout;
-	dma_device_t	dma_audio_rd;
-	dma_device_t	dma_audio_wr;
-	dma_device_t	dma_telco_rd;
-	dma_device_t	dma_telco_wr;
 	struct device	attached_device;
-	int		gpio_base;
 };
 
 struct mcp_ops {
@@ -47,15 +40,14 @@ void mcp_disable(struct mcp *);
 #define mcp_get_sclk_rate(mcp)	((mcp)->sclk_rate)
 
 struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_register(struct mcp *);
-void mcp_host_unregister(struct mcp *);
+int mcp_host_add(struct mcp *, void *);
+void mcp_host_del(struct mcp *);
+void mcp_host_free(struct mcp *);
 
 struct mcp_driver {
 	struct device_driver drv;
 	int (*probe)(struct mcp *);
 	void (*remove)(struct mcp *);
-	int (*suspend)(struct mcp *, pm_message_t);
-	int (*resume)(struct mcp *);
 };
 
 int mcp_driver_register(struct mcp_driver *);
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index ca1d7a3..a1c6aa7 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -26,6 +26,7 @@ enum stmpe_partnum {
 	STMPE1601,
 	STMPE2401,
 	STMPE2403,
+	STMPE_NBR_PARTS
 };
 
 /*
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
new file mode 100644
index 0000000..e030ef9
--- /dev/null
+++ b/include/linux/mfd/tps65217.h
@@ -0,0 +1,283 @@
+/*
+ * linux/mfd/tps65217.h
+ *
+ * Functions to access TPS65217 power management chip.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LINUX_MFD_TPS65217_H
+#define __LINUX_MFD_TPS65217_H
+
+#include <linux/i2c.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+/* I2C ID for TPS65217 part */
+#define TPS65217_I2C_ID			0x24
+
+/* All register addresses */
+#define TPS65217_REG_CHIPID		0X00
+#define TPS65217_REG_PPATH		0X01
+#define TPS65217_REG_INT		0X02
+#define TPS65217_REG_CHGCONFIG0		0X03
+#define TPS65217_REG_CHGCONFIG1		0X04
+#define TPS65217_REG_CHGCONFIG2		0X05
+#define TPS65217_REG_CHGCONFIG3		0X06
+#define TPS65217_REG_WLEDCTRL1		0X07
+#define TPS65217_REG_WLEDCTRL2		0X08
+#define TPS65217_REG_MUXCTRL		0X09
+#define TPS65217_REG_STATUS		0X0A
+#define TPS65217_REG_PASSWORD		0X0B
+#define TPS65217_REG_PGOOD		0X0C
+#define TPS65217_REG_DEFPG		0X0D
+#define TPS65217_REG_DEFDCDC1		0X0E
+#define TPS65217_REG_DEFDCDC2		0X0F
+#define TPS65217_REG_DEFDCDC3		0X10
+#define TPS65217_REG_DEFSLEW		0X11
+#define TPS65217_REG_DEFLDO1		0X12
+#define TPS65217_REG_DEFLDO2		0X13
+#define TPS65217_REG_DEFLS1		0X14
+#define TPS65217_REG_DEFLS2		0X15
+#define TPS65217_REG_ENABLE		0X16
+#define TPS65217_REG_DEFUVLO		0X18
+#define TPS65217_REG_SEQ1		0X19
+#define TPS65217_REG_SEQ2		0X1A
+#define TPS65217_REG_SEQ3		0X1B
+#define TPS65217_REG_SEQ4		0X1C
+#define TPS65217_REG_SEQ5		0X1D
+#define TPS65217_REG_SEQ6		0X1E
+
+/* Register field definitions */
+#define TPS65217_CHIPID_CHIP_MASK	0xF0
+#define TPS65217_CHIPID_REV_MASK	0x0F
+
+#define TPS65217_PPATH_ACSINK_ENABLE	BIT(7)
+#define TPS65217_PPATH_USBSINK_ENABLE	BIT(6)
+#define TPS65217_PPATH_AC_PW_ENABLE	BIT(5)
+#define TPS65217_PPATH_USB_PW_ENABLE	BIT(4)
+#define TPS65217_PPATH_AC_CURRENT_MASK	0x0C
+#define TPS65217_PPATH_USB_CURRENT_MASK	0x03
+
+#define TPS65217_INT_PBM		BIT(6)
+#define TPS65217_INT_ACM		BIT(5)
+#define TPS65217_INT_USBM		BIT(4)
+#define TPS65217_INT_PBI		BIT(2)
+#define TPS65217_INT_ACI		BIT(1)
+#define TPS65217_INT_USBI		BIT(0)
+
+#define TPS65217_CHGCONFIG0_TREG	BIT(7)
+#define TPS65217_CHGCONFIG0_DPPM	BIT(6)
+#define TPS65217_CHGCONFIG0_TSUSP	BIT(5)
+#define TPS65217_CHGCONFIG0_TERMI	BIT(4)
+#define TPS65217_CHGCONFIG0_ACTIVE	BIT(3)
+#define TPS65217_CHGCONFIG0_CHGTOUT	BIT(2)
+#define TPS65217_CHGCONFIG0_PCHGTOUT	BIT(1)
+#define TPS65217_CHGCONFIG0_BATTEMP	BIT(0)
+
+#define TPS65217_CHGCONFIG1_TMR_MASK	0xC0
+#define TPS65217_CHGCONFIG1_TMR_ENABLE	BIT(5)
+#define TPS65217_CHGCONFIG1_NTC_TYPE	BIT(4)
+#define TPS65217_CHGCONFIG1_RESET	BIT(3)
+#define TPS65217_CHGCONFIG1_TERM	BIT(2)
+#define TPS65217_CHGCONFIG1_SUSP	BIT(1)
+#define TPS65217_CHGCONFIG1_CHG_EN	BIT(0)
+
+#define TPS65217_CHGCONFIG2_DYNTMR	BIT(7)
+#define TPS65217_CHGCONFIG2_VPREGHG	BIT(6)
+#define TPS65217_CHGCONFIG2_VOREG_MASK	0x30
+
+#define TPS65217_CHGCONFIG3_ICHRG_MASK	0xC0
+#define TPS65217_CHGCONFIG3_DPPMTH_MASK	0x30
+#define TPS65217_CHGCONFIG2_PCHRGT	BIT(3)
+#define TPS65217_CHGCONFIG2_TERMIF	0x06
+#define TPS65217_CHGCONFIG2_TRANGE	BIT(0)
+
+#define TPS65217_WLEDCTRL1_ISINK_ENABLE	BIT(3)
+#define TPS65217_WLEDCTRL1_ISEL		BIT(2)
+#define TPS65217_WLEDCTRL1_FDIM_MASK	0x03
+
+#define TPS65217_WLEDCTRL2_DUTY_MASK	0x7F
+
+#define TPS65217_MUXCTRL_MUX_MASK	0x07
+
+#define TPS65217_STATUS_OFF		BIT(7)
+#define TPS65217_STATUS_ACPWR		BIT(3)
+#define TPS65217_STATUS_USBPWR		BIT(2)
+#define TPS65217_STATUS_PB		BIT(0)
+
+#define TPS65217_PASSWORD_REGS_UNLOCK	0x7D
+
+#define TPS65217_PGOOD_LDO3_PG		BIT(6)
+#define TPS65217_PGOOD_LDO4_PG		BIT(5)
+#define TPS65217_PGOOD_DC1_PG		BIT(4)
+#define TPS65217_PGOOD_DC2_PG		BIT(3)
+#define TPS65217_PGOOD_DC3_PG		BIT(2)
+#define TPS65217_PGOOD_LDO1_PG		BIT(1)
+#define TPS65217_PGOOD_LDO2_PG		BIT(0)
+
+#define TPS65217_DEFPG_LDO1PGM		BIT(3)
+#define TPS65217_DEFPG_LDO2PGM		BIT(2)
+#define TPS65217_DEFPG_PGDLY_MASK	0x03
+
+#define TPS65217_DEFDCDCX_XADJX		BIT(7)
+#define TPS65217_DEFDCDCX_DCDC_MASK	0x3F
+
+#define TPS65217_DEFSLEW_GO		BIT(7)
+#define TPS65217_DEFSLEW_GODSBL		BIT(6)
+#define TPS65217_DEFSLEW_PFM_EN1	BIT(5)
+#define TPS65217_DEFSLEW_PFM_EN2	BIT(4)
+#define TPS65217_DEFSLEW_PFM_EN3	BIT(3)
+#define TPS65217_DEFSLEW_SLEW_MASK	0x07
+
+#define TPS65217_DEFLDO1_LDO1_MASK	0x0F
+
+#define TPS65217_DEFLDO2_TRACK		BIT(6)
+#define TPS65217_DEFLDO2_LDO2_MASK	0x3F
+
+#define TPS65217_DEFLDO3_LDO3_EN	BIT(5)
+#define TPS65217_DEFLDO3_LDO3_MASK	0x1F
+
+#define TPS65217_DEFLDO4_LDO4_EN	BIT(5)
+#define TPS65217_DEFLDO4_LDO4_MASK	0x1F
+
+#define TPS65217_ENABLE_LS1_EN		BIT(6)
+#define TPS65217_ENABLE_LS2_EN		BIT(5)
+#define TPS65217_ENABLE_DC1_EN		BIT(4)
+#define TPS65217_ENABLE_DC2_EN		BIT(3)
+#define TPS65217_ENABLE_DC3_EN		BIT(2)
+#define TPS65217_ENABLE_LDO1_EN		BIT(1)
+#define TPS65217_ENABLE_LDO2_EN		BIT(0)
+
+#define TPS65217_DEFUVLO_UVLOHYS	BIT(2)
+#define TPS65217_DEFUVLO_UVLO_MASK	0x03
+
+#define TPS65217_SEQ1_DC1_SEQ_MASK	0xF0
+#define TPS65217_SEQ1_DC2_SEQ_MASK	0x0F
+
+#define TPS65217_SEQ2_DC3_SEQ_MASK	0xF0
+#define TPS65217_SEQ2_LDO1_SEQ_MASK	0x0F
+
+#define TPS65217_SEQ3_LDO2_SEQ_MASK	0xF0
+#define TPS65217_SEQ3_LDO3_SEQ_MASK	0x0F
+
+#define TPS65217_SEQ4_LDO4_SEQ_MASK	0xF0
+
+#define TPS65217_SEQ5_DLY1_MASK		0xC0
+#define TPS65217_SEQ5_DLY2_MASK		0x30
+#define TPS65217_SEQ5_DLY3_MASK		0x0C
+#define TPS65217_SEQ5_DLY4_MASK		0x03
+
+#define TPS65217_SEQ6_DLY5_MASK		0xC0
+#define TPS65217_SEQ6_DLY6_MASK		0x30
+#define TPS65217_SEQ6_SEQUP		BIT(2)
+#define TPS65217_SEQ6_SEQDWN		BIT(1)
+#define TPS65217_SEQ6_INSTDWN		BIT(0)
+
+#define TPS65217_MAX_REGISTER		0x1E
+#define TPS65217_PROTECT_NONE		0
+#define TPS65217_PROTECT_L1		1
+#define TPS65217_PROTECT_L2		2
+
+
+enum tps65217_regulator_id {
+	/* DCDC's */
+	TPS65217_DCDC_1,
+	TPS65217_DCDC_2,
+	TPS65217_DCDC_3,
+	/* LDOs */
+	TPS65217_LDO_1,
+	TPS65217_LDO_2,
+	TPS65217_LDO_3,
+	TPS65217_LDO_4,
+};
+
+#define TPS65217_MAX_REG_ID		TPS65217_LDO_4
+
+/* Number of step-down converters available */
+#define TPS65217_NUM_DCDC		3
+/* Number of LDO voltage regulators available */
+#define TPS65217_NUM_LDO		4
+/* Number of total regulators available */
+#define TPS65217_NUM_REGULATOR		(TPS65217_NUM_DCDC + TPS65217_NUM_LDO)
+
+/**
+ * struct tps65217_board - packages regulator init data
+ * @tps65217_regulator_data: regulator initialization values
+ *
+ * Board data may be used to initialize regulator.
+ */
+struct tps65217_board {
+	struct regulator_init_data *tps65217_init_data;
+};
+
+/**
+ * struct tps_info - packages regulator constraints
+ * @name:		Voltage regulator name
+ * @min_uV:		minimum micro volts
+ * @max_uV:		minimum micro volts
+ * @vsel_to_uv:		Function pointer to get voltage from selector
+ * @uv_to_vsel:		Function pointer to get selector from voltage
+ * @table:		Table for non-uniform voltage step-size
+ * @table_len:		Length of the voltage table
+ * @enable_mask:	Regulator enable mask bits
+ * @set_vout_reg:	Regulator output voltage set register
+ * @set_vout_mask:	Regulator output voltage set mask
+ *
+ * This data is used to check the regualtor voltage limits while setting.
+ */
+struct tps_info {
+	const char *name;
+	int min_uV;
+	int max_uV;
+	int (*vsel_to_uv)(unsigned int vsel);
+	int (*uv_to_vsel)(int uV, unsigned int *vsel);
+	const int *table;
+	unsigned int table_len;
+	unsigned int enable_mask;
+	unsigned int set_vout_reg;
+	unsigned int set_vout_mask;
+};
+
+/**
+ * struct tps65217 - tps65217 sub-driver chip access routines
+ *
+ * Device data may be used to access the TPS65217 chip
+ */
+
+struct tps65217 {
+	struct device *dev;
+	struct tps65217_board *pdata;
+	struct regulator_desc desc[TPS65217_NUM_REGULATOR];
+	struct regulator_dev *rdev[TPS65217_NUM_REGULATOR];
+	struct tps_info *info[TPS65217_NUM_REGULATOR];
+	struct regmap *regmap;
+
+	/* Client devices */
+	struct platform_device *regulator_pdev[TPS65217_NUM_REGULATOR];
+};
+
+static inline struct tps65217 *dev_to_tps65217(struct device *dev)
+{
+	return dev_get_drvdata(dev);
+}
+
+int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
+					unsigned int *val);
+int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
+			unsigned int val, unsigned int level);
+int tps65217_set_bits(struct tps65217 *tps, unsigned int reg,
+		unsigned int mask, unsigned int val, unsigned int level);
+int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
+		unsigned int mask, unsigned int level);
+
+#endif /*  __LINUX_MFD_TPS65217_H */
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index d0cb12e..520f1bf 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -657,6 +657,8 @@
 
 
 /*Register GPIO  (0x80) register.RegisterDescription */
+#define GPIO_SLEEP_MASK                         0x80
+#define GPIO_SLEEP_SHIFT                        7
 #define GPIO_DEB_MASK                           0x10
 #define GPIO_DEB_SHIFT                          4
 #define GPIO_PUEN_MASK                          0x08
@@ -740,6 +742,11 @@
 #define TPS65910_GPIO_STS				BIT(1)
 #define TPS65910_GPIO_SET				BIT(0)
 
+/* Max number of TPS65910/11 GPIOs */
+#define TPS65910_NUM_GPIO				6
+#define TPS65911_NUM_GPIO				9
+#define TPS6591X_MAX_NUM_GPIO				9
+
 /* Regulator Index Definitions */
 #define TPS65910_REG_VRTC				0
 #define TPS65910_REG_VIO				1
@@ -768,6 +775,13 @@
 /* Max number of TPS65910/11 regulators */
 #define TPS65910_NUM_REGS				13
 
+/* External sleep controls through EN1/EN2/EN3 inputs*/
+#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1		0x1
+#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2		0x2
+#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3		0x4
+/* TPS65911 names the EN3 signal as SLEEP */
+#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP		0x4
+
 /**
  * struct tps65910_board
  * Board platform data may be used to initialize regulators.
@@ -779,6 +793,8 @@ struct tps65910_board {
 	int irq_base;
 	int vmbch_threshold;
 	int vmbch2_threshold;
+	unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
+	bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
 	struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];
 };
 
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index 9bc9ac6..bf3931e 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -174,8 +174,37 @@
 #define TWL6040_SYSCLK_SEL_LPPLL	0
 #define TWL6040_SYSCLK_SEL_HPPLL	1
 
+struct twl6040_codec_data {
+	u16 hs_left_step;
+	u16 hs_right_step;
+	u16 hf_left_step;
+	u16 hf_right_step;
+};
+
+struct twl6040_vibra_data {
+	unsigned int vibldrv_res;	/* left driver resistance */
+	unsigned int vibrdrv_res;	/* right driver resistance */
+	unsigned int viblmotor_res;	/* left motor resistance */
+	unsigned int vibrmotor_res;	/* right motor resistance */
+	int vddvibl_uV;			/* VDDVIBL volt, set 0 for fixed reg */
+	int vddvibr_uV;			/* VDDVIBR volt, set 0 for fixed reg */
+};
+
+struct twl6040_platform_data {
+	int audpwron_gpio;	/* audio power-on gpio */
+	unsigned int irq_base;
+
+	struct twl6040_codec_data *codec;
+	struct twl6040_vibra_data *vibra;
+};
+
+struct regmap;
+struct regulator_bulk_data;
+
 struct twl6040 {
 	struct device *dev;
+	struct regmap *regmap;
+	struct regulator_bulk_data *supplies; /* supplies for vio, v2v1 */
 	struct mutex mutex;
 	struct mutex io_mutex;
 	struct mutex irq_mutex;
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
index 4321f04..28af417 100644
--- a/include/linux/mfd/ucb1x00.h
+++ b/include/linux/mfd/ucb1x00.h
@@ -12,7 +12,7 @@
 
 #include <linux/mfd/mcp.h>
 #include <linux/gpio.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #define UCB_IO_DATA	0x00
 #define UCB_IO_DIR	0x01
@@ -104,17 +104,27 @@
 #define UCB_MODE_DYN_VFLAG_ENA	(1 << 12)
 #define UCB_MODE_AUD_OFF_CAN	(1 << 13)
 
+enum ucb1x00_reset {
+	UCB_RST_PROBE,
+	UCB_RST_RESUME,
+	UCB_RST_SUSPEND,
+	UCB_RST_REMOVE,
+	UCB_RST_PROBE_FAIL,
+};
 
-struct ucb1x00_irq {
-	void *devid;
-	void (*fn)(int, void *);
+struct ucb1x00_plat_data {
+	void			(*reset)(enum ucb1x00_reset);
+	unsigned		irq_base;
+	int			gpio_base;
+	unsigned		can_wakeup;
 };
 
 struct ucb1x00 {
-	spinlock_t		lock;
+	raw_spinlock_t		irq_lock;
 	struct mcp		*mcp;
 	unsigned int		irq;
-	struct semaphore	adc_sem;
+	int			irq_base;
+	struct mutex		adc_mutex;
 	spinlock_t		io_lock;
 	u16			id;
 	u16			io_dir;
@@ -122,7 +132,8 @@ struct ucb1x00 {
 	u16			adc_cr;
 	u16			irq_fal_enbl;
 	u16			irq_ris_enbl;
-	struct ucb1x00_irq	irq_handler[16];
+	u16			irq_mask;
+	u16			irq_wake;
 	struct device		dev;
 	struct list_head	node;
 	struct list_head	devs;
@@ -144,7 +155,7 @@ struct ucb1x00_driver {
 	struct list_head	devs;
 	int	(*add)(struct ucb1x00_dev *dev);
 	void	(*remove)(struct ucb1x00_dev *dev);
-	int	(*suspend)(struct ucb1x00_dev *dev, pm_message_t state);
+	int	(*suspend)(struct ucb1x00_dev *dev);
 	int	(*resume)(struct ucb1x00_dev *dev);
 };
 
@@ -245,15 +256,4 @@ unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
 void ucb1x00_adc_enable(struct ucb1x00 *ucb);
 void ucb1x00_adc_disable(struct ucb1x00 *ucb);
 
-/*
- * Which edges of the IRQ do you want to control today?
- */
-#define UCB_RISING	(1 << 0)
-#define UCB_FALLING	(1 << 1)
-
-int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-
 #endif
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 3fb1f40..dc3e050 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -185,6 +185,9 @@ struct wm8994_pdata {
         unsigned int jd_scthr:2;
         unsigned int jd_thr:2;
 
+	/* Configure WM1811 jack detection for use with external capacitor */
+	unsigned int jd_ext_cap:1;
+
 	/* WM8958 microphone bias configuration */
 	int micbias[2];
 
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 05ed282..855c337 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -8,7 +8,6 @@
 typedef struct page *new_page_t(struct page *, unsigned long private, int **);
 
 #ifdef CONFIG_MIGRATION
-#define PAGE_MIGRATION 1
 
 extern void putback_lru_pages(struct list_head *l);
 extern int migrate_page(struct address_space *,
@@ -32,7 +31,6 @@ extern void migrate_page_copy(struct page *newpage, struct page *page);
 extern int migrate_huge_page_move_mapping(struct address_space *mapping,
 				  struct page *newpage, struct page *page);
 #else
-#define PAGE_MIGRATION 0
 
 static inline void putback_lru_pages(struct list_head *l) {}
 static inline int migrate_pages(struct list_head *l, new_page_t x,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 17b27cd..ee3ebc1 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1058,19 +1058,20 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
 /*
  * per-process(per-mm_struct) statistics.
  */
-static inline void set_mm_counter(struct mm_struct *mm, int member, long value)
-{
-	atomic_long_set(&mm->rss_stat.count[member], value);
-}
-
-#if defined(SPLIT_RSS_COUNTING)
-unsigned long get_mm_counter(struct mm_struct *mm, int member);
-#else
 static inline unsigned long get_mm_counter(struct mm_struct *mm, int member)
 {
-	return atomic_long_read(&mm->rss_stat.count[member]);
-}
+	long val = atomic_long_read(&mm->rss_stat.count[member]);
+
+#ifdef SPLIT_RSS_COUNTING
+	/*
+	 * counter is updated in asynchronous manner and may go to minus.
+	 * But it's never be expected number for users.
+	 */
+	if (val < 0)
+		val = 0;
 #endif
+	return (unsigned long)val;
+}
 
 static inline void add_mm_counter(struct mm_struct *mm, int member, long value)
 {
@@ -1598,9 +1599,9 @@ void vmemmap_populate_print_last(void);
 
 enum mf_flags {
 	MF_COUNT_INCREASED = 1 << 0,
+	MF_ACTION_REQUIRED = 1 << 1,
 };
-extern void memory_failure(unsigned long pfn, int trapno);
-extern int __memory_failure(unsigned long pfn, int trapno, int flags);
+extern int memory_failure(unsigned long pfn, int trapno, int flags);
 extern void memory_failure_queue(unsigned long pfn, int trapno, int flags);
 extern int unpoison_memory(unsigned long pfn);
 extern int sysctl_memory_failure_early_kill;
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 3cc3062..81a56df 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -12,6 +12,7 @@
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/page-debug-flags.h>
+#include <linux/uprobes.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
 
@@ -354,6 +355,7 @@ struct mm_struct {
 	unsigned int faultstamp;
 	unsigned int token_priority;
 	unsigned int last_interval;
+	atomic_t active_swap_token;
 
 	unsigned long flags; /* Must use atomic bitops to access the bits */
 
@@ -388,6 +390,10 @@ struct mm_struct {
 #ifdef CONFIG_CPUMASK_OFFSTACK
 	struct cpumask cpumask_allocation;
 #endif
+#ifdef CONFIG_UPROBES
+	atomic_t mm_uprobes_count;
+	struct uprobes_xol_area *uprobes_xol_area;
+#endif
 };
 
 static inline void mm_init_cpumask(struct mm_struct *mm)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 19a41d1..1a1ca71 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -71,6 +71,8 @@ struct mmc_ext_csd {
 	bool			hpi_en;			/* HPI enablebit */
 	bool			hpi;			/* HPI support bit */
 	unsigned int		hpi_cmd;		/* cmd used as HPI */
+	unsigned int            data_sector_size;       /* 512 bytes or 4KB */
+	unsigned int            data_tag_unit_size;     /* DATA TAG UNIT size */
 	unsigned int		boot_ro_lock;		/* ro lock support */
 	bool			boot_ro_lockable;
 	u8			raw_partition_support;	/* 160 */
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index aae5d1f..8f66e28 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -76,7 +76,7 @@ struct mmc_data;
  * @num_slots: Number of slots available.
  * @verid: Denote Version ID.
  * @data_offset: Set the offset of DATA register according to VERID.
- * @pdev: Platform device associated with the MMC controller.
+ * @dev: Device associated with the MMC controller.
  * @pdata: Platform data associated with the MMC controller.
  * @slot: Slots sharing this MMC controller.
  * @fifo_depth: depth of FIFO.
@@ -87,6 +87,8 @@ struct mmc_data;
  * @push_data: Pointer to FIFO push function.
  * @pull_data: Pointer to FIFO pull function.
  * @quirks: Set of quirks that apply to specific versions of the IP.
+ * @irq_flags: The flags to be passed to request_irq.
+ * @irq: The irq value to be passed to request_irq.
  *
  * Locking
  * =======
@@ -153,7 +155,7 @@ struct dw_mci {
 	u32			fifoth_val;
 	u16			verid;
 	u16			data_offset;
-	struct platform_device	*pdev;
+	struct device		dev;
 	struct dw_mci_board	*pdata;
 	struct dw_mci_slot	*slot[MAX_MCI_SLOTS];
 
@@ -174,6 +176,8 @@ struct dw_mci {
 	u32			quirks;
 
 	struct regulator	*vmmc;	/* Power regulator */
+	unsigned long		irq_flags; /* IRQ flags */
+	unsigned int		irq;
 };
 
 /* DMA ops for Internal/External DMAC interface */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index fb9f6e1..b822a2c 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -274,6 +274,7 @@ struct _mmc_csd {
 #define EXT_CSD_FLUSH_CACHE		32      /* W */
 #define EXT_CSD_CACHE_CTRL		33      /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION	34	/* R/W */
+#define EXT_CSD_DATA_SECTOR_SIZE	61	/* R */
 #define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
 #define EXT_CSD_PARTITION_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITION_SUPPORT	160	/* RO */
@@ -315,6 +316,8 @@ struct _mmc_csd {
 #define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
 #define EXT_CSD_CACHE_SIZE		249	/* RO, 4 bytes */
+#define EXT_CSD_TAG_UNIT_SIZE		498	/* RO */
+#define EXT_CSD_DATA_TAG_SUPPORT	499	/* RO */
 #define EXT_CSD_HPI_FEATURES		503	/* RO */
 
 /*
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 650ba2f..f10a54c 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -365,6 +365,7 @@ struct zone {
 	 */
 	unsigned int		compact_considered;
 	unsigned int		compact_defer_shift;
+	int			compact_order_failed;
 #endif
 
 	ZONE_PADDING(_pad1_)
@@ -795,7 +796,7 @@ static inline int is_dma(struct zone *zone)
 
 /* These two functions are used to setup the per zone pages min values */
 struct ctl_table;
-int min_free_kbytes_sysctl_handler(struct ctl_table *, int,
+int free_kbytes_sysctl_handler(struct ctl_table *, int,
 					void __user *, size_t *, loff_t *);
 extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
 int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int,
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 83ac071..501da4c 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -414,6 +414,15 @@ struct hv_vmbus_device_id {
 			__attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+/* rpmsg */
+
+#define RPMSG_NAME_SIZE			32
+#define RPMSG_DEVICE_MODALIAS_FMT	"rpmsg:%s"
+
+struct rpmsg_device_id {
+	char name[RPMSG_NAME_SIZE];
+};
+
 /* i2c */
 
 #define I2C_NAME_SIZE	20
@@ -560,4 +569,25 @@ struct amba_id {
 #endif
 };
 
+/*
+ * Match x86 CPUs for CPU specific drivers.
+ * See documentation of "x86_match_cpu" for details.
+ */
+
+struct x86_cpu_id {
+	__u16 vendor;
+	__u16 family;
+	__u16 model;
+	__u16 feature;	/* bit index */
+	kernel_ulong_t driver_data;
+};
+
+#define X86_FEATURE_MATCH(x) \
+	{ X86_VENDOR_ANY, X86_FAMILY_ANY, X86_MODEL_ANY, x }
+
+#define X86_VENDOR_ANY 0xffff
+#define X86_FAMILY_ANY 0
+#define X86_MODEL_ANY  0
+#define X86_FEATURE_ANY 0	/* Same as FPU, you can't test for that */
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/modem_shm/Kbuild b/include/linux/modem_shm/Kbuild
new file mode 100644
index 0000000..165b66c
--- /dev/null
+++ b/include/linux/modem_shm/Kbuild
@@ -0,0 +1 @@
+header-y += modem_shm_netlink.h
diff --git a/include/linux/modem_shm/modem_shm_netlink.h b/include/linux/modem_shm/modem_shm_netlink.h
new file mode 100644
index 0000000..fedeab5
--- /dev/null
+++ b/include/linux/modem_shm/modem_shm_netlink.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef SHM_NL_H_
+#define SHM_NL_H_
+
+#define SHM_PROTO_VERSION 1
+#define SHM_PROTO_SUB_VERSION 0
+#define SHM_NETLINK_VERSION 1
+/**
+ * enum SHM_COMMANDS - Attributes used for configuring SHM device.
+ *
+ * @SHM_C_ADD_STREAM_CHANNEL: Adds a Stream Channel.
+ * This will cause an instance of SHM-CHR to be created.
+ * @SHM_C_ADD_PACKET_CHANNEL: Adds a Packet Channel.
+ * This will cause an instance of CAIF-SHM to be created.
+ * @SHM_C_COMMIT: formats and write Channel configuration data to
+ *	Shared Memory.
+ * @SHM_C_SET_ADDR: Writes the TOC address to GENO register.
+ * @SHM_C_REGISTER:  Initiates registration of the channel devices.
+ *	This will cause shm - character devices or
+ *	CAIF network instances to be created.
+ * @SHM_C_RESET:  Reset the configuration data and removes the
+ *	platform devices and their associated channel configuration.
+ *	ipc_ready and caif_ready is set to false.
+ *
+ * A normal sequence of events is: [SHM_C_RESET], [SHM_C_ADD_X_CHANNEL],
+ *	SHM_C_COMMIT, SHM_C_REGISTER, SHM_C_SET_ADDR.
+ */
+enum SHM_COMMANDS {
+	SHM_C_ADD_STREAM_CHANNEL = 1,
+	SHM_C_ADD_PACKET_CHANNEL,
+	SHM_C_RESET,
+	SHM_C_SET_ADDR,
+	SHM_C_COMMIT,
+	SHM_C_REGISTER,
+	__SHM_C_VERIFY,
+	__SHM_C_MAX
+};
+
+/**
+ * enum SHM_ATTRIBUTES - Attributes used for configuring SHM device.
+ * @SHM_A_VERSION: Version of SHM netlink protocol. Type NLA_U8
+ * @SHM_A_SUB_VERSION: Sub-version of SHM netlink protocol. Type NLA_U8
+ * @SHM_A_NAME: Name of the channel, max 15 characters. Type NLA_NUL_STRING
+ * @SHM_A_EXCL_GROUP: Devices may be part of a group. Devices from the
+ *	same group are allowed to be open simultaneously,
+ *	but devices from different groups cannot be opened
+ *	at the same time. Type NLA_U8.
+ * @SHM_A_RX_CHANNEL: The RX direction attributes. Type NLA_NESTED.
+ *	Each channel may contain the attributes - SHM_A_CHANNEL_SIZE,
+ *	SHM_A_CHANNEL_BUFFERS, SHM_A_ALIGNMENT, SHM_A_MTU.
+ *
+ * @SHM_A_TX_CHANNEL: The TX direction attributes. Type NLA_NESTED.
+ *
+ * @SHM_A_CHANNEL_SIZE: Size of the data area for a channel. Specified
+ *	for RX, TX. Type NLA_U32,
+ * @SHM_A_CHANNEL_BUFFERS: Numer of buffers for a packet channel.
+ *	This attribute is only used for packet channels.  Specified for RX, TX.
+ *	Type NLA_U32,
+ * @SHM_A_ALIGNMENT: Alignment for each packet in a buffer. This attribute
+ *	 is only used for packet channels.  Specified for RX, TX.Type NLA_U8,
+ * @SHM_A_MTU: Maximum Transfer Unit for packets in a buffer.
+ *	This is only appplicable for packet channels.
+ *	Specified for RX, TX.Type NLA_U16,
+ * @SHM_A_PACKETS: Maximum number of packets in a buffer. Type NLA_U8
+ * @SHM_A_PRIORITY: Priority of the channel, legal range is 0-7 where
+ *	0 is lowest priority. Type NLA_U8.
+ * @SHM_A_LATENCY: Latency for channel, value:0 means low latency
+ *	 and low bandwidth,
+ *	 value 1 means high latency and high bandwidth. Type NLA_U8.
+ */
+enum SHM_ATTRIBUTES {
+	__SHM_A_FLAGS = 1,		/* Test flags: NLA_U32 */
+	SHM_A_VERSION,
+	SHM_A_SUB_VERSION,
+	SHM_A_NAME,
+	SHM_A_EXCL_GROUP,
+	SHM_A_RX_CHANNEL,
+	SHM_A_TX_CHANNEL,
+	SHM_A_CHANNEL_SIZE,
+	SHM_A_CHANNEL_BUFFERS,
+	SHM_A_ALIGNMENT,
+	SHM_A_MTU,
+	SHM_A_PACKETS,
+	SHM_A_PRIORITY,
+	SHM_A_LATENCY,
+	__SHM_A_MAX,
+};
+#define SHM_A_MAX (__SHM_A_MAX - 1)
+
+#endif /* SHM_NL_H_ */
diff --git a/include/linux/modem_shm/shm_dev.h b/include/linux/modem_shm/shm_dev.h
new file mode 100644
index 0000000..a90676f
--- /dev/null
+++ b/include/linux/modem_shm/shm_dev.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Author: Sjur Brændeland / sjur.brandeland@stericsson.com
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef SHM_DEV_H_
+#define SHM_DEV_H_
+
+#include <linux/device.h>
+#include <linux/firmware.h>
+
+#define SHM_NAMESZ 16
+#define SHM_MAX_CHANNELS 7
+#define SHM_PACKET_MODE 0x1
+#define SHM_STREAM_MODE 0x2
+#define SHM_LOOP_MODE	 0x4
+#define SHM_PAIR_MODE	 0x8
+#define SHM_MODE_MASK	 0x3
+
+/**
+ * struct shm_udchannel - Unidirectional channel for shm driver.
+ *
+ * @addr: Base address of the channel, address must be
+ *		  a kernel logical address.
+ * @buffers: The number of buffers in the channel.
+ * @ch_size: The size of data area for the channel in one direction.
+ * @xfer_bit: GENI/O bit used when sending data (write pointer move)
+ * @xfer_done_bit: GENI/O bit used to indicate avilable buffers
+ *	(read pointer move).
+ * @alignment: Alignment used in payload protocol.
+ * @mtu: Maxium Transfer Unit used for packet in a buffer (Packet mode).
+ * @packets: Maxium number of packets in a buffer (Packet mode).
+ * @state: State of the device 0 - Closed, 1 - Open
+ * @read: Specify the read index for a channel. In packed mode
+ *	this index will at any time refer to the next buffer available for read.
+ *	In stream mode, this will be the read index in the ring-buffer.
+ * @write: Specify the write index for a channel. In packed mode
+ *	this index will at any time refer to the next buffer available for
+ *	write. In stream mode, this will be the write index in the ring-buffer.
+ * @buf_size: In packet mode, this array contains the size of each buffer.
+ *	In stream mode this is unused.
+ *
+ * This external shared memory channel configuration is exported from the
+ * shm device. It gives the shm driver the necessary information for
+ * running the shared memory protocol between modem and host.
+ *
+ * Note that two instances of this configuration is needed in order to run a
+ * bi-directional channel.
+ */
+struct shm_udchannel {
+	void *addr;
+	u32 buffers;
+	u32 ch_size;
+	u8 xfer_done_bit;
+	u8 xfer_bit;
+	u32 mtu;
+	u32 alignment;
+	u32 packets;
+	__le32 *state;
+	__le32 *read;
+	__le32 *write;
+	__le32 *buf_size;
+/* private: */
+	struct kobject kobj; /* kobj must be located at the end */
+};
+
+/**
+ * struct shm_channel - Channel definition for shm driver.
+ * @rx: Configuration for RX channel
+ * @tx: Configuration for TX channel
+ * @excl_group: Only channels with the same group ID can be open simultaneously.
+ * @mode: Configuring type of channel PACKET(1), STREAM(2)
+ * @name: Name of interface.
+ * @priority: Priority of the channel.
+ * @latency: Latency of the channel.
+ */
+struct shm_channel {
+	struct shm_udchannel rx, tx;
+	u32 excl_group;
+	u32 mode;
+	char name[SHM_NAMESZ];
+	u32 priority;
+	u32 latency;
+};
+
+#define SHM_OPEN   1
+#define SHM_CLOSED 0
+
+enum shm_dev_state {
+	SHM_DEV_CLOSED = 0,
+	SHM_DEV_OPENING,
+	SHM_DEV_OPEN,
+	SHM_DEV_ACTIVE,
+};
+
+/**
+ * struct shm_dev - Device definition for shm device.
+ *
+ * @dev: Reference to device
+ * @cfg: Configuration for the Channel
+ * @state: State of the device: Closed - No user space client is using it,
+ *	Open - Open but no payload queued, Active - Payload queued on device.
+ *
+ * @open: The driver calls open() when channel is taken into use.
+ *	This function will fail if channel configuration is inconsistent,
+ *	or upon resource conflicts with other channels.
+ *
+ * @open_cb: The device calls open_cb() when is ready for use.
+ *
+ * @close: Called by the driver when a channel is no longer in use.
+ *
+ * @close_cb: The device calls close_cb() to notify about remote side closure.
+ *
+ * @ipc_tx_release_cb: This callback is triggered by the modem when a
+ *	transmit operation has completed and the buffer can be reused.
+ *	This function must be set by the driver upon device registration.
+ *	The "more" flag is set if ipc_rx_cb() call is coming immediately
+ *	after this call to ipc_tx_release_cb().
+ *
+ * @ipc_rx_cb: The driver gets this callback when the modem sends a buffer
+ *	from the modem. The driver must call ipc_rx_release()
+ *	to make the buffer available again when the received buffer has been
+ *	processed.
+ *	This function pointer must be set by the driver upon device
+ *	registration.
+ *
+ * @ipc_rx_release: Called by the driver when a RX operation has completed
+ *	and that the rx-buffer is released.
+ *
+ * @ipc_tx: Called by the driver when a TX buffer shall be sent to the modem.
+ *
+ * @driver_data: pointer to driver specific data.
+ *
+ * When communicating between two systems (e.g. modem and host),
+ * external shared memory can bused (e.g. C2C or DPRAM).
+ *
+ * This structure is used by the shm device representing the
+ * External Shared Memory.
+ *
+ * The this structure contains configuration data for the shm device and
+ * functions pointers for IPC communication between Linux host and modem.
+ * The external shared memory protocol memory e.g. C2C or DPRAM
+ * together is a IPC mechanism for transporting small commands such as
+ * Mailbox or GENI/O.
+ *
+ * This data structure is initiated by the shm device, except
+ * for the functions ipc_rx_cb() and ipc_tx_release_cb(). They must be set by
+ * the shm-driver when device is registering.
+ */
+
+struct shm_dev {
+	struct device dev;
+	struct shm_channel cfg;
+	enum shm_dev_state state;
+	int (*open)(struct shm_dev *dev);
+	void (*close)(struct shm_dev *dev);
+	int (*ipc_rx_release)(struct shm_dev *dev, bool more);
+	int (*ipc_tx)(struct shm_dev *dev);
+	int (*open_cb)(void *drv);
+	void (*close_cb)(void *drv);
+	int (*ipc_rx_cb)(void *drv);
+	int (*ipc_tx_release_cb)(void *drv);
+	void *driver_data;
+	/* private: */
+	struct list_head node;
+	void *priv;
+};
+
+/**
+ * shm_driver - operations for a shm I/O driver
+ * @driver: underlying device driver (populate name and owner).
+ * @mode: Type of channel for driver: PACKET(1), STREAM(2)
+ * @probe: the function to call when a device is found.  Returns 0 or -errno.
+ * @remove: the function when a device is removed.
+ */
+struct shm_driver {
+	struct device_driver driver;
+	u32 mode;
+	int (*probe)(struct shm_dev *dev);
+	void (*remove)(struct shm_dev *dev);
+};
+
+/**
+ * modem_shm_register_driver() - Register an shm driver.
+ * @driver: SHM driver instance
+ */
+int modem_shm_register_driver(struct shm_driver *driver);
+
+/**
+ * modem_shm_unregister_driver() - Unregister an shm driver.
+ * @driver: SHM driver instance
+ */
+void modem_shm_unregister_driver(struct shm_driver *driver);
+
+/**
+ * modem_shm_register_device() - Register an shm device.
+ * @dev: SHM device instance
+ */
+int modem_shm_register_device(struct shm_dev *dev);
+
+/**
+ * modem_shm_unregister_device() - Unregister an shm device.
+ * @dev: SHM device instance
+ */
+void modem_shm_unregister_device(struct shm_dev *dev);
+
+/**
+ * modem_shm_foreach_dev - device iterator.
+ * @data: data for the callback.
+ * @fn: function to be called for each device.
+ *
+ * Iterate over shm bus's list of devices, and call @fn for each,
+ * passing it @data.
+ */
+void modem_shm_foreach_dev(void fn(struct shm_dev*, void *data), void *data);
+
+/**
+ * modem_shm_register_devices() - Register an array of shm devices.
+ * @devs: SHM devices to register
+ * @devices: Number of devices in array
+ */
+int modem_shm_register_devices(struct shm_channel *channel[], int channels);
+
+/**
+ * modem_shm_reset() - SHM unregister and remove all SHM devices
+ */
+void modem_shm_reset(void);
+
+/**
+ * genio_ipc_ready_cb() - Callback for CAIF_READY notification.
+ */
+void genio_ipc_ready_cb(void);
+
+/**
+ * modem_shm_request_firmware() - Request firmware from user-space.
+ * @context: Context returned in cb() function.
+ * @img_name: Name of the firmware image to load.
+ * @fw_avilable: Callback function called when firmware is avilable.
+ */
+int modem_shm_request_firmware(void *context, struct module *mod,
+		const char *img_name,
+		void (*fw_avilable)(const struct firmware *fw, void *ctx));
+
+#endif
diff --git a/include/linux/module.h b/include/linux/module.h
index 4598bf0..fbcafe2 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -21,8 +21,6 @@
 #include <linux/percpu.h>
 #include <asm/module.h>
 
-#include <trace/events/module.h>
-
 /* Not Yet Implemented */
 #define MODULE_SUPPORTED_DEVICE(name)
 
@@ -452,33 +450,11 @@ void symbol_put_addr(void *addr);
 
 /* Sometimes we know we already have a refcount, and it's easier not
    to handle the error case (which only happens with rmmod --wait). */
-static inline void __module_get(struct module *module)
-{
-	if (module) {
-		preempt_disable();
-		__this_cpu_inc(module->refptr->incs);
-		trace_module_get(module, _THIS_IP_);
-		preempt_enable();
-	}
-}
-
-static inline int try_module_get(struct module *module)
-{
-	int ret = 1;
-
-	if (module) {
-		preempt_disable();
+extern void __module_get(struct module *module);
 
-		if (likely(module_is_live(module))) {
-			__this_cpu_inc(module->refptr->incs);
-			trace_module_get(module, _THIS_IP_);
-		} else
-			ret = 0;
-
-		preempt_enable();
-	}
-	return ret;
-}
+/* This is the Right Way to get a module: if it fails, it's being removed,
+ * so pretend it's not there. */
+extern bool try_module_get(struct module *module);
 
 extern void module_put(struct module *module);
 
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index c47f4d6..ea36486 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -47,14 +47,11 @@ struct kernel_param_ops {
 	void (*free)(void *arg);
 };
 
-/* Flag bits for kernel_param.flags */
-#define KPARAM_ISBOOL		2
-
 struct kernel_param {
 	const char *name;
 	const struct kernel_param_ops *ops;
 	u16 perm;
-	u16 flags;
+	s16 level;
 	union {
 		void *arg;
 		const struct kparam_string *str;
@@ -131,8 +128,40 @@ struct kparam_array
  * The ops can have NULL set or get functions.
  */
 #define module_param_cb(name, ops, arg, perm)				      \
-	__module_param_call(MODULE_PARAM_PREFIX,			      \
-			    name, ops, arg, __same_type((arg), bool *), perm)
+	__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, 0)
+
+/**
+ * <level>_param_cb - general callback for a module/cmdline parameter
+ *                    to be evaluated before certain initcall level
+ * @name: a valid C identifier which is the parameter name.
+ * @ops: the set & get operations for this parameter.
+ * @perm: visibility in sysfs.
+ *
+ * The ops can have NULL set or get functions.
+ */
+#define __level_param_cb(name, ops, arg, perm, level)			\
+	__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, level)
+
+#define core_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 1)
+
+#define postcore_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 2)
+
+#define arch_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 3)
+
+#define subsys_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 4)
+
+#define fs_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 5)
+
+#define device_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 6)
+
+#define late_param_cb(name, ops, arg, perm)		\
+	__level_param_cb(name, ops, arg, perm, 7)
 
 /* On alpha, ia64 and ppc64 relocations to global data cannot go into
    read-only sections (which is part of respective UNIX ABI on these
@@ -146,7 +175,7 @@ struct kparam_array
 
 /* This is the fundamental function for registering boot/module
    parameters. */
-#define __module_param_call(prefix, name, ops, arg, isbool, perm)	\
+#define __module_param_call(prefix, name, ops, arg, perm, level)	\
 	/* Default value instead of permissions? */			\
 	static int __param_perm_check_##name __attribute__((unused)) =	\
 	BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))	\
@@ -155,8 +184,7 @@ struct kparam_array
 	static struct kernel_param __moduleparam_const __param_##name	\
 	__used								\
     __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
-	= { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0,	\
-	    { arg } }
+	= { __param_str_##name, ops, perm, level, { arg } }
 
 /* Obsolete - use module_param_cb() */
 #define module_param_call(name, set, get, arg, perm)			\
@@ -164,8 +192,7 @@ struct kparam_array
 		 { (void *)set, (void *)get };				\
 	__module_param_call(MODULE_PARAM_PREFIX,			\
 			    name, &__param_ops_##name, arg,		\
-			    __same_type(arg, bool *),			\
-			    (perm) + sizeof(__check_old_set_param(set))*0)
+			    (perm) + sizeof(__check_old_set_param(set))*0, 0)
 
 /* We don't get oldget: it's often a new-style param_get_uint, etc. */
 static inline int
@@ -245,8 +272,7 @@ static inline void __kernel_param_unlock(void)
  */
 #define core_param(name, var, type, perm)				\
 	param_check_##type(name, &(var));				\
-	__module_param_call("", name, &param_ops_##type,		\
-			    &var, __same_type(var, bool), perm)
+	__module_param_call("", name, &param_ops_##type, &var, perm, 0)
 #endif /* !MODULE */
 
 /**
@@ -264,7 +290,7 @@ static inline void __kernel_param_unlock(void)
 		= { len, string };					\
 	__module_param_call(MODULE_PARAM_PREFIX, name,			\
 			    &param_ops_string,				\
-			    .str = &__param_string_##name, 0, perm);	\
+			    .str = &__param_string_##name, perm, 0);	\
 	__MODULE_PARM_TYPE(name, "string")
 
 /**
@@ -292,6 +318,8 @@ extern int parse_args(const char *name,
 		      char *args,
 		      const struct kernel_param *params,
 		      unsigned num,
+		      s16 level_min,
+		      s16 level_max,
 		      int (*unknown)(char *param, char *val));
 
 /* Called by module remove. */
@@ -403,7 +431,7 @@ extern int param_set_bint(const char *val, const struct kernel_param *kp);
 	__module_param_call(MODULE_PARAM_PREFIX, name,			\
 			    &param_array_ops,				\
 			    .arr = &__param_arr_##name,			\
-			    __same_type(array[0], bool), perm);		\
+			    perm, 0);					\
 	__MODULE_PARM_TYPE(name, "array of " #type)
 
 extern struct kernel_param_ops param_array_ops;
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index c4eec22..650ef35 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -112,6 +112,11 @@ struct nand_bbt_descr {
 #define NAND_BBT_USE_FLASH	0x00020000
 /* Do not store flash based bad block table in OOB area; store it in-band */
 #define NAND_BBT_NO_OOB		0x00040000
+/*
+ * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
+ * entire spare area. Must be used with NAND_BBT_USE_FLASH.
+ */
+#define NAND_BBT_NO_OOB_BBM	0x00080000
 
 /*
  * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index 1bbd9f2..ed270bd 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -47,6 +47,7 @@ struct mtd_blktrans_dev {
 	struct request_queue *rq;
 	spinlock_t queue_lock;
 	void *priv;
+	fmode_t file_mode;
 };
 
 struct mtd_blktrans_ops {
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index d43dc25..726c2d1 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -174,52 +174,52 @@ struct mtd_info {
 	 * Do not call via these pointers, use corresponding mtd_*()
 	 * wrappers instead.
 	 */
-	int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
-	int (*point) (struct mtd_info *mtd, loff_t from, size_t len,
-		      size_t *retlen, void **virt, resource_size_t *phys);
-	void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
-	unsigned long (*get_unmapped_area) (struct mtd_info *mtd,
-					    unsigned long len,
-					    unsigned long offset,
-					    unsigned long flags);
-	int (*read) (struct mtd_info *mtd, loff_t from, size_t len,
-		     size_t *retlen, u_char *buf);
-	int (*write) (struct mtd_info *mtd, loff_t to, size_t len,
-		      size_t *retlen, const u_char *buf);
-	int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
-			    size_t *retlen, const u_char *buf);
-	int (*read_oob) (struct mtd_info *mtd, loff_t from,
-			 struct mtd_oob_ops *ops);
-	int (*write_oob) (struct mtd_info *mtd, loff_t to,
+	int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
+	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
+		       size_t *retlen, void **virt, resource_size_t *phys);
+	int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
+	unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
+					     unsigned long len,
+					     unsigned long offset,
+					     unsigned long flags);
+	int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
+		      size_t *retlen, u_char *buf);
+	int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
+		       size_t *retlen, const u_char *buf);
+	int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
+			     size_t *retlen, const u_char *buf);
+	int (*_read_oob) (struct mtd_info *mtd, loff_t from,
 			  struct mtd_oob_ops *ops);
-	int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
-				   size_t len);
-	int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
-				   size_t len, size_t *retlen, u_char *buf);
-	int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
-				   size_t len);
-	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
-				   size_t len, size_t *retlen, u_char *buf);
-	int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len,
-				    size_t *retlen, u_char *buf);
-	int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
-				   size_t len);
-	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs,
+	int (*_write_oob) (struct mtd_info *mtd, loff_t to,
+			   struct mtd_oob_ops *ops);
+	int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
+				    size_t len);
+	int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
+				    size_t len, size_t *retlen, u_char *buf);
+	int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
+				    size_t len);
+	int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
+				    size_t len, size_t *retlen, u_char *buf);
+	int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
+				     size_t len, size_t *retlen, u_char *buf);
+	int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
+				    size_t len);
+	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
 			unsigned long count, loff_t to, size_t *retlen);
-	void (*sync) (struct mtd_info *mtd);
-	int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
-	int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
-	int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
-	int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
-	int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
-	int (*suspend) (struct mtd_info *mtd);
-	void (*resume) (struct mtd_info *mtd);
+	void (*_sync) (struct mtd_info *mtd);
+	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+	int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
+	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
+	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
+	int (*_suspend) (struct mtd_info *mtd);
+	void (*_resume) (struct mtd_info *mtd);
 	/*
 	 * If the driver is something smart, like UBI, it may need to maintain
 	 * its own reference counting. The below functions are only for driver.
 	 */
-	int (*get_device) (struct mtd_info *mtd);
-	void (*put_device) (struct mtd_info *mtd);
+	int (*_get_device) (struct mtd_info *mtd);
+	void (*_put_device) (struct mtd_info *mtd);
 
 	/* Backing device capabilities for this device
 	 * - provides mmap capabilities
@@ -240,214 +240,75 @@ struct mtd_info {
 	int usecount;
 };
 
-/*
- * Erase is an asynchronous operation.  Device drivers are supposed
- * to call instr->callback() whenever the operation completes, even
- * if it completes with a failure.
- * Callers are supposed to pass a callback function and wait for it
- * to be called before writing to the block.
- */
-static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-	return mtd->erase(mtd, instr);
-}
-
-/*
- * This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
- */
-static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len,
-			    size_t *retlen, void **virt, resource_size_t *phys)
-{
-	*retlen = 0;
-	if (!mtd->point)
-		return -EOPNOTSUPP;
-	return mtd->point(mtd, from, len, retlen, virt, phys);
-}
-
-/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
-static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
-{
-	return mtd->unpoint(mtd, from, len);
-}
-
-/*
- * Allow NOMMU mmap() to directly map the device (if not NULL)
- * - return the address to which the offset maps
- * - return -ENOSYS to indicate refusal to do the mapping
- */
-static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd,
-						  unsigned long len,
-						  unsigned long offset,
-						  unsigned long flags)
-{
-	if (!mtd->get_unmapped_area)
-		return -EOPNOTSUPP;
-	return mtd->get_unmapped_area(mtd, len, offset, flags);
-}
-
-static inline int mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
-			   size_t *retlen, u_char *buf)
-{
-	return mtd->read(mtd, from, len, retlen, buf);
-}
-
-static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
-			    size_t *retlen, const u_char *buf)
-{
-	*retlen = 0;
-	if (!mtd->write)
-		return -EROFS;
-	return mtd->write(mtd, to, len, retlen, buf);
-}
-
-/*
- * In blackbox flight recorder like scenarios we want to make successful writes
- * in interrupt context. panic_write() is only intended to be called when its
- * known the kernel is about to panic and we need the write to succeed. Since
- * the kernel is not going to be running for much longer, this function can
- * break locks and delay to ensure the write succeeds (but not sleep).
- */
-static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
-				  size_t *retlen, const u_char *buf)
-{
-	*retlen = 0;
-	if (!mtd->panic_write)
-		return -EOPNOTSUPP;
-	return mtd->panic_write(mtd, to, len, retlen, buf);
-}
+int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
+int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+	      void **virt, resource_size_t *phys);
+int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
+unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
+				    unsigned long offset, unsigned long flags);
+int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
+	     u_char *buf);
+int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+	      const u_char *buf);
+int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
+		    const u_char *buf);
 
 static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,
 			       struct mtd_oob_ops *ops)
 {
 	ops->retlen = ops->oobretlen = 0;
-	if (!mtd->read_oob)
+	if (!mtd->_read_oob)
 		return -EOPNOTSUPP;
-	return mtd->read_oob(mtd, from, ops);
+	return mtd->_read_oob(mtd, from, ops);
 }
 
 static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
 				struct mtd_oob_ops *ops)
 {
 	ops->retlen = ops->oobretlen = 0;
-	if (!mtd->write_oob)
-		return -EOPNOTSUPP;
-	return mtd->write_oob(mtd, to, ops);
-}
-
-/*
- * Method to access the protection register area, present in some flash
- * devices. The user data is one time programmable but the factory data is read
- * only.
- */
-static inline int mtd_get_fact_prot_info(struct mtd_info *mtd,
-					 struct otp_info *buf, size_t len)
-{
-	if (!mtd->get_fact_prot_info)
+	if (!mtd->_write_oob)
 		return -EOPNOTSUPP;
-	return mtd->get_fact_prot_info(mtd, buf, len);
-}
-
-static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
-					 size_t len, size_t *retlen,
-					 u_char *buf)
-{
-	*retlen = 0;
-	if (!mtd->read_fact_prot_reg)
-		return -EOPNOTSUPP;
-	return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf);
-}
-
-static inline int mtd_get_user_prot_info(struct mtd_info *mtd,
-					 struct otp_info *buf,
-					 size_t len)
-{
-	if (!mtd->get_user_prot_info)
-		return -EOPNOTSUPP;
-	return mtd->get_user_prot_info(mtd, buf, len);
-}
-
-static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
-					 size_t len, size_t *retlen,
-					 u_char *buf)
-{
-	*retlen = 0;
-	if (!mtd->read_user_prot_reg)
-		return -EOPNOTSUPP;
-	return mtd->read_user_prot_reg(mtd, from, len, retlen, buf);
-}
-
-static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to,
-					  size_t len, size_t *retlen,
-					  u_char *buf)
-{
-	*retlen = 0;
-	if (!mtd->write_user_prot_reg)
-		return -EOPNOTSUPP;
-	return mtd->write_user_prot_reg(mtd, to, len, retlen, buf);
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+	return mtd->_write_oob(mtd, to, ops);
 }
 
-static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from,
-					 size_t len)
-{
-	if (!mtd->lock_user_prot_reg)
-		return -EOPNOTSUPP;
-	return mtd->lock_user_prot_reg(mtd, from, len);
-}
+int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+			   size_t len);
+int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+			   size_t *retlen, u_char *buf);
+int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
+			   size_t len);
+int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
+			   size_t *retlen, u_char *buf);
+int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
+			    size_t *retlen, u_char *buf);
+int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
 
 int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
 	       unsigned long count, loff_t to, size_t *retlen);
 
 static inline void mtd_sync(struct mtd_info *mtd)
 {
-	if (mtd->sync)
-		mtd->sync(mtd);
-}
-
-/* Chip-supported device locking */
-static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-{
-	if (!mtd->lock)
-		return -EOPNOTSUPP;
-	return mtd->lock(mtd, ofs, len);
+	if (mtd->_sync)
+		mtd->_sync(mtd);
 }
 
-static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-{
-	if (!mtd->unlock)
-		return -EOPNOTSUPP;
-	return mtd->unlock(mtd, ofs, len);
-}
-
-static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
-{
-	if (!mtd->is_locked)
-		return -EOPNOTSUPP;
-	return mtd->is_locked(mtd, ofs, len);
-}
+int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
+int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
 
 static inline int mtd_suspend(struct mtd_info *mtd)
 {
-	return mtd->suspend ? mtd->suspend(mtd) : 0;
+	return mtd->_suspend ? mtd->_suspend(mtd) : 0;
 }
 
 static inline void mtd_resume(struct mtd_info *mtd)
 {
-	if (mtd->resume)
-		mtd->resume(mtd);
-}
-
-static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
-{
-	if (!mtd->block_isbad)
-		return 0;
-	return mtd->block_isbad(mtd, ofs);
-}
-
-static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
-{
-	if (!mtd->block_markbad)
-		return -EOPNOTSUPP;
-	return mtd->block_markbad(mtd, ofs);
+	if (mtd->_resume)
+		mtd->_resume(mtd);
 }
 
 static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
@@ -482,12 +343,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
 
 static inline int mtd_has_oob(const struct mtd_info *mtd)
 {
-	return mtd->read_oob && mtd->write_oob;
+	return mtd->_read_oob && mtd->_write_oob;
 }
 
 static inline int mtd_can_have_bb(const struct mtd_info *mtd)
 {
-	return !!mtd->block_isbad;
+	return !!mtd->_block_isbad;
 }
 
 	/* Kernel-side ioctl definitions */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 63b5a8b..609868f 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -448,8 +448,9 @@ struct nand_buffers {
  *			will be copied to the appropriate nand_bbt_descr's.
  * @badblockpos:	[INTERN] position of the bad block marker in the oob
  *			area.
- * @badblockbits:	[INTERN] number of bits to left-shift the bad block
- *			number
+ * @badblockbits:	[INTERN] minimum number of set bits in a good block's
+ *			bad block marker position; i.e., BBM == 11110111b is
+ *			not bad when badblockbits == 7
  * @cellinfo:		[INTERN] MLC/multichip data from chip ident
  * @numchips:		[INTERN] number of physical chips
  * @chipsize:		[INTERN] the size of one chip for multichip arrays
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h
deleted file mode 100644
index 27ad40a..0000000
--- a/include/linux/mtd/pmc551.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * PMC551 PCI Mezzanine Ram Device
- *
- * Author:
- *       Mark Ferrell
- *       Copyright 1999,2000 Nortel Networks
- *
- * License:
- *	 As part of this driver was derrived from the slram.c driver it falls
- *	 under the same license, which is GNU General Public License v2
- */
-
-#ifndef __MTD_PMC551_H__
-#define __MTD_PMC551_H__
-
-#include <linux/mtd/mtd.h>
-
-#define PMC551_VERSION \
-       "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
-
-/*
- * Our personal and private information
- */
-struct mypriv {
-        struct pci_dev *dev;
-        u_char *start;
-        u32    base_map0;
-        u32    curr_map0;
-        u32    asize;
-	struct mtd_info *nextpmc551;
-};
-
-/*
- * Function Prototypes
- */
-static int pmc551_erase(struct mtd_info *, struct erase_info *);
-static void pmc551_unpoint(struct mtd_info *, loff_t, size_t);
-static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
-		size_t *retlen, void **virt, resource_size_t *phys);
-static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-
-
-/*
- * Define the PCI ID's if the kernel doesn't define them for us
- */
-#ifndef PCI_VENDOR_ID_V3_SEMI
-#define PCI_VENDOR_ID_V3_SEMI             0x11b0
-#endif
-
-#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC
-#define PCI_DEVICE_ID_V3_SEMI_V370PDC     0x0200
-#endif
-
-
-#define PMC551_PCI_MEM_MAP0	0x50
-#define PMC551_PCI_MEM_MAP1	0x54
-#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK	0x3ff00000
-#define PMC551_PCI_MEM_MAP_APERTURE_MASK	0x000000f0
-#define PMC551_PCI_MEM_MAP_REG_EN		0x00000002
-#define PMC551_PCI_MEM_MAP_ENABLE		0x00000001
-
-#define PMC551_SDRAM_MA		0x60
-#define PMC551_SDRAM_CMD	0x62
-#define PMC551_DRAM_CFG		0x64
-#define PMC551_SYS_CTRL_REG	0x78
-
-#define PMC551_DRAM_BLK0	0x68
-#define PMC551_DRAM_BLK1	0x6c
-#define PMC551_DRAM_BLK2	0x70
-#define PMC551_DRAM_BLK3	0x74
-#define PMC551_DRAM_BLK_GET_SIZE(x) (524288<<((x>>4)&0x0f))
-#define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12))
-#define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8))
-
-
-#endif /* __MTD_PMC551_H__ */
-
diff --git a/include/linux/mtd/spear_smi.h b/include/linux/mtd/spear_smi.h
new file mode 100644
index 0000000..a2ed4be
--- /dev/null
+++ b/include/linux/mtd/spear_smi.h
@@ -0,0 +1,62 @@
+/*
+ * include/linux/mtd/spear_smi.h
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim <shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MTD_SPEAR_SMI_H
+#define __MTD_SPEAR_SMI_H
+
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+
+/* macro to define partitions for flash devices */
+#define DEFINE_PARTS(n, of, s)		\
+{					\
+	.name = n,			\
+	.offset = of,			\
+	.size = s,			\
+}
+
+/**
+ * struct spear_smi_flash_info - platform structure for passing flash
+ * information
+ *
+ * name: name of the serial nor flash for identification
+ * mem_base: the memory base on which the flash is mapped
+ * size: size of the flash in bytes
+ * partitions: parition details
+ * nr_partitions: number of partitions
+ * fast_mode: whether flash supports fast mode
+ */
+
+struct spear_smi_flash_info {
+	char *name;
+	unsigned long mem_base;
+	unsigned long size;
+	struct mtd_partition *partitions;
+	int nr_partitions;
+	u8 fast_mode;
+};
+
+/**
+ * struct spear_smi_plat_data - platform structure for configuring smi
+ *
+ * clk_rate: clk rate at which SMI must operate
+ * num_flashes: number of flashes present on board
+ * board_flash_info: specific details of each flash present on board
+ */
+struct spear_smi_plat_data {
+	unsigned long clk_rate;
+	int num_flashes;
+	struct spear_smi_flash_info *board_flash_info;
+};
+
+#endif /* __MTD_SPEAR_SMI_H */
diff --git a/include/linux/net.h b/include/linux/net.h
index b299230..be60c7f 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -206,6 +206,7 @@ struct proto_ops {
 				      int offset, size_t size, int flags);
 	ssize_t 	(*splice_read)(struct socket *sock,  loff_t *ppos,
 				       struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+	void		(*set_peek_off)(struct sock *sk, int val);
 };
 
 #define DECLARE_SOCKADDR(type, dst, src)	\
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0eac07c..f486f63 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2687,14 +2687,14 @@ int netdev_info(const struct net_device *dev, const char *format, ...);
 #define MODULE_ALIAS_NETDEV(device) \
 	MODULE_ALIAS("netdev-" device)
 
-#if defined(DEBUG)
-#define netdev_dbg(__dev, format, args...)			\
-	netdev_printk(KERN_DEBUG, __dev, format, ##args)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
+#if defined(CONFIG_DYNAMIC_DEBUG)
 #define netdev_dbg(__dev, format, args...)			\
 do {								\
 	dynamic_netdev_dbg(__dev, format, ##args);		\
 } while (0)
+#elif defined(DEBUG)
+#define netdev_dbg(__dev, format, args...)			\
+	netdev_printk(KERN_DEBUG, __dev, format, ##args)
 #else
 #define netdev_dbg(__dev, format, args...)			\
 ({								\
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 52e4895..a390e9d 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -237,22 +237,8 @@ struct netlink_notify {
 	int protocol;
 };
 
-static __inline__ struct nlmsghdr *
-__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
-{
-	struct nlmsghdr *nlh;
-	int size = NLMSG_LENGTH(len);
-
-	nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size));
-	nlh->nlmsg_type = type;
-	nlh->nlmsg_len = size;
-	nlh->nlmsg_flags = flags;
-	nlh->nlmsg_pid = pid;
-	nlh->nlmsg_seq = seq;
-	if (!__builtin_constant_p(size) || NLMSG_ALIGN(size) - size != 0)
-		memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
-	return nlh;
-}
+struct nlmsghdr *
+__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags);
 
 #define NLMSG_NEW(skb, pid, seq, type, len, flags) \
 ({	if (unlikely(skb_tailroom(skb) < (int)NLMSG_SPACE(len))) \
diff --git a/include/linux/nfc.h b/include/linux/nfc.h
index 01d4e5d..b4999ab 100644
--- a/include/linux/nfc.h
+++ b/include/linux/nfc.h
@@ -89,6 +89,8 @@ enum nfc_commands {
  * @NFC_ATTR_TARGET_SEL_RES: NFC-A targets extra information (useful if the
  *	target is not NFC-Forum compliant)
  * @NFC_ATTR_TARGET_NFCID1: NFC-A targets identifier, max 10 bytes
+ * @NFC_ATTR_TARGET_SENSB_RES: NFC-B targets extra information, max 12 bytes
+ * @NFC_ATTR_TARGET_SENSF_RES: NFC-F targets extra information, max 18 bytes
  * @NFC_ATTR_COMM_MODE: Passive or active mode
  * @NFC_ATTR_RF_MODE: Initiator or target
  */
@@ -101,6 +103,8 @@ enum nfc_attrs {
 	NFC_ATTR_TARGET_SENS_RES,
 	NFC_ATTR_TARGET_SEL_RES,
 	NFC_ATTR_TARGET_NFCID1,
+	NFC_ATTR_TARGET_SENSB_RES,
+	NFC_ATTR_TARGET_SENSF_RES,
 	NFC_ATTR_COMM_MODE,
 	NFC_ATTR_RF_MODE,
 /* private: internal use only */
@@ -109,6 +113,9 @@ enum nfc_attrs {
 #define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1)
 
 #define NFC_DEVICE_NAME_MAXSIZE 8
+#define NFC_NFCID1_MAXSIZE 10
+#define NFC_SENSB_RES_MAXSIZE 12
+#define NFC_SENSF_RES_MAXSIZE 18
 
 /* NFC protocols */
 #define NFC_PROTO_JEWEL		1
diff --git a/include/linux/nfs.h b/include/linux/nfs.h
index 8c6ee44..6d1fb63 100644
--- a/include/linux/nfs.h
+++ b/include/linux/nfs.h
@@ -29,7 +29,7 @@
 #define NFS_MNT_VERSION		1
 #define NFS_MNT3_VERSION	3
 
-#define NFS_PIPE_DIRNAME "/nfs"
+#define NFS_PIPE_DIRNAME "nfs"
 
 /*
  * NFS stats. The good thing with these values is that NFSv3 errors are
diff --git a/include/linux/nfs_fs_i.h b/include/linux/nfs_fs_i.h
index 8617302..a5c50d9 100644
--- a/include/linux/nfs_fs_i.h
+++ b/include/linux/nfs_fs_i.h
@@ -1,10 +1,6 @@
 #ifndef _NFS_FS_I
 #define _NFS_FS_I
 
-#include <asm/types.h>
-#include <linux/list.h>
-#include <linux/nfs.h>
-
 struct nlm_lockowner;
 
 /*
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index ba4d765..3bf4766 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -3,6 +3,7 @@
 
 #include <linux/list.h>
 #include <linux/backing-dev.h>
+#include <linux/idr.h>
 #include <linux/wait.h>
 #include <linux/nfs_xdr.h>
 #include <linux/sunrpc/xprt.h>
@@ -85,6 +86,7 @@ struct nfs_client {
 #endif
 
 	struct server_scope	*server_scope;	/* from exchange_id */
+	struct net		*net;
 };
 
 /*
@@ -150,9 +152,9 @@ struct nfs_server {
 
 	/* the following fields are protected by nfs_client->cl_lock */
 	struct rb_root		state_owners;
-	struct rb_root		openowner_id;
-	struct rb_root		lockowner_id;
 #endif
+	struct ida		openowner_id;
+	struct ida		lockowner_id;
 	struct list_head	state_owners_lru;
 	struct list_head	layouts;
 	struct list_head	delegations;
@@ -188,21 +190,23 @@ struct nfs_server {
 
 
 /* maximum number of slots to use */
-#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
+#define NFS4_DEF_SLOT_TABLE_SIZE (16U)
+#define NFS4_MAX_SLOT_TABLE (256U)
+#define NFS4_NO_SLOT ((u32)-1)
 
 #if defined(CONFIG_NFS_V4)
 
 /* Sessions */
-#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
+#define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long))
 struct nfs4_slot_table {
 	struct nfs4_slot *slots;		/* seqid per slot */
 	unsigned long   used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
 	spinlock_t	slot_tbl_lock;
 	struct rpc_wait_queue	slot_tbl_waitq;	/* allocators may wait here */
-	int		max_slots;		/* # slots in table */
-	int		highest_used_slotid;	/* sent to server on each SEQ.
+	u32		max_slots;		/* # slots in table */
+	u32		highest_used_slotid;	/* sent to server on each SEQ.
 						 * op for dynamic resizing */
-	int		target_max_slots;	/* Set by CB_RECALL_SLOT as
+	u32		target_max_slots;	/* Set by CB_RECALL_SLOT as
 						 * the new max_slots */
 	struct completion complete;
 };
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index 308c188..7eed201 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -69,36 +69,22 @@ struct nfs_server;
 struct nfs_fattr;
 struct nfs4_string;
 
-#ifdef CONFIG_NFS_USE_NEW_IDMAPPER
-
+#ifdef CONFIG_NFS_V4
 int nfs_idmap_init(void);
 void nfs_idmap_quit(void);
-
-static inline int nfs_idmap_new(struct nfs_client *clp)
-{
-	return 0;
-}
-
-static inline void nfs_idmap_delete(struct nfs_client *clp)
-{
-}
-
-#else /* CONFIG_NFS_USE_NEW_IDMAPPER not set */
-
+#else
 static inline int nfs_idmap_init(void)
 {
 	return 0;
 }
 
 static inline void nfs_idmap_quit(void)
-{
-}
+{}
+#endif
 
 int nfs_idmap_new(struct nfs_client *);
 void nfs_idmap_delete(struct nfs_client *);
 
-#endif /* CONFIG_NFS_USE_NEW_IDMAPPER */
-
 void nfs_fattr_init_names(struct nfs_fattr *fattr,
 		struct nfs4_string *owner_name,
 		struct nfs4_string *group_name);
diff --git a/include/linux/nfs_iostat.h b/include/linux/nfs_iostat.h
index 8866bb3..9dcbbe9 100644
--- a/include/linux/nfs_iostat.h
+++ b/include/linux/nfs_iostat.h
@@ -21,7 +21,7 @@
 #ifndef _LINUX_NFS_IOSTAT
 #define _LINUX_NFS_IOSTAT
 
-#define NFS_IOSTAT_VERS		"1.0"
+#define NFS_IOSTAT_VERS		"1.1"
 
 /*
  * NFS byte counters
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a764cef..1e4a87c 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -2,7 +2,6 @@
 #define _LINUX_NFS_XDR_H
 
 #include <linux/nfsacl.h>
-#include <linux/nfs3.h>
 #include <linux/sunrpc/gss_api.h>
 
 /*
@@ -182,7 +181,7 @@ struct nfs4_slot {
 
 struct nfs4_sequence_args {
 	struct nfs4_session	*sa_session;
-	u8			sa_slotid;
+	u32			sa_slotid;
 	u8			sa_cache_this;
 };
 
@@ -614,7 +613,6 @@ struct nfs_getaclargs {
 	size_t				acl_len;
 	unsigned int			acl_pgbase;
 	struct page **			acl_pages;
-	struct page *			acl_scratch;
 	struct nfs4_sequence_args 	seq_args;
 };
 
@@ -624,6 +622,7 @@ struct nfs_getaclres {
 	size_t				acl_len;
 	size_t				acl_data_offset;
 	int				acl_flags;
+	struct page *			acl_scratch;
 	struct nfs4_sequence_res	seq_res;
 };
 
@@ -1275,11 +1274,11 @@ struct nfs_rpc_ops {
 extern const struct nfs_rpc_ops	nfs_v2_clientops;
 extern const struct nfs_rpc_ops	nfs_v3_clientops;
 extern const struct nfs_rpc_ops	nfs_v4_clientops;
-extern struct rpc_version	nfs_version2;
-extern struct rpc_version	nfs_version3;
-extern struct rpc_version	nfs_version4;
+extern const struct rpc_version nfs_version2;
+extern const struct rpc_version nfs_version3;
+extern const struct rpc_version nfs_version4;
 
-extern struct rpc_version	nfsacl_version3;
-extern struct rpc_program	nfsacl_program;
+extern const struct rpc_version nfsacl_version3;
+extern const struct rpc_program nfsacl_program;
 
 #endif
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 0f5ff37..ad56e21 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1475,6 +1475,7 @@ enum nl80211_attrs {
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
 
 #define NL80211_MAX_SUPP_RATES			32
+#define NL80211_MAX_SUPP_HT_RATES		77
 #define NL80211_MAX_SUPP_REG_RULES		32
 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY	0
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY	16
@@ -2104,6 +2105,9 @@ enum nl80211_mntr_flags {
  * TUs) during which a mesh STA can send only one Action frame containing a
  * PERR element.
  *
+ * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
+ * or forwarding entity (default is TRUE - forwarding entity)
+ *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2128,6 +2132,7 @@ enum nl80211_meshconf_params {
 	NL80211_MESHCONF_HWMP_RANN_INTERVAL,
 	NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
 	NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+	NL80211_MESHCONF_FORWARDING,
 
 	/* keep last */
 	__NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -2401,12 +2406,15 @@ enum nl80211_key_attributes {
  *	in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
  *	1 = 500 kbps) but without the IE length restriction (at most
  *	%NL80211_MAX_SUPP_RATES in a single array).
+ * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ *	in an array of MCS numbers.
  * @__NL80211_TXRATE_AFTER_LAST: internal
  * @NL80211_TXRATE_MAX: highest TX rate attribute
  */
 enum nl80211_tx_rate_attributes {
 	__NL80211_TXRATE_INVALID,
 	NL80211_TXRATE_LEGACY,
+	NL80211_TXRATE_MCS,
 
 	/* keep last */
 	__NL80211_TXRATE_AFTER_LAST,
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index 2d304ef..db50840 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -14,7 +14,7 @@
  * may be used to reset the timeout - for code which intentionally
  * disables interrupts for a long time. This call is stateless.
  */
-#if defined(ARCH_HAS_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
+#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
 #include <asm/nmi.h>
 extern void touch_nmi_watchdog(void);
 #else
diff --git a/include/linux/of.h b/include/linux/of.h
index a75a831..f02d8b2 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -72,19 +72,17 @@ struct of_phandle_args {
 	uint32_t args[MAX_PHANDLE_ARGS];
 };
 
-#if defined(CONFIG_SPARC) || !defined(CONFIG_OF)
+#ifdef CONFIG_OF_DYNAMIC
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+#else /* CONFIG_OF_DYNAMIC */
 /* Dummy ref counting routines - to be implemented later */
 static inline struct device_node *of_node_get(struct device_node *node)
 {
 	return node;
 }
-static inline void of_node_put(struct device_node *node)
-{
-}
-#else
-extern struct device_node *of_node_get(struct device_node *node);
-extern void of_node_put(struct device_node *node);
-#endif
+static inline void of_node_put(struct device_node *node) { }
+#endif /* !CONFIG_OF_DYNAMIC */
 
 #ifdef CONFIG_OF
 
@@ -217,6 +215,9 @@ extern int of_property_read_string(struct device_node *np,
 extern int of_property_read_string_index(struct device_node *np,
 					 const char *propname,
 					 int index, const char **output);
+extern int of_property_match_string(struct device_node *np,
+				    const char *propname,
+				    const char *string);
 extern int of_property_count_strings(struct device_node *np,
 				     const char *propname);
 extern int of_device_is_compatible(const struct device_node *device,
@@ -281,6 +282,14 @@ static inline struct property *of_find_property(const struct device_node *np,
 	return NULL;
 }
 
+static inline struct device_node *of_find_compatible_node(
+						struct device_node *from,
+						const char *type,
+						const char *compat)
+{
+	return NULL;
+}
+
 static inline int of_property_read_u32_array(const struct device_node *np,
 					     const char *propname,
 					     u32 *out_values, size_t sz)
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 3118623..01b925a 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -4,6 +4,7 @@
 #include <linux/errno.h>
 #include <linux/of.h>
 
+#ifdef CONFIG_OF_ADDRESS
 extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
 extern int of_address_to_resource(struct device_node *dev, int index,
 				  struct resource *r);
@@ -25,12 +26,37 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
 #define pci_address_to_pio pci_address_to_pio
 #endif
 
-#ifdef CONFIG_PCI
+#else /* CONFIG_OF_ADDRESS */
+static inline int of_address_to_resource(struct device_node *dev, int index,
+					 struct resource *r)
+{
+	return -EINVAL;
+}
+static inline struct device_node *of_find_matching_node_by_address(
+					struct device_node *from,
+					const struct of_device_id *matches,
+					u64 base_address)
+{
+	return NULL;
+}
+static inline void __iomem *of_iomap(struct device_node *device, int index)
+{
+	return NULL;
+}
+static inline const u32 *of_get_address(struct device_node *dev, int index,
+					u64 *size, unsigned int *flags)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF_ADDRESS */
+
+
+#if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)
 extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
 			       u64 *size, unsigned int *flags);
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
 				      struct resource *r);
-#else /* CONFIG_PCI */
+#else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
 				             struct resource *r)
 {
@@ -42,8 +68,7 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
 {
 	return NULL;
 }
-#endif /* CONFIG_PCI */
-
+#endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
 
 #endif /* __OF_ADDRESS_H */
 
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index ae56384..cbc4214 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -34,7 +34,8 @@ extern void of_device_unregister(struct platform_device *ofdev);
 extern ssize_t of_device_get_modalias(struct device *dev,
 					char *str, ssize_t len);
 
-extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
+extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env);
+extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env);
 
 static inline void of_device_node_put(struct device *dev)
 {
@@ -49,7 +50,10 @@ static inline int of_driver_match_device(struct device *dev,
 	return 0;
 }
 
-static inline int of_device_uevent(struct device *dev,
+static inline void of_device_uevent(struct device *dev,
+			struct kobj_uevent_env *env) { }
+
+static inline int of_device_uevent_modalias(struct device *dev,
 				   struct kobj_uevent_env *env)
 {
 	return -ENODEV;
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index b254052..81733d1 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -50,7 +50,8 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)
 extern int of_get_named_gpio_flags(struct device_node *np,
 		const char *list_name, int index, enum of_gpio_flags *flags);
 
-extern unsigned int of_gpio_count(struct device_node *np);
+extern unsigned int of_gpio_named_count(struct device_node *np,
+					const char* propname);
 
 extern int of_mm_gpiochip_add(struct device_node *np,
 			      struct of_mm_gpio_chip *mm_gc);
@@ -71,7 +72,8 @@ static inline int of_get_named_gpio_flags(struct device_node *np,
 	return -ENOSYS;
 }
 
-static inline unsigned int of_gpio_count(struct device_node *np)
+static inline unsigned int of_gpio_named_count(struct device_node *np,
+					const char* propname)
 {
 	return 0;
 }
@@ -89,6 +91,27 @@ static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
 #endif /* CONFIG_OF_GPIO */
 
 /**
+ * of_gpio_count - Count GPIOs for a device
+ * @np:		device node to count GPIOs for
+ *
+ * The function returns the count of GPIOs specified for a node.
+ *
+ * Note that the empty GPIO specifiers counts too. For example,
+ *
+ * gpios = <0
+ *          &pio1 1 2
+ *          0
+ *          &pio2 3 4>;
+ *
+ * defines four GPIOs (so this function will return 4), two of which
+ * are not specified.
+ */
+static inline unsigned int of_gpio_count(struct device_node *np)
+{
+	return of_gpio_named_count(np, "gpios");
+}
+
+/**
  * of_get_gpio_flags() - Get a GPIO number and flags to use with GPIO API
  * @np:		device node to get GPIO from
  * @index:	index of the GPIO
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h
index a2d1177..1060292 100644
--- a/include/linux/page_cgroup.h
+++ b/include/linux/page_cgroup.h
@@ -4,7 +4,6 @@
 enum {
 	/* flags for mem_cgroup */
 	PCG_LOCK,  /* Lock for pc->mem_cgroup and following bits. */
-	PCG_CACHE, /* charged as cache */
 	PCG_USED, /* this object is in use. */
 	PCG_MIGRATION, /* under page migration */
 	/* flags for mem_cgroup and file and I/O status */
@@ -64,11 +63,6 @@ static inline void ClearPageCgroup##uname(struct page_cgroup *pc)	\
 static inline int TestClearPageCgroup##uname(struct page_cgroup *pc)	\
 	{ return test_and_clear_bit(PCG_##lname, &pc->flags);  }
 
-/* Cache flag is set only once (at allocation) */
-TESTPCGFLAG(Cache, CACHE)
-CLEARPCGFLAG(Cache, CACHE)
-SETPCGFLAG(Cache, CACHE)
-
 TESTPCGFLAG(Used, USED)
 CLEARPCGFLAG(Used, USED)
 SETPCGFLAG(Used, USED)
@@ -85,7 +79,7 @@ static inline void lock_page_cgroup(struct page_cgroup *pc)
 {
 	/*
 	 * Don't take this lock in IRQ context.
-	 * This lock is for pc->mem_cgroup, USED, CACHE, MIGRATION
+	 * This lock is for pc->mem_cgroup, USED, MIGRATION
 	 */
 	bit_spin_lock(PCG_LOCK, &pc->flags);
 }
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a16b1df..70f864e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -299,7 +299,6 @@ struct pci_dev {
 	 */
 	unsigned int	irq;
 	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
-	resource_size_t	fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */
 
 	/* These fields are used by common fixups */
 	unsigned int	transparent:1;	/* Transparent PCI bridge */
@@ -817,6 +816,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq);
 int pcie_get_mps(struct pci_dev *dev);
 int pcie_set_mps(struct pci_dev *dev, int mps);
 int __pci_reset_function(struct pci_dev *dev);
+int __pci_reset_function_locked(struct pci_dev *dev);
 int pci_reset_function(struct pci_dev *dev);
 void pci_update_resource(struct pci_dev *dev, int resno);
 int __must_check pci_assign_resource(struct pci_dev *dev, int i);
@@ -882,6 +882,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev);
 /* Functions for PCI Hotplug drivers to use */
 int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
 #ifdef CONFIG_HOTPLUG
+unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);
 unsigned int pci_rescan_bus(struct pci_bus *bus);
 #endif
 
@@ -891,13 +892,13 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void
 int pci_vpd_truncate(struct pci_dev *dev, size_t size);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
+resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);
 void pci_bus_assign_resources(const struct pci_bus *bus);
 void pci_bus_size_bridges(struct pci_bus *bus);
 int pci_claim_resource(struct pci_dev *, int);
 void pci_assign_unassigned_resources(void);
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge);
 void pdev_enable_device(struct pci_dev *);
-void pdev_sort_resources(struct pci_dev *, struct resource_list *);
 int pci_enable_resources(struct pci_dev *, int mask);
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
 		    int (*)(const struct pci_dev *, u8, u8));
@@ -946,6 +947,19 @@ int __must_check __pci_register_driver(struct pci_driver *, struct module *,
 	__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
 
 void pci_unregister_driver(struct pci_driver *dev);
+
+/**
+ * module_pci_driver() - Helper macro for registering a PCI driver
+ * @__pci_driver: pci_driver struct
+ *
+ * Helper macro for PCI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_pci_driver(__pci_driver) \
+	module_driver(__pci_driver, pci_register_driver, \
+		       pci_unregister_driver)
+
 void pci_remove_behind_bridge(struct pci_dev *dev);
 struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
 int pci_add_dynid(struct pci_driver *drv,
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 32cd1f6..5903f73 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -166,60 +166,6 @@ extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
 	(typeof(type) __percpu *)__alloc_percpu(sizeof(type), __alignof__(type))
 
 /*
- * Optional methods for optimized non-lvalue per-cpu variable access.
- *
- * @var can be a percpu variable or a field of it and its size should
- * equal char, int or long.  percpu_read() evaluates to a lvalue and
- * all others to void.
- *
- * These operations are guaranteed to be atomic.
- * The generic versions disable interrupts.  Archs are
- * encouraged to implement single-instruction alternatives which don't
- * require protection.
- */
-#ifndef percpu_read
-# define percpu_read(var)						\
-  ({									\
-	typeof(var) *pr_ptr__ = &(var);					\
-	typeof(var) pr_ret__;						\
-	pr_ret__ = get_cpu_var(*pr_ptr__);				\
-	put_cpu_var(*pr_ptr__);						\
-	pr_ret__;							\
-  })
-#endif
-
-#define __percpu_generic_to_op(var, val, op)				\
-do {									\
-	typeof(var) *pgto_ptr__ = &(var);				\
-	get_cpu_var(*pgto_ptr__) op val;				\
-	put_cpu_var(*pgto_ptr__);					\
-} while (0)
-
-#ifndef percpu_write
-# define percpu_write(var, val)		__percpu_generic_to_op(var, (val), =)
-#endif
-
-#ifndef percpu_add
-# define percpu_add(var, val)		__percpu_generic_to_op(var, (val), +=)
-#endif
-
-#ifndef percpu_sub
-# define percpu_sub(var, val)		__percpu_generic_to_op(var, (val), -=)
-#endif
-
-#ifndef percpu_and
-# define percpu_and(var, val)		__percpu_generic_to_op(var, (val), &=)
-#endif
-
-#ifndef percpu_or
-# define percpu_or(var, val)		__percpu_generic_to_op(var, (val), |=)
-#endif
-
-#ifndef percpu_xor
-# define percpu_xor(var, val)		__percpu_generic_to_op(var, (val), ^=)
-#endif
-
-/*
  * Branching function to split up a function into a set of functions that
  * are called for different scalar sizes of the objects handled.
  */
@@ -348,9 +294,9 @@ do {									\
 #define _this_cpu_generic_to_op(pcp, val, op)				\
 do {									\
 	unsigned long flags;						\
-	local_irq_save(flags);						\
+	raw_local_irq_save(flags);					\
 	*__this_cpu_ptr(&(pcp)) op val;					\
-	local_irq_restore(flags);					\
+	raw_local_irq_restore(flags);					\
 } while (0)
 
 #ifndef this_cpu_write
@@ -449,10 +395,10 @@ do {									\
 ({									\
 	typeof(pcp) ret__;						\
 	unsigned long flags;						\
-	local_irq_save(flags);						\
+	raw_local_irq_save(flags);					\
 	__this_cpu_add(pcp, val);					\
 	ret__ = __this_cpu_read(pcp);					\
-	local_irq_restore(flags);					\
+	raw_local_irq_restore(flags);					\
 	ret__;								\
 })
 
@@ -479,10 +425,10 @@ do {									\
 #define _this_cpu_generic_xchg(pcp, nval)				\
 ({	typeof(pcp) ret__;						\
 	unsigned long flags;						\
-	local_irq_save(flags);						\
+	raw_local_irq_save(flags);					\
 	ret__ = __this_cpu_read(pcp);					\
 	__this_cpu_write(pcp, nval);					\
-	local_irq_restore(flags);					\
+	raw_local_irq_restore(flags);					\
 	ret__;								\
 })
 
@@ -507,11 +453,11 @@ do {									\
 ({									\
 	typeof(pcp) ret__;						\
 	unsigned long flags;						\
-	local_irq_save(flags);						\
+	raw_local_irq_save(flags);					\
 	ret__ = __this_cpu_read(pcp);					\
 	if (ret__ == (oval))						\
 		__this_cpu_write(pcp, nval);				\
-	local_irq_restore(flags);					\
+	raw_local_irq_restore(flags);					\
 	ret__;								\
 })
 
@@ -544,10 +490,10 @@ do {									\
 ({									\
 	int ret__;							\
 	unsigned long flags;						\
-	local_irq_save(flags);						\
+	raw_local_irq_save(flags);					\
 	ret__ = __this_cpu_generic_cmpxchg_double(pcp1, pcp2,		\
 			oval1, oval2, nval1, nval2);			\
-	local_irq_restore(flags);					\
+	raw_local_irq_restore(flags);					\
 	ret__;								\
 })
 
@@ -718,7 +664,8 @@ do {									\
 # ifndef __this_cpu_add_return_8
 #  define __this_cpu_add_return_8(pcp, val)	__this_cpu_generic_add_return(pcp, val)
 # endif
-# define __this_cpu_add_return(pcp, val)	__pcpu_size_call_return2(this_cpu_add_return_, pcp, val)
+# define __this_cpu_add_return(pcp, val)	\
+	__pcpu_size_call_return2(__this_cpu_add_return_, pcp, val)
 #endif
 
 #define __this_cpu_sub_return(pcp, val)	this_cpu_add_return(pcp, -(val))
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index abb2776..412b790 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -291,12 +291,14 @@ struct perf_event_mmap_page {
 	__s64	offset;			/* add to hardware event value */
 	__u64	time_enabled;		/* time event active */
 	__u64	time_running;		/* time event on cpu */
+	__u32	time_mult, time_shift;
+	__u64	time_offset;
 
 		/*
 		 * Hole for extension of the self monitor capabilities
 		 */
 
-	__u64	__reserved[123];	/* align to 1k */
+	__u64	__reserved[121];	/* align to 1k */
 
 	/*
 	 * Control data for the mmap() data buffer.
@@ -616,6 +618,7 @@ struct pmu {
 	struct list_head		entry;
 
 	struct device			*dev;
+	const struct attribute_group	**attr_groups;
 	char				*name;
 	int				type;
 
@@ -681,6 +684,12 @@ struct pmu {
 	 * for each successful ->add() during the transaction.
 	 */
 	void (*cancel_txn)		(struct pmu *pmu); /* optional */
+
+	/*
+	 * Will return the value for perf_event_mmap_page::index for this event,
+	 * if no implementation is provided it will default to: event->hw.idx + 1.
+	 */
+	int (*event_idx)		(struct perf_event *event); /*optional */
 };
 
 /**
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index e7cf666..a1ece7e 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -32,6 +32,7 @@ struct pid_namespace {
 #endif
 	gid_t pid_gid;
 	int hide_pid;
+	int reboot;	/* group exit code if this pidns was rebooted */
 };
 
 extern struct pid_namespace init_pid_ns;
@@ -47,6 +48,7 @@ static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
 extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns);
 extern void free_pid_ns(struct kref *kref);
 extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
+extern int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd);
 
 static inline void put_pid_ns(struct pid_namespace *ns)
 {
@@ -74,11 +76,15 @@ static inline void put_pid_ns(struct pid_namespace *ns)
 {
 }
 
-
 static inline void zap_pid_ns_processes(struct pid_namespace *ns)
 {
 	BUG();
 }
+
+static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd)
+{
+	return 0;
+}
 #endif /* CONFIG_PID_NS */
 
 extern struct pid_namespace *task_active_pid_ns(struct task_struct *tsk);
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h
new file mode 100644
index 0000000..3086594
--- /dev/null
+++ b/include/linux/pinctrl/consumer.h
@@ -0,0 +1,118 @@
+/*
+ * Consumer interface the pin control subsystem
+ *
+ * Copyright (C) 2012 ST-Ericsson SA
+ * Written on behalf of Linaro for ST-Ericsson
+ * Based on bits of regulator core, gpio core and clk core
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#ifndef __LINUX_PINCTRL_CONSUMER_H
+#define __LINUX_PINCTRL_CONSUMER_H
+
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include "pinctrl.h"
+
+/* This struct is private to the core and should be regarded as a cookie */
+struct pinctrl;
+
+#ifdef CONFIG_PINCTRL
+
+/* External interface to pin control */
+extern int pinctrl_request_gpio(unsigned gpio);
+extern void pinctrl_free_gpio(unsigned gpio);
+extern int pinctrl_gpio_direction_input(unsigned gpio);
+extern int pinctrl_gpio_direction_output(unsigned gpio);
+extern struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name);
+extern void pinctrl_put(struct pinctrl *p);
+extern int pinctrl_enable(struct pinctrl *p);
+extern void pinctrl_disable(struct pinctrl *p);
+
+#else /* !CONFIG_PINCTRL */
+
+static inline int pinctrl_request_gpio(unsigned gpio)
+{
+	return 0;
+}
+
+static inline void pinctrl_free_gpio(unsigned gpio)
+{
+}
+
+static inline int pinctrl_gpio_direction_input(unsigned gpio)
+{
+	return 0;
+}
+
+static inline int pinctrl_gpio_direction_output(unsigned gpio)
+{
+	return 0;
+}
+
+static inline struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name)
+{
+	return NULL;
+}
+
+static inline void pinctrl_put(struct pinctrl *p)
+{
+}
+
+static inline int pinctrl_enable(struct pinctrl *p)
+{
+	return 0;
+}
+
+static inline void pinctrl_disable(struct pinctrl *p)
+{
+}
+
+#endif /* CONFIG_PINCTRL */
+
+#ifdef CONFIG_PINCONF
+
+extern int pin_config_get(const char *dev_name, const char *name,
+			  unsigned long *config);
+extern int pin_config_set(const char *dev_name, const char *name,
+			  unsigned long config);
+extern int pin_config_group_get(const char *dev_name,
+				const char *pin_group,
+				unsigned long *config);
+extern int pin_config_group_set(const char *dev_name,
+				const char *pin_group,
+				unsigned long config);
+
+#else
+
+static inline int pin_config_get(const char *dev_name, const char *name,
+				 unsigned long *config)
+{
+	return 0;
+}
+
+static inline int pin_config_set(const char *dev_name, const char *name,
+				 unsigned long config)
+{
+	return 0;
+}
+
+static inline int pin_config_group_get(const char *dev_name,
+				       const char *pin_group,
+				       unsigned long *config)
+{
+	return 0;
+}
+
+static inline int pin_config_group_set(const char *dev_name,
+				       const char *pin_group,
+				       unsigned long config)
+{
+	return 0;
+}
+
+#endif
+
+#endif /* __LINUX_PINCTRL_CONSUMER_H */
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h
index d0aecb7..af145d5 100644
--- a/include/linux/pinctrl/machine.h
+++ b/include/linux/pinctrl/machine.h
@@ -9,87 +9,73 @@
  *
  * License terms: GNU General Public License (GPL) version 2
  */
-#ifndef __LINUX_PINMUX_MACHINE_H
-#define __LINUX_PINMUX_MACHINE_H
+#ifndef __LINUX_PINCTRL_MACHINE_H
+#define __LINUX_PINCTRL_MACHINE_H
 
 /**
- * struct pinmux_map - boards/machines shall provide this map for devices
+ * struct pinctrl_map - boards/machines shall provide this map for devices
  * @name: the name of this specific map entry for the particular machine.
  *	This is the second parameter passed to pinmux_get() when you want
  *	to have several mappings to the same device
- * @ctrl_dev: the pin control device to be used by this mapping, may be NULL
- *	if you provide .ctrl_dev_name instead (this is more common)
  * @ctrl_dev_name: the name of the device controlling this specific mapping,
- *	the name must be the same as in your struct device*, may be NULL if
- *	you provide .ctrl_dev instead
+ *	the name must be the same as in your struct device*
  * @function: a function in the driver to use for this mapping, the driver
  *	will lookup the function referenced by this ID on the specified
  *	pin control device
  * @group: sometimes a function can map to different pin groups, so this
  *	selects a certain specific pin group to activate for the function, if
  *	left as NULL, the first applicable group will be used
- * @dev: the device using this specific mapping, may be NULL if you provide
- *	.dev_name instead (this is more common)
  * @dev_name: the name of the device using this specific mapping, the name
- *	must be the same as in your struct device*, may be NULL if you
- *	provide .dev instead
- * @hog_on_boot: if this is set to true, the pin control subsystem will itself
- *	hog the mappings as the pinmux device drivers are attached, so this is
- *	typically used with system maps (mux mappings without an assigned
- *	device) that you want to get hogged and enabled by default as soon as
- *	a pinmux device supporting it is registered. These maps will not be
- *	disabled and put until the system shuts down.
+ *	must be the same as in your struct device*. If this name is set to the
+ *	same name as the pin controllers own dev_name(), the map entry will be
+ *	hogged by the driver itself upon registration
  */
-struct pinmux_map {
+struct pinctrl_map {
 	const char *name;
-	struct device *ctrl_dev;
 	const char *ctrl_dev_name;
 	const char *function;
 	const char *group;
-	struct device *dev;
 	const char *dev_name;
-	bool hog_on_boot;
 };
 
 /*
  * Convenience macro to set a simple map from a certain pin controller and a
  * certain function to a named device
  */
-#define PINMUX_MAP(a, b, c, d) \
+#define PIN_MAP(a, b, c, d) \
 	{ .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d }
 
 /*
  * Convenience macro to map a system function onto a certain pinctrl device.
  * System functions are not assigned to a particular device.
  */
-#define PINMUX_MAP_SYS(a, b, c) \
+#define PIN_MAP_SYS(a, b, c) \
 	{ .name = a, .ctrl_dev_name = b, .function = c }
 
 /*
  * Convenience macro to map a system function onto a certain pinctrl device,
- * to be hogged by the pinmux core until the system shuts down.
+ * to be hogged by the pin control core until the system shuts down.
  */
-#define PINMUX_MAP_SYS_HOG(a, b, c) \
-	{ .name = a, .ctrl_dev_name = b, .function = c, \
-	  .hog_on_boot = true }
+#define PIN_MAP_SYS_HOG(a, b, c) \
+	{ .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, }
 
 /*
  * Convenience macro to map a system function onto a certain pinctrl device
- * using a specified group, to be hogged by the pinmux core until the system
- * shuts down.
+ * using a specified group, to be hogged by the pin control core until the
+ * system shuts down.
  */
-#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d)		\
-	{ .name = a, .ctrl_dev_name = b, .function = c, .group = d, \
-	  .hog_on_boot = true }
+#define PIN_MAP_SYS_HOG_GROUP(a, b, c, d)		\
+	{ .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, \
+	  .group = d, }
 
 #ifdef CONFIG_PINMUX
 
-extern int pinmux_register_mappings(struct pinmux_map const *map,
+extern int pinctrl_register_mappings(struct pinctrl_map const *map,
 				unsigned num_maps);
 
 #else
 
-static inline int pinmux_register_mappings(struct pinmux_map const *map,
+static inline int pinctrl_register_mappings(struct pinctrl_map const *map,
 					   unsigned num_maps)
 {
 	return 0;
diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h
index 477922c..f8cf156 100644
--- a/include/linux/pinctrl/pinconf.h
+++ b/include/linux/pinctrl/pinconf.h
@@ -53,45 +53,6 @@ struct pinconf_ops {
 					   unsigned selector);
 };
 
-extern int pin_config_get(const char *dev_name, const char *name,
-			  unsigned long *config);
-extern int pin_config_set(const char *dev_name, const char *name,
-			  unsigned long config);
-extern int pin_config_group_get(const char *dev_name,
-				const char *pin_group,
-				unsigned long *config);
-extern int pin_config_group_set(const char *dev_name,
-				const char *pin_group,
-				unsigned long config);
-
-#else
-
-static inline int pin_config_get(const char *dev_name, const char *name,
-				 unsigned long *config)
-{
-	return 0;
-}
-
-static inline int pin_config_set(const char *dev_name, const char *name,
-				 unsigned long config)
-{
-	return 0;
-}
-
-static inline int pin_config_group_get(const char *dev_name,
-				       const char *pin_group,
-				       unsigned long *config)
-{
-	return 0;
-}
-
-static inline int pin_config_group_set(const char *dev_name,
-				       const char *pin_group,
-				       unsigned long config)
-{
-	return 0;
-}
-
 #endif
 
 #endif /* __LINUX_PINCTRL_PINCONF_H */
diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h
index 937b3e2..47e9237 100644
--- a/include/linux/pinctrl/pinmux.h
+++ b/include/linux/pinctrl/pinmux.h
@@ -16,9 +16,6 @@
 #include <linux/seq_file.h>
 #include "pinctrl.h"
 
-/* This struct is private to the core and should be regarded as a cookie */
-struct pinmux;
-
 #ifdef CONFIG_PINMUX
 
 struct pinctrl_dev;
@@ -88,55 +85,6 @@ struct pinmux_ops {
 				   bool input);
 };
 
-/* External interface to pinmux */
-extern int pinmux_request_gpio(unsigned gpio);
-extern void pinmux_free_gpio(unsigned gpio);
-extern int pinmux_gpio_direction_input(unsigned gpio);
-extern int pinmux_gpio_direction_output(unsigned gpio);
-extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name);
-extern void pinmux_put(struct pinmux *pmx);
-extern int pinmux_enable(struct pinmux *pmx);
-extern void pinmux_disable(struct pinmux *pmx);
-
-#else /* !CONFIG_PINMUX */
-
-static inline int pinmux_request_gpio(unsigned gpio)
-{
-	return 0;
-}
-
-static inline void pinmux_free_gpio(unsigned gpio)
-{
-}
-
-static inline int pinmux_gpio_direction_input(unsigned gpio)
-{
-	return 0;
-}
-
-static inline int pinmux_gpio_direction_output(unsigned gpio)
-{
-	return 0;
-}
-
-static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name)
-{
-	return NULL;
-}
-
-static inline void pinmux_put(struct pinmux *pmx)
-{
-}
-
-static inline int pinmux_enable(struct pinmux *pmx)
-{
-	return 0;
-}
-
-static inline void pinmux_disable(struct pinmux *pmx)
-{
-}
-
 #endif /* CONFIG_PINMUX */
 
 #endif /* __LINUX_PINCTRL_PINMUX_H */
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 77257c9..6d626ff 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -1,8 +1,6 @@
 #ifndef _LINUX_PIPE_FS_I_H
 #define _LINUX_PIPE_FS_I_H
 
-#define PIPEFS_MAGIC 0x50495045
-
 #define PIPE_DEF_BUFFERS	16
 
 #define PIPE_BUF_FLAG_LRU	0x01	/* page is on the LRU */
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index 0d5b793..410b33d 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -127,6 +127,27 @@ struct tc_multiq_qopt {
 	__u16	max_bands;		/* Maximum number of queues */
 };
 
+/* PLUG section */
+
+#define TCQ_PLUG_BUFFER                0
+#define TCQ_PLUG_RELEASE_ONE           1
+#define TCQ_PLUG_RELEASE_INDEFINITE    2
+#define TCQ_PLUG_LIMIT                 3
+
+struct tc_plug_qopt {
+	/* TCQ_PLUG_BUFFER: Inset a plug into the queue and
+	 *  buffer any incoming packets
+	 * TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue head
+	 *   to beginning of the next plug.
+	 * TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue.
+	 *   Stop buffering packets until the next TCQ_PLUG_BUFFER
+	 *   command is received (just act as a pass-thru queue).
+	 * TCQ_PLUG_LIMIT: Increase/decrease queue size
+	 */
+	int             action;
+	__u32           limit;
+};
+
 /* TBF section */
 
 struct tc_tbf_qopt {
diff --git a/include/linux/platform_data/efm32-uart.h b/include/linux/platform_data/efm32-uart.h
new file mode 100644
index 0000000..ed0e975
--- /dev/null
+++ b/include/linux/platform_data/efm32-uart.h
@@ -0,0 +1,18 @@
+/*
+ *
+ *
+ */
+#ifndef __LINUX_PLATFORM_DATA_EFM32_UART_H__
+#define __LINUX_PLATFORM_DATA_EFM32_UART_H__
+
+#include <linux/types.h>
+
+/**
+ * struct efm32_uart_pdata
+ * @location: pinmux location for the I/O pins (to be written to the ROUTE
+ * 	register)
+ */
+struct efm32_uart_pdata {
+	u8 location;
+};
+#endif /* ifndef __LINUX_PLATFORM_DATA_EFM32_UART_H__ */
diff --git a/include/linux/platform_data/omap-abe-twl6040.h b/include/linux/platform_data/omap-abe-twl6040.h
new file mode 100644
index 0000000..5d298ac
--- /dev/null
+++ b/include/linux/platform_data/omap-abe-twl6040.h
@@ -0,0 +1,49 @@
+/**
+ * omap-abe-twl6040.h - ASoC machine driver OMAP4+ devices, header.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _OMAP_ABE_TWL6040_H_
+#define _OMAP_ABE_TWL6040_H_
+
+/* To select if only one channel is connected in a stereo port */
+#define ABE_TWL6040_LEFT	(1 << 0)
+#define ABE_TWL6040_RIGHT	(1 << 1)
+
+struct omap_abe_twl6040_data {
+	char *card_name;
+	/* Feature flags for connected audio pins */
+	u8	has_hs;
+	u8	has_hf;
+	bool	has_ep;
+	u8	has_aux;
+	u8	has_vibra;
+	bool	has_dmic;
+	bool	has_hsmic;
+	bool	has_mainmic;
+	bool	has_submic;
+	u8	has_afm;
+	/* Other features */
+	bool	jack_detection;	/* board can detect jack events */
+	int	mclk_freq;	/* MCLK frequency speed for twl6040 */
+};
+
+#endif /* _OMAP_ABE_TWL6040_H_ */
diff --git a/include/linux/platform_data/tegra_emc.h b/include/linux/platform_data/tegra_emc.h
new file mode 100644
index 0000000..df67505
--- /dev/null
+++ b/include/linux/platform_data/tegra_emc.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ *	Colin Cross <ccross@android.com>
+ *	Olof Johansson <olof@lixom.net>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+	unsigned long rate;
+	u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+struct tegra_emc_pdata {
+	int num_tables;
+	struct tegra_emc_table *tables;
+};
+
+#endif
diff --git a/include/linux/pm.h b/include/linux/pm.h
index e4982ac..d6dd6f6 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -110,6 +110,10 @@ typedef struct pm_message {
  *	Subsystem-level @suspend() is executed for all devices after invoking
  *	subsystem-level @prepare() for all of them.
  *
+ * @suspend_late: Continue operations started by @suspend().  For a number of
+ *	devices @suspend_late() may point to the same callback routine as the
+ *	runtime suspend callback.
+ *
  * @resume: Executed after waking the system up from a sleep state in which the
  *	contents of main memory were preserved.  The exact action to perform
  *	depends on the device's subsystem, but generally the driver is expected
@@ -122,6 +126,10 @@ typedef struct pm_message {
  *	Subsystem-level @resume() is executed for all devices after invoking
  *	subsystem-level @resume_noirq() for all of them.
  *
+ * @resume_early: Prepare to execute @resume().  For a number of devices
+ *	@resume_early() may point to the same callback routine as the runtime
+ *	resume callback.
+ *
  * @freeze: Hibernation-specific, executed before creating a hibernation image.
  *	Analogous to @suspend(), but it should not enable the device to signal
  *	wakeup events or change its power state.  The majority of subsystems
@@ -131,6 +139,10 @@ typedef struct pm_message {
  *	Subsystem-level @freeze() is executed for all devices after invoking
  *	subsystem-level @prepare() for all of them.
  *
+ * @freeze_late: Continue operations started by @freeze().  Analogous to
+ *	@suspend_late(), but it should not enable the device to signal wakeup
+ *	events or change its power state.
+ *
  * @thaw: Hibernation-specific, executed after creating a hibernation image OR
  *	if the creation of an image has failed.  Also executed after a failing
  *	attempt to restore the contents of main memory from such an image.
@@ -140,15 +152,23 @@ typedef struct pm_message {
  *	subsystem-level @thaw_noirq() for all of them.  It also may be executed
  *	directly after @freeze() in case of a transition error.
  *
+ * @thaw_early: Prepare to execute @thaw().  Undo the changes made by the
+ *	preceding @freeze_late().
+ *
  * @poweroff: Hibernation-specific, executed after saving a hibernation image.
  *	Analogous to @suspend(), but it need not save the device's settings in
  *	memory.
  *	Subsystem-level @poweroff() is executed for all devices after invoking
  *	subsystem-level @prepare() for all of them.
  *
+ * @poweroff_late: Continue operations started by @poweroff().  Analogous to
+ *	@suspend_late(), but it need not save the device's settings in memory.
+ *
  * @restore: Hibernation-specific, executed after restoring the contents of main
  *	memory from a hibernation image, analogous to @resume().
  *
+ * @restore_early: Prepare to execute @restore(), analogous to @resume_early().
+ *
  * @suspend_noirq: Complete the actions started by @suspend().  Carry out any
  *	additional operations required for suspending the device that might be
  *	racing with its driver's interrupt handler, which is guaranteed not to
@@ -158,9 +178,10 @@ typedef struct pm_message {
  *	@suspend_noirq() has returned successfully.  If the device can generate
  *	system wakeup signals and is enabled to wake up the system, it should be
  *	configured to do so at that time.  However, depending on the platform
- *	and device's subsystem, @suspend() may be allowed to put the device into
- *	the low-power state and configure it to generate wakeup signals, in
- *	which case it generally is not necessary to define @suspend_noirq().
+ *	and device's subsystem, @suspend() or @suspend_late() may be allowed to
+ *	put the device into the low-power state and configure it to generate
+ *	wakeup signals, in which case it generally is not necessary to define
+ *	@suspend_noirq().
  *
  * @resume_noirq: Prepare for the execution of @resume() by carrying out any
  *	operations required for resuming the device that might be racing with
@@ -171,9 +192,9 @@ typedef struct pm_message {
  *	additional operations required for freezing the device that might be
  *	racing with its driver's interrupt handler, which is guaranteed not to
  *	run while @freeze_noirq() is being executed.
- *	The power state of the device should not be changed by either @freeze()
- *	or @freeze_noirq() and it should not be configured to signal system
- *	wakeup by any of these callbacks.
+ *	The power state of the device should not be changed by either @freeze(),
+ *	or @freeze_late(), or @freeze_noirq() and it should not be configured to
+ *	signal system wakeup by any of these callbacks.
  *
  * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any
  *	operations required for thawing the device that might be racing with its
@@ -249,6 +270,12 @@ struct dev_pm_ops {
 	int (*thaw)(struct device *dev);
 	int (*poweroff)(struct device *dev);
 	int (*restore)(struct device *dev);
+	int (*suspend_late)(struct device *dev);
+	int (*resume_early)(struct device *dev);
+	int (*freeze_late)(struct device *dev);
+	int (*thaw_early)(struct device *dev);
+	int (*poweroff_late)(struct device *dev);
+	int (*restore_early)(struct device *dev);
 	int (*suspend_noirq)(struct device *dev);
 	int (*resume_noirq)(struct device *dev);
 	int (*freeze_noirq)(struct device *dev);
@@ -293,6 +320,15 @@ const struct dev_pm_ops name = { \
 /*
  * Use this for defining a set of PM operations to be used in all situations
  * (sustem suspend, hibernation or runtime PM).
+ * NOTE: In general, system suspend callbacks, .suspend() and .resume(), should
+ * be different from the corresponding runtime PM callbacks, .runtime_suspend(),
+ * and .runtime_resume(), because .runtime_suspend() always works on an already
+ * quiescent device, while .suspend() should assume that the device may be doing
+ * something when it is called (it should ensure that the device will be
+ * quiescent after it has returned).  Therefore it's better to point the "late"
+ * suspend and "early" resume callback pointers, .suspend_late() and
+ * .resume_early(), to the same routines as .runtime_suspend() and
+ * .runtime_resume(), respectively (and analogously for hibernation).
  */
 #define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
 const struct dev_pm_ops name = { \
@@ -584,13 +620,13 @@ struct dev_pm_domain {
 
 #ifdef CONFIG_PM_SLEEP
 extern void device_pm_lock(void);
-extern void dpm_resume_noirq(pm_message_t state);
+extern void dpm_resume_start(pm_message_t state);
 extern void dpm_resume_end(pm_message_t state);
 extern void dpm_resume(pm_message_t state);
 extern void dpm_complete(pm_message_t state);
 
 extern void device_pm_unlock(void);
-extern int dpm_suspend_noirq(pm_message_t state);
+extern int dpm_suspend_end(pm_message_t state);
 extern int dpm_suspend_start(pm_message_t state);
 extern int dpm_suspend(pm_message_t state);
 extern int dpm_prepare(pm_message_t state);
@@ -605,17 +641,23 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
 extern int device_pm_wait_for_dev(struct device *sub, struct device *dev);
 
 extern int pm_generic_prepare(struct device *dev);
+extern int pm_generic_suspend_late(struct device *dev);
 extern int pm_generic_suspend_noirq(struct device *dev);
 extern int pm_generic_suspend(struct device *dev);
+extern int pm_generic_resume_early(struct device *dev);
 extern int pm_generic_resume_noirq(struct device *dev);
 extern int pm_generic_resume(struct device *dev);
 extern int pm_generic_freeze_noirq(struct device *dev);
+extern int pm_generic_freeze_late(struct device *dev);
 extern int pm_generic_freeze(struct device *dev);
 extern int pm_generic_thaw_noirq(struct device *dev);
+extern int pm_generic_thaw_early(struct device *dev);
 extern int pm_generic_thaw(struct device *dev);
 extern int pm_generic_restore_noirq(struct device *dev);
+extern int pm_generic_restore_early(struct device *dev);
 extern int pm_generic_restore(struct device *dev);
 extern int pm_generic_poweroff_noirq(struct device *dev);
+extern int pm_generic_poweroff_late(struct device *dev);
 extern int pm_generic_poweroff(struct device *dev);
 extern void pm_generic_complete(struct device *dev);
 
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index a03a0ad..e76cc9a 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -11,6 +11,7 @@
 
 #include <linux/device.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 enum gpd_status {
 	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
@@ -70,6 +71,7 @@ struct generic_pm_domain {
 	s64 break_even_ns;	/* Power break even for the entire domain. */
 	s64 max_off_time_ns;	/* Maximum allowed "suspended" time. */
 	ktime_t power_off_time;
+	struct device_node *of_node; /* Node in device tree */
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
@@ -99,12 +101,12 @@ struct generic_pm_domain_data {
 	bool need_restore;
 };
 
+#ifdef CONFIG_PM_GENERIC_DOMAINS
 static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd)
 {
 	return container_of(pdd, struct generic_pm_domain_data, base);
 }
 
-#ifdef CONFIG_PM_GENERIC_DOMAINS
 static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
 {
 	return to_gpd_data(dev->power.subsys_data->domain_data);
@@ -117,12 +119,22 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd,
 				 struct device *dev,
 				 struct gpd_timing_data *td);
 
+extern int __pm_genpd_of_add_device(struct device_node *genpd_node,
+				    struct device *dev,
+				    struct gpd_timing_data *td);
+
 static inline int pm_genpd_add_device(struct generic_pm_domain *genpd,
 				      struct device *dev)
 {
 	return __pm_genpd_add_device(genpd, dev, NULL);
 }
 
+static inline int pm_genpd_of_add_device(struct device_node *genpd_node,
+					 struct device *dev)
+{
+	return __pm_genpd_of_add_device(genpd_node, dev, NULL);
+}
+
 extern int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 				  struct device *dev);
 extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
@@ -195,6 +207,10 @@ static inline bool default_stop_ok(struct device *dev)
 	return false;
 }
 #define pm_domain_always_on_gov NULL
+static inline struct generic_pm_domain_data *dev_gpd_data(struct device *dev)
+{
+	return NULL;
+}
 #endif
 
 static inline int pm_genpd_remove_callbacks(struct device *dev)
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h
index 4d99e4e..c8a541e 100644
--- a/include/linux/pm_qos.h
+++ b/include/linux/pm_qos.h
@@ -9,12 +9,16 @@
 #include <linux/miscdevice.h>
 #include <linux/device.h>
 
-#define PM_QOS_RESERVED 0
-#define PM_QOS_CPU_DMA_LATENCY 1
-#define PM_QOS_NETWORK_LATENCY 2
-#define PM_QOS_NETWORK_THROUGHPUT 3
+enum {
+	PM_QOS_RESERVED = 0,
+	PM_QOS_CPU_DMA_LATENCY,
+	PM_QOS_NETWORK_LATENCY,
+	PM_QOS_NETWORK_THROUGHPUT,
+
+	/* insert new class ID */
+	PM_QOS_NUM_CLASSES,
+};
 
-#define PM_QOS_NUM_CLASSES 4
 #define PM_QOS_DEFAULT_VALUE -1
 
 #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE	(2000 * USEC_PER_SEC)
@@ -63,7 +67,6 @@ static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req)
 	return req->dev != 0;
 }
 
-#ifdef CONFIG_PM
 int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
 			 enum pm_qos_req_action action, int value);
 void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class,
@@ -78,6 +81,7 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier);
 int pm_qos_request_active(struct pm_qos_request *req);
 s32 pm_qos_read_value(struct pm_qos_constraints *c);
 
+#ifdef CONFIG_PM
 s32 __dev_pm_qos_read_value(struct device *dev);
 s32 dev_pm_qos_read_value(struct device *dev);
 int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
@@ -95,45 +99,6 @@ void dev_pm_qos_constraints_destroy(struct device *dev);
 int dev_pm_qos_add_ancestor_request(struct device *dev,
 				    struct dev_pm_qos_request *req, s32 value);
 #else
-static inline int pm_qos_update_target(struct pm_qos_constraints *c,
-				       struct plist_node *node,
-				       enum pm_qos_req_action action,
-				       int value)
-			{ return 0; }
-static inline void pm_qos_add_request(struct pm_qos_request *req,
-				      int pm_qos_class, s32 value)
-			{ return; }
-static inline void pm_qos_update_request(struct pm_qos_request *req,
-					 s32 new_value)
-			{ return; }
-static inline void pm_qos_remove_request(struct pm_qos_request *req)
-			{ return; }
-
-static inline int pm_qos_request(int pm_qos_class)
-{
-	switch (pm_qos_class) {
-	case PM_QOS_CPU_DMA_LATENCY:
-		return PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
-	case PM_QOS_NETWORK_LATENCY:
-		return PM_QOS_NETWORK_LAT_DEFAULT_VALUE;
-	case PM_QOS_NETWORK_THROUGHPUT:
-		return PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE;
-	default:
-		return PM_QOS_DEFAULT_VALUE;
-	}
-}
-
-static inline int pm_qos_add_notifier(int pm_qos_class,
-				      struct notifier_block *notifier)
-			{ return 0; }
-static inline int pm_qos_remove_notifier(int pm_qos_class,
-					 struct notifier_block *notifier)
-			{ return 0; }
-static inline int pm_qos_request_active(struct pm_qos_request *req)
-			{ return 0; }
-static inline s32 pm_qos_read_value(struct pm_qos_constraints *c)
-			{ return 0; }
-
 static inline s32 __dev_pm_qos_read_value(struct device *dev)
 			{ return 0; }
 static inline s32 dev_pm_qos_read_value(struct device *dev)
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index 7ddc7f1..91a9c59 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -113,5 +113,20 @@
 # define PR_SET_MM_START_STACK		5
 # define PR_SET_MM_START_BRK		6
 # define PR_SET_MM_BRK			7
+# define PR_SET_MM_ARG_START		8
+# define PR_SET_MM_ARG_END		9
+# define PR_SET_MM_ENV_START		10
+# define PR_SET_MM_ENV_END		11
+# define PR_SET_MM_AUXV			12
+
+/*
+ * Set specific pid that is allowed to ptrace the current task.
+ * A value of 0 mean "no process".
+ */
+#define PR_SET_PTRACER 0x59616d61
+# define PR_SET_PTRACER_ANY ((unsigned long)-1)
+
+#define PR_SET_CHILD_SUBREAPER 36
+#define PR_GET_CHILD_SUBREAPER 37
 
 #endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/printk.h b/include/linux/printk.h
index f0e22f7..f9abd93 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -180,13 +180,13 @@ extern void dump_stack(void) __cold;
 #endif
 
 /* If you are writing a driver, please use dev_dbg instead */
-#if defined(DEBUG)
-#define pr_debug(fmt, ...) \
-	printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
-#elif defined(CONFIG_DYNAMIC_DEBUG)
+#if defined(CONFIG_DYNAMIC_DEBUG)
 /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
 #define pr_debug(fmt, ...) \
 	dynamic_pr_debug(fmt, ##__VA_ARGS__)
+#elif defined(DEBUG)
+#define pr_debug(fmt, ...) \
+	printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
 #else
 #define pr_debug(fmt, ...) \
 	no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index c2f1f6a..407c678 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -51,20 +51,6 @@
 #define PTRACE_INTERRUPT	0x4207
 #define PTRACE_LISTEN		0x4208
 
-/* flags in @data for PTRACE_SEIZE */
-#define PTRACE_SEIZE_DEVEL	0x80000000 /* temp flag for development */
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD	0x00000001
-#define PTRACE_O_TRACEFORK	0x00000002
-#define PTRACE_O_TRACEVFORK	0x00000004
-#define PTRACE_O_TRACECLONE	0x00000008
-#define PTRACE_O_TRACEEXEC	0x00000010
-#define PTRACE_O_TRACEVFORKDONE	0x00000020
-#define PTRACE_O_TRACEEXIT	0x00000040
-
-#define PTRACE_O_MASK		0x0000007f
-
 /* Wait extended result codes for the above trace options.  */
 #define PTRACE_EVENT_FORK	1
 #define PTRACE_EVENT_VFORK	2
@@ -72,7 +58,19 @@
 #define PTRACE_EVENT_EXEC	4
 #define PTRACE_EVENT_VFORK_DONE	5
 #define PTRACE_EVENT_EXIT	6
-#define PTRACE_EVENT_STOP	7
+/* Extended result codes which enabled by means other than options.  */
+#define PTRACE_EVENT_STOP	128
+
+/* Options set using PTRACE_SETOPTIONS or using PTRACE_SEIZE @data param */
+#define PTRACE_O_TRACESYSGOOD	1
+#define PTRACE_O_TRACEFORK	(1 << PTRACE_EVENT_FORK)
+#define PTRACE_O_TRACEVFORK	(1 << PTRACE_EVENT_VFORK)
+#define PTRACE_O_TRACECLONE	(1 << PTRACE_EVENT_CLONE)
+#define PTRACE_O_TRACEEXEC	(1 << PTRACE_EVENT_EXEC)
+#define PTRACE_O_TRACEVFORKDONE	(1 << PTRACE_EVENT_VFORK_DONE)
+#define PTRACE_O_TRACEEXIT	(1 << PTRACE_EVENT_EXIT)
+
+#define PTRACE_O_MASK		0x0000007f
 
 #include <asm/ptrace.h>
 
@@ -88,13 +86,12 @@
 #define PT_SEIZED	0x00010000	/* SEIZE used, enable new behavior */
 #define PT_PTRACED	0x00000001
 #define PT_DTRACE	0x00000002	/* delayed trace (used on m68k, i386) */
-#define PT_TRACESYSGOOD	0x00000004
-#define PT_PTRACE_CAP	0x00000008	/* ptracer can follow suid-exec */
+#define PT_PTRACE_CAP	0x00000004	/* ptracer can follow suid-exec */
 
+#define PT_OPT_FLAG_SHIFT	3
 /* PT_TRACE_* event enable flags */
-#define PT_EVENT_FLAG_SHIFT	4
-#define PT_EVENT_FLAG(event)	(1 << (PT_EVENT_FLAG_SHIFT + (event) - 1))
-
+#define PT_EVENT_FLAG(event)	(1 << (PT_OPT_FLAG_SHIFT + (event)))
+#define PT_TRACESYSGOOD		PT_EVENT_FLAG(0)
 #define PT_TRACE_FORK		PT_EVENT_FLAG(PTRACE_EVENT_FORK)
 #define PT_TRACE_VFORK		PT_EVENT_FLAG(PTRACE_EVENT_VFORK)
 #define PT_TRACE_CLONE		PT_EVENT_FLAG(PTRACE_EVENT_CLONE)
@@ -102,8 +99,6 @@
 #define PT_TRACE_VFORK_DONE	PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
 #define PT_TRACE_EXIT		PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
 
-#define PT_TRACE_MASK	0x000003f4
-
 /* single stepping state bits (used on ARM and PA-RISC) */
 #define PT_SINGLESTEP_BIT	31
 #define PT_SINGLESTEP		(1<<PT_SINGLESTEP_BIT)
@@ -199,9 +194,10 @@ static inline void ptrace_event(int event, unsigned long message)
 	if (unlikely(ptrace_event_enabled(current, event))) {
 		current->ptrace_message = message;
 		ptrace_notify((event << 8) | SIGTRAP);
-	} else if (event == PTRACE_EVENT_EXEC && unlikely(current->ptrace)) {
+	} else if (event == PTRACE_EVENT_EXEC) {
 		/* legacy EXEC report via SIGTRAP */
-		send_sig(SIGTRAP, current, 0);
+		if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) == PT_PTRACED)
+			send_sig(SIGTRAP, current, 0);
 	}
 }
 
diff --git a/include/linux/rar_register.h b/include/linux/rar_register.h
deleted file mode 100644
index 5c61181..0000000
--- a/include/linux/rar_register.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General
- * Public License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA  02111-1307, USA.
- * The full GNU General Public License is included in this
- * distribution in the file called COPYING.
- */
-
-
-#ifndef _RAR_REGISTER_H
-#define _RAR_REGISTER_H
-
-#include <linux/types.h>
-
-/* following are used both in drivers as well as user space apps */
-
-#define	RAR_TYPE_VIDEO	0
-#define	RAR_TYPE_AUDIO	1
-#define	RAR_TYPE_IMAGE	2
-#define	RAR_TYPE_DATA	3
-
-#ifdef __KERNEL__
-
-struct rar_device;
-
-#if defined(CONFIG_RAR_REGISTER)
-int register_rar(int num,
-		int (*callback)(unsigned long data), unsigned long data);
-void unregister_rar(int num);
-int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end);
-int rar_lock(int rar_index);
-#else
-extern void unregister_rar(int num)  { }
-extern int rar_lock(int rar_index) { return -EIO; }
-
-extern inline int register_rar(int num,
-		int (*callback)(unsigned long data), unsigned long data)
-{
-	return -ENODEV;
-}
-
-extern int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end)
-{
-	return -ENODEV;
-}
-#endif	/* RAR_REGISTER */
-
-#endif  /* __KERNEL__ */
-#endif  /* _RAR_REGISTER_H */
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 81c04f4..9372174 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -190,6 +190,33 @@ extern void rcu_idle_exit(void);
 extern void rcu_irq_enter(void);
 extern void rcu_irq_exit(void);
 
+/**
+ * RCU_NONIDLE - Indicate idle-loop code that needs RCU readers
+ * @a: Code that RCU needs to pay attention to.
+ *
+ * RCU, RCU-bh, and RCU-sched read-side critical sections are forbidden
+ * in the inner idle loop, that is, between the rcu_idle_enter() and
+ * the rcu_idle_exit() -- RCU will happily ignore any such read-side
+ * critical sections.  However, things like powertop need tracepoints
+ * in the inner idle loop.
+ *
+ * This macro provides the way out:  RCU_NONIDLE(do_something_with_RCU())
+ * will tell RCU that it needs to pay attending, invoke its argument
+ * (in this example, a call to the do_something_with_RCU() function),
+ * and then tell RCU to go back to ignoring this CPU.  It is permissible
+ * to nest RCU_NONIDLE() wrappers, but the nesting level is currently
+ * quite limited.  If deeper nesting is required, it will be necessary
+ * to adjust DYNTICK_TASK_NESTING_VALUE accordingly.
+ *
+ * This macro may be used from process-level code only.
+ */
+#define RCU_NONIDLE(a) \
+	do { \
+		rcu_idle_exit(); \
+		do { a; } while (0); \
+		rcu_idle_enter(); \
+	} while (0)
+
 /*
  * Infrastructure to implement the synchronize_() primitives in
  * TREE_RCU and rcu_barrier_() primitives in TINY_RCU.
@@ -226,6 +253,15 @@ static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
 }
 #endif	/* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */
 
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU)
+bool rcu_lockdep_current_cpu_online(void);
+#else /* #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */
+static inline bool rcu_lockdep_current_cpu_online(void)
+{
+	return 1;
+}
+#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PROVE_RCU) */
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
 #ifdef CONFIG_PROVE_RCU
@@ -239,13 +275,11 @@ static inline int rcu_is_cpu_idle(void)
 
 static inline void rcu_lock_acquire(struct lockdep_map *map)
 {
-	WARN_ON_ONCE(rcu_is_cpu_idle());
 	lock_acquire(map, 0, 0, 2, 1, NULL, _THIS_IP_);
 }
 
 static inline void rcu_lock_release(struct lockdep_map *map)
 {
-	WARN_ON_ONCE(rcu_is_cpu_idle());
 	lock_release(map, 1, _THIS_IP_);
 }
 
@@ -270,6 +304,9 @@ extern int debug_lockdep_rcu_enabled(void);
  * occur in the same context, for example, it is illegal to invoke
  * rcu_read_unlock() in process context if the matching rcu_read_lock()
  * was invoked from within an irq handler.
+ *
+ * Note that rcu_read_lock() is disallowed if the CPU is either idle or
+ * offline from an RCU perspective, so check for those as well.
  */
 static inline int rcu_read_lock_held(void)
 {
@@ -277,6 +314,8 @@ static inline int rcu_read_lock_held(void)
 		return 1;
 	if (rcu_is_cpu_idle())
 		return 0;
+	if (!rcu_lockdep_current_cpu_online())
+		return 0;
 	return lock_is_held(&rcu_lock_map);
 }
 
@@ -313,6 +352,9 @@ extern int rcu_read_lock_bh_held(void);
  * notice an extended quiescent state to other CPUs that started a grace
  * period. Otherwise we would delay any grace period as long as we run in
  * the idle task.
+ *
+ * Similarly, we avoid claiming an SRCU read lock held if the current
+ * CPU is offline.
  */
 #ifdef CONFIG_PREEMPT_COUNT
 static inline int rcu_read_lock_sched_held(void)
@@ -323,6 +365,8 @@ static inline int rcu_read_lock_sched_held(void)
 		return 1;
 	if (rcu_is_cpu_idle())
 		return 0;
+	if (!rcu_lockdep_current_cpu_online())
+		return 0;
 	if (debug_locks)
 		lockdep_opinion = lock_is_held(&rcu_sched_lock_map);
 	return lockdep_opinion || preempt_count() != 0 || irqs_disabled();
@@ -381,8 +425,22 @@ extern int rcu_my_thread_group_empty(void);
 		}							\
 	} while (0)
 
+#if defined(CONFIG_PROVE_RCU) && !defined(CONFIG_PREEMPT_RCU)
+static inline void rcu_preempt_sleep_check(void)
+{
+	rcu_lockdep_assert(!lock_is_held(&rcu_lock_map),
+			   "Illegal context switch in RCU read-side "
+			   "critical section");
+}
+#else /* #ifdef CONFIG_PROVE_RCU */
+static inline void rcu_preempt_sleep_check(void)
+{
+}
+#endif /* #else #ifdef CONFIG_PROVE_RCU */
+
 #define rcu_sleep_check()						\
 	do {								\
+		rcu_preempt_sleep_check();				\
 		rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),	\
 				   "Illegal context switch in RCU-bh"	\
 				   " read-side critical section");	\
@@ -470,6 +528,13 @@ extern int rcu_my_thread_group_empty(void);
  * NULL.  Although rcu_access_pointer() may also be used in cases where
  * update-side locks prevent the value of the pointer from changing, you
  * should instead use rcu_dereference_protected() for this use case.
+ *
+ * It is also permissible to use rcu_access_pointer() when read-side
+ * access to the pointer was removed at least one grace period ago, as
+ * is the case in the context of the RCU callback that is freeing up
+ * the data, or after a synchronize_rcu() returns.  This can be useful
+ * when tearing down multi-linked structures after a grace period
+ * has elapsed.
  */
 #define rcu_access_pointer(p) __rcu_access_pointer((p), __rcu)
 
@@ -659,6 +724,8 @@ static inline void rcu_read_lock(void)
 	__rcu_read_lock();
 	__acquire(RCU);
 	rcu_lock_acquire(&rcu_lock_map);
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "rcu_read_lock() used illegally while idle");
 }
 
 /*
@@ -678,6 +745,8 @@ static inline void rcu_read_lock(void)
  */
 static inline void rcu_read_unlock(void)
 {
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "rcu_read_unlock() used illegally while idle");
 	rcu_lock_release(&rcu_lock_map);
 	__release(RCU);
 	__rcu_read_unlock();
@@ -705,6 +774,8 @@ static inline void rcu_read_lock_bh(void)
 	local_bh_disable();
 	__acquire(RCU_BH);
 	rcu_lock_acquire(&rcu_bh_lock_map);
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "rcu_read_lock_bh() used illegally while idle");
 }
 
 /*
@@ -714,6 +785,8 @@ static inline void rcu_read_lock_bh(void)
  */
 static inline void rcu_read_unlock_bh(void)
 {
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "rcu_read_unlock_bh() used illegally while idle");
 	rcu_lock_release(&rcu_bh_lock_map);
 	__release(RCU_BH);
 	local_bh_enable();
@@ -737,6 +810,8 @@ static inline void rcu_read_lock_sched(void)
 	preempt_disable();
 	__acquire(RCU_SCHED);
 	rcu_lock_acquire(&rcu_sched_lock_map);
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "rcu_read_lock_sched() used illegally while idle");
 }
 
 /* Used by lockdep and tracing: cannot be traced, cannot call lockdep. */
@@ -753,6 +828,8 @@ static inline notrace void rcu_read_lock_sched_notrace(void)
  */
 static inline void rcu_read_unlock_sched(void)
 {
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "rcu_read_unlock_sched() used illegally while idle");
 	rcu_lock_release(&rcu_sched_lock_map);
 	__release(RCU_SCHED);
 	preempt_enable();
@@ -841,7 +918,7 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset)
 	/* See the kfree_rcu() header comment. */
 	BUILD_BUG_ON(!__is_kfree_rcu_offset(offset));
 
-	call_rcu(head, (rcu_callback)offset);
+	kfree_call_rcu(head, (rcu_callback)offset);
 }
 
 /**
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
index 00b7a5e..e93df77 100644
--- a/include/linux/rcutiny.h
+++ b/include/linux/rcutiny.h
@@ -27,13 +27,9 @@
 
 #include <linux/cache.h>
 
-#ifdef CONFIG_RCU_BOOST
 static inline void rcu_init(void)
 {
 }
-#else /* #ifdef CONFIG_RCU_BOOST */
-void rcu_init(void);
-#endif /* #else #ifdef CONFIG_RCU_BOOST */
 
 static inline void rcu_barrier_bh(void)
 {
@@ -83,6 +79,12 @@ static inline void synchronize_sched_expedited(void)
 	synchronize_sched();
 }
 
+static inline void kfree_call_rcu(struct rcu_head *head,
+				  void (*func)(struct rcu_head *rcu))
+{
+	call_rcu(head, func);
+}
+
 #ifdef CONFIG_TINY_RCU
 
 static inline void rcu_preempt_note_context_switch(void)
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 6745846..e8ee5dd 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -61,6 +61,24 @@ extern void synchronize_rcu_bh(void);
 extern void synchronize_sched_expedited(void);
 extern void synchronize_rcu_expedited(void);
 
+void kfree_call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
+
+/**
+ * synchronize_rcu_bh_expedited - Brute-force RCU-bh grace period
+ *
+ * Wait for an RCU-bh grace period to elapse, but use a "big hammer"
+ * approach to force the grace period to end quickly.  This consumes
+ * significant time on all CPUs and is unfriendly to real-time workloads,
+ * so is thus not recommended for any sort of common-case code.  In fact,
+ * if you are using synchronize_rcu_bh_expedited() in a loop, please
+ * restructure your code to batch your updates, and then use a single
+ * synchronize_rcu_bh() instead.
+ *
+ * Note that it is illegal to call this function while holding any lock
+ * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
+ * to call this function from a CPU-hotplug notifier.  Failing to observe
+ * these restriction will result in deadlock.
+ */
 static inline void synchronize_rcu_bh_expedited(void)
 {
 	synchronize_sched_expedited();
@@ -83,6 +101,7 @@ extern void rcu_sched_force_quiescent_state(void);
 /* A context switch is a grace period for RCU-sched and RCU-bh. */
 static inline int rcu_blocking_is_gp(void)
 {
+	might_sleep();  /* Check for RCU read-side critical section. */
 	return num_online_cpus() == 1;
 }
 
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index eb93921..df9ffcc 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -16,6 +16,8 @@
 #include <linux/device.h>
 #include <linux/list.h>
 
+#ifdef CONFIG_REGMAP
+
 struct module;
 struct i2c_client;
 struct spi_device;
@@ -44,6 +46,7 @@ struct reg_default {
  * Configuration for the register map of a device.
  *
  * @reg_bits: Number of bits in a register address, mandatory.
+ * @pad_bits: Number of bits of padding between register and value.
  * @val_bits: Number of bits in a register value, mandatory.
  *
  * @writeable_reg: Optional callback returning true if the register
@@ -74,6 +77,7 @@ struct reg_default {
  */
 struct regmap_config {
 	int reg_bits;
+	int pad_bits;
 	int val_bits;
 
 	bool (*writeable_reg)(struct device *dev, unsigned int reg);
@@ -127,12 +131,22 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c,
 struct regmap *regmap_init_spi(struct spi_device *dev,
 			       const struct regmap_config *config);
 
+struct regmap *devm_regmap_init(struct device *dev,
+				const struct regmap_bus *bus,
+				const struct regmap_config *config);
+struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
+				    const struct regmap_config *config);
+struct regmap *devm_regmap_init_spi(struct spi_device *dev,
+				    const struct regmap_config *config);
+
 void regmap_exit(struct regmap *map);
 int regmap_reinit_cache(struct regmap *map,
 			const struct regmap_config *config);
 int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
 int regmap_raw_write(struct regmap *map, unsigned int reg,
 		     const void *val, size_t val_len);
+int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
+			size_t val_count);
 int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
 int regmap_raw_read(struct regmap *map, unsigned int reg,
 		    void *val, size_t val_len);
@@ -143,12 +157,16 @@ int regmap_update_bits(struct regmap *map, unsigned int reg,
 int regmap_update_bits_check(struct regmap *map, unsigned int reg,
 			     unsigned int mask, unsigned int val,
 			     bool *change);
+int regmap_get_val_bytes(struct regmap *map);
 
 int regcache_sync(struct regmap *map);
 void regcache_cache_only(struct regmap *map, bool enable);
 void regcache_cache_bypass(struct regmap *map, bool enable);
 void regcache_mark_dirty(struct regmap *map);
 
+int regmap_register_patch(struct regmap *map, const struct reg_default *regs,
+			  int num_regs);
+
 /**
  * Description of an IRQ for the generic regmap irq_chip.
  *
@@ -197,4 +215,108 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *data);
 int regmap_irq_chip_get_base(struct regmap_irq_chip_data *data);
 
+#else
+
+/*
+ * These stubs should only ever be called by generic code which has
+ * regmap based facilities, if they ever get called at runtime
+ * something is going wrong and something probably needs to select
+ * REGMAP.
+ */
+
+static inline int regmap_write(struct regmap *map, unsigned int reg,
+			       unsigned int val)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_raw_write(struct regmap *map, unsigned int reg,
+				   const void *val, size_t val_len)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_bulk_write(struct regmap *map, unsigned int reg,
+				    const void *val, size_t val_count)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_read(struct regmap *map, unsigned int reg,
+			      unsigned int *val)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_raw_read(struct regmap *map, unsigned int reg,
+				  void *val, size_t val_len)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_bulk_read(struct regmap *map, unsigned int reg,
+				   void *val, size_t val_count)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_update_bits(struct regmap *map, unsigned int reg,
+				     unsigned int mask, unsigned int val)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_update_bits_check(struct regmap *map,
+					   unsigned int reg,
+					   unsigned int mask, unsigned int val,
+					   bool *change)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regmap_get_val_bytes(struct regmap *map)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline int regcache_sync(struct regmap *map)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+static inline void regcache_cache_only(struct regmap *map, bool enable)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+}
+
+static inline void regcache_cache_bypass(struct regmap *map, bool enable)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+}
+
+static inline void regcache_mark_dirty(struct regmap *map)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+}
+
+static inline int regmap_register_patch(struct regmap *map,
+					const struct reg_default *regs,
+					int num_regs)
+{
+	WARN_ONCE(1, "regmap API is disabled");
+	return -EINVAL;
+}
+
+#endif
+
 #endif
diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h
index 76579f9..7bd73bb 100644
--- a/include/linux/regulator/ab8500.h
+++ b/include/linux/regulator/ab8500.h
@@ -26,7 +26,26 @@ enum ab8500_regulator_id {
 	AB8500_NUM_REGULATORS,
 };
 
-/* AB8500 register initialization */
+/* AB9450 regulators */
+enum ab9540_regulator_id {
+	AB9540_LDO_AUX1,
+	AB9540_LDO_AUX2,
+	AB9540_LDO_AUX3,
+	AB9540_LDO_AUX4,
+	AB9540_LDO_INTCORE,
+	AB9540_LDO_TVOUT,
+	AB9540_LDO_USB,
+	AB9540_LDO_AUDIO,
+	AB9540_LDO_ANAMIC1,
+	AB9540_LDO_ANAMIC2,
+	AB9540_LDO_DMIC,
+	AB9540_LDO_ANA,
+	AB9540_SYSCLKREQ_2,
+	AB9540_SYSCLKREQ_4,
+	AB9540_NUM_REGULATORS,
+};
+
+/* AB8500 and AB9540 register initialization */
 struct ab8500_regulator_reg_init {
 	int id;
 	u8 value;
@@ -71,4 +90,53 @@ enum ab8500_regulator_reg {
 	AB8500_NUM_REGULATOR_REGISTERS,
 };
 
+
+/* AB9540 registers */
+enum ab9540_regulator_reg {
+	AB9540_REGUREQUESTCTRL1,
+	AB9540_REGUREQUESTCTRL2,
+	AB9540_REGUREQUESTCTRL3,
+	AB9540_REGUREQUESTCTRL4,
+	AB9540_REGUSYSCLKREQ1HPVALID1,
+	AB9540_REGUSYSCLKREQ1HPVALID2,
+	AB9540_REGUHWHPREQ1VALID1,
+	AB9540_REGUHWHPREQ1VALID2,
+	AB9540_REGUHWHPREQ2VALID1,
+	AB9540_REGUHWHPREQ2VALID2,
+	AB9540_REGUSWHPREQVALID1,
+	AB9540_REGUSWHPREQVALID2,
+	AB9540_REGUSYSCLKREQVALID1,
+	AB9540_REGUSYSCLKREQVALID2,
+	AB9540_REGUVAUX4REQVALID,
+	AB9540_REGUMISC1,
+	AB9540_VAUDIOSUPPLY,
+	AB9540_REGUCTRL1VAMIC,
+	AB9540_VSMPS1REGU,
+	AB9540_VSMPS2REGU,
+	AB9540_VSMPS3REGU, /* NOTE! PRCMU register */
+	AB9540_VPLLVANAREGU,
+	AB9540_EXTSUPPLYREGU,
+	AB9540_VAUX12REGU,
+	AB9540_VRF1VAUX3REGU,
+	AB9540_VSMPS1SEL1,
+	AB9540_VSMPS1SEL2,
+	AB9540_VSMPS1SEL3,
+	AB9540_VSMPS2SEL1,
+	AB9540_VSMPS2SEL2,
+	AB9540_VSMPS2SEL3,
+	AB9540_VSMPS3SEL1, /* NOTE! PRCMU register */
+	AB9540_VSMPS3SEL2, /* NOTE! PRCMU register */
+	AB9540_VAUX1SEL,
+	AB9540_VAUX2SEL,
+	AB9540_VRF1VAUX3SEL,
+	AB9540_REGUCTRL2SPARE,
+	AB9540_VAUX4REQCTRL,
+	AB9540_VAUX4REGU,
+	AB9540_VAUX4SEL,
+	AB9540_REGUCTRLDISCH,
+	AB9540_REGUCTRLDISCH2,
+	AB9540_REGUCTRLDISCH3,
+	AB9540_NUM_REGULATOR_REGISTERS,
+};
+
 #endif
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index f2698a0..b6c8d71 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -132,9 +132,12 @@ struct regulator_bulk_data {
 /* regulator get and put */
 struct regulator *__must_check regulator_get(struct device *dev,
 					     const char *id);
+struct regulator *__must_check devm_regulator_get(struct device *dev,
+					     const char *id);
 struct regulator *__must_check regulator_get_exclusive(struct device *dev,
 						       const char *id);
 void regulator_put(struct regulator *regulator);
+void devm_regulator_put(struct regulator *regulator);
 
 /* regulator output control and status */
 int regulator_enable(struct regulator *regulator);
@@ -145,6 +148,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms);
 
 int regulator_bulk_get(struct device *dev, int num_consumers,
 		       struct regulator_bulk_data *consumers);
+int devm_regulator_bulk_get(struct device *dev, int num_consumers,
+			    struct regulator_bulk_data *consumers);
 int regulator_bulk_enable(int num_consumers,
 			  struct regulator_bulk_data *consumers);
 int regulator_bulk_disable(int num_consumers,
@@ -200,10 +205,21 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
 	 */
 	return NULL;
 }
+
+static inline struct regulator *__must_check
+devm_regulator_get(struct device *dev, const char *id)
+{
+	return NULL;
+}
+
 static inline void regulator_put(struct regulator *regulator)
 {
 }
 
+static inline void devm_regulator_put(struct regulator *regulator)
+{
+}
+
 static inline int regulator_enable(struct regulator *regulator)
 {
 	return 0;
@@ -237,6 +253,12 @@ static inline int regulator_bulk_get(struct device *dev,
 	return 0;
 }
 
+static inline int devm_regulator_bulk_get(struct device *dev, int num_consumers,
+					  struct regulator_bulk_data *consumers)
+{
+	return 0;
+}
+
 static inline int regulator_bulk_enable(int num_consumers,
 					struct regulator_bulk_data *consumers)
 {
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 4214b9a..fa8b55b 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -104,7 +104,7 @@ struct regulator_ops {
 	int (*disable) (struct regulator_dev *);
 	int (*is_enabled) (struct regulator_dev *);
 
-	/* get/set regulator operating mode (defined in regulator.h) */
+	/* get/set regulator operating mode (defined in consumer.h) */
 	int (*set_mode) (struct regulator_dev *, unsigned int mode);
 	unsigned int (*get_mode) (struct regulator_dev *);
 
@@ -135,7 +135,7 @@ struct regulator_ops {
 	int (*set_suspend_enable) (struct regulator_dev *);
 	int (*set_suspend_disable) (struct regulator_dev *);
 
-	/* set regulator suspend operating mode (defined in regulator.h) */
+	/* set regulator suspend operating mode (defined in consumer.h) */
 	int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
 };
 
@@ -207,9 +207,7 @@ struct regulator_dev {
 
 	void *reg_data;		/* regulator_dev data */
 
-#ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs;
-#endif
 };
 
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index f3f13fd..7abb160 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -139,12 +139,10 @@ struct regulation_constraints {
  * make struct device available late such as I2C and is the preferred
  * form.
  *
- * @dev: Device structure for the consumer.
  * @dev_name: Result of dev_name() for the consumer.
  * @supply: Name for the supply.
  */
 struct regulator_consumer_supply {
-	struct device *dev;	/* consumer */
 	const char *dev_name;   /* dev_name() for consumer */
 	const char *supply;	/* consumer supply - e.g. "vcc" */
 };
diff --git a/include/linux/regulator/tps62360.h b/include/linux/regulator/tps62360.h
new file mode 100644
index 0000000..6a5c1b2
--- /dev/null
+++ b/include/linux/regulator/tps62360.h
@@ -0,0 +1,57 @@
+/*
+ * tps62360.h -- TI tps62360
+ *
+ * Interface for regulator driver for TI TPS62360 Processor core supply
+ *
+ * Copyright (C) 2012 NVIDIA Corporation
+
+ * Author: Laxman Dewangan <ldewangan@nvidia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA	02110-1301, USA.
+ *
+ */
+
+#ifndef __LINUX_REGULATOR_TPS62360_H
+#define __LINUX_REGULATOR_TPS62360_H
+
+#include <linux/regulator/machine.h>
+
+/*
+ * struct tps62360_regulator_platform_data - tps62360 regulator platform data.
+ *
+ * @reg_init_data: The regulator init data.
+ * @en_force_pwm: Enable force pwm or not.
+ * @en_discharge: Enable discharge the output capacitor via internal
+ *                register.
+ * @en_internal_pulldn: internal pull down enable or not.
+ * @vsel0_gpio: Gpio number for vsel0. It should be -1 if this is tied with
+ *              fixed logic.
+ * @vsel1_gpio: Gpio number for vsel1. It should be -1 if this is tied with
+ *              fixed logic.
+ * @vsel0_def_state: Default state of vsel0. 1 if it is high else 0.
+ * @vsel1_def_state: Default state of vsel1. 1 if it is high else 0.
+ */
+struct tps62360_regulator_platform_data {
+	struct regulator_init_data reg_init_data;
+	bool en_force_pwm;
+	bool en_discharge;
+	bool en_internal_pulldn;
+	int vsel0_gpio;
+	int vsel1_gpio;
+	int vsel0_def_state;
+	int vsel1_def_state;
+};
+
+#endif /* __LINUX_REGULATOR_TPS62360_H */
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
new file mode 100644
index 0000000..ada4cb0
--- /dev/null
+++ b/include/linux/remoteproc.h
@@ -0,0 +1,271 @@
+/*
+ * Remote Processor Framework
+ *
+ * Copyright(c) 2011 Texas Instruments, Inc.
+ * Copyright(c) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef REMOTEPROC_H
+#define REMOTEPROC_H
+
+#include <linux/types.h>
+#include <linux/kref.h>
+#include <linux/klist.h>
+#include <linux/mutex.h>
+#include <linux/virtio.h>
+#include <linux/completion.h>
+
+/*
+ * The alignment between the consumer and producer parts of the vring.
+ * Note: this is part of the "wire" protocol. If you change this, you need
+ * to update your peers too.
+ */
+#define AMP_VRING_ALIGN	(4096)
+
+/**
+ * struct fw_resource - describes an entry from the resource section
+ * @type: resource type
+ * @id: index number of the resource
+ * @da: device address of the resource
+ * @pa: physical address of the resource
+ * @len: size, in bytes, of the resource
+ * @flags: properties of the resource, e.g. iommu protection required
+ * @reserved: must be 0 atm
+ * @name: name of resource
+ *
+ * The remote processor firmware should contain a "resource table":
+ * array of 'struct fw_resource' entries.
+ *
+ * Some resources entries are mere announcements, where the host is informed
+ * of specific remoteproc configuration. Other entries require the host to
+ * do something (e.g. reserve a requested resource) and possibly also reply
+ * by overwriting a member inside 'struct fw_resource' with info about the
+ * allocated resource.
+ *
+ * Different resource entries use different members of this struct,
+ * with different meanings. This is pretty limiting and error-prone,
+ * so the plan is to move to variable-length TLV-based resource entries,
+ * where each resource type will have its own structure.
+ */
+struct fw_resource {
+	u32 type;
+	u32 id;
+	u64 da;
+	u64 pa;
+	u32 len;
+	u32 flags;
+	u8 reserved[16];
+	u8 name[48];
+} __packed;
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT:   request for allocation of a physically contiguous
+ *		    memory region.
+ * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE:	    announces the availability of a trace buffer into which
+ *		    the remote processor will be writing logs. In this case,
+ *		    'da' indicates the device address where logs are written to,
+ *		    and 'len' is the size of the trace buffer.
+ * @RSC_VRING:	    request for allocation of a virtio vring (address should
+ *		    be indicated in 'da', and 'len' should contain the number
+ *		    of buffers supported by the vring).
+ * @RSC_VIRTIO_DEV: this entry declares about support for a virtio device,
+ *		    and serves as the virtio header. 'da' holds the
+ *		    the virtio device features, 'pa' holds the virtio guest
+ *		    features, 'len' holds the virtio status, and 'flags' holds
+ *		    the virtio id (currently only VIRTIO_ID_RPMSG is supported).
+ * @RSC_LAST:       just keep this one at the end
+ *
+ * Most of the resource entries share the basic idea of address/length
+ * negotiation with the host: the firmware usually asks (on behalf of the
+ * remote processor that will soon be booted with it) for memory
+ * of size 'len' bytes, and the host needs to allocate it and provide
+ * the device/physical address (when relevant) in 'da'/'pa' respectively.
+ *
+ * If the firmware is compiled with hard coded device addresses, and
+ * can't handle dynamically allocated 'da' values, then the 'da' field
+ * will contain the expected device addresses (today we actually only support
+ * this scheme, as there aren't yet any use cases for dynamically allocated
+ * device addresses).
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+	RSC_CARVEOUT	= 0,
+	RSC_DEVMEM	= 1,
+	RSC_TRACE	= 2,
+	RSC_VRING	= 3,
+	RSC_VIRTIO_DEV	= 4,
+	RSC_LAST	= 5,
+};
+
+/**
+ * struct rproc_mem_entry - memory entry descriptor
+ * @va:	virtual address
+ * @dma: dma address
+ * @len: length, in bytes
+ * @da: device address
+ * @priv: associated data
+ * @node: list node
+ */
+struct rproc_mem_entry {
+	void *va;
+	dma_addr_t dma;
+	int len;
+	u64 da;
+	void *priv;
+	struct list_head node;
+};
+
+struct rproc;
+
+/**
+ * struct rproc_ops - platform-specific device handlers
+ * @start:	power on the device and boot it
+ * @stop:	power off the device
+ * @kick:	kick a virtqueue (virtqueue id given as a parameter)
+ */
+struct rproc_ops {
+	int (*start)(struct rproc *rproc);
+	int (*stop)(struct rproc *rproc);
+	void (*kick)(struct rproc *rproc, int vqid);
+};
+
+/**
+ * enum rproc_state - remote processor states
+ * @RPROC_OFFLINE:	device is powered off
+ * @RPROC_SUSPENDED:	device is suspended; needs to be woken up to receive
+ *			a message.
+ * @RPROC_RUNNING:	device is up and running
+ * @RPROC_CRASHED:	device has crashed; need to start recovery
+ * @RPROC_LAST:		just keep this one at the end
+ *
+ * Please note that the values of these states are used as indices
+ * to rproc_state_string, a state-to-name lookup table,
+ * so please keep the two synchronized. @RPROC_LAST is used to check
+ * the validity of an index before the lookup table is accessed, so
+ * please update it as needed too.
+ */
+enum rproc_state {
+	RPROC_OFFLINE	= 0,
+	RPROC_SUSPENDED	= 1,
+	RPROC_RUNNING	= 2,
+	RPROC_CRASHED	= 3,
+	RPROC_LAST	= 4,
+};
+
+/**
+ * struct rproc - represents a physical remote processor device
+ * @node: klist node of this rproc object
+ * @domain: iommu domain
+ * @name: human readable name of the rproc
+ * @firmware: name of firmware file to be loaded
+ * @priv: private data which belongs to the platform-specific rproc module
+ * @ops: platform-specific start/stop rproc handlers
+ * @dev: underlying device
+ * @refcount: refcount of users that have a valid pointer to this rproc
+ * @power: refcount of users who need this rproc powered up
+ * @state: state of the device
+ * @lock: lock which protects concurrent manipulations of the rproc
+ * @dbg_dir: debugfs directory of this rproc device
+ * @traces: list of trace buffers
+ * @num_traces: number of trace buffers
+ * @carveouts: list of physically contiguous memory allocations
+ * @mappings: list of iommu mappings we initiated, needed on shutdown
+ * @firmware_loading_complete: marks e/o asynchronous firmware loading
+ * @bootaddr: address of first instruction to boot rproc with (optional)
+ * @rvdev: virtio device (we only support a single rpmsg virtio device for now)
+ */
+struct rproc {
+	struct klist_node node;
+	struct iommu_domain *domain;
+	const char *name;
+	const char *firmware;
+	void *priv;
+	const struct rproc_ops *ops;
+	struct device *dev;
+	struct kref refcount;
+	atomic_t power;
+	unsigned int state;
+	struct mutex lock;
+	struct dentry *dbg_dir;
+	struct list_head traces;
+	int num_traces;
+	struct list_head carveouts;
+	struct list_head mappings;
+	struct completion firmware_loading_complete;
+	u64 bootaddr;
+	struct rproc_vdev *rvdev;
+};
+
+/**
+ * struct rproc_vdev - remoteproc state for a supported virtio device
+ * @rproc: the rproc handle
+ * @vdev: the virio device
+ * @vq: the virtqueues for this vdev
+ * @vring: the vrings for this vdev
+ * @dfeatures: virtio device features
+ * @gfeatures: virtio guest features
+ */
+struct rproc_vdev {
+	struct rproc *rproc;
+	struct virtio_device vdev;
+	struct virtqueue *vq[2];
+	struct rproc_mem_entry vring[2];
+	unsigned long dfeatures;
+	unsigned long gfeatures;
+};
+
+struct rproc *rproc_get_by_name(const char *name);
+void rproc_put(struct rproc *rproc);
+
+struct rproc *rproc_alloc(struct device *dev, const char *name,
+				const struct rproc_ops *ops,
+				const char *firmware, int len);
+void rproc_free(struct rproc *rproc);
+int rproc_register(struct rproc *rproc);
+int rproc_unregister(struct rproc *rproc);
+
+int rproc_boot(struct rproc *rproc);
+void rproc_shutdown(struct rproc *rproc);
+
+static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev)
+{
+	struct rproc_vdev *rvdev = container_of(vdev, struct rproc_vdev, vdev);
+
+	return rvdev->rproc;
+}
+
+#endif /* REMOTEPROC_H */
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h
new file mode 100644
index 0000000..a8e50e4
--- /dev/null
+++ b/include/linux/rpmsg.h
@@ -0,0 +1,326 @@
+/*
+ * Remote processor messaging
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_RPMSG_H
+#define _LINUX_RPMSG_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+/* The feature bitmap for virtio rpmsg */
+#define VIRTIO_RPMSG_F_NS	0 /* RP supports name service notifications */
+
+/**
+ * struct rpmsg_hdr - common header for all rpmsg messages
+ * @src: source address
+ * @dst: destination address
+ * @reserved: reserved for future use
+ * @len: length of payload (in bytes)
+ * @flags: message flags
+ * @data: @len bytes of message payload data
+ *
+ * Every message sent(/received) on the rpmsg bus begins with this header.
+ */
+struct rpmsg_hdr {
+	u32 src;
+	u32 dst;
+	u32 reserved;
+	u16 len;
+	u16 flags;
+	u8 data[0];
+} __packed;
+
+/**
+ * struct rpmsg_ns_msg - dynamic name service announcement message
+ * @name: name of remote service that is published
+ * @addr: address of remote service that is published
+ * @flags: indicates whether service is created or destroyed
+ *
+ * This message is sent across to publish a new service, or announce
+ * about its removal. When we receive these messages, an appropriate
+ * rpmsg channel (i.e device) is created/destroyed. In turn, the ->probe()
+ * or ->remove() handler of the appropriate rpmsg driver will be invoked
+ * (if/as-soon-as one is registered).
+ */
+struct rpmsg_ns_msg {
+	char name[RPMSG_NAME_SIZE];
+	u32 addr;
+	u32 flags;
+} __packed;
+
+/**
+ * enum rpmsg_ns_flags - dynamic name service announcement flags
+ *
+ * @RPMSG_NS_CREATE: a new remote service was just created
+ * @RPMSG_NS_DESTROY: a known remote service was just destroyed
+ */
+enum rpmsg_ns_flags {
+	RPMSG_NS_CREATE		= 0,
+	RPMSG_NS_DESTROY	= 1,
+};
+
+#define RPMSG_ADDR_ANY		0xFFFFFFFF
+
+struct virtproc_info;
+
+/**
+ * rpmsg_channel - devices that belong to the rpmsg bus are called channels
+ * @vrp: the remote processor this channel belongs to
+ * @dev: the device struct
+ * @id: device id (used to match between rpmsg drivers and devices)
+ * @src: local address
+ * @dst: destination address
+ * @ept: the rpmsg endpoint of this channel
+ * @announce: if set, rpmsg will announce the creation/removal of this channel
+ */
+struct rpmsg_channel {
+	struct virtproc_info *vrp;
+	struct device dev;
+	struct rpmsg_device_id id;
+	u32 src;
+	u32 dst;
+	struct rpmsg_endpoint *ept;
+	bool announce;
+};
+
+typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, u32);
+
+/**
+ * struct rpmsg_endpoint - binds a local rpmsg address to its user
+ * @rpdev: rpmsg channel device
+ * @cb: rx callback handler
+ * @addr: local rpmsg address
+ * @priv: private data for the driver's use
+ *
+ * In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
+ * it binds an rpmsg address with an rx callback handler.
+ *
+ * Simple rpmsg drivers shouldn't use this struct directly, because
+ * things just work: every rpmsg driver provides an rx callback upon
+ * registering to the bus, and that callback is then bound to its rpmsg
+ * address when the driver is probed. When relevant inbound messages arrive
+ * (i.e. messages which their dst address equals to the src address of
+ * the rpmsg channel), the driver's handler is invoked to process it.
+ *
+ * More complicated drivers though, that do need to allocate additional rpmsg
+ * addresses, and bind them to different rx callbacks, must explicitly
+ * create additional endpoints by themselves (see rpmsg_create_ept()).
+ */
+struct rpmsg_endpoint {
+	struct rpmsg_channel *rpdev;
+	rpmsg_rx_cb_t cb;
+	u32 addr;
+	void *priv;
+};
+
+/**
+ * struct rpmsg_driver - rpmsg driver struct
+ * @drv: underlying device driver
+ * @id_table: rpmsg ids serviced by this driver
+ * @probe: invoked when a matching rpmsg channel (i.e. device) is found
+ * @remove: invoked when the rpmsg channel is removed
+ * @callback: invoked when an inbound message is received on the channel
+ */
+struct rpmsg_driver {
+	struct device_driver drv;
+	const struct rpmsg_device_id *id_table;
+	int (*probe)(struct rpmsg_channel *dev);
+	void (*remove)(struct rpmsg_channel *dev);
+	void (*callback)(struct rpmsg_channel *, void *, int, void *, u32);
+};
+
+int register_rpmsg_device(struct rpmsg_channel *dev);
+void unregister_rpmsg_device(struct rpmsg_channel *dev);
+int register_rpmsg_driver(struct rpmsg_driver *drv);
+void unregister_rpmsg_driver(struct rpmsg_driver *drv);
+void rpmsg_destroy_ept(struct rpmsg_endpoint *);
+struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *,
+				rpmsg_rx_cb_t cb, void *priv, u32 addr);
+int
+rpmsg_send_offchannel_raw(struct rpmsg_channel *, u32, u32, void *, int, bool);
+
+/**
+ * rpmsg_send() - send a message across to the remote processor
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len on the @rpdev channel.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source and destination addresses.
+ * In case there are no TX buffers available, the function will block until
+ * one becomes available, or a timeout of 15 seconds elapses. When the latter
+ * happens, -ERESTARTSYS is returned.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len)
+{
+	u32 src = rpdev->src, dst = rpdev->dst;
+
+	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
+}
+
+/**
+ * rpmsg_sendto() - send a message across to the remote processor, specify dst
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ * @dst: destination address
+ *
+ * This function sends @data of length @len to the remote @dst address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source address.
+ * In case there are no TX buffers available, the function will block until
+ * one becomes available, or a timeout of 15 seconds elapses. When the latter
+ * happens, -ERESTARTSYS is returned.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
+{
+	u32 src = rpdev->src;
+
+	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
+}
+
+/**
+ * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
+ * @rpdev: the rpmsg channel
+ * @src: source address
+ * @dst: destination address
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len to the remote @dst address,
+ * and uses @src as the source address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to.
+ * In case there are no TX buffers available, the function will block until
+ * one becomes available, or a timeout of 15 seconds elapses. When the latter
+ * happens, -ERESTARTSYS is returned.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+							void *data, int len)
+{
+	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true);
+}
+
+/**
+ * rpmsg_send() - send a message across to the remote processor
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len on the @rpdev channel.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source and destination addresses.
+ * In case there are no TX buffers available, the function will immediately
+ * return -ENOMEM without waiting until one becomes available.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len)
+{
+	u32 src = rpdev->src, dst = rpdev->dst;
+
+	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
+}
+
+/**
+ * rpmsg_sendto() - send a message across to the remote processor, specify dst
+ * @rpdev: the rpmsg channel
+ * @data: payload of message
+ * @len: length of payload
+ * @dst: destination address
+ *
+ * This function sends @data of length @len to the remote @dst address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to, using @rpdev's source address.
+ * In case there are no TX buffers available, the function will immediately
+ * return -ENOMEM without waiting until one becomes available.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst)
+{
+	u32 src = rpdev->src;
+
+	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
+}
+
+/**
+ * rpmsg_send_offchannel() - send a message using explicit src/dst addresses
+ * @rpdev: the rpmsg channel
+ * @src: source address
+ * @dst: destination address
+ * @data: payload of message
+ * @len: length of payload
+ *
+ * This function sends @data of length @len to the remote @dst address,
+ * and uses @src as the source address.
+ * The message will be sent to the remote processor which the @rpdev
+ * channel belongs to.
+ * In case there are no TX buffers available, the function will immediately
+ * return -ENOMEM without waiting until one becomes available.
+ *
+ * Can only be called from process context (for now).
+ *
+ * Returns 0 on success and an appropriate error value on failure.
+ */
+static inline
+int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst,
+							void *data, int len)
+{
+	return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false);
+}
+
+#endif /* _LINUX_RPMSG_H */
diff --git a/include/linux/sa11x0-dma.h b/include/linux/sa11x0-dma.h
new file mode 100644
index 0000000..65839a5
--- /dev/null
+++ b/include/linux/sa11x0-dma.h
@@ -0,0 +1,24 @@
+/*
+ * SA11x0 DMA Engine support
+ *
+ * Copyright (C) 2012 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_SA11X0_DMA_H
+#define __LINUX_SA11X0_DMA_H
+
+struct dma_chan;
+
+#if defined(CONFIG_DMA_SA11X0) || defined(CONFIG_DMA_SA11X0_MODULE)
+bool sa11x0_dma_filter_fn(struct dma_chan *, void *);
+#else
+static inline bool sa11x0_dma_filter_fn(struct dma_chan *c, void *d)
+{
+	return false;
+}
+#endif
+
+#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 7d379a6..779e2f2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -552,6 +552,18 @@ struct signal_struct {
 	int			group_stop_count;
 	unsigned int		flags; /* see SIGNAL_* flags below */
 
+	/*
+	 * PR_SET_CHILD_SUBREAPER marks a process, like a service
+	 * manager, to re-parent orphan (double-forking) child processes
+	 * to this process instead of 'init'. The service manager is
+	 * able to receive SIGCHLD signals and is able to investigate
+	 * the process until it calls wait(). All children of this
+	 * process will inherit a flag if they should look for a
+	 * child_subreaper process at exit.
+	 */
+	unsigned int		is_child_subreaper:1;
+	unsigned int		has_child_subreaper:1;
+
 	/* POSIX.1b Interval Timers */
 	struct list_head posix_timers;
 
@@ -905,6 +917,7 @@ struct sched_group_power {
 	 * single CPU.
 	 */
 	unsigned int power, power_orig;
+	unsigned long next_update;
 	/*
 	 * Number of busy cpus in this group.
 	 */
@@ -1052,6 +1065,8 @@ static inline int test_sd_parent(struct sched_domain *sd, int flag)
 unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu);
 unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu);
 
+bool cpus_share_cache(int this_cpu, int that_cpu);
+
 #else /* CONFIG_SMP */
 
 struct sched_domain_attr;
@@ -1061,6 +1076,12 @@ partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
 			struct sched_domain_attr *dattr_new)
 {
 }
+
+static inline bool cpus_share_cache(int this_cpu, int that_cpu)
+{
+	return true;
+}
+
 #endif	/* !CONFIG_SMP */
 
 
@@ -1590,6 +1611,10 @@ struct task_struct {
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 	atomic_t ptrace_bp_refcnt;
 #endif
+#ifdef CONFIG_UPROBES
+	struct uprobe_task *utask;
+	int uprobes_srcu_id;
+#endif
 };
 
 /* Future-safe accessor for struct task_struct's cpus_allowed. */
@@ -1864,8 +1889,7 @@ extern void task_clear_jobctl_pending(struct task_struct *task,
 #ifdef CONFIG_PREEMPT_RCU
 
 #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */
-#define RCU_READ_UNLOCK_BOOSTED (1 << 1) /* boosted while in RCU read-side. */
-#define RCU_READ_UNLOCK_NEED_QS (1 << 2) /* RCU core needs CPU response. */
+#define RCU_READ_UNLOCK_NEED_QS (1 << 1) /* RCU core needs CPU response. */
 
 static inline void rcu_copy_process(struct task_struct *p)
 {
@@ -2390,12 +2414,15 @@ static inline void task_unlock(struct task_struct *p)
 extern struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
 							unsigned long *flags);
 
-#define lock_task_sighand(tsk, flags)					\
-({	struct sighand_struct *__ss;					\
-	__cond_lock(&(tsk)->sighand->siglock,				\
-		    (__ss = __lock_task_sighand(tsk, flags)));		\
-	__ss;								\
-})									\
+static inline struct sighand_struct *lock_task_sighand(struct task_struct *tsk,
+						       unsigned long *flags)
+{
+	struct sighand_struct *ret;
+
+	ret = __lock_task_sighand(tsk, flags);
+	(void)__cond_lock(&tsk->sighand->siglock, ret);
+	return ret;
+}
 
 static inline void unlock_task_sighand(struct task_struct *tsk,
 						unsigned long *flags)
diff --git a/include/linux/security.h b/include/linux/security.h
index 83c18e8..339b3b1 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -22,22 +22,36 @@
 #ifndef __LINUX_SECURITY_H
 #define __LINUX_SECURITY_H
 
-#include <linux/fs.h>
-#include <linux/fsnotify.h>
-#include <linux/binfmts.h>
-#include <linux/dcache.h>
-#include <linux/signal.h>
-#include <linux/resource.h>
-#include <linux/sem.h>
-#include <linux/shm.h>
-#include <linux/mm.h> /* PAGE_ALIGN */
-#include <linux/msg.h>
-#include <linux/sched.h>
 #include <linux/key.h>
-#include <linux/xfrm.h>
+#include <linux/capability.h>
 #include <linux/slab.h>
-#include <linux/xattr.h>
-#include <net/flow.h>
+#include <linux/err.h>
+
+struct linux_binprm;
+struct cred;
+struct rlimit;
+struct siginfo;
+struct sem_array;
+struct sembuf;
+struct kern_ipc_perm;
+struct audit_context;
+struct super_block;
+struct inode;
+struct dentry;
+struct file;
+struct vfsmount;
+struct path;
+struct qstr;
+struct nameidata;
+struct iattr;
+struct fown_struct;
+struct file_operations;
+struct shmid_kernel;
+struct msg_msg;
+struct msg_queue;
+struct xattr;
+struct xfrm_sec_ctx;
+struct mm_struct;
 
 /* Maximum number of letters for an LSM name string */
 #define SECURITY_NAME_MAX	10
@@ -49,6 +63,7 @@
 struct ctl_table;
 struct audit_krule;
 struct user_namespace;
+struct timezone;
 
 /*
  * These functions are in security/capability.c and are used
@@ -131,18 +146,6 @@ struct request_sock;
 #define LSM_UNSAFE_PTRACE_CAP	4
 
 #ifdef CONFIG_MMU
-/*
- * If a hint addr is less than mmap_min_addr change hint to be as
- * low as possible but still greater than mmap_min_addr
- */
-static inline unsigned long round_hint_to_min(unsigned long hint)
-{
-	hint &= PAGE_MASK;
-	if (((void *)hint != NULL) &&
-	    (hint < mmap_min_addr))
-		return PAGE_ALIGN(mmap_min_addr);
-	return hint;
-}
 extern int mmap_min_addr_handler(struct ctl_table *table, int write,
 				 void __user *buffer, size_t *lenp, loff_t *ppos);
 #endif
@@ -651,6 +654,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *	manual page for definitions of the @clone_flags.
  *	@clone_flags contains the flags indicating what should be shared.
  *	Return 0 if permission is granted.
+ * @task_free:
+ *	@task task being freed
+ *	Handle release of task-related resources. (Note that this can be called
+ *	from interrupt context.)
  * @cred_alloc_blank:
  *	@cred points to the credentials.
  *	@gfp indicates the atomicity of any memory allocations.
@@ -1493,6 +1500,7 @@ struct security_operations {
 	int (*dentry_open) (struct file *file, const struct cred *cred);
 
 	int (*task_create) (unsigned long clone_flags);
+	void (*task_free) (struct task_struct *task);
 	int (*cred_alloc_blank) (struct cred *cred, gfp_t gfp);
 	void (*cred_free) (struct cred *cred);
 	int (*cred_prepare)(struct cred *new, const struct cred *old,
@@ -1674,9 +1682,7 @@ int security_quotactl(int cmds, int type, int id, struct super_block *sb);
 int security_quota_on(struct dentry *dentry);
 int security_syslog(int type);
 int security_settime(const struct timespec *ts, const struct timezone *tz);
-int security_vm_enough_memory(long pages);
 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
-int security_vm_enough_memory_kern(long pages);
 int security_bprm_set_creds(struct linux_binprm *bprm);
 int security_bprm_check(struct linux_binprm *bprm);
 void security_bprm_committing_creds(struct linux_binprm *bprm);
@@ -1752,6 +1758,7 @@ int security_file_send_sigiotask(struct task_struct *tsk,
 int security_file_receive(struct file *file);
 int security_dentry_open(struct file *file, const struct cred *cred);
 int security_task_create(unsigned long clone_flags);
+void security_task_free(struct task_struct *task);
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
 void security_cred_free(struct cred *cred);
 int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
@@ -1896,25 +1903,11 @@ static inline int security_settime(const struct timespec *ts,
 	return cap_settime(ts, tz);
 }
 
-static inline int security_vm_enough_memory(long pages)
-{
-	WARN_ON(current->mm == NULL);
-	return cap_vm_enough_memory(current->mm, pages);
-}
-
 static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
 {
-	WARN_ON(mm == NULL);
 	return cap_vm_enough_memory(mm, pages);
 }
 
-static inline int security_vm_enough_memory_kern(long pages)
-{
-	/* If current->mm is a kernel thread then we will pass NULL,
-	   for this specific case that is fine */
-	return cap_vm_enough_memory(current->mm, pages);
-}
-
 static inline int security_bprm_set_creds(struct linux_binprm *bprm)
 {
 	return cap_bprm_set_creds(bprm);
@@ -2245,6 +2238,9 @@ static inline int security_task_create(unsigned long clone_flags)
 	return 0;
 }
 
+static inline void security_task_free(struct task_struct *task)
+{ }
+
 static inline int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
 	return 0;
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 44f1514..54e5ae7 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -121,9 +121,12 @@ int single_release(struct inode *, struct file *);
 void *__seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_open_private(struct file *, const struct seq_operations *, int);
 int seq_release_private(struct inode *, struct file *);
+int seq_put_decimal_ull(struct seq_file *m, char delimiter,
+			unsigned long long num);
+int seq_put_decimal_ll(struct seq_file *m, char delimiter,
+			long long num);
 
 #define SEQ_START_TOKEN ((void *)1)
-
 /*
  * Helpers for iteration over list_head-s in seq_files
  */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index c91ace7..585bfd0 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -210,6 +210,8 @@
 /* Atheros AR933X SoC */
 #define PORT_AR933X	99
 
+/* Energy Micro efm32 SoC */
+#define PORT_EFMUART   100
 
 #ifdef __KERNEL__
 
diff --git a/include/linux/sh_eth.h b/include/linux/sh_eth.h
index 2076acf..b17d765d 100644
--- a/include/linux/sh_eth.h
+++ b/include/linux/sh_eth.h
@@ -20,6 +20,7 @@ struct sh_eth_plat_data {
 	unsigned char mac_addr[6];
 	unsigned no_ether_link:1;
 	unsigned ether_link_active_low:1;
+	unsigned needs_init:1;
 };
 
 #endif
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index b160645..6aed080 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -3,6 +3,23 @@
 
 #include <linux/ioport.h>
 
+#ifdef CONFIG_SUPERH
+#define INTC_NR_IRQS	512
+#else
+#define INTC_NR_IRQS	1024
+#endif
+
+/*
+ * Convert back and forth between INTEVT and IRQ values.
+ */
+#ifdef CONFIG_CPU_HAS_INTEVT
+#define evt2irq(evt)		(((evt) >> 5) - 16)
+#define irq2evt(irq)		(((irq) + 16) << 5)
+#else
+#define evt2irq(evt)		(evt)
+#define irq2evt(irq)		(irq)
+#endif
+
 typedef unsigned char intc_enum;
 
 struct intc_vect {
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 50db9b0..c11a44e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -438,6 +438,11 @@ struct sk_buff {
 #endif
 
 	int			skb_iif;
+
+	__u32			rxhash;
+
+	__u16			vlan_tci;
+
 #ifdef CONFIG_NET_SCHED
 	__u16			tc_index;	/* traffic control index */
 #ifdef CONFIG_NET_CLS_ACT
@@ -445,8 +450,6 @@ struct sk_buff {
 #endif
 #endif
 
-	__u32			rxhash;
-
 	__u16			queue_mapping;
 	kmemcheck_bitfield_begin(flags2);
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
@@ -470,8 +473,6 @@ struct sk_buff {
 		__u32		dropcount;
 	};
 
-	__u16			vlan_tci;
-
 	sk_buff_data_t		transport_header;
 	sk_buff_data_t		network_header;
 	sk_buff_data_t		mac_header;
@@ -876,6 +877,24 @@ static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
 }
 
 /**
+ *	skb_peek_next - peek skb following the given one from a queue
+ *	@skb: skb to start from
+ *	@list_: list to peek at
+ *
+ *	Returns %NULL when the end of the list is met or a pointer to the
+ *	next element. The reference count is not incremented and the
+ *	reference is therefore volatile. Use with caution.
+ */
+static inline struct sk_buff *skb_peek_next(struct sk_buff *skb,
+		const struct sk_buff_head *list_)
+{
+	struct sk_buff *next = skb->next;
+	if (next == (struct sk_buff *)list_)
+		next = NULL;
+	return next;
+}
+
+/**
  *	skb_peek_tail - peek at the tail of an &sk_buff_head
  *	@list_: list to peek at
  *
@@ -2045,7 +2064,7 @@ static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)
 	for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
 
 extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
-					   int *peeked, int *err);
+					   int *peeked, int *off, int *err);
 extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
 					 int noblock, int *err);
 extern unsigned int    datagram_poll(struct file *file, struct socket *sock,
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 573c809..a595dce 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -190,7 +190,7 @@ size_t ksize(const void *);
 #endif
 
 /**
- * kcalloc - allocate memory for an array. The memory is set to zero.
+ * kmalloc_array - allocate memory for an array.
  * @n: number of elements.
  * @size: element size.
  * @flags: the type of memory to allocate.
@@ -240,11 +240,22 @@ size_t ksize(const void *);
  * for general use, and so are not documented here. For a full list of
  * potential flags, always refer to linux/gfp.h.
  */
-static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
 {
 	if (size != 0 && n > ULONG_MAX / size)
 		return NULL;
-	return __kmalloc(n * size, flags | __GFP_ZERO);
+	return __kmalloc(n * size, flags);
+}
+
+/**
+ * kcalloc - allocate memory for an array. The memory is set to zero.
+ * @n: number of elements.
+ * @size: element size.
+ * @flags: the type of memory to allocate (see kmalloc).
+ */
+static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+{
+	return kmalloc_array(n, size, flags | __GFP_ZERO);
 }
 
 #if !defined(CONFIG_NUMA) && !defined(CONFIG_SLOB)
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index a32bcfd..30bc8b1 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -21,7 +21,7 @@ enum stat_item {
 	FREE_FROZEN,		/* Freeing to frozen slab */
 	FREE_ADD_PARTIAL,	/* Freeing moves slab to partial list */
 	FREE_REMOVE_PARTIAL,	/* Freeing removes last object */
-	ALLOC_FROM_PARTIAL,	/* Cpu slab acquired from partial list */
+	ALLOC_FROM_PARTIAL,	/* Cpu slab acquired from node partial list */
 	ALLOC_SLAB,		/* Cpu slab acquired from page allocator */
 	ALLOC_REFILL,		/* Refill cpu slab from slab freelist */
 	ALLOC_NODE_MISMATCH,	/* Switching cpu slab */
@@ -37,7 +37,9 @@ enum stat_item {
 	CMPXCHG_DOUBLE_CPU_FAIL,/* Failure of this_cpu_cmpxchg_double */
 	CMPXCHG_DOUBLE_FAIL,	/* Number of times that cmpxchg double did not match */
 	CPU_PARTIAL_ALLOC,	/* Used cpu partial on alloc */
-	CPU_PARTIAL_FREE,	/* USed cpu partial on free */
+	CPU_PARTIAL_FREE,	/* Refill cpu partial on free */
+	CPU_PARTIAL_NODE,	/* Refill cpu partial from node partial */
+	CPU_PARTIAL_DRAIN,	/* Drain cpu partial to node partial */
 	NR_SLUB_STAT_ITEMS };
 
 struct kmem_cache_cpu {
@@ -45,7 +47,6 @@ struct kmem_cache_cpu {
 	unsigned long tid;	/* Globally unique transaction id */
 	struct page *page;	/* The slab from which we are allocating */
 	struct page *partial;	/* Partially allocated frozen slabs */
-	int node;		/* The node of the page (or -1 for debug) */
 #ifdef CONFIG_SLUB_STATS
 	unsigned stat[NR_SLUB_STAT_ITEMS];
 #endif
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 8cc38d3..10530d9 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -102,6 +102,22 @@ static inline void call_function_init(void) { }
 int on_each_cpu(smp_call_func_t func, void *info, int wait);
 
 /*
+ * Call a function on processors specified by mask, which might include
+ * the local one.
+ */
+void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func,
+		void *info, bool wait);
+
+/*
+ * Call a function on each processor for which the supplied function
+ * cond_func returns a positive value. This may include the local
+ * processor.
+ */
+void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info),
+		smp_call_func_t func, void *info, bool wait,
+		gfp_t gfp_flags);
+
+/*
  * Mark the boot cpu "online" so that it can call console drivers in
  * printk() and can access its per-cpu storage.
  */
@@ -132,6 +148,36 @@ static inline int up_smp_call_function(smp_call_func_t func, void *info)
 		local_irq_enable();		\
 		0;				\
 	})
+/*
+ * Note we still need to test the mask even for UP
+ * because we actually can get an empty mask from
+ * code that on SMP might call us without the local
+ * CPU in the mask.
+ */
+#define on_each_cpu_mask(mask, func, info, wait) \
+	do {						\
+		if (cpumask_test_cpu(0, (mask))) {	\
+			local_irq_disable();		\
+			(func)(info);			\
+			local_irq_enable();		\
+		}					\
+	} while (0)
+/*
+ * Preemption is disabled here to make sure the cond_func is called under the
+ * same condtions in UP and SMP.
+ */
+#define on_each_cpu_cond(cond_func, func, info, wait, gfp_flags)\
+	do {							\
+		void *__info = (info);				\
+		preempt_disable();				\
+		if ((cond_func)(0, __info)) {			\
+			local_irq_disable();			\
+			(func)(__info);				\
+			local_irq_enable();			\
+		}						\
+		preempt_enable();				\
+	} while (0)
+
 static inline void smp_send_reschedule(int cpu) { }
 #define num_booting_cpus()			1
 #define smp_prepare_boot_cpu()			do {} while (0)
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index c1241c42..8ee8af4 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -232,6 +232,7 @@ enum
 	LINUX_MIB_TCPTIMEWAITOVERFLOW,		/* TCPTimeWaitOverflow */
 	LINUX_MIB_TCPREQQFULLDOCOOKIES,		/* TCPReqQFullDoCookies */
 	LINUX_MIB_TCPREQQFULLDROP,		/* TCPReqQFullDrop */
+	LINUX_MIB_TCPRETRANSFAIL,		/* TCPRetransFail */
 	__LINUX_MIB_MAX
 };
 
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index e1b0059..d3d5fa5 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -99,15 +99,18 @@ long srcu_batches_completed(struct srcu_struct *sp);
  * power mode. This way we can notice an extended quiescent state to
  * other CPUs that started a grace period. Otherwise we would delay any
  * grace period as long as we run in the idle task.
+ *
+ * Similarly, we avoid claiming an SRCU read lock held if the current
+ * CPU is offline.
  */
 static inline int srcu_read_lock_held(struct srcu_struct *sp)
 {
-	if (rcu_is_cpu_idle())
-		return 0;
-
 	if (!debug_lockdep_rcu_enabled())
 		return 1;
-
+	if (rcu_is_cpu_idle())
+		return 0;
+	if (!rcu_lockdep_current_cpu_online())
+		return 0;
 	return lock_is_held(&sp->dep_map);
 }
 
@@ -169,6 +172,8 @@ static inline int srcu_read_lock(struct srcu_struct *sp) __acquires(sp)
 	int retval = __srcu_read_lock(sp);
 
 	rcu_lock_acquire(&(sp)->dep_map);
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "srcu_read_lock() used illegally while idle");
 	return retval;
 }
 
@@ -182,6 +187,8 @@ static inline int srcu_read_lock(struct srcu_struct *sp) __acquires(sp)
 static inline void srcu_read_unlock(struct srcu_struct *sp, int idx)
 	__releases(sp)
 {
+	rcu_lockdep_assert(!rcu_is_cpu_idle(),
+			   "srcu_read_unlock() used illegally while idle");
 	rcu_lock_release(&(sp)->dep_map);
 	__srcu_read_unlock(sp, idx);
 }
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index dcf35b0..bbc2612 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -16,6 +16,12 @@ struct pcmcia_device;
 struct ssb_bus;
 struct ssb_driver;
 
+struct ssb_sprom_core_pwr_info {
+	u8 itssi_2g, itssi_5g;
+	u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
+	u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3];
+};
+
 struct ssb_sprom {
 	u8 revision;
 	u8 il0mac[6];		/* MAC address for 802.11b/g */
@@ -82,6 +88,8 @@ struct ssb_sprom {
 	u16 boardflags2_hi;	/* Board flags (bits 48-63) */
 	/* TODO store board flags in a single u64 */
 
+	struct ssb_sprom_core_pwr_info core_pwr_info[4];
+
 	/* Antenna gain values for up to 4 antennas
 	 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
 	 * loss in the connectors is bigger than the gain. */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index c814ae6..40b1ef8 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -449,6 +449,39 @@
 #define SSB_SPROM8_TS_SLP_OPT_CORRX	0x00B6
 #define SSB_SPROM8_FOC_HWIQ_IQSWP	0x00B8
 #define SSB_SPROM8_PHYCAL_TEMPDELTA	0x00BA
+
+/* There are 4 blocks with power info sharing the same layout */
+#define SSB_SROM8_PWR_INFO_CORE0	0x00C0
+#define SSB_SROM8_PWR_INFO_CORE1	0x00E0
+#define SSB_SROM8_PWR_INFO_CORE2	0x0100
+#define SSB_SROM8_PWR_INFO_CORE3	0x0120
+
+#define SSB_SROM8_2G_MAXP_ITSSI		0x00
+#define  SSB_SPROM8_2G_MAXP		0x00FF
+#define  SSB_SPROM8_2G_ITSSI		0xFF00
+#define  SSB_SPROM8_2G_ITSSI_SHIFT	8
+#define SSB_SROM8_2G_PA_0		0x02	/* 2GHz power amp settings */
+#define SSB_SROM8_2G_PA_1		0x04
+#define SSB_SROM8_2G_PA_2		0x06
+#define SSB_SROM8_5G_MAXP_ITSSI		0x08	/* 5GHz ITSSI and 5.3GHz Max Power */
+#define  SSB_SPROM8_5G_MAXP		0x00FF
+#define  SSB_SPROM8_5G_ITSSI		0xFF00
+#define  SSB_SPROM8_5G_ITSSI_SHIFT	8
+#define SSB_SPROM8_5GHL_MAXP		0x0A	/* 5.2GHz and 5.8GHz Max Power */
+#define  SSB_SPROM8_5GH_MAXP		0x00FF
+#define  SSB_SPROM8_5GL_MAXP		0xFF00
+#define  SSB_SPROM8_5GL_MAXP_SHIFT	8
+#define SSB_SROM8_5G_PA_0		0x0C	/* 5.3GHz power amp settings */
+#define SSB_SROM8_5G_PA_1		0x0E
+#define SSB_SROM8_5G_PA_2		0x10
+#define SSB_SROM8_5GL_PA_0		0x12	/* 5.2GHz power amp settings */
+#define SSB_SROM8_5GL_PA_1		0x14
+#define SSB_SROM8_5GL_PA_2		0x16
+#define SSB_SROM8_5GH_PA_0		0x18	/* 5.8GHz power amp settings */
+#define SSB_SROM8_5GH_PA_1		0x1A
+#define SSB_SROM8_5GH_PA_2		0x1C
+
+/* TODO: Make it deprecated */
 #define SSB_SPROM8_MAXP_BG		0x00C0  /* Max Power 2GHz in path 1 */
 #define  SSB_SPROM8_MAXP_BG_MASK	0x00FF  /* Mask for Max Power 2GHz */
 #define  SSB_SPROM8_ITSSI_BG		0xFF00	/* Mask for path 1 itssi_bg */
@@ -473,6 +506,7 @@
 #define SSB_SPROM8_PA1HIB0		0x00D8	/* 5.8GHz power amp settings */
 #define SSB_SPROM8_PA1HIB1		0x00DA
 #define SSB_SPROM8_PA1HIB2		0x00DC
+
 #define SSB_SPROM8_CCK2GPO		0x0140	/* CCK power offset */
 #define SSB_SPROM8_OFDM2GPO		0x0142	/* 2.4GHz OFDM power offset */
 #define SSB_SPROM8_OFDM5GPO		0x0146	/* 5.3GHz OFDM power offset */
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 7874a8a..492a36d 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -99,6 +99,8 @@ struct rpc_authops {
 
 	struct rpc_cred *	(*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
 	struct rpc_cred *	(*crcreate)(struct rpc_auth*, struct auth_cred *, int);
+	int			(*pipes_create)(struct rpc_auth *);
+	void			(*pipes_destroy)(struct rpc_auth *);
 };
 
 struct rpc_credops {
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 57531f8..f5fd616 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -117,6 +117,7 @@ struct cache_detail {
 		struct cache_detail_procfs procfs;
 		struct cache_detail_pipefs pipefs;
 	} u;
+	struct net		*net;
 };
 
 
@@ -197,11 +198,14 @@ extern void cache_flush(void);
 extern void cache_purge(struct cache_detail *detail);
 #define NEVER (0x7FFFFFFF)
 extern void __init cache_initialize(void);
-extern int cache_register(struct cache_detail *cd);
 extern int cache_register_net(struct cache_detail *cd, struct net *net);
-extern void cache_unregister(struct cache_detail *cd);
 extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
 
+extern struct cache_detail *cache_create_net(struct cache_detail *tmpl, struct net *net);
+extern void cache_destroy_net(struct cache_detail *cd, struct net *net);
+
+extern void sunrpc_init_cache_detail(struct cache_detail *cd);
+extern void sunrpc_destroy_cache_detail(struct cache_detail *cd);
 extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
 					umode_t, struct cache_detail *);
 extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 2c5993a..a4c62e9 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -41,8 +41,8 @@ struct rpc_clnt {
 				cl_vers,	/* RPC version number */
 				cl_maxproc;	/* max procedure number */
 
-	char *			cl_server;	/* server machine name */
-	char *			cl_protname;	/* protocol name */
+	const char *		cl_server;	/* server machine name */
+	const char *		cl_protname;	/* protocol name */
 	struct rpc_auth *	cl_auth;	/* authenticator */
 	struct rpc_stat *	cl_stats;	/* per-program statistics */
 	struct rpc_iostats *	cl_metrics;	/* per-client statistics */
@@ -57,12 +57,11 @@ struct rpc_clnt {
 
 	int			cl_nodelen;	/* nodename length */
 	char 			cl_nodename[UNX_MAXNODENAME];
-	struct path		cl_path;
+	struct dentry *		cl_dentry;
 	struct rpc_clnt *	cl_parent;	/* Points to parent of clones */
 	struct rpc_rtt		cl_rtt_default;
 	struct rpc_timeout	cl_timeout_default;
-	struct rpc_program *	cl_program;
-	char			cl_inline_name[32];
+	const struct rpc_program *cl_program;
 	char			*cl_principal;	/* target to authenticate to */
 };
 
@@ -71,12 +70,12 @@ struct rpc_clnt {
  */
 #define RPC_MAXVERSION		4
 struct rpc_program {
-	char *			name;		/* protocol name */
+	const char *		name;		/* protocol name */
 	u32			number;		/* program number */
 	unsigned int		nrvers;		/* number of versions */
-	struct rpc_version **	version;	/* version array */
+	const struct rpc_version **	version;	/* version array */
 	struct rpc_stat *	stats;		/* statistics */
-	char *			pipe_dir_name;	/* path to rpc_pipefs dir */
+	const char *		pipe_dir_name;	/* path to rpc_pipefs dir */
 };
 
 struct rpc_version {
@@ -97,7 +96,7 @@ struct rpc_procinfo {
 	unsigned int		p_count;	/* call count */
 	unsigned int		p_timer;	/* Which RTT timer to use */
 	u32			p_statidx;	/* Which procedure to account */
-	char *			p_name;		/* name of procedure */
+	const char *		p_name;		/* name of procedure */
 };
 
 #ifdef __KERNEL__
@@ -109,8 +108,8 @@ struct rpc_create_args {
 	size_t			addrsize;
 	struct sockaddr		*saddress;
 	const struct rpc_timeout *timeout;
-	char			*servername;
-	struct rpc_program	*program;
+	const char		*servername;
+	const struct rpc_program *program;
 	u32			prognumber;	/* overrides program->number */
 	u32			version;
 	rpc_authflavor_t	authflavor;
@@ -129,17 +128,18 @@ struct rpc_create_args {
 
 struct rpc_clnt *rpc_create(struct rpc_create_args *args);
 struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
-				struct rpc_program *, u32);
+				const struct rpc_program *, u32);
 void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
 void		rpc_shutdown_client(struct rpc_clnt *);
 void		rpc_release_client(struct rpc_clnt *);
 void		rpc_task_release_client(struct rpc_task *);
 
-int		rpcb_create_local(void);
-void		rpcb_put_local(void);
-int		rpcb_register(u32, u32, int, unsigned short);
-int		rpcb_v4_register(const u32 program, const u32 version,
+int		rpcb_create_local(struct net *);
+void		rpcb_put_local(struct net *);
+int		rpcb_register(struct net *, u32, u32, int, unsigned short);
+int		rpcb_v4_register(struct net *net, const u32 program,
+				 const u32 version,
 				 const struct sockaddr *address,
 				 const char *netid);
 void		rpcb_getport_async(struct rpc_task *);
@@ -162,10 +162,10 @@ size_t		rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
 const char	*rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
 
 size_t		rpc_ntop(const struct sockaddr *, char *, const size_t);
-size_t		rpc_pton(const char *, const size_t,
+size_t		rpc_pton(struct net *, const char *, const size_t,
 			 struct sockaddr *, const size_t);
 char *		rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
-size_t		rpc_uaddr2sockaddr(const char *, const size_t,
+size_t		rpc_uaddr2sockaddr(struct net *, const char *, const size_t,
 				   struct sockaddr *, const size_t);
 
 static inline unsigned short rpc_get_port(const struct sockaddr *sap)
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
index c2786f2..b506936 100644
--- a/include/linux/sunrpc/debug.h
+++ b/include/linux/sunrpc/debug.h
@@ -34,6 +34,9 @@
 #ifdef CONFIG_SYSCTL
 #define  RPC_DEBUG
 #endif
+#ifdef CONFIG_TRACEPOINTS
+#define RPC_TRACEPOINTS
+#endif
 /* #define  RPC_PROFILE */
 
 /*
@@ -51,7 +54,11 @@ extern unsigned int		nlm_debug;
 #undef ifdebug
 #ifdef RPC_DEBUG			
 # define ifdebug(fac)		if (unlikely(rpc_debug & RPCDBG_##fac))
-# define dfprintk(fac, args...)	do { ifdebug(fac) printk(args); } while(0)
+# define dfprintk(fac, args...)	\
+	do { \
+		ifdebug(fac) \
+			printk(KERN_DEFAULT args); \
+	} while (0)
 # define RPC_IFDEBUG(x)		x
 #else
 # define ifdebug(fac)		if (0)
diff --git a/include/linux/sunrpc/metrics.h b/include/linux/sunrpc/metrics.h
index b6edbc0..1565bbe 100644
--- a/include/linux/sunrpc/metrics.h
+++ b/include/linux/sunrpc/metrics.h
@@ -74,14 +74,16 @@ struct rpc_clnt;
 #ifdef CONFIG_PROC_FS
 
 struct rpc_iostats *	rpc_alloc_iostats(struct rpc_clnt *);
-void			rpc_count_iostats(struct rpc_task *);
+void			rpc_count_iostats(const struct rpc_task *,
+					  struct rpc_iostats *);
 void			rpc_print_iostats(struct seq_file *, struct rpc_clnt *);
 void			rpc_free_iostats(struct rpc_iostats *);
 
 #else  /*  CONFIG_PROC_FS  */
 
 static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; }
-static inline void rpc_count_iostats(struct rpc_task *task) {}
+static inline void rpc_count_iostats(const struct rpc_task *task,
+				     struct rpc_iostats *stats) {}
 static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {}
 static inline void rpc_free_iostats(struct rpc_iostats *stats) {}
 
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 2bb03d7..426ce6e 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -21,21 +21,26 @@ struct rpc_pipe_ops {
 	void (*destroy_msg)(struct rpc_pipe_msg *);
 };
 
-struct rpc_inode {
-	struct inode vfs_inode;
-	void *private;
+struct rpc_pipe {
 	struct list_head pipe;
 	struct list_head in_upcall;
 	struct list_head in_downcall;
 	int pipelen;
 	int nreaders;
 	int nwriters;
-	int nkern_readwriters;
 	wait_queue_head_t waitq;
 #define RPC_PIPE_WAIT_FOR_OPEN	1
 	int flags;
 	struct delayed_work queue_timeout;
 	const struct rpc_pipe_ops *ops;
+	spinlock_t lock;
+	struct dentry *dentry;
+};
+
+struct rpc_inode {
+	struct inode vfs_inode;
+	void *private;
+	struct rpc_pipe *pipe;
 };
 
 static inline struct rpc_inode *
@@ -44,9 +49,28 @@ RPC_I(struct inode *inode)
 	return container_of(inode, struct rpc_inode, vfs_inode);
 }
 
+enum {
+	SUNRPC_PIPEFS_NFS_PRIO,
+	SUNRPC_PIPEFS_RPC_PRIO,
+};
+
+extern int rpc_pipefs_notifier_register(struct notifier_block *);
+extern void rpc_pipefs_notifier_unregister(struct notifier_block *);
+
+enum {
+	RPC_PIPEFS_MOUNT,
+	RPC_PIPEFS_UMOUNT,
+};
+
+extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+				      const unsigned char *dir_name);
+extern void rpc_pipefs_init_net(struct net *net);
+extern struct super_block *rpc_get_sb_net(const struct net *net);
+extern void rpc_put_sb_net(const struct net *net);
+
 extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
 				       char __user *, size_t);
-extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
+extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
 
 struct rpc_clnt;
 extern struct dentry *rpc_create_client_dir(struct dentry *, struct qstr *, struct rpc_clnt *);
@@ -59,11 +83,13 @@ extern struct dentry *rpc_create_cache_dir(struct dentry *,
 					   struct cache_detail *);
 extern void rpc_remove_cache_dir(struct dentry *);
 
-extern struct dentry *rpc_mkpipe(struct dentry *, const char *, void *,
-				 const struct rpc_pipe_ops *, int flags);
+extern int rpc_rmdir(struct dentry *dentry);
+
+struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags);
+void rpc_destroy_pipe_data(struct rpc_pipe *pipe);
+extern struct dentry *rpc_mkpipe_dentry(struct dentry *, const char *, void *,
+					struct rpc_pipe *);
 extern int rpc_unlink(struct dentry *);
-extern struct vfsmount *rpc_get_mount(void);
-extern void rpc_put_mount(void);
 extern int register_rpc_pipefs(void);
 extern void unregister_rpc_pipefs(void);
 
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index e775689..dc0c3cc 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -103,6 +103,7 @@ typedef void			(*rpc_action)(struct rpc_task *);
 struct rpc_call_ops {
 	void (*rpc_call_prepare)(struct rpc_task *, void *);
 	void (*rpc_call_done)(struct rpc_task *, void *);
+	void (*rpc_count_stats)(struct rpc_task *, void *);
 	void (*rpc_release)(void *);
 };
 
@@ -195,7 +196,7 @@ struct rpc_wait_queue {
 	unsigned char		nr;			/* # tasks remaining for cookie */
 	unsigned short		qlen;			/* total # tasks waiting in queue */
 	struct rpc_timer	timer_list;
-#ifdef RPC_DEBUG
+#if defined(RPC_DEBUG) || defined(RPC_TRACEPOINTS)
 	const char *		name;
 #endif
 };
@@ -235,6 +236,9 @@ void		rpc_wake_up_queued_task(struct rpc_wait_queue *,
 					struct rpc_task *);
 void		rpc_wake_up(struct rpc_wait_queue *);
 struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
+struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *,
+					bool (*)(struct rpc_task *, void *),
+					void *);
 void		rpc_wake_up_status(struct rpc_wait_queue *, int);
 int		rpc_queue_empty(struct rpc_wait_queue *);
 void		rpc_delay(struct rpc_task *, unsigned long);
@@ -244,7 +248,8 @@ int		rpciod_up(void);
 void		rpciod_down(void);
 int		__rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *));
 #ifdef RPC_DEBUG
-void		rpc_show_tasks(void);
+struct net;
+void		rpc_show_tasks(struct net *);
 #endif
 int		rpc_init_mempool(void);
 void		rpc_destroy_mempool(void);
@@ -266,11 +271,22 @@ static inline int rpc_task_has_priority(struct rpc_task *task, unsigned char pri
 	return (task->tk_priority + RPC_PRIORITY_LOW == prio);
 }
 
-#ifdef RPC_DEBUG
-static inline const char * rpc_qname(struct rpc_wait_queue *q)
+#if defined(RPC_DEBUG) || defined (RPC_TRACEPOINTS)
+static inline const char * rpc_qname(const struct rpc_wait_queue *q)
 {
 	return ((q && q->name) ? q->name : "unknown");
 }
+
+static inline void rpc_assign_waitqueue_name(struct rpc_wait_queue *q,
+		const char *name)
+{
+	q->name = name;
+}
+#else
+static inline void rpc_assign_waitqueue_name(struct rpc_wait_queue *q,
+		const char *name)
+{
+}
 #endif
 
 #endif /* _LINUX_SUNRPC_SCHED_H_ */
diff --git a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h
index 680471d..edc6421 100644
--- a/include/linux/sunrpc/stats.h
+++ b/include/linux/sunrpc/stats.h
@@ -12,7 +12,7 @@
 #include <linux/proc_fs.h>
 
 struct rpc_stat {
-	struct rpc_program *	program;
+	const struct rpc_program *program;
 
 	unsigned int		netcnt,
 				netudpcnt,
@@ -58,24 +58,24 @@ void			rpc_modcount(struct inode *, int);
 #endif
 
 #ifdef CONFIG_PROC_FS
-struct proc_dir_entry *	rpc_proc_register(struct rpc_stat *);
-void			rpc_proc_unregister(const char *);
-void			rpc_proc_zero(struct rpc_program *);
-struct proc_dir_entry *	svc_proc_register(struct svc_stat *,
+struct proc_dir_entry *	rpc_proc_register(struct net *,struct rpc_stat *);
+void			rpc_proc_unregister(struct net *,const char *);
+void			rpc_proc_zero(const struct rpc_program *);
+struct proc_dir_entry *	svc_proc_register(struct net *, struct svc_stat *,
 					  const struct file_operations *);
-void			svc_proc_unregister(const char *);
+void			svc_proc_unregister(struct net *, const char *);
 
 void			svc_seq_show(struct seq_file *,
 				     const struct svc_stat *);
 #else
 
-static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
-static inline void rpc_proc_unregister(const char *p) {}
-static inline void rpc_proc_zero(struct rpc_program *p) {}
+static inline struct proc_dir_entry *rpc_proc_register(struct net *net, struct rpc_stat *s) { return NULL; }
+static inline void rpc_proc_unregister(struct net *net, const char *p) {}
+static inline void rpc_proc_zero(const struct rpc_program *p) {}
 
-static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s,
+static inline struct proc_dir_entry *svc_proc_register(struct net *net, struct svc_stat *s,
 						       const struct file_operations *f) { return NULL; }
-static inline void svc_proc_unregister(const char *p) {}
+static inline void svc_proc_unregister(struct net *net, const char *p) {}
 
 static inline void svc_seq_show(struct seq_file *seq,
 				const struct svc_stat *st) {}
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 35b37b1..51b29ac 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -84,7 +84,8 @@ struct svc_serv {
 	unsigned int		sv_nrpools;	/* number of thread pools */
 	struct svc_pool *	sv_pools;	/* array of thread pools */
 
-	void			(*sv_shutdown)(struct svc_serv *serv);
+	void			(*sv_shutdown)(struct svc_serv *serv,
+					       struct net *net);
 						/* Callback to use when last thread
 						 * exits.
 						 */
@@ -413,22 +414,24 @@ struct svc_procedure {
 /*
  * Function prototypes.
  */
-void svc_rpcb_cleanup(struct svc_serv *serv);
+int svc_rpcb_setup(struct svc_serv *serv, struct net *net);
+void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net);
 struct svc_serv *svc_create(struct svc_program *, unsigned int,
-			    void (*shutdown)(struct svc_serv *));
+			    void (*shutdown)(struct svc_serv *, struct net *net));
 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv,
 					struct svc_pool *pool, int node);
 void		   svc_exit_thread(struct svc_rqst *);
 struct svc_serv *  svc_create_pooled(struct svc_program *, unsigned int,
-			void (*shutdown)(struct svc_serv *),
+			void (*shutdown)(struct svc_serv *, struct net *net),
 			svc_thread_fn, struct module *);
 int		   svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
 int		   svc_pool_stats_open(struct svc_serv *serv, struct file *file);
 void		   svc_destroy(struct svc_serv *);
+void		   svc_shutdown_net(struct svc_serv *, struct net *);
 int		   svc_process(struct svc_rqst *);
 int		   bc_svc_process(struct svc_serv *, struct rpc_rqst *,
 			struct svc_rqst *);
-int		   svc_register(const struct svc_serv *, const int,
+int		   svc_register(const struct svc_serv *, struct net *, const int,
 				const unsigned short, const unsigned short);
 
 void		   svc_wake_up(struct svc_serv *);
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index c14fe86..d205e9f 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -292,7 +292,7 @@ svc_rdma_get_reply_array(struct rpcrdma_msg *rmsgp)
 	if (wr_ary) {
 		rp_ary = (struct rpcrdma_write_array *)
 			&wr_ary->
-			wc_array[wr_ary->wc_nchunks].wc_target.rs_length;
+			wc_array[ntohl(wr_ary->wc_nchunks)].wc_target.rs_length;
 
 		goto found_it;
 	}
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index dfa9009..b3f64b1 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -121,7 +121,8 @@ void	svc_close_xprt(struct svc_xprt *xprt);
 int	svc_port_is_privileged(struct sockaddr *sin);
 int	svc_print_xprts(char *buf, int maxlen);
 struct	svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
-			const sa_family_t af, const unsigned short port);
+			struct net *net, const sa_family_t af,
+			const unsigned short port);
 int	svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
 
 static inline void svc_xprt_get(struct svc_xprt *xprt)
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
index 83bbee3..7c32daa 100644
--- a/include/linux/sunrpc/svcauth_gss.h
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -18,6 +18,8 @@
 
 int gss_svc_init(void);
 void gss_svc_shutdown(void);
+int gss_svc_init_net(struct net *net);
+void gss_svc_shutdown_net(struct net *net);
 int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
 u32 svcauth_gss_flavor(struct auth_domain *dom);
 char *svc_gss_principal(struct svc_rqst *);
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index c84e974..cb4ac69 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -34,7 +34,7 @@ struct svc_sock {
 /*
  * Function prototypes.
  */
-void		svc_close_all(struct svc_serv *);
+void		svc_close_net(struct svc_serv *, struct net *);
 int		svc_recv(struct svc_rqst *, long);
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 15518a1..ea712f9 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -21,8 +21,8 @@
 
 #define RPC_MIN_SLOT_TABLE	(2U)
 #define RPC_DEF_SLOT_TABLE	(16U)
-#define RPC_MAX_SLOT_TABLE	(128U)
 #define RPC_MAX_SLOT_TABLE_LIMIT	(65536U)
+#define RPC_MAX_SLOT_TABLE	RPC_MAX_SLOT_TABLE_LIMIT
 
 /*
  * This describes a timeout strategy
@@ -219,10 +219,13 @@ struct rpc_xprt {
 					connect_time,	/* jiffies waiting for connect */
 					sends,		/* how many complete requests */
 					recvs,		/* how many complete requests */
-					bad_xids;	/* lookup_rqst didn't find XID */
+					bad_xids,	/* lookup_rqst didn't find XID */
+					max_slots;	/* max rpc_slots used */
 
 		unsigned long long	req_u,		/* average requests on the wire */
-					bklog_u;	/* backlog queue utilization */
+					bklog_u,	/* backlog queue utilization */
+					sending_u,	/* send q utilization */
+					pending_u;	/* pend q utilization */
 	} stat;
 
 	struct net		*xprt_net;
diff --git a/include/linux/sunserialcore.h b/include/linux/sunserialcore.h
new file mode 100644
index 0000000..68e7430
--- /dev/null
+++ b/include/linux/sunserialcore.h
@@ -0,0 +1,33 @@
+/* sunserialcore.h
+ *
+ * Generic SUN serial/kbd/ms layer.  Based entirely
+ * upon drivers/sbus/char/sunserial.h which is:
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Port to new UART layer is:
+ *
+ * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _SERIAL_SUN_H
+#define _SERIAL_SUN_H
+
+/* Serial keyboard defines for L1-A processing... */
+#define SUNKBD_RESET		0xff
+#define SUNKBD_L1		0x01
+#define SUNKBD_UP		0x80
+#define SUNKBD_A		0x4d
+
+extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *);
+extern int suncore_mouse_baud_detection(unsigned char, int);
+
+extern int sunserial_register_minors(struct uart_driver *, int);
+extern void sunserial_unregister_minors(struct uart_driver *, int);
+
+extern int sunserial_console_match(struct console *, struct device_node *,
+				   struct uart_driver *, int, bool);
+extern void sunserial_console_termios(struct console *,
+				      struct device_node *);
+
+#endif /* !(_SERIAL_SUN_H) */
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 91784a4..ac1c114 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -42,8 +42,10 @@ enum suspend_stat_step {
 	SUSPEND_FREEZE = 1,
 	SUSPEND_PREPARE,
 	SUSPEND_SUSPEND,
+	SUSPEND_SUSPEND_LATE,
 	SUSPEND_SUSPEND_NOIRQ,
 	SUSPEND_RESUME_NOIRQ,
+	SUSPEND_RESUME_EARLY,
 	SUSPEND_RESUME
 };
 
@@ -53,8 +55,10 @@ struct suspend_stats {
 	int	failed_freeze;
 	int	failed_prepare;
 	int	failed_suspend;
+	int	failed_suspend_late;
 	int	failed_suspend_noirq;
 	int	failed_resume;
+	int	failed_resume_early;
 	int	failed_resume_noirq;
 #define	REC_FAILED_NUM	2
 	int	last_failed_dev;
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 3e60228..f7df3ea 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -194,6 +194,10 @@ struct swap_info_struct {
 	struct block_device *bdev;	/* swap device or bdev of swap file */
 	struct file *swap_file;		/* seldom referenced */
 	unsigned int old_block_size;	/* seldom referenced */
+#ifdef CONFIG_FRONTSWAP
+	unsigned long *frontswap_map;	/* frontswap in-use, one bit per page */
+	atomic_t frontswap_pages;	/* frontswap pages in-use counter */
+#endif
 };
 
 struct swap_list_t {
@@ -208,6 +212,8 @@ struct swap_list_t {
 extern unsigned long totalram_pages;
 extern unsigned long totalreserve_pages;
 extern unsigned long dirty_balance_reserve;
+extern int min_free_kbytes;
+extern int extra_free_kbytes;
 extern unsigned int nr_free_buffer_pages(void);
 extern unsigned int nr_free_pagecache_pages(void);
 
@@ -329,7 +335,6 @@ extern long total_swap_pages;
 extern void si_swapinfo(struct sysinfo *);
 extern swp_entry_t get_swap_page(void);
 extern swp_entry_t get_swap_page_of_type(int);
-extern int valid_swaphandles(swp_entry_t, unsigned long *);
 extern int add_swap_count_continuation(swp_entry_t, gfp_t);
 extern void swap_shmem_alloc(swp_entry_t);
 extern int swap_duplicate(swp_entry_t);
@@ -362,6 +367,26 @@ static inline void put_swap_token(struct mm_struct *mm)
 		__put_swap_token(mm);
 }
 
+static inline bool has_active_swap_token(struct mm_struct *mm)
+{
+	return has_swap_token(mm) && atomic_read(&mm->active_swap_token);
+}
+
+static inline bool activate_swap_token(struct mm_struct *mm)
+{
+	if (has_swap_token(mm)) {
+		atomic_inc(&mm->active_swap_token);
+		return true;
+	}
+	return false;
+}
+
+static inline void deactivate_swap_token(struct mm_struct *mm, bool swap_token)
+{
+	if (swap_token)
+		atomic_dec(&mm->active_swap_token);
+}
+
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR
 extern void
 mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout);
@@ -487,6 +512,20 @@ static inline int has_swap_token(struct mm_struct *mm)
 	return 0;
 }
 
+static inline bool has_active_swap_token(struct mm_struct *mm)
+{
+	return false;
+}
+
+static inline bool activate_swap_token(struct mm_struct *mm)
+{
+	return false;
+}
+
+static inline void deactivate_swap_token(struct mm_struct *mm, bool swap_token)
+{
+}
+
 static inline void disable_swap_token(struct mem_cgroup *memcg)
 {
 }
diff --git a/include/linux/swapfile.h b/include/linux/swapfile.h
new file mode 100644
index 0000000..e282624
--- /dev/null
+++ b/include/linux/swapfile.h
@@ -0,0 +1,13 @@
+#ifndef _LINUX_SWAPFILE_H
+#define _LINUX_SWAPFILE_H
+
+/*
+ * these were static in swapfile.c but frontswap.c needs them and we don't
+ * want to expose them to the dozens of source files that include swap.h
+ */
+extern spinlock_t swap_lock;
+extern struct swap_list_t swap_list;
+extern struct swap_info_struct *swap_info[];
+extern int try_to_unuse(unsigned int, bool, unsigned long);
+
+#endif /* _LINUX_SWAPFILE_H */
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index e872526..bb2bc14 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -50,11 +50,13 @@ extern void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size,
 
 extern void
 *swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			dma_addr_t *dma_handle, gfp_t flags);
+			dma_addr_t *dma_handle, gfp_t flags,
+			struct dma_attrs *attrs);
 
 extern void
 swiotlb_free_coherent(struct device *hwdev, size_t size,
-		      void *vaddr, dma_addr_t dma_handle);
+		      void *vaddr, dma_addr_t dma_handle,
+		      struct dma_attrs *attrs);
 
 extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
 				   unsigned long offset, size_t size,
diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h
new file mode 100644
index 0000000..2739ccb
--- /dev/null
+++ b/include/linux/sys_soc.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef __SOC_BUS_H
+#define __SOC_BUS_H
+
+#include <linux/device.h>
+
+struct soc_device_attribute {
+	const char *machine;
+	const char *family;
+	const char *revision;
+	const char *soc_id;
+};
+
+/**
+ * soc_device_register - register SoC as a device
+ * @soc_plat_dev_attr: Attributes passed from platform to be attributed to a SoC
+ */
+struct soc_device *soc_device_register(
+	struct soc_device_attribute *soc_plat_dev_attr);
+
+/**
+ * soc_device_unregister - unregister SoC device
+ * @dev: SoC device to be unregistered
+ */
+void soc_device_unregister(struct soc_device *soc_dev);
+
+/**
+ * soc_device_to_device - helper function to fetch struct device
+ * @soc: Previously registered SoC device container
+ */
+struct device *soc_device_to_device(struct soc_device *soc);
+
+#endif /* __SOC_BUS_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 515669f..0cad941 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -857,4 +857,6 @@ asmlinkage long sys_process_vm_writev(pid_t pid,
 				      unsigned long riovcnt,
 				      unsigned long flags);
 
+asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type,
+			 unsigned long idx1, unsigned long idx2);
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index bb9127d..c34b4c8 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -932,34 +932,14 @@ enum
 #include <linux/list.h>
 #include <linux/rcupdate.h>
 #include <linux/wait.h>
+#include <linux/rbtree.h>
 
 /* For the /proc/sys support */
 struct ctl_table;
 struct nsproxy;
 struct ctl_table_root;
-
-struct ctl_table_set {
-	struct list_head list;
-	struct ctl_table_set *parent;
-	int (*is_seen)(struct ctl_table_set *);
-};
-
-extern void setup_sysctl_set(struct ctl_table_set *p,
-	struct ctl_table_set *parent,
-	int (*is_seen)(struct ctl_table_set *));
-
 struct ctl_table_header;
-
-extern void sysctl_head_get(struct ctl_table_header *);
-extern void sysctl_head_put(struct ctl_table_header *);
-extern int sysctl_is_seen(struct ctl_table_header *);
-extern struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *);
-extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev);
-extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
-						struct ctl_table_header *prev);
-extern void sysctl_head_finish(struct ctl_table_header *prev);
-extern int sysctl_perm(struct ctl_table_root *root,
-		struct ctl_table *table, int op);
+struct ctl_dir;
 
 typedef struct ctl_table ctl_table;
 
@@ -1023,8 +1003,6 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
 	return (void *)(unsigned long)atomic_read(&poll->event);
 }
 
-void proc_sys_poll_notify(struct ctl_table_poll *poll);
-
 #define __CTL_TABLE_POLL_INITIALIZER(name) {				\
 	.event = ATOMIC_INIT(0),					\
 	.wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait) }
@@ -1039,21 +1017,16 @@ struct ctl_table
 	void *data;
 	int maxlen;
 	umode_t mode;
-	struct ctl_table *child;
-	struct ctl_table *parent;	/* Automatically set */
+	struct ctl_table *child;	/* Deprecated */
 	proc_handler *proc_handler;	/* Callback for text formatting */
 	struct ctl_table_poll *poll;
 	void *extra1;
 	void *extra2;
 };
 
-struct ctl_table_root {
-	struct list_head root_list;
-	struct ctl_table_set default_set;
-	struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
-					   struct nsproxy *namespaces);
-	int (*permissions)(struct ctl_table_root *root,
-			struct nsproxy *namespaces, struct ctl_table *table);
+struct ctl_node {
+	struct rb_node node;
+	struct ctl_table_header *header;
 };
 
 /* struct ctl_table_header is used to maintain dynamic lists of
@@ -1063,9 +1036,9 @@ struct ctl_table_header
 	union {
 		struct {
 			struct ctl_table *ctl_table;
-			struct list_head ctl_entry;
 			int used;
 			int count;
+			int nreg;
 		};
 		struct rcu_head rcu;
 	};
@@ -1073,9 +1046,27 @@ struct ctl_table_header
 	struct ctl_table *ctl_table_arg;
 	struct ctl_table_root *root;
 	struct ctl_table_set *set;
-	struct ctl_table *attached_by;
-	struct ctl_table *attached_to;
-	struct ctl_table_header *parent;
+	struct ctl_dir *parent;
+	struct ctl_node *node;
+};
+
+struct ctl_dir {
+	/* Header must be at the start of ctl_dir */
+	struct ctl_table_header header;
+	struct rb_root root;
+};
+
+struct ctl_table_set {
+	int (*is_seen)(struct ctl_table_set *);
+	struct ctl_dir dir;
+};
+
+struct ctl_table_root {
+	struct ctl_table_set default_set;
+	struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
+					   struct nsproxy *namespaces);
+	int (*permissions)(struct ctl_table_root *root,
+			struct nsproxy *namespaces, struct ctl_table *table);
 };
 
 /* struct ctl_path describes where in the hierarchy a table is added */
@@ -1083,16 +1074,53 @@ struct ctl_path {
 	const char *procname;
 };
 
+#ifdef CONFIG_SYSCTL
+
+void proc_sys_poll_notify(struct ctl_table_poll *poll);
+
+extern void setup_sysctl_set(struct ctl_table_set *p,
+	struct ctl_table_root *root,
+	int (*is_seen)(struct ctl_table_set *));
+extern void retire_sysctl_set(struct ctl_table_set *set);
+
 void register_sysctl_root(struct ctl_table_root *root);
+struct ctl_table_header *__register_sysctl_table(
+	struct ctl_table_set *set,
+	const char *path, struct ctl_table *table);
 struct ctl_table_header *__register_sysctl_paths(
-	struct ctl_table_root *root, struct nsproxy *namespaces,
+	struct ctl_table_set *set,
 	const struct ctl_path *path, struct ctl_table *table);
+struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table);
 struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
 struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
 						struct ctl_table *table);
 
 void unregister_sysctl_table(struct ctl_table_header * table);
-int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table);
+
+extern int sysctl_init(void);
+#else /* CONFIG_SYSCTL */
+static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
+{
+	return NULL;
+}
+
+static inline struct ctl_table_header *register_sysctl_paths(
+			const struct ctl_path *path, struct ctl_table *table)
+{
+	return NULL;
+}
+
+static inline void unregister_sysctl_table(struct ctl_table_header * table)
+{
+}
+
+static inline void setup_sysctl_set(struct ctl_table_set *p,
+	struct ctl_table_root *root,
+	int (*is_seen)(struct ctl_table_set *))
+{
+}
+
+#endif /* CONFIG_SYSCTL */
 
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 46a85c9..115389e 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -463,7 +463,7 @@ struct tcp_sock {
 	const struct tcp_sock_af_ops	*af_specific;
 
 /* TCP MD5 Signature Option information */
-	struct tcp_md5sig_info	*md5sig_info;
+	struct tcp_md5sig_info	__rcu *md5sig_info;
 #endif
 
 	/* When the cookie options are generated and exchanged, then this
@@ -486,8 +486,7 @@ struct tcp_timewait_sock {
 	u32			  tw_ts_recent;
 	long			  tw_ts_recent_stamp;
 #ifdef CONFIG_TCP_MD5SIG
-	u16			  tw_md5_keylen;
-	u8			  tw_md5_key[TCP_MD5SIG_MAXKEYLEN];
+	struct tcp_md5sig_key	*tw_md5_key;
 #endif
 	/* Few sockets in timewait have cookies; in that case, then this
 	 * object holds a reference to them (tw_cookie_values->kref).
diff --git a/include/linux/topology.h b/include/linux/topology.h
index e26db03..b480403 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -239,7 +239,7 @@ static inline int cpu_to_node(int cpu)
 #ifndef set_numa_node
 static inline void set_numa_node(int node)
 {
-	percpu_write(numa_node, node);
+	__this_cpu_write(numa_node, node);
 }
 #endif
 
@@ -274,7 +274,7 @@ DECLARE_PER_CPU(int, _numa_mem_);
 #ifndef set_numa_mem
 static inline void set_numa_mem(int node)
 {
-	percpu_write(_numa_mem_, node);
+	__this_cpu_write(_numa_mem_, node);
 }
 #endif
 
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
index a71a292..51bd91d 100644
--- a/include/linux/tracehook.h
+++ b/include/linux/tracehook.h
@@ -54,12 +54,12 @@ struct linux_binprm;
 /*
  * ptrace report for syscall entry and exit looks identical.
  */
-static inline void ptrace_report_syscall(struct pt_regs *regs)
+static inline int ptrace_report_syscall(struct pt_regs *regs)
 {
 	int ptrace = current->ptrace;
 
 	if (!(ptrace & PT_PTRACED))
-		return;
+		return 0;
 
 	ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
 
@@ -72,6 +72,8 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
 		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
+
+	return fatal_signal_pending(current);
 }
 
 /**
@@ -96,8 +98,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs)
 static inline __must_check int tracehook_report_syscall_entry(
 	struct pt_regs *regs)
 {
-	ptrace_report_syscall(regs);
-	return 0;
+	return ptrace_report_syscall(regs);
 }
 
 /**
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 5dbb3cb..a91ff40 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -52,6 +52,7 @@
  * hardcoded at present.)
  */
 #define NR_UNIX98_PTY_DEFAULT	4096      /* Default maximum for Unix98 ptys */
+#define NR_UNIX98_PTY_RESERVE	1024	  /* Default reserve for main devpts */
 #define NR_UNIX98_PTY_MAX	(1 << MINORBITS) /* Absolute limit */
 
 /*
@@ -480,10 +481,11 @@ extern void free_tty_struct(struct tty_struct *tty);
 extern void initialize_tty_struct(struct tty_struct *tty,
 		struct tty_driver *driver, int idx);
 extern void deinitialize_tty_struct(struct tty_struct *tty);
-extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
-								int first_ok);
+extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx);
 extern int tty_release(struct inode *inode, struct file *filp);
 extern int tty_init_termios(struct tty_struct *tty);
+extern int tty_standard_install(struct tty_driver *driver,
+		struct tty_struct *tty);
 
 extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty);
 extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty);
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
new file mode 100644
index 0000000..0f6cc1a
--- /dev/null
+++ b/include/linux/uprobes.h
@@ -0,0 +1,171 @@
+#ifndef _LINUX_UPROBES_H
+#define _LINUX_UPROBES_H
+/*
+ * Userspace Probes (UProbes)
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2008-2011
+ * Authors:
+ *	Srikar Dronamraju
+ *	Jim Keniston
+ */
+
+#include <linux/errno.h>
+#include <linux/rbtree.h>
+
+struct vm_area_struct;
+struct mm_struct;
+#ifdef CONFIG_ARCH_SUPPORTS_UPROBES
+#include <asm/uprobes.h>
+#else
+
+typedef u8 uprobe_opcode_t;
+struct uprobe_arch_info {};
+struct uprobe_task_arch_info {};	/* arch specific task info */
+#define MAX_UINSN_BYTES 4
+#endif
+
+#define uprobe_opcode_sz sizeof(uprobe_opcode_t)
+
+/* flags that denote/change uprobes behaviour */
+/* Have a copy of original instruction */
+#define UPROBES_COPY_INSN	0x1
+/* Dont run handlers when first register/ last unregister in progress*/
+#define UPROBES_RUN_HANDLER	0x2
+/* Can skip singlestep */
+#define UPROBES_SKIP_SSTEP	0x4
+
+struct uprobe_consumer {
+	int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
+	/*
+	 * filter is optional; If a filter exists, handler is run
+	 * if and only if filter returns true.
+	 */
+	bool (*filter)(struct uprobe_consumer *self, struct task_struct *task);
+
+	struct uprobe_consumer *next;
+};
+
+struct uprobe {
+	struct rb_node		rb_node;	/* node in the rb tree */
+	atomic_t		ref;
+	struct rw_semaphore	consumer_rwsem;
+	struct list_head	pending_list;
+	struct uprobe_arch_info arch_info;
+	struct uprobe_consumer	*consumers;
+	struct inode		*inode;		/* Also hold a ref to inode */
+	loff_t			offset;
+	int			flags;
+	u8			insn[MAX_UINSN_BYTES];
+};
+
+enum uprobe_task_state {
+	UTASK_RUNNING,
+	UTASK_BP_HIT,
+	UTASK_SSTEP,
+	UTASK_SSTEP_ACK,
+	UTASK_SSTEP_TRAPPED,
+};
+
+/*
+ * uprobe_task: Metadata of a task while it singlesteps.
+ */
+struct uprobe_task {
+	unsigned long xol_vaddr;
+	unsigned long vaddr;
+
+	enum uprobe_task_state state;
+	struct uprobe_task_arch_info tskinfo;
+
+	struct uprobe *active_uprobe;
+};
+
+/*
+ * On a breakpoint hit, thread contests for a slot.  It free the
+ * slot after singlestep.  Only definite number of slots are
+ * allocated.
+ */
+
+struct uprobes_xol_area {
+	wait_queue_head_t wq;	/* if all slots are busy */
+	atomic_t slot_count;	/* currently in use slots */
+	unsigned long *bitmap;	/* 0 = free slot */
+	struct page *page;
+
+	/*
+	 * We keep the vma's vm_start rather than a pointer to the vma
+	 * itself.  The probed process or a naughty kernel module could make
+	 * the vma go away, and we must handle that reasonably gracefully.
+	 */
+	unsigned long vaddr;		/* Page(s) of instruction slots */
+};
+
+#ifdef CONFIG_UPROBES
+extern int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
+							unsigned long vaddr);
+extern int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe,
+					unsigned long vaddr, bool verify);
+extern bool __weak is_bkpt_insn(uprobe_opcode_t *insn);
+extern int register_uprobe(struct inode *inode, loff_t offset,
+				struct uprobe_consumer *consumer);
+extern void unregister_uprobe(struct inode *inode, loff_t offset,
+				struct uprobe_consumer *consumer);
+extern void free_uprobe_utask(struct task_struct *tsk);
+extern void free_uprobes_xol_area(struct mm_struct *mm);
+extern int mmap_uprobe(struct vm_area_struct *vma);
+extern void munmap_uprobe(struct vm_area_struct *vma);
+extern unsigned long __weak get_uprobe_bkpt_addr(struct pt_regs *regs);
+extern int uprobe_post_notifier(struct pt_regs *regs);
+extern int uprobe_bkpt_notifier(struct pt_regs *regs);
+extern void uprobe_notify_resume(struct pt_regs *regs);
+extern bool uprobe_deny_signal(void);
+extern bool __weak uprobe_skip_sstep(struct pt_regs *regs, struct uprobe *u);
+#else /* CONFIG_UPROBES is not defined */
+static inline int register_uprobe(struct inode *inode, loff_t offset,
+				struct uprobe_consumer *consumer)
+{
+	return -ENOSYS;
+}
+static inline void unregister_uprobe(struct inode *inode, loff_t offset,
+				struct uprobe_consumer *consumer)
+{
+}
+static inline int mmap_uprobe(struct vm_area_struct *vma)
+{
+	return 0;
+}
+static inline void munmap_uprobe(struct vm_area_struct *vma)
+{
+}
+static inline void uprobe_notify_resume(struct pt_regs *regs)
+{
+}
+static inline bool uprobe_deny_signal(void)
+{
+	return false;
+}
+static inline unsigned long get_uprobe_bkpt_addr(struct pt_regs *regs)
+{
+	return 0;
+}
+static inline void free_uprobe_utask(struct task_struct *tsk)
+{
+}
+static inline void free_uprobes_xol_area(struct mm_struct *mm)
+{
+}
+#endif /* CONFIG_UPROBES */
+#endif	/* _LINUX_UPROBES_H */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 69d8457..0c51663 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -376,6 +376,12 @@ struct usb_bus {
 
 struct usb_tt;
 
+enum usb_device_removable {
+	USB_DEVICE_REMOVABLE_UNKNOWN = 0,
+	USB_DEVICE_REMOVABLE,
+	USB_DEVICE_FIXED,
+};
+
 /**
  * struct usb_device - kernel's representation of a USB device
  * @devnum: device number; address on a USB bus
@@ -432,6 +438,7 @@ struct usb_tt;
  * @wusb_dev: if this is a Wireless USB device, link to the WUSB
  *	specific data for the device.
  * @slot_id: Slot ID assigned by xHCI
+ * @removable: Device can be physically removed from this port
  *
  * Notes:
  * Usbcore drivers should not set usbdev->state directly.  Instead use
@@ -509,6 +516,7 @@ struct usb_device {
 #endif
 	struct wusb_dev *wusb_dev;
 	int slot_id;
+	enum usb_device_removable removable;
 };
 #define	to_usb_device(d) container_of(d, struct usb_device, dev)
 
diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h
index 31fdb4c..f1d26b6 100644
--- a/include/linux/usb/ch11.h
+++ b/include/linux/usb/ch11.h
@@ -61,12 +61,6 @@
 #define USB_PORT_FEAT_TEST              21
 #define USB_PORT_FEAT_INDICATOR         22
 #define USB_PORT_FEAT_C_PORT_L1         23
-#define USB_PORT_FEAT_C_PORT_LINK_STATE	25
-#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR 26
-#define USB_PORT_FEAT_PORT_REMOTE_WAKE_MASK 27
-#define USB_PORT_FEAT_BH_PORT_RESET     28
-#define USB_PORT_FEAT_C_BH_PORT_RESET   29
-#define USB_PORT_FEAT_FORCE_LINKPM_ACCEPT 30
 
 /*
  * Port feature selectors added by USB 3.0 spec.
@@ -75,13 +69,18 @@
 #define USB_PORT_FEAT_LINK_STATE		5
 #define USB_PORT_FEAT_U1_TIMEOUT		23
 #define USB_PORT_FEAT_U2_TIMEOUT		24
-#define USB_PORT_FEAT_C_LINK_STATE		25
-#define USB_PORT_FEAT_C_CONFIG_ERR		26
+#define USB_PORT_FEAT_C_PORT_LINK_STATE		25
+#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR	26
 #define USB_PORT_FEAT_REMOTE_WAKE_MASK		27
 #define USB_PORT_FEAT_BH_PORT_RESET		28
 #define USB_PORT_FEAT_C_BH_PORT_RESET		29
 #define USB_PORT_FEAT_FORCE_LINKPM_ACCEPT	30
 
+/* USB 3.0 hub remote wake mask bits, see table 10-14 */
+#define USB_PORT_FEAT_REMOTE_WAKE_CONNECT	(1 << 8)
+#define USB_PORT_FEAT_REMOTE_WAKE_DISCONNECT	(1 << 9)
+#define USB_PORT_FEAT_REMOTE_WAKE_OVER_CURRENT	(1 << 10)
+
 /*
  * Hub Status and Hub Change results
  * See USB 2.0 spec Table 11-19 and Table 11-20
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index b2f62f3..2e6071e 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -412,6 +412,8 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);
 
 extern void usb_hc_died(struct usb_hcd *hcd);
 extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
+extern void usb_wakeup_notification(struct usb_device *hdev,
+		unsigned int portnum);
 
 /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
 #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 4267a9c..10cb74d 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -389,5 +389,20 @@ do {									\
 		printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg);	\
 } while (0)
 
+/*
+ * Macro for reporting errors in write path to avoid inifinite loop
+ * when port is used as a console.
+ */
+#define dev_err_console(usport, fmt, ...)				\
+do {									\
+	static bool __print_once;					\
+	struct usb_serial_port *__port = (usport);			\
+									\
+	if (!__port->port.console || !__print_once) {			\
+		__print_once = true;					\
+		dev_err(&__port->dev, fmt, ##__VA_ARGS__);		\
+	}								\
+} while (0)
+
 #endif /* __LINUX_USB_SERIAL_H */
 
diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h
new file mode 100644
index 0000000..9a988e4
--- /dev/null
+++ b/include/linux/usb/uas.h
@@ -0,0 +1,69 @@
+#ifndef __USB_UAS_H__
+#define __USB_UAS_H__
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+
+/* Common header for all IUs */
+struct iu {
+	__u8 iu_id;
+	__u8 rsvd1;
+	__be16 tag;
+};
+
+enum {
+	IU_ID_COMMAND		= 0x01,
+	IU_ID_STATUS		= 0x03,
+	IU_ID_RESPONSE		= 0x04,
+	IU_ID_TASK_MGMT		= 0x05,
+	IU_ID_READ_READY	= 0x06,
+	IU_ID_WRITE_READY	= 0x07,
+};
+
+struct command_iu {
+	__u8 iu_id;
+	__u8 rsvd1;
+	__be16 tag;
+	__u8 prio_attr;
+	__u8 rsvd5;
+	__u8 len;
+	__u8 rsvd7;
+	struct scsi_lun lun;
+	__u8 cdb[16];	/* XXX: Overflow-checking tools may misunderstand */
+};
+
+/*
+ * Also used for the Read Ready and Write Ready IUs since they have the
+ * same first four bytes
+ */
+struct sense_iu {
+	__u8 iu_id;
+	__u8 rsvd1;
+	__be16 tag;
+	__be16 status_qual;
+	__u8 status;
+	__u8 rsvd7[7];
+	__be16 len;
+	__u8 sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+struct usb_pipe_usage_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  bPipeID;
+	__u8  Reserved;
+} __attribute__((__packed__));
+
+enum {
+	CMD_PIPE_ID		= 1,
+	STATUS_PIPE_ID		= 2,
+	DATA_IN_PIPE_ID		= 3,
+	DATA_OUT_PIPE_ID	= 4,
+
+	UAS_SIMPLE_TAG		= 0,
+	UAS_HEAD_TAG		= 1,
+	UAS_ORDERED_TAG		= 2,
+	UAS_ACA			= 4,
+};
+#endif
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 5e11f8a..b739d7d 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -235,16 +235,25 @@ struct v4l2_fract {
 	__u32   denominator;
 };
 
-/*
- *	D R I V E R   C A P A B I L I T I E S
- */
+/**
+  * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP
+  *
+  * @driver:	   name of the driver module (e.g. "bttv")
+  * @card:	   name of the card (e.g. "Hauppauge WinTV")
+  * @bus_info:	   name of the bus (e.g. "PCI:" + pci_name(pci_dev) )
+  * @version:	   KERNEL_VERSION
+  * @capabilities: capabilities of the physical device as a whole
+  * @device_caps:  capabilities accessed via this particular device (node)
+  * @reserved:	   reserved fields for future extensions
+  */
 struct v4l2_capability {
-	__u8	driver[16];	/* i.e. "bttv" */
-	__u8	card[32];	/* i.e. "Hauppauge WinTV" */
-	__u8	bus_info[32];	/* "PCI:" + pci_name(pci_dev) */
-	__u32   version;        /* should use KERNEL_VERSION() */
-	__u32	capabilities;	/* Device capabilities */
-	__u32	reserved[4];
+	__u8	driver[16];
+	__u8	card[32];
+	__u8	bus_info[32];
+	__u32   version;
+	__u32	capabilities;
+	__u32	device_caps;
+	__u32	reserved[3];
 };
 
 /* Values for 'capabilities' field */
@@ -274,6 +283,8 @@ struct v4l2_capability {
 #define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
 #define V4L2_CAP_STREAMING              0x04000000  /* streaming I/O ioctls */
 
+#define V4L2_CAP_DEVICE_CAPS            0x80000000  /* sets device capabilities field */
+
 /*
  *	V I D E O   I M A G E   F O R M A T
  */
@@ -1396,6 +1407,16 @@ enum v4l2_mpeg_audio_ac3_bitrate {
 	V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
 	V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
 };
+#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK	(V4L2_CID_MPEG_BASE+112)
+enum v4l2_mpeg_audio_dec_playback {
+	V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO	    = 0,
+	V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO	    = 1,
+	V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT	    = 2,
+	V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT	    = 3,
+	V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO	    = 4,
+	V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5,
+};
+#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113)
 
 /*  MPEG video controls specific to multiplexed streams */
 #define V4L2_CID_MPEG_VIDEO_ENCODING 		(V4L2_CID_MPEG_BASE+200)
@@ -1446,6 +1467,9 @@ enum v4l2_mpeg_video_multi_slice_mode {
 	V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES	= 2,
 };
 #define V4L2_CID_MPEG_VIDEO_VBV_SIZE			(V4L2_CID_MPEG_BASE+222)
+#define V4L2_CID_MPEG_VIDEO_DEC_PTS			(V4L2_CID_MPEG_BASE+223)
+#define V4L2_CID_MPEG_VIDEO_DEC_FRAME			(V4L2_CID_MPEG_BASE+224)
+
 #define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP		(V4L2_CID_MPEG_BASE+300)
 #define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP		(V4L2_CID_MPEG_BASE+301)
 #define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP		(V4L2_CID_MPEG_BASE+302)
@@ -1897,6 +1921,54 @@ struct v4l2_encoder_cmd {
 	};
 };
 
+/* Decoder commands */
+#define V4L2_DEC_CMD_START       (0)
+#define V4L2_DEC_CMD_STOP        (1)
+#define V4L2_DEC_CMD_PAUSE       (2)
+#define V4L2_DEC_CMD_RESUME      (3)
+
+/* Flags for V4L2_DEC_CMD_START */
+#define V4L2_DEC_CMD_START_MUTE_AUDIO	(1 << 0)
+
+/* Flags for V4L2_DEC_CMD_PAUSE */
+#define V4L2_DEC_CMD_PAUSE_TO_BLACK	(1 << 0)
+
+/* Flags for V4L2_DEC_CMD_STOP */
+#define V4L2_DEC_CMD_STOP_TO_BLACK	(1 << 0)
+#define V4L2_DEC_CMD_STOP_IMMEDIATELY	(1 << 1)
+
+/* Play format requirements (returned by the driver): */
+
+/* The decoder has no special format requirements */
+#define V4L2_DEC_START_FMT_NONE		(0)
+/* The decoder requires full GOPs */
+#define V4L2_DEC_START_FMT_GOP		(1)
+
+/* The structure must be zeroed before use by the application
+   This ensures it can be extended safely in the future. */
+struct v4l2_decoder_cmd {
+	__u32 cmd;
+	__u32 flags;
+	union {
+		struct {
+			__u64 pts;
+		} stop;
+
+		struct {
+			/* 0 or 1000 specifies normal speed,
+			   1 specifies forward single stepping,
+			   -1 specifies backward single stepping,
+			   >1: playback at speed/1000 of the normal speed,
+			   <-1: reverse playback at (-speed/1000) of the normal speed. */
+			__s32 speed;
+			__u32 format;
+		} start;
+
+		struct {
+			__u32 data[16];
+		} raw;
+	};
+};
 #endif
 
 
@@ -2307,6 +2379,11 @@ struct v4l2_create_buffers {
 #define VIDIOC_G_SELECTION	_IOWR('V', 94, struct v4l2_selection)
 #define VIDIOC_S_SELECTION	_IOWR('V', 95, struct v4l2_selection)
 
+/* Experimental, these two ioctls may change over the next couple of kernel
+   versions. */
+#define VIDIOC_DECODER_CMD	_IOWR('V', 96, struct v4l2_decoder_cmd)
+#define VIDIOC_TRY_DECODER_CMD	_IOWR('V', 97, struct v4l2_decoder_cmd)
+
 /* Reminder: when adding new ioctls please add support for them to
    drivers/media/video/v4l2-compat-ioctl32.c as well! */
 
diff --git a/include/linux/virtio_ids.h b/include/linux/virtio_ids.h
index 85bb0bb..7529b85 100644
--- a/include/linux/virtio_ids.h
+++ b/include/linux/virtio_ids.h
@@ -34,6 +34,8 @@
 #define VIRTIO_ID_CONSOLE	3 /* virtio console */
 #define VIRTIO_ID_RNG		4 /* virtio ring */
 #define VIRTIO_ID_BALLOON	5 /* virtio balloon */
+#define VIRTIO_ID_RPMSG		7 /* virtio remote processor messaging */
+#define VIRTIO_ID_SCSI		8 /* virtio scsi */
 #define VIRTIO_ID_9P		9 /* 9p virtio console */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
diff --git a/include/linux/virtio_scsi.h b/include/linux/virtio_scsi.h
new file mode 100644
index 0000000..8ddeafd
--- /dev/null
+++ b/include/linux/virtio_scsi.h
@@ -0,0 +1,114 @@
+#ifndef _LINUX_VIRTIO_SCSI_H
+#define _LINUX_VIRTIO_SCSI_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers. */
+
+#define VIRTIO_SCSI_CDB_SIZE   32
+#define VIRTIO_SCSI_SENSE_SIZE 96
+
+/* SCSI command request, followed by data-out */
+struct virtio_scsi_cmd_req {
+	u8 lun[8];		/* Logical Unit Number */
+	u64 tag;		/* Command identifier */
+	u8 task_attr;		/* Task attribute */
+	u8 prio;
+	u8 crn;
+	u8 cdb[VIRTIO_SCSI_CDB_SIZE];
+} __packed;
+
+/* Response, followed by sense data and data-in */
+struct virtio_scsi_cmd_resp {
+	u32 sense_len;		/* Sense data length */
+	u32 resid;		/* Residual bytes in data buffer */
+	u16 status_qualifier;	/* Status qualifier */
+	u8 status;		/* Command completion status */
+	u8 response;		/* Response values */
+	u8 sense[VIRTIO_SCSI_SENSE_SIZE];
+} __packed;
+
+/* Task Management Request */
+struct virtio_scsi_ctrl_tmf_req {
+	u32 type;
+	u32 subtype;
+	u8 lun[8];
+	u64 tag;
+} __packed;
+
+struct virtio_scsi_ctrl_tmf_resp {
+	u8 response;
+} __packed;
+
+/* Asynchronous notification query/subscription */
+struct virtio_scsi_ctrl_an_req {
+	u32 type;
+	u8 lun[8];
+	u32 event_requested;
+} __packed;
+
+struct virtio_scsi_ctrl_an_resp {
+	u32 event_actual;
+	u8 response;
+} __packed;
+
+struct virtio_scsi_event {
+	u32 event;
+	u8 lun[8];
+	u32 reason;
+} __packed;
+
+struct virtio_scsi_config {
+	u32 num_queues;
+	u32 seg_max;
+	u32 max_sectors;
+	u32 cmd_per_lun;
+	u32 event_info_size;
+	u32 sense_size;
+	u32 cdb_size;
+	u16 max_channel;
+	u16 max_target;
+	u32 max_lun;
+} __packed;
+
+/* Response codes */
+#define VIRTIO_SCSI_S_OK                       0
+#define VIRTIO_SCSI_S_OVERRUN                  1
+#define VIRTIO_SCSI_S_ABORTED                  2
+#define VIRTIO_SCSI_S_BAD_TARGET               3
+#define VIRTIO_SCSI_S_RESET                    4
+#define VIRTIO_SCSI_S_BUSY                     5
+#define VIRTIO_SCSI_S_TRANSPORT_FAILURE        6
+#define VIRTIO_SCSI_S_TARGET_FAILURE           7
+#define VIRTIO_SCSI_S_NEXUS_FAILURE            8
+#define VIRTIO_SCSI_S_FAILURE                  9
+#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED       10
+#define VIRTIO_SCSI_S_FUNCTION_REJECTED        11
+#define VIRTIO_SCSI_S_INCORRECT_LUN            12
+
+/* Controlq type codes.  */
+#define VIRTIO_SCSI_T_TMF                      0
+#define VIRTIO_SCSI_T_AN_QUERY                 1
+#define VIRTIO_SCSI_T_AN_SUBSCRIBE             2
+
+/* Valid TMF subtypes.  */
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK           0
+#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET       1
+#define VIRTIO_SCSI_T_TMF_CLEAR_ACA            2
+#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET       3
+#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET      4
+#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET   5
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK           6
+#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET       7
+
+/* Events.  */
+#define VIRTIO_SCSI_T_EVENTS_MISSED            0x80000000
+#define VIRTIO_SCSI_T_NO_EVENT                 0
+#define VIRTIO_SCSI_T_TRANSPORT_RESET          1
+#define VIRTIO_SCSI_T_ASYNC_NOTIFY             2
+
+#define VIRTIO_SCSI_S_SIMPLE                   0
+#define VIRTIO_SCSI_S_ORDERED                  1
+#define VIRTIO_SCSI_S_HEAD                     2
+#define VIRTIO_SCSI_S_ACA                      3
+
+
+#endif /* _LINUX_VIRTIO_SCSI_H */
diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h
index 9929b05..bd8217c 100644
--- a/include/media/davinci/vpif_types.h
+++ b/include/media/davinci/vpif_types.h
@@ -17,6 +17,8 @@
 #ifndef _VPIF_TYPES_H
 #define _VPIF_TYPES_H
 
+#include <linux/i2c.h>
+
 #define VPIF_CAPTURE_MAX_CHANNELS	2
 
 enum vpif_if_type {
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index f688bde..5b988d7 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -102,6 +102,8 @@ void rc_map_init(void);
 #define RC_MAP_IMON_MCE                  "rc-imon-mce"
 #define RC_MAP_IMON_PAD                  "rc-imon-pad"
 #define RC_MAP_IODATA_BCTV7E             "rc-iodata-bctv7e"
+#define RC_MAP_IT913X_V1                 "rc-it913x-v1"
+#define RC_MAP_IT913X_V2                 "rc-it913x-v2"
 #define RC_MAP_KAIOMY                    "rc-kaiomy"
 #define RC_MAP_KWORLD_315U               "rc-kworld-315u"
 #define RC_MAP_KWORLD_PLUS_TV_ANALOG     "rc-kworld-plus-tv-analog"
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 29e1920..926aff9 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -136,6 +136,7 @@
 #define TUNER_TENA_TNF_5337		86
 
 #define TUNER_XC4000			87	/* Xceive Silicon Tuner */
+#define TUNER_XC5000C			88	/* Xceive Silicon Tuner */
 
 /* tv card specific */
 #define TDA9887_PRESENT 		(1<<0)
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index eeb3df6..3dbd066 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -33,6 +33,7 @@ struct video_device;
 struct v4l2_subdev;
 struct v4l2_subscribed_event;
 struct v4l2_fh;
+struct poll_table_struct;
 
 /** struct v4l2_ctrl_ops - The control operations that the driver has to provide.
   * @g_volatile_ctrl: Get a new value for this control. Generally only relevant
@@ -492,6 +493,18 @@ void v4l2_ctrl_add_event(struct v4l2_ctrl *ctrl,
 void v4l2_ctrl_del_event(struct v4l2_ctrl *ctrl,
 		struct v4l2_subscribed_event *sev);
 
+/* Can be used as a vidioc_log_status function that just dumps all controls
+   associated with the filehandle. */
+int v4l2_ctrl_log_status(struct file *file, void *fh);
+
+/* Can be used as a vidioc_subscribe_event function that just subscribes
+   control events. */
+int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
+				struct v4l2_event_subscription *sub);
+
+/* Can be used as a poll function that just polls for control events. */
+unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait);
+
 /* Helpers for ioctl_ops. If hdl == NULL then they will all return -EINVAL. */
 int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc);
 int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm);
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 3f5d60f..4df031a 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -211,6 +211,10 @@ struct v4l2_ioctl_ops {
 					struct v4l2_encoder_cmd *a);
 	int (*vidioc_try_encoder_cmd)  (struct file *file, void *fh,
 					struct v4l2_encoder_cmd *a);
+	int (*vidioc_decoder_cmd)      (struct file *file, void *fh,
+					struct v4l2_decoder_cmd *a);
+	int (*vidioc_try_decoder_cmd)  (struct file *file, void *fh,
+					struct v4l2_decoder_cmd *a);
 
 	/* Stream type-dependent parameter ioctls */
 	int (*vidioc_g_parm)           (struct file *file, void *fh,
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index f68dce2..757a176 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -160,7 +160,6 @@ extern void addrconf_prefix_rcv(struct net_device *dev,
 extern int ipv6_sock_ac_join(struct sock *sk,int ifindex, const struct in6_addr *addr);
 extern int ipv6_sock_ac_drop(struct sock *sk,int ifindex, const struct in6_addr *addr);
 extern void ipv6_sock_ac_close(struct sock *sk);
-extern int inet6_ac_check(struct sock *sk, const struct in6_addr *addr, int ifindex);
 
 extern int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr);
 extern int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr);
diff --git a/include/net/arp.h b/include/net/arp.h
index 0013dc8..4a1f3fb 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -15,14 +15,14 @@ static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd
 	return val * hash_rnd;
 }
 
-static inline struct neighbour *__ipv4_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, u32 key)
+static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key)
 {
 	struct neigh_hash_table *nht;
 	struct neighbour *n;
 	u32 hash_val;
 
 	rcu_read_lock_bh();
-	nht = rcu_dereference_bh(tbl->nht);
+	nht = rcu_dereference_bh(arp_tbl.nht);
 	hash_val = arp_hashfn(key, dev, nht->hash_rnd[0]) >> (32 - nht->hash_shift);
 	for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
 	     n != NULL;
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index abaad6e..4a82ca0 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -256,4 +256,6 @@ void l2cap_exit(void);
 int sco_init(void);
 void sco_exit(void);
 
+void bt_sock_reclassify_lock(struct sock *sk, int proto);
+
 #endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ea9231f..453893b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -540,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn);
 static inline void hci_conn_hold(struct hci_conn *conn)
 {
 	atomic_inc(&conn->refcnt);
-	cancel_delayed_work_sync(&conn->disc_work);
+	cancel_delayed_work(&conn->disc_work);
 }
 
 static inline void hci_conn_put(struct hci_conn *conn)
@@ -559,9 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
 		} else {
 			timeo = msecs_to_jiffies(10);
 		}
-		cancel_delayed_work_sync(&conn->disc_work);
+		cancel_delayed_work(&conn->disc_work);
 		queue_delayed_work(conn->hdev->workqueue,
-					&conn->disc_work, jiffies + timeo);
+					&conn->disc_work, timeo);
 	}
 }
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 68f5891..b1664ed 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
 {
 	BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
 
-	if (!__cancel_delayed_work(work))
+	if (!cancel_delayed_work(work))
 		l2cap_chan_hold(chan);
 	schedule_delayed_work(work, timeout);
 }
@@ -619,20 +619,20 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
 static inline void l2cap_clear_timer(struct l2cap_chan *chan,
 					struct delayed_work *work)
 {
-	if (__cancel_delayed_work(work))
+	if (cancel_delayed_work(work))
 		l2cap_chan_put(chan);
 }
 
 #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
 #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
 #define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
-		L2CAP_DEFAULT_RETRANS_TO);
+		msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
 #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
 #define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
-		L2CAP_DEFAULT_MONITOR_TO);
+		msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
 #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
 #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
-		L2CAP_DEFAULT_ACK_TO);
+		msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
 #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
 
 static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
@@ -834,7 +834,7 @@ int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
 struct l2cap_chan *l2cap_chan_create(struct sock *sk);
 void l2cap_chan_close(struct l2cap_chan *chan, int reason);
 void l2cap_chan_destroy(struct l2cap_chan *chan);
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 								bdaddr_t *dst);
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 								u32 priority);
diff --git a/include/net/caif/caif_hsi.h b/include/net/caif/caif_hsi.h
index 8d55251..6db8ecf 100644
--- a/include/net/caif/caif_hsi.h
+++ b/include/net/caif/caif_hsi.h
@@ -138,6 +138,7 @@ struct cfhsi {
 	u8 *rx_ptr;
 	u8 *tx_buf;
 	u8 *rx_buf;
+	u8 *rx_flip_buf;
 	spinlock_t lock;
 	int flow_off_sent;
 	u32 q_low_mark;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a067d30..e0c9ff3 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -120,6 +120,7 @@ enum ieee80211_channel_flags {
  * @band: band this channel belongs to.
  * @max_antenna_gain: maximum antenna gain in dBi
  * @max_power: maximum transmission power (in dBm)
+ * @max_reg_power: maximum regulatory transmission power (in dBm)
  * @beacon_found: helper to regulatory code to indicate when a beacon
  *	has been found on this channel. Use regulatory_hint_found_beacon()
  *	to enable this, this is useful only on 5 GHz band.
@@ -133,6 +134,7 @@ struct ieee80211_channel {
 	u32 flags;
 	int max_antenna_gain;
 	int max_power;
+	int max_reg_power;
 	bool beacon_found;
 	u32 orig_flags;
 	int orig_mag, orig_mpwr;
@@ -796,6 +798,7 @@ struct mesh_config {
 	 * mesh gate, but not necessarily using the gate announcement protocol.
 	 * Still keeping the same nomenclature to be in sync with the spec. */
 	bool  dot11MeshGateAnnouncementProtocol;
+	bool dot11MeshForwarding;
 };
 
 /**
@@ -1036,10 +1039,6 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
  * @key_len: length of WEP key for shared key authentication
  * @key_idx: index of WEP key for shared key authentication
  * @key: WEP key for shared key authentication
- * @local_state_change: This is a request for a local state only, i.e., no
- *	Authentication frame is to be transmitted and authentication state is
- *	to be changed without having to wait for a response from the peer STA
- *	(AP).
  */
 struct cfg80211_auth_request {
 	struct cfg80211_bss *bss;
@@ -1048,7 +1047,6 @@ struct cfg80211_auth_request {
 	enum nl80211_auth_type auth_type;
 	const u8 *key;
 	u8 key_len, key_idx;
-	bool local_state_change;
 };
 
 /**
@@ -1065,7 +1063,11 @@ enum cfg80211_assoc_req_flags {
  *
  * This structure provides information needed to complete IEEE 802.11
  * (re)association.
- * @bss: The BSS to associate with.
+ * @bss: The BSS to associate with. If the call is successful the driver
+ *	is given a reference that it must release, normally via a call to
+ *	cfg80211_send_rx_assoc(), or, if association timed out, with a
+ *	call to cfg80211_put_bss() (in addition to calling
+ *	cfg80211_send_assoc_timeout())
  * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
  * @ie_len: Length of ie buffer in octets
  * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
@@ -1093,19 +1095,16 @@ struct cfg80211_assoc_request {
  * This structure provides information needed to complete IEEE 802.11
  * deauthentication.
  *
- * @bss: the BSS to deauthenticate from
+ * @bssid: the BSSID of the BSS to deauthenticate from
  * @ie: Extra IEs to add to Deauthentication frame or %NULL
  * @ie_len: Length of ie buffer in octets
  * @reason_code: The reason code for the deauthentication
- * @local_state_change: This is a request for a local state only, i.e., no
- *	Deauthentication frame is to be transmitted.
  */
 struct cfg80211_deauth_request {
-	struct cfg80211_bss *bss;
+	const u8 *bssid;
 	const u8 *ie;
 	size_t ie_len;
 	u16 reason_code;
-	bool local_state_change;
 };
 
 /**
@@ -1148,6 +1147,10 @@ struct cfg80211_disassoc_request {
  * @beacon_interval: beacon interval to use
  * @privacy: this is a protected network, keys will be configured
  *	after joining
+ * @control_port: whether user space controls IEEE 802.1X port, i.e.,
+ *	sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ *	required to assume that the port is unauthorized until authorized by
+ *	user space. Otherwise, port is marked authorized by default.
  * @basic_rates: bitmap of basic rates to use when creating the IBSS
  * @mcast_rate: per-band multicast rate index + 1 (0: disabled)
  */
@@ -1162,6 +1165,7 @@ struct cfg80211_ibss_params {
 	u32 basic_rates;
 	bool channel_fixed;
 	bool privacy;
+	bool control_port;
 	int mcast_rate[IEEE80211_NUM_BANDS];
 };
 
@@ -1229,8 +1233,7 @@ enum wiphy_params_flags {
 struct cfg80211_bitrate_mask {
 	struct {
 		u32 legacy;
-		/* TODO: add support for masking MCS rates; e.g.: */
-		/* u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; */
+		u8 mcs[IEEE80211_HT_MCS_MASK_LEN];
 	} control[IEEE80211_NUM_BANDS];
 };
 /**
@@ -2204,8 +2207,6 @@ struct cfg80211_conn;
 struct cfg80211_internal_bss;
 struct cfg80211_cached_keys;
 
-#define MAX_AUTH_BSSES		4
-
 /**
  * struct wireless_dev - wireless per-netdev state
  *
@@ -2269,8 +2270,6 @@ struct wireless_dev {
 	struct list_head event_list;
 	spinlock_t event_lock;
 
-	struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
-	struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
 	struct cfg80211_internal_bss *current_bss; /* associated / joined */
 	struct ieee80211_channel *channel;
 
@@ -2725,6 +2724,20 @@ struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
 				       struct ieee80211_channel *channel,
 				       const u8 *meshid, size_t meshidlen,
 				       const u8 *meshcfg);
+/**
+ * cfg80211_ref_bss - reference BSS struct
+ * @bss: the BSS struct to reference
+ *
+ * Increments the refcount of the given BSS struct.
+ */
+void cfg80211_ref_bss(struct cfg80211_bss *bss);
+
+/**
+ * cfg80211_put_bss - unref BSS struct
+ * @bss: the BSS struct
+ *
+ * Decrements the refcount of the given BSS struct.
+ */
 void cfg80211_put_bss(struct cfg80211_bss *bss);
 
 /**
@@ -2762,20 +2775,10 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
 
 /**
- * __cfg80211_auth_canceled - notify cfg80211 that authentication was canceled
- * @dev: network device
- * @addr: The MAC address of the device with which the authentication timed out
- *
- * When a pending authentication had no action yet, the driver may decide
- * to not send a deauth frame, but in that case must calls this function
- * to tell cfg80211 about this decision. It is only valid to call this
- * function within the deauth() callback.
- */
-void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr);
-
-/**
  * cfg80211_send_rx_assoc - notification of processed association
  * @dev: network device
+ * @bss: the BSS struct association was requested for, the struct reference
+ *	is owned by cfg80211 after this call
  * @buf: (re)association response frame (header + body)
  * @len: length of the frame data
  *
@@ -2784,7 +2787,8 @@ void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr);
  * function or cfg80211_send_assoc_timeout() to indicate the result of
  * cfg80211_ops::assoc() call. This function may sleep.
  */
-void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
+			    const u8 *buf, size_t len);
 
 /**
  * cfg80211_send_assoc_timeout - notification of timed out association
diff --git a/include/net/dn.h b/include/net/dn.h
index 298521e..814af0b 100644
--- a/include/net/dn.h
+++ b/include/net/dn.h
@@ -3,6 +3,7 @@
 
 #include <linux/dn.h>
 #include <net/sock.h>
+#include <net/flow.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 7db3299..ccb6888 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -131,35 +131,8 @@ extern void genl_unregister_mc_group(struct genl_family *family,
 extern void genl_notify(struct sk_buff *skb, struct net *net, u32 pid,
 			u32 group, struct nlmsghdr *nlh, gfp_t flags);
 
-/**
- * genlmsg_put - Add generic netlink header to netlink message
- * @skb: socket buffer holding the message
- * @pid: netlink pid the message is addressed to
- * @seq: sequence number (usually the one of the sender)
- * @family: generic netlink family
- * @flags netlink message flags
- * @cmd: generic netlink command
- *
- * Returns pointer to user specific header
- */
-static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
-				struct genl_family *family, int flags, u8 cmd)
-{
-	struct nlmsghdr *nlh;
-	struct genlmsghdr *hdr;
-
-	nlh = nlmsg_put(skb, pid, seq, family->id, GENL_HDRLEN +
-			family->hdrsize, flags);
-	if (nlh == NULL)
-		return NULL;
-
-	hdr = nlmsg_data(nlh);
-	hdr->cmd = cmd;
-	hdr->version = family->version;
-	hdr->reserved = 0;
-
-	return (char *) hdr + GENL_HDRLEN;
-}
+void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+				struct genl_family *family, int flags, u8 cmd);
 
 /**
  * genlmsg_nlhdr - Obtain netlink header from user specified header
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index e3e4051..ae17e13 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -132,6 +132,7 @@ struct rtable;
  * @tos - TOS
  * @mc_ttl - Multicasting TTL
  * @is_icsk - is this an inet_connection_sock?
+ * @uc_index - Unicast outgoing device index
  * @mc_index - Multicast device index
  * @mc_list - Group array
  * @cork - info to build ip hdr on each ip frag while socket is corked
@@ -167,6 +168,8 @@ struct inet_sock {
 				transparent:1,
 				mc_all:1,
 				nodefrag:1;
+	__u8			rcv_tos;
+	int			uc_index;
 	int			mc_index;
 	__be32			mc_addr;
 	struct ip_mc_socklist __rcu	*mc_list;
diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h
index 0954ec9..2e1d5ec 100644
--- a/include/net/iucv/af_iucv.h
+++ b/include/net/iucv/af_iucv.h
@@ -113,6 +113,7 @@ struct iucv_sock {
 	spinlock_t		accept_q_lock;
 	struct sock		*parent;
 	struct iucv_path	*path;
+	struct net_device	*hs_dev;
 	struct sk_buff_head	send_skb_q;
 	struct sk_buff_head	backlog_skb_q;
 	struct sock_msg_q	message_q;
@@ -131,6 +132,7 @@ struct iucv_sock {
 /* iucv socket options (SOL_IUCV) */
 #define SO_IPRMDATA_MSG	0x0080		/* send/recv IPRM_DATA msgs */
 #define SO_MSGLIMIT	0x1000		/* get/set IUCV MSGLIMIT */
+#define SO_MSGSIZE	0x0800		/* get maximum msgsize */
 
 /* iucv related control messages (scm) */
 #define SCM_IUCV_TRGCLS	0x0001		/* target class control message */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d49928b..cbff4f9 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -852,6 +852,21 @@ struct ieee80211_channel_switch {
 };
 
 /**
+ * enum ieee80211_vif_flags - virtual interface flags
+ *
+ * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering
+ *	on this virtual interface to avoid unnecessary CPU wakeups
+ * @IEEE80211_VIF_SUPPORTS_CQM_RSSI: the device can do connection quality
+ *	monitoring on this virtual interface -- i.e. it can monitor
+ *	connection quality related parameters, such as the RSSI level and
+ *	provide notifications if configured trigger levels are reached.
+ */
+enum ieee80211_vif_flags {
+	IEEE80211_VIF_BEACON_FILTER		= BIT(0),
+	IEEE80211_VIF_SUPPORTS_CQM_RSSI		= BIT(1),
+};
+
+/**
  * struct ieee80211_vif - per-interface data
  *
  * Data in this structure is continually present for driver
@@ -863,6 +878,10 @@ struct ieee80211_channel_switch {
  * @addr: address of this interface
  * @p2p: indicates whether this AP or STA interface is a p2p
  *	interface, i.e. a GO or p2p-sta respectively
+ * @driver_flags: flags/capabilities the driver has for this interface,
+ *	these need to be set (or cleared) when the interface is added
+ *	or, if supported by the driver, the interface type is changed
+ *	at runtime, mac80211 will never touch this field
  * @drv_priv: data area for driver use, will always be aligned to
  *	sizeof(void *).
  */
@@ -871,6 +890,7 @@ struct ieee80211_vif {
 	struct ieee80211_bss_conf bss_conf;
 	u8 addr[ETH_ALEN];
 	bool p2p;
+	u32 driver_flags;
 	/* must be last */
 	u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
 };
@@ -962,6 +982,25 @@ enum set_key_cmd {
 };
 
 /**
+ * enum ieee80211_sta_state - station state
+ *
+ * @IEEE80211_STA_NOTEXIST: station doesn't exist at all,
+ *	this is a special state for add/remove transitions
+ * @IEEE80211_STA_NONE: station exists without special state
+ * @IEEE80211_STA_AUTH: station is authenticated
+ * @IEEE80211_STA_ASSOC: station is associated
+ * @IEEE80211_STA_AUTHORIZED: station is authorized (802.1X)
+ */
+enum ieee80211_sta_state {
+	/* NOTE: These need to be ordered correctly! */
+	IEEE80211_STA_NOTEXIST,
+	IEEE80211_STA_NONE,
+	IEEE80211_STA_AUTH,
+	IEEE80211_STA_ASSOC,
+	IEEE80211_STA_AUTHORIZED,
+};
+
+/**
  * struct ieee80211_sta - station table entry
  *
  * A station table entry represents a station we are possibly
@@ -1079,10 +1118,6 @@ enum sta_notify_cmd {
  * @IEEE80211_HW_MFP_CAPABLE:
  *	Hardware supports management frame protection (MFP, IEEE 802.11w).
  *
- * @IEEE80211_HW_BEACON_FILTER:
- *	Hardware supports dropping of irrelevant beacon frames to
- *	avoid waking up cpu.
- *
  * @IEEE80211_HW_SUPPORTS_STATIC_SMPS:
  *	Hardware supports static spatial multiplexing powersave,
  *	ie. can turn off all but one chain even on HT connections
@@ -1108,11 +1143,6 @@ enum sta_notify_cmd {
  *      When this flag is set, signaling beacon-loss will cause an immediate
  *      change to disassociated state.
  *
- * @IEEE80211_HW_SUPPORTS_CQM_RSSI:
- *	Hardware can do connection quality monitoring - i.e. it can monitor
- *	connection quality related parameters, such as the RSSI level and
- *	provide notifications if configured trigger levels are reached.
- *
  * @IEEE80211_HW_NEED_DTIM_PERIOD:
  *	This device needs to know the DTIM period for the BSS before
  *	associating.
@@ -1134,6 +1164,10 @@ enum sta_notify_cmd {
  * @IEEE80211_HW_TX_AMPDU_SETUP_IN_HW: The device handles TX A-MPDU session
  *	setup strictly in HW. mac80211 should not attempt to do this in
  *	software.
+ *
+ * @IEEE80211_HW_SCAN_WHILE_IDLE: The device can do hw scan while
+ *	being idle (i.e. mac80211 doesn't have to go idle-off during the
+ *	the scan).
  */
 enum ieee80211_hw_flags {
 	IEEE80211_HW_HAS_RATE_CONTROL			= 1<<0,
@@ -1150,16 +1184,17 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_PS_NULLFUNC_STACK			= 1<<11,
 	IEEE80211_HW_SUPPORTS_DYNAMIC_PS		= 1<<12,
 	IEEE80211_HW_MFP_CAPABLE			= 1<<13,
-	IEEE80211_HW_BEACON_FILTER			= 1<<14,
+	/* reuse bit 14 */
 	IEEE80211_HW_SUPPORTS_STATIC_SMPS		= 1<<15,
 	IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS		= 1<<16,
 	IEEE80211_HW_SUPPORTS_UAPSD			= 1<<17,
 	IEEE80211_HW_REPORTS_TX_ACK_STATUS		= 1<<18,
 	IEEE80211_HW_CONNECTION_MONITOR			= 1<<19,
-	IEEE80211_HW_SUPPORTS_CQM_RSSI			= 1<<20,
+	/* reuse bit 20 */
 	IEEE80211_HW_SUPPORTS_PER_STA_GTK		= 1<<21,
 	IEEE80211_HW_AP_LINK_PS				= 1<<22,
 	IEEE80211_HW_TX_AMPDU_SETUP_IN_HW		= 1<<23,
+	IEEE80211_HW_SCAN_WHILE_IDLE			= 1<<24,
 };
 
 /**
@@ -1446,8 +1481,8 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
  * way the host will only receive beacons where some relevant information
  * (for example ERP protection or WMM settings) have changed.
  *
- * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER
- * hardware capability. The driver needs to enable beacon filter support
+ * Beacon filter support is advertised with the %IEEE80211_VIF_BEACON_FILTER
+ * interface capability. The driver needs to enable beacon filter support
  * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When
  * power save is enabled, the stack will not check for beacon loss and the
  * driver needs to notify about loss of beacons with ieee80211_beacon_loss().
@@ -1963,6 +1998,13 @@ enum ieee80211_frame_release_type {
  *	in AP mode, this callback will not be called when the flag
  *	%IEEE80211_HW_AP_LINK_PS is set. Must be atomic.
  *
+ * @sta_state: Notifies low level driver about state transition of a
+ *	station (which can be the AP, a client, IBSS/WDS/mesh peer etc.)
+ *	This callback is mutually exclusive with @sta_add/@sta_remove.
+ *	It must not fail for down transitions but may fail for transitions
+ *	up the list of states.
+ *	The callback can sleep.
+ *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
  *	bursting) for a hardware TX queue.
  *	Returns a negative error code on failure.
@@ -2182,6 +2224,10 @@ struct ieee80211_ops {
 			  struct ieee80211_sta *sta);
 	void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			enum sta_notify_cmd, struct ieee80211_sta *sta);
+	int (*sta_state)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			 struct ieee80211_sta *sta,
+			 enum ieee80211_sta_state old_state,
+			 enum ieee80211_sta_state new_state);
 	int (*conf_tx)(struct ieee80211_hw *hw,
 		       struct ieee80211_vif *vif, u16 queue,
 		       const struct ieee80211_tx_queue_params *params);
@@ -3316,7 +3362,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
  *
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
  *
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and
+ * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER and
  * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the
  * hardware is not receiving beacons with this function.
  */
@@ -3327,7 +3373,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif);
  *
  * @vif: &struct ieee80211_vif pointer from the add_interface callback.
  *
- * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and
+ * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and
  * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver
  * needs to inform if the connection to the AP has been lost.
  *
@@ -3397,7 +3443,7 @@ void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif);
  * @rssi_event: the RSSI trigger event type
  * @gfp: context flags
  *
- * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality
+ * When the %IEEE80211_VIF_SUPPORTS_CQM_RSSI is set, and a connection quality
  * monitoring is configured with an rssi threshold, the driver will inform
  * whenever the rssi level reaches the threshold.
  */
@@ -3540,6 +3586,7 @@ struct ieee80211_tx_rate_control {
 	bool rts, short_preamble;
 	u8 max_rate_idx;
 	u32 rate_idx_mask;
+	u8 rate_idx_mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 	bool bss;
 };
 
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index e3133c2..6f9c25a 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -133,7 +133,6 @@ extern void			ndisc_send_rs(struct net_device *dev,
 					      const struct in6_addr *daddr);
 
 extern void			ndisc_send_redirect(struct sk_buff *skb,
-						    struct neighbour *neigh,
 						    const struct in6_addr *target);
 
 extern int			ndisc_mc_map(const struct in6_addr *addr, char *buf,
diff --git a/include/net/netlink.h b/include/net/netlink.h
index cb1f350..f394fe5 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -441,41 +441,6 @@ static inline int nlmsg_report(const struct nlmsghdr *nlh)
 	nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
 			  nlmsg_attrlen(nlh, hdrlen), rem)
 
-#if 0
-/* FIXME: Enable once all users have been converted */
-
-/**
- * __nlmsg_put - Add a new netlink message to an skb
- * @skb: socket buffer to store message in
- * @pid: netlink process id
- * @seq: sequence number of message
- * @type: message type
- * @payload: length of message payload
- * @flags: message flags
- *
- * The caller is responsible to ensure that the skb provides enough
- * tailroom for both the netlink header and payload.
- */
-static inline struct nlmsghdr *__nlmsg_put(struct sk_buff *skb, u32 pid,
-					   u32 seq, int type, int payload,
-					   int flags)
-{
-	struct nlmsghdr *nlh;
-
-	nlh = (struct nlmsghdr *) skb_put(skb, nlmsg_total_size(payload));
-	nlh->nlmsg_type = type;
-	nlh->nlmsg_len = nlmsg_msg_size(payload);
-	nlh->nlmsg_flags = flags;
-	nlh->nlmsg_pid = pid;
-	nlh->nlmsg_seq = seq;
-
-	memset((unsigned char *) nlmsg_data(nlh) + payload, 0,
-	       nlmsg_padlen(payload));
-
-	return nlh;
-}
-#endif
-
 /**
  * nlmsg_put - Add a new netlink message to an skb
  * @skb: socket buffer to store message in
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h
index 2be95e2..276094b 100644
--- a/include/net/nfc/nci.h
+++ b/include/net/nfc/nci.h
@@ -116,6 +116,11 @@
 #define NCI_DISC_MAP_MODE_POLL					0x01
 #define NCI_DISC_MAP_MODE_LISTEN				0x02
 
+/* NCI Discover Notification Type */
+#define NCI_DISCOVER_NTF_TYPE_LAST				0x00
+#define NCI_DISCOVER_NTF_TYPE_LAST_NFCC				0x01
+#define NCI_DISCOVER_NTF_TYPE_MORE				0x02
+
 /* NCI Deactivation Type */
 #define NCI_DEACTIVATE_TYPE_IDLE_MODE				0x00
 #define NCI_DEACTIVATE_TYPE_SLEEP_MODE				0x01
@@ -207,6 +212,13 @@ struct nci_rf_disc_cmd {
 	struct disc_config		disc_configs[NCI_MAX_NUM_RF_CONFIGS];
 } __packed;
 
+#define NCI_OP_RF_DISCOVER_SELECT_CMD	nci_opcode_pack(NCI_GID_RF_MGMT, 0x04)
+struct nci_rf_discover_select_cmd {
+	__u8	rf_discovery_id;
+	__u8	rf_protocol;
+	__u8	rf_interface;
+} __packed;
+
 #define NCI_OP_RF_DEACTIVATE_CMD	nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
 struct nci_rf_deactivate_cmd {
 	__u8	type;
@@ -244,6 +256,8 @@ struct nci_core_init_rsp_2 {
 
 #define NCI_OP_RF_DISCOVER_RSP		nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
 
+#define NCI_OP_RF_DISCOVER_SELECT_RSP	nci_opcode_pack(NCI_GID_RF_MGMT, 0x04)
+
 #define NCI_OP_RF_DEACTIVATE_RSP	nci_opcode_pack(NCI_GID_RF_MGMT, 0x06)
 
 /* --------------------------- */
@@ -260,13 +274,15 @@ struct nci_core_conn_credit_ntf {
 	struct conn_credit_entry	conn_entries[NCI_MAX_NUM_CONN];
 } __packed;
 
+#define NCI_OP_CORE_GENERIC_ERROR_NTF	nci_opcode_pack(NCI_GID_CORE, 0x07)
+
 #define NCI_OP_CORE_INTF_ERROR_NTF	nci_opcode_pack(NCI_GID_CORE, 0x08)
 struct nci_core_intf_error_ntf {
 	__u8	status;
 	__u8	conn_id;
 } __packed;
 
-#define NCI_OP_RF_INTF_ACTIVATED_NTF	nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
+#define NCI_OP_RF_DISCOVER_NTF		nci_opcode_pack(NCI_GID_RF_MGMT, 0x03)
 struct rf_tech_specific_params_nfca_poll {
 	__u16	sens_res;
 	__u8	nfcid1_len;	/* 0, 4, 7, or 10 Bytes */
@@ -275,11 +291,43 @@ struct rf_tech_specific_params_nfca_poll {
 	__u8	sel_res;
 } __packed;
 
+struct rf_tech_specific_params_nfcb_poll {
+	__u8	sensb_res_len;
+	__u8	sensb_res[12];	/* 11 or 12 Bytes */
+} __packed;
+
+struct rf_tech_specific_params_nfcf_poll {
+	__u8	bit_rate;
+	__u8	sensf_res_len;
+	__u8	sensf_res[18];	/* 16 or 18 Bytes */
+} __packed;
+
+struct nci_rf_discover_ntf {
+	__u8	rf_discovery_id;
+	__u8	rf_protocol;
+	__u8	rf_tech_and_mode;
+	__u8	rf_tech_specific_params_len;
+
+	union {
+		struct rf_tech_specific_params_nfca_poll nfca_poll;
+		struct rf_tech_specific_params_nfcb_poll nfcb_poll;
+		struct rf_tech_specific_params_nfcf_poll nfcf_poll;
+	} rf_tech_specific_params;
+
+	__u8	ntf_type;
+} __packed;
+
+#define NCI_OP_RF_INTF_ACTIVATED_NTF	nci_opcode_pack(NCI_GID_RF_MGMT, 0x05)
 struct activation_params_nfca_poll_iso_dep {
 	__u8	rats_res_len;
 	__u8	rats_res[20];
 };
 
+struct activation_params_nfcb_poll_iso_dep {
+	__u8	attrib_res_len;
+	__u8	attrib_res[50];
+};
+
 struct nci_rf_intf_activated_ntf {
 	__u8	rf_discovery_id;
 	__u8	rf_interface;
@@ -291,6 +339,8 @@ struct nci_rf_intf_activated_ntf {
 
 	union {
 		struct rf_tech_specific_params_nfca_poll nfca_poll;
+		struct rf_tech_specific_params_nfcb_poll nfcb_poll;
+		struct rf_tech_specific_params_nfcf_poll nfcf_poll;
 	} rf_tech_specific_params;
 
 	__u8	data_exch_rf_tech_and_mode;
@@ -300,6 +350,7 @@ struct nci_rf_intf_activated_ntf {
 
 	union {
 		struct activation_params_nfca_poll_iso_dep nfca_poll_iso_dep;
+		struct activation_params_nfcb_poll_iso_dep nfcb_poll_iso_dep;
 	} activation_params;
 
 } __packed;
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index bccd89e..86fee8b 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -34,21 +34,31 @@
 #include <net/nfc/nfc.h>
 #include <net/nfc/nci.h>
 
-/* NCI device state */
-enum {
+/* NCI device flags */
+enum nci_flag {
 	NCI_INIT,
 	NCI_UP,
+	NCI_DATA_EXCHANGE,
+	NCI_DATA_EXCHANGE_TO,
+};
+
+/* NCI device states */
+enum nci_state {
+	NCI_IDLE,
 	NCI_DISCOVERY,
+	NCI_W4_ALL_DISCOVERIES,
+	NCI_W4_HOST_SELECT,
 	NCI_POLL_ACTIVE,
-	NCI_DATA_EXCHANGE,
 };
 
 /* NCI timeouts */
 #define NCI_RESET_TIMEOUT			5000
 #define NCI_INIT_TIMEOUT			5000
 #define NCI_RF_DISC_TIMEOUT			5000
-#define NCI_RF_DEACTIVATE_TIMEOUT		5000
+#define NCI_RF_DISC_SELECT_TIMEOUT		5000
+#define NCI_RF_DEACTIVATE_TIMEOUT		30000
 #define NCI_CMD_TIMEOUT				5000
+#define NCI_DATA_TIMEOUT			700
 
 struct nci_dev;
 
@@ -59,6 +69,7 @@ struct nci_ops {
 };
 
 #define NCI_MAX_SUPPORTED_RF_INTERFACES		4
+#define NCI_MAX_DISCOVERED_TARGETS		10
 
 /* NCI Core structures */
 struct nci_dev {
@@ -68,12 +79,14 @@ struct nci_dev {
 	int			tx_headroom;
 	int			tx_tailroom;
 
+	atomic_t		state;
 	unsigned long		flags;
 
 	atomic_t		cmd_cnt;
 	atomic_t		credits_cnt;
 
 	struct timer_list	cmd_timer;
+	struct timer_list	data_timer;
 
 	struct workqueue_struct	*cmd_wq;
 	struct work_struct	cmd_work;
@@ -96,9 +109,11 @@ struct nci_dev {
 	void			*driver_data;
 
 	__u32			poll_prots;
-	__u32			target_available_prots;
 	__u32			target_active_prot;
 
+	struct nfc_target	targets[NCI_MAX_DISCOVERED_TARGETS];
+	int			n_targets;
+
 	/* received during NCI_OP_CORE_RESET_RSP */
 	__u8			nci_ver;
 
@@ -169,6 +184,7 @@ int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload);
 int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb);
 void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb,
 				int err);
+void nci_clear_target_list(struct nci_dev *ndev);
 
 /* ----- NCI requests ----- */
 #define NCI_REQ_DONE		0
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index 8696b77..d253278 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -24,6 +24,7 @@
 #ifndef __NET_NFC_H
 #define __NET_NFC_H
 
+#include <linux/nfc.h>
 #include <linux/device.h>
 #include <linux/skbuff.h>
 
@@ -65,7 +66,6 @@ struct nfc_ops {
 
 #define NFC_TARGET_IDX_ANY -1
 #define NFC_MAX_GT_LEN 48
-#define NFC_MAX_NFCID1_LEN 10
 
 struct nfc_target {
 	u32 idx;
@@ -73,7 +73,11 @@ struct nfc_target {
 	u16 sens_res;
 	u8 sel_res;
 	u8 nfcid1_len;
-	u8 nfcid1[NFC_MAX_NFCID1_LEN];
+	u8 nfcid1[NFC_NFCID1_MAXSIZE];
+	u8 sensb_res_len;
+	u8 sensb_res[NFC_SENSB_RES_MAXSIZE];
+	u8 sensf_res_len;
+	u8 sensf_res[NFC_SENSF_RES_MAXSIZE];
 };
 
 struct nfc_genl_data {
@@ -83,7 +87,6 @@ struct nfc_genl_data {
 
 struct nfc_dev {
 	unsigned idx;
-	unsigned target_idx;
 	struct nfc_target *targets;
 	int n_targets;
 	int targets_generation;
diff --git a/include/net/sock.h b/include/net/sock.h
index 91c1c8b..5fbf120 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -56,6 +56,8 @@
 #include <linux/memcontrol.h>
 #include <linux/res_counter.h>
 #include <linux/jump_label.h>
+#include <linux/aio.h>
+#include <linux/sched.h>
 
 #include <linux/filter.h>
 #include <linux/rculist_nulls.h>
@@ -69,7 +71,7 @@ struct cgroup;
 struct cgroup_subsys;
 #ifdef CONFIG_NET
 int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp, struct cgroup_subsys *ss);
+void mem_cgroup_sockets_destroy(struct cgroup *cgrp);
 #else
 static inline
 int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
@@ -77,7 +79,7 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
 	return 0;
 }
 static inline
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp, struct cgroup_subsys *ss)
+void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
 {
 }
 #endif
@@ -357,6 +359,7 @@ struct sock {
 	struct page		*sk_sndmsg_page;
 	struct sk_buff		*sk_send_head;
 	__u32			sk_sndmsg_off;
+	__s32			sk_peek_off;
 	int			sk_write_pending;
 #ifdef CONFIG_SECURITY
 	void			*sk_security;
@@ -373,6 +376,30 @@ struct sock {
 	void                    (*sk_destruct)(struct sock *sk);
 };
 
+static inline int sk_peek_offset(struct sock *sk, int flags)
+{
+	if ((flags & MSG_PEEK) && (sk->sk_peek_off >= 0))
+		return sk->sk_peek_off;
+	else
+		return 0;
+}
+
+static inline void sk_peek_offset_bwd(struct sock *sk, int val)
+{
+	if (sk->sk_peek_off >= 0) {
+		if (sk->sk_peek_off >= val)
+			sk->sk_peek_off -= val;
+		else
+			sk->sk_peek_off = 0;
+	}
+}
+
+static inline void sk_peek_offset_fwd(struct sock *sk, int val)
+{
+	if (sk->sk_peek_off >= 0)
+		sk->sk_peek_off += val;
+}
+
 /*
  * Hashed lists helper routines
  */
@@ -871,8 +898,7 @@ struct proto {
 	 */
 	int			(*init_cgroup)(struct cgroup *cgrp,
 					       struct cgroup_subsys *ss);
-	void			(*destroy_cgroup)(struct cgroup *cgrp,
-						  struct cgroup_subsys *ss);
+	void			(*destroy_cgroup)(struct cgroup *cgrp);
 	struct cg_proto		*(*proto_cgroup)(struct mem_cgroup *memcg);
 #endif
 };
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 42c29bf..6b2acfc 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1138,35 +1138,27 @@ static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
 /* MD5 Signature */
 struct crypto_hash;
 
+union tcp_md5_addr {
+	struct in_addr  a4;
+#if IS_ENABLED(CONFIG_IPV6)
+	struct in6_addr	a6;
+#endif
+};
+
 /* - key database */
 struct tcp_md5sig_key {
-	u8			*key;
+	struct hlist_node	node;
 	u8			keylen;
-};
-
-struct tcp4_md5sig_key {
-	struct tcp_md5sig_key	base;
-	__be32			addr;
-};
-
-struct tcp6_md5sig_key {
-	struct tcp_md5sig_key	base;
-#if 0
-	u32			scope_id;	/* XXX */
-#endif
-	struct in6_addr		addr;
+	u8			family; /* AF_INET or AF_INET6 */
+	union tcp_md5_addr	addr;
+	u8			key[TCP_MD5SIG_MAXKEYLEN];
+	struct rcu_head		rcu;
 };
 
 /* - sock block */
 struct tcp_md5sig_info {
-	struct tcp4_md5sig_key	*keys4;
-#if IS_ENABLED(CONFIG_IPV6)
-	struct tcp6_md5sig_key	*keys6;
-	u32			entries6;
-	u32			alloced6;
-#endif
-	u32			entries4;
-	u32			alloced4;
+	struct hlist_head	head;
+	struct rcu_head		rcu;
 };
 
 /* - pseudo header */
@@ -1203,19 +1195,25 @@ extern int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key,
 			       const struct sock *sk,
 			       const struct request_sock *req,
 			       const struct sk_buff *skb);
-extern struct tcp_md5sig_key * tcp_v4_md5_lookup(struct sock *sk,
-						 struct sock *addr_sk);
-extern int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, u8 *newkey,
-			     u8 newkeylen);
-extern int tcp_v4_md5_do_del(struct sock *sk, __be32 addr);
+extern int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
+			  int family, const u8 *newkey,
+			  u8 newkeylen, gfp_t gfp);
+extern int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr,
+			  int family);
+extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk,
+					 struct sock *addr_sk);
 
 #ifdef CONFIG_TCP_MD5SIG
-#define tcp_twsk_md5_key(twsk)	((twsk)->tw_md5_keylen ? 		 \
-				 &(struct tcp_md5sig_key) {		 \
-					.key = (twsk)->tw_md5_key,	 \
-					.keylen = (twsk)->tw_md5_keylen, \
-				} : NULL)
+extern struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk,
+			const union tcp_md5_addr *addr, int family);
+#define tcp_twsk_md5_key(twsk)	((twsk)->tw_md5_key)
 #else
+static inline struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk,
+					 const union tcp_md5_addr *addr,
+					 int family)
+{
+	return NULL;
+}
 #define tcp_twsk_md5_key(twsk)	NULL
 #endif
 
@@ -1470,10 +1468,6 @@ struct tcp_sock_af_ops {
 						  const struct sock *sk,
 						  const struct request_sock *req,
 						  const struct sk_buff *skb);
-	int			(*md5_add) (struct sock *sk,
-					    struct sock *addr_sk,
-					    u8 *newkey,
-					    u8 len);
 	int			(*md5_parse) (struct sock *sk,
 					      char __user *optval,
 					      int optlen);
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 3512082..48410ff 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -13,7 +13,7 @@ struct tcp_memcontrol {
 
 struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
 int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
+void tcp_destroy_cgroup(struct cgroup *cgrp);
 unsigned long long tcp_max_memory(const struct mem_cgroup *memcg);
 void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx);
 #endif /* _TCP_MEMCG_H */
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
index 652dec2..0d7d67e 100644
--- a/include/scsi/fc/fc_fcp.h
+++ b/include/scsi/fc/fc_fcp.h
@@ -20,6 +20,8 @@
 #ifndef _FC_FCP_H_
 #define	_FC_FCP_H_
 
+#include <scsi/scsi.h>
+
 /*
  * Fibre Channel Protocol for SCSI.
  * From T10 FCP-3, T10 project 1560-D Rev 4, Sept. 13, 2005.
@@ -45,7 +47,7 @@
  * FCP_CMND IU Payload.
  */
 struct fcp_cmnd {
-	__u8		fc_lun[8];	/* logical unit number */
+	struct scsi_lun	fc_lun;		/* logical unit number */
 	__u8		fc_cmdref;	/* command reference number */
 	__u8		fc_pri_ta;	/* priority and task attribute */
 	__u8		fc_tm_flags;	/* task management flags */
@@ -57,7 +59,7 @@ struct fcp_cmnd {
 #define	FCP_CMND_LEN	32	/* expected length of structure */
 
 struct fcp_cmnd32 {
-	__u8		fc_lun[8];	/* logical unit number */
+	struct scsi_lun	fc_lun;		/* logical unit number */
 	__u8		fc_cmdref;	/* command reference number */
 	__u8		fc_pri_ta;	/* priority and task attribute */
 	__u8		fc_tm_flags;	/* task management flags */
diff --git a/include/scsi/fc/fc_ms.h b/include/scsi/fc/fc_ms.h
new file mode 100644
index 0000000..f52b921
--- /dev/null
+++ b/include/scsi/fc/fc_ms.h
@@ -0,0 +1,213 @@
+/* * Copyright(c) 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FC_MS_H_
+#define	_FC_MS_H_
+
+#include <linux/types.h>
+
+/*
+ * Fibre Channel Services - Management Service (MS)
+ * From T11.org FC-GS-4 Rev 7.91 February 4, 2004
+ */
+
+/*
+ * Fabric Device Management Interface
+ */
+
+/*
+ * Common-transport sub-type for FDMI
+ */
+#define	FC_FDMI_SUBTYPE	    0x10 /* fs_ct_hdr.ct_fs_subtype */
+
+/*
+ * Management server FDMI Requests.
+ */
+enum fc_fdmi_req {
+	FC_FDMI_GRHL = 0x0100,	/* Get Registered HBA List */
+	FC_FDMI_GHAT = 0x0101,	/* Get HBA Attributes */
+	FC_FDMI_GRPL = 0x0102,	/* Get Registered Port List */
+	FC_FDMI_GPAT = 0x0110,	/* Get Port Attributes */
+	FC_FDMI_RHBA = 0x0200,	/* Register HBA */
+	FC_FDMI_RHAT = 0x0201,	/* Register HBA Attributes */
+	FC_FDMI_RPRT = 0x0210,	/* Register Port */
+	FC_FDMI_RPA = 0x0211,	/* Register Port Attributes */
+	FC_FDMI_DHBA = 0x0300,	/* Deregister HBA */
+	FC_FDMI_DHAT = 0x0301,	/* Deregister HBA Attributes */
+	FC_FDMI_DPRT = 0x0310,	/* Deregister Port */
+	FC_FDMI_DPA = 0x0311,	/* Deregister Port Attributes */
+};
+
+/*
+ * HBA Attribute Entry Type
+ */
+enum fc_fdmi_hba_attr_type {
+	FC_FDMI_HBA_ATTR_NODENAME = 0x0001,
+	FC_FDMI_HBA_ATTR_MANUFACTURER = 0x0002,
+	FC_FDMI_HBA_ATTR_SERIALNUMBER = 0x0003,
+	FC_FDMI_HBA_ATTR_MODEL = 0x0004,
+	FC_FDMI_HBA_ATTR_MODELDESCRIPTION = 0x0005,
+	FC_FDMI_HBA_ATTR_HARDWAREVERSION = 0x0006,
+	FC_FDMI_HBA_ATTR_DRIVERVERSION = 0x0007,
+	FC_FDMI_HBA_ATTR_OPTIONROMVERSION = 0x0008,
+	FC_FDMI_HBA_ATTR_FIRMWAREVERSION = 0x0009,
+	FC_FDMI_HBA_ATTR_OSNAMEVERSION = 0x000A,
+	FC_FDMI_HBA_ATTR_MAXCTPAYLOAD = 0x000B,
+};
+
+/*
+ * HBA Attribute Length
+ */
+#define FC_FDMI_HBA_ATTR_NODENAME_LEN		8
+#define FC_FDMI_HBA_ATTR_MANUFACTURER_LEN	64
+#define FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN	64
+#define FC_FDMI_HBA_ATTR_MODEL_LEN		256
+#define FC_FDMI_HBA_ATTR_MODELDESCR_LEN		256
+#define FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN	256
+#define FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN	256
+#define FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN	256
+#define FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN	256
+#define FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN	256
+#define FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN	4
+
+/*
+ * Port Attribute Type
+ */
+enum fc_fdmi_port_attr_type {
+	FC_FDMI_PORT_ATTR_FC4TYPES = 0x0001,
+	FC_FDMI_PORT_ATTR_SUPPORTEDSPEED = 0x0002,
+	FC_FDMI_PORT_ATTR_CURRENTPORTSPEED = 0x0003,
+	FC_FDMI_PORT_ATTR_MAXFRAMESIZE = 0x0004,
+	FC_FDMI_PORT_ATTR_OSDEVICENAME = 0x0005,
+	FC_FDMI_PORT_ATTR_HOSTNAME = 0x0006,
+};
+
+/*
+ * Port Attribute Length
+ */
+#define FC_FDMI_PORT_ATTR_FC4TYPES_LEN		32
+#define FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN	4
+#define FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN	4
+#define FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN	4
+#define FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN	256
+#define FC_FDMI_PORT_ATTR_HOSTNAME_LEN		256
+
+/*
+ * HBA Attribute ID
+ */
+struct fc_fdmi_hba_identifier {
+	__be64		id;
+};
+
+/*
+ * Port Name
+ */
+struct fc_fdmi_port_name {
+	__be64		portname;
+};
+
+/*
+ * Attribute Entry Block for HBA/Port Attributes
+ */
+#define FC_FDMI_ATTR_ENTRY_HEADER_LEN	4
+struct fc_fdmi_attr_entry {
+	__be16		type;
+	__be16		len;
+	__u8		value[1];
+} __attribute__((__packed__));
+
+/*
+ * Common for HBA/Port Attributes
+ */
+struct fs_fdmi_attrs {
+	__be32				numattrs;
+	struct fc_fdmi_attr_entry	attr[1];
+} __attribute__((__packed__));
+
+/*
+ * Registered Port List
+ */
+struct fc_fdmi_rpl {
+	__be32				numport;
+	struct fc_fdmi_port_name	port[1];
+} __attribute__((__packed__));
+
+/*
+ * Register HBA (RHBA)
+ */
+struct fc_fdmi_rhba {
+	struct fc_fdmi_hba_identifier hbaid;
+	struct fc_fdmi_rpl		 port;
+	struct fs_fdmi_attrs		 hba_attrs;
+} __attribute__((__packed__));
+
+/*
+ * Register HBA Attributes (RHAT)
+ */
+struct fc_fdmi_rhat {
+	struct fc_fdmi_hba_identifier hbaid;
+	struct fs_fdmi_attrs		 hba_attrs;
+} __attribute__((__packed__));
+
+/*
+ * Register Port (RPRT)
+ */
+struct fc_fdmi_rprt {
+	struct fc_fdmi_hba_identifier hbaid;
+	struct fc_fdmi_port_name	 port;
+	struct fs_fdmi_attrs		 hba_attrs;
+} __attribute__((__packed__));
+
+/*
+ * Register Port Attributes (RPA)
+ */
+struct fc_fdmi_rpa {
+	struct fc_fdmi_port_name	 port;
+	struct fs_fdmi_attrs		 hba_attrs;
+} __attribute__((__packed__));
+
+/*
+ * Deregister Port (DPRT)
+ */
+struct fc_fdmi_dprt {
+	struct fc_fdmi_port_name	 port;
+} __attribute__((__packed__));
+
+/*
+ * Deregister Port Attributes (DPA)
+ */
+struct fc_fdmi_dpa {
+	struct fc_fdmi_port_name	 port;
+	struct fs_fdmi_attrs		 hba_attrs;
+} __attribute__((__packed__));
+
+/*
+ * Deregister HBA Attributes (DHAT)
+ */
+struct fc_fdmi_dhat {
+	struct fc_fdmi_hba_identifier hbaid;
+} __attribute__((__packed__));
+
+/*
+ * Deregister HBA (DHBA)
+ */
+struct fc_fdmi_dhba {
+	struct fc_fdmi_hba_identifier hbaid;
+} __attribute__((__packed__));
+
+#endif /* _FC_MS_H_ */
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index be418d8..35fd474 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -20,6 +20,7 @@
 #ifndef _FC_ENCODE_H_
 #define _FC_ENCODE_H_
 #include <asm/unaligned.h>
+#include <linux/utsname.h>
 
 /*
  * F_CTL values for simple requests and responses.
@@ -43,6 +44,10 @@ struct fc_ct_req {
 		struct fc_ns_fid fid;
 		struct fc_ns_rsnn snn;
 		struct fc_ns_rspn spn;
+		struct fc_fdmi_rhba rhba;
+		struct fc_fdmi_rpa  rpa;
+		struct fc_fdmi_dprt dprt;
+		struct fc_fdmi_dhba dhba;
 	} payload;
 };
 
@@ -97,7 +102,9 @@ static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
  * returns pointer to ct request.
  */
 static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
-					       unsigned int op, size_t req_size)
+					       unsigned int op, size_t req_size,
+					       enum fc_ct_fs_type fs_type,
+					       u8 subtype)
 {
 	struct fc_ct_req *ct;
 	size_t ct_plen;
@@ -106,14 +113,14 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
 	ct = fc_frame_payload_get(fp, ct_plen);
 	memset(ct, 0, ct_plen);
 	ct->hdr.ct_rev = FC_CT_REV;
-	ct->hdr.ct_fs_type = FC_FST_DIR;
-	ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE;
+	ct->hdr.ct_fs_type = fs_type;
+	ct->hdr.ct_fs_subtype = subtype;
 	ct->hdr.ct_cmd = htons((u16) op);
 	return ct;
 }
 
 /**
- * fc_ct_fill() - Fill in a name service request frame
+ * fc_ct_ns_fill() - Fill in a name service request frame
  * @lport: local port.
  * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
  * @fp: frame to contain payload.
@@ -121,7 +128,7 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
  * @r_ctl: pointer to FC header R_CTL.
  * @fh_type: pointer to FC-4 type.
  */
-static inline int fc_ct_fill(struct fc_lport *lport,
+static inline int fc_ct_ns_fill(struct fc_lport *lport,
 		      u32 fc_id, struct fc_frame *fp,
 		      unsigned int op, enum fc_rctl *r_ctl,
 		      enum fc_fh_type *fh_type)
@@ -131,23 +138,28 @@ static inline int fc_ct_fill(struct fc_lport *lport,
 
 	switch (op) {
 	case FC_NS_GPN_FT:
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft));
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft),
+				    FC_FST_DIR, FC_NS_SUBTYPE);
 		ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 		break;
 
 	case FC_NS_GPN_ID:
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid));
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid),
+				    FC_FST_DIR, FC_NS_SUBTYPE);
+		ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 		hton24(ct->payload.fid.fp_fid, fc_id);
 		break;
 
 	case FC_NS_RFT_ID:
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft));
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft),
+				    FC_FST_DIR, FC_NS_SUBTYPE);
 		hton24(ct->payload.rft.fid.fp_fid, lport->port_id);
 		ct->payload.rft.fts = lport->fcts;
 		break;
 
 	case FC_NS_RFF_ID:
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id));
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id),
+				    FC_FST_DIR, FC_NS_SUBTYPE);
 		hton24(ct->payload.rff.fr_fid.fp_fid, lport->port_id);
 		ct->payload.rff.fr_type = FC_TYPE_FCP;
 		if (lport->service_params & FCP_SPPF_INIT_FCN)
@@ -157,14 +169,16 @@ static inline int fc_ct_fill(struct fc_lport *lport,
 		break;
 
 	case FC_NS_RNN_ID:
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id),
+				    FC_FST_DIR, FC_NS_SUBTYPE);
 		hton24(ct->payload.rn.fr_fid.fp_fid, lport->port_id);
 		put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
 		break;
 
 	case FC_NS_RSPN_ID:
 		len = strnlen(fc_host_symbolic_name(lport->host), 255);
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len);
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn) + len,
+				    FC_FST_DIR, FC_NS_SUBTYPE);
 		hton24(ct->payload.spn.fr_fid.fp_fid, lport->port_id);
 		strncpy(ct->payload.spn.fr_name,
 			fc_host_symbolic_name(lport->host), len);
@@ -173,7 +187,8 @@ static inline int fc_ct_fill(struct fc_lport *lport,
 
 	case FC_NS_RSNN_NN:
 		len = strnlen(fc_host_symbolic_name(lport->host), 255);
-		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len);
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn) + len,
+				    FC_FST_DIR, FC_NS_SUBTYPE);
 		put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);
 		strncpy(ct->payload.snn.fr_name,
 			fc_host_symbolic_name(lport->host), len);
@@ -189,6 +204,330 @@ static inline int fc_ct_fill(struct fc_lport *lport,
 }
 
 /**
+ * fc_ct_ms_fill() - Fill in a mgmt service request frame
+ * @lport: local port.
+ * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
+ * @fp: frame to contain payload.
+ * @op: CT opcode.
+ * @r_ctl: pointer to FC header R_CTL.
+ * @fh_type: pointer to FC-4 type.
+ */
+static inline int fc_ct_ms_fill(struct fc_lport *lport,
+		      u32 fc_id, struct fc_frame *fp,
+		      unsigned int op, enum fc_rctl *r_ctl,
+		      enum fc_fh_type *fh_type)
+{
+	struct fc_ct_req *ct;
+	size_t len;
+	struct fc_fdmi_attr_entry *entry;
+	struct fs_fdmi_attrs *hba_attrs;
+	int numattrs = 0;
+
+	switch (op) {
+	case FC_FDMI_RHBA:
+		numattrs = 10;
+		len = sizeof(struct fc_fdmi_rhba);
+		len -= sizeof(struct fc_fdmi_attr_entry);
+		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
+		len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
+		len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
+		len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
+		len += FC_FDMI_HBA_ATTR_MODEL_LEN;
+		len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
+		len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
+		len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
+		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
+				    FC_FDMI_SUBTYPE);
+
+		/* HBA Identifier */
+		put_unaligned_be64(lport->wwpn, &ct->payload.rhba.hbaid.id);
+		/* Number of Ports - always 1 */
+		put_unaligned_be32(1, &ct->payload.rhba.port.numport);
+		/* Port Name */
+		put_unaligned_be64(lport->wwpn,
+				   &ct->payload.rhba.port.port[0].portname);
+
+		/* HBA Attributes */
+		put_unaligned_be32(numattrs,
+				   &ct->payload.rhba.hba_attrs.numattrs);
+		hba_attrs = &ct->payload.rhba.hba_attrs;
+		entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
+		/* NodeName*/
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_NODENAME_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_NODENAME,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		put_unaligned_be64(lport->wwnn,
+				   (__be64 *)&entry->value[0]);
+
+		/* Manufacturer */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_NODENAME_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_MANUFACTURER_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_MANUFACTURER,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_manufacturer(lport->host),
+			FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
+
+		/* SerialNumber */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_MANUFACTURER_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_SERIALNUMBER,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_serial_number(lport->host),
+			FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
+
+		/* Model */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_SERIALNUMBER_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_MODEL_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_MODEL,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_model(lport->host),
+			FC_FDMI_HBA_ATTR_MODEL_LEN);
+
+		/* Model Description */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_MODEL_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_MODELDESCR_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_MODELDESCRIPTION,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_model_description(lport->host),
+			FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
+
+		/* Hardware Version */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_MODELDESCR_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_HARDWAREVERSION,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_hardware_version(lport->host),
+			FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
+
+		/* Driver Version */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_HARDWAREVERSION_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_DRIVERVERSION,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_driver_version(lport->host),
+			FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
+
+		/* OptionROM Version */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_DRIVERVERSION_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_OPTIONROMVERSION,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_optionrom_version(lport->host),
+			FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
+
+		/* Firmware Version */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_OPTIONROMVERSION_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_FIRMWAREVERSION,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		strncpy((char *)&entry->value,
+			fc_host_firmware_version(lport->host),
+			FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
+
+		/* OS Name and Version */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_HBA_ATTR_FIRMWAREVERSION_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN;
+		put_unaligned_be16(FC_FDMI_HBA_ATTR_OSNAMEVERSION,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		snprintf((char *)&entry->value,
+			FC_FDMI_HBA_ATTR_OSNAMEVERSION_LEN,
+			"%s v%s",
+			init_utsname()->sysname,
+			init_utsname()->release);
+		break;
+	case FC_FDMI_RPA:
+		numattrs = 6;
+		len = sizeof(struct fc_fdmi_rpa);
+		len -= sizeof(struct fc_fdmi_attr_entry);
+		len += (numattrs * FC_FDMI_ATTR_ENTRY_HEADER_LEN);
+		len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
+		len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
+		len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
+		len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
+		len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
+		len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
+		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
+				    FC_FDMI_SUBTYPE);
+
+		/* Port Name */
+		put_unaligned_be64(lport->wwpn,
+				   &ct->payload.rpa.port.portname);
+
+		/* Port Attributes */
+		put_unaligned_be32(numattrs,
+				   &ct->payload.rpa.hba_attrs.numattrs);
+
+		hba_attrs = &ct->payload.rpa.hba_attrs;
+		entry = (struct fc_fdmi_attr_entry *)hba_attrs->attr;
+
+		/* FC4 types */
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_PORT_ATTR_FC4TYPES_LEN;
+		put_unaligned_be16(FC_FDMI_PORT_ATTR_FC4TYPES,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		memcpy(&entry->value, fc_host_supported_fc4s(lport->host),
+		       FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
+
+		/* Supported Speed */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_PORT_ATTR_FC4TYPES_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN;
+		put_unaligned_be16(FC_FDMI_PORT_ATTR_SUPPORTEDSPEED,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+
+		put_unaligned_be32(fc_host_supported_speeds(lport->host),
+				   &entry->value);
+
+		/* Current Port Speed */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN;
+		put_unaligned_be16(FC_FDMI_PORT_ATTR_CURRENTPORTSPEED,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		put_unaligned_be32(lport->link_speed,
+				   &entry->value);
+
+		/* Max Frame Size */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN;
+		put_unaligned_be16(FC_FDMI_PORT_ATTR_MAXFRAMESIZE,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		put_unaligned_be32(fc_host_maxframe_size(lport->host),
+				   &entry->value);
+
+		/* OS Device Name */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN;
+		put_unaligned_be16(FC_FDMI_PORT_ATTR_OSDEVICENAME,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		/* Use the sysfs device name */
+		strncpy((char *)&entry->value,
+			dev_name(&lport->host->shost_gendev),
+			strnlen(dev_name(&lport->host->shost_gendev),
+				FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
+
+		/* Host Name */
+		entry = (struct fc_fdmi_attr_entry *)((char *)entry->value +
+					FC_FDMI_PORT_ATTR_OSDEVICENAME_LEN);
+		len = FC_FDMI_ATTR_ENTRY_HEADER_LEN;
+		len += FC_FDMI_PORT_ATTR_HOSTNAME_LEN;
+		put_unaligned_be16(FC_FDMI_PORT_ATTR_HOSTNAME,
+				   &entry->type);
+		put_unaligned_be16(len, &entry->len);
+		if (strlen(fc_host_system_hostname(lport->host)))
+			strncpy((char *)&entry->value,
+				fc_host_system_hostname(lport->host),
+				strnlen(fc_host_system_hostname(lport->host),
+					FC_FDMI_PORT_ATTR_HOSTNAME_LEN));
+		else
+			strncpy((char *)&entry->value,
+				init_utsname()->nodename,
+				FC_FDMI_PORT_ATTR_HOSTNAME_LEN);
+		break;
+	case FC_FDMI_DPRT:
+		len = sizeof(struct fc_fdmi_dprt);
+		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
+				    FC_FDMI_SUBTYPE);
+		/* Port Name */
+		put_unaligned_be64(lport->wwpn,
+				   &ct->payload.dprt.port.portname);
+		break;
+	case FC_FDMI_DHBA:
+		len = sizeof(struct fc_fdmi_dhba);
+		ct = fc_ct_hdr_fill(fp, op, len, FC_FST_MGMT,
+				    FC_FDMI_SUBTYPE);
+		/* HBA Identifier */
+		put_unaligned_be64(lport->wwpn, &ct->payload.dhba.hbaid.id);
+		break;
+	default:
+		return -EINVAL;
+	}
+	*r_ctl = FC_RCTL_DD_UNSOL_CTL;
+	*fh_type = FC_TYPE_CT;
+	return 0;
+}
+
+/**
+ * fc_ct_fill() - Fill in a common transport service request frame
+ * @lport: local port.
+ * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
+ * @fp: frame to contain payload.
+ * @op: CT opcode.
+ * @r_ctl: pointer to FC header R_CTL.
+ * @fh_type: pointer to FC-4 type.
+ */
+static inline int fc_ct_fill(struct fc_lport *lport,
+		      u32 fc_id, struct fc_frame *fp,
+		      unsigned int op, enum fc_rctl *r_ctl,
+		      enum fc_fh_type *fh_type, u32 *did)
+{
+	int rc = -EINVAL;
+
+	switch (fc_id) {
+	case FC_FID_MGMT_SERV:
+		rc = fc_ct_ms_fill(lport, fc_id, fp, op, r_ctl, fh_type);
+		*did = FC_FID_MGMT_SERV;
+		break;
+	case FC_FID_DIR_SERV:
+	default:
+		rc = fc_ct_ns_fill(lport, fc_id, fp, op, r_ctl, fh_type);
+		*did = FC_FID_DIR_SERV;
+		break;
+	}
+
+	return rc;
+}
+/**
  * fc_plogi_fill - Fill in plogi request frame
  */
 static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp,
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 2703e3b..7ff9678 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -60,6 +60,7 @@ enum iscsi_uevent_e {
 
 	ISCSI_UEVENT_PATH_UPDATE	= UEVENT_BASE + 20,
 	ISCSI_UEVENT_SET_IFACE_PARAMS	= UEVENT_BASE + 21,
+	ISCSI_UEVENT_PING		= UEVENT_BASE + 22,
 
 	/* up events */
 	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1,
@@ -72,6 +73,8 @@ enum iscsi_uevent_e {
 	ISCSI_KEVENT_PATH_REQ		= KEVENT_BASE + 7,
 	ISCSI_KEVENT_IF_DOWN		= KEVENT_BASE + 8,
 	ISCSI_KEVENT_CONN_LOGIN_STATE   = KEVENT_BASE + 9,
+	ISCSI_KEVENT_HOST_EVENT		= KEVENT_BASE + 10,
+	ISCSI_KEVENT_PING_COMP		= KEVENT_BASE + 11,
 };
 
 enum iscsi_tgt_dscvr {
@@ -80,6 +83,13 @@ enum iscsi_tgt_dscvr {
 	ISCSI_TGT_DSCVR_SLP		= 3,
 };
 
+enum iscsi_host_event_code {
+	ISCSI_EVENT_LINKUP		= 1,
+	ISCSI_EVENT_LINKDOWN,
+	/* must always be last */
+	ISCSI_EVENT_MAX,
+};
+
 struct iscsi_uevent {
 	uint32_t type; /* k/u events type */
 	uint32_t iferror; /* carries interface or resource errors */
@@ -178,6 +188,14 @@ struct iscsi_uevent {
 			uint32_t	host_no;
 			uint32_t	count;
 		} set_iface_params;
+		struct msg_iscsi_ping {
+			uint32_t        host_no;
+			uint32_t        iface_num;
+			uint32_t        iface_type;
+			uint32_t        payload_size;
+			uint32_t	pid;	/* unique ping id associated
+						   with each ping request */
+		} iscsi_ping;
 	} u;
 	union {
 		/* messages k -> u */
@@ -222,6 +240,18 @@ struct iscsi_uevent {
 		struct msg_notify_if_down {
 			uint32_t	host_no;
 		} notify_if_down;
+		struct msg_host_event {
+			uint32_t	host_no;
+			uint32_t	data_size;
+			enum iscsi_host_event_code code;
+		} host_event;
+		struct msg_ping_comp {
+			uint32_t        host_no;
+			uint32_t        status;
+			uint32_t	pid;	/* unique ping id associated
+						   with each ping request */
+			uint32_t        data_size;
+		} ping_comp;
 	} r;
 } __attribute__ ((aligned (sizeof(uint64_t))));
 
@@ -416,9 +446,26 @@ enum iscsi_host_param {
 	ISCSI_HOST_PARAM_INITIATOR_NAME,
 	ISCSI_HOST_PARAM_NETDEV_NAME,
 	ISCSI_HOST_PARAM_IPADDRESS,
+	ISCSI_HOST_PARAM_PORT_STATE,
+	ISCSI_HOST_PARAM_PORT_SPEED,
 	ISCSI_HOST_PARAM_MAX,
 };
 
+/* iSCSI port Speed */
+enum iscsi_port_speed {
+	ISCSI_PORT_SPEED_UNKNOWN	= 0x1,
+	ISCSI_PORT_SPEED_10MBPS		= 0x2,
+	ISCSI_PORT_SPEED_100MBPS	= 0x4,
+	ISCSI_PORT_SPEED_1GBPS		= 0x8,
+	ISCSI_PORT_SPEED_10GBPS		= 0x10,
+};
+
+/* iSCSI port state */
+enum iscsi_port_state {
+	ISCSI_PORT_STATE_DOWN		= 0x1,
+	ISCSI_PORT_STATE_UP		= 0x2,
+};
+
 #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
 #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
 
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 6a3922f..8f9dfba 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -30,6 +30,7 @@
 
 #include <scsi/fc/fc_fcp.h>
 #include <scsi/fc/fc_ns.h>
+#include <scsi/fc/fc_ms.h>
 #include <scsi/fc/fc_els.h>
 #include <scsi/fc/fc_gs.h>
 
@@ -52,6 +53,8 @@
  * @LPORT_ST_RPN_ID:   Register port name by ID (RPN_ID) sent
  * @LPORT_ST_RFT_ID:   Register Fibre Channel types by ID (RFT_ID) sent
  * @LPORT_ST_RFF_ID:   Register FC-4 Features by ID (RFF_ID) sent
+ * @LPORT_ST_FDMI:     Waiting for mgmt server rport to become ready
+ * @LPORT_ST_RHBA:
  * @LPORT_ST_SCR:      State Change Register (SCR) sent
  * @LPORT_ST_READY:    Ready for use
  * @LPORT_ST_LOGO:     Local port logout (LOGO) sent
@@ -66,6 +69,11 @@ enum fc_lport_state {
 	LPORT_ST_RSPN_ID,
 	LPORT_ST_RFT_ID,
 	LPORT_ST_RFF_ID,
+	LPORT_ST_FDMI,
+	LPORT_ST_RHBA,
+	LPORT_ST_RPA,
+	LPORT_ST_DHBA,
+	LPORT_ST_DPRT,
 	LPORT_ST_SCR,
 	LPORT_ST_READY,
 	LPORT_ST_LOGO,
@@ -797,6 +805,7 @@ enum fc_lport_event {
  * @host:                  The SCSI host associated with a local port
  * @ema_list:              Exchange manager anchor list
  * @dns_rdata:             The directory server remote port
+ * @ms_rdata:		   The management server remote port
  * @ptp_rdata:             Point to point remote port
  * @scsi_priv:             FCP layer internal data
  * @disc:                  Discovery context
@@ -842,6 +851,7 @@ struct fc_lport {
 	struct Scsi_Host	       *host;
 	struct list_head	       ema_list;
 	struct fc_rport_priv	       *dns_rdata;
+	struct fc_rport_priv	       *ms_rdata;
 	struct fc_rport_priv	       *ptp_rdata;
 	void			       *scsi_priv;
 	struct fc_disc                 disc;
@@ -877,6 +887,7 @@ struct fc_lport {
 	u32			       does_npiv:1;
 	u32			       npiv_enabled:1;
 	u32			       point_to_multipoint:1;
+	u32			       fdmi_enabled:1;
 	u32			       mfs;
 	u8			       max_retry_count;
 	u8			       max_rport_retry_count;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index cedcff3..6e33386 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -268,7 +268,7 @@ struct iscsi_session {
 	int			lu_reset_timeout;
 	int			tgt_reset_timeout;
 	int			initial_r2t_en;
-	unsigned		max_r2t;
+	unsigned short		max_r2t;
 	int			imm_data_en;
 	unsigned		first_burst;
 	unsigned		max_burst;
@@ -284,6 +284,7 @@ struct iscsi_session {
 	char			*password;
 	char			*password_in;
 	char			*targetname;
+	char			*targetalias;
 	char			*ifacename;
 	char			*initiatorname;
 	/* control data */
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h
index ac0cc1d..215469a 100644
--- a/include/scsi/libiscsi_tcp.h
+++ b/include/scsi/libiscsi_tcp.h
@@ -128,7 +128,7 @@ extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn);
 /* misc helpers */
 extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session);
 extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session);
-
+extern int iscsi_tcp_set_max_r2t(struct iscsi_conn *conn, char *buf);
 extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
 				     struct iscsi_stats *stats);
 #endif /* LIBISCSI_TCP_H */
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 6a308d4..4e84ef3 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -86,7 +86,9 @@ enum discover_event {
 	DISCE_DISCOVER_DOMAIN   = 0U,
 	DISCE_REVALIDATE_DOMAIN = 1,
 	DISCE_PORT_GONE         = 2,
-	DISC_NUM_EVENTS 	= 3,
+	DISCE_PROBE		= 3,
+	DISCE_DESTRUCT		= 4,
+	DISC_NUM_EVENTS		= 5,
 };
 
 /* ---------- Expander Devices ---------- */
@@ -151,6 +153,8 @@ struct expander_device {
 
 	struct ex_phy *ex_phy;
 	struct sas_port *parent_port;
+
+	struct mutex cmd_mutex;
 };
 
 /* ---------- SATA device ---------- */
@@ -162,22 +166,21 @@ enum ata_command_set {
 struct sata_device {
         enum   ata_command_set command_set;
         struct smp_resp        rps_resp; /* report_phy_sata_resp */
-        __le16 *identify_device;
-        __le16 *identify_packet_device;
-
         u8     port_no;        /* port number, if this is a PM (Port) */
         struct list_head children; /* PM Ports if this is a PM */
 
 	struct ata_port *ap;
 	struct ata_host ata_host;
 	struct ata_taskfile tf;
-	u32 sstatus;
-	u32 serror;
-	u32 scontrol;
 };
 
-/* ---------- Domain device ---------- */
+enum {
+	SAS_DEV_GONE,
+	SAS_DEV_DESTROY,
+};
+
 struct domain_device {
+	spinlock_t done_lock;
         enum sas_dev_type dev_type;
 
         enum sas_linkrate linkrate;
@@ -189,8 +192,10 @@ struct domain_device {
         struct domain_device *parent;
         struct list_head siblings; /* devices on the same level */
         struct asd_sas_port *port;        /* shortcut to root of the tree */
+	struct sas_phy *phy;
 
         struct list_head dev_list_node;
+	struct list_head disco_list_node; /* awaiting probe or destruct */
 
         enum sas_protocol    iproto;
         enum sas_protocol    tproto;
@@ -208,7 +213,8 @@ struct domain_device {
         };
 
         void *lldd_dev;
-	int gone;
+	unsigned long state;
+	struct kref kref;
 };
 
 struct sas_discovery_event {
@@ -217,7 +223,6 @@ struct sas_discovery_event {
 };
 
 struct sas_discovery {
-	spinlock_t disc_event_lock;
 	struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
 	unsigned long    pending;
 	u8     fanout_sas_addr[8];
@@ -226,7 +231,6 @@ struct sas_discovery {
 	int    max_level;
 };
 
-
 /* The port struct is Class:RW, driver:RO */
 struct asd_sas_port {
 /* private: */
@@ -236,9 +240,10 @@ struct asd_sas_port {
 	struct domain_device *port_dev;
 	spinlock_t dev_list_lock;
 	struct list_head dev_list;
+	struct list_head disco_list;
+	struct list_head destroy_list;
 	enum   sas_linkrate linkrate;
 
-	struct sas_phy *phy;
 	struct work_struct work;
 
 /* public: */
@@ -274,7 +279,6 @@ struct asd_sas_event {
  */
 struct asd_sas_phy {
 /* private: */
-	/* protected by ha->event_lock */
 	struct asd_sas_event   port_events[PORT_NUM_EVENTS];
 	struct asd_sas_event   phy_events[PHY_NUM_EVENTS];
 
@@ -320,6 +324,7 @@ struct asd_sas_phy {
 struct scsi_core {
 	struct Scsi_Host *shost;
 
+	struct mutex	  task_queue_flush;
 	spinlock_t        task_queue_lock;
 	struct list_head  task_queue;
 	int               task_queue_size;
@@ -334,18 +339,23 @@ struct sas_ha_event {
 
 enum sas_ha_state {
 	SAS_HA_REGISTERED,
-	SAS_HA_UNREGISTERED
+	SAS_HA_DRAINING,
+	SAS_HA_ATA_EH_ACTIVE,
+	SAS_HA_FROZEN,
 };
 
 struct sas_ha_struct {
 /* private: */
-	spinlock_t       event_lock;
 	struct sas_ha_event ha_events[HA_NUM_EVENTS];
 	unsigned long	 pending;
 
-	enum sas_ha_state state;
+	struct list_head  defer_q; /* work queued while draining */
+	struct mutex	  drain_mutex;
+	unsigned long	  state;
 	spinlock_t 	  state_lock;
 
+	struct mutex disco_mutex;
+
 	struct scsi_core core;
 
 /* public: */
@@ -374,7 +384,8 @@ struct sas_ha_struct {
 
 	void *lldd_ha;		  /* not touched by sas class code */
 
-	struct list_head eh_done_q;
+	struct list_head eh_done_q;  /* complete via scsi_eh_flush_done_q */
+	struct list_head eh_ata_q; /* scmds to promote from sas to ata eh */
 };
 
 #define SHOST_TO_SAS_HA(_shost) (*(struct sas_ha_struct **)(_shost)->hostdata)
@@ -418,6 +429,11 @@ static inline unsigned int to_sas_gpio_od(int device, int bit)
 	return 3 * device + bit;
 }
 
+static inline void sas_put_local_phy(struct sas_phy *phy)
+{
+	put_device(&phy->dev);
+}
+
 #ifdef CONFIG_SCSI_SAS_HOST_SMP
 int try_test_sas_gpio_gp_bit(unsigned int od, u8 *data, u8 index, u8 count);
 #else
@@ -447,7 +463,10 @@ enum service_response {
 };
 
 enum exec_status {
-	/* The SAM_STAT_.. codes fit in the lower 6 bits */
+	/* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of
+	 * them here to silence 'case value not in enumerated type' warnings
+	 */
+	__SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
 
 	SAS_DEV_NO_RESPONSE = 0x80,
 	SAS_DATA_UNDERRUN,
@@ -487,10 +506,6 @@ enum exec_status {
 struct ata_task_resp {
 	u16  frame_len;
 	u8   ending_fis[24];	  /* dev to host or data-in */
-	u32  sstatus;
-	u32  serror;
-	u32  scontrol;
-	u32  sactive;
 };
 
 #define SAS_STATUS_BUF_SIZE 96
@@ -553,10 +568,6 @@ struct sas_task {
 
 	enum   sas_protocol      task_proto;
 
-	/* Used by the discovery code. */
-	struct timer_list     timer;
-	struct completion     completion;
-
 	union {
 		struct sas_ata_task ata_task;
 		struct sas_smp_task smp_task;
@@ -573,8 +584,15 @@ struct sas_task {
 
 	void   *lldd_task;	  /* for use by LLDDs */
 	void   *uldd_task;
+	struct sas_task_slow *slow_task;
+};
 
-	struct work_struct abort_work;
+struct sas_task_slow {
+	/* standard/extra infrastructure for slow path commands (SMP and
+	 * internal lldd commands
+	 */
+	struct timer_list     timer;
+	struct completion     completion;
 };
 
 #define SAS_TASK_STATE_PENDING      1
@@ -584,6 +602,7 @@ struct sas_task {
 #define SAS_TASK_AT_INITIATOR       16
 
 extern struct sas_task *sas_alloc_task(gfp_t flags);
+extern struct sas_task *sas_alloc_slow_task(gfp_t flags);
 extern void sas_free_task(struct sas_task *task);
 
 struct sas_domain_function_template {
@@ -604,7 +623,8 @@ struct sas_domain_function_template {
 	int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
 	int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
 	int (*lldd_I_T_nexus_reset)(struct domain_device *);
-	int (*lldd_ata_soft_reset)(struct domain_device *);
+	int (*lldd_ata_check_ready)(struct domain_device *);
+	void (*lldd_ata_set_dmamode)(struct domain_device *);
 	int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
 	int (*lldd_query_task)(struct sas_task *);
 
@@ -625,14 +645,11 @@ extern int sas_unregister_ha(struct sas_ha_struct *);
 
 int sas_set_phy_speed(struct sas_phy *phy,
 		      struct sas_phy_linkrates *rates);
-int sas_phy_enable(struct sas_phy *phy, int enabled);
 int sas_phy_reset(struct sas_phy *phy, int hard_reset);
 int sas_queue_up(struct sas_task *task);
 extern int sas_queuecommand(struct Scsi_Host * ,struct scsi_cmnd *);
 extern int sas_target_alloc(struct scsi_target *);
-extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_slave_configure(struct scsi_device *);
-extern void sas_slave_destroy(struct scsi_device *);
 extern int sas_change_queue_depth(struct scsi_device *, int new_depth,
 				  int reason);
 extern int sas_change_queue_type(struct scsi_device *, int qt);
@@ -649,7 +666,7 @@ void sas_init_ex_attr(void);
 
 int  sas_ex_revalidate_domain(struct domain_device *);
 
-void sas_unregister_domain_devices(struct asd_sas_port *port);
+void sas_unregister_domain_devices(struct asd_sas_port *port, int gone);
 void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *);
 int  sas_discover_event(struct asd_sas_port *, enum discover_event ev);
 
@@ -661,20 +678,21 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *);
 void sas_init_dev(struct domain_device *);
 
 void sas_task_abort(struct sas_task *);
-int __sas_task_abort(struct sas_task *);
+int sas_eh_abort_handler(struct scsi_cmnd *cmd);
 int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
 int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);
 
 extern void sas_target_destroy(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
 extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
+extern int sas_drain_work(struct sas_ha_struct *ha);
 
 extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 			   struct request *req);
 
 extern void sas_ssp_task_response(struct device *dev, struct sas_task *task,
 				  struct ssp_response_iu *iu);
-struct sas_phy *sas_find_local_phy(struct domain_device *dev);
+struct sas_phy *sas_get_local_phy(struct domain_device *dev);
 
 int sas_request_addr(struct Scsi_Host *shost, u8 *addr);
 
diff --git a/include/scsi/sas.h b/include/scsi/sas.h
index 3673d68..a577a83 100644
--- a/include/scsi/sas.h
+++ b/include/scsi/sas.h
@@ -89,8 +89,7 @@ enum sas_oob_mode {
 	SAS_OOB_MODE
 };
 
-/* See sas_discover.c if you plan on changing these.
- */
+/* See sas_discover.c if you plan on changing these */
 enum sas_dev_type {
 	NO_DEVICE   = 0,	  /* protocol */
 	SAS_END_DEV = 1,	  /* protocol */
@@ -100,6 +99,7 @@ enum sas_dev_type {
 	SATA_DEV    = 5,
 	SATA_PM     = 7,
 	SATA_PM_PORT= 8,
+	SATA_PENDING  = 9,
 };
 
 enum sas_protocol {
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
index 9c159f7..cdccd2e 100644
--- a/include/scsi/sas_ata.h
+++ b/include/scsi/sas_ata.h
@@ -32,19 +32,19 @@
 
 static inline int dev_is_sata(struct domain_device *dev)
 {
-	return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA);
+	return dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM ||
+	       dev->dev_type == SATA_PM_PORT || dev->dev_type == SATA_PENDING;
 }
 
-int sas_ata_init_host_and_port(struct domain_device *found_dev,
-			       struct scsi_target *starget);
-
+int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy);
+int sas_ata_init_host_and_port(struct domain_device *found_dev);
 void sas_ata_task_abort(struct sas_task *task);
 void sas_ata_strategy_handler(struct Scsi_Host *shost);
-int sas_ata_timed_out(struct scsi_cmnd *cmd, struct sas_task *task,
-		      enum blk_eh_timer_return *rtn);
-int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
-	       struct list_head *done_q);
-
+void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
+		struct list_head *done_q);
+void sas_ata_schedule_reset(struct domain_device *dev);
+void sas_ata_wait_eh(struct domain_device *dev);
+void sas_probe_sata(struct asd_sas_port *port);
 #else
 
 
@@ -52,8 +52,7 @@ static inline int dev_is_sata(struct domain_device *dev)
 {
 	return 0;
 }
-static inline int sas_ata_init_host_and_port(struct domain_device *found_dev,
-			       struct scsi_target *starget)
+static inline int sas_ata_init_host_and_port(struct domain_device *found_dev)
 {
 	return 0;
 }
@@ -65,18 +64,27 @@ static inline void sas_ata_strategy_handler(struct Scsi_Host *shost)
 {
 }
 
-static inline int sas_ata_timed_out(struct scsi_cmnd *cmd,
-				    struct sas_task *task,
-				    enum blk_eh_timer_return *rtn)
+static inline void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
+			      struct list_head *done_q)
 {
-	return 0;
 }
-static inline int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
-			     struct list_head *done_q)
+
+static inline void sas_ata_schedule_reset(struct domain_device *dev)
+{
+}
+
+static inline void sas_ata_wait_eh(struct domain_device *dev)
+{
+}
+
+static inline void sas_probe_sata(struct asd_sas_port *port)
 {
-	return 0;
 }
 
+static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
+{
+	return 0;
+}
 #endif
 
 #endif /* _SAS_ATA_H_ */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 8001ae4..529dfe0 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -143,6 +143,7 @@ struct scsi_cmnd;
 #define READ_ATTRIBUTE        0x8c
 #define WRITE_ATTRIBUTE	      0x8d
 #define VERIFY_16	      0x8f
+#define SYNCHRONIZE_CACHE_16  0x91
 #define WRITE_SAME_16	      0x93
 #define SERVICE_ACTION_IN     0x9e
 /* values for service action in */
@@ -213,6 +214,16 @@ scsi_command_size(const unsigned char *cmnd)
 		scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]);
 }
 
+#ifdef CONFIG_ACPI
+struct acpi_bus_type;
+
+extern int
+scsi_register_acpi_bus_type(struct acpi_bus_type *bus);
+
+static inline void
+scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus) { return; }
+#endif
+
 /*
  *  SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft
  *  T10/1561-D Revision 4 Draft dated 7th November 2002.
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index a5e885a..377df4a 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -10,6 +10,7 @@
 
 struct Scsi_Host;
 struct scsi_device;
+struct scsi_driver;
 
 /*
  * MAX_COMMAND_SIZE is:
@@ -131,6 +132,11 @@ struct scsi_cmnd {
 	unsigned char tag;	/* SCSI-II queued command tag */
 };
 
+static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
+{
+	return *(struct scsi_driver **)cmd->request->rq_disk->private_data;
+}
+
 extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);
 extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t);
 extern void scsi_put_command(struct scsi_cmnd *);
@@ -289,17 +295,17 @@ static inline struct scsi_data_buffer *scsi_prot(struct scsi_cmnd *cmd)
 
 static inline void set_msg_byte(struct scsi_cmnd *cmd, char status)
 {
-	cmd->result |= status << 8;
+	cmd->result = (cmd->result & 0xffff00ff) | (status << 8);
 }
 
 static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
 {
-	cmd->result |= status << 16;
+	cmd->result = (cmd->result & 0xff00ffff) | (status << 16);
 }
 
 static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
 {
-	cmd->result |= status << 24;
+	cmd->result = (cmd->result & 0x00ffffff) | (status << 24);
 }
 
 #endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 77273f2..b3a1c2d 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -136,6 +136,7 @@ struct scsi_device {
 	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
 	unsigned skip_ms_page_8:1;	/* do not use MODE SENSE page 0x08 */
 	unsigned skip_ms_page_3f:1;	/* do not use MODE SENSE page 0x3f */
+	unsigned skip_vpd_pages:1;	/* do not read VPD pages */
 	unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
 	unsigned no_start_on_add:1;	/* do not issue start on add */
 	unsigned allow_restart:1; /* issue START_UNIT in error handler */
@@ -246,8 +247,10 @@ struct scsi_target {
 	unsigned int		single_lun:1;	/* Indicates we should only
 						 * allow I/O to one of the luns
 						 * for the device at a time. */
-	unsigned int		pdt_1f_for_no_lun;	/* PDT = 0x1f */
-						/* means no lun present */
+	unsigned int		pdt_1f_for_no_lun:1;	/* PDT = 0x1f
+						 * means no lun present. */
+	unsigned int		no_report_luns:1;	/* Don't use
+						 * REPORT LUNS for scanning. */
 	/* commands actually active on LLD. protected by host lock. */
 	unsigned int		target_busy;
 	/*
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index 9fd6702..d443aa0 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -16,6 +16,7 @@ struct scsi_driver {
 
 	void (*rescan)(struct device *);
 	int (*done)(struct scsi_cmnd *);
+	int (*eh_action)(struct scsi_cmnd *, unsigned char *, int, int);
 };
 #define to_scsi_driver(drv) \
 	container_of((drv), struct scsi_driver, gendrv)
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 2a65167..719faf1 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -126,8 +126,8 @@ enum fc_vport_state {
 					     incapable of reporting */
 #define FC_PORTSPEED_1GBIT		1
 #define FC_PORTSPEED_2GBIT		2
-#define FC_PORTSPEED_4GBIT		4
-#define FC_PORTSPEED_10GBIT		8
+#define FC_PORTSPEED_10GBIT		4
+#define FC_PORTSPEED_4GBIT		8
 #define FC_PORTSPEED_8GBIT		0x10
 #define FC_PORTSPEED_16GBIT		0x20
 #define FC_PORTSPEED_NOT_NEGOTIATED	(1 << 15) /* Speed not established */
@@ -486,6 +486,13 @@ struct fc_host_attrs {
 	u32 maxframe_size;
 	u16 max_npiv_vports;
 	char serial_number[FC_SERIAL_NUMBER_SIZE];
+	char manufacturer[FC_SERIAL_NUMBER_SIZE];
+	char model[FC_SYMBOLIC_NAME_SIZE];
+	char model_description[FC_SYMBOLIC_NAME_SIZE];
+	char hardware_version[FC_VERSION_STRING_SIZE];
+	char driver_version[FC_VERSION_STRING_SIZE];
+	char firmware_version[FC_VERSION_STRING_SIZE];
+	char optionrom_version[FC_VERSION_STRING_SIZE];
 
 	/* Dynamic Attributes */
 	u32 port_id;
@@ -541,6 +548,20 @@ struct fc_host_attrs {
 	(((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports)
 #define fc_host_serial_number(x)	\
 	(((struct fc_host_attrs *)(x)->shost_data)->serial_number)
+#define fc_host_manufacturer(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->manufacturer)
+#define fc_host_model(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->model)
+#define fc_host_model_description(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->model_description)
+#define fc_host_hardware_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->hardware_version)
+#define fc_host_driver_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->driver_version)
+#define fc_host_firmware_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->firmware_version)
+#define fc_host_optionrom_version(x)	\
+	(((struct fc_host_attrs *)(x)->shost_data)->optionrom_version)
 #define fc_host_port_id(x)	\
 	(((struct fc_host_attrs *)(x)->shost_data)->port_id)
 #define fc_host_port_type(x)	\
@@ -700,6 +721,13 @@ struct fc_function_template {
 	unsigned long	show_host_supported_speeds:1;
 	unsigned long	show_host_maxframe_size:1;
 	unsigned long	show_host_serial_number:1;
+	unsigned long	show_host_manufacturer:1;
+	unsigned long	show_host_model:1;
+	unsigned long	show_host_model_description:1;
+	unsigned long	show_host_hardware_version:1;
+	unsigned long	show_host_driver_version:1;
+	unsigned long	show_host_firmware_version:1;
+	unsigned long	show_host_optionrom_version:1;
 	/* host dynamic attributes */
 	unsigned long	show_host_port_id:1;
 	unsigned long	show_host_port_type:1;
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 2c3a46d..aede513 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -144,6 +144,9 @@ struct iscsi_transport {
 				int param, char *buf);
 	umode_t (*attr_is_visible)(int param_type, int param);
 	int (*bsg_request)(struct bsg_job *job);
+	int (*send_ping) (struct Scsi_Host *shost, uint32_t iface_num,
+			  uint32_t iface_type, uint32_t payload_size,
+			  uint32_t pid, struct sockaddr *dst_addr);
 };
 
 /*
@@ -166,6 +169,17 @@ extern int iscsi_offload_mesg(struct Scsi_Host *shost,
 			      struct iscsi_transport *transport, uint32_t type,
 			      char *data, uint16_t data_size);
 
+extern void iscsi_post_host_event(uint32_t host_no,
+				  struct iscsi_transport *transport,
+				  enum iscsi_host_event_code code,
+				  uint32_t data_size,
+				  uint8_t *data);
+
+extern void iscsi_ping_comp_event(uint32_t host_no,
+				  struct iscsi_transport *transport,
+				  uint32_t status, uint32_t pid,
+				  uint32_t data_size, uint8_t *data);
+
 struct iscsi_cls_conn {
 	struct list_head conn_list;	/* item in connlist */
 	void *dd_data;			/* LLD private data */
@@ -238,6 +252,8 @@ struct iscsi_cls_host {
 	atomic_t nr_scans;
 	struct mutex mutex;
 	struct request_queue *bsg_q;
+	uint32_t port_speed;
+	uint32_t port_state;
 };
 
 #define iscsi_job_to_shost(_job) \
@@ -307,5 +323,7 @@ extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
 					      uint32_t iface_num, int dd_size);
 extern void iscsi_destroy_iface(struct iscsi_iface *iface);
 extern struct iscsi_iface *iscsi_lookup_iface(int handle);
+extern char *iscsi_get_port_speed_name(struct Scsi_Host *shost);
+extern char *iscsi_get_port_state_name(struct Scsi_Host *shost);
 
 #endif
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h
index ffeebc3..98b3a20 100644
--- a/include/scsi/scsi_transport_sas.h
+++ b/include/scsi/scsi_transport_sas.h
@@ -75,7 +75,8 @@ struct sas_phy {
 	/* for the list of phys belonging to a port */
 	struct list_head	port_siblings;
 
-	struct work_struct      reset_work;
+	/* available to the lldd */
+	void			*hostdata;
 };
 
 #define dev_to_phy(d) \
@@ -169,6 +170,8 @@ struct sas_function_template {
 	int (*get_bay_identifier)(struct sas_rphy *);
 	int (*phy_reset)(struct sas_phy *, int);
 	int (*phy_enable)(struct sas_phy *, int);
+	int (*phy_setup)(struct sas_phy *);
+	void (*phy_release)(struct sas_phy *);
 	int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *);
 	int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
 };
@@ -194,6 +197,7 @@ void sas_rphy_free(struct sas_rphy *);
 extern int sas_rphy_add(struct sas_rphy *);
 extern void sas_rphy_remove(struct sas_rphy *);
 extern void sas_rphy_delete(struct sas_rphy *);
+extern void sas_rphy_unlink(struct sas_rphy *);
 extern int scsi_is_sas_rphy(const struct device *);
 
 struct sas_port *sas_port_alloc(struct device *, int);
@@ -205,6 +209,12 @@ void sas_port_add_phy(struct sas_port *, struct sas_phy *);
 void sas_port_delete_phy(struct sas_port *, struct sas_phy *);
 void sas_port_mark_backlink(struct sas_port *);
 int scsi_is_sas_port(const struct device *);
+struct sas_phy *sas_port_get_phy(struct sas_port *port);
+static inline void sas_port_put_phy(struct sas_phy *phy)
+{
+	if (phy)
+		put_device(&phy->dev);
+}
 
 extern struct scsi_transport_template *
 sas_attach_transport(struct sas_function_template *);
diff --git a/include/sound/control.h b/include/sound/control.h
index b2796e8..57815f6 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -40,7 +40,7 @@ struct snd_kcontrol_new {
 	snd_ctl_elem_iface_t iface;	/* interface identifier */
 	unsigned int device;		/* device/client number */
 	unsigned int subdevice;		/* subdevice (substream) number */
-	unsigned char *name;		/* ASCII name of item */
+	const unsigned char *name;	/* ASCII name of item */
 	unsigned int index;		/* index of item */
 	unsigned int access;		/* access rights */
 	unsigned int count;		/* count of same elements */
diff --git a/include/sound/max9768.h b/include/sound/max9768.h
new file mode 100644
index 0000000..0f78b41
--- /dev/null
+++ b/include/sound/max9768.h
@@ -0,0 +1,24 @@
+/*
+ * Platform data for MAX9768
+ * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
+ * same licence as the driver
+ */
+
+#ifndef __SOUND_MAX9768_PDATA_H__
+#define __SOUND_MAX9768_PDATA_H__
+
+/**
+ * struct max9768_pdata - optional platform specific MAX9768 configuration
+ * @shdn_gpio:	GPIO to SHDN pin. If not valid, pin must be hardwired HIGH
+ * @mute_gpio:	GPIO to MUTE pin. If not valid, control for mute won't be added
+ * @flags: configuration flags, e.g. set classic PWM mode (check datasheet
+ *         regarding "filterless modulation" which is default).
+ */
+struct max9768_pdata {
+	int shdn_gpio;
+	int mute_gpio;
+	unsigned flags;
+#define MAX9768_FLAG_CLASSIC_PWM	(1 << 0)
+};
+
+#endif /* __SOUND_MAX9768_PDATA_H__*/
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 0cf91b2..1d58d79 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -454,6 +454,7 @@ struct snd_pcm {
 	void *private_data;
 	void (*private_free) (struct snd_pcm *pcm);
 	struct device *dev; /* actual hw device this belongs to */
+	bool internal; /* pcm is for internal use only */
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	struct snd_pcm_oss oss;
 #endif
@@ -475,6 +476,9 @@ extern const struct file_operations snd_pcm_f_ops[2];
 int snd_pcm_new(struct snd_card *card, const char *id, int device,
 		int playback_count, int capture_count,
 		struct snd_pcm **rpcm);
+int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
+		int playback_count, int capture_count,
+		struct snd_pcm **rpcm);
 int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
 
 int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
index 9b1aaca..b457e87 100644
--- a/include/sound/sh_fsi.h
+++ b/include/sound/sh_fsi.h
@@ -72,10 +72,16 @@
 #define SH_FSI_BPFMD_32		(5 << 4)
 #define SH_FSI_BPFMD_16		(6 << 4)
 
+struct sh_fsi_port_info {
+	unsigned long flags;
+	int tx_id;
+	int rx_id;
+	int (*set_rate)(struct device *dev, int rate, int enable);
+};
+
 struct sh_fsi_platform_info {
-	unsigned long porta_flags;
-	unsigned long portb_flags;
-	int (*set_rate)(struct device *dev, int is_porta, int rate, int enable);
+	struct sh_fsi_port_info port_a;
+	struct sh_fsi_port_info port_b;
 };
 
 /*
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 2413acc..adb07fc 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -17,6 +17,7 @@
 #include <linux/list.h>
 
 struct snd_pcm_substream;
+struct snd_soc_dapm_widget;
 
 /*
  * DAI hardware audio formats.
@@ -238,6 +239,9 @@ struct snd_soc_dai {
 	unsigned char pop_wait:1;
 	unsigned char probed:1;
 
+	struct snd_soc_dapm_widget *playback_widget;
+	struct snd_soc_dapm_widget *capture_widget;
+
 	/* DAI DMA data */
 	void *playback_dma_data;
 	void *capture_dma_data;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index d26a9b7..e46107f 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -243,6 +243,10 @@
 {	.id = snd_soc_dapm_supply, .name = wname, .reg = wreg,	\
 	.shift = wshift, .invert = winvert, .event = wevent, \
 	.event_flags = wflags}
+#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay) \
+{	.id = snd_soc_dapm_regulator_supply, .name = wname, \
+	.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
 
 /* dapm kcontrol types */
 #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \
@@ -322,6 +326,8 @@ struct snd_soc_dapm_context;
 
 int dapm_reg_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event);
+int dapm_regulator_event(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event);
 
 /* dapm controls */
 int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
@@ -346,11 +352,12 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *uncontrol);
 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *uncontrol);
-int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
-	const struct snd_soc_dapm_widget *widget);
 int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
 	const struct snd_soc_dapm_widget *widget,
 	int num);
+int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
+				 struct snd_soc_dai *dai);
+int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
 
 /* dapm path setup */
 int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm);
@@ -361,10 +368,16 @@ int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
 			     const struct snd_soc_dapm_route *route, int num);
 
 /* dapm events */
-int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
-	const char *stream, int event);
+int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
+			      struct snd_soc_dai *dai, int event);
 void snd_soc_dapm_shutdown(struct snd_soc_card *card);
 
+/* external DAPM widget events */
+int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
+		struct snd_kcontrol *kcontrol, int connect);
+int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
+				 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e);
+
 /* dapm sys fs - used by the core */
 int snd_soc_dapm_sys_add(struct device *dev);
 void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
@@ -411,9 +424,11 @@ enum snd_soc_dapm_type {
 	snd_soc_dapm_pre,			/* machine specific pre widget - exec first */
 	snd_soc_dapm_post,			/* machine specific post widget - exec last */
 	snd_soc_dapm_supply,		/* power/clock supply */
+	snd_soc_dapm_regulator_supply,	/* external regulator */
 	snd_soc_dapm_aif_in,		/* audio interface input */
 	snd_soc_dapm_aif_out,		/* audio interface output */
 	snd_soc_dapm_siggen,		/* signal generator */
+	snd_soc_dapm_dai,		/* link to DAI structure */
 };
 
 /*
@@ -434,8 +449,8 @@ struct snd_soc_dapm_route {
 
 /* dapm audio path between two widgets */
 struct snd_soc_dapm_path {
-	char *name;
-	char *long_name;
+	const char *name;
+	const char *long_name;
 
 	/* source (input) and sink (output) widgets */
 	struct snd_soc_dapm_widget *source;
@@ -458,13 +473,15 @@ struct snd_soc_dapm_path {
 /* dapm widget */
 struct snd_soc_dapm_widget {
 	enum snd_soc_dapm_type id;
-	char *name;		/* widget name */
-	char *sname;	/* stream name */
+	const char *name;		/* widget name */
+	const char *sname;	/* stream name */
 	struct snd_soc_codec *codec;
 	struct snd_soc_platform *platform;
 	struct list_head list;
 	struct snd_soc_dapm_context *dapm;
 
+	void *priv;				/* widget specific data */
+
 	/* dapm control */
 	short reg;						/* negative reg = no direct dapm */
 	unsigned char shift;			/* bits to shift */
diff --git a/include/sound/soc-dmaengine.h b/include/sound/soc-dmaengine.h
new file mode 100644
index 0000000..b435133
--- /dev/null
+++ b/include/sound/soc-dmaengine.h
@@ -0,0 +1,26 @@
+/*
+ * Generic ASoC DMA engine backend
+ *
+ * Copyright (C) 2012 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _LINUX_SND_SOC_DMAENGINE_H
+#define _LINUX_SND_SOC_DMAENGINE_H
+
+#include <linux/dmaengine.h>
+
+struct soc_dma_config {
+	dma_filter_fn filter;
+	void *data;
+
+	dma_addr_t reg;
+	enum dma_slave_buswidth width;
+	u32 maxburst;
+	size_t align;
+	size_t fifo_size;
+};
+
+#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 0992dff..82bd773 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -185,6 +185,20 @@
 		 .rreg = xreg_right, .shift = xshift, \
 		 .min = xmin, .max = xmax} }
 
+#define SND_SOC_BYTES(xname, xbase, xregs)		      \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
+	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
+	.put = snd_soc_bytes_put, .private_value =	      \
+		((unsigned long)&(struct soc_bytes)           \
+		{.base = xbase, .num_regs = xregs }) }
+
+#define SND_SOC_BYTES_MASK(xname, xbase, xregs, xmask)	      \
+{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,   \
+	.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
+	.put = snd_soc_bytes_put, .private_value =	      \
+		((unsigned long)&(struct soc_bytes)           \
+		{.base = xbase, .num_regs = xregs,	      \
+		 .mask = xmask }) }
 
 /*
  * Simplified versions of above macros, declaring a struct and calculating
@@ -366,12 +380,16 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
  *Controls
  */
 struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
-				  void *data, char *long_name,
+				  void *data, const char *long_name,
 				  const char *prefix);
-int snd_soc_add_controls(struct snd_soc_codec *codec,
+int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
 	const struct snd_kcontrol_new *controls, int num_controls);
 int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
 	const struct snd_kcontrol_new *controls, int num_controls);
+int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
+	const struct snd_kcontrol_new *controls, int num_controls);
+int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
+	const struct snd_kcontrol_new *controls, int num_controls);
 int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_info *uinfo);
 int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
@@ -409,6 +427,13 @@ int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol);
 int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol);
+int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_info *uinfo);
+int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol);
+int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol);
+
 
 /**
  * struct snd_soc_reg_access - Describes whether a given register is
@@ -505,6 +530,7 @@ struct snd_soc_pcm_stream {
 	unsigned int rate_max;		/* max rate */
 	unsigned int channels_min;	/* min channels */
 	unsigned int channels_max;	/* max channels */
+	unsigned int sig_bits;		/* number of bits of content */
 };
 
 /* SoC audio ops */
@@ -559,6 +585,7 @@ struct snd_soc_codec {
 	unsigned int ac97_created:1; /* Codec has been created by SoC */
 	unsigned int sysfs_registered:1; /* codec has been sysfs registered */
 	unsigned int cache_init:1; /* codec cache has been initialized */
+	unsigned int using_regmap:1; /* using regmap access */
 	u32 cache_only;  /* Suppress writes to hardware */
 	u32 cache_sync; /* Cache needs to be synced to hardware */
 
@@ -637,6 +664,8 @@ struct snd_soc_codec_driver {
 	/* codec stream completion event */
 	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
 
+	bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
+
 	/* probe ordering - for components with runtime dependencies */
 	int probe_order;
 	int remove_order;
@@ -698,6 +727,11 @@ struct snd_soc_platform {
 	struct list_head card_list;
 
 	struct snd_soc_dapm_context dapm;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_platform_root;
+	struct dentry *debugfs_dapm;
+#endif
 };
 
 struct snd_soc_dai_link {
@@ -875,6 +909,12 @@ struct soc_mixer_control {
 	unsigned int reg, rreg, shift, rshift, invert;
 };
 
+struct soc_bytes {
+	int base;
+	int num_regs;
+	u32 mask;
+};
+
 /* enumerated kcontrol */
 struct soc_enum {
 	unsigned short reg;
diff --git a/include/sound/version.h b/include/sound/version.h
index 8fc5321..cc75024 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h */
-#define CONFIG_SND_VERSION "1.0.24"
+#define CONFIG_SND_VERSION "1.0.25"
 #define CONFIG_SND_DATE ""
diff --git a/include/sound/wm2200.h b/include/sound/wm2200.h
new file mode 100644
index 0000000..79bf55b
--- /dev/null
+++ b/include/sound/wm2200.h
@@ -0,0 +1,41 @@
+/*
+ * linux/sound/wm2200.h -- Platform data for WM2200
+ *
+ * Copyright 2012 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_WM2200_H
+#define __LINUX_SND_WM2200_H
+
+#define WM2200_GPIO_SET 0x10000
+
+enum wm2200_in_mode {
+	WM2200_IN_SE = 0,
+	WM2200_IN_DIFF = 1,
+	WM2200_IN_DMIC = 2,
+};
+
+enum wm2200_dmic_sup {
+	WM2200_DMIC_SUP_MICVDD = 0,
+	WM2200_DMIC_SUP_MICBIAS1 = 1,
+	WM2200_DMIC_SUP_MICBIAS2 = 2,
+};
+
+struct wm2200_pdata {
+	int reset;      /** GPIO controlling /RESET, if any */
+	int ldo_ena;    /** GPIO controlling LODENA, if any */
+	int irq_flags;
+
+	int gpio_defaults[4];
+
+	enum wm2200_in_mode in_mode[3];
+	enum wm2200_dmic_sup dmic_sup[3];
+
+	int micbias_cfg[2];  /** Register value to configure MICBIAS */
+};
+
+#endif
diff --git a/include/sound/wm8962.h b/include/sound/wm8962.h
index 1750bed..79e6d42 100644
--- a/include/sound/wm8962.h
+++ b/include/sound/wm8962.h
@@ -49,6 +49,12 @@ struct wm8962_pdata {
 	bool irq_active_low;
 
 	bool spk_mono;   /* Speaker outputs tied together as mono */
+
+	/**
+	 * This flag should be set if one or both IN4 inputs is wired
+	 * in a DC measurement configuration.
+	 */
+	bool in4_dc_measure;
 };
 
 #endif
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index dc4e345..a3da23b 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -230,6 +230,7 @@ enum tcm_sense_reason_table {
 enum target_sc_flags_table {
 	TARGET_SCF_BIDI_OP		= 0x01,
 	TARGET_SCF_ACK_KREF		= 0x02,
+	TARGET_SCF_UNKNOWN_SIZE		= 0x04,
 };
 
 /* fabric independent task management function values */
@@ -474,12 +475,6 @@ struct t10_reservation {
 	struct t10_reservation_ops pr_ops;
 };
 
-struct se_queue_req {
-	int			state;
-	struct se_cmd		*cmd;
-	struct list_head	qr_list;
-};
-
 struct se_queue_obj {
 	atomic_t		queue_cnt;
 	spinlock_t		cmd_queue_lock;
@@ -522,6 +517,7 @@ struct se_cmd {
 	/* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */
 	unsigned		check_release:1;
 	unsigned		cmd_wait_set:1;
+	unsigned		unknown_data_length:1;
 	/* See se_cmd_flags_table */
 	u32			se_cmd_flags;
 	u32			se_ordered_id;
@@ -555,23 +551,23 @@ struct se_cmd {
 	unsigned char		*t_task_cdb;
 	unsigned char		__t_task_cdb[TCM_MAX_COMMAND_SIZE];
 	unsigned long long	t_task_lba;
-	int			t_tasks_failed;
 	u32			t_tasks_sg_chained_no;
 	atomic_t		t_fe_count;
 	atomic_t		t_se_count;
 	atomic_t		t_task_cdbs_left;
 	atomic_t		t_task_cdbs_ex_left;
 	atomic_t		t_task_cdbs_sent;
-	atomic_t		t_transport_aborted;
-	atomic_t		t_transport_active;
-	atomic_t		t_transport_complete;
-	atomic_t		t_transport_queue_active;
-	atomic_t		t_transport_sent;
-	atomic_t		t_transport_stop;
-	atomic_t		transport_dev_active;
-	atomic_t		transport_lun_active;
-	atomic_t		transport_lun_fe_stop;
-	atomic_t		transport_lun_stop;
+	unsigned int		transport_state;
+#define CMD_T_ABORTED		(1 << 0)
+#define CMD_T_ACTIVE		(1 << 1)
+#define CMD_T_COMPLETE		(1 << 2)
+#define CMD_T_QUEUED		(1 << 3)
+#define CMD_T_SENT		(1 << 4)
+#define CMD_T_STOP		(1 << 5)
+#define CMD_T_FAILED		(1 << 6)
+#define CMD_T_LUN_STOP		(1 << 7)
+#define CMD_T_LUN_FE_STOP	(1 << 8)
+#define CMD_T_DEV_ACTIVE	(1 << 9)
 	spinlock_t		t_state_lock;
 	struct completion	t_transport_stop_comp;
 	struct completion	transport_lun_fe_stop_comp;
@@ -593,12 +589,12 @@ struct se_cmd {
 };
 
 struct se_tmr_req {
-	/* Task Management function to be preformed */
+	/* Task Management function to be performed */
 	u8			function;
 	/* Task Management response to send */
 	u8			response;
 	int			call_transport;
-	/* Reference to ITT that Task Mgmt should be preformed */
+	/* Reference to ITT that Task Mgmt should be performed */
 	u32			ref_task_tag;
 	/* 64-bit encoded SAM LUN from $FABRIC_MOD TMR header */
 	u64			ref_task_lun;
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
index 7596441..ae59bc2 100644
--- a/include/trace/events/jbd2.h
+++ b/include/trace/events/jbd2.h
@@ -81,6 +81,13 @@ DEFINE_EVENT(jbd2_commit, jbd2_commit_logging,
 	TP_ARGS(journal, commit_transaction)
 );
 
+DEFINE_EVENT(jbd2_commit, jbd2_drop_transaction,
+
+	TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
+
+	TP_ARGS(journal, commit_transaction)
+);
+
 TRACE_EVENT(jbd2_end_commit,
 	TP_PROTO(journal_t *journal, transaction_t *commit_transaction),
 
@@ -229,6 +236,27 @@ TRACE_EVENT(jbd2_cleanup_journal_tail,
 		  __entry->block_nr, __entry->freed)
 );
 
+TRACE_EVENT(jbd2_update_superblock_end,
+
+	TP_PROTO(journal_t *journal, int wait),
+
+	TP_ARGS(journal, wait),
+
+	TP_STRUCT__entry(
+		__field(	dev_t,  dev			)
+		__field(	int,    wait			)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= journal->j_fs_dev->bd_dev;
+		__entry->wait		= wait;
+	),
+
+	TP_printk("dev %d,%d wait %d",
+		  MAJOR(__entry->dev), MINOR(__entry->dev),
+		  __entry->wait)
+);
+
 #endif /* _TRACE_JBD2_H */
 
 /* This part must be outside protection */
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index 1bcc2a8..5800eb8 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -65,7 +65,6 @@ TRACE_EVENT(machine_suspend,
 	TP_printk("state=%lu", (unsigned long)__entry->state)
 );
 
-/* This code will be removed after deprecation time exceeded (2.6.41) */
 #ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED
 
 /*
diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
index d2d88be..3370997 100644
--- a/include/trace/events/rcu.h
+++ b/include/trace/events/rcu.h
@@ -313,19 +313,22 @@ TRACE_EVENT(rcu_prep_idle,
 /*
  * Tracepoint for the registration of a single RCU callback function.
  * The first argument is the type of RCU, the second argument is
- * a pointer to the RCU callback itself, and the third element is the
- * new RCU callback queue length for the current CPU.
+ * a pointer to the RCU callback itself, the third element is the
+ * number of lazy callbacks queued, and the fourth element is the
+ * total number of callbacks queued.
  */
 TRACE_EVENT(rcu_callback,
 
-	TP_PROTO(char *rcuname, struct rcu_head *rhp, long qlen),
+	TP_PROTO(char *rcuname, struct rcu_head *rhp, long qlen_lazy,
+		 long qlen),
 
-	TP_ARGS(rcuname, rhp, qlen),
+	TP_ARGS(rcuname, rhp, qlen_lazy, qlen),
 
 	TP_STRUCT__entry(
 		__field(char *, rcuname)
 		__field(void *, rhp)
 		__field(void *, func)
+		__field(long, qlen_lazy)
 		__field(long, qlen)
 	),
 
@@ -333,11 +336,13 @@ TRACE_EVENT(rcu_callback,
 		__entry->rcuname = rcuname;
 		__entry->rhp = rhp;
 		__entry->func = rhp->func;
+		__entry->qlen_lazy = qlen_lazy;
 		__entry->qlen = qlen;
 	),
 
-	TP_printk("%s rhp=%p func=%pf %ld",
-		  __entry->rcuname, __entry->rhp, __entry->func, __entry->qlen)
+	TP_printk("%s rhp=%p func=%pf %ld/%ld",
+		  __entry->rcuname, __entry->rhp, __entry->func,
+		  __entry->qlen_lazy, __entry->qlen)
 );
 
 /*
@@ -345,20 +350,21 @@ TRACE_EVENT(rcu_callback,
  * kfree() form.  The first argument is the RCU type, the second argument
  * is a pointer to the RCU callback, the third argument is the offset
  * of the callback within the enclosing RCU-protected data structure,
- * and the fourth argument is the new RCU callback queue length for the
- * current CPU.
+ * the fourth argument is the number of lazy callbacks queued, and the
+ * fifth argument is the total number of callbacks queued.
  */
 TRACE_EVENT(rcu_kfree_callback,
 
 	TP_PROTO(char *rcuname, struct rcu_head *rhp, unsigned long offset,
-		 long qlen),
+		 long qlen_lazy, long qlen),
 
-	TP_ARGS(rcuname, rhp, offset, qlen),
+	TP_ARGS(rcuname, rhp, offset, qlen_lazy, qlen),
 
 	TP_STRUCT__entry(
 		__field(char *, rcuname)
 		__field(void *, rhp)
 		__field(unsigned long, offset)
+		__field(long, qlen_lazy)
 		__field(long, qlen)
 	),
 
@@ -366,41 +372,45 @@ TRACE_EVENT(rcu_kfree_callback,
 		__entry->rcuname = rcuname;
 		__entry->rhp = rhp;
 		__entry->offset = offset;
+		__entry->qlen_lazy = qlen_lazy;
 		__entry->qlen = qlen;
 	),
 
-	TP_printk("%s rhp=%p func=%ld %ld",
+	TP_printk("%s rhp=%p func=%ld %ld/%ld",
 		  __entry->rcuname, __entry->rhp, __entry->offset,
-		  __entry->qlen)
+		  __entry->qlen_lazy, __entry->qlen)
 );
 
 /*
  * Tracepoint for marking the beginning rcu_do_batch, performed to start
  * RCU callback invocation.  The first argument is the RCU flavor,
- * the second is the total number of callbacks (including those that
- * are not yet ready to be invoked), and the third argument is the
- * current RCU-callback batch limit.
+ * the second is the number of lazy callbacks queued, the third is
+ * the total number of callbacks queued, and the fourth argument is
+ * the current RCU-callback batch limit.
  */
 TRACE_EVENT(rcu_batch_start,
 
-	TP_PROTO(char *rcuname, long qlen, int blimit),
+	TP_PROTO(char *rcuname, long qlen_lazy, long qlen, int blimit),
 
-	TP_ARGS(rcuname, qlen, blimit),
+	TP_ARGS(rcuname, qlen_lazy, qlen, blimit),
 
 	TP_STRUCT__entry(
 		__field(char *, rcuname)
+		__field(long, qlen_lazy)
 		__field(long, qlen)
 		__field(int, blimit)
 	),
 
 	TP_fast_assign(
 		__entry->rcuname = rcuname;
+		__entry->qlen_lazy = qlen_lazy;
 		__entry->qlen = qlen;
 		__entry->blimit = blimit;
 	),
 
-	TP_printk("%s CBs=%ld bl=%d",
-		  __entry->rcuname, __entry->qlen, __entry->blimit)
+	TP_printk("%s CBs=%ld/%ld bl=%d",
+		  __entry->rcuname, __entry->qlen_lazy, __entry->qlen,
+		  __entry->blimit)
 );
 
 /*
@@ -531,16 +541,21 @@ TRACE_EVENT(rcu_torture_read,
 #else /* #ifdef CONFIG_RCU_TRACE */
 
 #define trace_rcu_grace_period(rcuname, gpnum, gpevent) do { } while (0)
-#define trace_rcu_grace_period_init(rcuname, gpnum, level, grplo, grphi, qsmask) do { } while (0)
+#define trace_rcu_grace_period_init(rcuname, gpnum, level, grplo, grphi, \
+				    qsmask) do { } while (0)
 #define trace_rcu_preempt_task(rcuname, pid, gpnum) do { } while (0)
 #define trace_rcu_unlock_preempted_task(rcuname, gpnum, pid) do { } while (0)
-#define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, grplo, grphi, gp_tasks) do { } while (0)
+#define trace_rcu_quiescent_state_report(rcuname, gpnum, mask, qsmask, level, \
+					 grplo, grphi, gp_tasks) do { } \
+	while (0)
 #define trace_rcu_fqs(rcuname, gpnum, cpu, qsevent) do { } while (0)
 #define trace_rcu_dyntick(polarity, oldnesting, newnesting) do { } while (0)
 #define trace_rcu_prep_idle(reason) do { } while (0)
-#define trace_rcu_callback(rcuname, rhp, qlen) do { } while (0)
-#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen) do { } while (0)
-#define trace_rcu_batch_start(rcuname, qlen, blimit) do { } while (0)
+#define trace_rcu_callback(rcuname, rhp, qlen_lazy, qlen) do { } while (0)
+#define trace_rcu_kfree_callback(rcuname, rhp, offset, qlen_lazy, qlen) \
+	do { } while (0)
+#define trace_rcu_batch_start(rcuname, qlen_lazy, qlen, blimit) \
+	do { } while (0)
 #define trace_rcu_invoke_callback(rcuname, rhp) do { } while (0)
 #define trace_rcu_invoke_kfree_callback(rcuname, rhp, offset) do { } while (0)
 #define trace_rcu_batch_end(rcuname, callbacks_invoked, cb, nr, iit, risk) \
diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h
index 17df434..39a8a43 100644
--- a/include/trace/events/signal.h
+++ b/include/trace/events/signal.h
@@ -23,11 +23,23 @@
 		}						\
 	} while (0)
 
+#ifndef TRACE_HEADER_MULTI_READ
+enum {
+	TRACE_SIGNAL_DELIVERED,
+	TRACE_SIGNAL_IGNORED,
+	TRACE_SIGNAL_ALREADY_PENDING,
+	TRACE_SIGNAL_OVERFLOW_FAIL,
+	TRACE_SIGNAL_LOSE_INFO,
+};
+#endif
+
 /**
  * signal_generate - called when a signal is generated
  * @sig: signal number
  * @info: pointer to struct siginfo
  * @task: pointer to struct task_struct
+ * @group: shared or private
+ * @result: TRACE_SIGNAL_*
  *
  * Current process sends a 'sig' signal to 'task' process with
  * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV,
@@ -37,9 +49,10 @@
  */
 TRACE_EVENT(signal_generate,
 
-	TP_PROTO(int sig, struct siginfo *info, struct task_struct *task),
+	TP_PROTO(int sig, struct siginfo *info, struct task_struct *task,
+			int group, int result),
 
-	TP_ARGS(sig, info, task),
+	TP_ARGS(sig, info, task, group, result),
 
 	TP_STRUCT__entry(
 		__field(	int,	sig			)
@@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate,
 		__field(	int,	code			)
 		__array(	char,	comm,	TASK_COMM_LEN	)
 		__field(	pid_t,	pid			)
+		__field(	int,	group			)
+		__field(	int,	result			)
 	),
 
 	TP_fast_assign(
@@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate,
 		TP_STORE_SIGINFO(__entry, info);
 		memcpy(__entry->comm, task->comm, TASK_COMM_LEN);
 		__entry->pid	= task->pid;
+		__entry->group	= group;
+		__entry->result	= result;
 	),
 
-	TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d",
+	TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d",
 		  __entry->sig, __entry->errno, __entry->code,
-		  __entry->comm, __entry->pid)
+		  __entry->comm, __entry->pid, __entry->group,
+		  __entry->result)
 );
 
 /**
@@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver,
 		  __entry->sa_handler, __entry->sa_flags)
 );
 
-DECLARE_EVENT_CLASS(signal_queue_overflow,
-
-	TP_PROTO(int sig, int group, struct siginfo *info),
-
-	TP_ARGS(sig, group, info),
-
-	TP_STRUCT__entry(
-		__field(	int,	sig	)
-		__field(	int,	group	)
-		__field(	int,	errno	)
-		__field(	int,	code	)
-	),
-
-	TP_fast_assign(
-		__entry->sig	= sig;
-		__entry->group	= group;
-		TP_STORE_SIGINFO(__entry, info);
-	),
-
-	TP_printk("sig=%d group=%d errno=%d code=%d",
-		  __entry->sig, __entry->group, __entry->errno, __entry->code)
-);
-
-/**
- * signal_overflow_fail - called when signal queue is overflow
- * @sig: signal number
- * @group: signal to process group or not (bool)
- * @info: pointer to struct siginfo
- *
- * Kernel fails to generate 'sig' signal with 'info' siginfo, because
- * siginfo queue is overflow, and the signal is dropped.
- * 'group' is not 0 if the signal will be sent to a process group.
- * 'sig' is always one of RT signals.
- */
-DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail,
-
-	TP_PROTO(int sig, int group, struct siginfo *info),
-
-	TP_ARGS(sig, group, info)
-);
-
-/**
- * signal_lose_info - called when siginfo is lost
- * @sig: signal number
- * @group: signal to process group or not (bool)
- * @info: pointer to struct siginfo
- *
- * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo
- * queue is overflow.
- * 'group' is not 0 if the signal will be sent to a process group.
- * 'sig' is always one of non-RT signals.
- */
-DEFINE_EVENT(signal_queue_overflow, signal_lose_info,
-
-	TP_PROTO(int sig, int group, struct siginfo *info),
-
-	TP_ARGS(sig, group, info)
-);
-
 #endif /* _TRACE_SIGNAL_H */
 
 /* This part must be outside protection */
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
new file mode 100644
index 0000000..43be87d
--- /dev/null
+++ b/include/trace/events/sunrpc.h
@@ -0,0 +1,177 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sunrpc
+
+#if !defined(_TRACE_SUNRPC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SUNRPC_H
+
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(rpc_task_status,
+
+	TP_PROTO(struct rpc_task *task),
+
+	TP_ARGS(task),
+
+	TP_STRUCT__entry(
+		__field(const struct rpc_task *, task)
+		__field(const struct rpc_clnt *, clnt)
+		__field(int, status)
+	),
+
+	TP_fast_assign(
+		__entry->task = task;
+		__entry->clnt = task->tk_client;
+		__entry->status = task->tk_status;
+	),
+
+	TP_printk("task:%p@%p, status %d",__entry->task, __entry->clnt, __entry->status)
+);
+
+DEFINE_EVENT(rpc_task_status, rpc_call_status,
+	TP_PROTO(struct rpc_task *task),
+
+	TP_ARGS(task)
+);
+
+DEFINE_EVENT(rpc_task_status, rpc_bind_status,
+	TP_PROTO(struct rpc_task *task),
+
+	TP_ARGS(task)
+);
+
+TRACE_EVENT(rpc_connect_status,
+	TP_PROTO(struct rpc_task *task, int status),
+
+	TP_ARGS(task, status),
+
+	TP_STRUCT__entry(
+		__field(const struct rpc_task *, task)
+		__field(const struct rpc_clnt *, clnt)
+		__field(int, status)
+	),
+
+	TP_fast_assign(
+		__entry->task = task;
+		__entry->clnt = task->tk_client;
+		__entry->status = status;
+	),
+
+	TP_printk("task:%p@%p, status %d",__entry->task, __entry->clnt, __entry->status)
+);
+
+DECLARE_EVENT_CLASS(rpc_task_running,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
+
+	TP_ARGS(clnt, task, action),
+
+	TP_STRUCT__entry(
+		__field(const struct rpc_clnt *, clnt)
+		__field(const struct rpc_task *, task)
+		__field(const void *, action)
+		__field(unsigned long, runstate)
+		__field(int, status)
+		__field(unsigned short, flags)
+		),
+
+	TP_fast_assign(
+		__entry->clnt = clnt;
+		__entry->task = task;
+		__entry->action = action;
+		__entry->runstate = task->tk_runstate;
+		__entry->status = task->tk_status;
+		__entry->flags = task->tk_flags;
+		),
+
+	TP_printk("task:%p@%p flags=%4.4x state=%4.4lx status=%d action=%pf",
+		__entry->task,
+		__entry->clnt,
+		__entry->flags,
+		__entry->runstate,
+		__entry->status,
+		__entry->action
+		)
+);
+
+DEFINE_EVENT(rpc_task_running, rpc_task_begin,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
+
+	TP_ARGS(clnt, task, action)
+
+);
+
+DEFINE_EVENT(rpc_task_running, rpc_task_run_action,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
+
+	TP_ARGS(clnt, task, action)
+
+);
+
+DEFINE_EVENT(rpc_task_running, rpc_task_complete,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const void *action),
+
+	TP_ARGS(clnt, task, action)
+
+);
+
+DECLARE_EVENT_CLASS(rpc_task_queued,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q),
+
+	TP_ARGS(clnt, task, q),
+
+	TP_STRUCT__entry(
+		__field(const struct rpc_clnt *, clnt)
+		__field(const struct rpc_task *, task)
+		__field(unsigned long, timeout)
+		__field(unsigned long, runstate)
+		__field(int, status)
+		__field(unsigned short, flags)
+		__string(q_name, rpc_qname(q))
+		),
+
+	TP_fast_assign(
+		__entry->clnt = clnt;
+		__entry->task = task;
+		__entry->timeout = task->tk_timeout;
+		__entry->runstate = task->tk_runstate;
+		__entry->status = task->tk_status;
+		__entry->flags = task->tk_flags;
+		__assign_str(q_name, rpc_qname(q));
+		),
+
+	TP_printk("task:%p@%p flags=%4.4x state=%4.4lx status=%d timeout=%lu queue=%s",
+		__entry->task,
+		__entry->clnt,
+		__entry->flags,
+		__entry->runstate,
+		__entry->status,
+		__entry->timeout,
+		__get_str(q_name)
+		)
+);
+
+DEFINE_EVENT(rpc_task_queued, rpc_task_sleep,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q),
+
+	TP_ARGS(clnt, task, q)
+
+);
+
+DEFINE_EVENT(rpc_task_queued, rpc_task_wakeup,
+
+	TP_PROTO(const struct rpc_clnt *clnt, const struct rpc_task *task, const struct rpc_wait_queue *q),
+
+	TP_ARGS(clnt, task, q)
+
+);
+
+#endif /* _TRACE_SUNRPC_H */
+
+#include <trace/define_trace.h>
diff --git a/include/video/exynos_dp.h b/include/video/exynos_dp.h
new file mode 100644
index 0000000..8847a9d
--- /dev/null
+++ b/include/video/exynos_dp.h
@@ -0,0 +1,131 @@
+/*
+ * Samsung SoC DP device support
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ * Author: Jingoo Han <jg1.han@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _EXYNOS_DP_H
+#define _EXYNOS_DP_H
+
+#define DP_TIMEOUT_LOOP_COUNT 100
+#define MAX_CR_LOOP 5
+#define MAX_EQ_LOOP 4
+
+enum link_rate_type {
+	LINK_RATE_1_62GBPS = 0x06,
+	LINK_RATE_2_70GBPS = 0x0a
+};
+
+enum link_lane_count_type {
+	LANE_COUNT1 = 1,
+	LANE_COUNT2 = 2,
+	LANE_COUNT4 = 4
+};
+
+enum link_training_state {
+	START,
+	CLOCK_RECOVERY,
+	EQUALIZER_TRAINING,
+	FINISHED,
+	FAILED
+};
+
+enum voltage_swing_level {
+	VOLTAGE_LEVEL_0,
+	VOLTAGE_LEVEL_1,
+	VOLTAGE_LEVEL_2,
+	VOLTAGE_LEVEL_3,
+};
+
+enum pre_emphasis_level {
+	PRE_EMPHASIS_LEVEL_0,
+	PRE_EMPHASIS_LEVEL_1,
+	PRE_EMPHASIS_LEVEL_2,
+	PRE_EMPHASIS_LEVEL_3,
+};
+
+enum pattern_set {
+	PRBS7,
+	D10_2,
+	TRAINING_PTN1,
+	TRAINING_PTN2,
+	DP_NONE
+};
+
+enum color_space {
+	COLOR_RGB,
+	COLOR_YCBCR422,
+	COLOR_YCBCR444
+};
+
+enum color_depth {
+	COLOR_6,
+	COLOR_8,
+	COLOR_10,
+	COLOR_12
+};
+
+enum color_coefficient {
+	COLOR_YCBCR601,
+	COLOR_YCBCR709
+};
+
+enum dynamic_range {
+	VESA,
+	CEA
+};
+
+enum pll_status {
+	PLL_UNLOCKED,
+	PLL_LOCKED
+};
+
+enum clock_recovery_m_value_type {
+	CALCULATED_M,
+	REGISTER_M
+};
+
+enum video_timing_recognition_type {
+	VIDEO_TIMING_FROM_CAPTURE,
+	VIDEO_TIMING_FROM_REGISTER
+};
+
+enum analog_power_block {
+	AUX_BLOCK,
+	CH0_BLOCK,
+	CH1_BLOCK,
+	CH2_BLOCK,
+	CH3_BLOCK,
+	ANALOG_TOTAL,
+	POWER_ALL
+};
+
+struct video_info {
+	char *name;
+
+	bool h_sync_polarity;
+	bool v_sync_polarity;
+	bool interlaced;
+
+	enum color_space color_space;
+	enum dynamic_range dynamic_range;
+	enum color_coefficient ycbcr_coeff;
+	enum color_depth color_depth;
+
+	enum link_rate_type link_rate;
+	enum link_lane_count_type lane_count;
+};
+
+struct exynos_dp_platdata {
+	struct video_info *video_info;
+
+	void (*phy_init)(void);
+	void (*phy_exit)(void);
+};
+
+#endif /* _EXYNOS_DP_H */
diff --git a/include/video/exynos_mipi_dsim.h b/include/video/exynos_mipi_dsim.h
new file mode 100644
index 0000000..772c770
--- /dev/null
+++ b/include/video/exynos_mipi_dsim.h
@@ -0,0 +1,359 @@
+/* include/video/exynos_mipi_dsim.h
+ *
+ * Platform data header for Samsung SoC MIPI-DSIM.
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef _EXYNOS_MIPI_DSIM_H
+#define _EXYNOS_MIPI_DSIM_H
+
+#include <linux/device.h>
+#include <linux/fb.h>
+
+#define PANEL_NAME_SIZE		(32)
+
+/*
+ * Enumerate display interface type.
+ *
+ * DSIM_COMMAND means cpu interface and rgb interface for DSIM_VIDEO.
+ *
+ * P.S. MIPI DSI Master has two display controller intefaces, RGB Interface
+ *	for main display and CPU Interface(same as I80 Interface) for main
+ *	and sub display.
+ */
+enum mipi_dsim_interface_type {
+	DSIM_COMMAND,
+	DSIM_VIDEO
+};
+
+enum mipi_dsim_virtual_ch_no {
+	DSIM_VIRTUAL_CH_0,
+	DSIM_VIRTUAL_CH_1,
+	DSIM_VIRTUAL_CH_2,
+	DSIM_VIRTUAL_CH_3
+};
+
+enum mipi_dsim_burst_mode_type {
+	DSIM_NON_BURST_SYNC_EVENT,
+	DSIM_BURST_SYNC_EVENT,
+	DSIM_NON_BURST_SYNC_PULSE,
+	DSIM_BURST,
+	DSIM_NON_VIDEO_MODE
+};
+
+enum mipi_dsim_no_of_data_lane {
+	DSIM_DATA_LANE_1,
+	DSIM_DATA_LANE_2,
+	DSIM_DATA_LANE_3,
+	DSIM_DATA_LANE_4
+};
+
+enum mipi_dsim_byte_clk_src {
+	DSIM_PLL_OUT_DIV8,
+	DSIM_EXT_CLK_DIV8,
+	DSIM_EXT_CLK_BYPASS
+};
+
+enum mipi_dsim_pixel_format {
+	DSIM_CMD_3BPP,
+	DSIM_CMD_8BPP,
+	DSIM_CMD_12BPP,
+	DSIM_CMD_16BPP,
+	DSIM_VID_16BPP_565,
+	DSIM_VID_18BPP_666PACKED,
+	DSIM_18BPP_666LOOSELYPACKED,
+	DSIM_24BPP_888
+};
+
+/*
+ * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
+ *
+ * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
+ * @eot_disable: enable or disable EoT packet in HS mode.
+ * @auto_vertical_cnt: specifies auto vertical count mode.
+ *	in Video mode, the vertical line transition uses line counter
+ *	configured by VSA, VBP, and Vertical resolution.
+ *	If this bit is set to '1', the line counter does not use VSA and VBP
+ *	registers.(in command mode, this variable is ignored)
+ * @hse: set horizontal sync event mode.
+ *	In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
+ *	start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
+ *	this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
+ *	(in mommand mode, this variable is ignored)
+ * @hfp: specifies HFP disable mode.
+ *	if this variable is set, DSI master ignores HFP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hbp: specifies HBP disable mode.
+ *	if this variable is set, DSI master ignores HBP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hsa: specifies HSA disable mode.
+ *	if this variable is set, DSI master ignores HSA area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @cma_allow: specifies the number of horizontal lines, where command packet
+ *	transmission is allowed after Stable VFP period.
+ * @e_interface: specifies interface to be used.(CPU or RGB interface)
+ * @e_virtual_ch: specifies virtual channel number that main or
+ *	sub diaplsy uses.
+ * @e_pixel_format: specifies pixel stream format for main or sub display.
+ * @e_burst_mode: selects Burst mode in Video mode.
+ *	in Non-burst mode, RGB data area is filled with RGB data and NULL
+ *	packets, according to input bandwidth of RGB interface.
+ *	In Burst mode, RGB data area is filled with RGB data only.
+ * @e_no_data_lane: specifies data lane count to be used by Master.
+ * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
+ *	DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
+ * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
+ *	clock(System clock cycle base)
+ *	if the timer value goes to 0x00000000, the clock stable bit of status
+ *	and interrupt register is set.
+ * @esc_clk: specifies escape clock frequency for getting the escape clock
+ *	prescaler value.
+ * @stop_holding_cnt: specifies the interval value between transmitting
+ *	read packet(or write "set_tear_on" command) and BTA request.
+ *	after transmitting read packet or write "set_tear_on" command,
+ *	BTA requests to D-PHY automatically. this counter value specifies
+ *	the interval between them.
+ * @bta_timeout: specifies the timer for BTA.
+ *	this register specifies time out from BTA request to change
+ *	the direction with respect to Tx escape clock.
+ * @rx_timeout: specifies the timer for LP Rx mode timeout.
+ *	this register specifies time out on how long RxValid deasserts,
+ *	after RxLpdt asserts with respect to Tx escape clock.
+ *	- RxValid specifies Rx data valid indicator.
+ *	- RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
+ *	- RxValid and RxLpdt specifies signal from D-PHY.
+ */
+struct mipi_dsim_config {
+	unsigned char			auto_flush;
+	unsigned char			eot_disable;
+
+	unsigned char			auto_vertical_cnt;
+	unsigned char			hse;
+	unsigned char			hfp;
+	unsigned char			hbp;
+	unsigned char			hsa;
+	unsigned char			cmd_allow;
+
+	enum mipi_dsim_interface_type	e_interface;
+	enum mipi_dsim_virtual_ch_no	e_virtual_ch;
+	enum mipi_dsim_pixel_format	e_pixel_format;
+	enum mipi_dsim_burst_mode_type	e_burst_mode;
+	enum mipi_dsim_no_of_data_lane	e_no_data_lane;
+	enum mipi_dsim_byte_clk_src	e_byte_clk;
+
+	/*
+	 * ===========================================
+	 * |    P    |    M    |    S    |    MHz    |
+	 * -------------------------------------------
+	 * |    3    |   100   |    3    |    100    |
+	 * |    3    |   100   |    2    |    200    |
+	 * |    3    |    63   |    1    |    252    |
+	 * |    4    |   100   |    1    |    300    |
+	 * |    4    |   110   |    1    |    330    |
+	 * |   12    |   350   |    1    |    350    |
+	 * |    3    |   100   |    1    |    400    |
+	 * |    4    |   150   |    1    |    450    |
+	 * |    6    |   118   |    1    |    472    |
+	 * |	3    |   120   |    1    |    480    |
+	 * |   12    |   250   |    0    |    500    |
+	 * |    4    |   100   |    0    |    600    |
+	 * |    3    |    81   |    0    |    648    |
+	 * |    3    |    88   |    0    |    704    |
+	 * |    3    |    90   |    0    |    720    |
+	 * |    3    |   100   |    0    |    800    |
+	 * |   12    |   425   |    0    |    850    |
+	 * |    4    |   150   |    0    |    900    |
+	 * |   12    |   475   |    0    |    950    |
+	 * |    6    |   250   |    0    |   1000    |
+	 * -------------------------------------------
+	 */
+
+	/*
+	 * pms could be calculated as the following.
+	 * M * 24 / P * 2 ^ S = MHz
+	 */
+	unsigned char			p;
+	unsigned short			m;
+	unsigned char			s;
+
+	unsigned int			pll_stable_time;
+	unsigned long			esc_clk;
+
+	unsigned short			stop_holding_cnt;
+	unsigned char			bta_timeout;
+	unsigned short			rx_timeout;
+};
+
+/*
+ * struct mipi_dsim_device - global interface for mipi-dsi driver.
+ *
+ * @dev: driver model representation of the device.
+ * @id: unique device id.
+ * @clock: pointer to MIPI-DSI clock of clock framework.
+ * @irq: interrupt number to MIPI-DSI controller.
+ * @reg_base: base address to memory mapped SRF of MIPI-DSI controller.
+ *	(virtual address)
+ * @lock: the mutex protecting this data structure.
+ * @dsim_info: infomation for configuring mipi-dsi controller.
+ * @master_ops: callbacks to mipi-dsi operations.
+ * @dsim_lcd_dev: pointer to activated ddi device.
+ *	(it would be registered by mipi-dsi driver.)
+ * @dsim_lcd_drv: pointer to activated_ddi driver.
+ *	(it would be registered by mipi-dsi driver.)
+ * @lcd_info: pointer to mipi_lcd_info structure.
+ * @state: specifies status of MIPI-DSI controller.
+ *	the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
+ * @data_lane: specifiec enabled data lane number.
+ *	this variable would be set by driver according to e_no_data_lane
+ *	automatically.
+ * @e_clk_src: select byte clock source.
+ * @pd: pointer to MIPI-DSI driver platform data.
+ */
+struct mipi_dsim_device {
+	struct device			*dev;
+	int				id;
+	struct resource			*res;
+	struct clk			*clock;
+	unsigned int			irq;
+	void __iomem			*reg_base;
+	struct mutex			lock;
+
+	struct mipi_dsim_config		*dsim_config;
+	struct mipi_dsim_master_ops	*master_ops;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+
+	unsigned int			state;
+	unsigned int			data_lane;
+	unsigned int			e_clk_src;
+	bool				suspended;
+
+	struct mipi_dsim_platform_data	*pd;
+};
+
+/*
+ * struct mipi_dsim_platform_data - interface to platform data
+ *	for mipi-dsi driver.
+ *
+ * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver.
+ *	lcd panel driver searched would be actived.
+ * @dsim_config: pointer of structure for configuring mipi-dsi controller.
+ * @enabled: indicate whether mipi controller got enabled or not.
+ * @lcd_panel_info: pointer for lcd panel specific structure.
+ *	this structure specifies width, height, timing and polarity and so on.
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct mipi_dsim_platform_data {
+	char				lcd_panel_name[PANEL_NAME_SIZE];
+
+	struct mipi_dsim_config		*dsim_config;
+	unsigned int			enabled;
+	void				*lcd_panel_info;
+
+	int (*phy_enable)(struct platform_device *pdev, bool on);
+};
+
+/*
+ * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations.
+ *
+ * @cmd_write: transfer command to lcd panel at LP mode.
+ * @cmd_read: read command from rx register.
+ * @get_dsim_frame_done: get the status that all screen data have been
+ *	transferred to mipi-dsi.
+ * @clear_dsim_frame_done: clear frame done status.
+ * @get_fb_frame_done: get frame done status of display controller.
+ * @trigger: trigger display controller.
+ *	- this one would be used only in case of CPU mode.
+ *  @set_early_blank_mode: set framebuffer blank mode.
+ *	- this callback should be called prior to fb_blank() by a client driver
+ *	only if needing.
+ *  @set_blank_mode: set framebuffer blank mode.
+ *	- this callback should be called after fb_blank() by a client driver
+ *	only if needing.
+ */
+
+struct mipi_dsim_master_ops {
+	int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		const unsigned char *data0, unsigned int data1);
+	int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		unsigned int data0, unsigned int req_size, u8 *rx_buf);
+	int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim);
+	int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim);
+
+	int (*get_fb_frame_done)(struct fb_info *info);
+	void (*trigger)(struct fb_info *info);
+	int (*set_early_blank_mode)(struct mipi_dsim_device *dsim, int power);
+	int (*set_blank_mode)(struct mipi_dsim_device *dsim, int power);
+};
+
+/*
+ * device structure for mipi-dsi based lcd panel.
+ *
+ * @name: name of the device to use with this device, or an
+ *	alias for that name.
+ * @dev: driver model representation of the device.
+ * @id: id of device to be registered.
+ * @bus_id: bus id for identifing connected bus
+ *	and this bus id should be same as id of mipi_dsim_device.
+ * @irq: irq number for signaling when framebuffer transfer of
+ *	lcd panel module is completed.
+ *	this irq would be used only for MIPI-DSI based CPU mode lcd panel.
+ * @master: pointer to mipi-dsi master device object.
+ * @platform_data: lcd panel specific platform data.
+ */
+struct mipi_dsim_lcd_device {
+	char			*name;
+	struct device		dev;
+	int			id;
+	int			bus_id;
+	int			irq;
+
+	struct mipi_dsim_device *master;
+	void			*platform_data;
+};
+
+/*
+ * driver structure for mipi-dsi based lcd panel.
+ *
+ * this structure should be registered by lcd panel driver.
+ * mipi-dsi driver seeks lcd panel registered through name field
+ * and calls these callback functions in appropriate time.
+ *
+ * @name: name of the driver to use with this device, or an
+ *	alias for that name.
+ * @id: id of driver to be registered.
+ *	this id would be used for finding device object registered.
+ */
+struct mipi_dsim_lcd_driver {
+	char			*name;
+	int			id;
+
+	void	(*power_on)(struct mipi_dsim_lcd_device *dsim_dev, int enable);
+	void	(*set_sequence)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*probe)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*remove)(struct mipi_dsim_lcd_device *dsim_dev);
+	void	(*shutdown)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*suspend)(struct mipi_dsim_lcd_device *dsim_dev);
+	int	(*resume)(struct mipi_dsim_lcd_device *dsim_dev);
+};
+
+/*
+ * register mipi_dsim_lcd_device to mipi-dsi master.
+ */
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
+						*lcd_dev);
+/**
+ * register mipi_dsim_lcd_driver object defined by lcd panel driver
+ * to mipi-dsi driver.
+ */
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
+						*lcd_drv);
+#endif /* _EXYNOS_MIPI_DSIM_H */
diff --git a/include/video/sa1100fb.h b/include/video/sa1100fb.h
new file mode 100644
index 0000000..4ab4096
--- /dev/null
+++ b/include/video/sa1100fb.h
@@ -0,0 +1,63 @@
+/*
+ * StrongARM 1100 LCD Controller Frame Buffer Device
+ *
+ * Copyright (C) 1999 Eric A. Thomas
+ *  Based on acornfb.c Copyright (C) Russell King.
+ *  
+ * 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.
+ */
+#ifndef _VIDEO_SA1100FB_H
+#define _VIDEO_SA1100FB_H
+
+#include <linux/fb.h>
+#include <linux/types.h>
+
+#define RGB_4	0
+#define RGB_8	1
+#define RGB_16	2
+#define NR_RGB	3
+
+/* These are the bitfields for each display depth that we support. */
+struct sa1100fb_rgb {
+	struct fb_bitfield	red;
+	struct fb_bitfield	green;
+	struct fb_bitfield	blue;
+	struct fb_bitfield	transp;
+};
+
+/* This structure describes the machine which we are running on. */
+struct sa1100fb_mach_info {
+	u_long		pixclock;
+
+	u_short		xres;
+	u_short		yres;
+
+	u_char		bpp;
+	u_char		hsync_len;
+	u_char		left_margin;
+	u_char		right_margin;
+
+	u_char		vsync_len;
+	u_char		upper_margin;
+	u_char		lower_margin;
+	u_char		sync;
+
+	u_int		cmap_greyscale:1,
+			cmap_inverse:1,
+			cmap_static:1,
+			unused:29;
+
+	u_int		lccr0;
+	u_int		lccr3;
+
+	/* Overrides for the default RGB maps */
+	const struct sa1100fb_rgb *rgb[NR_RGB];
+
+	void (*backlight_power)(int);
+	void (*lcd_power)(int);
+	void (*set_visual)(u32);
+};
+
+#endif
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index c1080d9..0c28989 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -145,6 +145,13 @@ struct physdev_manage_pci {
 	uint8_t devfn;
 };
 
+#define PHYSDEVOP_restore_msi            19
+struct physdev_restore_msi {
+	/* IN */
+	uint8_t bus;
+	uint8_t devfn;
+};
+
 #define PHYSDEVOP_manage_pci_add_ext	20
 struct physdev_manage_pci_ext {
 	/* IN */
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 2ea2fdc..4f4d449 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -7,11 +7,13 @@ extern void xen_swiotlb_init(int verbose);
 
 extern void
 *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-			    dma_addr_t *dma_handle, gfp_t flags);
+			    dma_addr_t *dma_handle, gfp_t flags,
+			    struct dma_attrs *attrs);
 
 extern void
 xen_swiotlb_free_coherent(struct device *hwdev, size_t size,
-			  void *vaddr, dma_addr_t dma_handle);
+			  void *vaddr, dma_addr_t dma_handle,
+			  struct dma_attrs *attrs);
 
 extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
 				       unsigned long offset, size_t size,
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index e8c599b..0a7515c 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -139,9 +139,9 @@ int xenbus_transaction_start(struct xenbus_transaction *t);
 int xenbus_transaction_end(struct xenbus_transaction t, int abort);
 
 /* Single read and scanf: returns -errno or num scanned if > 0. */
+__scanf(4, 5)
 int xenbus_scanf(struct xenbus_transaction t,
-		 const char *dir, const char *node, const char *fmt, ...)
-	__attribute__((format(scanf, 4, 5)));
+		 const char *dir, const char *node, const char *fmt, ...);
 
 /* Single printf and write: returns -errno or 0. */
 __printf(4, 5)
diff --git a/init/Kconfig b/init/Kconfig
index 3f42cd6..72f33fa 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -438,15 +438,6 @@ config PREEMPT_RCU
 	  This option enables preemptible-RCU code that is common between
 	  the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations.
 
-config RCU_TRACE
-	bool "Enable tracing for RCU"
-	help
-	  This option provides tracing in RCU which presents stats
-	  in debugfs for debugging RCU implementation.
-
-	  Say Y here if you want to enable RCU tracing
-	  Say N if you are unsure.
-
 config RCU_FANOUT
 	int "Tree-based hierarchical RCU fanout value"
 	range 2 64 if 64BIT
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 2974c8b..06225d2 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -352,6 +352,9 @@ void __init mount_block_root(char *name, int flags)
 	const char *b = name;
 #endif
 
+	if (sys_access((const char __user *) "/root", 0) != 0)
+		sys_mkdir((const char __user *) "/root", 0700);
+
 	get_fs_names(fs_names);
 retry:
 	for (p = fs_names; *p; p += strlen(p)+1) {
diff --git a/init/main.c b/init/main.c
index ff49a6d..b229ee6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -403,7 +403,7 @@ static int __init do_early_param(char *param, char *val)
 
 void __init parse_early_options(char *cmdline)
 {
-	parse_args("early options", cmdline, NULL, 0, do_early_param);
+	parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param);
 }
 
 /* Arch code calls this early on, or if not, just before other parsing. */
@@ -506,7 +506,7 @@ asmlinkage void __init start_kernel(void)
 	parse_early_param();
 	parse_args("Booting kernel", static_command_line, __start___param,
 		   __stop___param - __start___param,
-		   &unknown_bootoption);
+		   0, 0, &unknown_bootoption);
 
 	jump_label_init();
 
@@ -702,16 +702,69 @@ int __init_or_module do_one_initcall(initcall_t fn)
 }
 
 
-extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
+extern initcall_t __initcall_start[];
+extern initcall_t __initcall0_start[];
+extern initcall_t __initcall1_start[];
+extern initcall_t __initcall2_start[];
+extern initcall_t __initcall3_start[];
+extern initcall_t __initcall4_start[];
+extern initcall_t __initcall5_start[];
+extern initcall_t __initcall6_start[];
+extern initcall_t __initcall7_start[];
+extern initcall_t __initcall_end[];
+
+static initcall_t *initcall_levels[] __initdata = {
+	__initcall0_start,
+	__initcall1_start,
+	__initcall2_start,
+	__initcall3_start,
+	__initcall4_start,
+	__initcall5_start,
+	__initcall6_start,
+	__initcall7_start,
+	__initcall_end,
+};
+
+static char *initcall_level_names[] __initdata = {
+	"early parameters",
+	"core parameters",
+	"postcore parameters",
+	"arch parameters",
+	"subsys parameters",
+	"fs parameters",
+	"device parameters",
+	"late parameters",
+};
+
+static int __init ignore_unknown_bootoption(char *param, char *val)
+{
+	return 0;
+}
 
-static void __init do_initcalls(void)
+static void __init do_initcall_level(int level)
 {
+	extern const struct kernel_param __start___param[], __stop___param[];
 	initcall_t *fn;
 
-	for (fn = __early_initcall_end; fn < __initcall_end; fn++)
+	strcpy(static_command_line, saved_command_line);
+	parse_args(initcall_level_names[level],
+		   static_command_line, __start___param,
+		   __stop___param - __start___param,
+		   level, level,
+		   ignore_unknown_bootoption);
+
+	for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
 		do_one_initcall(*fn);
 }
 
+static void __init do_initcalls(void)
+{
+	int level;
+
+	for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
+		do_initcall_level(level);
+}
+
 /*
  * Ok, the machine is now initialized. None of the devices
  * have been touched yet, but the CPU subsystem is up and
@@ -735,7 +788,7 @@ static void __init do_pre_smp_initcalls(void)
 {
 	initcall_t *fn;
 
-	for (fn = __initcall_start; fn < __early_initcall_end; fn++)
+	for (fn = __initcall_start; fn < __initcall0_start; fn++)
 		do_one_initcall(*fn);
 }
 
diff --git a/ipc/compat.c b/ipc/compat.c
index 845a287..a6df704 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -27,6 +27,7 @@
 #include <linux/msg.h>
 #include <linux/shm.h>
 #include <linux/syscalls.h>
+#include <linux/ptrace.h>
 
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
@@ -117,6 +118,7 @@ extern int sem_ctls[];
 
 static inline int compat_ipc_parse_version(int *cmd)
 {
+#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
 	int version = *cmd & IPC_64;
 
 	/* this is tricky: architectures that have support for the old
@@ -128,6 +130,10 @@ static inline int compat_ipc_parse_version(int *cmd)
 	*cmd &= ~IPC_64;
 #endif
 	return version;
+#else
+	/* With the asm-generic APIs, we always use the 64-bit versions. */
+	return IPC_64;
+#endif
 }
 
 static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64,
@@ -232,10 +238,9 @@ static inline int put_compat_semid_ds(struct semid64_ds *s,
 	return err;
 }
 
-long compat_sys_semctl(int first, int second, int third, void __user *uptr)
+static long do_compat_semctl(int first, int second, int third, u32 pad)
 {
 	union semun fourth;
-	u32 pad;
 	int err, err2;
 	struct semid64_ds s64;
 	struct semid64_ds __user *up64;
@@ -243,10 +248,6 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
 
 	memset(&s64, 0, sizeof(s64));
 
-	if (!uptr)
-		return -EINVAL;
-	if (get_user(pad, (u32 __user *) uptr))
-		return -EFAULT;
 	if ((third & (~IPC_64)) == SETVAL)
 		fourth.val = (int) pad;
 	else
@@ -305,6 +306,18 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
 	return err;
 }
 
+#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
+long compat_sys_semctl(int first, int second, int third, void __user *uptr)
+{
+	u32 pad;
+
+	if (!uptr)
+		return -EINVAL;
+	if (get_user(pad, (u32 __user *) uptr))
+		return -EFAULT;
+	return do_compat_semctl(first, second, third, pad);
+}
+
 long compat_sys_msgsnd(int first, int second, int third, void __user *uptr)
 {
 	struct compat_msgbuf __user *up = uptr;
@@ -353,6 +366,37 @@ long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
 out:
 	return err;
 }
+#else
+long compat_sys_semctl(int semid, int semnum, int cmd, int arg)
+{
+	return do_compat_semctl(semid, semnum, cmd, arg);
+}
+
+long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
+		       size_t msgsz, int msgflg)
+{
+	compat_long_t mtype;
+
+	if (get_user(mtype, &msgp->mtype))
+		return -EFAULT;
+	return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
+}
+
+long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
+		       size_t msgsz, long msgtyp, int msgflg)
+{
+	long err, mtype;
+
+	err =  do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
+	if (err < 0)
+		goto out;
+
+	if (put_user(mtype, &msgp->mtype))
+		err = -EFAULT;
+ out:
+	return err;
+}
+#endif
 
 static inline int get_compat_msqid64(struct msqid64_ds *m64,
 				     struct compat_msqid64_ds __user *up64)
@@ -470,6 +514,7 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
 	return err;
 }
 
+#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
 long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
 			void __user *uptr)
 {
@@ -485,6 +530,19 @@ long compat_sys_shmat(int first, int second, compat_uptr_t third, int version,
 	uaddr = compat_ptr(third);
 	return put_user(raddr, uaddr);
 }
+#else
+long compat_sys_shmat(int shmid, compat_uptr_t shmaddr, int shmflg)
+{
+	unsigned long ret;
+	long err;
+
+	err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret);
+	if (err)
+		return err;
+	force_successful_syscall_return();
+	return (long)ret;
+}
+#endif
 
 static inline int get_compat_shmid64_ds(struct shmid64_ds *s64,
 					struct compat_shmid64_ds __user *up64)
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 86ee272..28bd64d 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -188,30 +188,20 @@ static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct ipc_namespace *ns = data;
-	int error;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = MQUEUE_MAGIC;
 	sb->s_op = &mqueue_super_ops;
 
-	inode = mqueue_get_inode(sb, ns, S_IFDIR | S_ISVTX | S_IRWXUGO,
-				NULL);
-	if (IS_ERR(inode)) {
-		error = PTR_ERR(inode);
-		goto out;
-	}
+	inode = mqueue_get_inode(sb, ns, S_IFDIR | S_ISVTX | S_IRWXUGO, NULL);
+	if (IS_ERR(inode))
+		return PTR_ERR(inode);
 
-	sb->s_root = d_alloc_root(inode);
-	if (!sb->s_root) {
-		iput(inode);
-		error = -ENOMEM;
-		goto out;
-	}
-	error = 0;
-
-out:
-	return error;
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root)
+		return -ENOMEM;
+	return 0;
 }
 
 static struct dentry *mqueue_mount(struct file_system_type *fs_type,
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index 5652101..26143d3 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -13,7 +13,9 @@
 #include <linux/security.h>
 #include <linux/slab.h>
 #include <linux/ipc.h>
+#include <linux/msg.h>
 #include <linux/ipc_namespace.h>
+#include <linux/utsname.h>
 #include <asm/uaccess.h>
 
 #include "util.h"
diff --git a/ipc/sem.c b/ipc/sem.c
index 5215a81..10386b8 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -61,8 +61,8 @@
  * - A woken up task may not even touch the semaphore array anymore, it may
  *   have been destroyed already by a semctl(RMID).
  * - The synchronizations between wake-ups due to a timeout/signal and a
- *   wake-up due to a completed semaphore operation is achieved by using an
- *   intermediate state (IN_WAKEUP).
+ *   wake-up due to a completed semaphore operation is achieved by using a
+ *   special wakeup scheme (queuewakeup_wait and support functions)
  * - UNDO values are stored in an array (one per process and per
  *   semaphore array, lazily allocated). For backwards compatibility, multiple
  *   modes for the UNDO variables are supported (per process, per thread)
@@ -90,6 +90,135 @@
 #include <asm/uaccess.h>
 #include "util.h"
 
+
+#ifdef CONFIG_PREEMPT_RT_BASE
+	#define SYSVSEM_COMPLETION 1
+#else
+	#define SYSVSEM_CUSTOM 1
+#endif
+
+#ifdef SYSVSEM_COMPLETION
+	/* Using a completion causes some overhead, but avoids a busy loop
+	 * that increases the worst case latency.
+	 */
+	struct queue_done {
+		struct completion done;
+	};
+
+	static void queuewakeup_prepare(void)
+	{
+		/* no preparation necessary */
+	}
+
+	static void queuewakeup_completed(void)
+	{
+		/* empty */
+	}
+
+	static void queuewakeup_block(struct queue_done *qd)
+	{
+		/* empty */
+	}
+
+	static void queuewakeup_handsoff(struct queue_done *qd)
+	{
+		complete_all(&qd->done);
+	}
+
+	static void queuewakeup_init(struct queue_done *qd)
+	{
+		init_completion(&qd->done);
+	}
+
+	static void queuewakeup_wait(struct queue_done *qd)
+	{
+		wait_for_completion(&qd->done);
+	}
+
+#elif defined(SYSVSEM_SPINLOCK)
+	/* Note: Spinlocks do not work because:
+	 * - lockdep complains [could be fixed]
+	 * - only 255 concurrent spin_lock() calls are permitted, then the
+	 *   preempt-counter overflows
+	 */
+#error SYSVSEM_SPINLOCK is a prove of concept, does not work.
+	struct queue_done {
+		spinlock_t done;
+	};
+
+	static void queuewakeup_prepare(void)
+	{
+		/* empty */
+	}
+
+	static void queuewakeup_completed(void)
+	{
+		/* empty */
+	}
+
+	static void queuewakeup_block(struct queue_done *qd)
+	{
+		BUG_ON(spin_is_locked(&qd->done));
+		spin_lock(&qd->done);
+	}
+
+	static void queuewakeup_handsoff(struct queue_done *qd)
+	{
+		spin_unlock(&qd->done);
+	}
+
+	static void queuewakeup_init(struct queue_done *qd)
+	{
+		spin_lock_init(&qd->done);
+	}
+
+	static void queuewakeup_wait(struct queue_done *qd)
+	{
+		spin_unlock_wait(&qd->done);
+	}
+#else
+	struct queue_done {
+		atomic_t done;
+	};
+
+	static void queuewakeup_prepare(void)
+	{
+		preempt_disable();
+	}
+
+	static void queuewakeup_completed(void)
+	{
+		preempt_enable();
+	}
+
+	static void queuewakeup_block(struct queue_done *qd)
+	{
+		BUG_ON(atomic_read(&qd->done) != 1);
+		atomic_set(&qd->done, 2);
+	}
+
+	static void queuewakeup_handsoff(struct queue_done *qd)
+	{
+		BUG_ON(atomic_read(&qd->done) != 2);
+		smp_mb();
+		atomic_set(&qd->done, 1);
+	}
+
+	static void queuewakeup_init(struct queue_done *qd)
+	{
+		atomic_set(&qd->done, 1);
+	}
+
+	static void queuewakeup_wait(struct queue_done *qd)
+	{
+		while (atomic_read(&qd->done) != 1)
+			cpu_relax();
+
+		smp_mb();
+	}
+#endif
+
+
 /* One semaphore structure for each semaphore in the system. */
 struct sem {
 	int	semval;		/* current value */
@@ -108,6 +237,7 @@ struct sem_queue {
 	struct sembuf		*sops;	 /* array of pending operations */
 	int			nsops;	 /* number of operations */
 	int			alter;	 /* does *sops alter the array? */
+	struct queue_done	done;	 /* completion synchronization */
 };
 
 /* Each task has a list of undo requests. They are executed automatically
@@ -245,23 +375,27 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
  * - queue.status is initialized to -EINTR before blocking.
  * - wakeup is performed by
  *	* unlinking the queue entry from sma->sem_pending
- *	* setting queue.status to IN_WAKEUP
- *	  This is the notification for the blocked thread that a
- *	  result value is imminent.
+ *	* setting queue.status to the actual result code
+ *	  This is the notification for the blocked thread that someone
+ *	  (usually: update_queue()) completed the semtimedop() operation.
  *	* call wake_up_process
- *	* set queue.status to the final value.
+ *	* queuewakeup_handsoff(&q->done);
  * - the previously blocked thread checks queue.status:
- *   	* if it's IN_WAKEUP, then it must wait until the value changes
- *   	* if it's not -EINTR, then the operation was completed by
- *   	  update_queue. semtimedop can return queue.status without
- *   	  performing any operation on the sem array.
- *   	* otherwise it must acquire the spinlock and check what's up.
+ *	* if it's not -EINTR, then someone completed the operation.
+ *	  First, queuewakeup_wait() must be called. Afterwards,
+ *	  semtimedop must return queue.status without performing any
+ *	  operation on the sem array.
+ *	  - otherwise it must acquire the spinlock and repeat the test
+ *	  - If it is still -EINTR, then no update_queue() completed the
+ *	    operation, thus semtimedop() can proceed normally.
  *
- * The two-stage algorithm is necessary to protect against the following
+ * queuewakeup_wait() is necessary to protect against the following
  * races:
  * - if queue.status is set after wake_up_process, then the woken up idle
  *   thread could race forward and try (and fail) to acquire sma->lock
- *   before update_queue had a chance to set queue.status
+ *   before update_queue had a chance to set queue.status.
+ *   More importantly, it would mean that wake_up_process must be done
+ *   while holding sma->lock, i.e. this would reduce the scalability.
  * - if queue.status is written before wake_up_process and if the
  *   blocked process is woken up by a signal between writing
  *   queue.status and the wake_up_process, then the woken up
@@ -271,7 +405,6 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
  *   (yes, this happened on s390 with sysv msg).
  *
  */
-#define IN_WAKEUP	1
 
 /**
  * newary - Create a new semaphore set
@@ -461,15 +594,11 @@ undo:
 static void wake_up_sem_queue_prepare(struct list_head *pt,
 				struct sem_queue *q, int error)
 {
-	if (list_empty(pt)) {
-		/*
-		 * Hold preempt off so that we don't get preempted and have the
-		 * wakee busy-wait until we're scheduled back on.
-		 */
-		preempt_disable();
-	}
-	q->status = IN_WAKEUP;
-	q->pid = error;
+	if (list_empty(pt))
+		queuewakeup_prepare();
+
+	queuewakeup_block(&q->done);
+	q->status = error;
 
 	list_add_tail(&q->simple_list, pt);
 }
@@ -480,8 +609,8 @@ static void wake_up_sem_queue_prepare(struct list_head *pt,
  *
  * Do the actual wake-up.
  * The function is called without any locks held, thus the semaphore array
- * could be destroyed already and the tasks can disappear as soon as the
- * status is set to the actual return code.
+ * could be destroyed already and the tasks can disappear as soon as
+ * queuewakeup_handsoff() is called.
  */
 static void wake_up_sem_queue_do(struct list_head *pt)
 {
@@ -491,12 +620,11 @@ static void wake_up_sem_queue_do(struct list_head *pt)
 	did_something = !list_empty(pt);
 	list_for_each_entry_safe(q, t, pt, simple_list) {
 		wake_up_process(q->sleeper);
-		/* q can disappear immediately after writing q->status. */
-		smp_wmb();
-		q->status = q->pid;
+		/* q can disappear immediately after completing q->done */
+		queuewakeup_handsoff(&q->done);
 	}
 	if (did_something)
-		preempt_enable();
+		queuewakeup_completed();
 }
 
 static void unlink_queue(struct sem_array *sma, struct sem_queue *q)
@@ -1300,33 +1428,6 @@ out:
 	return un;
 }
 
-
-/**
- * get_queue_result - Retrieve the result code from sem_queue
- * @q: Pointer to queue structure
- *
- * Retrieve the return code from the pending queue. If IN_WAKEUP is found in
- * q->status, then we must loop until the value is replaced with the final
- * value: This may happen if a task is woken up by an unrelated event (e.g.
- * signal) and in parallel the task is woken up by another task because it got
- * the requested semaphores.
- *
- * The function can be called with or without holding the semaphore spinlock.
- */
-static int get_queue_result(struct sem_queue *q)
-{
-	int error;
-
-	error = q->status;
-	while (unlikely(error == IN_WAKEUP)) {
-		cpu_relax();
-		error = q->status;
-	}
-
-	return error;
-}
-
-
 SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 		unsigned, nsops, const struct timespec __user *, timeout)
 {
@@ -1472,6 +1573,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 
 	queue.status = -EINTR;
 	queue.sleeper = current;
+	queuewakeup_init(&queue.done);
 
 sleep_again:
 	current->state = TASK_INTERRUPTIBLE;
@@ -1482,17 +1584,14 @@ sleep_again:
 	else
 		schedule();
 
-	error = get_queue_result(&queue);
+	error = queue.status;
 
 	if (error != -EINTR) {
 		/* fast path: update_queue already obtained all requested
-		 * resources.
-		 * Perform a smp_mb(): User space could assume that semop()
-		 * is a memory barrier: Without the mb(), the cpu could
-		 * speculatively read in user space stale data that was
-		 * overwritten by the previous owner of the semaphore.
+		 * resources. Just ensure that update_queue completed
+		 * it's access to &queue.
 		 */
-		smp_mb();
+		queuewakeup_wait(&queue.done);
 
 		goto out_free;
 	}
@@ -1502,23 +1601,16 @@ sleep_again:
 	/*
 	 * Wait until it's guaranteed that no wakeup_sem_queue_do() is ongoing.
 	 */
-	error = get_queue_result(&queue);
-
-	/*
-	 * Array removed? If yes, leave without sem_unlock().
-	 */
-	if (IS_ERR(sma)) {
-		goto out_free;
-	}
-
-
-	/*
-	 * If queue.status != -EINTR we are woken up by another process.
-	 * Leave without unlink_queue(), but with sem_unlock().
-	 */
-
+	error = queue.status;
 	if (error != -EINTR) {
-		goto out_unlock_free;
+		/* If there is a return code, then we can leave immediately. */
+		if (!IS_ERR(sma)) {
+			/* sem_lock() succeeded - then unlock */
+			sem_unlock(sma);
+		}
+		/* Except that we must wait for the hands-off */
+		queuewakeup_wait(&queue.done);
+		goto out_free;
 	}
 
 	/*
diff --git a/kernel/Makefile b/kernel/Makefile
index 2d9de86..9111af9 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -10,7 +10,7 @@ obj-y     = fork.o exec_domain.o panic.o printk.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
 	    hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
 	    notifier.o ksysfs.o cred.o \
-	    async.o range.o groups.o
+	    async.o range.o groups.o lglock.o
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace debug files and internal ftrace files
@@ -25,9 +25,11 @@ endif
 obj-y += sched/
 obj-y += power/
 
+ifeq ($(CONFIG_CHECKPOINT_RESTORE),y)
+obj-$(CONFIG_X86) += kcmp.o
+endif
 obj-$(CONFIG_FREEZER) += freezer.o
 obj-$(CONFIG_PROFILING) += profile.o
-obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
@@ -107,6 +109,7 @@ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
 obj-$(CONFIG_PADATA) += padata.o
 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+obj-$(CONFIG_UPROBES) += uprobes.o
 
 $(obj)/configs.o: $(obj)/config_data.h
 
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index a5d3b53..f4ea4b6 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -818,7 +818,7 @@ static int cgroup_call_pre_destroy(struct cgroup *cgrp)
 
 	for_each_subsys(cgrp->root, ss)
 		if (ss->pre_destroy) {
-			ret = ss->pre_destroy(ss, cgrp);
+			ret = ss->pre_destroy(cgrp);
 			if (ret)
 				break;
 		}
@@ -846,7 +846,7 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode)
 		 * Release the subsystem state objects.
 		 */
 		for_each_subsys(cgrp->root, ss)
-			ss->destroy(ss, cgrp);
+			ss->destroy(cgrp);
 
 		cgrp->root->number_of_cgroups--;
 		mutex_unlock(&cgroup_mutex);
@@ -1015,7 +1015,7 @@ static int rebind_subsystems(struct cgroupfs_root *root,
 			list_move(&ss->sibling, &root->subsys_list);
 			ss->root = root;
 			if (ss->bind)
-				ss->bind(ss, cgrp);
+				ss->bind(cgrp);
 			mutex_unlock(&ss->hierarchy_mutex);
 			/* refcount was already taken, and we're keeping it */
 		} else if (bit & removed_bits) {
@@ -1025,7 +1025,7 @@ static int rebind_subsystems(struct cgroupfs_root *root,
 			BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
 			mutex_lock(&ss->hierarchy_mutex);
 			if (ss->bind)
-				ss->bind(ss, dummytop);
+				ss->bind(dummytop);
 			dummytop->subsys[i]->cgroup = dummytop;
 			cgrp->subsys[i] = NULL;
 			subsys[i]->root = &rootnode;
@@ -1472,7 +1472,6 @@ static int cgroup_get_rootdir(struct super_block *sb)
 
 	struct inode *inode =
 		cgroup_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, sb);
-	struct dentry *dentry;
 
 	if (!inode)
 		return -ENOMEM;
@@ -1481,12 +1480,9 @@ static int cgroup_get_rootdir(struct super_block *sb)
 	inode->i_op = &cgroup_dir_inode_operations;
 	/* directories start off with i_nlink == 2 (for "." entry) */
 	inc_nlink(inode);
-	dentry = d_alloc_root(inode);
-	if (!dentry) {
-		iput(inode);
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root)
 		return -ENOMEM;
-	}
-	sb->s_root = dentry;
 	/* for everything else we want ->d_op set */
 	sb->s_d_op = &cgroup_dops;
 	return 0;
@@ -1763,6 +1759,7 @@ EXPORT_SYMBOL_GPL(cgroup_path);
 struct task_and_cgroup {
 	struct task_struct	*task;
 	struct cgroup		*cgrp;
+	struct css_set		*cg;
 };
 
 struct cgroup_taskset {
@@ -1843,11 +1840,10 @@ EXPORT_SYMBOL_GPL(cgroup_taskset_size);
  * will already exist. If not set, this function might sleep, and can fail with
  * -ENOMEM. Must be called with cgroup_mutex and threadgroup locked.
  */
-static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
-			       struct task_struct *tsk, bool guarantee)
+static void cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
+				struct task_struct *tsk, struct css_set *newcg)
 {
 	struct css_set *oldcg;
-	struct css_set *newcg;
 
 	/*
 	 * We are synchronized through threadgroup_lock() against PF_EXITING
@@ -1857,23 +1853,6 @@ static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
 	WARN_ON_ONCE(tsk->flags & PF_EXITING);
 	oldcg = tsk->cgroups;
 
-	/* locate or allocate a new css_set for this task. */
-	if (guarantee) {
-		/* we know the css_set we want already exists. */
-		struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
-		read_lock(&css_set_lock);
-		newcg = find_existing_css_set(oldcg, cgrp, template);
-		BUG_ON(!newcg);
-		get_css_set(newcg);
-		read_unlock(&css_set_lock);
-	} else {
-		might_sleep();
-		/* find_css_set will give us newcg already referenced. */
-		newcg = find_css_set(oldcg, cgrp);
-		if (!newcg)
-			return -ENOMEM;
-	}
-
 	task_lock(tsk);
 	rcu_assign_pointer(tsk->cgroups, newcg);
 	task_unlock(tsk);
@@ -1892,7 +1871,6 @@ static int cgroup_task_migrate(struct cgroup *cgrp, struct cgroup *oldcgrp,
 	put_css_set(oldcg);
 
 	set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
-	return 0;
 }
 
 /**
@@ -1910,6 +1888,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 	struct cgroup *oldcgrp;
 	struct cgroupfs_root *root = cgrp->root;
 	struct cgroup_taskset tset = { };
+	struct css_set *newcg;
 
 	/* @tsk either already exited or can't exit until the end */
 	if (tsk->flags & PF_EXITING)
@@ -1925,7 +1904,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 
 	for_each_subsys(root, ss) {
 		if (ss->can_attach) {
-			retval = ss->can_attach(ss, cgrp, &tset);
+			retval = ss->can_attach(cgrp, &tset);
 			if (retval) {
 				/*
 				 * Remember on which subsystem the can_attach()
@@ -1939,13 +1918,17 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 		}
 	}
 
-	retval = cgroup_task_migrate(cgrp, oldcgrp, tsk, false);
-	if (retval)
+	newcg = find_css_set(tsk->cgroups, cgrp);
+	if (!newcg) {
+		retval = -ENOMEM;
 		goto out;
+	}
+
+	cgroup_task_migrate(cgrp, oldcgrp, tsk, newcg);
 
 	for_each_subsys(root, ss) {
 		if (ss->attach)
-			ss->attach(ss, cgrp, &tset);
+			ss->attach(cgrp, &tset);
 	}
 
 	synchronize_rcu();
@@ -1967,7 +1950,7 @@ out:
 				 */
 				break;
 			if (ss->cancel_attach)
-				ss->cancel_attach(ss, cgrp, &tset);
+				ss->cancel_attach(cgrp, &tset);
 		}
 	}
 	return retval;
@@ -1997,66 +1980,6 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
 }
 EXPORT_SYMBOL_GPL(cgroup_attach_task_all);
 
-/*
- * cgroup_attach_proc works in two stages, the first of which prefetches all
- * new css_sets needed (to make sure we have enough memory before committing
- * to the move) and stores them in a list of entries of the following type.
- * TODO: possible optimization: use css_set->rcu_head for chaining instead
- */
-struct cg_list_entry {
-	struct css_set *cg;
-	struct list_head links;
-};
-
-static bool css_set_check_fetched(struct cgroup *cgrp,
-				  struct task_struct *tsk, struct css_set *cg,
-				  struct list_head *newcg_list)
-{
-	struct css_set *newcg;
-	struct cg_list_entry *cg_entry;
-	struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
-
-	read_lock(&css_set_lock);
-	newcg = find_existing_css_set(cg, cgrp, template);
-	read_unlock(&css_set_lock);
-
-	/* doesn't exist at all? */
-	if (!newcg)
-		return false;
-	/* see if it's already in the list */
-	list_for_each_entry(cg_entry, newcg_list, links)
-		if (cg_entry->cg == newcg)
-			return true;
-
-	/* not found */
-	return false;
-}
-
-/*
- * Find the new css_set and store it in the list in preparation for moving the
- * given task to the given cgroup. Returns 0 or -ENOMEM.
- */
-static int css_set_prefetch(struct cgroup *cgrp, struct css_set *cg,
-			    struct list_head *newcg_list)
-{
-	struct css_set *newcg;
-	struct cg_list_entry *cg_entry;
-
-	/* ensure a new css_set will exist for this thread */
-	newcg = find_css_set(cg, cgrp);
-	if (!newcg)
-		return -ENOMEM;
-	/* add it to the list */
-	cg_entry = kmalloc(sizeof(struct cg_list_entry), GFP_KERNEL);
-	if (!cg_entry) {
-		put_css_set(newcg);
-		return -ENOMEM;
-	}
-	cg_entry->cg = newcg;
-	list_add(&cg_entry->links, newcg_list);
-	return 0;
-}
-
 /**
  * cgroup_attach_proc - attach all threads in a threadgroup to a cgroup
  * @cgrp: the cgroup to attach to
@@ -2070,20 +1993,12 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	int retval, i, group_size;
 	struct cgroup_subsys *ss, *failed_ss = NULL;
 	/* guaranteed to be initialized later, but the compiler needs this */
-	struct css_set *oldcg;
 	struct cgroupfs_root *root = cgrp->root;
 	/* threadgroup list cursor and array */
 	struct task_struct *tsk;
 	struct task_and_cgroup *tc;
 	struct flex_array *group;
 	struct cgroup_taskset tset = { };
-	/*
-	 * we need to make sure we have css_sets for all the tasks we're
-	 * going to move -before- we actually start moving them, so that in
-	 * case we get an ENOMEM we can bail out before making any changes.
-	 */
-	struct list_head newcg_list;
-	struct cg_list_entry *cg_entry, *temp_nobe;
 
 	/*
 	 * step 0: in order to do expensive, possibly blocking operations for
@@ -2102,23 +2017,14 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	if (retval)
 		goto out_free_group_list;
 
-	/* prevent changes to the threadgroup list while we take a snapshot. */
-	read_lock(&tasklist_lock);
-	if (!thread_group_leader(leader)) {
-		/*
-		 * a race with de_thread from another thread's exec() may strip
-		 * us of our leadership, making while_each_thread unsafe to use
-		 * on this task. if this happens, there is no choice but to
-		 * throw this task away and try again (from cgroup_procs_write);
-		 * this is "double-double-toil-and-trouble-check locking".
-		 */
-		read_unlock(&tasklist_lock);
-		retval = -EAGAIN;
-		goto out_free_group_list;
-	}
-
 	tsk = leader;
 	i = 0;
+	/*
+	 * Prevent freeing of tasks while we take a snapshot. Tasks that are
+	 * already PF_EXITING could be freed from underneath us unless we
+	 * take an rcu_read_lock.
+	 */
+	rcu_read_lock();
 	do {
 		struct task_and_cgroup ent;
 
@@ -2128,24 +2034,24 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 
 		/* as per above, nr_threads may decrease, but not increase. */
 		BUG_ON(i >= group_size);
-		/*
-		 * saying GFP_ATOMIC has no effect here because we did prealloc
-		 * earlier, but it's good form to communicate our expectations.
-		 */
 		ent.task = tsk;
 		ent.cgrp = task_cgroup_from_root(tsk, root);
 		/* nothing to do if this task is already in the cgroup */
 		if (ent.cgrp == cgrp)
 			continue;
+		/*
+		 * saying GFP_ATOMIC has no effect here because we did prealloc
+		 * earlier, but it's good form to communicate our expectations.
+		 */
 		retval = flex_array_put(group, i, &ent, GFP_ATOMIC);
 		BUG_ON(retval != 0);
 		i++;
 	} while_each_thread(leader, tsk);
+	rcu_read_unlock();
 	/* remember the number of threads in the array for later. */
 	group_size = i;
 	tset.tc_array = group;
 	tset.tc_array_len = group_size;
-	read_unlock(&tasklist_lock);
 
 	/* methods shouldn't be called if no task is actually migrating */
 	retval = 0;
@@ -2157,7 +2063,7 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	 */
 	for_each_subsys(root, ss) {
 		if (ss->can_attach) {
-			retval = ss->can_attach(ss, cgrp, &tset);
+			retval = ss->can_attach(cgrp, &tset);
 			if (retval) {
 				failed_ss = ss;
 				goto out_cancel_attach;
@@ -2169,17 +2075,12 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	 * step 2: make sure css_sets exist for all threads to be migrated.
 	 * we use find_css_set, which allocates a new one if necessary.
 	 */
-	INIT_LIST_HEAD(&newcg_list);
 	for (i = 0; i < group_size; i++) {
 		tc = flex_array_get(group, i);
-		oldcg = tc->task->cgroups;
-
-		/* if we don't already have it in the list get a new one */
-		if (!css_set_check_fetched(cgrp, tc->task, oldcg,
-					   &newcg_list)) {
-			retval = css_set_prefetch(cgrp, oldcg, &newcg_list);
-			if (retval)
-				goto out_list_teardown;
+		tc->cg = find_css_set(tc->task->cgroups, cgrp);
+		if (!tc->cg) {
+			retval = -ENOMEM;
+			goto out_put_css_set_refs;
 		}
 	}
 
@@ -2190,8 +2091,7 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	 */
 	for (i = 0; i < group_size; i++) {
 		tc = flex_array_get(group, i);
-		retval = cgroup_task_migrate(cgrp, tc->cgrp, tc->task, true);
-		BUG_ON(retval);
+		cgroup_task_migrate(cgrp, tc->cgrp, tc->task, tc->cg);
 	}
 	/* nothing is sensitive to fork() after this point. */
 
@@ -2200,7 +2100,7 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	 */
 	for_each_subsys(root, ss) {
 		if (ss->attach)
-			ss->attach(ss, cgrp, &tset);
+			ss->attach(cgrp, &tset);
 	}
 
 	/*
@@ -2209,21 +2109,22 @@ static int cgroup_attach_proc(struct cgroup *cgrp, struct task_struct *leader)
 	synchronize_rcu();
 	cgroup_wakeup_rmdir_waiter(cgrp);
 	retval = 0;
-out_list_teardown:
-	/* clean up the list of prefetched css_sets. */
-	list_for_each_entry_safe(cg_entry, temp_nobe, &newcg_list, links) {
-		list_del(&cg_entry->links);
-		put_css_set(cg_entry->cg);
-		kfree(cg_entry);
+out_put_css_set_refs:
+	if (retval) {
+		for (i = 0; i < group_size; i++) {
+			tc = flex_array_get(group, i);
+			if (!tc->cg)
+				break;
+			put_css_set(tc->cg);
+		}
 	}
 out_cancel_attach:
-	/* same deal as in cgroup_attach_task */
 	if (retval) {
 		for_each_subsys(root, ss) {
 			if (ss == failed_ss)
 				break;
 			if (ss->cancel_attach)
-				ss->cancel_attach(ss, cgrp, &tset);
+				ss->cancel_attach(cgrp, &tset);
 		}
 	}
 out_free_group_list:
@@ -2245,22 +2146,14 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid, bool threadgroup)
 	if (!cgroup_lock_live_group(cgrp))
 		return -ENODEV;
 
+retry_find_task:
+	rcu_read_lock();
 	if (pid) {
-		rcu_read_lock();
 		tsk = find_task_by_vpid(pid);
 		if (!tsk) {
 			rcu_read_unlock();
-			cgroup_unlock();
-			return -ESRCH;
-		}
-		if (threadgroup) {
-			/*
-			 * RCU protects this access, since tsk was found in the
-			 * tid map. a race with de_thread may cause group_leader
-			 * to stop being the leader, but cgroup_attach_proc will
-			 * detect it later.
-			 */
-			tsk = tsk->group_leader;
+			ret= -ESRCH;
+			goto out_unlock_cgroup;
 		}
 		/*
 		 * even if we're attaching all tasks in the thread group, we
@@ -2271,29 +2164,38 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid, bool threadgroup)
 		    cred->euid != tcred->uid &&
 		    cred->euid != tcred->suid) {
 			rcu_read_unlock();
-			cgroup_unlock();
-			return -EACCES;
+			ret = -EACCES;
+			goto out_unlock_cgroup;
 		}
-		get_task_struct(tsk);
-		rcu_read_unlock();
-	} else {
-		if (threadgroup)
-			tsk = current->group_leader;
-		else
-			tsk = current;
-		get_task_struct(tsk);
-	}
-
-	threadgroup_lock(tsk);
+	} else
+		tsk = current;
 
 	if (threadgroup)
+		tsk = tsk->group_leader;
+	get_task_struct(tsk);
+	rcu_read_unlock();
+
+	threadgroup_lock(tsk);
+	if (threadgroup) {
+		if (!thread_group_leader(tsk)) {
+			/*
+			 * a race with de_thread from another thread's exec()
+			 * may strip us of our leadership, if this happens,
+			 * there is no choice but to throw this task away and
+			 * try again; this is
+			 * "double-double-toil-and-trouble-check locking".
+			 */
+			threadgroup_unlock(tsk);
+			put_task_struct(tsk);
+			goto retry_find_task;
+		}
 		ret = cgroup_attach_proc(cgrp, tsk);
-	else
+	} else
 		ret = cgroup_attach_task(cgrp, tsk);
-
 	threadgroup_unlock(tsk);
 
 	put_task_struct(tsk);
+out_unlock_cgroup:
 	cgroup_unlock();
 	return ret;
 }
@@ -2305,16 +2207,7 @@ static int cgroup_tasks_write(struct cgroup *cgrp, struct cftype *cft, u64 pid)
 
 static int cgroup_procs_write(struct cgroup *cgrp, struct cftype *cft, u64 tgid)
 {
-	int ret;
-	do {
-		/*
-		 * attach_proc fails with -EAGAIN if threadgroup leadership
-		 * changes in the middle of the operation, in which case we need
-		 * to find the task_struct for the new leader and start over.
-		 */
-		ret = attach_task_by_pid(cgrp, tgid, true);
-	} while (ret == -EAGAIN);
-	return ret;
+	return attach_task_by_pid(cgrp, tgid, true);
 }
 
 /**
@@ -2804,15 +2697,20 @@ static void cgroup_advance_iter(struct cgroup *cgrp,
  * using their cgroups capability, we don't maintain the lists running
  * through each css_set to its tasks until we see the list actually
  * used - in other words after the first call to cgroup_iter_start().
- *
- * The tasklist_lock is not held here, as do_each_thread() and
- * while_each_thread() are protected by RCU.
  */
 static void cgroup_enable_task_cg_lists(void)
 {
 	struct task_struct *p, *g;
 	write_lock(&css_set_lock);
 	use_task_css_set_links = 1;
+	/*
+	 * We need tasklist_lock because RCU is not safe against
+	 * while_each_thread(). Besides, a forking task that has passed
+	 * cgroup_post_fork() without seeing use_task_css_set_links = 1
+	 * is not guaranteed to have its child immediately visible in the
+	 * tasklist if we walk through it with RCU.
+	 */
+	read_lock(&tasklist_lock);
 	do_each_thread(g, p) {
 		task_lock(p);
 		/*
@@ -2824,6 +2722,7 @@ static void cgroup_enable_task_cg_lists(void)
 			list_add(&p->cg_list, &p->cgroups->tasks);
 		task_unlock(p);
 	} while_each_thread(g, p);
+	read_unlock(&tasklist_lock);
 	write_unlock(&css_set_lock);
 }
 
@@ -3043,6 +2942,38 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan)
  *
  */
 
+/* which pidlist file are we talking about? */
+enum cgroup_filetype {
+	CGROUP_FILE_PROCS,
+	CGROUP_FILE_TASKS,
+};
+
+/*
+ * A pidlist is a list of pids that virtually represents the contents of one
+ * of the cgroup files ("procs" or "tasks"). We keep a list of such pidlists,
+ * a pair (one each for procs, tasks) for each pid namespace that's relevant
+ * to the cgroup.
+ */
+struct cgroup_pidlist {
+	/*
+	 * used to find which pidlist is wanted. doesn't change as long as
+	 * this particular list stays in the list.
+	*/
+	struct { enum cgroup_filetype type; struct pid_namespace *ns; } key;
+	/* array of xids */
+	pid_t *list;
+	/* how many elements the above list has */
+	int length;
+	/* how many files are using the current array */
+	int use_count;
+	/* each of these stored in a list by its cgroup */
+	struct list_head links;
+	/* pointer to the cgroup we belong to, for list removal purposes */
+	struct cgroup *owner;
+	/* protects the other fields */
+	struct rw_semaphore mutex;
+};
+
 /*
  * The following two functions "fix" the issue where there are more pids
  * than kmalloc will give memory for; in such cases, we use vmalloc/vfree.
@@ -3827,7 +3758,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 		set_bit(CGRP_CLONE_CHILDREN, &cgrp->flags);
 
 	for_each_subsys(root, ss) {
-		struct cgroup_subsys_state *css = ss->create(ss, cgrp);
+		struct cgroup_subsys_state *css = ss->create(cgrp);
 
 		if (IS_ERR(css)) {
 			err = PTR_ERR(css);
@@ -3841,7 +3772,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 		}
 		/* At error, ->destroy() callback has to free assigned ID. */
 		if (clone_children(parent) && ss->post_clone)
-			ss->post_clone(ss, cgrp);
+			ss->post_clone(cgrp);
 	}
 
 	cgroup_lock_hierarchy(root);
@@ -3875,7 +3806,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
 
 	for_each_subsys(root, ss) {
 		if (cgrp->subsys[ss->subsys_id])
-			ss->destroy(ss, cgrp);
+			ss->destroy(cgrp);
 	}
 
 	mutex_unlock(&cgroup_mutex);
@@ -4099,7 +4030,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
 	/* Create the top cgroup state for this subsystem */
 	list_add(&ss->sibling, &rootnode.subsys_list);
 	ss->root = &rootnode;
-	css = ss->create(ss, dummytop);
+	css = ss->create(dummytop);
 	/* We don't handle early failures gracefully */
 	BUG_ON(IS_ERR(css));
 	init_cgroup_css(css, ss, dummytop);
@@ -4188,7 +4119,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
 	 * no ss->create seems to need anything important in the ss struct, so
 	 * this can happen first (i.e. before the rootnode attachment).
 	 */
-	css = ss->create(ss, dummytop);
+	css = ss->create(dummytop);
 	if (IS_ERR(css)) {
 		/* failure case - need to deassign the subsys[] slot. */
 		subsys[i] = NULL;
@@ -4206,7 +4137,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
 		int ret = cgroup_init_idr(ss, css);
 		if (ret) {
 			dummytop->subsys[ss->subsys_id] = NULL;
-			ss->destroy(ss, dummytop);
+			ss->destroy(dummytop);
 			subsys[i] = NULL;
 			mutex_unlock(&cgroup_mutex);
 			return ret;
@@ -4304,7 +4235,7 @@ void cgroup_unload_subsys(struct cgroup_subsys *ss)
 	 * pointer to find their state. note that this also takes care of
 	 * freeing the css_id.
 	 */
-	ss->destroy(ss, dummytop);
+	ss->destroy(dummytop);
 	dummytop->subsys[ss->subsys_id] = NULL;
 
 	mutex_unlock(&cgroup_mutex);
@@ -4580,7 +4511,7 @@ void cgroup_fork_callbacks(struct task_struct *child)
 		for (i = 0; i < CGROUP_BUILTIN_SUBSYS_COUNT; i++) {
 			struct cgroup_subsys *ss = subsys[i];
 			if (ss->fork)
-				ss->fork(ss, child);
+				ss->fork(child);
 		}
 	}
 }
@@ -4596,6 +4527,17 @@ void cgroup_fork_callbacks(struct task_struct *child)
  */
 void cgroup_post_fork(struct task_struct *child)
 {
+	/*
+	 * use_task_css_set_links is set to 1 before we walk the tasklist
+	 * under the tasklist_lock and we read it here after we added the child
+	 * to the tasklist under the tasklist_lock as well. If the child wasn't
+	 * yet in the tasklist when we walked through it from
+	 * cgroup_enable_task_cg_lists(), then use_task_css_set_links value
+	 * should be visible now due to the paired locking and barriers implied
+	 * by LOCK/UNLOCK: it is written before the tasklist_lock unlock
+	 * in cgroup_enable_task_cg_lists() and read here after the tasklist_lock
+	 * lock on fork.
+	 */
 	if (use_task_css_set_links) {
 		write_lock(&css_set_lock);
 		if (list_empty(&child->cg_list)) {
@@ -4682,7 +4624,7 @@ void cgroup_exit(struct task_struct *tsk, int run_callbacks)
 				struct cgroup *old_cgrp =
 					rcu_dereference_raw(cg->subsys[i])->cgroup;
 				struct cgroup *cgrp = task_cgroup(tsk, i);
-				ss->exit(ss, cgrp, old_cgrp, tsk);
+				ss->exit(cgrp, old_cgrp, tsk);
 			}
 		}
 	}
@@ -4939,9 +4881,9 @@ void free_css_id(struct cgroup_subsys *ss, struct cgroup_subsys_state *css)
 
 	rcu_assign_pointer(id->css, NULL);
 	rcu_assign_pointer(css->id, NULL);
-	write_lock(&ss->id_lock);
+	spin_lock(&ss->id_lock);
 	idr_remove(&ss->idr, id->id);
-	write_unlock(&ss->id_lock);
+	spin_unlock(&ss->id_lock);
 	kfree_rcu(id, rcu_head);
 }
 EXPORT_SYMBOL_GPL(free_css_id);
@@ -4967,10 +4909,10 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
 		error = -ENOMEM;
 		goto err_out;
 	}
-	write_lock(&ss->id_lock);
+	spin_lock(&ss->id_lock);
 	/* Don't use 0. allocates an ID of 1-65535 */
 	error = idr_get_new_above(&ss->idr, newid, 1, &myid);
-	write_unlock(&ss->id_lock);
+	spin_unlock(&ss->id_lock);
 
 	/* Returns error when there are no free spaces for new ID.*/
 	if (error) {
@@ -4985,9 +4927,9 @@ static struct css_id *get_new_cssid(struct cgroup_subsys *ss, int depth)
 	return newid;
 remove_idr:
 	error = -ENOSPC;
-	write_lock(&ss->id_lock);
+	spin_lock(&ss->id_lock);
 	idr_remove(&ss->idr, myid);
-	write_unlock(&ss->id_lock);
+	spin_unlock(&ss->id_lock);
 err_out:
 	kfree(newid);
 	return ERR_PTR(error);
@@ -4999,7 +4941,7 @@ static int __init_or_module cgroup_init_idr(struct cgroup_subsys *ss,
 {
 	struct css_id *newid;
 
-	rwlock_init(&ss->id_lock);
+	spin_lock_init(&ss->id_lock);
 	idr_init(&ss->idr);
 
 	newid = get_new_cssid(ss, 0);
@@ -5087,6 +5029,8 @@ css_get_next(struct cgroup_subsys *ss, int id,
 		return NULL;
 
 	BUG_ON(!ss->use_id);
+	WARN_ON_ONCE(!rcu_read_lock_held());
+
 	/* fill start point for scan */
 	tmpid = id;
 	while (1) {
@@ -5094,10 +5038,7 @@ css_get_next(struct cgroup_subsys *ss, int id,
 		 * scan next entry from bitmap(tree), tmpid is updated after
 		 * idr_get_next().
 		 */
-		read_lock(&ss->id_lock);
 		tmp = idr_get_next(&ss->idr, &tmpid);
-		read_unlock(&ss->id_lock);
-
 		if (!tmp)
 			break;
 		if (tmp->depth >= depth && tmp->stack[depth] == rootid) {
@@ -5137,8 +5078,7 @@ struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id)
 }
 
 #ifdef CONFIG_CGROUP_DEBUG
-static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss,
-						   struct cgroup *cont)
+static struct cgroup_subsys_state *debug_create(struct cgroup *cont)
 {
 	struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL);
 
@@ -5148,7 +5088,7 @@ static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss,
 	return css;
 }
 
-static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
+static void debug_destroy(struct cgroup *cont)
 {
 	kfree(cont->subsys[debug_subsys_id]);
 }
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
index fc0646b..f86e939 100644
--- a/kernel/cgroup_freezer.c
+++ b/kernel/cgroup_freezer.c
@@ -128,8 +128,7 @@ struct cgroup_subsys freezer_subsys;
  *    task->alloc_lock (inside __thaw_task(), prevents race with refrigerator())
  *     sighand->siglock
  */
-static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss,
-						  struct cgroup *cgroup)
+static struct cgroup_subsys_state *freezer_create(struct cgroup *cgroup)
 {
 	struct freezer *freezer;
 
@@ -142,8 +141,7 @@ static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss,
 	return &freezer->css;
 }
 
-static void freezer_destroy(struct cgroup_subsys *ss,
-			    struct cgroup *cgroup)
+static void freezer_destroy(struct cgroup *cgroup)
 {
 	struct freezer *freezer = cgroup_freezer(cgroup);
 
@@ -164,8 +162,7 @@ static bool is_task_frozen_enough(struct task_struct *task)
  * a write to that file racing against an attach, and hence the
  * can_attach() result will remain valid until the attach completes.
  */
-static int freezer_can_attach(struct cgroup_subsys *ss,
-			      struct cgroup *new_cgroup,
+static int freezer_can_attach(struct cgroup *new_cgroup,
 			      struct cgroup_taskset *tset)
 {
 	struct freezer *freezer;
@@ -185,7 +182,7 @@ static int freezer_can_attach(struct cgroup_subsys *ss,
 	return 0;
 }
 
-static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
+static void freezer_fork(struct task_struct *task)
 {
 	struct freezer *freezer;
 
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 2060c6e..d520d34 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -604,9 +604,13 @@ EXPORT_SYMBOL(cpu_all_bits);
 #ifdef CONFIG_INIT_ALL_POSSIBLE
 static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly
 	= CPU_BITS_ALL;
+unsigned int nr_possible_cpus __read_mostly = CONFIG_NR_CPUS;
 #else
 static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
+unsigned int nr_possible_cpus __read_mostly;
 #endif
+EXPORT_SYMBOL(nr_possible_cpus);
+
 const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits);
 EXPORT_SYMBOL(cpu_possible_mask);
 
@@ -614,6 +618,9 @@ static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly;
 const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits);
 EXPORT_SYMBOL(cpu_online_mask);
 
+unsigned int nr_online_cpus __read_mostly;
+EXPORT_SYMBOL(nr_online_cpus);
+
 static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly;
 const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits);
 EXPORT_SYMBOL(cpu_present_mask);
@@ -628,6 +635,8 @@ void set_cpu_possible(unsigned int cpu, bool possible)
 		cpumask_set_cpu(cpu, to_cpumask(cpu_possible_bits));
 	else
 		cpumask_clear_cpu(cpu, to_cpumask(cpu_possible_bits));
+
+	nr_possible_cpus = cpumask_weight(cpu_possible_mask);
 }
 
 void set_cpu_present(unsigned int cpu, bool present)
@@ -644,6 +653,8 @@ void set_cpu_online(unsigned int cpu, bool online)
 		cpumask_set_cpu(cpu, to_cpumask(cpu_online_bits));
 	else
 		cpumask_clear_cpu(cpu, to_cpumask(cpu_online_bits));
+
+	nr_online_cpus = cpumask_weight(cpu_online_mask);
 }
 
 void set_cpu_active(unsigned int cpu, bool active)
@@ -662,9 +673,11 @@ void init_cpu_present(const struct cpumask *src)
 void init_cpu_possible(const struct cpumask *src)
 {
 	cpumask_copy(to_cpumask(cpu_possible_bits), src);
+	nr_possible_cpus = cpumask_weight(cpu_possible_mask);
 }
 
 void init_cpu_online(const struct cpumask *src)
 {
 	cpumask_copy(to_cpumask(cpu_online_bits), src);
+	nr_online_cpus = cpumask_weight(cpu_online_mask);
 }
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index a09ac2b..5d57583 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1399,8 +1399,7 @@ static nodemask_t cpuset_attach_nodemask_from;
 static nodemask_t cpuset_attach_nodemask_to;
 
 /* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */
-static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			     struct cgroup_taskset *tset)
+static int cpuset_can_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 {
 	struct cpuset *cs = cgroup_cs(cgrp);
 	struct task_struct *task;
@@ -1436,8 +1435,7 @@ static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 	return 0;
 }
 
-static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			  struct cgroup_taskset *tset)
+static void cpuset_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 {
 	struct mm_struct *mm;
 	struct task_struct *task;
@@ -1833,8 +1831,7 @@ static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont)
  * (and likewise for mems) to the new cgroup. Called with cgroup_mutex
  * held.
  */
-static void cpuset_post_clone(struct cgroup_subsys *ss,
-			      struct cgroup *cgroup)
+static void cpuset_post_clone(struct cgroup *cgroup)
 {
 	struct cgroup *parent, *child;
 	struct cpuset *cs, *parent_cs;
@@ -1857,13 +1854,10 @@ static void cpuset_post_clone(struct cgroup_subsys *ss,
 
 /*
  *	cpuset_create - create a cpuset
- *	ss:	cpuset cgroup subsystem
  *	cont:	control group that the new cpuset will be part of
  */
 
-static struct cgroup_subsys_state *cpuset_create(
-	struct cgroup_subsys *ss,
-	struct cgroup *cont)
+static struct cgroup_subsys_state *cpuset_create(struct cgroup *cont)
 {
 	struct cpuset *cs;
 	struct cpuset *parent;
@@ -1902,7 +1896,7 @@ static struct cgroup_subsys_state *cpuset_create(
  * will call async_rebuild_sched_domains().
  */
 
-static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
+static void cpuset_destroy(struct cgroup *cont)
 {
 	struct cpuset *cs = cgroup_cs(cont);
 
diff --git a/kernel/cred.c b/kernel/cred.c
index 5791612..97b36ee 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -16,6 +16,7 @@
 #include <linux/keyctl.h>
 #include <linux/init_task.h>
 #include <linux/security.h>
+#include <linux/binfmts.h>
 #include <linux/cn_proc.h>
 
 #if 0
diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c
index 7d6fb40..d35cc2d 100644
--- a/kernel/debug/kdb/kdb_support.c
+++ b/kernel/debug/kdb/kdb_support.c
@@ -384,9 +384,9 @@ static int kdb_getphys(void *res, unsigned long addr, size_t size)
 	if (!pfn_valid(pfn))
 		return 1;
 	page = pfn_to_page(pfn);
-	vaddr = kmap_atomic(page, KM_KDB);
+	vaddr = kmap_atomic(page);
 	memcpy(res, vaddr + (addr & (PAGE_SIZE - 1)), size);
-	kunmap_atomic(vaddr, KM_KDB);
+	kunmap_atomic(vaddr);
 
 	return 0;
 }
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1b5c081..c32d6e3 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3238,10 +3238,6 @@ int perf_event_task_disable(void)
 	return 0;
 }
 
-#ifndef PERF_EVENT_INDEX_OFFSET
-# define PERF_EVENT_INDEX_OFFSET 0
-#endif
-
 static int perf_event_index(struct perf_event *event)
 {
 	if (event->hw.state & PERF_HES_STOPPED)
@@ -3250,21 +3246,26 @@ static int perf_event_index(struct perf_event *event)
 	if (event->state != PERF_EVENT_STATE_ACTIVE)
 		return 0;
 
-	return event->hw.idx + 1 - PERF_EVENT_INDEX_OFFSET;
+	return event->pmu->event_idx(event);
 }
 
 static void calc_timer_values(struct perf_event *event,
+				u64 *now,
 				u64 *enabled,
 				u64 *running)
 {
-	u64 now, ctx_time;
+	u64 ctx_time;
 
-	now = perf_clock();
-	ctx_time = event->shadow_ctx_time + now;
+	*now = perf_clock();
+	ctx_time = event->shadow_ctx_time + *now;
 	*enabled = ctx_time - event->tstamp_enabled;
 	*running = ctx_time - event->tstamp_running;
 }
 
+void __weak perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now)
+{
+}
+
 /*
  * Callers need to ensure there can be no nesting of this function, otherwise
  * the seqlock logic goes bad. We can not serialize this because the arch
@@ -3274,7 +3275,7 @@ void perf_event_update_userpage(struct perf_event *event)
 {
 	struct perf_event_mmap_page *userpg;
 	struct ring_buffer *rb;
-	u64 enabled, running;
+	u64 enabled, running, now;
 
 	rcu_read_lock();
 	/*
@@ -3286,7 +3287,7 @@ void perf_event_update_userpage(struct perf_event *event)
 	 * because of locking issue as we can be called in
 	 * NMI context
 	 */
-	calc_timer_values(event, &enabled, &running);
+	calc_timer_values(event, &now, &enabled, &running);
 	rb = rcu_dereference(event->rb);
 	if (!rb)
 		goto unlock;
@@ -3302,7 +3303,7 @@ void perf_event_update_userpage(struct perf_event *event)
 	barrier();
 	userpg->index = perf_event_index(event);
 	userpg->offset = perf_event_count(event);
-	if (event->state == PERF_EVENT_STATE_ACTIVE)
+	if (userpg->index)
 		userpg->offset -= local64_read(&event->hw.prev_count);
 
 	userpg->time_enabled = enabled +
@@ -3311,6 +3312,8 @@ void perf_event_update_userpage(struct perf_event *event)
 	userpg->time_running = running +
 			atomic64_read(&event->child_total_time_running);
 
+	perf_update_user_clock(userpg, now);
+
 	barrier();
 	++userpg->lock;
 	preempt_enable();
@@ -3568,6 +3571,8 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
 	event->mmap_user = get_current_user();
 	vma->vm_mm->pinned_vm += event->mmap_locked;
 
+	perf_event_update_userpage(event);
+
 unlock:
 	if (!ret)
 		atomic_inc(&event->mmap_count);
@@ -3799,7 +3804,7 @@ static void perf_output_read_group(struct perf_output_handle *handle,
 static void perf_output_read(struct perf_output_handle *handle,
 			     struct perf_event *event)
 {
-	u64 enabled = 0, running = 0;
+	u64 enabled = 0, running = 0, now;
 	u64 read_format = event->attr.read_format;
 
 	/*
@@ -3812,7 +3817,7 @@ static void perf_output_read(struct perf_output_handle *handle,
 	 * NMI context
 	 */
 	if (read_format & PERF_FORMAT_TOTAL_TIMES)
-		calc_timer_values(event, &enabled, &running);
+		calc_timer_values(event, &now, &enabled, &running);
 
 	if (event->attr.read_format & PERF_FORMAT_GROUP)
 		perf_output_read_group(handle, event, enabled, running);
@@ -5031,6 +5036,11 @@ static int perf_swevent_init(struct perf_event *event)
 	return 0;
 }
 
+static int perf_swevent_event_idx(struct perf_event *event)
+{
+	return 0;
+}
+
 static struct pmu perf_swevent = {
 	.task_ctx_nr	= perf_sw_context,
 
@@ -5040,6 +5050,8 @@ static struct pmu perf_swevent = {
 	.start		= perf_swevent_start,
 	.stop		= perf_swevent_stop,
 	.read		= perf_swevent_read,
+
+	.event_idx	= perf_swevent_event_idx,
 };
 
 #ifdef CONFIG_EVENT_TRACING
@@ -5126,6 +5138,8 @@ static struct pmu perf_tracepoint = {
 	.start		= perf_swevent_start,
 	.stop		= perf_swevent_stop,
 	.read		= perf_swevent_read,
+
+	.event_idx	= perf_swevent_event_idx,
 };
 
 static inline void perf_tp_register(void)
@@ -5345,6 +5359,8 @@ static struct pmu perf_cpu_clock = {
 	.start		= cpu_clock_event_start,
 	.stop		= cpu_clock_event_stop,
 	.read		= cpu_clock_event_read,
+
+	.event_idx	= perf_swevent_event_idx,
 };
 
 /*
@@ -5417,6 +5433,8 @@ static struct pmu perf_task_clock = {
 	.start		= task_clock_event_start,
 	.stop		= task_clock_event_stop,
 	.read		= task_clock_event_read,
+
+	.event_idx	= perf_swevent_event_idx,
 };
 
 static void perf_pmu_nop_void(struct pmu *pmu)
@@ -5444,6 +5462,11 @@ static void perf_pmu_cancel_txn(struct pmu *pmu)
 	perf_pmu_enable(pmu);
 }
 
+static int perf_event_idx_default(struct perf_event *event)
+{
+	return event->hw.idx + 1;
+}
+
 /*
  * Ensures all contexts with the same task_ctx_nr have the same
  * pmu_cpu_context too.
@@ -5530,6 +5553,7 @@ static int pmu_dev_alloc(struct pmu *pmu)
 	if (!pmu->dev)
 		goto out;
 
+	pmu->dev->groups = pmu->attr_groups;
 	device_initialize(pmu->dev);
 	ret = dev_set_name(pmu->dev, "%s", pmu->name);
 	if (ret)
@@ -5633,6 +5657,9 @@ got_cpu_context:
 		pmu->pmu_disable = perf_pmu_nop_void;
 	}
 
+	if (!pmu->event_idx)
+		pmu->event_idx = perf_event_idx_default;
+
 	list_add_rcu(&pmu->entry, &pmus);
 	ret = 0;
 unlock:
@@ -6943,8 +6970,7 @@ unlock:
 device_initcall(perf_event_sysfs_init);
 
 #ifdef CONFIG_CGROUP_PERF
-static struct cgroup_subsys_state *perf_cgroup_create(
-	struct cgroup_subsys *ss, struct cgroup *cont)
+static struct cgroup_subsys_state *perf_cgroup_create(struct cgroup *cont)
 {
 	struct perf_cgroup *jc;
 
@@ -6961,8 +6987,7 @@ static struct cgroup_subsys_state *perf_cgroup_create(
 	return &jc->css;
 }
 
-static void perf_cgroup_destroy(struct cgroup_subsys *ss,
-				struct cgroup *cont)
+static void perf_cgroup_destroy(struct cgroup *cont)
 {
 	struct perf_cgroup *jc;
 	jc = container_of(cgroup_subsys_state(cont, perf_subsys_id),
@@ -6978,8 +7003,7 @@ static int __perf_cgroup_move(void *info)
 	return 0;
 }
 
-static void perf_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-			       struct cgroup_taskset *tset)
+static void perf_cgroup_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
 {
 	struct task_struct *task;
 
@@ -6987,8 +7011,8 @@ static void perf_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 		task_function_call(task, __perf_cgroup_move, task);
 }
 
-static void perf_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp,
-		struct cgroup *old_cgrp, struct task_struct *task)
+static void perf_cgroup_exit(struct cgroup *cgrp, struct cgroup *old_cgrp,
+			     struct task_struct *task)
 {
 	/*
 	 * cgroup_exit() is called in the copy_process() failure path.
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index b7971d6..b0309f7 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -613,6 +613,11 @@ static void hw_breakpoint_stop(struct perf_event *bp, int flags)
 	bp->hw.state = PERF_HES_STOPPED;
 }
 
+static int hw_breakpoint_event_idx(struct perf_event *bp)
+{
+	return 0;
+}
+
 static struct pmu perf_breakpoint = {
 	.task_ctx_nr	= perf_sw_context, /* could eventually get its own */
 
@@ -622,6 +627,8 @@ static struct pmu perf_breakpoint = {
 	.start		= hw_breakpoint_start,
 	.stop		= hw_breakpoint_stop,
 	.read		= hw_breakpoint_pmu_read,
+
+	.event_idx	= hw_breakpoint_event_idx,
 };
 
 int __init init_hw_breakpoint(void)
diff --git a/kernel/exit.c b/kernel/exit.c
index 4b4042f..f1c39d4 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -52,6 +52,7 @@
 #include <linux/hw_breakpoint.h>
 #include <linux/oom.h>
 #include <linux/writeback.h>
+#include <linux/shm.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -686,11 +687,11 @@ static void exit_mm(struct task_struct * tsk)
 }
 
 /*
- * When we die, we re-parent all our children.
- * Try to give them to another thread in our thread
- * group, and if no such member exists, give it to
- * the child reaper process (ie "init") in our pid
- * space.
+ * When we die, we re-parent all our children, and try to:
+ * 1. give them to another thread in our thread group, if such a member exists
+ * 2. give it to the first ancestor process which prctl'd itself as a
+ *    child_subreaper for its children (like a service manager)
+ * 3. give it to the init process (PID 1) in our pid namespace
  */
 static struct task_struct *find_new_reaper(struct task_struct *father)
 	__releases(&tasklist_lock)
@@ -710,8 +711,11 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
 
 	if (unlikely(pid_ns->child_reaper == father)) {
 		write_unlock_irq(&tasklist_lock);
-		if (unlikely(pid_ns == &init_pid_ns))
-			panic("Attempted to kill init!");
+		if (unlikely(pid_ns == &init_pid_ns)) {
+			panic("Attempted to kill init! exitcode=0x%08x\n",
+				father->signal->group_exit_code ?:
+					father->exit_code);
+		}
 
 		zap_pid_ns_processes(pid_ns);
 		write_lock_irq(&tasklist_lock);
@@ -721,6 +725,29 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
 		 * forget_original_parent() must move them somewhere.
 		 */
 		pid_ns->child_reaper = init_pid_ns.child_reaper;
+	} else if (father->signal->has_child_subreaper) {
+		struct task_struct *reaper;
+
+		/*
+		 * Find the first ancestor marked as child_subreaper.
+		 * Note that the code below checks same_thread_group(reaper,
+		 * pid_ns->child_reaper).  This is what we need to DTRT in a
+		 * PID namespace. However we still need the check above, see
+		 * http://marc.info/?l=linux-kernel&m=131385460420380
+		 */
+		for (reaper = father->real_parent;
+		     reaper != &init_task;
+		     reaper = reaper->real_parent) {
+			if (same_thread_group(reaper, pid_ns->child_reaper))
+				break;
+			if (!reaper->signal->is_child_subreaper)
+				continue;
+			thread = reaper;
+			do {
+				if (!(thread->flags & PF_EXITING))
+					return reaper;
+			} while_each_thread(reaper, thread);
+		}
 	}
 
 	return pid_ns->child_reaper;
diff --git a/kernel/fork.c b/kernel/fork.c
index b77fd55..5895404 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -66,6 +66,7 @@
 #include <linux/user-return-notifier.h>
 #include <linux/oom.h>
 #include <linux/khugepaged.h>
+#include <linux/uprobes.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -192,6 +193,7 @@ void __put_task_struct(struct task_struct *tsk)
 	WARN_ON(atomic_read(&tsk->usage));
 	WARN_ON(tsk == current);
 
+	security_task_free(tsk);
 	exit_creds(tsk);
 	delayacct_tsk_free(tsk);
 	put_signal_struct(tsk->signal);
@@ -354,7 +356,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 		charge = 0;
 		if (mpnt->vm_flags & VM_ACCOUNT) {
 			unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
-			if (security_vm_enough_memory(len))
+			if (security_vm_enough_memory_mm(oldmm, len)) /* sic */
 				goto fail_nomem;
 			charge = len;
 		}
@@ -419,6 +421,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 
 		if (retval)
 			goto out;
+
+		if (file && mmap_uprobe(tmp))
+			goto out;
 	}
 	/* a new mm has just been created */
 	arch_dup_mmap(oldmm, mm);
@@ -510,6 +515,23 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
 	return NULL;
 }
 
+static void check_mm(struct mm_struct *mm)
+{
+	int i;
+
+	for (i = 0; i < NR_MM_COUNTERS; i++) {
+		long x = atomic_long_read(&mm->rss_stat.count[i]);
+
+		if (unlikely(x))
+			printk(KERN_ALERT "BUG: Bad rss-counter state "
+					  "mm:%p idx:%d val:%ld\n", mm, i, x);
+	}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	VM_BUG_ON(mm->pmd_huge_pte);
+#endif
+}
+
 /*
  * Allocate and initialize an mm_struct.
  */
@@ -537,9 +559,7 @@ void __mmdrop(struct mm_struct *mm)
 	mm_free_pgd(mm);
 	destroy_context(mm);
 	mmu_notifier_mm_destroy(mm);
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-	VM_BUG_ON(mm->pmd_huge_pte);
-#endif
+	check_mm(mm);
 	free_mm(mm);
 }
 EXPORT_SYMBOL_GPL(__mmdrop);
@@ -552,6 +572,7 @@ void mmput(struct mm_struct *mm)
 	might_sleep();
 
 	if (atomic_dec_and_test(&mm->mm_users)) {
+		free_uprobes_xol_area(mm);
 		exit_aio(mm);
 		ksm_exit(mm);
 		khugepaged_exit(mm); /* must run before exit_mmap */
@@ -700,6 +721,8 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
 		exit_pi_state_list(tsk);
 #endif
 
+	free_uprobe_utask(tsk);
+
 	/* Get rid of any cached register state */
 	deactivate_mm(tsk, mm);
 
@@ -752,10 +775,15 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
 	/* Initializing for Swap token stuff */
 	mm->token_priority = 0;
 	mm->last_interval = 0;
+	atomic_set(&mm->active_swap_token, 0);
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	mm->pmd_huge_pte = NULL;
 #endif
+#ifdef CONFIG_UPROBES
+	atomic_set(&mm->mm_uprobes_count, 0);
+	mm->uprobes_xol_area = NULL;
+#endif
 
 	if (!mm_init(mm, tsk))
 		goto fail_nomem;
@@ -1004,6 +1032,9 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 	sig->oom_score_adj = current->signal->oom_score_adj;
 	sig->oom_score_adj_min = current->signal->oom_score_adj_min;
 
+	sig->has_child_subreaper = current->signal->has_child_subreaper ||
+				   current->signal->is_child_subreaper;
+
 	mutex_init(&sig->cred_guard_mutex);
 
 	return 0;
@@ -1292,6 +1323,10 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	INIT_LIST_HEAD(&p->pi_state_list);
 	p->pi_state_cache = NULL;
 #endif
+#ifdef CONFIG_UPROBES
+	p->utask = NULL;
+	p->uprobes_srcu_id = -1;
+#endif
 	/*
 	 * sigaltstack should be cleared when sharing the same VM
 	 */
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index ae34bf5..a53fff9 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1568,6 +1568,14 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
 	if (rt_task(current))
 		slack = 0;
 
+	/*
+	 * Applications will often sleep(0) to indicate that they wish to
+	 * be scheduled. Special case that to avoid actually putting them
+	 * to sleep for the duration of the slack.
+	 */
+	if (rqtp->tv_sec == 0 && rqtp->tv_nsec == 0)
+		slack = 0;
+
 	hrtimer_init_on_stack(&t.timer, clockid, mode);
 	hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack);
 	if (do_nanosleep(&t, mode))
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 5a38bf4..1f2dece 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -13,7 +13,7 @@ config GENERIC_HARDIRQS
 # Options selectable by the architecture code
 
 # Make sparse irq Kconfig switch below available
-config HAVE_SPARSE_IRQ
+config MAY_HAVE_SPARSE_IRQ
        bool
 
 # Enable the generic irq autoprobe mechanism
@@ -61,8 +61,7 @@ config IRQ_FORCED_THREADING
        bool
 
 config SPARSE_IRQ
-	bool "Support sparse irq numbering"
-	depends on HAVE_SPARSE_IRQ
+	bool "Support sparse irq numbering" if MAY_HAVE_SPARSE_IRQ
 	---help---
 
 	  Sparse irq numbering is useful for distro kernels that want
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index f7c543a..4dbc9c9 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -61,8 +61,7 @@ int irq_set_irq_type(unsigned int irq, unsigned int type)
 		return -EINVAL;
 
 	type &= IRQ_TYPE_SENSE_MASK;
-	if (type != IRQ_TYPE_NONE)
-		ret = __irq_set_trigger(desc, irq, type);
+	ret = __irq_set_trigger(desc, irq, type);
 	irq_put_desc_busunlock(desc, flags);
 	return ret;
 }
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 1f9e265..25a498e 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1,189 +1,781 @@
+#include <linux/debugfs.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdesc.h>
 #include <linux/irqdomain.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/fs.h>
+
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
+				 * ie. legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
+#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
+#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
 
 static LIST_HEAD(irq_domain_list);
 static DEFINE_MUTEX(irq_domain_mutex);
 
+static DEFINE_MUTEX(revmap_trees_mutex);
+static unsigned int irq_virq_count = NR_IRQS;
+static struct irq_domain *irq_default_domain;
+
 /**
- * irq_domain_add() - Register an irq_domain
- * @domain: ptr to initialized irq_domain structure
+ * irq_domain_alloc() - Allocate a new irq_domain data structure
+ * @of_node: optional device-tree node of the interrupt controller
+ * @revmap_type: type of reverse mapping to use
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
  *
- * Registers an irq_domain structure.  The irq_domain must at a minimum be
- * initialized with an ops structure pointer, and either a ->to_irq hook or
- * a valid irq_base value.  Everything else is optional.
+ * Allocates and initialize and irq_domain structure.  Caller is expected to
+ * register allocated irq_domain with irq_domain_register().  Returns pointer
+ * to IRQ domain, or NULL on failure.
  */
-void irq_domain_add(struct irq_domain *domain)
+static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
+					   unsigned int revmap_type,
+					   const struct irq_domain_ops *ops,
+					   void *host_data)
 {
-	struct irq_data *d;
-	int hwirq, irq;
+	struct irq_domain *domain;
 
-	/*
-	 * This assumes that the irq_domain owner has already allocated
-	 * the irq_descs.  This block will be removed when support for dynamic
-	 * allocation of irq_descs is added to irq_domain.
-	 */
-	irq_domain_for_each_irq(domain, hwirq, irq) {
-		d = irq_get_irq_data(irq);
-		if (!d) {
-			WARN(1, "error: assigning domain to non existant irq_desc");
-			return;
-		}
-		if (d->domain) {
-			/* things are broken; just report, don't clean up */
-			WARN(1, "error: irq_desc already assigned to a domain");
-			return;
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (WARN_ON(!domain))
+		return NULL;
+
+	/* Fill structure */
+	domain->revmap_type = revmap_type;
+	domain->ops = ops;
+	domain->host_data = host_data;
+	domain->of_node = of_node_get(of_node);
+
+	return domain;
+}
+
+static void irq_domain_add(struct irq_domain *domain)
+{
+	mutex_lock(&irq_domain_mutex);
+	list_add(&domain->link, &irq_domain_list);
+	mutex_unlock(&irq_domain_mutex);
+	pr_debug("irq: Allocated domain of type %d @0x%p\n",
+		 domain->revmap_type, domain);
+}
+
+static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
+					     irq_hw_number_t hwirq)
+{
+	irq_hw_number_t first_hwirq = domain->revmap_data.legacy.first_hwirq;
+	int size = domain->revmap_data.legacy.size;
+
+	if (WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size))
+		return 0;
+	return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq;
+}
+
+/**
+ * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @size: total number of irqs in legacy mapping
+ * @first_irq: first number of irq block assigned to the domain
+ * @first_hwirq: first hwirq number to use for the translation. Should normally
+ *               be '0', but a positive integer can be used if the effective
+ *               hwirqs numbering does not begin at zero.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ *
+ * Note: the map() callback will be called before this function returns
+ * for all legacy interrupts except 0 (which is always the invalid irq for
+ * a legacy controller).
+ */
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+					 unsigned int size,
+					 unsigned int first_irq,
+					 irq_hw_number_t first_hwirq,
+					 const struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain;
+	unsigned int i;
+
+	domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
+	if (!domain)
+		return NULL;
+
+	domain->revmap_data.legacy.first_irq = first_irq;
+	domain->revmap_data.legacy.first_hwirq = first_hwirq;
+	domain->revmap_data.legacy.size = size;
+
+	mutex_lock(&irq_domain_mutex);
+	/* Verify that all the irqs are available */
+	for (i = 0; i < size; i++) {
+		int irq = first_irq + i;
+		struct irq_data *irq_data = irq_get_irq_data(irq);
+
+		if (WARN_ON(!irq_data || irq_data->domain)) {
+			mutex_unlock(&irq_domain_mutex);
+			of_node_put(domain->of_node);
+			kfree(domain);
+			return NULL;
 		}
-		d->domain = domain;
-		d->hwirq = hwirq;
 	}
 
-	mutex_lock(&irq_domain_mutex);
-	list_add(&domain->list, &irq_domain_list);
+	/* Claim all of the irqs before registering a legacy domain */
+	for (i = 0; i < size; i++) {
+		struct irq_data *irq_data = irq_get_irq_data(first_irq + i);
+		irq_data->hwirq = first_hwirq + i;
+		irq_data->domain = domain;
+	}
 	mutex_unlock(&irq_domain_mutex);
+
+	for (i = 0; i < size; i++) {
+		int irq = first_irq + i;
+		int hwirq = first_hwirq + i;
+
+		/* IRQ0 gets ignored */
+		if (!irq)
+			continue;
+
+		/* Legacy flags are left to default at this point,
+		 * one can then use irq_create_mapping() to
+		 * explicitly change them
+		 */
+		ops->map(domain, irq, hwirq);
+
+		/* Clear norequest flags */
+		irq_clear_status_flags(irq, IRQ_NOREQUEST);
+	}
+
+	irq_domain_add(domain);
+	return domain;
+}
+
+/**
+ * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ */
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+					 unsigned int size,
+					 const struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain;
+	unsigned int *revmap;
+
+	revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
+	if (WARN_ON(!revmap))
+		return NULL;
+
+	domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data);
+	if (!domain) {
+		kfree(revmap);
+		return NULL;
+	}
+	domain->revmap_data.linear.size = size;
+	domain->revmap_data.linear.revmap = revmap;
+	irq_domain_add(domain);
+	return domain;
+}
+
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+					 const struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain = irq_domain_alloc(of_node,
+					IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
+	if (domain)
+		irq_domain_add(domain);
+	return domain;
+}
+
+/**
+ * irq_domain_add_tree()
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ *
+ * Note: The radix tree will be allocated later during boot automatically
+ * (the reverse mapping will use the slow path until that happens).
+ */
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+					 const struct irq_domain_ops *ops,
+					 void *host_data)
+{
+	struct irq_domain *domain = irq_domain_alloc(of_node,
+					IRQ_DOMAIN_MAP_TREE, ops, host_data);
+	if (domain) {
+		INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
+		irq_domain_add(domain);
+	}
+	return domain;
 }
 
 /**
- * irq_domain_del() - Unregister an irq_domain
- * @domain: ptr to registered irq_domain.
+ * irq_find_host() - Locates a domain for a given device node
+ * @node: device-tree node of the interrupt controller
  */
-void irq_domain_del(struct irq_domain *domain)
+struct irq_domain *irq_find_host(struct device_node *node)
 {
-	struct irq_data *d;
-	int hwirq, irq;
+	struct irq_domain *h, *found = NULL;
+	int rc;
 
+	/* We might want to match the legacy controller last since
+	 * it might potentially be set to match all interrupts in
+	 * the absence of a device node. This isn't a problem so far
+	 * yet though...
+	 */
 	mutex_lock(&irq_domain_mutex);
-	list_del(&domain->list);
+	list_for_each_entry(h, &irq_domain_list, link) {
+		if (h->ops->match)
+			rc = h->ops->match(h, node);
+		else
+			rc = (h->of_node != NULL) && (h->of_node == node);
+
+		if (rc) {
+			found = h;
+			break;
+		}
+	}
 	mutex_unlock(&irq_domain_mutex);
+	return found;
+}
+EXPORT_SYMBOL_GPL(irq_find_host);
+
+/**
+ * irq_set_default_host() - Set a "default" irq domain
+ * @domain: default domain pointer
+ *
+ * For convenience, it's possible to set a "default" domain that will be used
+ * whenever NULL is passed to irq_create_mapping(). It makes life easier for
+ * platforms that want to manipulate a few hard coded interrupt numbers that
+ * aren't properly represented in the device-tree.
+ */
+void irq_set_default_host(struct irq_domain *domain)
+{
+	pr_debug("irq: Default domain set to @0x%p\n", domain);
+
+	irq_default_domain = domain;
+}
+
+/**
+ * irq_set_virq_count() - Set the maximum number of linux irqs
+ * @count: number of linux irqs, capped with NR_IRQS
+ *
+ * This is mainly for use by platforms like iSeries who want to program
+ * the virtual irq number in the controller to avoid the reverse mapping
+ */
+void irq_set_virq_count(unsigned int count)
+{
+	pr_debug("irq: Trying to set virq count to %d\n", count);
 
-	/* Clear the irq_domain assignments */
-	irq_domain_for_each_irq(domain, hwirq, irq) {
-		d = irq_get_irq_data(irq);
-		d->domain = NULL;
+	BUG_ON(count < NUM_ISA_INTERRUPTS);
+	if (count < NR_IRQS)
+		irq_virq_count = count;
+}
+
+static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+			    irq_hw_number_t hwirq)
+{
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+
+	irq_data->hwirq = hwirq;
+	irq_data->domain = domain;
+	if (domain->ops->map(domain, virq, hwirq)) {
+		pr_debug("irq: -> mapping failed, freeing\n");
+		irq_data->domain = NULL;
+		irq_data->hwirq = 0;
+		return -1;
 	}
+
+	irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
+	return 0;
 }
 
-#if defined(CONFIG_OF_IRQ)
 /**
- * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
+ * irq_create_direct_mapping() - Allocate an irq for direct mapping
+ * @domain: domain to allocate the irq for or NULL for default domain
  *
- * Used by the device tree interrupt mapping code to translate a device tree
- * interrupt specifier to a valid linux irq number.  Returns either a valid
- * linux IRQ number or 0.
+ * This routine is used for irq controllers which can choose the hardware
+ * interrupt numbers they generate. In such a case it's simplest to use
+ * the linux irq as the hardware interrupt number.
+ */
+unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+{
+	unsigned int virq;
+
+	if (domain == NULL)
+		domain = irq_default_domain;
+
+	BUG_ON(domain == NULL);
+	WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
+
+	virq = irq_alloc_desc_from(1, 0);
+	if (!virq) {
+		pr_debug("irq: create_direct virq allocation failed\n");
+		return 0;
+	}
+	if (virq >= irq_virq_count) {
+		pr_err("ERROR: no free irqs available below %i maximum\n",
+			irq_virq_count);
+		irq_free_desc(virq);
+		return 0;
+	}
+
+	pr_debug("irq: create_direct obtained virq %d\n", virq);
+
+	if (irq_setup_virq(domain, virq, virq)) {
+		irq_free_desc(virq);
+		return 0;
+	}
+
+	return virq;
+}
+
+/**
+ * irq_create_mapping() - Map a hardware interrupt into linux irq space
+ * @domain: domain owning this hardware interrupt or NULL for default domain
+ * @hwirq: hardware irq number in that domain space
  *
- * When the caller no longer need the irq number returned by this function it
- * should arrange to call irq_dispose_mapping().
+ * Only one mapping per hardware interrupt is permitted. Returns a linux
+ * irq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
  */
+unsigned int irq_create_mapping(struct irq_domain *domain,
+				irq_hw_number_t hwirq)
+{
+	unsigned int virq, hint;
+
+	pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
+
+	/* Look for default domain if nececssary */
+	if (domain == NULL)
+		domain = irq_default_domain;
+	if (domain == NULL) {
+		printk(KERN_WARNING "irq_create_mapping called for"
+		       " NULL domain, hwirq=%lx\n", hwirq);
+		WARN_ON(1);
+		return 0;
+	}
+	pr_debug("irq: -> using domain @%p\n", domain);
+
+	/* Check if mapping already exists */
+	virq = irq_find_mapping(domain, hwirq);
+	if (virq) {
+		pr_debug("irq: -> existing mapping on virq %d\n", virq);
+		return virq;
+	}
+
+	/* Get a virtual interrupt number */
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return irq_domain_legacy_revmap(domain, hwirq);
+
+	/* Allocate a virtual interrupt number */
+	hint = hwirq % irq_virq_count;
+	if (hint == 0)
+		hint++;
+	virq = irq_alloc_desc_from(hint, 0);
+	if (!virq)
+		virq = irq_alloc_desc_from(1, 0);
+	if (!virq) {
+		pr_debug("irq: -> virq allocation failed\n");
+		return 0;
+	}
+
+	if (irq_setup_virq(domain, virq, hwirq)) {
+		if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
+			irq_free_desc(virq);
+		return 0;
+	}
+
+	pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
+		hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
+
+	return virq;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping);
+
 unsigned int irq_create_of_mapping(struct device_node *controller,
 				   const u32 *intspec, unsigned int intsize)
 {
 	struct irq_domain *domain;
-	unsigned long hwirq;
-	unsigned int irq, type;
-	int rc = -EINVAL;
+	irq_hw_number_t hwirq;
+	unsigned int type = IRQ_TYPE_NONE;
+	unsigned int virq;
 
-	/* Find a domain which can translate the irq spec */
-	mutex_lock(&irq_domain_mutex);
-	list_for_each_entry(domain, &irq_domain_list, list) {
-		if (!domain->ops->dt_translate)
-			continue;
-		rc = domain->ops->dt_translate(domain, controller,
-					intspec, intsize, &hwirq, &type);
-		if (rc == 0)
-			break;
+	domain = controller ? irq_find_host(controller) : irq_default_domain;
+	if (!domain) {
+		printk(KERN_WARNING "irq: no irq domain found for %s !\n",
+		       controller->full_name);
+		return 0;
 	}
-	mutex_unlock(&irq_domain_mutex);
 
-	if (rc != 0)
-		return 0;
+	/* If domain has no translation, then we assume interrupt line */
+	if (domain->ops->xlate == NULL)
+		hwirq = intspec[0];
+	else {
+		if (domain->ops->xlate(domain, controller, intspec, intsize,
+				     &hwirq, &type))
+			return 0;
+	}
+
+	/* Create mapping */
+	virq = irq_create_mapping(domain, hwirq);
+	if (!virq)
+		return virq;
 
-	irq = irq_domain_to_irq(domain, hwirq);
-	if (type != IRQ_TYPE_NONE)
-		irq_set_irq_type(irq, type);
-	pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
-		 controller->full_name, (int)hwirq, irq, type);
-	return irq;
+	/* Set type if specified and different than the current one */
+	if (type != IRQ_TYPE_NONE &&
+	    type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
+		irq_set_irq_type(virq, type);
+	return virq;
 }
 EXPORT_SYMBOL_GPL(irq_create_of_mapping);
 
 /**
- * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
- * @irq: linux irq number to be discarded
+ * irq_dispose_mapping() - Unmap an interrupt
+ * @virq: linux irq number of the interrupt to unmap
+ */
+void irq_dispose_mapping(unsigned int virq)
+{
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+	struct irq_domain *domain;
+	irq_hw_number_t hwirq;
+
+	if (!virq || !irq_data)
+		return;
+
+	domain = irq_data->domain;
+	if (WARN_ON(domain == NULL))
+		return;
+
+	/* Never unmap legacy interrupts */
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return;
+
+	irq_set_status_flags(virq, IRQ_NOREQUEST);
+
+	/* remove chip and handler */
+	irq_set_chip_and_handler(virq, NULL, NULL);
+
+	/* Make sure it's completed */
+	synchronize_irq(virq);
+
+	/* Tell the PIC about it */
+	if (domain->ops->unmap)
+		domain->ops->unmap(domain, virq);
+	smp_mb();
+
+	/* Clear reverse map */
+	hwirq = irq_data->hwirq;
+	switch(domain->revmap_type) {
+	case IRQ_DOMAIN_MAP_LINEAR:
+		if (hwirq < domain->revmap_data.linear.size)
+			domain->revmap_data.linear.revmap[hwirq] = 0;
+		break;
+	case IRQ_DOMAIN_MAP_TREE:
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_delete(&domain->revmap_data.tree, hwirq);
+		mutex_unlock(&revmap_trees_mutex);
+		break;
+	}
+
+	irq_free_desc(virq);
+}
+EXPORT_SYMBOL_GPL(irq_dispose_mapping);
+
+/**
+ * irq_find_mapping() - Find a linux irq from an hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is a slow path, for use by generic code. It's expected that an
+ * irq controller implementation directly calls the appropriate low level
+ * mapping function.
+ */
+unsigned int irq_find_mapping(struct irq_domain *domain,
+			      irq_hw_number_t hwirq)
+{
+	unsigned int i;
+	unsigned int hint = hwirq % irq_virq_count;
+
+	/* Look for default domain if nececssary */
+	if (domain == NULL)
+		domain = irq_default_domain;
+	if (domain == NULL)
+		return 0;
+
+	/* legacy -> bail early */
+	if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+		return irq_domain_legacy_revmap(domain, hwirq);
+
+	/* Slow path does a linear search of the map */
+	if (hint == 0)
+		hint = 1;
+	i = hint;
+	do {
+		struct irq_data *data = irq_get_irq_data(i);
+		if (data && (data->domain == domain) && (data->hwirq == hwirq))
+			return i;
+		i++;
+		if (i >= irq_virq_count)
+			i = 1;
+	} while(i != hint);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_find_mapping);
+
+/**
+ * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
  *
- * Calling this function indicates the caller no longer needs a reference to
- * the linux irq number returned by a prior call to irq_create_of_mapping().
+ * This is a fast path, for use by irq controller code that uses radix tree
+ * revmaps
  */
-void irq_dispose_mapping(unsigned int irq)
+unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
+				     irq_hw_number_t hwirq)
 {
+	struct irq_data *irq_data;
+
+	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+		return irq_find_mapping(domain, hwirq);
+
+	/*
+	 * Freeing an irq can delete nodes along the path to
+	 * do the lookup via call_rcu.
+	 */
+	rcu_read_lock();
+	irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq);
+	rcu_read_unlock();
+
 	/*
-	 * nothing yet; will be filled when support for dynamic allocation of
-	 * irq_descs is added to irq_domain
+	 * If found in radix tree, then fine.
+	 * Else fallback to linear lookup - this should not happen in practice
+	 * as it means that we failed to insert the node in the radix tree.
 	 */
+	return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
 }
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
-int irq_domain_simple_dt_translate(struct irq_domain *d,
-			    struct device_node *controller,
-			    const u32 *intspec, unsigned int intsize,
-			    unsigned long *out_hwirq, unsigned int *out_type)
+/**
+ * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
+ * @domain: domain owning this hardware interrupt
+ * @virq: linux irq number
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is for use by irq controllers that use a radix tree reverse
+ * mapping for fast lookup.
+ */
+void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
+			     irq_hw_number_t hwirq)
 {
-	if (d->of_node != controller)
-		return -EINVAL;
-	if (intsize < 1)
-		return -EINVAL;
-	if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
-	    (intspec[0] >= d->hwirq_base + d->nr_irq)))
-		return -EINVAL;
+	struct irq_data *irq_data = irq_get_irq_data(virq);
+
+	if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+		return;
+
+	if (virq) {
+		mutex_lock(&revmap_trees_mutex);
+		radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
+		mutex_unlock(&revmap_trees_mutex);
+	}
+}
+
+/**
+ * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is a fast path, for use by irq controller code that uses linear
+ * revmaps. It does fallback to the slow path if the revmap doesn't exist
+ * yet and will create the revmap entry with appropriate locking
+ */
+unsigned int irq_linear_revmap(struct irq_domain *domain,
+			       irq_hw_number_t hwirq)
+{
+	unsigned int *revmap;
+
+	if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
+		return irq_find_mapping(domain, hwirq);
+
+	/* Check revmap bounds */
+	if (unlikely(hwirq >= domain->revmap_data.linear.size))
+		return irq_find_mapping(domain, hwirq);
+
+	/* Check if revmap was allocated */
+	revmap = domain->revmap_data.linear.revmap;
+	if (unlikely(revmap == NULL))
+		return irq_find_mapping(domain, hwirq);
+
+	/* Fill up revmap with slow path if no mapping found */
+	if (unlikely(!revmap[hwirq]))
+		revmap[hwirq] = irq_find_mapping(domain, hwirq);
+
+	return revmap[hwirq];
+}
+
+#ifdef CONFIG_VIRQ_DEBUG
+static int virq_debug_show(struct seq_file *m, void *private)
+{
+	unsigned long flags;
+	struct irq_desc *desc;
+	const char *p;
+	static const char none[] = "none";
+	void *data;
+	int i;
+
+	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
+		      "chip name", "chip data", "domain name");
+
+	for (i = 1; i < nr_irqs; i++) {
+		desc = irq_to_desc(i);
+		if (!desc)
+			continue;
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
+
+		if (desc->action && desc->action->handler) {
+			struct irq_chip *chip;
+
+			seq_printf(m, "%5d  ", i);
+			seq_printf(m, "0x%05lx  ", desc->irq_data.hwirq);
+
+			chip = irq_desc_get_chip(desc);
+			if (chip && chip->name)
+				p = chip->name;
+			else
+				p = none;
+			seq_printf(m, "%-15s  ", p);
+
+			data = irq_desc_get_chip_data(desc);
+			seq_printf(m, "0x%16p  ", data);
+
+			if (desc->irq_data.domain->of_node)
+				p = desc->irq_data.domain->of_node->full_name;
+			else
+				p = none;
+			seq_printf(m, "%s\n", p);
+		}
+
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+	}
+
+	return 0;
+}
 
+static int virq_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, virq_debug_show, inode->i_private);
+}
+
+static const struct file_operations virq_debug_fops = {
+	.open = virq_debug_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int __init irq_debugfs_init(void)
+{
+	if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
+				 NULL, &virq_debug_fops) == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+__initcall(irq_debugfs_init);
+#endif /* CONFIG_VIRQ_DEBUG */
+
+int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
+			  irq_hw_number_t hwirq)
+{
+	return 0;
+}
+
+/**
+ * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with one cell
+ * bindings where the cell value maps directly to the hwirq number.
+ */
+int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
+			     const u32 *intspec, unsigned int intsize,
+			     unsigned long *out_hwirq, unsigned int *out_type)
+{
+	if (WARN_ON(intsize < 1))
+		return -EINVAL;
 	*out_hwirq = intspec[0];
 	*out_type = IRQ_TYPE_NONE;
-	if (intsize > 1)
-		*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell);
 
 /**
- * irq_domain_create_simple() - Set up a 'simple' translation range
+ * irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with two cell
+ * bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
  */
-void irq_domain_add_simple(struct device_node *controller, int irq_base)
+int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
+			const u32 *intspec, unsigned int intsize,
+			irq_hw_number_t *out_hwirq, unsigned int *out_type)
 {
-	struct irq_domain *domain;
-
-	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
-	if (!domain) {
-		WARN_ON(1);
-		return;
-	}
+	if (WARN_ON(intsize < 2))
+		return -EINVAL;
+	*out_hwirq = intspec[0];
+	*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
 
-	domain->irq_base = irq_base;
-	domain->of_node = of_node_get(controller);
-	domain->ops = &irq_domain_simple_ops;
-	irq_domain_add(domain);
+/**
+ * irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with either one
+ * or two cell bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
+ *
+ * Note: don't use this function unless your interrupt controller explicitly
+ * supports both one and two cell bindings.  For the majority of controllers
+ * the _onecell() or _twocell() variants above should be used.
+ */
+int irq_domain_xlate_onetwocell(struct irq_domain *d,
+				struct device_node *ctrlr,
+				const u32 *intspec, unsigned int intsize,
+				unsigned long *out_hwirq, unsigned int *out_type)
+{
+	if (WARN_ON(intsize < 1))
+		return -EINVAL;
+	*out_hwirq = intspec[0];
+	*out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE;
+	return 0;
 }
-EXPORT_SYMBOL_GPL(irq_domain_add_simple);
+EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell);
 
+const struct irq_domain_ops irq_domain_simple_ops = {
+	.map = irq_domain_simple_map,
+	.xlate = irq_domain_xlate_onetwocell,
+};
+EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+
+#ifdef CONFIG_OF_IRQ
 void irq_domain_generate_simple(const struct of_device_id *match,
 				u64 phys_base, unsigned int irq_start)
 {
 	struct device_node *node;
-	pr_info("looking for phys_base=%llx, irq_start=%i\n",
+	pr_debug("looking for phys_base=%llx, irq_start=%i\n",
 		(unsigned long long) phys_base, (int) irq_start);
 	node = of_find_matching_node_by_address(NULL, match, phys_base);
 	if (node)
-		irq_domain_add_simple(node, irq_start);
-	else
-		pr_info("no node found\n");
+		irq_domain_add_legacy(node, 32, irq_start, 0,
+				      &irq_domain_simple_ops, NULL);
 }
 EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
-#endif /* CONFIG_OF_IRQ */
-
-struct irq_domain_ops irq_domain_simple_ops = {
-#ifdef CONFIG_OF_IRQ
-	.dt_translate = irq_domain_simple_dt_translate,
-#endif /* CONFIG_OF_IRQ */
-};
-EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+#endif
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a9a9dbe..93d3079 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1026,9 +1026,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		if (new->flags & IRQF_ONESHOT)
 			desc->istate |= IRQS_ONESHOT;
 
-		if (irq_settings_can_autoenable(desc))
+		if (irq_settings_can_autoenable(desc)) {
 			irq_startup(desc);
-		else
+			check_irq_resend(desc, irq);
+		} else
 			/* Undo nested disables: */
 			desc->depth = 1;
 
diff --git a/kernel/kcmp.c b/kernel/kcmp.c
new file mode 100644
index 0000000..69f9362
--- /dev/null
+++ b/kernel/kcmp.c
@@ -0,0 +1,187 @@
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+#include <linux/fdtable.h>
+#include <linux/string.h>
+#include <linux/random.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/cache.h>
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/kcmp.h>
+
+#include <asm/unistd.h>
+
+/*
+ * We don't expose real in-memory order of objects for security
+ * reasons, still the comparison results should be suitable for
+ * sorting. Thus, we obfuscate kernel pointers values and compare
+ * the production instead.
+ */
+static unsigned long cookies[KCMP_TYPES][2] __read_mostly;
+
+static long kptr_obfuscate(long v, int type)
+{
+	return (v ^ cookies[type][0]) * cookies[type][1];
+}
+
+/*
+ * 0 - equal, i.e. v1 = v2
+ * 1 - less than, i.e. v1 < v2
+ * 2 - greater than, i.e. v1 > v2
+ * 3 - not equal but ordering unavailable (reserved for future)
+ */
+static int kcmp_ptr(void *v1, void *v2, enum kcmp_type type)
+{
+	long ret;
+
+	ret = kptr_obfuscate((long)v1, type) - kptr_obfuscate((long)v2, type);
+
+	return (ret < 0) | ((ret > 0) << 1);
+}
+
+/* The caller must have pinned the task */
+static struct file *
+get_file_raw_ptr(struct task_struct *task, unsigned int idx)
+{
+	struct file *file = NULL;
+
+	task_lock(task);
+	rcu_read_lock();
+
+	if (task->files)
+		file = fcheck_files(task->files, idx);
+
+	rcu_read_unlock();
+	task_unlock(task);
+
+	return file;
+}
+
+static void kcmp_unlock(struct mutex *m1, struct mutex *m2)
+{
+	if (likely(m2 != m1))
+		mutex_unlock(m2);
+	mutex_unlock(m1);
+}
+
+static int kcmp_lock(struct mutex *m1, struct mutex *m2)
+{
+	int err;
+
+	if (m2 > m1)
+		swap(m1, m2);
+
+	err = mutex_lock_killable(m1);
+	if (!err && likely(m1 != m2)) {
+		err = mutex_lock_killable_nested(m2, SINGLE_DEPTH_NESTING);
+		if (err)
+			mutex_unlock(m1);
+	}
+
+	return err;
+}
+
+SYSCALL_DEFINE5(kcmp, pid_t, pid1, pid_t, pid2, int, type,
+		unsigned long, idx1, unsigned long, idx2)
+{
+	struct task_struct *task1, *task2;
+	int ret;
+
+	rcu_read_lock();
+
+	/*
+	 * Tasks are looked up in caller's PID namespace only.
+	 */
+	task1 = find_task_by_vpid(pid1);
+	task2 = find_task_by_vpid(pid2);
+	if (!task1 || !task2)
+		goto err_no_task;
+
+	get_task_struct(task1);
+	get_task_struct(task2);
+
+	rcu_read_unlock();
+
+	/*
+	 * One should have enough rights to inspect task details.
+	 */
+	ret = kcmp_lock(&task1->signal->cred_guard_mutex,
+			&task2->signal->cred_guard_mutex);
+	if (ret)
+		goto err;
+	if (!ptrace_may_access(task1, PTRACE_MODE_READ) ||
+	    !ptrace_may_access(task2, PTRACE_MODE_READ)) {
+		ret = -EPERM;
+		goto err_unlock;
+	}
+
+	switch (type) {
+	case KCMP_FILE: {
+		struct file *filp1, *filp2;
+
+		filp1 = get_file_raw_ptr(task1, idx1);
+		filp2 = get_file_raw_ptr(task2, idx2);
+
+		if (filp1 && filp2)
+			ret = kcmp_ptr(filp1, filp2, KCMP_FILE);
+		else
+			ret = -EBADF;
+		break;
+	}
+	case KCMP_VM:
+		ret = kcmp_ptr(task1->mm, task2->mm, KCMP_VM);
+		break;
+	case KCMP_FILES:
+		ret = kcmp_ptr(task1->files, task2->files, KCMP_FILES);
+		break;
+	case KCMP_FS:
+		ret = kcmp_ptr(task1->fs, task2->fs, KCMP_FS);
+		break;
+	case KCMP_SIGHAND:
+		ret = kcmp_ptr(task1->sighand, task2->sighand, KCMP_SIGHAND);
+		break;
+	case KCMP_IO:
+		ret = kcmp_ptr(task1->io_context, task2->io_context, KCMP_IO);
+		break;
+	case KCMP_SYSVSEM:
+#ifdef CONFIG_SYSVIPC
+		ret = kcmp_ptr(task1->sysvsem.undo_list,
+			       task2->sysvsem.undo_list,
+			       KCMP_SYSVSEM);
+#else
+		ret = -EOPNOTSUP;
+#endif
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+err_unlock:
+	kcmp_unlock(&task1->signal->cred_guard_mutex,
+		    &task2->signal->cred_guard_mutex);
+err:
+	put_task_struct(task1);
+	put_task_struct(task2);
+
+	return ret;
+
+err_no_task:
+	rcu_read_unlock();
+	return -ESRCH;
+}
+
+static __init int kcmp_cookies_init(void)
+{
+	int i;
+
+	get_random_bytes(cookies, sizeof(cookies));
+
+	for (i = 0; i < KCMP_TYPES; i++)
+		cookies[i][1] |= (~(~0UL >>  1) | 1);
+
+	return 0;
+}
+arch_initcall(kcmp_cookies_init);
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 7b08867..a6a675c 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1546,13 +1546,13 @@ int kernel_kexec(void)
 		if (error)
 			goto Resume_console;
 		/* At this point, dpm_suspend_start() has been called,
-		 * but *not* dpm_suspend_noirq(). We *must* call
-		 * dpm_suspend_noirq() now.  Otherwise, drivers for
+		 * but *not* dpm_suspend_end(). We *must* call
+		 * dpm_suspend_end() now.  Otherwise, drivers for
 		 * some devices (e.g. interrupt controllers) become
 		 * desynchronized with the actual state of the
 		 * hardware at resume time, and evil weirdness ensues.
 		 */
-		error = dpm_suspend_noirq(PMSG_FREEZE);
+		error = dpm_suspend_end(PMSG_FREEZE);
 		if (error)
 			goto Resume_devices;
 		error = disable_nonboot_cpus();
@@ -1579,7 +1579,7 @@ int kernel_kexec(void)
 		local_irq_enable();
  Enable_cpus:
 		enable_nonboot_cpus();
-		dpm_resume_noirq(PMSG_RESTORE);
+		dpm_resume_start(PMSG_RESTORE);
  Resume_devices:
 		dpm_resume_end(PMSG_RESTORE);
  Resume_console:
diff --git a/kernel/kmod.c b/kernel/kmod.c
index a0a8854..9faa560 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -45,6 +45,13 @@ extern int max_threads;
 
 static struct workqueue_struct *khelper_wq;
 
+/*
+ * kmod_thread_locker is used for deadlock avoidance.  There is no explicit
+ * locking to protect this global - it is private to the singleton khelper
+ * thread and should only ever be modified by that thread.
+ */
+static const struct task_struct *kmod_thread_locker;
+
 #define CAP_BSET	(void *)1
 #define CAP_PI		(void *)2
 
@@ -60,6 +67,43 @@ static DECLARE_RWSEM(umhelper_sem);
 */
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
 
+static void free_modprobe_argv(struct subprocess_info *info)
+{
+	kfree(info->argv[3]); /* check call_modprobe() */
+	kfree(info->argv);
+}
+
+static int call_modprobe(char *module_name, int wait)
+{
+	static char *envp[] = {
+		"HOME=/",
+		"TERM=linux",
+		"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+		NULL
+	};
+
+	char **argv = kmalloc(sizeof(char *[5]), GFP_KERNEL);
+	if (!argv)
+		goto out;
+
+	module_name = kstrdup(module_name, GFP_KERNEL);
+	if (!module_name)
+		goto free_argv;
+
+	argv[0] = modprobe_path;
+	argv[1] = "-q";
+	argv[2] = "--";
+	argv[3] = module_name;	/* check free_modprobe_argv() */
+	argv[4] = NULL;
+
+	return call_usermodehelper_fns(modprobe_path, argv, envp,
+		wait | UMH_KILLABLE, NULL, free_modprobe_argv, NULL);
+free_argv:
+	kfree(argv);
+out:
+	return -ENOMEM;
+}
+
 /**
  * __request_module - try to load a kernel module
  * @wait: wait (or not) for the operation to complete
@@ -81,11 +125,6 @@ int __request_module(bool wait, const char *fmt, ...)
 	char module_name[MODULE_NAME_LEN];
 	unsigned int max_modprobes;
 	int ret;
-	char *argv[] = { modprobe_path, "-q", "--", module_name, NULL };
-	static char *envp[] = { "HOME=/",
-				"TERM=linux",
-				"PATH=/sbin:/usr/sbin:/bin:/usr/bin",
-				NULL };
 	static atomic_t kmod_concurrent = ATOMIC_INIT(0);
 #define MAX_KMOD_CONCURRENT 50	/* Completely arbitrary value - KAO */
 	static int kmod_loop_msg;
@@ -128,9 +167,7 @@ int __request_module(bool wait, const char *fmt, ...)
 
 	trace_module_request(module_name, wait, _RET_IP_);
 
-	ret = call_usermodehelper_fns(modprobe_path, argv, envp,
-			wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC,
-			NULL, NULL, NULL);
+	ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
 
 	atomic_dec(&kmod_concurrent);
 	return ret;
@@ -188,7 +225,14 @@ static int ____call_usermodehelper(void *data)
 	/* Exec failed? */
 fail:
 	sub_info->retval = retval;
-	do_exit(0);
+	return 0;
+}
+
+static int call_helper(void *data)
+{
+	/* Worker thread started blocking khelper thread. */
+	kmod_thread_locker = current;
+	return ____call_usermodehelper(data);
 }
 
 void call_usermodehelper_freeinfo(struct subprocess_info *info)
@@ -199,6 +243,19 @@ void call_usermodehelper_freeinfo(struct subprocess_info *info)
 }
 EXPORT_SYMBOL(call_usermodehelper_freeinfo);
 
+static void umh_complete(struct subprocess_info *sub_info)
+{
+	struct completion *comp = xchg(&sub_info->complete, NULL);
+	/*
+	 * See call_usermodehelper_exec(). If xchg() returns NULL
+	 * we own sub_info, the UMH_KILLABLE caller has gone away.
+	 */
+	if (comp)
+		complete(comp);
+	else
+		call_usermodehelper_freeinfo(sub_info);
+}
+
 /* Keventd can't block, but this (a child) can. */
 static int wait_for_helper(void *data)
 {
@@ -235,7 +292,7 @@ static int wait_for_helper(void *data)
 			sub_info->retval = ret;
 	}
 
-	complete(sub_info->complete);
+	umh_complete(sub_info);
 	return 0;
 }
 
@@ -244,7 +301,7 @@ static void __call_usermodehelper(struct work_struct *work)
 {
 	struct subprocess_info *sub_info =
 		container_of(work, struct subprocess_info, work);
-	enum umh_wait wait = sub_info->wait;
+	int wait = sub_info->wait & ~UMH_KILLABLE;
 	pid_t pid;
 
 	/* CLONE_VFORK: wait until the usermode helper has execve'd
@@ -253,9 +310,12 @@ static void __call_usermodehelper(struct work_struct *work)
 	if (wait == UMH_WAIT_PROC)
 		pid = kernel_thread(wait_for_helper, sub_info,
 				    CLONE_FS | CLONE_FILES | SIGCHLD);
-	else
-		pid = kernel_thread(____call_usermodehelper, sub_info,
+	else {
+		pid = kernel_thread(call_helper, sub_info,
 				    CLONE_VFORK | SIGCHLD);
+		/* Worker thread stopped blocking khelper thread. */
+		kmod_thread_locker = NULL;
+	}
 
 	switch (wait) {
 	case UMH_NO_WAIT:
@@ -269,7 +329,7 @@ static void __call_usermodehelper(struct work_struct *work)
 	case UMH_WAIT_EXEC:
 		if (pid < 0)
 			sub_info->retval = pid;
-		complete(sub_info->complete);
+		umh_complete(sub_info);
 	}
 }
 
@@ -435,8 +495,7 @@ EXPORT_SYMBOL(call_usermodehelper_setfns);
  * asynchronously if wait is not set, and runs as a child of keventd.
  * (ie. it runs with full root capabilities).
  */
-int call_usermodehelper_exec(struct subprocess_info *sub_info,
-			     enum umh_wait wait)
+int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 {
 	DECLARE_COMPLETION_ONSTACK(done);
 	int retval = 0;
@@ -449,6 +508,16 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
 		retval = -EBUSY;
 		goto out;
 	}
+	/*
+	 * Worker thread must not wait for khelper thread at below
+	 * wait_for_completion() if the thread was created with CLONE_VFORK
+	 * flag, for khelper thread is already waiting for the thread at
+	 * wait_for_completion() in do_fork().
+	 */
+	if (wait != UMH_NO_WAIT && current == kmod_thread_locker) {
+		retval = -EBUSY;
+		goto out;
+	}
 
 	sub_info->complete = &done;
 	sub_info->wait = wait;
@@ -456,9 +525,21 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
 	queue_work(khelper_wq, &sub_info->work);
 	if (wait == UMH_NO_WAIT)	/* task has freed sub_info */
 		goto unlock;
+
+	if (wait & UMH_KILLABLE) {
+		retval = wait_for_completion_killable(&done);
+		if (!retval)
+			goto wait_done;
+
+		/* umh_complete() will see NULL and free sub_info */
+		if (xchg(&sub_info->complete, NULL))
+			goto unlock;
+		/* fallthrough, umh_complete() was already called */
+	}
+
 	wait_for_completion(&done);
+wait_done:
 	retval = sub_info->retval;
-
 out:
 	call_usermodehelper_freeinfo(sub_info);
 unlock:
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 9788c0e..c62b854 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1334,8 +1334,10 @@ int __kprobes register_kprobe(struct kprobe *p)
 	if (!kernel_text_address((unsigned long) p->addr) ||
 	    in_kprobes_functions((unsigned long) p->addr) ||
 	    ftrace_text_reserved(p->addr, p->addr) ||
-	    jump_label_text_reserved(p->addr, p->addr))
-		goto fail_with_jump_label;
+	    jump_label_text_reserved(p->addr, p->addr)) {
+		ret = -EINVAL;
+		goto cannot_probe;
+	}
 
 	/* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
 	p->flags &= KPROBE_FLAG_DISABLED;
@@ -1352,7 +1354,7 @@ int __kprobes register_kprobe(struct kprobe *p)
 		 * its code to prohibit unexpected unloading.
 		 */
 		if (unlikely(!try_module_get(probed_mod)))
-			goto fail_with_jump_label;
+			goto cannot_probe;
 
 		/*
 		 * If the module freed .init.text, we couldn't insert
@@ -1361,7 +1363,7 @@ int __kprobes register_kprobe(struct kprobe *p)
 		if (within_module_init((unsigned long)p->addr, probed_mod) &&
 		    probed_mod->state != MODULE_STATE_COMING) {
 			module_put(probed_mod);
-			goto fail_with_jump_label;
+			goto cannot_probe;
 		}
 		/* ret will be updated by following code */
 	}
@@ -1409,7 +1411,7 @@ out:
 
 	return ret;
 
-fail_with_jump_label:
+cannot_probe:
 	preempt_enable();
 	jump_label_unlock();
 	return ret;
diff --git a/kernel/lglock.c b/kernel/lglock.c
new file mode 100644
index 0000000..c6e6f09
--- /dev/null
+++ b/kernel/lglock.c
@@ -0,0 +1,136 @@
+/* See include/linux/lglock.h for description */
+#include <linux/module.h>
+#include <linux/lglock.h>
+#include <linux/cpu.h>
+#include <linux/string.h>
+
+/* Note there is no uninit, so lglocks cannot be defined in
+ * modules (but it's fine to use them from there)
+ * Could be added though, just undo lg_lock_init
+ */
+
+void lg_lock_init(struct lglock *lg, char *name)
+{
+	int i;
+
+	LOCKDEP_INIT_MAP(&lg->lock_dep_map, name, &lg->lock_key, 0);
+
+	register_hotcpu_notifier(&lg->cpu_notifier);
+	get_online_cpus();
+	for_each_online_cpu (i)
+		cpu_set(i, lg->cpus);
+	put_online_cpus();
+}
+EXPORT_SYMBOL(lg_lock_init);
+
+void lg_local_lock(struct lglock *lg)
+{
+	arch_spinlock_t *lock;
+	preempt_disable();
+	rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	lock = this_cpu_ptr(lg->lock);
+	arch_spin_lock(lock);
+}
+EXPORT_SYMBOL(lg_local_lock);
+
+void lg_local_unlock(struct lglock *lg)
+{
+	arch_spinlock_t *lock;
+	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	lock = this_cpu_ptr(lg->lock);
+	arch_spin_unlock(lock);
+	preempt_enable();
+}
+EXPORT_SYMBOL(lg_local_unlock);
+
+void lg_local_lock_cpu(struct lglock *lg, int cpu)
+{
+	arch_spinlock_t *lock;
+	preempt_disable();
+	rwlock_acquire_read(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	lock = per_cpu_ptr(lg->lock, cpu);
+	arch_spin_lock(lock);
+}
+EXPORT_SYMBOL(lg_local_lock_cpu);
+
+void lg_local_unlock_cpu(struct lglock *lg, int cpu)
+{
+	arch_spinlock_t *lock;
+	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	lock = per_cpu_ptr(lg->lock, cpu);
+	arch_spin_unlock(lock);
+	preempt_enable();
+}
+EXPORT_SYMBOL(lg_local_unlock_cpu);
+
+void lg_global_lock_online(struct lglock *lg)
+{
+	int i;
+	spin_lock(&lg->cpu_lock);
+	rwlock_acquire(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	for_each_cpu(i, &lg->cpus) {
+		arch_spinlock_t *lock;
+		lock = per_cpu_ptr(lg->lock, i);
+		arch_spin_lock(lock);
+	}
+}
+EXPORT_SYMBOL(lg_global_lock_online);
+
+void lg_global_unlock_online(struct lglock *lg)
+{
+	int i;
+	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	for_each_cpu(i, &lg->cpus) {
+		arch_spinlock_t *lock;
+		lock = per_cpu_ptr(lg->lock, i);
+		arch_spin_unlock(lock);
+	}
+	spin_unlock(&lg->cpu_lock);
+}
+EXPORT_SYMBOL(lg_global_unlock_online);
+
+void lg_global_lock(struct lglock *lg)
+{
+	int i;
+	preempt_disable();
+	rwlock_acquire(&lg->lock_dep_map, 0, 0, _RET_IP_);
+	for_each_possible_cpu(i) {
+		arch_spinlock_t *lock;
+		lock = per_cpu_ptr(lg->lock, i);
+		arch_spin_lock(lock);
+	}
+}
+EXPORT_SYMBOL(lg_global_lock);
+
+void lg_global_unlock(struct lglock *lg)
+{
+	int i;
+	rwlock_release(&lg->lock_dep_map, 1, _RET_IP_);
+	for_each_possible_cpu(i) {
+		arch_spinlock_t *lock;
+		lock = per_cpu_ptr(lg->lock, i);
+		arch_spin_unlock(lock);
+	}
+	preempt_enable();
+}
+EXPORT_SYMBOL(lg_global_unlock);
+
+int lg_cpu_callback(struct notifier_block *nb,
+                              unsigned long action, void *hcpu)
+{
+	struct lglock *lglock = container_of(nb, struct lglock, cpu_notifier);
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_UP_PREPARE:
+		spin_lock(&lglock->cpu_lock);
+		cpu_set((unsigned long)hcpu, lglock->cpus);
+		spin_unlock(&lglock->cpu_lock);
+		break;
+	case CPU_UP_CANCELED: case CPU_DEAD:
+		spin_lock(&lglock->cpu_lock);
+		cpu_clear((unsigned long)hcpu, lglock->cpus);
+		spin_unlock(&lglock->cpu_lock);
+	}
+	return NOTIFY_OK;
+}
+EXPORT_SYMBOL(lg_cpu_callback);
+
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 8889f7d..ea9ee45 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -4176,7 +4176,13 @@ void lockdep_rcu_suspicious(const char *file, const int line, const char *s)
 	printk("-------------------------------\n");
 	printk("%s:%d %s!\n", file, line, s);
 	printk("\nother info that might help us debug this:\n\n");
-	printk("\nrcu_scheduler_active = %d, debug_locks = %d\n", rcu_scheduler_active, debug_locks);
+	printk("\n%srcu_scheduler_active = %d, debug_locks = %d\n",
+	       !rcu_lockdep_current_cpu_online()
+			? "RCU used illegally from offline CPU!\n"
+			: rcu_is_cpu_idle()
+				? "RCU used illegally from idle CPU!\n"
+				: "",
+	       rcu_scheduler_active, debug_locks);
 
 	/*
 	 * If a CPU is in the RCU-free window in idle (ie: in the section
diff --git a/kernel/module.c b/kernel/module.c
index 2c93276..78ac6ec 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -105,6 +105,7 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
 
 /* Block module loading/unloading? */
 int modules_disabled = 0;
+core_param(nomodule, modules_disabled, bint, 0);
 
 /* Waiting for a module to finish initializing? */
 static DECLARE_WAIT_QUEUE_HEAD(module_wq);
@@ -903,6 +904,36 @@ static ssize_t show_refcnt(struct module_attribute *mattr,
 static struct module_attribute modinfo_refcnt =
 	__ATTR(refcnt, 0444, show_refcnt, NULL);
 
+void __module_get(struct module *module)
+{
+	if (module) {
+		preempt_disable();
+		__this_cpu_inc(module->refptr->incs);
+		trace_module_get(module, _RET_IP_);
+		preempt_enable();
+	}
+}
+EXPORT_SYMBOL(__module_get);
+
+bool try_module_get(struct module *module)
+{
+	bool ret = true;
+
+	if (module) {
+		preempt_disable();
+
+		if (likely(module_is_live(module))) {
+			__this_cpu_inc(module->refptr->incs);
+			trace_module_get(module, _RET_IP_);
+		} else
+			ret = false;
+
+		preempt_enable();
+	}
+	return ret;
+}
+EXPORT_SYMBOL(try_module_get);
+
 void module_put(struct module *module)
 {
 	if (module) {
@@ -2380,8 +2411,7 @@ static int copy_and_check(struct load_info *info,
 		return -ENOEXEC;
 
 	/* Suck in entire file: we'll want most of it. */
-	/* vmalloc barfs on "unusual" numbers.  Check here */
-	if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
+	if ((hdr = vmalloc(len)) == NULL)
 		return -ENOMEM;
 
 	if (copy_from_user(hdr, umod, len) != 0) {
@@ -2922,7 +2952,8 @@ static struct module *load_module(void __user *umod,
 	mutex_unlock(&module_mutex);
 
 	/* Module is ready to execute: parsing args may do that. */
-	err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
+	err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
+			 -32768, 32767, NULL);
 	if (err < 0)
 		goto unlink;
 
diff --git a/kernel/params.c b/kernel/params.c
index 4bc965d..f055afff 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -88,6 +88,8 @@ static int parse_one(char *param,
 		     char *val,
 		     const struct kernel_param *params,
 		     unsigned num_params,
+		     s16 min_level,
+		     s16 max_level,
 		     int (*handle_unknown)(char *param, char *val))
 {
 	unsigned int i;
@@ -96,6 +98,9 @@ static int parse_one(char *param,
 	/* Find parameter */
 	for (i = 0; i < num_params; i++) {
 		if (parameq(param, params[i].name)) {
+			if (params[i].level < min_level
+			    || params[i].level > max_level)
+				return 0;
 			/* No one handled NULL, so do it here. */
 			if (!val && params[i].ops->set != param_set_bool
 			    && params[i].ops->set != param_set_bint)
@@ -175,6 +180,8 @@ int parse_args(const char *name,
 	       char *args,
 	       const struct kernel_param *params,
 	       unsigned num,
+	       s16 min_level,
+	       s16 max_level,
 	       int (*unknown)(char *param, char *val))
 {
 	char *param, *val;
@@ -190,7 +197,8 @@ int parse_args(const char *name,
 
 		args = next_arg(args, &param, &val);
 		irq_was_disabled = irqs_disabled();
-		ret = parse_one(param, val, params, num, unknown);
+		ret = parse_one(param, val, params, num,
+				min_level, max_level, unknown);
 		if (irq_was_disabled && !irqs_disabled()) {
 			printk(KERN_WARNING "parse_args(): option '%s' enabled "
 					"irq's!\n", param);
@@ -298,35 +306,18 @@ EXPORT_SYMBOL(param_ops_charp);
 /* Actually could be a bool or an int, for historical reasons. */
 int param_set_bool(const char *val, const struct kernel_param *kp)
 {
-	bool v;
-	int ret;
-
 	/* No equals means "set"... */
 	if (!val) val = "1";
 
 	/* One of =[yYnN01] */
-	ret = strtobool(val, &v);
-	if (ret)
-		return ret;
-
-	if (kp->flags & KPARAM_ISBOOL)
-		*(bool *)kp->arg = v;
-	else
-		*(int *)kp->arg = v;
-	return 0;
+	return strtobool(val, kp->arg);
 }
 EXPORT_SYMBOL(param_set_bool);
 
 int param_get_bool(char *buffer, const struct kernel_param *kp)
 {
-	bool val;
-	if (kp->flags & KPARAM_ISBOOL)
-		val = *(bool *)kp->arg;
-	else
-		val = *(int *)kp->arg;
-
 	/* Y and N chosen as being relatively non-coder friendly */
-	return sprintf(buffer, "%c", val ? 'Y' : 'N');
+	return sprintf(buffer, "%c", *(bool *)kp->arg ? 'Y' : 'N');
 }
 EXPORT_SYMBOL(param_get_bool);
 
@@ -344,7 +335,6 @@ int param_set_invbool(const char *val, const struct kernel_param *kp)
 	struct kernel_param dummy;
 
 	dummy.arg = &boolval;
-	dummy.flags = KPARAM_ISBOOL;
 	ret = param_set_bool(val, &dummy);
 	if (ret == 0)
 		*(bool *)kp->arg = !boolval;
@@ -373,7 +363,6 @@ int param_set_bint(const char *val, const struct kernel_param *kp)
 	/* Match bool exactly, by re-using it. */
 	boolkp = *kp;
 	boolkp.arg = &v;
-	boolkp.flags |= KPARAM_ISBOOL;
 
 	ret = param_set_bool(val, &boolkp);
 	if (ret == 0)
@@ -394,7 +383,7 @@ static int param_array(const char *name,
 		       unsigned int min, unsigned int max,
 		       void *elem, int elemsize,
 		       int (*set)(const char *, const struct kernel_param *kp),
-		       u16 flags,
+		       s16 level,
 		       unsigned int *num)
 {
 	int ret;
@@ -404,7 +393,7 @@ static int param_array(const char *name,
 	/* Get the name right for errors. */
 	kp.name = name;
 	kp.arg = elem;
-	kp.flags = flags;
+	kp.level = level;
 
 	*num = 0;
 	/* We expect a comma-separated list of values. */
@@ -445,7 +434,7 @@ static int param_array_set(const char *val, const struct kernel_param *kp)
 	unsigned int temp_num;
 
 	return param_array(kp->name, val, 1, arr->max, arr->elem,
-			   arr->elemsize, arr->ops->set, kp->flags,
+			   arr->elemsize, arr->ops->set, kp->level,
 			   arr->num ?: &temp_num);
 }
 
diff --git a/kernel/pid.c b/kernel/pid.c
index ce8e00d..9f08dfa 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -543,12 +543,12 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
  */
 void __init pidhash_init(void)
 {
-	int i, pidhash_size;
+	unsigned int i, pidhash_size;
 
 	pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,
 					   HASH_EARLY | HASH_SMALL,
 					   &pidhash_shift, NULL, 4096);
-	pidhash_size = 1 << pidhash_shift;
+	pidhash_size = 1U << pidhash_shift;
 
 	for (i = 0; i < pidhash_size; i++)
 		INIT_HLIST_HEAD(&pid_hash[i]);
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index a896839..ab0bfa9 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -15,6 +15,7 @@
 #include <linux/acct.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/reboot.h>
 
 #define BITS_PER_PAGE		(PAGE_SIZE*8)
 
@@ -168,13 +169,9 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
 	while (nr > 0) {
 		rcu_read_lock();
 
-		/*
-		 * Any nested-container's init processes won't ignore the
-		 * SEND_SIG_NOINFO signal, see send_signal()->si_fromuser().
-		 */
 		task = pid_task(find_vpid(nr), PIDTYPE_PID);
-		if (task)
-			send_sig_info(SIGKILL, SEND_SIG_NOINFO, task);
+		if (task && !__fatal_signal_pending(task))
+			send_sig_info(SIGKILL, SEND_SIG_FORCED, task);
 
 		rcu_read_unlock();
 
@@ -187,10 +184,14 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
 		rc = sys_wait4(-1, NULL, __WALL, NULL);
 	} while (rc != -ECHILD);
 
+	if (pid_ns->reboot)
+		current->signal->group_exit_code = pid_ns->reboot;
+
 	acct_exit_ns(pid_ns);
 	return;
 }
 
+#ifdef CONFIG_CHECKPOINT_RESTORE
 static int pid_ns_ctl_handler(struct ctl_table *table, int write,
 		void __user *buffer, size_t *lenp, loff_t *ppos)
 {
@@ -218,13 +219,45 @@ static struct ctl_table pid_ns_ctl_table[] = {
 	},
 	{ }
 };
-
 static struct ctl_path kern_path[] = { { .procname = "kernel", }, { } };
+#endif	/* CONFIG_CHECKPOINT_RESTORE */
+
+int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd)
+{
+	if (pid_ns == &init_pid_ns)
+		return 0;
+
+	switch (cmd) {
+	case LINUX_REBOOT_CMD_RESTART2:
+	case LINUX_REBOOT_CMD_RESTART:
+		pid_ns->reboot = SIGHUP;
+		break;
+
+	case LINUX_REBOOT_CMD_POWER_OFF:
+	case LINUX_REBOOT_CMD_HALT:
+		pid_ns->reboot = SIGINT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	read_lock(&tasklist_lock);
+	force_sig(SIGKILL, pid_ns->child_reaper);
+	read_unlock(&tasklist_lock);
+
+	do_exit(0);
+
+	/* Not reached */
+	return 0;
+}
 
 static __init int pid_namespaces_init(void)
 {
 	pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);
+
+#ifdef CONFIG_CHECKPOINT_RESTORE
 	register_sysctl_paths(kern_path, pid_ns_ctl_table);
+#endif
 	return 0;
 }
 
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 07e0e28..66d808e 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -1,7 +1,8 @@
 
 ccflags-$(CONFIG_PM_DEBUG)	:= -DDEBUG
 
-obj-$(CONFIG_PM)		+= main.o qos.o
+obj-y				+= qos.o
+obj-$(CONFIG_PM)		+= main.o
 obj-$(CONFIG_VT_CONSOLE_SLEEP)	+= console.o
 obj-$(CONFIG_FREEZER)		+= process.o
 obj-$(CONFIG_SUSPEND)		+= suspend.o
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 6d6d288..0a186cf 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -245,8 +245,8 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop,
  * create_image - Create a hibernation image.
  * @platform_mode: Whether or not to use the platform driver.
  *
- * Execute device drivers' .freeze_noirq() callbacks, create a hibernation image
- * and execute the drivers' .thaw_noirq() callbacks.
+ * Execute device drivers' "late" and "noirq" freeze callbacks, create a
+ * hibernation image and run the drivers' "noirq" and "early" thaw callbacks.
  *
  * Control reappears in this routine after the subsequent restore.
  */
@@ -254,7 +254,7 @@ static int create_image(int platform_mode)
 {
 	int error;
 
-	error = dpm_suspend_noirq(PMSG_FREEZE);
+	error = dpm_suspend_end(PMSG_FREEZE);
 	if (error) {
 		printk(KERN_ERR "PM: Some devices failed to power down, "
 			"aborting hibernation\n");
@@ -306,7 +306,7 @@ static int create_image(int platform_mode)
  Platform_finish:
 	platform_finish(platform_mode);
 
-	dpm_resume_noirq(in_suspend ?
+	dpm_resume_start(in_suspend ?
 		(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
 
 	return error;
@@ -343,13 +343,13 @@ int hibernation_snapshot(int platform_mode)
 		 * successful freezer test.
 		 */
 		freezer_test_done = true;
-		goto Cleanup;
+		goto Thaw;
 	}
 
 	error = dpm_prepare(PMSG_FREEZE);
 	if (error) {
 		dpm_complete(PMSG_RECOVER);
-		goto Cleanup;
+		goto Thaw;
 	}
 
 	suspend_console();
@@ -385,6 +385,8 @@ int hibernation_snapshot(int platform_mode)
 	platform_end(platform_mode);
 	return error;
 
+ Thaw:
+	thaw_kernel_threads();
  Cleanup:
 	swsusp_free();
 	goto Close;
@@ -394,16 +396,16 @@ int hibernation_snapshot(int platform_mode)
  * resume_target_kernel - Restore system state from a hibernation image.
  * @platform_mode: Whether or not to use the platform driver.
  *
- * Execute device drivers' .freeze_noirq() callbacks, restore the contents of
- * highmem that have not been restored yet from the image and run the low-level
- * code that will restore the remaining contents of memory and switch to the
- * just restored target kernel.
+ * Execute device drivers' "noirq" and "late" freeze callbacks, restore the
+ * contents of highmem that have not been restored yet from the image and run
+ * the low-level code that will restore the remaining contents of memory and
+ * switch to the just restored target kernel.
  */
 static int resume_target_kernel(bool platform_mode)
 {
 	int error;
 
-	error = dpm_suspend_noirq(PMSG_QUIESCE);
+	error = dpm_suspend_end(PMSG_QUIESCE);
 	if (error) {
 		printk(KERN_ERR "PM: Some devices failed to power down, "
 			"aborting resume\n");
@@ -460,7 +462,7 @@ static int resume_target_kernel(bool platform_mode)
  Cleanup:
 	platform_restore_cleanup(platform_mode);
 
-	dpm_resume_noirq(PMSG_RECOVER);
+	dpm_resume_start(PMSG_RECOVER);
 
 	return error;
 }
@@ -518,7 +520,7 @@ int hibernation_platform_enter(void)
 		goto Resume_devices;
 	}
 
-	error = dpm_suspend_noirq(PMSG_HIBERNATE);
+	error = dpm_suspend_end(PMSG_HIBERNATE);
 	if (error)
 		goto Resume_devices;
 
@@ -549,7 +551,7 @@ int hibernation_platform_enter(void)
  Platform_finish:
 	hibernation_ops->finish();
 
-	dpm_resume_noirq(PMSG_RESTORE);
+	dpm_resume_start(PMSG_RESTORE);
 
  Resume_devices:
 	entering_platform_hibernation = false;
@@ -616,7 +618,7 @@ int hibernate(void)
 	/* Allocate memory management structures */
 	error = create_basic_memory_bitmaps();
 	if (error)
-		goto Exit;
+		goto Enable_umh;
 
 	printk(KERN_INFO "PM: Syncing filesystems ... ");
 	sys_sync();
@@ -624,15 +626,11 @@ int hibernate(void)
 
 	error = freeze_processes();
 	if (error)
-		goto Finish;
+		goto Free_bitmaps;
 
 	error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
-	if (error)
-		goto Thaw;
-	if (freezer_test_done) {
-		freezer_test_done = false;
+	if (error || freezer_test_done)
 		goto Thaw;
-	}
 
 	if (in_suspend) {
 		unsigned int flags = 0;
@@ -657,8 +655,13 @@ int hibernate(void)
 
  Thaw:
 	thaw_processes();
- Finish:
+
+	/* Don't bother checking whether freezer_test_done is true */
+	freezer_test_done = false;
+
+ Free_bitmaps:
 	free_basic_memory_bitmaps();
+ Enable_umh:
 	usermodehelper_enable();
  Exit:
 	pm_notifier_call_chain(PM_POST_HIBERNATION);
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 9824b41e..1c12581 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -165,16 +165,20 @@ static int suspend_stats_show(struct seq_file *s, void *unused)
 	last_errno %= REC_FAILED_NUM;
 	last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1;
 	last_step %= REC_FAILED_NUM;
-	seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
-			"%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
+	seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
+			"%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n",
 			"success", suspend_stats.success,
 			"fail", suspend_stats.fail,
 			"failed_freeze", suspend_stats.failed_freeze,
 			"failed_prepare", suspend_stats.failed_prepare,
 			"failed_suspend", suspend_stats.failed_suspend,
+			"failed_suspend_late",
+				suspend_stats.failed_suspend_late,
 			"failed_suspend_noirq",
 				suspend_stats.failed_suspend_noirq,
 			"failed_resume", suspend_stats.failed_resume,
+			"failed_resume_early",
+				suspend_stats.failed_resume_early,
 			"failed_resume_noirq",
 				suspend_stats.failed_resume_noirq);
 	seq_printf(s,	"failures:\n  last_failed_dev:\t%-s\n",
@@ -287,16 +291,10 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
 
 #ifdef CONFIG_SUSPEND
 	for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) {
-		if (*s && len == strlen(*s) && !strncmp(buf, *s, len))
+		if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) {
+			error = pm_suspend(state);
 			break;
-	}
-	if (state < PM_SUSPEND_MAX && *s) {
-		error = enter_state(state);
-		if (error) {
-			suspend_stats.fail++;
-			dpm_save_failed_errno(error);
-		} else
-			suspend_stats.success++;
+		}
 	}
 #endif
 
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 21724ee..98f3622 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -177,13 +177,11 @@ extern const char *const pm_states[];
 
 extern bool valid_state(suspend_state_t state);
 extern int suspend_devices_and_enter(suspend_state_t state);
-extern int enter_state(suspend_state_t state);
 #else /* !CONFIG_SUSPEND */
 static inline int suspend_devices_and_enter(suspend_state_t state)
 {
 	return -ENOSYS;
 }
-static inline int enter_state(suspend_state_t state) { return -ENOSYS; }
 static inline bool valid_state(suspend_state_t state) { return false; }
 #endif /* !CONFIG_SUSPEND */
 
@@ -234,16 +232,14 @@ static inline int suspend_freeze_processes(void)
 	int error;
 
 	error = freeze_processes();
-
 	/*
 	 * freeze_processes() automatically thaws every task if freezing
 	 * fails. So we need not do anything extra upon error.
 	 */
 	if (error)
-		goto Finish;
+		return error;
 
 	error = freeze_kernel_threads();
-
 	/*
 	 * freeze_kernel_threads() thaws only kernel threads upon freezing
 	 * failure. So we have to thaw the userspace tasks ourselves.
@@ -251,7 +247,6 @@ static inline int suspend_freeze_processes(void)
 	if (error)
 		thaw_processes();
 
- Finish:
 	return error;
 }
 
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 7e42645..6aeb5ef 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -98,13 +98,15 @@ static int try_to_freeze_tasks(bool user_only)
 		       elapsed_csecs / 100, elapsed_csecs % 100,
 		       todo - wq_busy, wq_busy);
 
-		read_lock(&tasklist_lock);
-		do_each_thread(g, p) {
-			if (!wakeup && !freezer_should_skip(p) &&
-			    p != current && freezing(p) && !frozen(p))
-				sched_show_task(p);
-		} while_each_thread(g, p);
-		read_unlock(&tasklist_lock);
+		if (!wakeup) {
+			read_lock(&tasklist_lock);
+			do_each_thread(g, p) {
+				if (p != current && !freezer_should_skip(p)
+				    && freezing(p) && !frozen(p))
+					sched_show_task(p);
+			} while_each_thread(g, p);
+			read_unlock(&tasklist_lock);
+		}
 	} else {
 		printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
 			elapsed_csecs % 100);
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index 995e3bd..d6d6dbd 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -469,21 +469,18 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
 static int __init pm_qos_power_init(void)
 {
 	int ret = 0;
+	int i;
 
-	ret = register_pm_qos_misc(&cpu_dma_pm_qos);
-	if (ret < 0) {
-		printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n");
-		return ret;
-	}
-	ret = register_pm_qos_misc(&network_lat_pm_qos);
-	if (ret < 0) {
-		printk(KERN_ERR "pm_qos_param: network_latency setup failed\n");
-		return ret;
+	BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES);
+
+	for (i = 1; i < PM_QOS_NUM_CLASSES; i++) {
+		ret = register_pm_qos_misc(pm_qos_array[i]);
+		if (ret < 0) {
+			printk(KERN_ERR "pm_qos_param: %s setup failed\n",
+			       pm_qos_array[i]->name);
+			return ret;
+		}
 	}
-	ret = register_pm_qos_misc(&network_throughput_pm_qos);
-	if (ret < 0)
-		printk(KERN_ERR
-			"pm_qos_param: network_throughput setup failed\n");
 
 	return ret;
 }
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 6a768e5..0de2857 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -711,9 +711,10 @@ static void mark_nosave_pages(struct memory_bitmap *bm)
 	list_for_each_entry(region, &nosave_regions, list) {
 		unsigned long pfn;
 
-		pr_debug("PM: Marking nosave pages: %016lx - %016lx\n",
-				region->start_pfn << PAGE_SHIFT,
-				region->end_pfn << PAGE_SHIFT);
+		pr_debug("PM: Marking nosave pages: [mem %#010llx-%#010llx]\n",
+			 (unsigned long long) region->start_pfn << PAGE_SHIFT,
+			 ((unsigned long long) region->end_pfn << PAGE_SHIFT)
+				- 1);
 
 		for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++)
 			if (pfn_valid(pfn)) {
@@ -1000,20 +1001,20 @@ static void copy_data_page(unsigned long dst_pfn, unsigned long src_pfn)
 	s_page = pfn_to_page(src_pfn);
 	d_page = pfn_to_page(dst_pfn);
 	if (PageHighMem(s_page)) {
-		src = kmap_atomic(s_page, KM_USER0);
-		dst = kmap_atomic(d_page, KM_USER1);
+		src = kmap_atomic(s_page);
+		dst = kmap_atomic(d_page);
 		do_copy_page(dst, src);
-		kunmap_atomic(dst, KM_USER1);
-		kunmap_atomic(src, KM_USER0);
+		kunmap_atomic(dst);
+		kunmap_atomic(src);
 	} else {
 		if (PageHighMem(d_page)) {
 			/* Page pointed to by src may contain some kernel
 			 * data modified by kmap_atomic()
 			 */
 			safe_copy_page(buffer, s_page);
-			dst = kmap_atomic(d_page, KM_USER0);
+			dst = kmap_atomic(d_page);
 			copy_page(dst, buffer);
-			kunmap_atomic(dst, KM_USER0);
+			kunmap_atomic(dst);
 		} else {
 			safe_copy_page(page_address(d_page), s_page);
 		}
@@ -1728,9 +1729,9 @@ int snapshot_read_next(struct snapshot_handle *handle)
 			 */
 			void *kaddr;
 
-			kaddr = kmap_atomic(page, KM_USER0);
+			kaddr = kmap_atomic(page);
 			copy_page(buffer, kaddr);
-			kunmap_atomic(kaddr, KM_USER0);
+			kunmap_atomic(kaddr);
 			handle->buffer = buffer;
 		} else {
 			handle->buffer = page_address(page);
@@ -2014,9 +2015,9 @@ static void copy_last_highmem_page(void)
 	if (last_highmem_page) {
 		void *dst;
 
-		dst = kmap_atomic(last_highmem_page, KM_USER0);
+		dst = kmap_atomic(last_highmem_page);
 		copy_page(dst, buffer);
-		kunmap_atomic(dst, KM_USER0);
+		kunmap_atomic(dst);
 		last_highmem_page = NULL;
 	}
 }
@@ -2309,13 +2310,13 @@ swap_two_pages_data(struct page *p1, struct page *p2, void *buf)
 {
 	void *kaddr1, *kaddr2;
 
-	kaddr1 = kmap_atomic(p1, KM_USER0);
-	kaddr2 = kmap_atomic(p2, KM_USER1);
+	kaddr1 = kmap_atomic(p1);
+	kaddr2 = kmap_atomic(p2);
 	copy_page(buf, kaddr1);
 	copy_page(kaddr1, kaddr2);
 	copy_page(kaddr2, buf);
-	kunmap_atomic(kaddr2, KM_USER1);
-	kunmap_atomic(kaddr1, KM_USER0);
+	kunmap_atomic(kaddr2);
+	kunmap_atomic(kaddr1);
 }
 
 /**
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 4fd51be..88e5c96 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -37,8 +37,8 @@ const char *const pm_states[PM_SUSPEND_MAX] = {
 static const struct platform_suspend_ops *suspend_ops;
 
 /**
- *	suspend_set_ops - Set the global suspend method table.
- *	@ops:	Pointer to ops structure.
+ * suspend_set_ops - Set the global suspend method table.
+ * @ops: Suspend operations to use.
  */
 void suspend_set_ops(const struct platform_suspend_ops *ops)
 {
@@ -58,11 +58,11 @@ bool valid_state(suspend_state_t state)
 }
 
 /**
- * suspend_valid_only_mem - generic memory-only valid callback
+ * suspend_valid_only_mem - Generic memory-only valid callback.
  *
- * Platform drivers that implement mem suspend only and only need
- * to check for that in their .valid callback can use this instead
- * of rolling their own .valid callback.
+ * Platform drivers that implement mem suspend only and only need to check for
+ * that in their .valid() callback can use this instead of rolling their own
+ * .valid() callback.
  */
 int suspend_valid_only_mem(suspend_state_t state)
 {
@@ -83,10 +83,11 @@ static int suspend_test(int level)
 }
 
 /**
- *	suspend_prepare - Do prep work before entering low-power state.
+ * suspend_prepare - Prepare for entering system sleep state.
  *
- *	This is common code that is called for each state that we're entering.
- *	Run suspend notifiers, allocate a console and stop all processes.
+ * Common code run for every system sleep state that can be entered (except for
+ * hibernation).  Run suspend notifiers, allocate the "suspend" console and
+ * freeze processes.
  */
 static int suspend_prepare(void)
 {
@@ -131,9 +132,9 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void)
 }
 
 /**
- * suspend_enter - enter the desired system sleep state.
- * @state: State to enter
- * @wakeup: Returns information that suspend should not be entered again.
+ * suspend_enter - Make the system enter the given sleep state.
+ * @state: System sleep state to enter.
+ * @wakeup: Returns information that the sleep state should not be re-entered.
  *
  * This function should be called after devices have been suspended.
  */
@@ -147,7 +148,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
 			goto Platform_finish;
 	}
 
-	error = dpm_suspend_noirq(PMSG_SUSPEND);
+	error = dpm_suspend_end(PMSG_SUSPEND);
 	if (error) {
 		printk(KERN_ERR "PM: Some devices failed to power down\n");
 		goto Platform_finish;
@@ -189,7 +190,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
 	if (suspend_ops->wake)
 		suspend_ops->wake();
 
-	dpm_resume_noirq(PMSG_RESUME);
+	dpm_resume_start(PMSG_RESUME);
 
  Platform_finish:
 	if (suspend_ops->finish)
@@ -199,9 +200,8 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
 }
 
 /**
- *	suspend_devices_and_enter - suspend devices and enter the desired system
- *				    sleep state.
- *	@state:		  state to enter
+ * suspend_devices_and_enter - Suspend devices and enter system sleep state.
+ * @state: System sleep state to enter.
  */
 int suspend_devices_and_enter(suspend_state_t state)
 {
@@ -251,10 +251,10 @@ int suspend_devices_and_enter(suspend_state_t state)
 }
 
 /**
- *	suspend_finish - Do final work before exiting suspend sequence.
+ * suspend_finish - Clean up before finishing the suspend sequence.
  *
- *	Call platform code to clean up, restart processes, and free the
- *	console that we've allocated. This is not called for suspend-to-disk.
+ * Call platform code to clean up, restart processes, and free the console that
+ * we've allocated. This routine is not called for hibernation.
  */
 static void suspend_finish(void)
 {
@@ -265,16 +265,14 @@ static void suspend_finish(void)
 }
 
 /**
- *	enter_state - Do common work of entering low-power state.
- *	@state:		pm_state structure for state we're entering.
+ * enter_state - Do common work needed to enter system sleep state.
+ * @state: System sleep state to enter.
  *
- *	Make sure we're the only ones trying to enter a sleep state. Fail
- *	if someone has beat us to it, since we don't want anything weird to
- *	happen when we wake up.
- *	Then, do the setup for suspend, enter the state, and cleaup (after
- *	we've woken up).
+ * Make sure that no one else is trying to put the system into a sleep state.
+ * Fail if that's not the case.  Otherwise, prepare for system suspend, make the
+ * system enter the given sleep state and clean up after wakeup.
  */
-int enter_state(suspend_state_t state)
+static int enter_state(suspend_state_t state)
 {
 	int error;
 
@@ -310,24 +308,26 @@ int enter_state(suspend_state_t state)
 }
 
 /**
- *	pm_suspend - Externally visible function for suspending system.
- *	@state:		Enumerated value of state to enter.
+ * pm_suspend - Externally visible function for suspending the system.
+ * @state: System sleep state to enter.
  *
- *	Determine whether or not value is within range, get state
- *	structure, and enter (above).
+ * Check if the value of @state represents one of the supported states,
+ * execute enter_state() and update system suspend statistics.
  */
 int pm_suspend(suspend_state_t state)
 {
-	int ret;
-	if (state > PM_SUSPEND_ON && state < PM_SUSPEND_MAX) {
-		ret = enter_state(state);
-		if (ret) {
-			suspend_stats.fail++;
-			dpm_save_failed_errno(ret);
-		} else
-			suspend_stats.success++;
-		return ret;
+	int error;
+
+	if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX)
+		return -EINVAL;
+
+	error = enter_state(state);
+	if (error) {
+		suspend_stats.fail++;
+		dpm_save_failed_errno(error);
+	} else {
+		suspend_stats.success++;
 	}
-	return -EINVAL;
+	return error;
 }
 EXPORT_SYMBOL(pm_suspend);
diff --git a/kernel/power/user.c b/kernel/power/user.c
index 3e10007..33c4329 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -249,16 +249,10 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
 		}
 		pm_restore_gfp_mask();
 		error = hibernation_snapshot(data->platform_support);
-		if (error) {
-			thaw_kernel_threads();
-		} else {
+		if (!error) {
 			error = put_user(in_suspend, (int __user *)arg);
-			if (!error && !freezer_test_done)
-				data->ready = 1;
-			if (freezer_test_done) {
-				freezer_test_done = false;
-				thaw_kernel_threads();
-			}
+			data->ready = !freezer_test_done && !error;
+			freezer_test_done = false;
 		}
 		break;
 
diff --git a/kernel/printk.c b/kernel/printk.c
index 13c0a11..32690a0 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -702,6 +702,9 @@ static bool printk_time = 0;
 #endif
 module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
 
+static bool always_kmsg_dump;
+module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR);
+
 /* Check if we have any console registered that can be called early in boot. */
 static int have_callable_console(void)
 {
@@ -1732,6 +1735,9 @@ void kmsg_dump(enum kmsg_dump_reason reason)
 	unsigned long l1, l2;
 	unsigned long flags;
 
+	if ((reason > KMSG_DUMP_OOPS) && !always_kmsg_dump)
+		return;
+
 	/* Theoretically, the log could move on after we do this, but
 	   there's not a lot we can do about that. The new messages
 	   will overwrite the start of what we dump. */
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 00ab2ca..ee8d49b 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -231,26 +231,22 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 }
 
 static int ptrace_attach(struct task_struct *task, long request,
+			 unsigned long addr,
 			 unsigned long flags)
 {
 	bool seize = (request == PTRACE_SEIZE);
 	int retval;
 
-	/*
-	 * SEIZE will enable new ptrace behaviors which will be implemented
-	 * gradually.  SEIZE_DEVEL is used to prevent applications
-	 * expecting full SEIZE behaviors trapping on kernel commits which
-	 * are still in the process of implementing them.
-	 *
-	 * Only test programs for new ptrace behaviors being implemented
-	 * should set SEIZE_DEVEL.  If unset, SEIZE will fail with -EIO.
-	 *
-	 * Once SEIZE behaviors are completely implemented, this flag and
-	 * the following test will be removed.
-	 */
 	retval = -EIO;
-	if (seize && !(flags & PTRACE_SEIZE_DEVEL))
-		goto out;
+	if (seize) {
+		if (addr != 0)
+			goto out;
+		if (flags & ~(unsigned long)PTRACE_O_MASK)
+			goto out;
+		flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT);
+	} else {
+		flags = PT_PTRACED;
+	}
 
 	audit_ptrace(task);
 
@@ -262,7 +258,7 @@ static int ptrace_attach(struct task_struct *task, long request,
 
 	/*
 	 * Protect exec's credential calculations against our interference;
-	 * interference; SUID, SGID and LSM creds get determined differently
+	 * SUID, SGID and LSM creds get determined differently
 	 * under ptrace.
 	 */
 	retval = -ERESTARTNOINTR;
@@ -282,11 +278,11 @@ static int ptrace_attach(struct task_struct *task, long request,
 	if (task->ptrace)
 		goto unlock_tasklist;
 
-	task->ptrace = PT_PTRACED;
 	if (seize)
-		task->ptrace |= PT_SEIZED;
+		flags |= PT_SEIZED;
 	if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))
-		task->ptrace |= PT_PTRACE_CAP;
+		flags |= PT_PTRACE_CAP;
+	task->ptrace = flags;
 
 	__ptrace_link(task, current);
 
@@ -528,30 +524,18 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds
 
 static int ptrace_setoptions(struct task_struct *child, unsigned long data)
 {
-	child->ptrace &= ~PT_TRACE_MASK;
+	unsigned flags;
 
-	if (data & PTRACE_O_TRACESYSGOOD)
-		child->ptrace |= PT_TRACESYSGOOD;
-
-	if (data & PTRACE_O_TRACEFORK)
-		child->ptrace |= PT_TRACE_FORK;
-
-	if (data & PTRACE_O_TRACEVFORK)
-		child->ptrace |= PT_TRACE_VFORK;
-
-	if (data & PTRACE_O_TRACECLONE)
-		child->ptrace |= PT_TRACE_CLONE;
-
-	if (data & PTRACE_O_TRACEEXEC)
-		child->ptrace |= PT_TRACE_EXEC;
-
-	if (data & PTRACE_O_TRACEVFORKDONE)
-		child->ptrace |= PT_TRACE_VFORK_DONE;
+	if (data & ~(unsigned long)PTRACE_O_MASK)
+		return -EINVAL;
 
-	if (data & PTRACE_O_TRACEEXIT)
-		child->ptrace |= PT_TRACE_EXIT;
+	/* Avoid intermediate state when all opts are cleared */
+	flags = child->ptrace;
+	flags &= ~(PTRACE_O_MASK << PT_OPT_FLAG_SHIFT);
+	flags |= (data << PT_OPT_FLAG_SHIFT);
+	child->ptrace = flags;
 
-	return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
+	return 0;
 }
 
 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
@@ -891,7 +875,7 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
 	}
 
 	if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
-		ret = ptrace_attach(child, request, data);
+		ret = ptrace_attach(child, request, addr, data);
 		/*
 		 * Some architectures need to do book-keeping after
 		 * a ptrace attach.
@@ -1034,7 +1018,7 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
 	}
 
 	if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) {
-		ret = ptrace_attach(child, request, data);
+		ret = ptrace_attach(child, request, addr, data);
 		/*
 		 * Some architectures need to do book-keeping after
 		 * a ptrace attach.
diff --git a/kernel/rcu.h b/kernel/rcu.h
index aa88baa..8ba99cd 100644
--- a/kernel/rcu.h
+++ b/kernel/rcu.h
@@ -33,8 +33,27 @@
  * Process-level increment to ->dynticks_nesting field.  This allows for
  * architectures that use half-interrupts and half-exceptions from
  * process context.
+ *
+ * DYNTICK_TASK_NEST_MASK defines a field of width DYNTICK_TASK_NEST_WIDTH
+ * that counts the number of process-based reasons why RCU cannot
+ * consider the corresponding CPU to be idle, and DYNTICK_TASK_NEST_VALUE
+ * is the value used to increment or decrement this field.
+ *
+ * The rest of the bits could in principle be used to count interrupts,
+ * but this would mean that a negative-one value in the interrupt
+ * field could incorrectly zero out the DYNTICK_TASK_NEST_MASK field.
+ * We therefore provide a two-bit guard field defined by DYNTICK_TASK_MASK
+ * that is set to DYNTICK_TASK_FLAG upon initial exit from idle.
+ * The DYNTICK_TASK_EXIT_IDLE value is thus the combined value used upon
+ * initial exit from idle.
  */
-#define DYNTICK_TASK_NESTING (LLONG_MAX / 2 - 1)
+#define DYNTICK_TASK_NEST_WIDTH 7
+#define DYNTICK_TASK_NEST_VALUE ((LLONG_MAX >> DYNTICK_TASK_NEST_WIDTH) + 1)
+#define DYNTICK_TASK_NEST_MASK  (LLONG_MAX - DYNTICK_TASK_NEST_VALUE + 1)
+#define DYNTICK_TASK_FLAG	   ((DYNTICK_TASK_NEST_VALUE / 8) * 2)
+#define DYNTICK_TASK_MASK	   ((DYNTICK_TASK_NEST_VALUE / 8) * 3)
+#define DYNTICK_TASK_EXIT_IDLE	   (DYNTICK_TASK_NEST_VALUE + \
+				    DYNTICK_TASK_FLAG)
 
 /*
  * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally
@@ -50,7 +69,6 @@ extern struct debug_obj_descr rcuhead_debug_descr;
 
 static inline void debug_rcu_head_queue(struct rcu_head *head)
 {
-	WARN_ON_ONCE((unsigned long)head & 0x3);
 	debug_object_activate(head, &rcuhead_debug_descr);
 	debug_object_active_state(head, &rcuhead_debug_descr,
 				  STATE_RCU_HEAD_READY,
@@ -76,16 +94,18 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head)
 
 extern void kfree(const void *);
 
-static inline void __rcu_reclaim(char *rn, struct rcu_head *head)
+static inline bool __rcu_reclaim(char *rn, struct rcu_head *head)
 {
 	unsigned long offset = (unsigned long)head->func;
 
 	if (__is_kfree_rcu_offset(offset)) {
 		RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset));
 		kfree((void *)head - offset);
+		return 1;
 	} else {
 		RCU_TRACE(trace_rcu_invoke_callback(rn, head));
 		head->func(head);
+		return 0;
 	}
 }
 
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 2bc4e13..a86f174 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -88,6 +88,9 @@ EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
  * section.
  *
  * Check debug_lockdep_rcu_enabled() to prevent false positives during boot.
+ *
+ * Note that rcu_read_lock() is disallowed if the CPU is either idle or
+ * offline from an RCU perspective, so check for those as well.
  */
 int rcu_read_lock_bh_held(void)
 {
@@ -95,6 +98,8 @@ int rcu_read_lock_bh_held(void)
 		return 1;
 	if (rcu_is_cpu_idle())
 		return 0;
+	if (!rcu_lockdep_current_cpu_online())
+		return 0;
 	return in_softirq() || irqs_disabled();
 }
 EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
index 977296d..37a5444 100644
--- a/kernel/rcutiny.c
+++ b/kernel/rcutiny.c
@@ -53,7 +53,7 @@ static void __call_rcu(struct rcu_head *head,
 
 #include "rcutiny_plugin.h"
 
-static long long rcu_dynticks_nesting = DYNTICK_TASK_NESTING;
+static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 
 /* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. */
 static void rcu_idle_enter_common(long long oldval)
@@ -88,10 +88,16 @@ void rcu_idle_enter(void)
 
 	local_irq_save(flags);
 	oldval = rcu_dynticks_nesting;
-	rcu_dynticks_nesting = 0;
+	WARN_ON_ONCE((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) == 0);
+	if ((rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK) ==
+	    DYNTICK_TASK_NEST_VALUE)
+		rcu_dynticks_nesting = 0;
+	else
+		rcu_dynticks_nesting  -= DYNTICK_TASK_NEST_VALUE;
 	rcu_idle_enter_common(oldval);
 	local_irq_restore(flags);
 }
+EXPORT_SYMBOL_GPL(rcu_idle_enter);
 
 /*
  * Exit an interrupt handler towards idle.
@@ -140,11 +146,15 @@ void rcu_idle_exit(void)
 
 	local_irq_save(flags);
 	oldval = rcu_dynticks_nesting;
-	WARN_ON_ONCE(oldval != 0);
-	rcu_dynticks_nesting = DYNTICK_TASK_NESTING;
+	WARN_ON_ONCE(rcu_dynticks_nesting < 0);
+	if (rcu_dynticks_nesting & DYNTICK_TASK_NEST_MASK)
+		rcu_dynticks_nesting += DYNTICK_TASK_NEST_VALUE;
+	else
+		rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 	rcu_idle_exit_common(oldval);
 	local_irq_restore(flags);
 }
+EXPORT_SYMBOL_GPL(rcu_idle_exit);
 
 /*
  * Enter an interrupt handler, moving away from idle.
@@ -258,7 +268,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
 
 	/* If no RCU callbacks ready to invoke, just return. */
 	if (&rcp->rcucblist == rcp->donetail) {
-		RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, -1));
+		RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, 0, -1));
 		RCU_TRACE(trace_rcu_batch_end(rcp->name, 0,
 					      ACCESS_ONCE(rcp->rcucblist),
 					      need_resched(),
@@ -269,7 +279,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
 
 	/* Move the ready-to-invoke callbacks to a local list. */
 	local_irq_save(flags);
-	RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, -1));
+	RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, rcp->qlen, -1));
 	list = rcp->rcucblist;
 	rcp->rcucblist = *rcp->donetail;
 	*rcp->donetail = NULL;
@@ -319,6 +329,10 @@ static void rcu_process_callbacks(struct softirq_action *unused)
  */
 void synchronize_sched(void)
 {
+	rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+			   !lock_is_held(&rcu_lock_map) &&
+			   !lock_is_held(&rcu_sched_lock_map),
+			   "Illegal synchronize_sched() in RCU read-side critical section");
 	cond_resched();
 }
 EXPORT_SYMBOL_GPL(synchronize_sched);
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
index 9cb1ae4..22ecea0 100644
--- a/kernel/rcutiny_plugin.h
+++ b/kernel/rcutiny_plugin.h
@@ -132,6 +132,7 @@ static struct rcu_preempt_ctrlblk rcu_preempt_ctrlblk = {
 	RCU_TRACE(.rcb.name = "rcu_preempt")
 };
 
+static void rcu_read_unlock_special(struct task_struct *t);
 static int rcu_preempted_readers_exp(void);
 static void rcu_report_exp_done(void);
 
@@ -146,6 +147,16 @@ static int rcu_cpu_blocking_cur_gp(void)
 /*
  * Check for a running RCU reader.  Because there is only one CPU,
  * there can be but one running RCU reader at a time.  ;-)
+ *
+ * Returns zero if there are no running readers.  Returns a positive
+ * number if there is at least one reader within its RCU read-side
+ * critical section.  Returns a negative number if an outermost reader
+ * is in the midst of exiting from its RCU read-side critical section
+ *
+ * Returns zero if there are no running readers.  Returns a positive
+ * number if there is at least one reader within its RCU read-side
+ * critical section.  Returns a negative number if an outermost reader
+ * is in the midst of exiting from its RCU read-side critical section.
  */
 static int rcu_preempt_running_reader(void)
 {
@@ -307,7 +318,6 @@ static int rcu_boost(void)
 	t = container_of(tb, struct task_struct, rcu_node_entry);
 	rt_mutex_init_proxy_locked(&mtx, t);
 	t->rcu_boost_mutex = &mtx;
-	t->rcu_read_unlock_special |= RCU_READ_UNLOCK_BOOSTED;
 	raw_local_irq_restore(flags);
 	rt_mutex_lock(&mtx);
 	rt_mutex_unlock(&mtx);  /* Keep lockdep happy. */
@@ -475,7 +485,7 @@ void rcu_preempt_note_context_switch(void)
 	unsigned long flags;
 
 	local_irq_save(flags); /* must exclude scheduler_tick(). */
-	if (rcu_preempt_running_reader() &&
+	if (rcu_preempt_running_reader() > 0 &&
 	    (t->rcu_read_unlock_special & RCU_READ_UNLOCK_BLOCKED) == 0) {
 
 		/* Possibly blocking in an RCU read-side critical section. */
@@ -494,6 +504,13 @@ void rcu_preempt_note_context_switch(void)
 		list_add(&t->rcu_node_entry, &rcu_preempt_ctrlblk.blkd_tasks);
 		if (rcu_cpu_blocking_cur_gp())
 			rcu_preempt_ctrlblk.gp_tasks = &t->rcu_node_entry;
+	} else if (rcu_preempt_running_reader() < 0 &&
+		   t->rcu_read_unlock_special) {
+		/*
+		 * Complete exit from RCU read-side critical section on
+		 * behalf of preempted instance of __rcu_read_unlock().
+		 */
+		rcu_read_unlock_special(t);
 	}
 
 	/*
@@ -526,12 +543,15 @@ EXPORT_SYMBOL_GPL(__rcu_read_lock);
  * notify RCU core processing or task having blocked during the RCU
  * read-side critical section.
  */
-static void rcu_read_unlock_special(struct task_struct *t)
+static noinline void rcu_read_unlock_special(struct task_struct *t)
 {
 	int empty;
 	int empty_exp;
 	unsigned long flags;
 	struct list_head *np;
+#ifdef CONFIG_RCU_BOOST
+	struct rt_mutex *rbmp = NULL;
+#endif /* #ifdef CONFIG_RCU_BOOST */
 	int special;
 
 	/*
@@ -552,7 +572,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
 		rcu_preempt_cpu_qs();
 
 	/* Hardware IRQ handlers cannot block. */
-	if (in_irq()) {
+	if (in_irq() || in_serving_softirq()) {
 		local_irq_restore(flags);
 		return;
 	}
@@ -597,10 +617,10 @@ static void rcu_read_unlock_special(struct task_struct *t)
 	}
 #ifdef CONFIG_RCU_BOOST
 	/* Unboost self if was boosted. */
-	if (special & RCU_READ_UNLOCK_BOOSTED) {
-		t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_BOOSTED;
-		rt_mutex_unlock(t->rcu_boost_mutex);
+	if (t->rcu_boost_mutex != NULL) {
+		rbmp = t->rcu_boost_mutex;
 		t->rcu_boost_mutex = NULL;
+		rt_mutex_unlock(rbmp);
 	}
 #endif /* #ifdef CONFIG_RCU_BOOST */
 	local_irq_restore(flags);
@@ -618,13 +638,22 @@ void __rcu_read_unlock(void)
 	struct task_struct *t = current;
 
 	barrier();  /* needed if we ever invoke rcu_read_unlock in rcutiny.c */
-	--t->rcu_read_lock_nesting;
-	barrier();  /* decrement before load of ->rcu_read_unlock_special */
-	if (t->rcu_read_lock_nesting == 0 &&
-	    unlikely(ACCESS_ONCE(t->rcu_read_unlock_special)))
-		rcu_read_unlock_special(t);
+	if (t->rcu_read_lock_nesting != 1)
+		--t->rcu_read_lock_nesting;
+	else {
+		t->rcu_read_lock_nesting = INT_MIN;
+		barrier();  /* assign before ->rcu_read_unlock_special load */
+		if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special)))
+			rcu_read_unlock_special(t);
+		barrier();  /* ->rcu_read_unlock_special load before assign */
+		t->rcu_read_lock_nesting = 0;
+	}
 #ifdef CONFIG_PROVE_LOCKING
-	WARN_ON_ONCE(t->rcu_read_lock_nesting < 0);
+	{
+		int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting);
+
+		WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2);
+	}
 #endif /* #ifdef CONFIG_PROVE_LOCKING */
 }
 EXPORT_SYMBOL_GPL(__rcu_read_unlock);
@@ -649,7 +678,7 @@ static void rcu_preempt_check_callbacks(void)
 		invoke_rcu_callbacks();
 	if (rcu_preempt_gp_in_progress() &&
 	    rcu_cpu_blocking_cur_gp() &&
-	    rcu_preempt_running_reader())
+	    rcu_preempt_running_reader() > 0)
 		t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS;
 }
 
@@ -706,6 +735,11 @@ EXPORT_SYMBOL_GPL(call_rcu);
  */
 void synchronize_rcu(void)
 {
+	rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+			   !lock_is_held(&rcu_lock_map) &&
+			   !lock_is_held(&rcu_sched_lock_map),
+			   "Illegal synchronize_rcu() in RCU read-side critical section");
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 	if (!rcu_scheduler_active)
 		return;
@@ -882,7 +916,8 @@ static void rcu_preempt_process_callbacks(void)
 static void invoke_rcu_callbacks(void)
 {
 	have_rcu_kthread_work = 1;
-	wake_up(&rcu_kthread_wq);
+	if (rcu_kthread_task != NULL)
+		wake_up(&rcu_kthread_wq);
 }
 
 #ifdef CONFIG_RCU_TRACE
@@ -943,12 +978,16 @@ early_initcall(rcu_spawn_kthreads);
 
 #else /* #ifdef CONFIG_RCU_BOOST */
 
+/* Hold off callback invocation until early_initcall() time. */
+static int rcu_scheduler_fully_active __read_mostly;
+
 /*
  * Start up softirq processing of callbacks.
  */
 void invoke_rcu_callbacks(void)
 {
-	raise_softirq(RCU_SOFTIRQ);
+	if (rcu_scheduler_fully_active)
+		raise_softirq(RCU_SOFTIRQ);
 }
 
 #ifdef CONFIG_RCU_TRACE
@@ -963,10 +1002,14 @@ static bool rcu_is_callbacks_kthread(void)
 
 #endif /* #ifdef CONFIG_RCU_TRACE */
 
-void rcu_init(void)
+static int __init rcu_scheduler_really_started(void)
 {
+	rcu_scheduler_fully_active = 1;
 	open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+	raise_softirq(RCU_SOFTIRQ);  /* Invoke any callbacks from early boot. */
+	return 0;
 }
+early_initcall(rcu_scheduler_really_started);
 
 #endif /* #else #ifdef CONFIG_RCU_BOOST */
 
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index a58ac28..a89b381 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -65,7 +65,10 @@ static int fqs_duration;	/* Duration of bursts (us), 0 to disable. */
 static int fqs_holdoff;		/* Hold time within burst (us). */
 static int fqs_stutter = 3;	/* Wait time between bursts (s). */
 static int onoff_interval;	/* Wait time between CPU hotplugs, 0=disable. */
+static int onoff_holdoff;	/* Seconds after boot before CPU hotplugs. */
 static int shutdown_secs;	/* Shutdown time (s).  <=0 for no shutdown. */
+static int stall_cpu;		/* CPU-stall duration (s).  0 for no stall. */
+static int stall_cpu_holdoff = 10; /* Time to wait until stall (s).  */
 static int test_boost = 1;	/* Test RCU prio boost: 0=no, 1=maybe, 2=yes. */
 static int test_boost_interval = 7; /* Interval between boost tests, seconds. */
 static int test_boost_duration = 4; /* Duration of each boost test, seconds. */
@@ -95,8 +98,14 @@ module_param(fqs_stutter, int, 0444);
 MODULE_PARM_DESC(fqs_stutter, "Wait time between fqs bursts (s)");
 module_param(onoff_interval, int, 0444);
 MODULE_PARM_DESC(onoff_interval, "Time between CPU hotplugs (s), 0=disable");
+module_param(onoff_holdoff, int, 0444);
+MODULE_PARM_DESC(onoff_holdoff, "Time after boot before CPU hotplugs (s)");
 module_param(shutdown_secs, int, 0444);
 MODULE_PARM_DESC(shutdown_secs, "Shutdown time (s), zero to disable.");
+module_param(stall_cpu, int, 0444);
+MODULE_PARM_DESC(stall_cpu, "Stall duration (s), zero to disable.");
+module_param(stall_cpu_holdoff, int, 0444);
+MODULE_PARM_DESC(stall_cpu_holdoff, "Time to wait before starting stall (s).");
 module_param(test_boost, int, 0444);
 MODULE_PARM_DESC(test_boost, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");
 module_param(test_boost_interval, int, 0444);
@@ -129,6 +138,7 @@ static struct task_struct *shutdown_task;
 #ifdef CONFIG_HOTPLUG_CPU
 static struct task_struct *onoff_task;
 #endif /* #ifdef CONFIG_HOTPLUG_CPU */
+static struct task_struct *stall_task;
 
 #define RCU_TORTURE_PIPE_LEN 10
 
@@ -990,12 +1000,12 @@ static void rcu_torture_timer(unsigned long unused)
 				  rcu_read_lock_bh_held() ||
 				  rcu_read_lock_sched_held() ||
 				  srcu_read_lock_held(&srcu_ctl));
-	do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu);
 	if (p == NULL) {
 		/* Leave because rcu_torture_writer is not yet underway */
 		cur_ops->readunlock(idx);
 		return;
 	}
+	do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu);
 	if (p->rtort_mbtest == 0)
 		atomic_inc(&n_rcu_torture_mberror);
 	spin_lock(&rand_lock);
@@ -1053,13 +1063,13 @@ rcu_torture_reader(void *arg)
 					  rcu_read_lock_bh_held() ||
 					  rcu_read_lock_sched_held() ||
 					  srcu_read_lock_held(&srcu_ctl));
-		do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu);
 		if (p == NULL) {
 			/* Wait for rcu_torture_writer to get underway */
 			cur_ops->readunlock(idx);
 			schedule_timeout_interruptible(HZ);
 			continue;
 		}
+		do_trace_rcu_torture_read(cur_ops->name, &p->rtort_rcu);
 		if (p->rtort_mbtest == 0)
 			atomic_inc(&n_rcu_torture_mberror);
 		cur_ops->read_delay(&rand);
@@ -1300,13 +1310,13 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag)
 		"fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "
 		"test_boost=%d/%d test_boost_interval=%d "
 		"test_boost_duration=%d shutdown_secs=%d "
-		"onoff_interval=%d\n",
+		"onoff_interval=%d onoff_holdoff=%d\n",
 		torture_type, tag, nrealreaders, nfakewriters,
 		stat_interval, verbose, test_no_idle_hz, shuffle_interval,
 		stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,
 		test_boost, cur_ops->can_boost,
 		test_boost_interval, test_boost_duration, shutdown_secs,
-		onoff_interval);
+		onoff_interval, onoff_holdoff);
 }
 
 static struct notifier_block rcutorture_shutdown_nb = {
@@ -1410,6 +1420,11 @@ rcu_torture_onoff(void *arg)
 	for_each_online_cpu(cpu)
 		maxcpu = cpu;
 	WARN_ON(maxcpu < 0);
+	if (onoff_holdoff > 0) {
+		VERBOSE_PRINTK_STRING("rcu_torture_onoff begin holdoff");
+		schedule_timeout_interruptible(onoff_holdoff * HZ);
+		VERBOSE_PRINTK_STRING("rcu_torture_onoff end holdoff");
+	}
 	while (!kthread_should_stop()) {
 		cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1);
 		if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
@@ -1450,12 +1465,15 @@ rcu_torture_onoff(void *arg)
 static int __cpuinit
 rcu_torture_onoff_init(void)
 {
+	int ret;
+
 	if (onoff_interval <= 0)
 		return 0;
 	onoff_task = kthread_run(rcu_torture_onoff, NULL, "rcu_torture_onoff");
 	if (IS_ERR(onoff_task)) {
+		ret = PTR_ERR(onoff_task);
 		onoff_task = NULL;
-		return PTR_ERR(onoff_task);
+		return ret;
 	}
 	return 0;
 }
@@ -1481,6 +1499,63 @@ static void rcu_torture_onoff_cleanup(void)
 
 #endif /* #else #ifdef CONFIG_HOTPLUG_CPU */
 
+/*
+ * CPU-stall kthread.  It waits as specified by stall_cpu_holdoff, then
+ * induces a CPU stall for the time specified by stall_cpu.
+ */
+static int __cpuinit rcu_torture_stall(void *args)
+{
+	unsigned long stop_at;
+
+	VERBOSE_PRINTK_STRING("rcu_torture_stall task started");
+	if (stall_cpu_holdoff > 0) {
+		VERBOSE_PRINTK_STRING("rcu_torture_stall begin holdoff");
+		schedule_timeout_interruptible(stall_cpu_holdoff * HZ);
+		VERBOSE_PRINTK_STRING("rcu_torture_stall end holdoff");
+	}
+	if (!kthread_should_stop()) {
+		stop_at = get_seconds() + stall_cpu;
+		/* RCU CPU stall is expected behavior in following code. */
+		printk(KERN_ALERT "rcu_torture_stall start.\n");
+		rcu_read_lock();
+		preempt_disable();
+		while (ULONG_CMP_LT(get_seconds(), stop_at))
+			continue;  /* Induce RCU CPU stall warning. */
+		preempt_enable();
+		rcu_read_unlock();
+		printk(KERN_ALERT "rcu_torture_stall end.\n");
+	}
+	rcutorture_shutdown_absorb("rcu_torture_stall");
+	while (!kthread_should_stop())
+		schedule_timeout_interruptible(10 * HZ);
+	return 0;
+}
+
+/* Spawn CPU-stall kthread, if stall_cpu specified. */
+static int __init rcu_torture_stall_init(void)
+{
+	int ret;
+
+	if (stall_cpu <= 0)
+		return 0;
+	stall_task = kthread_run(rcu_torture_stall, NULL, "rcu_torture_stall");
+	if (IS_ERR(stall_task)) {
+		ret = PTR_ERR(stall_task);
+		stall_task = NULL;
+		return ret;
+	}
+	return 0;
+}
+
+/* Clean up after the CPU-stall kthread, if one was spawned. */
+static void rcu_torture_stall_cleanup(void)
+{
+	if (stall_task == NULL)
+		return;
+	VERBOSE_PRINTK_STRING("Stopping rcu_torture_stall_task.");
+	kthread_stop(stall_task);
+}
+
 static int rcutorture_cpu_notify(struct notifier_block *self,
 				 unsigned long action, void *hcpu)
 {
@@ -1523,6 +1598,7 @@ rcu_torture_cleanup(void)
 	fullstop = FULLSTOP_RMMOD;
 	mutex_unlock(&fullstop_mutex);
 	unregister_reboot_notifier(&rcutorture_shutdown_nb);
+	rcu_torture_stall_cleanup();
 	if (stutter_task) {
 		VERBOSE_PRINTK_STRING("Stopping rcu_torture_stutter task");
 		kthread_stop(stutter_task);
@@ -1602,6 +1678,10 @@ rcu_torture_cleanup(void)
 		cur_ops->cleanup();
 	if (atomic_read(&n_rcu_torture_error))
 		rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE");
+	else if (n_online_successes != n_online_attempts ||
+		 n_offline_successes != n_offline_attempts)
+		rcu_torture_print_module_parms(cur_ops,
+					       "End of test: RCU_HOTPLUG");
 	else
 		rcu_torture_print_module_parms(cur_ops, "End of test: SUCCESS");
 }
@@ -1819,6 +1899,7 @@ rcu_torture_init(void)
 	}
 	rcu_torture_onoff_init();
 	register_reboot_notifier(&rcutorture_shutdown_nb);
+	rcu_torture_stall_init();
 	rcutorture_record_test_transition();
 	mutex_unlock(&fullstop_mutex);
 	return 0;
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 6c4a672..1050d6d 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -50,6 +50,8 @@
 #include <linux/wait.h>
 #include <linux/kthread.h>
 #include <linux/prefetch.h>
+#include <linux/delay.h>
+#include <linux/stop_machine.h>
 
 #include "rcutree.h"
 #include <trace/events/rcu.h>
@@ -196,7 +198,7 @@ void rcu_note_context_switch(int cpu)
 EXPORT_SYMBOL_GPL(rcu_note_context_switch);
 
 DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
-	.dynticks_nesting = DYNTICK_TASK_NESTING,
+	.dynticks_nesting = DYNTICK_TASK_EXIT_IDLE,
 	.dynticks = ATOMIC_INIT(1),
 };
 
@@ -208,8 +210,11 @@ module_param(blimit, int, 0);
 module_param(qhimark, int, 0);
 module_param(qlowmark, int, 0);
 
-int rcu_cpu_stall_suppress __read_mostly;
+int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
+int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
+
 module_param(rcu_cpu_stall_suppress, int, 0644);
+module_param(rcu_cpu_stall_timeout, int, 0644);
 
 static void force_quiescent_state(struct rcu_state *rsp, int relaxed);
 static int rcu_pending(int cpu);
@@ -301,8 +306,6 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
 	return &rsp->node[0];
 }
 
-#ifdef CONFIG_SMP
-
 /*
  * If the specified CPU is offline, tell the caller that it is in
  * a quiescent state.  Otherwise, whack it with a reschedule IPI.
@@ -317,30 +320,21 @@ static struct rcu_node *rcu_get_root(struct rcu_state *rsp)
 static int rcu_implicit_offline_qs(struct rcu_data *rdp)
 {
 	/*
-	 * If the CPU is offline, it is in a quiescent state.  We can
-	 * trust its state not to change because interrupts are disabled.
+	 * If the CPU is offline for more than a jiffy, it is in a quiescent
+	 * state.  We can trust its state not to change because interrupts
+	 * are disabled.  The reason for the jiffy's worth of slack is to
+	 * handle CPUs initializing on the way up and finding their way
+	 * to the idle loop on the way down.
 	 */
-	if (cpu_is_offline(rdp->cpu)) {
+	if (cpu_is_offline(rdp->cpu) &&
+	    ULONG_CMP_LT(rdp->rsp->gp_start + 2, jiffies)) {
 		trace_rcu_fqs(rdp->rsp->name, rdp->gpnum, rdp->cpu, "ofl");
 		rdp->offline_fqs++;
 		return 1;
 	}
-
-	/*
-	 * The CPU is online, so send it a reschedule IPI.  This forces
-	 * it through the scheduler, and (inefficiently) also handles cases
-	 * where idle loops fail to inform RCU about the CPU being idle.
-	 */
-	if (rdp->cpu != smp_processor_id())
-		smp_send_reschedule(rdp->cpu);
-	else
-		set_need_resched();
-	rdp->resched_ipi++;
 	return 0;
 }
 
-#endif /* #ifdef CONFIG_SMP */
-
 /*
  * rcu_idle_enter_common - inform RCU that current CPU is moving towards idle
  *
@@ -366,6 +360,17 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
 	atomic_inc(&rdtp->dynticks);
 	smp_mb__after_atomic_inc();  /* Force ordering with next sojourn. */
 	WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
+
+	/*
+	 * The idle task is not permitted to enter the idle loop while
+	 * in an RCU read-side critical section.
+	 */
+	rcu_lockdep_assert(!lock_is_held(&rcu_lock_map),
+			   "Illegal idle entry in RCU read-side critical section.");
+	rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map),
+			   "Illegal idle entry in RCU-bh read-side critical section.");
+	rcu_lockdep_assert(!lock_is_held(&rcu_sched_lock_map),
+			   "Illegal idle entry in RCU-sched read-side critical section.");
 }
 
 /**
@@ -389,10 +394,15 @@ void rcu_idle_enter(void)
 	local_irq_save(flags);
 	rdtp = &__get_cpu_var(rcu_dynticks);
 	oldval = rdtp->dynticks_nesting;
-	rdtp->dynticks_nesting = 0;
+	WARN_ON_ONCE((oldval & DYNTICK_TASK_NEST_MASK) == 0);
+	if ((oldval & DYNTICK_TASK_NEST_MASK) == DYNTICK_TASK_NEST_VALUE)
+		rdtp->dynticks_nesting = 0;
+	else
+		rdtp->dynticks_nesting -= DYNTICK_TASK_NEST_VALUE;
 	rcu_idle_enter_common(rdtp, oldval);
 	local_irq_restore(flags);
 }
+EXPORT_SYMBOL_GPL(rcu_idle_enter);
 
 /**
  * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
@@ -462,7 +472,7 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
  * Exit idle mode, in other words, -enter- the mode in which RCU
  * read-side critical sections can occur.
  *
- * We crowbar the ->dynticks_nesting field to DYNTICK_TASK_NESTING to
+ * We crowbar the ->dynticks_nesting field to DYNTICK_TASK_NEST to
  * allow for the possibility of usermode upcalls messing up our count
  * of interrupt nesting level during the busy period that is just
  * now starting.
@@ -476,11 +486,15 @@ void rcu_idle_exit(void)
 	local_irq_save(flags);
 	rdtp = &__get_cpu_var(rcu_dynticks);
 	oldval = rdtp->dynticks_nesting;
-	WARN_ON_ONCE(oldval != 0);
-	rdtp->dynticks_nesting = DYNTICK_TASK_NESTING;
+	WARN_ON_ONCE(oldval < 0);
+	if (oldval & DYNTICK_TASK_NEST_MASK)
+		rdtp->dynticks_nesting += DYNTICK_TASK_NEST_VALUE;
+	else
+		rdtp->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 	rcu_idle_exit_common(rdtp, oldval);
 	local_irq_restore(flags);
 }
+EXPORT_SYMBOL_GPL(rcu_idle_exit);
 
 /**
  * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle
@@ -581,6 +595,49 @@ int rcu_is_cpu_idle(void)
 }
 EXPORT_SYMBOL(rcu_is_cpu_idle);
 
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Is the current CPU online?  Disable preemption to avoid false positives
+ * that could otherwise happen due to the current CPU number being sampled,
+ * this task being preempted, its old CPU being taken offline, resuming
+ * on some other CPU, then determining that its old CPU is now offline.
+ * It is OK to use RCU on an offline processor during initial boot, hence
+ * the check for rcu_scheduler_fully_active.  Note also that it is OK
+ * for a CPU coming online to use RCU for one jiffy prior to marking itself
+ * online in the cpu_online_mask.  Similarly, it is OK for a CPU going
+ * offline to continue to use RCU for one jiffy after marking itself
+ * offline in the cpu_online_mask.  This leniency is necessary given the
+ * non-atomic nature of the online and offline processing, for example,
+ * the fact that a CPU enters the scheduler after completing the CPU_DYING
+ * notifiers.
+ *
+ * This is also why RCU internally marks CPUs online during the
+ * CPU_UP_PREPARE phase and offline during the CPU_DEAD phase.
+ *
+ * Disable checking if in an NMI handler because we cannot safely report
+ * errors from NMI handlers anyway.
+ */
+bool rcu_lockdep_current_cpu_online(void)
+{
+	struct rcu_data *rdp;
+	struct rcu_node *rnp;
+	bool ret;
+
+	if (in_nmi())
+		return 1;
+	preempt_disable();
+	rdp = &__get_cpu_var(rcu_sched_data);
+	rnp = rdp->mynode;
+	ret = (rdp->grpmask & rnp->qsmaskinit) ||
+	      !rcu_scheduler_fully_active;
+	preempt_enable();
+	return ret;
+}
+EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online);
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
 #endif /* #ifdef CONFIG_PROVE_RCU */
 
 /**
@@ -595,8 +652,6 @@ int rcu_is_cpu_rrupt_from_idle(void)
 	return __get_cpu_var(rcu_dynticks).dynticks_nesting <= 1;
 }
 
-#ifdef CONFIG_SMP
-
 /*
  * Snapshot the specified CPU's dynticks counter so that we can later
  * credit them with an implicit quiescent state.  Return 1 if this CPU
@@ -640,12 +695,28 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
 	return rcu_implicit_offline_qs(rdp);
 }
 
-#endif /* #ifdef CONFIG_SMP */
+static int jiffies_till_stall_check(void)
+{
+	int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
+
+	/*
+	 * Limit check must be consistent with the Kconfig limits
+	 * for CONFIG_RCU_CPU_STALL_TIMEOUT.
+	 */
+	if (till_stall_check < 3) {
+		ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
+		till_stall_check = 3;
+	} else if (till_stall_check > 300) {
+		ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
+		till_stall_check = 300;
+	}
+	return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
+}
 
 static void record_gp_stall_check_time(struct rcu_state *rsp)
 {
 	rsp->gp_start = jiffies;
-	rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_CHECK;
+	rsp->jiffies_stall = jiffies + jiffies_till_stall_check();
 }
 
 static void print_other_cpu_stall(struct rcu_state *rsp)
@@ -664,13 +735,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
 		raw_spin_unlock_irqrestore(&rnp->lock, flags);
 		return;
 	}
-	rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
-
-	/*
-	 * Now rat on any tasks that got kicked up to the root rcu_node
-	 * due to CPU offlining.
-	 */
-	ndetected = rcu_print_task_stall(rnp);
+	rsp->jiffies_stall = jiffies + 3 * jiffies_till_stall_check() + 3;
 	raw_spin_unlock_irqrestore(&rnp->lock, flags);
 
 	/*
@@ -678,8 +743,9 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
 	 * See Documentation/RCU/stallwarn.txt for info on how to debug
 	 * RCU CPU stall warnings.
 	 */
-	printk(KERN_ERR "INFO: %s detected stalls on CPUs/tasks: {",
+	printk(KERN_ERR "INFO: %s detected stalls on CPUs/tasks:",
 	       rsp->name);
+	print_cpu_stall_info_begin();
 	rcu_for_each_leaf_node(rsp, rnp) {
 		raw_spin_lock_irqsave(&rnp->lock, flags);
 		ndetected += rcu_print_task_stall(rnp);
@@ -688,11 +754,22 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
 			continue;
 		for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
 			if (rnp->qsmask & (1UL << cpu)) {
-				printk(" %d", rnp->grplo + cpu);
+				print_cpu_stall_info(rsp, rnp->grplo + cpu);
 				ndetected++;
 			}
 	}
-	printk("} (detected by %d, t=%ld jiffies)\n",
+
+	/*
+	 * Now rat on any tasks that got kicked up to the root rcu_node
+	 * due to CPU offlining.
+	 */
+	rnp = rcu_get_root(rsp);
+	raw_spin_lock_irqsave(&rnp->lock, flags);
+	ndetected = rcu_print_task_stall(rnp);
+	raw_spin_unlock_irqrestore(&rnp->lock, flags);
+
+	print_cpu_stall_info_end();
+	printk(KERN_CONT "(detected by %d, t=%ld jiffies)\n",
 	       smp_processor_id(), (long)(jiffies - rsp->gp_start));
 	if (ndetected == 0)
 		printk(KERN_ERR "INFO: Stall ended before state dump start\n");
@@ -716,15 +793,18 @@ static void print_cpu_stall(struct rcu_state *rsp)
 	 * See Documentation/RCU/stallwarn.txt for info on how to debug
 	 * RCU CPU stall warnings.
 	 */
-	printk(KERN_ERR "INFO: %s detected stall on CPU %d (t=%lu jiffies)\n",
-	       rsp->name, smp_processor_id(), jiffies - rsp->gp_start);
+	printk(KERN_ERR "INFO: %s self-detected stall on CPU", rsp->name);
+	print_cpu_stall_info_begin();
+	print_cpu_stall_info(rsp, smp_processor_id());
+	print_cpu_stall_info_end();
+	printk(KERN_CONT " (t=%lu jiffies)\n", jiffies - rsp->gp_start);
 	if (!trigger_all_cpu_backtrace())
 		dump_stack();
 
 	raw_spin_lock_irqsave(&rnp->lock, flags);
 	if (ULONG_CMP_GE(jiffies, rsp->jiffies_stall))
-		rsp->jiffies_stall =
-			jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
+		rsp->jiffies_stall = jiffies +
+				     3 * jiffies_till_stall_check() + 3;
 	raw_spin_unlock_irqrestore(&rnp->lock, flags);
 
 	set_need_resched();  /* kick ourselves to get things going. */
@@ -807,6 +887,7 @@ static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct
 			rdp->passed_quiesce = 0;
 		} else
 			rdp->qs_pending = 0;
+		zero_cpu_stall_ticks(rdp);
 	}
 }
 
@@ -943,6 +1024,10 @@ rcu_start_gp_per_cpu(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_dat
  * in preparation for detecting the next grace period.  The caller must hold
  * the root node's ->lock, which is released before return.  Hard irqs must
  * be disabled.
+ *
+ * Note that it is legal for a dying CPU (which is marked as offline) to
+ * invoke this function.  This can happen when the dying CPU reports its
+ * quiescent state.
  */
 static void
 rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
@@ -980,26 +1065,8 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 	rsp->fqs_state = RCU_GP_INIT; /* Hold off force_quiescent_state. */
 	rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
 	record_gp_stall_check_time(rsp);
-
-	/* Special-case the common single-level case. */
-	if (NUM_RCU_NODES == 1) {
-		rcu_preempt_check_blocked_tasks(rnp);
-		rnp->qsmask = rnp->qsmaskinit;
-		rnp->gpnum = rsp->gpnum;
-		rnp->completed = rsp->completed;
-		rsp->fqs_state = RCU_SIGNAL_INIT; /* force_quiescent_state OK */
-		rcu_start_gp_per_cpu(rsp, rnp, rdp);
-		rcu_preempt_boost_start_gp(rnp);
-		trace_rcu_grace_period_init(rsp->name, rnp->gpnum,
-					    rnp->level, rnp->grplo,
-					    rnp->grphi, rnp->qsmask);
-		raw_spin_unlock_irqrestore(&rnp->lock, flags);
-		return;
-	}
-
 	raw_spin_unlock(&rnp->lock);  /* leave irqs disabled. */
 
-
 	/* Exclude any concurrent CPU-hotplug operations. */
 	raw_spin_lock(&rsp->onofflock);  /* irqs already disabled. */
 
@@ -1245,53 +1312,115 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
 
 /*
  * Move a dying CPU's RCU callbacks to online CPU's callback list.
- * Synchronization is not required because this function executes
- * in stop_machine() context.
+ * Also record a quiescent state for this CPU for the current grace period.
+ * Synchronization and interrupt disabling are not required because
+ * this function executes in stop_machine() context.  Therefore, cleanup
+ * operations that might block must be done later from the CPU_DEAD
+ * notifier.
+ *
+ * Note that the outgoing CPU's bit has already been cleared in the
+ * cpu_online_mask.  This allows us to randomly pick a callback
+ * destination from the bits set in that mask.
  */
-static void rcu_send_cbs_to_online(struct rcu_state *rsp)
+static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
 {
 	int i;
-	/* current DYING CPU is cleared in the cpu_online_mask */
+	unsigned long mask;
 	int receive_cpu = cpumask_any(cpu_online_mask);
 	struct rcu_data *rdp = this_cpu_ptr(rsp->rda);
 	struct rcu_data *receive_rdp = per_cpu_ptr(rsp->rda, receive_cpu);
+	RCU_TRACE(struct rcu_node *rnp = rdp->mynode); /* For dying CPU. */
+
+	/* First, adjust the counts. */
+	if (rdp->nxtlist != NULL) {
+		receive_rdp->qlen_lazy += rdp->qlen_lazy;
+		receive_rdp->qlen += rdp->qlen;
+		rdp->qlen_lazy = 0;
+		rdp->qlen = 0;
+	}
 
-	if (rdp->nxtlist == NULL)
-		return;  /* irqs disabled, so comparison is stable. */
+	/*
+	 * Next, move ready-to-invoke callbacks to be invoked on some
+	 * other CPU.  These will not be required to pass through another
+	 * grace period:  They are done, regardless of CPU.
+	 */
+	if (rdp->nxtlist != NULL &&
+	    rdp->nxttail[RCU_DONE_TAIL] != &rdp->nxtlist) {
+		struct rcu_head *oldhead;
+		struct rcu_head **oldtail;
+		struct rcu_head **newtail;
+
+		oldhead = rdp->nxtlist;
+		oldtail = receive_rdp->nxttail[RCU_DONE_TAIL];
+		rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
+		*rdp->nxttail[RCU_DONE_TAIL] = *oldtail;
+		*receive_rdp->nxttail[RCU_DONE_TAIL] = oldhead;
+		newtail = rdp->nxttail[RCU_DONE_TAIL];
+		for (i = RCU_DONE_TAIL; i < RCU_NEXT_SIZE; i++) {
+			if (receive_rdp->nxttail[i] == oldtail)
+				receive_rdp->nxttail[i] = newtail;
+			if (rdp->nxttail[i] == newtail)
+				rdp->nxttail[i] = &rdp->nxtlist;
+		}
+	}
 
-	*receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist;
-	receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
-	receive_rdp->qlen += rdp->qlen;
-	receive_rdp->n_cbs_adopted += rdp->qlen;
-	rdp->n_cbs_orphaned += rdp->qlen;
+	/*
+	 * Finally, put the rest of the callbacks at the end of the list.
+	 * The ones that made it partway through get to start over:  We
+	 * cannot assume that grace periods are synchronized across CPUs.
+	 * (We could splice RCU_WAIT_TAIL into RCU_NEXT_READY_TAIL, but
+	 * this does not seem compelling.  Not yet, anyway.)
+	 */
+	if (rdp->nxtlist != NULL) {
+		*receive_rdp->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist;
+		receive_rdp->nxttail[RCU_NEXT_TAIL] =
+				rdp->nxttail[RCU_NEXT_TAIL];
+		receive_rdp->n_cbs_adopted += rdp->qlen;
+		rdp->n_cbs_orphaned += rdp->qlen;
+
+		rdp->nxtlist = NULL;
+		for (i = 0; i < RCU_NEXT_SIZE; i++)
+			rdp->nxttail[i] = &rdp->nxtlist;
+	}
 
-	rdp->nxtlist = NULL;
-	for (i = 0; i < RCU_NEXT_SIZE; i++)
-		rdp->nxttail[i] = &rdp->nxtlist;
-	rdp->qlen = 0;
+	/*
+	 * Record a quiescent state for the dying CPU.  This is safe
+	 * only because we have already cleared out the callbacks.
+	 * (Otherwise, the RCU core might try to schedule the invocation
+	 * of callbacks on this now-offline CPU, which would be bad.)
+	 */
+	mask = rdp->grpmask;	/* rnp->grplo is constant. */
+	trace_rcu_grace_period(rsp->name,
+			       rnp->gpnum + 1 - !!(rnp->qsmask & mask),
+			       "cpuofl");
+	rcu_report_qs_rdp(smp_processor_id(), rsp, rdp, rsp->gpnum);
+	/* Note that rcu_report_qs_rdp() might call trace_rcu_grace_period(). */
 }
 
 /*
- * Remove the outgoing CPU from the bitmasks in the rcu_node hierarchy
- * and move all callbacks from the outgoing CPU to the current one.
+ * The CPU has been completely removed, and some other CPU is reporting
+ * this fact from process context.  Do the remainder of the cleanup.
  * There can only be one CPU hotplug operation at a time, so no other
  * CPU can be attempting to update rcu_cpu_kthread_task.
  */
-static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
+static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
 {
 	unsigned long flags;
 	unsigned long mask;
 	int need_report = 0;
 	struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
-	struct rcu_node *rnp;
+	struct rcu_node *rnp = rdp->mynode;  /* Outgoing CPU's rnp. */
 
+	/* Adjust any no-longer-needed kthreads. */
 	rcu_stop_cpu_kthread(cpu);
+	rcu_node_kthread_setaffinity(rnp, -1);
+
+	/* Remove the dying CPU from the bitmasks in the rcu_node hierarchy. */
 
 	/* Exclude any attempts to start a new grace period. */
 	raw_spin_lock_irqsave(&rsp->onofflock, flags);
 
 	/* Remove the outgoing CPU from the masks in the rcu_node hierarchy. */
-	rnp = rdp->mynode;	/* this is the outgoing CPU's rnp. */
 	mask = rdp->grpmask;	/* rnp->grplo is constant. */
 	do {
 		raw_spin_lock(&rnp->lock);	/* irqs already disabled. */
@@ -1299,20 +1428,11 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
 		if (rnp->qsmaskinit != 0) {
 			if (rnp != rdp->mynode)
 				raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
-			else
-				trace_rcu_grace_period(rsp->name,
-						       rnp->gpnum + 1 -
-						       !!(rnp->qsmask & mask),
-						       "cpuofl");
 			break;
 		}
-		if (rnp == rdp->mynode) {
-			trace_rcu_grace_period(rsp->name,
-					       rnp->gpnum + 1 -
-					       !!(rnp->qsmask & mask),
-					       "cpuofl");
+		if (rnp == rdp->mynode)
 			need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
-		} else
+		else
 			raw_spin_unlock(&rnp->lock); /* irqs remain disabled. */
 		mask = rnp->grpmask;
 		rnp = rnp->parent;
@@ -1332,29 +1452,15 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
 		raw_spin_unlock_irqrestore(&rnp->lock, flags);
 	if (need_report & RCU_OFL_TASKS_EXP_GP)
 		rcu_report_exp_rnp(rsp, rnp, true);
-	rcu_node_kthread_setaffinity(rnp, -1);
-}
-
-/*
- * Remove the specified CPU from the RCU hierarchy and move any pending
- * callbacks that it might have to the current CPU.  This code assumes
- * that at least one CPU in the system will remain running at all times.
- * Any attempt to offline -all- CPUs is likely to strand RCU callbacks.
- */
-static void rcu_offline_cpu(int cpu)
-{
-	__rcu_offline_cpu(cpu, &rcu_sched_state);
-	__rcu_offline_cpu(cpu, &rcu_bh_state);
-	rcu_preempt_offline_cpu(cpu);
 }
 
 #else /* #ifdef CONFIG_HOTPLUG_CPU */
 
-static void rcu_send_cbs_to_online(struct rcu_state *rsp)
+static void rcu_cleanup_dying_cpu(struct rcu_state *rsp)
 {
 }
 
-static void rcu_offline_cpu(int cpu)
+static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp)
 {
 }
 
@@ -1368,11 +1474,11 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 {
 	unsigned long flags;
 	struct rcu_head *next, *list, **tail;
-	int bl, count;
+	int bl, count, count_lazy;
 
 	/* If no callbacks are ready, just return.*/
 	if (!cpu_has_callbacks_ready_to_invoke(rdp)) {
-		trace_rcu_batch_start(rsp->name, 0, 0);
+		trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, 0);
 		trace_rcu_batch_end(rsp->name, 0, !!ACCESS_ONCE(rdp->nxtlist),
 				    need_resched(), is_idle_task(current),
 				    rcu_is_callbacks_kthread());
@@ -1384,8 +1490,9 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 	 * races with call_rcu() from interrupt handlers.
 	 */
 	local_irq_save(flags);
+	WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
 	bl = rdp->blimit;
-	trace_rcu_batch_start(rsp->name, rdp->qlen, bl);
+	trace_rcu_batch_start(rsp->name, rdp->qlen_lazy, rdp->qlen, bl);
 	list = rdp->nxtlist;
 	rdp->nxtlist = *rdp->nxttail[RCU_DONE_TAIL];
 	*rdp->nxttail[RCU_DONE_TAIL] = NULL;
@@ -1396,12 +1503,13 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 	local_irq_restore(flags);
 
 	/* Invoke callbacks. */
-	count = 0;
+	count = count_lazy = 0;
 	while (list) {
 		next = list->next;
 		prefetch(next);
 		debug_rcu_head_unqueue(list);
-		__rcu_reclaim(rsp->name, list);
+		if (__rcu_reclaim(rsp->name, list))
+			count_lazy++;
 		list = next;
 		/* Stop only if limit reached and CPU has something to do. */
 		if (++count >= bl &&
@@ -1416,6 +1524,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 			    rcu_is_callbacks_kthread());
 
 	/* Update count, and requeue any remaining callbacks. */
+	rdp->qlen_lazy -= count_lazy;
 	rdp->qlen -= count;
 	rdp->n_cbs_invoked += count;
 	if (list != NULL) {
@@ -1458,6 +1567,7 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
 void rcu_check_callbacks(int cpu, int user)
 {
 	trace_rcu_utilization("Start scheduler-tick");
+	increment_cpu_stall_ticks();
 	if (user || rcu_is_cpu_rrupt_from_idle()) {
 
 		/*
@@ -1492,8 +1602,6 @@ void rcu_check_callbacks(int cpu, int user)
 	trace_rcu_utilization("End scheduler-tick");
 }
 
-#ifdef CONFIG_SMP
-
 /*
  * Scan the leaf rcu_node structures, processing dyntick state for any that
  * have not yet encountered a quiescent state, using the function specified.
@@ -1616,15 +1724,6 @@ unlock_fqs_ret:
 	trace_rcu_utilization("End fqs");
 }
 
-#else /* #ifdef CONFIG_SMP */
-
-static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
-{
-	set_need_resched();
-}
-
-#endif /* #else #ifdef CONFIG_SMP */
-
 /*
  * This does the RCU core processing work for the specified rcu_state
  * and rcu_data structures.  This may be called only from the CPU to
@@ -1702,11 +1801,12 @@ static void invoke_rcu_core(void)
 
 static void
 __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
-	   struct rcu_state *rsp)
+	   struct rcu_state *rsp, bool lazy)
 {
 	unsigned long flags;
 	struct rcu_data *rdp;
 
+	WARN_ON_ONCE((unsigned long)head & 0x3); /* Misaligned rcu_head! */
 	debug_rcu_head_queue(head);
 	head->func = func;
 	head->next = NULL;
@@ -1720,18 +1820,21 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
 	 * a quiescent state betweentimes.
 	 */
 	local_irq_save(flags);
+	WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
 	rdp = this_cpu_ptr(rsp->rda);
 
 	/* Add the callback to our list. */
 	*rdp->nxttail[RCU_NEXT_TAIL] = head;
 	rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
 	rdp->qlen++;
+	if (lazy)
+		rdp->qlen_lazy++;
 
 	if (__is_kfree_rcu_offset((unsigned long)func))
 		trace_rcu_kfree_callback(rsp->name, head, (unsigned long)func,
-					 rdp->qlen);
+					 rdp->qlen_lazy, rdp->qlen);
 	else
-		trace_rcu_callback(rsp->name, head, rdp->qlen);
+		trace_rcu_callback(rsp->name, head, rdp->qlen_lazy, rdp->qlen);
 
 	/* If interrupts were disabled, don't dive into RCU core. */
 	if (irqs_disabled_flags(flags)) {
@@ -1778,16 +1881,16 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
  */
 void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-	__call_rcu(head, func, &rcu_sched_state);
+	__call_rcu(head, func, &rcu_sched_state, 0);
 }
 EXPORT_SYMBOL_GPL(call_rcu_sched);
 
 /*
- * Queue an RCU for invocation after a quicker grace period.
+ * Queue an RCU callback for invocation after a quicker grace period.
  */
 void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-	__call_rcu(head, func, &rcu_bh_state);
+	__call_rcu(head, func, &rcu_bh_state, 0);
 }
 EXPORT_SYMBOL_GPL(call_rcu_bh);
 
@@ -1816,6 +1919,10 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
  */
 void synchronize_sched(void)
 {
+	rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+			   !lock_is_held(&rcu_lock_map) &&
+			   !lock_is_held(&rcu_sched_lock_map),
+			   "Illegal synchronize_sched() in RCU-sched read-side critical section");
 	if (rcu_blocking_is_gp())
 		return;
 	wait_rcu_gp(call_rcu_sched);
@@ -1833,12 +1940,137 @@ EXPORT_SYMBOL_GPL(synchronize_sched);
  */
 void synchronize_rcu_bh(void)
 {
+	rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+			   !lock_is_held(&rcu_lock_map) &&
+			   !lock_is_held(&rcu_sched_lock_map),
+			   "Illegal synchronize_rcu_bh() in RCU-bh read-side critical section");
 	if (rcu_blocking_is_gp())
 		return;
 	wait_rcu_gp(call_rcu_bh);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
 
+static atomic_t sync_sched_expedited_started = ATOMIC_INIT(0);
+static atomic_t sync_sched_expedited_done = ATOMIC_INIT(0);
+
+static int synchronize_sched_expedited_cpu_stop(void *data)
+{
+	/*
+	 * There must be a full memory barrier on each affected CPU
+	 * between the time that try_stop_cpus() is called and the
+	 * time that it returns.
+	 *
+	 * In the current initial implementation of cpu_stop, the
+	 * above condition is already met when the control reaches
+	 * this point and the following smp_mb() is not strictly
+	 * necessary.  Do smp_mb() anyway for documentation and
+	 * robustness against future implementation changes.
+	 */
+	smp_mb(); /* See above comment block. */
+	return 0;
+}
+
+/**
+ * synchronize_sched_expedited - Brute-force RCU-sched grace period
+ *
+ * Wait for an RCU-sched grace period to elapse, but use a "big hammer"
+ * approach to force the grace period to end quickly.  This consumes
+ * significant time on all CPUs and is unfriendly to real-time workloads,
+ * so is thus not recommended for any sort of common-case code.  In fact,
+ * if you are using synchronize_sched_expedited() in a loop, please
+ * restructure your code to batch your updates, and then use a single
+ * synchronize_sched() instead.
+ *
+ * Note that it is illegal to call this function while holding any lock
+ * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
+ * to call this function from a CPU-hotplug notifier.  Failing to observe
+ * these restriction will result in deadlock.
+ *
+ * This implementation can be thought of as an application of ticket
+ * locking to RCU, with sync_sched_expedited_started and
+ * sync_sched_expedited_done taking on the roles of the halves
+ * of the ticket-lock word.  Each task atomically increments
+ * sync_sched_expedited_started upon entry, snapshotting the old value,
+ * then attempts to stop all the CPUs.  If this succeeds, then each
+ * CPU will have executed a context switch, resulting in an RCU-sched
+ * grace period.  We are then done, so we use atomic_cmpxchg() to
+ * update sync_sched_expedited_done to match our snapshot -- but
+ * only if someone else has not already advanced past our snapshot.
+ *
+ * On the other hand, if try_stop_cpus() fails, we check the value
+ * of sync_sched_expedited_done.  If it has advanced past our
+ * initial snapshot, then someone else must have forced a grace period
+ * some time after we took our snapshot.  In this case, our work is
+ * done for us, and we can simply return.  Otherwise, we try again,
+ * but keep our initial snapshot for purposes of checking for someone
+ * doing our work for us.
+ *
+ * If we fail too many times in a row, we fall back to synchronize_sched().
+ */
+void synchronize_sched_expedited(void)
+{
+	int firstsnap, s, snap, trycount = 0;
+
+	/* Note that atomic_inc_return() implies full memory barrier. */
+	firstsnap = snap = atomic_inc_return(&sync_sched_expedited_started);
+	get_online_cpus();
+	WARN_ON_ONCE(cpu_is_offline(raw_smp_processor_id()));
+
+	/*
+	 * Each pass through the following loop attempts to force a
+	 * context switch on each CPU.
+	 */
+	while (try_stop_cpus(cpu_online_mask,
+			     synchronize_sched_expedited_cpu_stop,
+			     NULL) == -EAGAIN) {
+		put_online_cpus();
+
+		/* No joy, try again later.  Or just synchronize_sched(). */
+		if (trycount++ < 10)
+			udelay(trycount * num_online_cpus());
+		else {
+			synchronize_sched();
+			return;
+		}
+
+		/* Check to see if someone else did our work for us. */
+		s = atomic_read(&sync_sched_expedited_done);
+		if (UINT_CMP_GE((unsigned)s, (unsigned)firstsnap)) {
+			smp_mb(); /* ensure test happens before caller kfree */
+			return;
+		}
+
+		/*
+		 * Refetching sync_sched_expedited_started allows later
+		 * callers to piggyback on our grace period.  We subtract
+		 * 1 to get the same token that the last incrementer got.
+		 * We retry after they started, so our grace period works
+		 * for them, and they started after our first try, so their
+		 * grace period works for us.
+		 */
+		get_online_cpus();
+		snap = atomic_read(&sync_sched_expedited_started);
+		smp_mb(); /* ensure read is before try_stop_cpus(). */
+	}
+
+	/*
+	 * Everyone up to our most recent fetch is covered by our grace
+	 * period.  Update the counter, but only if our work is still
+	 * relevant -- which it won't be if someone who started later
+	 * than we did beat us to the punch.
+	 */
+	do {
+		s = atomic_read(&sync_sched_expedited_done);
+		if (UINT_CMP_GE((unsigned)s, (unsigned)snap)) {
+			smp_mb(); /* ensure test happens before caller kfree */
+			break;
+		}
+	} while (atomic_cmpxchg(&sync_sched_expedited_done, s, snap) != s);
+
+	put_online_cpus();
+}
+EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
+
 /*
  * Check to see if there is any immediate RCU-related work to be done
  * by the current CPU, for the specified type of RCU, returning 1 if so.
@@ -1932,7 +2164,7 @@ static int rcu_cpu_has_callbacks(int cpu)
 	/* RCU callbacks either ready or pending? */
 	return per_cpu(rcu_sched_data, cpu).nxtlist ||
 	       per_cpu(rcu_bh_data, cpu).nxtlist ||
-	       rcu_preempt_needs_cpu(cpu);
+	       rcu_preempt_cpu_has_callbacks(cpu);
 }
 
 static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
@@ -2027,9 +2259,10 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp)
 	rdp->nxtlist = NULL;
 	for (i = 0; i < RCU_NEXT_SIZE; i++)
 		rdp->nxttail[i] = &rdp->nxtlist;
+	rdp->qlen_lazy = 0;
 	rdp->qlen = 0;
 	rdp->dynticks = &per_cpu(rcu_dynticks, cpu);
-	WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_NESTING);
+	WARN_ON_ONCE(rdp->dynticks->dynticks_nesting != DYNTICK_TASK_EXIT_IDLE);
 	WARN_ON_ONCE(atomic_read(&rdp->dynticks->dynticks) != 1);
 	rdp->cpu = cpu;
 	rdp->rsp = rsp;
@@ -2057,7 +2290,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptible)
 	rdp->qlen_last_fqs_check = 0;
 	rdp->n_force_qs_snap = rsp->n_force_qs;
 	rdp->blimit = blimit;
-	rdp->dynticks->dynticks_nesting = DYNTICK_TASK_NESTING;
+	rdp->dynticks->dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 	atomic_set(&rdp->dynticks->dynticks,
 		   (atomic_read(&rdp->dynticks->dynticks) & ~0x1) + 1);
 	rcu_prepare_for_idle_init(cpu);
@@ -2139,16 +2372,18 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
 		 * touch any data without introducing corruption. We send the
 		 * dying CPU's callbacks to an arbitrarily chosen online CPU.
 		 */
-		rcu_send_cbs_to_online(&rcu_bh_state);
-		rcu_send_cbs_to_online(&rcu_sched_state);
-		rcu_preempt_send_cbs_to_online();
+		rcu_cleanup_dying_cpu(&rcu_bh_state);
+		rcu_cleanup_dying_cpu(&rcu_sched_state);
+		rcu_preempt_cleanup_dying_cpu();
 		rcu_cleanup_after_idle(cpu);
 		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 	case CPU_UP_CANCELED:
 	case CPU_UP_CANCELED_FROZEN:
-		rcu_offline_cpu(cpu);
+		rcu_cleanup_dead_cpu(cpu, &rcu_bh_state);
+		rcu_cleanup_dead_cpu(cpu, &rcu_sched_state);
+		rcu_preempt_cleanup_dead_cpu(cpu);
 		break;
 	default:
 		break;
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index fddff92..cdd1be0 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -239,6 +239,12 @@ struct rcu_data {
 	bool		preemptible;	/* Preemptible RCU? */
 	struct rcu_node *mynode;	/* This CPU's leaf of hierarchy */
 	unsigned long grpmask;		/* Mask to apply to leaf qsmask. */
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+	unsigned long	ticks_this_gp;	/* The number of scheduling-clock */
+					/*  ticks this CPU has handled */
+					/*  during and after the last grace */
+					/* period it is aware of. */
+#endif /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
 
 	/* 2) batch handling */
 	/*
@@ -265,7 +271,8 @@ struct rcu_data {
 	 */
 	struct rcu_head *nxtlist;
 	struct rcu_head **nxttail[RCU_NEXT_SIZE];
-	long		qlen;		/* # of queued callbacks */
+	long		qlen_lazy;	/* # of lazy queued callbacks */
+	long		qlen;		/* # of queued callbacks, incl lazy */
 	long		qlen_last_fqs_check;
 					/* qlen at last check for QS forcing */
 	unsigned long	n_cbs_invoked;	/* count of RCU cbs invoked. */
@@ -282,7 +289,6 @@ struct rcu_data {
 	/* 4) reasons this CPU needed to be kicked by force_quiescent_state */
 	unsigned long dynticks_fqs;	/* Kicked due to dynticks idle. */
 	unsigned long offline_fqs;	/* Kicked due to being offline. */
-	unsigned long resched_ipi;	/* Sent a resched IPI. */
 
 	/* 5) __rcu_pending() statistics. */
 	unsigned long n_rcu_pending;	/* rcu_pending() calls since boot. */
@@ -313,12 +319,6 @@ struct rcu_data {
 #else
 #define RCU_STALL_DELAY_DELTA	       0
 #endif
-
-#define RCU_SECONDS_TILL_STALL_CHECK   (CONFIG_RCU_CPU_STALL_TIMEOUT * HZ + \
-					RCU_STALL_DELAY_DELTA)
-						/* for rsp->jiffies_stall */
-#define RCU_SECONDS_TILL_STALL_RECHECK (3 * RCU_SECONDS_TILL_STALL_CHECK + 30)
-						/* for rsp->jiffies_stall */
 #define RCU_STALL_RAT_DELAY		2	/* Allow other CPUs time */
 						/*  to take at least one */
 						/*  scheduling clock irq */
@@ -438,8 +438,8 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
 static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
 				     struct rcu_node *rnp,
 				     struct rcu_data *rdp);
-static void rcu_preempt_offline_cpu(int cpu);
 #endif /* #ifdef CONFIG_HOTPLUG_CPU */
+static void rcu_preempt_cleanup_dead_cpu(int cpu);
 static void rcu_preempt_check_callbacks(int cpu);
 static void rcu_preempt_process_callbacks(void);
 void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
@@ -448,9 +448,9 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp,
 			       bool wake);
 #endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */
 static int rcu_preempt_pending(int cpu);
-static int rcu_preempt_needs_cpu(int cpu);
+static int rcu_preempt_cpu_has_callbacks(int cpu);
 static void __cpuinit rcu_preempt_init_percpu_data(int cpu);
-static void rcu_preempt_send_cbs_to_online(void);
+static void rcu_preempt_cleanup_dying_cpu(void);
 static void __init __rcu_init_preempt(void);
 static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags);
 static void rcu_preempt_boost_start_gp(struct rcu_node *rnp);
@@ -471,5 +471,10 @@ static void __cpuinit rcu_prepare_kthreads(int cpu);
 static void rcu_prepare_for_idle_init(int cpu);
 static void rcu_cleanup_after_idle(int cpu);
 static void rcu_prepare_for_idle(int cpu);
+static void print_cpu_stall_info_begin(void);
+static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
+static void print_cpu_stall_info_end(void);
+static void zero_cpu_stall_ticks(struct rcu_data *rdp);
+static void increment_cpu_stall_ticks(void);
 
 #endif /* #ifndef RCU_TREE_NONCORE */
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index 8bb35d7..c023464 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -25,7 +25,6 @@
  */
 
 #include <linux/delay.h>
-#include <linux/stop_machine.h>
 
 #define RCU_KTHREAD_PRIO 1
 
@@ -63,7 +62,10 @@ static void __init rcu_bootup_announce_oddness(void)
 	printk(KERN_INFO "\tRCU torture testing starts during boot.\n");
 #endif
 #if defined(CONFIG_TREE_PREEMPT_RCU) && !defined(CONFIG_RCU_CPU_STALL_VERBOSE)
-	printk(KERN_INFO "\tVerbose stalled-CPUs detection is disabled.\n");
+	printk(KERN_INFO "\tDump stacks of tasks blocking RCU-preempt GP.\n");
+#endif
+#if defined(CONFIG_RCU_CPU_STALL_INFO)
+	printk(KERN_INFO "\tAdditional per-CPU info printed with stalls.\n");
 #endif
 #if NUM_RCU_LVL_4 != 0
 	printk(KERN_INFO "\tExperimental four-level hierarchy is enabled.\n");
@@ -490,6 +492,31 @@ static void rcu_print_detail_task_stall(struct rcu_state *rsp)
 
 #endif /* #else #ifdef CONFIG_RCU_CPU_STALL_VERBOSE */
 
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+
+static void rcu_print_task_stall_begin(struct rcu_node *rnp)
+{
+	printk(KERN_ERR "\tTasks blocked on level-%d rcu_node (CPUs %d-%d):",
+	       rnp->level, rnp->grplo, rnp->grphi);
+}
+
+static void rcu_print_task_stall_end(void)
+{
+	printk(KERN_CONT "\n");
+}
+
+#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+static void rcu_print_task_stall_begin(struct rcu_node *rnp)
+{
+}
+
+static void rcu_print_task_stall_end(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
 /*
  * Scan the current list of tasks blocked within RCU read-side critical
  * sections, printing out the tid of each.
@@ -501,12 +528,14 @@ static int rcu_print_task_stall(struct rcu_node *rnp)
 
 	if (!rcu_preempt_blocked_readers_cgp(rnp))
 		return 0;
+	rcu_print_task_stall_begin(rnp);
 	t = list_entry(rnp->gp_tasks,
 		       struct task_struct, rcu_node_entry);
 	list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {
-		printk(" P%d", t->pid);
+		printk(KERN_CONT " P%d", t->pid);
 		ndetected++;
 	}
+	rcu_print_task_stall_end();
 	return ndetected;
 }
 
@@ -581,7 +610,7 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
 	 * absolutely necessary, but this is a good performance/complexity
 	 * tradeoff.
 	 */
-	if (rcu_preempt_blocked_readers_cgp(rnp))
+	if (rcu_preempt_blocked_readers_cgp(rnp) && rnp->qsmask == 0)
 		retval |= RCU_OFL_TASKS_NORM_GP;
 	if (rcu_preempted_readers_exp(rnp))
 		retval |= RCU_OFL_TASKS_EXP_GP;
@@ -618,16 +647,16 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
 	return retval;
 }
 
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
 /*
  * Do CPU-offline processing for preemptible RCU.
  */
-static void rcu_preempt_offline_cpu(int cpu)
+static void rcu_preempt_cleanup_dead_cpu(int cpu)
 {
-	__rcu_offline_cpu(cpu, &rcu_preempt_state);
+	rcu_cleanup_dead_cpu(cpu, &rcu_preempt_state);
 }
 
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-
 /*
  * Check for a quiescent state from the current CPU.  When a task blocks,
  * the task is recorded in the corresponding CPU's rcu_node structure,
@@ -671,10 +700,24 @@ static void rcu_preempt_do_callbacks(void)
  */
 void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-	__call_rcu(head, func, &rcu_preempt_state);
+	__call_rcu(head, func, &rcu_preempt_state, 0);
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
+/*
+ * Queue an RCU callback for lazy invocation after a grace period.
+ * This will likely be later named something like "call_rcu_lazy()",
+ * but this change will require some way of tagging the lazy RCU
+ * callbacks in the list of pending callbacks.  Until then, this
+ * function may only be called from __kfree_rcu().
+ */
+void kfree_call_rcu(struct rcu_head *head,
+		    void (*func)(struct rcu_head *rcu))
+{
+	__call_rcu(head, func, &rcu_preempt_state, 1);
+}
+EXPORT_SYMBOL_GPL(kfree_call_rcu);
+
 /**
  * synchronize_rcu - wait until a grace period has elapsed.
  *
@@ -688,6 +731,10 @@ EXPORT_SYMBOL_GPL(call_rcu);
  */
 void synchronize_rcu(void)
 {
+	rcu_lockdep_assert(!lock_is_held(&rcu_bh_lock_map) &&
+			   !lock_is_held(&rcu_lock_map) &&
+			   !lock_is_held(&rcu_sched_lock_map),
+			   "Illegal synchronize_rcu() in RCU read-side critical section");
 	if (!rcu_scheduler_active)
 		return;
 	wait_rcu_gp(call_rcu);
@@ -788,10 +835,22 @@ sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp)
 		rcu_report_exp_rnp(rsp, rnp, false); /* Don't wake self. */
 }
 
-/*
- * Wait for an rcu-preempt grace period, but expedite it.  The basic idea
- * is to invoke synchronize_sched_expedited() to push all the tasks to
- * the ->blkd_tasks lists and wait for this list to drain.
+/**
+ * synchronize_rcu_expedited - Brute-force RCU grace period
+ *
+ * Wait for an RCU-preempt grace period, but expedite it.  The basic
+ * idea is to invoke synchronize_sched_expedited() to push all the tasks to
+ * the ->blkd_tasks lists and wait for this list to drain.  This consumes
+ * significant time on all CPUs and is unfriendly to real-time workloads,
+ * so is thus not recommended for any sort of common-case code.
+ * In fact, if you are using synchronize_rcu_expedited() in a loop,
+ * please restructure your code to batch your updates, and then Use a
+ * single synchronize_rcu() instead.
+ *
+ * Note that it is illegal to call this function while holding any lock
+ * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
+ * to call this function from a CPU-hotplug notifier.  Failing to observe
+ * these restriction will result in deadlock.
  */
 void synchronize_rcu_expedited(void)
 {
@@ -869,9 +928,9 @@ static int rcu_preempt_pending(int cpu)
 }
 
 /*
- * Does preemptible RCU need the CPU to stay out of dynticks mode?
+ * Does preemptible RCU have callbacks on this CPU?
  */
-static int rcu_preempt_needs_cpu(int cpu)
+static int rcu_preempt_cpu_has_callbacks(int cpu)
 {
 	return !!per_cpu(rcu_preempt_data, cpu).nxtlist;
 }
@@ -894,11 +953,12 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu)
 }
 
 /*
- * Move preemptible RCU's callbacks from dying CPU to other online CPU.
+ * Move preemptible RCU's callbacks from dying CPU to other online CPU
+ * and record a quiescent state.
  */
-static void rcu_preempt_send_cbs_to_online(void)
+static void rcu_preempt_cleanup_dying_cpu(void)
 {
-	rcu_send_cbs_to_online(&rcu_preempt_state);
+	rcu_cleanup_dying_cpu(&rcu_preempt_state);
 }
 
 /*
@@ -1034,16 +1094,16 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
 	return 0;
 }
 
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
 /*
  * Because preemptible RCU does not exist, it never needs CPU-offline
  * processing.
  */
-static void rcu_preempt_offline_cpu(int cpu)
+static void rcu_preempt_cleanup_dead_cpu(int cpu)
 {
 }
 
-#endif /* #ifdef CONFIG_HOTPLUG_CPU */
-
 /*
  * Because preemptible RCU does not exist, it never has any callbacks
  * to check.
@@ -1061,6 +1121,22 @@ static void rcu_preempt_process_callbacks(void)
 }
 
 /*
+ * Queue an RCU callback for lazy invocation after a grace period.
+ * This will likely be later named something like "call_rcu_lazy()",
+ * but this change will require some way of tagging the lazy RCU
+ * callbacks in the list of pending callbacks.  Until then, this
+ * function may only be called from __kfree_rcu().
+ *
+ * Because there is no preemptible RCU, we use RCU-sched instead.
+ */
+void kfree_call_rcu(struct rcu_head *head,
+		    void (*func)(struct rcu_head *rcu))
+{
+	__call_rcu(head, func, &rcu_sched_state, 1);
+}
+EXPORT_SYMBOL_GPL(kfree_call_rcu);
+
+/*
  * Wait for an rcu-preempt grace period, but make it happen quickly.
  * But because preemptible RCU does not exist, map to rcu-sched.
  */
@@ -1093,9 +1169,9 @@ static int rcu_preempt_pending(int cpu)
 }
 
 /*
- * Because preemptible RCU does not exist, it never needs any CPU.
+ * Because preemptible RCU does not exist, it never has callbacks
  */
-static int rcu_preempt_needs_cpu(int cpu)
+static int rcu_preempt_cpu_has_callbacks(int cpu)
 {
 	return 0;
 }
@@ -1119,9 +1195,9 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu)
 }
 
 /*
- * Because there is no preemptible RCU, there are no callbacks to move.
+ * Because there is no preemptible RCU, there is no cleanup to do.
  */
-static void rcu_preempt_send_cbs_to_online(void)
+static void rcu_preempt_cleanup_dying_cpu(void)
 {
 }
 
@@ -1823,132 +1899,6 @@ static void __cpuinit rcu_prepare_kthreads(int cpu)
 
 #endif /* #else #ifdef CONFIG_RCU_BOOST */
 
-#ifndef CONFIG_SMP
-
-void synchronize_sched_expedited(void)
-{
-	cond_resched();
-}
-EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
-
-#else /* #ifndef CONFIG_SMP */
-
-static atomic_t sync_sched_expedited_started = ATOMIC_INIT(0);
-static atomic_t sync_sched_expedited_done = ATOMIC_INIT(0);
-
-static int synchronize_sched_expedited_cpu_stop(void *data)
-{
-	/*
-	 * There must be a full memory barrier on each affected CPU
-	 * between the time that try_stop_cpus() is called and the
-	 * time that it returns.
-	 *
-	 * In the current initial implementation of cpu_stop, the
-	 * above condition is already met when the control reaches
-	 * this point and the following smp_mb() is not strictly
-	 * necessary.  Do smp_mb() anyway for documentation and
-	 * robustness against future implementation changes.
-	 */
-	smp_mb(); /* See above comment block. */
-	return 0;
-}
-
-/*
- * Wait for an rcu-sched grace period to elapse, but use "big hammer"
- * approach to force grace period to end quickly.  This consumes
- * significant time on all CPUs, and is thus not recommended for
- * any sort of common-case code.
- *
- * Note that it is illegal to call this function while holding any
- * lock that is acquired by a CPU-hotplug notifier.  Failing to
- * observe this restriction will result in deadlock.
- *
- * This implementation can be thought of as an application of ticket
- * locking to RCU, with sync_sched_expedited_started and
- * sync_sched_expedited_done taking on the roles of the halves
- * of the ticket-lock word.  Each task atomically increments
- * sync_sched_expedited_started upon entry, snapshotting the old value,
- * then attempts to stop all the CPUs.  If this succeeds, then each
- * CPU will have executed a context switch, resulting in an RCU-sched
- * grace period.  We are then done, so we use atomic_cmpxchg() to
- * update sync_sched_expedited_done to match our snapshot -- but
- * only if someone else has not already advanced past our snapshot.
- *
- * On the other hand, if try_stop_cpus() fails, we check the value
- * of sync_sched_expedited_done.  If it has advanced past our
- * initial snapshot, then someone else must have forced a grace period
- * some time after we took our snapshot.  In this case, our work is
- * done for us, and we can simply return.  Otherwise, we try again,
- * but keep our initial snapshot for purposes of checking for someone
- * doing our work for us.
- *
- * If we fail too many times in a row, we fall back to synchronize_sched().
- */
-void synchronize_sched_expedited(void)
-{
-	int firstsnap, s, snap, trycount = 0;
-
-	/* Note that atomic_inc_return() implies full memory barrier. */
-	firstsnap = snap = atomic_inc_return(&sync_sched_expedited_started);
-	get_online_cpus();
-
-	/*
-	 * Each pass through the following loop attempts to force a
-	 * context switch on each CPU.
-	 */
-	while (try_stop_cpus(cpu_online_mask,
-			     synchronize_sched_expedited_cpu_stop,
-			     NULL) == -EAGAIN) {
-		put_online_cpus();
-
-		/* No joy, try again later.  Or just synchronize_sched(). */
-		if (trycount++ < 10)
-			udelay(trycount * num_online_cpus());
-		else {
-			synchronize_sched();
-			return;
-		}
-
-		/* Check to see if someone else did our work for us. */
-		s = atomic_read(&sync_sched_expedited_done);
-		if (UINT_CMP_GE((unsigned)s, (unsigned)firstsnap)) {
-			smp_mb(); /* ensure test happens before caller kfree */
-			return;
-		}
-
-		/*
-		 * Refetching sync_sched_expedited_started allows later
-		 * callers to piggyback on our grace period.  We subtract
-		 * 1 to get the same token that the last incrementer got.
-		 * We retry after they started, so our grace period works
-		 * for them, and they started after our first try, so their
-		 * grace period works for us.
-		 */
-		get_online_cpus();
-		snap = atomic_read(&sync_sched_expedited_started);
-		smp_mb(); /* ensure read is before try_stop_cpus(). */
-	}
-
-	/*
-	 * Everyone up to our most recent fetch is covered by our grace
-	 * period.  Update the counter, but only if our work is still
-	 * relevant -- which it won't be if someone who started later
-	 * than we did beat us to the punch.
-	 */
-	do {
-		s = atomic_read(&sync_sched_expedited_done);
-		if (UINT_CMP_GE((unsigned)s, (unsigned)snap)) {
-			smp_mb(); /* ensure test happens before caller kfree */
-			break;
-		}
-	} while (atomic_cmpxchg(&sync_sched_expedited_done, s, snap) != s);
-
-	put_online_cpus();
-}
-EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
-
-#endif /* #else #ifndef CONFIG_SMP */
-
 #if !defined(CONFIG_RCU_FAST_NO_HZ)
 
 /*
@@ -1981,7 +1931,7 @@ static void rcu_cleanup_after_idle(int cpu)
 }
 
 /*
- * Do the idle-entry grace-period work, which, because CONFIG_RCU_FAST_NO_HZ=y,
+ * Do the idle-entry grace-period work, which, because CONFIG_RCU_FAST_NO_HZ=n,
  * is nothing.
  */
 static void rcu_prepare_for_idle(int cpu)
@@ -2015,6 +1965,9 @@ static void rcu_prepare_for_idle(int cpu)
  *	number, be warned: Setting RCU_IDLE_GP_DELAY too high can hang your
  *	system.  And if you are -that- concerned about energy efficiency,
  *	just power the system down and be done with it!
+ * RCU_IDLE_LAZY_GP_DELAY gives the number of jiffies that a CPU is
+ *	permitted to sleep in dyntick-idle mode with only lazy RCU
+ *	callbacks pending.  Setting this too high can OOM your system.
  *
  * The values below work well in practice.  If future workloads require
  * adjustment, they can be converted into kernel config parameters, though
@@ -2023,11 +1976,13 @@ static void rcu_prepare_for_idle(int cpu)
 #define RCU_IDLE_FLUSHES 5		/* Number of dyntick-idle tries. */
 #define RCU_IDLE_OPT_FLUSHES 3		/* Optional dyntick-idle tries. */
 #define RCU_IDLE_GP_DELAY 6		/* Roughly one grace period. */
+#define RCU_IDLE_LAZY_GP_DELAY (6 * HZ)	/* Roughly six seconds. */
 
 static DEFINE_PER_CPU(int, rcu_dyntick_drain);
 static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff);
 static DEFINE_PER_CPU(struct hrtimer, rcu_idle_gp_timer);
-static ktime_t rcu_idle_gp_wait;
+static ktime_t rcu_idle_gp_wait;	/* If some non-lazy callbacks. */
+static ktime_t rcu_idle_lazy_gp_wait;	/* If only lazy callbacks. */
 
 /*
  * Allow the CPU to enter dyntick-idle mode if either: (1) There are no
@@ -2048,6 +2003,48 @@ int rcu_needs_cpu(int cpu)
 }
 
 /*
+ * Does the specified flavor of RCU have non-lazy callbacks pending on
+ * the specified CPU?  Both RCU flavor and CPU are specified by the
+ * rcu_data structure.
+ */
+static bool __rcu_cpu_has_nonlazy_callbacks(struct rcu_data *rdp)
+{
+	return rdp->qlen != rdp->qlen_lazy;
+}
+
+#ifdef CONFIG_TREE_PREEMPT_RCU
+
+/*
+ * Are there non-lazy RCU-preempt callbacks?  (There cannot be if there
+ * is no RCU-preempt in the kernel.)
+ */
+static bool rcu_preempt_cpu_has_nonlazy_callbacks(int cpu)
+{
+	struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
+
+	return __rcu_cpu_has_nonlazy_callbacks(rdp);
+}
+
+#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+
+static bool rcu_preempt_cpu_has_nonlazy_callbacks(int cpu)
+{
+	return 0;
+}
+
+#endif /* else #ifdef CONFIG_TREE_PREEMPT_RCU */
+
+/*
+ * Does any flavor of RCU have non-lazy callbacks on the specified CPU?
+ */
+static bool rcu_cpu_has_nonlazy_callbacks(int cpu)
+{
+	return __rcu_cpu_has_nonlazy_callbacks(&per_cpu(rcu_sched_data, cpu)) ||
+	       __rcu_cpu_has_nonlazy_callbacks(&per_cpu(rcu_bh_data, cpu)) ||
+	       rcu_preempt_cpu_has_nonlazy_callbacks(cpu);
+}
+
+/*
  * Timer handler used to force CPU to start pushing its remaining RCU
  * callbacks in the case where it entered dyntick-idle mode with callbacks
  * pending.  The hander doesn't really need to do anything because the
@@ -2074,6 +2071,8 @@ static void rcu_prepare_for_idle_init(int cpu)
 		unsigned int upj = jiffies_to_usecs(RCU_IDLE_GP_DELAY);
 
 		rcu_idle_gp_wait = ns_to_ktime(upj * (u64)1000);
+		upj = jiffies_to_usecs(RCU_IDLE_LAZY_GP_DELAY);
+		rcu_idle_lazy_gp_wait = ns_to_ktime(upj * (u64)1000);
 		firsttime = 0;
 	}
 }
@@ -2109,10 +2108,6 @@ static void rcu_cleanup_after_idle(int cpu)
  */
 static void rcu_prepare_for_idle(int cpu)
 {
-	unsigned long flags;
-
-	local_irq_save(flags);
-
 	/*
 	 * If there are no callbacks on this CPU, enter dyntick-idle mode.
 	 * Also reset state to avoid prejudicing later attempts.
@@ -2120,7 +2115,6 @@ static void rcu_prepare_for_idle(int cpu)
 	if (!rcu_cpu_has_callbacks(cpu)) {
 		per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
 		per_cpu(rcu_dyntick_drain, cpu) = 0;
-		local_irq_restore(flags);
 		trace_rcu_prep_idle("No callbacks");
 		return;
 	}
@@ -2130,7 +2124,6 @@ static void rcu_prepare_for_idle(int cpu)
 	 * refrained from disabling the scheduling-clock tick.
 	 */
 	if (per_cpu(rcu_dyntick_holdoff, cpu) == jiffies) {
-		local_irq_restore(flags);
 		trace_rcu_prep_idle("In holdoff");
 		return;
 	}
@@ -2140,18 +2133,22 @@ static void rcu_prepare_for_idle(int cpu)
 		/* First time through, initialize the counter. */
 		per_cpu(rcu_dyntick_drain, cpu) = RCU_IDLE_FLUSHES;
 	} else if (per_cpu(rcu_dyntick_drain, cpu) <= RCU_IDLE_OPT_FLUSHES &&
-		   !rcu_pending(cpu)) {
+		   !rcu_pending(cpu) &&
+		   !local_softirq_pending()) {
 		/* Can we go dyntick-idle despite still having callbacks? */
 		trace_rcu_prep_idle("Dyntick with callbacks");
 		per_cpu(rcu_dyntick_drain, cpu) = 0;
-		per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
-		hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu),
-			      rcu_idle_gp_wait, HRTIMER_MODE_REL);
+		per_cpu(rcu_dyntick_holdoff, cpu) = jiffies;
+		if (rcu_cpu_has_nonlazy_callbacks(cpu))
+			hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu),
+				      rcu_idle_gp_wait, HRTIMER_MODE_REL);
+		else
+			hrtimer_start(&per_cpu(rcu_idle_gp_timer, cpu),
+				      rcu_idle_lazy_gp_wait, HRTIMER_MODE_REL);
 		return; /* Nothing more to do immediately. */
 	} else if (--per_cpu(rcu_dyntick_drain, cpu) <= 0) {
 		/* We have hit the limit, so time to give up. */
 		per_cpu(rcu_dyntick_holdoff, cpu) = jiffies;
-		local_irq_restore(flags);
 		trace_rcu_prep_idle("Begin holdoff");
 		invoke_rcu_core();  /* Force the CPU out of dyntick-idle. */
 		return;
@@ -2163,23 +2160,17 @@ static void rcu_prepare_for_idle(int cpu)
 	 */
 #ifdef CONFIG_TREE_PREEMPT_RCU
 	if (per_cpu(rcu_preempt_data, cpu).nxtlist) {
-		local_irq_restore(flags);
 		rcu_preempt_qs(cpu);
 		force_quiescent_state(&rcu_preempt_state, 0);
-		local_irq_save(flags);
 	}
 #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
 	if (per_cpu(rcu_sched_data, cpu).nxtlist) {
-		local_irq_restore(flags);
 		rcu_sched_qs(cpu);
 		force_quiescent_state(&rcu_sched_state, 0);
-		local_irq_save(flags);
 	}
 	if (per_cpu(rcu_bh_data, cpu).nxtlist) {
-		local_irq_restore(flags);
 		rcu_bh_qs(cpu);
 		force_quiescent_state(&rcu_bh_state, 0);
-		local_irq_save(flags);
 	}
 
 	/*
@@ -2187,13 +2178,124 @@ static void rcu_prepare_for_idle(int cpu)
 	 * So try forcing the callbacks through the grace period.
 	 */
 	if (rcu_cpu_has_callbacks(cpu)) {
-		local_irq_restore(flags);
 		trace_rcu_prep_idle("More callbacks");
 		invoke_rcu_core();
-	} else {
-		local_irq_restore(flags);
+	} else
 		trace_rcu_prep_idle("Callbacks drained");
-	}
 }
 
 #endif /* #else #if !defined(CONFIG_RCU_FAST_NO_HZ) */
+
+#ifdef CONFIG_RCU_CPU_STALL_INFO
+
+#ifdef CONFIG_RCU_FAST_NO_HZ
+
+static void print_cpu_stall_fast_no_hz(char *cp, int cpu)
+{
+	struct hrtimer *hrtp = &per_cpu(rcu_idle_gp_timer, cpu);
+
+	sprintf(cp, "drain=%d %c timer=%lld",
+		per_cpu(rcu_dyntick_drain, cpu),
+		per_cpu(rcu_dyntick_holdoff, cpu) == jiffies ? 'H' : '.',
+		hrtimer_active(hrtp)
+			? ktime_to_us(hrtimer_get_remaining(hrtp))
+			: -1);
+}
+
+#else /* #ifdef CONFIG_RCU_FAST_NO_HZ */
+
+static void print_cpu_stall_fast_no_hz(char *cp, int cpu)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_FAST_NO_HZ */
+
+/* Initiate the stall-info list. */
+static void print_cpu_stall_info_begin(void)
+{
+	printk(KERN_CONT "\n");
+}
+
+/*
+ * Print out diagnostic information for the specified stalled CPU.
+ *
+ * If the specified CPU is aware of the current RCU grace period
+ * (flavor specified by rsp), then print the number of scheduling
+ * clock interrupts the CPU has taken during the time that it has
+ * been aware.  Otherwise, print the number of RCU grace periods
+ * that this CPU is ignorant of, for example, "1" if the CPU was
+ * aware of the previous grace period.
+ *
+ * Also print out idle and (if CONFIG_RCU_FAST_NO_HZ) idle-entry info.
+ */
+static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
+{
+	char fast_no_hz[72];
+	struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
+	struct rcu_dynticks *rdtp = rdp->dynticks;
+	char *ticks_title;
+	unsigned long ticks_value;
+
+	if (rsp->gpnum == rdp->gpnum) {
+		ticks_title = "ticks this GP";
+		ticks_value = rdp->ticks_this_gp;
+	} else {
+		ticks_title = "GPs behind";
+		ticks_value = rsp->gpnum - rdp->gpnum;
+	}
+	print_cpu_stall_fast_no_hz(fast_no_hz, cpu);
+	printk(KERN_ERR "\t%d: (%lu %s) idle=%03x/%llx/%d %s\n",
+	       cpu, ticks_value, ticks_title,
+	       atomic_read(&rdtp->dynticks) & 0xfff,
+	       rdtp->dynticks_nesting, rdtp->dynticks_nmi_nesting,
+	       fast_no_hz);
+}
+
+/* Terminate the stall-info list. */
+static void print_cpu_stall_info_end(void)
+{
+	printk(KERN_ERR "\t");
+}
+
+/* Zero ->ticks_this_gp for all flavors of RCU. */
+static void zero_cpu_stall_ticks(struct rcu_data *rdp)
+{
+	rdp->ticks_this_gp = 0;
+}
+
+/* Increment ->ticks_this_gp for all flavors of RCU. */
+static void increment_cpu_stall_ticks(void)
+{
+	__get_cpu_var(rcu_sched_data).ticks_this_gp++;
+	__get_cpu_var(rcu_bh_data).ticks_this_gp++;
+#ifdef CONFIG_TREE_PREEMPT_RCU
+	__get_cpu_var(rcu_preempt_data).ticks_this_gp++;
+#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+}
+
+#else /* #ifdef CONFIG_RCU_CPU_STALL_INFO */
+
+static void print_cpu_stall_info_begin(void)
+{
+	printk(KERN_CONT " {");
+}
+
+static void print_cpu_stall_info(struct rcu_state *rsp, int cpu)
+{
+	printk(KERN_CONT " %d", cpu);
+}
+
+static void print_cpu_stall_info_end(void)
+{
+	printk(KERN_CONT "} ");
+}
+
+static void zero_cpu_stall_ticks(struct rcu_data *rdp)
+{
+}
+
+static void increment_cpu_stall_ticks(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index 654cfe6..ed459ed 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -72,9 +72,9 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp)
 		   rdp->dynticks->dynticks_nesting,
 		   rdp->dynticks->dynticks_nmi_nesting,
 		   rdp->dynticks_fqs);
-	seq_printf(m, " of=%lu ri=%lu", rdp->offline_fqs, rdp->resched_ipi);
-	seq_printf(m, " ql=%ld qs=%c%c%c%c",
-		   rdp->qlen,
+	seq_printf(m, " of=%lu", rdp->offline_fqs);
+	seq_printf(m, " ql=%ld/%ld qs=%c%c%c%c",
+		   rdp->qlen_lazy, rdp->qlen,
 		   ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
 			rdp->nxttail[RCU_NEXT_TAIL]],
 		   ".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
@@ -144,8 +144,8 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp)
 		   rdp->dynticks->dynticks_nesting,
 		   rdp->dynticks->dynticks_nmi_nesting,
 		   rdp->dynticks_fqs);
-	seq_printf(m, ",%lu,%lu", rdp->offline_fqs, rdp->resched_ipi);
-	seq_printf(m, ",%ld,\"%c%c%c%c\"", rdp->qlen,
+	seq_printf(m, ",%lu", rdp->offline_fqs);
+	seq_printf(m, ",%ld,%ld,\"%c%c%c%c\"", rdp->qlen_lazy, rdp->qlen,
 		   ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] !=
 			rdp->nxttail[RCU_NEXT_TAIL]],
 		   ".R"[rdp->nxttail[RCU_WAIT_TAIL] !=
@@ -168,7 +168,7 @@ static int show_rcudata_csv(struct seq_file *m, void *unused)
 {
 	seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pgp\",\"pq\",");
 	seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\",");
-	seq_puts(m, "\"of\",\"ri\",\"ql\",\"qs\"");
+	seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\"");
 #ifdef CONFIG_RCU_BOOST
 	seq_puts(m, "\"kt\",\"ktl\"");
 #endif /* #ifdef CONFIG_RCU_BOOST */
diff --git a/kernel/resource.c b/kernel/resource.c
index 7640b3a..7e8ea66 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -749,6 +749,7 @@ int adjust_resource(struct resource *res, resource_size_t start, resource_size_t
 	write_unlock(&resource_lock);
 	return result;
 }
+EXPORT_SYMBOL(adjust_resource);
 
 static void __init __reserve_region_with_split(struct resource *root,
 		resource_size_t start, resource_size_t end,
@@ -792,8 +793,6 @@ void __init reserve_region_with_split(struct resource *root,
 	write_unlock(&resource_lock);
 }
 
-EXPORT_SYMBOL(adjust_resource);
-
 /**
  * resource_alignment - calculate resource's alignment
  * @res: resource pointer
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5255c9d..a55ce41 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -71,6 +71,7 @@
 #include <linux/ftrace.h>
 #include <linux/slab.h>
 #include <linux/init_task.h>
+#include <linux/binfmts.h>
 
 #include <asm/tlb.h>
 #include <asm/irq_regs.h>
@@ -1507,7 +1508,7 @@ static int ttwu_activate_remote(struct task_struct *p, int wake_flags)
 }
 #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
 
-static inline int ttwu_share_cache(int this_cpu, int that_cpu)
+bool cpus_share_cache(int this_cpu, int that_cpu)
 {
 	return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
 }
@@ -1518,7 +1519,7 @@ static void ttwu_queue(struct task_struct *p, int cpu)
 	struct rq *rq = cpu_rq(cpu);
 
 #if defined(CONFIG_SMP)
-	if (sched_feat(TTWU_QUEUE) && !ttwu_share_cache(smp_processor_id(), cpu)) {
+	if (sched_feat(TTWU_QUEUE) && !cpus_share_cache(smp_processor_id(), cpu)) {
 		sched_clock_cpu(cpu); /* sync clocks x-cpu */
 		ttwu_queue_remote(p, cpu);
 		return;
@@ -5754,7 +5755,7 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu)
  *
  * Also keep a unique ID per domain (we use the first cpu number in
  * the cpumask of the domain), this allows us to quickly tell if
- * two cpus are in the same cache domain, see ttwu_share_cache().
+ * two cpus are in the same cache domain, see cpus_share_cache().
  */
 DEFINE_PER_CPU(struct sched_domain *, sd_llc);
 DEFINE_PER_CPU(int, sd_llc_id);
@@ -7525,8 +7526,7 @@ static inline struct task_group *cgroup_tg(struct cgroup *cgrp)
 			    struct task_group, css);
 }
 
-static struct cgroup_subsys_state *
-cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
+static struct cgroup_subsys_state *cpu_cgroup_create(struct cgroup *cgrp)
 {
 	struct task_group *tg, *parent;
 
@@ -7543,15 +7543,14 @@ cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
 	return &tg->css;
 }
 
-static void
-cpu_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
+static void cpu_cgroup_destroy(struct cgroup *cgrp)
 {
 	struct task_group *tg = cgroup_tg(cgrp);
 
 	sched_destroy_group(tg);
 }
 
-static int cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
+static int cpu_cgroup_can_attach(struct cgroup *cgrp,
 				 struct cgroup_taskset *tset)
 {
 	struct task_struct *task;
@@ -7569,7 +7568,7 @@ static int cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 	return 0;
 }
 
-static void cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
+static void cpu_cgroup_attach(struct cgroup *cgrp,
 			      struct cgroup_taskset *tset)
 {
 	struct task_struct *task;
@@ -7579,8 +7578,8 @@ static void cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 }
 
 static void
-cpu_cgroup_exit(struct cgroup_subsys *ss, struct cgroup *cgrp,
-		struct cgroup *old_cgrp, struct task_struct *task)
+cpu_cgroup_exit(struct cgroup *cgrp, struct cgroup *old_cgrp,
+		struct task_struct *task)
 {
 	/*
 	 * cgroup_exit() is called in the copy_process() failure path.
@@ -7930,8 +7929,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {
  */
 
 /* create a new cpu accounting group */
-static struct cgroup_subsys_state *cpuacct_create(
-	struct cgroup_subsys *ss, struct cgroup *cgrp)
+static struct cgroup_subsys_state *cpuacct_create(struct cgroup *cgrp)
 {
 	struct cpuacct *ca;
 
@@ -7961,8 +7959,7 @@ out:
 }
 
 /* destroy an existing cpu accounting group */
-static void
-cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
+static void cpuacct_destroy(struct cgroup *cgrp)
 {
 	struct cpuacct *ca = cgroup_ca(cgrp);
 
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 2a075e1..09acaa1 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -288,7 +288,6 @@ static void print_cpu(struct seq_file *m, int cpu)
 
 	P(yld_count);
 
-	P(sched_switch);
 	P(sched_count);
 	P(sched_goidle);
 #ifdef CONFIG_SMP
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7c6414f..4ab60a2 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -3084,6 +3084,8 @@ static bool yield_to_task_fair(struct rq *rq, struct task_struct *p, bool preemp
  * Fair scheduling class load-balancing methods:
  */
 
+static unsigned long __read_mostly max_load_balance_interval = HZ/10;
+
 /*
  * pull_task - move a task from a remote runqueue to the local runqueue.
  * Both runqueues must be locked.
@@ -3776,6 +3778,11 @@ void update_group_power(struct sched_domain *sd, int cpu)
 	struct sched_domain *child = sd->child;
 	struct sched_group *group, *sdg = sd->groups;
 	unsigned long power;
+	unsigned long interval;
+
+	interval = msecs_to_jiffies(sd->balance_interval);
+	interval = clamp(interval, 1UL, max_load_balance_interval);
+	sdg->sgp->next_update = jiffies + interval;
 
 	if (!child) {
 		update_cpu_power(sd, cpu);
@@ -3883,12 +3890,15 @@ static inline void update_sg_lb_stats(struct sched_domain *sd,
 	 * domains. In the newly idle case, we will allow all the cpu's
 	 * to do the newly idle load balance.
 	 */
-	if (idle != CPU_NEWLY_IDLE && local_group) {
-		if (balance_cpu != this_cpu) {
-			*balance = 0;
-			return;
-		}
-		update_group_power(sd, this_cpu);
+	if (local_group) {
+		if (idle != CPU_NEWLY_IDLE) {
+			if (balance_cpu != this_cpu) {
+				*balance = 0;
+				return;
+			}
+			update_group_power(sd, this_cpu);
+		} else if (time_after_eq(jiffies, group->sgp->next_update))
+			update_group_power(sd, this_cpu);
 	}
 
 	/* Adjust by relative CPU power of the group */
@@ -4945,8 +4955,6 @@ static int __cpuinit sched_ilb_notifier(struct notifier_block *nfb,
 
 static DEFINE_SPINLOCK(balancing);
 
-static unsigned long __read_mostly max_load_balance_interval = HZ/10;
-
 /*
  * Scale the max load_balance interval with the number of CPUs in the system.
  * This trades load-balance latency on larger machines for less cross talk.
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 98c0c26..8a2c768 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -462,7 +462,6 @@ struct rq {
 	unsigned int yld_count;
 
 	/* schedule() stats */
-	unsigned int sched_switch;
 	unsigned int sched_count;
 	unsigned int sched_goidle;
 
diff --git a/kernel/sched/stats.c b/kernel/sched/stats.c
index 2a581ba..903ffa9e 100644
--- a/kernel/sched/stats.c
+++ b/kernel/sched/stats.c
@@ -32,9 +32,9 @@ static int show_schedstat(struct seq_file *seq, void *v)
 
 		/* runqueue-specific stats */
 		seq_printf(seq,
-		    "cpu%d %u %u %u %u %u %u %llu %llu %lu",
+		    "cpu%d %u 0 %u %u %u %u %llu %llu %lu",
 		    cpu, rq->yld_count,
-		    rq->sched_switch, rq->sched_count, rq->sched_goidle,
+		    rq->sched_count, rq->sched_goidle,
 		    rq->ttwu_count, rq->ttwu_local,
 		    rq->rq_cpu_time,
 		    rq->rq_sched_info.run_delay, rq->rq_sched_info.pcount);
diff --git a/kernel/signal.c b/kernel/signal.c
index c73c428..ff06cf8 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -58,21 +58,20 @@ static int sig_handler_ignored(void __user *handler, int sig)
 		(handler == SIG_DFL && sig_kernel_ignore(sig));
 }
 
-static int sig_task_ignored(struct task_struct *t, int sig,
-		int from_ancestor_ns)
+static int sig_task_ignored(struct task_struct *t, int sig, bool force)
 {
 	void __user *handler;
 
 	handler = sig_handler(t, sig);
 
 	if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) &&
-			handler == SIG_DFL && !from_ancestor_ns)
+			handler == SIG_DFL && !force)
 		return 1;
 
 	return sig_handler_ignored(handler, sig);
 }
 
-static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns)
+static int sig_ignored(struct task_struct *t, int sig, bool force)
 {
 	/*
 	 * Blocked signals are never ignored, since the
@@ -82,7 +81,7 @@ static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns)
 	if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
 		return 0;
 
-	if (!sig_task_ignored(t, sig, from_ancestor_ns))
+	if (!sig_task_ignored(t, sig, force))
 		return 0;
 
 	/*
@@ -855,7 +854,7 @@ static void ptrace_trap_notify(struct task_struct *t)
  * Returns true if the signal should be actually delivered, otherwise
  * it should be dropped.
  */
-static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
+static int prepare_signal(int sig, struct task_struct *p, bool force)
 {
 	struct signal_struct *signal = p->signal;
 	struct task_struct *t;
@@ -915,7 +914,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns)
 		}
 	}
 
-	return !sig_ignored(p, sig, from_ancestor_ns);
+	return !sig_ignored(p, sig, force);
 }
 
 /*
@@ -1054,13 +1053,14 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
 	struct sigpending *pending;
 	struct sigqueue *q;
 	int override_rlimit;
-
-	trace_signal_generate(sig, info, t);
+	int ret = 0, result;
 
 	assert_spin_locked(&t->sighand->siglock);
 
-	if (!prepare_signal(sig, t, from_ancestor_ns))
-		return 0;
+	result = TRACE_SIGNAL_IGNORED;
+	if (!prepare_signal(sig, t,
+			from_ancestor_ns || (info == SEND_SIG_FORCED)))
+		goto ret;
 
 	pending = group ? &t->signal->shared_pending : &t->pending;
 	/*
@@ -1068,8 +1068,11 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
 	 * exactly one non-rt signal, so that we can get more
 	 * detailed information about the cause of the signal.
 	 */
+	result = TRACE_SIGNAL_ALREADY_PENDING;
 	if (legacy_queue(pending, sig))
-		return 0;
+		goto ret;
+
+	result = TRACE_SIGNAL_DELIVERED;
 	/*
 	 * fast-pathed signals for kernel-internal things like SIGSTOP
 	 * or SIGKILL.
@@ -1127,14 +1130,15 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
 			 * signal was rt and sent by user using something
 			 * other than kill().
 			 */
-			trace_signal_overflow_fail(sig, group, info);
-			return -EAGAIN;
+			result = TRACE_SIGNAL_OVERFLOW_FAIL;
+			ret = -EAGAIN;
+			goto ret;
 		} else {
 			/*
 			 * This is a silent loss of information.  We still
 			 * send the signal, but the *info bits are lost.
 			 */
-			trace_signal_lose_info(sig, group, info);
+			result = TRACE_SIGNAL_LOSE_INFO;
 		}
 	}
 
@@ -1142,7 +1146,9 @@ out_set:
 	signalfd_notify(t, sig);
 	sigaddset(&pending->signal, sig);
 	complete_signal(sig, t, group);
-	return 0;
+ret:
+	trace_signal_generate(sig, info, t, group, result);
+	return ret;
 }
 
 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
@@ -1585,7 +1591,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
 	int sig = q->info.si_signo;
 	struct sigpending *pending;
 	unsigned long flags;
-	int ret;
+	int ret, result;
 
 	BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
 
@@ -1594,7 +1600,8 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
 		goto ret;
 
 	ret = 1; /* the signal is ignored */
-	if (!prepare_signal(sig, t, 0))
+	result = TRACE_SIGNAL_IGNORED;
+	if (!prepare_signal(sig, t, false))
 		goto out;
 
 	ret = 0;
@@ -1605,6 +1612,7 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
 		 */
 		BUG_ON(q->info.si_code != SI_TIMER);
 		q->info.si_overrun++;
+		result = TRACE_SIGNAL_ALREADY_PENDING;
 		goto out;
 	}
 	q->info.si_overrun = 0;
@@ -1614,7 +1622,9 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
 	list_add_tail(&q->list, &pending->list);
 	sigaddset(&pending->signal, sig);
 	complete_signal(sig, t, group);
+	result = TRACE_SIGNAL_DELIVERED;
 out:
+	trace_signal_generate(sig, &q->info, t, group, result);
 	unlock_task_sighand(t, &flags);
 ret:
 	return ret;
@@ -2182,6 +2192,9 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
 	struct signal_struct *signal = current->signal;
 	int signr;
 
+	if (unlikely(uprobe_deny_signal()))
+		return 0;
+
 relock:
 	/*
 	 * We'll jump back here after any time we were stopped in TASK_STOPPED.
diff --git a/kernel/smp.c b/kernel/smp.c
index db197d6..2f8b10e 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -701,3 +701,93 @@ int on_each_cpu(void (*func) (void *info), void *info, int wait)
 	return ret;
 }
 EXPORT_SYMBOL(on_each_cpu);
+
+/**
+ * on_each_cpu_mask(): Run a function on processors specified by
+ * cpumask, which may include the local processor.
+ * @mask: The set of cpus to run on (only runs on online subset).
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @wait: If true, wait (atomically) until function has completed
+ *        on other CPUs.
+ *
+ * If @wait is true, then returns once @func has returned.
+ *
+ * You must not call this function with disabled interrupts or
+ * from a hardware interrupt handler or from a bottom half handler.
+ */
+void on_each_cpu_mask(const struct cpumask *mask, smp_call_func_t func,
+			void *info, bool wait)
+{
+	int cpu = get_cpu();
+
+	smp_call_function_many(mask, func, info, wait);
+	if (cpumask_test_cpu(cpu, mask)) {
+		local_irq_disable();
+		func(info);
+		local_irq_enable();
+	}
+	put_cpu();
+}
+EXPORT_SYMBOL(on_each_cpu_mask);
+
+/*
+ * on_each_cpu_cond(): Call a function on each processor for which
+ * the supplied function cond_func returns true, optionally waiting
+ * for all the required CPUs to finish. This may include the local
+ * processor.
+ * @cond_func:	A callback function that is passed a cpu id and
+ *		the the info parameter. The function is called
+ *		with preemption disabled. The function should
+ *		return a blooean value indicating whether to IPI
+ *		the specified CPU.
+ * @func:	The function to run on all applicable CPUs.
+ *		This must be fast and non-blocking.
+ * @info:	An arbitrary pointer to pass to both functions.
+ * @wait:	If true, wait (atomically) until function has
+ *		completed on other CPUs.
+ * @gfp_flags:	GFP flags to use when allocating the cpumask
+ *		used internally by the function.
+ *
+ * The function might sleep if the GFP flags indicates a non
+ * atomic allocation is allowed.
+ *
+ * Preemption is disabled to protect against CPUs going offline but not online.
+ * CPUs going online during the call will not be seen or sent an IPI.
+ *
+ * You must not call this function with disabled interrupts or
+ * from a hardware interrupt handler or from a bottom half handler.
+ */
+void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info),
+			smp_call_func_t func, void *info, bool wait,
+			gfp_t gfp_flags)
+{
+	cpumask_var_t cpus;
+	int cpu, ret;
+
+	might_sleep_if(gfp_flags & __GFP_WAIT);
+
+	if (likely(zalloc_cpumask_var(&cpus, (gfp_flags|__GFP_NOWARN)))) {
+		preempt_disable();
+		for_each_online_cpu(cpu)
+			if (cond_func(cpu, info))
+				cpumask_set_cpu(cpu, cpus);
+		on_each_cpu_mask(cpus, func, info, wait);
+		preempt_enable();
+		free_cpumask_var(cpus);
+	} else {
+		/*
+		 * No free cpumask, bother. No matter, we'll
+		 * just have to IPI them one by one.
+		 */
+		preempt_disable();
+		for_each_online_cpu(cpu)
+			if (cond_func(cpu, info)) {
+				ret = smp_call_function_single(cpu, func,
+								info, wait);
+				WARN_ON_ONCE(!ret);
+			}
+		preempt_enable();
+	}
+}
+EXPORT_SYMBOL(on_each_cpu_cond);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 4eb3a0f..c82d95a 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -310,31 +310,21 @@ void irq_enter(void)
 	__irq_enter();
 }
 
-#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
 static inline void invoke_softirq(void)
 {
-	if (!force_irqthreads)
+	if (!force_irqthreads) {
+#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
 		__do_softirq();
-	else {
-		__local_bh_disable((unsigned long)__builtin_return_address(0),
-				SOFTIRQ_OFFSET);
-		wakeup_softirqd();
-		__local_bh_enable(SOFTIRQ_OFFSET);
-	}
-}
 #else
-static inline void invoke_softirq(void)
-{
-	if (!force_irqthreads)
 		do_softirq();
-	else {
+#endif
+	} else {
 		__local_bh_disable((unsigned long)__builtin_return_address(0),
 				SOFTIRQ_OFFSET);
 		wakeup_softirqd();
 		__local_bh_enable(SOFTIRQ_OFFSET);
 	}
 }
-#endif
 
 /*
  * Exit an interrupt context. Process softirqs if needed and possible:
diff --git a/kernel/srcu.c b/kernel/srcu.c
index 0febf61..ba35f3a 100644
--- a/kernel/srcu.c
+++ b/kernel/srcu.c
@@ -172,6 +172,12 @@ static void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void))
 {
 	int idx;
 
+	rcu_lockdep_assert(!lock_is_held(&sp->dep_map) &&
+			   !lock_is_held(&rcu_bh_lock_map) &&
+			   !lock_is_held(&rcu_lock_map) &&
+			   !lock_is_held(&rcu_sched_lock_map),
+			   "Illegal synchronize_srcu() in same-type SRCU (or RCU) read-side critical section");
+
 	idx = sp->completed;
 	mutex_lock(&sp->mutex);
 
@@ -280,19 +286,26 @@ void synchronize_srcu(struct srcu_struct *sp)
 EXPORT_SYMBOL_GPL(synchronize_srcu);
 
 /**
- * synchronize_srcu_expedited - like synchronize_srcu, but less patient
+ * synchronize_srcu_expedited - Brute-force SRCU grace period
  * @sp: srcu_struct with which to synchronize.
  *
- * Flip the completed counter, and wait for the old count to drain to zero.
- * As with classic RCU, the updater must use some separate means of
- * synchronizing concurrent updates.  Can block; must be called from
- * process context.
+ * Wait for an SRCU grace period to elapse, but use a "big hammer"
+ * approach to force the grace period to end quickly.  This consumes
+ * significant time on all CPUs and is unfriendly to real-time workloads,
+ * so is thus not recommended for any sort of common-case code.  In fact,
+ * if you are using synchronize_srcu_expedited() in a loop, please
+ * restructure your code to batch your updates, and then use a single
+ * synchronize_srcu() instead.
  *
- * Note that it is illegal to call synchronize_srcu_expedited()
- * from the corresponding SRCU read-side critical section; doing so
- * will result in deadlock.  However, it is perfectly legal to call
- * synchronize_srcu_expedited() on one srcu_struct from some other
- * srcu_struct's read-side critical section.
+ * Note that it is illegal to call this function while holding any lock
+ * that is acquired by a CPU-hotplug notifier.  And yes, it is also illegal
+ * to call this function from a CPU-hotplug notifier.  Failing to observe
+ * these restriction will result in deadlock.  It is also illegal to call
+ * synchronize_srcu_expedited() from the corresponding SRCU read-side
+ * critical section; doing so will result in deadlock.  However, it is
+ * perfectly legal to call synchronize_srcu_expedited() on one srcu_struct
+ * from some other srcu_struct's read-side critical section, as long as
+ * the resulting graph of srcu_structs is acyclic.
  */
 void synchronize_srcu_expedited(struct srcu_struct *sp)
 {
diff --git a/kernel/sys.c b/kernel/sys.c
index 4070153..4686119 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -444,6 +444,15 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
 	                magic2 != LINUX_REBOOT_MAGIC2C))
 		return -EINVAL;
 
+	/*
+	 * If pid namespaces are enabled and the current task is in a child
+	 * pid_namespace, the command is handled by reboot_pid_ns() which will
+	 * call do_exit().
+	 */
+	ret = reboot_pid_ns(task_active_pid_ns(current), cmd);
+	if (ret)
+		return ret;
+
 	/* Instead of trying to make the power_off code look like
 	 * halt when pm_power_off is not set do it the easy way.
 	 */
@@ -1693,17 +1702,23 @@ SYSCALL_DEFINE1(umask, int, mask)
 }
 
 #ifdef CONFIG_CHECKPOINT_RESTORE
+static bool vma_flags_mismatch(struct vm_area_struct *vma,
+			       unsigned long required,
+			       unsigned long banned)
+{
+	return (vma->vm_flags & required) != required ||
+		(vma->vm_flags & banned);
+}
+
 static int prctl_set_mm(int opt, unsigned long addr,
 			unsigned long arg4, unsigned long arg5)
 {
 	unsigned long rlim = rlimit(RLIMIT_DATA);
-	unsigned long vm_req_flags;
-	unsigned long vm_bad_flags;
-	struct vm_area_struct *vma;
-	int error = 0;
 	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	int error;
 
-	if (arg4 | arg5)
+	if (arg5 || (arg4 && opt != PR_SET_MM_AUXV))
 		return -EINVAL;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -1712,24 +1727,24 @@ static int prctl_set_mm(int opt, unsigned long addr,
 	if (addr >= TASK_SIZE)
 		return -EINVAL;
 
+	error = -EINVAL;
+
 	down_read(&mm->mmap_sem);
 	vma = find_vma(mm, addr);
 
-	if (opt != PR_SET_MM_START_BRK && opt != PR_SET_MM_BRK) {
+	if (opt != PR_SET_MM_START_BRK &&
+	    opt != PR_SET_MM_BRK &&
+	    opt != PR_SET_MM_AUXV) {
 		/* It must be existing VMA */
 		if (!vma || vma->vm_start > addr)
 			goto out;
 	}
 
-	error = -EINVAL;
 	switch (opt) {
 	case PR_SET_MM_START_CODE:
 	case PR_SET_MM_END_CODE:
-		vm_req_flags = VM_READ | VM_EXEC;
-		vm_bad_flags = VM_WRITE | VM_MAYSHARE;
-
-		if ((vma->vm_flags & vm_req_flags) != vm_req_flags ||
-		    (vma->vm_flags & vm_bad_flags))
+		if (vma_flags_mismatch(vma, VM_READ | VM_EXEC,
+				       VM_WRITE | VM_MAYSHARE))
 			goto out;
 
 		if (opt == PR_SET_MM_START_CODE)
@@ -1740,11 +1755,8 @@ static int prctl_set_mm(int opt, unsigned long addr,
 
 	case PR_SET_MM_START_DATA:
 	case PR_SET_MM_END_DATA:
-		vm_req_flags = VM_READ | VM_WRITE;
-		vm_bad_flags = VM_EXEC | VM_MAYSHARE;
-
-		if ((vma->vm_flags & vm_req_flags) != vm_req_flags ||
-		    (vma->vm_flags & vm_bad_flags))
+		if (vma_flags_mismatch(vma, VM_READ | VM_WRITE,
+				       VM_EXEC | VM_MAYSHARE))
 			goto out;
 
 		if (opt == PR_SET_MM_START_DATA)
@@ -1753,19 +1765,6 @@ static int prctl_set_mm(int opt, unsigned long addr,
 			mm->end_data = addr;
 		break;
 
-	case PR_SET_MM_START_STACK:
-
-#ifdef CONFIG_STACK_GROWSUP
-		vm_req_flags = VM_READ | VM_WRITE | VM_GROWSUP;
-#else
-		vm_req_flags = VM_READ | VM_WRITE | VM_GROWSDOWN;
-#endif
-		if ((vma->vm_flags & vm_req_flags) != vm_req_flags)
-			goto out;
-
-		mm->start_stack = addr;
-		break;
-
 	case PR_SET_MM_START_BRK:
 		if (addr <= mm->end_data)
 			goto out;
@@ -1790,16 +1789,73 @@ static int prctl_set_mm(int opt, unsigned long addr,
 		mm->brk = addr;
 		break;
 
+	/*
+	 * If command line arguments and environment
+	 * are placed somewhere else on stack, we can
+	 * set them up here, ARG_START/END to setup
+	 * command line argumets and ENV_START/END
+	 * for environment.
+	 */
+	case PR_SET_MM_START_STACK:
+	case PR_SET_MM_ARG_START:
+	case PR_SET_MM_ARG_END:
+	case PR_SET_MM_ENV_START:
+	case PR_SET_MM_ENV_END:
+#ifdef CONFIG_STACK_GROWSUP
+		if (vma_flags_mismatch(vma, VM_READ | VM_WRITE | VM_GROWSUP, 0))
+#else
+		if (vma_flags_mismatch(vma, VM_READ | VM_WRITE | VM_GROWSDOWN, 0))
+#endif
+			goto out;
+		if (opt == PR_SET_MM_START_STACK)
+			mm->start_stack = addr;
+		else if (opt == PR_SET_MM_ARG_START)
+			mm->arg_start = addr;
+		else if (opt == PR_SET_MM_ARG_END)
+			mm->arg_end = addr;
+		else if (opt == PR_SET_MM_ENV_START)
+			mm->env_start = addr;
+		else if (opt == PR_SET_MM_ENV_END)
+			mm->env_end = addr;
+		break;
+
+	/*
+	 * This doesn't move auxiliary vector itself
+	 * since it's pinned to mm_struct, but allow
+	 * to fill vector with new values. It's up
+	 * to a caller to provide sane values here
+	 * otherwise user space tools which use this
+	 * vector might be unhappy.
+	 */
+	case PR_SET_MM_AUXV: {
+		unsigned long user_auxv[AT_VECTOR_SIZE];
+
+		if (arg4 > sizeof(user_auxv))
+			goto out;
+		up_read(&mm->mmap_sem);
+
+		if (copy_from_user(user_auxv, (const void __user *)addr, arg4))
+			return -EFAULT;
+
+		/* Make sure the last entry is always AT_NULL */
+		user_auxv[AT_VECTOR_SIZE - 2] = 0;
+		user_auxv[AT_VECTOR_SIZE - 1] = 0;
+
+		BUILD_BUG_ON(sizeof(user_auxv) != sizeof(mm->saved_auxv));
+
+		task_lock(current);
+		memcpy(mm->saved_auxv, user_auxv, arg4);
+		task_unlock(current);
+
+		return 0;
+	}
 	default:
-		error = -EINVAL;
 		goto out;
 	}
 
 	error = 0;
-
 out:
 	up_read(&mm->mmap_sem);
-
 	return error;
 }
 #else /* CONFIG_CHECKPOINT_RESTORE */
@@ -1962,6 +2018,14 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		case PR_SET_MM:
 			error = prctl_set_mm(arg2, arg3, arg4, arg5);
 			break;
+		case PR_SET_CHILD_SUBREAPER:
+			me->signal->is_child_subreaper = !!arg2;
+			error = 0;
+			break;
+		case PR_GET_CHILD_SUBREAPER:
+			error = put_user(me->signal->is_child_subreaper,
+					 (int __user *) arg2);
+			break;
 		default:
 			error = -EINVAL;
 			break;
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 47bfa16..dbff751 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -203,3 +203,6 @@ cond_syscall(sys_fanotify_mark);
 cond_syscall(sys_name_to_handle_at);
 cond_syscall(sys_open_by_handle_at);
 cond_syscall(compat_sys_open_by_handle_at);
+
+/* compare kernel pointers */
+cond_syscall(sys_kcmp);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index f487f25..1b26a6a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -23,6 +23,7 @@
 #include <linux/swap.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
+#include <linux/bitmap.h>
 #include <linux/signal.h>
 #include <linux/printk.h>
 #include <linux/proc_fs.h>
@@ -58,6 +59,7 @@
 #include <linux/oom.h>
 #include <linux/kmod.h>
 #include <linux/capability.h>
+#include <linux/binfmts.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -96,7 +98,6 @@ extern int suid_dumpable;
 extern char core_pattern[];
 extern unsigned int core_pipe_limit;
 extern int pid_max;
-extern int min_free_kbytes;
 extern int pid_max_min, pid_max_max;
 extern int sysctl_drop_caches;
 extern int percpu_pagelist_fraction;
@@ -192,20 +193,6 @@ static int sysrq_sysctl_handler(ctl_table *table, int write,
 
 #endif
 
-static struct ctl_table root_table[];
-static struct ctl_table_root sysctl_table_root;
-static struct ctl_table_header root_table_header = {
-	{{.count = 1,
-	.ctl_table = root_table,
-	.ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),}},
-	.root = &sysctl_table_root,
-	.set = &sysctl_table_root.default_set,
-};
-static struct ctl_table_root sysctl_table_root = {
-	.root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
-	.default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
-};
-
 static struct ctl_table kern_table[];
 static struct ctl_table vm_table[];
 static struct ctl_table fs_table[];
@@ -222,7 +209,7 @@ int sysctl_legacy_va_layout;
 
 /* The default sysctl tables: */
 
-static struct ctl_table root_table[] = {
+static struct ctl_table sysctl_base_table[] = {
 	{
 		.procname	= "kernel",
 		.mode		= 0555,
@@ -1205,7 +1192,15 @@ static struct ctl_table vm_table[] = {
 		.data		= &min_free_kbytes,
 		.maxlen		= sizeof(min_free_kbytes),
 		.mode		= 0644,
-		.proc_handler	= min_free_kbytes_sysctl_handler,
+		.proc_handler	= free_kbytes_sysctl_handler,
+		.extra1		= &zero,
+	},
+	{
+		.procname	= "extra_free_kbytes",
+		.data		= &extra_free_kbytes,
+		.maxlen		= sizeof(extra_free_kbytes),
+		.mode		= 0644,
+		.proc_handler	= free_kbytes_sysctl_handler,
 		.extra1		= &zero,
 	},
 	{
@@ -1559,490 +1554,12 @@ static struct ctl_table dev_table[] = {
 	{ }
 };
 
-static DEFINE_SPINLOCK(sysctl_lock);
-
-/* called under sysctl_lock */
-static int use_table(struct ctl_table_header *p)
-{
-	if (unlikely(p->unregistering))
-		return 0;
-	p->used++;
-	return 1;
-}
-
-/* called under sysctl_lock */
-static void unuse_table(struct ctl_table_header *p)
-{
-	if (!--p->used)
-		if (unlikely(p->unregistering))
-			complete(p->unregistering);
-}
-
-/* called under sysctl_lock, will reacquire if has to wait */
-static void start_unregistering(struct ctl_table_header *p)
-{
-	/*
-	 * if p->used is 0, nobody will ever touch that entry again;
-	 * we'll eliminate all paths to it before dropping sysctl_lock
-	 */
-	if (unlikely(p->used)) {
-		struct completion wait;
-		init_completion(&wait);
-		p->unregistering = &wait;
-		spin_unlock(&sysctl_lock);
-		wait_for_completion(&wait);
-		spin_lock(&sysctl_lock);
-	} else {
-		/* anything non-NULL; we'll never dereference it */
-		p->unregistering = ERR_PTR(-EINVAL);
-	}
-	/*
-	 * do not remove from the list until nobody holds it; walking the
-	 * list in do_sysctl() relies on that.
-	 */
-	list_del_init(&p->ctl_entry);
-}
-
-void sysctl_head_get(struct ctl_table_header *head)
-{
-	spin_lock(&sysctl_lock);
-	head->count++;
-	spin_unlock(&sysctl_lock);
-}
-
-void sysctl_head_put(struct ctl_table_header *head)
-{
-	spin_lock(&sysctl_lock);
-	if (!--head->count)
-		kfree_rcu(head, rcu);
-	spin_unlock(&sysctl_lock);
-}
-
-struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
-{
-	if (!head)
-		BUG();
-	spin_lock(&sysctl_lock);
-	if (!use_table(head))
-		head = ERR_PTR(-ENOENT);
-	spin_unlock(&sysctl_lock);
-	return head;
-}
-
-void sysctl_head_finish(struct ctl_table_header *head)
-{
-	if (!head)
-		return;
-	spin_lock(&sysctl_lock);
-	unuse_table(head);
-	spin_unlock(&sysctl_lock);
-}
-
-static struct ctl_table_set *
-lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
-{
-	struct ctl_table_set *set = &root->default_set;
-	if (root->lookup)
-		set = root->lookup(root, namespaces);
-	return set;
-}
-
-static struct list_head *
-lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
-{
-	struct ctl_table_set *set = lookup_header_set(root, namespaces);
-	return &set->list;
-}
-
-struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
-					    struct ctl_table_header *prev)
-{
-	struct ctl_table_root *root;
-	struct list_head *header_list;
-	struct ctl_table_header *head;
-	struct list_head *tmp;
-
-	spin_lock(&sysctl_lock);
-	if (prev) {
-		head = prev;
-		tmp = &prev->ctl_entry;
-		unuse_table(prev);
-		goto next;
-	}
-	tmp = &root_table_header.ctl_entry;
-	for (;;) {
-		head = list_entry(tmp, struct ctl_table_header, ctl_entry);
-
-		if (!use_table(head))
-			goto next;
-		spin_unlock(&sysctl_lock);
-		return head;
-	next:
-		root = head->root;
-		tmp = tmp->next;
-		header_list = lookup_header_list(root, namespaces);
-		if (tmp != header_list)
-			continue;
-
-		do {
-			root = list_entry(root->root_list.next,
-					struct ctl_table_root, root_list);
-			if (root == &sysctl_table_root)
-				goto out;
-			header_list = lookup_header_list(root, namespaces);
-		} while (list_empty(header_list));
-		tmp = header_list->next;
-	}
-out:
-	spin_unlock(&sysctl_lock);
-	return NULL;
-}
-
-struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
+int __init sysctl_init(void)
 {
-	return __sysctl_head_next(current->nsproxy, prev);
-}
-
-void register_sysctl_root(struct ctl_table_root *root)
-{
-	spin_lock(&sysctl_lock);
-	list_add_tail(&root->root_list, &sysctl_table_root.root_list);
-	spin_unlock(&sysctl_lock);
-}
-
-/*
- * sysctl_perm does NOT grant the superuser all rights automatically, because
- * some sysctl variables are readonly even to root.
- */
-
-static int test_perm(int mode, int op)
-{
-	if (!current_euid())
-		mode >>= 6;
-	else if (in_egroup_p(0))
-		mode >>= 3;
-	if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
-		return 0;
-	return -EACCES;
-}
-
-int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
-{
-	int mode;
-
-	if (root->permissions)
-		mode = root->permissions(root, current->nsproxy, table);
-	else
-		mode = table->mode;
-
-	return test_perm(mode, op);
-}
-
-static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table)
-{
-	for (; table->procname; table++) {
-		table->parent = parent;
-		if (table->child)
-			sysctl_set_parent(table, table->child);
-	}
-}
-
-static __init int sysctl_init(void)
-{
-	sysctl_set_parent(NULL, root_table);
-#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
-	sysctl_check_table(current->nsproxy, root_table);
-#endif
+	register_sysctl_table(sysctl_base_table);
 	return 0;
 }
 
-core_initcall(sysctl_init);
-
-static struct ctl_table *is_branch_in(struct ctl_table *branch,
-				      struct ctl_table *table)
-{
-	struct ctl_table *p;
-	const char *s = branch->procname;
-
-	/* branch should have named subdirectory as its first element */
-	if (!s || !branch->child)
-		return NULL;
-
-	/* ... and nothing else */
-	if (branch[1].procname)
-		return NULL;
-
-	/* table should contain subdirectory with the same name */
-	for (p = table; p->procname; p++) {
-		if (!p->child)
-			continue;
-		if (p->procname && strcmp(p->procname, s) == 0)
-			return p;
-	}
-	return NULL;
-}
-
-/* see if attaching q to p would be an improvement */
-static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
-{
-	struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
-	struct ctl_table *next;
-	int is_better = 0;
-	int not_in_parent = !p->attached_by;
-
-	while ((next = is_branch_in(by, to)) != NULL) {
-		if (by == q->attached_by)
-			is_better = 1;
-		if (to == p->attached_by)
-			not_in_parent = 1;
-		by = by->child;
-		to = next->child;
-	}
-
-	if (is_better && not_in_parent) {
-		q->attached_by = by;
-		q->attached_to = to;
-		q->parent = p;
-	}
-}
-
-/**
- * __register_sysctl_paths - register a sysctl hierarchy
- * @root: List of sysctl headers to register on
- * @namespaces: Data to compute which lists of sysctl entries are visible
- * @path: The path to the directory the sysctl table is in.
- * @table: the top-level table structure
- *
- * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. A completely 0 filled entry terminates the table.
- *
- * The members of the &struct ctl_table structure are used as follows:
- *
- * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
- *            enter a sysctl file
- *
- * data - a pointer to data for use by proc_handler
- *
- * maxlen - the maximum size in bytes of the data
- *
- * mode - the file permissions for the /proc/sys file, and for sysctl(2)
- *
- * child - a pointer to the child sysctl table if this entry is a directory, or
- *         %NULL.
- *
- * proc_handler - the text handler routine (described below)
- *
- * de - for internal use by the sysctl routines
- *
- * extra1, extra2 - extra pointers usable by the proc handler routines
- *
- * Leaf nodes in the sysctl tree will be represented by a single file
- * under /proc; non-leaf nodes will be represented by directories.
- *
- * sysctl(2) can automatically manage read and write requests through
- * the sysctl table.  The data and maxlen fields of the ctl_table
- * struct enable minimal validation of the values being written to be
- * performed, and the mode field allows minimal authentication.
- *
- * There must be a proc_handler routine for any terminal nodes
- * mirrored under /proc/sys (non-terminals are handled by a built-in
- * directory handler).  Several default handlers are available to
- * cover common cases -
- *
- * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
- * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(), 
- * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
- *
- * It is the handler's job to read the input buffer from user memory
- * and process it. The handler should return 0 on success.
- *
- * This routine returns %NULL on a failure to register, and a pointer
- * to the table header on success.
- */
-struct ctl_table_header *__register_sysctl_paths(
-	struct ctl_table_root *root,
-	struct nsproxy *namespaces,
-	const struct ctl_path *path, struct ctl_table *table)
-{
-	struct ctl_table_header *header;
-	struct ctl_table *new, **prevp;
-	unsigned int n, npath;
-	struct ctl_table_set *set;
-
-	/* Count the path components */
-	for (npath = 0; path[npath].procname; ++npath)
-		;
-
-	/*
-	 * For each path component, allocate a 2-element ctl_table array.
-	 * The first array element will be filled with the sysctl entry
-	 * for this, the second will be the sentinel (procname == 0).
-	 *
-	 * We allocate everything in one go so that we don't have to
-	 * worry about freeing additional memory in unregister_sysctl_table.
-	 */
-	header = kzalloc(sizeof(struct ctl_table_header) +
-			 (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
-	if (!header)
-		return NULL;
-
-	new = (struct ctl_table *) (header + 1);
-
-	/* Now connect the dots */
-	prevp = &header->ctl_table;
-	for (n = 0; n < npath; ++n, ++path) {
-		/* Copy the procname */
-		new->procname = path->procname;
-		new->mode     = 0555;
-
-		*prevp = new;
-		prevp = &new->child;
-
-		new += 2;
-	}
-	*prevp = table;
-	header->ctl_table_arg = table;
-
-	INIT_LIST_HEAD(&header->ctl_entry);
-	header->used = 0;
-	header->unregistering = NULL;
-	header->root = root;
-	sysctl_set_parent(NULL, header->ctl_table);
-	header->count = 1;
-#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
-	if (sysctl_check_table(namespaces, header->ctl_table)) {
-		kfree(header);
-		return NULL;
-	}
-#endif
-	spin_lock(&sysctl_lock);
-	header->set = lookup_header_set(root, namespaces);
-	header->attached_by = header->ctl_table;
-	header->attached_to = root_table;
-	header->parent = &root_table_header;
-	for (set = header->set; set; set = set->parent) {
-		struct ctl_table_header *p;
-		list_for_each_entry(p, &set->list, ctl_entry) {
-			if (p->unregistering)
-				continue;
-			try_attach(p, header);
-		}
-	}
-	header->parent->count++;
-	list_add_tail(&header->ctl_entry, &header->set->list);
-	spin_unlock(&sysctl_lock);
-
-	return header;
-}
-
-/**
- * register_sysctl_table_path - register a sysctl table hierarchy
- * @path: The path to the directory the sysctl table is in.
- * @table: the top-level table structure
- *
- * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. A completely 0 filled entry terminates the table.
- *
- * See __register_sysctl_paths for more details.
- */
-struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
-						struct ctl_table *table)
-{
-	return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
-					path, table);
-}
-
-/**
- * register_sysctl_table - register a sysctl table hierarchy
- * @table: the top-level table structure
- *
- * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. A completely 0 filled entry terminates the table.
- *
- * See register_sysctl_paths for more details.
- */
-struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
-{
-	static const struct ctl_path null_path[] = { {} };
-
-	return register_sysctl_paths(null_path, table);
-}
-
-/**
- * unregister_sysctl_table - unregister a sysctl table hierarchy
- * @header: the header returned from register_sysctl_table
- *
- * Unregisters the sysctl table and all children. proc entries may not
- * actually be removed until they are no longer used by anyone.
- */
-void unregister_sysctl_table(struct ctl_table_header * header)
-{
-	might_sleep();
-
-	if (header == NULL)
-		return;
-
-	spin_lock(&sysctl_lock);
-	start_unregistering(header);
-	if (!--header->parent->count) {
-		WARN_ON(1);
-		kfree_rcu(header->parent, rcu);
-	}
-	if (!--header->count)
-		kfree_rcu(header, rcu);
-	spin_unlock(&sysctl_lock);
-}
-
-int sysctl_is_seen(struct ctl_table_header *p)
-{
-	struct ctl_table_set *set = p->set;
-	int res;
-	spin_lock(&sysctl_lock);
-	if (p->unregistering)
-		res = 0;
-	else if (!set->is_seen)
-		res = 1;
-	else
-		res = set->is_seen(set);
-	spin_unlock(&sysctl_lock);
-	return res;
-}
-
-void setup_sysctl_set(struct ctl_table_set *p,
-	struct ctl_table_set *parent,
-	int (*is_seen)(struct ctl_table_set *))
-{
-	INIT_LIST_HEAD(&p->list);
-	p->parent = parent ? parent : &sysctl_table_root.default_set;
-	p->is_seen = is_seen;
-}
-
-#else /* !CONFIG_SYSCTL */
-struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
-{
-	return NULL;
-}
-
-struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
-						    struct ctl_table *table)
-{
-	return NULL;
-}
-
-void unregister_sysctl_table(struct ctl_table_header * table)
-{
-}
-
-void setup_sysctl_set(struct ctl_table_set *p,
-	struct ctl_table_set *parent,
-	int (*is_seen)(struct ctl_table_set *))
-{
-}
-
-void sysctl_head_put(struct ctl_table_header *head)
-{
-}
-
 #endif /* CONFIG_SYSCTL */
 
 /*
@@ -2884,9 +2401,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 				}
 			}
 
-			while (val_a <= val_b)
-				set_bit(val_a++, tmp_bitmap);
-
+			bitmap_set(tmp_bitmap, val_a, val_b - val_a + 1);
 			first = 0;
 			proc_skip_char(&kbuf, &left, '\n');
 		}
@@ -2929,8 +2444,7 @@ int proc_do_large_bitmap(struct ctl_table *table, int write,
 			if (*ppos)
 				bitmap_or(bitmap, bitmap, tmp_bitmap, bitmap_len);
 			else
-				memcpy(bitmap, tmp_bitmap,
-					BITS_TO_LONGS(bitmap_len) * sizeof(unsigned long));
+				bitmap_copy(bitmap, tmp_bitmap, bitmap_len);
 		}
 		kfree(tmp_bitmap);
 		*lenp -= left;
@@ -3008,6 +2522,3 @@ EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
 EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
-EXPORT_SYMBOL(register_sysctl_table);
-EXPORT_SYMBOL(register_sysctl_paths);
-EXPORT_SYMBOL(unregister_sysctl_table);
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
deleted file mode 100644
index 362da65..0000000
--- a/kernel/sysctl_check.c
+++ /dev/null
@@ -1,160 +0,0 @@
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include "../fs/xfs/xfs_sysctl.h"
-#include <linux/sunrpc/debug.h>
-#include <linux/string.h>
-#include <net/ip_vs.h>
-
-
-static int sysctl_depth(struct ctl_table *table)
-{
-	struct ctl_table *tmp;
-	int depth;
-
-	depth = 0;
-	for (tmp = table; tmp->parent; tmp = tmp->parent)
-		depth++;
-
-	return depth;
-}
-
-static struct ctl_table *sysctl_parent(struct ctl_table *table, int n)
-{
-	int i;
-
-	for (i = 0; table && i < n; i++)
-		table = table->parent;
-
-	return table;
-}
-
-
-static void sysctl_print_path(struct ctl_table *table)
-{
-	struct ctl_table *tmp;
-	int depth, i;
-	depth = sysctl_depth(table);
-	if (table->procname) {
-		for (i = depth; i >= 0; i--) {
-			tmp = sysctl_parent(table, i);
-			printk("/%s", tmp->procname?tmp->procname:"");
-		}
-	}
-	printk(" ");
-}
-
-static struct ctl_table *sysctl_check_lookup(struct nsproxy *namespaces,
-						struct ctl_table *table)
-{
-	struct ctl_table_header *head;
-	struct ctl_table *ref, *test;
-	int depth, cur_depth;
-
-	depth = sysctl_depth(table);
-
-	for (head = __sysctl_head_next(namespaces, NULL); head;
-	     head = __sysctl_head_next(namespaces, head)) {
-		cur_depth = depth;
-		ref = head->ctl_table;
-repeat:
-		test = sysctl_parent(table, cur_depth);
-		for (; ref->procname; ref++) {
-			int match = 0;
-			if (cur_depth && !ref->child)
-				continue;
-
-			if (test->procname && ref->procname &&
-			    (strcmp(test->procname, ref->procname) == 0))
-					match++;
-
-			if (match) {
-				if (cur_depth != 0) {
-					cur_depth--;
-					ref = ref->child;
-					goto repeat;
-				}
-				goto out;
-			}
-		}
-	}
-	ref = NULL;
-out:
-	sysctl_head_finish(head);
-	return ref;
-}
-
-static void set_fail(const char **fail, struct ctl_table *table, const char *str)
-{
-	if (*fail) {
-		printk(KERN_ERR "sysctl table check failed: ");
-		sysctl_print_path(table);
-		printk(" %s\n", *fail);
-		dump_stack();
-	}
-	*fail = str;
-}
-
-static void sysctl_check_leaf(struct nsproxy *namespaces,
-				struct ctl_table *table, const char **fail)
-{
-	struct ctl_table *ref;
-
-	ref = sysctl_check_lookup(namespaces, table);
-	if (ref && (ref != table))
-		set_fail(fail, table, "Sysctl already exists");
-}
-
-int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table)
-{
-	int error = 0;
-	for (; table->procname; table++) {
-		const char *fail = NULL;
-
-		if (table->parent) {
-			if (!table->parent->procname)
-				set_fail(&fail, table, "Parent without procname");
-		}
-		if (table->child) {
-			if (table->data)
-				set_fail(&fail, table, "Directory with data?");
-			if (table->maxlen)
-				set_fail(&fail, table, "Directory with maxlen?");
-			if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode)
-				set_fail(&fail, table, "Writable sysctl directory");
-			if (table->proc_handler)
-				set_fail(&fail, table, "Directory with proc_handler");
-			if (table->extra1)
-				set_fail(&fail, table, "Directory with extra1");
-			if (table->extra2)
-				set_fail(&fail, table, "Directory with extra2");
-		} else {
-			if ((table->proc_handler == proc_dostring) ||
-			    (table->proc_handler == proc_dointvec) ||
-			    (table->proc_handler == proc_dointvec_minmax) ||
-			    (table->proc_handler == proc_dointvec_jiffies) ||
-			    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
-			    (table->proc_handler == proc_dointvec_ms_jiffies) ||
-			    (table->proc_handler == proc_doulongvec_minmax) ||
-			    (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
-				if (!table->data)
-					set_fail(&fail, table, "No data");
-				if (!table->maxlen)
-					set_fail(&fail, table, "No maxlen");
-			}
-#ifdef CONFIG_PROC_SYSCTL
-			if (!table->proc_handler)
-				set_fail(&fail, table, "No proc_handler");
-#endif
-			sysctl_check_leaf(namespaces, table, &fail);
-		}
-		if (table->mode > 0777)
-			set_fail(&fail, table, "bogus .mode");
-		if (fail) {
-			set_fail(&fail, table, NULL);
-			error = -EINVAL;
-		}
-		if (table->child)
-			error |= sysctl_check_table(namespaces, table->child);
-	}
-	return error;
-}
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 0c63581..e6a5a6b 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1230,6 +1230,8 @@ ktime_t ktime_get_monotonic_offset(void)
 	} while (read_seqretry(&xtime_lock, seq));
 	return timespec_to_ktime(wtom);
 }
+EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset);
+
 
 /**
  * xtime_update() - advances the timekeeping infrastructure
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index cd31345..b001fb1 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -373,6 +373,7 @@ config KPROBE_EVENT
 	depends on HAVE_REGS_AND_STACK_ACCESS_API
 	bool "Enable kprobes-based dynamic events"
 	select TRACING
+	select PROBE_EVENTS
 	default y
 	help
 	  This allows the user to add tracing events (similar to tracepoints)
@@ -385,6 +386,25 @@ config KPROBE_EVENT
 	  This option is also required by perf-probe subcommand of perf tools.
 	  If you want to use perf tools, this option is strongly recommended.
 
+config UPROBE_EVENT
+	bool "Enable uprobes-based dynamic events"
+	depends on ARCH_SUPPORTS_UPROBES
+	depends on MMU
+	select UPROBES
+	select PROBE_EVENTS
+	select TRACING
+	default n
+	help
+	  This allows the user to add tracing events on top of userspace dynamic
+	  events (similar to tracepoints) on the fly via the traceevents interface.
+	  Those events can be inserted wherever uprobes can probe, and record
+	  various registers.
+	  This option is required if you plan to use perf-probe subcommand of perf
+	  tools on user space applications.
+
+config PROBE_EVENTS
+	def_bool n
+
 config DYNAMIC_FTRACE
 	bool "enable/disable ftrace tracepoints dynamically"
 	depends on FUNCTION_TRACER
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 5f39a07..1734c03 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -61,5 +61,7 @@ endif
 ifeq ($(CONFIG_TRACING),y)
 obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
 endif
+obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
+obj-$(CONFIG_UPROBE_EVENT) += trace_uprobe.o
 
 libftrace-y := ftrace.o
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index b93ecba..03a5818 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -97,6 +97,11 @@ struct kretprobe_trace_entry_head {
 	unsigned long		ret_ip;
 };
 
+struct uprobe_trace_entry_head {
+	struct trace_entry	ent;
+	unsigned long		ip;
+};
+
 /*
  * trace_flag_type is an enumeration that holds different
  * states when a trace occurs. These are:
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 00d527c..60384df 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -19,547 +19,15 @@
 
 #include <linux/module.h>
 #include <linux/uaccess.h>
-#include <linux/kprobes.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-#include <linux/debugfs.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/ptrace.h>
-#include <linux/perf_event.h>
-#include <linux/stringify.h>
-#include <linux/limits.h>
-#include <asm/bitsperlong.h>
-
-#include "trace.h"
-#include "trace_output.h"
-
-#define MAX_TRACE_ARGS 128
-#define MAX_ARGSTR_LEN 63
-#define MAX_EVENT_NAME_LEN 64
-#define MAX_STRING_SIZE PATH_MAX
-#define KPROBE_EVENT_SYSTEM "kprobes"
-
-/* Reserved field names */
-#define FIELD_STRING_IP "__probe_ip"
-#define FIELD_STRING_RETIP "__probe_ret_ip"
-#define FIELD_STRING_FUNC "__probe_func"
-
-const char *reserved_field_names[] = {
-	"common_type",
-	"common_flags",
-	"common_preempt_count",
-	"common_pid",
-	"common_tgid",
-	FIELD_STRING_IP,
-	FIELD_STRING_RETIP,
-	FIELD_STRING_FUNC,
-};
-
-/* Printing function type */
-typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *,
-				 void *);
-#define PRINT_TYPE_FUNC_NAME(type)	print_type_##type
-#define PRINT_TYPE_FMT_NAME(type)	print_type_format_##type
-
-/* Printing  in basic type function template */
-#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)			\
-static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,	\
-						const char *name,	\
-						void *data, void *ent)\
-{									\
-	return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
-}									\
-static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
-
-DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
-DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
-DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
-DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
-DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
-DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
-DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
-DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
-
-/* data_rloc: data relative location, compatible with u32 */
-#define make_data_rloc(len, roffs)	\
-	(((u32)(len) << 16) | ((u32)(roffs) & 0xffff))
-#define get_rloc_len(dl)	((u32)(dl) >> 16)
-#define get_rloc_offs(dl)	((u32)(dl) & 0xffff)
-
-static inline void *get_rloc_data(u32 *dl)
-{
-	return (u8 *)dl + get_rloc_offs(*dl);
-}
-
-/* For data_loc conversion */
-static inline void *get_loc_data(u32 *dl, void *ent)
-{
-	return (u8 *)ent + get_rloc_offs(*dl);
-}
-
-/*
- * Convert data_rloc to data_loc:
- *  data_rloc stores the offset from data_rloc itself, but data_loc
- *  stores the offset from event entry.
- */
-#define convert_rloc_to_loc(dl, offs)	((u32)(dl) + (offs))
-
-/* For defining macros, define string/string_size types */
-typedef u32 string;
-typedef u32 string_size;
-
-/* Print type function for string type */
-static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
-						  const char *name,
-						  void *data, void *ent)
-{
-	int len = *(u32 *)data >> 16;
-
-	if (!len)
-		return trace_seq_printf(s, " %s=(fault)", name);
-	else
-		return trace_seq_printf(s, " %s=\"%s\"", name,
-					(const char *)get_loc_data(data, ent));
-}
-static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
-
-/* Data fetch function type */
-typedef	void (*fetch_func_t)(struct pt_regs *, void *, void *);
-
-struct fetch_param {
-	fetch_func_t	fn;
-	void *data;
-};
-
-static __kprobes void call_fetch(struct fetch_param *fprm,
-				 struct pt_regs *regs, void *dest)
-{
-	return fprm->fn(regs, fprm->data, dest);
-}
-
-#define FETCH_FUNC_NAME(method, type)	fetch_##method##_##type
-/*
- * Define macro for basic types - we don't need to define s* types, because
- * we have to care only about bitwidth at recording time.
- */
-#define DEFINE_BASIC_FETCH_FUNCS(method) \
-DEFINE_FETCH_##method(u8)		\
-DEFINE_FETCH_##method(u16)		\
-DEFINE_FETCH_##method(u32)		\
-DEFINE_FETCH_##method(u64)
-
-#define CHECK_FETCH_FUNCS(method, fn)			\
-	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
-	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
-	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
-	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
-	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
-	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
-	 && (fn != NULL))
-
-/* Data fetch function templates */
-#define DEFINE_FETCH_reg(type)						\
-static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,	\
-					void *offset, void *dest)	\
-{									\
-	*(type *)dest = (type)regs_get_register(regs,			\
-				(unsigned int)((unsigned long)offset));	\
-}
-DEFINE_BASIC_FETCH_FUNCS(reg)
-/* No string on the register */
-#define fetch_reg_string NULL
-#define fetch_reg_string_size NULL
-
-#define DEFINE_FETCH_stack(type)					\
-static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
-					  void *offset, void *dest)	\
-{									\
-	*(type *)dest = (type)regs_get_kernel_stack_nth(regs,		\
-				(unsigned int)((unsigned long)offset));	\
-}
-DEFINE_BASIC_FETCH_FUNCS(stack)
-/* No string on the stack entry */
-#define fetch_stack_string NULL
-#define fetch_stack_string_size NULL
-
-#define DEFINE_FETCH_retval(type)					\
-static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
-					  void *dummy, void *dest)	\
-{									\
-	*(type *)dest = (type)regs_return_value(regs);			\
-}
-DEFINE_BASIC_FETCH_FUNCS(retval)
-/* No string on the retval */
-#define fetch_retval_string NULL
-#define fetch_retval_string_size NULL
-
-#define DEFINE_FETCH_memory(type)					\
-static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
-					  void *addr, void *dest)	\
-{									\
-	type retval;							\
-	if (probe_kernel_address(addr, retval))				\
-		*(type *)dest = 0;					\
-	else								\
-		*(type *)dest = retval;					\
-}
-DEFINE_BASIC_FETCH_FUNCS(memory)
-/*
- * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
- * length and relative data location.
- */
-static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
-						      void *addr, void *dest)
-{
-	long ret;
-	int maxlen = get_rloc_len(*(u32 *)dest);
-	u8 *dst = get_rloc_data(dest);
-	u8 *src = addr;
-	mm_segment_t old_fs = get_fs();
-	if (!maxlen)
-		return;
-	/*
-	 * Try to get string again, since the string can be changed while
-	 * probing.
-	 */
-	set_fs(KERNEL_DS);
-	pagefault_disable();
-	do
-		ret = __copy_from_user_inatomic(dst++, src++, 1);
-	while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
-	dst[-1] = '\0';
-	pagefault_enable();
-	set_fs(old_fs);
-
-	if (ret < 0) {	/* Failed to fetch string */
-		((u8 *)get_rloc_data(dest))[0] = '\0';
-		*(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
-	} else
-		*(u32 *)dest = make_data_rloc(src - (u8 *)addr,
-					      get_rloc_offs(*(u32 *)dest));
-}
-/* Return the length of string -- including null terminal byte */
-static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
-							void *addr, void *dest)
-{
-	int ret, len = 0;
-	u8 c;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	pagefault_disable();
-	do {
-		ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
-		len++;
-	} while (c && ret == 0 && len < MAX_STRING_SIZE);
-	pagefault_enable();
-	set_fs(old_fs);
-
-	if (ret < 0)	/* Failed to check the length */
-		*(u32 *)dest = 0;
-	else
-		*(u32 *)dest = len;
-}
-
-/* Memory fetching by symbol */
-struct symbol_cache {
-	char *symbol;
-	long offset;
-	unsigned long addr;
-};
-
-static unsigned long update_symbol_cache(struct symbol_cache *sc)
-{
-	sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
-	if (sc->addr)
-		sc->addr += sc->offset;
-	return sc->addr;
-}
-
-static void free_symbol_cache(struct symbol_cache *sc)
-{
-	kfree(sc->symbol);
-	kfree(sc);
-}
-
-static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
-{
-	struct symbol_cache *sc;
-
-	if (!sym || strlen(sym) == 0)
-		return NULL;
-	sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
-	if (!sc)
-		return NULL;
-
-	sc->symbol = kstrdup(sym, GFP_KERNEL);
-	if (!sc->symbol) {
-		kfree(sc);
-		return NULL;
-	}
-	sc->offset = offset;
 
-	update_symbol_cache(sc);
-	return sc;
-}
-
-#define DEFINE_FETCH_symbol(type)					\
-static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
-					  void *data, void *dest)	\
-{									\
-	struct symbol_cache *sc = data;					\
-	if (sc->addr)							\
-		fetch_memory_##type(regs, (void *)sc->addr, dest);	\
-	else								\
-		*(type *)dest = 0;					\
-}
-DEFINE_BASIC_FETCH_FUNCS(symbol)
-DEFINE_FETCH_symbol(string)
-DEFINE_FETCH_symbol(string_size)
-
-/* Dereference memory access function */
-struct deref_fetch_param {
-	struct fetch_param orig;
-	long offset;
-};
-
-#define DEFINE_FETCH_deref(type)					\
-static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
-					    void *data, void *dest)	\
-{									\
-	struct deref_fetch_param *dprm = data;				\
-	unsigned long addr;						\
-	call_fetch(&dprm->orig, regs, &addr);				\
-	if (addr) {							\
-		addr += dprm->offset;					\
-		fetch_memory_##type(regs, (void *)addr, dest);		\
-	} else								\
-		*(type *)dest = 0;					\
-}
-DEFINE_BASIC_FETCH_FUNCS(deref)
-DEFINE_FETCH_deref(string)
-DEFINE_FETCH_deref(string_size)
-
-static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
-{
-	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-		update_deref_fetch_param(data->orig.data);
-	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-		update_symbol_cache(data->orig.data);
-}
-
-static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
-{
-	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-		free_deref_fetch_param(data->orig.data);
-	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-		free_symbol_cache(data->orig.data);
-	kfree(data);
-}
-
-/* Bitfield fetch function */
-struct bitfield_fetch_param {
-	struct fetch_param orig;
-	unsigned char hi_shift;
-	unsigned char low_shift;
-};
+#include "trace_probe.h"
 
-#define DEFINE_FETCH_bitfield(type)					\
-static __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
-					    void *data, void *dest)	\
-{									\
-	struct bitfield_fetch_param *bprm = data;			\
-	type buf = 0;							\
-	call_fetch(&bprm->orig, regs, &buf);				\
-	if (buf) {							\
-		buf <<= bprm->hi_shift;					\
-		buf >>= bprm->low_shift;				\
-	}								\
-	*(type *)dest = buf;						\
-}
-DEFINE_BASIC_FETCH_FUNCS(bitfield)
-#define fetch_bitfield_string NULL
-#define fetch_bitfield_string_size NULL
-
-static __kprobes void
-update_bitfield_fetch_param(struct bitfield_fetch_param *data)
-{
-	/*
-	 * Don't check the bitfield itself, because this must be the
-	 * last fetch function.
-	 */
-	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-		update_deref_fetch_param(data->orig.data);
-	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-		update_symbol_cache(data->orig.data);
-}
-
-static __kprobes void
-free_bitfield_fetch_param(struct bitfield_fetch_param *data)
-{
-	/*
-	 * Don't check the bitfield itself, because this must be the
-	 * last fetch function.
-	 */
-	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-		free_deref_fetch_param(data->orig.data);
-	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-		free_symbol_cache(data->orig.data);
-	kfree(data);
-}
-
-/* Default (unsigned long) fetch type */
-#define __DEFAULT_FETCH_TYPE(t) u##t
-#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
-#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
-#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
-
-/* Fetch types */
-enum {
-	FETCH_MTD_reg = 0,
-	FETCH_MTD_stack,
-	FETCH_MTD_retval,
-	FETCH_MTD_memory,
-	FETCH_MTD_symbol,
-	FETCH_MTD_deref,
-	FETCH_MTD_bitfield,
-	FETCH_MTD_END,
-};
-
-#define ASSIGN_FETCH_FUNC(method, type)	\
-	[FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
-
-#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)	\
-	{.name = _name,				\
-	 .size = _size,					\
-	 .is_signed = sign,				\
-	 .print = PRINT_TYPE_FUNC_NAME(ptype),		\
-	 .fmt = PRINT_TYPE_FMT_NAME(ptype),		\
-	 .fmttype = _fmttype,				\
-	 .fetch = {					\
-ASSIGN_FETCH_FUNC(reg, ftype),				\
-ASSIGN_FETCH_FUNC(stack, ftype),			\
-ASSIGN_FETCH_FUNC(retval, ftype),			\
-ASSIGN_FETCH_FUNC(memory, ftype),			\
-ASSIGN_FETCH_FUNC(symbol, ftype),			\
-ASSIGN_FETCH_FUNC(deref, ftype),			\
-ASSIGN_FETCH_FUNC(bitfield, ftype),			\
-	  }						\
-	}
-
-#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)			\
-	__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
-
-#define FETCH_TYPE_STRING 0
-#define FETCH_TYPE_STRSIZE 1
-
-/* Fetch type information table */
-static const struct fetch_type {
-	const char	*name;		/* Name of type */
-	size_t		size;		/* Byte size of type */
-	int		is_signed;	/* Signed flag */
-	print_type_func_t	print;	/* Print functions */
-	const char	*fmt;		/* Fromat string */
-	const char	*fmttype;	/* Name in format file */
-	/* Fetch functions */
-	fetch_func_t	fetch[FETCH_MTD_END];
-} fetch_type_table[] = {
-	/* Special types */
-	[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
-					sizeof(u32), 1, "__data_loc char[]"),
-	[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
-					string_size, sizeof(u32), 0, "u32"),
-	/* Basic types */
-	ASSIGN_FETCH_TYPE(u8,  u8,  0),
-	ASSIGN_FETCH_TYPE(u16, u16, 0),
-	ASSIGN_FETCH_TYPE(u32, u32, 0),
-	ASSIGN_FETCH_TYPE(u64, u64, 0),
-	ASSIGN_FETCH_TYPE(s8,  u8,  1),
-	ASSIGN_FETCH_TYPE(s16, u16, 1),
-	ASSIGN_FETCH_TYPE(s32, u32, 1),
-	ASSIGN_FETCH_TYPE(s64, u64, 1),
-};
-
-static const struct fetch_type *find_fetch_type(const char *type)
-{
-	int i;
-
-	if (!type)
-		type = DEFAULT_FETCH_TYPE_STR;
-
-	/* Special case: bitfield */
-	if (*type == 'b') {
-		unsigned long bs;
-		type = strchr(type, '/');
-		if (!type)
-			goto fail;
-		type++;
-		if (strict_strtoul(type, 0, &bs))
-			goto fail;
-		switch (bs) {
-		case 8:
-			return find_fetch_type("u8");
-		case 16:
-			return find_fetch_type("u16");
-		case 32:
-			return find_fetch_type("u32");
-		case 64:
-			return find_fetch_type("u64");
-		default:
-			goto fail;
-		}
-	}
-
-	for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
-		if (strcmp(type, fetch_type_table[i].name) == 0)
-			return &fetch_type_table[i];
-fail:
-	return NULL;
-}
-
-/* Special function : only accept unsigned long */
-static __kprobes void fetch_stack_address(struct pt_regs *regs,
-					  void *dummy, void *dest)
-{
-	*(unsigned long *)dest = kernel_stack_pointer(regs);
-}
-
-static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
-					    fetch_func_t orig_fn)
-{
-	int i;
-
-	if (type != &fetch_type_table[FETCH_TYPE_STRING])
-		return NULL;	/* Only string type needs size function */
-	for (i = 0; i < FETCH_MTD_END; i++)
-		if (type->fetch[i] == orig_fn)
-			return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
-
-	WARN_ON(1);	/* This should not happen */
-	return NULL;
-}
+#define KPROBE_EVENT_SYSTEM "kprobes"
 
 /**
  * Kprobe event core functions
  */
 
-struct probe_arg {
-	struct fetch_param	fetch;
-	struct fetch_param	fetch_size;
-	unsigned int		offset;	/* Offset from argument entry */
-	const char		*name;	/* Name of this argument */
-	const char		*comm;	/* Command of this argument */
-	const struct fetch_type	*type;	/* Type of this argument */
-};
-
-/* Flags for trace_probe */
-#define TP_FLAG_TRACE	1
-#define TP_FLAG_PROFILE	2
-#define TP_FLAG_REGISTERED 4
-
 struct trace_probe {
 	struct list_head	list;
 	struct kretprobe	rp;	/* Use rp.kp for kprobe use */
@@ -631,18 +99,6 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
 static int kretprobe_dispatcher(struct kretprobe_instance *ri,
 				struct pt_regs *regs);
 
-/* Check the name is good for event/group/fields */
-static int is_good_name(const char *name)
-{
-	if (!isalpha(*name) && *name != '_')
-		return 0;
-	while (*++name != '\0') {
-		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
-			return 0;
-	}
-	return 1;
-}
-
 /*
  * Allocate new trace_probe and initialize it (including kprobes).
  */
@@ -651,7 +107,7 @@ static struct trace_probe *alloc_trace_probe(const char *group,
 					     void *addr,
 					     const char *symbol,
 					     unsigned long offs,
-					     int nargs, int is_return)
+					     int nargs, bool is_return)
 {
 	struct trace_probe *tp;
 	int ret = -ENOMEM;
@@ -702,34 +158,12 @@ error:
 	return ERR_PTR(ret);
 }
 
-static void update_probe_arg(struct probe_arg *arg)
-{
-	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
-		update_bitfield_fetch_param(arg->fetch.data);
-	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
-		update_deref_fetch_param(arg->fetch.data);
-	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
-		update_symbol_cache(arg->fetch.data);
-}
-
-static void free_probe_arg(struct probe_arg *arg)
-{
-	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
-		free_bitfield_fetch_param(arg->fetch.data);
-	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
-		free_deref_fetch_param(arg->fetch.data);
-	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
-		free_symbol_cache(arg->fetch.data);
-	kfree(arg->name);
-	kfree(arg->comm);
-}
-
 static void free_trace_probe(struct trace_probe *tp)
 {
 	int i;
 
 	for (i = 0; i < tp->nr_args; i++)
-		free_probe_arg(&tp->args[i]);
+		traceprobe_free_probe_arg(&tp->args[i]);
 
 	kfree(tp->call.class->system);
 	kfree(tp->call.name);
@@ -787,7 +221,7 @@ static int __register_trace_probe(struct trace_probe *tp)
 		return -EINVAL;
 
 	for (i = 0; i < tp->nr_args; i++)
-		update_probe_arg(&tp->args[i]);
+		traceprobe_update_arg(&tp->args[i]);
 
 	/* Set/clear disabled flag according to tp->flag */
 	if (trace_probe_is_enabled(tp))
@@ -919,227 +353,6 @@ static struct notifier_block trace_probe_module_nb = {
 	.priority = 1	/* Invoked after kprobe module callback */
 };
 
-/* Split symbol and offset. */
-static int split_symbol_offset(char *symbol, unsigned long *offset)
-{
-	char *tmp;
-	int ret;
-
-	if (!offset)
-		return -EINVAL;
-
-	tmp = strchr(symbol, '+');
-	if (tmp) {
-		/* skip sign because strict_strtol doesn't accept '+' */
-		ret = strict_strtoul(tmp + 1, 0, offset);
-		if (ret)
-			return ret;
-		*tmp = '\0';
-	} else
-		*offset = 0;
-	return 0;
-}
-
-#define PARAM_MAX_ARGS 16
-#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
-
-static int parse_probe_vars(char *arg, const struct fetch_type *t,
-			    struct fetch_param *f, int is_return)
-{
-	int ret = 0;
-	unsigned long param;
-
-	if (strcmp(arg, "retval") == 0) {
-		if (is_return)
-			f->fn = t->fetch[FETCH_MTD_retval];
-		else
-			ret = -EINVAL;
-	} else if (strncmp(arg, "stack", 5) == 0) {
-		if (arg[5] == '\0') {
-			if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
-				f->fn = fetch_stack_address;
-			else
-				ret = -EINVAL;
-		} else if (isdigit(arg[5])) {
-			ret = strict_strtoul(arg + 5, 10, &param);
-			if (ret || param > PARAM_MAX_STACK)
-				ret = -EINVAL;
-			else {
-				f->fn = t->fetch[FETCH_MTD_stack];
-				f->data = (void *)param;
-			}
-		} else
-			ret = -EINVAL;
-	} else
-		ret = -EINVAL;
-	return ret;
-}
-
-/* Recursive argument parser */
-static int __parse_probe_arg(char *arg, const struct fetch_type *t,
-			     struct fetch_param *f, int is_return)
-{
-	int ret = 0;
-	unsigned long param;
-	long offset;
-	char *tmp;
-
-	switch (arg[0]) {
-	case '$':
-		ret = parse_probe_vars(arg + 1, t, f, is_return);
-		break;
-	case '%':	/* named register */
-		ret = regs_query_register_offset(arg + 1);
-		if (ret >= 0) {
-			f->fn = t->fetch[FETCH_MTD_reg];
-			f->data = (void *)(unsigned long)ret;
-			ret = 0;
-		}
-		break;
-	case '@':	/* memory or symbol */
-		if (isdigit(arg[1])) {
-			ret = strict_strtoul(arg + 1, 0, &param);
-			if (ret)
-				break;
-			f->fn = t->fetch[FETCH_MTD_memory];
-			f->data = (void *)param;
-		} else {
-			ret = split_symbol_offset(arg + 1, &offset);
-			if (ret)
-				break;
-			f->data = alloc_symbol_cache(arg + 1, offset);
-			if (f->data)
-				f->fn = t->fetch[FETCH_MTD_symbol];
-		}
-		break;
-	case '+':	/* deref memory */
-		arg++;	/* Skip '+', because strict_strtol() rejects it. */
-	case '-':
-		tmp = strchr(arg, '(');
-		if (!tmp)
-			break;
-		*tmp = '\0';
-		ret = strict_strtol(arg, 0, &offset);
-		if (ret)
-			break;
-		arg = tmp + 1;
-		tmp = strrchr(arg, ')');
-		if (tmp) {
-			struct deref_fetch_param *dprm;
-			const struct fetch_type *t2 = find_fetch_type(NULL);
-			*tmp = '\0';
-			dprm = kzalloc(sizeof(struct deref_fetch_param),
-				       GFP_KERNEL);
-			if (!dprm)
-				return -ENOMEM;
-			dprm->offset = offset;
-			ret = __parse_probe_arg(arg, t2, &dprm->orig,
-						is_return);
-			if (ret)
-				kfree(dprm);
-			else {
-				f->fn = t->fetch[FETCH_MTD_deref];
-				f->data = (void *)dprm;
-			}
-		}
-		break;
-	}
-	if (!ret && !f->fn) {	/* Parsed, but do not find fetch method */
-		pr_info("%s type has no corresponding fetch method.\n",
-			t->name);
-		ret = -EINVAL;
-	}
-	return ret;
-}
-
-#define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
-
-/* Bitfield type needs to be parsed into a fetch function */
-static int __parse_bitfield_probe_arg(const char *bf,
-				      const struct fetch_type *t,
-				      struct fetch_param *f)
-{
-	struct bitfield_fetch_param *bprm;
-	unsigned long bw, bo;
-	char *tail;
-
-	if (*bf != 'b')
-		return 0;
-
-	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
-	if (!bprm)
-		return -ENOMEM;
-	bprm->orig = *f;
-	f->fn = t->fetch[FETCH_MTD_bitfield];
-	f->data = (void *)bprm;
-
-	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
-	if (bw == 0 || *tail != '@')
-		return -EINVAL;
-
-	bf = tail + 1;
-	bo = simple_strtoul(bf, &tail, 0);
-	if (tail == bf || *tail != '/')
-		return -EINVAL;
-
-	bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo);
-	bprm->low_shift = bprm->hi_shift + bo;
-	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
-}
-
-/* String length checking wrapper */
-static int parse_probe_arg(char *arg, struct trace_probe *tp,
-			   struct probe_arg *parg, int is_return)
-{
-	const char *t;
-	int ret;
-
-	if (strlen(arg) > MAX_ARGSTR_LEN) {
-		pr_info("Argument is too long.: %s\n",  arg);
-		return -ENOSPC;
-	}
-	parg->comm = kstrdup(arg, GFP_KERNEL);
-	if (!parg->comm) {
-		pr_info("Failed to allocate memory for command '%s'.\n", arg);
-		return -ENOMEM;
-	}
-	t = strchr(parg->comm, ':');
-	if (t) {
-		arg[t - parg->comm] = '\0';
-		t++;
-	}
-	parg->type = find_fetch_type(t);
-	if (!parg->type) {
-		pr_info("Unsupported type: %s\n", t);
-		return -EINVAL;
-	}
-	parg->offset = tp->size;
-	tp->size += parg->type->size;
-	ret = __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
-	if (ret >= 0 && t != NULL)
-		ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
-	if (ret >= 0) {
-		parg->fetch_size.fn = get_fetch_size_function(parg->type,
-							      parg->fetch.fn);
-		parg->fetch_size.data = parg->fetch.data;
-	}
-	return ret;
-}
-
-/* Return 1 if name is reserved or already used by another argument */
-static int conflict_field_name(const char *name,
-			       struct probe_arg *args, int narg)
-{
-	int i;
-	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
-		if (strcmp(reserved_field_names[i], name) == 0)
-			return 1;
-	for (i = 0; i < narg; i++)
-		if (strcmp(args[i].name, name) == 0)
-			return 1;
-	return 0;
-}
-
 static int create_trace_probe(int argc, char **argv)
 {
 	/*
@@ -1162,7 +375,7 @@ static int create_trace_probe(int argc, char **argv)
 	 */
 	struct trace_probe *tp;
 	int i, ret = 0;
-	int is_return = 0, is_delete = 0;
+	bool is_return = false, is_delete = false;
 	char *symbol = NULL, *event = NULL, *group = NULL;
 	char *arg;
 	unsigned long offset = 0;
@@ -1171,11 +384,11 @@ static int create_trace_probe(int argc, char **argv)
 
 	/* argc must be >= 1 */
 	if (argv[0][0] == 'p')
-		is_return = 0;
+		is_return = false;
 	else if (argv[0][0] == 'r')
-		is_return = 1;
+		is_return = true;
 	else if (argv[0][0] == '-')
-		is_delete = 1;
+		is_delete = true;
 	else {
 		pr_info("Probe definition must be started with 'p', 'r' or"
 			" '-'.\n");
@@ -1240,7 +453,7 @@ static int create_trace_probe(int argc, char **argv)
 		/* a symbol specified */
 		symbol = argv[1];
 		/* TODO: support .init module functions */
-		ret = split_symbol_offset(symbol, &offset);
+		ret = traceprobe_split_symbol_offset(symbol, &offset);
 		if (ret) {
 			pr_info("Failed to parse symbol.\n");
 			return ret;
@@ -1302,7 +515,8 @@ static int create_trace_probe(int argc, char **argv)
 			goto error;
 		}
 
-		if (conflict_field_name(tp->args[i].name, tp->args, i)) {
+		if (traceprobe_conflict_field_name(tp->args[i].name,
+							tp->args, i)) {
 			pr_info("Argument[%d] name '%s' conflicts with "
 				"another field.\n", i, argv[i]);
 			ret = -EINVAL;
@@ -1310,7 +524,8 @@ static int create_trace_probe(int argc, char **argv)
 		}
 
 		/* Parse fetch argument */
-		ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
+		ret = traceprobe_parse_probe_arg(arg, &tp->size,
+					&tp->args[i], is_return, true);
 		if (ret) {
 			pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
 			goto error;
@@ -1412,70 +627,11 @@ static int probes_open(struct inode *inode, struct file *file)
 	return seq_open(file, &probes_seq_op);
 }
 
-static int command_trace_probe(const char *buf)
-{
-	char **argv;
-	int argc = 0, ret = 0;
-
-	argv = argv_split(GFP_KERNEL, buf, &argc);
-	if (!argv)
-		return -ENOMEM;
-
-	if (argc)
-		ret = create_trace_probe(argc, argv);
-
-	argv_free(argv);
-	return ret;
-}
-
-#define WRITE_BUFSIZE 4096
-
 static ssize_t probes_write(struct file *file, const char __user *buffer,
 			    size_t count, loff_t *ppos)
 {
-	char *kbuf, *tmp;
-	int ret;
-	size_t done;
-	size_t size;
-
-	kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL);
-	if (!kbuf)
-		return -ENOMEM;
-
-	ret = done = 0;
-	while (done < count) {
-		size = count - done;
-		if (size >= WRITE_BUFSIZE)
-			size = WRITE_BUFSIZE - 1;
-		if (copy_from_user(kbuf, buffer + done, size)) {
-			ret = -EFAULT;
-			goto out;
-		}
-		kbuf[size] = '\0';
-		tmp = strchr(kbuf, '\n');
-		if (tmp) {
-			*tmp = '\0';
-			size = tmp - kbuf + 1;
-		} else if (done + size < count) {
-			pr_warning("Line length is too long: "
-				   "Should be less than %d.", WRITE_BUFSIZE);
-			ret = -EINVAL;
-			goto out;
-		}
-		done += size;
-		/* Remove comments */
-		tmp = strchr(kbuf, '#');
-		if (tmp)
-			*tmp = '\0';
-
-		ret = command_trace_probe(kbuf);
-		if (ret)
-			goto out;
-	}
-	ret = done;
-out:
-	kfree(kbuf);
-	return ret;
+	return traceprobe_probes_write(file, buffer, count, ppos,
+			create_trace_probe);
 }
 
 static const struct file_operations kprobe_events_ops = {
@@ -1711,16 +867,6 @@ partial:
 	return TRACE_TYPE_PARTIAL_LINE;
 }
 
-#undef DEFINE_FIELD
-#define DEFINE_FIELD(type, item, name, is_signed)			\
-	do {								\
-		ret = trace_define_field(event_call, #type, name,	\
-					 offsetof(typeof(field), item),	\
-					 sizeof(field.item), is_signed, \
-					 FILTER_OTHER);			\
-		if (ret)						\
-			return ret;					\
-	} while (0)
 
 static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
 {
@@ -2045,8 +1191,9 @@ static __init int kprobe_trace_self_tests_init(void)
 
 	pr_info("Testing kprobe tracing: ");
 
-	ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target "
-				  "$stack $stack0 +0($stack)");
+	ret = traceprobe_command("p:testprobe kprobe_trace_selftest_target "
+				  "$stack $stack0 +0($stack)",
+				  create_trace_probe);
 	if (WARN_ON_ONCE(ret)) {
 		pr_warning("error on probing function entry.\n");
 		warn++;
@@ -2060,8 +1207,8 @@ static __init int kprobe_trace_self_tests_init(void)
 			enable_trace_probe(tp, TP_FLAG_TRACE);
 	}
 
-	ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target "
-				  "$retval");
+	ret = traceprobe_command("r:testprobe2 kprobe_trace_selftest_target "
+				  "$retval", create_trace_probe);
 	if (WARN_ON_ONCE(ret)) {
 		pr_warning("error on probing function return.\n");
 		warn++;
@@ -2095,13 +1242,13 @@ static __init int kprobe_trace_self_tests_init(void)
 	} else
 		disable_trace_probe(tp, TP_FLAG_TRACE);
 
-	ret = command_trace_probe("-:testprobe");
+	ret = traceprobe_command("-:testprobe", create_trace_probe);
 	if (WARN_ON_ONCE(ret)) {
 		pr_warning("error on deleting a probe.\n");
 		warn++;
 	}
 
-	ret = command_trace_probe("-:testprobe2");
+	ret = traceprobe_command("-:testprobe2", create_trace_probe);
 	if (WARN_ON_ONCE(ret)) {
 		pr_warning("error on deleting a probe.\n");
 		warn++;
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
new file mode 100644
index 0000000..c0a98e6
--- /dev/null
+++ b/kernel/trace/trace_probe.c
@@ -0,0 +1,786 @@
+/*
+ * Common code for probe-based Dynamic events.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This code was copied from kernel/trace/trace_kprobe.c written by
+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+ *
+ * Updates to make this generic:
+ * Copyright (C) IBM Corporation, 2010-2011
+ * Author:     Srikar Dronamraju
+ */
+
+#include "trace_probe.h"
+
+const char *reserved_field_names[] = {
+	"common_type",
+	"common_flags",
+	"common_preempt_count",
+	"common_pid",
+	"common_tgid",
+	FIELD_STRING_IP,
+	FIELD_STRING_RETIP,
+	FIELD_STRING_FUNC,
+};
+
+/* Printing function type */
+#define PRINT_TYPE_FUNC_NAME(type)	print_type_##type
+#define PRINT_TYPE_FMT_NAME(type)	print_type_format_##type
+
+/* Printing  in basic type function template */
+#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)			\
+static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,	\
+						const char *name,	\
+						void *data, void *ent)\
+{									\
+	return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
+}									\
+static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
+
+DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
+
+static inline void *get_rloc_data(u32 *dl)
+{
+	return (u8 *)dl + get_rloc_offs(*dl);
+}
+
+/* For data_loc conversion */
+static inline void *get_loc_data(u32 *dl, void *ent)
+{
+	return (u8 *)ent + get_rloc_offs(*dl);
+}
+
+/* For defining macros, define string/string_size types */
+typedef u32 string;
+typedef u32 string_size;
+
+/* Print type function for string type */
+static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
+						  const char *name,
+						  void *data, void *ent)
+{
+	int len = *(u32 *)data >> 16;
+
+	if (!len)
+		return trace_seq_printf(s, " %s=(fault)", name);
+	else
+		return trace_seq_printf(s, " %s=\"%s\"", name,
+					(const char *)get_loc_data(data, ent));
+}
+
+static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
+
+#define FETCH_FUNC_NAME(method, type)	fetch_##method##_##type
+/*
+ * Define macro for basic types - we don't need to define s* types, because
+ * we have to care only about bitwidth at recording time.
+ */
+#define DEFINE_BASIC_FETCH_FUNCS(method) \
+DEFINE_FETCH_##method(u8)		\
+DEFINE_FETCH_##method(u16)		\
+DEFINE_FETCH_##method(u32)		\
+DEFINE_FETCH_##method(u64)
+
+#define CHECK_FETCH_FUNCS(method, fn)			\
+	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
+	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
+	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
+	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
+	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
+	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
+	 && (fn != NULL))
+
+/* Data fetch function templates */
+#define DEFINE_FETCH_reg(type)						\
+static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,	\
+					void *offset, void *dest)	\
+{									\
+	*(type *)dest = (type)regs_get_register(regs,			\
+				(unsigned int)((unsigned long)offset));	\
+}
+DEFINE_BASIC_FETCH_FUNCS(reg)
+/* No string on the register */
+#define fetch_reg_string NULL
+#define fetch_reg_string_size NULL
+
+#define DEFINE_FETCH_stack(type)					\
+static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
+					  void *offset, void *dest)	\
+{									\
+	*(type *)dest = (type)regs_get_kernel_stack_nth(regs,		\
+				(unsigned int)((unsigned long)offset));	\
+}
+DEFINE_BASIC_FETCH_FUNCS(stack)
+/* No string on the stack entry */
+#define fetch_stack_string NULL
+#define fetch_stack_string_size NULL
+
+#define DEFINE_FETCH_retval(type)					\
+static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
+					  void *dummy, void *dest)	\
+{									\
+	*(type *)dest = (type)regs_return_value(regs);			\
+}
+DEFINE_BASIC_FETCH_FUNCS(retval)
+/* No string on the retval */
+#define fetch_retval_string NULL
+#define fetch_retval_string_size NULL
+
+#define DEFINE_FETCH_memory(type)					\
+static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
+					  void *addr, void *dest)	\
+{									\
+	type retval;							\
+	if (probe_kernel_address(addr, retval))				\
+		*(type *)dest = 0;					\
+	else								\
+		*(type *)dest = retval;					\
+}
+DEFINE_BASIC_FETCH_FUNCS(memory)
+/*
+ * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
+ * length and relative data location.
+ */
+static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
+						      void *addr, void *dest)
+{
+	long ret;
+	int maxlen = get_rloc_len(*(u32 *)dest);
+	u8 *dst = get_rloc_data(dest);
+	u8 *src = addr;
+	mm_segment_t old_fs = get_fs();
+	if (!maxlen)
+		return;
+	/*
+	 * Try to get string again, since the string can be changed while
+	 * probing.
+	 */
+	set_fs(KERNEL_DS);
+	pagefault_disable();
+	do
+		ret = __copy_from_user_inatomic(dst++, src++, 1);
+	while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
+	dst[-1] = '\0';
+	pagefault_enable();
+	set_fs(old_fs);
+
+	if (ret < 0) {	/* Failed to fetch string */
+		((u8 *)get_rloc_data(dest))[0] = '\0';
+		*(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
+	} else
+		*(u32 *)dest = make_data_rloc(src - (u8 *)addr,
+					      get_rloc_offs(*(u32 *)dest));
+}
+
+/* Return the length of string -- including null terminal byte */
+static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
+							void *addr, void *dest)
+{
+	int ret, len = 0;
+	u8 c;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+	pagefault_disable();
+	do {
+		ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
+		len++;
+	} while (c && ret == 0 && len < MAX_STRING_SIZE);
+	pagefault_enable();
+	set_fs(old_fs);
+
+	if (ret < 0)	/* Failed to check the length */
+		*(u32 *)dest = 0;
+	else
+		*(u32 *)dest = len;
+}
+
+/* Memory fetching by symbol */
+struct symbol_cache {
+	char *symbol;
+	long offset;
+	unsigned long addr;
+};
+
+static unsigned long update_symbol_cache(struct symbol_cache *sc)
+{
+	sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
+	if (sc->addr)
+		sc->addr += sc->offset;
+	return sc->addr;
+}
+
+static void free_symbol_cache(struct symbol_cache *sc)
+{
+	kfree(sc->symbol);
+	kfree(sc);
+}
+
+static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
+{
+	struct symbol_cache *sc;
+
+	if (!sym || strlen(sym) == 0)
+		return NULL;
+	sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
+	if (!sc)
+		return NULL;
+
+	sc->symbol = kstrdup(sym, GFP_KERNEL);
+	if (!sc->symbol) {
+		kfree(sc);
+		return NULL;
+	}
+	sc->offset = offset;
+
+	update_symbol_cache(sc);
+	return sc;
+}
+
+#define DEFINE_FETCH_symbol(type)					\
+static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
+					  void *data, void *dest)	\
+{									\
+	struct symbol_cache *sc = data;					\
+	if (sc->addr)							\
+		fetch_memory_##type(regs, (void *)sc->addr, dest);	\
+	else								\
+		*(type *)dest = 0;					\
+}
+DEFINE_BASIC_FETCH_FUNCS(symbol)
+DEFINE_FETCH_symbol(string)
+DEFINE_FETCH_symbol(string_size)
+
+/* Dereference memory access function */
+struct deref_fetch_param {
+	struct fetch_param orig;
+	long offset;
+};
+
+#define DEFINE_FETCH_deref(type)					\
+static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
+					    void *data, void *dest)	\
+{									\
+	struct deref_fetch_param *dprm = data;				\
+	unsigned long addr;						\
+	call_fetch(&dprm->orig, regs, &addr);				\
+	if (addr) {							\
+		addr += dprm->offset;					\
+		fetch_memory_##type(regs, (void *)addr, dest);		\
+	} else								\
+		*(type *)dest = 0;					\
+}
+DEFINE_BASIC_FETCH_FUNCS(deref)
+DEFINE_FETCH_deref(string)
+DEFINE_FETCH_deref(string_size)
+
+static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
+{
+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
+		update_deref_fetch_param(data->orig.data);
+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
+		update_symbol_cache(data->orig.data);
+}
+
+static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
+{
+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
+		free_deref_fetch_param(data->orig.data);
+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
+		free_symbol_cache(data->orig.data);
+	kfree(data);
+}
+
+/* Bitfield fetch function */
+struct bitfield_fetch_param {
+	struct fetch_param orig;
+	unsigned char hi_shift;
+	unsigned char low_shift;
+};
+
+#define DEFINE_FETCH_bitfield(type)					\
+static __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
+					    void *data, void *dest)	\
+{									\
+	struct bitfield_fetch_param *bprm = data;			\
+	type buf = 0;							\
+	call_fetch(&bprm->orig, regs, &buf);				\
+	if (buf) {							\
+		buf <<= bprm->hi_shift;					\
+		buf >>= bprm->low_shift;				\
+	}								\
+	*(type *)dest = buf;						\
+}
+
+DEFINE_BASIC_FETCH_FUNCS(bitfield)
+#define fetch_bitfield_string NULL
+#define fetch_bitfield_string_size NULL
+
+static __kprobes void
+update_bitfield_fetch_param(struct bitfield_fetch_param *data)
+{
+	/*
+	 * Don't check the bitfield itself, because this must be the
+	 * last fetch function.
+	 */
+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
+		update_deref_fetch_param(data->orig.data);
+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
+		update_symbol_cache(data->orig.data);
+}
+
+static __kprobes void
+free_bitfield_fetch_param(struct bitfield_fetch_param *data)
+{
+	/*
+	 * Don't check the bitfield itself, because this must be the
+	 * last fetch function.
+	 */
+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
+		free_deref_fetch_param(data->orig.data);
+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
+		free_symbol_cache(data->orig.data);
+	kfree(data);
+}
+
+/* Default (unsigned long) fetch type */
+#define __DEFAULT_FETCH_TYPE(t) u##t
+#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
+#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
+#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
+
+#define ASSIGN_FETCH_FUNC(method, type)	\
+	[FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
+
+#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)	\
+	{.name = _name,				\
+	 .size = _size,					\
+	 .is_signed = sign,				\
+	 .print = PRINT_TYPE_FUNC_NAME(ptype),		\
+	 .fmt = PRINT_TYPE_FMT_NAME(ptype),		\
+	 .fmttype = _fmttype,				\
+	 .fetch = {					\
+ASSIGN_FETCH_FUNC(reg, ftype),				\
+ASSIGN_FETCH_FUNC(stack, ftype),			\
+ASSIGN_FETCH_FUNC(retval, ftype),			\
+ASSIGN_FETCH_FUNC(memory, ftype),			\
+ASSIGN_FETCH_FUNC(symbol, ftype),			\
+ASSIGN_FETCH_FUNC(deref, ftype),			\
+ASSIGN_FETCH_FUNC(bitfield, ftype),			\
+	  }						\
+	}
+
+#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)			\
+	__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
+
+#define FETCH_TYPE_STRING 0
+#define FETCH_TYPE_STRSIZE 1
+
+/* Fetch type information table */
+static const struct fetch_type fetch_type_table[] = {
+	/* Special types */
+	[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
+					sizeof(u32), 1, "__data_loc char[]"),
+	[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
+					string_size, sizeof(u32), 0, "u32"),
+	/* Basic types */
+	ASSIGN_FETCH_TYPE(u8,  u8,  0),
+	ASSIGN_FETCH_TYPE(u16, u16, 0),
+	ASSIGN_FETCH_TYPE(u32, u32, 0),
+	ASSIGN_FETCH_TYPE(u64, u64, 0),
+	ASSIGN_FETCH_TYPE(s8,  u8,  1),
+	ASSIGN_FETCH_TYPE(s16, u16, 1),
+	ASSIGN_FETCH_TYPE(s32, u32, 1),
+	ASSIGN_FETCH_TYPE(s64, u64, 1),
+};
+
+static const struct fetch_type *find_fetch_type(const char *type)
+{
+	int i;
+
+	if (!type)
+		type = DEFAULT_FETCH_TYPE_STR;
+
+	/* Special case: bitfield */
+	if (*type == 'b') {
+		unsigned long bs;
+		type = strchr(type, '/');
+		if (!type)
+			goto fail;
+		type++;
+		if (strict_strtoul(type, 0, &bs))
+			goto fail;
+		switch (bs) {
+		case 8:
+			return find_fetch_type("u8");
+		case 16:
+			return find_fetch_type("u16");
+		case 32:
+			return find_fetch_type("u32");
+		case 64:
+			return find_fetch_type("u64");
+		default:
+			goto fail;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
+		if (strcmp(type, fetch_type_table[i].name) == 0)
+			return &fetch_type_table[i];
+fail:
+	return NULL;
+}
+
+/* Special function : only accept unsigned long */
+static __kprobes void fetch_stack_address(struct pt_regs *regs,
+					void *dummy, void *dest)
+{
+	*(unsigned long *)dest = kernel_stack_pointer(regs);
+}
+
+static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
+					fetch_func_t orig_fn)
+{
+	int i;
+
+	if (type != &fetch_type_table[FETCH_TYPE_STRING])
+		return NULL;	/* Only string type needs size function */
+	for (i = 0; i < FETCH_MTD_END; i++)
+		if (type->fetch[i] == orig_fn)
+			return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
+
+	WARN_ON(1);	/* This should not happen */
+	return NULL;
+}
+
+/* Split symbol and offset. */
+int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
+{
+	char *tmp;
+	int ret;
+
+	if (!offset)
+		return -EINVAL;
+
+	tmp = strchr(symbol, '+');
+	if (tmp) {
+		/* skip sign because strict_strtol doesn't accept '+' */
+		ret = strict_strtoul(tmp + 1, 0, offset);
+		if (ret)
+			return ret;
+		*tmp = '\0';
+	} else
+		*offset = 0;
+	return 0;
+}
+
+#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
+
+static int parse_probe_vars(char *arg, const struct fetch_type *t,
+			    struct fetch_param *f, bool is_return)
+{
+	int ret = 0;
+	unsigned long param;
+
+	if (strcmp(arg, "retval") == 0) {
+		if (is_return)
+			f->fn = t->fetch[FETCH_MTD_retval];
+		else
+			ret = -EINVAL;
+	} else if (strncmp(arg, "stack", 5) == 0) {
+		if (arg[5] == '\0') {
+			if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
+				f->fn = fetch_stack_address;
+			else
+				ret = -EINVAL;
+		} else if (isdigit(arg[5])) {
+			ret = strict_strtoul(arg + 5, 10, &param);
+			if (ret || param > PARAM_MAX_STACK)
+				ret = -EINVAL;
+			else {
+				f->fn = t->fetch[FETCH_MTD_stack];
+				f->data = (void *)param;
+			}
+		} else
+			ret = -EINVAL;
+	} else
+		ret = -EINVAL;
+	return ret;
+}
+
+/* Recursive argument parser */
+static int parse_probe_arg(char *arg, const struct fetch_type *t,
+		     struct fetch_param *f, bool is_return, bool is_kprobe)
+{
+	int ret = 0;
+	unsigned long param;
+	long offset;
+	char *tmp;
+
+	/* Until uprobe_events supports only reg arguments */
+	if (!is_kprobe && arg[0] != '%')
+		return -EINVAL;
+
+	switch (arg[0]) {
+	case '$':
+		ret = parse_probe_vars(arg + 1, t, f, is_return);
+		break;
+	case '%':	/* named register */
+		ret = regs_query_register_offset(arg + 1);
+		if (ret >= 0) {
+			f->fn = t->fetch[FETCH_MTD_reg];
+			f->data = (void *)(unsigned long)ret;
+			ret = 0;
+		}
+		break;
+	case '@':	/* memory or symbol */
+		if (isdigit(arg[1])) {
+			ret = strict_strtoul(arg + 1, 0, &param);
+			if (ret)
+				break;
+			f->fn = t->fetch[FETCH_MTD_memory];
+			f->data = (void *)param;
+		} else {
+			ret = traceprobe_split_symbol_offset(arg + 1, &offset);
+			if (ret)
+				break;
+			f->data = alloc_symbol_cache(arg + 1, offset);
+			if (f->data)
+				f->fn = t->fetch[FETCH_MTD_symbol];
+		}
+		break;
+	case '+':	/* deref memory */
+		arg++;	/* Skip '+', because strict_strtol() rejects it. */
+	case '-':
+		tmp = strchr(arg, '(');
+		if (!tmp)
+			break;
+		*tmp = '\0';
+		ret = strict_strtol(arg, 0, &offset);
+		if (ret)
+			break;
+		arg = tmp + 1;
+		tmp = strrchr(arg, ')');
+		if (tmp) {
+			struct deref_fetch_param *dprm;
+			const struct fetch_type *t2 = find_fetch_type(NULL);
+			*tmp = '\0';
+			dprm = kzalloc(sizeof(struct deref_fetch_param),
+				       GFP_KERNEL);
+			if (!dprm)
+				return -ENOMEM;
+			dprm->offset = offset;
+			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return,
+							is_kprobe);
+			if (ret)
+				kfree(dprm);
+			else {
+				f->fn = t->fetch[FETCH_MTD_deref];
+				f->data = (void *)dprm;
+			}
+		}
+		break;
+	}
+	if (!ret && !f->fn) {	/* Parsed, but do not find fetch method */
+		pr_info("%s type has no corresponding fetch method.\n",
+			t->name);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+#define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
+
+/* Bitfield type needs to be parsed into a fetch function */
+static int __parse_bitfield_probe_arg(const char *bf,
+				      const struct fetch_type *t,
+				      struct fetch_param *f)
+{
+	struct bitfield_fetch_param *bprm;
+	unsigned long bw, bo;
+	char *tail;
+
+	if (*bf != 'b')
+		return 0;
+
+	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
+	if (!bprm)
+		return -ENOMEM;
+	bprm->orig = *f;
+	f->fn = t->fetch[FETCH_MTD_bitfield];
+	f->data = (void *)bprm;
+
+	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
+	if (bw == 0 || *tail != '@')
+		return -EINVAL;
+
+	bf = tail + 1;
+	bo = simple_strtoul(bf, &tail, 0);
+	if (tail == bf || *tail != '/')
+		return -EINVAL;
+
+	bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo);
+	bprm->low_shift = bprm->hi_shift + bo;
+	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
+}
+
+/* String length checking wrapper */
+int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
+		struct probe_arg *parg, bool is_return, bool is_kprobe)
+{
+	const char *t;
+	int ret;
+
+	if (strlen(arg) > MAX_ARGSTR_LEN) {
+		pr_info("Argument is too long.: %s\n",  arg);
+		return -ENOSPC;
+	}
+	parg->comm = kstrdup(arg, GFP_KERNEL);
+	if (!parg->comm) {
+		pr_info("Failed to allocate memory for command '%s'.\n", arg);
+		return -ENOMEM;
+	}
+	t = strchr(parg->comm, ':');
+	if (t) {
+		arg[t - parg->comm] = '\0';
+		t++;
+	}
+	parg->type = find_fetch_type(t);
+	if (!parg->type) {
+		pr_info("Unsupported type: %s\n", t);
+		return -EINVAL;
+	}
+	parg->offset = *size;
+	*size += parg->type->size;
+	ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return,
+							is_kprobe);
+	if (ret >= 0 && t != NULL)
+		ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
+	if (ret >= 0) {
+		parg->fetch_size.fn = get_fetch_size_function(parg->type,
+							      parg->fetch.fn);
+		parg->fetch_size.data = parg->fetch.data;
+	}
+	return ret;
+}
+
+/* Return 1 if name is reserved or already used by another argument */
+int traceprobe_conflict_field_name(const char *name,
+			       struct probe_arg *args, int narg)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
+		if (strcmp(reserved_field_names[i], name) == 0)
+			return 1;
+	for (i = 0; i < narg; i++)
+		if (strcmp(args[i].name, name) == 0)
+			return 1;
+	return 0;
+}
+
+void traceprobe_update_arg(struct probe_arg *arg)
+{
+	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
+		update_bitfield_fetch_param(arg->fetch.data);
+	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
+		update_deref_fetch_param(arg->fetch.data);
+	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
+		update_symbol_cache(arg->fetch.data);
+}
+
+void traceprobe_free_probe_arg(struct probe_arg *arg)
+{
+	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
+		free_bitfield_fetch_param(arg->fetch.data);
+	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
+		free_deref_fetch_param(arg->fetch.data);
+	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
+		free_symbol_cache(arg->fetch.data);
+	kfree(arg->name);
+	kfree(arg->comm);
+}
+
+int traceprobe_command(const char *buf, int (*createfn)(int, char **))
+{
+	char **argv;
+	int argc = 0, ret = 0;
+
+	argv = argv_split(GFP_KERNEL, buf, &argc);
+	if (!argv)
+		return -ENOMEM;
+
+	if (argc)
+		ret = createfn(argc, argv);
+
+	argv_free(argv);
+	return ret;
+}
+
+#define WRITE_BUFSIZE 128
+
+ssize_t traceprobe_probes_write(struct file *file, const char __user *buffer,
+				size_t count, loff_t *ppos,
+				int (*createfn)(int, char **))
+{
+	char *kbuf, *tmp;
+	int ret = 0;
+	size_t done = 0;
+	size_t size;
+
+	kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
+
+	while (done < count) {
+		size = count - done;
+		if (size >= WRITE_BUFSIZE)
+			size = WRITE_BUFSIZE - 1;
+		if (copy_from_user(kbuf, buffer + done, size)) {
+			ret = -EFAULT;
+			goto out;
+		}
+		kbuf[size] = '\0';
+		tmp = strchr(kbuf, '\n');
+		if (tmp) {
+			*tmp = '\0';
+			size = tmp - kbuf + 1;
+		} else if (done + size < count) {
+			pr_warning("Line length is too long: "
+				   "Should be less than %d.", WRITE_BUFSIZE);
+			ret = -EINVAL;
+			goto out;
+		}
+		done += size;
+		/* Remove comments */
+		tmp = strchr(kbuf, '#');
+		if (tmp)
+			*tmp = '\0';
+
+		ret = traceprobe_command(kbuf, createfn);
+		if (ret)
+			goto out;
+	}
+	ret = done;
+out:
+	kfree(kbuf);
+	return ret;
+}
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
new file mode 100644
index 0000000..31e635e
--- /dev/null
+++ b/kernel/trace/trace_probe.h
@@ -0,0 +1,162 @@
+/*
+ * Common header file for probe-based Dynamic events.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This code was copied from kernel/trace/trace_kprobe.h written by
+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+ *
+ * Updates to make this generic:
+ * Copyright (C) IBM Corporation, 2010-2011
+ * Author:     Srikar Dronamraju
+ */
+
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/ptrace.h>
+#include <linux/perf_event.h>
+#include <linux/kprobes.h>
+#include <linux/stringify.h>
+#include <linux/limits.h>
+#include <linux/uaccess.h>
+#include <asm/bitsperlong.h>
+
+#include "trace.h"
+#include "trace_output.h"
+
+#define MAX_TRACE_ARGS 128
+#define MAX_ARGSTR_LEN 63
+#define MAX_EVENT_NAME_LEN 64
+#define MAX_STRING_SIZE PATH_MAX
+
+/* Reserved field names */
+#define FIELD_STRING_IP "__probe_ip"
+#define FIELD_STRING_RETIP "__probe_ret_ip"
+#define FIELD_STRING_FUNC "__probe_func"
+
+#undef DEFINE_FIELD
+#define DEFINE_FIELD(type, item, name, is_signed)			\
+	do {								\
+		ret = trace_define_field(event_call, #type, name,	\
+					 offsetof(typeof(field), item),	\
+					 sizeof(field.item), is_signed, \
+					 FILTER_OTHER);			\
+		if (ret)						\
+			return ret;					\
+	} while (0)
+
+
+/* Flags for trace_probe */
+#define TP_FLAG_TRACE	1
+#define TP_FLAG_PROFILE	2
+#define TP_FLAG_REGISTERED 4
+#define TP_FLAG_UPROBE	8
+
+
+/* data_rloc: data relative location, compatible with u32 */
+#define make_data_rloc(len, roffs)	\
+	(((u32)(len) << 16) | ((u32)(roffs) & 0xffff))
+#define get_rloc_len(dl)	((u32)(dl) >> 16)
+#define get_rloc_offs(dl)	((u32)(dl) & 0xffff)
+
+/*
+ * Convert data_rloc to data_loc:
+ *  data_rloc stores the offset from data_rloc itself, but data_loc
+ *  stores the offset from event entry.
+ */
+#define convert_rloc_to_loc(dl, offs)	((u32)(dl) + (offs))
+
+/* Data fetch function type */
+typedef	void (*fetch_func_t)(struct pt_regs *, void *, void *);
+/* Printing function type */
+typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *,
+				 void *);
+
+/* Fetch types */
+enum {
+	FETCH_MTD_reg = 0,
+	FETCH_MTD_stack,
+	FETCH_MTD_retval,
+	FETCH_MTD_memory,
+	FETCH_MTD_symbol,
+	FETCH_MTD_deref,
+	FETCH_MTD_bitfield,
+	FETCH_MTD_END,
+};
+
+/* Fetch type information table */
+struct fetch_type {
+	const char	*name;		/* Name of type */
+	size_t		size;		/* Byte size of type */
+	int		is_signed;	/* Signed flag */
+	print_type_func_t	print;	/* Print functions */
+	const char	*fmt;		/* Fromat string */
+	const char	*fmttype;	/* Name in format file */
+	/* Fetch functions */
+	fetch_func_t	fetch[FETCH_MTD_END];
+};
+
+struct fetch_param {
+	fetch_func_t	fn;
+	void *data;
+};
+
+struct probe_arg {
+	struct fetch_param	fetch;
+	struct fetch_param	fetch_size;
+	unsigned int		offset;	/* Offset from argument entry */
+	const char		*name;	/* Name of this argument */
+	const char		*comm;	/* Command of this argument */
+	const struct fetch_type	*type;	/* Type of this argument */
+};
+
+static inline __kprobes void call_fetch(struct fetch_param *fprm,
+				 struct pt_regs *regs, void *dest)
+{
+	return fprm->fn(regs, fprm->data, dest);
+}
+
+/* Check the name is good for event/group/fields */
+static inline int is_good_name(const char *name)
+{
+	if (!isalpha(*name) && *name != '_')
+		return 0;
+	while (*++name != '\0') {
+		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
+			return 0;
+	}
+	return 1;
+}
+
+extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
+		   struct probe_arg *parg, bool is_return, bool is_kprobe);
+
+extern int traceprobe_conflict_field_name(const char *name,
+			       struct probe_arg *args, int narg);
+
+extern void traceprobe_update_arg(struct probe_arg *arg);
+extern void traceprobe_free_probe_arg(struct probe_arg *arg);
+
+extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
+
+extern ssize_t traceprobe_probes_write(struct file *file,
+		const char __user *buffer, size_t count, loff_t *ppos,
+		int (*createfn)(int, char**));
+
+extern int traceprobe_command(const char *buf, int (*createfn)(int, char**));
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
new file mode 100644
index 0000000..4d3857c
--- /dev/null
+++ b/kernel/trace/trace_uprobe.c
@@ -0,0 +1,772 @@
+/*
+ * uprobes-based tracing events
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright (C) IBM Corporation, 2010
+ * Author:	Srikar Dronamraju
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/uprobes.h>
+#include <linux/namei.h>
+
+#include "trace_probe.h"
+
+#define UPROBE_EVENT_SYSTEM "uprobes"
+
+/**
+ * uprobe event core functions
+ */
+struct trace_uprobe;
+struct uprobe_trace_consumer {
+	struct uprobe_consumer cons;
+	struct trace_uprobe *tp;
+};
+
+struct trace_uprobe {
+	struct list_head	list;
+	struct ftrace_event_class	class;
+	struct ftrace_event_call	call;
+	struct uprobe_trace_consumer	*consumer;
+	struct inode		*inode;
+	char			*filename;
+	unsigned long		offset;
+	unsigned long		nhit;
+	unsigned int		flags;	/* For TP_FLAG_* */
+	ssize_t			size;		/* trace entry size */
+	unsigned int		nr_args;
+	struct probe_arg	args[];
+};
+
+#define SIZEOF_TRACE_UPROBE(n)			\
+	(offsetof(struct trace_uprobe, args) +	\
+	(sizeof(struct probe_arg) * (n)))
+
+static int register_uprobe_event(struct trace_uprobe *tp);
+static void unregister_uprobe_event(struct trace_uprobe *tp);
+
+static DEFINE_MUTEX(uprobe_lock);
+static LIST_HEAD(uprobe_list);
+
+static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
+
+/*
+ * Allocate new trace_uprobe and initialize it (including uprobes).
+ */
+static struct trace_uprobe *alloc_trace_uprobe(const char *group,
+				const char *event, int nargs)
+{
+	struct trace_uprobe *tp;
+
+	if (!event || !is_good_name(event))
+		return ERR_PTR(-EINVAL);
+
+	if (!group || !is_good_name(group))
+		return ERR_PTR(-EINVAL);
+
+	tp = kzalloc(SIZEOF_TRACE_UPROBE(nargs), GFP_KERNEL);
+	if (!tp)
+		return ERR_PTR(-ENOMEM);
+
+	tp->call.class = &tp->class;
+	tp->call.name = kstrdup(event, GFP_KERNEL);
+	if (!tp->call.name)
+		goto error;
+
+	tp->class.system = kstrdup(group, GFP_KERNEL);
+	if (!tp->class.system)
+		goto error;
+
+	INIT_LIST_HEAD(&tp->list);
+	return tp;
+error:
+	kfree(tp->call.name);
+	kfree(tp);
+	return ERR_PTR(-ENOMEM);
+}
+
+static void free_trace_uprobe(struct trace_uprobe *tp)
+{
+	int i;
+
+	for (i = 0; i < tp->nr_args; i++)
+		traceprobe_free_probe_arg(&tp->args[i]);
+
+	iput(tp->inode);
+	kfree(tp->call.class->system);
+	kfree(tp->call.name);
+	kfree(tp->filename);
+	kfree(tp);
+}
+
+static struct trace_uprobe *find_probe_event(const char *event,
+					const char *group)
+{
+	struct trace_uprobe *tp;
+
+	list_for_each_entry(tp, &uprobe_list, list)
+		if (strcmp(tp->call.name, event) == 0 &&
+		    strcmp(tp->call.class->system, group) == 0)
+			return tp;
+	return NULL;
+}
+
+/* Unregister a trace_uprobe and probe_event: call with locking uprobe_lock */
+static void unregister_trace_uprobe(struct trace_uprobe *tp)
+{
+	list_del(&tp->list);
+	unregister_uprobe_event(tp);
+	free_trace_uprobe(tp);
+}
+
+/* Register a trace_uprobe and probe_event */
+static int register_trace_uprobe(struct trace_uprobe *tp)
+{
+	struct trace_uprobe *old_tp;
+	int ret;
+
+	mutex_lock(&uprobe_lock);
+
+	/* register as an event */
+	old_tp = find_probe_event(tp->call.name, tp->call.class->system);
+	if (old_tp)
+		/* delete old event */
+		unregister_trace_uprobe(old_tp);
+
+	ret = register_uprobe_event(tp);
+	if (ret) {
+		pr_warning("Failed to register probe event(%d)\n", ret);
+		goto end;
+	}
+
+	list_add_tail(&tp->list, &uprobe_list);
+end:
+	mutex_unlock(&uprobe_lock);
+	return ret;
+}
+
+static int create_trace_uprobe(int argc, char **argv)
+{
+	/*
+	 * Argument syntax:
+	 *  - Add uprobe: p[:[GRP/]EVENT] VADDR@PID [%REG]
+	 *
+	 *  - Remove uprobe: -:[GRP/]EVENT
+	 */
+	struct path path;
+	struct inode *inode = NULL;
+	struct trace_uprobe *tp;
+	int i, ret = 0;
+	int is_delete = 0;
+	char *arg = NULL, *event = NULL, *group = NULL;
+	unsigned long offset;
+	char buf[MAX_EVENT_NAME_LEN];
+	char *filename;
+
+	/* argc must be >= 1 */
+	if (argv[0][0] == '-')
+		is_delete = 1;
+	else if (argv[0][0] != 'p') {
+		pr_info("Probe definition must be started with 'p', 'r' or"
+			" '-'.\n");
+		return -EINVAL;
+	}
+
+	if (argv[0][1] == ':') {
+		event = &argv[0][2];
+		if (strchr(event, '/')) {
+			group = event;
+			event = strchr(group, '/') + 1;
+			event[-1] = '\0';
+			if (strlen(group) == 0) {
+				pr_info("Group name is not specified\n");
+				return -EINVAL;
+			}
+		}
+		if (strlen(event) == 0) {
+			pr_info("Event name is not specified\n");
+			return -EINVAL;
+		}
+	}
+	if (!group)
+		group = UPROBE_EVENT_SYSTEM;
+
+	if (is_delete) {
+		if (!event) {
+			pr_info("Delete command needs an event name.\n");
+			return -EINVAL;
+		}
+		mutex_lock(&uprobe_lock);
+		tp = find_probe_event(event, group);
+		if (!tp) {
+			mutex_unlock(&uprobe_lock);
+			pr_info("Event %s/%s doesn't exist.\n", group, event);
+			return -ENOENT;
+		}
+		/* delete an event */
+		unregister_trace_uprobe(tp);
+		mutex_unlock(&uprobe_lock);
+		return 0;
+	}
+
+	if (argc < 2) {
+		pr_info("Probe point is not specified.\n");
+		return -EINVAL;
+	}
+	if (isdigit(argv[1][0])) {
+		pr_info("probe point must be have a filename.\n");
+		return -EINVAL;
+	}
+	arg = strchr(argv[1], ':');
+	if (!arg)
+		goto fail_address_parse;
+
+	*arg++ = '\0';
+	filename = argv[1];
+	ret = kern_path(filename, LOOKUP_FOLLOW, &path);
+	if (ret)
+		goto fail_address_parse;
+
+	inode = igrab(path.dentry->d_inode);
+
+	ret = strict_strtoul(arg, 0, &offset);
+		if (ret)
+			goto fail_address_parse;
+
+	argc -= 2;
+	argv += 2;
+
+	/* setup a probe */
+	if (!event) {
+		char *tail = strrchr(filename, '/');
+		char *ptr;
+
+		ptr = kstrdup((tail ? tail + 1 : filename), GFP_KERNEL);
+		if (!ptr) {
+			ret = -ENOMEM;
+			goto fail_address_parse;
+		}
+
+		tail = ptr;
+		ptr = strpbrk(tail, ".-_");
+		if (ptr)
+			*ptr = '\0';
+
+		snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_0x%lx", 'p', tail,
+				offset);
+		event = buf;
+		kfree(tail);
+	}
+	tp = alloc_trace_uprobe(group, event, argc);
+	if (IS_ERR(tp)) {
+		pr_info("Failed to allocate trace_uprobe.(%d)\n",
+			(int)PTR_ERR(tp));
+		iput(inode);
+		return PTR_ERR(tp);
+	}
+	tp->offset = offset;
+	tp->inode = inode;
+	tp->filename = kstrdup(filename, GFP_KERNEL);
+	if (!tp->filename) {
+			pr_info("Failed to allocate filename.\n");
+			ret = -ENOMEM;
+			goto error;
+	}
+
+	/* parse arguments */
+	ret = 0;
+	for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
+		/* Increment count for freeing args in error case */
+		tp->nr_args++;
+
+		/* Parse argument name */
+		arg = strchr(argv[i], '=');
+		if (arg) {
+			*arg++ = '\0';
+			tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
+		} else {
+			arg = argv[i];
+			/* If argument name is omitted, set "argN" */
+			snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
+			tp->args[i].name = kstrdup(buf, GFP_KERNEL);
+		}
+
+		if (!tp->args[i].name) {
+			pr_info("Failed to allocate argument[%d] name.\n", i);
+			ret = -ENOMEM;
+			goto error;
+		}
+
+		if (!is_good_name(tp->args[i].name)) {
+			pr_info("Invalid argument[%d] name: %s\n",
+				i, tp->args[i].name);
+			ret = -EINVAL;
+			goto error;
+		}
+
+		if (traceprobe_conflict_field_name(tp->args[i].name,
+							tp->args, i)) {
+			pr_info("Argument[%d] name '%s' conflicts with "
+				"another field.\n", i, argv[i]);
+			ret = -EINVAL;
+			goto error;
+		}
+
+		/* Parse fetch argument */
+		ret = traceprobe_parse_probe_arg(arg, &tp->size, &tp->args[i],
+								false, false);
+		if (ret) {
+			pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
+			goto error;
+		}
+	}
+
+	ret = register_trace_uprobe(tp);
+	if (ret)
+		goto error;
+	return 0;
+
+error:
+	free_trace_uprobe(tp);
+	return ret;
+
+fail_address_parse:
+	if (inode)
+		iput(inode);
+	pr_info("Failed to parse address.\n");
+	return ret;
+}
+
+static void cleanup_all_probes(void)
+{
+	struct trace_uprobe *tp;
+
+	mutex_lock(&uprobe_lock);
+	while (!list_empty(&uprobe_list)) {
+		tp = list_entry(uprobe_list.next, struct trace_uprobe, list);
+		unregister_trace_uprobe(tp);
+	}
+	mutex_unlock(&uprobe_lock);
+}
+
+/* Probes listing interfaces */
+static void *probes_seq_start(struct seq_file *m, loff_t *pos)
+{
+	mutex_lock(&uprobe_lock);
+	return seq_list_start(&uprobe_list, *pos);
+}
+
+static void *probes_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	return seq_list_next(v, &uprobe_list, pos);
+}
+
+static void probes_seq_stop(struct seq_file *m, void *v)
+{
+	mutex_unlock(&uprobe_lock);
+}
+
+static int probes_seq_show(struct seq_file *m, void *v)
+{
+	struct trace_uprobe *tp = v;
+	int i;
+
+	seq_printf(m, "p:%s/%s", tp->call.class->system, tp->call.name);
+	seq_printf(m, " %s:0x%p", tp->filename, (void *)tp->offset);
+
+	for (i = 0; i < tp->nr_args; i++)
+		seq_printf(m, " %s=%s", tp->args[i].name, tp->args[i].comm);
+	seq_printf(m, "\n");
+	return 0;
+}
+
+static const struct seq_operations probes_seq_op = {
+	.start  = probes_seq_start,
+	.next   = probes_seq_next,
+	.stop   = probes_seq_stop,
+	.show   = probes_seq_show
+};
+
+static int probes_open(struct inode *inode, struct file *file)
+{
+	if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC))
+		cleanup_all_probes();
+
+	return seq_open(file, &probes_seq_op);
+}
+
+static ssize_t probes_write(struct file *file, const char __user *buffer,
+			    size_t count, loff_t *ppos)
+{
+	return traceprobe_probes_write(file, buffer, count, ppos,
+			create_trace_uprobe);
+}
+
+static const struct file_operations uprobe_events_ops = {
+	.owner          = THIS_MODULE,
+	.open           = probes_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = seq_release,
+	.write		= probes_write,
+};
+
+/* Probes profiling interfaces */
+static int probes_profile_seq_show(struct seq_file *m, void *v)
+{
+	struct trace_uprobe *tp = v;
+
+	seq_printf(m, "  %s %-44s %15lu\n", tp->filename, tp->call.name,
+								tp->nhit);
+	return 0;
+}
+
+static const struct seq_operations profile_seq_op = {
+	.start  = probes_seq_start,
+	.next   = probes_seq_next,
+	.stop   = probes_seq_stop,
+	.show   = probes_profile_seq_show
+};
+
+static int profile_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &profile_seq_op);
+}
+
+static const struct file_operations uprobe_profile_ops = {
+	.owner          = THIS_MODULE,
+	.open           = profile_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = seq_release,
+};
+
+/* uprobe handler */
+static void uprobe_trace_func(struct trace_uprobe *tp, struct pt_regs *regs)
+{
+	struct uprobe_trace_entry_head *entry;
+	struct ring_buffer_event *event;
+	struct ring_buffer *buffer;
+	u8 *data;
+	int size, i, pc;
+	unsigned long irq_flags;
+	struct ftrace_event_call *call = &tp->call;
+
+	tp->nhit++;
+
+	local_save_flags(irq_flags);
+	pc = preempt_count();
+
+	size = sizeof(*entry) + tp->size;
+
+	event = trace_current_buffer_lock_reserve(&buffer, call->event.type,
+						  size, irq_flags, pc);
+	if (!event)
+		return;
+
+	entry = ring_buffer_event_data(event);
+	entry->ip = get_uprobe_bkpt_addr(task_pt_regs(current));
+	data = (u8 *)&entry[1];
+	for (i = 0; i < tp->nr_args; i++)
+		call_fetch(&tp->args[i].fetch, regs,
+						data + tp->args[i].offset);
+
+	if (!filter_current_check_discard(buffer, call, entry, event))
+		trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
+}
+
+/* Event entry printers */
+static enum print_line_t
+print_uprobe_event(struct trace_iterator *iter, int flags,
+		   struct trace_event *event)
+{
+	struct uprobe_trace_entry_head *field;
+	struct trace_seq *s = &iter->seq;
+	struct trace_uprobe *tp;
+	u8 *data;
+	int i;
+
+	field = (struct uprobe_trace_entry_head *)iter->ent;
+	tp = container_of(event, struct trace_uprobe, call.event);
+
+	if (!trace_seq_printf(s, "%s: (", tp->call.name))
+		goto partial;
+
+	if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
+		goto partial;
+
+	if (!trace_seq_puts(s, ")"))
+		goto partial;
+
+	data = (u8 *)&field[1];
+	for (i = 0; i < tp->nr_args; i++)
+		if (!tp->args[i].type->print(s, tp->args[i].name,
+					     data + tp->args[i].offset, field))
+			goto partial;
+
+	if (!trace_seq_puts(s, "\n"))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static int probe_event_enable(struct trace_uprobe *tp, int flag)
+{
+	struct uprobe_trace_consumer *utc;
+	int ret = 0;
+
+	if (!tp->inode || tp->consumer)
+		return -EINTR;
+
+	utc = kzalloc(sizeof(struct uprobe_trace_consumer), GFP_KERNEL);
+	if (!utc)
+		return -EINTR;
+
+	utc->cons.handler = uprobe_dispatcher;
+	utc->cons.filter = NULL;
+	ret = register_uprobe(tp->inode, tp->offset, &utc->cons);
+	if (ret) {
+		kfree(utc);
+		return ret;
+	}
+
+	tp->flags |= flag;
+	utc->tp = tp;
+	tp->consumer = utc;
+	return 0;
+}
+
+static void probe_event_disable(struct trace_uprobe *tp, int flag)
+{
+	if (!tp->inode || !tp->consumer)
+		return;
+
+	unregister_uprobe(tp->inode, tp->offset, &tp->consumer->cons);
+	tp->flags &= ~flag;
+	kfree(tp->consumer);
+	tp->consumer = NULL;
+}
+
+static int uprobe_event_define_fields(struct ftrace_event_call *event_call)
+{
+	int ret, i;
+	struct uprobe_trace_entry_head field;
+	struct trace_uprobe *tp = (struct trace_uprobe *)event_call->data;
+
+	DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
+	/* Set argument names as fields */
+	for (i = 0; i < tp->nr_args; i++) {
+		ret = trace_define_field(event_call, tp->args[i].type->fmttype,
+					 tp->args[i].name,
+					 sizeof(field) + tp->args[i].offset,
+					 tp->args[i].type->size,
+					 tp->args[i].type->is_signed,
+					 FILTER_OTHER);
+		if (ret)
+			return ret;
+	}
+	return 0;
+}
+
+static int __set_print_fmt(struct trace_uprobe *tp, char *buf, int len)
+{
+	int i;
+	int pos = 0;
+
+	const char *fmt, *arg;
+
+	fmt = "(%lx)";
+	arg = "REC->" FIELD_STRING_IP;
+
+	/* When len=0, we just calculate the needed length */
+#define LEN_OR_ZERO (len ? len - pos : 0)
+
+	pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
+
+	for (i = 0; i < tp->nr_args; i++) {
+		pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
+				tp->args[i].name, tp->args[i].type->fmt);
+	}
+
+	pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
+
+	for (i = 0; i < tp->nr_args; i++) {
+		pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
+				tp->args[i].name);
+	}
+
+#undef LEN_OR_ZERO
+
+	/* return the length of print_fmt */
+	return pos;
+}
+
+static int set_print_fmt(struct trace_uprobe *tp)
+{
+	int len;
+	char *print_fmt;
+
+	/* First: called with 0 length to calculate the needed length */
+	len = __set_print_fmt(tp, NULL, 0);
+	print_fmt = kmalloc(len + 1, GFP_KERNEL);
+	if (!print_fmt)
+		return -ENOMEM;
+
+	/* Second: actually write the @print_fmt */
+	__set_print_fmt(tp, print_fmt, len + 1);
+	tp->call.print_fmt = print_fmt;
+
+	return 0;
+}
+
+#ifdef CONFIG_PERF_EVENTS
+
+/* uprobe profile handler */
+static void uprobe_perf_func(struct trace_uprobe *tp, struct pt_regs *regs)
+{
+	struct ftrace_event_call *call = &tp->call;
+	struct uprobe_trace_entry_head *entry;
+	struct hlist_head *head;
+	u8 *data;
+	int size, __size, i;
+	int rctx;
+
+	__size = sizeof(*entry) + tp->size;
+	size = ALIGN(__size + sizeof(u32), sizeof(u64));
+	size -= sizeof(u32);
+	if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
+		     "profile buffer not large enough"))
+		return;
+
+	preempt_disable();
+
+	entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
+	if (!entry)
+		goto out;
+
+	entry->ip = get_uprobe_bkpt_addr(task_pt_regs(current));
+	data = (u8 *)&entry[1];
+	for (i = 0; i < tp->nr_args; i++)
+		call_fetch(&tp->args[i].fetch, regs,
+						data + tp->args[i].offset);
+
+	head = this_cpu_ptr(call->perf_events);
+	perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
+ out:
+	preempt_enable();
+}
+#endif	/* CONFIG_PERF_EVENTS */
+
+static
+int uprobe_register(struct ftrace_event_call *event, enum trace_reg type)
+{
+	switch (type) {
+	case TRACE_REG_REGISTER:
+		return probe_event_enable(event->data, TP_FLAG_TRACE);
+	case TRACE_REG_UNREGISTER:
+		probe_event_disable(event->data, TP_FLAG_TRACE);
+		return 0;
+
+#ifdef CONFIG_PERF_EVENTS
+	case TRACE_REG_PERF_REGISTER:
+		return probe_event_enable(event->data, TP_FLAG_PROFILE);
+	case TRACE_REG_PERF_UNREGISTER:
+		probe_event_disable(event->data, TP_FLAG_PROFILE);
+		return 0;
+#endif
+	}
+	return 0;
+}
+
+static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
+{
+	struct uprobe_trace_consumer *utc;
+	struct trace_uprobe *tp;
+
+	utc = container_of(con, struct uprobe_trace_consumer, cons);
+	tp = utc->tp;
+	if (!tp || tp->consumer != utc)
+		return 0;
+
+	if (tp->flags & TP_FLAG_TRACE)
+		uprobe_trace_func(tp, regs);
+#ifdef CONFIG_PERF_EVENTS
+	if (tp->flags & TP_FLAG_PROFILE)
+		uprobe_perf_func(tp, regs);
+#endif
+	return 0;
+}
+
+static struct trace_event_functions uprobe_funcs = {
+	.trace		= print_uprobe_event
+};
+
+static int register_uprobe_event(struct trace_uprobe *tp)
+{
+	struct ftrace_event_call *call = &tp->call;
+	int ret;
+
+	/* Initialize ftrace_event_call */
+	INIT_LIST_HEAD(&call->class->fields);
+	call->event.funcs = &uprobe_funcs;
+	call->class->define_fields = uprobe_event_define_fields;
+	if (set_print_fmt(tp) < 0)
+		return -ENOMEM;
+	ret = register_ftrace_event(&call->event);
+	if (!ret) {
+		kfree(call->print_fmt);
+		return -ENODEV;
+	}
+	call->flags = 0;
+	call->class->reg = uprobe_register;
+	call->data = tp;
+	ret = trace_add_event_call(call);
+	if (ret) {
+		pr_info("Failed to register uprobe event: %s\n", call->name);
+		kfree(call->print_fmt);
+		unregister_ftrace_event(&call->event);
+	}
+	return ret;
+}
+
+static void unregister_uprobe_event(struct trace_uprobe *tp)
+{
+	/* tp->event is unregistered in trace_remove_event_call() */
+	trace_remove_event_call(&tp->call);
+	kfree(tp->call.print_fmt);
+	tp->call.print_fmt = NULL;
+}
+
+/* Make a trace interface for controling probe points */
+static __init int init_uprobe_trace(void)
+{
+	struct dentry *d_tracer;
+
+	d_tracer = tracing_init_dentry();
+	if (!d_tracer)
+		return 0;
+
+	trace_create_file("uprobe_events", 0644, d_tracer,
+				    NULL, &uprobe_events_ops);
+	/* Profile interface */
+	trace_create_file("uprobe_profile", 0444, d_tracer,
+				    NULL, &uprobe_profile_ops);
+	return 0;
+}
+
+fs_initcall(init_uprobe_trace);
diff --git a/kernel/uprobes.c b/kernel/uprobes.c
new file mode 100644
index 0000000..96cf12c
--- /dev/null
+++ b/kernel/uprobes.c
@@ -0,0 +1,1546 @@
+/*
+ * Userspace Probes (UProbes)
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2008-2011
+ * Authors:
+ *	Srikar Dronamraju
+ *	Jim Keniston
+ */
+
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>	/* read_mapping_page */
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/rmap.h>		/* anon_vma_prepare */
+#include <linux/mmu_notifier.h>	/* set_pte_at_notify */
+#include <linux/swap.h>		/* try_to_free_swap */
+#include <linux/ptrace.h>	/* user_enable_single_step */
+#include <linux/kdebug.h>	/* notifier mechanism */
+#include <linux/uprobes.h>
+
+#define UINSNS_PER_PAGE	(PAGE_SIZE/UPROBES_XOL_SLOT_BYTES)
+#define MAX_UPROBES_XOL_SLOTS UINSNS_PER_PAGE
+
+static struct srcu_struct uprobes_srcu;
+static struct rb_root uprobes_tree = RB_ROOT;
+static DEFINE_SPINLOCK(uprobes_treelock);	/* serialize rbtree access */
+
+#define UPROBES_HASH_SZ	13
+/* serialize (un)register */
+static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
+#define uprobes_hash(v)	(&uprobes_mutex[((unsigned long)(v)) %\
+						UPROBES_HASH_SZ])
+
+/* serialize uprobe->pending_list */
+static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
+#define uprobes_mmap_hash(v)	(&uprobes_mmap_mutex[((unsigned long)(v)) %\
+						UPROBES_HASH_SZ])
+
+/*
+ * uprobe_events allows us to skip the mmap_uprobe if there are no uprobe
+ * events active at this time.  Probably a fine grained per inode count is
+ * better?
+ */
+static atomic_t uprobe_events = ATOMIC_INIT(0);
+
+/*
+ * Maintain a temporary per vma info that can be used to search if a vma
+ * has already been handled. This structure is introduced since extending
+ * vm_area_struct wasnt recommended.
+ */
+struct vma_info {
+	struct list_head probe_list;
+	struct mm_struct *mm;
+	loff_t vaddr;
+};
+
+/*
+ * valid_vma: Verify if the specified vma is an executable vma
+ * Relax restrictions while unregistering: vm_flags might have
+ * changed after breakpoint was inserted.
+ *	- is_register: indicates if we are in register context.
+ *	- Return 1 if the specified virtual address is in an
+ *	  executable vma.
+ */
+static bool valid_vma(struct vm_area_struct *vma, bool is_register)
+{
+	if (!vma->vm_file)
+		return false;
+
+	if (!is_register)
+		return true;
+
+	if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) ==
+						(VM_READ|VM_EXEC))
+		return true;
+
+	return false;
+}
+
+static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
+{
+	loff_t vaddr;
+
+	vaddr = vma->vm_start + offset;
+	vaddr -= vma->vm_pgoff << PAGE_SHIFT;
+	return vaddr;
+}
+
+/**
+ * __replace_page - replace page in vma by new page.
+ * based on replace_page in mm/ksm.c
+ *
+ * @vma:      vma that holds the pte pointing to page
+ * @page:     the cowed page we are replacing by kpage
+ * @kpage:    the modified page we replace page by
+ *
+ * Returns 0 on success, -EFAULT on failure.
+ */
+static int __replace_page(struct vm_area_struct *vma, struct page *page,
+					struct page *kpage)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *ptep;
+	spinlock_t *ptl;
+	unsigned long addr;
+	int err = -EFAULT;
+
+	addr = page_address_in_vma(page, vma);
+	if (addr == -EFAULT)
+		goto out;
+
+	pgd = pgd_offset(mm, addr);
+	if (!pgd_present(*pgd))
+		goto out;
+
+	pud = pud_offset(pgd, addr);
+	if (!pud_present(*pud))
+		goto out;
+
+	pmd = pmd_offset(pud, addr);
+	if (!pmd_present(*pmd))
+		goto out;
+
+	ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
+	if (!ptep)
+		goto out;
+
+	get_page(kpage);
+	page_add_new_anon_rmap(kpage, vma, addr);
+
+	flush_cache_page(vma, addr, pte_pfn(*ptep));
+	ptep_clear_flush(vma, addr, ptep);
+	set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot));
+
+	page_remove_rmap(page);
+	if (!page_mapped(page))
+		try_to_free_swap(page);
+	put_page(page);
+	pte_unmap_unlock(ptep, ptl);
+	err = 0;
+
+out:
+	return err;
+}
+
+/**
+ * is_bkpt_insn - check if instruction is breakpoint instruction.
+ * @insn: instruction to be checked.
+ * Default implementation of is_bkpt_insn
+ * Returns true if @insn is a breakpoint instruction.
+ */
+bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
+{
+	return (*insn == UPROBES_BKPT_INSN);
+}
+
+/*
+ * NOTE:
+ * Expect the breakpoint instruction to be the smallest size instruction for
+ * the architecture. If an arch has variable length instruction and the
+ * breakpoint instruction is not of the smallest length instruction
+ * supported by that architecture then we need to modify read_opcode /
+ * write_opcode accordingly. This would never be a problem for archs that
+ * have fixed length instructions.
+ */
+
+/*
+ * write_opcode - write the opcode at a given virtual address.
+ * @mm: the probed process address space.
+ * @uprobe: the breakpointing information.
+ * @vaddr: the virtual address to store the opcode.
+ * @opcode: opcode to be written at @vaddr.
+ *
+ * Called with mm->mmap_sem held (for read and with a reference to
+ * mm).
+ *
+ * For mm @mm, write the opcode at @vaddr.
+ * Return 0 (success) or a negative errno.
+ */
+static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
+			unsigned long vaddr, uprobe_opcode_t opcode)
+{
+	struct page *old_page, *new_page;
+	struct address_space *mapping;
+	void *vaddr_old, *vaddr_new;
+	struct vm_area_struct *vma;
+	loff_t addr;
+	int ret;
+
+	/* Read the page with vaddr into memory */
+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
+	if (ret <= 0)
+		return ret;
+	ret = -EINVAL;
+
+	/*
+	 * We are interested in text pages only. Our pages of interest
+	 * should be mapped for read and execute only. We desist from
+	 * adding probes in write mapped pages since the breakpoints
+	 * might end up in the file copy.
+	 */
+	if (!valid_vma(vma, is_bkpt_insn(&opcode)))
+		goto put_out;
+
+	mapping = uprobe->inode->i_mapping;
+	if (mapping != vma->vm_file->f_mapping)
+		goto put_out;
+
+	addr = vma_address(vma, uprobe->offset);
+	if (vaddr != (unsigned long)addr)
+		goto put_out;
+
+	ret = -ENOMEM;
+	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
+	if (!new_page)
+		goto put_out;
+
+	__SetPageUptodate(new_page);
+
+	/*
+	 * lock page will serialize against do_wp_page()'s
+	 * PageAnon() handling
+	 */
+	lock_page(old_page);
+	/* copy the page now that we've got it stable */
+	vaddr_old = kmap_atomic(old_page);
+	vaddr_new = kmap_atomic(new_page);
+
+	memcpy(vaddr_new, vaddr_old, PAGE_SIZE);
+	/* poke the new insn in, ASSUMES we don't cross page boundary */
+	vaddr &= ~PAGE_MASK;
+	BUG_ON(vaddr + uprobe_opcode_sz > PAGE_SIZE);
+	memcpy(vaddr_new + vaddr, &opcode, uprobe_opcode_sz);
+
+	kunmap_atomic(vaddr_new);
+	kunmap_atomic(vaddr_old);
+
+	ret = anon_vma_prepare(vma);
+	if (ret)
+		goto unlock_out;
+
+	lock_page(new_page);
+	ret = __replace_page(vma, old_page, new_page);
+	unlock_page(new_page);
+
+unlock_out:
+	unlock_page(old_page);
+	page_cache_release(new_page);
+
+put_out:
+	put_page(old_page);	/* we did a get_page in the beginning */
+	return ret;
+}
+
+/**
+ * read_opcode - read the opcode at a given virtual address.
+ * @mm: the probed process address space.
+ * @vaddr: the virtual address to read the opcode.
+ * @opcode: location to store the read opcode.
+ *
+ * Called with mm->mmap_sem held (for read and with a reference to
+ * mm.
+ *
+ * For mm @mm, read the opcode at @vaddr and store it in @opcode.
+ * Return 0 (success) or a negative errno.
+ */
+static int read_opcode(struct mm_struct *mm, unsigned long vaddr,
+						uprobe_opcode_t *opcode)
+{
+	struct page *page;
+	void *vaddr_new;
+	int ret;
+
+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL);
+	if (ret <= 0)
+		return ret;
+
+	lock_page(page);
+	vaddr_new = kmap_atomic(page);
+	vaddr &= ~PAGE_MASK;
+	memcpy(opcode, vaddr_new + vaddr, uprobe_opcode_sz);
+	kunmap_atomic(vaddr_new);
+	unlock_page(page);
+	put_page(page);		/* we did a get_user_pages in the beginning */
+	return 0;
+}
+
+static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
+{
+	uprobe_opcode_t opcode;
+	int result = read_opcode(mm, vaddr, &opcode);
+
+	if (result)
+		return result;
+
+	if (is_bkpt_insn(&opcode))
+		return 1;
+
+	return 0;
+}
+
+/**
+ * set_bkpt - store breakpoint at a given address.
+ * @mm: the probed process address space.
+ * @uprobe: the probepoint information.
+ * @vaddr: the virtual address to insert the opcode.
+ *
+ * For mm @mm, store the breakpoint instruction at @vaddr.
+ * Return 0 (success) or a negative errno.
+ */
+int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
+						unsigned long vaddr)
+{
+	int result = is_bkpt_at_addr(mm, vaddr);
+
+	if (result == 1)
+		return -EEXIST;
+
+	if (result)
+		return result;
+
+	return write_opcode(mm, uprobe, vaddr, UPROBES_BKPT_INSN);
+}
+
+/**
+ * set_orig_insn - Restore the original instruction.
+ * @mm: the probed process address space.
+ * @uprobe: the probepoint information.
+ * @vaddr: the virtual address to insert the opcode.
+ * @verify: if true, verify existance of breakpoint instruction.
+ *
+ * For mm @mm, restore the original opcode (opcode) at @vaddr.
+ * Return 0 (success) or a negative errno.
+ */
+int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe,
+					unsigned long vaddr, bool verify)
+{
+	if (verify) {
+		int result = is_bkpt_at_addr(mm, vaddr);
+
+		if (!result)
+			return -EINVAL;
+
+		if (result != 1)
+			return result;
+	}
+	return write_opcode(mm, uprobe, vaddr,
+				*(uprobe_opcode_t *)uprobe->insn);
+}
+
+static int match_uprobe(struct uprobe *l, struct uprobe *r)
+{
+	if (l->inode < r->inode)
+		return -1;
+	if (l->inode > r->inode)
+		return 1;
+	else {
+		if (l->offset < r->offset)
+			return -1;
+
+		if (l->offset > r->offset)
+			return 1;
+	}
+
+	return 0;
+}
+
+static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
+{
+	struct uprobe u = { .inode = inode, .offset = offset };
+	struct rb_node *n = uprobes_tree.rb_node;
+	struct uprobe *uprobe;
+	int match;
+
+	while (n) {
+		uprobe = rb_entry(n, struct uprobe, rb_node);
+		match = match_uprobe(&u, uprobe);
+		if (!match) {
+			atomic_inc(&uprobe->ref);
+			return uprobe;
+		}
+		if (match < 0)
+			n = n->rb_left;
+		else
+			n = n->rb_right;
+	}
+	return NULL;
+}
+
+/*
+ * Find a uprobe corresponding to a given inode:offset
+ * Acquires uprobes_treelock
+ */
+static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
+{
+	struct uprobe *uprobe;
+	unsigned long flags;
+
+	spin_lock_irqsave(&uprobes_treelock, flags);
+	uprobe = __find_uprobe(inode, offset);
+	spin_unlock_irqrestore(&uprobes_treelock, flags);
+	return uprobe;
+}
+
+static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
+{
+	struct rb_node **p = &uprobes_tree.rb_node;
+	struct rb_node *parent = NULL;
+	struct uprobe *u;
+	int match;
+
+	while (*p) {
+		parent = *p;
+		u = rb_entry(parent, struct uprobe, rb_node);
+		match = match_uprobe(uprobe, u);
+		if (!match) {
+			atomic_inc(&u->ref);
+			return u;
+		}
+
+		if (match < 0)
+			p = &parent->rb_left;
+		else
+			p = &parent->rb_right;
+
+	}
+	u = NULL;
+	rb_link_node(&uprobe->rb_node, parent, p);
+	rb_insert_color(&uprobe->rb_node, &uprobes_tree);
+	/* get access + creation ref */
+	atomic_set(&uprobe->ref, 2);
+	return u;
+}
+
+/*
+ * Acquires uprobes_treelock.
+ * Matching uprobe already exists in rbtree;
+ *	increment (access refcount) and return the matching uprobe.
+ *
+ * No matching uprobe; insert the uprobe in rb_tree;
+ *	get a double refcount (access + creation) and return NULL.
+ */
+static struct uprobe *insert_uprobe(struct uprobe *uprobe)
+{
+	unsigned long flags;
+	struct uprobe *u;
+
+	spin_lock_irqsave(&uprobes_treelock, flags);
+	u = __insert_uprobe(uprobe);
+	spin_unlock_irqrestore(&uprobes_treelock, flags);
+
+	/* For now assume that the instruction need not be single-stepped */
+	uprobe->flags |= UPROBES_SKIP_SSTEP;
+	return u;
+}
+
+static void put_uprobe(struct uprobe *uprobe)
+{
+	if (atomic_dec_and_test(&uprobe->ref))
+		kfree(uprobe);
+}
+
+static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
+{
+	struct uprobe *uprobe, *cur_uprobe;
+
+	uprobe = kzalloc(sizeof(struct uprobe), GFP_KERNEL);
+	if (!uprobe)
+		return NULL;
+
+	uprobe->inode = igrab(inode);
+	uprobe->offset = offset;
+	init_rwsem(&uprobe->consumer_rwsem);
+	INIT_LIST_HEAD(&uprobe->pending_list);
+
+	/* add to uprobes_tree, sorted on inode:offset */
+	cur_uprobe = insert_uprobe(uprobe);
+
+	/* a uprobe exists for this inode:offset combination */
+	if (cur_uprobe) {
+		kfree(uprobe);
+		uprobe = cur_uprobe;
+		iput(inode);
+	} else
+		atomic_inc(&uprobe_events);
+	return uprobe;
+}
+
+static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
+{
+	struct uprobe_consumer *consumer;
+
+	if (!(uprobe->flags & UPROBES_RUN_HANDLER))
+		return;
+
+	down_read(&uprobe->consumer_rwsem);
+	consumer = uprobe->consumers;
+	for (consumer = uprobe->consumers; consumer;
+					consumer = consumer->next) {
+		if (!consumer->filter ||
+				consumer->filter(consumer, current))
+			consumer->handler(consumer, regs);
+	}
+	up_read(&uprobe->consumer_rwsem);
+}
+
+/* Returns the previous consumer */
+static struct uprobe_consumer *add_consumer(struct uprobe *uprobe,
+				struct uprobe_consumer *consumer)
+{
+	down_write(&uprobe->consumer_rwsem);
+	consumer->next = uprobe->consumers;
+	uprobe->consumers = consumer;
+	up_write(&uprobe->consumer_rwsem);
+	return consumer->next;
+}
+
+/*
+ * For uprobe @uprobe, delete the consumer @consumer.
+ * Return true if the @consumer is deleted successfully
+ * or return false.
+ */
+static bool del_consumer(struct uprobe *uprobe,
+				struct uprobe_consumer *consumer)
+{
+	struct uprobe_consumer **con;
+	bool ret = false;
+
+	down_write(&uprobe->consumer_rwsem);
+	for (con = &uprobe->consumers; *con; con = &(*con)->next) {
+		if (*con == consumer) {
+			*con = consumer->next;
+			ret = true;
+			break;
+		}
+	}
+	up_write(&uprobe->consumer_rwsem);
+	return ret;
+}
+
+static int __copy_insn(struct address_space *mapping,
+			struct vm_area_struct *vma, char *insn,
+			unsigned long nbytes, unsigned long offset)
+{
+	struct file *filp = vma->vm_file;
+	struct page *page;
+	void *vaddr;
+	unsigned long off1;
+	unsigned long idx;
+
+	if (!filp)
+		return -EINVAL;
+
+	idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT);
+	off1 = offset &= ~PAGE_MASK;
+
+	/*
+	 * Ensure that the page that has the original instruction is
+	 * populated and in page-cache.
+	 */
+	page = read_mapping_page(mapping, idx, filp);
+	if (IS_ERR(page))
+		return PTR_ERR(page);
+
+	vaddr = kmap_atomic(page);
+	memcpy(insn, vaddr + off1, nbytes);
+	kunmap_atomic(vaddr);
+	page_cache_release(page);
+	return 0;
+}
+
+static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma,
+					unsigned long addr)
+{
+	struct address_space *mapping;
+	int bytes;
+	unsigned long nbytes;
+
+	addr &= ~PAGE_MASK;
+	nbytes = PAGE_SIZE - addr;
+	mapping = uprobe->inode->i_mapping;
+
+	/* Instruction at end of binary; copy only available bytes */
+	if (uprobe->offset + MAX_UINSN_BYTES > uprobe->inode->i_size)
+		bytes = uprobe->inode->i_size - uprobe->offset;
+	else
+		bytes = MAX_UINSN_BYTES;
+
+	/* Instruction at the page-boundary; copy bytes in second page */
+	if (nbytes < bytes) {
+		if (__copy_insn(mapping, vma, uprobe->insn + nbytes,
+				bytes - nbytes, uprobe->offset + nbytes))
+			return -ENOMEM;
+
+		bytes = nbytes;
+	}
+	return __copy_insn(mapping, vma, uprobe->insn, bytes, uprobe->offset);
+}
+
+/*
+ * How mm_uprobes_count gets updated
+ * mmap_uprobe() increments the count if
+ * 	- it successfully adds a breakpoint.
+ * 	- it not add a breakpoint, but sees that there is a underlying
+ * 	  breakpoint (via a is_bkpt_at_addr()).
+ *
+ * munmap_uprobe() decrements the count if
+ * 	- it sees a underlying breakpoint, (via is_bkpt_at_addr)
+ * 	- Subsequent unregister_uprobe wouldnt find the breakpoint
+ * 	  unless a mmap_uprobe kicks in, since the old vma would be
+ * 	  dropped just after munmap_uprobe.
+ *
+ * register_uprobe increments the count if:
+ * 	- it successfully adds a breakpoint.
+ *
+ * unregister_uprobe decrements the count if:
+ * 	- it sees a underlying breakpoint and removes successfully.
+ * 			(via is_bkpt_at_addr)
+ * 	- Subsequent munmap_uprobe wouldnt find the breakpoint
+ * 	  since there is no underlying breakpoint after the
+ * 	  breakpoint removal.
+ */
+
+static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
+				struct vm_area_struct *vma, loff_t vaddr)
+{
+	unsigned long addr;
+	int ret;
+
+	/*
+	 * If probe is being deleted, unregister thread could be done with
+	 * the vma-rmap-walk through. Adding a probe now can be fatal since
+	 * nobody will be able to cleanup. Also we could be from fork or
+	 * mremap path, where the probe might have already been inserted.
+	 * Hence behave as if probe already existed.
+	 */
+	if (!uprobe->consumers)
+		return -EEXIST;
+
+	addr = (unsigned long)vaddr;
+	if (!(uprobe->flags & UPROBES_COPY_INSN)) {
+		ret = copy_insn(uprobe, vma, addr);
+		if (ret)
+			return ret;
+
+		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn))
+			return -EEXIST;
+
+		ret = analyze_insn(mm, uprobe);
+		if (ret)
+			return ret;
+
+		uprobe->flags |= UPROBES_COPY_INSN;
+	}
+
+	/*
+	 * Ideally, should be updating the probe count after the breakpoint
+	 * has been successfully inserted. However a thread could hit the
+	 * breakpoint we just inserted even before the probe count is
+	 * incremented. If this is the first breakpoint placed, breakpoint
+	 * notifier might ignore uprobes and pass the trap to the thread.
+	 * Hence increment before and decrement on failure.
+	 */
+	atomic_inc(&mm->mm_uprobes_count);
+	ret = set_bkpt(mm, uprobe, addr);
+	if (ret)
+		atomic_dec(&mm->mm_uprobes_count);
+
+	return ret;
+}
+
+static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
+							loff_t vaddr)
+{
+	if (!set_orig_insn(mm, uprobe, (unsigned long)vaddr, true))
+		atomic_dec(&mm->mm_uprobes_count);
+}
+
+/*
+ * There could be threads that have hit the breakpoint and are entering the
+ * notifier code and trying to acquire the uprobes_treelock. The thread
+ * calling delete_uprobe() that is removing the uprobe from the rb_tree can
+ * race with these threads and might acquire the uprobes_treelock compared
+ * to some of the breakpoint hit threads. In such a case, the breakpoint hit
+ * threads will not find the uprobe. Hence wait till the current breakpoint
+ * hit threads acquire the uprobes_treelock before the uprobe is removed
+ * from the rbtree.
+ */
+static void delete_uprobe(struct uprobe *uprobe)
+{
+	unsigned long flags;
+
+	synchronize_srcu(&uprobes_srcu);
+	spin_lock_irqsave(&uprobes_treelock, flags);
+	rb_erase(&uprobe->rb_node, &uprobes_tree);
+	spin_unlock_irqrestore(&uprobes_treelock, flags);
+	iput(uprobe->inode);
+	put_uprobe(uprobe);
+	atomic_dec(&uprobe_events);
+}
+
+static struct vma_info *__find_next_vma_info(struct list_head *head,
+			loff_t offset, struct address_space *mapping,
+			struct vma_info *vi, bool is_register)
+{
+	struct prio_tree_iter iter;
+	struct vm_area_struct *vma;
+	struct vma_info *tmpvi;
+	loff_t vaddr;
+	unsigned long pgoff = offset >> PAGE_SHIFT;
+	int existing_vma;
+
+	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+		if (!valid_vma(vma, is_register))
+			continue;
+
+		existing_vma = 0;
+		vaddr = vma_address(vma, offset);
+		list_for_each_entry(tmpvi, head, probe_list) {
+			if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) {
+				existing_vma = 1;
+				break;
+			}
+		}
+
+		/*
+		 * Another vma needs a probe to be installed. However skip
+		 * installing the probe if the vma is about to be unlinked.
+		 */
+		if (!existing_vma &&
+				atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
+			vi->mm = vma->vm_mm;
+			vi->vaddr = vaddr;
+			list_add(&vi->probe_list, head);
+			return vi;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * Iterate in the rmap prio tree  and find a vma where a probe has not
+ * yet been inserted.
+ */
+static struct vma_info *find_next_vma_info(struct list_head *head,
+			loff_t offset, struct address_space *mapping,
+			bool is_register)
+{
+	struct vma_info *vi, *retvi;
+	vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL);
+	if (!vi)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&mapping->i_mmap_mutex);
+	retvi = __find_next_vma_info(head, offset, mapping, vi, is_register);
+	mutex_unlock(&mapping->i_mmap_mutex);
+
+	if (!retvi)
+		kfree(vi);
+	return retvi;
+}
+
+static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
+{
+	struct list_head try_list;
+	struct vm_area_struct *vma;
+	struct address_space *mapping;
+	struct vma_info *vi, *tmpvi;
+	struct mm_struct *mm;
+	loff_t vaddr;
+	int ret = 0;
+
+	mapping = uprobe->inode->i_mapping;
+	INIT_LIST_HEAD(&try_list);
+	while ((vi = find_next_vma_info(&try_list, uprobe->offset,
+					mapping, is_register)) != NULL) {
+		if (IS_ERR(vi)) {
+			ret = PTR_ERR(vi);
+			break;
+		}
+		mm = vi->mm;
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, (unsigned long)vi->vaddr);
+		if (!vma || !valid_vma(vma, is_register)) {
+			list_del(&vi->probe_list);
+			kfree(vi);
+			up_read(&mm->mmap_sem);
+			mmput(mm);
+			continue;
+		}
+		vaddr = vma_address(vma, uprobe->offset);
+		if (vma->vm_file->f_mapping->host != uprobe->inode ||
+						vaddr != vi->vaddr) {
+			list_del(&vi->probe_list);
+			kfree(vi);
+			up_read(&mm->mmap_sem);
+			mmput(mm);
+			continue;
+		}
+
+		if (is_register)
+			ret = install_breakpoint(mm, uprobe, vma, vi->vaddr);
+		else
+			remove_breakpoint(mm, uprobe, vi->vaddr);
+
+		up_read(&mm->mmap_sem);
+		mmput(mm);
+		if (is_register) {
+			if (ret && ret == -EEXIST)
+				ret = 0;
+			if (ret)
+				break;
+		}
+	}
+	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
+		list_del(&vi->probe_list);
+		kfree(vi);
+	}
+	return ret;
+}
+
+static int __register_uprobe(struct uprobe *uprobe)
+{
+	return register_for_each_vma(uprobe, true);
+}
+
+static void __unregister_uprobe(struct uprobe *uprobe)
+{
+	if (!register_for_each_vma(uprobe, false))
+		delete_uprobe(uprobe);
+
+	/* TODO : cant unregister? schedule a worker thread */
+}
+
+/*
+ * register_uprobe - register a probe
+ * @inode: the file in which the probe has to be placed.
+ * @offset: offset from the start of the file.
+ * @consumer: information on howto handle the probe..
+ *
+ * Apart from the access refcount, register_uprobe() takes a creation
+ * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
+ * inserted into the rbtree (i.e first consumer for a @inode:@offset
+ * tuple).  Creation refcount stops unregister_uprobe from freeing the
+ * @uprobe even before the register operation is complete. Creation
+ * refcount is released when the last @consumer for the @uprobe
+ * unregisters.
+ *
+ * Return errno if it cannot successully install probes
+ * else return 0 (success)
+ */
+int register_uprobe(struct inode *inode, loff_t offset,
+				struct uprobe_consumer *consumer)
+{
+	struct uprobe *uprobe;
+	int ret = -EINVAL;
+
+	if (!inode || !consumer || consumer->next)
+		return ret;
+
+	if (offset > i_size_read(inode))
+		return ret;
+
+	ret = 0;
+	mutex_lock(uprobes_hash(inode));
+	uprobe = alloc_uprobe(inode, offset);
+	if (uprobe && !add_consumer(uprobe, consumer)) {
+		ret = __register_uprobe(uprobe);
+		if (ret) {
+			uprobe->consumers = NULL;
+			__unregister_uprobe(uprobe);
+		} else
+			uprobe->flags |= UPROBES_RUN_HANDLER;
+	}
+
+	mutex_unlock(uprobes_hash(inode));
+	put_uprobe(uprobe);
+
+	return ret;
+}
+
+/*
+ * unregister_uprobe - unregister a already registered probe.
+ * @inode: the file in which the probe has to be removed.
+ * @offset: offset from the start of the file.
+ * @consumer: identify which probe if multiple probes are colocated.
+ */
+void unregister_uprobe(struct inode *inode, loff_t offset,
+				struct uprobe_consumer *consumer)
+{
+	struct uprobe *uprobe = NULL;
+
+	if (!inode || !consumer)
+		return;
+
+	uprobe = find_uprobe(inode, offset);
+	if (!uprobe)
+		return;
+
+	mutex_lock(uprobes_hash(inode));
+	if (!del_consumer(uprobe, consumer))
+		goto unreg_out;
+
+	if (!uprobe->consumers) {
+		__unregister_uprobe(uprobe);
+		uprobe->flags &= ~UPROBES_RUN_HANDLER;
+	}
+
+unreg_out:
+	mutex_unlock(uprobes_hash(inode));
+	if (uprobe)
+		put_uprobe(uprobe);
+}
+
+/*
+ * Of all the nodes that correspond to the given inode, return the node
+ * with the least offset.
+ */
+static struct rb_node *find_least_offset_node(struct inode *inode)
+{
+	struct uprobe u = { .inode = inode, .offset = 0};
+	struct rb_node *n = uprobes_tree.rb_node;
+	struct rb_node *close_node = NULL;
+	struct uprobe *uprobe;
+	int match;
+
+	while (n) {
+		uprobe = rb_entry(n, struct uprobe, rb_node);
+		match = match_uprobe(&u, uprobe);
+		if (uprobe->inode == inode)
+			close_node = n;
+
+		if (!match)
+			return close_node;
+
+		if (match < 0)
+			n = n->rb_left;
+		else
+			n = n->rb_right;
+	}
+	return close_node;
+}
+
+/*
+ * For a given inode, build a list of probes that need to be inserted.
+ */
+static void build_probe_list(struct inode *inode, struct list_head *head)
+{
+	struct uprobe *uprobe;
+	struct rb_node *n;
+	unsigned long flags;
+
+	spin_lock_irqsave(&uprobes_treelock, flags);
+	n = find_least_offset_node(inode);
+	for (; n; n = rb_next(n)) {
+		uprobe = rb_entry(n, struct uprobe, rb_node);
+		if (uprobe->inode != inode)
+			break;
+
+		list_add(&uprobe->pending_list, head);
+		atomic_inc(&uprobe->ref);
+	}
+	spin_unlock_irqrestore(&uprobes_treelock, flags);
+}
+
+/*
+ * Called from mmap_region.
+ * called with mm->mmap_sem acquired.
+ *
+ * Return -ve no if we fail to insert probes and we cannot
+ * bail-out.
+ * Return 0 otherwise. i.e :
+ *	- successful insertion of probes
+ *	- (or) no possible probes to be inserted.
+ *	- (or) insertion of probes failed but we can bail-out.
+ */
+int mmap_uprobe(struct vm_area_struct *vma)
+{
+	struct list_head tmp_list;
+	struct uprobe *uprobe, *u;
+	struct inode *inode;
+	int ret = 0, count = 0;
+
+	if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
+		return ret;	/* Bail-out */
+
+	inode = vma->vm_file->f_mapping->host;
+	if (!inode)
+		return ret;
+
+	INIT_LIST_HEAD(&tmp_list);
+	mutex_lock(uprobes_mmap_hash(inode));
+	build_probe_list(inode, &tmp_list);
+	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
+		loff_t vaddr;
+
+		list_del(&uprobe->pending_list);
+		if (!ret) {
+			vaddr = vma_address(vma, uprobe->offset);
+			if (vaddr < vma->vm_start || vaddr >= vma->vm_end) {
+				put_uprobe(uprobe);
+				continue;
+			}
+			ret = install_breakpoint(vma->vm_mm, uprobe, vma,
+								vaddr);
+			if (ret == -EEXIST) {
+				ret = 0;
+				if (!is_bkpt_at_addr(vma->vm_mm, vaddr))
+					continue;
+
+				/*
+				 * Unable to insert a breakpoint, but
+				 * breakpoint lies underneath. Increment the
+				 * probe count.
+				 */
+				atomic_inc(&vma->vm_mm->mm_uprobes_count);
+			}
+			if (!ret)
+				count++;
+
+		}
+		put_uprobe(uprobe);
+	}
+
+	mutex_unlock(uprobes_mmap_hash(inode));
+	if (ret)
+		atomic_sub(count, &vma->vm_mm->mm_uprobes_count);
+
+	return ret;
+}
+
+/*
+ * Called in context of a munmap of a vma.
+ */
+void munmap_uprobe(struct vm_area_struct *vma)
+{
+	struct list_head tmp_list;
+	struct uprobe *uprobe, *u;
+	struct inode *inode;
+
+	if (!atomic_read(&uprobe_events) || !valid_vma(vma, false))
+		return;		/* Bail-out */
+
+	if (!atomic_read(&vma->vm_mm->mm_uprobes_count))
+		return;
+
+	inode = vma->vm_file->f_mapping->host;
+	if (!inode)
+		return;
+
+	INIT_LIST_HEAD(&tmp_list);
+	mutex_lock(uprobes_mmap_hash(inode));
+	build_probe_list(inode, &tmp_list);
+	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
+		loff_t vaddr;
+
+		list_del(&uprobe->pending_list);
+		vaddr = vma_address(vma, uprobe->offset);
+		if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
+
+			/*
+			 * An unregister could have removed the probe before
+			 * unmap. So check before we decrement the count.
+			 */
+			if (is_bkpt_at_addr(vma->vm_mm, vaddr) == 1)
+				atomic_dec(&vma->vm_mm->mm_uprobes_count);
+		}
+		put_uprobe(uprobe);
+	}
+	mutex_unlock(uprobes_mmap_hash(inode));
+	return;
+}
+
+/* Slot allocation for XOL */
+static int xol_add_vma(struct uprobes_xol_area *area)
+{
+	struct mm_struct *mm;
+	int ret;
+
+	area->page = alloc_page(GFP_HIGHUSER);
+	if (!area->page)
+		return -ENOMEM;
+
+	mm = current->mm;
+	down_write(&mm->mmap_sem);
+	ret = -EALREADY;
+	if (mm->uprobes_xol_area)
+		goto fail;
+
+	ret = -ENOMEM;
+
+	/* Try to map as high as possible, this is only a hint. */
+	area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE,
+							PAGE_SIZE, 0, 0);
+	if (area->vaddr & ~PAGE_MASK) {
+		ret = area->vaddr;
+		goto fail;
+	}
+
+	ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
+				VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO,
+				&area->page);
+	if (ret)
+		goto fail;
+
+	smp_wmb();	/* pairs with get_uprobes_xol_area() */
+	mm->uprobes_xol_area = area;
+	ret = 0;
+
+fail:
+	up_write(&mm->mmap_sem);
+	if (ret)
+		__free_page(area->page);
+
+	return ret;
+}
+
+static struct uprobes_xol_area *get_uprobes_xol_area(struct mm_struct *mm)
+{
+	struct uprobes_xol_area *area = mm->uprobes_xol_area;
+	smp_read_barrier_depends();/* pairs with wmb in xol_add_vma() */
+	return area;
+}
+
+/*
+ * xol_alloc_area - Allocate process's uprobes_xol_area.
+ * This area will be used for storing instructions for execution out of
+ * line.
+ *
+ * Returns the allocated area or NULL.
+ */
+static struct uprobes_xol_area *xol_alloc_area(void)
+{
+	struct uprobes_xol_area *area;
+
+	area = kzalloc(sizeof(*area), GFP_KERNEL);
+	if (unlikely(!area))
+		return NULL;
+
+	area->bitmap = kzalloc(BITS_TO_LONGS(UINSNS_PER_PAGE) * sizeof(long),
+								GFP_KERNEL);
+
+	if (!area->bitmap)
+		goto fail;
+
+	init_waitqueue_head(&area->wq);
+	if (!xol_add_vma(area))
+		return area;
+
+fail:
+	kfree(area->bitmap);
+	kfree(area);
+	return get_uprobes_xol_area(current->mm);
+}
+
+/*
+ * free_uprobes_xol_area - Free the area allocated for slots.
+ */
+void free_uprobes_xol_area(struct mm_struct *mm)
+{
+	struct uprobes_xol_area *area = mm->uprobes_xol_area;
+
+	if (!area)
+		return;
+
+	put_page(area->page);
+	kfree(area->bitmap);
+	kfree(area);
+}
+
+/*
+ *  - search for a free slot.
+ */
+static unsigned long xol_take_insn_slot(struct uprobes_xol_area *area)
+{
+	unsigned long slot_addr;
+	int slot_nr;
+
+	do {
+		slot_nr = find_first_zero_bit(area->bitmap, UINSNS_PER_PAGE);
+		if (slot_nr < UINSNS_PER_PAGE) {
+			if (!test_and_set_bit(slot_nr, area->bitmap))
+				break;
+
+			slot_nr = UINSNS_PER_PAGE;
+			continue;
+		}
+		wait_event(area->wq,
+			(atomic_read(&area->slot_count) < UINSNS_PER_PAGE));
+	} while (slot_nr >= UINSNS_PER_PAGE);
+
+	slot_addr = area->vaddr + (slot_nr * UPROBES_XOL_SLOT_BYTES);
+	atomic_inc(&area->slot_count);
+	return slot_addr;
+}
+
+/*
+ * xol_get_insn_slot - If was not allocated a slot, then
+ * allocate a slot.
+ * Returns the allocated slot address or 0.
+ */
+static unsigned long xol_get_insn_slot(struct uprobe *uprobe,
+					unsigned long slot_addr)
+{
+	struct uprobes_xol_area *area;
+	unsigned long offset;
+	void *vaddr;
+
+	area = get_uprobes_xol_area(current->mm);
+	if (!area) {
+		area = xol_alloc_area();
+		if (!area)
+			return 0;
+	}
+	current->utask->xol_vaddr = xol_take_insn_slot(area);
+
+	/*
+	 * Initialize the slot if xol_vaddr points to valid
+	 * instruction slot.
+	 */
+	if (unlikely(!current->utask->xol_vaddr))
+		return 0;
+
+	current->utask->vaddr = slot_addr;
+	offset = current->utask->xol_vaddr & ~PAGE_MASK;
+	vaddr = kmap_atomic(area->page);
+	memcpy(vaddr + offset, uprobe->insn, MAX_UINSN_BYTES);
+	kunmap_atomic(vaddr);
+	return current->utask->xol_vaddr;
+}
+
+/*
+ * xol_free_insn_slot - If slot was earlier allocated by
+ * @xol_get_insn_slot(), make the slot available for
+ * subsequent requests.
+ */
+static void xol_free_insn_slot(struct task_struct *tsk)
+{
+	struct uprobes_xol_area *area;
+	unsigned long vma_end;
+	unsigned long slot_addr;
+
+	if (!tsk->mm || !tsk->mm->uprobes_xol_area || !tsk->utask)
+		return;
+
+	slot_addr = tsk->utask->xol_vaddr;
+
+	if (unlikely(!slot_addr || IS_ERR_VALUE(slot_addr)))
+		return;
+
+	area = tsk->mm->uprobes_xol_area;
+	vma_end = area->vaddr + PAGE_SIZE;
+	if (area->vaddr <= slot_addr && slot_addr < vma_end) {
+		int slot_nr;
+		unsigned long offset = slot_addr - area->vaddr;
+
+		slot_nr = offset / UPROBES_XOL_SLOT_BYTES;
+		if (slot_nr >= UINSNS_PER_PAGE)
+			return;
+
+		clear_bit(slot_nr, area->bitmap);
+		atomic_dec(&area->slot_count);
+		if (waitqueue_active(&area->wq))
+			wake_up(&area->wq);
+		tsk->utask->xol_vaddr = 0;
+	}
+}
+
+/**
+ * get_uprobe_bkpt_addr - compute address of bkpt given post-bkpt regs
+ * @regs: Reflects the saved state of the task after it has hit a breakpoint
+ * instruction.
+ * Return the address of the breakpoint instruction.
+ */
+unsigned long __weak get_uprobe_bkpt_addr(struct pt_regs *regs)
+{
+	return instruction_pointer(regs) - UPROBES_BKPT_INSN_SIZE;
+}
+
+/*
+ * Called with no locks held.
+ * Called in context of a exiting or a exec-ing thread.
+ */
+void free_uprobe_utask(struct task_struct *tsk)
+{
+	struct uprobe_task *utask = tsk->utask;
+
+	if (tsk->uprobes_srcu_id != -1)
+		srcu_read_unlock_raw(&uprobes_srcu, tsk->uprobes_srcu_id);
+
+	if (!utask)
+		return;
+
+	if (utask->active_uprobe)
+		put_uprobe(utask->active_uprobe);
+
+	xol_free_insn_slot(tsk);
+	kfree(utask);
+	tsk->utask = NULL;
+}
+
+/*
+ * Allocate a uprobe_task object for the task.
+ * Called when the thread hits a breakpoint for the first time.
+ *
+ * Returns:
+ * - pointer to new uprobe_task on success
+ * - NULL otherwise
+ */
+static struct uprobe_task *add_utask(void)
+{
+	struct uprobe_task *utask;
+
+	utask = kzalloc(sizeof *utask, GFP_KERNEL);
+	if (unlikely(utask == NULL))
+		return NULL;
+
+	utask->active_uprobe = NULL;
+	current->utask = utask;
+	return utask;
+}
+
+/* Prepare to single-step probed instruction out of line. */
+static int pre_ssout(struct uprobe *uprobe, struct pt_regs *regs,
+				unsigned long vaddr)
+{
+	if (xol_get_insn_slot(uprobe, vaddr) && !pre_xol(uprobe, regs))
+		return 0;
+	return -EFAULT;
+}
+
+/*
+ * If we are singlestepping, then ensure this thread is not connected to
+ * non-fatal signals until completion of singlestep.  When xol insn itself
+ * triggers the signal,  restart the original insn even if the task is
+ * already SIGKILL'ed (since coredump should report the correct ip).  This
+ * is even more important if the task has a handler for SIGSEGV/etc, The
+ * _same_ instruction should be repeated again after return from the signal
+ * handler, and SSTEP can never finish in this case.
+ */
+bool uprobe_deny_signal(void)
+{
+	struct task_struct *tsk = current;
+	struct uprobe_task *utask = tsk->utask;
+
+	if (likely(!utask || !utask->active_uprobe))
+		return false;
+
+	WARN_ON_ONCE(utask->state != UTASK_SSTEP);
+
+	if (signal_pending(tsk)) {
+		spin_lock_irq(&tsk->sighand->siglock);
+		clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
+		spin_unlock_irq(&tsk->sighand->siglock);
+
+		if (__fatal_signal_pending(tsk) || xol_was_trapped(tsk)) {
+			utask->state = UTASK_SSTEP_TRAPPED;
+			set_tsk_thread_flag(tsk, TIF_UPROBE);
+			set_tsk_thread_flag(tsk, TIF_NOTIFY_RESUME);
+		}
+	}
+
+	return true;
+}
+
+bool __weak uprobe_skip_sstep(struct pt_regs *regs, struct uprobe *u)
+{
+	u->flags &= ~UPROBES_SKIP_SSTEP;
+	return false;
+}
+
+/*
+ * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag.  (and on
+ * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and
+ * allows the thread to return from interrupt.  While returning to
+ * userspace, thread noticies the TIF_UPROBE flag and calls
+ * uprobe_notify_resume(). uprobe_notify_resume will run the handler and ask
+ * the thread to singlestep.
+ *
+ * On subsequent singlestep exception, singlestep notifier sets the
+ * TIF_UPROBE flag and also sets the state to UTASK_SSTEP_ACK and allows the
+ * thread to return from interrupt. While returning to userspace, thread
+ * notices the TIF_UPROBE and calls uprobe_notify_resume().
+ * uprobe_notify_resume disables singlestep and performs the required
+ * fix-ups.
+ *
+ * All non-fatal signals cannot interrupt thread while the thread singlesteps.
+ */
+void uprobe_notify_resume(struct pt_regs *regs)
+{
+	struct vm_area_struct *vma;
+	struct uprobe_task *utask;
+	struct mm_struct *mm;
+	struct uprobe *u = NULL;
+	unsigned long probept;
+
+	utask = current->utask;
+	mm = current->mm;
+	if (!utask || utask->state == UTASK_BP_HIT) {
+		probept = get_uprobe_bkpt_addr(regs);
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, probept);
+		if (vma && vma->vm_start <= probept && valid_vma(vma, false))
+			u = find_uprobe(vma->vm_file->f_mapping->host,
+					probept - vma->vm_start +
+					(vma->vm_pgoff << PAGE_SHIFT));
+
+		srcu_read_unlock_raw(&uprobes_srcu,
+					current->uprobes_srcu_id);
+		current->uprobes_srcu_id = -1;
+		up_read(&mm->mmap_sem);
+		if (!u)
+			/* No matching uprobe; signal SIGTRAP. */
+			goto cleanup_ret;
+		if (!utask) {
+			utask = add_utask();
+			/* Cannot Allocate; re-execute the instruction. */
+			if (!utask)
+				goto cleanup_ret;
+		}
+		utask->active_uprobe = u;
+		handler_chain(u, regs);
+
+		if (u->flags & UPROBES_SKIP_SSTEP && uprobe_skip_sstep(regs, u))
+			goto cleanup_ret;
+
+		utask->state = UTASK_SSTEP;
+		if (!pre_ssout(u, regs, probept))
+			user_enable_single_step(current);
+		else
+			/* Cannot Singlestep; re-execute the instruction. */
+			goto cleanup_ret;
+	} else {
+		u = utask->active_uprobe;
+		if (utask->state == UTASK_SSTEP_ACK)
+			post_xol(u, regs);
+		else if (utask->state == UTASK_SSTEP_TRAPPED)
+			abort_xol(regs, u);
+		else
+			WARN_ON_ONCE(1);
+
+		put_uprobe(u);
+		utask->active_uprobe = NULL;
+		utask->state = UTASK_RUNNING;
+		user_disable_single_step(current);
+		xol_free_insn_slot(current);
+
+		spin_lock_irq(&current->sighand->siglock);
+		recalc_sigpending(); /* see uprobe_deny_signal() */
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+	return;
+
+cleanup_ret:
+	if (utask) {
+		utask->active_uprobe = NULL;
+		utask->state = UTASK_RUNNING;
+	}
+	if (u) {
+		if (!(u->flags & UPROBES_SKIP_SSTEP))
+			instruction_pointer_set(regs, probept);
+
+		put_uprobe(u);
+	} else
+		send_sig(SIGTRAP, current, 0);
+}
+
+/*
+ * uprobe_bkpt_notifier gets called from interrupt context as part of
+ * notifier mechanism. Set TIF_UPROBE flag and indicate breakpoint hit.
+ */
+int uprobe_bkpt_notifier(struct pt_regs *regs)
+{
+	struct uprobe_task *utask;
+
+	if (!current->mm || !atomic_read(&current->mm->mm_uprobes_count))
+		/* task is currently not uprobed */
+		return 0;
+
+	utask = current->utask;
+	if (utask)
+		utask->state = UTASK_BP_HIT;
+
+	set_thread_flag(TIF_UPROBE);
+	current->uprobes_srcu_id = srcu_read_lock_raw(&uprobes_srcu);
+	return 1;
+}
+
+/*
+ * uprobe_post_notifier gets called in interrupt context as part of notifier
+ * mechanism. Set TIF_UPROBE flag and indicate completion of singlestep.
+ */
+int uprobe_post_notifier(struct pt_regs *regs)
+{
+	struct uprobe_task *utask = current->utask;
+
+	if (!current->mm || !utask || !utask->active_uprobe)
+		/* task is currently not uprobed */
+		return 0;
+
+	utask->state = UTASK_SSTEP_ACK;
+	set_thread_flag(TIF_UPROBE);
+	return 1;
+}
+
+struct notifier_block uprobe_exception_nb = {
+	.notifier_call = uprobe_exception_notify,
+	.priority = INT_MAX - 1,	/* notified after kprobes, kgdb */
+};
+
+static int __init init_uprobes(void)
+{
+	int i;
+
+	for (i = 0; i < UPROBES_HASH_SZ; i++) {
+		mutex_init(&uprobes_mutex[i]);
+		mutex_init(&uprobes_mmap_mutex[i]);
+	}
+	init_srcu_struct(&uprobes_srcu);
+	return register_die_notifier(&uprobe_exception_nb);
+}
+
+static void __exit exit_uprobes(void)
+{
+}
+
+module_init(init_uprobes);
+module_exit(exit_uprobes);
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index d117262..14bc092 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -3,12 +3,9 @@
  *
  * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc.
  *
- * this code detects hard lockups: incidents in where on a CPU
- * the kernel does not respond to anything except NMI.
- *
- * Note: Most of this code is borrowed heavily from softlockup.c,
- * so thanks to Ingo for the initial implementation.
- * Some chunks also taken from arch/x86/kernel/apic/nmi.c, thanks
+ * Note: Most of this code is borrowed heavily from the original softlockup
+ * detector, so thanks to Ingo for the initial implementation.
+ * Some chunks also taken from the old x86-specific nmi watchdog code, thanks
  * to those contributors as well.
  */
 
@@ -117,9 +114,10 @@ static unsigned long get_sample_period(void)
 {
 	/*
 	 * convert watchdog_thresh from seconds to ns
-	 * the divide by 5 is to give hrtimer 5 chances to
-	 * increment before the hardlockup detector generates
-	 * a warning
+	 * the divide by 5 is to give hrtimer several chances (two
+	 * or three with the current relation between the soft
+	 * and hard thresholds) to increment before the
+	 * hardlockup detector generates a warning
 	 */
 	return get_softlockup_thresh() * (NSEC_PER_SEC / 5);
 }
@@ -336,9 +334,11 @@ static int watchdog(void *unused)
 
 	set_current_state(TASK_INTERRUPTIBLE);
 	/*
-	 * Run briefly once per second to reset the softlockup timestamp.
-	 * If this gets delayed for more than 60 seconds then the
-	 * debug-printout triggers in watchdog_timer_fn().
+	 * Run briefly (kicked by the hrtimer callback function) once every
+	 * get_sample_period() seconds (4 seconds by default) to reset the
+	 * softlockup timestamp. If this gets delayed for more than
+	 * 2*watchdog_thresh seconds then the debug-printout triggers in
+	 * watchdog_timer_fn().
 	 */
 	while (!kthread_should_stop()) {
 		__touch_watchdog();
diff --git a/lib/Kconfig b/lib/Kconfig
index 028aba9..43359bb 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -61,14 +61,67 @@ config CRC_ITU_T
 	  functions require M here.
 
 config CRC32
-	tristate "CRC32 functions"
+	tristate "CRC32/CRC32c functions"
 	default y
 	select BITREVERSE
 	help
 	  This option is provided for the case where no in-kernel-tree
-	  modules require CRC32 functions, but a module built outside the
-	  kernel tree does. Such modules that use library CRC32 functions
-	  require M here.
+	  modules require CRC32/CRC32c functions, but a module built outside
+	  the kernel tree does. Such modules that use library CRC32/CRC32c
+	  functions require M here.
+
+config CRC32_SELFTEST
+	bool "CRC32 perform self test on init"
+	default n
+	depends on CRC32
+	help
+	  This option enables the CRC32 library functions to perform a
+	  self test on initialization. The self test computes crc32_le
+	  and crc32_be over byte strings with random alignment and length
+	  and computes the total elapsed time and number of bytes processed.
+
+choice
+	prompt "CRC32 implementation"
+	depends on CRC32
+	default CRC32_SLICEBY8
+
+config CRC32_SLICEBY8
+	bool "Slice by 8 bytes"
+	help
+	  Calculate checksum 8 bytes at a time with a clever slicing algorithm.
+	  This is the fastest algorithm, but comes with a 8KiB lookup table.
+	  Most modern processors have enough cache to hold this table without
+	  thrashing the cache.
+
+	  This is the default implementation choice.  Choose this one unless
+	  you have a good reason not to.
+
+config CRC32_SLICEBY4
+	bool "Slice by 4 bytes"
+	help
+	  Calculate checksum 4 bytes at a time with a clever slicing algorithm.
+	  This is a bit slower than slice by 8, but has a smaller 4KiB lookup
+	  table.
+
+	  Only choose this option if you know what you are doing.
+
+config CRC32_SARWATE
+	bool "Sarwate's Algorithm (one byte at a time)"
+	help
+	  Calculate checksum a byte at a time using Sarwate's algorithm.  This
+	  is not particularly fast, but has a small 256 byte lookup table.
+
+	  Only choose this option if you know what you are doing.
+
+config CRC32_BIT
+	bool "Classic Algorithm (one bit at a time)"
+	help
+	  Calculate checksum one bit at a time.  This is VERY slow, but has
+	  no lookup table.  This is provided as a debugging option.
+
+	  Only choose this option if you are debugging crc32.
+
+endchoice
 
 config CRC7
 	tristate "CRC7 functions"
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8745ac7..f7af95d 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -166,22 +166,25 @@ config LOCKUP_DETECTOR
 	  hard and soft lockups.
 
 	  Softlockups are bugs that cause the kernel to loop in kernel
-	  mode for more than 60 seconds, without giving other tasks a
+	  mode for more than 20 seconds, without giving other tasks a
 	  chance to run.  The current stack trace is displayed upon
 	  detection and the system will stay locked up.
 
 	  Hardlockups are bugs that cause the CPU to loop in kernel mode
-	  for more than 60 seconds, without letting other interrupts have a
+	  for more than 10 seconds, without letting other interrupts have a
 	  chance to run.  The current stack trace is displayed upon detection
 	  and the system will stay locked up.
 
 	  The overhead should be minimal.  A periodic hrtimer runs to
-	  generate interrupts and kick the watchdog task every 10-12 seconds.
-	  An NMI is generated every 60 seconds or so to check for hardlockups.
+	  generate interrupts and kick the watchdog task every 4 seconds.
+	  An NMI is generated every 10 seconds or so to check for hardlockups.
+
+	  The frequency of hrtimer and NMI events and the soft and hard lockup
+	  thresholds can be controlled through the sysctl watchdog_thresh.
 
 config HARDLOCKUP_DETECTOR
 	def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \
-		 !ARCH_HAS_NMI_WATCHDOG
+		 !HAVE_NMI_WATCHDOG
 
 config BOOTPARAM_HARDLOCKUP_PANIC
 	bool "Panic (Reboot) On Hard Lockups"
@@ -189,7 +192,8 @@ config BOOTPARAM_HARDLOCKUP_PANIC
 	help
 	  Say Y here to enable the kernel to panic on "hard lockups",
 	  which are bugs that cause the kernel to loop in kernel
-	  mode with interrupts disabled for more than 60 seconds.
+	  mode with interrupts disabled for more than 10 seconds (configurable
+	  using the watchdog_thresh sysctl).
 
 	  Say N if unsure.
 
@@ -206,8 +210,8 @@ config BOOTPARAM_SOFTLOCKUP_PANIC
 	help
 	  Say Y here to enable the kernel to panic on "soft lockups",
 	  which are bugs that cause the kernel to loop in kernel
-	  mode for more than 60 seconds, without giving other tasks a
-	  chance to run.
+	  mode for more than 20 seconds (configurable using the watchdog_thresh
+	  sysctl), without giving other tasks a chance to run.
 
 	  The panic can be used in combination with panic_timeout,
 	  to cause the system to reboot automatically after a
@@ -927,6 +931,30 @@ config RCU_CPU_STALL_VERBOSE
 
 	  Say Y if you want to enable such checks.
 
+config RCU_CPU_STALL_INFO
+	bool "Print additional diagnostics on RCU CPU stall"
+	depends on (TREE_RCU || TREE_PREEMPT_RCU) && DEBUG_KERNEL
+	default n
+	help
+	  For each stalled CPU that is aware of the current RCU grace
+	  period, print out additional per-CPU diagnostic information
+	  regarding scheduling-clock ticks, idle state, and,
+	  for RCU_FAST_NO_HZ kernels, idle-entry state.
+
+	  Say N if you are unsure.
+
+	  Say Y if you want to enable such diagnostics.
+
+config RCU_TRACE
+	bool "Enable tracing for RCU"
+	depends on DEBUG_KERNEL
+	help
+	  This option provides tracing in RCU which presents stats
+	  in debugfs for debugging RCU implementation.
+
+	  Say Y here if you want to enable RCU tracing
+	  Say N if you are unsure.
+
 config KPROBES_SANITY_TEST
 	bool "Kprobes sanity tests"
 	depends on DEBUG_KERNEL
@@ -1113,14 +1141,6 @@ config LATENCYTOP
 	  Enable this option if you want to use the LatencyTOP tool
 	  to find out which userspace is blocking on what kernel operations.
 
-config SYSCTL_SYSCALL_CHECK
-	bool "Sysctl checks"
-	depends on SYSCTL
-	---help---
-	  sys_sysctl uses binary paths that have been found challenging
-	  to properly maintain and use. This enables checks that help
-	  you to keep things correct.
-
 source mm/Kconfig.debug
 source kernel/trace/Kconfig
 
diff --git a/lib/cpumask.c b/lib/cpumask.c
index af3e5817..0470742 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -26,18 +26,6 @@ int __next_cpu_nr(int n, const cpumask_t *srcp)
 EXPORT_SYMBOL(__next_cpu_nr);
 #endif
 
-int __any_online_cpu(const cpumask_t *mask)
-{
-	int cpu;
-
-	for_each_cpu(cpu, mask) {
-		if (cpu_online(cpu))
-			break;
-	}
-	return cpu;
-}
-EXPORT_SYMBOL(__any_online_cpu);
-
 /**
  * cpumask_next_and - get the next cpu in *src1p & *src2p
  * @n: the cpu prior to the place to search (ie. return will be > @n)
diff --git a/lib/crc32.c b/lib/crc32.c
index 4b35d2b..b0d278f 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -1,4 +1,8 @@
 /*
+ * Aug 8, 2011 Bob Pearson with help from Joakim Tjernlund and George Spelvin
+ * cleaned up code to current version of sparse and added the slicing-by-8
+ * algorithm to the closely similar existing slicing-by-4 algorithm.
+ *
  * Oct 15, 2000 Matt Domsch <Matt_Domsch@dell.com>
  * Nicer crc32 functions/docs submitted by linux@horizon.com.  Thanks!
  * Code was from the public domain, copyright abandoned.  Code was
@@ -20,52 +24,58 @@
  * Version 2.  See the file COPYING for more details.
  */
 
+/* see: Documentation/crc32.txt for a description of algorithms */
+
 #include <linux/crc32.h>
-#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/compiler.h>
 #include <linux/types.h>
-#include <linux/init.h>
-#include <linux/atomic.h>
 #include "crc32defs.h"
-#if CRC_LE_BITS == 8
-# define tole(x) __constant_cpu_to_le32(x)
+
+#if CRC_LE_BITS > 8
+# define tole(x) ((__force u32) __constant_cpu_to_le32(x))
 #else
 # define tole(x) (x)
 #endif
 
-#if CRC_BE_BITS == 8
-# define tobe(x) __constant_cpu_to_be32(x)
+#if CRC_BE_BITS > 8
+# define tobe(x) ((__force u32) __constant_cpu_to_be32(x))
 #else
 # define tobe(x) (x)
 #endif
+
 #include "crc32table.h"
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
-MODULE_DESCRIPTION("Ethernet CRC32 calculations");
+MODULE_DESCRIPTION("Various CRC32 calculations");
 MODULE_LICENSE("GPL");
 
-#if CRC_LE_BITS == 8 || CRC_BE_BITS == 8
+#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8
 
+/* implements slicing-by-4 or slicing-by-8 algorithm */
 static inline u32
 crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
 {
 # ifdef __LITTLE_ENDIAN
 #  define DO_CRC(x) crc = t0[(crc ^ (x)) & 255] ^ (crc >> 8)
-#  define DO_CRC4 crc = t3[(crc) & 255] ^ \
-		t2[(crc >> 8) & 255] ^ \
-		t1[(crc >> 16) & 255] ^ \
-		t0[(crc >> 24) & 255]
+#  define DO_CRC4 (t3[(q) & 255] ^ t2[(q >> 8) & 255] ^ \
+		   t1[(q >> 16) & 255] ^ t0[(q >> 24) & 255])
+#  define DO_CRC8 (t7[(q) & 255] ^ t6[(q >> 8) & 255] ^ \
+		   t5[(q >> 16) & 255] ^ t4[(q >> 24) & 255])
 # else
 #  define DO_CRC(x) crc = t0[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
-#  define DO_CRC4 crc = t0[(crc) & 255] ^ \
-		t1[(crc >> 8) & 255] ^  \
-		t2[(crc >> 16) & 255] ^	\
-		t3[(crc >> 24) & 255]
+#  define DO_CRC4 (t0[(q) & 255] ^ t1[(q >> 8) & 255] ^ \
+		   t2[(q >> 16) & 255] ^ t3[(q >> 24) & 255])
+#  define DO_CRC8 (t4[(q) & 255] ^ t5[(q >> 8) & 255] ^ \
+		   t6[(q >> 16) & 255] ^ t7[(q >> 24) & 255])
 # endif
 	const u32 *b;
 	size_t    rem_len;
+# ifdef CONFIG_X86
+	size_t i;
+# endif
 	const u32 *t0=tab[0], *t1=tab[1], *t2=tab[2], *t3=tab[3];
+	const u32 *t4 = tab[4], *t5 = tab[5], *t6 = tab[6], *t7 = tab[7];
+	u32 q;
 
 	/* Align it */
 	if (unlikely((long)buf & 3 && len)) {
@@ -73,27 +83,51 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
 			DO_CRC(*buf++);
 		} while ((--len) && ((long)buf)&3);
 	}
+
+# if CRC_LE_BITS == 32
 	rem_len = len & 3;
-	/* load data 32 bits wide, xor data 32 bits wide. */
 	len = len >> 2;
+# else
+	rem_len = len & 7;
+	len = len >> 3;
+# endif
+
 	b = (const u32 *)buf;
+# ifdef CONFIG_X86
+	--b;
+	for (i = 0; i < len; i++) {
+# else
 	for (--b; len; --len) {
-		crc ^= *++b; /* use pre increment for speed */
-		DO_CRC4;
+# endif
+		q = crc ^ *++b; /* use pre increment for speed */
+# if CRC_LE_BITS == 32
+		crc = DO_CRC4;
+# else
+		crc = DO_CRC8;
+		q = *++b;
+		crc ^= DO_CRC4;
+# endif
 	}
 	len = rem_len;
 	/* And the last few bytes */
 	if (len) {
 		u8 *p = (u8 *)(b + 1) - 1;
+# ifdef CONFIG_X86
+		for (i = 0; i < len; i++)
+			DO_CRC(*++p); /* use pre increment for speed */
+# else
 		do {
 			DO_CRC(*++p); /* use pre increment for speed */
 		} while (--len);
+# endif
 	}
 	return crc;
 #undef DO_CRC
 #undef DO_CRC4
+#undef DO_CRC8
 }
 #endif
+
 /**
  * crc32_le() - Calculate bitwise little-endian Ethernet AUTODIN II CRC32
  * @crc: seed value for computation.  ~0 for Ethernet, sometimes 0 for
@@ -101,53 +135,66 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len);
-
-#if CRC_LE_BITS == 1
-/*
- * In fact, the table-based code will work in this case, but it can be
- * simplified by inlining the table in ?: form.
- */
-
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+static inline u32 __pure crc32_le_generic(u32 crc, unsigned char const *p,
+					  size_t len, const u32 (*tab)[256],
+					  u32 polynomial)
 {
+#if CRC_LE_BITS == 1
 	int i;
 	while (len--) {
 		crc ^= *p++;
 		for (i = 0; i < 8; i++)
-			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+			crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
+	}
+# elif CRC_LE_BITS == 2
+	while (len--) {
+		crc ^= *p++;
+		crc = (crc >> 2) ^ tab[0][crc & 3];
+		crc = (crc >> 2) ^ tab[0][crc & 3];
+		crc = (crc >> 2) ^ tab[0][crc & 3];
+		crc = (crc >> 2) ^ tab[0][crc & 3];
 	}
-	return crc;
-}
-#else				/* Table-based approach */
-
-u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
-{
-# if CRC_LE_BITS == 8
-	const u32      (*tab)[] = crc32table_le;
-
-	crc = __cpu_to_le32(crc);
-	crc = crc32_body(crc, p, len, tab);
-	return __le32_to_cpu(crc);
 # elif CRC_LE_BITS == 4
 	while (len--) {
 		crc ^= *p++;
-		crc = (crc >> 4) ^ crc32table_le[crc & 15];
-		crc = (crc >> 4) ^ crc32table_le[crc & 15];
+		crc = (crc >> 4) ^ tab[0][crc & 15];
+		crc = (crc >> 4) ^ tab[0][crc & 15];
 	}
-	return crc;
-# elif CRC_LE_BITS == 2
+# elif CRC_LE_BITS == 8
+	/* aka Sarwate algorithm */
 	while (len--) {
 		crc ^= *p++;
-		crc = (crc >> 2) ^ crc32table_le[crc & 3];
-		crc = (crc >> 2) ^ crc32table_le[crc & 3];
-		crc = (crc >> 2) ^ crc32table_le[crc & 3];
-		crc = (crc >> 2) ^ crc32table_le[crc & 3];
+		crc = (crc >> 8) ^ tab[0][crc & 255];
 	}
+# else
+	crc = (__force u32) __cpu_to_le32(crc);
+	crc = crc32_body(crc, p, len, tab);
+	crc = __le32_to_cpu((__force __le32)crc);
+#endif
 	return crc;
-# endif
+}
+
+#if CRC_LE_BITS == 1
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+	return crc32_le_generic(crc, p, len, NULL, CRCPOLY_LE);
+}
+u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+	return crc32_le_generic(crc, p, len, NULL, CRC32C_POLY_LE);
+}
+#else
+u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
+{
+	return crc32_le_generic(crc, p, len, crc32table_le, CRCPOLY_LE);
+}
+u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
+{
+	return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
+EXPORT_SYMBOL(crc32_le);
+EXPORT_SYMBOL(__crc32c_le);
 
 /**
  * crc32_be() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32
@@ -156,317 +203,913 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len)
  * @p: pointer to buffer over which CRC is run
  * @len: length of buffer @p
  */
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len);
-
-#if CRC_BE_BITS == 1
-/*
- * In fact, the table-based code will work in this case, but it can be
- * simplified by inlining the table in ?: form.
- */
-
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
+					  size_t len, const u32 (*tab)[256],
+					  u32 polynomial)
 {
+#if CRC_BE_BITS == 1
 	int i;
 	while (len--) {
 		crc ^= *p++ << 24;
 		for (i = 0; i < 8; i++)
 			crc =
-			    (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE :
+			    (crc << 1) ^ ((crc & 0x80000000) ? polynomial :
 					  0);
 	}
-	return crc;
-}
-
-#else				/* Table-based approach */
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
-{
-# if CRC_BE_BITS == 8
-	const u32      (*tab)[] = crc32table_be;
-
-	crc = __cpu_to_be32(crc);
-	crc = crc32_body(crc, p, len, tab);
-	return __be32_to_cpu(crc);
+# elif CRC_BE_BITS == 2
+	while (len--) {
+		crc ^= *p++ << 24;
+		crc = (crc << 2) ^ tab[0][crc >> 30];
+		crc = (crc << 2) ^ tab[0][crc >> 30];
+		crc = (crc << 2) ^ tab[0][crc >> 30];
+		crc = (crc << 2) ^ tab[0][crc >> 30];
+	}
 # elif CRC_BE_BITS == 4
 	while (len--) {
 		crc ^= *p++ << 24;
-		crc = (crc << 4) ^ crc32table_be[crc >> 28];
-		crc = (crc << 4) ^ crc32table_be[crc >> 28];
+		crc = (crc << 4) ^ tab[0][crc >> 28];
+		crc = (crc << 4) ^ tab[0][crc >> 28];
 	}
-	return crc;
-# elif CRC_BE_BITS == 2
+# elif CRC_BE_BITS == 8
 	while (len--) {
 		crc ^= *p++ << 24;
-		crc = (crc << 2) ^ crc32table_be[crc >> 30];
-		crc = (crc << 2) ^ crc32table_be[crc >> 30];
-		crc = (crc << 2) ^ crc32table_be[crc >> 30];
-		crc = (crc << 2) ^ crc32table_be[crc >> 30];
+		crc = (crc << 8) ^ tab[0][crc >> 24];
 	}
-	return crc;
+# else
+	crc = (__force u32) __cpu_to_be32(crc);
+	crc = crc32_body(crc, p, len, tab);
+	crc = __be32_to_cpu((__force __be32)crc);
 # endif
+	return crc;
 }
-#endif
 
-EXPORT_SYMBOL(crc32_le);
+#if CRC_LE_BITS == 1
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+	return crc32_be_generic(crc, p, len, NULL, CRCPOLY_BE);
+}
+#else
+u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+{
+	return crc32_be_generic(crc, p, len, crc32table_be, CRCPOLY_BE);
+}
+#endif
 EXPORT_SYMBOL(crc32_be);
 
-/*
- * A brief CRC tutorial.
- *
- * A CRC is a long-division remainder.  You add the CRC to the message,
- * and the whole thing (message+CRC) is a multiple of the given
- * CRC polynomial.  To check the CRC, you can either check that the
- * CRC matches the recomputed value, *or* you can check that the
- * remainder computed on the message+CRC is 0.  This latter approach
- * is used by a lot of hardware implementations, and is why so many
- * protocols put the end-of-frame flag after the CRC.
- *
- * It's actually the same long division you learned in school, except that
- * - We're working in binary, so the digits are only 0 and 1, and
- * - When dividing polynomials, there are no carries.  Rather than add and
- *   subtract, we just xor.  Thus, we tend to get a bit sloppy about
- *   the difference between adding and subtracting.
- *
- * A 32-bit CRC polynomial is actually 33 bits long.  But since it's
- * 33 bits long, bit 32 is always going to be set, so usually the CRC
- * is written in hex with the most significant bit omitted.  (If you're
- * familiar with the IEEE 754 floating-point format, it's the same idea.)
- *
- * Note that a CRC is computed over a string of *bits*, so you have
- * to decide on the endianness of the bits within each byte.  To get
- * the best error-detecting properties, this should correspond to the
- * order they're actually sent.  For example, standard RS-232 serial is
- * little-endian; the most significant bit (sometimes used for parity)
- * is sent last.  And when appending a CRC word to a message, you should
- * do it in the right order, matching the endianness.
- *
- * Just like with ordinary division, the remainder is always smaller than
- * the divisor (the CRC polynomial) you're dividing by.  Each step of the
- * division, you take one more digit (bit) of the dividend and append it
- * to the current remainder.  Then you figure out the appropriate multiple
- * of the divisor to subtract to being the remainder back into range.
- * In binary, it's easy - it has to be either 0 or 1, and to make the
- * XOR cancel, it's just a copy of bit 32 of the remainder.
- *
- * When computing a CRC, we don't care about the quotient, so we can
- * throw the quotient bit away, but subtract the appropriate multiple of
- * the polynomial from the remainder and we're back to where we started,
- * ready to process the next bit.
- *
- * A big-endian CRC written this way would be coded like:
- * for (i = 0; i < input_bits; i++) {
- * 	multiple = remainder & 0x80000000 ? CRCPOLY : 0;
- * 	remainder = (remainder << 1 | next_input_bit()) ^ multiple;
- * }
- * Notice how, to get at bit 32 of the shifted remainder, we look
- * at bit 31 of the remainder *before* shifting it.
- *
- * But also notice how the next_input_bit() bits we're shifting into
- * the remainder don't actually affect any decision-making until
- * 32 bits later.  Thus, the first 32 cycles of this are pretty boring.
- * Also, to add the CRC to a message, we need a 32-bit-long hole for it at
- * the end, so we have to add 32 extra cycles shifting in zeros at the
- * end of every message,
- *
- * So the standard trick is to rearrage merging in the next_input_bit()
- * until the moment it's needed.  Then the first 32 cycles can be precomputed,
- * and merging in the final 32 zero bits to make room for the CRC can be
- * skipped entirely.
- * This changes the code to:
- * for (i = 0; i < input_bits; i++) {
- *      remainder ^= next_input_bit() << 31;
- * 	multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
- * 	remainder = (remainder << 1) ^ multiple;
- * }
- * With this optimization, the little-endian code is simpler:
- * for (i = 0; i < input_bits; i++) {
- *      remainder ^= next_input_bit();
- * 	multiple = (remainder & 1) ? CRCPOLY : 0;
- * 	remainder = (remainder >> 1) ^ multiple;
- * }
- *
- * Note that the other details of endianness have been hidden in CRCPOLY
- * (which must be bit-reversed) and next_input_bit().
- *
- * However, as long as next_input_bit is returning the bits in a sensible
- * order, we can actually do the merging 8 or more bits at a time rather
- * than one bit at a time:
- * for (i = 0; i < input_bytes; i++) {
- * 	remainder ^= next_input_byte() << 24;
- * 	for (j = 0; j < 8; j++) {
- * 		multiple = (remainder & 0x80000000) ? CRCPOLY : 0;
- * 		remainder = (remainder << 1) ^ multiple;
- * 	}
- * }
- * Or in little-endian:
- * for (i = 0; i < input_bytes; i++) {
- * 	remainder ^= next_input_byte();
- * 	for (j = 0; j < 8; j++) {
- * 		multiple = (remainder & 1) ? CRCPOLY : 0;
- * 		remainder = (remainder << 1) ^ multiple;
- * 	}
- * }
- * If the input is a multiple of 32 bits, you can even XOR in a 32-bit
- * word at a time and increase the inner loop count to 32.
- *
- * You can also mix and match the two loop styles, for example doing the
- * bulk of a message byte-at-a-time and adding bit-at-a-time processing
- * for any fractional bytes at the end.
- *
- * The only remaining optimization is to the byte-at-a-time table method.
- * Here, rather than just shifting one bit of the remainder to decide
- * in the correct multiple to subtract, we can shift a byte at a time.
- * This produces a 40-bit (rather than a 33-bit) intermediate remainder,
- * but again the multiple of the polynomial to subtract depends only on
- * the high bits, the high 8 bits in this case.  
- *
- * The multiple we need in that case is the low 32 bits of a 40-bit
- * value whose high 8 bits are given, and which is a multiple of the
- * generator polynomial.  This is simply the CRC-32 of the given
- * one-byte message.
- *
- * Two more details: normally, appending zero bits to a message which
- * is already a multiple of a polynomial produces a larger multiple of that
- * polynomial.  To enable a CRC to detect this condition, it's common to
- * invert the CRC before appending it.  This makes the remainder of the
- * message+crc come out not as zero, but some fixed non-zero value.
- *
- * The same problem applies to zero bits prepended to the message, and
- * a similar solution is used.  Instead of starting with a remainder of
- * 0, an initial remainder of all ones is used.  As long as you start
- * the same way on decoding, it doesn't make a difference.
- */
-
-#ifdef UNITTEST
+#ifdef CONFIG_CRC32_SELFTEST
 
-#include <stdlib.h>
-#include <stdio.h>
+/* 4096 random bytes */
+static u8 __attribute__((__aligned__(8))) test_buf[] =
+{
+	0x5b, 0x85, 0x21, 0xcb, 0x09, 0x68, 0x7d, 0x30,
+	0xc7, 0x69, 0xd7, 0x30, 0x92, 0xde, 0x59, 0xe4,
+	0xc9, 0x6e, 0x8b, 0xdb, 0x98, 0x6b, 0xaa, 0x60,
+	0xa8, 0xb5, 0xbc, 0x6c, 0xa9, 0xb1, 0x5b, 0x2c,
+	0xea, 0xb4, 0x92, 0x6a, 0x3f, 0x79, 0x91, 0xe4,
+	0xe9, 0x70, 0x51, 0x8c, 0x7f, 0x95, 0x6f, 0x1a,
+	0x56, 0xa1, 0x5c, 0x27, 0x03, 0x67, 0x9f, 0x3a,
+	0xe2, 0x31, 0x11, 0x29, 0x6b, 0x98, 0xfc, 0xc4,
+	0x53, 0x24, 0xc5, 0x8b, 0xce, 0x47, 0xb2, 0xb9,
+	0x32, 0xcb, 0xc1, 0xd0, 0x03, 0x57, 0x4e, 0xd4,
+	0xe9, 0x3c, 0xa1, 0x63, 0xcf, 0x12, 0x0e, 0xca,
+	0xe1, 0x13, 0xd1, 0x93, 0xa6, 0x88, 0x5c, 0x61,
+	0x5b, 0xbb, 0xf0, 0x19, 0x46, 0xb4, 0xcf, 0x9e,
+	0xb6, 0x6b, 0x4c, 0x3a, 0xcf, 0x60, 0xf9, 0x7a,
+	0x8d, 0x07, 0x63, 0xdb, 0x40, 0xe9, 0x0b, 0x6f,
+	0xad, 0x97, 0xf1, 0xed, 0xd0, 0x1e, 0x26, 0xfd,
+	0xbf, 0xb7, 0xc8, 0x04, 0x94, 0xf8, 0x8b, 0x8c,
+	0xf1, 0xab, 0x7a, 0xd4, 0xdd, 0xf3, 0xe8, 0x88,
+	0xc3, 0xed, 0x17, 0x8a, 0x9b, 0x40, 0x0d, 0x53,
+	0x62, 0x12, 0x03, 0x5f, 0x1b, 0x35, 0x32, 0x1f,
+	0xb4, 0x7b, 0x93, 0x78, 0x0d, 0xdb, 0xce, 0xa4,
+	0xc0, 0x47, 0xd5, 0xbf, 0x68, 0xe8, 0x5d, 0x74,
+	0x8f, 0x8e, 0x75, 0x1c, 0xb2, 0x4f, 0x9a, 0x60,
+	0xd1, 0xbe, 0x10, 0xf4, 0x5c, 0xa1, 0x53, 0x09,
+	0xa5, 0xe0, 0x09, 0x54, 0x85, 0x5c, 0xdc, 0x07,
+	0xe7, 0x21, 0x69, 0x7b, 0x8a, 0xfd, 0x90, 0xf1,
+	0x22, 0xd0, 0xb4, 0x36, 0x28, 0xe6, 0xb8, 0x0f,
+	0x39, 0xde, 0xc8, 0xf3, 0x86, 0x60, 0x34, 0xd2,
+	0x5e, 0xdf, 0xfd, 0xcf, 0x0f, 0xa9, 0x65, 0xf0,
+	0xd5, 0x4d, 0x96, 0x40, 0xe3, 0xdf, 0x3f, 0x95,
+	0x5a, 0x39, 0x19, 0x93, 0xf4, 0x75, 0xce, 0x22,
+	0x00, 0x1c, 0x93, 0xe2, 0x03, 0x66, 0xf4, 0x93,
+	0x73, 0x86, 0x81, 0x8e, 0x29, 0x44, 0x48, 0x86,
+	0x61, 0x7c, 0x48, 0xa3, 0x43, 0xd2, 0x9c, 0x8d,
+	0xd4, 0x95, 0xdd, 0xe1, 0x22, 0x89, 0x3a, 0x40,
+	0x4c, 0x1b, 0x8a, 0x04, 0xa8, 0x09, 0x69, 0x8b,
+	0xea, 0xc6, 0x55, 0x8e, 0x57, 0xe6, 0x64, 0x35,
+	0xf0, 0xc7, 0x16, 0x9f, 0x5d, 0x5e, 0x86, 0x40,
+	0x46, 0xbb, 0xe5, 0x45, 0x88, 0xfe, 0xc9, 0x63,
+	0x15, 0xfb, 0xf5, 0xbd, 0x71, 0x61, 0xeb, 0x7b,
+	0x78, 0x70, 0x07, 0x31, 0x03, 0x9f, 0xb2, 0xc8,
+	0xa7, 0xab, 0x47, 0xfd, 0xdf, 0xa0, 0x78, 0x72,
+	0xa4, 0x2a, 0xe4, 0xb6, 0xba, 0xc0, 0x1e, 0x86,
+	0x71, 0xe6, 0x3d, 0x18, 0x37, 0x70, 0xe6, 0xff,
+	0xe0, 0xbc, 0x0b, 0x22, 0xa0, 0x1f, 0xd3, 0xed,
+	0xa2, 0x55, 0x39, 0xab, 0xa8, 0x13, 0x73, 0x7c,
+	0x3f, 0xb2, 0xd6, 0x19, 0xac, 0xff, 0x99, 0xed,
+	0xe8, 0xe6, 0xa6, 0x22, 0xe3, 0x9c, 0xf1, 0x30,
+	0xdc, 0x01, 0x0a, 0x56, 0xfa, 0xe4, 0xc9, 0x99,
+	0xdd, 0xa8, 0xd8, 0xda, 0x35, 0x51, 0x73, 0xb4,
+	0x40, 0x86, 0x85, 0xdb, 0x5c, 0xd5, 0x85, 0x80,
+	0x14, 0x9c, 0xfd, 0x98, 0xa9, 0x82, 0xc5, 0x37,
+	0xff, 0x32, 0x5d, 0xd0, 0x0b, 0xfa, 0xdc, 0x04,
+	0x5e, 0x09, 0xd2, 0xca, 0x17, 0x4b, 0x1a, 0x8e,
+	0x15, 0xe1, 0xcc, 0x4e, 0x52, 0x88, 0x35, 0xbd,
+	0x48, 0xfe, 0x15, 0xa0, 0x91, 0xfd, 0x7e, 0x6c,
+	0x0e, 0x5d, 0x79, 0x1b, 0x81, 0x79, 0xd2, 0x09,
+	0x34, 0x70, 0x3d, 0x81, 0xec, 0xf6, 0x24, 0xbb,
+	0xfb, 0xf1, 0x7b, 0xdf, 0x54, 0xea, 0x80, 0x9b,
+	0xc7, 0x99, 0x9e, 0xbd, 0x16, 0x78, 0x12, 0x53,
+	0x5e, 0x01, 0xa7, 0x4e, 0xbd, 0x67, 0xe1, 0x9b,
+	0x4c, 0x0e, 0x61, 0x45, 0x97, 0xd2, 0xf0, 0x0f,
+	0xfe, 0x15, 0x08, 0xb7, 0x11, 0x4c, 0xe7, 0xff,
+	0x81, 0x53, 0xff, 0x91, 0x25, 0x38, 0x7e, 0x40,
+	0x94, 0xe5, 0xe0, 0xad, 0xe6, 0xd9, 0x79, 0xb6,
+	0x92, 0xc9, 0xfc, 0xde, 0xc3, 0x1a, 0x23, 0xbb,
+	0xdd, 0xc8, 0x51, 0x0c, 0x3a, 0x72, 0xfa, 0x73,
+	0x6f, 0xb7, 0xee, 0x61, 0x39, 0x03, 0x01, 0x3f,
+	0x7f, 0x94, 0x2e, 0x2e, 0xba, 0x3a, 0xbb, 0xb4,
+	0xfa, 0x6a, 0x17, 0xfe, 0xea, 0xef, 0x5e, 0x66,
+	0x97, 0x3f, 0x32, 0x3d, 0xd7, 0x3e, 0xb1, 0xf1,
+	0x6c, 0x14, 0x4c, 0xfd, 0x37, 0xd3, 0x38, 0x80,
+	0xfb, 0xde, 0xa6, 0x24, 0x1e, 0xc8, 0xca, 0x7f,
+	0x3a, 0x93, 0xd8, 0x8b, 0x18, 0x13, 0xb2, 0xe5,
+	0xe4, 0x93, 0x05, 0x53, 0x4f, 0x84, 0x66, 0xa7,
+	0x58, 0x5c, 0x7b, 0x86, 0x52, 0x6d, 0x0d, 0xce,
+	0xa4, 0x30, 0x7d, 0xb6, 0x18, 0x9f, 0xeb, 0xff,
+	0x22, 0xbb, 0x72, 0x29, 0xb9, 0x44, 0x0b, 0x48,
+	0x1e, 0x84, 0x71, 0x81, 0xe3, 0x6d, 0x73, 0x26,
+	0x92, 0xb4, 0x4d, 0x2a, 0x29, 0xb8, 0x1f, 0x72,
+	0xed, 0xd0, 0xe1, 0x64, 0x77, 0xea, 0x8e, 0x88,
+	0x0f, 0xef, 0x3f, 0xb1, 0x3b, 0xad, 0xf9, 0xc9,
+	0x8b, 0xd0, 0xac, 0xc6, 0xcc, 0xa9, 0x40, 0xcc,
+	0x76, 0xf6, 0x3b, 0x53, 0xb5, 0x88, 0xcb, 0xc8,
+	0x37, 0xf1, 0xa2, 0xba, 0x23, 0x15, 0x99, 0x09,
+	0xcc, 0xe7, 0x7a, 0x3b, 0x37, 0xf7, 0x58, 0xc8,
+	0x46, 0x8c, 0x2b, 0x2f, 0x4e, 0x0e, 0xa6, 0x5c,
+	0xea, 0x85, 0x55, 0xba, 0x02, 0x0e, 0x0e, 0x48,
+	0xbc, 0xe1, 0xb1, 0x01, 0x35, 0x79, 0x13, 0x3d,
+	0x1b, 0xc0, 0x53, 0x68, 0x11, 0xe7, 0x95, 0x0f,
+	0x9d, 0x3f, 0x4c, 0x47, 0x7b, 0x4d, 0x1c, 0xae,
+	0x50, 0x9b, 0xcb, 0xdd, 0x05, 0x8d, 0x9a, 0x97,
+	0xfd, 0x8c, 0xef, 0x0c, 0x1d, 0x67, 0x73, 0xa8,
+	0x28, 0x36, 0xd5, 0xb6, 0x92, 0x33, 0x40, 0x75,
+	0x0b, 0x51, 0xc3, 0x64, 0xba, 0x1d, 0xc2, 0xcc,
+	0xee, 0x7d, 0x54, 0x0f, 0x27, 0x69, 0xa7, 0x27,
+	0x63, 0x30, 0x29, 0xd9, 0xc8, 0x84, 0xd8, 0xdf,
+	0x9f, 0x68, 0x8d, 0x04, 0xca, 0xa6, 0xc5, 0xc7,
+	0x7a, 0x5c, 0xc8, 0xd1, 0xcb, 0x4a, 0xec, 0xd0,
+	0xd8, 0x20, 0x69, 0xc5, 0x17, 0xcd, 0x78, 0xc8,
+	0x75, 0x23, 0x30, 0x69, 0xc9, 0xd4, 0xea, 0x5c,
+	0x4f, 0x6b, 0x86, 0x3f, 0x8b, 0xfe, 0xee, 0x44,
+	0xc9, 0x7c, 0xb7, 0xdd, 0x3e, 0xe5, 0xec, 0x54,
+	0x03, 0x3e, 0xaa, 0x82, 0xc6, 0xdf, 0xb2, 0x38,
+	0x0e, 0x5d, 0xb3, 0x88, 0xd9, 0xd3, 0x69, 0x5f,
+	0x8f, 0x70, 0x8a, 0x7e, 0x11, 0xd9, 0x1e, 0x7b,
+	0x38, 0xf1, 0x42, 0x1a, 0xc0, 0x35, 0xf5, 0xc7,
+	0x36, 0x85, 0xf5, 0xf7, 0xb8, 0x7e, 0xc7, 0xef,
+	0x18, 0xf1, 0x63, 0xd6, 0x7a, 0xc6, 0xc9, 0x0e,
+	0x4d, 0x69, 0x4f, 0x84, 0xef, 0x26, 0x41, 0x0c,
+	0xec, 0xc7, 0xe0, 0x7e, 0x3c, 0x67, 0x01, 0x4c,
+	0x62, 0x1a, 0x20, 0x6f, 0xee, 0x47, 0x4d, 0xc0,
+	0x99, 0x13, 0x8d, 0x91, 0x4a, 0x26, 0xd4, 0x37,
+	0x28, 0x90, 0x58, 0x75, 0x66, 0x2b, 0x0a, 0xdf,
+	0xda, 0xee, 0x92, 0x25, 0x90, 0x62, 0x39, 0x9e,
+	0x44, 0x98, 0xad, 0xc1, 0x88, 0xed, 0xe4, 0xb4,
+	0xaf, 0xf5, 0x8c, 0x9b, 0x48, 0x4d, 0x56, 0x60,
+	0x97, 0x0f, 0x61, 0x59, 0x9e, 0xa6, 0x27, 0xfe,
+	0xc1, 0x91, 0x15, 0x38, 0xb8, 0x0f, 0xae, 0x61,
+	0x7d, 0x26, 0x13, 0x5a, 0x73, 0xff, 0x1c, 0xa3,
+	0x61, 0x04, 0x58, 0x48, 0x55, 0x44, 0x11, 0xfe,
+	0x15, 0xca, 0xc3, 0xbd, 0xca, 0xc5, 0xb4, 0x40,
+	0x5d, 0x1b, 0x7f, 0x39, 0xb5, 0x9c, 0x35, 0xec,
+	0x61, 0x15, 0x32, 0x32, 0xb8, 0x4e, 0x40, 0x9f,
+	0x17, 0x1f, 0x0a, 0x4d, 0xa9, 0x91, 0xef, 0xb7,
+	0xb0, 0xeb, 0xc2, 0x83, 0x9a, 0x6c, 0xd2, 0x79,
+	0x43, 0x78, 0x5e, 0x2f, 0xe5, 0xdd, 0x1a, 0x3c,
+	0x45, 0xab, 0x29, 0x40, 0x3a, 0x37, 0x5b, 0x6f,
+	0xd7, 0xfc, 0x48, 0x64, 0x3c, 0x49, 0xfb, 0x21,
+	0xbe, 0xc3, 0xff, 0x07, 0xfb, 0x17, 0xe9, 0xc9,
+	0x0c, 0x4c, 0x5c, 0x15, 0x9e, 0x8e, 0x22, 0x30,
+	0x0a, 0xde, 0x48, 0x7f, 0xdb, 0x0d, 0xd1, 0x2b,
+	0x87, 0x38, 0x9e, 0xcc, 0x5a, 0x01, 0x16, 0xee,
+	0x75, 0x49, 0x0d, 0x30, 0x01, 0x34, 0x6a, 0xb6,
+	0x9a, 0x5a, 0x2a, 0xec, 0xbb, 0x48, 0xac, 0xd3,
+	0x77, 0x83, 0xd8, 0x08, 0x86, 0x4f, 0x48, 0x09,
+	0x29, 0x41, 0x79, 0xa1, 0x03, 0x12, 0xc4, 0xcd,
+	0x90, 0x55, 0x47, 0x66, 0x74, 0x9a, 0xcc, 0x4f,
+	0x35, 0x8c, 0xd6, 0x98, 0xef, 0xeb, 0x45, 0xb9,
+	0x9a, 0x26, 0x2f, 0x39, 0xa5, 0x70, 0x6d, 0xfc,
+	0xb4, 0x51, 0xee, 0xf4, 0x9c, 0xe7, 0x38, 0x59,
+	0xad, 0xf4, 0xbc, 0x46, 0xff, 0x46, 0x8e, 0x60,
+	0x9c, 0xa3, 0x60, 0x1d, 0xf8, 0x26, 0x72, 0xf5,
+	0x72, 0x9d, 0x68, 0x80, 0x04, 0xf6, 0x0b, 0xa1,
+	0x0a, 0xd5, 0xa7, 0x82, 0x3a, 0x3e, 0x47, 0xa8,
+	0x5a, 0xde, 0x59, 0x4f, 0x7b, 0x07, 0xb3, 0xe9,
+	0x24, 0x19, 0x3d, 0x34, 0x05, 0xec, 0xf1, 0xab,
+	0x6e, 0x64, 0x8f, 0xd3, 0xe6, 0x41, 0x86, 0x80,
+	0x70, 0xe3, 0x8d, 0x60, 0x9c, 0x34, 0x25, 0x01,
+	0x07, 0x4d, 0x19, 0x41, 0x4e, 0x3d, 0x5c, 0x7e,
+	0xa8, 0xf5, 0xcc, 0xd5, 0x7b, 0xe2, 0x7d, 0x3d,
+	0x49, 0x86, 0x7d, 0x07, 0xb7, 0x10, 0xe3, 0x35,
+	0xb8, 0x84, 0x6d, 0x76, 0xab, 0x17, 0xc6, 0x38,
+	0xb4, 0xd3, 0x28, 0x57, 0xad, 0xd3, 0x88, 0x5a,
+	0xda, 0xea, 0xc8, 0x94, 0xcc, 0x37, 0x19, 0xac,
+	0x9c, 0x9f, 0x4b, 0x00, 0x15, 0xc0, 0xc8, 0xca,
+	0x1f, 0x15, 0xaa, 0xe0, 0xdb, 0xf9, 0x2f, 0x57,
+	0x1b, 0x24, 0xc7, 0x6f, 0x76, 0x29, 0xfb, 0xed,
+	0x25, 0x0d, 0xc0, 0xfe, 0xbd, 0x5a, 0xbf, 0x20,
+	0x08, 0x51, 0x05, 0xec, 0x71, 0xa3, 0xbf, 0xef,
+	0x5e, 0x99, 0x75, 0xdb, 0x3c, 0x5f, 0x9a, 0x8c,
+	0xbb, 0x19, 0x5c, 0x0e, 0x93, 0x19, 0xf8, 0x6a,
+	0xbc, 0xf2, 0x12, 0x54, 0x2f, 0xcb, 0x28, 0x64,
+	0x88, 0xb3, 0x92, 0x0d, 0x96, 0xd1, 0xa6, 0xe4,
+	0x1f, 0xf1, 0x4d, 0xa4, 0xab, 0x1c, 0xee, 0x54,
+	0xf2, 0xad, 0x29, 0x6d, 0x32, 0x37, 0xb2, 0x16,
+	0x77, 0x5c, 0xdc, 0x2e, 0x54, 0xec, 0x75, 0x26,
+	0xc6, 0x36, 0xd9, 0x17, 0x2c, 0xf1, 0x7a, 0xdc,
+	0x4b, 0xf1, 0xe2, 0xd9, 0x95, 0xba, 0xac, 0x87,
+	0xc1, 0xf3, 0x8e, 0x58, 0x08, 0xd8, 0x87, 0x60,
+	0xc9, 0xee, 0x6a, 0xde, 0xa4, 0xd2, 0xfc, 0x0d,
+	0xe5, 0x36, 0xc4, 0x5c, 0x52, 0xb3, 0x07, 0x54,
+	0x65, 0x24, 0xc1, 0xb1, 0xd1, 0xb1, 0x53, 0x13,
+	0x31, 0x79, 0x7f, 0x05, 0x76, 0xeb, 0x37, 0x59,
+	0x15, 0x2b, 0xd1, 0x3f, 0xac, 0x08, 0x97, 0xeb,
+	0x91, 0x98, 0xdf, 0x6c, 0x09, 0x0d, 0x04, 0x9f,
+	0xdc, 0x3b, 0x0e, 0x60, 0x68, 0x47, 0x23, 0x15,
+	0x16, 0xc6, 0x0b, 0x35, 0xf8, 0x77, 0xa2, 0x78,
+	0x50, 0xd4, 0x64, 0x22, 0x33, 0xff, 0xfb, 0x93,
+	0x71, 0x46, 0x50, 0x39, 0x1b, 0x9c, 0xea, 0x4e,
+	0x8d, 0x0c, 0x37, 0xe5, 0x5c, 0x51, 0x3a, 0x31,
+	0xb2, 0x85, 0x84, 0x3f, 0x41, 0xee, 0xa2, 0xc1,
+	0xc6, 0x13, 0x3b, 0x54, 0x28, 0xd2, 0x18, 0x37,
+	0xcc, 0x46, 0x9f, 0x6a, 0x91, 0x3d, 0x5a, 0x15,
+	0x3c, 0x89, 0xa3, 0x61, 0x06, 0x7d, 0x2e, 0x78,
+	0xbe, 0x7d, 0x40, 0xba, 0x2f, 0x95, 0xb1, 0x2f,
+	0x87, 0x3b, 0x8a, 0xbe, 0x6a, 0xf4, 0xc2, 0x31,
+	0x74, 0xee, 0x91, 0xe0, 0x23, 0xaa, 0x5d, 0x7f,
+	0xdd, 0xf0, 0x44, 0x8c, 0x0b, 0x59, 0x2b, 0xfc,
+	0x48, 0x3a, 0xdf, 0x07, 0x05, 0x38, 0x6c, 0xc9,
+	0xeb, 0x18, 0x24, 0x68, 0x8d, 0x58, 0x98, 0xd3,
+	0x31, 0xa3, 0xe4, 0x70, 0x59, 0xb1, 0x21, 0xbe,
+	0x7e, 0x65, 0x7d, 0xb8, 0x04, 0xab, 0xf6, 0xe4,
+	0xd7, 0xda, 0xec, 0x09, 0x8f, 0xda, 0x6d, 0x24,
+	0x07, 0xcc, 0x29, 0x17, 0x05, 0x78, 0x1a, 0xc1,
+	0xb1, 0xce, 0xfc, 0xaa, 0x2d, 0xe7, 0xcc, 0x85,
+	0x84, 0x84, 0x03, 0x2a, 0x0c, 0x3f, 0xa9, 0xf8,
+	0xfd, 0x84, 0x53, 0x59, 0x5c, 0xf0, 0xd4, 0x09,
+	0xf0, 0xd2, 0x6c, 0x32, 0x03, 0xb0, 0xa0, 0x8c,
+	0x52, 0xeb, 0x23, 0x91, 0x88, 0x43, 0x13, 0x46,
+	0xf6, 0x1e, 0xb4, 0x1b, 0xf5, 0x8e, 0x3a, 0xb5,
+	0x3d, 0x00, 0xf6, 0xe5, 0x08, 0x3d, 0x5f, 0x39,
+	0xd3, 0x21, 0x69, 0xbc, 0x03, 0x22, 0x3a, 0xd2,
+	0x5c, 0x84, 0xf8, 0x15, 0xc4, 0x80, 0x0b, 0xbc,
+	0x29, 0x3c, 0xf3, 0x95, 0x98, 0xcd, 0x8f, 0x35,
+	0xbc, 0xa5, 0x3e, 0xfc, 0xd4, 0x13, 0x9e, 0xde,
+	0x4f, 0xce, 0x71, 0x9d, 0x09, 0xad, 0xf2, 0x80,
+	0x6b, 0x65, 0x7f, 0x03, 0x00, 0x14, 0x7c, 0x15,
+	0x85, 0x40, 0x6d, 0x70, 0xea, 0xdc, 0xb3, 0x63,
+	0x35, 0x4f, 0x4d, 0xe0, 0xd9, 0xd5, 0x3c, 0x58,
+	0x56, 0x23, 0x80, 0xe2, 0x36, 0xdd, 0x75, 0x1d,
+	0x94, 0x11, 0x41, 0x8e, 0xe0, 0x81, 0x8e, 0xcf,
+	0xe0, 0xe5, 0xf6, 0xde, 0xd1, 0xe7, 0x04, 0x12,
+	0x79, 0x92, 0x2b, 0x71, 0x2a, 0x79, 0x8b, 0x7c,
+	0x44, 0x79, 0x16, 0x30, 0x4e, 0xf4, 0xf6, 0x9b,
+	0xb7, 0x40, 0xa3, 0x5a, 0xa7, 0x69, 0x3e, 0xc1,
+	0x3a, 0x04, 0xd0, 0x88, 0xa0, 0x3b, 0xdd, 0xc6,
+	0x9e, 0x7e, 0x1e, 0x1e, 0x8f, 0x44, 0xf7, 0x73,
+	0x67, 0x1e, 0x1a, 0x78, 0xfa, 0x62, 0xf4, 0xa9,
+	0xa8, 0xc6, 0x5b, 0xb8, 0xfa, 0x06, 0x7d, 0x5e,
+	0x38, 0x1c, 0x9a, 0x39, 0xe9, 0x39, 0x98, 0x22,
+	0x0b, 0xa7, 0xac, 0x0b, 0xf3, 0xbc, 0xf1, 0xeb,
+	0x8c, 0x81, 0xe3, 0x48, 0x8a, 0xed, 0x42, 0xc2,
+	0x38, 0xcf, 0x3e, 0xda, 0xd2, 0x89, 0x8d, 0x9c,
+	0x53, 0xb5, 0x2f, 0x41, 0x01, 0x26, 0x84, 0x9c,
+	0xa3, 0x56, 0xf6, 0x49, 0xc7, 0xd4, 0x9f, 0x93,
+	0x1b, 0x96, 0x49, 0x5e, 0xad, 0xb3, 0x84, 0x1f,
+	0x3c, 0xa4, 0xe0, 0x9b, 0xd1, 0x90, 0xbc, 0x38,
+	0x6c, 0xdd, 0x95, 0x4d, 0x9d, 0xb1, 0x71, 0x57,
+	0x2d, 0x34, 0xe8, 0xb8, 0x42, 0xc7, 0x99, 0x03,
+	0xc7, 0x07, 0x30, 0x65, 0x91, 0x55, 0xd5, 0x90,
+	0x70, 0x97, 0x37, 0x68, 0xd4, 0x11, 0xf9, 0xe8,
+	0xce, 0xec, 0xdc, 0x34, 0xd5, 0xd3, 0xb7, 0xc4,
+	0xb8, 0x97, 0x05, 0x92, 0xad, 0xf8, 0xe2, 0x36,
+	0x64, 0x41, 0xc9, 0xc5, 0x41, 0x77, 0x52, 0xd7,
+	0x2c, 0xa5, 0x24, 0x2f, 0xd9, 0x34, 0x0b, 0x47,
+	0x35, 0xa7, 0x28, 0x8b, 0xc5, 0xcd, 0xe9, 0x46,
+	0xac, 0x39, 0x94, 0x3c, 0x10, 0xc6, 0x29, 0x73,
+	0x0e, 0x0e, 0x5d, 0xe0, 0x71, 0x03, 0x8a, 0x72,
+	0x0e, 0x26, 0xb0, 0x7d, 0x84, 0xed, 0x95, 0x23,
+	0x49, 0x5a, 0x45, 0x83, 0x45, 0x60, 0x11, 0x4a,
+	0x46, 0x31, 0xd4, 0xd8, 0x16, 0x54, 0x98, 0x58,
+	0xed, 0x6d, 0xcc, 0x5d, 0xd6, 0x50, 0x61, 0x9f,
+	0x9d, 0xc5, 0x3e, 0x9d, 0x32, 0x47, 0xde, 0x96,
+	0xe1, 0x5d, 0xd8, 0xf8, 0xb4, 0x69, 0x6f, 0xb9,
+	0x15, 0x90, 0x57, 0x7a, 0xf6, 0xad, 0xb0, 0x5b,
+	0xf5, 0xa6, 0x36, 0x94, 0xfd, 0x84, 0xce, 0x1c,
+	0x0f, 0x4b, 0xd0, 0xc2, 0x5b, 0x6b, 0x56, 0xef,
+	0x73, 0x93, 0x0b, 0xc3, 0xee, 0xd9, 0xcf, 0xd3,
+	0xa4, 0x22, 0x58, 0xcd, 0x50, 0x6e, 0x65, 0xf4,
+	0xe9, 0xb7, 0x71, 0xaf, 0x4b, 0xb3, 0xb6, 0x2f,
+	0x0f, 0x0e, 0x3b, 0xc9, 0x85, 0x14, 0xf5, 0x17,
+	0xe8, 0x7a, 0x3a, 0xbf, 0x5f, 0x5e, 0xf8, 0x18,
+	0x48, 0xa6, 0x72, 0xab, 0x06, 0x95, 0xe9, 0xc8,
+	0xa7, 0xf4, 0x32, 0x44, 0x04, 0x0c, 0x84, 0x98,
+	0x73, 0xe3, 0x89, 0x8d, 0x5f, 0x7e, 0x4a, 0x42,
+	0x8f, 0xc5, 0x28, 0xb1, 0x82, 0xef, 0x1c, 0x97,
+	0x31, 0x3b, 0x4d, 0xe0, 0x0e, 0x10, 0x10, 0x97,
+	0x93, 0x49, 0x78, 0x2f, 0x0d, 0x86, 0x8b, 0xa1,
+	0x53, 0xa9, 0x81, 0x20, 0x79, 0xe7, 0x07, 0x77,
+	0xb6, 0xac, 0x5e, 0xd2, 0x05, 0xcd, 0xe9, 0xdb,
+	0x8a, 0x94, 0x82, 0x8a, 0x23, 0xb9, 0x3d, 0x1c,
+	0xa9, 0x7d, 0x72, 0x4a, 0xed, 0x33, 0xa3, 0xdb,
+	0x21, 0xa7, 0x86, 0x33, 0x45, 0xa5, 0xaa, 0x56,
+	0x45, 0xb5, 0x83, 0x29, 0x40, 0x47, 0x79, 0x04,
+	0x6e, 0xb9, 0x95, 0xd0, 0x81, 0x77, 0x2d, 0x48,
+	0x1e, 0xfe, 0xc3, 0xc2, 0x1e, 0xe5, 0xf2, 0xbe,
+	0xfd, 0x3b, 0x94, 0x9f, 0xc4, 0xc4, 0x26, 0x9d,
+	0xe4, 0x66, 0x1e, 0x19, 0xee, 0x6c, 0x79, 0x97,
+	0x11, 0x31, 0x4b, 0x0d, 0x01, 0xcb, 0xde, 0xa8,
+	0xf6, 0x6d, 0x7c, 0x39, 0x46, 0x4e, 0x7e, 0x3f,
+	0x94, 0x17, 0xdf, 0xa1, 0x7d, 0xd9, 0x1c, 0x8e,
+	0xbc, 0x7d, 0x33, 0x7d, 0xe3, 0x12, 0x40, 0xca,
+	0xab, 0x37, 0x11, 0x46, 0xd4, 0xae, 0xef, 0x44,
+	0xa2, 0xb3, 0x6a, 0x66, 0x0e, 0x0c, 0x90, 0x7f,
+	0xdf, 0x5c, 0x66, 0x5f, 0xf2, 0x94, 0x9f, 0xa6,
+	0x73, 0x4f, 0xeb, 0x0d, 0xad, 0xbf, 0xc0, 0x63,
+	0x5c, 0xdc, 0x46, 0x51, 0xe8, 0x8e, 0x90, 0x19,
+	0xa8, 0xa4, 0x3c, 0x91, 0x79, 0xfa, 0x7e, 0x58,
+	0x85, 0x13, 0x55, 0xc5, 0x19, 0x82, 0x37, 0x1b,
+	0x0a, 0x02, 0x1f, 0x99, 0x6b, 0x18, 0xf1, 0x28,
+	0x08, 0xa2, 0x73, 0xb8, 0x0f, 0x2e, 0xcd, 0xbf,
+	0xf3, 0x86, 0x7f, 0xea, 0xef, 0xd0, 0xbb, 0xa6,
+	0x21, 0xdf, 0x49, 0x73, 0x51, 0xcc, 0x36, 0xd3,
+	0x3e, 0xa0, 0xf8, 0x44, 0xdf, 0xd3, 0xa6, 0xbe,
+	0x8a, 0xd4, 0x57, 0xdd, 0x72, 0x94, 0x61, 0x0f,
+	0x82, 0xd1, 0x07, 0xb8, 0x7c, 0x18, 0x83, 0xdf,
+	0x3a, 0xe5, 0x50, 0x6a, 0x82, 0x20, 0xac, 0xa9,
+	0xa8, 0xff, 0xd9, 0xf3, 0x77, 0x33, 0x5a, 0x9e,
+	0x7f, 0x6d, 0xfe, 0x5d, 0x33, 0x41, 0x42, 0xe7,
+	0x6c, 0x19, 0xe0, 0x44, 0x8a, 0x15, 0xf6, 0x70,
+	0x98, 0xb7, 0x68, 0x4d, 0xfa, 0x97, 0x39, 0xb0,
+	0x8e, 0xe8, 0x84, 0x8b, 0x75, 0x30, 0xb7, 0x7d,
+	0x92, 0x69, 0x20, 0x9c, 0x81, 0xfb, 0x4b, 0xf4,
+	0x01, 0x50, 0xeb, 0xce, 0x0c, 0x1c, 0x6c, 0xb5,
+	0x4a, 0xd7, 0x27, 0x0c, 0xce, 0xbb, 0xe5, 0x85,
+	0xf0, 0xb6, 0xee, 0xd5, 0x70, 0xdd, 0x3b, 0xfc,
+	0xd4, 0x99, 0xf1, 0x33, 0xdd, 0x8b, 0xc4, 0x2f,
+	0xae, 0xab, 0x74, 0x96, 0x32, 0xc7, 0x4c, 0x56,
+	0x3c, 0x89, 0x0f, 0x96, 0x0b, 0x42, 0xc0, 0xcb,
+	0xee, 0x0f, 0x0b, 0x8c, 0xfb, 0x7e, 0x47, 0x7b,
+	0x64, 0x48, 0xfd, 0xb2, 0x00, 0x80, 0x89, 0xa5,
+	0x13, 0x55, 0x62, 0xfc, 0x8f, 0xe2, 0x42, 0x03,
+	0xb7, 0x4e, 0x2a, 0x79, 0xb4, 0x82, 0xea, 0x23,
+	0x49, 0xda, 0xaf, 0x52, 0x63, 0x1e, 0x60, 0x03,
+	0x89, 0x06, 0x44, 0x46, 0x08, 0xc3, 0xc4, 0x87,
+	0x70, 0x2e, 0xda, 0x94, 0xad, 0x6b, 0xe0, 0xe4,
+	0xd1, 0x8a, 0x06, 0xc2, 0xa8, 0xc0, 0xa7, 0x43,
+	0x3c, 0x47, 0x52, 0x0e, 0xc3, 0x77, 0x81, 0x11,
+	0x67, 0x0e, 0xa0, 0x70, 0x04, 0x47, 0x29, 0x40,
+	0x86, 0x0d, 0x34, 0x56, 0xa7, 0xc9, 0x35, 0x59,
+	0x68, 0xdc, 0x93, 0x81, 0x70, 0xee, 0x86, 0xd9,
+	0x80, 0x06, 0x40, 0x4f, 0x1a, 0x0d, 0x40, 0x30,
+	0x0b, 0xcb, 0x96, 0x47, 0xc1, 0xb7, 0x52, 0xfd,
+	0x56, 0xe0, 0x72, 0x4b, 0xfb, 0xbd, 0x92, 0x45,
+	0x61, 0x71, 0xc2, 0x33, 0x11, 0xbf, 0x52, 0x83,
+	0x79, 0x26, 0xe0, 0x49, 0x6b, 0xb7, 0x05, 0x8b,
+	0xe8, 0x0e, 0x87, 0x31, 0xd7, 0x9d, 0x8a, 0xf5,
+	0xc0, 0x5f, 0x2e, 0x58, 0x4a, 0xdb, 0x11, 0xb3,
+	0x6c, 0x30, 0x2a, 0x46, 0x19, 0xe3, 0x27, 0x84,
+	0x1f, 0x63, 0x6e, 0xf6, 0x57, 0xc7, 0xc9, 0xd8,
+	0x5e, 0xba, 0xb3, 0x87, 0xd5, 0x83, 0x26, 0x34,
+	0x21, 0x9e, 0x65, 0xde, 0x42, 0xd3, 0xbe, 0x7b,
+	0xbc, 0x91, 0x71, 0x44, 0x4d, 0x99, 0x3b, 0x31,
+	0xe5, 0x3f, 0x11, 0x4e, 0x7f, 0x13, 0x51, 0x3b,
+	0xae, 0x79, 0xc9, 0xd3, 0x81, 0x8e, 0x25, 0x40,
+	0x10, 0xfc, 0x07, 0x1e, 0xf9, 0x7b, 0x9a, 0x4b,
+	0x6c, 0xe3, 0xb3, 0xad, 0x1a, 0x0a, 0xdd, 0x9e,
+	0x59, 0x0c, 0xa2, 0xcd, 0xae, 0x48, 0x4a, 0x38,
+	0x5b, 0x47, 0x41, 0x94, 0x65, 0x6b, 0xbb, 0xeb,
+	0x5b, 0xe3, 0xaf, 0x07, 0x5b, 0xd4, 0x4a, 0xa2,
+	0xc9, 0x5d, 0x2f, 0x64, 0x03, 0xd7, 0x3a, 0x2c,
+	0x6e, 0xce, 0x76, 0x95, 0xb4, 0xb3, 0xc0, 0xf1,
+	0xe2, 0x45, 0x73, 0x7a, 0x5c, 0xab, 0xc1, 0xfc,
+	0x02, 0x8d, 0x81, 0x29, 0xb3, 0xac, 0x07, 0xec,
+	0x40, 0x7d, 0x45, 0xd9, 0x7a, 0x59, 0xee, 0x34,
+	0xf0, 0xe9, 0xd5, 0x7b, 0x96, 0xb1, 0x3d, 0x95,
+	0xcc, 0x86, 0xb5, 0xb6, 0x04, 0x2d, 0xb5, 0x92,
+	0x7e, 0x76, 0xf4, 0x06, 0xa9, 0xa3, 0x12, 0x0f,
+	0xb1, 0xaf, 0x26, 0xba, 0x7c, 0xfc, 0x7e, 0x1c,
+	0xbc, 0x2c, 0x49, 0x97, 0x53, 0x60, 0x13, 0x0b,
+	0xa6, 0x61, 0x83, 0x89, 0x42, 0xd4, 0x17, 0x0c,
+	0x6c, 0x26, 0x52, 0xc3, 0xb3, 0xd4, 0x67, 0xf5,
+	0xe3, 0x04, 0xb7, 0xf4, 0xcb, 0x80, 0xb8, 0xcb,
+	0x77, 0x56, 0x3e, 0xaa, 0x57, 0x54, 0xee, 0xb4,
+	0x2c, 0x67, 0xcf, 0xf2, 0xdc, 0xbe, 0x55, 0xf9,
+	0x43, 0x1f, 0x6e, 0x22, 0x97, 0x67, 0x7f, 0xc4,
+	0xef, 0xb1, 0x26, 0x31, 0x1e, 0x27, 0xdf, 0x41,
+	0x80, 0x47, 0x6c, 0xe2, 0xfa, 0xa9, 0x8c, 0x2a,
+	0xf6, 0xf2, 0xab, 0xf0, 0x15, 0xda, 0x6c, 0xc8,
+	0xfe, 0xb5, 0x23, 0xde, 0xa9, 0x05, 0x3f, 0x06,
+	0x54, 0x4c, 0xcd, 0xe1, 0xab, 0xfc, 0x0e, 0x62,
+	0x33, 0x31, 0x73, 0x2c, 0x76, 0xcb, 0xb4, 0x47,
+	0x1e, 0x20, 0xad, 0xd8, 0xf2, 0x31, 0xdd, 0xc4,
+	0x8b, 0x0c, 0x77, 0xbe, 0xe1, 0x8b, 0x26, 0x00,
+	0x02, 0x58, 0xd6, 0x8d, 0xef, 0xad, 0x74, 0x67,
+	0xab, 0x3f, 0xef, 0xcb, 0x6f, 0xb0, 0xcc, 0x81,
+	0x44, 0x4c, 0xaf, 0xe9, 0x49, 0x4f, 0xdb, 0xa0,
+	0x25, 0xa4, 0xf0, 0x89, 0xf1, 0xbe, 0xd8, 0x10,
+	0xff, 0xb1, 0x3b, 0x4b, 0xfa, 0x98, 0xf5, 0x79,
+	0x6d, 0x1e, 0x69, 0x4d, 0x57, 0xb1, 0xc8, 0x19,
+	0x1b, 0xbd, 0x1e, 0x8c, 0x84, 0xb7, 0x7b, 0xe8,
+	0xd2, 0x2d, 0x09, 0x41, 0x41, 0x37, 0x3d, 0xb1,
+	0x6f, 0x26, 0x5d, 0x71, 0x16, 0x3d, 0xb7, 0x83,
+	0x27, 0x2c, 0xa7, 0xb6, 0x50, 0xbd, 0x91, 0x86,
+	0xab, 0x24, 0xa1, 0x38, 0xfd, 0xea, 0x71, 0x55,
+	0x7e, 0x9a, 0x07, 0x77, 0x4b, 0xfa, 0x61, 0x66,
+	0x20, 0x1e, 0x28, 0x95, 0x18, 0x1b, 0xa4, 0xa0,
+	0xfd, 0xc0, 0x89, 0x72, 0x43, 0xd9, 0x3b, 0x49,
+	0x5a, 0x3f, 0x9d, 0xbf, 0xdb, 0xb4, 0x46, 0xea,
+	0x42, 0x01, 0x77, 0x23, 0x68, 0x95, 0xb6, 0x24,
+	0xb3, 0xa8, 0x6c, 0x28, 0x3b, 0x11, 0x40, 0x7e,
+	0x18, 0x65, 0x6d, 0xd8, 0x24, 0x42, 0x7d, 0x88,
+	0xc0, 0x52, 0xd9, 0x05, 0xe4, 0x95, 0x90, 0x87,
+	0x8c, 0xf4, 0xd0, 0x6b, 0xb9, 0x83, 0x99, 0x34,
+	0x6d, 0xfe, 0x54, 0x40, 0x94, 0x52, 0x21, 0x4f,
+	0x14, 0x25, 0xc5, 0xd6, 0x5e, 0x95, 0xdc, 0x0a,
+	0x2b, 0x89, 0x20, 0x11, 0x84, 0x48, 0xd6, 0x3a,
+	0xcd, 0x5c, 0x24, 0xad, 0x62, 0xe3, 0xb1, 0x93,
+	0x25, 0x8d, 0xcd, 0x7e, 0xfc, 0x27, 0xa3, 0x37,
+	0xfd, 0x84, 0xfc, 0x1b, 0xb2, 0xf1, 0x27, 0x38,
+	0x5a, 0xb7, 0xfc, 0xf2, 0xfa, 0x95, 0x66, 0xd4,
+	0xfb, 0xba, 0xa7, 0xd7, 0xa3, 0x72, 0x69, 0x48,
+	0x48, 0x8c, 0xeb, 0x28, 0x89, 0xfe, 0x33, 0x65,
+	0x5a, 0x36, 0x01, 0x7e, 0x06, 0x79, 0x0a, 0x09,
+	0x3b, 0x74, 0x11, 0x9a, 0x6e, 0xbf, 0xd4, 0x9e,
+	0x58, 0x90, 0x49, 0x4f, 0x4d, 0x08, 0xd4, 0xe5,
+	0x4a, 0x09, 0x21, 0xef, 0x8b, 0xb8, 0x74, 0x3b,
+	0x91, 0xdd, 0x36, 0x85, 0x60, 0x2d, 0xfa, 0xd4,
+	0x45, 0x7b, 0x45, 0x53, 0xf5, 0x47, 0x87, 0x7e,
+	0xa6, 0x37, 0xc8, 0x78, 0x7a, 0x68, 0x9d, 0x8d,
+	0x65, 0x2c, 0x0e, 0x91, 0x5c, 0xa2, 0x60, 0xf0,
+	0x8e, 0x3f, 0xe9, 0x1a, 0xcd, 0xaa, 0xe7, 0xd5,
+	0x77, 0x18, 0xaf, 0xc9, 0xbc, 0x18, 0xea, 0x48,
+	0x1b, 0xfb, 0x22, 0x48, 0x70, 0x16, 0x29, 0x9e,
+	0x5b, 0xc1, 0x2c, 0x66, 0x23, 0xbc, 0xf0, 0x1f,
+	0xef, 0xaf, 0xe4, 0xd6, 0x04, 0x19, 0x82, 0x7a,
+	0x0b, 0xba, 0x4b, 0x46, 0xb1, 0x6a, 0x85, 0x5d,
+	0xb4, 0x73, 0xd6, 0x21, 0xa1, 0x71, 0x60, 0x14,
+	0xee, 0x0a, 0x77, 0xc4, 0x66, 0x2e, 0xf9, 0x69,
+	0x30, 0xaf, 0x41, 0x0b, 0xc8, 0x83, 0x3c, 0x53,
+	0x99, 0x19, 0x27, 0x46, 0xf7, 0x41, 0x6e, 0x56,
+	0xdc, 0x94, 0x28, 0x67, 0x4e, 0xb7, 0x25, 0x48,
+	0x8a, 0xc2, 0xe0, 0x60, 0x96, 0xcc, 0x18, 0xf4,
+	0x84, 0xdd, 0xa7, 0x5e, 0x3e, 0x05, 0x0b, 0x26,
+	0x26, 0xb2, 0x5c, 0x1f, 0x57, 0x1a, 0x04, 0x7e,
+	0x6a, 0xe3, 0x2f, 0xb4, 0x35, 0xb6, 0x38, 0x40,
+	0x40, 0xcd, 0x6f, 0x87, 0x2e, 0xef, 0xa3, 0xd7,
+	0xa9, 0xc2, 0xe8, 0x0d, 0x27, 0xdf, 0x44, 0x62,
+	0x99, 0xa0, 0xfc, 0xcf, 0x81, 0x78, 0xcb, 0xfe,
+	0xe5, 0xa0, 0x03, 0x4e, 0x6c, 0xd7, 0xf4, 0xaf,
+	0x7a, 0xbb, 0x61, 0x82, 0xfe, 0x71, 0x89, 0xb2,
+	0x22, 0x7c, 0x8e, 0x83, 0x04, 0xce, 0xf6, 0x5d,
+	0x84, 0x8f, 0x95, 0x6a, 0x7f, 0xad, 0xfd, 0x32,
+	0x9c, 0x5e, 0xe4, 0x9c, 0x89, 0x60, 0x54, 0xaa,
+	0x96, 0x72, 0xd2, 0xd7, 0x36, 0x85, 0xa9, 0x45,
+	0xd2, 0x2a, 0xa1, 0x81, 0x49, 0x6f, 0x7e, 0x04,
+	0xfa, 0xe2, 0xfe, 0x90, 0x26, 0x77, 0x5a, 0x33,
+	0xb8, 0x04, 0x9a, 0x7a, 0xe6, 0x4c, 0x4f, 0xad,
+	0x72, 0x96, 0x08, 0x28, 0x58, 0x13, 0xf8, 0xc4,
+	0x1c, 0xf0, 0xc3, 0x45, 0x95, 0x49, 0x20, 0x8c,
+	0x9f, 0x39, 0x70, 0xe1, 0x77, 0xfe, 0xd5, 0x4b,
+	0xaf, 0x86, 0xda, 0xef, 0x22, 0x06, 0x83, 0x36,
+	0x29, 0x12, 0x11, 0x40, 0xbc, 0x3b, 0x86, 0xaa,
+	0xaa, 0x65, 0x60, 0xc3, 0x80, 0xca, 0xed, 0xa9,
+	0xf3, 0xb0, 0x79, 0x96, 0xa2, 0x55, 0x27, 0x28,
+	0x55, 0x73, 0x26, 0xa5, 0x50, 0xea, 0x92, 0x4b,
+	0x3c, 0x5c, 0x82, 0x33, 0xf0, 0x01, 0x3f, 0x03,
+	0xc1, 0x08, 0x05, 0xbf, 0x98, 0xf4, 0x9b, 0x6d,
+	0xa5, 0xa8, 0xb4, 0x82, 0x0c, 0x06, 0xfa, 0xff,
+	0x2d, 0x08, 0xf3, 0x05, 0x4f, 0x57, 0x2a, 0x39,
+	0xd4, 0x83, 0x0d, 0x75, 0x51, 0xd8, 0x5b, 0x1b,
+	0xd3, 0x51, 0x5a, 0x32, 0x2a, 0x9b, 0x32, 0xb2,
+	0xf2, 0xa4, 0x96, 0x12, 0xf2, 0xae, 0x40, 0x34,
+	0x67, 0xa8, 0xf5, 0x44, 0xd5, 0x35, 0x53, 0xfe,
+	0xa3, 0x60, 0x96, 0x63, 0x0f, 0x1f, 0x6e, 0xb0,
+	0x5a, 0x42, 0xa6, 0xfc, 0x51, 0x0b, 0x60, 0x27,
+	0xbc, 0x06, 0x71, 0xed, 0x65, 0x5b, 0x23, 0x86,
+	0x4a, 0x07, 0x3b, 0x22, 0x07, 0x46, 0xe6, 0x90,
+	0x3e, 0xf3, 0x25, 0x50, 0x1b, 0x4c, 0x7f, 0x03,
+	0x08, 0xa8, 0x36, 0x6b, 0x87, 0xe5, 0xe3, 0xdb,
+	0x9a, 0x38, 0x83, 0xff, 0x9f, 0x1a, 0x9f, 0x57,
+	0xa4, 0x2a, 0xf6, 0x37, 0xbc, 0x1a, 0xff, 0xc9,
+	0x1e, 0x35, 0x0c, 0xc3, 0x7c, 0xa3, 0xb2, 0xe5,
+	0xd2, 0xc6, 0xb4, 0x57, 0x47, 0xe4, 0x32, 0x16,
+	0x6d, 0xa9, 0xae, 0x64, 0xe6, 0x2d, 0x8d, 0xc5,
+	0x8d, 0x50, 0x8e, 0xe8, 0x1a, 0x22, 0x34, 0x2a,
+	0xd9, 0xeb, 0x51, 0x90, 0x4a, 0xb1, 0x41, 0x7d,
+	0x64, 0xf9, 0xb9, 0x0d, 0xf6, 0x23, 0x33, 0xb0,
+	0x33, 0xf4, 0xf7, 0x3f, 0x27, 0x84, 0xc6, 0x0f,
+	0x54, 0xa5, 0xc0, 0x2e, 0xec, 0x0b, 0x3a, 0x48,
+	0x6e, 0x80, 0x35, 0x81, 0x43, 0x9b, 0x90, 0xb1,
+	0xd0, 0x2b, 0xea, 0x21, 0xdc, 0xda, 0x5b, 0x09,
+	0xf4, 0xcc, 0x10, 0xb4, 0xc7, 0xfe, 0x79, 0x51,
+	0xc3, 0xc5, 0xac, 0x88, 0x74, 0x84, 0x0b, 0x4b,
+	0xca, 0x79, 0x16, 0x29, 0xfb, 0x69, 0x54, 0xdf,
+	0x41, 0x7e, 0xe9, 0xc7, 0x8e, 0xea, 0xa5, 0xfe,
+	0xfc, 0x76, 0x0e, 0x90, 0xc4, 0x92, 0x38, 0xad,
+	0x7b, 0x48, 0xe6, 0x6e, 0xf7, 0x21, 0xfd, 0x4e,
+	0x93, 0x0a, 0x7b, 0x41, 0x83, 0x68, 0xfb, 0x57,
+	0x51, 0x76, 0x34, 0xa9, 0x6c, 0x00, 0xaa, 0x4f,
+	0x66, 0x65, 0x98, 0x4a, 0x4f, 0xa3, 0xa0, 0xef,
+	0x69, 0x3f, 0xe3, 0x1c, 0x92, 0x8c, 0xfd, 0xd8,
+	0xe8, 0xde, 0x7c, 0x7f, 0x3e, 0x84, 0x8e, 0x69,
+	0x3c, 0xf1, 0xf2, 0x05, 0x46, 0xdc, 0x2f, 0x9d,
+	0x5e, 0x6e, 0x4c, 0xfb, 0xb5, 0x99, 0x2a, 0x59,
+	0x63, 0xc1, 0x34, 0xbc, 0x57, 0xc0, 0x0d, 0xb9,
+	0x61, 0x25, 0xf3, 0x33, 0x23, 0x51, 0xb6, 0x0d,
+	0x07, 0xa6, 0xab, 0x94, 0x4a, 0xb7, 0x2a, 0xea,
+	0xee, 0xac, 0xa3, 0xc3, 0x04, 0x8b, 0x0e, 0x56,
+	0xfe, 0x44, 0xa7, 0x39, 0xe2, 0xed, 0xed, 0xb4,
+	0x22, 0x2b, 0xac, 0x12, 0x32, 0x28, 0x91, 0xd8,
+	0xa5, 0xab, 0xff, 0x5f, 0xe0, 0x4b, 0xda, 0x78,
+	0x17, 0xda, 0xf1, 0x01, 0x5b, 0xcd, 0xe2, 0x5f,
+	0x50, 0x45, 0x73, 0x2b, 0xe4, 0x76, 0x77, 0xf4,
+	0x64, 0x1d, 0x43, 0xfb, 0x84, 0x7a, 0xea, 0x91,
+	0xae, 0xf9, 0x9e, 0xb7, 0xb4, 0xb0, 0x91, 0x5f,
+	0x16, 0x35, 0x9a, 0x11, 0xb8, 0xc7, 0xc1, 0x8c,
+	0xc6, 0x10, 0x8d, 0x2f, 0x63, 0x4a, 0xa7, 0x57,
+	0x3a, 0x51, 0xd6, 0x32, 0x2d, 0x64, 0x72, 0xd4,
+	0x66, 0xdc, 0x10, 0xa6, 0x67, 0xd6, 0x04, 0x23,
+	0x9d, 0x0a, 0x11, 0x77, 0xdd, 0x37, 0x94, 0x17,
+	0x3c, 0xbf, 0x8b, 0x65, 0xb0, 0x2e, 0x5e, 0x66,
+	0x47, 0x64, 0xac, 0xdd, 0xf0, 0x84, 0xfd, 0x39,
+	0xfa, 0x15, 0x5d, 0xef, 0xae, 0xca, 0xc1, 0x36,
+	0xa7, 0x5c, 0xbf, 0xc7, 0x08, 0xc2, 0x66, 0x00,
+	0x74, 0x74, 0x4e, 0x27, 0x3f, 0x55, 0x8a, 0xb7,
+	0x38, 0x66, 0x83, 0x6d, 0xcf, 0x99, 0x9e, 0x60,
+	0x8f, 0xdd, 0x2e, 0x62, 0x22, 0x0e, 0xef, 0x0c,
+	0x98, 0xa7, 0x85, 0x74, 0x3b, 0x9d, 0xec, 0x9e,
+	0xa9, 0x19, 0x72, 0xa5, 0x7f, 0x2c, 0x39, 0xb7,
+	0x7d, 0xb7, 0xf1, 0x12, 0x65, 0x27, 0x4b, 0x5a,
+	0xde, 0x17, 0xfe, 0xad, 0x44, 0xf3, 0x20, 0x4d,
+	0xfd, 0xe4, 0x1f, 0xb5, 0x81, 0xb0, 0x36, 0x37,
+	0x08, 0x6f, 0xc3, 0x0c, 0xe9, 0x85, 0x98, 0x82,
+	0xa9, 0x62, 0x0c, 0xc4, 0x97, 0xc0, 0x50, 0xc8,
+	0xa7, 0x3c, 0x50, 0x9f, 0x43, 0xb9, 0xcd, 0x5e,
+	0x4d, 0xfa, 0x1c, 0x4b, 0x0b, 0xa9, 0x98, 0x85,
+	0x38, 0x92, 0xac, 0x8d, 0xe4, 0xad, 0x9b, 0x98,
+	0xab, 0xd9, 0x38, 0xac, 0x62, 0x52, 0xa3, 0x22,
+	0x63, 0x0f, 0xbf, 0x95, 0x48, 0xdf, 0x69, 0xe7,
+	0x8b, 0x33, 0xd5, 0xb2, 0xbd, 0x05, 0x49, 0x49,
+	0x9d, 0x57, 0x73, 0x19, 0x33, 0xae, 0xfa, 0x33,
+	0xf1, 0x19, 0xa8, 0x80, 0xce, 0x04, 0x9f, 0xbc,
+	0x1d, 0x65, 0x82, 0x1b, 0xe5, 0x3a, 0x51, 0xc8,
+	0x1c, 0x21, 0xe3, 0x5d, 0xf3, 0x7d, 0x9b, 0x2f,
+	0x2c, 0x1d, 0x4a, 0x7f, 0x9b, 0x68, 0x35, 0xa3,
+	0xb2, 0x50, 0xf7, 0x62, 0x79, 0xcd, 0xf4, 0x98,
+	0x4f, 0xe5, 0x63, 0x7c, 0x3e, 0x45, 0x31, 0x8c,
+	0x16, 0xa0, 0x12, 0xc8, 0x58, 0xce, 0x39, 0xa6,
+	0xbc, 0x54, 0xdb, 0xc5, 0xe0, 0xd5, 0xba, 0xbc,
+	0xb9, 0x04, 0xf4, 0x8d, 0xe8, 0x2f, 0x15, 0x9d,
+};
 
-#if 0				/*Not used at present */
-static void
-buf_dump(char const *prefix, unsigned char const *buf, size_t len)
+/* 100 test cases */
+static struct crc_test {
+	u32 crc;	/* random starting crc */
+	u32 start;	/* random 6 bit offset in buf */
+	u32 length;	/* random 11 bit length of test */
+	u32 crc_le;	/* expected crc32_le result */
+	u32 crc_be;	/* expected crc32_be result */
+	u32 crc32c_le;	/* expected crc32c_le result */
+} test[] =
 {
-	fputs(prefix, stdout);
-	while (len--)
-		printf(" %02x", *buf++);
-	putchar('\n');
+	{0x674bf11d, 0x00000038, 0x00000542, 0x0af6d466, 0xd8b6e4c1,
+	 0xf6e93d6c},
+	{0x35c672c6, 0x0000003a, 0x000001aa, 0xc6d3dfba, 0x28aaf3ad,
+	 0x0fe92aca},
+	{0x496da28e, 0x00000039, 0x000005af, 0xd933660f, 0x5d57e81f,
+	 0x52e1ebb8},
+	{0x09a9b90e, 0x00000027, 0x000001f8, 0xb45fe007, 0xf45fca9a,
+	 0x0798af9a},
+	{0xdc97e5a9, 0x00000025, 0x000003b6, 0xf81a3562, 0xe0126ba2,
+	 0x18eb3152},
+	{0x47c58900, 0x0000000a, 0x000000b9, 0x8e58eccf, 0xf3afc793,
+	 0xd00d08c7},
+	{0x292561e8, 0x0000000c, 0x00000403, 0xa2ba8aaf, 0x0b797aed,
+	 0x8ba966bc},
+	{0x415037f6, 0x00000003, 0x00000676, 0xa17d52e8, 0x7f0fdf35,
+	 0x11d694a2},
+	{0x3466e707, 0x00000026, 0x00000042, 0x258319be, 0x75c484a2,
+	 0x6ab3208d},
+	{0xafd1281b, 0x00000023, 0x000002ee, 0x4428eaf8, 0x06c7ad10,
+	 0xba4603c5},
+	{0xd3857b18, 0x00000028, 0x000004a2, 0x5c430821, 0xb062b7cb,
+	 0xe6071c6f},
+	{0x1d825a8f, 0x0000002b, 0x0000050b, 0xd2c45f0c, 0xd68634e0,
+	 0x179ec30a},
+	{0x5033e3bc, 0x0000000b, 0x00000078, 0xa3ea4113, 0xac6d31fb,
+	 0x0903beb8},
+	{0x94f1fb5e, 0x0000000f, 0x000003a2, 0xfbfc50b1, 0x3cfe50ed,
+	 0x6a7cb4fa},
+	{0xc9a0fe14, 0x00000009, 0x00000473, 0x5fb61894, 0x87070591,
+	 0xdb535801},
+	{0x88a034b1, 0x0000001c, 0x000005ad, 0xc1b16053, 0x46f95c67,
+	 0x92bed597},
+	{0xf0f72239, 0x00000020, 0x0000026d, 0xa6fa58f3, 0xf8c2c1dd,
+	 0x192a3f1b},
+	{0xcc20a5e3, 0x0000003b, 0x0000067a, 0x7740185a, 0x308b979a,
+	 0xccbaec1a},
+	{0xce589c95, 0x0000002b, 0x00000641, 0xd055e987, 0x40aae25b,
+	 0x7eabae4d},
+	{0x78edc885, 0x00000035, 0x000005be, 0xa39cb14b, 0x035b0d1f,
+	 0x28c72982},
+	{0x9d40a377, 0x0000003b, 0x00000038, 0x1f47ccd2, 0x197fbc9d,
+	 0xc3cd4d18},
+	{0x703d0e01, 0x0000003c, 0x000006f1, 0x88735e7c, 0xfed57c5a,
+	 0xbca8f0e7},
+	{0x776bf505, 0x0000000f, 0x000005b2, 0x5cc4fc01, 0xf32efb97,
+	 0x713f60b3},
+	{0x4a3e7854, 0x00000027, 0x000004b8, 0x8d923c82, 0x0cbfb4a2,
+	 0xebd08fd5},
+	{0x209172dd, 0x0000003b, 0x00000356, 0xb89e9c2b, 0xd7868138,
+	 0x64406c59},
+	{0x3ba4cc5b, 0x0000002f, 0x00000203, 0xe51601a9, 0x5b2a1032,
+	 0x7421890e},
+	{0xfc62f297, 0x00000000, 0x00000079, 0x71a8e1a2, 0x5d88685f,
+	 0xe9347603},
+	{0x64280b8b, 0x00000016, 0x000007ab, 0x0fa7a30c, 0xda3a455f,
+	 0x1bef9060},
+	{0x97dd724b, 0x00000033, 0x000007ad, 0x5788b2f4, 0xd7326d32,
+	 0x34720072},
+	{0x61394b52, 0x00000035, 0x00000571, 0xc66525f1, 0xcabe7fef,
+	 0x48310f59},
+	{0x29b4faff, 0x00000024, 0x0000006e, 0xca13751e, 0x993648e0,
+	 0x783a4213},
+	{0x29bfb1dc, 0x0000000b, 0x00000244, 0x436c43f7, 0x429f7a59,
+	 0x9e8efd41},
+	{0x86ae934b, 0x00000035, 0x00000104, 0x0760ec93, 0x9cf7d0f4,
+	 0xfc3d34a5},
+	{0xc4c1024e, 0x0000002e, 0x000006b1, 0x6516a3ec, 0x19321f9c,
+	 0x17a52ae2},
+	{0x3287a80a, 0x00000026, 0x00000496, 0x0b257eb1, 0x754ebd51,
+	 0x886d935a},
+	{0xa4db423e, 0x00000023, 0x0000045d, 0x9b3a66dc, 0x873e9f11,
+	 0xeaaeaeb2},
+	{0x7a1078df, 0x00000015, 0x0000014a, 0x8c2484c5, 0x6a628659,
+	 0x8e900a4b},
+	{0x6048bd5b, 0x00000006, 0x0000006a, 0x897e3559, 0xac9961af,
+	 0xd74662b1},
+	{0xd8f9ea20, 0x0000003d, 0x00000277, 0x60eb905b, 0xed2aaf99,
+	 0xd26752ba},
+	{0xea5ec3b4, 0x0000002a, 0x000004fe, 0x869965dc, 0x6c1f833b,
+	 0x8b1fcd62},
+	{0x2dfb005d, 0x00000016, 0x00000345, 0x6a3b117e, 0xf05e8521,
+	 0xf54342fe},
+	{0x5a214ade, 0x00000020, 0x000005b6, 0x467f70be, 0xcb22ccd3,
+	 0x5b95b988},
+	{0xf0ab9cca, 0x00000032, 0x00000515, 0xed223df3, 0x7f3ef01d,
+	 0x2e1176be},
+	{0x91b444f9, 0x0000002e, 0x000007f8, 0x84e9a983, 0x5676756f,
+	 0x66120546},
+	{0x1b5d2ddb, 0x0000002e, 0x0000012c, 0xba638c4c, 0x3f42047b,
+	 0xf256a5cc},
+	{0xd824d1bb, 0x0000003a, 0x000007b5, 0x6288653b, 0x3a3ebea0,
+	 0x4af1dd69},
+	{0x0470180c, 0x00000034, 0x000001f0, 0x9d5b80d6, 0x3de08195,
+	 0x56f0a04a},
+	{0xffaa3a3f, 0x00000036, 0x00000299, 0xf3a82ab8, 0x53e0c13d,
+	 0x74f6b6b2},
+	{0x6406cfeb, 0x00000023, 0x00000600, 0xa920b8e8, 0xe4e2acf4,
+	 0x085951fd},
+	{0xb24aaa38, 0x0000003e, 0x000004a1, 0x657cc328, 0x5077b2c3,
+	 0xc65387eb},
+	{0x58b2ab7c, 0x00000039, 0x000002b4, 0x3a17ee7e, 0x9dcb3643,
+	 0x1ca9257b},
+	{0x3db85970, 0x00000006, 0x000002b6, 0x95268b59, 0xb9812c10,
+	 0xfd196d76},
+	{0x857830c5, 0x00000003, 0x00000590, 0x4ef439d5, 0xf042161d,
+	 0x5ef88339},
+	{0xe1fcd978, 0x0000003e, 0x000007d8, 0xae8d8699, 0xce0a1ef5,
+	 0x2c3714d9},
+	{0xb982a768, 0x00000016, 0x000006e0, 0x62fad3df, 0x5f8a067b,
+	 0x58576548},
+	{0x1d581ce8, 0x0000001e, 0x0000058b, 0xf0f5da53, 0x26e39eee,
+	 0xfd7c57de},
+	{0x2456719b, 0x00000025, 0x00000503, 0x4296ac64, 0xd50e4c14,
+	 0xd5fedd59},
+	{0xfae6d8f2, 0x00000000, 0x0000055d, 0x057fdf2e, 0x2a31391a,
+	 0x1cc3b17b},
+	{0xcba828e3, 0x00000039, 0x000002ce, 0xe3f22351, 0x8f00877b,
+	 0x270eed73},
+	{0x13d25952, 0x0000000a, 0x0000072d, 0x76d4b4cc, 0x5eb67ec3,
+	 0x91ecbb11},
+	{0x0342be3f, 0x00000015, 0x00000599, 0xec75d9f1, 0x9d4d2826,
+	 0x05ed8d0c},
+	{0xeaa344e0, 0x00000014, 0x000004d8, 0x72a4c981, 0x2064ea06,
+	 0x0b09ad5b},
+	{0xbbb52021, 0x0000003b, 0x00000272, 0x04af99fc, 0xaf042d35,
+	 0xf8d511fb},
+	{0xb66384dc, 0x0000001d, 0x000007fc, 0xd7629116, 0x782bd801,
+	 0x5ad832cc},
+	{0x616c01b6, 0x00000022, 0x000002c8, 0x5b1dab30, 0x783ce7d2,
+	 0x1214d196},
+	{0xce2bdaad, 0x00000016, 0x0000062a, 0x932535c8, 0x3f02926d,
+	 0x5747218a},
+	{0x00fe84d7, 0x00000005, 0x00000205, 0x850e50aa, 0x753d649c,
+	 0xde8f14de},
+	{0xbebdcb4c, 0x00000006, 0x0000055d, 0xbeaa37a2, 0x2d8c9eba,
+	 0x3563b7b9},
+	{0xd8b1a02a, 0x00000010, 0x00000387, 0x5017d2fc, 0x503541a5,
+	 0x071475d0},
+	{0x3b96cad2, 0x00000036, 0x00000347, 0x1d2372ae, 0x926cd90b,
+	 0x54c79d60},
+	{0xc94c1ed7, 0x00000005, 0x0000038b, 0x9e9fdb22, 0x144a9178,
+	 0x4c53eee6},
+	{0x1aad454e, 0x00000025, 0x000002b2, 0xc3f6315c, 0x5c7a35b3,
+	 0x10137a3c},
+	{0xa4fec9a6, 0x00000000, 0x000006d6, 0x90be5080, 0xa4107605,
+	 0xaa9d6c73},
+	{0x1bbe71e2, 0x0000001f, 0x000002fd, 0x4e504c3b, 0x284ccaf1,
+	 0xb63d23e7},
+	{0x4201c7e4, 0x00000002, 0x000002b7, 0x7822e3f9, 0x0cc912a9,
+	 0x7f53e9cf},
+	{0x23fddc96, 0x00000003, 0x00000627, 0x8a385125, 0x07767e78,
+	 0x13c1cd83},
+	{0xd82ba25c, 0x00000016, 0x0000063e, 0x98e4148a, 0x283330c9,
+	 0x49ff5867},
+	{0x786f2032, 0x0000002d, 0x0000060f, 0xf201600a, 0xf561bfcd,
+	 0x8467f211},
+	{0xfebe4e1f, 0x0000002a, 0x000004f2, 0x95e51961, 0xfd80dcab,
+	 0x3f9683b2},
+	{0x1a6e0a39, 0x00000008, 0x00000672, 0x8af6c2a5, 0x78dd84cb,
+	 0x76a3f874},
+	{0x56000ab8, 0x0000000e, 0x000000e5, 0x36bacb8f, 0x22ee1f77,
+	 0x863b702f},
+	{0x4717fe0c, 0x00000000, 0x000006ec, 0x8439f342, 0x5c8e03da,
+	 0xdc6c58ff},
+	{0xd5d5d68e, 0x0000003c, 0x000003a3, 0x46fff083, 0x177d1b39,
+	 0x0622cc95},
+	{0xc25dd6c6, 0x00000024, 0x000006c0, 0x5ceb8eb4, 0x892b0d16,
+	 0xe85605cd},
+	{0xe9b11300, 0x00000023, 0x00000683, 0x07a5d59a, 0x6c6a3208,
+	 0x31da5f06},
+	{0x95cd285e, 0x00000001, 0x00000047, 0x7b3a4368, 0x0202c07e,
+	 0xa1f2e784},
+	{0xd9245a25, 0x0000001e, 0x000003a6, 0xd33c1841, 0x1936c0d5,
+	 0xb07cc616},
+	{0x103279db, 0x00000006, 0x0000039b, 0xca09b8a0, 0x77d62892,
+	 0xbf943b6c},
+	{0x1cba3172, 0x00000027, 0x000001c8, 0xcb377194, 0xebe682db,
+	 0x2c01af1c},
+	{0x8f613739, 0x0000000c, 0x000001df, 0xb4b0bc87, 0x7710bd43,
+	 0x0fe5f56d},
+	{0x1c6aa90d, 0x0000001b, 0x0000053c, 0x70559245, 0xda7894ac,
+	 0xf8943b2d},
+	{0xaabe5b93, 0x0000003d, 0x00000715, 0xcdbf42fa, 0x0c3b99e7,
+	 0xe4d89272},
+	{0xf15dd038, 0x00000006, 0x000006db, 0x6e104aea, 0x8d5967f2,
+	 0x7c2f6bbb},
+	{0x584dd49c, 0x00000020, 0x000007bc, 0x36b6cfd6, 0xad4e23b2,
+	 0xabbf388b},
+	{0x5d8c9506, 0x00000020, 0x00000470, 0x4c62378e, 0x31d92640,
+	 0x1dca1f4e},
+	{0xb80d17b0, 0x00000032, 0x00000346, 0x22a5bb88, 0x9a7ec89f,
+	 0x5c170e23},
+	{0xdaf0592e, 0x00000023, 0x000007b0, 0x3cab3f99, 0x9b1fdd99,
+	 0xc0e9d672},
+	{0x4793cc85, 0x0000000d, 0x00000706, 0xe82e04f6, 0xed3db6b7,
+	 0xc18bdc86},
+	{0x82ebf64e, 0x00000009, 0x000007c3, 0x69d590a9, 0x9efa8499,
+	 0xa874fcdd},
+	{0xb18a0319, 0x00000026, 0x000007db, 0x1cf98dcc, 0x8fa9ad6a,
+	 0x9dc0bb48},
+};
 
-}
-#endif
+#include <linux/time.h>
 
-static void bytereverse(unsigned char *buf, size_t len)
+static int __init crc32c_test(void)
 {
-	while (len--) {
-		unsigned char x = bitrev8(*buf);
-		*buf++ = x;
+	int i;
+	int errors = 0;
+	int bytes = 0;
+	struct timespec start, stop;
+	u64 nsec;
+	unsigned long flags;
+
+	/* keep static to prevent cache warming code from
+	 * getting eliminated by the compiler */
+	static u32 crc;
+
+	/* pre-warm the cache */
+	for (i = 0; i < 100; i++) {
+		bytes += 2*test[i].length;
+
+		crc ^= __crc32c_le(test[i].crc, test_buf +
+		    test[i].start, test[i].length);
 	}
-}
 
-static void random_garbage(unsigned char *buf, size_t len)
-{
-	while (len--)
-		*buf++ = (unsigned char) random();
-}
+	/* reduce OS noise */
+	local_irq_save(flags);
+	local_irq_disable();
 
-#if 0				/* Not used at present */
-static void store_le(u32 x, unsigned char *buf)
-{
-	buf[0] = (unsigned char) x;
-	buf[1] = (unsigned char) (x >> 8);
-	buf[2] = (unsigned char) (x >> 16);
-	buf[3] = (unsigned char) (x >> 24);
-}
-#endif
+	getnstimeofday(&start);
+	for (i = 0; i < 100; i++) {
+		if (test[i].crc32c_le != __crc32c_le(test[i].crc, test_buf +
+		    test[i].start, test[i].length))
+			errors++;
+	}
+	getnstimeofday(&stop);
 
-static void store_be(u32 x, unsigned char *buf)
-{
-	buf[0] = (unsigned char) (x >> 24);
-	buf[1] = (unsigned char) (x >> 16);
-	buf[2] = (unsigned char) (x >> 8);
-	buf[3] = (unsigned char) x;
+	local_irq_restore(flags);
+	local_irq_enable();
+
+	nsec = stop.tv_nsec - start.tv_nsec +
+		1000000000 * (stop.tv_sec - start.tv_sec);
+
+	pr_info("crc32c: CRC_LE_BITS = %d\n", CRC_LE_BITS);
+
+	if (errors)
+		pr_warn("crc32c: %d self tests failed\n", errors);
+	else {
+		pr_info("crc32c: self tests passed, processed %d bytes in %lld nsec\n",
+			bytes, nsec);
+	}
+
+	return 0;
 }
 
-/*
- * This checks that CRC(buf + CRC(buf)) = 0, and that
- * CRC commutes with bit-reversal.  This has the side effect
- * of bytewise bit-reversing the input buffer, and returns
- * the CRC of the reversed buffer.
- */
-static u32 test_step(u32 init, unsigned char *buf, size_t len)
+static int __init crc32_test(void)
 {
-	u32 crc1, crc2;
-	size_t i;
+	int i;
+	int errors = 0;
+	int bytes = 0;
+	struct timespec start, stop;
+	u64 nsec;
+	unsigned long flags;
+
+	/* keep static to prevent cache warming code from
+	 * getting eliminated by the compiler */
+	static u32 crc;
+
+	/* pre-warm the cache */
+	for (i = 0; i < 100; i++) {
+		bytes += 2*test[i].length;
 
-	crc1 = crc32_be(init, buf, len);
-	store_be(crc1, buf + len);
-	crc2 = crc32_be(init, buf, len + 4);
-	if (crc2)
-		printf("\nCRC cancellation fail: 0x%08x should be 0\n",
-		       crc2);
-
-	for (i = 0; i <= len + 4; i++) {
-		crc2 = crc32_be(init, buf, i);
-		crc2 = crc32_be(crc2, buf + i, len + 4 - i);
-		if (crc2)
-			printf("\nCRC split fail: 0x%08x\n", crc2);
+		crc ^= crc32_le(test[i].crc, test_buf +
+		    test[i].start, test[i].length);
+
+		crc ^= crc32_be(test[i].crc, test_buf +
+		    test[i].start, test[i].length);
 	}
 
-	/* Now swap it around for the other test */
-
-	bytereverse(buf, len + 4);
-	init = bitrev32(init);
-	crc2 = bitrev32(crc1);
-	if (crc1 != bitrev32(crc2))
-		printf("\nBit reversal fail: 0x%08x -> 0x%08x -> 0x%08x\n",
-		       crc1, crc2, bitrev32(crc2));
-	crc1 = crc32_le(init, buf, len);
-	if (crc1 != crc2)
-		printf("\nCRC endianness fail: 0x%08x != 0x%08x\n", crc1,
-		       crc2);
-	crc2 = crc32_le(init, buf, len + 4);
-	if (crc2)
-		printf("\nCRC cancellation fail: 0x%08x should be 0\n",
-		       crc2);
-
-	for (i = 0; i <= len + 4; i++) {
-		crc2 = crc32_le(init, buf, i);
-		crc2 = crc32_le(crc2, buf + i, len + 4 - i);
-		if (crc2)
-			printf("\nCRC split fail: 0x%08x\n", crc2);
+	/* reduce OS noise */
+	local_irq_save(flags);
+	local_irq_disable();
+
+	getnstimeofday(&start);
+	for (i = 0; i < 100; i++) {
+		if (test[i].crc_le != crc32_le(test[i].crc, test_buf +
+		    test[i].start, test[i].length))
+			errors++;
+
+		if (test[i].crc_be != crc32_be(test[i].crc, test_buf +
+		    test[i].start, test[i].length))
+			errors++;
 	}
+	getnstimeofday(&stop);
 
-	return crc1;
-}
+	local_irq_restore(flags);
+	local_irq_enable();
 
-#define SIZE 64
-#define INIT1 0
-#define INIT2 0
+	nsec = stop.tv_nsec - start.tv_nsec +
+		1000000000 * (stop.tv_sec - start.tv_sec);
 
-int main(void)
-{
-	unsigned char buf1[SIZE + 4];
-	unsigned char buf2[SIZE + 4];
-	unsigned char buf3[SIZE + 4];
-	int i, j;
-	u32 crc1, crc2, crc3;
-
-	for (i = 0; i <= SIZE; i++) {
-		printf("\rTesting length %d...", i);
-		fflush(stdout);
-		random_garbage(buf1, i);
-		random_garbage(buf2, i);
-		for (j = 0; j < i; j++)
-			buf3[j] = buf1[j] ^ buf2[j];
-
-		crc1 = test_step(INIT1, buf1, i);
-		crc2 = test_step(INIT2, buf2, i);
-		/* Now check that CRC(buf1 ^ buf2) = CRC(buf1) ^ CRC(buf2) */
-		crc3 = test_step(INIT1 ^ INIT2, buf3, i);
-		if (crc3 != (crc1 ^ crc2))
-			printf("CRC XOR fail: 0x%08x != 0x%08x ^ 0x%08x\n",
-			       crc3, crc1, crc2);
+	pr_info("crc32: CRC_LE_BITS = %d, CRC_BE BITS = %d\n",
+		 CRC_LE_BITS, CRC_BE_BITS);
+
+	if (errors)
+		pr_warn("crc32: %d self tests failed\n", errors);
+	else {
+		pr_info("crc32: self tests passed, processed %d bytes in %lld nsec\n",
+			bytes, nsec);
 	}
-	printf("\nAll test complete.  No failures expected.\n");
+
 	return 0;
 }
 
-#endif				/* UNITTEST */
+static int __init crc32test_init(void)
+{
+	crc32_test();
+	crc32c_test();
+	return 0;
+}
+
+static void __exit crc32_exit(void)
+{
+}
+
+module_init(crc32test_init);
+module_exit(crc32_exit);
+#endif /* CONFIG_CRC32_SELFTEST */
diff --git a/lib/crc32defs.h b/lib/crc32defs.h
index 9b6773d..64cba2c 100644
--- a/lib/crc32defs.h
+++ b/lib/crc32defs.h
@@ -6,27 +6,67 @@
 #define CRCPOLY_LE 0xedb88320
 #define CRCPOLY_BE 0x04c11db7
 
-/* How many bits at a time to use.  Requires a table of 4<<CRC_xx_BITS bytes. */
-/* For less performance-sensitive, use 4 */
-#ifndef CRC_LE_BITS 
+/*
+ * This is the CRC32c polynomial, as outlined by Castagnoli.
+ * x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+x^11+x^10+x^9+
+ * x^8+x^6+x^0
+ */
+#define CRC32C_POLY_LE 0x82F63B78
+
+/* Try to choose an implementation variant via Kconfig */
+#ifdef CONFIG_CRC32_SLICEBY8
+# define CRC_LE_BITS 64
+# define CRC_BE_BITS 64
+#endif
+#ifdef CONFIG_CRC32_SLICEBY4
+# define CRC_LE_BITS 32
+# define CRC_BE_BITS 32
+#endif
+#ifdef CONFIG_CRC32_SARWATE
 # define CRC_LE_BITS 8
+# define CRC_BE_BITS 8
+#endif
+#ifdef CONFIG_CRC32_BIT
+# define CRC_LE_BITS 1
+# define CRC_BE_BITS 1
+#endif
+
+/*
+ * How many bits at a time to use.  Valid values are 1, 2, 4, 8, 32 and 64.
+ * For less performance-sensitive, use 4 or 8 to save table size.
+ * For larger systems choose same as CPU architecture as default.
+ * This works well on X86_64, SPARC64 systems. This may require some
+ * elaboration after experiments with other architectures.
+ */
+#ifndef CRC_LE_BITS
+#  ifdef CONFIG_64BIT
+#  define CRC_LE_BITS 64
+#  else
+#  define CRC_LE_BITS 32
+#  endif
 #endif
 #ifndef CRC_BE_BITS
-# define CRC_BE_BITS 8
+#  ifdef CONFIG_64BIT
+#  define CRC_BE_BITS 64
+#  else
+#  define CRC_BE_BITS 32
+#  endif
 #endif
 
 /*
  * Little-endian CRC computation.  Used with serial bit streams sent
  * lsbit-first.  Be sure to use cpu_to_le32() to append the computed CRC.
  */
-#if CRC_LE_BITS > 8 || CRC_LE_BITS < 1 || CRC_LE_BITS & CRC_LE_BITS-1
-# error CRC_LE_BITS must be a power of 2 between 1 and 8
+#if CRC_LE_BITS > 64 || CRC_LE_BITS < 1 || CRC_LE_BITS == 16 || \
+	CRC_LE_BITS & CRC_LE_BITS-1
+# error "CRC_LE_BITS must be one of {1, 2, 4, 8, 32, 64}"
 #endif
 
 /*
  * Big-endian CRC computation.  Used with serial bit streams sent
  * msbit-first.  Be sure to use cpu_to_be32() to append the computed CRC.
  */
-#if CRC_BE_BITS > 8 || CRC_BE_BITS < 1 || CRC_BE_BITS & CRC_BE_BITS-1
-# error CRC_BE_BITS must be a power of 2 between 1 and 8
+#if CRC_BE_BITS > 64 || CRC_BE_BITS < 1 || CRC_BE_BITS == 16 || \
+	CRC_BE_BITS & CRC_BE_BITS-1
+# error "CRC_BE_BITS must be one of {1, 2, 4, 8, 32, 64}"
 #endif
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 77cb245..0ab9ae8 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -818,17 +818,9 @@ static int __init fixup_activate(void *addr, enum debug_obj_state state)
 		if (obj->static_init == 1) {
 			debug_object_init(obj, &descr_type_test);
 			debug_object_activate(obj, &descr_type_test);
-			/*
-			 * Real code should return 0 here ! This is
-			 * not a fixup of some bad behaviour. We
-			 * merily call the debug_init function to keep
-			 * track of the object.
-			 */
-			return 1;
-		} else {
-			/* Real code needs to emit a warning here */
+			return 0;
 		}
-		return 0;
+		return 1;
 
 	case ODEBUG_STATE_ACTIVE:
 		debug_object_deactivate(obj, &descr_type_test);
@@ -967,7 +959,7 @@ static void __init debug_objects_selftest(void)
 
 	obj.static_init = 1;
 	debug_object_activate(&obj, &descr_type_test);
-	if (check_results(&obj, ODEBUG_STATE_ACTIVE, ++fixups, warnings))
+	if (check_results(&obj, ODEBUG_STATE_ACTIVE, fixups, warnings))
 		goto out;
 	debug_object_init(&obj, &descr_type_test);
 	if (check_results(&obj, ODEBUG_STATE_INIT, ++fixups, ++warnings))
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index fea790a..13ef233 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -170,7 +170,7 @@ static bool driver_filter(struct device *dev)
 		return false;
 
 	/* driver filter on but not yet initialized */
-	drv = get_driver(dev->driver);
+	drv = dev->driver;
 	if (!drv)
 		return false;
 
@@ -185,7 +185,6 @@ static bool driver_filter(struct device *dev)
 	}
 
 	read_unlock_irqrestore(&driver_name_lock, flags);
-	put_driver(drv);
 
 	return ret;
 }
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dcdade3..310c753 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -60,6 +60,7 @@ struct ddebug_iter {
 static DEFINE_MUTEX(ddebug_lock);
 static LIST_HEAD(ddebug_tables);
 static int verbose = 0;
+module_param(verbose, int, 0644);
 
 /* Return the last part of a pathname */
 static inline const char *basename(const char *path)
@@ -68,12 +69,24 @@ static inline const char *basename(const char *path)
 	return tail ? tail+1 : path;
 }
 
+/* Return the path relative to source root */
+static inline const char *trim_prefix(const char *path)
+{
+	int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
+
+	if (strncmp(path, __FILE__, skip))
+		skip = 0; /* prefix mismatch, don't skip */
+
+	return path + skip;
+}
+
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
 	{ _DPRINTK_FLAGS_PRINT, 'p' },
 	{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
 	{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
 	{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
 	{ _DPRINTK_FLAGS_INCL_TID, 't' },
+	{ _DPRINTK_FLAGS_NONE, '_' },
 };
 
 /* format a string into buf[] which describes the _ddebug's flags */
@@ -83,58 +96,74 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
 	char *p = buf;
 	int i;
 
-	BUG_ON(maxlen < 4);
+	BUG_ON(maxlen < 6);
 	for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
 		if (dp->flags & opt_array[i].flag)
 			*p++ = opt_array[i].opt_char;
 	if (p == buf)
-		*p++ = '-';
+		*p++ = '_';
 	*p = '\0';
 
 	return buf;
 }
 
+#define vpr_info_dq(q, msg)						\
+do {									\
+	if (verbose)							\
+		/* trim last char off format print */			\
+		pr_info("%s: func=\"%s\" file=\"%s\" "			\
+			"module=\"%s\" format=\"%.*s\" "		\
+			"lineno=%u-%u",					\
+			msg,						\
+			q->function ? q->function : "",			\
+			q->filename ? q->filename : "",			\
+			q->module ? q->module : "",			\
+			(int)(q->format ? strlen(q->format) - 1 : 0),	\
+			q->format ? q->format : "",			\
+			q->first_lineno, q->last_lineno);		\
+} while (0)
+
 /*
- * Search the tables for _ddebug's which match the given
- * `query' and apply the `flags' and `mask' to them.  Tells
- * the user which ddebug's were changed, or whether none
- * were matched.
+ * Search the tables for _ddebug's which match the given `query' and
+ * apply the `flags' and `mask' to them.  Returns number of matching
+ * callsites, normally the same as number of changes.  If verbose,
+ * logs the changes.  Takes ddebug_lock.
  */
-static void ddebug_change(const struct ddebug_query *query,
-			   unsigned int flags, unsigned int mask)
+static int ddebug_change(const struct ddebug_query *query,
+			unsigned int flags, unsigned int mask)
 {
 	int i;
 	struct ddebug_table *dt;
 	unsigned int newflags;
 	unsigned int nfound = 0;
-	char flagbuf[8];
+	char flagbuf[10];
 
 	/* search for matching ddebugs */
 	mutex_lock(&ddebug_lock);
 	list_for_each_entry(dt, &ddebug_tables, link) {
 
 		/* match against the module name */
-		if (query->module != NULL &&
-		    strcmp(query->module, dt->mod_name))
+		if (query->module && strcmp(query->module, dt->mod_name))
 			continue;
 
 		for (i = 0 ; i < dt->num_ddebugs ; i++) {
 			struct _ddebug *dp = &dt->ddebugs[i];
 
 			/* match against the source filename */
-			if (query->filename != NULL &&
+			if (query->filename &&
 			    strcmp(query->filename, dp->filename) &&
-			    strcmp(query->filename, basename(dp->filename)))
+			    strcmp(query->filename, basename(dp->filename)) &&
+			    strcmp(query->filename, trim_prefix(dp->filename)))
 				continue;
 
 			/* match against the function */
-			if (query->function != NULL &&
+			if (query->function &&
 			    strcmp(query->function, dp->function))
 				continue;
 
 			/* match against the format */
-			if (query->format != NULL &&
-			    strstr(dp->format, query->format) == NULL)
+			if (query->format &&
+			    !strstr(dp->format, query->format))
 				continue;
 
 			/* match against the line number range */
@@ -151,13 +180,9 @@ static void ddebug_change(const struct ddebug_query *query,
 			if (newflags == dp->flags)
 				continue;
 			dp->flags = newflags;
-			if (newflags)
-				dp->enabled = 1;
-			else
-				dp->enabled = 0;
 			if (verbose)
-				pr_info("changed %s:%d [%s]%s %s\n",
-					dp->filename, dp->lineno,
+				pr_info("changed %s:%d [%s]%s =%s\n",
+					trim_prefix(dp->filename), dp->lineno,
 					dt->mod_name, dp->function,
 					ddebug_describe_flags(dp, flagbuf,
 							sizeof(flagbuf)));
@@ -167,6 +192,8 @@ static void ddebug_change(const struct ddebug_query *query,
 
 	if (!nfound && verbose)
 		pr_info("no matches for query\n");
+
+	return nfound;
 }
 
 /*
@@ -186,8 +213,10 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
 		buf = skip_spaces(buf);
 		if (!*buf)
 			break;	/* oh, it was trailing whitespace */
+		if (*buf == '#')
+			break;	/* token starts comment, skip rest of line */
 
-		/* Run `end' over a word, either whitespace separated or quoted */
+		/* find `end' of word, whitespace separated or quoted */
 		if (*buf == '"' || *buf == '\'') {
 			int quote = *buf++;
 			for (end = buf ; *end && *end != quote ; end++)
@@ -199,8 +228,8 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
 				;
 			BUG_ON(end == buf);
 		}
-		/* Here `buf' is the start of the word, `end' is one past the end */
 
+		/* `buf' is start of word, `end' is one past its end */
 		if (nwords == maxwords)
 			return -EINVAL;	/* ran out of words[] before bytes */
 		if (*end)
@@ -279,6 +308,19 @@ static char *unescape(char *str)
 	return str;
 }
 
+static int check_set(const char **dest, char *src, char *name)
+{
+	int rc = 0;
+
+	if (*dest) {
+		rc = -EINVAL;
+		pr_err("match-spec:%s val:%s overridden by %s",
+			name, *dest, src);
+	}
+	*dest = src;
+	return rc;
+}
+
 /*
  * Parse words[] as a ddebug query specification, which is a series
  * of (keyword, value) pairs chosen from these possibilities:
@@ -290,11 +332,15 @@ static char *unescape(char *str)
  * format <escaped-string-to-find-in-format>
  * line <lineno>
  * line <first-lineno>-<last-lineno> // where either may be empty
+ *
+ * Only 1 of each type is allowed.
+ * Returns 0 on success, <0 on error.
  */
 static int ddebug_parse_query(char *words[], int nwords,
 			       struct ddebug_query *query)
 {
 	unsigned int i;
+	int rc;
 
 	/* check we have an even number of words */
 	if (nwords % 2 != 0)
@@ -303,41 +349,43 @@ static int ddebug_parse_query(char *words[], int nwords,
 
 	for (i = 0 ; i < nwords ; i += 2) {
 		if (!strcmp(words[i], "func"))
-			query->function = words[i+1];
+			rc = check_set(&query->function, words[i+1], "func");
 		else if (!strcmp(words[i], "file"))
-			query->filename = words[i+1];
+			rc = check_set(&query->filename, words[i+1], "file");
 		else if (!strcmp(words[i], "module"))
-			query->module = words[i+1];
+			rc = check_set(&query->module, words[i+1], "module");
 		else if (!strcmp(words[i], "format"))
-			query->format = unescape(words[i+1]);
+			rc = check_set(&query->format, unescape(words[i+1]),
+				"format");
 		else if (!strcmp(words[i], "line")) {
 			char *first = words[i+1];
 			char *last = strchr(first, '-');
+			if (query->first_lineno || query->last_lineno) {
+				pr_err("match-spec:line given 2 times\n");
+				return -EINVAL;
+			}
 			if (last)
 				*last++ = '\0';
 			if (parse_lineno(first, &query->first_lineno) < 0)
 				return -EINVAL;
-			if (last != NULL) {
+			if (last) {
 				/* range <first>-<last> */
-				if (parse_lineno(last, &query->last_lineno) < 0)
+				if (parse_lineno(last, &query->last_lineno)
+				    < query->first_lineno) {
+					pr_err("last-line < 1st-line\n");
 					return -EINVAL;
+				}
 			} else {
 				query->last_lineno = query->first_lineno;
 			}
 		} else {
-			if (verbose)
-				pr_err("unknown keyword \"%s\"\n", words[i]);
+			pr_err("unknown keyword \"%s\"\n", words[i]);
 			return -EINVAL;
 		}
+		if (rc)
+			return rc;
 	}
-
-	if (verbose)
-		pr_info("q->function=\"%s\" q->filename=\"%s\" "
-			"q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
-			query->function, query->filename,
-			query->module, query->format, query->first_lineno,
-			query->last_lineno);
-
+	vpr_info_dq(query, "parsed");
 	return 0;
 }
 
@@ -375,8 +423,6 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
 		if (i < 0)
 			return -EINVAL;
 	}
-	if (flags == 0)
-		return -EINVAL;
 	if (verbose)
 		pr_info("flags=0x%x\n", flags);
 
@@ -405,7 +451,7 @@ static int ddebug_exec_query(char *query_string)
 	unsigned int flags = 0, mask = 0;
 	struct ddebug_query query;
 #define MAXWORDS 9
-	int nwords;
+	int nwords, nfound;
 	char *words[MAXWORDS];
 
 	nwords = ddebug_tokenize(query_string, words, MAXWORDS);
@@ -417,8 +463,47 @@ static int ddebug_exec_query(char *query_string)
 		return -EINVAL;
 
 	/* actually go and implement the change */
-	ddebug_change(&query, flags, mask);
-	return 0;
+	nfound = ddebug_change(&query, flags, mask);
+	vpr_info_dq((&query), (nfound) ? "applied" : "no-match");
+
+	return nfound;
+}
+
+/* handle multiple queries in query string, continue on error, return
+   last error or number of matching callsites.  Module name is either
+   in param (for boot arg) or perhaps in query string.
+*/
+static int ddebug_exec_queries(char *query)
+{
+	char *split;
+	int i, errs = 0, exitcode = 0, rc, nfound = 0;
+
+	for (i = 0; query; query = split) {
+		split = strpbrk(query, ";\n");
+		if (split)
+			*split++ = '\0';
+
+		query = skip_spaces(query);
+		if (!query || !*query || *query == '#')
+			continue;
+
+		if (verbose)
+			pr_info("query %d: \"%s\"\n", i, query);
+
+		rc = ddebug_exec_query(query);
+		if (rc < 0) {
+			errs++;
+			exitcode = rc;
+		} else
+			nfound += rc;
+		i++;
+	}
+	pr_info("processed %d queries, with %d matches, %d errs\n",
+		 i, nfound, errs);
+
+	if (exitcode)
+		return exitcode;
+	return nfound;
 }
 
 #define PREFIX_SIZE 64
@@ -452,7 +537,8 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
 		pos += snprintf(buf + pos, remaining(pos), "%s:",
 					desc->function);
 	if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
-		pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno);
+		pos += snprintf(buf + pos, remaining(pos), "%d:",
+					desc->lineno);
 	if (pos - pos_after_tid)
 		pos += snprintf(buf + pos, remaining(pos), " ");
 	if (pos >= PREFIX_SIZE)
@@ -527,14 +613,16 @@ EXPORT_SYMBOL(__dynamic_netdev_dbg);
 
 #endif
 
-static __initdata char ddebug_setup_string[1024];
+#define DDEBUG_STRING_SIZE 1024
+static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
+
 static __init int ddebug_setup_query(char *str)
 {
-	if (strlen(str) >= 1024) {
+	if (strlen(str) >= DDEBUG_STRING_SIZE) {
 		pr_warn("ddebug boot param string too large\n");
 		return 0;
 	}
-	strcpy(ddebug_setup_string, str);
+	strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
 	return 1;
 }
 
@@ -544,25 +632,33 @@ __setup("ddebug_query=", ddebug_setup_query);
  * File_ops->write method for <debugfs>/dynamic_debug/conrol.  Gathers the
  * command text from userspace, parses and executes it.
  */
+#define USER_BUF_PAGE 4096
 static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
 				  size_t len, loff_t *offp)
 {
-	char tmpbuf[256];
+	char *tmpbuf;
 	int ret;
 
 	if (len == 0)
 		return 0;
-	/* we don't check *offp -- multiple writes() are allowed */
-	if (len > sizeof(tmpbuf)-1)
+	if (len > USER_BUF_PAGE - 1) {
+		pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
 		return -E2BIG;
-	if (copy_from_user(tmpbuf, ubuf, len))
+	}
+	tmpbuf = kmalloc(len + 1, GFP_KERNEL);
+	if (!tmpbuf)
+		return -ENOMEM;
+	if (copy_from_user(tmpbuf, ubuf, len)) {
+		kfree(tmpbuf);
 		return -EFAULT;
+	}
 	tmpbuf[len] = '\0';
 	if (verbose)
 		pr_info("read %d bytes from userspace\n", (int)len);
 
-	ret = ddebug_exec_query(tmpbuf);
-	if (ret)
+	ret = ddebug_exec_queries(tmpbuf);
+	kfree(tmpbuf);
+	if (ret < 0)
 		return ret;
 
 	*offp += len;
@@ -668,7 +764,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
 {
 	struct ddebug_iter *iter = m->private;
 	struct _ddebug *dp = p;
-	char flagsbuf[8];
+	char flagsbuf[10];
 
 	if (verbose)
 		pr_info("called m=%p p=%p\n", m, p);
@@ -679,10 +775,10 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
 		return 0;
 	}
 
-	seq_printf(m, "%s:%u [%s]%s %s \"",
-		   dp->filename, dp->lineno,
-		   iter->table->mod_name, dp->function,
-		   ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
+	seq_printf(m, "%s:%u [%s]%s =%s \"",
+		trim_prefix(dp->filename), dp->lineno,
+		iter->table->mod_name, dp->function,
+		ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
 	seq_escape(m, dp->format, "\t\r\n\"");
 	seq_puts(m, "\"\n");
 
@@ -708,10 +804,11 @@ static const struct seq_operations ddebug_proc_seqops = {
 };
 
 /*
- * File_ops->open method for <debugfs>/dynamic_debug/control.  Does the seq_file
- * setup dance, and also creates an iterator to walk the _ddebugs.
- * Note that we create a seq_file always, even for O_WRONLY files
- * where it's not needed, as doing so simplifies the ->release method.
+ * File_ops->open method for <debugfs>/dynamic_debug/control.  Does
+ * the seq_file setup dance, and also creates an iterator to walk the
+ * _ddebugs.  Note that we create a seq_file always, even for O_WRONLY
+ * files where it's not needed, as doing so simplifies the ->release
+ * method.
  */
 static int ddebug_proc_open(struct inode *inode, struct file *file)
 {
@@ -846,33 +943,40 @@ static int __init dynamic_debug_init(void)
 	int ret = 0;
 	int n = 0;
 
-	if (__start___verbose != __stop___verbose) {
-		iter = __start___verbose;
-		modname = iter->modname;
-		iter_start = iter;
-		for (; iter < __stop___verbose; iter++) {
-			if (strcmp(modname, iter->modname)) {
-				ret = ddebug_add_module(iter_start, n, modname);
-				if (ret)
-					goto out_free;
-				n = 0;
-				modname = iter->modname;
-				iter_start = iter;
-			}
-			n++;
+	if (__start___verbose == __stop___verbose) {
+		pr_warn("_ddebug table is empty in a "
+			"CONFIG_DYNAMIC_DEBUG build");
+		return 1;
+	}
+	iter = __start___verbose;
+	modname = iter->modname;
+	iter_start = iter;
+	for (; iter < __stop___verbose; iter++) {
+		if (strcmp(modname, iter->modname)) {
+			ret = ddebug_add_module(iter_start, n, modname);
+			if (ret)
+				goto out_free;
+			n = 0;
+			modname = iter->modname;
+			iter_start = iter;
 		}
-		ret = ddebug_add_module(iter_start, n, modname);
+		n++;
 	}
+	ret = ddebug_add_module(iter_start, n, modname);
+	if (ret)
+		goto out_free;
 
 	/* ddebug_query boot param got passed -> set it up */
 	if (ddebug_setup_string[0] != '\0') {
-		ret = ddebug_exec_query(ddebug_setup_string);
-		if (ret)
+		ret = ddebug_exec_queries(ddebug_setup_string);
+		if (ret < 0)
 			pr_warn("Invalid ddebug boot param %s",
 				ddebug_setup_string);
 		else
-			pr_info("ddebug initialized with string %s",
-				ddebug_setup_string);
+			pr_info("%d changes by ddebug_query\n", ret);
+
+		/* keep tables even on ddebug_query parse error */
+		ret = 0;
 	}
 
 out_free:
diff --git a/lib/gen_crc32table.c b/lib/gen_crc32table.c
index 85d0e41..8f8d543 100644
--- a/lib/gen_crc32table.c
+++ b/lib/gen_crc32table.c
@@ -1,14 +1,29 @@
 #include <stdio.h>
+#include "../include/generated/autoconf.h"
 #include "crc32defs.h"
 #include <inttypes.h>
 
 #define ENTRIES_PER_LINE 4
 
-#define LE_TABLE_SIZE (1 << CRC_LE_BITS)
-#define BE_TABLE_SIZE (1 << CRC_BE_BITS)
+#if CRC_LE_BITS > 8
+# define LE_TABLE_ROWS (CRC_LE_BITS/8)
+# define LE_TABLE_SIZE 256
+#else
+# define LE_TABLE_ROWS 1
+# define LE_TABLE_SIZE (1 << CRC_LE_BITS)
+#endif
 
-static uint32_t crc32table_le[4][LE_TABLE_SIZE];
-static uint32_t crc32table_be[4][BE_TABLE_SIZE];
+#if CRC_BE_BITS > 8
+# define BE_TABLE_ROWS (CRC_BE_BITS/8)
+# define BE_TABLE_SIZE 256
+#else
+# define BE_TABLE_ROWS 1
+# define BE_TABLE_SIZE (1 << CRC_BE_BITS)
+#endif
+
+static uint32_t crc32table_le[LE_TABLE_ROWS][256];
+static uint32_t crc32table_be[BE_TABLE_ROWS][256];
+static uint32_t crc32ctable_le[LE_TABLE_ROWS][256];
 
 /**
  * crc32init_le() - allocate and initialize LE table data
@@ -17,27 +32,38 @@ static uint32_t crc32table_be[4][BE_TABLE_SIZE];
  * fact that crctable[i^j] = crctable[i] ^ crctable[j].
  *
  */
-static void crc32init_le(void)
+static void crc32init_le_generic(const uint32_t polynomial,
+				 uint32_t (*tab)[256])
 {
 	unsigned i, j;
 	uint32_t crc = 1;
 
-	crc32table_le[0][0] = 0;
+	tab[0][0] = 0;
 
-	for (i = 1 << (CRC_LE_BITS - 1); i; i >>= 1) {
-		crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_LE : 0);
+	for (i = LE_TABLE_SIZE >> 1; i; i >>= 1) {
+		crc = (crc >> 1) ^ ((crc & 1) ? polynomial : 0);
 		for (j = 0; j < LE_TABLE_SIZE; j += 2 * i)
-			crc32table_le[0][i + j] = crc ^ crc32table_le[0][j];
+			tab[0][i + j] = crc ^ tab[0][j];
 	}
 	for (i = 0; i < LE_TABLE_SIZE; i++) {
-		crc = crc32table_le[0][i];
-		for (j = 1; j < 4; j++) {
-			crc = crc32table_le[0][crc & 0xff] ^ (crc >> 8);
-			crc32table_le[j][i] = crc;
+		crc = tab[0][i];
+		for (j = 1; j < LE_TABLE_ROWS; j++) {
+			crc = tab[0][crc & 0xff] ^ (crc >> 8);
+			tab[j][i] = crc;
 		}
 	}
 }
 
+static void crc32init_le(void)
+{
+	crc32init_le_generic(CRCPOLY_LE, crc32table_le);
+}
+
+static void crc32cinit_le(void)
+{
+	crc32init_le_generic(CRC32C_POLY_LE, crc32ctable_le);
+}
+
 /**
  * crc32init_be() - allocate and initialize BE table data
  */
@@ -55,18 +81,18 @@ static void crc32init_be(void)
 	}
 	for (i = 0; i < BE_TABLE_SIZE; i++) {
 		crc = crc32table_be[0][i];
-		for (j = 1; j < 4; j++) {
+		for (j = 1; j < BE_TABLE_ROWS; j++) {
 			crc = crc32table_be[0][(crc >> 24) & 0xff] ^ (crc << 8);
 			crc32table_be[j][i] = crc;
 		}
 	}
 }
 
-static void output_table(uint32_t table[4][256], int len, char *trans)
+static void output_table(uint32_t (*table)[256], int rows, int len, char *trans)
 {
 	int i, j;
 
-	for (j = 0 ; j < 4; j++) {
+	for (j = 0 ; j < rows; j++) {
 		printf("{");
 		for (i = 0; i < len - 1; i++) {
 			if (i % ENTRIES_PER_LINE == 0)
@@ -83,15 +109,30 @@ int main(int argc, char** argv)
 
 	if (CRC_LE_BITS > 1) {
 		crc32init_le();
-		printf("static const u32 crc32table_le[4][256] = {");
-		output_table(crc32table_le, LE_TABLE_SIZE, "tole");
+		printf("static const u32 __cacheline_aligned "
+		       "crc32table_le[%d][%d] = {",
+		       LE_TABLE_ROWS, LE_TABLE_SIZE);
+		output_table(crc32table_le, LE_TABLE_ROWS,
+			     LE_TABLE_SIZE, "tole");
 		printf("};\n");
 	}
 
 	if (CRC_BE_BITS > 1) {
 		crc32init_be();
-		printf("static const u32 crc32table_be[4][256] = {");
-		output_table(crc32table_be, BE_TABLE_SIZE, "tobe");
+		printf("static const u32 __cacheline_aligned "
+		       "crc32table_be[%d][%d] = {",
+		       BE_TABLE_ROWS, BE_TABLE_SIZE);
+		output_table(crc32table_be, LE_TABLE_ROWS,
+			     BE_TABLE_SIZE, "tobe");
+		printf("};\n");
+	}
+	if (CRC_LE_BITS > 1) {
+		crc32cinit_le();
+		printf("static const u32 __cacheline_aligned "
+		       "crc32ctable_le[%d][%d] = {",
+		       LE_TABLE_ROWS, LE_TABLE_SIZE);
+		output_table(crc32ctable_le, LE_TABLE_ROWS,
+			     LE_TABLE_SIZE, "tole");
 		printf("};\n");
 	}
 
diff --git a/lib/idr.c b/lib/idr.c
index ed055b2..12499ba 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -595,8 +595,10 @@ EXPORT_SYMBOL(idr_for_each);
  * Returns pointer to registered object with id, which is next number to
  * given id. After being looked up, *@nextidp will be updated for the next
  * iteration.
+ *
+ * This function can be called under rcu_read_lock(), given that the leaf
+ * pointers lifetimes are correctly managed.
  */
-
 void *idr_get_next(struct idr *idp, int *nextidp)
 {
 	struct idr_layer *p, *pa[MAX_LEVEL];
@@ -605,11 +607,11 @@ void *idr_get_next(struct idr *idp, int *nextidp)
 	int n, max;
 
 	/* find first ent */
-	n = idp->layers * IDR_BITS;
-	max = 1 << n;
 	p = rcu_dereference_raw(idp->top);
 	if (!p)
 		return NULL;
+	n = (p->layer + 1) * IDR_BITS;
+	max = 1 << n;
 
 	while (id < max) {
 		while (n > 0 && p) {
diff --git a/lib/prio_tree.c b/lib/prio_tree.c
index ccfd850..8d443af 100644
--- a/lib/prio_tree.c
+++ b/lib/prio_tree.c
@@ -85,6 +85,17 @@ static inline unsigned long prio_tree_maxindex(unsigned int bits)
 	return index_bits_to_maxindex[bits - 1];
 }
 
+static void prio_set_parent(struct prio_tree_node *parent,
+			    struct prio_tree_node *child, bool left)
+{
+	if (left)
+		parent->left = child;
+	else
+		parent->right = child;
+
+	child->parent = parent;
+}
+
 /*
  * Extend a priority search tree so that it can store a node with heap_index
  * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
@@ -94,45 +105,32 @@ static inline unsigned long prio_tree_maxindex(unsigned int bits)
 static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
 		struct prio_tree_node *node, unsigned long max_heap_index)
 {
-	struct prio_tree_node *first = NULL, *prev, *last = NULL;
+	struct prio_tree_node *prev;
 
 	if (max_heap_index > prio_tree_maxindex(root->index_bits))
 		root->index_bits++;
 
+	prev = node;
+	INIT_PRIO_TREE_NODE(node);
+
 	while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
+		struct prio_tree_node *tmp = root->prio_tree_node;
+
 		root->index_bits++;
 
 		if (prio_tree_empty(root))
 			continue;
 
-		if (first == NULL) {
-			first = root->prio_tree_node;
-			prio_tree_remove(root, root->prio_tree_node);
-			INIT_PRIO_TREE_NODE(first);
-			last = first;
-		} else {
-			prev = last;
-			last = root->prio_tree_node;
-			prio_tree_remove(root, root->prio_tree_node);
-			INIT_PRIO_TREE_NODE(last);
-			prev->left = last;
-			last->parent = prev;
-		}
-	}
-
-	INIT_PRIO_TREE_NODE(node);
-
-	if (first) {
-		node->left = first;
-		first->parent = node;
-	} else
-		last = node;
+		prio_tree_remove(root, root->prio_tree_node);
+		INIT_PRIO_TREE_NODE(tmp);
 
-	if (!prio_tree_empty(root)) {
-		last->left = root->prio_tree_node;
-		last->left->parent = last;
+		prio_set_parent(prev, tmp, true);
+		prev = tmp;
 	}
 
+	if (!prio_tree_empty(root))
+		prio_set_parent(prev, root->prio_tree_node, true);
+
 	root->prio_tree_node = node;
 	return node;
 }
@@ -151,25 +149,15 @@ struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
 		 * We can reduce root->index_bits here. However, it is complex
 		 * and does not help much to improve performance (IMO).
 		 */
-		node->parent = node;
 		root->prio_tree_node = node;
-	} else {
-		node->parent = old->parent;
-		if (old->parent->left == old)
-			old->parent->left = node;
-		else
-			old->parent->right = node;
-	}
+	} else
+		prio_set_parent(old->parent, node, old->parent->left == old);
 
-	if (!prio_tree_left_empty(old)) {
-		node->left = old->left;
-		old->left->parent = node;
-	}
+	if (!prio_tree_left_empty(old))
+		prio_set_parent(node, old->left, true);
 
-	if (!prio_tree_right_empty(old)) {
-		node->right = old->right;
-		old->right->parent = node;
-	}
+	if (!prio_tree_right_empty(old))
+		prio_set_parent(node, old->right, false);
 
 	return old;
 }
@@ -229,16 +217,14 @@ struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
 		if (index & mask) {
 			if (prio_tree_right_empty(cur)) {
 				INIT_PRIO_TREE_NODE(node);
-				cur->right = node;
-				node->parent = cur;
+				prio_set_parent(cur, node, false);
 				return res;
 			} else
 				cur = cur->right;
 		} else {
 			if (prio_tree_left_empty(cur)) {
 				INIT_PRIO_TREE_NODE(node);
-				cur->left = node;
-				node->parent = cur;
+				prio_set_parent(cur, node, true);
 				return res;
 			} else
 				cur = cur->left;
@@ -305,6 +291,40 @@ void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
 		cur = prio_tree_replace(root, cur->parent, cur);
 }
 
+static void iter_walk_down(struct prio_tree_iter *iter)
+{
+	iter->mask >>= 1;
+	if (iter->mask) {
+		if (iter->size_level)
+			iter->size_level++;
+		return;
+	}
+
+	if (iter->size_level) {
+		BUG_ON(!prio_tree_left_empty(iter->cur));
+		BUG_ON(!prio_tree_right_empty(iter->cur));
+		iter->size_level++;
+		iter->mask = ULONG_MAX;
+	} else {
+		iter->size_level = 1;
+		iter->mask = 1UL << (BITS_PER_LONG - 1);
+	}
+}
+
+static void iter_walk_up(struct prio_tree_iter *iter)
+{
+	if (iter->mask == ULONG_MAX)
+		iter->mask = 1UL;
+	else if (iter->size_level == 1)
+		iter->mask = 1UL;
+	else
+		iter->mask <<= 1;
+	if (iter->size_level)
+		iter->size_level--;
+	if (!iter->size_level && (iter->value & iter->mask))
+		iter->value ^= iter->mask;
+}
+
 /*
  * Following functions help to enumerate all prio_tree_nodes in the tree that
  * overlap with the input interval X [radix_index, heap_index]. The enumeration
@@ -323,21 +343,7 @@ static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
 
 	if (iter->r_index <= *h_index) {
 		iter->cur = iter->cur->left;
-		iter->mask >>= 1;
-		if (iter->mask) {
-			if (iter->size_level)
-				iter->size_level++;
-		} else {
-			if (iter->size_level) {
-				BUG_ON(!prio_tree_left_empty(iter->cur));
-				BUG_ON(!prio_tree_right_empty(iter->cur));
-				iter->size_level++;
-				iter->mask = ULONG_MAX;
-			} else {
-				iter->size_level = 1;
-				iter->mask = 1UL << (BITS_PER_LONG - 1);
-			}
-		}
+		iter_walk_down(iter);
 		return iter->cur;
 	}
 
@@ -364,22 +370,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
 
 	if (iter->r_index <= *h_index) {
 		iter->cur = iter->cur->right;
-		iter->mask >>= 1;
-		iter->value = value;
-		if (iter->mask) {
-			if (iter->size_level)
-				iter->size_level++;
-		} else {
-			if (iter->size_level) {
-				BUG_ON(!prio_tree_left_empty(iter->cur));
-				BUG_ON(!prio_tree_right_empty(iter->cur));
-				iter->size_level++;
-				iter->mask = ULONG_MAX;
-			} else {
-				iter->size_level = 1;
-				iter->mask = 1UL << (BITS_PER_LONG - 1);
-			}
-		}
+		iter_walk_down(iter);
 		return iter->cur;
 	}
 
@@ -389,16 +380,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
 static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
 {
 	iter->cur = iter->cur->parent;
-	if (iter->mask == ULONG_MAX)
-		iter->mask = 1UL;
-	else if (iter->size_level == 1)
-		iter->mask = 1UL;
-	else
-		iter->mask <<= 1;
-	if (iter->size_level)
-		iter->size_level--;
-	if (!iter->size_level && (iter->value & iter->mask))
-		iter->value ^= iter->mask;
+	iter_walk_up(iter);
 	return iter->cur;
 }
 
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 4ceb05d..33b2cbb 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -390,7 +390,7 @@ bool sg_miter_next(struct sg_mapping_iter *miter)
 	miter->consumed = miter->length;
 
 	if (miter->__flags & SG_MITER_ATOMIC)
-		miter->addr = kmap_atomic(miter->page, KM_BIO_SRC_IRQ) + off;
+		miter->addr = kmap_atomic(miter->page) + off;
 	else
 		miter->addr = kmap(miter->page) + off;
 
@@ -424,7 +424,7 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
 
 		if (miter->__flags & SG_MITER_ATOMIC) {
 			WARN_ON(!irqs_disabled());
-			kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ);
+			kunmap_atomic(miter->addr);
 		} else
 			kunmap(miter->page);
 
diff --git a/lib/string.c b/lib/string.c
index dc4a863..3a03782 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -785,12 +785,24 @@ void *memchr_inv(const void *start, int c, size_t bytes)
 	if (bytes <= 16)
 		return check_bytes8(start, value, bytes);
 
-	value64 = value | value << 8 | value << 16 | value << 24;
-	value64 = (value64 & 0xffffffff) | value64 << 32;
-	prefix = 8 - ((unsigned long)start) % 8;
+	value64 = value;
+#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
+	value64 *= 0x0101010101010101;
+#elif defined(ARCH_HAS_FAST_MULTIPLIER)
+	value64 *= 0x01010101;
+	value64 |= value64 << 32;
+#else
+	value64 |= value64 << 8;
+	value64 |= value64 << 16;
+	value64 |= value64 << 32;
+#endif
 
+	prefix = (unsigned long)start % 8;
 	if (prefix) {
-		u8 *r = check_bytes8(start, value, prefix);
+		u8 *r;
+
+		prefix = 8 - prefix;
+		r = check_bytes8(start, value, prefix);
 		if (r)
 			return r;
 		start += prefix;
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 058935e..0c2dece 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -349,13 +349,12 @@ void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size,
 			sz = min_t(size_t, PAGE_SIZE - offset, size);
 
 			local_irq_save(flags);
-			buffer = kmap_atomic(pfn_to_page(pfn),
-					     KM_BOUNCE_READ);
+			buffer = kmap_atomic(pfn_to_page(pfn));
 			if (dir == DMA_TO_DEVICE)
 				memcpy(dma_addr, buffer + offset, sz);
 			else
 				memcpy(buffer + offset, dma_addr, sz);
-			kunmap_atomic(buffer, KM_BOUNCE_READ);
+			kunmap_atomic(buffer);
 			local_irq_restore(flags);
 
 			size -= sz;
@@ -566,7 +565,8 @@ EXPORT_SYMBOL_GPL(swiotlb_tbl_sync_single);
 
 void *
 swiotlb_alloc_coherent(struct device *hwdev, size_t size,
-		       dma_addr_t *dma_handle, gfp_t flags)
+		       dma_addr_t *dma_handle, gfp_t flags,
+		       struct dma_attrs *attrs)
 {
 	dma_addr_t dev_addr;
 	void *ret;
@@ -615,7 +615,7 @@ EXPORT_SYMBOL(swiotlb_alloc_coherent);
 
 void
 swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
-		      dma_addr_t dev_addr)
+		      dma_addr_t dev_addr, struct dma_attrs *attrs)
 {
 	phys_addr_t paddr = dma_to_phys(hwdev, dev_addr);
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 8e75003..30026ad 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -212,6 +212,26 @@ char *put_dec(char *buf, unsigned long long num)
 	}
 }
 
+/*
+ * Convert passed number to decimal string.
+ * Returns the length of string.  On buffer overflow, returns 0.
+ *
+ * If speed is not important, use snprintf(). It's easy to read the code.
+ */
+int num_to_str(char *buf, int size, unsigned long long num)
+{
+	char tmp[21];		/* Enough for 2^64 in decimal */
+	int idx, len;
+
+	len = put_dec(tmp, num) - tmp;
+
+	if (len > size)
+		return 0;
+	for (idx = 0; idx < len; ++idx)
+		buf[idx] = tmp[len - idx - 1];
+	return  len;
+}
+
 #define ZEROPAD	1		/* pad with zero */
 #define SIGN	2		/* unsigned/signed long */
 #define PLUS	4		/* show plus */
diff --git a/localversion-next b/localversion-next
new file mode 100644
index 0000000..d2158f8
--- /dev/null
+++ b/localversion-next
@@ -0,0 +1 @@
+-next-20120222
diff --git a/mm/Kconfig b/mm/Kconfig
index e338407..2613c91 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -379,3 +379,20 @@ config CLEANCACHE
 	  in a negligible performance hit.
 
 	  If unsure, say Y to enable cleancache
+
+config FRONTSWAP
+	bool "Enable frontswap to cache swap pages if tmem is present"
+	depends on SWAP
+	default n
+	help
+	  Frontswap is so named because it can be thought of as the opposite
+	  of a "backing" store for a swap device.  The data is stored into
+	  "transcendent memory", memory that is not directly accessible or
+	  addressable by the kernel and is of unknown and possibly
+	  time-varying size.  When space in transcendent memory is available,
+	  a significant swap I/O reduction may be achieved.  When none is
+	  available, all frontswap calls are reduced to a single pointer-
+	  compare-against-NULL resulting in a negligible performance hit
+	  and swap data is stored as normal on the matching swap device.
+
+	  If unsure, say Y to enable frontswap.
diff --git a/mm/Makefile b/mm/Makefile
index 50ec00e..306742a 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o
 
 obj-$(CONFIG_BOUNCE)	+= bounce.o
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
+obj-$(CONFIG_FRONTSWAP)	+= frontswap.o
 obj-$(CONFIG_HAS_DMA)	+= dmapool.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
 obj-$(CONFIG_NUMA) 	+= mempolicy.o
diff --git a/mm/bounce.c b/mm/bounce.c
index 4e9ae72..d1be02c 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -50,9 +50,9 @@ static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom)
 	unsigned char *vto;
 
 	local_irq_save(flags);
-	vto = kmap_atomic(to->bv_page, KM_BOUNCE_READ);
+	vto = kmap_atomic(to->bv_page);
 	memcpy(vto + to->bv_offset, vfrom, to->bv_len);
-	kunmap_atomic(vto, KM_BOUNCE_READ);
+	kunmap_atomic(vto);
 	local_irq_restore(flags);
 }
 
diff --git a/mm/cleancache.c b/mm/cleancache.c
index bcaae4c..5646c74 100644
--- a/mm/cleancache.c
+++ b/mm/cleancache.c
@@ -15,29 +15,34 @@
 #include <linux/fs.h>
 #include <linux/exportfs.h>
 #include <linux/mm.h>
+#include <linux/debugfs.h>
 #include <linux/cleancache.h>
 
 /*
  * This global enablement flag may be read thousands of times per second
- * by cleancache_get/put/flush even on systems where cleancache_ops
+ * by cleancache_get/put/invalidate even on systems where cleancache_ops
  * is not claimed (e.g. cleancache is config'ed on but remains
  * disabled), so is preferred to the slower alternative: a function
  * call that checks a non-global.
  */
-int cleancache_enabled;
+int cleancache_enabled __read_mostly;
 EXPORT_SYMBOL(cleancache_enabled);
 
 /*
  * cleancache_ops is set by cleancache_ops_register to contain the pointers
  * to the cleancache "backend" implementation functions.
  */
-static struct cleancache_ops cleancache_ops;
+static struct cleancache_ops cleancache_ops __read_mostly;
 
-/* useful stats available in /sys/kernel/mm/cleancache */
-static unsigned long cleancache_succ_gets;
-static unsigned long cleancache_failed_gets;
-static unsigned long cleancache_puts;
-static unsigned long cleancache_flushes;
+/*
+ * Counters available via /sys/kernel/debug/frontswap (if debugfs is
+ * properly configured.  These are for information only so are not protected
+ * against increment races.
+ */
+static u64 cleancache_succ_gets;
+static u64 cleancache_failed_gets;
+static u64 cleancache_puts;
+static u64 cleancache_invalidates;
 
 /*
  * register operations for cleancache, returning previous thus allowing
@@ -148,10 +153,11 @@ void __cleancache_put_page(struct page *page)
 EXPORT_SYMBOL(__cleancache_put_page);
 
 /*
- * Flush any data from cleancache associated with the poolid and the
+ * Invalidate any data from cleancache associated with the poolid and the
  * page's inode and page index so that a subsequent "get" will fail.
  */
-void __cleancache_flush_page(struct address_space *mapping, struct page *page)
+void __cleancache_invalidate_page(struct address_space *mapping,
+					struct page *page)
 {
 	/* careful... page->mapping is NULL sometimes when this is called */
 	int pool_id = mapping->host->i_sb->cleancache_poolid;
@@ -160,85 +166,57 @@ void __cleancache_flush_page(struct address_space *mapping, struct page *page)
 	if (pool_id >= 0) {
 		VM_BUG_ON(!PageLocked(page));
 		if (cleancache_get_key(mapping->host, &key) >= 0) {
-			(*cleancache_ops.flush_page)(pool_id, key, page->index);
-			cleancache_flushes++;
+			(*cleancache_ops.invalidate_page)(pool_id,
+							  key, page->index);
+			cleancache_invalidates++;
 		}
 	}
 }
-EXPORT_SYMBOL(__cleancache_flush_page);
+EXPORT_SYMBOL(__cleancache_invalidate_page);
 
 /*
- * Flush all data from cleancache associated with the poolid and the
+ * Invalidate all data from cleancache associated with the poolid and the
  * mappings's inode so that all subsequent gets to this poolid/inode
  * will fail.
  */
-void __cleancache_flush_inode(struct address_space *mapping)
+void __cleancache_invalidate_inode(struct address_space *mapping)
 {
 	int pool_id = mapping->host->i_sb->cleancache_poolid;
 	struct cleancache_filekey key = { .u.key = { 0 } };
 
 	if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0)
-		(*cleancache_ops.flush_inode)(pool_id, key);
+		(*cleancache_ops.invalidate_inode)(pool_id, key);
 }
-EXPORT_SYMBOL(__cleancache_flush_inode);
+EXPORT_SYMBOL(__cleancache_invalidate_inode);
 
 /*
  * Called by any cleancache-enabled filesystem at time of unmount;
  * note that pool_id is surrendered and may be reutrned by a subsequent
  * cleancache_init_fs or cleancache_init_shared_fs
  */
-void __cleancache_flush_fs(struct super_block *sb)
+void __cleancache_invalidate_fs(struct super_block *sb)
 {
 	if (sb->cleancache_poolid >= 0) {
 		int old_poolid = sb->cleancache_poolid;
 		sb->cleancache_poolid = -1;
-		(*cleancache_ops.flush_fs)(old_poolid);
+		(*cleancache_ops.invalidate_fs)(old_poolid);
 	}
 }
-EXPORT_SYMBOL(__cleancache_flush_fs);
-
-#ifdef CONFIG_SYSFS
-
-/* see Documentation/ABI/xxx/sysfs-kernel-mm-cleancache */
-
-#define CLEANCACHE_SYSFS_RO(_name) \
-	static ssize_t cleancache_##_name##_show(struct kobject *kobj, \
-				struct kobj_attribute *attr, char *buf) \
-	{ \
-		return sprintf(buf, "%lu\n", cleancache_##_name); \
-	} \
-	static struct kobj_attribute cleancache_##_name##_attr = { \
-		.attr = { .name = __stringify(_name), .mode = 0444 }, \
-		.show = cleancache_##_name##_show, \
-	}
-
-CLEANCACHE_SYSFS_RO(succ_gets);
-CLEANCACHE_SYSFS_RO(failed_gets);
-CLEANCACHE_SYSFS_RO(puts);
-CLEANCACHE_SYSFS_RO(flushes);
-
-static struct attribute *cleancache_attrs[] = {
-	&cleancache_succ_gets_attr.attr,
-	&cleancache_failed_gets_attr.attr,
-	&cleancache_puts_attr.attr,
-	&cleancache_flushes_attr.attr,
-	NULL,
-};
-
-static struct attribute_group cleancache_attr_group = {
-	.attrs = cleancache_attrs,
-	.name = "cleancache",
-};
-
-#endif /* CONFIG_SYSFS */
+EXPORT_SYMBOL(__cleancache_invalidate_fs);
 
 static int __init init_cleancache(void)
 {
-#ifdef CONFIG_SYSFS
-	int err;
-
-	err = sysfs_create_group(mm_kobj, &cleancache_attr_group);
-#endif /* CONFIG_SYSFS */
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *root = debugfs_create_dir("cleancache", NULL);
+	if (root == NULL)
+		return -ENXIO;
+	debugfs_create_u64("succ_gets", S_IRUGO, root, &cleancache_succ_gets);
+	debugfs_create_u64("failed_gets", S_IRUGO,
+				root, &cleancache_failed_gets);
+	debugfs_create_u64("puts", S_IRUGO, root, &cleancache_puts);
+	debugfs_create_u64("invalidates", S_IRUGO,
+				root, &cleancache_invalidates);
+#endif
 	return 0;
 }
 module_init(init_cleancache)
diff --git a/mm/compaction.c b/mm/compaction.c
index d9ebebe..74a8c82 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -35,7 +35,7 @@ struct compact_control {
 	unsigned long migrate_pfn;	/* isolate_migratepages search base */
 	bool sync;			/* Synchronous migration */
 
-	unsigned int order;		/* order a direct compactor needs */
+	int order;			/* order a direct compactor needs */
 	int migratetype;		/* MOVABLE, RECLAIMABLE etc */
 	struct zone *zone;
 };
@@ -675,49 +675,71 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist,
 
 
 /* Compact all zones within a node */
-static int compact_node(int nid)
+static int __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc)
 {
 	int zoneid;
-	pg_data_t *pgdat;
 	struct zone *zone;
 
-	if (nid < 0 || nid >= nr_node_ids || !node_online(nid))
-		return -EINVAL;
-	pgdat = NODE_DATA(nid);
-
-	/* Flush pending updates to the LRU lists */
-	lru_add_drain_all();
-
 	for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
-		struct compact_control cc = {
-			.nr_freepages = 0,
-			.nr_migratepages = 0,
-			.order = -1,
-			.sync = true,
-		};
 
 		zone = &pgdat->node_zones[zoneid];
 		if (!populated_zone(zone))
 			continue;
 
-		cc.zone = zone;
-		INIT_LIST_HEAD(&cc.freepages);
-		INIT_LIST_HEAD(&cc.migratepages);
-
-		compact_zone(zone, &cc);
+		cc->nr_freepages = 0;
+		cc->nr_migratepages = 0;
+		cc->zone = zone;
+		INIT_LIST_HEAD(&cc->freepages);
+		INIT_LIST_HEAD(&cc->migratepages);
+
+		if (cc->order == -1 || !compaction_deferred(zone, cc->order))
+			compact_zone(zone, cc);
+
+		if (cc->order > 0) {
+			int ok = zone_watermark_ok(zone, cc->order,
+						low_wmark_pages(zone), 0, 0);
+			if (ok && cc->order > zone->compact_order_failed)
+				zone->compact_order_failed = cc->order + 1;
+			/* Currently async compaction is never deferred. */
+			else if (!ok && cc->sync)
+				defer_compaction(zone, cc->order);
+		}
 
-		VM_BUG_ON(!list_empty(&cc.freepages));
-		VM_BUG_ON(!list_empty(&cc.migratepages));
+		VM_BUG_ON(!list_empty(&cc->freepages));
+		VM_BUG_ON(!list_empty(&cc->migratepages));
 	}
 
 	return 0;
 }
 
+int compact_pgdat(pg_data_t *pgdat, int order)
+{
+	struct compact_control cc = {
+		.order = order,
+		.sync = false,
+	};
+
+	return __compact_pgdat(pgdat, &cc);
+}
+
+static int compact_node(int nid)
+{
+	struct compact_control cc = {
+		.order = -1,
+		.sync = true,
+	};
+
+	return __compact_pgdat(NODE_DATA(nid), &cc);
+}
+
 /* Compact all nodes in the system */
 static int compact_nodes(void)
 {
 	int nid;
 
+	/* Flush pending updates to the LRU lists */
+	lru_add_drain_all();
+
 	for_each_online_node(nid)
 		compact_node(nid);
 
@@ -750,7 +772,14 @@ ssize_t sysfs_compact_node(struct device *dev,
 			struct device_attribute *attr,
 			const char *buf, size_t count)
 {
-	compact_node(dev->id);
+	int nid = dev->id;
+
+	if (nid >= 0 && nid < nr_node_ids && node_online(nid)) {
+		/* Flush pending updates to the LRU lists */
+		lru_add_drain_all();
+
+		compact_node(nid);
+	}
 
 	return count;
 }
diff --git a/mm/filemap.c b/mm/filemap.c
index b662757..20fe2f7 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -123,7 +123,7 @@ void __delete_from_page_cache(struct page *page)
 	if (PageUptodate(page) && PageMappedToDisk(page))
 		cleancache_put_page(page);
 	else
-		cleancache_flush_page(mapping, page);
+		cleancache_invalidate_page(mapping, page);
 
 	radix_tree_delete(&mapping->page_tree, page->index);
 	page->mapping = NULL;
@@ -1318,10 +1318,10 @@ int file_read_actor(read_descriptor_t *desc, struct page *page,
 	 * taking the kmap.
 	 */
 	if (!fault_in_pages_writeable(desc->arg.buf, size)) {
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		left = __copy_to_user_inatomic(desc->arg.buf,
 						kaddr + offset, size);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		if (left == 0)
 			goto success;
 	}
@@ -2045,7 +2045,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
 	size_t copied;
 
 	BUG_ON(!in_atomic());
-	kaddr = kmap_atomic(page, KM_USER0);
+	kaddr = kmap_atomic(page);
 	if (likely(i->nr_segs == 1)) {
 		int left;
 		char __user *buf = i->iov->iov_base + i->iov_offset;
@@ -2055,7 +2055,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
 		copied = __iovec_copy_from_user_inatomic(kaddr + offset,
 						i->iov, i->iov_offset, bytes);
 	}
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 
 	return copied;
 }
diff --git a/mm/frontswap.c b/mm/frontswap.c
new file mode 100644
index 0000000..2b80c5a
--- /dev/null
+++ b/mm/frontswap.c
@@ -0,0 +1,273 @@
+/*
+ * Frontswap frontend
+ *
+ * This code provides the generic "frontend" layer to call a matching
+ * "backend" driver implementation of frontswap.  See
+ * Documentation/vm/frontswap.txt for more information.
+ *
+ * Copyright (C) 2009-2010 Oracle Corp.  All rights reserved.
+ * Author: Dan Magenheimer
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/proc_fs.h>
+#include <linux/security.h>
+#include <linux/capability.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/frontswap.h>
+#include <linux/swapfile.h>
+
+/*
+ * frontswap_ops is set by frontswap_register_ops to contain the pointers
+ * to the frontswap "backend" implementation functions.
+ */
+static struct frontswap_ops frontswap_ops __read_mostly;
+
+/*
+ * This global enablement flag reduces overhead on systems where frontswap_ops
+ * has not been registered, so is preferred to the slower alternative: a
+ * function call that checks a non-global.
+ */
+int frontswap_enabled __read_mostly;
+EXPORT_SYMBOL(frontswap_enabled);
+
+/*
+ * Counters available via /sys/kernel/debug/frontswap (if debugfs is
+ * properly configured.  These are for information only so are not protected
+ * against increment races.
+ */
+static u64 frontswap_gets;
+static u64 frontswap_succ_puts;
+static u64 frontswap_failed_puts;
+static u64 frontswap_invalidates;
+
+/*
+ * Register operations for frontswap, returning previous thus allowing
+ * detection of multiple backends and possible nesting
+ */
+struct frontswap_ops frontswap_register_ops(struct frontswap_ops *ops)
+{
+	struct frontswap_ops old = frontswap_ops;
+
+	frontswap_ops = *ops;
+	frontswap_enabled = 1;
+	return old;
+}
+EXPORT_SYMBOL(frontswap_register_ops);
+
+/* Called when a swap device is swapon'd */
+void __frontswap_init(unsigned type)
+{
+	struct swap_info_struct *sis = swap_info[type];
+
+	BUG_ON(sis == NULL);
+	if (sis->frontswap_map == NULL)
+		return;
+	if (frontswap_enabled)
+		(*frontswap_ops.init)(type);
+}
+EXPORT_SYMBOL(__frontswap_init);
+
+/*
+ * "Put" data from a page to frontswap and associate it with the page's
+ * swaptype and offset.  Page must be locked and in the swap cache.
+ * If frontswap already contains a page with matching swaptype and
+ * offset, the frontswap implmentation may either overwrite the data and
+ * return success or invalidate the page from frontswap and return failure
+ */
+int __frontswap_put_page(struct page *page)
+{
+	int ret = -1, dup = 0;
+	swp_entry_t entry = { .val = page_private(page), };
+	int type = swp_type(entry);
+	struct swap_info_struct *sis = swap_info[type];
+	pgoff_t offset = swp_offset(entry);
+
+	BUG_ON(!PageLocked(page));
+	BUG_ON(sis == NULL);
+	if (frontswap_test(sis, offset))
+		dup = 1;
+	ret = (*frontswap_ops.put_page)(type, offset, page);
+	if (ret == 0) {
+		frontswap_set(sis, offset);
+		frontswap_succ_puts++;
+		if (!dup)
+			atomic_inc(&sis->frontswap_pages);
+	} else if (dup) {
+		/*
+		  failed dup always results in automatic invalidate of
+		  the (older) page from frontswap
+		 */
+		frontswap_clear(sis, offset);
+		atomic_dec(&sis->frontswap_pages);
+		frontswap_failed_puts++;
+	} else
+		frontswap_failed_puts++;
+	return ret;
+}
+EXPORT_SYMBOL(__frontswap_put_page);
+
+/*
+ * "Get" data from frontswap associated with swaptype and offset that were
+ * specified when the data was put to frontswap and use it to fill the
+ * specified page with data. Page must be locked and in the swap cache
+ */
+int __frontswap_get_page(struct page *page)
+{
+	int ret = -1;
+	swp_entry_t entry = { .val = page_private(page), };
+	int type = swp_type(entry);
+	struct swap_info_struct *sis = swap_info[type];
+	pgoff_t offset = swp_offset(entry);
+
+	BUG_ON(!PageLocked(page));
+	BUG_ON(sis == NULL);
+	if (frontswap_test(sis, offset))
+		ret = (*frontswap_ops.get_page)(type, offset, page);
+	if (ret == 0)
+		frontswap_gets++;
+	return ret;
+}
+EXPORT_SYMBOL(__frontswap_get_page);
+
+/*
+ * Invalidate any data from frontswap associated with the specified swaptype
+ * and offset so that a subsequent "get" will fail.
+ */
+void __frontswap_invalidate_page(unsigned type, pgoff_t offset)
+{
+	struct swap_info_struct *sis = swap_info[type];
+
+	BUG_ON(sis == NULL);
+	if (frontswap_test(sis, offset)) {
+		(*frontswap_ops.invalidate_page)(type, offset);
+		atomic_dec(&sis->frontswap_pages);
+		frontswap_clear(sis, offset);
+		frontswap_invalidates++;
+	}
+}
+EXPORT_SYMBOL(__frontswap_invalidate_page);
+
+/*
+ * Invalidate all data from frontswap associated with all offsets for the
+ * specified swaptype.
+ */
+void __frontswap_invalidate_area(unsigned type)
+{
+	struct swap_info_struct *sis = swap_info[type];
+
+	BUG_ON(sis == NULL);
+	if (sis->frontswap_map == NULL)
+		return;
+	(*frontswap_ops.invalidate_area)(type);
+	atomic_set(&sis->frontswap_pages, 0);
+	memset(sis->frontswap_map, 0, sis->max / sizeof(long));
+}
+EXPORT_SYMBOL(__frontswap_invalidate_area);
+
+/*
+ * Frontswap, like a true swap device, may unnecessarily retain pages
+ * under certain circumstances; "shrink" frontswap is essentially a
+ * "partial swapoff" and works by calling try_to_unuse to attempt to
+ * unuse enough frontswap pages to attempt to -- subject to memory
+ * constraints -- reduce the number of pages in frontswap to the
+ * number given in the parameter target_pages.
+ */
+void frontswap_shrink(unsigned long target_pages)
+{
+	struct swap_info_struct *si = NULL;
+	int si_frontswap_pages;
+	unsigned long total_pages = 0, total_pages_to_unuse;
+	unsigned long pages = 0, pages_to_unuse = 0;
+	int type;
+	bool locked = false;
+
+	/*
+	 * we don't want to hold swap_lock while doing a very
+	 * lengthy try_to_unuse, but swap_list may change
+	 * so restart scan from swap_list.head each time
+	 */
+	spin_lock(&swap_lock);
+	locked = true;
+	total_pages = 0;
+	for (type = swap_list.head; type >= 0; type = si->next) {
+		si = swap_info[type];
+		total_pages += atomic_read(&si->frontswap_pages);
+	}
+	if (total_pages <= target_pages)
+		goto out;
+	total_pages_to_unuse = total_pages - target_pages;
+	for (type = swap_list.head; type >= 0; type = si->next) {
+		si = swap_info[type];
+		si_frontswap_pages = atomic_read(&si->frontswap_pages);
+		if (total_pages_to_unuse < si_frontswap_pages)
+			pages = pages_to_unuse = total_pages_to_unuse;
+		else {
+			pages = si_frontswap_pages;
+			pages_to_unuse = 0; /* unuse all */
+		}
+		/* ensure there is enough RAM to fetch pages from frontswap */
+		if (security_vm_enough_memory_mm(current->mm, pages))
+			continue;
+		vm_unacct_memory(pages);
+		break;
+	}
+	if (type < 0)
+		goto out;
+	locked = false;
+	spin_unlock(&swap_lock);
+	try_to_unuse(type, true, pages_to_unuse);
+out:
+	if (locked)
+		spin_unlock(&swap_lock);
+	return;
+}
+EXPORT_SYMBOL(frontswap_shrink);
+
+/*
+ * Count and return the number of frontswap pages across all
+ * swap devices.  This is exported so that backend drivers can
+ * determine current usage without reading debugfs.
+ */
+unsigned long frontswap_curr_pages(void)
+{
+	int type;
+	unsigned long totalpages = 0;
+	struct swap_info_struct *si = NULL;
+
+	spin_lock(&swap_lock);
+	for (type = swap_list.head; type >= 0; type = si->next) {
+		si = swap_info[type];
+		totalpages += atomic_read(&si->frontswap_pages);
+	}
+	spin_unlock(&swap_lock);
+	return totalpages;
+}
+EXPORT_SYMBOL(frontswap_curr_pages);
+
+static int __init init_frontswap(void)
+{
+	int err = 0;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *root = debugfs_create_dir("frontswap", NULL);
+	if (root == NULL)
+		return -ENXIO;
+	debugfs_create_u64("gets", S_IRUGO, root, &frontswap_gets);
+	debugfs_create_u64("succ_puts", S_IRUGO, root, &frontswap_succ_puts);
+	debugfs_create_u64("failed_puts", S_IRUGO, root,
+				&frontswap_failed_puts);
+	debugfs_create_u64("invalidates", S_IRUGO,
+				root, &frontswap_invalidates);
+#endif
+	return err;
+}
+
+module_init(init_frontswap);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 91d3efb..b310847 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1030,30 +1030,22 @@ int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
 {
 	int ret = 0;
 
-	spin_lock(&tlb->mm->page_table_lock);
-	if (likely(pmd_trans_huge(*pmd))) {
-		if (unlikely(pmd_trans_splitting(*pmd))) {
-			spin_unlock(&tlb->mm->page_table_lock);
-			wait_split_huge_page(vma->anon_vma,
-					     pmd);
-		} else {
-			struct page *page;
-			pgtable_t pgtable;
-			pgtable = get_pmd_huge_pte(tlb->mm);
-			page = pmd_page(*pmd);
-			pmd_clear(pmd);
-			tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
-			page_remove_rmap(page);
-			VM_BUG_ON(page_mapcount(page) < 0);
-			add_mm_counter(tlb->mm, MM_ANONPAGES, -HPAGE_PMD_NR);
-			VM_BUG_ON(!PageHead(page));
-			spin_unlock(&tlb->mm->page_table_lock);
-			tlb_remove_page(tlb, page);
-			pte_free(tlb->mm, pgtable);
-			ret = 1;
-		}
-	} else
+	if (__pmd_trans_huge_lock(pmd, vma)) {
+		struct page *page;
+		pgtable_t pgtable;
+		pgtable = get_pmd_huge_pte(tlb->mm);
+		page = pmd_page(*pmd);
+		pmd_clear(pmd);
+		tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
+		page_remove_rmap(page);
+		VM_BUG_ON(page_mapcount(page) < 0);
+		add_mm_counter(tlb->mm, MM_ANONPAGES, -HPAGE_PMD_NR);
+		VM_BUG_ON(!PageHead(page));
 		spin_unlock(&tlb->mm->page_table_lock);
+		tlb_remove_page(tlb, page);
+		pte_free(tlb->mm, pgtable);
+		ret = 1;
+	}
 
 	return ret;
 }
@@ -1064,21 +1056,15 @@ int mincore_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 {
 	int ret = 0;
 
-	spin_lock(&vma->vm_mm->page_table_lock);
-	if (likely(pmd_trans_huge(*pmd))) {
-		ret = !pmd_trans_splitting(*pmd);
-		spin_unlock(&vma->vm_mm->page_table_lock);
-		if (unlikely(!ret))
-			wait_split_huge_page(vma->anon_vma, pmd);
-		else {
-			/*
-			 * All logical pages in the range are present
-			 * if backed by a huge page.
-			 */
-			memset(vec, 1, (end - addr) >> PAGE_SHIFT);
-		}
-	} else
+	if (__pmd_trans_huge_lock(pmd, vma)) {
+		/*
+		 * All logical pages in the range are present
+		 * if backed by a huge page.
+		 */
 		spin_unlock(&vma->vm_mm->page_table_lock);
+		memset(vec, 1, (end - addr) >> PAGE_SHIFT);
+		ret = 1;
+	}
 
 	return ret;
 }
@@ -1108,21 +1094,12 @@ int move_huge_pmd(struct vm_area_struct *vma, struct vm_area_struct *new_vma,
 		goto out;
 	}
 
-	spin_lock(&mm->page_table_lock);
-	if (likely(pmd_trans_huge(*old_pmd))) {
-		if (pmd_trans_splitting(*old_pmd)) {
-			spin_unlock(&mm->page_table_lock);
-			wait_split_huge_page(vma->anon_vma, old_pmd);
-			ret = -1;
-		} else {
-			pmd = pmdp_get_and_clear(mm, old_addr, old_pmd);
-			VM_BUG_ON(!pmd_none(*new_pmd));
-			set_pmd_at(mm, new_addr, new_pmd, pmd);
-			spin_unlock(&mm->page_table_lock);
-			ret = 1;
-		}
-	} else {
+	if (__pmd_trans_huge_lock(old_pmd, vma)) {
+		pmd = pmdp_get_and_clear(mm, old_addr, old_pmd);
+		VM_BUG_ON(!pmd_none(*new_pmd));
+		set_pmd_at(mm, new_addr, new_pmd, pmd);
 		spin_unlock(&mm->page_table_lock);
+		ret = 1;
 	}
 out:
 	return ret;
@@ -1134,24 +1111,41 @@ int change_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd,
 	struct mm_struct *mm = vma->vm_mm;
 	int ret = 0;
 
-	spin_lock(&mm->page_table_lock);
+	if (__pmd_trans_huge_lock(pmd, vma)) {
+		pmd_t entry;
+		entry = pmdp_get_and_clear(mm, addr, pmd);
+		entry = pmd_modify(entry, newprot);
+		set_pmd_at(mm, addr, pmd, entry);
+		spin_unlock(&vma->vm_mm->page_table_lock);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+/*
+ * Returns 1 if a given pmd maps a stable (not under splitting) thp.
+ * Returns 0 otherwise.
+ *
+ * Note that if it returns 1, this routine returns without unlocking page
+ * table locks. So callers must unlock them.
+ */
+int __pmd_trans_huge_lock(pmd_t *pmd, struct vm_area_struct *vma)
+{
+	spin_lock(&vma->vm_mm->page_table_lock);
 	if (likely(pmd_trans_huge(*pmd))) {
 		if (unlikely(pmd_trans_splitting(*pmd))) {
-			spin_unlock(&mm->page_table_lock);
+			spin_unlock(&vma->vm_mm->page_table_lock);
 			wait_split_huge_page(vma->anon_vma, pmd);
+			return 0;
 		} else {
-			pmd_t entry;
-
-			entry = pmdp_get_and_clear(mm, addr, pmd);
-			entry = pmd_modify(entry, newprot);
-			set_pmd_at(mm, addr, pmd, entry);
-			spin_unlock(&vma->vm_mm->page_table_lock);
-			ret = 1;
+			/* Thp mapped by 'pmd' is stable, so we can
+			 * handle it as it is. */
+			return 1;
 		}
-	} else
-		spin_unlock(&vma->vm_mm->page_table_lock);
-
-	return ret;
+	}
+	spin_unlock(&vma->vm_mm->page_table_lock);
+	return 0;
 }
 
 pmd_t *page_check_address_pmd(struct page *page,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 5f34bd8..50e83ee 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -852,6 +852,7 @@ static int gather_surplus_pages(struct hstate *h, int delta)
 	struct page *page, *tmp;
 	int ret, i;
 	int needed, allocated;
+	bool alloc_ok = true;
 
 	needed = (h->resv_huge_pages + delta) - h->free_huge_pages;
 	if (needed <= 0) {
@@ -867,17 +868,13 @@ retry:
 	spin_unlock(&hugetlb_lock);
 	for (i = 0; i < needed; i++) {
 		page = alloc_buddy_huge_page(h, NUMA_NO_NODE);
-		if (!page)
-			/*
-			 * We were not able to allocate enough pages to
-			 * satisfy the entire reservation so we free what
-			 * we've allocated so far.
-			 */
-			goto free;
-
+		if (!page) {
+			alloc_ok = false;
+			break;
+		}
 		list_add(&page->lru, &surplus_list);
 	}
-	allocated += needed;
+	allocated += i;
 
 	/*
 	 * After retaking hugetlb_lock, we need to recalculate 'needed'
@@ -886,9 +883,16 @@ retry:
 	spin_lock(&hugetlb_lock);
 	needed = (h->resv_huge_pages + delta) -
 			(h->free_huge_pages + allocated);
-	if (needed > 0)
-		goto retry;
-
+	if (needed > 0) {
+		if (alloc_ok)
+			goto retry;
+		/*
+		 * We were not able to allocate enough pages to
+		 * satisfy the entire reservation so we free what
+		 * we've allocated so far.
+		 */
+		goto free;
+	}
 	/*
 	 * The surplus_list now contains _at_least_ the number of extra pages
 	 * needed to accommodate the reservation.  Add the appropriate number
@@ -914,10 +918,10 @@ retry:
 		VM_BUG_ON(page_count(page));
 		enqueue_huge_page(h, page);
 	}
+free:
 	spin_unlock(&hugetlb_lock);
 
 	/* Free unnecessary surplus pages to the buddy allocator */
-free:
 	if (!list_empty(&surplus_list)) {
 		list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
 			list_del(&page->lru);
diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c
index c7fc7fd..cc448bb 100644
--- a/mm/hwpoison-inject.c
+++ b/mm/hwpoison-inject.c
@@ -45,7 +45,7 @@ static int hwpoison_inject(void *data, u64 val)
 	 * do a racy check with elevated page count, to make sure PG_hwpoison
 	 * will only be set for the targeted owner (or on a free page).
 	 * We temporarily take page lock for try_get_mem_cgroup_from_page().
-	 * __memory_failure() will redo the check reliably inside page lock.
+	 * memory_failure() will redo the check reliably inside page lock.
 	 */
 	lock_page(hpage);
 	err = hwpoison_filter(hpage);
@@ -55,7 +55,7 @@ static int hwpoison_inject(void *data, u64 val)
 
 inject:
 	printk(KERN_INFO "Injecting memory failure at pfn %lx\n", pfn);
-	return __memory_failure(pfn, 18, MF_COUNT_INCREASED);
+	return memory_failure(pfn, 18, MF_COUNT_INCREASED);
 }
 
 static int hwpoison_unpoison(void *data, u64 val)
diff --git a/mm/ksm.c b/mm/ksm.c
index 1925ffb..e20de58 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -673,9 +673,9 @@ error:
 static u32 calc_checksum(struct page *page)
 {
 	u32 checksum;
-	void *addr = kmap_atomic(page, KM_USER0);
+	void *addr = kmap_atomic(page);
 	checksum = jhash2(addr, PAGE_SIZE / 4, 17);
-	kunmap_atomic(addr, KM_USER0);
+	kunmap_atomic(addr);
 	return checksum;
 }
 
@@ -684,11 +684,11 @@ static int memcmp_pages(struct page *page1, struct page *page2)
 	char *addr1, *addr2;
 	int ret;
 
-	addr1 = kmap_atomic(page1, KM_USER0);
-	addr2 = kmap_atomic(page2, KM_USER1);
+	addr1 = kmap_atomic(page1);
+	addr2 = kmap_atomic(page2);
 	ret = memcmp(addr1, addr2, PAGE_SIZE);
-	kunmap_atomic(addr2, KM_USER1);
-	kunmap_atomic(addr1, KM_USER0);
+	kunmap_atomic(addr2);
+	kunmap_atomic(addr1);
 	return ret;
 }
 
diff --git a/mm/madvise.c b/mm/madvise.c
index 74bf193..f5ab745 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -251,7 +251,7 @@ static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end)
 		printk(KERN_INFO "Injecting memory failure for page %lx at %lx\n",
 		       page_to_pfn(p), start);
 		/* Ignore return value for now */
-		__memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED);
+		memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED);
 	}
 	return ret;
 }
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6728a7a..ab315ab 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -135,7 +135,7 @@ struct mem_cgroup_reclaim_iter {
  */
 struct mem_cgroup_per_zone {
 	struct lruvec		lruvec;
-	unsigned long		count[NR_LRU_LISTS];
+	unsigned long		lru_size[NR_LRU_LISTS];
 
 	struct mem_cgroup_reclaim_iter reclaim_iter[DEF_PRIORITY + 1];
 
@@ -144,11 +144,9 @@ struct mem_cgroup_per_zone {
 	unsigned long long	usage_in_excess;/* Set to the value by which */
 						/* the soft limit is exceeded*/
 	bool			on_tree;
-	struct mem_cgroup	*mem;		/* Back pointer, we cannot */
+	struct mem_cgroup	*memcg;		/* Back pointer, we cannot */
 						/* use container_of	   */
 };
-/* Macro for accessing counter */
-#define MEM_CGROUP_ZSTAT(mz, idx)	((mz)->count[(idx)])
 
 struct mem_cgroup_per_node {
 	struct mem_cgroup_per_zone zoneinfo[MAX_NR_ZONES];
@@ -592,9 +590,9 @@ retry:
 	 * we will to add it back at the end of reclaim to its correct
 	 * position in the tree.
 	 */
-	__mem_cgroup_remove_exceeded(mz->mem, mz, mctz);
-	if (!res_counter_soft_limit_excess(&mz->mem->res) ||
-		!css_tryget(&mz->mem->css))
+	__mem_cgroup_remove_exceeded(mz->memcg, mz, mctz);
+	if (!res_counter_soft_limit_excess(&mz->memcg->res) ||
+		!css_tryget(&mz->memcg->css))
 		goto retry;
 done:
 	return mz;
@@ -672,15 +670,19 @@ static unsigned long mem_cgroup_read_events(struct mem_cgroup *memcg,
 }
 
 static void mem_cgroup_charge_statistics(struct mem_cgroup *memcg,
-					 bool file, int nr_pages)
+					 bool anon, int nr_pages)
 {
 	preempt_disable();
 
-	if (file)
-		__this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_CACHE],
+	/*
+	 * Here, RSS means 'mapped anon' and anon's SwapCache. Shmem/tmpfs is
+	 * counted as CACHE even if it's on ANON LRU.
+	 */
+	if (anon)
+		__this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_RSS],
 				nr_pages);
 	else
-		__this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_RSS],
+		__this_cpu_add(memcg->stat->count[MEM_CGROUP_STAT_CACHE],
 				nr_pages);
 
 	/* pagein of a big page is an event. So, ignore page size */
@@ -701,14 +703,14 @@ mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, int nid, int zid,
 			unsigned int lru_mask)
 {
 	struct mem_cgroup_per_zone *mz;
-	enum lru_list l;
+	enum lru_list lru;
 	unsigned long ret = 0;
 
 	mz = mem_cgroup_zoneinfo(memcg, nid, zid);
 
-	for_each_lru(l) {
-		if (BIT(l) & lru_mask)
-			ret += MEM_CGROUP_ZSTAT(mz, l);
+	for_each_lru(lru) {
+		if (BIT(lru) & lru_mask)
+			ret += mz->lru_size[lru];
 	}
 	return ret;
 }
@@ -1044,7 +1046,7 @@ struct lruvec *mem_cgroup_lru_add_list(struct zone *zone, struct page *page,
 	memcg = pc->mem_cgroup;
 	mz = page_cgroup_zoneinfo(memcg, page);
 	/* compound_order() is stabilized through lru_lock */
-	MEM_CGROUP_ZSTAT(mz, lru) += 1 << compound_order(page);
+	mz->lru_size[lru] += 1 << compound_order(page);
 	return &mz->lruvec;
 }
 
@@ -1072,8 +1074,8 @@ void mem_cgroup_lru_del_list(struct page *page, enum lru_list lru)
 	VM_BUG_ON(!memcg);
 	mz = page_cgroup_zoneinfo(memcg, page);
 	/* huge page split is done under lru_lock. so, we have no races. */
-	VM_BUG_ON(MEM_CGROUP_ZSTAT(mz, lru) < (1 << compound_order(page)));
-	MEM_CGROUP_ZSTAT(mz, lru) -= 1 << compound_order(page);
+	VM_BUG_ON(mz->lru_size[lru] < (1 << compound_order(page)));
+	mz->lru_size[lru] -= 1 << compound_order(page);
 }
 
 void mem_cgroup_lru_del(struct page *page)
@@ -1360,7 +1362,6 @@ void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p)
 	if (!memcg || !p)
 		return;
 
-
 	rcu_read_lock();
 
 	mem_cgrp = memcg->css.cgroup;
@@ -1739,22 +1740,22 @@ static DEFINE_SPINLOCK(memcg_oom_lock);
 static DECLARE_WAIT_QUEUE_HEAD(memcg_oom_waitq);
 
 struct oom_wait_info {
-	struct mem_cgroup *mem;
+	struct mem_cgroup *memcg;
 	wait_queue_t	wait;
 };
 
 static int memcg_oom_wake_function(wait_queue_t *wait,
 	unsigned mode, int sync, void *arg)
 {
-	struct mem_cgroup *wake_memcg = (struct mem_cgroup *)arg,
-			  *oom_wait_memcg;
+	struct mem_cgroup *wake_memcg = (struct mem_cgroup *)arg;
+	struct mem_cgroup *oom_wait_memcg;
 	struct oom_wait_info *oom_wait_info;
 
 	oom_wait_info = container_of(wait, struct oom_wait_info, wait);
-	oom_wait_memcg = oom_wait_info->mem;
+	oom_wait_memcg = oom_wait_info->memcg;
 
 	/*
-	 * Both of oom_wait_info->mem and wake_mem are stable under us.
+	 * Both of oom_wait_info->memcg and wake_memcg are stable under us.
 	 * Then we can use css_is_ancestor without taking care of RCU.
 	 */
 	if (!mem_cgroup_same_or_subtree(oom_wait_memcg, wake_memcg)
@@ -1783,7 +1784,7 @@ bool mem_cgroup_handle_oom(struct mem_cgroup *memcg, gfp_t mask)
 	struct oom_wait_info owait;
 	bool locked, need_to_kill;
 
-	owait.mem = memcg;
+	owait.memcg = memcg;
 	owait.wait.flags = 0;
 	owait.wait.func = memcg_oom_wake_function;
 	owait.wait.private = current;
@@ -1868,7 +1869,7 @@ void mem_cgroup_update_page_stat(struct page *page,
 	if (unlikely(!memcg || !PageCgroupUsed(pc)))
 		goto out;
 	/* pc->mem_cgroup is unstable ? */
-	if (unlikely(mem_cgroup_stealed(memcg)) || PageTransHuge(page)) {
+	if (unlikely(mem_cgroup_stealed(memcg))) {
 		/* take a lock against to access pc->mem_cgroup */
 		move_lock_page_cgroup(pc, &flags);
 		need_unlock = true;
@@ -1895,7 +1896,6 @@ out:
 	if (unlikely(need_unlock))
 		move_unlock_page_cgroup(pc, &flags);
 	rcu_read_unlock();
-	return;
 }
 EXPORT_SYMBOL(mem_cgroup_update_page_stat);
 
@@ -2410,6 +2410,8 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
 				       struct page_cgroup *pc,
 				       enum charge_type ctype)
 {
+	bool anon;
+
 	lock_page_cgroup(pc);
 	if (unlikely(PageCgroupUsed(pc))) {
 		unlock_page_cgroup(pc);
@@ -2429,21 +2431,14 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
 	 * See mem_cgroup_add_lru_list(), etc.
  	 */
 	smp_wmb();
-	switch (ctype) {
-	case MEM_CGROUP_CHARGE_TYPE_CACHE:
-	case MEM_CGROUP_CHARGE_TYPE_SHMEM:
-		SetPageCgroupCache(pc);
-		SetPageCgroupUsed(pc);
-		break;
-	case MEM_CGROUP_CHARGE_TYPE_MAPPED:
-		ClearPageCgroupCache(pc);
-		SetPageCgroupUsed(pc);
-		break;
-	default:
-		break;
-	}
 
-	mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), nr_pages);
+	SetPageCgroupUsed(pc);
+	if (ctype == MEM_CGROUP_CHARGE_TYPE_MAPPED)
+		anon = true;
+	else
+		anon = false;
+
+	mem_cgroup_charge_statistics(memcg, anon, nr_pages);
 	unlock_page_cgroup(pc);
 	WARN_ON_ONCE(PageLRU(page));
 	/*
@@ -2508,6 +2503,7 @@ static int mem_cgroup_move_account(struct page *page,
 {
 	unsigned long flags;
 	int ret;
+	bool anon = PageAnon(page);
 
 	VM_BUG_ON(from == to);
 	VM_BUG_ON(PageLRU(page));
@@ -2536,14 +2532,14 @@ static int mem_cgroup_move_account(struct page *page,
 		__this_cpu_inc(to->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
 		preempt_enable();
 	}
-	mem_cgroup_charge_statistics(from, PageCgroupCache(pc), -nr_pages);
+	mem_cgroup_charge_statistics(from, anon, -nr_pages);
 	if (uncharge)
 		/* This is not "cancel", but cancel_charge does all we need. */
 		__mem_cgroup_cancel_charge(from, nr_pages);
 
 	/* caller should have done css_get */
 	pc->mem_cgroup = to;
-	mem_cgroup_charge_statistics(to, PageCgroupCache(pc), nr_pages);
+	mem_cgroup_charge_statistics(to, anon, nr_pages);
 	/*
 	 * We charges against "to" which may not have any tasks. Then, "to"
 	 * can be under rmdir(). But in current implementation, caller of
@@ -2689,7 +2685,6 @@ __mem_cgroup_commit_charge_lrucare(struct page *page, struct mem_cgroup *memcg,
 		SetPageLRU(page);
 	}
 	spin_unlock_irqrestore(&zone->lru_lock, flags);
-	return;
 }
 
 int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
@@ -2879,7 +2874,6 @@ direct_uncharge:
 		res_counter_uncharge(&memcg->memsw, nr_pages * PAGE_SIZE);
 	if (unlikely(batch->memcg != memcg))
 		memcg_oom_recover(memcg);
-	return;
 }
 
 /*
@@ -2891,6 +2885,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
 	struct mem_cgroup *memcg = NULL;
 	unsigned int nr_pages = 1;
 	struct page_cgroup *pc;
+	bool anon;
 
 	if (mem_cgroup_disabled())
 		return NULL;
@@ -2922,6 +2917,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
 		/* See mem_cgroup_prepare_migration() */
 		if (page_mapped(page) || PageCgroupMigration(pc))
 			goto unlock_out;
+		anon = true;
 		break;
 	case MEM_CGROUP_CHARGE_TYPE_SWAPOUT:
 		if (!PageAnon(page)) {	/* Shared memory */
@@ -2929,12 +2925,14 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
 				goto unlock_out;
 		} else if (page_mapped(page)) /* Anon */
 				goto unlock_out;
+		anon = true;
 		break;
 	default:
+		anon = false;
 		break;
 	}
 
-	mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), -nr_pages);
+	mem_cgroup_charge_statistics(memcg, anon, -nr_pages);
 
 	ClearPageCgroupUsed(pc);
 	/*
@@ -3258,6 +3256,7 @@ void mem_cgroup_end_migration(struct mem_cgroup *memcg,
 {
 	struct page *used, *unused;
 	struct page_cgroup *pc;
+	bool anon;
 
 	if (!memcg)
 		return;
@@ -3279,8 +3278,10 @@ void mem_cgroup_end_migration(struct mem_cgroup *memcg,
 	lock_page_cgroup(pc);
 	ClearPageCgroupMigration(pc);
 	unlock_page_cgroup(pc);
-
-	__mem_cgroup_uncharge_common(unused, MEM_CGROUP_CHARGE_TYPE_FORCE);
+	anon = PageAnon(used);
+	__mem_cgroup_uncharge_common(unused,
+		anon ? MEM_CGROUP_CHARGE_TYPE_MAPPED
+		     : MEM_CGROUP_CHARGE_TYPE_CACHE);
 
 	/*
 	 * If a page is a file cache, radix-tree replacement is very atomic
@@ -3290,7 +3291,7 @@ void mem_cgroup_end_migration(struct mem_cgroup *memcg,
 	 * and USED bit check in mem_cgroup_uncharge_page() will do enough
 	 * check. (see prepare_charge() also)
 	 */
-	if (PageAnon(used))
+	if (anon)
 		mem_cgroup_uncharge_page(used);
 	/*
 	 * At migration, we may charge account against cgroup which has no
@@ -3320,7 +3321,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage,
 	/* fix accounting on old pages */
 	lock_page_cgroup(pc);
 	memcg = pc->mem_cgroup;
-	mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), -1);
+	mem_cgroup_charge_statistics(memcg, false, -1);
 	ClearPageCgroupUsed(pc);
 	unlock_page_cgroup(pc);
 
@@ -3531,7 +3532,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
 			break;
 
 		nr_scanned = 0;
-		reclaimed = mem_cgroup_soft_reclaim(mz->mem, zone,
+		reclaimed = mem_cgroup_soft_reclaim(mz->memcg, zone,
 						    gfp_mask, &nr_scanned);
 		nr_reclaimed += reclaimed;
 		*total_scanned += nr_scanned;
@@ -3558,13 +3559,13 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
 				next_mz =
 				__mem_cgroup_largest_soft_limit_node(mctz);
 				if (next_mz == mz)
-					css_put(&next_mz->mem->css);
+					css_put(&next_mz->memcg->css);
 				else /* next_mz == NULL or other memcg */
 					break;
 			} while (1);
 		}
-		__mem_cgroup_remove_exceeded(mz->mem, mz, mctz);
-		excess = res_counter_soft_limit_excess(&mz->mem->res);
+		__mem_cgroup_remove_exceeded(mz->memcg, mz, mctz);
+		excess = res_counter_soft_limit_excess(&mz->memcg->res);
 		/*
 		 * One school of thought says that we should not add
 		 * back the node to the tree if reclaim returns 0.
@@ -3574,9 +3575,9 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
 		 * term TODO.
 		 */
 		/* If excess == 0, no tree ops */
-		__mem_cgroup_insert_exceeded(mz->mem, mz, mctz, excess);
+		__mem_cgroup_insert_exceeded(mz->memcg, mz, mctz, excess);
 		spin_unlock(&mctz->lock);
-		css_put(&mz->mem->css);
+		css_put(&mz->memcg->css);
 		loop++;
 		/*
 		 * Could not reclaim anything and there are no more
@@ -3589,7 +3590,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
 			break;
 	} while (!nr_reclaimed);
 	if (next_mz)
-		css_put(&next_mz->mem->css);
+		css_put(&next_mz->memcg->css);
 	return nr_reclaimed;
 }
 
@@ -3611,7 +3612,7 @@ static int mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
 	mz = mem_cgroup_zoneinfo(memcg, node, zid);
 	list = &mz->lruvec.lists[lru];
 
-	loop = MEM_CGROUP_ZSTAT(mz, lru);
+	loop = mz->lru_size[lru];
 	/* give some margin against EBUSY etc...*/
 	loop += 256;
 	busy = NULL;
@@ -3685,10 +3686,10 @@ move_account:
 		mem_cgroup_start_move(memcg);
 		for_each_node_state(node, N_HIGH_MEMORY) {
 			for (zid = 0; !ret && zid < MAX_NR_ZONES; zid++) {
-				enum lru_list l;
-				for_each_lru(l) {
+				enum lru_list lru;
+				for_each_lru(lru) {
 					ret = mem_cgroup_force_empty_list(memcg,
-							node, zid, l);
+							node, zid, lru);
 					if (ret)
 						break;
 				}
@@ -3921,7 +3922,6 @@ static void memcg_get_hierarchical_limit(struct mem_cgroup *memcg,
 out:
 	*mem_limit = min_limit;
 	*memsw_limit = min_memsw_limit;
-	return;
 }
 
 static int mem_cgroup_reset(struct cgroup *cont, unsigned int event)
@@ -4080,38 +4080,38 @@ static int mem_control_numa_stat_show(struct seq_file *m, void *arg)
 	unsigned long total_nr, file_nr, anon_nr, unevictable_nr;
 	unsigned long node_nr;
 	struct cgroup *cont = m->private;
-	struct mem_cgroup *mem_cont = mem_cgroup_from_cont(cont);
+	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
 
-	total_nr = mem_cgroup_nr_lru_pages(mem_cont, LRU_ALL);
+	total_nr = mem_cgroup_nr_lru_pages(memcg, LRU_ALL);
 	seq_printf(m, "total=%lu", total_nr);
 	for_each_node_state(nid, N_HIGH_MEMORY) {
-		node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid, LRU_ALL);
+		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid, LRU_ALL);
 		seq_printf(m, " N%d=%lu", nid, node_nr);
 	}
 	seq_putc(m, '\n');
 
-	file_nr = mem_cgroup_nr_lru_pages(mem_cont, LRU_ALL_FILE);
+	file_nr = mem_cgroup_nr_lru_pages(memcg, LRU_ALL_FILE);
 	seq_printf(m, "file=%lu", file_nr);
 	for_each_node_state(nid, N_HIGH_MEMORY) {
-		node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid,
+		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
 				LRU_ALL_FILE);
 		seq_printf(m, " N%d=%lu", nid, node_nr);
 	}
 	seq_putc(m, '\n');
 
-	anon_nr = mem_cgroup_nr_lru_pages(mem_cont, LRU_ALL_ANON);
+	anon_nr = mem_cgroup_nr_lru_pages(memcg, LRU_ALL_ANON);
 	seq_printf(m, "anon=%lu", anon_nr);
 	for_each_node_state(nid, N_HIGH_MEMORY) {
-		node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid,
+		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
 				LRU_ALL_ANON);
 		seq_printf(m, " N%d=%lu", nid, node_nr);
 	}
 	seq_putc(m, '\n');
 
-	unevictable_nr = mem_cgroup_nr_lru_pages(mem_cont, BIT(LRU_UNEVICTABLE));
+	unevictable_nr = mem_cgroup_nr_lru_pages(memcg, BIT(LRU_UNEVICTABLE));
 	seq_printf(m, "unevictable=%lu", unevictable_nr);
 	for_each_node_state(nid, N_HIGH_MEMORY) {
-		node_nr = mem_cgroup_node_nr_lru_pages(mem_cont, nid,
+		node_nr = mem_cgroup_node_nr_lru_pages(memcg, nid,
 				BIT(LRU_UNEVICTABLE));
 		seq_printf(m, " N%d=%lu", nid, node_nr);
 	}
@@ -4123,12 +4123,12 @@ static int mem_control_numa_stat_show(struct seq_file *m, void *arg)
 static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft,
 				 struct cgroup_map_cb *cb)
 {
-	struct mem_cgroup *mem_cont = mem_cgroup_from_cont(cont);
+	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
 	struct mcs_total_stat mystat;
 	int i;
 
 	memset(&mystat, 0, sizeof(mystat));
-	mem_cgroup_get_local_stat(mem_cont, &mystat);
+	mem_cgroup_get_local_stat(memcg, &mystat);
 
 
 	for (i = 0; i < NR_MCS_STAT; i++) {
@@ -4140,14 +4140,14 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft,
 	/* Hierarchical information */
 	{
 		unsigned long long limit, memsw_limit;
-		memcg_get_hierarchical_limit(mem_cont, &limit, &memsw_limit);
+		memcg_get_hierarchical_limit(memcg, &limit, &memsw_limit);
 		cb->fill(cb, "hierarchical_memory_limit", limit);
 		if (do_swap_account)
 			cb->fill(cb, "hierarchical_memsw_limit", memsw_limit);
 	}
 
 	memset(&mystat, 0, sizeof(mystat));
-	mem_cgroup_get_total_stat(mem_cont, &mystat);
+	mem_cgroup_get_total_stat(memcg, &mystat);
 	for (i = 0; i < NR_MCS_STAT; i++) {
 		if (i == MCS_SWAP && !do_swap_account)
 			continue;
@@ -4163,7 +4163,7 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft,
 
 		for_each_online_node(nid)
 			for (zid = 0; zid < MAX_NR_ZONES; zid++) {
-				mz = mem_cgroup_zoneinfo(mem_cont, nid, zid);
+				mz = mem_cgroup_zoneinfo(memcg, nid, zid);
 
 				recent_rotated[0] +=
 					mz->reclaim_stat.recent_rotated[0];
@@ -4581,10 +4581,9 @@ static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
 	return mem_cgroup_sockets_init(cont, ss);
 };
 
-static void kmem_cgroup_destroy(struct cgroup_subsys *ss,
-				struct cgroup *cont)
+static void kmem_cgroup_destroy(struct cgroup *cont)
 {
-	mem_cgroup_sockets_destroy(cont, ss);
+	mem_cgroup_sockets_destroy(cont);
 }
 #else
 static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
@@ -4592,8 +4591,7 @@ static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
 	return 0;
 }
 
-static void kmem_cgroup_destroy(struct cgroup_subsys *ss,
-				struct cgroup *cont)
+static void kmem_cgroup_destroy(struct cgroup *cont)
 {
 }
 #endif
@@ -4717,7 +4715,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
 {
 	struct mem_cgroup_per_node *pn;
 	struct mem_cgroup_per_zone *mz;
-	enum lru_list l;
+	enum lru_list lru;
 	int zone, tmp = node;
 	/*
 	 * This routine is called against possible nodes.
@@ -4735,11 +4733,11 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
 
 	for (zone = 0; zone < MAX_NR_ZONES; zone++) {
 		mz = &pn->zoneinfo[zone];
-		for_each_lru(l)
-			INIT_LIST_HEAD(&mz->lruvec.lists[l]);
+		for_each_lru(lru)
+			INIT_LIST_HEAD(&mz->lruvec.lists[lru]);
 		mz->usage_in_excess = 0;
 		mz->on_tree = false;
-		mz->mem = memcg;
+		mz->memcg = memcg;
 	}
 	memcg->info.nodeinfo[node] = pn;
 	return 0;
@@ -4752,29 +4750,29 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
 
 static struct mem_cgroup *mem_cgroup_alloc(void)
 {
-	struct mem_cgroup *mem;
+	struct mem_cgroup *memcg;
 	int size = sizeof(struct mem_cgroup);
 
 	/* Can be very big if MAX_NUMNODES is very big */
 	if (size < PAGE_SIZE)
-		mem = kzalloc(size, GFP_KERNEL);
+		memcg = kzalloc(size, GFP_KERNEL);
 	else
-		mem = vzalloc(size);
+		memcg = vzalloc(size);
 
-	if (!mem)
+	if (!memcg)
 		return NULL;
 
-	mem->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
-	if (!mem->stat)
+	memcg->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
+	if (!memcg->stat)
 		goto out_free;
-	spin_lock_init(&mem->pcp_counter_lock);
-	return mem;
+	spin_lock_init(&memcg->pcp_counter_lock);
+	return memcg;
 
 out_free:
 	if (size < PAGE_SIZE)
-		kfree(mem);
+		kfree(memcg);
 	else
-		vfree(mem);
+		vfree(memcg);
 	return NULL;
 }
 
@@ -4885,7 +4883,7 @@ err_cleanup:
 }
 
 static struct cgroup_subsys_state * __ref
-mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
+mem_cgroup_create(struct cgroup *cont)
 {
 	struct mem_cgroup *memcg, *parent;
 	long error = -ENOMEM;
@@ -4947,20 +4945,18 @@ free_out:
 	return ERR_PTR(error);
 }
 
-static int mem_cgroup_pre_destroy(struct cgroup_subsys *ss,
-					struct cgroup *cont)
+static int mem_cgroup_pre_destroy(struct cgroup *cont)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
 
 	return mem_cgroup_force_empty(memcg, false);
 }
 
-static void mem_cgroup_destroy(struct cgroup_subsys *ss,
-				struct cgroup *cont)
+static void mem_cgroup_destroy(struct cgroup *cont)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
 
-	kmem_cgroup_destroy(ss, cont);
+	kmem_cgroup_destroy(cont);
 
 	mem_cgroup_put(memcg);
 }
@@ -5297,9 +5293,8 @@ static void mem_cgroup_clear_mc(void)
 	mem_cgroup_end_move(from);
 }
 
-static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
-				struct cgroup *cgroup,
-				struct cgroup_taskset *tset)
+static int mem_cgroup_can_attach(struct cgroup *cgroup,
+				 struct cgroup_taskset *tset)
 {
 	struct task_struct *p = cgroup_taskset_first(tset);
 	int ret = 0;
@@ -5337,9 +5332,8 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
 	return ret;
 }
 
-static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
-				struct cgroup *cgroup,
-				struct cgroup_taskset *tset)
+static void mem_cgroup_cancel_attach(struct cgroup *cgroup,
+				     struct cgroup_taskset *tset)
 {
 	mem_cgroup_clear_mc();
 }
@@ -5454,9 +5448,8 @@ retry:
 	up_read(&mm->mmap_sem);
 }
 
-static void mem_cgroup_move_task(struct cgroup_subsys *ss,
-				struct cgroup *cont,
-				struct cgroup_taskset *tset)
+static void mem_cgroup_move_task(struct cgroup *cont,
+				 struct cgroup_taskset *tset)
 {
 	struct task_struct *p = cgroup_taskset_first(tset);
 	struct mm_struct *mm = get_task_mm(p);
@@ -5471,20 +5464,17 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
 		mem_cgroup_clear_mc();
 }
 #else	/* !CONFIG_MMU */
-static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
-				struct cgroup *cgroup,
-				struct cgroup_taskset *tset)
+static int mem_cgroup_can_attach(struct cgroup *cgroup,
+				 struct cgroup_taskset *tset)
 {
 	return 0;
 }
-static void mem_cgroup_cancel_attach(struct cgroup_subsys *ss,
-				struct cgroup *cgroup,
-				struct cgroup_taskset *tset)
+static void mem_cgroup_cancel_attach(struct cgroup *cgroup,
+				     struct cgroup_taskset *tset)
 {
 }
-static void mem_cgroup_move_task(struct cgroup_subsys *ss,
-				struct cgroup *cont,
-				struct cgroup_taskset *tset)
+static void mem_cgroup_move_task(struct cgroup *cont,
+				 struct cgroup_taskset *tset)
 {
 }
 #endif
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 56080ea..0f6033b 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -187,33 +187,40 @@ int hwpoison_filter(struct page *p)
 EXPORT_SYMBOL_GPL(hwpoison_filter);
 
 /*
- * Send all the processes who have the page mapped an ``action optional''
- * signal.
+ * Send all the processes who have the page mapped a signal.
+ * ``action optional'' if they are not immediately affected by the error
+ * ``action required'' if error happened in current execution context
  */
-static int kill_proc_ao(struct task_struct *t, unsigned long addr, int trapno,
-			unsigned long pfn, struct page *page)
+static int kill_proc(struct task_struct *t, unsigned long addr, int trapno,
+			unsigned long pfn, struct page *page, int flags)
 {
 	struct siginfo si;
 	int ret;
 
 	printk(KERN_ERR
-		"MCE %#lx: Killing %s:%d early due to hardware memory corruption\n",
+		"MCE %#lx: Killing %s:%d due to hardware memory corruption\n",
 		pfn, t->comm, t->pid);
 	si.si_signo = SIGBUS;
 	si.si_errno = 0;
-	si.si_code = BUS_MCEERR_AO;
 	si.si_addr = (void *)addr;
 #ifdef __ARCH_SI_TRAPNO
 	si.si_trapno = trapno;
 #endif
 	si.si_addr_lsb = compound_trans_order(compound_head(page)) + PAGE_SHIFT;
-	/*
-	 * Don't use force here, it's convenient if the signal
-	 * can be temporarily blocked.
-	 * This could cause a loop when the user sets SIGBUS
-	 * to SIG_IGN, but hopefully no one will do that?
-	 */
-	ret = send_sig_info(SIGBUS, &si, t);  /* synchronous? */
+
+	if ((flags & MF_ACTION_REQUIRED) && t == current) {
+		si.si_code = BUS_MCEERR_AR;
+		ret = force_sig_info(SIGBUS, &si, t);
+	} else {
+		/*
+		 * Don't use force here, it's convenient if the signal
+		 * can be temporarily blocked.
+		 * This could cause a loop when the user sets SIGBUS
+		 * to SIG_IGN, but hopefully no one will do that?
+		 */
+		si.si_code = BUS_MCEERR_AO;
+		ret = send_sig_info(SIGBUS, &si, t);  /* synchronous? */
+	}
 	if (ret < 0)
 		printk(KERN_INFO "MCE: Error sending signal to %s:%d: %d\n",
 		       t->comm, t->pid, ret);
@@ -338,8 +345,9 @@ static void add_to_kill(struct task_struct *tsk, struct page *p,
  * Also when FAIL is set do a force kill because something went
  * wrong earlier.
  */
-static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno,
-			  int fail, struct page *page, unsigned long pfn)
+static void kill_procs(struct list_head *to_kill, int doit, int trapno,
+			  int fail, struct page *page, unsigned long pfn,
+			  int flags)
 {
 	struct to_kill *tk, *next;
 
@@ -363,8 +371,8 @@ static void kill_procs_ao(struct list_head *to_kill, int doit, int trapno,
 			 * check for that, but we need to tell the
 			 * process anyways.
 			 */
-			else if (kill_proc_ao(tk->tsk, tk->addr, trapno,
-					      pfn, page) < 0)
+			else if (kill_proc(tk->tsk, tk->addr, trapno,
+					      pfn, page, flags) < 0)
 				printk(KERN_ERR
 		"MCE %#lx: Cannot send advisory machine check signal to %s:%d\n",
 					pfn, tk->tsk->comm, tk->tsk->pid);
@@ -844,7 +852,7 @@ static int page_action(struct page_state *ps, struct page *p,
  * the pages and send SIGBUS to the processes if the data was dirty.
  */
 static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
-				  int trapno)
+				  int trapno, int flags)
 {
 	enum ttu_flags ttu = TTU_UNMAP | TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS;
 	struct address_space *mapping;
@@ -962,8 +970,8 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
 	 * use a more force-full uncatchable kill to prevent
 	 * any accesses to the poisoned memory.
 	 */
-	kill_procs_ao(&tokill, !!PageDirty(ppage), trapno,
-		      ret != SWAP_SUCCESS, p, pfn);
+	kill_procs(&tokill, !!PageDirty(ppage), trapno,
+		      ret != SWAP_SUCCESS, p, pfn, flags);
 
 	return ret;
 }
@@ -984,7 +992,25 @@ static void clear_page_hwpoison_huge_page(struct page *hpage)
 		ClearPageHWPoison(hpage + i);
 }
 
-int __memory_failure(unsigned long pfn, int trapno, int flags)
+/**
+ * memory_failure - Handle memory failure of a page.
+ * @pfn: Page Number of the corrupted page
+ * @trapno: Trap number reported in the signal to user space.
+ * @flags: fine tune action taken
+ *
+ * This function is called by the low level machine check code
+ * of an architecture when it detects hardware memory corruption
+ * of a page. It tries its best to recover, which includes
+ * dropping pages, killing processes etc.
+ *
+ * The function is primarily of use for corruptions that
+ * happen outside the current execution context (e.g. when
+ * detected by a background scrubber)
+ *
+ * Must run in process context (e.g. a work queue) with interrupts
+ * enabled and no spinlocks hold.
+ */
+int memory_failure(unsigned long pfn, int trapno, int flags)
 {
 	struct page_state *ps;
 	struct page *p;
@@ -1130,7 +1156,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
 	 * Now take care of user space mappings.
 	 * Abort on fail: __delete_from_page_cache() assumes unmapped page.
 	 */
-	if (hwpoison_user_mappings(p, pfn, trapno) != SWAP_SUCCESS) {
+	if (hwpoison_user_mappings(p, pfn, trapno, flags) != SWAP_SUCCESS) {
 		printk(KERN_ERR "MCE %#lx: cannot unmap page, give up\n", pfn);
 		res = -EBUSY;
 		goto out;
@@ -1156,29 +1182,7 @@ out:
 	unlock_page(hpage);
 	return res;
 }
-EXPORT_SYMBOL_GPL(__memory_failure);
-
-/**
- * memory_failure - Handle memory failure of a page.
- * @pfn: Page Number of the corrupted page
- * @trapno: Trap number reported in the signal to user space.
- *
- * This function is called by the low level machine check code
- * of an architecture when it detects hardware memory corruption
- * of a page. It tries its best to recover, which includes
- * dropping pages, killing processes etc.
- *
- * The function is primarily of use for corruptions that
- * happen outside the current execution context (e.g. when
- * detected by a background scrubber)
- *
- * Must run in process context (e.g. a work queue) with interrupts
- * enabled and no spinlocks hold.
- */
-void memory_failure(unsigned long pfn, int trapno)
-{
-	__memory_failure(pfn, trapno, 0);
-}
+EXPORT_SYMBOL_GPL(memory_failure);
 
 #define MEMORY_FAILURE_FIFO_ORDER	4
 #define MEMORY_FAILURE_FIFO_SIZE	(1 << MEMORY_FAILURE_FIFO_ORDER)
@@ -1251,7 +1255,7 @@ static void memory_failure_work_func(struct work_struct *work)
 		spin_unlock_irqrestore(&mf_cpu->lock, proc_flags);
 		if (!gotten)
 			break;
-		__memory_failure(entry.pfn, entry.trapno, entry.flags);
+		memory_failure(entry.pfn, entry.trapno, entry.flags);
 	}
 }
 
diff --git a/mm/memory.c b/mm/memory.c
index fa2f04e..7b0c26c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -160,24 +160,6 @@ static void check_sync_rss_stat(struct task_struct *task)
 		__sync_task_rss_stat(task, task->mm);
 }
 
-unsigned long get_mm_counter(struct mm_struct *mm, int member)
-{
-	long val = 0;
-
-	/*
-	 * Don't use task->mm here...for avoiding to use task_get_mm()..
-	 * The caller must guarantee task->mm is not invalid.
-	 */
-	val = atomic_long_read(&mm->rss_stat.count[member]);
-	/*
-	 * counter is updated in asynchronous manner and may go to minus.
-	 * But it's never be expected number for users.
-	 */
-	if (val < 0)
-		return 0;
-	return (unsigned long)val;
-}
-
 void sync_mm_rss(struct task_struct *task, struct mm_struct *mm)
 {
 	__sync_task_rss_stat(task, mm);
@@ -2447,7 +2429,7 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
 	 * fails, we just zero-fill it. Live with it.
 	 */
 	if (unlikely(!src)) {
-		void *kaddr = kmap_atomic(dst, KM_USER0);
+		void *kaddr = kmap_atomic(dst);
 		void __user *uaddr = (void __user *)(va & PAGE_MASK);
 
 		/*
@@ -2458,7 +2440,7 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
 		 */
 		if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
 			clear_page(kaddr);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		flush_dcache_page(dst);
 	} else
 		copy_user_highpage(dst, src, va, vma);
@@ -2880,6 +2862,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
 	struct mem_cgroup *ptr;
 	int exclusive = 0;
 	int ret = 0;
+	bool swap_token;
 
 	if (!pte_unmap_same(mm, pmd, page_table, orig_pte))
 		goto out;
@@ -2928,7 +2911,12 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
 		goto out_release;
 	}
 
+	swap_token = activate_swap_token(mm);
+
 	locked = lock_page_or_retry(page, mm, flags);
+
+	deactivate_swap_token(mm, swap_token);
+
 	delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
 	if (!locked) {
 		ret |= VM_FAULT_RETRY;
@@ -3175,6 +3163,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	struct vm_fault vmf;
 	int ret;
 	int page_mkwrite = 0;
+	bool swap_token;
 
 	/*
 	 * If we do COW later, allocate page befor taking lock_page()
@@ -3196,6 +3185,8 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	} else
 		cow_page = NULL;
 
+	swap_token = activate_swap_token(mm);
+
 	vmf.virtual_address = (void __user *)(address & PAGE_MASK);
 	vmf.pgoff = pgoff;
 	vmf.flags = flags;
@@ -3264,6 +3255,8 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 
 	}
 
+	deactivate_swap_token(mm, swap_token);
+
 	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
 
 	/*
@@ -3335,9 +3328,11 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	return ret;
 
 unwritable_page:
+	deactivate_swap_token(mm, swap_token);
 	page_cache_release(page);
 	return ret;
 uncharge_out:
+	deactivate_swap_token(mm, swap_token);
 	/* fs's fault handler get error */
 	if (cow_page) {
 		mem_cgroup_uncharge_page(cow_page);
diff --git a/mm/mmap.c b/mm/mmap.c
index 3f758c7..8fea0b5 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -30,6 +30,7 @@
 #include <linux/perf_event.h>
 #include <linux/audit.h>
 #include <linux/khugepaged.h>
+#include <linux/uprobes.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -217,6 +218,7 @@ void unlink_file_vma(struct vm_area_struct *vma)
 		mutex_lock(&mapping->i_mmap_mutex);
 		__remove_shared_vm_struct(vma, file, mapping);
 		mutex_unlock(&mapping->i_mmap_mutex);
+		munmap_uprobe(vma);
 	}
 }
 
@@ -545,8 +547,14 @@ again:			remove_next = 1 + (end > next->vm_end);
 
 	if (file) {
 		mapping = file->f_mapping;
-		if (!(vma->vm_flags & VM_NONLINEAR))
+		if (!(vma->vm_flags & VM_NONLINEAR)) {
 			root = &mapping->i_mmap;
+			munmap_uprobe(vma);
+
+			if (adjust_next)
+				munmap_uprobe(next);
+		}
+
 		mutex_lock(&mapping->i_mmap_mutex);
 		if (insert) {
 			/*
@@ -616,8 +624,16 @@ again:			remove_next = 1 + (end > next->vm_end);
 	if (mapping)
 		mutex_unlock(&mapping->i_mmap_mutex);
 
+	if (root) {
+		mmap_uprobe(vma);
+
+		if (adjust_next)
+			mmap_uprobe(next);
+	}
+
 	if (remove_next) {
 		if (file) {
+			munmap_uprobe(next);
 			fput(file);
 			if (next->vm_flags & VM_EXECUTABLE)
 				removed_exe_file_vma(mm);
@@ -637,6 +653,8 @@ again:			remove_next = 1 + (end > next->vm_end);
 			goto again;
 		}
 	}
+	if (insert && file)
+		mmap_uprobe(insert);
 
 	validate_mm(mm);
 
@@ -936,6 +954,19 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags,
 #endif /* CONFIG_PROC_FS */
 
 /*
+ * If a hint addr is less than mmap_min_addr change hint to be as
+ * low as possible but still greater than mmap_min_addr
+ */
+static inline unsigned long round_hint_to_min(unsigned long hint)
+{
+	hint &= PAGE_MASK;
+	if (((void *)hint != NULL) &&
+	    (hint < mmap_min_addr))
+		return PAGE_ALIGN(mmap_min_addr);
+	return hint;
+}
+
+/*
  * The caller must hold down_write(&current->mm->mmap_sem).
  */
 
@@ -1235,7 +1266,7 @@ munmap_back:
 	 */
 	if (accountable_mapping(file, vm_flags)) {
 		charged = len >> PAGE_SHIFT;
-		if (security_vm_enough_memory(charged))
+		if (security_vm_enough_memory_mm(mm, charged))
 			return -ENOMEM;
 		vm_flags |= VM_ACCOUNT;
 	}
@@ -1329,6 +1360,11 @@ out:
 			mm->locked_vm += (len >> PAGE_SHIFT);
 	} else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
 		make_pages_present(addr, addr + len);
+
+	if (file && mmap_uprobe(vma))
+		/* matching probes but cannot insert */
+		goto unmap_and_free_vma;
+
 	return addr;
 
 unmap_and_free_vma:
@@ -1423,10 +1459,8 @@ void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
 	/*
 	 * Is this a new hole at the lowest possible address?
 	 */
-	if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
+	if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache)
 		mm->free_area_cache = addr;
-		mm->cached_hole_size = ~0UL;
-	}
 }
 
 /*
@@ -1441,7 +1475,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 {
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
-	unsigned long addr = addr0;
+	unsigned long addr = addr0, start_addr;
 
 	/* requested length too big for entire address space */
 	if (len > TASK_SIZE)
@@ -1465,22 +1499,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
  		mm->free_area_cache = mm->mmap_base;
  	}
 
+try_again:
 	/* either no address requested or can't fit in requested address hole */
-	addr = mm->free_area_cache;
+	start_addr = addr = mm->free_area_cache;
 
-	/* make sure it can fit in the remaining address space */
-	if (addr > len) {
-		vma = find_vma(mm, addr-len);
-		if (!vma || addr <= vma->vm_start)
-			/* remember the address as a hint for next time */
-			return (mm->free_area_cache = addr-len);
-	}
-
-	if (mm->mmap_base < len)
-		goto bottomup;
-
-	addr = mm->mmap_base-len;
+	if (addr < len)
+		goto fail;
 
+	addr -= len;
 	do {
 		/*
 		 * Lookup failure means no vma is above this address,
@@ -1500,7 +1526,21 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
 		addr = vma->vm_start-len;
 	} while (len < vma->vm_start);
 
-bottomup:
+fail:
+	/*
+	 * if hint left us with no space for the requested
+	 * mapping then try again:
+	 *
+	 * Note: this is different with the case of bottomup
+	 * which does the fully line-search, but we use find_vma
+	 * here that causes some holes skipped.
+	 */
+	if (start_addr != mm->mmap_base) {
+		mm->free_area_cache = mm->mmap_base;
+		mm->cached_hole_size = 0;
+		goto try_again;
+	}
+
 	/*
 	 * A failed mmap() very likely causes application failure,
 	 * so fall back to the bottom-up function here. This scenario
@@ -2169,7 +2209,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
 	if (mm->map_count > sysctl_max_map_count)
 		return -ENOMEM;
 
-	if (security_vm_enough_memory(len >> PAGE_SHIFT))
+	if (security_vm_enough_memory_mm(mm, len >> PAGE_SHIFT))
 		return -ENOMEM;
 
 	/* Can we just expand an old private anonymous mapping? */
@@ -2285,6 +2325,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
 	if ((vma->vm_flags & VM_ACCOUNT) &&
 	     security_vm_enough_memory_mm(mm, vma_pages(vma)))
 		return -ENOMEM;
+
+	if (vma->vm_file && mmap_uprobe(vma))
+		return -EINVAL;
+
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	return 0;
 }
@@ -2354,6 +2398,10 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
 			new_vma->vm_pgoff = pgoff;
 			if (new_vma->vm_file) {
 				get_file(new_vma->vm_file);
+
+				if (mmap_uprobe(new_vma))
+					goto out_free_mempol;
+
 				if (vma->vm_flags & VM_EXECUTABLE)
 					added_exe_file_vma(mm);
 			}
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 5a688a2..c0dec61 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -60,7 +60,7 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
 				ptent = pte_mkwrite(ptent);
 
 			ptep_modify_prot_commit(mm, addr, pte, ptent);
-		} else if (PAGE_MIGRATION && !pte_file(oldpte)) {
+		} else if (IS_ENABLED(CONFIG_MIGRATION) && !pte_file(oldpte)) {
 			swp_entry_t entry = pte_to_swp_entry(oldpte);
 
 			if (is_write_migration_entry(entry)) {
@@ -168,7 +168,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 		if (!(oldflags & (VM_ACCOUNT|VM_WRITE|VM_HUGETLB|
 						VM_SHARED|VM_NORESERVE))) {
 			charged = nrpages;
-			if (security_vm_enough_memory(charged))
+			if (security_vm_enough_memory_mm(mm, charged))
 				return -ENOMEM;
 			newflags |= VM_ACCOUNT;
 		}
diff --git a/mm/mremap.c b/mm/mremap.c
index 87bb839..cbe2f3c 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -155,8 +155,6 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
 			if (err > 0) {
 				need_flush = true;
 				continue;
-			} else if (!err) {
-				split_huge_page_pmd(vma->vm_mm, old_pmd);
 			}
 			VM_BUG_ON(pmd_trans_huge(*old_pmd));
 		}
@@ -329,7 +327,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
 
 	if (vma->vm_flags & VM_ACCOUNT) {
 		unsigned long charged = (new_len - old_len) >> PAGE_SHIFT;
-		if (security_vm_enough_memory(charged))
+		if (security_vm_enough_memory_mm(mm, charged))
 			goto Efault;
 		*p = charged;
 	}
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 2958fd8..ba8d0dc 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -34,6 +34,7 @@
 #include <linux/ptrace.h>
 #include <linux/freezer.h>
 #include <linux/ftrace.h>
+#include <linux/ratelimit.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/oom.h>
@@ -434,66 +435,18 @@ static void dump_header(struct task_struct *p, gfp_t gfp_mask, int order,
 }
 
 #define K(x) ((x) << (PAGE_SHIFT-10))
-static int oom_kill_task(struct task_struct *p)
-{
-	struct task_struct *q;
-	struct mm_struct *mm;
-
-	p = find_lock_task_mm(p);
-	if (!p)
-		return 1;
-
-	/* mm cannot be safely dereferenced after task_unlock(p) */
-	mm = p->mm;
-
-	pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
-		task_pid_nr(p), p->comm, K(p->mm->total_vm),
-		K(get_mm_counter(p->mm, MM_ANONPAGES)),
-		K(get_mm_counter(p->mm, MM_FILEPAGES)));
-	task_unlock(p);
-
-	/*
-	 * Kill all user processes sharing p->mm in other thread groups, if any.
-	 * They don't get access to memory reserves or a higher scheduler
-	 * priority, though, to avoid depletion of all memory or task
-	 * starvation.  This prevents mm->mmap_sem livelock when an oom killed
-	 * task cannot exit because it requires the semaphore and its contended
-	 * by another thread trying to allocate memory itself.  That thread will
-	 * now get access to memory reserves since it has a pending fatal
-	 * signal.
-	 */
-	for_each_process(q)
-		if (q->mm == mm && !same_thread_group(q, p) &&
-		    !(q->flags & PF_KTHREAD)) {
-			if (q->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
-				continue;
-
-			task_lock(q);	/* Protect ->comm from prctl() */
-			pr_err("Kill process %d (%s) sharing same memory\n",
-				task_pid_nr(q), q->comm);
-			task_unlock(q);
-			force_sig(SIGKILL, q);
-		}
-
-	set_tsk_thread_flag(p, TIF_MEMDIE);
-	force_sig(SIGKILL, p);
-
-	return 0;
-}
-#undef K
-
-static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
-			    unsigned int points, unsigned long totalpages,
-			    struct mem_cgroup *memcg, nodemask_t *nodemask,
-			    const char *message)
+static void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
+			     unsigned int points, unsigned long totalpages,
+			     struct mem_cgroup *memcg, nodemask_t *nodemask,
+			     const char *message)
 {
 	struct task_struct *victim = p;
 	struct task_struct *child;
 	struct task_struct *t = p;
+	struct mm_struct *mm;
 	unsigned int victim_points = 0;
-
-	if (printk_ratelimit())
-		dump_header(p, gfp_mask, order, memcg, nodemask);
+	static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
+					      DEFAULT_RATELIMIT_BURST);
 
 	/*
 	 * If the task is already exiting, don't alarm the sysadmin or kill
@@ -501,9 +454,12 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
 	 */
 	if (p->flags & PF_EXITING) {
 		set_tsk_thread_flag(p, TIF_MEMDIE);
-		return 0;
+		return;
 	}
 
+	if (__ratelimit(&oom_rs))
+		dump_header(p, gfp_mask, order, memcg, nodemask);
+
 	task_lock(p);
 	pr_err("%s: Kill process %d (%s) score %d or sacrifice child\n",
 		message, task_pid_nr(p), p->comm, points);
@@ -533,8 +489,44 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
 		}
 	} while_each_thread(p, t);
 
-	return oom_kill_task(victim);
+	victim = find_lock_task_mm(victim);
+	if (!victim)
+		return;
+
+	/* mm cannot safely be dereferenced after task_unlock(victim) */
+	mm = victim->mm;
+	pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB\n",
+		task_pid_nr(victim), victim->comm, K(victim->mm->total_vm),
+		K(get_mm_counter(victim->mm, MM_ANONPAGES)),
+		K(get_mm_counter(victim->mm, MM_FILEPAGES)));
+	task_unlock(victim);
+
+	/*
+	 * Kill all user processes sharing victim->mm in other thread groups, if
+	 * any.  They don't get access to memory reserves, though, to avoid
+	 * depletion of all memory.  This prevents mm->mmap_sem livelock when an
+	 * oom killed thread cannot exit because it requires the semaphore and
+	 * its contended by another thread trying to allocate memory itself.
+	 * That thread will now get access to memory reserves since it has a
+	 * pending fatal signal.
+	 */
+	for_each_process(p)
+		if (p->mm == mm && !same_thread_group(p, victim) &&
+		    !(p->flags & PF_KTHREAD)) {
+			if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
+				continue;
+
+			task_lock(p);	/* Protect ->comm from prctl() */
+			pr_err("Kill process %d (%s) sharing same memory\n",
+				task_pid_nr(p), p->comm);
+			task_unlock(p);
+			do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true);
+		}
+
+	set_tsk_thread_flag(victim, TIF_MEMDIE);
+	do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
 }
+#undef K
 
 /*
  * Determines whether the kernel must panic because of the panic_on_oom sysctl.
@@ -580,15 +572,10 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask)
 	check_panic_on_oom(CONSTRAINT_MEMCG, gfp_mask, 0, NULL);
 	limit = mem_cgroup_get_limit(memcg) >> PAGE_SHIFT;
 	read_lock(&tasklist_lock);
-retry:
 	p = select_bad_process(&points, limit, memcg, NULL);
-	if (!p || PTR_ERR(p) == -1UL)
-		goto out;
-
-	if (oom_kill_process(p, gfp_mask, 0, points, limit, memcg, NULL,
-				"Memory cgroup out of memory"))
-		goto retry;
-out:
+	if (p && PTR_ERR(p) != -1UL)
+		oom_kill_process(p, gfp_mask, 0, points, limit, memcg, NULL,
+				 "Memory cgroup out of memory");
 	read_unlock(&tasklist_lock);
 }
 #endif
@@ -745,33 +732,24 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
 	if (sysctl_oom_kill_allocating_task &&
 	    !oom_unkillable_task(current, NULL, nodemask) &&
 	    current->mm) {
-		/*
-		 * oom_kill_process() needs tasklist_lock held.  If it returns
-		 * non-zero, current could not be killed so we must fallback to
-		 * the tasklist scan.
-		 */
-		if (!oom_kill_process(current, gfp_mask, order, 0, totalpages,
-				NULL, nodemask,
-				"Out of memory (oom_kill_allocating_task)"))
-			goto out;
+		oom_kill_process(current, gfp_mask, order, 0, totalpages, NULL,
+				 nodemask,
+				 "Out of memory (oom_kill_allocating_task)");
+		goto out;
 	}
 
-retry:
 	p = select_bad_process(&points, totalpages, NULL, mpol_mask);
-	if (PTR_ERR(p) == -1UL)
-		goto out;
-
 	/* Found nothing?!?! Either we hang forever, or we panic. */
 	if (!p) {
 		dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
 		read_unlock(&tasklist_lock);
 		panic("Out of memory and no killable processes...\n");
 	}
-
-	if (oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
-				nodemask, "Out of memory"))
-		goto retry;
-	killed = 1;
+	if (PTR_ERR(p) != -1UL) {
+		oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
+				 nodemask, "Out of memory");
+		killed = 1;
+	}
 out:
 	read_unlock(&tasklist_lock);
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d2186ec..896cd4f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -191,8 +191,21 @@ static char * const zone_names[MAX_NR_ZONES] = {
 	 "Movable",
 };
 
+/*
+ * Try to keep at least this much lowmem free.  Do not allow normal
+ * allocations below this point, only high priority ones. Automatically
+ * tuned according to the amount of memory in the system.
+ */
 int min_free_kbytes = 1024;
 
+/*
+ * Extra memory for the system to try freeing between the min and
+ * low watermarks.  Useful for workloads that require low latency
+ * memory allocations in bursts larger than the normal gap between
+ * low and min.
+ */
+int extra_free_kbytes;
+
 static unsigned long __meminitdata nr_kernel_pages;
 static unsigned long __meminitdata nr_all_pages;
 static unsigned long __meminitdata dma_reserve;
@@ -1161,11 +1174,47 @@ void drain_local_pages(void *arg)
 }
 
 /*
- * Spill all the per-cpu pages from all CPUs back into the buddy allocator
+ * Spill all the per-cpu pages from all CPUs back into the buddy allocator.
+ *
+ * Note that this code is protected against sending an IPI to an offline
+ * CPU but does not guarantee sending an IPI to newly hotplugged CPUs:
+ * on_each_cpu_mask() blocks hotplug and won't talk to offlined CPUs but
+ * nothing keeps CPUs from showing up after we populated the cpumask and
+ * before the call to on_each_cpu_mask().
  */
 void drain_all_pages(void)
 {
-	on_each_cpu(drain_local_pages, NULL, 1);
+	int cpu;
+	struct per_cpu_pageset *pcp;
+	struct zone *zone;
+
+	/*
+	 * Allocate in the BSS so we wont require allocation in
+	 * direct reclaim path for CONFIG_CPUMASK_OFFSTACK=y
+	 */
+	static cpumask_t cpus_with_pcps;
+
+	/*
+	 * We don't care about racing with CPU hotplug event
+	 * as offline notification will cause the notified
+	 * cpu to drain that CPU pcps and on_each_cpu_mask
+	 * disables preemption as part of its processing
+	 */
+	for_each_online_cpu(cpu) {
+		bool has_pcps = false;
+		for_each_populated_zone(zone) {
+			pcp = per_cpu_ptr(zone->pageset, cpu);
+			if (pcp->pcp.count) {
+				has_pcps = true;
+				break;
+			}
+		}
+		if (has_pcps)
+			cpumask_set_cpu(cpu, &cpus_with_pcps);
+		else
+			cpumask_clear_cpu(cpu, &cpus_with_pcps);
+	}
+	on_each_cpu_mask(&cpus_with_pcps, drain_local_pages, NULL, 1);
 }
 
 #ifdef CONFIG_HIBERNATION
@@ -1990,7 +2039,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 	if (!order)
 		return NULL;
 
-	if (compaction_deferred(preferred_zone)) {
+	if (compaction_deferred(preferred_zone, order)) {
 		*deferred_compaction = true;
 		return NULL;
 	}
@@ -2012,6 +2061,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 		if (page) {
 			preferred_zone->compact_considered = 0;
 			preferred_zone->compact_defer_shift = 0;
+			if (order >= preferred_zone->compact_order_failed)
+				preferred_zone->compact_order_failed = order + 1;
 			count_vm_event(COMPACTSUCCESS);
 			return page;
 		}
@@ -2028,7 +2079,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
 		 * defer if the failure was a sync compaction failure.
 		 */
 		if (sync_migration)
-			defer_compaction(preferred_zone);
+			defer_compaction(preferred_zone, order);
 
 		cond_resched();
 	}
@@ -4942,6 +4993,7 @@ static void setup_per_zone_lowmem_reserve(void)
 void setup_per_zone_wmarks(void)
 {
 	unsigned long pages_min = min_free_kbytes >> (PAGE_SHIFT - 10);
+	unsigned long pages_low = extra_free_kbytes >> (PAGE_SHIFT - 10);
 	unsigned long lowmem_pages = 0;
 	struct zone *zone;
 	unsigned long flags;
@@ -4953,11 +5005,14 @@ void setup_per_zone_wmarks(void)
 	}
 
 	for_each_zone(zone) {
-		u64 tmp;
+		u64 min, low;
 
 		spin_lock_irqsave(&zone->lock, flags);
-		tmp = (u64)pages_min * zone->present_pages;
-		do_div(tmp, lowmem_pages);
+		min = (u64)pages_min * zone->present_pages;
+		do_div(min, lowmem_pages);
+		low = (u64)pages_low * zone->present_pages;
+		do_div(low, vm_total_pages);
+
 		if (is_highmem(zone)) {
 			/*
 			 * __GFP_HIGH and PF_MEMALLOC allocations usually don't
@@ -4981,11 +5036,13 @@ void setup_per_zone_wmarks(void)
 			 * If it's a lowmem zone, reserve a number of pages
 			 * proportionate to the zone's size.
 			 */
-			zone->watermark[WMARK_MIN] = tmp;
+			zone->watermark[WMARK_MIN] = min;
 		}
 
-		zone->watermark[WMARK_LOW]  = min_wmark_pages(zone) + (tmp >> 2);
-		zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) + (tmp >> 1);
+		zone->watermark[WMARK_LOW]  = min_wmark_pages(zone) +
+					low + (min >> 2);
+		zone->watermark[WMARK_HIGH] = min_wmark_pages(zone) +
+					low + (min >> 1);
 		setup_zone_migrate_reserve(zone);
 		spin_unlock_irqrestore(&zone->lock, flags);
 	}
@@ -5081,11 +5138,11 @@ int __meminit init_per_zone_wmark_min(void)
 module_init(init_per_zone_wmark_min)
 
 /*
- * min_free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so 
+ * free_kbytes_sysctl_handler - just a wrapper around proc_dointvec() so
  *	that we can call two helper functions whenever min_free_kbytes
- *	changes.
+ *	or extra_free_kbytes changes.
  */
-int min_free_kbytes_sysctl_handler(ctl_table *table, int write, 
+int free_kbytes_sysctl_handler(ctl_table *table, int write,
 	void __user *buffer, size_t *length, loff_t *ppos)
 {
 	proc_dointvec(table, write, buffer, length, ppos);
@@ -5236,6 +5293,7 @@ void *__init alloc_large_system_hash(const char *tablename,
 		max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
 		do_div(max, bucketsize);
 	}
+	max = min(max, 0x80000000ULL);
 
 	if (numentries > max)
 		numentries = max;
diff --git a/mm/page_io.c b/mm/page_io.c
index dc76b4d..651a912 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -18,6 +18,7 @@
 #include <linux/bio.h>
 #include <linux/swapops.h>
 #include <linux/writeback.h>
+#include <linux/frontswap.h>
 #include <asm/pgtable.h>
 
 static struct bio *get_swap_bio(gfp_t gfp_flags,
@@ -98,6 +99,12 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)
 		unlock_page(page);
 		goto out;
 	}
+	if (frontswap_put_page(page) == 0) {
+		set_page_writeback(page);
+		unlock_page(page);
+		end_page_writeback(page);
+		goto out;
+	}
 	bio = get_swap_bio(GFP_NOIO, page, end_swap_bio_write);
 	if (bio == NULL) {
 		set_page_dirty(page);
@@ -122,6 +129,11 @@ int swap_readpage(struct page *page)
 
 	VM_BUG_ON(!PageLocked(page));
 	VM_BUG_ON(PageUptodate(page));
+	if (frontswap_get_page(page) == 0) {
+		SetPageUptodate(page);
+		unlock_page(page);
+		goto out;
+	}
 	bio = get_swap_bio(GFP_KERNEL, page, end_swap_bio_read);
 	if (bio == NULL) {
 		unlock_page(page);
diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c
index 12a48a88..405d331 100644
--- a/mm/percpu-vm.c
+++ b/mm/percpu-vm.c
@@ -184,8 +184,7 @@ static void pcpu_unmap_pages(struct pcpu_chunk *chunk,
 				   page_end - page_start);
 	}
 
-	for (i = page_start; i < page_end; i++)
-		__clear_bit(i, populated);
+	bitmap_clear(populated, page_start, page_end - page_start);
 }
 
 /**
diff --git a/mm/rmap.c b/mm/rmap.c
index c8454e0..5b3dca4 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -760,8 +760,7 @@ int page_referenced_one(struct page *page, struct vm_area_struct *vma,
 
 	/* Pretend the page is referenced if the task has the
 	   swap token and is in the middle of a page fault. */
-	if (mm != current->mm && has_swap_token(mm) &&
-			rwsem_is_locked(&mm->mmap_sem))
+	if (mm != current->mm && has_active_swap_token(mm))
 		referenced++;
 
 	(*mapcount)--;
@@ -1282,7 +1281,7 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 			}
 			dec_mm_counter(mm, MM_ANONPAGES);
 			inc_mm_counter(mm, MM_SWAPENTS);
-		} else if (PAGE_MIGRATION) {
+		} else if (IS_ENABLED(CONFIG_MIGRATION)) {
 			/*
 			 * Store the pfn of the page in a special migration
 			 * pte. do_swap_page() will wait until the migration
@@ -1293,7 +1292,8 @@ int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 		}
 		set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
 		BUG_ON(pte_file(*pte));
-	} else if (PAGE_MIGRATION && (TTU_ACTION(flags) == TTU_MIGRATION)) {
+	} else if (IS_ENABLED(CONFIG_MIGRATION) &&
+		   (TTU_ACTION(flags) == TTU_MIGRATION)) {
 		/* Establish migration entry for a file page */
 		swp_entry_t entry;
 		entry = make_migration_entry(page, pte_write(pteval));
@@ -1499,7 +1499,7 @@ static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
 		 * locking requirements of exec(), migration skips
 		 * temporary VMAs until after exec() completes.
 		 */
-		if (PAGE_MIGRATION && (flags & TTU_MIGRATION) &&
+		if (IS_ENABLED(CONFIG_MIGRATION) && (flags & TTU_MIGRATION) &&
 				is_vma_temporary_stack(vma))
 			continue;
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 269d049..7a45ad0 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -127,7 +127,7 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb)
 static inline int shmem_acct_size(unsigned long flags, loff_t size)
 {
 	return (flags & VM_NORESERVE) ?
-		0 : security_vm_enough_memory_kern(VM_ACCT(size));
+		0 : security_vm_enough_memory_mm(current->mm, VM_ACCT(size));
 }
 
 static inline void shmem_unacct_size(unsigned long flags, loff_t size)
@@ -145,7 +145,7 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size)
 static inline int shmem_acct_block(unsigned long flags)
 {
 	return (flags & VM_NORESERVE) ?
-		security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)) : 0;
+		security_vm_enough_memory_mm(current->mm, VM_ACCT(PAGE_CACHE_SIZE)) : 0;
 }
 
 static inline void shmem_unacct_blocks(unsigned long flags, long pages)
@@ -1656,9 +1656,9 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
 		}
 		inode->i_mapping->a_ops = &shmem_aops;
 		inode->i_op = &shmem_symlink_inode_operations;
-		kaddr = kmap_atomic(page, KM_USER0);
+		kaddr = kmap_atomic(page);
 		memcpy(kaddr, symname, len);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 		set_page_dirty(page);
 		unlock_page(page);
 		page_cache_release(page);
@@ -2175,7 +2175,6 @@ static void shmem_put_super(struct super_block *sb)
 int shmem_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
-	struct dentry *root;
 	struct shmem_sb_info *sbinfo;
 	int err = -ENOMEM;
 
@@ -2232,14 +2231,11 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed;
 	inode->i_uid = sbinfo->uid;
 	inode->i_gid = sbinfo->gid;
-	root = d_alloc_root(inode);
-	if (!root)
-		goto failed_iput;
-	sb->s_root = root;
+	sb->s_root = d_make_root(inode);
+	if (!sb->s_root)
+		goto failed;
 	return 0;
 
-failed_iput:
-	iput(inode);
 failed:
 	shmem_put_super(sb);
 	return err;
diff --git a/mm/slab.c b/mm/slab.c
index f0bd785..806a754 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3693,13 +3693,12 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp,
 
 	if (likely(ac->avail < ac->limit)) {
 		STATS_INC_FREEHIT(cachep);
-		ac->entry[ac->avail++] = objp;
-		return;
 	} else {
 		STATS_INC_FREEMISS(cachep);
 		cache_flusharray(cachep, ac);
-		ac->entry[ac->avail++] = objp;
 	}
+
+	ac->entry[ac->avail++] = objp;
 }
 
 /**
diff --git a/mm/slub.c b/mm/slub.c
index 4907563..33bab2a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -29,6 +29,7 @@
 #include <linux/math64.h>
 #include <linux/fault-inject.h>
 #include <linux/stacktrace.h>
+#include <linux/prefetch.h>
 
 #include <trace/events/kmem.h>
 
@@ -269,6 +270,11 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object)
 	return *(void **)(object + s->offset);
 }
 
+static void prefetch_freepointer(const struct kmem_cache *s, void *object)
+{
+	prefetch(object + s->offset);
+}
+
 static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
 {
 	void *p;
@@ -1484,12 +1490,12 @@ static inline void remove_partial(struct kmem_cache_node *n,
 }
 
 /*
- * Lock slab, remove from the partial list and put the object into the
- * per cpu freelist.
+ * Remove slab from the partial list, freeze it and
+ * return the pointer to the freelist.
  *
  * Returns a list of objects or NULL if it fails.
  *
- * Must hold list_lock.
+ * Must hold list_lock since we modify the partial list.
  */
 static inline void *acquire_slab(struct kmem_cache *s,
 		struct kmem_cache_node *n, struct page *page,
@@ -1504,22 +1510,24 @@ static inline void *acquire_slab(struct kmem_cache *s,
 	 * The old freelist is the list of objects for the
 	 * per cpu allocation list.
 	 */
-	do {
-		freelist = page->freelist;
-		counters = page->counters;
-		new.counters = counters;
-		if (mode)
-			new.inuse = page->objects;
+	freelist = page->freelist;
+	counters = page->counters;
+	new.counters = counters;
+	if (mode)
+		new.inuse = page->objects;
 
-		VM_BUG_ON(new.frozen);
-		new.frozen = 1;
+	VM_BUG_ON(new.frozen);
+	new.frozen = 1;
 
-	} while (!__cmpxchg_double_slab(s, page,
+	if (!__cmpxchg_double_slab(s, page,
 			freelist, counters,
 			NULL, new.counters,
-			"lock and freeze"));
+			"acquire_slab"))
+
+		return NULL;
 
 	remove_partial(n, page);
+	WARN_ON(!freelist);
 	return freelist;
 }
 
@@ -1553,13 +1561,13 @@ static void *get_partial_node(struct kmem_cache *s,
 
 		if (!object) {
 			c->page = page;
-			c->node = page_to_nid(page);
 			stat(s, ALLOC_FROM_PARTIAL);
 			object = t;
 			available =  page->objects - page->inuse;
 		} else {
 			page->freelist = t;
 			available = put_cpu_partial(s, page, 0);
+			stat(s, CPU_PARTIAL_NODE);
 		}
 		if (kmem_cache_debug(s) || available > s->cpu_partial / 2)
 			break;
@@ -1711,14 +1719,12 @@ void init_kmem_cache_cpus(struct kmem_cache *s)
 /*
  * Remove the cpu slab
  */
-static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
+static void deactivate_slab(struct kmem_cache *s, struct page *page, void *freelist)
 {
 	enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
-	struct page *page = c->page;
 	struct kmem_cache_node *n = get_node(s, page_to_nid(page));
 	int lock = 0;
 	enum slab_modes l = M_NONE, m = M_NONE;
-	void *freelist;
 	void *nextfree;
 	int tail = DEACTIVATE_TO_HEAD;
 	struct page new;
@@ -1729,11 +1735,6 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 		tail = DEACTIVATE_TO_TAIL;
 	}
 
-	c->tid = next_tid(c->tid);
-	c->page = NULL;
-	freelist = c->freelist;
-	c->freelist = NULL;
-
 	/*
 	 * Stage one: Free all available per cpu objects back
 	 * to the page freelist while it is still frozen. Leave the
@@ -1973,6 +1974,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
 				local_irq_restore(flags);
 				pobjects = 0;
 				pages = 0;
+				stat(s, CPU_PARTIAL_DRAIN);
 			}
 		}
 
@@ -1984,14 +1986,17 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
 		page->next = oldpage;
 
 	} while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
-	stat(s, CPU_PARTIAL_FREE);
 	return pobjects;
 }
 
 static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
 {
 	stat(s, CPUSLAB_FLUSH);
-	deactivate_slab(s, c);
+	deactivate_slab(s, c->page, c->freelist);
+
+	c->tid = next_tid(c->tid);
+	c->page = NULL;
+	c->freelist = NULL;
 }
 
 /*
@@ -2018,19 +2023,27 @@ static void flush_cpu_slab(void *d)
 	__flush_cpu_slab(s, smp_processor_id());
 }
 
+static bool has_cpu_slab(int cpu, void *info)
+{
+	struct kmem_cache *s = info;
+	struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
+
+	return !!(c->page);
+}
+
 static void flush_all(struct kmem_cache *s)
 {
-	on_each_cpu(flush_cpu_slab, s, 1);
+	on_each_cpu_cond(has_cpu_slab, flush_cpu_slab, s, 1, GFP_ATOMIC);
 }
 
 /*
  * Check if the objects in a per cpu structure fit numa
  * locality expectations.
  */
-static inline int node_match(struct kmem_cache_cpu *c, int node)
+static inline int node_match(struct page *page, int node)
 {
 #ifdef CONFIG_NUMA
-	if (node != NUMA_NO_NODE && c->node != node)
+	if (node != NUMA_NO_NODE && page_to_nid(page) != node)
 		return 0;
 #endif
 	return 1;
@@ -2102,10 +2115,16 @@ slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
 static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
 			int node, struct kmem_cache_cpu **pc)
 {
-	void *object;
-	struct kmem_cache_cpu *c;
-	struct page *page = new_slab(s, flags, node);
+	void *freelist;
+	struct kmem_cache_cpu *c = *pc;
+	struct page *page;
 
+	freelist = get_partial(s, flags, node, c);
+
+	if (freelist)
+		return freelist;
+
+	page = new_slab(s, flags, node);
 	if (page) {
 		c = __this_cpu_ptr(s->cpu_slab);
 		if (c->page)
@@ -2115,17 +2134,16 @@ static inline void *new_slab_objects(struct kmem_cache *s, gfp_t flags,
 		 * No other reference to the page yet so we can
 		 * muck around with it freely without cmpxchg
 		 */
-		object = page->freelist;
+		freelist = page->freelist;
 		page->freelist = NULL;
 
 		stat(s, ALLOC_SLAB);
-		c->node = page_to_nid(page);
 		c->page = page;
 		*pc = c;
 	} else
-		object = NULL;
+		freelist = NULL;
 
-	return object;
+	return freelist;
 }
 
 /*
@@ -2145,6 +2163,7 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
 	do {
 		freelist = page->freelist;
 		counters = page->counters;
+
 		new.counters = counters;
 		VM_BUG_ON(!new.frozen);
 
@@ -2178,7 +2197,8 @@ static inline void *get_freelist(struct kmem_cache *s, struct page *page)
 static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
 			  unsigned long addr, struct kmem_cache_cpu *c)
 {
-	void **object;
+	void *freelist;
+	struct page *page;
 	unsigned long flags;
 
 	local_irq_save(flags);
@@ -2191,25 +2211,29 @@ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
 	c = this_cpu_ptr(s->cpu_slab);
 #endif
 
-	if (!c->page)
+	page = c->page;
+	if (!page)
 		goto new_slab;
 redo:
-	if (unlikely(!node_match(c, node))) {
+
+	if (unlikely(!node_match(page, node))) {
 		stat(s, ALLOC_NODE_MISMATCH);
-		deactivate_slab(s, c);
+		deactivate_slab(s, page, c->freelist);
+		c->page = NULL;
+		c->freelist = NULL;
 		goto new_slab;
 	}
 
 	/* must check again c->freelist in case of cpu migration or IRQ */
-	object = c->freelist;
-	if (object)
+	freelist = c->freelist;
+	if (freelist)
 		goto load_freelist;
 
 	stat(s, ALLOC_SLOWPATH);
 
-	object = get_freelist(s, c->page);
+	freelist = get_freelist(s, page);
 
-	if (!object) {
+	if (!freelist) {
 		c->page = NULL;
 		stat(s, DEACTIVATE_BYPASS);
 		goto new_slab;
@@ -2218,50 +2242,50 @@ redo:
 	stat(s, ALLOC_REFILL);
 
 load_freelist:
-	c->freelist = get_freepointer(s, object);
+	/*
+	 * freelist is pointing to the list of objects to be used.
+	 * page is pointing to the page from which the objects are obtained.
+	 * That page must be frozen for per cpu allocations to work.
+	 */
+	VM_BUG_ON(!c->page->frozen);
+	c->freelist = get_freepointer(s, freelist);
 	c->tid = next_tid(c->tid);
 	local_irq_restore(flags);
-	return object;
+	return freelist;
 
 new_slab:
 
 	if (c->partial) {
-		c->page = c->partial;
-		c->partial = c->page->next;
-		c->node = page_to_nid(c->page);
+		page = c->page = c->partial;
+		c->partial = page->next;
 		stat(s, CPU_PARTIAL_ALLOC);
 		c->freelist = NULL;
 		goto redo;
 	}
 
-	/* Then do expensive stuff like retrieving pages from the partial lists */
-	object = get_partial(s, gfpflags, node, c);
+	freelist = new_slab_objects(s, gfpflags, node, &c);
 
-	if (unlikely(!object)) {
+	if (unlikely(!freelist)) {
+		if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
+			slab_out_of_memory(s, gfpflags, node);
 
-		object = new_slab_objects(s, gfpflags, node, &c);
-
-		if (unlikely(!object)) {
-			if (!(gfpflags & __GFP_NOWARN) && printk_ratelimit())
-				slab_out_of_memory(s, gfpflags, node);
-
-			local_irq_restore(flags);
-			return NULL;
-		}
+		local_irq_restore(flags);
+		return NULL;
 	}
 
+	page = c->page;
 	if (likely(!kmem_cache_debug(s)))
 		goto load_freelist;
 
 	/* Only entered in the debug case */
-	if (!alloc_debug_processing(s, c->page, object, addr))
+	if (!alloc_debug_processing(s, page, freelist, addr))
 		goto new_slab;	/* Slab failed checks. Next slab needed */
 
-	c->freelist = get_freepointer(s, object);
-	deactivate_slab(s, c);
-	c->node = NUMA_NO_NODE;
+	deactivate_slab(s, page, get_freepointer(s, freelist));
+	c->page = NULL;
+	c->freelist = NULL;
 	local_irq_restore(flags);
-	return object;
+	return freelist;
 }
 
 /*
@@ -2279,6 +2303,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
 {
 	void **object;
 	struct kmem_cache_cpu *c;
+	struct page *page;
 	unsigned long tid;
 
 	if (slab_pre_alloc_hook(s, gfpflags))
@@ -2304,11 +2329,14 @@ redo:
 	barrier();
 
 	object = c->freelist;
-	if (unlikely(!object || !node_match(c, node)))
+	page = c->page;
+	if (unlikely(!object || !node_match(page, node)))
 
 		object = __slab_alloc(s, gfpflags, node, addr, c);
 
 	else {
+		void *next_object = get_freepointer_safe(s, object);
+
 		/*
 		 * The cmpxchg will only match if there was no additional
 		 * operation and if we are on the right processor.
@@ -2324,11 +2352,12 @@ redo:
 		if (unlikely(!this_cpu_cmpxchg_double(
 				s->cpu_slab->freelist, s->cpu_slab->tid,
 				object, tid,
-				get_freepointer_safe(s, object), next_tid(tid)))) {
+				next_object, next_tid(tid)))) {
 
 			note_cmpxchg_failure("slab_alloc", s, tid);
 			goto redo;
 		}
+		prefetch_freepointer(s, next_object);
 		stat(s, ALLOC_FASTPATH);
 	}
 
@@ -2465,9 +2494,10 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
 		 * If we just froze the page then put it onto the
 		 * per cpu partial list.
 		 */
-		if (new.frozen && !was_frozen)
+		if (new.frozen && !was_frozen) {
 			put_cpu_partial(s, page, 1);
-
+			stat(s, CPU_PARTIAL_FREE);
+		}
 		/*
 		 * The list lock was not taken therefore no list
 		 * activity can be necessary.
@@ -3929,13 +3959,14 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
 		if (kmem_cache_open(s, n,
 				size, align, flags, ctor)) {
 			list_add(&s->list, &slab_caches);
+			up_write(&slub_lock);
 			if (sysfs_slab_add(s)) {
+				down_write(&slub_lock);
 				list_del(&s->list);
 				kfree(n);
 				kfree(s);
 				goto err;
 			}
-			up_write(&slub_lock);
 			return s;
 		}
 		kfree(n);
@@ -4467,30 +4498,31 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
 
 		for_each_possible_cpu(cpu) {
 			struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
-			int node = ACCESS_ONCE(c->node);
+			int node;
 			struct page *page;
 
-			if (node < 0)
-				continue;
 			page = ACCESS_ONCE(c->page);
-			if (page) {
-				if (flags & SO_TOTAL)
-					x = page->objects;
-				else if (flags & SO_OBJECTS)
-					x = page->inuse;
-				else
-					x = 1;
+			if (!page)
+				continue;
 
-				total += x;
-				nodes[node] += x;
-			}
-			page = c->partial;
+			node = page_to_nid(page);
+			if (flags & SO_TOTAL)
+				x = page->objects;
+			else if (flags & SO_OBJECTS)
+				x = page->inuse;
+			else
+				x = 1;
 
+			total += x;
+			nodes[node] += x;
+
+			page = ACCESS_ONCE(c->partial);
 			if (page) {
 				x = page->pobjects;
 				total += x;
 				nodes[node] += x;
 			}
+
 			per_cpu[node]++;
 		}
 	}
@@ -5059,6 +5091,8 @@ STAT_ATTR(CMPXCHG_DOUBLE_CPU_FAIL, cmpxchg_double_cpu_fail);
 STAT_ATTR(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail);
 STAT_ATTR(CPU_PARTIAL_ALLOC, cpu_partial_alloc);
 STAT_ATTR(CPU_PARTIAL_FREE, cpu_partial_free);
+STAT_ATTR(CPU_PARTIAL_NODE, cpu_partial_node);
+STAT_ATTR(CPU_PARTIAL_DRAIN, cpu_partial_drain);
 #endif
 
 static struct attribute *slab_attrs[] = {
@@ -5124,6 +5158,8 @@ static struct attribute *slab_attrs[] = {
 	&cmpxchg_double_cpu_fail_attr.attr,
 	&cpu_partial_alloc_attr.attr,
 	&cpu_partial_free_attr.attr,
+	&cpu_partial_node_attr.attr,
+	&cpu_partial_drain_attr.attr,
 #endif
 #ifdef CONFIG_FAILSLAB
 	&failslab_attr.attr,
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 470038a..6761622 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -382,25 +382,23 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
 struct page *swapin_readahead(swp_entry_t entry, gfp_t gfp_mask,
 			struct vm_area_struct *vma, unsigned long addr)
 {
-	int nr_pages;
 	struct page *page;
-	unsigned long offset;
-	unsigned long end_offset;
+	unsigned long offset = swp_offset(entry);
+	unsigned long start_offset, end_offset;
+	unsigned long mask = (1UL << page_cluster) - 1;
 
-	/*
-	 * Get starting offset for readaround, and number of pages to read.
-	 * Adjust starting address by readbehind (for NUMA interleave case)?
-	 * No, it's very unlikely that swap layout would follow vma layout,
-	 * more likely that neighbouring swap pages came from the same node:
-	 * so use the same "addr" to choose the same node for each swap read.
-	 */
-	nr_pages = valid_swaphandles(entry, &offset);
-	for (end_offset = offset + nr_pages; offset < end_offset; offset++) {
+	/* Read a page_cluster sized and aligned cluster around offset. */
+	start_offset = offset & ~mask;
+	end_offset = offset | mask;
+	if (!start_offset)	/* First page is swap header. */
+		start_offset++;
+
+	for (offset = start_offset; offset <= end_offset ; offset++) {
 		/* Ok, do the async read-ahead now */
 		page = read_swap_cache_async(swp_entry(swp_type(entry), offset),
 						gfp_mask, vma, addr);
 		if (!page)
-			break;
+			continue;
 		page_cache_release(page);
 	}
 	lru_add_drain();	/* Push any new pages onto the LRU now */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index d999f09..fa3c519 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -31,6 +31,8 @@
 #include <linux/memcontrol.h>
 #include <linux/poll.h>
 #include <linux/oom.h>
+#include <linux/frontswap.h>
+#include <linux/swapfile.h>
 
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
@@ -42,7 +44,7 @@ static bool swap_count_continued(struct swap_info_struct *, pgoff_t,
 static void free_swap_count_continuations(struct swap_info_struct *);
 static sector_t map_swap_entry(swp_entry_t, struct block_device**);
 
-static DEFINE_SPINLOCK(swap_lock);
+DEFINE_SPINLOCK(swap_lock);
 static unsigned int nr_swapfiles;
 long nr_swap_pages;
 long total_swap_pages;
@@ -53,9 +55,9 @@ static const char Unused_file[] = "Unused swap file entry ";
 static const char Bad_offset[] = "Bad swap offset entry ";
 static const char Unused_offset[] = "Unused swap offset entry ";
 
-static struct swap_list_t swap_list = {-1, -1};
+struct swap_list_t swap_list = {-1, -1};
 
-static struct swap_info_struct *swap_info[MAX_SWAPFILES];
+struct swap_info_struct *swap_info[MAX_SWAPFILES];
 
 static DEFINE_MUTEX(swapon_mutex);
 
@@ -556,6 +558,7 @@ static unsigned char swap_entry_free(struct swap_info_struct *p,
 			swap_list.next = p->type;
 		nr_swap_pages++;
 		p->inuse_pages--;
+		frontswap_invalidate_page(p->type, offset);
 		if ((p->flags & SWP_BLKDEV) &&
 				disk->fops->swap_slot_free_notify)
 			disk->fops->swap_slot_free_notify(p->bdev, offset);
@@ -1018,11 +1021,12 @@ static int unuse_mm(struct mm_struct *mm,
 }
 
 /*
- * Scan swap_map from current position to next entry still in use.
+ * Scan swap_map (or frontswap_map if frontswap parameter is true)
+ * from current position to next entry still in use.
  * Recycle to start on reaching the end, returning 0 when empty.
  */
 static unsigned int find_next_to_unuse(struct swap_info_struct *si,
-					unsigned int prev)
+					unsigned int prev, bool frontswap)
 {
 	unsigned int max = si->max;
 	unsigned int i = prev;
@@ -1048,6 +1052,12 @@ static unsigned int find_next_to_unuse(struct swap_info_struct *si,
 			prev = 0;
 			i = 1;
 		}
+		if (frontswap) {
+			if (frontswap_test(si, i))
+				break;
+			else
+				continue;
+		}
 		count = si->swap_map[i];
 		if (count && swap_count(count) != SWAP_MAP_BAD)
 			break;
@@ -1059,8 +1069,12 @@ static unsigned int find_next_to_unuse(struct swap_info_struct *si,
  * We completely avoid races by reading each swap page in advance,
  * and then search for the process using it.  All the necessary
  * page table adjustments can then be made atomically.
+ *
+ * if the boolean frontswap is true, only unuse pages_to_unuse pages;
+ * pages_to_unuse==0 means all pages; ignored if frontswap is false
  */
-static int try_to_unuse(unsigned int type)
+int try_to_unuse(unsigned int type, bool frontswap,
+		 unsigned long pages_to_unuse)
 {
 	struct swap_info_struct *si = swap_info[type];
 	struct mm_struct *start_mm;
@@ -1093,7 +1107,7 @@ static int try_to_unuse(unsigned int type)
 	 * one pass through swap_map is enough, but not necessarily:
 	 * there are races when an instance of an entry might be missed.
 	 */
-	while ((i = find_next_to_unuse(si, i)) != 0) {
+	while ((i = find_next_to_unuse(si, i, frontswap)) != 0) {
 		if (signal_pending(current)) {
 			retval = -EINTR;
 			break;
@@ -1260,6 +1274,10 @@ static int try_to_unuse(unsigned int type)
 		 * interactive performance.
 		 */
 		cond_resched();
+		if (frontswap && pages_to_unuse > 0) {
+			if (!--pages_to_unuse)
+				break;
+		}
 	}
 
 	mmput(start_mm);
@@ -1519,7 +1537,8 @@ bad_bmap:
 }
 
 static void enable_swap_info(struct swap_info_struct *p, int prio,
-				unsigned char *swap_map)
+				unsigned char *swap_map,
+				unsigned long *frontswap_map)
 {
 	int i, prev;
 
@@ -1529,6 +1548,7 @@ static void enable_swap_info(struct swap_info_struct *p, int prio,
 	else
 		p->prio = --least_priority;
 	p->swap_map = swap_map;
+	frontswap_map_set(p, frontswap_map);
 	p->flags |= SWP_WRITEOK;
 	nr_swap_pages += p->pages;
 	total_swap_pages += p->pages;
@@ -1545,6 +1565,7 @@ static void enable_swap_info(struct swap_info_struct *p, int prio,
 		swap_list.head = swap_list.next = p->type;
 	else
 		swap_info[prev]->next = p->type;
+	frontswap_init(p->type);
 	spin_unlock(&swap_lock);
 }
 
@@ -1563,6 +1584,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
+	BUG_ON(!current->mm);
+
 	pathname = getname(specialfile);
 	err = PTR_ERR(pathname);
 	if (IS_ERR(pathname))
@@ -1590,7 +1613,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 		spin_unlock(&swap_lock);
 		goto out_dput;
 	}
-	if (!security_vm_enough_memory(p->pages))
+	if (!security_vm_enough_memory_mm(current->mm, p->pages))
 		vm_unacct_memory(p->pages);
 	else {
 		err = -ENOMEM;
@@ -1616,7 +1639,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 	spin_unlock(&swap_lock);
 
 	oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
-	err = try_to_unuse(type);
+	err = try_to_unuse(type, false, 0); /* force all pages to be unused */
 	compare_swap_oom_score_adj(OOM_SCORE_ADJ_MAX, oom_score_adj);
 
 	if (err) {
@@ -1627,7 +1650,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 		 * sys_swapoff for this swap_info_struct at this point.
 		 */
 		/* re-insert swap space back into swap_list */
-		enable_swap_info(p, p->prio, p->swap_map);
+		enable_swap_info(p, p->prio, p->swap_map, frontswap_map_get(p));
 		goto out_dput;
 	}
 
@@ -1653,9 +1676,11 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
 	swap_map = p->swap_map;
 	p->swap_map = NULL;
 	p->flags = 0;
+	frontswap_invalidate_area(type);
 	spin_unlock(&swap_lock);
 	mutex_unlock(&swapon_mutex);
 	vfree(swap_map);
+	vfree(frontswap_map_get(p));
 	/* Destroy swap account informatin */
 	swap_cgroup_swapoff(type);
 
@@ -2019,6 +2044,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
 	sector_t span;
 	unsigned long maxpages;
 	unsigned char *swap_map = NULL;
+	unsigned long *frontswap_map = NULL;
 	struct page *page = NULL;
 	struct inode *inode = NULL;
 
@@ -2099,6 +2125,9 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
 		error = nr_extents;
 		goto bad_swap;
 	}
+	/* frontswap enabled? set up bit-per-page map for frontswap */
+	if (frontswap_enabled)
+		frontswap_map = vzalloc(maxpages / sizeof(long));
 
 	if (p->bdev) {
 		if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
@@ -2114,14 +2143,15 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
 	if (swap_flags & SWAP_FLAG_PREFER)
 		prio =
 		  (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
-	enable_swap_info(p, prio, swap_map);
+	enable_swap_info(p, prio, swap_map, frontswap_map);
 
 	printk(KERN_INFO "Adding %uk swap on %s.  "
-			"Priority:%d extents:%d across:%lluk %s%s\n",
+			"Priority:%d extents:%d across:%lluk %s%s%s\n",
 		p->pages<<(PAGE_SHIFT-10), name, p->prio,
 		nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10),
 		(p->flags & SWP_SOLIDSTATE) ? "SS" : "",
-		(p->flags & SWP_DISCARDABLE) ? "D" : "");
+		(p->flags & SWP_DISCARDABLE) ? "D" : "",
+		(frontswap_map) ? "FS" : "");
 
 	mutex_unlock(&swapon_mutex);
 	atomic_inc(&proc_poll_event);
@@ -2290,58 +2320,6 @@ int swapcache_prepare(swp_entry_t entry)
 }
 
 /*
- * swap_lock prevents swap_map being freed. Don't grab an extra
- * reference on the swaphandle, it doesn't matter if it becomes unused.
- */
-int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
-{
-	struct swap_info_struct *si;
-	int our_page_cluster = page_cluster;
-	pgoff_t target, toff;
-	pgoff_t base, end;
-	int nr_pages = 0;
-
-	if (!our_page_cluster)	/* no readahead */
-		return 0;
-
-	si = swap_info[swp_type(entry)];
-	target = swp_offset(entry);
-	base = (target >> our_page_cluster) << our_page_cluster;
-	end = base + (1 << our_page_cluster);
-	if (!base)		/* first page is swap header */
-		base++;
-
-	spin_lock(&swap_lock);
-	if (end > si->max)	/* don't go beyond end of map */
-		end = si->max;
-
-	/* Count contiguous allocated slots above our target */
-	for (toff = target; ++toff < end; nr_pages++) {
-		/* Don't read in free or bad pages */
-		if (!si->swap_map[toff])
-			break;
-		if (swap_count(si->swap_map[toff]) == SWAP_MAP_BAD)
-			break;
-	}
-	/* Count contiguous allocated slots below our target */
-	for (toff = target; --toff >= base; nr_pages++) {
-		/* Don't read in free or bad pages */
-		if (!si->swap_map[toff])
-			break;
-		if (swap_count(si->swap_map[toff]) == SWAP_MAP_BAD)
-			break;
-	}
-	spin_unlock(&swap_lock);
-
-	/*
-	 * Indicate starting offset, and return number of pages to get:
-	 * if only 1, say 0, since there's then no readahead to be done.
-	 */
-	*offset = ++toff;
-	return nr_pages? ++nr_pages: 0;
-}
-
-/*
  * add_swap_count_continuation - called when a swap count is duplicated
  * beyond SWAP_MAP_MAX, it allocates a new page and links that to the entry's
  * page of the original vmalloc'ed swap_map, to hold the continuation count
@@ -2427,9 +2405,9 @@ int add_swap_count_continuation(swp_entry_t entry, gfp_t gfp_mask)
 		if (!(count & COUNT_CONTINUED))
 			goto out;
 
-		map = kmap_atomic(list_page, KM_USER0) + offset;
+		map = kmap_atomic(list_page) + offset;
 		count = *map;
-		kunmap_atomic(map, KM_USER0);
+		kunmap_atomic(map);
 
 		/*
 		 * If this continuation count now has some space in it,
@@ -2472,7 +2450,7 @@ static bool swap_count_continued(struct swap_info_struct *si,
 
 	offset &= ~PAGE_MASK;
 	page = list_entry(head->lru.next, struct page, lru);
-	map = kmap_atomic(page, KM_USER0) + offset;
+	map = kmap_atomic(page) + offset;
 
 	if (count == SWAP_MAP_MAX)	/* initial increment from swap_map */
 		goto init_map;		/* jump over SWAP_CONT_MAX checks */
@@ -2482,26 +2460,26 @@ static bool swap_count_continued(struct swap_info_struct *si,
 		 * Think of how you add 1 to 999
 		 */
 		while (*map == (SWAP_CONT_MAX | COUNT_CONTINUED)) {
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 			page = list_entry(page->lru.next, struct page, lru);
 			BUG_ON(page == head);
-			map = kmap_atomic(page, KM_USER0) + offset;
+			map = kmap_atomic(page) + offset;
 		}
 		if (*map == SWAP_CONT_MAX) {
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 			page = list_entry(page->lru.next, struct page, lru);
 			if (page == head)
 				return false;	/* add count continuation */
-			map = kmap_atomic(page, KM_USER0) + offset;
+			map = kmap_atomic(page) + offset;
 init_map:		*map = 0;		/* we didn't zero the page */
 		}
 		*map += 1;
-		kunmap_atomic(map, KM_USER0);
+		kunmap_atomic(map);
 		page = list_entry(page->lru.prev, struct page, lru);
 		while (page != head) {
-			map = kmap_atomic(page, KM_USER0) + offset;
+			map = kmap_atomic(page) + offset;
 			*map = COUNT_CONTINUED;
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 			page = list_entry(page->lru.prev, struct page, lru);
 		}
 		return true;			/* incremented */
@@ -2512,22 +2490,22 @@ init_map:		*map = 0;		/* we didn't zero the page */
 		 */
 		BUG_ON(count != COUNT_CONTINUED);
 		while (*map == COUNT_CONTINUED) {
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 			page = list_entry(page->lru.next, struct page, lru);
 			BUG_ON(page == head);
-			map = kmap_atomic(page, KM_USER0) + offset;
+			map = kmap_atomic(page) + offset;
 		}
 		BUG_ON(*map == 0);
 		*map -= 1;
 		if (*map == 0)
 			count = 0;
-		kunmap_atomic(map, KM_USER0);
+		kunmap_atomic(map);
 		page = list_entry(page->lru.prev, struct page, lru);
 		while (page != head) {
-			map = kmap_atomic(page, KM_USER0) + offset;
+			map = kmap_atomic(page) + offset;
 			*map = SWAP_CONT_MAX | count;
 			count = COUNT_CONTINUED;
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 			page = list_entry(page->lru.prev, struct page, lru);
 		}
 		return count == COUNT_CONTINUED;
diff --git a/mm/truncate.c b/mm/truncate.c
index 632b15e..b4d575c 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -52,7 +52,7 @@ void do_invalidatepage(struct page *page, unsigned long offset)
 static inline void truncate_partial_page(struct page *page, unsigned partial)
 {
 	zero_user_segment(page, partial, PAGE_CACHE_SIZE);
-	cleancache_flush_page(page->mapping, page);
+	cleancache_invalidate_page(page->mapping, page);
 	if (page_has_private(page))
 		do_invalidatepage(page, partial);
 }
@@ -213,7 +213,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
 	pgoff_t end;
 	int i;
 
-	cleancache_flush_inode(mapping);
+	cleancache_invalidate_inode(mapping);
 	if (mapping->nrpages == 0)
 		return;
 
@@ -292,7 +292,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
 		mem_cgroup_uncharge_end();
 		index++;
 	}
-	cleancache_flush_inode(mapping);
+	cleancache_invalidate_inode(mapping);
 }
 EXPORT_SYMBOL(truncate_inode_pages_range);
 
@@ -444,7 +444,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 	int ret2 = 0;
 	int did_range_unmap = 0;
 
-	cleancache_flush_inode(mapping);
+	cleancache_invalidate_inode(mapping);
 	pagevec_init(&pvec, 0);
 	index = start;
 	while (index <= end && pagevec_lookup(&pvec, mapping, index,
@@ -500,7 +500,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
 		cond_resched();
 		index++;
 	}
-	cleancache_flush_inode(mapping);
+	cleancache_invalidate_inode(mapping);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(invalidate_inode_pages2_range);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 86ce9a5..94dff88 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1906,9 +1906,9 @@ static int aligned_vread(char *buf, char *addr, unsigned long count)
 			 * we can expect USER0 is not used (see vread/vwrite's
 			 * function description)
 			 */
-			void *map = kmap_atomic(p, KM_USER0);
+			void *map = kmap_atomic(p);
 			memcpy(buf, map + offset, length);
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 		} else
 			memset(buf, 0, length);
 
@@ -1945,9 +1945,9 @@ static int aligned_vwrite(char *buf, char *addr, unsigned long count)
 			 * we can expect USER0 is not used (see vread/vwrite's
 			 * function description)
 			 */
-			void *map = kmap_atomic(p, KM_USER0);
+			void *map = kmap_atomic(p);
 			memcpy(map + offset, buf, length);
-			kunmap_atomic(map, KM_USER0);
+			kunmap_atomic(map);
 		}
 		addr += length;
 		buf += length;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index c52b235..efd50f5 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -374,7 +374,7 @@ static void set_reclaim_mode(int priority, struct scan_control *sc,
 	 * reclaim/compaction.Depending on the order, we will either set the
 	 * sync mode or just reclaim order-0 pages later.
 	 */
-	if (COMPACTION_BUILD)
+	if (IS_ENABLED(CONFIG_COMPACTION))
 		sc->reclaim_mode = RECLAIM_MODE_COMPACTION;
 	else
 		sc->reclaim_mode = RECLAIM_MODE_LUMPYRECLAIM;
@@ -1138,7 +1138,7 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file)
  * @mz:		The mem_cgroup_zone to pull pages from.
  * @dst:	The temp list to put pages on to.
  * @nr_scanned:	The number of pages that were scanned.
- * @order:	The caller's attempted allocation order
+ * @sc:		The scan_control struct for this reclaim session
  * @mode:	One of the LRU isolation modes
  * @active:	True [1] if isolating active pages
  * @file:	True [1] if isolating file [!anon] pages
@@ -1147,8 +1147,8 @@ int __isolate_lru_page(struct page *page, isolate_mode_t mode, int file)
  */
 static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
 		struct mem_cgroup_zone *mz, struct list_head *dst,
-		unsigned long *nr_scanned, int order, isolate_mode_t mode,
-		int active, int file)
+		unsigned long *nr_scanned, struct scan_control *sc,
+		isolate_mode_t mode, int active, int file)
 {
 	struct lruvec *lruvec;
 	struct list_head *src;
@@ -1194,7 +1194,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
 			BUG();
 		}
 
-		if (!order)
+		if (!sc->order || !(sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM))
 			continue;
 
 		/*
@@ -1208,8 +1208,8 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
 		 */
 		zone_id = page_zone_id(page);
 		page_pfn = page_to_pfn(page);
-		pfn = page_pfn & ~((1 << order) - 1);
-		end_pfn = pfn + (1 << order);
+		pfn = page_pfn & ~((1 << sc->order) - 1);
+		end_pfn = pfn + (1 << sc->order);
 		for (; pfn < end_pfn; pfn++) {
 			struct page *cursor_page;
 
@@ -1275,7 +1275,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
 
 	*nr_scanned = scan;
 
-	trace_mm_vmscan_lru_isolate(order,
+	trace_mm_vmscan_lru_isolate(sc->order,
 			nr_to_scan, scan,
 			nr_taken,
 			nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed,
@@ -1509,7 +1509,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz,
 	unsigned long nr_file;
 	unsigned long nr_dirty = 0;
 	unsigned long nr_writeback = 0;
-	isolate_mode_t reclaim_mode = ISOLATE_INACTIVE;
+	isolate_mode_t isolate_mode = ISOLATE_INACTIVE;
 	struct zone *zone = mz->zone;
 
 	while (unlikely(too_many_isolated(zone, file, sc))) {
@@ -1522,20 +1522,19 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz,
 
 	set_reclaim_mode(priority, sc, false);
 	if (sc->reclaim_mode & RECLAIM_MODE_LUMPYRECLAIM)
-		reclaim_mode |= ISOLATE_ACTIVE;
+		isolate_mode |= ISOLATE_ACTIVE;
 
 	lru_add_drain();
 
 	if (!sc->may_unmap)
-		reclaim_mode |= ISOLATE_UNMAPPED;
+		isolate_mode |= ISOLATE_UNMAPPED;
 	if (!sc->may_writepage)
-		reclaim_mode |= ISOLATE_CLEAN;
+		isolate_mode |= ISOLATE_CLEAN;
 
 	spin_lock_irq(&zone->lru_lock);
 
-	nr_taken = isolate_lru_pages(nr_to_scan, mz, &page_list,
-				     &nr_scanned, sc->order,
-				     reclaim_mode, 0, file);
+	nr_taken = isolate_lru_pages(nr_to_scan, mz, &page_list, &nr_scanned,
+				     sc, isolate_mode, 0, file);
 	if (global_reclaim(sc)) {
 		zone->pages_scanned += nr_scanned;
 		if (current_is_kswapd())
@@ -1699,21 +1698,20 @@ static void shrink_active_list(unsigned long nr_to_scan,
 	struct page *page;
 	struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(mz);
 	unsigned long nr_rotated = 0;
-	isolate_mode_t reclaim_mode = ISOLATE_ACTIVE;
+	isolate_mode_t isolate_mode = ISOLATE_ACTIVE;
 	struct zone *zone = mz->zone;
 
 	lru_add_drain();
 
 	if (!sc->may_unmap)
-		reclaim_mode |= ISOLATE_UNMAPPED;
+		isolate_mode |= ISOLATE_UNMAPPED;
 	if (!sc->may_writepage)
-		reclaim_mode |= ISOLATE_CLEAN;
+		isolate_mode |= ISOLATE_CLEAN;
 
 	spin_lock_irq(&zone->lru_lock);
 
-	nr_taken = isolate_lru_pages(nr_to_scan, mz, &l_hold,
-				     &nr_scanned, sc->order,
-				     reclaim_mode, 1, file);
+	nr_taken = isolate_lru_pages(nr_to_scan, mz, &l_hold, &nr_scanned, sc,
+				     isolate_mode, 1, file);
 	if (global_reclaim(sc))
 		zone->pages_scanned += nr_scanned;
 
@@ -2112,7 +2110,12 @@ restart:
 		 * with multiple processes reclaiming pages, the total
 		 * freeing target can get unreasonably large.
 		 */
-		if (nr_reclaimed >= nr_to_reclaim && priority < DEF_PRIORITY)
+		if (nr_reclaimed >= nr_to_reclaim)
+			nr_to_reclaim = 0;
+		else
+			nr_to_reclaim -= nr_reclaimed;
+
+		if (!nr_to_reclaim && priority < DEF_PRIORITY)
 			break;
 	}
 	blk_finish_plug(&plug);
@@ -2195,7 +2198,7 @@ static inline bool compaction_ready(struct zone *zone, struct scan_control *sc)
 	 * If compaction is deferred, reclaim up to a point where
 	 * compaction will have a chance of success when re-enabled
 	 */
-	if (compaction_deferred(zone))
+	if (compaction_deferred(zone, sc->order))
 		return watermark_ok;
 
 	/* If compaction is not ready to start, keep reclaiming */
@@ -2235,6 +2238,14 @@ static bool shrink_zones(int priority, struct zonelist *zonelist,
 	unsigned long nr_soft_scanned;
 	bool aborted_reclaim = false;
 
+	/*
+	 * If the number of buffer_heads in the machine exceeds the maximum
+	 * allowed level, force direct reclaim to scan the highmem zone as
+	 * highmem pages could be pinning lowmem pages storing buffer_heads
+	 */
+	if (buffer_heads_over_limit)
+		sc->gfp_mask |= __GFP_HIGHMEM;
+
 	for_each_zone_zonelist_nodemask(zone, z, zonelist,
 					gfp_zone(sc->gfp_mask), sc->nodemask) {
 		if (!populated_zone(zone))
@@ -2248,7 +2259,7 @@ static bool shrink_zones(int priority, struct zonelist *zonelist,
 				continue;
 			if (zone->all_unreclaimable && priority != DEF_PRIORITY)
 				continue;	/* Let kswapd poll it */
-			if (COMPACTION_BUILD) {
+			if (IS_ENABLED(CONFIG_COMPACTION)) {
 				/*
 				 * If we already have plenty of memory free for
 				 * compaction in this zone, don't free any more.
@@ -2724,6 +2735,17 @@ loop_again:
 			 */
 			age_active_anon(zone, &sc, priority);
 
+			/*
+			 * If the number of buffer_heads in the machine
+			 * exceeds the maximum allowed level and this node
+			 * has a highmem zone, force kswapd to reclaim from
+			 * it to relieve lowmem pressure.
+			 */
+			if (buffer_heads_over_limit && is_highmem_idx(i)) {
+				end_zone = i;
+				break;
+			}
+
 			if (!zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone), 0, 0)) {
 				end_zone = i;
@@ -2753,7 +2775,7 @@ loop_again:
 		 */
 		for (i = 0; i <= end_zone; i++) {
 			struct zone *zone = pgdat->node_zones + i;
-			int nr_slab;
+			int nr_slab, testorder;
 			unsigned long balance_gap;
 
 			if (!populated_zone(zone))
@@ -2786,7 +2808,21 @@ loop_again:
 				(zone->present_pages +
 					KSWAPD_ZONE_BALANCE_GAP_RATIO-1) /
 				KSWAPD_ZONE_BALANCE_GAP_RATIO);
-			if (!zone_watermark_ok_safe(zone, order,
+			/*
+			 * Kswapd reclaims only single pages with compaction
+			 * enabled. Trying too hard to reclaim until contiguous
+			 * free pages have become available can hurt performance
+			 * by evicting too much useful data from memory.
+			 * Do not reclaim more than needed for compaction.
+			 */
+			testorder = order;
+			if (IS_ENABLED(CONFIG_COMPACTION) && order &&
+					compaction_suitable(zone, order) !=
+						COMPACT_SKIPPED)
+				testorder = 0;
+
+			if ((buffer_heads_over_limit && is_highmem_idx(i)) ||
+				    !zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone) + balance_gap,
 					end_zone, 0)) {
 				shrink_zone(priority, zone, &sc);
@@ -2815,7 +2851,7 @@ loop_again:
 				continue;
 			}
 
-			if (!zone_watermark_ok_safe(zone, order,
+			if (!zone_watermark_ok_safe(zone, testorder,
 					high_wmark_pages(zone), end_zone, 0)) {
 				all_zones_ok = 0;
 				/*
@@ -2903,6 +2939,8 @@ out:
 	 * and it is potentially going to sleep here.
 	 */
 	if (order) {
+		int zones_need_compaction = 1;
+
 		for (i = 0; i <= end_zone; i++) {
 			struct zone *zone = pgdat->node_zones + i;
 
@@ -2912,6 +2950,10 @@ out:
 			if (zone->all_unreclaimable && priority != DEF_PRIORITY)
 				continue;
 
+			/* Would compaction fail due to lack of free memory? */
+			if (compaction_suitable(zone, order) == COMPACT_SKIPPED)
+				goto loop_again;
+
 			/* Confirm the zone is balanced for order-0 */
 			if (!zone_watermark_ok(zone, 0,
 					high_wmark_pages(zone), 0, 0)) {
@@ -2919,11 +2961,17 @@ out:
 				goto loop_again;
 			}
 
+			/* Check if the memory needs to be defragmented. */
+			if (zone_watermark_ok(zone, order,
+				    low_wmark_pages(zone), *classzone_idx, 0))
+				zones_need_compaction = 0;
+
 			/* If balanced, clear the congested flag */
 			zone_clear_flag(zone, ZONE_CONGESTED);
-			if (i <= *classzone_idx)
-				balanced += zone->present_pages;
 		}
+
+		if (zones_need_compaction)
+			compact_pgdat(pgdat, order);
 	}
 
 	/*
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c12c258..ef95a30 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -328,6 +328,8 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
 	struct atmarp_entry *entry;
 	struct neighbour *n;
 	struct atm_vcc *vcc;
+	struct rtable *rt;
+	__be32 *daddr;
 	int old;
 	unsigned long flags;
 
@@ -338,7 +340,12 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
 		dev->stats.tx_dropped++;
 		return NETDEV_TX_OK;
 	}
-	n = dst_get_neighbour_noref(dst);
+	rt = (struct rtable *) dst;
+	if (rt->rt_gateway)
+		daddr = &rt->rt_gateway;
+	else
+		daddr = &ip_hdr(skb)->daddr;
+	n = dst_neigh_lookup(dst, daddr);
 	if (!n) {
 		pr_err("NO NEIGHBOUR !\n");
 		dev_kfree_skb(skb);
@@ -358,7 +365,7 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
 			dev_kfree_skb(skb);
 			dev->stats.tx_dropped++;
 		}
-		return NETDEV_TX_OK;
+		goto out_release_neigh;
 	}
 	pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
 	ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
@@ -377,14 +384,14 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
 	old = xchg(&entry->vccs->xoff, 1);	/* assume XOFF ... */
 	if (old) {
 		pr_warning("XOFF->XOFF transition\n");
-		return NETDEV_TX_OK;
+		goto out_release_neigh;
 	}
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 	vcc->send(vcc, skb);
 	if (atm_may_send(vcc, 0)) {
 		entry->vccs->xoff = 0;
-		return NETDEV_TX_OK;
+		goto out_release_neigh;
 	}
 	spin_lock_irqsave(&clip_priv->xoff_lock, flags);
 	netif_stop_queue(dev);	/* XOFF -> throttle immediately */
@@ -396,6 +403,8 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
 	   of the brief netif_stop_queue. If this isn't true or if it
 	   changes, use netif_wake_queue instead. */
 	spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
+out_release_neigh:
+	neigh_release(n);
 	return NETDEV_TX_OK;
 }
 
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
new file mode 100644
index 0000000..755379f
--- /dev/null
+++ b/net/batman-adv/bat_algo.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
+ *
+ */
+
+#ifndef _NET_BATMAN_ADV_BAT_ALGO_H_
+#define _NET_BATMAN_ADV_BAT_ALGO_H_
+
+int bat_iv_init(void);
+
+#endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */
diff --git a/net/batman-adv/bat_debugfs.c b/net/batman-adv/bat_debugfs.c
index d0af9bf..a7a393e 100644
--- a/net/batman-adv/bat_debugfs.c
+++ b/net/batman-adv/bat_debugfs.c
@@ -221,6 +221,11 @@ static void debug_log_cleanup(struct bat_priv *bat_priv)
 }
 #endif
 
+static int bat_algorithms_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bat_algo_seq_print_text, NULL);
+}
+
 static int originators_open(struct inode *inode, struct file *file)
 {
 	struct net_device *net_dev = (struct net_device *)inode->i_private;
@@ -274,6 +279,7 @@ struct bat_debuginfo bat_debuginfo_##_name = {	\
 		}				\
 };
 
+static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open);
 static BAT_DEBUGINFO(originators, S_IRUGO, originators_open);
 static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open);
 static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open);
@@ -293,9 +299,25 @@ static struct bat_debuginfo *mesh_debuginfos[] = {
 
 void debugfs_init(void)
 {
+	struct bat_debuginfo *bat_debug;
+	struct dentry *file;
+
 	bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL);
 	if (bat_debugfs == ERR_PTR(-ENODEV))
 		bat_debugfs = NULL;
+
+	if (!bat_debugfs)
+		goto out;
+
+	bat_debug = &bat_debuginfo_routing_algos;
+	file = debugfs_create_file(bat_debug->attr.name,
+				   S_IFREG | bat_debug->attr.mode,
+				   bat_debugfs, NULL, &bat_debug->fops);
+	if (!file)
+		pr_err("Can't add debugfs file: %s\n", bat_debug->attr.name);
+
+out:
+	return;
 }
 
 void debugfs_destroy(void)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 3512e25..1c483a5 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -20,7 +20,6 @@
  */
 
 #include "main.h"
-#include "bat_ogm.h"
 #include "translation-table.h"
 #include "ring_buffer.h"
 #include "originator.h"
@@ -29,8 +28,9 @@
 #include "gateway_client.h"
 #include "hard-interface.h"
 #include "send.h"
+#include "bat_algo.h"
 
-void bat_ogm_init(struct hard_iface *hard_iface)
+static void bat_iv_ogm_init(struct hard_iface *hard_iface)
 {
 	struct batman_ogm_packet *batman_ogm_packet;
 
@@ -38,25 +38,25 @@ void bat_ogm_init(struct hard_iface *hard_iface)
 	hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
 
 	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
-	batman_ogm_packet->packet_type = BAT_OGM;
-	batman_ogm_packet->version = COMPAT_VERSION;
+	batman_ogm_packet->header.packet_type = BAT_OGM;
+	batman_ogm_packet->header.version = COMPAT_VERSION;
+	batman_ogm_packet->header.ttl = 2;
 	batman_ogm_packet->flags = NO_FLAGS;
-	batman_ogm_packet->ttl = 2;
 	batman_ogm_packet->tq = TQ_MAX_VALUE;
 	batman_ogm_packet->tt_num_changes = 0;
 	batman_ogm_packet->ttvn = 0;
 }
 
-void bat_ogm_init_primary(struct hard_iface *hard_iface)
+static void bat_iv_ogm_init_primary(struct hard_iface *hard_iface)
 {
 	struct batman_ogm_packet *batman_ogm_packet;
 
 	batman_ogm_packet = (struct batman_ogm_packet *)hard_iface->packet_buff;
 	batman_ogm_packet->flags = PRIMARIES_FIRST_HOP;
-	batman_ogm_packet->ttl = TTL;
+	batman_ogm_packet->header.ttl = TTL;
 }
 
-void bat_ogm_update_mac(struct hard_iface *hard_iface)
+static void bat_iv_ogm_update_mac(struct hard_iface *hard_iface)
 {
 	struct batman_ogm_packet *batman_ogm_packet;
 
@@ -68,7 +68,7 @@ void bat_ogm_update_mac(struct hard_iface *hard_iface)
 }
 
 /* when do we schedule our own ogm to be sent */
-static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv)
+static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv)
 {
 	return jiffies + msecs_to_jiffies(
 		   atomic_read(&bat_priv->orig_interval) -
@@ -76,7 +76,7 @@ static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv)
 }
 
 /* when do we schedule a ogm packet to be sent */
-static unsigned long bat_ogm_fwd_send_time(void)
+static unsigned long bat_iv_ogm_fwd_send_time(void)
 {
 	return jiffies + msecs_to_jiffies(random32() % (JITTER/2));
 }
@@ -89,8 +89,8 @@ static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv)
 }
 
 /* is there another aggregated packet here? */
-static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
-			       int tt_num_changes)
+static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len,
+				  int tt_num_changes)
 {
 	int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
 
@@ -99,8 +99,8 @@ static int bat_ogm_aggr_packet(int buff_pos, int packet_len,
 }
 
 /* send a batman ogm to a given interface */
-static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
-			       struct hard_iface *hard_iface)
+static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,
+				  struct hard_iface *hard_iface)
 {
 	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 	char *fwd_str;
@@ -117,8 +117,8 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
 	batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
 
 	/* adjust all flags and log packets */
-	while (bat_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
-				   batman_ogm_packet->tt_num_changes)) {
+	while (bat_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
+				      batman_ogm_packet->tt_num_changes)) {
 
 		/* we might have aggregated direct link packets with an
 		 * ordinary base packet */
@@ -137,7 +137,7 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
 			fwd_str, (packet_num > 0 ? "aggregated " : ""),
 			batman_ogm_packet->orig,
 			ntohl(batman_ogm_packet->seqno),
-			batman_ogm_packet->tq, batman_ogm_packet->ttl,
+			batman_ogm_packet->tq, batman_ogm_packet->header.ttl,
 			(batman_ogm_packet->flags & DIRECTLINK ?
 			 "on" : "off"),
 			batman_ogm_packet->ttvn, hard_iface->net_dev->name,
@@ -157,7 +157,7 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet,
 }
 
 /* send a batman ogm packet */
-void bat_ogm_emit(struct forw_packet *forw_packet)
+static void bat_iv_ogm_emit(struct forw_packet *forw_packet)
 {
 	struct hard_iface *hard_iface;
 	struct net_device *soft_iface;
@@ -188,7 +188,7 @@ void bat_ogm_emit(struct forw_packet *forw_packet)
 
 	/* multihomed peer assumed */
 	/* non-primary OGMs are only broadcasted on their interface */
-	if ((directlink && (batman_ogm_packet->ttl == 1)) ||
+	if ((directlink && (batman_ogm_packet->header.ttl == 1)) ||
 	    (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
 
 		/* FIXME: what about aggregated packets ? */
@@ -198,7 +198,7 @@ void bat_ogm_emit(struct forw_packet *forw_packet)
 			(forw_packet->own ? "Sending own" : "Forwarding"),
 			batman_ogm_packet->orig,
 			ntohl(batman_ogm_packet->seqno),
-			batman_ogm_packet->ttl,
+			batman_ogm_packet->header.ttl,
 			forw_packet->if_incoming->net_dev->name,
 			forw_packet->if_incoming->net_dev->dev_addr);
 
@@ -216,7 +216,7 @@ void bat_ogm_emit(struct forw_packet *forw_packet)
 		if (hard_iface->soft_iface != soft_iface)
 			continue;
 
-		bat_ogm_send_to_if(forw_packet, hard_iface);
+		bat_iv_ogm_send_to_if(forw_packet, hard_iface);
 	}
 	rcu_read_unlock();
 
@@ -226,13 +226,13 @@ out:
 }
 
 /* return true if new_packet can be aggregated with forw_packet */
-static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
+static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet
 							*new_batman_ogm_packet,
-				  struct bat_priv *bat_priv,
-				  int packet_len, unsigned long send_time,
-				  bool directlink,
-				  const struct hard_iface *if_incoming,
-				  const struct forw_packet *forw_packet)
+				     struct bat_priv *bat_priv,
+				     int packet_len, unsigned long send_time,
+				     bool directlink,
+				     const struct hard_iface *if_incoming,
+				     const struct forw_packet *forw_packet)
 {
 	struct batman_ogm_packet *batman_ogm_packet;
 	int aggregated_bytes = forw_packet->packet_len + packet_len;
@@ -272,7 +272,7 @@ static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
 		 * are flooded through the net  */
 		if ((!directlink) &&
 		    (!(batman_ogm_packet->flags & DIRECTLINK)) &&
-		    (batman_ogm_packet->ttl != 1) &&
+		    (batman_ogm_packet->header.ttl != 1) &&
 
 		    /* own packets originating non-primary
 		     * interfaces leave only that interface */
@@ -285,7 +285,7 @@ static bool bat_ogm_can_aggregate(const struct batman_ogm_packet
 		/* if the incoming packet is sent via this one
 		 * interface only - we still can aggregate */
 		if ((directlink) &&
-		    (new_batman_ogm_packet->ttl == 1) &&
+		    (new_batman_ogm_packet->header.ttl == 1) &&
 		    (forw_packet->if_incoming == if_incoming) &&
 
 		    /* packets from direct neighbors or
@@ -306,11 +306,11 @@ out:
 }
 
 /* create a new aggregated packet and add this packet to it */
-static void bat_ogm_aggregate_new(const unsigned char *packet_buff,
-				  int packet_len, unsigned long send_time,
-				  bool direct_link,
-				  struct hard_iface *if_incoming,
-				  int own_packet)
+static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff,
+				     int packet_len, unsigned long send_time,
+				     bool direct_link,
+				     struct hard_iface *if_incoming,
+				     int own_packet)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct forw_packet *forw_packet_aggr;
@@ -385,9 +385,9 @@ out:
 }
 
 /* aggregate a new packet into the existing ogm packet */
-static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr,
-			      const unsigned char *packet_buff,
-			      int packet_len, bool direct_link)
+static void bat_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr,
+				 const unsigned char *packet_buff,
+				 int packet_len, bool direct_link)
 {
 	unsigned char *skb_buff;
 
@@ -402,10 +402,10 @@ static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr,
 			(1 << forw_packet_aggr->num_packets);
 }
 
-static void bat_ogm_queue_add(struct bat_priv *bat_priv,
-			      unsigned char *packet_buff,
-			      int packet_len, struct hard_iface *if_incoming,
-			      int own_packet, unsigned long send_time)
+static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv,
+				 unsigned char *packet_buff,
+				 int packet_len, struct hard_iface *if_incoming,
+				 int own_packet, unsigned long send_time)
 {
 	/**
 	 * _aggr -> pointer to the packet we want to aggregate with
@@ -425,11 +425,11 @@ static void bat_ogm_queue_add(struct bat_priv *bat_priv,
 	if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) {
 		hlist_for_each_entry(forw_packet_pos, tmp_node,
 				     &bat_priv->forw_bat_list, list) {
-			if (bat_ogm_can_aggregate(batman_ogm_packet,
-						  bat_priv, packet_len,
-						  send_time, direct_link,
-						  if_incoming,
-						  forw_packet_pos)) {
+			if (bat_iv_ogm_can_aggregate(batman_ogm_packet,
+						     bat_priv, packet_len,
+						     send_time, direct_link,
+						     if_incoming,
+						     forw_packet_pos)) {
 				forw_packet_aggr = forw_packet_pos;
 				break;
 			}
@@ -451,27 +451,27 @@ static void bat_ogm_queue_add(struct bat_priv *bat_priv,
 		    (atomic_read(&bat_priv->aggregated_ogms)))
 			send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
 
-		bat_ogm_aggregate_new(packet_buff, packet_len,
-				      send_time, direct_link,
-				      if_incoming, own_packet);
+		bat_iv_ogm_aggregate_new(packet_buff, packet_len,
+					 send_time, direct_link,
+					 if_incoming, own_packet);
 	} else {
-		bat_ogm_aggregate(forw_packet_aggr, packet_buff, packet_len,
-				  direct_link);
+		bat_iv_ogm_aggregate(forw_packet_aggr, packet_buff,
+				     packet_len, direct_link);
 		spin_unlock_bh(&bat_priv->forw_bat_list_lock);
 	}
 }
 
-static void bat_ogm_forward(struct orig_node *orig_node,
-			    const struct ethhdr *ethhdr,
-			    struct batman_ogm_packet *batman_ogm_packet,
-			    int directlink, struct hard_iface *if_incoming)
+static void bat_iv_ogm_forward(struct orig_node *orig_node,
+			       const struct ethhdr *ethhdr,
+			       struct batman_ogm_packet *batman_ogm_packet,
+			       int directlink, struct hard_iface *if_incoming)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct neigh_node *router;
 	uint8_t in_tq, in_ttl, tq_avg = 0;
 	uint8_t tt_num_changes;
 
-	if (batman_ogm_packet->ttl <= 1) {
+	if (batman_ogm_packet->header.ttl <= 1) {
 		bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n");
 		return;
 	}
@@ -479,10 +479,10 @@ static void bat_ogm_forward(struct orig_node *orig_node,
 	router = orig_node_get_router(orig_node);
 
 	in_tq = batman_ogm_packet->tq;
-	in_ttl = batman_ogm_packet->ttl;
+	in_ttl = batman_ogm_packet->header.ttl;
 	tt_num_changes = batman_ogm_packet->tt_num_changes;
 
-	batman_ogm_packet->ttl--;
+	batman_ogm_packet->header.ttl--;
 	memcpy(batman_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);
 
 	/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
@@ -494,7 +494,8 @@ static void bat_ogm_forward(struct orig_node *orig_node,
 			batman_ogm_packet->tq = router->tq_avg;
 
 			if (router->last_ttl)
-				batman_ogm_packet->ttl = router->last_ttl - 1;
+				batman_ogm_packet->header.ttl =
+					router->last_ttl - 1;
 		}
 
 		tq_avg = router->tq_avg;
@@ -510,7 +511,7 @@ static void bat_ogm_forward(struct orig_node *orig_node,
 		"Forwarding packet: tq_orig: %i, tq_avg: %i, "
 		"tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n",
 		in_tq, tq_avg, batman_ogm_packet->tq, in_ttl - 1,
-		batman_ogm_packet->ttl);
+		batman_ogm_packet->header.ttl);
 
 	batman_ogm_packet->seqno = htonl(batman_ogm_packet->seqno);
 	batman_ogm_packet->tt_crc = htons(batman_ogm_packet->tt_crc);
@@ -522,12 +523,13 @@ static void bat_ogm_forward(struct orig_node *orig_node,
 	else
 		batman_ogm_packet->flags &= ~DIRECTLINK;
 
-	bat_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
-			  BATMAN_OGM_LEN + tt_len(tt_num_changes),
-			  if_incoming, 0, bat_ogm_fwd_send_time());
+	bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet,
+			     BATMAN_OGM_LEN + tt_len(tt_num_changes),
+			     if_incoming, 0, bat_iv_ogm_fwd_send_time());
 }
 
-void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes)
+static void bat_iv_ogm_schedule(struct hard_iface *hard_iface,
+				int tt_num_changes)
 {
 	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 	struct batman_ogm_packet *batman_ogm_packet;
@@ -564,21 +566,22 @@ void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes)
 	atomic_inc(&hard_iface->seqno);
 
 	slide_own_bcast_window(hard_iface);
-	bat_ogm_queue_add(bat_priv, hard_iface->packet_buff,
-			  hard_iface->packet_len, hard_iface, 1,
-			  bat_ogm_emit_send_time(bat_priv));
+	bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff,
+			     hard_iface->packet_len, hard_iface, 1,
+			     bat_iv_ogm_emit_send_time(bat_priv));
 
 	if (primary_if)
 		hardif_free_ref(primary_if);
 }
 
-static void bat_ogm_orig_update(struct bat_priv *bat_priv,
-				struct orig_node *orig_node,
-				const struct ethhdr *ethhdr,
-				const struct batman_ogm_packet
+static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv,
+				   struct orig_node *orig_node,
+				   const struct ethhdr *ethhdr,
+				   const struct batman_ogm_packet
 							*batman_ogm_packet,
-				struct hard_iface *if_incoming,
-				const unsigned char *tt_buff, int is_duplicate)
+				   struct hard_iface *if_incoming,
+				   const unsigned char *tt_buff,
+				   int is_duplicate)
 {
 	struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
 	struct neigh_node *router = NULL;
@@ -642,8 +645,8 @@ static void bat_ogm_orig_update(struct bat_priv *bat_priv,
 	spin_unlock_bh(&neigh_node->tq_lock);
 
 	if (!is_duplicate) {
-		orig_node->last_ttl = batman_ogm_packet->ttl;
-		neigh_node->last_ttl = batman_ogm_packet->ttl;
+		orig_node->last_ttl = batman_ogm_packet->header.ttl;
+		neigh_node->last_ttl = batman_ogm_packet->header.ttl;
 	}
 
 	bonding_candidate_add(orig_node, neigh_node);
@@ -683,7 +686,7 @@ update_tt:
 	/* I have to check for transtable changes only if the OGM has been
 	 * sent through a primary interface */
 	if (((batman_ogm_packet->orig != ethhdr->h_source) &&
-	     (batman_ogm_packet->ttl > 2)) ||
+	     (batman_ogm_packet->header.ttl > 2)) ||
 	    (batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
 		tt_update_orig(bat_priv, orig_node, tt_buff,
 			       batman_ogm_packet->tt_num_changes,
@@ -713,10 +716,10 @@ out:
 		neigh_node_free_ref(router);
 }
 
-static int bat_ogm_calc_tq(struct orig_node *orig_node,
-			   struct orig_node *orig_neigh_node,
-			   struct batman_ogm_packet *batman_ogm_packet,
-			   struct hard_iface *if_incoming)
+static int bat_iv_ogm_calc_tq(struct orig_node *orig_node,
+			      struct orig_node *orig_neigh_node,
+			      struct batman_ogm_packet *batman_ogm_packet,
+			      struct hard_iface *if_incoming)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
@@ -825,10 +828,10 @@ out:
  *  -1 the packet is old and has been received while the seqno window
  *     was protected. Caller should drop it.
  */
-static int bat_ogm_update_seqnos(const struct ethhdr *ethhdr,
-				 const struct batman_ogm_packet
+static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
+				    const struct batman_ogm_packet
 							*batman_ogm_packet,
-				 const struct hard_iface *if_incoming)
+				    const struct hard_iface *if_incoming)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct orig_node *orig_node;
@@ -890,10 +893,10 @@ out:
 	return ret;
 }
 
-static void bat_ogm_process(const struct ethhdr *ethhdr,
-			    struct batman_ogm_packet *batman_ogm_packet,
-			    const unsigned char *tt_buff,
-			    struct hard_iface *if_incoming)
+static void bat_iv_ogm_process(const struct ethhdr *ethhdr,
+			       struct batman_ogm_packet *batman_ogm_packet,
+			       const unsigned char *tt_buff,
+			       struct hard_iface *if_incoming)
 {
 	struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
 	struct hard_iface *hard_iface;
@@ -918,7 +921,7 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 	 * packet in an aggregation.  Here we expect that the padding
 	 * is always zero (or not 0x01)
 	 */
-	if (batman_ogm_packet->packet_type != BAT_OGM)
+	if (batman_ogm_packet->header.packet_type != BAT_OGM)
 		return;
 
 	/* could be changed by schedule_own_packet() */
@@ -938,8 +941,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 		batman_ogm_packet->prev_sender, batman_ogm_packet->seqno,
 		batman_ogm_packet->ttvn, batman_ogm_packet->tt_crc,
 		batman_ogm_packet->tt_num_changes, batman_ogm_packet->tq,
-		batman_ogm_packet->ttl, batman_ogm_packet->version,
-		has_directlink_flag);
+		batman_ogm_packet->header.ttl,
+		batman_ogm_packet->header.version, has_directlink_flag);
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(hard_iface, &hardif_list, list) {
@@ -966,10 +969,10 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 	}
 	rcu_read_unlock();
 
-	if (batman_ogm_packet->version != COMPAT_VERSION) {
+	if (batman_ogm_packet->header.version != COMPAT_VERSION) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: incompatible batman version (%i)\n",
-			batman_ogm_packet->version);
+			batman_ogm_packet->header.version);
 		return;
 	}
 
@@ -1031,8 +1034,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 	if (!orig_node)
 		return;
 
-	is_duplicate = bat_ogm_update_seqnos(ethhdr, batman_ogm_packet,
-					     if_incoming);
+	is_duplicate = bat_iv_ogm_update_seqnos(ethhdr, batman_ogm_packet,
+						if_incoming);
 
 	if (is_duplicate == -1) {
 		bat_dbg(DBG_BATMAN, bat_priv,
@@ -1081,8 +1084,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 		goto out_neigh;
 	}
 
-	is_bidirectional = bat_ogm_calc_tq(orig_node, orig_neigh_node,
-					   batman_ogm_packet, if_incoming);
+	is_bidirectional = bat_iv_ogm_calc_tq(orig_node, orig_neigh_node,
+					      batman_ogm_packet, if_incoming);
 
 	bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
 
@@ -1091,17 +1094,17 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 	if (is_bidirectional &&
 	    (!is_duplicate ||
 	     ((orig_node->last_real_seqno == batman_ogm_packet->seqno) &&
-	      (orig_node->last_ttl - 3 <= batman_ogm_packet->ttl))))
-		bat_ogm_orig_update(bat_priv, orig_node, ethhdr,
-				    batman_ogm_packet, if_incoming,
-				    tt_buff, is_duplicate);
+	      (orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl))))
+		bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
+				       batman_ogm_packet, if_incoming,
+				       tt_buff, is_duplicate);
 
 	/* is single hop (direct) neighbor */
 	if (is_single_hop_neigh) {
 
 		/* mark direct link on incoming interface */
-		bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
-				1, if_incoming);
+		bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
+				   1, if_incoming);
 
 		bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: "
 			"rebroadcast neighbor packet with direct link flag\n");
@@ -1123,7 +1126,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
 
 	bat_dbg(DBG_BATMAN, bat_priv,
 		"Forwarding packet: rebroadcast originator packet\n");
-	bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 0, if_incoming);
+	bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet,
+			   0, if_incoming);
 
 out_neigh:
 	if ((orig_neigh_node) && (!is_single_hop_neigh))
@@ -1139,13 +1143,17 @@ out:
 	orig_node_free_ref(orig_node);
 }
 
-void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
-		     int packet_len, struct hard_iface *if_incoming)
+static void bat_iv_ogm_receive(struct hard_iface *if_incoming,
+			       struct sk_buff *skb)
 {
 	struct batman_ogm_packet *batman_ogm_packet;
-	int buff_pos = 0;
-	unsigned char *tt_buff;
+	struct ethhdr *ethhdr;
+	int buff_pos = 0, packet_len;
+	unsigned char *tt_buff, *packet_buff;
 
+	packet_len = skb_headlen(skb);
+	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+	packet_buff = skb->data;
 	batman_ogm_packet = (struct batman_ogm_packet *)packet_buff;
 
 	/* unpack the aggregated packets and process them one by one */
@@ -1157,14 +1165,29 @@ void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
 
 		tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
 
-		bat_ogm_process(ethhdr, batman_ogm_packet,
-				tt_buff, if_incoming);
+		bat_iv_ogm_process(ethhdr, batman_ogm_packet,
+				   tt_buff, if_incoming);
 
 		buff_pos += BATMAN_OGM_LEN +
 				tt_len(batman_ogm_packet->tt_num_changes);
 
 		batman_ogm_packet = (struct batman_ogm_packet *)
 						(packet_buff + buff_pos);
-	} while (bat_ogm_aggr_packet(buff_pos, packet_len,
-				     batman_ogm_packet->tt_num_changes));
+	} while (bat_iv_ogm_aggr_packet(buff_pos, packet_len,
+					batman_ogm_packet->tt_num_changes));
+}
+
+static struct bat_algo_ops batman_iv __read_mostly = {
+	.name = "BATMAN IV",
+	.bat_ogm_init = bat_iv_ogm_init,
+	.bat_ogm_init_primary = bat_iv_ogm_init_primary,
+	.bat_ogm_update_mac = bat_iv_ogm_update_mac,
+	.bat_ogm_schedule = bat_iv_ogm_schedule,
+	.bat_ogm_emit = bat_iv_ogm_emit,
+	.bat_ogm_receive = bat_iv_ogm_receive,
+};
+
+int __init bat_iv_init(void)
+{
+	return bat_algo_register(&batman_iv);
 }
diff --git a/net/batman-adv/bat_ogm.h b/net/batman-adv/bat_ogm.h
deleted file mode 100644
index 69329c1..0000000
--- a/net/batman-adv/bat_ogm.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA
- *
- */
-
-#ifndef _NET_BATMAN_ADV_OGM_H_
-#define _NET_BATMAN_ADV_OGM_H_
-
-#include "main.h"
-
-void bat_ogm_init(struct hard_iface *hard_iface);
-void bat_ogm_init_primary(struct hard_iface *hard_iface);
-void bat_ogm_update_mac(struct hard_iface *hard_iface);
-void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes);
-void bat_ogm_emit(struct forw_packet *forw_packet);
-void bat_ogm_receive(const struct ethhdr *ethhdr, unsigned char *packet_buff,
-		     int packet_len, struct hard_iface *if_incoming);
-
-#endif /* _NET_BATMAN_ADV_OGM_H_ */
diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c
index c25492f..480ae0a 100644
--- a/net/batman-adv/bat_sysfs.c
+++ b/net/batman-adv/bat_sysfs.c
@@ -272,6 +272,13 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr,
 	return count;
 }
 
+static ssize_t show_bat_algo(struct kobject *kobj, struct attribute *attr,
+			    char *buff)
+{
+	struct bat_priv *bat_priv = kobj_to_batpriv(kobj);
+	return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name);
+}
+
 static void post_gw_deselect(struct net_device *net_dev)
 {
 	struct bat_priv *bat_priv = netdev_priv(net_dev);
@@ -382,6 +389,7 @@ BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
 BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu);
 BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
 static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode);
+static BAT_ATTR(routing_algo, S_IRUGO, show_bat_algo, NULL);
 static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode);
 BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL);
 BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL);
@@ -399,6 +407,7 @@ static struct bat_attribute *mesh_attrs[] = {
 	&bat_attr_fragmentation,
 	&bat_attr_ap_isolation,
 	&bat_attr_vis_mode,
+	&bat_attr_routing_algo,
 	&bat_attr_gw_mode,
 	&bat_attr_orig_interval,
 	&bat_attr_hop_penalty,
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 7704df4..ff5ba40 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -28,7 +28,6 @@
 #include "bat_sysfs.h"
 #include "originator.h"
 #include "hash.h"
-#include "bat_ogm.h"
 
 #include <linux/if_arp.h>
 
@@ -147,7 +146,7 @@ static void primary_if_select(struct bat_priv *bat_priv,
 	if (!new_hard_iface)
 		return;
 
-	bat_ogm_init_primary(new_hard_iface);
+	bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface);
 	primary_if_update_addr(bat_priv);
 }
 
@@ -233,7 +232,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
 
 	bat_priv = netdev_priv(hard_iface->soft_iface);
 
-	bat_ogm_update_mac(hard_iface);
+	bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface);
 	hard_iface->if_status = IF_TO_BE_ACTIVATED;
 
 	/**
@@ -281,6 +280,14 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 	if (!atomic_inc_not_zero(&hard_iface->refcount))
 		goto out;
 
+	/* hard-interface is part of a bridge */
+	if (hard_iface->net_dev->priv_flags & IFF_BRIDGE_PORT)
+		pr_err("You are about to enable batman-adv on '%s' which "
+		       "already is part of a bridge. Unless you know exactly "
+		       "what you are doing this is probably wrong and won't "
+		       "work the way you think it would.\n",
+		       hard_iface->net_dev->name);
+
 	soft_iface = dev_get_by_name(&init_net, iface_name);
 
 	if (!soft_iface) {
@@ -307,7 +314,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
 	hard_iface->soft_iface = soft_iface;
 	bat_priv = netdev_priv(hard_iface->soft_iface);
 
-	bat_ogm_init(hard_iface);
+	bat_priv->bat_algo_ops->bat_ogm_init(hard_iface);
 
 	if (!hard_iface->packet_buff) {
 		bat_err(hard_iface->soft_iface, "Can't add interface packet "
@@ -527,9 +534,10 @@ static int hard_if_event(struct notifier_block *this,
 			goto hardif_put;
 
 		check_known_mac_addr(hard_iface->net_dev);
-		bat_ogm_update_mac(hard_iface);
 
 		bat_priv = netdev_priv(hard_iface->soft_iface);
+		bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface);
+
 		primary_if = primary_if_get_selected(bat_priv);
 		if (!primary_if)
 			goto hardif_put;
@@ -590,17 +598,17 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
 
 	batman_ogm_packet = (struct batman_ogm_packet *)skb->data;
 
-	if (batman_ogm_packet->version != COMPAT_VERSION) {
+	if (batman_ogm_packet->header.version != COMPAT_VERSION) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Drop packet: incompatible batman version (%i)\n",
-			batman_ogm_packet->version);
+			batman_ogm_packet->header.version);
 		goto err_free;
 	}
 
 	/* all receive handlers return whether they received or reused
 	 * the supplied skb. if not, we have to free the skb. */
 
-	switch (batman_ogm_packet->packet_type) {
+	switch (batman_ogm_packet->header.packet_type) {
 		/* batman originator packet */
 	case BAT_OGM:
 		ret = recv_bat_ogm_packet(skb, hard_iface);
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index d9c1e7b..5d69e10 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -191,7 +191,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
 		goto free_skb;
 	}
 
-	if (icmp_packet->packet_type != BAT_ICMP) {
+	if (icmp_packet->header.packet_type != BAT_ICMP) {
 		bat_dbg(DBG_BATMAN, bat_priv,
 			"Error - can't send packet from char device: "
 			"got bogus packet type (expected: BAT_ICMP)\n");
@@ -209,9 +209,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
 
 	icmp_packet->uid = socket_client->index;
 
-	if (icmp_packet->version != COMPAT_VERSION) {
+	if (icmp_packet->header.version != COMPAT_VERSION) {
 		icmp_packet->msg_type = PARAMETER_PROBLEM;
-		icmp_packet->version = COMPAT_VERSION;
+		icmp_packet->header.version = COMPAT_VERSION;
 		bat_socket_add_packet(socket_client, icmp_packet, packet_len);
 		goto free_skb;
 	}
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index fb87bdc..8ae497b 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -32,11 +32,14 @@
 #include "gateway_client.h"
 #include "vis.h"
 #include "hash.h"
+#include "bat_algo.h"
 
 
 /* List manipulations on hardif_list have to be rtnl_lock()'ed,
  * list traversals just rcu-locked */
 struct list_head hardif_list;
+char bat_routing_algo[20] = "BATMAN IV";
+static struct hlist_head bat_algo_list;
 
 unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
@@ -45,6 +48,9 @@ struct workqueue_struct *bat_event_workqueue;
 static int __init batman_init(void)
 {
 	INIT_LIST_HEAD(&hardif_list);
+	INIT_HLIST_HEAD(&bat_algo_list);
+
+	bat_iv_init();
 
 	/* the name should not be longer than 10 chars - see
 	 * http://lwn.net/Articles/23634/ */
@@ -170,9 +176,110 @@ int is_my_mac(const uint8_t *addr)
 	}
 	rcu_read_unlock();
 	return 0;
+}
+
+static struct bat_algo_ops *bat_algo_get(char *name)
+{
+	struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp;
+	struct hlist_node *node;
+
+	hlist_for_each_entry(bat_algo_ops_tmp, node, &bat_algo_list, list) {
+		if (strcmp(bat_algo_ops_tmp->name, name) != 0)
+			continue;
+
+		bat_algo_ops = bat_algo_ops_tmp;
+		break;
+	}
+
+	return bat_algo_ops;
+}
+
+int bat_algo_register(struct bat_algo_ops *bat_algo_ops)
+{
+	struct bat_algo_ops *bat_algo_ops_tmp;
+	int ret = -1;
+
+	bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name);
+	if (bat_algo_ops_tmp) {
+		pr_info("Trying to register already registered routing "
+			"algorithm: %s\n", bat_algo_ops->name);
+		goto out;
+	}
+
+	/* all algorithms must implement all ops (for now) */
+	if (!bat_algo_ops->bat_ogm_init ||
+	    !bat_algo_ops->bat_ogm_init_primary ||
+	    !bat_algo_ops->bat_ogm_update_mac ||
+	    !bat_algo_ops->bat_ogm_schedule ||
+	    !bat_algo_ops->bat_ogm_emit ||
+	    !bat_algo_ops->bat_ogm_receive) {
+		pr_info("Routing algo '%s' does not implement required ops\n",
+			bat_algo_ops->name);
+		goto out;
+	}
+
+	INIT_HLIST_NODE(&bat_algo_ops->list);
+	hlist_add_head(&bat_algo_ops->list, &bat_algo_list);
+	ret = 0;
+
+out:
+	return ret;
+}
+
+int bat_algo_select(struct bat_priv *bat_priv, char *name)
+{
+	struct bat_algo_ops *bat_algo_ops;
+	int ret = -1;
+
+	bat_algo_ops = bat_algo_get(name);
+	if (!bat_algo_ops)
+		goto out;
+
+	bat_priv->bat_algo_ops = bat_algo_ops;
+	ret = 0;
+
+out:
+	return ret;
+}
+
+int bat_algo_seq_print_text(struct seq_file *seq, void *offset)
+{
+	struct bat_algo_ops *bat_algo_ops;
+	struct hlist_node *node;
+
+	seq_printf(seq, "Available routing algorithms:\n");
+
+	hlist_for_each_entry(bat_algo_ops, node, &bat_algo_list, list) {
+		seq_printf(seq, "%s\n", bat_algo_ops->name);
+	}
+
+	return 0;
+}
+
+static int param_set_ra(const char *val, const struct kernel_param *kp)
+{
+	struct bat_algo_ops *bat_algo_ops;
 
+	bat_algo_ops = bat_algo_get((char *)val);
+	if (!bat_algo_ops) {
+		pr_err("Routing algorithm '%s' is not supported\n", val);
+		return -EINVAL;
+	}
+
+	return param_set_copystring(val, kp);
 }
 
+static const struct kernel_param_ops param_ops_ra = {
+	.set = param_set_ra,
+	.get = param_get_string,
+};
+
+static struct kparam_string __param_string_ra = {
+	.maxlen = sizeof(bat_routing_algo),
+	.string = bat_routing_algo,
+};
+
+module_param_cb(routing_algo, &param_ops_ra, &__param_string_ra, 0644);
 module_init(batman_init);
 module_exit(batman_exit);
 
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 86354e0..586afaf 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -147,6 +147,7 @@ enum dbg_level {
 #include <linux/seq_file.h>
 #include "types.h"
 
+extern char bat_routing_algo[];
 extern struct list_head hardif_list;
 
 extern unsigned char broadcast_addr[];
@@ -157,6 +158,9 @@ void mesh_free(struct net_device *soft_iface);
 void inc_module_count(void);
 void dec_module_count(void);
 int is_my_mac(const uint8_t *addr);
+int bat_algo_register(struct bat_algo_ops *bat_algo_ops);
+int bat_algo_select(struct bat_priv *bat_priv, char *name);
+int bat_algo_seq_print_text(struct seq_file *seq, void *offset);
 
 #ifdef CONFIG_BATMAN_ADV_DEBUG
 int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3);
@@ -202,6 +206,17 @@ static inline int compare_eth(const void *data1, const void *data2)
 	return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
 }
 
+/**
+ * has_timed_out - compares current time (jiffies) and timestamp + timeout
+ * @timestamp:		base value to compare with (in jiffies)
+ * @timeout:		added to base value before comparing (in milliseconds)
+ *
+ * Returns true if current time is after timestamp + timeout
+ */
+static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout)
+{
+	return time_is_before_jiffies(timestamp + msecs_to_jiffies(timeout));
+}
 
 #define atomic_dec_not_zero(v)	atomic_add_unless((v), -1, 0)
 
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 0bc2045..847ff7e 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -219,6 +219,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
 	/* extra reference for return */
 	atomic_set(&orig_node->refcount, 2);
 
+	orig_node->tt_initialised = false;
 	orig_node->tt_poss_change = false;
 	orig_node->bat_priv = bat_priv;
 	memcpy(orig_node->orig, addr, ETH_ALEN);
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h
index 4d9e54c..88c717b 100644
--- a/net/batman-adv/packet.h
+++ b/net/batman-adv/packet.h
@@ -90,10 +90,14 @@ enum tt_client_flags {
 	TT_CLIENT_PENDING = 1 << 10
 };
 
-struct batman_ogm_packet {
+struct batman_header {
 	uint8_t  packet_type;
 	uint8_t  version;  /* batman version field */
 	uint8_t  ttl;
+} __packed;
+
+struct batman_ogm_packet {
+	struct batman_header header;
 	uint8_t  flags;    /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
 	uint32_t seqno;
 	uint8_t  orig[6];
@@ -108,9 +112,7 @@ struct batman_ogm_packet {
 #define BATMAN_OGM_LEN sizeof(struct batman_ogm_packet)
 
 struct icmp_packet {
-	uint8_t  packet_type;
-	uint8_t  version;  /* batman version field */
-	uint8_t  ttl;
+	struct batman_header header;
 	uint8_t  msg_type; /* see ICMP message types above */
 	uint8_t  dst[6];
 	uint8_t  orig[6];
@@ -124,9 +126,7 @@ struct icmp_packet {
 /* icmp_packet_rr must start with all fields from imcp_packet
  * as this is assumed by code that handles ICMP packets */
 struct icmp_packet_rr {
-	uint8_t  packet_type;
-	uint8_t  version;  /* batman version field */
-	uint8_t  ttl;
+	struct batman_header header;
 	uint8_t  msg_type; /* see ICMP message types above */
 	uint8_t  dst[6];
 	uint8_t  orig[6];
@@ -137,17 +137,13 @@ struct icmp_packet_rr {
 } __packed;
 
 struct unicast_packet {
-	uint8_t  packet_type;
-	uint8_t  version;  /* batman version field */
-	uint8_t  ttl;
+	struct batman_header header;
 	uint8_t  ttvn; /* destination translation table version number */
 	uint8_t  dest[6];
 } __packed;
 
 struct unicast_frag_packet {
-	uint8_t  packet_type;
-	uint8_t  version;  /* batman version field */
-	uint8_t  ttl;
+	struct batman_header header;
 	uint8_t  ttvn; /* destination translation table version number */
 	uint8_t  dest[6];
 	uint8_t  flags;
@@ -157,18 +153,14 @@ struct unicast_frag_packet {
 } __packed;
 
 struct bcast_packet {
-	uint8_t  packet_type;
-	uint8_t  version;  /* batman version field */
-	uint8_t  ttl;
+	struct batman_header header;
 	uint8_t  reserved;
 	uint32_t seqno;
 	uint8_t  orig[6];
 } __packed;
 
 struct vis_packet {
-	uint8_t  packet_type;
-	uint8_t  version;        /* batman version field */
-	uint8_t  ttl;		 /* TTL */
+	struct batman_header header;
 	uint8_t  vis_type;	 /* which type of vis-participant sent this? */
 	uint32_t seqno;		 /* sequence number */
 	uint8_t  entries;	 /* number of entries behind this struct */
@@ -179,9 +171,7 @@ struct vis_packet {
 } __packed;
 
 struct tt_query_packet {
-	uint8_t  packet_type;
-	uint8_t  version;  /* batman version field */
-	uint8_t  ttl;
+	struct batman_header header;
 	/* the flag field is a combination of:
 	 * - TT_REQUEST or TT_RESPONSE
 	 * - TT_FULL_TABLE */
@@ -202,9 +192,7 @@ struct tt_query_packet {
 } __packed;
 
 struct roam_adv_packet {
-	uint8_t  packet_type;
-	uint8_t  version;
-	uint8_t  ttl;
+	struct batman_header header;
 	uint8_t  reserved;
 	uint8_t  dst[ETH_ALEN];
 	uint8_t  src[ETH_ALEN];
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 773e606..b72d7f3 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -29,7 +29,6 @@
 #include "originator.h"
 #include "vis.h"
 #include "unicast.h"
-#include "bat_ogm.h"
 
 void slide_own_bcast_window(struct hard_iface *hard_iface)
 {
@@ -248,6 +247,7 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
 
 int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
 {
+	struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
 	struct ethhdr *ethhdr;
 
 	/* drop packet if it has not necessary minimum size */
@@ -272,9 +272,7 @@ int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface)
 	if (skb_linearize(skb) < 0)
 		return NET_RX_DROP;
 
-	ethhdr = (struct ethhdr *)skb_mac_header(skb);
-
-	bat_ogm_receive(ethhdr, skb->data, skb_headlen(skb), hard_iface);
+	bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb);
 
 	kfree_skb(skb);
 	return NET_RX_SUCCESS;
@@ -320,7 +318,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
 	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
 	memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
 	icmp_packet->msg_type = ECHO_REPLY;
-	icmp_packet->ttl = TTL;
+	icmp_packet->header.ttl = TTL;
 
 	send_skb_packet(skb, router->if_incoming, router->addr);
 	ret = NET_RX_SUCCESS;
@@ -376,7 +374,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
 	memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN);
 	memcpy(icmp_packet->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
 	icmp_packet->msg_type = TTL_EXCEEDED;
-	icmp_packet->ttl = TTL;
+	icmp_packet->header.ttl = TTL;
 
 	send_skb_packet(skb, router->if_incoming, router->addr);
 	ret = NET_RX_SUCCESS;
@@ -441,7 +439,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 		return recv_my_icmp_packet(bat_priv, skb, hdr_size);
 
 	/* TTL exceeded */
-	if (icmp_packet->ttl < 2)
+	if (icmp_packet->header.ttl < 2)
 		return recv_icmp_ttl_exceeded(bat_priv, skb);
 
 	/* get routing information */
@@ -460,7 +458,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	icmp_packet = (struct icmp_packet_rr *)skb->data;
 
 	/* decrement ttl */
-	icmp_packet->ttl--;
+	icmp_packet->header.ttl--;
 
 	/* route it */
 	send_skb_packet(skb, router->if_incoming, router->addr);
@@ -815,7 +813,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	unicast_packet = (struct unicast_packet *)skb->data;
 
 	/* TTL exceeded */
-	if (unicast_packet->ttl < 2) {
+	if (unicast_packet->header.ttl < 2) {
 		pr_debug("Warning - can't forward unicast packet from %pM to "
 			 "%pM: ttl exceeded\n", ethhdr->h_source,
 			 unicast_packet->dest);
@@ -840,7 +838,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 
 	unicast_packet = (struct unicast_packet *)skb->data;
 
-	if (unicast_packet->packet_type == BAT_UNICAST &&
+	if (unicast_packet->header.packet_type == BAT_UNICAST &&
 	    atomic_read(&bat_priv->fragmentation) &&
 	    skb->len > neigh_node->if_incoming->net_dev->mtu) {
 		ret = frag_send_skb(skb, bat_priv,
@@ -848,7 +846,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 		goto out;
 	}
 
-	if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
+	if (unicast_packet->header.packet_type == BAT_UNICAST_FRAG &&
 	    frag_can_reassemble(skb, neigh_node->if_incoming->net_dev->mtu)) {
 
 		ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
@@ -867,7 +865,7 @@ int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	}
 
 	/* decrement ttl */
-	unicast_packet->ttl--;
+	unicast_packet->header.ttl--;
 
 	/* route it */
 	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
@@ -1041,7 +1039,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
 	if (is_my_mac(bcast_packet->orig))
 		goto out;
 
-	if (bcast_packet->ttl < 2)
+	if (bcast_packet->header.ttl < 2)
 		goto out;
 
 	orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 8a684eb..019337e 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -28,7 +28,6 @@
 #include "vis.h"
 #include "gateway_common.h"
 #include "originator.h"
-#include "bat_ogm.h"
 
 static void send_outstanding_bcast_packet(struct work_struct *work);
 
@@ -168,7 +167,7 @@ void schedule_bat_ogm(struct hard_iface *hard_iface)
 	if (primary_if)
 		hardif_free_ref(primary_if);
 
-	bat_ogm_schedule(hard_iface, tt_num_changes);
+	bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface, tt_num_changes);
 }
 
 static void forw_packet_free(struct forw_packet *forw_packet)
@@ -234,7 +233,7 @@ int add_bcast_packet_to_list(struct bat_priv *bat_priv,
 
 	/* as we have a copy now, it is safe to decrease the TTL */
 	bcast_packet = (struct bcast_packet *)newskb->data;
-	bcast_packet->ttl--;
+	bcast_packet->header.ttl--;
 
 	skb_reset_mac_header(newskb);
 
@@ -318,7 +317,7 @@ void send_outstanding_bat_ogm_packet(struct work_struct *work)
 	if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING)
 		goto out;
 
-	bat_ogm_emit(forw_packet);
+	bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet);
 
 	/**
 	 * we have to have at least one packet in the queue
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 987c75a..2d8bd2a 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -457,10 +457,10 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
 		batman_ogm_packet = (struct batman_ogm_packet *)
 							(skb->data + ETH_HLEN);
 
-	if (batman_ogm_packet->version != COMPAT_VERSION)
+	if (batman_ogm_packet->header.version != COMPAT_VERSION)
 		goto out;
 
-	if (batman_ogm_packet->packet_type != BAT_OGM)
+	if (batman_ogm_packet->header.packet_type != BAT_OGM)
 		goto out;
 
 	if (!(batman_ogm_packet->flags & PRIMARIES_FIRST_HOP))
@@ -541,6 +541,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
 	}
 
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	return 0;
 }
 
@@ -632,11 +633,11 @@ static int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
 			goto dropped;
 
 		bcast_packet = (struct bcast_packet *)skb->data;
-		bcast_packet->version = COMPAT_VERSION;
-		bcast_packet->ttl = TTL;
+		bcast_packet->header.version = COMPAT_VERSION;
+		bcast_packet->header.ttl = TTL;
 
 		/* batman packet type: broadcast */
-		bcast_packet->packet_type = BAT_BCAST;
+		bcast_packet->header.packet_type = BAT_BCAST;
 
 		/* hw address of first interface is the orig mac because only
 		 * this mac is known throughout the mesh */
@@ -725,8 +726,8 @@ void interface_rx(struct net_device *soft_iface,
 		skb_push(skb, hdr_size);
 		unicast_packet = (struct unicast_packet *)skb->data;
 
-		if ((unicast_packet->packet_type != BAT_UNICAST) &&
-		    (unicast_packet->packet_type != BAT_UNICAST_FRAG))
+		if ((unicast_packet->header.packet_type != BAT_UNICAST) &&
+		    (unicast_packet->header.packet_type != BAT_UNICAST_FRAG))
 			goto dropped;
 
 		skb_reset_mac_header(skb);
@@ -783,7 +784,6 @@ static const struct net_device_ops bat_netdev_ops = {
 static void interface_setup(struct net_device *dev)
 {
 	struct bat_priv *priv = netdev_priv(dev);
-	char dev_addr[ETH_ALEN];
 
 	ether_setup(dev);
 
@@ -800,8 +800,7 @@ static void interface_setup(struct net_device *dev)
 	dev->hard_header_len = BAT_HEADER_LEN;
 
 	/* generate random address */
-	random_ether_addr(dev_addr);
-	memcpy(dev->dev_addr, dev_addr, ETH_ALEN);
+	eth_hw_addr_random(dev);
 
 	SET_ETHTOOL_OPS(dev, &bat_ethtool_ops);
 
@@ -855,6 +854,10 @@ struct net_device *softif_create(const char *name)
 	bat_priv->primary_if = NULL;
 	bat_priv->num_ifaces = 0;
 
+	ret = bat_algo_select(bat_priv, bat_routing_algo);
+	if (ret < 0)
+		goto unreg_soft_iface;
+
 	ret = sysfs_add_meshif(soft_iface);
 	if (ret < 0)
 		goto unreg_soft_iface;
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index ab8dea8..a84e804 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -108,14 +108,6 @@ static struct tt_global_entry *tt_global_hash_find(struct bat_priv *bat_priv,
 
 }
 
-static bool is_out_of_time(unsigned long starting_time, unsigned long timeout)
-{
-	unsigned long deadline;
-	deadline = starting_time + msecs_to_jiffies(timeout);
-
-	return time_after(jiffies, deadline);
-}
-
 static void tt_local_entry_free_ref(struct tt_local_entry *tt_local_entry)
 {
 	if (atomic_dec_and_test(&tt_local_entry->common.refcount))
@@ -420,8 +412,8 @@ static void tt_local_purge(struct bat_priv *bat_priv)
 			if (tt_local_entry->common.flags & TT_CLIENT_PENDING)
 				continue;
 
-			if (!is_out_of_time(tt_local_entry->last_seen,
-					    TT_LOCAL_TIMEOUT * 1000))
+			if (!has_timed_out(tt_local_entry->last_seen,
+					   TT_LOCAL_TIMEOUT * 1000))
 				continue;
 
 			tt_local_set_pending(bat_priv, tt_local_entry,
@@ -733,6 +725,7 @@ void tt_global_del_orig(struct bat_priv *bat_priv,
 		spin_unlock_bh(list_lock);
 	}
 	atomic_set(&orig_node->tt_size, 0);
+	orig_node->tt_initialised = false;
 }
 
 static void tt_global_roam_purge(struct bat_priv *bat_priv)
@@ -757,8 +750,8 @@ static void tt_global_roam_purge(struct bat_priv *bat_priv)
 						       common);
 			if (!(tt_global_entry->common.flags & TT_CLIENT_ROAM))
 				continue;
-			if (!is_out_of_time(tt_global_entry->roam_at,
-					    TT_CLIENT_ROAM_TIMEOUT * 1000))
+			if (!has_timed_out(tt_global_entry->roam_at,
+					   TT_CLIENT_ROAM_TIMEOUT * 1000))
 				continue;
 
 			bat_dbg(DBG_TT, bat_priv, "Deleting global "
@@ -977,8 +970,8 @@ static void tt_req_purge(struct bat_priv *bat_priv)
 
 	spin_lock_bh(&bat_priv->tt_req_list_lock);
 	list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) {
-		if (is_out_of_time(node->issued_at,
-		    TT_REQUEST_TIMEOUT * 1000)) {
+		if (has_timed_out(node->issued_at,
+				  TT_REQUEST_TIMEOUT * 1000)) {
 			list_del(&node->list);
 			kfree(node);
 		}
@@ -996,8 +989,8 @@ static struct tt_req_node *new_tt_req_node(struct bat_priv *bat_priv,
 	spin_lock_bh(&bat_priv->tt_req_list_lock);
 	list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) {
 		if (compare_eth(tt_req_node_tmp, orig_node) &&
-		    !is_out_of_time(tt_req_node_tmp->issued_at,
-				    TT_REQUEST_TIMEOUT * 1000))
+		    !has_timed_out(tt_req_node_tmp->issued_at,
+				   TT_REQUEST_TIMEOUT * 1000))
 			goto unlock;
 	}
 
@@ -1134,11 +1127,11 @@ static int send_tt_request(struct bat_priv *bat_priv,
 	tt_request = (struct tt_query_packet *)skb_put(skb,
 				sizeof(struct tt_query_packet));
 
-	tt_request->packet_type = BAT_TT_QUERY;
-	tt_request->version = COMPAT_VERSION;
+	tt_request->header.packet_type = BAT_TT_QUERY;
+	tt_request->header.version = COMPAT_VERSION;
 	memcpy(tt_request->src, primary_if->net_dev->dev_addr, ETH_ALEN);
 	memcpy(tt_request->dst, dst_orig_node->orig, ETH_ALEN);
-	tt_request->ttl = TTL;
+	tt_request->header.ttl = TTL;
 	tt_request->ttvn = ttvn;
 	tt_request->tt_data = tt_crc;
 	tt_request->flags = TT_REQUEST;
@@ -1264,9 +1257,9 @@ static bool send_other_tt_response(struct bat_priv *bat_priv,
 		tt_response = (struct tt_query_packet *)skb->data;
 	}
 
-	tt_response->packet_type = BAT_TT_QUERY;
-	tt_response->version = COMPAT_VERSION;
-	tt_response->ttl = TTL;
+	tt_response->header.packet_type = BAT_TT_QUERY;
+	tt_response->header.version = COMPAT_VERSION;
+	tt_response->header.ttl = TTL;
 	memcpy(tt_response->src, req_dst_orig_node->orig, ETH_ALEN);
 	memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
 	tt_response->flags = TT_RESPONSE;
@@ -1381,9 +1374,9 @@ static bool send_my_tt_response(struct bat_priv *bat_priv,
 		tt_response = (struct tt_query_packet *)skb->data;
 	}
 
-	tt_response->packet_type = BAT_TT_QUERY;
-	tt_response->version = COMPAT_VERSION;
-	tt_response->ttl = TTL;
+	tt_response->header.packet_type = BAT_TT_QUERY;
+	tt_response->header.version = COMPAT_VERSION;
+	tt_response->header.ttl = TTL;
 	memcpy(tt_response->src, primary_if->net_dev->dev_addr, ETH_ALEN);
 	memcpy(tt_response->dst, tt_request->src, ETH_ALEN);
 	tt_response->flags = TT_RESPONSE;
@@ -1450,6 +1443,7 @@ static void _tt_update_changes(struct bat_priv *bat_priv,
 				 */
 				return;
 	}
+	orig_node->tt_initialised = true;
 }
 
 static void tt_fill_gtable(struct bat_priv *bat_priv,
@@ -1589,8 +1583,8 @@ static void tt_roam_purge(struct bat_priv *bat_priv)
 
 	spin_lock_bh(&bat_priv->tt_roam_list_lock);
 	list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) {
-		if (!is_out_of_time(node->first_time,
-				    ROAMING_MAX_TIME * 1000))
+		if (!has_timed_out(node->first_time,
+				   ROAMING_MAX_TIME * 1000))
 			continue;
 
 		list_del(&node->list);
@@ -1617,8 +1611,8 @@ static bool tt_check_roam_count(struct bat_priv *bat_priv,
 		if (!compare_eth(tt_roam_node->addr, client))
 			continue;
 
-		if (is_out_of_time(tt_roam_node->first_time,
-				   ROAMING_MAX_TIME * 1000))
+		if (has_timed_out(tt_roam_node->first_time,
+				  ROAMING_MAX_TIME * 1000))
 			continue;
 
 		if (!atomic_dec_not_zero(&tt_roam_node->counter))
@@ -1669,9 +1663,9 @@ void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
 	roam_adv_packet = (struct roam_adv_packet *)skb_put(skb,
 					sizeof(struct roam_adv_packet));
 
-	roam_adv_packet->packet_type = BAT_ROAM_ADV;
-	roam_adv_packet->version = COMPAT_VERSION;
-	roam_adv_packet->ttl = TTL;
+	roam_adv_packet->header.packet_type = BAT_ROAM_ADV;
+	roam_adv_packet->header.version = COMPAT_VERSION;
+	roam_adv_packet->header.ttl = TTL;
 	primary_if = primary_if_get_selected(bat_priv);
 	if (!primary_if)
 		goto out;
@@ -1854,8 +1848,10 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 	uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
 	bool full_table = true;
 
-	/* the ttvn increased by one -> we can apply the attached changes */
-	if (ttvn - orig_ttvn == 1) {
+	/* orig table not initialised AND first diff is in the OGM OR the ttvn
+	 * increased by one -> we can apply the attached changes */
+	if ((!orig_node->tt_initialised && ttvn == 1) ||
+	    ttvn - orig_ttvn == 1) {
 		/* the OGM could not contain the changes due to their size or
 		 * because they have already been sent TT_OGM_APPEND_MAX times.
 		 * In this case send a tt request */
@@ -1889,7 +1885,8 @@ void tt_update_orig(struct bat_priv *bat_priv, struct orig_node *orig_node,
 	} else {
 		/* if we missed more than one change or our tables are not
 		 * in sync anymore -> request fresh tt data */
-		if (ttvn != orig_ttvn || orig_node->tt_crc != tt_crc) {
+		if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
+		    orig_node->tt_crc != tt_crc) {
 request_table:
 			bat_dbg(DBG_TT, bat_priv, "TT inconsistency for %pM. "
 				"Need to retrieve the correct information "
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index e9eb043..650ce5f 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -81,6 +81,7 @@ struct orig_node {
 	int16_t tt_buff_len;
 	spinlock_t tt_buff_lock; /* protects tt_buff */
 	atomic_t tt_size;
+	bool tt_initialised;
 	/* The tt_poss_change flag is used to detect an ongoing roaming phase.
 	 * If true, then I sent a Roaming_adv to this orig_node and I have to
 	 * inspect every packet directed to it to check whether it is still
@@ -205,6 +206,7 @@ struct bat_priv {
 	atomic_t gw_reselect;
 	struct hard_iface __rcu *primary_if;  /* rcu protected pointer */
 	struct vis_info *my_vis_info;
+	struct bat_algo_ops *bat_algo_ops;
 };
 
 struct socket_client {
@@ -343,4 +345,23 @@ struct softif_neigh {
 	struct rcu_head rcu;
 };
 
+struct bat_algo_ops {
+	struct hlist_node list;
+	char *name;
+	/* init OGM when hard-interface is enabled */
+	void (*bat_ogm_init)(struct hard_iface *hard_iface);
+	/* init primary OGM when primary interface is selected */
+	void (*bat_ogm_init_primary)(struct hard_iface *hard_iface);
+	/* init mac addresses of the OGM belonging to this hard-interface */
+	void (*bat_ogm_update_mac)(struct hard_iface *hard_iface);
+	/* prepare a new outgoing OGM for the send queue */
+	void (*bat_ogm_schedule)(struct hard_iface *hard_iface,
+				 int tt_num_changes);
+	/* send scheduled OGM */
+	void (*bat_ogm_emit)(struct forw_packet *forw_packet);
+	/* receive incoming OGM */
+	void (*bat_ogm_receive)(struct hard_iface *if_incoming,
+				struct sk_buff *skb);
+};
+
 #endif /* _NET_BATMAN_ADV_TYPES_H_ */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 07d1c1d..6f3c659 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -67,7 +67,7 @@ static struct sk_buff *frag_merge_packet(struct list_head *head,
 
 	memmove(skb->data + uni_diff, skb->data, hdr_len);
 	unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff);
-	unicast_packet->packet_type = BAT_UNICAST;
+	unicast_packet->header.packet_type = BAT_UNICAST;
 
 	return skb;
 
@@ -251,9 +251,9 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
 
 	memcpy(frag1, &tmp_uc, sizeof(tmp_uc));
 
-	frag1->ttl--;
-	frag1->version = COMPAT_VERSION;
-	frag1->packet_type = BAT_UNICAST_FRAG;
+	frag1->header.ttl--;
+	frag1->header.version = COMPAT_VERSION;
+	frag1->header.packet_type = BAT_UNICAST_FRAG;
 
 	memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
 	memcpy(frag2, frag1, sizeof(*frag2));
@@ -320,11 +320,11 @@ find_router:
 
 	unicast_packet = (struct unicast_packet *)skb->data;
 
-	unicast_packet->version = COMPAT_VERSION;
+	unicast_packet->header.version = COMPAT_VERSION;
 	/* batman packet type: unicast */
-	unicast_packet->packet_type = BAT_UNICAST;
+	unicast_packet->header.packet_type = BAT_UNICAST;
 	/* set unicast ttl */
-	unicast_packet->ttl = TTL;
+	unicast_packet->header.ttl = TTL;
 	/* copy the destination for faster routing */
 	memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN);
 	/* set the destination tt version number */
@@ -335,7 +335,7 @@ find_router:
 	    data_len + sizeof(*unicast_packet) >
 				neigh_node->if_incoming->net_dev->mtu) {
 		/* send frag skb decreases ttl */
-		unicast_packet->ttl++;
+		unicast_packet->header.ttl++;
 		ret = frag_send_skb(skb, bat_priv,
 				    neigh_node->if_incoming, neigh_node->addr);
 		goto out;
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index cc3b9f2..ac7e661 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -617,7 +617,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
 	packet->vis_type = atomic_read(&bat_priv->vis_mode);
 
 	memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
-	packet->ttl = TTL;
+	packet->header.ttl = TTL;
 	packet->seqno = htonl(ntohl(packet->seqno) + 1);
 	packet->entries = 0;
 	skb_trim(info->skb_packet, sizeof(*packet));
@@ -818,19 +818,19 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info)
 		goto out;
 
 	packet = (struct vis_packet *)info->skb_packet->data;
-	if (packet->ttl < 2) {
+	if (packet->header.ttl < 2) {
 		pr_debug("Error - can't send vis packet: ttl exceeded\n");
 		goto out;
 	}
 
 	memcpy(packet->sender_orig, primary_if->net_dev->dev_addr, ETH_ALEN);
-	packet->ttl--;
+	packet->header.ttl--;
 
 	if (is_broadcast_ether_addr(packet->target_orig))
 		broadcast_vis_packet(bat_priv, info);
 	else
 		unicast_vis_packet(bat_priv, info);
-	packet->ttl++; /* restore TTL */
+	packet->header.ttl++; /* restore TTL */
 
 out:
 	if (primary_if)
@@ -910,9 +910,9 @@ int vis_init(struct bat_priv *bat_priv)
 	INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list);
 	kref_init(&bat_priv->my_vis_info->refcount);
 	bat_priv->my_vis_info->bat_priv = bat_priv;
-	packet->version = COMPAT_VERSION;
-	packet->packet_type = BAT_VIS;
-	packet->ttl = TTL;
+	packet->header.version = COMPAT_VERSION;
+	packet->header.packet_type = BAT_VIS;
+	packet->header.ttl = TTL;
 	packet->seqno = 0;
 	packet->entries = 0;
 
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ef92864..72eb187 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -71,19 +71,16 @@ static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
 	"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
 };
 
-static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+void bt_sock_reclassify_lock(struct sock *sk, int proto)
 {
-	struct sock *sk = sock->sk;
-
-	if (!sk)
-		return;
-
+	BUG_ON(!sk);
 	BUG_ON(sock_owned_by_user(sk));
 
 	sock_lock_init_class_and_name(sk,
 			bt_slock_key_strings[proto], &bt_slock_key[proto],
 				bt_key_strings[proto], &bt_lock_key[proto]);
 }
+EXPORT_SYMBOL(bt_sock_reclassify_lock);
 
 int bt_sock_register(int proto, const struct net_proto_family *ops)
 {
@@ -145,7 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto,
 
 	if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
 		err = bt_proto[proto]->create(net, sock, proto, kern);
-		bt_sock_reclassify_lock(sock, proto);
+		if (!err)
+			bt_sock_reclassify_lock(sock->sk, proto);
 		module_put(bt_proto[proto]->owner);
 	}
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3db4324..07bc69e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -635,6 +635,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 
 	if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
 		struct hci_cp_auth_requested cp;
+
+		/* encrypt must be pending if auth is also pending */
+		set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+
 		cp.handle = cpu_to_le16(conn->handle);
 		hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
 							sizeof(cp), &cp);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9de9371..5aeb624 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -640,7 +640,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	/* Reset device */
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
-	if (!test_bit(HCI_RAW, &hdev->flags)) {
+	if (!test_bit(HCI_RAW, &hdev->flags) &&
+				test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
 		set_bit(HCI_INIT, &hdev->flags);
 		__hci_request(hdev, hci_reset_req, 0,
 					msecs_to_jiffies(250));
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index faf0b11..32d338c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
 	hci_chan_del(conn->hchan);
 
 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
-		__cancel_delayed_work(&conn->info_timer);
+		cancel_delayed_work_sync(&conn->info_timer);
 
 	if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
-		__cancel_delayed_work(&conn->security_timer);
+		cancel_delayed_work_sync(&conn->security_timer);
 		smp_chan_destroy(conn);
 	}
 
@@ -1120,7 +1120,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
 	return c1;
 }
 
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
 {
 	struct sock *sk = chan->sk;
 	bdaddr_t *src = &bt_sk(sk)->src;
@@ -2574,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
 
 	if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
 					cmd->ident == conn->info_ident) {
-		__cancel_delayed_work(&conn->info_timer);
+		cancel_delayed_work(&conn->info_timer);
 
 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
 		conn->info_ident = 0;
@@ -2970,7 +2970,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
 	default:
 		sk->sk_err = ECONNRESET;
-		__set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
+		__set_chan_timer(chan,
+				msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
 		l2cap_send_disconn_req(conn, chan, ECONNRESET);
 		goto done;
 	}
@@ -3120,7 +3121,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
 			conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
 		return 0;
 
-	__cancel_delayed_work(&conn->info_timer);
+	cancel_delayed_work(&conn->info_timer);
 
 	if (result != L2CAP_IR_SUCCESS) {
 		conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4478,7 +4479,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
 	if (encrypt == 0x00) {
 		if (chan->sec_level == BT_SECURITY_MEDIUM) {
 			__clear_chan_timer(chan);
-			__set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
+			__set_chan_timer(chan,
+					msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
 		} else if (chan->sec_level == BT_SECURITY_HIGH)
 			l2cap_chan_close(chan, ECONNREFUSED);
 	} else {
@@ -4499,7 +4501,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
 	if (hcon->type == LE_LINK) {
 		smp_distribute_keys(conn, 0);
-		__cancel_delayed_work(&conn->security_timer);
+		cancel_delayed_work(&conn->security_timer);
 	}
 
 	rcu_read_lock();
@@ -4546,7 +4548,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 					L2CAP_CONN_REQ, sizeof(req), &req);
 			} else {
 				__clear_chan_timer(chan);
-				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+				__set_chan_timer(chan,
+					msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
 			}
 		} else if (chan->state == BT_CONNECT2) {
 			struct l2cap_conn_rsp rsp;
@@ -4566,7 +4569,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 				}
 			} else {
 				l2cap_state_change(chan, BT_DISCONN);
-				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+				__set_chan_timer(chan,
+					msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
 				res = L2CAP_CR_SEC_BLOCK;
 				stat = L2CAP_CS_NO_INFO;
 			}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c61d967..401d942 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -849,6 +849,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
 	if (!sk)
 		return NULL;
 
+	bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
+
 	l2cap_sock_init(sk, parent);
 
 	return l2cap_pi(sk)->chan;
@@ -1002,7 +1004,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
 	INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
 
 	sk->sk_destruct = l2cap_sock_destruct;
-	sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+	sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
 
 	sock_reset_flag(sk, SOCK_ZAPPED);
 
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 501649b..8a60238 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1164,12 +1164,18 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
 			break;
 
 		case BT_DISCONN:
-			/* When socket is closed and we are not RFCOMM
-			 * initiator rfcomm_process_rx already calls
-			 * rfcomm_session_put() */
-			if (s->sock->sk->sk_state != BT_CLOSED)
-				if (list_empty(&s->dlcs))
-					rfcomm_session_put(s);
+			/* rfcomm_session_put is called later so don't do
+			 * anything here otherwise we will mess up the session
+			 * reference counter:
+			 *
+			 * (a) when we are the initiator dlc_unlink will drive
+			 * the reference counter to 0 (there is no initial put
+			 * after session_add)
+			 *
+			 * (b) when we are not the initiator rfcomm_rx_process
+			 * will explicitly call put to balance the initial hold
+			 * done after session add.
+			 */
 			break;
 		}
 	}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index f066678..22169c3 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -956,6 +956,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
 	if (!sk)
 		goto done;
 
+	bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
+
 	rfcomm_sock_init(sk, parent);
 	bacpy(&bt_sk(sk)->src, &src);
 	bacpy(&bt_sk(sk)->dst, &dst);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 71773b0..a157bf8 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -171,6 +171,7 @@ static int br_set_mac_address(struct net_device *dev, void *p)
 
 	spin_lock_bh(&br->lock);
 	if (compare_ether_addr(dev->dev_addr, addr->sa_data)) {
+		dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 		memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
 		br_fdb_change_mac_address(br, addr->sa_data);
 		br_stp_change_bridge_id(br, addr->sa_data);
@@ -334,7 +335,7 @@ void br_dev_setup(struct net_device *dev)
 {
 	struct net_bridge *br = netdev_priv(dev);
 
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 	ether_setup(dev);
 
 	dev->netdev_ops = &br_netdev_ops;
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index 82c5706..aa6f716 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -162,7 +162,6 @@ void caif_flow_cb(struct sk_buff *skb)
 static int transmit(struct cflayer *layer, struct cfpkt *pkt)
 {
 	int err, high = 0, qlen = 0;
-	struct caif_dev_common *caifdev;
 	struct caif_device_entry *caifd =
 	    container_of(layer, struct caif_device_entry, layer);
 	struct sk_buff *skb;
@@ -174,7 +173,6 @@ static int transmit(struct cflayer *layer, struct cfpkt *pkt)
 	skb->dev = caifd->netdev;
 	skb_reset_network_header(skb);
 	skb->protocol = htons(ETH_P_CAIF);
-	caifdev = netdev_priv(caifd->netdev);
 
 	/* Check if we need to handle xoff */
 	if (likely(caifd->netdev->tx_queue_len == 0))
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index a97d97a..5016fa5 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -43,34 +43,9 @@ enum caif_states {
 #define TX_FLOW_ON_BIT	1
 #define RX_FLOW_ON_BIT	2
 
-static struct dentry *debugfsdir;
-
-#ifdef CONFIG_DEBUG_FS
-struct debug_fs_counter {
-	atomic_t caif_nr_socks;
-	atomic_t caif_sock_create;
-	atomic_t num_connect_req;
-	atomic_t num_connect_resp;
-	atomic_t num_connect_fail_resp;
-	atomic_t num_disconnect;
-	atomic_t num_remote_shutdown_ind;
-	atomic_t num_tx_flow_off_ind;
-	atomic_t num_tx_flow_on_ind;
-	atomic_t num_rx_flow_off;
-	atomic_t num_rx_flow_on;
-};
-static struct debug_fs_counter cnt;
-#define	dbfs_atomic_inc(v) atomic_inc_return(v)
-#define	dbfs_atomic_dec(v) atomic_dec_return(v)
-#else
-#define	dbfs_atomic_inc(v) 0
-#define	dbfs_atomic_dec(v) 0
-#endif
-
 struct caifsock {
 	struct sock sk; /* must be first member */
 	struct cflayer layer;
-	char name[CAIF_LAYER_NAME_SZ]; /* Used for debugging */
 	u32 flow_state;
 	struct caif_connect_request conn_req;
 	struct mutex readlock;
@@ -161,7 +136,6 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 					atomic_read(&cf_sk->sk.sk_rmem_alloc),
 					sk_rcvbuf_lowwater(cf_sk));
 		set_rx_flow_off(cf_sk);
-		dbfs_atomic_inc(&cnt.num_rx_flow_off);
 		caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
 	}
 
@@ -172,7 +146,6 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 		set_rx_flow_off(cf_sk);
 		if (net_ratelimit())
 			pr_debug("sending flow OFF due to rmem_schedule\n");
-		dbfs_atomic_inc(&cnt.num_rx_flow_off);
 		caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ);
 	}
 	skb->dev = NULL;
@@ -233,14 +206,12 @@ static void caif_ctrl_cb(struct cflayer *layr,
 	switch (flow) {
 	case CAIF_CTRLCMD_FLOW_ON_IND:
 		/* OK from modem to start sending again */
-		dbfs_atomic_inc(&cnt.num_tx_flow_on_ind);
 		set_tx_flow_on(cf_sk);
 		cf_sk->sk.sk_state_change(&cf_sk->sk);
 		break;
 
 	case CAIF_CTRLCMD_FLOW_OFF_IND:
 		/* Modem asks us to shut up */
-		dbfs_atomic_inc(&cnt.num_tx_flow_off_ind);
 		set_tx_flow_off(cf_sk);
 		cf_sk->sk.sk_state_change(&cf_sk->sk);
 		break;
@@ -249,7 +220,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
 		/* We're now connected */
 		caif_client_register_refcnt(&cf_sk->layer,
 						cfsk_hold, cfsk_put);
-		dbfs_atomic_inc(&cnt.num_connect_resp);
 		cf_sk->sk.sk_state = CAIF_CONNECTED;
 		set_tx_flow_on(cf_sk);
 		cf_sk->sk.sk_state_change(&cf_sk->sk);
@@ -263,7 +233,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
 
 	case CAIF_CTRLCMD_INIT_FAIL_RSP:
 		/* Connect request failed */
-		dbfs_atomic_inc(&cnt.num_connect_fail_resp);
 		cf_sk->sk.sk_err = ECONNREFUSED;
 		cf_sk->sk.sk_state = CAIF_DISCONNECTED;
 		cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
@@ -277,7 +246,6 @@ static void caif_ctrl_cb(struct cflayer *layr,
 
 	case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND:
 		/* Modem has closed this connection, or device is down. */
-		dbfs_atomic_inc(&cnt.num_remote_shutdown_ind);
 		cf_sk->sk.sk_shutdown = SHUTDOWN_MASK;
 		cf_sk->sk.sk_err = ECONNRESET;
 		set_rx_flow_on(cf_sk);
@@ -297,7 +265,6 @@ static void caif_check_flow_release(struct sock *sk)
 		return;
 
 	if (atomic_read(&sk->sk_rmem_alloc) <= sk_rcvbuf_lowwater(cf_sk)) {
-			dbfs_atomic_inc(&cnt.num_rx_flow_on);
 			set_rx_flow_on(cf_sk);
 			caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_ON_REQ);
 	}
@@ -856,7 +823,6 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
 	/*ifindex = id of the interface.*/
 	cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if;
 
-	dbfs_atomic_inc(&cnt.num_connect_req);
 	cf_sk->layer.receive = caif_sktrecv_cb;
 
 	err = caif_connect_client(sock_net(sk), &cf_sk->conn_req,
@@ -945,8 +911,6 @@ static int caif_release(struct socket *sock)
 	spin_unlock_bh(&sk->sk_receive_queue.lock);
 	sock->sk = NULL;
 
-	dbfs_atomic_inc(&cnt.num_disconnect);
-
 	WARN_ON(IS_ERR(cf_sk->debugfs_socket_dir));
 	if (cf_sk->debugfs_socket_dir != NULL)
 		debugfs_remove_recursive(cf_sk->debugfs_socket_dir);
@@ -1054,14 +1018,12 @@ static void caif_sock_destructor(struct sock *sk)
 		return;
 	}
 	sk_stream_kill_queues(&cf_sk->sk);
-	dbfs_atomic_dec(&cnt.caif_nr_socks);
 	caif_free_client(&cf_sk->layer);
 }
 
 static int caif_create(struct net *net, struct socket *sock, int protocol,
 			int kern)
 {
-	int num;
 	struct sock *sk = NULL;
 	struct caifsock *cf_sk = NULL;
 	static struct proto prot = {.name = "PF_CAIF",
@@ -1122,34 +1084,6 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
 	cf_sk->sk.sk_priority = CAIF_PRIO_NORMAL;
 	cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
 	cf_sk->conn_req.protocol = protocol;
-	/* Increase the number of sockets created. */
-	dbfs_atomic_inc(&cnt.caif_nr_socks);
-	num = dbfs_atomic_inc(&cnt.caif_sock_create);
-#ifdef CONFIG_DEBUG_FS
-	if (!IS_ERR(debugfsdir)) {
-
-		/* Fill in some information concerning the misc socket. */
-		snprintf(cf_sk->name, sizeof(cf_sk->name), "cfsk%d", num);
-
-		cf_sk->debugfs_socket_dir =
-			debugfs_create_dir(cf_sk->name, debugfsdir);
-
-		debugfs_create_u32("sk_state", S_IRUSR | S_IWUSR,
-				cf_sk->debugfs_socket_dir,
-				(u32 *) &cf_sk->sk.sk_state);
-		debugfs_create_u32("flow_state", S_IRUSR | S_IWUSR,
-				cf_sk->debugfs_socket_dir, &cf_sk->flow_state);
-		debugfs_create_u32("sk_rmem_alloc", S_IRUSR | S_IWUSR,
-				cf_sk->debugfs_socket_dir,
-				(u32 *) &cf_sk->sk.sk_rmem_alloc);
-		debugfs_create_u32("sk_wmem_alloc", S_IRUSR | S_IWUSR,
-				cf_sk->debugfs_socket_dir,
-				(u32 *) &cf_sk->sk.sk_wmem_alloc);
-		debugfs_create_u32("identity", S_IRUSR | S_IWUSR,
-				cf_sk->debugfs_socket_dir,
-				(u32 *) &cf_sk->layer.id);
-	}
-#endif
 	release_sock(&cf_sk->sk);
 	return 0;
 }
@@ -1161,7 +1095,7 @@ static struct net_proto_family caif_family_ops = {
 	.owner = THIS_MODULE,
 };
 
-static int af_caif_init(void)
+static int __init caif_sktinit_module(void)
 {
 	int err = sock_register(&caif_family_ops);
 	if (!err)
@@ -1169,54 +1103,9 @@ static int af_caif_init(void)
 	return 0;
 }
 
-static int __init caif_sktinit_module(void)
-{
-#ifdef CONFIG_DEBUG_FS
-	debugfsdir = debugfs_create_dir("caif_sk", NULL);
-	if (!IS_ERR(debugfsdir)) {
-		debugfs_create_u32("num_sockets", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.caif_nr_socks);
-		debugfs_create_u32("num_create", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.caif_sock_create);
-		debugfs_create_u32("num_connect_req", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_connect_req);
-		debugfs_create_u32("num_connect_resp", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_connect_resp);
-		debugfs_create_u32("num_connect_fail_resp", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_connect_fail_resp);
-		debugfs_create_u32("num_disconnect", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_disconnect);
-		debugfs_create_u32("num_remote_shutdown_ind",
-				S_IRUSR | S_IWUSR, debugfsdir,
-				(u32 *) &cnt.num_remote_shutdown_ind);
-		debugfs_create_u32("num_tx_flow_off_ind", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_tx_flow_off_ind);
-		debugfs_create_u32("num_tx_flow_on_ind", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_tx_flow_on_ind);
-		debugfs_create_u32("num_rx_flow_off", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_rx_flow_off);
-		debugfs_create_u32("num_rx_flow_on", S_IRUSR | S_IWUSR,
-				debugfsdir,
-				(u32 *) &cnt.num_rx_flow_on);
-	}
-#endif
-	return af_caif_init();
-}
-
 static void __exit caif_sktexit_module(void)
 {
 	sock_unregister(PF_CAIF);
-	if (debugfsdir != NULL)
-		debugfs_remove_recursive(debugfsdir);
 }
 module_init(caif_sktinit_module);
 module_exit(caif_sktexit_module);
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index 8656909..e866234 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -72,14 +72,12 @@ static void robust_list_del(struct list_head *delete_node)
 static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
 {
 	struct sk_buff *skb;
-	struct chnl_net *priv  = container_of(layr, struct chnl_net, chnl);
+	struct chnl_net *priv;
 	int pktlen;
-	int err = 0;
 	const u8 *ip_version;
 	u8 buf;
 
 	priv = container_of(layr, struct chnl_net, chnl);
-
 	if (!priv)
 		return -EINVAL;
 
@@ -95,8 +93,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
 
 	/* check the version of IP */
 	ip_version = skb_header_pointer(skb, 0, 1, &buf);
-	if (!ip_version)
-		return -EINVAL;
+
 	switch (*ip_version >> 4) {
 	case 4:
 		skb->protocol = htons(ETH_P_IP);
@@ -105,6 +102,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
 		skb->protocol = htons(ETH_P_IPV6);
 		break;
 	default:
+		priv->netdev->stats.rx_errors++;
 		return -EINVAL;
 	}
 
@@ -123,7 +121,7 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt)
 	priv->netdev->stats.rx_packets++;
 	priv->netdev->stats.rx_bytes += pktlen;
 
-	return err;
+	return 0;
 }
 
 static int delete_device(struct chnl_net *dev)
@@ -221,11 +219,13 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (skb->len > priv->netdev->mtu) {
 		pr_warn("Size of skb exceeded MTU\n");
+		dev->stats.tx_errors++;
 		return -ENOSPC;
 	}
 
 	if (!priv->flowenabled) {
 		pr_debug("dropping packets flow off\n");
+		dev->stats.tx_dropped++;
 		return NETDEV_TX_BUSY;
 	}
 
@@ -240,8 +240,7 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Send the packet down the stack. */
 	result = priv->chnl.dn->transmit(priv->chnl.dn, pkt);
 	if (result) {
-		if (result == -EAGAIN)
-			result = NETDEV_TX_BUSY;
+		dev->stats.tx_dropped++;
 		return result;
 	}
 
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 68bbf9f..d3cf12f 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -132,6 +132,8 @@ out_noerr:
  *	__skb_recv_datagram - Receive a datagram skbuff
  *	@sk: socket
  *	@flags: MSG_ flags
+ *	@off: an offset in bytes to peek skb from. Returns an offset
+ *	      within an skb where data actually starts
  *	@peeked: returns non-zero if this packet has been seen before
  *	@err: error code returned
  *
@@ -158,7 +160,7 @@ out_noerr:
  *	the standard around please.
  */
 struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
-				    int *peeked, int *err)
+				    int *peeked, int *off, int *err)
 {
 	struct sk_buff *skb;
 	long timeo;
@@ -180,21 +182,25 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
 		 * However, this function was correct in any case. 8)
 		 */
 		unsigned long cpu_flags;
+		struct sk_buff_head *queue = &sk->sk_receive_queue;
 
-		spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
-		skb = skb_peek(&sk->sk_receive_queue);
-		if (skb) {
+		spin_lock_irqsave(&queue->lock, cpu_flags);
+		skb_queue_walk(queue, skb) {
 			*peeked = skb->peeked;
 			if (flags & MSG_PEEK) {
+				if (*off >= skb->len) {
+					*off -= skb->len;
+					continue;
+				}
 				skb->peeked = 1;
 				atomic_inc(&skb->users);
 			} else
-				__skb_unlink(skb, &sk->sk_receive_queue);
-		}
-		spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
+				__skb_unlink(skb, queue);
 
-		if (skb)
+			spin_unlock_irqrestore(&queue->lock, cpu_flags);
 			return skb;
+		}
+		spin_unlock_irqrestore(&queue->lock, cpu_flags);
 
 		/* User doesn't want to wait */
 		error = -EAGAIN;
@@ -214,10 +220,10 @@ EXPORT_SYMBOL(__skb_recv_datagram);
 struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
 				  int noblock, int *err)
 {
-	int peeked;
+	int peeked, off = 0;
 
 	return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
-				   &peeked, err);
+				   &peeked, &off, err);
 }
 EXPORT_SYMBOL(skb_recv_datagram);
 
diff --git a/net/core/dev.c b/net/core/dev.c
index 6ca32f6..763a0ed 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -446,7 +446,7 @@ void __dev_remove_pack(struct packet_type *pt)
 		}
 	}
 
-	printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
+	pr_warn("dev_remove_pack: %p not found\n", pt);
 out:
 	spin_unlock(&ptype_lock);
 }
@@ -1039,8 +1039,7 @@ rollback:
 			memcpy(dev->name, oldname, IFNAMSIZ);
 			goto rollback;
 		} else {
-			printk(KERN_ERR
-			       "%s: name change rollback failed: %d.\n",
+			pr_err("%s: name change rollback failed: %d\n",
 			       dev->name, ret);
 		}
 	}
@@ -1139,9 +1138,8 @@ void dev_load(struct net *net, const char *name)
 		no_module = request_module("netdev-%s", name);
 	if (no_module && capable(CAP_SYS_MODULE)) {
 		if (!request_module("%s", name))
-			pr_err("Loading kernel module for a network device "
-"with CAP_SYS_MODULE (deprecated).  Use CAP_NET_ADMIN and alias netdev-%s "
-"instead\n", name);
+			pr_err("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated).  Use CAP_NET_ADMIN and alias netdev-%s instead.\n",
+			       name);
 	}
 }
 EXPORT_SYMBOL(dev_load);
@@ -1655,10 +1653,9 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 			if (skb_network_header(skb2) < skb2->data ||
 			    skb2->network_header > skb2->tail) {
 				if (net_ratelimit())
-					printk(KERN_CRIT "protocol %04x is "
-					       "buggy, dev %s\n",
-					       ntohs(skb2->protocol),
-					       dev->name);
+					pr_crit("protocol %04x is buggy, dev %s\n",
+						ntohs(skb2->protocol),
+						dev->name);
 				skb_reset_network_header(skb2);
 			}
 
@@ -1691,9 +1688,7 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
 
 	/* If TC0 is invalidated disable TC mapping */
 	if (tc->offset + tc->count > txq) {
-		pr_warning("Number of in use tx queues changed "
-			   "invalidating tc mappings. Priority "
-			   "traffic classification disabled!\n");
+		pr_warn("Number of in use tx queues changed invalidating tc mappings. Priority traffic classification disabled!\n");
 		dev->num_tc = 0;
 		return;
 	}
@@ -1704,11 +1699,8 @@ static void netif_setup_tc(struct net_device *dev, unsigned int txq)
 
 		tc = &dev->tc_to_txq[q];
 		if (tc->offset + tc->count > txq) {
-			pr_warning("Number of in use tx queues "
-				   "changed. Priority %i to tc "
-				   "mapping %i is no longer valid "
-				   "setting map to 0\n",
-				   i, q);
+			pr_warn("Number of in use tx queues changed. Priority %i to tc mapping %i is no longer valid. Setting map to 0\n",
+				i, q);
 			netdev_set_prio_tc_map(dev, i, 0);
 		}
 	}
@@ -2014,8 +2006,7 @@ EXPORT_SYMBOL(skb_gso_segment);
 void netdev_rx_csum_fault(struct net_device *dev)
 {
 	if (net_ratelimit()) {
-		printk(KERN_ERR "%s: hw csum failure.\n",
-			dev ? dev->name : "<unknown>");
+		pr_err("%s: hw csum failure\n", dev ? dev->name : "<unknown>");
 		dump_stack();
 	}
 }
@@ -2332,9 +2323,9 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)
 {
 	if (unlikely(queue_index >= dev->real_num_tx_queues)) {
 		if (net_ratelimit()) {
-			pr_warning("%s selects TX queue %d, but "
-				"real number of TX queues is %d\n",
-				dev->name, queue_index, dev->real_num_tx_queues);
+			pr_warn("%s selects TX queue %d, but real number of TX queues is %d\n",
+				dev->name, queue_index,
+				dev->real_num_tx_queues);
 		}
 		return 0;
 	}
@@ -2578,16 +2569,16 @@ int dev_queue_xmit(struct sk_buff *skb)
 			}
 			HARD_TX_UNLOCK(dev, txq);
 			if (net_ratelimit())
-				printk(KERN_CRIT "Virtual device %s asks to "
-				       "queue packet!\n", dev->name);
+				pr_crit("Virtual device %s asks to queue packet!\n",
+					dev->name);
 		} else {
 			/* Recursion is detected! It is possible,
 			 * unfortunately
 			 */
 recursion_alert:
 			if (net_ratelimit())
-				printk(KERN_CRIT "Dead loop on virtual device "
-				       "%s, fix it urgently!\n", dev->name);
+				pr_crit("Dead loop on virtual device %s, fix it urgently!\n",
+					dev->name);
 		}
 	}
 
@@ -3069,8 +3060,8 @@ static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq)
 
 	if (unlikely(MAX_RED_LOOP < ttl++)) {
 		if (net_ratelimit())
-			pr_warning( "Redir loop detected Dropping packet (%d->%d)\n",
-			       skb->skb_iif, dev->ifindex);
+			pr_warn("Redir loop detected Dropping packet (%d->%d)\n",
+				skb->skb_iif, dev->ifindex);
 		return TC_ACT_SHOT;
 	}
 
@@ -4497,16 +4488,15 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc)
 			dev->flags &= ~IFF_PROMISC;
 		else {
 			dev->promiscuity -= inc;
-			printk(KERN_WARNING "%s: promiscuity touches roof, "
-				"set promiscuity failed, promiscuity feature "
-				"of device might be broken.\n", dev->name);
+			pr_warn("%s: promiscuity touches roof, set promiscuity failed. promiscuity feature of device might be broken.\n",
+				dev->name);
 			return -EOVERFLOW;
 		}
 	}
 	if (dev->flags != old_flags) {
-		printk(KERN_INFO "device %s %s promiscuous mode\n",
-		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
-							       "left");
+		pr_info("device %s %s promiscuous mode\n",
+			dev->name,
+			dev->flags & IFF_PROMISC ? "entered" : "left");
 		if (audit_enabled) {
 			current_uid_gid(&uid, &gid);
 			audit_log(current->audit_context, GFP_ATOMIC,
@@ -4579,9 +4569,8 @@ int dev_set_allmulti(struct net_device *dev, int inc)
 			dev->flags &= ~IFF_ALLMULTI;
 		else {
 			dev->allmulti -= inc;
-			printk(KERN_WARNING "%s: allmulti touches roof, "
-				"set allmulti failed, allmulti feature of "
-				"device might be broken.\n", dev->name);
+			pr_warn("%s: allmulti touches roof, set allmulti failed. allmulti feature of device might be broken.\n",
+				dev->name);
 			return -EOVERFLOW;
 		}
 	}
@@ -5238,8 +5227,8 @@ static void rollback_registered_many(struct list_head *head)
 		 * devices and proceed with the remaining.
 		 */
 		if (dev->reg_state == NETREG_UNINITIALIZED) {
-			pr_debug("unregister_netdevice: device %s/%p never "
-				 "was registered\n", dev->name, dev);
+			pr_debug("unregister_netdevice: device %s/%p never was registered\n",
+				 dev->name, dev);
 
 			WARN_ON(1);
 			list_del(&dev->unreg_list);
@@ -5471,7 +5460,7 @@ static int netif_alloc_rx_queues(struct net_device *dev)
 
 	rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL);
 	if (!rx) {
-		pr_err("netdev: Unable to allocate %u rx queues.\n", count);
+		pr_err("netdev: Unable to allocate %u rx queues\n", count);
 		return -ENOMEM;
 	}
 	dev->_rx = rx;
@@ -5505,8 +5494,7 @@ static int netif_alloc_netdev_queues(struct net_device *dev)
 
 	tx = kcalloc(count, sizeof(struct netdev_queue), GFP_KERNEL);
 	if (!tx) {
-		pr_err("netdev: Unable to allocate %u tx queues.\n",
-		       count);
+		pr_err("netdev: Unable to allocate %u tx queues\n", count);
 		return -ENOMEM;
 	}
 	dev->_tx = tx;
@@ -5765,10 +5753,8 @@ static void netdev_wait_allrefs(struct net_device *dev)
 		refcnt = netdev_refcnt_read(dev);
 
 		if (time_after(jiffies, warning_time + 10 * HZ)) {
-			printk(KERN_EMERG "unregister_netdevice: "
-			       "waiting for %s to become free. Usage "
-			       "count = %d\n",
-			       dev->name, refcnt);
+			pr_emerg("unregister_netdevice: waiting for %s to become free. Usage count = %d\n",
+				 dev->name, refcnt);
 			warning_time = jiffies;
 		}
 	}
@@ -5819,7 +5805,7 @@ void netdev_run_todo(void)
 		list_del(&dev->todo_list);
 
 		if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
-			printk(KERN_ERR "network todo '%s' but state %d\n",
+			pr_err("network todo '%s' but state %d\n",
 			       dev->name, dev->reg_state);
 			dump_stack();
 			continue;
@@ -5935,15 +5921,13 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 	BUG_ON(strlen(name) >= sizeof(dev->name));
 
 	if (txqs < 1) {
-		pr_err("alloc_netdev: Unable to allocate device "
-		       "with zero queues.\n");
+		pr_err("alloc_netdev: Unable to allocate device with zero queues\n");
 		return NULL;
 	}
 
 #ifdef CONFIG_RPS
 	if (rxqs < 1) {
-		pr_err("alloc_netdev: Unable to allocate device "
-		       "with zero RX queues.\n");
+		pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n");
 		return NULL;
 	}
 #endif
@@ -5959,7 +5943,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 
 	p = kzalloc(alloc_size, GFP_KERNEL);
 	if (!p) {
-		printk(KERN_ERR "alloc_netdev: Unable to allocate device.\n");
+		pr_err("alloc_netdev: Unable to allocate device\n");
 		return NULL;
 	}
 
@@ -6492,8 +6476,8 @@ static void __net_exit default_device_exit(struct net *net)
 		snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
 		err = dev_change_net_namespace(dev, &init_net, fb_name);
 		if (err) {
-			printk(KERN_EMERG "%s: failed to move %s to init_net: %d\n",
-				__func__, dev->name, err);
+			pr_emerg("%s: failed to move %s to init_net: %d\n",
+				 __func__, dev->name, err);
 			BUG();
 		}
 	}
diff --git a/net/core/kmap_skb.h b/net/core/kmap_skb.h
index 81e1ed7..52d0a44 100644
--- a/net/core/kmap_skb.h
+++ b/net/core/kmap_skb.h
@@ -7,12 +7,12 @@ static inline void *kmap_skb_frag(const skb_frag_t *frag)
 
 	local_bh_disable();
 #endif
-	return kmap_atomic(skb_frag_page(frag), KM_SKB_DATA_SOFTIRQ);
+	return kmap_atomic(skb_frag_page(frag));
 }
 
 static inline void kunmap_skb_frag(void *vaddr)
 {
-	kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
+	kunmap_atomic(vaddr);
 #ifdef CONFIG_HIGHMEM
 	local_bh_enable();
 #endif
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e287346..0a68045 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -826,6 +826,8 @@ next_elt:
 		write_unlock_bh(&tbl->lock);
 		cond_resched();
 		write_lock_bh(&tbl->lock);
+		nht = rcu_dereference_protected(tbl->nht,
+						lockdep_is_held(&tbl->lock));
 	}
 	/* Cycle through all hash buckets every base_reachable_time/2 ticks.
 	 * ARP entry timeouts range from 1/2 base_reachable_time to 3/2
@@ -2165,6 +2167,35 @@ nla_put_failure:
 	return -EMSGSIZE;
 }
 
+static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
+			    u32 pid, u32 seq, int type, unsigned int flags,
+			    struct neigh_table *tbl)
+{
+	struct nlmsghdr *nlh;
+	struct ndmsg *ndm;
+
+	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), flags);
+	if (nlh == NULL)
+		return -EMSGSIZE;
+
+	ndm = nlmsg_data(nlh);
+	ndm->ndm_family	 = tbl->family;
+	ndm->ndm_pad1    = 0;
+	ndm->ndm_pad2    = 0;
+	ndm->ndm_flags	 = pn->flags | NTF_PROXY;
+	ndm->ndm_type	 = NDA_DST;
+	ndm->ndm_ifindex = pn->dev->ifindex;
+	ndm->ndm_state	 = NUD_NONE;
+
+	NLA_PUT(skb, NDA_DST, tbl->key_len, pn->key);
+
+	return nlmsg_end(skb, nlh);
+
+nla_put_failure:
+	nlmsg_cancel(skb, nlh);
+	return -EMSGSIZE;
+}
+
 static void neigh_update_notify(struct neighbour *neigh)
 {
 	call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
@@ -2214,23 +2245,78 @@ out:
 	return rc;
 }
 
+static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
+			     struct netlink_callback *cb)
+{
+	struct pneigh_entry *n;
+	struct net *net = sock_net(skb->sk);
+	int rc, h, s_h = cb->args[3];
+	int idx, s_idx = idx = cb->args[4];
+
+	read_lock_bh(&tbl->lock);
+
+	for (h = 0; h <= PNEIGH_HASHMASK; h++) {
+		if (h < s_h)
+			continue;
+		if (h > s_h)
+			s_idx = 0;
+		for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) {
+			if (dev_net(n->dev) != net)
+				continue;
+			if (idx < s_idx)
+				goto next;
+			if (pneigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
+					    cb->nlh->nlmsg_seq,
+					    RTM_NEWNEIGH,
+					    NLM_F_MULTI, tbl) <= 0) {
+				read_unlock_bh(&tbl->lock);
+				rc = -1;
+				goto out;
+			}
+		next:
+			idx++;
+		}
+	}
+
+	read_unlock_bh(&tbl->lock);
+	rc = skb->len;
+out:
+	cb->args[3] = h;
+	cb->args[4] = idx;
+	return rc;
+
+}
+
 static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct neigh_table *tbl;
 	int t, family, s_t;
+	int proxy = 0;
+	int err = 0;
 
 	read_lock(&neigh_tbl_lock);
 	family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
+
+	/* check for full ndmsg structure presence, family member is
+	 * the same for both structures
+	 */
+	if (nlmsg_len(cb->nlh) >= sizeof(struct ndmsg) &&
+	    ((struct ndmsg *) nlmsg_data(cb->nlh))->ndm_flags == NTF_PROXY)
+		proxy = 1;
+
 	s_t = cb->args[0];
 
-	for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) {
+	for (tbl = neigh_tables, t = 0; tbl && (err >= 0);
+	     tbl = tbl->next, t++) {
 		if (t < s_t || (family && tbl->family != family))
 			continue;
 		if (t > s_t)
 			memset(&cb->args[1], 0, sizeof(cb->args) -
 						sizeof(cb->args[0]));
-		if (neigh_dump_table(tbl, skb, cb) < 0)
-			break;
+		if (proxy)
+			err = pneigh_dump_table(tbl, skb, cb);
+		else
+			err = neigh_dump_table(tbl, skb, cb);
 	}
 	read_unlock(&neigh_tbl_lock);
 
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index ddefc51..3d84fb9 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -9,6 +9,8 @@
  * Copyright (C) 2002  Red Hat, Inc.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/moduleparam.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -45,9 +47,11 @@ static atomic_t trapped;
 #define NETPOLL_RX_ENABLED  1
 #define NETPOLL_RX_DROP     2
 
-#define MAX_SKB_SIZE \
-		(MAX_UDP_CHUNK + sizeof(struct udphdr) + \
-				sizeof(struct iphdr) + sizeof(struct ethhdr))
+#define MAX_SKB_SIZE							\
+	(sizeof(struct ethhdr) +					\
+	 sizeof(struct iphdr) +						\
+	 sizeof(struct udphdr) +					\
+	 MAX_UDP_CHUNK)
 
 static void zap_completion_queue(void);
 static void arp_reply(struct sk_buff *skb);
@@ -55,6 +59,13 @@ static void arp_reply(struct sk_buff *skb);
 static unsigned int carrier_timeout = 4;
 module_param(carrier_timeout, uint, 0644);
 
+#define np_info(np, fmt, ...)				\
+	pr_info("%s: " fmt, np->name, ##__VA_ARGS__)
+#define np_err(np, fmt, ...)				\
+	pr_err("%s: " fmt, np->name, ##__VA_ARGS__)
+#define np_notice(np, fmt, ...)				\
+	pr_notice("%s: " fmt, np->name, ##__VA_ARGS__)
+
 static void queue_process(struct work_struct *work)
 {
 	struct netpoll_info *npinfo =
@@ -627,18 +638,12 @@ out:
 
 void netpoll_print_options(struct netpoll *np)
 {
-	printk(KERN_INFO "%s: local port %d\n",
-			 np->name, np->local_port);
-	printk(KERN_INFO "%s: local IP %pI4\n",
-			 np->name, &np->local_ip);
-	printk(KERN_INFO "%s: interface '%s'\n",
-			 np->name, np->dev_name);
-	printk(KERN_INFO "%s: remote port %d\n",
-			 np->name, np->remote_port);
-	printk(KERN_INFO "%s: remote IP %pI4\n",
-			 np->name, &np->remote_ip);
-	printk(KERN_INFO "%s: remote ethernet address %pM\n",
-	                 np->name, np->remote_mac);
+	np_info(np, "local port %d\n", np->local_port);
+	np_info(np, "local IP %pI4\n", &np->local_ip);
+	np_info(np, "interface '%s'\n", np->dev_name);
+	np_info(np, "remote port %d\n", np->remote_port);
+	np_info(np, "remote IP %pI4\n", &np->remote_ip);
+	np_info(np, "remote ethernet address %pM\n", np->remote_mac);
 }
 EXPORT_SYMBOL(netpoll_print_options);
 
@@ -680,8 +685,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
 			goto parse_failed;
 		*delim = 0;
 		if (*cur == ' ' || *cur == '\t')
-			printk(KERN_INFO "%s: warning: whitespace"
-					"is not allowed\n", np->name);
+			np_info(np, "warning: whitespace is not allowed\n");
 		np->remote_port = simple_strtol(cur, NULL, 10);
 		cur = delim;
 	}
@@ -705,8 +709,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
 	return 0;
 
  parse_failed:
-	printk(KERN_INFO "%s: couldn't parse config at '%s'!\n",
-	       np->name, cur);
+	np_info(np, "couldn't parse config at '%s'!\n", cur);
 	return -1;
 }
 EXPORT_SYMBOL(netpoll_parse_options);
@@ -721,8 +724,8 @@ int __netpoll_setup(struct netpoll *np)
 
 	if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) ||
 	    !ndev->netdev_ops->ndo_poll_controller) {
-		printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
-		       np->name, np->dev_name);
+		np_err(np, "%s doesn't support polling, aborting\n",
+		       np->dev_name);
 		err = -ENOTSUPP;
 		goto out;
 	}
@@ -785,14 +788,12 @@ int netpoll_setup(struct netpoll *np)
 	if (np->dev_name)
 		ndev = dev_get_by_name(&init_net, np->dev_name);
 	if (!ndev) {
-		printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
-		       np->name, np->dev_name);
+		np_err(np, "%s doesn't exist, aborting\n", np->dev_name);
 		return -ENODEV;
 	}
 
 	if (ndev->master) {
-		printk(KERN_ERR "%s: %s is a slave device, aborting.\n",
-		       np->name, np->dev_name);
+		np_err(np, "%s is a slave device, aborting\n", np->dev_name);
 		err = -EBUSY;
 		goto put;
 	}
@@ -800,16 +801,14 @@ int netpoll_setup(struct netpoll *np)
 	if (!netif_running(ndev)) {
 		unsigned long atmost, atleast;
 
-		printk(KERN_INFO "%s: device %s not up yet, forcing it\n",
-		       np->name, np->dev_name);
+		np_info(np, "device %s not up yet, forcing it\n", np->dev_name);
 
 		rtnl_lock();
 		err = dev_open(ndev);
 		rtnl_unlock();
 
 		if (err) {
-			printk(KERN_ERR "%s: failed to open %s\n",
-			       np->name, ndev->name);
+			np_err(np, "failed to open %s\n", ndev->name);
 			goto put;
 		}
 
@@ -817,9 +816,7 @@ int netpoll_setup(struct netpoll *np)
 		atmost = jiffies + carrier_timeout * HZ;
 		while (!netif_carrier_ok(ndev)) {
 			if (time_after(jiffies, atmost)) {
-				printk(KERN_NOTICE
-				       "%s: timeout waiting for carrier\n",
-				       np->name);
+				np_notice(np, "timeout waiting for carrier\n");
 				break;
 			}
 			msleep(1);
@@ -831,9 +828,7 @@ int netpoll_setup(struct netpoll *np)
 		 */
 
 		if (time_before(jiffies, atleast)) {
-			printk(KERN_NOTICE "%s: carrier detect appears"
-			       " untrustworthy, waiting 4 seconds\n",
-			       np->name);
+			np_notice(np, "carrier detect appears untrustworthy, waiting 4 seconds\n");
 			msleep(4000);
 		}
 	}
@@ -844,15 +839,15 @@ int netpoll_setup(struct netpoll *np)
 
 		if (!in_dev || !in_dev->ifa_list) {
 			rcu_read_unlock();
-			printk(KERN_ERR "%s: no IP address for %s, aborting\n",
-			       np->name, np->dev_name);
+			np_err(np, "no IP address for %s, aborting\n",
+			       np->dev_name);
 			err = -EDESTADDRREQ;
 			goto put;
 		}
 
 		np->local_ip = in_dev->ifa_list->ifa_local;
 		rcu_read_unlock();
-		printk(KERN_INFO "%s: local IP %pI4\n", np->name, &np->local_ip);
+		np_info(np, "local IP %pI4\n", &np->local_ip);
 	}
 
 	np->dev = ndev;
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 4dacc44..ba6900f 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -23,9 +23,8 @@
 #include <net/sock.h>
 #include <net/netprio_cgroup.h>
 
-static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
-					       struct cgroup *cgrp);
-static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp);
+static void cgrp_destroy(struct cgroup *cgrp);
 static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
 
 struct cgroup_subsys net_prio_subsys = {
@@ -121,8 +120,7 @@ static void update_netdev_tables(void)
 	rtnl_unlock();
 }
 
-static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
-						 struct cgroup *cgrp)
+static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
 {
 	struct cgroup_netprio_state *cs;
 	int ret;
@@ -146,7 +144,7 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
 	return &cs->css;
 }
 
-static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
+static void cgrp_destroy(struct cgroup *cgrp)
 {
 	struct cgroup_netprio_state *cs;
 	struct net_device *dev;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index da0c97f..f3a5307 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2906,7 +2906,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 	nskb->prev = p;
 
 	nskb->data_len += p->len;
-	nskb->truesize += p->len;
+	nskb->truesize += p->truesize;
 	nskb->len += p->len;
 
 	*head = nskb;
@@ -2916,6 +2916,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 	p = nskb;
 
 merge:
+	p->truesize += skb->truesize - len;
 	if (offset > headlen) {
 		unsigned int eat = offset - headlen;
 
diff --git a/net/core/sock.c b/net/core/sock.c
index 02f8dfe..1c7ae67 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -160,19 +160,19 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
 out:
 	list_for_each_entry_continue_reverse(proto, &proto_list, node)
 		if (proto->destroy_cgroup)
-			proto->destroy_cgroup(cgrp, ss);
+			proto->destroy_cgroup(cgrp);
 	mutex_unlock(&proto_list_mutex);
 	return ret;
 }
 
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp, struct cgroup_subsys *ss)
+void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
 {
 	struct proto *proto;
 
 	mutex_lock(&proto_list_mutex);
 	list_for_each_entry_reverse(proto, &proto_list, node)
 		if (proto->destroy_cgroup)
-			proto->destroy_cgroup(cgrp, ss);
+			proto->destroy_cgroup(cgrp);
 	mutex_unlock(&proto_list_mutex);
 }
 #endif
@@ -793,6 +793,12 @@ set_rcvbuf:
 		sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
 		break;
 
+	case SO_PEEK_OFF:
+		if (sock->ops->set_peek_off)
+			sock->ops->set_peek_off(sk, val);
+		else
+			ret = -EOPNOTSUPP;
+		break;
 	default:
 		ret = -ENOPROTOOPT;
 		break;
@@ -1018,6 +1024,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 		v.val = !!sock_flag(sk, SOCK_WIFI_STATUS);
 		break;
 
+	case SO_PEEK_OFF:
+		if (!sock->ops->set_peek_off)
+			return -EOPNOTSUPP;
+
+		v.val = sk->sk_peek_off;
+		break;
 	default:
 		return -ENOPROTOOPT;
 	}
@@ -2092,6 +2104,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
 
 	sk->sk_sndmsg_page	=	NULL;
 	sk->sk_sndmsg_off	=	0;
+	sk->sk_peek_off		=	-1;
 
 	sk->sk_peer_pid 	=	NULL;
 	sk->sk_peer_cred	=	NULL;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index befe426..ee7013f 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -205,17 +205,23 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
 	struct neighbour *neigh = dst_get_neighbour_noref(dst);
 	struct net_device *dev = neigh->dev;
 	char mac_addr[ETH_ALEN];
+	unsigned int seq;
+	int err;
 
 	dn_dn2eth(mac_addr, rt->rt_local_src);
-	if (dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha,
-			    mac_addr, skb->len) >= 0)
-		return dev_queue_xmit(skb);
-
-	if (net_ratelimit())
-		printk(KERN_DEBUG "dn_neigh_output_packet: oops, can't send packet\n");
-
-	kfree_skb(skb);
-	return -EINVAL;
+	do {
+		seq = read_seqbegin(&neigh->ha_lock);
+		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+				      neigh->ha, mac_addr, skb->len);
+	} while (read_seqretry(&neigh->ha_lock, seq));
+
+	if (err >= 0)
+		err = dev_queue_xmit(skb);
+	else {
+		kfree_skb(skb);
+		err = -EINVAL;
+	}
+	return err;
 }
 
 static int dn_long_output(struct neighbour *neigh, struct sk_buff *skb)
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index f31ce72..80a3de4 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -724,11 +724,10 @@ static int dn_output(struct sk_buff *skb)
 	struct dn_route *rt = (struct dn_route *)dst;
 	struct net_device *dev = dst->dev;
 	struct dn_skb_cb *cb = DN_SKB_CB(skb);
-	struct neighbour *neigh;
 
 	int err = -EINVAL;
 
-	if ((neigh = dst_get_neighbour_noref(dst)) == NULL)
+	if (dst_get_neighbour_noref(dst) == NULL)
 		goto error;
 
 	skb->dev = dev;
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index fa000d2..c73bba3 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -281,6 +281,7 @@ static int __init init_dns_resolver(void)
 
 	/* instruct request_key() to use this special keyring as a cache for
 	 * the results it looks up */
+	set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
 	cred->thread_keyring = keyring;
 	cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
 	dns_resolver_cache = cred;
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a246836..a93af86 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -288,6 +288,8 @@ int eth_mac_addr(struct net_device *dev, void *p)
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	/* if device marked as NET_ADDR_RANDOM, reset it */
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	return 0;
 }
 EXPORT_SYMBOL(eth_mac_addr);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index f7b5670..e588a34 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -381,6 +381,7 @@ lookup_protocol:
 	inet->mc_all	= 1;
 	inet->mc_index	= 0;
 	inet->mc_list	= NULL;
+	inet->rcv_tos	= 0;
 
 	sk_refcnt_debug_inc(sk);
 
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 86f3b88..c48adc5 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1857,11 +1857,6 @@ static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
 	return CIPSO_V4_HDR_LEN + ret_val;
 }
 
-static void opt_kfree_rcu(struct rcu_head *head)
-{
-	kfree(container_of(head, struct ip_options_rcu, rcu));
-}
-
 /**
  * cipso_v4_sock_setattr - Add a CIPSO option to a socket
  * @sk: the socket
@@ -1938,7 +1933,7 @@ int cipso_v4_sock_setattr(struct sock *sk,
 	}
 	rcu_assign_pointer(sk_inet->inet_opt, opt);
 	if (old)
-		call_rcu(&old->rcu, opt_kfree_rcu);
+		kfree_rcu(old, rcu);
 
 	return 0;
 
@@ -2005,7 +2000,7 @@ int cipso_v4_req_setattr(struct request_sock *req,
 	req_inet = inet_rsk(req);
 	opt = xchg(&req_inet->opt, opt);
 	if (opt)
-		call_rcu(&opt->rcu, opt_kfree_rcu);
+		kfree_rcu(opt, rcu);
 
 	return 0;
 
@@ -2075,7 +2070,7 @@ static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr)
 		 * remove the entire option struct */
 		*opt_ptr = NULL;
 		hdr_delta = opt->opt.optlen;
-		call_rcu(&opt->rcu, opt_kfree_rcu);
+		kfree_rcu(opt, rcu);
 	}
 
 	return hdr_delta;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6b3ca5b..b59414a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -730,15 +730,16 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
 
 		if (skb->protocol == htons(ETH_P_IP)) {
 			rt = skb_rtable(skb);
-			if ((dst = rt->rt_gateway) == 0)
-				goto tx_error_icmp;
+			dst = rt->rt_gateway;
 		}
 #if IS_ENABLED(CONFIG_IPV6)
 		else if (skb->protocol == htons(ETH_P_IPV6)) {
-			struct neighbour *neigh = dst_get_neighbour_noref(skb_dst(skb));
 			const struct in6_addr *addr6;
+			struct neighbour *neigh;
+			bool do_tx_error_icmp;
 			int addr_type;
 
+			neigh = dst_neigh_lookup(skb_dst(skb), &ipv6_hdr(skb)->daddr);
 			if (neigh == NULL)
 				goto tx_error;
 
@@ -751,9 +752,14 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
 			}
 
 			if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
+				do_tx_error_icmp = true;
+			else {
+				do_tx_error_icmp = false;
+				dst = addr6->s6_addr32[3];
+			}
+			neigh_release(neigh);
+			if (do_tx_error_icmp)
 				goto tx_error_icmp;
-
-			dst = addr6->s6_addr32[3];
 		}
 #endif
 		else
@@ -914,9 +920,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
 	__IPTUNNEL_XMIT(tstats, &dev->stats);
 	return NETDEV_TX_OK;
 
+#if IS_ENABLED(CONFIG_IPV6)
 tx_error_icmp:
 	dst_link_failure(skb);
-
+#endif
 tx_error:
 	dev->stats.tx_errors++;
 	dev_kfree_skb(skb);
@@ -1529,7 +1536,7 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nla
 		return -EEXIST;
 
 	if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
-		random_ether_addr(dev->dev_addr);
+		eth_hw_addr_random(dev);
 
 	mtu = ipgre_tunnel_bind_dev(dev);
 	if (!tb[IFLA_MTU])
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 8aa87c1..2fd0fba 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -445,11 +445,6 @@ out:
 }
 
 
-static void opt_kfree_rcu(struct rcu_head *head)
-{
-	kfree(container_of(head, struct ip_options_rcu, rcu));
-}
-
 /*
  *	Socket option code for IP. This is the end of the line after any
  *	TCP,UDP etc options on an IP socket.
@@ -469,6 +464,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 			     (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
 			     (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
 			     (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
+	    optname == IP_UNICAST_IF ||
 	    optname == IP_MULTICAST_TTL ||
 	    optname == IP_MULTICAST_ALL ||
 	    optname == IP_MULTICAST_LOOP ||
@@ -525,7 +521,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 		}
 		rcu_assign_pointer(inet->inet_opt, opt);
 		if (old)
-			call_rcu(&old->rcu, opt_kfree_rcu);
+			kfree_rcu(old, rcu);
 		break;
 	}
 	case IP_PKTINFO:
@@ -628,6 +624,35 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 			goto e_inval;
 		inet->mc_loop = !!val;
 		break;
+	case IP_UNICAST_IF:
+	{
+		struct net_device *dev = NULL;
+		int ifindex;
+
+		if (optlen != sizeof(int))
+			goto e_inval;
+
+		ifindex = (__force int)ntohl((__force __be32)val);
+		if (ifindex == 0) {
+			inet->uc_index = 0;
+			err = 0;
+			break;
+		}
+
+		dev = dev_get_by_index(sock_net(sk), ifindex);
+		err = -EADDRNOTAVAIL;
+		if (!dev)
+			break;
+		dev_put(dev);
+
+		err = -EINVAL;
+		if (sk->sk_bound_dev_if)
+			break;
+
+		inet->uc_index = ifindex;
+		err = 0;
+		break;
+	}
 	case IP_MULTICAST_IF:
 	{
 		struct ip_mreqn mreq;
@@ -1178,6 +1203,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
 	case IP_MULTICAST_LOOP:
 		val = inet->mc_loop;
 		break;
+	case IP_UNICAST_IF:
+		val = (__force int)htonl((__u32) inet->uc_index);
+		break;
 	case IP_MULTICAST_IF:
 	{
 		struct in_addr addr;
@@ -1256,6 +1284,10 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
 			int hlim = inet->mc_ttl;
 			put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim);
 		}
+		if (inet->cmsg_flags & IP_CMSG_TOS) {
+			int tos = inet->rcv_tos;
+			put_cmsg(&msg, SOL_IP, IP_TOS, sizeof(tos), &tos);
+		}
 		len -= msg.msg_controllen;
 		return put_user(len, optlen);
 	}
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 22a1993..f84ebff 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -454,8 +454,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 			dev->stats.tx_fifo_errors++;
 			goto tx_error;
 		}
-		if ((dst = rt->rt_gateway) == 0)
-			goto tx_error_icmp;
+		dst = rt->rt_gateway;
 	}
 
 	rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index aea5a19..cfc82cf 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -556,7 +556,8 @@ static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 			ipc.oif = inet->mc_index;
 		if (!saddr)
 			saddr = inet->mc_addr;
-	}
+	} else if (!ipc.oif)
+		ipc.oif = inet->uc_index;
 
 	flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
 			   RT_SCOPE_UNIVERSE, sk->sk_protocol,
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 6afc807..02d6107 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -256,6 +256,7 @@ static const struct snmp_mib snmp4_net_list[] = {
 	SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
 	SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES),
 	SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP),
+	SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL),
 	SNMP_MIB_SENTINEL
 };
 
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 3ccda5a..ab46630 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 			ipc.oif = inet->mc_index;
 		if (!saddr)
 			saddr = inet->mc_addr;
-	}
+	} else if (!ipc.oif)
+		ipc.oif = inet->uc_index;
 
 	flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
 			   RT_SCOPE_UNIVERSE,
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bcacf54..0489ced 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1117,12 +1117,17 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const vo
 	static const __be32 inaddr_any = 0;
 	struct net_device *dev = dst->dev;
 	const __be32 *pkey = daddr;
+	const struct rtable *rt;
 	struct neighbour *n;
 
+	rt = (const struct rtable *) dst;
+
 	if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
 		pkey = &inaddr_any;
+	else if (rt->rt_gateway)
+		pkey = (const __be32 *) &rt->rt_gateway;
 
-	n = __ipv4_neigh_lookup(&arp_tbl, dev, *(__force u32 *)pkey);
+	n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey);
 	if (n)
 		return n;
 	return neigh_create(&arp_tbl, pkey, dev);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 37755cc..22ef5f9 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3240,7 +3240,8 @@ void __init tcp_init(void)
 {
 	struct sk_buff *skb = NULL;
 	unsigned long limit;
-	int i, max_share, cnt;
+	int max_share, cnt;
+	unsigned int i;
 	unsigned long jiffy = jiffies;
 
 	BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
@@ -3283,7 +3284,7 @@ void __init tcp_init(void)
 					&tcp_hashinfo.bhash_size,
 					NULL,
 					64 * 1024);
-	tcp_hashinfo.bhash_size = 1 << tcp_hashinfo.bhash_size;
+	tcp_hashinfo.bhash_size = 1U << tcp_hashinfo.bhash_size;
 	for (i = 0; i < tcp_hashinfo.bhash_size; i++) {
 		spin_lock_init(&tcp_hashinfo.bhash[i].lock);
 		INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 94d683a..94abee8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -90,16 +90,8 @@ EXPORT_SYMBOL(sysctl_tcp_low_latency);
 
 
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
-						   __be32 addr);
-static int tcp_v4_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
+static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
 			       __be32 daddr, __be32 saddr, const struct tcphdr *th);
-#else
-static inline
-struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
-{
-	return NULL;
-}
 #endif
 
 struct inet_hashinfo tcp_hashinfo;
@@ -601,6 +593,10 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 	struct ip_reply_arg arg;
 #ifdef CONFIG_TCP_MD5SIG
 	struct tcp_md5sig_key *key;
+	const __u8 *hash_location = NULL;
+	unsigned char newhash[16];
+	int genhash;
+	struct sock *sk1 = NULL;
 #endif
 	struct net *net;
 
@@ -631,7 +627,36 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 	arg.iov[0].iov_len  = sizeof(rep.th);
 
 #ifdef CONFIG_TCP_MD5SIG
-	key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->saddr) : NULL;
+	hash_location = tcp_parse_md5sig_option(th);
+	if (!sk && hash_location) {
+		/*
+		 * active side is lost. Try to find listening socket through
+		 * source port, and then find md5 key through listening socket.
+		 * we are not loose security here:
+		 * Incoming packet is checked with md5 hash with finding key,
+		 * no RST generated if md5 hash doesn't match.
+		 */
+		sk1 = __inet_lookup_listener(dev_net(skb_dst(skb)->dev),
+					     &tcp_hashinfo, ip_hdr(skb)->daddr,
+					     ntohs(th->source), inet_iif(skb));
+		/* don't send rst if it can't find key */
+		if (!sk1)
+			return;
+		rcu_read_lock();
+		key = tcp_md5_do_lookup(sk1, (union tcp_md5_addr *)
+					&ip_hdr(skb)->saddr, AF_INET);
+		if (!key)
+			goto release_sk1;
+
+		genhash = tcp_v4_md5_hash_skb(newhash, key, NULL, NULL, skb);
+		if (genhash || memcmp(hash_location, newhash, 16) != 0)
+			goto release_sk1;
+	} else {
+		key = sk ? tcp_md5_do_lookup(sk, (union tcp_md5_addr *)
+					     &ip_hdr(skb)->saddr,
+					     AF_INET) : NULL;
+	}
+
 	if (key) {
 		rep.opt[0] = htonl((TCPOPT_NOP << 24) |
 				   (TCPOPT_NOP << 16) |
@@ -664,6 +689,14 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 
 	TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
 	TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
+
+#ifdef CONFIG_TCP_MD5SIG
+release_sk1:
+	if (sk1) {
+		rcu_read_unlock();
+		sock_put(sk1);
+	}
+#endif
 }
 
 /* The code following below sending ACKs in SYN-RECV and TIME-WAIT states
@@ -764,7 +797,8 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 			tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
 			req->ts_recent,
 			0,
-			tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr),
+			tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr,
+					  AF_INET),
 			inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
 			ip_hdr(skb)->tos);
 }
@@ -881,153 +915,137 @@ static struct ip_options_rcu *tcp_v4_save_options(struct sock *sk,
  */
 
 /* Find the Key structure for an address.  */
-static struct tcp_md5sig_key *
-			tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
+struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk,
+					 const union tcp_md5_addr *addr,
+					 int family)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	int i;
-
-	if (!tp->md5sig_info || !tp->md5sig_info->entries4)
+	struct tcp_md5sig_key *key;
+	struct hlist_node *pos;
+	unsigned int size = sizeof(struct in_addr);
+	struct tcp_md5sig_info *md5sig;
+
+	/* caller either holds rcu_read_lock() or socket lock */
+	md5sig = rcu_dereference_check(tp->md5sig_info,
+				       sock_owned_by_user(sk));
+	if (!md5sig)
 		return NULL;
-	for (i = 0; i < tp->md5sig_info->entries4; i++) {
-		if (tp->md5sig_info->keys4[i].addr == addr)
-			return &tp->md5sig_info->keys4[i].base;
+#if IS_ENABLED(CONFIG_IPV6)
+	if (family == AF_INET6)
+		size = sizeof(struct in6_addr);
+#endif
+	hlist_for_each_entry_rcu(key, pos, &md5sig->head, node) {
+		if (key->family != family)
+			continue;
+		if (!memcmp(&key->addr, addr, size))
+			return key;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(tcp_md5_do_lookup);
 
 struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk,
 					 struct sock *addr_sk)
 {
-	return tcp_v4_md5_do_lookup(sk, inet_sk(addr_sk)->inet_daddr);
+	union tcp_md5_addr *addr;
+
+	addr = (union tcp_md5_addr *)&inet_sk(addr_sk)->inet_daddr;
+	return tcp_md5_do_lookup(sk, addr, AF_INET);
 }
 EXPORT_SYMBOL(tcp_v4_md5_lookup);
 
 static struct tcp_md5sig_key *tcp_v4_reqsk_md5_lookup(struct sock *sk,
 						      struct request_sock *req)
 {
-	return tcp_v4_md5_do_lookup(sk, inet_rsk(req)->rmt_addr);
+	union tcp_md5_addr *addr;
+
+	addr = (union tcp_md5_addr *)&inet_rsk(req)->rmt_addr;
+	return tcp_md5_do_lookup(sk, addr, AF_INET);
 }
 
 /* This can be called on a newly created socket, from other files */
-int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
-		      u8 *newkey, u8 newkeylen)
+int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
+		   int family, const u8 *newkey, u8 newkeylen, gfp_t gfp)
 {
 	/* Add Key to the list */
 	struct tcp_md5sig_key *key;
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp4_md5sig_key *keys;
+	struct tcp_md5sig_info *md5sig;
 
-	key = tcp_v4_md5_do_lookup(sk, addr);
+	key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET);
 	if (key) {
 		/* Pre-existing entry - just update that one. */
-		kfree(key->key);
-		key->key = newkey;
+		memcpy(key->key, newkey, newkeylen);
 		key->keylen = newkeylen;
-	} else {
-		struct tcp_md5sig_info *md5sig;
-
-		if (!tp->md5sig_info) {
-			tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info),
-						  GFP_ATOMIC);
-			if (!tp->md5sig_info) {
-				kfree(newkey);
-				return -ENOMEM;
-			}
-			sk_nocaps_add(sk, NETIF_F_GSO_MASK);
-		}
+		return 0;
+	}
 
-		md5sig = tp->md5sig_info;
-		if (md5sig->entries4 == 0 &&
-		    tcp_alloc_md5sig_pool(sk) == NULL) {
-			kfree(newkey);
+	md5sig = rcu_dereference_protected(tp->md5sig_info,
+					   sock_owned_by_user(sk));
+	if (!md5sig) {
+		md5sig = kmalloc(sizeof(*md5sig), gfp);
+		if (!md5sig)
 			return -ENOMEM;
-		}
-
-		if (md5sig->alloced4 == md5sig->entries4) {
-			keys = kmalloc((sizeof(*keys) *
-					(md5sig->entries4 + 1)), GFP_ATOMIC);
-			if (!keys) {
-				kfree(newkey);
-				if (md5sig->entries4 == 0)
-					tcp_free_md5sig_pool();
-				return -ENOMEM;
-			}
 
-			if (md5sig->entries4)
-				memcpy(keys, md5sig->keys4,
-				       sizeof(*keys) * md5sig->entries4);
+		sk_nocaps_add(sk, NETIF_F_GSO_MASK);
+		INIT_HLIST_HEAD(&md5sig->head);
+		rcu_assign_pointer(tp->md5sig_info, md5sig);
+	}
 
-			/* Free old key list, and reference new one */
-			kfree(md5sig->keys4);
-			md5sig->keys4 = keys;
-			md5sig->alloced4++;
-		}
-		md5sig->entries4++;
-		md5sig->keys4[md5sig->entries4 - 1].addr        = addr;
-		md5sig->keys4[md5sig->entries4 - 1].base.key    = newkey;
-		md5sig->keys4[md5sig->entries4 - 1].base.keylen = newkeylen;
+	key = sock_kmalloc(sk, sizeof(*key), gfp);
+	if (!key)
+		return -ENOMEM;
+	if (hlist_empty(&md5sig->head) && !tcp_alloc_md5sig_pool(sk)) {
+		sock_kfree_s(sk, key, sizeof(*key));
+		return -ENOMEM;
 	}
-	return 0;
-}
-EXPORT_SYMBOL(tcp_v4_md5_do_add);
 
-static int tcp_v4_md5_add_func(struct sock *sk, struct sock *addr_sk,
-			       u8 *newkey, u8 newkeylen)
-{
-	return tcp_v4_md5_do_add(sk, inet_sk(addr_sk)->inet_daddr,
-				 newkey, newkeylen);
+	memcpy(key->key, newkey, newkeylen);
+	key->keylen = newkeylen;
+	key->family = family;
+	memcpy(&key->addr, addr,
+	       (family == AF_INET6) ? sizeof(struct in6_addr) :
+				      sizeof(struct in_addr));
+	hlist_add_head_rcu(&key->node, &md5sig->head);
+	return 0;
 }
+EXPORT_SYMBOL(tcp_md5_do_add);
 
-int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
+int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	int i;
-
-	for (i = 0; i < tp->md5sig_info->entries4; i++) {
-		if (tp->md5sig_info->keys4[i].addr == addr) {
-			/* Free the key */
-			kfree(tp->md5sig_info->keys4[i].base.key);
-			tp->md5sig_info->entries4--;
-
-			if (tp->md5sig_info->entries4 == 0) {
-				kfree(tp->md5sig_info->keys4);
-				tp->md5sig_info->keys4 = NULL;
-				tp->md5sig_info->alloced4 = 0;
-				tcp_free_md5sig_pool();
-			} else if (tp->md5sig_info->entries4 != i) {
-				/* Need to do some manipulation */
-				memmove(&tp->md5sig_info->keys4[i],
-					&tp->md5sig_info->keys4[i+1],
-					(tp->md5sig_info->entries4 - i) *
-					 sizeof(struct tcp4_md5sig_key));
-			}
-			return 0;
-		}
-	}
-	return -ENOENT;
+	struct tcp_md5sig_key *key;
+	struct tcp_md5sig_info *md5sig;
+
+	key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&addr, AF_INET);
+	if (!key)
+		return -ENOENT;
+	hlist_del_rcu(&key->node);
+	atomic_sub(sizeof(*key), &sk->sk_omem_alloc);
+	kfree_rcu(key, rcu);
+	md5sig = rcu_dereference_protected(tp->md5sig_info,
+					   sock_owned_by_user(sk));
+	if (hlist_empty(&md5sig->head))
+		tcp_free_md5sig_pool();
+	return 0;
 }
-EXPORT_SYMBOL(tcp_v4_md5_do_del);
+EXPORT_SYMBOL(tcp_md5_do_del);
 
-static void tcp_v4_clear_md5_list(struct sock *sk)
+void tcp_clear_md5_list(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	struct tcp_md5sig_key *key;
+	struct hlist_node *pos, *n;
+	struct tcp_md5sig_info *md5sig;
 
-	/* Free each key, then the set of key keys,
-	 * the crypto element, and then decrement our
-	 * hold on the last resort crypto.
-	 */
-	if (tp->md5sig_info->entries4) {
-		int i;
-		for (i = 0; i < tp->md5sig_info->entries4; i++)
-			kfree(tp->md5sig_info->keys4[i].base.key);
-		tp->md5sig_info->entries4 = 0;
+	md5sig = rcu_dereference_protected(tp->md5sig_info, 1);
+
+	if (!hlist_empty(&md5sig->head))
 		tcp_free_md5sig_pool();
-	}
-	if (tp->md5sig_info->keys4) {
-		kfree(tp->md5sig_info->keys4);
-		tp->md5sig_info->keys4 = NULL;
-		tp->md5sig_info->alloced4  = 0;
+	hlist_for_each_entry_safe(key, pos, n, &md5sig->head, node) {
+		hlist_del_rcu(&key->node);
+		atomic_sub(sizeof(*key), &sk->sk_omem_alloc);
+		kfree_rcu(key, rcu);
 	}
 }
 
@@ -1036,7 +1054,6 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
 {
 	struct tcp_md5sig cmd;
 	struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr;
-	u8 *newkey;
 
 	if (optlen < sizeof(cmd))
 		return -EINVAL;
@@ -1047,32 +1064,16 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
 	if (sin->sin_family != AF_INET)
 		return -EINVAL;
 
-	if (!cmd.tcpm_key || !cmd.tcpm_keylen) {
-		if (!tcp_sk(sk)->md5sig_info)
-			return -ENOENT;
-		return tcp_v4_md5_do_del(sk, sin->sin_addr.s_addr);
-	}
+	if (!cmd.tcpm_key || !cmd.tcpm_keylen)
+		return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin->sin_addr.s_addr,
+				      AF_INET);
 
 	if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
 		return -EINVAL;
 
-	if (!tcp_sk(sk)->md5sig_info) {
-		struct tcp_sock *tp = tcp_sk(sk);
-		struct tcp_md5sig_info *p;
-
-		p = kzalloc(sizeof(*p), sk->sk_allocation);
-		if (!p)
-			return -EINVAL;
-
-		tp->md5sig_info = p;
-		sk_nocaps_add(sk, NETIF_F_GSO_MASK);
-	}
-
-	newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, sk->sk_allocation);
-	if (!newkey)
-		return -ENOMEM;
-	return tcp_v4_md5_do_add(sk, sin->sin_addr.s_addr,
-				 newkey, cmd.tcpm_keylen);
+	return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin->sin_addr.s_addr,
+			      AF_INET, cmd.tcpm_key, cmd.tcpm_keylen,
+			      GFP_KERNEL);
 }
 
 static int tcp_v4_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
@@ -1098,7 +1099,7 @@ static int tcp_v4_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
 	return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp));
 }
 
-static int tcp_v4_md5_hash_hdr(char *md5_hash, struct tcp_md5sig_key *key,
+static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
 			       __be32 daddr, __be32 saddr, const struct tcphdr *th)
 {
 	struct tcp_md5sig_pool *hp;
@@ -1198,7 +1199,8 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, const struct sk_buff *skb)
 	int genhash;
 	unsigned char newhash[16];
 
-	hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr);
+	hash_expected = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&iph->saddr,
+					  AF_INET);
 	hash_location = tcp_parse_md5sig_option(th);
 
 	/* We've parsed the options - do we have a hash? */
@@ -1461,6 +1463,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 	ireq->opt	      = NULL;
 	newinet->mc_index     = inet_iif(skb);
 	newinet->mc_ttl	      = ip_hdr(skb)->ttl;
+	newinet->rcv_tos      = ip_hdr(skb)->tos;
 	inet_csk(newsk)->icsk_ext_hdr_len = 0;
 	if (inet_opt)
 		inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
@@ -1486,7 +1489,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 
 #ifdef CONFIG_TCP_MD5SIG
 	/* Copy over the MD5 key from the original socket */
-	key = tcp_v4_md5_do_lookup(sk, newinet->inet_daddr);
+	key = tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&newinet->inet_daddr,
+				AF_INET);
 	if (key != NULL) {
 		/*
 		 * We're using one, so create a matching key
@@ -1494,10 +1498,8 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 		 * memory, then we end up not copying the key
 		 * across. Shucks.
 		 */
-		char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
-		if (newkey != NULL)
-			tcp_v4_md5_do_add(newsk, newinet->inet_daddr,
-					  newkey, key->keylen);
+		tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newinet->inet_daddr,
+			       AF_INET, key->key, key->keylen, GFP_ATOMIC);
 		sk_nocaps_add(newsk, NETIF_F_GSO_MASK);
 	}
 #endif
@@ -1858,7 +1860,6 @@ EXPORT_SYMBOL(ipv4_specific);
 static const struct tcp_sock_af_ops tcp_sock_ipv4_specific = {
 	.md5_lookup		= tcp_v4_md5_lookup,
 	.calc_md5_hash		= tcp_v4_md5_hash_skb,
-	.md5_add		= tcp_v4_md5_add_func,
 	.md5_parse		= tcp_v4_parse_md5_keys,
 };
 #endif
@@ -1947,8 +1948,8 @@ void tcp_v4_destroy_sock(struct sock *sk)
 #ifdef CONFIG_TCP_MD5SIG
 	/* Clean up the MD5 key list, if any */
 	if (tp->md5sig_info) {
-		tcp_v4_clear_md5_list(sk);
-		kfree(tp->md5sig_info);
+		tcp_clear_md5_list(sk);
+		kfree_rcu(tp->md5sig_info, rcu);
 		tp->md5sig_info = NULL;
 	}
 #endif
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 4997878..e714c68 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -94,7 +94,7 @@ create_files:
 }
 EXPORT_SYMBOL(tcp_init_cgroup);
 
-void tcp_destroy_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
+void tcp_destroy_cgroup(struct cgroup *cgrp)
 {
 	struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
 	struct cg_proto *cg_proto;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 550e755..3cabafb 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -359,13 +359,11 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
 		 */
 		do {
 			struct tcp_md5sig_key *key;
-			memset(tcptw->tw_md5_key, 0, sizeof(tcptw->tw_md5_key));
-			tcptw->tw_md5_keylen = 0;
+			tcptw->tw_md5_key = NULL;
 			key = tp->af_specific->md5_lookup(sk, sk);
 			if (key != NULL) {
-				memcpy(&tcptw->tw_md5_key, key->key, key->keylen);
-				tcptw->tw_md5_keylen = key->keylen;
-				if (tcp_alloc_md5sig_pool(sk) == NULL)
+				tcptw->tw_md5_key = kmemdup(key, sizeof(*key), GFP_ATOMIC);
+				if (tcptw->tw_md5_key && tcp_alloc_md5sig_pool(sk) == NULL)
 					BUG();
 			}
 		} while (0);
@@ -405,8 +403,10 @@ void tcp_twsk_destructor(struct sock *sk)
 {
 #ifdef CONFIG_TCP_MD5SIG
 	struct tcp_timewait_sock *twsk = tcp_twsk(sk);
-	if (twsk->tw_md5_keylen)
+	if (twsk->tw_md5_key) {
 		tcp_free_md5sig_pool();
+		kfree_rcu(twsk->tw_md5_key, rcu);
+	}
 #endif
 }
 EXPORT_SYMBOL_GPL(tcp_twsk_destructor);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 4ff3b6d..364784a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2306,8 +2306,10 @@ begin_fwd:
 		if (sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))
 			continue;
 
-		if (tcp_retransmit_skb(sk, skb))
+		if (tcp_retransmit_skb(sk, skb)) {
+			NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL);
 			return;
+		}
 		NET_INC_STATS_BH(sock_net(sk), mib_idx);
 
 		if (inet_csk(sk)->icsk_ca_state == TCP_CA_Recovery)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 5d075b5..7c41ab8 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -917,7 +917,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		if (!saddr)
 			saddr = inet->mc_addr;
 		connected = 0;
-	}
+	} else if (!ipc.oif)
+		ipc.oif = inet->uc_index;
 
 	if (connected)
 		rt = (struct rtable *)sk_dst_check(sk, 0);
@@ -1166,7 +1167,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
 	struct sk_buff *skb;
 	unsigned int ulen, copied;
-	int peeked;
+	int peeked, off = 0;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
 	bool slow;
@@ -1182,7 +1183,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
 try_again:
 	skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
-				  &peeked, &err);
+				  &peeked, &off, &err);
 	if (!skb)
 		goto out;
 
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 273f48d..5605f9d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -214,6 +214,7 @@ lookup_protocol:
 	inet->mc_ttl	= 1;
 	inet->mc_index	= 0;
 	inet->mc_list	= NULL;
+	inet->rcv_tos	= 0;
 
 	if (ipv4_config.no_pmtu_disc)
 		inet->pmtudisc = IP_PMTUDISC_DONT;
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 59402b4..db00d27 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -211,35 +211,6 @@ void ipv6_sock_ac_close(struct sock *sk)
 	rcu_read_unlock();
 }
 
-#if 0
-/* The function is not used, which is funny. Apparently, author
- * supposed to use it to filter out datagrams inside udp/raw but forgot.
- *
- * It is OK, anycasts are not special comparing to delivery to unicasts.
- */
-
-int inet6_ac_check(struct sock *sk, struct in6_addr *addr, int ifindex)
-{
-	struct ipv6_ac_socklist *pac;
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	int	found;
-
-	found = 0;
-	read_lock(&ipv6_sk_ac_lock);
-	for (pac=np->ipv6_ac_list; pac; pac=pac->acl_next) {
-		if (ifindex && pac->acl_ifindex != ifindex)
-			continue;
-		found = ipv6_addr_equal(&pac->acl_addr, addr);
-		if (found)
-			break;
-	}
-	read_unlock(&ipv6_sk_ac_lock);
-
-	return found;
-}
-
-#endif
-
 static void aca_put(struct ifacaddr6 *ac)
 {
 	if (atomic_dec_and_test(&ac->aca_refcnt)) {
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 251e7cd..76832c8 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -485,7 +485,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
 	}
 
 	if (np->rxopt.bits.rxtclass) {
-		int tclass = (ntohl(*(__be32 *)ipv6_hdr(skb)) >> 20) & 0xff;
+		int tclass = ipv6_tclass(ipv6_hdr(skb));
 		put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
 	}
 
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 01d46bf..af88934 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -468,6 +468,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 
 	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
 		fl6.flowi6_oif = np->mcast_oif;
+	else if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->ucast_oif;
 
 	dst = icmpv6_route_lookup(net, skb, sk, &fl6);
 	if (IS_ERR(dst))
@@ -553,6 +555,8 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 
 	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
 		fl6.flowi6_oif = np->mcast_oif;
+	else if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->ucast_oif;
 
 	err = ip6_dst_lookup(sk, &dst, &fl6);
 	if (err)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index b82bcde..5b27fbc 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1552,11 +1552,20 @@ static int fib6_age(struct rt6_info *rt, void *arg)
 		    time_after_eq(now, rt->dst.lastuse + gc_args.timeout)) {
 			RT6_TRACE("aging clone %p\n", rt);
 			return -1;
-		} else if ((rt->rt6i_flags & RTF_GATEWAY) &&
-			   (!(dst_get_neighbour_noref_raw(&rt->dst)->flags & NTF_ROUTER))) {
-			RT6_TRACE("purging route %p via non-router but gateway\n",
-				  rt);
-			return -1;
+		} else if (rt->rt6i_flags & RTF_GATEWAY) {
+			struct neighbour *neigh;
+			__u8 neigh_flags = 0;
+
+			neigh = dst_neigh_lookup(&rt->dst, &rt->rt6i_gateway);
+			if (neigh) {
+				neigh_flags = neigh->flags;
+				neigh_release(neigh);
+			}
+			if (neigh_flags & NTF_ROUTER) {
+				RT6_TRACE("purging route %p via non-router but gateway\n",
+					  rt);
+				return -1;
+			}
 		}
 		gc_args.more++;
 	}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d97e071..7a98fc2 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -388,7 +388,6 @@ int ip6_forward(struct sk_buff *skb)
 	struct ipv6hdr *hdr = ipv6_hdr(skb);
 	struct inet6_skb_parm *opt = IP6CB(skb);
 	struct net *net = dev_net(dst->dev);
-	struct neighbour *n;
 	u32 mtu;
 
 	if (net->ipv6.devconf_all->forwarding == 0)
@@ -463,8 +462,7 @@ int ip6_forward(struct sk_buff *skb)
 	   send redirects to source routed frames.
 	   We don't send redirects to frames decapsulated from IPsec.
 	 */
-	n = dst_get_neighbour_noref(dst);
-	if (skb->dev == dst->dev && n && opt->srcrt == 0 && !skb_sec_path(skb)) {
+	if (skb->dev == dst->dev && opt->srcrt == 0 && !skb_sec_path(skb)) {
 		struct in6_addr *target = NULL;
 		struct rt6_info *rt;
 
@@ -474,8 +472,8 @@ int ip6_forward(struct sk_buff *skb)
 		 */
 
 		rt = (struct rt6_info *) dst;
-		if ((rt->rt6i_flags & RTF_GATEWAY))
-			target = (struct in6_addr*)&n->primary_key;
+		if (rt->rt6i_flags & RTF_GATEWAY)
+			target = &rt->rt6i_gateway;
 		else
 			target = &hdr->daddr;
 
@@ -486,7 +484,7 @@ int ip6_forward(struct sk_buff *skb)
 		   and by source (inside ndisc_send_redirect)
 		 */
 		if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
-			ndisc_send_redirect(skb, n, target);
+			ndisc_send_redirect(skb, target);
 	} else {
 		int addrtype = ipv6_addr_type(&hdr->saddr);
 
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 18a2719..63dd1f8 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -516,6 +516,36 @@ done:
 		retv = 0;
 		break;
 
+	case IPV6_UNICAST_IF:
+	{
+		struct net_device *dev = NULL;
+		int ifindex;
+
+		if (optlen != sizeof(int))
+			goto e_inval;
+
+		ifindex = (__force int)ntohl((__force __be32)val);
+		if (ifindex == 0) {
+			np->ucast_oif = 0;
+			retv = 0;
+			break;
+		}
+
+		dev = dev_get_by_index(net, ifindex);
+		retv = -EADDRNOTAVAIL;
+		if (!dev)
+			break;
+		dev_put(dev);
+
+		retv = -EINVAL;
+		if (sk->sk_bound_dev_if)
+			break;
+
+		np->ucast_oif = ifindex;
+		retv = 0;
+		break;
+	}
+
 	case IPV6_MULTICAST_IF:
 		if (sk->sk_type == SOCK_STREAM)
 			break;
@@ -987,6 +1017,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 				int hlim = np->mcast_hops;
 				put_cmsg(&msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
 			}
+			if (np->rxopt.bits.rxtclass) {
+				int tclass = np->rcv_tclass;
+				put_cmsg(&msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
+			}
 			if (np->rxopt.bits.rxoinfo) {
 				struct in6_pktinfo src_info;
 				src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif :
@@ -1160,6 +1194,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 		val = np->mcast_oif;
 		break;
 
+	case IPV6_UNICAST_IF:
+		val = (__force int)htonl((__u32) np->ucast_oif);
+		break;
+
 	case IPV6_MTU_DISCOVER:
 		val = np->pmtudisc;
 		break;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d8f02ef..8d81701 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1223,11 +1223,17 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 
 	rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
 
-	if (rt)
-		neigh = dst_get_neighbour_noref(&rt->dst);
-
+	if (rt) {
+		neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
+		if (!neigh) {
+			ND_PRINTK0(KERN_ERR
+				   "ICMPv6 RA: %s() got default router without neighbour.\n",
+				   __func__);
+			dst_release(&rt->dst);
+			return;
+		}
+	}
 	if (rt && lifetime == 0) {
-		neigh_clone(neigh);
 		ip6_del_rt(rt);
 		rt = NULL;
 	}
@@ -1244,7 +1250,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 			return;
 		}
 
-		neigh = dst_get_neighbour_noref(&rt->dst);
+		neigh = dst_neigh_lookup(&rt->dst, &ipv6_hdr(skb)->saddr);
 		if (neigh == NULL) {
 			ND_PRINTK0(KERN_ERR
 				   "ICMPv6 RA: %s() got default router without neighbour.\n",
@@ -1411,7 +1417,7 @@ skip_routeinfo:
 out:
 	if (rt)
 		dst_release(&rt->dst);
-	else if (neigh)
+	if (neigh)
 		neigh_release(neigh);
 }
 
@@ -1506,8 +1512,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
 	}
 }
 
-void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
-			 const struct in6_addr *target)
+void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
 {
 	struct net_device *dev = skb->dev;
 	struct net *net = dev_net(dev);
@@ -1565,6 +1570,13 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
 		goto release;
 
 	if (dev->addr_len) {
+		struct neighbour *neigh = dst_neigh_lookup(skb_dst(skb), target);
+		if (!neigh) {
+			ND_PRINTK2(KERN_WARNING
+				   "ICMPv6 Redirect: no neigh for target address\n");
+			goto release;
+		}
+
 		read_lock_bh(&neigh->lock);
 		if (neigh->nud_state & NUD_VALID) {
 			memcpy(ha_buf, neigh->ha, dev->addr_len);
@@ -1573,6 +1585,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
 			len += ndisc_opt_addr_space(dev);
 		} else
 			read_unlock_bh(&neigh->lock);
+
+		neigh_release(neigh);
 	}
 
 	rd_len = min_t(unsigned int,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d02f7e4..5bddea7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -856,6 +856,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 
 	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
 		fl6.flowi6_oif = np->mcast_oif;
+	else if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->ucast_oif;
 	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
 	dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index b69fae7..9447bd6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -336,12 +336,11 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
 	}
 
 found:
-	/* RFC5722, Section 4:
-	 *                                  When reassembling an IPv6 datagram, if
+	/* RFC5722, Section 4, amended by Errata ID : 3089
+	 *                          When reassembling an IPv6 datagram, if
 	 *   one or more its constituent fragments is determined to be an
 	 *   overlapping fragment, the entire datagram (and any constituent
-	 *   fragments, including those not yet received) MUST be silently
-	 *   discarded.
+	 *   fragments) MUST be silently discarded.
 	 */
 
 	/* Check for overlap with preceding fragment. */
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8c2e3ab..92be12b 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -121,9 +121,22 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
 	return p;
 }
 
+static inline const void *choose_neigh_daddr(struct rt6_info *rt, const void *daddr)
+{
+	struct in6_addr *p = &rt->rt6i_gateway;
+
+	if (!ipv6_addr_any(p))
+		return (const void *) p;
+	return daddr;
+}
+
 static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr)
 {
-	struct neighbour *n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr);
+	struct rt6_info *rt = (struct rt6_info *) dst;
+	struct neighbour *n;
+
+	daddr = choose_neigh_daddr(rt, daddr);
+	n = __ipv6_neigh_lookup(&nd_tbl, dst->dev, daddr);
 	if (n)
 		return n;
 	return neigh_create(&nd_tbl, daddr, dst->dev);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 133768e..c4ffd17 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -680,9 +680,10 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 	/* ISATAP (RFC4214) - must come before 6to4 */
 	if (dev->priv_flags & IFF_ISATAP) {
 		struct neighbour *neigh = NULL;
+		bool do_tx_error = false;
 
 		if (skb_dst(skb))
-			neigh = dst_get_neighbour_noref(skb_dst(skb));
+			neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr);
 
 		if (neigh == NULL) {
 			if (net_ratelimit())
@@ -697,6 +698,10 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 		     ipv6_addr_is_isatap(addr6))
 			dst = addr6->s6_addr32[3];
 		else
+			do_tx_error = true;
+
+		neigh_release(neigh);
+		if (do_tx_error)
 			goto tx_error;
 	}
 
@@ -705,9 +710,10 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 
 	if (!dst) {
 		struct neighbour *neigh = NULL;
+		bool do_tx_error = false;
 
 		if (skb_dst(skb))
-			neigh = dst_get_neighbour_noref(skb_dst(skb));
+			neigh = dst_neigh_lookup(skb_dst(skb), &iph6->daddr);
 
 		if (neigh == NULL) {
 			if (net_ratelimit())
@@ -723,10 +729,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 			addr_type = ipv6_addr_type(addr6);
 		}
 
-		if ((addr_type & IPV6_ADDR_COMPATv4) == 0)
-			goto tx_error_icmp;
+		if ((addr_type & IPV6_ADDR_COMPATv4) != 0)
+			dst = addr6->s6_addr32[3];
+		else
+			do_tx_error = true;
 
-		dst = addr6->s6_addr32[3];
+		neigh_release(neigh);
+		if (do_tx_error)
+			goto tx_error;
 	}
 
 	rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3edd05a..12c6ece 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -540,19 +540,7 @@ static void tcp_v6_reqsk_destructor(struct request_sock *req)
 static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
 						   const struct in6_addr *addr)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
-	int i;
-
-	BUG_ON(tp == NULL);
-
-	if (!tp->md5sig_info || !tp->md5sig_info->entries6)
-		return NULL;
-
-	for (i = 0; i < tp->md5sig_info->entries6; i++) {
-		if (ipv6_addr_equal(&tp->md5sig_info->keys6[i].addr, addr))
-			return &tp->md5sig_info->keys6[i].base;
-	}
-	return NULL;
+	return tcp_md5_do_lookup(sk, (union tcp_md5_addr *)addr, AF_INET6);
 }
 
 static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk,
@@ -567,136 +555,11 @@ static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
 	return tcp_v6_md5_do_lookup(sk, &inet6_rsk(req)->rmt_addr);
 }
 
-static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
-			     char *newkey, u8 newkeylen)
-{
-	/* Add key to the list */
-	struct tcp_md5sig_key *key;
-	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp6_md5sig_key *keys;
-
-	key = tcp_v6_md5_do_lookup(sk, peer);
-	if (key) {
-		/* modify existing entry - just update that one */
-		kfree(key->key);
-		key->key = newkey;
-		key->keylen = newkeylen;
-	} else {
-		/* reallocate new list if current one is full. */
-		if (!tp->md5sig_info) {
-			tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info), GFP_ATOMIC);
-			if (!tp->md5sig_info) {
-				kfree(newkey);
-				return -ENOMEM;
-			}
-			sk_nocaps_add(sk, NETIF_F_GSO_MASK);
-		}
-		if (tp->md5sig_info->entries6 == 0 &&
-			tcp_alloc_md5sig_pool(sk) == NULL) {
-			kfree(newkey);
-			return -ENOMEM;
-		}
-		if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) {
-			keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) *
-				       (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
-
-			if (!keys) {
-				kfree(newkey);
-				if (tp->md5sig_info->entries6 == 0)
-					tcp_free_md5sig_pool();
-				return -ENOMEM;
-			}
-
-			if (tp->md5sig_info->entries6)
-				memmove(keys, tp->md5sig_info->keys6,
-					(sizeof (tp->md5sig_info->keys6[0]) *
-					 tp->md5sig_info->entries6));
-
-			kfree(tp->md5sig_info->keys6);
-			tp->md5sig_info->keys6 = keys;
-			tp->md5sig_info->alloced6++;
-		}
-
-		tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr = *peer;
-		tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.key = newkey;
-		tp->md5sig_info->keys6[tp->md5sig_info->entries6].base.keylen = newkeylen;
-
-		tp->md5sig_info->entries6++;
-	}
-	return 0;
-}
-
-static int tcp_v6_md5_add_func(struct sock *sk, struct sock *addr_sk,
-			       u8 *newkey, __u8 newkeylen)
-{
-	return tcp_v6_md5_do_add(sk, &inet6_sk(addr_sk)->daddr,
-				 newkey, newkeylen);
-}
-
-static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	int i;
-
-	for (i = 0; i < tp->md5sig_info->entries6; i++) {
-		if (ipv6_addr_equal(&tp->md5sig_info->keys6[i].addr, peer)) {
-			/* Free the key */
-			kfree(tp->md5sig_info->keys6[i].base.key);
-			tp->md5sig_info->entries6--;
-
-			if (tp->md5sig_info->entries6 == 0) {
-				kfree(tp->md5sig_info->keys6);
-				tp->md5sig_info->keys6 = NULL;
-				tp->md5sig_info->alloced6 = 0;
-				tcp_free_md5sig_pool();
-			} else {
-				/* shrink the database */
-				if (tp->md5sig_info->entries6 != i)
-					memmove(&tp->md5sig_info->keys6[i],
-						&tp->md5sig_info->keys6[i+1],
-						(tp->md5sig_info->entries6 - i)
-						* sizeof (tp->md5sig_info->keys6[0]));
-			}
-			return 0;
-		}
-	}
-	return -ENOENT;
-}
-
-static void tcp_v6_clear_md5_list (struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	int i;
-
-	if (tp->md5sig_info->entries6) {
-		for (i = 0; i < tp->md5sig_info->entries6; i++)
-			kfree(tp->md5sig_info->keys6[i].base.key);
-		tp->md5sig_info->entries6 = 0;
-		tcp_free_md5sig_pool();
-	}
-
-	kfree(tp->md5sig_info->keys6);
-	tp->md5sig_info->keys6 = NULL;
-	tp->md5sig_info->alloced6 = 0;
-
-	if (tp->md5sig_info->entries4) {
-		for (i = 0; i < tp->md5sig_info->entries4; i++)
-			kfree(tp->md5sig_info->keys4[i].base.key);
-		tp->md5sig_info->entries4 = 0;
-		tcp_free_md5sig_pool();
-	}
-
-	kfree(tp->md5sig_info->keys4);
-	tp->md5sig_info->keys4 = NULL;
-	tp->md5sig_info->alloced4 = 0;
-}
-
 static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
 				  int optlen)
 {
 	struct tcp_md5sig cmd;
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr;
-	u8 *newkey;
 
 	if (optlen < sizeof(cmd))
 		return -EINVAL;
@@ -708,36 +571,22 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
 		return -EINVAL;
 
 	if (!cmd.tcpm_keylen) {
-		if (!tcp_sk(sk)->md5sig_info)
-			return -ENOENT;
 		if (ipv6_addr_v4mapped(&sin6->sin6_addr))
-			return tcp_v4_md5_do_del(sk, sin6->sin6_addr.s6_addr32[3]);
-		return tcp_v6_md5_do_del(sk, &sin6->sin6_addr);
+			return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin6->sin6_addr.s6_addr32[3],
+					      AF_INET);
+		return tcp_md5_do_del(sk, (union tcp_md5_addr *)&sin6->sin6_addr,
+				      AF_INET6);
 	}
 
 	if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
 		return -EINVAL;
 
-	if (!tcp_sk(sk)->md5sig_info) {
-		struct tcp_sock *tp = tcp_sk(sk);
-		struct tcp_md5sig_info *p;
-
-		p = kzalloc(sizeof(struct tcp_md5sig_info), GFP_KERNEL);
-		if (!p)
-			return -ENOMEM;
+	if (ipv6_addr_v4mapped(&sin6->sin6_addr))
+		return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin6->sin6_addr.s6_addr32[3],
+				      AF_INET, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
 
-		tp->md5sig_info = p;
-		sk_nocaps_add(sk, NETIF_F_GSO_MASK);
-	}
-
-	newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
-	if (!newkey)
-		return -ENOMEM;
-	if (ipv6_addr_v4mapped(&sin6->sin6_addr)) {
-		return tcp_v4_md5_do_add(sk, sin6->sin6_addr.s6_addr32[3],
-					 newkey, cmd.tcpm_keylen);
-	}
-	return tcp_v6_md5_do_add(sk, &sin6->sin6_addr, newkey, cmd.tcpm_keylen);
+	return tcp_md5_do_add(sk, (union tcp_md5_addr *)&sin6->sin6_addr,
+			      AF_INET6, cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
 }
 
 static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp,
@@ -1074,6 +923,13 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
 	const struct tcphdr *th = tcp_hdr(skb);
 	u32 seq = 0, ack_seq = 0;
 	struct tcp_md5sig_key *key = NULL;
+#ifdef CONFIG_TCP_MD5SIG
+	const __u8 *hash_location = NULL;
+	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+	unsigned char newhash[16];
+	int genhash;
+	struct sock *sk1 = NULL;
+#endif
 
 	if (th->rst)
 		return;
@@ -1082,8 +938,32 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
 		return;
 
 #ifdef CONFIG_TCP_MD5SIG
-	if (sk)
-		key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr);
+	hash_location = tcp_parse_md5sig_option(th);
+	if (!sk && hash_location) {
+		/*
+		 * active side is lost. Try to find listening socket through
+		 * source port, and then find md5 key through listening socket.
+		 * we are not loose security here:
+		 * Incoming packet is checked with md5 hash with finding key,
+		 * no RST generated if md5 hash doesn't match.
+		 */
+		sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev),
+					   &tcp_hashinfo, &ipv6h->daddr,
+					   ntohs(th->source), inet6_iif(skb));
+		if (!sk1)
+			return;
+
+		rcu_read_lock();
+		key = tcp_v6_md5_do_lookup(sk1, &ipv6h->saddr);
+		if (!key)
+			goto release_sk1;
+
+		genhash = tcp_v6_md5_hash_skb(newhash, key, NULL, NULL, skb);
+		if (genhash || memcmp(hash_location, newhash, 16) != 0)
+			goto release_sk1;
+	} else {
+		key = sk ? tcp_v6_md5_do_lookup(sk, &ipv6h->saddr) : NULL;
+	}
 #endif
 
 	if (th->ack)
@@ -1093,6 +973,14 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
 			  (th->doff << 2);
 
 	tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1, 0);
+
+#ifdef CONFIG_TCP_MD5SIG
+release_sk1:
+	if (sk1) {
+		rcu_read_unlock();
+		sock_put(sk1);
+	}
+#endif
 }
 
 static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
@@ -1394,6 +1282,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 		newnp->opt	   = NULL;
 		newnp->mcast_oif   = inet6_iif(skb);
 		newnp->mcast_hops  = ipv6_hdr(skb)->hop_limit;
+		newnp->rcv_tclass  = ipv6_tclass(ipv6_hdr(skb));
 
 		/*
 		 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
@@ -1472,6 +1361,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 	newnp->opt	  = NULL;
 	newnp->mcast_oif  = inet6_iif(skb);
 	newnp->mcast_hops = ipv6_hdr(skb)->hop_limit;
+	newnp->rcv_tclass = ipv6_tclass(ipv6_hdr(skb));
 
 	/* Clone native IPv6 options from listening socket (if any)
 
@@ -1510,10 +1400,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 		 * memory, then we end up not copying the key
 		 * across. Shucks.
 		 */
-		char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
-		if (newkey != NULL)
-			tcp_v6_md5_do_add(newsk, &newnp->daddr,
-					  newkey, key->keylen);
+		tcp_md5_do_add(newsk, (union tcp_md5_addr *)&newnp->daddr,
+			       AF_INET6, key->key, key->keylen, GFP_ATOMIC);
 	}
 #endif
 
@@ -1676,6 +1564,8 @@ ipv6_pktoptions:
 			np->mcast_oif = inet6_iif(opt_skb);
 		if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
 			np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
+		if (np->rxopt.bits.rxtclass)
+			np->rcv_tclass = ipv6_tclass(ipv6_hdr(skb));
 		if (ipv6_opt_accepted(sk, opt_skb)) {
 			skb_set_owner_r(opt_skb, sk);
 			opt_skb = xchg(&np->pktoptions, opt_skb);
@@ -1898,7 +1788,6 @@ static const struct inet_connection_sock_af_ops ipv6_specific = {
 static const struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
 	.md5_lookup	=	tcp_v6_md5_lookup,
 	.calc_md5_hash	=	tcp_v6_md5_hash_skb,
-	.md5_add	=	tcp_v6_md5_add_func,
 	.md5_parse	=	tcp_v6_parse_md5_keys,
 };
 #endif
@@ -1930,7 +1819,6 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
 static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
 	.md5_lookup	=	tcp_v4_md5_lookup,
 	.calc_md5_hash	=	tcp_v4_md5_hash_skb,
-	.md5_add	=	tcp_v6_md5_add_func,
 	.md5_parse	=	tcp_v6_parse_md5_keys,
 };
 #endif
@@ -2004,11 +1892,6 @@ static int tcp_v6_init_sock(struct sock *sk)
 
 static void tcp_v6_destroy_sock(struct sock *sk)
 {
-#ifdef CONFIG_TCP_MD5SIG
-	/* Clean up the MD5 key list */
-	if (tcp_sk(sk)->md5sig_info)
-		tcp_v6_clear_md5_list(sk);
-#endif
 	tcp_v4_destroy_sock(sk);
 	inet6_destroy_sock(sk);
 }
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4f96b5c..37b0699 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -342,7 +342,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
 	struct inet_sock *inet = inet_sk(sk);
 	struct sk_buff *skb;
 	unsigned int ulen, copied;
-	int peeked;
+	int peeked, off = 0;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
 	int is_udp4;
@@ -359,7 +359,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
 
 try_again:
 	skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
-				  &peeked, &err);
+				  &peeked, &off, &err);
 	if (!skb)
 		goto out;
 
@@ -1130,7 +1130,8 @@ do_udp_sendmsg:
 	if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr)) {
 		fl6.flowi6_oif = np->mcast_oif;
 		connected = 0;
-	}
+	} else if (!fl6.flowi6_oif)
+		fl6.flowi6_oif = np->ucast_oif;
 
 	security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
 
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 4eeff89..8755a30 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -146,7 +146,7 @@ static int __xfrm6_output(struct sk_buff *skb)
 		return -EMSGSIZE;
 	}
 
-	if ((x && x->props.mode == XFRM_MODE_TUNNEL) &&
+	if (x->props.mode == XFRM_MODE_TUNNEL &&
 	    ((skb->len > mtu && !skb_is_gso(skb)) ||
 		dst_allfrag(skb_dst(skb)))) {
 			return ip6_fragment(skb, x->outer_mode->afinfo->output_finish);
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index d5c5b8f..98d1f0b 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -90,6 +90,7 @@ do {									\
 
 static void iucv_sock_kill(struct sock *sk);
 static void iucv_sock_close(struct sock *sk);
+static void iucv_sever_path(struct sock *, int);
 
 static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
 	struct packet_type *pt, struct net_device *orig_dev);
@@ -130,17 +131,6 @@ static inline void low_nmcpy(unsigned char *dst, char *src)
        memcpy(&dst[8], src, 8);
 }
 
-static void iucv_skb_queue_purge(struct sk_buff_head *list)
-{
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(list)) != NULL) {
-		if (skb->dev)
-			dev_put(skb->dev);
-		kfree_skb(skb);
-	}
-}
-
 static int afiucv_pm_prepare(struct device *dev)
 {
 #ifdef CONFIG_PM_DEBUG
@@ -175,17 +165,13 @@ static int afiucv_pm_freeze(struct device *dev)
 	read_lock(&iucv_sk_list.lock);
 	sk_for_each(sk, node, &iucv_sk_list.head) {
 		iucv = iucv_sk(sk);
-		iucv_skb_queue_purge(&iucv->send_skb_q);
+		skb_queue_purge(&iucv->send_skb_q);
 		skb_queue_purge(&iucv->backlog_skb_q);
 		switch (sk->sk_state) {
 		case IUCV_DISCONN:
 		case IUCV_CLOSING:
 		case IUCV_CONNECTED:
-			if (iucv->path) {
-				err = pr_iucv->path_sever(iucv->path, NULL);
-				iucv_path_free(iucv->path);
-				iucv->path = NULL;
-			}
+			iucv_sever_path(sk, 0);
 			break;
 		case IUCV_OPEN:
 		case IUCV_BOUND:
@@ -194,6 +180,8 @@ static int afiucv_pm_freeze(struct device *dev)
 		default:
 			break;
 		}
+		skb_queue_purge(&iucv->send_skb_q);
+		skb_queue_purge(&iucv->backlog_skb_q);
 	}
 	read_unlock(&iucv_sk_list.lock);
 	return err;
@@ -338,7 +326,6 @@ static void iucv_sock_wake_msglim(struct sock *sk)
 static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
 		   struct sk_buff *skb, u8 flags)
 {
-	struct net *net = sock_net(sock);
 	struct iucv_sock *iucv = iucv_sk(sock);
 	struct af_iucv_trans_hdr *phs_hdr;
 	struct sk_buff *nskb;
@@ -375,10 +362,10 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
 	if (imsg)
 		memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message));
 
-	skb->dev = dev_get_by_index(net, sock->sk_bound_dev_if);
+	skb->dev = iucv->hs_dev;
 	if (!skb->dev)
 		return -ENODEV;
-	if (!(skb->dev->flags & IFF_UP))
+	if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev))
 		return -ENETDOWN;
 	if (skb->len > skb->dev->mtu) {
 		if (sock->sk_type == SOCK_SEQPACKET)
@@ -393,15 +380,14 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock,
 		return -ENOMEM;
 	skb_queue_tail(&iucv->send_skb_q, nskb);
 	err = dev_queue_xmit(skb);
-	if (err) {
+	if (net_xmit_eval(err)) {
 		skb_unlink(nskb, &iucv->send_skb_q);
-		dev_put(nskb->dev);
 		kfree_skb(nskb);
 	} else {
 		atomic_sub(confirm_recv, &iucv->msg_recv);
 		WARN_ON(atomic_read(&iucv->msg_recv) < 0);
 	}
-	return err;
+	return net_xmit_eval(err);
 }
 
 static struct sock *__iucv_get_sock_by_name(char *nm)
@@ -447,13 +433,33 @@ static void iucv_sock_kill(struct sock *sk)
 	sock_put(sk);
 }
 
+/* Terminate an IUCV path */
+static void iucv_sever_path(struct sock *sk, int with_user_data)
+{
+	unsigned char user_data[16];
+	struct iucv_sock *iucv = iucv_sk(sk);
+	struct iucv_path *path = iucv->path;
+
+	if (iucv->path) {
+		iucv->path = NULL;
+		if (with_user_data) {
+			low_nmcpy(user_data, iucv->src_name);
+			high_nmcpy(user_data, iucv->dst_name);
+			ASCEBC(user_data, sizeof(user_data));
+			pr_iucv->path_sever(path, user_data);
+		} else
+			pr_iucv->path_sever(path, NULL);
+		iucv_path_free(path);
+	}
+}
+
 /* Close an IUCV socket */
 static void iucv_sock_close(struct sock *sk)
 {
-	unsigned char user_data[16];
 	struct iucv_sock *iucv = iucv_sk(sk);
 	unsigned long timeo;
-	int err, blen;
+	int err = 0;
+	int blen;
 	struct sk_buff *skb;
 
 	lock_sock(sk);
@@ -480,7 +486,7 @@ static void iucv_sock_close(struct sock *sk)
 		sk->sk_state = IUCV_CLOSING;
 		sk->sk_state_change(sk);
 
-		if (!skb_queue_empty(&iucv->send_skb_q)) {
+		if (!err && !skb_queue_empty(&iucv->send_skb_q)) {
 			if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
 				timeo = sk->sk_lingertime;
 			else
@@ -494,25 +500,20 @@ static void iucv_sock_close(struct sock *sk)
 		sk->sk_state = IUCV_CLOSED;
 		sk->sk_state_change(sk);
 
-		if (iucv->path) {
-			low_nmcpy(user_data, iucv->src_name);
-			high_nmcpy(user_data, iucv->dst_name);
-			ASCEBC(user_data, sizeof(user_data));
-			pr_iucv->path_sever(iucv->path, user_data);
-			iucv_path_free(iucv->path);
-			iucv->path = NULL;
-		}
-
 		sk->sk_err = ECONNRESET;
 		sk->sk_state_change(sk);
 
-		iucv_skb_queue_purge(&iucv->send_skb_q);
+		skb_queue_purge(&iucv->send_skb_q);
 		skb_queue_purge(&iucv->backlog_skb_q);
-		break;
 
-	default:
-		/* nothing to do here */
-		break;
+	default:   /* fall through */
+		iucv_sever_path(sk, 1);
+	}
+
+	if (iucv->hs_dev) {
+		dev_put(iucv->hs_dev);
+		iucv->hs_dev = NULL;
+		sk->sk_bound_dev_if = 0;
 	}
 
 	/* mark socket for deletion by iucv_sock_kill() */
@@ -706,7 +707,6 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
 		goto done_unlock;
 
 	/* Bind the socket */
-
 	if (pr_iucv)
 		if (!memcmp(sa->siucv_user_id, iucv_userid, 8))
 			goto vm_bind; /* VM IUCV transport */
@@ -720,6 +720,8 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
 			memcpy(iucv->src_name, sa->siucv_name, 8);
 			memcpy(iucv->src_user_id, sa->siucv_user_id, 8);
 			sk->sk_bound_dev_if = dev->ifindex;
+			iucv->hs_dev = dev;
+			dev_hold(dev);
 			sk->sk_state = IUCV_BOUND;
 			iucv->transport = AF_IUCV_TRANS_HIPER;
 			if (!iucv->msglimit)
@@ -894,11 +896,8 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
 	if (sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_CLOSED)
 		err = -ECONNREFUSED;
 
-	if (err && iucv->transport == AF_IUCV_TRANS_IUCV) {
-		pr_iucv->path_sever(iucv->path, NULL);
-		iucv_path_free(iucv->path);
-		iucv->path = NULL;
-	}
+	if (err && iucv->transport == AF_IUCV_TRANS_IUCV)
+		iucv_sever_path(sk, 0);
 
 done:
 	release_sock(sk);
@@ -1124,8 +1123,10 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 			noblock, &err);
 	else
 		skb = sock_alloc_send_skb(sk, len, noblock, &err);
-	if (!skb)
+	if (!skb) {
+		err = -ENOMEM;
 		goto out;
+	}
 	if (iucv->transport == AF_IUCV_TRANS_HIPER)
 		skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN);
 	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
@@ -1148,6 +1149,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 	/* increment and save iucv message tag for msg_completion cbk */
 	txmsg.tag = iucv->send_tag++;
 	memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
+
 	if (iucv->transport == AF_IUCV_TRANS_HIPER) {
 		atomic_inc(&iucv->msg_sent);
 		err = afiucv_hs_send(&txmsg, sk, skb, 0);
@@ -1202,8 +1204,6 @@ release:
 	return len;
 
 fail:
-	if (skb->dev)
-		dev_put(skb->dev);
 	kfree_skb(skb);
 out:
 	release_sock(sk);
@@ -1396,7 +1396,14 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 		}
 
 		kfree_skb(skb);
-		atomic_inc(&iucv->msg_recv);
+		if (iucv->transport == AF_IUCV_TRANS_HIPER) {
+			atomic_inc(&iucv->msg_recv);
+			if (atomic_read(&iucv->msg_recv) > iucv->msglimit) {
+				WARN_ON(1);
+				iucv_sock_close(sk);
+				return -EFAULT;
+			}
+		}
 
 		/* Queue backlog skbs */
 		spin_lock_bh(&iucv->message_q.lock);
@@ -1486,7 +1493,7 @@ unsigned int iucv_sock_poll(struct file *file, struct socket *sock,
 	if (sk->sk_state == IUCV_DISCONN)
 		mask |= POLLIN;
 
-	if (sock_writeable(sk))
+	if (sock_writeable(sk) && iucv_below_msglim(sk))
 		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
 	else
 		set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
@@ -1565,13 +1572,6 @@ static int iucv_sock_release(struct socket *sock)
 
 	iucv_sock_close(sk);
 
-	/* Unregister with IUCV base support */
-	if (iucv_sk(sk)->path) {
-		pr_iucv->path_sever(iucv_sk(sk)->path, NULL);
-		iucv_path_free(iucv_sk(sk)->path);
-		iucv_sk(sk)->path = NULL;
-	}
-
 	sock_orphan(sk);
 	iucv_sock_kill(sk);
 	return err;
@@ -1633,7 +1633,8 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
 {
 	struct sock *sk = sock->sk;
 	struct iucv_sock *iucv = iucv_sk(sk);
-	int val, len;
+	unsigned int val;
+	int len;
 
 	if (level != SOL_IUCV)
 		return -ENOPROTOOPT;
@@ -1656,6 +1657,13 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
 					   : iucv->msglimit;	/* default */
 		release_sock(sk);
 		break;
+	case SO_MSGSIZE:
+		if (sk->sk_state == IUCV_OPEN)
+			return -EBADFD;
+		val = (iucv->hs_dev) ? iucv->hs_dev->mtu -
+				sizeof(struct af_iucv_trans_hdr) - ETH_HLEN :
+				0x7fffffff;
+		break;
 	default:
 		return -ENOPROTOOPT;
 	}
@@ -1750,8 +1758,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
 	path->msglim = iucv->msglimit;
 	err = pr_iucv->path_accept(path, &af_iucv_handler, nuser_data, nsk);
 	if (err) {
-		err = pr_iucv->path_sever(path, user_data);
-		iucv_path_free(path);
+		iucv_sever_path(nsk, 1);
 		iucv_sock_kill(nsk);
 		goto fail;
 	}
@@ -1828,6 +1835,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
 	struct sk_buff *list_skb = list->next;
 	unsigned long flags;
 
+	bh_lock_sock(sk);
 	if (!skb_queue_empty(list)) {
 		spin_lock_irqsave(&list->lock, flags);
 
@@ -1849,7 +1857,6 @@ static void iucv_callback_txdone(struct iucv_path *path,
 			iucv_sock_wake_msglim(sk);
 		}
 	}
-	BUG_ON(!this);
 
 	if (sk->sk_state == IUCV_CLOSING) {
 		if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) {
@@ -1857,6 +1864,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
 			sk->sk_state_change(sk);
 		}
 	}
+	bh_unlock_sock(sk);
 
 }
 
@@ -1864,9 +1872,15 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
 {
 	struct sock *sk = path->private;
 
+	if (sk->sk_state == IUCV_CLOSED)
+		return;
+
+	bh_lock_sock(sk);
+	iucv_sever_path(sk, 1);
 	sk->sk_state = IUCV_DISCONN;
 
 	sk->sk_state_change(sk);
+	bh_unlock_sock(sk);
 }
 
 /* called if the other communication side shuts down its RECV direction;
@@ -1954,6 +1968,8 @@ static int afiucv_hs_callback_syn(struct sock *sk, struct sk_buff *skb)
 	memcpy(niucv->src_name, iucv->src_name, 8);
 	memcpy(niucv->src_user_id, iucv->src_user_id, 8);
 	nsk->sk_bound_dev_if = sk->sk_bound_dev_if;
+	niucv->hs_dev = iucv->hs_dev;
+	dev_hold(niucv->hs_dev);
 	afiucv_swap_src_dest(skb);
 	trans_hdr->flags = AF_IUCV_FLAG_SYN | AF_IUCV_FLAG_ACK;
 	trans_hdr->window = niucv->msglimit;
@@ -2022,12 +2038,15 @@ static int afiucv_hs_callback_fin(struct sock *sk, struct sk_buff *skb)
 	struct iucv_sock *iucv = iucv_sk(sk);
 
 	/* other end of connection closed */
-	if (iucv) {
-		bh_lock_sock(sk);
+	if (!iucv)
+		goto out;
+	bh_lock_sock(sk);
+	if (sk->sk_state == IUCV_CONNECTED) {
 		sk->sk_state = IUCV_DISCONN;
 		sk->sk_state_change(sk);
-		bh_unlock_sock(sk);
 	}
+	bh_unlock_sock(sk);
+out:
 	kfree_skb(skb);
 	return NET_RX_SUCCESS;
 }
@@ -2172,11 +2191,11 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
 		break;
 	case (AF_IUCV_FLAG_WIN):
 		err = afiucv_hs_callback_win(sk, skb);
-		if (skb->len > sizeof(struct af_iucv_trans_hdr))
-			err = afiucv_hs_callback_rx(sk, skb);
-		else
-			kfree(skb);
-		break;
+		if (skb->len == sizeof(struct af_iucv_trans_hdr)) {
+			kfree_skb(skb);
+			break;
+		}
+		/* fall through */
 	case 0:
 		/* plain data frame */
 		memcpy(CB_TRGCLS(skb), &trans_hdr->iucv_hdr.class,
@@ -2202,65 +2221,64 @@ static void afiucv_hs_callback_txnotify(struct sk_buff *skb,
 	struct iucv_sock *iucv = NULL;
 	struct sk_buff_head *list;
 	struct sk_buff *list_skb;
-	struct sk_buff *this = NULL;
+	struct sk_buff *nskb;
 	unsigned long flags;
 	struct hlist_node *node;
 
-	read_lock(&iucv_sk_list.lock);
+	read_lock_irqsave(&iucv_sk_list.lock, flags);
 	sk_for_each(sk, node, &iucv_sk_list.head)
 		if (sk == isk) {
 			iucv = iucv_sk(sk);
 			break;
 		}
-	read_unlock(&iucv_sk_list.lock);
+	read_unlock_irqrestore(&iucv_sk_list.lock, flags);
 
-	if (!iucv)
+	if (!iucv || sock_flag(sk, SOCK_ZAPPED))
 		return;
 
-	bh_lock_sock(sk);
 	list = &iucv->send_skb_q;
-	list_skb = list->next;
+	spin_lock_irqsave(&list->lock, flags);
 	if (skb_queue_empty(list))
 		goto out_unlock;
-
-	spin_lock_irqsave(&list->lock, flags);
+	list_skb = list->next;
+	nskb = list_skb->next;
 	while (list_skb != (struct sk_buff *)list) {
 		if (skb_shinfo(list_skb) == skb_shinfo(skb)) {
-			this = list_skb;
 			switch (n) {
 			case TX_NOTIFY_OK:
-				__skb_unlink(this, list);
+				__skb_unlink(list_skb, list);
+				kfree_skb(list_skb);
 				iucv_sock_wake_msglim(sk);
-				dev_put(this->dev);
-				kfree_skb(this);
 				break;
 			case TX_NOTIFY_PENDING:
 				atomic_inc(&iucv->pendings);
 				break;
 			case TX_NOTIFY_DELAYED_OK:
-				__skb_unlink(this, list);
+				__skb_unlink(list_skb, list);
 				atomic_dec(&iucv->pendings);
 				if (atomic_read(&iucv->pendings) <= 0)
 					iucv_sock_wake_msglim(sk);
-				dev_put(this->dev);
-				kfree_skb(this);
+				kfree_skb(list_skb);
 				break;
 			case TX_NOTIFY_UNREACHABLE:
 			case TX_NOTIFY_DELAYED_UNREACHABLE:
 			case TX_NOTIFY_TPQFULL: /* not yet used */
 			case TX_NOTIFY_GENERALERROR:
 			case TX_NOTIFY_DELAYED_GENERALERROR:
-				__skb_unlink(this, list);
-				dev_put(this->dev);
-				kfree_skb(this);
-				sk->sk_state = IUCV_DISCONN;
-				sk->sk_state_change(sk);
+				__skb_unlink(list_skb, list);
+				kfree_skb(list_skb);
+				if (sk->sk_state == IUCV_CONNECTED) {
+					sk->sk_state = IUCV_DISCONN;
+					sk->sk_state_change(sk);
+				}
 				break;
 			}
 			break;
 		}
-		list_skb = list_skb->next;
+		list_skb = nskb;
+		nskb = nskb->next;
 	}
+out_unlock:
 	spin_unlock_irqrestore(&list->lock, flags);
 
 	if (sk->sk_state == IUCV_CLOSING) {
@@ -2270,8 +2288,6 @@ static void afiucv_hs_callback_txnotify(struct sk_buff *skb,
 		}
 	}
 
-out_unlock:
-	bh_unlock_sock(sk);
 }
 static const struct proto_ops iucv_sock_ops = {
 	.family		= PF_IUCV,
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 403be43..3ad1f9d 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -1800,7 +1800,7 @@ static void iucv_work_fn(struct work_struct *work)
  * Handles external interrupts coming in from CP.
  * Places the interrupt buffer on a queue and schedules iucv_tasklet_fn().
  */
-static void iucv_external_interrupt(unsigned int ext_int_code,
+static void iucv_external_interrupt(struct ext_code ext_code,
 				    unsigned int param32, unsigned long param64)
 {
 	struct iucv_irq_data *p;
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index d2726a7..63fe5f3 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -64,7 +64,7 @@ static int l2tp_eth_dev_init(struct net_device *dev)
 	struct l2tp_eth *priv = netdev_priv(dev);
 
 	priv->dev = dev;
-	random_ether_addr(dev->dev_addr);
+	eth_hw_addr_random(dev);
 	memset(&dev->broadcast[0], 0xff, 6);
 
 	return 0;
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index d540c3b..1be7a45 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -9,7 +9,7 @@ mac80211-y := \
 	scan.o offchannel.o \
 	ht.o agg-tx.o agg-rx.o \
 	ibss.o \
-	mlme.o work.o \
+	work.o \
 	iface.o \
 	rate.o \
 	michael.o \
@@ -25,7 +25,7 @@ mac80211-y := \
 	wme.o \
 	event.o \
 	chan.o \
-	driver-trace.o
+	driver-trace.o mlme.o
 
 mac80211-$(CONFIG_MAC80211_LEDS) += led.o
 mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 296620d..c3de921 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -776,12 +776,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
 		if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED) &&
 		    !test_sta_flag(sta, WLAN_STA_AUTH)) {
-			ret = sta_info_move_state_checked(sta,
-					IEEE80211_STA_AUTH);
+			ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
 			if (ret)
 				return ret;
-			ret = sta_info_move_state_checked(sta,
-					IEEE80211_STA_ASSOC);
+			ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
 			if (ret)
 				return ret;
 		}
@@ -789,11 +787,9 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
 	if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
 		if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
-			ret = sta_info_move_state_checked(sta,
-					IEEE80211_STA_AUTHORIZED);
+			ret = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
 		else if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
-			ret = sta_info_move_state_checked(sta,
-					IEEE80211_STA_ASSOC);
+			ret = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
 		if (ret)
 			return ret;
 	}
@@ -805,12 +801,10 @@ static int sta_apply_parameters(struct ieee80211_local *local,
 
 		if (!(set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) &&
 		    test_sta_flag(sta, WLAN_STA_AUTH)) {
-			ret = sta_info_move_state_checked(sta,
-					IEEE80211_STA_AUTH);
+			ret = sta_info_move_state(sta, IEEE80211_STA_AUTH);
 			if (ret)
 				return ret;
-			ret = sta_info_move_state_checked(sta,
-					IEEE80211_STA_NONE);
+			ret = sta_info_move_state(sta, IEEE80211_STA_NONE);
 			if (ret)
 				return ret;
 		}
@@ -944,8 +938,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 	if (!sta)
 		return -ENOMEM;
 
-	sta_info_move_state(sta, IEEE80211_STA_AUTH);
-	sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+	sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+	sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
 
 	err = sta_apply_parameters(local, sta, params);
 	if (err) {
@@ -1001,6 +995,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 	struct sta_info *sta;
 	struct ieee80211_sub_if_data *vlansdata;
+	int err;
 
 	mutex_lock(&local->sta_mtx);
 
@@ -1040,7 +1035,11 @@ static int ieee80211_change_station(struct wiphy *wiphy,
 		ieee80211_send_layer2_update(sta);
 	}
 
-	sta_apply_parameters(local, sta, params);
+	err = sta_apply_parameters(local, sta, params);
+	if (err) {
+		mutex_unlock(&local->sta_mtx);
+		return err;
+	}
 
 	if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates)
 		rate_control_rate_init(sta);
@@ -1341,6 +1340,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
 		conf->dot11MeshHWMPRannInterval =
 			nconf->dot11MeshHWMPRannInterval;
 	}
+	if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
+		conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
 	return 0;
 }
 
@@ -1868,7 +1869,6 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
 					 s32 rssi_thold, u32 rssi_hyst)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_vif *vif = &sdata->vif;
 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 
@@ -1879,14 +1879,9 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy,
 	bss_conf->cqm_rssi_thold = rssi_thold;
 	bss_conf->cqm_rssi_hyst = rssi_hyst;
 
-	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
-		if (sdata->vif.type != NL80211_IFTYPE_STATION)
-			return -EOPNOTSUPP;
-		return 0;
-	}
-
 	/* tell the driver upon association, unless already associated */
-	if (sdata->u.mgd.associated)
+	if (sdata->u.mgd.associated &&
+	    sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)
 		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM);
 
 	return 0;
@@ -1907,8 +1902,11 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
 			return ret;
 	}
 
-	for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
 		sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
+		memcpy(sdata->rc_rateidx_mcs_mask[i], mask->control[i].mcs,
+		       sizeof(mask->control[i].mcs));
+	}
 
 	return 0;
 }
@@ -2030,7 +2028,7 @@ ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)
 	if (wk->offchan_tx.wait && !wk->offchan_tx.status)
 		cfg80211_mgmt_tx_status(wk->sdata->dev,
 					(unsigned long) wk->offchan_tx.frame,
-					wk->ie, wk->ie_len, false, GFP_KERNEL);
+					wk->data, wk->data_len, false, GFP_KERNEL);
 
 	return WORK_DONE_DESTROY;
 }
@@ -2181,8 +2179,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 	wk->done = ieee80211_offchan_tx_done;
 	wk->offchan_tx.frame = skb;
 	wk->offchan_tx.wait = wait;
-	wk->ie_len = len;
-	memcpy(wk->ie, buf, len);
+	wk->data_len = len;
+	memcpy(wk->data, buf, len);
 
 	ieee80211_add_work(wk);
 	return 0;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 889c3e9..d1f7abd 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -20,23 +20,29 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local,
 		if (!ieee80211_sdata_running(sdata))
 			continue;
 
-		if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+		switch (sdata->vif.type) {
+		case NL80211_IFTYPE_MONITOR:
 			continue;
-
-		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-		    !sdata->u.mgd.associated)
-			continue;
-
-		if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+		case NL80211_IFTYPE_STATION:
+			if (!sdata->u.mgd.associated)
+				continue;
+			break;
+		case NL80211_IFTYPE_ADHOC:
 			if (!sdata->u.ibss.ssid_len)
 				continue;
 			if (!sdata->u.ibss.fixed_channel)
 				return CHAN_MODE_HOPPING;
-		}
-
-		if (sdata->vif.type == NL80211_IFTYPE_AP &&
-		    !sdata->u.ap.beacon)
+			break;
+		case NL80211_IFTYPE_AP_VLAN:
+			/* will also have _AP interface */
 			continue;
+		case NL80211_IFTYPE_AP:
+			if (!sdata->u.ap.beacon)
+				continue;
+			break;
+		default:
+			break;
+		}
 
 		return CHAN_MODE_FIXED;
 	}
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 90baea5..483e96e 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -247,8 +247,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
 		sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n");
 	if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE)
 		sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n");
-	if (local->hw.flags & IEEE80211_HW_BEACON_FILTER)
-		sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n");
 	if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS)
 		sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n");
 	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
@@ -259,14 +257,14 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf,
 		sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n");
 	if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
 		sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n");
-	if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)
-		sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n");
 	if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)
 		sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n");
 	if (local->hw.flags & IEEE80211_HW_AP_LINK_PS)
 		sf += snprintf(buf + sf, mxln - sf, "AP_LINK_PS\n");
 	if (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)
 		sf += snprintf(buf + sf, mxln - sf, "TX_AMPDU_SETUP_IN_HW\n");
+	if (local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)
+		sf += snprintf(buf + sf, mxln - sf, "SCAN_WHILE_IDLE\n");
 
 	rv = simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
 	kfree(buf);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 176c08f..510ed1d 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -87,6 +87,21 @@ static ssize_t ieee80211_if_fmt_##name(					\
 #define IEEE80211_IF_FMT_SIZE(name, field)				\
 		IEEE80211_IF_FMT(name, field, "%zd\n")
 
+#define IEEE80211_IF_FMT_HEXARRAY(name, field)				\
+static ssize_t ieee80211_if_fmt_##name(					\
+	const struct ieee80211_sub_if_data *sdata,			\
+	char *buf, int buflen)						\
+{									\
+	char *p = buf;							\
+	int i;								\
+	for (i = 0; i < sizeof(sdata->field); i++) {			\
+		p += scnprintf(p, buflen + buf - p, "%.2x ",		\
+				 sdata->field[i]);			\
+	}								\
+	p += scnprintf(p, buflen + buf - p, "\n");			\
+	return p - buf;							\
+}
+
 #define IEEE80211_IF_FMT_ATOMIC(name, field)				\
 static ssize_t ieee80211_if_fmt_##name(					\
 	const struct ieee80211_sub_if_data *sdata,			\
@@ -148,6 +163,11 @@ IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
 		  HEX);
 IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
 		  HEX);
+IEEE80211_IF_FILE(rc_rateidx_mcs_mask_2ghz,
+		  rc_rateidx_mcs_mask[IEEE80211_BAND_2GHZ], HEXARRAY);
+IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
+		  rc_rateidx_mcs_mask[IEEE80211_BAND_5GHZ], HEXARRAY);
+
 IEEE80211_IF_FILE(flags, flags, HEX);
 IEEE80211_IF_FILE(state, state, LHEX);
 IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
@@ -422,6 +442,7 @@ IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
 		u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
 IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
 		u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
 #endif
 
 
@@ -441,6 +462,8 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
 	DEBUGFS_ADD(bssid);
 	DEBUGFS_ADD(aid);
@@ -458,6 +481,8 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
 	DEBUGFS_ADD(num_sta_authorized);
 	DEBUGFS_ADD(num_sta_ps);
@@ -468,6 +493,12 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 
 static void add_ibss_files(struct ieee80211_sub_if_data *sdata)
 {
+	DEBUGFS_ADD(channel_type);
+	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
+
 	DEBUGFS_ADD_MODE(tsf, 0600);
 }
 
@@ -479,6 +510,8 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 
 	DEBUGFS_ADD(peer);
 }
@@ -491,6 +524,8 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(channel_type);
 	DEBUGFS_ADD(rc_rateidx_mask_2ghz);
 	DEBUGFS_ADD(rc_rateidx_mask_5ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_2ghz);
+	DEBUGFS_ADD(rc_rateidx_mcs_mask_5ghz);
 }
 
 static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 2406b3e..6d45804 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,14 +63,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
 	test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
 
 	int res = scnprintf(buf, sizeof(buf),
-			    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+			    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
 			    TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
 			    TEST(PS_DRIVER), TEST(AUTHORIZED),
 			    TEST(SHORT_PREAMBLE),
 			    TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
 			    TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
 			    TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
-			    TEST(TDLS_PEER_AUTH));
+			    TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
+			    TEST(INSERTED), TEST(RATE_CONTROL));
 #undef TEST
 	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index e8960ae..70dfb64 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -253,6 +253,7 @@ static inline int drv_set_key(struct ieee80211_local *local,
 
 	might_sleep();
 
+	sdata = get_bss_sdata(sdata);
 	check_sdata_in_driver(sdata);
 
 	trace_drv_set_key(local, cmd, sdata, sta, key);
@@ -272,6 +273,7 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
 	if (sta)
 		ista = &sta->sta;
 
+	sdata = get_bss_sdata(sdata);
 	check_sdata_in_driver(sdata);
 
 	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
@@ -476,6 +478,37 @@ static inline void drv_sta_remove(struct ieee80211_local *local,
 	trace_drv_return_void(local);
 }
 
+static inline __must_check
+int drv_sta_state(struct ieee80211_local *local,
+		  struct ieee80211_sub_if_data *sdata,
+		  struct sta_info *sta,
+		  enum ieee80211_sta_state old_state,
+		  enum ieee80211_sta_state new_state)
+{
+	int ret = 0;
+
+	might_sleep();
+
+	sdata = get_bss_sdata(sdata);
+	check_sdata_in_driver(sdata);
+
+	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
+	if (local->ops->sta_state) {
+		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
+					    old_state, new_state);
+	} else if (old_state == IEEE80211_STA_AUTH &&
+		   new_state == IEEE80211_STA_ASSOC) {
+		ret = drv_sta_add(local, sdata, &sta->sta);
+		if (ret == 0)
+			sta->uploaded = true;
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		   new_state == IEEE80211_STA_AUTH) {
+		drv_sta_remove(local, sdata, &sta->sta);
+	}
+	trace_drv_return_int(local, ret);
+	return ret;
+}
+
 static inline int drv_conf_tx(struct ieee80211_local *local,
 			      struct ieee80211_sub_if_data *sdata, u16 queue,
 			      const struct ieee80211_tx_queue_params *params)
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 6e9df8f..384e2f0 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -635,6 +635,38 @@ TRACE_EVENT(drv_sta_notify,
 	)
 );
 
+TRACE_EVENT(drv_sta_state,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sub_if_data *sdata,
+		 struct ieee80211_sta *sta,
+		 enum ieee80211_sta_state old_state,
+		 enum ieee80211_sta_state new_state),
+
+	TP_ARGS(local, sdata, sta, old_state, new_state),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		STA_ENTRY
+		__field(u32, old_state)
+		__field(u32, new_state)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		STA_ASSIGN;
+		__entry->old_state = old_state;
+		__entry->new_state = new_state;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " state: %d->%d",
+		LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG,
+		__entry->old_state, __entry->new_state
+	)
+);
+
 TRACE_EVENT(drv_sta_add,
 	TP_PROTO(struct ieee80211_local *local,
 		 struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a464396..8361da4 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -36,31 +36,6 @@
 #define IEEE80211_IBSS_MAX_STA_ENTRIES 128
 
 
-static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
-					struct ieee80211_mgmt *mgmt,
-					size_t len)
-{
-	u16 auth_alg, auth_transaction;
-
-	lockdep_assert_held(&sdata->u.ibss.mtx);
-
-	if (len < 24 + 6)
-		return;
-
-	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
-	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
-
-	/*
-	 * IEEE 802.11 standard does not require authentication in IBSS
-	 * networks and most implementations do not seem to use it.
-	 * However, try to reply to authentication attempts if someone
-	 * has actually implemented this.
-	 */
-	if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
-		ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
-				    sdata->u.ibss.bssid, NULL, 0, 0);
-}
-
 static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 				      const u8 *bssid, const int beacon_int,
 				      struct ieee80211_channel *chan,
@@ -276,7 +251,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 				  cbss->tsf);
 }
 
-static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
+static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
+						  bool auth)
 	__acquires(RCU)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -290,22 +266,34 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
 		    addr, sdata->name);
 #endif
 
-	sta_info_move_state(sta, IEEE80211_STA_AUTH);
-	sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-	sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
+	sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+	sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+	/* authorize the station only if the network is not RSN protected. If
+	 * not wait for the userspace to authorize it */
+	if (!sta->sdata->u.ibss.control_port)
+		sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
 	rate_control_rate_init(sta);
 
 	/* If it fails, maybe we raced another insertion? */
 	if (sta_info_insert_rcu(sta))
 		return sta_info_get(sdata, addr);
+	if (auth) {
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+		printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM"
+		       "(auth_transaction=1)\n", sdata->vif.addr,
+		       sdata->u.ibss.bssid, addr);
+#endif
+		ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
+				    addr, sdata->u.ibss.bssid, NULL, 0, 0);
+	}
 	return sta;
 }
 
 static struct sta_info *
 ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 		       const u8 *bssid, const u8 *addr,
-		       u32 supp_rates)
+		       u32 supp_rates, bool auth)
 	__acquires(RCU)
 {
 	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
@@ -347,7 +335,42 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 	sta->sta.supp_rates[band] = supp_rates |
 			ieee80211_mandatory_rates(local, band);
 
-	return ieee80211_ibss_finish_sta(sta);
+	return ieee80211_ibss_finish_sta(sta, auth);
+}
+
+static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
+					struct ieee80211_mgmt *mgmt,
+					size_t len)
+{
+	u16 auth_alg, auth_transaction;
+
+	lockdep_assert_held(&sdata->u.ibss.mtx);
+
+	if (len < 24 + 6)
+		return;
+
+	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
+	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
+
+	if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
+		return;
+#ifdef CONFIG_MAC80211_IBSS_DEBUG
+	printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM."
+	       "(auth_transaction=%d)\n",
+	       sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
+#endif
+	sta_info_destroy_addr(sdata, mgmt->sa);
+	ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
+	rcu_read_unlock();
+
+	/*
+	 * IEEE 802.11 standard does not require authentication in IBSS
+	 * networks and most implementations do not seem to use it.
+	 * However, try to reply to authentication attempts if someone
+	 * has actually implemented this.
+	 */
+	ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
+			    mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0);
 }
 
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -412,7 +435,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 			} else {
 				rcu_read_unlock();
 				sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
-						mgmt->sa, supp_rates);
+						mgmt->sa, supp_rates, true);
 			}
 		}
 
@@ -540,7 +563,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 		ieee80211_sta_join_ibss(sdata, bss);
 		supp_rates = ieee80211_sta_get_rates(local, elems, band);
 		ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
-				       supp_rates);
+				       supp_rates, true);
 		rcu_read_unlock();
 	}
 
@@ -643,8 +666,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
 	       "IBSS networks with same SSID (merge)\n", sdata->name);
 
 	ieee80211_request_internal_scan(sdata,
-			ifibss->ssid, ifibss->ssid_len,
-			ifibss->fixed_channel ? ifibss->channel : NULL);
+			ifibss->ssid, ifibss->ssid_len, NULL);
 }
 
 static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -855,9 +877,6 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 	size_t baselen;
 	struct ieee802_11_elems elems;
 
-	if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
-		return; /* ignore ProbeResp to foreign address */
-
 	baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
 	if (baselen > len)
 		return;
@@ -945,7 +964,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
 		list_del(&sta->list);
 		spin_unlock_bh(&ifibss->incomplete_lock);
 
-		ieee80211_ibss_finish_sta(sta);
+		ieee80211_ibss_finish_sta(sta, true);
 		rcu_read_unlock();
 		spin_lock_bh(&ifibss->incomplete_lock);
 	}
@@ -1059,6 +1078,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 		sdata->u.ibss.fixed_bssid = false;
 
 	sdata->u.ibss.privacy = params->privacy;
+	sdata->u.ibss.control_port = params->control_port;
 	sdata->u.ibss.basic_rates = params->basic_rates;
 	memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
 	       sizeof(params->mcast_rate));
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 2f0642d..74594f0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -280,10 +280,6 @@ struct mesh_preq_queue {
 
 enum ieee80211_work_type {
 	IEEE80211_WORK_ABORT,
-	IEEE80211_WORK_DIRECT_PROBE,
-	IEEE80211_WORK_AUTH,
-	IEEE80211_WORK_ASSOC_BEACON_WAIT,
-	IEEE80211_WORK_ASSOC,
 	IEEE80211_WORK_REMAIN_ON_CHANNEL,
 	IEEE80211_WORK_OFFCHANNEL_TX,
 };
@@ -316,36 +312,10 @@ struct ieee80211_work {
 	unsigned long timeout;
 	enum ieee80211_work_type type;
 
-	u8 filter_ta[ETH_ALEN];
-
 	bool started;
 
 	union {
 		struct {
-			int tries;
-			u16 algorithm, transaction;
-			u8 ssid[IEEE80211_MAX_SSID_LEN];
-			u8 ssid_len;
-			u8 key[WLAN_KEY_LEN_WEP104];
-			u8 key_len, key_idx;
-			bool privacy;
-			bool synced;
-		} probe_auth;
-		struct {
-			struct cfg80211_bss *bss;
-			const u8 *supp_rates;
-			const u8 *ht_information_ie;
-			enum ieee80211_smps_mode smps;
-			int tries;
-			u16 capability;
-			u8 prev_bssid[ETH_ALEN];
-			u8 ssid[IEEE80211_MAX_SSID_LEN];
-			u8 ssid_len;
-			u8 supp_rates_len;
-			bool wmm_used, use_11n, uapsd_used;
-			bool synced;
-		} assoc;
-		struct {
 			u32 duration;
 		} remain;
 		struct {
@@ -355,9 +325,8 @@ struct ieee80211_work {
 		} offchan_tx;
 	};
 
-	int ie_len;
-	/* must be last */
-	u8 ie[0];
+	size_t data_len;
+	u8 data[];
 };
 
 /* flags used in struct ieee80211_if_managed.flags */
@@ -373,6 +342,43 @@ enum ieee80211_sta_flags {
 	IEEE80211_STA_RESET_SIGNAL_AVE	= BIT(9),
 };
 
+struct ieee80211_mgd_auth_data {
+	struct cfg80211_bss *bss;
+	unsigned long timeout;
+	int tries;
+	u16 algorithm, expected_transaction;
+
+	u8 key[WLAN_KEY_LEN_WEP104];
+	u8 key_len, key_idx;
+	bool synced;
+	bool done;
+
+	size_t ie_len;
+	u8 ie[];
+};
+
+struct ieee80211_mgd_assoc_data {
+	struct cfg80211_bss *bss;
+	const u8 *supp_rates;
+	const u8 *ht_information_ie;
+
+	unsigned long timeout;
+	int tries;
+
+	u16 capability;
+	u8 prev_bssid[ETH_ALEN];
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 ssid_len;
+	u8 supp_rates_len;
+	bool wmm_used, uapsd_used;
+	bool have_beacon;
+	bool sent_assoc;
+	bool synced;
+
+	size_t ie_len;
+	u8 ie[];
+};
+
 struct ieee80211_if_managed {
 	struct timer_list timer;
 	struct timer_list conn_mon_timer;
@@ -389,6 +395,8 @@ struct ieee80211_if_managed {
 
 	struct mutex mtx;
 	struct cfg80211_bss *associated;
+	struct ieee80211_mgd_auth_data *auth_data;
+	struct ieee80211_mgd_assoc_data *assoc_data;
 
 	u8 bssid[ETH_ALEN];
 
@@ -470,6 +478,8 @@ struct ieee80211_if_ibss {
 	bool fixed_channel;
 	bool privacy;
 
+	bool control_port;
+
 	u8 bssid[ETH_ALEN];
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len, ie_len;
@@ -646,6 +656,7 @@ struct ieee80211_sub_if_data {
 
 	/* bitmap of allowed (non-MCS) rate indexes for rate control */
 	u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
+	u8  rc_rateidx_mcs_mask[IEEE80211_NUM_BANDS][IEEE80211_HT_MCS_MASK_LEN];
 
 	union {
 		struct ieee80211_if_ap ap;
@@ -769,7 +780,6 @@ struct ieee80211_local {
 	struct list_head work_list;
 	struct timer_list work_timer;
 	struct work_struct work_work;
-	struct sk_buff_head work_skb_queue;
 
 	/*
 	 * private workqueue to mac80211. mac80211 makes this accessible
@@ -1396,7 +1406,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 			 u16 transaction, u16 auth_alg,
 			 u8 *extra, size_t extra_len, const u8 *bssid,
-			 const u8 *key, u8 key_len, u8 key_idx);
+			 const u8 *da, const u8 *key, u8 key_len, u8 key_idx);
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     const u8 *ie, size_t ie_len,
 			     enum ieee80211_band band, u32 rate_mask,
@@ -1436,8 +1446,6 @@ void ieee80211_work_init(struct ieee80211_local *local);
 void ieee80211_add_work(struct ieee80211_work *wk);
 void free_work(struct ieee80211_work *wk);
 void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata);
-ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-					   struct sk_buff *skb);
 int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
 				   struct ieee80211_channel *chan,
 				   enum nl80211_channel_type channel_type,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 01a21c2..daa50ea 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -318,9 +318,9 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
 			goto err_del_interface;
 		}
 
-		sta_info_move_state(sta, IEEE80211_STA_AUTH);
-		sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-		sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
+		sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+		sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+		sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
 		res = sta_info_insert(sta);
 		if (res) {
@@ -1181,6 +1181,13 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 		sband = local->hw.wiphy->bands[i];
 		sdata->rc_rateidx_mask[i] =
 			sband ? (1 << sband->n_bitrates) - 1 : 0;
+		if (sband)
+			memcpy(sdata->rc_rateidx_mcs_mask[i],
+			       sband->ht_cap.mcs.rx_mask,
+			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
+		else
+			memset(sdata->rc_rateidx_mcs_mask[i], 0,
+			       sizeof(sdata->rc_rateidx_mcs_mask[i]));
 	}
 
 	/* setup type-dependent data */
@@ -1303,7 +1310,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
 
 		/* do not count disabled managed interfaces */
 		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-		    !sdata->u.mgd.associated) {
+		    !sdata->u.mgd.associated &&
+		    !sdata->u.mgd.auth_data &&
+		    !sdata->u.mgd.assoc_data) {
 			sdata->vif.bss_conf.idle = true;
 			continue;
 		}
@@ -1323,7 +1332,8 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
 		wk->sdata->vif.bss_conf.idle = false;
 	}
 
-	if (local->scan_sdata) {
+	if (local->scan_sdata &&
+	    !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) {
 		scanning = true;
 		local->scan_sdata->vif.bss_conf.idle = false;
 	}
@@ -1332,6 +1342,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
 		hw_roc = true;
 
 	list_for_each_entry(sdata, &local->interfaces, list) {
+		if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+		    sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+			continue;
 		if (sdata->old_idle == sdata->vif.bss_conf.idle)
 			continue;
 		if (!ieee80211_sdata_running(sdata))
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 87a8974..e8616b3 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -54,14 +54,6 @@ static void assert_key_lock(struct ieee80211_local *local)
 	lockdep_assert_held(&local->key_mtx);
 }
 
-static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
-{
-	if (key->sta)
-		return &key->sta->sta;
-
-	return NULL;
-}
-
 static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
 {
 	/*
@@ -95,7 +87,7 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
 static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 {
 	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_sta *sta;
+	struct sta_info *sta;
 	int ret;
 
 	might_sleep();
@@ -105,7 +97,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
 	assert_key_lock(key->local);
 
-	sta = get_sta_for_key(key);
+	sta = key->sta;
 
 	/*
 	 * If this is a per-STA GTK, check if it
@@ -115,6 +107,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 	    !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
 		goto out_unsupported;
 
+	if (sta && !sta->uploaded)
+		goto out_unsupported;
+
 	sdata = key->sdata;
 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
 		/*
@@ -123,12 +118,10 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 		 */
 		if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
 			goto out_unsupported;
-		sdata = container_of(sdata->bss,
-				     struct ieee80211_sub_if_data,
-				     u.ap);
 	}
 
-	ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
+	ret = drv_set_key(key->local, SET_KEY, sdata,
+			  sta ? &sta->sta : NULL, &key->conf);
 
 	if (!ret) {
 		key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
@@ -147,7 +140,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 	if (ret != -ENOSPC && ret != -EOPNOTSUPP)
 		wiphy_err(key->local->hw.wiphy,
 			  "failed to set key (%d, %pM) to hardware (%d)\n",
-			  key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+			  key->conf.keyidx,
+			  sta ? sta->sta.addr : bcast_addr, ret);
 
  out_unsupported:
 	switch (key->conf.cipher) {
@@ -166,7 +160,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 {
 	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_sta *sta;
+	struct sta_info *sta;
 	int ret;
 
 	might_sleep();
@@ -179,7 +173,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 	if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
 		return;
 
-	sta = get_sta_for_key(key);
+	sta = key->sta;
 	sdata = key->sdata;
 
 	if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
@@ -187,18 +181,14 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 	      (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
 		increment_tailroom_need_count(sdata);
 
-	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-		sdata = container_of(sdata->bss,
-				     struct ieee80211_sub_if_data,
-				     u.ap);
-
 	ret = drv_set_key(key->local, DISABLE_KEY, sdata,
-			  sta, &key->conf);
+			  sta ? &sta->sta : NULL, &key->conf);
 
 	if (ret)
 		wiphy_err(key->local->hw.wiphy,
 			  "failed to remove key (%d, %pM) from hardware (%d)\n",
-			  key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+			  key->conf.keyidx,
+			  sta ? sta->sta.addr : bcast_addr, ret);
 
 	key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
 }
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b142bd4..2306d75 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -155,7 +155,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 		power = chan->max_power;
 	else
 		power = local->power_constr_level ?
-			(chan->max_power - local->power_constr_level) :
+			min(chan->max_power,
+				(chan->max_reg_power  - local->power_constr_level)) :
 			chan->max_power;
 
 	if (local->user_power_level >= 0)
@@ -198,15 +199,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 		return;
 
 	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		/*
-		 * While not associated, claim a BSSID of all-zeroes
-		 * so that drivers don't do any weird things with the
-		 * BSSID at that time.
-		 */
-		if (sdata->vif.bss_conf.assoc)
-			sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
-		else
-			sdata->vif.bss_conf.bssid = zero;
+		sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
 	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 		sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
 	else if (sdata->vif.type == NL80211_IFTYPE_AP)
@@ -534,6 +527,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	int priv_size, i;
 	struct wiphy *wiphy;
 
+	if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove)))
+		return NULL;
+
 	/* Ensure 32-byte alignment of our private data and hw private data.
 	 * We use the wiphy priv data for both our ieee80211_local and for
 	 * the driver's private data
@@ -701,6 +697,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	    )
 		return -EINVAL;
 
+	if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan)
+		return -EINVAL;
+
 	if (hw->max_report_rates == 0)
 		hw->max_report_rates = hw->max_rates;
 
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 54df1b2..c27dec9 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -575,7 +575,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 			ifmsh->mshstats.dropped_frames_ttl++;
 	}
 
-	if (forward) {
+	if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
 		u32 preq_id;
 		u8 hopcount, flags;
 
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index edf167e..4f8caaf8 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -336,7 +336,7 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
 }
 
 
-static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst,
+static struct mesh_path *mpath_lookup(struct mesh_table *tbl, u8 *dst,
 					  struct ieee80211_sub_if_data *sdata)
 {
 	struct mesh_path *mpath;
@@ -371,12 +371,12 @@ static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst,
  */
 struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
 {
-	return path_lookup(rcu_dereference(mesh_paths), dst, sdata);
+	return mpath_lookup(rcu_dereference(mesh_paths), dst, sdata);
 }
 
 struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
 {
-	return path_lookup(rcu_dereference(mpp_paths), dst, sdata);
+	return mpath_lookup(rcu_dereference(mpp_paths), dst, sdata);
 }
 
 
@@ -413,12 +413,6 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
 	return NULL;
 }
 
-static void mesh_gate_node_reclaim(struct rcu_head *rp)
-{
-	struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
-	kfree(node);
-}
-
 /**
  * mesh_path_add_gate - add the given mpath to a mesh gate to our path table
  * @mpath: gate path to add to table
@@ -479,7 +473,7 @@ static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath)
 		if (gate->mpath == mpath) {
 			spin_lock_bh(&tbl->gates_lock);
 			hlist_del_rcu(&gate->list);
-			call_rcu(&gate->rcu, mesh_gate_node_reclaim);
+			kfree_rcu(gate, rcu);
 			spin_unlock_bh(&tbl->gates_lock);
 			mpath->sdata->u.mesh.num_gates--;
 			mpath->is_gate = false;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index a172517..8806e5e 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -96,9 +96,9 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
 	if (!sta)
 		return NULL;
 
-	sta_info_move_state(sta, IEEE80211_STA_AUTH);
-	sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-	sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
+	sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+	sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
+	sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
 
 	set_sta_flag(sta, WLAN_STA_WME);
 
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 295be92..52133da 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -30,6 +30,12 @@
 #include "rate.h"
 #include "led.h"
 
+#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
+#define IEEE80211_AUTH_MAX_TRIES 3
+#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
+#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
+#define IEEE80211_ASSOC_MAX_TRIES 3
+
 static int max_nullfunc_tries = 2;
 module_param(max_nullfunc_tries, int, 0644);
 MODULE_PARM_DESC(max_nullfunc_tries,
@@ -97,6 +103,15 @@ enum rx_mgmt_action {
 
 	/* caller must call cfg80211_send_disassoc() */
 	RX_MGMT_CFG80211_DISASSOC,
+
+	/* caller must call cfg80211_send_rx_auth() */
+	RX_MGMT_CFG80211_RX_AUTH,
+
+	/* caller must call cfg80211_send_rx_assoc() */
+	RX_MGMT_CFG80211_RX_ASSOC,
+
+	/* caller must call cfg80211_send_assoc_timeout() */
+	RX_MGMT_CFG80211_ASSOC_TIMEOUT,
 };
 
 /* utils */
@@ -115,8 +130,7 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
  * has happened -- the work that runs from this timer will
  * do that.
  */
-static void run_again(struct ieee80211_if_managed *ifmgd,
-			     unsigned long timeout)
+static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout)
 {
 	ASSERT_MGD_MTX(ifmgd);
 
@@ -127,7 +141,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd,
 
 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
 {
-	if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
+	if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
 		return;
 
 	mod_timer(&sdata->u.mgd.bcn_mon_timer,
@@ -284,6 +298,319 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
 
 /* frame sending functions */
 
+static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
+				      struct ieee80211_supported_band *sband,
+				      u32 *rates)
+{
+	int i, j, count;
+	*rates = 0;
+	count = 0;
+	for (i = 0; i < supp_rates_len; i++) {
+		int rate = (supp_rates[i] & 0x7F) * 5;
+
+		for (j = 0; j < sband->n_bitrates; j++)
+			if (sband->bitrates[j].bitrate == rate) {
+				*rates |= BIT(j);
+				count++;
+				break;
+			}
+	}
+
+	return count;
+}
+
+static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
+				struct sk_buff *skb, const u8 *ht_info_ie,
+				struct ieee80211_supported_band *sband,
+				struct ieee80211_channel *channel,
+				enum ieee80211_smps_mode smps)
+{
+	struct ieee80211_ht_info *ht_info;
+	u8 *pos;
+	u32 flags = channel->flags;
+	u16 cap;
+	struct ieee80211_sta_ht_cap ht_cap;
+
+	BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
+
+	if (!sband->ht_cap.ht_supported)
+		return;
+
+	if (!ht_info_ie)
+		return;
+
+	if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
+		return;
+
+	memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
+	ieee80211_apply_htcap_overrides(sdata, &ht_cap);
+
+	ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
+
+	/* determine capability flags */
+	cap = ht_cap.cap;
+
+	switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+		if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
+			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+			cap &= ~IEEE80211_HT_CAP_SGI_40;
+		}
+		break;
+	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+		if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
+			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+			cap &= ~IEEE80211_HT_CAP_SGI_40;
+		}
+		break;
+	}
+
+	/* set SM PS mode properly */
+	cap &= ~IEEE80211_HT_CAP_SM_PS;
+	switch (smps) {
+	case IEEE80211_SMPS_AUTOMATIC:
+	case IEEE80211_SMPS_NUM_MODES:
+		WARN_ON(1);
+	case IEEE80211_SMPS_OFF:
+		cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
+			IEEE80211_HT_CAP_SM_PS_SHIFT;
+		break;
+	case IEEE80211_SMPS_STATIC:
+		cap |= WLAN_HT_CAP_SM_PS_STATIC <<
+			IEEE80211_HT_CAP_SM_PS_SHIFT;
+		break;
+	case IEEE80211_SMPS_DYNAMIC:
+		cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
+			IEEE80211_HT_CAP_SM_PS_SHIFT;
+		break;
+	}
+
+	/* reserve and fill IE */
+	pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
+	ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
+}
+
+static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
+	struct sk_buff *skb;
+	struct ieee80211_mgmt *mgmt;
+	u8 *pos, qos_info;
+	size_t offset = 0, noffset;
+	int i, count, rates_len, supp_rates_len;
+	u16 capab;
+	struct ieee80211_supported_band *sband;
+	u32 rates = 0;
+	struct ieee80211_bss *bss = (void *)assoc_data->bss->priv;
+
+	lockdep_assert_held(&ifmgd->mtx);
+
+	sband = local->hw.wiphy->bands[local->oper_channel->band];
+
+	if (assoc_data->supp_rates_len) {
+		/*
+		 * Get all rates supported by the device and the AP as
+		 * some APs don't like getting a superset of their rates
+		 * in the association request (e.g. D-Link DAP 1353 in
+		 * b-only mode)...
+		 */
+		rates_len = ieee80211_compatible_rates(assoc_data->supp_rates,
+						       assoc_data->supp_rates_len,
+						       sband, &rates);
+	} else {
+		/*
+		 * In case AP not provide any supported rates information
+		 * before association, we send information element(s) with
+		 * all rates that we support.
+		 */
+		rates = ~0;
+		rates_len = sband->n_bitrates;
+	}
+
+	skb = alloc_skb(local->hw.extra_tx_headroom +
+			sizeof(*mgmt) + /* bit too much but doesn't matter */
+			2 + assoc_data->ssid_len + /* SSID */
+			4 + rates_len + /* (extended) rates */
+			4 + /* power capability */
+			2 + 2 * sband->n_channels + /* supported channels */
+			2 + sizeof(struct ieee80211_ht_cap) + /* HT */
+			assoc_data->ie_len + /* extra IEs */
+			9, /* WMM */
+			GFP_KERNEL);
+	if (!skb)
+		return;
+
+	skb_reserve(skb, local->hw.extra_tx_headroom);
+
+	capab = WLAN_CAPABILITY_ESS;
+
+	if (sband->band == IEEE80211_BAND_2GHZ) {
+		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
+			capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
+		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
+			capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+	}
+
+	if (assoc_data->capability & WLAN_CAPABILITY_PRIVACY)
+		capab |= WLAN_CAPABILITY_PRIVACY;
+
+	if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
+	    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
+		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
+
+	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
+	memset(mgmt, 0, 24);
+	memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN);
+	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+	memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);
+
+	if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
+		skb_put(skb, 10);
+		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+						  IEEE80211_STYPE_REASSOC_REQ);
+		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
+		mgmt->u.reassoc_req.listen_interval =
+				cpu_to_le16(local->hw.conf.listen_interval);
+		memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
+		       ETH_ALEN);
+	} else {
+		skb_put(skb, 4);
+		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+						  IEEE80211_STYPE_ASSOC_REQ);
+		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
+		mgmt->u.assoc_req.listen_interval =
+				cpu_to_le16(local->hw.conf.listen_interval);
+	}
+
+	/* SSID */
+	pos = skb_put(skb, 2 + assoc_data->ssid_len);
+	*pos++ = WLAN_EID_SSID;
+	*pos++ = assoc_data->ssid_len;
+	memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
+
+	/* add all rates which were marked to be used above */
+	supp_rates_len = rates_len;
+	if (supp_rates_len > 8)
+		supp_rates_len = 8;
+
+	pos = skb_put(skb, supp_rates_len + 2);
+	*pos++ = WLAN_EID_SUPP_RATES;
+	*pos++ = supp_rates_len;
+
+	count = 0;
+	for (i = 0; i < sband->n_bitrates; i++) {
+		if (BIT(i) & rates) {
+			int rate = sband->bitrates[i].bitrate;
+			*pos++ = (u8) (rate / 5);
+			if (++count == 8)
+				break;
+		}
+	}
+
+	if (rates_len > count) {
+		pos = skb_put(skb, rates_len - count + 2);
+		*pos++ = WLAN_EID_EXT_SUPP_RATES;
+		*pos++ = rates_len - count;
+
+		for (i++; i < sband->n_bitrates; i++) {
+			if (BIT(i) & rates) {
+				int rate = sband->bitrates[i].bitrate;
+				*pos++ = (u8) (rate / 5);
+			}
+		}
+	}
+
+	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
+		/* 1. power capabilities */
+		pos = skb_put(skb, 4);
+		*pos++ = WLAN_EID_PWR_CAPABILITY;
+		*pos++ = 2;
+		*pos++ = 0; /* min tx power */
+		*pos++ = local->oper_channel->max_power; /* max tx power */
+
+		/* 2. supported channels */
+		/* TODO: get this in reg domain format */
+		pos = skb_put(skb, 2 * sband->n_channels + 2);
+		*pos++ = WLAN_EID_SUPPORTED_CHANNELS;
+		*pos++ = 2 * sband->n_channels;
+		for (i = 0; i < sband->n_channels; i++) {
+			*pos++ = ieee80211_frequency_to_channel(
+					sband->channels[i].center_freq);
+			*pos++ = 1; /* one channel in the subband*/
+		}
+	}
+
+	/* if present, add any custom IEs that go before HT */
+	if (assoc_data->ie_len && assoc_data->ie) {
+		static const u8 before_ht[] = {
+			WLAN_EID_SSID,
+			WLAN_EID_SUPP_RATES,
+			WLAN_EID_EXT_SUPP_RATES,
+			WLAN_EID_PWR_CAPABILITY,
+			WLAN_EID_SUPPORTED_CHANNELS,
+			WLAN_EID_RSN,
+			WLAN_EID_QOS_CAPA,
+			WLAN_EID_RRM_ENABLED_CAPABILITIES,
+			WLAN_EID_MOBILITY_DOMAIN,
+			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
+		};
+		noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
+					     before_ht, ARRAY_SIZE(before_ht),
+					     offset);
+		pos = skb_put(skb, noffset - offset);
+		memcpy(pos, assoc_data->ie + offset, noffset - offset);
+		offset = noffset;
+	}
+
+	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N) &&
+	    bss->wmm_used && local->hw.queues >= 4)
+		ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_information_ie,
+				    sband, local->oper_channel, ifmgd->ap_smps);
+
+	/* if present, add any custom non-vendor IEs that go after HT */
+	if (assoc_data->ie_len && assoc_data->ie) {
+		noffset = ieee80211_ie_split_vendor(assoc_data->ie,
+						    assoc_data->ie_len,
+						    offset);
+		pos = skb_put(skb, noffset - offset);
+		memcpy(pos, assoc_data->ie + offset, noffset - offset);
+		offset = noffset;
+	}
+
+	if (assoc_data->wmm_used && local->hw.queues >= 4) {
+		if (assoc_data->uapsd_used) {
+			qos_info = local->uapsd_queues;
+			qos_info |= (local->uapsd_max_sp_len <<
+				     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
+		} else {
+			qos_info = 0;
+		}
+
+		pos = skb_put(skb, 9);
+		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
+		*pos++ = 7; /* len */
+		*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
+		*pos++ = 0x50;
+		*pos++ = 0xf2;
+		*pos++ = 2; /* WME */
+		*pos++ = 0; /* WME info */
+		*pos++ = 1; /* WME ver */
+		*pos++ = qos_info;
+	}
+
+	/* add any remaining custom (i.e. vendor specific here) IEs */
+	if (assoc_data->ie_len && assoc_data->ie) {
+		noffset = assoc_data->ie_len;
+		pos = skb_put(skb, noffset - offset);
+		memcpy(pos, assoc_data->ie + offset, noffset - offset);
+	}
+
+	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+	ieee80211_tx_skb(sdata, skb);
+}
+
 static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
 					   const u8 *bssid, u16 stype, u16 reason,
 					   void *cookie, bool send_frame)
@@ -547,7 +874,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
 	if (pwr_constr_elem_len != 1)
 		return;
 
-	if ((*pwr_constr_elem <= conf->channel->max_power) &&
+	if ((*pwr_constr_elem <= conf->channel->max_reg_power) &&
 	    (*pwr_constr_elem != sdata->local->power_constr_level)) {
 		sdata->local->power_constr_level = *pwr_constr_elem;
 		ieee80211_hw_config(sdata->local, 0);
@@ -1043,7 +1370,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 	bss_info_changed |= BSS_CHANGED_BSSID;
 
 	/* Tell the driver to monitor connection quality (if supported) */
-	if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) &&
+	if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
 	    bss_conf->cqm_rssi_thold)
 		bss_info_changed |= BSS_CHANGED_CQM;
 
@@ -1423,6 +1750,135 @@ void ieee80211_connection_loss(struct ieee80211_vif *vif)
 EXPORT_SYMBOL(ieee80211_connection_loss);
 
 
+static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
+					bool assoc)
+{
+	struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
+
+	lockdep_assert_held(&sdata->u.mgd.mtx);
+
+	if (auth_data->synced)
+		drv_finish_tx_sync(sdata->local, sdata,
+				   auth_data->bss->bssid,
+				   IEEE80211_TX_SYNC_AUTH);
+
+	if (!assoc) {
+		sta_info_destroy_addr(sdata, auth_data->bss->bssid);
+
+		memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
+		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
+	}
+
+	cfg80211_put_bss(auth_data->bss);
+	kfree(auth_data);
+	sdata->u.mgd.auth_data = NULL;
+}
+
+static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_mgmt *mgmt, size_t len)
+{
+	struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
+	u8 *pos;
+	struct ieee802_11_elems elems;
+
+	pos = mgmt->u.auth.variable;
+	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+	if (!elems.challenge)
+		return;
+	auth_data->expected_transaction = 4;
+	ieee80211_send_auth(sdata, 3, auth_data->algorithm,
+			    elems.challenge - 2, elems.challenge_len + 2,
+			    auth_data->bss->bssid, auth_data->bss->bssid,
+			    auth_data->key, auth_data->key_len,
+			    auth_data->key_idx);
+}
+
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
+		       struct ieee80211_mgmt *mgmt, size_t len)
+{
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	u8 bssid[ETH_ALEN];
+	u16 auth_alg, auth_transaction, status_code;
+	struct sta_info *sta;
+
+	lockdep_assert_held(&ifmgd->mtx);
+
+	if (len < 24 + 6)
+		return RX_MGMT_NONE;
+
+	if (!ifmgd->auth_data || ifmgd->auth_data->done)
+		return RX_MGMT_NONE;
+
+	memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
+
+	if (memcmp(bssid, mgmt->bssid, ETH_ALEN))
+		return RX_MGMT_NONE;
+
+	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
+	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
+	status_code = le16_to_cpu(mgmt->u.auth.status_code);
+
+	if (auth_alg != ifmgd->auth_data->algorithm ||
+	    auth_transaction != ifmgd->auth_data->expected_transaction)
+		return RX_MGMT_NONE;
+
+	if (status_code != WLAN_STATUS_SUCCESS) {
+		printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
+		       sdata->name, mgmt->sa, status_code);
+		goto out;
+	}
+
+	switch (ifmgd->auth_data->algorithm) {
+	case WLAN_AUTH_OPEN:
+	case WLAN_AUTH_LEAP:
+	case WLAN_AUTH_FT:
+		break;
+	case WLAN_AUTH_SHARED_KEY:
+		if (ifmgd->auth_data->expected_transaction != 4) {
+			ieee80211_auth_challenge(sdata, mgmt, len);
+			/* need another frame */
+			return RX_MGMT_NONE;
+		}
+		break;
+	default:
+		WARN_ONCE(1, "invalid auth alg %d",
+			  ifmgd->auth_data->algorithm);
+		return RX_MGMT_NONE;
+	}
+
+	printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
+ out:
+	if (ifmgd->auth_data->synced)
+		drv_finish_tx_sync(sdata->local, sdata, bssid,
+				   IEEE80211_TX_SYNC_AUTH);
+	ifmgd->auth_data->synced = false;
+	ifmgd->auth_data->done = true;
+	ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
+	run_again(ifmgd, ifmgd->auth_data->timeout);
+
+	/* move station state to auth */
+	mutex_lock(&sdata->local->sta_mtx);
+	sta = sta_info_get(sdata, bssid);
+	if (!sta) {
+		WARN_ONCE(1, "%s: STA %pM not found", sdata->name, bssid);
+		goto out_err;
+	}
+	if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
+		printk(KERN_DEBUG "%s: failed moving %pM to auth\n",
+		       sdata->name, bssid);
+		goto out_err;
+	}
+	mutex_unlock(&sdata->local->sta_mtx);
+
+	return RX_MGMT_CFG80211_RX_AUTH;
+ out_err:
+	mutex_unlock(&sdata->local->sta_mtx);
+	/* ignore frame -- wait for timeout */
+	return RX_MGMT_NONE;
+}
+
+
 static enum rx_mgmt_action __must_check
 ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
 			 struct ieee80211_mgmt *mgmt, size_t len)
@@ -1431,10 +1887,14 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
 	const u8 *bssid = NULL;
 	u16 reason_code;
 
+	lockdep_assert_held(&ifmgd->mtx);
+
 	if (len < 24 + 2)
 		return RX_MGMT_NONE;
 
-	ASSERT_MGD_MTX(ifmgd);
+	if (!ifmgd->associated ||
+	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
+		return RX_MGMT_NONE;
 
 	bssid = ifmgd->associated->bssid;
 
@@ -1459,15 +1919,13 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	u16 reason_code;
 
-	if (len < 24 + 2)
-		return RX_MGMT_NONE;
-
-	ASSERT_MGD_MTX(ifmgd);
+	lockdep_assert_held(&ifmgd->mtx);
 
-	if (WARN_ON(!ifmgd->associated))
+	if (len < 24 + 2)
 		return RX_MGMT_NONE;
 
-	if (WARN_ON(memcmp(ifmgd->associated->bssid, mgmt->sa, ETH_ALEN)))
+	if (!ifmgd->associated ||
+	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
 		return RX_MGMT_NONE;
 
 	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
@@ -1524,15 +1982,37 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
 	}
 }
 
-static bool ieee80211_assoc_success(struct ieee80211_work *wk,
+static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
+					 bool assoc)
+{
+	struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
+
+	lockdep_assert_held(&sdata->u.mgd.mtx);
+
+	if (assoc_data->synced)
+		drv_finish_tx_sync(sdata->local, sdata,
+				   assoc_data->bss->bssid,
+				   IEEE80211_TX_SYNC_ASSOC);
+
+	if (!assoc) {
+		sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
+
+		memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
+		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
+	}
+
+	kfree(assoc_data);
+	sdata->u.mgd.assoc_data = NULL;
+}
+
+static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
+				    struct cfg80211_bss *cbss,
 				    struct ieee80211_mgmt *mgmt, size_t len)
 {
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_supported_band *sband;
 	struct sta_info *sta;
-	struct cfg80211_bss *cbss = wk->assoc.bss;
 	u8 *pos;
 	u32 rates, basic_rates;
 	u16 capab_info, aid;
@@ -1581,20 +2061,15 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 	 * station info was already allocated and inserted before
 	 * the association and should be available to us
 	 */
-	sta = sta_info_get_rx(sdata, cbss->bssid);
+	sta = sta_info_get(sdata, cbss->bssid);
 	if (WARN_ON(!sta)) {
 		mutex_unlock(&sdata->local->sta_mtx);
 		return false;
 	}
 
-	sta_info_move_state(sta, IEEE80211_STA_AUTH);
-	sta_info_move_state(sta, IEEE80211_STA_ASSOC);
-	if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
-		sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
-
 	rates = 0;
 	basic_rates = 0;
-	sband = local->hw.wiphy->bands[wk->chan->band];
+	sband = local->hw.wiphy->bands[local->oper_channel->band];
 
 	ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
 			    &rates, &basic_rates, &have_higher_than_11mbit,
@@ -1615,11 +2090,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 		basic_rates = BIT(min_rate_index);
 	}
 
-	sta->sta.supp_rates[wk->chan->band] = rates;
+	sta->sta.supp_rates[local->oper_channel->band] = rates;
 	sdata->vif.bss_conf.basic_rates = basic_rates;
 
 	/* cf. IEEE 802.11 9.2.12 */
-	if (wk->chan->band == IEEE80211_BAND_2GHZ &&
+	if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
 	    have_higher_than_11mbit)
 		sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
 	else
@@ -1639,15 +2114,22 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 	if (elems.wmm_param)
 		set_sta_flag(sta, WLAN_STA_WME);
 
-	/* sta_info_reinsert will also unlock the mutex lock */
-	err = sta_info_reinsert(sta);
-	sta = NULL;
+	err = sta_info_move_state(sta, IEEE80211_STA_AUTH);
+	if (!err)
+		err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
+	if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
+		err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
 	if (err) {
-		printk(KERN_DEBUG "%s: failed to insert STA entry for"
-		       " the AP (error %d)\n", sdata->name, err);
+		printk(KERN_DEBUG
+		       "%s: failed to move station %pM to desired state\n",
+		       sdata->name, sta->sta.addr);
+		WARN_ON(__sta_info_destroy(sta));
+		mutex_unlock(&sdata->local->sta_mtx);
 		return false;
 	}
 
+	mutex_unlock(&sdata->local->sta_mtx);
+
 	/*
 	 * Always handle WMM once after association regardless
 	 * of the first value the AP uses. Setting -1 here has
@@ -1662,8 +2144,6 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 	else
 		ieee80211_set_wmm_default(sdata);
 
-	local->oper_channel = wk->chan;
-
 	if (elems.ht_info_elem && elems.wmm_param &&
 	    (sdata->local->hw.queues >= 4) &&
 	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
@@ -1694,7 +2174,82 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
 	return true;
 }
 
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+			     struct ieee80211_mgmt *mgmt, size_t len,
+			     struct cfg80211_bss **bss)
+{
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
+	u16 capab_info, status_code, aid;
+	struct ieee802_11_elems elems;
+	u8 *pos;
+	bool reassoc;
+
+	lockdep_assert_held(&ifmgd->mtx);
+
+	if (!assoc_data)
+		return RX_MGMT_NONE;
+	if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN))
+		return RX_MGMT_NONE;
+
+	/*
+	 * AssocResp and ReassocResp have identical structure, so process both
+	 * of them in this function.
+	 */
+
+	if (len < 24 + 6)
+		return RX_MGMT_NONE;
+
+	reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
+	capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
+	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
+	aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
+
+	printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
+	       "status=%d aid=%d)\n",
+	       sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
+	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
+
+	pos = mgmt->u.assoc_resp.variable;
+	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
+
+	if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
+	    elems.timeout_int && elems.timeout_int_len == 5 &&
+	    elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
+		u32 tu, ms;
+		tu = get_unaligned_le32(elems.timeout_int + 1);
+		ms = tu * 1024 / 1000;
+		printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
+		       "comeback duration %u TU (%u ms)\n",
+		       sdata->name, mgmt->sa, tu, ms);
+		assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
+		if (ms > IEEE80211_ASSOC_TIMEOUT)
+			run_again(ifmgd, assoc_data->timeout);
+		return RX_MGMT_NONE;
+	}
+
+	*bss = assoc_data->bss;
+
+	if (status_code != WLAN_STATUS_SUCCESS) {
+		printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
+		       sdata->name, mgmt->sa, status_code);
+		ieee80211_destroy_assoc_data(sdata, false);
+	} else {
+		printk(KERN_DEBUG "%s: associated\n", sdata->name);
+
+		ieee80211_destroy_assoc_data(sdata, true);
 
+		if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
+			/* oops -- internal error -- send timeout for now */
+			sta_info_destroy_addr(sdata, mgmt->bssid);
+			cfg80211_put_bss(*bss);
+			return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
+		}
+	}
+
+	return RX_MGMT_CFG80211_RX_ASSOC;
+}
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 				  struct ieee80211_mgmt *mgmt,
 				  size_t len,
@@ -1708,7 +2263,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_channel *channel;
 	bool need_ps = false;
 
-	if (sdata->u.mgd.associated) {
+	if (sdata->u.mgd.associated &&
+	    memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
+		   ETH_ALEN) == 0) {
 		bss = (void *)sdata->u.mgd.associated->priv;
 		/* not previously set so we may need to recalc */
 		need_ps = !bss->dtim_period;
@@ -1778,6 +2335,15 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 	if (ifmgd->associated &&
 	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
 		ieee80211_reset_ap_probe(sdata);
+
+	if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
+	    memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) {
+		/* got probe response, continue with auth */
+		printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
+		ifmgd->auth_data->tries = 0;
+		ifmgd->auth_data->timeout = jiffies;
+		run_again(ifmgd, ifmgd->auth_data->timeout);
+	}
 }
 
 /*
@@ -1817,7 +2383,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	u32 ncrc;
 	u8 *bssid;
 
-	ASSERT_MGD_MTX(ifmgd);
+	lockdep_assert_held(&ifmgd->mtx);
 
 	/* Process beacon from the current BSS */
 	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1827,21 +2393,25 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	if (rx_status->freq != local->hw.conf.channel->center_freq)
 		return;
 
-	/*
-	 * We might have received a number of frames, among them a
-	 * disassoc frame and a beacon...
-	 */
-	if (!ifmgd->associated)
-		return;
+	if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
+	    memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) {
+		ieee802_11_parse_elems(mgmt->u.beacon.variable,
+				       len - baselen, &elems);
 
-	bssid = ifmgd->associated->bssid;
+		ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
+				      false);
+		ifmgd->assoc_data->have_beacon = true;
+		ifmgd->assoc_data->sent_assoc = false;
+		/* continue assoc process */
+		ifmgd->assoc_data->timeout = jiffies;
+		run_again(ifmgd, ifmgd->assoc_data->timeout);
+		return;
+	}
 
-	/*
-	 * And in theory even frames from a different AP we were just
-	 * associated to a split-second ago!
-	 */
-	if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
+	if (!ifmgd->associated ||
+	    memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
 		return;
+	bssid = ifmgd->associated->bssid;
 
 	/* Track average RSSI from the Beacon frames of the current AP */
 	ifmgd->last_beacon_signal = rx_status->signal;
@@ -1882,7 +2452,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 
 	if (bss_conf->cqm_rssi_thold &&
 	    ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
-	    !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) {
+	    !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
 		int sig = ifmgd->ave_beacon_signal / 16;
 		int last_event = ifmgd->last_cqm_event_signal;
 		int thold = bss_conf->cqm_rssi_thold;
@@ -2025,6 +2595,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_rx_status *rx_status;
 	struct ieee80211_mgmt *mgmt;
+	struct cfg80211_bss *bss = NULL;
 	enum rx_mgmt_action rma = RX_MGMT_NONE;
 	u16 fc;
 
@@ -2034,92 +2605,59 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
 	mutex_lock(&ifmgd->mtx);
 
-	if (ifmgd->associated &&
-	    memcmp(ifmgd->associated->bssid, mgmt->bssid, ETH_ALEN) == 0) {
-		switch (fc & IEEE80211_FCTL_STYPE) {
-		case IEEE80211_STYPE_BEACON:
-			ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
-						 rx_status);
-			break;
-		case IEEE80211_STYPE_PROBE_RESP:
-			ieee80211_rx_mgmt_probe_resp(sdata, skb);
-			break;
-		case IEEE80211_STYPE_DEAUTH:
-			rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
-			break;
-		case IEEE80211_STYPE_DISASSOC:
-			rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
-			break;
-		case IEEE80211_STYPE_ACTION:
-			switch (mgmt->u.action.category) {
-			case WLAN_CATEGORY_SPECTRUM_MGMT:
-				ieee80211_sta_process_chanswitch(sdata,
-						&mgmt->u.action.u.chan_switch.sw_elem,
-						(void *)ifmgd->associated->priv,
-						rx_status->mactime);
-				break;
-			}
-		}
-		mutex_unlock(&ifmgd->mtx);
-
-		switch (rma) {
-		case RX_MGMT_NONE:
-			/* no action */
-			break;
-		case RX_MGMT_CFG80211_DEAUTH:
-			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
-			break;
-		case RX_MGMT_CFG80211_DISASSOC:
-			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
+	switch (fc & IEEE80211_FCTL_STYPE) {
+	case IEEE80211_STYPE_BEACON:
+		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
+		break;
+	case IEEE80211_STYPE_PROBE_RESP:
+		ieee80211_rx_mgmt_probe_resp(sdata, skb);
+		break;
+	case IEEE80211_STYPE_AUTH:
+		rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
+		break;
+	case IEEE80211_STYPE_DEAUTH:
+		rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
+		break;
+	case IEEE80211_STYPE_DISASSOC:
+		rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
+		break;
+	case IEEE80211_STYPE_ASSOC_RESP:
+	case IEEE80211_STYPE_REASSOC_RESP:
+		rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss);
+		break;
+	case IEEE80211_STYPE_ACTION:
+		switch (mgmt->u.action.category) {
+		case WLAN_CATEGORY_SPECTRUM_MGMT:
+			ieee80211_sta_process_chanswitch(sdata,
+					&mgmt->u.action.u.chan_switch.sw_elem,
+					(void *)ifmgd->associated->priv,
+					rx_status->mactime);
 			break;
-		default:
-			WARN(1, "unexpected: %d", rma);
 		}
-		return;
 	}
-
 	mutex_unlock(&ifmgd->mtx);
 
-	if (skb->len >= 24 + 2 /* mgmt + deauth reason */ &&
-	    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) {
-		struct ieee80211_local *local = sdata->local;
-		struct ieee80211_work *wk;
-
-		mutex_lock(&local->mtx);
-		list_for_each_entry(wk, &local->work_list, list) {
-			if (wk->sdata != sdata)
-				continue;
-
-			if (wk->type != IEEE80211_WORK_ASSOC &&
-			    wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
-				continue;
-
-			if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
-				continue;
-			if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN))
-				continue;
-
-			/*
-			 * Printing the message only here means we can't
-			 * spuriously print it, but it also means that it
-			 * won't be printed when the frame comes in before
-			 * we even tried to associate or in similar cases.
-			 *
-			 * Ultimately, I suspect cfg80211 should print the
-			 * messages instead.
-			 */
-			printk(KERN_DEBUG
-			       "%s: deauthenticated from %pM (Reason: %u)\n",
-			       sdata->name, mgmt->bssid,
-			       le16_to_cpu(mgmt->u.deauth.reason_code));
-
-			list_del_rcu(&wk->list);
-			free_work(wk);
-			break;
-		}
-		mutex_unlock(&local->mtx);
-
+	switch (rma) {
+	case RX_MGMT_NONE:
+		/* no action */
+		break;
+	case RX_MGMT_CFG80211_DEAUTH:
 		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
+		break;
+	case RX_MGMT_CFG80211_DISASSOC:
+		cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
+		break;
+	case RX_MGMT_CFG80211_RX_AUTH:
+		cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
+		break;
+	case RX_MGMT_CFG80211_RX_ASSOC:
+		cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
+		break;
+	case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
+		cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
+		break;
+	default:
+		WARN(1, "unexpected: %d", rma);
 	}
 }
 
@@ -2164,14 +2702,160 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
 	mutex_lock(&ifmgd->mtx);
 }
 
+static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
+
+	lockdep_assert_held(&ifmgd->mtx);
+
+	if (WARN_ON_ONCE(!auth_data))
+		return -EINVAL;
+
+	if (!auth_data->synced) {
+		int ret = drv_tx_sync(local, sdata, auth_data->bss->bssid,
+				      IEEE80211_TX_SYNC_AUTH);
+		if (ret)
+			return ret;
+	}
+	auth_data->synced = true;
+
+	auth_data->tries++;
+
+	if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
+		printk(KERN_DEBUG "%s: authentication with %pM timed out\n",
+		       sdata->name, auth_data->bss->bssid);
+
+		/*
+		 * Most likely AP is not in the range so remove the
+		 * bss struct for that AP.
+		 */
+		cfg80211_unlink_bss(local->hw.wiphy, auth_data->bss);
+
+		return -ETIMEDOUT;
+	}
+
+	if (auth_data->bss->proberesp_ies) {
+		printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n",
+		       sdata->name, auth_data->bss->bssid, auth_data->tries,
+		       IEEE80211_AUTH_MAX_TRIES);
+
+		auth_data->expected_transaction = 2;
+		ieee80211_send_auth(sdata, 1, auth_data->algorithm,
+				    auth_data->ie, auth_data->ie_len,
+				    auth_data->bss->bssid,
+				    auth_data->bss->bssid, NULL, 0, 0);
+	} else {
+		const u8 *ssidie;
+
+		printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
+		       sdata->name, auth_data->bss->bssid, auth_data->tries,
+		       IEEE80211_AUTH_MAX_TRIES);
+
+		ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
+		if (!ssidie)
+			return -EINVAL;
+		/*
+		 * Direct probe is sent to broadcast address as some APs
+		 * will not answer to direct packet in unassociated state.
+		 */
+		ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
+					 NULL, 0, (u32) -1, true, false);
+	}
+
+	auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
+	run_again(ifmgd, auth_data->timeout);
+
+	return 0;
+}
+
+static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
+	struct ieee80211_local *local = sdata->local;
+
+	lockdep_assert_held(&sdata->u.mgd.mtx);
+
+	if (!assoc_data->synced) {
+		int ret = drv_tx_sync(local, sdata, assoc_data->bss->bssid,
+				      IEEE80211_TX_SYNC_ASSOC);
+		if (ret)
+			return ret;
+	}
+	assoc_data->synced = true;
+
+	assoc_data->tries++;
+	if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
+		printk(KERN_DEBUG "%s: association with %pM timed out\n",
+		       sdata->name, assoc_data->bss->bssid);
+
+		/*
+		 * Most likely AP is not in the range so remove the
+		 * bss struct for that AP.
+		 */
+		cfg80211_unlink_bss(local->hw.wiphy, assoc_data->bss);
+
+		return -ETIMEDOUT;
+	}
+
+	printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n",
+	       sdata->name, assoc_data->bss->bssid, assoc_data->tries,
+	       IEEE80211_ASSOC_MAX_TRIES);
+	ieee80211_send_assoc(sdata);
+
+	assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
+	run_again(&sdata->u.mgd, assoc_data->timeout);
+
+	return 0;
+}
+
 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-	/* then process the rest of the work */
 	mutex_lock(&ifmgd->mtx);
 
+	if (ifmgd->auth_data &&
+	    time_after(jiffies, ifmgd->auth_data->timeout)) {
+		if (ifmgd->auth_data->done) {
+			/*
+			 * ok ... we waited for assoc but userspace didn't,
+			 * so let's just kill the auth data
+			 */
+			ieee80211_destroy_auth_data(sdata, false);
+		} else if (ieee80211_probe_auth(sdata)) {
+			u8 bssid[ETH_ALEN];
+
+			memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
+
+			ieee80211_destroy_auth_data(sdata, false);
+
+			mutex_unlock(&ifmgd->mtx);
+			cfg80211_send_auth_timeout(sdata->dev, bssid);
+			mutex_lock(&ifmgd->mtx);
+		}
+	} else if (ifmgd->auth_data)
+		run_again(ifmgd, ifmgd->auth_data->timeout);
+
+	if (ifmgd->assoc_data &&
+	    time_after(jiffies, ifmgd->assoc_data->timeout)) {
+		if (!ifmgd->assoc_data->have_beacon ||
+		    ieee80211_do_assoc(sdata)) {
+			u8 bssid[ETH_ALEN];
+
+			memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
+
+			ieee80211_destroy_assoc_data(sdata, false);
+
+			mutex_unlock(&ifmgd->mtx);
+			cfg80211_send_assoc_timeout(sdata->dev, bssid);
+			mutex_lock(&ifmgd->mtx);
+		}
+	} else if (ifmgd->assoc_data)
+		run_again(ifmgd, ifmgd->assoc_data->timeout);
+
 	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
 			    IEEE80211_STA_CONNECTION_POLL) &&
 	    ifmgd->associated) {
@@ -2247,6 +2931,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 	}
 
 	mutex_unlock(&ifmgd->mtx);
+
+	mutex_lock(&local->mtx);
+	ieee80211_recalc_idle(local);
+	mutex_unlock(&local->mtx);
 }
 
 static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -2419,53 +3107,24 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
 }
 
 /* config hooks */
-static enum work_done_result
-ieee80211_probe_auth_done(struct ieee80211_work *wk,
-			  struct sk_buff *skb)
-{
-	struct ieee80211_local *local = wk->sdata->local;
-
-	if (!skb) {
-		cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
-		goto destroy;
-	}
-
-	if (wk->type == IEEE80211_WORK_AUTH) {
-		cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
-		goto destroy;
-	}
-
-	mutex_lock(&wk->sdata->u.mgd.mtx);
-	ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
-	mutex_unlock(&wk->sdata->u.mgd.mtx);
-
-	wk->type = IEEE80211_WORK_AUTH;
-	wk->probe_auth.tries = 0;
-	return WORK_DONE_REQUEUE;
- destroy:
-	if (wk->probe_auth.synced)
-		drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
-				   IEEE80211_TX_SYNC_AUTH);
-
-	return WORK_DONE_DESTROY;
-}
-
 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 		       struct cfg80211_auth_request *req)
 {
-	const u8 *ssid;
-	struct ieee80211_work *wk;
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_auth_data *auth_data;
+	struct sta_info *sta;
 	u16 auth_alg;
+	int err;
 
-	if (req->local_state_change)
-		return 0; /* no need to update mac80211 state */
+	/* prepare auth data structure */
 
 	switch (req->auth_type) {
 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
 		auth_alg = WLAN_AUTH_OPEN;
 		break;
 	case NL80211_AUTHTYPE_SHARED_KEY:
-		if (IS_ERR(sdata->local->wep_tx_tfm))
+		if (IS_ERR(local->wep_tx_tfm))
 			return -EOPNOTSUPP;
 		auth_alg = WLAN_AUTH_SHARED_KEY;
 		break;
@@ -2479,171 +3138,142 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 		return -EOPNOTSUPP;
 	}
 
-	wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
-	if (!wk)
+	auth_data = kzalloc(sizeof(*auth_data) + req->ie_len, GFP_KERNEL);
+	if (!auth_data)
 		return -ENOMEM;
 
-	memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
+	auth_data->bss = req->bss;
 
 	if (req->ie && req->ie_len) {
-		memcpy(wk->ie, req->ie, req->ie_len);
-		wk->ie_len = req->ie_len;
+		memcpy(auth_data->ie, req->ie, req->ie_len);
+		auth_data->ie_len = req->ie_len;
 	}
 
 	if (req->key && req->key_len) {
-		wk->probe_auth.key_len = req->key_len;
-		wk->probe_auth.key_idx = req->key_idx;
-		memcpy(wk->probe_auth.key, req->key, req->key_len);
+		auth_data->key_len = req->key_len;
+		auth_data->key_idx = req->key_idx;
+		memcpy(auth_data->key, req->key, req->key_len);
 	}
 
-	ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
-	memcpy(wk->probe_auth.ssid, ssid + 2, ssid[1]);
-	wk->probe_auth.ssid_len = ssid[1];
+	auth_data->algorithm = auth_alg;
 
-	wk->probe_auth.algorithm = auth_alg;
-	wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
-
-	/* if we already have a probe, don't probe again */
-	if (req->bss->proberesp_ies)
-		wk->type = IEEE80211_WORK_AUTH;
-	else
-		wk->type = IEEE80211_WORK_DIRECT_PROBE;
-	wk->chan = req->bss->channel;
-	wk->chan_type = NL80211_CHAN_NO_HT;
-	wk->sdata = sdata;
-	wk->done = ieee80211_probe_auth_done;
+	/* try to authenticate/probe */
 
-	ieee80211_add_work(wk);
-	return 0;
-}
-
-/* create and insert a dummy station entry */
-static int ieee80211_pre_assoc(struct ieee80211_sub_if_data *sdata,
-				u8 *bssid) {
-	struct sta_info *sta;
-	int err;
-
-	sta = sta_info_alloc(sdata, bssid, GFP_KERNEL);
-	if (!sta)
-		return -ENOMEM;
-
-	sta->dummy = true;
+	mutex_lock(&ifmgd->mtx);
 
-	err = sta_info_insert(sta);
-	sta = NULL;
-	if (err) {
-		printk(KERN_DEBUG "%s: failed to insert Dummy STA entry for"
-		       " the AP (error %d)\n", sdata->name, err);
-		return err;
+	if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
+	    ifmgd->assoc_data) {
+		err = -EBUSY;
+		goto err_free;
 	}
 
-	return 0;
-}
+	if (ifmgd->auth_data)
+		ieee80211_destroy_auth_data(sdata, false);
 
-static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
-						  struct sk_buff *skb)
-{
-	struct ieee80211_local *local = wk->sdata->local;
-	struct ieee80211_mgmt *mgmt;
-	struct ieee80211_rx_status *rx_status;
-	struct ieee802_11_elems elems;
-	struct cfg80211_bss *cbss = wk->assoc.bss;
-	u16 status;
+	/* prep auth_data so we don't go into idle on disassoc */
+	ifmgd->auth_data = auth_data;
 
-	if (!skb) {
-		sta_info_destroy_addr(wk->sdata, cbss->bssid);
-		cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
-		goto destroy;
-	}
+	if (ifmgd->associated)
+		ieee80211_set_disassoc(sdata, true, false);
 
-	if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
-		mutex_lock(&wk->sdata->u.mgd.mtx);
-		rx_status = (void *) skb->cb;
-		ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
-		ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
-				      &elems, true);
-		mutex_unlock(&wk->sdata->u.mgd.mtx);
+	printk(KERN_DEBUG "%s: authenticate with %pM\n",
+	       sdata->name, req->bss->bssid);
 
-		wk->type = IEEE80211_WORK_ASSOC;
-		/* not really done yet */
-		return WORK_DONE_REQUEUE;
-	}
+	mutex_lock(&local->mtx);
+	ieee80211_recalc_idle(sdata->local);
+	mutex_unlock(&local->mtx);
 
-	mgmt = (void *)skb->data;
-	status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
+	/* switch to the right channel */
+	local->oper_channel = req->bss->channel;
+	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
-	if (status == WLAN_STATUS_SUCCESS) {
-		if (wk->assoc.synced)
-			drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
-					   IEEE80211_TX_SYNC_ASSOC);
+	/* set BSSID */
+	memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
+	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
 
-		mutex_lock(&wk->sdata->u.mgd.mtx);
-		if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
-			mutex_unlock(&wk->sdata->u.mgd.mtx);
-			/* oops -- internal error -- send timeout for now */
-			sta_info_destroy_addr(wk->sdata, cbss->bssid);
-			cfg80211_send_assoc_timeout(wk->sdata->dev,
-						    wk->filter_ta);
-			return WORK_DONE_DESTROY;
-		}
+	/* add station entry */
+	sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
+	if (!sta) {
+		err = -ENOMEM;
+		goto err_clear;
+	}
 
-		mutex_unlock(&wk->sdata->u.mgd.mtx);
-	} else {
-		/* assoc failed - destroy the dummy station entry */
-		sta_info_destroy_addr(wk->sdata, cbss->bssid);
+	err = sta_info_insert(sta);
+	if (err) {
+		printk(KERN_DEBUG
+		       "%s: failed to insert STA entry for the AP %pM (error %d)\n",
+		       sdata->name, req->bss->bssid, err);
+		goto err_clear;
 	}
 
-	cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
- destroy:
-	if (wk->assoc.synced)
-		drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
-				   IEEE80211_TX_SYNC_ASSOC);
+	err = ieee80211_probe_auth(sdata);
+	if (err) {
+		if (auth_data->synced)
+			drv_finish_tx_sync(local, sdata, req->bss->bssid,
+					   IEEE80211_TX_SYNC_AUTH);
+		sta_info_destroy_addr(sdata, req->bss->bssid);
+		goto err_clear;
+	}
+
+	/* hold our own reference */
+	cfg80211_ref_bss(auth_data->bss);
+	err = 0;
+	goto out_unlock;
+
+ err_clear:
+	ifmgd->auth_data = NULL;
+ err_free:
+	kfree(auth_data);
+ out_unlock:
+	mutex_unlock(&ifmgd->mtx);
 
-	return WORK_DONE_DESTROY;
+	return err;
 }
 
 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 			struct cfg80211_assoc_request *req)
 {
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_bss *bss = (void *)req->bss->priv;
-	struct ieee80211_work *wk;
-	const u8 *ssid;
+	struct ieee80211_mgd_assoc_data *assoc_data;
+	struct sta_info *sta;
+	const u8 *ssidie;
 	int i, err;
 
+	ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
+	if (!ssidie)
+		return -EINVAL;
+
+	assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
+	if (!assoc_data)
+		return -ENOMEM;
+
 	mutex_lock(&ifmgd->mtx);
-	if (ifmgd->associated) {
-		if (!req->prev_bssid ||
-		    memcmp(req->prev_bssid, ifmgd->associated->bssid,
-			   ETH_ALEN)) {
-			/*
-			 * We are already associated and the request was not a
-			 * reassociation request from the current BSS, so
-			 * reject it.
-			 */
-			mutex_unlock(&ifmgd->mtx);
-			return -EALREADY;
-		}
 
-		/* Trying to reassociate - clear previous association state */
+	if (ifmgd->associated)
 		ieee80211_set_disassoc(sdata, true, false);
+
+	if (ifmgd->auth_data && !ifmgd->auth_data->done) {
+		err = -EBUSY;
+		goto err_free;
 	}
-	mutex_unlock(&ifmgd->mtx);
 
-	wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
-	if (!wk)
-		return -ENOMEM;
+	if (ifmgd->assoc_data) {
+		err = -EBUSY;
+		goto err_free;
+	}
 
-	/*
-	 * create a dummy station info entry in order
-	 * to start accepting incoming EAPOL packets from the station
-	 */
-	err = ieee80211_pre_assoc(sdata, req->bss->bssid);
-	if (err) {
-		kfree(wk);
-		return err;
+	if (ifmgd->auth_data) {
+		bool match;
+
+		/* keep sta info, bssid if matching */
+		match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0;
+		ieee80211_destroy_auth_data(sdata, match);
 	}
 
+	/* prepare assoc data */
+
 	ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
 	ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
 
@@ -2655,7 +3285,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
 			ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
-
 	if (req->flags & ASSOC_REQ_DISABLE_HT)
 		ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
 
@@ -2664,16 +3293,12 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	       sizeof(ifmgd->ht_capa_mask));
 
 	if (req->ie && req->ie_len) {
-		memcpy(wk->ie, req->ie, req->ie_len);
-		wk->ie_len = req->ie_len;
-	} else
-		wk->ie_len = 0;
-
-	wk->assoc.bss = req->bss;
+		memcpy(assoc_data->ie, req->ie, req->ie_len);
+		assoc_data->ie_len = req->ie_len;
+	}
 
-	memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
+	assoc_data->bss = req->bss;
 
-	/* new association always uses requested smps mode */
 	if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
 		if (ifmgd->powersave)
 			ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
@@ -2682,7 +3307,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	} else
 		ifmgd->ap_smps = ifmgd->req_smps;
 
-	wk->assoc.smps = ifmgd->ap_smps;
 	/*
 	 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
 	 * We still associate in non-HT mode (11a/b/g) if any one of these
@@ -2690,39 +3314,27 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	 * We can set this to true for non-11n hardware, that'll be checked
 	 * separately along with the peer capabilities.
 	 */
-	wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N);
-	wk->assoc.capability = req->bss->capability;
-	wk->assoc.wmm_used = bss->wmm_used;
-	wk->assoc.supp_rates = bss->supp_rates;
-	wk->assoc.supp_rates_len = bss->supp_rates_len;
-	wk->assoc.ht_information_ie =
+	assoc_data->capability = req->bss->capability;
+	assoc_data->wmm_used = bss->wmm_used;
+	assoc_data->supp_rates = bss->supp_rates;
+	assoc_data->supp_rates_len = bss->supp_rates_len;
+	assoc_data->ht_information_ie =
 		ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
 
 	if (bss->wmm_used && bss->uapsd_supported &&
 	    (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
-		wk->assoc.uapsd_used = true;
+		assoc_data->uapsd_used = true;
 		ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
 	} else {
-		wk->assoc.uapsd_used = false;
+		assoc_data->uapsd_used = false;
 		ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
 	}
 
-	ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
-	memcpy(wk->assoc.ssid, ssid + 2, ssid[1]);
-	wk->assoc.ssid_len = ssid[1];
+	memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
+	assoc_data->ssid_len = ssidie[1];
 
 	if (req->prev_bssid)
-		memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
-
-	wk->chan = req->bss->channel;
-	wk->chan_type = NL80211_CHAN_NO_HT;
-	wk->sdata = sdata;
-	wk->done = ieee80211_assoc_done;
-	if (!bss->dtim_period &&
-	    sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
-		wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
-	else
-		wk->type = IEEE80211_WORK_ASSOC;
+		memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN);
 
 	if (req->use_mfp) {
 		ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2740,89 +3352,100 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	sdata->control_port_protocol = req->crypto.control_port_ethertype;
 	sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
 
-	ieee80211_add_work(wk);
-	return 0;
+	/* kick off associate process */
+
+	ifmgd->assoc_data = assoc_data;
+
+	mutex_lock(&local->mtx);
+	ieee80211_recalc_idle(sdata->local);
+	mutex_unlock(&local->mtx);
+
+	/* switch to the right channel */
+	local->oper_channel = req->bss->channel;
+	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+
+	rcu_read_lock();
+	sta = sta_info_get(sdata, req->bss->bssid);
+	rcu_read_unlock();
+
+	if (!sta) {
+		/* set BSSID */
+		memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
+		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
+
+		sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
+		if (!sta) {
+			err = -ENOMEM;
+			goto err_clear;
+		}
+
+		sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
+
+		err = sta_info_insert(sta);
+		sta = NULL;
+		if (err) {
+			printk(KERN_DEBUG
+			       "%s: failed to insert STA entry for the AP (error %d)\n",
+			       sdata->name, err);
+			goto err_clear;
+		}
+	} else
+		WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN));
+
+	if (!bss->dtim_period &&
+	    sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
+		/*
+		 * Wait up to one beacon interval ...
+		 * should this be more if we miss one?
+		 */
+		printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
+		       sdata->name, ifmgd->bssid);
+		assoc_data->timeout = jiffies +
+				TU_TO_EXP_TIME(req->bss->beacon_interval);
+	} else {
+		assoc_data->have_beacon = true;
+		assoc_data->sent_assoc = false;
+		assoc_data->timeout = jiffies;
+	}
+	run_again(ifmgd, assoc_data->timeout);
+
+	err = 0;
+	goto out;
+ err_clear:
+	ifmgd->assoc_data = NULL;
+ err_free:
+	kfree(assoc_data);
+ out:
+	mutex_unlock(&ifmgd->mtx);
+
+	return err;
 }
 
 int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
 			 struct cfg80211_deauth_request *req,
 			 void *cookie)
 {
-	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	u8 bssid[ETH_ALEN];
 	bool assoc_bss = false;
 
 	mutex_lock(&ifmgd->mtx);
 
-	memcpy(bssid, req->bss->bssid, ETH_ALEN);
-	if (ifmgd->associated == req->bss) {
+	if (ifmgd->associated &&
+	    memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) {
 		ieee80211_set_disassoc(sdata, false, true);
-		mutex_unlock(&ifmgd->mtx);
 		assoc_bss = true;
-	} else {
-		bool not_auth_yet = false;
-		struct ieee80211_work *tmp, *wk = NULL;
-
+	} else if (ifmgd->auth_data) {
+		ieee80211_destroy_auth_data(sdata, false);
 		mutex_unlock(&ifmgd->mtx);
-
-		mutex_lock(&local->mtx);
-		list_for_each_entry(tmp, &local->work_list, list) {
-			if (tmp->sdata != sdata)
-				continue;
-
-			if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
-			    tmp->type != IEEE80211_WORK_AUTH &&
-			    tmp->type != IEEE80211_WORK_ASSOC &&
-			    tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
-				continue;
-
-			if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
-				continue;
-
-			not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
-			list_del_rcu(&tmp->list);
-			synchronize_rcu();
-			wk = tmp;
-			break;
-		}
-		mutex_unlock(&local->mtx);
-
-		if (wk && wk->type == IEEE80211_WORK_ASSOC) {
-			/* clean up dummy sta & TX sync */
-			sta_info_destroy_addr(wk->sdata, wk->filter_ta);
-			if (wk->assoc.synced)
-				drv_finish_tx_sync(local, wk->sdata,
-						   wk->filter_ta,
-						   IEEE80211_TX_SYNC_ASSOC);
-		} else if (wk && wk->type == IEEE80211_WORK_AUTH) {
-			if (wk->probe_auth.synced)
-				drv_finish_tx_sync(local, wk->sdata,
-						   wk->filter_ta,
-						   IEEE80211_TX_SYNC_AUTH);
-		}
-		kfree(wk);
-
-		/*
-		 * If somebody requests authentication and we haven't
-		 * sent out an auth frame yet there's no need to send
-		 * out a deauth frame either. If the state was PROBE,
-		 * then this is the case. If it's AUTH we have sent a
-		 * frame, and if it's IDLE we have completed the auth
-		 * process already.
-		 */
-		if (not_auth_yet) {
-			__cfg80211_auth_canceled(sdata->dev, bssid);
-			return 0;
-		}
+		return 0;
 	}
+	mutex_unlock(&ifmgd->mtx);
 
 	printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
-	       sdata->name, bssid, req->reason_code);
+	       sdata->name, req->bssid, req->reason_code);
 
-	ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
-				       req->reason_code, cookie,
-				       !req->local_state_change);
+	ieee80211_send_deauth_disassoc(sdata, req->bssid, IEEE80211_STYPE_DEAUTH,
+				       req->reason_code, cookie, true);
 	if (assoc_bss)
 		sta_info_flush(sdata->local, sdata);
 
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 596efaf..2b53a53 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -98,13 +98,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 	mutex_lock(&local->sta_mtx);
 	list_for_each_entry(sta, &local->sta_list, list) {
 		if (sta->uploaded) {
-			sdata = sta->sdata;
-			if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-				sdata = container_of(sdata->bss,
-					     struct ieee80211_sub_if_data,
-					     u.ap);
+			enum ieee80211_sta_state state;
 
-			drv_sta_remove(local, sdata, &sta->sta);
+			state = sta->sta_state;
+			for (; state > IEEE80211_STA_NOTEXIST; state--)
+				WARN_ON(drv_sta_state(local, sdata, sta,
+						      state, state - 1));
 		}
 
 		mesh_plink_quiesce(sta);
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 5a5a776..b4f7600 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -159,7 +159,6 @@ static struct rate_control_ref *rate_control_alloc(const char *name,
 	ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
 	if (!ref)
 		goto fail_ref;
-	kref_init(&ref->kref);
 	ref->local = local;
 	ref->ops = ieee80211_rate_control_ops_get(name);
 	if (!ref->ops)
@@ -184,11 +183,8 @@ fail_ref:
 	return NULL;
 }
 
-static void rate_control_release(struct kref *kref)
+static void rate_control_free(struct rate_control_ref *ctrl_ref)
 {
-	struct rate_control_ref *ctrl_ref;
-
-	ctrl_ref = container_of(kref, struct rate_control_ref, kref);
 	ctrl_ref->ops->free(ctrl_ref->priv);
 
 #ifdef CONFIG_MAC80211_DEBUGFS
@@ -293,8 +289,8 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
 }
 EXPORT_SYMBOL(rate_control_send_low);
 
-static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
-				int n_bitrates, u32 mask)
+static bool rate_idx_match_legacy_mask(struct ieee80211_tx_rate *rate,
+				       int n_bitrates, u32 mask)
 {
 	int j;
 
@@ -303,7 +299,7 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
 		if (mask & (1 << j)) {
 			/* Okay, found a suitable rate. Use it. */
 			rate->idx = j;
-			return;
+			return true;
 		}
 	}
 
@@ -312,6 +308,112 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
 		if (mask & (1 << j)) {
 			/* Okay, found a suitable rate. Use it. */
 			rate->idx = j;
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool rate_idx_match_mcs_mask(struct ieee80211_tx_rate *rate,
+				    u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
+{
+	int i, j;
+	int ridx, rbit;
+
+	ridx = rate->idx / 8;
+	rbit = rate->idx % 8;
+
+	/* sanity check */
+	if (ridx < 0 || ridx >= IEEE80211_HT_MCS_MASK_LEN)
+		return false;
+
+	/* See whether the selected rate or anything below it is allowed. */
+	for (i = ridx; i >= 0; i--) {
+		for (j = rbit; j >= 0; j--)
+			if (mcs_mask[i] & BIT(j)) {
+				rate->idx = i * 8 + j;
+				return true;
+			}
+		rbit = 7;
+	}
+
+	/* Try to find a higher rate that would be allowed */
+	ridx = (rate->idx + 1) / 8;
+	rbit = (rate->idx + 1) % 8;
+
+	for (i = ridx; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
+		for (j = rbit; j < 8; j++)
+			if (mcs_mask[i] & BIT(j)) {
+				rate->idx = i * 8 + j;
+				return true;
+			}
+		rbit = 0;
+	}
+	return false;
+}
+
+
+
+static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
+				struct ieee80211_tx_rate_control *txrc,
+				u32 mask,
+				u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN])
+{
+	struct ieee80211_tx_rate alt_rate;
+
+	/* handle HT rates */
+	if (rate->flags & IEEE80211_TX_RC_MCS) {
+		if (rate_idx_match_mcs_mask(rate, mcs_mask))
+			return;
+
+		/* also try the legacy rates. */
+		alt_rate.idx = 0;
+		/* keep protection flags */
+		alt_rate.flags = rate->flags &
+				 (IEEE80211_TX_RC_USE_RTS_CTS |
+				  IEEE80211_TX_RC_USE_CTS_PROTECT |
+				  IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+		alt_rate.count = rate->count;
+		if (rate_idx_match_legacy_mask(&alt_rate,
+					       txrc->sband->n_bitrates,
+					       mask)) {
+			*rate = alt_rate;
+			return;
+		}
+	} else {
+		struct sk_buff *skb = txrc->skb;
+		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+		__le16 fc;
+
+		/* handle legacy rates */
+		if (rate_idx_match_legacy_mask(rate, txrc->sband->n_bitrates,
+					       mask))
+			return;
+
+		/* if HT BSS, and we handle a data frame, also try HT rates */
+		if (txrc->bss_conf->channel_type == NL80211_CHAN_NO_HT)
+			return;
+
+		fc = hdr->frame_control;
+		if (!ieee80211_is_data(fc))
+			return;
+
+		alt_rate.idx = 0;
+		/* keep protection flags */
+		alt_rate.flags = rate->flags &
+				 (IEEE80211_TX_RC_USE_RTS_CTS |
+				  IEEE80211_TX_RC_USE_CTS_PROTECT |
+				  IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
+		alt_rate.count = rate->count;
+
+		alt_rate.flags |= IEEE80211_TX_RC_MCS;
+
+		if ((txrc->bss_conf->channel_type == NL80211_CHAN_HT40MINUS) ||
+		    (txrc->bss_conf->channel_type == NL80211_CHAN_HT40PLUS))
+			alt_rate.flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+
+		if (rate_idx_match_mcs_mask(&alt_rate, mcs_mask)) {
+			*rate = alt_rate;
 			return;
 		}
 	}
@@ -335,8 +437,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
 	int i;
 	u32 mask;
+	u8 mcs_mask[IEEE80211_HT_MCS_MASK_LEN];
 
-	if (sta) {
+	if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
 		ista = &sta->sta;
 		priv_sta = sta->rate_ctrl_priv;
 	}
@@ -344,7 +447,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
 		info->control.rates[i].idx = -1;
 		info->control.rates[i].flags = 0;
-		info->control.rates[i].count = 1;
+		info->control.rates[i].count = 0;
 	}
 
 	if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
@@ -358,10 +461,14 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 	 * the common case.
 	 */
 	mask = sdata->rc_rateidx_mask[info->band];
+	memcpy(mcs_mask, sdata->rc_rateidx_mcs_mask[info->band],
+	       sizeof(mcs_mask));
 	if (mask != (1 << txrc->sband->n_bitrates) - 1) {
 		if (sta) {
 			/* Filter out rates that the STA does not support */
 			mask &= sta->sta.supp_rates[info->band];
+			for (i = 0; i < sizeof(mcs_mask); i++)
+				mcs_mask[i] &= sta->sta.ht_cap.mcs.rx_mask[i];
 		}
 		/*
 		 * Make sure the rate index selected for each TX rate is
@@ -372,32 +479,18 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 			/* Skip invalid rates */
 			if (info->control.rates[i].idx < 0)
 				break;
-			/* Rate masking supports only legacy rates for now */
-			if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
-				continue;
-			rate_idx_match_mask(&info->control.rates[i],
-					    txrc->sband->n_bitrates, mask);
+			rate_idx_match_mask(&info->control.rates[i], txrc,
+					    mask, mcs_mask);
 		}
 	}
 
 	BUG_ON(info->control.rates[0].idx < 0);
 }
 
-struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
-{
-	kref_get(&ref->kref);
-	return ref;
-}
-
-void rate_control_put(struct rate_control_ref *ref)
-{
-	kref_put(&ref->kref, rate_control_release);
-}
-
 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
 				 const char *name)
 {
-	struct rate_control_ref *ref, *old;
+	struct rate_control_ref *ref;
 
 	ASSERT_RTNL();
 
@@ -417,12 +510,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
 		return -ENOENT;
 	}
 
-	old = local->rate_ctrl;
+	WARN_ON(local->rate_ctrl);
 	local->rate_ctrl = ref;
-	if (old) {
-		rate_control_put(old);
-		sta_info_flush(local, NULL);
-	}
 
 	wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n",
 		    ref->ops->name);
@@ -440,6 +529,6 @@ void rate_control_deinitialize(struct ieee80211_local *local)
 		return;
 
 	local->rate_ctrl = NULL;
-	rate_control_put(ref);
+	rate_control_free(ref);
 }
 
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 168427b..fbb1efd 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -14,7 +14,6 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/types.h>
-#include <linux/kref.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "sta_info.h"
@@ -23,14 +22,11 @@ struct rate_control_ref {
 	struct ieee80211_local *local;
 	struct rate_control_ops *ops;
 	void *priv;
-	struct kref kref;
 };
 
 void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 			   struct sta_info *sta,
 			   struct ieee80211_tx_rate_control *txrc);
-struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
-void rate_control_put(struct rate_control_ref *ref);
 
 static inline void rate_control_tx_status(struct ieee80211_local *local,
 					  struct ieee80211_supported_band *sband,
@@ -41,7 +37,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
 	struct ieee80211_sta *ista = &sta->sta;
 	void *priv_sta = sta->rate_ctrl_priv;
 
-	if (!ref)
+	if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
 		return;
 
 	ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
@@ -62,6 +58,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
 	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
 	ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
+	set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
 }
 
 static inline void rate_control_rate_update(struct ieee80211_local *local,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5a5e504..3ab85c0 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -859,7 +859,12 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
 		     rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
 		     rx->sdata->vif.type != NL80211_IFTYPE_WDS &&
 		     (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) {
-		if (rx->sta && rx->sta->dummy &&
+		/*
+		 * accept port control frames from the AP even when it's not
+		 * yet marked ASSOC to prevent a race where we don't set the
+		 * assoc bit quickly enough before it sends the first frame
+		 */
+		if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
 		    ieee80211_is_data_present(hdr->frame_control)) {
 			u16 ethertype;
 			u8 *payload;
@@ -1145,19 +1150,15 @@ static void ap_sta_ps_start(struct sta_info *sta)
 
 static void ap_sta_ps_end(struct sta_info *sta)
 {
-	struct ieee80211_sub_if_data *sdata = sta->sdata;
-
-	atomic_dec(&sdata->bss->num_sta_ps);
-
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 	printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
-	       sdata->name, sta->sta.addr, sta->sta.aid);
+	       sta->sdata->name, sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 
 	if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 		printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n",
-		       sdata->name, sta->sta.addr, sta->sta.aid);
+		       sta->sdata->name, sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 		return;
 	}
@@ -2180,9 +2181,6 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
 	if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
 	    ieee80211_is_beacon(mgmt->frame_control) &&
 	    !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
-		struct ieee80211_rx_status *status;
-
-		status = IEEE80211_SKB_RXCB(rx->skb);
 		cfg80211_report_obss_beacon(rx->local->hw.wiphy,
 					    rx->skb->data, rx->skb->len,
 					    status->freq, GFP_ATOMIC);
@@ -2486,14 +2484,9 @@ static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 {
 	struct ieee80211_sub_if_data *sdata = rx->sdata;
-	ieee80211_rx_result rxs;
 	struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
 	__le16 stype;
 
-	rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
-	if (rxs != RX_CONTINUE)
-		return rxs;
-
 	stype = mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
 
 	if (!ieee80211_vif_is_mesh(&sdata->vif) &&
@@ -2502,10 +2495,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 		return RX_DROP_MONITOR;
 
 	switch (stype) {
+	case cpu_to_le16(IEEE80211_STYPE_AUTH):
 	case cpu_to_le16(IEEE80211_STYPE_BEACON):
 	case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
 		/* process for all: mesh, mlme, ibss */
 		break;
+	case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+	case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
 	case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
 	case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
 		if (is_multicast_ether_addr(mgmt->da) &&
@@ -2517,7 +2513,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 			return RX_DROP_MONITOR;
 		break;
 	case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
-	case cpu_to_le16(IEEE80211_STYPE_AUTH):
 		/* process only for ibss */
 		if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
 			return RX_DROP_MONITOR;
@@ -2956,7 +2951,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 	if (ieee80211_is_data(fc)) {
 		prev_sta = NULL;
 
-		for_each_sta_info_rx(local, hdr->addr2, sta, tmp) {
+		for_each_sta_info(local, hdr->addr2, sta, tmp) {
 			if (!prev_sta) {
 				prev_sta = sta;
 				continue;
@@ -3000,7 +2995,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 			continue;
 		}
 
-		rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
+		rx.sta = sta_info_get_bss(prev, hdr->addr2);
 		rx.sdata = prev;
 		ieee80211_prepare_and_rx_handle(&rx, skb, false);
 
@@ -3008,7 +3003,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 	}
 
 	if (prev) {
-		rx.sta = sta_info_get_bss_rx(prev, hdr->addr2);
+		rx.sta = sta_info_get_bss(prev, hdr->addr2);
 		rx.sdata = prev;
 
 		if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index ff11f6b..4034ee6 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -100,25 +100,6 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
 	sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
 				    lockdep_is_held(&local->sta_mtx));
 	while (sta) {
-		if (sta->sdata == sdata && !sta->dummy &&
-		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
-			break;
-		sta = rcu_dereference_check(sta->hnext,
-					    lockdep_is_held(&local->sta_mtx));
-	}
-	return sta;
-}
-
-/* get a station info entry even if it is a dummy station*/
-struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
-			      const u8 *addr)
-{
-	struct ieee80211_local *local = sdata->local;
-	struct sta_info *sta;
-
-	sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
-				    lockdep_is_held(&local->sta_mtx));
-	while (sta) {
 		if (sta->sdata == sdata &&
 		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
 			break;
@@ -143,30 +124,6 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
 	while (sta) {
 		if ((sta->sdata == sdata ||
 		     (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
-		    !sta->dummy &&
-		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
-			break;
-		sta = rcu_dereference_check(sta->hnext,
-					    lockdep_is_held(&local->sta_mtx));
-	}
-	return sta;
-}
-
-/*
- * Get sta info either from the specified interface
- * or from one of its vlans (including dummy stations)
- */
-struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
-				  const u8 *addr)
-{
-	struct ieee80211_local *local = sdata->local;
-	struct sta_info *sta;
-
-	sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
-				    lockdep_is_held(&local->sta_mtx));
-	while (sta) {
-		if ((sta->sdata == sdata ||
-		     (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
 		    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
 			break;
 		sta = rcu_dereference_check(sta->hnext,
@@ -208,10 +165,8 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
  */
 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
 {
-	if (sta->rate_ctrl) {
+	if (sta->rate_ctrl)
 		rate_control_free_sta(sta);
-		rate_control_put(sta->rate_ctrl);
-	}
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 	wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr);
@@ -264,13 +219,11 @@ static int sta_prepare_rate_control(struct ieee80211_local *local,
 	if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
 		return 0;
 
-	sta->rate_ctrl = rate_control_get(local->rate_ctrl);
+	sta->rate_ctrl = local->rate_ctrl;
 	sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
 						     &sta->sta, gfp);
-	if (!sta->rate_ctrl_priv) {
-		rate_control_put(sta->rate_ctrl);
+	if (!sta->rate_ctrl_priv)
 		return -ENOMEM;
-	}
 
 	return 0;
 }
@@ -297,6 +250,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
 	sta->sdata = sdata;
 	sta->last_rx = jiffies;
 
+	sta->sta_state = IEEE80211_STA_NONE;
+
 	do_posix_clock_monotonic_gettime(&uptime);
 	sta->last_connected = uptime.tv_sec;
 	ewma_init(&sta->avg_signal, 1024, 8);
@@ -353,6 +308,43 @@ static int sta_info_insert_check(struct sta_info *sta)
 	return 0;
 }
 
+static int sta_info_insert_drv_state(struct ieee80211_local *local,
+				     struct ieee80211_sub_if_data *sdata,
+				     struct sta_info *sta)
+{
+	enum ieee80211_sta_state state;
+	int err = 0;
+
+	for (state = IEEE80211_STA_NOTEXIST; state < sta->sta_state; state++) {
+		err = drv_sta_state(local, sdata, sta, state, state + 1);
+		if (err)
+			break;
+	}
+
+	if (!err) {
+		/*
+		 * Drivers using legacy sta_add/sta_remove callbacks only
+		 * get uploaded set to true after sta_add is called.
+		 */
+		if (!local->ops->sta_add)
+			sta->uploaded = true;
+		return 0;
+	}
+
+	if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+		printk(KERN_DEBUG
+		       "%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway.\n",
+		       sdata->name, sta->sta.addr, state + 1, err);
+		err = 0;
+	}
+
+	/* unwind on error */
+	for (; state > IEEE80211_STA_NOTEXIST; state--)
+		WARN_ON(drv_sta_state(local, sdata, sta, state, state - 1));
+
+	return err;
+}
+
 /*
  * should be called with sta_mtx locked
  * this function replaces the mutex lock
@@ -362,70 +354,43 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
 {
 	struct ieee80211_local *local = sta->local;
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
-	struct sta_info *exist_sta;
-	bool dummy_reinsert = false;
+	struct station_info sinfo;
 	int err = 0;
 
 	lockdep_assert_held(&local->sta_mtx);
 
-	/*
-	 * check if STA exists already.
-	 * only accept a scenario of a second call to sta_info_insert_finish
-	 * with a dummy station entry that was inserted earlier
-	 * in that case - assume that the dummy station flag should
-	 * be removed.
-	 */
-	exist_sta = sta_info_get_bss_rx(sdata, sta->sta.addr);
-	if (exist_sta) {
-		if (exist_sta == sta && sta->dummy) {
-			dummy_reinsert = true;
-		} else {
-			err = -EEXIST;
-			goto out_err;
-		}
+	/* check if STA exists already */
+	if (sta_info_get_bss(sdata, sta->sta.addr)) {
+		err = -EEXIST;
+		goto out_err;
 	}
 
-	if (!sta->dummy || dummy_reinsert) {
-		/* notify driver */
-		err = drv_sta_add(local, sdata, &sta->sta);
-		if (err) {
-			if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
-				goto out_err;
-			printk(KERN_DEBUG "%s: failed to add IBSS STA %pM to "
-					  "driver (%d) - keeping it anyway.\n",
-			       sdata->name, sta->sta.addr, err);
-		} else
-			sta->uploaded = true;
-	}
+	/* notify driver */
+	err = sta_info_insert_drv_state(local, sdata, sta);
+	if (err)
+		goto out_err;
 
-	if (!dummy_reinsert) {
-		local->num_sta++;
-		local->sta_generation++;
-		smp_mb();
+	local->num_sta++;
+	local->sta_generation++;
+	smp_mb();
 
-		/* make the station visible */
-		sta_info_hash_add(local, sta);
+	/* make the station visible */
+	sta_info_hash_add(local, sta);
 
-		list_add(&sta->list, &local->sta_list);
-	} else {
-		sta->dummy = false;
-	}
+	list_add(&sta->list, &local->sta_list);
 
-	if (!sta->dummy) {
-		struct station_info sinfo;
+	set_sta_flag(sta, WLAN_STA_INSERTED);
 
-		ieee80211_sta_debugfs_add(sta);
-		rate_control_add_sta_debugfs(sta);
+	ieee80211_sta_debugfs_add(sta);
+	rate_control_add_sta_debugfs(sta);
 
-		memset(&sinfo, 0, sizeof(sinfo));
-		sinfo.filled = 0;
-		sinfo.generation = local->sta_generation;
-		cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
-	}
+	memset(&sinfo, 0, sizeof(sinfo));
+	sinfo.filled = 0;
+	sinfo.generation = local->sta_generation;
+	cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-	wiphy_debug(local->hw.wiphy, "Inserted %sSTA %pM\n",
-			sta->dummy ? "dummy " : "", sta->sta.addr);
+	wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
 	/* move reference to rcu-protected */
@@ -477,25 +442,6 @@ int sta_info_insert(struct sta_info *sta)
 	return err;
 }
 
-/* Caller must hold sta->local->sta_mtx */
-int sta_info_reinsert(struct sta_info *sta)
-{
-	struct ieee80211_local *local = sta->local;
-	int err = 0;
-
-	err = sta_info_insert_check(sta);
-	if (err) {
-		mutex_unlock(&local->sta_mtx);
-		return err;
-	}
-
-	might_sleep();
-
-	err = sta_info_insert_finish(sta);
-	rcu_read_unlock();
-	return err;
-}
-
 static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
 {
 	/*
@@ -711,7 +657,7 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
 	return have_buffered;
 }
 
-static int __must_check __sta_info_destroy(struct sta_info *sta)
+int __must_check __sta_info_destroy(struct sta_info *sta)
 {
 	struct ieee80211_local *local;
 	struct ieee80211_sub_if_data *sdata;
@@ -726,6 +672,8 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
 	local = sta->local;
 	sdata = sta->sdata;
 
+	lockdep_assert_held(&local->sta_mtx);
+
 	/*
 	 * Before removing the station from the driver and
 	 * rate control, it might still start new aggregation
@@ -750,33 +698,24 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
 
 	sta->dead = true;
 
-	if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
-	    test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
-		BUG_ON(!sdata->bss);
-
-		clear_sta_flag(sta, WLAN_STA_PS_STA);
-		clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-
-		atomic_dec(&sdata->bss->num_sta_ps);
-		sta_info_recalc_tim(sta);
-	}
-
 	local->num_sta--;
 	local->sta_generation++;
 
 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
 		RCU_INIT_POINTER(sdata->u.vlan.sta, NULL);
 
-	while (sta->sta_state > IEEE80211_STA_NONE)
-		sta_info_move_state(sta, sta->sta_state - 1);
+	while (sta->sta_state > IEEE80211_STA_NONE) {
+		ret = sta_info_move_state(sta, sta->sta_state - 1);
+		if (ret) {
+			WARN_ON_ONCE(1);
+			break;
+		}
+	}
 
 	if (sta->uploaded) {
-		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-			sdata = container_of(sdata->bss,
-					     struct ieee80211_sub_if_data,
-					     u.ap);
-		drv_sta_remove(local, sdata, &sta->sta);
-		sdata = sta->sdata;
+		ret = drv_sta_state(local, sdata, sta, IEEE80211_STA_NONE,
+				    IEEE80211_STA_NOTEXIST);
+		WARN_ON_ONCE(ret != 0);
 	}
 
 	/*
@@ -787,6 +726,15 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
 	 */
 	synchronize_rcu();
 
+	if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+		BUG_ON(!sdata->bss);
+
+		clear_sta_flag(sta, WLAN_STA_PS_STA);
+
+		atomic_dec(&sdata->bss->num_sta_ps);
+		sta_info_recalc_tim(sta);
+	}
+
 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
 		local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
 		__skb_queue_purge(&sta->ps_tx_buf[ac]);
@@ -815,35 +763,20 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
 	}
 #endif
 
-	/* There could be some memory leaks because of ampdu tx pending queue
-	 * not being freed before destroying the station info.
-	 *
-	 * Make sure that such queues are purged before freeing the station
-	 * info.
-	 * TODO: We have to somehow postpone the full destruction
-	 * until the aggregation stop completes. Refer
-	 * http://thread.gmane.org/gmane.linux.kernel.wireless.general/81936
+	/*
+	 * Destroy aggregation state here. It would be nice to wait for the
+	 * driver to finish aggregation stop and then clean up, but for now
+	 * drivers have to handle aggregation stop being requested, followed
+	 * directly by station destruction.
 	 */
-
-	mutex_lock(&sta->ampdu_mlme.mtx);
-
 	for (i = 0; i < STA_TID_NUM; i++) {
-		tid_tx = rcu_dereference_protected_tid_tx(sta, i);
+		tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
 		if (!tid_tx)
 			continue;
-		if (skb_queue_len(&tid_tx->pending)) {
-#ifdef CONFIG_MAC80211_HT_DEBUG
-			wiphy_debug(local->hw.wiphy, "TX A-MPDU  purging %d "
-				"packets for tid=%d\n",
-				skb_queue_len(&tid_tx->pending), i);
-#endif /* CONFIG_MAC80211_HT_DEBUG */
-			__skb_queue_purge(&tid_tx->pending);
-		}
-		kfree_rcu(tid_tx, rcu_head);
+		__skb_queue_purge(&tid_tx->pending);
+		kfree(tid_tx);
 	}
 
-	mutex_unlock(&sta->ampdu_mlme.mtx);
-
 	sta_info_free(local, sta);
 
 	return 0;
@@ -855,7 +788,7 @@ int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr)
 	int ret;
 
 	mutex_lock(&sdata->local->sta_mtx);
-	sta = sta_info_get_rx(sdata, addr);
+	sta = sta_info_get(sdata, addr);
 	ret = __sta_info_destroy(sta);
 	mutex_unlock(&sdata->local->sta_mtx);
 
@@ -869,7 +802,7 @@ int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
 	int ret;
 
 	mutex_lock(&sdata->local->sta_mtx);
-	sta = sta_info_get_bss_rx(sdata, addr);
+	sta = sta_info_get_bss(sdata, addr);
 	ret = __sta_info_destroy(sta);
 	mutex_unlock(&sdata->local->sta_mtx);
 
@@ -1009,9 +942,11 @@ EXPORT_SYMBOL(ieee80211_find_sta);
 static void clear_sta_ps_flags(void *_sta)
 {
 	struct sta_info *sta = _sta;
+	struct ieee80211_sub_if_data *sdata = sta->sdata;
 
 	clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
-	clear_sta_flag(sta, WLAN_STA_PS_STA);
+	if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA))
+		atomic_dec(&sdata->bss->num_sta_ps);
 }
 
 /* powersave support code */
@@ -1410,28 +1345,68 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
 }
 EXPORT_SYMBOL(ieee80211_sta_set_buffered);
 
-int sta_info_move_state_checked(struct sta_info *sta,
-				enum ieee80211_sta_state new_state)
+int sta_info_move_state(struct sta_info *sta,
+			enum ieee80211_sta_state new_state)
 {
 	might_sleep();
 
 	if (sta->sta_state == new_state)
 		return 0;
 
+	/* check allowed transitions first */
+
+	switch (new_state) {
+	case IEEE80211_STA_NONE:
+		if (sta->sta_state != IEEE80211_STA_AUTH)
+			return -EINVAL;
+		break;
+	case IEEE80211_STA_AUTH:
+		if (sta->sta_state != IEEE80211_STA_NONE &&
+		    sta->sta_state != IEEE80211_STA_ASSOC)
+			return -EINVAL;
+		break;
+	case IEEE80211_STA_ASSOC:
+		if (sta->sta_state != IEEE80211_STA_AUTH &&
+		    sta->sta_state != IEEE80211_STA_AUTHORIZED)
+			return -EINVAL;
+		break;
+	case IEEE80211_STA_AUTHORIZED:
+		if (sta->sta_state != IEEE80211_STA_ASSOC)
+			return -EINVAL;
+		break;
+	default:
+		WARN(1, "invalid state %d", new_state);
+		return -EINVAL;
+	}
+
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+	printk(KERN_DEBUG "%s: moving STA %pM to state %d\n",
+		sta->sdata->name, sta->sta.addr, new_state);
+#endif
+
+	/*
+	 * notify the driver before the actual changes so it can
+	 * fail the transition
+	 */
+	if (test_sta_flag(sta, WLAN_STA_INSERTED)) {
+		int err = drv_sta_state(sta->local, sta->sdata, sta,
+					sta->sta_state, new_state);
+		if (err)
+			return err;
+	}
+
+	/* reflect the change in all state variables */
+
 	switch (new_state) {
 	case IEEE80211_STA_NONE:
 		if (sta->sta_state == IEEE80211_STA_AUTH)
 			clear_bit(WLAN_STA_AUTH, &sta->_flags);
-		else
-			return -EINVAL;
 		break;
 	case IEEE80211_STA_AUTH:
 		if (sta->sta_state == IEEE80211_STA_NONE)
 			set_bit(WLAN_STA_AUTH, &sta->_flags);
 		else if (sta->sta_state == IEEE80211_STA_ASSOC)
 			clear_bit(WLAN_STA_ASSOC, &sta->_flags);
-		else
-			return -EINVAL;
 		break;
 	case IEEE80211_STA_ASSOC:
 		if (sta->sta_state == IEEE80211_STA_AUTH) {
@@ -1440,24 +1415,19 @@ int sta_info_move_state_checked(struct sta_info *sta,
 			if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
 				atomic_dec(&sta->sdata->u.ap.num_sta_authorized);
 			clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
-		} else
-			return -EINVAL;
+		}
 		break;
 	case IEEE80211_STA_AUTHORIZED:
 		if (sta->sta_state == IEEE80211_STA_ASSOC) {
 			if (sta->sdata->vif.type == NL80211_IFTYPE_AP)
 				atomic_inc(&sta->sdata->u.ap.num_sta_authorized);
 			set_bit(WLAN_STA_AUTHORIZED, &sta->_flags);
-		} else
-			return -EINVAL;
+		}
 		break;
 	default:
-		WARN(1, "invalid state %d", new_state);
-		return -EINVAL;
+		break;
 	}
 
-	printk(KERN_DEBUG "%s: moving STA %pM to state %d\n",
-		sta->sdata->name, sta->sta.addr, new_state);
 	sta->sta_state = new_state;
 
 	return 0;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f77f12..23a97c9 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,8 @@
  * @WLAN_STA_SP: Station is in a service period, so don't try to
  *	reply to other uAPSD trigger frames or PS-Poll.
  * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
+ * @WLAN_STA_INSERTED: This station is inserted into the hash table.
+ * @WLAN_STA_RATE_CONTROL: rate control was initialized for this station.
  */
 enum ieee80211_sta_info_flags {
 	WLAN_STA_AUTH,
@@ -71,14 +73,8 @@ enum ieee80211_sta_info_flags {
 	WLAN_STA_UAPSD,
 	WLAN_STA_SP,
 	WLAN_STA_4ADDR_EVENT,
-};
-
-enum ieee80211_sta_state {
-	/* NOTE: These need to be ordered correctly! */
-	IEEE80211_STA_NONE,
-	IEEE80211_STA_AUTH,
-	IEEE80211_STA_ASSOC,
-	IEEE80211_STA_AUTHORIZED,
+	WLAN_STA_INSERTED,
+	WLAN_STA_RATE_CONTROL,
 };
 
 #define STA_TID_NUM 16
@@ -271,8 +267,6 @@ struct sta_ampdu_mlme {
  * @dead: set to true when sta is unlinked
  * @uploaded: set to true when sta is uploaded to the driver
  * @lost_packets: number of consecutive lost packets
- * @dummy: indicate a dummy station created for receiving
- *	EAP frames before association
  * @sta: station information we share with the driver
  * @sta_state: duplicates information about station state (for debug)
  * @beacon_loss_count: number of times beacon loss has triggered
@@ -370,9 +364,6 @@ struct sta_info {
 	unsigned int lost_packets;
 	unsigned int beacon_loss_count;
 
-	/* should be right in front of sta to be in the same cache line */
-	bool dummy;
-
 	/* keep last! */
 	struct ieee80211_sta sta;
 };
@@ -427,13 +418,17 @@ static inline int test_and_set_sta_flag(struct sta_info *sta,
 	return test_and_set_bit(flag, &sta->_flags);
 }
 
-int sta_info_move_state_checked(struct sta_info *sta,
-				enum ieee80211_sta_state new_state);
+int sta_info_move_state(struct sta_info *sta,
+			enum ieee80211_sta_state new_state);
 
-static inline void sta_info_move_state(struct sta_info *sta,
-				       enum ieee80211_sta_state new_state)
+static inline void sta_info_pre_move_state(struct sta_info *sta,
+					   enum ieee80211_sta_state new_state)
 {
-	int ret = sta_info_move_state_checked(sta, new_state);
+	int ret;
+
+	WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED));
+
+	ret = sta_info_move_state(sta, new_state);
 	WARN_ON_ONCE(ret);
 }
 
@@ -470,15 +465,9 @@ rcu_dereference_protected_tid_tx(struct sta_info *sta, int tid)
 struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
 			      const u8 *addr);
 
-struct sta_info *sta_info_get_rx(struct ieee80211_sub_if_data *sdata,
-			      const u8 *addr);
-
 struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
 				  const u8 *addr);
 
-struct sta_info *sta_info_get_bss_rx(struct ieee80211_sub_if_data *sdata,
-				  const u8 *addr);
-
 static inline
 void for_each_sta_info_type_check(struct ieee80211_local *local,
 				  const u8 *addr,
@@ -487,23 +476,7 @@ void for_each_sta_info_type_check(struct ieee80211_local *local,
 {
 }
 
-#define for_each_sta_info(local, _addr, _sta, nxt) 			\
-	for (	/* initialise loop */					\
-		_sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
-		nxt = _sta ? rcu_dereference(_sta->hnext) : NULL;	\
-		/* typecheck */						\
-		for_each_sta_info_type_check(local, (_addr), _sta, nxt),\
-		/* continue condition */				\
-		_sta;							\
-		/* advance loop */					\
-		_sta = nxt,						\
-		nxt = _sta ? rcu_dereference(_sta->hnext) : NULL	\
-	     )								\
-	/* run code only if address matches and it's not a dummy sta */	\
-	if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0 &&		\
-		!_sta->dummy)
-
-#define for_each_sta_info_rx(local, _addr, _sta, nxt)			\
+#define for_each_sta_info(local, _addr, _sta, nxt)			\
 	for (	/* initialise loop */					\
 		_sta = rcu_dereference(local->sta_hash[STA_HASH(_addr)]),\
 		nxt = _sta ? rcu_dereference(_sta->hnext) : NULL;	\
@@ -542,8 +515,8 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta);
  */
 int sta_info_insert(struct sta_info *sta);
 int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU);
-int sta_info_reinsert(struct sta_info *sta);
 
+int __must_check __sta_info_destroy(struct sta_info *sta);
 int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata,
 			  const u8 *addr);
 int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 30c265c..d67f0b9 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -350,7 +350,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 	bool send_to_cooked;
 	bool acked;
 	struct ieee80211_bar *bar;
-	u16 tid;
 	int rtap_len;
 
 	for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -412,7 +411,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 		}
 
 		if (!acked && ieee80211_is_back_req(fc)) {
-			u16 control;
+			u16 tid, control;
 
 			/*
 			 * BAR failed, store the last SSN and retry sending
@@ -516,7 +515,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 
 		if (ieee80211_is_nullfunc(hdr->frame_control) ||
 		    ieee80211_is_qos_nullfunc(hdr->frame_control)) {
-			bool acked = info->flags & IEEE80211_TX_STAT_ACK;
+			acked = info->flags & IEEE80211_TX_STAT_ACK;
+
 			cfg80211_probe_status(skb->dev, hdr->addr1,
 					      cookie, acked, GFP_ATOMIC);
 		} else {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e05667c..1be0ca2 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -635,6 +635,9 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 		txrc.max_rate_idx = -1;
 	else
 		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
+	memcpy(txrc.rate_idx_mcs_mask,
+	       tx->sdata->rc_rateidx_mcs_mask[tx->channel->band],
+	       sizeof(txrc.rate_idx_mcs_mask));
 	txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
 		    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
 		    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
@@ -2431,6 +2434,8 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 		txrc.max_rate_idx = -1;
 	else
 		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
+	memcpy(txrc.rate_idx_mcs_mask, sdata->rc_rateidx_mcs_mask[band],
+	       sizeof(txrc.rate_idx_mcs_mask));
 	txrc.bss = true;
 	rate_control_get_rate(sdata, NULL, &txrc);
 
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9919892..264397a 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -862,8 +862,8 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 			 u16 transaction, u16 auth_alg,
-			 u8 *extra, size_t extra_len, const u8 *bssid,
-			 const u8 *key, u8 key_len, u8 key_idx)
+			 u8 *extra, size_t extra_len, const u8 *da,
+			 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct sk_buff *skb;
@@ -881,7 +881,7 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	memset(mgmt, 0, 24 + 6);
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 					  IEEE80211_STYPE_AUTH);
-	memcpy(mgmt->da, bssid, ETH_ALEN);
+	memcpy(mgmt->da, da, ETH_ALEN);
 	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
 	memcpy(mgmt->bssid, bssid, ETH_ALEN);
 	mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
@@ -1185,13 +1185,12 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 	mutex_lock(&local->sta_mtx);
 	list_for_each_entry(sta, &local->sta_list, list) {
 		if (sta->uploaded) {
-			sdata = sta->sdata;
-			if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-				sdata = container_of(sdata->bss,
-					     struct ieee80211_sub_if_data,
-					     u.ap);
+			enum ieee80211_sta_state state;
 
-			WARN_ON(drv_sta_add(local, sdata, &sta->sta));
+			for (state = IEEE80211_STA_NOTEXIST;
+			     state < sta->sta_state - 1; state++)
+				WARN_ON(drv_sta_state(local, sta->sdata, sta,
+						      state, state + 1));
 		}
 	}
 	mutex_unlock(&local->sta_mtx);
@@ -1272,6 +1271,21 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 	ieee80211_recalc_ps(local, -1);
 
 	/*
+	 * The sta might be in psm against the ap (e.g. because
+	 * this was the state before a hw restart), so we
+	 * explicitly send a null packet in order to make sure
+	 * it'll sync against the ap (and get out of psm).
+	 */
+	if (!(local->hw.conf.flags & IEEE80211_CONF_PS)) {
+		list_for_each_entry(sdata, &local->interfaces, list) {
+			if (sdata->vif.type != NL80211_IFTYPE_STATION)
+				continue;
+
+			ieee80211_send_nullfunc(local, sdata, 0);
+		}
+	}
+
+	/*
 	 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
 	 * sessions can be established after a resume.
 	 *
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index c6dd01a..c6e230e 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -27,16 +27,9 @@
 #include "rate.h"
 #include "driver-ops.h"
 
-#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
-#define IEEE80211_AUTH_MAX_TRIES 3
-#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
-#define IEEE80211_ASSOC_MAX_TRIES 3
-
 enum work_action {
-	WORK_ACT_MISMATCH,
 	WORK_ACT_NONE,
 	WORK_ACT_TIMEOUT,
-	WORK_ACT_DONE,
 };
 
 
@@ -71,464 +64,6 @@ void free_work(struct ieee80211_work *wk)
 	kfree_rcu(wk, rcu_head);
 }
 
-static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
-				      struct ieee80211_supported_band *sband,
-				      u32 *rates)
-{
-	int i, j, count;
-	*rates = 0;
-	count = 0;
-	for (i = 0; i < supp_rates_len; i++) {
-		int rate = (supp_rates[i] & 0x7F) * 5;
-
-		for (j = 0; j < sband->n_bitrates; j++)
-			if (sband->bitrates[j].bitrate == rate) {
-				*rates |= BIT(j);
-				count++;
-				break;
-			}
-	}
-
-	return count;
-}
-
-/* frame sending functions */
-
-static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
-				struct sk_buff *skb, const u8 *ht_info_ie,
-				struct ieee80211_supported_band *sband,
-				struct ieee80211_channel *channel,
-				enum ieee80211_smps_mode smps)
-{
-	struct ieee80211_ht_info *ht_info;
-	u8 *pos;
-	u32 flags = channel->flags;
-	u16 cap;
-	struct ieee80211_sta_ht_cap ht_cap;
-
-	BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
-
-	if (!sband->ht_cap.ht_supported)
-		return;
-
-	if (!ht_info_ie)
-		return;
-
-	if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
-		return;
-
-	memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
-	ieee80211_apply_htcap_overrides(sdata, &ht_cap);
-
-	ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
-
-	/* determine capability flags */
-	cap = ht_cap.cap;
-
-	switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
-	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-		if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
-			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-			cap &= ~IEEE80211_HT_CAP_SGI_40;
-		}
-		break;
-	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-		if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
-			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-			cap &= ~IEEE80211_HT_CAP_SGI_40;
-		}
-		break;
-	}
-
-	/* set SM PS mode properly */
-	cap &= ~IEEE80211_HT_CAP_SM_PS;
-	switch (smps) {
-	case IEEE80211_SMPS_AUTOMATIC:
-	case IEEE80211_SMPS_NUM_MODES:
-		WARN_ON(1);
-	case IEEE80211_SMPS_OFF:
-		cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
-			IEEE80211_HT_CAP_SM_PS_SHIFT;
-		break;
-	case IEEE80211_SMPS_STATIC:
-		cap |= WLAN_HT_CAP_SM_PS_STATIC <<
-			IEEE80211_HT_CAP_SM_PS_SHIFT;
-		break;
-	case IEEE80211_SMPS_DYNAMIC:
-		cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
-			IEEE80211_HT_CAP_SM_PS_SHIFT;
-		break;
-	}
-
-	/* reserve and fill IE */
-	pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
-	ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
-}
-
-static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
-				 struct ieee80211_work *wk)
-{
-	struct ieee80211_local *local = sdata->local;
-	struct sk_buff *skb;
-	struct ieee80211_mgmt *mgmt;
-	u8 *pos, qos_info;
-	size_t offset = 0, noffset;
-	int i, count, rates_len, supp_rates_len;
-	u16 capab;
-	struct ieee80211_supported_band *sband;
-	u32 rates = 0;
-
-	sband = local->hw.wiphy->bands[wk->chan->band];
-
-	if (wk->assoc.supp_rates_len) {
-		/*
-		 * Get all rates supported by the device and the AP as
-		 * some APs don't like getting a superset of their rates
-		 * in the association request (e.g. D-Link DAP 1353 in
-		 * b-only mode)...
-		 */
-		rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
-						       wk->assoc.supp_rates_len,
-						       sband, &rates);
-	} else {
-		/*
-		 * In case AP not provide any supported rates information
-		 * before association, we send information element(s) with
-		 * all rates that we support.
-		 */
-		rates = ~0;
-		rates_len = sband->n_bitrates;
-	}
-
-	skb = alloc_skb(local->hw.extra_tx_headroom +
-			sizeof(*mgmt) + /* bit too much but doesn't matter */
-			2 + wk->assoc.ssid_len + /* SSID */
-			4 + rates_len + /* (extended) rates */
-			4 + /* power capability */
-			2 + 2 * sband->n_channels + /* supported channels */
-			2 + sizeof(struct ieee80211_ht_cap) + /* HT */
-			wk->ie_len + /* extra IEs */
-			9, /* WMM */
-			GFP_KERNEL);
-	if (!skb)
-		return;
-
-	skb_reserve(skb, local->hw.extra_tx_headroom);
-
-	capab = WLAN_CAPABILITY_ESS;
-
-	if (sband->band == IEEE80211_BAND_2GHZ) {
-		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
-			capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
-		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
-			capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
-	}
-
-	if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
-		capab |= WLAN_CAPABILITY_PRIVACY;
-
-	if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
-	    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
-		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
-
-	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
-	memset(mgmt, 0, 24);
-	memcpy(mgmt->da, wk->filter_ta, ETH_ALEN);
-	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
-	memcpy(mgmt->bssid, wk->filter_ta, ETH_ALEN);
-
-	if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
-		skb_put(skb, 10);
-		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-						  IEEE80211_STYPE_REASSOC_REQ);
-		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
-		mgmt->u.reassoc_req.listen_interval =
-				cpu_to_le16(local->hw.conf.listen_interval);
-		memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
-		       ETH_ALEN);
-	} else {
-		skb_put(skb, 4);
-		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-						  IEEE80211_STYPE_ASSOC_REQ);
-		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
-		mgmt->u.assoc_req.listen_interval =
-				cpu_to_le16(local->hw.conf.listen_interval);
-	}
-
-	/* SSID */
-	pos = skb_put(skb, 2 + wk->assoc.ssid_len);
-	*pos++ = WLAN_EID_SSID;
-	*pos++ = wk->assoc.ssid_len;
-	memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
-
-	/* add all rates which were marked to be used above */
-	supp_rates_len = rates_len;
-	if (supp_rates_len > 8)
-		supp_rates_len = 8;
-
-	pos = skb_put(skb, supp_rates_len + 2);
-	*pos++ = WLAN_EID_SUPP_RATES;
-	*pos++ = supp_rates_len;
-
-	count = 0;
-	for (i = 0; i < sband->n_bitrates; i++) {
-		if (BIT(i) & rates) {
-			int rate = sband->bitrates[i].bitrate;
-			*pos++ = (u8) (rate / 5);
-			if (++count == 8)
-				break;
-		}
-	}
-
-	if (rates_len > count) {
-		pos = skb_put(skb, rates_len - count + 2);
-		*pos++ = WLAN_EID_EXT_SUPP_RATES;
-		*pos++ = rates_len - count;
-
-		for (i++; i < sband->n_bitrates; i++) {
-			if (BIT(i) & rates) {
-				int rate = sband->bitrates[i].bitrate;
-				*pos++ = (u8) (rate / 5);
-			}
-		}
-	}
-
-	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
-		/* 1. power capabilities */
-		pos = skb_put(skb, 4);
-		*pos++ = WLAN_EID_PWR_CAPABILITY;
-		*pos++ = 2;
-		*pos++ = 0; /* min tx power */
-		*pos++ = wk->chan->max_power; /* max tx power */
-
-		/* 2. supported channels */
-		/* TODO: get this in reg domain format */
-		pos = skb_put(skb, 2 * sband->n_channels + 2);
-		*pos++ = WLAN_EID_SUPPORTED_CHANNELS;
-		*pos++ = 2 * sband->n_channels;
-		for (i = 0; i < sband->n_channels; i++) {
-			*pos++ = ieee80211_frequency_to_channel(
-					sband->channels[i].center_freq);
-			*pos++ = 1; /* one channel in the subband*/
-		}
-	}
-
-	/* if present, add any custom IEs that go before HT */
-	if (wk->ie_len && wk->ie) {
-		static const u8 before_ht[] = {
-			WLAN_EID_SSID,
-			WLAN_EID_SUPP_RATES,
-			WLAN_EID_EXT_SUPP_RATES,
-			WLAN_EID_PWR_CAPABILITY,
-			WLAN_EID_SUPPORTED_CHANNELS,
-			WLAN_EID_RSN,
-			WLAN_EID_QOS_CAPA,
-			WLAN_EID_RRM_ENABLED_CAPABILITIES,
-			WLAN_EID_MOBILITY_DOMAIN,
-			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
-		};
-		noffset = ieee80211_ie_split(wk->ie, wk->ie_len,
-					     before_ht, ARRAY_SIZE(before_ht),
-					     offset);
-		pos = skb_put(skb, noffset - offset);
-		memcpy(pos, wk->ie + offset, noffset - offset);
-		offset = noffset;
-	}
-
-	if (wk->assoc.use_11n && wk->assoc.wmm_used &&
-	    local->hw.queues >= 4)
-		ieee80211_add_ht_ie(sdata, skb, wk->assoc.ht_information_ie,
-				    sband, wk->chan, wk->assoc.smps);
-
-	/* if present, add any custom non-vendor IEs that go after HT */
-	if (wk->ie_len && wk->ie) {
-		noffset = ieee80211_ie_split_vendor(wk->ie, wk->ie_len,
-						    offset);
-		pos = skb_put(skb, noffset - offset);
-		memcpy(pos, wk->ie + offset, noffset - offset);
-		offset = noffset;
-	}
-
-	if (wk->assoc.wmm_used && local->hw.queues >= 4) {
-		if (wk->assoc.uapsd_used) {
-			qos_info = local->uapsd_queues;
-			qos_info |= (local->uapsd_max_sp_len <<
-				     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
-		} else {
-			qos_info = 0;
-		}
-
-		pos = skb_put(skb, 9);
-		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
-		*pos++ = 7; /* len */
-		*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
-		*pos++ = 0x50;
-		*pos++ = 0xf2;
-		*pos++ = 2; /* WME */
-		*pos++ = 0; /* WME info */
-		*pos++ = 1; /* WME ver */
-		*pos++ = qos_info;
-	}
-
-	/* add any remaining custom (i.e. vendor specific here) IEs */
-	if (wk->ie_len && wk->ie) {
-		noffset = wk->ie_len;
-		pos = skb_put(skb, noffset - offset);
-		memcpy(pos, wk->ie + offset, noffset - offset);
-	}
-
-	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
-	ieee80211_tx_skb(sdata, skb);
-}
-
-static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
-				      struct ieee80211_work *wk)
-{
-	struct cfg80211_bss *cbss;
-	u16 capa_val = WLAN_CAPABILITY_ESS;
-
-	if (wk->probe_auth.privacy)
-		capa_val |= WLAN_CAPABILITY_PRIVACY;
-
-	cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->filter_ta,
-				wk->probe_auth.ssid, wk->probe_auth.ssid_len,
-				WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
-				capa_val);
-	if (!cbss)
-		return;
-
-	cfg80211_unlink_bss(local->hw.wiphy, cbss);
-	cfg80211_put_bss(cbss);
-}
-
-static enum work_action __must_check
-ieee80211_direct_probe(struct ieee80211_work *wk)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	struct ieee80211_local *local = sdata->local;
-
-	if (!wk->probe_auth.synced) {
-		int ret = drv_tx_sync(local, sdata, wk->filter_ta,
-				      IEEE80211_TX_SYNC_AUTH);
-		if (ret)
-			return WORK_ACT_TIMEOUT;
-	}
-	wk->probe_auth.synced = true;
-
-	wk->probe_auth.tries++;
-	if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
-		printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
-		       sdata->name, wk->filter_ta);
-
-		/*
-		 * Most likely AP is not in the range so remove the
-		 * bss struct for that AP.
-		 */
-		ieee80211_remove_auth_bss(local, wk);
-
-		return WORK_ACT_TIMEOUT;
-	}
-
-	printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
-	       sdata->name, wk->filter_ta, wk->probe_auth.tries,
-	       IEEE80211_AUTH_MAX_TRIES);
-
-	/*
-	 * Direct probe is sent to broadcast address as some APs
-	 * will not answer to direct packet in unassociated state.
-	 */
-	ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
-				 wk->probe_auth.ssid_len, NULL, 0,
-				 (u32) -1, true, false);
-
-	wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
-	run_again(local, wk->timeout);
-
-	return WORK_ACT_NONE;
-}
-
-
-static enum work_action __must_check
-ieee80211_authenticate(struct ieee80211_work *wk)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	struct ieee80211_local *local = sdata->local;
-
-	if (!wk->probe_auth.synced) {
-		int ret = drv_tx_sync(local, sdata, wk->filter_ta,
-				      IEEE80211_TX_SYNC_AUTH);
-		if (ret)
-			return WORK_ACT_TIMEOUT;
-	}
-	wk->probe_auth.synced = true;
-
-	wk->probe_auth.tries++;
-	if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
-		printk(KERN_DEBUG "%s: authentication with %pM"
-		       " timed out\n", sdata->name, wk->filter_ta);
-
-		/*
-		 * Most likely AP is not in the range so remove the
-		 * bss struct for that AP.
-		 */
-		ieee80211_remove_auth_bss(local, wk);
-
-		return WORK_ACT_TIMEOUT;
-	}
-
-	printk(KERN_DEBUG "%s: authenticate with %pM (try %d)\n",
-	       sdata->name, wk->filter_ta, wk->probe_auth.tries);
-
-	ieee80211_send_auth(sdata, 1, wk->probe_auth.algorithm, wk->ie,
-			    wk->ie_len, wk->filter_ta, NULL, 0, 0);
-	wk->probe_auth.transaction = 2;
-
-	wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
-	run_again(local, wk->timeout);
-
-	return WORK_ACT_NONE;
-}
-
-static enum work_action __must_check
-ieee80211_associate(struct ieee80211_work *wk)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	struct ieee80211_local *local = sdata->local;
-
-	if (!wk->assoc.synced) {
-		int ret = drv_tx_sync(local, sdata, wk->filter_ta,
-				      IEEE80211_TX_SYNC_ASSOC);
-		if (ret)
-			return WORK_ACT_TIMEOUT;
-	}
-	wk->assoc.synced = true;
-
-	wk->assoc.tries++;
-	if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
-		printk(KERN_DEBUG "%s: association with %pM"
-		       " timed out\n",
-		       sdata->name, wk->filter_ta);
-
-		/*
-		 * Most likely AP is not in the range so remove the
-		 * bss struct for that AP.
-		 */
-		if (wk->assoc.bss)
-			cfg80211_unlink_bss(local->hw.wiphy, wk->assoc.bss);
-
-		return WORK_ACT_TIMEOUT;
-	}
-
-	printk(KERN_DEBUG "%s: associate with %pM (try %d)\n",
-	       sdata->name, wk->filter_ta, wk->assoc.tries);
-	ieee80211_send_assoc(sdata, wk);
-
-	wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
-	run_again(local, wk->timeout);
-
-	return WORK_ACT_NONE;
-}
-
 static enum work_action __must_check
 ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
 {
@@ -568,300 +103,6 @@ ieee80211_offchannel_tx(struct ieee80211_work *wk)
 	return WORK_ACT_TIMEOUT;
 }
 
-static enum work_action __must_check
-ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
-{
-	if (wk->started)
-		return WORK_ACT_TIMEOUT;
-
-	/*
-	 * Wait up to one beacon interval ...
-	 * should this be more if we miss one?
-	 */
-	printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
-	       wk->sdata->name, wk->filter_ta);
-	wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval);
-	return WORK_ACT_NONE;
-}
-
-static void ieee80211_auth_challenge(struct ieee80211_work *wk,
-				     struct ieee80211_mgmt *mgmt,
-				     size_t len)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	u8 *pos;
-	struct ieee802_11_elems elems;
-
-	pos = mgmt->u.auth.variable;
-	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
-	if (!elems.challenge)
-		return;
-	ieee80211_send_auth(sdata, 3, wk->probe_auth.algorithm,
-			    elems.challenge - 2, elems.challenge_len + 2,
-			    wk->filter_ta, wk->probe_auth.key,
-			    wk->probe_auth.key_len, wk->probe_auth.key_idx);
-	wk->probe_auth.transaction = 4;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
-		       struct ieee80211_mgmt *mgmt, size_t len)
-{
-	u16 auth_alg, auth_transaction, status_code;
-
-	if (wk->type != IEEE80211_WORK_AUTH)
-		return WORK_ACT_MISMATCH;
-
-	if (len < 24 + 6)
-		return WORK_ACT_NONE;
-
-	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
-	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
-	status_code = le16_to_cpu(mgmt->u.auth.status_code);
-
-	if (auth_alg != wk->probe_auth.algorithm ||
-	    auth_transaction != wk->probe_auth.transaction)
-		return WORK_ACT_NONE;
-
-	if (status_code != WLAN_STATUS_SUCCESS) {
-		printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
-		       wk->sdata->name, mgmt->sa, status_code);
-		return WORK_ACT_DONE;
-	}
-
-	switch (wk->probe_auth.algorithm) {
-	case WLAN_AUTH_OPEN:
-	case WLAN_AUTH_LEAP:
-	case WLAN_AUTH_FT:
-		break;
-	case WLAN_AUTH_SHARED_KEY:
-		if (wk->probe_auth.transaction != 4) {
-			ieee80211_auth_challenge(wk, mgmt, len);
-			/* need another frame */
-			return WORK_ACT_NONE;
-		}
-		break;
-	default:
-		WARN_ON(1);
-		return WORK_ACT_NONE;
-	}
-
-	printk(KERN_DEBUG "%s: authenticated\n", wk->sdata->name);
-	return WORK_ACT_DONE;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
-			     struct ieee80211_mgmt *mgmt, size_t len,
-			     bool reassoc)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	struct ieee80211_local *local = sdata->local;
-	u16 capab_info, status_code, aid;
-	struct ieee802_11_elems elems;
-	u8 *pos;
-
-	if (wk->type != IEEE80211_WORK_ASSOC)
-		return WORK_ACT_MISMATCH;
-
-	/*
-	 * AssocResp and ReassocResp have identical structure, so process both
-	 * of them in this function.
-	 */
-
-	if (len < 24 + 6)
-		return WORK_ACT_NONE;
-
-	capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
-	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
-	aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
-
-	printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
-	       "status=%d aid=%d)\n",
-	       sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
-	       capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
-
-	pos = mgmt->u.assoc_resp.variable;
-	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
-
-	if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
-	    elems.timeout_int && elems.timeout_int_len == 5 &&
-	    elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
-		u32 tu, ms;
-		tu = get_unaligned_le32(elems.timeout_int + 1);
-		ms = tu * 1024 / 1000;
-		printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
-		       "comeback duration %u TU (%u ms)\n",
-		       sdata->name, mgmt->sa, tu, ms);
-		wk->timeout = jiffies + msecs_to_jiffies(ms);
-		if (ms > IEEE80211_ASSOC_TIMEOUT)
-			run_again(local, wk->timeout);
-		return WORK_ACT_NONE;
-	}
-
-	if (status_code != WLAN_STATUS_SUCCESS)
-		printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
-		       sdata->name, mgmt->sa, status_code);
-	else
-		printk(KERN_DEBUG "%s: associated\n", sdata->name);
-
-	return WORK_ACT_DONE;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
-			     struct ieee80211_mgmt *mgmt, size_t len,
-			     struct ieee80211_rx_status *rx_status)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	struct ieee80211_local *local = sdata->local;
-	size_t baselen;
-
-	ASSERT_WORK_MTX(local);
-
-	if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
-		return WORK_ACT_MISMATCH;
-
-	if (len < 24 + 12)
-		return WORK_ACT_NONE;
-
-	baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
-	if (baselen > len)
-		return WORK_ACT_NONE;
-
-	printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
-	return WORK_ACT_DONE;
-}
-
-static enum work_action __must_check
-ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk,
-			 struct ieee80211_mgmt *mgmt, size_t len)
-{
-	struct ieee80211_sub_if_data *sdata = wk->sdata;
-	struct ieee80211_local *local = sdata->local;
-
-	ASSERT_WORK_MTX(local);
-
-	if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
-		return WORK_ACT_MISMATCH;
-
-	if (len < 24 + 12)
-		return WORK_ACT_NONE;
-
-	printk(KERN_DEBUG "%s: beacon received\n", sdata->name);
-	return WORK_ACT_DONE;
-}
-
-static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
-					  struct sk_buff *skb)
-{
-	struct ieee80211_rx_status *rx_status;
-	struct ieee80211_mgmt *mgmt;
-	struct ieee80211_work *wk;
-	enum work_action rma = WORK_ACT_NONE;
-	u16 fc;
-
-	rx_status = (struct ieee80211_rx_status *) skb->cb;
-	mgmt = (struct ieee80211_mgmt *) skb->data;
-	fc = le16_to_cpu(mgmt->frame_control);
-
-	mutex_lock(&local->mtx);
-
-	list_for_each_entry(wk, &local->work_list, list) {
-		const u8 *bssid = NULL;
-
-		switch (wk->type) {
-		case IEEE80211_WORK_DIRECT_PROBE:
-		case IEEE80211_WORK_AUTH:
-		case IEEE80211_WORK_ASSOC:
-		case IEEE80211_WORK_ASSOC_BEACON_WAIT:
-			bssid = wk->filter_ta;
-			break;
-		default:
-			continue;
-		}
-
-		/*
-		 * Before queuing, we already verified mgmt->sa,
-		 * so this is needed just for matching.
-		 */
-		if (compare_ether_addr(bssid, mgmt->bssid))
-			continue;
-
-		switch (fc & IEEE80211_FCTL_STYPE) {
-		case IEEE80211_STYPE_BEACON:
-			rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len);
-			break;
-		case IEEE80211_STYPE_PROBE_RESP:
-			rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
-							   rx_status);
-			break;
-		case IEEE80211_STYPE_AUTH:
-			rma = ieee80211_rx_mgmt_auth(wk, mgmt, skb->len);
-			break;
-		case IEEE80211_STYPE_ASSOC_RESP:
-			rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
-							   skb->len, false);
-			break;
-		case IEEE80211_STYPE_REASSOC_RESP:
-			rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
-							   skb->len, true);
-			break;
-		default:
-			WARN_ON(1);
-			rma = WORK_ACT_NONE;
-		}
-
-		/*
-		 * We've either received an unexpected frame, or we have
-		 * multiple work items and need to match the frame to the
-		 * right one.
-		 */
-		if (rma == WORK_ACT_MISMATCH)
-			continue;
-
-		/*
-		 * We've processed this frame for that work, so it can't
-		 * belong to another work struct.
-		 * NB: this is also required for correctness for 'rma'!
-		 */
-		break;
-	}
-
-	switch (rma) {
-	case WORK_ACT_MISMATCH:
-		/* ignore this unmatched frame */
-		break;
-	case WORK_ACT_NONE:
-		break;
-	case WORK_ACT_DONE:
-		list_del_rcu(&wk->list);
-		break;
-	default:
-		WARN(1, "unexpected: %d", rma);
-	}
-
-	mutex_unlock(&local->mtx);
-
-	if (rma != WORK_ACT_DONE)
-		goto out;
-
-	switch (wk->done(wk, skb)) {
-	case WORK_DONE_DESTROY:
-		free_work(wk);
-		break;
-	case WORK_DONE_REQUEUE:
-		synchronize_rcu();
-		wk->started = false; /* restart */
-		mutex_lock(&local->mtx);
-		list_add_tail(&wk->list, &local->work_list);
-		mutex_unlock(&local->mtx);
-	}
-
- out:
-	kfree_skb(skb);
-}
-
 static void ieee80211_work_timer(unsigned long data)
 {
 	struct ieee80211_local *local = (void *) data;
@@ -876,7 +117,6 @@ static void ieee80211_work_work(struct work_struct *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, work_work);
-	struct sk_buff *skb;
 	struct ieee80211_work *wk, *tmp;
 	LIST_HEAD(free_work);
 	enum work_action rma;
@@ -892,10 +132,6 @@ static void ieee80211_work_work(struct work_struct *work)
 	if (WARN(local->suspended, "work scheduled while going to suspend\n"))
 		return;
 
-	/* first process frames to avoid timing out while a frame is pending */
-	while ((skb = skb_dequeue(&local->work_skb_queue)))
-		ieee80211_work_rx_queued_mgmt(local, skb);
-
 	mutex_lock(&local->mtx);
 
 	ieee80211_recalc_idle(local);
@@ -946,24 +182,12 @@ static void ieee80211_work_work(struct work_struct *work)
 		case IEEE80211_WORK_ABORT:
 			rma = WORK_ACT_TIMEOUT;
 			break;
-		case IEEE80211_WORK_DIRECT_PROBE:
-			rma = ieee80211_direct_probe(wk);
-			break;
-		case IEEE80211_WORK_AUTH:
-			rma = ieee80211_authenticate(wk);
-			break;
-		case IEEE80211_WORK_ASSOC:
-			rma = ieee80211_associate(wk);
-			break;
 		case IEEE80211_WORK_REMAIN_ON_CHANNEL:
 			rma = ieee80211_remain_on_channel_timeout(wk);
 			break;
 		case IEEE80211_WORK_OFFCHANNEL_TX:
 			rma = ieee80211_offchannel_tx(wk);
 			break;
-		case IEEE80211_WORK_ASSOC_BEACON_WAIT:
-			rma = ieee80211_assoc_beacon_wait(wk);
-			break;
 		}
 
 		wk->started = started;
@@ -1051,7 +275,6 @@ void ieee80211_work_init(struct ieee80211_local *local)
 	setup_timer(&local->work_timer, ieee80211_work_timer,
 		    (unsigned long)local);
 	INIT_WORK(&local->work_work, ieee80211_work_work);
-	skb_queue_head_init(&local->work_skb_queue);
 }
 
 void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
@@ -1085,43 +308,6 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
 	mutex_unlock(&local->mtx);
 }
 
-ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-					   struct sk_buff *skb)
-{
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_mgmt *mgmt;
-	struct ieee80211_work *wk;
-	u16 fc;
-
-	if (skb->len < 24)
-		return RX_DROP_MONITOR;
-
-	mgmt = (struct ieee80211_mgmt *) skb->data;
-	fc = le16_to_cpu(mgmt->frame_control);
-
-	list_for_each_entry_rcu(wk, &local->work_list, list) {
-		if (sdata != wk->sdata)
-			continue;
-		if (compare_ether_addr(wk->filter_ta, mgmt->sa))
-			continue;
-		if (compare_ether_addr(wk->filter_ta, mgmt->bssid))
-			continue;
-
-		switch (fc & IEEE80211_FCTL_STYPE) {
-		case IEEE80211_STYPE_AUTH:
-		case IEEE80211_STYPE_PROBE_RESP:
-		case IEEE80211_STYPE_ASSOC_RESP:
-		case IEEE80211_STYPE_REASSOC_RESP:
-		case IEEE80211_STYPE_BEACON:
-			skb_queue_tail(&local->work_skb_queue, skb);
-			ieee80211_queue_work(&local->hw, &local->work_work);
-			return RX_QUEUED;
-		}
-	}
-
-	return RX_CONTINUE;
-}
-
 static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk,
 						   struct sk_buff *skb)
 {
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9307b03..0c62c76 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -584,6 +584,11 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
 		return 0;
 
 	net = nf_ct_net(ct);
+
+	/* container deinit, netlink may have died before death_by_timeout */
+	if (!net->nfnl)
+		return 0;
+
 	if (!item->report && !nfnetlink_has_listeners(net, group))
 		return 0;
 
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index 3aae66f..f81eba4 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -87,7 +87,7 @@ tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 	const struct xt_tee_tginfo *info = par->targinfo;
 	struct iphdr *iph;
 
-	if (percpu_read(tee_active))
+	if (__this_cpu_read(tee_active))
 		return XT_CONTINUE;
 	/*
 	 * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
@@ -124,9 +124,9 @@ tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 	ip_send_check(iph);
 
 	if (tee_tg_route4(skb, info)) {
-		percpu_write(tee_active, true);
+		__this_cpu_write(tee_active, true);
 		ip_local_out(skb);
-		percpu_write(tee_active, false);
+		__this_cpu_write(tee_active, false);
 	} else {
 		kfree_skb(skb);
 	}
@@ -167,7 +167,7 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 {
 	const struct xt_tee_tginfo *info = par->targinfo;
 
-	if (percpu_read(tee_active))
+	if (__this_cpu_read(tee_active))
 		return XT_CONTINUE;
 	skb = pskb_copy(skb, GFP_ATOMIC);
 	if (skb == NULL)
@@ -185,9 +185,9 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 		--iph->hop_limit;
 	}
 	if (tee_tg_route6(skb, info)) {
-		percpu_write(tee_active, true);
+		__this_cpu_write(tee_active, true);
 		ip6_local_out(skb);
-		percpu_write(tee_active, false);
+		__this_cpu_write(tee_active, false);
 	} else {
 		kfree_skb(skb);
 	}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 629b061..4d751e3 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1645,6 +1645,24 @@ static void netlink_destroy_callback(struct netlink_callback *cb)
 	kfree(cb);
 }
 
+struct nlmsghdr *
+__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
+{
+	struct nlmsghdr *nlh;
+	int size = NLMSG_LENGTH(len);
+
+	nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size));
+	nlh->nlmsg_type = type;
+	nlh->nlmsg_len = size;
+	nlh->nlmsg_flags = flags;
+	nlh->nlmsg_pid = pid;
+	nlh->nlmsg_seq = seq;
+	if (!__builtin_constant_p(size) || NLMSG_ALIGN(size) - size != 0)
+		memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
+	return nlh;
+}
+EXPORT_SYMBOL(__nlmsg_put);
+
 /*
  * It looks a bit ugly.
  * It would be better to create kernel thread.
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index c29d256..a115471 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -498,6 +498,37 @@ int genl_unregister_family(struct genl_family *family)
 }
 EXPORT_SYMBOL(genl_unregister_family);
 
+/**
+ * genlmsg_put - Add generic netlink header to netlink message
+ * @skb: socket buffer holding the message
+ * @pid: netlink pid the message is addressed to
+ * @seq: sequence number (usually the one of the sender)
+ * @family: generic netlink family
+ * @flags netlink message flags
+ * @cmd: generic netlink command
+ *
+ * Returns pointer to user specific header
+ */
+void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
+				struct genl_family *family, int flags, u8 cmd)
+{
+	struct nlmsghdr *nlh;
+	struct genlmsghdr *hdr;
+
+	nlh = nlmsg_put(skb, pid, seq, family->id, GENL_HDRLEN +
+			family->hdrsize, flags);
+	if (nlh == NULL)
+		return NULL;
+
+	hdr = nlmsg_data(nlh);
+	hdr->cmd = cmd;
+	hdr->version = family->version;
+	hdr->reserved = 0;
+
+	return (char *) hdr + GENL_HDRLEN;
+}
+EXPORT_SYMBOL(genlmsg_put);
+
 static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	struct genl_ops *ops;
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 3ddf6e6..6089aca 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -431,15 +431,10 @@ EXPORT_SYMBOL(nfc_alloc_recv_skb);
 int nfc_targets_found(struct nfc_dev *dev, struct nfc_target *targets,
 							int n_targets)
 {
-	int i;
-
 	pr_debug("dev_name=%s n_targets=%d\n", dev_name(&dev->dev), n_targets);
 
 	dev->polling = false;
 
-	for (i = 0; i < n_targets; i++)
-		targets[i].idx = dev->target_idx++;
-
 	spin_lock_bh(&dev->targets_lock);
 
 	dev->targets_generation++;
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index 7650139..a47e90c 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -216,6 +216,39 @@ static void nci_rf_discover_req(struct nci_dev *ndev, unsigned long opt)
 		&cmd);
 }
 
+struct nci_rf_discover_select_param {
+	__u8	rf_discovery_id;
+	__u8	rf_protocol;
+};
+
+static void nci_rf_discover_select_req(struct nci_dev *ndev, unsigned long opt)
+{
+	struct nci_rf_discover_select_param *param =
+				(struct nci_rf_discover_select_param *)opt;
+	struct nci_rf_discover_select_cmd cmd;
+
+	cmd.rf_discovery_id = param->rf_discovery_id;
+	cmd.rf_protocol = param->rf_protocol;
+
+	switch (cmd.rf_protocol) {
+	case NCI_RF_PROTOCOL_ISO_DEP:
+		cmd.rf_interface = NCI_RF_INTERFACE_ISO_DEP;
+		break;
+
+	case NCI_RF_PROTOCOL_NFC_DEP:
+		cmd.rf_interface = NCI_RF_INTERFACE_NFC_DEP;
+		break;
+
+	default:
+		cmd.rf_interface = NCI_RF_INTERFACE_FRAME;
+		break;
+	}
+
+	nci_send_cmd(ndev, NCI_OP_RF_DISCOVER_SELECT_CMD,
+			sizeof(struct nci_rf_discover_select_cmd),
+			&cmd);
+}
+
 static void nci_rf_deactivate_req(struct nci_dev *ndev, unsigned long opt)
 {
 	struct nci_rf_deactivate_cmd cmd;
@@ -264,6 +297,8 @@ static int nci_open_device(struct nci_dev *ndev)
 
 	if (!rc) {
 		set_bit(NCI_UP, &ndev->flags);
+		nci_clear_target_list(ndev);
+		atomic_set(&ndev->state, NCI_IDLE);
 	} else {
 		/* Init failed, cleanup */
 		skb_queue_purge(&ndev->cmd_q);
@@ -286,6 +321,7 @@ static int nci_close_device(struct nci_dev *ndev)
 
 	if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
 		del_timer_sync(&ndev->cmd_timer);
+		del_timer_sync(&ndev->data_timer);
 		mutex_unlock(&ndev->req_lock);
 		return 0;
 	}
@@ -331,6 +367,15 @@ static void nci_cmd_timer(unsigned long arg)
 	queue_work(ndev->cmd_wq, &ndev->cmd_work);
 }
 
+/* NCI data exchange timer function */
+static void nci_data_timer(unsigned long arg)
+{
+	struct nci_dev *ndev = (void *) arg;
+
+	set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
+	queue_work(ndev->rx_wq, &ndev->rx_work);
+}
+
 static int nci_dev_up(struct nfc_dev *nfc_dev)
 {
 	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
@@ -350,7 +395,8 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
 	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
 	int rc;
 
-	if (test_bit(NCI_DISCOVERY, &ndev->flags)) {
+	if ((atomic_read(&ndev->state) == NCI_DISCOVERY) ||
+		(atomic_read(&ndev->state) == NCI_W4_ALL_DISCOVERIES)) {
 		pr_err("unable to start poll, since poll is already active\n");
 		return -EBUSY;
 	}
@@ -360,8 +406,9 @@ static int nci_start_poll(struct nfc_dev *nfc_dev, __u32 protocols)
 		return -EBUSY;
 	}
 
-	if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
-		pr_debug("target is active, implicitly deactivate...\n");
+	if ((atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) ||
+		(atomic_read(&ndev->state) == NCI_POLL_ACTIVE)) {
+		pr_debug("target active or w4 select, implicitly deactivate\n");
 
 		rc = nci_request(ndev, nci_rf_deactivate_req, 0,
 			msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
@@ -382,7 +429,8 @@ static void nci_stop_poll(struct nfc_dev *nfc_dev)
 {
 	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
 
-	if (!test_bit(NCI_DISCOVERY, &ndev->flags)) {
+	if ((atomic_read(&ndev->state) != NCI_DISCOVERY) &&
+		(atomic_read(&ndev->state) != NCI_W4_ALL_DISCOVERIES)) {
 		pr_err("unable to stop poll, since poll is not active\n");
 		return;
 	}
@@ -395,10 +443,15 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
 				__u32 protocol)
 {
 	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
+	struct nci_rf_discover_select_param param;
+	struct nfc_target *target = NULL;
+	int i;
+	int rc = 0;
 
 	pr_debug("target_idx %d, protocol 0x%x\n", target_idx, protocol);
 
-	if (!test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
+	if ((atomic_read(&ndev->state) != NCI_W4_HOST_SELECT) &&
+		(atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
 		pr_err("there is no available target to activate\n");
 		return -EINVAL;
 	}
@@ -408,16 +461,47 @@ static int nci_activate_target(struct nfc_dev *nfc_dev, __u32 target_idx,
 		return -EBUSY;
 	}
 
-	if (!(ndev->target_available_prots & (1 << protocol))) {
+	for (i = 0; i < ndev->n_targets; i++) {
+		if (ndev->targets[i].idx == target_idx) {
+			target = &ndev->targets[i];
+			break;
+		}
+	}
+
+	if (!target) {
+		pr_err("unable to find the selected target\n");
+		return -EINVAL;
+	}
+
+	if (!(target->supported_protocols & (1 << protocol))) {
 		pr_err("target does not support the requested protocol 0x%x\n",
 		       protocol);
 		return -EINVAL;
 	}
 
-	ndev->target_active_prot = protocol;
-	ndev->target_available_prots = 0;
+	if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
+		param.rf_discovery_id = target->idx;
 
-	return 0;
+		if (protocol == NFC_PROTO_JEWEL)
+			param.rf_protocol = NCI_RF_PROTOCOL_T1T;
+		else if (protocol == NFC_PROTO_MIFARE)
+			param.rf_protocol = NCI_RF_PROTOCOL_T2T;
+		else if (protocol == NFC_PROTO_FELICA)
+			param.rf_protocol = NCI_RF_PROTOCOL_T3T;
+		else if (protocol == NFC_PROTO_ISO14443)
+			param.rf_protocol = NCI_RF_PROTOCOL_ISO_DEP;
+		else
+			param.rf_protocol = NCI_RF_PROTOCOL_NFC_DEP;
+
+		rc = nci_request(ndev, nci_rf_discover_select_req,
+				(unsigned long)&param,
+				msecs_to_jiffies(NCI_RF_DISC_SELECT_TIMEOUT));
+	}
+
+	if (!rc)
+		ndev->target_active_prot = protocol;
+
+	return rc;
 }
 
 static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
@@ -433,7 +517,7 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, __u32 target_idx)
 
 	ndev->target_active_prot = 0;
 
-	if (test_bit(NCI_POLL_ACTIVE, &ndev->flags)) {
+	if (atomic_read(&ndev->state) == NCI_POLL_ACTIVE) {
 		nci_request(ndev, nci_rf_deactivate_req, 0,
 			msecs_to_jiffies(NCI_RF_DEACTIVATE_TIMEOUT));
 	}
@@ -585,6 +669,8 @@ int nci_register_device(struct nci_dev *ndev)
 
 	setup_timer(&ndev->cmd_timer, nci_cmd_timer,
 			(unsigned long) ndev);
+	setup_timer(&ndev->data_timer, nci_data_timer,
+			(unsigned long) ndev);
 
 	mutex_init(&ndev->req_lock);
 
@@ -722,6 +808,9 @@ static void nci_tx_work(struct work_struct *work)
 			 nci_plen(skb->data));
 
 		nci_send_frame(skb);
+
+		mod_timer(&ndev->data_timer,
+			jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
 	}
 }
 
@@ -753,6 +842,15 @@ static void nci_rx_work(struct work_struct *work)
 			break;
 		}
 	}
+
+	/* check if a data exchange timout has occurred */
+	if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) {
+		/* complete the data exchange transaction, if exists */
+		if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
+			nci_data_exchange_complete(ndev, NULL, -ETIMEDOUT);
+
+		clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
+	}
 }
 
 /* ----- NCI TX CMD worker thread ----- */
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
index e5756b3..7880ae9 100644
--- a/net/nfc/nci/data.c
+++ b/net/nfc/nci/data.c
@@ -44,6 +44,10 @@ void nci_data_exchange_complete(struct nci_dev *ndev,
 
 	pr_debug("len %d, err %d\n", skb ? skb->len : 0, err);
 
+	/* data exchange is complete, stop the data timer */
+	del_timer_sync(&ndev->data_timer);
+	clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
+
 	if (cb) {
 		ndev->data_exchange_cb = NULL;
 		ndev->data_exchange_cb_context = 0;
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
index b16a8dc..03e7b46 100644
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -71,6 +71,20 @@ static void nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
 		queue_work(ndev->tx_wq, &ndev->tx_work);
 }
 
+static void nci_core_generic_error_ntf_packet(struct nci_dev *ndev,
+						struct sk_buff *skb)
+{
+	__u8 status = skb->data[0];
+
+	pr_debug("status 0x%x\n", status);
+
+	if (atomic_read(&ndev->state) == NCI_W4_HOST_SELECT) {
+		/* Activation failed, so complete the request
+		(the state remains the same) */
+		nci_req_complete(ndev, status);
+	}
+}
+
 static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
 						struct sk_buff *skb)
 {
@@ -86,12 +100,9 @@ static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
 }
 
 static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
-			struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
+			struct rf_tech_specific_params_nfca_poll *nfca_poll,
+			__u8 *data)
 {
-	struct rf_tech_specific_params_nfca_poll *nfca_poll;
-
-	nfca_poll = &ntf->rf_tech_specific_params.nfca_poll;
-
 	nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
 	data += 2;
 
@@ -115,15 +126,213 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
 	return data;
 }
 
+static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
+			struct rf_tech_specific_params_nfcb_poll *nfcb_poll,
+			__u8 *data)
+{
+	nfcb_poll->sensb_res_len = *data++;
+
+	pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len);
+
+	memcpy(nfcb_poll->sensb_res, data, nfcb_poll->sensb_res_len);
+	data += nfcb_poll->sensb_res_len;
+
+	return data;
+}
+
+static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
+			struct rf_tech_specific_params_nfcf_poll *nfcf_poll,
+			__u8 *data)
+{
+	nfcf_poll->bit_rate = *data++;
+	nfcf_poll->sensf_res_len = *data++;
+
+	pr_debug("bit_rate %d, sensf_res_len %d\n",
+		nfcf_poll->bit_rate, nfcf_poll->sensf_res_len);
+
+	memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len);
+	data += nfcf_poll->sensf_res_len;
+
+	return data;
+}
+
+static int nci_add_new_protocol(struct nci_dev *ndev,
+				struct nfc_target *target,
+				__u8 rf_protocol,
+				__u8 rf_tech_and_mode,
+				void *params)
+{
+	struct rf_tech_specific_params_nfca_poll *nfca_poll;
+	struct rf_tech_specific_params_nfcb_poll *nfcb_poll;
+	struct rf_tech_specific_params_nfcf_poll *nfcf_poll;
+	__u32 protocol;
+
+	if (rf_protocol == NCI_RF_PROTOCOL_T2T)
+		protocol = NFC_PROTO_MIFARE_MASK;
+	else if (rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)
+		protocol = NFC_PROTO_ISO14443_MASK;
+	else if (rf_protocol == NCI_RF_PROTOCOL_T3T)
+		protocol = NFC_PROTO_FELICA_MASK;
+	else
+		protocol = 0;
+
+	if (!(protocol & ndev->poll_prots)) {
+		pr_err("the target found does not have the desired protocol\n");
+		return -EPROTO;
+	}
+
+	if (rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) {
+		nfca_poll = (struct rf_tech_specific_params_nfca_poll *)params;
+
+		target->sens_res = nfca_poll->sens_res;
+		target->sel_res = nfca_poll->sel_res;
+		target->nfcid1_len = nfca_poll->nfcid1_len;
+		if (target->nfcid1_len > 0) {
+			memcpy(target->nfcid1, nfca_poll->nfcid1,
+				target->nfcid1_len);
+		}
+	} else if (rf_tech_and_mode == NCI_NFC_B_PASSIVE_POLL_MODE) {
+		nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
+
+		target->sensb_res_len = nfcb_poll->sensb_res_len;
+		if (target->sensb_res_len > 0) {
+			memcpy(target->sensb_res, nfcb_poll->sensb_res,
+				target->sensb_res_len);
+		}
+	} else if (rf_tech_and_mode == NCI_NFC_F_PASSIVE_POLL_MODE) {
+		nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
+
+		target->sensf_res_len = nfcf_poll->sensf_res_len;
+		if (target->sensf_res_len > 0) {
+			memcpy(target->sensf_res, nfcf_poll->sensf_res,
+				target->sensf_res_len);
+		}
+	} else {
+		pr_err("unsupported rf_tech_and_mode 0x%x\n", rf_tech_and_mode);
+		return -EPROTO;
+	}
+
+	target->supported_protocols |= protocol;
+
+	pr_debug("protocol 0x%x\n", protocol);
+
+	return 0;
+}
+
+static void nci_add_new_target(struct nci_dev *ndev,
+				struct nci_rf_discover_ntf *ntf)
+{
+	struct nfc_target *target;
+	int i, rc;
+
+	for (i = 0; i < ndev->n_targets; i++) {
+		target = &ndev->targets[i];
+		if (target->idx == ntf->rf_discovery_id) {
+			/* This target already exists, add the new protocol */
+			nci_add_new_protocol(ndev, target, ntf->rf_protocol,
+						ntf->rf_tech_and_mode,
+						&ntf->rf_tech_specific_params);
+			return;
+		}
+	}
+
+	/* This is a new target, check if we've enough room */
+	if (ndev->n_targets == NCI_MAX_DISCOVERED_TARGETS) {
+		pr_debug("not enough room, ignoring new target...\n");
+		return;
+	}
+
+	target = &ndev->targets[ndev->n_targets];
+
+	rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
+					ntf->rf_tech_and_mode,
+					&ntf->rf_tech_specific_params);
+	if (!rc) {
+		target->idx = ntf->rf_discovery_id;
+		ndev->n_targets++;
+
+		pr_debug("target_idx %d, n_targets %d\n", target->idx,
+				ndev->n_targets);
+	}
+}
+
+void nci_clear_target_list(struct nci_dev *ndev)
+{
+	memset(ndev->targets, 0,
+		(sizeof(struct nfc_target)*NCI_MAX_DISCOVERED_TARGETS));
+
+	ndev->n_targets = 0;
+}
+
+static void nci_rf_discover_ntf_packet(struct nci_dev *ndev,
+					struct sk_buff *skb)
+{
+	struct nci_rf_discover_ntf ntf;
+	__u8 *data = skb->data;
+	bool add_target = true;
+
+	ntf.rf_discovery_id = *data++;
+	ntf.rf_protocol = *data++;
+	ntf.rf_tech_and_mode = *data++;
+	ntf.rf_tech_specific_params_len = *data++;
+
+	pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);
+	pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);
+	pr_debug("rf_tech_and_mode 0x%x\n", ntf.rf_tech_and_mode);
+	pr_debug("rf_tech_specific_params_len %d\n",
+			ntf.rf_tech_specific_params_len);
+
+	if (ntf.rf_tech_specific_params_len > 0) {
+		switch (ntf.rf_tech_and_mode) {
+		case NCI_NFC_A_PASSIVE_POLL_MODE:
+			data = nci_extract_rf_params_nfca_passive_poll(ndev,
+				&(ntf.rf_tech_specific_params.nfca_poll), data);
+			break;
+
+		case NCI_NFC_B_PASSIVE_POLL_MODE:
+			data = nci_extract_rf_params_nfcb_passive_poll(ndev,
+				&(ntf.rf_tech_specific_params.nfcb_poll), data);
+			break;
+
+		case NCI_NFC_F_PASSIVE_POLL_MODE:
+			data = nci_extract_rf_params_nfcf_passive_poll(ndev,
+				&(ntf.rf_tech_specific_params.nfcf_poll), data);
+			break;
+
+		default:
+			pr_err("unsupported rf_tech_and_mode 0x%x\n",
+			       ntf.rf_tech_and_mode);
+			data += ntf.rf_tech_specific_params_len;
+			add_target = false;
+		}
+	}
+
+	ntf.ntf_type = *data++;
+	pr_debug("ntf_type %d\n", ntf.ntf_type);
+
+	if (add_target == true)
+		nci_add_new_target(ndev, &ntf);
+
+	if (ntf.ntf_type == NCI_DISCOVER_NTF_TYPE_MORE) {
+		atomic_set(&ndev->state, NCI_W4_ALL_DISCOVERIES);
+	} else {
+		atomic_set(&ndev->state, NCI_W4_HOST_SELECT);
+		nfc_targets_found(ndev->nfc_dev, ndev->targets,
+					ndev->n_targets);
+	}
+}
+
 static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
 			struct nci_rf_intf_activated_ntf *ntf, __u8 *data)
 {
 	struct activation_params_nfca_poll_iso_dep *nfca_poll;
+	struct activation_params_nfcb_poll_iso_dep *nfcb_poll;
 
 	switch (ntf->activation_rf_tech_and_mode) {
 	case NCI_NFC_A_PASSIVE_POLL_MODE:
 		nfca_poll = &ntf->activation_params.nfca_poll_iso_dep;
 		nfca_poll->rats_res_len = *data++;
+		pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len);
 		if (nfca_poll->rats_res_len > 0) {
 			memcpy(nfca_poll->rats_res,
 				data,
@@ -131,52 +340,47 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev,
 		}
 		break;
 
+	case NCI_NFC_B_PASSIVE_POLL_MODE:
+		nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep;
+		nfcb_poll->attrib_res_len = *data++;
+		pr_debug("attrib_res_len %d\n",
+			nfcb_poll->attrib_res_len);
+		if (nfcb_poll->attrib_res_len > 0) {
+			memcpy(nfcb_poll->attrib_res,
+				data,
+				nfcb_poll->attrib_res_len);
+		}
+		break;
+
 	default:
 		pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
 		       ntf->activation_rf_tech_and_mode);
-		return -EPROTO;
+		return NCI_STATUS_RF_PROTOCOL_ERROR;
 	}
 
-	return 0;
+	return NCI_STATUS_OK;
 }
 
-static void nci_target_found(struct nci_dev *ndev,
-				struct nci_rf_intf_activated_ntf *ntf)
+static void nci_target_auto_activated(struct nci_dev *ndev,
+					struct nci_rf_intf_activated_ntf *ntf)
 {
-	struct nfc_target nfc_tgt;
+	struct nfc_target *target;
+	int rc;
 
-	if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T)	/* T2T MifareUL */
-		nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK;
-	else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP)	/* 4A */
-		nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK;
-	else
-		nfc_tgt.supported_protocols = 0;
-
-	nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res;
-	nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res;
-	nfc_tgt.nfcid1_len = ntf->rf_tech_specific_params.nfca_poll.nfcid1_len;
-	if (nfc_tgt.nfcid1_len > 0) {
-		memcpy(nfc_tgt.nfcid1,
-			ntf->rf_tech_specific_params.nfca_poll.nfcid1,
-			nfc_tgt.nfcid1_len);
-	}
+	target = &ndev->targets[ndev->n_targets];
 
-	if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) {
-		pr_debug("the target found does not have the desired protocol\n");
+	rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
+					ntf->activation_rf_tech_and_mode,
+					&ntf->rf_tech_specific_params);
+	if (rc)
 		return;
-	}
 
-	pr_debug("new target found,  supported_protocols 0x%x\n",
-		 nfc_tgt.supported_protocols);
+	target->idx = ntf->rf_discovery_id;
+	ndev->n_targets++;
 
-	ndev->target_available_prots = nfc_tgt.supported_protocols;
-	ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size;
-	ndev->initial_num_credits = ntf->initial_num_credits;
+	pr_debug("target_idx %d, n_targets %d\n", target->idx, ndev->n_targets);
 
-	/* set the available credits to initial value */
-	atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
-
-	nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);
+	nfc_targets_found(ndev->nfc_dev, ndev->targets, ndev->n_targets);
 }
 
 static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
@@ -184,10 +388,7 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 {
 	struct nci_rf_intf_activated_ntf ntf;
 	__u8 *data = skb->data;
-	int err = 0;
-
-	clear_bit(NCI_DISCOVERY, &ndev->flags);
-	set_bit(NCI_POLL_ACTIVE, &ndev->flags);
+	int err = NCI_STATUS_OK;
 
 	ntf.rf_discovery_id = *data++;
 	ntf.rf_interface = *data++;
@@ -212,13 +413,24 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 		switch (ntf.activation_rf_tech_and_mode) {
 		case NCI_NFC_A_PASSIVE_POLL_MODE:
 			data = nci_extract_rf_params_nfca_passive_poll(ndev,
-				&ntf, data);
+				&(ntf.rf_tech_specific_params.nfca_poll), data);
+			break;
+
+		case NCI_NFC_B_PASSIVE_POLL_MODE:
+			data = nci_extract_rf_params_nfcb_passive_poll(ndev,
+				&(ntf.rf_tech_specific_params.nfcb_poll), data);
+			break;
+
+		case NCI_NFC_F_PASSIVE_POLL_MODE:
+			data = nci_extract_rf_params_nfcf_passive_poll(ndev,
+				&(ntf.rf_tech_specific_params.nfcf_poll), data);
 			break;
 
 		default:
 			pr_err("unsupported activation_rf_tech_and_mode 0x%x\n",
 			       ntf.activation_rf_tech_and_mode);
-			return;
+			err = NCI_STATUS_RF_PROTOCOL_ERROR;
+			goto exit;
 		}
 	}
 
@@ -250,12 +462,30 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
 		default:
 			pr_err("unsupported rf_interface 0x%x\n",
 			       ntf.rf_interface);
-			return;
+			err = NCI_STATUS_RF_PROTOCOL_ERROR;
+			break;
 		}
 	}
 
-	if (!err)
-		nci_target_found(ndev, &ntf);
+exit:
+	if (err == NCI_STATUS_OK) {
+		ndev->max_data_pkt_payload_size = ntf.max_data_pkt_payload_size;
+		ndev->initial_num_credits = ntf.initial_num_credits;
+
+		/* set the available credits to initial value */
+		atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);
+	}
+
+	if (atomic_read(&ndev->state) == NCI_DISCOVERY) {
+		/* A single target was found and activated automatically */
+		atomic_set(&ndev->state, NCI_POLL_ACTIVE);
+		if (err == NCI_STATUS_OK)
+			nci_target_auto_activated(ndev, &ntf);
+	} else {	/* ndev->state == NCI_W4_HOST_SELECT */
+		/* A selected target was activated, so complete the request */
+		atomic_set(&ndev->state, NCI_POLL_ACTIVE);
+		nci_req_complete(ndev, err);
+	}
 }
 
 static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
@@ -265,9 +495,6 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
 
 	pr_debug("entry, type 0x%x, reason 0x%x\n", ntf->type, ntf->reason);
 
-	clear_bit(NCI_POLL_ACTIVE, &ndev->flags);
-	ndev->target_active_prot = 0;
-
 	/* drop tx data queue */
 	skb_queue_purge(&ndev->tx_q);
 
@@ -280,6 +507,10 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev,
 	/* complete the data exchange transaction, if exists */
 	if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
 		nci_data_exchange_complete(ndev, NULL, -EIO);
+
+	nci_clear_target_list(ndev);
+	atomic_set(&ndev->state, NCI_IDLE);
+	nci_req_complete(ndev, NCI_STATUS_OK);
 }
 
 void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
@@ -300,10 +531,18 @@ void nci_ntf_packet(struct nci_dev *ndev, struct sk_buff *skb)
 		nci_core_conn_credits_ntf_packet(ndev, skb);
 		break;
 
+	case NCI_OP_CORE_GENERIC_ERROR_NTF:
+		nci_core_generic_error_ntf_packet(ndev, skb);
+		break;
+
 	case NCI_OP_CORE_INTF_ERROR_NTF:
 		nci_core_conn_intf_error_ntf_packet(ndev, skb);
 		break;
 
+	case NCI_OP_RF_DISCOVER_NTF:
+		nci_rf_discover_ntf_packet(ndev, skb);
+		break;
+
 	case NCI_OP_RF_INTF_ACTIVATED_NTF:
 		nci_rf_intf_activated_ntf_packet(ndev, skb);
 		break;
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c
index 2840ae2..aa63b1e 100644
--- a/net/nfc/nci/rsp.c
+++ b/net/nfc/nci/rsp.c
@@ -137,11 +137,23 @@ static void nci_rf_disc_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
 	pr_debug("status 0x%x\n", status);
 
 	if (status == NCI_STATUS_OK)
-		set_bit(NCI_DISCOVERY, &ndev->flags);
+		atomic_set(&ndev->state, NCI_DISCOVERY);
 
 	nci_req_complete(ndev, status);
 }
 
+static void nci_rf_disc_select_rsp_packet(struct nci_dev *ndev,
+						struct sk_buff *skb)
+{
+	__u8 status = skb->data[0];
+
+	pr_debug("status 0x%x\n", status);
+
+	/* Complete the request on intf_activated_ntf or generic_error_ntf */
+	if (status != NCI_STATUS_OK)
+		nci_req_complete(ndev, status);
+}
+
 static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
 					struct sk_buff *skb)
 {
@@ -149,9 +161,13 @@ static void nci_rf_deactivate_rsp_packet(struct nci_dev *ndev,
 
 	pr_debug("status 0x%x\n", status);
 
-	clear_bit(NCI_DISCOVERY, &ndev->flags);
-
-	nci_req_complete(ndev, status);
+	/* If target was active, complete the request only in deactivate_ntf */
+	if ((status != NCI_STATUS_OK) ||
+		(atomic_read(&ndev->state) != NCI_POLL_ACTIVE)) {
+		nci_clear_target_list(ndev);
+		atomic_set(&ndev->state, NCI_IDLE);
+		nci_req_complete(ndev, status);
+	}
 }
 
 void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
@@ -187,6 +203,10 @@ void nci_rsp_packet(struct nci_dev *ndev, struct sk_buff *skb)
 		nci_rf_disc_rsp_packet(ndev, skb);
 		break;
 
+	case NCI_OP_RF_DISCOVER_SELECT_RSP:
+		nci_rf_disc_select_rsp_packet(ndev, skb);
+		break;
+
 	case NCI_OP_RF_DEACTIVATE_RSP:
 		nci_rf_deactivate_rsp_packet(ndev, skb);
 		break;
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 6989dfa..07f0348 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -70,6 +70,12 @@ static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
 	if (target->nfcid1_len > 0)
 		NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len,
 				target->nfcid1);
+	if (target->sensb_res_len > 0)
+		NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len,
+				target->sensb_res);
+	if (target->sensf_res_len > 0)
+		NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len,
+				target->sensf_res);
 
 	return genlmsg_end(msg, hdr);
 
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index 2e2f8c6..5325439 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -92,18 +92,6 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
 		goto error;
 	}
 
-	if (addr->target_idx > dev->target_idx - 1 ||
-		addr->target_idx < dev->target_idx - dev->n_targets) {
-		rc = -EINVAL;
-		goto error;
-	}
-
-	if (addr->target_idx > dev->target_idx - 1 ||
-		addr->target_idx < dev->target_idx - dev->n_targets) {
-		rc = -EINVAL;
-		goto error;
-	}
-
 	rc = nfc_activate_target(dev, addr->target_idx, addr->nfc_protocol);
 	if (rc)
 		goto put_dev;
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 322b8d2..b6b1d7d 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -66,6 +66,7 @@ static int internal_dev_mac_addr(struct net_device *dev, void *p)
 
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 	return 0;
 }
@@ -145,7 +146,7 @@ static void do_setup(struct net_device *netdev)
 	netdev->vlan_features = netdev->features;
 	netdev->features |= NETIF_F_HW_VLAN_TX;
 	netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
-	random_ether_addr(netdev->dev_addr);
+	eth_hw_addr_random(netdev);
 }
 
 static struct vport *internal_dev_create(const struct vport_parms *parms)
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index e29e0ca..8d19491 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -763,7 +763,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
 		to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off);
 		BUG_ON(to_copy & 7); /* Must be 64bit aligned. */
 
-		addr = kmap_atomic(sg_page(&frag->f_sg), KM_SOFTIRQ0);
+		addr = kmap_atomic(sg_page(&frag->f_sg));
 
 		src = addr + frag_off;
 		dst = (void *)map->m_page_addrs[map_page] + map_off;
@@ -773,7 +773,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
 			uncongested |= ~(*src) & *dst;
 			*dst++ = *src++;
 		}
-		kunmap_atomic(addr, KM_SOFTIRQ0);
+		kunmap_atomic(addr);
 
 		copied += to_copy;
 
@@ -826,7 +826,7 @@ static void rds_ib_process_recv(struct rds_connection *conn,
 
 	if (data_len < sizeof(struct rds_header)) {
 		rds_ib_conn_error(conn, "incoming message "
-		       "from %pI4 didn't inclue a "
+		       "from %pI4 didn't include a "
 		       "header, disconnecting and "
 		       "reconnecting\n",
 		       &conn->c_faddr);
@@ -919,8 +919,7 @@ static void rds_ib_process_recv(struct rds_connection *conn,
 			rds_ib_cong_recv(conn, ibinc);
 		else {
 			rds_recv_incoming(conn, conn->c_faddr, conn->c_laddr,
-					  &ibinc->ii_inc, GFP_ATOMIC,
-					  KM_SOFTIRQ0);
+					  &ibinc->ii_inc, GFP_ATOMIC);
 			state->ack_next = be64_to_cpu(hdr->h_sequence);
 			state->ack_next_valid = 1;
 		}
diff --git a/net/rds/info.c b/net/rds/info.c
index f1c016c..9a6b4f6 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -104,7 +104,7 @@ EXPORT_SYMBOL_GPL(rds_info_deregister_func);
 void rds_info_iter_unmap(struct rds_info_iterator *iter)
 {
 	if (iter->addr) {
-		kunmap_atomic(iter->addr, KM_USER0);
+		kunmap_atomic(iter->addr);
 		iter->addr = NULL;
 	}
 }
@@ -119,7 +119,7 @@ void rds_info_copy(struct rds_info_iterator *iter, void *data,
 
 	while (bytes) {
 		if (!iter->addr)
-			iter->addr = kmap_atomic(*iter->pages, KM_USER0);
+			iter->addr = kmap_atomic(*iter->pages);
 
 		this = min(bytes, PAGE_SIZE - iter->offset);
 
@@ -134,7 +134,7 @@ void rds_info_copy(struct rds_info_iterator *iter, void *data,
 		iter->offset += this;
 
 		if (iter->offset == PAGE_SIZE) {
-			kunmap_atomic(iter->addr, KM_USER0);
+			kunmap_atomic(iter->addr);
 			iter->addr = NULL;
 			iter->offset = 0;
 			iter->pages++;
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index 5e57347..4503335 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -598,7 +598,7 @@ static void rds_iw_cong_recv(struct rds_connection *conn,
 		to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off);
 		BUG_ON(to_copy & 7); /* Must be 64bit aligned. */
 
-		addr = kmap_atomic(frag->f_page, KM_SOFTIRQ0);
+		addr = kmap_atomic(frag->f_page);
 
 		src = addr + frag_off;
 		dst = (void *)map->m_page_addrs[map_page] + map_off;
@@ -608,7 +608,7 @@ static void rds_iw_cong_recv(struct rds_connection *conn,
 			uncongested |= ~(*src) & *dst;
 			*dst++ = *src++;
 		}
-		kunmap_atomic(addr, KM_SOFTIRQ0);
+		kunmap_atomic(addr);
 
 		copied += to_copy;
 
@@ -661,7 +661,7 @@ static void rds_iw_process_recv(struct rds_connection *conn,
 
 	if (byte_len < sizeof(struct rds_header)) {
 		rds_iw_conn_error(conn, "incoming message "
-		       "from %pI4 didn't inclue a "
+		       "from %pI4 didn't include a "
 		       "header, disconnecting and "
 		       "reconnecting\n",
 		       &conn->c_faddr);
@@ -754,8 +754,7 @@ static void rds_iw_process_recv(struct rds_connection *conn,
 			rds_iw_cong_recv(conn, iwinc);
 		else {
 			rds_recv_incoming(conn, conn->c_faddr, conn->c_laddr,
-					  &iwinc->ii_inc, GFP_ATOMIC,
-					  KM_SOFTIRQ0);
+					  &iwinc->ii_inc, GFP_ATOMIC);
 			state->ack_next = be64_to_cpu(hdr->h_sequence);
 			state->ack_next_valid = 1;
 		}
diff --git a/net/rds/loop.c b/net/rds/loop.c
index bca6761..87ff2a8 100644
--- a/net/rds/loop.c
+++ b/net/rds/loop.c
@@ -79,7 +79,7 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm,
 	rds_message_addref(rm);
 
 	rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc,
-			  GFP_KERNEL, KM_USER0);
+			  GFP_KERNEL);
 
 	rds_send_drop_acked(conn, be64_to_cpu(rm->m_inc.i_hdr.h_sequence),
 			    NULL);
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 7eaba18..ec1d731 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -704,7 +704,7 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
 		  __be32 saddr);
 void rds_inc_put(struct rds_incoming *inc);
 void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr,
-		       struct rds_incoming *inc, gfp_t gfp, enum km_type km);
+		       struct rds_incoming *inc, gfp_t gfp);
 int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 		size_t size, int msg_flags);
 void rds_clear_recv_queue(struct rds_sock *rs);
diff --git a/net/rds/recv.c b/net/rds/recv.c
index bc3f8cd..5c6e9f1 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -155,7 +155,7 @@ static void rds_recv_incoming_exthdrs(struct rds_incoming *inc, struct rds_sock
  * tell us which roles the addrs in the conn are playing for this message.
  */
 void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr,
-		       struct rds_incoming *inc, gfp_t gfp, enum km_type km)
+		       struct rds_incoming *inc, gfp_t gfp)
 {
 	struct rds_sock *rs = NULL;
 	struct sock *sk;
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index 78205e2..6243258 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -169,7 +169,6 @@ static void rds_tcp_cong_recv(struct rds_connection *conn,
 struct rds_tcp_desc_arg {
 	struct rds_connection *conn;
 	gfp_t gfp;
-	enum km_type km;
 };
 
 static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
@@ -255,7 +254,7 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
 			else
 				rds_recv_incoming(conn, conn->c_faddr,
 						  conn->c_laddr, &tinc->ti_inc,
-						  arg->gfp, arg->km);
+						  arg->gfp);
 
 			tc->t_tinc_hdr_rem = sizeof(struct rds_header);
 			tc->t_tinc_data_rem = 0;
@@ -272,8 +271,7 @@ out:
 }
 
 /* the caller has to hold the sock lock */
-static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp,
-			     enum km_type km)
+static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp)
 {
 	struct rds_tcp_connection *tc = conn->c_transport_data;
 	struct socket *sock = tc->t_sock;
@@ -283,7 +281,6 @@ static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp,
 	/* It's like glib in the kernel! */
 	arg.conn = conn;
 	arg.gfp = gfp;
-	arg.km = km;
 	desc.arg.data = &arg;
 	desc.error = 0;
 	desc.count = 1; /* give more than one skb per call */
@@ -311,7 +308,7 @@ int rds_tcp_recv(struct rds_connection *conn)
 	rdsdebug("recv worker conn %p tc %p sock %p\n", conn, tc, sock);
 
 	lock_sock(sock->sk);
-	ret = rds_tcp_read_sock(conn, GFP_KERNEL, KM_USER0);
+	ret = rds_tcp_read_sock(conn, GFP_KERNEL);
 	release_sock(sock->sk);
 
 	return ret;
@@ -336,7 +333,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
 	ready = tc->t_orig_data_ready;
 	rds_tcp_stats_inc(s_tcp_data_ready_calls);
 
-	if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM)
+	if (rds_tcp_read_sock(conn, GFP_ATOMIC) == -ENOMEM)
 		queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
 out:
 	read_unlock_bh(&sk->sk_callback_lock);
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 2590e91..75b58f8 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -260,6 +260,32 @@ config NET_SCH_INGRESS
 	  To compile this code as a module, choose M here: the
 	  module will be called sch_ingress.
 
+config NET_SCH_PLUG
+	tristate "Plug network traffic until release (PLUG)"
+	---help---
+
+	  This queuing discipline allows userspace to plug/unplug a network
+	  output queue, using the netlink interface.  When it receives an
+	  enqueue command it inserts a plug into the outbound queue that
+	  causes following packets to enqueue until a dequeue command arrives
+	  over netlink, causing the plug to be removed and resuming the normal
+	  packet flow.
+
+	  This module also provides a generic "network output buffering"
+	  functionality (aka output commit), wherein upon arrival of a dequeue
+	  command, only packets up to the first plug are released for delivery.
+	  The Remus HA project uses this module to enable speculative execution
+	  of virtual machines by allowing the generated network output to be rolled
+	  back if needed.
+
+	  For more information, please refer to http://wiki.xensource.com/xenwiki/Remus
+
+	  Say Y here if you are using this kernel for Xen dom0 and
+	  want to protect Xen guests with Remus.
+
+	  To compile this code as a module, choose M here: the
+	  module will be called sch_plug.
+
 comment "Classification"
 
 config NET_CLS
diff --git a/net/sched/Makefile b/net/sched/Makefile
index dc5889c..8cdf4e2 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_NET_SCH_MULTIQ)	+= sch_multiq.o
 obj-$(CONFIG_NET_SCH_ATM)	+= sch_atm.o
 obj-$(CONFIG_NET_SCH_NETEM)	+= sch_netem.o
 obj-$(CONFIG_NET_SCH_DRR)	+= sch_drr.o
+obj-$(CONFIG_NET_SCH_PLUG)	+= sch_plug.o
 obj-$(CONFIG_NET_SCH_MQPRIO)	+= sch_mqprio.o
 obj-$(CONFIG_NET_SCH_CHOKE)	+= sch_choke.o
 obj-$(CONFIG_NET_SCH_QFQ)	+= sch_qfq.o
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index f84fdc3..1afaa28 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -22,9 +22,8 @@
 #include <net/sock.h>
 #include <net/cls_cgroup.h>
 
-static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
-					       struct cgroup *cgrp);
-static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp);
+static void cgrp_destroy(struct cgroup *cgrp);
 static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
 
 struct cgroup_subsys net_cls_subsys = {
@@ -51,8 +50,7 @@ static inline struct cgroup_cls_state *task_cls_state(struct task_struct *p)
 			    struct cgroup_cls_state, css);
 }
 
-static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
-						 struct cgroup *cgrp)
+static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
 {
 	struct cgroup_cls_state *cs;
 
@@ -66,7 +64,7 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
 	return &cs->css;
 }
 
-static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
+static void cgrp_destroy(struct cgroup *cgrp)
 {
 	kfree(cgrp_cls_state(cgrp));
 }
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index e83d61c..5da548f 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -501,9 +501,8 @@ tfifo_dequeue:
 
 		/* if more time remaining? */
 		if (cb->time_to_send <= psched_get_time()) {
-			skb = qdisc_dequeue_tail(sch);
-			if (unlikely(!skb))
-				goto qdisc_dequeue;
+			__skb_unlink(skb, &sch->q);
+			sch->qstats.backlog -= qdisc_pkt_len(skb);
 
 #ifdef CONFIG_NET_CLS_ACT
 			/*
@@ -539,7 +538,6 @@ deliver:
 		qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
 	}
 
-qdisc_dequeue:
 	if (q->qdisc) {
 		skb = q->qdisc->ops->dequeue(q->qdisc);
 		if (skb)
diff --git a/net/sched/sch_plug.c b/net/sched/sch_plug.c
new file mode 100644
index 0000000..89f8fcf
--- /dev/null
+++ b/net/sched/sch_plug.c
@@ -0,0 +1,233 @@
+/*
+ * sch_plug.c Queue traffic until an explicit release command
+ *
+ *             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.
+ *
+ * There are two ways to use this qdisc:
+ * 1. A simple "instantaneous" plug/unplug operation, by issuing an alternating
+ *    sequence of TCQ_PLUG_BUFFER & TCQ_PLUG_RELEASE_INDEFINITE commands.
+ *
+ * 2. For network output buffering (a.k.a output commit) functionality.
+ *    Output commit property is commonly used by applications using checkpoint
+ *    based fault-tolerance to ensure that the checkpoint from which a system
+ *    is being restored is consistent w.r.t outside world.
+ *
+ *    Consider for e.g. Remus - a Virtual Machine checkpointing system,
+ *    wherein a VM is checkpointed, say every 50ms. The checkpoint is replicated
+ *    asynchronously to the backup host, while the VM continues executing the
+ *    next epoch speculatively.
+ *
+ *    The following is a typical sequence of output buffer operations:
+ *       1.At epoch i, start_buffer(i)
+ *       2. At end of epoch i (i.e. after 50ms):
+ *          2.1 Stop VM and take checkpoint(i).
+ *          2.2 start_buffer(i+1) and Resume VM
+ *       3. While speculatively executing epoch(i+1), asynchronously replicate
+ *          checkpoint(i) to backup host.
+ *       4. When checkpoint_ack(i) is received from backup, release_buffer(i)
+ *    Thus, this Qdisc would receive the following sequence of commands:
+ *       TCQ_PLUG_BUFFER (epoch i)
+ *       .. TCQ_PLUG_BUFFER (epoch i+1)
+ *       ....TCQ_PLUG_RELEASE_ONE (epoch i)
+ *       ......TCQ_PLUG_BUFFER (epoch i+2)
+ *       ........
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/pkt_sched.h>
+
+/*
+ * State of the queue, when used for network output buffering:
+ *
+ *                 plug(i+1)            plug(i)          head
+ * ------------------+--------------------+---------------->
+ *                   |                    |
+ *                   |                    |
+ * pkts_current_epoch| pkts_last_epoch    |pkts_to_release
+ * ----------------->|<--------+--------->|+--------------->
+ *                   v                    v
+ *
+ */
+
+struct plug_sched_data {
+	/* If true, the dequeue function releases all packets
+	 * from head to end of the queue. The queue turns into
+	 * a pass-through queue for newly arriving packets.
+	 */
+	bool unplug_indefinite;
+
+	/* Queue Limit in bytes */
+	u32 limit;
+
+	/* Number of packets (output) from the current speculatively
+	 * executing epoch.
+	 */
+	u32 pkts_current_epoch;
+
+	/* Number of packets corresponding to the recently finished
+	 * epoch. These will be released when we receive a
+	 * TCQ_PLUG_RELEASE_ONE command. This command is typically
+	 * issued after committing a checkpoint at the target.
+	 */
+	u32 pkts_last_epoch;
+
+	/*
+	 * Number of packets from the head of the queue, that can
+	 * be released (committed checkpoint).
+	 */
+	u32 pkts_to_release;
+};
+
+static int plug_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+	struct plug_sched_data *q = qdisc_priv(sch);
+
+	if (likely(sch->qstats.backlog + skb->len <= q->limit)) {
+		if (!q->unplug_indefinite)
+			q->pkts_current_epoch++;
+		return qdisc_enqueue_tail(skb, sch);
+	}
+
+	return qdisc_reshape_fail(skb, sch);
+}
+
+static struct sk_buff *plug_dequeue(struct Qdisc *sch)
+{
+	struct plug_sched_data *q = qdisc_priv(sch);
+
+	if (qdisc_is_throttled(sch))
+		return NULL;
+
+	if (!q->unplug_indefinite) {
+		if (!q->pkts_to_release) {
+			/* No more packets to dequeue. Block the queue
+			 * and wait for the next release command.
+			 */
+			qdisc_throttled(sch);
+			return NULL;
+		}
+		q->pkts_to_release--;
+	}
+
+	return qdisc_dequeue_head(sch);
+}
+
+static int plug_init(struct Qdisc *sch, struct nlattr *opt)
+{
+	struct plug_sched_data *q = qdisc_priv(sch);
+
+	q->pkts_current_epoch = 0;
+	q->pkts_last_epoch = 0;
+	q->pkts_to_release = 0;
+	q->unplug_indefinite = false;
+
+	if (opt == NULL) {
+		/* We will set a default limit of 100 pkts (~150kB)
+		 * in case tx_queue_len is not available. The
+		 * default value is completely arbitrary.
+		 */
+		u32 pkt_limit = qdisc_dev(sch)->tx_queue_len ? : 100;
+		q->limit = pkt_limit * psched_mtu(qdisc_dev(sch));
+	} else {
+		struct tc_plug_qopt *ctl = nla_data(opt);
+
+		if (nla_len(opt) < sizeof(*ctl))
+			return -EINVAL;
+
+		q->limit = ctl->limit;
+	}
+
+	qdisc_throttled(sch);
+	return 0;
+}
+
+/* Receives 4 types of messages:
+ * TCQ_PLUG_BUFFER: Inset a plug into the queue and
+ *  buffer any incoming packets
+ * TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue head
+ *   to beginning of the next plug.
+ * TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue.
+ *   Stop buffering packets until the next TCQ_PLUG_BUFFER
+ *   command is received (just act as a pass-thru queue).
+ * TCQ_PLUG_LIMIT: Increase/decrease queue size
+ */
+static int plug_change(struct Qdisc *sch, struct nlattr *opt)
+{
+	struct plug_sched_data *q = qdisc_priv(sch);
+	struct tc_plug_qopt *msg;
+
+	if (opt == NULL)
+		return -EINVAL;
+
+	msg = nla_data(opt);
+	if (nla_len(opt) < sizeof(*msg))
+		return -EINVAL;
+
+	switch (msg->action) {
+	case TCQ_PLUG_BUFFER:
+		/* Save size of the current buffer */
+		q->pkts_last_epoch = q->pkts_current_epoch;
+		q->pkts_current_epoch = 0;
+		if (q->unplug_indefinite)
+			qdisc_throttled(sch);
+		q->unplug_indefinite = false;
+		break;
+	case TCQ_PLUG_RELEASE_ONE:
+		/* Add packets from the last complete buffer to the
+		 * packets to be released set.
+		 */
+		q->pkts_to_release += q->pkts_last_epoch;
+		q->pkts_last_epoch = 0;
+		qdisc_unthrottled(sch);
+		netif_schedule_queue(sch->dev_queue);
+		break;
+	case TCQ_PLUG_RELEASE_INDEFINITE:
+		q->unplug_indefinite = true;
+		q->pkts_to_release = 0;
+		q->pkts_last_epoch = 0;
+		q->pkts_current_epoch = 0;
+		qdisc_unthrottled(sch);
+		netif_schedule_queue(sch->dev_queue);
+		break;
+	case TCQ_PLUG_LIMIT:
+		/* Limit is supplied in bytes */
+		q->limit = msg->limit;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct Qdisc_ops plug_qdisc_ops __read_mostly = {
+	.id          =       "plug",
+	.priv_size   =       sizeof(struct plug_sched_data),
+	.enqueue     =       plug_enqueue,
+	.dequeue     =       plug_dequeue,
+	.peek        =       qdisc_peek_head,
+	.init        =       plug_init,
+	.change      =       plug_change,
+	.owner       =       THIS_MODULE,
+};
+
+static int __init plug_module_init(void)
+{
+	return register_qdisc(&plug_qdisc_ops);
+}
+
+static void __exit plug_module_exit(void)
+{
+	unregister_qdisc(&plug_qdisc_ops);
+}
+module_init(plug_module_init)
+module_exit(plug_module_exit)
+MODULE_LICENSE("GPL");
diff --git a/net/socket.c b/net/socket.c
index 28a96af..784d93a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -479,7 +479,7 @@ static struct socket *sock_alloc(void)
 	inode->i_uid = current_fsuid();
 	inode->i_gid = current_fsgid();
 
-	percpu_add(sockets_in_use, 1);
+	this_cpu_add(sockets_in_use, 1);
 	return sock;
 }
 
@@ -522,7 +522,7 @@ void sock_release(struct socket *sock)
 	if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
 		printk(KERN_ERR "sock_release: fasync list not empty!\n");
 
-	percpu_sub(sockets_in_use, 1);
+	this_cpu_sub(sockets_in_use, 1);
 	if (!sock->file) {
 		iput(SOCK_INODE(sock));
 		return;
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c
index ee77742..d11418f 100644
--- a/net/sunrpc/addr.c
+++ b/net/sunrpc/addr.c
@@ -156,8 +156,9 @@ static size_t rpc_pton4(const char *buf, const size_t buflen,
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
-static int rpc_parse_scope_id(const char *buf, const size_t buflen,
-			      const char *delim, struct sockaddr_in6 *sin6)
+static int rpc_parse_scope_id(struct net *net, const char *buf,
+			      const size_t buflen, const char *delim,
+			      struct sockaddr_in6 *sin6)
 {
 	char *p;
 	size_t len;
@@ -177,7 +178,7 @@ static int rpc_parse_scope_id(const char *buf, const size_t buflen,
 		unsigned long scope_id = 0;
 		struct net_device *dev;
 
-		dev = dev_get_by_name(&init_net, p);
+		dev = dev_get_by_name(net, p);
 		if (dev != NULL) {
 			scope_id = dev->ifindex;
 			dev_put(dev);
@@ -197,7 +198,7 @@ static int rpc_parse_scope_id(const char *buf, const size_t buflen,
 	return 0;
 }
 
-static size_t rpc_pton6(const char *buf, const size_t buflen,
+static size_t rpc_pton6(struct net *net, const char *buf, const size_t buflen,
 			struct sockaddr *sap, const size_t salen)
 {
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
@@ -213,14 +214,14 @@ static size_t rpc_pton6(const char *buf, const size_t buflen,
 	if (in6_pton(buf, buflen, addr, IPV6_SCOPE_DELIMITER, &delim) == 0)
 		return 0;
 
-	if (!rpc_parse_scope_id(buf, buflen, delim, sin6))
+	if (!rpc_parse_scope_id(net, buf, buflen, delim, sin6))
 		return 0;
 
 	sin6->sin6_family = AF_INET6;
 	return sizeof(struct sockaddr_in6);
 }
 #else
-static size_t rpc_pton6(const char *buf, const size_t buflen,
+static size_t rpc_pton6(struct net *net, const char *buf, const size_t buflen,
 			struct sockaddr *sap, const size_t salen)
 {
 	return 0;
@@ -229,6 +230,7 @@ static size_t rpc_pton6(const char *buf, const size_t buflen,
 
 /**
  * rpc_pton - Construct a sockaddr in @sap
+ * @net: applicable network namespace
  * @buf: C string containing presentation format IP address
  * @buflen: length of presentation address in bytes
  * @sap: buffer into which to plant socket address
@@ -241,14 +243,14 @@ static size_t rpc_pton6(const char *buf, const size_t buflen,
  * socket address, if successful.  Returns zero if an error
  * occurred.
  */
-size_t rpc_pton(const char *buf, const size_t buflen,
+size_t rpc_pton(struct net *net, const char *buf, const size_t buflen,
 		struct sockaddr *sap, const size_t salen)
 {
 	unsigned int i;
 
 	for (i = 0; i < buflen; i++)
 		if (buf[i] == ':')
-			return rpc_pton6(buf, buflen, sap, salen);
+			return rpc_pton6(net, buf, buflen, sap, salen);
 	return rpc_pton4(buf, buflen, sap, salen);
 }
 EXPORT_SYMBOL_GPL(rpc_pton);
@@ -295,6 +297,7 @@ char *rpc_sockaddr2uaddr(const struct sockaddr *sap, gfp_t gfp_flags)
 
 /**
  * rpc_uaddr2sockaddr - convert a universal address to a socket address.
+ * @net: applicable network namespace
  * @uaddr: C string containing universal address to convert
  * @uaddr_len: length of universal address string
  * @sap: buffer into which to plant socket address
@@ -306,8 +309,9 @@ char *rpc_sockaddr2uaddr(const struct sockaddr *sap, gfp_t gfp_flags)
  * Returns the size of the socket address if successful; otherwise
  * zero is returned.
  */
-size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
-			  struct sockaddr *sap, const size_t salen)
+size_t rpc_uaddr2sockaddr(struct net *net, const char *uaddr,
+			  const size_t uaddr_len, struct sockaddr *sap,
+			  const size_t salen)
 {
 	char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')];
 	unsigned long portlo, porthi;
@@ -339,7 +343,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
 	port = (unsigned short)((porthi << 8) | portlo);
 
 	*c = '\0';
-	if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
+	if (rpc_pton(net, buf, strlen(buf), sap, salen) == 0)
 		return 0;
 
 	switch (sap->sa_family) {
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index affa631..cb2e564 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -81,7 +81,7 @@ struct gss_auth {
 	 * mechanism (for example, "krb5") and exists for
 	 * backwards-compatibility with older gssd's.
 	 */
-	struct dentry *dentry[2];
+	struct rpc_pipe *pipe[2];
 };
 
 /* pipe_version >= 0 if and only if someone has a pipe open. */
@@ -112,7 +112,7 @@ gss_put_ctx(struct gss_cl_ctx *ctx)
 /* gss_cred_set_ctx:
  * called by gss_upcall_callback and gss_create_upcall in order
  * to set the gss context. The actual exchange of an old context
- * and a new one is protected by the inode->i_lock.
+ * and a new one is protected by the pipe->lock.
  */
 static void
 gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
@@ -251,7 +251,7 @@ struct gss_upcall_msg {
 	struct rpc_pipe_msg msg;
 	struct list_head list;
 	struct gss_auth *auth;
-	struct rpc_inode *inode;
+	struct rpc_pipe *pipe;
 	struct rpc_wait_queue rpc_waitqueue;
 	wait_queue_head_t waitqueue;
 	struct gss_cl_ctx *ctx;
@@ -294,10 +294,10 @@ gss_release_msg(struct gss_upcall_msg *gss_msg)
 }
 
 static struct gss_upcall_msg *
-__gss_find_upcall(struct rpc_inode *rpci, uid_t uid)
+__gss_find_upcall(struct rpc_pipe *pipe, uid_t uid)
 {
 	struct gss_upcall_msg *pos;
-	list_for_each_entry(pos, &rpci->in_downcall, list) {
+	list_for_each_entry(pos, &pipe->in_downcall, list) {
 		if (pos->uid != uid)
 			continue;
 		atomic_inc(&pos->count);
@@ -315,18 +315,17 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid)
 static inline struct gss_upcall_msg *
 gss_add_msg(struct gss_upcall_msg *gss_msg)
 {
-	struct rpc_inode *rpci = gss_msg->inode;
-	struct inode *inode = &rpci->vfs_inode;
+	struct rpc_pipe *pipe = gss_msg->pipe;
 	struct gss_upcall_msg *old;
 
-	spin_lock(&inode->i_lock);
-	old = __gss_find_upcall(rpci, gss_msg->uid);
+	spin_lock(&pipe->lock);
+	old = __gss_find_upcall(pipe, gss_msg->uid);
 	if (old == NULL) {
 		atomic_inc(&gss_msg->count);
-		list_add(&gss_msg->list, &rpci->in_downcall);
+		list_add(&gss_msg->list, &pipe->in_downcall);
 	} else
 		gss_msg = old;
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 	return gss_msg;
 }
 
@@ -342,14 +341,14 @@ __gss_unhash_msg(struct gss_upcall_msg *gss_msg)
 static void
 gss_unhash_msg(struct gss_upcall_msg *gss_msg)
 {
-	struct inode *inode = &gss_msg->inode->vfs_inode;
+	struct rpc_pipe *pipe = gss_msg->pipe;
 
 	if (list_empty(&gss_msg->list))
 		return;
-	spin_lock(&inode->i_lock);
+	spin_lock(&pipe->lock);
 	if (!list_empty(&gss_msg->list))
 		__gss_unhash_msg(gss_msg);
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 }
 
 static void
@@ -376,11 +375,11 @@ gss_upcall_callback(struct rpc_task *task)
 	struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
 			struct gss_cred, gc_base);
 	struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
-	struct inode *inode = &gss_msg->inode->vfs_inode;
+	struct rpc_pipe *pipe = gss_msg->pipe;
 
-	spin_lock(&inode->i_lock);
+	spin_lock(&pipe->lock);
 	gss_handle_downcall_result(gss_cred, gss_msg);
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 	task->tk_status = gss_msg->msg.errno;
 	gss_release_msg(gss_msg);
 }
@@ -450,7 +449,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
 		kfree(gss_msg);
 		return ERR_PTR(vers);
 	}
-	gss_msg->inode = RPC_I(gss_auth->dentry[vers]->d_inode);
+	gss_msg->pipe = gss_auth->pipe[vers];
 	INIT_LIST_HEAD(&gss_msg->list);
 	rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
 	init_waitqueue_head(&gss_msg->waitqueue);
@@ -474,8 +473,7 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr
 		return gss_new;
 	gss_msg = gss_add_msg(gss_new);
 	if (gss_msg == gss_new) {
-		struct inode *inode = &gss_new->inode->vfs_inode;
-		int res = rpc_queue_upcall(inode, &gss_new->msg);
+		int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
 		if (res) {
 			gss_unhash_msg(gss_new);
 			gss_msg = ERR_PTR(res);
@@ -506,7 +504,7 @@ gss_refresh_upcall(struct rpc_task *task)
 	struct gss_cred *gss_cred = container_of(cred,
 			struct gss_cred, gc_base);
 	struct gss_upcall_msg *gss_msg;
-	struct inode *inode;
+	struct rpc_pipe *pipe;
 	int err = 0;
 
 	dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
@@ -524,8 +522,8 @@ gss_refresh_upcall(struct rpc_task *task)
 		err = PTR_ERR(gss_msg);
 		goto out;
 	}
-	inode = &gss_msg->inode->vfs_inode;
-	spin_lock(&inode->i_lock);
+	pipe = gss_msg->pipe;
+	spin_lock(&pipe->lock);
 	if (gss_cred->gc_upcall != NULL)
 		rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
 	else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
@@ -538,7 +536,7 @@ gss_refresh_upcall(struct rpc_task *task)
 		gss_handle_downcall_result(gss_cred, gss_msg);
 		err = gss_msg->msg.errno;
 	}
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 	gss_release_msg(gss_msg);
 out:
 	dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n",
@@ -549,7 +547,7 @@ out:
 static inline int
 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
 {
-	struct inode *inode;
+	struct rpc_pipe *pipe;
 	struct rpc_cred *cred = &gss_cred->gc_base;
 	struct gss_upcall_msg *gss_msg;
 	DEFINE_WAIT(wait);
@@ -573,14 +571,14 @@ retry:
 		err = PTR_ERR(gss_msg);
 		goto out;
 	}
-	inode = &gss_msg->inode->vfs_inode;
+	pipe = gss_msg->pipe;
 	for (;;) {
 		prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE);
-		spin_lock(&inode->i_lock);
+		spin_lock(&pipe->lock);
 		if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
 			break;
 		}
-		spin_unlock(&inode->i_lock);
+		spin_unlock(&pipe->lock);
 		if (fatal_signal_pending(current)) {
 			err = -ERESTARTSYS;
 			goto out_intr;
@@ -591,7 +589,7 @@ retry:
 		gss_cred_set_ctx(cred, gss_msg->ctx);
 	else
 		err = gss_msg->msg.errno;
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 out_intr:
 	finish_wait(&gss_msg->waitqueue, &wait);
 	gss_release_msg(gss_msg);
@@ -609,7 +607,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 	const void *p, *end;
 	void *buf;
 	struct gss_upcall_msg *gss_msg;
-	struct inode *inode = filp->f_path.dentry->d_inode;
+	struct rpc_pipe *pipe = RPC_I(filp->f_dentry->d_inode)->pipe;
 	struct gss_cl_ctx *ctx;
 	uid_t uid;
 	ssize_t err = -EFBIG;
@@ -639,14 +637,14 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 
 	err = -ENOENT;
 	/* Find a matching upcall */
-	spin_lock(&inode->i_lock);
-	gss_msg = __gss_find_upcall(RPC_I(inode), uid);
+	spin_lock(&pipe->lock);
+	gss_msg = __gss_find_upcall(pipe, uid);
 	if (gss_msg == NULL) {
-		spin_unlock(&inode->i_lock);
+		spin_unlock(&pipe->lock);
 		goto err_put_ctx;
 	}
 	list_del_init(&gss_msg->list);
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 
 	p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
 	if (IS_ERR(p)) {
@@ -674,9 +672,9 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 	err = mlen;
 
 err_release_msg:
-	spin_lock(&inode->i_lock);
+	spin_lock(&pipe->lock);
 	__gss_unhash_msg(gss_msg);
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 	gss_release_msg(gss_msg);
 err_put_ctx:
 	gss_put_ctx(ctx);
@@ -722,23 +720,23 @@ static int gss_pipe_open_v1(struct inode *inode)
 static void
 gss_pipe_release(struct inode *inode)
 {
-	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	struct gss_upcall_msg *gss_msg;
 
 restart:
-	spin_lock(&inode->i_lock);
-	list_for_each_entry(gss_msg, &rpci->in_downcall, list) {
+	spin_lock(&pipe->lock);
+	list_for_each_entry(gss_msg, &pipe->in_downcall, list) {
 
 		if (!list_empty(&gss_msg->msg.list))
 			continue;
 		gss_msg->msg.errno = -EPIPE;
 		atomic_inc(&gss_msg->count);
 		__gss_unhash_msg(gss_msg);
-		spin_unlock(&inode->i_lock);
+		spin_unlock(&pipe->lock);
 		gss_release_msg(gss_msg);
 		goto restart;
 	}
-	spin_unlock(&inode->i_lock);
+	spin_unlock(&pipe->lock);
 
 	put_pipe_version();
 }
@@ -759,6 +757,75 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
 	}
 }
 
+static void gss_pipes_dentries_destroy(struct rpc_auth *auth)
+{
+	struct gss_auth *gss_auth;
+
+	gss_auth = container_of(auth, struct gss_auth, rpc_auth);
+	if (gss_auth->pipe[0]->dentry)
+		rpc_unlink(gss_auth->pipe[0]->dentry);
+	if (gss_auth->pipe[1]->dentry)
+		rpc_unlink(gss_auth->pipe[1]->dentry);
+}
+
+static int gss_pipes_dentries_create(struct rpc_auth *auth)
+{
+	int err;
+	struct gss_auth *gss_auth;
+	struct rpc_clnt *clnt;
+
+	gss_auth = container_of(auth, struct gss_auth, rpc_auth);
+	clnt = gss_auth->client;
+
+	gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
+						      "gssd",
+						      clnt, gss_auth->pipe[1]);
+	if (IS_ERR(gss_auth->pipe[1]->dentry))
+		return PTR_ERR(gss_auth->pipe[1]->dentry);
+	gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
+						      gss_auth->mech->gm_name,
+						      clnt, gss_auth->pipe[0]);
+	if (IS_ERR(gss_auth->pipe[0]->dentry)) {
+		err = PTR_ERR(gss_auth->pipe[0]->dentry);
+		goto err_unlink_pipe_1;
+	}
+	return 0;
+
+err_unlink_pipe_1:
+	rpc_unlink(gss_auth->pipe[1]->dentry);
+	return err;
+}
+
+static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt,
+					   struct rpc_auth *auth)
+{
+	struct net *net = clnt->cl_xprt->xprt_net;
+	struct super_block *sb;
+
+	sb = rpc_get_sb_net(net);
+	if (sb) {
+		if (clnt->cl_dentry)
+			gss_pipes_dentries_destroy(auth);
+		rpc_put_sb_net(net);
+	}
+}
+
+static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt,
+					 struct rpc_auth *auth)
+{
+	struct net *net = clnt->cl_xprt->xprt_net;
+	struct super_block *sb;
+	int err = 0;
+
+	sb = rpc_get_sb_net(net);
+	if (sb) {
+		if (clnt->cl_dentry)
+			err = gss_pipes_dentries_create(auth);
+		rpc_put_sb_net(net);
+	}
+	return err;
+}
+
 /*
  * NOTE: we have the opportunity to use different
  * parameters based on the input flavor (which must be a pseudoflavor)
@@ -801,32 +868,33 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
 	 * that we supported only the old pipe.  So we instead create
 	 * the new pipe first.
 	 */
-	gss_auth->dentry[1] = rpc_mkpipe(clnt->cl_path.dentry,
-					 "gssd",
-					 clnt, &gss_upcall_ops_v1,
-					 RPC_PIPE_WAIT_FOR_OPEN);
-	if (IS_ERR(gss_auth->dentry[1])) {
-		err = PTR_ERR(gss_auth->dentry[1]);
+	gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1,
+					    RPC_PIPE_WAIT_FOR_OPEN);
+	if (IS_ERR(gss_auth->pipe[1])) {
+		err = PTR_ERR(gss_auth->pipe[1]);
 		goto err_put_mech;
 	}
 
-	gss_auth->dentry[0] = rpc_mkpipe(clnt->cl_path.dentry,
-					 gss_auth->mech->gm_name,
-					 clnt, &gss_upcall_ops_v0,
-					 RPC_PIPE_WAIT_FOR_OPEN);
-	if (IS_ERR(gss_auth->dentry[0])) {
-		err = PTR_ERR(gss_auth->dentry[0]);
-		goto err_unlink_pipe_1;
+	gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0,
+					    RPC_PIPE_WAIT_FOR_OPEN);
+	if (IS_ERR(gss_auth->pipe[0])) {
+		err = PTR_ERR(gss_auth->pipe[0]);
+		goto err_destroy_pipe_1;
 	}
+	err = gss_pipes_dentries_create_net(clnt, auth);
+	if (err)
+		goto err_destroy_pipe_0;
 	err = rpcauth_init_credcache(auth);
 	if (err)
-		goto err_unlink_pipe_0;
+		goto err_unlink_pipes;
 
 	return auth;
-err_unlink_pipe_0:
-	rpc_unlink(gss_auth->dentry[0]);
-err_unlink_pipe_1:
-	rpc_unlink(gss_auth->dentry[1]);
+err_unlink_pipes:
+	gss_pipes_dentries_destroy_net(clnt, auth);
+err_destroy_pipe_0:
+	rpc_destroy_pipe_data(gss_auth->pipe[0]);
+err_destroy_pipe_1:
+	rpc_destroy_pipe_data(gss_auth->pipe[1]);
 err_put_mech:
 	gss_mech_put(gss_auth->mech);
 err_free:
@@ -839,8 +907,9 @@ out_dec:
 static void
 gss_free(struct gss_auth *gss_auth)
 {
-	rpc_unlink(gss_auth->dentry[1]);
-	rpc_unlink(gss_auth->dentry[0]);
+	gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth);
+	rpc_destroy_pipe_data(gss_auth->pipe[0]);
+	rpc_destroy_pipe_data(gss_auth->pipe[1]);
 	gss_mech_put(gss_auth->mech);
 
 	kfree(gss_auth);
@@ -1547,7 +1616,9 @@ static const struct rpc_authops authgss_ops = {
 	.create		= gss_create,
 	.destroy	= gss_destroy,
 	.lookup_cred	= gss_lookup_cred,
-	.crcreate	= gss_create_cred
+	.crcreate	= gss_create_cred,
+	.pipes_create	= gss_pipes_dentries_create,
+	.pipes_destroy	= gss_pipes_dentries_destroy,
 };
 
 static const struct rpc_credops gss_credops = {
@@ -1591,6 +1662,21 @@ static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
 	.release_pipe	= gss_pipe_release,
 };
 
+static __net_init int rpcsec_gss_init_net(struct net *net)
+{
+	return gss_svc_init_net(net);
+}
+
+static __net_exit void rpcsec_gss_exit_net(struct net *net)
+{
+	gss_svc_shutdown_net(net);
+}
+
+static struct pernet_operations rpcsec_gss_net_ops = {
+	.init = rpcsec_gss_init_net,
+	.exit = rpcsec_gss_exit_net,
+};
+
 /*
  * Initialize RPCSEC_GSS module
  */
@@ -1604,8 +1690,13 @@ static int __init init_rpcsec_gss(void)
 	err = gss_svc_init();
 	if (err)
 		goto out_unregister;
+	err = register_pernet_subsys(&rpcsec_gss_net_ops);
+	if (err)
+		goto out_svc_exit;
 	rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
 	return 0;
+out_svc_exit:
+	gss_svc_shutdown();
 out_unregister:
 	rpcauth_unregister(&authgss_ops);
 out:
@@ -1614,6 +1705,7 @@ out:
 
 static void __exit exit_rpcsec_gss(void)
 {
+	unregister_pernet_subsys(&rpcsec_gss_net_ops);
 	gss_svc_shutdown();
 	rpcauth_unregister(&authgss_ops);
 	rcu_barrier(); /* Wait for completion of call_rcu()'s */
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index 2763e3e..38f388c 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -82,9 +82,9 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
 					>>PAGE_CACHE_SHIFT;
 		unsigned int offset = (buf->page_base + len - 1)
 					& (PAGE_CACHE_SIZE - 1);
-		ptr = kmap_atomic(buf->pages[last], KM_USER0);
+		ptr = kmap_atomic(buf->pages[last]);
 		pad = *(ptr + offset);
-		kunmap_atomic(ptr, KM_USER0);
+		kunmap_atomic(ptr);
 		goto out;
 	} else
 		len -= buf->page_len;
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 8d0f7d3..1600cfb 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -48,6 +48,8 @@
 #include <linux/sunrpc/svcauth_gss.h>
 #include <linux/sunrpc/cache.h>
 
+#include "../netns.h"
+
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_AUTH
 #endif
@@ -75,10 +77,8 @@ struct rsi {
 	int			major_status, minor_status;
 };
 
-static struct cache_head *rsi_table[RSI_HASHMAX];
-static struct cache_detail rsi_cache;
-static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
-static struct rsi *rsi_lookup(struct rsi *item);
+static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
+static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item);
 
 static void rsi_free(struct rsi *rsii)
 {
@@ -216,7 +216,7 @@ static int rsi_parse(struct cache_detail *cd,
 	if (dup_to_netobj(&rsii.in_token, buf, len))
 		goto out;
 
-	rsip = rsi_lookup(&rsii);
+	rsip = rsi_lookup(cd, &rsii);
 	if (!rsip)
 		goto out;
 
@@ -258,21 +258,20 @@ static int rsi_parse(struct cache_detail *cd,
 	if (dup_to_netobj(&rsii.out_token, buf, len))
 		goto out;
 	rsii.h.expiry_time = expiry;
-	rsip = rsi_update(&rsii, rsip);
+	rsip = rsi_update(cd, &rsii, rsip);
 	status = 0;
 out:
 	rsi_free(&rsii);
 	if (rsip)
-		cache_put(&rsip->h, &rsi_cache);
+		cache_put(&rsip->h, cd);
 	else
 		status = -ENOMEM;
 	return status;
 }
 
-static struct cache_detail rsi_cache = {
+static struct cache_detail rsi_cache_template = {
 	.owner		= THIS_MODULE,
 	.hash_size	= RSI_HASHMAX,
-	.hash_table     = rsi_table,
 	.name           = "auth.rpcsec.init",
 	.cache_put      = rsi_put,
 	.cache_upcall   = rsi_upcall,
@@ -283,24 +282,24 @@ static struct cache_detail rsi_cache = {
 	.alloc		= rsi_alloc,
 };
 
-static struct rsi *rsi_lookup(struct rsi *item)
+static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
 {
 	struct cache_head *ch;
 	int hash = rsi_hash(item);
 
-	ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash);
+	ch = sunrpc_cache_lookup(cd, &item->h, hash);
 	if (ch)
 		return container_of(ch, struct rsi, h);
 	else
 		return NULL;
 }
 
-static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
+static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old)
 {
 	struct cache_head *ch;
 	int hash = rsi_hash(new);
 
-	ch = sunrpc_cache_update(&rsi_cache, &new->h,
+	ch = sunrpc_cache_update(cd, &new->h,
 				 &old->h, hash);
 	if (ch)
 		return container_of(ch, struct rsi, h);
@@ -339,10 +338,8 @@ struct rsc {
 	char			*client_name;
 };
 
-static struct cache_head *rsc_table[RSC_HASHMAX];
-static struct cache_detail rsc_cache;
-static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
-static struct rsc *rsc_lookup(struct rsc *item);
+static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
+static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item);
 
 static void rsc_free(struct rsc *rsci)
 {
@@ -444,7 +441,7 @@ static int rsc_parse(struct cache_detail *cd,
 	if (expiry == 0)
 		goto out;
 
-	rscp = rsc_lookup(&rsci);
+	rscp = rsc_lookup(cd, &rsci);
 	if (!rscp)
 		goto out;
 
@@ -506,22 +503,21 @@ static int rsc_parse(struct cache_detail *cd,
 
 	}
 	rsci.h.expiry_time = expiry;
-	rscp = rsc_update(&rsci, rscp);
+	rscp = rsc_update(cd, &rsci, rscp);
 	status = 0;
 out:
 	gss_mech_put(gm);
 	rsc_free(&rsci);
 	if (rscp)
-		cache_put(&rscp->h, &rsc_cache);
+		cache_put(&rscp->h, cd);
 	else
 		status = -ENOMEM;
 	return status;
 }
 
-static struct cache_detail rsc_cache = {
+static struct cache_detail rsc_cache_template = {
 	.owner		= THIS_MODULE,
 	.hash_size	= RSC_HASHMAX,
-	.hash_table	= rsc_table,
 	.name		= "auth.rpcsec.context",
 	.cache_put	= rsc_put,
 	.cache_parse	= rsc_parse,
@@ -531,24 +527,24 @@ static struct cache_detail rsc_cache = {
 	.alloc		= rsc_alloc,
 };
 
-static struct rsc *rsc_lookup(struct rsc *item)
+static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
 {
 	struct cache_head *ch;
 	int hash = rsc_hash(item);
 
-	ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
+	ch = sunrpc_cache_lookup(cd, &item->h, hash);
 	if (ch)
 		return container_of(ch, struct rsc, h);
 	else
 		return NULL;
 }
 
-static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
+static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old)
 {
 	struct cache_head *ch;
 	int hash = rsc_hash(new);
 
-	ch = sunrpc_cache_update(&rsc_cache, &new->h,
+	ch = sunrpc_cache_update(cd, &new->h,
 				 &old->h, hash);
 	if (ch)
 		return container_of(ch, struct rsc, h);
@@ -558,7 +554,7 @@ static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
 
 
 static struct rsc *
-gss_svc_searchbyctx(struct xdr_netobj *handle)
+gss_svc_searchbyctx(struct cache_detail *cd, struct xdr_netobj *handle)
 {
 	struct rsc rsci;
 	struct rsc *found;
@@ -566,11 +562,11 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
 	memset(&rsci, 0, sizeof(rsci));
 	if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
 		return NULL;
-	found = rsc_lookup(&rsci);
+	found = rsc_lookup(cd, &rsci);
 	rsc_free(&rsci);
 	if (!found)
 		return NULL;
-	if (cache_check(&rsc_cache, &found->h, NULL))
+	if (cache_check(cd, &found->h, NULL))
 		return NULL;
 	return found;
 }
@@ -968,20 +964,20 @@ svcauth_gss_set_client(struct svc_rqst *rqstp)
 }
 
 static inline int
-gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
+gss_write_init_verf(struct cache_detail *cd, struct svc_rqst *rqstp, struct rsi *rsip)
 {
 	struct rsc *rsci;
 	int        rc;
 
 	if (rsip->major_status != GSS_S_COMPLETE)
 		return gss_write_null_verf(rqstp);
-	rsci = gss_svc_searchbyctx(&rsip->out_handle);
+	rsci = gss_svc_searchbyctx(cd, &rsip->out_handle);
 	if (rsci == NULL) {
 		rsip->major_status = GSS_S_NO_CONTEXT;
 		return gss_write_null_verf(rqstp);
 	}
 	rc = gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
-	cache_put(&rsci->h, &rsc_cache);
+	cache_put(&rsci->h, cd);
 	return rc;
 }
 
@@ -1000,6 +996,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
 	struct xdr_netobj tmpobj;
 	struct rsi *rsip, rsikey;
 	int ret;
+	struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
 
 	/* Read the verifier; should be NULL: */
 	*authp = rpc_autherr_badverf;
@@ -1028,17 +1025,17 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
 	}
 
 	/* Perform upcall, or find upcall result: */
-	rsip = rsi_lookup(&rsikey);
+	rsip = rsi_lookup(sn->rsi_cache, &rsikey);
 	rsi_free(&rsikey);
 	if (!rsip)
 		return SVC_CLOSE;
-	if (cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
+	if (cache_check(sn->rsi_cache, &rsip->h, &rqstp->rq_chandle) < 0)
 		/* No upcall result: */
 		return SVC_CLOSE;
 
 	ret = SVC_CLOSE;
 	/* Got an answer to the upcall; use it: */
-	if (gss_write_init_verf(rqstp, rsip))
+	if (gss_write_init_verf(sn->rsc_cache, rqstp, rsip))
 		goto out;
 	if (resv->iov_len + 4 > PAGE_SIZE)
 		goto out;
@@ -1055,7 +1052,7 @@ static int svcauth_gss_handle_init(struct svc_rqst *rqstp,
 
 	ret = SVC_COMPLETE;
 out:
-	cache_put(&rsip->h, &rsi_cache);
+	cache_put(&rsip->h, sn->rsi_cache);
 	return ret;
 }
 
@@ -1079,6 +1076,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
 	__be32		*rpcstart;
 	__be32		*reject_stat = resv->iov_base + resv->iov_len;
 	int		ret;
+	struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
 
 	dprintk("RPC:       svcauth_gss: argv->iov_len = %zd\n",
 			argv->iov_len);
@@ -1129,7 +1127,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
 	case RPC_GSS_PROC_DESTROY:
 		/* Look up the context, and check the verifier: */
 		*authp = rpcsec_gsserr_credproblem;
-		rsci = gss_svc_searchbyctx(&gc->gc_ctx);
+		rsci = gss_svc_searchbyctx(sn->rsc_cache, &gc->gc_ctx);
 		if (!rsci)
 			goto auth_err;
 		switch (gss_verify_header(rqstp, rsci, rpcstart, gc, authp)) {
@@ -1209,7 +1207,7 @@ drop:
 	ret = SVC_DROP;
 out:
 	if (rsci)
-		cache_put(&rsci->h, &rsc_cache);
+		cache_put(&rsci->h, sn->rsc_cache);
 	return ret;
 }
 
@@ -1362,6 +1360,7 @@ svcauth_gss_release(struct svc_rqst *rqstp)
 	struct rpc_gss_wire_cred *gc = &gsd->clcred;
 	struct xdr_buf *resbuf = &rqstp->rq_res;
 	int stat = -EINVAL;
+	struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
 
 	if (gc->gc_proc != RPC_GSS_PROC_DATA)
 		goto out;
@@ -1404,7 +1403,7 @@ out_err:
 		put_group_info(rqstp->rq_cred.cr_group_info);
 	rqstp->rq_cred.cr_group_info = NULL;
 	if (gsd->rsci)
-		cache_put(&gsd->rsci->h, &rsc_cache);
+		cache_put(&gsd->rsci->h, sn->rsc_cache);
 	gsd->rsci = NULL;
 
 	return stat;
@@ -1429,30 +1428,96 @@ static struct auth_ops svcauthops_gss = {
 	.set_client	= svcauth_gss_set_client,
 };
 
+static int rsi_cache_create_net(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd;
+	int err;
+
+	cd = cache_create_net(&rsi_cache_template, net);
+	if (IS_ERR(cd))
+		return PTR_ERR(cd);
+	err = cache_register_net(cd, net);
+	if (err) {
+		cache_destroy_net(cd, net);
+		return err;
+	}
+	sn->rsi_cache = cd;
+	return 0;
+}
+
+static void rsi_cache_destroy_net(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd = sn->rsi_cache;
+
+	sn->rsi_cache = NULL;
+	cache_purge(cd);
+	cache_unregister_net(cd, net);
+	cache_destroy_net(cd, net);
+}
+
+static int rsc_cache_create_net(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd;
+	int err;
+
+	cd = cache_create_net(&rsc_cache_template, net);
+	if (IS_ERR(cd))
+		return PTR_ERR(cd);
+	err = cache_register_net(cd, net);
+	if (err) {
+		cache_destroy_net(cd, net);
+		return err;
+	}
+	sn->rsc_cache = cd;
+	return 0;
+}
+
+static void rsc_cache_destroy_net(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd = sn->rsc_cache;
+
+	sn->rsc_cache = NULL;
+	cache_purge(cd);
+	cache_unregister_net(cd, net);
+	cache_destroy_net(cd, net);
+}
+
 int
-gss_svc_init(void)
+gss_svc_init_net(struct net *net)
 {
-	int rv = svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
+	int rv;
+
+	rv = rsc_cache_create_net(net);
 	if (rv)
 		return rv;
-	rv = cache_register(&rsc_cache);
+	rv = rsi_cache_create_net(net);
 	if (rv)
 		goto out1;
-	rv = cache_register(&rsi_cache);
-	if (rv)
-		goto out2;
 	return 0;
-out2:
-	cache_unregister(&rsc_cache);
 out1:
-	svc_auth_unregister(RPC_AUTH_GSS);
+	rsc_cache_destroy_net(net);
 	return rv;
 }
 
 void
+gss_svc_shutdown_net(struct net *net)
+{
+	rsi_cache_destroy_net(net);
+	rsc_cache_destroy_net(net);
+}
+
+int
+gss_svc_init(void)
+{
+	return svc_auth_register(RPC_AUTH_GSS, &svcauthops_gss);
+}
+
+void
 gss_svc_shutdown(void)
 {
-	cache_unregister(&rsc_cache);
-	cache_unregister(&rsi_cache);
 	svc_auth_unregister(RPC_AUTH_GSS);
 }
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 465df9a..de0b0f3 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -344,7 +344,7 @@ static int current_index;
 static void do_cache_clean(struct work_struct *work);
 static struct delayed_work cache_cleaner;
 
-static void sunrpc_init_cache_detail(struct cache_detail *cd)
+void sunrpc_init_cache_detail(struct cache_detail *cd)
 {
 	rwlock_init(&cd->hash_lock);
 	INIT_LIST_HEAD(&cd->queue);
@@ -360,8 +360,9 @@ static void sunrpc_init_cache_detail(struct cache_detail *cd)
 	/* start the cleaning process */
 	schedule_delayed_work(&cache_cleaner, 0);
 }
+EXPORT_SYMBOL_GPL(sunrpc_init_cache_detail);
 
-static void sunrpc_destroy_cache_detail(struct cache_detail *cd)
+void sunrpc_destroy_cache_detail(struct cache_detail *cd)
 {
 	cache_purge(cd);
 	spin_lock(&cache_list_lock);
@@ -384,6 +385,7 @@ static void sunrpc_destroy_cache_detail(struct cache_detail *cd)
 out:
 	printk(KERN_ERR "nfsd: failed to unregister %s cache\n", cd->name);
 }
+EXPORT_SYMBOL_GPL(sunrpc_destroy_cache_detail);
 
 /* clean cache tries to find something to clean
  * and cleans it.
@@ -828,6 +830,8 @@ static ssize_t cache_do_downcall(char *kaddr, const char __user *buf,
 {
 	ssize_t ret;
 
+	if (count == 0)
+		return -EINVAL;
 	if (copy_from_user(kaddr, buf, count))
 		return -EFAULT;
 	kaddr[count] = '\0';
@@ -1643,12 +1647,6 @@ int cache_register_net(struct cache_detail *cd, struct net *net)
 }
 EXPORT_SYMBOL_GPL(cache_register_net);
 
-int cache_register(struct cache_detail *cd)
-{
-	return cache_register_net(cd, &init_net);
-}
-EXPORT_SYMBOL_GPL(cache_register);
-
 void cache_unregister_net(struct cache_detail *cd, struct net *net)
 {
 	remove_cache_proc_entries(cd, net);
@@ -1656,11 +1654,31 @@ void cache_unregister_net(struct cache_detail *cd, struct net *net)
 }
 EXPORT_SYMBOL_GPL(cache_unregister_net);
 
-void cache_unregister(struct cache_detail *cd)
+struct cache_detail *cache_create_net(struct cache_detail *tmpl, struct net *net)
+{
+	struct cache_detail *cd;
+
+	cd = kmemdup(tmpl, sizeof(struct cache_detail), GFP_KERNEL);
+	if (cd == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	cd->hash_table = kzalloc(cd->hash_size * sizeof(struct cache_head *),
+				 GFP_KERNEL);
+	if (cd->hash_table == NULL) {
+		kfree(cd);
+		return ERR_PTR(-ENOMEM);
+	}
+	cd->net = net;
+	return cd;
+}
+EXPORT_SYMBOL_GPL(cache_create_net);
+
+void cache_destroy_net(struct cache_detail *cd, struct net *net)
 {
-	cache_unregister_net(cd, &init_net);
+	kfree(cd->hash_table);
+	kfree(cd);
 }
-EXPORT_SYMBOL_GPL(cache_unregister);
+EXPORT_SYMBOL_GPL(cache_destroy_net);
 
 static ssize_t cache_read_pipefs(struct file *filp, char __user *buf,
 				 size_t count, loff_t *ppos)
@@ -1787,17 +1805,14 @@ int sunrpc_cache_register_pipefs(struct dentry *parent,
 	struct dentry *dir;
 	int ret = 0;
 
-	sunrpc_init_cache_detail(cd);
 	q.name = name;
 	q.len = strlen(name);
 	q.hash = full_name_hash(q.name, q.len);
 	dir = rpc_create_cache_dir(parent, &q, umode, cd);
 	if (!IS_ERR(dir))
 		cd->u.pipefs.dir = dir;
-	else {
-		sunrpc_destroy_cache_detail(cd);
+	else
 		ret = PTR_ERR(dir);
-	}
 	return ret;
 }
 EXPORT_SYMBOL_GPL(sunrpc_cache_register_pipefs);
@@ -1806,7 +1821,6 @@ void sunrpc_cache_unregister_pipefs(struct cache_detail *cd)
 {
 	rpc_remove_cache_dir(cd->u.pipefs.dir);
 	cd->u.pipefs.dir = NULL;
-	sunrpc_destroy_cache_detail(cd);
 }
 EXPORT_SYMBOL_GPL(sunrpc_cache_unregister_pipefs);
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index f0268ea..bb7ed2f3 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -36,8 +36,10 @@
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/metrics.h>
 #include <linux/sunrpc/bc_xprt.h>
+#include <trace/events/sunrpc.h>
 
 #include "sunrpc.h"
+#include "netns.h"
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_CALL
@@ -50,8 +52,6 @@
 /*
  * All RPC clients are linked into this list
  */
-static LIST_HEAD(all_clients);
-static DEFINE_SPINLOCK(rpc_client_lock);
 
 static DECLARE_WAIT_QUEUE_HEAD(destroy_wait);
 
@@ -81,70 +81,166 @@ static int	rpc_ping(struct rpc_clnt *clnt);
 
 static void rpc_register_client(struct rpc_clnt *clnt)
 {
-	spin_lock(&rpc_client_lock);
-	list_add(&clnt->cl_clients, &all_clients);
-	spin_unlock(&rpc_client_lock);
+	struct sunrpc_net *sn = net_generic(clnt->cl_xprt->xprt_net, sunrpc_net_id);
+
+	spin_lock(&sn->rpc_client_lock);
+	list_add(&clnt->cl_clients, &sn->all_clients);
+	spin_unlock(&sn->rpc_client_lock);
 }
 
 static void rpc_unregister_client(struct rpc_clnt *clnt)
 {
-	spin_lock(&rpc_client_lock);
+	struct sunrpc_net *sn = net_generic(clnt->cl_xprt->xprt_net, sunrpc_net_id);
+
+	spin_lock(&sn->rpc_client_lock);
 	list_del(&clnt->cl_clients);
-	spin_unlock(&rpc_client_lock);
+	spin_unlock(&sn->rpc_client_lock);
 }
 
-static int
-rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
+static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
+{
+	if (clnt->cl_dentry) {
+		if (clnt->cl_auth && clnt->cl_auth->au_ops->pipes_destroy)
+			clnt->cl_auth->au_ops->pipes_destroy(clnt->cl_auth);
+		rpc_remove_client_dir(clnt->cl_dentry);
+	}
+	clnt->cl_dentry = NULL;
+}
+
+static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
+{
+	struct super_block *pipefs_sb;
+
+	pipefs_sb = rpc_get_sb_net(clnt->cl_xprt->xprt_net);
+	if (pipefs_sb) {
+		__rpc_clnt_remove_pipedir(clnt);
+		rpc_put_sb_net(clnt->cl_xprt->xprt_net);
+	}
+}
+
+static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
+				    struct rpc_clnt *clnt,
+				    const char *dir_name)
 {
 	static uint32_t clntid;
-	struct path path, dir;
 	char name[15];
 	struct qstr q = {
 		.name = name,
 	};
+	struct dentry *dir, *dentry;
 	int error;
 
-	clnt->cl_path.mnt = ERR_PTR(-ENOENT);
-	clnt->cl_path.dentry = ERR_PTR(-ENOENT);
-	if (dir_name == NULL)
-		return 0;
-
-	path.mnt = rpc_get_mount();
-	if (IS_ERR(path.mnt))
-		return PTR_ERR(path.mnt);
-	error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &dir);
-	if (error)
-		goto err;
-
+	dir = rpc_d_lookup_sb(sb, dir_name);
+	if (dir == NULL)
+		return dir;
 	for (;;) {
 		q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
 		name[sizeof(name) - 1] = '\0';
 		q.hash = full_name_hash(q.name, q.len);
-		path.dentry = rpc_create_client_dir(dir.dentry, &q, clnt);
-		if (!IS_ERR(path.dentry))
+		dentry = rpc_create_client_dir(dir, &q, clnt);
+		if (!IS_ERR(dentry))
 			break;
-		error = PTR_ERR(path.dentry);
+		error = PTR_ERR(dentry);
 		if (error != -EEXIST) {
 			printk(KERN_INFO "RPC: Couldn't create pipefs entry"
 					" %s/%s, error %d\n",
 					dir_name, name, error);
-			goto err_path_put;
+			break;
 		}
 	}
-	path_put(&dir);
-	clnt->cl_path = path;
+	dput(dir);
+	return dentry;
+}
+
+static int
+rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name)
+{
+	struct super_block *pipefs_sb;
+	struct dentry *dentry;
+
+	clnt->cl_dentry = NULL;
+	if (dir_name == NULL)
+		return 0;
+	pipefs_sb = rpc_get_sb_net(clnt->cl_xprt->xprt_net);
+	if (!pipefs_sb)
+		return 0;
+	dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
+	rpc_put_sb_net(clnt->cl_xprt->xprt_net);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+	clnt->cl_dentry = dentry;
 	return 0;
-err_path_put:
-	path_put(&dir);
-err:
-	rpc_put_mount();
+}
+
+static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
+				struct super_block *sb)
+{
+	struct dentry *dentry;
+	int err = 0;
+
+	switch (event) {
+	case RPC_PIPEFS_MOUNT:
+		if (clnt->cl_program->pipe_dir_name == NULL)
+			break;
+		dentry = rpc_setup_pipedir_sb(sb, clnt,
+					      clnt->cl_program->pipe_dir_name);
+		BUG_ON(dentry == NULL);
+		if (IS_ERR(dentry))
+			return PTR_ERR(dentry);
+		clnt->cl_dentry = dentry;
+		if (clnt->cl_auth->au_ops->pipes_create) {
+			err = clnt->cl_auth->au_ops->pipes_create(clnt->cl_auth);
+			if (err)
+				__rpc_clnt_remove_pipedir(clnt);
+		}
+		break;
+	case RPC_PIPEFS_UMOUNT:
+		__rpc_clnt_remove_pipedir(clnt);
+		break;
+	default:
+		printk(KERN_ERR "%s: unknown event: %ld\n", __func__, event);
+		return -ENOTSUPP;
+	}
+	return err;
+}
+
+static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
+			    void *ptr)
+{
+	struct super_block *sb = ptr;
+	struct rpc_clnt *clnt;
+	int error = 0;
+	struct sunrpc_net *sn = net_generic(sb->s_fs_info, sunrpc_net_id);
+
+	spin_lock(&sn->rpc_client_lock);
+	list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
+		error = __rpc_pipefs_event(clnt, event, sb);
+		if (error)
+			break;
+	}
+	spin_unlock(&sn->rpc_client_lock);
 	return error;
 }
 
+static struct notifier_block rpc_clients_block = {
+	.notifier_call	= rpc_pipefs_event,
+	.priority	= SUNRPC_PIPEFS_RPC_PRIO,
+};
+
+int rpc_clients_notifier_register(void)
+{
+	return rpc_pipefs_notifier_register(&rpc_clients_block);
+}
+
+void rpc_clients_notifier_unregister(void)
+{
+	return rpc_pipefs_notifier_unregister(&rpc_clients_block);
+}
+
 static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
 {
-	struct rpc_program	*program = args->program;
-	struct rpc_version	*version;
+	const struct rpc_program *program = args->program;
+	const struct rpc_version *version;
 	struct rpc_clnt		*clnt = NULL;
 	struct rpc_auth		*auth;
 	int err;
@@ -179,15 +275,9 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
 		goto out_err;
 	clnt->cl_parent = clnt;
 
-	clnt->cl_server = clnt->cl_inline_name;
-	if (len > sizeof(clnt->cl_inline_name)) {
-		char *buf = kmalloc(len, GFP_KERNEL);
-		if (buf != NULL)
-			clnt->cl_server = buf;
-		else
-			len = sizeof(clnt->cl_inline_name);
-	}
-	strlcpy(clnt->cl_server, args->servername, len);
+	clnt->cl_server = kstrdup(args->servername, GFP_KERNEL);
+	if (clnt->cl_server == NULL)
+		goto out_no_server;
 
 	clnt->cl_xprt     = xprt;
 	clnt->cl_procinfo = version->procs;
@@ -246,17 +336,14 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
 	return clnt;
 
 out_no_auth:
-	if (!IS_ERR(clnt->cl_path.dentry)) {
-		rpc_remove_client_dir(clnt->cl_path.dentry);
-		rpc_put_mount();
-	}
+	rpc_clnt_remove_pipedir(clnt);
 out_no_path:
 	kfree(clnt->cl_principal);
 out_no_principal:
 	rpc_free_iostats(clnt->cl_metrics);
 out_no_stats:
-	if (clnt->cl_server != clnt->cl_inline_name)
-		kfree(clnt->cl_server);
+	kfree(clnt->cl_server);
+out_no_server:
 	kfree(clnt);
 out_err:
 	xprt_put(xprt);
@@ -379,6 +466,9 @@ rpc_clone_client(struct rpc_clnt *clnt)
 	new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
 	if (!new)
 		goto out_no_clnt;
+	new->cl_server = kstrdup(clnt->cl_server, GFP_KERNEL);
+	if (new->cl_server == NULL)
+		goto out_no_server;
 	new->cl_parent = clnt;
 	/* Turn off autobind on clones */
 	new->cl_autobind = 0;
@@ -409,6 +499,8 @@ out_no_path:
 out_no_principal:
 	rpc_free_iostats(new->cl_metrics);
 out_no_stats:
+	kfree(new->cl_server);
+out_no_server:
 	kfree(new);
 out_no_clnt:
 	dprintk("RPC:       %s: returned error %d\n", __func__, err);
@@ -474,18 +566,11 @@ rpc_free_client(struct rpc_clnt *clnt)
 {
 	dprintk("RPC:       destroying %s client for %s\n",
 			clnt->cl_protname, clnt->cl_server);
-	if (!IS_ERR(clnt->cl_path.dentry)) {
-		rpc_remove_client_dir(clnt->cl_path.dentry);
-		rpc_put_mount();
-	}
-	if (clnt->cl_parent != clnt) {
+	if (clnt->cl_parent != clnt)
 		rpc_release_client(clnt->cl_parent);
-		goto out_free;
-	}
-	if (clnt->cl_server != clnt->cl_inline_name)
-		kfree(clnt->cl_server);
-out_free:
+	kfree(clnt->cl_server);
 	rpc_unregister_client(clnt);
+	rpc_clnt_remove_pipedir(clnt);
 	rpc_free_iostats(clnt->cl_metrics);
 	kfree(clnt->cl_principal);
 	clnt->cl_metrics = NULL;
@@ -542,11 +627,11 @@ rpc_release_client(struct rpc_clnt *clnt)
  * The Sun NFSv2/v3 ACL protocol can do this.
  */
 struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
-				      struct rpc_program *program,
+				      const struct rpc_program *program,
 				      u32 vers)
 {
 	struct rpc_clnt *clnt;
-	struct rpc_version *version;
+	const struct rpc_version *version;
 	int err;
 
 	BUG_ON(vers >= program->nrvers || !program->version[vers]);
@@ -1163,6 +1248,7 @@ call_bind_status(struct rpc_task *task)
 		return;
 	}
 
+	trace_rpc_bind_status(task);
 	switch (task->tk_status) {
 	case -ENOMEM:
 		dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid);
@@ -1262,6 +1348,7 @@ call_connect_status(struct rpc_task *task)
 		return;
 	}
 
+	trace_rpc_connect_status(task, status);
 	switch (status) {
 		/* if soft mounted, test if we've timed out */
 	case -ETIMEDOUT:
@@ -1450,6 +1537,7 @@ call_status(struct rpc_task *task)
 		return;
 	}
 
+	trace_rpc_call_status(task);
 	task->tk_status = 0;
 	switch(status) {
 	case -EHOSTDOWN:
@@ -1852,14 +1940,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt,
 		task->tk_action, rpc_waitq);
 }
 
-void rpc_show_tasks(void)
+void rpc_show_tasks(struct net *net)
 {
 	struct rpc_clnt *clnt;
 	struct rpc_task *task;
 	int header = 0;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
-	spin_lock(&rpc_client_lock);
-	list_for_each_entry(clnt, &all_clients, cl_clients) {
+	spin_lock(&sn->rpc_client_lock);
+	list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
 		spin_lock(&clnt->cl_lock);
 		list_for_each_entry(task, &clnt->cl_tasks, tk_task) {
 			if (!header) {
@@ -1870,6 +1959,6 @@ void rpc_show_tasks(void)
 		}
 		spin_unlock(&clnt->cl_lock);
 	}
-	spin_unlock(&rpc_client_lock);
+	spin_unlock(&sn->rpc_client_lock);
 }
 #endif
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index d013bf2..ce7bd44 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -9,6 +9,20 @@ struct cache_detail;
 struct sunrpc_net {
 	struct proc_dir_entry *proc_net_rpc;
 	struct cache_detail *ip_map_cache;
+	struct cache_detail *unix_gid_cache;
+	struct cache_detail *rsc_cache;
+	struct cache_detail *rsi_cache;
+
+	struct super_block *pipefs_sb;
+	struct mutex pipefs_sb_lock;
+
+	struct list_head all_clients;
+	spinlock_t rpc_client_lock;
+
+	struct rpc_clnt *rpcb_local_clnt;
+	struct rpc_clnt *rpcb_local_clnt4;
+	spinlock_t rpcb_clnt_lock;
+	unsigned int rpcb_users;
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 63a7a7a..391af76 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -18,7 +18,6 @@
 #include <linux/kernel.h>
 
 #include <asm/ioctls.h>
-#include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/wait.h>
 #include <linux/seq_file.h>
@@ -27,9 +26,15 @@
 #include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/cache.h>
+#include <linux/nsproxy.h>
+#include <linux/notifier.h>
 
-static struct vfsmount *rpc_mnt __read_mostly;
-static int rpc_mount_count;
+#include "netns.h"
+#include "sunrpc.h"
+
+#define RPCDBG_FACILITY RPCDBG_DEBUG
+
+#define NET_NAME(net)	((net == &init_net) ? " (init_net)" : "")
 
 static struct file_system_type rpc_pipe_fs_type;
 
@@ -38,7 +43,21 @@ static struct kmem_cache *rpc_inode_cachep __read_mostly;
 
 #define RPC_UPCALL_TIMEOUT (30*HZ)
 
-static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
+static BLOCKING_NOTIFIER_HEAD(rpc_pipefs_notifier_list);
+
+int rpc_pipefs_notifier_register(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register);
+
+void rpc_pipefs_notifier_unregister(struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&rpc_pipefs_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_unregister);
+
+static void rpc_purge_list(struct rpc_pipe *pipe, struct list_head *head,
 		void (*destroy_msg)(struct rpc_pipe_msg *), int err)
 {
 	struct rpc_pipe_msg *msg;
@@ -51,30 +70,25 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
 		msg->errno = err;
 		destroy_msg(msg);
 	} while (!list_empty(head));
-	wake_up(&rpci->waitq);
+	wake_up(&pipe->waitq);
 }
 
 static void
 rpc_timeout_upcall_queue(struct work_struct *work)
 {
 	LIST_HEAD(free_list);
-	struct rpc_inode *rpci =
-		container_of(work, struct rpc_inode, queue_timeout.work);
-	struct inode *inode = &rpci->vfs_inode;
+	struct rpc_pipe *pipe =
+		container_of(work, struct rpc_pipe, queue_timeout.work);
 	void (*destroy_msg)(struct rpc_pipe_msg *);
 
-	spin_lock(&inode->i_lock);
-	if (rpci->ops == NULL) {
-		spin_unlock(&inode->i_lock);
-		return;
-	}
-	destroy_msg = rpci->ops->destroy_msg;
-	if (rpci->nreaders == 0) {
-		list_splice_init(&rpci->pipe, &free_list);
-		rpci->pipelen = 0;
+	spin_lock(&pipe->lock);
+	destroy_msg = pipe->ops->destroy_msg;
+	if (pipe->nreaders == 0) {
+		list_splice_init(&pipe->pipe, &free_list);
+		pipe->pipelen = 0;
 	}
-	spin_unlock(&inode->i_lock);
-	rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT);
+	spin_unlock(&pipe->lock);
+	rpc_purge_list(pipe, &free_list, destroy_msg, -ETIMEDOUT);
 }
 
 ssize_t rpc_pipe_generic_upcall(struct file *filp, struct rpc_pipe_msg *msg,
@@ -108,30 +122,26 @@ EXPORT_SYMBOL_GPL(rpc_pipe_generic_upcall);
  * initialize the fields of @msg (other than @msg->list) appropriately.
  */
 int
-rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
+rpc_queue_upcall(struct rpc_pipe *pipe, struct rpc_pipe_msg *msg)
 {
-	struct rpc_inode *rpci = RPC_I(inode);
 	int res = -EPIPE;
 
-	spin_lock(&inode->i_lock);
-	if (rpci->ops == NULL)
-		goto out;
-	if (rpci->nreaders) {
-		list_add_tail(&msg->list, &rpci->pipe);
-		rpci->pipelen += msg->len;
+	spin_lock(&pipe->lock);
+	if (pipe->nreaders) {
+		list_add_tail(&msg->list, &pipe->pipe);
+		pipe->pipelen += msg->len;
 		res = 0;
-	} else if (rpci->flags & RPC_PIPE_WAIT_FOR_OPEN) {
-		if (list_empty(&rpci->pipe))
+	} else if (pipe->flags & RPC_PIPE_WAIT_FOR_OPEN) {
+		if (list_empty(&pipe->pipe))
 			queue_delayed_work(rpciod_workqueue,
-					&rpci->queue_timeout,
+					&pipe->queue_timeout,
 					RPC_UPCALL_TIMEOUT);
-		list_add_tail(&msg->list, &rpci->pipe);
-		rpci->pipelen += msg->len;
+		list_add_tail(&msg->list, &pipe->pipe);
+		pipe->pipelen += msg->len;
 		res = 0;
 	}
-out:
-	spin_unlock(&inode->i_lock);
-	wake_up(&rpci->waitq);
+	spin_unlock(&pipe->lock);
+	wake_up(&pipe->waitq);
 	return res;
 }
 EXPORT_SYMBOL_GPL(rpc_queue_upcall);
@@ -145,28 +155,24 @@ rpc_inode_setowner(struct inode *inode, void *private)
 static void
 rpc_close_pipes(struct inode *inode)
 {
-	struct rpc_inode *rpci = RPC_I(inode);
-	const struct rpc_pipe_ops *ops;
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	int need_release;
+	LIST_HEAD(free_list);
 
 	mutex_lock(&inode->i_mutex);
-	ops = rpci->ops;
-	if (ops != NULL) {
-		LIST_HEAD(free_list);
-		spin_lock(&inode->i_lock);
-		need_release = rpci->nreaders != 0 || rpci->nwriters != 0;
-		rpci->nreaders = 0;
-		list_splice_init(&rpci->in_upcall, &free_list);
-		list_splice_init(&rpci->pipe, &free_list);
-		rpci->pipelen = 0;
-		rpci->ops = NULL;
-		spin_unlock(&inode->i_lock);
-		rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE);
-		rpci->nwriters = 0;
-		if (need_release && ops->release_pipe)
-			ops->release_pipe(inode);
-		cancel_delayed_work_sync(&rpci->queue_timeout);
-	}
+	spin_lock(&pipe->lock);
+	need_release = pipe->nreaders != 0 || pipe->nwriters != 0;
+	pipe->nreaders = 0;
+	list_splice_init(&pipe->in_upcall, &free_list);
+	list_splice_init(&pipe->pipe, &free_list);
+	pipe->pipelen = 0;
+	pipe->dentry = NULL;
+	spin_unlock(&pipe->lock);
+	rpc_purge_list(pipe, &free_list, pipe->ops->destroy_msg, -EPIPE);
+	pipe->nwriters = 0;
+	if (need_release && pipe->ops->release_pipe)
+		pipe->ops->release_pipe(inode);
+	cancel_delayed_work_sync(&pipe->queue_timeout);
 	rpc_inode_setowner(inode, NULL);
 	mutex_unlock(&inode->i_mutex);
 }
@@ -197,23 +203,23 @@ rpc_destroy_inode(struct inode *inode)
 static int
 rpc_pipe_open(struct inode *inode, struct file *filp)
 {
-	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	int first_open;
 	int res = -ENXIO;
 
 	mutex_lock(&inode->i_mutex);
-	if (rpci->ops == NULL)
+	if (pipe->dentry == NULL)
 		goto out;
-	first_open = rpci->nreaders == 0 && rpci->nwriters == 0;
-	if (first_open && rpci->ops->open_pipe) {
-		res = rpci->ops->open_pipe(inode);
+	first_open = pipe->nreaders == 0 && pipe->nwriters == 0;
+	if (first_open && pipe->ops->open_pipe) {
+		res = pipe->ops->open_pipe(inode);
 		if (res)
 			goto out;
 	}
 	if (filp->f_mode & FMODE_READ)
-		rpci->nreaders++;
+		pipe->nreaders++;
 	if (filp->f_mode & FMODE_WRITE)
-		rpci->nwriters++;
+		pipe->nwriters++;
 	res = 0;
 out:
 	mutex_unlock(&inode->i_mutex);
@@ -223,38 +229,38 @@ out:
 static int
 rpc_pipe_release(struct inode *inode, struct file *filp)
 {
-	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	struct rpc_pipe_msg *msg;
 	int last_close;
 
 	mutex_lock(&inode->i_mutex);
-	if (rpci->ops == NULL)
+	if (pipe->dentry == NULL)
 		goto out;
 	msg = filp->private_data;
 	if (msg != NULL) {
-		spin_lock(&inode->i_lock);
+		spin_lock(&pipe->lock);
 		msg->errno = -EAGAIN;
 		list_del_init(&msg->list);
-		spin_unlock(&inode->i_lock);
-		rpci->ops->destroy_msg(msg);
+		spin_unlock(&pipe->lock);
+		pipe->ops->destroy_msg(msg);
 	}
 	if (filp->f_mode & FMODE_WRITE)
-		rpci->nwriters --;
+		pipe->nwriters --;
 	if (filp->f_mode & FMODE_READ) {
-		rpci->nreaders --;
-		if (rpci->nreaders == 0) {
+		pipe->nreaders --;
+		if (pipe->nreaders == 0) {
 			LIST_HEAD(free_list);
-			spin_lock(&inode->i_lock);
-			list_splice_init(&rpci->pipe, &free_list);
-			rpci->pipelen = 0;
-			spin_unlock(&inode->i_lock);
-			rpc_purge_list(rpci, &free_list,
-					rpci->ops->destroy_msg, -EAGAIN);
+			spin_lock(&pipe->lock);
+			list_splice_init(&pipe->pipe, &free_list);
+			pipe->pipelen = 0;
+			spin_unlock(&pipe->lock);
+			rpc_purge_list(pipe, &free_list,
+					pipe->ops->destroy_msg, -EAGAIN);
 		}
 	}
-	last_close = rpci->nwriters == 0 && rpci->nreaders == 0;
-	if (last_close && rpci->ops->release_pipe)
-		rpci->ops->release_pipe(inode);
+	last_close = pipe->nwriters == 0 && pipe->nreaders == 0;
+	if (last_close && pipe->ops->release_pipe)
+		pipe->ops->release_pipe(inode);
 out:
 	mutex_unlock(&inode->i_mutex);
 	return 0;
@@ -264,39 +270,39 @@ static ssize_t
 rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
 {
 	struct inode *inode = filp->f_path.dentry->d_inode;
-	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	struct rpc_pipe_msg *msg;
 	int res = 0;
 
 	mutex_lock(&inode->i_mutex);
-	if (rpci->ops == NULL) {
+	if (pipe->dentry == NULL) {
 		res = -EPIPE;
 		goto out_unlock;
 	}
 	msg = filp->private_data;
 	if (msg == NULL) {
-		spin_lock(&inode->i_lock);
-		if (!list_empty(&rpci->pipe)) {
-			msg = list_entry(rpci->pipe.next,
+		spin_lock(&pipe->lock);
+		if (!list_empty(&pipe->pipe)) {
+			msg = list_entry(pipe->pipe.next,
 					struct rpc_pipe_msg,
 					list);
-			list_move(&msg->list, &rpci->in_upcall);
-			rpci->pipelen -= msg->len;
+			list_move(&msg->list, &pipe->in_upcall);
+			pipe->pipelen -= msg->len;
 			filp->private_data = msg;
 			msg->copied = 0;
 		}
-		spin_unlock(&inode->i_lock);
+		spin_unlock(&pipe->lock);
 		if (msg == NULL)
 			goto out_unlock;
 	}
 	/* NOTE: it is up to the callback to update msg->copied */
-	res = rpci->ops->upcall(filp, msg, buf, len);
+	res = pipe->ops->upcall(filp, msg, buf, len);
 	if (res < 0 || msg->len == msg->copied) {
 		filp->private_data = NULL;
-		spin_lock(&inode->i_lock);
+		spin_lock(&pipe->lock);
 		list_del_init(&msg->list);
-		spin_unlock(&inode->i_lock);
-		rpci->ops->destroy_msg(msg);
+		spin_unlock(&pipe->lock);
+		pipe->ops->destroy_msg(msg);
 	}
 out_unlock:
 	mutex_unlock(&inode->i_mutex);
@@ -307,13 +313,13 @@ static ssize_t
 rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset)
 {
 	struct inode *inode = filp->f_path.dentry->d_inode;
-	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	int res;
 
 	mutex_lock(&inode->i_mutex);
 	res = -EPIPE;
-	if (rpci->ops != NULL)
-		res = rpci->ops->downcall(filp, buf, len);
+	if (pipe->dentry != NULL)
+		res = pipe->ops->downcall(filp, buf, len);
 	mutex_unlock(&inode->i_mutex);
 	return res;
 }
@@ -321,16 +327,15 @@ rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *of
 static unsigned int
 rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
 {
-	struct rpc_inode *rpci;
+	struct rpc_pipe *pipe = RPC_I(filp->f_path.dentry->d_inode)->pipe;
 	unsigned int mask = 0;
 
-	rpci = RPC_I(filp->f_path.dentry->d_inode);
-	poll_wait(filp, &rpci->waitq, wait);
+	poll_wait(filp, &pipe->waitq, wait);
 
 	mask = POLLOUT | POLLWRNORM;
-	if (rpci->ops == NULL)
+	if (pipe->dentry == NULL)
 		mask |= POLLERR | POLLHUP;
-	if (filp->private_data || !list_empty(&rpci->pipe))
+	if (filp->private_data || !list_empty(&pipe->pipe))
 		mask |= POLLIN | POLLRDNORM;
 	return mask;
 }
@@ -339,23 +344,23 @@ static long
 rpc_pipe_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	struct inode *inode = filp->f_path.dentry->d_inode;
-	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe *pipe = RPC_I(inode)->pipe;
 	int len;
 
 	switch (cmd) {
 	case FIONREAD:
-		spin_lock(&inode->i_lock);
-		if (rpci->ops == NULL) {
-			spin_unlock(&inode->i_lock);
+		spin_lock(&pipe->lock);
+		if (pipe->dentry == NULL) {
+			spin_unlock(&pipe->lock);
 			return -EPIPE;
 		}
-		len = rpci->pipelen;
+		len = pipe->pipelen;
 		if (filp->private_data) {
 			struct rpc_pipe_msg *msg;
 			msg = filp->private_data;
 			len += msg->len - msg->copied;
 		}
-		spin_unlock(&inode->i_lock);
+		spin_unlock(&pipe->lock);
 		return put_user(len, (int __user *)arg);
 	default:
 		return -EINVAL;
@@ -440,23 +445,6 @@ struct rpc_filelist {
 	umode_t mode;
 };
 
-struct vfsmount *rpc_get_mount(void)
-{
-	int err;
-
-	err = simple_pin_fs(&rpc_pipe_fs_type, &rpc_mnt, &rpc_mount_count);
-	if (err != 0)
-		return ERR_PTR(err);
-	return rpc_mnt;
-}
-EXPORT_SYMBOL_GPL(rpc_get_mount);
-
-void rpc_put_mount(void)
-{
-	simple_release_fs(&rpc_mnt, &rpc_mount_count);
-}
-EXPORT_SYMBOL_GPL(rpc_put_mount);
-
 static int rpc_delete_dentry(const struct dentry *dentry)
 {
 	return 1;
@@ -540,12 +528,48 @@ static int __rpc_mkdir(struct inode *dir, struct dentry *dentry,
 	return 0;
 }
 
-static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry,
-			umode_t mode,
-			const struct file_operations *i_fop,
-			void *private,
-			const struct rpc_pipe_ops *ops,
-			int flags)
+static void
+init_pipe(struct rpc_pipe *pipe)
+{
+	pipe->nreaders = 0;
+	pipe->nwriters = 0;
+	INIT_LIST_HEAD(&pipe->in_upcall);
+	INIT_LIST_HEAD(&pipe->in_downcall);
+	INIT_LIST_HEAD(&pipe->pipe);
+	pipe->pipelen = 0;
+	init_waitqueue_head(&pipe->waitq);
+	INIT_DELAYED_WORK(&pipe->queue_timeout,
+			    rpc_timeout_upcall_queue);
+	pipe->ops = NULL;
+	spin_lock_init(&pipe->lock);
+	pipe->dentry = NULL;
+}
+
+void rpc_destroy_pipe_data(struct rpc_pipe *pipe)
+{
+	kfree(pipe);
+}
+EXPORT_SYMBOL_GPL(rpc_destroy_pipe_data);
+
+struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags)
+{
+	struct rpc_pipe *pipe;
+
+	pipe = kzalloc(sizeof(struct rpc_pipe), GFP_KERNEL);
+	if (!pipe)
+		return ERR_PTR(-ENOMEM);
+	init_pipe(pipe);
+	pipe->ops = ops;
+	pipe->flags = flags;
+	return pipe;
+}
+EXPORT_SYMBOL_GPL(rpc_mkpipe_data);
+
+static int __rpc_mkpipe_dentry(struct inode *dir, struct dentry *dentry,
+			       umode_t mode,
+			       const struct file_operations *i_fop,
+			       void *private,
+			       struct rpc_pipe *pipe)
 {
 	struct rpc_inode *rpci;
 	int err;
@@ -554,10 +578,8 @@ static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry,
 	if (err)
 		return err;
 	rpci = RPC_I(dentry->d_inode);
-	rpci->nkern_readwriters = 1;
 	rpci->private = private;
-	rpci->flags = flags;
-	rpci->ops = ops;
+	rpci->pipe = pipe;
 	fsnotify_create(dir, dentry);
 	return 0;
 }
@@ -573,6 +595,22 @@ static int __rpc_rmdir(struct inode *dir, struct dentry *dentry)
 	return ret;
 }
 
+int rpc_rmdir(struct dentry *dentry)
+{
+	struct dentry *parent;
+	struct inode *dir;
+	int error;
+
+	parent = dget_parent(dentry);
+	dir = parent->d_inode;
+	mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
+	error = __rpc_rmdir(dir, dentry);
+	mutex_unlock(&dir->i_mutex);
+	dput(parent);
+	return error;
+}
+EXPORT_SYMBOL_GPL(rpc_rmdir);
+
 static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
 {
 	int ret;
@@ -587,16 +625,12 @@ static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
 static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
-	struct rpc_inode *rpci = RPC_I(inode);
 
-	rpci->nkern_readwriters--;
-	if (rpci->nkern_readwriters != 0)
-		return 0;
 	rpc_close_pipes(inode);
 	return __rpc_unlink(dir, dentry);
 }
 
-static struct dentry *__rpc_lookup_create(struct dentry *parent,
+static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
 					  struct qstr *name)
 {
 	struct dentry *dentry;
@@ -604,27 +638,13 @@ static struct dentry *__rpc_lookup_create(struct dentry *parent,
 	dentry = d_lookup(parent, name);
 	if (!dentry) {
 		dentry = d_alloc(parent, name);
-		if (!dentry) {
-			dentry = ERR_PTR(-ENOMEM);
-			goto out_err;
-		}
+		if (!dentry)
+			return ERR_PTR(-ENOMEM);
 	}
-	if (!dentry->d_inode)
+	if (dentry->d_inode == NULL) {
 		d_set_d_op(dentry, &rpc_dentry_operations);
-out_err:
-	return dentry;
-}
-
-static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
-					  struct qstr *name)
-{
-	struct dentry *dentry;
-
-	dentry = __rpc_lookup_create(parent, name);
-	if (IS_ERR(dentry))
-		return dentry;
-	if (dentry->d_inode == NULL)
 		return dentry;
+	}
 	dput(dentry);
 	return ERR_PTR(-EEXIST);
 }
@@ -779,7 +799,7 @@ static int rpc_rmdir_depopulate(struct dentry *dentry,
  * @private: private data to associate with the pipe, for the caller's use
  * @ops: operations defining the behavior of the pipe: upcall, downcall,
  *	release_pipe, open_pipe, and destroy_msg.
- * @flags: rpc_inode flags
+ * @flags: rpc_pipe flags
  *
  * Data is made available for userspace to read by calls to
  * rpc_queue_upcall().  The actual reads will result in calls to
@@ -792,9 +812,8 @@ static int rpc_rmdir_depopulate(struct dentry *dentry,
  * The @private argument passed here will be available to all these methods
  * from the file pointer, via RPC_I(file->f_dentry->d_inode)->private.
  */
-struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
-			  void *private, const struct rpc_pipe_ops *ops,
-			  int flags)
+struct dentry *rpc_mkpipe_dentry(struct dentry *parent, const char *name,
+				 void *private, struct rpc_pipe *pipe)
 {
 	struct dentry *dentry;
 	struct inode *dir = parent->d_inode;
@@ -802,9 +821,9 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
 	struct qstr q;
 	int err;
 
-	if (ops->upcall == NULL)
+	if (pipe->ops->upcall == NULL)
 		umode &= ~S_IRUGO;
-	if (ops->downcall == NULL)
+	if (pipe->ops->downcall == NULL)
 		umode &= ~S_IWUGO;
 
 	q.name = name;
@@ -812,24 +831,11 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
 	q.hash = full_name_hash(q.name, q.len),
 
 	mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
-	dentry = __rpc_lookup_create(parent, &q);
+	dentry = __rpc_lookup_create_exclusive(parent, &q);
 	if (IS_ERR(dentry))
 		goto out;
-	if (dentry->d_inode) {
-		struct rpc_inode *rpci = RPC_I(dentry->d_inode);
-		if (rpci->private != private ||
-				rpci->ops != ops ||
-				rpci->flags != flags) {
-			dput (dentry);
-			err = -EBUSY;
-			goto out_err;
-		}
-		rpci->nkern_readwriters++;
-		goto out;
-	}
-
-	err = __rpc_mkpipe(dir, dentry, umode, &rpc_pipe_fops,
-			   private, ops, flags);
+	err = __rpc_mkpipe_dentry(dir, dentry, umode, &rpc_pipe_fops,
+				  private, pipe);
 	if (err)
 		goto out_err;
 out:
@@ -842,7 +848,7 @@ out_err:
 			err);
 	goto out;
 }
-EXPORT_SYMBOL_GPL(rpc_mkpipe);
+EXPORT_SYMBOL_GPL(rpc_mkpipe_dentry);
 
 /**
  * rpc_unlink - remove a pipe
@@ -915,7 +921,7 @@ struct dentry *rpc_create_client_dir(struct dentry *dentry,
 
 /**
  * rpc_remove_client_dir - Remove a directory created with rpc_create_client_dir()
- * @dentry: directory to remove
+ * @clnt: rpc client
  */
 int rpc_remove_client_dir(struct dentry *dentry)
 {
@@ -1020,11 +1026,64 @@ static const struct rpc_filelist files[] = {
 	},
 };
 
+/*
+ * This call can be used only in RPC pipefs mount notification hooks.
+ */
+struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+			       const unsigned char *dir_name)
+{
+	struct qstr dir = {
+		.name = dir_name,
+		.len = strlen(dir_name),
+		.hash = full_name_hash(dir_name, strlen(dir_name)),
+	};
+
+	return d_lookup(sb->s_root, &dir);
+}
+EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
+
+void rpc_pipefs_init_net(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	mutex_init(&sn->pipefs_sb_lock);
+}
+
+/*
+ * This call will be used for per network namespace operations calls.
+ * Note: Function will be returned with pipefs_sb_lock taken if superblock was
+ * found. This lock have to be released by rpc_put_sb_net() when all operations
+ * will be completed.
+ */
+struct super_block *rpc_get_sb_net(const struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	mutex_lock(&sn->pipefs_sb_lock);
+	if (sn->pipefs_sb)
+		return sn->pipefs_sb;
+	mutex_unlock(&sn->pipefs_sb_lock);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(rpc_get_sb_net);
+
+void rpc_put_sb_net(const struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	BUG_ON(sn->pipefs_sb == NULL);
+	mutex_unlock(&sn->pipefs_sb_lock);
+}
+EXPORT_SYMBOL_GPL(rpc_put_sb_net);
+
 static int
 rpc_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
+	struct net *net = data;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	int err;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1033,30 +1092,59 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_time_gran = 1;
 
 	inode = rpc_get_inode(sb, S_IFDIR | 0755);
-	if (!inode)
-		return -ENOMEM;
-	sb->s_root = root = d_alloc_root(inode);
-	if (!root) {
-		iput(inode);
+	sb->s_root = root = d_make_root(inode);
+	if (!root)
 		return -ENOMEM;
-	}
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
+	dprintk("RPC:	sending pipefs MOUNT notification for net %p%s\n", net,
+								NET_NAME(net));
+	err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_MOUNT,
+					   sb);
+	if (err)
+		goto err_depopulate;
+	sb->s_fs_info = get_net(net);
+	sn->pipefs_sb = sb;
 	return 0;
+
+err_depopulate:
+	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_UMOUNT,
+					   sb);
+	__rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
+	return err;
 }
 
 static struct dentry *
 rpc_mount(struct file_system_type *fs_type,
 		int flags, const char *dev_name, void *data)
 {
-	return mount_single(fs_type, flags, data, rpc_fill_super);
+	return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super);
+}
+
+void rpc_kill_sb(struct super_block *sb)
+{
+	struct net *net = sb->s_fs_info;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	mutex_lock(&sn->pipefs_sb_lock);
+	sn->pipefs_sb = NULL;
+	mutex_unlock(&sn->pipefs_sb_lock);
+	put_net(net);
+	dprintk("RPC:	sending pipefs UMOUNT notification for net %p%s\n", net,
+								NET_NAME(net));
+	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_UMOUNT,
+					   sb);
+	kill_litter_super(sb);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "rpc_pipefs",
 	.mount		= rpc_mount,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= rpc_kill_sb,
 };
 
 static void
@@ -1066,16 +1154,7 @@ init_once(void *foo)
 
 	inode_init_once(&rpci->vfs_inode);
 	rpci->private = NULL;
-	rpci->nreaders = 0;
-	rpci->nwriters = 0;
-	INIT_LIST_HEAD(&rpci->in_upcall);
-	INIT_LIST_HEAD(&rpci->in_downcall);
-	INIT_LIST_HEAD(&rpci->pipe);
-	rpci->pipelen = 0;
-	init_waitqueue_head(&rpci->waitq);
-	INIT_DELAYED_WORK(&rpci->queue_timeout,
-			    rpc_timeout_upcall_queue);
-	rpci->ops = NULL;
+	rpci->pipe = NULL;
 }
 
 int register_rpc_pipefs(void)
@@ -1089,17 +1168,24 @@ int register_rpc_pipefs(void)
 				init_once);
 	if (!rpc_inode_cachep)
 		return -ENOMEM;
+	err = rpc_clients_notifier_register();
+	if (err)
+		goto err_notifier;
 	err = register_filesystem(&rpc_pipe_fs_type);
-	if (err) {
-		kmem_cache_destroy(rpc_inode_cachep);
-		return err;
-	}
-
+	if (err)
+		goto err_register;
 	return 0;
+
+err_register:
+	rpc_clients_notifier_unregister();
+err_notifier:
+	kmem_cache_destroy(rpc_inode_cachep);
+	return err;
 }
 
 void unregister_rpc_pipefs(void)
 {
+	rpc_clients_notifier_unregister();
 	kmem_cache_destroy(rpc_inode_cachep);
 	unregister_filesystem(&rpc_pipe_fs_type);
 }
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 8761bf8..b1f08bd 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -23,12 +23,15 @@
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/nsproxy.h>
 #include <net/ipv6.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/xprtsock.h>
 
+#include "netns.h"
+
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_BIND
 #endif
@@ -109,13 +112,7 @@ enum {
 
 static void			rpcb_getport_done(struct rpc_task *, void *);
 static void			rpcb_map_release(void *data);
-static struct rpc_program	rpcb_program;
-
-static struct rpc_clnt *	rpcb_local_clnt;
-static struct rpc_clnt *	rpcb_local_clnt4;
-
-DEFINE_SPINLOCK(rpcb_clnt_lock);
-unsigned int			rpcb_users;
+static const struct rpc_program	rpcb_program;
 
 struct rpcbind_args {
 	struct rpc_xprt *	r_xprt;
@@ -140,8 +137,8 @@ struct rpcb_info {
 	struct rpc_procinfo *	rpc_proc;
 };
 
-static struct rpcb_info rpcb_next_version[];
-static struct rpcb_info rpcb_next_version6[];
+static const struct rpcb_info rpcb_next_version[];
+static const struct rpcb_info rpcb_next_version6[];
 
 static const struct rpc_call_ops rpcb_getport_ops = {
 	.rpc_call_done		= rpcb_getport_done,
@@ -164,32 +161,34 @@ static void rpcb_map_release(void *data)
 	kfree(map);
 }
 
-static int rpcb_get_local(void)
+static int rpcb_get_local(struct net *net)
 {
 	int cnt;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
-	spin_lock(&rpcb_clnt_lock);
-	if (rpcb_users)
-		rpcb_users++;
-	cnt = rpcb_users;
-	spin_unlock(&rpcb_clnt_lock);
+	spin_lock(&sn->rpcb_clnt_lock);
+	if (sn->rpcb_users)
+		sn->rpcb_users++;
+	cnt = sn->rpcb_users;
+	spin_unlock(&sn->rpcb_clnt_lock);
 
 	return cnt;
 }
 
-void rpcb_put_local(void)
+void rpcb_put_local(struct net *net)
 {
-	struct rpc_clnt *clnt = rpcb_local_clnt;
-	struct rpc_clnt *clnt4 = rpcb_local_clnt4;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct rpc_clnt *clnt = sn->rpcb_local_clnt;
+	struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
 	int shutdown;
 
-	spin_lock(&rpcb_clnt_lock);
-	if (--rpcb_users == 0) {
-		rpcb_local_clnt = NULL;
-		rpcb_local_clnt4 = NULL;
+	spin_lock(&sn->rpcb_clnt_lock);
+	if (--sn->rpcb_users == 0) {
+		sn->rpcb_local_clnt = NULL;
+		sn->rpcb_local_clnt4 = NULL;
 	}
-	shutdown = !rpcb_users;
-	spin_unlock(&rpcb_clnt_lock);
+	shutdown = !sn->rpcb_users;
+	spin_unlock(&sn->rpcb_clnt_lock);
 
 	if (shutdown) {
 		/*
@@ -202,30 +201,34 @@ void rpcb_put_local(void)
 	}
 }
 
-static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
+static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
+			struct rpc_clnt *clnt4)
 {
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
 	/* Protected by rpcb_create_local_mutex */
-	rpcb_local_clnt = clnt;
-	rpcb_local_clnt4 = clnt4;
+	sn->rpcb_local_clnt = clnt;
+	sn->rpcb_local_clnt4 = clnt4;
 	smp_wmb(); 
-	rpcb_users = 1;
+	sn->rpcb_users = 1;
 	dprintk("RPC:       created new rpcb local clients (rpcb_local_clnt: "
-			"%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
-			rpcb_local_clnt4);
+			"%p, rpcb_local_clnt4: %p) for net %p%s\n",
+			sn->rpcb_local_clnt, sn->rpcb_local_clnt4,
+			net, (net == &init_net) ? " (init_net)" : "");
 }
 
 /*
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local_unix(void)
+static int rpcb_create_local_unix(struct net *net)
 {
 	static const struct sockaddr_un rpcb_localaddr_rpcbind = {
 		.sun_family		= AF_LOCAL,
 		.sun_path		= RPCBIND_SOCK_PATHNAME,
 	};
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= net,
 		.protocol	= XPRT_TRANSPORT_LOCAL,
 		.address	= (struct sockaddr *)&rpcb_localaddr_rpcbind,
 		.addrsize	= sizeof(rpcb_localaddr_rpcbind),
@@ -258,7 +261,7 @@ static int rpcb_create_local_unix(void)
 		clnt4 = NULL;
 	}
 
-	rpcb_set_local(clnt, clnt4);
+	rpcb_set_local(net, clnt, clnt4);
 
 out:
 	return result;
@@ -268,7 +271,7 @@ out:
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local_net(void)
+static int rpcb_create_local_net(struct net *net)
 {
 	static const struct sockaddr_in rpcb_inaddr_loopback = {
 		.sin_family		= AF_INET,
@@ -276,7 +279,7 @@ static int rpcb_create_local_net(void)
 		.sin_port		= htons(RPCBIND_PORT),
 	};
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= net,
 		.protocol	= XPRT_TRANSPORT_TCP,
 		.address	= (struct sockaddr *)&rpcb_inaddr_loopback,
 		.addrsize	= sizeof(rpcb_inaddr_loopback),
@@ -310,7 +313,7 @@ static int rpcb_create_local_net(void)
 		clnt4 = NULL;
 	}
 
-	rpcb_set_local(clnt, clnt4);
+	rpcb_set_local(net, clnt, clnt4);
 
 out:
 	return result;
@@ -320,31 +323,32 @@ out:
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-int rpcb_create_local(void)
+int rpcb_create_local(struct net *net)
 {
 	static DEFINE_MUTEX(rpcb_create_local_mutex);
 	int result = 0;
 
-	if (rpcb_get_local())
+	if (rpcb_get_local(net))
 		return result;
 
 	mutex_lock(&rpcb_create_local_mutex);
-	if (rpcb_get_local())
+	if (rpcb_get_local(net))
 		goto out;
 
-	if (rpcb_create_local_unix() != 0)
-		result = rpcb_create_local_net();
+	if (rpcb_create_local_unix(net) != 0)
+		result = rpcb_create_local_net(net);
 
 out:
 	mutex_unlock(&rpcb_create_local_mutex);
 	return result;
 }
 
-static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
-				    size_t salen, int proto, u32 version)
+static struct rpc_clnt *rpcb_create(struct net *net, const char *hostname,
+				    struct sockaddr *srvaddr, size_t salen,
+				    int proto, u32 version)
 {
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= net,
 		.protocol	= proto,
 		.address	= srvaddr,
 		.addrsize	= salen,
@@ -420,7 +424,7 @@ static int rpcb_register_call(struct rpc_clnt *clnt, struct rpc_message *msg)
  * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
  * addresses).
  */
-int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
+int rpcb_register(struct net *net, u32 prog, u32 vers, int prot, unsigned short port)
 {
 	struct rpcbind_args map = {
 		.r_prog		= prog,
@@ -431,6 +435,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	struct rpc_message msg = {
 		.rpc_argp	= &map,
 	};
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
 	dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
 			"rpcbind\n", (port ? "" : "un"),
@@ -440,13 +445,14 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	if (port)
 		msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
 
-	return rpcb_register_call(rpcb_local_clnt, &msg);
+	return rpcb_register_call(sn->rpcb_local_clnt, &msg);
 }
 
 /*
  * Fill in AF_INET family-specific arguments to register
  */
-static int rpcb_register_inet4(const struct sockaddr *sap,
+static int rpcb_register_inet4(struct sunrpc_net *sn,
+			       const struct sockaddr *sap,
 			       struct rpc_message *msg)
 {
 	const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
@@ -465,7 +471,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
 	if (port)
 		msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 
-	result = rpcb_register_call(rpcb_local_clnt4, msg);
+	result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
 	kfree(map->r_addr);
 	return result;
 }
@@ -473,7 +479,8 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
 /*
  * Fill in AF_INET6 family-specific arguments to register
  */
-static int rpcb_register_inet6(const struct sockaddr *sap,
+static int rpcb_register_inet6(struct sunrpc_net *sn,
+			       const struct sockaddr *sap,
 			       struct rpc_message *msg)
 {
 	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
@@ -492,12 +499,13 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
 	if (port)
 		msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 
-	result = rpcb_register_call(rpcb_local_clnt4, msg);
+	result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
 	kfree(map->r_addr);
 	return result;
 }
 
-static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
+static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn,
+					     struct rpc_message *msg)
 {
 	struct rpcbind_args *map = msg->rpc_argp;
 
@@ -508,7 +516,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
 	map->r_addr = "";
 	msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
 
-	return rpcb_register_call(rpcb_local_clnt4, msg);
+	return rpcb_register_call(sn->rpcb_local_clnt4, msg);
 }
 
 /**
@@ -554,7 +562,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
  * service on any IPv4 address, but not on IPv6.  The latter
  * advertises the service on all IPv4 and IPv6 addresses.
  */
-int rpcb_v4_register(const u32 program, const u32 version,
+int rpcb_v4_register(struct net *net, const u32 program, const u32 version,
 		     const struct sockaddr *address, const char *netid)
 {
 	struct rpcbind_args map = {
@@ -566,18 +574,19 @@ int rpcb_v4_register(const u32 program, const u32 version,
 	struct rpc_message msg = {
 		.rpc_argp	= &map,
 	};
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
-	if (rpcb_local_clnt4 == NULL)
+	if (sn->rpcb_local_clnt4 == NULL)
 		return -EPROTONOSUPPORT;
 
 	if (address == NULL)
-		return rpcb_unregister_all_protofamilies(&msg);
+		return rpcb_unregister_all_protofamilies(sn, &msg);
 
 	switch (address->sa_family) {
 	case AF_INET:
-		return rpcb_register_inet4(address, &msg);
+		return rpcb_register_inet4(sn, address, &msg);
 	case AF_INET6:
-		return rpcb_register_inet6(address, &msg);
+		return rpcb_register_inet6(sn, address, &msg);
 	}
 
 	return -EAFNOSUPPORT;
@@ -699,8 +708,8 @@ void rpcb_getport_async(struct rpc_task *task)
 	dprintk("RPC: %5u %s: trying rpcbind version %u\n",
 		task->tk_pid, __func__, bind_version);
 
-	rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
-				bind_version);
+	rpcb_clnt = rpcb_create(xprt->xprt_net, clnt->cl_server, sap, salen,
+				xprt->prot, bind_version);
 	if (IS_ERR(rpcb_clnt)) {
 		status = PTR_ERR(rpcb_clnt);
 		dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
@@ -925,7 +934,8 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
 	dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid,
 			task->tk_msg.rpc_proc->p_name, (char *)p);
 
-	if (rpc_uaddr2sockaddr((char *)p, len, sap, sizeof(address)) == 0)
+	if (rpc_uaddr2sockaddr(req->rq_xprt->xprt_net, (char *)p, len,
+				sap, sizeof(address)) == 0)
 		goto out_fail;
 	rpcb->r_port = rpc_get_port(sap);
 
@@ -1041,7 +1051,7 @@ static struct rpc_procinfo rpcb_procedures4[] = {
 	},
 };
 
-static struct rpcb_info rpcb_next_version[] = {
+static const struct rpcb_info rpcb_next_version[] = {
 	{
 		.rpc_vers	= RPCBVERS_2,
 		.rpc_proc	= &rpcb_procedures2[RPCBPROC_GETPORT],
@@ -1051,7 +1061,7 @@ static struct rpcb_info rpcb_next_version[] = {
 	},
 };
 
-static struct rpcb_info rpcb_next_version6[] = {
+static const struct rpcb_info rpcb_next_version6[] = {
 	{
 		.rpc_vers	= RPCBVERS_4,
 		.rpc_proc	= &rpcb_procedures4[RPCBPROC_GETADDR],
@@ -1065,25 +1075,25 @@ static struct rpcb_info rpcb_next_version6[] = {
 	},
 };
 
-static struct rpc_version rpcb_version2 = {
+static const struct rpc_version rpcb_version2 = {
 	.number		= RPCBVERS_2,
 	.nrprocs	= ARRAY_SIZE(rpcb_procedures2),
 	.procs		= rpcb_procedures2
 };
 
-static struct rpc_version rpcb_version3 = {
+static const struct rpc_version rpcb_version3 = {
 	.number		= RPCBVERS_3,
 	.nrprocs	= ARRAY_SIZE(rpcb_procedures3),
 	.procs		= rpcb_procedures3
 };
 
-static struct rpc_version rpcb_version4 = {
+static const struct rpc_version rpcb_version4 = {
 	.number		= RPCBVERS_4,
 	.nrprocs	= ARRAY_SIZE(rpcb_procedures4),
 	.procs		= rpcb_procedures4
 };
 
-static struct rpc_version *rpcb_version[] = {
+static const struct rpc_version *rpcb_version[] = {
 	NULL,
 	NULL,
 	&rpcb_version2,
@@ -1093,7 +1103,7 @@ static struct rpc_version *rpcb_version[] = {
 
 static struct rpc_stat rpcb_stats;
 
-static struct rpc_program rpcb_program = {
+static const struct rpc_program rpcb_program = {
 	.name		= "rpcbind",
 	.number		= RPCBIND_PROGRAM,
 	.nrvers		= ARRAY_SIZE(rpcb_version),
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 3341d89..1c570a8 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -28,6 +28,9 @@
 #define RPCDBG_FACILITY		RPCDBG_SCHED
 #endif
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/sunrpc.h>
+
 /*
  * RPC slabs and memory pools
  */
@@ -205,9 +208,7 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c
 	queue->qlen = 0;
 	setup_timer(&queue->timer_list.timer, __rpc_queue_timer_fn, (unsigned long)queue);
 	INIT_LIST_HEAD(&queue->timer_list.list);
-#ifdef RPC_DEBUG
-	queue->name = qname;
-#endif
+	rpc_assign_waitqueue_name(queue, qname);
 }
 
 void rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const char *qname)
@@ -251,6 +252,8 @@ static inline void rpc_task_set_debuginfo(struct rpc_task *task)
 
 static void rpc_set_active(struct rpc_task *task)
 {
+	trace_rpc_task_begin(task->tk_client, task, NULL);
+
 	rpc_task_set_debuginfo(task);
 	set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
 }
@@ -267,6 +270,8 @@ static int rpc_complete_task(struct rpc_task *task)
 	unsigned long flags;
 	int ret;
 
+	trace_rpc_task_complete(task->tk_client, task, NULL);
+
 	spin_lock_irqsave(&wq->lock, flags);
 	clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
 	ret = atomic_dec_and_test(&task->tk_count);
@@ -324,6 +329,8 @@ static void __rpc_sleep_on_priority(struct rpc_wait_queue *q,
 	dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
 			task->tk_pid, rpc_qname(q), jiffies);
 
+	trace_rpc_task_sleep(task->tk_client, task, q);
+
 	__rpc_add_wait_queue(q, task, queue_priority);
 
 	BUG_ON(task->tk_callback != NULL);
@@ -378,6 +385,8 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task
 		return;
 	}
 
+	trace_rpc_task_wakeup(task->tk_client, task, queue);
+
 	__rpc_remove_wait_queue(queue, task);
 
 	rpc_make_runnable(task);
@@ -422,7 +431,7 @@ EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task);
 /*
  * Wake up the next task on a priority queue.
  */
-static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queue)
+static struct rpc_task *__rpc_find_next_queued_priority(struct rpc_wait_queue *queue)
 {
 	struct list_head *q;
 	struct rpc_task *task;
@@ -467,30 +476,54 @@ new_queue:
 new_owner:
 	rpc_set_waitqueue_owner(queue, task->tk_owner);
 out:
-	rpc_wake_up_task_queue_locked(queue, task);
 	return task;
 }
 
+static struct rpc_task *__rpc_find_next_queued(struct rpc_wait_queue *queue)
+{
+	if (RPC_IS_PRIORITY(queue))
+		return __rpc_find_next_queued_priority(queue);
+	if (!list_empty(&queue->tasks[0]))
+		return list_first_entry(&queue->tasks[0], struct rpc_task, u.tk_wait.list);
+	return NULL;
+}
+
 /*
- * Wake up the next task on the wait queue.
+ * Wake up the first task on the wait queue.
  */
-struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue)
+struct rpc_task *rpc_wake_up_first(struct rpc_wait_queue *queue,
+		bool (*func)(struct rpc_task *, void *), void *data)
 {
 	struct rpc_task	*task = NULL;
 
-	dprintk("RPC:       wake_up_next(%p \"%s\")\n",
+	dprintk("RPC:       wake_up_first(%p \"%s\")\n",
 			queue, rpc_qname(queue));
 	spin_lock_bh(&queue->lock);
-	if (RPC_IS_PRIORITY(queue))
-		task = __rpc_wake_up_next_priority(queue);
-	else {
-		task_for_first(task, &queue->tasks[0])
+	task = __rpc_find_next_queued(queue);
+	if (task != NULL) {
+		if (func(task, data))
 			rpc_wake_up_task_queue_locked(queue, task);
+		else
+			task = NULL;
 	}
 	spin_unlock_bh(&queue->lock);
 
 	return task;
 }
+EXPORT_SYMBOL_GPL(rpc_wake_up_first);
+
+static bool rpc_wake_up_next_func(struct rpc_task *task, void *data)
+{
+	return true;
+}
+
+/*
+ * Wake up the next task on the wait queue.
+*/
+struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *queue)
+{
+	return rpc_wake_up_first(queue, rpc_wake_up_next_func, NULL);
+}
 EXPORT_SYMBOL_GPL(rpc_wake_up_next);
 
 /**
@@ -677,6 +710,7 @@ static void __rpc_execute(struct rpc_task *task)
 			if (do_action == NULL)
 				break;
 		}
+		trace_rpc_task_run_action(task->tk_client, task, task->tk_action);
 		do_action(task);
 
 		/*
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index 145e6784..0a648c5 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -114,7 +114,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct
 		}
 
 		len = PAGE_CACHE_SIZE;
-		kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
+		kaddr = kmap_atomic(*ppage);
 		if (base) {
 			len -= base;
 			if (pglen < len)
@@ -127,7 +127,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct
 			ret = copy_actor(desc, kaddr, len);
 		}
 		flush_dcache_page(*ppage);
-		kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
+		kunmap_atomic(kaddr);
 		copied += ret;
 		if (ret != len || !desc->count)
 			goto out;
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 80df89d..1eb3304 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -133,20 +133,19 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
 /**
  * rpc_count_iostats - tally up per-task stats
  * @task: completed rpc_task
+ * @stats: array of stat structures
  *
  * Relies on the caller for serialization.
  */
-void rpc_count_iostats(struct rpc_task *task)
+void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
 {
 	struct rpc_rqst *req = task->tk_rqstp;
-	struct rpc_iostats *stats;
 	struct rpc_iostats *op_metrics;
 	ktime_t delta;
 
-	if (!task->tk_client || !task->tk_client->cl_metrics || !req)
+	if (!stats || !req)
 		return;
 
-	stats = task->tk_client->cl_metrics;
 	op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
 
 	op_metrics->om_ops++;
@@ -164,6 +163,7 @@ void rpc_count_iostats(struct rpc_task *task)
 	delta = ktime_sub(ktime_get(), task->tk_start);
 	op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
 }
+EXPORT_SYMBOL_GPL(rpc_count_iostats);
 
 static void _print_name(struct seq_file *seq, unsigned int op,
 			struct rpc_procinfo *procs)
@@ -213,45 +213,46 @@ EXPORT_SYMBOL_GPL(rpc_print_iostats);
  * Register/unregister RPC proc files
  */
 static inline struct proc_dir_entry *
-do_register(const char *name, void *data, const struct file_operations *fops)
+do_register(struct net *net, const char *name, void *data,
+	    const struct file_operations *fops)
 {
 	struct sunrpc_net *sn;
 
 	dprintk("RPC:       registering /proc/net/rpc/%s\n", name);
-	sn = net_generic(&init_net, sunrpc_net_id);
+	sn = net_generic(net, sunrpc_net_id);
 	return proc_create_data(name, 0, sn->proc_net_rpc, fops, data);
 }
 
 struct proc_dir_entry *
-rpc_proc_register(struct rpc_stat *statp)
+rpc_proc_register(struct net *net, struct rpc_stat *statp)
 {
-	return do_register(statp->program->name, statp, &rpc_proc_fops);
+	return do_register(net, statp->program->name, statp, &rpc_proc_fops);
 }
 EXPORT_SYMBOL_GPL(rpc_proc_register);
 
 void
-rpc_proc_unregister(const char *name)
+rpc_proc_unregister(struct net *net, const char *name)
 {
 	struct sunrpc_net *sn;
 
-	sn = net_generic(&init_net, sunrpc_net_id);
+	sn = net_generic(net, sunrpc_net_id);
 	remove_proc_entry(name, sn->proc_net_rpc);
 }
 EXPORT_SYMBOL_GPL(rpc_proc_unregister);
 
 struct proc_dir_entry *
-svc_proc_register(struct svc_stat *statp, const struct file_operations *fops)
+svc_proc_register(struct net *net, struct svc_stat *statp, const struct file_operations *fops)
 {
-	return do_register(statp->program->pg_name, statp, fops);
+	return do_register(net, statp->program->pg_name, statp, fops);
 }
 EXPORT_SYMBOL_GPL(svc_proc_register);
 
 void
-svc_proc_unregister(const char *name)
+svc_proc_unregister(struct net *net, const char *name)
 {
 	struct sunrpc_net *sn;
 
-	sn = net_generic(&init_net, sunrpc_net_id);
+	sn = net_generic(net, sunrpc_net_id);
 	remove_proc_entry(name, sn->proc_net_rpc);
 }
 EXPORT_SYMBOL_GPL(svc_proc_unregister);
diff --git a/net/sunrpc/sunrpc.h b/net/sunrpc/sunrpc.h
index 90c292e..14c9f6d 100644
--- a/net/sunrpc/sunrpc.h
+++ b/net/sunrpc/sunrpc.h
@@ -47,5 +47,7 @@ int svc_send_common(struct socket *sock, struct xdr_buf *xdr,
 		    struct page *headpage, unsigned long headoffset,
 		    struct page *tailpage, unsigned long tailoffset);
 
+int rpc_clients_notifier_register(void);
+void rpc_clients_notifier_unregister(void);
 #endif /* _NET_SUNRPC_SUNRPC_H */
 
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 8ec9778..21d106e 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -25,10 +25,15 @@
 #include "netns.h"
 
 int sunrpc_net_id;
+EXPORT_SYMBOL_GPL(sunrpc_net_id);
+
+extern int unix_gid_cache_create(struct net *net);
+extern int unix_gid_cache_destroy(struct net *net);
 
 static __net_init int sunrpc_init_net(struct net *net)
 {
 	int err;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
 	err = rpc_proc_init(net);
 	if (err)
@@ -38,8 +43,18 @@ static __net_init int sunrpc_init_net(struct net *net)
 	if (err)
 		goto err_ipmap;
 
+	err = unix_gid_cache_create(net);
+	if (err)
+		goto err_unixgid;
+
+	rpc_pipefs_init_net(net);
+	INIT_LIST_HEAD(&sn->all_clients);
+	spin_lock_init(&sn->rpc_client_lock);
+	spin_lock_init(&sn->rpcb_clnt_lock);
 	return 0;
 
+err_unixgid:
+	ip_map_cache_destroy(net);
 err_ipmap:
 	rpc_proc_exit(net);
 err_proc:
@@ -48,6 +63,7 @@ err_proc:
 
 static __net_exit void sunrpc_exit_net(struct net *net)
 {
+	unix_gid_cache_destroy(net);
 	ip_map_cache_destroy(net);
 	rpc_proc_exit(net);
 }
@@ -59,8 +75,6 @@ static struct pernet_operations sunrpc_net_ops = {
 	.size = sizeof(struct sunrpc_net),
 };
 
-extern struct cache_detail unix_gid_cache;
-
 static int __init
 init_sunrpc(void)
 {
@@ -82,7 +96,6 @@ init_sunrpc(void)
 #ifdef RPC_DEBUG
 	rpc_register_sysctl();
 #endif
-	cache_register(&unix_gid_cache);
 	svc_init_xprt_sock();	/* svc sock transport */
 	init_socket_xprt();	/* clnt sock transport */
 	return 0;
@@ -105,7 +118,6 @@ cleanup_sunrpc(void)
 	svc_cleanup_xprt_sock();
 	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
-	cache_unregister(&unix_gid_cache);
 	unregister_pernet_subsys(&sunrpc_net_ops);
 #ifdef RPC_DEBUG
 	rpc_unregister_sysctl();
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index e4aabc0..4153846 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
+#include <linux/nsproxy.h>
 
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
@@ -30,7 +31,7 @@
 
 #define RPCDBG_FACILITY	RPCDBG_SVCDSP
 
-static void svc_unregister(const struct svc_serv *serv);
+static void svc_unregister(const struct svc_serv *serv, struct net *net);
 
 #define svc_serv_is_pooled(serv)    ((serv)->sv_function)
 
@@ -368,23 +369,24 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
 	return &serv->sv_pools[pidx % serv->sv_nrpools];
 }
 
-static int svc_rpcb_setup(struct svc_serv *serv)
+int svc_rpcb_setup(struct svc_serv *serv, struct net *net)
 {
 	int err;
 
-	err = rpcb_create_local();
+	err = rpcb_create_local(net);
 	if (err)
 		return err;
 
 	/* Remove any stale portmap registrations */
-	svc_unregister(serv);
+	svc_unregister(serv, net);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(svc_rpcb_setup);
 
-void svc_rpcb_cleanup(struct svc_serv *serv)
+void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net)
 {
-	svc_unregister(serv);
-	rpcb_put_local();
+	svc_unregister(serv, net);
+	rpcb_put_local(net);
 }
 EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
 
@@ -410,7 +412,7 @@ static int svc_uses_rpcbind(struct svc_serv *serv)
  */
 static struct svc_serv *
 __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
-	     void (*shutdown)(struct svc_serv *serv))
+	     void (*shutdown)(struct svc_serv *serv, struct net *net))
 {
 	struct svc_serv	*serv;
 	unsigned int vers;
@@ -470,7 +472,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 	}
 
 	if (svc_uses_rpcbind(serv)) {
-	       	if (svc_rpcb_setup(serv) < 0) {
+		if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) {
 			kfree(serv->sv_pools);
 			kfree(serv);
 			return NULL;
@@ -484,7 +486,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 
 struct svc_serv *
 svc_create(struct svc_program *prog, unsigned int bufsize,
-	   void (*shutdown)(struct svc_serv *serv))
+	   void (*shutdown)(struct svc_serv *serv, struct net *net))
 {
 	return __svc_create(prog, bufsize, /*npools*/1, shutdown);
 }
@@ -492,7 +494,7 @@ EXPORT_SYMBOL_GPL(svc_create);
 
 struct svc_serv *
 svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
-		  void (*shutdown)(struct svc_serv *serv),
+		  void (*shutdown)(struct svc_serv *serv, struct net *net),
 		  svc_thread_fn func, struct module *mod)
 {
 	struct svc_serv *serv;
@@ -509,6 +511,24 @@ svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
 }
 EXPORT_SYMBOL_GPL(svc_create_pooled);
 
+void svc_shutdown_net(struct svc_serv *serv, struct net *net)
+{
+	/*
+	 * The set of xprts (contained in the sv_tempsocks and
+	 * sv_permsocks lists) is now constant, since it is modified
+	 * only by accepting new sockets (done by service threads in
+	 * svc_recv) or aging old ones (done by sv_temptimer), or
+	 * configuration changes (excluded by whatever locking the
+	 * caller is using--nfsd_mutex in the case of nfsd).  So it's
+	 * safe to traverse those lists and shut everything down:
+	 */
+	svc_close_net(serv, net);
+
+	if (serv->sv_shutdown)
+		serv->sv_shutdown(serv, net);
+}
+EXPORT_SYMBOL_GPL(svc_shutdown_net);
+
 /*
  * Destroy an RPC service. Should be called with appropriate locking to
  * protect the sv_nrthreads, sv_permsocks and sv_tempsocks.
@@ -516,6 +536,8 @@ EXPORT_SYMBOL_GPL(svc_create_pooled);
 void
 svc_destroy(struct svc_serv *serv)
 {
+	struct net *net = current->nsproxy->net_ns;
+
 	dprintk("svc: svc_destroy(%s, %d)\n",
 				serv->sv_program->pg_name,
 				serv->sv_nrthreads);
@@ -529,19 +551,15 @@ svc_destroy(struct svc_serv *serv)
 		printk("svc_destroy: no threads for serv=%p!\n", serv);
 
 	del_timer_sync(&serv->sv_temptimer);
+
+	svc_shutdown_net(serv, net);
+
 	/*
-	 * The set of xprts (contained in the sv_tempsocks and
-	 * sv_permsocks lists) is now constant, since it is modified
-	 * only by accepting new sockets (done by service threads in
-	 * svc_recv) or aging old ones (done by sv_temptimer), or
-	 * configuration changes (excluded by whatever locking the
-	 * caller is using--nfsd_mutex in the case of nfsd).  So it's
-	 * safe to traverse those lists and shut everything down:
+	 * The last user is gone and thus all sockets have to be destroyed to
+	 * the point. Check this.
 	 */
-	svc_close_all(serv);
-
-	if (serv->sv_shutdown)
-		serv->sv_shutdown(serv);
+	BUG_ON(!list_empty(&serv->sv_permsocks));
+	BUG_ON(!list_empty(&serv->sv_tempsocks));
 
 	cache_clean_deferred(serv);
 
@@ -795,7 +813,8 @@ EXPORT_SYMBOL_GPL(svc_exit_thread);
  * Returns zero on success; a negative errno value is returned
  * if any error occurs.
  */
-static int __svc_rpcb_register4(const u32 program, const u32 version,
+static int __svc_rpcb_register4(struct net *net, const u32 program,
+				const u32 version,
 				const unsigned short protocol,
 				const unsigned short port)
 {
@@ -818,7 +837,7 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
 		return -ENOPROTOOPT;
 	}
 
-	error = rpcb_v4_register(program, version,
+	error = rpcb_v4_register(net, program, version,
 					(const struct sockaddr *)&sin, netid);
 
 	/*
@@ -826,7 +845,7 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
 	 * registration request with the legacy rpcbind v2 protocol.
 	 */
 	if (error == -EPROTONOSUPPORT)
-		error = rpcb_register(program, version, protocol, port);
+		error = rpcb_register(net, program, version, protocol, port);
 
 	return error;
 }
@@ -842,7 +861,8 @@ static int __svc_rpcb_register4(const u32 program, const u32 version,
  * Returns zero on success; a negative errno value is returned
  * if any error occurs.
  */
-static int __svc_rpcb_register6(const u32 program, const u32 version,
+static int __svc_rpcb_register6(struct net *net, const u32 program,
+				const u32 version,
 				const unsigned short protocol,
 				const unsigned short port)
 {
@@ -865,7 +885,7 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
 		return -ENOPROTOOPT;
 	}
 
-	error = rpcb_v4_register(program, version,
+	error = rpcb_v4_register(net, program, version,
 					(const struct sockaddr *)&sin6, netid);
 
 	/*
@@ -885,7 +905,7 @@ static int __svc_rpcb_register6(const u32 program, const u32 version,
  * Returns zero on success; a negative errno value is returned
  * if any error occurs.
  */
-static int __svc_register(const char *progname,
+static int __svc_register(struct net *net, const char *progname,
 			  const u32 program, const u32 version,
 			  const int family,
 			  const unsigned short protocol,
@@ -895,12 +915,12 @@ static int __svc_register(const char *progname,
 
 	switch (family) {
 	case PF_INET:
-		error = __svc_rpcb_register4(program, version,
+		error = __svc_rpcb_register4(net, program, version,
 						protocol, port);
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
 	case PF_INET6:
-		error = __svc_rpcb_register6(program, version,
+		error = __svc_rpcb_register6(net, program, version,
 						protocol, port);
 #endif
 	}
@@ -914,14 +934,16 @@ static int __svc_register(const char *progname,
 /**
  * svc_register - register an RPC service with the local portmapper
  * @serv: svc_serv struct for the service to register
+ * @net: net namespace for the service to register
  * @family: protocol family of service's listener socket
  * @proto: transport protocol number to advertise
  * @port: port to advertise
  *
  * Service is registered for any address in the passed-in protocol family
  */
-int svc_register(const struct svc_serv *serv, const int family,
-		 const unsigned short proto, const unsigned short port)
+int svc_register(const struct svc_serv *serv, struct net *net,
+		 const int family, const unsigned short proto,
+		 const unsigned short port)
 {
 	struct svc_program	*progp;
 	unsigned int		i;
@@ -946,7 +968,7 @@ int svc_register(const struct svc_serv *serv, const int family,
 			if (progp->pg_vers[i]->vs_hidden)
 				continue;
 
-			error = __svc_register(progp->pg_name, progp->pg_prog,
+			error = __svc_register(net, progp->pg_name, progp->pg_prog,
 						i, family, proto, port);
 			if (error < 0)
 				break;
@@ -963,19 +985,19 @@ int svc_register(const struct svc_serv *serv, const int family,
  * any "inet6" entries anyway.  So a PMAP_UNSET should be sufficient
  * in this case to clear all existing entries for [program, version].
  */
-static void __svc_unregister(const u32 program, const u32 version,
+static void __svc_unregister(struct net *net, const u32 program, const u32 version,
 			     const char *progname)
 {
 	int error;
 
-	error = rpcb_v4_register(program, version, NULL, "");
+	error = rpcb_v4_register(net, program, version, NULL, "");
 
 	/*
 	 * User space didn't support rpcbind v4, so retry this
 	 * request with the legacy rpcbind v2 protocol.
 	 */
 	if (error == -EPROTONOSUPPORT)
-		error = rpcb_register(program, version, 0, 0);
+		error = rpcb_register(net, program, version, 0, 0);
 
 	dprintk("svc: %s(%sv%u), error %d\n",
 			__func__, progname, version, error);
@@ -989,7 +1011,7 @@ static void __svc_unregister(const u32 program, const u32 version,
  * The result of unregistration is reported via dprintk for those who want
  * verification of the result, but is otherwise not important.
  */
-static void svc_unregister(const struct svc_serv *serv)
+static void svc_unregister(const struct svc_serv *serv, struct net *net)
 {
 	struct svc_program *progp;
 	unsigned long flags;
@@ -1006,7 +1028,7 @@ static void svc_unregister(const struct svc_serv *serv)
 
 			dprintk("svc: attempting to unregister %sv%u\n",
 				progp->pg_name, i);
-			__svc_unregister(progp->pg_prog, i, progp->pg_name);
+			__svc_unregister(net, progp->pg_prog, i, progp->pg_name);
 		}
 	}
 
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 74cb0d8..4bda09d 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -922,48 +922,65 @@ void svc_close_xprt(struct svc_xprt *xprt)
 }
 EXPORT_SYMBOL_GPL(svc_close_xprt);
 
-static void svc_close_list(struct list_head *xprt_list)
+static void svc_close_list(struct list_head *xprt_list, struct net *net)
 {
 	struct svc_xprt *xprt;
 
 	list_for_each_entry(xprt, xprt_list, xpt_list) {
+		if (xprt->xpt_net != net)
+			continue;
 		set_bit(XPT_CLOSE, &xprt->xpt_flags);
 		set_bit(XPT_BUSY, &xprt->xpt_flags);
 	}
 }
 
-void svc_close_all(struct svc_serv *serv)
+static void svc_clear_pools(struct svc_serv *serv, struct net *net)
 {
 	struct svc_pool *pool;
 	struct svc_xprt *xprt;
 	struct svc_xprt *tmp;
 	int i;
 
-	svc_close_list(&serv->sv_tempsocks);
-	svc_close_list(&serv->sv_permsocks);
-
 	for (i = 0; i < serv->sv_nrpools; i++) {
 		pool = &serv->sv_pools[i];
 
 		spin_lock_bh(&pool->sp_lock);
-		while (!list_empty(&pool->sp_sockets)) {
-			xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready);
+		list_for_each_entry_safe(xprt, tmp, &pool->sp_sockets, xpt_ready) {
+			if (xprt->xpt_net != net)
+				continue;
 			list_del_init(&xprt->xpt_ready);
 		}
 		spin_unlock_bh(&pool->sp_lock);
 	}
+}
+
+static void svc_clear_list(struct list_head *xprt_list, struct net *net)
+{
+	struct svc_xprt *xprt;
+	struct svc_xprt *tmp;
+
+	list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
+		if (xprt->xpt_net != net)
+			continue;
+		svc_delete_xprt(xprt);
+	}
+	list_for_each_entry(xprt, xprt_list, xpt_list)
+		BUG_ON(xprt->xpt_net == net);
+}
+
+void svc_close_net(struct svc_serv *serv, struct net *net)
+{
+	svc_close_list(&serv->sv_tempsocks, net);
+	svc_close_list(&serv->sv_permsocks, net);
+
+	svc_clear_pools(serv, net);
 	/*
 	 * At this point the sp_sockets lists will stay empty, since
 	 * svc_enqueue will not add new entries without taking the
 	 * sp_lock and checking XPT_BUSY.
 	 */
-	list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list)
-		svc_delete_xprt(xprt);
-	list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list)
-		svc_delete_xprt(xprt);
-
-	BUG_ON(!list_empty(&serv->sv_permsocks));
-	BUG_ON(!list_empty(&serv->sv_tempsocks));
+	svc_clear_list(&serv->sv_tempsocks, net);
+	svc_clear_list(&serv->sv_permsocks, net);
 }
 
 /*
@@ -1089,6 +1106,7 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
  * svc_find_xprt - find an RPC transport instance
  * @serv: pointer to svc_serv to search
  * @xcl_name: C string containing transport's class name
+ * @net: owner net pointer
  * @af: Address family of transport's local address
  * @port: transport's IP port number
  *
@@ -1101,7 +1119,8 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
  * service's list that has a matching class name.
  */
 struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
-			       const sa_family_t af, const unsigned short port)
+			       struct net *net, const sa_family_t af,
+			       const unsigned short port)
 {
 	struct svc_xprt *xprt;
 	struct svc_xprt *found = NULL;
@@ -1112,6 +1131,8 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
 
 	spin_lock_bh(&serv->sv_lock);
 	list_for_each_entry(xprt, &serv->sv_permsocks, xpt_list) {
+		if (xprt->xpt_net != net)
+			continue;
 		if (strcmp(xprt->xpt_class->xcl_name, xcl_name))
 			continue;
 		if (af != AF_UNSPEC && af != xprt->xpt_local.ss_family)
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 01153ea..521d8f7 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -211,7 +211,7 @@ static int ip_map_parse(struct cache_detail *cd,
 	len = qword_get(&mesg, buf, mlen);
 	if (len <= 0) return -EINVAL;
 
-	if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0)
+	if (rpc_pton(cd->net, buf, len, &address.sa, sizeof(address)) == 0)
 		return -EINVAL;
 	switch (address.sa.sa_family) {
 	case AF_INET:
@@ -436,7 +436,6 @@ struct unix_gid {
 	uid_t			uid;
 	struct group_info	*gi;
 };
-static struct cache_head	*gid_table[GID_HASHMAX];
 
 static void unix_gid_put(struct kref *kref)
 {
@@ -494,8 +493,7 @@ static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
 	return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
 }
 
-static struct unix_gid *unix_gid_lookup(uid_t uid);
-extern struct cache_detail unix_gid_cache;
+static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid);
 
 static int unix_gid_parse(struct cache_detail *cd,
 			char *mesg, int mlen)
@@ -509,7 +507,7 @@ static int unix_gid_parse(struct cache_detail *cd,
 	time_t expiry;
 	struct unix_gid ug, *ugp;
 
-	if (mlen <= 0 || mesg[mlen-1] != '\n')
+	if (mesg[mlen - 1] != '\n')
 		return -EINVAL;
 	mesg[mlen-1] = 0;
 
@@ -539,19 +537,19 @@ static int unix_gid_parse(struct cache_detail *cd,
 		GROUP_AT(ug.gi, i) = gid;
 	}
 
-	ugp = unix_gid_lookup(uid);
+	ugp = unix_gid_lookup(cd, uid);
 	if (ugp) {
 		struct cache_head *ch;
 		ug.h.flags = 0;
 		ug.h.expiry_time = expiry;
-		ch = sunrpc_cache_update(&unix_gid_cache,
+		ch = sunrpc_cache_update(cd,
 					 &ug.h, &ugp->h,
 					 hash_long(uid, GID_HASHBITS));
 		if (!ch)
 			err = -ENOMEM;
 		else {
 			err = 0;
-			cache_put(ch, &unix_gid_cache);
+			cache_put(ch, cd);
 		}
 	} else
 		err = -ENOMEM;
@@ -587,10 +585,9 @@ static int unix_gid_show(struct seq_file *m,
 	return 0;
 }
 
-struct cache_detail unix_gid_cache = {
+static struct cache_detail unix_gid_cache_template = {
 	.owner		= THIS_MODULE,
 	.hash_size	= GID_HASHMAX,
-	.hash_table	= gid_table,
 	.name		= "auth.unix.gid",
 	.cache_put	= unix_gid_put,
 	.cache_upcall	= unix_gid_upcall,
@@ -602,14 +599,42 @@ struct cache_detail unix_gid_cache = {
 	.alloc		= unix_gid_alloc,
 };
 
-static struct unix_gid *unix_gid_lookup(uid_t uid)
+int unix_gid_cache_create(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd;
+	int err;
+
+	cd = cache_create_net(&unix_gid_cache_template, net);
+	if (IS_ERR(cd))
+		return PTR_ERR(cd);
+	err = cache_register_net(cd, net);
+	if (err) {
+		cache_destroy_net(cd, net);
+		return err;
+	}
+	sn->unix_gid_cache = cd;
+	return 0;
+}
+
+void unix_gid_cache_destroy(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd = sn->unix_gid_cache;
+
+	sn->unix_gid_cache = NULL;
+	cache_purge(cd);
+	cache_unregister_net(cd, net);
+	cache_destroy_net(cd, net);
+}
+
+static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid)
 {
 	struct unix_gid ug;
 	struct cache_head *ch;
 
 	ug.uid = uid;
-	ch = sunrpc_cache_lookup(&unix_gid_cache, &ug.h,
-				 hash_long(uid, GID_HASHBITS));
+	ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS));
 	if (ch)
 		return container_of(ch, struct unix_gid, h);
 	else
@@ -621,11 +646,13 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
 	struct unix_gid *ug;
 	struct group_info *gi;
 	int ret;
+	struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net,
+					    sunrpc_net_id);
 
-	ug = unix_gid_lookup(uid);
+	ug = unix_gid_lookup(sn->unix_gid_cache, uid);
 	if (!ug)
 		return ERR_PTR(-EAGAIN);
-	ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle);
+	ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle);
 	switch (ret) {
 	case -ENOENT:
 		return ERR_PTR(-ENOENT);
@@ -633,7 +660,7 @@ static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp)
 		return ERR_PTR(-ESHUTDOWN);
 	case 0:
 		gi = get_group_info(ug->gi);
-		cache_put(&ug->h, &unix_gid_cache);
+		cache_put(&ug->h, sn->unix_gid_cache);
 		return gi;
 	default:
 		return ERR_PTR(-EAGAIN);
@@ -849,56 +876,45 @@ struct auth_ops svcauth_unix = {
 	.set_client	= svcauth_unix_set_client,
 };
 
+static struct cache_detail ip_map_cache_template = {
+	.owner		= THIS_MODULE,
+	.hash_size	= IP_HASHMAX,
+	.name		= "auth.unix.ip",
+	.cache_put	= ip_map_put,
+	.cache_upcall	= ip_map_upcall,
+	.cache_parse	= ip_map_parse,
+	.cache_show	= ip_map_show,
+	.match		= ip_map_match,
+	.init		= ip_map_init,
+	.update		= update,
+	.alloc		= ip_map_alloc,
+};
+
 int ip_map_cache_create(struct net *net)
 {
-	int err = -ENOMEM;
-	struct cache_detail *cd;
-	struct cache_head **tbl;
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd;
+	int err;
 
-	cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL);
-	if (cd == NULL)
-		goto err_cd;
-
-	tbl = kzalloc(IP_HASHMAX * sizeof(struct cache_head *), GFP_KERNEL);
-	if (tbl == NULL)
-		goto err_tbl;
-
-	cd->owner = THIS_MODULE,
-	cd->hash_size = IP_HASHMAX,
-	cd->hash_table = tbl,
-	cd->name = "auth.unix.ip",
-	cd->cache_put = ip_map_put,
-	cd->cache_upcall = ip_map_upcall,
-	cd->cache_parse = ip_map_parse,
-	cd->cache_show = ip_map_show,
-	cd->match = ip_map_match,
-	cd->init = ip_map_init,
-	cd->update = update,
-	cd->alloc = ip_map_alloc,
-
+	cd = cache_create_net(&ip_map_cache_template, net);
+	if (IS_ERR(cd))
+		return PTR_ERR(cd);
 	err = cache_register_net(cd, net);
-	if (err)
-		goto err_reg;
-
+	if (err) {
+		cache_destroy_net(cd, net);
+		return err;
+	}
 	sn->ip_map_cache = cd;
 	return 0;
-
-err_reg:
-	kfree(tbl);
-err_tbl:
-	kfree(cd);
-err_cd:
-	return err;
 }
 
 void ip_map_cache_destroy(struct net *net)
 {
-	struct sunrpc_net *sn;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+	struct cache_detail *cd = sn->ip_map_cache;
 
-	sn = net_generic(net, sunrpc_net_id);
-	cache_purge(sn->ip_map_cache);
-	cache_unregister_net(sn->ip_map_cache, net);
-	kfree(sn->ip_map_cache->hash_table);
-	kfree(sn->ip_map_cache);
+	sn->ip_map_cache = NULL;
+	cache_purge(cd);
+	cache_unregister_net(cd, net);
+	cache_destroy_net(cd, net);
 }
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 4645709..4e870f2 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1381,8 +1381,6 @@ void svc_sock_update_bufs(struct svc_serv *serv)
 	spin_lock_bh(&serv->sv_lock);
 	list_for_each_entry(svsk, &serv->sv_permsocks, sk_xprt.xpt_list)
 		set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
-	list_for_each_entry(svsk, &serv->sv_tempsocks, sk_xprt.xpt_list)
-		set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
 	spin_unlock_bh(&serv->sv_lock);
 }
 EXPORT_SYMBOL_GPL(svc_sock_update_bufs);
@@ -1409,7 +1407,8 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
 
 	/* Register socket with portmapper */
 	if (*errp >= 0 && pmap_register)
-		*errp = svc_register(serv, inet->sk_family, inet->sk_protocol,
+		*errp = svc_register(serv, sock_net(sock->sk), inet->sk_family,
+				     inet->sk_protocol,
 				     ntohs(inet_sk(inet)->inet_sport));
 
 	if (*errp < 0) {
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index e65dcc6..af7d339 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -20,6 +20,8 @@
 #include <linux/sunrpc/stats.h>
 #include <linux/sunrpc/svc_xprt.h>
 
+#include "netns.h"
+
 /*
  * Declare the debug flags here
  */
@@ -110,7 +112,7 @@ proc_dodebug(ctl_table *table, int write,
 		*(unsigned int *) table->data = value;
 		/* Display the RPC tasks on writing to rpc_debug */
 		if (strcmp(table->procname, "rpc_debug") == 0)
-			rpc_show_tasks();
+			rpc_show_tasks(&init_net);
 	} else {
 		if (!access_ok(VERIFY_WRITE, buffer, left))
 			return -EFAULT;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 593f4c6..b97a3dd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -122,9 +122,9 @@ xdr_terminate_string(struct xdr_buf *buf, const u32 len)
 {
 	char *kaddr;
 
-	kaddr = kmap_atomic(buf->pages[0], KM_USER0);
+	kaddr = kmap_atomic(buf->pages[0]);
 	kaddr[buf->page_base + len] = '\0';
-	kunmap_atomic(kaddr, KM_USER0);
+	kunmap_atomic(kaddr);
 }
 EXPORT_SYMBOL_GPL(xdr_terminate_string);
 
@@ -232,12 +232,12 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base,
 		pgto_base -= copy;
 		pgfrom_base -= copy;
 
-		vto = kmap_atomic(*pgto, KM_USER0);
-		vfrom = kmap_atomic(*pgfrom, KM_USER1);
+		vto = kmap_atomic(*pgto);
+		vfrom = kmap_atomic(*pgfrom);
 		memmove(vto + pgto_base, vfrom + pgfrom_base, copy);
 		flush_dcache_page(*pgto);
-		kunmap_atomic(vfrom, KM_USER1);
-		kunmap_atomic(vto, KM_USER0);
+		kunmap_atomic(vfrom);
+		kunmap_atomic(vto);
 
 	} while ((len -= copy) != 0);
 }
@@ -267,9 +267,9 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
 		if (copy > len)
 			copy = len;
 
-		vto = kmap_atomic(*pgto, KM_USER0);
+		vto = kmap_atomic(*pgto);
 		memcpy(vto + pgbase, p, copy);
-		kunmap_atomic(vto, KM_USER0);
+		kunmap_atomic(vto);
 
 		len -= copy;
 		if (len == 0)
@@ -311,9 +311,9 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
 		if (copy > len)
 			copy = len;
 
-		vfrom = kmap_atomic(*pgfrom, KM_USER0);
+		vfrom = kmap_atomic(*pgfrom);
 		memcpy(p, vfrom + pgbase, copy);
-		kunmap_atomic(vfrom, KM_USER0);
+		kunmap_atomic(vfrom);
 
 		pgbase += copy;
 		if (pgbase == PAGE_CACHE_SIZE) {
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c64c0ef..32e3794 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -292,54 +292,57 @@ static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
 	return retval;
 }
 
-static void __xprt_lock_write_next(struct rpc_xprt *xprt)
+static bool __xprt_lock_write_func(struct rpc_task *task, void *data)
 {
-	struct rpc_task *task;
+	struct rpc_xprt *xprt = data;
 	struct rpc_rqst *req;
 
-	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
-		return;
-
-	task = rpc_wake_up_next(&xprt->sending);
-	if (task == NULL)
-		goto out_unlock;
-
 	req = task->tk_rqstp;
 	xprt->snd_task = task;
 	if (req) {
 		req->rq_bytes_sent = 0;
 		req->rq_ntrans++;
 	}
-	return;
+	return true;
+}
 
-out_unlock:
+static void __xprt_lock_write_next(struct rpc_xprt *xprt)
+{
+	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
+		return;
+
+	if (rpc_wake_up_first(&xprt->sending, __xprt_lock_write_func, xprt))
+		return;
 	xprt_clear_locked(xprt);
 }
 
-static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
+static bool __xprt_lock_write_cong_func(struct rpc_task *task, void *data)
 {
-	struct rpc_task *task;
+	struct rpc_xprt *xprt = data;
 	struct rpc_rqst *req;
 
-	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
-		return;
-	if (RPCXPRT_CONGESTED(xprt))
-		goto out_unlock;
-	task = rpc_wake_up_next(&xprt->sending);
-	if (task == NULL)
-		goto out_unlock;
-
 	req = task->tk_rqstp;
 	if (req == NULL) {
 		xprt->snd_task = task;
-		return;
+		return true;
 	}
 	if (__xprt_get_cong(xprt, task)) {
 		xprt->snd_task = task;
 		req->rq_bytes_sent = 0;
 		req->rq_ntrans++;
-		return;
+		return true;
 	}
+	return false;
+}
+
+static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
+{
+	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
+		return;
+	if (RPCXPRT_CONGESTED(xprt))
+		goto out_unlock;
+	if (rpc_wake_up_first(&xprt->sending, __xprt_lock_write_cong_func, xprt))
+		return;
 out_unlock:
 	xprt_clear_locked(xprt);
 }
@@ -712,9 +715,7 @@ void xprt_connect(struct rpc_task *task)
 	if (xprt_connected(xprt))
 		xprt_release_write(xprt, task);
 	else {
-		if (task->tk_rqstp)
-			task->tk_rqstp->rq_bytes_sent = 0;
-
+		task->tk_rqstp->rq_bytes_sent = 0;
 		task->tk_timeout = task->tk_rqstp->rq_timeout;
 		rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
 
@@ -884,7 +885,7 @@ void xprt_transmit(struct rpc_task *task)
 {
 	struct rpc_rqst	*req = task->tk_rqstp;
 	struct rpc_xprt	*xprt = req->rq_xprt;
-	int status;
+	int status, numreqs;
 
 	dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
 
@@ -921,9 +922,14 @@ void xprt_transmit(struct rpc_task *task)
 
 	xprt->ops->set_retrans_timeout(task);
 
+	numreqs = atomic_read(&xprt->num_reqs);
+	if (numreqs > xprt->stat.max_slots)
+		xprt->stat.max_slots = numreqs;
 	xprt->stat.sends++;
 	xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
 	xprt->stat.bklog_u += xprt->backlog.qlen;
+	xprt->stat.sending_u += xprt->sending.qlen;
+	xprt->stat.pending_u += xprt->pending.qlen;
 
 	/* Don't race with disconnect */
 	if (!xprt_connected(xprt))
@@ -1131,7 +1137,10 @@ void xprt_release(struct rpc_task *task)
 		return;
 
 	xprt = req->rq_xprt;
-	rpc_count_iostats(task);
+	if (task->tk_ops->rpc_count_stats != NULL)
+		task->tk_ops->rpc_count_stats(task, task->tk_calldata);
+	else if (task->tk_client)
+		rpc_count_iostats(task, task->tk_client->cl_metrics);
 	spin_lock_bh(&xprt->transport_lock);
 	xprt->ops->release_xprt(xprt, task);
 	if (xprt->ops->release_request)
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 554d081..1776e57 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -338,9 +338,9 @@ rpcrdma_inline_pullup(struct rpc_rqst *rqst, int pad)
 			curlen = copy_len;
 		dprintk("RPC:       %s: page %d destp 0x%p len %d curlen %d\n",
 			__func__, i, destp, copy_len, curlen);
-		srcp = kmap_atomic(ppages[i], KM_SKB_SUNRPC_DATA);
+		srcp = kmap_atomic(ppages[i]);
 		memcpy(destp, srcp+page_base, curlen);
-		kunmap_atomic(srcp, KM_SKB_SUNRPC_DATA);
+		kunmap_atomic(srcp);
 		rqst->rq_svec[0].iov_len += curlen;
 		destp += curlen;
 		copy_len -= curlen;
@@ -639,10 +639,10 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
 			dprintk("RPC:       %s: page %d"
 				" srcp 0x%p len %d curlen %d\n",
 				__func__, i, srcp, copy_len, curlen);
-			destp = kmap_atomic(ppages[i], KM_SKB_SUNRPC_DATA);
+			destp = kmap_atomic(ppages[i]);
 			memcpy(destp + page_base, srcp, curlen);
 			flush_dcache_page(ppages[i]);
-			kunmap_atomic(destp, KM_SKB_SUNRPC_DATA);
+			kunmap_atomic(destp);
 			srcp += curlen;
 			copy_len -= curlen;
 			if (copy_len == 0)
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
index 09af4fa..8343737 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -47,6 +47,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/svc_rdma.h>
+#include "xprt_rdma.h"
 
 #define RPCDBG_FACILITY	RPCDBG_SVCXPRT
 
diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
index 9530ef2..8d2eddd 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_marshal.c
@@ -60,21 +60,11 @@ static u32 *decode_read_list(u32 *va, u32 *vaend)
 	struct rpcrdma_read_chunk *ch = (struct rpcrdma_read_chunk *)va;
 
 	while (ch->rc_discrim != xdr_zero) {
-		u64 ch_offset;
-
 		if (((unsigned long)ch + sizeof(struct rpcrdma_read_chunk)) >
 		    (unsigned long)vaend) {
 			dprintk("svcrdma: vaend=%p, ch=%p\n", vaend, ch);
 			return NULL;
 		}
-
-		ch->rc_discrim = ntohl(ch->rc_discrim);
-		ch->rc_position = ntohl(ch->rc_position);
-		ch->rc_target.rs_handle = ntohl(ch->rc_target.rs_handle);
-		ch->rc_target.rs_length = ntohl(ch->rc_target.rs_length);
-		va = (u32 *)&ch->rc_target.rs_offset;
-		xdr_decode_hyper(va, &ch_offset);
-		put_unaligned(ch_offset, (u64 *)va);
 		ch++;
 	}
 	return (u32 *)&ch->rc_position;
@@ -91,7 +81,7 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
 	*byte_count = 0;
 	*ch_count = 0;
 	for (; ch->rc_discrim != 0; ch++) {
-		*byte_count = *byte_count + ch->rc_target.rs_length;
+		*byte_count = *byte_count + ntohl(ch->rc_target.rs_length);
 		*ch_count = *ch_count + 1;
 	}
 }
@@ -108,7 +98,8 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
  */
 static u32 *decode_write_list(u32 *va, u32 *vaend)
 {
-	int ch_no;
+	int nchunks;
+
 	struct rpcrdma_write_array *ary =
 		(struct rpcrdma_write_array *)va;
 
@@ -121,37 +112,24 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
 		dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
 		return NULL;
 	}
-	ary->wc_discrim = ntohl(ary->wc_discrim);
-	ary->wc_nchunks = ntohl(ary->wc_nchunks);
+	nchunks = ntohl(ary->wc_nchunks);
 	if (((unsigned long)&ary->wc_array[0] +
-	     (sizeof(struct rpcrdma_write_chunk) * ary->wc_nchunks)) >
+	     (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
 	    (unsigned long)vaend) {
 		dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
-			ary, ary->wc_nchunks, vaend);
+			ary, nchunks, vaend);
 		return NULL;
 	}
-	for (ch_no = 0; ch_no < ary->wc_nchunks; ch_no++) {
-		u64 ch_offset;
-
-		ary->wc_array[ch_no].wc_target.rs_handle =
-			ntohl(ary->wc_array[ch_no].wc_target.rs_handle);
-		ary->wc_array[ch_no].wc_target.rs_length =
-			ntohl(ary->wc_array[ch_no].wc_target.rs_length);
-		va = (u32 *)&ary->wc_array[ch_no].wc_target.rs_offset;
-		xdr_decode_hyper(va, &ch_offset);
-		put_unaligned(ch_offset, (u64 *)va);
-	}
-
 	/*
 	 * rs_length is the 2nd 4B field in wc_target and taking its
 	 * address skips the list terminator
 	 */
-	return (u32 *)&ary->wc_array[ch_no].wc_target.rs_length;
+	return (u32 *)&ary->wc_array[nchunks].wc_target.rs_length;
 }
 
 static u32 *decode_reply_array(u32 *va, u32 *vaend)
 {
-	int ch_no;
+	int nchunks;
 	struct rpcrdma_write_array *ary =
 		(struct rpcrdma_write_array *)va;
 
@@ -164,28 +142,15 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
 		dprintk("svcrdma: ary=%p, vaend=%p\n", ary, vaend);
 		return NULL;
 	}
-	ary->wc_discrim = ntohl(ary->wc_discrim);
-	ary->wc_nchunks = ntohl(ary->wc_nchunks);
+	nchunks = ntohl(ary->wc_nchunks);
 	if (((unsigned long)&ary->wc_array[0] +
-	     (sizeof(struct rpcrdma_write_chunk) * ary->wc_nchunks)) >
+	     (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
 	    (unsigned long)vaend) {
 		dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
-			ary, ary->wc_nchunks, vaend);
+			ary, nchunks, vaend);
 		return NULL;
 	}
-	for (ch_no = 0; ch_no < ary->wc_nchunks; ch_no++) {
-		u64 ch_offset;
-
-		ary->wc_array[ch_no].wc_target.rs_handle =
-			ntohl(ary->wc_array[ch_no].wc_target.rs_handle);
-		ary->wc_array[ch_no].wc_target.rs_length =
-			ntohl(ary->wc_array[ch_no].wc_target.rs_length);
-		va = (u32 *)&ary->wc_array[ch_no].wc_target.rs_offset;
-		xdr_decode_hyper(va, &ch_offset);
-		put_unaligned(ch_offset, (u64 *)va);
-	}
-
-	return (u32 *)&ary->wc_array[ch_no];
+	return (u32 *)&ary->wc_array[nchunks];
 }
 
 int svc_rdma_xdr_decode_req(struct rpcrdma_msg **rdma_req,
@@ -386,13 +351,14 @@ void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *ary,
 
 void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *ary,
 				     int chunk_no,
-				     u32 rs_handle, u64 rs_offset,
+				     __be32 rs_handle,
+				     __be64 rs_offset,
 				     u32 write_len)
 {
 	struct rpcrdma_segment *seg = &ary->wc_array[chunk_no].wc_target;
-	seg->rs_handle = htonl(rs_handle);
+	seg->rs_handle = rs_handle;
+	seg->rs_offset = rs_offset;
 	seg->rs_length = htonl(write_len);
-	xdr_encode_hyper((u32 *) &seg->rs_offset, rs_offset);
 }
 
 void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *xprt,
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index df67211..41cb63b 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -147,7 +147,7 @@ static int map_read_chunks(struct svcxprt_rdma *xprt,
 	page_off = 0;
 	ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
 	ch_no = 0;
-	ch_bytes = ch->rc_target.rs_length;
+	ch_bytes = ntohl(ch->rc_target.rs_length);
 	head->arg.head[0] = rqstp->rq_arg.head[0];
 	head->arg.tail[0] = rqstp->rq_arg.tail[0];
 	head->arg.pages = &head->pages[head->count];
@@ -183,7 +183,7 @@ static int map_read_chunks(struct svcxprt_rdma *xprt,
 			ch_no++;
 			ch++;
 			chl_map->ch[ch_no].start = sge_no;
-			ch_bytes = ch->rc_target.rs_length;
+			ch_bytes = ntohl(ch->rc_target.rs_length);
 			/* If bytes remaining account for next chunk */
 			if (byte_count) {
 				head->arg.page_len += ch_bytes;
@@ -281,11 +281,12 @@ static int fast_reg_read_chunks(struct svcxprt_rdma *xprt,
 	offset = 0;
 	ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
 	for (ch_no = 0; ch_no < ch_count; ch_no++) {
+		int len = ntohl(ch->rc_target.rs_length);
 		rpl_map->sge[ch_no].iov_base = frmr->kva + offset;
-		rpl_map->sge[ch_no].iov_len = ch->rc_target.rs_length;
+		rpl_map->sge[ch_no].iov_len = len;
 		chl_map->ch[ch_no].count = 1;
 		chl_map->ch[ch_no].start = ch_no;
-		offset += ch->rc_target.rs_length;
+		offset += len;
 		ch++;
 	}
 
@@ -316,7 +317,7 @@ static int rdma_set_ctxt_sge(struct svcxprt_rdma *xprt,
 	for (i = 0; i < count; i++) {
 		ctxt->sge[i].length = 0; /* in case map fails */
 		if (!frmr) {
-			BUG_ON(0 == virt_to_page(vec[i].iov_base));
+			BUG_ON(!virt_to_page(vec[i].iov_base));
 			off = (unsigned long)vec[i].iov_base & ~PAGE_MASK;
 			ctxt->sge[i].addr =
 				ib_dma_map_page(xprt->sc_cm_id->device,
@@ -426,6 +427,7 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
 
 	for (ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
 	     ch->rc_discrim != 0; ch++, ch_no++) {
+		u64 rs_offset;
 next_sge:
 		ctxt = svc_rdma_get_context(xprt);
 		ctxt->direction = DMA_FROM_DEVICE;
@@ -440,10 +442,10 @@ next_sge:
 		read_wr.opcode = IB_WR_RDMA_READ;
 		ctxt->wr_op = read_wr.opcode;
 		read_wr.send_flags = IB_SEND_SIGNALED;
-		read_wr.wr.rdma.rkey = ch->rc_target.rs_handle;
-		read_wr.wr.rdma.remote_addr =
-			get_unaligned(&(ch->rc_target.rs_offset)) +
-			sgl_offset;
+		read_wr.wr.rdma.rkey = ntohl(ch->rc_target.rs_handle);
+		xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset,
+				 &rs_offset);
+		read_wr.wr.rdma.remote_addr = rs_offset + sgl_offset;
 		read_wr.sg_list = ctxt->sge;
 		read_wr.num_sge =
 			rdma_read_max_sge(xprt, chl_map->ch[ch_no].count);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 249a835..42eb7ba 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -409,21 +409,21 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
 		u64 rs_offset;
 
 		arg_ch = &arg_ary->wc_array[chunk_no].wc_target;
-		write_len = min(xfer_len, arg_ch->rs_length);
+		write_len = min(xfer_len, ntohl(arg_ch->rs_length));
 
 		/* Prepare the response chunk given the length actually
 		 * written */
-		rs_offset = get_unaligned(&(arg_ch->rs_offset));
+		xdr_decode_hyper((__be32 *)&arg_ch->rs_offset, &rs_offset);
 		svc_rdma_xdr_encode_array_chunk(res_ary, chunk_no,
-					    arg_ch->rs_handle,
-					    rs_offset,
-					    write_len);
+						arg_ch->rs_handle,
+						arg_ch->rs_offset,
+						write_len);
 		chunk_off = 0;
 		while (write_len) {
 			int this_write;
 			this_write = min(write_len, max_write);
 			ret = send_write(xprt, rqstp,
-					 arg_ch->rs_handle,
+					 ntohl(arg_ch->rs_handle),
 					 rs_offset + chunk_off,
 					 xdr_off,
 					 this_write,
@@ -457,6 +457,7 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
 	u32 xdr_off;
 	int chunk_no;
 	int chunk_off;
+	int nchunks;
 	struct rpcrdma_segment *ch;
 	struct rpcrdma_write_array *arg_ary;
 	struct rpcrdma_write_array *res_ary;
@@ -476,26 +477,27 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
 		max_write = xprt->sc_max_sge * PAGE_SIZE;
 
 	/* xdr offset starts at RPC message */
+	nchunks = ntohl(arg_ary->wc_nchunks);
 	for (xdr_off = 0, chunk_no = 0;
-	     xfer_len && chunk_no < arg_ary->wc_nchunks;
+	     xfer_len && chunk_no < nchunks;
 	     chunk_no++) {
 		u64 rs_offset;
 		ch = &arg_ary->wc_array[chunk_no].wc_target;
-		write_len = min(xfer_len, ch->rs_length);
+		write_len = min(xfer_len, htonl(ch->rs_length));
 
 		/* Prepare the reply chunk given the length actually
 		 * written */
-		rs_offset = get_unaligned(&(ch->rs_offset));
+		xdr_decode_hyper((__be32 *)&ch->rs_offset, &rs_offset);
 		svc_rdma_xdr_encode_array_chunk(res_ary, chunk_no,
-					    ch->rs_handle, rs_offset,
-					    write_len);
+						ch->rs_handle, ch->rs_offset,
+						write_len);
 		chunk_off = 0;
 		while (write_len) {
 			int this_write;
 
 			this_write = min(write_len, max_write);
 			ret = send_write(xprt, rqstp,
-					 ch->rs_handle,
+					 ntohl(ch->rs_handle),
 					 rs_offset + chunk_off,
 					 xdr_off,
 					 this_write,
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 894cb42..73b428b 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -51,6 +51,7 @@
 #include <rdma/rdma_cm.h>
 #include <linux/sunrpc/svc_rdma.h>
 #include <linux/export.h>
+#include "xprt_rdma.h"
 
 #define RPCDBG_FACILITY	RPCDBG_SVCXPRT
 
@@ -90,12 +91,6 @@ struct svc_xprt_class svc_rdma_class = {
 	.xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
 };
 
-/* WR context cache. Created in svc_rdma.c  */
-extern struct kmem_cache *svc_rdma_ctxt_cachep;
-
-/* Workqueue created in svc_rdma.c */
-extern struct workqueue_struct *svc_rdma_wq;
-
 struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
 {
 	struct svc_rdma_op_ctxt *ctxt;
@@ -150,9 +145,6 @@ void svc_rdma_put_context(struct svc_rdma_op_ctxt *ctxt, int free_pages)
 	atomic_dec(&xprt->sc_ctxt_used);
 }
 
-/* Temporary NFS request map cache. Created in svc_rdma.c  */
-extern struct kmem_cache *svc_rdma_map_cachep;
-
 /*
  * Temporary NFS req mappings are shared across all transport
  * instances. These are short lived and should be bounded by the number
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 08c5d5a..9a66c95 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -343,4 +343,11 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *);
  */
 int rpcrdma_marshal_req(struct rpc_rqst *);
 
+/* Temporary NFS request map cache. Created in svc_rdma.c  */
+extern struct kmem_cache *svc_rdma_map_cachep;
+/* WR context cache. Created in svc_rdma.c  */
+extern struct kmem_cache *svc_rdma_ctxt_cachep;
+/* Workqueue created in svc_rdma.c */
+extern struct workqueue_struct *svc_rdma_wq;
+
 #endif				/* _LINUX_SUNRPC_XPRT_RDMA_H */
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 55472c4..4c8281d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2227,7 +2227,7 @@ static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 		idle_time = (long)(jiffies - xprt->last_used) / HZ;
 
 	seq_printf(seq, "\txprt:\tlocal %lu %lu %lu %ld %lu %lu %lu "
-			"%llu %llu\n",
+			"%llu %llu %lu %llu %llu\n",
 			xprt->stat.bind_count,
 			xprt->stat.connect_count,
 			xprt->stat.connect_time,
@@ -2236,7 +2236,10 @@ static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 			xprt->stat.recvs,
 			xprt->stat.bad_xids,
 			xprt->stat.req_u,
-			xprt->stat.bklog_u);
+			xprt->stat.bklog_u,
+			xprt->stat.max_slots,
+			xprt->stat.sending_u,
+			xprt->stat.pending_u);
 }
 
 /**
@@ -2249,14 +2252,18 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 {
 	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
 
-	seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
+	seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %llu %llu "
+			"%lu %llu %llu\n",
 			transport->srcport,
 			xprt->stat.bind_count,
 			xprt->stat.sends,
 			xprt->stat.recvs,
 			xprt->stat.bad_xids,
 			xprt->stat.req_u,
-			xprt->stat.bklog_u);
+			xprt->stat.bklog_u,
+			xprt->stat.max_slots,
+			xprt->stat.sending_u,
+			xprt->stat.pending_u);
 }
 
 /**
@@ -2273,7 +2280,8 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 	if (xprt_connected(xprt))
 		idle_time = (long)(jiffies - xprt->last_used) / HZ;
 
-	seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
+	seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu "
+			"%llu %llu %lu %llu %llu\n",
 			transport->srcport,
 			xprt->stat.bind_count,
 			xprt->stat.connect_count,
@@ -2283,7 +2291,10 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 			xprt->stat.recvs,
 			xprt->stat.bad_xids,
 			xprt->stat.req_u,
-			xprt->stat.bklog_u);
+			xprt->stat.bklog_u,
+			xprt->stat.max_slots,
+			xprt->stat.sending_u,
+			xprt->stat.pending_u);
 }
 
 /*
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index e758139..c3e65ae 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -74,15 +74,13 @@ static struct ctl_table_root net_sysctl_ro_root = {
 
 static int __net_init sysctl_net_init(struct net *net)
 {
-	setup_sysctl_set(&net->sysctls,
-			 &net_sysctl_ro_root.default_set,
-			 is_seen);
+	setup_sysctl_set(&net->sysctls, &net_sysctl_root, is_seen);
 	return 0;
 }
 
 static void __net_exit sysctl_net_exit(struct net *net)
 {
-	WARN_ON(!list_empty(&net->sysctls.list));
+	retire_sysctl_set(&net->sysctls);
 }
 
 static struct pernet_operations sysctl_pernet_ops = {
@@ -90,36 +88,32 @@ static struct pernet_operations sysctl_pernet_ops = {
 	.exit = sysctl_net_exit,
 };
 
-static __init int sysctl_init(void)
+static __init int net_sysctl_init(void)
 {
 	int ret;
 	ret = register_pernet_subsys(&sysctl_pernet_ops);
 	if (ret)
 		goto out;
-	register_sysctl_root(&net_sysctl_root);
-	setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL);
+	setup_sysctl_set(&net_sysctl_ro_root.default_set, &net_sysctl_ro_root, NULL);
 	register_sysctl_root(&net_sysctl_ro_root);
+	register_sysctl_root(&net_sysctl_root);
 out:
 	return ret;
 }
-subsys_initcall(sysctl_init);
+subsys_initcall(net_sysctl_init);
 
 struct ctl_table_header *register_net_sysctl_table(struct net *net,
 	const struct ctl_path *path, struct ctl_table *table)
 {
-	struct nsproxy namespaces;
-	namespaces = *current->nsproxy;
-	namespaces.net_ns = net;
-	return __register_sysctl_paths(&net_sysctl_root,
-					&namespaces, path, table);
+	return __register_sysctl_paths(&net->sysctls, path, table);
 }
 EXPORT_SYMBOL_GPL(register_net_sysctl_table);
 
 struct ctl_table_header *register_net_sysctl_rotable(const
 		struct ctl_path *path, struct ctl_table *table)
 {
-	return __register_sysctl_paths(&net_sysctl_ro_root,
-			&init_nsproxy, path, table);
+	return __register_sysctl_paths(&net_sysctl_ro_root.default_set,
+					path, table);
 }
 EXPORT_SYMBOL_GPL(register_net_sysctl_rotable);
 
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 8eb87b1..41ecf31 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -157,39 +157,14 @@ u32 tipc_bclink_get_last_sent(void)
 	return bcl->fsm_msg_cnt;
 }
 
-/**
- * bclink_set_gap - set gap according to contents of current deferred pkt queue
- *
- * Called with 'node' locked, bc_lock unlocked
- */
-
-static void bclink_set_gap(struct tipc_node *n_ptr)
-{
-	struct sk_buff *buf = n_ptr->bclink.deferred_head;
-
-	n_ptr->bclink.gap_after = n_ptr->bclink.gap_to =
-		mod(n_ptr->bclink.last_in);
-	if (unlikely(buf != NULL))
-		n_ptr->bclink.gap_to = mod(buf_seqno(buf) - 1);
-}
-
-/**
- * bclink_ack_allowed - test if ACK or NACK message can be sent at this moment
- *
- * This mechanism endeavours to prevent all nodes in network from trying
- * to ACK or NACK at the same time.
- *
- * Note: TIPC uses a different trigger to distribute ACKs than it does to
- *       distribute NACKs, but tries to use the same spacing (divide by 16).
- */
-
-static int bclink_ack_allowed(u32 n)
+static void bclink_update_last_sent(struct tipc_node *node, u32 seqno)
 {
-	return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag;
+	node->bclink.last_sent = less_eq(node->bclink.last_sent, seqno) ?
+						seqno : node->bclink.last_sent;
 }
 
 
-/**
+/*
  * tipc_bclink_retransmit_to - get most recent node to request retransmission
  *
  * Called with bc_lock locked
@@ -300,140 +275,94 @@ exit:
 	spin_unlock_bh(&bc_lock);
 }
 
-/**
- * bclink_send_ack - unicast an ACK msg
+/*
+ * tipc_bclink_update_link_state - update broadcast link state
  *
  * tipc_net_lock and node lock set
  */
 
-static void bclink_send_ack(struct tipc_node *n_ptr)
+void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
 {
-	struct tipc_link *l_ptr = n_ptr->active_links[n_ptr->addr & 1];
+	struct sk_buff *buf;
 
-	if (l_ptr != NULL)
-		tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
-}
+	/* Ignore "stale" link state info */
 
-/**
- * bclink_send_nack- broadcast a NACK msg
- *
- * tipc_net_lock and node lock set
- */
+	if (less_eq(last_sent, n_ptr->bclink.last_in))
+		return;
 
-static void bclink_send_nack(struct tipc_node *n_ptr)
-{
-	struct sk_buff *buf;
-	struct tipc_msg *msg;
+	/* Update link synchronization state; quit if in sync */
+
+	bclink_update_last_sent(n_ptr, last_sent);
+
+	if (n_ptr->bclink.last_sent == n_ptr->bclink.last_in)
+		return;
+
+	/* Update out-of-sync state; quit if loss is still unconfirmed */
+
+	if ((++n_ptr->bclink.oos_state) == 1) {
+		if (n_ptr->bclink.deferred_size < (TIPC_MIN_LINK_WIN / 2))
+			return;
+		n_ptr->bclink.oos_state++;
+	}
 
-	if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to))
+	/* Don't NACK if one has been recently sent (or seen) */
+
+	if (n_ptr->bclink.oos_state & 0x1)
 		return;
 
+	/* Send NACK */
+
 	buf = tipc_buf_acquire(INT_H_SIZE);
 	if (buf) {
-		msg = buf_msg(buf);
+		struct tipc_msg *msg = buf_msg(buf);
+
 		tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG,
-			 INT_H_SIZE, n_ptr->addr);
+			      INT_H_SIZE, n_ptr->addr);
 		msg_set_non_seq(msg, 1);
 		msg_set_mc_netid(msg, tipc_net_id);
-		msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in));
-		msg_set_bcgap_after(msg, n_ptr->bclink.gap_after);
-		msg_set_bcgap_to(msg, n_ptr->bclink.gap_to);
-		msg_set_bcast_tag(msg, tipc_own_tag);
+		msg_set_bcast_ack(msg, n_ptr->bclink.last_in);
+		msg_set_bcgap_after(msg, n_ptr->bclink.last_in);
+		msg_set_bcgap_to(msg, n_ptr->bclink.deferred_head
+				 ? buf_seqno(n_ptr->bclink.deferred_head) - 1
+				 : n_ptr->bclink.last_sent);
 
+		spin_lock_bh(&bc_lock);
 		tipc_bearer_send(&bcbearer->bearer, buf, NULL);
 		bcl->stats.sent_nacks++;
+		spin_unlock_bh(&bc_lock);
 		buf_discard(buf);
 
-		/*
-		 * Ensure we doesn't send another NACK msg to the node
-		 * until 16 more deferred messages arrive from it
-		 * (i.e. helps prevent all nodes from NACK'ing at same time)
-		 */
-
-		n_ptr->bclink.nack_sync = tipc_own_tag;
+		n_ptr->bclink.oos_state++;
 	}
 }
 
-/**
- * tipc_bclink_check_gap - send a NACK if a sequence gap exists
+/*
+ * bclink_peek_nack - monitor retransmission requests sent by other nodes
  *
- * tipc_net_lock and node lock set
- */
-
-void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 last_sent)
-{
-	if (!n_ptr->bclink.supported ||
-	    less_eq(last_sent, mod(n_ptr->bclink.last_in)))
-		return;
-
-	bclink_set_gap(n_ptr);
-	if (n_ptr->bclink.gap_after == n_ptr->bclink.gap_to)
-		n_ptr->bclink.gap_to = last_sent;
-	bclink_send_nack(n_ptr);
-}
-
-/**
- * tipc_bclink_peek_nack - process a NACK msg meant for another node
+ * Delay any upcoming NACK by this node if another node has already
+ * requested the first message this node is going to ask for.
  *
  * Only tipc_net_lock set.
  */
 
-static void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to)
+static void bclink_peek_nack(struct tipc_msg *msg)
 {
-	struct tipc_node *n_ptr = tipc_node_find(dest);
-	u32 my_after, my_to;
+	struct tipc_node *n_ptr = tipc_node_find(msg_destnode(msg));
 
-	if (unlikely(!n_ptr || !tipc_node_is_up(n_ptr)))
+	if (unlikely(!n_ptr))
 		return;
+
 	tipc_node_lock(n_ptr);
-	/*
-	 * Modify gap to suppress unnecessary NACKs from this node
-	 */
-	my_after = n_ptr->bclink.gap_after;
-	my_to = n_ptr->bclink.gap_to;
-
-	if (less_eq(gap_after, my_after)) {
-		if (less(my_after, gap_to) && less(gap_to, my_to))
-			n_ptr->bclink.gap_after = gap_to;
-		else if (less_eq(my_to, gap_to))
-			n_ptr->bclink.gap_to = n_ptr->bclink.gap_after;
-	} else if (less_eq(gap_after, my_to)) {
-		if (less_eq(my_to, gap_to))
-			n_ptr->bclink.gap_to = gap_after;
-	} else {
-		/*
-		 * Expand gap if missing bufs not in deferred queue:
-		 */
-		struct sk_buff *buf = n_ptr->bclink.deferred_head;
-		u32 prev = n_ptr->bclink.gap_to;
 
-		for (; buf; buf = buf->next) {
-			u32 seqno = buf_seqno(buf);
+	if (n_ptr->bclink.supported &&
+	    (n_ptr->bclink.last_in != n_ptr->bclink.last_sent) &&
+	    (n_ptr->bclink.last_in == msg_bcgap_after(msg)))
+		n_ptr->bclink.oos_state = 2;
 
-			if (mod(seqno - prev) != 1) {
-				buf = NULL;
-				break;
-			}
-			if (seqno == gap_after)
-				break;
-			prev = seqno;
-		}
-		if (buf == NULL)
-			n_ptr->bclink.gap_to = gap_after;
-	}
-	/*
-	 * Some nodes may send a complementary NACK now:
-	 */
-	if (bclink_ack_allowed(sender_tag + 1)) {
-		if (n_ptr->bclink.gap_to != n_ptr->bclink.gap_after) {
-			bclink_send_nack(n_ptr);
-			bclink_set_gap(n_ptr);
-		}
-	}
 	tipc_node_unlock(n_ptr);
 }
 
-/**
+/*
  * tipc_bclink_send_msg - broadcast a packet to all nodes in cluster
  */
 
@@ -460,7 +389,33 @@ exit:
 	return res;
 }
 
-/**
+/*
+ * bclink_accept_pkt - accept an incoming, in-sequence broadcast packet
+ *
+ * Called with both sending node's lock and bc_lock taken.
+ */
+
+static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
+{
+	bclink_update_last_sent(node, seqno);
+	node->bclink.last_in = seqno;
+	node->bclink.oos_state = 0;
+	bcl->stats.recv_info++;
+
+	/*
+	 * Unicast an ACK periodically, ensuring that
+	 * all nodes in the cluster don't ACK at the same time
+	 */
+
+	if (((seqno - tipc_own_addr) % TIPC_MIN_LINK_WIN) == 0) {
+		tipc_link_send_proto_msg(
+			node->active_links[node->addr & 1],
+			STATE_MSG, 0, 0, 0, 0, 0);
+		bcl->stats.sent_acks++;
+	}
+}
+
+/*
  * tipc_bclink_recv_pkt - receive a broadcast packet, and deliver upwards
  *
  * tipc_net_lock is read_locked, no other locks set
@@ -472,7 +427,7 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
 	struct tipc_node *node;
 	u32 next_in;
 	u32 seqno;
-	struct sk_buff *deferred;
+	int deferred;
 
 	/* Screen out unwanted broadcast messages */
 
@@ -487,6 +442,8 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
 	if (unlikely(!node->bclink.supported))
 		goto unlock;
 
+	/* Handle broadcast protocol message */
+
 	if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) {
 		if (msg_type(msg) != STATE_MSG)
 			goto unlock;
@@ -501,85 +458,114 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
 			spin_unlock_bh(&bc_lock);
 		} else {
 			tipc_node_unlock(node);
-			tipc_bclink_peek_nack(msg_destnode(msg),
-					      msg_bcast_tag(msg),
-					      msg_bcgap_after(msg),
-					      msg_bcgap_to(msg));
+			bclink_peek_nack(msg);
 		}
 		goto exit;
 	}
 
 	/* Handle in-sequence broadcast message */
 
-receive:
-	next_in = mod(node->bclink.last_in + 1);
 	seqno = msg_seqno(msg);
+	next_in = mod(node->bclink.last_in + 1);
 
 	if (likely(seqno == next_in)) {
-		bcl->stats.recv_info++;
-		node->bclink.last_in++;
-		bclink_set_gap(node);
-		if (unlikely(bclink_ack_allowed(seqno))) {
-			bclink_send_ack(node);
-			bcl->stats.sent_acks++;
-		}
+receive:
+		/* Deliver message to destination */
+
 		if (likely(msg_isdata(msg))) {
+			spin_lock_bh(&bc_lock);
+			bclink_accept_pkt(node, seqno);
+			spin_unlock_bh(&bc_lock);
 			tipc_node_unlock(node);
 			if (likely(msg_mcast(msg)))
 				tipc_port_recv_mcast(buf, NULL);
 			else
 				buf_discard(buf);
 		} else if (msg_user(msg) == MSG_BUNDLER) {
+			spin_lock_bh(&bc_lock);
+			bclink_accept_pkt(node, seqno);
 			bcl->stats.recv_bundles++;
 			bcl->stats.recv_bundled += msg_msgcnt(msg);
+			spin_unlock_bh(&bc_lock);
 			tipc_node_unlock(node);
 			tipc_link_recv_bundle(buf);
 		} else if (msg_user(msg) == MSG_FRAGMENTER) {
+			int ret = tipc_link_recv_fragment(&node->bclink.defragm,
+						      &buf, &msg);
+			if (ret < 0)
+				goto unlock;
+			spin_lock_bh(&bc_lock);
+			bclink_accept_pkt(node, seqno);
 			bcl->stats.recv_fragments++;
-			if (tipc_link_recv_fragment(&node->bclink.defragm,
-						    &buf, &msg))
+			if (ret > 0)
 				bcl->stats.recv_fragmented++;
+			spin_unlock_bh(&bc_lock);
 			tipc_node_unlock(node);
 			tipc_net_route_msg(buf);
 		} else if (msg_user(msg) == NAME_DISTRIBUTOR) {
+			spin_lock_bh(&bc_lock);
+			bclink_accept_pkt(node, seqno);
+			spin_unlock_bh(&bc_lock);
 			tipc_node_unlock(node);
 			tipc_named_recv(buf);
 		} else {
+			spin_lock_bh(&bc_lock);
+			bclink_accept_pkt(node, seqno);
+			spin_unlock_bh(&bc_lock);
 			tipc_node_unlock(node);
 			buf_discard(buf);
 		}
 		buf = NULL;
+
+		/* Determine new synchronization state */
+
 		tipc_node_lock(node);
-		deferred = node->bclink.deferred_head;
-		if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) {
-			buf = deferred;
-			msg = buf_msg(buf);
-			node->bclink.deferred_head = deferred->next;
-			goto receive;
-		}
-	} else if (less(next_in, seqno)) {
-		u32 gap_after = node->bclink.gap_after;
-		u32 gap_to = node->bclink.gap_to;
-
-		if (tipc_link_defer_pkt(&node->bclink.deferred_head,
-					&node->bclink.deferred_tail,
-					buf)) {
-			node->bclink.nack_sync++;
-			bcl->stats.deferred_recv++;
-			if (seqno == mod(gap_after + 1))
-				node->bclink.gap_after = seqno;
-			else if (less(gap_after, seqno) && less(seqno, gap_to))
-				node->bclink.gap_to = seqno;
+		if (unlikely(!tipc_node_is_up(node)))
+			goto unlock;
+
+		if (node->bclink.last_in == node->bclink.last_sent)
+			goto unlock;
+
+		if (!node->bclink.deferred_head) {
+			node->bclink.oos_state = 1;
+			goto unlock;
 		}
+
+		msg = buf_msg(node->bclink.deferred_head);
+		seqno = msg_seqno(msg);
+		next_in = mod(next_in + 1);
+		if (seqno != next_in)
+			goto unlock;
+
+		/* Take in-sequence message from deferred queue & deliver it */
+
+		buf = node->bclink.deferred_head;
+		node->bclink.deferred_head = buf->next;
+		node->bclink.deferred_size--;
+		goto receive;
+	}
+
+	/* Handle out-of-sequence broadcast message */
+
+	if (less(next_in, seqno)) {
+		deferred = tipc_link_defer_pkt(&node->bclink.deferred_head,
+					       &node->bclink.deferred_tail,
+					       buf);
+		node->bclink.deferred_size += deferred;
+		bclink_update_last_sent(node, seqno);
 		buf = NULL;
-		if (bclink_ack_allowed(node->bclink.nack_sync)) {
-			if (gap_to != gap_after)
-				bclink_send_nack(node);
-			bclink_set_gap(node);
-		}
-	} else {
+	} else
+		deferred = 0;
+
+	spin_lock_bh(&bc_lock);
+
+	if (deferred)
+		bcl->stats.deferred_recv++;
+	else
 		bcl->stats.duplicates++;
-	}
+
+	spin_unlock_bh(&bc_lock);
+
 unlock:
 	tipc_node_unlock(node);
 exit:
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index b009666..5571394 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -96,7 +96,7 @@ int  tipc_bclink_send_msg(struct sk_buff *buf);
 void tipc_bclink_recv_pkt(struct sk_buff *buf);
 u32  tipc_bclink_get_last_sent(void);
 u32  tipc_bclink_acks_missing(struct tipc_node *n_ptr);
-void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 seqno);
+void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent);
 int  tipc_bclink_stats(char *stats_buf, const u32 buf_size);
 int  tipc_bclink_reset_stats(void);
 int  tipc_bclink_set_queue_limits(u32 limit);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ac1832a..d8b0a22 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1501,13 +1501,13 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
 		tipc_node_lock(n_ptr);
 
 		tipc_addr_string_fill(addr_string, n_ptr->addr);
-		info("Multicast link info for %s\n", addr_string);
+		info("Broadcast link info for %s\n", addr_string);
+		info("Supportable: %d,  ", n_ptr->bclink.supportable);
 		info("Supported: %d,  ", n_ptr->bclink.supported);
 		info("Acked: %u\n", n_ptr->bclink.acked);
 		info("Last in: %u,  ", n_ptr->bclink.last_in);
-		info("Gap after: %u,  ", n_ptr->bclink.gap_after);
-		info("Gap to: %u\n", n_ptr->bclink.gap_to);
-		info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync);
+		info("Oos state: %u,  ", n_ptr->bclink.oos_state);
+		info("Last sent: %u\n", n_ptr->bclink.last_sent);
 
 		tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
 
@@ -1736,7 +1736,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
 
 		/* Release acked messages */
 
-		if (tipc_node_is_up(n_ptr) && n_ptr->bclink.supported)
+		if (n_ptr->bclink.supported)
 			tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
 
 		crs = l_ptr->first_out;
@@ -1774,6 +1774,7 @@ protocol_check:
 					head = link_insert_deferred_queue(l_ptr,
 									  head);
 				if (likely(msg_is_dest(msg, tipc_own_addr))) {
+					int ret;
 deliver:
 					if (likely(msg_isdata(msg))) {
 						tipc_node_unlock(n_ptr);
@@ -1798,11 +1799,15 @@ deliver:
 						continue;
 					case MSG_FRAGMENTER:
 						l_ptr->stats.recv_fragments++;
-						if (tipc_link_recv_fragment(&l_ptr->defragm_buf,
-									    &buf, &msg)) {
+						ret = tipc_link_recv_fragment(
+							&l_ptr->defragm_buf,
+							&buf, &msg);
+						if (ret == 1) {
 							l_ptr->stats.recv_fragmented++;
 							goto deliver;
 						}
+						if (ret == -1)
+							l_ptr->next_in_no--;
 						break;
 					case CHANGEOVER_PROTOCOL:
 						type = msg_type(msg);
@@ -1853,17 +1858,16 @@ cont:
 }
 
 /*
- * link_defer_buf(): Sort a received out-of-sequence packet
- *                   into the deferred reception queue.
- * Returns the increase of the queue length,i.e. 0 or 1
+ * tipc_link_defer_pkt - Add out-of-sequence message to deferred reception queue
+ *
+ * Returns increase in queue length (i.e. 0 or 1)
  */
 
-u32 tipc_link_defer_pkt(struct sk_buff **head,
-			struct sk_buff **tail,
+u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail,
 			struct sk_buff *buf)
 {
-	struct sk_buff *prev = NULL;
-	struct sk_buff *crs = *head;
+	struct sk_buff *queue_buf;
+	struct sk_buff **prev;
 	u32 seq_no = buf_seqno(buf);
 
 	buf->next = NULL;
@@ -1881,31 +1885,30 @@ u32 tipc_link_defer_pkt(struct sk_buff **head,
 		return 1;
 	}
 
-	/* Scan through queue and sort it in */
-	do {
-		struct tipc_msg *msg = buf_msg(crs);
+	/* Locate insertion point in queue, then insert; discard if duplicate */
+	prev = head;
+	queue_buf = *head;
+	for (;;) {
+		u32 curr_seqno = buf_seqno(queue_buf);
 
-		if (less(seq_no, msg_seqno(msg))) {
-			buf->next = crs;
-			if (prev)
-				prev->next = buf;
-			else
-				*head = buf;
-			return 1;
+		if (seq_no == curr_seqno) {
+			buf_discard(buf);
+			return 0;
 		}
-		if (seq_no == msg_seqno(msg))
+
+		if (less(seq_no, curr_seqno))
 			break;
-		prev = crs;
-		crs = crs->next;
-	} while (crs);
 
-	/* Message is a duplicate of an existing message */
+		prev = &queue_buf->next;
+		queue_buf = queue_buf->next;
+	}
 
-	buf_discard(buf);
-	return 0;
+	buf->next = queue_buf;
+	*prev = buf;
+	return 1;
 }
 
-/**
+/*
  * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet
  */
 
@@ -1956,6 +1959,13 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
 	u32 msg_size = sizeof(l_ptr->proto_msg);
 	int r_flag;
 
+	/* Discard any previous message that was deferred due to congestion */
+
+	if (l_ptr->proto_msg_queue) {
+		buf_discard(l_ptr->proto_msg_queue);
+		l_ptr->proto_msg_queue = NULL;
+	}
+
 	if (link_blocked(l_ptr))
 		return;
 
@@ -1964,9 +1974,11 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
 	if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG))
 		return;
 
+	/* Create protocol message with "out-of-sequence" sequence number */
+
 	msg_set_type(msg, msg_typ);
 	msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
-	msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in));
+	msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
 	msg_set_last_bcast(msg, tipc_bclink_get_last_sent());
 
 	if (msg_typ == STATE_MSG) {
@@ -2020,44 +2032,36 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
 	r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
 	msg_set_redundant_link(msg, r_flag);
 	msg_set_linkprio(msg, l_ptr->priority);
-
-	/* Ensure sequence number will not fit : */
+	msg_set_size(msg, msg_size);
 
 	msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2)));
 
-	/* Congestion? */
-
-	if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
-		if (!l_ptr->proto_msg_queue) {
-			l_ptr->proto_msg_queue =
-				tipc_buf_acquire(sizeof(l_ptr->proto_msg));
-		}
-		buf = l_ptr->proto_msg_queue;
-		if (!buf)
-			return;
-		skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
-		return;
-	}
-
-	/* Message can be sent */
-
 	buf = tipc_buf_acquire(msg_size);
 	if (!buf)
 		return;
 
 	skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
-	msg_set_size(buf_msg(buf), msg_size);
 
-	if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
-		l_ptr->unacked_window = 0;
-		buf_discard(buf);
+	/* Defer message if bearer is already congested */
+
+	if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
+		l_ptr->proto_msg_queue = buf;
 		return;
 	}
 
-	/* New congestion */
-	tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
-	l_ptr->proto_msg_queue = buf;
-	l_ptr->stats.bearer_congs++;
+	/* Defer message if attempting to send results in bearer congestion */
+
+	if (!tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
+		tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
+		l_ptr->proto_msg_queue = buf;
+		l_ptr->stats.bearer_congs++;
+		return;
+	}
+
+	/* Discard message if it was sent successfully */
+
+	l_ptr->unacked_window = 0;
+	buf_discard(buf);
 }
 
 /*
@@ -2105,6 +2109,8 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
 			l_ptr->owner->block_setup = WAIT_NODE_DOWN;
 		}
 
+		link_state_event(l_ptr, RESET_MSG);
+
 		/* fall thru' */
 	case ACTIVATE_MSG:
 		/* Update link settings according other endpoint's values */
@@ -2127,16 +2133,22 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
 		} else {
 			l_ptr->max_pkt = l_ptr->max_pkt_target;
 		}
-		l_ptr->owner->bclink.supported = (max_pkt_info != 0);
+		l_ptr->owner->bclink.supportable = (max_pkt_info != 0);
 
-		link_state_event(l_ptr, msg_type(msg));
+		/* Synchronize broadcast link info, if not done previously */
+
+		if (!tipc_node_is_up(l_ptr->owner)) {
+			l_ptr->owner->bclink.last_sent =
+				l_ptr->owner->bclink.last_in =
+				msg_last_bcast(msg);
+			l_ptr->owner->bclink.oos_state = 0;
+		}
 
 		l_ptr->peer_session = msg_session(msg);
 		l_ptr->peer_bearer_id = msg_bearer_id(msg);
 
-		/* Synchronize broadcast sequence numbers */
-		if (!tipc_node_redundant_links(l_ptr->owner))
-			l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg));
+		if (msg_type(msg) == ACTIVATE_MSG)
+			link_state_event(l_ptr, ACTIVATE_MSG);
 		break;
 	case STATE_MSG:
 
@@ -2177,7 +2189,9 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf)
 
 		/* Protocol message before retransmits, reduce loss risk */
 
-		tipc_bclink_check_gap(l_ptr->owner, msg_last_bcast(msg));
+		if (l_ptr->owner->bclink.supported)
+			tipc_bclink_update_link_state(l_ptr->owner,
+						      msg_last_bcast(msg));
 
 		if (rec_gap || (msg_probe(msg))) {
 			tipc_link_send_proto_msg(l_ptr, STATE_MSG,
@@ -2623,7 +2637,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
 			set_fragm_size(pbuf, fragm_sz);
 			set_expected_frags(pbuf, exp_fragm_cnt - 1);
 		} else {
-			warn("Link unable to reassemble fragmented message\n");
+			dbg("Link unable to reassemble fragmented message\n");
+			buf_discard(fbuf);
+			return -1;
 		}
 		buf_discard(fbuf);
 		return 0;
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 98ebb37..acecfda 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -239,9 +239,6 @@ exit:
  *
  * Invoked for each publication issued by a newly failed node.
  * Removes publication structure from name table & deletes it.
- * In rare cases the link may have come back up again when this
- * function is called, and we have two items representing the same
- * publication. Nudge this item's key to distinguish it from the other.
  */
 
 static void named_purge_publ(struct publication *publ)
@@ -249,7 +246,6 @@ static void named_purge_publ(struct publication *publ)
 	struct publication *p;
 
 	write_lock_bh(&tipc_nametbl_lock);
-	publ->key += 1222345;
 	p = tipc_nametbl_remove_publ(publ->type, publ->lower,
 				     publ->node, publ->ref, publ->key);
 	if (p)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 6b226fa..7bc45e1 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -49,9 +49,8 @@ LIST_HEAD(tipc_node_list);
 static u32 tipc_num_nodes;
 
 static atomic_t tipc_num_links = ATOMIC_INIT(0);
-u32 tipc_own_tag;
 
-/**
+/*
  * tipc_node_find - locate specified node object, if it exists
  */
 
@@ -306,10 +305,9 @@ static void node_established_contact(struct tipc_node *n_ptr)
 	/* Syncronize broadcast acks */
 	n_ptr->bclink.acked = tipc_bclink_get_last_sent();
 
-	if (n_ptr->bclink.supported) {
+	if (n_ptr->bclink.supportable) {
 		tipc_bclink_add_node(n_ptr->addr);
-		if (n_ptr->addr < tipc_own_addr)
-			tipc_own_tag++;
+		n_ptr->bclink.supported = 1;
 	}
 }
 
@@ -338,12 +336,12 @@ static void node_lost_contact(struct tipc_node *n_ptr)
 	/* Flush broadcast link info associated with lost node */
 
 	if (n_ptr->bclink.supported) {
-		n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0;
 		while (n_ptr->bclink.deferred_head) {
 			struct sk_buff *buf = n_ptr->bclink.deferred_head;
 			n_ptr->bclink.deferred_head = buf->next;
 			buf_discard(buf);
 		}
+		n_ptr->bclink.deferred_size = 0;
 
 		if (n_ptr->bclink.defragm) {
 			buf_discard(n_ptr->bclink.defragm);
@@ -352,8 +350,6 @@ static void node_lost_contact(struct tipc_node *n_ptr)
 
 		tipc_bclink_remove_node(n_ptr->addr);
 		tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ);
-		if (n_ptr->addr < tipc_own_addr)
-			tipc_own_tag--;
 
 		n_ptr->bclink.supported = 0;
 	}
@@ -449,7 +445,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
 
 	read_lock_bh(&tipc_net_lock);
 
-	/* Get space for all unicast links + multicast link */
+	/* Get space for all unicast links + broadcast link */
 
 	payload_size = TLV_SPACE(sizeof(link_info)) *
 		(atomic_read(&tipc_num_links) + 1);
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 0b1c5f8..e1b78a2 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -62,12 +62,13 @@
  * @link_cnt: number of links to node
  * @permit_changeover: non-zero if node has redundant links to this system
  * @bclink: broadcast-related info
+ *    @supportable: non-zero if node supports TIPC b'cast link capability
  *    @supported: non-zero if node supports TIPC b'cast capability
  *    @acked: sequence # of last outbound b'cast message acknowledged by node
  *    @last_in: sequence # of last in-sequence b'cast message received from node
- *    @gap_after: sequence # of last message not requiring a NAK request
- *    @gap_to: sequence # of last message requiring a NAK request
- *    @nack_sync: counter that determines when NAK requests should be sent
+ *    @last_sent: sequence # of last b'cast message sent by node
+ *    @oos_state: state tracker for handling OOS b'cast messages
+ *    @deferred_size: number of OOS b'cast messages in deferred queue
  *    @deferred_head: oldest OOS b'cast message received from node
  *    @deferred_tail: newest OOS b'cast message received from node
  *    @defragm: list of partially reassembled b'cast message fragments from node
@@ -86,12 +87,13 @@ struct tipc_node {
 	int block_setup;
 	int permit_changeover;
 	struct {
-		int supported;
+		u8 supportable;
+		u8 supported;
 		u32 acked;
 		u32 last_in;
-		u32 gap_after;
-		u32 gap_to;
-		u32 nack_sync;
+		u32 last_sent;
+		u32 oos_state;
+		u32 deferred_size;
 		struct sk_buff *deferred_head;
 		struct sk_buff *deferred_tail;
 		struct sk_buff *defragm;
@@ -112,8 +114,6 @@ static inline unsigned int tipc_hashfn(u32 addr)
 	return addr & (NODE_HTABLE_SIZE - 1);
 }
 
-extern u32 tipc_own_tag;
-
 struct tipc_node *tipc_node_find(u32 addr);
 struct tipc_node *tipc_node_create(u32 addr);
 void tipc_node_delete(struct tipc_node *n_ptr);
diff --git a/net/tipc/port.c b/net/tipc/port.c
index d91efc6..ba3268b 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -400,15 +400,16 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err)
 
 	/* send self-abort message when rejecting on a connected port */
 	if (msg_connected(msg)) {
-		struct sk_buff *abuf = NULL;
 		struct tipc_port *p_ptr = tipc_port_lock(msg_destport(msg));
 
 		if (p_ptr) {
+			struct sk_buff *abuf = NULL;
+
 			if (p_ptr->connected)
 				abuf = port_build_self_abort_msg(p_ptr, err);
 			tipc_port_unlock(p_ptr);
+			tipc_net_route_msg(abuf);
 		}
-		tipc_net_route_msg(abuf);
 	}
 
 	/* send returned message & dispose of rejected message */
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 85d3bb7..0be4d24 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -530,6 +530,16 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
 static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
 				  struct msghdr *, size_t, int);
 
+static void unix_set_peek_off(struct sock *sk, int val)
+{
+	struct unix_sock *u = unix_sk(sk);
+
+	mutex_lock(&u->readlock);
+	sk->sk_peek_off = val;
+	mutex_unlock(&u->readlock);
+}
+
+
 static const struct proto_ops unix_stream_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
@@ -549,6 +559,7 @@ static const struct proto_ops unix_stream_ops = {
 	.recvmsg =	unix_stream_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
+	.set_peek_off =	unix_set_peek_off,
 };
 
 static const struct proto_ops unix_dgram_ops = {
@@ -570,6 +581,7 @@ static const struct proto_ops unix_dgram_ops = {
 	.recvmsg =	unix_dgram_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
+	.set_peek_off =	unix_set_peek_off,
 };
 
 static const struct proto_ops unix_seqpacket_ops = {
@@ -591,6 +603,7 @@ static const struct proto_ops unix_seqpacket_ops = {
 	.recvmsg =	unix_seqpacket_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
+	.set_peek_off =	unix_set_peek_off,
 };
 
 static struct proto unix_proto = {
@@ -1756,6 +1769,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 	int noblock = flags & MSG_DONTWAIT;
 	struct sk_buff *skb;
 	int err;
+	int peeked, skip;
 
 	err = -EOPNOTSUPP;
 	if (flags&MSG_OOB)
@@ -1769,7 +1783,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 		goto out;
 	}
 
-	skb = skb_recv_datagram(sk, flags, noblock, &err);
+	skip = sk_peek_offset(sk, flags);
+
+	skb = __skb_recv_datagram(sk, flags, &peeked, &skip, &err);
 	if (!skb) {
 		unix_state_lock(sk);
 		/* Signal EOF on disconnected non-blocking SEQPACKET socket. */
@@ -1786,12 +1802,12 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 	if (msg->msg_name)
 		unix_copy_addr(msg, skb->sk);
 
-	if (size > skb->len)
-		size = skb->len;
-	else if (size < skb->len)
+	if (size > skb->len - skip)
+		size = skb->len - skip;
+	else if (size < skb->len - skip)
 		msg->msg_flags |= MSG_TRUNC;
 
-	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
+	err = skb_copy_datagram_iovec(skb, skip, msg->msg_iov, size);
 	if (err)
 		goto out_free;
 
@@ -1808,6 +1824,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 	if (!(flags & MSG_PEEK)) {
 		if (UNIXCB(skb).fp)
 			unix_detach_fds(siocb->scm, skb);
+
+		sk_peek_offset_bwd(sk, skb->len);
 	} else {
 		/* It is questionable: on PEEK we could:
 		   - do not return fds - good, but too simple 8)
@@ -1821,6 +1839,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
 		   clearly however!
 
 		*/
+
+		sk_peek_offset_fwd(sk, size);
+
 		if (UNIXCB(skb).fp)
 			siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
 	}
@@ -1884,6 +1905,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 	int target;
 	int err = 0;
 	long timeo;
+	int skip;
 
 	err = -EINVAL;
 	if (sk->sk_state != TCP_ESTABLISHED)
@@ -1913,12 +1935,15 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 		goto out;
 	}
 
+	skip = sk_peek_offset(sk, flags);
+
 	do {
 		int chunk;
 		struct sk_buff *skb;
 
 		unix_state_lock(sk);
 		skb = skb_peek(&sk->sk_receive_queue);
+again:
 		if (skb == NULL) {
 			unix_sk(sk)->recursion_level = 0;
 			if (copied >= target)
@@ -1953,6 +1978,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			unix_state_unlock(sk);
 			break;
 		}
+
+		if (skip >= skb->len) {
+			skip -= skb->len;
+			skb = skb_peek_next(skb, &sk->sk_receive_queue);
+			goto again;
+		}
+
 		unix_state_unlock(sk);
 
 		if (check_creds) {
@@ -1972,8 +2004,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			sunaddr = NULL;
 		}
 
-		chunk = min_t(unsigned int, skb->len, size);
-		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+		chunk = min_t(unsigned int, skb->len - skip, size);
+		if (memcpy_toiovec(msg->msg_iov, skb->data + skip, chunk)) {
 			if (copied == 0)
 				copied = -EFAULT;
 			break;
@@ -1985,6 +2017,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 		if (!(flags & MSG_PEEK)) {
 			skb_pull(skb, chunk);
 
+			sk_peek_offset_bwd(sk, chunk);
+
 			if (UNIXCB(skb).fp)
 				unix_detach_fds(siocb->scm, skb);
 
@@ -2002,6 +2036,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			if (UNIXCB(skb).fp)
 				siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
 
+			sk_peek_offset_fwd(sk, chunk);
+
 			break;
 		}
 	} while (size);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 43ad9c8..3ac2dd0 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -144,11 +144,6 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu
 	return container_of(pub, struct cfg80211_internal_bss, pub);
 }
 
-static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss)
-{
-	kref_get(&bss->ref);
-}
-
 static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
 {
 	atomic_inc(&bss->hold);
@@ -325,15 +320,13 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 			 const u8 *bssid,
 			 const u8 *ssid, int ssid_len,
 			 const u8 *ie, int ie_len,
-			 const u8 *key, int key_len, int key_idx,
-			 bool local_state_change);
+			 const u8 *key, int key_len, int key_idx);
 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev, struct ieee80211_channel *chan,
 		       enum nl80211_auth_type auth_type, const u8 *bssid,
 		       const u8 *ssid, int ssid_len,
 		       const u8 *ie, int ie_len,
-		       const u8 *key, int key_len, int key_idx,
-		       bool local_state_change);
+		       const u8 *key, int key_len, int key_idx);
 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 			  struct net_device *dev,
 			  struct ieee80211_channel *chan,
@@ -421,7 +414,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 			     size_t ie_len, u16 reason, bool from_ap);
 void cfg80211_sme_scan_done(struct net_device *dev);
 void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
-void cfg80211_sme_disassoc(struct net_device *dev, int idx);
+void cfg80211_sme_disassoc(struct net_device *dev,
+			   struct cfg80211_internal_bss *bss);
 void __cfg80211_scan_done(struct work_struct *wk);
 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
 void __cfg80211_sched_scan_results(struct work_struct *wk);
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 8c550df..9d3e3b6 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -55,6 +55,7 @@ const struct mesh_config default_mesh_config = {
 	.min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
 	.dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
 	.dot11MeshGateAnnouncementProtocol = false,
+	.dot11MeshForwarding = true,
 };
 
 const struct mesh_setup default_mesh_setup = {
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 438dfc1..d553d36 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -20,40 +20,18 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
-	u8 *bssid = mgmt->bssid;
-	int i;
-	u16 status = le16_to_cpu(mgmt->u.auth.status_code);
-	bool done = false;
 
 	wdev_lock(wdev);
 
-	for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (wdev->authtry_bsses[i] &&
-		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
-							ETH_ALEN) == 0) {
-			if (status == WLAN_STATUS_SUCCESS) {
-				wdev->auth_bsses[i] = wdev->authtry_bsses[i];
-			} else {
-				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-			}
-			wdev->authtry_bsses[i] = NULL;
-			done = true;
-			break;
-		}
-	}
-
-	if (done) {
-		nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
-		cfg80211_sme_rx_auth(dev, buf, len);
-	}
+	nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
+	cfg80211_sme_rx_auth(dev, buf, len);
 
 	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_auth);
 
-void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
+void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
+			    const u8 *buf, size_t len)
 {
 	u16 status_code;
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -61,8 +39,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 	u8 *ie = mgmt->u.assoc_resp.variable;
-	int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
-	struct cfg80211_internal_bss *bss = NULL;
+	int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
 
 	wdev_lock(wdev);
 
@@ -75,43 +52,20 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 	 * frame instead of reassoc.
 	 */
 	if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
-	    cfg80211_sme_failed_reassoc(wdev))
+	    cfg80211_sme_failed_reassoc(wdev)) {
+		cfg80211_put_bss(bss);
 		goto out;
+	}
 
 	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
 
-	if (status_code == WLAN_STATUS_SUCCESS) {
-		for (i = 0; i < MAX_AUTH_BSSES; i++) {
-			if (!wdev->auth_bsses[i])
-				continue;
-			if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
-				   ETH_ALEN) == 0) {
-				bss = wdev->auth_bsses[i];
-				wdev->auth_bsses[i] = NULL;
-				/* additional reference to drop hold */
-				cfg80211_ref_bss(bss);
-				break;
-			}
-		}
-
-		/*
-		 * We might be coming here because the driver reported
-		 * a successful association at the same time as the
-		 * user requested a deauth. In that case, we will have
-		 * removed the BSS from the auth_bsses list due to the
-		 * deauth request when the assoc response makes it. If
-		 * the two code paths acquire the lock the other way
-		 * around, that's just the standard situation of a
-		 * deauth being requested while connected.
-		 */
-		if (!bss)
-			goto out;
-	} else if (wdev->conn) {
+	if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
 		cfg80211_sme_failed_assoc(wdev);
 		/*
 		 * do not call connect_result() now because the
 		 * sme will schedule work that does it later.
 		 */
+		cfg80211_put_bss(bss);
 		goto out;
 	}
 
@@ -124,17 +78,10 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 		wdev->sme_state = CFG80211_SME_CONNECTING;
 	}
 
-	/* this consumes one bss reference (unless bss is NULL) */
+	/* this consumes the bss reference */
 	__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
 				  status_code,
-				  status_code == WLAN_STATUS_SUCCESS,
-				  bss ? &bss->pub : NULL);
-	/* drop hold now, and also reference acquired above */
-	if (bss) {
-		cfg80211_unhold_bss(bss);
-		cfg80211_put_bss(&bss->pub);
-	}
-
+				  status_code == WLAN_STATUS_SUCCESS, bss);
  out:
 	wdev_unlock(wdev);
 }
@@ -148,8 +95,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 	const u8 *bssid = mgmt->bssid;
-	int i;
-	bool found = false, was_current = false;
+	bool was_current = false;
 
 	ASSERT_WDEV_LOCK(wdev);
 
@@ -158,32 +104,9 @@ void __cfg80211_send_deauth(struct net_device *dev,
 		cfg80211_unhold_bss(wdev->current_bss);
 		cfg80211_put_bss(&wdev->current_bss->pub);
 		wdev->current_bss = NULL;
-		found = true;
 		was_current = true;
-	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (wdev->auth_bsses[i] &&
-		    memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
-			cfg80211_unhold_bss(wdev->auth_bsses[i]);
-			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
-			wdev->auth_bsses[i] = NULL;
-			found = true;
-			break;
-		}
-		if (wdev->authtry_bsses[i] &&
-		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
-			   ETH_ALEN) == 0 &&
-		    memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) {
-			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-			wdev->authtry_bsses[i] = NULL;
-			found = true;
-			break;
-		}
 	}
 
-	if (!found)
-		return;
-
 	nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
 
 	if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
@@ -220,10 +143,8 @@ void __cfg80211_send_disassoc(struct net_device *dev,
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 	const u8 *bssid = mgmt->bssid;
-	int i;
 	u16 reason_code;
 	bool from_ap;
-	bool done = false;
 
 	ASSERT_WDEV_LOCK(wdev);
 
@@ -234,16 +155,10 @@ void __cfg80211_send_disassoc(struct net_device *dev,
 
 	if (wdev->current_bss &&
 	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
-		for (i = 0; i < MAX_AUTH_BSSES; i++) {
-			if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
-				continue;
-			wdev->auth_bsses[i] = wdev->current_bss;
-			wdev->current_bss = NULL;
-			done = true;
-			cfg80211_sme_disassoc(dev, i);
-			break;
-		}
-		WARN_ON(!done);
+		cfg80211_sme_disassoc(dev, wdev->current_bss);
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
+		wdev->current_bss = NULL;
 	} else
 		WARN_ON(1);
 
@@ -287,34 +202,6 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
 }
 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
 
-static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
-{
-	int i;
-	bool done = false;
-
-	ASSERT_WDEV_LOCK(wdev);
-
-	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
-		if (wdev->authtry_bsses[i] &&
-		    memcmp(wdev->authtry_bsses[i]->pub.bssid,
-			   addr, ETH_ALEN) == 0) {
-			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-			wdev->authtry_bsses[i] = NULL;
-			done = true;
-			break;
-		}
-	}
-
-	WARN_ON(!done);
-}
-
-void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
-{
-	__cfg80211_auth_remove(dev->ieee80211_ptr, addr);
-}
-EXPORT_SYMBOL(__cfg80211_auth_canceled);
-
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
@@ -329,8 +216,6 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
 					  false, NULL);
 
-	__cfg80211_auth_remove(wdev, addr);
-
 	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
@@ -340,8 +225,6 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	int i;
-	bool done = false;
 
 	wdev_lock(wdev);
 
@@ -351,20 +234,6 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
 					  false, NULL);
 
-	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
-		if (wdev->auth_bsses[i] &&
-		    memcmp(wdev->auth_bsses[i]->pub.bssid,
-			   addr, ETH_ALEN) == 0) {
-			cfg80211_unhold_bss(wdev->auth_bsses[i]);
-			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
-			wdev->auth_bsses[i] = NULL;
-			done = true;
-			break;
-		}
-	}
-
-	WARN_ON(!done);
-
 	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
@@ -403,13 +272,11 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 			 const u8 *bssid,
 			 const u8 *ssid, int ssid_len,
 			 const u8 *ie, int ie_len,
-			 const u8 *key, int key_len, int key_idx,
-			 bool local_state_change)
+			 const u8 *key, int key_len, int key_idx)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_auth_request req;
-	struct cfg80211_internal_bss *bss;
-	int i, err, slot = -1, nfree = 0;
+	int err;
 
 	ASSERT_WDEV_LOCK(wdev);
 
@@ -421,20 +288,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 	    memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
 		return -EALREADY;
 
-	for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (wdev->authtry_bsses[i] &&
-		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
-						ETH_ALEN) == 0)
-			return -EALREADY;
-		if (wdev->auth_bsses[i] &&
-		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
-						ETH_ALEN) == 0)
-			return -EALREADY;
-	}
-
 	memset(&req, 0, sizeof(req));
 
-	req.local_state_change = local_state_change;
 	req.ie = ie;
 	req.ie_len = ie_len;
 	req.auth_type = auth_type;
@@ -446,39 +301,9 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 	if (!req.bss)
 		return -ENOENT;
 
-	bss = bss_from_pub(req.bss);
-
-	for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
-			slot = i;
-			nfree++;
-		}
-	}
-
-	/* we need one free slot for disassoc and one for this auth */
-	if (nfree < 2) {
-		err = -ENOSPC;
-		goto out;
-	}
-
-	if (local_state_change)
-		wdev->auth_bsses[slot] = bss;
-	else
-		wdev->authtry_bsses[slot] = bss;
-	cfg80211_hold_bss(bss);
-
 	err = rdev->ops->auth(&rdev->wiphy, dev, &req);
-	if (err) {
-		if (local_state_change)
-			wdev->auth_bsses[slot] = NULL;
-		else
-			wdev->authtry_bsses[slot] = NULL;
-		cfg80211_unhold_bss(bss);
-	}
 
- out:
-	if (err)
-		cfg80211_put_bss(req.bss);
+	cfg80211_put_bss(req.bss);
 	return err;
 }
 
@@ -487,15 +312,14 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 		       enum nl80211_auth_type auth_type, const u8 *bssid,
 		       const u8 *ssid, int ssid_len,
 		       const u8 *ie, int ie_len,
-		       const u8 *key, int key_len, int key_idx,
-		       bool local_state_change)
+		       const u8 *key, int key_len, int key_idx)
 {
 	int err;
 
 	wdev_lock(dev->ieee80211_ptr);
 	err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
 				   ssid, ssid_len, ie, ie_len,
-				   key, key_len, key_idx, local_state_change);
+				   key, key_len, key_idx);
 	wdev_unlock(dev->ieee80211_ptr);
 
 	return err;
@@ -530,8 +354,7 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_assoc_request req;
-	struct cfg80211_internal_bss *bss;
-	int i, err, slot = -1;
+	int err;
 	bool was_connected = false;
 
 	ASSERT_WDEV_LOCK(wdev);
@@ -573,26 +396,14 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 		return -ENOENT;
 	}
 
-	bss = bss_from_pub(req.bss);
-
-	for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (bss == wdev->auth_bsses[i]) {
-			slot = i;
-			break;
-		}
-	}
+	err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
 
-	if (slot < 0) {
-		err = -ENOTCONN;
-		goto out;
+	if (err) {
+		if (was_connected)
+			wdev->sme_state = CFG80211_SME_CONNECTED;
+		cfg80211_put_bss(req.bss);
 	}
 
-	err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
- out:
-	if (err && was_connected)
-		wdev->sme_state = CFG80211_SME_CONNECTED;
-	/* still a reference in wdev->auth_bsses[slot] */
-	cfg80211_put_bss(req.bss);
 	return err;
 }
 
@@ -624,34 +435,25 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 			   bool local_state_change)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct cfg80211_deauth_request req;
-	int i;
+	struct cfg80211_deauth_request req = {
+		.bssid = bssid,
+		.reason_code = reason,
+		.ie = ie,
+		.ie_len = ie_len,
+	};
 
 	ASSERT_WDEV_LOCK(wdev);
 
-	memset(&req, 0, sizeof(req));
-	req.reason_code = reason;
-	req.local_state_change = local_state_change;
-	req.ie = ie;
-	req.ie_len = ie_len;
-	if (wdev->current_bss &&
-	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
-		req.bss = &wdev->current_bss->pub;
-	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (wdev->auth_bsses[i] &&
-		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
-			req.bss = &wdev->auth_bsses[i]->pub;
-			break;
-		}
-		if (wdev->authtry_bsses[i] &&
-		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
-			req.bss = &wdev->authtry_bsses[i]->pub;
-			break;
+	if (local_state_change) {
+		if (wdev->current_bss &&
+		    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->current_bss);
+			cfg80211_put_bss(&wdev->current_bss->pub);
+			wdev->current_bss = NULL;
 		}
-	}
 
-	if (!req.bss)
-		return -ENOTCONN;
+		return 0;
+	}
 
 	return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 }
@@ -722,7 +524,7 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_deauth_request req;
-	int i;
+	u8 bssid[ETH_ALEN];
 
 	ASSERT_WDEV_LOCK(wdev);
 
@@ -734,35 +536,17 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 	req.ie = NULL;
 	req.ie_len = 0;
 
-	if (wdev->current_bss) {
-		req.bss = &wdev->current_bss->pub;
-		rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
-		if (wdev->current_bss) {
-			cfg80211_unhold_bss(wdev->current_bss);
-			cfg80211_put_bss(&wdev->current_bss->pub);
-			wdev->current_bss = NULL;
-		}
-	}
+	if (!wdev->current_bss)
+		return;
 
-	for (i = 0; i < MAX_AUTH_BSSES; i++) {
-		if (wdev->auth_bsses[i]) {
-			req.bss = &wdev->auth_bsses[i]->pub;
-			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
-			if (wdev->auth_bsses[i]) {
-				cfg80211_unhold_bss(wdev->auth_bsses[i]);
-				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
-				wdev->auth_bsses[i] = NULL;
-			}
-		}
-		if (wdev->authtry_bsses[i]) {
-			req.bss = &wdev->authtry_bsses[i]->pub;
-			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
-			if (wdev->authtry_bsses[i]) {
-				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
-				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
-				wdev->authtry_bsses[i] = NULL;
-			}
-		}
+	memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
+	req.bssid = bssid;
+	rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
+
+	if (wdev->current_bss) {
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
+		wdev->current_bss = NULL;
 	}
 }
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index afeea32..fe27476 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -427,10 +427,9 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
 
 	if (tb[NL80211_KEY_DEFAULT_TYPES]) {
 		struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
-		int err = nla_parse_nested(kdt,
-					   NUM_NL80211_KEY_DEFAULT_TYPES - 1,
-					   tb[NL80211_KEY_DEFAULT_TYPES],
-					   nl80211_key_default_policy);
+		err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
+				       tb[NL80211_KEY_DEFAULT_TYPES],
+				       nl80211_key_default_policy);
 		if (err)
 			return err;
 
@@ -2655,13 +2654,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 		break;
 	case NL80211_IFTYPE_P2P_CLIENT:
 	case NL80211_IFTYPE_STATION:
-		/* disallow things sta doesn't support */
-		if (params.plink_action)
-			return -EINVAL;
-		if (params.ht_capa)
-			return -EINVAL;
-		if (params.listen_interval >= 0)
-			return -EINVAL;
 		/*
 		 * Don't allow userspace to change the TDLS_PEER flag,
 		 * but silently ignore attempts to change it since we
@@ -2669,7 +2661,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 		 * to change the flag.
 		 */
 		params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
-
+		/* fall through */
+	case NL80211_IFTYPE_ADHOC:
+		/* disallow things sta doesn't support */
+		if (params.plink_action)
+			return -EINVAL;
+		if (params.ht_capa)
+			return -EINVAL;
+		if (params.listen_interval >= 0)
+			return -EINVAL;
 		/* reject any changes other than AUTHORIZED */
 		if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
 			return -EINVAL;
@@ -3259,6 +3259,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
 			cur_params.dot11MeshHWMPRannInterval);
 	NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
 			cur_params.dot11MeshGateAnnouncementProtocol);
+	NLA_PUT_U8(msg, NL80211_MESHCONF_FORWARDING,
+			cur_params.dot11MeshForwarding);
 	nla_nest_end(msg, pinfoattr);
 	genlmsg_end(msg, hdr);
 	return genlmsg_reply(msg, info);
@@ -3290,6 +3292,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
 	[NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
 	[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
 	[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
+	[NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
 };
 
 static const struct nla_policy
@@ -3379,6 +3382,8 @@ do {\
 			dot11MeshGateAnnouncementProtocol, mask,
 			NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
 			nla_get_u8);
+	FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
+			mask, NL80211_MESHCONF_FORWARDING, nla_get_u8);
 	if (mask_out)
 		*mask_out = mask;
 
@@ -4079,7 +4084,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
 	struct cfg80211_bss *res = &intbss->pub;
 	void *hdr;
 	struct nlattr *bss;
-	int i;
 
 	ASSERT_WDEV_LOCK(wdev);
 
@@ -4132,13 +4136,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
 		if (intbss == wdev->current_bss)
 			NLA_PUT_U32(msg, NL80211_BSS_STATUS,
 				    NL80211_BSS_STATUS_ASSOCIATED);
-		else for (i = 0; i < MAX_AUTH_BSSES; i++) {
-			if (intbss != wdev->auth_bsses[i])
-				continue;
-			NLA_PUT_U32(msg, NL80211_BSS_STATUS,
-				    NL80211_BSS_STATUS_AUTHENTICATED);
-			break;
-		}
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		if (intbss == wdev->current_bss)
@@ -4406,10 +4403,16 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 
 	local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
 
+	/*
+	 * Since we no longer track auth state, ignore
+	 * requests to only change local state.
+	 */
+	if (local_state_change)
+		return 0;
+
 	return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
 				  ssid, ssid_len, ie, ie_len,
-				  key.p.key, key.p.key_len, key.idx,
-				  local_state_change);
+				  key.p.key, key.p.key_len, key.idx);
 }
 
 static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
@@ -4781,7 +4784,6 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 			nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
 		struct ieee80211_supported_band *sband =
 			wiphy->bands[ibss.channel->band];
-		int err;
 
 		err = ieee80211_get_ratemask(sband, rates, n_rates,
 					     &ibss.basic_rates);
@@ -4801,6 +4803,9 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 			return PTR_ERR(connkeys);
 	}
 
+	ibss.control_port =
+		nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
+
 	err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
 	if (err)
 		kfree(connkeys);
@@ -5390,9 +5395,39 @@ static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
 	return mask;
 }
 
+static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
+			       u8 *rates, u8 rates_len,
+			       u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
+{
+	u8 i;
+
+	memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
+
+	for (i = 0; i < rates_len; i++) {
+		int ridx, rbit;
+
+		ridx = rates[i] / 8;
+		rbit = BIT(rates[i] % 8);
+
+		/* check validity */
+		if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
+			return false;
+
+		/* check availability */
+		if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
+			mcs[ridx] |= rbit;
+		else
+			return false;
+	}
+
+	return true;
+}
+
 static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
 	[NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
 				    .len = NL80211_MAX_SUPP_RATES },
+	[NL80211_TXRATE_MCS] = { .type = NLA_BINARY,
+				 .len = NL80211_MAX_SUPP_HT_RATES },
 };
 
 static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
@@ -5418,12 +5453,20 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
 		sband = rdev->wiphy.bands[i];
 		mask.control[i].legacy =
 			sband ? (1 << sband->n_bitrates) - 1 : 0;
+		if (sband)
+			memcpy(mask.control[i].mcs,
+			       sband->ht_cap.mcs.rx_mask,
+			       sizeof(mask.control[i].mcs));
+		else
+			memset(mask.control[i].mcs, 0,
+			       sizeof(mask.control[i].mcs));
 	}
 
 	/*
 	 * The nested attribute uses enum nl80211_band as the index. This maps
 	 * directly to the enum ieee80211_band values used in cfg80211.
 	 */
+	BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
 	nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
 	{
 		enum ieee80211_band band = nla_type(tx_rates);
@@ -5439,7 +5482,28 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
 				sband,
 				nla_data(tb[NL80211_TXRATE_LEGACY]),
 				nla_len(tb[NL80211_TXRATE_LEGACY]));
-			if (mask.control[band].legacy == 0)
+		}
+		if (tb[NL80211_TXRATE_MCS]) {
+			if (!ht_rateset_to_mask(
+					sband,
+					nla_data(tb[NL80211_TXRATE_MCS]),
+					nla_len(tb[NL80211_TXRATE_MCS]),
+					mask.control[band].mcs))
+				return -EINVAL;
+		}
+
+		if (mask.control[band].legacy == 0) {
+			/* don't allow empty legacy rates if HT
+			 * is not even supported. */
+			if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
+				return -EINVAL;
+
+			for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
+				if (mask.control[band].mcs[i])
+					break;
+
+			/* legacy and mcs rates may not be both empty */
+			if (i == IEEE80211_HT_MCS_MASK_LEN)
 				return -EINVAL;
 		}
 	}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index f65feaa..e9a0ac8 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -882,23 +882,8 @@ static void handle_channel(struct wiphy *wiphy,
 	chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
 	chan->max_antenna_gain = min(chan->orig_mag,
 		(int) MBI_TO_DBI(power_rule->max_antenna_gain));
-	if (chan->orig_mpwr) {
-		/*
-		 * Devices that have their own custom regulatory domain
-		 * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the
-		 * passed country IE power settings.
-		 */
-		if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
-		    wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
-		    wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {
-			chan->max_power =
-				MBM_TO_DBM(power_rule->max_eirp);
-		} else {
-			chan->max_power = min(chan->orig_mpwr,
-				(int) MBM_TO_DBM(power_rule->max_eirp));
-		}
-	} else
-		chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
+	chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
+	chan->max_power = min(chan->max_power, chan->max_reg_power);
 }
 
 static void handle_band(struct wiphy *wiphy,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 31119e3..afde7e5 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -861,6 +861,18 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(cfg80211_inform_bss_frame);
 
+void cfg80211_ref_bss(struct cfg80211_bss *pub)
+{
+	struct cfg80211_internal_bss *bss;
+
+	if (!pub)
+		return;
+
+	bss = container_of(pub, struct cfg80211_internal_bss, pub);
+	kref_get(&bss->ref);
+}
+EXPORT_SYMBOL(cfg80211_ref_bss);
+
 void cfg80211_put_bss(struct cfg80211_bss *pub)
 {
 	struct cfg80211_internal_bss *bss;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 7b9ecae..f7e937f 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -179,7 +179,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
 					    params->ssid, params->ssid_len,
 					    NULL, 0,
 					    params->key, params->key_len,
-					    params->key_idx, false);
+					    params->key_idx);
 	case CFG80211_CONN_ASSOCIATE_NEXT:
 		BUG_ON(!rdev->ops->assoc);
 		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -477,6 +477,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
 		kfree(wdev->connect_keys);
 		wdev->connect_keys = NULL;
 		wdev->ssid_len = 0;
+		cfg80211_put_bss(bss);
 		return;
 	}
 
@@ -701,31 +702,10 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
 	wdev->ssid_len = 0;
 
 	if (wdev->conn) {
-		const u8 *bssid;
-		int ret;
-
 		kfree(wdev->conn->ie);
 		wdev->conn->ie = NULL;
 		kfree(wdev->conn);
 		wdev->conn = NULL;
-
-		/*
-		 * If this disconnect was due to a disassoc, we
-		 * we might still have an auth BSS around. For
-		 * the userspace SME that's currently expected,
-		 * but for the kernel SME (nl80211 CONNECT or
-		 * wireless extensions) we want to clear up all
-		 * state.
-		 */
-		for (i = 0; i < MAX_AUTH_BSSES; i++) {
-			if (!wdev->auth_bsses[i])
-				continue;
-			bssid = wdev->auth_bsses[i]->pub.bssid;
-			ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
-						WLAN_REASON_DEAUTH_LEAVING,
-						false);
-			WARN(ret, "deauth failed: %d\n", ret);
-		}
 	}
 
 	nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
@@ -1012,7 +992,8 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
 	return err;
 }
 
-void cfg80211_sme_disassoc(struct net_device *dev, int idx)
+void cfg80211_sme_disassoc(struct net_device *dev,
+			   struct cfg80211_internal_bss *bss)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1031,16 +1012,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx)
 	 * want it any more so deauthenticate too.
 	 */
 
-	if (!wdev->auth_bsses[idx])
-		return;
+	memcpy(bssid, bss->pub.bssid, ETH_ALEN);
 
-	memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
-	if (__cfg80211_mlme_deauth(rdev, dev, bssid,
-				   NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
-				   false)) {
-		/* whatever -- assume gone anyway */
-		cfg80211_unhold_bss(wdev->auth_bsses[idx]);
-		cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
-		wdev->auth_bsses[idx] = NULL;
-	}
+	__cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
+			       WLAN_REASON_DEAUTH_LEAVING, false);
 }
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7661576..596f125 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -26,6 +26,7 @@
 #include <linux/cache.h>
 #include <linux/audit.h>
 #include <net/dst.h>
+#include <net/flow.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 #ifdef CONFIG_XFRM_STATISTICS
diff --git a/samples/Kconfig b/samples/Kconfig
index 41063e7..7b6792a 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -61,4 +61,12 @@ config SAMPLE_KDB
 	  Build an example of how to dynamically add the hello
 	  command to the kdb shell.
 
+config SAMPLE_RPMSG_CLIENT
+	tristate "Build rpmsg client sample -- loadable modules only"
+	depends on RPMSG && m
+	help
+	  Build an rpmsg client sample driver, which demonstrates how
+	  to communicate with an AMP-configured remote processor over
+	  the rpmsg bus.
+
 endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index 6280817..2f75851 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,4 +1,4 @@
 # Makefile for Linux samples code
 
 obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/ \
-			   hw_breakpoint/ kfifo/ kdb/ hidraw/
+			   hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/
diff --git a/samples/rpmsg/Makefile b/samples/rpmsg/Makefile
new file mode 100644
index 0000000..2d4973c
--- /dev/null
+++ b/samples/rpmsg/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SAMPLE_RPMSG_CLIENT) += rpmsg_client_sample.o
diff --git a/samples/rpmsg/rpmsg_client_sample.c b/samples/rpmsg/rpmsg_client_sample.c
new file mode 100644
index 0000000..23ea9f2
--- /dev/null
+++ b/samples/rpmsg/rpmsg_client_sample.c
@@ -0,0 +1,100 @@
+/*
+ * Remote processor messaging - sample client driver
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Ohad Ben-Cohen <ohad@wizery.com>
+ * Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rpmsg.h>
+
+#define MSG		"hello world!"
+#define MSG_LIMIT	100
+
+static void rpmsg_sample_cb(struct rpmsg_channel *rpdev, void *data, int len,
+						void *priv, u32 src)
+{
+	int ret;
+	static int rx_count;
+
+	dev_info(&rpdev->dev, "incoming msg %d (src: 0x%x)\n", ++rx_count, src);
+
+	print_hex_dump(KERN_DEBUG, __func__, DUMP_PREFIX_NONE, 16, 1,
+		       data, len,  true);
+
+	/* samples should not live forever */
+	if (rx_count >= MSG_LIMIT) {
+		dev_info(&rpdev->dev, "goodbye!\n");
+		return;
+	}
+
+	/* send a new message now */
+	ret = rpmsg_send(rpdev, MSG, strlen(MSG));
+	if (ret)
+		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+}
+
+static int rpmsg_sample_probe(struct rpmsg_channel *rpdev)
+{
+	int ret;
+
+	dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+					rpdev->src, rpdev->dst);
+
+	/* send a message to our remote processor */
+	ret = rpmsg_send(rpdev, MSG, strlen(MSG));
+	if (ret) {
+		dev_err(&rpdev->dev, "rpmsg_send failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void __devexit rpmsg_sample_remove(struct rpmsg_channel *rpdev)
+{
+	dev_info(&rpdev->dev, "rpmsg sample client driver is removed\n");
+}
+
+static struct rpmsg_device_id rpmsg_driver_sample_id_table[] = {
+	{ .name	= "rpmsg-client-sample" },
+	{ },
+};
+MODULE_DEVICE_TABLE(rpmsg, rpmsg_driver_sample_id_table);
+
+static struct rpmsg_driver rpmsg_sample_client = {
+	.drv.name	= KBUILD_MODNAME,
+	.drv.owner	= THIS_MODULE,
+	.id_table	= rpmsg_driver_sample_id_table,
+	.probe		= rpmsg_sample_probe,
+	.callback	= rpmsg_sample_cb,
+	.remove		= __devexit_p(rpmsg_sample_remove),
+};
+
+static int __init rpmsg_client_sample_init(void)
+{
+	return register_rpmsg_driver(&rpmsg_sample_client);
+}
+module_init(rpmsg_client_sample_init);
+
+static void __exit rpmsg_client_sample_fini(void)
+{
+	unregister_rpmsg_driver(&rpmsg_sample_client);
+}
+module_exit(rpmsg_client_sample_fini);
+
+MODULE_DESCRIPTION("Remote processor messaging sample client driver");
+MODULE_LICENSE("GPL v2");
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index d2b366c..ff1720d 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -69,6 +69,7 @@ warning-1 += -Wmissing-prototypes
 warning-1 += -Wold-style-definition
 warning-1 += $(call cc-option, -Wmissing-include-dirs)
 warning-1 += $(call cc-option, -Wunused-but-set-variable)
+warning-1 += $(call cc-disable-warning, missing-field-initializers)
 
 warning-2 := -Waggregate-return
 warning-2 += -Wcast-align
@@ -76,6 +77,7 @@ warning-2 += -Wdisabled-optimization
 warning-2 += -Wnested-externs
 warning-2 += -Wshadow
 warning-2 += $(call cc-option, -Wlogical-op)
+warning-2 += $(call cc-option, -Wmissing-field-initializers)
 
 warning-3 := -Wbad-function-cast
 warning-3 += -Wcast-qual
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index a3b9782..89d24b3 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -3123,6 +3123,12 @@ sub process {
 			     "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
 		}
 
+# Check for __attribute__ format(scanf, prefer __scanf
+		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
+			WARN("PREFER_SCANF",
+			     "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
+		}
+
 # check for sizeof(&)
 		if ($line =~ /\bsizeof\s*\(\s*\&/) {
 			WARN("SIZEOF_ADDRESS",
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 3c27764..823e972 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -9,15 +9,10 @@ if [ "$C" = "1" -o "$C" = "2" ]; then
 #    FLAGS="-ignore_unknown_options -very_quiet"
 #    OPTIONS=$*
 
-    if [ "$KBUILD_EXTMOD" = "" ] ; then
-        # Workaround for Coccinelle < 0.2.3
-        FLAGS="-I $srctree/include -very_quiet"
-        shift $(( $# - 1 ))
-        OPTIONS=$1
-    else
-	echo M= is not currently supported when C=1 or C=2
-	exit 1
-    fi
+# Workaround for Coccinelle < 0.2.3
+	FLAGS="-I $srctree/include -very_quiet"
+	shift $(( $# - 1 ))
+	OPTIONS=$1
 else
     ONLINE=0
     FLAGS="-very_quiet"
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index a272356..2ae4817 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -9,12 +9,6 @@ fi
 DEPMOD=$1
 KERNELRELEASE=$2
 
-if ! "$DEPMOD" -V 2>/dev/null | grep -q module-init-tools; then
-	echo "Warning: you may need to install module-init-tools" >&2
-	echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt" >&2
-	sleep 1
-fi
-
 if ! test -r System.map -a -x "$DEPMOD"; then
 	exit 0
 fi
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 7966265..dce29cd 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -3,7 +3,7 @@
 # These targets are used from top-level makefile
 
 PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \
-	localmodconfig localyesconfig
+	localmodconfig localyesconfig kvmconfig
 
 ifdef KBUILD_KCONFIG
 Kconfig := $(KBUILD_KCONFIG)
@@ -33,6 +33,11 @@ silentoldconfig: $(obj)/conf
 	$(Q)mkdir -p include/generated
 	$< --$@ $(Kconfig)
 
+kvmconfig:
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/config -e KVMTOOL_TEST_ENABLE
+	$(Q)yes "" | make oldconfig > /dev/null
+	@echo 'Kernel configuration modified to run as KVM guest.'
+
 localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
 	$(Q)mkdir -p include/generated
 	$(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
index 7c7a5a6..0586085 100644
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -344,10 +344,8 @@ setsym:
 
 int conf_read(const char *name)
 {
-	struct symbol *sym, *choice_sym;
-	struct property *prop;
-	struct expr *e;
-	int i, flags;
+	struct symbol *sym;
+	int i;
 
 	sym_set_change_count(0);
 
@@ -357,7 +355,7 @@ int conf_read(const char *name)
 	for_all_symbols(i, sym) {
 		sym_calc_value(sym);
 		if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO))
-			goto sym_ok;
+			continue;
 		if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) {
 			/* check that calculated value agrees with saved value */
 			switch (sym->type) {
@@ -366,30 +364,18 @@ int conf_read(const char *name)
 				if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
 					break;
 				if (!sym_is_choice(sym))
-					goto sym_ok;
+					continue;
 				/* fall through */
 			default:
 				if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
-					goto sym_ok;
+					continue;
 				break;
 			}
 		} else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE))
 			/* no previous value and not saved */
-			goto sym_ok;
+			continue;
 		conf_unsaved++;
 		/* maybe print value in verbose mode... */
-	sym_ok:
-		if (!sym_is_choice(sym))
-			continue;
-		/* The choice symbol only has a set value (and thus is not new)
-		 * if all its visible childs have values.
-		 */
-		prop = sym_get_choice_prop(sym);
-		flags = sym->flags;
-		expr_list_for_each_sym(prop->expr, e, choice_sym)
-			if (choice_sym->visible != no)
-				flags &= choice_sym->flags;
-		sym->flags &= flags | ~SYMBOL_DEF_USER;
 	}
 
 	for_all_symbols(i, sym) {
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 071f00c..22a3c40 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -262,11 +262,18 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
 	struct symbol *def_sym;
 	struct property *prop;
 	struct expr *e;
+	int flags;
 
 	/* first calculate all choice values' visibilities */
+	flags = sym->flags;
 	prop = sym_get_choice_prop(sym);
-	expr_list_for_each_sym(prop->expr, e, def_sym)
+	expr_list_for_each_sym(prop->expr, e, def_sym) {
 		sym_calc_visibility(def_sym);
+		if (def_sym->visible != no)
+			flags &= def_sym->flags;
+	}
+
+	sym->flags &= flags | ~SYMBOL_DEF_USER;
 
 	/* is the user choice visible? */
 	def_sym = sym->def[S_DEF_USER].val;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index d0de2a2..8d929db 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -1003,6 +1003,31 @@ static int do_amba_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry);
 
+/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
+ * All fields are numbers. It would be nicer to use strings for vendor
+ * and feature, but getting those out of the build system here is too
+ * complicated.
+ */
+
+static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id,
+			   char *alias)
+{
+	id->feature = TO_NATIVE(id->feature);
+	id->family = TO_NATIVE(id->family);
+	id->model = TO_NATIVE(id->model);
+	id->vendor = TO_NATIVE(id->vendor);
+
+	strcpy(alias, "x86cpu:");
+	ADD(alias, "vendor:",  id->vendor != X86_VENDOR_ANY, id->vendor);
+	ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
+	ADD(alias, ":model:",  id->model  != X86_MODEL_ANY,  id->model);
+	strcat(alias, ":feature:*");
+	if (id->feature != X86_FEATURE_ANY)
+		sprintf(alias + strlen(alias), "%04X*", id->feature);
+	return 1;
+}
+ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id, do_x86cpu_entry);
+
 /* Does namelen bytes of name exactly match the symbol? */
 static bool sym_is(const char *name, unsigned namelen, const char *symbol)
 {
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2bd594e..9adb667 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1494,6 +1494,13 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 	return 0;
 }
 
+#ifndef R_ARM_CALL
+#define R_ARM_CALL	28
+#endif
+#ifndef R_ARM_JUMP24
+#define R_ARM_JUMP24	29
+#endif
+
 static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 {
 	unsigned int r_typ = ELF_R_TYPE(r->r_info);
@@ -1505,6 +1512,8 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
 		              (elf->symtab_start + ELF_R_SYM(r->r_info));
 		break;
 	case R_ARM_PC24:
+	case R_ARM_CALL:
+	case R_ARM_JUMP24:
 		/* From ARM ABI: ((S + A) | T) - P */
 		r->r_addend = (int)(long)(elf->hdr +
 		              sechdr->sh_offset +
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index f6cbc3d..3c6c0b1 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -238,14 +238,14 @@ EOF
 fi
 
 # Build header package
-(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$)
-(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> /tmp/files$$)
-(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$)
+(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles")
+(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles")
+(cd $objtree; find .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles")
 destdir=$kernel_headers_dir/usr/src/linux-headers-$version
 mkdir -p "$destdir"
-(cd $srctree; tar -c -f - -T /tmp/files$$) | (cd $destdir; tar -xf -)
-(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -)
-rm -f /tmp/files$$ /tmp/objfiles$$
+(cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -)
+(cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -)
+rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
 arch=$(dpkg --print-architecture)
 
 cat <<EOF >> debian/control
diff --git a/security/Kconfig b/security/Kconfig
index 51bd5a0..ccc61f8 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -187,6 +187,7 @@ source security/selinux/Kconfig
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
+source security/yama/Kconfig
 
 source security/integrity/Kconfig
 
@@ -196,6 +197,7 @@ choice
 	default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
 	default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
 	default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
+	default DEFAULT_SECURITY_YAMA if SECURITY_YAMA
 	default DEFAULT_SECURITY_DAC
 
 	help
@@ -214,6 +216,9 @@ choice
 	config DEFAULT_SECURITY_APPARMOR
 		bool "AppArmor" if SECURITY_APPARMOR=y
 
+	config DEFAULT_SECURITY_YAMA
+		bool "Yama" if SECURITY_YAMA=y
+
 	config DEFAULT_SECURITY_DAC
 		bool "Unix Discretionary Access Controls"
 
@@ -225,6 +230,7 @@ config DEFAULT_SECURITY
 	default "smack" if DEFAULT_SECURITY_SMACK
 	default "tomoyo" if DEFAULT_SECURITY_TOMOYO
 	default "apparmor" if DEFAULT_SECURITY_APPARMOR
+	default "yama" if DEFAULT_SECURITY_YAMA
 	default "" if DEFAULT_SECURITY_DAC
 
 endmenu
diff --git a/security/Makefile b/security/Makefile
index a5e502f..c26c81e 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -7,6 +7,7 @@ subdir-$(CONFIG_SECURITY_SELINUX)	+= selinux
 subdir-$(CONFIG_SECURITY_SMACK)		+= smack
 subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR)	+= apparmor
+subdir-$(CONFIG_SECURITY_YAMA)		+= yama
 
 # always enable default capabilities
 obj-y					+= commoncap.o
@@ -21,6 +22,7 @@ obj-$(CONFIG_SECURITY_SMACK)		+= smack/built-in.o
 obj-$(CONFIG_AUDIT)			+= lsm_audit.o
 obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/built-in.o
 obj-$(CONFIG_SECURITY_APPARMOR)		+= apparmor/built-in.o
+obj-$(CONFIG_SECURITY_YAMA)		+= yama/built-in.o
 obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
 
 # Object integrity file lists
diff --git a/security/capability.c b/security/capability.c
index 2f680eb..5bb21b1 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -358,6 +358,10 @@ static int cap_task_create(unsigned long clone_flags)
 	return 0;
 }
 
+static void cap_task_free(struct task_struct *task)
+{
+}
+
 static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
 	return 0;
@@ -954,6 +958,7 @@ void __init security_fixup_ops(struct security_operations *ops)
 	set_to_cap_if_null(ops, file_receive);
 	set_to_cap_if_null(ops, dentry_open);
 	set_to_cap_if_null(ops, task_create);
+	set_to_cap_if_null(ops, task_free);
 	set_to_cap_if_null(ops, cred_alloc_blank);
 	set_to_cap_if_null(ops, cred_free);
 	set_to_cap_if_null(ops, cred_prepare);
diff --git a/security/commoncap.c b/security/commoncap.c
index 7ce191e..0cf4b53 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -28,6 +28,7 @@
 #include <linux/prctl.h>
 #include <linux/securebits.h>
 #include <linux/user_namespace.h>
+#include <linux/binfmts.h>
 
 /*
  * If a non-root user executes a setuid-root binary in
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 8b5b5d8..c43a332 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -61,8 +61,8 @@ static inline struct dev_cgroup *task_devcgroup(struct task_struct *task)
 
 struct cgroup_subsys devices_subsys;
 
-static int devcgroup_can_attach(struct cgroup_subsys *ss,
-			struct cgroup *new_cgrp, struct cgroup_taskset *set)
+static int devcgroup_can_attach(struct cgroup *new_cgrp,
+				struct cgroup_taskset *set)
 {
 	struct task_struct *task = cgroup_taskset_first(set);
 
@@ -156,8 +156,7 @@ remove:
 /*
  * called from kernel/cgroup.c with cgroup_lock() held.
  */
-static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss,
-						struct cgroup *cgroup)
+static struct cgroup_subsys_state *devcgroup_create(struct cgroup *cgroup)
 {
 	struct dev_cgroup *dev_cgroup, *parent_dev_cgroup;
 	struct cgroup *parent_cgroup;
@@ -195,8 +194,7 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss,
 	return &dev_cgroup->css;
 }
 
-static void devcgroup_destroy(struct cgroup_subsys *ss,
-			struct cgroup *cgroup)
+static void devcgroup_destroy(struct cgroup *cgroup)
 {
 	struct dev_cgroup *dev_cgroup;
 	struct dev_whitelist_item *wh, *tmp;
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 4f554f2..063298a 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -9,7 +9,7 @@ config IMA
 	select CRYPTO_HMAC
 	select CRYPTO_MD5
 	select CRYPTO_SHA1
-	select TCG_TPM if !S390 && !UML
+	select TCG_TPM if HAS_IOMEM && !UML
 	select TCG_TIS if TCG_TPM
 	help
 	  The Trusted Computing Group(TCG) runtime Integrity
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index 2ad942f..21e96bf 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -61,6 +61,6 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
 		audit_log_untrustedstring(ab, inode->i_sb->s_id);
 		audit_log_format(ab, " ino=%lu", inode->i_ino);
 	}
-	audit_log_format(ab, " res=%d", !result ? 0 : 1);
+	audit_log_format(ab, " res=%d", !result);
 	audit_log_end(ab);
 }
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index d45061d..d8edff2 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -62,6 +62,7 @@ static struct ima_measure_rule_entry default_rules[] = {
 	{.action = DONT_MEASURE,.fsmagic = SYSFS_MAGIC,.flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE,.fsmagic = DEBUGFS_MAGIC,.flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE,.fsmagic = TMPFS_MAGIC,.flags = IMA_FSMAGIC},
+	{.action = DONT_MEASURE,.fsmagic = RAMFS_MAGIC,.flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE,.fsmagic = SECURITYFS_MAGIC,.flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE,.fsmagic = SELINUX_MAGIC,.flags = IMA_FSMAGIC},
 	{.action = MEASURE,.func = FILE_MMAP,.mask = MAY_EXEC,
@@ -417,7 +418,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
 	if (!result && (entry->action == UNKNOWN))
 		result = -EINVAL;
 
-	audit_log_format(ab, "res=%d", !!result);
+	audit_log_format(ab, "res=%d", !result);
 	audit_log_end(ab);
 	return result;
 }
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 0b3f5d7..6523599 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -388,11 +388,24 @@ long keyctl_keyring_clear(key_serial_t ringid)
 	keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE);
 	if (IS_ERR(keyring_ref)) {
 		ret = PTR_ERR(keyring_ref);
+
+		/* Root is permitted to invalidate certain special keyrings */
+		if (capable(CAP_SYS_ADMIN)) {
+			keyring_ref = lookup_user_key(ringid, 0, 0);
+			if (IS_ERR(keyring_ref))
+				goto error;
+			if (test_bit(KEY_FLAG_ROOT_CAN_CLEAR,
+				     &key_ref_to_ptr(keyring_ref)->flags))
+				goto clear;
+			goto error_put;
+		}
+
 		goto error;
 	}
 
+clear:
 	ret = keyring_clear(key_ref_to_ptr(keyring_ref));
-
+error_put:
 	key_ref_put(keyring_ref);
 error:
 	return ret;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 8246532..fc7c8cc 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -91,7 +91,7 @@ static void umh_keys_cleanup(struct subprocess_info *info)
  * Call a usermode helper with a specific session keyring.
  */
 static int call_usermodehelper_keys(char *path, char **argv, char **envp,
-			 struct key *session_keyring, enum umh_wait wait)
+			 		struct key *session_keyring, int wait)
 {
 	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
 	struct subprocess_info *info =
diff --git a/security/security.c b/security/security.c
index d754249..bf619ff 100644
--- a/security/security.c
+++ b/security/security.c
@@ -19,6 +19,8 @@
 #include <linux/integrity.h>
 #include <linux/ima.h>
 #include <linux/evm.h>
+#include <linux/fsnotify.h>
+#include <net/flow.h>
 
 #define MAX_LSM_EVM_XATTR	2
 
@@ -187,25 +189,11 @@ int security_settime(const struct timespec *ts, const struct timezone *tz)
 	return security_ops->settime(ts, tz);
 }
 
-int security_vm_enough_memory(long pages)
-{
-	WARN_ON(current->mm == NULL);
-	return security_ops->vm_enough_memory(current->mm, pages);
-}
-
 int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
 {
-	WARN_ON(mm == NULL);
 	return security_ops->vm_enough_memory(mm, pages);
 }
 
-int security_vm_enough_memory_kern(long pages)
-{
-	/* If current->mm is a kernel thread then we will pass NULL,
-	   for this specific case that is fine */
-	return security_ops->vm_enough_memory(current->mm, pages);
-}
-
 int security_bprm_set_creds(struct linux_binprm *bprm)
 {
 	return security_ops->bprm_set_creds(bprm);
@@ -729,6 +717,11 @@ int security_task_create(unsigned long clone_flags)
 	return security_ops->task_create(clone_flags);
 }
 
+void security_task_free(struct task_struct *task)
+{
+	security_ops->task_free(task);
+}
+
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp)
 {
 	return security_ops->cred_alloc_blank(cred, gfp);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6a3683e..3049299 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -81,6 +81,8 @@
 #include <linux/syslog.h>
 #include <linux/user_namespace.h>
 #include <linux/export.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
 
 #include "avc.h"
 #include "objsec.h"
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index b43813c..c220f31 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -7,6 +7,8 @@
 #ifndef _SELINUX_XFRM_H_
 #define _SELINUX_XFRM_H_
 
+#include <net/flow.h>
+
 int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
 			      struct xfrm_user_sec_ctx *sec_ctx);
 int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 48a7d00..1f633a0 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -496,6 +496,7 @@ static const struct file_operations sel_policy_ops = {
 	.read		= sel_read_policy,
 	.mmap		= sel_mmap_policy,
 	.release	= sel_release_policy,
+	.llseek		= generic_file_llseek,
 };
 
 static ssize_t sel_write_load(struct file *file, const char __user *buf,
@@ -1832,7 +1833,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
 		[SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
 		[SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
 		[SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
-		[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR},
+		[SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUGO},
 		/* last one */ {""}
 	};
 	ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index e8af5b0b..cd667b4 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -36,6 +36,9 @@
 #include <linux/magic.h>
 #include <linux/dcache.h>
 #include <linux/personality.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/binfmts.h>
 #include "smack.h"
 
 #define task_security(task)	(task_cred_xxx((task), security))
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index 9027ac1..3865145 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -886,12 +886,12 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
 		 * But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
 		 * So do I.
 		 */
-		char *kaddr = kmap_atomic(page, KM_USER0);
+		char *kaddr = kmap_atomic(page);
 
 		dump->page = page;
 		memcpy(dump->data + offset, kaddr + offset,
 		       PAGE_SIZE - offset);
-		kunmap_atomic(kaddr, KM_USER0);
+		kunmap_atomic(kaddr);
 	}
 	/* Same with put_arg_page(page) in fs/exec.c */
 #ifdef CONFIG_MMU
diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c
index 6797540..078fac0 100644
--- a/security/tomoyo/load_policy.c
+++ b/security/tomoyo/load_policy.c
@@ -102,7 +102,7 @@ void tomoyo_load_policy(const char *filename)
 	envp[0] = "HOME=/";
 	envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 	envp[2] = NULL;
-	call_usermodehelper(argv[0], argv, envp, 1);
+	call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
 	tomoyo_check_profile();
 }
 
diff --git a/security/yama/Kconfig b/security/yama/Kconfig
new file mode 100644
index 0000000..51d6709
--- /dev/null
+++ b/security/yama/Kconfig
@@ -0,0 +1,13 @@
+config SECURITY_YAMA
+	bool "Yama support"
+	depends on SECURITY
+	select SECURITYFS
+	select SECURITY_PATH
+	default n
+	help
+	  This selects Yama, which extends DAC support with additional
+	  system-wide security settings beyond regular Linux discretionary
+	  access controls. Currently available is ptrace scope restriction.
+	  Further information can be found in Documentation/security/Yama.txt.
+
+	  If you are unsure how to answer this question, answer N.
diff --git a/security/yama/Makefile b/security/yama/Makefile
new file mode 100644
index 0000000..8b5e065
--- /dev/null
+++ b/security/yama/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SECURITY_YAMA) := yama.o
+
+yama-y := yama_lsm.o
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
new file mode 100644
index 0000000..5737238
--- /dev/null
+++ b/security/yama/yama_lsm.c
@@ -0,0 +1,323 @@
+/*
+ * Yama Linux Security Module
+ *
+ * Author: Kees Cook <keescook@chromium.org>
+ *
+ * Copyright (C) 2010 Canonical, Ltd.
+ * Copyright (C) 2011 The Chromium OS Authors.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/security.h>
+#include <linux/sysctl.h>
+#include <linux/ptrace.h>
+#include <linux/prctl.h>
+#include <linux/ratelimit.h>
+
+static int ptrace_scope = 1;
+
+/* describe a ptrace relationship for potential exception */
+struct ptrace_relation {
+	struct task_struct *tracer;
+	struct task_struct *tracee;
+	struct list_head node;
+};
+
+static LIST_HEAD(ptracer_relations);
+static DEFINE_SPINLOCK(ptracer_relations_lock);
+
+/**
+ * yama_ptracer_add - add/replace an exception for this tracer/tracee pair
+ * @tracer: the task_struct of the process doing the ptrace
+ * @tracee: the task_struct of the process to be ptraced
+ *
+ * Each tracee can have, at most, one tracer registered. Each time this
+ * is called, the prior registered tracer will be replaced for the tracee.
+ *
+ * Returns 0 if relationship was added, -ve on error.
+ */
+static int yama_ptracer_add(struct task_struct *tracer,
+			    struct task_struct *tracee)
+{
+	int rc = 0;
+	struct ptrace_relation *added;
+	struct ptrace_relation *entry, *relation = NULL;
+
+	added = kmalloc(sizeof(*added), GFP_KERNEL);
+	if (!added)
+		return -ENOMEM;
+
+	spin_lock_bh(&ptracer_relations_lock);
+	list_for_each_entry(entry, &ptracer_relations, node)
+		if (entry->tracee == tracee) {
+			relation = entry;
+			break;
+		}
+	if (!relation) {
+		relation = added;
+		relation->tracee = tracee;
+		list_add(&relation->node, &ptracer_relations);
+	}
+	relation->tracer = tracer;
+
+	spin_unlock_bh(&ptracer_relations_lock);
+	if (added != relation)
+		kfree(added);
+
+	return rc;
+}
+
+/**
+ * yama_ptracer_del - remove exceptions related to the given tasks
+ * @tracer: remove any relation where tracer task matches
+ * @tracee: remove any relation where tracee task matches
+ */
+static void yama_ptracer_del(struct task_struct *tracer,
+			     struct task_struct *tracee)
+{
+	struct ptrace_relation *relation, *safe;
+
+	spin_lock_bh(&ptracer_relations_lock);
+	list_for_each_entry_safe(relation, safe, &ptracer_relations, node)
+		if (relation->tracee == tracee ||
+		    (tracer && relation->tracer == tracer)) {
+			list_del(&relation->node);
+			kfree(relation);
+		}
+	spin_unlock_bh(&ptracer_relations_lock);
+}
+
+/**
+ * yama_task_free - check for task_pid to remove from exception list
+ * @task: task being removed
+ */
+static void yama_task_free(struct task_struct *task)
+{
+	yama_ptracer_del(task, task);
+}
+
+/**
+ * yama_task_prctl - check for Yama-specific prctl operations
+ * @option: operation
+ * @arg2: argument
+ * @arg3: argument
+ * @arg4: argument
+ * @arg5: argument
+ *
+ * Return 0 on success, -ve on error.  -ENOSYS is returned when Yama
+ * does not handle the given option.
+ */
+static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
+			   unsigned long arg4, unsigned long arg5)
+{
+	int rc;
+	struct task_struct *myself = current;
+
+	rc = cap_task_prctl(option, arg2, arg3, arg4, arg5);
+	if (rc != -ENOSYS)
+		return rc;
+
+	switch (option) {
+	case PR_SET_PTRACER:
+		/* Since a thread can call prctl(), find the group leader
+		 * before calling _add() or _del() on it, since we want
+		 * process-level granularity of control. The tracer group
+		 * leader checking is handled later when walking the ancestry
+		 * at the time of PTRACE_ATTACH check.
+		 */
+		rcu_read_lock();
+		if (!thread_group_leader(myself))
+			myself = rcu_dereference(myself->group_leader);
+		get_task_struct(myself);
+		rcu_read_unlock();
+
+		if (arg2 == 0) {
+			yama_ptracer_del(NULL, myself);
+			rc = 0;
+		} else if (arg2 == PR_SET_PTRACER_ANY) {
+			rc = yama_ptracer_add(NULL, myself);
+		} else {
+			struct task_struct *tracer;
+
+			rcu_read_lock();
+			tracer = find_task_by_vpid(arg2);
+			if (tracer)
+				get_task_struct(tracer);
+			else
+				rc = -EINVAL;
+			rcu_read_unlock();
+
+			if (tracer) {
+				rc = yama_ptracer_add(tracer, myself);
+				put_task_struct(tracer);
+			}
+		}
+
+		put_task_struct(myself);
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * task_is_descendant - walk up a process family tree looking for a match
+ * @parent: the process to compare against while walking up from child
+ * @child: the process to start from while looking upwards for parent
+ *
+ * Returns 1 if child is a descendant of parent, 0 if not.
+ */
+static int task_is_descendant(struct task_struct *parent,
+			      struct task_struct *child)
+{
+	int rc = 0;
+	struct task_struct *walker = child;
+
+	if (!parent || !child)
+		return 0;
+
+	rcu_read_lock();
+	if (!thread_group_leader(parent))
+		parent = rcu_dereference(parent->group_leader);
+	while (walker->pid > 0) {
+		if (!thread_group_leader(walker))
+			walker = rcu_dereference(walker->group_leader);
+		if (walker == parent) {
+			rc = 1;
+			break;
+		}
+		walker = rcu_dereference(walker->real_parent);
+	}
+	rcu_read_unlock();
+
+	return rc;
+}
+
+/**
+ * ptracer_exception_found - tracer registered as exception for this tracee
+ * @tracer: the task_struct of the process attempting ptrace
+ * @tracee: the task_struct of the process to be ptraced
+ *
+ * Returns 1 if tracer has is ptracer exception ancestor for tracee.
+ */
+static int ptracer_exception_found(struct task_struct *tracer,
+				   struct task_struct *tracee)
+{
+	int rc = 0;
+	struct ptrace_relation *relation;
+	struct task_struct *parent = NULL;
+	bool found = false;
+
+	spin_lock_bh(&ptracer_relations_lock);
+	rcu_read_lock();
+	if (!thread_group_leader(tracee))
+		tracee = rcu_dereference(tracee->group_leader);
+	list_for_each_entry(relation, &ptracer_relations, node)
+		if (relation->tracee == tracee) {
+			parent = relation->tracer;
+			found = true;
+			break;
+		}
+
+	if (found && (parent == NULL || task_is_descendant(parent, tracer)))
+		rc = 1;
+	rcu_read_unlock();
+	spin_unlock_bh(&ptracer_relations_lock);
+
+	return rc;
+}
+
+/**
+ * yama_ptrace_access_check - validate PTRACE_ATTACH calls
+ * @child: task that current task is attempting to ptrace
+ * @mode: ptrace attach mode
+ *
+ * Returns 0 if following the ptrace is allowed, -ve on error.
+ */
+static int yama_ptrace_access_check(struct task_struct *child,
+				    unsigned int mode)
+{
+	int rc;
+
+	/* If standard caps disallows it, so does Yama.  We should
+	 * only tighten restrictions further.
+	 */
+	rc = cap_ptrace_access_check(child, mode);
+	if (rc)
+		return rc;
+
+	/* require ptrace target be a child of ptracer on attach */
+	if (mode == PTRACE_MODE_ATTACH &&
+	    ptrace_scope &&
+	    !task_is_descendant(current, child) &&
+	    !ptracer_exception_found(current, child) &&
+	    !capable(CAP_SYS_PTRACE))
+		rc = -EPERM;
+
+	if (rc) {
+		char name[sizeof(current->comm)];
+		printk_ratelimited(KERN_NOTICE "ptrace of non-child"
+			" pid %d was attempted by: %s (pid %d)\n",
+			child->pid,
+			get_task_comm(name, current),
+			current->pid);
+	}
+
+	return rc;
+}
+
+static struct security_operations yama_ops = {
+	.name =			"yama",
+
+	.ptrace_access_check =	yama_ptrace_access_check,
+	.task_prctl =		yama_task_prctl,
+	.task_free =		yama_task_free,
+};
+
+#ifdef CONFIG_SYSCTL
+static int zero;
+static int one = 1;
+
+struct ctl_path yama_sysctl_path[] = {
+	{ .procname = "kernel", },
+	{ .procname = "yama", },
+	{ }
+};
+
+static struct ctl_table yama_sysctl_table[] = {
+	{
+		.procname       = "ptrace_scope",
+		.data           = &ptrace_scope,
+		.maxlen         = sizeof(int),
+		.mode           = 0644,
+		.proc_handler   = proc_dointvec_minmax,
+		.extra1         = &zero,
+		.extra2         = &one,
+	},
+	{ }
+};
+#endif /* CONFIG_SYSCTL */
+
+static __init int yama_init(void)
+{
+	if (!security_module_enable(&yama_ops))
+		return 0;
+
+	printk(KERN_INFO "Yama: becoming mindful.\n");
+
+	if (register_security(&yama_ops))
+		panic("Yama: kernel registration failed.\n");
+
+#ifdef CONFIG_SYSCTL
+	if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table))
+		panic("Yama: sysctl registration failed.\n");
+#endif
+
+	return 0;
+}
+
+security_initcall(yama_init);
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 762af68..270790d 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1132,15 +1132,4 @@ static struct i2c_driver onyx_driver = {
 	.id_table = onyx_i2c_id,
 };
 
-static int __init onyx_init(void)
-{
-	return i2c_add_driver(&onyx_driver);
-}
-
-static void __exit onyx_exit(void)
-{
-	i2c_del_driver(&onyx_driver);
-}
-
-module_init(onyx_init);
-module_exit(onyx_exit);
+module_i2c_driver(onyx_driver);
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index fd2188c..8e63d1f 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -1026,15 +1026,4 @@ static struct i2c_driver tas_driver = {
 	.id_table = tas_i2c_id,
 };
 
-static int __init tas_init(void)
-{
-	return i2c_add_driver(&tas_driver);
-}
-
-static void __exit tas_exit(void)
-{
-	i2c_del_driver(&tas_driver);
-}
-
-module_init(tas_init);
-module_exit(tas_exit);
+module_i2c_driver(tas_driver);
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index d1aa421..0e9e822 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -21,7 +21,7 @@
 #include <sound/ac97_codec.h>
 #include <sound/pxa2xx-lib.h>
 
-#include <asm/irq.h>
+#include <mach/irqs.h>
 #include <mach/regs-ac97.h>
 #include <mach/audio.h>
 
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 465f0ce..7681679 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -72,7 +72,7 @@ void __snd_printk(unsigned int level, const char *path, int line,
 	char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
 #endif
 
-#ifdef CONFIG_SND_DEBUG	
+#ifdef CONFIG_SND_DEBUG
 	if (debug < level)
 		return;
 #endif
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 8928ca87..6e4bfcc 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -650,7 +650,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
 	pstr->stream = stream;
 	pstr->pcm = pcm;
 	pstr->substream_count = substream_count;
-	if (substream_count > 0) {
+	if (substream_count > 0 && !pcm->internal) {
 		err = snd_pcm_stream_proc_init(pstr);
 		if (err < 0) {
 			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
@@ -674,15 +674,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
 			pstr->substream = substream;
 		else
 			prev->next = substream;
-		err = snd_pcm_substream_proc_init(substream);
-		if (err < 0) {
-			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
-			if (prev == NULL)
-				pstr->substream = NULL;
-			else
-				prev->next = NULL;
-			kfree(substream);
-			return err;
+
+		if (!pcm->internal) {
+			err = snd_pcm_substream_proc_init(substream);
+			if (err < 0) {
+				snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
+				if (prev == NULL)
+					pstr->substream = NULL;
+				else
+					prev->next = NULL;
+				kfree(substream);
+				return err;
+			}
 		}
 		substream->group = &substream->self_group;
 		spin_lock_init(&substream->self_group.lock);
@@ -696,25 +699,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
 
 EXPORT_SYMBOL(snd_pcm_new_stream);
 
-/**
- * snd_pcm_new - create a new PCM instance
- * @card: the card instance
- * @id: the id string
- * @device: the device index (zero based)
- * @playback_count: the number of substreams for playback
- * @capture_count: the number of substreams for capture
- * @rpcm: the pointer to store the new pcm instance
- *
- * Creates a new PCM instance.
- *
- * The pcm operators have to be set afterwards to the new instance
- * via snd_pcm_set_ops().
- *
- * Returns zero if successful, or a negative error code on failure.
- */
-int snd_pcm_new(struct snd_card *card, const char *id, int device,
-		int playback_count, int capture_count,
-	        struct snd_pcm ** rpcm)
+static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
+		int playback_count, int capture_count, bool internal,
+		struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
 	int err;
@@ -735,6 +722,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
 	}
 	pcm->card = card;
 	pcm->device = device;
+	pcm->internal = internal;
 	if (id)
 		strlcpy(pcm->id, id, sizeof(pcm->id));
 	if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
@@ -756,8 +744,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device,
 	return 0;
 }
 
+/**
+ * snd_pcm_new - create a new PCM instance
+ * @card: the card instance
+ * @id: the id string
+ * @device: the device index (zero based)
+ * @playback_count: the number of substreams for playback
+ * @capture_count: the number of substreams for capture
+ * @rpcm: the pointer to store the new pcm instance
+ *
+ * Creates a new PCM instance.
+ *
+ * The pcm operators have to be set afterwards to the new instance
+ * via snd_pcm_set_ops().
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
+int snd_pcm_new(struct snd_card *card, const char *id, int device,
+		int playback_count, int capture_count, struct snd_pcm **rpcm)
+{
+	return _snd_pcm_new(card, id, device, playback_count, capture_count,
+			false, rpcm);
+}
 EXPORT_SYMBOL(snd_pcm_new);
 
+/**
+ * snd_pcm_new_internal - create a new internal PCM instance
+ * @card: the card instance
+ * @id: the id string
+ * @device: the device index (zero based - shared with normal PCMs)
+ * @playback_count: the number of substreams for playback
+ * @capture_count: the number of substreams for capture
+ * @rpcm: the pointer to store the new pcm instance
+ *
+ * Creates a new internal PCM instance with no userspace device or procfs
+ * entries. This is used by ASoC Back End PCMs in order to create a PCM that
+ * will only be used internally by kernel drivers. i.e. it cannot be opened
+ * by userspace. It provides existing ASoC components drivers with a substream
+ * and access to any private data.
+ *
+ * The pcm operators have to be set afterwards to the new instance
+ * via snd_pcm_set_ops().
+ *
+ * Returns zero if successful, or a negative error code on failure.
+ */
+int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
+	int playback_count, int capture_count,
+	struct snd_pcm **rpcm)
+{
+	return _snd_pcm_new(card, id, device, playback_count, capture_count,
+			true, rpcm);
+}
+EXPORT_SYMBOL(snd_pcm_new_internal);
+
 static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
 {
 	struct snd_pcm_substream *substream, *substream_next;
@@ -994,7 +1033,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
 	}
 	for (cidx = 0; cidx < 2; cidx++) {
 		int devtype = -1;
-		if (pcm->streams[cidx].substream == NULL)
+		if (pcm->streams[cidx].substream == NULL || pcm->internal)
 			continue;
 		switch (cidx) {
 		case SNDRV_PCM_STREAM_PLAYBACK:
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index cd094ec..d428ffe 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -611,7 +611,6 @@ static void isight_card_free(struct snd_card *card)
 
 	fw_iso_resources_destroy(&isight->resources);
 	fw_unit_put(isight->unit);
-	fw_device_put(isight->device);
 	mutex_destroy(&isight->mutex);
 }
 
@@ -644,7 +643,7 @@ static int isight_probe(struct device *unit_dev)
 	isight->card = card;
 	mutex_init(&isight->mutex);
 	isight->unit = fw_unit_get(unit);
-	isight->device = fw_device_get(fw_dev);
+	isight->device = fw_dev;
 	isight->audio_base = get_unit_base(unit);
 	if (!isight->audio_base) {
 		dev_err(&unit->device, "audio unit base not found\n");
@@ -681,7 +680,6 @@ static int isight_probe(struct device *unit_dev)
 
 err_unit:
 	fw_unit_put(isight->unit);
-	fw_device_put(isight->device);
 	mutex_destroy(&isight->mutex);
 error:
 	snd_card_free(card);
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index cbe6bb9..297244e 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -656,12 +656,10 @@ static u32 fwspk_read_firmware_version(struct fw_unit *unit)
 static void fwspk_card_free(struct snd_card *card)
 {
 	struct fwspk *fwspk = card->private_data;
-	struct fw_device *dev = fw_parent_device(fwspk->unit);
 
 	amdtp_out_stream_destroy(&fwspk->stream);
 	cmp_connection_destroy(&fwspk->connection);
 	fw_unit_put(fwspk->unit);
-	fw_device_put(dev);
 	mutex_destroy(&fwspk->mutex);
 }
 
@@ -718,7 +716,6 @@ static int __devinit fwspk_probe(struct device *unit_dev)
 	fwspk = card->private_data;
 	fwspk->card = card;
 	mutex_init(&fwspk->mutex);
-	fw_device_get(fw_dev);
 	fwspk->unit = fw_unit_get(unit);
 	fwspk->device_info = fwspk_detect(fw_dev);
 	if (!fwspk->device_info) {
@@ -767,7 +764,6 @@ err_connection:
 	cmp_connection_destroy(&fwspk->connection);
 err_unit:
 	fw_unit_put(fwspk->unit);
-	fw_device_put(fw_dev);
 	mutex_destroy(&fwspk->mutex);
 error:
 	snd_card_free(card);
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index bb93815..466a5c8 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -26,7 +26,7 @@
 #include <sound/mpu401.h>
 #include <sound/hwdep.h>
 #include <sound/ac97_codec.h>
-
+#include <sound/tlv.h>
 #endif
 
 #ifndef CHIP_AU8820
@@ -107,6 +107,14 @@
 #define NR_WTPB 0x20		/* WT channels per each bank. */
 #define NR_PCM	0x10
 
+struct pcm_vol {
+	struct snd_kcontrol *kctl;
+	int active;
+	int dma;
+	int mixin[4];
+	int vol[4];
+};
+
 /* Structs */
 typedef struct {
 	//int this_08;          /* Still unknown */
@@ -168,6 +176,7 @@ struct snd_vortex {
 	/* Xtalk canceler */
 	int xt_mode;		/* 1: speakers, 0:headphones. */
 #endif
+	struct pcm_vol pcm_vol[NR_PCM];
 
 	int isquad;		/* cache of extended ID codec flag. */
 
@@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt);
 /* Connection  stuff. */
 static void vortex_connect_default(vortex_t * vortex, int en);
 static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
-				 int dir, int type);
+				 int dir, int type, int subdev);
 static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
 				  int restype);
 #ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 6933a27..1181c5e 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
 }
 
 /* Default Connections  */
-static int
-vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
 
 static void vortex_connect_default(vortex_t * vortex, int en)
 {
@@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en)
   Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
 */
 static int
-vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
+vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
+			int type, int subdev)
 {
 	stream_t *stream;
 	int i, en;
+	struct pcm_vol *p;
 	
-	if ((nr_ch == 3)
-	    || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
-		return -EBUSY;
-
 	if (dma >= 0) {
 		en = 0;
 		vortex_adb_checkinout(vortex,
@@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
 							      MIX_DEFIGAIN);
 #endif
 			}
+			if (stream->type == VORTEX_PCM_ADB && en) {
+				p = &vortex->pcm_vol[subdev];
+				p->dma = dma;
+				for (i = 0; i < nr_ch; i++)
+					p->mixin[i] = mix[i];
+				for (i = 0; i < ch_top; i++)
+					p->vol[i] = 0;
+			}
 		}
 #ifndef CHIP_AU8820
 		else {
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 0ef2f97..e59f120 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
 	.mask = 0,
 };
 #endif
+
+static void vortex_notify_pcm_vol_change(struct snd_card *card,
+			struct snd_kcontrol *kctl, int activate)
+{
+	if (activate)
+		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	else
+		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
+	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
+				SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
+}
+
 /* open callback */
 static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
 {
@@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
 		if (stream != NULL)
 			vortex_adb_allocroute(chip, stream->dma,
 					      stream->nr_ch, stream->dir,
-					      stream->type);
+					      stream->type,
+					      substream->number);
 		/* Alloc routes. */
 		dma =
 		    vortex_adb_allocroute(chip, -1,
 					  params_channels(hw_params),
-					  substream->stream, type);
+					  substream->stream, type,
+					  substream->number);
 		if (dma < 0) {
 			spin_unlock_irq(&chip->lock);
 			return dma;
@@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
 		vortex_adbdma_setbuffers(chip, dma,
 					 params_period_bytes(hw_params),
 					 params_periods(hw_params));
+		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
+			chip->pcm_vol[substream->number].active = 1;
+			vortex_notify_pcm_vol_change(chip->card,
+				chip->pcm_vol[substream->number].kctl, 1);
+		}
 	}
 #ifndef CHIP_AU8810
 	else {
@@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
 	spin_lock_irq(&chip->lock);
 	// Delete audio routes.
 	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
-		if (stream != NULL)
+		if (stream != NULL) {
+			if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
+				chip->pcm_vol[substream->number].active = 0;
+				vortex_notify_pcm_vol_change(chip->card,
+					chip->pcm_vol[substream->number].kctl,
+					0);
+			}
 			vortex_adb_allocroute(chip, stream->dma,
 					      stream->nr_ch, stream->dir,
-					      stream->type);
+					      stream->type,
+					      substream->number);
+		}
 	}
 #ifndef CHIP_AU8810
 	else {
@@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
 	},
 };
 
+/* subdevice PCM Volume control */
+
+static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
+{
+	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+	uinfo->value.integer.min = -128;
+	uinfo->value.integer.max = 32;
+	return 0;
+}
+
+static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
+	int subdev = kcontrol->id.subdevice;
+	struct pcm_vol *p = &vortex->pcm_vol[subdev];
+	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+	for (i = 0; i < max_chn; i++)
+		ucontrol->value.integer.value[i] = p->vol[i];
+	return 0;
+}
+
+static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	int changed = 0;
+	int mixin;
+	unsigned char vol;
+	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
+	int subdev = kcontrol->id.subdevice;
+	struct pcm_vol *p = &vortex->pcm_vol[subdev];
+	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
+	for (i = 0; i < max_chn; i++) {
+		if (p->vol[i] != ucontrol->value.integer.value[i]) {
+			p->vol[i] = ucontrol->value.integer.value[i];
+			if (p->active) {
+				switch (vortex->dma_adb[p->dma].nr_ch) {
+				case 1:
+					mixin = p->mixin[0];
+					break;
+				case 2:
+				default:
+					mixin = p->mixin[(i < 2) ? i : (i - 2)];
+					break;
+				case 4:
+					mixin = p->mixin[i];
+					break;
+				};
+				vol = p->vol[i];
+				vortex_mix_setinputvolumebyte(vortex,
+					vortex->mixplayb[i], mixin, vol);
+			}
+			changed = 1;
+		}
+	}
+	return changed;
+}
+
+static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
+
+static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
+	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+	.name = "PCM Playback Volume",
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+		SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+		SNDRV_CTL_ELEM_ACCESS_INACTIVE,
+	.info = snd_vortex_pcm_vol_info,
+	.get = snd_vortex_pcm_vol_get,
+	.put = snd_vortex_pcm_vol_put,
+	.tlv = { .p = vortex_pcm_vol_db_scale },
+};
+
 /* create a pcm device */
 static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
 {
@@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
 				return err;
 		}
 	}
+	if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
+		for (i = 0; i < NR_PCM; i++) {
+			chip->pcm_vol[i].active = 0;
+			chip->pcm_vol[i].dma = -1;
+			kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
+			if (!kctl)
+				return -ENOMEM;
+			chip->pcm_vol[i].kctl = kctl;
+			kctl->id.device = 0;
+			kctl->id.subdevice = i;
+			err = snd_ctl_add(chip->card, kctl);
+			if (err < 0)
+				return err;
+		}
+	}
 	return 0;
 }
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
deleted file mode 100644
index 3b5170b..0000000
--- a/sound/pci/hda/alc260_quirks.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * ALC260 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC260 models */
-enum {
-	ALC260_AUTO,
-	ALC260_BASIC,
-	ALC260_FUJITSU_S702X,
-	ALC260_ACER,
-	ALC260_WILL,
-	ALC260_REPLACER_672V,
-	ALC260_FAVORIT100,
-#ifdef CONFIG_SND_DEBUG
-	ALC260_TEST,
-#endif
-	ALC260_MODEL_LAST /* last tag */
-};
-
-static const hda_nid_t alc260_dac_nids[1] = {
-	/* front */
-	0x02,
-};
-
-static const hda_nid_t alc260_adc_nids[1] = {
-	/* ADC0 */
-	0x04,
-};
-
-static const hda_nid_t alc260_adc_nids_alt[1] = {
-	/* ADC1 */
-	0x05,
-};
-
-/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
- * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
- */
-static const hda_nid_t alc260_dual_adc_nids[2] = {
-	/* ADC0, ADC1 */
-	0x04, 0x05
-};
-
-#define ALC260_DIGOUT_NID	0x03
-#define ALC260_DIGIN_NID	0x06
-
-static const struct hda_input_mux alc260_capture_source = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Front Mic", 0x1 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
-
-/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
- * headphone jack and the internal CD lines since these are the only pins at
- * which audio can appear.  For flexibility, also allow the option of
- * recording the mixer output on the second ADC (ADC0 doesn't have a
- * connection to the mixer output).
- */
-static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
-	{
-		.num_items = 3,
-		.items = {
-			{ "Mic/Line", 0x0 },
-			{ "CD", 0x4 },
-			{ "Headphone", 0x2 },
-		},
-	},
-	{
-		.num_items = 4,
-		.items = {
-			{ "Mic/Line", 0x0 },
-			{ "CD", 0x4 },
-			{ "Headphone", 0x2 },
-			{ "Mixer", 0x5 },
-		},
-	},
-
-};
-
-/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
- * the Fujitsu S702x, but jacks are marked differently.
- */
-static const struct hda_input_mux alc260_acer_capture_sources[2] = {
-	{
-		.num_items = 4,
-		.items = {
-			{ "Mic", 0x0 },
-			{ "Line", 0x2 },
-			{ "CD", 0x4 },
-			{ "Headphone", 0x5 },
-		},
-	},
-	{
-		.num_items = 5,
-		.items = {
-			{ "Mic", 0x0 },
-			{ "Line", 0x2 },
-			{ "CD", 0x4 },
-			{ "Headphone", 0x6 },
-			{ "Mixer", 0x5 },
-		},
-	},
-};
-
-/* Maxdata Favorit 100XS */
-static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
-	{
-		.num_items = 2,
-		.items = {
-			{ "Line/Mic", 0x0 },
-			{ "CD", 0x4 },
-		},
-	},
-	{
-		.num_items = 3,
-		.items = {
-			{ "Line/Mic", 0x0 },
-			{ "CD", 0x4 },
-			{ "Mixer", 0x5 },
-		},
-	},
-};
-
-/*
- * This is just place-holder, so there's something for alc_build_pcms to look
- * at when it calculates the maximum number of channels. ALC260 has no mixer
- * element which allows changing the channel mode, so the verb list is
- * never used.
- */
-static const struct hda_channel_mode alc260_modes[1] = {
-	{ 2, NULL },
-};
-
-
-/* Mixer combinations
- *
- * basic: base_output + input + pc_beep + capture
- * fujitsu: fujitsu + capture
- * acer: acer + capture
- */
-
-static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc260_input_mixer[] = {
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
-	{ } /* end */
-};
-
-/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
- * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
- */
-static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
-	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
-	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
-	{ } /* end */
-};
-
-/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
- * versions of the ALC260 don't act on requests to enable mic bias from NID
- * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
- * datasheet doesn't mention this restriction.  At this stage it's not clear
- * whether this behaviour is intentional or is a hardware bug in chip
- * revisions available in early 2006.  Therefore for now allow the
- * "Headphone Jack Mode" control to span all choices, but if it turns out
- * that the lack of mic bias for this NID is intentional we could change the
- * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
- *
- * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
- * don't appear to make the mic bias available from the "line" jack, even
- * though the NID used for this jack (0x14) can supply it.  The theory is
- * that perhaps Acer have included blocking capacitors between the ALC260
- * and the output jack.  If this turns out to be the case for all such
- * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
- * to ALC_PIN_DIR_INOUT_NOMICBIAS.
- *
- * The C20x Tablet series have a mono internal speaker which is controlled
- * via the chip's Mono sum widget and pin complex, so include the necessary
- * controls for such models.  On models without a "mono speaker" the control
- * won't do anything.
- */
-static const struct snd_kcontrol_new alc260_acer_mixer[] = {
-	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
-	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
-	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
-			      HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
-			   HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-	{ } /* end */
-};
-
-/* Maxdata Favorit 100XS: one output and one input (0x12) jack
- */
-static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
-	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
-	ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
-	HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-	ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-	{ } /* end */
-};
-
-/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
- * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
- */
-static const struct snd_kcontrol_new alc260_will_mixer[] = {
-	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-	{ } /* end */
-};
-
-/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
- * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
- */
-static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
-	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
-	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
-	{ } /* end */
-};
-
-/*
- * initialization verbs
- */
-static const struct hda_verb alc260_init_verbs[] = {
-	/* Line In pin widget for input */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* CD pin widget for input */
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	/* Mic2 (front panel) pin widget for input and vref at 80% */
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	/* LINE-2 is used for line-out in rear */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	/* select line-out */
-	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* LINE-OUT pin */
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	/* enable HP */
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	/* enable Mono */
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	/* mute capture amp left and right */
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	/* set connection select to line in (default select for this ADC) */
-	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* mute capture amp left and right */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	/* set connection select to line in (default select for this ADC) */
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* set vol=0 Line-Out mixer amp left and right */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	/* unmute pin widget amp left and right (no gain on this amp) */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* set vol=0 HP mixer amp left and right */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	/* unmute pin widget amp left and right (no gain on this amp) */
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* set vol=0 Mono mixer amp left and right */
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	/* unmute pin widget amp left and right (no gain on this amp) */
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* unmute LINE-2 out pin */
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
-	 * Line In 2 = 0x03
-	 */
-	/* mute analog inputs */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-	/* mute Front out path */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* mute Headphone out path */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* mute Mono out path */
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{ }
-};
-
-/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
- * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
- * audio = 0x16, internal speaker = 0x10.
- */
-static const struct hda_verb alc260_fujitsu_init_verbs[] = {
-	/* Disable all GPIOs */
-	{0x01, AC_VERB_SET_GPIO_MASK, 0},
-	/* Internal speaker is connected to headphone pin */
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
-	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* Ensure all other unused pins are disabled and muted. */
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-
-	/* Disable digital (SPDIF) pins */
-	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
-	 * when acting as an output.
-	 */
-	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-
-	/* Start with output sum widgets muted and their output gains at min */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Unmute Line1 pin widget output buffer since it starts as an output.
-	 * If the pin mode is changed by the user the pin mode control will
-	 * take care of enabling the pin's input/output buffers as needed.
-	 * Therefore there's no need to enable the input buffer at this
-	 * stage.
-	 */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Unmute input buffer of pin widget used for Line-in (no equiv
-	 * mixer ctrl)
-	 */
-	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-	/* Mute capture amp left and right */
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	/* Set ADC connection select to match default mixer setting - line
-	 * in (on mic1 pin)
-	 */
-	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Do the same for the second ADC: mute capture input amp and
-	 * set ADC connection to line in (on mic1 pin)
-	 */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Mute all inputs to mixer widget (even unconnected ones) */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-	{ }
-};
-
-/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
- * similar laptops (adapted from Fujitsu init verbs).
- */
-static const struct hda_verb alc260_acer_init_verbs[] = {
-	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
-	 * the headphone jack.  Turn this on and rely on the standard mute
-	 * methods whenever the user wants to turn these outputs off.
-	 */
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-	/* Internal speaker/Headphone jack is connected to Line-out pin */
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	/* Internal microphone/Mic jack is connected to Mic1 pin */
-	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-	/* Line In jack is connected to Line1 pin */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	/* Ensure all other unused pins are disabled and muted. */
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	/* Disable digital (SPDIF) pins */
-	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
-	 * bus when acting as outputs.
-	 */
-	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
-	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-
-	/* Start with output sum widgets muted and their output gains at min */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-	/* Unmute Line-out pin widget amp left and right
-	 * (no equiv mixer ctrl)
-	 */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
-	 * inputs. If the pin mode is changed by the user the pin mode control
-	 * will take care of enabling the pin's input/output buffers as needed.
-	 * Therefore there's no need to enable the input buffer at this
-	 * stage.
-	 */
-	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-	/* Mute capture amp left and right */
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	/* Set ADC connection select to match default mixer setting - mic
-	 * (on mic1 pin)
-	 */
-	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Do similar with the second ADC: mute capture input amp and
-	 * set ADC connection to mic to match ALSA's default state.
-	 */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Mute all inputs to mixer widget (even unconnected ones) */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-	{ }
-};
-
-/* Initialisation sequence for Maxdata Favorit 100XS
- * (adapted from Acer init verbs).
- */
-static const struct hda_verb alc260_favorit100_init_verbs[] = {
-	/* GPIO 0 enables the output jack.
-	 * Turn this on and rely on the standard mute
-	 * methods whenever the user wants to turn these outputs off.
-	 */
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
-	/* Line/Mic input jack is connected to Mic1 pin */
-	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-	/* Ensure all other unused pins are disabled and muted. */
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	/* Disable digital (SPDIF) pins */
-	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
-	 * bus when acting as outputs.
-	 */
-	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
-	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-
-	/* Start with output sum widgets muted and their output gains at min */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-	/* Unmute Line-out pin widget amp left and right
-	 * (no equiv mixer ctrl)
-	 */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
-	 * inputs. If the pin mode is changed by the user the pin mode control
-	 * will take care of enabling the pin's input/output buffers as needed.
-	 * Therefore there's no need to enable the input buffer at this
-	 * stage.
-	 */
-	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-	/* Mute capture amp left and right */
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	/* Set ADC connection select to match default mixer setting - mic
-	 * (on mic1 pin)
-	 */
-	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Do similar with the second ADC: mute capture input amp and
-	 * set ADC connection to mic to match ALSA's default state.
-	 */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Mute all inputs to mixer widget (even unconnected ones) */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-	{ }
-};
-
-static const struct hda_verb alc260_will_verbs[] = {
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
-	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
-	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
-	{}
-};
-
-static const struct hda_verb alc260_replacer_672v_verbs[] = {
-	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
-	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
-	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
-
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
-
-	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{}
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc260_replacer_672v_automute(struct hda_codec *codec)
-{
-        unsigned int present;
-
-	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
-	present = snd_hda_jack_detect(codec, 0x0f);
-	if (present) {
-		snd_hda_codec_write_cache(codec, 0x01, 0,
-					  AC_VERB_SET_GPIO_DATA, 1);
-		snd_hda_codec_write_cache(codec, 0x0f, 0,
-					  AC_VERB_SET_PIN_WIDGET_CONTROL,
-					  PIN_HP);
-	} else {
-		snd_hda_codec_write_cache(codec, 0x01, 0,
-					  AC_VERB_SET_GPIO_DATA, 0);
-		snd_hda_codec_write_cache(codec, 0x0f, 0,
-					  AC_VERB_SET_PIN_WIDGET_CONTROL,
-					  PIN_OUT);
-	}
-}
-
-static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
-                                       unsigned int res)
-{
-        if ((res >> 26) == ALC_HP_EVENT)
-                alc260_replacer_672v_automute(codec);
-}
-
-static const struct hda_verb alc260_hp_dc7600_verbs[] = {
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{}
-};
-
-/* Test configuration for debugging, modelled after the ALC880 test
- * configuration.
- */
-#ifdef CONFIG_SND_DEBUG
-static const hda_nid_t alc260_test_dac_nids[1] = {
-	0x02,
-};
-static const hda_nid_t alc260_test_adc_nids[2] = {
-	0x04, 0x05,
-};
-/* For testing the ALC260, each input MUX needs its own definition since
- * the signal assignments are different.  This assumes that the first ADC
- * is NID 0x04.
- */
-static const struct hda_input_mux alc260_test_capture_sources[2] = {
-	{
-		.num_items = 7,
-		.items = {
-			{ "MIC1 pin", 0x0 },
-			{ "MIC2 pin", 0x1 },
-			{ "LINE1 pin", 0x2 },
-			{ "LINE2 pin", 0x3 },
-			{ "CD pin", 0x4 },
-			{ "LINE-OUT pin", 0x5 },
-			{ "HP-OUT pin", 0x6 },
-		},
-        },
-	{
-		.num_items = 8,
-		.items = {
-			{ "MIC1 pin", 0x0 },
-			{ "MIC2 pin", 0x1 },
-			{ "LINE1 pin", 0x2 },
-			{ "LINE2 pin", 0x3 },
-			{ "CD pin", 0x4 },
-			{ "Mixer", 0x5 },
-			{ "LINE-OUT pin", 0x6 },
-			{ "HP-OUT pin", 0x7 },
-		},
-        },
-};
-static const struct snd_kcontrol_new alc260_test_mixer[] = {
-	/* Output driver widgets */
-	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
-
-	/* Modes for retasking pin widgets
-	 * Note: the ALC260 doesn't seem to act on requests to enable mic
-         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
-         * mention this restriction.  At this stage it's not clear whether
-         * this behaviour is intentional or is a hardware bug in chip
-         * revisions available at least up until early 2006.  Therefore for
-         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
-         * choices, but if it turns out that the lack of mic bias for these
-         * NIDs is intentional we could change their modes from
-         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
-	 */
-	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
-	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
-	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
-	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
-	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
-	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
-
-	/* Loopback mixer controls */
-	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
-	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
-	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
-	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
-	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
-	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
-	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
-
-	/* Controls for GPIO pins, assuming they are configured as outputs */
-	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
-	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
-	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
-	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
-
-	/* Switches to allow the digital IO pins to be enabled.  The datasheet
-	 * is ambigious as to which NID is which; testing on laptops which
-	 * make this output available should provide clarification.
-	 */
-	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
-	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
-
-	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
-	 * this output to turn on an external amplifier.
-	 */
-	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
-	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
-
-	{ } /* end */
-};
-static const struct hda_verb alc260_test_init_verbs[] = {
-	/* Enable all GPIOs as outputs with an initial value of 0 */
-	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
-	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
-	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
-
-	/* Enable retasking pins as output, initially without power amp */
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-
-	/* Disable digital (SPDIF) pins initially, but users can enable
-	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
-	 * payload also sets the generation to 0, output to be in "consumer"
-	 * PCM format, copyright asserted, no pre-emphasis and no validity
-	 * control.
-	 */
-	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
-	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
-
-	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
-	 * OUT1 sum bus when acting as an output.
-	 */
-	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
-	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
-	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
-	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
-
-	/* Start with output sum widgets muted and their output gains at min */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-
-	/* Unmute retasking pin widget output buffers since the default
-	 * state appears to be output.  As the pin mode is changed by the
-	 * user the pin mode control will take care of enabling the pin's
-	 * input/output buffers as needed.
-	 */
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Also unmute the mono-out pin widget */
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	/* Mute capture amp left and right */
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	/* Set ADC connection select to match default mixer setting (mic1
-	 * pin)
-	 */
-	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Do the same for the second ADC: mute capture input amp and
-	 * set ADC connection to mic1 pin
-	 */
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Mute all inputs to mixer widget (even unconnected ones) */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
-
-	{ }
-};
-#endif
-
-/*
- * ALC260 configurations
- */
-static const char * const alc260_models[ALC260_MODEL_LAST] = {
-	[ALC260_BASIC]		= "basic",
-	[ALC260_FUJITSU_S702X]	= "fujitsu",
-	[ALC260_ACER]		= "acer",
-	[ALC260_WILL]		= "will",
-	[ALC260_REPLACER_672V]	= "replacer",
-	[ALC260_FAVORIT100]	= "favorit100",
-#ifdef CONFIG_SND_DEBUG
-	[ALC260_TEST]		= "test",
-#endif
-	[ALC260_AUTO]		= "auto",
-};
-
-static const struct snd_pci_quirk alc260_cfg_tbl[] = {
-	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
-	SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
-	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
-	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
-	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
-	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
-	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
-	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
-	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
-	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
-	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
-	{}
-};
-
-static const struct alc_config_preset alc260_presets[] = {
-	[ALC260_BASIC] = {
-		.mixers = { alc260_base_output_mixer,
-			    alc260_input_mixer },
-		.init_verbs = { alc260_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
-		.dac_nids = alc260_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-		.adc_nids = alc260_dual_adc_nids,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.input_mux = &alc260_capture_source,
-	},
-	[ALC260_FUJITSU_S702X] = {
-		.mixers = { alc260_fujitsu_mixer },
-		.init_verbs = { alc260_fujitsu_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
-		.dac_nids = alc260_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-		.adc_nids = alc260_dual_adc_nids,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
-		.input_mux = alc260_fujitsu_capture_sources,
-	},
-	[ALC260_ACER] = {
-		.mixers = { alc260_acer_mixer },
-		.init_verbs = { alc260_acer_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
-		.dac_nids = alc260_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-		.adc_nids = alc260_dual_adc_nids,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
-		.input_mux = alc260_acer_capture_sources,
-	},
-	[ALC260_FAVORIT100] = {
-		.mixers = { alc260_favorit100_mixer },
-		.init_verbs = { alc260_favorit100_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
-		.dac_nids = alc260_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
-		.adc_nids = alc260_dual_adc_nids,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
-		.input_mux = alc260_favorit100_capture_sources,
-	},
-	[ALC260_WILL] = {
-		.mixers = { alc260_will_mixer },
-		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
-		.dac_nids = alc260_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
-		.adc_nids = alc260_adc_nids,
-		.dig_out_nid = ALC260_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.input_mux = &alc260_capture_source,
-	},
-	[ALC260_REPLACER_672V] = {
-		.mixers = { alc260_replacer_672v_mixer },
-		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
-		.dac_nids = alc260_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
-		.adc_nids = alc260_adc_nids,
-		.dig_out_nid = ALC260_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.input_mux = &alc260_capture_source,
-		.unsol_event = alc260_replacer_672v_unsol_event,
-		.init_hook = alc260_replacer_672v_automute,
-	},
-#ifdef CONFIG_SND_DEBUG
-	[ALC260_TEST] = {
-		.mixers = { alc260_test_mixer },
-		.init_verbs = { alc260_test_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
-		.dac_nids = alc260_test_dac_nids,
-		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
-		.adc_nids = alc260_test_adc_nids,
-		.num_channel_mode = ARRAY_SIZE(alc260_modes),
-		.channel_mode = alc260_modes,
-		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
-		.input_mux = alc260_test_capture_sources,
-	},
-#endif
-};
-
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
deleted file mode 100644
index 501501e..0000000
--- a/sound/pci/hda/alc880_quirks.c
+++ /dev/null
@@ -1,1707 +0,0 @@
-/*
- * ALC880 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC880 board config type */
-enum {
-	ALC880_AUTO,
-	ALC880_3ST,
-	ALC880_3ST_DIG,
-	ALC880_5ST,
-	ALC880_5ST_DIG,
-	ALC880_W810,
-	ALC880_Z71V,
-	ALC880_6ST,
-	ALC880_6ST_DIG,
-	ALC880_F1734,
-	ALC880_ASUS,
-	ALC880_ASUS_DIG,
-	ALC880_ASUS_W1V,
-	ALC880_ASUS_DIG2,
-	ALC880_FUJITSU,
-	ALC880_UNIWILL_DIG,
-	ALC880_UNIWILL,
-	ALC880_UNIWILL_P53,
-	ALC880_CLEVO,
-	ALC880_TCL_S700,
-	ALC880_LG,
-#ifdef CONFIG_SND_DEBUG
-	ALC880_TEST,
-#endif
-	ALC880_MODEL_LAST /* last tag */
-};
-
-/*
- * ALC880 3-stack model
- *
- * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
- * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
- *                 F-Mic = 0x1b, HP = 0x19
- */
-
-static const hda_nid_t alc880_dac_nids[4] = {
-	/* front, rear, clfe, rear_surr */
-	0x02, 0x05, 0x04, 0x03
-};
-
-static const hda_nid_t alc880_adc_nids[3] = {
-	/* ADC0-2 */
-	0x07, 0x08, 0x09,
-};
-
-/* The datasheet says the node 0x07 is connected from inputs,
- * but it shows zero connection in the real implementation on some devices.
- * Note: this is a 915GAV bug, fixed on 915GLV
- */
-static const hda_nid_t alc880_adc_nids_alt[2] = {
-	/* ADC1-2 */
-	0x08, 0x09,
-};
-
-#define ALC880_DIGOUT_NID	0x06
-#define ALC880_DIGIN_NID	0x0a
-#define ALC880_PIN_CD_NID	0x1c
-
-static const struct hda_input_mux alc880_capture_source = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Front Mic", 0x3 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
-
-/* channel source setting (2/6 channel selection for 3-stack) */
-/* 2ch mode */
-static const struct hda_verb alc880_threestack_ch2_init[] = {
-	/* set line-in to input, mute it */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-	/* set mic-in to input vref 80%, mute it */
-	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-	{ } /* end */
-};
-
-/* 6ch mode */
-static const struct hda_verb alc880_threestack_ch6_init[] = {
-	/* set line-in to output, unmute it */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-	/* set mic-in to output, unmute it */
-	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-	{ } /* end */
-};
-
-static const struct hda_channel_mode alc880_threestack_modes[2] = {
-	{ 2, alc880_threestack_ch2_init },
-	{ 6, alc880_threestack_ch6_init },
-};
-
-static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-/*
- * ALC880 5-stack model
- *
- * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
- *      Side = 0x02 (0xd)
- * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
- *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
- */
-
-/* additional mixers to alc880_three_stack_mixer */
-static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
-	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
-	{ } /* end */
-};
-
-/* channel source setting (6/8 channel selection for 5-stack) */
-/* 6ch mode */
-static const struct hda_verb alc880_fivestack_ch6_init[] = {
-	/* set line-in to input, mute it */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-	{ } /* end */
-};
-
-/* 8ch mode */
-static const struct hda_verb alc880_fivestack_ch8_init[] = {
-	/* set line-in to output, unmute it */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
-	{ } /* end */
-};
-
-static const struct hda_channel_mode alc880_fivestack_modes[2] = {
-	{ 6, alc880_fivestack_ch6_init },
-	{ 8, alc880_fivestack_ch8_init },
-};
-
-
-/*
- * ALC880 6-stack model
- *
- * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
- *      Side = 0x05 (0x0f)
- * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
- *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
- */
-
-static const hda_nid_t alc880_6st_dac_nids[4] = {
-	/* front, rear, clfe, rear_surr */
-	0x02, 0x03, 0x04, 0x05
-};
-
-static const struct hda_input_mux alc880_6stack_capture_source = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Front Mic", 0x1 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
-
-/* fixed 8-channels */
-static const struct hda_channel_mode alc880_sixstack_modes[1] = {
-	{ 8, NULL },
-};
-
-static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-
-/*
- * ALC880 W810 model
- *
- * W810 has rear IO for:
- * Front (DAC 02)
- * Surround (DAC 03)
- * Center/LFE (DAC 04)
- * Digital out (06)
- *
- * The system also has a pair of internal speakers, and a headphone jack.
- * These are both connected to Line2 on the codec, hence to DAC 02.
- *
- * There is a variable resistor to control the speaker or headphone
- * volume. This is a hardware-only device without a software API.
- *
- * Plugging headphones in will disable the internal speakers. This is
- * implemented in hardware, not via the driver using jack sense. In
- * a similar fashion, plugging into the rear socket marked "front" will
- * disable both the speakers and headphones.
- *
- * For input, there's a microphone jack, and an "audio in" jack.
- * These may not do anything useful with this driver yet, because I
- * haven't setup any initialization verbs for these yet...
- */
-
-static const hda_nid_t alc880_w810_dac_nids[3] = {
-	/* front, rear/surround, clfe */
-	0x02, 0x03, 0x04
-};
-
-/* fixed 6 channels */
-static const struct hda_channel_mode alc880_w810_modes[1] = {
-	{ 6, NULL }
-};
-
-/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
-static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-	{ } /* end */
-};
-
-
-/*
- * Z710V model
- *
- * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
- * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
- *                 Line = 0x1a
- */
-
-static const hda_nid_t alc880_z71v_dac_nids[1] = {
-	0x02
-};
-#define ALC880_Z71V_HP_DAC	0x03
-
-/* fixed 2 channels */
-static const struct hda_channel_mode alc880_2_jack_modes[1] = {
-	{ 2, NULL }
-};
-
-static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	{ } /* end */
-};
-
-
-/*
- * ALC880 F1734 model
- *
- * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
- * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
- */
-
-static const hda_nid_t alc880_f1734_dac_nids[1] = {
-	0x03
-};
-#define ALC880_F1734_HP_DAC	0x02
-
-static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct hda_input_mux alc880_f1734_capture_source = {
-	.num_items = 2,
-	.items = {
-		{ "Mic", 0x1 },
-		{ "CD", 0x4 },
-	},
-};
-
-
-/*
- * ALC880 ASUS model
- *
- * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
- * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
- *  Mic = 0x18, Line = 0x1a
- */
-
-#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
-#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
-
-static const struct snd_kcontrol_new alc880_asus_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-/*
- * ALC880 ASUS W1V model
- *
- * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
- * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
- *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
- */
-
-/* additional mixers to alc880_asus_mixer */
-static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
-	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
-	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
-	{ } /* end */
-};
-
-/* TCL S700 */
-static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
-	{ } /* end */
-};
-
-/* Uniwill */
-static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	{ } /* end */
-};
-
-/*
- * initialize the codec volumes, etc
- */
-
-/*
- * generic initialization of ADC, input mixers and output mixers
- */
-static const struct hda_verb alc880_volume_init_verbs[] = {
-	/*
-	 * Unmute ADC0-2 and set the default input to mic-in
-	 */
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-
-	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
-	 * mixer widget
-	 * Note: PASD motherboards uses the Line In 2 as the input for front
-	 * panel mic (mic 2)
-	 */
-	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
-
-	/*
-	 * Set up output mixers (0x0c - 0x0f)
-	 */
-	/* set vol=0 to output mixers */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	/* set up input amps for analog loopback */
-	/* Amp Indices: DAC = 0, mixer = 1 */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-	{ }
-};
-
-/*
- * 3-stack pin configuration:
- * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
- */
-static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
-	/*
-	 * preset connection lists of input pins
-	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
-	 */
-	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
-
-	/*
-	 * Set pin mode and muting
-	 */
-	/* set front pin widgets 0x14 for output */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Mic2 (as headphone out) for HP output */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Line In pin widget for input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Line2 (as front mic) pin widget for input and vref at 80% */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{ }
-};
-
-/*
- * 5-stack pin configuration:
- * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
- * line-in/side = 0x1a, f-mic = 0x1b
- */
-static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
-	/*
-	 * preset connection lists of input pins
-	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
-	 */
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
-
-	/*
-	 * Set pin mode and muting
-	 */
-	/* set pin widgets 0x14-0x17 for output */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	/* unmute pins for output (no gain on this amp) */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Mic2 (as headphone out) for HP output */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Line In pin widget for input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Line2 (as front mic) pin widget for input and vref at 80% */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{ }
-};
-
-/*
- * W810 pin configuration:
- * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
- */
-static const struct hda_verb alc880_pin_w810_init_verbs[] = {
-	/* hphone/speaker input selector: front DAC */
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
-
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-	{ }
-};
-
-/*
- * Z71V pin configuration:
- * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
- */
-static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{ }
-};
-
-/*
- * 6-stack pin configuration:
- * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
- * f-mic = 0x19, line = 0x1a, HP = 0x1b
- */
-static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{ }
-};
-
-/*
- * Uniwill pin configuration:
- * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
- * line = 0x1a
- */
-static const struct hda_verb alc880_uniwill_init_verbs[] = {
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
-	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
-
-	{ }
-};
-
-/*
-* Uniwill P53
-* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
- */
-static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
-
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
-
-	{ }
-};
-
-static const struct hda_verb alc880_beep_init_verbs[] = {
-	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
-	{ }
-};
-
-static void alc880_uniwill_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x14;
-	spec->autocfg.speaker_pins[0] = 0x15;
-	spec->autocfg.speaker_pins[0] = 0x16;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc880_uniwill_init_hook(struct hda_codec *codec)
-{
-	alc_hp_automute(codec);
-	alc88x_simple_mic_automute(codec);
-}
-
-static void alc880_uniwill_unsol_event(struct hda_codec *codec,
-				       unsigned int res)
-{
-	/* Looks like the unsol event is incompatible with the standard
-	 * definition.  4bit tag is placed at 28 bit!
-	 */
-	res >>= 28;
-	switch (res) {
-	case ALC_MIC_EVENT:
-		alc88x_simple_mic_automute(codec);
-		break;
-	default:
-		alc_exec_unsol_event(codec, res);
-		break;
-	}
-}
-
-static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	alc_exec_unsol_event(codec, res >> 28);
-}
-
-static void alc880_uniwill_p53_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x14;
-	spec->autocfg.speaker_pins[0] = 0x15;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
-{
-	unsigned int present;
-
-	present = snd_hda_codec_read(codec, 0x21, 0,
-				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
-	present &= HDA_AMP_VOLMASK;
-	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
-				 HDA_AMP_VOLMASK, present);
-	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
-				 HDA_AMP_VOLMASK, present);
-}
-
-static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
-					   unsigned int res)
-{
-	/* Looks like the unsol event is incompatible with the standard
-	 * definition.  4bit tag is placed at 28 bit!
-	 */
-	res >>= 28;
-	if (res == ALC_DCVOL_EVENT)
-		alc880_uniwill_p53_dcvol_automute(codec);
-	else
-		alc_exec_unsol_event(codec, res);
-}
-
-/*
- * F1734 pin configuration:
- * HP = 0x14, speaker-out = 0x15, mic = 0x18
- */
-static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
-	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
-
-	{ }
-};
-
-/*
- * ASUS pin configuration:
- * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
- */
-static const struct hda_verb alc880_pin_asus_init_verbs[] = {
-	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	{ }
-};
-
-/* Enable GPIO mask and set output */
-#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
-#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
-#define alc880_gpio3_init_verbs	alc_gpio3_init_verbs
-
-/* Clevo m520g init */
-static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
-	/* headphone output */
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
-	/* line-out */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Line-in */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* CD */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Mic1 (rear panel) */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Mic2 (front panel) */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* headphone */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-        /* change to EAPD mode */
-	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
-	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
-
-	{ }
-};
-
-static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
-	/* change to EAPD mode */
-	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
-	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
-
-	/* Headphone output */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	/* Front output*/
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	/* Line In pin widget for input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-
-	/* change to EAPD mode */
-	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
-	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
-
-	{ }
-};
-
-/*
- * LG m1 express dual
- *
- * Pin assignment:
- *   Rear Line-In/Out (blue): 0x14
- *   Build-in Mic-In: 0x15
- *   Speaker-out: 0x17
- *   HP-Out (green): 0x1b
- *   Mic-In/Out (red): 0x19
- *   SPDIF-Out: 0x1e
- */
-
-/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
-static const hda_nid_t alc880_lg_dac_nids[3] = {
-	0x05, 0x02, 0x03
-};
-
-/* seems analog CD is not working */
-static const struct hda_input_mux alc880_lg_capture_source = {
-	.num_items = 3,
-	.items = {
-		{ "Mic", 0x1 },
-		{ "Line", 0x5 },
-		{ "Internal Mic", 0x6 },
-	},
-};
-
-/* 2,4,6 channel modes */
-static const struct hda_verb alc880_lg_ch2_init[] = {
-	/* set line-in and mic-in to input */
-	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-	{ }
-};
-
-static const struct hda_verb alc880_lg_ch4_init[] = {
-	/* set line-in to out and mic-in to input */
-	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
-	{ }
-};
-
-static const struct hda_verb alc880_lg_ch6_init[] = {
-	/* set line-in and mic-in to output */
-	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
-	{ }
-};
-
-static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
-	{ 2, alc880_lg_ch2_init },
-	{ 4, alc880_lg_ch4_init },
-	{ 6, alc880_lg_ch6_init },
-};
-
-static const struct snd_kcontrol_new alc880_lg_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
-	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
-	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-static const struct hda_verb alc880_lg_init_verbs[] = {
-	/* set capture source to mic-in */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	/* mute all amp mixer inputs */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
-	/* line-in to input */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* built-in mic */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* speaker-out */
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* mic-in to input */
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* HP-out */
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* jack sense */
-	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
-	{ }
-};
-
-/* toggle speaker-output according to the hp-jack state */
-static void alc880_lg_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x1b;
-	spec->autocfg.speaker_pins[0] = 0x17;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc880_lg_loopbacks[] = {
-	{ 0x0b, HDA_INPUT, 1 },
-	{ 0x0b, HDA_INPUT, 6 },
-	{ 0x0b, HDA_INPUT, 7 },
-	{ } /* end */
-};
-#endif
-
-/*
- * Test configuration for debugging
- *
- * Almost all inputs/outputs are enabled.  I/O pins can be configured via
- * enum controls.
- */
-#ifdef CONFIG_SND_DEBUG
-static const hda_nid_t alc880_test_dac_nids[4] = {
-	0x02, 0x03, 0x04, 0x05
-};
-
-static const struct hda_input_mux alc880_test_capture_source = {
-	.num_items = 7,
-	.items = {
-		{ "In-1", 0x0 },
-		{ "In-2", 0x1 },
-		{ "In-3", 0x2 },
-		{ "In-4", 0x3 },
-		{ "CD", 0x4 },
-		{ "Front", 0x5 },
-		{ "Surround", 0x6 },
-	},
-};
-
-static const struct hda_channel_mode alc880_test_modes[4] = {
-	{ 2, NULL },
-	{ 4, NULL },
-	{ 6, NULL },
-	{ 8, NULL },
-};
-
-static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
-				 struct snd_ctl_elem_info *uinfo)
-{
-	static const char * const texts[] = {
-		"N/A", "Line Out", "HP Out",
-		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
-	};
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 8;
-	if (uinfo->value.enumerated.item >= 8)
-		uinfo->value.enumerated.item = 7;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-	unsigned int pin_ctl, item = 0;
-
-	pin_ctl = snd_hda_codec_read(codec, nid, 0,
-				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-	if (pin_ctl & AC_PINCTL_OUT_EN) {
-		if (pin_ctl & AC_PINCTL_HP_EN)
-			item = 2;
-		else
-			item = 1;
-	} else if (pin_ctl & AC_PINCTL_IN_EN) {
-		switch (pin_ctl & AC_PINCTL_VREFEN) {
-		case AC_PINCTL_VREF_HIZ: item = 3; break;
-		case AC_PINCTL_VREF_50:  item = 4; break;
-		case AC_PINCTL_VREF_GRD: item = 5; break;
-		case AC_PINCTL_VREF_80:  item = 6; break;
-		case AC_PINCTL_VREF_100: item = 7; break;
-		}
-	}
-	ucontrol->value.enumerated.item[0] = item;
-	return 0;
-}
-
-static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-	static const unsigned int ctls[] = {
-		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
-		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
-		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
-		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
-		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
-		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
-	};
-	unsigned int old_ctl, new_ctl;
-
-	old_ctl = snd_hda_codec_read(codec, nid, 0,
-				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
-	if (old_ctl != new_ctl) {
-		int val;
-		snd_hda_codec_write_cache(codec, nid, 0,
-					  AC_VERB_SET_PIN_WIDGET_CONTROL,
-					  new_ctl);
-		val = ucontrol->value.enumerated.item[0] >= 3 ?
-			HDA_AMP_MUTE : 0;
-		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-					 HDA_AMP_MUTE, val);
-		return 1;
-	}
-	return 0;
-}
-
-static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
-				 struct snd_ctl_elem_info *uinfo)
-{
-	static const char * const texts[] = {
-		"Front", "Surround", "CLFE", "Side"
-	};
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = 4;
-	if (uinfo->value.enumerated.item >= 4)
-		uinfo->value.enumerated.item = 3;
-	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-	unsigned int sel;
-
-	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
-	ucontrol->value.enumerated.item[0] = sel & 3;
-	return 0;
-}
-
-static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
-				struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
-	unsigned int sel;
-
-	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
-	if (ucontrol->value.enumerated.item[0] != sel) {
-		sel = ucontrol->value.enumerated.item[0] & 3;
-		snd_hda_codec_write_cache(codec, nid, 0,
-					  AC_VERB_SET_CONNECT_SEL, sel);
-		return 1;
-	}
-	return 0;
-}
-
-#define PIN_CTL_TEST(xname,nid) {			\
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
-			.name = xname,		       \
-			.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-			.info = alc_test_pin_ctl_info, \
-			.get = alc_test_pin_ctl_get,   \
-			.put = alc_test_pin_ctl_put,   \
-			.private_value = nid	       \
-			}
-
-#define PIN_SRC_TEST(xname,nid) {			\
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
-			.name = xname,		       \
-			.subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-			.info = alc_test_pin_src_info, \
-			.get = alc_test_pin_src_get,   \
-			.put = alc_test_pin_src_put,   \
-			.private_value = nid	       \
-			}
-
-static const struct snd_kcontrol_new alc880_test_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
-	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
-	PIN_CTL_TEST("Front Pin Mode", 0x14),
-	PIN_CTL_TEST("Surround Pin Mode", 0x15),
-	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
-	PIN_CTL_TEST("Side Pin Mode", 0x17),
-	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
-	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
-	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
-	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
-	PIN_SRC_TEST("In-1 Pin Source", 0x18),
-	PIN_SRC_TEST("In-2 Pin Source", 0x19),
-	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
-	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
-	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
-	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
-	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
-	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-static const struct hda_verb alc880_test_init_verbs[] = {
-	/* Unmute inputs of 0x0c - 0x0f */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	/* Vol output for 0x0c-0x0f */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	/* Set output pins 0x14-0x17 */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	/* Unmute output pins 0x14-0x17 */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Set input pins 0x18-0x1c */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	/* Mute input pins 0x18-0x1b */
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* ADC set up */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* Analog input/passthru */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	{ }
-};
-#endif
-
-/*
- */
-
-static const char * const alc880_models[ALC880_MODEL_LAST] = {
-	[ALC880_3ST]		= "3stack",
-	[ALC880_TCL_S700]	= "tcl",
-	[ALC880_3ST_DIG]	= "3stack-digout",
-	[ALC880_CLEVO]		= "clevo",
-	[ALC880_5ST]		= "5stack",
-	[ALC880_5ST_DIG]	= "5stack-digout",
-	[ALC880_W810]		= "w810",
-	[ALC880_Z71V]		= "z71v",
-	[ALC880_6ST]		= "6stack",
-	[ALC880_6ST_DIG]	= "6stack-digout",
-	[ALC880_ASUS]		= "asus",
-	[ALC880_ASUS_W1V]	= "asus-w1v",
-	[ALC880_ASUS_DIG]	= "asus-dig",
-	[ALC880_ASUS_DIG2]	= "asus-dig2",
-	[ALC880_UNIWILL_DIG]	= "uniwill",
-	[ALC880_UNIWILL_P53]	= "uniwill-p53",
-	[ALC880_FUJITSU]	= "fujitsu",
-	[ALC880_F1734]		= "F1734",
-	[ALC880_LG]		= "lg",
-#ifdef CONFIG_SND_DEBUG
-	[ALC880_TEST]		= "test",
-#endif
-	[ALC880_AUTO]		= "auto",
-};
-
-static const struct snd_pci_quirk alc880_cfg_tbl[] = {
-	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
-	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
-	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
-	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
-	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
-	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
-	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
-	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
-	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
-	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
-	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
-	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
-	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
-	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
-	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
-	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
-	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
-	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
-	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
-	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
-	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
-	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
-	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
-	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
-	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
-	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
-	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
-	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
-	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
-	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
-	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
-	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
-	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
-	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
-	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
-	/* default Intel */
-	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
-	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
-	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
-	{}
-};
-
-/*
- * ALC880 codec presets
- */
-static const struct alc_config_preset alc880_presets[] = {
-	[ALC880_3ST] = {
-		.mixers = { alc880_three_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_3stack_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-		.channel_mode = alc880_threestack_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_3ST_DIG] = {
-		.mixers = { alc880_three_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_3stack_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-		.channel_mode = alc880_threestack_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_TCL_S700] = {
-		.mixers = { alc880_tcl_s700_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_tcl_S700_init_verbs,
-				alc880_gpio2_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
-		.num_adc_nids = 1, /* single ADC */
-		.hp_nid = 0x03,
-		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-		.channel_mode = alc880_2_jack_modes,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_5ST] = {
-		.mixers = { alc880_three_stack_mixer,
-			    alc880_five_stack_mixer},
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_5stack_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
-		.channel_mode = alc880_fivestack_modes,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_5ST_DIG] = {
-		.mixers = { alc880_three_stack_mixer,
-			    alc880_five_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_5stack_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
-		.channel_mode = alc880_fivestack_modes,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_6ST] = {
-		.mixers = { alc880_six_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_6stack_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
-		.dac_nids = alc880_6st_dac_nids,
-		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
-		.channel_mode = alc880_sixstack_modes,
-		.input_mux = &alc880_6stack_capture_source,
-	},
-	[ALC880_6ST_DIG] = {
-		.mixers = { alc880_six_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_6stack_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
-		.dac_nids = alc880_6st_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
-		.channel_mode = alc880_sixstack_modes,
-		.input_mux = &alc880_6stack_capture_source,
-	},
-	[ALC880_W810] = {
-		.mixers = { alc880_w810_base_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_w810_init_verbs,
-				alc880_gpio2_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
-		.dac_nids = alc880_w810_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
-		.channel_mode = alc880_w810_modes,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_Z71V] = {
-		.mixers = { alc880_z71v_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_z71v_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
-		.dac_nids = alc880_z71v_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.hp_nid = 0x03,
-		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-		.channel_mode = alc880_2_jack_modes,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_F1734] = {
-		.mixers = { alc880_f1734_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_f1734_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
-		.dac_nids = alc880_f1734_dac_nids,
-		.hp_nid = 0x02,
-		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-		.channel_mode = alc880_2_jack_modes,
-		.input_mux = &alc880_f1734_capture_source,
-		.unsol_event = alc880_uniwill_p53_unsol_event,
-		.setup = alc880_uniwill_p53_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC880_ASUS] = {
-		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_asus_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-		.channel_mode = alc880_asus_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_ASUS_DIG] = {
-		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_asus_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-		.channel_mode = alc880_asus_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_ASUS_DIG2] = {
-		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_asus_init_verbs,
-				alc880_gpio2_init_verbs }, /* use GPIO2 */
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-		.channel_mode = alc880_asus_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_ASUS_W1V] = {
-		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_asus_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-		.channel_mode = alc880_asus_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_UNIWILL_DIG] = {
-		.mixers = { alc880_asus_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_asus_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
-		.channel_mode = alc880_asus_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_UNIWILL] = {
-		.mixers = { alc880_uniwill_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_uniwill_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-		.channel_mode = alc880_threestack_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-		.unsol_event = alc880_uniwill_unsol_event,
-		.setup = alc880_uniwill_setup,
-		.init_hook = alc880_uniwill_init_hook,
-	},
-	[ALC880_UNIWILL_P53] = {
-		.mixers = { alc880_uniwill_p53_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_uniwill_p53_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
-		.dac_nids = alc880_asus_dac_nids,
-		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
-		.channel_mode = alc880_threestack_modes,
-		.input_mux = &alc880_capture_source,
-		.unsol_event = alc880_uniwill_p53_unsol_event,
-		.setup = alc880_uniwill_p53_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC880_FUJITSU] = {
-		.mixers = { alc880_fujitsu_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_uniwill_p53_init_verbs,
-	       			alc880_beep_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
-		.channel_mode = alc880_2_jack_modes,
-		.input_mux = &alc880_capture_source,
-		.unsol_event = alc880_uniwill_p53_unsol_event,
-		.setup = alc880_uniwill_p53_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC880_CLEVO] = {
-		.mixers = { alc880_three_stack_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_pin_clevo_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
-		.dac_nids = alc880_dac_nids,
-		.hp_nid = 0x03,
-		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
-		.channel_mode = alc880_threestack_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_capture_source,
-	},
-	[ALC880_LG] = {
-		.mixers = { alc880_lg_mixer },
-		.init_verbs = { alc880_volume_init_verbs,
-				alc880_lg_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
-		.dac_nids = alc880_lg_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
-		.channel_mode = alc880_lg_ch_modes,
-		.need_dac_fix = 1,
-		.input_mux = &alc880_lg_capture_source,
-		.unsol_event = alc880_unsol_event,
-		.setup = alc880_lg_setup,
-		.init_hook = alc_hp_automute,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-		.loopbacks = alc880_lg_loopbacks,
-#endif
-	},
-#ifdef CONFIG_SND_DEBUG
-	[ALC880_TEST] = {
-		.mixers = { alc880_test_mixer },
-		.init_verbs = { alc880_test_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
-		.dac_nids = alc880_test_dac_nids,
-		.dig_out_nid = ALC880_DIGOUT_NID,
-		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
-		.channel_mode = alc880_test_modes,
-		.input_mux = &alc880_test_capture_source,
-	},
-#endif
-};
-
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
deleted file mode 100644
index bb364a5..0000000
--- a/sound/pci/hda/alc882_quirks.c
+++ /dev/null
@@ -1,866 +0,0 @@
-/*
- * ALC882/ALC883/ALC888/ALC889 quirk models
- * included by patch_realtek.c
- */
-
-/* ALC882 models */
-enum {
-	ALC882_AUTO,
-	ALC885_MBA21,
-	ALC885_MBP3,
-	ALC885_MB5,
-	ALC885_MACMINI3,
-	ALC885_IMAC91,
-	ALC889A_MB31,
-	ALC882_MODEL_LAST,
-};
-
-#define ALC882_DIGOUT_NID	0x06
-#define ALC882_DIGIN_NID	0x0a
-#define ALC883_DIGOUT_NID	ALC882_DIGOUT_NID
-#define ALC883_DIGIN_NID	ALC882_DIGIN_NID
-#define ALC1200_DIGOUT_NID	0x10
-
-
-static const struct hda_channel_mode alc882_ch_modes[1] = {
-	{ 8, NULL }
-};
-
-/* DACs */
-static const hda_nid_t alc882_dac_nids[4] = {
-	/* front, rear, clfe, rear_surr */
-	0x02, 0x03, 0x04, 0x05
-};
-#define alc883_dac_nids		alc882_dac_nids
-
-/* ADCs */
-#define alc882_adc_nids		alc880_adc_nids
-#define alc882_adc_nids_alt	alc880_adc_nids_alt
-#define alc883_adc_nids		alc882_adc_nids_alt
-
-static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
-#define alc883_capsrc_nids	alc882_capsrc_nids_alt
-
-/* input MUX */
-/* FIXME: should be a matrix-type input source selection */
-
-static const struct hda_input_mux alc882_capture_source = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Front Mic", 0x1 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
-
-#define alc883_capture_source	alc882_capture_source
-
-static const struct hda_input_mux mb5_capture_source = {
-	.num_items = 3,
-	.items = {
-		{ "Mic", 0x1 },
-		{ "Line", 0x7 },
-		{ "CD", 0x4 },
-	},
-};
-
-static const struct hda_input_mux macmini3_capture_source = {
-	.num_items = 2,
-	.items = {
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
-
-static const struct hda_input_mux alc883_3stack_6ch_intel = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x1 },
-		{ "Front Mic", 0x0 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
-
-static const struct hda_input_mux alc889A_mb31_capture_source = {
-	.num_items = 2,
-	.items = {
-		{ "Mic", 0x0 },
-		/* Front Mic (0x01) unused */
-		{ "Line", 0x2 },
-		/* Line 2 (0x03) unused */
-		/* CD (0x04) unused? */
-	},
-};
-
-static const struct hda_input_mux alc889A_imac91_capture_source = {
-	.num_items = 2,
-	.items = {
-		{ "Mic", 0x01 },
-		{ "Line", 0x2 }, /* Not sure! */
-	},
-};
-
-/* Macbook Air 2,1 */
-
-static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
-      { 2, NULL },
-};
-
-/*
- * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
- */
-
-/*
- * 2ch mode
- */
-static const struct hda_verb alc885_mbp_ch2_init[] = {
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
-	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{ } /* end */
-};
-
-/*
- * 4ch mode
- */
-static const struct hda_verb alc885_mbp_ch4_init[] = {
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
-	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{ } /* end */
-};
-
-static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
-	{ 2, alc885_mbp_ch2_init },
-	{ 4, alc885_mbp_ch4_init },
-};
-
-/*
- * 2ch
- * Speakers/Woofer/HP = Front
- * LineIn = Input
- */
-static const struct hda_verb alc885_mb5_ch2_init[] = {
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{ } /* end */
-};
-
-/*
- * 6ch mode
- * Speakers/HP = Front
- * Woofer = LFE
- * LineIn = Surround
- */
-static const struct hda_verb alc885_mb5_ch6_init[] = {
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-	{ } /* end */
-};
-
-static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
-	{ 2, alc885_mb5_ch2_init },
-	{ 6, alc885_mb5_ch6_init },
-};
-
-#define alc885_macmini3_6ch_modes	alc885_mb5_6ch_modes
-
-/* Macbook Air 2,1 same control for HP and internal Speaker */
-
-static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
-      HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-      HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
-     { }
-};
-
-
-static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
-	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
-	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
-	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
-	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
-	{ } /* end */
-};
-
-
-static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-static const struct hda_verb alc882_base_init_verbs[] = {
-	/* Front mixer: unmute input/output amp left and right (volume = 0) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Rear mixer */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* CLFE mixer */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Side mixer */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-
-	/* Front Pin: output 0 (0x0c) */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* Rear Pin: output 1 (0x0d) */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-	/* CLFE Pin: output 2 (0x0e) */
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* Side Pin: output 3 (0x0f) */
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
-	/* Mic (rear) pin: input vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Front Mic pin: input vref at 80% */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Line In pin: input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Line-2 In: Headphone output (output 0 - 0x0c) */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-
-	/* FIXME: use matrix-type input source selection */
-	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
-	/* Input mixer2 */
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	/* Input mixer3 */
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	/* ADC2: mute amp left and right */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* ADC3: mute amp left and right */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	{ }
-};
-
-#define alc883_init_verbs	alc882_base_init_verbs
-
-/* Macbook 5,1 */
-static const struct hda_verb alc885_mb5_init_verbs[] = {
-	/* DACs */
-	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Front mixer */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Surround mixer */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* LFE mixer */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* HP mixer */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Front Pin (0x0c) */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* LFE Pin (0x0e) */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* HP Pin (0x0f) */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-	/* Front Mic pin: input vref at 80% */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Line In pin */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
-	{ }
-};
-
-/* Macmini 3,1 */
-static const struct hda_verb alc885_macmini3_init_verbs[] = {
-	/* DACs */
-	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	/* Front mixer */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Surround mixer */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* LFE mixer */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* HP mixer */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Front Pin (0x0c) */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* LFE Pin (0x0e) */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* HP Pin (0x0f) */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-	/* Line In pin */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	{ }
-};
-
-
-static const struct hda_verb alc885_mba21_init_verbs[] = {
-	/*Internal and HP Speaker Mixer*/
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-	/*Internal Speaker Pin (0x0c)*/
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* HP Pin: output 0 (0x0e) */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
-	/* Line in (is hp when jack connected)*/
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-	{ }
- };
-
-
-/* Macbook Pro rev3 */
-static const struct hda_verb alc885_mbp3_init_verbs[] = {
-	/* Front mixer: unmute input/output amp left and right (volume = 0) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Rear mixer */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* HP mixer */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Front Pin: output 0 (0x0c) */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* HP Pin: output 0 (0x0e) */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
-	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-	/* Mic (rear) pin: input vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Front Mic pin: input vref at 80% */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Line In pin: use output 1 when in LineOut mode */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
-
-	/* FIXME: use matrix-type input source selection */
-	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
-	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* Input mixer2 */
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* Input mixer3 */
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* ADC1: mute amp left and right */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* ADC2: mute amp left and right */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* ADC3: mute amp left and right */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-
-	{ }
-};
-
-/* iMac 9,1 */
-static const struct hda_verb alc885_imac91_init_verbs[] = {
-	/* Internal Speaker Pin (0x0c) */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* HP Pin: Rear */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
-	/* Line in Rear */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Front Mic pin: input vref at 80% */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	/* Rear mixer */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	/* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
-	/* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
-	{ }
-};
-
-/* Toggle speaker-output according to the hp-jack state */
-static void alc885_imac24_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x14;
-	spec->autocfg.speaker_pins[0] = 0x18;
-	spec->autocfg.speaker_pins[1] = 0x1a;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-#define alc885_mb5_setup	alc885_imac24_setup
-#define alc885_macmini3_setup	alc885_imac24_setup
-
-/* Macbook Air 2,1 */
-static void alc885_mba21_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x14;
-	spec->autocfg.speaker_pins[0] = 0x18;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-
-
-static void alc885_mbp3_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x15;
-	spec->autocfg.speaker_pins[0] = 0x14;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-static void alc885_imac91_setup(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-
-	spec->autocfg.hp_pins[0] = 0x14;
-	spec->autocfg.speaker_pins[0] = 0x18;
-	spec->autocfg.speaker_pins[1] = 0x1a;
-	alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
-}
-
-/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
-static const struct hda_verb alc889A_mb31_ch2_init[] = {
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
-	{ } /* end */
-};
-
-/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
-static const struct hda_verb alc889A_mb31_ch4_init[] = {
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
-	{ } /* end */
-};
-
-/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
-static const struct hda_verb alc889A_mb31_ch5_init[] = {
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
-	{ } /* end */
-};
-
-/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
-static const struct hda_verb alc889A_mb31_ch6_init[] = {
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
-	{ } /* end */
-};
-
-static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
-	{ 2, alc889A_mb31_ch2_init },
-	{ 4, alc889A_mb31_ch4_init },
-	{ 5, alc889A_mb31_ch5_init },
-	{ 6, alc889A_mb31_ch6_init },
-};
-
-static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
-	/* Output mixers */
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
-		HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
-	/* Output switches */
-	HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
-	/* Boost mixers */
-	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
-	/* Input mixers */
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	{ } /* end */
-};
-
-static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc_ch_mode_info,
-		.get = alc_ch_mode_get,
-		.put = alc_ch_mode_put,
-	},
-	{ } /* end */
-};
-
-static const struct hda_verb alc889A_mb31_verbs[] = {
-	/* Init rear pin (used as headphone output) */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
-	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
-	/* Init line pin (used as output in 4ch and 6ch mode) */
-	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
-	/* Init line 2 pin (used as headphone out by default) */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
-	{ } /* end */
-};
-
-/* Mute speakers according to the headphone jack state */
-static void alc889A_mb31_automute(struct hda_codec *codec)
-{
-	unsigned int present;
-
-	/* Mute only in 2ch or 4ch mode */
-	if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
-	    == 0x00) {
-		present = snd_hda_jack_detect(codec, 0x15);
-		snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
-			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
-			HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
-	}
-}
-
-static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	if ((res >> 26) == ALC_HP_EVENT)
-		alc889A_mb31_automute(codec);
-}
-
-static void alc882_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	alc_exec_unsol_event(codec, res >> 26);
-}
-
-/*
- * configuration and preset
- */
-static const char * const alc882_models[ALC882_MODEL_LAST] = {
-	[ALC885_MB5]		= "mb5",
-	[ALC885_MACMINI3]	= "macmini3",
-	[ALC885_MBA21]		= "mba21",
-	[ALC885_MBP3]		= "mbp3",
-	[ALC885_IMAC91]		= "imac91",
-	[ALC889A_MB31]		= "mb31",
-	[ALC882_AUTO]		= "auto",
-};
-
-/* codec SSID table for Intel Mac */
-static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
-	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
-	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
-	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
-	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
-	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
-	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
-	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
-	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
-	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
-	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
-	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
-	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
-	/* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
-	 * so apparently no perfect solution yet
-	 */
-	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
-	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
-	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
-	{} /* terminator */
-};
-
-static const struct alc_config_preset alc882_presets[] = {
-	   [ALC885_MBA21] = {
-			.mixers = { alc885_mba21_mixer },
-			.init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
-			.num_dacs = 2,
-			.dac_nids = alc882_dac_nids,
-			.channel_mode = alc885_mba21_ch_modes,
-			.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
-			.input_mux = &alc882_capture_source,
-			.unsol_event = alc882_unsol_event,
-			.setup = alc885_mba21_setup,
-			.init_hook = alc_hp_automute,
-       },
-	[ALC885_MBP3] = {
-		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
-		.init_verbs = { alc885_mbp3_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = 2,
-		.dac_nids = alc882_dac_nids,
-		.hp_nid = 0x04,
-		.channel_mode = alc885_mbp_4ch_modes,
-		.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
-		.input_mux = &alc882_capture_source,
-		.dig_out_nid = ALC882_DIGOUT_NID,
-		.dig_in_nid = ALC882_DIGIN_NID,
-		.unsol_event = alc882_unsol_event,
-		.setup = alc885_mbp3_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC885_MB5] = {
-		.mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
-		.init_verbs = { alc885_mb5_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
-		.dac_nids = alc882_dac_nids,
-		.channel_mode = alc885_mb5_6ch_modes,
-		.num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
-		.input_mux = &mb5_capture_source,
-		.dig_out_nid = ALC882_DIGOUT_NID,
-		.dig_in_nid = ALC882_DIGIN_NID,
-		.unsol_event = alc882_unsol_event,
-		.setup = alc885_mb5_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC885_MACMINI3] = {
-		.mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
-		.init_verbs = { alc885_macmini3_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
-		.dac_nids = alc882_dac_nids,
-		.channel_mode = alc885_macmini3_6ch_modes,
-		.num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
-		.input_mux = &macmini3_capture_source,
-		.dig_out_nid = ALC882_DIGOUT_NID,
-		.dig_in_nid = ALC882_DIGIN_NID,
-		.unsol_event = alc882_unsol_event,
-		.setup = alc885_macmini3_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC885_IMAC91] = {
-		.mixers = {alc885_imac91_mixer},
-		.init_verbs = { alc885_imac91_init_verbs,
-				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
-		.dac_nids = alc882_dac_nids,
-		.channel_mode = alc885_mba21_ch_modes,
-		.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
-		.input_mux = &alc889A_imac91_capture_source,
-		.dig_out_nid = ALC882_DIGOUT_NID,
-		.dig_in_nid = ALC882_DIGIN_NID,
-		.unsol_event = alc882_unsol_event,
-		.setup = alc885_imac91_setup,
-		.init_hook = alc_hp_automute,
-	},
-	[ALC889A_MB31] = {
-		.mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
-		.init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
-			alc880_gpio1_init_verbs },
-		.adc_nids = alc883_adc_nids,
-		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
-		.capsrc_nids = alc883_capsrc_nids,
-		.dac_nids = alc883_dac_nids,
-		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
-		.channel_mode = alc889A_mb31_6ch_modes,
-		.num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
-		.input_mux = &alc889A_mb31_capture_source,
-		.dig_out_nid = ALC883_DIGOUT_NID,
-		.unsol_event = alc889A_mb31_unsol_event,
-		.init_hook = alc889A_mb31_automute,
-	},
-};
-
-
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
deleted file mode 100644
index a18952e..0000000
--- a/sound/pci/hda/alc_quirks.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Common codes for Realtek codec quirks
- * included by patch_realtek.c
- */
-
-/*
- * configuration template - to be copied to the spec instance
- */
-struct alc_config_preset {
-	const struct snd_kcontrol_new *mixers[5]; /* should be identical size
-					     * with spec
-					     */
-	const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
-	const struct hda_verb *init_verbs[5];
-	unsigned int num_dacs;
-	const hda_nid_t *dac_nids;
-	hda_nid_t dig_out_nid;		/* optional */
-	hda_nid_t hp_nid;		/* optional */
-	const hda_nid_t *slave_dig_outs;
-	unsigned int num_adc_nids;
-	const hda_nid_t *adc_nids;
-	const hda_nid_t *capsrc_nids;
-	hda_nid_t dig_in_nid;
-	unsigned int num_channel_mode;
-	const struct hda_channel_mode *channel_mode;
-	int need_dac_fix;
-	int const_channel_count;
-	unsigned int num_mux_defs;
-	const struct hda_input_mux *input_mux;
-	void (*unsol_event)(struct hda_codec *, unsigned int);
-	void (*setup)(struct hda_codec *);
-	void (*init_hook)(struct hda_codec *);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	const struct hda_amp_list *loopbacks;
-	void (*power_hook)(struct hda_codec *codec);
-#endif
-};
-
-/*
- * channel mode setting
- */
-static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
-			    struct snd_ctl_elem_info *uinfo)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
-				    spec->num_channel_mode);
-}
-
-static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
-			   struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
-				   spec->num_channel_mode,
-				   spec->ext_channel_count);
-}
-
-static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
-			   struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct alc_spec *spec = codec->spec;
-	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
-				      spec->num_channel_mode,
-				      &spec->ext_channel_count);
-	if (err >= 0 && !spec->const_channel_count) {
-		spec->multiout.max_channels = spec->ext_channel_count;
-		if (spec->need_dac_fix)
-			spec->multiout.num_dacs = spec->multiout.max_channels / 2;
-	}
-	return err;
-}
-
-/*
- * Control the mode of pin widget settings via the mixer.  "pc" is used
- * instead of "%" to avoid consequences of accidentally treating the % as
- * being part of a format specifier.  Maximum allowed length of a value is
- * 63 characters plus NULL terminator.
- *
- * Note: some retasking pin complexes seem to ignore requests for input
- * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
- * are requested.  Therefore order this list so that this behaviour will not
- * cause problems when mixer clients move through the enum sequentially.
- * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
- * March 2006.
- */
-static const char * const alc_pin_mode_names[] = {
-	"Mic 50pc bias", "Mic 80pc bias",
-	"Line in", "Line out", "Headphone out",
-};
-static const unsigned char alc_pin_mode_values[] = {
-	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
-};
-/* The control can present all 5 options, or it can limit the options based
- * in the pin being assumed to be exclusively an input or an output pin.  In
- * addition, "input" pins may or may not process the mic bias option
- * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
- * accept requests for bias as of chip versions up to March 2006) and/or
- * wiring in the computer.
- */
-#define ALC_PIN_DIR_IN              0x00
-#define ALC_PIN_DIR_OUT             0x01
-#define ALC_PIN_DIR_INOUT           0x02
-#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
-#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
-
-/* Info about the pin modes supported by the different pin direction modes.
- * For each direction the minimum and maximum values are given.
- */
-static const signed char alc_pin_mode_dir_info[5][2] = {
-	{ 0, 2 },    /* ALC_PIN_DIR_IN */
-	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
-	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
-	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
-	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
-};
-#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
-#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
-#define alc_pin_mode_n_items(_dir) \
-	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
-
-static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_info *uinfo)
-{
-	unsigned int item_num = uinfo->value.enumerated.item;
-	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
-
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
-
-	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
-		item_num = alc_pin_mode_min(dir);
-	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
-	return 0;
-}
-
-static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
-			    struct snd_ctl_elem_value *ucontrol)
-{
-	unsigned int i;
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
-	long *valp = ucontrol->value.integer.value;
-	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
-						 AC_VERB_GET_PIN_WIDGET_CONTROL,
-						 0x00);
-
-	/* Find enumerated value for current pinctl setting */
-	i = alc_pin_mode_min(dir);
-	while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
-		i++;
-	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
-	return 0;
-}
-
-static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
-			    struct snd_ctl_elem_value *ucontrol)
-{
-	signed int change;
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
-	long val = *ucontrol->value.integer.value;
-	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
-						 AC_VERB_GET_PIN_WIDGET_CONTROL,
-						 0x00);
-
-	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
-		val = alc_pin_mode_min(dir);
-
-	change = pinctl != alc_pin_mode_values[val];
-	if (change) {
-		/* Set pin mode to that requested */
-		snd_hda_codec_write_cache(codec, nid, 0,
-					  AC_VERB_SET_PIN_WIDGET_CONTROL,
-					  alc_pin_mode_values[val]);
-
-		/* Also enable the retasking pin's input/output as required
-		 * for the requested pin mode.  Enum values of 2 or less are
-		 * input modes.
-		 *
-		 * Dynamically switching the input/output buffers probably
-		 * reduces noise slightly (particularly on input) so we'll
-		 * do it.  However, having both input and output buffers
-		 * enabled simultaneously doesn't seem to be problematic if
-		 * this turns out to be necessary in the future.
-		 */
-		if (val <= 2) {
-			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-						 HDA_AMP_MUTE, HDA_AMP_MUTE);
-			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
-						 HDA_AMP_MUTE, 0);
-		} else {
-			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
-						 HDA_AMP_MUTE, HDA_AMP_MUTE);
-			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
-						 HDA_AMP_MUTE, 0);
-		}
-	}
-	return change;
-}
-
-#define ALC_PIN_MODE(xname, nid, dir) \
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-	  .info = alc_pin_mode_info, \
-	  .get = alc_pin_mode_get, \
-	  .put = alc_pin_mode_put, \
-	  .private_value = nid | (dir<<16) }
-
-/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
- * together using a mask with more than one bit set.  This control is
- * currently used only by the ALC260 test model.  At this stage they are not
- * needed for any "production" models.
- */
-#ifdef CONFIG_SND_DEBUG
-#define alc_gpio_data_info	snd_ctl_boolean_mono_info
-
-static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long *valp = ucontrol->value.integer.value;
-	unsigned int val = snd_hda_codec_read(codec, nid, 0,
-					      AC_VERB_GET_GPIO_DATA, 0x00);
-
-	*valp = (val & mask) != 0;
-	return 0;
-}
-static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_value *ucontrol)
-{
-	signed int change;
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long val = *ucontrol->value.integer.value;
-	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
-						    AC_VERB_GET_GPIO_DATA,
-						    0x00);
-
-	/* Set/unset the masked GPIO bit(s) as needed */
-	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
-	if (val == 0)
-		gpio_data &= ~mask;
-	else
-		gpio_data |= mask;
-	snd_hda_codec_write_cache(codec, nid, 0,
-				  AC_VERB_SET_GPIO_DATA, gpio_data);
-
-	return change;
-}
-#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-	  .info = alc_gpio_data_info, \
-	  .get = alc_gpio_data_get, \
-	  .put = alc_gpio_data_put, \
-	  .private_value = nid | (mask<<16) }
-#endif   /* CONFIG_SND_DEBUG */
-
-/* A switch control to allow the enabling of the digital IO pins on the
- * ALC260.  This is incredibly simplistic; the intention of this control is
- * to provide something in the test model allowing digital outputs to be
- * identified if present.  If models are found which can utilise these
- * outputs a more complete mixer control can be devised for those models if
- * necessary.
- */
-#ifdef CONFIG_SND_DEBUG
-#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
-
-static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long *valp = ucontrol->value.integer.value;
-	unsigned int val = snd_hda_codec_read(codec, nid, 0,
-					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
-
-	*valp = (val & mask) != 0;
-	return 0;
-}
-static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_value *ucontrol)
-{
-	signed int change;
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long val = *ucontrol->value.integer.value;
-	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
-						    AC_VERB_GET_DIGI_CONVERT_1,
-						    0x00);
-
-	/* Set/unset the masked control bit(s) as needed */
-	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
-	if (val==0)
-		ctrl_data &= ~mask;
-	else
-		ctrl_data |= mask;
-	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
-				  ctrl_data);
-
-	return change;
-}
-#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-	  .info = alc_spdif_ctrl_info, \
-	  .get = alc_spdif_ctrl_get, \
-	  .put = alc_spdif_ctrl_put, \
-	  .private_value = nid | (mask<<16) }
-#endif   /* CONFIG_SND_DEBUG */
-
-/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
- * Again, this is only used in the ALC26x test models to help identify when
- * the EAPD line must be asserted for features to work.
- */
-#ifdef CONFIG_SND_DEBUG
-#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
-
-static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long *valp = ucontrol->value.integer.value;
-	unsigned int val = snd_hda_codec_read(codec, nid, 0,
-					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
-
-	*valp = (val & mask) != 0;
-	return 0;
-}
-
-static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
-			      struct snd_ctl_elem_value *ucontrol)
-{
-	int change;
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	hda_nid_t nid = kcontrol->private_value & 0xffff;
-	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
-	long val = *ucontrol->value.integer.value;
-	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
-						    AC_VERB_GET_EAPD_BTLENABLE,
-						    0x00);
-
-	/* Set/unset the masked control bit(s) as needed */
-	change = (!val ? 0 : mask) != (ctrl_data & mask);
-	if (!val)
-		ctrl_data &= ~mask;
-	else
-		ctrl_data |= mask;
-	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
-				  ctrl_data);
-
-	return change;
-}
-
-#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
-	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
-	  .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
-	  .info = alc_eapd_ctrl_info, \
-	  .get = alc_eapd_ctrl_get, \
-	  .put = alc_eapd_ctrl_put, \
-	  .private_value = nid | (mask<<16) }
-#endif   /* CONFIG_SND_DEBUG */
-
-static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-	struct auto_pin_cfg *cfg = &spec->autocfg;
-
-	if (!cfg->line_outs) {
-		while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
-		       cfg->line_out_pins[cfg->line_outs])
-			cfg->line_outs++;
-	}
-	if (!cfg->speaker_outs) {
-		while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
-		       cfg->speaker_pins[cfg->speaker_outs])
-			cfg->speaker_outs++;
-	}
-	if (!cfg->hp_outs) {
-		while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
-		       cfg->hp_pins[cfg->hp_outs])
-			cfg->hp_outs++;
-	}
-}
-
-/*
- * set up from the preset table
- */
-static void setup_preset(struct hda_codec *codec,
-			 const struct alc_config_preset *preset)
-{
-	struct alc_spec *spec = codec->spec;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
-		add_mixer(spec, preset->mixers[i]);
-	spec->cap_mixer = preset->cap_mixer;
-	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
-	     i++)
-		add_verb(spec, preset->init_verbs[i]);
-
-	spec->channel_mode = preset->channel_mode;
-	spec->num_channel_mode = preset->num_channel_mode;
-	spec->need_dac_fix = preset->need_dac_fix;
-	spec->const_channel_count = preset->const_channel_count;
-
-	if (preset->const_channel_count)
-		spec->multiout.max_channels = preset->const_channel_count;
-	else
-		spec->multiout.max_channels = spec->channel_mode[0].channels;
-	spec->ext_channel_count = spec->channel_mode[0].channels;
-
-	spec->multiout.num_dacs = preset->num_dacs;
-	spec->multiout.dac_nids = preset->dac_nids;
-	spec->multiout.dig_out_nid = preset->dig_out_nid;
-	spec->multiout.slave_dig_outs = preset->slave_dig_outs;
-	spec->multiout.hp_nid = preset->hp_nid;
-
-	spec->num_mux_defs = preset->num_mux_defs;
-	if (!spec->num_mux_defs)
-		spec->num_mux_defs = 1;
-	spec->input_mux = preset->input_mux;
-
-	spec->num_adc_nids = preset->num_adc_nids;
-	spec->adc_nids = preset->adc_nids;
-	spec->capsrc_nids = preset->capsrc_nids;
-	spec->dig_in_nid = preset->dig_in_nid;
-
-	spec->unsol_event = preset->unsol_event;
-	spec->init_hook = preset->init_hook;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	spec->power_hook = preset->power_hook;
-	spec->loopback.amplist = preset->loopbacks;
-#endif
-
-	if (preset->setup)
-		preset->setup(codec);
-
-	alc_fixup_autocfg_pin_nums(codec);
-}
-
-static void alc_simple_setup_automute(struct alc_spec *spec, int mode)
-{
-	int lo_pin = spec->autocfg.line_out_pins[0];
-
-	if (lo_pin == spec->autocfg.speaker_pins[0] ||
-		lo_pin == spec->autocfg.hp_pins[0])
-		lo_pin = 0;
-	spec->automute_mode = mode;
-	spec->detect_hp = !!spec->autocfg.hp_pins[0];
-	spec->detect_lo = !!lo_pin;
-	spec->automute_lo = spec->automute_lo_possible = !!lo_pin;
-	spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0];
-}
-
-/* auto-toggle front mic */
-static void alc88x_simple_mic_automute(struct hda_codec *codec)
-{
- 	unsigned int present;
-	unsigned char bits;
-
-	present = snd_hda_jack_detect(codec, 0x18);
-	bits = present ? HDA_AMP_MUTE : 0;
-	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
-}
-
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c2c65f6..65c0179 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2300,7 +2300,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
 
 /* apply the function to all matching slave ctls in the mixer list */
 static int map_slaves(struct hda_codec *codec, const char * const *slaves,
-		      map_slave_func_t func, void *data) 
+		      const char *suffix, map_slave_func_t func, void *data) 
 {
 	struct hda_nid_item *items;
 	const char * const *s;
@@ -2313,7 +2313,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
 		    sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
 			continue;
 		for (s = slaves; *s; s++) {
-			if (!strcmp(sctl->id.name, *s)) {
+			char tmpname[sizeof(sctl->id.name)];
+			const char *name = *s;
+			if (suffix) {
+				snprintf(tmpname, sizeof(tmpname), "%s %s",
+					 name, suffix);
+				name = tmpname;
+			}
+			if (!strcmp(sctl->id.name, name)) {
 				err = func(data, sctl);
 				if (err)
 					return err;
@@ -2335,6 +2342,7 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
  * @name: vmaster control name
  * @tlv: TLV data (optional)
  * @slaves: slave control names (optional)
+ * @suffix: suffix string to each slave name (optional)
  *
  * Create a virtual master control with the given name.  The TLV data
  * must be either NULL or a valid data.
@@ -2346,12 +2354,13 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
  * This function returns zero if successful or a negative error code.
  */
 int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
-			unsigned int *tlv, const char * const *slaves)
+			unsigned int *tlv, const char * const *slaves,
+			const char *suffix)
 {
 	struct snd_kcontrol *kctl;
 	int err;
 
-	err = map_slaves(codec, slaves, check_slave_present, NULL);
+	err = map_slaves(codec, slaves, suffix, check_slave_present, NULL);
 	if (err != 1) {
 		snd_printdd("No slave found for %s\n", name);
 		return 0;
@@ -2363,8 +2372,8 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
 	if (err < 0)
 		return err;
 
-	err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave,
-			 kctl);
+	err = map_slaves(codec, slaves, suffix,
+			 (map_slave_func_t)snd_ctl_add_slave, kctl);
 	if (err < 0)
 		return err;
 	return 0;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e9f71dc..654d2e4 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -852,6 +852,7 @@ struct hda_codec {
 	unsigned int pins_shutup:1;	/* pins are shut up */
 	unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
 	unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
+	unsigned int no_jack_detect:1;	/* Machine has no jack-detection */
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	unsigned int power_on :1;	/* current (global) power-state */
 	unsigned int power_transition :1; /* power-state in transition */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 95dfb68..e354c16 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
 		 "(for debugging only).");
-module_param(enable_msi, int, 0444);
+module_param(enable_msi, bint, 0444);
 MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 module_param_array(patch, charp, NULL, 0444);
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644);
 MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
 #endif
 
-static bool align_buffer_size = 1;
-module_param(align_buffer_size, bool, 0644);
+static int align_buffer_size = -1;
+module_param(align_buffer_size, bint, 0644);
 MODULE_PARM_DESC(align_buffer_size,
 		"Force buffer and period sizes to be multiple of 128 bytes.");
 
@@ -148,6 +148,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
 			 "{Intel, PCH},"
 			 "{Intel, CPT},"
 			 "{Intel, PPT},"
+			 "{Intel, LPT},"
 			 "{Intel, PBG},"
 			 "{Intel, SCH},"
 			 "{ATI, SB450},"
@@ -515,6 +516,7 @@ enum {
 #define AZX_DCAPS_SYNC_WRITE	(1 << 19)	/* sync each cmd write */
 #define AZX_DCAPS_OLD_SSYNC	(1 << 20)	/* Old SSYNC reg for ICH */
 #define AZX_DCAPS_BUFSIZE	(1 << 21)	/* no buffer size alignment */
+#define AZX_DCAPS_ALIGN_BUFSIZE	(1 << 22)	/* buffer size alignment */
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -527,7 +529,8 @@ enum {
 
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
-	(AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI)
+	(AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
+	 AZX_DCAPS_ALIGN_BUFSIZE)
 
 static char *driver_short_names[] __devinitdata = {
 	[AZX_DRIVER_ICH] = "HDA Intel",
@@ -2774,9 +2777,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 	}
 
 	/* disable buffer size rounding to 128-byte multiples if supported */
-	chip->align_buffer_size = align_buffer_size;
-	if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
-		chip->align_buffer_size = 0;
+	if (align_buffer_size >= 0)
+		chip->align_buffer_size = !!align_buffer_size;
+	else {
+		if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
+			chip->align_buffer_size = 0;
+		else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
+			chip->align_buffer_size = 1;
+		else
+			chip->align_buffer_size = 1;
+	}
 
 	/* allow 64bit DMA address if supported by H/W */
 	if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2992,6 +3002,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
 	{ PCI_DEVICE(0x8086, 0x1e20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 	  AZX_DCAPS_BUFSIZE},
+	/* Lynx Point */
+	{ PCI_DEVICE(0x8086, 0x8c20),
+	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
+	  AZX_DCAPS_BUFSIZE},
 	/* SCH */
 	{ PCI_DEVICE(0x8086, 0x811b),
 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9d819c4..d689484 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -19,6 +19,22 @@
 #include "hda_local.h"
 #include "hda_jack.h"
 
+bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
+{
+	if (codec->no_jack_detect)
+		return false;
+	if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
+		return false;
+	if (!codec->ignore_misc_bit &&
+	    (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+	     AC_DEFCFG_MISC_NO_PRESENCE))
+		return false;
+	if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
+		return false;
+	return true;
+}
+EXPORT_SYMBOL_HDA(is_jack_detectable);
+
 /* execute pin sense measurement */
 static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
 {
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index f8f97c7..c66655c 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -62,18 +62,7 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
 
-static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
-{
-	if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
-		return false;
-	if (!codec->ignore_misc_bit &&
-	    (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
-	     AC_DEFCFG_MISC_NO_PRESENCE))
-		return false;
-	if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
-		return false;
-	return true;
-}
+bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
 
 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 			  const char *name, int idx);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index aca8d31..6094dea8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -140,7 +140,8 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
 struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
 					    const char *name);
 int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
-			unsigned int *tlv, const char * const *slaves);
+			unsigned int *tlv, const char * const *slaves,
+			const char *suffix);
 int snd_hda_codec_reset(struct hda_codec *codec);
 
 /* amp value bits */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 9cb14b4..9771b07 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -137,51 +137,17 @@ static int ad198x_init(struct hda_codec *codec)
 	return 0;
 }
 
-static const char * const ad_slave_vols[] = {
-	"Front Playback Volume",
-	"Surround Playback Volume",
-	"Center Playback Volume",
-	"LFE Playback Volume",
-	"Side Playback Volume",
-	"Headphone Playback Volume",
-	"Mono Playback Volume",
-	"Speaker Playback Volume",
-	"IEC958 Playback Volume",
+static const char * const ad_slave_pfxs[] = {
+	"Front", "Surround", "Center", "LFE", "Side",
+	"Headphone", "Mono", "Speaker", "IEC958",
 	NULL
 };
 
-static const char * const ad_slave_sws[] = {
-	"Front Playback Switch",
-	"Surround Playback Switch",
-	"Center Playback Switch",
-	"LFE Playback Switch",
-	"Side Playback Switch",
-	"Headphone Playback Switch",
-	"Mono Playback Switch",
-	"Speaker Playback Switch",
-	"IEC958 Playback Switch",
+static const char * const ad1988_6stack_fp_slave_pfxs[] = {
+	"Front", "Surround", "Center", "LFE", "Side", "IEC958",
 	NULL
 };
 
-static const char * const ad1988_6stack_fp_slave_vols[] = {
-	"Front Playback Volume",
-	"Surround Playback Volume",
-	"Center Playback Volume",
-	"LFE Playback Volume",
-	"Side Playback Volume",
-	"IEC958 Playback Volume",
-	NULL
-};
-
-static const char * const ad1988_6stack_fp_slave_sws[] = {
-	"Front Playback Switch",
-	"Surround Playback Switch",
-	"Center Playback Switch",
-	"LFE Playback Switch",
-	"Side Playback Switch",
-	"IEC958 Playback Switch",
-	NULL
-};
 static void ad198x_free_kctls(struct hda_codec *codec);
 
 #ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -260,7 +226,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
 					  vmaster_tlv,
 					  (spec->slave_vols ?
-					   spec->slave_vols : ad_slave_vols));
+					   spec->slave_vols : ad_slave_pfxs),
+					  "Playback Volume");
 		if (err < 0)
 			return err;
 	}
@@ -268,7 +235,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
 					  NULL,
 					  (spec->slave_sws ?
-					   spec->slave_sws : ad_slave_sws));
+					   spec->slave_sws : ad_slave_pfxs),
+					  "Playback Switch");
 		if (err < 0)
 			return err;
 	}
@@ -3385,8 +3353,8 @@ static int patch_ad1988(struct hda_codec *codec)
 
 	if (spec->autocfg.hp_pins[0]) {
 		spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
-		spec->slave_vols = ad1988_6stack_fp_slave_vols;
-		spec->slave_sws = ad1988_6stack_fp_slave_sws;
+		spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
+		spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
 		spec->alt_dac_nid = ad1988_alt_dac_nid;
 		spec->stream_analog_alt_playback =
 			&ad198x_pcm_analog_alt_playback;
@@ -3594,16 +3562,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = {
 #endif
 
 static const char * const ad1884_slave_vols[] = {
-	"PCM Playback Volume",
-	"Mic Playback Volume",
-	"Mono Playback Volume",
-	"Front Mic Playback Volume",
-	"Mic Playback Volume",
-	"CD Playback Volume",
-	"Internal Mic Playback Volume",
-	"Docking Mic Playback Volume",
-	/* "Beep Playback Volume", */
-	"IEC958 Playback Volume",
+	"PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
+	"Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
 	NULL
 };
 
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a7a5733..cc84e34 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -465,21 +465,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = {
 };
 #endif
 
-static const char * const slave_vols[] = {
-	"Headphone Playback Volume",
-	"Speaker Playback Volume",
-	"Front Playback Volume",
-	"Surround Playback Volume",
-	"CLFE Playback Volume",
-	NULL
-};
-
-static const char * const slave_sws[] = {
-	"Headphone Playback Switch",
-	"Speaker Playback Switch",
-	"Front Playback Switch",
-	"Surround Playback Switch",
-	"CLFE Playback Switch",
+static const char * const slave_pfxs[] = {
+	"Headphone", "Speaker", "Front", "Surround", "CLFE",
 	NULL
 };
 
@@ -519,14 +506,16 @@ static int conexant_build_controls(struct hda_codec *codec)
 		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
 					HDA_OUTPUT, vmaster_tlv);
 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-					  vmaster_tlv, slave_vols);
+					  vmaster_tlv, slave_pfxs,
+					  "Playback Volume");
 		if (err < 0)
 			return err;
 	}
 	if (spec->vmaster_nid &&
 	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-					  NULL, slave_sws);
+					  NULL, slave_pfxs,
+					  "Playback Switch");
 		if (err < 0)
 			return err;
 	}
@@ -1643,7 +1632,7 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
 	pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
 	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 			    pinctl);
-	/* on ideapad there is an aditional speaker (subwoofer) to mute */
+	/* on ideapad there is an additional speaker (subwoofer) to mute */
 	if (spec->ideapad)
 		snd_hda_codec_write(codec, 0x1b, 0,
 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
@@ -3034,7 +3023,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
 	SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
-	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
 	SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
 	{}
 };
@@ -4414,6 +4402,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
 	codec->patch_ops = cx_auto_patch_ops;
 	if (spec->beep_amp)
 		snd_hda_attach_beep_device(codec, spec->beep_amp);
+
+	/* Some laptops with Conexant chips show stalls in S3 resume,
+	 * which falls into the single-cmd mode.
+	 * Better to make reset, then.
+	 */
+	if (!codec->bus->sync_write) {
+		snd_printd("hda_codec: "
+			   "Enable sync_write for stable communication\n");
+		codec->bus->sync_write = 1;
+		codec->bus->allow_bus_reset = 1;
+	}
+
 	return 0;
 }
 
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1358987..19f85b7 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -80,6 +80,8 @@ enum {
 	ALC_AUTOMUTE_MIXER,	/* mute/unmute mixer widget AMP */
 };
 
+#define MAX_VOL_NIDS	0x40
+
 struct alc_spec {
 	/* codec parameterization */
 	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
@@ -118,8 +120,8 @@ struct alc_spec {
 	const hda_nid_t *capsrc_nids;
 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
 	hda_nid_t mixer_nid;		/* analog-mixer NID */
-	DECLARE_BITMAP(vol_ctls, 0x20 << 1);
-	DECLARE_BITMAP(sw_ctls, 0x20 << 1);
+	DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
+	DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
 
 	/* capture setup for dynamic dual-adc switch */
 	hda_nid_t cur_adc;
@@ -198,6 +200,8 @@ struct alc_spec {
 	hda_nid_t vmaster_nid;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	struct hda_loopback_check loopback;
+	int num_loopbacks;
+	struct hda_amp_list loopback_list[8];
 #endif
 
 	/* for PLL fix */
@@ -218,8 +222,6 @@ struct alc_spec {
 	struct snd_array bind_ctls;
 };
 
-#define ALC_MODEL_AUTO		0	/* common for all chips */
-
 static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
 			   int dir, unsigned int bits)
 {
@@ -298,6 +300,9 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
 	int i, type, num_conns;
 	hda_nid_t nid;
 
+	if (!spec->input_mux)
+		return 0;
+
 	mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
 	imux = &spec->input_mux[mux_idx];
 	if (!imux->num_items && mux_idx > 0)
@@ -649,15 +654,51 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action)
 	snd_hda_jack_report_sync(codec);
 }
 
+/* update the master volume per volume-knob's unsol event */
+static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
+{
+	unsigned int val;
+	struct snd_kcontrol *kctl;
+	struct snd_ctl_elem_value *uctl;
+
+	kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
+	if (!kctl)
+		return;
+	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
+	if (!uctl)
+		return;
+	val = snd_hda_codec_read(codec, nid, 0,
+				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
+	val &= HDA_AMP_VOLMASK;
+	uctl->value.integer.value[0] = val;
+	uctl->value.integer.value[1] = val;
+	kctl->put(kctl, uctl);
+	kfree(uctl);
+}
+
 /* unsolicited event for HP jack sensing */
 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
 {
+	int action;
+
 	if (codec->vendor_id == 0x10ec0880)
 		res >>= 28;
 	else
 		res >>= 26;
-	res = snd_hda_jack_get_action(codec, res);
-	alc_exec_unsol_event(codec, res);
+	action = snd_hda_jack_get_action(codec, res);
+	if (res == ALC_DCVOL_EVENT) {
+		/* Execute the dc-vol event here as it requires the NID
+		 * but we don't pass NID to alc_exec_unsol_event().
+		 * Once when we convert all static quirks to the auto-parser,
+		 * this can be integerated into there.
+		 */
+		struct hda_jack_tbl *jack;
+		jack = snd_hda_jack_tbl_get_from_tag(codec, res);
+		if (jack)
+			alc_update_knob_master(codec, jack->nid);
+		return;
+	}
+	alc_exec_unsol_event(codec, action);
 }
 
 /* call init functions of standard auto-mute helpers */
@@ -1031,45 +1072,6 @@ static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
 	return true;
 }
 
-/* rebuild imux for matching with the given auto-mic pins (if not yet) */
-static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
-{
-	struct alc_spec *spec = codec->spec;
-	struct hda_input_mux *imux;
-	static char * const texts[3] = {
-		"Mic", "Internal Mic", "Dock Mic"
-	};
-	int i;
-
-	if (!spec->auto_mic)
-		return false;
-	imux = &spec->private_imux[0];
-	if (spec->input_mux == imux)
-		return true;
-	spec->imux_pins[0] = spec->ext_mic_pin;
-	spec->imux_pins[1] = spec->int_mic_pin;
-	spec->imux_pins[2] = spec->dock_mic_pin;
-	for (i = 0; i < 3; i++) {
-		strcpy(imux->items[i].label, texts[i]);
-		if (spec->imux_pins[i]) {
-			hda_nid_t pin = spec->imux_pins[i];
-			int c;
-			for (c = 0; c < spec->num_adc_nids; c++) {
-				hda_nid_t cap = get_capsrc(spec, c);
-				int idx = get_connection_index(codec, cap, pin);
-				if (idx >= 0) {
-					imux->items[i].index = idx;
-					break;
-				}
-			}
-			imux->num_items = i + 1;
-		}
-	}
-	spec->num_mux_defs = 1;
-	spec->input_mux = imux;
-	return true;
-}
-
 /* check whether all auto-mic pins are valid; setup indices if OK */
 static bool alc_auto_mic_check_imux(struct hda_codec *codec)
 {
@@ -1518,6 +1520,13 @@ static void alc_pick_fixup(struct hda_codec *codec,
 	int id = -1;
 	const char *name = NULL;
 
+	/* when model=nofixup is given, don't pick up any fixups */
+	if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
+		spec->fixup_list = NULL;
+		spec->fixup_id = -1;
+		return;
+	}
+
 	if (codec->modelname && models) {
 		while (models->name) {
 			if (!strcmp(codec->modelname, models->name)) {
@@ -1845,36 +1854,10 @@ DEFINE_CAPMIX_NOSRC(3);
 /*
  * slave controls for virtual master
  */
-static const char * const alc_slave_vols[] = {
-	"Front Playback Volume",
-	"Surround Playback Volume",
-	"Center Playback Volume",
-	"LFE Playback Volume",
-	"Side Playback Volume",
-	"Headphone Playback Volume",
-	"Speaker Playback Volume",
-	"Mono Playback Volume",
-	"Line-Out Playback Volume",
-	"CLFE Playback Volume",
-	"Bass Speaker Playback Volume",
-	"PCM Playback Volume",
-	NULL,
-};
-
-static const char * const alc_slave_sws[] = {
-	"Front Playback Switch",
-	"Surround Playback Switch",
-	"Center Playback Switch",
-	"LFE Playback Switch",
-	"Side Playback Switch",
-	"Headphone Playback Switch",
-	"Speaker Playback Switch",
-	"Mono Playback Switch",
-	"IEC958 Playback Switch",
-	"Line-Out Playback Switch",
-	"CLFE Playback Switch",
-	"Bass Speaker Playback Switch",
-	"PCM Playback Switch",
+static const char * const alc_slave_pfxs[] = {
+	"Front", "Surround", "Center", "LFE", "Side",
+	"Headphone", "Speaker", "Mono", "Line-Out",
+	"CLFE", "Bass Speaker", "PCM",
 	NULL,
 };
 
@@ -1965,14 +1948,16 @@ static int __alc_build_controls(struct hda_codec *codec)
 		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
 					HDA_OUTPUT, vmaster_tlv);
 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-					  vmaster_tlv, alc_slave_vols);
+					  vmaster_tlv, alc_slave_pfxs,
+					  "Playback Volume");
 		if (err < 0)
 			return err;
 	}
 	if (!spec->no_analog &&
 	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-					  NULL, alc_slave_sws);
+					  NULL, alc_slave_pfxs,
+					  "Playback Switch");
 		if (err < 0)
 			return err;
 	}
@@ -2066,6 +2051,7 @@ static int alc_build_controls(struct hda_codec *codec)
  */
 
 static void alc_init_special_input_src(struct hda_codec *codec);
+static void alc_auto_init_std(struct hda_codec *codec);
 
 static int alc_init(struct hda_codec *codec)
 {
@@ -2078,6 +2064,7 @@ static int alc_init(struct hda_codec *codec)
 	for (i = 0; i < spec->num_init_verbs; i++)
 		snd_hda_sequence_write(codec, spec->init_verbs[i]);
 	alc_init_special_input_src(codec);
+	alc_auto_init_std(codec);
 
 	if (spec->init_hook)
 		spec->init_hook(codec);
@@ -2669,6 +2656,25 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
 	return channel_name[ch];
 }
 
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+/* add the powersave loopback-list entry */
+static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
+{
+	struct hda_amp_list *list;
+
+	if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
+		return;
+	list = spec->loopback_list + spec->num_loopbacks;
+	list->nid = mix;
+	list->dir = HDA_INPUT;
+	list->idx = idx;
+	spec->num_loopbacks++;
+	spec->loopback.amplist = spec->loopback_list;
+}
+#else
+#define add_loopback_list(spec, mix, idx) /* NOP */
+#endif
+
 /* create input playback/capture controls for the given pin */
 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
 			    const char *ctlname, int ctlidx,
@@ -2684,6 +2690,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
 			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 	if (err < 0)
 		return err;
+	add_loopback_list(spec, mix_nid, idx);
 	return 0;
 }
 
@@ -2948,10 +2955,27 @@ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
 	return 0;
 }
 
+static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+	if (found_in_nid_list(nid, spec->multiout.dac_nids,
+			      ARRAY_SIZE(spec->private_dac_nids)) ||
+	    found_in_nid_list(nid, spec->multiout.hp_out_nid,
+			      ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
+	    found_in_nid_list(nid, spec->multiout.extra_out_nid,
+			      ARRAY_SIZE(spec->multiout.extra_out_nid)))
+		return true;
+	for (i = 0; i < spec->multi_ios; i++) {
+		if (spec->multi_io[i].dac == nid)
+			return true;
+	}
+	return false;
+}
+
 /* look for an empty DAC slot */
 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
 {
-	struct alc_spec *spec = codec->spec;
 	hda_nid_t srcs[5];
 	int i, num;
 
@@ -2961,16 +2985,8 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
 		hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
 		if (!nid)
 			continue;
-		if (found_in_nid_list(nid, spec->multiout.dac_nids,
-				      ARRAY_SIZE(spec->private_dac_nids)))
-			continue;
-		if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
-				      ARRAY_SIZE(spec->multiout.hp_out_nid)))
-		    continue;
-		if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
-				      ARRAY_SIZE(spec->multiout.extra_out_nid)))
-		    continue;
-		return nid;
+		if (!alc_is_dac_already_used(codec, nid))
+			return nid;
 	}
 	return 0;
 }
@@ -2982,6 +2998,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
 	hda_nid_t srcs[5];
 	int i, num;
 
+	if (!pin || !dac)
+		return false;
 	pin = alc_go_down_to_selector(codec, pin);
 	num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
 	for (i = 0; i < num; i++) {
@@ -2994,83 +3012,260 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
 
 static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
 {
+	struct alc_spec *spec = codec->spec;
 	hda_nid_t sel = alc_go_down_to_selector(codec, pin);
-	if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
+	hda_nid_t nid, nid_found, srcs[5];
+	int i, num = snd_hda_get_connections(codec, sel, srcs,
+					  ARRAY_SIZE(srcs));
+	if (num == 1)
 		return alc_auto_look_for_dac(codec, pin);
-	return 0;
+	nid_found = 0;
+	for (i = 0; i < num; i++) {
+		if (srcs[i] == spec->mixer_nid)
+			continue;
+		nid = alc_auto_mix_to_dac(codec, srcs[i]);
+		if (nid && !alc_is_dac_already_used(codec, nid)) {
+			if (nid_found)
+				return 0;
+			nid_found = nid;
+		}
+	}
+	return nid_found;
 }
 
-/* return 0 if no possible DAC is found, 1 if one or more found */
-static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs,
-				    const hda_nid_t *pins, hda_nid_t *dacs)
+/* mark up volume and mute control NIDs: used during badness parsing and
+ * at creating actual controls
+ */
+static inline unsigned int get_ctl_pos(unsigned int data)
 {
-	int i;
+	hda_nid_t nid = get_amp_nid_(data);
+	unsigned int dir;
+	if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
+		return 0;
+	dir = get_amp_direction_(data);
+	return (nid << 1) | dir;
+}
 
-	if (num_outs && !dacs[0]) {
-		dacs[0] = alc_auto_look_for_dac(codec, pins[0]);
-		if (!dacs[0])
-			return 0;
-	}
+#define is_ctl_used(bits, data) \
+	test_bit(get_ctl_pos(data), bits)
+#define mark_ctl_usage(bits, data) \
+	set_bit(get_ctl_pos(data), bits)
 
-	for (i = 1; i < num_outs; i++)
-		dacs[i] = get_dac_if_single(codec, pins[i]);
-	for (i = 1; i < num_outs; i++) {
+static void clear_vol_marks(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
+	memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
+}
+
+/* badness definition */
+enum {
+	/* No primary DAC is found for the main output */
+	BAD_NO_PRIMARY_DAC = 0x10000,
+	/* No DAC is found for the extra output */
+	BAD_NO_DAC = 0x4000,
+	/* No possible multi-ios */
+	BAD_MULTI_IO = 0x103,
+	/* No individual DAC for extra output */
+	BAD_NO_EXTRA_DAC = 0x102,
+	/* No individual DAC for extra surrounds */
+	BAD_NO_EXTRA_SURR_DAC = 0x101,
+	/* Primary DAC shared with main surrounds */
+	BAD_SHARED_SURROUND = 0x100,
+	/* Primary DAC shared with main CLFE */
+	BAD_SHARED_CLFE = 0x10,
+	/* Primary DAC shared with extra surrounds */
+	BAD_SHARED_EXTRA_SURROUND = 0x10,
+	/* Volume widget is shared */
+	BAD_SHARED_VOL = 0x10,
+};
+
+static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
+					   hda_nid_t pin, hda_nid_t dac);
+static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
+					  hda_nid_t pin, hda_nid_t dac);
+
+static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
+				   hda_nid_t dac)
+{
+	struct alc_spec *spec = codec->spec;
+	hda_nid_t nid;
+	unsigned int val;
+	int badness = 0;
+
+	nid = alc_look_for_out_vol_nid(codec, pin, dac);
+	if (nid) {
+		val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+		if (is_ctl_used(spec->vol_ctls, nid))
+			badness += BAD_SHARED_VOL;
+		else
+			mark_ctl_usage(spec->vol_ctls, val);
+	} else
+		badness += BAD_SHARED_VOL;
+	nid = alc_look_for_out_mute_nid(codec, pin, dac);
+	if (nid) {
+		unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
+		if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
+			val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+		else
+			val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
+		if (is_ctl_used(spec->sw_ctls, val))
+			badness += BAD_SHARED_VOL;
+		else
+			mark_ctl_usage(spec->sw_ctls, val);
+	} else
+		badness += BAD_SHARED_VOL;
+	return badness;
+}
+
+struct badness_table {
+	int no_primary_dac;	/* no primary DAC */
+	int no_dac;		/* no secondary DACs */
+	int shared_primary;	/* primary DAC is shared with main output */
+	int shared_surr;	/* secondary DAC shared with main or primary */
+	int shared_clfe;	/* third DAC shared with main or primary */
+	int shared_surr_main;	/* secondary DAC sahred with main/DAC0 */
+};
+
+static struct badness_table main_out_badness = {
+	.no_primary_dac = BAD_NO_PRIMARY_DAC,
+	.no_dac = BAD_NO_DAC,
+	.shared_primary = BAD_NO_PRIMARY_DAC,
+	.shared_surr = BAD_SHARED_SURROUND,
+	.shared_clfe = BAD_SHARED_CLFE,
+	.shared_surr_main = BAD_SHARED_SURROUND,
+};
+
+static struct badness_table extra_out_badness = {
+	.no_primary_dac = BAD_NO_DAC,
+	.no_dac = BAD_NO_DAC,
+	.shared_primary = BAD_NO_EXTRA_DAC,
+	.shared_surr = BAD_SHARED_EXTRA_SURROUND,
+	.shared_clfe = BAD_SHARED_EXTRA_SURROUND,
+	.shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
+};
+
+/* try to assign DACs to pins and return the resultant badness */
+static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
+			      const hda_nid_t *pins, hda_nid_t *dacs,
+			      const struct badness_table *bad)
+{
+	struct alc_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	int i, j;
+	int badness = 0;
+	hda_nid_t dac;
+
+	if (!num_outs)
+		return 0;
+
+	for (i = 0; i < num_outs; i++) {
+		hda_nid_t pin = pins[i];
 		if (!dacs[i])
-			dacs[i] = alc_auto_look_for_dac(codec, pins[i]);
+			dacs[i] = alc_auto_look_for_dac(codec, pin);
+		if (!dacs[i] && !i) {
+			for (j = 1; j < num_outs; j++) {
+				if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
+					dacs[0] = dacs[j];
+					dacs[j] = 0;
+					break;
+				}
+			}
+		}
+		dac = dacs[i];
+		if (!dac) {
+			if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
+				dac = dacs[0];
+			else if (cfg->line_outs > i &&
+				 alc_auto_is_dac_reachable(codec, pin,
+					spec->private_dac_nids[i]))
+				dac = spec->private_dac_nids[i];
+			if (dac) {
+				if (!i)
+					badness += bad->shared_primary;
+				else if (i == 1)
+					badness += bad->shared_surr;
+				else
+					badness += bad->shared_clfe;
+			} else if (alc_auto_is_dac_reachable(codec, pin,
+					spec->private_dac_nids[0])) {
+				dac = spec->private_dac_nids[0];
+				badness += bad->shared_surr_main;
+			} else if (!i)
+				badness += bad->no_primary_dac;
+			else
+				badness += bad->no_dac;
+		}
+		if (dac)
+			badness += eval_shared_vol_badness(codec, pin, dac);
 	}
-	return 1;
+
+	return badness;
 }
 
 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
-				   unsigned int location, int offset);
-static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
-					  hda_nid_t pin, hda_nid_t dac);
+				   hda_nid_t reference_pin,
+				   bool hardwired, int offset);
+
+static bool alc_map_singles(struct hda_codec *codec, int outs,
+			    const hda_nid_t *pins, hda_nid_t *dacs)
+{
+	int i;
+	bool found = false;
+	for (i = 0; i < outs; i++) {
+		if (dacs[i])
+			continue;
+		dacs[i] = get_dac_if_single(codec, pins[i]);
+		if (dacs[i])
+			found = true;
+	}
+	return found;
+}
 
 /* fill in the dac_nids table from the parsed pin configuration */
-static int alc_auto_fill_dac_nids(struct hda_codec *codec)
+static int fill_and_eval_dacs(struct hda_codec *codec,
+			      bool fill_hardwired,
+			      bool fill_mio_first)
 {
 	struct alc_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
-	unsigned int location, defcfg;
-	int num_pins;
-	bool redone = false;
-	int i;
+	int i, err, badness;
 
- again:
 	/* set num_dacs once to full for alc_auto_look_for_dac() */
 	spec->multiout.num_dacs = cfg->line_outs;
-	spec->multiout.hp_out_nid[0] = 0;
-	spec->multiout.extra_out_nid[0] = 0;
-	memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
 	spec->multiout.dac_nids = spec->private_dac_nids;
+	memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
+	memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
+	memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
 	spec->multi_ios = 0;
+	clear_vol_marks(codec);
+	badness = 0;
 
 	/* fill hard-wired DACs first */
-	if (!redone) {
-		for (i = 0; i < cfg->line_outs; i++)
-			spec->private_dac_nids[i] =
-				get_dac_if_single(codec, cfg->line_out_pins[i]);
-		if (cfg->hp_outs)
-			spec->multiout.hp_out_nid[0] =
-				get_dac_if_single(codec, cfg->hp_pins[0]);
-		if (cfg->speaker_outs)
-			spec->multiout.extra_out_nid[0] =
-				get_dac_if_single(codec, cfg->speaker_pins[0]);
+	if (fill_hardwired) {
+		bool mapped;
+		do {
+			mapped = alc_map_singles(codec, cfg->line_outs,
+						 cfg->line_out_pins,
+						 spec->private_dac_nids);
+			mapped |= alc_map_singles(codec, cfg->hp_outs,
+						  cfg->hp_pins,
+						  spec->multiout.hp_out_nid);
+			mapped |= alc_map_singles(codec, cfg->speaker_outs,
+						  cfg->speaker_pins,
+						  spec->multiout.extra_out_nid);
+			if (fill_mio_first && cfg->line_outs == 1 &&
+			    cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+				err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
+				if (!err)
+					mapped = true;
+			}
+		} while (mapped);
 	}
 
-	for (i = 0; i < cfg->line_outs; i++) {
-		hda_nid_t pin = cfg->line_out_pins[i];
-		if (spec->private_dac_nids[i])
-			continue;
-		spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
-		if (!spec->private_dac_nids[i] && !redone) {
-			/* if we can't find primary DACs, re-probe without
-			 * checking the hard-wired DACs
-			 */
-			redone = true;
-			goto again;
-		}
-	}
+	badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
+				      spec->private_dac_nids,
+				      &main_out_badness);
 
 	/* re-count num_dacs and squash invalid entries */
 	spec->multiout.num_dacs = 0;
@@ -3085,30 +3280,144 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
 		}
 	}
 
-	if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+	if (fill_mio_first &&
+	    cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
 		/* try to fill multi-io first */
-		defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
-		location = get_defcfg_location(defcfg);
-
-		num_pins = alc_auto_fill_multi_ios(codec, location, 0);
-		if (num_pins > 0) {
-			spec->multi_ios = num_pins;
-			spec->ext_channel_count = 2;
-			spec->multiout.num_dacs = num_pins + 1;
-		}
+		err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
+		if (err < 0)
+			return err;
+		/* we don't count badness at this stage yet */
 	}
 
-	if (cfg->line_out_type != AUTO_PIN_HP_OUT)
-		alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins,
-				 spec->multiout.hp_out_nid);
+	if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
+		err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
+					 spec->multiout.hp_out_nid,
+					 &extra_out_badness);
+		if (err < 0)
+			return err;
+		badness += err;
+	}
 	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
-		int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs,
-					cfg->speaker_pins,
-					spec->multiout.extra_out_nid);
-		/* if no speaker volume is assigned, try again as the primary
-		 * output
-		 */
-		if (!err && cfg->speaker_outs > 0 &&
+		err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
+					 cfg->speaker_pins,
+					 spec->multiout.extra_out_nid,
+					 &extra_out_badness);
+		if (err < 0)
+			return err;
+		badness += err;
+	}
+	if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
+		err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
+		if (err < 0)
+			return err;
+		badness += err;
+	}
+	if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
+		/* try multi-ios with HP + inputs */
+		int offset = 0;
+		if (cfg->line_outs >= 3)
+			offset = 1;
+		err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
+					      offset);
+		if (err < 0)
+			return err;
+		badness += err;
+	}
+
+	if (spec->multi_ios == 2) {
+		for (i = 0; i < 2; i++)
+			spec->private_dac_nids[spec->multiout.num_dacs++] =
+				spec->multi_io[i].dac;
+		spec->ext_channel_count = 2;
+	} else if (spec->multi_ios) {
+		spec->multi_ios = 0;
+		badness += BAD_MULTI_IO;
+	}
+
+	return badness;
+}
+
+#define DEBUG_BADNESS
+
+#ifdef DEBUG_BADNESS
+#define debug_badness	snd_printdd
+#else
+#define debug_badness(...)
+#endif
+
+static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
+{
+	debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
+		      cfg->line_out_pins[0], cfg->line_out_pins[1],
+		      cfg->line_out_pins[2], cfg->line_out_pins[2],
+		      spec->multiout.dac_nids[0],
+		      spec->multiout.dac_nids[1],
+		      spec->multiout.dac_nids[2],
+		      spec->multiout.dac_nids[3]);
+	if (spec->multi_ios > 0)
+		debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
+			      spec->multi_ios,
+			      spec->multi_io[0].pin, spec->multi_io[1].pin,
+			      spec->multi_io[0].dac, spec->multi_io[1].dac);
+	debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
+		      cfg->hp_pins[0], cfg->hp_pins[1],
+		      cfg->hp_pins[2], cfg->hp_pins[2],
+		      spec->multiout.hp_out_nid[0],
+		      spec->multiout.hp_out_nid[1],
+		      spec->multiout.hp_out_nid[2],
+		      spec->multiout.hp_out_nid[3]);
+	debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
+		      cfg->speaker_pins[0], cfg->speaker_pins[1],
+		      cfg->speaker_pins[2], cfg->speaker_pins[3],
+		      spec->multiout.extra_out_nid[0],
+		      spec->multiout.extra_out_nid[1],
+		      spec->multiout.extra_out_nid[2],
+		      spec->multiout.extra_out_nid[3]);
+}
+
+static int alc_auto_fill_dac_nids(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	struct auto_pin_cfg *best_cfg;
+	int best_badness = INT_MAX;
+	int badness;
+	bool fill_hardwired = true, fill_mio_first = true;
+	bool best_wired = true, best_mio = true;
+	bool hp_spk_swapped = false;
+
+	best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
+	if (!best_cfg)
+		return -ENOMEM;
+	*best_cfg = *cfg;
+
+	for (;;) {
+		badness = fill_and_eval_dacs(codec, fill_hardwired,
+					     fill_mio_first);
+		if (badness < 0)
+			return badness;
+		debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
+			      cfg->line_out_type, fill_hardwired, fill_mio_first,
+			      badness);
+		debug_show_configs(spec, cfg);
+		if (badness < best_badness) {
+			best_badness = badness;
+			*best_cfg = *cfg;
+			best_wired = fill_hardwired;
+			best_mio = fill_mio_first;
+		}
+		if (!badness)
+			break;
+		fill_mio_first = !fill_mio_first;
+		if (!fill_mio_first)
+			continue;
+		fill_hardwired = !fill_hardwired;
+		if (!fill_hardwired)
+			continue;
+		if (hp_spk_swapped)
+			break;
+		hp_spk_swapped = true;
+		if (cfg->speaker_outs > 0 &&
 		    cfg->line_out_type == AUTO_PIN_HP_OUT) {
 			cfg->hp_outs = cfg->line_outs;
 			memcpy(cfg->hp_pins, cfg->line_out_pins,
@@ -3119,45 +3428,45 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
 			cfg->speaker_outs = 0;
 			memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
 			cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
-			redone = false;
-			goto again;
-		}
+			fill_hardwired = true;
+			continue;
+		} 
+		if (cfg->hp_outs > 0 &&
+		    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
+			cfg->speaker_outs = cfg->line_outs;
+			memcpy(cfg->speaker_pins, cfg->line_out_pins,
+			       sizeof(cfg->speaker_pins));
+			cfg->line_outs = cfg->hp_outs;
+			memcpy(cfg->line_out_pins, cfg->hp_pins,
+			       sizeof(cfg->hp_pins));
+			cfg->hp_outs = 0;
+			memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+			cfg->line_out_type = AUTO_PIN_HP_OUT;
+			fill_hardwired = true;
+			continue;
+		} 
+		break;
 	}
 
-	if (!spec->multi_ios &&
-	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
-	    cfg->hp_outs) {
-		/* try multi-ios with HP + inputs */
-		defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]);
-		location = get_defcfg_location(defcfg);
-
-		num_pins = alc_auto_fill_multi_ios(codec, location, 1);
-		if (num_pins > 0) {
-			spec->multi_ios = num_pins;
-			spec->ext_channel_count = 2;
-			spec->multiout.num_dacs = num_pins + 1;
-		}
+	if (badness) {
+		*cfg = *best_cfg;
+		fill_and_eval_dacs(codec, best_wired, best_mio);
 	}
+	debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
+		      cfg->line_out_type, best_wired, best_mio);
+	debug_show_configs(spec, cfg);
 
 	if (cfg->line_out_pins[0])
 		spec->vmaster_nid =
 			alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
 						 spec->multiout.dac_nids[0]);
-	return 0;
-}
 
-static inline unsigned int get_ctl_pos(unsigned int data)
-{
-	hda_nid_t nid = get_amp_nid_(data);
-	unsigned int dir = get_amp_direction_(data);
-	return (nid << 1) | dir;
+	/* clear the bitmap flags for creating controls */
+	clear_vol_marks(codec);
+	kfree(best_cfg);
+	return 0;
 }
 
-#define is_ctl_used(bits, data) \
-	test_bit(get_ctl_pos(data), bits)
-#define mark_ctl_usage(bits, data) \
-	set_bit(get_ctl_pos(data), bits)
-
 static int alc_auto_add_vol_ctl(struct hda_codec *codec,
 			      const char *pfx, int cidx,
 			      hda_nid_t nid, unsigned int chs)
@@ -3269,14 +3578,17 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
 		dac = spec->multiout.dac_nids[i];
 		if (!dac)
 			continue;
-		if (i >= cfg->line_outs)
+		if (i >= cfg->line_outs) {
 			pin = spec->multi_io[i - 1].pin;
-		else
+			index = 0;
+			name = channel_name[i];
+		} else {
 			pin = cfg->line_out_pins[i];
+			name = alc_get_line_out_pfx(spec, i, true, &index);
+		}
 
 		sw = alc_look_for_out_mute_nid(codec, pin, dac);
 		vol = alc_look_for_out_vol_nid(codec, pin, dac);
-		name = alc_get_line_out_pfx(spec, i, true, &index);
 		if (!name || !strcmp(name, "CLFE")) {
 			/* Center/LFE */
 			err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
@@ -3373,41 +3685,31 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
 		return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
 	}
 
-	if (dacs[num_pins - 1]) {
-		/* OK, we have a multi-output system with individual volumes */
-		for (i = 0; i < num_pins; i++) {
-			if (num_pins >= 3) {
-				snprintf(name, sizeof(name), "%s %s",
-					 pfx, channel_name[i]);
-				err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
-								name, 0);
-			} else {
-				err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
-								pfx, i);
-			}
-			if (err < 0)
-				return err;
-		}
-		return 0;
-	}
-
-	/* Let's create a bind-controls */
-	ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
-	if (!ctl)
-		return -ENOMEM;
-	n = 0;
 	for (i = 0; i < num_pins; i++) {
-		if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP)
-			ctl->values[n++] =
-				HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT);
-	}
-	if (n) {
-		snprintf(name, sizeof(name), "%s Playback Switch", pfx);
-		err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl);
+		hda_nid_t dac;
+		if (dacs[num_pins - 1])
+			dac = dacs[i]; /* with individual volumes */
+		else
+			dac = 0;
+		if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
+			err = alc_auto_create_extra_out(codec, pins[i], dac,
+							"Bass Speaker", 0);
+		} else if (num_pins >= 3) {
+			snprintf(name, sizeof(name), "%s %s",
+				 pfx, channel_name[i]);
+			err = alc_auto_create_extra_out(codec, pins[i], dac,
+							name, 0);
+		} else {
+			err = alc_auto_create_extra_out(codec, pins[i], dac,
+							pfx, i);
+		}
 		if (err < 0)
 			return err;
 	}
+	if (dacs[num_pins - 1])
+		return 0;
 
+	/* Let's create a bind-controls for volumes */
 	ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
 	if (!ctl)
 		return -ENOMEM;
@@ -3543,59 +3845,112 @@ static void alc_auto_init_extra_out(struct hda_codec *codec)
 	}
 }
 
+/* check whether the given pin can be a multi-io pin */
+static bool can_be_multiio_pin(struct hda_codec *codec,
+			       unsigned int location, hda_nid_t nid)
+{
+	unsigned int defcfg, caps;
+
+	defcfg = snd_hda_codec_get_pincfg(codec, nid);
+	if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
+		return false;
+	if (location && get_defcfg_location(defcfg) != location)
+		return false;
+	caps = snd_hda_query_pin_caps(codec, nid);
+	if (!(caps & AC_PINCAP_OUT))
+		return false;
+	return true;
+}
+
 /*
  * multi-io helper
+ *
+ * When hardwired is set, try to fill ony hardwired pins, and returns
+ * zero if any pins are filled, non-zero if nothing found.
+ * When hardwired is off, try to fill possible input pins, and returns
+ * the badness value.
  */
 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
-				   unsigned int location,
-				   int offset)
+				   hda_nid_t reference_pin,
+				   bool hardwired, int offset)
 {
 	struct alc_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
-	hda_nid_t prime_dac = spec->private_dac_nids[0];
-	int type, i, dacs, num_pins = 0;
+	int type, i, j, dacs, num_pins, old_pins;
+	unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
+	unsigned int location = get_defcfg_location(defcfg);
+	int badness = 0;
+
+	old_pins = spec->multi_ios;
+	if (old_pins >= 2)
+		goto end_fill;
+
+	num_pins = 0;
+	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
+		for (i = 0; i < cfg->num_inputs; i++) {
+			if (cfg->inputs[i].type != type)
+				continue;
+			if (can_be_multiio_pin(codec, location,
+					       cfg->inputs[i].pin))
+				num_pins++;
+		}
+	}
+	if (num_pins < 2)
+		goto end_fill;
 
 	dacs = spec->multiout.num_dacs;
 	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
 		for (i = 0; i < cfg->num_inputs; i++) {
 			hda_nid_t nid = cfg->inputs[i].pin;
 			hda_nid_t dac = 0;
-			unsigned int defcfg, caps;
+
 			if (cfg->inputs[i].type != type)
 				continue;
-			defcfg = snd_hda_codec_get_pincfg(codec, nid);
-			if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
+			if (!can_be_multiio_pin(codec, location, nid))
 				continue;
-			if (location && get_defcfg_location(defcfg) != location)
-				continue;
-			caps = snd_hda_query_pin_caps(codec, nid);
-			if (!(caps & AC_PINCAP_OUT))
+			for (j = 0; j < spec->multi_ios; j++) {
+				if (nid == spec->multi_io[j].pin)
+					break;
+			}
+			if (j < spec->multi_ios)
 				continue;
-			if (offset && offset + num_pins < dacs) {
-				dac = spec->private_dac_nids[offset + num_pins];
+
+			if (offset && offset + spec->multi_ios < dacs) {
+				dac = spec->private_dac_nids[offset + spec->multi_ios];
 				if (!alc_auto_is_dac_reachable(codec, nid, dac))
 					dac = 0;
 			}
-			if (!dac)
+			if (hardwired)
+				dac = get_dac_if_single(codec, nid);
+			else if (!dac)
 				dac = alc_auto_look_for_dac(codec, nid);
-			if (!dac)
+			if (!dac) {
+				badness++;
 				continue;
-			spec->multi_io[num_pins].pin = nid;
-			spec->multi_io[num_pins].dac = dac;
-			num_pins++;
-			spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
+			}
+			spec->multi_io[spec->multi_ios].pin = nid;
+			spec->multi_io[spec->multi_ios].dac = dac;
+			spec->multi_ios++;
+			if (spec->multi_ios >= 2)
+				break;
 		}
 	}
-	spec->multiout.num_dacs = dacs;
-	if (num_pins < 2) {
-		/* clear up again */
-		memset(spec->private_dac_nids + dacs, 0,
-		       sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs));
-		spec->private_dac_nids[0] = prime_dac;
-		return 0;
+ end_fill:
+	if (badness)
+		badness = BAD_MULTI_IO;
+	if (old_pins == spec->multi_ios) {
+		if (hardwired)
+			return 1; /* nothing found */
+		else
+			return badness; /* no badness if nothing found */
+	}
+	if (!hardwired && spec->multi_ios < 2) {
+		spec->multi_ios = old_pins;
+		return badness;
 	}
-	return num_pins;
-}
+
+	return 0;
+}
 
 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_info *uinfo)
@@ -4048,6 +4403,9 @@ static int alc_parse_auto_config(struct hda_codec *codec,
 	if (spec->kctls.list)
 		add_mixer(spec, spec->kctls.list);
 
+	if (!spec->no_analog && !spec->cap_mixer)
+		set_capture_mixer(codec);
+
 	return 1;
 }
 
@@ -4058,26 +4416,47 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
 	return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc880_loopbacks[] = {
-	{ 0x0b, HDA_INPUT, 0 },
-	{ 0x0b, HDA_INPUT, 1 },
-	{ 0x0b, HDA_INPUT, 2 },
-	{ 0x0b, HDA_INPUT, 3 },
-	{ 0x0b, HDA_INPUT, 4 },
-	{ } /* end */
-};
-#endif
-
 /*
  * ALC880 fix-ups
  */
 enum {
+	ALC880_FIXUP_GPIO1,
 	ALC880_FIXUP_GPIO2,
 	ALC880_FIXUP_MEDION_RIM,
+	ALC880_FIXUP_LG,
+	ALC880_FIXUP_W810,
+	ALC880_FIXUP_EAPD_COEF,
+	ALC880_FIXUP_TCL_S700,
+	ALC880_FIXUP_VOL_KNOB,
+	ALC880_FIXUP_FUJITSU,
+	ALC880_FIXUP_F1734,
+	ALC880_FIXUP_UNIWILL,
+	ALC880_FIXUP_UNIWILL_DIG,
+	ALC880_FIXUP_Z71V,
+	ALC880_FIXUP_3ST_BASE,
+	ALC880_FIXUP_3ST,
+	ALC880_FIXUP_3ST_DIG,
+	ALC880_FIXUP_5ST_BASE,
+	ALC880_FIXUP_5ST,
+	ALC880_FIXUP_5ST_DIG,
+	ALC880_FIXUP_6ST_BASE,
+	ALC880_FIXUP_6ST,
+	ALC880_FIXUP_6ST_DIG,
 };
 
+/* enable the volume-knob widget support on NID 0x21 */
+static void alc880_fixup_vol_knob(struct hda_codec *codec,
+				  const struct alc_fixup *fix, int action)
+{
+	if (action == ALC_FIXUP_ACT_PROBE)
+		snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
+}
+
 static const struct alc_fixup alc880_fixups[] = {
+	[ALC880_FIXUP_GPIO1] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = alc_gpio1_init_verbs,
+	},
 	[ALC880_FIXUP_GPIO2] = {
 		.type = ALC_FIXUP_VERBS,
 		.v.verbs = alc_gpio2_init_verbs,
@@ -4092,40 +4471,323 @@ static const struct alc_fixup alc880_fixups[] = {
 		.chained = true,
 		.chain_id = ALC880_FIXUP_GPIO2,
 	},
+	[ALC880_FIXUP_LG] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			/* disable bogus unused pins */
+			{ 0x16, 0x411111f0 },
+			{ 0x18, 0x411111f0 },
+			{ 0x1a, 0x411111f0 },
+			{ }
+		}
+	},
+	[ALC880_FIXUP_W810] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			/* disable bogus unused pins */
+			{ 0x17, 0x411111f0 },
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_GPIO2,
+	},
+	[ALC880_FIXUP_EAPD_COEF] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			/* change to EAPD mode */
+			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
+			{}
+		},
+	},
+	[ALC880_FIXUP_TCL_S700] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			/* change to EAPD mode */
+			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
+			{}
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_GPIO2,
+	},
+	[ALC880_FIXUP_VOL_KNOB] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc880_fixup_vol_knob,
+	},
+	[ALC880_FIXUP_FUJITSU] = {
+		/* override all pins as BIOS on old Amilo is broken */
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x0121411f }, /* HP */
+			{ 0x15, 0x99030120 }, /* speaker */
+			{ 0x16, 0x99030130 }, /* bass speaker */
+			{ 0x17, 0x411111f0 }, /* N/A */
+			{ 0x18, 0x411111f0 }, /* N/A */
+			{ 0x19, 0x01a19950 }, /* mic-in */
+			{ 0x1a, 0x411111f0 }, /* N/A */
+			{ 0x1b, 0x411111f0 }, /* N/A */
+			{ 0x1c, 0x411111f0 }, /* N/A */
+			{ 0x1d, 0x411111f0 }, /* N/A */
+			{ 0x1e, 0x01454140 }, /* SPDIF out */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_VOL_KNOB,
+	},
+	[ALC880_FIXUP_F1734] = {
+		/* almost compatible with FUJITSU, but no bass and SPDIF */
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x0121411f }, /* HP */
+			{ 0x15, 0x99030120 }, /* speaker */
+			{ 0x16, 0x411111f0 }, /* N/A */
+			{ 0x17, 0x411111f0 }, /* N/A */
+			{ 0x18, 0x411111f0 }, /* N/A */
+			{ 0x19, 0x01a19950 }, /* mic-in */
+			{ 0x1a, 0x411111f0 }, /* N/A */
+			{ 0x1b, 0x411111f0 }, /* N/A */
+			{ 0x1c, 0x411111f0 }, /* N/A */
+			{ 0x1d, 0x411111f0 }, /* N/A */
+			{ 0x1e, 0x411111f0 }, /* N/A */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_VOL_KNOB,
+	},
+	[ALC880_FIXUP_UNIWILL] = {
+		/* need to fix HP and speaker pins to be parsed correctly */
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x0121411f }, /* HP */
+			{ 0x15, 0x99030120 }, /* speaker */
+			{ 0x16, 0x99030130 }, /* bass speaker */
+			{ }
+		},
+	},
+	[ALC880_FIXUP_UNIWILL_DIG] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			/* disable bogus unused pins */
+			{ 0x17, 0x411111f0 },
+			{ 0x19, 0x411111f0 },
+			{ 0x1b, 0x411111f0 },
+			{ 0x1f, 0x411111f0 },
+			{ }
+		}
+	},
+	[ALC880_FIXUP_Z71V] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			/* set up the whole pins as BIOS is utterly broken */
+			{ 0x14, 0x99030120 }, /* speaker */
+			{ 0x15, 0x0121411f }, /* HP */
+			{ 0x16, 0x411111f0 }, /* N/A */
+			{ 0x17, 0x411111f0 }, /* N/A */
+			{ 0x18, 0x01a19950 }, /* mic-in */
+			{ 0x19, 0x411111f0 }, /* N/A */
+			{ 0x1a, 0x01813031 }, /* line-in */
+			{ 0x1b, 0x411111f0 }, /* N/A */
+			{ 0x1c, 0x411111f0 }, /* N/A */
+			{ 0x1d, 0x411111f0 }, /* N/A */
+			{ 0x1e, 0x0144111e }, /* SPDIF */
+			{ }
+		}
+	},
+	[ALC880_FIXUP_3ST_BASE] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x01014010 }, /* line-out */
+			{ 0x15, 0x411111f0 }, /* N/A */
+			{ 0x16, 0x411111f0 }, /* N/A */
+			{ 0x17, 0x411111f0 }, /* N/A */
+			{ 0x18, 0x01a19c30 }, /* mic-in */
+			{ 0x19, 0x0121411f }, /* HP */
+			{ 0x1a, 0x01813031 }, /* line-in */
+			{ 0x1b, 0x02a19c40 }, /* front-mic */
+			{ 0x1c, 0x411111f0 }, /* N/A */
+			{ 0x1d, 0x411111f0 }, /* N/A */
+			/* 0x1e is filled in below */
+			{ 0x1f, 0x411111f0 }, /* N/A */
+			{ }
+		}
+	},
+	[ALC880_FIXUP_3ST] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x1e, 0x411111f0 }, /* N/A */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_3ST_BASE,
+	},
+	[ALC880_FIXUP_3ST_DIG] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x1e, 0x0144111e }, /* SPDIF */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_3ST_BASE,
+	},
+	[ALC880_FIXUP_5ST_BASE] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x01014010 }, /* front */
+			{ 0x15, 0x411111f0 }, /* N/A */
+			{ 0x16, 0x01011411 }, /* CLFE */
+			{ 0x17, 0x01016412 }, /* surr */
+			{ 0x18, 0x01a19c30 }, /* mic-in */
+			{ 0x19, 0x0121411f }, /* HP */
+			{ 0x1a, 0x01813031 }, /* line-in */
+			{ 0x1b, 0x02a19c40 }, /* front-mic */
+			{ 0x1c, 0x411111f0 }, /* N/A */
+			{ 0x1d, 0x411111f0 }, /* N/A */
+			/* 0x1e is filled in below */
+			{ 0x1f, 0x411111f0 }, /* N/A */
+			{ }
+		}
+	},
+	[ALC880_FIXUP_5ST] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x1e, 0x411111f0 }, /* N/A */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_5ST_BASE,
+	},
+	[ALC880_FIXUP_5ST_DIG] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x1e, 0x0144111e }, /* SPDIF */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_5ST_BASE,
+	},
+	[ALC880_FIXUP_6ST_BASE] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x14, 0x01014010 }, /* front */
+			{ 0x15, 0x01016412 }, /* surr */
+			{ 0x16, 0x01011411 }, /* CLFE */
+			{ 0x17, 0x01012414 }, /* side */
+			{ 0x18, 0x01a19c30 }, /* mic-in */
+			{ 0x19, 0x02a19c40 }, /* front-mic */
+			{ 0x1a, 0x01813031 }, /* line-in */
+			{ 0x1b, 0x0121411f }, /* HP */
+			{ 0x1c, 0x411111f0 }, /* N/A */
+			{ 0x1d, 0x411111f0 }, /* N/A */
+			/* 0x1e is filled in below */
+			{ 0x1f, 0x411111f0 }, /* N/A */
+			{ }
+		}
+	},
+	[ALC880_FIXUP_6ST] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x1e, 0x411111f0 }, /* N/A */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_6ST_BASE,
+	},
+	[ALC880_FIXUP_6ST_DIG] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x1e, 0x0144111e }, /* SPDIF */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC880_FIXUP_6ST_BASE,
+	},
 };
 
 static const struct snd_pci_quirk alc880_fixup_tbl[] = {
+	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
+	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
+	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
+	SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
+	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
+	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
+	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
+	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
+	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
+	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
 	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
+	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
+	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
+	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
+	SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
+	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
+	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
+	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
+	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
+
+	/* Below is the copied entries from alc880_quirks.c.
+	 * It's not quite sure whether BIOS sets the correct pin-config table
+	 * on these machines, thus they are kept to be compatible with
+	 * the old static quirks.  Once when it's confirmed to work without
+	 * these overrides, it'd be better to remove.
+	 */
+	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
+	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
+	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
+	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
+	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
+	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
+	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
+	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
+	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
+	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
+	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
+	/* default Intel */
+	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
+	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
+	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
 	{}
 };
 
+static const struct alc_model_fixup alc880_fixup_models[] = {
+	{.id = ALC880_FIXUP_3ST, .name = "3stack"},
+	{.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
+	{.id = ALC880_FIXUP_5ST, .name = "5stack"},
+	{.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
+	{.id = ALC880_FIXUP_6ST, .name = "6stack"},
+	{.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
+	{}
+};
 
-/*
- * board setups
- */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#define alc_board_config \
-	snd_hda_check_board_config
-#define alc_board_codec_sid_config \
-	snd_hda_check_board_codec_sid_config
-#include "alc_quirks.c"
-#else
-#define alc_board_config(codec, nums, models, tbl)	-1
-#define alc_board_codec_sid_config(codec, nums, models, tbl)	-1
-#define setup_preset(codec, x)	/* NOP */
-#endif
 
 /*
  * OK, here we have finally the patch for ALC880
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc880_quirks.c"
-#endif
-
 static int patch_alc880(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
-	int board_config;
 	int err;
 
 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4137,47 +4799,14 @@ static int patch_alc880(struct hda_codec *codec)
 	spec->mixer_nid = 0x0b;
 	spec->need_dac_fix = 1;
 
-	board_config = alc_board_config(codec, ALC880_MODEL_LAST,
-					alc880_models, alc880_cfg_tbl);
-	if (board_config < 0) {
-		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-		       codec->chip_name);
-		board_config = ALC_MODEL_AUTO;
-	}
-
-	if (board_config == ALC_MODEL_AUTO) {
-		alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups);
-		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-	}
-
-	if (board_config == ALC_MODEL_AUTO) {
-		/* automatic parse from the BIOS config */
-		err = alc880_parse_auto_config(codec);
-		if (err < 0)
-			goto error;
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-		else if (!err) {
-			printk(KERN_INFO
-			       "hda_codec: Cannot set up configuration "
-			       "from BIOS.  Using 3-stack mode...\n");
-			board_config = ALC880_3ST;
-		}
-#endif
-	}
-
-	if (board_config != ALC_MODEL_AUTO) {
-		spec->vmaster_nid = 0x0c;
-		setup_preset(codec, &alc880_presets[board_config]);
-	}
-
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
+	alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
+		       alc880_fixups);
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
+	/* automatic parse from the BIOS config */
+	err = alc880_parse_auto_config(codec);
+	if (err < 0)
+		goto error;
 
 	if (!spec->no_analog) {
 		err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4186,17 +4815,9 @@ static int patch_alc880(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
-	if (board_config == ALC_MODEL_AUTO)
-		spec->init_hook = alc_auto_init_std;
-	else
-		codec->patch_ops.build_controls = __alc_build_controls;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc880_loopbacks;
-#endif
+
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	return 0;
 
@@ -4216,49 +4837,115 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
 	return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc260_loopbacks[] = {
-	{ 0x07, HDA_INPUT, 0 },
-	{ 0x07, HDA_INPUT, 1 },
-	{ 0x07, HDA_INPUT, 2 },
-	{ 0x07, HDA_INPUT, 3 },
-	{ 0x07, HDA_INPUT, 4 },
-	{ } /* end */
-};
-#endif
-
 /*
  * Pin config fixes
  */
 enum {
-	PINFIX_HP_DC5750,
+	ALC260_FIXUP_HP_DC5750,
+	ALC260_FIXUP_HP_PIN_0F,
+	ALC260_FIXUP_COEF,
+	ALC260_FIXUP_GPIO1,
+	ALC260_FIXUP_GPIO1_TOGGLE,
+	ALC260_FIXUP_REPLACER,
+	ALC260_FIXUP_HP_B1900,
 };
 
+static void alc260_gpio1_automute(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+			    spec->hp_jack_present);
+}
+
+static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
+				      const struct alc_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+	if (action == ALC_FIXUP_ACT_PROBE) {
+		/* although the machine has only one output pin, we need to
+		 * toggle GPIO1 according to the jack state
+		 */
+		spec->automute_hook = alc260_gpio1_automute;
+		spec->detect_hp = 1;
+		spec->automute_speaker = 1;
+		spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
+		snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
+		spec->unsol_event = alc_sku_unsol_event;
+		add_verb(codec->spec, alc_gpio1_init_verbs);
+	}
+}
+
 static const struct alc_fixup alc260_fixups[] = {
-	[PINFIX_HP_DC5750] = {
+	[ALC260_FIXUP_HP_DC5750] = {
 		.type = ALC_FIXUP_PINS,
 		.v.pins = (const struct alc_pincfg[]) {
 			{ 0x11, 0x90130110 }, /* speaker */
 			{ }
 		}
 	},
+	[ALC260_FIXUP_HP_PIN_0F] = {
+		.type = ALC_FIXUP_PINS,
+		.v.pins = (const struct alc_pincfg[]) {
+			{ 0x0f, 0x01214000 }, /* HP */
+			{ }
+		}
+	},
+	[ALC260_FIXUP_COEF] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3040 },
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC260_FIXUP_HP_PIN_0F,
+	},
+	[ALC260_FIXUP_GPIO1] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = alc_gpio1_init_verbs,
+	},
+	[ALC260_FIXUP_GPIO1_TOGGLE] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc260_fixup_gpio1_toggle,
+		.chained = true,
+		.chain_id = ALC260_FIXUP_HP_PIN_0F,
+	},
+	[ALC260_FIXUP_REPLACER] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = (const struct hda_verb[]) {
+			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
+			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3050 },
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
+	},
+	[ALC260_FIXUP_HP_B1900] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc260_fixup_gpio1_toggle,
+		.chained = true,
+		.chain_id = ALC260_FIXUP_COEF,
+	}
 };
 
 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
-	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
+	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
+	SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
+	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
+	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
+	SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
+	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
+	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
+	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
 	{}
 };
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc260_quirks.c"
-#endif
-
 static int patch_alc260(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
-	int err, board_config;
+	int err;
 
 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -4268,47 +4955,13 @@ static int patch_alc260(struct hda_codec *codec)
 
 	spec->mixer_nid = 0x07;
 
-	board_config = alc_board_config(codec, ALC260_MODEL_LAST,
-					alc260_models, alc260_cfg_tbl);
-	if (board_config < 0) {
-		snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-			   codec->chip_name);
-		board_config = ALC_MODEL_AUTO;
-	}
-
-	if (board_config == ALC_MODEL_AUTO) {
-		alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
-		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-	}
-
-	if (board_config == ALC_MODEL_AUTO) {
-		/* automatic parse from the BIOS config */
-		err = alc260_parse_auto_config(codec);
-		if (err < 0)
-			goto error;
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-		else if (!err) {
-			printk(KERN_INFO
-			       "hda_codec: Cannot set up configuration "
-			       "from BIOS.  Using base mode...\n");
-			board_config = ALC260_BASIC;
-		}
-#endif
-	}
-
-	if (board_config != ALC_MODEL_AUTO) {
-		setup_preset(codec, &alc260_presets[board_config]);
-		spec->vmaster_nid = 0x08;
-	}
-
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
+	alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
+	/* automatic parse from the BIOS config */
+	err = alc260_parse_auto_config(codec);
+	if (err < 0)
+		goto error;
 
 	if (!spec->no_analog) {
 		err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4317,18 +4970,10 @@ static int patch_alc260(struct hda_codec *codec)
 		set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
-	if (board_config == ALC_MODEL_AUTO)
-		spec->init_hook = alc_auto_init_std;
-	else
-		codec->patch_ops.build_controls = __alc_build_controls;
 	spec->shutup = alc_eapd_shutup;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc260_loopbacks;
-#endif
+
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	return 0;
 
@@ -4349,9 +4994,6 @@ static int patch_alc260(struct hda_codec *codec)
  * In addition, an independent DAC for the multi-playback (not used in this
  * driver yet).
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc882_loopbacks	alc880_loopbacks
-#endif
 
 /*
  * Pin config fixes
@@ -4367,6 +5009,8 @@ enum {
 	ALC882_FIXUP_EAPD,
 	ALC883_FIXUP_EAPD,
 	ALC883_FIXUP_ACER_EAPD,
+	ALC882_FIXUP_GPIO1,
+	ALC882_FIXUP_GPIO2,
 	ALC882_FIXUP_GPIO3,
 	ALC889_FIXUP_COEF,
 	ALC882_FIXUP_ASUS_W2JC,
@@ -4375,6 +5019,8 @@ enum {
 	ALC882_FIXUP_ASPIRE_8930G_VERBS,
 	ALC885_FIXUP_MACPRO_GPIO,
 	ALC889_FIXUP_DAC_ROUTE,
+	ALC889_FIXUP_MBP_VREF,
+	ALC889_FIXUP_IMAC91_VREF,
 };
 
 static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4436,15 +5082,68 @@ static void alc889_fixup_dac_route(struct hda_codec *codec,
 				   const struct alc_fixup *fix, int action)
 {
 	if (action == ALC_FIXUP_ACT_PRE_PROBE) {
+		/* fake the connections during parsing the tree */
 		hda_nid_t conn1[2] = { 0x0c, 0x0d };
 		hda_nid_t conn2[2] = { 0x0e, 0x0f };
 		snd_hda_override_conn_list(codec, 0x14, 2, conn1);
 		snd_hda_override_conn_list(codec, 0x15, 2, conn1);
 		snd_hda_override_conn_list(codec, 0x18, 2, conn2);
 		snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
+	} else if (action == ALC_FIXUP_ACT_PROBE) {
+		/* restore the connections */
+		hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
+		snd_hda_override_conn_list(codec, 0x14, 5, conn);
+		snd_hda_override_conn_list(codec, 0x15, 5, conn);
+		snd_hda_override_conn_list(codec, 0x18, 5, conn);
+		snd_hda_override_conn_list(codec, 0x1a, 5, conn);
 	}
 }
 
+/* Set VREF on HP pin */
+static void alc889_fixup_mbp_vref(struct hda_codec *codec,
+				  const struct alc_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+	static hda_nid_t nids[2] = { 0x14, 0x15 };
+	int i;
+
+	if (action != ALC_FIXUP_ACT_INIT)
+		return;
+	for (i = 0; i < ARRAY_SIZE(nids); i++) {
+		unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
+		if (get_defcfg_device(val) != AC_JACK_HP_OUT)
+			continue;
+		val = snd_hda_codec_read(codec, nids[i], 0,
+					 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+		val |= AC_PINCTL_VREF_80;
+		snd_hda_codec_write(codec, nids[i], 0,
+				    AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+		spec->keep_vref_in_automute = 1;
+		break;
+	}
+}
+
+/* Set VREF on speaker pins on imac91 */
+static void alc889_fixup_imac91_vref(struct hda_codec *codec,
+				     const struct alc_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+	static hda_nid_t nids[2] = { 0x18, 0x1a };
+	int i;
+
+	if (action != ALC_FIXUP_ACT_INIT)
+		return;
+	for (i = 0; i < ARRAY_SIZE(nids); i++) {
+		unsigned int val;
+		val = snd_hda_codec_read(codec, nids[i], 0,
+					 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+		val |= AC_PINCTL_VREF_50;
+		snd_hda_codec_write(codec, nids[i], 0,
+				    AC_VERB_SET_PIN_WIDGET_CONTROL, val);
+	}
+	spec->keep_vref_in_automute = 1;
+}
+
 static const struct alc_fixup alc882_fixups[] = {
 	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
 		.type = ALC_FIXUP_PINS,
@@ -4523,6 +5222,14 @@ static const struct alc_fixup alc882_fixups[] = {
 			{ }
 		}
 	},
+	[ALC882_FIXUP_GPIO1] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = alc_gpio1_init_verbs,
+	},
+	[ALC882_FIXUP_GPIO2] = {
+		.type = ALC_FIXUP_VERBS,
+		.v.verbs = alc_gpio2_init_verbs,
+	},
 	[ALC882_FIXUP_GPIO3] = {
 		.type = ALC_FIXUP_VERBS,
 		.v.verbs = alc_gpio3_init_verbs,
@@ -4596,6 +5303,18 @@ static const struct alc_fixup alc882_fixups[] = {
 		.type = ALC_FIXUP_FUNC,
 		.v.func = alc889_fixup_dac_route,
 	},
+	[ALC889_FIXUP_MBP_VREF] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc889_fixup_mbp_vref,
+		.chained = true,
+		.chain_id = ALC882_FIXUP_GPIO1,
+	},
+	[ALC889_FIXUP_IMAC91_VREF] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc889_fixup_imac91_vref,
+		.chained = true,
+		.chain_id = ALC882_FIXUP_GPIO1,
+	},
 };
 
 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4629,11 +5348,26 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
 
 	/* All Apple entries are in codec SSIDs */
+	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
+	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
+	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
 	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
 	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
 	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
+	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
+	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
 	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
+	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
+	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
+	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
+	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
 	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
+	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
+	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
+	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
+	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
+	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
+	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
 
 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
 	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
@@ -4658,14 +5392,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
 
 /*
  */
-#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
-#include "alc882_quirks.c"
-#endif
-
 static int patch_alc882(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
-	int err, board_config;
+	int err;
 
 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -4689,45 +5419,15 @@ static int patch_alc882(struct hda_codec *codec)
 	if (err < 0)
 		goto error;
 
-	board_config = alc_board_config(codec, ALC882_MODEL_LAST,
-					alc882_models, NULL);
-	if (board_config < 0)
-		board_config = alc_board_codec_sid_config(codec,
-			ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
-
-	if (board_config < 0) {
-		printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
-		       codec->chip_name);
-		board_config = ALC_MODEL_AUTO;
-	}
-
-	if (board_config == ALC_MODEL_AUTO) {
-		alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
-		alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-	}
+	alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
 	alc_auto_parse_customize_define(codec);
 
-	if (board_config == ALC_MODEL_AUTO) {
-		/* automatic parse from the BIOS config */
-		err = alc882_parse_auto_config(codec);
-		if (err < 0)
-			goto error;
-	}
-
-	if (board_config != ALC_MODEL_AUTO) {
-		setup_preset(codec, &alc882_presets[board_config]);
-		spec->vmaster_nid = 0x0c;
-	}
-
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
+	/* automatic parse from the BIOS config */
+	err = alc882_parse_auto_config(codec);
+	if (err < 0)
+		goto error;
 
 	if (!spec->no_analog && has_cdefine_beep(codec)) {
 		err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4736,18 +5436,9 @@ static int patch_alc882(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
-	if (board_config == ALC_MODEL_AUTO)
-		spec->init_hook = alc_auto_init_std;
-	else
-		codec->patch_ops.build_controls = __alc_build_controls;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc882_loopbacks;
-#endif
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	return 0;
 
@@ -4843,10 +5534,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
 };
 
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc262_loopbacks	alc880_loopbacks
-#endif
-
 /*
  */
 static int patch_alc262(struct hda_codec *codec)
@@ -4886,15 +5573,6 @@ static int patch_alc262(struct hda_codec *codec)
 	if (err < 0)
 		goto error;
 
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	if (!spec->no_analog && has_cdefine_beep(codec)) {
 		err = snd_hda_attach_beep_device(codec, 0x1);
 		if (err < 0)
@@ -4902,16 +5580,10 @@ static int patch_alc262(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
-	spec->init_hook = alc_auto_init_std;
 	spec->shutup = alc_eapd_shutup;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc262_loopbacks;
-#endif
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	return 0;
 
@@ -5005,17 +5677,7 @@ static int patch_alc268(struct hda_codec *codec)
 					  (0 << AC_AMPCAP_MUTE_SHIFT));
 	}
 
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	codec->patch_ops = alc_patch_ops;
-	spec->init_hook = alc_auto_init_std;
 	spec->shutup = alc_eapd_shutup;
 
 	return 0;
@@ -5028,10 +5690,6 @@ static int patch_alc268(struct hda_codec *codec)
 /*
  * ALC269
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc269_loopbacks	alc880_loopbacks
-#endif
-
 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
 	.substreams = 1,
 	.channels_min = 2,
@@ -5394,7 +6052,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
 	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 
-#if 1
+#if 0
 	/* Below is a quirk table taken from the old code.
 	 * Basically the device should work as is without the fixup table.
 	 * If BIOS doesn't give a proper info, enable the corresponding
@@ -5547,15 +6205,6 @@ static int patch_alc269(struct hda_codec *codec)
 	if (err < 0)
 		goto error;
 
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	if (!spec->no_analog && has_cdefine_beep(codec)) {
 		err = snd_hda_attach_beep_device(codec, 0x1);
 		if (err < 0)
@@ -5563,22 +6212,19 @@ static int patch_alc269(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
 #ifdef CONFIG_PM
 	codec->patch_ops.resume = alc269_resume;
 #endif
-	spec->init_hook = alc_auto_init_std;
 	spec->shutup = alc269_shutup;
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc269_loopbacks;
 	if (alc269_mic2_for_mute_led(codec))
 		codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
 #endif
 
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
+
 	return 0;
 
  error:
@@ -5597,21 +6243,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
 	return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static const struct hda_amp_list alc861_loopbacks[] = {
-	{ 0x15, HDA_INPUT, 0 },
-	{ 0x15, HDA_INPUT, 1 },
-	{ 0x15, HDA_INPUT, 2 },
-	{ 0x15, HDA_INPUT, 3 },
-	{ } /* end */
-};
-#endif
-
-
 /* Pin config fixes */
 enum {
-	PINFIX_FSC_AMILO_PI1505,
-	PINFIX_ASUS_A6RP,
+	ALC861_FIXUP_FSC_AMILO_PI1505,
+	ALC861_FIXUP_AMP_VREF_0F,
+	ALC861_FIXUP_NO_JACK_DETECT,
+	ALC861_FIXUP_ASUS_A6RP,
 };
 
 /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
@@ -5633,8 +6270,16 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
 	spec->keep_vref_in_automute = 1;
 }
 
+/* suppress the jack-detection */
+static void alc_fixup_no_jack_detect(struct hda_codec *codec,
+				     const struct alc_fixup *fix, int action)
+{
+	if (action == ALC_FIXUP_ACT_PRE_PROBE)
+		codec->no_jack_detect = 1;
+}	
+
 static const struct alc_fixup alc861_fixups[] = {
-	[PINFIX_FSC_AMILO_PI1505] = {
+	[ALC861_FIXUP_FSC_AMILO_PI1505] = {
 		.type = ALC_FIXUP_PINS,
 		.v.pins = (const struct alc_pincfg[]) {
 			{ 0x0b, 0x0221101f }, /* HP */
@@ -5642,17 +6287,29 @@ static const struct alc_fixup alc861_fixups[] = {
 			{ }
 		}
 	},
-	[PINFIX_ASUS_A6RP] = {
+	[ALC861_FIXUP_AMP_VREF_0F] = {
 		.type = ALC_FIXUP_FUNC,
 		.v.func = alc861_fixup_asus_amp_vref_0f,
 	},
+	[ALC861_FIXUP_NO_JACK_DETECT] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc_fixup_no_jack_detect,
+	},
+	[ALC861_FIXUP_ASUS_A6RP] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc861_fixup_asus_amp_vref_0f,
+		.chained = true,
+		.chain_id = ALC861_FIXUP_NO_JACK_DETECT,
+	}
 };
 
 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
-	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP),
-	SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP),	
-	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
-	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
+	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
+	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
+	SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
+	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
+	SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
+	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
 	{}
 };
 
@@ -5679,15 +6336,6 @@ static int patch_alc861(struct hda_codec *codec)
 	if (err < 0)
 		goto error;
 
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	if (!spec->no_analog) {
 		err = snd_hda_attach_beep_device(codec, 0x23);
 		if (err < 0)
@@ -5695,16 +6343,13 @@ static int patch_alc861(struct hda_codec *codec)
 		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
-	spec->init_hook = alc_auto_init_std;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
 	spec->power_hook = alc_power_eapd;
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc861_loopbacks;
 #endif
 
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
+
 	return 0;
 
  error:
@@ -5719,10 +6364,6 @@ static int patch_alc861(struct hda_codec *codec)
  *
  * In addition, an independent DAC
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc861vd_loopbacks	alc880_loopbacks
-#endif
-
 static int alc861vd_parse_auto_config(struct hda_codec *codec)
 {
 	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
@@ -5803,15 +6444,6 @@ static int patch_alc861vd(struct hda_codec *codec)
 		add_verb(spec, alc660vd_eapd_verbs);
 	}
 
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	if (!spec->no_analog) {
 		err = snd_hda_attach_beep_device(codec, 0x23);
 		if (err < 0)
@@ -5819,16 +6451,11 @@ static int patch_alc861vd(struct hda_codec *codec)
 		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
 
-	spec->init_hook = alc_auto_init_std;
 	spec->shutup = alc_eapd_shutup;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc861vd_loopbacks;
-#endif
+
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	return 0;
 
@@ -5848,9 +6475,6 @@ static int patch_alc861vd(struct hda_codec *codec)
  * In addition, an independent DAC for the multi-playback (not used in this
  * driver yet).
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-#define alc662_loopbacks	alc880_loopbacks
-#endif
 
 /*
  * BIOS auto configuration
@@ -5900,6 +6524,7 @@ enum {
 	ALC662_FIXUP_ASUS_MODE6,
 	ALC662_FIXUP_ASUS_MODE7,
 	ALC662_FIXUP_ASUS_MODE8,
+	ALC662_FIXUP_NO_JACK_DETECT,
 };
 
 static const struct alc_fixup alc662_fixups[] = {
@@ -6045,6 +6670,10 @@ static const struct alc_fixup alc662_fixups[] = {
 		.chained = true,
 		.chain_id = ALC662_FIXUP_SKU_IGNORE
 	},
+	[ALC662_FIXUP_NO_JACK_DETECT] = {
+		.type = ALC_FIXUP_FUNC,
+		.v.func = alc_fixup_no_jack_detect,
+	},
 };
 
 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6053,6 +6682,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
 	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
 	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
+	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
 	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
 	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
@@ -6174,15 +6804,6 @@ static int patch_alc662(struct hda_codec *codec)
 	if (err < 0)
 		goto error;
 
-	if (!spec->no_analog && !spec->adc_nids) {
-		alc_auto_fill_adc_caps(codec);
-		alc_rebuild_imux_for_auto_mic(codec);
-		alc_remove_invalid_adc_nids(codec);
-	}
-
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	if (!spec->no_analog && has_cdefine_beep(codec)) {
 		err = snd_hda_attach_beep_device(codec, 0x1);
 		if (err < 0)
@@ -6202,16 +6823,10 @@ static int patch_alc662(struct hda_codec *codec)
 		}
 	}
 
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
-
 	codec->patch_ops = alc_patch_ops;
-	spec->init_hook = alc_auto_init_std;
 	spec->shutup = alc_eapd_shutup;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	if (!spec->loopback.amplist)
-		spec->loopback.amplist = alc662_loopbacks;
-#endif
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
 	return 0;
 
@@ -6251,11 +6866,7 @@ static int patch_alc680(struct hda_codec *codec)
 		return err;
 	}
 
-	if (!spec->no_analog && !spec->cap_mixer)
-		set_capture_mixer(codec);
-
 	codec->patch_ops = alc_patch_ops;
-	spec->init_hook = alc_auto_init_std;
 
 	return 0;
 }
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6345df1..4c76940 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1060,26 +1060,9 @@ static struct snd_kcontrol_new stac_smux_mixer = {
 	.put = stac92xx_smux_enum_put,
 };
 
-static const char * const slave_vols[] = {
-	"Front Playback Volume",
-	"Surround Playback Volume",
-	"Center Playback Volume",
-	"LFE Playback Volume",
-	"Side Playback Volume",
-	"Headphone Playback Volume",
-	"Speaker Playback Volume",
-	NULL
-};
-
-static const char * const slave_sws[] = {
-	"Front Playback Switch",
-	"Surround Playback Switch",
-	"Center Playback Switch",
-	"LFE Playback Switch",
-	"Side Playback Switch",
-	"Headphone Playback Switch",
-	"Speaker Playback Switch",
-	"IEC958 Playback Switch",
+static const char * const slave_pfxs[] = {
+	"Front", "Surround", "Center", "LFE", "Side",
+	"Headphone", "Speaker", "IEC958",
 	NULL
 };
 
@@ -1153,13 +1136,15 @@ static int stac92xx_build_controls(struct hda_codec *codec)
 		/* minimum value is actually mute */
 		vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-					  vmaster_tlv, slave_vols);
+					  vmaster_tlv, slave_pfxs,
+					  "Playback Volume");
 		if (err < 0)
 			return err;
 	}
 	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-					  NULL, slave_sws);
+					  NULL, slave_pfxs,
+					  "Playback Switch");
 		if (err < 0)
 			return err;
 	}
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index dff9a00..c7eb4d7 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1445,25 +1445,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = {
 /*
  * slave controls for virtual master
  */
-static const char * const via_slave_vols[] = {
-	"Front Playback Volume",
-	"Surround Playback Volume",
-	"Center Playback Volume",
-	"LFE Playback Volume",
-	"Side Playback Volume",
-	"Headphone Playback Volume",
-	"Speaker Playback Volume",
-	NULL,
-};
-
-static const char * const via_slave_sws[] = {
-	"Front Playback Switch",
-	"Surround Playback Switch",
-	"Center Playback Switch",
-	"LFE Playback Switch",
-	"Side Playback Switch",
-	"Headphone Playback Switch",
-	"Speaker Playback Switch",
+static const char * const via_slave_pfxs[] = {
+	"Front", "Surround", "Center", "LFE", "Side",
+	"Headphone", "Speaker",
 	NULL,
 };
 
@@ -1508,13 +1492,15 @@ static int via_build_controls(struct hda_codec *codec)
 		snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
 					HDA_OUTPUT, vmaster_tlv);
 		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
-					  vmaster_tlv, via_slave_vols);
+					  vmaster_tlv, via_slave_pfxs,
+					  "Playback Volume");
 		if (err < 0)
 			return err;
 	}
 	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
-					  NULL, via_slave_sws);
+					  NULL, via_slave_pfxs,
+					  "Playback Switch");
 		if (err < 0)
 			return err;
 	}
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 35e662d..b1d4597 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -25,6 +25,9 @@ if SND_SOC
 config SND_SOC_AC97_BUS
 	bool
 
+config SND_SOC_DMAENGINE
+	tristate
+
 # All the supported SoCs
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
@@ -40,6 +43,7 @@ source "sound/soc/kirkwood/Kconfig"
 source "sound/soc/mid-x86/Kconfig"
 source "sound/soc/mxs/Kconfig"
 source "sound/soc/pxa/Kconfig"
+source "sound/soc/sa11x0/Kconfig"
 source "sound/soc/samsung/Kconfig"
 source "sound/soc/s6000/Kconfig"
 source "sound/soc/sh/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 9ea8ac8..7b8ff00 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,7 +1,9 @@
 snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
 snd-soc-core-objs += soc-pcm.o soc-io.o
+snd-soc-dmaengine-objs := soc-dmaengine.o
 
 obj-$(CONFIG_SND_SOC)	+= snd-soc-core.o
+obj-$(CONFIG_SND_SOC_DMAENGINE) += snd-soc-dmaengine.o
 obj-$(CONFIG_SND_SOC)	+= codecs/
 obj-$(CONFIG_SND_SOC)	+= atmel/
 obj-$(CONFIG_SND_SOC)	+= au1x/
@@ -17,6 +19,7 @@ obj-$(CONFIG_SND_SOC)	+= nuc900/
 obj-$(CONFIG_SND_SOC)	+= omap/
 obj-$(CONFIG_SND_SOC)	+= kirkwood/
 obj-$(CONFIG_SND_SOC)	+= pxa/
+obj-$(CONFIG_SND_SOC)	+= sa11x0/
 obj-$(CONFIG_SND_SOC)	+= samsung/
 obj-$(CONFIG_SND_SOC)	+= s6000/
 obj-$(CONFIG_SND_SOC)	+= sh/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index a21ff45..9b84f98 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -362,7 +362,7 @@ static struct snd_pcm_ops atmel_pcm_ops = {
 /*--------------------------------------------------------------------------*\
  * ASoC platform driver
 \*--------------------------------------------------------------------------*/
-static u64 atmel_pcm_dmamask = 0xffffffff;
+static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32);
 
 static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
@@ -373,7 +373,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &atmel_pcm_dmamask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = atmel_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 4ca667d..f65f08b 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -46,29 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int err;
 
-	/* Set codec DAI configuration */
-	err = snd_soc_dai_set_fmt(codec_dai,
-				  SND_SOC_DAIFMT_I2S|
-				  SND_SOC_DAIFMT_NB_IF |
-				  SND_SOC_DAIFMT_CBM_CFM);
-	if (err < 0) {
-		printk(KERN_ERR "can't set codec DAI configuration\n");
-		return err;
-	}
-
-	/* Set cpu DAI configuration */
-	err = snd_soc_dai_set_fmt(cpu_dai,
-				  SND_SOC_DAIFMT_I2S |
-				  SND_SOC_DAIFMT_NB_IF |
-				  SND_SOC_DAIFMT_CBM_CFM);
-	if (err < 0) {
-		printk(KERN_ERR "can't set cpu DAI configuration\n");
-		return err;
-	}
-
 	/* Set the codec system clock for DAC and ADC */
 	err =
 	    snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
@@ -91,7 +70,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
 	SND_SOC_DAPM_MIC("Mic Jack", NULL),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route afeb9260_audio_map[] = {
 	{"Headphone Jack", NULL, "LHPOUT"},
 	{"Headphone Jack", NULL, "RHPOUT"},
 
@@ -106,13 +85,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 
-	/* Add afeb9260 specific widgets */
-	snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
-				  ARRAY_SIZE(tlv320aic23_dapm_widgets));
-
-	/* Set up afeb9260 specific audio path audio_map */
-	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
 	snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
 	snd_soc_dapm_enable_pin(dapm, "Line In");
 	snd_soc_dapm_enable_pin(dapm, "Mic Jack");
@@ -129,6 +101,8 @@ static struct snd_soc_dai_link afeb9260_dai = {
 	.platform_name = "atmel_pcm-audio",
 	.codec_name = "tlv320aic23-codec.0-001a",
 	.init = afeb9260_tlv320aic23_init,
+	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
+		   SND_SOC_DAIFMT_CBM_CFM,
 	.ops = &afeb9260_ops,
 };
 
@@ -138,6 +112,11 @@ static struct snd_soc_card snd_soc_machine_afeb9260 = {
 	.owner = THIS_MODULE,
 	.dai_link = &afeb9260_dai,
 	.num_links = 1,
+
+	.dapm_widgets = tlv320aic23_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
+	.dapm_routes = afeb9260_audio_map,
+	.num_dapm_routes = ARRAY_SIZE(afeb9260_audio_map),
 };
 
 static struct platform_device *afeb9260_snd_device;
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 60962ce..d542d40 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -40,20 +40,8 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
 	int ret = 0;
-	/* set cpu DAI configuration */
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
-		SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
-
-	/* set codec DAI configuration */
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
-		SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
 
 	/* set cpu DAI channel mapping */
 	ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
@@ -68,6 +56,9 @@ static struct snd_soc_ops bf5xx_ad1836_ops = {
 	.hw_params = bf5xx_ad1836_hw_params,
 };
 
+#define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
+				SND_SOC_DAIFMT_CBM_CFM)
+
 static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
 	{
 		.name = "ad1836",
@@ -77,6 +68,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
 		.platform_name = "bfin-tdm-pcm-audio",
 		.codec_name = "spi0.4",
 		.ops = &bf5xx_ad1836_ops,
+		.dai_fmt = BF5XX_AD1836_DAIFMT,
 	},
 	{
 		.name = "ad1836",
@@ -86,6 +78,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
 		.platform_name = "bfin-tdm-pcm-audio",
 		.codec_name = "spi0.4",
 		.ops = &bf5xx_ad1836_ops,
+		.dai_fmt = BF5XX_AD1836_DAIFMT,
 	},
 };
 
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index 2d8d82d..0e55e9f 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -60,18 +60,6 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	/* set cpu DAI configuration */
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
-		SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
-
-	/* set codec DAI configuration */
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
-		SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
-
 	/* set the codec system clock for DAC and ADC */
 	ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
 		SND_SOC_CLOCK_IN);
@@ -92,6 +80,9 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+#define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
+				SND_SOC_DAIFMT_CBM_CFM)
+
 static struct snd_soc_ops bf5xx_ad193x_ops = {
 	.hw_params = bf5xx_ad193x_hw_params,
 };
@@ -105,6 +96,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
 		.platform_name = "bfin-tdm-pcm-audio",
 		.codec_name = "spi0.5",
 		.ops = &bf5xx_ad193x_ops,
+		.dai_fmt = BF5XX_AD193X_DAIFMT,
 	},
 	{
 		.name = "ad193x",
@@ -114,6 +106,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = {
 		.platform_name = "bfin-tdm-pcm-audio",
 		.codec_name = "spi0.5",
 		.ops = &bf5xx_ad193x_ops,
+		.dai_fmt = BF5XX_AD193X_DAIFMT,
 	},
 };
 
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 8e49508..61cc91d 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -145,29 +145,8 @@ static int bf5xx_probe(struct snd_soc_card *card)
 	return 0;
 }
 
-static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	int ret = 0;
-
-	pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
-		params_format(params));
-
-	/* set cpu DAI configuration */
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-
-static struct snd_soc_ops bf5xx_ad73311_ops = {
-	.hw_params = bf5xx_ad73311_hw_params,
-};
+#define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
+				SND_SOC_DAIFMT_CBM_CFM)
 
 static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
 	{
@@ -177,7 +156,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
 		.codec_dai_name = "ad73311-hifi",
 		.platform_name = "bfin-i2s-pcm-audio",
 		.codec_name = "ad73311",
-		.ops = &bf5xx_ad73311_ops,
+		.dai_fmt = BF5XX_AD7311_DAI_FMT,
 	},
 	{
 		.name = "ad73311",
@@ -186,7 +165,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {
 		.codec_dai_name = "ad73311-hifi",
 		.platform_name = "bfin-i2s-pcm-audio",
 		.codec_name = "ad73311",
-		.ops = &bf5xx_ad73311_ops,
+		.dai_fmt = BF5XX_AD7311_DAI_FMT,
 	},
 };
 
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 0303032..df3ac73 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -49,7 +49,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	unsigned int clk = 0;
 	int ret = 0;
 
@@ -75,21 +74,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
 		break;
 	}
 
-	/*
-	 * CODEC is master for BCLK and LRC in this configuration.
-	 */
-
-	/* set codec DAI configuration */
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
-	/* set cpu DAI configuration */
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-		SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret < 0)
-		return ret;
-
 	ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
 		SND_SOC_CLOCK_IN);
 	if (ret < 0)
@@ -102,6 +86,10 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = {
 	.hw_params = bf5xx_ssm2602_hw_params,
 };
 
+/* CODEC is master for BCLK and LRC in this configuration. */
+#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
+				SND_SOC_DAIFMT_CBM_CFM)
+
 static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
 	{
 		.name = "ssm2602",
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 26b271c..f3adbdb 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -67,21 +67,10 @@ static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	int ret;
 	int pll_rate;
 
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret)
-		return ret;
-
 	switch (params_rate(params)) {
 	case 48000:
 	case 8000:
@@ -143,6 +132,8 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = {
 	.codec_name = "adau1373.0-001a",
 	.ops = &bfin_eval_adau1373_ops,
 	.init = bfin_eval_adau1373_codec_init,
+	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBM_CFM,
 };
 
 static struct snd_soc_card bfin_eval_adau1373 = {
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index c0064fa..b0531fc 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -37,20 +37,9 @@ static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	int ret;
 
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret)
-		return ret;
-
 	ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000,
 			SND_SOC_CLOCK_IN);
 
@@ -61,6 +50,9 @@ static struct snd_soc_ops bfin_eval_adau1701_ops = {
 	.hw_params = bfin_eval_adau1701_hw_params,
 };
 
+#define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \
+				SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM)
+
 static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
 	{
 		.name = "adau1701",
@@ -70,6 +62,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
 		.platform_name = "bfin-i2s-pcm-audio",
 		.codec_name = "adau1701.0-0034",
 		.ops = &bfin_eval_adau1701_ops,
+		.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
 	},
 	{
 		.name = "adau1701",
@@ -79,6 +72,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = {
 		.platform_name = "bfin-i2s-pcm-audio",
 		.codec_name = "adau1701.0-0034",
 		.ops = &bfin_eval_adau1701_ops,
+		.dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT,
 	},
 };
 
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 4ef079f..84b0998 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -34,20 +34,9 @@ static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	int ret;
 
-	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
-	if (ret)
-		return ret;
-
 	ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL,
 			27000000, params_rate(params) * 256);
 	if (ret)
@@ -88,6 +77,8 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = {
 		.platform_name = "bfin-i2s-pcm-audio",
 		.init = bfin_eval_adav80x_codec_init,
 		.ops = &bfin_eval_adav80x_ops,
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+				SND_SOC_DAIFMT_CBM_CFM,
 	},
 };
 
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 7c205e7..59d8efa 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_MAX98088 if I2C
 	select SND_SOC_MAX98095 if I2C
 	select SND_SOC_MAX9850 if I2C
+	select SND_SOC_MAX9768 if I2C
 	select SND_SOC_MAX9877 if I2C
 	select SND_SOC_PCM3008
 	select SND_SOC_RT5631 if I2C
@@ -56,12 +57,13 @@ config SND_SOC_ALL_CODECS
 	select SND_SOC_TPA6130A2 if I2C
 	select SND_SOC_TLV320DAC33 if I2C
 	select SND_SOC_TWL4030 if TWL4030_CORE
-	select SND_SOC_TWL6040 if TWL4030_CORE
+	select SND_SOC_TWL6040 if TWL6040_CORE
 	select SND_SOC_UDA134X
 	select SND_SOC_UDA1380 if I2C
 	select SND_SOC_WL1273 if MFD_WL1273_CORE
 	select SND_SOC_WM1250_EV1 if I2C
 	select SND_SOC_WM2000 if I2C
+	select SND_SOC_WM2200 if I2C
 	select SND_SOC_WM5100 if I2C
 	select SND_SOC_WM8350 if MFD_WM8350
 	select SND_SOC_WM8400 if MFD_WM8400
@@ -274,7 +276,6 @@ config SND_SOC_TWL4030
 	tristate
 
 config SND_SOC_TWL6040
-	select TWL6040_CORE
 	tristate
 
 config SND_SOC_UDA134X
@@ -292,6 +293,9 @@ config SND_SOC_WM1250_EV1
 config SND_SOC_WM2000
 	tristate
 
+config SND_SOC_WM2200
+	tristate
+
 config SND_SOC_WM5100
 	tristate
 
@@ -425,6 +429,9 @@ config SND_SOC_WM9713
 config SND_SOC_LM4857
 	tristate
 
+config SND_SOC_MAX9768
+	tristate
+
 config SND_SOC_MAX9877
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index de80781..6662eb0 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o
 snd-soc-jz4740-codec-objs := jz4740.o
 snd-soc-l3-objs := l3.o
 snd-soc-lm4857-objs := lm4857.o
+snd-soc-max9768-objs := max9768.o
 snd-soc-max98088-objs := max98088.o
 snd-soc-max98095-objs := max98095.o
 snd-soc-max9850-objs := max9850.o
@@ -51,6 +52,7 @@ snd-soc-uda1380-objs := uda1380.o
 snd-soc-wl1273-objs := wl1273.o
 snd-soc-wm1250-ev1-objs := wm1250-ev1.o
 snd-soc-wm2000-objs := wm2000.o
+snd-soc-wm2200-objs := wm2200.o
 snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
 snd-soc-wm8350-objs := wm8350.o
 snd-soc-wm8400-objs := wm8400.o
@@ -129,6 +131,7 @@ obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_L3)	+= snd-soc-l3.o
 obj-$(CONFIG_SND_SOC_LM4857)	+= snd-soc-lm4857.o
 obj-$(CONFIG_SND_SOC_JZ4740_CODEC)	+= snd-soc-jz4740-codec.o
+obj-$(CONFIG_SND_SOC_MAX9768)	+= snd-soc-max9768.o
 obj-$(CONFIG_SND_SOC_MAX98088)	+= snd-soc-max98088.o
 obj-$(CONFIG_SND_SOC_MAX98095)	+= snd-soc-max98095.o
 obj-$(CONFIG_SND_SOC_MAX9850)	+= snd-soc-max9850.o
@@ -153,6 +156,7 @@ obj-$(CONFIG_SND_SOC_UDA1380)	+= snd-soc-uda1380.o
 obj-$(CONFIG_SND_SOC_WL1273)	+= snd-soc-wl1273.o
 obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
 obj-$(CONFIG_SND_SOC_WM2000)	+= snd-soc-wm2000.o
+obj-$(CONFIG_SND_SOC_WM2200)	+= snd-soc-wm2200.o
 obj-$(CONFIG_SND_SOC_WM5100)	+= snd-soc-wm5100.o
 obj-$(CONFIG_SND_SOC_WM8350)	+= snd-soc-wm8350.o
 obj-$(CONFIG_SND_SOC_WM8400)	+= snd-soc-wm8400.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 982d201..12e3b41 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 	if (ad1836->type == AD1836) {
 		/* left/right diff:PGA/MUX */
 		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
-		ret = snd_soc_add_controls(codec, ad1836_controls,
+		ret = snd_soc_add_codec_controls(codec, ad1836_controls,
 				ARRAY_SIZE(ad1836_controls));
 		if (ret)
 			return ret;
@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec)
 		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
 	}
 
-	ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2);
+	ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
 	if (ret)
 		return ret;
 
-	ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs);
+	ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs);
 	if (ret)
 		return ret;
 
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 9bba7f8..8c39ddd 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -228,7 +228,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
 	ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
 	ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
 
-	snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
+	snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls,
 				ARRAY_SIZE(ad1980_snd_ac97_controls));
 
 	return 0;
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 971ba45..44f5906 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
-	codec->dapm.idle_bias_off = true;
-
 	if (pdata) {
 		if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting))
 			return -EINVAL;
@@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
 				pdata->drc_setting[i]);
 		}
 
-		snd_soc_add_controls(codec, adau1373_drc_controls,
+		snd_soc_add_codec_controls(codec, adau1373_drc_controls,
 			pdata->num_drc);
 
 		val = 0;
@@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
 	}
 
 	if (!lineout_differential) {
-		snd_soc_add_controls(codec, adau1373_lineout2_controls,
+		snd_soc_add_codec_controls(codec, adau1373_lineout2_controls,
 			ARRAY_SIZE(adau1373_lineout2_controls));
 	}
 
@@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
 	.suspend =	adau1373_suspend,
 	.resume =	adau1373_resume,
 	.set_bias_level = adau1373_set_bias_level,
+	.idle_bias_off = true,
 	.reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
 	.reg_cache_default = adau1373_default_regs,
 	.reg_word_size = sizeof(uint8_t),
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 6b325ea..78e9ce4 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 {
 	int ret;
 
-	codec->dapm.idle_bias_off = 1;
 	codec->control_data = to_i2c_client(codec->dev);
 
 	ret = adau1701_load_firmware(codec);
@@ -473,6 +472,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver adau1701_codec_drv = {
 	.probe			= adau1701_probe,
 	.set_bias_level		= adau1701_set_bias_level,
+	.idle_bias_off		= true,
 
 	.reg_cache_size		= ADAU1701_NUM_REGS,
 	.reg_word_size		= sizeof(u16),
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index d27b5e4..f12c115 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -224,7 +224,6 @@ static int ak4104_probe(struct snd_soc_codec *codec)
 	if (ret < 0)
 		return ret;
 
-	dev_info(codec->dev, "SPI device initialized\n");
 	return 0;
 }
 
@@ -290,17 +289,7 @@ static struct spi_driver ak4104_spi_driver = {
 	.remove = __devexit_p(ak4104_spi_remove),
 };
 
-static int __init ak4104_init(void)
-{
-	return spi_register_driver(&ak4104_spi_driver);
-}
-module_init(ak4104_init);
-
-static void __exit ak4104_exit(void)
-{
-	spi_unregister_driver(&ak4104_spi_driver);
-}
-module_exit(ak4104_exit);
+module_spi_driver(ak4104_spi_driver);
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 9e809e0..838ae8b 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -27,24 +28,43 @@
 
 #include "ak4535.h"
 
-#define AK4535_VERSION "0.3"
-
 /* codec private data */
 struct ak4535_priv {
+	struct regmap *regmap;
 	unsigned int sysclk;
-	enum snd_soc_control_type control_type;
 };
 
 /*
  * ak4535 register cache
  */
-static const u8 ak4535_reg[AK4535_CACHEREGNUM] = {
-	0x00, 0x80, 0x00, 0x03,
-	0x02, 0x00, 0x11, 0x01,
-	0x00, 0x40, 0x36, 0x10,
-	0x00, 0x00, 0x57, 0x00,
+static const struct reg_default ak4535_reg_defaults[] = {
+	{ 0, 0x00 },
+	{ 1, 0x80 },
+	{ 2, 0x00 },
+	{ 3, 0x03 },
+	{ 4, 0x02 },
+	{ 5, 0x00 },
+	{ 6, 0x11 },
+	{ 7, 0x01 },
+	{ 8, 0x00 },
+	{ 9, 0x40 },
+	{ 10, 0x36 },
+	{ 11, 0x10 },
+	{ 12, 0x00 },
+	{ 13, 0x00 },
+	{ 14, 0x57 },
 };
 
+static bool ak4535_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case AK4535_STATUS:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"};
 static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"};
 static const char *ak4535_hp_out[] = {"Stereo", "Mono"};
@@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec)
 	struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
-	printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION);
-
-	ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type);
+	codec->control_data = ak4535->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec)
 	/* power on device */
 	ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-	snd_soc_add_controls(codec, ak4535_snd_controls,
+	snd_soc_add_codec_controls(codec, ak4535_snd_controls,
 				ARRAY_SIZE(ak4535_snd_controls));
 	return 0;
 }
@@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec)
 	return 0;
 }
 
+static const struct regmap_config ak4535_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = AK4535_STATUS,
+	.volatile_reg = ak4535_volatile,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = ak4535_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults),
+};
+
 static struct snd_soc_codec_driver soc_codec_dev_ak4535 = {
 	.probe =	ak4535_probe,
 	.remove =	ak4535_remove,
 	.suspend =	ak4535_suspend,
 	.resume =	ak4535_resume,
 	.set_bias_level = ak4535_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(ak4535_reg),
-	.reg_word_size = sizeof(u8),
-	.reg_cache_default = ak4535_reg,
 	.dapm_widgets = ak4535_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets),
 	.dapm_routes = ak4535_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(ak4535_audio_map),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
@@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c,
 	if (ak4535 == NULL)
 		return -ENOMEM;
 
+	ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap);
+	if (IS_ERR(ak4535->regmap)) {
+		ret = PTR_ERR(ak4535->regmap);
+		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, ak4535);
-	ak4535->control_type = SND_SOC_I2C;
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_ak4535, &ak4535_dai, 1);
+	if (ret != 0)
+		regmap_exit(ak4535->regmap);
+
 	return ret;
 }
 
 static __devexit int ak4535_i2c_remove(struct i2c_client *client)
 {
+	struct ak4535_priv *ak4535 = i2c_get_clientdata(client);
+
 	snd_soc_unregister_codec(&client->dev);
+	regmap_exit(ak4535->regmap);
 	return 0;
 }
 
@@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id);
 
 static struct i2c_driver ak4535_i2c_driver = {
 	.driver = {
-		.name = "ak4535-codec",
+		.name = "ak4535",
 		.owner = THIS_MODULE,
 	},
 	.probe =    ak4535_i2c_probe,
 	.remove =   __devexit_p(ak4535_i2c_remove),
 	.id_table = ak4535_i2c_id,
 };
-#endif
 
-static int __init ak4535_modinit(void)
-{
-	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	ret = i2c_add_driver(&ak4535_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n",
-		       ret);
-	}
-#endif
-	return ret;
-}
-module_init(ak4535_modinit);
-
-static void __exit ak4535_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	i2c_del_driver(&ak4535_i2c_driver);
-#endif
-}
-module_exit(ak4535_exit);
+module_i2c_driver(ak4535_i2c_driver);
 
 MODULE_DESCRIPTION("Soc AK4535 driver");
 MODULE_AUTHOR("Richard Purdie");
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h
index 0431e5f..402de1d 100644
--- a/sound/soc/codecs/ak4535.h
+++ b/sound/soc/codecs/ak4535.h
@@ -34,6 +34,4 @@
 #define AK4535_VOL		0xe
 #define AK4535_STATUS		0xf
 
-#define AK4535_CACHEREGNUM 	0x10
-
 #endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 5ef70b5..f8e10ce 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -146,13 +146,10 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 
 	SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
 			 0, 0xFF, 1, out_tlv),
-
-	SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
 };
 
-static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
-	SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
-};
+static const struct snd_kcontrol_new ak4642_headphone_control =
+	SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0);
 
 static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
 	SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
@@ -165,13 +162,12 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
 	SND_SOC_DAPM_OUTPUT("HPOUTR"),
 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
 
-	SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
-			   &ak4642_hpout_mixer_controls[0],
-			   ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+	SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0),
+	SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0,
+			    &ak4642_headphone_control),
 
-	SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
-			   &ak4642_hpout_mixer_controls[0],
-			   ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+	SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
 
 	SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
 			   &ak4642_lout_mixer_controls[0],
@@ -184,12 +180,17 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
 static const struct snd_soc_dapm_route ak4642_intercon[] = {
 
 	/* Outputs */
-	{"HPOUTL", NULL, "HPOUTL Mixer"},
-	{"HPOUTR", NULL, "HPOUTR Mixer"},
+	{"HPOUTL", NULL, "HPL Out"},
+	{"HPOUTR", NULL, "HPR Out"},
 	{"LINEOUT", NULL, "LINEOUT Mixer"},
 
-	{"HPOUTL Mixer", "DACH", "DAC"},
-	{"HPOUTR Mixer", "DACH", "DAC"},
+	{"HPL Out", NULL, "Headphone Enable"},
+	{"HPR Out", NULL, "Headphone Enable"},
+
+	{"Headphone Enable", "Switch", "DACH"},
+
+	{"DACH", NULL, "DAC"},
+
 	{"LINEOUT Mixer", "DACL", "DAC"},
 };
 
@@ -476,7 +477,7 @@ static int ak4642_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
-	snd_soc_add_controls(codec, ak4642_snd_controls,
+	snd_soc_add_codec_controls(codec, ak4642_snd_controls,
 			     ARRAY_SIZE(ak4642_snd_controls));
 
 	ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index a53b152..5fb7c2a 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
-	snd_soc_add_controls(codec, ak4671_snd_controls,
+	snd_soc_add_codec_controls(codec, ak4671_snd_controls,
 			     ARRAY_SIZE(ak4671_snd_controls));
 
 	ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index 3feee56..d47b62d 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec)
 
 	switch (alc5623->id) {
 	case 0x21:
-		snd_soc_add_controls(codec, alc5621_vol_snd_controls,
+		snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls,
 			ARRAY_SIZE(alc5621_vol_snd_controls));
 		break;
 	case 0x22:
-		snd_soc_add_controls(codec, alc5622_vol_snd_controls,
+		snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls,
 			ARRAY_SIZE(alc5622_vol_snd_controls));
 		break;
 	case 0x23:
-		snd_soc_add_controls(codec, alc5623_vol_snd_controls,
+		snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls,
 			ARRAY_SIZE(alc5623_vol_snd_controls));
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	snd_soc_add_controls(codec, alc5623_snd_controls,
+	snd_soc_add_codec_controls(codec, alc5623_snd_controls,
 			ARRAY_SIZE(alc5623_snd_controls));
 
 	snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
@@ -992,7 +992,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
  *    low  = 0x1a
  *    high = 0x1b
  */
-static int alc5623_i2c_probe(struct i2c_client *client,
+static __devinit int alc5623_i2c_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
 	struct alc5623_platform_data *pdata;
@@ -1059,7 +1059,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
 	return ret;
 }
 
-static int alc5623_i2c_remove(struct i2c_client *client)
+static __devexit int alc5623_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
 	return 0;
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index 390e437..e2111e0 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
 /* -16.5db min scale, 1.5db steps, no mute */
 static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
 static const unsigned int boost_tlv[] = {
-	TLV_DB_RANGE_HEAD(3),
-	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
-	1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
-	2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
+	TLV_DB_RANGE_HEAD(2),
+	0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),
+	1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0),
 };
 /* 0db min scale, 6 db steps, no mute */
 static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
 /* 0db min scalem 0.75db steps, no mute */
-static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0);
+static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0);
 
 static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = {
 	/* left starts at bit 8, right at bit 0 */
@@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = {
 			ALC5632_AUX_OUT_VOL, 15, 7, 1, 1),
 	SOC_SINGLE_TLV("Voice DAC Playback Volume",
 			ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv),
-	SOC_SINGLE_TLV("Phone Capture Volume",
+	SOC_SINGLE("Voice DAC Playback Switch",
+			ALC5632_VOICE_DAC_VOL, 12, 1, 1),
+	SOC_SINGLE_TLV("Phone Playback Volume",
 			ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv),
-	SOC_DOUBLE_TLV("LineIn Capture Volume",
+	SOC_DOUBLE_TLV("LineIn Playback Volume",
 			ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
 	SOC_DOUBLE_TLV("Master Playback Volume",
 			ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv),
 	SOC_DOUBLE("Master Playback Switch",
 			ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1),
-	SOC_SINGLE_TLV("Mic1 Capture Volume",
+	SOC_SINGLE_TLV("Mic1 Playback Volume",
 			ALC5632_MIC_VOL, 8, 31, 1, vol_tlv),
-	SOC_SINGLE_TLV("Mic2 Capture Volume",
+	SOC_SINGLE_TLV("Mic2 Playback Volume",
 			ALC5632_MIC_VOL, 0, 31, 1, vol_tlv),
 	SOC_DOUBLE_TLV("Rec Capture Volume",
 			ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv),
 	SOC_SINGLE_TLV("Mic 1 Boost Volume",
-			ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv),
+			ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv),
 	SOC_SINGLE_TLV("Mic 2 Boost Volume",
-			ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv),
-	SOC_SINGLE_TLV("Digital Boost Volume",
+			ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv),
+	SOC_SINGLE_TLV("DMIC Boost Capture Volume",
 			ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv),
+	SOC_SINGLE("DMIC En Capture Switch",
+			ALC5632_DIGI_BOOST_CTRL, 15, 1, 0),
+	SOC_SINGLE("DMIC PreFilter Capture Switch",
+			ALC5632_DIGI_BOOST_CTRL, 12, 1, 0),
 };
 
 /*
@@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1),
 
 /* Left Record Mixer */
 static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
-SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
-SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
-SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
-SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
-SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
+SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1),
+SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1),
+SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1),
+SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1),
+SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1),
+SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1),
+SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1),
 };
 
 /* Right Record Mixer */
 static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = {
-SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
-SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
-SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
-SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
-SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
-SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
-SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
+SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1),
+SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1),
+SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1),
+SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1),
+SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1),
+SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1),
+SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1),
 };
 
-static const char *alc5632_spk_n_sour_sel[] = {
+/* Dmic Mixer */
+static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = {
+SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1),
+};
+static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = {
+SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1),
+};
+
+static const char * const alc5632_spk_n_sour_sel[] = {
 		"RN/-R", "RP/+R", "LN/-R", "Mute"};
-static const char *alc5632_hpl_out_input_sel[] = {
+static const char * const alc5632_hpl_out_input_sel[] = {
 		"Vmid", "HP Left Mix"};
-static const char *alc5632_hpr_out_input_sel[] = {
+static const char * const alc5632_hpr_out_input_sel[] = {
 		"Vmid", "HP Right Mix"};
-static const char *alc5632_spkout_input_sel[] = {
+static const char * const alc5632_spkout_input_sel[] = {
 		"Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
-static const char *alc5632_aux_out_input_sel[] = {
+static const char * const alc5632_aux_out_input_sel[] = {
 		"Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
+static const char * const alc5632_adcr_func_sel[] = {
+		"Stereo ADC", "Voice ADC"};
+static const char * const alc5632_i2s_out_sel[] = {
+		"ADC LR", "Voice Stereo Digital"};
 
 /* auxout output mux */
 static const struct soc_enum alc5632_aux_out_input_enum =
@@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum =
 static const struct snd_kcontrol_new alc5632_amp_mux_controls =
 	SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum);
 
+/* ADC output select */
+static const struct soc_enum alc5632_adcr_func_enum =
+	SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel);
+static const struct snd_kcontrol_new alc5632_adcr_func_controls =
+	SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum);
+
+/* I2S out select */
+static const struct soc_enum alc5632_i2s_out_enum =
+	SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel);
+static const struct snd_kcontrol_new alc5632_i2s_out_controls =
+	SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum);
 
 static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = {
 /* Muxes */
@@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
 	&alc5632_hpr_out_mux_controls),
 SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
 	&alc5632_spkoutn_mux_controls),
+SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
+	&alc5632_adcr_func_controls),
+SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0,
+	&alc5632_i2s_out_controls),
 
 /* output mixers */
 SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
@@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0,
 SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0,
 	&alc5632_speaker_mixer_controls[0],
 	ARRAY_SIZE(alc5632_speaker_mixer_controls)),
+SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0,
+	&alc5632_dmicl_mixer_controls[0],
+	ARRAY_SIZE(alc5632_dmicl_mixer_controls)),
+SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0,
+	&alc5632_dmicr_mixer_controls[0],
+	ARRAY_SIZE(alc5632_dmicr_mixer_controls)),
 
 /* input mixers */
 SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0,
@@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0,
 	&alc5632_captureR_mixer_controls[0],
 	ARRAY_SIZE(alc5632_captureR_mixer_controls)),
 
-SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback",
-	ALC5632_PWR_MANAG_ADD2, 9, 0),
-SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback",
-	ALC5632_PWR_MANAG_ADD2, 8, 0),
+SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0),
+
+SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0),
+SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0),
+SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0),
+SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0),
+SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0),
+
 SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("DAC Right Channel",
 	ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
 SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
-SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture",
-	ALC5632_PWR_MANAG_ADD2, 7, 0),
-SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture",
-	ALC5632_PWR_MANAG_ADD2, 6, 0),
+SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
+SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0),
+
 SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0),
 SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0),
 SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0),
@@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"),
 SND_SOC_DAPM_OUTPUT("HPR"),
 SND_SOC_DAPM_OUTPUT("SPKOUT"),
 SND_SOC_DAPM_OUTPUT("SPKOUTN"),
+
 SND_SOC_DAPM_INPUT("LINEINL"),
 SND_SOC_DAPM_INPUT("LINEINR"),
 SND_SOC_DAPM_INPUT("PHONEP"),
 SND_SOC_DAPM_INPUT("PHONEN"),
+SND_SOC_DAPM_INPUT("DMICDAT"),
 SND_SOC_DAPM_INPUT("MIC1"),
 SND_SOC_DAPM_INPUT("MIC2"),
 SND_SOC_DAPM_VMID("Vmid"),
@@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"),
 
 
 static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
+	/* Playback streams */
+	{"Left DAC", NULL, "AIFRXL"},
+	{"Right DAC", NULL, "AIFRXR"},
+
 	/* virtual mixer - mixes left & right channels */
 	{"I2S Mix",	NULL,	"Left DAC"},
 	{"I2S Mix",	NULL,	"Right DAC"},
@@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
 	{"HP Mix",	"PHONE2HP Playback Switch",	"Phone Mix"},
 	{"HP Mix",	"MIC12HP Playback Switch",	"MIC1 PGA"},
 	{"HP Mix",	"MIC22HP Playback Switch",	"MIC2 PGA"},
-
+	{"HP Mix", "VOICE2HP Playback Switch",	"Voice Mix"},
 	{"HPR Mix", "DACR2HP Playback Switch",	"DAC Right Channel"},
 	{"HPL Mix", "DACL2HP Playback Switch",	"DAC Left Channel"},
+	{"HPOut Mix", NULL, "HP Mix"},
+	{"HPOut Mix", NULL, "HPR Mix"},
+	{"HPOut Mix", NULL, "HPL Mix"},
 
 	/* speaker mixer */
 	{"Speaker Mix", "LI2SPK Playback Switch",	"Line Mix"},
@@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
 	{"Speaker Mix", "MIC12SPK Playback Switch",	"MIC1 PGA"},
 	{"Speaker Mix", "MIC22SPK Playback Switch",	"MIC2 PGA"},
 	{"Speaker Mix", "DAC2SPK Playback Switch",	"DAC Left Channel"},
-
-
+	{"Speaker Mix", "VOICE2SPK Playback Switch",	"Voice Mix"},
 
 	/* mono mixer */
 	{"Mono Mix", "ADC2MONO_L Playback Switch",	"Left Capture Mix"},
 	{"Mono Mix", "ADC2MONO_R Playback Switch",	"Right Capture Mix"},
 	{"Mono Mix", "LI2MONO Playback Switch",		"Line Mix"},
-	{"Mono Mix", "VOICE2MONO Playback Switch",	"Phone Mix"},
 	{"Mono Mix", "MIC12MONO Playback Switch",	"MIC1 PGA"},
 	{"Mono Mix", "MIC22MONO Playback Switch",	"MIC2 PGA"},
 	{"Mono Mix", "DAC2MONO Playback Switch",	"DAC Left Channel"},
+	{"Mono Mix", "VOICE2MONO Playback Switch",	"Voice Mix"},
 
 	/* Left record mixer */
-	{"Left Capture Mix", "LineInL Capture Switch",	"LINEINL"},
-	{"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"},
-	{"Left Capture Mix", "Mic1 Capture Switch",	"MIC1 Pre Amp"},
-	{"Left Capture Mix", "Mic2 Capture Switch",	"MIC2 Pre Amp"},
-	{"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
-	{"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
-	{"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+	{"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"},
+	{"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"},
+	{"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"},
+	{"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"},
+	{"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"},
+	{"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"},
+	{"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"},
 
 	/*Right record mixer */
-	{"Right Capture Mix", "LineInR Capture Switch",	"LINEINR"},
-	{"Right Capture Mix", "Right Phone Capture Switch",	"PHONEP"},
-	{"Right Capture Mix", "Mic1 Capture Switch",	"MIC1 Pre Amp"},
-	{"Right Capture Mix", "Mic2 Capture Switch",	"MIC2 Pre Amp"},
-	{"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
-	{"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
-	{"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
+	{"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"},
+	{"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"},
+	{"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"},
+	{"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"},
+	{"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"},
+	{"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"},
+	{"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"},
 
 	/* headphone left mux */
 	{"Left Headphone Mux", "HP Left Mix",		"HPL Mix"},
@@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = {
 
 	/* left ADC */
 	{"Left ADC", NULL,				"Left Capture Mix"},
+	{"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"},
+	{"Left ADC", NULL,				"DMICL Mix"},
+	{"ADCLR", NULL,					"Left ADC"},
 
 	/* right ADC */
-	{"Right ADC", NULL,				"Right Capture Mix"},
-
+	{"Right ADC", NULL, "Right Capture Mix"},
+	{"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"},
+	{"Right ADC", NULL, "DMICR Mix"},
+	{"ADCR Mux", "Stereo ADC", "Right ADC"},
+	{"ADCR Mux", "Voice ADC", "Right ADC"},
+	{"ADCLR", NULL, "ADCR Mux"},
+	{"VAIFTX", NULL, "ADCR Mux"},
+
+	/* Digital I2S out */
+	{"I2SOut Mux", "ADC LR", "ADCLR"},
+	{"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"},
+	{"AIFTXL", NULL, "I2SOut Mux"},
+	{"AIFTXR", NULL, "I2SOut Mux"},
+
+	/* Voice Mix */
+	{"Voice DAC", NULL, "VAIFRX"},
+	{"Voice Mix", NULL, "Voice DAC"},
+
+	/* Speaker Output */
 	{"SpeakerOut N Mux", "RN/-R",			"Left Speaker"},
 	{"SpeakerOut N Mux", "RP/+R",			"Left Speaker"},
 	{"SpeakerOut N Mux", "LN/-R",			"Left Speaker"},
@@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec);
 
 	switch (freq) {
+	case  4096000:
 	case  8192000:
 	case 11289600:
 	case 12288000:
@@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
 
 	switch (alc5632->id) {
 	case 0x5c:
-		snd_soc_add_controls(codec, alc5632_vol_snd_controls,
+		snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls,
 			ARRAY_SIZE(alc5632_vol_snd_controls));
 		break;
 	default:
@@ -1109,7 +1184,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
 	return ret;
 }
 
-static int alc5632_i2c_remove(struct i2c_client *client)
+static __devexit int alc5632_i2c_remove(struct i2c_client *client)
 {
 	struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
 	snd_soc_unregister_codec(&client->dev);
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h
index 357651e..1b5bda5 100644
--- a/sound/soc/codecs/alc5632.h
+++ b/sound/soc/codecs/alc5632.h
@@ -51,6 +51,7 @@
 #define ALC5632_ADC_REC_MONOMIX			(1 << 0)
 
 #define ALC5632_VOICE_DAC_VOL			0x18 /* voice dac vol */
+#define ALC5632_I2S_OUT_CTL				0x1A /* undocumented reg. found in path scheme */
 /* ALC5632_OUTPUT_MIXER_CTRL :			*/
 /* same remark as for reg 2 line vs speaker	*/
 #define ALC5632_OUTPUT_MIXER_CTRL		0x1C /* out mix ctrl */
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 4854b47..064cd6a 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -38,8 +38,6 @@
 #include <sound/soc.h>
 #include <sound/initval.h>
 
-#include <mach/dm365.h>
-
 static inline unsigned int cq93vc_read(struct snd_soc_codec *codec,
 						unsigned int reg)
 {
@@ -159,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec)
 	codec->control_data = davinci_vc;
 
 	/* Set controls */
-	snd_soc_add_controls(codec, cq93vc_snd_controls,
+	snd_soc_add_codec_controls(codec, cq93vc_snd_controls,
 			     ARRAY_SIZE(cq93vc_snd_controls));
 
 	/* Off, with power on */
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 0555366..6baccd2 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec)
 	}
 
 	/* Add the non-DAPM controls */
-	ret = snd_soc_add_controls(codec, cs4270_snd_controls,
+	ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
 				ARRAY_SIZE(cs4270_snd_controls));
 	if (ret < 0) {
 		dev_err(codec->dev, "failed to add controls\n");
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index f6fe846..bf71412 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
 	/* Power-up sequence requires 85 uS */
 	udelay(85);
 
-	return snd_soc_add_controls(codec, cs4271_snd_controls,
+	return snd_soc_add_codec_controls(codec, cs4271_snd_controls,
 		ARRAY_SIZE(cs4271_snd_controls));
 }
 
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 3190392..ba4fafb 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec)
 
 	codec->control_data = lm4857->i2c;
 
-	ret = snd_soc_add_controls(codec, lm4857_controls,
+	ret = snd_soc_add_codec_controls(codec, lm4857_controls,
 			ARRAY_SIZE(lm4857_controls));
 	if (ret)
 		return ret;
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
new file mode 100644
index 0000000..17b3ec2
--- /dev/null
+++ b/sound/soc/codecs/max9768.c
@@ -0,0 +1,247 @@
+/*
+ * MAX9768 AMP driver
+ *
+ * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
+ *
+ * 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; version 2 of the License.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/regmap.h>
+
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <sound/max9768.h>
+
+/* "Registers" */
+#define MAX9768_VOL 0
+#define MAX9768_CTRL 3
+
+/* Commands */
+#define MAX9768_CTRL_PWM 0x15
+#define MAX9768_CTRL_FILTERLESS 0x16
+
+struct max9768 {
+	struct regmap *regmap;
+	int mute_gpio;
+	int shdn_gpio;
+	u32 flags;
+};
+
+static struct reg_default max9768_default_regs[] = {
+	{ 0, 0 },
+	{ 3,  MAX9768_CTRL_FILTERLESS},
+};
+
+static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
+	int val = gpio_get_value_cansleep(max9768->mute_gpio);
+
+	ucontrol->value.integer.value[0] = !val;
+
+	return 0;
+}
+
+static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
+	struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
+
+	gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
+
+	return 0;
+}
+
+static const unsigned int volume_tlv[] = {
+	TLV_DB_RANGE_HEAD(43),
+	0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
+	1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
+	2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
+	3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
+	4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
+	5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
+	6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
+	7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
+	8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
+	9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
+	10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
+	11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
+	12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
+	13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
+	14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
+	15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
+	18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
+	19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
+	20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
+	21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
+	22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
+	23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
+	24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
+	25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
+	26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
+	27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
+	28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
+	31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
+	32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
+	35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
+	38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
+	40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
+	41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
+	42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
+	43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
+	44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
+	45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
+	46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
+	47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
+	51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
+	58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
+	59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
+	63, 63, TLV_DB_SCALE_ITEM(950, 0, 0),
+};
+
+static const struct snd_kcontrol_new max9768_volume[] = {
+	SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
+};
+
+static const struct snd_kcontrol_new max9768_mute[] = {
+	SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
+};
+
+static int max9768_probe(struct snd_soc_codec *codec)
+{
+	struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
+	int ret;
+
+	codec->control_data = max9768->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP);
+	if (ret)
+		return ret;
+
+	if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
+		ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM);
+		if (ret)
+			return ret;
+	}
+
+	if (gpio_is_valid(max9768->mute_gpio)) {
+		ret = snd_soc_add_codec_controls(codec, max9768_mute,
+				ARRAY_SIZE(max9768_mute));
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_codec_driver max9768_codec_driver = {
+	.probe = max9768_probe,
+	.controls = max9768_volume,
+	.num_controls = ARRAY_SIZE(max9768_volume),
+};
+
+static const struct regmap_config max9768_i2c_regmap_config = {
+	.reg_bits = 2,
+	.val_bits = 6,
+	.max_register = 3,
+	.reg_defaults = max9768_default_regs,
+	.num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int __devinit max9768_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	struct max9768 *max9768;
+	struct max9768_pdata *pdata = client->dev.platform_data;
+	int err;
+
+	max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
+	if (!max9768)
+		return -ENOMEM;
+
+	if (pdata) {
+		/* Mute on powerup to avoid clicks */
+		err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute");
+		max9768->mute_gpio = err ?: pdata->mute_gpio;
+
+		/* Activate chip by releasing shutdown, enables I2C */
+		err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown");
+		max9768->shdn_gpio = err ?: pdata->shdn_gpio;
+
+		max9768->flags = pdata->flags;
+	} else {
+		max9768->shdn_gpio = -EINVAL;
+		max9768->mute_gpio = -EINVAL;
+	}
+
+	i2c_set_clientdata(client, max9768);
+
+	max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config);
+	if (IS_ERR(max9768->regmap)) {
+		err = PTR_ERR(max9768->regmap);
+		goto err_gpio_free;
+	}
+
+	err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0);
+	if (err)
+		goto err_regmap_free;
+
+	return 0;
+
+ err_regmap_free:
+	regmap_exit(max9768->regmap);
+ err_gpio_free:
+	if (gpio_is_valid(max9768->shdn_gpio))
+		gpio_free(max9768->shdn_gpio);
+	if (gpio_is_valid(max9768->mute_gpio))
+		gpio_free(max9768->mute_gpio);
+
+	return err;
+}
+
+static int __devexit max9768_i2c_remove(struct i2c_client *client)
+{
+	struct max9768 *max9768 = i2c_get_clientdata(client);
+
+	snd_soc_unregister_codec(&client->dev);
+	regmap_exit(max9768->regmap);
+
+	if (gpio_is_valid(max9768->shdn_gpio))
+		gpio_free(max9768->shdn_gpio);
+	if (gpio_is_valid(max9768->mute_gpio))
+		gpio_free(max9768->mute_gpio);
+
+	return 0;
+}
+
+static const struct i2c_device_id max9768_i2c_id[] = {
+	{ "max9768", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
+
+static struct i2c_driver max9768_i2c_driver = {
+	.driver = {
+		.name = "max9768",
+		.owner = THIS_MODULE,
+	},
+	.probe = max9768_i2c_probe,
+	.remove = __devexit_p(max9768_i2c_remove),
+	.id_table = max9768_i2c_id,
+};
+module_i2c_driver(max9768_i2c_driver);
+
+MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
+MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 006efcf..af7324b 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1908,7 +1908,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec)
        max98088->eq_enum.texts = max98088->eq_texts;
        max98088->eq_enum.max = max98088->eq_textcnt;
 
-       ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
+       ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
        if (ret != 0)
                dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
 }
@@ -2030,7 +2030,7 @@ static int max98088_probe(struct snd_soc_codec *codec)
 
        max98088_handle_pdata(codec);
 
-       snd_soc_add_controls(codec, max98088_snd_controls,
+       snd_soc_add_codec_controls(codec, max98088_snd_controls,
                             ARRAY_SIZE(max98088_snd_controls));
 
 err_access:
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index fcfa749..0bb511a 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = {
 
 static int max98095_add_widgets(struct snd_soc_codec *codec)
 {
-	snd_soc_add_controls(codec, max98095_snd_controls,
+	snd_soc_add_codec_controls(codec, max98095_snd_controls,
 			     ARRAY_SIZE(max98095_snd_controls));
 
 	return 0;
@@ -1984,7 +1984,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec)
 	max98095->eq_enum.texts = max98095->eq_texts;
 	max98095->eq_enum.max = max98095->eq_textcnt;
 
-	ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
+	ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
 	if (ret != 0)
 		dev_err(codec->dev, "Failed to add EQ control: %d\n", ret);
 }
@@ -2139,7 +2139,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec)
 	max98095->bq_enum.texts = max98095->bq_texts;
 	max98095->bq_enum.max = max98095->bq_textcnt;
 
-	ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
+	ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
 	if (ret != 0)
 		dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret);
 }
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index dcf6f2a..3a2ba3d 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = {
 /* This function is called from ASoC machine driver */
 int max9877_add_controls(struct snd_soc_codec *codec)
 {
-	return snd_soc_add_controls(codec, max9877_controls,
+	return snd_soc_add_codec_controls(codec, max9877_controls,
 			ARRAY_SIZE(max9877_controls));
 }
 EXPORT_SYMBOL_GPL(max9877_add_controls);
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 7f4ba81..d192626 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -227,7 +227,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
 };
 
 /* routes for sgtl5000 */
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
 	{"Capture Mux", "LINE_IN", "LINE_IN"},	/* line_in --> adc_mux */
 	{"Capture Mux", "MIC_IN", "MIC_IN"},	/* mic_in --> adc_mux */
 
@@ -1248,7 +1248,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
 	}
 
 	rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT;
-	dev_info(codec->dev, "sgtl5000 revision %d\n", rev);
+	dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev);
 
 	/*
 	 * workaround for revision 0x11 and later,
@@ -1353,15 +1353,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
 	if (ret)
 		goto err;
 
-	snd_soc_add_controls(codec, sgtl5000_snd_controls,
-			     ARRAY_SIZE(sgtl5000_snd_controls));
-
-	snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets,
-				  ARRAY_SIZE(sgtl5000_dapm_widgets));
-
-	snd_soc_dapm_add_routes(&codec->dapm, audio_map,
-				ARRAY_SIZE(audio_map));
-
 	snd_soc_dapm_new_widgets(&codec->dapm);
 
 	return 0;
@@ -1402,6 +1393,12 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
 	.reg_cache_step = 2,
 	.reg_cache_default = sgtl5000_regs,
 	.volatile_register = sgtl5000_volatile_register,
+	.controls = sgtl5000_snd_controls,
+	.num_controls = ARRAY_SIZE(sgtl5000_snd_controls),
+	.dapm_widgets = sgtl5000_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets),
+	.dapm_routes = sgtl5000_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes),
 };
 
 static __devinit int sgtl5000_i2c_probe(struct i2c_client *client,
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index f99baa0..50dbdb9 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
 {
 	pr_debug("codec_probe called\n");
 
-	codec->dapm.idle_bias_off = 1;
-
 	/* PCM interface config
 	 * This sets the pcm rx slot conguration to max 6 slots
 	 * for max 4 dais (2 stereo and 2 mono)
@@ -871,7 +869,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec)
 	snd_soc_write(codec, SN95031_SSR2, 0x10);
 	snd_soc_write(codec, SN95031_SSR3, 0x40);
 
-	snd_soc_add_controls(codec, sn95031_snd_controls,
+	snd_soc_add_codec_controls(codec, sn95031_snd_controls,
 			     ARRAY_SIZE(sn95031_snd_controls));
 
 	return 0;
@@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = {
 	.read		= sn95031_read,
 	.write		= sn95031_write,
 	.set_bias_level	= sn95031_set_vaud_bias,
+	.idle_bias_off	= true,
 	.dapm_widgets	= sn95031_dapm_widgets,
 	.num_dapm_widgets	= ARRAY_SIZE(sn95031_dapm_widgets),
 	.dapm_routes	= sn95031_audio_map,
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 333dd98..de2b205 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec)
 	snd_soc_update_bits(codec, SSM2602_ROUT1V,
 			    ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
 
-	ret = snd_soc_add_controls(codec, ssm2602_snd_controls,
+	ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
 			ARRAY_SIZE(ssm2602_snd_controls));
 	if (ret)
 		return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index cc0566c..982e437 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
 
 	stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-	snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
+	snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls,
 			     ARRAY_SIZE(stac9766_snd_ac97_controls));
 
 	return 0;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index dfa41a9..16d55f9 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
 
 	snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
 
-	snd_soc_add_controls(codec, tlv320aic23_snd_controls,
+	snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls,
 				ARRAY_SIZE(tlv320aic23_snd_controls));
 
 	return 0;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index a038dae..802064b 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
 
 	/* register controls */
 	dev_dbg(codec->dev, "Registering controls\n");
-	err = snd_soc_add_controls(codec, aic26_snd_controls,
+	err = snd_soc_add_codec_controls(codec, aic26_snd_controls,
 			ARRAY_SIZE(aic26_snd_controls));
 	WARN_ON(err < 0);
 
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 372b0b8..b0a73d3 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -671,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
 	}
 
 	aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	snd_soc_add_controls(codec, aic32x4_snd_controls,
+	snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
 			     ARRAY_SIZE(aic32x4_snd_controls));
 	aic32x4_add_widgets(codec);
 
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 492f22f..8d20f6e 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
 	0x00, 0x00, 0x02,	/* 100 */
 };
 
-/*
- * read from the aic3x register space. Only use for this function is if
- * wanting to read volatile bits from those registers that has both read-only
- * and read/write bits. All other cases should use snd_soc_read.
- */
-static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
-		      u8 *value)
-{
-	u8 *cache = codec->reg_cache;
-
-	if (codec->cache_only)
-		return -EINVAL;
-	if (reg >= AIC3X_CACHEREGNUM)
-		return -1;
-
-	codec->cache_bypass = 1;
-	*value = snd_soc_read(codec, reg);
-	codec->cache_bypass = 0;
-
-	cache[reg] = *value;
-
-	return 0;
-}
-
 #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
 {	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
 	.info = snd_soc_info_volsw, \
@@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
-void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state)
-{
-	u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
-	u8 bit = gpio ? 3: 0;
-	u8 val = snd_soc_read(codec, reg) & ~(1 << bit);
-	snd_soc_write(codec, reg, val | (!!state << bit));
-}
-EXPORT_SYMBOL_GPL(aic3x_set_gpio);
-
-int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
-{
-	u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG;
-	u8 val = 0, bit = gpio ? 2 : 1;
-
-	aic3x_read(codec, reg, &val);
-	return (val >> bit) & 1;
-}
-EXPORT_SYMBOL_GPL(aic3x_get_gpio);
-
 void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
 				 int headset_debounce, int button_debounce)
 {
@@ -1221,23 +1178,6 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
 
 	snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
 }
-EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
-
-int aic3x_headset_detected(struct snd_soc_codec *codec)
-{
-	u8 val = 0;
-	aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
-	return (val >> 4) & 1;
-}
-EXPORT_SYMBOL_GPL(aic3x_headset_detected);
-
-int aic3x_button_pressed(struct snd_soc_codec *codec)
-{
-	u8 val = 0;
-	aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
-	return (val >> 5) & 1;
-}
-EXPORT_SYMBOL_GPL(aic3x_button_pressed);
 
 #define AIC3X_RATES	SNDRV_PCM_RATE_8000_96000
 #define AIC3X_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
@@ -1377,7 +1317,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 
 	INIT_LIST_HEAD(&aic3x->list);
 	aic3x->codec = codec;
-	codec->dapm.idle_bias_off = 1;
 
 	ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
 	if (ret != 0) {
@@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec)
 			      (aic3x->setup->gpio_func[1] & 0xf) << 4);
 	}
 
-	snd_soc_add_controls(codec, aic3x_snd_controls,
+	snd_soc_add_codec_controls(codec, aic3x_snd_controls,
 			     ARRAY_SIZE(aic3x_snd_controls));
 	if (aic3x->model == AIC3X_MODEL_3007)
-		snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
+		snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
 
 	aic3x_add_widgets(codec);
 	list_add(&aic3x->list, &reset_list);
@@ -1471,6 +1410,7 @@ static int aic3x_remove(struct snd_soc_codec *codec)
 
 static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
 	.set_bias_level = aic3x_set_bias_level,
+	.idle_bias_off = true,
 	.reg_cache_size = ARRAY_SIZE(aic3x_reg),
 	.reg_word_size = sizeof(u8),
 	.reg_cache_default = aic3x_reg,
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 06a1978..6f097fb 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -212,9 +212,6 @@
 /* Default input volume */
 #define DEFAULT_GAIN    0x20
 
-void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
-int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
-
 /* headset detection / button API */
 
 /* The AIC3x supports detection of stereo headsets (GND + left + right signal)
@@ -252,10 +249,4 @@ enum {
 #define AIC3X_BUTTON_DEBOUNCE_SHIFT 	0
 #define AIC3X_BUTTON_DEBOUNCE_MASK	3
 
-/* see the enums above for valid parameters to this function */
-void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
-				 int headset_debounce, int button_debounce);
-int aic3x_headset_detected(struct snd_soc_codec *codec);
-int aic3x_button_pressed(struct snd_soc_codec *codec);
-
 #endif /* _AIC3X_H */
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index f0aad26..4587ddd 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -806,8 +806,6 @@ static int dac33_startup(struct snd_pcm_substream *substream,
 	/* Stream started, save the substream pointer */
 	dac33->substream = substream;
 
-	snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
-
 	return 0;
 }
 
@@ -1397,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
 
 	codec->control_data = dac33->control_data;
 	codec->hw_write = (hw_write_t) i2c_master_send;
-	codec->dapm.idle_bias_off = 1;
 	dac33->codec = codec;
 
 	/* Read the tlv320dac33 ID registers */
@@ -1440,7 +1437,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
 
 	/* Only add the FIFO controls, if we have valid IRQ number */
 	if (dac33->irq >= 0)
-		snd_soc_add_controls(codec, dac33_mode_snd_controls,
+		snd_soc_add_codec_controls(codec, dac33_mode_snd_controls,
 				     ARRAY_SIZE(dac33_mode_snd_controls));
 
 err_power:
@@ -1478,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
 	.read = dac33_read_reg_cache,
 	.write = dac33_write_locked,
 	.set_bias_level = dac33_set_bias_level,
+	.idle_bias_off = true,
 	.reg_cache_size = ARRAY_SIZE(dac33_reg),
 	.reg_word_size = sizeof(u8),
 	.reg_cache_default = dac33_reg,
@@ -1515,7 +1513,9 @@ static struct snd_soc_dai_driver dac33_dai = {
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = DAC33_RATES,
-		.formats = DAC33_FORMATS,},
+		.formats = DAC33_FORMATS,
+		.sig_bits = 24,
+	},
 	.ops = &dac33_dai_ops,
 };
 
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 363b99d..6fe4aa3 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
 	data = i2c_get_clientdata(tpa6130a2_client);
 
 	if (data->id == TPA6140A2)
-		return snd_soc_add_controls(codec, tpa6140a2_controls,
+		return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
 						ARRAY_SIZE(tpa6140a2_controls));
 	else
-		return snd_soc_add_controls(codec, tpa6130a2_controls,
+		return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
 						ARRAY_SIZE(tpa6130a2_controls));
 }
 EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 18e7101..170cf9a 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
 	unsigned short mask, bitmask;
 
 	if (twl4030->configured) {
-		printk(KERN_ERR "twl4030 operation mode cannot be "
-			"changed on-the-fly\n");
+		dev_err(codec->dev,
+			"operation mode cannot be changed on-the-fly\n");
 		return -EBUSY;
 	}
 
@@ -1689,7 +1689,6 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_codec *codec = rtd->codec;
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
 
-	snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
 	if (twl4030->master_substream) {
 		twl4030->slave_substream = substream;
 		/* The DAI has one configuration for playback and capture, so
@@ -1801,7 +1800,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 		mode |= TWL4030_APLL_RATE_96000;
 		break;
 	default:
-		printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
+		dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
 			params_rate(params));
 		return -EINVAL;
 	}
@@ -1818,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 		format |= TWL4030_DATA_WIDTH_32S_24W;
 		break;
 	default:
-		printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
+		dev_err(codec->dev, "%s: unknown format %d\n", __func__,
 			params_format(params));
 		return -EINVAL;
 	}
@@ -1868,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	case 38400000:
 		break;
 	default:
-		dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
+		dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq);
 		return -EINVAL;
 	}
 
 	if ((freq / 1000) != twl4030->sysclk) {
 		dev_err(codec->dev,
-			"Mismatch in APLL mclk: %u (configured: %u)\n",
+			"Mismatch in HFCLKIN: %u (configured: %u)\n",
 			freq, twl4030->sysclk * 1000);
 		return -EINVAL;
 	}
@@ -1984,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
 	 * not available.
 	 */
 	if (twl4030->sysclk != 26000) {
-		dev_err(codec->dev, "The board is configured for %u Hz, while"
-			"the Voice interface needs 26MHz APLL mclk\n",
-			twl4030->sysclk * 1000);
+		dev_err(codec->dev,
+			"%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
+			__func__, twl4030->sysclk);
 		return -EINVAL;
 	}
 
@@ -1997,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
 		& TWL4030_OPT_MODE;
 
 	if (mode != TWL4030_OPTION_2) {
-		printk(KERN_ERR "TWL4030 voice startup: "
-			"the codec mode is not option2\n");
+		dev_err(codec->dev, "%s: the codec mode is not option2\n",
+			__func__);
 		return -EINVAL;
 	}
 
@@ -2039,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
 		mode |= TWL4030_SEL_16K;
 		break;
 	default:
-		printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n",
+		dev_err(codec->dev, "%s: unknown rate %d\n", __func__,
 			params_rate(params));
 		return -EINVAL;
 	}
@@ -2068,13 +2067,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
 
 	if (freq != 26000000) {
-		dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
-			"interface needs 26MHz APLL mclk\n", freq);
+		dev_err(codec->dev,
+			"%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n",
+			__func__, freq / 1000);
 		return -EINVAL;
 	}
 	if ((freq / 1000) != twl4030->sysclk) {
 		dev_err(codec->dev,
-			"Mismatch in APLL mclk: %u (configured: %u)\n",
+			"Mismatch in HFCLKIN: %u (configured: %u)\n",
 			freq, twl4030->sysclk * 1000);
 		return -EINVAL;
 	}
@@ -2175,13 +2175,15 @@ static struct snd_soc_dai_driver twl4030_dai[] = {
 		.channels_min = 2,
 		.channels_max = 4,
 		.rates = TWL4030_RATES | SNDRV_PCM_RATE_96000,
-		.formats = TWL4030_FORMATS,},
+		.formats = TWL4030_FORMATS,
+		.sig_bits = 24,},
 	.capture = {
 		.stream_name = "Capture",
 		.channels_min = 2,
 		.channels_max = 4,
 		.rates = TWL4030_RATES,
-		.formats = TWL4030_FORMATS,},
+		.formats = TWL4030_FORMATS,
+		.sig_bits = 24,},
 	.ops = &twl4030_dai_hifi_ops,
 },
 {
@@ -2220,13 +2222,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
 
 	twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
 	if (twl4030 == NULL) {
-		printk("Can not allocate memroy\n");
+		dev_err(codec->dev, "Can not allocate memory\n");
 		return -ENOMEM;
 	}
 	snd_soc_codec_set_drvdata(codec, twl4030);
 	/* Set the defaults, and power up the codec */
 	twl4030->sysclk = twl4030_audio_get_mclk() / 1000;
-	codec->dapm.idle_bias_off = 1;
 
 	twl4030_init_chip(codec);
 
@@ -2252,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
 	.read = twl4030_read_reg_cache,
 	.write = twl4030_write,
 	.set_bias_level = twl4030_set_bias_level,
+	.idle_bias_off = true,
 	.reg_cache_size = sizeof(twl4030_reg),
 	.reg_word_size = sizeof(u8),
 	.reg_cache_default = twl4030_reg,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 5b9c79b..dc7509b 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -26,7 +26,6 @@
 #include <linux/pm.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/i2c/twl.h>
 #include <linux/mfd/twl6040.h>
 
 #include <sound/core.h>
@@ -1052,6 +1051,19 @@ int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim)
 }
 EXPORT_SYMBOL_GPL(twl6040_get_trim_value);
 
+int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
+{
+	struct twl6040 *twl6040 = codec->control_data;
+
+	if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2)
+		/* For ES under ES_1.3 HS step is 2 mV */
+		return 2;
+	else
+		/* For ES_1.3 HS step is 1 mV */
+		return 1;
+}
+EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size);
+
 static const struct snd_kcontrol_new twl6040_snd_controls[] = {
 	/* Capture gains */
 	SOC_DOUBLE_TLV("Capture Preamplifier Volume",
@@ -1125,14 +1137,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
 			TWL6040_REG_MICRCTL, 2, 0),
 
 	/* Microphone bias */
-	SND_SOC_DAPM_MICBIAS("Headset Mic Bias",
-			TWL6040_REG_AMICBCTL, 0, 0),
-	SND_SOC_DAPM_MICBIAS("Main Mic Bias",
-			TWL6040_REG_AMICBCTL, 4, 0),
-	SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias",
-			TWL6040_REG_DMICBCTL, 0, 0),
-	SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias",
-			TWL6040_REG_DMICBCTL, 4, 0),
+	SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
+			    TWL6040_REG_AMICBCTL, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("Main Mic Bias",
+			    TWL6040_REG_AMICBCTL, 4, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
+			    TWL6040_REG_DMICBCTL, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
+			    TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
 
 	/* DACs */
 	SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
@@ -1515,7 +1527,7 @@ static int twl6040_resume(struct snd_soc_codec *codec)
 static int twl6040_probe(struct snd_soc_codec *codec)
 {
 	struct twl6040_data *priv;
-	struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+	struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev);
 	struct platform_device *pdev = container_of(codec->dev,
 						   struct platform_device, dev);
 	int ret = 0;
@@ -1527,7 +1539,6 @@ static int twl6040_probe(struct snd_soc_codec *codec)
 
 	priv->codec = codec;
 	codec->control_data = dev_get_drvdata(codec->dev->parent);
-	codec->ignore_pmdown_time = 1;
 
 	if (pdata && pdata->hs_left_step && pdata->hs_right_step) {
 		priv->hs_left_step = pdata->hs_left_step;
@@ -1613,6 +1624,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
 	.reg_cache_size = ARRAY_SIZE(twl6040_reg),
 	.reg_word_size = sizeof(u8),
 	.reg_cache_default = twl6040_reg,
+	.ignore_pmdown_time = true,
 
 	.controls = twl6040_snd_controls,
 	.num_controls = ARRAY_SIZE(twl6040_snd_controls),
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index ef273f1..0611406 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -39,5 +39,6 @@ void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
 			    struct snd_soc_jack *jack, int report);
 int twl6040_get_clk_id(struct snd_soc_codec *codec);
 int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim);
+int twl6040_get_hs_step_size(struct snd_soc_codec *codec);
 
 #endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 8f4f469..797b0dd 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -531,15 +531,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
 	switch (pd->model) {
 	case UDA134X_UDA1340:
 	case UDA134X_UDA1344:
-		ret = snd_soc_add_controls(codec, uda1340_snd_controls,
+		ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls,
 					ARRAY_SIZE(uda1340_snd_controls));
 	break;
 	case UDA134X_UDA1341:
-		ret = snd_soc_add_controls(codec, uda1341_snd_controls,
+		ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls,
 					ARRAY_SIZE(uda1341_snd_controls));
 	break;
 	case UDA134X_UDA1345:
-		ret = snd_soc_add_controls(codec, uda1345_snd_controls,
+		ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls,
 					ARRAY_SIZE(uda1345_snd_controls));
 	break;
 	default:
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 44aacf9..3d868dc 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -464,7 +464,7 @@ static int wl1273_probe(struct snd_soc_codec *codec)
 
 	snd_soc_codec_set_drvdata(codec, wl1273);
 
-	r = snd_soc_add_controls(codec, wl1273_controls,
+	r = snd_soc_add_codec_controls(codec, wl1273_controls,
 				 ARRAY_SIZE(wl1273_controls));
 	if (r)
 		kfree(wl1273);
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
new file mode 100644
index 0000000..acbdc5f
--- /dev/null
+++ b/sound/soc/codecs/wm2200.c
@@ -0,0 +1,2286 @@
+/*
+ * wm2200.c  --  WM2200 ALSA SoC Audio driver
+ *
+ * Copyright 2012 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/gcd.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/fixed.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/wm2200.h>
+
+#include "wm2200.h"
+
+/* The code assumes DCVDD is generated internally */
+#define WM2200_NUM_CORE_SUPPLIES 2
+static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
+	"DBVDD",
+	"LDOVDD",
+};
+
+struct wm2200_fll {
+	int fref;
+	int fout;
+	int src;
+	struct completion lock;
+};
+
+/* codec private data */
+struct wm2200_priv {
+	struct regmap *regmap;
+	struct device *dev;
+	struct snd_soc_codec *codec;
+	struct wm2200_pdata pdata;
+	struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
+
+	struct completion fll_lock;
+	int fll_fout;
+	int fll_fref;
+	int fll_src;
+
+	int rev;
+	int sysclk;
+};
+
+static struct reg_default wm2200_reg_defaults[] = {
+	{ 0x000B, 0x0000 },   /* R11    - Tone Generator 1 */
+	{ 0x0102, 0x0000 },   /* R258   - Clocking 3 */
+	{ 0x0103, 0x0011 },   /* R259   - Clocking 4 */
+	{ 0x0111, 0x0000 },   /* R273   - FLL Control 1 */
+	{ 0x0112, 0x0000 },   /* R274   - FLL Control 2 */
+	{ 0x0113, 0x0000 },   /* R275   - FLL Control 3 */
+	{ 0x0114, 0x0000 },   /* R276   - FLL Control 4 */
+	{ 0x0116, 0x0177 },   /* R278   - FLL Control 6 */
+	{ 0x0117, 0x0004 },   /* R279   - FLL Control 7 */
+	{ 0x0119, 0x0000 },   /* R281   - FLL EFS 1 */
+	{ 0x011A, 0x0002 },   /* R282   - FLL EFS 2 */
+	{ 0x0200, 0x0000 },   /* R512   - Mic Charge Pump 1 */
+	{ 0x0201, 0x03FF },   /* R513   - Mic Charge Pump 2 */
+	{ 0x0202, 0x9BDE },   /* R514   - DM Charge Pump 1 */
+	{ 0x020C, 0x0000 },   /* R524   - Mic Bias Ctrl 1 */
+	{ 0x020D, 0x0000 },   /* R525   - Mic Bias Ctrl 2 */
+	{ 0x020F, 0x0000 },   /* R527   - Ear Piece Ctrl 1 */
+	{ 0x0210, 0x0000 },   /* R528   - Ear Piece Ctrl 2 */
+	{ 0x0301, 0x0000 },   /* R769   - Input Enables */
+	{ 0x0302, 0x2240 },   /* R770   - IN1L Control */
+	{ 0x0303, 0x0040 },   /* R771   - IN1R Control */
+	{ 0x0304, 0x2240 },   /* R772   - IN2L Control */
+	{ 0x0305, 0x0040 },   /* R773   - IN2R Control */
+	{ 0x0306, 0x2240 },   /* R774   - IN3L Control */
+	{ 0x0307, 0x0040 },   /* R775   - IN3R Control */
+	{ 0x030A, 0x0000 },   /* R778   - RXANC_SRC */
+	{ 0x030B, 0x0022 },   /* R779   - Input Volume Ramp */
+	{ 0x030C, 0x0180 },   /* R780   - ADC Digital Volume 1L */
+	{ 0x030D, 0x0180 },   /* R781   - ADC Digital Volume 1R */
+	{ 0x030E, 0x0180 },   /* R782   - ADC Digital Volume 2L */
+	{ 0x030F, 0x0180 },   /* R783   - ADC Digital Volume 2R */
+	{ 0x0310, 0x0180 },   /* R784   - ADC Digital Volume 3L */
+	{ 0x0311, 0x0180 },   /* R785   - ADC Digital Volume 3R */
+	{ 0x0400, 0x0000 },   /* R1024  - Output Enables */
+	{ 0x0401, 0x0000 },   /* R1025  - DAC Volume Limit 1L */
+	{ 0x0402, 0x0000 },   /* R1026  - DAC Volume Limit 1R */
+	{ 0x0403, 0x0000 },   /* R1027  - DAC Volume Limit 2L */
+	{ 0x0404, 0x0000 },   /* R1028  - DAC Volume Limit 2R */
+	{ 0x0409, 0x0000 },   /* R1033  - DAC AEC Control 1 */
+	{ 0x040A, 0x0022 },   /* R1034  - Output Volume Ramp */
+	{ 0x040B, 0x0180 },   /* R1035  - DAC Digital Volume 1L */
+	{ 0x040C, 0x0180 },   /* R1036  - DAC Digital Volume 1R */
+	{ 0x040D, 0x0180 },   /* R1037  - DAC Digital Volume 2L */
+	{ 0x040E, 0x0180 },   /* R1038  - DAC Digital Volume 2R */
+	{ 0x0417, 0x0069 },   /* R1047  - PDM 1 */
+	{ 0x0418, 0x0000 },   /* R1048  - PDM 2 */
+	{ 0x0500, 0x0000 },   /* R1280  - Audio IF 1_1 */
+	{ 0x0501, 0x0008 },   /* R1281  - Audio IF 1_2 */
+	{ 0x0502, 0x0000 },   /* R1282  - Audio IF 1_3 */
+	{ 0x0503, 0x0000 },   /* R1283  - Audio IF 1_4 */
+	{ 0x0504, 0x0000 },   /* R1284  - Audio IF 1_5 */
+	{ 0x0505, 0x0001 },   /* R1285  - Audio IF 1_6 */
+	{ 0x0506, 0x0001 },   /* R1286  - Audio IF 1_7 */
+	{ 0x0507, 0x0000 },   /* R1287  - Audio IF 1_8 */
+	{ 0x0508, 0x0000 },   /* R1288  - Audio IF 1_9 */
+	{ 0x0509, 0x0000 },   /* R1289  - Audio IF 1_10 */
+	{ 0x050A, 0x0000 },   /* R1290  - Audio IF 1_11 */
+	{ 0x050B, 0x0000 },   /* R1291  - Audio IF 1_12 */
+	{ 0x050C, 0x0000 },   /* R1292  - Audio IF 1_13 */
+	{ 0x050D, 0x0000 },   /* R1293  - Audio IF 1_14 */
+	{ 0x050E, 0x0000 },   /* R1294  - Audio IF 1_15 */
+	{ 0x050F, 0x0000 },   /* R1295  - Audio IF 1_16 */
+	{ 0x0510, 0x0000 },   /* R1296  - Audio IF 1_17 */
+	{ 0x0511, 0x0000 },   /* R1297  - Audio IF 1_18 */
+	{ 0x0512, 0x0000 },   /* R1298  - Audio IF 1_19 */
+	{ 0x0513, 0x0000 },   /* R1299  - Audio IF 1_20 */
+	{ 0x0514, 0x0000 },   /* R1300  - Audio IF 1_21 */
+	{ 0x0515, 0x0001 },   /* R1301  - Audio IF 1_22 */
+	{ 0x0600, 0x0000 },   /* R1536  - OUT1LMIX Input 1 Source */
+	{ 0x0601, 0x0080 },   /* R1537  - OUT1LMIX Input 1 Volume */
+	{ 0x0602, 0x0000 },   /* R1538  - OUT1LMIX Input 2 Source */
+	{ 0x0603, 0x0080 },   /* R1539  - OUT1LMIX Input 2 Volume */
+	{ 0x0604, 0x0000 },   /* R1540  - OUT1LMIX Input 3 Source */
+	{ 0x0605, 0x0080 },   /* R1541  - OUT1LMIX Input 3 Volume */
+	{ 0x0606, 0x0000 },   /* R1542  - OUT1LMIX Input 4 Source */
+	{ 0x0607, 0x0080 },   /* R1543  - OUT1LMIX Input 4 Volume */
+	{ 0x0608, 0x0000 },   /* R1544  - OUT1RMIX Input 1 Source */
+	{ 0x0609, 0x0080 },   /* R1545  - OUT1RMIX Input 1 Volume */
+	{ 0x060A, 0x0000 },   /* R1546  - OUT1RMIX Input 2 Source */
+	{ 0x060B, 0x0080 },   /* R1547  - OUT1RMIX Input 2 Volume */
+	{ 0x060C, 0x0000 },   /* R1548  - OUT1RMIX Input 3 Source */
+	{ 0x060D, 0x0080 },   /* R1549  - OUT1RMIX Input 3 Volume */
+	{ 0x060E, 0x0000 },   /* R1550  - OUT1RMIX Input 4 Source */
+	{ 0x060F, 0x0080 },   /* R1551  - OUT1RMIX Input 4 Volume */
+	{ 0x0610, 0x0000 },   /* R1552  - OUT2LMIX Input 1 Source */
+	{ 0x0611, 0x0080 },   /* R1553  - OUT2LMIX Input 1 Volume */
+	{ 0x0612, 0x0000 },   /* R1554  - OUT2LMIX Input 2 Source */
+	{ 0x0613, 0x0080 },   /* R1555  - OUT2LMIX Input 2 Volume */
+	{ 0x0614, 0x0000 },   /* R1556  - OUT2LMIX Input 3 Source */
+	{ 0x0615, 0x0080 },   /* R1557  - OUT2LMIX Input 3 Volume */
+	{ 0x0616, 0x0000 },   /* R1558  - OUT2LMIX Input 4 Source */
+	{ 0x0617, 0x0080 },   /* R1559  - OUT2LMIX Input 4 Volume */
+	{ 0x0618, 0x0000 },   /* R1560  - OUT2RMIX Input 1 Source */
+	{ 0x0619, 0x0080 },   /* R1561  - OUT2RMIX Input 1 Volume */
+	{ 0x061A, 0x0000 },   /* R1562  - OUT2RMIX Input 2 Source */
+	{ 0x061B, 0x0080 },   /* R1563  - OUT2RMIX Input 2 Volume */
+	{ 0x061C, 0x0000 },   /* R1564  - OUT2RMIX Input 3 Source */
+	{ 0x061D, 0x0080 },   /* R1565  - OUT2RMIX Input 3 Volume */
+	{ 0x061E, 0x0000 },   /* R1566  - OUT2RMIX Input 4 Source */
+	{ 0x061F, 0x0080 },   /* R1567  - OUT2RMIX Input 4 Volume */
+	{ 0x0620, 0x0000 },   /* R1568  - AIF1TX1MIX Input 1 Source */
+	{ 0x0621, 0x0080 },   /* R1569  - AIF1TX1MIX Input 1 Volume */
+	{ 0x0622, 0x0000 },   /* R1570  - AIF1TX1MIX Input 2 Source */
+	{ 0x0623, 0x0080 },   /* R1571  - AIF1TX1MIX Input 2 Volume */
+	{ 0x0624, 0x0000 },   /* R1572  - AIF1TX1MIX Input 3 Source */
+	{ 0x0625, 0x0080 },   /* R1573  - AIF1TX1MIX Input 3 Volume */
+	{ 0x0626, 0x0000 },   /* R1574  - AIF1TX1MIX Input 4 Source */
+	{ 0x0627, 0x0080 },   /* R1575  - AIF1TX1MIX Input 4 Volume */
+	{ 0x0628, 0x0000 },   /* R1576  - AIF1TX2MIX Input 1 Source */
+	{ 0x0629, 0x0080 },   /* R1577  - AIF1TX2MIX Input 1 Volume */
+	{ 0x062A, 0x0000 },   /* R1578  - AIF1TX2MIX Input 2 Source */
+	{ 0x062B, 0x0080 },   /* R1579  - AIF1TX2MIX Input 2 Volume */
+	{ 0x062C, 0x0000 },   /* R1580  - AIF1TX2MIX Input 3 Source */
+	{ 0x062D, 0x0080 },   /* R1581  - AIF1TX2MIX Input 3 Volume */
+	{ 0x062E, 0x0000 },   /* R1582  - AIF1TX2MIX Input 4 Source */
+	{ 0x062F, 0x0080 },   /* R1583  - AIF1TX2MIX Input 4 Volume */
+	{ 0x0630, 0x0000 },   /* R1584  - AIF1TX3MIX Input 1 Source */
+	{ 0x0631, 0x0080 },   /* R1585  - AIF1TX3MIX Input 1 Volume */
+	{ 0x0632, 0x0000 },   /* R1586  - AIF1TX3MIX Input 2 Source */
+	{ 0x0633, 0x0080 },   /* R1587  - AIF1TX3MIX Input 2 Volume */
+	{ 0x0634, 0x0000 },   /* R1588  - AIF1TX3MIX Input 3 Source */
+	{ 0x0635, 0x0080 },   /* R1589  - AIF1TX3MIX Input 3 Volume */
+	{ 0x0636, 0x0000 },   /* R1590  - AIF1TX3MIX Input 4 Source */
+	{ 0x0637, 0x0080 },   /* R1591  - AIF1TX3MIX Input 4 Volume */
+	{ 0x0638, 0x0000 },   /* R1592  - AIF1TX4MIX Input 1 Source */
+	{ 0x0639, 0x0080 },   /* R1593  - AIF1TX4MIX Input 1 Volume */
+	{ 0x063A, 0x0000 },   /* R1594  - AIF1TX4MIX Input 2 Source */
+	{ 0x063B, 0x0080 },   /* R1595  - AIF1TX4MIX Input 2 Volume */
+	{ 0x063C, 0x0000 },   /* R1596  - AIF1TX4MIX Input 3 Source */
+	{ 0x063D, 0x0080 },   /* R1597  - AIF1TX4MIX Input 3 Volume */
+	{ 0x063E, 0x0000 },   /* R1598  - AIF1TX4MIX Input 4 Source */
+	{ 0x063F, 0x0080 },   /* R1599  - AIF1TX4MIX Input 4 Volume */
+	{ 0x0640, 0x0000 },   /* R1600  - AIF1TX5MIX Input 1 Source */
+	{ 0x0641, 0x0080 },   /* R1601  - AIF1TX5MIX Input 1 Volume */
+	{ 0x0642, 0x0000 },   /* R1602  - AIF1TX5MIX Input 2 Source */
+	{ 0x0643, 0x0080 },   /* R1603  - AIF1TX5MIX Input 2 Volume */
+	{ 0x0644, 0x0000 },   /* R1604  - AIF1TX5MIX Input 3 Source */
+	{ 0x0645, 0x0080 },   /* R1605  - AIF1TX5MIX Input 3 Volume */
+	{ 0x0646, 0x0000 },   /* R1606  - AIF1TX5MIX Input 4 Source */
+	{ 0x0647, 0x0080 },   /* R1607  - AIF1TX5MIX Input 4 Volume */
+	{ 0x0648, 0x0000 },   /* R1608  - AIF1TX6MIX Input 1 Source */
+	{ 0x0649, 0x0080 },   /* R1609  - AIF1TX6MIX Input 1 Volume */
+	{ 0x064A, 0x0000 },   /* R1610  - AIF1TX6MIX Input 2 Source */
+	{ 0x064B, 0x0080 },   /* R1611  - AIF1TX6MIX Input 2 Volume */
+	{ 0x064C, 0x0000 },   /* R1612  - AIF1TX6MIX Input 3 Source */
+	{ 0x064D, 0x0080 },   /* R1613  - AIF1TX6MIX Input 3 Volume */
+	{ 0x064E, 0x0000 },   /* R1614  - AIF1TX6MIX Input 4 Source */
+	{ 0x064F, 0x0080 },   /* R1615  - AIF1TX6MIX Input 4 Volume */
+	{ 0x0650, 0x0000 },   /* R1616  - EQLMIX Input 1 Source */
+	{ 0x0651, 0x0080 },   /* R1617  - EQLMIX Input 1 Volume */
+	{ 0x0652, 0x0000 },   /* R1618  - EQLMIX Input 2 Source */
+	{ 0x0653, 0x0080 },   /* R1619  - EQLMIX Input 2 Volume */
+	{ 0x0654, 0x0000 },   /* R1620  - EQLMIX Input 3 Source */
+	{ 0x0655, 0x0080 },   /* R1621  - EQLMIX Input 3 Volume */
+	{ 0x0656, 0x0000 },   /* R1622  - EQLMIX Input 4 Source */
+	{ 0x0657, 0x0080 },   /* R1623  - EQLMIX Input 4 Volume */
+	{ 0x0658, 0x0000 },   /* R1624  - EQRMIX Input 1 Source */
+	{ 0x0659, 0x0080 },   /* R1625  - EQRMIX Input 1 Volume */
+	{ 0x065A, 0x0000 },   /* R1626  - EQRMIX Input 2 Source */
+	{ 0x065B, 0x0080 },   /* R1627  - EQRMIX Input 2 Volume */
+	{ 0x065C, 0x0000 },   /* R1628  - EQRMIX Input 3 Source */
+	{ 0x065D, 0x0080 },   /* R1629  - EQRMIX Input 3 Volume */
+	{ 0x065E, 0x0000 },   /* R1630  - EQRMIX Input 4 Source */
+	{ 0x065F, 0x0080 },   /* R1631  - EQRMIX Input 4 Volume */
+	{ 0x0660, 0x0000 },   /* R1632  - LHPF1MIX Input 1 Source */
+	{ 0x0661, 0x0080 },   /* R1633  - LHPF1MIX Input 1 Volume */
+	{ 0x0662, 0x0000 },   /* R1634  - LHPF1MIX Input 2 Source */
+	{ 0x0663, 0x0080 },   /* R1635  - LHPF1MIX Input 2 Volume */
+	{ 0x0664, 0x0000 },   /* R1636  - LHPF1MIX Input 3 Source */
+	{ 0x0665, 0x0080 },   /* R1637  - LHPF1MIX Input 3 Volume */
+	{ 0x0666, 0x0000 },   /* R1638  - LHPF1MIX Input 4 Source */
+	{ 0x0667, 0x0080 },   /* R1639  - LHPF1MIX Input 4 Volume */
+	{ 0x0668, 0x0000 },   /* R1640  - LHPF2MIX Input 1 Source */
+	{ 0x0669, 0x0080 },   /* R1641  - LHPF2MIX Input 1 Volume */
+	{ 0x066A, 0x0000 },   /* R1642  - LHPF2MIX Input 2 Source */
+	{ 0x066B, 0x0080 },   /* R1643  - LHPF2MIX Input 2 Volume */
+	{ 0x066C, 0x0000 },   /* R1644  - LHPF2MIX Input 3 Source */
+	{ 0x066D, 0x0080 },   /* R1645  - LHPF2MIX Input 3 Volume */
+	{ 0x066E, 0x0000 },   /* R1646  - LHPF2MIX Input 4 Source */
+	{ 0x066F, 0x0080 },   /* R1647  - LHPF2MIX Input 4 Volume */
+	{ 0x0670, 0x0000 },   /* R1648  - DSP1LMIX Input 1 Source */
+	{ 0x0671, 0x0080 },   /* R1649  - DSP1LMIX Input 1 Volume */
+	{ 0x0672, 0x0000 },   /* R1650  - DSP1LMIX Input 2 Source */
+	{ 0x0673, 0x0080 },   /* R1651  - DSP1LMIX Input 2 Volume */
+	{ 0x0674, 0x0000 },   /* R1652  - DSP1LMIX Input 3 Source */
+	{ 0x0675, 0x0080 },   /* R1653  - DSP1LMIX Input 3 Volume */
+	{ 0x0676, 0x0000 },   /* R1654  - DSP1LMIX Input 4 Source */
+	{ 0x0677, 0x0080 },   /* R1655  - DSP1LMIX Input 4 Volume */
+	{ 0x0678, 0x0000 },   /* R1656  - DSP1RMIX Input 1 Source */
+	{ 0x0679, 0x0080 },   /* R1657  - DSP1RMIX Input 1 Volume */
+	{ 0x067A, 0x0000 },   /* R1658  - DSP1RMIX Input 2 Source */
+	{ 0x067B, 0x0080 },   /* R1659  - DSP1RMIX Input 2 Volume */
+	{ 0x067C, 0x0000 },   /* R1660  - DSP1RMIX Input 3 Source */
+	{ 0x067D, 0x0080 },   /* R1661  - DSP1RMIX Input 3 Volume */
+	{ 0x067E, 0x0000 },   /* R1662  - DSP1RMIX Input 4 Source */
+	{ 0x067F, 0x0080 },   /* R1663  - DSP1RMIX Input 4 Volume */
+	{ 0x0680, 0x0000 },   /* R1664  - DSP1AUX1MIX Input 1 Source */
+	{ 0x0681, 0x0000 },   /* R1665  - DSP1AUX2MIX Input 1 Source */
+	{ 0x0682, 0x0000 },   /* R1666  - DSP1AUX3MIX Input 1 Source */
+	{ 0x0683, 0x0000 },   /* R1667  - DSP1AUX4MIX Input 1 Source */
+	{ 0x0684, 0x0000 },   /* R1668  - DSP1AUX5MIX Input 1 Source */
+	{ 0x0685, 0x0000 },   /* R1669  - DSP1AUX6MIX Input 1 Source */
+	{ 0x0686, 0x0000 },   /* R1670  - DSP2LMIX Input 1 Source */
+	{ 0x0687, 0x0080 },   /* R1671  - DSP2LMIX Input 1 Volume */
+	{ 0x0688, 0x0000 },   /* R1672  - DSP2LMIX Input 2 Source */
+	{ 0x0689, 0x0080 },   /* R1673  - DSP2LMIX Input 2 Volume */
+	{ 0x068A, 0x0000 },   /* R1674  - DSP2LMIX Input 3 Source */
+	{ 0x068B, 0x0080 },   /* R1675  - DSP2LMIX Input 3 Volume */
+	{ 0x068C, 0x0000 },   /* R1676  - DSP2LMIX Input 4 Source */
+	{ 0x068D, 0x0080 },   /* R1677  - DSP2LMIX Input 4 Volume */
+	{ 0x068E, 0x0000 },   /* R1678  - DSP2RMIX Input 1 Source */
+	{ 0x068F, 0x0080 },   /* R1679  - DSP2RMIX Input 1 Volume */
+	{ 0x0690, 0x0000 },   /* R1680  - DSP2RMIX Input 2 Source */
+	{ 0x0691, 0x0080 },   /* R1681  - DSP2RMIX Input 2 Volume */
+	{ 0x0692, 0x0000 },   /* R1682  - DSP2RMIX Input 3 Source */
+	{ 0x0693, 0x0080 },   /* R1683  - DSP2RMIX Input 3 Volume */
+	{ 0x0694, 0x0000 },   /* R1684  - DSP2RMIX Input 4 Source */
+	{ 0x0695, 0x0080 },   /* R1685  - DSP2RMIX Input 4 Volume */
+	{ 0x0696, 0x0000 },   /* R1686  - DSP2AUX1MIX Input 1 Source */
+	{ 0x0697, 0x0000 },   /* R1687  - DSP2AUX2MIX Input 1 Source */
+	{ 0x0698, 0x0000 },   /* R1688  - DSP2AUX3MIX Input 1 Source */
+	{ 0x0699, 0x0000 },   /* R1689  - DSP2AUX4MIX Input 1 Source */
+	{ 0x069A, 0x0000 },   /* R1690  - DSP2AUX5MIX Input 1 Source */
+	{ 0x069B, 0x0000 },   /* R1691  - DSP2AUX6MIX Input 1 Source */
+	{ 0x0700, 0xA101 },   /* R1792  - GPIO CTRL 1 */
+	{ 0x0701, 0xA101 },   /* R1793  - GPIO CTRL 2 */
+	{ 0x0702, 0xA101 },   /* R1794  - GPIO CTRL 3 */
+	{ 0x0703, 0xA101 },   /* R1795  - GPIO CTRL 4 */
+	{ 0x0709, 0x0000 },   /* R1801  - Misc Pad Ctrl 1 */
+	{ 0x0801, 0x00FF },   /* R2049  - Interrupt Status 1 Mask */
+	{ 0x0804, 0xFFFF },   /* R2052  - Interrupt Status 2 Mask */
+	{ 0x0808, 0x0000 },   /* R2056  - Interrupt Control */
+	{ 0x0900, 0x0000 },   /* R2304  - EQL_1 */
+	{ 0x0901, 0x0000 },   /* R2305  - EQL_2 */
+	{ 0x0902, 0x0000 },   /* R2306  - EQL_3 */
+	{ 0x0903, 0x0000 },   /* R2307  - EQL_4 */
+	{ 0x0904, 0x0000 },   /* R2308  - EQL_5 */
+	{ 0x0905, 0x0000 },   /* R2309  - EQL_6 */
+	{ 0x0906, 0x0000 },   /* R2310  - EQL_7 */
+	{ 0x0907, 0x0000 },   /* R2311  - EQL_8 */
+	{ 0x0908, 0x0000 },   /* R2312  - EQL_9 */
+	{ 0x0909, 0x0000 },   /* R2313  - EQL_10 */
+	{ 0x090A, 0x0000 },   /* R2314  - EQL_11 */
+	{ 0x090B, 0x0000 },   /* R2315  - EQL_12 */
+	{ 0x090C, 0x0000 },   /* R2316  - EQL_13 */
+	{ 0x090D, 0x0000 },   /* R2317  - EQL_14 */
+	{ 0x090E, 0x0000 },   /* R2318  - EQL_15 */
+	{ 0x090F, 0x0000 },   /* R2319  - EQL_16 */
+	{ 0x0910, 0x0000 },   /* R2320  - EQL_17 */
+	{ 0x0911, 0x0000 },   /* R2321  - EQL_18 */
+	{ 0x0912, 0x0000 },   /* R2322  - EQL_19 */
+	{ 0x0913, 0x0000 },   /* R2323  - EQL_20 */
+	{ 0x0916, 0x0000 },   /* R2326  - EQR_1 */
+	{ 0x0917, 0x0000 },   /* R2327  - EQR_2 */
+	{ 0x0918, 0x0000 },   /* R2328  - EQR_3 */
+	{ 0x0919, 0x0000 },   /* R2329  - EQR_4 */
+	{ 0x091A, 0x0000 },   /* R2330  - EQR_5 */
+	{ 0x091B, 0x0000 },   /* R2331  - EQR_6 */
+	{ 0x091C, 0x0000 },   /* R2332  - EQR_7 */
+	{ 0x091D, 0x0000 },   /* R2333  - EQR_8 */
+	{ 0x091E, 0x0000 },   /* R2334  - EQR_9 */
+	{ 0x091F, 0x0000 },   /* R2335  - EQR_10 */
+	{ 0x0920, 0x0000 },   /* R2336  - EQR_11 */
+	{ 0x0921, 0x0000 },   /* R2337  - EQR_12 */
+	{ 0x0922, 0x0000 },   /* R2338  - EQR_13 */
+	{ 0x0923, 0x0000 },   /* R2339  - EQR_14 */
+	{ 0x0924, 0x0000 },   /* R2340  - EQR_15 */
+	{ 0x0925, 0x0000 },   /* R2341  - EQR_16 */
+	{ 0x0926, 0x0000 },   /* R2342  - EQR_17 */
+	{ 0x0927, 0x0000 },   /* R2343  - EQR_18 */
+	{ 0x0928, 0x0000 },   /* R2344  - EQR_19 */
+	{ 0x0929, 0x0000 },   /* R2345  - EQR_20 */
+	{ 0x093E, 0x0000 },   /* R2366  - HPLPF1_1 */
+	{ 0x093F, 0x0000 },   /* R2367  - HPLPF1_2 */
+	{ 0x0942, 0x0000 },   /* R2370  - HPLPF2_1 */
+	{ 0x0943, 0x0000 },   /* R2371  - HPLPF2_2 */
+	{ 0x0A00, 0x0000 },   /* R2560  - DSP1 Control 1 */
+	{ 0x0A02, 0x0000 },   /* R2562  - DSP1 Control 2 */
+	{ 0x0A03, 0x0000 },   /* R2563  - DSP1 Control 3 */
+	{ 0x0A04, 0x0000 },   /* R2564  - DSP1 Control 4 */
+	{ 0x0A06, 0x0000 },   /* R2566  - DSP1 Control 5 */
+	{ 0x0A07, 0x0000 },   /* R2567  - DSP1 Control 6 */
+	{ 0x0A08, 0x0000 },   /* R2568  - DSP1 Control 7 */
+	{ 0x0A09, 0x0000 },   /* R2569  - DSP1 Control 8 */
+	{ 0x0A0A, 0x0000 },   /* R2570  - DSP1 Control 9 */
+	{ 0x0A0B, 0x0000 },   /* R2571  - DSP1 Control 10 */
+	{ 0x0A0C, 0x0000 },   /* R2572  - DSP1 Control 11 */
+	{ 0x0A0D, 0x0000 },   /* R2573  - DSP1 Control 12 */
+	{ 0x0A0F, 0x0000 },   /* R2575  - DSP1 Control 13 */
+	{ 0x0A10, 0x0000 },   /* R2576  - DSP1 Control 14 */
+	{ 0x0A11, 0x0000 },   /* R2577  - DSP1 Control 15 */
+	{ 0x0A12, 0x0000 },   /* R2578  - DSP1 Control 16 */
+	{ 0x0A13, 0x0000 },   /* R2579  - DSP1 Control 17 */
+	{ 0x0A14, 0x0000 },   /* R2580  - DSP1 Control 18 */
+	{ 0x0A16, 0x0000 },   /* R2582  - DSP1 Control 19 */
+	{ 0x0A17, 0x0000 },   /* R2583  - DSP1 Control 20 */
+	{ 0x0A18, 0x0000 },   /* R2584  - DSP1 Control 21 */
+	{ 0x0A1A, 0x1800 },   /* R2586  - DSP1 Control 22 */
+	{ 0x0A1B, 0x1000 },   /* R2587  - DSP1 Control 23 */
+	{ 0x0A1C, 0x0400 },   /* R2588  - DSP1 Control 24 */
+	{ 0x0A1E, 0x0000 },   /* R2590  - DSP1 Control 25 */
+	{ 0x0A20, 0x0000 },   /* R2592  - DSP1 Control 26 */
+	{ 0x0A21, 0x0000 },   /* R2593  - DSP1 Control 27 */
+	{ 0x0A22, 0x0000 },   /* R2594  - DSP1 Control 28 */
+	{ 0x0A23, 0x0000 },   /* R2595  - DSP1 Control 29 */
+	{ 0x0A24, 0x0000 },   /* R2596  - DSP1 Control 30 */
+	{ 0x0A26, 0x0000 },   /* R2598  - DSP1 Control 31 */
+	{ 0x0B00, 0x0000 },   /* R2816  - DSP2 Control 1 */
+	{ 0x0B02, 0x0000 },   /* R2818  - DSP2 Control 2 */
+	{ 0x0B03, 0x0000 },   /* R2819  - DSP2 Control 3 */
+	{ 0x0B04, 0x0000 },   /* R2820  - DSP2 Control 4 */
+	{ 0x0B06, 0x0000 },   /* R2822  - DSP2 Control 5 */
+	{ 0x0B07, 0x0000 },   /* R2823  - DSP2 Control 6 */
+	{ 0x0B08, 0x0000 },   /* R2824  - DSP2 Control 7 */
+	{ 0x0B09, 0x0000 },   /* R2825  - DSP2 Control 8 */
+	{ 0x0B0A, 0x0000 },   /* R2826  - DSP2 Control 9 */
+	{ 0x0B0B, 0x0000 },   /* R2827  - DSP2 Control 10 */
+	{ 0x0B0C, 0x0000 },   /* R2828  - DSP2 Control 11 */
+	{ 0x0B0D, 0x0000 },   /* R2829  - DSP2 Control 12 */
+	{ 0x0B0F, 0x0000 },   /* R2831  - DSP2 Control 13 */
+	{ 0x0B10, 0x0000 },   /* R2832  - DSP2 Control 14 */
+	{ 0x0B11, 0x0000 },   /* R2833  - DSP2 Control 15 */
+	{ 0x0B12, 0x0000 },   /* R2834  - DSP2 Control 16 */
+	{ 0x0B13, 0x0000 },   /* R2835  - DSP2 Control 17 */
+	{ 0x0B14, 0x0000 },   /* R2836  - DSP2 Control 18 */
+	{ 0x0B16, 0x0000 },   /* R2838  - DSP2 Control 19 */
+	{ 0x0B17, 0x0000 },   /* R2839  - DSP2 Control 20 */
+	{ 0x0B18, 0x0000 },   /* R2840  - DSP2 Control 21 */
+	{ 0x0B1A, 0x0800 },   /* R2842  - DSP2 Control 22 */
+	{ 0x0B1B, 0x1000 },   /* R2843  - DSP2 Control 23 */
+	{ 0x0B1C, 0x0400 },   /* R2844  - DSP2 Control 24 */
+	{ 0x0B1E, 0x0000 },   /* R2846  - DSP2 Control 25 */
+	{ 0x0B20, 0x0000 },   /* R2848  - DSP2 Control 26 */
+	{ 0x0B21, 0x0000 },   /* R2849  - DSP2 Control 27 */
+	{ 0x0B22, 0x0000 },   /* R2850  - DSP2 Control 28 */
+	{ 0x0B23, 0x0000 },   /* R2851  - DSP2 Control 29 */
+	{ 0x0B24, 0x0000 },   /* R2852  - DSP2 Control 30 */
+	{ 0x0B26, 0x0000 },   /* R2854  - DSP2 Control 31 */
+};
+
+static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM2200_SOFTWARE_RESET:
+	case WM2200_DEVICE_REVISION:
+	case WM2200_ADPS1_IRQ0:
+	case WM2200_ADPS1_IRQ1:
+	case WM2200_INTERRUPT_STATUS_1:
+	case WM2200_INTERRUPT_STATUS_2:
+	case WM2200_INTERRUPT_RAW_STATUS_2:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool wm2200_readable_register(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM2200_SOFTWARE_RESET:
+	case WM2200_DEVICE_REVISION:
+	case WM2200_TONE_GENERATOR_1:
+	case WM2200_CLOCKING_3:
+	case WM2200_CLOCKING_4:
+	case WM2200_FLL_CONTROL_1:
+	case WM2200_FLL_CONTROL_2:
+	case WM2200_FLL_CONTROL_3:
+	case WM2200_FLL_CONTROL_4:
+	case WM2200_FLL_CONTROL_6:
+	case WM2200_FLL_CONTROL_7:
+	case WM2200_FLL_EFS_1:
+	case WM2200_FLL_EFS_2:
+	case WM2200_MIC_CHARGE_PUMP_1:
+	case WM2200_MIC_CHARGE_PUMP_2:
+	case WM2200_DM_CHARGE_PUMP_1:
+	case WM2200_MIC_BIAS_CTRL_1:
+	case WM2200_MIC_BIAS_CTRL_2:
+	case WM2200_EAR_PIECE_CTRL_1:
+	case WM2200_EAR_PIECE_CTRL_2:
+	case WM2200_INPUT_ENABLES:
+	case WM2200_IN1L_CONTROL:
+	case WM2200_IN1R_CONTROL:
+	case WM2200_IN2L_CONTROL:
+	case WM2200_IN2R_CONTROL:
+	case WM2200_IN3L_CONTROL:
+	case WM2200_IN3R_CONTROL:
+	case WM2200_RXANC_SRC:
+	case WM2200_INPUT_VOLUME_RAMP:
+	case WM2200_ADC_DIGITAL_VOLUME_1L:
+	case WM2200_ADC_DIGITAL_VOLUME_1R:
+	case WM2200_ADC_DIGITAL_VOLUME_2L:
+	case WM2200_ADC_DIGITAL_VOLUME_2R:
+	case WM2200_ADC_DIGITAL_VOLUME_3L:
+	case WM2200_ADC_DIGITAL_VOLUME_3R:
+	case WM2200_OUTPUT_ENABLES:
+	case WM2200_DAC_VOLUME_LIMIT_1L:
+	case WM2200_DAC_VOLUME_LIMIT_1R:
+	case WM2200_DAC_VOLUME_LIMIT_2L:
+	case WM2200_DAC_VOLUME_LIMIT_2R:
+	case WM2200_DAC_AEC_CONTROL_1:
+	case WM2200_OUTPUT_VOLUME_RAMP:
+	case WM2200_DAC_DIGITAL_VOLUME_1L:
+	case WM2200_DAC_DIGITAL_VOLUME_1R:
+	case WM2200_DAC_DIGITAL_VOLUME_2L:
+	case WM2200_DAC_DIGITAL_VOLUME_2R:
+	case WM2200_PDM_1:
+	case WM2200_PDM_2:
+	case WM2200_AUDIO_IF_1_1:
+	case WM2200_AUDIO_IF_1_2:
+	case WM2200_AUDIO_IF_1_3:
+	case WM2200_AUDIO_IF_1_4:
+	case WM2200_AUDIO_IF_1_5:
+	case WM2200_AUDIO_IF_1_6:
+	case WM2200_AUDIO_IF_1_7:
+	case WM2200_AUDIO_IF_1_8:
+	case WM2200_AUDIO_IF_1_9:
+	case WM2200_AUDIO_IF_1_10:
+	case WM2200_AUDIO_IF_1_11:
+	case WM2200_AUDIO_IF_1_12:
+	case WM2200_AUDIO_IF_1_13:
+	case WM2200_AUDIO_IF_1_14:
+	case WM2200_AUDIO_IF_1_15:
+	case WM2200_AUDIO_IF_1_16:
+	case WM2200_AUDIO_IF_1_17:
+	case WM2200_AUDIO_IF_1_18:
+	case WM2200_AUDIO_IF_1_19:
+	case WM2200_AUDIO_IF_1_20:
+	case WM2200_AUDIO_IF_1_21:
+	case WM2200_AUDIO_IF_1_22:
+	case WM2200_OUT1LMIX_INPUT_1_SOURCE:
+	case WM2200_OUT1LMIX_INPUT_1_VOLUME:
+	case WM2200_OUT1LMIX_INPUT_2_SOURCE:
+	case WM2200_OUT1LMIX_INPUT_2_VOLUME:
+	case WM2200_OUT1LMIX_INPUT_3_SOURCE:
+	case WM2200_OUT1LMIX_INPUT_3_VOLUME:
+	case WM2200_OUT1LMIX_INPUT_4_SOURCE:
+	case WM2200_OUT1LMIX_INPUT_4_VOLUME:
+	case WM2200_OUT1RMIX_INPUT_1_SOURCE:
+	case WM2200_OUT1RMIX_INPUT_1_VOLUME:
+	case WM2200_OUT1RMIX_INPUT_2_SOURCE:
+	case WM2200_OUT1RMIX_INPUT_2_VOLUME:
+	case WM2200_OUT1RMIX_INPUT_3_SOURCE:
+	case WM2200_OUT1RMIX_INPUT_3_VOLUME:
+	case WM2200_OUT1RMIX_INPUT_4_SOURCE:
+	case WM2200_OUT1RMIX_INPUT_4_VOLUME:
+	case WM2200_OUT2LMIX_INPUT_1_SOURCE:
+	case WM2200_OUT2LMIX_INPUT_1_VOLUME:
+	case WM2200_OUT2LMIX_INPUT_2_SOURCE:
+	case WM2200_OUT2LMIX_INPUT_2_VOLUME:
+	case WM2200_OUT2LMIX_INPUT_3_SOURCE:
+	case WM2200_OUT2LMIX_INPUT_3_VOLUME:
+	case WM2200_OUT2LMIX_INPUT_4_SOURCE:
+	case WM2200_OUT2LMIX_INPUT_4_VOLUME:
+	case WM2200_OUT2RMIX_INPUT_1_SOURCE:
+	case WM2200_OUT2RMIX_INPUT_1_VOLUME:
+	case WM2200_OUT2RMIX_INPUT_2_SOURCE:
+	case WM2200_OUT2RMIX_INPUT_2_VOLUME:
+	case WM2200_OUT2RMIX_INPUT_3_SOURCE:
+	case WM2200_OUT2RMIX_INPUT_3_VOLUME:
+	case WM2200_OUT2RMIX_INPUT_4_SOURCE:
+	case WM2200_OUT2RMIX_INPUT_4_VOLUME:
+	case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
+	case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
+	case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
+	case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
+	case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
+	case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
+	case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
+	case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
+	case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
+	case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
+	case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
+	case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
+	case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
+	case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
+	case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
+	case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
+	case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
+	case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
+	case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
+	case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
+	case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
+	case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
+	case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
+	case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
+	case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
+	case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
+	case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
+	case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
+	case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
+	case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
+	case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
+	case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
+	case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
+	case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
+	case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
+	case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
+	case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
+	case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
+	case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
+	case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
+	case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
+	case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
+	case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
+	case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
+	case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
+	case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
+	case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
+	case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
+	case WM2200_EQLMIX_INPUT_1_SOURCE:
+	case WM2200_EQLMIX_INPUT_1_VOLUME:
+	case WM2200_EQLMIX_INPUT_2_SOURCE:
+	case WM2200_EQLMIX_INPUT_2_VOLUME:
+	case WM2200_EQLMIX_INPUT_3_SOURCE:
+	case WM2200_EQLMIX_INPUT_3_VOLUME:
+	case WM2200_EQLMIX_INPUT_4_SOURCE:
+	case WM2200_EQLMIX_INPUT_4_VOLUME:
+	case WM2200_EQRMIX_INPUT_1_SOURCE:
+	case WM2200_EQRMIX_INPUT_1_VOLUME:
+	case WM2200_EQRMIX_INPUT_2_SOURCE:
+	case WM2200_EQRMIX_INPUT_2_VOLUME:
+	case WM2200_EQRMIX_INPUT_3_SOURCE:
+	case WM2200_EQRMIX_INPUT_3_VOLUME:
+	case WM2200_EQRMIX_INPUT_4_SOURCE:
+	case WM2200_EQRMIX_INPUT_4_VOLUME:
+	case WM2200_LHPF1MIX_INPUT_1_SOURCE:
+	case WM2200_LHPF1MIX_INPUT_1_VOLUME:
+	case WM2200_LHPF1MIX_INPUT_2_SOURCE:
+	case WM2200_LHPF1MIX_INPUT_2_VOLUME:
+	case WM2200_LHPF1MIX_INPUT_3_SOURCE:
+	case WM2200_LHPF1MIX_INPUT_3_VOLUME:
+	case WM2200_LHPF1MIX_INPUT_4_SOURCE:
+	case WM2200_LHPF1MIX_INPUT_4_VOLUME:
+	case WM2200_LHPF2MIX_INPUT_1_SOURCE:
+	case WM2200_LHPF2MIX_INPUT_1_VOLUME:
+	case WM2200_LHPF2MIX_INPUT_2_SOURCE:
+	case WM2200_LHPF2MIX_INPUT_2_VOLUME:
+	case WM2200_LHPF2MIX_INPUT_3_SOURCE:
+	case WM2200_LHPF2MIX_INPUT_3_VOLUME:
+	case WM2200_LHPF2MIX_INPUT_4_SOURCE:
+	case WM2200_LHPF2MIX_INPUT_4_VOLUME:
+	case WM2200_DSP1LMIX_INPUT_1_SOURCE:
+	case WM2200_DSP1LMIX_INPUT_1_VOLUME:
+	case WM2200_DSP1LMIX_INPUT_2_SOURCE:
+	case WM2200_DSP1LMIX_INPUT_2_VOLUME:
+	case WM2200_DSP1LMIX_INPUT_3_SOURCE:
+	case WM2200_DSP1LMIX_INPUT_3_VOLUME:
+	case WM2200_DSP1LMIX_INPUT_4_SOURCE:
+	case WM2200_DSP1LMIX_INPUT_4_VOLUME:
+	case WM2200_DSP1RMIX_INPUT_1_SOURCE:
+	case WM2200_DSP1RMIX_INPUT_1_VOLUME:
+	case WM2200_DSP1RMIX_INPUT_2_SOURCE:
+	case WM2200_DSP1RMIX_INPUT_2_VOLUME:
+	case WM2200_DSP1RMIX_INPUT_3_SOURCE:
+	case WM2200_DSP1RMIX_INPUT_3_VOLUME:
+	case WM2200_DSP1RMIX_INPUT_4_SOURCE:
+	case WM2200_DSP1RMIX_INPUT_4_VOLUME:
+	case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
+	case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
+	case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
+	case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
+	case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
+	case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
+	case WM2200_DSP2LMIX_INPUT_1_SOURCE:
+	case WM2200_DSP2LMIX_INPUT_1_VOLUME:
+	case WM2200_DSP2LMIX_INPUT_2_SOURCE:
+	case WM2200_DSP2LMIX_INPUT_2_VOLUME:
+	case WM2200_DSP2LMIX_INPUT_3_SOURCE:
+	case WM2200_DSP2LMIX_INPUT_3_VOLUME:
+	case WM2200_DSP2LMIX_INPUT_4_SOURCE:
+	case WM2200_DSP2LMIX_INPUT_4_VOLUME:
+	case WM2200_DSP2RMIX_INPUT_1_SOURCE:
+	case WM2200_DSP2RMIX_INPUT_1_VOLUME:
+	case WM2200_DSP2RMIX_INPUT_2_SOURCE:
+	case WM2200_DSP2RMIX_INPUT_2_VOLUME:
+	case WM2200_DSP2RMIX_INPUT_3_SOURCE:
+	case WM2200_DSP2RMIX_INPUT_3_VOLUME:
+	case WM2200_DSP2RMIX_INPUT_4_SOURCE:
+	case WM2200_DSP2RMIX_INPUT_4_VOLUME:
+	case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
+	case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
+	case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
+	case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
+	case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
+	case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
+	case WM2200_GPIO_CTRL_1:
+	case WM2200_GPIO_CTRL_2:
+	case WM2200_GPIO_CTRL_3:
+	case WM2200_GPIO_CTRL_4:
+	case WM2200_ADPS1_IRQ0:
+	case WM2200_ADPS1_IRQ1:
+	case WM2200_MISC_PAD_CTRL_1:
+	case WM2200_INTERRUPT_STATUS_1:
+	case WM2200_INTERRUPT_STATUS_1_MASK:
+	case WM2200_INTERRUPT_STATUS_2:
+	case WM2200_INTERRUPT_RAW_STATUS_2:
+	case WM2200_INTERRUPT_STATUS_2_MASK:
+	case WM2200_INTERRUPT_CONTROL:
+	case WM2200_EQL_1:
+	case WM2200_EQL_2:
+	case WM2200_EQL_3:
+	case WM2200_EQL_4:
+	case WM2200_EQL_5:
+	case WM2200_EQL_6:
+	case WM2200_EQL_7:
+	case WM2200_EQL_8:
+	case WM2200_EQL_9:
+	case WM2200_EQL_10:
+	case WM2200_EQL_11:
+	case WM2200_EQL_12:
+	case WM2200_EQL_13:
+	case WM2200_EQL_14:
+	case WM2200_EQL_15:
+	case WM2200_EQL_16:
+	case WM2200_EQL_17:
+	case WM2200_EQL_18:
+	case WM2200_EQL_19:
+	case WM2200_EQL_20:
+	case WM2200_EQR_1:
+	case WM2200_EQR_2:
+	case WM2200_EQR_3:
+	case WM2200_EQR_4:
+	case WM2200_EQR_5:
+	case WM2200_EQR_6:
+	case WM2200_EQR_7:
+	case WM2200_EQR_8:
+	case WM2200_EQR_9:
+	case WM2200_EQR_10:
+	case WM2200_EQR_11:
+	case WM2200_EQR_12:
+	case WM2200_EQR_13:
+	case WM2200_EQR_14:
+	case WM2200_EQR_15:
+	case WM2200_EQR_16:
+	case WM2200_EQR_17:
+	case WM2200_EQR_18:
+	case WM2200_EQR_19:
+	case WM2200_EQR_20:
+	case WM2200_HPLPF1_1:
+	case WM2200_HPLPF1_2:
+	case WM2200_HPLPF2_1:
+	case WM2200_HPLPF2_2:
+	case WM2200_DSP1_CONTROL_1:
+	case WM2200_DSP1_CONTROL_2:
+	case WM2200_DSP1_CONTROL_3:
+	case WM2200_DSP1_CONTROL_4:
+	case WM2200_DSP1_CONTROL_5:
+	case WM2200_DSP1_CONTROL_6:
+	case WM2200_DSP1_CONTROL_7:
+	case WM2200_DSP1_CONTROL_8:
+	case WM2200_DSP1_CONTROL_9:
+	case WM2200_DSP1_CONTROL_10:
+	case WM2200_DSP1_CONTROL_11:
+	case WM2200_DSP1_CONTROL_12:
+	case WM2200_DSP1_CONTROL_13:
+	case WM2200_DSP1_CONTROL_14:
+	case WM2200_DSP1_CONTROL_15:
+	case WM2200_DSP1_CONTROL_16:
+	case WM2200_DSP1_CONTROL_17:
+	case WM2200_DSP1_CONTROL_18:
+	case WM2200_DSP1_CONTROL_19:
+	case WM2200_DSP1_CONTROL_20:
+	case WM2200_DSP1_CONTROL_21:
+	case WM2200_DSP1_CONTROL_22:
+	case WM2200_DSP1_CONTROL_23:
+	case WM2200_DSP1_CONTROL_24:
+	case WM2200_DSP1_CONTROL_25:
+	case WM2200_DSP1_CONTROL_26:
+	case WM2200_DSP1_CONTROL_27:
+	case WM2200_DSP1_CONTROL_28:
+	case WM2200_DSP1_CONTROL_29:
+	case WM2200_DSP1_CONTROL_30:
+	case WM2200_DSP1_CONTROL_31:
+	case WM2200_DSP2_CONTROL_1:
+	case WM2200_DSP2_CONTROL_2:
+	case WM2200_DSP2_CONTROL_3:
+	case WM2200_DSP2_CONTROL_4:
+	case WM2200_DSP2_CONTROL_5:
+	case WM2200_DSP2_CONTROL_6:
+	case WM2200_DSP2_CONTROL_7:
+	case WM2200_DSP2_CONTROL_8:
+	case WM2200_DSP2_CONTROL_9:
+	case WM2200_DSP2_CONTROL_10:
+	case WM2200_DSP2_CONTROL_11:
+	case WM2200_DSP2_CONTROL_12:
+	case WM2200_DSP2_CONTROL_13:
+	case WM2200_DSP2_CONTROL_14:
+	case WM2200_DSP2_CONTROL_15:
+	case WM2200_DSP2_CONTROL_16:
+	case WM2200_DSP2_CONTROL_17:
+	case WM2200_DSP2_CONTROL_18:
+	case WM2200_DSP2_CONTROL_19:
+	case WM2200_DSP2_CONTROL_20:
+	case WM2200_DSP2_CONTROL_21:
+	case WM2200_DSP2_CONTROL_22:
+	case WM2200_DSP2_CONTROL_23:
+	case WM2200_DSP2_CONTROL_24:
+	case WM2200_DSP2_CONTROL_25:
+	case WM2200_DSP2_CONTROL_26:
+	case WM2200_DSP2_CONTROL_27:
+	case WM2200_DSP2_CONTROL_28:
+	case WM2200_DSP2_CONTROL_29:
+	case WM2200_DSP2_CONTROL_30:
+	case WM2200_DSP2_CONTROL_31:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct reg_default wm2200_reva_patch[] = {
+	{ 0x07, 0x0003 },
+	{ 0x102, 0x0200 },
+	{ 0x203, 0x0084 },
+	{ 0x201, 0x83FF },
+	{ 0x20C, 0x0062 },
+	{ 0x20D, 0x0062 },
+	{ 0x207, 0x2002 },
+	{ 0x208, 0x20C0 },
+	{ 0x21D, 0x01C0 },
+	{ 0x50A, 0x0001 },
+	{ 0x50B, 0x0002 },
+	{ 0x50C, 0x0003 },
+	{ 0x50D, 0x0004 },
+	{ 0x50E, 0x0005 },
+	{ 0x510, 0x0001 },
+	{ 0x511, 0x0002 },
+	{ 0x512, 0x0003 },
+	{ 0x513, 0x0004 },
+	{ 0x514, 0x0005 },
+	{ 0x515, 0x0000 },
+	{ 0x201, 0x8084 },
+	{ 0x202, 0xBBDE },
+	{ 0x203, 0x00EC },
+	{ 0x500, 0x8000 },
+	{ 0x507, 0x1820 },
+	{ 0x508, 0x1820 },
+	{ 0x505, 0x0300 },
+	{ 0x506, 0x0300 },
+	{ 0x302, 0x2280 },
+	{ 0x303, 0x0080 },
+	{ 0x304, 0x2280 },
+	{ 0x305, 0x0080 },
+	{ 0x306, 0x2280 },
+	{ 0x307, 0x0080 },
+	{ 0x401, 0x0080 },
+	{ 0x402, 0x0080 },
+	{ 0x417, 0x3069 },
+	{ 0x900, 0x6318 },
+	{ 0x901, 0x6300 },
+	{ 0x902, 0x0FC8 },
+	{ 0x903, 0x03FE },
+	{ 0x904, 0x00E0 },
+	{ 0x905, 0x1EC4 },
+	{ 0x906, 0xF136 },
+	{ 0x907, 0x0409 },
+	{ 0x908, 0x04CC },
+	{ 0x909, 0x1C9B },
+	{ 0x90A, 0xF337 },
+	{ 0x90B, 0x040B },
+	{ 0x90C, 0x0CBB },
+	{ 0x90D, 0x16F8 },
+	{ 0x90E, 0xF7D9 },
+	{ 0x90F, 0x040A },
+	{ 0x910, 0x1F14 },
+	{ 0x911, 0x058C },
+	{ 0x912, 0x0563 },
+	{ 0x913, 0x4000 },
+	{ 0x916, 0x6318 },
+	{ 0x917, 0x6300 },
+	{ 0x918, 0x0FC8 },
+	{ 0x919, 0x03FE },
+	{ 0x91A, 0x00E0 },
+	{ 0x91B, 0x1EC4 },
+	{ 0x91C, 0xF136 },
+	{ 0x91D, 0x0409 },
+	{ 0x91E, 0x04CC },
+	{ 0x91F, 0x1C9B },
+	{ 0x920, 0xF337 },
+	{ 0x921, 0x040B },
+	{ 0x922, 0x0CBB },
+	{ 0x923, 0x16F8 },
+	{ 0x924, 0xF7D9 },
+	{ 0x925, 0x040A },
+	{ 0x926, 0x1F14 },
+	{ 0x927, 0x058C },
+	{ 0x928, 0x0563 },
+	{ 0x929, 0x4000 },
+	{ 0x709, 0x2000 },
+	{ 0x207, 0x200E },
+	{ 0x208, 0x20D4 },
+	{ 0x20A, 0x0080 },
+	{ 0x07, 0x0000 },
+};
+
+static int wm2200_reset(struct wm2200_priv *wm2200)
+{
+	if (wm2200->pdata.reset) {
+		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
+		gpio_set_value_cansleep(wm2200->pdata.reset, 1);
+
+		return 0;
+	} else {
+		return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
+				    0x2200);
+	}
+}
+
+static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
+static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
+static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
+
+static const char *wm2200_mixer_texts[] = {
+	"None",
+	"Tone Generator",
+	"AEC loopback",
+	"IN1L",
+	"IN1R",
+	"IN2L",
+	"IN2R",
+	"IN3L",
+	"IN3R",
+	"AIF1RX1",
+	"AIF1RX2",
+	"AIF1RX3",
+	"AIF1RX4",
+	"AIF1RX5",
+	"AIF1RX6",
+	"EQL",
+	"EQR",
+	"LHPF1",
+	"LHPF2",
+	"LHPF3",
+	"LHPF4",
+	"DSP1.1",
+	"DSP1.2",
+	"DSP1.3",
+	"DSP1.4",
+	"DSP1.5",
+	"DSP1.6",
+	"DSP2.1",
+	"DSP2.2",
+	"DSP2.3",
+	"DSP2.4",
+	"DSP2.5",
+	"DSP2.6",
+};
+
+static int wm2200_mixer_values[] = {
+	0x00,
+	0x04,   /* Tone */
+	0x08,   /* AEC */
+	0x10,   /* Input */
+	0x11,
+	0x12,
+	0x13,
+	0x14,
+	0x15,
+	0x20,   /* AIF */
+	0x21,
+	0x22,
+	0x23,
+	0x24,
+	0x25,
+	0x50,   /* EQ */
+	0x51,
+	0x52,
+	0x60,   /* LHPF1 */
+	0x61,   /* LHPF2 */
+	0x68,   /* DSP1 */
+	0x69,
+	0x6a,
+	0x6b,
+	0x6c,
+	0x6d,
+	0x70,   /* DSP2 */
+	0x71,
+	0x72,
+	0x73,
+	0x74,
+	0x75,
+};
+
+#define WM2200_MIXER_CONTROLS(name, base) \
+	SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
+		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
+	SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
+		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
+	SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
+		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
+	SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
+		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
+
+#define WM2200_MUX_ENUM_DECL(name, reg) \
+	SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, 			\
+				   wm2200_mixer_texts, wm2200_mixer_values)
+
+#define WM2200_MUX_CTL_DECL(name) \
+	const struct snd_kcontrol_new name##_mux =	\
+		SOC_DAPM_VALUE_ENUM("Route", name##_enum)
+
+#define WM2200_MIXER_ENUMS(name, base_reg) \
+	static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg);	     \
+	static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2);  \
+	static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4);  \
+	static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6);  \
+	static WM2200_MUX_CTL_DECL(name##_in1); \
+	static WM2200_MUX_CTL_DECL(name##_in2); \
+	static WM2200_MUX_CTL_DECL(name##_in3); \
+	static WM2200_MUX_CTL_DECL(name##_in4)
+
+static const struct snd_kcontrol_new wm2200_snd_controls[] = {
+SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
+	   WM2200_IN1_OSR_SHIFT, 1, 0),
+SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
+	   WM2200_IN2_OSR_SHIFT, 1, 0),
+SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
+	   WM2200_IN3_OSR_SHIFT, 1, 0),
+
+SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
+		 WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
+SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
+		 WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
+SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
+		 WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
+
+SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
+	     WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
+	     WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
+	     WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
+
+SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
+		 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
+		 0xbf, 0, digital_tlv),
+SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
+		 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
+		 0xbf, 0, digital_tlv),
+SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
+		 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
+		 0xbf, 0, digital_tlv),
+
+SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
+	   WM2200_OUT1_OSR_SHIFT, 1, 0),
+SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
+	   WM2200_OUT2_OSR_SHIFT, 1, 0),
+
+SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
+	     WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
+		 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
+		 digital_tlv),
+SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
+		 WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
+		 0x46, 0, out_tlv),
+
+SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
+	     WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
+		 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
+		 digital_tlv),
+SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
+	   WM2200_SPK1R_MUTE_SHIFT, 1, 0),
+};
+
+WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
+
+WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
+
+WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
+
+WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
+
+WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
+WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
+
+#define WM2200_MUX(name, ctrl) \
+	SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
+
+#define WM2200_MIXER_WIDGETS(name, name_str)	\
+	WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
+	WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
+	WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
+	WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
+	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
+
+#define WM2200_MIXER_INPUT_ROUTES(name)	\
+	{ name, "Tone Generator", "Tone Generator" }, \
+        { name, "IN1L", "IN1L PGA" }, \
+        { name, "IN1R", "IN1R PGA" }, \
+        { name, "IN2L", "IN2L PGA" }, \
+        { name, "IN2R", "IN2R PGA" }, \
+        { name, "IN3L", "IN3L PGA" }, \
+        { name, "IN3R", "IN3R PGA" }, \
+        { name, "DSP1.1", "DSP1" }, \
+        { name, "DSP1.2", "DSP1" }, \
+        { name, "DSP1.3", "DSP1" }, \
+        { name, "DSP1.4", "DSP1" }, \
+        { name, "DSP1.5", "DSP1" }, \
+        { name, "DSP1.6", "DSP1" }, \
+        { name, "DSP2.1", "DSP2" }, \
+        { name, "DSP2.2", "DSP2" }, \
+        { name, "DSP2.3", "DSP2" }, \
+        { name, "DSP2.4", "DSP2" }, \
+        { name, "DSP2.5", "DSP2" }, \
+        { name, "DSP2.6", "DSP2" }, \
+        { name, "AIF1RX1", "AIF1RX1" }, \
+        { name, "AIF1RX2", "AIF1RX2" }, \
+        { name, "AIF1RX3", "AIF1RX3" }, \
+        { name, "AIF1RX4", "AIF1RX4" }, \
+        { name, "AIF1RX5", "AIF1RX5" }, \
+        { name, "AIF1RX6", "AIF1RX6" }, \
+        { name, "EQL", "EQL" }, \
+        { name, "EQR", "EQR" }, \
+        { name, "LHPF1", "LHPF1" }, \
+        { name, "LHPF2", "LHPF2" }
+
+#define WM2200_MIXER_ROUTES(widget, name) \
+	{ widget, NULL, name " Mixer" },         \
+	{ name " Mixer", NULL, name " Input 1" }, \
+	{ name " Mixer", NULL, name " Input 2" }, \
+	{ name " Mixer", NULL, name " Input 3" }, \
+	{ name " Mixer", NULL, name " Input 4" }, \
+	WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
+	WM2200_MIXER_INPUT_ROUTES(name " Input 4")
+
+static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
+		    NULL, 0),
+SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
+		    NULL, 0),
+SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
+		    NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
+		    0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
+		    0, NULL, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
+SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
+
+SND_SOC_DAPM_INPUT("IN1L"),
+SND_SOC_DAPM_INPUT("IN1R"),
+SND_SOC_DAPM_INPUT("IN2L"),
+SND_SOC_DAPM_INPUT("IN2R"),
+SND_SOC_DAPM_INPUT("IN3L"),
+SND_SOC_DAPM_INPUT("IN3R"),
+
+SND_SOC_DAPM_SIGGEN("TONE"),
+SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
+		 WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
+		 NULL, 0),
+SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
+		 NULL, 0),
+
+SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
+SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0),
+
+SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
+		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
+
+SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
+		   WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
+		   WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
+		   WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
+		   WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
+		   WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
+		   WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
+		   WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
+		   WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
+		   WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
+		   WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
+		   WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
+		   WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
+		   WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
+		   WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
+
+SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
+		 0, NULL, 0),
+SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
+		 0, NULL, 0),
+
+SND_SOC_DAPM_OUTPUT("EPOUTLN"),
+SND_SOC_DAPM_OUTPUT("EPOUTLP"),
+SND_SOC_DAPM_OUTPUT("EPOUTRN"),
+SND_SOC_DAPM_OUTPUT("EPOUTRP"),
+SND_SOC_DAPM_OUTPUT("SPK"),
+
+WM2200_MIXER_WIDGETS(EQL, "EQL"),
+WM2200_MIXER_WIDGETS(EQR, "EQR"),
+
+WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
+WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
+
+WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"),
+WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"),
+WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"),
+WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"),
+
+WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
+WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
+WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
+WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
+WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
+WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
+
+WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
+WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
+WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
+WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
+};
+
+static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
+	/* Everything needs SYSCLK but only hook up things on the edge
+	 * of the chip */
+	{ "IN1L", NULL, "SYSCLK" },
+	{ "IN1R", NULL, "SYSCLK" },
+	{ "IN2L", NULL, "SYSCLK" },
+	{ "IN2R", NULL, "SYSCLK" },
+	{ "IN3L", NULL, "SYSCLK" },
+	{ "IN3R", NULL, "SYSCLK" },
+	{ "OUT1L", NULL, "SYSCLK" },
+	{ "OUT1R", NULL, "SYSCLK" },
+	{ "OUT2L", NULL, "SYSCLK" },
+	{ "OUT2R", NULL, "SYSCLK" },
+	{ "AIF1RX1", NULL, "SYSCLK" },
+	{ "AIF1RX2", NULL, "SYSCLK" },
+	{ "AIF1RX3", NULL, "SYSCLK" },
+	{ "AIF1RX4", NULL, "SYSCLK" },
+	{ "AIF1RX5", NULL, "SYSCLK" },
+	{ "AIF1RX6", NULL, "SYSCLK" },
+	{ "AIF1TX1", NULL, "SYSCLK" },
+	{ "AIF1TX2", NULL, "SYSCLK" },
+	{ "AIF1TX3", NULL, "SYSCLK" },
+	{ "AIF1TX4", NULL, "SYSCLK" },
+	{ "AIF1TX5", NULL, "SYSCLK" },
+	{ "AIF1TX6", NULL, "SYSCLK" },
+
+	{ "IN1L", NULL, "AVDD" },
+	{ "IN1R", NULL, "AVDD" },
+	{ "IN2L", NULL, "AVDD" },
+	{ "IN2R", NULL, "AVDD" },
+	{ "IN3L", NULL, "AVDD" },
+	{ "IN3R", NULL, "AVDD" },
+	{ "OUT1L", NULL, "AVDD" },
+	{ "OUT1R", NULL, "AVDD" },
+
+	{ "IN1L PGA", NULL, "IN1L" },
+	{ "IN1R PGA", NULL, "IN1R" },
+	{ "IN2L PGA", NULL, "IN2L" },
+	{ "IN2R PGA", NULL, "IN2R" },
+	{ "IN3L PGA", NULL, "IN3L" },
+	{ "IN3R PGA", NULL, "IN3R" },
+
+	{ "Tone Generator", NULL, "TONE" },
+
+	{ "CP2", NULL, "CPVDD" },
+	{ "MICBIAS1", NULL, "CP2" },
+	{ "MICBIAS2", NULL, "CP2" },
+
+	{ "CP1", NULL, "CPVDD" },
+	{ "EPD_LN", NULL, "CP1" },
+	{ "EPD_LP", NULL, "CP1" },
+	{ "EPD_RN", NULL, "CP1" },
+	{ "EPD_RP", NULL, "CP1" },
+
+	{ "EPD_LP", NULL, "OUT1L" },
+	{ "EPD_OUTP_LP", NULL, "EPD_LP" },
+	{ "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
+	{ "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
+
+	{ "EPD_LN", NULL, "OUT1L" },
+	{ "EPD_OUTP_LN", NULL, "EPD_LN" },
+	{ "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
+	{ "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
+
+	{ "EPD_RP", NULL, "OUT1R" },
+	{ "EPD_OUTP_RP", NULL, "EPD_RP" },
+	{ "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
+	{ "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
+
+	{ "EPD_RN", NULL, "OUT1R" },
+	{ "EPD_OUTP_RN", NULL, "EPD_RN" },
+	{ "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
+	{ "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
+
+	{ "SPK", NULL, "OUT2L" },
+	{ "SPK", NULL, "OUT2R" },
+
+	WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
+	WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
+	WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
+	WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
+
+	WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
+	WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
+	WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
+	WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
+
+	WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
+	WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
+	WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
+	WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
+	WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
+	WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
+
+	WM2200_MIXER_ROUTES("EQL", "EQL"),
+	WM2200_MIXER_ROUTES("EQR", "EQR"),
+
+	WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
+	WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
+};
+
+static int wm2200_probe(struct snd_soc_codec *codec)
+{
+	struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev);
+	int ret;
+
+	wm2200->codec = codec;
+	codec->control_data = wm2200->regmap;
+	codec->dapm.bias_level = SND_SOC_BIAS_OFF;
+
+	ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	int lrclk, bclk, fmt_val;
+
+	lrclk = 0;
+	bclk = 0;
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+		fmt_val = 0;
+		break;
+	case SND_SOC_DAIFMT_DSP_B:
+		fmt_val = 1;
+		break;
+	case SND_SOC_DAIFMT_I2S:
+		fmt_val = 2;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		fmt_val = 3;
+		break;
+	default:
+		dev_err(codec->dev, "Unsupported DAI format %d\n",
+			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	case SND_SOC_DAIFMT_CBS_CFM:
+		lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFS:
+		bclk |= WM2200_AIF1_BCLK_MSTR;
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM:
+		lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
+		bclk |= WM2200_AIF1_BCLK_MSTR;
+		break;
+	default:
+		dev_err(codec->dev, "Unsupported master mode %d\n",
+			fmt & SND_SOC_DAIFMT_MASTER_MASK);
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		bclk |= WM2200_AIF1_BCLK_INV;
+		lrclk |= WM2200_AIF1TX_LRCLK_INV;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		bclk |= WM2200_AIF1_BCLK_INV;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		lrclk |= WM2200_AIF1TX_LRCLK_INV;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
+			    WM2200_AIF1_BCLK_INV, bclk);
+	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
+			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
+			    lrclk);
+	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
+			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
+			    lrclk);
+	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
+			    WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
+
+	return 0;
+}
+
+static int wm2200_sr_code[] = {
+	0,
+	12000,
+	24000,
+	48000,
+	96000,
+	192000,
+	384000,
+	768000,
+	0,
+	11025,
+	22050,
+	44100,
+	88200,
+	176400,
+	352800,
+	705600,
+	4000,
+	8000,
+	16000,
+	32000,
+	64000,
+	128000,
+	256000,
+	512000,
+};
+
+#define WM2200_NUM_BCLK_RATES 12
+
+static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
+	6144000,
+	3072000,
+	2048000,
+	1536000,
+	768000,
+	512000,
+	384000,
+	256000,
+	192000,
+	128000,
+	96000,
+	64000,
+};	
+
+static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
+	5644800,
+	2882400,
+	1881600,
+	1411200,
+	705600,
+	470400,
+	352800,
+	176400,
+	117600,
+	88200,
+	58800,
+};
+
+static int wm2200_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	int i, bclk, lrclk, wl, fl, sr_code;
+	int *bclk_rates;
+
+	/* Data sizes if not using TDM */
+	wl = snd_pcm_format_width(params_format(params));
+	if (wl < 0)
+		return wl;
+	fl = snd_soc_params_to_frame_size(params);
+	if (fl < 0)
+		return fl;
+
+	dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
+		wl, fl);
+
+	/* Target BCLK rate */
+	bclk = snd_soc_params_to_bclk(params);
+	if (bclk < 0)
+		return bclk;
+
+	if (!wm2200->sysclk) {
+		dev_err(codec->dev, "SYSCLK has no rate set\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
+		if (wm2200_sr_code[i] == params_rate(params))
+			break;
+	if (i == ARRAY_SIZE(wm2200_sr_code)) {
+		dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
+			params_rate(params));
+		return -EINVAL;
+	}
+	sr_code = i;
+
+	dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
+		bclk, wm2200->sysclk);
+
+	if (wm2200->sysclk % 4000)
+		bclk_rates = wm2200_bclk_rates_cd;
+	else
+		bclk_rates = wm2200_bclk_rates_dat;
+
+	for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
+		if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
+			break;
+	if (i == WM2200_NUM_BCLK_RATES) {
+		dev_err(codec->dev,
+			"No valid BCLK for %dHz found from %dHz SYSCLK\n",
+			bclk, wm2200->sysclk);
+		return -EINVAL;
+	}
+
+	bclk = i;
+	dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
+	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
+			    WM2200_AIF1_BCLK_DIV_MASK, bclk);
+
+	lrclk = bclk_rates[bclk] / params_rate(params);
+	dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
+	    dai->symmetric_rates)
+		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
+				    WM2200_AIF1RX_BCPF_MASK, lrclk);
+	else
+		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
+				    WM2200_AIF1TX_BCPF_MASK, lrclk);
+
+	i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
+				    WM2200_AIF1RX_WL_MASK |
+				    WM2200_AIF1RX_SLOT_LEN_MASK, i);
+	else
+		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
+				    WM2200_AIF1TX_WL_MASK |
+				    WM2200_AIF1TX_SLOT_LEN_MASK, i);
+
+	snd_soc_update_bits(codec, WM2200_CLOCKING_4,
+			    WM2200_SAMPLE_RATE_1_MASK, sr_code);
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops wm2200_dai_ops = {
+	.set_fmt = wm2200_set_fmt,
+	.hw_params = wm2200_hw_params,
+};
+
+static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
+			     int source, unsigned int freq, int dir)
+{
+	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	int fval;
+
+	switch (clk_id) {
+	case WM2200_CLK_SYSCLK:
+		break;
+
+	default:
+		dev_err(codec->dev, "Unknown clock %d\n", clk_id);
+		return -EINVAL;
+	}
+
+	switch (source) {
+	case WM2200_CLKSRC_MCLK1:
+	case WM2200_CLKSRC_MCLK2:
+	case WM2200_CLKSRC_FLL:
+	case WM2200_CLKSRC_BCLK1:
+		break;
+	default:
+		dev_err(codec->dev, "Invalid source %d\n", source);
+		return -EINVAL;
+	}
+
+	switch (freq) {
+	case 22579200:
+	case 24576000:
+		fval = 2;
+		break;
+	default:
+		dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
+		return -EINVAL;
+	}
+
+	/* TODO: Check if MCLKs are in use and enable/disable pulls to
+	 * match.
+	 */
+
+	snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
+			    WM2200_SYSCLK_SRC_MASK,
+			    fval << WM2200_SYSCLK_FREQ_SHIFT | source);
+
+	wm2200->sysclk = freq;
+
+	return 0;
+}
+
+struct _fll_div {
+	u16 fll_fratio;
+	u16 fll_outdiv;
+	u16 fll_refclk_div;
+	u16 n;
+	u16 theta;
+	u16 lambda;
+};
+
+static struct {
+	unsigned int min;
+	unsigned int max;
+	u16 fll_fratio;
+	int ratio;
+} fll_fratios[] = {
+	{       0,    64000, 4, 16 },
+	{   64000,   128000, 3,  8 },
+	{  128000,   256000, 2,  4 },
+	{  256000,  1000000, 1,  2 },
+	{ 1000000, 13500000, 0,  1 },
+};
+
+static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
+		       unsigned int Fout)
+{
+	unsigned int target;
+	unsigned int div;
+	unsigned int fratio, gcd_fll;
+	int i;
+
+	/* Fref must be <=13.5MHz */
+	div = 1;
+	fll_div->fll_refclk_div = 0;
+	while ((Fref / div) > 13500000) {
+		div *= 2;
+		fll_div->fll_refclk_div++;
+
+		if (div > 8) {
+			pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
+			       Fref);
+			return -EINVAL;
+		}
+	}
+
+	pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
+
+	/* Apply the division for our remaining calculations */
+	Fref /= div;
+
+	/* Fvco should be 90-100MHz; don't check the upper bound */
+	div = 2;
+	while (Fout * div < 90000000) {
+		div++;
+		if (div > 64) {
+			pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
+			       Fout);
+			return -EINVAL;
+		}
+	}
+	target = Fout * div;
+	fll_div->fll_outdiv = div - 1;
+
+	pr_debug("FLL Fvco=%dHz\n", target);
+
+	/* Find an appropraite FLL_FRATIO and factor it out of the target */
+	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
+		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
+			fll_div->fll_fratio = fll_fratios[i].fll_fratio;
+			fratio = fll_fratios[i].ratio;
+			break;
+		}
+	}
+	if (i == ARRAY_SIZE(fll_fratios)) {
+		pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
+		return -EINVAL;
+	}
+
+	fll_div->n = target / (fratio * Fref);
+
+	if (target % Fref == 0) {
+		fll_div->theta = 0;
+		fll_div->lambda = 0;
+	} else {
+		gcd_fll = gcd(target, fratio * Fref);
+
+		fll_div->theta = (target - (fll_div->n * fratio * Fref))
+			/ gcd_fll;
+		fll_div->lambda = (fratio * Fref) / gcd_fll;
+	}
+
+	pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
+		 fll_div->n, fll_div->theta, fll_div->lambda);
+	pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
+		 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
+		 fll_div->fll_refclk_div);
+
+	return 0;
+}
+
+static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
+			  unsigned int Fref, unsigned int Fout)
+{
+	struct i2c_client *i2c = to_i2c_client(codec->dev);
+	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
+	struct _fll_div factors;
+	int ret, i, timeout;
+
+	if (!Fout) {
+		dev_dbg(codec->dev, "FLL disabled");
+
+		if (wm2200->fll_fout)
+			pm_runtime_put(codec->dev);
+
+		wm2200->fll_fout = 0;
+		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
+				    WM2200_FLL_ENA, 0);
+		return 0;
+	}
+
+	switch (source) {
+	case WM2200_FLL_SRC_MCLK1:
+	case WM2200_FLL_SRC_MCLK2:
+	case WM2200_FLL_SRC_BCLK:
+		break;
+	default:
+		dev_err(codec->dev, "Invalid FLL source %d\n", source);
+		return -EINVAL;
+	}
+
+	ret = fll_factors(&factors, Fref, Fout);
+	if (ret < 0)
+		return ret;
+
+	/* Disable the FLL while we reconfigure */
+	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
+
+	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
+			    WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
+			    (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
+			    factors.fll_fratio);
+	if (factors.theta) {
+		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
+				    WM2200_FLL_FRACN_ENA,
+				    WM2200_FLL_FRACN_ENA);
+		snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
+				    WM2200_FLL_EFS_ENA,
+				    WM2200_FLL_EFS_ENA);
+	} else {
+		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
+				    WM2200_FLL_FRACN_ENA, 0);
+		snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
+				    WM2200_FLL_EFS_ENA, 0);
+	}
+
+	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
+			    factors.theta);
+	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
+			    factors.n);
+	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
+			    WM2200_FLL_CLK_REF_DIV_MASK |
+			    WM2200_FLL_CLK_REF_SRC_MASK,
+			    (factors.fll_refclk_div
+			     << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
+	snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
+			    WM2200_FLL_LAMBDA_MASK, factors.lambda);
+
+	/* Clear any pending completions */
+	try_wait_for_completion(&wm2200->fll_lock);
+
+	pm_runtime_get_sync(codec->dev);
+
+	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
+			    WM2200_FLL_ENA, WM2200_FLL_ENA);
+
+	if (i2c->irq)
+		timeout = 2;
+	else
+		timeout = 50;
+
+	snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
+			    WM2200_SYSCLK_ENA);
+
+	/* Poll for the lock; will use the interrupt to exit quickly */
+	for (i = 0; i < timeout; i++) {
+		if (i2c->irq) {
+			ret = wait_for_completion_timeout(&wm2200->fll_lock,
+							  msecs_to_jiffies(25));
+			if (ret > 0)
+				break;
+		} else {
+			msleep(1);
+		}
+
+		ret = snd_soc_read(codec,
+				   WM2200_INTERRUPT_RAW_STATUS_2);
+		if (ret < 0) {
+			dev_err(codec->dev,
+				"Failed to read FLL status: %d\n",
+				ret);
+			continue;
+		}
+		if (ret & WM2200_FLL_LOCK_STS)
+			break;
+	}
+	if (i == timeout) {
+		dev_err(codec->dev, "FLL lock timed out\n");
+		pm_runtime_put(codec->dev);
+		return -ETIMEDOUT;
+	}
+
+	wm2200->fll_src = source;
+	wm2200->fll_fref = Fref;
+	wm2200->fll_fout = Fout;
+
+	dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
+
+	return 0;
+}
+
+static int wm2200_dai_probe(struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	unsigned int val = 0;
+	int ret;
+
+	ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
+	if (ret >= 0) {
+		if ((ret & WM2200_GP1_FN_MASK) != 0) {
+			dai->symmetric_rates = true;
+			val = WM2200_AIF1TX_LRCLK_SRC;
+		}
+	} else {
+		dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
+	}
+
+	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
+			    WM2200_AIF1TX_LRCLK_SRC, val);
+
+	return 0;
+}
+
+#define WM2200_RATES SNDRV_PCM_RATE_8000_48000
+
+#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver wm2200_dai = {
+	.name = "wm2200",
+	.probe = wm2200_dai_probe,
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = WM2200_RATES,
+		.formats = WM2200_FORMATS,
+	},
+	.capture = {
+		 .stream_name = "Capture",
+		 .channels_min = 2,
+		 .channels_max = 2,
+		 .rates = WM2200_RATES,
+		 .formats = WM2200_FORMATS,
+	 },
+	.ops = &wm2200_dai_ops,
+};
+
+static struct snd_soc_codec_driver soc_codec_wm2200 = {
+	.probe = wm2200_probe,
+
+	.idle_bias_off = true,
+	.ignore_pmdown_time = true,
+	.set_sysclk = wm2200_set_sysclk,
+	.set_pll = wm2200_set_fll,
+
+	.controls = wm2200_snd_controls,
+	.num_controls = ARRAY_SIZE(wm2200_snd_controls),
+	.dapm_widgets = wm2200_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
+	.dapm_routes = wm2200_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
+};
+
+static irqreturn_t wm2200_irq(int irq, void *data)
+{
+	struct wm2200_priv *wm2200 = data;
+	unsigned int val, mask;
+	int ret;
+
+	ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
+	if (ret != 0) {
+		dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
+		return IRQ_NONE;
+	}
+
+	ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
+			   &mask);
+	if (ret != 0) {
+		dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
+		mask = 0;
+	}
+
+	val &= ~mask;
+
+	if (val & WM2200_FLL_LOCK_EINT) {
+		dev_dbg(wm2200->dev, "FLL locked\n");
+		complete(&wm2200->fll_lock);
+	}
+
+	if (val) {
+		regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
+		
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
+}
+
+static const struct regmap_config wm2200_regmap = {
+	.reg_bits = 16,
+	.val_bits = 16,
+
+	.max_register = WM2200_MAX_REGISTER,
+	.reg_defaults = wm2200_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
+	.volatile_reg = wm2200_volatile_register,
+	.readable_reg = wm2200_readable_register,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static const unsigned int wm2200_dig_vu[] = {
+	WM2200_DAC_DIGITAL_VOLUME_1L,
+	WM2200_DAC_DIGITAL_VOLUME_1R,
+	WM2200_DAC_DIGITAL_VOLUME_2L,
+	WM2200_DAC_DIGITAL_VOLUME_2R,
+	WM2200_ADC_DIGITAL_VOLUME_1L,
+	WM2200_ADC_DIGITAL_VOLUME_1R,
+	WM2200_ADC_DIGITAL_VOLUME_2L,
+	WM2200_ADC_DIGITAL_VOLUME_2R,
+	WM2200_ADC_DIGITAL_VOLUME_3L,
+	WM2200_ADC_DIGITAL_VOLUME_3R,
+};
+
+static const unsigned int wm2200_mic_ctrl_reg[] = {
+	WM2200_IN1L_CONTROL,
+	WM2200_IN2L_CONTROL,
+	WM2200_IN3L_CONTROL,
+};
+
+static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
+				      const struct i2c_device_id *id)
+{
+	struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
+	struct wm2200_priv *wm2200;
+	unsigned int reg;
+	int ret, i;
+
+	wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
+			      GFP_KERNEL);
+	if (wm2200 == NULL)
+		return -ENOMEM;
+
+	wm2200->dev = &i2c->dev;
+	init_completion(&wm2200->fll_lock);
+
+	wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap);
+	if (IS_ERR(wm2200->regmap)) {
+		ret = PTR_ERR(wm2200->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
+	if (pdata)
+		wm2200->pdata = *pdata;
+
+	i2c_set_clientdata(i2c, wm2200);
+
+	for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
+		wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
+
+	ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies),
+				 wm2200->core_supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
+			ret);
+		goto err_regmap;
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
+				    wm2200->core_supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
+			ret);
+		goto err_core;
+	}
+
+	if (wm2200->pdata.ldo_ena) {
+		ret = gpio_request_one(wm2200->pdata.ldo_ena,
+				       GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA");
+		if (ret < 0) {
+			dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
+				wm2200->pdata.ldo_ena, ret);
+			goto err_enable;
+		}
+		msleep(2);
+	}
+
+	if (wm2200->pdata.reset) {
+		ret = gpio_request_one(wm2200->pdata.reset,
+				       GPIOF_OUT_INIT_HIGH, "WM2200 /RESET");
+		if (ret < 0) {
+			dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
+				wm2200->pdata.reset, ret);
+			goto err_ldo;
+		}
+	}
+
+	ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
+		goto err_reset;
+	}
+	switch (reg) {
+	case 0x2200:
+		break;
+
+	default:
+		dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
+		ret = -EINVAL;
+		goto err_reset;
+	}
+
+	ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to read revision register\n");
+		goto err_reset;
+	}
+
+	wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
+
+	dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
+
+	switch (wm2200->rev) {
+	case 0:
+		ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
+					    ARRAY_SIZE(wm2200_reva_patch));
+		if (ret != 0) {
+			dev_err(&i2c->dev, "Failed to register patch: %d\n",
+				ret);
+		}
+		break;
+	default:
+		break;
+	}
+
+	ret = wm2200_reset(wm2200);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to issue reset\n");
+		goto err_reset;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
+		if (!wm2200->pdata.gpio_defaults[i])
+			continue;
+
+		regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
+			     wm2200->pdata.gpio_defaults[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
+		regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
+				   WM2200_OUT_VU, WM2200_OUT_VU);
+
+	/* Assign slots 1-6 to channels 1-6 for both TX and RX */
+	for (i = 0; i < 6; i++) {
+		regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
+		regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
+		regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
+				   WM2200_IN1_MODE_MASK |
+				   WM2200_IN1_DMIC_SUP_MASK,
+				   (wm2200->pdata.in_mode[i] <<
+				    WM2200_IN1_MODE_SHIFT) |
+				   (wm2200->pdata.dmic_sup[i] <<
+				    WM2200_IN1_DMIC_SUP_SHIFT));
+	}
+
+	if (i2c->irq) {
+		ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
+					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					   "wm2200", wm2200);
+		if (ret == 0)
+			regmap_update_bits(wm2200->regmap,
+					   WM2200_INTERRUPT_STATUS_2_MASK,
+					   WM2200_FLL_LOCK_EINT, 0);
+		else
+			dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+				i2c->irq, ret);
+	}
+
+	pm_runtime_set_active(&i2c->dev);
+	pm_runtime_enable(&i2c->dev);
+	pm_request_idle(&i2c->dev);
+
+	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
+				     &wm2200_dai, 1);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+		goto err_pm_runtime;
+	}
+
+	return 0;
+
+err_pm_runtime:
+	pm_runtime_disable(&i2c->dev);
+err_reset:
+	if (wm2200->pdata.reset) {
+		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
+		gpio_free(wm2200->pdata.reset);
+	}
+err_ldo:
+	if (wm2200->pdata.ldo_ena) {
+		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
+		gpio_free(wm2200->pdata.ldo_ena);
+	}
+err_enable:
+	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
+			       wm2200->core_supplies);
+err_core:
+	regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
+			    wm2200->core_supplies);
+err_regmap:
+	regmap_exit(wm2200->regmap);
+err:
+	return ret;
+}
+
+static __devexit int wm2200_i2c_remove(struct i2c_client *i2c)
+{
+	struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
+
+	snd_soc_unregister_codec(&i2c->dev);
+	if (i2c->irq)
+		free_irq(i2c->irq, wm2200);
+	if (wm2200->pdata.reset) {
+		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
+		gpio_free(wm2200->pdata.reset);
+	}
+	if (wm2200->pdata.ldo_ena) {
+		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
+		gpio_free(wm2200->pdata.ldo_ena);
+	}
+	regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
+			    wm2200->core_supplies);
+	regmap_exit(wm2200->regmap);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int wm2200_runtime_suspend(struct device *dev)
+{
+	struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
+
+	regcache_cache_only(wm2200->regmap, true);
+	regcache_mark_dirty(wm2200->regmap);
+	if (wm2200->pdata.ldo_ena)
+		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
+	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
+			       wm2200->core_supplies);
+
+	return 0;
+}
+
+static int wm2200_runtime_resume(struct device *dev)
+{
+	struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
+				    wm2200->core_supplies);
+	if (ret != 0) {
+		dev_err(dev, "Failed to enable supplies: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (wm2200->pdata.ldo_ena) {
+		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1);
+		msleep(2);
+	}
+
+	regcache_cache_only(wm2200->regmap, false);
+	regcache_sync(wm2200->regmap);
+
+	return 0;
+}
+#endif
+
+static struct dev_pm_ops wm2200_pm = {
+	SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
+			   NULL)
+};
+
+static const struct i2c_device_id wm2200_i2c_id[] = {
+	{ "wm2200", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
+
+static struct i2c_driver wm2200_i2c_driver = {
+	.driver = {
+		.name = "wm2200",
+		.owner = THIS_MODULE,
+		.pm = &wm2200_pm,
+	},
+	.probe =    wm2200_i2c_probe,
+	.remove =   __devexit_p(wm2200_i2c_remove),
+	.id_table = wm2200_i2c_id,
+};
+
+static int __init wm2200_modinit(void)
+{
+	return i2c_add_driver(&wm2200_i2c_driver);
+}
+module_init(wm2200_modinit);
+
+static void __exit wm2200_exit(void)
+{
+	i2c_del_driver(&wm2200_i2c_driver);
+}
+module_exit(wm2200_exit);
+
+MODULE_DESCRIPTION("ASoC WM2200 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2200.h b/sound/soc/codecs/wm2200.h
new file mode 100644
index 0000000..5d719d6
--- /dev/null
+++ b/sound/soc/codecs/wm2200.h
@@ -0,0 +1,3674 @@
+/*
+ * wm2200.h - WM2200 audio codec interface
+ *
+ * Copyright 2012 Wolfson Microelectronics PLC.
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef _WM2200_H
+#define _WM2200_H
+
+#define WM2200_CLK_SYSCLK 1
+
+#define WM2200_CLKSRC_MCLK1  0
+#define WM2200_CLKSRC_MCLK2  1
+#define WM2200_CLKSRC_FLL    4
+#define WM2200_CLKSRC_BCLK1  8
+
+#define WM2200_FLL_SRC_MCLK1 0
+#define WM2200_FLL_SRC_MCLK2 1
+#define WM2200_FLL_SRC_BCLK  2
+
+/*
+ * Register values.
+ */
+#define WM2200_SOFTWARE_RESET                   0x00
+#define WM2200_DEVICE_REVISION                  0x01
+#define WM2200_TONE_GENERATOR_1                 0x0B
+#define WM2200_CLOCKING_3                       0x102
+#define WM2200_CLOCKING_4                       0x103
+#define WM2200_FLL_CONTROL_1                    0x111
+#define WM2200_FLL_CONTROL_2                    0x112
+#define WM2200_FLL_CONTROL_3                    0x113
+#define WM2200_FLL_CONTROL_4                    0x114
+#define WM2200_FLL_CONTROL_6                    0x116
+#define WM2200_FLL_CONTROL_7                    0x117
+#define WM2200_FLL_EFS_1                        0x119
+#define WM2200_FLL_EFS_2                        0x11A
+#define WM2200_MIC_CHARGE_PUMP_1                0x200
+#define WM2200_MIC_CHARGE_PUMP_2                0x201
+#define WM2200_DM_CHARGE_PUMP_1                 0x202
+#define WM2200_MIC_BIAS_CTRL_1                  0x20C
+#define WM2200_MIC_BIAS_CTRL_2                  0x20D
+#define WM2200_EAR_PIECE_CTRL_1                 0x20F
+#define WM2200_EAR_PIECE_CTRL_2                 0x210
+#define WM2200_INPUT_ENABLES                    0x301
+#define WM2200_IN1L_CONTROL                     0x302
+#define WM2200_IN1R_CONTROL                     0x303
+#define WM2200_IN2L_CONTROL                     0x304
+#define WM2200_IN2R_CONTROL                     0x305
+#define WM2200_IN3L_CONTROL                     0x306
+#define WM2200_IN3R_CONTROL                     0x307
+#define WM2200_RXANC_SRC                        0x30A
+#define WM2200_INPUT_VOLUME_RAMP                0x30B
+#define WM2200_ADC_DIGITAL_VOLUME_1L            0x30C
+#define WM2200_ADC_DIGITAL_VOLUME_1R            0x30D
+#define WM2200_ADC_DIGITAL_VOLUME_2L            0x30E
+#define WM2200_ADC_DIGITAL_VOLUME_2R            0x30F
+#define WM2200_ADC_DIGITAL_VOLUME_3L            0x310
+#define WM2200_ADC_DIGITAL_VOLUME_3R            0x311
+#define WM2200_OUTPUT_ENABLES                   0x400
+#define WM2200_DAC_VOLUME_LIMIT_1L              0x401
+#define WM2200_DAC_VOLUME_LIMIT_1R              0x402
+#define WM2200_DAC_VOLUME_LIMIT_2L              0x403
+#define WM2200_DAC_VOLUME_LIMIT_2R              0x404
+#define WM2200_DAC_AEC_CONTROL_1                0x409
+#define WM2200_OUTPUT_VOLUME_RAMP               0x40A
+#define WM2200_DAC_DIGITAL_VOLUME_1L            0x40B
+#define WM2200_DAC_DIGITAL_VOLUME_1R            0x40C
+#define WM2200_DAC_DIGITAL_VOLUME_2L            0x40D
+#define WM2200_DAC_DIGITAL_VOLUME_2R            0x40E
+#define WM2200_PDM_1                            0x417
+#define WM2200_PDM_2                            0x418
+#define WM2200_AUDIO_IF_1_1                     0x500
+#define WM2200_AUDIO_IF_1_2                     0x501
+#define WM2200_AUDIO_IF_1_3                     0x502
+#define WM2200_AUDIO_IF_1_4                     0x503
+#define WM2200_AUDIO_IF_1_5                     0x504
+#define WM2200_AUDIO_IF_1_6                     0x505
+#define WM2200_AUDIO_IF_1_7                     0x506
+#define WM2200_AUDIO_IF_1_8                     0x507
+#define WM2200_AUDIO_IF_1_9                     0x508
+#define WM2200_AUDIO_IF_1_10                    0x509
+#define WM2200_AUDIO_IF_1_11                    0x50A
+#define WM2200_AUDIO_IF_1_12                    0x50B
+#define WM2200_AUDIO_IF_1_13                    0x50C
+#define WM2200_AUDIO_IF_1_14                    0x50D
+#define WM2200_AUDIO_IF_1_15                    0x50E
+#define WM2200_AUDIO_IF_1_16                    0x50F
+#define WM2200_AUDIO_IF_1_17                    0x510
+#define WM2200_AUDIO_IF_1_18                    0x511
+#define WM2200_AUDIO_IF_1_19                    0x512
+#define WM2200_AUDIO_IF_1_20                    0x513
+#define WM2200_AUDIO_IF_1_21                    0x514
+#define WM2200_AUDIO_IF_1_22                    0x515
+#define WM2200_OUT1LMIX_INPUT_1_SOURCE          0x600
+#define WM2200_OUT1LMIX_INPUT_1_VOLUME          0x601
+#define WM2200_OUT1LMIX_INPUT_2_SOURCE          0x602
+#define WM2200_OUT1LMIX_INPUT_2_VOLUME          0x603
+#define WM2200_OUT1LMIX_INPUT_3_SOURCE          0x604
+#define WM2200_OUT1LMIX_INPUT_3_VOLUME          0x605
+#define WM2200_OUT1LMIX_INPUT_4_SOURCE          0x606
+#define WM2200_OUT1LMIX_INPUT_4_VOLUME          0x607
+#define WM2200_OUT1RMIX_INPUT_1_SOURCE          0x608
+#define WM2200_OUT1RMIX_INPUT_1_VOLUME          0x609
+#define WM2200_OUT1RMIX_INPUT_2_SOURCE          0x60A
+#define WM2200_OUT1RMIX_INPUT_2_VOLUME          0x60B
+#define WM2200_OUT1RMIX_INPUT_3_SOURCE          0x60C
+#define WM2200_OUT1RMIX_INPUT_3_VOLUME          0x60D
+#define WM2200_OUT1RMIX_INPUT_4_SOURCE          0x60E
+#define WM2200_OUT1RMIX_INPUT_4_VOLUME          0x60F
+#define WM2200_OUT2LMIX_INPUT_1_SOURCE          0x610
+#define WM2200_OUT2LMIX_INPUT_1_VOLUME          0x611
+#define WM2200_OUT2LMIX_INPUT_2_SOURCE          0x612
+#define WM2200_OUT2LMIX_INPUT_2_VOLUME          0x613
+#define WM2200_OUT2LMIX_INPUT_3_SOURCE          0x614
+#define WM2200_OUT2LMIX_INPUT_3_VOLUME          0x615
+#define WM2200_OUT2LMIX_INPUT_4_SOURCE          0x616
+#define WM2200_OUT2LMIX_INPUT_4_VOLUME          0x617
+#define WM2200_OUT2RMIX_INPUT_1_SOURCE          0x618
+#define WM2200_OUT2RMIX_INPUT_1_VOLUME          0x619
+#define WM2200_OUT2RMIX_INPUT_2_SOURCE          0x61A
+#define WM2200_OUT2RMIX_INPUT_2_VOLUME          0x61B
+#define WM2200_OUT2RMIX_INPUT_3_SOURCE          0x61C
+#define WM2200_OUT2RMIX_INPUT_3_VOLUME          0x61D
+#define WM2200_OUT2RMIX_INPUT_4_SOURCE          0x61E
+#define WM2200_OUT2RMIX_INPUT_4_VOLUME          0x61F
+#define WM2200_AIF1TX1MIX_INPUT_1_SOURCE        0x620
+#define WM2200_AIF1TX1MIX_INPUT_1_VOLUME        0x621
+#define WM2200_AIF1TX1MIX_INPUT_2_SOURCE        0x622
+#define WM2200_AIF1TX1MIX_INPUT_2_VOLUME        0x623
+#define WM2200_AIF1TX1MIX_INPUT_3_SOURCE        0x624
+#define WM2200_AIF1TX1MIX_INPUT_3_VOLUME        0x625
+#define WM2200_AIF1TX1MIX_INPUT_4_SOURCE        0x626
+#define WM2200_AIF1TX1MIX_INPUT_4_VOLUME        0x627
+#define WM2200_AIF1TX2MIX_INPUT_1_SOURCE        0x628
+#define WM2200_AIF1TX2MIX_INPUT_1_VOLUME        0x629
+#define WM2200_AIF1TX2MIX_INPUT_2_SOURCE        0x62A
+#define WM2200_AIF1TX2MIX_INPUT_2_VOLUME        0x62B
+#define WM2200_AIF1TX2MIX_INPUT_3_SOURCE        0x62C
+#define WM2200_AIF1TX2MIX_INPUT_3_VOLUME        0x62D
+#define WM2200_AIF1TX2MIX_INPUT_4_SOURCE        0x62E
+#define WM2200_AIF1TX2MIX_INPUT_4_VOLUME        0x62F
+#define WM2200_AIF1TX3MIX_INPUT_1_SOURCE        0x630
+#define WM2200_AIF1TX3MIX_INPUT_1_VOLUME        0x631
+#define WM2200_AIF1TX3MIX_INPUT_2_SOURCE        0x632
+#define WM2200_AIF1TX3MIX_INPUT_2_VOLUME        0x633
+#define WM2200_AIF1TX3MIX_INPUT_3_SOURCE        0x634
+#define WM2200_AIF1TX3MIX_INPUT_3_VOLUME        0x635
+#define WM2200_AIF1TX3MIX_INPUT_4_SOURCE        0x636
+#define WM2200_AIF1TX3MIX_INPUT_4_VOLUME        0x637
+#define WM2200_AIF1TX4MIX_INPUT_1_SOURCE        0x638
+#define WM2200_AIF1TX4MIX_INPUT_1_VOLUME        0x639
+#define WM2200_AIF1TX4MIX_INPUT_2_SOURCE        0x63A
+#define WM2200_AIF1TX4MIX_INPUT_2_VOLUME        0x63B
+#define WM2200_AIF1TX4MIX_INPUT_3_SOURCE        0x63C
+#define WM2200_AIF1TX4MIX_INPUT_3_VOLUME        0x63D
+#define WM2200_AIF1TX4MIX_INPUT_4_SOURCE        0x63E
+#define WM2200_AIF1TX4MIX_INPUT_4_VOLUME        0x63F
+#define WM2200_AIF1TX5MIX_INPUT_1_SOURCE        0x640
+#define WM2200_AIF1TX5MIX_INPUT_1_VOLUME        0x641
+#define WM2200_AIF1TX5MIX_INPUT_2_SOURCE        0x642
+#define WM2200_AIF1TX5MIX_INPUT_2_VOLUME        0x643
+#define WM2200_AIF1TX5MIX_INPUT_3_SOURCE        0x644
+#define WM2200_AIF1TX5MIX_INPUT_3_VOLUME        0x645
+#define WM2200_AIF1TX5MIX_INPUT_4_SOURCE        0x646
+#define WM2200_AIF1TX5MIX_INPUT_4_VOLUME        0x647
+#define WM2200_AIF1TX6MIX_INPUT_1_SOURCE        0x648
+#define WM2200_AIF1TX6MIX_INPUT_1_VOLUME        0x649
+#define WM2200_AIF1TX6MIX_INPUT_2_SOURCE        0x64A
+#define WM2200_AIF1TX6MIX_INPUT_2_VOLUME        0x64B
+#define WM2200_AIF1TX6MIX_INPUT_3_SOURCE        0x64C
+#define WM2200_AIF1TX6MIX_INPUT_3_VOLUME        0x64D
+#define WM2200_AIF1TX6MIX_INPUT_4_SOURCE        0x64E
+#define WM2200_AIF1TX6MIX_INPUT_4_VOLUME        0x64F
+#define WM2200_EQLMIX_INPUT_1_SOURCE            0x650
+#define WM2200_EQLMIX_INPUT_1_VOLUME            0x651
+#define WM2200_EQLMIX_INPUT_2_SOURCE            0x652
+#define WM2200_EQLMIX_INPUT_2_VOLUME            0x653
+#define WM2200_EQLMIX_INPUT_3_SOURCE            0x654
+#define WM2200_EQLMIX_INPUT_3_VOLUME            0x655
+#define WM2200_EQLMIX_INPUT_4_SOURCE            0x656
+#define WM2200_EQLMIX_INPUT_4_VOLUME            0x657
+#define WM2200_EQRMIX_INPUT_1_SOURCE            0x658
+#define WM2200_EQRMIX_INPUT_1_VOLUME            0x659
+#define WM2200_EQRMIX_INPUT_2_SOURCE            0x65A
+#define WM2200_EQRMIX_INPUT_2_VOLUME            0x65B
+#define WM2200_EQRMIX_INPUT_3_SOURCE            0x65C
+#define WM2200_EQRMIX_INPUT_3_VOLUME            0x65D
+#define WM2200_EQRMIX_INPUT_4_SOURCE            0x65E
+#define WM2200_EQRMIX_INPUT_4_VOLUME            0x65F
+#define WM2200_LHPF1MIX_INPUT_1_SOURCE          0x660
+#define WM2200_LHPF1MIX_INPUT_1_VOLUME          0x661
+#define WM2200_LHPF1MIX_INPUT_2_SOURCE          0x662
+#define WM2200_LHPF1MIX_INPUT_2_VOLUME          0x663
+#define WM2200_LHPF1MIX_INPUT_3_SOURCE          0x664
+#define WM2200_LHPF1MIX_INPUT_3_VOLUME          0x665
+#define WM2200_LHPF1MIX_INPUT_4_SOURCE          0x666
+#define WM2200_LHPF1MIX_INPUT_4_VOLUME          0x667
+#define WM2200_LHPF2MIX_INPUT_1_SOURCE          0x668
+#define WM2200_LHPF2MIX_INPUT_1_VOLUME          0x669
+#define WM2200_LHPF2MIX_INPUT_2_SOURCE          0x66A
+#define WM2200_LHPF2MIX_INPUT_2_VOLUME          0x66B
+#define WM2200_LHPF2MIX_INPUT_3_SOURCE          0x66C
+#define WM2200_LHPF2MIX_INPUT_3_VOLUME          0x66D
+#define WM2200_LHPF2MIX_INPUT_4_SOURCE          0x66E
+#define WM2200_LHPF2MIX_INPUT_4_VOLUME          0x66F
+#define WM2200_DSP1LMIX_INPUT_1_SOURCE          0x670
+#define WM2200_DSP1LMIX_INPUT_1_VOLUME          0x671
+#define WM2200_DSP1LMIX_INPUT_2_SOURCE          0x672
+#define WM2200_DSP1LMIX_INPUT_2_VOLUME          0x673
+#define WM2200_DSP1LMIX_INPUT_3_SOURCE          0x674
+#define WM2200_DSP1LMIX_INPUT_3_VOLUME          0x675
+#define WM2200_DSP1LMIX_INPUT_4_SOURCE          0x676
+#define WM2200_DSP1LMIX_INPUT_4_VOLUME          0x677
+#define WM2200_DSP1RMIX_INPUT_1_SOURCE          0x678
+#define WM2200_DSP1RMIX_INPUT_1_VOLUME          0x679
+#define WM2200_DSP1RMIX_INPUT_2_SOURCE          0x67A
+#define WM2200_DSP1RMIX_INPUT_2_VOLUME          0x67B
+#define WM2200_DSP1RMIX_INPUT_3_SOURCE          0x67C
+#define WM2200_DSP1RMIX_INPUT_3_VOLUME          0x67D
+#define WM2200_DSP1RMIX_INPUT_4_SOURCE          0x67E
+#define WM2200_DSP1RMIX_INPUT_4_VOLUME          0x67F
+#define WM2200_DSP1AUX1MIX_INPUT_1_SOURCE       0x680
+#define WM2200_DSP1AUX2MIX_INPUT_1_SOURCE       0x681
+#define WM2200_DSP1AUX3MIX_INPUT_1_SOURCE       0x682
+#define WM2200_DSP1AUX4MIX_INPUT_1_SOURCE       0x683
+#define WM2200_DSP1AUX5MIX_INPUT_1_SOURCE       0x684
+#define WM2200_DSP1AUX6MIX_INPUT_1_SOURCE       0x685
+#define WM2200_DSP2LMIX_INPUT_1_SOURCE          0x686
+#define WM2200_DSP2LMIX_INPUT_1_VOLUME          0x687
+#define WM2200_DSP2LMIX_INPUT_2_SOURCE          0x688
+#define WM2200_DSP2LMIX_INPUT_2_VOLUME          0x689
+#define WM2200_DSP2LMIX_INPUT_3_SOURCE          0x68A
+#define WM2200_DSP2LMIX_INPUT_3_VOLUME          0x68B
+#define WM2200_DSP2LMIX_INPUT_4_SOURCE          0x68C
+#define WM2200_DSP2LMIX_INPUT_4_VOLUME          0x68D
+#define WM2200_DSP2RMIX_INPUT_1_SOURCE          0x68E
+#define WM2200_DSP2RMIX_INPUT_1_VOLUME          0x68F
+#define WM2200_DSP2RMIX_INPUT_2_SOURCE          0x690
+#define WM2200_DSP2RMIX_INPUT_2_VOLUME          0x691
+#define WM2200_DSP2RMIX_INPUT_3_SOURCE          0x692
+#define WM2200_DSP2RMIX_INPUT_3_VOLUME          0x693
+#define WM2200_DSP2RMIX_INPUT_4_SOURCE          0x694
+#define WM2200_DSP2RMIX_INPUT_4_VOLUME          0x695
+#define WM2200_DSP2AUX1MIX_INPUT_1_SOURCE       0x696
+#define WM2200_DSP2AUX2MIX_INPUT_1_SOURCE       0x697
+#define WM2200_DSP2AUX3MIX_INPUT_1_SOURCE       0x698
+#define WM2200_DSP2AUX4MIX_INPUT_1_SOURCE       0x699
+#define WM2200_DSP2AUX5MIX_INPUT_1_SOURCE       0x69A
+#define WM2200_DSP2AUX6MIX_INPUT_1_SOURCE       0x69B
+#define WM2200_GPIO_CTRL_1                      0x700
+#define WM2200_GPIO_CTRL_2                      0x701
+#define WM2200_GPIO_CTRL_3                      0x702
+#define WM2200_GPIO_CTRL_4                      0x703
+#define WM2200_ADPS1_IRQ0                       0x707
+#define WM2200_ADPS1_IRQ1                       0x708
+#define WM2200_MISC_PAD_CTRL_1                  0x709
+#define WM2200_INTERRUPT_STATUS_1               0x800
+#define WM2200_INTERRUPT_STATUS_1_MASK          0x801
+#define WM2200_INTERRUPT_STATUS_2               0x802
+#define WM2200_INTERRUPT_RAW_STATUS_2           0x803
+#define WM2200_INTERRUPT_STATUS_2_MASK          0x804
+#define WM2200_INTERRUPT_CONTROL                0x808
+#define WM2200_EQL_1                            0x900
+#define WM2200_EQL_2                            0x901
+#define WM2200_EQL_3                            0x902
+#define WM2200_EQL_4                            0x903
+#define WM2200_EQL_5                            0x904
+#define WM2200_EQL_6                            0x905
+#define WM2200_EQL_7                            0x906
+#define WM2200_EQL_8                            0x907
+#define WM2200_EQL_9                            0x908
+#define WM2200_EQL_10                           0x909
+#define WM2200_EQL_11                           0x90A
+#define WM2200_EQL_12                           0x90B
+#define WM2200_EQL_13                           0x90C
+#define WM2200_EQL_14                           0x90D
+#define WM2200_EQL_15                           0x90E
+#define WM2200_EQL_16                           0x90F
+#define WM2200_EQL_17                           0x910
+#define WM2200_EQL_18                           0x911
+#define WM2200_EQL_19                           0x912
+#define WM2200_EQL_20                           0x913
+#define WM2200_EQR_1                            0x916
+#define WM2200_EQR_2                            0x917
+#define WM2200_EQR_3                            0x918
+#define WM2200_EQR_4                            0x919
+#define WM2200_EQR_5                            0x91A
+#define WM2200_EQR_6                            0x91B
+#define WM2200_EQR_7                            0x91C
+#define WM2200_EQR_8                            0x91D
+#define WM2200_EQR_9                            0x91E
+#define WM2200_EQR_10                           0x91F
+#define WM2200_EQR_11                           0x920
+#define WM2200_EQR_12                           0x921
+#define WM2200_EQR_13                           0x922
+#define WM2200_EQR_14                           0x923
+#define WM2200_EQR_15                           0x924
+#define WM2200_EQR_16                           0x925
+#define WM2200_EQR_17                           0x926
+#define WM2200_EQR_18                           0x927
+#define WM2200_EQR_19                           0x928
+#define WM2200_EQR_20                           0x929
+#define WM2200_HPLPF1_1                         0x93E
+#define WM2200_HPLPF1_2                         0x93F
+#define WM2200_HPLPF2_1                         0x942
+#define WM2200_HPLPF2_2                         0x943
+#define WM2200_DSP1_CONTROL_1                   0xA00
+#define WM2200_DSP1_CONTROL_2                   0xA02
+#define WM2200_DSP1_CONTROL_3                   0xA03
+#define WM2200_DSP1_CONTROL_4                   0xA04
+#define WM2200_DSP1_CONTROL_5                   0xA06
+#define WM2200_DSP1_CONTROL_6                   0xA07
+#define WM2200_DSP1_CONTROL_7                   0xA08
+#define WM2200_DSP1_CONTROL_8                   0xA09
+#define WM2200_DSP1_CONTROL_9                   0xA0A
+#define WM2200_DSP1_CONTROL_10                  0xA0B
+#define WM2200_DSP1_CONTROL_11                  0xA0C
+#define WM2200_DSP1_CONTROL_12                  0xA0D
+#define WM2200_DSP1_CONTROL_13                  0xA0F
+#define WM2200_DSP1_CONTROL_14                  0xA10
+#define WM2200_DSP1_CONTROL_15                  0xA11
+#define WM2200_DSP1_CONTROL_16                  0xA12
+#define WM2200_DSP1_CONTROL_17                  0xA13
+#define WM2200_DSP1_CONTROL_18                  0xA14
+#define WM2200_DSP1_CONTROL_19                  0xA16
+#define WM2200_DSP1_CONTROL_20                  0xA17
+#define WM2200_DSP1_CONTROL_21                  0xA18
+#define WM2200_DSP1_CONTROL_22                  0xA1A
+#define WM2200_DSP1_CONTROL_23                  0xA1B
+#define WM2200_DSP1_CONTROL_24                  0xA1C
+#define WM2200_DSP1_CONTROL_25                  0xA1E
+#define WM2200_DSP1_CONTROL_26                  0xA20
+#define WM2200_DSP1_CONTROL_27                  0xA21
+#define WM2200_DSP1_CONTROL_28                  0xA22
+#define WM2200_DSP1_CONTROL_29                  0xA23
+#define WM2200_DSP1_CONTROL_30                  0xA24
+#define WM2200_DSP1_CONTROL_31                  0xA26
+#define WM2200_DSP2_CONTROL_1                   0xB00
+#define WM2200_DSP2_CONTROL_2                   0xB02
+#define WM2200_DSP2_CONTROL_3                   0xB03
+#define WM2200_DSP2_CONTROL_4                   0xB04
+#define WM2200_DSP2_CONTROL_5                   0xB06
+#define WM2200_DSP2_CONTROL_6                   0xB07
+#define WM2200_DSP2_CONTROL_7                   0xB08
+#define WM2200_DSP2_CONTROL_8                   0xB09
+#define WM2200_DSP2_CONTROL_9                   0xB0A
+#define WM2200_DSP2_CONTROL_10                  0xB0B
+#define WM2200_DSP2_CONTROL_11                  0xB0C
+#define WM2200_DSP2_CONTROL_12                  0xB0D
+#define WM2200_DSP2_CONTROL_13                  0xB0F
+#define WM2200_DSP2_CONTROL_14                  0xB10
+#define WM2200_DSP2_CONTROL_15                  0xB11
+#define WM2200_DSP2_CONTROL_16                  0xB12
+#define WM2200_DSP2_CONTROL_17                  0xB13
+#define WM2200_DSP2_CONTROL_18                  0xB14
+#define WM2200_DSP2_CONTROL_19                  0xB16
+#define WM2200_DSP2_CONTROL_20                  0xB17
+#define WM2200_DSP2_CONTROL_21                  0xB18
+#define WM2200_DSP2_CONTROL_22                  0xB1A
+#define WM2200_DSP2_CONTROL_23                  0xB1B
+#define WM2200_DSP2_CONTROL_24                  0xB1C
+#define WM2200_DSP2_CONTROL_25                  0xB1E
+#define WM2200_DSP2_CONTROL_26                  0xB20
+#define WM2200_DSP2_CONTROL_27                  0xB21
+#define WM2200_DSP2_CONTROL_28                  0xB22
+#define WM2200_DSP2_CONTROL_29                  0xB23
+#define WM2200_DSP2_CONTROL_30                  0xB24
+#define WM2200_DSP2_CONTROL_31                  0xB26
+#define WM2200_ANC_CTRL1                        0xD00
+#define WM2200_ANC_CTRL2                        0xD01
+#define WM2200_ANC_CTRL3                        0xD02
+#define WM2200_ANC_CTRL7                        0xD08
+#define WM2200_ANC_CTRL8                        0xD09
+#define WM2200_ANC_CTRL9                        0xD0A
+#define WM2200_ANC_CTRL10                       0xD0B
+#define WM2200_ANC_CTRL11                       0xD0C
+#define WM2200_ANC_CTRL12                       0xD0D
+#define WM2200_ANC_CTRL13                       0xD0E
+#define WM2200_ANC_CTRL14                       0xD0F
+#define WM2200_ANC_CTRL15                       0xD10
+#define WM2200_ANC_CTRL16                       0xD11
+#define WM2200_ANC_CTRL17                       0xD12
+#define WM2200_ANC_CTRL18                       0xD15
+#define WM2200_ANC_CTRL19                       0xD16
+#define WM2200_ANC_CTRL20                       0xD17
+#define WM2200_ANC_CTRL21                       0xD18
+#define WM2200_ANC_CTRL22                       0xD19
+#define WM2200_ANC_CTRL23                       0xD1A
+#define WM2200_ANC_CTRL24                       0xD1B
+#define WM2200_ANC_CTRL25                       0xD1C
+#define WM2200_ANC_CTRL26                       0xD1D
+#define WM2200_ANC_CTRL27                       0xD1E
+#define WM2200_ANC_CTRL28                       0xD1F
+#define WM2200_ANC_CTRL29                       0xD20
+#define WM2200_ANC_CTRL30                       0xD21
+#define WM2200_ANC_CTRL31                       0xD23
+#define WM2200_ANC_CTRL32                       0xD24
+#define WM2200_ANC_CTRL33                       0xD25
+#define WM2200_ANC_CTRL34                       0xD27
+#define WM2200_ANC_CTRL35                       0xD28
+#define WM2200_ANC_CTRL36                       0xD29
+#define WM2200_ANC_CTRL37                       0xD2A
+#define WM2200_ANC_CTRL38                       0xD2B
+#define WM2200_ANC_CTRL39                       0xD2C
+#define WM2200_ANC_CTRL40                       0xD2D
+#define WM2200_ANC_CTRL41                       0xD2E
+#define WM2200_ANC_CTRL42                       0xD2F
+#define WM2200_ANC_CTRL43                       0xD30
+#define WM2200_ANC_CTRL44                       0xD31
+#define WM2200_ANC_CTRL45                       0xD32
+#define WM2200_ANC_CTRL46                       0xD33
+#define WM2200_ANC_CTRL47                       0xD34
+#define WM2200_ANC_CTRL48                       0xD35
+#define WM2200_ANC_CTRL49                       0xD36
+#define WM2200_ANC_CTRL50                       0xD37
+#define WM2200_ANC_CTRL51                       0xD38
+#define WM2200_ANC_CTRL52                       0xD39
+#define WM2200_ANC_CTRL53                       0xD3A
+#define WM2200_ANC_CTRL54                       0xD3B
+#define WM2200_ANC_CTRL55                       0xD3C
+#define WM2200_ANC_CTRL56                       0xD3D
+#define WM2200_ANC_CTRL57                       0xD3E
+#define WM2200_ANC_CTRL58                       0xD3F
+#define WM2200_ANC_CTRL59                       0xD40
+#define WM2200_ANC_CTRL60                       0xD41
+#define WM2200_ANC_CTRL61                       0xD42
+#define WM2200_ANC_CTRL62                       0xD43
+#define WM2200_ANC_CTRL63                       0xD44
+#define WM2200_ANC_CTRL64                       0xD45
+#define WM2200_ANC_CTRL65                       0xD46
+#define WM2200_ANC_CTRL66                       0xD47
+#define WM2200_ANC_CTRL67                       0xD48
+#define WM2200_ANC_CTRL68                       0xD49
+#define WM2200_ANC_CTRL69                       0xD4A
+#define WM2200_ANC_CTRL70                       0xD4B
+#define WM2200_ANC_CTRL71                       0xD4C
+#define WM2200_ANC_CTRL72                       0xD4D
+#define WM2200_ANC_CTRL73                       0xD4E
+#define WM2200_ANC_CTRL74                       0xD4F
+#define WM2200_ANC_CTRL75                       0xD50
+#define WM2200_ANC_CTRL76                       0xD51
+#define WM2200_ANC_CTRL77                       0xD52
+#define WM2200_ANC_CTRL78                       0xD53
+#define WM2200_ANC_CTRL79                       0xD54
+#define WM2200_ANC_CTRL80                       0xD55
+#define WM2200_ANC_CTRL81                       0xD56
+#define WM2200_ANC_CTRL82                       0xD57
+#define WM2200_ANC_CTRL83                       0xD58
+#define WM2200_ANC_CTRL84                       0xD5B
+#define WM2200_ANC_CTRL85                       0xD5C
+#define WM2200_ANC_CTRL86                       0xD5F
+#define WM2200_ANC_CTRL87                       0xD60
+#define WM2200_ANC_CTRL88                       0xD61
+#define WM2200_ANC_CTRL89                       0xD62
+#define WM2200_ANC_CTRL90                       0xD63
+#define WM2200_ANC_CTRL91                       0xD64
+#define WM2200_ANC_CTRL92                       0xD65
+#define WM2200_ANC_CTRL93                       0xD66
+#define WM2200_ANC_CTRL94                       0xD67
+#define WM2200_ANC_CTRL95                       0xD68
+#define WM2200_ANC_CTRL96                       0xD69
+#define WM2200_DSP1_DM_0                        0x3000
+#define WM2200_DSP1_DM_1                        0x3001
+#define WM2200_DSP1_DM_2                        0x3002
+#define WM2200_DSP1_DM_3                        0x3003
+#define WM2200_DSP1_DM_2044                     0x37FC
+#define WM2200_DSP1_DM_2045                     0x37FD
+#define WM2200_DSP1_DM_2046                     0x37FE
+#define WM2200_DSP1_DM_2047                     0x37FF
+#define WM2200_DSP1_PM_0                        0x3800
+#define WM2200_DSP1_PM_1                        0x3801
+#define WM2200_DSP1_PM_2                        0x3802
+#define WM2200_DSP1_PM_3                        0x3803
+#define WM2200_DSP1_PM_4                        0x3804
+#define WM2200_DSP1_PM_5                        0x3805
+#define WM2200_DSP1_PM_762                      0x3AFA
+#define WM2200_DSP1_PM_763                      0x3AFB
+#define WM2200_DSP1_PM_764                      0x3AFC
+#define WM2200_DSP1_PM_765                      0x3AFD
+#define WM2200_DSP1_PM_766                      0x3AFE
+#define WM2200_DSP1_PM_767                      0x3AFF
+#define WM2200_DSP1_ZM_0                        0x3C00
+#define WM2200_DSP1_ZM_1                        0x3C01
+#define WM2200_DSP1_ZM_2                        0x3C02
+#define WM2200_DSP1_ZM_3                        0x3C03
+#define WM2200_DSP1_ZM_1020                     0x3FFC
+#define WM2200_DSP1_ZM_1021                     0x3FFD
+#define WM2200_DSP1_ZM_1022                     0x3FFE
+#define WM2200_DSP1_ZM_1023                     0x3FFF
+#define WM2200_DSP2_DM_0                        0x4000
+#define WM2200_DSP2_DM_1                        0x4001
+#define WM2200_DSP2_DM_2                        0x4002
+#define WM2200_DSP2_DM_3                        0x4003
+#define WM2200_DSP2_DM_2044                     0x47FC
+#define WM2200_DSP2_DM_2045                     0x47FD
+#define WM2200_DSP2_DM_2046                     0x47FE
+#define WM2200_DSP2_DM_2047                     0x47FF
+#define WM2200_DSP2_PM_0                        0x4800
+#define WM2200_DSP2_PM_1                        0x4801
+#define WM2200_DSP2_PM_2                        0x4802
+#define WM2200_DSP2_PM_3                        0x4803
+#define WM2200_DSP2_PM_4                        0x4804
+#define WM2200_DSP2_PM_5                        0x4805
+#define WM2200_DSP2_PM_762                      0x4AFA
+#define WM2200_DSP2_PM_763                      0x4AFB
+#define WM2200_DSP2_PM_764                      0x4AFC
+#define WM2200_DSP2_PM_765                      0x4AFD
+#define WM2200_DSP2_PM_766                      0x4AFE
+#define WM2200_DSP2_PM_767                      0x4AFF
+#define WM2200_DSP2_ZM_0                        0x4C00
+#define WM2200_DSP2_ZM_1                        0x4C01
+#define WM2200_DSP2_ZM_2                        0x4C02
+#define WM2200_DSP2_ZM_3                        0x4C03
+#define WM2200_DSP2_ZM_1020                     0x4FFC
+#define WM2200_DSP2_ZM_1021                     0x4FFD
+#define WM2200_DSP2_ZM_1022                     0x4FFE
+#define WM2200_DSP2_ZM_1023                     0x4FFF
+
+#define WM2200_REGISTER_COUNT                   494
+#define WM2200_MAX_REGISTER                     0x4FFF
+
+/*
+ * Field Definitions.
+ */
+
+/*
+ * R0 (0x00) - software reset
+ */
+#define WM2200_SW_RESET_CHIP_ID1_MASK           0xFFFF  /* SW_RESET_CHIP_ID1 - [15:0] */
+#define WM2200_SW_RESET_CHIP_ID1_SHIFT               0  /* SW_RESET_CHIP_ID1 - [15:0] */
+#define WM2200_SW_RESET_CHIP_ID1_WIDTH              16  /* SW_RESET_CHIP_ID1 - [15:0] */
+
+/*
+ * R1 (0x01) - Device Revision
+ */
+#define WM2200_DEVICE_REVISION_MASK             0x000F  /* DEVICE_REVISION - [3:0] */
+#define WM2200_DEVICE_REVISION_SHIFT                 0  /* DEVICE_REVISION - [3:0] */
+#define WM2200_DEVICE_REVISION_WIDTH                 4  /* DEVICE_REVISION - [3:0] */
+
+/*
+ * R11 (0x0B) - Tone Generator 1
+ */
+#define WM2200_TONE_ENA                         0x0001  /* TONE_ENA */
+#define WM2200_TONE_ENA_MASK                    0x0001  /* TONE_ENA */
+#define WM2200_TONE_ENA_SHIFT                        0  /* TONE_ENA */
+#define WM2200_TONE_ENA_WIDTH                        1  /* TONE_ENA */
+
+/*
+ * R258 (0x102) - Clocking 3
+ */
+#define WM2200_SYSCLK_FREQ_MASK                 0x0700  /* SYSCLK_FREQ - [10:8] */
+#define WM2200_SYSCLK_FREQ_SHIFT                     8  /* SYSCLK_FREQ - [10:8] */
+#define WM2200_SYSCLK_FREQ_WIDTH                     3  /* SYSCLK_FREQ - [10:8] */
+#define WM2200_SYSCLK_ENA                       0x0040  /* SYSCLK_ENA */
+#define WM2200_SYSCLK_ENA_MASK                  0x0040  /* SYSCLK_ENA */
+#define WM2200_SYSCLK_ENA_SHIFT                      6  /* SYSCLK_ENA */
+#define WM2200_SYSCLK_ENA_WIDTH                      1  /* SYSCLK_ENA */
+#define WM2200_SYSCLK_SRC_MASK                  0x000F  /* SYSCLK_SRC - [3:0] */
+#define WM2200_SYSCLK_SRC_SHIFT                      0  /* SYSCLK_SRC - [3:0] */
+#define WM2200_SYSCLK_SRC_WIDTH                      4  /* SYSCLK_SRC - [3:0] */
+
+/*
+ * R259 (0x103) - Clocking 4
+ */
+#define WM2200_SAMPLE_RATE_1_MASK               0x001F  /* SAMPLE_RATE_1 - [4:0] */
+#define WM2200_SAMPLE_RATE_1_SHIFT                   0  /* SAMPLE_RATE_1 - [4:0] */
+#define WM2200_SAMPLE_RATE_1_WIDTH                   5  /* SAMPLE_RATE_1 - [4:0] */
+
+/*
+ * R273 (0x111) - FLL Control 1
+ */
+#define WM2200_FLL_ENA                          0x0001  /* FLL_ENA */
+#define WM2200_FLL_ENA_MASK                     0x0001  /* FLL_ENA */
+#define WM2200_FLL_ENA_SHIFT                         0  /* FLL_ENA */
+#define WM2200_FLL_ENA_WIDTH                         1  /* FLL_ENA */
+
+/*
+ * R274 (0x112) - FLL Control 2
+ */
+#define WM2200_FLL_OUTDIV_MASK                  0x3F00  /* FLL_OUTDIV - [13:8] */
+#define WM2200_FLL_OUTDIV_SHIFT                      8  /* FLL_OUTDIV - [13:8] */
+#define WM2200_FLL_OUTDIV_WIDTH                      6  /* FLL_OUTDIV - [13:8] */
+#define WM2200_FLL_FRATIO_MASK                  0x0007  /* FLL_FRATIO - [2:0] */
+#define WM2200_FLL_FRATIO_SHIFT                      0  /* FLL_FRATIO - [2:0] */
+#define WM2200_FLL_FRATIO_WIDTH                      3  /* FLL_FRATIO - [2:0] */
+
+/*
+ * R275 (0x113) - FLL Control 3
+ */
+#define WM2200_FLL_FRACN_ENA                    0x0001  /* FLL_FRACN_ENA */
+#define WM2200_FLL_FRACN_ENA_MASK               0x0001  /* FLL_FRACN_ENA */
+#define WM2200_FLL_FRACN_ENA_SHIFT                   0  /* FLL_FRACN_ENA */
+#define WM2200_FLL_FRACN_ENA_WIDTH                   1  /* FLL_FRACN_ENA */
+
+/*
+ * R276 (0x114) - FLL Control 4
+ */
+#define WM2200_FLL_THETA_MASK                   0xFFFF  /* FLL_THETA - [15:0] */
+#define WM2200_FLL_THETA_SHIFT                       0  /* FLL_THETA - [15:0] */
+#define WM2200_FLL_THETA_WIDTH                      16  /* FLL_THETA - [15:0] */
+
+/*
+ * R278 (0x116) - FLL Control 6
+ */
+#define WM2200_FLL_N_MASK                       0x03FF  /* FLL_N - [9:0] */
+#define WM2200_FLL_N_SHIFT                           0  /* FLL_N - [9:0] */
+#define WM2200_FLL_N_WIDTH                          10  /* FLL_N - [9:0] */
+
+/*
+ * R279 (0x117) - FLL Control 7
+ */
+#define WM2200_FLL_CLK_REF_DIV_MASK             0x0030  /* FLL_CLK_REF_DIV - [5:4] */
+#define WM2200_FLL_CLK_REF_DIV_SHIFT                 4  /* FLL_CLK_REF_DIV - [5:4] */
+#define WM2200_FLL_CLK_REF_DIV_WIDTH                 2  /* FLL_CLK_REF_DIV - [5:4] */
+#define WM2200_FLL_CLK_REF_SRC_MASK             0x0003  /* FLL_CLK_REF_SRC - [1:0] */
+#define WM2200_FLL_CLK_REF_SRC_SHIFT                 0  /* FLL_CLK_REF_SRC - [1:0] */
+#define WM2200_FLL_CLK_REF_SRC_WIDTH                 2  /* FLL_CLK_REF_SRC - [1:0] */
+
+/*
+ * R281 (0x119) - FLL EFS 1
+ */
+#define WM2200_FLL_LAMBDA_MASK                  0xFFFF  /* FLL_LAMBDA - [15:0] */
+#define WM2200_FLL_LAMBDA_SHIFT                      0  /* FLL_LAMBDA - [15:0] */
+#define WM2200_FLL_LAMBDA_WIDTH                     16  /* FLL_LAMBDA - [15:0] */
+
+/*
+ * R282 (0x11A) - FLL EFS 2
+ */
+#define WM2200_FLL_EFS_ENA                      0x0001  /* FLL_EFS_ENA */
+#define WM2200_FLL_EFS_ENA_MASK                 0x0001  /* FLL_EFS_ENA */
+#define WM2200_FLL_EFS_ENA_SHIFT                     0  /* FLL_EFS_ENA */
+#define WM2200_FLL_EFS_ENA_WIDTH                     1  /* FLL_EFS_ENA */
+
+/*
+ * R512 (0x200) - Mic Charge Pump 1
+ */
+#define WM2200_CPMIC_BYPASS_MODE                0x0020  /* CPMIC_BYPASS_MODE */
+#define WM2200_CPMIC_BYPASS_MODE_MASK           0x0020  /* CPMIC_BYPASS_MODE */
+#define WM2200_CPMIC_BYPASS_MODE_SHIFT               5  /* CPMIC_BYPASS_MODE */
+#define WM2200_CPMIC_BYPASS_MODE_WIDTH               1  /* CPMIC_BYPASS_MODE */
+#define WM2200_CPMIC_ENA                        0x0001  /* CPMIC_ENA */
+#define WM2200_CPMIC_ENA_MASK                   0x0001  /* CPMIC_ENA */
+#define WM2200_CPMIC_ENA_SHIFT                       0  /* CPMIC_ENA */
+#define WM2200_CPMIC_ENA_WIDTH                       1  /* CPMIC_ENA */
+
+/*
+ * R513 (0x201) - Mic Charge Pump 2
+ */
+#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_MASK     0xF800  /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
+#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_SHIFT        11  /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
+#define WM2200_CPMIC_LDO_VSEL_OVERRIDE_WIDTH         5  /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */
+
+/*
+ * R514 (0x202) - DM Charge Pump 1
+ */
+#define WM2200_CPDM_ENA                         0x0001  /* CPDM_ENA */
+#define WM2200_CPDM_ENA_MASK                    0x0001  /* CPDM_ENA */
+#define WM2200_CPDM_ENA_SHIFT                        0  /* CPDM_ENA */
+#define WM2200_CPDM_ENA_WIDTH                        1  /* CPDM_ENA */
+
+/*
+ * R524 (0x20C) - Mic Bias Ctrl 1
+ */
+#define WM2200_MICB1_DISCH                      0x0040  /* MICB1_DISCH */
+#define WM2200_MICB1_DISCH_MASK                 0x0040  /* MICB1_DISCH */
+#define WM2200_MICB1_DISCH_SHIFT                     6  /* MICB1_DISCH */
+#define WM2200_MICB1_DISCH_WIDTH                     1  /* MICB1_DISCH */
+#define WM2200_MICB1_RATE                       0x0020  /* MICB1_RATE */
+#define WM2200_MICB1_RATE_MASK                  0x0020  /* MICB1_RATE */
+#define WM2200_MICB1_RATE_SHIFT                      5  /* MICB1_RATE */
+#define WM2200_MICB1_RATE_WIDTH                      1  /* MICB1_RATE */
+#define WM2200_MICB1_LVL_MASK                   0x001C  /* MICB1_LVL - [4:2] */
+#define WM2200_MICB1_LVL_SHIFT                       2  /* MICB1_LVL - [4:2] */
+#define WM2200_MICB1_LVL_WIDTH                       3  /* MICB1_LVL - [4:2] */
+#define WM2200_MICB1_MODE                       0x0002  /* MICB1_MODE */
+#define WM2200_MICB1_MODE_MASK                  0x0002  /* MICB1_MODE */
+#define WM2200_MICB1_MODE_SHIFT                      1  /* MICB1_MODE */
+#define WM2200_MICB1_MODE_WIDTH                      1  /* MICB1_MODE */
+#define WM2200_MICB1_ENA                        0x0001  /* MICB1_ENA */
+#define WM2200_MICB1_ENA_MASK                   0x0001  /* MICB1_ENA */
+#define WM2200_MICB1_ENA_SHIFT                       0  /* MICB1_ENA */
+#define WM2200_MICB1_ENA_WIDTH                       1  /* MICB1_ENA */
+
+/*
+ * R525 (0x20D) - Mic Bias Ctrl 2
+ */
+#define WM2200_MICB2_DISCH                      0x0040  /* MICB2_DISCH */
+#define WM2200_MICB2_DISCH_MASK                 0x0040  /* MICB2_DISCH */
+#define WM2200_MICB2_DISCH_SHIFT                     6  /* MICB2_DISCH */
+#define WM2200_MICB2_DISCH_WIDTH                     1  /* MICB2_DISCH */
+#define WM2200_MICB2_RATE                       0x0020  /* MICB2_RATE */
+#define WM2200_MICB2_RATE_MASK                  0x0020  /* MICB2_RATE */
+#define WM2200_MICB2_RATE_SHIFT                      5  /* MICB2_RATE */
+#define WM2200_MICB2_RATE_WIDTH                      1  /* MICB2_RATE */
+#define WM2200_MICB2_LVL_MASK                   0x001C  /* MICB2_LVL - [4:2] */
+#define WM2200_MICB2_LVL_SHIFT                       2  /* MICB2_LVL - [4:2] */
+#define WM2200_MICB2_LVL_WIDTH                       3  /* MICB2_LVL - [4:2] */
+#define WM2200_MICB2_MODE                       0x0002  /* MICB2_MODE */
+#define WM2200_MICB2_MODE_MASK                  0x0002  /* MICB2_MODE */
+#define WM2200_MICB2_MODE_SHIFT                      1  /* MICB2_MODE */
+#define WM2200_MICB2_MODE_WIDTH                      1  /* MICB2_MODE */
+#define WM2200_MICB2_ENA                        0x0001  /* MICB2_ENA */
+#define WM2200_MICB2_ENA_MASK                   0x0001  /* MICB2_ENA */
+#define WM2200_MICB2_ENA_SHIFT                       0  /* MICB2_ENA */
+#define WM2200_MICB2_ENA_WIDTH                       1  /* MICB2_ENA */
+
+/*
+ * R527 (0x20F) - Ear Piece Ctrl 1
+ */
+#define WM2200_EPD_LP_ENA                       0x4000  /* EPD_LP_ENA */
+#define WM2200_EPD_LP_ENA_MASK                  0x4000  /* EPD_LP_ENA */
+#define WM2200_EPD_LP_ENA_SHIFT                     14  /* EPD_LP_ENA */
+#define WM2200_EPD_LP_ENA_WIDTH                      1  /* EPD_LP_ENA */
+#define WM2200_EPD_OUTP_LP_ENA                  0x2000  /* EPD_OUTP_LP_ENA */
+#define WM2200_EPD_OUTP_LP_ENA_MASK             0x2000  /* EPD_OUTP_LP_ENA */
+#define WM2200_EPD_OUTP_LP_ENA_SHIFT                13  /* EPD_OUTP_LP_ENA */
+#define WM2200_EPD_OUTP_LP_ENA_WIDTH                 1  /* EPD_OUTP_LP_ENA */
+#define WM2200_EPD_RMV_SHRT_LP                  0x1000  /* EPD_RMV_SHRT_LP */
+#define WM2200_EPD_RMV_SHRT_LP_MASK             0x1000  /* EPD_RMV_SHRT_LP */
+#define WM2200_EPD_RMV_SHRT_LP_SHIFT                12  /* EPD_RMV_SHRT_LP */
+#define WM2200_EPD_RMV_SHRT_LP_WIDTH                 1  /* EPD_RMV_SHRT_LP */
+#define WM2200_EPD_LN_ENA                       0x0800  /* EPD_LN_ENA */
+#define WM2200_EPD_LN_ENA_MASK                  0x0800  /* EPD_LN_ENA */
+#define WM2200_EPD_LN_ENA_SHIFT                     11  /* EPD_LN_ENA */
+#define WM2200_EPD_LN_ENA_WIDTH                      1  /* EPD_LN_ENA */
+#define WM2200_EPD_OUTP_LN_ENA                  0x0400  /* EPD_OUTP_LN_ENA */
+#define WM2200_EPD_OUTP_LN_ENA_MASK             0x0400  /* EPD_OUTP_LN_ENA */
+#define WM2200_EPD_OUTP_LN_ENA_SHIFT                10  /* EPD_OUTP_LN_ENA */
+#define WM2200_EPD_OUTP_LN_ENA_WIDTH                 1  /* EPD_OUTP_LN_ENA */
+#define WM2200_EPD_RMV_SHRT_LN                  0x0200  /* EPD_RMV_SHRT_LN */
+#define WM2200_EPD_RMV_SHRT_LN_MASK             0x0200  /* EPD_RMV_SHRT_LN */
+#define WM2200_EPD_RMV_SHRT_LN_SHIFT                 9  /* EPD_RMV_SHRT_LN */
+#define WM2200_EPD_RMV_SHRT_LN_WIDTH                 1  /* EPD_RMV_SHRT_LN */
+
+/*
+ * R528 (0x210) - Ear Piece Ctrl 2
+ */
+#define WM2200_EPD_RP_ENA                       0x4000  /* EPD_RP_ENA */
+#define WM2200_EPD_RP_ENA_MASK                  0x4000  /* EPD_RP_ENA */
+#define WM2200_EPD_RP_ENA_SHIFT                     14  /* EPD_RP_ENA */
+#define WM2200_EPD_RP_ENA_WIDTH                      1  /* EPD_RP_ENA */
+#define WM2200_EPD_OUTP_RP_ENA                  0x2000  /* EPD_OUTP_RP_ENA */
+#define WM2200_EPD_OUTP_RP_ENA_MASK             0x2000  /* EPD_OUTP_RP_ENA */
+#define WM2200_EPD_OUTP_RP_ENA_SHIFT                13  /* EPD_OUTP_RP_ENA */
+#define WM2200_EPD_OUTP_RP_ENA_WIDTH                 1  /* EPD_OUTP_RP_ENA */
+#define WM2200_EPD_RMV_SHRT_RP                  0x1000  /* EPD_RMV_SHRT_RP */
+#define WM2200_EPD_RMV_SHRT_RP_MASK             0x1000  /* EPD_RMV_SHRT_RP */
+#define WM2200_EPD_RMV_SHRT_RP_SHIFT                12  /* EPD_RMV_SHRT_RP */
+#define WM2200_EPD_RMV_SHRT_RP_WIDTH                 1  /* EPD_RMV_SHRT_RP */
+#define WM2200_EPD_RN_ENA                       0x0800  /* EPD_RN_ENA */
+#define WM2200_EPD_RN_ENA_MASK                  0x0800  /* EPD_RN_ENA */
+#define WM2200_EPD_RN_ENA_SHIFT                     11  /* EPD_RN_ENA */
+#define WM2200_EPD_RN_ENA_WIDTH                      1  /* EPD_RN_ENA */
+#define WM2200_EPD_OUTP_RN_ENA                  0x0400  /* EPD_OUTP_RN_ENA */
+#define WM2200_EPD_OUTP_RN_ENA_MASK             0x0400  /* EPD_OUTP_RN_ENA */
+#define WM2200_EPD_OUTP_RN_ENA_SHIFT                10  /* EPD_OUTP_RN_ENA */
+#define WM2200_EPD_OUTP_RN_ENA_WIDTH                 1  /* EPD_OUTP_RN_ENA */
+#define WM2200_EPD_RMV_SHRT_RN                  0x0200  /* EPD_RMV_SHRT_RN */
+#define WM2200_EPD_RMV_SHRT_RN_MASK             0x0200  /* EPD_RMV_SHRT_RN */
+#define WM2200_EPD_RMV_SHRT_RN_SHIFT                 9  /* EPD_RMV_SHRT_RN */
+#define WM2200_EPD_RMV_SHRT_RN_WIDTH                 1  /* EPD_RMV_SHRT_RN */
+
+/*
+ * R769 (0x301) - Input Enables
+ */
+#define WM2200_IN3L_ENA                         0x0020  /* IN3L_ENA */
+#define WM2200_IN3L_ENA_MASK                    0x0020  /* IN3L_ENA */
+#define WM2200_IN3L_ENA_SHIFT                        5  /* IN3L_ENA */
+#define WM2200_IN3L_ENA_WIDTH                        1  /* IN3L_ENA */
+#define WM2200_IN3R_ENA                         0x0010  /* IN3R_ENA */
+#define WM2200_IN3R_ENA_MASK                    0x0010  /* IN3R_ENA */
+#define WM2200_IN3R_ENA_SHIFT                        4  /* IN3R_ENA */
+#define WM2200_IN3R_ENA_WIDTH                        1  /* IN3R_ENA */
+#define WM2200_IN2L_ENA                         0x0008  /* IN2L_ENA */
+#define WM2200_IN2L_ENA_MASK                    0x0008  /* IN2L_ENA */
+#define WM2200_IN2L_ENA_SHIFT                        3  /* IN2L_ENA */
+#define WM2200_IN2L_ENA_WIDTH                        1  /* IN2L_ENA */
+#define WM2200_IN2R_ENA                         0x0004  /* IN2R_ENA */
+#define WM2200_IN2R_ENA_MASK                    0x0004  /* IN2R_ENA */
+#define WM2200_IN2R_ENA_SHIFT                        2  /* IN2R_ENA */
+#define WM2200_IN2R_ENA_WIDTH                        1  /* IN2R_ENA */
+#define WM2200_IN1L_ENA                         0x0002  /* IN1L_ENA */
+#define WM2200_IN1L_ENA_MASK                    0x0002  /* IN1L_ENA */
+#define WM2200_IN1L_ENA_SHIFT                        1  /* IN1L_ENA */
+#define WM2200_IN1L_ENA_WIDTH                        1  /* IN1L_ENA */
+#define WM2200_IN1R_ENA                         0x0001  /* IN1R_ENA */
+#define WM2200_IN1R_ENA_MASK                    0x0001  /* IN1R_ENA */
+#define WM2200_IN1R_ENA_SHIFT                        0  /* IN1R_ENA */
+#define WM2200_IN1R_ENA_WIDTH                        1  /* IN1R_ENA */
+
+/*
+ * R770 (0x302) - IN1L Control
+ */
+#define WM2200_IN1_OSR                          0x2000  /* IN1_OSR */
+#define WM2200_IN1_OSR_MASK                     0x2000  /* IN1_OSR */
+#define WM2200_IN1_OSR_SHIFT                        13  /* IN1_OSR */
+#define WM2200_IN1_OSR_WIDTH                         1  /* IN1_OSR */
+#define WM2200_IN1_DMIC_SUP_MASK                0x1800  /* IN1_DMIC_SUP - [12:11] */
+#define WM2200_IN1_DMIC_SUP_SHIFT                   11  /* IN1_DMIC_SUP - [12:11] */
+#define WM2200_IN1_DMIC_SUP_WIDTH                    2  /* IN1_DMIC_SUP - [12:11] */
+#define WM2200_IN1_MODE_MASK                    0x0600  /* IN1_MODE - [10:9] */
+#define WM2200_IN1_MODE_SHIFT                        9  /* IN1_MODE - [10:9] */
+#define WM2200_IN1_MODE_WIDTH                        2  /* IN1_MODE - [10:9] */
+#define WM2200_IN1L_PGA_VOL_MASK                0x00FE  /* IN1L_PGA_VOL - [7:1] */
+#define WM2200_IN1L_PGA_VOL_SHIFT                    1  /* IN1L_PGA_VOL - [7:1] */
+#define WM2200_IN1L_PGA_VOL_WIDTH                    7  /* IN1L_PGA_VOL - [7:1] */
+
+/*
+ * R771 (0x303) - IN1R Control
+ */
+#define WM2200_IN1R_PGA_VOL_MASK                0x00FE  /* IN1R_PGA_VOL - [7:1] */
+#define WM2200_IN1R_PGA_VOL_SHIFT                    1  /* IN1R_PGA_VOL - [7:1] */
+#define WM2200_IN1R_PGA_VOL_WIDTH                    7  /* IN1R_PGA_VOL - [7:1] */
+
+/*
+ * R772 (0x304) - IN2L Control
+ */
+#define WM2200_IN2_OSR                          0x2000  /* IN2_OSR */
+#define WM2200_IN2_OSR_MASK                     0x2000  /* IN2_OSR */
+#define WM2200_IN2_OSR_SHIFT                        13  /* IN2_OSR */
+#define WM2200_IN2_OSR_WIDTH                         1  /* IN2_OSR */
+#define WM2200_IN2_DMIC_SUP_MASK                0x1800  /* IN2_DMIC_SUP - [12:11] */
+#define WM2200_IN2_DMIC_SUP_SHIFT                   11  /* IN2_DMIC_SUP - [12:11] */
+#define WM2200_IN2_DMIC_SUP_WIDTH                    2  /* IN2_DMIC_SUP - [12:11] */
+#define WM2200_IN2_MODE_MASK                    0x0600  /* IN2_MODE - [10:9] */
+#define WM2200_IN2_MODE_SHIFT                        9  /* IN2_MODE - [10:9] */
+#define WM2200_IN2_MODE_WIDTH                        2  /* IN2_MODE - [10:9] */
+#define WM2200_IN2L_PGA_VOL_MASK                0x00FE  /* IN2L_PGA_VOL - [7:1] */
+#define WM2200_IN2L_PGA_VOL_SHIFT                    1  /* IN2L_PGA_VOL - [7:1] */
+#define WM2200_IN2L_PGA_VOL_WIDTH                    7  /* IN2L_PGA_VOL - [7:1] */
+
+/*
+ * R773 (0x305) - IN2R Control
+ */
+#define WM2200_IN2R_PGA_VOL_MASK                0x00FE  /* IN2R_PGA_VOL - [7:1] */
+#define WM2200_IN2R_PGA_VOL_SHIFT                    1  /* IN2R_PGA_VOL - [7:1] */
+#define WM2200_IN2R_PGA_VOL_WIDTH                    7  /* IN2R_PGA_VOL - [7:1] */
+
+/*
+ * R774 (0x306) - IN3L Control
+ */
+#define WM2200_IN3_OSR                          0x2000  /* IN3_OSR */
+#define WM2200_IN3_OSR_MASK                     0x2000  /* IN3_OSR */
+#define WM2200_IN3_OSR_SHIFT                        13  /* IN3_OSR */
+#define WM2200_IN3_OSR_WIDTH                         1  /* IN3_OSR */
+#define WM2200_IN3_DMIC_SUP_MASK                0x1800  /* IN3_DMIC_SUP - [12:11] */
+#define WM2200_IN3_DMIC_SUP_SHIFT                   11  /* IN3_DMIC_SUP - [12:11] */
+#define WM2200_IN3_DMIC_SUP_WIDTH                    2  /* IN3_DMIC_SUP - [12:11] */
+#define WM2200_IN3_MODE_MASK                    0x0600  /* IN3_MODE - [10:9] */
+#define WM2200_IN3_MODE_SHIFT                        9  /* IN3_MODE - [10:9] */
+#define WM2200_IN3_MODE_WIDTH                        2  /* IN3_MODE - [10:9] */
+#define WM2200_IN3L_PGA_VOL_MASK                0x00FE  /* IN3L_PGA_VOL - [7:1] */
+#define WM2200_IN3L_PGA_VOL_SHIFT                    1  /* IN3L_PGA_VOL - [7:1] */
+#define WM2200_IN3L_PGA_VOL_WIDTH                    7  /* IN3L_PGA_VOL - [7:1] */
+
+/*
+ * R775 (0x307) - IN3R Control
+ */
+#define WM2200_IN3R_PGA_VOL_MASK                0x00FE  /* IN3R_PGA_VOL - [7:1] */
+#define WM2200_IN3R_PGA_VOL_SHIFT                    1  /* IN3R_PGA_VOL - [7:1] */
+#define WM2200_IN3R_PGA_VOL_WIDTH                    7  /* IN3R_PGA_VOL - [7:1] */
+
+/*
+ * R778 (0x30A) - RXANC_SRC
+ */
+#define WM2200_IN_RXANC_SEL_MASK                0x0007  /* IN_RXANC_SEL - [2:0] */
+#define WM2200_IN_RXANC_SEL_SHIFT                    0  /* IN_RXANC_SEL - [2:0] */
+#define WM2200_IN_RXANC_SEL_WIDTH                    3  /* IN_RXANC_SEL - [2:0] */
+
+/*
+ * R779 (0x30B) - Input Volume Ramp
+ */
+#define WM2200_IN_VD_RAMP_MASK                  0x0070  /* IN_VD_RAMP - [6:4] */
+#define WM2200_IN_VD_RAMP_SHIFT                      4  /* IN_VD_RAMP - [6:4] */
+#define WM2200_IN_VD_RAMP_WIDTH                      3  /* IN_VD_RAMP - [6:4] */
+#define WM2200_IN_VI_RAMP_MASK                  0x0007  /* IN_VI_RAMP - [2:0] */
+#define WM2200_IN_VI_RAMP_SHIFT                      0  /* IN_VI_RAMP - [2:0] */
+#define WM2200_IN_VI_RAMP_WIDTH                      3  /* IN_VI_RAMP - [2:0] */
+
+/*
+ * R780 (0x30C) - ADC Digital Volume 1L
+ */
+#define WM2200_IN_VU                            0x0200  /* IN_VU */
+#define WM2200_IN_VU_MASK                       0x0200  /* IN_VU */
+#define WM2200_IN_VU_SHIFT                           9  /* IN_VU */
+#define WM2200_IN_VU_WIDTH                           1  /* IN_VU */
+#define WM2200_IN1L_MUTE                        0x0100  /* IN1L_MUTE */
+#define WM2200_IN1L_MUTE_MASK                   0x0100  /* IN1L_MUTE */
+#define WM2200_IN1L_MUTE_SHIFT                       8  /* IN1L_MUTE */
+#define WM2200_IN1L_MUTE_WIDTH                       1  /* IN1L_MUTE */
+#define WM2200_IN1L_DIG_VOL_MASK                0x00FF  /* IN1L_DIG_VOL - [7:0] */
+#define WM2200_IN1L_DIG_VOL_SHIFT                    0  /* IN1L_DIG_VOL - [7:0] */
+#define WM2200_IN1L_DIG_VOL_WIDTH                    8  /* IN1L_DIG_VOL - [7:0] */
+
+/*
+ * R781 (0x30D) - ADC Digital Volume 1R
+ */
+#define WM2200_IN_VU                            0x0200  /* IN_VU */
+#define WM2200_IN_VU_MASK                       0x0200  /* IN_VU */
+#define WM2200_IN_VU_SHIFT                           9  /* IN_VU */
+#define WM2200_IN_VU_WIDTH                           1  /* IN_VU */
+#define WM2200_IN1R_MUTE                        0x0100  /* IN1R_MUTE */
+#define WM2200_IN1R_MUTE_MASK                   0x0100  /* IN1R_MUTE */
+#define WM2200_IN1R_MUTE_SHIFT                       8  /* IN1R_MUTE */
+#define WM2200_IN1R_MUTE_WIDTH                       1  /* IN1R_MUTE */
+#define WM2200_IN1R_DIG_VOL_MASK                0x00FF  /* IN1R_DIG_VOL - [7:0] */
+#define WM2200_IN1R_DIG_VOL_SHIFT                    0  /* IN1R_DIG_VOL - [7:0] */
+#define WM2200_IN1R_DIG_VOL_WIDTH                    8  /* IN1R_DIG_VOL - [7:0] */
+
+/*
+ * R782 (0x30E) - ADC Digital Volume 2L
+ */
+#define WM2200_IN_VU                            0x0200  /* IN_VU */
+#define WM2200_IN_VU_MASK                       0x0200  /* IN_VU */
+#define WM2200_IN_VU_SHIFT                           9  /* IN_VU */
+#define WM2200_IN_VU_WIDTH                           1  /* IN_VU */
+#define WM2200_IN2L_MUTE                        0x0100  /* IN2L_MUTE */
+#define WM2200_IN2L_MUTE_MASK                   0x0100  /* IN2L_MUTE */
+#define WM2200_IN2L_MUTE_SHIFT                       8  /* IN2L_MUTE */
+#define WM2200_IN2L_MUTE_WIDTH                       1  /* IN2L_MUTE */
+#define WM2200_IN2L_DIG_VOL_MASK                0x00FF  /* IN2L_DIG_VOL - [7:0] */
+#define WM2200_IN2L_DIG_VOL_SHIFT                    0  /* IN2L_DIG_VOL - [7:0] */
+#define WM2200_IN2L_DIG_VOL_WIDTH                    8  /* IN2L_DIG_VOL - [7:0] */
+
+/*
+ * R783 (0x30F) - ADC Digital Volume 2R
+ */
+#define WM2200_IN_VU                            0x0200  /* IN_VU */
+#define WM2200_IN_VU_MASK                       0x0200  /* IN_VU */
+#define WM2200_IN_VU_SHIFT                           9  /* IN_VU */
+#define WM2200_IN_VU_WIDTH                           1  /* IN_VU */
+#define WM2200_IN2R_MUTE                        0x0100  /* IN2R_MUTE */
+#define WM2200_IN2R_MUTE_MASK                   0x0100  /* IN2R_MUTE */
+#define WM2200_IN2R_MUTE_SHIFT                       8  /* IN2R_MUTE */
+#define WM2200_IN2R_MUTE_WIDTH                       1  /* IN2R_MUTE */
+#define WM2200_IN2R_DIG_VOL_MASK                0x00FF  /* IN2R_DIG_VOL - [7:0] */
+#define WM2200_IN2R_DIG_VOL_SHIFT                    0  /* IN2R_DIG_VOL - [7:0] */
+#define WM2200_IN2R_DIG_VOL_WIDTH                    8  /* IN2R_DIG_VOL - [7:0] */
+
+/*
+ * R784 (0x310) - ADC Digital Volume 3L
+ */
+#define WM2200_IN_VU                            0x0200  /* IN_VU */
+#define WM2200_IN_VU_MASK                       0x0200  /* IN_VU */
+#define WM2200_IN_VU_SHIFT                           9  /* IN_VU */
+#define WM2200_IN_VU_WIDTH                           1  /* IN_VU */
+#define WM2200_IN3L_MUTE                        0x0100  /* IN3L_MUTE */
+#define WM2200_IN3L_MUTE_MASK                   0x0100  /* IN3L_MUTE */
+#define WM2200_IN3L_MUTE_SHIFT                       8  /* IN3L_MUTE */
+#define WM2200_IN3L_MUTE_WIDTH                       1  /* IN3L_MUTE */
+#define WM2200_IN3L_DIG_VOL_MASK                0x00FF  /* IN3L_DIG_VOL - [7:0] */
+#define WM2200_IN3L_DIG_VOL_SHIFT                    0  /* IN3L_DIG_VOL - [7:0] */
+#define WM2200_IN3L_DIG_VOL_WIDTH                    8  /* IN3L_DIG_VOL - [7:0] */
+
+/*
+ * R785 (0x311) - ADC Digital Volume 3R
+ */
+#define WM2200_IN_VU                            0x0200  /* IN_VU */
+#define WM2200_IN_VU_MASK                       0x0200  /* IN_VU */
+#define WM2200_IN_VU_SHIFT                           9  /* IN_VU */
+#define WM2200_IN_VU_WIDTH                           1  /* IN_VU */
+#define WM2200_IN3R_MUTE                        0x0100  /* IN3R_MUTE */
+#define WM2200_IN3R_MUTE_MASK                   0x0100  /* IN3R_MUTE */
+#define WM2200_IN3R_MUTE_SHIFT                       8  /* IN3R_MUTE */
+#define WM2200_IN3R_MUTE_WIDTH                       1  /* IN3R_MUTE */
+#define WM2200_IN3R_DIG_VOL_MASK                0x00FF  /* IN3R_DIG_VOL - [7:0] */
+#define WM2200_IN3R_DIG_VOL_SHIFT                    0  /* IN3R_DIG_VOL - [7:0] */
+#define WM2200_IN3R_DIG_VOL_WIDTH                    8  /* IN3R_DIG_VOL - [7:0] */
+
+/*
+ * R1024 (0x400) - Output Enables
+ */
+#define WM2200_OUT2L_ENA                        0x0008  /* OUT2L_ENA */
+#define WM2200_OUT2L_ENA_MASK                   0x0008  /* OUT2L_ENA */
+#define WM2200_OUT2L_ENA_SHIFT                       3  /* OUT2L_ENA */
+#define WM2200_OUT2L_ENA_WIDTH                       1  /* OUT2L_ENA */
+#define WM2200_OUT2R_ENA                        0x0004  /* OUT2R_ENA */
+#define WM2200_OUT2R_ENA_MASK                   0x0004  /* OUT2R_ENA */
+#define WM2200_OUT2R_ENA_SHIFT                       2  /* OUT2R_ENA */
+#define WM2200_OUT2R_ENA_WIDTH                       1  /* OUT2R_ENA */
+#define WM2200_OUT1L_ENA                        0x0002  /* OUT1L_ENA */
+#define WM2200_OUT1L_ENA_MASK                   0x0002  /* OUT1L_ENA */
+#define WM2200_OUT1L_ENA_SHIFT                       1  /* OUT1L_ENA */
+#define WM2200_OUT1L_ENA_WIDTH                       1  /* OUT1L_ENA */
+#define WM2200_OUT1R_ENA                        0x0001  /* OUT1R_ENA */
+#define WM2200_OUT1R_ENA_MASK                   0x0001  /* OUT1R_ENA */
+#define WM2200_OUT1R_ENA_SHIFT                       0  /* OUT1R_ENA */
+#define WM2200_OUT1R_ENA_WIDTH                       1  /* OUT1R_ENA */
+
+/*
+ * R1025 (0x401) - DAC Volume Limit 1L
+ */
+#define WM2200_OUT1_OSR                         0x2000  /* OUT1_OSR */
+#define WM2200_OUT1_OSR_MASK                    0x2000  /* OUT1_OSR */
+#define WM2200_OUT1_OSR_SHIFT                       13  /* OUT1_OSR */
+#define WM2200_OUT1_OSR_WIDTH                        1  /* OUT1_OSR */
+#define WM2200_OUT1L_ANC_SRC                    0x0800  /* OUT1L_ANC_SRC */
+#define WM2200_OUT1L_ANC_SRC_MASK               0x0800  /* OUT1L_ANC_SRC */
+#define WM2200_OUT1L_ANC_SRC_SHIFT                  11  /* OUT1L_ANC_SRC */
+#define WM2200_OUT1L_ANC_SRC_WIDTH                   1  /* OUT1L_ANC_SRC */
+#define WM2200_OUT1L_PGA_VOL_MASK               0x00FE  /* OUT1L_PGA_VOL - [7:1] */
+#define WM2200_OUT1L_PGA_VOL_SHIFT                   1  /* OUT1L_PGA_VOL - [7:1] */
+#define WM2200_OUT1L_PGA_VOL_WIDTH                   7  /* OUT1L_PGA_VOL - [7:1] */
+
+/*
+ * R1026 (0x402) - DAC Volume Limit 1R
+ */
+#define WM2200_OUT1R_ANC_SRC                    0x0800  /* OUT1R_ANC_SRC */
+#define WM2200_OUT1R_ANC_SRC_MASK               0x0800  /* OUT1R_ANC_SRC */
+#define WM2200_OUT1R_ANC_SRC_SHIFT                  11  /* OUT1R_ANC_SRC */
+#define WM2200_OUT1R_ANC_SRC_WIDTH                   1  /* OUT1R_ANC_SRC */
+#define WM2200_OUT1R_PGA_VOL_MASK               0x00FE  /* OUT1R_PGA_VOL - [7:1] */
+#define WM2200_OUT1R_PGA_VOL_SHIFT                   1  /* OUT1R_PGA_VOL - [7:1] */
+#define WM2200_OUT1R_PGA_VOL_WIDTH                   7  /* OUT1R_PGA_VOL - [7:1] */
+
+/*
+ * R1027 (0x403) - DAC Volume Limit 2L
+ */
+#define WM2200_OUT2_OSR                         0x2000  /* OUT2_OSR */
+#define WM2200_OUT2_OSR_MASK                    0x2000  /* OUT2_OSR */
+#define WM2200_OUT2_OSR_SHIFT                       13  /* OUT2_OSR */
+#define WM2200_OUT2_OSR_WIDTH                        1  /* OUT2_OSR */
+#define WM2200_OUT2L_ANC_SRC                    0x0800  /* OUT2L_ANC_SRC */
+#define WM2200_OUT2L_ANC_SRC_MASK               0x0800  /* OUT2L_ANC_SRC */
+#define WM2200_OUT2L_ANC_SRC_SHIFT                  11  /* OUT2L_ANC_SRC */
+#define WM2200_OUT2L_ANC_SRC_WIDTH                   1  /* OUT2L_ANC_SRC */
+
+/*
+ * R1028 (0x404) - DAC Volume Limit 2R
+ */
+#define WM2200_OUT2R_ANC_SRC                    0x0800  /* OUT2R_ANC_SRC */
+#define WM2200_OUT2R_ANC_SRC_MASK               0x0800  /* OUT2R_ANC_SRC */
+#define WM2200_OUT2R_ANC_SRC_SHIFT                  11  /* OUT2R_ANC_SRC */
+#define WM2200_OUT2R_ANC_SRC_WIDTH                   1  /* OUT2R_ANC_SRC */
+
+/*
+ * R1033 (0x409) - DAC AEC Control 1
+ */
+#define WM2200_AEC_LOOPBACK_ENA                 0x0004  /* AEC_LOOPBACK_ENA */
+#define WM2200_AEC_LOOPBACK_ENA_MASK            0x0004  /* AEC_LOOPBACK_ENA */
+#define WM2200_AEC_LOOPBACK_ENA_SHIFT                2  /* AEC_LOOPBACK_ENA */
+#define WM2200_AEC_LOOPBACK_ENA_WIDTH                1  /* AEC_LOOPBACK_ENA */
+#define WM2200_AEC_LOOPBACK_SRC_MASK            0x0003  /* AEC_LOOPBACK_SRC - [1:0] */
+#define WM2200_AEC_LOOPBACK_SRC_SHIFT                0  /* AEC_LOOPBACK_SRC - [1:0] */
+#define WM2200_AEC_LOOPBACK_SRC_WIDTH                2  /* AEC_LOOPBACK_SRC - [1:0] */
+
+/*
+ * R1034 (0x40A) - Output Volume Ramp
+ */
+#define WM2200_OUT_VD_RAMP_MASK                 0x0070  /* OUT_VD_RAMP - [6:4] */
+#define WM2200_OUT_VD_RAMP_SHIFT                     4  /* OUT_VD_RAMP - [6:4] */
+#define WM2200_OUT_VD_RAMP_WIDTH                     3  /* OUT_VD_RAMP - [6:4] */
+#define WM2200_OUT_VI_RAMP_MASK                 0x0007  /* OUT_VI_RAMP - [2:0] */
+#define WM2200_OUT_VI_RAMP_SHIFT                     0  /* OUT_VI_RAMP - [2:0] */
+#define WM2200_OUT_VI_RAMP_WIDTH                     3  /* OUT_VI_RAMP - [2:0] */
+
+/*
+ * R1035 (0x40B) - DAC Digital Volume 1L
+ */
+#define WM2200_OUT_VU                           0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_MASK                      0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_SHIFT                          9  /* OUT_VU */
+#define WM2200_OUT_VU_WIDTH                          1  /* OUT_VU */
+#define WM2200_OUT1L_MUTE                       0x0100  /* OUT1L_MUTE */
+#define WM2200_OUT1L_MUTE_MASK                  0x0100  /* OUT1L_MUTE */
+#define WM2200_OUT1L_MUTE_SHIFT                      8  /* OUT1L_MUTE */
+#define WM2200_OUT1L_MUTE_WIDTH                      1  /* OUT1L_MUTE */
+#define WM2200_OUT1L_VOL_MASK                   0x00FF  /* OUT1L_VOL - [7:0] */
+#define WM2200_OUT1L_VOL_SHIFT                       0  /* OUT1L_VOL - [7:0] */
+#define WM2200_OUT1L_VOL_WIDTH                       8  /* OUT1L_VOL - [7:0] */
+
+/*
+ * R1036 (0x40C) - DAC Digital Volume 1R
+ */
+#define WM2200_OUT_VU                           0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_MASK                      0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_SHIFT                          9  /* OUT_VU */
+#define WM2200_OUT_VU_WIDTH                          1  /* OUT_VU */
+#define WM2200_OUT1R_MUTE                       0x0100  /* OUT1R_MUTE */
+#define WM2200_OUT1R_MUTE_MASK                  0x0100  /* OUT1R_MUTE */
+#define WM2200_OUT1R_MUTE_SHIFT                      8  /* OUT1R_MUTE */
+#define WM2200_OUT1R_MUTE_WIDTH                      1  /* OUT1R_MUTE */
+#define WM2200_OUT1R_VOL_MASK                   0x00FF  /* OUT1R_VOL - [7:0] */
+#define WM2200_OUT1R_VOL_SHIFT                       0  /* OUT1R_VOL - [7:0] */
+#define WM2200_OUT1R_VOL_WIDTH                       8  /* OUT1R_VOL - [7:0] */
+
+/*
+ * R1037 (0x40D) - DAC Digital Volume 2L
+ */
+#define WM2200_OUT_VU                           0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_MASK                      0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_SHIFT                          9  /* OUT_VU */
+#define WM2200_OUT_VU_WIDTH                          1  /* OUT_VU */
+#define WM2200_OUT2L_MUTE                       0x0100  /* OUT2L_MUTE */
+#define WM2200_OUT2L_MUTE_MASK                  0x0100  /* OUT2L_MUTE */
+#define WM2200_OUT2L_MUTE_SHIFT                      8  /* OUT2L_MUTE */
+#define WM2200_OUT2L_MUTE_WIDTH                      1  /* OUT2L_MUTE */
+#define WM2200_OUT2L_VOL_MASK                   0x00FF  /* OUT2L_VOL - [7:0] */
+#define WM2200_OUT2L_VOL_SHIFT                       0  /* OUT2L_VOL - [7:0] */
+#define WM2200_OUT2L_VOL_WIDTH                       8  /* OUT2L_VOL - [7:0] */
+
+/*
+ * R1038 (0x40E) - DAC Digital Volume 2R
+ */
+#define WM2200_OUT_VU                           0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_MASK                      0x0200  /* OUT_VU */
+#define WM2200_OUT_VU_SHIFT                          9  /* OUT_VU */
+#define WM2200_OUT_VU_WIDTH                          1  /* OUT_VU */
+#define WM2200_OUT2R_MUTE                       0x0100  /* OUT2R_MUTE */
+#define WM2200_OUT2R_MUTE_MASK                  0x0100  /* OUT2R_MUTE */
+#define WM2200_OUT2R_MUTE_SHIFT                      8  /* OUT2R_MUTE */
+#define WM2200_OUT2R_MUTE_WIDTH                      1  /* OUT2R_MUTE */
+#define WM2200_OUT2R_VOL_MASK                   0x00FF  /* OUT2R_VOL - [7:0] */
+#define WM2200_OUT2R_VOL_SHIFT                       0  /* OUT2R_VOL - [7:0] */
+#define WM2200_OUT2R_VOL_WIDTH                       8  /* OUT2R_VOL - [7:0] */
+
+/*
+ * R1047 (0x417) - PDM 1
+ */
+#define WM2200_SPK1R_MUTE                       0x2000  /* SPK1R_MUTE */
+#define WM2200_SPK1R_MUTE_MASK                  0x2000  /* SPK1R_MUTE */
+#define WM2200_SPK1R_MUTE_SHIFT                     13  /* SPK1R_MUTE */
+#define WM2200_SPK1R_MUTE_WIDTH                      1  /* SPK1R_MUTE */
+#define WM2200_SPK1L_MUTE                       0x1000  /* SPK1L_MUTE */
+#define WM2200_SPK1L_MUTE_MASK                  0x1000  /* SPK1L_MUTE */
+#define WM2200_SPK1L_MUTE_SHIFT                     12  /* SPK1L_MUTE */
+#define WM2200_SPK1L_MUTE_WIDTH                      1  /* SPK1L_MUTE */
+#define WM2200_SPK1_MUTE_ENDIAN                 0x0100  /* SPK1_MUTE_ENDIAN */
+#define WM2200_SPK1_MUTE_ENDIAN_MASK            0x0100  /* SPK1_MUTE_ENDIAN */
+#define WM2200_SPK1_MUTE_ENDIAN_SHIFT                8  /* SPK1_MUTE_ENDIAN */
+#define WM2200_SPK1_MUTE_ENDIAN_WIDTH                1  /* SPK1_MUTE_ENDIAN */
+#define WM2200_SPK1_MUTE_SEQL_MASK              0x00FF  /* SPK1_MUTE_SEQL - [7:0] */
+#define WM2200_SPK1_MUTE_SEQL_SHIFT                  0  /* SPK1_MUTE_SEQL - [7:0] */
+#define WM2200_SPK1_MUTE_SEQL_WIDTH                  8  /* SPK1_MUTE_SEQL - [7:0] */
+
+/*
+ * R1048 (0x418) - PDM 2
+ */
+#define WM2200_SPK1_FMT                         0x0001  /* SPK1_FMT */
+#define WM2200_SPK1_FMT_MASK                    0x0001  /* SPK1_FMT */
+#define WM2200_SPK1_FMT_SHIFT                        0  /* SPK1_FMT */
+#define WM2200_SPK1_FMT_WIDTH                        1  /* SPK1_FMT */
+
+/*
+ * R1280 (0x500) - Audio IF 1_1
+ */
+#define WM2200_AIF1_BCLK_INV                    0x0040  /* AIF1_BCLK_INV */
+#define WM2200_AIF1_BCLK_INV_MASK               0x0040  /* AIF1_BCLK_INV */
+#define WM2200_AIF1_BCLK_INV_SHIFT                   6  /* AIF1_BCLK_INV */
+#define WM2200_AIF1_BCLK_INV_WIDTH                   1  /* AIF1_BCLK_INV */
+#define WM2200_AIF1_BCLK_FRC                    0x0020  /* AIF1_BCLK_FRC */
+#define WM2200_AIF1_BCLK_FRC_MASK               0x0020  /* AIF1_BCLK_FRC */
+#define WM2200_AIF1_BCLK_FRC_SHIFT                   5  /* AIF1_BCLK_FRC */
+#define WM2200_AIF1_BCLK_FRC_WIDTH                   1  /* AIF1_BCLK_FRC */
+#define WM2200_AIF1_BCLK_MSTR                   0x0010  /* AIF1_BCLK_MSTR */
+#define WM2200_AIF1_BCLK_MSTR_MASK              0x0010  /* AIF1_BCLK_MSTR */
+#define WM2200_AIF1_BCLK_MSTR_SHIFT                  4  /* AIF1_BCLK_MSTR */
+#define WM2200_AIF1_BCLK_MSTR_WIDTH                  1  /* AIF1_BCLK_MSTR */
+#define WM2200_AIF1_BCLK_DIV_MASK               0x000F  /* AIF1_BCLK_DIV - [3:0] */
+#define WM2200_AIF1_BCLK_DIV_SHIFT                   0  /* AIF1_BCLK_DIV - [3:0] */
+#define WM2200_AIF1_BCLK_DIV_WIDTH                   4  /* AIF1_BCLK_DIV - [3:0] */
+
+/*
+ * R1281 (0x501) - Audio IF 1_2
+ */
+#define WM2200_AIF1TX_DAT_TRI                   0x0020  /* AIF1TX_DAT_TRI */
+#define WM2200_AIF1TX_DAT_TRI_MASK              0x0020  /* AIF1TX_DAT_TRI */
+#define WM2200_AIF1TX_DAT_TRI_SHIFT                  5  /* AIF1TX_DAT_TRI */
+#define WM2200_AIF1TX_DAT_TRI_WIDTH                  1  /* AIF1TX_DAT_TRI */
+#define WM2200_AIF1TX_LRCLK_SRC                 0x0008  /* AIF1TX_LRCLK_SRC */
+#define WM2200_AIF1TX_LRCLK_SRC_MASK            0x0008  /* AIF1TX_LRCLK_SRC */
+#define WM2200_AIF1TX_LRCLK_SRC_SHIFT                3  /* AIF1TX_LRCLK_SRC */
+#define WM2200_AIF1TX_LRCLK_SRC_WIDTH                1  /* AIF1TX_LRCLK_SRC */
+#define WM2200_AIF1TX_LRCLK_INV                 0x0004  /* AIF1TX_LRCLK_INV */
+#define WM2200_AIF1TX_LRCLK_INV_MASK            0x0004  /* AIF1TX_LRCLK_INV */
+#define WM2200_AIF1TX_LRCLK_INV_SHIFT                2  /* AIF1TX_LRCLK_INV */
+#define WM2200_AIF1TX_LRCLK_INV_WIDTH                1  /* AIF1TX_LRCLK_INV */
+#define WM2200_AIF1TX_LRCLK_FRC                 0x0002  /* AIF1TX_LRCLK_FRC */
+#define WM2200_AIF1TX_LRCLK_FRC_MASK            0x0002  /* AIF1TX_LRCLK_FRC */
+#define WM2200_AIF1TX_LRCLK_FRC_SHIFT                1  /* AIF1TX_LRCLK_FRC */
+#define WM2200_AIF1TX_LRCLK_FRC_WIDTH                1  /* AIF1TX_LRCLK_FRC */
+#define WM2200_AIF1TX_LRCLK_MSTR                0x0001  /* AIF1TX_LRCLK_MSTR */
+#define WM2200_AIF1TX_LRCLK_MSTR_MASK           0x0001  /* AIF1TX_LRCLK_MSTR */
+#define WM2200_AIF1TX_LRCLK_MSTR_SHIFT               0  /* AIF1TX_LRCLK_MSTR */
+#define WM2200_AIF1TX_LRCLK_MSTR_WIDTH               1  /* AIF1TX_LRCLK_MSTR */
+
+/*
+ * R1282 (0x502) - Audio IF 1_3
+ */
+#define WM2200_AIF1RX_LRCLK_INV                 0x0004  /* AIF1RX_LRCLK_INV */
+#define WM2200_AIF1RX_LRCLK_INV_MASK            0x0004  /* AIF1RX_LRCLK_INV */
+#define WM2200_AIF1RX_LRCLK_INV_SHIFT                2  /* AIF1RX_LRCLK_INV */
+#define WM2200_AIF1RX_LRCLK_INV_WIDTH                1  /* AIF1RX_LRCLK_INV */
+#define WM2200_AIF1RX_LRCLK_FRC                 0x0002  /* AIF1RX_LRCLK_FRC */
+#define WM2200_AIF1RX_LRCLK_FRC_MASK            0x0002  /* AIF1RX_LRCLK_FRC */
+#define WM2200_AIF1RX_LRCLK_FRC_SHIFT                1  /* AIF1RX_LRCLK_FRC */
+#define WM2200_AIF1RX_LRCLK_FRC_WIDTH                1  /* AIF1RX_LRCLK_FRC */
+#define WM2200_AIF1RX_LRCLK_MSTR                0x0001  /* AIF1RX_LRCLK_MSTR */
+#define WM2200_AIF1RX_LRCLK_MSTR_MASK           0x0001  /* AIF1RX_LRCLK_MSTR */
+#define WM2200_AIF1RX_LRCLK_MSTR_SHIFT               0  /* AIF1RX_LRCLK_MSTR */
+#define WM2200_AIF1RX_LRCLK_MSTR_WIDTH               1  /* AIF1RX_LRCLK_MSTR */
+
+/*
+ * R1283 (0x503) - Audio IF 1_4
+ */
+#define WM2200_AIF1_TRI                         0x0040  /* AIF1_TRI */
+#define WM2200_AIF1_TRI_MASK                    0x0040  /* AIF1_TRI */
+#define WM2200_AIF1_TRI_SHIFT                        6  /* AIF1_TRI */
+#define WM2200_AIF1_TRI_WIDTH                        1  /* AIF1_TRI */
+
+/*
+ * R1284 (0x504) - Audio IF 1_5
+ */
+#define WM2200_AIF1_FMT_MASK                    0x0007  /* AIF1_FMT - [2:0] */
+#define WM2200_AIF1_FMT_SHIFT                        0  /* AIF1_FMT - [2:0] */
+#define WM2200_AIF1_FMT_WIDTH                        3  /* AIF1_FMT - [2:0] */
+
+/*
+ * R1285 (0x505) - Audio IF 1_6
+ */
+#define WM2200_AIF1TX_BCPF_MASK                 0x07FF  /* AIF1TX_BCPF - [10:0] */
+#define WM2200_AIF1TX_BCPF_SHIFT                     0  /* AIF1TX_BCPF - [10:0] */
+#define WM2200_AIF1TX_BCPF_WIDTH                    11  /* AIF1TX_BCPF - [10:0] */
+
+/*
+ * R1286 (0x506) - Audio IF 1_7
+ */
+#define WM2200_AIF1RX_BCPF_MASK                 0x07FF  /* AIF1RX_BCPF - [10:0] */
+#define WM2200_AIF1RX_BCPF_SHIFT                     0  /* AIF1RX_BCPF - [10:0] */
+#define WM2200_AIF1RX_BCPF_WIDTH                    11  /* AIF1RX_BCPF - [10:0] */
+
+/*
+ * R1287 (0x507) - Audio IF 1_8
+ */
+#define WM2200_AIF1TX_WL_MASK                   0x3F00  /* AIF1TX_WL - [13:8] */
+#define WM2200_AIF1TX_WL_SHIFT                       8  /* AIF1TX_WL - [13:8] */
+#define WM2200_AIF1TX_WL_WIDTH                       6  /* AIF1TX_WL - [13:8] */
+#define WM2200_AIF1TX_SLOT_LEN_MASK             0x00FF  /* AIF1TX_SLOT_LEN - [7:0] */
+#define WM2200_AIF1TX_SLOT_LEN_SHIFT                 0  /* AIF1TX_SLOT_LEN - [7:0] */
+#define WM2200_AIF1TX_SLOT_LEN_WIDTH                 8  /* AIF1TX_SLOT_LEN - [7:0] */
+
+/*
+ * R1288 (0x508) - Audio IF 1_9
+ */
+#define WM2200_AIF1RX_WL_MASK                   0x3F00  /* AIF1RX_WL - [13:8] */
+#define WM2200_AIF1RX_WL_SHIFT                       8  /* AIF1RX_WL - [13:8] */
+#define WM2200_AIF1RX_WL_WIDTH                       6  /* AIF1RX_WL - [13:8] */
+#define WM2200_AIF1RX_SLOT_LEN_MASK             0x00FF  /* AIF1RX_SLOT_LEN - [7:0] */
+#define WM2200_AIF1RX_SLOT_LEN_SHIFT                 0  /* AIF1RX_SLOT_LEN - [7:0] */
+#define WM2200_AIF1RX_SLOT_LEN_WIDTH                 8  /* AIF1RX_SLOT_LEN - [7:0] */
+
+/*
+ * R1289 (0x509) - Audio IF 1_10
+ */
+#define WM2200_AIF1TX1_SLOT_MASK                0x003F  /* AIF1TX1_SLOT - [5:0] */
+#define WM2200_AIF1TX1_SLOT_SHIFT                    0  /* AIF1TX1_SLOT - [5:0] */
+#define WM2200_AIF1TX1_SLOT_WIDTH                    6  /* AIF1TX1_SLOT - [5:0] */
+
+/*
+ * R1290 (0x50A) - Audio IF 1_11
+ */
+#define WM2200_AIF1TX2_SLOT_MASK                0x003F  /* AIF1TX2_SLOT - [5:0] */
+#define WM2200_AIF1TX2_SLOT_SHIFT                    0  /* AIF1TX2_SLOT - [5:0] */
+#define WM2200_AIF1TX2_SLOT_WIDTH                    6  /* AIF1TX2_SLOT - [5:0] */
+
+/*
+ * R1291 (0x50B) - Audio IF 1_12
+ */
+#define WM2200_AIF1TX3_SLOT_MASK                0x003F  /* AIF1TX3_SLOT - [5:0] */
+#define WM2200_AIF1TX3_SLOT_SHIFT                    0  /* AIF1TX3_SLOT - [5:0] */
+#define WM2200_AIF1TX3_SLOT_WIDTH                    6  /* AIF1TX3_SLOT - [5:0] */
+
+/*
+ * R1292 (0x50C) - Audio IF 1_13
+ */
+#define WM2200_AIF1TX4_SLOT_MASK                0x003F  /* AIF1TX4_SLOT - [5:0] */
+#define WM2200_AIF1TX4_SLOT_SHIFT                    0  /* AIF1TX4_SLOT - [5:0] */
+#define WM2200_AIF1TX4_SLOT_WIDTH                    6  /* AIF1TX4_SLOT - [5:0] */
+
+/*
+ * R1293 (0x50D) - Audio IF 1_14
+ */
+#define WM2200_AIF1TX5_SLOT_MASK                0x003F  /* AIF1TX5_SLOT - [5:0] */
+#define WM2200_AIF1TX5_SLOT_SHIFT                    0  /* AIF1TX5_SLOT - [5:0] */
+#define WM2200_AIF1TX5_SLOT_WIDTH                    6  /* AIF1TX5_SLOT - [5:0] */
+
+/*
+ * R1294 (0x50E) - Audio IF 1_15
+ */
+#define WM2200_AIF1TX6_SLOT_MASK                0x003F  /* AIF1TX6_SLOT - [5:0] */
+#define WM2200_AIF1TX6_SLOT_SHIFT                    0  /* AIF1TX6_SLOT - [5:0] */
+#define WM2200_AIF1TX6_SLOT_WIDTH                    6  /* AIF1TX6_SLOT - [5:0] */
+
+/*
+ * R1295 (0x50F) - Audio IF 1_16
+ */
+#define WM2200_AIF1RX1_SLOT_MASK                0x003F  /* AIF1RX1_SLOT - [5:0] */
+#define WM2200_AIF1RX1_SLOT_SHIFT                    0  /* AIF1RX1_SLOT - [5:0] */
+#define WM2200_AIF1RX1_SLOT_WIDTH                    6  /* AIF1RX1_SLOT - [5:0] */
+
+/*
+ * R1296 (0x510) - Audio IF 1_17
+ */
+#define WM2200_AIF1RX2_SLOT_MASK                0x003F  /* AIF1RX2_SLOT - [5:0] */
+#define WM2200_AIF1RX2_SLOT_SHIFT                    0  /* AIF1RX2_SLOT - [5:0] */
+#define WM2200_AIF1RX2_SLOT_WIDTH                    6  /* AIF1RX2_SLOT - [5:0] */
+
+/*
+ * R1297 (0x511) - Audio IF 1_18
+ */
+#define WM2200_AIF1RX3_SLOT_MASK                0x003F  /* AIF1RX3_SLOT - [5:0] */
+#define WM2200_AIF1RX3_SLOT_SHIFT                    0  /* AIF1RX3_SLOT - [5:0] */
+#define WM2200_AIF1RX3_SLOT_WIDTH                    6  /* AIF1RX3_SLOT - [5:0] */
+
+/*
+ * R1298 (0x512) - Audio IF 1_19
+ */
+#define WM2200_AIF1RX4_SLOT_MASK                0x003F  /* AIF1RX4_SLOT - [5:0] */
+#define WM2200_AIF1RX4_SLOT_SHIFT                    0  /* AIF1RX4_SLOT - [5:0] */
+#define WM2200_AIF1RX4_SLOT_WIDTH                    6  /* AIF1RX4_SLOT - [5:0] */
+
+/*
+ * R1299 (0x513) - Audio IF 1_20
+ */
+#define WM2200_AIF1RX5_SLOT_MASK                0x003F  /* AIF1RX5_SLOT - [5:0] */
+#define WM2200_AIF1RX5_SLOT_SHIFT                    0  /* AIF1RX5_SLOT - [5:0] */
+#define WM2200_AIF1RX5_SLOT_WIDTH                    6  /* AIF1RX5_SLOT - [5:0] */
+
+/*
+ * R1300 (0x514) - Audio IF 1_21
+ */
+#define WM2200_AIF1RX6_SLOT_MASK                0x003F  /* AIF1RX6_SLOT - [5:0] */
+#define WM2200_AIF1RX6_SLOT_SHIFT                    0  /* AIF1RX6_SLOT - [5:0] */
+#define WM2200_AIF1RX6_SLOT_WIDTH                    6  /* AIF1RX6_SLOT - [5:0] */
+
+/*
+ * R1301 (0x515) - Audio IF 1_22
+ */
+#define WM2200_AIF1RX6_ENA                      0x0800  /* AIF1RX6_ENA */
+#define WM2200_AIF1RX6_ENA_MASK                 0x0800  /* AIF1RX6_ENA */
+#define WM2200_AIF1RX6_ENA_SHIFT                    11  /* AIF1RX6_ENA */
+#define WM2200_AIF1RX6_ENA_WIDTH                     1  /* AIF1RX6_ENA */
+#define WM2200_AIF1RX5_ENA                      0x0400  /* AIF1RX5_ENA */
+#define WM2200_AIF1RX5_ENA_MASK                 0x0400  /* AIF1RX5_ENA */
+#define WM2200_AIF1RX5_ENA_SHIFT                    10  /* AIF1RX5_ENA */
+#define WM2200_AIF1RX5_ENA_WIDTH                     1  /* AIF1RX5_ENA */
+#define WM2200_AIF1RX4_ENA                      0x0200  /* AIF1RX4_ENA */
+#define WM2200_AIF1RX4_ENA_MASK                 0x0200  /* AIF1RX4_ENA */
+#define WM2200_AIF1RX4_ENA_SHIFT                     9  /* AIF1RX4_ENA */
+#define WM2200_AIF1RX4_ENA_WIDTH                     1  /* AIF1RX4_ENA */
+#define WM2200_AIF1RX3_ENA                      0x0100  /* AIF1RX3_ENA */
+#define WM2200_AIF1RX3_ENA_MASK                 0x0100  /* AIF1RX3_ENA */
+#define WM2200_AIF1RX3_ENA_SHIFT                     8  /* AIF1RX3_ENA */
+#define WM2200_AIF1RX3_ENA_WIDTH                     1  /* AIF1RX3_ENA */
+#define WM2200_AIF1RX2_ENA                      0x0080  /* AIF1RX2_ENA */
+#define WM2200_AIF1RX2_ENA_MASK                 0x0080  /* AIF1RX2_ENA */
+#define WM2200_AIF1RX2_ENA_SHIFT                     7  /* AIF1RX2_ENA */
+#define WM2200_AIF1RX2_ENA_WIDTH                     1  /* AIF1RX2_ENA */
+#define WM2200_AIF1RX1_ENA                      0x0040  /* AIF1RX1_ENA */
+#define WM2200_AIF1RX1_ENA_MASK                 0x0040  /* AIF1RX1_ENA */
+#define WM2200_AIF1RX1_ENA_SHIFT                     6  /* AIF1RX1_ENA */
+#define WM2200_AIF1RX1_ENA_WIDTH                     1  /* AIF1RX1_ENA */
+#define WM2200_AIF1TX6_ENA                      0x0020  /* AIF1TX6_ENA */
+#define WM2200_AIF1TX6_ENA_MASK                 0x0020  /* AIF1TX6_ENA */
+#define WM2200_AIF1TX6_ENA_SHIFT                     5  /* AIF1TX6_ENA */
+#define WM2200_AIF1TX6_ENA_WIDTH                     1  /* AIF1TX6_ENA */
+#define WM2200_AIF1TX5_ENA                      0x0010  /* AIF1TX5_ENA */
+#define WM2200_AIF1TX5_ENA_MASK                 0x0010  /* AIF1TX5_ENA */
+#define WM2200_AIF1TX5_ENA_SHIFT                     4  /* AIF1TX5_ENA */
+#define WM2200_AIF1TX5_ENA_WIDTH                     1  /* AIF1TX5_ENA */
+#define WM2200_AIF1TX4_ENA                      0x0008  /* AIF1TX4_ENA */
+#define WM2200_AIF1TX4_ENA_MASK                 0x0008  /* AIF1TX4_ENA */
+#define WM2200_AIF1TX4_ENA_SHIFT                     3  /* AIF1TX4_ENA */
+#define WM2200_AIF1TX4_ENA_WIDTH                     1  /* AIF1TX4_ENA */
+#define WM2200_AIF1TX3_ENA                      0x0004  /* AIF1TX3_ENA */
+#define WM2200_AIF1TX3_ENA_MASK                 0x0004  /* AIF1TX3_ENA */
+#define WM2200_AIF1TX3_ENA_SHIFT                     2  /* AIF1TX3_ENA */
+#define WM2200_AIF1TX3_ENA_WIDTH                     1  /* AIF1TX3_ENA */
+#define WM2200_AIF1TX2_ENA                      0x0002  /* AIF1TX2_ENA */
+#define WM2200_AIF1TX2_ENA_MASK                 0x0002  /* AIF1TX2_ENA */
+#define WM2200_AIF1TX2_ENA_SHIFT                     1  /* AIF1TX2_ENA */
+#define WM2200_AIF1TX2_ENA_WIDTH                     1  /* AIF1TX2_ENA */
+#define WM2200_AIF1TX1_ENA                      0x0001  /* AIF1TX1_ENA */
+#define WM2200_AIF1TX1_ENA_MASK                 0x0001  /* AIF1TX1_ENA */
+#define WM2200_AIF1TX1_ENA_SHIFT                     0  /* AIF1TX1_ENA */
+#define WM2200_AIF1TX1_ENA_WIDTH                     1  /* AIF1TX1_ENA */
+
+/*
+ * R1536 (0x600) - OUT1LMIX Input 1 Source
+ */
+#define WM2200_OUT1LMIX_SRC1_MASK               0x007F  /* OUT1LMIX_SRC1 - [6:0] */
+#define WM2200_OUT1LMIX_SRC1_SHIFT                   0  /* OUT1LMIX_SRC1 - [6:0] */
+#define WM2200_OUT1LMIX_SRC1_WIDTH                   7  /* OUT1LMIX_SRC1 - [6:0] */
+
+/*
+ * R1537 (0x601) - OUT1LMIX Input 1 Volume
+ */
+#define WM2200_OUT1LMIX_VOL1_MASK               0x00FE  /* OUT1LMIX_VOL1 - [7:1] */
+#define WM2200_OUT1LMIX_VOL1_SHIFT                   1  /* OUT1LMIX_VOL1 - [7:1] */
+#define WM2200_OUT1LMIX_VOL1_WIDTH                   7  /* OUT1LMIX_VOL1 - [7:1] */
+
+/*
+ * R1538 (0x602) - OUT1LMIX Input 2 Source
+ */
+#define WM2200_OUT1LMIX_SRC2_MASK               0x007F  /* OUT1LMIX_SRC2 - [6:0] */
+#define WM2200_OUT1LMIX_SRC2_SHIFT                   0  /* OUT1LMIX_SRC2 - [6:0] */
+#define WM2200_OUT1LMIX_SRC2_WIDTH                   7  /* OUT1LMIX_SRC2 - [6:0] */
+
+/*
+ * R1539 (0x603) - OUT1LMIX Input 2 Volume
+ */
+#define WM2200_OUT1LMIX_VOL2_MASK               0x00FE  /* OUT1LMIX_VOL2 - [7:1] */
+#define WM2200_OUT1LMIX_VOL2_SHIFT                   1  /* OUT1LMIX_VOL2 - [7:1] */
+#define WM2200_OUT1LMIX_VOL2_WIDTH                   7  /* OUT1LMIX_VOL2 - [7:1] */
+
+/*
+ * R1540 (0x604) - OUT1LMIX Input 3 Source
+ */
+#define WM2200_OUT1LMIX_SRC3_MASK               0x007F  /* OUT1LMIX_SRC3 - [6:0] */
+#define WM2200_OUT1LMIX_SRC3_SHIFT                   0  /* OUT1LMIX_SRC3 - [6:0] */
+#define WM2200_OUT1LMIX_SRC3_WIDTH                   7  /* OUT1LMIX_SRC3 - [6:0] */
+
+/*
+ * R1541 (0x605) - OUT1LMIX Input 3 Volume
+ */
+#define WM2200_OUT1LMIX_VOL3_MASK               0x00FE  /* OUT1LMIX_VOL3 - [7:1] */
+#define WM2200_OUT1LMIX_VOL3_SHIFT                   1  /* OUT1LMIX_VOL3 - [7:1] */
+#define WM2200_OUT1LMIX_VOL3_WIDTH                   7  /* OUT1LMIX_VOL3 - [7:1] */
+
+/*
+ * R1542 (0x606) - OUT1LMIX Input 4 Source
+ */
+#define WM2200_OUT1LMIX_SRC4_MASK               0x007F  /* OUT1LMIX_SRC4 - [6:0] */
+#define WM2200_OUT1LMIX_SRC4_SHIFT                   0  /* OUT1LMIX_SRC4 - [6:0] */
+#define WM2200_OUT1LMIX_SRC4_WIDTH                   7  /* OUT1LMIX_SRC4 - [6:0] */
+
+/*
+ * R1543 (0x607) - OUT1LMIX Input 4 Volume
+ */
+#define WM2200_OUT1LMIX_VOL4_MASK               0x00FE  /* OUT1LMIX_VOL4 - [7:1] */
+#define WM2200_OUT1LMIX_VOL4_SHIFT                   1  /* OUT1LMIX_VOL4 - [7:1] */
+#define WM2200_OUT1LMIX_VOL4_WIDTH                   7  /* OUT1LMIX_VOL4 - [7:1] */
+
+/*
+ * R1544 (0x608) - OUT1RMIX Input 1 Source
+ */
+#define WM2200_OUT1RMIX_SRC1_MASK               0x007F  /* OUT1RMIX_SRC1 - [6:0] */
+#define WM2200_OUT1RMIX_SRC1_SHIFT                   0  /* OUT1RMIX_SRC1 - [6:0] */
+#define WM2200_OUT1RMIX_SRC1_WIDTH                   7  /* OUT1RMIX_SRC1 - [6:0] */
+
+/*
+ * R1545 (0x609) - OUT1RMIX Input 1 Volume
+ */
+#define WM2200_OUT1RMIX_VOL1_MASK               0x00FE  /* OUT1RMIX_VOL1 - [7:1] */
+#define WM2200_OUT1RMIX_VOL1_SHIFT                   1  /* OUT1RMIX_VOL1 - [7:1] */
+#define WM2200_OUT1RMIX_VOL1_WIDTH                   7  /* OUT1RMIX_VOL1 - [7:1] */
+
+/*
+ * R1546 (0x60A) - OUT1RMIX Input 2 Source
+ */
+#define WM2200_OUT1RMIX_SRC2_MASK               0x007F  /* OUT1RMIX_SRC2 - [6:0] */
+#define WM2200_OUT1RMIX_SRC2_SHIFT                   0  /* OUT1RMIX_SRC2 - [6:0] */
+#define WM2200_OUT1RMIX_SRC2_WIDTH                   7  /* OUT1RMIX_SRC2 - [6:0] */
+
+/*
+ * R1547 (0x60B) - OUT1RMIX Input 2 Volume
+ */
+#define WM2200_OUT1RMIX_VOL2_MASK               0x00FE  /* OUT1RMIX_VOL2 - [7:1] */
+#define WM2200_OUT1RMIX_VOL2_SHIFT                   1  /* OUT1RMIX_VOL2 - [7:1] */
+#define WM2200_OUT1RMIX_VOL2_WIDTH                   7  /* OUT1RMIX_VOL2 - [7:1] */
+
+/*
+ * R1548 (0x60C) - OUT1RMIX Input 3 Source
+ */
+#define WM2200_OUT1RMIX_SRC3_MASK               0x007F  /* OUT1RMIX_SRC3 - [6:0] */
+#define WM2200_OUT1RMIX_SRC3_SHIFT                   0  /* OUT1RMIX_SRC3 - [6:0] */
+#define WM2200_OUT1RMIX_SRC3_WIDTH                   7  /* OUT1RMIX_SRC3 - [6:0] */
+
+/*
+ * R1549 (0x60D) - OUT1RMIX Input 3 Volume
+ */
+#define WM2200_OUT1RMIX_VOL3_MASK               0x00FE  /* OUT1RMIX_VOL3 - [7:1] */
+#define WM2200_OUT1RMIX_VOL3_SHIFT                   1  /* OUT1RMIX_VOL3 - [7:1] */
+#define WM2200_OUT1RMIX_VOL3_WIDTH                   7  /* OUT1RMIX_VOL3 - [7:1] */
+
+/*
+ * R1550 (0x60E) - OUT1RMIX Input 4 Source
+ */
+#define WM2200_OUT1RMIX_SRC4_MASK               0x007F  /* OUT1RMIX_SRC4 - [6:0] */
+#define WM2200_OUT1RMIX_SRC4_SHIFT                   0  /* OUT1RMIX_SRC4 - [6:0] */
+#define WM2200_OUT1RMIX_SRC4_WIDTH                   7  /* OUT1RMIX_SRC4 - [6:0] */
+
+/*
+ * R1551 (0x60F) - OUT1RMIX Input 4 Volume
+ */
+#define WM2200_OUT1RMIX_VOL4_MASK               0x00FE  /* OUT1RMIX_VOL4 - [7:1] */
+#define WM2200_OUT1RMIX_VOL4_SHIFT                   1  /* OUT1RMIX_VOL4 - [7:1] */
+#define WM2200_OUT1RMIX_VOL4_WIDTH                   7  /* OUT1RMIX_VOL4 - [7:1] */
+
+/*
+ * R1552 (0x610) - OUT2LMIX Input 1 Source
+ */
+#define WM2200_OUT2LMIX_SRC1_MASK               0x007F  /* OUT2LMIX_SRC1 - [6:0] */
+#define WM2200_OUT2LMIX_SRC1_SHIFT                   0  /* OUT2LMIX_SRC1 - [6:0] */
+#define WM2200_OUT2LMIX_SRC1_WIDTH                   7  /* OUT2LMIX_SRC1 - [6:0] */
+
+/*
+ * R1553 (0x611) - OUT2LMIX Input 1 Volume
+ */
+#define WM2200_OUT2LMIX_VOL1_MASK               0x00FE  /* OUT2LMIX_VOL1 - [7:1] */
+#define WM2200_OUT2LMIX_VOL1_SHIFT                   1  /* OUT2LMIX_VOL1 - [7:1] */
+#define WM2200_OUT2LMIX_VOL1_WIDTH                   7  /* OUT2LMIX_VOL1 - [7:1] */
+
+/*
+ * R1554 (0x612) - OUT2LMIX Input 2 Source
+ */
+#define WM2200_OUT2LMIX_SRC2_MASK               0x007F  /* OUT2LMIX_SRC2 - [6:0] */
+#define WM2200_OUT2LMIX_SRC2_SHIFT                   0  /* OUT2LMIX_SRC2 - [6:0] */
+#define WM2200_OUT2LMIX_SRC2_WIDTH                   7  /* OUT2LMIX_SRC2 - [6:0] */
+
+/*
+ * R1555 (0x613) - OUT2LMIX Input 2 Volume
+ */
+#define WM2200_OUT2LMIX_VOL2_MASK               0x00FE  /* OUT2LMIX_VOL2 - [7:1] */
+#define WM2200_OUT2LMIX_VOL2_SHIFT                   1  /* OUT2LMIX_VOL2 - [7:1] */
+#define WM2200_OUT2LMIX_VOL2_WIDTH                   7  /* OUT2LMIX_VOL2 - [7:1] */
+
+/*
+ * R1556 (0x614) - OUT2LMIX Input 3 Source
+ */
+#define WM2200_OUT2LMIX_SRC3_MASK               0x007F  /* OUT2LMIX_SRC3 - [6:0] */
+#define WM2200_OUT2LMIX_SRC3_SHIFT                   0  /* OUT2LMIX_SRC3 - [6:0] */
+#define WM2200_OUT2LMIX_SRC3_WIDTH                   7  /* OUT2LMIX_SRC3 - [6:0] */
+
+/*
+ * R1557 (0x615) - OUT2LMIX Input 3 Volume
+ */
+#define WM2200_OUT2LMIX_VOL3_MASK               0x00FE  /* OUT2LMIX_VOL3 - [7:1] */
+#define WM2200_OUT2LMIX_VOL3_SHIFT                   1  /* OUT2LMIX_VOL3 - [7:1] */
+#define WM2200_OUT2LMIX_VOL3_WIDTH                   7  /* OUT2LMIX_VOL3 - [7:1] */
+
+/*
+ * R1558 (0x616) - OUT2LMIX Input 4 Source
+ */
+#define WM2200_OUT2LMIX_SRC4_MASK               0x007F  /* OUT2LMIX_SRC4 - [6:0] */
+#define WM2200_OUT2LMIX_SRC4_SHIFT                   0  /* OUT2LMIX_SRC4 - [6:0] */
+#define WM2200_OUT2LMIX_SRC4_WIDTH                   7  /* OUT2LMIX_SRC4 - [6:0] */
+
+/*
+ * R1559 (0x617) - OUT2LMIX Input 4 Volume
+ */
+#define WM2200_OUT2LMIX_VOL4_MASK               0x00FE  /* OUT2LMIX_VOL4 - [7:1] */
+#define WM2200_OUT2LMIX_VOL4_SHIFT                   1  /* OUT2LMIX_VOL4 - [7:1] */
+#define WM2200_OUT2LMIX_VOL4_WIDTH                   7  /* OUT2LMIX_VOL4 - [7:1] */
+
+/*
+ * R1560 (0x618) - OUT2RMIX Input 1 Source
+ */
+#define WM2200_OUT2RMIX_SRC1_MASK               0x007F  /* OUT2RMIX_SRC1 - [6:0] */
+#define WM2200_OUT2RMIX_SRC1_SHIFT                   0  /* OUT2RMIX_SRC1 - [6:0] */
+#define WM2200_OUT2RMIX_SRC1_WIDTH                   7  /* OUT2RMIX_SRC1 - [6:0] */
+
+/*
+ * R1561 (0x619) - OUT2RMIX Input 1 Volume
+ */
+#define WM2200_OUT2RMIX_VOL1_MASK               0x00FE  /* OUT2RMIX_VOL1 - [7:1] */
+#define WM2200_OUT2RMIX_VOL1_SHIFT                   1  /* OUT2RMIX_VOL1 - [7:1] */
+#define WM2200_OUT2RMIX_VOL1_WIDTH                   7  /* OUT2RMIX_VOL1 - [7:1] */
+
+/*
+ * R1562 (0x61A) - OUT2RMIX Input 2 Source
+ */
+#define WM2200_OUT2RMIX_SRC2_MASK               0x007F  /* OUT2RMIX_SRC2 - [6:0] */
+#define WM2200_OUT2RMIX_SRC2_SHIFT                   0  /* OUT2RMIX_SRC2 - [6:0] */
+#define WM2200_OUT2RMIX_SRC2_WIDTH                   7  /* OUT2RMIX_SRC2 - [6:0] */
+
+/*
+ * R1563 (0x61B) - OUT2RMIX Input 2 Volume
+ */
+#define WM2200_OUT2RMIX_VOL2_MASK               0x00FE  /* OUT2RMIX_VOL2 - [7:1] */
+#define WM2200_OUT2RMIX_VOL2_SHIFT                   1  /* OUT2RMIX_VOL2 - [7:1] */
+#define WM2200_OUT2RMIX_VOL2_WIDTH                   7  /* OUT2RMIX_VOL2 - [7:1] */
+
+/*
+ * R1564 (0x61C) - OUT2RMIX Input 3 Source
+ */
+#define WM2200_OUT2RMIX_SRC3_MASK               0x007F  /* OUT2RMIX_SRC3 - [6:0] */
+#define WM2200_OUT2RMIX_SRC3_SHIFT                   0  /* OUT2RMIX_SRC3 - [6:0] */
+#define WM2200_OUT2RMIX_SRC3_WIDTH                   7  /* OUT2RMIX_SRC3 - [6:0] */
+
+/*
+ * R1565 (0x61D) - OUT2RMIX Input 3 Volume
+ */
+#define WM2200_OUT2RMIX_VOL3_MASK               0x00FE  /* OUT2RMIX_VOL3 - [7:1] */
+#define WM2200_OUT2RMIX_VOL3_SHIFT                   1  /* OUT2RMIX_VOL3 - [7:1] */
+#define WM2200_OUT2RMIX_VOL3_WIDTH                   7  /* OUT2RMIX_VOL3 - [7:1] */
+
+/*
+ * R1566 (0x61E) - OUT2RMIX Input 4 Source
+ */
+#define WM2200_OUT2RMIX_SRC4_MASK               0x007F  /* OUT2RMIX_SRC4 - [6:0] */
+#define WM2200_OUT2RMIX_SRC4_SHIFT                   0  /* OUT2RMIX_SRC4 - [6:0] */
+#define WM2200_OUT2RMIX_SRC4_WIDTH                   7  /* OUT2RMIX_SRC4 - [6:0] */
+
+/*
+ * R1567 (0x61F) - OUT2RMIX Input 4 Volume
+ */
+#define WM2200_OUT2RMIX_VOL4_MASK               0x00FE  /* OUT2RMIX_VOL4 - [7:1] */
+#define WM2200_OUT2RMIX_VOL4_SHIFT                   1  /* OUT2RMIX_VOL4 - [7:1] */
+#define WM2200_OUT2RMIX_VOL4_WIDTH                   7  /* OUT2RMIX_VOL4 - [7:1] */
+
+/*
+ * R1568 (0x620) - AIF1TX1MIX Input 1 Source
+ */
+#define WM2200_AIF1TX1MIX_SRC1_MASK             0x007F  /* AIF1TX1MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC1_SHIFT                 0  /* AIF1TX1MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC1_WIDTH                 7  /* AIF1TX1MIX_SRC1 - [6:0] */
+
+/*
+ * R1569 (0x621) - AIF1TX1MIX Input 1 Volume
+ */
+#define WM2200_AIF1TX1MIX_VOL1_MASK             0x00FE  /* AIF1TX1MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL1_SHIFT                 1  /* AIF1TX1MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL1_WIDTH                 7  /* AIF1TX1MIX_VOL1 - [7:1] */
+
+/*
+ * R1570 (0x622) - AIF1TX1MIX Input 2 Source
+ */
+#define WM2200_AIF1TX1MIX_SRC2_MASK             0x007F  /* AIF1TX1MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC2_SHIFT                 0  /* AIF1TX1MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC2_WIDTH                 7  /* AIF1TX1MIX_SRC2 - [6:0] */
+
+/*
+ * R1571 (0x623) - AIF1TX1MIX Input 2 Volume
+ */
+#define WM2200_AIF1TX1MIX_VOL2_MASK             0x00FE  /* AIF1TX1MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL2_SHIFT                 1  /* AIF1TX1MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL2_WIDTH                 7  /* AIF1TX1MIX_VOL2 - [7:1] */
+
+/*
+ * R1572 (0x624) - AIF1TX1MIX Input 3 Source
+ */
+#define WM2200_AIF1TX1MIX_SRC3_MASK             0x007F  /* AIF1TX1MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC3_SHIFT                 0  /* AIF1TX1MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC3_WIDTH                 7  /* AIF1TX1MIX_SRC3 - [6:0] */
+
+/*
+ * R1573 (0x625) - AIF1TX1MIX Input 3 Volume
+ */
+#define WM2200_AIF1TX1MIX_VOL3_MASK             0x00FE  /* AIF1TX1MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL3_SHIFT                 1  /* AIF1TX1MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL3_WIDTH                 7  /* AIF1TX1MIX_VOL3 - [7:1] */
+
+/*
+ * R1574 (0x626) - AIF1TX1MIX Input 4 Source
+ */
+#define WM2200_AIF1TX1MIX_SRC4_MASK             0x007F  /* AIF1TX1MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC4_SHIFT                 0  /* AIF1TX1MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX1MIX_SRC4_WIDTH                 7  /* AIF1TX1MIX_SRC4 - [6:0] */
+
+/*
+ * R1575 (0x627) - AIF1TX1MIX Input 4 Volume
+ */
+#define WM2200_AIF1TX1MIX_VOL4_MASK             0x00FE  /* AIF1TX1MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL4_SHIFT                 1  /* AIF1TX1MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX1MIX_VOL4_WIDTH                 7  /* AIF1TX1MIX_VOL4 - [7:1] */
+
+/*
+ * R1576 (0x628) - AIF1TX2MIX Input 1 Source
+ */
+#define WM2200_AIF1TX2MIX_SRC1_MASK             0x007F  /* AIF1TX2MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC1_SHIFT                 0  /* AIF1TX2MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC1_WIDTH                 7  /* AIF1TX2MIX_SRC1 - [6:0] */
+
+/*
+ * R1577 (0x629) - AIF1TX2MIX Input 1 Volume
+ */
+#define WM2200_AIF1TX2MIX_VOL1_MASK             0x00FE  /* AIF1TX2MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL1_SHIFT                 1  /* AIF1TX2MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL1_WIDTH                 7  /* AIF1TX2MIX_VOL1 - [7:1] */
+
+/*
+ * R1578 (0x62A) - AIF1TX2MIX Input 2 Source
+ */
+#define WM2200_AIF1TX2MIX_SRC2_MASK             0x007F  /* AIF1TX2MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC2_SHIFT                 0  /* AIF1TX2MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC2_WIDTH                 7  /* AIF1TX2MIX_SRC2 - [6:0] */
+
+/*
+ * R1579 (0x62B) - AIF1TX2MIX Input 2 Volume
+ */
+#define WM2200_AIF1TX2MIX_VOL2_MASK             0x00FE  /* AIF1TX2MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL2_SHIFT                 1  /* AIF1TX2MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL2_WIDTH                 7  /* AIF1TX2MIX_VOL2 - [7:1] */
+
+/*
+ * R1580 (0x62C) - AIF1TX2MIX Input 3 Source
+ */
+#define WM2200_AIF1TX2MIX_SRC3_MASK             0x007F  /* AIF1TX2MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC3_SHIFT                 0  /* AIF1TX2MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC3_WIDTH                 7  /* AIF1TX2MIX_SRC3 - [6:0] */
+
+/*
+ * R1581 (0x62D) - AIF1TX2MIX Input 3 Volume
+ */
+#define WM2200_AIF1TX2MIX_VOL3_MASK             0x00FE  /* AIF1TX2MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL3_SHIFT                 1  /* AIF1TX2MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL3_WIDTH                 7  /* AIF1TX2MIX_VOL3 - [7:1] */
+
+/*
+ * R1582 (0x62E) - AIF1TX2MIX Input 4 Source
+ */
+#define WM2200_AIF1TX2MIX_SRC4_MASK             0x007F  /* AIF1TX2MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC4_SHIFT                 0  /* AIF1TX2MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX2MIX_SRC4_WIDTH                 7  /* AIF1TX2MIX_SRC4 - [6:0] */
+
+/*
+ * R1583 (0x62F) - AIF1TX2MIX Input 4 Volume
+ */
+#define WM2200_AIF1TX2MIX_VOL4_MASK             0x00FE  /* AIF1TX2MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL4_SHIFT                 1  /* AIF1TX2MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX2MIX_VOL4_WIDTH                 7  /* AIF1TX2MIX_VOL4 - [7:1] */
+
+/*
+ * R1584 (0x630) - AIF1TX3MIX Input 1 Source
+ */
+#define WM2200_AIF1TX3MIX_SRC1_MASK             0x007F  /* AIF1TX3MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC1_SHIFT                 0  /* AIF1TX3MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC1_WIDTH                 7  /* AIF1TX3MIX_SRC1 - [6:0] */
+
+/*
+ * R1585 (0x631) - AIF1TX3MIX Input 1 Volume
+ */
+#define WM2200_AIF1TX3MIX_VOL1_MASK             0x00FE  /* AIF1TX3MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL1_SHIFT                 1  /* AIF1TX3MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL1_WIDTH                 7  /* AIF1TX3MIX_VOL1 - [7:1] */
+
+/*
+ * R1586 (0x632) - AIF1TX3MIX Input 2 Source
+ */
+#define WM2200_AIF1TX3MIX_SRC2_MASK             0x007F  /* AIF1TX3MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC2_SHIFT                 0  /* AIF1TX3MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC2_WIDTH                 7  /* AIF1TX3MIX_SRC2 - [6:0] */
+
+/*
+ * R1587 (0x633) - AIF1TX3MIX Input 2 Volume
+ */
+#define WM2200_AIF1TX3MIX_VOL2_MASK             0x00FE  /* AIF1TX3MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL2_SHIFT                 1  /* AIF1TX3MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL2_WIDTH                 7  /* AIF1TX3MIX_VOL2 - [7:1] */
+
+/*
+ * R1588 (0x634) - AIF1TX3MIX Input 3 Source
+ */
+#define WM2200_AIF1TX3MIX_SRC3_MASK             0x007F  /* AIF1TX3MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC3_SHIFT                 0  /* AIF1TX3MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC3_WIDTH                 7  /* AIF1TX3MIX_SRC3 - [6:0] */
+
+/*
+ * R1589 (0x635) - AIF1TX3MIX Input 3 Volume
+ */
+#define WM2200_AIF1TX3MIX_VOL3_MASK             0x00FE  /* AIF1TX3MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL3_SHIFT                 1  /* AIF1TX3MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL3_WIDTH                 7  /* AIF1TX3MIX_VOL3 - [7:1] */
+
+/*
+ * R1590 (0x636) - AIF1TX3MIX Input 4 Source
+ */
+#define WM2200_AIF1TX3MIX_SRC4_MASK             0x007F  /* AIF1TX3MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC4_SHIFT                 0  /* AIF1TX3MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX3MIX_SRC4_WIDTH                 7  /* AIF1TX3MIX_SRC4 - [6:0] */
+
+/*
+ * R1591 (0x637) - AIF1TX3MIX Input 4 Volume
+ */
+#define WM2200_AIF1TX3MIX_VOL4_MASK             0x00FE  /* AIF1TX3MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL4_SHIFT                 1  /* AIF1TX3MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX3MIX_VOL4_WIDTH                 7  /* AIF1TX3MIX_VOL4 - [7:1] */
+
+/*
+ * R1592 (0x638) - AIF1TX4MIX Input 1 Source
+ */
+#define WM2200_AIF1TX4MIX_SRC1_MASK             0x007F  /* AIF1TX4MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC1_SHIFT                 0  /* AIF1TX4MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC1_WIDTH                 7  /* AIF1TX4MIX_SRC1 - [6:0] */
+
+/*
+ * R1593 (0x639) - AIF1TX4MIX Input 1 Volume
+ */
+#define WM2200_AIF1TX4MIX_VOL1_MASK             0x00FE  /* AIF1TX4MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL1_SHIFT                 1  /* AIF1TX4MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL1_WIDTH                 7  /* AIF1TX4MIX_VOL1 - [7:1] */
+
+/*
+ * R1594 (0x63A) - AIF1TX4MIX Input 2 Source
+ */
+#define WM2200_AIF1TX4MIX_SRC2_MASK             0x007F  /* AIF1TX4MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC2_SHIFT                 0  /* AIF1TX4MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC2_WIDTH                 7  /* AIF1TX4MIX_SRC2 - [6:0] */
+
+/*
+ * R1595 (0x63B) - AIF1TX4MIX Input 2 Volume
+ */
+#define WM2200_AIF1TX4MIX_VOL2_MASK             0x00FE  /* AIF1TX4MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL2_SHIFT                 1  /* AIF1TX4MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL2_WIDTH                 7  /* AIF1TX4MIX_VOL2 - [7:1] */
+
+/*
+ * R1596 (0x63C) - AIF1TX4MIX Input 3 Source
+ */
+#define WM2200_AIF1TX4MIX_SRC3_MASK             0x007F  /* AIF1TX4MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC3_SHIFT                 0  /* AIF1TX4MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC3_WIDTH                 7  /* AIF1TX4MIX_SRC3 - [6:0] */
+
+/*
+ * R1597 (0x63D) - AIF1TX4MIX Input 3 Volume
+ */
+#define WM2200_AIF1TX4MIX_VOL3_MASK             0x00FE  /* AIF1TX4MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL3_SHIFT                 1  /* AIF1TX4MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL3_WIDTH                 7  /* AIF1TX4MIX_VOL3 - [7:1] */
+
+/*
+ * R1598 (0x63E) - AIF1TX4MIX Input 4 Source
+ */
+#define WM2200_AIF1TX4MIX_SRC4_MASK             0x007F  /* AIF1TX4MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC4_SHIFT                 0  /* AIF1TX4MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX4MIX_SRC4_WIDTH                 7  /* AIF1TX4MIX_SRC4 - [6:0] */
+
+/*
+ * R1599 (0x63F) - AIF1TX4MIX Input 4 Volume
+ */
+#define WM2200_AIF1TX4MIX_VOL4_MASK             0x00FE  /* AIF1TX4MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL4_SHIFT                 1  /* AIF1TX4MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX4MIX_VOL4_WIDTH                 7  /* AIF1TX4MIX_VOL4 - [7:1] */
+
+/*
+ * R1600 (0x640) - AIF1TX5MIX Input 1 Source
+ */
+#define WM2200_AIF1TX5MIX_SRC1_MASK             0x007F  /* AIF1TX5MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC1_SHIFT                 0  /* AIF1TX5MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC1_WIDTH                 7  /* AIF1TX5MIX_SRC1 - [6:0] */
+
+/*
+ * R1601 (0x641) - AIF1TX5MIX Input 1 Volume
+ */
+#define WM2200_AIF1TX5MIX_VOL1_MASK             0x00FE  /* AIF1TX5MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL1_SHIFT                 1  /* AIF1TX5MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL1_WIDTH                 7  /* AIF1TX5MIX_VOL1 - [7:1] */
+
+/*
+ * R1602 (0x642) - AIF1TX5MIX Input 2 Source
+ */
+#define WM2200_AIF1TX5MIX_SRC2_MASK             0x007F  /* AIF1TX5MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC2_SHIFT                 0  /* AIF1TX5MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC2_WIDTH                 7  /* AIF1TX5MIX_SRC2 - [6:0] */
+
+/*
+ * R1603 (0x643) - AIF1TX5MIX Input 2 Volume
+ */
+#define WM2200_AIF1TX5MIX_VOL2_MASK             0x00FE  /* AIF1TX5MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL2_SHIFT                 1  /* AIF1TX5MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL2_WIDTH                 7  /* AIF1TX5MIX_VOL2 - [7:1] */
+
+/*
+ * R1604 (0x644) - AIF1TX5MIX Input 3 Source
+ */
+#define WM2200_AIF1TX5MIX_SRC3_MASK             0x007F  /* AIF1TX5MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC3_SHIFT                 0  /* AIF1TX5MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC3_WIDTH                 7  /* AIF1TX5MIX_SRC3 - [6:0] */
+
+/*
+ * R1605 (0x645) - AIF1TX5MIX Input 3 Volume
+ */
+#define WM2200_AIF1TX5MIX_VOL3_MASK             0x00FE  /* AIF1TX5MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL3_SHIFT                 1  /* AIF1TX5MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL3_WIDTH                 7  /* AIF1TX5MIX_VOL3 - [7:1] */
+
+/*
+ * R1606 (0x646) - AIF1TX5MIX Input 4 Source
+ */
+#define WM2200_AIF1TX5MIX_SRC4_MASK             0x007F  /* AIF1TX5MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC4_SHIFT                 0  /* AIF1TX5MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX5MIX_SRC4_WIDTH                 7  /* AIF1TX5MIX_SRC4 - [6:0] */
+
+/*
+ * R1607 (0x647) - AIF1TX5MIX Input 4 Volume
+ */
+#define WM2200_AIF1TX5MIX_VOL4_MASK             0x00FE  /* AIF1TX5MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL4_SHIFT                 1  /* AIF1TX5MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX5MIX_VOL4_WIDTH                 7  /* AIF1TX5MIX_VOL4 - [7:1] */
+
+/*
+ * R1608 (0x648) - AIF1TX6MIX Input 1 Source
+ */
+#define WM2200_AIF1TX6MIX_SRC1_MASK             0x007F  /* AIF1TX6MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC1_SHIFT                 0  /* AIF1TX6MIX_SRC1 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC1_WIDTH                 7  /* AIF1TX6MIX_SRC1 - [6:0] */
+
+/*
+ * R1609 (0x649) - AIF1TX6MIX Input 1 Volume
+ */
+#define WM2200_AIF1TX6MIX_VOL1_MASK             0x00FE  /* AIF1TX6MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL1_SHIFT                 1  /* AIF1TX6MIX_VOL1 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL1_WIDTH                 7  /* AIF1TX6MIX_VOL1 - [7:1] */
+
+/*
+ * R1610 (0x64A) - AIF1TX6MIX Input 2 Source
+ */
+#define WM2200_AIF1TX6MIX_SRC2_MASK             0x007F  /* AIF1TX6MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC2_SHIFT                 0  /* AIF1TX6MIX_SRC2 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC2_WIDTH                 7  /* AIF1TX6MIX_SRC2 - [6:0] */
+
+/*
+ * R1611 (0x64B) - AIF1TX6MIX Input 2 Volume
+ */
+#define WM2200_AIF1TX6MIX_VOL2_MASK             0x00FE  /* AIF1TX6MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL2_SHIFT                 1  /* AIF1TX6MIX_VOL2 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL2_WIDTH                 7  /* AIF1TX6MIX_VOL2 - [7:1] */
+
+/*
+ * R1612 (0x64C) - AIF1TX6MIX Input 3 Source
+ */
+#define WM2200_AIF1TX6MIX_SRC3_MASK             0x007F  /* AIF1TX6MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC3_SHIFT                 0  /* AIF1TX6MIX_SRC3 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC3_WIDTH                 7  /* AIF1TX6MIX_SRC3 - [6:0] */
+
+/*
+ * R1613 (0x64D) - AIF1TX6MIX Input 3 Volume
+ */
+#define WM2200_AIF1TX6MIX_VOL3_MASK             0x00FE  /* AIF1TX6MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL3_SHIFT                 1  /* AIF1TX6MIX_VOL3 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL3_WIDTH                 7  /* AIF1TX6MIX_VOL3 - [7:1] */
+
+/*
+ * R1614 (0x64E) - AIF1TX6MIX Input 4 Source
+ */
+#define WM2200_AIF1TX6MIX_SRC4_MASK             0x007F  /* AIF1TX6MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC4_SHIFT                 0  /* AIF1TX6MIX_SRC4 - [6:0] */
+#define WM2200_AIF1TX6MIX_SRC4_WIDTH                 7  /* AIF1TX6MIX_SRC4 - [6:0] */
+
+/*
+ * R1615 (0x64F) - AIF1TX6MIX Input 4 Volume
+ */
+#define WM2200_AIF1TX6MIX_VOL4_MASK             0x00FE  /* AIF1TX6MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL4_SHIFT                 1  /* AIF1TX6MIX_VOL4 - [7:1] */
+#define WM2200_AIF1TX6MIX_VOL4_WIDTH                 7  /* AIF1TX6MIX_VOL4 - [7:1] */
+
+/*
+ * R1616 (0x650) - EQLMIX Input 1 Source
+ */
+#define WM2200_EQLMIX_SRC1_MASK                 0x007F  /* EQLMIX_SRC1 - [6:0] */
+#define WM2200_EQLMIX_SRC1_SHIFT                     0  /* EQLMIX_SRC1 - [6:0] */
+#define WM2200_EQLMIX_SRC1_WIDTH                     7  /* EQLMIX_SRC1 - [6:0] */
+
+/*
+ * R1617 (0x651) - EQLMIX Input 1 Volume
+ */
+#define WM2200_EQLMIX_VOL1_MASK                 0x00FE  /* EQLMIX_VOL1 - [7:1] */
+#define WM2200_EQLMIX_VOL1_SHIFT                     1  /* EQLMIX_VOL1 - [7:1] */
+#define WM2200_EQLMIX_VOL1_WIDTH                     7  /* EQLMIX_VOL1 - [7:1] */
+
+/*
+ * R1618 (0x652) - EQLMIX Input 2 Source
+ */
+#define WM2200_EQLMIX_SRC2_MASK                 0x007F  /* EQLMIX_SRC2 - [6:0] */
+#define WM2200_EQLMIX_SRC2_SHIFT                     0  /* EQLMIX_SRC2 - [6:0] */
+#define WM2200_EQLMIX_SRC2_WIDTH                     7  /* EQLMIX_SRC2 - [6:0] */
+
+/*
+ * R1619 (0x653) - EQLMIX Input 2 Volume
+ */
+#define WM2200_EQLMIX_VOL2_MASK                 0x00FE  /* EQLMIX_VOL2 - [7:1] */
+#define WM2200_EQLMIX_VOL2_SHIFT                     1  /* EQLMIX_VOL2 - [7:1] */
+#define WM2200_EQLMIX_VOL2_WIDTH                     7  /* EQLMIX_VOL2 - [7:1] */
+
+/*
+ * R1620 (0x654) - EQLMIX Input 3 Source
+ */
+#define WM2200_EQLMIX_SRC3_MASK                 0x007F  /* EQLMIX_SRC3 - [6:0] */
+#define WM2200_EQLMIX_SRC3_SHIFT                     0  /* EQLMIX_SRC3 - [6:0] */
+#define WM2200_EQLMIX_SRC3_WIDTH                     7  /* EQLMIX_SRC3 - [6:0] */
+
+/*
+ * R1621 (0x655) - EQLMIX Input 3 Volume
+ */
+#define WM2200_EQLMIX_VOL3_MASK                 0x00FE  /* EQLMIX_VOL3 - [7:1] */
+#define WM2200_EQLMIX_VOL3_SHIFT                     1  /* EQLMIX_VOL3 - [7:1] */
+#define WM2200_EQLMIX_VOL3_WIDTH                     7  /* EQLMIX_VOL3 - [7:1] */
+
+/*
+ * R1622 (0x656) - EQLMIX Input 4 Source
+ */
+#define WM2200_EQLMIX_SRC4_MASK                 0x007F  /* EQLMIX_SRC4 - [6:0] */
+#define WM2200_EQLMIX_SRC4_SHIFT                     0  /* EQLMIX_SRC4 - [6:0] */
+#define WM2200_EQLMIX_SRC4_WIDTH                     7  /* EQLMIX_SRC4 - [6:0] */
+
+/*
+ * R1623 (0x657) - EQLMIX Input 4 Volume
+ */
+#define WM2200_EQLMIX_VOL4_MASK                 0x00FE  /* EQLMIX_VOL4 - [7:1] */
+#define WM2200_EQLMIX_VOL4_SHIFT                     1  /* EQLMIX_VOL4 - [7:1] */
+#define WM2200_EQLMIX_VOL4_WIDTH                     7  /* EQLMIX_VOL4 - [7:1] */
+
+/*
+ * R1624 (0x658) - EQRMIX Input 1 Source
+ */
+#define WM2200_EQRMIX_SRC1_MASK                 0x007F  /* EQRMIX_SRC1 - [6:0] */
+#define WM2200_EQRMIX_SRC1_SHIFT                     0  /* EQRMIX_SRC1 - [6:0] */
+#define WM2200_EQRMIX_SRC1_WIDTH                     7  /* EQRMIX_SRC1 - [6:0] */
+
+/*
+ * R1625 (0x659) - EQRMIX Input 1 Volume
+ */
+#define WM2200_EQRMIX_VOL1_MASK                 0x00FE  /* EQRMIX_VOL1 - [7:1] */
+#define WM2200_EQRMIX_VOL1_SHIFT                     1  /* EQRMIX_VOL1 - [7:1] */
+#define WM2200_EQRMIX_VOL1_WIDTH                     7  /* EQRMIX_VOL1 - [7:1] */
+
+/*
+ * R1626 (0x65A) - EQRMIX Input 2 Source
+ */
+#define WM2200_EQRMIX_SRC2_MASK                 0x007F  /* EQRMIX_SRC2 - [6:0] */
+#define WM2200_EQRMIX_SRC2_SHIFT                     0  /* EQRMIX_SRC2 - [6:0] */
+#define WM2200_EQRMIX_SRC2_WIDTH                     7  /* EQRMIX_SRC2 - [6:0] */
+
+/*
+ * R1627 (0x65B) - EQRMIX Input 2 Volume
+ */
+#define WM2200_EQRMIX_VOL2_MASK                 0x00FE  /* EQRMIX_VOL2 - [7:1] */
+#define WM2200_EQRMIX_VOL2_SHIFT                     1  /* EQRMIX_VOL2 - [7:1] */
+#define WM2200_EQRMIX_VOL2_WIDTH                     7  /* EQRMIX_VOL2 - [7:1] */
+
+/*
+ * R1628 (0x65C) - EQRMIX Input 3 Source
+ */
+#define WM2200_EQRMIX_SRC3_MASK                 0x007F  /* EQRMIX_SRC3 - [6:0] */
+#define WM2200_EQRMIX_SRC3_SHIFT                     0  /* EQRMIX_SRC3 - [6:0] */
+#define WM2200_EQRMIX_SRC3_WIDTH                     7  /* EQRMIX_SRC3 - [6:0] */
+
+/*
+ * R1629 (0x65D) - EQRMIX Input 3 Volume
+ */
+#define WM2200_EQRMIX_VOL3_MASK                 0x00FE  /* EQRMIX_VOL3 - [7:1] */
+#define WM2200_EQRMIX_VOL3_SHIFT                     1  /* EQRMIX_VOL3 - [7:1] */
+#define WM2200_EQRMIX_VOL3_WIDTH                     7  /* EQRMIX_VOL3 - [7:1] */
+
+/*
+ * R1630 (0x65E) - EQRMIX Input 4 Source
+ */
+#define WM2200_EQRMIX_SRC4_MASK                 0x007F  /* EQRMIX_SRC4 - [6:0] */
+#define WM2200_EQRMIX_SRC4_SHIFT                     0  /* EQRMIX_SRC4 - [6:0] */
+#define WM2200_EQRMIX_SRC4_WIDTH                     7  /* EQRMIX_SRC4 - [6:0] */
+
+/*
+ * R1631 (0x65F) - EQRMIX Input 4 Volume
+ */
+#define WM2200_EQRMIX_VOL4_MASK                 0x00FE  /* EQRMIX_VOL4 - [7:1] */
+#define WM2200_EQRMIX_VOL4_SHIFT                     1  /* EQRMIX_VOL4 - [7:1] */
+#define WM2200_EQRMIX_VOL4_WIDTH                     7  /* EQRMIX_VOL4 - [7:1] */
+
+/*
+ * R1632 (0x660) - LHPF1MIX Input 1 Source
+ */
+#define WM2200_LHPF1MIX_SRC1_MASK               0x007F  /* LHPF1MIX_SRC1 - [6:0] */
+#define WM2200_LHPF1MIX_SRC1_SHIFT                   0  /* LHPF1MIX_SRC1 - [6:0] */
+#define WM2200_LHPF1MIX_SRC1_WIDTH                   7  /* LHPF1MIX_SRC1 - [6:0] */
+
+/*
+ * R1633 (0x661) - LHPF1MIX Input 1 Volume
+ */
+#define WM2200_LHPF1MIX_VOL1_MASK               0x00FE  /* LHPF1MIX_VOL1 - [7:1] */
+#define WM2200_LHPF1MIX_VOL1_SHIFT                   1  /* LHPF1MIX_VOL1 - [7:1] */
+#define WM2200_LHPF1MIX_VOL1_WIDTH                   7  /* LHPF1MIX_VOL1 - [7:1] */
+
+/*
+ * R1634 (0x662) - LHPF1MIX Input 2 Source
+ */
+#define WM2200_LHPF1MIX_SRC2_MASK               0x007F  /* LHPF1MIX_SRC2 - [6:0] */
+#define WM2200_LHPF1MIX_SRC2_SHIFT                   0  /* LHPF1MIX_SRC2 - [6:0] */
+#define WM2200_LHPF1MIX_SRC2_WIDTH                   7  /* LHPF1MIX_SRC2 - [6:0] */
+
+/*
+ * R1635 (0x663) - LHPF1MIX Input 2 Volume
+ */
+#define WM2200_LHPF1MIX_VOL2_MASK               0x00FE  /* LHPF1MIX_VOL2 - [7:1] */
+#define WM2200_LHPF1MIX_VOL2_SHIFT                   1  /* LHPF1MIX_VOL2 - [7:1] */
+#define WM2200_LHPF1MIX_VOL2_WIDTH                   7  /* LHPF1MIX_VOL2 - [7:1] */
+
+/*
+ * R1636 (0x664) - LHPF1MIX Input 3 Source
+ */
+#define WM2200_LHPF1MIX_SRC3_MASK               0x007F  /* LHPF1MIX_SRC3 - [6:0] */
+#define WM2200_LHPF1MIX_SRC3_SHIFT                   0  /* LHPF1MIX_SRC3 - [6:0] */
+#define WM2200_LHPF1MIX_SRC3_WIDTH                   7  /* LHPF1MIX_SRC3 - [6:0] */
+
+/*
+ * R1637 (0x665) - LHPF1MIX Input 3 Volume
+ */
+#define WM2200_LHPF1MIX_VOL3_MASK               0x00FE  /* LHPF1MIX_VOL3 - [7:1] */
+#define WM2200_LHPF1MIX_VOL3_SHIFT                   1  /* LHPF1MIX_VOL3 - [7:1] */
+#define WM2200_LHPF1MIX_VOL3_WIDTH                   7  /* LHPF1MIX_VOL3 - [7:1] */
+
+/*
+ * R1638 (0x666) - LHPF1MIX Input 4 Source
+ */
+#define WM2200_LHPF1MIX_SRC4_MASK               0x007F  /* LHPF1MIX_SRC4 - [6:0] */
+#define WM2200_LHPF1MIX_SRC4_SHIFT                   0  /* LHPF1MIX_SRC4 - [6:0] */
+#define WM2200_LHPF1MIX_SRC4_WIDTH                   7  /* LHPF1MIX_SRC4 - [6:0] */
+
+/*
+ * R1639 (0x667) - LHPF1MIX Input 4 Volume
+ */
+#define WM2200_LHPF1MIX_VOL4_MASK               0x00FE  /* LHPF1MIX_VOL4 - [7:1] */
+#define WM2200_LHPF1MIX_VOL4_SHIFT                   1  /* LHPF1MIX_VOL4 - [7:1] */
+#define WM2200_LHPF1MIX_VOL4_WIDTH                   7  /* LHPF1MIX_VOL4 - [7:1] */
+
+/*
+ * R1640 (0x668) - LHPF2MIX Input 1 Source
+ */
+#define WM2200_LHPF2MIX_SRC1_MASK               0x007F  /* LHPF2MIX_SRC1 - [6:0] */
+#define WM2200_LHPF2MIX_SRC1_SHIFT                   0  /* LHPF2MIX_SRC1 - [6:0] */
+#define WM2200_LHPF2MIX_SRC1_WIDTH                   7  /* LHPF2MIX_SRC1 - [6:0] */
+
+/*
+ * R1641 (0x669) - LHPF2MIX Input 1 Volume
+ */
+#define WM2200_LHPF2MIX_VOL1_MASK               0x00FE  /* LHPF2MIX_VOL1 - [7:1] */
+#define WM2200_LHPF2MIX_VOL1_SHIFT                   1  /* LHPF2MIX_VOL1 - [7:1] */
+#define WM2200_LHPF2MIX_VOL1_WIDTH                   7  /* LHPF2MIX_VOL1 - [7:1] */
+
+/*
+ * R1642 (0x66A) - LHPF2MIX Input 2 Source
+ */
+#define WM2200_LHPF2MIX_SRC2_MASK               0x007F  /* LHPF2MIX_SRC2 - [6:0] */
+#define WM2200_LHPF2MIX_SRC2_SHIFT                   0  /* LHPF2MIX_SRC2 - [6:0] */
+#define WM2200_LHPF2MIX_SRC2_WIDTH                   7  /* LHPF2MIX_SRC2 - [6:0] */
+
+/*
+ * R1643 (0x66B) - LHPF2MIX Input 2 Volume
+ */
+#define WM2200_LHPF2MIX_VOL2_MASK               0x00FE  /* LHPF2MIX_VOL2 - [7:1] */
+#define WM2200_LHPF2MIX_VOL2_SHIFT                   1  /* LHPF2MIX_VOL2 - [7:1] */
+#define WM2200_LHPF2MIX_VOL2_WIDTH                   7  /* LHPF2MIX_VOL2 - [7:1] */
+
+/*
+ * R1644 (0x66C) - LHPF2MIX Input 3 Source
+ */
+#define WM2200_LHPF2MIX_SRC3_MASK               0x007F  /* LHPF2MIX_SRC3 - [6:0] */
+#define WM2200_LHPF2MIX_SRC3_SHIFT                   0  /* LHPF2MIX_SRC3 - [6:0] */
+#define WM2200_LHPF2MIX_SRC3_WIDTH                   7  /* LHPF2MIX_SRC3 - [6:0] */
+
+/*
+ * R1645 (0x66D) - LHPF2MIX Input 3 Volume
+ */
+#define WM2200_LHPF2MIX_VOL3_MASK               0x00FE  /* LHPF2MIX_VOL3 - [7:1] */
+#define WM2200_LHPF2MIX_VOL3_SHIFT                   1  /* LHPF2MIX_VOL3 - [7:1] */
+#define WM2200_LHPF2MIX_VOL3_WIDTH                   7  /* LHPF2MIX_VOL3 - [7:1] */
+
+/*
+ * R1646 (0x66E) - LHPF2MIX Input 4 Source
+ */
+#define WM2200_LHPF2MIX_SRC4_MASK               0x007F  /* LHPF2MIX_SRC4 - [6:0] */
+#define WM2200_LHPF2MIX_SRC4_SHIFT                   0  /* LHPF2MIX_SRC4 - [6:0] */
+#define WM2200_LHPF2MIX_SRC4_WIDTH                   7  /* LHPF2MIX_SRC4 - [6:0] */
+
+/*
+ * R1647 (0x66F) - LHPF2MIX Input 4 Volume
+ */
+#define WM2200_LHPF2MIX_VOL4_MASK               0x00FE  /* LHPF2MIX_VOL4 - [7:1] */
+#define WM2200_LHPF2MIX_VOL4_SHIFT                   1  /* LHPF2MIX_VOL4 - [7:1] */
+#define WM2200_LHPF2MIX_VOL4_WIDTH                   7  /* LHPF2MIX_VOL4 - [7:1] */
+
+/*
+ * R1648 (0x670) - DSP1LMIX Input 1 Source
+ */
+#define WM2200_DSP1LMIX_SRC1_MASK               0x007F  /* DSP1LMIX_SRC1 - [6:0] */
+#define WM2200_DSP1LMIX_SRC1_SHIFT                   0  /* DSP1LMIX_SRC1 - [6:0] */
+#define WM2200_DSP1LMIX_SRC1_WIDTH                   7  /* DSP1LMIX_SRC1 - [6:0] */
+
+/*
+ * R1649 (0x671) - DSP1LMIX Input 1 Volume
+ */
+#define WM2200_DSP1LMIX_VOL1_MASK               0x00FE  /* DSP1LMIX_VOL1 - [7:1] */
+#define WM2200_DSP1LMIX_VOL1_SHIFT                   1  /* DSP1LMIX_VOL1 - [7:1] */
+#define WM2200_DSP1LMIX_VOL1_WIDTH                   7  /* DSP1LMIX_VOL1 - [7:1] */
+
+/*
+ * R1650 (0x672) - DSP1LMIX Input 2 Source
+ */
+#define WM2200_DSP1LMIX_SRC2_MASK               0x007F  /* DSP1LMIX_SRC2 - [6:0] */
+#define WM2200_DSP1LMIX_SRC2_SHIFT                   0  /* DSP1LMIX_SRC2 - [6:0] */
+#define WM2200_DSP1LMIX_SRC2_WIDTH                   7  /* DSP1LMIX_SRC2 - [6:0] */
+
+/*
+ * R1651 (0x673) - DSP1LMIX Input 2 Volume
+ */
+#define WM2200_DSP1LMIX_VOL2_MASK               0x00FE  /* DSP1LMIX_VOL2 - [7:1] */
+#define WM2200_DSP1LMIX_VOL2_SHIFT                   1  /* DSP1LMIX_VOL2 - [7:1] */
+#define WM2200_DSP1LMIX_VOL2_WIDTH                   7  /* DSP1LMIX_VOL2 - [7:1] */
+
+/*
+ * R1652 (0x674) - DSP1LMIX Input 3 Source
+ */
+#define WM2200_DSP1LMIX_SRC3_MASK               0x007F  /* DSP1LMIX_SRC3 - [6:0] */
+#define WM2200_DSP1LMIX_SRC3_SHIFT                   0  /* DSP1LMIX_SRC3 - [6:0] */
+#define WM2200_DSP1LMIX_SRC3_WIDTH                   7  /* DSP1LMIX_SRC3 - [6:0] */
+
+/*
+ * R1653 (0x675) - DSP1LMIX Input 3 Volume
+ */
+#define WM2200_DSP1LMIX_VOL3_MASK               0x00FE  /* DSP1LMIX_VOL3 - [7:1] */
+#define WM2200_DSP1LMIX_VOL3_SHIFT                   1  /* DSP1LMIX_VOL3 - [7:1] */
+#define WM2200_DSP1LMIX_VOL3_WIDTH                   7  /* DSP1LMIX_VOL3 - [7:1] */
+
+/*
+ * R1654 (0x676) - DSP1LMIX Input 4 Source
+ */
+#define WM2200_DSP1LMIX_SRC4_MASK               0x007F  /* DSP1LMIX_SRC4 - [6:0] */
+#define WM2200_DSP1LMIX_SRC4_SHIFT                   0  /* DSP1LMIX_SRC4 - [6:0] */
+#define WM2200_DSP1LMIX_SRC4_WIDTH                   7  /* DSP1LMIX_SRC4 - [6:0] */
+
+/*
+ * R1655 (0x677) - DSP1LMIX Input 4 Volume
+ */
+#define WM2200_DSP1LMIX_VOL4_MASK               0x00FE  /* DSP1LMIX_VOL4 - [7:1] */
+#define WM2200_DSP1LMIX_VOL4_SHIFT                   1  /* DSP1LMIX_VOL4 - [7:1] */
+#define WM2200_DSP1LMIX_VOL4_WIDTH                   7  /* DSP1LMIX_VOL4 - [7:1] */
+
+/*
+ * R1656 (0x678) - DSP1RMIX Input 1 Source
+ */
+#define WM2200_DSP1RMIX_SRC1_MASK               0x007F  /* DSP1RMIX_SRC1 - [6:0] */
+#define WM2200_DSP1RMIX_SRC1_SHIFT                   0  /* DSP1RMIX_SRC1 - [6:0] */
+#define WM2200_DSP1RMIX_SRC1_WIDTH                   7  /* DSP1RMIX_SRC1 - [6:0] */
+
+/*
+ * R1657 (0x679) - DSP1RMIX Input 1 Volume
+ */
+#define WM2200_DSP1RMIX_VOL1_MASK               0x00FE  /* DSP1RMIX_VOL1 - [7:1] */
+#define WM2200_DSP1RMIX_VOL1_SHIFT                   1  /* DSP1RMIX_VOL1 - [7:1] */
+#define WM2200_DSP1RMIX_VOL1_WIDTH                   7  /* DSP1RMIX_VOL1 - [7:1] */
+
+/*
+ * R1658 (0x67A) - DSP1RMIX Input 2 Source
+ */
+#define WM2200_DSP1RMIX_SRC2_MASK               0x007F  /* DSP1RMIX_SRC2 - [6:0] */
+#define WM2200_DSP1RMIX_SRC2_SHIFT                   0  /* DSP1RMIX_SRC2 - [6:0] */
+#define WM2200_DSP1RMIX_SRC2_WIDTH                   7  /* DSP1RMIX_SRC2 - [6:0] */
+
+/*
+ * R1659 (0x67B) - DSP1RMIX Input 2 Volume
+ */
+#define WM2200_DSP1RMIX_VOL2_MASK               0x00FE  /* DSP1RMIX_VOL2 - [7:1] */
+#define WM2200_DSP1RMIX_VOL2_SHIFT                   1  /* DSP1RMIX_VOL2 - [7:1] */
+#define WM2200_DSP1RMIX_VOL2_WIDTH                   7  /* DSP1RMIX_VOL2 - [7:1] */
+
+/*
+ * R1660 (0x67C) - DSP1RMIX Input 3 Source
+ */
+#define WM2200_DSP1RMIX_SRC3_MASK               0x007F  /* DSP1RMIX_SRC3 - [6:0] */
+#define WM2200_DSP1RMIX_SRC3_SHIFT                   0  /* DSP1RMIX_SRC3 - [6:0] */
+#define WM2200_DSP1RMIX_SRC3_WIDTH                   7  /* DSP1RMIX_SRC3 - [6:0] */
+
+/*
+ * R1661 (0x67D) - DSP1RMIX Input 3 Volume
+ */
+#define WM2200_DSP1RMIX_VOL3_MASK               0x00FE  /* DSP1RMIX_VOL3 - [7:1] */
+#define WM2200_DSP1RMIX_VOL3_SHIFT                   1  /* DSP1RMIX_VOL3 - [7:1] */
+#define WM2200_DSP1RMIX_VOL3_WIDTH                   7  /* DSP1RMIX_VOL3 - [7:1] */
+
+/*
+ * R1662 (0x67E) - DSP1RMIX Input 4 Source
+ */
+#define WM2200_DSP1RMIX_SRC4_MASK               0x007F  /* DSP1RMIX_SRC4 - [6:0] */
+#define WM2200_DSP1RMIX_SRC4_SHIFT                   0  /* DSP1RMIX_SRC4 - [6:0] */
+#define WM2200_DSP1RMIX_SRC4_WIDTH                   7  /* DSP1RMIX_SRC4 - [6:0] */
+
+/*
+ * R1663 (0x67F) - DSP1RMIX Input 4 Volume
+ */
+#define WM2200_DSP1RMIX_VOL4_MASK               0x00FE  /* DSP1RMIX_VOL4 - [7:1] */
+#define WM2200_DSP1RMIX_VOL4_SHIFT                   1  /* DSP1RMIX_VOL4 - [7:1] */
+#define WM2200_DSP1RMIX_VOL4_WIDTH                   7  /* DSP1RMIX_VOL4 - [7:1] */
+
+/*
+ * R1664 (0x680) - DSP1AUX1MIX Input 1 Source
+ */
+#define WM2200_DSP1AUX1MIX_SRC1_MASK            0x007F  /* DSP1AUX1MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX1MIX_SRC1_SHIFT                0  /* DSP1AUX1MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX1MIX_SRC1_WIDTH                7  /* DSP1AUX1MIX_SRC1 - [6:0] */
+
+/*
+ * R1665 (0x681) - DSP1AUX2MIX Input 1 Source
+ */
+#define WM2200_DSP1AUX2MIX_SRC1_MASK            0x007F  /* DSP1AUX2MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX2MIX_SRC1_SHIFT                0  /* DSP1AUX2MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX2MIX_SRC1_WIDTH                7  /* DSP1AUX2MIX_SRC1 - [6:0] */
+
+/*
+ * R1666 (0x682) - DSP1AUX3MIX Input 1 Source
+ */
+#define WM2200_DSP1AUX3MIX_SRC1_MASK            0x007F  /* DSP1AUX3MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX3MIX_SRC1_SHIFT                0  /* DSP1AUX3MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX3MIX_SRC1_WIDTH                7  /* DSP1AUX3MIX_SRC1 - [6:0] */
+
+/*
+ * R1667 (0x683) - DSP1AUX4MIX Input 1 Source
+ */
+#define WM2200_DSP1AUX4MIX_SRC1_MASK            0x007F  /* DSP1AUX4MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX4MIX_SRC1_SHIFT                0  /* DSP1AUX4MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX4MIX_SRC1_WIDTH                7  /* DSP1AUX4MIX_SRC1 - [6:0] */
+
+/*
+ * R1668 (0x684) - DSP1AUX5MIX Input 1 Source
+ */
+#define WM2200_DSP1AUX5MIX_SRC1_MASK            0x007F  /* DSP1AUX5MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX5MIX_SRC1_SHIFT                0  /* DSP1AUX5MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX5MIX_SRC1_WIDTH                7  /* DSP1AUX5MIX_SRC1 - [6:0] */
+
+/*
+ * R1669 (0x685) - DSP1AUX6MIX Input 1 Source
+ */
+#define WM2200_DSP1AUX6MIX_SRC1_MASK            0x007F  /* DSP1AUX6MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX6MIX_SRC1_SHIFT                0  /* DSP1AUX6MIX_SRC1 - [6:0] */
+#define WM2200_DSP1AUX6MIX_SRC1_WIDTH                7  /* DSP1AUX6MIX_SRC1 - [6:0] */
+
+/*
+ * R1670 (0x686) - DSP2LMIX Input 1 Source
+ */
+#define WM2200_DSP2LMIX_SRC1_MASK               0x007F  /* DSP2LMIX_SRC1 - [6:0] */
+#define WM2200_DSP2LMIX_SRC1_SHIFT                   0  /* DSP2LMIX_SRC1 - [6:0] */
+#define WM2200_DSP2LMIX_SRC1_WIDTH                   7  /* DSP2LMIX_SRC1 - [6:0] */
+
+/*
+ * R1671 (0x687) - DSP2LMIX Input 1 Volume
+ */
+#define WM2200_DSP2LMIX_VOL1_MASK               0x00FE  /* DSP2LMIX_VOL1 - [7:1] */
+#define WM2200_DSP2LMIX_VOL1_SHIFT                   1  /* DSP2LMIX_VOL1 - [7:1] */
+#define WM2200_DSP2LMIX_VOL1_WIDTH                   7  /* DSP2LMIX_VOL1 - [7:1] */
+
+/*
+ * R1672 (0x688) - DSP2LMIX Input 2 Source
+ */
+#define WM2200_DSP2LMIX_SRC2_MASK               0x007F  /* DSP2LMIX_SRC2 - [6:0] */
+#define WM2200_DSP2LMIX_SRC2_SHIFT                   0  /* DSP2LMIX_SRC2 - [6:0] */
+#define WM2200_DSP2LMIX_SRC2_WIDTH                   7  /* DSP2LMIX_SRC2 - [6:0] */
+
+/*
+ * R1673 (0x689) - DSP2LMIX Input 2 Volume
+ */
+#define WM2200_DSP2LMIX_VOL2_MASK               0x00FE  /* DSP2LMIX_VOL2 - [7:1] */
+#define WM2200_DSP2LMIX_VOL2_SHIFT                   1  /* DSP2LMIX_VOL2 - [7:1] */
+#define WM2200_DSP2LMIX_VOL2_WIDTH                   7  /* DSP2LMIX_VOL2 - [7:1] */
+
+/*
+ * R1674 (0x68A) - DSP2LMIX Input 3 Source
+ */
+#define WM2200_DSP2LMIX_SRC3_MASK               0x007F  /* DSP2LMIX_SRC3 - [6:0] */
+#define WM2200_DSP2LMIX_SRC3_SHIFT                   0  /* DSP2LMIX_SRC3 - [6:0] */
+#define WM2200_DSP2LMIX_SRC3_WIDTH                   7  /* DSP2LMIX_SRC3 - [6:0] */
+
+/*
+ * R1675 (0x68B) - DSP2LMIX Input 3 Volume
+ */
+#define WM2200_DSP2LMIX_VOL3_MASK               0x00FE  /* DSP2LMIX_VOL3 - [7:1] */
+#define WM2200_DSP2LMIX_VOL3_SHIFT                   1  /* DSP2LMIX_VOL3 - [7:1] */
+#define WM2200_DSP2LMIX_VOL3_WIDTH                   7  /* DSP2LMIX_VOL3 - [7:1] */
+
+/*
+ * R1676 (0x68C) - DSP2LMIX Input 4 Source
+ */
+#define WM2200_DSP2LMIX_SRC4_MASK               0x007F  /* DSP2LMIX_SRC4 - [6:0] */
+#define WM2200_DSP2LMIX_SRC4_SHIFT                   0  /* DSP2LMIX_SRC4 - [6:0] */
+#define WM2200_DSP2LMIX_SRC4_WIDTH                   7  /* DSP2LMIX_SRC4 - [6:0] */
+
+/*
+ * R1677 (0x68D) - DSP2LMIX Input 4 Volume
+ */
+#define WM2200_DSP2LMIX_VOL4_MASK               0x00FE  /* DSP2LMIX_VOL4 - [7:1] */
+#define WM2200_DSP2LMIX_VOL4_SHIFT                   1  /* DSP2LMIX_VOL4 - [7:1] */
+#define WM2200_DSP2LMIX_VOL4_WIDTH                   7  /* DSP2LMIX_VOL4 - [7:1] */
+
+/*
+ * R1678 (0x68E) - DSP2RMIX Input 1 Source
+ */
+#define WM2200_DSP2RMIX_SRC1_MASK               0x007F  /* DSP2RMIX_SRC1 - [6:0] */
+#define WM2200_DSP2RMIX_SRC1_SHIFT                   0  /* DSP2RMIX_SRC1 - [6:0] */
+#define WM2200_DSP2RMIX_SRC1_WIDTH                   7  /* DSP2RMIX_SRC1 - [6:0] */
+
+/*
+ * R1679 (0x68F) - DSP2RMIX Input 1 Volume
+ */
+#define WM2200_DSP2RMIX_VOL1_MASK               0x00FE  /* DSP2RMIX_VOL1 - [7:1] */
+#define WM2200_DSP2RMIX_VOL1_SHIFT                   1  /* DSP2RMIX_VOL1 - [7:1] */
+#define WM2200_DSP2RMIX_VOL1_WIDTH                   7  /* DSP2RMIX_VOL1 - [7:1] */
+
+/*
+ * R1680 (0x690) - DSP2RMIX Input 2 Source
+ */
+#define WM2200_DSP2RMIX_SRC2_MASK               0x007F  /* DSP2RMIX_SRC2 - [6:0] */
+#define WM2200_DSP2RMIX_SRC2_SHIFT                   0  /* DSP2RMIX_SRC2 - [6:0] */
+#define WM2200_DSP2RMIX_SRC2_WIDTH                   7  /* DSP2RMIX_SRC2 - [6:0] */
+
+/*
+ * R1681 (0x691) - DSP2RMIX Input 2 Volume
+ */
+#define WM2200_DSP2RMIX_VOL2_MASK               0x00FE  /* DSP2RMIX_VOL2 - [7:1] */
+#define WM2200_DSP2RMIX_VOL2_SHIFT                   1  /* DSP2RMIX_VOL2 - [7:1] */
+#define WM2200_DSP2RMIX_VOL2_WIDTH                   7  /* DSP2RMIX_VOL2 - [7:1] */
+
+/*
+ * R1682 (0x692) - DSP2RMIX Input 3 Source
+ */
+#define WM2200_DSP2RMIX_SRC3_MASK               0x007F  /* DSP2RMIX_SRC3 - [6:0] */
+#define WM2200_DSP2RMIX_SRC3_SHIFT                   0  /* DSP2RMIX_SRC3 - [6:0] */
+#define WM2200_DSP2RMIX_SRC3_WIDTH                   7  /* DSP2RMIX_SRC3 - [6:0] */
+
+/*
+ * R1683 (0x693) - DSP2RMIX Input 3 Volume
+ */
+#define WM2200_DSP2RMIX_VOL3_MASK               0x00FE  /* DSP2RMIX_VOL3 - [7:1] */
+#define WM2200_DSP2RMIX_VOL3_SHIFT                   1  /* DSP2RMIX_VOL3 - [7:1] */
+#define WM2200_DSP2RMIX_VOL3_WIDTH                   7  /* DSP2RMIX_VOL3 - [7:1] */
+
+/*
+ * R1684 (0x694) - DSP2RMIX Input 4 Source
+ */
+#define WM2200_DSP2RMIX_SRC4_MASK               0x007F  /* DSP2RMIX_SRC4 - [6:0] */
+#define WM2200_DSP2RMIX_SRC4_SHIFT                   0  /* DSP2RMIX_SRC4 - [6:0] */
+#define WM2200_DSP2RMIX_SRC4_WIDTH                   7  /* DSP2RMIX_SRC4 - [6:0] */
+
+/*
+ * R1685 (0x695) - DSP2RMIX Input 4 Volume
+ */
+#define WM2200_DSP2RMIX_VOL4_MASK               0x00FE  /* DSP2RMIX_VOL4 - [7:1] */
+#define WM2200_DSP2RMIX_VOL4_SHIFT                   1  /* DSP2RMIX_VOL4 - [7:1] */
+#define WM2200_DSP2RMIX_VOL4_WIDTH                   7  /* DSP2RMIX_VOL4 - [7:1] */
+
+/*
+ * R1686 (0x696) - DSP2AUX1MIX Input 1 Source
+ */
+#define WM2200_DSP2AUX1MIX_SRC1_MASK            0x007F  /* DSP2AUX1MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX1MIX_SRC1_SHIFT                0  /* DSP2AUX1MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX1MIX_SRC1_WIDTH                7  /* DSP2AUX1MIX_SRC1 - [6:0] */
+
+/*
+ * R1687 (0x697) - DSP2AUX2MIX Input 1 Source
+ */
+#define WM2200_DSP2AUX2MIX_SRC1_MASK            0x007F  /* DSP2AUX2MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX2MIX_SRC1_SHIFT                0  /* DSP2AUX2MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX2MIX_SRC1_WIDTH                7  /* DSP2AUX2MIX_SRC1 - [6:0] */
+
+/*
+ * R1688 (0x698) - DSP2AUX3MIX Input 1 Source
+ */
+#define WM2200_DSP2AUX3MIX_SRC1_MASK            0x007F  /* DSP2AUX3MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX3MIX_SRC1_SHIFT                0  /* DSP2AUX3MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX3MIX_SRC1_WIDTH                7  /* DSP2AUX3MIX_SRC1 - [6:0] */
+
+/*
+ * R1689 (0x699) - DSP2AUX4MIX Input 1 Source
+ */
+#define WM2200_DSP2AUX4MIX_SRC1_MASK            0x007F  /* DSP2AUX4MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX4MIX_SRC1_SHIFT                0  /* DSP2AUX4MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX4MIX_SRC1_WIDTH                7  /* DSP2AUX4MIX_SRC1 - [6:0] */
+
+/*
+ * R1690 (0x69A) - DSP2AUX5MIX Input 1 Source
+ */
+#define WM2200_DSP2AUX5MIX_SRC1_MASK            0x007F  /* DSP2AUX5MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX5MIX_SRC1_SHIFT                0  /* DSP2AUX5MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX5MIX_SRC1_WIDTH                7  /* DSP2AUX5MIX_SRC1 - [6:0] */
+
+/*
+ * R1691 (0x69B) - DSP2AUX6MIX Input 1 Source
+ */
+#define WM2200_DSP2AUX6MIX_SRC1_MASK            0x007F  /* DSP2AUX6MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX6MIX_SRC1_SHIFT                0  /* DSP2AUX6MIX_SRC1 - [6:0] */
+#define WM2200_DSP2AUX6MIX_SRC1_WIDTH                7  /* DSP2AUX6MIX_SRC1 - [6:0] */
+
+/*
+ * R1792 (0x700) - GPIO CTRL 1
+ */
+#define WM2200_GP1_DIR                          0x8000  /* GP1_DIR */
+#define WM2200_GP1_DIR_MASK                     0x8000  /* GP1_DIR */
+#define WM2200_GP1_DIR_SHIFT                        15  /* GP1_DIR */
+#define WM2200_GP1_DIR_WIDTH                         1  /* GP1_DIR */
+#define WM2200_GP1_PU                           0x4000  /* GP1_PU */
+#define WM2200_GP1_PU_MASK                      0x4000  /* GP1_PU */
+#define WM2200_GP1_PU_SHIFT                         14  /* GP1_PU */
+#define WM2200_GP1_PU_WIDTH                          1  /* GP1_PU */
+#define WM2200_GP1_PD                           0x2000  /* GP1_PD */
+#define WM2200_GP1_PD_MASK                      0x2000  /* GP1_PD */
+#define WM2200_GP1_PD_SHIFT                         13  /* GP1_PD */
+#define WM2200_GP1_PD_WIDTH                          1  /* GP1_PD */
+#define WM2200_GP1_POL                          0x0400  /* GP1_POL */
+#define WM2200_GP1_POL_MASK                     0x0400  /* GP1_POL */
+#define WM2200_GP1_POL_SHIFT                        10  /* GP1_POL */
+#define WM2200_GP1_POL_WIDTH                         1  /* GP1_POL */
+#define WM2200_GP1_OP_CFG                       0x0200  /* GP1_OP_CFG */
+#define WM2200_GP1_OP_CFG_MASK                  0x0200  /* GP1_OP_CFG */
+#define WM2200_GP1_OP_CFG_SHIFT                      9  /* GP1_OP_CFG */
+#define WM2200_GP1_OP_CFG_WIDTH                      1  /* GP1_OP_CFG */
+#define WM2200_GP1_DB                           0x0100  /* GP1_DB */
+#define WM2200_GP1_DB_MASK                      0x0100  /* GP1_DB */
+#define WM2200_GP1_DB_SHIFT                          8  /* GP1_DB */
+#define WM2200_GP1_DB_WIDTH                          1  /* GP1_DB */
+#define WM2200_GP1_LVL                          0x0040  /* GP1_LVL */
+#define WM2200_GP1_LVL_MASK                     0x0040  /* GP1_LVL */
+#define WM2200_GP1_LVL_SHIFT                         6  /* GP1_LVL */
+#define WM2200_GP1_LVL_WIDTH                         1  /* GP1_LVL */
+#define WM2200_GP1_FN_MASK                      0x003F  /* GP1_FN - [5:0] */
+#define WM2200_GP1_FN_SHIFT                          0  /* GP1_FN - [5:0] */
+#define WM2200_GP1_FN_WIDTH                          6  /* GP1_FN - [5:0] */
+
+/*
+ * R1793 (0x701) - GPIO CTRL 2
+ */
+#define WM2200_GP2_DIR                          0x8000  /* GP2_DIR */
+#define WM2200_GP2_DIR_MASK                     0x8000  /* GP2_DIR */
+#define WM2200_GP2_DIR_SHIFT                        15  /* GP2_DIR */
+#define WM2200_GP2_DIR_WIDTH                         1  /* GP2_DIR */
+#define WM2200_GP2_PU                           0x4000  /* GP2_PU */
+#define WM2200_GP2_PU_MASK                      0x4000  /* GP2_PU */
+#define WM2200_GP2_PU_SHIFT                         14  /* GP2_PU */
+#define WM2200_GP2_PU_WIDTH                          1  /* GP2_PU */
+#define WM2200_GP2_PD                           0x2000  /* GP2_PD */
+#define WM2200_GP2_PD_MASK                      0x2000  /* GP2_PD */
+#define WM2200_GP2_PD_SHIFT                         13  /* GP2_PD */
+#define WM2200_GP2_PD_WIDTH                          1  /* GP2_PD */
+#define WM2200_GP2_POL                          0x0400  /* GP2_POL */
+#define WM2200_GP2_POL_MASK                     0x0400  /* GP2_POL */
+#define WM2200_GP2_POL_SHIFT                        10  /* GP2_POL */
+#define WM2200_GP2_POL_WIDTH                         1  /* GP2_POL */
+#define WM2200_GP2_OP_CFG                       0x0200  /* GP2_OP_CFG */
+#define WM2200_GP2_OP_CFG_MASK                  0x0200  /* GP2_OP_CFG */
+#define WM2200_GP2_OP_CFG_SHIFT                      9  /* GP2_OP_CFG */
+#define WM2200_GP2_OP_CFG_WIDTH                      1  /* GP2_OP_CFG */
+#define WM2200_GP2_DB                           0x0100  /* GP2_DB */
+#define WM2200_GP2_DB_MASK                      0x0100  /* GP2_DB */
+#define WM2200_GP2_DB_SHIFT                          8  /* GP2_DB */
+#define WM2200_GP2_DB_WIDTH                          1  /* GP2_DB */
+#define WM2200_GP2_LVL                          0x0040  /* GP2_LVL */
+#define WM2200_GP2_LVL_MASK                     0x0040  /* GP2_LVL */
+#define WM2200_GP2_LVL_SHIFT                         6  /* GP2_LVL */
+#define WM2200_GP2_LVL_WIDTH                         1  /* GP2_LVL */
+#define WM2200_GP2_FN_MASK                      0x003F  /* GP2_FN - [5:0] */
+#define WM2200_GP2_FN_SHIFT                          0  /* GP2_FN - [5:0] */
+#define WM2200_GP2_FN_WIDTH                          6  /* GP2_FN - [5:0] */
+
+/*
+ * R1794 (0x702) - GPIO CTRL 3
+ */
+#define WM2200_GP3_DIR                          0x8000  /* GP3_DIR */
+#define WM2200_GP3_DIR_MASK                     0x8000  /* GP3_DIR */
+#define WM2200_GP3_DIR_SHIFT                        15  /* GP3_DIR */
+#define WM2200_GP3_DIR_WIDTH                         1  /* GP3_DIR */
+#define WM2200_GP3_PU                           0x4000  /* GP3_PU */
+#define WM2200_GP3_PU_MASK                      0x4000  /* GP3_PU */
+#define WM2200_GP3_PU_SHIFT                         14  /* GP3_PU */
+#define WM2200_GP3_PU_WIDTH                          1  /* GP3_PU */
+#define WM2200_GP3_PD                           0x2000  /* GP3_PD */
+#define WM2200_GP3_PD_MASK                      0x2000  /* GP3_PD */
+#define WM2200_GP3_PD_SHIFT                         13  /* GP3_PD */
+#define WM2200_GP3_PD_WIDTH                          1  /* GP3_PD */
+#define WM2200_GP3_POL                          0x0400  /* GP3_POL */
+#define WM2200_GP3_POL_MASK                     0x0400  /* GP3_POL */
+#define WM2200_GP3_POL_SHIFT                        10  /* GP3_POL */
+#define WM2200_GP3_POL_WIDTH                         1  /* GP3_POL */
+#define WM2200_GP3_OP_CFG                       0x0200  /* GP3_OP_CFG */
+#define WM2200_GP3_OP_CFG_MASK                  0x0200  /* GP3_OP_CFG */
+#define WM2200_GP3_OP_CFG_SHIFT                      9  /* GP3_OP_CFG */
+#define WM2200_GP3_OP_CFG_WIDTH                      1  /* GP3_OP_CFG */
+#define WM2200_GP3_DB                           0x0100  /* GP3_DB */
+#define WM2200_GP3_DB_MASK                      0x0100  /* GP3_DB */
+#define WM2200_GP3_DB_SHIFT                          8  /* GP3_DB */
+#define WM2200_GP3_DB_WIDTH                          1  /* GP3_DB */
+#define WM2200_GP3_LVL                          0x0040  /* GP3_LVL */
+#define WM2200_GP3_LVL_MASK                     0x0040  /* GP3_LVL */
+#define WM2200_GP3_LVL_SHIFT                         6  /* GP3_LVL */
+#define WM2200_GP3_LVL_WIDTH                         1  /* GP3_LVL */
+#define WM2200_GP3_FN_MASK                      0x003F  /* GP3_FN - [5:0] */
+#define WM2200_GP3_FN_SHIFT                          0  /* GP3_FN - [5:0] */
+#define WM2200_GP3_FN_WIDTH                          6  /* GP3_FN - [5:0] */
+
+/*
+ * R1795 (0x703) - GPIO CTRL 4
+ */
+#define WM2200_GP4_DIR                          0x8000  /* GP4_DIR */
+#define WM2200_GP4_DIR_MASK                     0x8000  /* GP4_DIR */
+#define WM2200_GP4_DIR_SHIFT                        15  /* GP4_DIR */
+#define WM2200_GP4_DIR_WIDTH                         1  /* GP4_DIR */
+#define WM2200_GP4_PU                           0x4000  /* GP4_PU */
+#define WM2200_GP4_PU_MASK                      0x4000  /* GP4_PU */
+#define WM2200_GP4_PU_SHIFT                         14  /* GP4_PU */
+#define WM2200_GP4_PU_WIDTH                          1  /* GP4_PU */
+#define WM2200_GP4_PD                           0x2000  /* GP4_PD */
+#define WM2200_GP4_PD_MASK                      0x2000  /* GP4_PD */
+#define WM2200_GP4_PD_SHIFT                         13  /* GP4_PD */
+#define WM2200_GP4_PD_WIDTH                          1  /* GP4_PD */
+#define WM2200_GP4_POL                          0x0400  /* GP4_POL */
+#define WM2200_GP4_POL_MASK                     0x0400  /* GP4_POL */
+#define WM2200_GP4_POL_SHIFT                        10  /* GP4_POL */
+#define WM2200_GP4_POL_WIDTH                         1  /* GP4_POL */
+#define WM2200_GP4_OP_CFG                       0x0200  /* GP4_OP_CFG */
+#define WM2200_GP4_OP_CFG_MASK                  0x0200  /* GP4_OP_CFG */
+#define WM2200_GP4_OP_CFG_SHIFT                      9  /* GP4_OP_CFG */
+#define WM2200_GP4_OP_CFG_WIDTH                      1  /* GP4_OP_CFG */
+#define WM2200_GP4_DB                           0x0100  /* GP4_DB */
+#define WM2200_GP4_DB_MASK                      0x0100  /* GP4_DB */
+#define WM2200_GP4_DB_SHIFT                          8  /* GP4_DB */
+#define WM2200_GP4_DB_WIDTH                          1  /* GP4_DB */
+#define WM2200_GP4_LVL                          0x0040  /* GP4_LVL */
+#define WM2200_GP4_LVL_MASK                     0x0040  /* GP4_LVL */
+#define WM2200_GP4_LVL_SHIFT                         6  /* GP4_LVL */
+#define WM2200_GP4_LVL_WIDTH                         1  /* GP4_LVL */
+#define WM2200_GP4_FN_MASK                      0x003F  /* GP4_FN - [5:0] */
+#define WM2200_GP4_FN_SHIFT                          0  /* GP4_FN - [5:0] */
+#define WM2200_GP4_FN_WIDTH                          6  /* GP4_FN - [5:0] */
+
+/*
+ * R1799 (0x707) - ADPS1 IRQ0
+ */
+#define WM2200_DSP_IRQ1                         0x0002  /* DSP_IRQ1 */
+#define WM2200_DSP_IRQ1_MASK                    0x0002  /* DSP_IRQ1 */
+#define WM2200_DSP_IRQ1_SHIFT                        1  /* DSP_IRQ1 */
+#define WM2200_DSP_IRQ1_WIDTH                        1  /* DSP_IRQ1 */
+#define WM2200_DSP_IRQ0                         0x0001  /* DSP_IRQ0 */
+#define WM2200_DSP_IRQ0_MASK                    0x0001  /* DSP_IRQ0 */
+#define WM2200_DSP_IRQ0_SHIFT                        0  /* DSP_IRQ0 */
+#define WM2200_DSP_IRQ0_WIDTH                        1  /* DSP_IRQ0 */
+
+/*
+ * R1800 (0x708) - ADPS1 IRQ1
+ */
+#define WM2200_DSP_IRQ3                         0x0002  /* DSP_IRQ3 */
+#define WM2200_DSP_IRQ3_MASK                    0x0002  /* DSP_IRQ3 */
+#define WM2200_DSP_IRQ3_SHIFT                        1  /* DSP_IRQ3 */
+#define WM2200_DSP_IRQ3_WIDTH                        1  /* DSP_IRQ3 */
+#define WM2200_DSP_IRQ2                         0x0001  /* DSP_IRQ2 */
+#define WM2200_DSP_IRQ2_MASK                    0x0001  /* DSP_IRQ2 */
+#define WM2200_DSP_IRQ2_SHIFT                        0  /* DSP_IRQ2 */
+#define WM2200_DSP_IRQ2_WIDTH                        1  /* DSP_IRQ2 */
+
+/*
+ * R1801 (0x709) - Misc Pad Ctrl 1
+ */
+#define WM2200_LDO1ENA_PD                       0x8000  /* LDO1ENA_PD */
+#define WM2200_LDO1ENA_PD_MASK                  0x8000  /* LDO1ENA_PD */
+#define WM2200_LDO1ENA_PD_SHIFT                     15  /* LDO1ENA_PD */
+#define WM2200_LDO1ENA_PD_WIDTH                      1  /* LDO1ENA_PD */
+#define WM2200_MCLK2_PD                         0x2000  /* MCLK2_PD */
+#define WM2200_MCLK2_PD_MASK                    0x2000  /* MCLK2_PD */
+#define WM2200_MCLK2_PD_SHIFT                       13  /* MCLK2_PD */
+#define WM2200_MCLK2_PD_WIDTH                        1  /* MCLK2_PD */
+#define WM2200_MCLK1_PD                         0x1000  /* MCLK1_PD */
+#define WM2200_MCLK1_PD_MASK                    0x1000  /* MCLK1_PD */
+#define WM2200_MCLK1_PD_SHIFT                       12  /* MCLK1_PD */
+#define WM2200_MCLK1_PD_WIDTH                        1  /* MCLK1_PD */
+#define WM2200_DACLRCLK1_PU                     0x0400  /* DACLRCLK1_PU */
+#define WM2200_DACLRCLK1_PU_MASK                0x0400  /* DACLRCLK1_PU */
+#define WM2200_DACLRCLK1_PU_SHIFT                   10  /* DACLRCLK1_PU */
+#define WM2200_DACLRCLK1_PU_WIDTH                    1  /* DACLRCLK1_PU */
+#define WM2200_DACLRCLK1_PD                     0x0200  /* DACLRCLK1_PD */
+#define WM2200_DACLRCLK1_PD_MASK                0x0200  /* DACLRCLK1_PD */
+#define WM2200_DACLRCLK1_PD_SHIFT                    9  /* DACLRCLK1_PD */
+#define WM2200_DACLRCLK1_PD_WIDTH                    1  /* DACLRCLK1_PD */
+#define WM2200_BCLK1_PU                         0x0100  /* BCLK1_PU */
+#define WM2200_BCLK1_PU_MASK                    0x0100  /* BCLK1_PU */
+#define WM2200_BCLK1_PU_SHIFT                        8  /* BCLK1_PU */
+#define WM2200_BCLK1_PU_WIDTH                        1  /* BCLK1_PU */
+#define WM2200_BCLK1_PD                         0x0080  /* BCLK1_PD */
+#define WM2200_BCLK1_PD_MASK                    0x0080  /* BCLK1_PD */
+#define WM2200_BCLK1_PD_SHIFT                        7  /* BCLK1_PD */
+#define WM2200_BCLK1_PD_WIDTH                        1  /* BCLK1_PD */
+#define WM2200_DACDAT1_PU                       0x0040  /* DACDAT1_PU */
+#define WM2200_DACDAT1_PU_MASK                  0x0040  /* DACDAT1_PU */
+#define WM2200_DACDAT1_PU_SHIFT                      6  /* DACDAT1_PU */
+#define WM2200_DACDAT1_PU_WIDTH                      1  /* DACDAT1_PU */
+#define WM2200_DACDAT1_PD                       0x0020  /* DACDAT1_PD */
+#define WM2200_DACDAT1_PD_MASK                  0x0020  /* DACDAT1_PD */
+#define WM2200_DACDAT1_PD_SHIFT                      5  /* DACDAT1_PD */
+#define WM2200_DACDAT1_PD_WIDTH                      1  /* DACDAT1_PD */
+#define WM2200_DMICDAT3_PD                      0x0010  /* DMICDAT3_PD */
+#define WM2200_DMICDAT3_PD_MASK                 0x0010  /* DMICDAT3_PD */
+#define WM2200_DMICDAT3_PD_SHIFT                     4  /* DMICDAT3_PD */
+#define WM2200_DMICDAT3_PD_WIDTH                     1  /* DMICDAT3_PD */
+#define WM2200_DMICDAT2_PD                      0x0008  /* DMICDAT2_PD */
+#define WM2200_DMICDAT2_PD_MASK                 0x0008  /* DMICDAT2_PD */
+#define WM2200_DMICDAT2_PD_SHIFT                     3  /* DMICDAT2_PD */
+#define WM2200_DMICDAT2_PD_WIDTH                     1  /* DMICDAT2_PD */
+#define WM2200_DMICDAT1_PD                      0x0004  /* DMICDAT1_PD */
+#define WM2200_DMICDAT1_PD_MASK                 0x0004  /* DMICDAT1_PD */
+#define WM2200_DMICDAT1_PD_SHIFT                     2  /* DMICDAT1_PD */
+#define WM2200_DMICDAT1_PD_WIDTH                     1  /* DMICDAT1_PD */
+#define WM2200_RSTB_PU                          0x0002  /* RSTB_PU */
+#define WM2200_RSTB_PU_MASK                     0x0002  /* RSTB_PU */
+#define WM2200_RSTB_PU_SHIFT                         1  /* RSTB_PU */
+#define WM2200_RSTB_PU_WIDTH                         1  /* RSTB_PU */
+#define WM2200_ADDR_PD                          0x0001  /* ADDR_PD */
+#define WM2200_ADDR_PD_MASK                     0x0001  /* ADDR_PD */
+#define WM2200_ADDR_PD_SHIFT                         0  /* ADDR_PD */
+#define WM2200_ADDR_PD_WIDTH                         1  /* ADDR_PD */
+
+/*
+ * R2048 (0x800) - Interrupt Status 1
+ */
+#define WM2200_DSP_IRQ0_EINT                    0x0080  /* DSP_IRQ0_EINT */
+#define WM2200_DSP_IRQ0_EINT_MASK               0x0080  /* DSP_IRQ0_EINT */
+#define WM2200_DSP_IRQ0_EINT_SHIFT                   7  /* DSP_IRQ0_EINT */
+#define WM2200_DSP_IRQ0_EINT_WIDTH                   1  /* DSP_IRQ0_EINT */
+#define WM2200_DSP_IRQ1_EINT                    0x0040  /* DSP_IRQ1_EINT */
+#define WM2200_DSP_IRQ1_EINT_MASK               0x0040  /* DSP_IRQ1_EINT */
+#define WM2200_DSP_IRQ1_EINT_SHIFT                   6  /* DSP_IRQ1_EINT */
+#define WM2200_DSP_IRQ1_EINT_WIDTH                   1  /* DSP_IRQ1_EINT */
+#define WM2200_DSP_IRQ2_EINT                    0x0020  /* DSP_IRQ2_EINT */
+#define WM2200_DSP_IRQ2_EINT_MASK               0x0020  /* DSP_IRQ2_EINT */
+#define WM2200_DSP_IRQ2_EINT_SHIFT                   5  /* DSP_IRQ2_EINT */
+#define WM2200_DSP_IRQ2_EINT_WIDTH                   1  /* DSP_IRQ2_EINT */
+#define WM2200_DSP_IRQ3_EINT                    0x0010  /* DSP_IRQ3_EINT */
+#define WM2200_DSP_IRQ3_EINT_MASK               0x0010  /* DSP_IRQ3_EINT */
+#define WM2200_DSP_IRQ3_EINT_SHIFT                   4  /* DSP_IRQ3_EINT */
+#define WM2200_DSP_IRQ3_EINT_WIDTH                   1  /* DSP_IRQ3_EINT */
+#define WM2200_GP4_EINT                         0x0008  /* GP4_EINT */
+#define WM2200_GP4_EINT_MASK                    0x0008  /* GP4_EINT */
+#define WM2200_GP4_EINT_SHIFT                        3  /* GP4_EINT */
+#define WM2200_GP4_EINT_WIDTH                        1  /* GP4_EINT */
+#define WM2200_GP3_EINT                         0x0004  /* GP3_EINT */
+#define WM2200_GP3_EINT_MASK                    0x0004  /* GP3_EINT */
+#define WM2200_GP3_EINT_SHIFT                        2  /* GP3_EINT */
+#define WM2200_GP3_EINT_WIDTH                        1  /* GP3_EINT */
+#define WM2200_GP2_EINT                         0x0002  /* GP2_EINT */
+#define WM2200_GP2_EINT_MASK                    0x0002  /* GP2_EINT */
+#define WM2200_GP2_EINT_SHIFT                        1  /* GP2_EINT */
+#define WM2200_GP2_EINT_WIDTH                        1  /* GP2_EINT */
+#define WM2200_GP1_EINT                         0x0001  /* GP1_EINT */
+#define WM2200_GP1_EINT_MASK                    0x0001  /* GP1_EINT */
+#define WM2200_GP1_EINT_SHIFT                        0  /* GP1_EINT */
+#define WM2200_GP1_EINT_WIDTH                        1  /* GP1_EINT */
+
+/*
+ * R2049 (0x801) - Interrupt Status 1 Mask
+ */
+#define WM2200_IM_DSP_IRQ0_EINT                 0x0080  /* IM_DSP_IRQ0_EINT */
+#define WM2200_IM_DSP_IRQ0_EINT_MASK            0x0080  /* IM_DSP_IRQ0_EINT */
+#define WM2200_IM_DSP_IRQ0_EINT_SHIFT                7  /* IM_DSP_IRQ0_EINT */
+#define WM2200_IM_DSP_IRQ0_EINT_WIDTH                1  /* IM_DSP_IRQ0_EINT */
+#define WM2200_IM_DSP_IRQ1_EINT                 0x0040  /* IM_DSP_IRQ1_EINT */
+#define WM2200_IM_DSP_IRQ1_EINT_MASK            0x0040  /* IM_DSP_IRQ1_EINT */
+#define WM2200_IM_DSP_IRQ1_EINT_SHIFT                6  /* IM_DSP_IRQ1_EINT */
+#define WM2200_IM_DSP_IRQ1_EINT_WIDTH                1  /* IM_DSP_IRQ1_EINT */
+#define WM2200_IM_DSP_IRQ2_EINT                 0x0020  /* IM_DSP_IRQ2_EINT */
+#define WM2200_IM_DSP_IRQ2_EINT_MASK            0x0020  /* IM_DSP_IRQ2_EINT */
+#define WM2200_IM_DSP_IRQ2_EINT_SHIFT                5  /* IM_DSP_IRQ2_EINT */
+#define WM2200_IM_DSP_IRQ2_EINT_WIDTH                1  /* IM_DSP_IRQ2_EINT */
+#define WM2200_IM_DSP_IRQ3_EINT                 0x0010  /* IM_DSP_IRQ3_EINT */
+#define WM2200_IM_DSP_IRQ3_EINT_MASK            0x0010  /* IM_DSP_IRQ3_EINT */
+#define WM2200_IM_DSP_IRQ3_EINT_SHIFT                4  /* IM_DSP_IRQ3_EINT */
+#define WM2200_IM_DSP_IRQ3_EINT_WIDTH                1  /* IM_DSP_IRQ3_EINT */
+#define WM2200_IM_GP4_EINT                      0x0008  /* IM_GP4_EINT */
+#define WM2200_IM_GP4_EINT_MASK                 0x0008  /* IM_GP4_EINT */
+#define WM2200_IM_GP4_EINT_SHIFT                     3  /* IM_GP4_EINT */
+#define WM2200_IM_GP4_EINT_WIDTH                     1  /* IM_GP4_EINT */
+#define WM2200_IM_GP3_EINT                      0x0004  /* IM_GP3_EINT */
+#define WM2200_IM_GP3_EINT_MASK                 0x0004  /* IM_GP3_EINT */
+#define WM2200_IM_GP3_EINT_SHIFT                     2  /* IM_GP3_EINT */
+#define WM2200_IM_GP3_EINT_WIDTH                     1  /* IM_GP3_EINT */
+#define WM2200_IM_GP2_EINT                      0x0002  /* IM_GP2_EINT */
+#define WM2200_IM_GP2_EINT_MASK                 0x0002  /* IM_GP2_EINT */
+#define WM2200_IM_GP2_EINT_SHIFT                     1  /* IM_GP2_EINT */
+#define WM2200_IM_GP2_EINT_WIDTH                     1  /* IM_GP2_EINT */
+#define WM2200_IM_GP1_EINT                      0x0001  /* IM_GP1_EINT */
+#define WM2200_IM_GP1_EINT_MASK                 0x0001  /* IM_GP1_EINT */
+#define WM2200_IM_GP1_EINT_SHIFT                     0  /* IM_GP1_EINT */
+#define WM2200_IM_GP1_EINT_WIDTH                     1  /* IM_GP1_EINT */
+
+/*
+ * R2050 (0x802) - Interrupt Status 2
+ */
+#define WM2200_WSEQ_BUSY_EINT                   0x0100  /* WSEQ_BUSY_EINT */
+#define WM2200_WSEQ_BUSY_EINT_MASK              0x0100  /* WSEQ_BUSY_EINT */
+#define WM2200_WSEQ_BUSY_EINT_SHIFT                  8  /* WSEQ_BUSY_EINT */
+#define WM2200_WSEQ_BUSY_EINT_WIDTH                  1  /* WSEQ_BUSY_EINT */
+#define WM2200_FLL_LOCK_EINT                    0x0002  /* FLL_LOCK_EINT */
+#define WM2200_FLL_LOCK_EINT_MASK               0x0002  /* FLL_LOCK_EINT */
+#define WM2200_FLL_LOCK_EINT_SHIFT                   1  /* FLL_LOCK_EINT */
+#define WM2200_FLL_LOCK_EINT_WIDTH                   1  /* FLL_LOCK_EINT */
+#define WM2200_CLKGEN_EINT                      0x0001  /* CLKGEN_EINT */
+#define WM2200_CLKGEN_EINT_MASK                 0x0001  /* CLKGEN_EINT */
+#define WM2200_CLKGEN_EINT_SHIFT                     0  /* CLKGEN_EINT */
+#define WM2200_CLKGEN_EINT_WIDTH                     1  /* CLKGEN_EINT */
+
+/*
+ * R2051 (0x803) - Interrupt Raw Status 2
+ */
+#define WM2200_WSEQ_BUSY_STS                    0x0100  /* WSEQ_BUSY_STS */
+#define WM2200_WSEQ_BUSY_STS_MASK               0x0100  /* WSEQ_BUSY_STS */
+#define WM2200_WSEQ_BUSY_STS_SHIFT                   8  /* WSEQ_BUSY_STS */
+#define WM2200_WSEQ_BUSY_STS_WIDTH                   1  /* WSEQ_BUSY_STS */
+#define WM2200_FLL_LOCK_STS                     0x0002  /* FLL_LOCK_STS */
+#define WM2200_FLL_LOCK_STS_MASK                0x0002  /* FLL_LOCK_STS */
+#define WM2200_FLL_LOCK_STS_SHIFT                    1  /* FLL_LOCK_STS */
+#define WM2200_FLL_LOCK_STS_WIDTH                    1  /* FLL_LOCK_STS */
+#define WM2200_CLKGEN_STS                       0x0001  /* CLKGEN_STS */
+#define WM2200_CLKGEN_STS_MASK                  0x0001  /* CLKGEN_STS */
+#define WM2200_CLKGEN_STS_SHIFT                      0  /* CLKGEN_STS */
+#define WM2200_CLKGEN_STS_WIDTH                      1  /* CLKGEN_STS */
+
+/*
+ * R2052 (0x804) - Interrupt Status 2 Mask
+ */
+#define WM2200_IM_WSEQ_BUSY_EINT                0x0100  /* IM_WSEQ_BUSY_EINT */
+#define WM2200_IM_WSEQ_BUSY_EINT_MASK           0x0100  /* IM_WSEQ_BUSY_EINT */
+#define WM2200_IM_WSEQ_BUSY_EINT_SHIFT               8  /* IM_WSEQ_BUSY_EINT */
+#define WM2200_IM_WSEQ_BUSY_EINT_WIDTH               1  /* IM_WSEQ_BUSY_EINT */
+#define WM2200_IM_FLL_LOCK_EINT                 0x0002  /* IM_FLL_LOCK_EINT */
+#define WM2200_IM_FLL_LOCK_EINT_MASK            0x0002  /* IM_FLL_LOCK_EINT */
+#define WM2200_IM_FLL_LOCK_EINT_SHIFT                1  /* IM_FLL_LOCK_EINT */
+#define WM2200_IM_FLL_LOCK_EINT_WIDTH                1  /* IM_FLL_LOCK_EINT */
+#define WM2200_IM_CLKGEN_EINT                   0x0001  /* IM_CLKGEN_EINT */
+#define WM2200_IM_CLKGEN_EINT_MASK              0x0001  /* IM_CLKGEN_EINT */
+#define WM2200_IM_CLKGEN_EINT_SHIFT                  0  /* IM_CLKGEN_EINT */
+#define WM2200_IM_CLKGEN_EINT_WIDTH                  1  /* IM_CLKGEN_EINT */
+
+/*
+ * R2056 (0x808) - Interrupt Control
+ */
+#define WM2200_IM_IRQ                           0x0001  /* IM_IRQ */
+#define WM2200_IM_IRQ_MASK                      0x0001  /* IM_IRQ */
+#define WM2200_IM_IRQ_SHIFT                          0  /* IM_IRQ */
+#define WM2200_IM_IRQ_WIDTH                          1  /* IM_IRQ */
+
+/*
+ * R2304 (0x900) - EQL_1
+ */
+#define WM2200_EQL_B1_GAIN_MASK                 0xF800  /* EQL_B1_GAIN - [15:11] */
+#define WM2200_EQL_B1_GAIN_SHIFT                    11  /* EQL_B1_GAIN - [15:11] */
+#define WM2200_EQL_B1_GAIN_WIDTH                     5  /* EQL_B1_GAIN - [15:11] */
+#define WM2200_EQL_B2_GAIN_MASK                 0x07C0  /* EQL_B2_GAIN - [10:6] */
+#define WM2200_EQL_B2_GAIN_SHIFT                     6  /* EQL_B2_GAIN - [10:6] */
+#define WM2200_EQL_B2_GAIN_WIDTH                     5  /* EQL_B2_GAIN - [10:6] */
+#define WM2200_EQL_B3_GAIN_MASK                 0x003E  /* EQL_B3_GAIN - [5:1] */
+#define WM2200_EQL_B3_GAIN_SHIFT                     1  /* EQL_B3_GAIN - [5:1] */
+#define WM2200_EQL_B3_GAIN_WIDTH                     5  /* EQL_B3_GAIN - [5:1] */
+#define WM2200_EQL_ENA                          0x0001  /* EQL_ENA */
+#define WM2200_EQL_ENA_MASK                     0x0001  /* EQL_ENA */
+#define WM2200_EQL_ENA_SHIFT                         0  /* EQL_ENA */
+#define WM2200_EQL_ENA_WIDTH                         1  /* EQL_ENA */
+
+/*
+ * R2305 (0x901) - EQL_2
+ */
+#define WM2200_EQL_B4_GAIN_MASK                 0xF800  /* EQL_B4_GAIN - [15:11] */
+#define WM2200_EQL_B4_GAIN_SHIFT                    11  /* EQL_B4_GAIN - [15:11] */
+#define WM2200_EQL_B4_GAIN_WIDTH                     5  /* EQL_B4_GAIN - [15:11] */
+#define WM2200_EQL_B5_GAIN_MASK                 0x07C0  /* EQL_B5_GAIN - [10:6] */
+#define WM2200_EQL_B5_GAIN_SHIFT                     6  /* EQL_B5_GAIN - [10:6] */
+#define WM2200_EQL_B5_GAIN_WIDTH                     5  /* EQL_B5_GAIN - [10:6] */
+
+/*
+ * R2306 (0x902) - EQL_3
+ */
+#define WM2200_EQL_B1_A_MASK                    0xFFFF  /* EQL_B1_A - [15:0] */
+#define WM2200_EQL_B1_A_SHIFT                        0  /* EQL_B1_A - [15:0] */
+#define WM2200_EQL_B1_A_WIDTH                       16  /* EQL_B1_A - [15:0] */
+
+/*
+ * R2307 (0x903) - EQL_4
+ */
+#define WM2200_EQL_B1_B_MASK                    0xFFFF  /* EQL_B1_B - [15:0] */
+#define WM2200_EQL_B1_B_SHIFT                        0  /* EQL_B1_B - [15:0] */
+#define WM2200_EQL_B1_B_WIDTH                       16  /* EQL_B1_B - [15:0] */
+
+/*
+ * R2308 (0x904) - EQL_5
+ */
+#define WM2200_EQL_B1_PG_MASK                   0xFFFF  /* EQL_B1_PG - [15:0] */
+#define WM2200_EQL_B1_PG_SHIFT                       0  /* EQL_B1_PG - [15:0] */
+#define WM2200_EQL_B1_PG_WIDTH                      16  /* EQL_B1_PG - [15:0] */
+
+/*
+ * R2309 (0x905) - EQL_6
+ */
+#define WM2200_EQL_B2_A_MASK                    0xFFFF  /* EQL_B2_A - [15:0] */
+#define WM2200_EQL_B2_A_SHIFT                        0  /* EQL_B2_A - [15:0] */
+#define WM2200_EQL_B2_A_WIDTH                       16  /* EQL_B2_A - [15:0] */
+
+/*
+ * R2310 (0x906) - EQL_7
+ */
+#define WM2200_EQL_B2_B_MASK                    0xFFFF  /* EQL_B2_B - [15:0] */
+#define WM2200_EQL_B2_B_SHIFT                        0  /* EQL_B2_B - [15:0] */
+#define WM2200_EQL_B2_B_WIDTH                       16  /* EQL_B2_B - [15:0] */
+
+/*
+ * R2311 (0x907) - EQL_8
+ */
+#define WM2200_EQL_B2_C_MASK                    0xFFFF  /* EQL_B2_C - [15:0] */
+#define WM2200_EQL_B2_C_SHIFT                        0  /* EQL_B2_C - [15:0] */
+#define WM2200_EQL_B2_C_WIDTH                       16  /* EQL_B2_C - [15:0] */
+
+/*
+ * R2312 (0x908) - EQL_9
+ */
+#define WM2200_EQL_B2_PG_MASK                   0xFFFF  /* EQL_B2_PG - [15:0] */
+#define WM2200_EQL_B2_PG_SHIFT                       0  /* EQL_B2_PG - [15:0] */
+#define WM2200_EQL_B2_PG_WIDTH                      16  /* EQL_B2_PG - [15:0] */
+
+/*
+ * R2313 (0x909) - EQL_10
+ */
+#define WM2200_EQL_B3_A_MASK                    0xFFFF  /* EQL_B3_A - [15:0] */
+#define WM2200_EQL_B3_A_SHIFT                        0  /* EQL_B3_A - [15:0] */
+#define WM2200_EQL_B3_A_WIDTH                       16  /* EQL_B3_A - [15:0] */
+
+/*
+ * R2314 (0x90A) - EQL_11
+ */
+#define WM2200_EQL_B3_B_MASK                    0xFFFF  /* EQL_B3_B - [15:0] */
+#define WM2200_EQL_B3_B_SHIFT                        0  /* EQL_B3_B - [15:0] */
+#define WM2200_EQL_B3_B_WIDTH                       16  /* EQL_B3_B - [15:0] */
+
+/*
+ * R2315 (0x90B) - EQL_12
+ */
+#define WM2200_EQL_B3_C_MASK                    0xFFFF  /* EQL_B3_C - [15:0] */
+#define WM2200_EQL_B3_C_SHIFT                        0  /* EQL_B3_C - [15:0] */
+#define WM2200_EQL_B3_C_WIDTH                       16  /* EQL_B3_C - [15:0] */
+
+/*
+ * R2316 (0x90C) - EQL_13
+ */
+#define WM2200_EQL_B3_PG_MASK                   0xFFFF  /* EQL_B3_PG - [15:0] */
+#define WM2200_EQL_B3_PG_SHIFT                       0  /* EQL_B3_PG - [15:0] */
+#define WM2200_EQL_B3_PG_WIDTH                      16  /* EQL_B3_PG - [15:0] */
+
+/*
+ * R2317 (0x90D) - EQL_14
+ */
+#define WM2200_EQL_B4_A_MASK                    0xFFFF  /* EQL_B4_A - [15:0] */
+#define WM2200_EQL_B4_A_SHIFT                        0  /* EQL_B4_A - [15:0] */
+#define WM2200_EQL_B4_A_WIDTH                       16  /* EQL_B4_A - [15:0] */
+
+/*
+ * R2318 (0x90E) - EQL_15
+ */
+#define WM2200_EQL_B4_B_MASK                    0xFFFF  /* EQL_B4_B - [15:0] */
+#define WM2200_EQL_B4_B_SHIFT                        0  /* EQL_B4_B - [15:0] */
+#define WM2200_EQL_B4_B_WIDTH                       16  /* EQL_B4_B - [15:0] */
+
+/*
+ * R2319 (0x90F) - EQL_16
+ */
+#define WM2200_EQL_B4_C_MASK                    0xFFFF  /* EQL_B4_C - [15:0] */
+#define WM2200_EQL_B4_C_SHIFT                        0  /* EQL_B4_C - [15:0] */
+#define WM2200_EQL_B4_C_WIDTH                       16  /* EQL_B4_C - [15:0] */
+
+/*
+ * R2320 (0x910) - EQL_17
+ */
+#define WM2200_EQL_B4_PG_MASK                   0xFFFF  /* EQL_B4_PG - [15:0] */
+#define WM2200_EQL_B4_PG_SHIFT                       0  /* EQL_B4_PG - [15:0] */
+#define WM2200_EQL_B4_PG_WIDTH                      16  /* EQL_B4_PG - [15:0] */
+
+/*
+ * R2321 (0x911) - EQL_18
+ */
+#define WM2200_EQL_B5_A_MASK                    0xFFFF  /* EQL_B5_A - [15:0] */
+#define WM2200_EQL_B5_A_SHIFT                        0  /* EQL_B5_A - [15:0] */
+#define WM2200_EQL_B5_A_WIDTH                       16  /* EQL_B5_A - [15:0] */
+
+/*
+ * R2322 (0x912) - EQL_19
+ */
+#define WM2200_EQL_B5_B_MASK                    0xFFFF  /* EQL_B5_B - [15:0] */
+#define WM2200_EQL_B5_B_SHIFT                        0  /* EQL_B5_B - [15:0] */
+#define WM2200_EQL_B5_B_WIDTH                       16  /* EQL_B5_B - [15:0] */
+
+/*
+ * R2323 (0x913) - EQL_20
+ */
+#define WM2200_EQL_B5_PG_MASK                   0xFFFF  /* EQL_B5_PG - [15:0] */
+#define WM2200_EQL_B5_PG_SHIFT                       0  /* EQL_B5_PG - [15:0] */
+#define WM2200_EQL_B5_PG_WIDTH                      16  /* EQL_B5_PG - [15:0] */
+
+/*
+ * R2326 (0x916) - EQR_1
+ */
+#define WM2200_EQR_B1_GAIN_MASK                 0xF800  /* EQR_B1_GAIN - [15:11] */
+#define WM2200_EQR_B1_GAIN_SHIFT                    11  /* EQR_B1_GAIN - [15:11] */
+#define WM2200_EQR_B1_GAIN_WIDTH                     5  /* EQR_B1_GAIN - [15:11] */
+#define WM2200_EQR_B2_GAIN_MASK                 0x07C0  /* EQR_B2_GAIN - [10:6] */
+#define WM2200_EQR_B2_GAIN_SHIFT                     6  /* EQR_B2_GAIN - [10:6] */
+#define WM2200_EQR_B2_GAIN_WIDTH                     5  /* EQR_B2_GAIN - [10:6] */
+#define WM2200_EQR_B3_GAIN_MASK                 0x003E  /* EQR_B3_GAIN - [5:1] */
+#define WM2200_EQR_B3_GAIN_SHIFT                     1  /* EQR_B3_GAIN - [5:1] */
+#define WM2200_EQR_B3_GAIN_WIDTH                     5  /* EQR_B3_GAIN - [5:1] */
+#define WM2200_EQR_ENA                          0x0001  /* EQR_ENA */
+#define WM2200_EQR_ENA_MASK                     0x0001  /* EQR_ENA */
+#define WM2200_EQR_ENA_SHIFT                         0  /* EQR_ENA */
+#define WM2200_EQR_ENA_WIDTH                         1  /* EQR_ENA */
+
+/*
+ * R2327 (0x917) - EQR_2
+ */
+#define WM2200_EQR_B4_GAIN_MASK                 0xF800  /* EQR_B4_GAIN - [15:11] */
+#define WM2200_EQR_B4_GAIN_SHIFT                    11  /* EQR_B4_GAIN - [15:11] */
+#define WM2200_EQR_B4_GAIN_WIDTH                     5  /* EQR_B4_GAIN - [15:11] */
+#define WM2200_EQR_B5_GAIN_MASK                 0x07C0  /* EQR_B5_GAIN - [10:6] */
+#define WM2200_EQR_B5_GAIN_SHIFT                     6  /* EQR_B5_GAIN - [10:6] */
+#define WM2200_EQR_B5_GAIN_WIDTH                     5  /* EQR_B5_GAIN - [10:6] */
+
+/*
+ * R2328 (0x918) - EQR_3
+ */
+#define WM2200_EQR_B1_A_MASK                    0xFFFF  /* EQR_B1_A - [15:0] */
+#define WM2200_EQR_B1_A_SHIFT                        0  /* EQR_B1_A - [15:0] */
+#define WM2200_EQR_B1_A_WIDTH                       16  /* EQR_B1_A - [15:0] */
+
+/*
+ * R2329 (0x919) - EQR_4
+ */
+#define WM2200_EQR_B1_B_MASK                    0xFFFF  /* EQR_B1_B - [15:0] */
+#define WM2200_EQR_B1_B_SHIFT                        0  /* EQR_B1_B - [15:0] */
+#define WM2200_EQR_B1_B_WIDTH                       16  /* EQR_B1_B - [15:0] */
+
+/*
+ * R2330 (0x91A) - EQR_5
+ */
+#define WM2200_EQR_B1_PG_MASK                   0xFFFF  /* EQR_B1_PG - [15:0] */
+#define WM2200_EQR_B1_PG_SHIFT                       0  /* EQR_B1_PG - [15:0] */
+#define WM2200_EQR_B1_PG_WIDTH                      16  /* EQR_B1_PG - [15:0] */
+
+/*
+ * R2331 (0x91B) - EQR_6
+ */
+#define WM2200_EQR_B2_A_MASK                    0xFFFF  /* EQR_B2_A - [15:0] */
+#define WM2200_EQR_B2_A_SHIFT                        0  /* EQR_B2_A - [15:0] */
+#define WM2200_EQR_B2_A_WIDTH                       16  /* EQR_B2_A - [15:0] */
+
+/*
+ * R2332 (0x91C) - EQR_7
+ */
+#define WM2200_EQR_B2_B_MASK                    0xFFFF  /* EQR_B2_B - [15:0] */
+#define WM2200_EQR_B2_B_SHIFT                        0  /* EQR_B2_B - [15:0] */
+#define WM2200_EQR_B2_B_WIDTH                       16  /* EQR_B2_B - [15:0] */
+
+/*
+ * R2333 (0x91D) - EQR_8
+ */
+#define WM2200_EQR_B2_C_MASK                    0xFFFF  /* EQR_B2_C - [15:0] */
+#define WM2200_EQR_B2_C_SHIFT                        0  /* EQR_B2_C - [15:0] */
+#define WM2200_EQR_B2_C_WIDTH                       16  /* EQR_B2_C - [15:0] */
+
+/*
+ * R2334 (0x91E) - EQR_9
+ */
+#define WM2200_EQR_B2_PG_MASK                   0xFFFF  /* EQR_B2_PG - [15:0] */
+#define WM2200_EQR_B2_PG_SHIFT                       0  /* EQR_B2_PG - [15:0] */
+#define WM2200_EQR_B2_PG_WIDTH                      16  /* EQR_B2_PG - [15:0] */
+
+/*
+ * R2335 (0x91F) - EQR_10
+ */
+#define WM2200_EQR_B3_A_MASK                    0xFFFF  /* EQR_B3_A - [15:0] */
+#define WM2200_EQR_B3_A_SHIFT                        0  /* EQR_B3_A - [15:0] */
+#define WM2200_EQR_B3_A_WIDTH                       16  /* EQR_B3_A - [15:0] */
+
+/*
+ * R2336 (0x920) - EQR_11
+ */
+#define WM2200_EQR_B3_B_MASK                    0xFFFF  /* EQR_B3_B - [15:0] */
+#define WM2200_EQR_B3_B_SHIFT                        0  /* EQR_B3_B - [15:0] */
+#define WM2200_EQR_B3_B_WIDTH                       16  /* EQR_B3_B - [15:0] */
+
+/*
+ * R2337 (0x921) - EQR_12
+ */
+#define WM2200_EQR_B3_C_MASK                    0xFFFF  /* EQR_B3_C - [15:0] */
+#define WM2200_EQR_B3_C_SHIFT                        0  /* EQR_B3_C - [15:0] */
+#define WM2200_EQR_B3_C_WIDTH                       16  /* EQR_B3_C - [15:0] */
+
+/*
+ * R2338 (0x922) - EQR_13
+ */
+#define WM2200_EQR_B3_PG_MASK                   0xFFFF  /* EQR_B3_PG - [15:0] */
+#define WM2200_EQR_B3_PG_SHIFT                       0  /* EQR_B3_PG - [15:0] */
+#define WM2200_EQR_B3_PG_WIDTH                      16  /* EQR_B3_PG - [15:0] */
+
+/*
+ * R2339 (0x923) - EQR_14
+ */
+#define WM2200_EQR_B4_A_MASK                    0xFFFF  /* EQR_B4_A - [15:0] */
+#define WM2200_EQR_B4_A_SHIFT                        0  /* EQR_B4_A - [15:0] */
+#define WM2200_EQR_B4_A_WIDTH                       16  /* EQR_B4_A - [15:0] */
+
+/*
+ * R2340 (0x924) - EQR_15
+ */
+#define WM2200_EQR_B4_B_MASK                    0xFFFF  /* EQR_B4_B - [15:0] */
+#define WM2200_EQR_B4_B_SHIFT                        0  /* EQR_B4_B - [15:0] */
+#define WM2200_EQR_B4_B_WIDTH                       16  /* EQR_B4_B - [15:0] */
+
+/*
+ * R2341 (0x925) - EQR_16
+ */
+#define WM2200_EQR_B4_C_MASK                    0xFFFF  /* EQR_B4_C - [15:0] */
+#define WM2200_EQR_B4_C_SHIFT                        0  /* EQR_B4_C - [15:0] */
+#define WM2200_EQR_B4_C_WIDTH                       16  /* EQR_B4_C - [15:0] */
+
+/*
+ * R2342 (0x926) - EQR_17
+ */
+#define WM2200_EQR_B4_PG_MASK                   0xFFFF  /* EQR_B4_PG - [15:0] */
+#define WM2200_EQR_B4_PG_SHIFT                       0  /* EQR_B4_PG - [15:0] */
+#define WM2200_EQR_B4_PG_WIDTH                      16  /* EQR_B4_PG - [15:0] */
+
+/*
+ * R2343 (0x927) - EQR_18
+ */
+#define WM2200_EQR_B5_A_MASK                    0xFFFF  /* EQR_B5_A - [15:0] */
+#define WM2200_EQR_B5_A_SHIFT                        0  /* EQR_B5_A - [15:0] */
+#define WM2200_EQR_B5_A_WIDTH                       16  /* EQR_B5_A - [15:0] */
+
+/*
+ * R2344 (0x928) - EQR_19
+ */
+#define WM2200_EQR_B5_B_MASK                    0xFFFF  /* EQR_B5_B - [15:0] */
+#define WM2200_EQR_B5_B_SHIFT                        0  /* EQR_B5_B - [15:0] */
+#define WM2200_EQR_B5_B_WIDTH                       16  /* EQR_B5_B - [15:0] */
+
+/*
+ * R2345 (0x929) - EQR_20
+ */
+#define WM2200_EQR_B5_PG_MASK                   0xFFFF  /* EQR_B5_PG - [15:0] */
+#define WM2200_EQR_B5_PG_SHIFT                       0  /* EQR_B5_PG - [15:0] */
+#define WM2200_EQR_B5_PG_WIDTH                      16  /* EQR_B5_PG - [15:0] */
+
+/*
+ * R2366 (0x93E) - HPLPF1_1
+ */
+#define WM2200_LHPF1_MODE                       0x0002  /* LHPF1_MODE */
+#define WM2200_LHPF1_MODE_MASK                  0x0002  /* LHPF1_MODE */
+#define WM2200_LHPF1_MODE_SHIFT                      1  /* LHPF1_MODE */
+#define WM2200_LHPF1_MODE_WIDTH                      1  /* LHPF1_MODE */
+#define WM2200_LHPF1_ENA                        0x0001  /* LHPF1_ENA */
+#define WM2200_LHPF1_ENA_MASK                   0x0001  /* LHPF1_ENA */
+#define WM2200_LHPF1_ENA_SHIFT                       0  /* LHPF1_ENA */
+#define WM2200_LHPF1_ENA_WIDTH                       1  /* LHPF1_ENA */
+
+/*
+ * R2367 (0x93F) - HPLPF1_2
+ */
+#define WM2200_LHPF1_COEFF_MASK                 0xFFFF  /* LHPF1_COEFF - [15:0] */
+#define WM2200_LHPF1_COEFF_SHIFT                     0  /* LHPF1_COEFF - [15:0] */
+#define WM2200_LHPF1_COEFF_WIDTH                    16  /* LHPF1_COEFF - [15:0] */
+
+/*
+ * R2370 (0x942) - HPLPF2_1
+ */
+#define WM2200_LHPF2_MODE                       0x0002  /* LHPF2_MODE */
+#define WM2200_LHPF2_MODE_MASK                  0x0002  /* LHPF2_MODE */
+#define WM2200_LHPF2_MODE_SHIFT                      1  /* LHPF2_MODE */
+#define WM2200_LHPF2_MODE_WIDTH                      1  /* LHPF2_MODE */
+#define WM2200_LHPF2_ENA                        0x0001  /* LHPF2_ENA */
+#define WM2200_LHPF2_ENA_MASK                   0x0001  /* LHPF2_ENA */
+#define WM2200_LHPF2_ENA_SHIFT                       0  /* LHPF2_ENA */
+#define WM2200_LHPF2_ENA_WIDTH                       1  /* LHPF2_ENA */
+
+/*
+ * R2371 (0x943) - HPLPF2_2
+ */
+#define WM2200_LHPF2_COEFF_MASK                 0xFFFF  /* LHPF2_COEFF - [15:0] */
+#define WM2200_LHPF2_COEFF_SHIFT                     0  /* LHPF2_COEFF - [15:0] */
+#define WM2200_LHPF2_COEFF_WIDTH                    16  /* LHPF2_COEFF - [15:0] */
+
+/*
+ * R2560 (0xA00) - DSP1 Control 1
+ */
+#define WM2200_DSP1_RW_SEQUENCE_ENA             0x0001  /* DSP1_RW_SEQUENCE_ENA */
+#define WM2200_DSP1_RW_SEQUENCE_ENA_MASK        0x0001  /* DSP1_RW_SEQUENCE_ENA */
+#define WM2200_DSP1_RW_SEQUENCE_ENA_SHIFT            0  /* DSP1_RW_SEQUENCE_ENA */
+#define WM2200_DSP1_RW_SEQUENCE_ENA_WIDTH            1  /* DSP1_RW_SEQUENCE_ENA */
+
+/*
+ * R2562 (0xA02) - DSP1 Control 2
+ */
+#define WM2200_DSP1_PAGE_BASE_PM_0_MASK         0xFF00  /* DSP1_PAGE_BASE_PM - [15:8] */
+#define WM2200_DSP1_PAGE_BASE_PM_0_SHIFT             8  /* DSP1_PAGE_BASE_PM - [15:8] */
+#define WM2200_DSP1_PAGE_BASE_PM_0_WIDTH             8  /* DSP1_PAGE_BASE_PM - [15:8] */
+
+/*
+ * R2563 (0xA03) - DSP1 Control 3
+ */
+#define WM2200_DSP1_PAGE_BASE_DM_0_MASK         0xFF00  /* DSP1_PAGE_BASE_DM - [15:8] */
+#define WM2200_DSP1_PAGE_BASE_DM_0_SHIFT             8  /* DSP1_PAGE_BASE_DM - [15:8] */
+#define WM2200_DSP1_PAGE_BASE_DM_0_WIDTH             8  /* DSP1_PAGE_BASE_DM - [15:8] */
+
+/*
+ * R2564 (0xA04) - DSP1 Control 4
+ */
+#define WM2200_DSP1_PAGE_BASE_ZM_0_MASK         0xFF00  /* DSP1_PAGE_BASE_ZM - [15:8] */
+#define WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT             8  /* DSP1_PAGE_BASE_ZM - [15:8] */
+#define WM2200_DSP1_PAGE_BASE_ZM_0_WIDTH             8  /* DSP1_PAGE_BASE_ZM - [15:8] */
+
+/*
+ * R2566 (0xA06) - DSP1 Control 5
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
+
+/*
+ * R2567 (0xA07) - DSP1 Control 6
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
+
+/*
+ * R2568 (0xA08) - DSP1 Control 7
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
+
+/*
+ * R2569 (0xA09) - DSP1 Control 8
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
+
+/*
+ * R2570 (0xA0A) - DSP1 Control 9
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
+
+/*
+ * R2571 (0xA0B) - DSP1 Control 10
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
+
+/*
+ * R2572 (0xA0C) - DSP1 Control 11
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
+
+/*
+ * R2573 (0xA0D) - DSP1 Control 12
+ */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF  /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_SHIFT      0  /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_WIDTH     14  /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
+
+/*
+ * R2575 (0xA0F) - DSP1 Control 13
+ */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF  /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_SHIFT      0  /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_WIDTH     14  /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
+
+/*
+ * R2576 (0xA10) - DSP1 Control 14
+ */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF  /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_SHIFT      0  /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_WIDTH     14  /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
+
+/*
+ * R2577 (0xA11) - DSP1 Control 15
+ */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF  /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_SHIFT      0  /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_WIDTH     14  /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
+
+/*
+ * R2578 (0xA12) - DSP1 Control 16
+ */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF  /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_SHIFT      0  /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_WIDTH     14  /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
+
+/*
+ * R2579 (0xA13) - DSP1 Control 17
+ */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF  /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_SHIFT      0  /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_WIDTH     14  /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
+
+/*
+ * R2580 (0xA14) - DSP1 Control 18
+ */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF  /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_SHIFT      0  /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_WIDTH     14  /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
+
+/*
+ * R2582 (0xA16) - DSP1 Control 19
+ */
+#define WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK     0x00FF  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
+#define WM2200_DSP1_WDMA_BUFFER_LENGTH_SHIFT         0  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
+#define WM2200_DSP1_WDMA_BUFFER_LENGTH_WIDTH         8  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
+
+/*
+ * R2583 (0xA17) - DSP1 Control 20
+ */
+#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_MASK    0x00FF  /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
+#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_SHIFT        0  /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
+#define WM2200_DSP1_WDMA_CHANNEL_ENABLE_WIDTH        8  /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */
+
+/*
+ * R2584 (0xA18) - DSP1 Control 21
+ */
+#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_MASK    0x003F  /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
+#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_SHIFT        0  /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
+#define WM2200_DSP1_RDMA_CHANNEL_ENABLE_WIDTH        6  /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */
+
+/*
+ * R2586 (0xA1A) - DSP1 Control 22
+ */
+#define WM2200_DSP1_DM_SIZE_MASK                0xFFFF  /* DSP1_DM_SIZE - [15:0] */
+#define WM2200_DSP1_DM_SIZE_SHIFT                    0  /* DSP1_DM_SIZE - [15:0] */
+#define WM2200_DSP1_DM_SIZE_WIDTH                   16  /* DSP1_DM_SIZE - [15:0] */
+
+/*
+ * R2587 (0xA1B) - DSP1 Control 23
+ */
+#define WM2200_DSP1_PM_SIZE_MASK                0xFFFF  /* DSP1_PM_SIZE - [15:0] */
+#define WM2200_DSP1_PM_SIZE_SHIFT                    0  /* DSP1_PM_SIZE - [15:0] */
+#define WM2200_DSP1_PM_SIZE_WIDTH                   16  /* DSP1_PM_SIZE - [15:0] */
+
+/*
+ * R2588 (0xA1C) - DSP1 Control 24
+ */
+#define WM2200_DSP1_ZM_SIZE_MASK                0xFFFF  /* DSP1_ZM_SIZE - [15:0] */
+#define WM2200_DSP1_ZM_SIZE_SHIFT                    0  /* DSP1_ZM_SIZE - [15:0] */
+#define WM2200_DSP1_ZM_SIZE_WIDTH                   16  /* DSP1_ZM_SIZE - [15:0] */
+
+/*
+ * R2590 (0xA1E) - DSP1 Control 25
+ */
+#define WM2200_DSP1_PING_FULL                   0x8000  /* DSP1_PING_FULL */
+#define WM2200_DSP1_PING_FULL_MASK              0x8000  /* DSP1_PING_FULL */
+#define WM2200_DSP1_PING_FULL_SHIFT                 15  /* DSP1_PING_FULL */
+#define WM2200_DSP1_PING_FULL_WIDTH                  1  /* DSP1_PING_FULL */
+#define WM2200_DSP1_PONG_FULL                   0x4000  /* DSP1_PONG_FULL */
+#define WM2200_DSP1_PONG_FULL_MASK              0x4000  /* DSP1_PONG_FULL */
+#define WM2200_DSP1_PONG_FULL_SHIFT                 14  /* DSP1_PONG_FULL */
+#define WM2200_DSP1_PONG_FULL_WIDTH                  1  /* DSP1_PONG_FULL */
+#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_MASK   0x00FF  /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
+#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_SHIFT       0  /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
+#define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_WIDTH       8  /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */
+
+/*
+ * R2592 (0xA20) - DSP1 Control 26
+ */
+#define WM2200_DSP1_SCRATCH_0_MASK              0xFFFF  /* DSP1_SCRATCH_0 - [15:0] */
+#define WM2200_DSP1_SCRATCH_0_SHIFT                  0  /* DSP1_SCRATCH_0 - [15:0] */
+#define WM2200_DSP1_SCRATCH_0_WIDTH                 16  /* DSP1_SCRATCH_0 - [15:0] */
+
+/*
+ * R2593 (0xA21) - DSP1 Control 27
+ */
+#define WM2200_DSP1_SCRATCH_1_MASK              0xFFFF  /* DSP1_SCRATCH_1 - [15:0] */
+#define WM2200_DSP1_SCRATCH_1_SHIFT                  0  /* DSP1_SCRATCH_1 - [15:0] */
+#define WM2200_DSP1_SCRATCH_1_WIDTH                 16  /* DSP1_SCRATCH_1 - [15:0] */
+
+/*
+ * R2594 (0xA22) - DSP1 Control 28
+ */
+#define WM2200_DSP1_SCRATCH_2_MASK              0xFFFF  /* DSP1_SCRATCH_2 - [15:0] */
+#define WM2200_DSP1_SCRATCH_2_SHIFT                  0  /* DSP1_SCRATCH_2 - [15:0] */
+#define WM2200_DSP1_SCRATCH_2_WIDTH                 16  /* DSP1_SCRATCH_2 - [15:0] */
+
+/*
+ * R2595 (0xA23) - DSP1 Control 29
+ */
+#define WM2200_DSP1_SCRATCH_3_MASK              0xFFFF  /* DSP1_SCRATCH_3 - [15:0] */
+#define WM2200_DSP1_SCRATCH_3_SHIFT                  0  /* DSP1_SCRATCH_3 - [15:0] */
+#define WM2200_DSP1_SCRATCH_3_WIDTH                 16  /* DSP1_SCRATCH_3 - [15:0] */
+
+/*
+ * R2596 (0xA24) - DSP1 Control 30
+ */
+#define WM2200_DSP1_DBG_CLK_ENA                 0x0008  /* DSP1_DBG_CLK_ENA */
+#define WM2200_DSP1_DBG_CLK_ENA_MASK            0x0008  /* DSP1_DBG_CLK_ENA */
+#define WM2200_DSP1_DBG_CLK_ENA_SHIFT                3  /* DSP1_DBG_CLK_ENA */
+#define WM2200_DSP1_DBG_CLK_ENA_WIDTH                1  /* DSP1_DBG_CLK_ENA */
+#define WM2200_DSP1_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
+#define WM2200_DSP1_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
+#define WM2200_DSP1_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
+#define WM2200_DSP1_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
+#define WM2200_DSP1_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
+#define WM2200_DSP1_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
+#define WM2200_DSP1_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
+#define WM2200_DSP1_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
+#define WM2200_DSP1_START                       0x0001  /* DSP1_START */
+#define WM2200_DSP1_START_MASK                  0x0001  /* DSP1_START */
+#define WM2200_DSP1_START_SHIFT                      0  /* DSP1_START */
+#define WM2200_DSP1_START_WIDTH                      1  /* DSP1_START */
+
+/*
+ * R2598 (0xA26) - DSP1 Control 31
+ */
+#define WM2200_DSP1_CLK_RATE_MASK               0x0018  /* DSP1_CLK_RATE - [4:3] */
+#define WM2200_DSP1_CLK_RATE_SHIFT                   3  /* DSP1_CLK_RATE - [4:3] */
+#define WM2200_DSP1_CLK_RATE_WIDTH                   2  /* DSP1_CLK_RATE - [4:3] */
+#define WM2200_DSP1_CLK_AVAIL                   0x0004  /* DSP1_CLK_AVAIL */
+#define WM2200_DSP1_CLK_AVAIL_MASK              0x0004  /* DSP1_CLK_AVAIL */
+#define WM2200_DSP1_CLK_AVAIL_SHIFT                  2  /* DSP1_CLK_AVAIL */
+#define WM2200_DSP1_CLK_AVAIL_WIDTH                  1  /* DSP1_CLK_AVAIL */
+#define WM2200_DSP1_CLK_REQ_MASK                0x0003  /* DSP1_CLK_REQ - [1:0] */
+#define WM2200_DSP1_CLK_REQ_SHIFT                    0  /* DSP1_CLK_REQ - [1:0] */
+#define WM2200_DSP1_CLK_REQ_WIDTH                    2  /* DSP1_CLK_REQ - [1:0] */
+
+/*
+ * R2816 (0xB00) - DSP2 Control 1
+ */
+#define WM2200_DSP2_RW_SEQUENCE_ENA             0x0001  /* DSP2_RW_SEQUENCE_ENA */
+#define WM2200_DSP2_RW_SEQUENCE_ENA_MASK        0x0001  /* DSP2_RW_SEQUENCE_ENA */
+#define WM2200_DSP2_RW_SEQUENCE_ENA_SHIFT            0  /* DSP2_RW_SEQUENCE_ENA */
+#define WM2200_DSP2_RW_SEQUENCE_ENA_WIDTH            1  /* DSP2_RW_SEQUENCE_ENA */
+
+/*
+ * R2818 (0xB02) - DSP2 Control 2
+ */
+#define WM2200_DSP2_PAGE_BASE_PM_0_MASK         0xFF00  /* DSP2_PAGE_BASE_PM - [15:8] */
+#define WM2200_DSP2_PAGE_BASE_PM_0_SHIFT             8  /* DSP2_PAGE_BASE_PM - [15:8] */
+#define WM2200_DSP2_PAGE_BASE_PM_0_WIDTH             8  /* DSP2_PAGE_BASE_PM - [15:8] */
+
+/*
+ * R2819 (0xB03) - DSP2 Control 3
+ */
+#define WM2200_DSP2_PAGE_BASE_DM_0_MASK         0xFF00  /* DSP2_PAGE_BASE_DM - [15:8] */
+#define WM2200_DSP2_PAGE_BASE_DM_0_SHIFT             8  /* DSP2_PAGE_BASE_DM - [15:8] */
+#define WM2200_DSP2_PAGE_BASE_DM_0_WIDTH             8  /* DSP2_PAGE_BASE_DM - [15:8] */
+
+/*
+ * R2820 (0xB04) - DSP2 Control 4
+ */
+#define WM2200_DSP2_PAGE_BASE_ZM_0_MASK         0xFF00  /* DSP2_PAGE_BASE_ZM - [15:8] */
+#define WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT             8  /* DSP2_PAGE_BASE_ZM - [15:8] */
+#define WM2200_DSP2_PAGE_BASE_ZM_0_WIDTH             8  /* DSP2_PAGE_BASE_ZM - [15:8] */
+
+/*
+ * R2822 (0xB06) - DSP2 Control 5
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */
+
+/*
+ * R2823 (0xB07) - DSP2 Control 6
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */
+
+/*
+ * R2824 (0xB08) - DSP2 Control 7
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */
+
+/*
+ * R2825 (0xB09) - DSP2 Control 8
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */
+
+/*
+ * R2826 (0xB0A) - DSP2 Control 9
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */
+
+/*
+ * R2827 (0xB0B) - DSP2 Control 10
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */
+
+/*
+ * R2828 (0xB0C) - DSP2 Control 11
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */
+
+/*
+ * R2829 (0xB0D) - DSP2 Control 12
+ */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF  /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_SHIFT      0  /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_WIDTH     14  /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */
+
+/*
+ * R2831 (0xB0F) - DSP2 Control 13
+ */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF  /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_SHIFT      0  /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_WIDTH     14  /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */
+
+/*
+ * R2832 (0xB10) - DSP2 Control 14
+ */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF  /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_SHIFT      0  /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_WIDTH     14  /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */
+
+/*
+ * R2833 (0xB11) - DSP2 Control 15
+ */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF  /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_SHIFT      0  /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_WIDTH     14  /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */
+
+/*
+ * R2834 (0xB12) - DSP2 Control 16
+ */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF  /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_SHIFT      0  /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_WIDTH     14  /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */
+
+/*
+ * R2835 (0xB13) - DSP2 Control 17
+ */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF  /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_SHIFT      0  /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_WIDTH     14  /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */
+
+/*
+ * R2836 (0xB14) - DSP2 Control 18
+ */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF  /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_SHIFT      0  /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
+#define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_WIDTH     14  /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */
+
+/*
+ * R2838 (0xB16) - DSP2 Control 19
+ */
+#define WM2200_DSP2_WDMA_BUFFER_LENGTH_MASK     0x00FF  /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
+#define WM2200_DSP2_WDMA_BUFFER_LENGTH_SHIFT         0  /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
+#define WM2200_DSP2_WDMA_BUFFER_LENGTH_WIDTH         8  /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */
+
+/*
+ * R2839 (0xB17) - DSP2 Control 20
+ */
+#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_MASK    0x00FF  /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
+#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_SHIFT        0  /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
+#define WM2200_DSP2_WDMA_CHANNEL_ENABLE_WIDTH        8  /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */
+
+/*
+ * R2840 (0xB18) - DSP2 Control 21
+ */
+#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_MASK    0x003F  /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
+#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_SHIFT        0  /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
+#define WM2200_DSP2_RDMA_CHANNEL_ENABLE_WIDTH        6  /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */
+
+/*
+ * R2842 (0xB1A) - DSP2 Control 22
+ */
+#define WM2200_DSP2_DM_SIZE_MASK                0xFFFF  /* DSP2_DM_SIZE - [15:0] */
+#define WM2200_DSP2_DM_SIZE_SHIFT                    0  /* DSP2_DM_SIZE - [15:0] */
+#define WM2200_DSP2_DM_SIZE_WIDTH                   16  /* DSP2_DM_SIZE - [15:0] */
+
+/*
+ * R2843 (0xB1B) - DSP2 Control 23
+ */
+#define WM2200_DSP2_PM_SIZE_MASK                0xFFFF  /* DSP2_PM_SIZE - [15:0] */
+#define WM2200_DSP2_PM_SIZE_SHIFT                    0  /* DSP2_PM_SIZE - [15:0] */
+#define WM2200_DSP2_PM_SIZE_WIDTH                   16  /* DSP2_PM_SIZE - [15:0] */
+
+/*
+ * R2844 (0xB1C) - DSP2 Control 24
+ */
+#define WM2200_DSP2_ZM_SIZE_MASK                0xFFFF  /* DSP2_ZM_SIZE - [15:0] */
+#define WM2200_DSP2_ZM_SIZE_SHIFT                    0  /* DSP2_ZM_SIZE - [15:0] */
+#define WM2200_DSP2_ZM_SIZE_WIDTH                   16  /* DSP2_ZM_SIZE - [15:0] */
+
+/*
+ * R2846 (0xB1E) - DSP2 Control 25
+ */
+#define WM2200_DSP2_PING_FULL                   0x8000  /* DSP2_PING_FULL */
+#define WM2200_DSP2_PING_FULL_MASK              0x8000  /* DSP2_PING_FULL */
+#define WM2200_DSP2_PING_FULL_SHIFT                 15  /* DSP2_PING_FULL */
+#define WM2200_DSP2_PING_FULL_WIDTH                  1  /* DSP2_PING_FULL */
+#define WM2200_DSP2_PONG_FULL                   0x4000  /* DSP2_PONG_FULL */
+#define WM2200_DSP2_PONG_FULL_MASK              0x4000  /* DSP2_PONG_FULL */
+#define WM2200_DSP2_PONG_FULL_SHIFT                 14  /* DSP2_PONG_FULL */
+#define WM2200_DSP2_PONG_FULL_WIDTH                  1  /* DSP2_PONG_FULL */
+#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_MASK   0x00FF  /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
+#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_SHIFT       0  /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
+#define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_WIDTH       8  /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */
+
+/*
+ * R2848 (0xB20) - DSP2 Control 26
+ */
+#define WM2200_DSP2_SCRATCH_0_MASK              0xFFFF  /* DSP2_SCRATCH_0 - [15:0] */
+#define WM2200_DSP2_SCRATCH_0_SHIFT                  0  /* DSP2_SCRATCH_0 - [15:0] */
+#define WM2200_DSP2_SCRATCH_0_WIDTH                 16  /* DSP2_SCRATCH_0 - [15:0] */
+
+/*
+ * R2849 (0xB21) - DSP2 Control 27
+ */
+#define WM2200_DSP2_SCRATCH_1_MASK              0xFFFF  /* DSP2_SCRATCH_1 - [15:0] */
+#define WM2200_DSP2_SCRATCH_1_SHIFT                  0  /* DSP2_SCRATCH_1 - [15:0] */
+#define WM2200_DSP2_SCRATCH_1_WIDTH                 16  /* DSP2_SCRATCH_1 - [15:0] */
+
+/*
+ * R2850 (0xB22) - DSP2 Control 28
+ */
+#define WM2200_DSP2_SCRATCH_2_MASK              0xFFFF  /* DSP2_SCRATCH_2 - [15:0] */
+#define WM2200_DSP2_SCRATCH_2_SHIFT                  0  /* DSP2_SCRATCH_2 - [15:0] */
+#define WM2200_DSP2_SCRATCH_2_WIDTH                 16  /* DSP2_SCRATCH_2 - [15:0] */
+
+/*
+ * R2851 (0xB23) - DSP2 Control 29
+ */
+#define WM2200_DSP2_SCRATCH_3_MASK              0xFFFF  /* DSP2_SCRATCH_3 - [15:0] */
+#define WM2200_DSP2_SCRATCH_3_SHIFT                  0  /* DSP2_SCRATCH_3 - [15:0] */
+#define WM2200_DSP2_SCRATCH_3_WIDTH                 16  /* DSP2_SCRATCH_3 - [15:0] */
+
+/*
+ * R2852 (0xB24) - DSP2 Control 30
+ */
+#define WM2200_DSP2_DBG_CLK_ENA                 0x0008  /* DSP2_DBG_CLK_ENA */
+#define WM2200_DSP2_DBG_CLK_ENA_MASK            0x0008  /* DSP2_DBG_CLK_ENA */
+#define WM2200_DSP2_DBG_CLK_ENA_SHIFT                3  /* DSP2_DBG_CLK_ENA */
+#define WM2200_DSP2_DBG_CLK_ENA_WIDTH                1  /* DSP2_DBG_CLK_ENA */
+#define WM2200_DSP2_SYS_ENA                     0x0004  /* DSP2_SYS_ENA */
+#define WM2200_DSP2_SYS_ENA_MASK                0x0004  /* DSP2_SYS_ENA */
+#define WM2200_DSP2_SYS_ENA_SHIFT                    2  /* DSP2_SYS_ENA */
+#define WM2200_DSP2_SYS_ENA_WIDTH                    1  /* DSP2_SYS_ENA */
+#define WM2200_DSP2_CORE_ENA                    0x0002  /* DSP2_CORE_ENA */
+#define WM2200_DSP2_CORE_ENA_MASK               0x0002  /* DSP2_CORE_ENA */
+#define WM2200_DSP2_CORE_ENA_SHIFT                   1  /* DSP2_CORE_ENA */
+#define WM2200_DSP2_CORE_ENA_WIDTH                   1  /* DSP2_CORE_ENA */
+#define WM2200_DSP2_START                       0x0001  /* DSP2_START */
+#define WM2200_DSP2_START_MASK                  0x0001  /* DSP2_START */
+#define WM2200_DSP2_START_SHIFT                      0  /* DSP2_START */
+#define WM2200_DSP2_START_WIDTH                      1  /* DSP2_START */
+
+/*
+ * R2854 (0xB26) - DSP2 Control 31
+ */
+#define WM2200_DSP2_CLK_RATE_MASK               0x0018  /* DSP2_CLK_RATE - [4:3] */
+#define WM2200_DSP2_CLK_RATE_SHIFT                   3  /* DSP2_CLK_RATE - [4:3] */
+#define WM2200_DSP2_CLK_RATE_WIDTH                   2  /* DSP2_CLK_RATE - [4:3] */
+#define WM2200_DSP2_CLK_AVAIL                   0x0004  /* DSP2_CLK_AVAIL */
+#define WM2200_DSP2_CLK_AVAIL_MASK              0x0004  /* DSP2_CLK_AVAIL */
+#define WM2200_DSP2_CLK_AVAIL_SHIFT                  2  /* DSP2_CLK_AVAIL */
+#define WM2200_DSP2_CLK_AVAIL_WIDTH                  1  /* DSP2_CLK_AVAIL */
+#define WM2200_DSP2_CLK_REQ_MASK                0x0003  /* DSP2_CLK_REQ - [1:0] */
+#define WM2200_DSP2_CLK_REQ_SHIFT                    0  /* DSP2_CLK_REQ - [1:0] */
+#define WM2200_DSP2_CLK_REQ_WIDTH                    2  /* DSP2_CLK_REQ - [1:0] */
+
+#endif
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index 89f2af7..b9c185c 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -18,6 +18,7 @@
 #include <linux/gcd.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/fixed.h>
 #include <linux/slab.h>
@@ -50,13 +51,11 @@ struct wm5100_fll {
 
 /* codec private data */
 struct wm5100_priv {
+	struct device *dev;
 	struct regmap *regmap;
 	struct snd_soc_codec *codec;
 
 	struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
-	struct regulator *cpvdd;
-	struct regulator *dbvdd2;
-	struct regulator *dbvdd3;
 
 	int rev;
 
@@ -73,6 +72,7 @@ struct wm5100_priv {
 	bool jack_detecting;
 	bool jack_mic;
 	int jack_mode;
+	int jack_flips;
 
 	struct wm5100_fll fll[2];
 
@@ -709,6 +709,8 @@ WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
 
 WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
 WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
+SND_SOC_BYTES_MASK("DRC", WM5100_DRC1_CTRL1, 5,
+		   WM5100_DRCL_ENA | WM5100_DRCR_ENA),
 
 WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
 WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
@@ -776,127 +778,48 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int wm5100_cp_ev(struct snd_soc_dapm_widget *w,
-			struct snd_kcontrol *kcontrol,
-			int event)
-{
-	struct snd_soc_codec *codec = w->codec;
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	int ret;
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		ret = regulator_enable(wm5100->cpvdd);
-		if (ret != 0) {
-			dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
-				ret);
-			return ret;
-		}
-		return ret;
-
-	case SND_SOC_DAPM_POST_PMD:
-		ret = regulator_disable_deferred(wm5100->cpvdd, 20);
-		if (ret != 0) {
-			dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
-				ret);
-			return ret;
-		}
-		return ret;
-
-	default:
-		BUG();
-		return 0;
-	}
-}
-
-static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
-			   struct snd_kcontrol *kcontrol,
-			   int event)
-{
-	struct snd_soc_codec *codec = w->codec;
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	struct regulator *regulator;
-	int ret;
-
-	switch (w->shift) {
-	case 2:
-		regulator = wm5100->dbvdd2;
-		break;
-	case 3:
-		regulator = wm5100->dbvdd3;
-		break;
-	default:
-		BUG();
-		return 0;
-	}
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		ret = regulator_enable(regulator);
-		if (ret != 0) {
-			dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
-				w->shift, ret);
-			return ret;
-		}
-		return ret;
-
-	case SND_SOC_DAPM_POST_PMD:
-		ret = regulator_disable(regulator);
-		if (ret != 0) {
-			dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
-				w->shift, ret);
-			return ret;
-		}
-		return ret;
-
-	default:
-		BUG();
-		return 0;
-	}
-}
-
-static void wm5100_log_status3(struct snd_soc_codec *codec, int val)
+static void wm5100_log_status3(struct wm5100_priv *wm5100, int val)
 {
 	if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
-		dev_crit(codec->dev, "Speaker shutdown warning\n");
+		dev_crit(wm5100->dev, "Speaker shutdown warning\n");
 	if (val & WM5100_SPK_SHUTDOWN_EINT)
-		dev_crit(codec->dev, "Speaker shutdown\n");
+		dev_crit(wm5100->dev, "Speaker shutdown\n");
 	if (val & WM5100_CLKGEN_ERR_EINT)
-		dev_crit(codec->dev, "SYSCLK underclocked\n");
+		dev_crit(wm5100->dev, "SYSCLK underclocked\n");
 	if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
-		dev_crit(codec->dev, "ASYNCCLK underclocked\n");
+		dev_crit(wm5100->dev, "ASYNCCLK underclocked\n");
 }
 
-static void wm5100_log_status4(struct snd_soc_codec *codec, int val)
+static void wm5100_log_status4(struct wm5100_priv *wm5100, int val)
 {
 	if (val & WM5100_AIF3_ERR_EINT)
-		dev_err(codec->dev, "AIF3 configuration error\n");
+		dev_err(wm5100->dev, "AIF3 configuration error\n");
 	if (val & WM5100_AIF2_ERR_EINT)
-		dev_err(codec->dev, "AIF2 configuration error\n");
+		dev_err(wm5100->dev, "AIF2 configuration error\n");
 	if (val & WM5100_AIF1_ERR_EINT)
-		dev_err(codec->dev, "AIF1 configuration error\n");
+		dev_err(wm5100->dev, "AIF1 configuration error\n");
 	if (val & WM5100_CTRLIF_ERR_EINT)
-		dev_err(codec->dev, "Control interface error\n");
+		dev_err(wm5100->dev, "Control interface error\n");
 	if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "ISRC2 underclocked\n");
+		dev_err(wm5100->dev, "ISRC2 underclocked\n");
 	if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "ISRC1 underclocked\n");
+		dev_err(wm5100->dev, "ISRC1 underclocked\n");
 	if (val & WM5100_FX_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "FX underclocked\n");
+		dev_err(wm5100->dev, "FX underclocked\n");
 	if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "AIF3 underclocked\n");
+		dev_err(wm5100->dev, "AIF3 underclocked\n");
 	if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "AIF2 underclocked\n");
+		dev_err(wm5100->dev, "AIF2 underclocked\n");
 	if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "AIF1 underclocked\n");
+		dev_err(wm5100->dev, "AIF1 underclocked\n");
 	if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "ASRC underclocked\n");
+		dev_err(wm5100->dev, "ASRC underclocked\n");
 	if (val & WM5100_DAC_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "DAC underclocked\n");
+		dev_err(wm5100->dev, "DAC underclocked\n");
 	if (val & WM5100_ADC_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "ADC underclocked\n");
+		dev_err(wm5100->dev, "ADC underclocked\n");
 	if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
-		dev_err(codec->dev, "Mixer underclocked\n");
+		dev_err(wm5100->dev, "Mixer underclocked\n");
 }
 
 static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
@@ -904,16 +827,17 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
 			  int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
 	ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
 	ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
 		WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
 		WM5100_CLKGEN_ERR_ASYNC_STS;
-	wm5100_log_status3(codec, ret);
+	wm5100_log_status3(wm5100, ret);
 
 	ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
-	wm5100_log_status4(codec, ret);
+	wm5100_log_status4(wm5100, ret);
 
 	return 0;
 }
@@ -924,18 +848,16 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
 SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
 		    0, NULL, 0),
 
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
+
 SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
-		    wm5100_cp_ev,
-		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+		    NULL, 0),
 SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
 		    NULL, 0),
 SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
-		    WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev,
-		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
-		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
-		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+		    WM5100_CP2_BYPASS_SHIFT, 1, NULL, 0),
 
 SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
 		    0, NULL, 0),
@@ -1146,6 +1068,9 @@ SND_SOC_DAPM_POST("Post", wm5100_post_ev),
 };
 
 static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
+	{ "CP1", NULL, "CPVDD" },
+	{ "CP2 Active", NULL, "CPVDD" },
+
 	{ "IN1L", NULL, "SYSCLK" },
 	{ "IN1R", NULL, "SYSCLK" },
 	{ "IN2L", NULL, "SYSCLK" },
@@ -1308,10 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
 	{ "PWM2", NULL, "PWM2 Driver" },
 };
 
-static struct {
-	int reg;
-	int val;
-} wm5100_reva_patches[] = {
+static const __devinitdata struct reg_default wm5100_reva_patches[] = {
 	{ WM5100_AUDIO_IF_1_10, 0 },
 	{ WM5100_AUDIO_IF_1_11, 1 },
 	{ WM5100_AUDIO_IF_1_12, 2 },
@@ -1343,80 +1265,6 @@ static struct {
 	{ WM5100_AUDIO_IF_3_19, 1 },
 };
 
-static int wm5100_set_bias_level(struct snd_soc_codec *codec,
-				 enum snd_soc_bias_level level)
-{
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	int ret, i;
-
-	switch (level) {
-	case SND_SOC_BIAS_ON:
-		break;
-
-	case SND_SOC_BIAS_PREPARE:
-		break;
-
-	case SND_SOC_BIAS_STANDBY:
-		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
-						    wm5100->core_supplies);
-			if (ret != 0) {
-				dev_err(codec->dev,
-					"Failed to enable supplies: %d\n",
-					ret);
-				return ret;
-			}
-
-			if (wm5100->pdata.ldo_ena) {
-				gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
-							1);
-				msleep(2);
-			}
-
-			regcache_cache_only(wm5100->regmap, false);
-
-			switch (wm5100->rev) {
-			case 0:
-				regcache_cache_bypass(wm5100->regmap, true);
-				snd_soc_write(codec, 0x11, 0x3);
-				snd_soc_write(codec, 0x203, 0xc);
-				snd_soc_write(codec, 0x206, 0);
-				snd_soc_write(codec, 0x207, 0xf0);
-				snd_soc_write(codec, 0x208, 0x3c);
-				snd_soc_write(codec, 0x209, 0);
-				snd_soc_write(codec, 0x211, 0x20d8);
-				snd_soc_write(codec, 0x11, 0);
-
-				for (i = 0;
-				     i < ARRAY_SIZE(wm5100_reva_patches);
-				     i++)
-					snd_soc_write(codec,
-						      wm5100_reva_patches[i].reg,
-						      wm5100_reva_patches[i].val);
-				regcache_cache_bypass(wm5100->regmap, false);
-				break;
-			default:
-				break;
-			}
-
-			regcache_sync(wm5100->regmap);
-		}
-		break;
-
-	case SND_SOC_BIAS_OFF:
-		regcache_cache_only(wm5100->regmap, true);
-		regcache_mark_dirty(wm5100->regmap);
-		if (wm5100->pdata.ldo_ena)
-			gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
-		regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
-				       wm5100->core_supplies);
-		break;
-	}
-	codec->dapm.bias_level = level;
-
-	return 0;
-}
-
 static int wm5100_dai_to_base(struct snd_soc_dai *dai)
 {
 	switch (dai->id) {
@@ -1944,6 +1792,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 
 	if (!Fout) {
 		dev_dbg(codec->dev, "FLL%d disabled", fll_id);
+		if (fll->fout)
+			pm_runtime_put(codec->dev);
 		fll->fout = 0;
 		snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
 		return 0;
@@ -1988,6 +1838,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	/* Clear any pending completions */
 	try_wait_for_completion(&fll->lock);
 
+	pm_runtime_get_sync(codec->dev);
+
 	snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
 
 	if (i2c->irq)
@@ -2022,6 +1874,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	}
 	if (i == timeout) {
 		dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
+		pm_runtime_put(codec->dev);
 		return -ETIMEDOUT;
 	}
 
@@ -2124,55 +1977,73 @@ static int wm5100_dig_vu[] = {
 	WM5100_DAC_DIGITAL_VOLUME_6R,
 };
 
-static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode)
+static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
 	struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode];
 
 	BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes));
 
 	gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
-	snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1,
-			    WM5100_ACCDET_BIAS_SRC_MASK |
-			    WM5100_ACCDET_SRC,
-			    (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
-			    mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
-	snd_soc_update_bits(codec, WM5100_MISC_CONTROL,
-			    WM5100_HPCOM_SRC,
-			    mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
+	regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1,
+			   WM5100_ACCDET_BIAS_SRC_MASK |
+			   WM5100_ACCDET_SRC,
+			   (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
+			   mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
+	regmap_update_bits(wm5100->regmap, WM5100_MISC_CONTROL,
+			   WM5100_HPCOM_SRC,
+			   mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
 
 	wm5100->jack_mode = the_mode;
 
-	dev_dbg(codec->dev, "Set microphone polarity to %d\n",
+	dev_dbg(wm5100->dev, "Set microphone polarity to %d\n",
 		wm5100->jack_mode);
 }
 
-static void wm5100_micd_irq(struct snd_soc_codec *codec)
+static void wm5100_report_headphone(struct wm5100_priv *wm5100)
 {
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	int val;
+	dev_dbg(wm5100->dev, "Headphone detected\n");
+	wm5100->jack_detecting = false;
+	snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
+			    SND_JACK_HEADPHONE);
+
+	/* Increase the detection rate a bit for responsiveness. */
+	regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
+			   WM5100_ACCDET_RATE_MASK,
+			   7 << WM5100_ACCDET_RATE_SHIFT);
+}
 
-	val = snd_soc_read(codec, WM5100_MIC_DETECT_3);
+static void wm5100_micd_irq(struct wm5100_priv *wm5100)
+{
+	unsigned int val;
+	int ret;
 
-	dev_dbg(codec->dev, "Microphone event: %x\n", val);
+	ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val);
+	if (ret != 0) {
+		dev_err(wm5100->dev, "Failed to read micropone status: %d\n",
+			ret);
+		return;
+	}
+
+	dev_dbg(wm5100->dev, "Microphone event: %x\n", val);
 
 	if (!(val & WM5100_ACCDET_VALID)) {
-		dev_warn(codec->dev, "Microphone detection state invalid\n");
+		dev_warn(wm5100->dev, "Microphone detection state invalid\n");
 		return;
 	}
 
 	/* No accessory, reset everything and report removal */
 	if (!(val & WM5100_ACCDET_STS)) {
-		dev_dbg(codec->dev, "Jack removal detected\n");
+		dev_dbg(wm5100->dev, "Jack removal detected\n");
 		wm5100->jack_mic = false;
 		wm5100->jack_detecting = true;
+		wm5100->jack_flips = 0;
 		snd_soc_jack_report(wm5100->jack, 0,
 				    SND_JACK_LINEOUT | SND_JACK_HEADSET |
 				    SND_JACK_BTN_0);
 
-		snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
-				    WM5100_ACCDET_RATE_MASK,
-				    WM5100_ACCDET_RATE_MASK);
+		regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
+				   WM5100_ACCDET_RATE_MASK,
+				   WM5100_ACCDET_RATE_MASK);
 		return;
 	}
 
@@ -2182,7 +2053,7 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
 	 */
 	if (val & 0x400) {
 		if (wm5100->jack_detecting) {
-			dev_dbg(codec->dev, "Microphone detected\n");
+			dev_dbg(wm5100->dev, "Microphone detected\n");
 			wm5100->jack_mic = true;
 			wm5100->jack_detecting = false;
 			snd_soc_jack_report(wm5100->jack,
@@ -2191,11 +2062,11 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
 
 			/* Increase poll rate to give better responsiveness
 			 * for buttons */
-			snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
-					    WM5100_ACCDET_RATE_MASK,
-					    5 << WM5100_ACCDET_RATE_SHIFT);
+			regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
+					   WM5100_ACCDET_RATE_MASK,
+					   5 << WM5100_ACCDET_RATE_SHIFT);
 		} else {
-			dev_dbg(codec->dev, "Mic button up\n");
+			dev_dbg(wm5100->dev, "Mic button up\n");
 			snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0);
 		}
 
@@ -2205,10 +2076,16 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
 	/* If we detected a lower impedence during initial startup
 	 * then we probably have the wrong polarity, flip it.  Don't
 	 * do this for the lowest impedences to speed up detection of
-	 * plain headphones.
+	 * plain headphones and give up if neither polarity looks
+	 * sensible.
 	 */
 	if (wm5100->jack_detecting && (val & 0x3f8)) {
-		wm5100_set_detect_mode(codec, !wm5100->jack_mode);
+		wm5100->jack_flips++;
+
+		if (wm5100->jack_flips > 1)
+			wm5100_report_headphone(wm5100);
+		else
+			wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
 
 		return;
 	}
@@ -2218,21 +2095,11 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec)
 	 */
 	if (val & 0x3fc) {
 		if (wm5100->jack_mic) {
-			dev_dbg(codec->dev, "Mic button detected\n");
+			dev_dbg(wm5100->dev, "Mic button detected\n");
 			snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
 					    SND_JACK_BTN_0);
 		} else if (wm5100->jack_detecting) {
-			dev_dbg(codec->dev, "Headphone detected\n");
-			wm5100->jack_detecting = false;
-			snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
-					    SND_JACK_HEADPHONE);
-
-			/* Increase the detection rate a bit for
-			 * responsiveness.
-			 */
-			snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
-					    WM5100_ACCDET_RATE_MASK,
-					    7 << WM5100_ACCDET_RATE_SHIFT);
+			wm5100_report_headphone(wm5100);
 		}
 	}
 }
@@ -2244,8 +2111,9 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 	if (jack) {
 		wm5100->jack = jack;
 		wm5100->jack_detecting = true;
+		wm5100->jack_flips = 0;
 
-		wm5100_set_detect_mode(codec, 0);
+		wm5100_set_detect_mode(wm5100, 0);
 
 		/* Slowest detection rate, gives debounce for initial
 		 * detection */
@@ -2284,52 +2152,70 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
 
 static irqreturn_t wm5100_irq(int irq, void *data)
 {
-	struct snd_soc_codec *codec = data;
-	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
+	struct wm5100_priv *wm5100 = data;
 	irqreturn_t status = IRQ_NONE;
-	int irq_val;
+	unsigned int irq_val, mask_val;
+	int ret;
 
-	irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3);
-	if (irq_val < 0) {
-		dev_err(codec->dev, "Failed to read IRQ status 3: %d\n",
-			irq_val);
+	ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, &irq_val);
+	if (ret < 0) {
+		dev_err(wm5100->dev, "Failed to read IRQ status 3: %d\n",
+			ret);
 		irq_val = 0;
 	}
-	irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
 
-	snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val);
+	ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3_MASK,
+			  &mask_val);
+	if (ret < 0) {
+		dev_err(wm5100->dev, "Failed to read IRQ mask 3: %d\n",
+			ret);
+		mask_val = 0xffff;
+	}
+
+	irq_val &= ~mask_val;
+
+	regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, irq_val);
 
 	if (irq_val)
 		status = IRQ_HANDLED;
 
-	wm5100_log_status3(codec, irq_val);
+	wm5100_log_status3(wm5100, irq_val);
 
 	if (irq_val & WM5100_FLL1_LOCK_EINT) {
-		dev_dbg(codec->dev, "FLL1 locked\n");
+		dev_dbg(wm5100->dev, "FLL1 locked\n");
 		complete(&wm5100->fll[0].lock);
 	}
 	if (irq_val & WM5100_FLL2_LOCK_EINT) {
-		dev_dbg(codec->dev, "FLL2 locked\n");
+		dev_dbg(wm5100->dev, "FLL2 locked\n");
 		complete(&wm5100->fll[1].lock);
 	}
 
 	if (irq_val & WM5100_ACCDET_EINT)
-		wm5100_micd_irq(codec);
+		wm5100_micd_irq(wm5100);
 
-	irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4);
-	if (irq_val < 0) {
-		dev_err(codec->dev, "Failed to read IRQ status 4: %d\n",
-			irq_val);
+	ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, &irq_val);
+	if (ret < 0) {
+		dev_err(wm5100->dev, "Failed to read IRQ status 4: %d\n",
+			ret);
 		irq_val = 0;
 	}
-	irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK);
+
+	ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4_MASK,
+			  &mask_val);
+	if (ret < 0) {
+		dev_err(wm5100->dev, "Failed to read IRQ mask 4: %d\n",
+			ret);
+		mask_val = 0xffff;
+	}
+
+	irq_val &= ~mask_val;
 
 	if (irq_val)
 		status = IRQ_HANDLED;
 
-	snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val);
+	regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, irq_val);
 
-	wm5100_log_status4(codec, irq_val);
+	wm5100_log_status4(wm5100, irq_val);
 
 	return status;
 }
@@ -2454,7 +2340,7 @@ static int wm5100_probe(struct snd_soc_codec *codec)
 {
 	struct i2c_client *i2c = to_i2c_client(codec->dev);
 	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	int ret, i, irq_flags;
+	int ret, i;
 
 	wm5100->codec = codec;
 	codec->control_data = wm5100->regmap;
@@ -2465,9 +2351,6 @@ static int wm5100_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
-	regcache_cache_only(wm5100->regmap, true);
-
-
 	for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
 		snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
 				    WM5100_OUT_VU);
@@ -2478,60 +2361,10 @@ static int wm5100_probe(struct snd_soc_codec *codec)
 
 	/* TODO: check if we're symmetric */
 
-	if (i2c->irq) {
-		if (wm5100->pdata.irq_flags)
-			irq_flags = wm5100->pdata.irq_flags;
-		else
-			irq_flags = IRQF_TRIGGER_LOW;
-
-		irq_flags |= IRQF_ONESHOT;
-
-		if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
-			ret = request_threaded_irq(i2c->irq, NULL,
-						   wm5100_edge_irq,
-						   irq_flags, "wm5100", codec);
-		else
-			ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
-						   irq_flags, "wm5100", codec);
-
-		if (ret != 0) {
-			dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
-				i2c->irq, ret);
-		} else {
-			/* Enable default interrupts */
-			snd_soc_update_bits(codec,
-					    WM5100_INTERRUPT_STATUS_3_MASK,
-					    WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
-					    WM5100_IM_SPK_SHUTDOWN_EINT |
-					    WM5100_IM_ASRC2_LOCK_EINT |
-					    WM5100_IM_ASRC1_LOCK_EINT |
-					    WM5100_IM_FLL2_LOCK_EINT |
-					    WM5100_IM_FLL1_LOCK_EINT |
-					    WM5100_CLKGEN_ERR_EINT |
-					    WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
-
-			snd_soc_update_bits(codec,
-					    WM5100_INTERRUPT_STATUS_4_MASK,
-					    WM5100_AIF3_ERR_EINT |
-					    WM5100_AIF2_ERR_EINT |
-					    WM5100_AIF1_ERR_EINT |
-					    WM5100_CTRLIF_ERR_EINT |
-					    WM5100_ISRC2_UNDERCLOCKED_EINT |
-					    WM5100_ISRC1_UNDERCLOCKED_EINT |
-					    WM5100_FX_UNDERCLOCKED_EINT |
-					    WM5100_AIF3_UNDERCLOCKED_EINT |
-					    WM5100_AIF2_UNDERCLOCKED_EINT |
-					    WM5100_AIF1_UNDERCLOCKED_EINT |
-					    WM5100_ASRC_UNDERCLOCKED_EINT |
-					    WM5100_DAC_UNDERCLOCKED_EINT |
-					    WM5100_ADC_UNDERCLOCKED_EINT |
-					    WM5100_MIXER_UNDERCLOCKED_EINT, 0);
-		}
-	} else {
+	if (i2c->irq)
 		snd_soc_dapm_new_controls(&codec->dapm,
 					  wm5100_dapm_widgets_noirq,
 					  ARRAY_SIZE(wm5100_dapm_widgets_noirq));
-	}
 
 	if (wm5100->pdata.hp_pol) {
 		ret = gpio_request_one(wm5100->pdata.hp_pol,
@@ -2543,19 +2376,9 @@ static int wm5100_probe(struct snd_soc_codec *codec)
 		}
 	}
 
-	/* We'll get woken up again when the system has something useful
-	 * for us to do.
-	 */
-	if (wm5100->pdata.ldo_ena)
-		gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
-	regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
-			       wm5100->core_supplies);
-
 	return 0;
 
 err_gpio:
-	if (i2c->irq)
-		free_irq(i2c->irq, codec);
 
 	return ret;
 }
@@ -2563,14 +2386,11 @@ err_gpio:
 static int wm5100_remove(struct snd_soc_codec *codec)
 {
 	struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
-	struct i2c_client *i2c = to_i2c_client(codec->dev);
 
-	wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
 	if (wm5100->pdata.hp_pol) {
 		gpio_free(wm5100->pdata.hp_pol);
 	}
-	if (i2c->irq)
-		free_irq(i2c->irq, codec);
+
 	return 0;
 }
 
@@ -2587,7 +2407,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
 
 	.set_sysclk = wm5100_set_sysclk,
 	.set_pll = wm5100_set_fll,
-	.set_bias_level = wm5100_set_bias_level,
 	.idle_bias_off = 1,
 	.reg_cache_size = WM5100_MAX_REGISTER,
 	.volatile_register = wm5100_soc_volatile,
@@ -2626,13 +2445,15 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 	struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
 	struct wm5100_priv *wm5100;
 	unsigned int reg;
-	int ret, i;
+	int ret, i, irq_flags;
 
 	wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv),
 			      GFP_KERNEL);
 	if (wm5100 == NULL)
 		return -ENOMEM;
 
+	wm5100->dev = &i2c->dev;
+
 	wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap);
 	if (IS_ERR(wm5100->regmap)) {
 		ret = PTR_ERR(wm5100->regmap);
@@ -2652,41 +2473,21 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 	for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
 		wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
 
-	ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
-				 wm5100->core_supplies);
+	ret = devm_regulator_bulk_get(&i2c->dev,
+				      ARRAY_SIZE(wm5100->core_supplies),
+				      wm5100->core_supplies);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
 			ret);
 		goto err_regmap;
 	}
 
-	wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
-	if (IS_ERR(wm5100->cpvdd)) {
-		ret = PTR_ERR(wm5100->cpvdd);
-		dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
-		goto err_core;
-	}
-
-	wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
-	if (IS_ERR(wm5100->dbvdd2)) {
-		ret = PTR_ERR(wm5100->dbvdd2);
-		dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
-		goto err_cpvdd;
-	}
-
-	wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
-	if (IS_ERR(wm5100->dbvdd3)) {
-		ret = PTR_ERR(wm5100->dbvdd3);
-		dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
-		goto err_dbvdd2;
-	}
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
 				    wm5100->core_supplies);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
 			ret);
-		goto err_dbvdd3;
+		goto err_regmap;
 	}
 
 	if (wm5100->pdata.ldo_ena) {
@@ -2712,7 +2513,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 
 	ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg);
 	if (ret < 0) {
-		dev_err(&i2c->dev, "Failed to read ID register\n");
+		dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
 		goto err_reset;
 	}
 	switch (reg) {
@@ -2741,6 +2542,22 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 		goto err_reset;
 	}
 
+	switch (wm5100->rev) {
+	case 0:
+		ret = regmap_register_patch(wm5100->regmap,
+					    wm5100_reva_patches,
+					    ARRAY_SIZE(wm5100_reva_patches));
+		if (ret != 0) {
+			dev_err(&i2c->dev, "Failed to register patches: %d\n",
+				ret);
+			goto err_reset;
+		}
+		break;
+	default:
+		break;
+	}
+
+
 	wm5100_init_gpio(i2c);
 
 	for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
@@ -2761,6 +2578,62 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 				    WM5100_IN1_DMIC_SUP_SHIFT));
 	}
 
+	if (i2c->irq) {
+		if (wm5100->pdata.irq_flags)
+			irq_flags = wm5100->pdata.irq_flags;
+		else
+			irq_flags = IRQF_TRIGGER_LOW;
+
+		irq_flags |= IRQF_ONESHOT;
+
+		if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
+			ret = request_threaded_irq(i2c->irq, NULL,
+						   wm5100_edge_irq, irq_flags,
+						   "wm5100", wm5100);
+		else
+			ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
+						   irq_flags, "wm5100",
+						   wm5100);
+
+		if (ret != 0) {
+			dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+				i2c->irq, ret);
+		} else {
+			/* Enable default interrupts */
+			regmap_update_bits(wm5100->regmap,
+					   WM5100_INTERRUPT_STATUS_3_MASK,
+					   WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
+					   WM5100_IM_SPK_SHUTDOWN_EINT |
+					   WM5100_IM_ASRC2_LOCK_EINT |
+					   WM5100_IM_ASRC1_LOCK_EINT |
+					   WM5100_IM_FLL2_LOCK_EINT |
+					   WM5100_IM_FLL1_LOCK_EINT |
+					   WM5100_CLKGEN_ERR_EINT |
+					   WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
+
+			regmap_update_bits(wm5100->regmap,
+					   WM5100_INTERRUPT_STATUS_4_MASK,
+					   WM5100_AIF3_ERR_EINT |
+					   WM5100_AIF2_ERR_EINT |
+					   WM5100_AIF1_ERR_EINT |
+					   WM5100_CTRLIF_ERR_EINT |
+					   WM5100_ISRC2_UNDERCLOCKED_EINT |
+					   WM5100_ISRC1_UNDERCLOCKED_EINT |
+					   WM5100_FX_UNDERCLOCKED_EINT |
+					   WM5100_AIF3_UNDERCLOCKED_EINT |
+					   WM5100_AIF2_UNDERCLOCKED_EINT |
+					   WM5100_AIF1_UNDERCLOCKED_EINT |
+					   WM5100_ASRC_UNDERCLOCKED_EINT |
+					   WM5100_DAC_UNDERCLOCKED_EINT |
+					   WM5100_ADC_UNDERCLOCKED_EINT |
+					   WM5100_MIXER_UNDERCLOCKED_EINT, 0);
+		}
+	}
+
+	pm_runtime_set_active(&i2c->dev);
+	pm_runtime_enable(&i2c->dev);
+	pm_request_idle(&i2c->dev);
+
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm5100, wm5100_dai,
 				     ARRAY_SIZE(wm5100_dai));
@@ -2772,9 +2645,11 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
 	return ret;
 
 err_reset:
+	if (i2c->irq)
+		free_irq(i2c->irq, wm5100);
 	wm5100_free_gpio(i2c);
 	if (wm5100->pdata.reset) {
-		gpio_set_value_cansleep(wm5100->pdata.reset, 1);
+		gpio_set_value_cansleep(wm5100->pdata.reset, 0);
 		gpio_free(wm5100->pdata.reset);
 	}
 err_ldo:
@@ -2785,45 +2660,78 @@ err_ldo:
 err_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
 			       wm5100->core_supplies);
-err_dbvdd3:
-	regulator_put(wm5100->dbvdd3);
-err_dbvdd2:
-	regulator_put(wm5100->dbvdd2);
-err_cpvdd:
-	regulator_put(wm5100->cpvdd);
-err_core:
-	regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
-			    wm5100->core_supplies);
 err_regmap:
 	regmap_exit(wm5100->regmap);
 err:
 	return ret;
 }
 
-static __devexit int wm5100_i2c_remove(struct i2c_client *client)
+static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
 {
-	struct wm5100_priv *wm5100 = i2c_get_clientdata(client);
+	struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
 
-	snd_soc_unregister_codec(&client->dev);
-	wm5100_free_gpio(client);
+	snd_soc_unregister_codec(&i2c->dev);
+	if (i2c->irq)
+		free_irq(i2c->irq, wm5100);
+	wm5100_free_gpio(i2c);
 	if (wm5100->pdata.reset) {
-		gpio_set_value_cansleep(wm5100->pdata.reset, 1);
+		gpio_set_value_cansleep(wm5100->pdata.reset, 0);
 		gpio_free(wm5100->pdata.reset);
 	}
 	if (wm5100->pdata.ldo_ena) {
 		gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
 		gpio_free(wm5100->pdata.ldo_ena);
 	}
-	regulator_put(wm5100->dbvdd3);
-	regulator_put(wm5100->dbvdd2);
-	regulator_put(wm5100->cpvdd);
-	regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
-			    wm5100->core_supplies);
 	regmap_exit(wm5100->regmap);
 
 	return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int wm5100_runtime_suspend(struct device *dev)
+{
+	struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
+
+	regcache_cache_only(wm5100->regmap, true);
+	regcache_mark_dirty(wm5100->regmap);
+	if (wm5100->pdata.ldo_ena)
+		gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
+	regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
+			       wm5100->core_supplies);
+
+	return 0;
+}
+
+static int wm5100_runtime_resume(struct device *dev)
+{
+	struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
+				    wm5100->core_supplies);
+	if (ret != 0) {
+		dev_err(dev, "Failed to enable supplies: %d\n",
+			ret);
+		return ret;
+	}
+
+	if (wm5100->pdata.ldo_ena) {
+		gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1);
+		msleep(2);
+	}
+
+	regcache_cache_only(wm5100->regmap, false);
+	regcache_sync(wm5100->regmap);
+
+	return 0;
+}
+#endif
+
+static struct dev_pm_ops wm5100_pm = {
+	SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume,
+			   NULL)
+};
+
 static const struct i2c_device_id wm5100_i2c_id[] = {
 	{ "wm5100", 0 },
 	{ }
@@ -2834,6 +2742,7 @@ static struct i2c_driver wm5100_i2c_driver = {
 	.driver = {
 		.name = "wm5100",
 		.owner = THIS_MODULE,
+		.pm = &wm5100_pm,
 	},
 	.probe =    wm5100_i2c_probe,
 	.remove =   __devexit_p(wm5100_i2c_remove),
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 8821af7..a32caa7 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/of_device.h>
@@ -41,7 +42,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
 
 /* codec private data */
 struct wm8731_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
 	unsigned int sysclk;
 	int sysclk_type;
@@ -52,16 +53,30 @@ struct wm8731_priv {
 
 /*
  * wm8731 register cache
- * We can't read the WM8731 register space when we are
- * using 2 wire for device control, so we cache them instead.
- * There is no point in caching the reset register
  */
-static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
-	0x0097, 0x0097, 0x0079, 0x0079,
-	0x000a, 0x0008, 0x009f, 0x000a,
-	0x0000, 0x0000
+static const struct reg_default wm8731_reg_defaults[] = {
+	{ 0, 0x0097 },
+	{ 1, 0x0097 },
+	{ 2, 0x0079 },
+	{ 3, 0x0079 },
+	{ 4, 0x000a },
+	{ 5, 0x0008 },
+	{ 6, 0x009f },
+	{ 7, 0x000a },
+	{ 8, 0x0000 },
+	{ 9, 0x0000 },
 };
 
+static bool wm8731_volatile(struct device *dev, unsigned int reg)
+{
+	return reg == WM8731_RESET;
+}
+
+static bool wm8731_writeable(struct device *dev, unsigned int reg)
+{
+	return reg <= WM8731_RESET;
+}
+
 #define wm8731_reset(c)	snd_soc_write(c, WM8731_RESET, 0)
 
 static const char *wm8731_input_select[] = {"Line In", "Mic"};
@@ -441,7 +456,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 			if (ret != 0)
 				return ret;
 
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8731->regmap);
 		}
 
 		/* Clear PWROFF, gate CLKOUT, everything else as-is */
@@ -452,7 +467,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 		snd_soc_write(codec, WM8731_PWR, 0xffff);
 		regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
 				       wm8731->supplies);
-		codec->cache_sync = 1;
+		regcache_mark_dirty(wm8731->regmap);
 		break;
 	}
 	codec->dapm.bias_level = level;
@@ -513,7 +528,8 @@ static int wm8731_probe(struct snd_soc_codec *codec)
 	struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
 	int ret = 0, i;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type);
+	codec->control_data = wm8731->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -585,9 +601,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = {
 	.suspend =	wm8731_suspend,
 	.resume =	wm8731_resume,
 	.set_bias_level = wm8731_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8731_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8731_reg,
 	.dapm_widgets = wm8731_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets),
 	.dapm_routes = wm8731_intercon,
@@ -603,6 +616,19 @@ static const struct of_device_id wm8731_of_match[] = {
 
 MODULE_DEVICE_TABLE(of, wm8731_of_match);
 
+static const struct regmap_config wm8731_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.max_register = WM8731_RESET,
+	.volatile_reg = wm8731_volatile,
+	.writeable_reg = wm8731_writeable,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8731_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults),
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8731_spi_probe(struct spi_device *spi)
 {
@@ -613,20 +639,39 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
 	if (wm8731 == NULL)
 		return -ENOMEM;
 
-	wm8731->control_type = SND_SOC_SPI;
+	wm8731->regmap = regmap_init_spi(spi, &wm8731_regmap);
+	if (IS_ERR(wm8731->regmap)) {
+		ret = PTR_ERR(wm8731->regmap);
+		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
 	spi_set_drvdata(spi, wm8731);
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8731, &wm8731_dai, 1);
-	if (ret < 0)
-		kfree(wm8731);
+	if (ret != 0) {
+		dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
+		goto err_regmap;
+	}
+
+	return 0;
+
+err_regmap:
+	regmap_exit(wm8731->regmap);
+err:
+	kfree(wm8731);
 	return ret;
 }
 
 static int __devexit wm8731_spi_remove(struct spi_device *spi)
 {
+	struct wm8731_priv *wm8731 = spi_get_drvdata(spi);
+
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+	regmap_exit(wm8731->regmap);
+	kfree(wm8731);
 	return 0;
 }
 
@@ -652,20 +697,38 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
 	if (wm8731 == NULL)
 		return -ENOMEM;
 
+	wm8731->regmap = regmap_init_i2c(i2c, &wm8731_regmap);
+	if (IS_ERR(wm8731->regmap)) {
+		ret = PTR_ERR(wm8731->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
 	i2c_set_clientdata(i2c, wm8731);
-	wm8731->control_type = SND_SOC_I2C;
 
-	ret =  snd_soc_register_codec(&i2c->dev,
+	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8731, &wm8731_dai, 1);
-	if (ret < 0)
-		kfree(wm8731);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+		goto err_regmap;
+	}
+
+	return 0;
+
+err_regmap:
+	regmap_exit(wm8731->regmap);
+err:
+	kfree(wm8731);
 	return ret;
 }
 
 static __devexit int wm8731_i2c_remove(struct i2c_client *client)
 {
+	struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	regmap_exit(wm8731->regmap);
+	kfree(wm8731);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index ff95e62c..4fe9d19 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -599,7 +599,7 @@ static int wm8737_probe(struct snd_soc_codec *codec)
 	/* Bias level configuration will have done an extra enable */
 	regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 
-	snd_soc_add_controls(codec, wm8737_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8737_snd_controls,
 			     ARRAY_SIZE(wm8737_snd_controls));
 	wm8737_add_widgets(codec);
 
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index b114c19..21ed75d 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -39,6 +39,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -65,28 +66,86 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec,
  * We can't read the WM8753 register space when we
  * are using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8753_reg[] = {
-	0x0000, 0x0008, 0x0000, 0x000a,
-	0x000a, 0x0033, 0x0000, 0x0007,
-	0x00ff, 0x00ff, 0x000f, 0x000f,
-	0x007b, 0x0000, 0x0032, 0x0000,
-	0x00c3, 0x00c3, 0x00c0, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0055, 0x0005, 0x0050, 0x0055,
-	0x0050, 0x0055, 0x0050, 0x0055,
-	0x0079, 0x0079, 0x0079, 0x0079,
-	0x0079, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0097, 0x0097, 0x0000,
-	0x0004, 0x0000, 0x0083, 0x0024,
-	0x01ba, 0x0000, 0x0083, 0x0024,
-	0x01ba, 0x0000, 0x0000, 0x0000
+static const struct reg_default wm8753_reg_defaults[] = {
+	{ 0x00, 0x0000 },
+	{ 0x01, 0x0008 },
+	{ 0x02, 0x0000 },
+	{ 0x03, 0x000a },
+	{ 0x04, 0x000a },
+	{ 0x05, 0x0033 },
+	{ 0x06, 0x0000 },
+	{ 0x07, 0x0007 },
+	{ 0x08, 0x00ff },
+	{ 0x09, 0x00ff },
+	{ 0x0a, 0x000f },
+	{ 0x0b, 0x000f },
+	{ 0x0c, 0x007b },
+	{ 0x0d, 0x0000 },
+	{ 0x0e, 0x0032 },
+	{ 0x0f, 0x0000 },
+	{ 0x10, 0x00c3 },
+	{ 0x11, 0x00c3 },
+	{ 0x12, 0x00c0 },
+	{ 0x13, 0x0000 },
+	{ 0x14, 0x0000 },
+	{ 0x15, 0x0000 },
+	{ 0x16, 0x0000 },
+	{ 0x17, 0x0000 },
+	{ 0x18, 0x0000 },
+	{ 0x19, 0x0000 },
+	{ 0x1a, 0x0000 },
+	{ 0x1b, 0x0000 },
+	{ 0x1c, 0x0000 },
+	{ 0x1d, 0x0000 },
+	{ 0x1e, 0x0000 },
+	{ 0x1f, 0x0000 },
+	{ 0x20, 0x0055 },
+	{ 0x21, 0x0005 },
+	{ 0x22, 0x0050 },
+	{ 0x23, 0x0055 },
+	{ 0x24, 0x0050 },
+	{ 0x25, 0x0055 },
+	{ 0x26, 0x0050 },
+	{ 0x27, 0x0055 },
+	{ 0x28, 0x0079 },
+	{ 0x29, 0x0079 },
+	{ 0x2a, 0x0079 },
+	{ 0x2b, 0x0079 },
+	{ 0x2c, 0x0079 },
+	{ 0x2d, 0x0000 },
+	{ 0x2e, 0x0000 },
+	{ 0x2f, 0x0000 },
+	{ 0x30, 0x0000 },
+	{ 0x31, 0x0097 },
+	{ 0x32, 0x0097 },
+	{ 0x33, 0x0000 },
+	{ 0x34, 0x0004 },
+	{ 0x35, 0x0000 },
+	{ 0x36, 0x0083 },
+	{ 0x37, 0x0024 },
+	{ 0x38, 0x01ba },
+	{ 0x39, 0x0000 },
+	{ 0x3a, 0x0083 },
+	{ 0x3b, 0x0024 },
+	{ 0x3c, 0x01ba },
+	{ 0x3d, 0x0000 },
+	{ 0x3e, 0x0000 },
+	{ 0x3f, 0x0000 },
 };
 
+static bool wm8753_volatile(struct device *dev, unsigned int reg)
+{
+	return reg == WM8753_RESET;
+}
+
+static bool wm8753_writeable(struct device *dev, unsigned int reg)
+{
+	return reg <= WM8753_ADCTL2;
+}
+
 /* codec private data */
 struct wm8753_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	unsigned int sysclk;
 	unsigned int pcmclk;
 
@@ -1383,25 +1442,15 @@ static void wm8753_work(struct work_struct *work)
 static int wm8753_suspend(struct snd_soc_codec *codec)
 {
 	wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	codec->cache_sync = 1;
 	return 0;
 }
 
 static int wm8753_resume(struct snd_soc_codec *codec)
 {
-	u16 *reg_cache = codec->reg_cache;
-	int i;
-
-	/* Sync reg_cache with the hardware */
-	for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
-		if (i == WM8753_RESET)
-			continue;
-
-		/* No point in writing hardware default values back */
-		if (reg_cache[i] == wm8753_reg[i])
-			continue;
+	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 
-		snd_soc_write(codec, i, reg_cache[i]);
-	}
+	regcache_sync(wm8753->regmap);
 
 	wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
@@ -1423,7 +1472,8 @@ static int wm8753_probe(struct snd_soc_codec *codec)
 
 	INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
+	codec->control_data = wm8753->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -1473,9 +1523,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
 	.suspend =	wm8753_suspend,
 	.resume =	wm8753_resume,
 	.set_bias_level = wm8753_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8753_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8753_reg,
 
 	.controls = wm8753_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8753_snd_controls),
@@ -1491,6 +1538,19 @@ static const struct of_device_id wm8753_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, wm8753_of_match);
 
+static const struct regmap_config wm8753_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.max_register = WM8753_ADCTL2,
+	.writeable_reg = wm8753_writeable,
+	.volatile_reg = wm8753_volatile,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8753_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults),
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8753_spi_probe(struct spi_device *spi)
 {
@@ -1501,20 +1561,36 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi)
 	if (wm8753 == NULL)
 		return -ENOMEM;
 
-	wm8753->control_type = SND_SOC_SPI;
 	spi_set_drvdata(spi, wm8753);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
-	if (ret < 0)
-		kfree(wm8753);
+	wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap);
+	if (IS_ERR(wm8753->regmap)) {
+		ret = PTR_ERR(wm8753->regmap);
+		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
+	ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753,
+				     wm8753_dai, ARRAY_SIZE(wm8753_dai));
+	if (ret != 0) {
+		dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
+		goto err_regmap;
+	}
+err_regmap:
+	regmap_exit(wm8753->regmap);
+err:
+	kfree(wm8753);
 	return ret;
 }
 
 static int __devexit wm8753_spi_remove(struct spi_device *spi)
 {
+	struct wm8753_priv *wm8753 = spi_get_drvdata(spi);
+
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+	regmap_exit(wm8753->regmap);
+	kfree(wm8753);
 	return 0;
 }
 
@@ -1541,19 +1617,35 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 
 	i2c_set_clientdata(i2c, wm8753);
-	wm8753->control_type = SND_SOC_I2C;
 
-	ret =  snd_soc_register_codec(&i2c->dev,
-			&soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
-	if (ret < 0)
-		kfree(wm8753);
+	wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap);
+	if (IS_ERR(wm8753->regmap)) {
+		ret = PTR_ERR(wm8753->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
+	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753,
+				     wm8753_dai, ARRAY_SIZE(wm8753_dai));
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+		goto err_regmap;
+	}
+err_regmap:
+	regmap_exit(wm8753->regmap);
+err:
+	kfree(wm8753);
 	return ret;
 }
 
 static __devexit int wm8753_i2c_remove(struct i2c_client *client)
 {
+	struct wm8753_priv *wm8753 = i2c_get_clientdata(client);
+
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	regmap_exit(wm8753->regmap);
+	kfree(wm8753);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index 19374a9..a5127b4 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -580,8 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec)
 	wm8770 = snd_soc_codec_get_drvdata(codec);
 	wm8770->codec = codec;
 
-	codec->dapm.idle_bias_off = 1;
-
 	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
@@ -643,7 +641,7 @@ static int wm8770_probe(struct snd_soc_codec *codec)
 	/* mute all DACs */
 	snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
 
-	snd_soc_add_controls(codec, wm8770_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8770_snd_controls,
 			     ARRAY_SIZE(wm8770_snd_controls));
 	snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
 				  ARRAY_SIZE(wm8770_dapm_widgets));
@@ -679,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
 	.suspend = wm8770_suspend,
 	.resume = wm8770_resume,
 	.set_bias_level = wm8770_set_bias_level,
+	.idle_bias_off = true,
 	.reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
 	.reg_word_size = sizeof (u16),
 	.reg_cache_default = wm8770_reg_defs
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 33e97d1..a19db5a 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -30,6 +30,11 @@
 
 #include "wm8776.h"
 
+enum wm8776_chip_type {
+	WM8775 = 1,
+	WM8776,
+};
+
 /* codec private data */
 struct wm8776_priv {
 	enum snd_soc_control_type control_type;
@@ -512,7 +517,8 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id wm8776_i2c_id[] = {
-	{ "wm8776", 0 },
+	{ "wm8775", WM8775 },
+	{ "wm8776", WM8776 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index d54a3ca..7ee8dcf 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/of_device.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -35,45 +36,33 @@ static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = {
 	"DVDD"
 };
 
-static const u8 wm8804_reg_defs[] = {
-	0x05,     /* R0  - RST/DEVID1 */
-	0x88,     /* R1  - DEVID2 */
-	0x04,     /* R2  - DEVREV */
-	0x21,     /* R3  - PLL1 */
-	0xFD,     /* R4  - PLL2 */
-	0x36,     /* R5  - PLL3 */
-	0x07,     /* R6  - PLL4 */
-	0x16,     /* R7  - PLL5 */
-	0x18,     /* R8  - PLL6 */
-	0xFF,     /* R9  - SPDMODE */
-	0x00,     /* R10 - INTMASK */
-	0x00,     /* R11 - INTSTAT */
-	0x00,     /* R12 - SPDSTAT */
-	0x00,     /* R13 - RXCHAN1 */
-	0x00,     /* R14 - RXCHAN2 */
-	0x00,     /* R15 - RXCHAN3 */
-	0x00,     /* R16 - RXCHAN4 */
-	0x00,     /* R17 - RXCHAN5 */
-	0x00,     /* R18 - SPDTX1 */
-	0x00,     /* R19 - SPDTX2 */
-	0x00,     /* R20 - SPDTX3 */
-	0x71,     /* R21 - SPDTX4 */
-	0x0B,     /* R22 - SPDTX5 */
-	0x70,     /* R23 - GPO0 */
-	0x57,     /* R24 - GPO1 */
-	0x00,     /* R25 */
-	0x42,     /* R26 - GPO2 */
-	0x06,     /* R27 - AIFTX */
-	0x06,     /* R28 - AIFRX */
-	0x80,     /* R29 - SPDRX1 */
-	0x07,     /* R30 - PWRDN */
+static const struct reg_default wm8804_reg_defaults[] = {
+	{ 3,  0x21 },     /* R3  - PLL1 */
+	{ 4,  0xFD },     /* R4  - PLL2 */
+	{ 5,  0x36 },     /* R5  - PLL3 */
+	{ 6,  0x07 },     /* R6  - PLL4 */
+	{ 7,  0x16 },     /* R7  - PLL5 */
+	{ 8,  0x18 },     /* R8  - PLL6 */
+	{ 9,  0xFF },     /* R9  - SPDMODE */
+	{ 10, 0x00 },     /* R10 - INTMASK */
+	{ 18, 0x00 },     /* R18 - SPDTX1 */
+	{ 19, 0x00 },     /* R19 - SPDTX2 */
+	{ 20, 0x00 },     /* R20 - SPDTX3 */
+	{ 21, 0x71 },     /* R21 - SPDTX4 */
+	{ 22, 0x0B },     /* R22 - SPDTX5 */
+	{ 23, 0x70 },     /* R23 - GPO0 */
+	{ 24, 0x57 },     /* R24 - GPO1 */
+	{ 26, 0x42 },     /* R26 - GPO2 */
+	{ 27, 0x06 },     /* R27 - AIFTX */
+	{ 28, 0x06 },     /* R28 - AIFRX */
+	{ 29, 0x80 },     /* R29 - SPDRX1 */
+	{ 30, 0x07 },     /* R30 - PWRDN */
 };
 
 struct wm8804_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
 	struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
-	struct snd_soc_codec *codec;
 };
 
 static int txsrc_get(struct snd_kcontrol *kcontrol,
@@ -94,7 +83,7 @@ static int wm8804_regulator_event_##n(struct notifier_block *nb, \
 	struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
 						  disable_nb[n]); \
 	if (event & REGULATOR_EVENT_DISABLE) { \
-		wm8804->codec->cache_sync = 1; \
+		regcache_mark_dirty(wm8804->regmap);	\
 	} \
 	return 0; \
 }
@@ -176,7 +165,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8804_volatile(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM8804_RST_DEVID1:
@@ -189,12 +178,10 @@ static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg)
 	case WM8804_RXCHAN3:
 	case WM8804_RXCHAN4:
 	case WM8804_RXCHAN5:
-		return 1;
+		return true;
 	default:
-		break;
+		return false;
 	}
-
-	return 0;
 }
 
 static int wm8804_reset(struct snd_soc_codec *codec)
@@ -482,24 +469,6 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
 	return 0;
 }
 
-static void wm8804_sync_cache(struct snd_soc_codec *codec)
-{
-	short i;
-	u8 *cache;
-
-	if (!codec->cache_sync)
-		return;
-
-	codec->cache_only = 0;
-	cache = codec->reg_cache;
-	for (i = 0; i < codec->driver->reg_cache_size; i++) {
-		if (i == WM8804_RST_DEVID1 || cache[i] == wm8804_reg_defs[i])
-			continue;
-		snd_soc_write(codec, i, cache[i]);
-	}
-	codec->cache_sync = 0;
-}
-
 static int wm8804_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
@@ -524,7 +493,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
 					ret);
 				return ret;
 			}
-			wm8804_sync_cache(codec);
+			regcache_sync(wm8804->regmap);
 		}
 		/* power down the OSC and the PLL */
 		snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
@@ -579,11 +548,10 @@ static int wm8804_probe(struct snd_soc_codec *codec)
 	int i, id1, id2, ret;
 
 	wm8804 = snd_soc_codec_get_drvdata(codec);
-	wm8804->codec = codec;
 
-	codec->dapm.idle_bias_off = 1;
+	codec->control_data = wm8804->regmap;
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
 		return ret;
@@ -636,8 +604,7 @@ static int wm8804_probe(struct snd_soc_codec *codec)
 
 	id2 = (id2 << 8) | id1;
 
-	if (id2 != ((wm8804_reg_defs[WM8804_DEVID2] << 8)
-			| wm8804_reg_defs[WM8804_RST_DEVID1])) {
+	if (id2 != 0x8805) {
 		dev_err(codec->dev, "Invalid device ID: %#x\n", id2);
 		ret = -EINVAL;
 		goto err_reg_enable;
@@ -710,10 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
 	.suspend = wm8804_suspend,
 	.resume = wm8804_resume,
 	.set_bias_level = wm8804_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8804_reg_defs),
-	.reg_word_size = sizeof(u8),
-	.reg_cache_default = wm8804_reg_defs,
-	.volatile_register = wm8804_volatile,
+	.idle_bias_off = true,
 
 	.controls = wm8804_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8804_snd_controls),
@@ -725,30 +689,47 @@ static const struct of_device_id wm8804_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, wm8804_of_match);
 
+static struct regmap_config wm8804_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = WM8804_MAX_REGISTER,
+	.volatile_reg = wm8804_volatile,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8804_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults),
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8804_spi_probe(struct spi_device *spi)
 {
 	struct wm8804_priv *wm8804;
 	int ret;
 
-	wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL);
+	wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL);
 	if (!wm8804)
 		return -ENOMEM;
 
-	wm8804->control_type = SND_SOC_SPI;
+	wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config);
+	if (IS_ERR(wm8804->regmap)) {
+		ret = PTR_ERR(wm8804->regmap);
+		return ret;
+	}
+
 	spi_set_drvdata(spi, wm8804);
 
 	ret = snd_soc_register_codec(&spi->dev,
 				     &soc_codec_dev_wm8804, &wm8804_dai, 1);
-	if (ret < 0)
-		kfree(wm8804);
+
 	return ret;
 }
 
 static int __devexit wm8804_spi_remove(struct spi_device *spi)
 {
+	struct wm8804_priv *wm8804 = spi_get_drvdata(spi);
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+	regmap_exit(wm8804->regmap);
 	return 0;
 }
 
@@ -770,24 +751,31 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c,
 	struct wm8804_priv *wm8804;
 	int ret;
 
-	wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL);
+	wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL);
 	if (!wm8804)
 		return -ENOMEM;
 
-	wm8804->control_type = SND_SOC_I2C;
 	i2c_set_clientdata(i2c, wm8804);
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8804, &wm8804_dai, 1);
-	if (ret < 0)
-		kfree(wm8804);
+	if (ret != 0)
+		goto err;
+
+	return 0;
+
+err:
+	regmap_exit(wm8804->regmap);
 	return ret;
 }
 
-static __devexit int wm8804_i2c_remove(struct i2c_client *client)
+static __devexit int wm8804_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c);
+
+	snd_soc_unregister_codec(&i2c->dev);
+	regmap_exit(wm8804->regmap);
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index f31c754..65d525d 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -47,6 +48,7 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
 
 /* codec private data */
 struct wm8904_priv {
+	struct regmap *regmap;
 
 	enum wm8904_type devtype;
 
@@ -86,517 +88,230 @@ struct wm8904_priv {
 	int dcs_state[WM8904_NUM_DCS_CHANNELS];
 };
 
-static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
-	0x8904,     /* R0   - SW Reset and ID */
-	0x0000,     /* R1   - Revision */
-	0x0000,     /* R2 */
-	0x0000,     /* R3 */
-	0x0018,     /* R4   - Bias Control 0 */
-	0x0000,     /* R5   - VMID Control 0 */
-	0x0000,     /* R6   - Mic Bias Control 0 */
-	0x0000,     /* R7   - Mic Bias Control 1 */
-	0x0001,     /* R8   - Analogue DAC 0 */
-	0x9696,     /* R9   - mic Filter Control */
-	0x0001,     /* R10  - Analogue ADC 0 */
-	0x0000,     /* R11 */
-	0x0000,     /* R12  - Power Management 0 */
-	0x0000,     /* R13 */
-	0x0000,     /* R14  - Power Management 2 */
-	0x0000,     /* R15  - Power Management 3 */
-	0x0000,     /* R16 */
-	0x0000,     /* R17 */
-	0x0000,     /* R18  - Power Management 6 */
-	0x0000,     /* R19 */
-	0x945E,     /* R20  - Clock Rates 0 */
-	0x0C05,     /* R21  - Clock Rates 1 */
-	0x0006,     /* R22  - Clock Rates 2 */
-	0x0000,     /* R23 */
-	0x0050,     /* R24  - Audio Interface 0 */
-	0x000A,     /* R25  - Audio Interface 1 */
-	0x00E4,     /* R26  - Audio Interface 2 */
-	0x0040,     /* R27  - Audio Interface 3 */
-	0x0000,     /* R28 */
-	0x0000,     /* R29 */
-	0x00C0,     /* R30  - DAC Digital Volume Left */
-	0x00C0,     /* R31  - DAC Digital Volume Right */
-	0x0000,     /* R32  - DAC Digital 0 */
-	0x0008,     /* R33  - DAC Digital 1 */
-	0x0000,     /* R34 */
-	0x0000,     /* R35 */
-	0x00C0,     /* R36  - ADC Digital Volume Left */
-	0x00C0,     /* R37  - ADC Digital Volume Right */
-	0x0010,     /* R38  - ADC Digital 0 */
-	0x0000,     /* R39  - Digital Microphone 0 */
-	0x01AF,     /* R40  - DRC 0 */
-	0x3248,     /* R41  - DRC 1 */
-	0x0000,     /* R42  - DRC 2 */
-	0x0000,     /* R43  - DRC 3 */
-	0x0085,     /* R44  - Analogue Left Input 0 */
-	0x0085,     /* R45  - Analogue Right Input 0 */
-	0x0044,     /* R46  - Analogue Left Input 1 */
-	0x0044,     /* R47  - Analogue Right Input 1 */
-	0x0000,     /* R48 */
-	0x0000,     /* R49 */
-	0x0000,     /* R50 */
-	0x0000,     /* R51 */
-	0x0000,     /* R52 */
-	0x0000,     /* R53 */
-	0x0000,     /* R54 */
-	0x0000,     /* R55 */
-	0x0000,     /* R56 */
-	0x002D,     /* R57  - Analogue OUT1 Left */
-	0x002D,     /* R58  - Analogue OUT1 Right */
-	0x0039,     /* R59  - Analogue OUT2 Left */
-	0x0039,     /* R60  - Analogue OUT2 Right */
-	0x0000,     /* R61  - Analogue OUT12 ZC */
-	0x0000,     /* R62 */
-	0x0000,     /* R63 */
-	0x0000,     /* R64 */
-	0x0000,     /* R65 */
-	0x0000,     /* R66 */
-	0x0000,     /* R67  - DC Servo 0 */
-	0x0000,     /* R68  - DC Servo 1 */
-	0xAAAA,     /* R69  - DC Servo 2 */
-	0x0000,     /* R70 */
-	0xAAAA,     /* R71  - DC Servo 4 */
-	0xAAAA,     /* R72  - DC Servo 5 */
-	0x0000,     /* R73  - DC Servo 6 */
-	0x0000,     /* R74  - DC Servo 7 */
-	0x0000,     /* R75  - DC Servo 8 */
-	0x0000,     /* R76  - DC Servo 9 */
-	0x0000,     /* R77  - DC Servo Readback 0 */
-	0x0000,     /* R78 */
-	0x0000,     /* R79 */
-	0x0000,     /* R80 */
-	0x0000,     /* R81 */
-	0x0000,     /* R82 */
-	0x0000,     /* R83 */
-	0x0000,     /* R84 */
-	0x0000,     /* R85 */
-	0x0000,     /* R86 */
-	0x0000,     /* R87 */
-	0x0000,     /* R88 */
-	0x0000,     /* R89 */
-	0x0000,     /* R90  - Analogue HP 0 */
-	0x0000,     /* R91 */
-	0x0000,     /* R92 */
-	0x0000,     /* R93 */
-	0x0000,     /* R94  - Analogue Lineout 0 */
-	0x0000,     /* R95 */
-	0x0000,     /* R96 */
-	0x0000,     /* R97 */
-	0x0000,     /* R98  - Charge Pump 0 */
-	0x0000,     /* R99 */
-	0x0000,     /* R100 */
-	0x0000,     /* R101 */
-	0x0000,     /* R102 */
-	0x0000,     /* R103 */
-	0x0004,     /* R104 - Class W 0 */
-	0x0000,     /* R105 */
-	0x0000,     /* R106 */
-	0x0000,     /* R107 */
-	0x0000,     /* R108 - Write Sequencer 0 */
-	0x0000,     /* R109 - Write Sequencer 1 */
-	0x0000,     /* R110 - Write Sequencer 2 */
-	0x0000,     /* R111 - Write Sequencer 3 */
-	0x0000,     /* R112 - Write Sequencer 4 */
-	0x0000,     /* R113 */
-	0x0000,     /* R114 */
-	0x0000,     /* R115 */
-	0x0000,     /* R116 - FLL Control 1 */
-	0x0007,     /* R117 - FLL Control 2 */
-	0x0000,     /* R118 - FLL Control 3 */
-	0x2EE0,     /* R119 - FLL Control 4 */
-	0x0004,     /* R120 - FLL Control 5 */
-	0x0014,     /* R121 - GPIO Control 1 */
-	0x0010,     /* R122 - GPIO Control 2 */
-	0x0010,     /* R123 - GPIO Control 3 */
-	0x0000,     /* R124 - GPIO Control 4 */
-	0x0000,     /* R125 */
-	0x0000,     /* R126 - Digital Pulls */
-	0x0000,     /* R127 - Interrupt Status */
-	0xFFFF,     /* R128 - Interrupt Status Mask */
-	0x0000,     /* R129 - Interrupt Polarity */
-	0x0000,     /* R130 - Interrupt Debounce */
-	0x0000,     /* R131 */
-	0x0000,     /* R132 */
-	0x0000,     /* R133 */
-	0x0000,     /* R134 - EQ1 */
-	0x000C,     /* R135 - EQ2 */
-	0x000C,     /* R136 - EQ3 */
-	0x000C,     /* R137 - EQ4 */
-	0x000C,     /* R138 - EQ5 */
-	0x000C,     /* R139 - EQ6 */
-	0x0FCA,     /* R140 - EQ7 */
-	0x0400,     /* R141 - EQ8 */
-	0x00D8,     /* R142 - EQ9 */
-	0x1EB5,     /* R143 - EQ10 */
-	0xF145,     /* R144 - EQ11 */
-	0x0B75,     /* R145 - EQ12 */
-	0x01C5,     /* R146 - EQ13 */
-	0x1C58,     /* R147 - EQ14 */
-	0xF373,     /* R148 - EQ15 */
-	0x0A54,     /* R149 - EQ16 */
-	0x0558,     /* R150 - EQ17 */
-	0x168E,     /* R151 - EQ18 */
-	0xF829,     /* R152 - EQ19 */
-	0x07AD,     /* R153 - EQ20 */
-	0x1103,     /* R154 - EQ21 */
-	0x0564,     /* R155 - EQ22 */
-	0x0559,     /* R156 - EQ23 */
-	0x4000,     /* R157 - EQ24 */
-	0x0000,     /* R158 */
-	0x0000,     /* R159 */
-	0x0000,     /* R160 */
-	0x0000,     /* R161 - Control Interface Test 1 */
-	0x0000,     /* R162 */
-	0x0000,     /* R163 */
-	0x0000,     /* R164 */
-	0x0000,     /* R165 */
-	0x0000,     /* R166 */
-	0x0000,     /* R167 */
-	0x0000,     /* R168 */
-	0x0000,     /* R169 */
-	0x0000,     /* R170 */
-	0x0000,     /* R171 */
-	0x0000,     /* R172 */
-	0x0000,     /* R173 */
-	0x0000,     /* R174 */
-	0x0000,     /* R175 */
-	0x0000,     /* R176 */
-	0x0000,     /* R177 */
-	0x0000,     /* R178 */
-	0x0000,     /* R179 */
-	0x0000,     /* R180 */
-	0x0000,     /* R181 */
-	0x0000,     /* R182 */
-	0x0000,     /* R183 */
-	0x0000,     /* R184 */
-	0x0000,     /* R185 */
-	0x0000,     /* R186 */
-	0x0000,     /* R187 */
-	0x0000,     /* R188 */
-	0x0000,     /* R189 */
-	0x0000,     /* R190 */
-	0x0000,     /* R191 */
-	0x0000,     /* R192 */
-	0x0000,     /* R193 */
-	0x0000,     /* R194 */
-	0x0000,     /* R195 */
-	0x0000,     /* R196 */
-	0x0000,     /* R197 */
-	0x0000,     /* R198 */
-	0x0000,     /* R199 */
-	0x0000,     /* R200 */
-	0x0000,     /* R201 */
-	0x0000,     /* R202 */
-	0x0000,     /* R203 */
-	0x0000,     /* R204 - Analogue Output Bias 0 */
-	0x0000,     /* R205 */
-	0x0000,     /* R206 */
-	0x0000,     /* R207 */
-	0x0000,     /* R208 */
-	0x0000,     /* R209 */
-	0x0000,     /* R210 */
-	0x0000,     /* R211 */
-	0x0000,     /* R212 */
-	0x0000,     /* R213 */
-	0x0000,     /* R214 */
-	0x0000,     /* R215 */
-	0x0000,     /* R216 */
-	0x0000,     /* R217 */
-	0x0000,     /* R218 */
-	0x0000,     /* R219 */
-	0x0000,     /* R220 */
-	0x0000,     /* R221 */
-	0x0000,     /* R222 */
-	0x0000,     /* R223 */
-	0x0000,     /* R224 */
-	0x0000,     /* R225 */
-	0x0000,     /* R226 */
-	0x0000,     /* R227 */
-	0x0000,     /* R228 */
-	0x0000,     /* R229 */
-	0x0000,     /* R230 */
-	0x0000,     /* R231 */
-	0x0000,     /* R232 */
-	0x0000,     /* R233 */
-	0x0000,     /* R234 */
-	0x0000,     /* R235 */
-	0x0000,     /* R236 */
-	0x0000,     /* R237 */
-	0x0000,     /* R238 */
-	0x0000,     /* R239 */
-	0x0000,     /* R240 */
-	0x0000,     /* R241 */
-	0x0000,     /* R242 */
-	0x0000,     /* R243 */
-	0x0000,     /* R244 */
-	0x0000,     /* R245 */
-	0x0000,     /* R246 */
-	0x0000,     /* R247 - FLL NCO Test 0 */
-	0x0019,     /* R248 - FLL NCO Test 1 */
+static const struct reg_default wm8904_reg_defaults[] = {
+	{ 4,   0x0018 },     /* R4   - Bias Control 0 */
+	{ 5,   0x0000 },     /* R5   - VMID Control 0 */
+	{ 6,   0x0000 },     /* R6   - Mic Bias Control 0 */
+	{ 7,   0x0000 },     /* R7   - Mic Bias Control 1 */
+	{ 8,   0x0001 },     /* R8   - Analogue DAC 0 */
+	{ 9,   0x9696 },     /* R9   - mic Filter Control */
+	{ 10,  0x0001 },     /* R10  - Analogue ADC 0 */
+	{ 12,  0x0000 },     /* R12  - Power Management 0 */
+	{ 14,  0x0000 },     /* R14  - Power Management 2 */
+	{ 15,  0x0000 },     /* R15  - Power Management 3 */
+	{ 18,  0x0000 },     /* R18  - Power Management 6 */
+	{ 19,  0x945E },     /* R20  - Clock Rates 0 */
+	{ 21,  0x0C05 },     /* R21  - Clock Rates 1 */
+	{ 22,  0x0006 },     /* R22  - Clock Rates 2 */
+	{ 24,  0x0050 },     /* R24  - Audio Interface 0 */
+	{ 25,  0x000A },     /* R25  - Audio Interface 1 */
+	{ 26,  0x00E4 },     /* R26  - Audio Interface 2 */
+	{ 27,  0x0040 },     /* R27  - Audio Interface 3 */
+	{ 30,  0x00C0 },     /* R30  - DAC Digital Volume Left */
+	{ 31,  0x00C0 },     /* R31  - DAC Digital Volume Right */
+	{ 32,  0x0000 },     /* R32  - DAC Digital 0 */
+	{ 33,  0x0008 },     /* R33  - DAC Digital 1 */
+	{ 36,  0x00C0 },     /* R36  - ADC Digital Volume Left */
+	{ 37,  0x00C0 },     /* R37  - ADC Digital Volume Right */
+	{ 38,  0x0010 },     /* R38  - ADC Digital 0 */
+	{ 39,  0x0000 },     /* R39  - Digital Microphone 0 */
+	{ 40,  0x01AF },     /* R40  - DRC 0 */
+	{ 41,  0x3248 },     /* R41  - DRC 1 */
+	{ 42,  0x0000 },     /* R42  - DRC 2 */
+	{ 43,  0x0000 },     /* R43  - DRC 3 */
+	{ 44,  0x0085 },     /* R44  - Analogue Left Input 0 */
+	{ 45,  0x0085 },     /* R45  - Analogue Right Input 0 */
+	{ 46,  0x0044 },     /* R46  - Analogue Left Input 1 */
+	{ 47,  0x0044 },     /* R47  - Analogue Right Input 1 */
+	{ 57,  0x002D },     /* R57  - Analogue OUT1 Left */
+	{ 58,  0x002D },     /* R58  - Analogue OUT1 Right */
+	{ 59,  0x0039 },     /* R59  - Analogue OUT2 Left */
+	{ 60,  0x0039 },     /* R60  - Analogue OUT2 Right */
+	{ 61,  0x0000 },     /* R61  - Analogue OUT12 ZC */
+	{ 67,  0x0000 },     /* R67  - DC Servo 0 */
+	{ 69,  0xAAAA },     /* R69  - DC Servo 2 */
+	{ 71,  0xAAAA },     /* R71  - DC Servo 4 */
+	{ 72,  0xAAAA },     /* R72  - DC Servo 5 */
+	{ 90,  0x0000 },     /* R90  - Analogue HP 0 */
+	{ 94,  0x0000 },     /* R94  - Analogue Lineout 0 */
+	{ 98,  0x0000 },     /* R98  - Charge Pump 0 */
+	{ 104, 0x0004 },     /* R104 - Class W 0 */
+	{ 108, 0x0000 },     /* R108 - Write Sequencer 0 */
+	{ 109, 0x0000 },     /* R109 - Write Sequencer 1 */
+	{ 110, 0x0000 },     /* R110 - Write Sequencer 2 */
+	{ 111, 0x0000 },     /* R111 - Write Sequencer 3 */
+	{ 112, 0x0000 },     /* R112 - Write Sequencer 4 */
+	{ 116, 0x0000 },     /* R116 - FLL Control 1 */
+	{ 117, 0x0007 },     /* R117 - FLL Control 2 */
+	{ 118, 0x0000 },     /* R118 - FLL Control 3 */
+	{ 119, 0x2EE0 },     /* R119 - FLL Control 4 */
+	{ 120, 0x0004 },     /* R120 - FLL Control 5 */
+	{ 121, 0x0014 },     /* R121 - GPIO Control 1 */
+	{ 122, 0x0010 },     /* R122 - GPIO Control 2 */
+	{ 123, 0x0010 },     /* R123 - GPIO Control 3 */
+	{ 124, 0x0000 },     /* R124 - GPIO Control 4 */
+	{ 126, 0x0000 },     /* R126 - Digital Pulls */
+	{ 128, 0xFFFF },     /* R128 - Interrupt Status Mask */
+	{ 129, 0x0000 },     /* R129 - Interrupt Polarity */
+	{ 130, 0x0000 },     /* R130 - Interrupt Debounce */
+	{ 134, 0x0000 },     /* R134 - EQ1 */
+	{ 135, 0x000C },     /* R135 - EQ2 */
+	{ 136, 0x000C },     /* R136 - EQ3 */
+	{ 137, 0x000C },     /* R137 - EQ4 */
+	{ 138, 0x000C },     /* R138 - EQ5 */
+	{ 139, 0x000C },     /* R139 - EQ6 */
+	{ 140, 0x0FCA },     /* R140 - EQ7 */
+	{ 141, 0x0400 },     /* R141 - EQ8 */
+	{ 142, 0x00D8 },     /* R142 - EQ9 */
+	{ 143, 0x1EB5 },     /* R143 - EQ10 */
+	{ 144, 0xF145 },     /* R144 - EQ11 */
+	{ 145, 0x0B75 },     /* R145 - EQ12 */
+	{ 146, 0x01C5 },     /* R146 - EQ13 */
+	{ 147, 0x1C58 },     /* R147 - EQ14 */
+	{ 148, 0xF373 },     /* R148 - EQ15 */
+	{ 149, 0x0A54 },     /* R149 - EQ16 */
+	{ 150, 0x0558 },     /* R150 - EQ17 */
+	{ 151, 0x168E },     /* R151 - EQ18 */
+	{ 152, 0xF829 },     /* R152 - EQ19 */
+	{ 153, 0x07AD },     /* R153 - EQ20 */
+	{ 154, 0x1103 },     /* R154 - EQ21 */
+	{ 155, 0x0564 },     /* R155 - EQ22 */
+	{ 156, 0x0559 },     /* R156 - EQ23 */
+	{ 157, 0x4000 },     /* R157 - EQ24 */
+	{ 161, 0x0000 },     /* R161 - Control Interface Test 1 */
+	{ 204, 0x0000 },     /* R204 - Analogue Output Bias 0 */
+	{ 247, 0x0000 },     /* R247 - FLL NCO Test 0 */
+	{ 248, 0x0019 },     /* R248 - FLL NCO Test 1 */
 };
 
-static struct {
-	int readable;
-	int writable;
-	int vol;
-} wm8904_access[] = {
-	{ 0xFFFF, 0xFFFF, 1 }, /* R0   - SW Reset and ID */
-	{ 0x0000, 0x0000, 0 }, /* R1   - Revision */
-	{ 0x0000, 0x0000, 0 }, /* R2 */
-	{ 0x0000, 0x0000, 0 }, /* R3 */
-	{ 0x001F, 0x001F, 0 }, /* R4   - Bias Control 0 */
-	{ 0x0047, 0x0047, 0 }, /* R5   - VMID Control 0 */
-	{ 0x007F, 0x007F, 0 }, /* R6   - Mic Bias Control 0 */
-	{ 0xC007, 0xC007, 0 }, /* R7   - Mic Bias Control 1 */
-	{ 0x001E, 0x001E, 0 }, /* R8   - Analogue DAC 0 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R9   - mic Filter Control */
-	{ 0x0001, 0x0001, 0 }, /* R10  - Analogue ADC 0 */
-	{ 0x0000, 0x0000, 0 }, /* R11 */
-	{ 0x0003, 0x0003, 0 }, /* R12  - Power Management 0 */
-	{ 0x0000, 0x0000, 0 }, /* R13 */
-	{ 0x0003, 0x0003, 0 }, /* R14  - Power Management 2 */
-	{ 0x0003, 0x0003, 0 }, /* R15  - Power Management 3 */
-	{ 0x0000, 0x0000, 0 }, /* R16 */
-	{ 0x0000, 0x0000, 0 }, /* R17 */
-	{ 0x000F, 0x000F, 0 }, /* R18  - Power Management 6 */
-	{ 0x0000, 0x0000, 0 }, /* R19 */
-	{ 0x7001, 0x7001, 0 }, /* R20  - Clock Rates 0 */
-	{ 0x3C07, 0x3C07, 0 }, /* R21  - Clock Rates 1 */
-	{ 0xD00F, 0xD00F, 0 }, /* R22  - Clock Rates 2 */
-	{ 0x0000, 0x0000, 0 }, /* R23 */
-	{ 0x1FFF, 0x1FFF, 0 }, /* R24  - Audio Interface 0 */
-	{ 0x3DDF, 0x3DDF, 0 }, /* R25  - Audio Interface 1 */
-	{ 0x0F1F, 0x0F1F, 0 }, /* R26  - Audio Interface 2 */
-	{ 0x0FFF, 0x0FFF, 0 }, /* R27  - Audio Interface 3 */
-	{ 0x0000, 0x0000, 0 }, /* R28 */
-	{ 0x0000, 0x0000, 0 }, /* R29 */
-	{ 0x00FF, 0x01FF, 0 }, /* R30  - DAC Digital Volume Left */
-	{ 0x00FF, 0x01FF, 0 }, /* R31  - DAC Digital Volume Right */
-	{ 0x0FFF, 0x0FFF, 0 }, /* R32  - DAC Digital 0 */
-	{ 0x1E4E, 0x1E4E, 0 }, /* R33  - DAC Digital 1 */
-	{ 0x0000, 0x0000, 0 }, /* R34 */
-	{ 0x0000, 0x0000, 0 }, /* R35 */
-	{ 0x00FF, 0x01FF, 0 }, /* R36  - ADC Digital Volume Left */
-	{ 0x00FF, 0x01FF, 0 }, /* R37  - ADC Digital Volume Right */
-	{ 0x0073, 0x0073, 0 }, /* R38  - ADC Digital 0 */
-	{ 0x1800, 0x1800, 0 }, /* R39  - Digital Microphone 0 */
-	{ 0xDFEF, 0xDFEF, 0 }, /* R40  - DRC 0 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R41  - DRC 1 */
-	{ 0x003F, 0x003F, 0 }, /* R42  - DRC 2 */
-	{ 0x07FF, 0x07FF, 0 }, /* R43  - DRC 3 */
-	{ 0x009F, 0x009F, 0 }, /* R44  - Analogue Left Input 0 */
-	{ 0x009F, 0x009F, 0 }, /* R45  - Analogue Right Input 0 */
-	{ 0x007F, 0x007F, 0 }, /* R46  - Analogue Left Input 1 */
-	{ 0x007F, 0x007F, 0 }, /* R47  - Analogue Right Input 1 */
-	{ 0x0000, 0x0000, 0 }, /* R48 */
-	{ 0x0000, 0x0000, 0 }, /* R49 */
-	{ 0x0000, 0x0000, 0 }, /* R50 */
-	{ 0x0000, 0x0000, 0 }, /* R51 */
-	{ 0x0000, 0x0000, 0 }, /* R52 */
-	{ 0x0000, 0x0000, 0 }, /* R53 */
-	{ 0x0000, 0x0000, 0 }, /* R54 */
-	{ 0x0000, 0x0000, 0 }, /* R55 */
-	{ 0x0000, 0x0000, 0 }, /* R56 */
-	{ 0x017F, 0x01FF, 0 }, /* R57  - Analogue OUT1 Left */
-	{ 0x017F, 0x01FF, 0 }, /* R58  - Analogue OUT1 Right */
-	{ 0x017F, 0x01FF, 0 }, /* R59  - Analogue OUT2 Left */
-	{ 0x017F, 0x01FF, 0 }, /* R60  - Analogue OUT2 Right */
-	{ 0x000F, 0x000F, 0 }, /* R61  - Analogue OUT12 ZC */
-	{ 0x0000, 0x0000, 0 }, /* R62 */
-	{ 0x0000, 0x0000, 0 }, /* R63 */
-	{ 0x0000, 0x0000, 0 }, /* R64 */
-	{ 0x0000, 0x0000, 0 }, /* R65 */
-	{ 0x0000, 0x0000, 0 }, /* R66 */
-	{ 0x000F, 0x000F, 0 }, /* R67  - DC Servo 0 */
-	{ 0xFFFF, 0xFFFF, 1 }, /* R68  - DC Servo 1 */
-	{ 0x0F0F, 0x0F0F, 0 }, /* R69  - DC Servo 2 */
-	{ 0x0000, 0x0000, 0 }, /* R70 */
-	{ 0x007F, 0x007F, 0 }, /* R71  - DC Servo 4 */
-	{ 0x007F, 0x007F, 0 }, /* R72  - DC Servo 5 */
-	{ 0x00FF, 0x00FF, 1 }, /* R73  - DC Servo 6 */
-	{ 0x00FF, 0x00FF, 1 }, /* R74  - DC Servo 7 */
-	{ 0x00FF, 0x00FF, 1 }, /* R75  - DC Servo 8 */
-	{ 0x00FF, 0x00FF, 1 }, /* R76  - DC Servo 9 */
-	{ 0x0FFF, 0x0000, 1 }, /* R77  - DC Servo Readback 0 */
-	{ 0x0000, 0x0000, 0 }, /* R78 */
-	{ 0x0000, 0x0000, 0 }, /* R79 */
-	{ 0x0000, 0x0000, 0 }, /* R80 */
-	{ 0x0000, 0x0000, 0 }, /* R81 */
-	{ 0x0000, 0x0000, 0 }, /* R82 */
-	{ 0x0000, 0x0000, 0 }, /* R83 */
-	{ 0x0000, 0x0000, 0 }, /* R84 */
-	{ 0x0000, 0x0000, 0 }, /* R85 */
-	{ 0x0000, 0x0000, 0 }, /* R86 */
-	{ 0x0000, 0x0000, 0 }, /* R87 */
-	{ 0x0000, 0x0000, 0 }, /* R88 */
-	{ 0x0000, 0x0000, 0 }, /* R89 */
-	{ 0x00FF, 0x00FF, 0 }, /* R90  - Analogue HP 0 */
-	{ 0x0000, 0x0000, 0 }, /* R91 */
-	{ 0x0000, 0x0000, 0 }, /* R92 */
-	{ 0x0000, 0x0000, 0 }, /* R93 */
-	{ 0x00FF, 0x00FF, 0 }, /* R94  - Analogue Lineout 0 */
-	{ 0x0000, 0x0000, 0 }, /* R95 */
-	{ 0x0000, 0x0000, 0 }, /* R96 */
-	{ 0x0000, 0x0000, 0 }, /* R97 */
-	{ 0x0001, 0x0001, 0 }, /* R98  - Charge Pump 0 */
-	{ 0x0000, 0x0000, 0 }, /* R99 */
-	{ 0x0000, 0x0000, 0 }, /* R100 */
-	{ 0x0000, 0x0000, 0 }, /* R101 */
-	{ 0x0000, 0x0000, 0 }, /* R102 */
-	{ 0x0000, 0x0000, 0 }, /* R103 */
-	{ 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
-	{ 0x0000, 0x0000, 0 }, /* R105 */
-	{ 0x0000, 0x0000, 0 }, /* R106 */
-	{ 0x0000, 0x0000, 0 }, /* R107 */
-	{ 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
-	{ 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
-	{ 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
-	{ 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
-	{ 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
-	{ 0x0000, 0x0000, 0 }, /* R113 */
-	{ 0x0000, 0x0000, 0 }, /* R114 */
-	{ 0x0000, 0x0000, 0 }, /* R115 */
-	{ 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
-	{ 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
-	{ 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
-	{ 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
-	{ 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
-	{ 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
-	{ 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
-	{ 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
-	{ 0x0000, 0x0000, 0 }, /* R125 */
-	{ 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
-	{ 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
-	{ 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
-	{ 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
-	{ 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
-	{ 0x0000, 0x0000, 0 }, /* R131 */
-	{ 0x0000, 0x0000, 0 }, /* R132 */
-	{ 0x0000, 0x0000, 0 }, /* R133 */
-	{ 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
-	{ 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
-	{ 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
-	{ 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
-	{ 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
-	{ 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
-	{ 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
-	{ 0x0000, 0x0000, 0 }, /* R158 */
-	{ 0x0000, 0x0000, 0 }, /* R159 */
-	{ 0x0000, 0x0000, 0 }, /* R160 */
-	{ 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
-	{ 0x0000, 0x0000, 0 }, /* R162 */
-	{ 0x0000, 0x0000, 0 }, /* R163 */
-	{ 0x0000, 0x0000, 0 }, /* R164 */
-	{ 0x0000, 0x0000, 0 }, /* R165 */
-	{ 0x0000, 0x0000, 0 }, /* R166 */
-	{ 0x0000, 0x0000, 0 }, /* R167 */
-	{ 0x0000, 0x0000, 0 }, /* R168 */
-	{ 0x0000, 0x0000, 0 }, /* R169 */
-	{ 0x0000, 0x0000, 0 }, /* R170 */
-	{ 0x0000, 0x0000, 0 }, /* R171 */
-	{ 0x0000, 0x0000, 0 }, /* R172 */
-	{ 0x0000, 0x0000, 0 }, /* R173 */
-	{ 0x0000, 0x0000, 0 }, /* R174 */
-	{ 0x0000, 0x0000, 0 }, /* R175 */
-	{ 0x0000, 0x0000, 0 }, /* R176 */
-	{ 0x0000, 0x0000, 0 }, /* R177 */
-	{ 0x0000, 0x0000, 0 }, /* R178 */
-	{ 0x0000, 0x0000, 0 }, /* R179 */
-	{ 0x0000, 0x0000, 0 }, /* R180 */
-	{ 0x0000, 0x0000, 0 }, /* R181 */
-	{ 0x0000, 0x0000, 0 }, /* R182 */
-	{ 0x0000, 0x0000, 0 }, /* R183 */
-	{ 0x0000, 0x0000, 0 }, /* R184 */
-	{ 0x0000, 0x0000, 0 }, /* R185 */
-	{ 0x0000, 0x0000, 0 }, /* R186 */
-	{ 0x0000, 0x0000, 0 }, /* R187 */
-	{ 0x0000, 0x0000, 0 }, /* R188 */
-	{ 0x0000, 0x0000, 0 }, /* R189 */
-	{ 0x0000, 0x0000, 0 }, /* R190 */
-	{ 0x0000, 0x0000, 0 }, /* R191 */
-	{ 0x0000, 0x0000, 0 }, /* R192 */
-	{ 0x0000, 0x0000, 0 }, /* R193 */
-	{ 0x0000, 0x0000, 0 }, /* R194 */
-	{ 0x0000, 0x0000, 0 }, /* R195 */
-	{ 0x0000, 0x0000, 0 }, /* R196 */
-	{ 0x0000, 0x0000, 0 }, /* R197 */
-	{ 0x0000, 0x0000, 0 }, /* R198 */
-	{ 0x0000, 0x0000, 0 }, /* R199 */
-	{ 0x0000, 0x0000, 0 }, /* R200 */
-	{ 0x0000, 0x0000, 0 }, /* R201 */
-	{ 0x0000, 0x0000, 0 }, /* R202 */
-	{ 0x0000, 0x0000, 0 }, /* R203 */
-	{ 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
-	{ 0x0000, 0x0000, 0 }, /* R205 */
-	{ 0x0000, 0x0000, 0 }, /* R206 */
-	{ 0x0000, 0x0000, 0 }, /* R207 */
-	{ 0x0000, 0x0000, 0 }, /* R208 */
-	{ 0x0000, 0x0000, 0 }, /* R209 */
-	{ 0x0000, 0x0000, 0 }, /* R210 */
-	{ 0x0000, 0x0000, 0 }, /* R211 */
-	{ 0x0000, 0x0000, 0 }, /* R212 */
-	{ 0x0000, 0x0000, 0 }, /* R213 */
-	{ 0x0000, 0x0000, 0 }, /* R214 */
-	{ 0x0000, 0x0000, 0 }, /* R215 */
-	{ 0x0000, 0x0000, 0 }, /* R216 */
-	{ 0x0000, 0x0000, 0 }, /* R217 */
-	{ 0x0000, 0x0000, 0 }, /* R218 */
-	{ 0x0000, 0x0000, 0 }, /* R219 */
-	{ 0x0000, 0x0000, 0 }, /* R220 */
-	{ 0x0000, 0x0000, 0 }, /* R221 */
-	{ 0x0000, 0x0000, 0 }, /* R222 */
-	{ 0x0000, 0x0000, 0 }, /* R223 */
-	{ 0x0000, 0x0000, 0 }, /* R224 */
-	{ 0x0000, 0x0000, 0 }, /* R225 */
-	{ 0x0000, 0x0000, 0 }, /* R226 */
-	{ 0x0000, 0x0000, 0 }, /* R227 */
-	{ 0x0000, 0x0000, 0 }, /* R228 */
-	{ 0x0000, 0x0000, 0 }, /* R229 */
-	{ 0x0000, 0x0000, 0 }, /* R230 */
-	{ 0x0000, 0x0000, 0 }, /* R231 */
-	{ 0x0000, 0x0000, 0 }, /* R232 */
-	{ 0x0000, 0x0000, 0 }, /* R233 */
-	{ 0x0000, 0x0000, 0 }, /* R234 */
-	{ 0x0000, 0x0000, 0 }, /* R235 */
-	{ 0x0000, 0x0000, 0 }, /* R236 */
-	{ 0x0000, 0x0000, 0 }, /* R237 */
-	{ 0x0000, 0x0000, 0 }, /* R238 */
-	{ 0x0000, 0x0000, 0 }, /* R239 */
-	{ 0x0000, 0x0000, 0 }, /* R240 */
-	{ 0x0000, 0x0000, 0 }, /* R241 */
-	{ 0x0000, 0x0000, 0 }, /* R242 */
-	{ 0x0000, 0x0000, 0 }, /* R243 */
-	{ 0x0000, 0x0000, 0 }, /* R244 */
-	{ 0x0000, 0x0000, 0 }, /* R245 */
-	{ 0x0000, 0x0000, 0 }, /* R246 */
-	{ 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
-	{ 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
-};
+static bool wm8904_volatile_register(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8904_SW_RESET_AND_ID:
+	case WM8904_REVISION:
+	case WM8904_DC_SERVO_1:
+	case WM8904_DC_SERVO_6:
+	case WM8904_DC_SERVO_7:
+	case WM8904_DC_SERVO_8:
+	case WM8904_DC_SERVO_9:
+	case WM8904_DC_SERVO_READBACK_0:
+	case WM8904_INTERRUPT_STATUS:
+		return true;
+	default:
+		return false;
+	}
+}
 
-static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8904_readable_register(struct device *dev, unsigned int reg)
 {
-	return wm8904_access[reg].vol;
+	switch (reg) {
+	case WM8904_SW_RESET_AND_ID:
+	case WM8904_REVISION:
+	case WM8904_BIAS_CONTROL_0:
+	case WM8904_VMID_CONTROL_0:
+	case WM8904_MIC_BIAS_CONTROL_0:
+	case WM8904_MIC_BIAS_CONTROL_1:
+	case WM8904_ANALOGUE_DAC_0:
+	case WM8904_MIC_FILTER_CONTROL:
+	case WM8904_ANALOGUE_ADC_0:
+	case WM8904_POWER_MANAGEMENT_0:
+	case WM8904_POWER_MANAGEMENT_2:
+	case WM8904_POWER_MANAGEMENT_3:
+	case WM8904_POWER_MANAGEMENT_6:
+	case WM8904_CLOCK_RATES_0:
+	case WM8904_CLOCK_RATES_1:
+	case WM8904_CLOCK_RATES_2:
+	case WM8904_AUDIO_INTERFACE_0:
+	case WM8904_AUDIO_INTERFACE_1:
+	case WM8904_AUDIO_INTERFACE_2:
+	case WM8904_AUDIO_INTERFACE_3:
+	case WM8904_DAC_DIGITAL_VOLUME_LEFT:
+	case WM8904_DAC_DIGITAL_VOLUME_RIGHT:
+	case WM8904_DAC_DIGITAL_0:
+	case WM8904_DAC_DIGITAL_1:
+	case WM8904_ADC_DIGITAL_VOLUME_LEFT:
+	case WM8904_ADC_DIGITAL_VOLUME_RIGHT:
+	case WM8904_ADC_DIGITAL_0:
+	case WM8904_DIGITAL_MICROPHONE_0:
+	case WM8904_DRC_0:
+	case WM8904_DRC_1:
+	case WM8904_DRC_2:
+	case WM8904_DRC_3:
+	case WM8904_ANALOGUE_LEFT_INPUT_0:
+	case WM8904_ANALOGUE_RIGHT_INPUT_0:
+	case WM8904_ANALOGUE_LEFT_INPUT_1:
+	case WM8904_ANALOGUE_RIGHT_INPUT_1:
+	case WM8904_ANALOGUE_OUT1_LEFT:
+	case WM8904_ANALOGUE_OUT1_RIGHT:
+	case WM8904_ANALOGUE_OUT2_LEFT:
+	case WM8904_ANALOGUE_OUT2_RIGHT:
+	case WM8904_ANALOGUE_OUT12_ZC:
+	case WM8904_DC_SERVO_0:
+	case WM8904_DC_SERVO_1:
+	case WM8904_DC_SERVO_2:
+	case WM8904_DC_SERVO_4:
+	case WM8904_DC_SERVO_5:
+	case WM8904_DC_SERVO_6:
+	case WM8904_DC_SERVO_7:
+	case WM8904_DC_SERVO_8:
+	case WM8904_DC_SERVO_9:
+	case WM8904_DC_SERVO_READBACK_0:
+	case WM8904_ANALOGUE_HP_0:
+	case WM8904_ANALOGUE_LINEOUT_0:
+	case WM8904_CHARGE_PUMP_0:
+	case WM8904_CLASS_W_0:
+	case WM8904_WRITE_SEQUENCER_0:
+	case WM8904_WRITE_SEQUENCER_1:
+	case WM8904_WRITE_SEQUENCER_2:
+	case WM8904_WRITE_SEQUENCER_3:
+	case WM8904_WRITE_SEQUENCER_4:
+	case WM8904_FLL_CONTROL_1:
+	case WM8904_FLL_CONTROL_2:
+	case WM8904_FLL_CONTROL_3:
+	case WM8904_FLL_CONTROL_4:
+	case WM8904_FLL_CONTROL_5:
+	case WM8904_GPIO_CONTROL_1:
+	case WM8904_GPIO_CONTROL_2:
+	case WM8904_GPIO_CONTROL_3:
+	case WM8904_GPIO_CONTROL_4:
+	case WM8904_DIGITAL_PULLS:
+	case WM8904_INTERRUPT_STATUS:
+	case WM8904_INTERRUPT_STATUS_MASK:
+	case WM8904_INTERRUPT_POLARITY:
+	case WM8904_INTERRUPT_DEBOUNCE:
+	case WM8904_EQ1:
+	case WM8904_EQ2:
+	case WM8904_EQ3:
+	case WM8904_EQ4:
+	case WM8904_EQ5:
+	case WM8904_EQ6:
+	case WM8904_EQ7:
+	case WM8904_EQ8:
+	case WM8904_EQ9:
+	case WM8904_EQ10:
+	case WM8904_EQ11:
+	case WM8904_EQ12:
+	case WM8904_EQ13:
+	case WM8904_EQ14:
+	case WM8904_EQ15:
+	case WM8904_EQ16:
+	case WM8904_EQ17:
+	case WM8904_EQ18:
+	case WM8904_EQ19:
+	case WM8904_EQ20:
+	case WM8904_EQ21:
+	case WM8904_EQ22:
+	case WM8904_EQ23:
+	case WM8904_EQ24:
+	case WM8904_CONTROL_INTERFACE_TEST_1:
+	case WM8904_ADC_TEST_0:
+	case WM8904_ANALOGUE_OUTPUT_BIAS_0:
+	case WM8904_FLL_NCO_TEST_0:
+	case WM8904_FLL_NCO_TEST_1:
+		return true;
+	default:
+		return true;
+	}
 }
 
 static int wm8904_reset(struct snd_soc_codec *codec)
@@ -855,6 +570,29 @@ static const char *hpf_mode_text[] = {
 static const struct soc_enum hpf_mode =
 	SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
 
+static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned int val;
+	int ret;
+
+	ret = snd_soc_put_volsw(kcontrol, ucontrol);
+	if (ret < 0)
+		return ret;
+
+	if (ucontrol->value.integer.value[0])
+		val = 0;
+	else
+		val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5;
+
+	snd_soc_update_bits(codec, WM8904_ADC_TEST_0,
+			    WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5,
+			    val);
+
+	return ret;
+}
+
 static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
 SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
 		 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
@@ -871,7 +609,12 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
 SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
 SOC_ENUM("High Pass Filter Mode", hpf_mode),
 
-SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
+{       .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "ADC 128x OSR Switch",
+	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,
+	.put = wm8904_adc_osr_put,
+	.private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0),
+},
 };
 
 static const char *drc_path_text[] = {
@@ -1433,11 +1176,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
 
 	switch (wm8904->devtype) {
 	case WM8904:
-		snd_soc_add_controls(codec, wm8904_adc_snd_controls,
+		snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls,
 				     ARRAY_SIZE(wm8904_adc_snd_controls));
-		snd_soc_add_controls(codec, wm8904_dac_snd_controls,
+		snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
 				     ARRAY_SIZE(wm8904_dac_snd_controls));
-		snd_soc_add_controls(codec, wm8904_snd_controls,
+		snd_soc_add_codec_controls(codec, wm8904_snd_controls,
 				     ARRAY_SIZE(wm8904_snd_controls));
 
 		snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
@@ -1458,7 +1201,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
 		break;
 
 	case WM8912:
-		snd_soc_add_controls(codec, wm8904_dac_snd_controls,
+		snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls,
 				     ARRAY_SIZE(wm8904_dac_snd_controls));
 
 		snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
@@ -2088,32 +1831,6 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 	return 0;
 }
 
-static void wm8904_sync_cache(struct snd_soc_codec *codec)
-{
-	u16 *reg_cache = codec->reg_cache;
-	int i;
-
-	if (!codec->cache_sync)
-		return;
-
-	codec->cache_only = 0;
-
-	/* Sync back cached values if they're different from the
-	 * hardware default.
-	 */
-	for (i = 1; i < codec->driver->reg_cache_size; i++) {
-		if (!wm8904_access[i].writable)
-			continue;
-
-		if (reg_cache[i] == wm8904_reg[i])
-			continue;
-
-		snd_soc_write(codec, i, reg_cache[i]);
-	}
-
-	codec->cache_sync = 0;
-}
-
 static int wm8904_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
@@ -2146,7 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
 				return ret;
 			}
 
-			wm8904_sync_cache(codec);
+			regcache_sync(wm8904->regmap);
 
 			/* Enable bias */
 			snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
@@ -2303,7 +2020,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
 	wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
 	wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
 
-	ret = snd_soc_add_controls(codec, &control, 1);
+	ret = snd_soc_add_codec_controls(codec, &control, 1);
 	if (ret != 0)
 		dev_err(codec->dev,
 			"Failed to add ReTune Mobile control: %d\n", ret);
@@ -2316,7 +2033,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
 	int ret, i;
 
 	if (!pdata) {
-		snd_soc_add_controls(codec, wm8904_eq_controls,
+		snd_soc_add_codec_controls(codec, wm8904_eq_controls,
 				     ARRAY_SIZE(wm8904_eq_controls));
 		return;
 	}
@@ -2344,7 +2061,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
 		wm8904->drc_enum.max = pdata->num_drc_cfgs;
 		wm8904->drc_enum.texts = wm8904->drc_texts;
 
-		ret = snd_soc_add_controls(codec, &control, 1);
+		ret = snd_soc_add_codec_controls(codec, &control, 1);
 		if (ret != 0)
 			dev_err(codec->dev,
 				"Failed to add DRC mode control: %d\n", ret);
@@ -2358,7 +2075,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
 	if (pdata->num_retune_mobile_cfgs)
 		wm8904_handle_retune_mobile_pdata(codec);
 	else
-		snd_soc_add_controls(codec, wm8904_eq_controls,
+		snd_soc_add_codec_controls(codec, wm8904_eq_controls,
 				     ARRAY_SIZE(wm8904_eq_controls));
 }
 
@@ -2371,7 +2088,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 	int ret, i;
 
 	codec->cache_sync = 1;
-	codec->dapm.idle_bias_off = 1;
+	codec->control_data = wm8904->regmap;
 
 	switch (wm8904->devtype) {
 	case WM8904:
@@ -2385,7 +2102,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 		return -EINVAL;
 	}
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -2413,7 +2130,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 		dev_err(codec->dev, "Failed to read ID register\n");
 		goto err_enable;
 	}
-	if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
+	if (ret != 0x8904) {
 		dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
 		ret = -EINVAL;
 		goto err_enable;
@@ -2519,38 +2236,62 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
 	.suspend =	wm8904_suspend,
 	.resume =	wm8904_resume,
 	.set_bias_level = wm8904_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8904_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8904_reg,
-	.volatile_register = wm8904_volatile_register,
+	.idle_bias_off = true,
+};
+
+static const struct regmap_config wm8904_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+
+	.max_register = WM8904_MAX_REGISTER,
+	.volatile_reg = wm8904_volatile_register,
+	.readable_reg = wm8904_readable_register,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8904_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8904_priv *wm8904;
 	int ret;
 
-	wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
+	wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv),
+			      GFP_KERNEL);
 	if (wm8904 == NULL)
 		return -ENOMEM;
 
+	wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap);
+	if (IS_ERR(wm8904->regmap)) {
+		ret = PTR_ERR(wm8904->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
 	wm8904->devtype = id->driver_data;
 	i2c_set_clientdata(i2c, wm8904);
 	wm8904->pdata = i2c->dev.platform_data;
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8904, &wm8904_dai, 1);
-	if (ret < 0)
-		kfree(wm8904);
+	if (ret != 0)
+		goto err;
+
+	return 0;
+
+err:
+	regmap_exit(wm8904->regmap);
 	return ret;
 }
 
 static __devexit int wm8904_i2c_remove(struct i2c_client *client)
 {
+	struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	regmap_exit(wm8904->regmap);
 	return 0;
 }
 
@@ -2571,27 +2312,22 @@ static struct i2c_driver wm8904_i2c_driver = {
 	.remove =   __devexit_p(wm8904_i2c_remove),
 	.id_table = wm8904_i2c_id,
 };
-#endif
 
 static int __init wm8904_modinit(void)
 {
 	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	ret = i2c_add_driver(&wm8904_i2c_driver);
 	if (ret != 0) {
 		printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
 		       ret);
 	}
-#endif
 	return ret;
 }
 module_init(wm8904_modinit);
 
 static void __exit wm8904_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	i2c_del_driver(&wm8904_i2c_driver);
-#endif
 }
 module_exit(wm8904_exit);
 
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
index 9e8c841..c29a0e8 100644
--- a/sound/soc/codecs/wm8904.h
+++ b/sound/soc/codecs/wm8904.h
@@ -123,6 +123,7 @@
 #define WM8904_EQ23                             0x9C
 #define WM8904_EQ24                             0x9D
 #define WM8904_CONTROL_INTERFACE_TEST_1         0xA1
+#define WM8904_ADC_TEST_0			0xC6
 #define WM8904_ANALOGUE_OUTPUT_BIAS_0           0xCC
 #define WM8904_FLL_NCO_TEST_0                   0xF7
 #define WM8904_FLL_NCO_TEST_1                   0xF8
@@ -1557,6 +1558,16 @@
 #define WM8904_USER_KEY_WIDTH                        1  /* USER_KEY */
 
 /*
+ * R198 (0xC6) - ADC Test 0
+ */
+#define WM8904_ADC_128_OSR_TST_MODE             0x0004  /* ADC_128_OSR_TST_MODE */
+#define WM8904_ADC_128_OSR_TST_MODE_SHIFT            2  /* ADC_128_OSR_TST_MODE */
+#define WM8904_ADC_128_OSR_TST_MODE_WIDTH            1  /* ADC_128_OSR_TST_MODE */
+#define WM8904_ADC_BIASX1P5                     0x0001  /* ADC_BIASX1P5 */
+#define WM8904_ADC_BIASX1P5_SHIFT                    0  /* ADC_BIASX1P5 */
+#define WM8904_ADC_BIASX1P5_WIDTH                    1  /* ADC_BIASX1P5 */
+
+/*
  * R204 (0xCC) - Analogue Output Bias 0
  */
 #define WM8904_PGA_BIAS_MASK                    0x0070  /* PGA_BIAS - [6:4] */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 14039ea..d2883af 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -717,7 +717,7 @@ static int wm8940_probe(struct snd_soc_codec *codec)
 			return ret;
 	}
 
-	ret = snd_soc_add_controls(codec, wm8940_snd_controls,
+	ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls,
 			     ARRAY_SIZE(wm8940_snd_controls));
 	if (ret)
 		return ret;
@@ -743,14 +743,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = {
 	.volatile_register = wm8940_volatile_register,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8940_priv *wm8940;
 	int ret;
 
-	wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL);
+	wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv),
+			      GFP_KERNEL);
 	if (wm8940 == NULL)
 		return -ENOMEM;
 
@@ -759,15 +759,14 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8940, &wm8940_dai, 1);
-	if (ret < 0)
-		kfree(wm8940);
+
 	return ret;
 }
 
 static __devexit int wm8940_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+
 	return 0;
 }
 
@@ -786,27 +785,22 @@ static struct i2c_driver wm8940_i2c_driver = {
 	.remove =   __devexit_p(wm8940_i2c_remove),
 	.id_table = wm8940_i2c_id,
 };
-#endif
 
 static int __init wm8940_modinit(void)
 {
 	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	ret = i2c_add_driver(&wm8940_i2c_driver);
 	if (ret != 0) {
 		printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
 		       ret);
 	}
-#endif
 	return ret;
 }
 module_init(wm8940_modinit);
 
 static void __exit wm8940_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	i2c_del_driver(&wm8940_i2c_driver);
-#endif
 }
 module_exit(wm8940_exit);
 
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 9245481..61fe974 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -38,7 +39,7 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
 
 /* codec private data */
 struct wm8955_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 
 	unsigned int mclk_rate;
 
@@ -48,69 +49,85 @@ struct wm8955_priv {
 	struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
 };
 
-static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
-	0x0000,     /* R0 */
-	0x0000,     /* R1 */
-	0x0079,     /* R2  - LOUT1 volume */
-	0x0079,     /* R3  - ROUT1 volume */
-	0x0000,     /* R4 */
-	0x0008,     /* R5  - DAC Control */
-	0x0000,     /* R6 */
-	0x000A,     /* R7  - Audio Interface */
-	0x0000,     /* R8  - Sample Rate */
-	0x0000,     /* R9 */
-	0x00FF,     /* R10 - Left DAC volume */
-	0x00FF,     /* R11 - Right DAC volume */
-	0x000F,     /* R12 - Bass control */
-	0x000F,     /* R13 - Treble control */
-	0x0000,     /* R14 */
-	0x0000,     /* R15 - Reset */
-	0x0000,     /* R16 */
-	0x0000,     /* R17 */
-	0x0000,     /* R18 */
-	0x0000,     /* R19 */
-	0x0000,     /* R20 */
-	0x0000,     /* R21 */
-	0x0000,     /* R22 */
-	0x00C1,     /* R23 - Additional control (1) */
-	0x0000,     /* R24 - Additional control (2) */
-	0x0000,     /* R25 - Power Management (1) */
-	0x0000,     /* R26 - Power Management (2) */
-	0x0000,     /* R27 - Additional Control (3) */
-	0x0000,     /* R28 */
-	0x0000,     /* R29 */
-	0x0000,     /* R30 */
-	0x0000,     /* R31 */
-	0x0000,     /* R32 */
-	0x0000,     /* R33 */
-	0x0050,     /* R34 - Left out Mix (1) */
-	0x0050,     /* R35 - Left out Mix (2) */
-	0x0050,     /* R36 - Right out Mix (1) */
-	0x0050,     /* R37 - Right Out Mix (2) */
-	0x0050,     /* R38 - Mono out Mix (1) */
-	0x0050,     /* R39 - Mono out Mix (2) */
-	0x0079,     /* R40 - LOUT2 volume */
-	0x0079,     /* R41 - ROUT2 volume */
-	0x0079,     /* R42 - MONOOUT volume */
-	0x0000,     /* R43 - Clocking / PLL */
-	0x0103,     /* R44 - PLL Control 1 */
-	0x0024,     /* R45 - PLL Control 2 */
-	0x01BA,     /* R46 - PLL Control 3 */
-	0x0000,     /* R47 */
-	0x0000,     /* R48 */
-	0x0000,     /* R49 */
-	0x0000,     /* R50 */
-	0x0000,     /* R51 */
-	0x0000,     /* R52 */
-	0x0000,     /* R53 */
-	0x0000,     /* R54 */
-	0x0000,     /* R55 */
-	0x0000,     /* R56 */
-	0x0000,     /* R57 */
-	0x0000,     /* R58 */
-	0x0000,     /* R59 - PLL Control 4 */
+static const struct reg_default wm8955_reg_defaults[] = {
+	{ 2,  0x0079 },     /* R2  - LOUT1 volume */
+	{ 3,  0x0079 },     /* R3  - ROUT1 volume */
+	{ 5,  0x0008 },     /* R5  - DAC Control */
+	{ 7,  0x000A },     /* R7  - Audio Interface */
+	{ 8,  0x0000 },     /* R8  - Sample Rate */
+	{ 10, 0x00FF },     /* R10 - Left DAC volume */
+	{ 11, 0x00FF },     /* R11 - Right DAC volume */
+	{ 12, 0x000F },     /* R12 - Bass control */
+	{ 13, 0x000F },     /* R13 - Treble control */
+	{ 23, 0x00C1 },     /* R23 - Additional control (1) */
+	{ 24, 0x0000 },     /* R24 - Additional control (2) */
+	{ 25, 0x0000 },     /* R25 - Power Management (1) */
+	{ 26, 0x0000 },     /* R26 - Power Management (2) */
+	{ 27, 0x0000 },     /* R27 - Additional Control (3) */
+	{ 34, 0x0050 },     /* R34 - Left out Mix (1) */
+	{ 35, 0x0050 },     /* R35 - Left out Mix (2) */
+	{ 36, 0x0050 },     /* R36 - Right out Mix (1) */
+	{ 37, 0x0050 },     /* R37 - Right Out Mix (2) */
+	{ 38, 0x0050 },     /* R38 - Mono out Mix (1) */
+	{ 39, 0x0050 },     /* R39 - Mono out Mix (2) */
+	{ 40, 0x0079 },     /* R40 - LOUT2 volume */
+	{ 41, 0x0079 },     /* R41 - ROUT2 volume */
+	{ 42, 0x0079 },     /* R42 - MONOOUT volume */
+	{ 43, 0x0000 },     /* R43 - Clocking / PLL */
+	{ 44, 0x0103 },     /* R44 - PLL Control 1 */
+	{ 45, 0x0024 },     /* R45 - PLL Control 2 */
+	{ 46, 0x01BA },     /* R46 - PLL Control 3 */
+	{ 59, 0x0000 },     /* R59 - PLL Control 4 */
 };
 
+static bool wm8955_writeable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8955_LOUT1_VOLUME:
+	case WM8955_ROUT1_VOLUME:
+	case WM8955_DAC_CONTROL:
+	case WM8955_AUDIO_INTERFACE:
+	case WM8955_SAMPLE_RATE:
+	case WM8955_LEFT_DAC_VOLUME:
+	case WM8955_RIGHT_DAC_VOLUME:
+	case WM8955_BASS_CONTROL:
+	case WM8955_TREBLE_CONTROL:
+	case WM8955_RESET:
+	case WM8955_ADDITIONAL_CONTROL_1:
+	case WM8955_ADDITIONAL_CONTROL_2:
+	case WM8955_POWER_MANAGEMENT_1:
+	case WM8955_POWER_MANAGEMENT_2:
+	case WM8955_ADDITIONAL_CONTROL_3:
+	case WM8955_LEFT_OUT_MIX_1:
+	case WM8955_LEFT_OUT_MIX_2:
+	case WM8955_RIGHT_OUT_MIX_1:
+	case WM8955_RIGHT_OUT_MIX_2:
+	case WM8955_MONO_OUT_MIX_1:
+	case WM8955_MONO_OUT_MIX_2:
+	case WM8955_LOUT2_VOLUME:
+	case WM8955_ROUT2_VOLUME:
+	case WM8955_MONOOUT_VOLUME:
+	case WM8955_CLOCKING_PLL:
+	case WM8955_PLL_CONTROL_1:
+	case WM8955_PLL_CONTROL_2:
+	case WM8955_PLL_CONTROL_3:
+	case WM8955_PLL_CONTROL_4:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool wm8955_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8955_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int wm8955_reset(struct snd_soc_codec *codec)
 {
 	return snd_soc_write(codec, WM8955_RESET, 0);
@@ -527,7 +544,7 @@ SND_SOC_DAPM_OUTPUT("MONOOUT"),
 SND_SOC_DAPM_OUTPUT("OUT3"),
 };
 
-static const struct snd_soc_dapm_route wm8955_intercon[] = {
+static const struct snd_soc_dapm_route wm8955_dapm_routes[] = {
 	{ "DACL", NULL, "SYSCLK" },
 	{ "DACR", NULL, "SYSCLK" },
 
@@ -572,21 +589,6 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = {
 	{ "OUT3", NULL, "OUT3 PGA" },
 };
 
-static int wm8955_add_widgets(struct snd_soc_codec *codec)
-{
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	snd_soc_add_controls(codec, wm8955_snd_controls,
-			     ARRAY_SIZE(wm8955_snd_controls));
-
-	snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets,
-				  ARRAY_SIZE(wm8955_dapm_widgets));
-	snd_soc_dapm_add_routes(dapm, wm8955_intercon,
-				ARRAY_SIZE(wm8955_intercon));
-
-	return 0;
-}
-
 static int wm8955_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params,
 			    struct snd_soc_dai *dai)
@@ -765,8 +767,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
-	u16 *reg_cache = codec->reg_cache;
-	int ret, i;
+	int ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -795,18 +796,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 				return ret;
 			}
 
-			/* Sync back cached values if they're
-			 * different from the hardware default.
-			 */
-			for (i = 0; i < codec->driver->reg_cache_size; i++) {
-				if (i == WM8955_RESET)
-					continue;
-
-				if (reg_cache[i] == wm8955_reg[i])
-					continue;
-
-				snd_soc_write(codec, i, reg_cache[i]);
-			}
+			regcache_sync(wm8955->regmap);
 
 			/* Enable VREF and VMID */
 			snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
@@ -880,8 +870,12 @@ static struct snd_soc_dai_driver wm8955_dai = {
 #ifdef CONFIG_PM
 static int wm8955_suspend(struct snd_soc_codec *codec)
 {
+	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+
 	wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
+	regcache_mark_dirty(wm8955->regmap);
+
 	return 0;
 }
 
@@ -900,10 +894,11 @@ static int wm8955_probe(struct snd_soc_codec *codec)
 {
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 	struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
-	u16 *reg_cache = codec->reg_cache;
 	int ret, i;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
+	codec->control_data = wm8955->regmap;
+
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -958,12 +953,12 @@ static int wm8955_probe(struct snd_soc_codec *codec)
 	/* Set platform data values */
 	if (pdata) {
 		if (pdata->out2_speaker)
-			reg_cache[WM8955_ADDITIONAL_CONTROL_2]
-				|= WM8955_ROUT2INV;
+			snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_2,
+					    WM8955_ROUT2INV, WM8955_ROUT2INV);
 
 		if (pdata->monoin_diff)
-			reg_cache[WM8955_MONO_OUT_MIX_1]
-				|= WM8955_DMEN;
+			snd_soc_update_bits(codec, WM8955_MONO_OUT_MIX_1,
+					    WM8955_DMEN, WM8955_DMEN);
 	}
 
 	wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -971,7 +966,6 @@ static int wm8955_probe(struct snd_soc_codec *codec)
 	/* Bias level configuration will have done an extra enable */
 	regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
 
-	wm8955_add_widgets(codec);
 	return 0;
 
 err_enable:
@@ -996,36 +990,68 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
 	.suspend =	wm8955_suspend,
 	.resume =	wm8955_resume,
 	.set_bias_level = wm8955_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8955_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8955_reg,
+
+	.controls =	wm8955_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8955_snd_controls),
+	.dapm_widgets = wm8955_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets),
+	.dapm_routes =	wm8955_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes),
+};
+
+static const struct regmap_config wm8955_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.max_register = WM8955_MAX_REGISTER,
+	.volatile_reg = wm8955_volatile,
+	.writeable_reg = wm8955_writeable,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8955_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8955_priv *wm8955;
 	int ret;
 
-	wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
+	wm8955 = devm_kzalloc(&i2c->dev, sizeof(struct wm8955_priv),
+			      GFP_KERNEL);
 	if (wm8955 == NULL)
 		return -ENOMEM;
 
+	wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap);
+	if (IS_ERR(wm8955->regmap)) {
+		ret = PTR_ERR(wm8955->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8955);
-	wm8955->control_type = SND_SOC_I2C;
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8955, &wm8955_dai, 1);
-	if (ret < 0)
-		kfree(wm8955);
+	if (ret != 0)
+		goto err;
+
+	return ret;
+
+err:
+	regmap_exit(wm8955->regmap);
 	return ret;
 }
 
 static __devexit int wm8955_i2c_remove(struct i2c_client *client)
 {
+	struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
+
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	regmap_exit(wm8955->regmap);
+
 	return 0;
 }
 
@@ -1044,27 +1070,22 @@ static struct i2c_driver wm8955_i2c_driver = {
 	.remove =   __devexit_p(wm8955_i2c_remove),
 	.id_table = wm8955_i2c_id,
 };
-#endif
 
 static int __init wm8955_modinit(void)
 {
 	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	ret = i2c_add_driver(&wm8955_i2c_driver);
 	if (ret != 0) {
 		printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
 		       ret);
 	}
-#endif
 	return ret;
 }
 module_init(wm8955_modinit);
 
 static void __exit wm8955_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	i2c_del_driver(&wm8955_i2c_driver);
-#endif
 }
 module_exit(wm8955_exit);
 
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 40ac888..1332692 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -920,11 +920,11 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 
 	wm8994->dsp_active = -1;
 
-	snd_soc_add_controls(codec, wm8958_mbc_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls,
 			     ARRAY_SIZE(wm8958_mbc_snd_controls));
-	snd_soc_add_controls(codec, wm8958_vss_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls,
 			     ARRAY_SIZE(wm8958_vss_snd_controls));
-	snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls,
 			     ARRAY_SIZE(wm8958_enh_eq_snd_controls));
 
 
@@ -958,7 +958,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
 		wm8994->mbc_enum.texts = wm8994->mbc_texts;
 
-		ret = snd_soc_add_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
 		if (ret != 0)
 			dev_err(wm8994->codec->dev,
 				"Failed to add MBC mode controls: %d\n", ret);
@@ -986,7 +986,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->vss_enum.max = pdata->num_vss_cfgs;
 		wm8994->vss_enum.texts = wm8994->vss_texts;
 
-		ret = snd_soc_add_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
 		if (ret != 0)
 			dev_err(wm8994->codec->dev,
 				"Failed to add VSS mode controls: %d\n", ret);
@@ -1015,7 +1015,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
 		wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
 
-		ret = snd_soc_add_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
 		if (ret != 0)
 			dev_err(wm8994->codec->dev,
 				"Failed to add VSS HPFmode controls: %d\n",
@@ -1045,7 +1045,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec)
 		wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
 		wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
 
-		ret = snd_soc_add_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
 		if (ret != 0)
 			dev_err(wm8994->codec->dev,
 				"Failed to add enhanced EQ controls: %d\n",
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e5caae3..840d720 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -940,7 +940,7 @@ static int wm8960_probe(struct snd_soc_codec *codec)
 	snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
 	snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
 
-	snd_soc_add_controls(codec, wm8960_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8960_snd_controls,
 				     ARRAY_SIZE(wm8960_snd_controls));
 	wm8960_add_widgets(codec);
 
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 4f20c72..05ea7c2 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1022,7 +1022,7 @@ static int wm8961_probe(struct snd_soc_codec *codec)
 
 	wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-	snd_soc_add_controls(codec, wm8961_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8961_snd_controls,
 				ARRAY_SIZE(wm8961_snd_controls));
 	snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
 				  ARRAY_SIZE(wm8961_dapm_widgets));
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 29c4b02..7ecb1d3 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -20,6 +20,7 @@
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
+#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -797,1167 +798,660 @@ static struct reg_default wm8962_reg[] = {
 	{ 21139, 0x8580 },   /* R21139 - VSS_XTS32_0 */
 };
 
-static const struct wm8962_reg_access {
-	u16 read;
-	u16 write;
-	u16 vol;
-} wm8962_reg_access[WM8962_MAX_REGISTER + 1] = {
-	[0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0     - Left Input volume */
-	[1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1     - Right Input volume */
-	[2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2     - HPOUTL volume */
-	[3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3     - HPOUTR volume */
-	[4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4     - Clocking1 */
-	[5] = { 0x007F, 0x007F, 0x0000 }, /* R5     - ADC & DAC Control 1 */
-	[6] = { 0x37ED, 0x37ED, 0x0000 }, /* R6     - ADC & DAC Control 2 */
-	[7] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R7     - Audio Interface 0 */
-	[8] = { 0x0FEF, 0x0FEF, 0xFFFF }, /* R8     - Clocking2 */
-	[9] = { 0x0B9F, 0x039F, 0x0000 }, /* R9     - Audio Interface 1 */
-	[10] = { 0x00FF, 0x01FF, 0x0000 }, /* R10    - Left DAC volume */
-	[11] = { 0x00FF, 0x01FF, 0x0000 }, /* R11    - Right DAC volume */
-	[14] = { 0x07FF, 0x07FF, 0x0000 }, /* R14    - Audio Interface 2 */
-	[15] = { 0xFFFF, 0xFFFF, 0xFFFF }, /* R15    - Software Reset */
-	[17] = { 0x07FF, 0x07FF, 0x0000 }, /* R17    - ALC1 */
-	[18] = { 0xF8FF, 0x00FF, 0xFFFF }, /* R18    - ALC2 */
-	[19] = { 0x1DFF, 0x1DFF, 0x0000 }, /* R19    - ALC3 */
-	[20] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20    - Noise Gate */
-	[21] = { 0x00FF, 0x01FF, 0x0000 }, /* R21    - Left ADC volume */
-	[22] = { 0x00FF, 0x01FF, 0x0000 }, /* R22    - Right ADC volume */
-	[23] = { 0x0161, 0x0161, 0x0000 }, /* R23    - Additional control(1) */
-	[24] = { 0x0008, 0x0008, 0x0000 }, /* R24    - Additional control(2) */
-	[25] = { 0x07FE, 0x07FE, 0x0000 }, /* R25    - Pwr Mgmt (1) */
-	[26] = { 0x01FB, 0x01FB, 0x0000 }, /* R26    - Pwr Mgmt (2) */
-	[27] = { 0x0017, 0x0017, 0x0000 }, /* R27    - Additional Control (3) */
-	[28] = { 0x001C, 0x001C, 0x0000 }, /* R28    - Anti-pop */
-
-	[30] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R30    - Clocking 3 */
-	[31] = { 0x000F, 0x000F, 0x0000 }, /* R31    - Input mixer control (1) */
-	[32] = { 0x01FF, 0x01FF, 0x0000 }, /* R32    - Left input mixer volume */
-	[33] = { 0x01FF, 0x01FF, 0x0000 }, /* R33    - Right input mixer volume */
-	[34] = { 0x003F, 0x003F, 0x0000 }, /* R34    - Input mixer control (2) */
-	[35] = { 0x003F, 0x003F, 0x0000 }, /* R35    - Input bias control */
-	[37] = { 0x001F, 0x001F, 0x0000 }, /* R37    - Left input PGA control */
-	[38] = { 0x001F, 0x001F, 0x0000 }, /* R38    - Right input PGA control */
-	[40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40    - SPKOUTL volume */
-	[41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41    - SPKOUTR volume */
-
-	[47] = { 0x000F, 0x0000, 0xFFFF }, /* R47    - Thermal Shutdown Status */
-	[48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48    - Additional Control (4) */
-	[49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49    - Class D Control 1 */
-	[51] = { 0x0047, 0x0047, 0x0000 }, /* R51    - Class D Control 2 */
-	[56] = { 0x001E, 0x001E, 0x0000 }, /* R56    - Clocking 4 */
-	[57] = { 0x02FC, 0x02FC, 0x0000 }, /* R57    - DAC DSP Mixing (1) */
-	[58] = { 0x00FC, 0x00FC, 0x0000 }, /* R58    - DAC DSP Mixing (2) */
-	[60] = { 0x00CC, 0x00CC, 0x0000 }, /* R60    - DC Servo 0 */
-	[61] = { 0x00DD, 0x00DD, 0x0000 }, /* R61    - DC Servo 1 */
-	[64] = { 0x3F80, 0x3F80, 0x0000 }, /* R64    - DC Servo 4 */
-	[66] = { 0x0780, 0x0000, 0xFFFF }, /* R66    - DC Servo 6 */
-	[68] = { 0x0007, 0x0007, 0x0000 }, /* R68    - Analogue PGA Bias */
-	[69] = { 0x00FF, 0x00FF, 0x0000 }, /* R69    - Analogue HP 0 */
-	[71] = { 0x01FF, 0x01FF, 0x0000 }, /* R71    - Analogue HP 2 */
-	[72] = { 0x0001, 0x0001, 0x0000 }, /* R72    - Charge Pump 1 */
-	[82] = { 0x0001, 0x0001, 0x0000 }, /* R82    - Charge Pump B */
-	[87] = { 0x00A0, 0x00A0, 0x0000 }, /* R87    - Write Sequencer Control 1 */
-	[90] = { 0x007F, 0x01FF, 0x0000 }, /* R90    - Write Sequencer Control 2 */
-	[93] = { 0x03F9, 0x0000, 0x0000 }, /* R93    - Write Sequencer Control 3 */
-	[94] = { 0x0070, 0x0070, 0x0000 }, /* R94    - Control Interface */
-	[99] = { 0x000F, 0x000F, 0x0000 }, /* R99    - Mixer Enables */
-	[100] = { 0x00BF, 0x00BF, 0x0000 }, /* R100   - Headphone Mixer (1) */
-	[101] = { 0x00BF, 0x00BF, 0x0000 }, /* R101   - Headphone Mixer (2) */
-	[102] = { 0x01FF, 0x01FF, 0x0000 }, /* R102   - Headphone Mixer (3) */
-	[103] = { 0x01FF, 0x01FF, 0x0000 }, /* R103   - Headphone Mixer (4) */
-	[105] = { 0x00BF, 0x00BF, 0x0000 }, /* R105   - Speaker Mixer (1) */
-	[106] = { 0x00BF, 0x00BF, 0x0000 }, /* R106   - Speaker Mixer (2) */
-	[107] = { 0x01FF, 0x01FF, 0x0000 }, /* R107   - Speaker Mixer (3) */
-	[108] = { 0x01FF, 0x01FF, 0x0000 }, /* R108   - Speaker Mixer (4) */
-	[109] = { 0x00F0, 0x00F0, 0x0000 }, /* R109   - Speaker Mixer (5) */
-	[110] = { 0x00F7, 0x00F7, 0x0000 }, /* R110   - Beep Generator (1) */
-	[115] = { 0x001F, 0x001F, 0x0000 }, /* R115   - Oscillator Trim (3) */
-	[116] = { 0x001F, 0x001F, 0x0000 }, /* R116   - Oscillator Trim (4) */
-	[119] = { 0x00FF, 0x00FF, 0x0000 }, /* R119   - Oscillator Trim (7) */
-	[124] = { 0x0079, 0x0079, 0x0000 }, /* R124   - Analogue Clocking1 */
-	[125] = { 0x00DF, 0x00DF, 0x0000 }, /* R125   - Analogue Clocking2 */
-	[126] = { 0x000D, 0x000D, 0x0000 }, /* R126   - Analogue Clocking3 */
-	[127] = { 0x0000, 0xFFFF, 0x0000 }, /* R127   - PLL Software Reset */
-	[129] = { 0x00B0, 0x00B0, 0x0000 }, /* R129   - PLL2 */
-	[131] = { 0x0003, 0x0003, 0x0000 }, /* R131   - PLL 4 */
-	[136] = { 0x005F, 0x005F, 0x0000 }, /* R136   - PLL 9 */
-	[137] = { 0x00FF, 0x00FF, 0x0000 }, /* R137   - PLL 10 */
-	[138] = { 0x00FF, 0x00FF, 0x0000 }, /* R138   - PLL 11 */
-	[139] = { 0x00FF, 0x00FF, 0x0000 }, /* R139   - PLL 12 */
-	[140] = { 0x005F, 0x005F, 0x0000 }, /* R140   - PLL 13 */
-	[141] = { 0x00FF, 0x00FF, 0x0000 }, /* R141   - PLL 14 */
-	[142] = { 0x00FF, 0x00FF, 0x0000 }, /* R142   - PLL 15 */
-	[143] = { 0x00FF, 0x00FF, 0x0000 }, /* R143   - PLL 16 */
-	[155] = { 0x0067, 0x0067, 0x0000 }, /* R155   - FLL Control (1) */
-	[156] = { 0x01FB, 0x01FB, 0x0000 }, /* R156   - FLL Control (2) */
-	[157] = { 0x0007, 0x0007, 0x0000 }, /* R157   - FLL Control (3) */
-	[159] = { 0x007F, 0x007F, 0x0000 }, /* R159   - FLL Control (5) */
-	[160] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R160   - FLL Control (6) */
-	[161] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R161   - FLL Control (7) */
-	[162] = { 0x03FF, 0x03FF, 0x0000 }, /* R162   - FLL Control (8) */
-	[252] = { 0x0005, 0x0005, 0x0000 }, /* R252   - General test 1 */
-	[256] = { 0x000F, 0x000F, 0x0000 }, /* R256   - DF1 */
-	[257] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R257   - DF2 */
-	[258] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R258   - DF3 */
-	[259] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R259   - DF4 */
-	[260] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R260   - DF5 */
-	[261] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R261   - DF6 */
-	[262] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R262   - DF7 */
-	[264] = { 0x0003, 0x0003, 0x0000 }, /* R264   - LHPF1 */
-	[265] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R265   - LHPF2 */
-	[268] = { 0x0077, 0x0077, 0x0000 }, /* R268   - THREED1 */
-	[269] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R269   - THREED2 */
-	[270] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R270   - THREED3 */
-	[271] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R271   - THREED4 */
-	[276] = { 0x7FFF, 0x7FFF, 0x0000 }, /* R276   - DRC 1 */
-	[277] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R277   - DRC 2 */
-	[278] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R278   - DRC 3 */
-	[279] = { 0x07FF, 0x07FF, 0x0000 }, /* R279   - DRC 4 */
-	[280] = { 0x03FF, 0x03FF, 0x0000 }, /* R280   - DRC 5 */
-	[285] = { 0x0003, 0x0003, 0x0000 }, /* R285   - Tloopback */
-	[335] = { 0x0007, 0x0007, 0x0000 }, /* R335   - EQ1 */
-	[336] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R336   - EQ2 */
-	[337] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R337   - EQ3 */
-	[338] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R338   - EQ4 */
-	[339] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R339   - EQ5 */
-	[340] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R340   - EQ6 */
-	[341] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R341   - EQ7 */
-	[342] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R342   - EQ8 */
-	[343] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R343   - EQ9 */
-	[344] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R344   - EQ10 */
-	[345] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R345   - EQ11 */
-	[346] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R346   - EQ12 */
-	[347] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R347   - EQ13 */
-	[348] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R348   - EQ14 */
-	[349] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R349   - EQ15 */
-	[350] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R350   - EQ16 */
-	[351] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R351   - EQ17 */
-	[352] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R352   - EQ18 */
-	[353] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R353   - EQ19 */
-	[354] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R354   - EQ20 */
-	[355] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R355   - EQ21 */
-	[356] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R356   - EQ22 */
-	[357] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R357   - EQ23 */
-	[358] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R358   - EQ24 */
-	[359] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R359   - EQ25 */
-	[360] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R360   - EQ26 */
-	[361] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R361   - EQ27 */
-	[362] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R362   - EQ28 */
-	[363] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R363   - EQ29 */
-	[364] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R364   - EQ30 */
-	[365] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R365   - EQ31 */
-	[366] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R366   - EQ32 */
-	[367] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R367   - EQ33 */
-	[368] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R368   - EQ34 */
-	[369] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R369   - EQ35 */
-	[370] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R370   - EQ36 */
-	[371] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R371   - EQ37 */
-	[372] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R372   - EQ38 */
-	[373] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R373   - EQ39 */
-	[374] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R374   - EQ40 */
-	[375] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R375   - EQ41 */
-	[513] = { 0x045F, 0x045F, 0x0000 }, /* R513   - GPIO 2 */
-	[514] = { 0x045F, 0x045F, 0x0000 }, /* R514   - GPIO 3 */
-	[516] = { 0xE75F, 0xE75F, 0x0000 }, /* R516   - GPIO 5 */
-	[517] = { 0xE75F, 0xE75F, 0x0000 }, /* R517   - GPIO 6 */
-	[560] = { 0x0030, 0x0030, 0xFFFF }, /* R560   - Interrupt Status 1 */
-	[561] = { 0xFFED, 0xFFED, 0xFFFF }, /* R561   - Interrupt Status 2 */
-	[568] = { 0x0030, 0x0030, 0x0000 }, /* R568   - Interrupt Status 1 Mask */
-	[569] = { 0xFFED, 0xFFED, 0x0000 }, /* R569   - Interrupt Status 2 Mask */
-	[576] = { 0x0001, 0x0001, 0x0000 }, /* R576   - Interrupt Control */
-	[584] = { 0x002D, 0x002D, 0x0000 }, /* R584   - IRQ Debounce */
-	[586] = { 0xC000, 0xC000, 0x0000 }, /* R586   -  MICINT Source Pol */
-	[768] = { 0x0001, 0x0001, 0x0000 }, /* R768   - DSP2 Power Management */
-	[1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037  - DSP2_ExecControl */
-	[4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096  - Write Sequencer 0 */
-	[4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097  - Write Sequencer 1 */
-	[4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098  - Write Sequencer 2 */
-	[4099] = { 0x010F, 0x010F, 0x0000 }, /* R4099  - Write Sequencer 3 */
-	[4100] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4100  - Write Sequencer 4 */
-	[4101] = { 0x00FF, 0x00FF, 0x0000 }, /* R4101  - Write Sequencer 5 */
-	[4102] = { 0x070F, 0x070F, 0x0000 }, /* R4102  - Write Sequencer 6 */
-	[4103] = { 0x010F, 0x010F, 0x0000 }, /* R4103  - Write Sequencer 7 */
-	[4104] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4104  - Write Sequencer 8 */
-	[4105] = { 0x00FF, 0x00FF, 0x0000 }, /* R4105  - Write Sequencer 9 */
-	[4106] = { 0x070F, 0x070F, 0x0000 }, /* R4106  - Write Sequencer 10 */
-	[4107] = { 0x010F, 0x010F, 0x0000 }, /* R4107  - Write Sequencer 11 */
-	[4108] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4108  - Write Sequencer 12 */
-	[4109] = { 0x00FF, 0x00FF, 0x0000 }, /* R4109  - Write Sequencer 13 */
-	[4110] = { 0x070F, 0x070F, 0x0000 }, /* R4110  - Write Sequencer 14 */
-	[4111] = { 0x010F, 0x010F, 0x0000 }, /* R4111  - Write Sequencer 15 */
-	[4112] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4112  - Write Sequencer 16 */
-	[4113] = { 0x00FF, 0x00FF, 0x0000 }, /* R4113  - Write Sequencer 17 */
-	[4114] = { 0x070F, 0x070F, 0x0000 }, /* R4114  - Write Sequencer 18 */
-	[4115] = { 0x010F, 0x010F, 0x0000 }, /* R4115  - Write Sequencer 19 */
-	[4116] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4116  - Write Sequencer 20 */
-	[4117] = { 0x00FF, 0x00FF, 0x0000 }, /* R4117  - Write Sequencer 21 */
-	[4118] = { 0x070F, 0x070F, 0x0000 }, /* R4118  - Write Sequencer 22 */
-	[4119] = { 0x010F, 0x010F, 0x0000 }, /* R4119  - Write Sequencer 23 */
-	[4120] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4120  - Write Sequencer 24 */
-	[4121] = { 0x00FF, 0x00FF, 0x0000 }, /* R4121  - Write Sequencer 25 */
-	[4122] = { 0x070F, 0x070F, 0x0000 }, /* R4122  - Write Sequencer 26 */
-	[4123] = { 0x010F, 0x010F, 0x0000 }, /* R4123  - Write Sequencer 27 */
-	[4124] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4124  - Write Sequencer 28 */
-	[4125] = { 0x00FF, 0x00FF, 0x0000 }, /* R4125  - Write Sequencer 29 */
-	[4126] = { 0x070F, 0x070F, 0x0000 }, /* R4126  - Write Sequencer 30 */
-	[4127] = { 0x010F, 0x010F, 0x0000 }, /* R4127  - Write Sequencer 31 */
-	[4128] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4128  - Write Sequencer 32 */
-	[4129] = { 0x00FF, 0x00FF, 0x0000 }, /* R4129  - Write Sequencer 33 */
-	[4130] = { 0x070F, 0x070F, 0x0000 }, /* R4130  - Write Sequencer 34 */
-	[4131] = { 0x010F, 0x010F, 0x0000 }, /* R4131  - Write Sequencer 35 */
-	[4132] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4132  - Write Sequencer 36 */
-	[4133] = { 0x00FF, 0x00FF, 0x0000 }, /* R4133  - Write Sequencer 37 */
-	[4134] = { 0x070F, 0x070F, 0x0000 }, /* R4134  - Write Sequencer 38 */
-	[4135] = { 0x010F, 0x010F, 0x0000 }, /* R4135  - Write Sequencer 39 */
-	[4136] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4136  - Write Sequencer 40 */
-	[4137] = { 0x00FF, 0x00FF, 0x0000 }, /* R4137  - Write Sequencer 41 */
-	[4138] = { 0x070F, 0x070F, 0x0000 }, /* R4138  - Write Sequencer 42 */
-	[4139] = { 0x010F, 0x010F, 0x0000 }, /* R4139  - Write Sequencer 43 */
-	[4140] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4140  - Write Sequencer 44 */
-	[4141] = { 0x00FF, 0x00FF, 0x0000 }, /* R4141  - Write Sequencer 45 */
-	[4142] = { 0x070F, 0x070F, 0x0000 }, /* R4142  - Write Sequencer 46 */
-	[4143] = { 0x010F, 0x010F, 0x0000 }, /* R4143  - Write Sequencer 47 */
-	[4144] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4144  - Write Sequencer 48 */
-	[4145] = { 0x00FF, 0x00FF, 0x0000 }, /* R4145  - Write Sequencer 49 */
-	[4146] = { 0x070F, 0x070F, 0x0000 }, /* R4146  - Write Sequencer 50 */
-	[4147] = { 0x010F, 0x010F, 0x0000 }, /* R4147  - Write Sequencer 51 */
-	[4148] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4148  - Write Sequencer 52 */
-	[4149] = { 0x00FF, 0x00FF, 0x0000 }, /* R4149  - Write Sequencer 53 */
-	[4150] = { 0x070F, 0x070F, 0x0000 }, /* R4150  - Write Sequencer 54 */
-	[4151] = { 0x010F, 0x010F, 0x0000 }, /* R4151  - Write Sequencer 55 */
-	[4152] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4152  - Write Sequencer 56 */
-	[4153] = { 0x00FF, 0x00FF, 0x0000 }, /* R4153  - Write Sequencer 57 */
-	[4154] = { 0x070F, 0x070F, 0x0000 }, /* R4154  - Write Sequencer 58 */
-	[4155] = { 0x010F, 0x010F, 0x0000 }, /* R4155  - Write Sequencer 59 */
-	[4156] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4156  - Write Sequencer 60 */
-	[4157] = { 0x00FF, 0x00FF, 0x0000 }, /* R4157  - Write Sequencer 61 */
-	[4158] = { 0x070F, 0x070F, 0x0000 }, /* R4158  - Write Sequencer 62 */
-	[4159] = { 0x010F, 0x010F, 0x0000 }, /* R4159  - Write Sequencer 63 */
-	[4160] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4160  - Write Sequencer 64 */
-	[4161] = { 0x00FF, 0x00FF, 0x0000 }, /* R4161  - Write Sequencer 65 */
-	[4162] = { 0x070F, 0x070F, 0x0000 }, /* R4162  - Write Sequencer 66 */
-	[4163] = { 0x010F, 0x010F, 0x0000 }, /* R4163  - Write Sequencer 67 */
-	[4164] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4164  - Write Sequencer 68 */
-	[4165] = { 0x00FF, 0x00FF, 0x0000 }, /* R4165  - Write Sequencer 69 */
-	[4166] = { 0x070F, 0x070F, 0x0000 }, /* R4166  - Write Sequencer 70 */
-	[4167] = { 0x010F, 0x010F, 0x0000 }, /* R4167  - Write Sequencer 71 */
-	[4168] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4168  - Write Sequencer 72 */
-	[4169] = { 0x00FF, 0x00FF, 0x0000 }, /* R4169  - Write Sequencer 73 */
-	[4170] = { 0x070F, 0x070F, 0x0000 }, /* R4170  - Write Sequencer 74 */
-	[4171] = { 0x010F, 0x010F, 0x0000 }, /* R4171  - Write Sequencer 75 */
-	[4172] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4172  - Write Sequencer 76 */
-	[4173] = { 0x00FF, 0x00FF, 0x0000 }, /* R4173  - Write Sequencer 77 */
-	[4174] = { 0x070F, 0x070F, 0x0000 }, /* R4174  - Write Sequencer 78 */
-	[4175] = { 0x010F, 0x010F, 0x0000 }, /* R4175  - Write Sequencer 79 */
-	[4176] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4176  - Write Sequencer 80 */
-	[4177] = { 0x00FF, 0x00FF, 0x0000 }, /* R4177  - Write Sequencer 81 */
-	[4178] = { 0x070F, 0x070F, 0x0000 }, /* R4178  - Write Sequencer 82 */
-	[4179] = { 0x010F, 0x010F, 0x0000 }, /* R4179  - Write Sequencer 83 */
-	[4180] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4180  - Write Sequencer 84 */
-	[4181] = { 0x00FF, 0x00FF, 0x0000 }, /* R4181  - Write Sequencer 85 */
-	[4182] = { 0x070F, 0x070F, 0x0000 }, /* R4182  - Write Sequencer 86 */
-	[4183] = { 0x010F, 0x010F, 0x0000 }, /* R4183  - Write Sequencer 87 */
-	[4184] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4184  - Write Sequencer 88 */
-	[4185] = { 0x00FF, 0x00FF, 0x0000 }, /* R4185  - Write Sequencer 89 */
-	[4186] = { 0x070F, 0x070F, 0x0000 }, /* R4186  - Write Sequencer 90 */
-	[4187] = { 0x010F, 0x010F, 0x0000 }, /* R4187  - Write Sequencer 91 */
-	[4188] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4188  - Write Sequencer 92 */
-	[4189] = { 0x00FF, 0x00FF, 0x0000 }, /* R4189  - Write Sequencer 93 */
-	[4190] = { 0x070F, 0x070F, 0x0000 }, /* R4190  - Write Sequencer 94 */
-	[4191] = { 0x010F, 0x010F, 0x0000 }, /* R4191  - Write Sequencer 95 */
-	[4192] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4192  - Write Sequencer 96 */
-	[4193] = { 0x00FF, 0x00FF, 0x0000 }, /* R4193  - Write Sequencer 97 */
-	[4194] = { 0x070F, 0x070F, 0x0000 }, /* R4194  - Write Sequencer 98 */
-	[4195] = { 0x010F, 0x010F, 0x0000 }, /* R4195  - Write Sequencer 99 */
-	[4196] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4196  - Write Sequencer 100 */
-	[4197] = { 0x00FF, 0x00FF, 0x0000 }, /* R4197  - Write Sequencer 101 */
-	[4198] = { 0x070F, 0x070F, 0x0000 }, /* R4198  - Write Sequencer 102 */
-	[4199] = { 0x010F, 0x010F, 0x0000 }, /* R4199  - Write Sequencer 103 */
-	[4200] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4200  - Write Sequencer 104 */
-	[4201] = { 0x00FF, 0x00FF, 0x0000 }, /* R4201  - Write Sequencer 105 */
-	[4202] = { 0x070F, 0x070F, 0x0000 }, /* R4202  - Write Sequencer 106 */
-	[4203] = { 0x010F, 0x010F, 0x0000 }, /* R4203  - Write Sequencer 107 */
-	[4204] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4204  - Write Sequencer 108 */
-	[4205] = { 0x00FF, 0x00FF, 0x0000 }, /* R4205  - Write Sequencer 109 */
-	[4206] = { 0x070F, 0x070F, 0x0000 }, /* R4206  - Write Sequencer 110 */
-	[4207] = { 0x010F, 0x010F, 0x0000 }, /* R4207  - Write Sequencer 111 */
-	[4208] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4208  - Write Sequencer 112 */
-	[4209] = { 0x00FF, 0x00FF, 0x0000 }, /* R4209  - Write Sequencer 113 */
-	[4210] = { 0x070F, 0x070F, 0x0000 }, /* R4210  - Write Sequencer 114 */
-	[4211] = { 0x010F, 0x010F, 0x0000 }, /* R4211  - Write Sequencer 115 */
-	[4212] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4212  - Write Sequencer 116 */
-	[4213] = { 0x00FF, 0x00FF, 0x0000 }, /* R4213  - Write Sequencer 117 */
-	[4214] = { 0x070F, 0x070F, 0x0000 }, /* R4214  - Write Sequencer 118 */
-	[4215] = { 0x010F, 0x010F, 0x0000 }, /* R4215  - Write Sequencer 119 */
-	[4216] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4216  - Write Sequencer 120 */
-	[4217] = { 0x00FF, 0x00FF, 0x0000 }, /* R4217  - Write Sequencer 121 */
-	[4218] = { 0x070F, 0x070F, 0x0000 }, /* R4218  - Write Sequencer 122 */
-	[4219] = { 0x010F, 0x010F, 0x0000 }, /* R4219  - Write Sequencer 123 */
-	[4220] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4220  - Write Sequencer 124 */
-	[4221] = { 0x00FF, 0x00FF, 0x0000 }, /* R4221  - Write Sequencer 125 */
-	[4222] = { 0x070F, 0x070F, 0x0000 }, /* R4222  - Write Sequencer 126 */
-	[4223] = { 0x010F, 0x010F, 0x0000 }, /* R4223  - Write Sequencer 127 */
-	[4224] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4224  - Write Sequencer 128 */
-	[4225] = { 0x00FF, 0x00FF, 0x0000 }, /* R4225  - Write Sequencer 129 */
-	[4226] = { 0x070F, 0x070F, 0x0000 }, /* R4226  - Write Sequencer 130 */
-	[4227] = { 0x010F, 0x010F, 0x0000 }, /* R4227  - Write Sequencer 131 */
-	[4228] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4228  - Write Sequencer 132 */
-	[4229] = { 0x00FF, 0x00FF, 0x0000 }, /* R4229  - Write Sequencer 133 */
-	[4230] = { 0x070F, 0x070F, 0x0000 }, /* R4230  - Write Sequencer 134 */
-	[4231] = { 0x010F, 0x010F, 0x0000 }, /* R4231  - Write Sequencer 135 */
-	[4232] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4232  - Write Sequencer 136 */
-	[4233] = { 0x00FF, 0x00FF, 0x0000 }, /* R4233  - Write Sequencer 137 */
-	[4234] = { 0x070F, 0x070F, 0x0000 }, /* R4234  - Write Sequencer 138 */
-	[4235] = { 0x010F, 0x010F, 0x0000 }, /* R4235  - Write Sequencer 139 */
-	[4236] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4236  - Write Sequencer 140 */
-	[4237] = { 0x00FF, 0x00FF, 0x0000 }, /* R4237  - Write Sequencer 141 */
-	[4238] = { 0x070F, 0x070F, 0x0000 }, /* R4238  - Write Sequencer 142 */
-	[4239] = { 0x010F, 0x010F, 0x0000 }, /* R4239  - Write Sequencer 143 */
-	[4240] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4240  - Write Sequencer 144 */
-	[4241] = { 0x00FF, 0x00FF, 0x0000 }, /* R4241  - Write Sequencer 145 */
-	[4242] = { 0x070F, 0x070F, 0x0000 }, /* R4242  - Write Sequencer 146 */
-	[4243] = { 0x010F, 0x010F, 0x0000 }, /* R4243  - Write Sequencer 147 */
-	[4244] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4244  - Write Sequencer 148 */
-	[4245] = { 0x00FF, 0x00FF, 0x0000 }, /* R4245  - Write Sequencer 149 */
-	[4246] = { 0x070F, 0x070F, 0x0000 }, /* R4246  - Write Sequencer 150 */
-	[4247] = { 0x010F, 0x010F, 0x0000 }, /* R4247  - Write Sequencer 151 */
-	[4248] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4248  - Write Sequencer 152 */
-	[4249] = { 0x00FF, 0x00FF, 0x0000 }, /* R4249  - Write Sequencer 153 */
-	[4250] = { 0x070F, 0x070F, 0x0000 }, /* R4250  - Write Sequencer 154 */
-	[4251] = { 0x010F, 0x010F, 0x0000 }, /* R4251  - Write Sequencer 155 */
-	[4252] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4252  - Write Sequencer 156 */
-	[4253] = { 0x00FF, 0x00FF, 0x0000 }, /* R4253  - Write Sequencer 157 */
-	[4254] = { 0x070F, 0x070F, 0x0000 }, /* R4254  - Write Sequencer 158 */
-	[4255] = { 0x010F, 0x010F, 0x0000 }, /* R4255  - Write Sequencer 159 */
-	[4256] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4256  - Write Sequencer 160 */
-	[4257] = { 0x00FF, 0x00FF, 0x0000 }, /* R4257  - Write Sequencer 161 */
-	[4258] = { 0x070F, 0x070F, 0x0000 }, /* R4258  - Write Sequencer 162 */
-	[4259] = { 0x010F, 0x010F, 0x0000 }, /* R4259  - Write Sequencer 163 */
-	[4260] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4260  - Write Sequencer 164 */
-	[4261] = { 0x00FF, 0x00FF, 0x0000 }, /* R4261  - Write Sequencer 165 */
-	[4262] = { 0x070F, 0x070F, 0x0000 }, /* R4262  - Write Sequencer 166 */
-	[4263] = { 0x010F, 0x010F, 0x0000 }, /* R4263  - Write Sequencer 167 */
-	[4264] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4264  - Write Sequencer 168 */
-	[4265] = { 0x00FF, 0x00FF, 0x0000 }, /* R4265  - Write Sequencer 169 */
-	[4266] = { 0x070F, 0x070F, 0x0000 }, /* R4266  - Write Sequencer 170 */
-	[4267] = { 0x010F, 0x010F, 0x0000 }, /* R4267  - Write Sequencer 171 */
-	[4268] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4268  - Write Sequencer 172 */
-	[4269] = { 0x00FF, 0x00FF, 0x0000 }, /* R4269  - Write Sequencer 173 */
-	[4270] = { 0x070F, 0x070F, 0x0000 }, /* R4270  - Write Sequencer 174 */
-	[4271] = { 0x010F, 0x010F, 0x0000 }, /* R4271  - Write Sequencer 175 */
-	[4272] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4272  - Write Sequencer 176 */
-	[4273] = { 0x00FF, 0x00FF, 0x0000 }, /* R4273  - Write Sequencer 177 */
-	[4274] = { 0x070F, 0x070F, 0x0000 }, /* R4274  - Write Sequencer 178 */
-	[4275] = { 0x010F, 0x010F, 0x0000 }, /* R4275  - Write Sequencer 179 */
-	[4276] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4276  - Write Sequencer 180 */
-	[4277] = { 0x00FF, 0x00FF, 0x0000 }, /* R4277  - Write Sequencer 181 */
-	[4278] = { 0x070F, 0x070F, 0x0000 }, /* R4278  - Write Sequencer 182 */
-	[4279] = { 0x010F, 0x010F, 0x0000 }, /* R4279  - Write Sequencer 183 */
-	[4280] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4280  - Write Sequencer 184 */
-	[4281] = { 0x00FF, 0x00FF, 0x0000 }, /* R4281  - Write Sequencer 185 */
-	[4282] = { 0x070F, 0x070F, 0x0000 }, /* R4282  - Write Sequencer 186 */
-	[4283] = { 0x010F, 0x010F, 0x0000 }, /* R4283  - Write Sequencer 187 */
-	[4284] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4284  - Write Sequencer 188 */
-	[4285] = { 0x00FF, 0x00FF, 0x0000 }, /* R4285  - Write Sequencer 189 */
-	[4286] = { 0x070F, 0x070F, 0x0000 }, /* R4286  - Write Sequencer 190 */
-	[4287] = { 0x010F, 0x010F, 0x0000 }, /* R4287  - Write Sequencer 191 */
-	[4288] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4288  - Write Sequencer 192 */
-	[4289] = { 0x00FF, 0x00FF, 0x0000 }, /* R4289  - Write Sequencer 193 */
-	[4290] = { 0x070F, 0x070F, 0x0000 }, /* R4290  - Write Sequencer 194 */
-	[4291] = { 0x010F, 0x010F, 0x0000 }, /* R4291  - Write Sequencer 195 */
-	[4292] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4292  - Write Sequencer 196 */
-	[4293] = { 0x00FF, 0x00FF, 0x0000 }, /* R4293  - Write Sequencer 197 */
-	[4294] = { 0x070F, 0x070F, 0x0000 }, /* R4294  - Write Sequencer 198 */
-	[4295] = { 0x010F, 0x010F, 0x0000 }, /* R4295  - Write Sequencer 199 */
-	[4296] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4296  - Write Sequencer 200 */
-	[4297] = { 0x00FF, 0x00FF, 0x0000 }, /* R4297  - Write Sequencer 201 */
-	[4298] = { 0x070F, 0x070F, 0x0000 }, /* R4298  - Write Sequencer 202 */
-	[4299] = { 0x010F, 0x010F, 0x0000 }, /* R4299  - Write Sequencer 203 */
-	[4300] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4300  - Write Sequencer 204 */
-	[4301] = { 0x00FF, 0x00FF, 0x0000 }, /* R4301  - Write Sequencer 205 */
-	[4302] = { 0x070F, 0x070F, 0x0000 }, /* R4302  - Write Sequencer 206 */
-	[4303] = { 0x010F, 0x010F, 0x0000 }, /* R4303  - Write Sequencer 207 */
-	[4304] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4304  - Write Sequencer 208 */
-	[4305] = { 0x00FF, 0x00FF, 0x0000 }, /* R4305  - Write Sequencer 209 */
-	[4306] = { 0x070F, 0x070F, 0x0000 }, /* R4306  - Write Sequencer 210 */
-	[4307] = { 0x010F, 0x010F, 0x0000 }, /* R4307  - Write Sequencer 211 */
-	[4308] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4308  - Write Sequencer 212 */
-	[4309] = { 0x00FF, 0x00FF, 0x0000 }, /* R4309  - Write Sequencer 213 */
-	[4310] = { 0x070F, 0x070F, 0x0000 }, /* R4310  - Write Sequencer 214 */
-	[4311] = { 0x010F, 0x010F, 0x0000 }, /* R4311  - Write Sequencer 215 */
-	[4312] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4312  - Write Sequencer 216 */
-	[4313] = { 0x00FF, 0x00FF, 0x0000 }, /* R4313  - Write Sequencer 217 */
-	[4314] = { 0x070F, 0x070F, 0x0000 }, /* R4314  - Write Sequencer 218 */
-	[4315] = { 0x010F, 0x010F, 0x0000 }, /* R4315  - Write Sequencer 219 */
-	[4316] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4316  - Write Sequencer 220 */
-	[4317] = { 0x00FF, 0x00FF, 0x0000 }, /* R4317  - Write Sequencer 221 */
-	[4318] = { 0x070F, 0x070F, 0x0000 }, /* R4318  - Write Sequencer 222 */
-	[4319] = { 0x010F, 0x010F, 0x0000 }, /* R4319  - Write Sequencer 223 */
-	[4320] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4320  - Write Sequencer 224 */
-	[4321] = { 0x00FF, 0x00FF, 0x0000 }, /* R4321  - Write Sequencer 225 */
-	[4322] = { 0x070F, 0x070F, 0x0000 }, /* R4322  - Write Sequencer 226 */
-	[4323] = { 0x010F, 0x010F, 0x0000 }, /* R4323  - Write Sequencer 227 */
-	[4324] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4324  - Write Sequencer 228 */
-	[4325] = { 0x00FF, 0x00FF, 0x0000 }, /* R4325  - Write Sequencer 229 */
-	[4326] = { 0x070F, 0x070F, 0x0000 }, /* R4326  - Write Sequencer 230 */
-	[4327] = { 0x010F, 0x010F, 0x0000 }, /* R4327  - Write Sequencer 231 */
-	[4328] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4328  - Write Sequencer 232 */
-	[4329] = { 0x00FF, 0x00FF, 0x0000 }, /* R4329  - Write Sequencer 233 */
-	[4330] = { 0x070F, 0x070F, 0x0000 }, /* R4330  - Write Sequencer 234 */
-	[4331] = { 0x010F, 0x010F, 0x0000 }, /* R4331  - Write Sequencer 235 */
-	[4332] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4332  - Write Sequencer 236 */
-	[4333] = { 0x00FF, 0x00FF, 0x0000 }, /* R4333  - Write Sequencer 237 */
-	[4334] = { 0x070F, 0x070F, 0x0000 }, /* R4334  - Write Sequencer 238 */
-	[4335] = { 0x010F, 0x010F, 0x0000 }, /* R4335  - Write Sequencer 239 */
-	[4336] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4336  - Write Sequencer 240 */
-	[4337] = { 0x00FF, 0x00FF, 0x0000 }, /* R4337  - Write Sequencer 241 */
-	[4338] = { 0x070F, 0x070F, 0x0000 }, /* R4338  - Write Sequencer 242 */
-	[4339] = { 0x010F, 0x010F, 0x0000 }, /* R4339  - Write Sequencer 243 */
-	[4340] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4340  - Write Sequencer 244 */
-	[4341] = { 0x00FF, 0x00FF, 0x0000 }, /* R4341  - Write Sequencer 245 */
-	[4342] = { 0x070F, 0x070F, 0x0000 }, /* R4342  - Write Sequencer 246 */
-	[4343] = { 0x010F, 0x010F, 0x0000 }, /* R4343  - Write Sequencer 247 */
-	[4344] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4344  - Write Sequencer 248 */
-	[4345] = { 0x00FF, 0x00FF, 0x0000 }, /* R4345  - Write Sequencer 249 */
-	[4346] = { 0x070F, 0x070F, 0x0000 }, /* R4346  - Write Sequencer 250 */
-	[4347] = { 0x010F, 0x010F, 0x0000 }, /* R4347  - Write Sequencer 251 */
-	[4348] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4348  - Write Sequencer 252 */
-	[4349] = { 0x00FF, 0x00FF, 0x0000 }, /* R4349  - Write Sequencer 253 */
-	[4350] = { 0x070F, 0x070F, 0x0000 }, /* R4350  - Write Sequencer 254 */
-	[4351] = { 0x010F, 0x010F, 0x0000 }, /* R4351  - Write Sequencer 255 */
-	[4352] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4352  - Write Sequencer 256 */
-	[4353] = { 0x00FF, 0x00FF, 0x0000 }, /* R4353  - Write Sequencer 257 */
-	[4354] = { 0x070F, 0x070F, 0x0000 }, /* R4354  - Write Sequencer 258 */
-	[4355] = { 0x010F, 0x010F, 0x0000 }, /* R4355  - Write Sequencer 259 */
-	[4356] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4356  - Write Sequencer 260 */
-	[4357] = { 0x00FF, 0x00FF, 0x0000 }, /* R4357  - Write Sequencer 261 */
-	[4358] = { 0x070F, 0x070F, 0x0000 }, /* R4358  - Write Sequencer 262 */
-	[4359] = { 0x010F, 0x010F, 0x0000 }, /* R4359  - Write Sequencer 263 */
-	[4360] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4360  - Write Sequencer 264 */
-	[4361] = { 0x00FF, 0x00FF, 0x0000 }, /* R4361  - Write Sequencer 265 */
-	[4362] = { 0x070F, 0x070F, 0x0000 }, /* R4362  - Write Sequencer 266 */
-	[4363] = { 0x010F, 0x010F, 0x0000 }, /* R4363  - Write Sequencer 267 */
-	[4364] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4364  - Write Sequencer 268 */
-	[4365] = { 0x00FF, 0x00FF, 0x0000 }, /* R4365  - Write Sequencer 269 */
-	[4366] = { 0x070F, 0x070F, 0x0000 }, /* R4366  - Write Sequencer 270 */
-	[4367] = { 0x010F, 0x010F, 0x0000 }, /* R4367  - Write Sequencer 271 */
-	[4368] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4368  - Write Sequencer 272 */
-	[4369] = { 0x00FF, 0x00FF, 0x0000 }, /* R4369  - Write Sequencer 273 */
-	[4370] = { 0x070F, 0x070F, 0x0000 }, /* R4370  - Write Sequencer 274 */
-	[4371] = { 0x010F, 0x010F, 0x0000 }, /* R4371  - Write Sequencer 275 */
-	[4372] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4372  - Write Sequencer 276 */
-	[4373] = { 0x00FF, 0x00FF, 0x0000 }, /* R4373  - Write Sequencer 277 */
-	[4374] = { 0x070F, 0x070F, 0x0000 }, /* R4374  - Write Sequencer 278 */
-	[4375] = { 0x010F, 0x010F, 0x0000 }, /* R4375  - Write Sequencer 279 */
-	[4376] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4376  - Write Sequencer 280 */
-	[4377] = { 0x00FF, 0x00FF, 0x0000 }, /* R4377  - Write Sequencer 281 */
-	[4378] = { 0x070F, 0x070F, 0x0000 }, /* R4378  - Write Sequencer 282 */
-	[4379] = { 0x010F, 0x010F, 0x0000 }, /* R4379  - Write Sequencer 283 */
-	[4380] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4380  - Write Sequencer 284 */
-	[4381] = { 0x00FF, 0x00FF, 0x0000 }, /* R4381  - Write Sequencer 285 */
-	[4382] = { 0x070F, 0x070F, 0x0000 }, /* R4382  - Write Sequencer 286 */
-	[4383] = { 0x010F, 0x010F, 0x0000 }, /* R4383  - Write Sequencer 287 */
-	[4384] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4384  - Write Sequencer 288 */
-	[4385] = { 0x00FF, 0x00FF, 0x0000 }, /* R4385  - Write Sequencer 289 */
-	[4386] = { 0x070F, 0x070F, 0x0000 }, /* R4386  - Write Sequencer 290 */
-	[4387] = { 0x010F, 0x010F, 0x0000 }, /* R4387  - Write Sequencer 291 */
-	[4388] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4388  - Write Sequencer 292 */
-	[4389] = { 0x00FF, 0x00FF, 0x0000 }, /* R4389  - Write Sequencer 293 */
-	[4390] = { 0x070F, 0x070F, 0x0000 }, /* R4390  - Write Sequencer 294 */
-	[4391] = { 0x010F, 0x010F, 0x0000 }, /* R4391  - Write Sequencer 295 */
-	[4392] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4392  - Write Sequencer 296 */
-	[4393] = { 0x00FF, 0x00FF, 0x0000 }, /* R4393  - Write Sequencer 297 */
-	[4394] = { 0x070F, 0x070F, 0x0000 }, /* R4394  - Write Sequencer 298 */
-	[4395] = { 0x010F, 0x010F, 0x0000 }, /* R4395  - Write Sequencer 299 */
-	[4396] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4396  - Write Sequencer 300 */
-	[4397] = { 0x00FF, 0x00FF, 0x0000 }, /* R4397  - Write Sequencer 301 */
-	[4398] = { 0x070F, 0x070F, 0x0000 }, /* R4398  - Write Sequencer 302 */
-	[4399] = { 0x010F, 0x010F, 0x0000 }, /* R4399  - Write Sequencer 303 */
-	[4400] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4400  - Write Sequencer 304 */
-	[4401] = { 0x00FF, 0x00FF, 0x0000 }, /* R4401  - Write Sequencer 305 */
-	[4402] = { 0x070F, 0x070F, 0x0000 }, /* R4402  - Write Sequencer 306 */
-	[4403] = { 0x010F, 0x010F, 0x0000 }, /* R4403  - Write Sequencer 307 */
-	[4404] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4404  - Write Sequencer 308 */
-	[4405] = { 0x00FF, 0x00FF, 0x0000 }, /* R4405  - Write Sequencer 309 */
-	[4406] = { 0x070F, 0x070F, 0x0000 }, /* R4406  - Write Sequencer 310 */
-	[4407] = { 0x010F, 0x010F, 0x0000 }, /* R4407  - Write Sequencer 311 */
-	[4408] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4408  - Write Sequencer 312 */
-	[4409] = { 0x00FF, 0x00FF, 0x0000 }, /* R4409  - Write Sequencer 313 */
-	[4410] = { 0x070F, 0x070F, 0x0000 }, /* R4410  - Write Sequencer 314 */
-	[4411] = { 0x010F, 0x010F, 0x0000 }, /* R4411  - Write Sequencer 315 */
-	[4412] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4412  - Write Sequencer 316 */
-	[4413] = { 0x00FF, 0x00FF, 0x0000 }, /* R4413  - Write Sequencer 317 */
-	[4414] = { 0x070F, 0x070F, 0x0000 }, /* R4414  - Write Sequencer 318 */
-	[4415] = { 0x010F, 0x010F, 0x0000 }, /* R4415  - Write Sequencer 319 */
-	[4416] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4416  - Write Sequencer 320 */
-	[4417] = { 0x00FF, 0x00FF, 0x0000 }, /* R4417  - Write Sequencer 321 */
-	[4418] = { 0x070F, 0x070F, 0x0000 }, /* R4418  - Write Sequencer 322 */
-	[4419] = { 0x010F, 0x010F, 0x0000 }, /* R4419  - Write Sequencer 323 */
-	[4420] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4420  - Write Sequencer 324 */
-	[4421] = { 0x00FF, 0x00FF, 0x0000 }, /* R4421  - Write Sequencer 325 */
-	[4422] = { 0x070F, 0x070F, 0x0000 }, /* R4422  - Write Sequencer 326 */
-	[4423] = { 0x010F, 0x010F, 0x0000 }, /* R4423  - Write Sequencer 327 */
-	[4424] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4424  - Write Sequencer 328 */
-	[4425] = { 0x00FF, 0x00FF, 0x0000 }, /* R4425  - Write Sequencer 329 */
-	[4426] = { 0x070F, 0x070F, 0x0000 }, /* R4426  - Write Sequencer 330 */
-	[4427] = { 0x010F, 0x010F, 0x0000 }, /* R4427  - Write Sequencer 331 */
-	[4428] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4428  - Write Sequencer 332 */
-	[4429] = { 0x00FF, 0x00FF, 0x0000 }, /* R4429  - Write Sequencer 333 */
-	[4430] = { 0x070F, 0x070F, 0x0000 }, /* R4430  - Write Sequencer 334 */
-	[4431] = { 0x010F, 0x010F, 0x0000 }, /* R4431  - Write Sequencer 335 */
-	[4432] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4432  - Write Sequencer 336 */
-	[4433] = { 0x00FF, 0x00FF, 0x0000 }, /* R4433  - Write Sequencer 337 */
-	[4434] = { 0x070F, 0x070F, 0x0000 }, /* R4434  - Write Sequencer 338 */
-	[4435] = { 0x010F, 0x010F, 0x0000 }, /* R4435  - Write Sequencer 339 */
-	[4436] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4436  - Write Sequencer 340 */
-	[4437] = { 0x00FF, 0x00FF, 0x0000 }, /* R4437  - Write Sequencer 341 */
-	[4438] = { 0x070F, 0x070F, 0x0000 }, /* R4438  - Write Sequencer 342 */
-	[4439] = { 0x010F, 0x010F, 0x0000 }, /* R4439  - Write Sequencer 343 */
-	[4440] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4440  - Write Sequencer 344 */
-	[4441] = { 0x00FF, 0x00FF, 0x0000 }, /* R4441  - Write Sequencer 345 */
-	[4442] = { 0x070F, 0x070F, 0x0000 }, /* R4442  - Write Sequencer 346 */
-	[4443] = { 0x010F, 0x010F, 0x0000 }, /* R4443  - Write Sequencer 347 */
-	[4444] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4444  - Write Sequencer 348 */
-	[4445] = { 0x00FF, 0x00FF, 0x0000 }, /* R4445  - Write Sequencer 349 */
-	[4446] = { 0x070F, 0x070F, 0x0000 }, /* R4446  - Write Sequencer 350 */
-	[4447] = { 0x010F, 0x010F, 0x0000 }, /* R4447  - Write Sequencer 351 */
-	[4448] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4448  - Write Sequencer 352 */
-	[4449] = { 0x00FF, 0x00FF, 0x0000 }, /* R4449  - Write Sequencer 353 */
-	[4450] = { 0x070F, 0x070F, 0x0000 }, /* R4450  - Write Sequencer 354 */
-	[4451] = { 0x010F, 0x010F, 0x0000 }, /* R4451  - Write Sequencer 355 */
-	[4452] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4452  - Write Sequencer 356 */
-	[4453] = { 0x00FF, 0x00FF, 0x0000 }, /* R4453  - Write Sequencer 357 */
-	[4454] = { 0x070F, 0x070F, 0x0000 }, /* R4454  - Write Sequencer 358 */
-	[4455] = { 0x010F, 0x010F, 0x0000 }, /* R4455  - Write Sequencer 359 */
-	[4456] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4456  - Write Sequencer 360 */
-	[4457] = { 0x00FF, 0x00FF, 0x0000 }, /* R4457  - Write Sequencer 361 */
-	[4458] = { 0x070F, 0x070F, 0x0000 }, /* R4458  - Write Sequencer 362 */
-	[4459] = { 0x010F, 0x010F, 0x0000 }, /* R4459  - Write Sequencer 363 */
-	[4460] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4460  - Write Sequencer 364 */
-	[4461] = { 0x00FF, 0x00FF, 0x0000 }, /* R4461  - Write Sequencer 365 */
-	[4462] = { 0x070F, 0x070F, 0x0000 }, /* R4462  - Write Sequencer 366 */
-	[4463] = { 0x010F, 0x010F, 0x0000 }, /* R4463  - Write Sequencer 367 */
-	[4464] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4464  - Write Sequencer 368 */
-	[4465] = { 0x00FF, 0x00FF, 0x0000 }, /* R4465  - Write Sequencer 369 */
-	[4466] = { 0x070F, 0x070F, 0x0000 }, /* R4466  - Write Sequencer 370 */
-	[4467] = { 0x010F, 0x010F, 0x0000 }, /* R4467  - Write Sequencer 371 */
-	[4468] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4468  - Write Sequencer 372 */
-	[4469] = { 0x00FF, 0x00FF, 0x0000 }, /* R4469  - Write Sequencer 373 */
-	[4470] = { 0x070F, 0x070F, 0x0000 }, /* R4470  - Write Sequencer 374 */
-	[4471] = { 0x010F, 0x010F, 0x0000 }, /* R4471  - Write Sequencer 375 */
-	[4472] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4472  - Write Sequencer 376 */
-	[4473] = { 0x00FF, 0x00FF, 0x0000 }, /* R4473  - Write Sequencer 377 */
-	[4474] = { 0x070F, 0x070F, 0x0000 }, /* R4474  - Write Sequencer 378 */
-	[4475] = { 0x010F, 0x010F, 0x0000 }, /* R4475  - Write Sequencer 379 */
-	[4476] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4476  - Write Sequencer 380 */
-	[4477] = { 0x00FF, 0x00FF, 0x0000 }, /* R4477  - Write Sequencer 381 */
-	[4478] = { 0x070F, 0x070F, 0x0000 }, /* R4478  - Write Sequencer 382 */
-	[4479] = { 0x010F, 0x010F, 0x0000 }, /* R4479  - Write Sequencer 383 */
-	[4480] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4480  - Write Sequencer 384 */
-	[4481] = { 0x00FF, 0x00FF, 0x0000 }, /* R4481  - Write Sequencer 385 */
-	[4482] = { 0x070F, 0x070F, 0x0000 }, /* R4482  - Write Sequencer 386 */
-	[4483] = { 0x010F, 0x010F, 0x0000 }, /* R4483  - Write Sequencer 387 */
-	[4484] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4484  - Write Sequencer 388 */
-	[4485] = { 0x00FF, 0x00FF, 0x0000 }, /* R4485  - Write Sequencer 389 */
-	[4486] = { 0x070F, 0x070F, 0x0000 }, /* R4486  - Write Sequencer 390 */
-	[4487] = { 0x010F, 0x010F, 0x0000 }, /* R4487  - Write Sequencer 391 */
-	[4488] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4488  - Write Sequencer 392 */
-	[4489] = { 0x00FF, 0x00FF, 0x0000 }, /* R4489  - Write Sequencer 393 */
-	[4490] = { 0x070F, 0x070F, 0x0000 }, /* R4490  - Write Sequencer 394 */
-	[4491] = { 0x010F, 0x010F, 0x0000 }, /* R4491  - Write Sequencer 395 */
-	[4492] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4492  - Write Sequencer 396 */
-	[4493] = { 0x00FF, 0x00FF, 0x0000 }, /* R4493  - Write Sequencer 397 */
-	[4494] = { 0x070F, 0x070F, 0x0000 }, /* R4494  - Write Sequencer 398 */
-	[4495] = { 0x010F, 0x010F, 0x0000 }, /* R4495  - Write Sequencer 399 */
-	[4496] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4496  - Write Sequencer 400 */
-	[4497] = { 0x00FF, 0x00FF, 0x0000 }, /* R4497  - Write Sequencer 401 */
-	[4498] = { 0x070F, 0x070F, 0x0000 }, /* R4498  - Write Sequencer 402 */
-	[4499] = { 0x010F, 0x010F, 0x0000 }, /* R4499  - Write Sequencer 403 */
-	[4500] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4500  - Write Sequencer 404 */
-	[4501] = { 0x00FF, 0x00FF, 0x0000 }, /* R4501  - Write Sequencer 405 */
-	[4502] = { 0x070F, 0x070F, 0x0000 }, /* R4502  - Write Sequencer 406 */
-	[4503] = { 0x010F, 0x010F, 0x0000 }, /* R4503  - Write Sequencer 407 */
-	[4504] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4504  - Write Sequencer 408 */
-	[4505] = { 0x00FF, 0x00FF, 0x0000 }, /* R4505  - Write Sequencer 409 */
-	[4506] = { 0x070F, 0x070F, 0x0000 }, /* R4506  - Write Sequencer 410 */
-	[4507] = { 0x010F, 0x010F, 0x0000 }, /* R4507  - Write Sequencer 411 */
-	[4508] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4508  - Write Sequencer 412 */
-	[4509] = { 0x00FF, 0x00FF, 0x0000 }, /* R4509  - Write Sequencer 413 */
-	[4510] = { 0x070F, 0x070F, 0x0000 }, /* R4510  - Write Sequencer 414 */
-	[4511] = { 0x010F, 0x010F, 0x0000 }, /* R4511  - Write Sequencer 415 */
-	[4512] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4512  - Write Sequencer 416 */
-	[4513] = { 0x00FF, 0x00FF, 0x0000 }, /* R4513  - Write Sequencer 417 */
-	[4514] = { 0x070F, 0x070F, 0x0000 }, /* R4514  - Write Sequencer 418 */
-	[4515] = { 0x010F, 0x010F, 0x0000 }, /* R4515  - Write Sequencer 419 */
-	[4516] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4516  - Write Sequencer 420 */
-	[4517] = { 0x00FF, 0x00FF, 0x0000 }, /* R4517  - Write Sequencer 421 */
-	[4518] = { 0x070F, 0x070F, 0x0000 }, /* R4518  - Write Sequencer 422 */
-	[4519] = { 0x010F, 0x010F, 0x0000 }, /* R4519  - Write Sequencer 423 */
-	[4520] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4520  - Write Sequencer 424 */
-	[4521] = { 0x00FF, 0x00FF, 0x0000 }, /* R4521  - Write Sequencer 425 */
-	[4522] = { 0x070F, 0x070F, 0x0000 }, /* R4522  - Write Sequencer 426 */
-	[4523] = { 0x010F, 0x010F, 0x0000 }, /* R4523  - Write Sequencer 427 */
-	[4524] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4524  - Write Sequencer 428 */
-	[4525] = { 0x00FF, 0x00FF, 0x0000 }, /* R4525  - Write Sequencer 429 */
-	[4526] = { 0x070F, 0x070F, 0x0000 }, /* R4526  - Write Sequencer 430 */
-	[4527] = { 0x010F, 0x010F, 0x0000 }, /* R4527  - Write Sequencer 431 */
-	[4528] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4528  - Write Sequencer 432 */
-	[4529] = { 0x00FF, 0x00FF, 0x0000 }, /* R4529  - Write Sequencer 433 */
-	[4530] = { 0x070F, 0x070F, 0x0000 }, /* R4530  - Write Sequencer 434 */
-	[4531] = { 0x010F, 0x010F, 0x0000 }, /* R4531  - Write Sequencer 435 */
-	[4532] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4532  - Write Sequencer 436 */
-	[4533] = { 0x00FF, 0x00FF, 0x0000 }, /* R4533  - Write Sequencer 437 */
-	[4534] = { 0x070F, 0x070F, 0x0000 }, /* R4534  - Write Sequencer 438 */
-	[4535] = { 0x010F, 0x010F, 0x0000 }, /* R4535  - Write Sequencer 439 */
-	[4536] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4536  - Write Sequencer 440 */
-	[4537] = { 0x00FF, 0x00FF, 0x0000 }, /* R4537  - Write Sequencer 441 */
-	[4538] = { 0x070F, 0x070F, 0x0000 }, /* R4538  - Write Sequencer 442 */
-	[4539] = { 0x010F, 0x010F, 0x0000 }, /* R4539  - Write Sequencer 443 */
-	[4540] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4540  - Write Sequencer 444 */
-	[4541] = { 0x00FF, 0x00FF, 0x0000 }, /* R4541  - Write Sequencer 445 */
-	[4542] = { 0x070F, 0x070F, 0x0000 }, /* R4542  - Write Sequencer 446 */
-	[4543] = { 0x010F, 0x010F, 0x0000 }, /* R4543  - Write Sequencer 447 */
-	[4544] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4544  - Write Sequencer 448 */
-	[4545] = { 0x00FF, 0x00FF, 0x0000 }, /* R4545  - Write Sequencer 449 */
-	[4546] = { 0x070F, 0x070F, 0x0000 }, /* R4546  - Write Sequencer 450 */
-	[4547] = { 0x010F, 0x010F, 0x0000 }, /* R4547  - Write Sequencer 451 */
-	[4548] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4548  - Write Sequencer 452 */
-	[4549] = { 0x00FF, 0x00FF, 0x0000 }, /* R4549  - Write Sequencer 453 */
-	[4550] = { 0x070F, 0x070F, 0x0000 }, /* R4550  - Write Sequencer 454 */
-	[4551] = { 0x010F, 0x010F, 0x0000 }, /* R4551  - Write Sequencer 455 */
-	[4552] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4552  - Write Sequencer 456 */
-	[4553] = { 0x00FF, 0x00FF, 0x0000 }, /* R4553  - Write Sequencer 457 */
-	[4554] = { 0x070F, 0x070F, 0x0000 }, /* R4554  - Write Sequencer 458 */
-	[4555] = { 0x010F, 0x010F, 0x0000 }, /* R4555  - Write Sequencer 459 */
-	[4556] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4556  - Write Sequencer 460 */
-	[4557] = { 0x00FF, 0x00FF, 0x0000 }, /* R4557  - Write Sequencer 461 */
-	[4558] = { 0x070F, 0x070F, 0x0000 }, /* R4558  - Write Sequencer 462 */
-	[4559] = { 0x010F, 0x010F, 0x0000 }, /* R4559  - Write Sequencer 463 */
-	[4560] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4560  - Write Sequencer 464 */
-	[4561] = { 0x00FF, 0x00FF, 0x0000 }, /* R4561  - Write Sequencer 465 */
-	[4562] = { 0x070F, 0x070F, 0x0000 }, /* R4562  - Write Sequencer 466 */
-	[4563] = { 0x010F, 0x010F, 0x0000 }, /* R4563  - Write Sequencer 467 */
-	[4564] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4564  - Write Sequencer 468 */
-	[4565] = { 0x00FF, 0x00FF, 0x0000 }, /* R4565  - Write Sequencer 469 */
-	[4566] = { 0x070F, 0x070F, 0x0000 }, /* R4566  - Write Sequencer 470 */
-	[4567] = { 0x010F, 0x010F, 0x0000 }, /* R4567  - Write Sequencer 471 */
-	[4568] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4568  - Write Sequencer 472 */
-	[4569] = { 0x00FF, 0x00FF, 0x0000 }, /* R4569  - Write Sequencer 473 */
-	[4570] = { 0x070F, 0x070F, 0x0000 }, /* R4570  - Write Sequencer 474 */
-	[4571] = { 0x010F, 0x010F, 0x0000 }, /* R4571  - Write Sequencer 475 */
-	[4572] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4572  - Write Sequencer 476 */
-	[4573] = { 0x00FF, 0x00FF, 0x0000 }, /* R4573  - Write Sequencer 477 */
-	[4574] = { 0x070F, 0x070F, 0x0000 }, /* R4574  - Write Sequencer 478 */
-	[4575] = { 0x010F, 0x010F, 0x0000 }, /* R4575  - Write Sequencer 479 */
-	[4576] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4576  - Write Sequencer 480 */
-	[4577] = { 0x00FF, 0x00FF, 0x0000 }, /* R4577  - Write Sequencer 481 */
-	[4578] = { 0x070F, 0x070F, 0x0000 }, /* R4578  - Write Sequencer 482 */
-	[4579] = { 0x010F, 0x010F, 0x0000 }, /* R4579  - Write Sequencer 483 */
-	[4580] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4580  - Write Sequencer 484 */
-	[4581] = { 0x00FF, 0x00FF, 0x0000 }, /* R4581  - Write Sequencer 485 */
-	[4582] = { 0x070F, 0x070F, 0x0000 }, /* R4582  - Write Sequencer 486 */
-	[4583] = { 0x010F, 0x010F, 0x0000 }, /* R4583  - Write Sequencer 487 */
-	[4584] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4584  - Write Sequencer 488 */
-	[4585] = { 0x00FF, 0x00FF, 0x0000 }, /* R4585  - Write Sequencer 489 */
-	[4586] = { 0x070F, 0x070F, 0x0000 }, /* R4586  - Write Sequencer 490 */
-	[4587] = { 0x010F, 0x010F, 0x0000 }, /* R4587  - Write Sequencer 491 */
-	[4588] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4588  - Write Sequencer 492 */
-	[4589] = { 0x00FF, 0x00FF, 0x0000 }, /* R4589  - Write Sequencer 493 */
-	[4590] = { 0x070F, 0x070F, 0x0000 }, /* R4590  - Write Sequencer 494 */
-	[4591] = { 0x010F, 0x010F, 0x0000 }, /* R4591  - Write Sequencer 495 */
-	[4592] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4592  - Write Sequencer 496 */
-	[4593] = { 0x00FF, 0x00FF, 0x0000 }, /* R4593  - Write Sequencer 497 */
-	[4594] = { 0x070F, 0x070F, 0x0000 }, /* R4594  - Write Sequencer 498 */
-	[4595] = { 0x010F, 0x010F, 0x0000 }, /* R4595  - Write Sequencer 499 */
-	[4596] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4596  - Write Sequencer 500 */
-	[4597] = { 0x00FF, 0x00FF, 0x0000 }, /* R4597  - Write Sequencer 501 */
-	[4598] = { 0x070F, 0x070F, 0x0000 }, /* R4598  - Write Sequencer 502 */
-	[4599] = { 0x010F, 0x010F, 0x0000 }, /* R4599  - Write Sequencer 503 */
-	[4600] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4600  - Write Sequencer 504 */
-	[4601] = { 0x00FF, 0x00FF, 0x0000 }, /* R4601  - Write Sequencer 505 */
-	[4602] = { 0x070F, 0x070F, 0x0000 }, /* R4602  - Write Sequencer 506 */
-	[4603] = { 0x010F, 0x010F, 0x0000 }, /* R4603  - Write Sequencer 507 */
-	[4604] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4604  - Write Sequencer 508 */
-	[4605] = { 0x00FF, 0x00FF, 0x0000 }, /* R4605  - Write Sequencer 509 */
-	[4606] = { 0x070F, 0x070F, 0x0000 }, /* R4606  - Write Sequencer 510 */
-	[4607] = { 0x010F, 0x010F, 0x0000 }, /* R4607  - Write Sequencer 511 */
-	[8192] = { 0x03FF, 0x03FF, 0x0000 }, /* R8192  - DSP2 Instruction RAM 0 */
-	[9216] = { 0x003F, 0x003F, 0x0000 }, /* R9216  - DSP2 Address RAM 2 */
-	[9217] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9217  - DSP2 Address RAM 1 */
-	[9218] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9218  - DSP2 Address RAM 0 */
-	[12288] = { 0x00FF, 0x00FF, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */
-	[12289] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */
-	[13312] = { 0x00FF, 0x00FF, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */
-	[13313] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */
-	[14336] = { 0x00FF, 0x00FF, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */
-	[14337] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */
-	[15360] = { 0x07FF, 0x07FF, 0x0000 }, /* R15360 - DSP2 Coeff RAM 0 */
-	[16384] = { 0x00FF, 0x00FF, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */
-	[16385] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */
-	[16386] = { 0x00FF, 0x00FF, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */
-	[16387] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */
-	[16388] = { 0x00FF, 0x00FF, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */
-	[16389] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */
-	[16896] = { 0x00FF, 0x00FF, 0x0000 }, /* R16896 - HDBASS_AI_1 */
-	[16897] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16897 - HDBASS_AI_0 */
-	[16898] = { 0x00FF, 0x00FF, 0x0000 }, /* R16898 - HDBASS_AR_1 */
-	[16899] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16899 - HDBASS_AR_0 */
-	[16900] = { 0x00FF, 0x00FF, 0x0000 }, /* R16900 - HDBASS_B_1 */
-	[16901] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16901 - HDBASS_B_0 */
-	[16902] = { 0x00FF, 0x00FF, 0x0000 }, /* R16902 - HDBASS_K_1 */
-	[16903] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16903 - HDBASS_K_0 */
-	[16904] = { 0x00FF, 0x00FF, 0x0000 }, /* R16904 - HDBASS_N1_1 */
-	[16905] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16905 - HDBASS_N1_0 */
-	[16906] = { 0x00FF, 0x00FF, 0x0000 }, /* R16906 - HDBASS_N2_1 */
-	[16907] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16907 - HDBASS_N2_0 */
-	[16908] = { 0x00FF, 0x00FF, 0x0000 }, /* R16908 - HDBASS_N3_1 */
-	[16909] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16909 - HDBASS_N3_0 */
-	[16910] = { 0x00FF, 0x00FF, 0x0000 }, /* R16910 - HDBASS_N4_1 */
-	[16911] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16911 - HDBASS_N4_0 */
-	[16912] = { 0x00FF, 0x00FF, 0x0000 }, /* R16912 - HDBASS_N5_1 */
-	[16913] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16913 - HDBASS_N5_0 */
-	[16914] = { 0x00FF, 0x00FF, 0x0000 }, /* R16914 - HDBASS_X1_1 */
-	[16915] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16915 - HDBASS_X1_0 */
-	[16916] = { 0x00FF, 0x00FF, 0x0000 }, /* R16916 - HDBASS_X2_1 */
-	[16917] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16917 - HDBASS_X2_0 */
-	[16918] = { 0x00FF, 0x00FF, 0x0000 }, /* R16918 - HDBASS_X3_1 */
-	[16919] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16919 - HDBASS_X3_0 */
-	[16920] = { 0x00FF, 0x00FF, 0x0000 }, /* R16920 - HDBASS_ATK_1 */
-	[16921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16921 - HDBASS_ATK_0 */
-	[16922] = { 0x00FF, 0x00FF, 0x0000 }, /* R16922 - HDBASS_DCY_1 */
-	[16923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16923 - HDBASS_DCY_0 */
-	[16924] = { 0x00FF, 0x00FF, 0x0000 }, /* R16924 - HDBASS_PG_1 */
-	[16925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16925 - HDBASS_PG_0 */
-	[17408] = { 0x00FF, 0x00FF, 0x0000 }, /* R17408 - HPF_C_1 */
-	[17409] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17409 - HPF_C_0 */
-	[17920] = { 0x00FF, 0x00FF, 0x0000 }, /* R17920 - ADCL_RETUNE_C1_1 */
-	[17921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17921 - ADCL_RETUNE_C1_0 */
-	[17922] = { 0x00FF, 0x00FF, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */
-	[17923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */
-	[17924] = { 0x00FF, 0x00FF, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */
-	[17925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */
-	[17926] = { 0x00FF, 0x00FF, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */
-	[17927] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */
-	[17928] = { 0x00FF, 0x00FF, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */
-	[17929] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */
-	[17930] = { 0x00FF, 0x00FF, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */
-	[17931] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */
-	[17932] = { 0x00FF, 0x00FF, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */
-	[17933] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */
-	[17934] = { 0x00FF, 0x00FF, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */
-	[17935] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */
-	[17936] = { 0x00FF, 0x00FF, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */
-	[17937] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */
-	[17938] = { 0x00FF, 0x00FF, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */
-	[17939] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */
-	[17940] = { 0x00FF, 0x00FF, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */
-	[17941] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */
-	[17942] = { 0x00FF, 0x00FF, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */
-	[17943] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */
-	[17944] = { 0x00FF, 0x00FF, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */
-	[17945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */
-	[17946] = { 0x00FF, 0x00FF, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */
-	[17947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */
-	[17948] = { 0x00FF, 0x00FF, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */
-	[17949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */
-	[17950] = { 0x00FF, 0x00FF, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */
-	[17951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */
-	[17952] = { 0x00FF, 0x00FF, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */
-	[17953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */
-	[17954] = { 0x00FF, 0x00FF, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */
-	[17955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */
-	[17956] = { 0x00FF, 0x00FF, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */
-	[17957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */
-	[17958] = { 0x00FF, 0x00FF, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */
-	[17959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */
-	[17960] = { 0x00FF, 0x00FF, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */
-	[17961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */
-	[17962] = { 0x00FF, 0x00FF, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */
-	[17963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */
-	[17964] = { 0x00FF, 0x00FF, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */
-	[17965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */
-	[17966] = { 0x00FF, 0x00FF, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */
-	[17967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */
-	[17968] = { 0x00FF, 0x00FF, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */
-	[17969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */
-	[17970] = { 0x00FF, 0x00FF, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */
-	[17971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */
-	[17972] = { 0x00FF, 0x00FF, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */
-	[17973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */
-	[17974] = { 0x00FF, 0x00FF, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */
-	[17975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */
-	[17976] = { 0x00FF, 0x00FF, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */
-	[17977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */
-	[17978] = { 0x00FF, 0x00FF, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */
-	[17979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */
-	[17980] = { 0x00FF, 0x00FF, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */
-	[17981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */
-	[17982] = { 0x00FF, 0x00FF, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */
-	[17983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */
-	[18432] = { 0x00FF, 0x00FF, 0x0000 }, /* R18432 - RETUNEADC_PG2_1 */
-	[18433] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */
-	[18434] = { 0x00FF, 0x00FF, 0x0000 }, /* R18434 - RETUNEADC_PG_1 */
-	[18435] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */
-	[18944] = { 0x00FF, 0x00FF, 0x0000 }, /* R18944 - ADCR_RETUNE_C1_1 */
-	[18945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18945 - ADCR_RETUNE_C1_0 */
-	[18946] = { 0x00FF, 0x00FF, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */
-	[18947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */
-	[18948] = { 0x00FF, 0x00FF, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */
-	[18949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */
-	[18950] = { 0x00FF, 0x00FF, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */
-	[18951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */
-	[18952] = { 0x00FF, 0x00FF, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */
-	[18953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */
-	[18954] = { 0x00FF, 0x00FF, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */
-	[18955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */
-	[18956] = { 0x00FF, 0x00FF, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */
-	[18957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */
-	[18958] = { 0x00FF, 0x00FF, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */
-	[18959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */
-	[18960] = { 0x00FF, 0x00FF, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */
-	[18961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */
-	[18962] = { 0x00FF, 0x00FF, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */
-	[18963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */
-	[18964] = { 0x00FF, 0x00FF, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */
-	[18965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */
-	[18966] = { 0x00FF, 0x00FF, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */
-	[18967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */
-	[18968] = { 0x00FF, 0x00FF, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */
-	[18969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */
-	[18970] = { 0x00FF, 0x00FF, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */
-	[18971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */
-	[18972] = { 0x00FF, 0x00FF, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */
-	[18973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */
-	[18974] = { 0x00FF, 0x00FF, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */
-	[18975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */
-	[18976] = { 0x00FF, 0x00FF, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */
-	[18977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */
-	[18978] = { 0x00FF, 0x00FF, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */
-	[18979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */
-	[18980] = { 0x00FF, 0x00FF, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */
-	[18981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */
-	[18982] = { 0x00FF, 0x00FF, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */
-	[18983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */
-	[18984] = { 0x00FF, 0x00FF, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */
-	[18985] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */
-	[18986] = { 0x00FF, 0x00FF, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */
-	[18987] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */
-	[18988] = { 0x00FF, 0x00FF, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */
-	[18989] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */
-	[18990] = { 0x00FF, 0x00FF, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */
-	[18991] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */
-	[18992] = { 0x00FF, 0x00FF, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */
-	[18993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */
-	[18994] = { 0x00FF, 0x00FF, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */
-	[18995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */
-	[18996] = { 0x00FF, 0x00FF, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */
-	[18997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */
-	[18998] = { 0x00FF, 0x00FF, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */
-	[18999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */
-	[19000] = { 0x00FF, 0x00FF, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */
-	[19001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */
-	[19002] = { 0x00FF, 0x00FF, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */
-	[19003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */
-	[19004] = { 0x00FF, 0x00FF, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */
-	[19005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */
-	[19006] = { 0x00FF, 0x00FF, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */
-	[19007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */
-	[19456] = { 0x00FF, 0x00FF, 0x0000 }, /* R19456 - DACL_RETUNE_C1_1 */
-	[19457] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19457 - DACL_RETUNE_C1_0 */
-	[19458] = { 0x00FF, 0x00FF, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */
-	[19459] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */
-	[19460] = { 0x00FF, 0x00FF, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */
-	[19461] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */
-	[19462] = { 0x00FF, 0x00FF, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */
-	[19463] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */
-	[19464] = { 0x00FF, 0x00FF, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */
-	[19465] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */
-	[19466] = { 0x00FF, 0x00FF, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */
-	[19467] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */
-	[19468] = { 0x00FF, 0x00FF, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */
-	[19469] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */
-	[19470] = { 0x00FF, 0x00FF, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */
-	[19471] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */
-	[19472] = { 0x00FF, 0x00FF, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */
-	[19473] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */
-	[19474] = { 0x00FF, 0x00FF, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */
-	[19475] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */
-	[19476] = { 0x00FF, 0x00FF, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */
-	[19477] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */
-	[19478] = { 0x00FF, 0x00FF, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */
-	[19479] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */
-	[19480] = { 0x00FF, 0x00FF, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */
-	[19481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */
-	[19482] = { 0x00FF, 0x00FF, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */
-	[19483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */
-	[19484] = { 0x00FF, 0x00FF, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */
-	[19485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */
-	[19486] = { 0x00FF, 0x00FF, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */
-	[19487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */
-	[19488] = { 0x00FF, 0x00FF, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */
-	[19489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */
-	[19490] = { 0x00FF, 0x00FF, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */
-	[19491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */
-	[19492] = { 0x00FF, 0x00FF, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */
-	[19493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */
-	[19494] = { 0x00FF, 0x00FF, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */
-	[19495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */
-	[19496] = { 0x00FF, 0x00FF, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */
-	[19497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */
-	[19498] = { 0x00FF, 0x00FF, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */
-	[19499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */
-	[19500] = { 0x00FF, 0x00FF, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */
-	[19501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */
-	[19502] = { 0x00FF, 0x00FF, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */
-	[19503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */
-	[19504] = { 0x00FF, 0x00FF, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */
-	[19505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */
-	[19506] = { 0x00FF, 0x00FF, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */
-	[19507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */
-	[19508] = { 0x00FF, 0x00FF, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */
-	[19509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */
-	[19510] = { 0x00FF, 0x00FF, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */
-	[19511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */
-	[19512] = { 0x00FF, 0x00FF, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */
-	[19513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */
-	[19514] = { 0x00FF, 0x00FF, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */
-	[19515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */
-	[19516] = { 0x00FF, 0x00FF, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */
-	[19517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */
-	[19518] = { 0x00FF, 0x00FF, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */
-	[19519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */
-	[19968] = { 0x00FF, 0x00FF, 0x0000 }, /* R19968 - RETUNEDAC_PG2_1 */
-	[19969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */
-	[19970] = { 0x00FF, 0x00FF, 0x0000 }, /* R19970 - RETUNEDAC_PG_1 */
-	[19971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */
-	[20480] = { 0x00FF, 0x00FF, 0x0000 }, /* R20480 - DACR_RETUNE_C1_1 */
-	[20481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20481 - DACR_RETUNE_C1_0 */
-	[20482] = { 0x00FF, 0x00FF, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */
-	[20483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */
-	[20484] = { 0x00FF, 0x00FF, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */
-	[20485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */
-	[20486] = { 0x00FF, 0x00FF, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */
-	[20487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */
-	[20488] = { 0x00FF, 0x00FF, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */
-	[20489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */
-	[20490] = { 0x00FF, 0x00FF, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */
-	[20491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */
-	[20492] = { 0x00FF, 0x00FF, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */
-	[20493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */
-	[20494] = { 0x00FF, 0x00FF, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */
-	[20495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */
-	[20496] = { 0x00FF, 0x00FF, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */
-	[20497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */
-	[20498] = { 0x00FF, 0x00FF, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */
-	[20499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */
-	[20500] = { 0x00FF, 0x00FF, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */
-	[20501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */
-	[20502] = { 0x00FF, 0x00FF, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */
-	[20503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */
-	[20504] = { 0x00FF, 0x00FF, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */
-	[20505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */
-	[20506] = { 0x00FF, 0x00FF, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */
-	[20507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */
-	[20508] = { 0x00FF, 0x00FF, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */
-	[20509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */
-	[20510] = { 0x00FF, 0x00FF, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */
-	[20511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */
-	[20512] = { 0x00FF, 0x00FF, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */
-	[20513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */
-	[20514] = { 0x00FF, 0x00FF, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */
-	[20515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */
-	[20516] = { 0x00FF, 0x00FF, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */
-	[20517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */
-	[20518] = { 0x00FF, 0x00FF, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */
-	[20519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */
-	[20520] = { 0x00FF, 0x00FF, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */
-	[20521] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */
-	[20522] = { 0x00FF, 0x00FF, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */
-	[20523] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */
-	[20524] = { 0x00FF, 0x00FF, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */
-	[20525] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */
-	[20526] = { 0x00FF, 0x00FF, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */
-	[20527] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */
-	[20528] = { 0x00FF, 0x00FF, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */
-	[20529] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */
-	[20530] = { 0x00FF, 0x00FF, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */
-	[20531] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */
-	[20532] = { 0x00FF, 0x00FF, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */
-	[20533] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */
-	[20534] = { 0x00FF, 0x00FF, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */
-	[20535] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */
-	[20536] = { 0x00FF, 0x00FF, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */
-	[20537] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */
-	[20538] = { 0x00FF, 0x00FF, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */
-	[20539] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */
-	[20540] = { 0x00FF, 0x00FF, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */
-	[20541] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */
-	[20542] = { 0x00FF, 0x00FF, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */
-	[20543] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */
-	[20992] = { 0x00FF, 0x00FF, 0x0000 }, /* R20992 - VSS_XHD2_1 */
-	[20993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20993 - VSS_XHD2_0 */
-	[20994] = { 0x00FF, 0x00FF, 0x0000 }, /* R20994 - VSS_XHD3_1 */
-	[20995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20995 - VSS_XHD3_0 */
-	[20996] = { 0x00FF, 0x00FF, 0x0000 }, /* R20996 - VSS_XHN1_1 */
-	[20997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20997 - VSS_XHN1_0 */
-	[20998] = { 0x00FF, 0x00FF, 0x0000 }, /* R20998 - VSS_XHN2_1 */
-	[20999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20999 - VSS_XHN2_0 */
-	[21000] = { 0x00FF, 0x00FF, 0x0000 }, /* R21000 - VSS_XHN3_1 */
-	[21001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21001 - VSS_XHN3_0 */
-	[21002] = { 0x00FF, 0x00FF, 0x0000 }, /* R21002 - VSS_XLA_1 */
-	[21003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21003 - VSS_XLA_0 */
-	[21004] = { 0x00FF, 0x00FF, 0x0000 }, /* R21004 - VSS_XLB_1 */
-	[21005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21005 - VSS_XLB_0 */
-	[21006] = { 0x00FF, 0x00FF, 0x0000 }, /* R21006 - VSS_XLG_1 */
-	[21007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21007 - VSS_XLG_0 */
-	[21008] = { 0x00FF, 0x00FF, 0x0000 }, /* R21008 - VSS_PG2_1 */
-	[21009] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21009 - VSS_PG2_0 */
-	[21010] = { 0x00FF, 0x00FF, 0x0000 }, /* R21010 - VSS_PG_1 */
-	[21011] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21011 - VSS_PG_0 */
-	[21012] = { 0x00FF, 0x00FF, 0x0000 }, /* R21012 - VSS_XTD1_1 */
-	[21013] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21013 - VSS_XTD1_0 */
-	[21014] = { 0x00FF, 0x00FF, 0x0000 }, /* R21014 - VSS_XTD2_1 */
-	[21015] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21015 - VSS_XTD2_0 */
-	[21016] = { 0x00FF, 0x00FF, 0x0000 }, /* R21016 - VSS_XTD3_1 */
-	[21017] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21017 - VSS_XTD3_0 */
-	[21018] = { 0x00FF, 0x00FF, 0x0000 }, /* R21018 - VSS_XTD4_1 */
-	[21019] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21019 - VSS_XTD4_0 */
-	[21020] = { 0x00FF, 0x00FF, 0x0000 }, /* R21020 - VSS_XTD5_1 */
-	[21021] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21021 - VSS_XTD5_0 */
-	[21022] = { 0x00FF, 0x00FF, 0x0000 }, /* R21022 - VSS_XTD6_1 */
-	[21023] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21023 - VSS_XTD6_0 */
-	[21024] = { 0x00FF, 0x00FF, 0x0000 }, /* R21024 - VSS_XTD7_1 */
-	[21025] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21025 - VSS_XTD7_0 */
-	[21026] = { 0x00FF, 0x00FF, 0x0000 }, /* R21026 - VSS_XTD8_1 */
-	[21027] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21027 - VSS_XTD8_0 */
-	[21028] = { 0x00FF, 0x00FF, 0x0000 }, /* R21028 - VSS_XTD9_1 */
-	[21029] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21029 - VSS_XTD9_0 */
-	[21030] = { 0x00FF, 0x00FF, 0x0000 }, /* R21030 - VSS_XTD10_1 */
-	[21031] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21031 - VSS_XTD10_0 */
-	[21032] = { 0x00FF, 0x00FF, 0x0000 }, /* R21032 - VSS_XTD11_1 */
-	[21033] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21033 - VSS_XTD11_0 */
-	[21034] = { 0x00FF, 0x00FF, 0x0000 }, /* R21034 - VSS_XTD12_1 */
-	[21035] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21035 - VSS_XTD12_0 */
-	[21036] = { 0x00FF, 0x00FF, 0x0000 }, /* R21036 - VSS_XTD13_1 */
-	[21037] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21037 - VSS_XTD13_0 */
-	[21038] = { 0x00FF, 0x00FF, 0x0000 }, /* R21038 - VSS_XTD14_1 */
-	[21039] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21039 - VSS_XTD14_0 */
-	[21040] = { 0x00FF, 0x00FF, 0x0000 }, /* R21040 - VSS_XTD15_1 */
-	[21041] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21041 - VSS_XTD15_0 */
-	[21042] = { 0x00FF, 0x00FF, 0x0000 }, /* R21042 - VSS_XTD16_1 */
-	[21043] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21043 - VSS_XTD16_0 */
-	[21044] = { 0x00FF, 0x00FF, 0x0000 }, /* R21044 - VSS_XTD17_1 */
-	[21045] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21045 - VSS_XTD17_0 */
-	[21046] = { 0x00FF, 0x00FF, 0x0000 }, /* R21046 - VSS_XTD18_1 */
-	[21047] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21047 - VSS_XTD18_0 */
-	[21048] = { 0x00FF, 0x00FF, 0x0000 }, /* R21048 - VSS_XTD19_1 */
-	[21049] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21049 - VSS_XTD19_0 */
-	[21050] = { 0x00FF, 0x00FF, 0x0000 }, /* R21050 - VSS_XTD20_1 */
-	[21051] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21051 - VSS_XTD20_0 */
-	[21052] = { 0x00FF, 0x00FF, 0x0000 }, /* R21052 - VSS_XTD21_1 */
-	[21053] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21053 - VSS_XTD21_0 */
-	[21054] = { 0x00FF, 0x00FF, 0x0000 }, /* R21054 - VSS_XTD22_1 */
-	[21055] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21055 - VSS_XTD22_0 */
-	[21056] = { 0x00FF, 0x00FF, 0x0000 }, /* R21056 - VSS_XTD23_1 */
-	[21057] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21057 - VSS_XTD23_0 */
-	[21058] = { 0x00FF, 0x00FF, 0x0000 }, /* R21058 - VSS_XTD24_1 */
-	[21059] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21059 - VSS_XTD24_0 */
-	[21060] = { 0x00FF, 0x00FF, 0x0000 }, /* R21060 - VSS_XTD25_1 */
-	[21061] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21061 - VSS_XTD25_0 */
-	[21062] = { 0x00FF, 0x00FF, 0x0000 }, /* R21062 - VSS_XTD26_1 */
-	[21063] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21063 - VSS_XTD26_0 */
-	[21064] = { 0x00FF, 0x00FF, 0x0000 }, /* R21064 - VSS_XTD27_1 */
-	[21065] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21065 - VSS_XTD27_0 */
-	[21066] = { 0x00FF, 0x00FF, 0x0000 }, /* R21066 - VSS_XTD28_1 */
-	[21067] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21067 - VSS_XTD28_0 */
-	[21068] = { 0x00FF, 0x00FF, 0x0000 }, /* R21068 - VSS_XTD29_1 */
-	[21069] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21069 - VSS_XTD29_0 */
-	[21070] = { 0x00FF, 0x00FF, 0x0000 }, /* R21070 - VSS_XTD30_1 */
-	[21071] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21071 - VSS_XTD30_0 */
-	[21072] = { 0x00FF, 0x00FF, 0x0000 }, /* R21072 - VSS_XTD31_1 */
-	[21073] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21073 - VSS_XTD31_0 */
-	[21074] = { 0x00FF, 0x00FF, 0x0000 }, /* R21074 - VSS_XTD32_1 */
-	[21075] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21075 - VSS_XTD32_0 */
-	[21076] = { 0x00FF, 0x00FF, 0x0000 }, /* R21076 - VSS_XTS1_1 */
-	[21077] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21077 - VSS_XTS1_0 */
-	[21078] = { 0x00FF, 0x00FF, 0x0000 }, /* R21078 - VSS_XTS2_1 */
-	[21079] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21079 - VSS_XTS2_0 */
-	[21080] = { 0x00FF, 0x00FF, 0x0000 }, /* R21080 - VSS_XTS3_1 */
-	[21081] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21081 - VSS_XTS3_0 */
-	[21082] = { 0x00FF, 0x00FF, 0x0000 }, /* R21082 - VSS_XTS4_1 */
-	[21083] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21083 - VSS_XTS4_0 */
-	[21084] = { 0x00FF, 0x00FF, 0x0000 }, /* R21084 - VSS_XTS5_1 */
-	[21085] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21085 - VSS_XTS5_0 */
-	[21086] = { 0x00FF, 0x00FF, 0x0000 }, /* R21086 - VSS_XTS6_1 */
-	[21087] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21087 - VSS_XTS6_0 */
-	[21088] = { 0x00FF, 0x00FF, 0x0000 }, /* R21088 - VSS_XTS7_1 */
-	[21089] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21089 - VSS_XTS7_0 */
-	[21090] = { 0x00FF, 0x00FF, 0x0000 }, /* R21090 - VSS_XTS8_1 */
-	[21091] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21091 - VSS_XTS8_0 */
-	[21092] = { 0x00FF, 0x00FF, 0x0000 }, /* R21092 - VSS_XTS9_1 */
-	[21093] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21093 - VSS_XTS9_0 */
-	[21094] = { 0x00FF, 0x00FF, 0x0000 }, /* R21094 - VSS_XTS10_1 */
-	[21095] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21095 - VSS_XTS10_0 */
-	[21096] = { 0x00FF, 0x00FF, 0x0000 }, /* R21096 - VSS_XTS11_1 */
-	[21097] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21097 - VSS_XTS11_0 */
-	[21098] = { 0x00FF, 0x00FF, 0x0000 }, /* R21098 - VSS_XTS12_1 */
-	[21099] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21099 - VSS_XTS12_0 */
-	[21100] = { 0x00FF, 0x00FF, 0x0000 }, /* R21100 - VSS_XTS13_1 */
-	[21101] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21101 - VSS_XTS13_0 */
-	[21102] = { 0x00FF, 0x00FF, 0x0000 }, /* R21102 - VSS_XTS14_1 */
-	[21103] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21103 - VSS_XTS14_0 */
-	[21104] = { 0x00FF, 0x00FF, 0x0000 }, /* R21104 - VSS_XTS15_1 */
-	[21105] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21105 - VSS_XTS15_0 */
-	[21106] = { 0x00FF, 0x00FF, 0x0000 }, /* R21106 - VSS_XTS16_1 */
-	[21107] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21107 - VSS_XTS16_0 */
-	[21108] = { 0x00FF, 0x00FF, 0x0000 }, /* R21108 - VSS_XTS17_1 */
-	[21109] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21109 - VSS_XTS17_0 */
-	[21110] = { 0x00FF, 0x00FF, 0x0000 }, /* R21110 - VSS_XTS18_1 */
-	[21111] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21111 - VSS_XTS18_0 */
-	[21112] = { 0x00FF, 0x00FF, 0x0000 }, /* R21112 - VSS_XTS19_1 */
-	[21113] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21113 - VSS_XTS19_0 */
-	[21114] = { 0x00FF, 0x00FF, 0x0000 }, /* R21114 - VSS_XTS20_1 */
-	[21115] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21115 - VSS_XTS20_0 */
-	[21116] = { 0x00FF, 0x00FF, 0x0000 }, /* R21116 - VSS_XTS21_1 */
-	[21117] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21117 - VSS_XTS21_0 */
-	[21118] = { 0x00FF, 0x00FF, 0x0000 }, /* R21118 - VSS_XTS22_1 */
-	[21119] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21119 - VSS_XTS22_0 */
-	[21120] = { 0x00FF, 0x00FF, 0x0000 }, /* R21120 - VSS_XTS23_1 */
-	[21121] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21121 - VSS_XTS23_0 */
-	[21122] = { 0x00FF, 0x00FF, 0x0000 }, /* R21122 - VSS_XTS24_1 */
-	[21123] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21123 - VSS_XTS24_0 */
-	[21124] = { 0x00FF, 0x00FF, 0x0000 }, /* R21124 - VSS_XTS25_1 */
-	[21125] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21125 - VSS_XTS25_0 */
-	[21126] = { 0x00FF, 0x00FF, 0x0000 }, /* R21126 - VSS_XTS26_1 */
-	[21127] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21127 - VSS_XTS26_0 */
-	[21128] = { 0x00FF, 0x00FF, 0x0000 }, /* R21128 - VSS_XTS27_1 */
-	[21129] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21129 - VSS_XTS27_0 */
-	[21130] = { 0x00FF, 0x00FF, 0x0000 }, /* R21130 - VSS_XTS28_1 */
-	[21131] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21131 - VSS_XTS28_0 */
-	[21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */
-	[21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */
-	[21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */
-	[21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */
-	[21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */
-	[21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */
-	[21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */
-	[21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */
-};
-
 static bool wm8962_volatile_register(struct device *dev, unsigned int reg)
 {
-	if (wm8962_reg_access[reg].vol)
-		return 1;
-	else
-		return 0;
+	switch (reg) {
+	case WM8962_CLOCKING1:
+	case WM8962_CLOCKING2:
+	case WM8962_SOFTWARE_RESET:
+	case WM8962_ALC2:
+	case WM8962_THERMAL_SHUTDOWN_STATUS:
+	case WM8962_ADDITIONAL_CONTROL_4:
+	case WM8962_CLASS_D_CONTROL_1:
+	case WM8962_DC_SERVO_6:
+	case WM8962_INTERRUPT_STATUS_1:
+	case WM8962_INTERRUPT_STATUS_2:
+	case WM8962_DSP2_EXECCONTROL:
+		return true;
+	default:
+		return false;
+	}
 }
 
 static bool wm8962_readable_register(struct device *dev, unsigned int reg)
 {
-	if (wm8962_reg_access[reg].read)
-		return 1;
-	else
-		return 0;
+	switch (reg) {
+	case WM8962_LEFT_INPUT_VOLUME:
+	case WM8962_RIGHT_INPUT_VOLUME:
+	case WM8962_HPOUTL_VOLUME:
+	case WM8962_HPOUTR_VOLUME:
+	case WM8962_CLOCKING1:
+	case WM8962_ADC_DAC_CONTROL_1:
+	case WM8962_ADC_DAC_CONTROL_2:
+	case WM8962_AUDIO_INTERFACE_0:
+	case WM8962_CLOCKING2:
+	case WM8962_AUDIO_INTERFACE_1:
+	case WM8962_LEFT_DAC_VOLUME:
+	case WM8962_RIGHT_DAC_VOLUME:
+	case WM8962_AUDIO_INTERFACE_2:
+	case WM8962_SOFTWARE_RESET:
+	case WM8962_ALC1:
+	case WM8962_ALC2:
+	case WM8962_ALC3:
+	case WM8962_NOISE_GATE:
+	case WM8962_LEFT_ADC_VOLUME:
+	case WM8962_RIGHT_ADC_VOLUME:
+	case WM8962_ADDITIONAL_CONTROL_1:
+	case WM8962_ADDITIONAL_CONTROL_2:
+	case WM8962_PWR_MGMT_1:
+	case WM8962_PWR_MGMT_2:
+	case WM8962_ADDITIONAL_CONTROL_3:
+	case WM8962_ANTI_POP:
+	case WM8962_CLOCKING_3:
+	case WM8962_INPUT_MIXER_CONTROL_1:
+	case WM8962_LEFT_INPUT_MIXER_VOLUME:
+	case WM8962_RIGHT_INPUT_MIXER_VOLUME:
+	case WM8962_INPUT_MIXER_CONTROL_2:
+	case WM8962_INPUT_BIAS_CONTROL:
+	case WM8962_LEFT_INPUT_PGA_CONTROL:
+	case WM8962_RIGHT_INPUT_PGA_CONTROL:
+	case WM8962_SPKOUTL_VOLUME:
+	case WM8962_SPKOUTR_VOLUME:
+	case WM8962_THERMAL_SHUTDOWN_STATUS:
+	case WM8962_ADDITIONAL_CONTROL_4:
+	case WM8962_CLASS_D_CONTROL_1:
+	case WM8962_CLASS_D_CONTROL_2:
+	case WM8962_CLOCKING_4:
+	case WM8962_DAC_DSP_MIXING_1:
+	case WM8962_DAC_DSP_MIXING_2:
+	case WM8962_DC_SERVO_0:
+	case WM8962_DC_SERVO_1:
+	case WM8962_DC_SERVO_4:
+	case WM8962_DC_SERVO_6:
+	case WM8962_ANALOGUE_PGA_BIAS:
+	case WM8962_ANALOGUE_HP_0:
+	case WM8962_ANALOGUE_HP_2:
+	case WM8962_CHARGE_PUMP_1:
+	case WM8962_CHARGE_PUMP_B:
+	case WM8962_WRITE_SEQUENCER_CONTROL_1:
+	case WM8962_WRITE_SEQUENCER_CONTROL_2:
+	case WM8962_WRITE_SEQUENCER_CONTROL_3:
+	case WM8962_CONTROL_INTERFACE:
+	case WM8962_MIXER_ENABLES:
+	case WM8962_HEADPHONE_MIXER_1:
+	case WM8962_HEADPHONE_MIXER_2:
+	case WM8962_HEADPHONE_MIXER_3:
+	case WM8962_HEADPHONE_MIXER_4:
+	case WM8962_SPEAKER_MIXER_1:
+	case WM8962_SPEAKER_MIXER_2:
+	case WM8962_SPEAKER_MIXER_3:
+	case WM8962_SPEAKER_MIXER_4:
+	case WM8962_SPEAKER_MIXER_5:
+	case WM8962_BEEP_GENERATOR_1:
+	case WM8962_OSCILLATOR_TRIM_3:
+	case WM8962_OSCILLATOR_TRIM_4:
+	case WM8962_OSCILLATOR_TRIM_7:
+	case WM8962_ANALOGUE_CLOCKING1:
+	case WM8962_ANALOGUE_CLOCKING2:
+	case WM8962_ANALOGUE_CLOCKING3:
+	case WM8962_PLL_SOFTWARE_RESET:
+	case WM8962_PLL2:
+	case WM8962_PLL_4:
+	case WM8962_PLL_9:
+	case WM8962_PLL_10:
+	case WM8962_PLL_11:
+	case WM8962_PLL_12:
+	case WM8962_PLL_13:
+	case WM8962_PLL_14:
+	case WM8962_PLL_15:
+	case WM8962_PLL_16:
+	case WM8962_FLL_CONTROL_1:
+	case WM8962_FLL_CONTROL_2:
+	case WM8962_FLL_CONTROL_3:
+	case WM8962_FLL_CONTROL_5:
+	case WM8962_FLL_CONTROL_6:
+	case WM8962_FLL_CONTROL_7:
+	case WM8962_FLL_CONTROL_8:
+	case WM8962_GENERAL_TEST_1:
+	case WM8962_DF1:
+	case WM8962_DF2:
+	case WM8962_DF3:
+	case WM8962_DF4:
+	case WM8962_DF5:
+	case WM8962_DF6:
+	case WM8962_DF7:
+	case WM8962_LHPF1:
+	case WM8962_LHPF2:
+	case WM8962_THREED1:
+	case WM8962_THREED2:
+	case WM8962_THREED3:
+	case WM8962_THREED4:
+	case WM8962_DRC_1:
+	case WM8962_DRC_2:
+	case WM8962_DRC_3:
+	case WM8962_DRC_4:
+	case WM8962_DRC_5:
+	case WM8962_TLOOPBACK:
+	case WM8962_EQ1:
+	case WM8962_EQ2:
+	case WM8962_EQ3:
+	case WM8962_EQ4:
+	case WM8962_EQ5:
+	case WM8962_EQ6:
+	case WM8962_EQ7:
+	case WM8962_EQ8:
+	case WM8962_EQ9:
+	case WM8962_EQ10:
+	case WM8962_EQ11:
+	case WM8962_EQ12:
+	case WM8962_EQ13:
+	case WM8962_EQ14:
+	case WM8962_EQ15:
+	case WM8962_EQ16:
+	case WM8962_EQ17:
+	case WM8962_EQ18:
+	case WM8962_EQ19:
+	case WM8962_EQ20:
+	case WM8962_EQ21:
+	case WM8962_EQ22:
+	case WM8962_EQ23:
+	case WM8962_EQ24:
+	case WM8962_EQ25:
+	case WM8962_EQ26:
+	case WM8962_EQ27:
+	case WM8962_EQ28:
+	case WM8962_EQ29:
+	case WM8962_EQ30:
+	case WM8962_EQ31:
+	case WM8962_EQ32:
+	case WM8962_EQ33:
+	case WM8962_EQ34:
+	case WM8962_EQ35:
+	case WM8962_EQ36:
+	case WM8962_EQ37:
+	case WM8962_EQ38:
+	case WM8962_EQ39:
+	case WM8962_EQ40:
+	case WM8962_EQ41:
+	case WM8962_GPIO_BASE:
+	case WM8962_GPIO_2:
+	case WM8962_GPIO_3:
+	case WM8962_GPIO_5:
+	case WM8962_GPIO_6:
+	case WM8962_INTERRUPT_STATUS_1:
+	case WM8962_INTERRUPT_STATUS_2:
+	case WM8962_INTERRUPT_STATUS_1_MASK:
+	case WM8962_INTERRUPT_STATUS_2_MASK:
+	case WM8962_INTERRUPT_CONTROL:
+	case WM8962_IRQ_DEBOUNCE:
+	case WM8962_MICINT_SOURCE_POL:
+	case WM8962_DSP2_POWER_MANAGEMENT:
+	case WM8962_DSP2_EXECCONTROL:
+	case WM8962_DSP2_INSTRUCTION_RAM_0:
+	case WM8962_DSP2_ADDRESS_RAM_2:
+	case WM8962_DSP2_ADDRESS_RAM_1:
+	case WM8962_DSP2_ADDRESS_RAM_0:
+	case WM8962_DSP2_DATA1_RAM_1:
+	case WM8962_DSP2_DATA1_RAM_0:
+	case WM8962_DSP2_DATA2_RAM_1:
+	case WM8962_DSP2_DATA2_RAM_0:
+	case WM8962_DSP2_DATA3_RAM_1:
+	case WM8962_DSP2_DATA3_RAM_0:
+	case WM8962_DSP2_COEFF_RAM_0:
+	case WM8962_RETUNEADC_SHARED_COEFF_1:
+	case WM8962_RETUNEADC_SHARED_COEFF_0:
+	case WM8962_RETUNEDAC_SHARED_COEFF_1:
+	case WM8962_RETUNEDAC_SHARED_COEFF_0:
+	case WM8962_SOUNDSTAGE_ENABLES_1:
+	case WM8962_SOUNDSTAGE_ENABLES_0:
+	case WM8962_HDBASS_AI_1:
+	case WM8962_HDBASS_AI_0:
+	case WM8962_HDBASS_AR_1:
+	case WM8962_HDBASS_AR_0:
+	case WM8962_HDBASS_B_1:
+	case WM8962_HDBASS_B_0:
+	case WM8962_HDBASS_K_1:
+	case WM8962_HDBASS_K_0:
+	case WM8962_HDBASS_N1_1:
+	case WM8962_HDBASS_N1_0:
+	case WM8962_HDBASS_N2_1:
+	case WM8962_HDBASS_N2_0:
+	case WM8962_HDBASS_N3_1:
+	case WM8962_HDBASS_N3_0:
+	case WM8962_HDBASS_N4_1:
+	case WM8962_HDBASS_N4_0:
+	case WM8962_HDBASS_N5_1:
+	case WM8962_HDBASS_N5_0:
+	case WM8962_HDBASS_X1_1:
+	case WM8962_HDBASS_X1_0:
+	case WM8962_HDBASS_X2_1:
+	case WM8962_HDBASS_X2_0:
+	case WM8962_HDBASS_X3_1:
+	case WM8962_HDBASS_X3_0:
+	case WM8962_HDBASS_ATK_1:
+	case WM8962_HDBASS_ATK_0:
+	case WM8962_HDBASS_DCY_1:
+	case WM8962_HDBASS_DCY_0:
+	case WM8962_HDBASS_PG_1:
+	case WM8962_HDBASS_PG_0:
+	case WM8962_HPF_C_1:
+	case WM8962_HPF_C_0:
+	case WM8962_ADCL_RETUNE_C1_1:
+	case WM8962_ADCL_RETUNE_C1_0:
+	case WM8962_ADCL_RETUNE_C2_1:
+	case WM8962_ADCL_RETUNE_C2_0:
+	case WM8962_ADCL_RETUNE_C3_1:
+	case WM8962_ADCL_RETUNE_C3_0:
+	case WM8962_ADCL_RETUNE_C4_1:
+	case WM8962_ADCL_RETUNE_C4_0:
+	case WM8962_ADCL_RETUNE_C5_1:
+	case WM8962_ADCL_RETUNE_C5_0:
+	case WM8962_ADCL_RETUNE_C6_1:
+	case WM8962_ADCL_RETUNE_C6_0:
+	case WM8962_ADCL_RETUNE_C7_1:
+	case WM8962_ADCL_RETUNE_C7_0:
+	case WM8962_ADCL_RETUNE_C8_1:
+	case WM8962_ADCL_RETUNE_C8_0:
+	case WM8962_ADCL_RETUNE_C9_1:
+	case WM8962_ADCL_RETUNE_C9_0:
+	case WM8962_ADCL_RETUNE_C10_1:
+	case WM8962_ADCL_RETUNE_C10_0:
+	case WM8962_ADCL_RETUNE_C11_1:
+	case WM8962_ADCL_RETUNE_C11_0:
+	case WM8962_ADCL_RETUNE_C12_1:
+	case WM8962_ADCL_RETUNE_C12_0:
+	case WM8962_ADCL_RETUNE_C13_1:
+	case WM8962_ADCL_RETUNE_C13_0:
+	case WM8962_ADCL_RETUNE_C14_1:
+	case WM8962_ADCL_RETUNE_C14_0:
+	case WM8962_ADCL_RETUNE_C15_1:
+	case WM8962_ADCL_RETUNE_C15_0:
+	case WM8962_ADCL_RETUNE_C16_1:
+	case WM8962_ADCL_RETUNE_C16_0:
+	case WM8962_ADCL_RETUNE_C17_1:
+	case WM8962_ADCL_RETUNE_C17_0:
+	case WM8962_ADCL_RETUNE_C18_1:
+	case WM8962_ADCL_RETUNE_C18_0:
+	case WM8962_ADCL_RETUNE_C19_1:
+	case WM8962_ADCL_RETUNE_C19_0:
+	case WM8962_ADCL_RETUNE_C20_1:
+	case WM8962_ADCL_RETUNE_C20_0:
+	case WM8962_ADCL_RETUNE_C21_1:
+	case WM8962_ADCL_RETUNE_C21_0:
+	case WM8962_ADCL_RETUNE_C22_1:
+	case WM8962_ADCL_RETUNE_C22_0:
+	case WM8962_ADCL_RETUNE_C23_1:
+	case WM8962_ADCL_RETUNE_C23_0:
+	case WM8962_ADCL_RETUNE_C24_1:
+	case WM8962_ADCL_RETUNE_C24_0:
+	case WM8962_ADCL_RETUNE_C25_1:
+	case WM8962_ADCL_RETUNE_C25_0:
+	case WM8962_ADCL_RETUNE_C26_1:
+	case WM8962_ADCL_RETUNE_C26_0:
+	case WM8962_ADCL_RETUNE_C27_1:
+	case WM8962_ADCL_RETUNE_C27_0:
+	case WM8962_ADCL_RETUNE_C28_1:
+	case WM8962_ADCL_RETUNE_C28_0:
+	case WM8962_ADCL_RETUNE_C29_1:
+	case WM8962_ADCL_RETUNE_C29_0:
+	case WM8962_ADCL_RETUNE_C30_1:
+	case WM8962_ADCL_RETUNE_C30_0:
+	case WM8962_ADCL_RETUNE_C31_1:
+	case WM8962_ADCL_RETUNE_C31_0:
+	case WM8962_ADCL_RETUNE_C32_1:
+	case WM8962_ADCL_RETUNE_C32_0:
+	case WM8962_RETUNEADC_PG2_1:
+	case WM8962_RETUNEADC_PG2_0:
+	case WM8962_RETUNEADC_PG_1:
+	case WM8962_RETUNEADC_PG_0:
+	case WM8962_ADCR_RETUNE_C1_1:
+	case WM8962_ADCR_RETUNE_C1_0:
+	case WM8962_ADCR_RETUNE_C2_1:
+	case WM8962_ADCR_RETUNE_C2_0:
+	case WM8962_ADCR_RETUNE_C3_1:
+	case WM8962_ADCR_RETUNE_C3_0:
+	case WM8962_ADCR_RETUNE_C4_1:
+	case WM8962_ADCR_RETUNE_C4_0:
+	case WM8962_ADCR_RETUNE_C5_1:
+	case WM8962_ADCR_RETUNE_C5_0:
+	case WM8962_ADCR_RETUNE_C6_1:
+	case WM8962_ADCR_RETUNE_C6_0:
+	case WM8962_ADCR_RETUNE_C7_1:
+	case WM8962_ADCR_RETUNE_C7_0:
+	case WM8962_ADCR_RETUNE_C8_1:
+	case WM8962_ADCR_RETUNE_C8_0:
+	case WM8962_ADCR_RETUNE_C9_1:
+	case WM8962_ADCR_RETUNE_C9_0:
+	case WM8962_ADCR_RETUNE_C10_1:
+	case WM8962_ADCR_RETUNE_C10_0:
+	case WM8962_ADCR_RETUNE_C11_1:
+	case WM8962_ADCR_RETUNE_C11_0:
+	case WM8962_ADCR_RETUNE_C12_1:
+	case WM8962_ADCR_RETUNE_C12_0:
+	case WM8962_ADCR_RETUNE_C13_1:
+	case WM8962_ADCR_RETUNE_C13_0:
+	case WM8962_ADCR_RETUNE_C14_1:
+	case WM8962_ADCR_RETUNE_C14_0:
+	case WM8962_ADCR_RETUNE_C15_1:
+	case WM8962_ADCR_RETUNE_C15_0:
+	case WM8962_ADCR_RETUNE_C16_1:
+	case WM8962_ADCR_RETUNE_C16_0:
+	case WM8962_ADCR_RETUNE_C17_1:
+	case WM8962_ADCR_RETUNE_C17_0:
+	case WM8962_ADCR_RETUNE_C18_1:
+	case WM8962_ADCR_RETUNE_C18_0:
+	case WM8962_ADCR_RETUNE_C19_1:
+	case WM8962_ADCR_RETUNE_C19_0:
+	case WM8962_ADCR_RETUNE_C20_1:
+	case WM8962_ADCR_RETUNE_C20_0:
+	case WM8962_ADCR_RETUNE_C21_1:
+	case WM8962_ADCR_RETUNE_C21_0:
+	case WM8962_ADCR_RETUNE_C22_1:
+	case WM8962_ADCR_RETUNE_C22_0:
+	case WM8962_ADCR_RETUNE_C23_1:
+	case WM8962_ADCR_RETUNE_C23_0:
+	case WM8962_ADCR_RETUNE_C24_1:
+	case WM8962_ADCR_RETUNE_C24_0:
+	case WM8962_ADCR_RETUNE_C25_1:
+	case WM8962_ADCR_RETUNE_C25_0:
+	case WM8962_ADCR_RETUNE_C26_1:
+	case WM8962_ADCR_RETUNE_C26_0:
+	case WM8962_ADCR_RETUNE_C27_1:
+	case WM8962_ADCR_RETUNE_C27_0:
+	case WM8962_ADCR_RETUNE_C28_1:
+	case WM8962_ADCR_RETUNE_C28_0:
+	case WM8962_ADCR_RETUNE_C29_1:
+	case WM8962_ADCR_RETUNE_C29_0:
+	case WM8962_ADCR_RETUNE_C30_1:
+	case WM8962_ADCR_RETUNE_C30_0:
+	case WM8962_ADCR_RETUNE_C31_1:
+	case WM8962_ADCR_RETUNE_C31_0:
+	case WM8962_ADCR_RETUNE_C32_1:
+	case WM8962_ADCR_RETUNE_C32_0:
+	case WM8962_DACL_RETUNE_C1_1:
+	case WM8962_DACL_RETUNE_C1_0:
+	case WM8962_DACL_RETUNE_C2_1:
+	case WM8962_DACL_RETUNE_C2_0:
+	case WM8962_DACL_RETUNE_C3_1:
+	case WM8962_DACL_RETUNE_C3_0:
+	case WM8962_DACL_RETUNE_C4_1:
+	case WM8962_DACL_RETUNE_C4_0:
+	case WM8962_DACL_RETUNE_C5_1:
+	case WM8962_DACL_RETUNE_C5_0:
+	case WM8962_DACL_RETUNE_C6_1:
+	case WM8962_DACL_RETUNE_C6_0:
+	case WM8962_DACL_RETUNE_C7_1:
+	case WM8962_DACL_RETUNE_C7_0:
+	case WM8962_DACL_RETUNE_C8_1:
+	case WM8962_DACL_RETUNE_C8_0:
+	case WM8962_DACL_RETUNE_C9_1:
+	case WM8962_DACL_RETUNE_C9_0:
+	case WM8962_DACL_RETUNE_C10_1:
+	case WM8962_DACL_RETUNE_C10_0:
+	case WM8962_DACL_RETUNE_C11_1:
+	case WM8962_DACL_RETUNE_C11_0:
+	case WM8962_DACL_RETUNE_C12_1:
+	case WM8962_DACL_RETUNE_C12_0:
+	case WM8962_DACL_RETUNE_C13_1:
+	case WM8962_DACL_RETUNE_C13_0:
+	case WM8962_DACL_RETUNE_C14_1:
+	case WM8962_DACL_RETUNE_C14_0:
+	case WM8962_DACL_RETUNE_C15_1:
+	case WM8962_DACL_RETUNE_C15_0:
+	case WM8962_DACL_RETUNE_C16_1:
+	case WM8962_DACL_RETUNE_C16_0:
+	case WM8962_DACL_RETUNE_C17_1:
+	case WM8962_DACL_RETUNE_C17_0:
+	case WM8962_DACL_RETUNE_C18_1:
+	case WM8962_DACL_RETUNE_C18_0:
+	case WM8962_DACL_RETUNE_C19_1:
+	case WM8962_DACL_RETUNE_C19_0:
+	case WM8962_DACL_RETUNE_C20_1:
+	case WM8962_DACL_RETUNE_C20_0:
+	case WM8962_DACL_RETUNE_C21_1:
+	case WM8962_DACL_RETUNE_C21_0:
+	case WM8962_DACL_RETUNE_C22_1:
+	case WM8962_DACL_RETUNE_C22_0:
+	case WM8962_DACL_RETUNE_C23_1:
+	case WM8962_DACL_RETUNE_C23_0:
+	case WM8962_DACL_RETUNE_C24_1:
+	case WM8962_DACL_RETUNE_C24_0:
+	case WM8962_DACL_RETUNE_C25_1:
+	case WM8962_DACL_RETUNE_C25_0:
+	case WM8962_DACL_RETUNE_C26_1:
+	case WM8962_DACL_RETUNE_C26_0:
+	case WM8962_DACL_RETUNE_C27_1:
+	case WM8962_DACL_RETUNE_C27_0:
+	case WM8962_DACL_RETUNE_C28_1:
+	case WM8962_DACL_RETUNE_C28_0:
+	case WM8962_DACL_RETUNE_C29_1:
+	case WM8962_DACL_RETUNE_C29_0:
+	case WM8962_DACL_RETUNE_C30_1:
+	case WM8962_DACL_RETUNE_C30_0:
+	case WM8962_DACL_RETUNE_C31_1:
+	case WM8962_DACL_RETUNE_C31_0:
+	case WM8962_DACL_RETUNE_C32_1:
+	case WM8962_DACL_RETUNE_C32_0:
+	case WM8962_RETUNEDAC_PG2_1:
+	case WM8962_RETUNEDAC_PG2_0:
+	case WM8962_RETUNEDAC_PG_1:
+	case WM8962_RETUNEDAC_PG_0:
+	case WM8962_DACR_RETUNE_C1_1:
+	case WM8962_DACR_RETUNE_C1_0:
+	case WM8962_DACR_RETUNE_C2_1:
+	case WM8962_DACR_RETUNE_C2_0:
+	case WM8962_DACR_RETUNE_C3_1:
+	case WM8962_DACR_RETUNE_C3_0:
+	case WM8962_DACR_RETUNE_C4_1:
+	case WM8962_DACR_RETUNE_C4_0:
+	case WM8962_DACR_RETUNE_C5_1:
+	case WM8962_DACR_RETUNE_C5_0:
+	case WM8962_DACR_RETUNE_C6_1:
+	case WM8962_DACR_RETUNE_C6_0:
+	case WM8962_DACR_RETUNE_C7_1:
+	case WM8962_DACR_RETUNE_C7_0:
+	case WM8962_DACR_RETUNE_C8_1:
+	case WM8962_DACR_RETUNE_C8_0:
+	case WM8962_DACR_RETUNE_C9_1:
+	case WM8962_DACR_RETUNE_C9_0:
+	case WM8962_DACR_RETUNE_C10_1:
+	case WM8962_DACR_RETUNE_C10_0:
+	case WM8962_DACR_RETUNE_C11_1:
+	case WM8962_DACR_RETUNE_C11_0:
+	case WM8962_DACR_RETUNE_C12_1:
+	case WM8962_DACR_RETUNE_C12_0:
+	case WM8962_DACR_RETUNE_C13_1:
+	case WM8962_DACR_RETUNE_C13_0:
+	case WM8962_DACR_RETUNE_C14_1:
+	case WM8962_DACR_RETUNE_C14_0:
+	case WM8962_DACR_RETUNE_C15_1:
+	case WM8962_DACR_RETUNE_C15_0:
+	case WM8962_DACR_RETUNE_C16_1:
+	case WM8962_DACR_RETUNE_C16_0:
+	case WM8962_DACR_RETUNE_C17_1:
+	case WM8962_DACR_RETUNE_C17_0:
+	case WM8962_DACR_RETUNE_C18_1:
+	case WM8962_DACR_RETUNE_C18_0:
+	case WM8962_DACR_RETUNE_C19_1:
+	case WM8962_DACR_RETUNE_C19_0:
+	case WM8962_DACR_RETUNE_C20_1:
+	case WM8962_DACR_RETUNE_C20_0:
+	case WM8962_DACR_RETUNE_C21_1:
+	case WM8962_DACR_RETUNE_C21_0:
+	case WM8962_DACR_RETUNE_C22_1:
+	case WM8962_DACR_RETUNE_C22_0:
+	case WM8962_DACR_RETUNE_C23_1:
+	case WM8962_DACR_RETUNE_C23_0:
+	case WM8962_DACR_RETUNE_C24_1:
+	case WM8962_DACR_RETUNE_C24_0:
+	case WM8962_DACR_RETUNE_C25_1:
+	case WM8962_DACR_RETUNE_C25_0:
+	case WM8962_DACR_RETUNE_C26_1:
+	case WM8962_DACR_RETUNE_C26_0:
+	case WM8962_DACR_RETUNE_C27_1:
+	case WM8962_DACR_RETUNE_C27_0:
+	case WM8962_DACR_RETUNE_C28_1:
+	case WM8962_DACR_RETUNE_C28_0:
+	case WM8962_DACR_RETUNE_C29_1:
+	case WM8962_DACR_RETUNE_C29_0:
+	case WM8962_DACR_RETUNE_C30_1:
+	case WM8962_DACR_RETUNE_C30_0:
+	case WM8962_DACR_RETUNE_C31_1:
+	case WM8962_DACR_RETUNE_C31_0:
+	case WM8962_DACR_RETUNE_C32_1:
+	case WM8962_DACR_RETUNE_C32_0:
+	case WM8962_VSS_XHD2_1:
+	case WM8962_VSS_XHD2_0:
+	case WM8962_VSS_XHD3_1:
+	case WM8962_VSS_XHD3_0:
+	case WM8962_VSS_XHN1_1:
+	case WM8962_VSS_XHN1_0:
+	case WM8962_VSS_XHN2_1:
+	case WM8962_VSS_XHN2_0:
+	case WM8962_VSS_XHN3_1:
+	case WM8962_VSS_XHN3_0:
+	case WM8962_VSS_XLA_1:
+	case WM8962_VSS_XLA_0:
+	case WM8962_VSS_XLB_1:
+	case WM8962_VSS_XLB_0:
+	case WM8962_VSS_XLG_1:
+	case WM8962_VSS_XLG_0:
+	case WM8962_VSS_PG2_1:
+	case WM8962_VSS_PG2_0:
+	case WM8962_VSS_PG_1:
+	case WM8962_VSS_PG_0:
+	case WM8962_VSS_XTD1_1:
+	case WM8962_VSS_XTD1_0:
+	case WM8962_VSS_XTD2_1:
+	case WM8962_VSS_XTD2_0:
+	case WM8962_VSS_XTD3_1:
+	case WM8962_VSS_XTD3_0:
+	case WM8962_VSS_XTD4_1:
+	case WM8962_VSS_XTD4_0:
+	case WM8962_VSS_XTD5_1:
+	case WM8962_VSS_XTD5_0:
+	case WM8962_VSS_XTD6_1:
+	case WM8962_VSS_XTD6_0:
+	case WM8962_VSS_XTD7_1:
+	case WM8962_VSS_XTD7_0:
+	case WM8962_VSS_XTD8_1:
+	case WM8962_VSS_XTD8_0:
+	case WM8962_VSS_XTD9_1:
+	case WM8962_VSS_XTD9_0:
+	case WM8962_VSS_XTD10_1:
+	case WM8962_VSS_XTD10_0:
+	case WM8962_VSS_XTD11_1:
+	case WM8962_VSS_XTD11_0:
+	case WM8962_VSS_XTD12_1:
+	case WM8962_VSS_XTD12_0:
+	case WM8962_VSS_XTD13_1:
+	case WM8962_VSS_XTD13_0:
+	case WM8962_VSS_XTD14_1:
+	case WM8962_VSS_XTD14_0:
+	case WM8962_VSS_XTD15_1:
+	case WM8962_VSS_XTD15_0:
+	case WM8962_VSS_XTD16_1:
+	case WM8962_VSS_XTD16_0:
+	case WM8962_VSS_XTD17_1:
+	case WM8962_VSS_XTD17_0:
+	case WM8962_VSS_XTD18_1:
+	case WM8962_VSS_XTD18_0:
+	case WM8962_VSS_XTD19_1:
+	case WM8962_VSS_XTD19_0:
+	case WM8962_VSS_XTD20_1:
+	case WM8962_VSS_XTD20_0:
+	case WM8962_VSS_XTD21_1:
+	case WM8962_VSS_XTD21_0:
+	case WM8962_VSS_XTD22_1:
+	case WM8962_VSS_XTD22_0:
+	case WM8962_VSS_XTD23_1:
+	case WM8962_VSS_XTD23_0:
+	case WM8962_VSS_XTD24_1:
+	case WM8962_VSS_XTD24_0:
+	case WM8962_VSS_XTD25_1:
+	case WM8962_VSS_XTD25_0:
+	case WM8962_VSS_XTD26_1:
+	case WM8962_VSS_XTD26_0:
+	case WM8962_VSS_XTD27_1:
+	case WM8962_VSS_XTD27_0:
+	case WM8962_VSS_XTD28_1:
+	case WM8962_VSS_XTD28_0:
+	case WM8962_VSS_XTD29_1:
+	case WM8962_VSS_XTD29_0:
+	case WM8962_VSS_XTD30_1:
+	case WM8962_VSS_XTD30_0:
+	case WM8962_VSS_XTD31_1:
+	case WM8962_VSS_XTD31_0:
+	case WM8962_VSS_XTD32_1:
+	case WM8962_VSS_XTD32_0:
+	case WM8962_VSS_XTS1_1:
+	case WM8962_VSS_XTS1_0:
+	case WM8962_VSS_XTS2_1:
+	case WM8962_VSS_XTS2_0:
+	case WM8962_VSS_XTS3_1:
+	case WM8962_VSS_XTS3_0:
+	case WM8962_VSS_XTS4_1:
+	case WM8962_VSS_XTS4_0:
+	case WM8962_VSS_XTS5_1:
+	case WM8962_VSS_XTS5_0:
+	case WM8962_VSS_XTS6_1:
+	case WM8962_VSS_XTS6_0:
+	case WM8962_VSS_XTS7_1:
+	case WM8962_VSS_XTS7_0:
+	case WM8962_VSS_XTS8_1:
+	case WM8962_VSS_XTS8_0:
+	case WM8962_VSS_XTS9_1:
+	case WM8962_VSS_XTS9_0:
+	case WM8962_VSS_XTS10_1:
+	case WM8962_VSS_XTS10_0:
+	case WM8962_VSS_XTS11_1:
+	case WM8962_VSS_XTS11_0:
+	case WM8962_VSS_XTS12_1:
+	case WM8962_VSS_XTS12_0:
+	case WM8962_VSS_XTS13_1:
+	case WM8962_VSS_XTS13_0:
+	case WM8962_VSS_XTS14_1:
+	case WM8962_VSS_XTS14_0:
+	case WM8962_VSS_XTS15_1:
+	case WM8962_VSS_XTS15_0:
+	case WM8962_VSS_XTS16_1:
+	case WM8962_VSS_XTS16_0:
+	case WM8962_VSS_XTS17_1:
+	case WM8962_VSS_XTS17_0:
+	case WM8962_VSS_XTS18_1:
+	case WM8962_VSS_XTS18_0:
+	case WM8962_VSS_XTS19_1:
+	case WM8962_VSS_XTS19_0:
+	case WM8962_VSS_XTS20_1:
+	case WM8962_VSS_XTS20_0:
+	case WM8962_VSS_XTS21_1:
+	case WM8962_VSS_XTS21_0:
+	case WM8962_VSS_XTS22_1:
+	case WM8962_VSS_XTS22_0:
+	case WM8962_VSS_XTS23_1:
+	case WM8962_VSS_XTS23_0:
+	case WM8962_VSS_XTS24_1:
+	case WM8962_VSS_XTS24_0:
+	case WM8962_VSS_XTS25_1:
+	case WM8962_VSS_XTS25_0:
+	case WM8962_VSS_XTS26_1:
+	case WM8962_VSS_XTS26_0:
+	case WM8962_VSS_XTS27_1:
+	case WM8962_VSS_XTS27_0:
+	case WM8962_VSS_XTS28_1:
+	case WM8962_VSS_XTS28_0:
+	case WM8962_VSS_XTS29_1:
+	case WM8962_VSS_XTS29_0:
+	case WM8962_VSS_XTS30_1:
+	case WM8962_VSS_XTS30_0:
+	case WM8962_VSS_XTS31_1:
+	case WM8962_VSS_XTS31_0:
+	case WM8962_VSS_XTS32_1:
+	case WM8962_VSS_XTS32_0:
+		return true;
+	default:
+		return false;
+	}
 }
 
 static int wm8962_reset(struct wm8962_priv *wm8962)
@@ -2221,6 +1715,8 @@ SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
 SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME,
 		 WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv),
 SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0),
+SOC_SINGLE("DAC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 5, 1, 0),
+SOC_SINGLE("ADC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 8, 1, 0),
 
 SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1,
 	   5, 1, 0),
@@ -2337,65 +1833,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
 	       4, 1, 0, inmix_tlv),
 };
 
-static int sysclk_event(struct snd_soc_dapm_widget *w,
-			struct snd_kcontrol *kcontrol, int event)
-{
-	struct snd_soc_codec *codec = w->codec;
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-	unsigned long timeout;
-	int src;
-	int fll;
-
-	/* Ignore attempts to run the event during startup */
-	if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
-		return 0;
-
-	src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
-
-	switch (src) {
-	case 0:      /* MCLK */
-		fll = 0;
-		break;
-	case 0x200:  /* FLL */
-		fll = 1;
-		break;
-	default:
-		dev_err(codec->dev, "Unknown SYSCLK source %x\n", src);
-		return -EINVAL;
-	}
-
-	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		if (fll) {
-			try_wait_for_completion(&wm8962->fll_lock);
-
-			snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
-					    WM8962_FLL_ENA, WM8962_FLL_ENA);
-
-			timeout = msecs_to_jiffies(5);
-			timeout = wait_for_completion_timeout(&wm8962->fll_lock,
-							      timeout);
-
-			if (wm8962->irq && timeout == 0)
-				dev_err(codec->dev,
-					"Timed out starting FLL\n");
-		}
-		break;
-
-	case SND_SOC_DAPM_POST_PMD:
-		if (fll)
-			snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
-					    WM8962_FLL_ENA, 0);
-		break;
-
-	default:
-		BUG();
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static int cp_event(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
@@ -2564,7 +2001,7 @@ static int dsp2_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static const char *st_text[] = { "None", "Right", "Left" };
+static const char *st_text[] = { "None", "Left", "Right" };
 
 static const struct soc_enum str_enum =
 	SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text);
@@ -2681,8 +2118,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"),
 SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0),
 
 SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
-SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
-		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
 		    SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
@@ -2910,13 +2346,13 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
 	struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 
-	snd_soc_add_controls(codec, wm8962_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8962_snd_controls,
 			     ARRAY_SIZE(wm8962_snd_controls));
 	if (pdata && pdata->spk_mono)
-		snd_soc_add_controls(codec, wm8962_spk_mono_controls,
+		snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls,
 				     ARRAY_SIZE(wm8962_spk_mono_controls));
 	else
-		snd_soc_add_controls(codec, wm8962_spk_stereo_controls,
+		snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls,
 				     ARRAY_SIZE(wm8962_spk_stereo_controls));
 
 
@@ -2950,7 +2386,7 @@ static const int bclk_divs[] = {
 };
 
 static const int sysclk_rates[] = {
-	64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
+	64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144
 };
 
 static void wm8962_configure_bclk(struct snd_soc_codec *codec)
@@ -2984,6 +2420,8 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
 		return;
 	}
 
+	dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]);
+
 	snd_soc_update_bits(codec, WM8962_CLOCKING_4,
 			    WM8962_SYSCLK_RATE_MASK, clocking4);
 
@@ -3042,9 +2480,6 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec)
 static int wm8962_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-	int ret;
-
 	if (level == codec->dapm.bias_level)
 		return 0;
 
@@ -3061,51 +2496,15 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
 		break;
 
 	case SND_SOC_BIAS_STANDBY:
-		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
-						    wm8962->supplies);
-			if (ret != 0) {
-				dev_err(codec->dev,
-					"Failed to enable supplies: %d\n",
-					ret);
-				return ret;
-			}
-
-			regcache_cache_only(wm8962->regmap, false);
-			regcache_sync(wm8962->regmap);
-
-			snd_soc_update_bits(codec, WM8962_ANTI_POP,
-					    WM8962_STARTUP_BIAS_ENA |
-					    WM8962_VMID_BUF_ENA,
-					    WM8962_STARTUP_BIAS_ENA |
-					    WM8962_VMID_BUF_ENA);
-
-			/* Bias enable at 2*50k for ramp */
-			snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
-					    WM8962_VMID_SEL_MASK |
-					    WM8962_BIAS_ENA,
-					    WM8962_BIAS_ENA | 0x180);
-
-			msleep(5);
-		}
-
 		/* VMID 2*250k */
 		snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
 				    WM8962_VMID_SEL_MASK, 0x100);
 		break;
 
 	case SND_SOC_BIAS_OFF:
-		snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
-				    WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
-
-		snd_soc_update_bits(codec, WM8962_ANTI_POP,
-				    WM8962_STARTUP_BIAS_ENA |
-				    WM8962_VMID_BUF_ENA, 0);
-
-		regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
-				       wm8962->supplies);
 		break;
 	}
+
 	codec->dapm.bias_level = level;
 	return 0;
 }
@@ -3139,6 +2538,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 	int adctl3 = 0;
 
 	wm8962->bclk = snd_soc_params_to_bclk(params);
+	if (params_channels(params) == 1)
+		wm8962->bclk *= 2;
+
 	wm8962->lrclk = params_rate(params);
 
 	for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
@@ -3177,7 +2579,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 			    WM8962_SAMPLE_RATE_INT_MODE |
 			    WM8962_SAMPLE_RATE_MASK, adctl3);
 
-	wm8962_configure_bclk(codec);
+	if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
+		wm8962_configure_bclk(codec);
 
 	return 0;
 }
@@ -3207,6 +2610,8 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 
 	wm8962->sysclk_rate = freq;
 
+	wm8962_configure_bclk(codec);
+
 	return 0;
 }
 
@@ -3385,8 +2790,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	struct _fll_div fll_div;
 	unsigned long timeout;
 	int ret;
-	int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA;
-	int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA;
+	int fll1 = 0;
 
 	/* Any change? */
 	if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
@@ -3402,6 +2806,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 		snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
 				    WM8962_FLL_ENA, 0);
 
+		pm_runtime_put(codec->dev);
+
 		return 0;
 	}
 
@@ -3409,6 +2815,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	if (ret != 0)
 		return ret;
 
+	/* Parameters good, disable so we can reprogram */
+	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
+
 	switch (fll_id) {
 	case WM8962_FLL_MCLK:
 	case WM8962_FLL_BCLK:
@@ -3447,12 +2856,11 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 
 	try_wait_for_completion(&wm8962->fll_lock);
 
-	if (sysclk)
-		fll1 |= WM8962_FLL_ENA;
+	pm_runtime_get_sync(codec->dev);
 
 	snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
 			    WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
-			    WM8962_FLL_ENA, fll1);
+			    WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA);
 
 	dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
 
@@ -3513,14 +2921,14 @@ static struct snd_soc_dai_driver wm8962_dai = {
 	.name = "wm8962",
 	.playback = {
 		.stream_name = "Playback",
-		.channels_min = 2,
+		.channels_min = 1,
 		.channels_max = 2,
 		.rates = WM8962_RATES,
 		.formats = WM8962_FORMATS,
 	},
 	.capture = {
 		.stream_name = "Capture",
-		.channels_min = 2,
+		.channels_min = 1,
 		.channels_max = 2,
 		.rates = WM8962_RATES,
 		.formats = WM8962_FORMATS,
@@ -4127,20 +3535,19 @@ static int wm8962_remove(struct snd_soc_codec *codec)
 	return 0;
 }
 
-static int wm8962_soc_volatile(struct snd_soc_codec *codec,
-			       unsigned int reg)
-{
-	return true;
-}
-
-
 static struct snd_soc_codec_driver soc_codec_dev_wm8962 = {
 	.probe =	wm8962_probe,
 	.remove =	wm8962_remove,
 	.set_bias_level = wm8962_set_bias_level,
 	.set_pll = wm8962_set_fll,
-	.reg_cache_size	= WM8962_MAX_REGISTER,
-	.volatile_register = wm8962_soc_volatile,
+	.idle_bias_off = true,
+};
+
+/* Improve power consumption for IN4 DC measurement mode */
+static const struct reg_default wm8962_dc_measure[] = {
+	{ 0xfd, 0x1 },
+	{ 0xcc, 0x40 },
+	{ 0xfd, 0 },
 };
 
 static const struct regmap_config wm8962_regmap = {
@@ -4155,10 +3562,10 @@ static const struct regmap_config wm8962_regmap = {
 	.cache_type = REGCACHE_RBTREE,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
+	struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev);
 	struct wm8962_priv *wm8962;
 	unsigned int reg;
 	int ret, i;
@@ -4212,7 +3619,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
 	}
 	if (reg != 0x6243) {
 		dev_err(&i2c->dev,
-			"Device is not a WM8962, ID %x != 0x6243\n", ret);
+			"Device is not a WM8962, ID %x != 0x6243\n", reg);
 		ret = -EINVAL;
 		goto err_regmap;
 	}
@@ -4237,7 +3644,19 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
 		goto err_regmap;
 	}
 
-	regcache_cache_only(wm8962->regmap, true);
+	if (pdata && pdata->in4_dc_measure) {
+		ret = regmap_register_patch(wm8962->regmap,
+					    wm8962_dc_measure,
+					    ARRAY_SIZE(wm8962_dc_measure));
+		if (ret != 0)
+			dev_err(&i2c->dev,
+				"Failed to configure for DC mesurement: %d\n",
+				ret);
+	}
+
+	pm_runtime_set_active(&i2c->dev);
+	pm_runtime_enable(&i2c->dev);
+	pm_request_idle(&i2c->dev);
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8962, &wm8962_dai, 1);
@@ -4269,6 +3688,69 @@ static __devexit int wm8962_i2c_remove(struct i2c_client *client)
 	return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
+static int wm8962_runtime_resume(struct device *dev)
+{
+	struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
+				    wm8962->supplies);
+	if (ret != 0) {
+		dev_err(dev,
+			"Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
+	regcache_cache_only(wm8962->regmap, false);
+	regcache_sync(wm8962->regmap);
+
+	regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
+			   WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
+			   WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
+
+	/* Bias enable at 2*50k for ramp */
+	regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
+			   WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA,
+			   WM8962_BIAS_ENA | 0x180);
+
+	msleep(5);
+
+	/* VMID back to 2x250k for standby */
+	regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
+			   WM8962_VMID_SEL_MASK, 0x100);
+
+	dev_crit(dev, "RESUME\n");
+
+	return 0;
+}
+
+static int wm8962_runtime_suspend(struct device *dev)
+{
+	struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
+
+	dev_crit(dev, "SUSPEND\n");
+
+	regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
+			   WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
+
+	regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
+			   WM8962_STARTUP_BIAS_ENA |
+			   WM8962_VMID_BUF_ENA, 0);
+
+	regcache_cache_only(wm8962->regmap, true);
+
+	regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
+			       wm8962->supplies);
+
+	return 0;
+}
+#endif
+
+static struct dev_pm_ops wm8962_pm = {
+	SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL)
+};
+
 static const struct i2c_device_id wm8962_i2c_id[] = {
 	{ "wm8962", 0 },
 	{ }
@@ -4279,34 +3761,14 @@ static struct i2c_driver wm8962_i2c_driver = {
 	.driver = {
 		.name = "wm8962",
 		.owner = THIS_MODULE,
+		.pm = &wm8962_pm,
 	},
 	.probe =    wm8962_i2c_probe,
 	.remove =   __devexit_p(wm8962_i2c_remove),
 	.id_table = wm8962_i2c_id,
 };
-#endif
 
-static int __init wm8962_modinit(void)
-{
-	int ret;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	ret = i2c_add_driver(&wm8962_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8962 I2C driver: %d\n",
-		       ret);
-	}
-#endif
-	return 0;
-}
-module_init(wm8962_modinit);
-
-static void __exit wm8962_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	i2c_del_driver(&wm8962_i2c_driver);
-#endif
-}
-module_exit(wm8962_exit);
+module_i2c_driver(wm8962_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8962 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 4af8936..28fe59e 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -252,7 +252,7 @@ static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = {
 	SND_SOC_DAPM_INPUT("MIC"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8971_dapm_routes[] = {
 	/* left mixer */
 	{"Left Mixer", "Playback Switch", "Left DAC"},
 	{"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
@@ -329,17 +329,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Right ADC", NULL, "Right ADC Mux"},
 };
 
-static int wm8971_add_widgets(struct snd_soc_codec *codec)
-{
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
-				  ARRAY_SIZE(wm8971_dapm_widgets));
-	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-	return 0;
-}
-
 struct _coeff_div {
 	u32 mclk;
 	u32 rate;
@@ -659,10 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec)
 	snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
 	snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
 
-	snd_soc_add_controls(codec, wm8971_snd_controls,
-				ARRAY_SIZE(wm8971_snd_controls));
-	wm8971_add_widgets(codec);
-
 	return ret;
 }
 
@@ -686,16 +671,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
 	.reg_cache_size = ARRAY_SIZE(wm8971_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8971_reg,
+
+	.controls = wm8971_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8971_snd_controls),
+	.dapm_widgets = wm8971_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets),
+	.dapm_routes = wm8971_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8971_priv *wm8971;
 	int ret;
 
-	wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL);
+	wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
+			      GFP_KERNEL);
 	if (wm8971 == NULL)
 		return -ENOMEM;
 
@@ -704,15 +696,13 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8971, &wm8971_dai, 1);
-	if (ret < 0)
-		kfree(wm8971);
+
 	return ret;
 }
 
 static __devexit int wm8971_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
@@ -731,27 +721,22 @@ static struct i2c_driver wm8971_i2c_driver = {
 	.remove =   __devexit_p(wm8971_i2c_remove),
 	.id_table = wm8971_i2c_id,
 };
-#endif
 
 static int __init wm8971_modinit(void)
 {
 	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	ret = i2c_add_driver(&wm8971_i2c_driver);
 	if (ret != 0) {
 		printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
 		       ret);
 	}
-#endif
 	return ret;
 }
 module_init(wm8971_modinit);
 
 static void __exit wm8971_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	i2c_del_driver(&wm8971_i2c_driver);
-#endif
 }
 module_exit(wm8971_exit);
 
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 4a6a7b5..d93c03f 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -48,10 +48,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
 #define WM8974_POWER1_BIASEN  0x08
 #define WM8974_POWER1_BUFIOEN 0x04
 
-struct wm8974_priv {
-	enum snd_soc_control_type control_type;
-};
-
 #define wm8974_reset(c)	snd_soc_write(c, WM8974_RESET, 0)
 
 static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
@@ -235,7 +231,7 @@ SND_SOC_DAPM_OUTPUT("SPKOUTP"),
 SND_SOC_DAPM_OUTPUT("SPKOUTN"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8974_dapm_routes[] = {
 	/* Mono output mixer */
 	{"Mono Mixer", "PCM Playback Switch", "DAC"},
 	{"Mono Mixer", "Aux Playback Switch", "Aux Input"},
@@ -269,17 +265,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Aux Input", NULL, "AUX"},
 };
 
-static int wm8974_add_widgets(struct snd_soc_codec *codec)
-{
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets,
-				  ARRAY_SIZE(wm8974_dapm_widgets));
-	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-	return 0;
-}
-
 struct pll_ {
 	unsigned int pre_div:1;
 	unsigned int n:4;
@@ -611,9 +596,6 @@ static int wm8974_probe(struct snd_soc_codec *codec)
 	}
 
 	wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	snd_soc_add_controls(codec, wm8974_snd_controls,
-			     ARRAY_SIZE(wm8974_snd_controls));
-	wm8974_add_widgets(codec);
 
 	return ret;
 }
@@ -634,32 +616,30 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
 	.reg_cache_size = ARRAY_SIZE(wm8974_reg),
 	.reg_word_size = sizeof(u16),
 	.reg_cache_default = wm8974_reg,
+
+	.controls = wm8974_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8974_snd_controls),
+	.dapm_widgets = wm8974_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets),
+	.dapm_routes = wm8974_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
-	struct wm8974_priv *wm8974;
 	int ret;
 
-	wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL);
-	if (wm8974 == NULL)
-		return -ENOMEM;
-
-	i2c_set_clientdata(i2c, wm8974);
-
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8974, &wm8974_dai, 1);
-	if (ret < 0)
-		kfree(wm8974);
+
 	return ret;
 }
 
 static __devexit int wm8974_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+
 	return 0;
 }
 
@@ -678,27 +658,22 @@ static struct i2c_driver wm8974_i2c_driver = {
 	.remove =   __devexit_p(wm8974_i2c_remove),
 	.id_table = wm8974_i2c_id,
 };
-#endif
 
 static int __init wm8974_modinit(void)
 {
 	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	ret = i2c_add_driver(&wm8974_i2c_driver);
 	if (ret != 0) {
 		printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
 		       ret);
 	}
-#endif
 	return ret;
 }
 module_init(wm8974_modinit);
 
 static void __exit wm8974_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	i2c_del_driver(&wm8974_i2c_driver);
-#endif
 }
 module_exit(wm8974_exit);
 
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 85d514d..72d5fdc 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -29,28 +30,74 @@
 
 #include "wm8978.h"
 
-/* wm8978 register cache. Note that register 0 is not included in the cache. */
-static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
-	0x0000, 0x0000, 0x0000, 0x0000,	/* 0x00...0x03 */
-	0x0050, 0x0000, 0x0140, 0x0000,	/* 0x04...0x07 */
-	0x0000, 0x0000, 0x0000, 0x00ff,	/* 0x08...0x0b */
-	0x00ff, 0x0000, 0x0100, 0x00ff,	/* 0x0c...0x0f */
-	0x00ff, 0x0000, 0x012c, 0x002c,	/* 0x10...0x13 */
-	0x002c, 0x002c, 0x002c, 0x0000,	/* 0x14...0x17 */
-	0x0032, 0x0000, 0x0000, 0x0000,	/* 0x18...0x1b */
-	0x0000, 0x0000, 0x0000, 0x0000,	/* 0x1c...0x1f */
-	0x0038, 0x000b, 0x0032, 0x0000,	/* 0x20...0x23 */
-	0x0008, 0x000c, 0x0093, 0x00e9,	/* 0x24...0x27 */
-	0x0000, 0x0000, 0x0000, 0x0000,	/* 0x28...0x2b */
-	0x0033, 0x0010, 0x0010, 0x0100,	/* 0x2c...0x2f */
-	0x0100, 0x0002, 0x0001, 0x0001,	/* 0x30...0x33 */
-	0x0039, 0x0039, 0x0039, 0x0039,	/* 0x34...0x37 */
-	0x0001,	0x0001,			/* 0x38...0x3b */
+static const struct reg_default wm8978_reg_defaults[] = {
+	{ 1, 0x0000 },
+	{ 2, 0x0000 },
+	{ 3, 0x0000 },
+	{ 4, 0x0050 },
+	{ 5, 0x0000 },
+	{ 6, 0x0140 },
+	{ 7, 0x0000 },
+	{ 8, 0x0000 },
+	{ 9, 0x0000 },
+	{ 10, 0x0000 },
+	{ 11, 0x00ff },
+	{ 12, 0x00ff },
+	{ 13, 0x0000 },
+	{ 14, 0x0100 },
+	{ 15, 0x00ff },
+	{ 16, 0x00ff },
+	{ 17, 0x0000 },
+	{ 18, 0x012c },
+	{ 19, 0x002c },
+	{ 20, 0x002c },
+	{ 21, 0x002c },
+	{ 22, 0x002c },
+	{ 23, 0x0000 },
+	{ 24, 0x0032 },
+	{ 25, 0x0000 },
+	{ 26, 0x0000 },
+	{ 27, 0x0000 },
+	{ 28, 0x0000 },
+	{ 29, 0x0000 },
+	{ 30, 0x0000 },
+	{ 31, 0x0000 },
+	{ 32, 0x0038 },
+	{ 33, 0x000b },
+	{ 34, 0x0032 },
+	{ 35, 0x0000 },
+	{ 36, 0x0008 },
+	{ 37, 0x000c },
+	{ 38, 0x0093 },
+	{ 39, 0x00e9 },
+	{ 40, 0x0000 },
+	{ 41, 0x0000 },
+	{ 42, 0x0000 },
+	{ 43, 0x0000 },
+	{ 44, 0x0033 },
+	{ 45, 0x0010 },
+	{ 46, 0x0010 },
+	{ 47, 0x0100 },
+	{ 48, 0x0100 },
+	{ 49, 0x0002 },
+	{ 50, 0x0001 },
+	{ 51, 0x0001 },
+	{ 52, 0x0039 },
+	{ 53, 0x0039 },
+	{ 54, 0x0039 },
+	{ 55, 0x0039 },
+	{ 56, 0x0001 },
+	{ 57, 0x0001 },
 };
 
+static bool wm8978_volatile(struct device *dev, unsigned int reg)
+{
+	return reg == WM8978_RESET;
+}
+
 /* codec private data */
 struct wm8978_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	unsigned int f_pllout;
 	unsigned int f_mclk;
 	unsigned int f_256fs;
@@ -303,7 +350,7 @@ static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
 	SND_SOC_DAPM_OUTPUT("RSPK"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8978_dapm_routes[] = {
 	/* Output mixer */
 	{"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
 	{"Right Output Mixer", "Aux Playback Switch", "RAUX"},
@@ -352,18 +399,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Left Input Mixer", "MicP Switch", "LMICP"},
 };
 
-static int wm8978_add_widgets(struct snd_soc_codec *codec)
-{
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
-				  ARRAY_SIZE(wm8978_dapm_widgets));
-	/* set up the WM8978 audio map */
-	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
-	return 0;
-}
-
 /* PLL divisors */
 struct wm8978_pll_div {
 	u32 k;
@@ -894,26 +929,23 @@ static struct snd_soc_dai_driver wm8978_dai = {
 
 static int wm8978_suspend(struct snd_soc_codec *codec)
 {
+	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
+
 	wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
 	/* Also switch PLL off */
 	snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
 
+	regcache_mark_dirty(wm8978->regmap);
+
 	return 0;
 }
 
 static int wm8978_resume(struct snd_soc_codec *codec)
 {
 	struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
-	int i;
-	u16 *cache = codec->reg_cache;
 
 	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) {
-		if (i == WM8978_RESET)
-			continue;
-		if (cache[i] != wm8978_reg[i])
-			snd_soc_write(codec, i, cache[i]);
-	}
+	regcache_sync(wm8978->regmap);
 
 	wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
@@ -953,7 +985,8 @@ static int wm8978_probe(struct snd_soc_codec *codec)
 	 * default hardware setting
 	 */
 	wm8978->sysclk = WM8978_PLL;
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
+	codec->control_data = wm8978->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -967,19 +1000,8 @@ static int wm8978_probe(struct snd_soc_codec *codec)
 	for (i = 0; i < ARRAY_SIZE(update_reg); i++)
 		snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100);
 
-	/* Reset the codec */
-	ret = snd_soc_write(codec, WM8978_RESET, 0);
-	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
-		return ret;
-	}
-
 	wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-	snd_soc_add_controls(codec, wm8978_snd_controls,
-			     ARRAY_SIZE(wm8978_snd_controls));
-	wm8978_add_widgets(codec);
-
 	return 0;
 }
 
@@ -996,35 +1018,75 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = {
 	.suspend =	wm8978_suspend,
 	.resume =	wm8978_resume,
 	.set_bias_level = wm8978_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8978_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8978_reg,
+
+	.controls = wm8978_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8978_snd_controls),
+	.dapm_widgets = wm8978_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets),
+	.dapm_routes = wm8978_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes),
+};
+
+static const struct regmap_config wm8978_regmap_config = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.max_register = WM8978_MAX_REGISTER,
+	.volatile_reg = wm8978_volatile,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8978_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults),
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8978_priv *wm8978;
 	int ret;
 
-	wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
+	wm8978 = devm_kzalloc(&i2c->dev, sizeof(struct wm8978_priv),
+			      GFP_KERNEL);
 	if (wm8978 == NULL)
 		return -ENOMEM;
 
+	wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config);
+	if (IS_ERR(wm8978->regmap)) {
+		ret = PTR_ERR(wm8978->regmap);
+		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8978);
 
+	/* Reset the codec */
+	ret = regmap_write(wm8978->regmap, WM8978_RESET, 0);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
+		goto err;
+	}
+
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8978, &wm8978_dai, 1);
-	if (ret < 0)
-		kfree(wm8978);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	regmap_exit(wm8978->regmap);
 	return ret;
 }
 
 static __devexit int wm8978_i2c_remove(struct i2c_client *client)
 {
+	struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
+
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	regmap_exit(wm8978->regmap);
+
 	return 0;
 }
 
@@ -1043,27 +1105,22 @@ static struct i2c_driver wm8978_i2c_driver = {
 	.remove =   __devexit_p(wm8978_i2c_remove),
 	.id_table = wm8978_i2c_id,
 };
-#endif
 
 static int __init wm8978_modinit(void)
 {
 	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	ret = i2c_add_driver(&wm8978_i2c_driver);
 	if (ret != 0) {
 		printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
 		       ret);
 	}
-#endif
 	return ret;
 }
 module_init(wm8978_modinit);
 
 static void __exit wm8978_exit(void)
 {
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	i2c_del_driver(&wm8978_i2c_driver);
-#endif
 }
 module_exit(wm8978_exit);
 
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
index c75525b..6ae4349 100644
--- a/sound/soc/codecs/wm8978.h
+++ b/sound/soc/codecs/wm8978.h
@@ -67,6 +67,8 @@
 #define WM8978_OUT3_MIXER_CONTROL		0x38
 #define WM8978_OUT4_MIXER_CONTROL		0x39
 
+#define WM8978_MAX_REGISTER			0x39
+
 #define WM8978_CACHEREGNUM			58
 
 /* Clock divider Id's */
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index cebde56..367388f 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -249,9 +249,6 @@ static const char *eq5_cutoff_text[] = {
 static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5,
 				  eq5_cutoff_text);
 
-static const char *speaker_mode_text[] = { "Class A/B", "Class D" };
-static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text);
-
 static const char *depth_3d_text[] = {
 	"Off",
 	"6.67%",
@@ -369,8 +366,6 @@ static const struct snd_kcontrol_new wm8983_snd_controls[] = {
 	SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv),
 
 	SOC_ENUM("3D Depth", depth_3d),
-
-	SOC_ENUM("Speaker Mode", speaker_mode)
 };
 
 static const struct snd_kcontrol_new left_out_mixer[] = {
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index c0c86b3..14f6663 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
@@ -39,73 +40,127 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = {
 	"AVDD2"
 };
 
-static const u16 wm8985_reg_defs[] = {
-	0x0000,     /* R0  - Software Reset */
-	0x0000,     /* R1  - Power management 1 */
-	0x0000,     /* R2  - Power management 2 */
-	0x0000,     /* R3  - Power management 3 */
-	0x0050,     /* R4  - Audio Interface */
-	0x0000,     /* R5  - Companding control */
-	0x0140,     /* R6  - Clock Gen control */
-	0x0000,     /* R7  - Additional control */
-	0x0000,     /* R8  - GPIO Control */
-	0x0000,     /* R9  - Jack Detect Control 1 */
-	0x0000,     /* R10 - DAC Control */
-	0x00FF,     /* R11 - Left DAC digital Vol */
-	0x00FF,     /* R12 - Right DAC digital vol */
-	0x0000,     /* R13 - Jack Detect Control 2 */
-	0x0100,     /* R14 - ADC Control */
-	0x00FF,     /* R15 - Left ADC Digital Vol */
-	0x00FF,     /* R16 - Right ADC Digital Vol */
-	0x0000,     /* R17 */
-	0x012C,     /* R18 - EQ1 - low shelf */
-	0x002C,     /* R19 - EQ2 - peak 1 */
-	0x002C,     /* R20 - EQ3 - peak 2 */
-	0x002C,     /* R21 - EQ4 - peak 3 */
-	0x002C,     /* R22 - EQ5 - high shelf */
-	0x0000,     /* R23 */
-	0x0032,     /* R24 - DAC Limiter 1 */
-	0x0000,     /* R25 - DAC Limiter 2 */
-	0x0000,     /* R26 */
-	0x0000,     /* R27 - Notch Filter 1 */
-	0x0000,     /* R28 - Notch Filter 2 */
-	0x0000,     /* R29 - Notch Filter 3 */
-	0x0000,     /* R30 - Notch Filter 4 */
-	0x0000,     /* R31 */
-	0x0038,     /* R32 - ALC control 1 */
-	0x000B,     /* R33 - ALC control 2 */
-	0x0032,     /* R34 - ALC control 3 */
-	0x0000,     /* R35 - Noise Gate */
-	0x0008,     /* R36 - PLL N */
-	0x000C,     /* R37 - PLL K 1 */
-	0x0093,     /* R38 - PLL K 2 */
-	0x00E9,     /* R39 - PLL K 3 */
-	0x0000,     /* R40 */
-	0x0000,     /* R41 - 3D control */
-	0x0000,     /* R42 - OUT4 to ADC */
-	0x0000,     /* R43 - Beep control */
-	0x0033,     /* R44 - Input ctrl */
-	0x0010,     /* R45 - Left INP PGA gain ctrl */
-	0x0010,     /* R46 - Right INP PGA gain ctrl */
-	0x0100,     /* R47 - Left ADC BOOST ctrl */
-	0x0100,     /* R48 - Right ADC BOOST ctrl */
-	0x0002,     /* R49 - Output ctrl */
-	0x0001,     /* R50 - Left mixer ctrl */
-	0x0001,     /* R51 - Right mixer ctrl */
-	0x0039,     /* R52 - LOUT1 (HP) volume ctrl */
-	0x0039,     /* R53 - ROUT1 (HP) volume ctrl */
-	0x0039,     /* R54 - LOUT2 (SPK) volume ctrl */
-	0x0039,     /* R55 - ROUT2 (SPK) volume ctrl */
-	0x0001,     /* R56 - OUT3 mixer ctrl */
-	0x0001,     /* R57 - OUT4 (MONO) mix ctrl */
-	0x0001,     /* R58 */
-	0x0000,     /* R59 */
-	0x0004,     /* R60 - OUTPUT ctrl */
-	0x0000,     /* R61 - BIAS CTRL */
-	0x0180,     /* R62 */
-	0x0000      /* R63 */
+static const struct reg_default wm8985_reg_defaults[] = {
+	{ 1,  0x0000 },     /* R1  - Power management 1 */
+	{ 2,  0x0000 },     /* R2  - Power management 2 */
+	{ 3,  0x0000 },     /* R3  - Power management 3 */
+	{ 4,  0x0050 },     /* R4  - Audio Interface */
+	{ 5,  0x0000 },     /* R5  - Companding control */
+	{ 6,  0x0140 },     /* R6  - Clock Gen control */
+	{ 7,  0x0000 },     /* R7  - Additional control */
+	{ 8,  0x0000 },     /* R8  - GPIO Control */
+	{ 9,  0x0000 },     /* R9  - Jack Detect Control 1 */
+	{ 10, 0x0000 },     /* R10 - DAC Control */
+	{ 11, 0x00FF },     /* R11 - Left DAC digital Vol */
+	{ 12, 0x00FF },     /* R12 - Right DAC digital vol */
+	{ 13, 0x0000 },     /* R13 - Jack Detect Control 2 */
+	{ 14, 0x0100 },     /* R14 - ADC Control */
+	{ 15, 0x00FF },     /* R15 - Left ADC Digital Vol */
+	{ 16, 0x00FF },     /* R16 - Right ADC Digital Vol */
+	{ 18, 0x012C },     /* R18 - EQ1 - low shelf */
+	{ 19, 0x002C },     /* R19 - EQ2 - peak 1 */
+	{ 20, 0x002C },     /* R20 - EQ3 - peak 2 */
+	{ 21, 0x002C },     /* R21 - EQ4 - peak 3 */
+	{ 22, 0x002C },     /* R22 - EQ5 - high shelf */
+	{ 24, 0x0032 },     /* R24 - DAC Limiter 1 */
+	{ 25, 0x0000 },     /* R25 - DAC Limiter 2 */
+	{ 27, 0x0000 },     /* R27 - Notch Filter 1 */
+	{ 28, 0x0000 },     /* R28 - Notch Filter 2 */
+	{ 29, 0x0000 },     /* R29 - Notch Filter 3 */
+	{ 30, 0x0000 },     /* R30 - Notch Filter 4 */
+	{ 32, 0x0038 },     /* R32 - ALC control 1 */
+	{ 33, 0x000B },     /* R33 - ALC control 2 */
+	{ 34, 0x0032 },     /* R34 - ALC control 3 */
+	{ 35, 0x0000 },     /* R35 - Noise Gate */
+	{ 36, 0x0008 },     /* R36 - PLL N */
+	{ 37, 0x000C },     /* R37 - PLL K 1 */
+	{ 38, 0x0093 },     /* R38 - PLL K 2 */
+	{ 39, 0x00E9 },     /* R39 - PLL K 3 */
+	{ 41, 0x0000 },     /* R41 - 3D control */
+	{ 42, 0x0000 },     /* R42 - OUT4 to ADC */
+	{ 43, 0x0000 },     /* R43 - Beep control */
+	{ 44, 0x0033 },     /* R44 - Input ctrl */
+	{ 45, 0x0010 },     /* R45 - Left INP PGA gain ctrl */
+	{ 46, 0x0010 },     /* R46 - Right INP PGA gain ctrl */
+	{ 47, 0x0100 },     /* R47 - Left ADC BOOST ctrl */
+	{ 48, 0x0100 },     /* R48 - Right ADC BOOST ctrl */
+	{ 49, 0x0002 },     /* R49 - Output ctrl */
+	{ 50, 0x0001 },     /* R50 - Left mixer ctrl */
+	{ 51, 0x0001 },     /* R51 - Right mixer ctrl */
+	{ 52, 0x0039 },     /* R52 - LOUT1 (HP) volume ctrl */
+	{ 53, 0x0039 },     /* R53 - ROUT1 (HP) volume ctrl */
+	{ 54, 0x0039 },     /* R54 - LOUT2 (SPK) volume ctrl */
+	{ 55, 0x0039 },     /* R55 - ROUT2 (SPK) volume ctrl */
+	{ 56, 0x0001 },     /* R56 - OUT3 mixer ctrl */
+	{ 57, 0x0001 },     /* R57 - OUT4 (MONO) mix ctrl */
+	{ 60, 0x0004 },     /* R60 - OUTPUT ctrl */
+	{ 61, 0x0000 },     /* R61 - BIAS CTRL */
 };
 
+static bool wm8985_writeable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8985_SOFTWARE_RESET:
+	case WM8985_POWER_MANAGEMENT_1:
+	case WM8985_POWER_MANAGEMENT_2:
+	case WM8985_POWER_MANAGEMENT_3:
+	case WM8985_AUDIO_INTERFACE:
+	case WM8985_COMPANDING_CONTROL:
+	case WM8985_CLOCK_GEN_CONTROL:
+	case WM8985_ADDITIONAL_CONTROL:
+	case WM8985_GPIO_CONTROL:
+	case WM8985_JACK_DETECT_CONTROL_1:
+	case WM8985_DAC_CONTROL:
+	case WM8985_LEFT_DAC_DIGITAL_VOL:
+	case WM8985_RIGHT_DAC_DIGITAL_VOL:
+	case WM8985_JACK_DETECT_CONTROL_2:
+	case WM8985_ADC_CONTROL:
+	case WM8985_LEFT_ADC_DIGITAL_VOL:
+	case WM8985_RIGHT_ADC_DIGITAL_VOL:
+	case WM8985_EQ1_LOW_SHELF:
+	case WM8985_EQ2_PEAK_1:
+	case WM8985_EQ3_PEAK_2:
+	case WM8985_EQ4_PEAK_3:
+	case WM8985_EQ5_HIGH_SHELF:
+	case WM8985_DAC_LIMITER_1:
+	case WM8985_DAC_LIMITER_2:
+	case WM8985_NOTCH_FILTER_1:
+	case WM8985_NOTCH_FILTER_2:
+	case WM8985_NOTCH_FILTER_3:
+	case WM8985_NOTCH_FILTER_4:
+	case WM8985_ALC_CONTROL_1:
+	case WM8985_ALC_CONTROL_2:
+	case WM8985_ALC_CONTROL_3:
+	case WM8985_NOISE_GATE:
+	case WM8985_PLL_N:
+	case WM8985_PLL_K_1:
+	case WM8985_PLL_K_2:
+	case WM8985_PLL_K_3:
+	case WM8985_3D_CONTROL:
+	case WM8985_OUT4_TO_ADC:
+	case WM8985_BEEP_CONTROL:
+	case WM8985_INPUT_CTRL:
+	case WM8985_LEFT_INP_PGA_GAIN_CTRL:
+	case WM8985_RIGHT_INP_PGA_GAIN_CTRL:
+	case WM8985_LEFT_ADC_BOOST_CTRL:
+	case WM8985_RIGHT_ADC_BOOST_CTRL:
+	case WM8985_OUTPUT_CTRL0:
+	case WM8985_LEFT_MIXER_CTRL:
+	case WM8985_RIGHT_MIXER_CTRL:
+	case WM8985_LOUT1_HP_VOLUME_CTRL:
+	case WM8985_ROUT1_HP_VOLUME_CTRL:
+	case WM8985_LOUT2_SPK_VOLUME_CTRL:
+	case WM8985_ROUT2_SPK_VOLUME_CTRL:
+	case WM8985_OUT3_MIXER_CTRL:
+	case WM8985_OUT4_MONO_MIX_CTRL:
+	case WM8985_OUTPUT_CTRL1:
+	case WM8985_BIAS_CTRL:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /*
  * latch bit 8 of these registers to ensure instant
  * volume updates
@@ -124,7 +179,7 @@ static const int volume_update_regs[] = {
 };
 
 struct wm8985_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES];
 	unsigned int sysclk;
 	unsigned int bclk;
@@ -428,7 +483,7 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = {
 	SND_SOC_DAPM_OUTPUT("SPKR")
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8985_dapm_routes[] = {
 	{ "Right Output Mixer", "PCM Switch", "Right DAC" },
 	{ "Right Output Mixer", "Aux Switch", "AUXR" },
 	{ "Right Output Mixer", "Line Switch", "Right Boost Mixer" },
@@ -531,17 +586,6 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static int wm8985_add_widgets(struct snd_soc_codec *codec)
-{
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
-	snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
-				  ARRAY_SIZE(wm8985_dapm_widgets));
-	snd_soc_dapm_add_routes(dapm, audio_map,
-				ARRAY_SIZE(audio_map));
-	return 0;
-}
-
 static int wm8985_reset(struct snd_soc_codec *codec)
 {
 	return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0);
@@ -845,25 +889,6 @@ static int wm8985_set_sysclk(struct snd_soc_dai *dai,
 	return 0;
 }
 
-static void wm8985_sync_cache(struct snd_soc_codec *codec)
-{
-	short i;
-	u16 *cache;
-
-	if (!codec->cache_sync)
-		return;
-	codec->cache_only = 0;
-	/* restore cache */
-	cache = codec->reg_cache;
-	for (i = 0; i < codec->driver->reg_cache_size; i++) {
-		if (i == WM8985_SOFTWARE_RESET
-				|| cache[i] == wm8985_reg_defs[i])
-			continue;
-		snd_soc_write(codec, i, cache[i]);
-	}
-	codec->cache_sync = 0;
-}
-
 static int wm8985_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
@@ -890,7 +915,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
 				return ret;
 			}
 
-			wm8985_sync_cache(codec);
+			regcache_sync(wm8985->regmap);
 
 			/* enable anti-pop features */
 			snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC,
@@ -933,7 +958,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
 		snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0);
 		snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0);
 
-		codec->cache_sync = 1;
+		regcache_mark_dirty(wm8985->regmap);
 
 		regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies),
 				       wm8985->supplies);
@@ -976,11 +1001,11 @@ static int wm8985_probe(struct snd_soc_codec *codec)
 	size_t i;
 	struct wm8985_priv *wm8985;
 	int ret;
-	u16 *cache;
 
 	wm8985 = snd_soc_codec_get_drvdata(codec);
+	codec->control_data = wm8985->regmap;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
 		return ret;
@@ -1009,17 +1034,13 @@ static int wm8985_probe(struct snd_soc_codec *codec)
 		goto err_reg_enable;
 	}
 
-	cache = codec->reg_cache;
 	/* latch volume update bits */
 	for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i)
-		cache[volume_update_regs[i]] |= 0x100;
+		snd_soc_update_bits(codec, volume_update_regs[i],
+				    0x100, 0x100);
 	/* enable BIASCUT */
-	cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT;
-	codec->cache_sync = 1;
-
-	snd_soc_add_controls(codec, wm8985_snd_controls,
-			     ARRAY_SIZE(wm8985_snd_controls));
-	wm8985_add_widgets(codec);
+	snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT,
+			    WM8985_BIASCUT);
 
 	wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	return 0;
@@ -1068,9 +1089,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = {
 	.suspend = wm8985_suspend,
 	.resume = wm8985_resume,
 	.set_bias_level = wm8985_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8985_reg_defs),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8985_reg_defs
+
+	.controls = wm8985_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8985_snd_controls),
+	.dapm_widgets = wm8985_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets),
+	.dapm_routes = wm8985_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes),
+};
+
+static const struct regmap_config wm8985_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.max_register = WM8985_MAX_REGISTER,
+	.writeable_reg = wm8985_writeable,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8985_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8985_reg_defaults),
 };
 
 #if defined(CONFIG_SPI_MASTER)
@@ -1079,24 +1116,39 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi)
 	struct wm8985_priv *wm8985;
 	int ret;
 
-	wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL);
+	wm8985 = devm_kzalloc(&spi->dev, sizeof *wm8985, GFP_KERNEL);
 	if (!wm8985)
 		return -ENOMEM;
 
-	wm8985->control_type = SND_SOC_SPI;
 	spi_set_drvdata(spi, wm8985);
 
+	wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap);
+	if (IS_ERR(wm8985->regmap)) {
+		ret = PTR_ERR(wm8985->regmap);
+		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
 	ret = snd_soc_register_codec(&spi->dev,
 				     &soc_codec_dev_wm8985, &wm8985_dai, 1);
-	if (ret < 0)
-		kfree(wm8985);
+	if (ret != 0)
+		goto err;
+
+	return 0;
+
+err:
+	regmap_exit(wm8985->regmap);
 	return ret;
 }
 
 static int __devexit wm8985_spi_remove(struct spi_device *spi)
 {
+	struct wm8985_priv *wm8985 = spi_get_drvdata(spi);
+
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+	regmap_exit(wm8985->regmap);
+
 	return 0;
 }
 
@@ -1117,24 +1169,39 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c,
 	struct wm8985_priv *wm8985;
 	int ret;
 
-	wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL);
+	wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL);
 	if (!wm8985)
 		return -ENOMEM;
 
-	wm8985->control_type = SND_SOC_I2C;
 	i2c_set_clientdata(i2c, wm8985);
 
+	wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap);
+	if (IS_ERR(wm8985->regmap)) {
+		ret = PTR_ERR(wm8985->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8985, &wm8985_dai, 1);
-	if (ret < 0)
-		kfree(wm8985);
+	if (ret != 0)
+		goto err;
+
+	return 0;
+
+err:
+	regmap_exit(wm8985->regmap);
 	return ret;
 }
 
-static __devexit int wm8985_i2c_remove(struct i2c_client *client)
+static __devexit int wm8985_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c);
+
+	snd_soc_unregister_codec(&i2c->dev);
+	regmap_exit(wm8985->regmap);
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index ab52963..6cdf6a2 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -33,24 +33,89 @@
  * We can't read the WM8988 register space when we
  * are using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8988_reg[] = {
-	0x0097, 0x0097, 0x0079, 0x0079,  /*  0 */
-	0x0000, 0x0008, 0x0000, 0x000a,  /*  4 */
-	0x0000, 0x0000, 0x00ff, 0x00ff,  /*  8 */
-	0x000f, 0x000f, 0x0000, 0x0000,  /* 12 */
-	0x0000, 0x007b, 0x0000, 0x0032,  /* 16 */
-	0x0000, 0x00c3, 0x00c3, 0x00c0,  /* 20 */
-	0x0000, 0x0000, 0x0000, 0x0000,  /* 24 */
-	0x0000, 0x0000, 0x0000, 0x0000,  /* 28 */
-	0x0000, 0x0000, 0x0050, 0x0050,  /* 32 */
-	0x0050, 0x0050, 0x0050, 0x0050,  /* 36 */
-	0x0079, 0x0079, 0x0079,          /* 40 */
+static const struct reg_default wm8988_reg_defaults[] = {
+	{ 0, 0x0097 },
+	{ 1, 0x0097 },
+	{ 2, 0x0079 },
+	{ 3, 0x0079 },
+	{ 5, 0x0008 },
+	{ 7, 0x000a },
+	{ 8, 0x0000 },
+	{ 10, 0x00ff },
+	{ 11, 0x00ff },
+	{ 12, 0x000f },
+	{ 13, 0x000f },
+	{ 16, 0x0000 },
+	{ 17, 0x007b },
+	{ 18, 0x0000 },
+	{ 19, 0x0032 },
+	{ 20, 0x0000 },
+	{ 21, 0x00c3 },
+	{ 22, 0x00c3 },
+	{ 23, 0x00c0 },
+	{ 24, 0x0000 },
+	{ 25, 0x0000 },
+	{ 26, 0x0000 },
+	{ 27, 0x0000 },
+	{ 31, 0x0000 },
+	{ 32, 0x0000 },
+	{ 33, 0x0000 },
+	{ 34, 0x0050 },
+	{ 35, 0x0050 },
+	{ 36, 0x0050 },
+	{ 37, 0x0050 },
+	{ 40, 0x0079 },
+	{ 41, 0x0079 },
+	{ 42, 0x0079 },
 };
 
+static bool wm8988_writeable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8988_LINVOL:
+	case WM8988_RINVOL:
+	case WM8988_LOUT1V:
+	case WM8988_ROUT1V:
+	case WM8988_ADCDAC:
+	case WM8988_IFACE:
+	case WM8988_SRATE:
+	case WM8988_LDAC:
+	case WM8988_RDAC:
+	case WM8988_BASS:
+	case WM8988_TREBLE:
+	case WM8988_RESET:
+	case WM8988_3D:
+	case WM8988_ALC1:
+	case WM8988_ALC2:
+	case WM8988_ALC3:
+	case WM8988_NGATE:
+	case WM8988_LADC:
+	case WM8988_RADC:
+	case WM8988_ADCTL1:
+	case WM8988_ADCTL2:
+	case WM8988_PWR1:
+	case WM8988_PWR2:
+	case WM8988_ADCTL3:
+	case WM8988_ADCIN:
+	case WM8988_LADCIN:
+	case WM8988_RADCIN:
+	case WM8988_LOUTM1:
+	case WM8988_LOUTM2:
+	case WM8988_ROUTM1:
+	case WM8988_ROUTM2:
+	case WM8988_LOUT2V:
+	case WM8988_ROUT2V:
+	case WM8988_LPPB:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /* codec private data */
 struct wm8988_priv {
+	struct regmap *regmap;
 	unsigned int sysclk;
-	enum snd_soc_control_type control_type;
 	struct snd_pcm_hw_constraint_list *sysclk_constraints;
 };
 
@@ -317,7 +382,7 @@ static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
 	SND_SOC_DAPM_INPUT("RINPUT2"),
 };
 
-static const struct snd_soc_dapm_route audio_map[] = {
+static const struct snd_soc_dapm_route wm8988_dapm_routes[] = {
 
 	{ "Left Line Mux", "Line 1", "LINPUT1" },
 	{ "Left Line Mux", "Line 2", "LINPUT2" },
@@ -661,6 +726,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute)
 static int wm8988_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
 	u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
 
 	switch (level) {
@@ -674,7 +740,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
 
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8988->regmap);
 
 			/* VREF, VMID=2x5k */
 			snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
@@ -730,7 +796,10 @@ static struct snd_soc_dai_driver wm8988_dai = {
 
 static int wm8988_suspend(struct snd_soc_codec *codec)
 {
+	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
+
 	wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF);
+	regcache_mark_dirty(wm8988->regmap);
 	return 0;
 }
 
@@ -743,10 +812,10 @@ static int wm8988_resume(struct snd_soc_codec *codec)
 static int wm8988_probe(struct snd_soc_codec *codec)
 {
 	struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int ret = 0;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type);
+	codec->control_data = wm8988->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -767,12 +836,6 @@ static int wm8988_probe(struct snd_soc_codec *codec)
 
 	wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-	snd_soc_add_controls(codec, wm8988_snd_controls,
-				ARRAY_SIZE(wm8988_snd_controls));
-	snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
-				  ARRAY_SIZE(wm8988_dapm_widgets));
-	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
 	return 0;
 }
 
@@ -788,9 +851,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
 	.suspend =	wm8988_suspend,
 	.resume =	wm8988_resume,
 	.set_bias_level = wm8988_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8988_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8988_reg,
+
+	.controls = wm8988_snd_controls,
+	.num_controls = ARRAY_SIZE(wm8988_snd_controls),
+	.dapm_widgets = wm8988_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets),
+	.dapm_routes = wm8988_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
+};
+
+static struct regmap_config wm8988_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.max_register = WM8988_LPPB,
+	.writeable_reg = wm8988_writeable,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8988_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
 };
 
 #if defined(CONFIG_SPI_MASTER)
@@ -799,24 +878,33 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
 	struct wm8988_priv *wm8988;
 	int ret;
 
-	wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
+	wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv),
+			      GFP_KERNEL);
 	if (wm8988 == NULL)
 		return -ENOMEM;
 
-	wm8988->control_type = SND_SOC_SPI;
+	wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap);
+	if (IS_ERR(wm8988->regmap)) {
+		ret = PTR_ERR(wm8988->regmap);
+		dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	spi_set_drvdata(spi, wm8988);
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8988, &wm8988_dai, 1);
-	if (ret < 0)
-		kfree(wm8988);
+	if (ret != 0)
+		regmap_exit(wm8988->regmap);
+
 	return ret;
 }
 
 static int __devexit wm8988_spi_remove(struct spi_device *spi)
 {
+	struct wm8988_priv *wm8988 = spi_get_drvdata(spi);
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+	regmap_exit(wm8988->regmap);
 	return 0;
 }
 
@@ -837,24 +925,33 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c,
 	struct wm8988_priv *wm8988;
 	int ret;
 
-	wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL);
+	wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv),
+			      GFP_KERNEL);
 	if (wm8988 == NULL)
 		return -ENOMEM;
 
 	i2c_set_clientdata(i2c, wm8988);
-	wm8988->control_type = SND_SOC_I2C;
+
+	wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap);
+	if (IS_ERR(wm8988->regmap)) {
+		ret = PTR_ERR(wm8988->regmap);
+		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8988, &wm8988_dai, 1);
-	if (ret < 0)
-		kfree(wm8988);
+	if (ret != 0)
+		regmap_exit(wm8988->regmap);
+
 	return ret;
 }
 
 static __devexit int wm8988_i2c_remove(struct i2c_client *client)
 {
+	struct wm8988_priv *wm8988 = i2c_get_clientdata(client);
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	regmap_exit(wm8988->regmap);
 	return 0;
 }
 
@@ -866,7 +963,7 @@ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
 
 static struct i2c_driver wm8988_i2c_driver = {
 	.driver = {
-		.name = "wm8988-codec",
+		.name = "wm8988",
 		.owner = THIS_MODULE,
 	},
 	.probe =    wm8988_i2c_probe,
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index e538eda..9d24235 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1356,7 +1356,7 @@ static int wm8990_probe(struct snd_soc_codec *codec)
 	snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
 	snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
-	snd_soc_add_controls(codec, wm8990_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8990_snd_controls,
 				ARRAY_SIZE(wm8990_snd_controls));
 	wm8990_add_widgets(codec);
 
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 7ee40da..9ac31ba 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1297,7 +1297,7 @@ static int wm8991_probe(struct snd_soc_codec *codec)
 	snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
 	snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
 
-	snd_soc_add_controls(codec, wm8991_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8991_snd_controls,
 			     ARRAY_SIZE(wm8991_snd_controls));
 
 	snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 7c7fd92..d256a93 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
@@ -40,134 +41,113 @@ static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
 	"SPKVDD",
 };
 
-static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
-	0x8993,     /* R0   - Software Reset */
-	0x0000,     /* R1   - Power Management (1) */
-	0x6000,     /* R2   - Power Management (2) */
-	0x0000,     /* R3   - Power Management (3) */
-	0x4050,     /* R4   - Audio Interface (1) */
-	0x4000,     /* R5   - Audio Interface (2) */
-	0x01C8,     /* R6   - Clocking 1 */
-	0x0000,     /* R7   - Clocking 2 */
-	0x0000,     /* R8   - Audio Interface (3) */
-	0x0040,     /* R9   - Audio Interface (4) */
-	0x0004,     /* R10  - DAC CTRL */
-	0x00C0,     /* R11  - Left DAC Digital Volume */
-	0x00C0,     /* R12  - Right DAC Digital Volume */
-	0x0000,     /* R13  - Digital Side Tone */
-	0x0300,     /* R14  - ADC CTRL */
-	0x00C0,     /* R15  - Left ADC Digital Volume */
-	0x00C0,     /* R16  - Right ADC Digital Volume */
-	0x0000,     /* R17 */
-	0x0000,     /* R18  - GPIO CTRL 1 */
-	0x0010,     /* R19  - GPIO1 */
-	0x0000,     /* R20  - IRQ_DEBOUNCE */
-	0x0000,     /* R21 */
-	0x8000,     /* R22  - GPIOCTRL 2 */
-	0x0800,     /* R23  - GPIO_POL */
-	0x008B,     /* R24  - Left Line Input 1&2 Volume */
-	0x008B,     /* R25  - Left Line Input 3&4 Volume */
-	0x008B,     /* R26  - Right Line Input 1&2 Volume */
-	0x008B,     /* R27  - Right Line Input 3&4 Volume */
-	0x006D,     /* R28  - Left Output Volume */
-	0x006D,     /* R29  - Right Output Volume */
-	0x0066,     /* R30  - Line Outputs Volume */
-	0x0020,     /* R31  - HPOUT2 Volume */
-	0x0079,     /* R32  - Left OPGA Volume */
-	0x0079,     /* R33  - Right OPGA Volume */
-	0x0003,     /* R34  - SPKMIXL Attenuation */
-	0x0003,     /* R35  - SPKMIXR Attenuation */
-	0x0011,     /* R36  - SPKOUT Mixers */
-	0x0100,     /* R37  - SPKOUT Boost */
-	0x0079,     /* R38  - Speaker Volume Left */
-	0x0079,     /* R39  - Speaker Volume Right */
-	0x0000,     /* R40  - Input Mixer2 */
-	0x0000,     /* R41  - Input Mixer3 */
-	0x0000,     /* R42  - Input Mixer4 */
-	0x0000,     /* R43  - Input Mixer5 */
-	0x0000,     /* R44  - Input Mixer6 */
-	0x0000,     /* R45  - Output Mixer1 */
-	0x0000,     /* R46  - Output Mixer2 */
-	0x0000,     /* R47  - Output Mixer3 */
-	0x0000,     /* R48  - Output Mixer4 */
-	0x0000,     /* R49  - Output Mixer5 */
-	0x0000,     /* R50  - Output Mixer6 */
-	0x0000,     /* R51  - HPOUT2 Mixer */
-	0x0000,     /* R52  - Line Mixer1 */
-	0x0000,     /* R53  - Line Mixer2 */
-	0x0000,     /* R54  - Speaker Mixer */
-	0x0000,     /* R55  - Additional Control */
-	0x0000,     /* R56  - AntiPOP1 */
-	0x0000,     /* R57  - AntiPOP2 */
-	0x0000,     /* R58  - MICBIAS */
-	0x0000,     /* R59 */
-	0x0000,     /* R60  - FLL Control 1 */
-	0x0000,     /* R61  - FLL Control 2 */
-	0x0000,     /* R62  - FLL Control 3 */
-	0x2EE0,     /* R63  - FLL Control 4 */
-	0x0002,     /* R64  - FLL Control 5 */
-	0x2287,     /* R65  - Clocking 3 */
-	0x025F,     /* R66  - Clocking 4 */
-	0x0000,     /* R67  - MW Slave Control */
-	0x0000,     /* R68 */
-	0x0002,     /* R69  - Bus Control 1 */
-	0x0000,     /* R70  - Write Sequencer 0 */
-	0x0000,     /* R71  - Write Sequencer 1 */
-	0x0000,     /* R72  - Write Sequencer 2 */
-	0x0000,     /* R73  - Write Sequencer 3 */
-	0x0000,     /* R74  - Write Sequencer 4 */
-	0x0000,     /* R75  - Write Sequencer 5 */
-	0x1F25,     /* R76  - Charge Pump 1 */
-	0x0000,     /* R77 */
-	0x0000,     /* R78 */
-	0x0000,     /* R79 */
-	0x0000,     /* R80 */
-	0x0000,     /* R81  - Class W 0 */
-	0x0000,     /* R82 */
-	0x0000,     /* R83 */
-	0x0000,     /* R84  - DC Servo 0 */
-	0x054A,     /* R85  - DC Servo 1 */
-	0x0000,     /* R86 */
-	0x0000,     /* R87  - DC Servo 3 */
-	0x0000,     /* R88  - DC Servo Readback 0 */
-	0x0000,     /* R89  - DC Servo Readback 1 */
-	0x0000,     /* R90  - DC Servo Readback 2 */
-	0x0000,     /* R91 */
-	0x0000,     /* R92 */
-	0x0000,     /* R93 */
-	0x0000,     /* R94 */
-	0x0000,     /* R95 */
-	0x0100,     /* R96  - Analogue HP 0 */
-	0x0000,     /* R97 */
-	0x0000,     /* R98  - EQ1 */
-	0x000C,     /* R99  - EQ2 */
-	0x000C,     /* R100 - EQ3 */
-	0x000C,     /* R101 - EQ4 */
-	0x000C,     /* R102 - EQ5 */
-	0x000C,     /* R103 - EQ6 */
-	0x0FCA,     /* R104 - EQ7 */
-	0x0400,     /* R105 - EQ8 */
-	0x00D8,     /* R106 - EQ9 */
-	0x1EB5,     /* R107 - EQ10 */
-	0xF145,     /* R108 - EQ11 */
-	0x0B75,     /* R109 - EQ12 */
-	0x01C5,     /* R110 - EQ13 */
-	0x1C58,     /* R111 - EQ14 */
-	0xF373,     /* R112 - EQ15 */
-	0x0A54,     /* R113 - EQ16 */
-	0x0558,     /* R114 - EQ17 */
-	0x168E,     /* R115 - EQ18 */
-	0xF829,     /* R116 - EQ19 */
-	0x07AD,     /* R117 - EQ20 */
-	0x1103,     /* R118 - EQ21 */
-	0x0564,     /* R119 - EQ22 */
-	0x0559,     /* R120 - EQ23 */
-	0x4000,     /* R121 - EQ24 */
-	0x0000,     /* R122 - Digital Pulls */
-	0x0F08,     /* R123 - DRC Control 1 */
-	0x0000,     /* R124 - DRC Control 2 */
-	0x0080,     /* R125 - DRC Control 3 */
-	0x0000,     /* R126 - DRC Control 4 */
+static struct reg_default wm8993_reg_defaults[] = {
+	{ 1,   0x0000 },     /* R1   - Power Management (1) */
+	{ 2,   0x6000 },     /* R2   - Power Management (2) */
+	{ 3,   0x0000 },     /* R3   - Power Management (3) */
+	{ 4,   0x4050 },     /* R4   - Audio Interface (1) */
+	{ 5,   0x4000 },     /* R5   - Audio Interface (2) */
+	{ 6,   0x01C8 },     /* R6   - Clocking 1 */
+	{ 7,   0x0000 },     /* R7   - Clocking 2 */
+	{ 8,   0x0000 },     /* R8   - Audio Interface (3) */
+	{ 9,   0x0040 },     /* R9   - Audio Interface (4) */
+	{ 10,  0x0004 },     /* R10  - DAC CTRL */
+	{ 11,  0x00C0 },     /* R11  - Left DAC Digital Volume */
+	{ 12,  0x00C0 },     /* R12  - Right DAC Digital Volume */
+	{ 13,  0x0000 },     /* R13  - Digital Side Tone */
+	{ 14,  0x0300 },     /* R14  - ADC CTRL */
+	{ 15,  0x00C0 },     /* R15  - Left ADC Digital Volume */
+	{ 16,  0x00C0 },     /* R16  - Right ADC Digital Volume */
+	{ 18,  0x0000 },     /* R18  - GPIO CTRL 1 */
+	{ 19,  0x0010 },     /* R19  - GPIO1 */
+	{ 20,  0x0000 },     /* R20  - IRQ_DEBOUNCE */
+	{ 21,  0x0000 },     /* R21  - Inputs Clamp */
+	{ 22,  0x8000 },     /* R22  - GPIOCTRL 2 */
+	{ 23,  0x0800 },     /* R23  - GPIO_POL */
+	{ 24,  0x008B },     /* R24  - Left Line Input 1&2 Volume */
+	{ 25,  0x008B },     /* R25  - Left Line Input 3&4 Volume */
+	{ 26,  0x008B },     /* R26  - Right Line Input 1&2 Volume */
+	{ 27,  0x008B },     /* R27  - Right Line Input 3&4 Volume */
+	{ 28,  0x006D },     /* R28  - Left Output Volume */
+	{ 29,  0x006D },     /* R29  - Right Output Volume */
+	{ 30,  0x0066 },     /* R30  - Line Outputs Volume */
+	{ 31,  0x0020 },     /* R31  - HPOUT2 Volume */
+	{ 32,  0x0079 },     /* R32  - Left OPGA Volume */
+	{ 33,  0x0079 },     /* R33  - Right OPGA Volume */
+	{ 34,  0x0003 },     /* R34  - SPKMIXL Attenuation */
+	{ 35,  0x0003 },     /* R35  - SPKMIXR Attenuation */
+	{ 36,  0x0011 },     /* R36  - SPKOUT Mixers */
+	{ 37,  0x0100 },     /* R37  - SPKOUT Boost */
+	{ 38,  0x0079 },     /* R38  - Speaker Volume Left */
+	{ 39,  0x0079 },     /* R39  - Speaker Volume Right */
+	{ 40,  0x0000 },     /* R40  - Input Mixer2 */
+	{ 41,  0x0000 },     /* R41  - Input Mixer3 */
+	{ 42,  0x0000 },     /* R42  - Input Mixer4 */
+	{ 43,  0x0000 },     /* R43  - Input Mixer5 */
+	{ 44,  0x0000 },     /* R44  - Input Mixer6 */
+	{ 45,  0x0000 },     /* R45  - Output Mixer1 */
+	{ 46,  0x0000 },     /* R46  - Output Mixer2 */
+	{ 47,  0x0000 },     /* R47  - Output Mixer3 */
+	{ 48,  0x0000 },     /* R48  - Output Mixer4 */
+	{ 49,  0x0000 },     /* R49  - Output Mixer5 */
+	{ 50,  0x0000 },     /* R50  - Output Mixer6 */
+	{ 51,  0x0000 },     /* R51  - HPOUT2 Mixer */
+	{ 52,  0x0000 },     /* R52  - Line Mixer1 */
+	{ 53,  0x0000 },     /* R53  - Line Mixer2 */
+	{ 54,  0x0000 },     /* R54  - Speaker Mixer */
+	{ 55,  0x0000 },     /* R55  - Additional Control */
+	{ 56,  0x0000 },     /* R56  - AntiPOP1 */
+	{ 57,  0x0000 },     /* R57  - AntiPOP2 */
+	{ 58,  0x0000 },     /* R58  - MICBIAS */
+	{ 60,  0x0000 },     /* R60  - FLL Control 1 */
+	{ 61,  0x0000 },     /* R61  - FLL Control 2 */
+	{ 62,  0x0000 },     /* R62  - FLL Control 3 */
+	{ 63,  0x2EE0 },     /* R63  - FLL Control 4 */
+	{ 64,  0x0002 },     /* R64  - FLL Control 5 */
+	{ 65,  0x2287 },     /* R65  - Clocking 3 */
+	{ 66,  0x025F },     /* R66  - Clocking 4 */
+	{ 67,  0x0000 },     /* R67  - MW Slave Control */
+	{ 69,  0x0002 },     /* R69  - Bus Control 1 */
+	{ 70,  0x0000 },     /* R70  - Write Sequencer 0 */
+	{ 71,  0x0000 },     /* R71  - Write Sequencer 1 */
+	{ 72,  0x0000 },     /* R72  - Write Sequencer 2 */
+	{ 73,  0x0000 },     /* R73  - Write Sequencer 3 */
+	{ 74,  0x0000 },     /* R74  - Write Sequencer 4 */
+	{ 75,  0x0000 },     /* R75  - Write Sequencer 5 */
+	{ 76,  0x1F25 },     /* R76  - Charge Pump 1 */
+	{ 81,  0x0000 },     /* R81  - Class W 0 */
+	{ 85,  0x054A },     /* R85  - DC Servo 1 */
+	{ 87,  0x0000 },     /* R87  - DC Servo 3 */
+	{ 96,  0x0100 },     /* R96  - Analogue HP 0 */
+	{ 98,  0x0000 },     /* R98  - EQ1 */
+	{ 99,  0x000C },     /* R99  - EQ2 */
+	{ 100, 0x000C },     /* R100 - EQ3 */
+	{ 101, 0x000C },     /* R101 - EQ4 */
+	{ 102, 0x000C },     /* R102 - EQ5 */
+	{ 103, 0x000C },     /* R103 - EQ6 */
+	{ 104, 0x0FCA },     /* R104 - EQ7 */
+	{ 105, 0x0400 },     /* R105 - EQ8 */
+	{ 106, 0x00D8 },     /* R106 - EQ9 */
+	{ 107, 0x1EB5 },     /* R107 - EQ10 */
+	{ 108, 0xF145 },     /* R108 - EQ11 */
+	{ 109, 0x0B75 },     /* R109 - EQ12 */
+	{ 110, 0x01C5 },     /* R110 - EQ13 */
+	{ 111, 0x1C58 },     /* R111 - EQ14 */
+	{ 112, 0xF373 },     /* R112 - EQ15 */
+	{ 113, 0x0A54 },     /* R113 - EQ16 */
+	{ 114, 0x0558 },     /* R114 - EQ17 */
+	{ 115, 0x168E },     /* R115 - EQ18 */
+	{ 116, 0xF829 },     /* R116 - EQ19 */
+	{ 117, 0x07AD },     /* R117 - EQ20 */
+	{ 118, 0x1103 },     /* R118 - EQ21 */
+	{ 119, 0x0564 },     /* R119 - EQ22 */
+	{ 120, 0x0559 },     /* R120 - EQ23 */
+	{ 121, 0x4000 },     /* R121 - EQ24 */
+	{ 122, 0x0000 },     /* R122 - Digital Pulls */
+	{ 123, 0x0F08 },     /* R123 - DRC Control 1 */
+	{ 124, 0x0000 },     /* R124 - DRC Control 2 */
+	{ 125, 0x0080 },     /* R125 - DRC Control 3 */
+	{ 126, 0x0000 },     /* R126 - DRC Control 4 */
 };
 
 static struct {
@@ -225,9 +205,11 @@ static struct {
 
 struct wm8993_priv {
 	struct wm_hubs_data hubs_data;
+	struct device *dev;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
 	struct wm8993_platform_data pdata;
-	enum snd_soc_control_type control_type;
+	struct completion fll_lock;
 	int master;
 	int sysclk_source;
 	int tdm_slots;
@@ -242,17 +224,137 @@ struct wm8993_priv {
 	int fll_src;
 };
 
-static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8993_volatile(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM8993_SOFTWARE_RESET:
+	case WM8993_GPIO_CTRL_1:
 	case WM8993_DC_SERVO_0:
 	case WM8993_DC_SERVO_READBACK_0:
 	case WM8993_DC_SERVO_READBACK_1:
 	case WM8993_DC_SERVO_READBACK_2:
-		return 1;
+		return true;
 	default:
-		return 0;
+		return false;
+	}
+}
+
+static bool wm8993_readable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8993_SOFTWARE_RESET:
+	case WM8993_POWER_MANAGEMENT_1:
+	case WM8993_POWER_MANAGEMENT_2:
+	case WM8993_POWER_MANAGEMENT_3:
+	case WM8993_AUDIO_INTERFACE_1:
+	case WM8993_AUDIO_INTERFACE_2:
+	case WM8993_CLOCKING_1:
+	case WM8993_CLOCKING_2:
+	case WM8993_AUDIO_INTERFACE_3:
+	case WM8993_AUDIO_INTERFACE_4:
+	case WM8993_DAC_CTRL:
+	case WM8993_LEFT_DAC_DIGITAL_VOLUME:
+	case WM8993_RIGHT_DAC_DIGITAL_VOLUME:
+	case WM8993_DIGITAL_SIDE_TONE:
+	case WM8993_ADC_CTRL:
+	case WM8993_LEFT_ADC_DIGITAL_VOLUME:
+	case WM8993_RIGHT_ADC_DIGITAL_VOLUME:
+	case WM8993_GPIO_CTRL_1:
+	case WM8993_GPIO1:
+	case WM8993_IRQ_DEBOUNCE:
+	case WM8993_GPIOCTRL_2:
+	case WM8993_GPIO_POL:
+	case WM8993_LEFT_LINE_INPUT_1_2_VOLUME:
+	case WM8993_LEFT_LINE_INPUT_3_4_VOLUME:
+	case WM8993_RIGHT_LINE_INPUT_1_2_VOLUME:
+	case WM8993_RIGHT_LINE_INPUT_3_4_VOLUME:
+	case WM8993_LEFT_OUTPUT_VOLUME:
+	case WM8993_RIGHT_OUTPUT_VOLUME:
+	case WM8993_LINE_OUTPUTS_VOLUME:
+	case WM8993_HPOUT2_VOLUME:
+	case WM8993_LEFT_OPGA_VOLUME:
+	case WM8993_RIGHT_OPGA_VOLUME:
+	case WM8993_SPKMIXL_ATTENUATION:
+	case WM8993_SPKMIXR_ATTENUATION:
+	case WM8993_SPKOUT_MIXERS:
+	case WM8993_SPKOUT_BOOST:
+	case WM8993_SPEAKER_VOLUME_LEFT:
+	case WM8993_SPEAKER_VOLUME_RIGHT:
+	case WM8993_INPUT_MIXER2:
+	case WM8993_INPUT_MIXER3:
+	case WM8993_INPUT_MIXER4:
+	case WM8993_INPUT_MIXER5:
+	case WM8993_INPUT_MIXER6:
+	case WM8993_OUTPUT_MIXER1:
+	case WM8993_OUTPUT_MIXER2:
+	case WM8993_OUTPUT_MIXER3:
+	case WM8993_OUTPUT_MIXER4:
+	case WM8993_OUTPUT_MIXER5:
+	case WM8993_OUTPUT_MIXER6:
+	case WM8993_HPOUT2_MIXER:
+	case WM8993_LINE_MIXER1:
+	case WM8993_LINE_MIXER2:
+	case WM8993_SPEAKER_MIXER:
+	case WM8993_ADDITIONAL_CONTROL:
+	case WM8993_ANTIPOP1:
+	case WM8993_ANTIPOP2:
+	case WM8993_MICBIAS:
+	case WM8993_FLL_CONTROL_1:
+	case WM8993_FLL_CONTROL_2:
+	case WM8993_FLL_CONTROL_3:
+	case WM8993_FLL_CONTROL_4:
+	case WM8993_FLL_CONTROL_5:
+	case WM8993_CLOCKING_3:
+	case WM8993_CLOCKING_4:
+	case WM8993_MW_SLAVE_CONTROL:
+	case WM8993_BUS_CONTROL_1:
+	case WM8993_WRITE_SEQUENCER_0:
+	case WM8993_WRITE_SEQUENCER_1:
+	case WM8993_WRITE_SEQUENCER_2:
+	case WM8993_WRITE_SEQUENCER_3:
+	case WM8993_WRITE_SEQUENCER_4:
+	case WM8993_WRITE_SEQUENCER_5:
+	case WM8993_CHARGE_PUMP_1:
+	case WM8993_CLASS_W_0:
+	case WM8993_DC_SERVO_0:
+	case WM8993_DC_SERVO_1:
+	case WM8993_DC_SERVO_3:
+	case WM8993_DC_SERVO_READBACK_0:
+	case WM8993_DC_SERVO_READBACK_1:
+	case WM8993_DC_SERVO_READBACK_2:
+	case WM8993_ANALOGUE_HP_0:
+	case WM8993_EQ1:
+	case WM8993_EQ2:
+	case WM8993_EQ3:
+	case WM8993_EQ4:
+	case WM8993_EQ5:
+	case WM8993_EQ6:
+	case WM8993_EQ7:
+	case WM8993_EQ8:
+	case WM8993_EQ9:
+	case WM8993_EQ10:
+	case WM8993_EQ11:
+	case WM8993_EQ12:
+	case WM8993_EQ13:
+	case WM8993_EQ14:
+	case WM8993_EQ15:
+	case WM8993_EQ16:
+	case WM8993_EQ17:
+	case WM8993_EQ18:
+	case WM8993_EQ19:
+	case WM8993_EQ20:
+	case WM8993_EQ21:
+	case WM8993_EQ22:
+	case WM8993_EQ23:
+	case WM8993_EQ24:
+	case WM8993_DIGITAL_PULLS:
+	case WM8993_DRC_CONTROL_1:
+	case WM8993_DRC_CONTROL_2:
+	case WM8993_DRC_CONTROL_3:
+	case WM8993_DRC_CONTROL_4:
+		return true;
+	default:
+		return false;
 	}
 }
 
@@ -369,8 +471,10 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 			  unsigned int Fref, unsigned int Fout)
 {
 	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
+	struct i2c_client *i2c = to_i2c_client(codec->dev);
 	u16 reg1, reg4, reg5;
 	struct _fll_div fll_div;
+	unsigned int timeout;
 	int ret;
 
 	/* Any change? */
@@ -441,14 +545,22 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
 	reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
 	snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
 
+	/* If we've got an interrupt wired up make sure we get it */
+	if (i2c->irq)
+		timeout = msecs_to_jiffies(20);
+	else if (Fref < 1000000)
+		timeout = msecs_to_jiffies(3);
+	else
+		timeout = msecs_to_jiffies(1);
+
+	try_wait_for_completion(&wm8993->fll_lock);
+
 	/* Enable the FLL */
 	snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
 
-	/* Both overestimates */
-	if (Fref < 1000000)
-		msleep(3);
-	else
-		msleep(1);
+	timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout);
+	if (i2c->irq && !timeout)
+		dev_warn(codec->dev, "Timed out waiting for FLL\n");
 
 	dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
 
@@ -946,6 +1058,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
 	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
+	wm_hubs_set_bias_level(codec, level);
+
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_PREPARE:
@@ -963,12 +1077,10 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
 			if (ret != 0)
 				return ret;
 
-			snd_soc_cache_sync(codec);
+			regcache_cache_only(wm8993->regmap, false);
+			regcache_sync(wm8993->regmap);
 
-			/* Tune DC servo configuration */
-			snd_soc_write(codec, 0x44, 3);
-			snd_soc_write(codec, 0x56, 3);
-			snd_soc_write(codec, 0x44, 0);
+			wm_hubs_vmid_ena(codec);
 
 			/* Bring up VMID with fast soft start */
 			snd_soc_update_bits(codec, WM8993_ANTIPOP2,
@@ -1024,14 +1136,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
 				    WM8993_VMID_RAMP_MASK |
 				    WM8993_BIAS_SRC, 0);
 
-#ifdef CONFIG_REGULATOR
-               /* Post 2.6.34 we will be able to get a callback when
-                * the regulators are disabled which we can use but
-		* for now just assume that the power will be cut if
-		* the regulator API is in use.
-		*/
-		codec->cache_sync = 1;
-#endif
+		regcache_cache_only(wm8993->regmap, true);
+		regcache_mark_dirty(wm8993->regmap);
 
 		regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
 				       wm8993->supplies);
@@ -1378,6 +1484,45 @@ out:
 	return 0;
 }
 
+static irqreturn_t wm8993_irq(int irq, void *data)
+{
+	struct wm8993_priv *wm8993 = data;
+	int mask, val, ret;
+
+	ret = regmap_read(wm8993->regmap, WM8993_GPIO_CTRL_1, &val);
+	if (ret != 0) {
+		dev_err(wm8993->dev, "Failed to read interrupt status: %d\n",
+			ret);
+		return IRQ_NONE;
+	}
+
+	ret = regmap_read(wm8993->regmap, WM8993_GPIOCTRL_2, &mask);
+	if (ret != 0) {
+		dev_err(wm8993->dev, "Failed to read interrupt mask: %d\n",
+			ret);
+		return IRQ_NONE;
+	}
+
+	/* The IRQ pin status is visible in the register too */
+	val &= ~(mask | WM8993_IRQ);
+	if (!val)
+		return IRQ_NONE;
+
+	if (val & WM8993_TEMPOK_EINT)
+		dev_crit(wm8993->dev, "Thermal warning\n");
+
+	if (val & WM8993_FLL_LOCK_EINT) {
+		dev_dbg(wm8993->dev, "FLL locked\n");
+		complete(&wm8993->fll_lock);
+	}
+
+	ret = regmap_write(wm8993->regmap, WM8993_GPIO_CTRL_1, val);
+	if (ret != 0)
+		dev_err(wm8993->dev, "Failed to ack interrupt: %d\n", ret);
+
+	return IRQ_HANDLED;
+}
+
 static const struct snd_soc_dai_ops wm8993_ops = {
 	.set_sysclk = wm8993_set_sysclk,
 	.set_fmt = wm8993_set_dai_fmt,
@@ -1402,6 +1547,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
 		.channels_max = 2,
 		.rates = WM8993_RATES,
 		.formats = WM8993_FORMATS,
+		.sig_bits = 24,
 	},
 	.capture = {
 		 .stream_name = "Capture",
@@ -1409,6 +1555,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
 		 .channels_max = 2,
 		 .rates = WM8993_RATES,
 		 .formats = WM8993_FORMATS,
+		 .sig_bits = 24,
 	 },
 	.ops = &wm8993_ops,
 	.symmetric_rates = 1,
@@ -1418,49 +1565,20 @@ static int wm8993_probe(struct snd_soc_codec *codec)
 {
 	struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
-	int ret, i, val;
+	int ret;
 
 	wm8993->hubs_data.hp_startup_mode = 1;
 	wm8993->hubs_data.dcs_codes_l = -2;
 	wm8993->hubs_data.dcs_codes_r = -2;
 	wm8993->hubs_data.series_startup = 1;
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+	codec->control_data = wm8993->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
-		wm8993->supplies[i].supply = wm8993_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
-				 wm8993->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		return ret;
-	}
-
-	ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
-				    wm8993->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
-		goto err_get;
-	}
-
-	val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
-	if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
-		dev_err(codec->dev, "Invalid ID register value %x\n", val);
-		ret = -EINVAL;
-		goto err_enable;
-	}
-
-	ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
-	if (ret != 0)
-		goto err_enable;
-
-	codec->cache_only = 1;
-
 	/* By default we're using the output mixers */
 	wm8993->class_w_users = 2;
 
@@ -1489,15 +1607,15 @@ static int wm8993_probe(struct snd_soc_codec *codec)
 
 	ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	if (ret != 0)
-		goto err_enable;
+		return ret;
 
-	snd_soc_add_controls(codec, wm8993_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8993_snd_controls,
 			     ARRAY_SIZE(wm8993_snd_controls));
 	if (wm8993->pdata.num_retune_configs != 0) {
 		dev_dbg(codec->dev, "Using ReTune Mobile\n");
 	} else {
 		dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
-		snd_soc_add_controls(codec, wm8993_eq_controls,
+		snd_soc_add_codec_controls(codec, wm8993_eq_controls,
 				     ARRAY_SIZE(wm8993_eq_controls));
 	}
 
@@ -1509,13 +1627,14 @@ static int wm8993_probe(struct snd_soc_codec *codec)
 	wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
 				    wm8993->pdata.lineout2_diff);
 
+	/* If the line outputs are differential then we aren't presenting
+	 * VMID as an output and can disable it.
+	 */
+	if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff)
+		codec->dapm.idle_bias_off = 1;
+
 	return 0;
 
-err_enable:
-	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-err_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
-	return ret;
 }
 
 static int wm8993_remove(struct snd_soc_codec *codec)
@@ -1578,41 +1697,149 @@ static int wm8993_resume(struct snd_soc_codec *codec)
 #define wm8993_resume NULL
 #endif
 
+/* Tune DC servo configuration */
+static struct reg_default wm8993_regmap_patch[] = {
+	{ 0x44, 3 },
+	{ 0x56, 3 },
+	{ 0x44, 0 },
+};
+
+static const struct regmap_config wm8993_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+
+	.max_register = WM8993_MAX_REGISTER,
+	.volatile_reg = wm8993_volatile,
+	.readable_reg = wm8993_readable,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm8993_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults),
+};
+
 static struct snd_soc_codec_driver soc_codec_dev_wm8993 = {
 	.probe = 	wm8993_probe,
 	.remove = 	wm8993_remove,
 	.suspend =	wm8993_suspend,
 	.resume =	wm8993_resume,
 	.set_bias_level = wm8993_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8993_reg_defaults),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8993_reg_defaults,
-	.volatile_register = wm8993_volatile,
 };
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8993_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8993_priv *wm8993;
-	int ret;
+	unsigned int reg;
+	int ret, i;
 
 	wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv),
 			      GFP_KERNEL);
 	if (wm8993 == NULL)
 		return -ENOMEM;
 
+	wm8993->dev = &i2c->dev;
+	init_completion(&wm8993->fll_lock);
+
+	wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap);
+	if (IS_ERR(wm8993->regmap)) {
+		ret = PTR_ERR(wm8993->regmap);
+		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8993);
 
+	for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
+		wm8993->supplies[i].supply = wm8993_supply_names[i];
+
+	ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies),
+				 wm8993->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+		goto err;
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
+				    wm8993->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+		goto err_get;
+	}
+
+	ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, &reg);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
+		goto err_enable;
+	}
+
+	if (reg != 0x8993) {
+		dev_err(&i2c->dev, "Invalid ID register value %x\n", reg);
+		ret = -EINVAL;
+		goto err_enable;
+	}
+
+	ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff);
+	if (ret != 0)
+		goto err_enable;
+
+	ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch,
+				    ARRAY_SIZE(wm8993_regmap_patch));
+	if (ret != 0)
+		dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n",
+			 ret);
+
+	if (i2c->irq) {
+		/* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */
+		ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1,
+					 WM8993_GPIO1_PD |
+					 WM8993_GPIO1_SEL_MASK, 7);
+		if (ret != 0)
+			goto err_enable;
+
+		ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq,
+					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					   "wm8993", wm8993);
+		if (ret != 0)
+			goto err_enable;
+
+	}
+
+	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
+
+	regcache_cache_only(wm8993->regmap, true);
+
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8993, &wm8993_dai, 1);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+		goto err_irq;
+	}
+
+	return 0;
+
+err_irq:
+	if (i2c->irq)
+		free_irq(i2c->irq, wm8993);
+err_enable:
+	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
+err_get:
+	regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
+err:
+	regmap_exit(wm8993->regmap);
 	return ret;
 }
 
-static __devexit int wm8993_i2c_remove(struct i2c_client *client)
+static __devexit int wm8993_i2c_remove(struct i2c_client *i2c)
 {
-	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+	struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c);
+
+	snd_soc_unregister_codec(&i2c->dev);
+	if (i2c->irq)
+		free_irq(i2c->irq, wm8993);
+	regmap_exit(wm8993->regmap);
+	regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
+	regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
+
 	return 0;
 }
 
@@ -1631,30 +1858,8 @@ static struct i2c_driver wm8993_i2c_driver = {
 	.remove =   __devexit_p(wm8993_i2c_remove),
 	.id_table = wm8993_i2c_id,
 };
-#endif
-
-static int __init wm8993_modinit(void)
-{
-	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	ret = i2c_add_driver(&wm8993_i2c_driver);
-	if (ret != 0) {
-		pr_err("WM8993: Unable to register I2C driver: %d\n",
-		       ret);
-	}
-#endif
-	return ret;
-}
-module_init(wm8993_modinit);
-
-static void __exit wm8993_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	i2c_del_driver(&wm8993_i2c_driver);
-#endif
-}
-module_exit(wm8993_exit);
 
+module_i2c_driver(wm8993_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8993 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 2184617..4478b40 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -31,6 +31,7 @@
 #define WM8993_GPIO_CTRL_1                      0x12
 #define WM8993_GPIO1                            0x13
 #define WM8993_IRQ_DEBOUNCE                     0x14
+#define WM8993_INPUTS_CLAMP_REG			0x15
 #define WM8993_GPIOCTRL_2                       0x16
 #define WM8993_GPIO_POL                         0x17
 #define WM8993_LEFT_LINE_INPUT_1_2_VOLUME       0x18
@@ -656,6 +657,14 @@
 #define WM8993_GPIO1_DB_WIDTH                        1  /* GPIO1_DB */
 
 /*
+ * R21 (0x15) - Inputs Clamp
+ */
+#define WM8993_INPUTS_CLAMP                     0x0040  /* INPUTS_CLAMP */
+#define WM8993_INPUTS_CLAMP_MASK                0x0040  /* INPUTS_CLAMP */
+#define WM8993_INPUTS_CLAMP_SHIFT                    7  /* INPUTS_CLAMP */
+#define WM8993_INPUTS_CLAMP_WIDTH                    1  /* INPUTS_CLAMP */
+
+/*
  * R22 (0x16) - GPIOCTRL 2
  */
 #define WM8993_IM_JD2_EINT                      0x2000  /* IM_JD2_EINT */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index ec69a6c..6d17945 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -778,19 +778,25 @@ static void vmid_reference(struct snd_soc_codec *codec)
 		wm8994->vmid_refcount);
 
 	if (wm8994->vmid_refcount == 1) {
+		snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+				    WM8994_LINEOUT_VMID_BUF_ENA |
+				    WM8994_LINEOUT1_DISCH |
+				    WM8994_LINEOUT2_DISCH,
+				    WM8994_LINEOUT_VMID_BUF_ENA);
+
 		/* Startup bias, VMID ramp & buffer */
 		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+				    WM8994_BIAS_SRC |
+				    WM8994_VMID_DISCH |
 				    WM8994_STARTUP_BIAS_ENA |
 				    WM8994_VMID_BUF_ENA |
 				    WM8994_VMID_RAMP_MASK,
+				    WM8994_BIAS_SRC |
 				    WM8994_STARTUP_BIAS_ENA |
 				    WM8994_VMID_BUF_ENA |
-				    (0x3 << WM8994_VMID_RAMP_SHIFT));
+				    (0x2 << WM8994_VMID_RAMP_SHIFT));
 
-		/* Remove discharge for line out */
-		snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
-				    WM8994_LINEOUT1_DISCH |
-				    WM8994_LINEOUT2_DISCH, 0);
+		wm_hubs_vmid_ena(codec);
 
 		/* Main bias enable, VMID=2x40k */
 		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
@@ -798,7 +804,11 @@ static void vmid_reference(struct snd_soc_codec *codec)
 				    WM8994_VMID_SEL_MASK,
 				    WM8994_BIAS_ENA | 0x2);
 
-		msleep(20);
+		msleep(50);
+
+		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+				    WM8994_VMID_RAMP_MASK | WM8994_BIAS_SRC,
+				    0);
 	}
 }
 
@@ -828,6 +838,10 @@ static void vmid_dereference(struct snd_soc_codec *codec)
 				    WM8994_BIAS_ENA |
 				    WM8994_VMID_SEL_MASK, 0);
 
+		/* Discharge VMID */
+		snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+				    WM8994_VMID_DISCH, WM8994_VMID_DISCH);
+
 		/* Discharge line */
 		snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
 				    WM8994_LINEOUT1_DISCH |
@@ -1459,17 +1473,17 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
 		      WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
-SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_IN("AIF2DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT",  NULL, 0, SND_SOC_NOPM, 0, 0),
 
 SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
 SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
 SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
 
-SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_IN("AIF3DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0),
 
 SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
 
@@ -1584,6 +1598,14 @@ static const struct snd_soc_dapm_route intercon[] = {
 
 	{ "TOCLK", NULL, "CLK_SYS" },
 
+	{ "AIF1DACDAT", NULL, "AIF1 Playback" },
+	{ "AIF2DACDAT", NULL, "AIF2 Playback" },
+	{ "AIF3DACDAT", NULL, "AIF3 Playback" },
+
+	{ "AIF1 Capture", NULL, "AIF1ADCDAT" },
+	{ "AIF2 Capture", NULL, "AIF2ADCDAT" },
+	{ "AIF3 Capture", NULL, "AIF3ADCDAT" },
+
 	/* AIF1 outputs */
 	{ "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
 	{ "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
@@ -2074,6 +2096,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994 *control = wm8994->wm8994;
 
+	wm_hubs_set_bias_level(codec, level);
+
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -2099,26 +2123,9 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 			switch (control->type) {
-			case WM8994:
-				if (wm8994->revision < 4) {
-					/* Tweak DC servo and DSP
-					 * configuration for improved
-					 * performance. */
-					snd_soc_write(codec, 0x102, 0x3);
-					snd_soc_write(codec, 0x56, 0x3);
-					snd_soc_write(codec, 0x817, 0);
-					snd_soc_write(codec, 0x102, 0);
-				}
-				break;
-
 			case WM8958:
 				if (wm8994->revision == 0) {
 					/* Optimise performance for rev A */
-					snd_soc_write(codec, 0x102, 0x3);
-					snd_soc_write(codec, 0xcb, 0x81);
-					snd_soc_write(codec, 0x817, 0);
-					snd_soc_write(codec, 0x102, 0);
-
 					snd_soc_update_bits(codec,
 							    WM8958_CHARGE_PUMP_2,
 							    WM8958_CP_DISCH,
@@ -2126,13 +2133,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 				}
 				break;
 
-			case WM1811:
-				if (wm8994->revision < 2) {
-					snd_soc_write(codec, 0x102, 0x3);
-					snd_soc_write(codec, 0x5d, 0x7e);
-					snd_soc_write(codec, 0x5e, 0x0);
-					snd_soc_write(codec, 0x102, 0x0);
-				}
+			default:
 				break;
 			}
 
@@ -2168,6 +2169,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
 			wm8994->cur_fw = NULL;
 		break;
 	}
+
 	codec->dapm.bias_level = level;
 
 	return 0;
@@ -2654,6 +2656,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 			.channels_max = 2,
 			.rates = WM8994_RATES,
 			.formats = WM8994_FORMATS,
+			.sig_bits = 24,
 		},
 		.capture = {
 			.stream_name = "AIF1 Capture",
@@ -2661,6 +2664,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 			.channels_max = 2,
 			.rates = WM8994_RATES,
 			.formats = WM8994_FORMATS,
+			.sig_bits = 24,
 		 },
 		.ops = &wm8994_aif1_dai_ops,
 	},
@@ -2673,6 +2677,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 			.channels_max = 2,
 			.rates = WM8994_RATES,
 			.formats = WM8994_FORMATS,
+			.sig_bits = 24,
 		},
 		.capture = {
 			.stream_name = "AIF2 Capture",
@@ -2680,6 +2685,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 			.channels_max = 2,
 			.rates = WM8994_RATES,
 			.formats = WM8994_FORMATS,
+			.sig_bits = 24,
 		},
 		.probe = wm8994_aif2_probe,
 		.ops = &wm8994_aif2_dai_ops,
@@ -2693,6 +2699,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 			.channels_max = 2,
 			.rates = WM8994_RATES,
 			.formats = WM8994_FORMATS,
+			.sig_bits = 24,
 		},
 		.capture = {
 			.stream_name = "AIF3 Capture",
@@ -2700,7 +2707,8 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 			.channels_max = 2,
 			.rates = WM8994_RATES,
 			.formats = WM8994_FORMATS,
-		},
+			.sig_bits = 24,
+		 },
 		.ops = &wm8994_aif3_dai_ops,
 	}
 };
@@ -2762,8 +2770,6 @@ static int wm8994_resume(struct snd_soc_codec *codec)
 		codec->cache_only = 0;
 	}
 
-	wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
 		if (!wm8994->fll_suspend[i].out)
 			continue;
@@ -2865,7 +2871,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
 	wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
 	wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
 
-	ret = snd_soc_add_controls(wm8994->codec, controls,
+	ret = snd_soc_add_codec_controls(wm8994->codec, controls,
 				   ARRAY_SIZE(controls));
 	if (ret != 0)
 		dev_err(wm8994->codec->dev,
@@ -2918,7 +2924,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 		wm8994->drc_enum.max = pdata->num_drc_cfgs;
 		wm8994->drc_enum.texts = wm8994->drc_texts;
 
-		ret = snd_soc_add_controls(wm8994->codec, controls,
+		ret = snd_soc_add_codec_controls(wm8994->codec, controls,
 					   ARRAY_SIZE(controls));
 		if (ret != 0)
 			dev_err(wm8994->codec->dev,
@@ -2934,7 +2940,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 	if (pdata->num_retune_mobile_cfgs)
 		wm8994_handle_retune_mobile_pdata(wm8994);
 	else
-		snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
+		snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
 				     ARRAY_SIZE(wm8994_eq_controls));
 
 	for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -2951,8 +2957,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
  * @codec:   WM8994 codec
  * @jack:    jack to report detection events on
  * @micbias: microphone bias to detect on
- * @det:     value to report for presence detection
- * @shrt:    value to report for short detection
  *
  * Enable microphone detection via IRQ on the WM8994.  If GPIOs are
  * being used to bring out signals to the processor then only platform
@@ -2963,43 +2967,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
  * and micbias2_lvl platform data members.
  */
 int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
-		      int micbias, int det, int shrt)
+		      int micbias)
 {
 	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 	struct wm8994_micdet *micdet;
 	struct wm8994 *control = wm8994->wm8994;
-	int reg;
+	int reg, ret;
 
-	if (control->type != WM8994)
+	if (control->type != WM8994) {
+		dev_warn(codec->dev, "Not a WM8994\n");
 		return -EINVAL;
+	}
 
 	switch (micbias) {
 	case 1:
 		micdet = &wm8994->micdet[0];
+		if (jack)
+			ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
+							    "MICBIAS1");
+		else
+			ret = snd_soc_dapm_disable_pin(&codec->dapm,
+						       "MICBIAS1");
 		break;
 	case 2:
 		micdet = &wm8994->micdet[1];
+		if (jack)
+			ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
+							    "MICBIAS1");
+		else
+			ret = snd_soc_dapm_disable_pin(&codec->dapm,
+						       "MICBIAS1");
 		break;
 	default:
+		dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias);
 		return -EINVAL;
-	}	
+	}
 
-	dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n",
-		micbias, det, shrt);
+	if (ret != 0)
+		dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n",
+			 micbias, ret);
+
+	dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n",
+		micbias, jack);
 
 	/* Store the configuration */
 	micdet->jack = jack;
-	micdet->det = det;
-	micdet->shrt = shrt;
+	micdet->detecting = true;
 
 	/* If either of the jacks is set up then enable detection */
 	if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
 		reg = WM8994_MICD_ENA;
-	else 
+	else
 		reg = 0;
 
 	snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
 
+	snd_soc_dapm_sync(&codec->dapm);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(wm8994_mic_detect);
@@ -3025,20 +3049,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
 	dev_dbg(codec->dev, "Microphone status: %x\n", reg);
 
 	report = 0;
-	if (reg & WM8994_MIC1_DET_STS)
-		report |= priv->micdet[0].det;
-	if (reg & WM8994_MIC1_SHRT_STS)
-		report |= priv->micdet[0].shrt;
+	if (reg & WM8994_MIC1_DET_STS) {
+		if (priv->micdet[0].detecting)
+			report = SND_JACK_HEADSET;
+	}
+	if (reg & WM8994_MIC1_SHRT_STS) {
+		if (priv->micdet[0].detecting)
+			report = SND_JACK_HEADPHONE;
+		else
+			report |= SND_JACK_BTN_0;
+	}
+	if (report)
+		priv->micdet[0].detecting = false;
+	else
+		priv->micdet[0].detecting = true;
+
 	snd_soc_jack_report(priv->micdet[0].jack, report,
-			    priv->micdet[0].det | priv->micdet[0].shrt);
+			    SND_JACK_HEADSET | SND_JACK_BTN_0);
 
 	report = 0;
-	if (reg & WM8994_MIC2_DET_STS)
-		report |= priv->micdet[1].det;
-	if (reg & WM8994_MIC2_SHRT_STS)
-		report |= priv->micdet[1].shrt;
+	if (reg & WM8994_MIC2_DET_STS) {
+		if (priv->micdet[1].detecting)
+			report = SND_JACK_HEADSET;
+	}
+	if (reg & WM8994_MIC2_SHRT_STS) {
+		if (priv->micdet[1].detecting)
+			report = SND_JACK_HEADPHONE;
+		else
+			report |= SND_JACK_BTN_0;
+	}
+	if (report)
+		priv->micdet[1].detecting = false;
+	else
+		priv->micdet[1].detecting = true;
+
 	snd_soc_jack_report(priv->micdet[1].jack, report,
-			    priv->micdet[1].det | priv->micdet[1].shrt);
+			    SND_JACK_HEADSET | SND_JACK_BTN_0);
 
 	return IRQ_HANDLED;
 }
@@ -3087,7 +3133,7 @@ static void wm8958_default_micdet(u16 status, void *data)
 	}
 
 
-	if (wm8994->mic_detecting && status & 0x4) {
+	if (wm8994->mic_detecting && status & 0xfc) {
 		dev_dbg(codec->dev, "Detected headphone\n");
 		wm8994->mic_detecting = false;
 
@@ -3103,6 +3149,14 @@ static void wm8958_default_micdet(u16 status, void *data)
 
 			wm1811_jackdet_set_mode(codec,
 						WM1811_JACKDET_MODE_JACK);
+
+			if (wm8994->pdata->jd_ext_cap) {
+				mutex_lock(&codec->mutex);
+				snd_soc_dapm_disable_pin(&codec->dapm,
+							 "MICBIAS2");
+				snd_soc_dapm_sync(&codec->dapm);
+				mutex_unlock(&codec->mutex);
+			}
 		}
 	}
 
@@ -3155,6 +3209,18 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 		snd_soc_jack_report(wm8994->micdet[0].jack,
 				    SND_JACK_MECHANICAL, SND_JACK_MECHANICAL);
 
+		snd_soc_update_bits(codec, WM8958_MICBIAS2,
+				    WM8958_MICB2_DISCH, 0);
+
+		/* If required for an external cap force MICBIAS on */
+		if (wm8994->pdata->jd_ext_cap) {
+			mutex_lock(&codec->mutex);
+			snd_soc_dapm_force_enable_pin(&codec->dapm,
+						      "MICBIAS2");
+			snd_soc_dapm_sync(&codec->dapm);
+			mutex_unlock(&codec->mutex);
+		}
+
 		/*
 		 * Start off measument of microphone impedence to find
 		 * out what's actually there.
@@ -3166,6 +3232,16 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 	} else {
 		dev_dbg(codec->dev, "Jack not detected\n");
 
+		snd_soc_update_bits(codec, WM8958_MICBIAS2,
+				    WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
+
+		if (wm8994->pdata->jd_ext_cap) {
+			mutex_lock(&codec->mutex);
+			snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
+			snd_soc_dapm_sync(&codec->dapm);
+			mutex_unlock(&codec->mutex);
+		}
+
 		snd_soc_jack_report(wm8994->micdet[0].jack, 0,
 				    SND_JACK_MECHANICAL | SND_JACK_HEADSET |
 				    wm8994->btn_mask);
@@ -3251,6 +3327,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 		 * otherwise jump straight to microphone detection.
 		 */
 		if (wm8994->jackdet) {
+			snd_soc_update_bits(codec, WM8958_MICBIAS2,
+					    WM8958_MICB2_DISCH,
+					    WM8958_MICB2_DISCH);
 			snd_soc_update_bits(codec, WM8994_LDO_1,
 					    WM8994_LDO1_DISCH, 0);
 			wm1811_jackdet_set_mode(codec,
@@ -3392,12 +3471,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 				     WM8994_IRQ_MIC1_DET;
 
 	pm_runtime_enable(codec->dev);
-	pm_runtime_resume(codec->dev);
+	pm_runtime_idle(codec->dev);
+
+	/* By default use idle_bias_off, will override for WM8994 */
+	codec->dapm.idle_bias_off = 1;
 
 	/* Set revision-specific configuration */
 	wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
 	switch (control->type) {
 	case WM8994:
+		/* Single ended line outputs should have VMID on. */
+		if (!wm8994->pdata->lineout1_diff ||
+		    !wm8994->pdata->lineout2_diff)
+			codec->dapm.idle_bias_off = 0;
+
 		switch (wm8994->revision) {
 		case 2:
 		case 3:
@@ -3415,11 +3502,13 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 
 	case WM8958:
 		wm8994->hubs.dcs_readback_mode = 1;
+		wm8994->hubs.hp_startup_mode = 1;
 		break;
 
 	case WM1811:
 		wm8994->hubs.dcs_readback_mode = 2;
 		wm8994->hubs.no_series_update = 1;
+		wm8994->hubs.hp_startup_mode = 1;
 
 		switch (wm8994->revision) {
 		case 0:
@@ -3536,6 +3625,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 			wm8994->fll_locked_irq = false;
 	}
 
+	/* Make sure we can read from the GPIOs if they're inputs */
+	pm_runtime_get_sync(codec->dev);
+
 	/* Remember if AIFnLRCLK is configured as a GPIO.  This should be
 	 * configured on init - if a system wants to do this dynamically
 	 * at runtime we can deal with that then.
@@ -3564,7 +3656,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		wm8994->lrclk_shared[1] = 0;
 	}
 
-	wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+	pm_runtime_put(codec->dev);
 
 	/* Latch volume updates (right only; we always do left then right). */
 	snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME,
@@ -3642,7 +3734,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 	wm8994_handle_pdata(wm8994);
 
 	wm_hubs_add_analogue_controls(codec);
-	snd_soc_add_controls(codec, wm8994_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8994_snd_controls,
 			     ARRAY_SIZE(wm8994_snd_controls));
 	snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
 				  ARRAY_SIZE(wm8994_dapm_widgets));
@@ -3668,7 +3760,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		}
 		break;
 	case WM8958:
-		snd_soc_add_controls(codec, wm8958_snd_controls,
+		snd_soc_add_codec_controls(codec, wm8958_snd_controls,
 				     ARRAY_SIZE(wm8958_snd_controls));
 		snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
 					  ARRAY_SIZE(wm8958_dapm_widgets));
@@ -3690,7 +3782,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		break;
 
 	case WM1811:
-		snd_soc_add_controls(codec, wm8958_snd_controls,
+		snd_soc_add_codec_controls(codec, wm8958_snd_controls,
 				     ARRAY_SIZE(wm8958_snd_controls));
 		snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
 					  ARRAY_SIZE(wm8958_dapm_widgets));
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index c3a4247..f996d14 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -35,7 +35,7 @@
 typedef void (*wm8958_micdet_cb)(u16 status, void *data);
 
 int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
-		      int micbias, int det, int shrt);
+		      int micbias);
 int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 		      wm8958_micdet_cb cb, void *cb_data);
 
@@ -46,8 +46,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec);
 
 struct wm8994_micdet {
 	struct snd_soc_jack *jack;
-	int det;
-	int shrt;
+	bool detecting;
 };
 
 /* codec private data */
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index c8aada5..28c89b0 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -2047,7 +2047,6 @@ static int wm8995_probe(struct snd_soc_codec *codec)
 	int i;
 	int ret;
 
-	codec->dapm.idle_bias_off = 1;
 	wm8995 = snd_soc_codec_get_drvdata(codec);
 	wm8995->codec = codec;
 
@@ -2137,7 +2136,7 @@ static int wm8995_probe(struct snd_soc_codec *codec)
 
 	wm8995_update_class_w(codec);
 
-	snd_soc_add_controls(codec, wm8995_snd_controls,
+	snd_soc_add_codec_controls(codec, wm8995_snd_controls,
 			     ARRAY_SIZE(wm8995_snd_controls));
 	snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
 				  ARRAY_SIZE(wm8995_dapm_widgets));
@@ -2241,6 +2240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
 	.suspend = wm8995_suspend,
 	.resume = wm8995_resume,
 	.set_bias_level = wm8995_set_bias_level,
+	.idle_bias_off = true,
 };
 
 static struct regmap_config wm8995_regmap = {
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 61f7daa..adaaf80 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -73,7 +73,6 @@ struct wm8996_priv {
 
 	struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];
 	struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];
-	struct regulator *cpvdd;
 	int bg_ena;
 
 	struct wm8996_pdata pdata;
@@ -90,6 +89,7 @@ struct wm8996_priv {
 	struct snd_soc_jack *jack;
 	bool detecting;
 	bool jack_mic;
+	int jack_flips;
 	wm8996_polarity_fn polarity_cb;
 
 #ifdef CONFIG_GPIOLIB
@@ -716,10 +716,16 @@ SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),
 SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),
 SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),
 SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),
+SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5,
+		   WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA |
+		   WM8996_DSP1TXR_DRC_ENA),
 
 SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),
 SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),
 SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),
+SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5,
+		   WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA |
+		   WM8996_DSP2TXR_DRC_ENA),
 };
 
 static const struct snd_kcontrol_new wm8996_eq_controls[] = {
@@ -792,29 +798,18 @@ static int bg_event(struct snd_soc_dapm_widget *w,
 static int cp_event(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
-	struct snd_soc_codec *codec = w->codec;
-	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
 	int ret = 0;
 
 	switch (event) {
-	case SND_SOC_DAPM_PRE_PMU:
-		ret = regulator_enable(wm8996->cpvdd);
-		if (ret != 0)
-			dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
-				ret);
-		break;
 	case SND_SOC_DAPM_POST_PMU:
 		msleep(5);
 		break;
-	case SND_SOC_DAPM_POST_PMD:
-		regulator_disable_deferred(wm8996->cpvdd, 20);
-		break;
 	default:
 		BUG();
 		ret = -EINVAL;
 	}
 
-	return ret;
+	return 0;
 }
 
 static int rmv_short_event(struct snd_soc_dapm_widget *w,
@@ -1116,12 +1111,12 @@ SND_SOC_DAPM_INPUT("IN2RP"),
 SND_SOC_DAPM_INPUT("DMIC1DAT"),
 SND_SOC_DAPM_INPUT("DMIC2DAT"),
 
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
 SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
-		      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
-		      SND_SOC_DAPM_POST_PMD),
+		      SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
@@ -1280,6 +1275,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {
 	{ "AIFCLK", NULL, "SYSCLK" },
 	{ "SYSDSPCLK", NULL, "SYSCLK" },
 	{ "Charge Pump", NULL, "SYSCLK" },
+	{ "Charge Pump", NULL, "CPVDD" },
 
 	{ "MICB1", NULL, "LDO2" },
 	{ "MICB1", NULL, "MICB1 Audio" },
@@ -1719,6 +1715,7 @@ static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
 static int wm8996_reset(struct wm8996_priv *wm8996)
 {
 	if (wm8996->pdata.ldo_ena > 0) {
+		gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
 		gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
 		return 0;
 	} else {
@@ -2438,6 +2435,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
 	wm8996->jack = jack;
 	wm8996->detecting = true;
 	wm8996->polarity_cb = polarity_cb;
+	wm8996->jack_flips = 0;
 
 	if (wm8996->polarity_cb)
 		wm8996->polarity_cb(codec, 0);
@@ -2553,6 +2551,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec)
 			    WM8996_HP_POLL, WM8996_HP_POLL);
 }
 
+static void wm8996_report_headphone(struct snd_soc_codec *codec)
+{
+	dev_dbg(codec->dev, "Headphone detected\n");
+	wm8996_hpdet_start(codec);
+
+	/* Increase the detection rate a bit for responsiveness. */
+	snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
+			    WM8996_MICD_RATE_MASK |
+			    WM8996_MICD_BIAS_STARTTIME_MASK,
+			    7 << WM8996_MICD_RATE_SHIFT |
+			    7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
+}
+
 static void wm8996_micd(struct snd_soc_codec *codec)
 {
 	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
@@ -2572,6 +2583,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 		dev_dbg(codec->dev, "Jack removal detected\n");
 		wm8996->jack_mic = false;
 		wm8996->detecting = true;
+		wm8996->jack_flips = 0;
 		snd_soc_jack_report(wm8996->jack, 0,
 				    SND_JACK_LINEOUT | SND_JACK_HEADSET |
 				    SND_JACK_BTN_0);
@@ -2612,9 +2624,17 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 	/* If we detected a lower impedence during initial startup
 	 * then we probably have the wrong polarity, flip it.  Don't
 	 * do this for the lowest impedences to speed up detection of
-	 * plain headphones.
+	 * plain headphones.  If both polarities report a low
+	 * impedence then give up and report headphones.
 	 */
 	if (wm8996->detecting && (val & 0x3f0)) {
+		wm8996->jack_flips++;
+
+		if (wm8996->jack_flips > 1) {
+			wm8996_report_headphone(codec);
+			return;
+		}
+
 		reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2);
 		reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |
 			WM8996_MICD_BIAS_SRC;
@@ -2641,17 +2661,7 @@ static void wm8996_micd(struct snd_soc_codec *codec)
 			snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,
 					    SND_JACK_BTN_0);
 		} else if (wm8996->detecting) {
-			dev_dbg(codec->dev, "Headphone detected\n");
-			wm8996_hpdet_start(codec);
-
-			/* Increase the detection rate a bit for
-			 * responsiveness.
-			 */
-			snd_soc_update_bits(codec, WM8996_MIC_DETECT_1,
-					    WM8996_MICD_RATE_MASK |
-					    WM8996_MICD_BIAS_STARTTIME_MASK,
-					    7 << WM8996_MICD_RATE_SHIFT |
-					    7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);
+			wm8996_report_headphone(codec);
 		}
 	}
 }
@@ -2768,7 +2778,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec)
 	wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts;
 	wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;
 
-	ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls));
+	ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls));
 	if (ret != 0)
 		dev_err(codec->dev,
 			"Failed to add ReTune Mobile controls: %d\n", ret);
@@ -2791,7 +2801,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 	int ret;
 	struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
 	struct i2c_client *i2c = to_i2c_client(codec->dev);
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int i, irq_flags;
 
 	wm8996->codec = codec;
@@ -2799,8 +2808,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 	init_completion(&wm8996->dcs_done);
 	init_completion(&wm8996->fll_lock);
 
-	dapm->idle_bias_off = true;
-
 	codec->control_data = wm8996->regmap;
 
 	ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
@@ -2966,7 +2973,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
 	if (wm8996->pdata.num_retune_mobile_cfgs)
 		wm8996_retune_mobile_pdata(codec);
 	else
-		snd_soc_add_controls(codec, wm8996_eq_controls,
+		snd_soc_add_codec_controls(codec, wm8996_eq_controls,
 				     ARRAY_SIZE(wm8996_eq_controls));
 
 	/* If the TX LRCLK pins are not in LRCLK mode configure the
@@ -3038,7 +3045,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
 	for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
 		regulator_unregister_notifier(wm8996->supplies[i].consumer,
 					      &wm8996->disable_nb[i]);
-	regulator_put(wm8996->cpvdd);
 	regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
 
 	return 0;
@@ -3054,6 +3060,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = {
 	.probe =	wm8996_probe,
 	.remove =	wm8996_remove,
 	.set_bias_level = wm8996_set_bias_level,
+	.idle_bias_off	= true,
 	.seq_notifier = wm8996_seq_notifier,
 	.controls = wm8996_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8996_snd_controls),
@@ -3087,6 +3094,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
 			.channels_max = 6,
 			.rates = WM8996_RATES,
 			.formats = WM8996_FORMATS,
+			.sig_bits = 24,
 		},
 		.capture = {
 			 .stream_name = "AIF1 Capture",
@@ -3094,6 +3102,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
 			 .channels_max = 6,
 			 .rates = WM8996_RATES,
 			 .formats = WM8996_FORMATS,
+			 .sig_bits = 24,
 		 },
 		.ops = &wm8996_dai_ops,
 	},
@@ -3105,6 +3114,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
 			.channels_max = 2,
 			.rates = WM8996_RATES,
 			.formats = WM8996_FORMATS,
+			.sig_bits = 24,
 		},
 		.capture = {
 			 .stream_name = "AIF2 Capture",
@@ -3112,6 +3122,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = {
 			 .channels_max = 2,
 			 .rates = WM8996_RATES,
 			 .formats = WM8996_FORMATS,
+			.sig_bits = 24,
 		 },
 		.ops = &wm8996_dai_ops,
 	},
@@ -3149,25 +3160,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
 	for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
 		wm8996->supplies[i].supply = wm8996_supply_names[i];
 
-	ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
-				 wm8996->supplies);
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
+				      wm8996->supplies);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
 		goto err_gpio;
 	}
 
-	wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
-	if (IS_ERR(wm8996->cpvdd)) {
-		ret = PTR_ERR(wm8996->cpvdd);
-		dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
-		goto err_get;
-	}
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
 				    wm8996->supplies);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
-		goto err_cpvdd;
+		goto err_gpio;
 	}
 
 	if (wm8996->pdata.ldo_ena > 0) {
@@ -3188,7 +3192,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
 		goto err_regmap;
 	}
 	if (reg != 0x8915) {
-		dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret);
+		dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg);
 		ret = -EINVAL;
 		goto err_regmap;
 	}
@@ -3229,10 +3233,6 @@ err_enable:
 	if (wm8996->pdata.ldo_ena > 0)
 		gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
 	regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
-err_cpvdd:
-	regulator_put(wm8996->cpvdd);
-err_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
 err_gpio:
 	if (wm8996->pdata.ldo_ena > 0)
 		gpio_free(wm8996->pdata.ldo_ena);
@@ -3247,8 +3247,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
 
 	snd_soc_unregister_codec(&client->dev);
 	wm8996_free_gpio(wm8996);
-	regulator_put(wm8996->cpvdd);
-	regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
 	regmap_exit(wm8996->regmap);
 	if (wm8996->pdata.ldo_ena > 0) {
 		gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3273,25 +3271,7 @@ static struct i2c_driver wm8996_i2c_driver = {
 	.id_table = wm8996_i2c_id,
 };
 
-static int __init wm8996_modinit(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&wm8996_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8996 I2C driver: %d\n",
-		       ret);
-	}
-
-	return ret;
-}
-module_init(wm8996_modinit);
-
-static void __exit wm8996_exit(void)
-{
-	i2c_del_driver(&wm8996_i2c_driver);
-}
-module_exit(wm8996_exit);
+module_i2c_driver(wm8996_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8996 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a6bab39..076c126 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -824,6 +824,8 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
 static int wm9081_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
+
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -841,6 +843,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_STANDBY:
 		/* Initial cold start */
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			regcache_cache_only(wm9081->regmap, false);
+			regcache_sync(wm9081->regmap);
+
 			/* Disable LINEOUT discharge */
 			snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
 					    WM9081_LINEOUT_DISCH, 0);
@@ -892,6 +897,8 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
 		snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL,
 				    WM9081_LINEOUT_DISCH,
 				    WM9081_LINEOUT_DISCH);
+
+		regcache_cache_only(wm9081->regmap, true);
 		break;
 	}
 
@@ -1258,7 +1265,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
 {
 	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
 	int ret;
-	u16 reg;
 
 	codec->control_data = wm9081->regmap;
 
@@ -1268,16 +1274,6 @@ static int wm9081_probe(struct snd_soc_codec *codec)
 		return ret;
 	}
 
-	reg = 0;
-	if (wm9081->pdata.irq_high)
-		reg |= WM9081_IRQ_POL;
-	if (!wm9081->pdata.irq_cmos)
-		reg |= WM9081_IRQ_OP_CTRL;
-	snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
-			    WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
-
-	wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
 	/* Enable zero cross by default */
 	snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT,
 			    WM9081_LINEOUTZC, WM9081_LINEOUTZC);
@@ -1287,7 +1283,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
 	if (!wm9081->pdata.num_retune_configs) {
 		dev_dbg(codec->dev,
 			"No ReTune Mobile data, using normal EQ\n");
-		snd_soc_add_controls(codec, wm9081_eq_controls,
+		snd_soc_add_codec_controls(codec, wm9081_eq_controls,
 				     ARRAY_SIZE(wm9081_eq_controls));
 	}
 
@@ -1300,38 +1296,15 @@ static int wm9081_remove(struct snd_soc_codec *codec)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int wm9081_suspend(struct snd_soc_codec *codec)
-{
-	wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF);
-
-	return 0;
-}
-
-static int wm9081_resume(struct snd_soc_codec *codec)
-{
-	struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
-
-	regcache_sync(wm9081->regmap);
-
-	wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-	return 0;
-}
-#else
-#define wm9081_suspend NULL
-#define wm9081_resume NULL
-#endif
-
 static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
 	.probe = 	wm9081_probe,
 	.remove = 	wm9081_remove,
-	.suspend =	wm9081_suspend,
-	.resume =	wm9081_resume,
 
 	.set_sysclk = wm9081_set_sysclk,
 	.set_bias_level = wm9081_set_bias_level,
 
+	.idle_bias_off = true,
+
 	.controls         = wm9081_snd_controls,
 	.num_controls     = ARRAY_SIZE(wm9081_snd_controls),
 	.dapm_widgets	  = wm9081_dapm_widgets,
@@ -1395,6 +1368,16 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
 		memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
 		       sizeof(wm9081->pdata));
 
+	reg = 0;
+	if (wm9081->pdata.irq_high)
+		reg |= WM9081_IRQ_POL;
+	if (!wm9081->pdata.irq_cmos)
+		reg |= WM9081_IRQ_OP_CTRL;
+	regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL,
+			   WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
+
+	regcache_cache_only(wm9081->regmap, true);
+
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm9081, &wm9081_dai, 1);
 	if (ret < 0)
@@ -1435,28 +1418,7 @@ static struct i2c_driver wm9081_i2c_driver = {
 };
 #endif
 
-static int __init wm9081_modinit(void)
-{
-	int ret = 0;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	ret = i2c_add_driver(&wm9081_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n",
-		       ret);
-	}
-#endif
-	return ret;
-}
-module_init(wm9081_modinit);
-
-static void __exit wm9081_exit(void)
-{
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-	i2c_del_driver(&wm9081_i2c_driver);
-#endif
-}
-module_exit(wm9081_exit);
-
+module_i2c_driver(wm9081_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM9081 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 41ebe0d..4b263b6 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -25,6 +25,7 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/delay.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
@@ -33,116 +34,51 @@
 
 #include "wm9090.h"
 
-static const u16 wm9090_reg_defaults[] = {
-	0x9093,     /* R0   - Software Reset */
-	0x0006,     /* R1   - Power Management (1) */
-	0x6000,     /* R2   - Power Management (2) */
-	0x0000,     /* R3   - Power Management (3) */
-	0x0000,     /* R4 */
-	0x0000,     /* R5 */
-	0x01C0,     /* R6   - Clocking 1 */
-	0x0000,     /* R7 */
-	0x0000,     /* R8 */
-	0x0000,     /* R9 */
-	0x0000,     /* R10 */
-	0x0000,     /* R11 */
-	0x0000,     /* R12 */
-	0x0000,     /* R13 */
-	0x0000,     /* R14 */
-	0x0000,     /* R15 */
-	0x0000,     /* R16 */
-	0x0000,     /* R17 */
-	0x0000,     /* R18 */
-	0x0000,     /* R19 */
-	0x0000,     /* R20 */
-	0x0000,     /* R21 */
-	0x0003,     /* R22  - IN1 Line Control */
-	0x0003,     /* R23  - IN2 Line Control */
-	0x0083,     /* R24  - IN1 Line Input A Volume */
-	0x0083,     /* R25  - IN1  Line Input B Volume */
-	0x0083,     /* R26  - IN2 Line Input A Volume */
-	0x0083,     /* R27  - IN2 Line Input B Volume */
-	0x002D,     /* R28  - Left Output Volume */
-	0x002D,     /* R29  - Right Output Volume */
-	0x0000,     /* R30 */
-	0x0000,     /* R31 */
-	0x0000,     /* R32 */
-	0x0000,     /* R33 */
-	0x0100,     /* R34  - SPKMIXL Attenuation */
-	0x0000,     /* R35 */
-	0x0010,     /* R36  - SPKOUT Mixers */
-	0x0140,     /* R37  - ClassD3 */
-	0x0039,     /* R38  - Speaker Volume Left */
-	0x0000,     /* R39 */
-	0x0000,     /* R40 */
-	0x0000,     /* R41 */
-	0x0000,     /* R42 */
-	0x0000,     /* R43 */
-	0x0000,     /* R44 */
-	0x0000,     /* R45  - Output Mixer1 */
-	0x0000,     /* R46  - Output Mixer2 */
-	0x0100,     /* R47  - Output Mixer3 */
-	0x0100,     /* R48  - Output Mixer4 */
-	0x0000,     /* R49 */
-	0x0000,     /* R50 */
-	0x0000,     /* R51 */
-	0x0000,     /* R52 */
-	0x0000,     /* R53 */
-	0x0000,     /* R54  - Speaker Mixer */
-	0x0000,     /* R55 */
-	0x0000,     /* R56 */
-	0x000D,     /* R57  - AntiPOP2 */
-	0x0000,     /* R58 */
-	0x0000,     /* R59 */
-	0x0000,     /* R60 */
-	0x0000,     /* R61 */
-	0x0000,     /* R62 */
-	0x0000,     /* R63 */
-	0x0000,     /* R64 */
-	0x0000,     /* R65 */
-	0x0000,     /* R66 */
-	0x0000,     /* R67 */
-	0x0000,     /* R68 */
-	0x0000,     /* R69 */
-	0x0000,     /* R70  - Write Sequencer 0 */
-	0x0000,     /* R71  - Write Sequencer 1 */
-	0x0000,     /* R72  - Write Sequencer 2 */
-	0x0000,     /* R73  - Write Sequencer 3 */
-	0x0000,     /* R74  - Write Sequencer 4 */
-	0x0000,     /* R75  - Write Sequencer 5 */
-	0x1F25,     /* R76  - Charge Pump 1 */
-	0x0000,     /* R77 */
-	0x0000,     /* R78 */
-	0x0000,     /* R79 */
-	0x0000,     /* R80 */
-	0x0000,     /* R81 */
-	0x0000,     /* R82 */
-	0x0000,     /* R83 */
-	0x0000,     /* R84  - DC Servo 0 */
-	0x054A,     /* R85  - DC Servo 1 */
-	0x0000,     /* R86 */
-	0x0000,     /* R87  - DC Servo 3 */
-	0x0000,     /* R88  - DC Servo Readback 0 */
-	0x0000,     /* R89  - DC Servo Readback 1 */
-	0x0000,     /* R90  - DC Servo Readback 2 */
-	0x0000,     /* R91 */
-	0x0000,     /* R92 */
-	0x0000,     /* R93 */
-	0x0000,     /* R94 */
-	0x0000,     /* R95 */
-	0x0100,     /* R96  - Analogue HP 0 */
-	0x0000,     /* R97 */
-	0x8640,     /* R98  - AGC Control 0 */
-	0xC000,     /* R99  - AGC Control 1 */
-	0x0200,     /* R100 - AGC Control 2 */
+static const struct reg_default wm9090_reg_defaults[] = {
+	{ 1,  0x0006 },     /* R1   - Power Management (1) */
+	{ 2,  0x6000 },     /* R2   - Power Management (2) */
+	{ 3,  0x0000 },     /* R3   - Power Management (3) */
+	{ 6,  0x01C0 },     /* R6   - Clocking 1 */
+	{ 22, 0x0003 },     /* R22  - IN1 Line Control */
+	{ 23, 0x0003 },     /* R23  - IN2 Line Control */
+	{ 24, 0x0083 },     /* R24  - IN1 Line Input A Volume */
+	{ 25, 0x0083 },     /* R25  - IN1  Line Input B Volume */
+	{ 26, 0x0083 },     /* R26  - IN2 Line Input A Volume */
+	{ 27, 0x0083 },     /* R27  - IN2 Line Input B Volume */
+	{ 28, 0x002D },     /* R28  - Left Output Volume */
+	{ 29, 0x002D },     /* R29  - Right Output Volume */
+	{ 34, 0x0100 },     /* R34  - SPKMIXL Attenuation */
+	{ 35, 0x0010 },     /* R36  - SPKOUT Mixers */
+	{ 37, 0x0140 },     /* R37  - ClassD3 */
+	{ 38, 0x0039 },     /* R38  - Speaker Volume Left */
+	{ 45, 0x0000 },     /* R45  - Output Mixer1 */
+	{ 46, 0x0000 },     /* R46  - Output Mixer2 */
+	{ 47, 0x0100 },     /* R47  - Output Mixer3 */
+	{ 48, 0x0100 },     /* R48  - Output Mixer4 */
+	{ 54, 0x0000 },     /* R54  - Speaker Mixer */
+	{ 57, 0x000D },     /* R57  - AntiPOP2 */
+	{ 70, 0x0000 },     /* R70  - Write Sequencer 0 */
+	{ 71, 0x0000 },     /* R71  - Write Sequencer 1 */
+	{ 72, 0x0000 },     /* R72  - Write Sequencer 2 */
+	{ 73, 0x0000 },     /* R73  - Write Sequencer 3 */
+	{ 74, 0x0000 },     /* R74  - Write Sequencer 4 */
+	{ 75, 0x0000 },     /* R75  - Write Sequencer 5 */
+	{ 76, 0x1F25 },     /* R76  - Charge Pump 1 */
+	{ 85, 0x054A },     /* R85  - DC Servo 1 */
+	{ 87, 0x0000 },     /* R87  - DC Servo 3 */
+	{ 96, 0x0100 },     /* R96  - Analogue HP 0 */
+	{ 98, 0x8640 },     /* R98  - AGC Control 0 */
+	{ 99, 0xC000 },     /* R99  - AGC Control 1 */
+	{ 100, 0x0200 },     /* R100 - AGC Control 2 */
 };
 
 /* This struct is used to save the context */
 struct wm9090_priv {
 	struct wm9090_platform_data pdata;
+	struct regmap *regmap;
 };
 
-static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm9090_volatile(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM9090_SOFTWARE_RESET:
@@ -150,10 +86,60 @@ static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg)
 	case WM9090_DC_SERVO_READBACK_0:
 	case WM9090_DC_SERVO_READBACK_1:
 	case WM9090_DC_SERVO_READBACK_2:
-		return 1;
+		return true;
 
 	default:
-		return 0;
+		return false;
+	}
+}
+
+static bool wm9090_readable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM9090_SOFTWARE_RESET:
+	case WM9090_POWER_MANAGEMENT_1:
+	case WM9090_POWER_MANAGEMENT_2:
+	case WM9090_POWER_MANAGEMENT_3:
+	case WM9090_CLOCKING_1:
+	case WM9090_IN1_LINE_CONTROL:
+	case WM9090_IN2_LINE_CONTROL:
+	case WM9090_IN1_LINE_INPUT_A_VOLUME:
+	case WM9090_IN1_LINE_INPUT_B_VOLUME:
+	case WM9090_IN2_LINE_INPUT_A_VOLUME:
+	case WM9090_IN2_LINE_INPUT_B_VOLUME:
+	case WM9090_LEFT_OUTPUT_VOLUME:
+	case WM9090_RIGHT_OUTPUT_VOLUME:
+	case WM9090_SPKMIXL_ATTENUATION:
+	case WM9090_SPKOUT_MIXERS:
+	case WM9090_CLASSD3:
+	case WM9090_SPEAKER_VOLUME_LEFT:
+	case WM9090_OUTPUT_MIXER1:
+	case WM9090_OUTPUT_MIXER2:
+	case WM9090_OUTPUT_MIXER3:
+	case WM9090_OUTPUT_MIXER4:
+	case WM9090_SPEAKER_MIXER:
+	case WM9090_ANTIPOP2:
+	case WM9090_WRITE_SEQUENCER_0:
+	case WM9090_WRITE_SEQUENCER_1:
+	case WM9090_WRITE_SEQUENCER_2:
+	case WM9090_WRITE_SEQUENCER_3:
+	case WM9090_WRITE_SEQUENCER_4:
+	case WM9090_WRITE_SEQUENCER_5:
+	case WM9090_CHARGE_PUMP_1:
+	case WM9090_DC_SERVO_0:
+	case WM9090_DC_SERVO_1:
+	case WM9090_DC_SERVO_3:
+	case WM9090_DC_SERVO_READBACK_0:
+	case WM9090_DC_SERVO_READBACK_1:
+	case WM9090_DC_SERVO_READBACK_2:
+	case WM9090_ANALOGUE_HP_0:
+	case WM9090_AGC_CONTROL_0:
+	case WM9090_AGC_CONTROL_1:
+	case WM9090_AGC_CONTROL_2:
+		return true;
+
+	default:
+		return false;
 	}
 }
 
@@ -447,7 +433,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 
 	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
 
-	snd_soc_add_controls(codec, wm9090_controls,
+	snd_soc_add_codec_controls(codec, wm9090_controls,
 			     ARRAY_SIZE(wm9090_controls));
 
 	if (wm9090->pdata.lin1_diff) {
@@ -456,7 +442,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 	} else {
 		snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
 					ARRAY_SIZE(audio_map_in1_se));
-		snd_soc_add_controls(codec, wm9090_in1_se_controls,
+		snd_soc_add_codec_controls(codec, wm9090_in1_se_controls,
 				     ARRAY_SIZE(wm9090_in1_se_controls));
 	}
 
@@ -466,7 +452,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 	} else {
 		snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
 					ARRAY_SIZE(audio_map_in2_se));
-		snd_soc_add_controls(codec, wm9090_in2_se_controls,
+		snd_soc_add_codec_controls(codec, wm9090_in2_se_controls,
 				     ARRAY_SIZE(wm9090_in2_se_controls));
 	}
 
@@ -492,8 +478,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec)
 static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
-	u16 *reg_cache = codec->reg_cache;
-	int i, ret;
+	struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -513,7 +498,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 			/* Restore the register cache */
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm9090->regmap);
 		}
 
 		/* We keep VMID off during standby since the combination of
@@ -537,26 +522,16 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 
 static int wm9090_probe(struct snd_soc_codec *codec)
 {
+	struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev);
 	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+	codec->control_data = wm9090->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
 
-	ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET);
-	if (ret < 0)
-		return ret;
-	if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) {
-		dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret);
-		return -EINVAL;
-	}
-
-	ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0);
-	if (ret < 0)
-		return ret;
-
 	/* Configure some defaults; they will be written out when we
 	 * bring the bias up.
 	 */
@@ -624,16 +599,27 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9090 = {
 	.suspend = 	wm9090_suspend,
 	.resume =	wm9090_resume,
 	.set_bias_level = wm9090_set_bias_level,
-	.reg_cache_size = (WM9090_MAX_REGISTER + 1),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm9090_reg_defaults,
-	.volatile_register = wm9090_volatile,
 };
 
+static const struct regmap_config wm9090_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+
+	.max_register = WM9090_MAX_REGISTER,
+	.volatile_reg = wm9090_volatile,
+	.readable_reg = wm9090_readable,
+
+	.cache_type = REGCACHE_RBTREE,
+	.reg_defaults = wm9090_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults),
+};
+
+
 static int wm9090_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct wm9090_priv *wm9090;
+	unsigned int reg;
 	int ret;
 
 	wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL);
@@ -642,6 +628,26 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 	}
 
+	wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap);
+	if (IS_ERR(wm9090->regmap)) {
+		ret = PTR_ERR(wm9090->regmap);
+		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, &reg);
+	if (ret < 0)
+		goto err;
+	if (reg != 0x9093) {
+		dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
+	if (ret < 0)
+		goto err;
+
 	if (i2c->dev.platform_data)
 		memcpy(&wm9090->pdata, i2c->dev.platform_data,
 		       sizeof(wm9090->pdata));
@@ -650,6 +656,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c,
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm9090,  NULL, 0);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	regmap_exit(wm9090->regmap);
 	return ret;
 }
 
@@ -658,6 +673,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c)
 	struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c);
 
 	snd_soc_unregister_codec(&i2c->dev);
+	regmap_exit(wm9090->regmap);
 
 	return 0;
 }
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index 40c92ea..cacc6a8 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -351,7 +351,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
 	if (ret)
 		goto reset_err;
 
-	snd_soc_add_controls(codec, wm9705_snd_ac97_controls,
+	snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls,
 				ARRAY_SIZE(wm9705_snd_ac97_controls));
 
 	return 0;
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index b7b31f8..b342ae5 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,10 +20,9 @@
 #include <sound/ac97_codec.h>
 #include <sound/initval.h>
 #include <sound/soc.h>
+#include <sound/tlv.h>
 #include "wm9712.h"
 
-#define WM9712_VERSION "0.4"
-
 static unsigned int ac97_read(struct snd_soc_codec *codec,
 	unsigned int reg);
 static int ac97_write(struct snd_soc_codec *codec,
@@ -71,6 +70,9 @@ static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer",
 static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"};
 static const char *wm9712_diff_sel[] = {"Mic", "Line"};
 
+static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0);
+
 static const struct soc_enum wm9712_enum[] = {
 SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select),
 SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux),
@@ -149,9 +151,9 @@ SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
 SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1),
 SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
 
-SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1),
-SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1),
-SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0),
+SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
+SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
+SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv),
 };
 
 /* We have to create a fake left and right HP mixers because
@@ -619,8 +621,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
 {
 	int ret = 0;
 
-	printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
-
 	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
 	if (ret < 0) {
 		printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
@@ -637,7 +637,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
 	ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
 
 	wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-	snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
+	snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls,
 				ARRAY_SIZE(wm9712_snd_ac97_controls));
 
 	return 0;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2b8479b..2d22cc7 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1216,7 +1216,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
 	reg = ac97_read(codec, AC97_CD) & 0x7fff;
 	ac97_write(codec, AC97_CD, reg);
 
-	snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
+	snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls,
 				ARRAY_SIZE(wm9713_snd_ac97_controls));
 
 	return 0;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 8a68cea..82b7e9d 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -500,6 +500,36 @@ static int earpiece_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
+static int lineout_event(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *control, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	bool *flag;
+
+	switch (w->shift) {
+	case WM8993_LINEOUT1N_ENA_SHIFT:
+		flag = &hubs->lineout1n_ena;
+		break;
+	case WM8993_LINEOUT1P_ENA_SHIFT:
+		flag = &hubs->lineout1p_ena;
+		break;
+	case WM8993_LINEOUT2N_ENA_SHIFT:
+		flag = &hubs->lineout2n_ena;
+		break;
+	case WM8993_LINEOUT2P_ENA_SHIFT:
+		flag = &hubs->lineout2p_ena;
+		break;
+	default:
+		WARN(1, "Unknown line output");
+		return -EINVAL;
+	}
+
+	*flag = SND_SOC_DAPM_EVENT_ON(event);
+
+	return 0;
+}
+
 static const struct snd_kcontrol_new in1l_pga[] = {
 SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
 SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
@@ -640,9 +670,8 @@ SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
 
 SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, 
 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
-SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
-		   NULL, 0,
-		   hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
+		       hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
 		   earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
@@ -656,10 +685,10 @@ SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
 		   right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
 
 SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0),
-SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
-		 NULL, 0),
-SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
-		 NULL, 0),
+SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
+		     NULL, 0),
+SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
+		     NULL, 0),
 
 SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
 		   line1_mix, ARRAY_SIZE(line1_mix)),
@@ -675,14 +704,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
 SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
 		   line2p_mix, ARRAY_SIZE(line2p_mix)),
 
-SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
-		 NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
-		 NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
-		 NULL, 0),
-SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
-		 NULL, 0),
+SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
+		       NULL, 0, lineout_event,
+		     SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
+		       NULL, 0, lineout_event,
+		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
+		       NULL, 0, lineout_event,
+		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
+		       NULL, 0, lineout_event,
+		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 
 SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
 SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
@@ -901,7 +934,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
 			    WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
 			    WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
 
-	snd_soc_add_controls(codec, analogue_snd_controls,
+	snd_soc_add_codec_controls(codec, analogue_snd_controls,
 			     ARRAY_SIZE(analogue_snd_controls));
 
 	snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
@@ -949,6 +982,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
 				  int jd_scthr, int jd_thr, int micbias1_lvl,
 				  int micbias2_lvl)
 {
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+
+	hubs->lineout1_se = !lineout1_diff;
+	hubs->lineout2_se = !lineout2_diff;
+
 	if (!lineout1_diff)
 		snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
 				    WM8993_LINEOUT1_MODE,
@@ -958,12 +996,6 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
 				    WM8993_LINEOUT2_MODE,
 				    WM8993_LINEOUT2_MODE);
 
-	/* If the line outputs are differential then we aren't presenting
-	 * VMID as an output and can disable it.
-	 */
-	if (lineout1_diff && lineout2_diff)
-		codec->dapm.idle_bias_off = 1;
-
 	if (lineout1fb)
 		snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
 				    WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
@@ -984,6 +1016,74 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
 }
 EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
 
+void wm_hubs_vmid_ena(struct snd_soc_codec *codec)
+{
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	int val = 0;
+
+	if (hubs->lineout1_se)
+		val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
+
+	if (hubs->lineout2_se)
+		val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
+
+	/* Enable the line outputs while we power up */
+	snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val);
+}
+EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena);
+
+void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
+			    enum snd_soc_bias_level level)
+{
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	int val;
+
+	switch (level) {
+	case SND_SOC_BIAS_STANDBY:
+		/* Clamp the inputs to VMID while we ramp to charge caps */
+		snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
+				    WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP);
+		break;
+
+	case SND_SOC_BIAS_ON:
+		/* Turn off any unneded single ended outputs */
+		val = 0;
+
+		if (hubs->lineout1_se && hubs->lineout1n_ena)
+			val |= WM8993_LINEOUT1N_ENA;
+
+		if (hubs->lineout1_se && hubs->lineout1p_ena)
+			val |= WM8993_LINEOUT1P_ENA;
+
+		if (hubs->lineout2_se && hubs->lineout2n_ena)
+			val |= WM8993_LINEOUT2N_ENA;
+
+		if (hubs->lineout2_se && hubs->lineout2p_ena)
+			val |= WM8993_LINEOUT2P_ENA;
+
+		snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
+				    WM8993_LINEOUT1N_ENA |
+				    WM8993_LINEOUT1P_ENA |
+				    WM8993_LINEOUT2N_ENA |
+				    WM8993_LINEOUT2P_ENA,
+				    val);
+
+		if (!hubs->lineout1n_ena && !hubs->lineout1p_ena &&
+		    !hubs->lineout2n_ena && !hubs->lineout2p_ena)
+			snd_soc_update_bits(codec, WM8993_ANTIPOP1,
+					    WM8993_LINEOUT_VMID_BUF_ENA, 0);
+
+		/* Remove the input clamps */
+		snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
+				    WM8993_INPUTS_CLAMP, 0);
+		break;
+
+	default:
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level);
+
 MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index c674c7a..4140905 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -33,6 +33,14 @@ struct wm_hubs_data {
 	bool class_w;
 	u16 class_w_dcs;
 
+	bool lineout1_se;
+	bool lineout1n_ena;
+	bool lineout1p_ena;
+
+	bool lineout2_se;
+	bool lineout2n_ena;
+	bool lineout2p_ena;
+
 	bool dcs_done_irq;
 	struct completion dcs_done;
 };
@@ -46,5 +54,8 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
 					 int micbias1_lvl, int micbias2_lvl);
 
 extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
+extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec);
+extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
+				   enum snd_soc_bias_level level);
 
 #endif
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index b26401f..97d77b2 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -826,7 +826,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
 	}
 }
 
-static u64 davinci_pcm_dmamask = 0xffffffff;
+static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32);
 
 static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
@@ -837,7 +837,7 @@ static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &davinci_pcm_dmamask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = davinci_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c
index bae5cbb..e01cb02 100644
--- a/sound/soc/ep93xx/edb93xx.c
+++ b/sound/soc/ep93xx/edb93xx.c
@@ -85,9 +85,7 @@ static int __devinit edb93xx_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &snd_soc_edb93xx;
 	int ret;
 
-	ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
-				 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
-				 EP93XX_SYSCON_I2SCLKDIV_SPOL);
+	ret = ep93xx_i2s_acquire();
 	if (ret)
 		return ret;
 
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index de83904..32adca3 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -281,7 +281,7 @@ static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
 	}
 }
 
-static u64 ep93xx_pcm_dmamask = 0xffffffff;
+static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32);
 
 static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
 {
@@ -292,7 +292,7 @@ static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &ep93xx_pcm_dmamask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = ep93xx_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index ccae34a..a193cea 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -103,9 +103,7 @@ static int __devinit snappercl15_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &snd_soc_snappercl15;
 	int ret;
 
-	ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97,
-				 EP93XX_SYSCON_I2SCLKDIV_ORIDE |
-				 EP93XX_SYSCON_I2SCLKDIV_SPOL);
+	ret = ep93xx_i2s_acquire();
 	if (ret)
 		return ret;
 
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 4f59bba..96bb92d 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -311,23 +311,23 @@ static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd)
 	 * should allocate a DMA buffer only for the streams that are valid.
 	 */
 
-	if (pcm->streams[0].substream) {
+	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
 			fsl_dma_hardware.buffer_bytes_max,
-			&pcm->streams[0].substream->dma_buffer);
+			&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
 		if (ret) {
 			dev_err(card->dev, "can't alloc playback dma buffer\n");
 			return ret;
 		}
 	}
 
-	if (pcm->streams[1].substream) {
+	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
 		ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
 			fsl_dma_hardware.buffer_bytes_max,
-			&pcm->streams[1].substream->dma_buffer);
+			&pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
 		if (ret) {
 			dev_err(card->dev, "can't alloc capture dma buffer\n");
-			snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer);
+			snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
 			return ret;
 		}
 	}
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index e7803d3..33adbf1 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -298,7 +298,7 @@ static struct snd_pcm_ops psc_dma_ops = {
 	.hw_params	= psc_dma_hw_params,
 };
 
-static u64 psc_dma_dmamask = 0xffffffff;
+static u64 psc_dma_dmamask = DMA_BIT_MASK(32);
 static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_card *card = rtd->card->snd_card;
@@ -314,18 +314,18 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &psc_dma_dmamask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
-	if (pcm->streams[0].substream) {
+	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
-				size, &pcm->streams[0].substream->dma_buffer);
+				size, &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
 		if (rc)
 			goto playback_alloc_err;
 	}
 
-	if (pcm->streams[1].substream) {
+	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
 		rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev,
-				size, &pcm->streams[1].substream->dma_buffer);
+				size, &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer);
 		if (rc)
 			goto capture_alloc_err;
 	}
@@ -336,8 +336,8 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 
  capture_alloc_err:
-	if (pcm->streams[0].substream)
-		snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer);
+	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
+		snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
 
  playback_alloc_err:
 	dev_err(card->dev, "Cannot allocate buffer(s)\n");
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index 7383917..91b66ef 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,7 +1,6 @@
 menuconfig SND_IMX_SOC
 	tristate "SoC Audio for Freescale i.MX CPUs"
 	depends on ARCH_MXC
-	select SND_PCM
 	select FIQ
 	select SND_SOC_AC97_BUS
 	help
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 5780c9b..268ed9b 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -35,11 +35,7 @@
 struct imx_pcm_runtime_data {
 	int period_bytes;
 	int periods;
-	int dma;
 	unsigned long offset;
-	unsigned long size;
-	void *buf;
-	int period_time;
 	struct dma_async_tx_descriptor *desc;
 	struct dma_chan *dma_chan;
 	struct imx_dma_data dma_data;
@@ -144,19 +140,14 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	chan = iprtd->dma_chan;
 
-	iprtd->size = params_buffer_bytes(params);
 	iprtd->periods = params_periods(params);
 	iprtd->period_bytes = params_period_bytes(params);
 	iprtd->offset = 0;
-	iprtd->period_time = HZ / (params_rate(params) /
-			params_period_size(params));
 
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
 	dma_addr = runtime->dma_addr;
 
-	iprtd->buf = (unsigned int *)substream->dma_buffer.area;
-
 	iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
 			iprtd->period_bytes * iprtd->periods,
 			iprtd->period_bytes,
@@ -186,16 +177,6 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
 	return 0;
 }
 
-static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct imx_pcm_dma_params *dma_params;
-
-	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
-
-	return 0;
-}
-
 static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
@@ -206,6 +187,7 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		dmaengine_submit(iprtd->desc);
+		dma_async_issue_pending(iprtd->dma_chan);
 
 		break;
 
@@ -291,7 +273,6 @@ static struct snd_pcm_ops imx_pcm_ops = {
 	.ioctl		= snd_pcm_lib_ioctl,
 	.hw_params	= snd_imx_pcm_hw_params,
 	.hw_free	= snd_imx_pcm_hw_free,
-	.prepare	= snd_imx_pcm_prepare,
 	.trigger	= snd_imx_pcm_trigger,
 	.pointer	= snd_imx_pcm_pointer,
 	.mmap		= snd_imx_pcm_mmap,
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c
index 3c2eed9..155899c 100644
--- a/sound/soc/imx/mx27vis-aic32x4.c
+++ b/sound/soc/imx/mx27vis-aic32x4.c
@@ -25,16 +25,37 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
+#include <sound/tlv.h>
 #include <asm/mach-types.h>
 #include <mach/audmux.h>
+#include <mach/iomux-mx27.h>
 
 #include "../codecs/tlv320aic32x4.h"
 #include "imx-ssi.h"
 
+#define MX27VIS_AMP_GAIN	0
+#define MX27VIS_AMP_MUTE	1
+
+#define MX27VIS_PIN_G0		(GPIO_PORTF + 9)
+#define MX27VIS_PIN_G1		(GPIO_PORTF + 8)
+#define MX27VIS_PIN_SDL		(GPIO_PORTE + 5)
+#define MX27VIS_PIN_SDR		(GPIO_PORTF + 7)
+
+static int mx27vis_amp_gain;
+static int mx27vis_amp_mute;
+
+static const int mx27vis_amp_pins[] = {
+	MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
+	MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
+	MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
+	MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
+};
+
 static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params)
 {
@@ -74,6 +95,76 @@ static struct snd_soc_ops mx27vis_aic32x4_snd_ops = {
 	.hw_params	= mx27vis_aic32x4_hw_params,
 };
 
+static int mx27vis_amp_set(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	int value = ucontrol->value.integer.value[0];
+	unsigned int reg = mc->reg;
+	int max = mc->max;
+
+	if (value > max)
+		return -EINVAL;
+
+	switch (reg) {
+	case MX27VIS_AMP_GAIN:
+		gpio_set_value(MX27VIS_PIN_G0, value & 1);
+		gpio_set_value(MX27VIS_PIN_G1, value >> 1);
+		mx27vis_amp_gain = value;
+		break;
+	case MX27VIS_AMP_MUTE:
+		gpio_set_value(MX27VIS_PIN_SDL, value & 1);
+		gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
+		mx27vis_amp_mute = value;
+		break;
+	}
+	return 0;
+}
+
+static int mx27vis_amp_get(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_mixer_control *mc =
+		(struct soc_mixer_control *)kcontrol->private_value;
+	unsigned int reg = mc->reg;
+
+	switch (reg) {
+	case MX27VIS_AMP_GAIN:
+		ucontrol->value.integer.value[0] = mx27vis_amp_gain;
+		break;
+	case MX27VIS_AMP_MUTE:
+		ucontrol->value.integer.value[0] = mx27vis_amp_mute;
+		break;
+	}
+	return 0;
+}
+
+/* From 6dB to 24dB in steps of 6dB */
+static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0);
+
+static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = {
+	SOC_DAPM_PIN_SWITCH("External Mic"),
+	SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0,
+		       mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv),
+	SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0,
+		       mx27vis_amp_get, mx27vis_amp_set),
+};
+
+static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
+	SND_SOC_DAPM_MIC("External Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
+	{"Mic Bias", NULL, "External Mic"},
+	{"IN1_R", NULL, "Mic Bias"},
+	{"IN2_R", NULL, "Mic Bias"},
+	{"IN3_R", NULL, "Mic Bias"},
+	{"IN1_L", NULL, "Mic Bias"},
+	{"IN2_L", NULL, "Mic Bias"},
+	{"IN3_L", NULL, "Mic Bias"},
+};
+
 static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
 	.name		= "tlv320aic32x4",
 	.stream_name	= "TLV320AIC32X4",
@@ -89,6 +180,12 @@ static struct snd_soc_card mx27vis_aic32x4 = {
 	.owner		= THIS_MODULE,
 	.dai_link	= &mx27vis_aic32x4_dai,
 	.num_links	= 1,
+	.controls	= mx27vis_aic32x4_controls,
+	.num_controls	= ARRAY_SIZE(mx27vis_aic32x4_controls),
+	.dapm_widgets	= aic32x4_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
+	.dapm_routes	= aic32x4_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
 };
 
 static struct platform_device *mx27vis_aic32x4_snd_device;
@@ -122,6 +219,13 @@ static int __init mx27vis_aic32x4_init(void)
 			MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
 	);
 
+	ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
+			ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
+	if (ret) {
+		printk(KERN_ERR "ASoC: unable to setup gpios\n");
+		platform_device_put(mx27vis_aic32x4_snd_device);
+	}
+
 	return ret;
 }
 
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index 0097c3b..e8aaff1 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -91,56 +91,52 @@ static struct snd_soc_card qi_lb60 = {
 	.num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
 };
 
-static struct platform_device *qi_lb60_snd_device;
-
 static const struct gpio qi_lb60_gpios[] = {
 	{ QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
 	{ QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
 };
 
-static int __init qi_lb60_init(void)
+static int __devinit qi_lb60_probe(struct platform_device *pdev)
 {
+	struct snd_soc_card *card = &qi_lb60;
 	int ret;
 
-	qi_lb60_snd_device = platform_device_alloc("soc-audio", -1);
-
-	if (!qi_lb60_snd_device)
-		return -ENOMEM;
-
 	ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
-	if (ret) {
-		pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret);
-		goto err_device_put;
-	}
+	if (ret)
+		return ret;
 
-	platform_set_drvdata(qi_lb60_snd_device, &qi_lb60);
+	card->dev = &pdev->dev;
 
-	ret = platform_device_add(qi_lb60_snd_device);
+	ret = snd_soc_register_card(card);
 	if (ret) {
-		pr_err("qi_lb60 snd: Failed to add snd soc device: %d\n", ret);
-		goto err_unset_pdata;
+		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+			ret);
+		gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
 	}
-
-	 return 0;
-
-err_unset_pdata:
-	platform_set_drvdata(qi_lb60_snd_device, NULL);
-/*err_gpio_free_array:*/
-	gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
-err_device_put:
-	platform_device_put(qi_lb60_snd_device);
-
 	return ret;
 }
-module_init(qi_lb60_init);
 
-static void __exit qi_lb60_exit(void)
+static int __devexit qi_lb60_remove(struct platform_device *pdev)
 {
-	platform_device_unregister(qi_lb60_snd_device);
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
 	gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
+	return 0;
 }
-module_exit(qi_lb60_exit);
+
+static struct platform_driver qi_lb60_driver = {
+	.driver		= {
+		.name	= "qi-lb60-audio",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= qi_lb60_probe,
+	.remove		= __devexit_p(qi_lb60_remove),
+};
+
+module_platform_driver(qi_lb60_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:qi-lb60-audio");
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index d038540..b9f1659 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -55,7 +55,7 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
 	.fifo_size		= 0,
 };
 
-static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL;
+static u64 kirkwood_dma_dmamask = DMA_BIT_MASK(32);
 
 static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
 {
@@ -324,7 +324,7 @@ static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &kirkwood_dma_dmamask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = kirkwood_dma_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 55d2ed3..80bd59c 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -71,41 +71,41 @@ static struct snd_soc_card openrd_client = {
 	.num_links = ARRAY_SIZE(openrd_client_dai),
 };
 
-static struct platform_device *openrd_client_snd_device;
-
-static int __init openrd_client_init(void)
+static int __devinit openrd_probe(struct platform_device *pdev)
 {
+	struct snd_soc_card *card = &openrd_client;
 	int ret;
 
-	if (!machine_is_openrd_client() && !machine_is_openrd_ultimate())
-		return 0;
-
-	openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!openrd_client_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(openrd_client_snd_device,
-			&openrd_client);
-
-	ret = platform_device_add(openrd_client_snd_device);
-	if (ret) {
-		printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
-		platform_device_put(openrd_client_snd_device);
-	}
+	card->dev = &pdev->dev;
 
+	ret = snd_soc_register_card(card);
+	if (ret)
+		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+			ret);
 	return ret;
 }
 
-static void __exit openrd_client_exit(void)
+static int __devexit openrd_remove(struct platform_device *pdev)
 {
-	platform_device_unregister(openrd_client_snd_device);
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+	return 0;
 }
 
-module_init(openrd_client_init);
-module_exit(openrd_client_exit);
+static struct platform_driver openrd_driver = {
+	.driver		= {
+		.name	= "openrd-client-audio",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= openrd_probe,
+	.remove		= __devexit_p(openrd_remove),
+};
+
+module_platform_driver(openrd_driver);
 
 /* Module information */
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("ALSA SoC OpenRD Client");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:soc-audio");
+MODULE_ALIAS("platform:openrd-client-audio");
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index b47cc4e..f898363 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -80,7 +80,6 @@ static struct snd_soc_dai_link t5325_dai[] = {
 },
 };
 
-
 static struct snd_soc_card t5325 = {
 	.name = "t5325",
 	.owner = THIS_MODULE,
@@ -93,38 +92,40 @@ static struct snd_soc_card t5325 = {
 	.num_dapm_routes = ARRAY_SIZE(t5325_route),
 };
 
-static struct platform_device *t5325_snd_device;
-
-static int __init t5325_init(void)
+static int __devinit t5325_probe(struct platform_device *pdev)
 {
+	struct snd_soc_card *card = &t5325;
 	int ret;
 
-	if (!machine_is_t5325())
-		return 0;
-
-	t5325_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!t5325_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(t5325_snd_device,
-			&t5325);
-
-	ret = platform_device_add(t5325_snd_device);
-	if (ret) {
-		printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
-		platform_device_put(t5325_snd_device);
-	}
+	card->dev = &pdev->dev;
 
+	ret = snd_soc_register_card(card);
+	if (ret)
+		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+			ret);
 	return ret;
 }
-module_init(t5325_init);
 
-static void __exit t5325_exit(void)
+static int __devexit t5325_remove(struct platform_device *pdev)
 {
-	platform_device_unregister(t5325_snd_device);
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+	return 0;
 }
-module_exit(t5325_exit);
+
+static struct platform_driver t5325_driver = {
+	.driver		= {
+		.name	= "t5325-audio",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= t5325_probe,
+	.remove		= __devexit_p(t5325_remove),
+};
+
+module_platform_driver(t5325_driver);
 
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:t5325-audio");
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 6f77eef..2937e54 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -235,7 +235,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
 	snd_soc_dapm_enable_pin(dapm, "Headphones");
 	snd_soc_dapm_enable_pin(dapm, "Mic");
 
-	ret_val = snd_soc_add_controls(codec, mfld_snd_controls,
+	ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls,
 				ARRAY_SIZE(mfld_snd_controls));
 	if (ret_val) {
 		pr_err("soc_add_controls failed %d", ret_val);
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
index e4ba8d5..21d20f3 100644
--- a/sound/soc/mxs/Kconfig
+++ b/sound/soc/mxs/Kconfig
@@ -1,7 +1,6 @@
 menuconfig SND_MXS_SOC
 	tristate "SoC Audio for Freescale MXS CPUs"
 	depends on ARCH_MXS
-	select SND_PCM
 	help
 	  Say Y or M if you want to add support for codecs attached to
 	  the MXS SAIF interface.
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 105f42a..06c18ec 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -119,19 +119,14 @@ static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	chan = iprtd->dma_chan;
 
-	iprtd->size = params_buffer_bytes(params);
 	iprtd->periods = params_periods(params);
 	iprtd->period_bytes = params_period_bytes(params);
 	iprtd->offset = 0;
-	iprtd->period_time = HZ / (params_rate(params) /
-			params_period_size(params));
 
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
 	dma_addr = runtime->dma_addr;
 
-	iprtd->buf = substream->dma_buffer.area;
-
 	iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
 			iprtd->period_bytes * iprtd->periods,
 			iprtd->period_bytes,
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index f55ac4f..ba75e10 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -29,11 +29,7 @@ struct mxs_pcm_dma_params {
 struct mxs_pcm_runtime_data {
 	int period_bytes;
 	int periods;
-	int dma;
 	unsigned long offset;
-	unsigned long size;
-	void *buf;
-	int period_time;
 	struct dma_async_tx_descriptor *desc;
 	struct dma_chan *dma_chan;
 	struct mxs_dma_data dma_data;
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index f204dba..12be05b 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -630,7 +630,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
 	if (pdev->id >= ARRAY_SIZE(mxs_saif))
 		return -EINVAL;
 
-	saif = kzalloc(sizeof(*saif), GFP_KERNEL);
+	saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
 	if (!saif)
 		return -ENOMEM;
 
@@ -655,29 +655,16 @@ static int mxs_saif_probe(struct platform_device *pdev)
 		ret = PTR_ERR(saif->clk);
 		dev_err(&pdev->dev, "Cannot get the clock: %d\n",
 			ret);
-		goto failed_clk;
+		return ret;
 	}
 
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!iores) {
-		ret = -ENODEV;
-		dev_err(&pdev->dev, "failed to get io resource: %d\n",
-			ret);
-		goto failed_get_resource;
-	}
 
-	if (!request_mem_region(iores->start, resource_size(iores),
-				"mxs-saif")) {
-		dev_err(&pdev->dev, "request_mem_region failed\n");
-		ret = -EBUSY;
-		goto failed_get_resource;
-	}
-
-	saif->base = ioremap(iores->start, resource_size(iores));
+	saif->base = devm_request_and_ioremap(&pdev->dev, iores);
 	if (!saif->base) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -ENODEV;
-		goto failed_ioremap;
+		goto failed_get_resource;
 	}
 
 	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -685,7 +672,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
 		ret = -ENODEV;
 		dev_err(&pdev->dev, "failed to get dma resource: %d\n",
 			ret);
-		goto failed_ioremap;
+		goto failed_get_resource;
 	}
 	saif->dma_param.chan_num = dmares->start;
 
@@ -694,14 +681,15 @@ static int mxs_saif_probe(struct platform_device *pdev)
 		ret = saif->irq;
 		dev_err(&pdev->dev, "failed to get irq resource: %d\n",
 			ret);
-		goto failed_get_irq1;
+		goto failed_get_resource;
 	}
 
 	saif->dev = &pdev->dev;
-	ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif);
+	ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0,
+			       "mxs-saif", saif);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
-		goto failed_get_irq1;
+		goto failed_get_resource;
 	}
 
 	saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
@@ -709,7 +697,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
 		ret = saif->dma_param.chan_irq;
 		dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
 			ret);
-		goto failed_get_irq2;
+		goto failed_get_resource;
 	}
 
 	platform_set_drvdata(pdev, saif);
@@ -717,7 +705,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
 	ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
 	if (ret) {
 		dev_err(&pdev->dev, "register DAI failed\n");
-		goto failed_register;
+		goto failed_get_resource;
 	}
 
 	saif->soc_platform_pdev = platform_device_alloc(
@@ -740,36 +728,19 @@ failed_pdev_add:
 	platform_device_put(saif->soc_platform_pdev);
 failed_pdev_alloc:
 	snd_soc_unregister_dai(&pdev->dev);
-failed_register:
-failed_get_irq2:
-	free_irq(saif->irq, saif);
-failed_get_irq1:
-	iounmap(saif->base);
-failed_ioremap:
-	release_mem_region(iores->start, resource_size(iores));
 failed_get_resource:
 	clk_put(saif->clk);
-failed_clk:
-	kfree(saif);
 
 	return ret;
 }
 
 static int __devexit mxs_saif_remove(struct platform_device *pdev)
 {
-	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct mxs_saif *saif = platform_get_drvdata(pdev);
 
 	platform_device_unregister(saif->soc_platform_pdev);
-
 	snd_soc_unregister_dai(&pdev->dev);
-
-	iounmap(saif->base);
-	release_mem_region(res->start, resource_size(res));
-	free_irq(saif->irq, saif);
-
 	clk_put(saif->clk);
-	kfree(saif);
 
 	return 0;
 }
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index fb1bf25..47b23fe 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -97,16 +97,19 @@ config SND_OMAP_SOC_SDP3430
 	  Say Y if you want to add support for SoC audio on Texas Instruments
 	  SDP3430.
 
-config SND_OMAP_SOC_SDP4430
-	tristate "SoC Audio support for Texas Instruments SDP4430"
-	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP
+config SND_OMAP_SOC_OMAP_ABE_TWL6040
+	tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
+	depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4
 	select SND_OMAP_SOC_DMIC
 	select SND_OMAP_SOC_MCPDM
 	select SND_SOC_TWL6040
 	select SND_SOC_DMIC
 	help
-	  Say Y if you want to add support for SoC audio on Texas Instruments
-	  SDP4430.
+	  Say Y if you want to add support for SoC audio on OMAP boards using
+	  ABE and twl6040 codec. This driver currently supports:
+	  - SDP4430/Blaze boards
+	  - PandaBoard (4430)
+	  - PandaBoardES (4460)
 
 config SND_OMAP_SOC_OMAP4_HDMI
 	tristate "SoC Audio support for Texas Instruments OMAP4 HDMI"
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 1fd723f..123ac18 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -20,7 +20,7 @@ snd-soc-overo-objs := overo.o
 snd-soc-omap3evm-objs := omap3evm.o
 snd-soc-am3517evm-objs := am3517evm.o
 snd-soc-sdp3430-objs := sdp3430.o
-snd-soc-sdp4430-objs := sdp4430.o
+snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
 snd-soc-omap3pandora-objs := omap3pandora.o
 snd-soc-omap3beagle-objs := omap3beagle.o
 snd-soc-zoom2-objs := zoom2.o
@@ -36,7 +36,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
 obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
 obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
-obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o
+obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
 obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index a67f437..78563bb 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -570,7 +570,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
 	snd_soc_dapm_disable_pin(dapm, "AGCOUT");
 
 	/* Add virtual switch */
-	ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
+	ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls,
 					ARRAY_SIZE(ams_delta_audio_controls));
 	if (ret)
 		dev_warn(card->dev,
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 597be41..c292bf0 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -55,9 +55,8 @@ static int n810_spk_func;
 static int n810_jack_func;
 static int n810_dmic_func;
 
-static void n810_ext_control(struct snd_soc_codec *codec)
+static void n810_ext_control(struct snd_soc_dapm_context *dapm)
 {
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int hp = 0, line1l = 0;
 
 	switch (n810_jack_func) {
@@ -102,7 +101,7 @@ static int n810_startup(struct snd_pcm_substream *substream)
 	snd_pcm_hw_constraint_minmax(runtime,
 				     SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
 
-	n810_ext_control(codec);
+	n810_ext_control(&codec->dapm);
 	return clk_enable(sys_clkout2);
 }
 
@@ -142,13 +141,13 @@ static int n810_get_spk(struct snd_kcontrol *kcontrol,
 static int n810_set_spk(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card =  snd_kcontrol_chip(kcontrol);
 
 	if (n810_spk_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	n810_spk_func = ucontrol->value.integer.value[0];
-	n810_ext_control(codec);
+	n810_ext_control(&card->dapm);
 
 	return 1;
 }
@@ -164,13 +163,13 @@ static int n810_get_jack(struct snd_kcontrol *kcontrol,
 static int n810_set_jack(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card =  snd_kcontrol_chip(kcontrol);
 
 	if (n810_jack_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	n810_jack_func = ucontrol->value.integer.value[0];
-	n810_ext_control(codec);
+	n810_ext_control(&card->dapm);
 
 	return 1;
 }
@@ -186,13 +185,13 @@ static int n810_get_input(struct snd_kcontrol *kcontrol,
 static int n810_set_input(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card =  snd_kcontrol_chip(kcontrol);
 
 	if (n810_dmic_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	n810_dmic_func = ucontrol->value.integer.value[0];
-	n810_ext_control(codec);
+	n810_ext_control(&card->dapm);
 
 	return 1;
 }
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
new file mode 100644
index 0000000..93bb8ee
--- /dev/null
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -0,0 +1,349 @@
+/*
+ * omap-abe-twl6040.c  --  SoC audio for TI OMAP based boards with ABE and
+ *			   twl6040 codec
+ *
+ * Author: Misael Lopez Cruz <misael.lopez@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/twl6040.h>
+#include <linux/platform_data/omap-abe-twl6040.h>
+#include <linux/module.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/jack.h>
+
+#include <asm/mach-types.h>
+#include <plat/hardware.h>
+#include <plat/mux.h>
+
+#include "omap-dmic.h"
+#include "omap-mcpdm.h"
+#include "omap-pcm.h"
+#include "../codecs/twl6040.h"
+
+static int omap_abe_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_card *card = codec->card;
+	struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
+	int clk_id, freq;
+	int ret;
+
+	clk_id = twl6040_get_clk_id(rtd->codec);
+	if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
+		freq = pdata->mclk_freq;
+	else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
+		freq = 32768;
+	else
+		return -EINVAL;
+
+	/* set the codec mclk */
+	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
+				SND_SOC_CLOCK_IN);
+	if (ret) {
+		printk(KERN_ERR "can't set codec system clock\n");
+		return ret;
+	}
+	return ret;
+}
+
+static struct snd_soc_ops omap_abe_ops = {
+	.hw_params = omap_abe_hw_params,
+};
+
+static int omap_abe_dmic_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	int ret = 0;
+
+	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
+				     19200000, SND_SOC_CLOCK_IN);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set DMIC cpu system clock\n");
+		return ret;
+	}
+	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
+				     SND_SOC_CLOCK_OUT);
+	if (ret < 0) {
+		printk(KERN_ERR "can't set DMIC output clock\n");
+		return ret;
+	}
+	return 0;
+}
+
+static struct snd_soc_ops omap_abe_dmic_ops = {
+	.hw_params = omap_abe_dmic_hw_params,
+};
+
+/* Headset jack */
+static struct snd_soc_jack hs_jack;
+
+/*Headset jack detection DAPM pins */
+static struct snd_soc_jack_pin hs_jack_pins[] = {
+	{
+		.pin = "Headset Mic",
+		.mask = SND_JACK_MICROPHONE,
+	},
+	{
+		.pin = "Headset Stereophone",
+		.mask = SND_JACK_HEADPHONE,
+	},
+};
+
+/* SDP4430 machine DAPM */
+static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
+	/* Outputs */
+	SND_SOC_DAPM_HP("Headset Stereophone", NULL),
+	SND_SOC_DAPM_SPK("Earphone Spk", NULL),
+	SND_SOC_DAPM_SPK("Ext Spk", NULL),
+	SND_SOC_DAPM_LINE("Line Out", NULL),
+	SND_SOC_DAPM_SPK("Vibrator", NULL),
+
+	/* Inputs */
+	SND_SOC_DAPM_MIC("Headset Mic", NULL),
+	SND_SOC_DAPM_MIC("Main Handset Mic", NULL),
+	SND_SOC_DAPM_MIC("Sub Handset Mic", NULL),
+	SND_SOC_DAPM_LINE("Line In", NULL),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+	/* Routings for outputs */
+	{"Headset Stereophone", NULL, "HSOL"},
+	{"Headset Stereophone", NULL, "HSOR"},
+
+	{"Earphone Spk", NULL, "EP"},
+
+	{"Ext Spk", NULL, "HFL"},
+	{"Ext Spk", NULL, "HFR"},
+
+	{"Line Out", NULL, "AUXL"},
+	{"Line Out", NULL, "AUXR"},
+
+	{"Vibrator", NULL, "VIBRAL"},
+	{"Vibrator", NULL, "VIBRAR"},
+
+	/* Routings for inputs */
+	{"HSMIC", NULL, "Headset Mic"},
+	{"Headset Mic", NULL, "Headset Mic Bias"},
+
+	{"MAINMIC", NULL, "Main Handset Mic"},
+	{"Main Handset Mic", NULL, "Main Mic Bias"},
+
+	{"SUBMIC", NULL, "Sub Handset Mic"},
+	{"Sub Handset Mic", NULL, "Main Mic Bias"},
+
+	{"AFML", NULL, "Line In"},
+	{"AFMR", NULL, "Line In"},
+};
+
+static inline void twl6040_disconnect_pin(struct snd_soc_dapm_context *dapm,
+					  int connected, char *pin)
+{
+	if (!connected)
+		snd_soc_dapm_disable_pin(dapm, pin);
+}
+
+static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_card *card = codec->card;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
+	int hs_trim;
+	int ret = 0;
+
+	/* Disable not connected paths if not used */
+	twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
+	twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
+	twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
+	twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
+	twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
+	twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
+	twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
+	twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
+	twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
+
+	/*
+	 * Configure McPDM offset cancellation based on the HSOTRIM value from
+	 * twl6040.
+	 */
+	hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
+	omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
+					TWL6040_HSF_TRIM_RIGHT(hs_trim));
+
+	/* Headset jack detection only if it is supported */
+	if (pdata->jack_detection) {
+		ret = snd_soc_jack_new(codec, "Headset Jack",
+					SND_JACK_HEADSET, &hs_jack);
+		if (ret)
+			return ret;
+
+		ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
+					hs_jack_pins);
+		twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
+	}
+
+	return ret;
+}
+
+static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
+	SND_SOC_DAPM_MIC("Digital Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route dmic_audio_map[] = {
+	{"DMic", NULL, "Digital Mic"},
+	{"Digital Mic", NULL, "Digital Mic1 Bias"},
+};
+
+static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	int ret;
+
+	ret = snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
+				ARRAY_SIZE(dmic_dapm_widgets));
+	if (ret)
+		return ret;
+
+	return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
+				ARRAY_SIZE(dmic_audio_map));
+}
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link twl6040_dmic_dai[] = {
+	{
+		.name = "TWL6040",
+		.stream_name = "TWL6040",
+		.cpu_dai_name = "omap-mcpdm",
+		.codec_dai_name = "twl6040-legacy",
+		.platform_name = "omap-pcm-audio",
+		.codec_name = "twl6040-codec",
+		.init = omap_abe_twl6040_init,
+		.ops = &omap_abe_ops,
+	},
+	{
+		.name = "DMIC",
+		.stream_name = "DMIC Capture",
+		.cpu_dai_name = "omap-dmic",
+		.codec_dai_name = "dmic-hifi",
+		.platform_name = "omap-pcm-audio",
+		.codec_name = "dmic-codec",
+		.init = omap_abe_dmic_init,
+		.ops = &omap_abe_dmic_ops,
+	},
+};
+
+static struct snd_soc_dai_link twl6040_only_dai[] = {
+	{
+		.name = "TWL6040",
+		.stream_name = "TWL6040",
+		.cpu_dai_name = "omap-mcpdm",
+		.codec_dai_name = "twl6040-legacy",
+		.platform_name = "omap-pcm-audio",
+		.codec_name = "twl6040-codec",
+		.init = omap_abe_twl6040_init,
+		.ops = &omap_abe_ops,
+	},
+};
+
+/* Audio machine driver */
+static struct snd_soc_card omap_abe_card = {
+	.owner = THIS_MODULE,
+
+	.dapm_widgets = twl6040_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets),
+	.dapm_routes = audio_map,
+	.num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+static __devinit int omap_abe_probe(struct platform_device *pdev)
+{
+	struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
+	struct snd_soc_card *card = &omap_abe_card;
+	int ret;
+
+	card->dev = &pdev->dev;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Missing pdata\n");
+		return -ENODEV;
+	}
+
+	if (pdata->card_name) {
+		card->name = pdata->card_name;
+	} else {
+		dev_err(&pdev->dev, "Card name is not provided\n");
+		return -ENODEV;
+	}
+
+	if (!pdata->mclk_freq) {
+		dev_err(&pdev->dev, "MCLK frequency missing\n");
+		return -ENODEV;
+	}
+
+	if (pdata->has_dmic) {
+		card->dai_link = twl6040_dmic_dai;
+		card->num_links = ARRAY_SIZE(twl6040_dmic_dai);
+	} else {
+		card->dai_link = twl6040_only_dai;
+		card->num_links = ARRAY_SIZE(twl6040_only_dai);
+	}
+
+	ret = snd_soc_register_card(card);
+	if (ret)
+		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+			ret);
+
+	return ret;
+}
+
+static int __devexit omap_abe_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+
+	return 0;
+}
+
+static struct platform_driver omap_abe_driver = {
+	.driver = {
+		.name = "omap-abe-twl6040",
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+	},
+	.probe = omap_abe_probe,
+	.remove = __devexit_p(omap_abe_remove),
+};
+
+module_platform_driver(omap_abe_driver);
+
+MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
+MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap-abe-twl6040");
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 0855c1c..4dcb5a7 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -113,12 +113,10 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream,
 
 	mutex_lock(&dmic->mutex);
 
-	if (!dai->active) {
-		snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
+	if (!dai->active)
 		dmic->active = 1;
-	} else {
+	else
 		ret = -EBUSY;
-	}
 
 	mutex_unlock(&dmic->mutex);
 
@@ -445,6 +443,7 @@ static struct snd_soc_dai_driver omap_dmic_dai = {
 		.channels_max = 6,
 		.rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
 		.formats = SNDRV_PCM_FMTBIT_S32_LE,
+		.sig_bits = 24,
 	},
 	.ops = &omap_dmic_dai_ops,
 };
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 0173719..1287b87 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -744,17 +744,17 @@ static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
 				      omap_mcbsp3_set_st_ch1_volume),
 };
 
-int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id)
+int omap_mcbsp_st_add_controls(struct snd_soc_dai *dai)
 {
 	if (!cpu_is_omap34xx())
 		return -ENODEV;
 
-	switch (mcbsp_id) {
+	switch (dai->id) {
 	case 1: /* McBSP 2 */
-		return snd_soc_add_controls(codec, omap_mcbsp2_st_controls,
+		return snd_soc_add_dai_controls(dai, omap_mcbsp2_st_controls,
 					ARRAY_SIZE(omap_mcbsp2_st_controls));
 	case 2: /* McBSP 3 */
-		return snd_soc_add_controls(codec, omap_mcbsp3_st_controls,
+		return snd_soc_add_dai_controls(dai, omap_mcbsp3_st_controls,
 					ARRAY_SIZE(omap_mcbsp3_st_controls));
 	default:
 		break;
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index 65cde9d..476fe2a 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -59,6 +59,6 @@ enum omap_mcbsp_div {
 #define NUM_LINKS	5
 #endif
 
-int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id);
+int omap_mcbsp_st_add_controls(struct snd_soc_dai *dai);
 
 #endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 0e25df4..3970556 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -419,12 +419,14 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = {
 		.channels_max = 5,
 		.rates = OMAP_MCPDM_RATES,
 		.formats = OMAP_MCPDM_FORMATS,
+		.sig_bits = 24,
 	},
 	.capture = {
 		.channels_min = 1,
 		.channels_max = 3,
 		.rates = OMAP_MCPDM_RATES,
 		.formats = OMAP_MCPDM_FORMATS,
+		.sig_bits = 24,
 	},
 	.ops = &omap_mcpdm_dai_ops,
 };
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index fada6ef..58936c7 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -59,9 +59,8 @@ static int rx51_spk_func;
 static int rx51_dmic_func;
 static int rx51_jack_func;
 
-static void rx51_ext_control(struct snd_soc_codec *codec)
+static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
 {
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	int hp = 0, hs = 0, tvout = 0;
 
 	switch (rx51_jack_func) {
@@ -102,11 +101,11 @@ static int rx51_startup(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_card *card = rtd->card;
 
 	snd_pcm_hw_constraint_minmax(runtime,
 				     SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
-	rx51_ext_control(codec);
+	rx51_ext_control(&card->dapm);
 
 	return 0;
 }
@@ -138,13 +137,13 @@ static int rx51_get_spk(struct snd_kcontrol *kcontrol,
 static int rx51_set_spk(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 
 	if (rx51_spk_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	rx51_spk_func = ucontrol->value.integer.value[0];
-	rx51_ext_control(codec);
+	rx51_ext_control(&card->dapm);
 
 	return 1;
 }
@@ -184,13 +183,13 @@ static int rx51_get_input(struct snd_kcontrol *kcontrol,
 static int rx51_set_input(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 
 	if (rx51_dmic_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	rx51_dmic_func = ucontrol->value.integer.value[0];
-	rx51_ext_control(codec);
+	rx51_ext_control(&card->dapm);
 
 	return 1;
 }
@@ -206,13 +205,13 @@ static int rx51_get_jack(struct snd_kcontrol *kcontrol,
 static int rx51_set_jack(struct snd_kcontrol *kcontrol,
 			 struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 
 	if (rx51_jack_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	rx51_jack_func = ucontrol->value.integer.value[0];
-	rx51_ext_control(codec);
+	rx51_ext_control(&card->dapm);
 
 	return 1;
 }
@@ -297,7 +296,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
 	snd_soc_dapm_nc_pin(dapm, "LINE1R");
 
 	/* Add RX-51 specific controls */
-	err = snd_soc_add_controls(codec, aic34_rx51_controls,
+	err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls,
 				   ARRAY_SIZE(aic34_rx51_controls));
 	if (err < 0)
 		return err;
@@ -314,7 +313,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
 		return err;
 	snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
 
-	err = omap_mcbsp_st_add_controls(codec, 1);
+	err = omap_mcbsp_st_add_controls(rtd->cpu_dai);
 	if (err < 0)
 		return err;
 
@@ -335,7 +334,7 @@ static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
 {
 	int err;
 
-	err = snd_soc_add_controls(dapm->codec, aic34_rx51_controlsb,
+	err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb,
 				   ARRAY_SIZE(aic34_rx51_controlsb));
 	if (err < 0)
 		return err;
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
deleted file mode 100644
index 175ba9a..0000000
--- a/sound/soc/omap/sdp4430.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * sdp4430.c  --  SoC audio for TI OMAP4430 SDP
- *
- * Author: Misael Lopez Cruz <x0052729@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/twl6040.h>
-#include <linux/module.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/jack.h>
-
-#include <asm/mach-types.h>
-#include <plat/hardware.h>
-#include <plat/mux.h>
-
-#include "omap-dmic.h"
-#include "omap-mcpdm.h"
-#include "omap-pcm.h"
-#include "../codecs/twl6040.h"
-
-static int sdp4430_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int clk_id, freq;
-	int ret;
-
-	clk_id = twl6040_get_clk_id(rtd->codec);
-	if (clk_id == TWL6040_SYSCLK_SEL_HPPLL)
-		freq = 38400000;
-	else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL)
-		freq = 32768;
-	else
-		return -EINVAL;
-
-	/* set the codec mclk */
-	ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq,
-				SND_SOC_CLOCK_IN);
-	if (ret) {
-		printk(KERN_ERR "can't set codec system clock\n");
-		return ret;
-	}
-	return ret;
-}
-
-static struct snd_soc_ops sdp4430_ops = {
-	.hw_params = sdp4430_hw_params,
-};
-
-static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	int ret = 0;
-
-	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS,
-				     19200000, SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set DMIC cpu system clock\n");
-		return ret;
-	}
-	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000,
-				     SND_SOC_CLOCK_OUT);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set DMIC output clock\n");
-		return ret;
-	}
-	return 0;
-}
-
-static struct snd_soc_ops sdp4430_dmic_ops = {
-	.hw_params = sdp4430_dmic_hw_params,
-};
-
-/* Headset jack */
-static struct snd_soc_jack hs_jack;
-
-/*Headset jack detection DAPM pins */
-static struct snd_soc_jack_pin hs_jack_pins[] = {
-	{
-		.pin = "Headset Mic",
-		.mask = SND_JACK_MICROPHONE,
-	},
-	{
-		.pin = "Headset Stereophone",
-		.mask = SND_JACK_HEADPHONE,
-	},
-};
-
-/* SDP4430 machine DAPM */
-static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
-	SND_SOC_DAPM_MIC("Ext Mic", NULL),
-	SND_SOC_DAPM_SPK("Ext Spk", NULL),
-	SND_SOC_DAPM_MIC("Headset Mic", NULL),
-	SND_SOC_DAPM_HP("Headset Stereophone", NULL),
-	SND_SOC_DAPM_SPK("Earphone Spk", NULL),
-	SND_SOC_DAPM_INPUT("FM Stereo In"),
-};
-
-static const struct snd_soc_dapm_route audio_map[] = {
-	/* External Mics: MAINMIC, SUBMIC with bias*/
-	{"MAINMIC", NULL, "Main Mic Bias"},
-	{"SUBMIC", NULL, "Main Mic Bias"},
-	{"Main Mic Bias", NULL, "Ext Mic"},
-
-	/* External Speakers: HFL, HFR */
-	{"Ext Spk", NULL, "HFL"},
-	{"Ext Spk", NULL, "HFR"},
-
-	/* Headset Mic: HSMIC with bias */
-	{"HSMIC", NULL, "Headset Mic Bias"},
-	{"Headset Mic Bias", NULL, "Headset Mic"},
-
-	/* Headset Stereophone (Headphone): HSOL, HSOR */
-	{"Headset Stereophone", NULL, "HSOL"},
-	{"Headset Stereophone", NULL, "HSOR"},
-
-	/* Earphone speaker */
-	{"Earphone Spk", NULL, "EP"},
-
-	/* Aux/FM Stereo In: AFML, AFMR */
-	{"AFML", NULL, "FM Stereo In"},
-	{"AFMR", NULL, "FM Stereo In"},
-};
-
-static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_codec *codec = rtd->codec;
-	int ret, hs_trim;
-
-	/*
-	 * Configure McPDM offset cancellation based on the HSOTRIM value from
-	 * twl6040.
-	 */
-	hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM);
-	omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim),
-					TWL6040_HSF_TRIM_RIGHT(hs_trim));
-
-	/* Headset jack detection */
-	ret = snd_soc_jack_new(codec, "Headset Jack",
-				SND_JACK_HEADSET, &hs_jack);
-	if (ret)
-		return ret;
-
-	ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
-				hs_jack_pins);
-
-	if (machine_is_omap_4430sdp())
-		twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
-	else
-		snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET);
-
-	return ret;
-}
-
-static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = {
-	SND_SOC_DAPM_MIC("Digital Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route dmic_audio_map[] = {
-	{"DMic", NULL, "Digital Mic1 Bias"},
-	{"Digital Mic1 Bias", NULL, "Digital Mic"},
-};
-
-static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd)
-{
-	struct snd_soc_codec *codec = rtd->codec;
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-	int ret;
-
-	ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets,
-				ARRAY_SIZE(sdp4430_dmic_dapm_widgets));
-	if (ret)
-		return ret;
-
-	return snd_soc_dapm_add_routes(dapm, dmic_audio_map,
-				ARRAY_SIZE(dmic_audio_map));
-}
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link sdp4430_dai[] = {
-	{
-		.name = "TWL6040",
-		.stream_name = "TWL6040",
-		.cpu_dai_name = "omap-mcpdm",
-		.codec_dai_name = "twl6040-legacy",
-		.platform_name = "omap-pcm-audio",
-		.codec_name = "twl6040-codec",
-		.init = sdp4430_twl6040_init,
-		.ops = &sdp4430_ops,
-	},
-	{
-		.name = "DMIC",
-		.stream_name = "DMIC Capture",
-		.cpu_dai_name = "omap-dmic",
-		.codec_dai_name = "dmic-hifi",
-		.platform_name = "omap-pcm-audio",
-		.codec_name = "dmic-codec",
-		.init = sdp4430_dmic_init,
-		.ops = &sdp4430_dmic_ops,
-	},
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_sdp4430 = {
-	.name = "SDP4430",
-	.owner = THIS_MODULE,
-	.dai_link = sdp4430_dai,
-	.num_links = ARRAY_SIZE(sdp4430_dai),
-
-	.dapm_widgets = sdp4430_twl6040_dapm_widgets,
-	.num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets),
-	.dapm_routes = audio_map,
-	.num_dapm_routes = ARRAY_SIZE(audio_map),
-};
-
-static struct platform_device *sdp4430_snd_device;
-
-static int __init sdp4430_soc_init(void)
-{
-	int ret;
-
-	if (!machine_is_omap_4430sdp())
-		return -ENODEV;
-	printk(KERN_INFO "SDP4430 SoC init\n");
-
-	sdp4430_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!sdp4430_snd_device) {
-		printk(KERN_ERR "Platform device allocation failed\n");
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430);
-
-	ret = platform_device_add(sdp4430_snd_device);
-	if (ret)
-		goto err;
-
-	return 0;
-
-err:
-	printk(KERN_ERR "Unable to add platform device\n");
-	platform_device_put(sdp4430_snd_device);
-	return ret;
-}
-module_init(sdp4430_soc_init);
-
-static void __exit sdp4430_soc_exit(void)
-{
-	platform_device_unregister(sdp4430_snd_device);
-}
-module_exit(sdp4430_soc_exit);
-
-MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC SDP4430");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index bc21944..863367a 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -45,10 +45,8 @@
 static int corgi_jack_func;
 static int corgi_spk_func;
 
-static void corgi_ext_control(struct snd_soc_codec *codec)
+static void corgi_ext_control(struct snd_soc_dapm_context *dapm)
 {
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
 	/* set up jack connection */
 	switch (corgi_jack_func) {
 	case CORGI_HP:
@@ -104,7 +102,7 @@ static int corgi_startup(struct snd_pcm_substream *substream)
 	mutex_lock(&codec->mutex);
 
 	/* check the jack status at stream startup */
-	corgi_ext_control(codec);
+	corgi_ext_control(&codec->dapm);
 
 	mutex_unlock(&codec->mutex);
 
@@ -173,13 +171,13 @@ static int corgi_get_jack(struct snd_kcontrol *kcontrol,
 static int corgi_set_jack(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 
 	if (corgi_jack_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	corgi_jack_func = ucontrol->value.integer.value[0];
-	corgi_ext_control(codec);
+	corgi_ext_control(&card->dapm);
 	return 1;
 }
 
@@ -193,13 +191,13 @@ static int corgi_get_spk(struct snd_kcontrol *kcontrol,
 static int corgi_set_spk(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card =  snd_kcontrol_chip(kcontrol);
 
 	if (corgi_spk_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	corgi_spk_func = ucontrol->value.integer.value[0];
-	corgi_ext_control(codec);
+	corgi_ext_control(&card->dapm);
 	return 1;
 }
 
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 3f7a8ec..aace19e 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -411,7 +411,7 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
 	snd_soc_dapm_nc_pin(dapm, "VINR");
 
 	/* Add magician specific controls */
-	err = snd_soc_add_controls(codec, uda1380_magician_controls,
+	err = snd_soc_add_codec_controls(codec, uda1380_magician_controls,
 				ARRAY_SIZE(uda1380_magician_controls));
 	if (err < 0)
 		return err;
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index fd0ed10..d2cc8173 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -43,10 +43,8 @@
 static int poodle_jack_func;
 static int poodle_spk_func;
 
-static void poodle_ext_control(struct snd_soc_codec *codec)
+static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
 {
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
 	/* set up jack connection */
 	if (poodle_jack_func == POODLE_HP) {
 		/* set = unmute headphone */
@@ -81,7 +79,7 @@ static int poodle_startup(struct snd_pcm_substream *substream)
 	mutex_lock(&codec->mutex);
 
 	/* check the jack status at stream startup */
-	poodle_ext_control(codec);
+	poodle_ext_control(&codec->dapm);
 
 	mutex_unlock(&codec->mutex);
 
@@ -152,13 +150,13 @@ static int poodle_get_jack(struct snd_kcontrol *kcontrol,
 static int poodle_set_jack(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card =  snd_kcontrol_chip(kcontrol);
 
 	if (poodle_jack_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	poodle_jack_func = ucontrol->value.integer.value[0];
-	poodle_ext_control(codec);
+	poodle_ext_control(&card->dapm);
 	return 1;
 }
 
@@ -172,13 +170,13 @@ static int poodle_get_spk(struct snd_kcontrol *kcontrol,
 static int poodle_set_spk(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card =  snd_kcontrol_chip(kcontrol);
 
 	if (poodle_spk_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	poodle_spk_func = ucontrol->value.integer.value[0];
-	poodle_ext_control(codec);
+	poodle_ext_control(&card->dapm);
 	return 1;
 }
 
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 837ff34..4800d5f 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -103,7 +103,7 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
 #define pxa2xx_ac97_resume	NULL
 #endif
 
-static int pxa2xx_ac97_probe(struct snd_soc_dai *dai)
+static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai)
 {
 	return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev));
 }
@@ -179,7 +179,7 @@ static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
  * There is only 1 physical AC97 interface for pxa2xx, but it
  * has extra fifo's that can be used for aux DACs and ADCs.
  */
-static struct snd_soc_dai_driver pxa_ac97_dai[] = {
+static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = {
 {
 	.name = "pxa2xx-ac97",
 	.ac97_control = 1,
@@ -244,13 +244,13 @@ static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev)
 	 * driver to do interesting things with the clocking to get us up
 	 * and running.
 	 */
-	return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai,
-			ARRAY_SIZE(pxa_ac97_dai));
+	return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver,
+			ARRAY_SIZE(pxa_ac97_dai_driver));
 }
 
 static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev)
 {
-	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai));
+	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver));
 	return 0;
 }
 
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 90c5245..fc052d8 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -44,10 +44,8 @@ static int spitz_jack_func;
 static int spitz_spk_func;
 static int spitz_mic_gpio;
 
-static void spitz_ext_control(struct snd_soc_codec *codec)
+static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
 {
-	struct snd_soc_dapm_context *dapm = &codec->dapm;
-
 	if (spitz_spk_func == SPITZ_SPK_ON)
 		snd_soc_dapm_enable_pin(dapm, "Ext Spk");
 	else
@@ -113,7 +111,7 @@ static int spitz_startup(struct snd_pcm_substream *substream)
 	mutex_lock(&codec->mutex);
 
 	/* check the jack status at stream startup */
-	spitz_ext_control(codec);
+	spitz_ext_control(&codec->dapm);
 
 	mutex_unlock(&codec->mutex);
 
@@ -173,13 +171,13 @@ static int spitz_get_jack(struct snd_kcontrol *kcontrol,
 static int spitz_set_jack(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 
 	if (spitz_jack_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	spitz_jack_func = ucontrol->value.integer.value[0];
-	spitz_ext_control(codec);
+	spitz_ext_control(&card->dapm);
 	return 1;
 }
 
@@ -193,13 +191,13 @@ static int spitz_get_spk(struct snd_kcontrol *kcontrol,
 static int spitz_set_spk(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 
 	if (spitz_spk_func == ucontrol->value.integer.value[0])
 		return 0;
 
 	spitz_spk_func = ucontrol->value.integer.value[0];
-	spitz_ext_control(codec);
+	spitz_ext_control(&card->dapm);
 	return 1;
 }
 
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 564ef08..2aec63f 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -197,7 +197,7 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
 	snd_soc_dapm_nc_pin(dapm, "MONOOUT");
 
 	/* add tosa specific controls */
-	err = snd_soc_add_controls(codec, tosa_controls,
+	err = snd_soc_add_codec_controls(codec, tosa_controls,
 				ARRAY_SIZE(tosa_controls));
 	if (err < 0)
 		return err;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 43c014f..716da86 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -435,7 +435,8 @@ static void s6000_pcm_free(struct snd_pcm *pcm)
 {
 	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
 	struct s6000_pcm_dma_params *params =
-		snd_soc_dai_get_dma_data(runtime->cpu_dai, pcm->streams[0].substream);
+		snd_soc_dai_get_dma_data(runtime->cpu_dai,
+			pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
 
 	free_irq(params->irq, pcm);
 	snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -451,7 +452,7 @@ static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime)
 	int res;
 
 	params = snd_soc_dai_get_dma_data(runtime->cpu_dai,
-			pcm->streams[0].substream);
+			pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream);
 
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &s6000_pcm_dmamask;
diff --git a/sound/soc/sa11x0/Kconfig b/sound/soc/sa11x0/Kconfig
new file mode 100644
index 0000000..f18fe9f
--- /dev/null
+++ b/sound/soc/sa11x0/Kconfig
@@ -0,0 +1,14 @@
+config SND_SOC_SA11X0_SSP
+	tristate
+	depends on DMA_SA11X0
+	select SND_SOC_DMAENGINE
+
+config SND_SA11X0_ASSABET
+	tristate "SoC Audio support for the Intel Assabet board"
+	depends on SA1100_ASSABET && DMA_SA11X0
+	select SND_SOC_L3
+	select SND_SOC_UDA134X
+	select SND_SOC_SA11X0_SSP
+	help
+	  Enable support for the audio UDA1341 codec found on the Intel
+	  Assabet SA-1110 development board.
diff --git a/sound/soc/sa11x0/Makefile b/sound/soc/sa11x0/Makefile
new file mode 100644
index 0000000..7031c02
--- /dev/null
+++ b/sound/soc/sa11x0/Makefile
@@ -0,0 +1,5 @@
+snd-soc-sa11x0-ssp-objs := sa11x0-ssp.o
+obj-$(CONFIG_SND_SOC_SA11X0_SSP) += snd-soc-sa11x0-ssp.o
+
+snd-soc-sa11x0-assabet-objs := sa11x0-assabet.o
+obj-$(CONFIG_SND_SA11X0_ASSABET) += snd-soc-sa11x0-assabet.o
diff --git a/sound/soc/sa11x0/sa11x0-assabet.c b/sound/soc/sa11x0/sa11x0-assabet.c
new file mode 100644
index 0000000..dc8ad27
--- /dev/null
+++ b/sound/soc/sa11x0/sa11x0-assabet.c
@@ -0,0 +1,432 @@
+/*
+ * SA11x0 Assabet ASoC driver
+ *
+ * Copyright (C) 2012 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The Assabet board uses an unused SDRAM clock output as the source
+ * clock for the UDA1341 audio subsystem.  This clock is supplied to
+ * via a CPLD divider to the SA11x0 GPIO19 (alternately the SSP block
+ * external clock input) and to the UDA1341 as the bit clock.
+ *
+ * As the SSPs TXD,RXD,SFRM,SCLK outputs are not directly compatible
+ * with the UDA1341 input, the CPLD implements logic to provide the
+ * WS (LRCK) signal to the UDA1341, and buffer the RXD and clock signals.
+ *
+ * The UDA1341 is powered by the AUDIO3P3V supply, which can be turned
+ * off.  This tristates the CPLD outputs, preventing power draining
+ * into the UDA1341.  However, revision 4 Assabets do not tristate the
+ * WS signal, and so need to be worked-around to place this at logic 0.
+ *
+ * A side effect of using the SDRAM clock is that this scales with the
+ * core CPU frequency.  Hence, the available sample rate depends on the
+ * CPU clock rate.  At present, we have no logic here to restrict the
+ * requested sample rate; the UDA1341 driver will just fail the preparation.
+ * We rely on userspace (at present) to ask for the correct sample rate.
+ */
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/uda134x.h>
+
+#include <mach/assabet.h>
+#include "sa11x0-ssp.h"
+
+#define GPIO_TXD	10
+#define GPIO_RXD	11
+#define GPIO_SCLK	12
+#define GPIO_SFRM	13
+#define GPIO_L3_DAT	15
+#define GPIO_L3_MODE	17
+#define GPIO_L3_SCK	18
+#define GPIO_CLK	19
+
+/*
+ * The UDA1341 wants a WS (or LRCK), and the Assabet derives this from
+ * the SFRM pulses from the SSP.  Unfortunately, some Assabets have a bug
+ * in the hardware where the WS output from the CPLD remains high even
+ * after the codec is powered down, causing power to drain through the
+ * CPLD to the UDA1341.
+ *
+ * Although the Assabet provides a reset signal to initialize WS to a
+ * known state, this presents two problems: (a) this forces the WS output
+ * high, (b) this signal also resets the UCB1300 device.
+ */
+static void assabet_asoc_uda1341_power(int on)
+{
+	static bool state;
+
+	if (state == !!on)
+		return;
+	state = !!on;
+
+	if (on) {
+		/*
+		 * Enable the power for the UDA1341 before fixing WS.
+		 * Also assert the mute signal.
+		 */
+		ASSABET_BCR_set(ASSABET_BCR_AUDIO_ON | ASSABET_BCR_QMUTE);
+
+		/*
+		 * Toggle SFRM with the codec reset signal held active.
+		 * This will set LRCK high, which results in the left
+		 * sample being transmitted first.
+		 */
+		gpio_set_value(GPIO_SFRM, 1);
+		gpio_set_value(GPIO_SFRM, 0);
+
+		/*
+		 * If the reset was being held, release it now.  This
+		 * ensures that the above SFRM fiddling has no effect
+		 * should the reset be raised elsewhere.
+		 */
+		ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
+	} else {
+		/*
+		 * The SSP will have transmitted a whole number of 32-bit
+		 * words, so we know that LRCK will be left high at this
+		 * point.  Toggle SFRM once to kick the LRCK low before
+		 * powering down the codec.
+		 */
+		gpio_set_value(GPIO_SFRM, 1);
+		gpio_set_value(GPIO_SFRM, 0);
+
+		/* Finally, disable the audio power */
+		ASSABET_BCR_clear(ASSABET_BCR_AUDIO_ON);
+
+		/* And lower the QMUTE signal to stop power draining */
+		ASSABET_BCR_clear(ASSABET_BCR_QMUTE);
+	}
+}
+
+static void assabet_asoc_init_clk(void)
+{
+	u32 mdrefr, mdrefr_old;
+
+	/*
+	 * The assabet board uses the SDRAM clock as the source clock for
+	 * audio. This is supplied to the SA11x0 from the CPLD on pin 19.
+	 * At 206MHz we need to run the audio clock (SDRAM bank 2) at half
+	 * speed.  This clock will scale with core frequency so the audio
+	 * sample rate will also scale. The CPLD on Assabet will need to
+	 * be programmed to match the core frequency.
+	 */
+	mdrefr_old = MDREFR;
+	mdrefr = mdrefr_old & ~(MDREFR_EAPD | MDREFR_KAPD);
+	mdrefr = mdrefr | MDREFR_K2DB2 | MDREFR_K2RUN;
+	if (mdrefr != mdrefr_old) {
+		MDREFR = mdrefr;
+		(void) MDREFR;
+	}
+}
+
+/*
+ * We really ought to only do this when the device is in use, but finding
+ * that out from a snd_soc_card is no trivial matter.  The way ASoC is
+ * structured, a 'card' can encompass multiple audio subsystems...  It
+ * would be nice if ASoC had suspend/resume callbacks in snd_soc_ops, then
+ * we'd know.
+ */
+static int assabet_asoc_resume_pre(struct snd_soc_card *card)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	assabet_asoc_init_clk();
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+static int assabet_asoc_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+	if (!cpu_dai->active) {
+		unsigned long flags;
+
+		/*
+		 * Hand the SFRM signal over to the SSP block as it is
+		 * now enabled.  This keeps SFRM low until the interface
+		 * starts outputting data.
+		 */
+		local_irq_save(flags);
+		GAFR |= GPIO_SSP_SFRM;
+
+		assabet_asoc_init_clk();
+		local_irq_restore(flags);
+	}
+
+	/* Enable the audio power amp */
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ASSABET_BCR_clear(ASSABET_BCR_QMUTE | ASSABET_BCR_SPK_OFF);
+
+	return 0;
+}
+
+static void assabet_asoc_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+
+	/* Disable the audio power amp */
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		ASSABET_BCR_set(ASSABET_BCR_QMUTE | ASSABET_BCR_SPK_OFF);
+
+	if (!cpu_dai->active) {
+		unsigned long flags;
+
+		/*
+		 * Take the SFRM pin away from the SSP block before it
+		 * shuts down.  We must do this to keep SFRM low.
+		 */
+		local_irq_save(flags);
+		GAFR &= ~GPIO_SSP_SFRM;
+		local_irq_restore(flags);
+	}
+}
+
+static int assabet_asoc_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	unsigned rate = params_rate(params);
+	unsigned clk_ref, sysclk, sclk;
+	int ret, div;
+
+	clk_ref = cpufreq_get(0) * 1000;
+
+	/*
+	 * sysclk is the codecs sysclk signal.  sclk is supplied to the
+	 * SA1110 GPIO19 to drive the SSP at sysclk/4 by the CPLD.
+	 */
+	sysclk = clk_ref / 18;
+	sclk = sysclk / 4;
+
+	if (rate > sysclk * 4 / (256 * 7)) {
+		/* fs256 */
+		div = 2;
+	} else {
+		/* fs512 */
+		div = 4;
+	}
+
+	ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_sysclk(cpu_dai, SA11X0_SSP_CLK_EXT, sclk,
+		SND_SOC_CLOCK_IN);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_dai_set_clkdiv(cpu_dai, SA11X0_SSP_DIV_SCR, div);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct snd_soc_ops assabet_asoc_ops = {
+	.startup = assabet_asoc_startup,
+	.shutdown = assabet_asoc_shutdown,
+	.hw_params = assabet_asoc_hw_params,
+};
+
+static struct snd_soc_dai_link assabet_asoc_dai = {
+	.name = "Assabet",
+	.stream_name = "Assabet",
+	.codec_name = "uda134x-codec",
+	.platform_name = "soc-dmaengine",
+	.cpu_dai_name = "sa11x0-ssp",
+	.codec_dai_name = "uda134x-hifi",
+	.ops = &assabet_asoc_ops,
+	.dai_fmt = SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF |
+		   SND_SOC_DAIFMT_CBS_CFS,
+};
+
+static struct snd_soc_card snd_soc_assabet = {
+	.name = "Assabet",
+	.resume_pre = assabet_asoc_resume_pre,
+	.dai_link = &assabet_asoc_dai,
+	.num_links = 1,
+};
+
+/*
+ * This is not-quite-right stuff: we have to _hope_ by a miracle that
+ * we don't stamp on the toes of I2C, which shares these pins.
+ */
+static void assabet_setdat(int v)
+{
+	gpio_set_value(GPIO_L3_DAT, !!v);
+}
+
+static void assabet_setclk(int v)
+{
+	gpio_set_value(GPIO_L3_SCK, !!v);
+}
+
+static void assabet_setmode(int v)
+{
+	gpio_set_value(GPIO_L3_MODE, !!v);
+}
+
+static struct uda134x_platform_data uda1341_data = {
+	.l3 = {
+		.setdat = assabet_setdat,
+		.setclk = assabet_setclk,
+		.setmode = assabet_setmode,
+		.data_hold = 1,
+		.data_setup = 1,
+		.clock_high = 1,
+		.mode_hold = 1,
+		.mode = 1,
+		.mode_setup = 1,
+	},
+	.model = UDA134X_UDA1341,
+	.power = assabet_asoc_uda1341_power,
+};
+
+static struct gpio ssp_gpio[] = {
+	{
+		.gpio = GPIO_TXD,
+		.flags = GPIOF_OUT_INIT_LOW,
+		.label = "ssp_txd",
+	}, {
+		.gpio = GPIO_RXD,
+		.flags = GPIOF_IN,
+		.label = "ssp_rxd",
+	}, {
+		.gpio = GPIO_SCLK,
+		.flags = GPIOF_OUT_INIT_LOW,
+		.label = "ssp_sclk",
+	}, {
+		.gpio = GPIO_SFRM,
+		.flags = GPIOF_OUT_INIT_LOW,
+		.label = "ssp_sfrm",
+	}, {
+		.gpio = GPIO_CLK,
+		.flags = GPIOF_IN,
+		.label = "ssp_clk",
+	}, {
+		.gpio = GPIO_L3_MODE,
+		.flags = GPIOF_OUT_INIT_LOW,
+		.label = "l3_mode",
+	},
+};
+
+static struct platform_device *soc, *uda, *dma;
+
+static int assabet_init(void)
+{
+	unsigned long flags;
+	int ret;
+
+	ret = gpio_request_array(ssp_gpio, ARRAY_SIZE(ssp_gpio));
+	if (ret)
+		return ret;
+
+	/*
+	 * Request these irrespective of whether they succeed.  Wish we
+	 * could have our shared I2C/L3 driver from v2.4 kernels, but
+	 * alas this would require a buggeration of the ASoC code.
+	 * Not only this, but we have no way to do any kind of locking
+	 * between the UDA134x L3 driver and I2C.
+	 */
+	gpio_request_one(GPIO_L3_DAT, GPIOF_OUT_INIT_LOW, "l3_dat");
+	gpio_request_one(GPIO_L3_SCK, GPIOF_OUT_INIT_LOW, "l3_sck");
+
+	/*
+	 * Put the LRCK signal into a known good state: early Assabets
+	 * do not mask the LRCK signal when the codec is powered down,
+	 * and it defaults to logic 1.  So, first release the reset,
+	 * and then toggle the SFRM signal to set LRCK to zero.
+	 */
+	ASSABET_BCR_set(ASSABET_BCR_CODEC_RST | ASSABET_BCR_SPK_OFF);
+	ASSABET_BCR_clear(ASSABET_BCR_STEREO_LB);
+
+	gpio_set_value(GPIO_SFRM, 1);
+	gpio_set_value(GPIO_SFRM, 0);
+
+	local_irq_save(flags);
+	/*
+	 * Ensure SSP pin reassignment is enabled, so that the SSP appears
+	 * on the GPIO pins rather than the deddicated UART4 pins.
+	 */
+	PPAR |= PPAR_SPR;
+
+	/* Configure the SSP input clock, and most SSP output signals */
+	GAFR |= GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | GPIO_SSP_CLK;
+
+	local_irq_restore(flags);
+
+	/*
+	 * This is horrible, vile, disgusting abuse of the driver model
+	 * just for the hell of it.  ASoC abuses the driver model elsewhere
+	 * by kfreeing kobjects too!  As long as it does this kind of vile
+	 * abuse, it is a total disaster waiting to happen, and should
+	 * never have been merged into the kernel in the first place.
+	 *   --rmk
+	 */
+	uda = platform_device_alloc(assabet_asoc_dai.codec_name, -1);
+	soc = platform_device_alloc("soc-audio", -1);
+	dma = platform_device_alloc("soc-dmaengine", -1);
+	if (!soc || !uda || !dma) {
+		ret = -ENOMEM;
+		goto err_dev_alloc;
+	}
+	/* Ah, a void pointer, what can we stuff in here to pass around... */
+	platform_set_drvdata(soc, &snd_soc_assabet);
+	/* Oh look mummy, another void pointer, what can we stuff in here? */
+	platform_device_add_data(soc, &uda1341_data, sizeof(uda1341_data));
+
+	/* Let's at least give soc-audio a decent parent */
+	soc->dev.parent = &uda->dev;
+
+	ret = platform_device_add(uda);
+	if (ret)
+		goto err_dev_alloc;
+	ret = platform_device_add(dma);
+	if (ret)
+		goto err_dev_add_dma;
+	ret = platform_device_add(soc);
+	if (ret == 0)
+		return 0;
+
+	platform_device_del(dma);
+ err_dev_add_dma:
+	platform_device_del(uda);
+ err_dev_alloc:
+	if (soc)
+		platform_device_put(soc);
+	if (uda)
+		platform_device_put(uda);
+
+	gpio_free_array(ssp_gpio, ARRAY_SIZE(ssp_gpio));
+
+	return ret;
+}
+module_init(assabet_init);
+
+static void assabet_exit(void)
+{
+	platform_device_unregister(soc);
+	platform_device_unregister(dma);
+	platform_device_unregister(uda);
+
+	gpio_free_array(ssp_gpio, ARRAY_SIZE(ssp_gpio));
+}
+module_exit(assabet_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/sa11x0/sa11x0-ssp.c b/sound/soc/sa11x0/sa11x0-ssp.c
new file mode 100644
index 0000000..5635a67
--- /dev/null
+++ b/sound/soc/sa11x0/sa11x0-ssp.c
@@ -0,0 +1,345 @@
+/*
+ * ASoC SA11x0 SSP DAI driver
+ *
+ * Copyright (C) 2012 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The SA11x0 SSP interface gives us four signals: TXD, RXD, SFRM and SCLK,
+ * and SFRM pulses for each and every word transmitted.  These signals can
+ * be routed to GPIO10(TXD), GPIO11(RXD), GPIO12(SCLK), and GPIO13(SFRM)
+ * when the PPAR_SPR bit it set, along with the appropriate GAFR and GPDR
+ * configuration.  If PPAR_SPR is clear, the SSP shares the same pins with
+ * the MCP.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sa11x0-dma.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc-dmaengine.h>
+#include <sound/soc.h>
+
+#include "sa11x0-ssp.h"
+
+#define SA11X0_SSP_CHANNELS_MIN	1
+#define SA11X0_SSP_CHANNELS_MAX	8
+
+/*
+ * This isn't really up to us - it depends how the board implements the
+ * clocking, whether the board uses the on-board clock source, or whether
+ * the SSP is clocked via GPIO19.
+ */
+#define SA11X0_SSP_RATES \
+	(SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS)
+#define SA11X0_SSP_FORMATS \
+	(SNDRV_PCM_FORMAT_S8		| SNDRV_PCM_FORMAT_U8		| \
+	 SNDRV_PCM_FORMAT_S16_LE	| SNDRV_PCM_FORMAT_U16_LE)
+
+#define SSCR0		0x60
+#define SSCR0_DSS	(15 << 0)	/* s */
+#define SSCR0_FRF_MOT	(0 << 4)
+#define SSCR0_FRF_TI	(1 << 4)
+#define SSCR0_FRF_NAT	(2 << 4)
+#define SSCR0_SSE	(1 << 7)	/* s */
+#define SSCR0_SCR	(0xff << 8)	/* s */
+#define SSCR1		0x64
+#define SSCR1_RIE	(1 << 0)
+#define SSCR1_TIE	(1 << 1)
+#define SSCR1_LBM	(1 << 2)
+#define SSCR1_SPO	(1 << 3)
+#define SSCR1_SP	(1 << 4)
+#define SSCR1_ECS	(1 << 5)	/* s */
+#define SSDR		0x6c
+#define SSSR		0x74
+
+struct ssp_priv {
+	struct resource *res;
+	void __iomem *base;
+	u32 cr0;
+	u32 cr1;
+};
+
+static struct soc_dma_config sa11x0_tx_cfg = {
+	.filter = sa11x0_dma_filter_fn,
+	.data = "Ser4SSPTr",
+	.reg = 0x80070000 + SSDR,
+	.width = DMA_SLAVE_BUSWIDTH_2_BYTES,
+	.maxburst = 4,
+	.align = 32,
+	.fifo_size = 2 * 8,
+};
+
+static struct soc_dma_config sa11x0_rx_cfg = {
+	.filter = sa11x0_dma_filter_fn,
+	.data = "Ser4SSPRc",
+	.reg = 0x80070000 + SSDR,
+	.width = DMA_SLAVE_BUSWIDTH_2_BYTES,
+	.maxburst = 4,
+	.align = 32,
+	.fifo_size = 2 * 12,
+};
+
+static int sa11x0_ssp_startup(struct snd_pcm_substream *substream,
+	struct snd_soc_dai *dai)
+{
+	if (!dai->active) {
+		struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+
+		writel_relaxed(ssp->cr0, ssp->base + SSCR0);
+		writel_relaxed(ssp->cr1, ssp->base + SSCR1);
+		ssp->cr0 |= SSCR0_SSE;
+		writel_relaxed(ssp->cr0, ssp->base + SSCR0);
+	}
+
+	return 0;
+}
+
+static void sa11x0_ssp_shutdown(struct snd_pcm_substream *substream,
+	struct snd_soc_dai *dai)
+{
+	if (!dai->active) {
+		struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+
+		ssp->cr0 &= ~SSCR0_SSE;
+		writel_relaxed(ssp->cr0, ssp->base + SSCR0);
+	}
+}
+
+static int sa11x0_ssp_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+	struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+	snd_pcm_format_t fmt = params_format(params);
+	int width = snd_pcm_format_width(fmt);
+	u32 cr0;
+
+	if (width < 0)
+		return width;
+	if (width < 4 || width > 16)
+		return -EINVAL;
+
+	/* Set the bit-width for the format */
+	cr0 = (ssp->cr0 & ~SSCR0_DSS) | (width - 1);
+	if (cr0 != ssp->cr0) {
+		ssp->cr0 = cr0;
+		writel_relaxed(cr0, ssp->base + SSCR0);
+	}
+
+	return 0;
+}
+
+static int sa11x0_ssp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+	unsigned int freq, int dir)
+{
+	struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+
+	switch (clk_id) {
+	case SA11X0_SSP_CLK_INT:
+		ssp->cr1 &= ~SSCR1_ECS;
+		break;
+
+	case SA11X0_SSP_CLK_EXT:
+		ssp->cr1 |= SSCR1_ECS;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	writel_relaxed(ssp->cr1, ssp->base + SSCR1);
+
+	return 0;
+}
+
+static int sa11x0_ssp_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
+{
+	struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+	u32 cr0;
+
+	if (div_id != SA11X0_SSP_DIV_SCR)
+		return -EINVAL;
+
+	cr0 = (ssp->cr0 & ~SSCR0_SCR) | ((div - 2) / 2) << 8;
+	if (cr0 != ssp->cr0) {
+		ssp->cr0 = cr0;
+		writel_relaxed(cr0, ssp->base + SSCR0);
+	}
+
+	return 0;
+}
+
+static int sa11x0_ssp_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	/* We generate the clock and frm signals */
+	if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static struct snd_soc_dai_ops sa11x0_ssp_ops = {
+	.startup = sa11x0_ssp_startup,
+	.shutdown = sa11x0_ssp_shutdown,
+	.hw_params = sa11x0_ssp_hw_params,
+	.set_sysclk = sa11x0_ssp_set_sysclk,
+	.set_clkdiv = sa11x0_ssp_set_clkdiv,
+	.set_fmt = sa11x0_ssp_set_fmt,
+};
+
+static int sa11x0_ssp_probe(struct snd_soc_dai *dai)
+{
+	struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+
+	/* Default to TI mode and a bit-width of 16 */
+	ssp->cr0 = SSCR0_FRF_TI | 15;
+
+	/*
+	 * Set the DMA data now - it's needed for the dmaengine backend to
+	 * obtain its DMA channel, in turn its struct device, and therefore
+	 * a struct device to allocate DMA memory against.
+	 */
+	dai->playback_dma_data = &sa11x0_tx_cfg;
+	dai->capture_dma_data = &sa11x0_rx_cfg;
+
+	return 0;
+}
+
+static int sa11x0_ssp_remove(struct snd_soc_dai *dai)
+{
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sa11x0_ssp_suspend(struct snd_soc_dai *dai)
+{
+	struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+
+	writel_relaxed(ssp->cr0 & ~SSCR0_SSE, ssp->base + SSCR0);
+
+	return 0;
+}
+
+static int sa11x0_ssp_resume(struct snd_soc_dai *dai)
+{
+	struct ssp_priv *ssp = snd_soc_dai_get_drvdata(dai);
+
+	writel_relaxed(ssp->cr0 & ~SSCR0_SSE, ssp->base + SSCR0);
+	writel_relaxed(ssp->cr1, ssp->base + SSCR1);
+	if (ssp->cr0 & SSCR0_SSE)
+		writel_relaxed(ssp->cr0, ssp->base + SSCR0);
+
+	return 0;
+}
+#else
+#define sa11x0_ssp_suspend NULL
+#define sa11x0_ssp_resume NULL
+#endif
+
+static struct snd_soc_dai_driver sa11x0_ssp_driver = {
+	.probe = sa11x0_ssp_probe,
+	.remove = sa11x0_ssp_remove,
+	.suspend = sa11x0_ssp_suspend,
+	.resume = sa11x0_ssp_resume,
+	.ops = &sa11x0_ssp_ops,
+	.capture = {
+		.channels_min = SA11X0_SSP_CHANNELS_MIN,
+		.channels_max = SA11X0_SSP_CHANNELS_MAX,
+		.rates = SA11X0_SSP_RATES,
+		.formats = SA11X0_SSP_FORMATS,
+	},
+	.playback = {
+		.channels_min = SA11X0_SSP_CHANNELS_MIN,
+		.channels_max = SA11X0_SSP_CHANNELS_MAX,
+		.rates = SA11X0_SSP_RATES,
+		.formats = SA11X0_SSP_FORMATS,
+	},
+	.symmetric_rates = 1,
+};
+
+static int __devinit sa11x0_ssp_plat_probe(struct platform_device *pdev)
+{
+	struct ssp_priv *ssp;
+	struct resource *res;
+	int ret;
+
+	ssp = kzalloc(sizeof(*ssp), GFP_KERNEL);
+	if (!ssp) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (!request_mem_region(res->start, resource_size(res),
+				dev_name(&pdev->dev))) {
+		ret = -EBUSY;
+		goto err;
+	}
+
+	ssp->res = res;
+	ssp->base = ioremap(res->start, resource_size(res));
+	if (!ssp->base) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	writel_relaxed(ssp->cr0, ssp->base + SSCR0);
+	writel_relaxed(ssp->cr1, ssp->base + SSCR1);
+
+	platform_set_drvdata(pdev, ssp);
+	ret = snd_soc_register_dai(&pdev->dev, &sa11x0_ssp_driver);
+	if (ret)
+		goto err;
+
+	return 0;
+
+ err:
+	platform_set_drvdata(pdev, NULL);
+	if (ssp && ssp->base)
+		iounmap(ssp->base);
+	if (ssp && ssp->res)
+		release_mem_region(ssp->res->start, resource_size(ssp->res));
+	kfree(ssp);
+	return ret;
+}
+
+static int __devexit sa11x0_ssp_plat_remove(struct platform_device *pdev)
+{
+	struct ssp_priv *ssp = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_dai(&pdev->dev);
+
+	platform_set_drvdata(pdev, NULL);
+	iounmap(ssp->base);
+	release_mem_region(ssp->res->start, resource_size(ssp->res));
+	kfree(ssp);
+
+	return 0;
+}
+
+static struct platform_driver sa11x0_ssp_plat_driver = {
+	.driver = {
+		.name = "sa11x0-ssp",
+		.owner = THIS_MODULE,
+	},
+	.probe = sa11x0_ssp_plat_probe,
+	.remove = __devexit_p(sa11x0_ssp_plat_remove),
+};
+module_platform_driver(sa11x0_ssp_plat_driver);
+
+MODULE_AUTHOR("Russell King <linux@arm.linux.org.uk>");
+MODULE_DESCRIPTION("SA11x0 SSP/PCM SoC Interface");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sa11x0-ssp");
diff --git a/sound/soc/sa11x0/sa11x0-ssp.h b/sound/soc/sa11x0/sa11x0-ssp.h
new file mode 100644
index 0000000..22f1e5b
--- /dev/null
+++ b/sound/soc/sa11x0/sa11x0-ssp.h
@@ -0,0 +1,11 @@
+#ifndef SA11X0_SSP_H
+#define SA11X0_SSP_H
+
+/* SSP clock sources */
+#define SA11X0_SSP_CLK_INT	0x11000000
+#define SA11X0_SSP_CLK_EXT	0x11000001
+
+/* SSP audio dividers */
+#define SA11X0_SSP_DIV_SCR	0x11000100
+
+#endif
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index e4ba17c..ddc6cde 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -411,7 +411,7 @@ static int dma_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &dma_mask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = preallocate_dma_buffer(pcm,
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 9dd818b..e741685 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -189,6 +189,9 @@ static int littlemill_late_probe(struct snd_soc_card *card)
 	/* This will check device compatibility itself */
 	wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL);
 
+	/* As will this */
+	wm8994_mic_detect(codec, &littlemill_headset, 1);
+
 	return 0;
 }
 
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index c6012ff..24bdb32 100644
--- a/sound/soc/samsung/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -296,7 +296,7 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
 	if (ret)
 		return ret;
 
-	ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls,
+	ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls,
 			ARRAY_SIZE(neo1973_gta02_wm8753_controls));
 	if (ret)
 		return ret;
@@ -328,7 +328,7 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
 		return ret;
 
 	/* add neo1973 specific controls */
-	ret = snd_soc_add_controls(codec, neo1973_wm8753_controls,
+	ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls,
 			ARRAY_SIZE(neo1973_wm8753_controls));
 	if (ret)
 		return ret;
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index a253bcc..656d5af 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -134,18 +134,18 @@ static const struct snd_kcontrol_new amp_unmute_controls[] = {
 
 void simtec_audio_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_card *card = rtd->card;
 
 	if (pdata->amp_gpio > 0) {
 		pr_debug("%s: adding amp routes\n", __func__);
 
-		snd_soc_add_controls(codec, amp_unmute_controls,
+		snd_soc_add_card_controls(card, amp_unmute_controls,
 				     ARRAY_SIZE(amp_unmute_controls));
 	}
 
 	if (pdata->amp_gain[0] > 0) {
 		pr_debug("%s: adding amp controls\n", __func__);
-		snd_soc_add_controls(codec, amp_gain_controls,
+		snd_soc_add_card_controls(card, amp_gain_controls,
 				     ARRAY_SIZE(amp_gain_controls));
 	}
 }
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index ea4a82d0..378cc5b 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -13,8 +13,11 @@
  */
 
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/io.h>
+#include <linux/scatterlist.h>
+#include <linux/sh_dma.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <sound/soc.h>
@@ -53,6 +56,7 @@
 
 /* DO_FMT */
 /* DI_FMT */
+#define CR_BWS_MASK	(0x3 << 20) /* FSI2 */
 #define CR_BWS_24	(0x0 << 20) /* FSI2 */
 #define CR_BWS_16	(0x1 << 20) /* FSI2 */
 #define CR_BWS_20	(0x2 << 20) /* FSI2 */
@@ -68,6 +72,15 @@
 #define CR_TDM		(0x4 << 4)
 #define CR_TDM_D	(0x5 << 4)
 
+/* OUT_DMAC */
+/* IN_DMAC */
+#define VDMD_MASK	(0x3 << 4)
+#define VDMD_FRONT	(0x0 << 4) /* Package in front */
+#define VDMD_BACK	(0x1 << 4) /* Package in back */
+#define VDMD_STREAM	(0x2 << 4) /* Stream mode(16bit * 2) */
+
+#define DMA_ON		(0x1 << 0)
+
 /* DOFF_CTL */
 /* DIFF_CTL */
 #define IRQ_HALF	0x00100000
@@ -116,7 +129,7 @@
 
 #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
 
-typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable);
+typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
 
 /*
  * FSI driver use below type name for variable
@@ -159,22 +172,41 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
  *		struct
  */
 
+struct fsi_stream_handler;
 struct fsi_stream {
-	struct snd_pcm_substream *substream;
 
+	/*
+	 * these are initialized by fsi_stream_init()
+	 */
+	struct snd_pcm_substream *substream;
 	int fifo_sample_capa;	/* sample capacity of FSI FIFO */
 	int buff_sample_capa;	/* sample capacity of ALSA buffer */
 	int buff_sample_pos;	/* sample position of ALSA buffer */
 	int period_samples;	/* sample number / 1 period */
 	int period_pos;		/* current period position */
-
+	int sample_width;	/* sample width */
 	int uerr_num;
 	int oerr_num;
+
+	/*
+	 * thse are initialized by fsi_handler_init()
+	 */
+	struct fsi_stream_handler *handler;
+	struct fsi_priv		*priv;
+
+	/*
+	 * these are for DMAEngine
+	 */
+	struct dma_chan		*chan;
+	struct sh_dmae_slave	slave; /* see fsi_handler_init() */
+	struct tasklet_struct	tasklet;
+	dma_addr_t		dma;
 };
 
 struct fsi_priv {
 	void __iomem *base;
 	struct fsi_master *master;
+	struct sh_fsi_port_info *info;
 
 	struct fsi_stream playback;
 	struct fsi_stream capture;
@@ -189,6 +221,20 @@ struct fsi_priv {
 	long rate;
 };
 
+struct fsi_stream_handler {
+	int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
+	int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
+	int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
+	int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
+	int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
+	void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
+			   int enable);
+};
+#define fsi_stream_handler_call(io, func, args...)	\
+	(!(io) ? -ENODEV :				\
+	 !((io)->handler->func) ? 0 :			\
+	 (io)->handler->func(args))
+
 struct fsi_core {
 	int ver;
 
@@ -205,10 +251,11 @@ struct fsi_master {
 	struct fsi_priv fsia;
 	struct fsi_priv fsib;
 	struct fsi_core *core;
-	struct sh_fsi_platform_info *info;
 	spinlock_t lock;
 };
 
+static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io);
+
 /*
  *		basic read write function
  */
@@ -295,6 +342,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi)
 	return fsi->spdif;
 }
 
+static int fsi_is_play(struct snd_pcm_substream *substream)
+{
+	return substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+}
+
 static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -317,44 +369,25 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
 	return fsi_get_priv_frm_dai(fsi_get_dai(substream));
 }
 
-static set_rate_func fsi_get_info_set_rate(struct fsi_master *master)
+static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi)
 {
-	if (!master->info)
+	if (!fsi->info)
 		return NULL;
 
-	return master->info->set_rate;
+	return fsi->info->set_rate;
 }
 
 static u32 fsi_get_info_flags(struct fsi_priv *fsi)
 {
-	int is_porta = fsi_is_port_a(fsi);
-	struct fsi_master *master = fsi_get_master(fsi);
-
-	if (!master->info)
+	if (!fsi->info)
 		return 0;
 
-	return is_porta ? master->info->porta_flags :
-		master->info->portb_flags;
-}
-
-static inline int fsi_stream_is_play(int stream)
-{
-	return stream == SNDRV_PCM_STREAM_PLAYBACK;
-}
-
-static inline int fsi_is_play(struct snd_pcm_substream *substream)
-{
-	return fsi_stream_is_play(substream->stream);
+	return fsi->info->flags;
 }
 
-static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
-						int is_play)
-{
-	return is_play ? &fsi->playback : &fsi->capture;
-}
-
-static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
+static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io)
 {
+	int is_play = fsi_stream_is_play(fsi, io);
 	int is_porta = fsi_is_port_a(fsi);
 	u32 shift;
 
@@ -376,26 +409,81 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples)
 	return samples / fsi->chan_num;
 }
 
+static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
+					struct fsi_stream *io)
+{
+	int is_play = fsi_stream_is_play(fsi, io);
+	u32 status;
+	int frames;
+
+	status = is_play ?
+		fsi_reg_read(fsi, DOFF_ST) :
+		fsi_reg_read(fsi, DIFF_ST);
+
+	frames = 0x1ff & (status >> 8);
+
+	return fsi_frame2sample(fsi, frames);
+}
+
+static void fsi_count_fifo_err(struct fsi_priv *fsi)
+{
+	u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
+	u32 istatus = fsi_reg_read(fsi, DIFF_ST);
+
+	if (ostatus & ERR_OVER)
+		fsi->playback.oerr_num++;
+
+	if (ostatus & ERR_UNDER)
+		fsi->playback.uerr_num++;
+
+	if (istatus & ERR_OVER)
+		fsi->capture.oerr_num++;
+
+	if (istatus & ERR_UNDER)
+		fsi->capture.uerr_num++;
+
+	fsi_reg_write(fsi, DOFF_ST, 0);
+	fsi_reg_write(fsi, DIFF_ST, 0);
+}
+
+/*
+ *		fsi_stream_xx() function
+ */
+static inline int fsi_stream_is_play(struct fsi_priv *fsi,
+				     struct fsi_stream *io)
+{
+	return &fsi->playback == io;
+}
+
+static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi,
+					struct snd_pcm_substream *substream)
+{
+	return fsi_is_play(substream) ? &fsi->playback : &fsi->capture;
+}
+
 static int fsi_stream_is_working(struct fsi_priv *fsi,
-				  int is_play)
+				 struct fsi_stream *io)
 {
-	struct fsi_stream *io = fsi_get_stream(fsi, is_play);
 	struct fsi_master *master = fsi_get_master(fsi);
 	unsigned long flags;
 	int ret;
 
 	spin_lock_irqsave(&master->lock, flags);
-	ret = !!io->substream;
+	ret = !!(io->substream && io->substream->runtime);
 	spin_unlock_irqrestore(&master->lock, flags);
 
 	return ret;
 }
 
-static void fsi_stream_push(struct fsi_priv *fsi,
-			    int is_play,
+static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
+{
+	return io->priv;
+}
+
+static void fsi_stream_init(struct fsi_priv *fsi,
+			    struct fsi_stream *io,
 			    struct snd_pcm_substream *substream)
 {
-	struct fsi_stream *io = fsi_get_stream(fsi, is_play);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsi_master *master = fsi_get_master(fsi);
 	unsigned long flags;
@@ -406,14 +494,15 @@ static void fsi_stream_push(struct fsi_priv *fsi,
 	io->buff_sample_pos	= 0;
 	io->period_samples	= fsi_frame2sample(fsi, runtime->period_size);
 	io->period_pos		= 0;
+	io->sample_width	= samples_to_bytes(runtime, 1);
 	io->oerr_num	= -1; /* ignore 1st err */
 	io->uerr_num	= -1; /* ignore 1st err */
+	fsi_stream_handler_call(io, init, fsi, io);
 	spin_unlock_irqrestore(&master->lock, flags);
 }
 
-static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
+static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
 {
-	struct fsi_stream *io = fsi_get_stream(fsi, is_play);
 	struct snd_soc_dai *dai = fsi_get_dai(io->substream);
 	struct fsi_master *master = fsi_get_master(fsi);
 	unsigned long flags;
@@ -426,127 +515,87 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
 	if (io->uerr_num > 0)
 		dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
 
+	fsi_stream_handler_call(io, quit, fsi, io);
 	io->substream	= NULL;
 	io->buff_sample_capa	= 0;
 	io->buff_sample_pos	= 0;
 	io->period_samples	= 0;
 	io->period_pos		= 0;
+	io->sample_width	= 0;
 	io->oerr_num	= 0;
 	io->uerr_num	= 0;
 	spin_unlock_irqrestore(&master->lock, flags);
 }
 
-static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play)
+static int fsi_stream_transfer(struct fsi_stream *io)
 {
-	u32 status;
-	int frames;
-
-	status = is_play ?
-		fsi_reg_read(fsi, DOFF_ST) :
-		fsi_reg_read(fsi, DIFF_ST);
-
-	frames = 0x1ff & (status >> 8);
-
-	return fsi_frame2sample(fsi, frames);
-}
-
-static void fsi_count_fifo_err(struct fsi_priv *fsi)
-{
-	u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
-	u32 istatus = fsi_reg_read(fsi, DIFF_ST);
-
-	if (ostatus & ERR_OVER)
-		fsi->playback.oerr_num++;
-
-	if (ostatus & ERR_UNDER)
-		fsi->playback.uerr_num++;
-
-	if (istatus & ERR_OVER)
-		fsi->capture.oerr_num++;
-
-	if (istatus & ERR_UNDER)
-		fsi->capture.uerr_num++;
+	struct fsi_priv *fsi = fsi_stream_to_priv(io);
+	if (!fsi)
+		return -EIO;
 
-	fsi_reg_write(fsi, DOFF_ST, 0);
-	fsi_reg_write(fsi, DIFF_ST, 0);
+	return fsi_stream_handler_call(io, transfer, fsi, io);
 }
 
-/*
- *		dma function
- */
+#define fsi_stream_start(fsi, io)\
+	fsi_stream_handler_call(io, start_stop, fsi, io, 1)
 
-static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
-{
-	int is_play = fsi_stream_is_play(stream);
-	struct fsi_stream *io = fsi_get_stream(fsi, is_play);
-	struct snd_pcm_runtime *runtime = io->substream->runtime;
+#define fsi_stream_stop(fsi, io)\
+	fsi_stream_handler_call(io, start_stop, fsi, io, 0)
 
-	return runtime->dma_area +
-		samples_to_bytes(runtime, io->buff_sample_pos);
-}
-
-static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
+static int fsi_stream_probe(struct fsi_priv *fsi)
 {
-	u16 *start;
-	int i;
-
-	start  = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+	struct fsi_stream *io;
+	int ret1, ret2;
 
-	for (i = 0; i < num; i++)
-		fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
-}
-
-static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num)
-{
-	u16 *start;
-	int i;
+	io = &fsi->playback;
+	ret1 = fsi_stream_handler_call(io, probe, fsi, io);
 
-	start  = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+	io = &fsi->capture;
+	ret2 = fsi_stream_handler_call(io, probe, fsi, io);
 
+	if (ret1 < 0)
+		return ret1;
+	if (ret2 < 0)
+		return ret2;
 
-	for (i = 0; i < num; i++)
-		*(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
+	return 0;
 }
 
-static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num)
+static int fsi_stream_remove(struct fsi_priv *fsi)
 {
-	u32 *start;
-	int i;
+	struct fsi_stream *io;
+	int ret1, ret2;
 
-	start  = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
-
-
-	for (i = 0; i < num; i++)
-		fsi_reg_write(fsi, DODT, *(start + i));
-}
+	io = &fsi->playback;
+	ret1 = fsi_stream_handler_call(io, remove, fsi, io);
 
-static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num)
-{
-	u32 *start;
-	int i;
+	io = &fsi->capture;
+	ret2 = fsi_stream_handler_call(io, remove, fsi, io);
 
-	start  = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
+	if (ret1 < 0)
+		return ret1;
+	if (ret2 < 0)
+		return ret2;
 
-	for (i = 0; i < num; i++)
-		*(start + i) = fsi_reg_read(fsi, DIDT);
+	return 0;
 }
 
 /*
  *		irq function
  */
 
-static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
+static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io)
 {
-	u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
+	u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
 	struct fsi_master *master = fsi_get_master(fsi);
 
 	fsi_core_mask_set(master, imsk,  data, data);
 	fsi_core_mask_set(master, iemsk, data, data);
 }
 
-static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
+static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io)
 {
-	u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
+	u32 data = AB_IO(1, fsi_get_port_shift(fsi, io));
 	struct fsi_master *master = fsi_get_master(fsi);
 
 	fsi_core_mask_set(master, imsk,  data, 0);
@@ -563,8 +612,8 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
 	u32 data = 0;
 	struct fsi_master *master = fsi_get_master(fsi);
 
-	data |= AB_IO(1, fsi_get_port_shift(fsi, 0));
-	data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
+	data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
+	data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));
 
 	/* clear interrupt factor */
 	fsi_core_mask_set(master, int_st, data, 0);
@@ -600,11 +649,14 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
 			      long rate, int enable)
 {
 	struct fsi_master *master = fsi_get_master(fsi);
-	set_rate_func set_rate = fsi_get_info_set_rate(master);
+	set_rate_func set_rate = fsi_get_info_set_rate(fsi);
 	int fsi_ver = master->core->ver;
 	int ret;
 
-	ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable);
+	if (!set_rate)
+		return 0;
+
+	ret = set_rate(dev, rate, enable);
 	if (ret < 0) /* error */
 		return ret;
 
@@ -671,96 +723,64 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
 	return ret;
 }
 
-#define fsi_port_start(f, i)	__fsi_port_clk_ctrl(f, i, 1)
-#define fsi_port_stop(f, i)	__fsi_port_clk_ctrl(f, i, 0)
-static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable)
+/*
+ *		pio data transfer handler
+ */
+static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
 {
-	struct fsi_master *master = fsi_get_master(fsi);
-	u32 clk  = fsi_is_port_a(fsi) ? CRA  : CRB;
+	u16 *buf = (u16 *)_buf;
+	int i;
 
-	if (enable)
-		fsi_irq_enable(fsi, is_play);
-	else
-		fsi_irq_disable(fsi, is_play);
+	for (i = 0; i < samples; i++)
+		fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
+}
 
-	if (fsi_is_clk_master(fsi))
-		fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
+static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
+{
+	u16 *buf = (u16 *)_buf;
+	int i;
+
+	for (i = 0; i < samples; i++)
+		*(buf + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
 }
 
-/*
- *		ctrl function
- */
-static void fsi_fifo_init(struct fsi_priv *fsi,
-			  int is_play,
-			  struct device *dev)
+static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int samples)
 {
-	struct fsi_master *master = fsi_get_master(fsi);
-	struct fsi_stream *io = fsi_get_stream(fsi, is_play);
-	u32 shift, i;
-	int frame_capa;
+	u32 *buf = (u32 *)_buf;
+	int i;
 
-	/* get on-chip RAM capacity */
-	shift = fsi_master_read(master, FIFO_SZ);
-	shift >>= fsi_get_port_shift(fsi, is_play);
-	shift &= FIFO_SZ_MASK;
-	frame_capa = 256 << shift;
-	dev_dbg(dev, "fifo = %d words\n", frame_capa);
+	for (i = 0; i < samples; i++)
+		fsi_reg_write(fsi, DODT, *(buf + i));
+}
 
-	/*
-	 * The maximum number of sample data varies depending
-	 * on the number of channels selected for the format.
-	 *
-	 * FIFOs are used in 4-channel units in 3-channel mode
-	 * and in 8-channel units in 5- to 7-channel mode
-	 * meaning that more FIFOs than the required size of DPRAM
-	 * are used.
-	 *
-	 * ex) if 256 words of DP-RAM is connected
-	 * 1 channel:  256 (256 x 1 = 256)
-	 * 2 channels: 128 (128 x 2 = 256)
-	 * 3 channels:  64 ( 64 x 3 = 192)
-	 * 4 channels:  64 ( 64 x 4 = 256)
-	 * 5 channels:  32 ( 32 x 5 = 160)
-	 * 6 channels:  32 ( 32 x 6 = 192)
-	 * 7 channels:  32 ( 32 x 7 = 224)
-	 * 8 channels:  32 ( 32 x 8 = 256)
-	 */
-	for (i = 1; i < fsi->chan_num; i <<= 1)
-		frame_capa >>= 1;
-	dev_dbg(dev, "%d channel %d store\n",
-		fsi->chan_num, frame_capa);
+static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int samples)
+{
+	u32 *buf = (u32 *)_buf;
+	int i;
 
-	io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
+	for (i = 0; i < samples; i++)
+		*(buf + i) = fsi_reg_read(fsi, DIDT);
+}
 
-	/*
-	 * set interrupt generation factor
-	 * clear FIFO
-	 */
-	if (is_play) {
-		fsi_reg_write(fsi,	DOFF_CTL, IRQ_HALF);
-		fsi_reg_mask_set(fsi,	DOFF_CTL, FIFO_CLR, FIFO_CLR);
-	} else {
-		fsi_reg_write(fsi,	DIFF_CTL, IRQ_HALF);
-		fsi_reg_mask_set(fsi,	DIFF_CTL, FIFO_CLR, FIFO_CLR);
-	}
+static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	struct snd_pcm_runtime *runtime = io->substream->runtime;
+
+	return runtime->dma_area +
+		samples_to_bytes(runtime, io->buff_sample_pos);
 }
 
-static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
+static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io,
+		void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples),
+		void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples),
+		int samples)
 {
 	struct snd_pcm_runtime *runtime;
-	struct snd_pcm_substream *substream = NULL;
-	int is_play = fsi_stream_is_play(stream);
-	struct fsi_stream *io = fsi_get_stream(fsi, is_play);
-	int sample_residues;
-	int sample_width;
-	int samples;
-	int samples_max;
+	struct snd_pcm_substream *substream;
+	u8 *buf;
 	int over_period;
-	void (*fn)(struct fsi_priv *fsi, int size);
 
-	if (!fsi			||
-	    !io->substream		||
-	    !io->substream->runtime)
+	if (!fsi_stream_is_working(fsi, io))
 		return -EINVAL;
 
 	over_period	= 0;
@@ -780,60 +800,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
 			io->buff_sample_pos = 0;
 	}
 
-	/* get 1 sample data width */
-	sample_width = samples_to_bytes(runtime, 1);
+	buf = fsi_pio_get_area(fsi, io);
 
-	/* get number of residue samples */
-	sample_residues = io->buff_sample_capa - io->buff_sample_pos;
-
-	if (is_play) {
-		/*
-		 * for play-back
-		 *
-		 * samples_max	: number of FSI fifo free samples space
-		 * samples	: number of ALSA residue samples
-		 */
-		samples_max  = io->fifo_sample_capa;
-		samples_max -= fsi_get_current_fifo_samples(fsi, is_play);
-
-		samples = sample_residues;
-
-		switch (sample_width) {
-		case 2:
-			fn = fsi_dma_soft_push16;
-			break;
-		case 4:
-			fn = fsi_dma_soft_push32;
-			break;
-		default:
-			return -EINVAL;
-		}
-	} else {
-		/*
-		 * for capture
-		 *
-		 * samples_max	: number of ALSA free samples space
-		 * samples	: number of samples in FSI fifo
-		 */
-		samples_max = sample_residues;
-		samples     = fsi_get_current_fifo_samples(fsi, is_play);
-
-		switch (sample_width) {
-		case 2:
-			fn = fsi_dma_soft_pop16;
-			break;
-		case 4:
-			fn = fsi_dma_soft_pop32;
-			break;
-		default:
-			return -EINVAL;
-		}
+	switch (io->sample_width) {
+	case 2:
+		run16(fsi, buf, samples);
+		break;
+	case 4:
+		run32(fsi, buf, samples);
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	samples = min(samples, samples_max);
-
-	fn(fsi, samples);
-
 	/* update buff_sample_pos */
 	io->buff_sample_pos += samples;
 
@@ -843,16 +822,66 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
 	return 0;
 }
 
-static int fsi_data_pop(struct fsi_priv *fsi)
+static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	int sample_residues;	/* samples in FSI fifo */
+	int sample_space;	/* ALSA free samples space */
+	int samples;
+
+	sample_residues	= fsi_get_current_fifo_samples(fsi, io);
+	sample_space	= io->buff_sample_capa - io->buff_sample_pos;
+
+	samples = min(sample_residues, sample_space);
+
+	return fsi_pio_transfer(fsi, io,
+				  fsi_pio_pop16,
+				  fsi_pio_pop32,
+				  samples);
+}
+
+static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
 {
-	return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE);
+	int sample_residues;	/* ALSA residue samples */
+	int sample_space;	/* FSI fifo free samples space */
+	int samples;
+
+	sample_residues	= io->buff_sample_capa - io->buff_sample_pos;
+	sample_space	= io->fifo_sample_capa -
+		fsi_get_current_fifo_samples(fsi, io);
+
+	samples = min(sample_residues, sample_space);
+
+	return fsi_pio_transfer(fsi, io,
+				  fsi_pio_push16,
+				  fsi_pio_push32,
+				  samples);
 }
 
-static int fsi_data_push(struct fsi_priv *fsi)
+static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
+			       int enable)
 {
-	return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK);
+	struct fsi_master *master = fsi_get_master(fsi);
+	u32 clk  = fsi_is_port_a(fsi) ? CRA  : CRB;
+
+	if (enable)
+		fsi_irq_enable(fsi, io);
+	else
+		fsi_irq_disable(fsi, io);
+
+	if (fsi_is_clk_master(fsi))
+		fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
 }
 
+static struct fsi_stream_handler fsi_pio_push_handler = {
+	.transfer	= fsi_pio_push,
+	.start_stop	= fsi_pio_start_stop,
+};
+
+static struct fsi_stream_handler fsi_pio_pop_handler = {
+	.transfer	= fsi_pio_pop,
+	.start_stop	= fsi_pio_start_stop,
+};
+
 static irqreturn_t fsi_interrupt(int irq, void *data)
 {
 	struct fsi_master *master = data;
@@ -863,13 +892,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
 	fsi_master_mask_set(master, SOFT_RST, IR, IR);
 
 	if (int_st & AB_IO(1, AO_SHIFT))
-		fsi_data_push(&master->fsia);
+		fsi_stream_transfer(&master->fsia.playback);
 	if (int_st & AB_IO(1, BO_SHIFT))
-		fsi_data_push(&master->fsib);
+		fsi_stream_transfer(&master->fsib.playback);
 	if (int_st & AB_IO(1, AI_SHIFT))
-		fsi_data_pop(&master->fsia);
+		fsi_stream_transfer(&master->fsia.capture);
 	if (int_st & AB_IO(1, BI_SHIFT))
-		fsi_data_pop(&master->fsib);
+		fsi_stream_transfer(&master->fsib.capture);
 
 	fsi_count_fifo_err(&master->fsia);
 	fsi_count_fifo_err(&master->fsib);
@@ -881,11 +910,271 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
 }
 
 /*
+ *		dma data transfer handler
+ */
+static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	struct snd_pcm_runtime *runtime = io->substream->runtime;
+	struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+	enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
+				DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+	io->dma = dma_map_single(dai->dev, runtime->dma_area,
+				 snd_pcm_lib_buffer_bytes(io->substream), dir);
+	return 0;
+}
+
+static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+	enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
+		DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+	dma_unmap_single(dai->dev, io->dma,
+			 snd_pcm_lib_buffer_bytes(io->substream), dir);
+	return 0;
+}
+
+static void fsi_dma_complete(void *data)
+{
+	struct fsi_stream *io = (struct fsi_stream *)data;
+	struct fsi_priv *fsi = fsi_stream_to_priv(io);
+	struct snd_pcm_runtime *runtime = io->substream->runtime;
+	struct snd_soc_dai *dai = fsi_get_dai(io->substream);
+	enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
+		DMA_TO_DEVICE : DMA_FROM_DEVICE;
+
+	dma_sync_single_for_cpu(dai->dev, io->dma,
+			samples_to_bytes(runtime, io->period_samples), dir);
+
+	io->buff_sample_pos += io->period_samples;
+	io->period_pos++;
+
+	if (io->period_pos >= runtime->periods) {
+		io->period_pos = 0;
+		io->buff_sample_pos = 0;
+	}
+
+	fsi_count_fifo_err(fsi);
+	fsi_stream_transfer(io);
+
+	snd_pcm_period_elapsed(io->substream);
+}
+
+static dma_addr_t fsi_dma_get_area(struct fsi_stream *io)
+{
+	struct snd_pcm_runtime *runtime = io->substream->runtime;
+
+	return io->dma + samples_to_bytes(runtime, io->buff_sample_pos);
+}
+
+static void fsi_dma_do_tasklet(unsigned long data)
+{
+	struct fsi_stream *io = (struct fsi_stream *)data;
+	struct fsi_priv *fsi = fsi_stream_to_priv(io);
+	struct dma_chan *chan;
+	struct snd_soc_dai *dai;
+	struct dma_async_tx_descriptor *desc;
+	struct scatterlist sg;
+	struct snd_pcm_runtime *runtime;
+	enum dma_data_direction dir;
+	dma_cookie_t cookie;
+	int is_play = fsi_stream_is_play(fsi, io);
+	int len;
+	dma_addr_t buf;
+
+	if (!fsi_stream_is_working(fsi, io))
+		return;
+
+	dai	= fsi_get_dai(io->substream);
+	chan	= io->chan;
+	runtime	= io->substream->runtime;
+	dir	= is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
+	len	= samples_to_bytes(runtime, io->period_samples);
+	buf	= fsi_dma_get_area(io);
+
+	dma_sync_single_for_device(dai->dev, io->dma, len, dir);
+
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)),
+		    len , offset_in_page(buf));
+	sg_dma_address(&sg) = buf;
+	sg_dma_len(&sg) = len;
+
+	desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir,
+						  DMA_PREP_INTERRUPT |
+						  DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(dai->dev, "device_prep_slave_sg() fail\n");
+		return;
+	}
+
+	desc->callback		= fsi_dma_complete;
+	desc->callback_param	= io;
+
+	cookie = desc->tx_submit(desc);
+	if (cookie < 0) {
+		dev_err(dai->dev, "tx_submit() fail\n");
+		return;
+	}
+
+	dma_async_issue_pending(chan);
+
+	/*
+	 * FIXME
+	 *
+	 * In DMAEngine case, codec and FSI cannot be started simultaneously
+	 * since FSI is using tasklet.
+	 * Therefore, in capture case, probably FSI FIFO will have got
+	 * overflow error in this point.
+	 * in that case, DMA cannot start transfer until error was cleared.
+	 */
+	if (!is_play) {
+		if (ERR_OVER & fsi_reg_read(fsi, DIFF_ST)) {
+			fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
+			fsi_reg_write(fsi, DIFF_ST, 0);
+		}
+	}
+}
+
+static bool fsi_dma_filter(struct dma_chan *chan, void *param)
+{
+	struct sh_dmae_slave *slave = param;
+
+	chan->private = slave;
+
+	return true;
+}
+
+static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	tasklet_schedule(&io->tasklet);
+
+	return 0;
+}
+
+static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
+				 int start)
+{
+	u32 bws;
+	u32 dma;
+
+	switch (io->sample_width * start) {
+	case 2:
+		bws = CR_BWS_16;
+		dma = VDMD_STREAM | DMA_ON;
+		break;
+	case 4:
+		bws = CR_BWS_24;
+		dma = VDMD_BACK | DMA_ON;
+		break;
+	default:
+		bws = 0;
+		dma = 0;
+	}
+
+	fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
+	fsi_reg_write(fsi, OUT_DMAC, dma);
+}
+
+static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	dma_cap_mask_t mask;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
+	if (!io->chan)
+		return -EIO;
+
+	tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
+
+	return 0;
+}
+
+static int fsi_dma_remove(struct fsi_priv *fsi, struct fsi_stream *io)
+{
+	tasklet_kill(&io->tasklet);
+
+	fsi_stream_stop(fsi, io);
+
+	if (io->chan)
+		dma_release_channel(io->chan);
+
+	io->chan = NULL;
+	return 0;
+}
+
+static struct fsi_stream_handler fsi_dma_push_handler = {
+	.init		= fsi_dma_init,
+	.quit		= fsi_dma_quit,
+	.probe		= fsi_dma_probe,
+	.transfer	= fsi_dma_transfer,
+	.remove		= fsi_dma_remove,
+	.start_stop	= fsi_dma_push_start_stop,
+};
+
+/*
  *		dai ops
  */
+static void fsi_fifo_init(struct fsi_priv *fsi,
+			  struct fsi_stream *io,
+			  struct device *dev)
+{
+	struct fsi_master *master = fsi_get_master(fsi);
+	int is_play = fsi_stream_is_play(fsi, io);
+	u32 shift, i;
+	int frame_capa;
+
+	/* get on-chip RAM capacity */
+	shift = fsi_master_read(master, FIFO_SZ);
+	shift >>= fsi_get_port_shift(fsi, io);
+	shift &= FIFO_SZ_MASK;
+	frame_capa = 256 << shift;
+	dev_dbg(dev, "fifo = %d words\n", frame_capa);
+
+	/*
+	 * The maximum number of sample data varies depending
+	 * on the number of channels selected for the format.
+	 *
+	 * FIFOs are used in 4-channel units in 3-channel mode
+	 * and in 8-channel units in 5- to 7-channel mode
+	 * meaning that more FIFOs than the required size of DPRAM
+	 * are used.
+	 *
+	 * ex) if 256 words of DP-RAM is connected
+	 * 1 channel:  256 (256 x 1 = 256)
+	 * 2 channels: 128 (128 x 2 = 256)
+	 * 3 channels:  64 ( 64 x 3 = 192)
+	 * 4 channels:  64 ( 64 x 4 = 256)
+	 * 5 channels:  32 ( 32 x 5 = 160)
+	 * 6 channels:  32 ( 32 x 6 = 192)
+	 * 7 channels:  32 ( 32 x 7 = 224)
+	 * 8 channels:  32 ( 32 x 8 = 256)
+	 */
+	for (i = 1; i < fsi->chan_num; i <<= 1)
+		frame_capa >>= 1;
+	dev_dbg(dev, "%d channel %d store\n",
+		fsi->chan_num, frame_capa);
+
+	io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa);
+
+	/*
+	 * set interrupt generation factor
+	 * clear FIFO
+	 */
+	if (is_play) {
+		fsi_reg_write(fsi,	DOFF_CTL, IRQ_HALF);
+		fsi_reg_mask_set(fsi,	DOFF_CTL, FIFO_CLR, FIFO_CLR);
+	} else {
+		fsi_reg_write(fsi,	DIFF_CTL, IRQ_HALF);
+		fsi_reg_mask_set(fsi,	DIFF_CTL, FIFO_CLR, FIFO_CLR);
+	}
+}
 
 static int fsi_hw_startup(struct fsi_priv *fsi,
-			  int is_play,
+			  struct fsi_stream *io,
 			  struct device *dev)
 {
 	struct fsi_master *master = fsi_get_master(fsi);
@@ -934,17 +1223,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
 	}
 
 	/* irq clear */
-	fsi_irq_disable(fsi, is_play);
+	fsi_irq_disable(fsi, io);
 	fsi_irq_clear_status(fsi);
 
 	/* fifo init */
-	fsi_fifo_init(fsi, is_play, dev);
+	fsi_fifo_init(fsi, io, dev);
 
 	return 0;
 }
 
 static void fsi_hw_shutdown(struct fsi_priv *fsi,
-			    int is_play,
 			    struct device *dev)
 {
 	if (fsi_is_clk_master(fsi))
@@ -955,18 +1243,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
-	int is_play = fsi_is_play(substream);
 
-	return fsi_hw_startup(fsi, is_play, dai->dev);
+	return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
 }
 
 static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *dai)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
-	int is_play = fsi_is_play(substream);
 
-	fsi_hw_shutdown(fsi, is_play, dai->dev);
+	fsi_hw_shutdown(fsi, dai->dev);
 	fsi->rate = 0;
 }
 
@@ -974,18 +1260,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
 			   struct snd_soc_dai *dai)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
-	int is_play = fsi_is_play(substream);
+	struct fsi_stream *io = fsi_stream_get(fsi, substream);
 	int ret = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
-		fsi_stream_push(fsi, is_play, substream);
-		ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
-		fsi_port_start(fsi, is_play);
+		fsi_stream_init(fsi, io, substream);
+		ret = fsi_stream_transfer(io);
+		if (0 == ret)
+			fsi_stream_start(fsi, io);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
-		fsi_port_stop(fsi, is_play);
-		fsi_stream_pop(fsi, is_play);
+		fsi_stream_stop(fsi, io);
+		fsi_stream_quit(fsi, io);
 		break;
 	}
 
@@ -1036,8 +1323,7 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
 static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
 	struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai);
-	struct fsi_master *master = fsi_get_master(fsi);
-	set_rate_func set_rate = fsi_get_info_set_rate(master);
+	set_rate_func set_rate = fsi_get_info_set_rate(fsi);
 	u32 flags = fsi_get_info_flags(fsi);
 	int ret;
 
@@ -1151,7 +1437,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
 static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
-	struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
+	struct fsi_stream *io = fsi_stream_get(fsi, substream);
 
 	return fsi_sample2frame(fsi, io->buff_sample_pos);
 }
@@ -1239,11 +1525,24 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
 /*
  *		platform function
  */
+static void fsi_handler_init(struct fsi_priv *fsi)
+{
+	fsi->playback.handler	= &fsi_pio_push_handler; /* default PIO */
+	fsi->playback.priv	= fsi;
+	fsi->capture.handler	= &fsi_pio_pop_handler;  /* default PIO */
+	fsi->capture.priv	= fsi;
+
+	if (fsi->info->tx_id) {
+		fsi->playback.slave.slave_id	= fsi->info->tx_id;
+		fsi->playback.handler		= &fsi_dma_push_handler;
+	}
+}
 
 static int fsi_probe(struct platform_device *pdev)
 {
 	struct fsi_master *master;
 	const struct platform_device_id	*id_entry;
+	struct sh_fsi_platform_info *info = pdev->dev.platform_data;
 	struct resource *res;
 	unsigned int irq;
 	int ret;
@@ -1278,17 +1577,30 @@ static int fsi_probe(struct platform_device *pdev)
 
 	/* master setting */
 	master->irq		= irq;
-	master->info		= pdev->dev.platform_data;
 	master->core		= (struct fsi_core *)id_entry->driver_data;
 	spin_lock_init(&master->lock);
 
 	/* FSI A setting */
 	master->fsia.base	= master->base;
 	master->fsia.master	= master;
+	master->fsia.info	= &info->port_a;
+	fsi_handler_init(&master->fsia);
+	ret = fsi_stream_probe(&master->fsia);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "FSIA stream probe failed\n");
+		goto exit_iounmap;
+	}
 
 	/* FSI B setting */
 	master->fsib.base	= master->base + 0x40;
 	master->fsib.master	= master;
+	master->fsib.info	= &info->port_b;
+	fsi_handler_init(&master->fsib);
+	ret = fsi_stream_probe(&master->fsib);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "FSIB stream probe failed\n");
+		goto exit_fsia;
+	}
 
 	pm_runtime_enable(&pdev->dev);
 	dev_set_drvdata(&pdev->dev, master);
@@ -1297,7 +1609,7 @@ static int fsi_probe(struct platform_device *pdev)
 			  id_entry->name, master);
 	if (ret) {
 		dev_err(&pdev->dev, "irq request err\n");
-		goto exit_iounmap;
+		goto exit_fsib;
 	}
 
 	ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
@@ -1319,6 +1631,10 @@ exit_snd_soc:
 	snd_soc_unregister_platform(&pdev->dev);
 exit_free_irq:
 	free_irq(irq, master);
+exit_fsib:
+	fsi_stream_remove(&master->fsib);
+exit_fsia:
+	fsi_stream_remove(&master->fsia);
 exit_iounmap:
 	iounmap(master->base);
 	pm_runtime_disable(&pdev->dev);
@@ -1341,6 +1657,9 @@ static int fsi_remove(struct platform_device *pdev)
 	snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
 	snd_soc_unregister_platform(&pdev->dev);
 
+	fsi_stream_remove(&master->fsia);
+	fsi_stream_remove(&master->fsib);
+
 	iounmap(master->base);
 	kfree(master);
 
@@ -1348,30 +1667,29 @@ static int fsi_remove(struct platform_device *pdev)
 }
 
 static void __fsi_suspend(struct fsi_priv *fsi,
-			  int is_play,
+			  struct fsi_stream *io,
 			  struct device *dev)
 {
-	if (!fsi_stream_is_working(fsi, is_play))
+	if (!fsi_stream_is_working(fsi, io))
 		return;
 
-	fsi_port_stop(fsi, is_play);
-	fsi_hw_shutdown(fsi, is_play, dev);
+	fsi_stream_stop(fsi, io);
+	fsi_hw_shutdown(fsi, dev);
 }
 
 static void __fsi_resume(struct fsi_priv *fsi,
-			 int is_play,
+			 struct fsi_stream *io,
 			 struct device *dev)
 {
-	if (!fsi_stream_is_working(fsi, is_play))
+	if (!fsi_stream_is_working(fsi, io))
 		return;
 
-	fsi_hw_startup(fsi, is_play, dev);
+	fsi_hw_startup(fsi, io, dev);
 
 	if (fsi_is_clk_master(fsi) && fsi->rate)
 		fsi_set_master_clk(dev, fsi, fsi->rate, 1);
 
-	fsi_port_start(fsi, is_play);
-
+	fsi_stream_start(fsi, io);
 }
 
 static int fsi_suspend(struct device *dev)
@@ -1380,11 +1698,11 @@ static int fsi_suspend(struct device *dev)
 	struct fsi_priv *fsia = &master->fsia;
 	struct fsi_priv *fsib = &master->fsib;
 
-	__fsi_suspend(fsia, 1, dev);
-	__fsi_suspend(fsia, 0, dev);
+	__fsi_suspend(fsia, &fsia->playback, dev);
+	__fsi_suspend(fsia, &fsia->capture, dev);
 
-	__fsi_suspend(fsib, 1, dev);
-	__fsi_suspend(fsib, 0, dev);
+	__fsi_suspend(fsib, &fsib->playback, dev);
+	__fsi_suspend(fsib, &fsib->capture, dev);
 
 	return 0;
 }
@@ -1395,32 +1713,18 @@ static int fsi_resume(struct device *dev)
 	struct fsi_priv *fsia = &master->fsia;
 	struct fsi_priv *fsib = &master->fsib;
 
-	__fsi_resume(fsia, 1, dev);
-	__fsi_resume(fsia, 0, dev);
+	__fsi_resume(fsia, &fsia->playback, dev);
+	__fsi_resume(fsia, &fsia->capture, dev);
 
-	__fsi_resume(fsib, 1, dev);
-	__fsi_resume(fsib, 0, dev);
+	__fsi_resume(fsib, &fsib->playback, dev);
+	__fsi_resume(fsib, &fsib->capture, dev);
 
 	return 0;
 }
 
-static int fsi_runtime_nop(struct device *dev)
-{
-	/* Runtime PM callback shared between ->runtime_suspend()
-	 * and ->runtime_resume(). Simply returns success.
-	 *
-	 * This driver re-initializes all registers after
-	 * pm_runtime_get_sync() anyway so there is no need
-	 * to save and restore registers here.
-	 */
-	return 0;
-}
-
 static struct dev_pm_ops fsi_pm_ops = {
 	.suspend		= fsi_suspend,
 	.resume			= fsi_resume,
-	.runtime_suspend	= fsi_runtime_nop,
-	.runtime_resume		= fsi_runtime_nop,
 };
 
 static struct fsi_core fsi1_core = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 92cee24..fc0fd34 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -277,8 +277,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
 	codec->debugfs_codec_root = debugfs_create_dir(codec->name,
 						       debugfs_card_root);
 	if (!codec->debugfs_codec_root) {
-		printk(KERN_WARNING
-		       "ASoC: Failed to create codec debugfs directory\n");
+		dev_warn(codec->dev, "Failed to create codec debugfs directory\n");
 		return;
 	}
 
@@ -291,8 +290,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
 						 codec->debugfs_codec_root,
 						 codec, &codec_reg_fops);
 	if (!codec->debugfs_reg)
-		printk(KERN_WARNING
-		       "ASoC: Failed to create codec register debugfs file\n");
+		dev_warn(codec->dev, "Failed to create codec register debugfs file\n");
 
 	snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
 }
@@ -302,6 +300,27 @@ static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
 	debugfs_remove_recursive(codec->debugfs_codec_root);
 }
 
+static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
+{
+	struct dentry *debugfs_card_root = platform->card->debugfs_card_root;
+
+	platform->debugfs_platform_root = debugfs_create_dir(platform->name,
+						       debugfs_card_root);
+	if (!platform->debugfs_platform_root) {
+		dev_warn(platform->dev,
+			"Failed to create platform debugfs directory\n");
+		return;
+	}
+
+	snd_soc_dapm_debugfs_init(&platform->dapm,
+		platform->debugfs_platform_root);
+}
+
+static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
+{
+	debugfs_remove_recursive(platform->debugfs_platform_root);
+}
+
 static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
 				    size_t count, loff_t *ppos)
 {
@@ -435,6 +454,14 @@ static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
 {
 }
 
+static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform)
+{
+}
+
+static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
+{
+}
+
 static inline void soc_init_card_debugfs(struct snd_soc_card *card)
 {
 }
@@ -546,18 +573,20 @@ int snd_soc_suspend(struct device *dev)
 	}
 
 	for (i = 0; i < card->num_rtd; i++) {
-		struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver;
+		struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
 
 		if (card->rtd[i].dai_link->ignore_suspend)
 			continue;
 
-		if (driver->playback.stream_name != NULL)
-			snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name,
-				SND_SOC_DAPM_STREAM_SUSPEND);
+		snd_soc_dapm_stream_event(&card->rtd[i],
+					  SNDRV_PCM_STREAM_PLAYBACK,
+					  codec_dai,
+					  SND_SOC_DAPM_STREAM_SUSPEND);
 
-		if (driver->capture.stream_name != NULL)
-			snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name,
-				SND_SOC_DAPM_STREAM_SUSPEND);
+		snd_soc_dapm_stream_event(&card->rtd[i],
+					  SNDRV_PCM_STREAM_CAPTURE,
+					  codec_dai,
+					  SND_SOC_DAPM_STREAM_SUSPEND);
 	}
 
 	/* suspend all CODECs */
@@ -660,18 +689,18 @@ static void soc_resume_deferred(struct work_struct *work)
 	}
 
 	for (i = 0; i < card->num_rtd; i++) {
-		struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver;
+		struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
 
 		if (card->rtd[i].dai_link->ignore_suspend)
 			continue;
 
-		if (driver->playback.stream_name != NULL)
-			snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name,
-				SND_SOC_DAPM_STREAM_RESUME);
+		snd_soc_dapm_stream_event(&card->rtd[i],
+					  SNDRV_PCM_STREAM_PLAYBACK, codec_dai,
+					  SND_SOC_DAPM_STREAM_RESUME);
 
-		if (driver->capture.stream_name != NULL)
-			snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name,
-				SND_SOC_DAPM_STREAM_RESUME);
+		snd_soc_dapm_stream_event(&card->rtd[i],
+					  SNDRV_PCM_STREAM_CAPTURE, codec_dai,
+					  SND_SOC_DAPM_STREAM_RESUME);
 	}
 
 	/* unmute any active DACs */
@@ -904,7 +933,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
 		if (codec_dai->driver->remove) {
 			err = codec_dai->driver->remove(codec_dai);
 			if (err < 0)
-				printk(KERN_ERR "asoc: failed to remove %s\n", codec_dai->name);
+				pr_err("asoc: failed to remove %s: %d\n",
+							codec_dai->name, err);
 		}
 		codec_dai->probed = 0;
 		list_del(&codec_dai->card_list);
@@ -916,12 +946,14 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
 		if (platform->driver->remove) {
 			err = platform->driver->remove(platform);
 			if (err < 0)
-				printk(KERN_ERR "asoc: failed to remove %s\n", platform->name);
+				pr_err("asoc: failed to remove %s: %d\n",
+							platform->name, err);
 		}
 
 		/* Make sure all DAPM widgets are freed */
 		snd_soc_dapm_free(&platform->dapm);
 
+		soc_cleanup_platform_debugfs(platform);
 		platform->probed = 0;
 		list_del(&platform->card_list);
 		module_put(platform->dev->driver->owner);
@@ -938,7 +970,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
 		if (cpu_dai->driver->remove) {
 			err = cpu_dai->driver->remove(cpu_dai);
 			if (err < 0)
-				printk(KERN_ERR "asoc: failed to remove %s\n", cpu_dai->name);
+				pr_err("asoc: failed to remove %s: %d\n",
+							cpu_dai->name, err);
 		}
 		cpu_dai->probed = 0;
 		list_del(&cpu_dai->card_list);
@@ -980,6 +1013,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
 {
 	int ret = 0;
 	const struct snd_soc_codec_driver *driver = codec->driver;
+	struct snd_soc_dai *dai;
 
 	codec->card = card;
 	codec->dapm.card = card;
@@ -994,6 +1028,14 @@ static int soc_probe_codec(struct snd_soc_card *card,
 		snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets,
 					  driver->num_dapm_widgets);
 
+	/* Create DAPM widgets for each DAI stream */
+	list_for_each_entry(dai, &dai_list, list) {
+		if (dai->dev != codec->dev)
+			continue;
+
+		snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
+	}
+
 	codec->dapm.idle_bias_off = driver->idle_bias_off;
 
 	if (driver->probe) {
@@ -1007,7 +1049,7 @@ static int soc_probe_codec(struct snd_soc_card *card,
 	}
 
 	if (driver->controls)
-		snd_soc_add_controls(codec, driver->controls,
+		snd_soc_add_codec_controls(codec, driver->controls,
 				     driver->num_controls);
 	if (driver->dapm_routes)
 		snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes,
@@ -1039,6 +1081,8 @@ static int soc_probe_platform(struct snd_soc_card *card,
 	if (!try_module_get(platform->dev->driver->owner))
 		return -ENODEV;
 
+	soc_init_platform_debugfs(platform);
+
 	if (driver->dapm_widgets)
 		snd_soc_dapm_new_controls(&platform->dapm,
 			driver->dapm_widgets, driver->num_dapm_widgets);
@@ -1183,8 +1227,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
 		if (cpu_dai->driver->probe) {
 			ret = cpu_dai->driver->probe(cpu_dai);
 			if (ret < 0) {
-				printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n",
-						cpu_dai->name);
+				pr_err("asoc: failed to probe CPU DAI %s: %d\n",
+							cpu_dai->name, ret);
 				module_put(cpu_dai->dev->driver->owner);
 				return ret;
 			}
@@ -1215,8 +1259,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
 		if (codec_dai->driver->probe) {
 			ret = codec_dai->driver->probe(codec_dai);
 			if (ret < 0) {
-				printk(KERN_ERR "asoc: failed to probe CODEC DAI %s\n",
-						codec_dai->name);
+				pr_err("asoc: failed to probe CODEC DAI %s: %d\n",
+							codec_dai->name, ret);
 				return ret;
 			}
 		}
@@ -1236,12 +1280,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
 
 	ret = device_create_file(rtd->dev, &dev_attr_pmdown_time);
 	if (ret < 0)
-		printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
+		pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
 
 	/* create the pcm */
 	ret = soc_new_pcm(rtd, num);
 	if (ret < 0) {
-		printk(KERN_ERR "asoc: can't create pcm %s\n", dai_link->stream_name);
+		pr_err("asoc: can't create pcm %s :%d\n",
+				dai_link->stream_name, ret);
 		return ret;
 	}
 
@@ -1274,7 +1319,7 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd)
 
 		ret = soc_ac97_dev_register(rtd->codec);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: AC97 device register failed\n");
+			pr_err("asoc: AC97 device register failed:%d\n", ret);
 			return ret;
 		}
 
@@ -1414,8 +1459,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 	ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 			card->owner, 0, &card->snd_card);
 	if (ret < 0) {
-		printk(KERN_ERR "asoc: can't create sound card for card %s\n",
-			card->name);
+		pr_err("asoc: can't create sound card for card %s: %d\n",
+			card->name, ret);
 		mutex_unlock(&card->mutex);
 		return;
 	}
@@ -1468,13 +1513,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 		}
 	}
 
-	/* We should have a non-codec control add function but we don't */
+	snd_soc_dapm_link_dai_widgets(card);
+
 	if (card->controls)
-		snd_soc_add_controls(list_first_entry(&card->codec_dev_list,
-						      struct snd_soc_codec,
-						      card_list),
-				     card->controls,
-				     card->num_controls);
+		snd_soc_add_card_controls(card, card->controls, card->num_controls);
 
 	if (card->dapm_routes)
 		snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
@@ -1538,7 +1580,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 
 	ret = snd_card_register(card->snd_card);
 	if (ret < 0) {
-		printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
+		pr_err("asoc: failed to register soundcard for %s: %d\n",
+							card->name, ret);
 		goto probe_aux_dev_err;
 	}
 
@@ -1547,7 +1590,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 	for (i = 0; i < card->num_rtd; i++) {
 		ret = soc_register_ac97_dai_link(&card->rtd[i]);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+			pr_err("asoc: failed to register AC97 %s: %d\n",
+							card->name, ret);
 			while (--i >= 0)
 				soc_unregister_ac97_dai_link(card->rtd[i].codec);
 			goto probe_aux_dev_err;
@@ -1674,8 +1718,7 @@ int snd_soc_poweroff(struct device *dev)
 EXPORT_SYMBOL_GPL(snd_soc_poweroff);
 
 const struct dev_pm_ops snd_soc_pm_ops = {
-	.suspend = snd_soc_suspend,
-	.resume = snd_soc_resume,
+	SET_SYSTEM_SLEEP_PM_OPS(snd_soc_suspend, snd_soc_resume)
 	.poweroff = snd_soc_poweroff,
 };
 EXPORT_SYMBOL_GPL(snd_soc_pm_ops);
@@ -1880,23 +1923,28 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
 int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
 				unsigned int mask, unsigned int value)
 {
-	int change;
+	bool change;
 	unsigned int old, new;
 	int ret;
 
-	ret = snd_soc_read(codec, reg);
-	if (ret < 0)
-		return ret;
-
-	old = ret;
-	new = (old & ~mask) | (value & mask);
-	change = old != new;
-	if (change) {
-		ret = snd_soc_write(codec, reg, new);
+	if (codec->using_regmap) {
+		ret = regmap_update_bits_check(codec->control_data, reg,
+					       mask, value, &change);
+	} else {
+		ret = snd_soc_read(codec, reg);
 		if (ret < 0)
 			return ret;
+
+		old = ret;
+		new = (old & ~mask) | (value & mask);
+		change = old != new;
+		if (change)
+			ret = snd_soc_write(codec, reg, new);
 	}
 
+	if (ret < 0)
+		return ret;
+
 	return change;
 }
 EXPORT_SYMBOL_GPL(snd_soc_update_bits);
@@ -1987,7 +2035,7 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
  * Returns 0 for success, else error.
  */
 struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
-				  void *data, char *long_name,
+				  void *data, const char *long_name,
 				  const char *prefix)
 {
 	struct snd_kcontrol_new template;
@@ -2022,9 +2070,28 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
 }
 EXPORT_SYMBOL_GPL(snd_soc_cnew);
 
+static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
+	const struct snd_kcontrol_new *controls, int num_controls,
+	const char *prefix, void *data)
+{
+	int err, i;
+
+	for (i = 0; i < num_controls; i++) {
+		const struct snd_kcontrol_new *control = &controls[i];
+		err = snd_ctl_add(card, snd_soc_cnew(control, data,
+						     control->name, prefix));
+		if (err < 0) {
+			dev_err(dev, "Failed to add %s: %d\n", control->name, err);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 /**
- * snd_soc_add_controls - add an array of controls to a codec.
- * Convienience function to add a list of controls. Many codecs were
+ * snd_soc_add_codec_controls - add an array of controls to a codec.
+ * Convenience function to add a list of controls. Many codecs were
  * duplicating this code.
  *
  * @codec: codec to add controls to
@@ -2033,31 +2100,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cnew);
  *
  * Return 0 for success, else error.
  */
-int snd_soc_add_controls(struct snd_soc_codec *codec,
+int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
 	const struct snd_kcontrol_new *controls, int num_controls)
 {
 	struct snd_card *card = codec->card->snd_card;
-	int err, i;
-
-	for (i = 0; i < num_controls; i++) {
-		const struct snd_kcontrol_new *control = &controls[i];
-		err = snd_ctl_add(card, snd_soc_cnew(control, codec,
-						     control->name,
-						     codec->name_prefix));
-		if (err < 0) {
-			dev_err(codec->dev, "%s: Failed to add %s: %d\n",
-				codec->name, control->name, err);
-			return err;
-		}
-	}
 
-	return 0;
+	return snd_soc_add_controls(card, codec->dev, controls, num_controls,
+			codec->name_prefix, codec);
 }
-EXPORT_SYMBOL_GPL(snd_soc_add_controls);
+EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls);
 
 /**
  * snd_soc_add_platform_controls - add an array of controls to a platform.
- * Convienience function to add a list of controls.
+ * Convenience function to add a list of controls.
  *
  * @platform: platform to add controls to
  * @controls: array of controls to add
@@ -2069,23 +2124,53 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
 	const struct snd_kcontrol_new *controls, int num_controls)
 {
 	struct snd_card *card = platform->card->snd_card;
-	int err, i;
-
-	for (i = 0; i < num_controls; i++) {
-		const struct snd_kcontrol_new *control = &controls[i];
-		err = snd_ctl_add(card, snd_soc_cnew(control, platform,
-				control->name, NULL));
-		if (err < 0) {
-			dev_err(platform->dev, "Failed to add %s %d\n",control->name, err);
-			return err;
-		}
-	}
 
-	return 0;
+	return snd_soc_add_controls(card, platform->dev, controls, num_controls,
+			NULL, platform);
 }
 EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls);
 
 /**
+ * snd_soc_add_card_controls - add an array of controls to a SoC card.
+ * Convenience function to add a list of controls.
+ *
+ * @soc_card: SoC card to add controls to
+ * @controls: array of controls to add
+ * @num_controls: number of elements in the array
+ *
+ * Return 0 for success, else error.
+ */
+int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
+	const struct snd_kcontrol_new *controls, int num_controls)
+{
+	struct snd_card *card = soc_card->snd_card;
+
+	return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
+			NULL, soc_card);
+}
+EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
+
+/**
+ * snd_soc_add_dai_controls - add an array of controls to a DAI.
+ * Convienience function to add a list of controls.
+ *
+ * @dai: DAI to add controls to
+ * @controls: array of controls to add
+ * @num_controls: number of elements in the array
+ *
+ * Return 0 for success, else error.
+ */
+int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
+	const struct snd_kcontrol_new *controls, int num_controls)
+{
+	struct snd_card *card = dai->card->snd_card;
+
+	return snd_soc_add_controls(card, dai->dev, controls, num_controls,
+			NULL, dai);
+}
+EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
+
+/**
  * snd_soc_info_enum_double - enumerated double mixer info callback
  * @kcontrol: mixer control
  * @uinfo: control element information
@@ -2651,6 +2736,115 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
 
+int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct soc_bytes *params = (void *)kcontrol->private_value;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+	uinfo->count = params->num_regs * codec->val_bytes;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_bytes_info);
+
+int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_bytes *params = (void *)kcontrol->private_value;
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int ret;
+
+	if (codec->using_regmap)
+		ret = regmap_raw_read(codec->control_data, params->base,
+				      ucontrol->value.bytes.data,
+				      params->num_regs * codec->val_bytes);
+	else
+		ret = -EINVAL;
+
+	/* Hide any masked bytes to ensure consistent data reporting */
+	if (ret == 0 && params->mask) {
+		switch (codec->val_bytes) {
+		case 1:
+			ucontrol->value.bytes.data[0] &= ~params->mask;
+			break;
+		case 2:
+			((u16 *)(&ucontrol->value.bytes.data))[0]
+				&= ~params->mask;
+			break;
+		case 4:
+			((u32 *)(&ucontrol->value.bytes.data))[0]
+				&= ~params->mask;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_bytes_get);
+
+int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol)
+{
+	struct soc_bytes *params = (void *)kcontrol->private_value;
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	int ret, len;
+	unsigned int val;
+	void *data;
+
+	if (!codec->using_regmap)
+		return -EINVAL;
+
+	data = ucontrol->value.bytes.data;
+	len = params->num_regs * codec->val_bytes;
+
+	/*
+	 * If we've got a mask then we need to preserve the register
+	 * bits.  We shouldn't modify the incoming data so take a
+	 * copy.
+	 */
+	if (params->mask) {
+		ret = regmap_read(codec->control_data, params->base, &val);
+		if (ret != 0)
+			return ret;
+
+		val &= params->mask;
+
+		data = kmemdup(data, len, GFP_KERNEL);
+		if (!data)
+			return -ENOMEM;
+
+		switch (codec->val_bytes) {
+		case 1:
+			((u8 *)data)[0] &= ~params->mask;
+			((u8 *)data)[0] |= val;
+			break;
+		case 2:
+			((u16 *)data)[0] &= cpu_to_be16(~params->mask);
+			((u16 *)data)[0] |= cpu_to_be16(val);
+			break;
+		case 4:
+			((u32 *)data)[0] &= cpu_to_be32(~params->mask);
+			((u32 *)data)[0] |= cpu_to_be32(val);
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	ret = regmap_raw_write(codec->control_data, params->base,
+			       data, len);
+
+	if (params->mask)
+		kfree(data);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
+
 /**
  * snd_soc_dai_set_sysclk - configure DAI system or master clock.
  * @dai: DAI
@@ -2875,7 +3069,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
 		 */
 		if (!!link->codec_name == !!link->codec_of_node) {
 			dev_err(card->dev,
-				"Neither/both codec name/of_node are set\n");
+				"Neither/both codec name/of_node are set for %s\n",
+				link->name);
 			return -EINVAL;
 		}
 
@@ -2885,7 +3080,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
 		 */
 		if (link->platform_name && link->platform_of_node) {
 			dev_err(card->dev,
-				"Both platform name/of_node are set\n");
+				"Both platform name/of_node are set for %s\n", link->name);
 			return -EINVAL;
 		}
 
@@ -2895,7 +3090,8 @@ int snd_soc_register_card(struct snd_soc_card *card)
 		 */
 		if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) {
 			dev_err(card->dev,
-				"Neither/both cpu_dai name/of_node are set\n");
+				"Neither/both cpu_dai name/of_node are set for %s\n",
+				link->name);
 			return -EINVAL;
 		}
 	}
@@ -3002,7 +3198,7 @@ static inline char *fmt_multiple_name(struct device *dev,
 		struct snd_soc_dai_driver *dai_drv)
 {
 	if (dai_drv->name == NULL) {
-		printk(KERN_ERR "asoc: error - multiple DAI %s registered with no name\n",
+		pr_err("asoc: error - multiple DAI %s registered with no name\n",
 				dev_name(dev));
 		return NULL;
 	}
@@ -3285,6 +3481,7 @@ int snd_soc_register_codec(struct device *dev,
 	codec->volatile_register = codec_drv->volatile_register;
 	codec->readable_register = codec_drv->readable_register;
 	codec->writable_register = codec_drv->writable_register;
+	codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time;
 	codec->dapm.bias_level = SND_SOC_BIAS_OFF;
 	codec->dapm.dev = dev;
 	codec->dapm.codec = codec;
@@ -3473,8 +3670,7 @@ static int __init snd_soc_init(void)
 #ifdef CONFIG_DEBUG_FS
 	snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
 	if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
-		printk(KERN_WARNING
-		       "ASoC: Failed to create debugfs directory\n");
+		pr_warn("ASoC: Failed to create debugfs directory\n");
 		snd_soc_debugfs_root = NULL;
 	}
 
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1f55ded..c9b088d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -14,19 +14,13 @@
  *      dynamic configuration of codec internal audio paths and active
  *      DACs/ADCs.
  *    o Platform power domain - can support external components i.e. amps and
- *      mic/meadphone insertion events.
+ *      mic/headphone insertion events.
  *    o Automatic Mic Bias support
  *    o Jack insertion power event initiation - e.g. hp insertion will enable
  *      sinks, dacs, etc
- *    o Delayed powerdown of audio susbsystem to reduce pops between a quick
+ *    o Delayed power down of audio subsystem to reduce pops between a quick
  *      device reopen.
  *
- *  Todo:
- *    o DAPM power change sequencing - allow for configurable per
- *      codec sequences.
- *    o Support for analogue bias optimisation.
- *    o Support for reduced codec oversampling rates.
- *    o Support for reduced codec bias currents.
  */
 
 #include <linux/module.h>
@@ -40,6 +34,7 @@
 #include <linux/jiffies.h>
 #include <linux/debugfs.h>
 #include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -55,7 +50,9 @@
 static int dapm_up_seq[] = {
 	[snd_soc_dapm_pre] = 0,
 	[snd_soc_dapm_supply] = 1,
+	[snd_soc_dapm_regulator_supply] = 1,
 	[snd_soc_dapm_micbias] = 2,
+	[snd_soc_dapm_dai] = 3,
 	[snd_soc_dapm_aif_in] = 3,
 	[snd_soc_dapm_aif_out] = 3,
 	[snd_soc_dapm_mic] = 4,
@@ -90,6 +87,8 @@ static int dapm_down_seq[] = {
 	[snd_soc_dapm_value_mux] = 9,
 	[snd_soc_dapm_aif_in] = 10,
 	[snd_soc_dapm_aif_out] = 10,
+	[snd_soc_dapm_dai] = 10,
+	[snd_soc_dapm_regulator_supply] = 11,
 	[snd_soc_dapm_supply] = 11,
 	[snd_soc_dapm_post] = 12,
 };
@@ -172,6 +171,19 @@ static inline struct snd_soc_card *dapm_get_soc_card(
 	return NULL;
 }
 
+static void dapm_reset(struct snd_soc_card *card)
+{
+	struct snd_soc_dapm_widget *w;
+
+	memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
+
+	list_for_each_entry(w, &card->widgets, list) {
+		w->power_checked = false;
+		w->inputs = -1;
+		w->outputs = -1;
+	}
+}
+
 static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg)
 {
 	if (w->codec)
@@ -197,21 +209,28 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
 static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
 	unsigned short reg, unsigned int mask, unsigned int value)
 {
-	int change;
+	bool change;
 	unsigned int old, new;
 	int ret;
 
-	ret = soc_widget_read(w, reg);
-	if (ret < 0)
-		return ret;
-
-	old = ret;
-	new = (old & ~mask) | (value & mask);
-	change = old != new;
-	if (change) {
-		ret = soc_widget_write(w, reg, new);
+	if (w->codec && w->codec->using_regmap) {
+		ret = regmap_update_bits_check(w->codec->control_data,
+					       reg, mask, value, &change);
+		if (ret != 0)
+			return ret;
+	} else {
+		ret = soc_widget_read(w, reg);
 		if (ret < 0)
 			return ret;
+
+		old = ret;
+		new = (old & ~mask) | (value & mask);
+		change = old != new;
+		if (change) {
+			ret = soc_widget_write(w, reg, new);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
 	return change;
@@ -345,8 +364,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
 	case snd_soc_dapm_micbias:
 	case snd_soc_dapm_vmid:
 	case snd_soc_dapm_supply:
+	case snd_soc_dapm_regulator_supply:
 	case snd_soc_dapm_aif_in:
 	case snd_soc_dapm_aif_out:
+	case snd_soc_dapm_dai:
 	case snd_soc_dapm_hp:
 	case snd_soc_dapm_mic:
 	case snd_soc_dapm_spk:
@@ -504,17 +525,17 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
 				 * for widgets so cut the prefix off
 				 * the front of the widget name.
 				 */
-				snprintf(path->long_name, name_len, "%s %s",
-					 w->name + prefix_len,
+				snprintf((char *)path->long_name, name_len,
+					 "%s %s", w->name + prefix_len,
 					 w->kcontrol_news[i].name);
 				break;
 			case snd_soc_dapm_mixer_named_ctl:
-				snprintf(path->long_name, name_len, "%s",
-					 w->kcontrol_news[i].name);
+				snprintf((char *)path->long_name, name_len,
+					 "%s", w->kcontrol_news[i].name);
 				break;
 			}
 
-			path->long_name[name_len - 1] = '\0';
+			((char *)path->long_name)[name_len - 1] = '\0';
 
 			path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i],
 						      wlist, path->long_name,
@@ -548,7 +569,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
 	struct snd_soc_dapm_widget_list *wlist;
 	int shared, wlistentries;
 	size_t wlistsize;
-	char *name;
+	const char *name;
 
 	if (w->num_kcontrols != 1) {
 		dev_err(dapm->dev,
@@ -673,12 +694,18 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
 
 	DAPM_UPDATE_STAT(widget, path_checks);
 
-	if (widget->id == snd_soc_dapm_supply)
+	switch (widget->id) {
+	case snd_soc_dapm_supply:
+	case snd_soc_dapm_regulator_supply:
 		return 0;
+	default:
+		break;
+	}
 
 	switch (widget->id) {
 	case snd_soc_dapm_adc:
 	case snd_soc_dapm_aif_out:
+	case snd_soc_dapm_dai:
 		if (widget->active) {
 			widget->outputs = snd_soc_dapm_suspend_check(widget);
 			return widget->outputs;
@@ -738,13 +765,19 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
 
 	DAPM_UPDATE_STAT(widget, path_checks);
 
-	if (widget->id == snd_soc_dapm_supply)
+	switch (widget->id) {
+	case snd_soc_dapm_supply:
+	case snd_soc_dapm_regulator_supply:
 		return 0;
+	default:
+		break;
+	}
 
 	/* active stream ? */
 	switch (widget->id) {
 	case snd_soc_dapm_dac:
 	case snd_soc_dapm_aif_in:
+	case snd_soc_dapm_dai:
 		if (widget->active) {
 			widget->inputs = snd_soc_dapm_suspend_check(widget);
 			return widget->inputs;
@@ -821,6 +854,19 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
 }
 EXPORT_SYMBOL_GPL(dapm_reg_event);
 
+/*
+ * Handler for regulator supply widget.
+ */
+int dapm_regulator_event(struct snd_soc_dapm_widget *w,
+		   struct snd_kcontrol *kcontrol, int event)
+{
+	if (SND_SOC_DAPM_EVENT_ON(event))
+		return regulator_enable(w->priv);
+	else
+		return regulator_disable_deferred(w->priv, w->shift);
+}
+EXPORT_SYMBOL_GPL(dapm_regulator_event);
+
 static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
 {
 	if (w->power_checked)
@@ -851,6 +897,13 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
 	return out != 0 && in != 0;
 }
 
+static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
+{
+	DAPM_UPDATE_STAT(w, power_checks);
+
+	return w->active;
+}
+
 /* Check to see if an ADC has power */
 static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
 {
@@ -1251,7 +1304,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
 			dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
 
 		if (d->dev)
-			pm_runtime_put_sync(d->dev);
+			pm_runtime_put(d->dev);
 	}
 
 	/* If we just powered up then move to active bias */
@@ -1301,6 +1354,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
 	}
 	switch (w->id) {
 	case snd_soc_dapm_supply:
+	case snd_soc_dapm_regulator_supply:
 		/* Supplies can't affect their outputs, only their inputs */
 		break;
 	default:
@@ -1373,13 +1427,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
 		}
 	}
 
-	memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
-
-	list_for_each_entry(w, &card->widgets, list) {
-		w->power_checked = false;
-		w->inputs = -1;
-		w->outputs = -1;
-	}
+	dapm_reset(card);
 
 	/* Check which widgets we need to power and store them in
 	 * lists indicating if they should be powered up or down.  We
@@ -1400,10 +1448,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
 			/* Supplies and micbiases only bring the
 			 * context up to STANDBY as unless something
 			 * else is active and passing audio they
-			 * generally don't require full power.
+			 * generally don't require full power.  Signal
+			 * generators are virtual pins and have no
+			 * power impact themselves.
 			 */
 			switch (w->id) {
+			case snd_soc_dapm_siggen:
+				break;
 			case snd_soc_dapm_supply:
+			case snd_soc_dapm_regulator_supply:
 			case snd_soc_dapm_micbias:
 				if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
 					d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1475,6 +1528,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
 					&async_domain);
 	async_synchronize_full_domain(&async_domain);
 
+	/* do we need to notify any clients that DAPM event is complete */
+	list_for_each_entry(d, &card->dapm_list, list) {
+		if (d->stream_event)
+			d->stream_event(d, event);
+	}
+
 	pop_dbg(dapm->dev, card->pop_time,
 		"DAPM sequencing finished, waiting %dms\n", card->pop_time);
 	pop_wait(card->pop_time);
@@ -1659,9 +1718,8 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
 #endif
 
 /* test and update the power status of a mux widget */
-static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
-				 struct snd_kcontrol *kcontrol, int change,
-				 int mux, struct soc_enum *e)
+int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
+				 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
 {
 	struct snd_soc_dapm_path *path;
 	int found = 0;
@@ -1671,9 +1729,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
 	    widget->id != snd_soc_dapm_value_mux)
 		return -ENODEV;
 
-	if (!change)
-		return 0;
-
 	/* find dapm widget path assoc with kcontrol */
 	list_for_each_entry(path, &widget->dapm->card->paths, list) {
 		if (path->kcontrol != kcontrol)
@@ -1702,9 +1757,10 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
 
 /* test and update the power status of a mixer or switch widget */
-static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
+int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
 				   struct snd_kcontrol *kcontrol, int connect)
 {
 	struct snd_soc_dapm_path *path;
@@ -1733,6 +1789,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
 
 /* show dapm widget status in sys fs */
 static ssize_t dapm_widget_show(struct device *dev,
@@ -1762,6 +1819,7 @@ static ssize_t dapm_widget_show(struct device *dev,
 		case snd_soc_dapm_mixer:
 		case snd_soc_dapm_mixer_named_ctl:
 		case snd_soc_dapm_supply:
+		case snd_soc_dapm_regulator_supply:
 			if (w->name)
 				count += sprintf(buf + count, "%s: %s\n",
 					w->name, w->power ? "On":"Off");
@@ -1869,10 +1927,12 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
 		return -EINVAL;
 	}
 
+	if (w->connected != status)
+		dapm_mark_dirty(w, "pin configuration");
+
 	w->connected = status;
 	if (status == 0)
 		w->force = 0;
-	dapm_mark_dirty(w, "pin configuration");
 
 	return 0;
 }
@@ -2000,8 +2060,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
 	case snd_soc_dapm_pre:
 	case snd_soc_dapm_post:
 	case snd_soc_dapm_supply:
+	case snd_soc_dapm_regulator_supply:
 	case snd_soc_dapm_aif_in:
 	case snd_soc_dapm_aif_out:
+	case snd_soc_dapm_dai:
 		list_add(&path->list, &dapm->card->paths);
 		list_add(&path->list_sink, &wsink->sources);
 		list_add(&path->list_source, &wsource->sinks);
@@ -2315,7 +2377,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
 			update.val = val;
 			widget->dapm->update = &update;
 
-			dapm_mixer_update_power(widget, kcontrol, connect);
+			snd_soc_dapm_mixer_update_power(widget, kcontrol, connect);
 
 			widget->dapm->update = NULL;
 		}
@@ -2406,7 +2468,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
 			update.val = val;
 			widget->dapm->update = &update;
 
-			dapm_mux_update_power(widget, kcontrol, change, mux, e);
+			snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
 
 			widget->dapm->update = NULL;
 		}
@@ -2467,8 +2529,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
 
 			widget->value = ucontrol->value.enumerated.item[0];
 
-			dapm_mux_update_power(widget, kcontrol, change,
-					      widget->value, e);
+			snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
 		}
 	}
 
@@ -2571,7 +2632,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
 			update.val = val;
 			widget->dapm->update = &update;
 
-			dapm_mux_update_power(widget, kcontrol, change, mux, e);
+			snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
 
 			widget->dapm->update = NULL;
 		}
@@ -2611,15 +2672,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch);
 int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 	const char *pin = (const char *)kcontrol->private_value;
 
-	mutex_lock(&codec->mutex);
+	mutex_lock(&card->mutex);
 
 	ucontrol->value.integer.value[0] =
-		snd_soc_dapm_get_pin_status(&codec->dapm, pin);
+		snd_soc_dapm_get_pin_status(&card->dapm, pin);
 
-	mutex_unlock(&codec->mutex);
+	mutex_unlock(&card->mutex);
 
 	return 0;
 }
@@ -2634,41 +2695,48 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch);
 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
 	const char *pin = (const char *)kcontrol->private_value;
 
-	mutex_lock(&codec->mutex);
+	mutex_lock(&card->mutex);
 
 	if (ucontrol->value.integer.value[0])
-		snd_soc_dapm_enable_pin(&codec->dapm, pin);
+		snd_soc_dapm_enable_pin(&card->dapm, pin);
 	else
-		snd_soc_dapm_disable_pin(&codec->dapm, pin);
+		snd_soc_dapm_disable_pin(&card->dapm, pin);
 
-	snd_soc_dapm_sync(&codec->dapm);
+	snd_soc_dapm_sync(&card->dapm);
 
-	mutex_unlock(&codec->mutex);
+	mutex_unlock(&card->mutex);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
 
-/**
- * snd_soc_dapm_new_control - create new dapm control
- * @dapm: DAPM context
- * @widget: widget template
- *
- * Creates a new dapm control based upon the template.
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
-	const struct snd_soc_dapm_widget *widget)
+static struct snd_soc_dapm_widget *
+snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
+			 const struct snd_soc_dapm_widget *widget)
 {
 	struct snd_soc_dapm_widget *w;
 	size_t name_len;
+	int ret;
 
 	if ((w = dapm_cnew_widget(widget)) == NULL)
-		return -ENOMEM;
+		return NULL;
+
+	switch (w->id) {
+	case snd_soc_dapm_regulator_supply:
+		w->priv = devm_regulator_get(dapm->dev, w->name);
+		if (IS_ERR(w->priv)) {
+			ret = PTR_ERR(w->priv);
+			dev_err(dapm->dev, "Failed to request %s: %d\n",
+				w->name, ret);
+			return NULL;
+		}
+		break;
+	default:
+		break;
+	}
 
 	name_len = strlen(widget->name) + 1;
 	if (dapm->codec && dapm->codec->name_prefix)
@@ -2676,13 +2744,13 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 	w->name = kmalloc(name_len, GFP_KERNEL);
 	if (w->name == NULL) {
 		kfree(w);
-		return -ENOMEM;
+		return NULL;
 	}
 	if (dapm->codec && dapm->codec->name_prefix)
-		snprintf(w->name, name_len, "%s %s",
+		snprintf((char *)w->name, name_len, "%s %s",
 			dapm->codec->name_prefix, widget->name);
 	else
-		snprintf(w->name, name_len, "%s", widget->name);
+		snprintf((char *)w->name, name_len, "%s", widget->name);
 
 	switch (w->id) {
 	case snd_soc_dapm_switch:
@@ -2715,8 +2783,12 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 		w->power_check = dapm_generic_check_power;
 		break;
 	case snd_soc_dapm_supply:
+	case snd_soc_dapm_regulator_supply:
 		w->power_check = dapm_supply_check_power;
 		break;
+	case snd_soc_dapm_dai:
+		w->power_check = dapm_dai_check_power;
+		break;
 	default:
 		w->power_check = dapm_always_on_check_power;
 		break;
@@ -2734,9 +2806,8 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
 
 	/* machine layer set ups unconnected pins and insertions */
 	w->connected = 1;
-	return 0;
+	return w;
 }
-EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
 
 /**
  * snd_soc_dapm_new_controls - create new dapm controls
@@ -2752,15 +2823,16 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
 	const struct snd_soc_dapm_widget *widget,
 	int num)
 {
-	int i, ret;
+	struct snd_soc_dapm_widget *w;
+	int i;
 
 	for (i = 0; i < num; i++) {
-		ret = snd_soc_dapm_new_control(dapm, widget);
-		if (ret < 0) {
+		w = snd_soc_dapm_new_control(dapm, widget);
+		if (!w) {
 			dev_err(dapm->dev,
-				"ASoC: Failed to create DAPM control %s: %d\n",
-				widget->name, ret);
-			return ret;
+				"ASoC: Failed to create DAPM control %s\n",
+				widget->name);
+			return -ENOMEM;
 		}
 		widget++;
 	}
@@ -2768,40 +2840,140 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
 }
 EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
 
-static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
-	const char *stream, int event)
+int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
+				 struct snd_soc_dai *dai)
 {
+	struct snd_soc_dapm_widget template;
 	struct snd_soc_dapm_widget *w;
 
-	list_for_each_entry(w, &dapm->card->widgets, list)
-	{
-		if (!w->sname || w->dapm != dapm)
+	WARN_ON(dapm->dev != dai->dev);
+
+	memset(&template, 0, sizeof(template));
+	template.reg = SND_SOC_NOPM;
+
+	if (dai->driver->playback.stream_name) {
+		template.id = snd_soc_dapm_dai;
+		template.name = dai->driver->playback.stream_name;
+		template.sname = dai->driver->playback.stream_name;
+
+		dev_dbg(dai->dev, "adding %s widget\n",
+			template.name);
+
+		w = snd_soc_dapm_new_control(dapm, &template);
+		if (!w) {
+			dev_err(dapm->dev, "Failed to create %s widget\n",
+				dai->driver->playback.stream_name);
+		}
+
+		w->priv = dai;
+		dai->playback_widget = w;
+	}
+
+	if (dai->driver->capture.stream_name) {
+		template.id = snd_soc_dapm_dai;
+		template.name = dai->driver->capture.stream_name;
+		template.sname = dai->driver->capture.stream_name;
+
+		dev_dbg(dai->dev, "adding %s widget\n",
+			template.name);
+
+		w = snd_soc_dapm_new_control(dapm, &template);
+		if (!w) {
+			dev_err(dapm->dev, "Failed to create %s widget\n",
+				dai->driver->capture.stream_name);
+		}
+
+		w->priv = dai;
+		dai->capture_widget = w;
+	}
+
+	return 0;
+}
+
+int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
+{
+	struct snd_soc_dapm_widget *dai_w, *w;
+	struct snd_soc_dai *dai;
+	struct snd_soc_dapm_route r;
+
+	memset(&r, 0, sizeof(r));
+
+	/* For each DAI widget... */
+	list_for_each_entry(dai_w, &card->widgets, list) {
+		if (dai_w->id != snd_soc_dapm_dai)
 			continue;
-		dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
-			w->name, w->sname, stream, event);
-		if (strstr(w->sname, stream)) {
-			dapm_mark_dirty(w, "stream event");
-			switch(event) {
-			case SND_SOC_DAPM_STREAM_START:
-				w->active = 1;
-				break;
-			case SND_SOC_DAPM_STREAM_STOP:
-				w->active = 0;
-				break;
-			case SND_SOC_DAPM_STREAM_SUSPEND:
-			case SND_SOC_DAPM_STREAM_RESUME:
-			case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
-			case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
-				break;
+
+		dai = dai_w->priv;
+
+		/* ...find all widgets with the same stream and link them */
+		list_for_each_entry(w, &card->widgets, list) {
+			if (w->dapm != dai_w->dapm)
+				continue;
+
+			if (w->id == snd_soc_dapm_dai)
+				continue;
+
+			if (!w->sname)
+				continue;
+
+			if (dai->driver->playback.stream_name &&
+			    strstr(w->sname,
+				   dai->driver->playback.stream_name)) {
+				r.source = dai->playback_widget->name;
+				r.sink = w->name;
+				dev_dbg(dai->dev, "%s -> %s\n",
+					 r.source, r.sink);
+
+				snd_soc_dapm_add_route(w->dapm, &r);
+			}
+
+			if (dai->driver->capture.stream_name &&
+			    strstr(w->sname,
+				   dai->driver->capture.stream_name)) {
+				r.source = w->name;
+				r.sink = dai->capture_widget->name;
+				dev_dbg(dai->dev, "%s -> %s\n",
+					r.source, r.sink);
+
+				snd_soc_dapm_add_route(w->dapm, &r);
 			}
 		}
 	}
 
-	dapm_power_widgets(dapm, event);
+	return 0;
+}
 
-	/* do we need to notify any clients that DAPM stream is complete */
-	if (dapm->stream_event)
-		dapm->stream_event(dapm, event);
+static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
+				  int stream, struct snd_soc_dai *dai,
+				  int event)
+{
+	struct snd_soc_dapm_widget *w;
+
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		w = dai->playback_widget;
+	else
+		w = dai->capture_widget;
+
+	if (!w)
+		return;
+
+	dapm_mark_dirty(w, "stream event");
+
+	switch (event) {
+	case SND_SOC_DAPM_STREAM_START:
+		w->active = 1;
+		break;
+	case SND_SOC_DAPM_STREAM_STOP:
+		w->active = 0;
+		break;
+	case SND_SOC_DAPM_STREAM_SUSPEND:
+	case SND_SOC_DAPM_STREAM_RESUME:
+	case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
+	case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
+		break;
+	}
+
+	dapm_power_widgets(dapm, event);
 }
 
 /**
@@ -2815,16 +2987,13 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
  *
  * Returns 0 for success else error.
  */
-int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
-	const char *stream, int event)
+int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
+			      struct snd_soc_dai *dai, int event)
 {
 	struct snd_soc_codec *codec = rtd->codec;
 
-	if (stream == NULL)
-		return 0;
-
 	mutex_lock(&codec->mutex);
-	soc_dapm_stream_event(&codec->dapm, stream, event);
+	soc_dapm_stream_event(&codec->dapm, stream, dai, event);
 	mutex_unlock(&codec->mutex);
 	return 0;
 }
diff --git a/sound/soc/soc-dmaengine.c b/sound/soc/soc-dmaengine.c
new file mode 100644
index 0000000..0df4b77
--- /dev/null
+++ b/sound/soc/soc-dmaengine.c
@@ -0,0 +1,576 @@
+/*
+ * Generic ASoC DMA engine backend
+ *
+ * Copyright (C) 2012 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * We expect the DMA engine to give accurate residue information,
+ * returning the number of bytes left to complete to the requested
+ * cookie.  We also expect the DMA engine to be able to resume
+ * submitted descriptors after a suspend/resume cycle.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <sound/core.h>
+#include <sound/soc-dmaengine.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#define BUFFER_SIZE_MAX		65536
+#define PERIOD_SIZE_MIN		32
+#define PERIOD_SIZE_MAX		16384
+#define PERIODS_MIN		2
+#define PERIODS_MAX		256
+
+struct buf_info {
+	struct scatterlist sg;
+	dma_cookie_t cookie;
+};
+
+struct soc_dma_chan {
+	const struct soc_dma_config *conf;
+	spinlock_t lock;
+	struct dma_chan *chan;
+	struct dma_slave_config cfg;
+	enum dma_transfer_direction dir;
+	unsigned nr_periods;
+	unsigned sg_index;
+	unsigned stopped;
+	struct buf_info buf[PERIODS_MAX];
+};
+
+struct soc_dma_info {
+	struct soc_dma_chan *chan[2];
+};
+
+static const struct snd_pcm_hardware soc_dmaengine_hardware = {
+	.info			= SNDRV_PCM_INFO_MMAP |
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_PAUSE |
+				  SNDRV_PCM_INFO_RESUME,
+	.period_bytes_min	= PERIOD_SIZE_MIN,
+	.period_bytes_max	= PERIOD_SIZE_MAX,
+	.periods_min		= PERIODS_MIN,
+	.periods_max		= PERIODS_MAX,
+	.buffer_bytes_max	= BUFFER_SIZE_MAX,
+};
+
+static int soc_dmaengine_submit(struct snd_pcm_substream *substream,
+	struct soc_dma_chan *dma);
+
+static void soc_dmaengine_callback(void *data)
+{
+	struct snd_pcm_substream *substream = data;
+	struct soc_dma_chan *dma = substream->runtime->private_data;
+	int ret;
+
+	snd_pcm_period_elapsed(substream);
+
+	if (!dma->stopped) {
+		spin_lock(&dma->lock);
+		ret = soc_dmaengine_submit(substream, dma);
+		spin_unlock(&dma->lock);
+
+		if (ret == 0)
+			dma_async_issue_pending(dma->chan);
+		else
+			pr_err("%s: failed to submit next DMA buffer\n", __func__);
+	}
+}
+
+static int soc_dmaengine_submit(struct snd_pcm_substream *substream,
+	struct soc_dma_chan *dma)
+{
+	struct dma_async_tx_descriptor *tx;
+	struct dma_chan *ch = dma->chan;
+	struct buf_info *buf;
+	unsigned sg_index;
+
+	sg_index = dma->sg_index;
+
+	buf = &dma->buf[sg_index];
+
+	tx = ch->device->device_prep_slave_sg(ch, &buf->sg, 1,
+		dma->dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (tx) {
+		tx->callback = soc_dmaengine_callback;
+		tx->callback_param = substream;
+
+		buf->cookie = dmaengine_submit(tx);
+
+		sg_index++;
+		if (sg_index >= dma->nr_periods)
+			sg_index = 0;
+		dma->sg_index = sg_index;
+	}
+
+	return tx ? 0 : -ENOMEM;
+}
+
+static int soc_dmaengine_start(struct snd_pcm_substream *substream)
+{
+	struct soc_dma_chan *dma = substream->runtime->private_data;
+	unsigned long flags;
+	unsigned i;
+	int ret = 0;
+
+	spin_lock_irqsave(&dma->lock, flags);
+	for (i = 0; i < dma->nr_periods; i++) {
+		ret = soc_dmaengine_submit(substream, dma);
+		if (ret)
+			break;
+	}
+	spin_unlock_irqrestore(&dma->lock, flags);
+	if (ret == 0) {
+		dma->stopped = 0;
+		dma_async_issue_pending(dma->chan);
+	} else {
+		dma->stopped = 1;
+		dmaengine_terminate_all(dma->chan);
+	}
+
+	return ret;
+}
+
+static int soc_dmaengine_stop(struct snd_pcm_substream *substream)
+{
+	struct soc_dma_chan *dma = substream->runtime->private_data;
+
+	dma->stopped = 1;
+	dmaengine_terminate_all(dma->chan);
+
+	return 0;
+}
+
+static int soc_dmaengine_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct soc_dma_info *info = snd_soc_platform_get_drvdata(rtd->platform);
+	struct soc_dma_chan *dma;
+	int ret = 0;
+
+	dma = info->chan[substream->stream];
+	if (!dma)
+		return -EINVAL;
+
+	runtime->hw = soc_dmaengine_hardware;
+	runtime->hw.fifo_size = dma->conf->fifo_size;
+
+	if (dma->conf->align) {
+		/*
+		 * FIXME: Ideally, there should be some way to query
+		 * this from the DMA engine itself.
+		 *
+		 * It would also be helpful to know the maximum size
+		 * a scatterlist entry can be to set the period size.
+		 */
+		ret = snd_pcm_hw_constraint_step(runtime, 0,
+			SNDRV_PCM_HW_PARAM_PERIOD_BYTES, dma->conf->align);
+		if (ret)
+			goto err;
+
+		ret = snd_pcm_hw_constraint_step(runtime, 0,
+			SNDRV_PCM_HW_PARAM_BUFFER_BYTES, dma->conf->align);
+		if (ret)
+			goto err;
+	}
+
+	runtime->private_data = dma;
+
+ err:
+	return ret;
+}
+
+static int soc_dmaengine_close(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+static int soc_dmaengine_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	int ret = snd_pcm_lib_malloc_pages(substream,
+			params_buffer_bytes(params));
+
+	return ret < 0 ? ret : 0;
+}
+
+static int soc_dmaengine_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct soc_dma_chan *dma = runtime->private_data;
+	size_t buf_size = snd_pcm_lib_buffer_bytes(substream);
+	size_t period = snd_pcm_lib_period_bytes(substream);
+	dma_addr_t addr = runtime->dma_addr;
+	unsigned i;
+
+	/* Create an array of sg entries, one for each period */
+	for (i = 0; i < PERIODS_MAX && buf_size; i++) {
+		BUG_ON(buf_size < period);
+
+		sg_dma_address(&dma->buf[i].sg) = addr;
+		sg_dma_len(&dma->buf[i].sg) = period;
+
+		addr += period;
+		buf_size -= period;
+	}
+
+	if (buf_size) {
+		pr_err("DMA buffer size not a multiple of the period size: residue=%zu\n", buf_size);
+		return -EINVAL;
+	}
+
+	dma->nr_periods = i;
+	dma->sg_index = 0;
+
+	return 0;
+}
+
+static int soc_dmaengine_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct soc_dma_chan *dma = runtime->private_data;
+	int ret;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		ret = soc_dmaengine_start(substream);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		ret = soc_dmaengine_stop(substream);
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		ret = dmaengine_pause(dma->chan);
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		ret = dmaengine_resume(dma->chan);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t soc_dmaengine_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct soc_dma_chan *dma = runtime->private_data;
+	struct dma_chan *ch = dma->chan;
+	struct dma_tx_state state;
+	enum dma_status status;
+	unsigned index, last, bytes = 0, pos;
+	size_t period = snd_pcm_lib_period_bytes(substream);
+	unsigned long flags;
+	dma_cookie_t cookie;
+
+	/*
+	 * Get the next-to-be-submitted index, and the last submitted
+	 * cookie value.  We use this to obtain the DMA engine state.
+	 */
+	spin_lock_irqsave(&dma->lock, flags);
+	index = dma->sg_index;
+	last = (index == 0 ? dma->nr_periods : index) - 1;
+	cookie = dma->buf[last].cookie;
+	spin_unlock_irqrestore(&dma->lock, flags);
+
+	/* The end of the current DMA buffer */
+	pos = index * period;
+
+	status = ch->device->device_tx_status(ch, cookie, &state);
+
+	/* The last submitted cookie should not have completed. */
+	if (status == DMA_IN_PROGRESS) {
+		if (state.residue) {
+			/*
+			 * Good, the DMA engine provides us with the
+			 * number of bytes to be transferred until the
+			 * requested cookie.  Use this to calculate
+			 * where the DMA engine is in the buffer.
+			 */
+			int off = pos - state.residue;
+			if (off < 0)
+				off += period * dma->nr_periods;
+			bytes = off;
+		} else {
+			/*
+			 * The DMA engine does not provide us with
+			 * this information, so we have to work out
+			 * which cookie is complete.
+			 */
+			unsigned i;
+
+			for (i = 0; i < dma->nr_periods; i++) {
+				status = dma_async_is_complete(
+						dma->buf[i].cookie,
+						state.last, state.used);
+			}
+		}
+	}
+
+	pr_debug("%s: index %u last %u residue %04x pos %04x bytes %04x\n",
+		__func__, index, last, state.residue, pos, bytes);
+
+	return bytes_to_frames(runtime, bytes);
+}
+
+static int soc_dmaengine_mmap(struct snd_pcm_substream *substream,
+	struct vm_area_struct *vma)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dma_buffer *buf = runtime->dma_buffer_p;
+
+	return dma_mmap_writecombine(buf->dev.dev, vma,
+		runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
+}
+
+static struct snd_pcm_ops soc_dmaengine_ops = {
+	.open = soc_dmaengine_open,
+	.close = soc_dmaengine_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = soc_dmaengine_hw_params,
+	.hw_free = snd_pcm_lib_free_pages,
+	.prepare = soc_dmaengine_prepare,
+	.trigger = soc_dmaengine_trigger,
+	.pointer = soc_dmaengine_pointer,
+	.mmap = soc_dmaengine_mmap,
+};
+
+static struct soc_dma_chan *soc_dmaengine_alloc(void)
+{
+	struct soc_dma_chan *dma = kzalloc(sizeof(*dma), GFP_KERNEL);
+	unsigned i;
+
+	if (dma) {
+		spin_lock_init(&dma->lock);
+		for (i = 0; i < PERIODS_MAX; i++)
+			sg_init_table(&dma->buf[i].sg, 1);
+	}
+	return dma;
+}
+
+static int soc_dmaengine_request(struct soc_dma_chan *dma,
+	struct soc_dma_config *cfg, unsigned stream)
+{
+	dma_cap_mask_t m;
+	int ret;
+
+	dma_cap_zero(m);
+	dma_cap_set(DMA_SLAVE, m);
+	dma->conf = cfg;
+	dma->chan = dma_request_channel(m, cfg->filter, cfg->data);
+	if (!dma->chan) {
+		ret = -ENXIO;
+		goto err_dma_req;
+	}
+
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		dma->dir = DMA_MEM_TO_DEV;
+		dma->cfg.direction = DMA_MEM_TO_DEV;
+		dma->cfg.dst_addr = cfg->reg;
+		dma->cfg.dst_addr_width = cfg->width;
+		dma->cfg.dst_maxburst = cfg->maxburst;
+	} else {
+		dma->dir = DMA_DEV_TO_MEM;
+		dma->cfg.direction = DMA_DEV_TO_MEM;
+		dma->cfg.src_addr = cfg->reg;
+		dma->cfg.src_addr_width = cfg->width;
+		dma->cfg.src_maxburst = cfg->maxburst;
+	}
+
+	ret = dmaengine_slave_config(dma->chan, &dma->cfg);
+	if (ret)
+		goto err_dma_cfg;
+
+	return 0;
+
+ err_dma_cfg:
+	dma_release_channel(dma->chan);
+	dma->chan = NULL;
+ err_dma_req:
+	return ret;
+}
+
+static void soc_dmaengine_release(struct soc_dma_chan *dma)
+{
+	if (dma && dma->chan)
+		dma_release_channel(dma->chan);
+	kfree(dma);
+}
+
+static int soc_dmaengine_preallocate_buffer(struct snd_pcm *pcm,
+	unsigned stream, struct soc_dma_chan *dma)
+{
+	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+	int ret = 0;
+
+	if (substream) {
+		struct snd_dma_buffer *buf = &substream->dma_buffer;
+
+		buf->dev.type = SNDRV_DMA_TYPE_DEV;
+		buf->dev.dev = dma->chan->device->dev;
+		buf->private_data = NULL;
+		buf->area = dma_alloc_writecombine(buf->dev.dev,
+				BUFFER_SIZE_MAX, &buf->addr, GFP_KERNEL);
+		if (!buf->area)
+			return -ENOMEM;
+
+		buf->bytes = BUFFER_SIZE_MAX;
+	}
+	return ret;
+}
+
+static int soc_dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_pcm *pcm = rtd->pcm;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct soc_dma_info *info;
+	unsigned stream;
+	int ret = 0;
+
+	if (!cpu_dai)
+		return -EINVAL;
+
+	if (!cpu_dai->playback_dma_data &&
+	    !cpu_dai->capture_dma_data) {
+		pr_err("soc_dmaengine: %s has no cpu_dai DMA data - incorrect probe ordering?\n",
+			rtd->card->name);
+		return -EINVAL;
+	}
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	for (stream = 0; stream < ARRAY_SIZE(pcm->streams); stream++) {
+		struct soc_dma_config *cfg = NULL;
+		struct soc_dma_chan *dma;
+
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			cfg = cpu_dai->playback_dma_data;
+		else if (stream == SNDRV_PCM_STREAM_CAPTURE)
+			cfg = cpu_dai->capture_dma_data;
+
+		if (!cfg)
+			continue;
+
+		info->chan[stream] = dma = soc_dmaengine_alloc();
+		if (!dma) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		ret = soc_dmaengine_request(dma, cfg, stream);
+		if (ret)
+			return ret;
+
+		ret = soc_dmaengine_preallocate_buffer(pcm, stream, dma);
+		if (ret)
+			break;
+	}
+
+	if (ret) {
+		for (stream = 0; stream < ARRAY_SIZE(info->chan); stream++)
+			soc_dmaengine_release(info->chan[stream]);
+		kfree(info);
+	} else {
+		snd_soc_platform_set_drvdata(rtd->platform, info);
+	}
+
+	return ret;
+}
+
+/*
+ * Use write-combining memory here: the standard ALSA
+ * snd_free_dev_pages() doesn't support this.
+ */
+static void soc_dmaengine_pcm_free(struct snd_pcm *pcm)
+{
+	unsigned stream;
+
+	for (stream = 0; stream < ARRAY_SIZE(pcm->streams); stream++) {
+		struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+		struct snd_dma_buffer *buf;
+
+		if (!substream)
+			continue;
+		buf = &substream->dma_buffer;
+		if (!buf->area)
+			continue;
+
+		if (buf->dev.type == SNDRV_DMA_TYPE_DEV)
+			dma_free_writecombine(buf->dev.dev, buf->bytes,
+					      buf->area, buf->addr);
+		else
+			snd_dma_free_pages(buf);
+		buf->area = NULL;
+	}
+}
+
+/*
+ * This is annoying - we can't have symetry with .pcm_new because .pcm_free
+ * is called after the runtime information has been removed.  It would be
+ * better if we could find somewhere else to store our soc_dma_info pointer.
+ */
+static int soc_dmaengine_plat_remove(struct snd_soc_platform *platform)
+{
+	struct soc_dma_info *info = snd_soc_platform_get_drvdata(platform);
+	unsigned stream;
+
+	for (stream = 0; stream < ARRAY_SIZE(info->chan); stream++)
+		soc_dmaengine_release(info->chan[stream]);
+	kfree(info);
+
+	return 0;
+}
+
+static struct snd_soc_platform_driver soc_dmaengine_platform = {
+	.remove = soc_dmaengine_plat_remove,
+	.pcm_new = soc_dmaengine_pcm_new,
+	.pcm_free = soc_dmaengine_pcm_free,
+	.ops = &soc_dmaengine_ops,
+	/* Wait until the cpu_dai has been probed */
+	.probe_order = SND_SOC_COMP_ORDER_LATE,
+};
+
+static int __devinit soc_dmaengine_probe(struct platform_device *pdev)
+{
+	return snd_soc_register_platform(&pdev->dev, &soc_dmaengine_platform);
+}
+
+static int __devexit soc_dmaengine_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_platform(&pdev->dev);
+	return 0;
+}
+
+static struct platform_driver soc_dmaengine_driver = {
+	.driver = {
+		.name = "soc-dmaengine",
+		.owner = THIS_MODULE,
+	},
+	.probe = soc_dmaengine_probe,
+	.remove = soc_dmaengine_remove,
+};
+
+module_platform_driver(soc_dmaengine_driver);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("ALSA SoC DMA engine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:soc-dmaengine");
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index c8610cb..4d8dc6a 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -114,6 +114,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
 			       enum snd_soc_control_type control)
 {
 	struct regmap_config config;
+	int ret;
 
 	memset(&config, 0, sizeof(config));
 	codec->write = hw_write;
@@ -140,6 +141,12 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
 
 	case SND_SOC_REGMAP:
 		/* Device has made its own regmap arrangements */
+		codec->using_regmap = true;
+
+		ret = regmap_get_val_bytes(codec->control_data);
+		/* Errors are legitimate for non-integer byte multiples */
+		if (ret > 0)
+			codec->val_bytes = ret;
 		break;
 
 	default:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index cdc860a..0ad8dca 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -63,6 +63,41 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
 }
 
 /*
+ * List of sample sizes that might go over the bus for parameter
+ * application.  There ought to be a wildcard sample size for things
+ * like the DAC/ADC resolution to use but there isn't right now.
+ */
+static int sample_sizes[] = {
+	24, 32,
+};
+
+static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
+			      struct snd_soc_dai *dai)
+{
+	int ret, i, bits;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		bits = dai->driver->playback.sig_bits;
+	else
+		bits = dai->driver->capture.sig_bits;
+
+	if (!bits)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) {
+		if (bits >= sample_sizes[i])
+			continue;
+
+		ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0,
+						   sample_sizes[i], bits);
+		if (ret != 0)
+			dev_warn(dai->dev,
+				 "Failed to set MSB %d/%d: %d\n",
+				 bits, sample_sizes[i], ret);
+	}
+}
+
+/*
  * Called by ALSA when a PCM substream is opened, the runtime->hw record is
  * then initialized and any private data can be allocated. This also calls
  * startup for the cpu DAI, platform, machine and codec DAI.
@@ -88,8 +123,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 	if (cpu_dai->driver->ops->startup) {
 		ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: can't open interface %s\n",
-				cpu_dai->name);
+			dev_err(cpu_dai->dev, "can't open interface %s: %d\n",
+				cpu_dai->name, ret);
 			goto out;
 		}
 	}
@@ -97,7 +132,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 	if (platform->driver->ops && platform->driver->ops->open) {
 		ret = platform->driver->ops->open(substream);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
+			dev_err(platform->dev, "can't open platform %s: %d\n",
+				platform->name, ret);
 			goto platform_err;
 		}
 	}
@@ -105,8 +141,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 	if (codec_dai->driver->ops->startup) {
 		ret = codec_dai->driver->ops->startup(substream, codec_dai);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: can't open codec %s\n",
-				codec_dai->name);
+			dev_err(codec_dai->dev, "can't open codec %s: %d\n",
+				codec_dai->name, ret);
 			goto codec_dai_err;
 		}
 	}
@@ -114,7 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 	if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
 		ret = rtd->dai_link->ops->startup(substream);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name);
+			pr_err("asoc: %s startup failed: %d\n",
+			       rtd->dai_link->name, ret);
 			goto machine_err;
 		}
 	}
@@ -187,6 +224,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 		goto config_err;
 	}
 
+	soc_pcm_apply_msb(substream, codec_dai);
+	soc_pcm_apply_msb(substream, cpu_dai);
+
 	/* Symmetry only applies if we've already got an active stream. */
 	if (cpu_dai->active) {
 		ret = soc_pcm_apply_symmetry(substream, cpu_dai);
@@ -267,9 +307,8 @@ static void close_delayed_work(struct work_struct *work)
 	/* are we waiting on this codec DAI stream */
 	if (codec_dai->pop_wait == 1) {
 		codec_dai->pop_wait = 0;
-		snd_soc_dapm_stream_event(rtd,
-			codec_dai->driver->playback.stream_name,
-			SND_SOC_DAPM_STREAM_STOP);
+		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
+					  codec_dai, SND_SOC_DAPM_STREAM_STOP);
 	}
 
 	mutex_unlock(&rtd->pcm_mutex);
@@ -329,12 +368,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
 	cpu_dai->runtime = NULL;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (codec->ignore_pmdown_time ||
+		if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
 		    rtd->dai_link->ignore_pmdown_time) {
 			/* powered down playback stream now */
 			snd_soc_dapm_stream_event(rtd,
-				codec_dai->driver->playback.stream_name,
-				SND_SOC_DAPM_STREAM_STOP);
+						  SNDRV_PCM_STREAM_PLAYBACK,
+						  codec_dai,
+						  SND_SOC_DAPM_STREAM_STOP);
 		} else {
 			/* start delayed pop wq here for playback streams */
 			codec_dai->pop_wait = 1;
@@ -343,9 +383,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
 		}
 	} else {
 		/* capture streams can be powered down now */
-		snd_soc_dapm_stream_event(rtd,
-			codec_dai->driver->capture.stream_name,
-			SND_SOC_DAPM_STREAM_STOP);
+		snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
+					  codec_dai, SND_SOC_DAPM_STREAM_STOP);
 	}
 
 	mutex_unlock(&rtd->pcm_mutex);
@@ -375,7 +414,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 	if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
 		ret = rtd->dai_link->ops->prepare(substream);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: machine prepare error\n");
+			pr_err("asoc: machine prepare error: %d\n", ret);
 			goto out;
 		}
 	}
@@ -383,7 +422,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 	if (platform->driver->ops && platform->driver->ops->prepare) {
 		ret = platform->driver->ops->prepare(substream);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: platform prepare error\n");
+			dev_err(platform->dev, "platform prepare error: %d\n",
+				ret);
 			goto out;
 		}
 	}
@@ -391,7 +431,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 	if (codec_dai->driver->ops->prepare) {
 		ret = codec_dai->driver->ops->prepare(substream, codec_dai);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: codec DAI prepare error\n");
+			dev_err(codec_dai->dev, "DAI prepare error: %d\n",
+				ret);
 			goto out;
 		}
 	}
@@ -399,7 +440,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 	if (cpu_dai->driver->ops->prepare) {
 		ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: cpu DAI prepare error\n");
+			dev_err(cpu_dai->dev, "DAI prepare error: %d\n",
+				ret);
 			goto out;
 		}
 	}
@@ -411,14 +453,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 		cancel_delayed_work(&rtd->delayed_work);
 	}
 
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		snd_soc_dapm_stream_event(rtd,
-					  codec_dai->driver->playback.stream_name,
-					  SND_SOC_DAPM_STREAM_START);
-	else
-		snd_soc_dapm_stream_event(rtd,
-					  codec_dai->driver->capture.stream_name,
-					  SND_SOC_DAPM_STREAM_START);
+	snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai,
+				  SND_SOC_DAPM_STREAM_START);
 
 	snd_soc_dai_digital_mute(codec_dai, 0);
 
@@ -446,7 +482,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 	if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
 		ret = rtd->dai_link->ops->hw_params(substream, params);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: machine hw_params failed\n");
+			pr_err("asoc: machine hw_params failed: %d\n", ret);
 			goto out;
 		}
 	}
@@ -454,8 +490,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 	if (codec_dai->driver->ops->hw_params) {
 		ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: can't set codec %s hw params\n",
-				codec_dai->name);
+			dev_err(codec_dai->dev, "can't set %s hw params: %d\n",
+				codec_dai->name, ret);
 			goto codec_err;
 		}
 	}
@@ -463,8 +499,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 	if (cpu_dai->driver->ops->hw_params) {
 		ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: interface %s hw params failed\n",
-				cpu_dai->name);
+			dev_err(cpu_dai->dev, "%s hw params failed: %d\n",
+				cpu_dai->name, ret);
 			goto interface_err;
 		}
 	}
@@ -472,8 +508,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 	if (platform->driver->ops && platform->driver->ops->hw_params) {
 		ret = platform->driver->ops->hw_params(substream, params);
 		if (ret < 0) {
-			printk(KERN_ERR "asoc: platform %s hw params failed\n",
-				platform->name);
+			dev_err(platform->dev, "%s hw params failed: %d\n",
+			       platform->name, ret);
 			goto platform_err;
 		}
 	}
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 4220bb0..6005370 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -89,14 +89,32 @@ static struct snd_soc_platform_driver dummy_platform = {
 	.ops = &dummy_dma_ops,
 };
 
+static struct snd_soc_codec_driver dummy_codec;
+static struct snd_soc_dai_driver dummy_dai = {
+	.name = "snd-soc-dummy-dai",
+};
+
 static __devinit int snd_soc_dummy_probe(struct platform_device *pdev)
 {
-	return snd_soc_register_platform(&pdev->dev, &dummy_platform);
+	int ret;
+
+	ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_soc_register_platform(&pdev->dev, &dummy_platform);
+	if (ret < 0) {
+		snd_soc_unregister_codec(&pdev->dev);
+		return ret;
+	}
+
+	return ret;
 }
 
 static __devexit int snd_soc_dummy_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_platform(&pdev->dev);
+	snd_soc_unregister_codec(&pdev->dev);
 
 	return 0;
 }
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 4a0e805..2a27725 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 
 #include <sound/core.h>
 #include <sound/jack.h>
@@ -34,8 +35,13 @@
 
 #define DRV_NAME "tegra-alc5632"
 
+#define GPIO_HP_DET     BIT(0)
+
 struct tegra_alc5632 {
 	struct tegra_asoc_utils_data util_data;
+	struct platform_device *pcm_dev;
+	int gpio_requested;
+	int gpio_hp_det;
 };
 
 static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
@@ -85,24 +91,18 @@ static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = {
 	},
 };
 
+static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
+	.name = "Headset detection",
+	.report = SND_JACK_HEADSET,
+	.debounce_time = 150,
+	.invert = 1,
+};
+
 static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
 	SND_SOC_DAPM_SPK("Int Spk", NULL),
 	SND_SOC_DAPM_HP("Headset Stereophone", NULL),
 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
-};
-
-static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = {
-	/* Internal Speaker */
-	{"Int Spk", NULL, "SPKOUT"},
-	{"Int Spk", NULL, "SPKOUTN"},
-
-	/* Headset Mic */
-	{"MIC1", NULL, "MICBIAS1"},
-	{"MICBIAS1", NULL, "Headset Mic"},
-
-	/* Headset Stereophone */
-	{"Headset Stereophone", NULL, "HPR"},
-	{"Headset Stereophone", NULL, "HPL"},
+	SND_SOC_DAPM_MIC("Digital Mic", NULL),
 };
 
 static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
@@ -113,6 +113,9 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
+	struct device_node *np = codec->card->dev->of_node;
+	struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
+	int ret;
 
 	snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
 			 &tegra_alc5632_hs_jack);
@@ -120,6 +123,16 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
 			ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
 			tegra_alc5632_hs_jack_pins);
 
+	machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
+
+	if (gpio_is_valid(machine->gpio_hp_det)) {
+		tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
+		snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
+						1,
+						&tegra_alc5632_hp_jack_gpio);
+		machine->gpio_requested |= GPIO_HP_DET;
+	}
+
 	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
 
 	return 0;
@@ -128,9 +141,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
 static struct snd_soc_dai_link tegra_alc5632_dai = {
 	.name = "ALC5632",
 	.stream_name = "ALC5632 PCM",
-	.codec_name = "alc5632.0-001e",
 	.platform_name = "tegra-pcm-audio",
-	.cpu_dai_name = "tegra-i2s.0",
 	.codec_dai_name = "alc5632-hifi",
 	.init = tegra_alc5632_asoc_init,
 	.ops = &tegra_alc5632_asoc_ops,
@@ -148,8 +159,6 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = {
 	.num_controls = ARRAY_SIZE(tegra_alc5632_controls),
 	.dapm_widgets = tegra_alc5632_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets),
-	.dapm_routes = tegra_alc5632_audio_map,
-	.num_dapm_routes = ARRAY_SIZE(tegra_alc5632_audio_map),
 	.fully_routed = true,
 };
 
@@ -163,45 +172,111 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
 			sizeof(struct tegra_alc5632), GFP_KERNEL);
 	if (!alc5632) {
 		dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n");
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err;
 	}
 
-	ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
-	if (ret)
-		return ret;
-
 	card->dev = &pdev->dev;
 	platform_set_drvdata(pdev, card);
 	snd_soc_card_set_drvdata(card, alc5632);
 
+	alc5632->pcm_dev = ERR_PTR(-EINVAL);
+
+	if (!(pdev->dev.of_node)) {
+		dev_err(&pdev->dev, "Must be instantiated using device tree\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = snd_soc_of_parse_card_name(card, "nvidia,model");
+	if (ret)
+		goto err;
+
+	ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
+	if (ret)
+		goto err;
+
+	tegra_alc5632_dai.codec_of_node = of_parse_phandle(
+			pdev->dev.of_node, "nvidia,audio-codec", 0);
+
+	if (!tegra_alc5632_dai.codec_of_node) {
+		dev_err(&pdev->dev,
+			"Property 'nvidia,audio-codec' missing or invalid\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle(
+			pdev->dev.of_node, "nvidia,i2s-controller", 0);
+	if (!tegra_alc5632_dai.cpu_dai_of_node) {
+		dev_err(&pdev->dev,
+		"Property 'nvidia,i2s-controller' missing or invalid\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	alc5632->pcm_dev = platform_device_register_simple(
+		"tegra-pcm-audio", -1, NULL, 0);
+	if (IS_ERR(alc5632->pcm_dev)) {
+		dev_err(&pdev->dev,
+			"Can't instantiate tegra-pcm-audio\n");
+		ret = PTR_ERR(alc5632->pcm_dev);
+		goto err;
+	}
+
+	ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
+	if (ret)
+		goto err_unregister;
+
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
 			ret);
-		tegra_asoc_utils_fini(&alc5632->util_data);
-		return ret;
+		goto err_fini_utils;
 	}
 
 	return 0;
+
+err_fini_utils:
+	tegra_asoc_utils_fini(&alc5632->util_data);
+err_unregister:
+	if (!IS_ERR(alc5632->pcm_dev))
+		platform_device_unregister(alc5632->pcm_dev);
+err:
+	return ret;
 }
 
 static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
-	struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
+	struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
+
+	if (machine->gpio_requested & GPIO_HP_DET)
+		snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack,
+					1,
+					&tegra_alc5632_hp_jack_gpio);
+	machine->gpio_requested = 0;
 
 	snd_soc_unregister_card(card);
 
-	tegra_asoc_utils_fini(&alc5632->util_data);
+	tegra_asoc_utils_fini(&machine->util_data);
+	if (!IS_ERR(machine->pcm_dev))
+		platform_device_unregister(machine->pcm_dev);
 
 	return 0;
 }
 
+static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = {
+	{ .compatible = "nvidia,tegra-audio-alc5632", },
+	{},
+};
+
 static struct platform_driver tegra_alc5632_driver = {
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
 		.pm = &snd_soc_pm_ops,
+		.of_match_table = tegra_alc5632_of_match,
 	},
 	.probe = tegra_alc5632_probe,
 	.remove = __devexit_p(tegra_alc5632_remove),
@@ -212,3 +287,4 @@ MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
 MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match);
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index c224315..8b44571 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -336,7 +336,7 @@ static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd)
 	if (!card->dev->dma_mask)
 		card->dev->dma_mask = &tegra_dma_mask;
 	if (!card->dev->coherent_dma_mask)
-		card->dev->coherent_dma_mask = 0xffffffff;
+		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 		ret = tegra_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 4dd051b..c6500d0 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -1112,17 +1112,7 @@ static struct spi_driver at73c213_driver = {
 	.remove		= __devexit_p(snd_at73c213_remove),
 };
 
-static int __init at73c213_init(void)
-{
-	return spi_register_driver(&at73c213_driver);
-}
-module_init(at73c213_init);
-
-static void __exit at73c213_exit(void)
-{
-	spi_unregister_driver(&at73c213_driver);
-}
-module_exit(at73c213_exit);
+module_spi_driver(at73c213_driver);
 
 MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
 MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
diff --git a/sound/usb/card.h b/sound/usb/card.h
index a39edcc..da5fa1a 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -1,6 +1,7 @@
 #ifndef __USBAUDIO_CARD_H
 #define __USBAUDIO_CARD_H
 
+#define MAX_NR_RATES	1024
 #define MAX_PACKS	20
 #define MAX_PACKS_HS	(MAX_PACKS * 8)	/* in high speed mode */
 #define MAX_URBS	8
diff --git a/sound/usb/format.c b/sound/usb/format.c
index e09aba1..ddfef57 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -209,8 +209,6 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
 	return 0;
 }
 
-#define MAX_UAC2_NR_RATES 1024
-
 /*
  * Helper function to walk the array of sample rate triplets reported by
  * the device. The problem is that we need to parse whole array first to
@@ -255,7 +253,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
 			fp->rates |= snd_pcm_rate_to_rate_bit(rate);
 
 			nr_rates++;
-			if (nr_rates >= MAX_UAC2_NR_RATES) {
+			if (nr_rates >= MAX_NR_RATES) {
 				snd_printk(KERN_ERR "invalid uac2 rates\n");
 				break;
 			}
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a3ddac0..2781726 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -132,10 +132,14 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 	unsigned *rate_table = NULL;
 
 	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
-	if (! fp) {
+	if (!fp) {
 		snd_printk(KERN_ERR "cannot memdup\n");
 		return -ENOMEM;
 	}
+	if (fp->nr_rates > MAX_NR_RATES) {
+		kfree(fp);
+		return -EINVAL;
+	}
 	if (fp->nr_rates > 0) {
 		rate_table = kmemdup(fp->rate_table,
 				     sizeof(int) * fp->nr_rates, GFP_KERNEL);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 6ffb371..520ef96 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -80,7 +80,7 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
 		cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
 			snd_printk(KERN_ERR "active frame status %i. "
-				   "Most propably some hardware problem.\n",
+				   "Most probably some hardware problem.\n",
 				   urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
@@ -300,7 +300,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
 {
 	snd_printk(KERN_ERR
 "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
-"Most propably some urb of usb-frame %i is still missing.\n"
+"Most probably some urb of usb-frame %i is still missing.\n"
 "Cause could be too long delays in usb-hcd interrupt handling.\n",
 		   usb_get_current_frame_number(usX2Y->dev),
 		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index a51340f..8e40b6e 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -74,7 +74,7 @@ static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
 	}
 	for (i = 0; i < nr_of_packs(); i++) {
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 11224ed..4ebf703 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -34,21 +34,12 @@
 #include <errno.h>
 #include <arpa/inet.h>
 #include <linux/connector.h>
+#include <linux/hyperv.h>
 #include <linux/netlink.h>
 #include <ifaddrs.h>
 #include <netdb.h>
 #include <syslog.h>
 
-/*
- * KYS: TODO. Need to register these in the kernel.
- *
- * The following definitions are shared with the in-kernel component; do not
- * change any of this without making the corresponding changes in
- * the KVP kernel component.
- */
-#define CN_KVP_IDX		0x9     /* MSFT KVP functionality */
-#define CN_KVP_VAL		0x1 /* This supports queries from the kernel */
-#define CN_KVP_USER_VAL		0x2 /* This supports queries from the user  */
 
 /*
  * KVP protocol: The user mode component first registers with the
@@ -60,25 +51,8 @@
  * We use this infrastructure for also supporting queries from user mode
  * application for state that may be maintained in the KVP kernel component.
  *
- * XXXKYS: Have a shared header file between the user and kernel (TODO)
  */
 
-enum kvp_op {
-	KVP_REGISTER = 0, /* Register the user mode component*/
-	KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/
-	KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/
-	KVP_USER_GET, /*User is requesting the value for the specified key*/
-	KVP_USER_SET /*User is providing the value for the specified key*/
-};
-
-#define HV_KVP_EXCHANGE_MAX_KEY_SIZE	512
-#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE	2048
-
-struct hv_ku_msg {
-	__u32	kvp_index;
-	__u8  kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
-	__u8  kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key  value */
-};
 
 enum key_index {
 	FullyQualifiedDomainName = 0,
@@ -93,10 +67,6 @@ enum key_index {
 	ProcessorArchitecture
 };
 
-/*
- * End of shared definitions.
- */
-
 static char kvp_send_buffer[4096];
 static char kvp_recv_buffer[4096];
 static struct sockaddr_nl addr;
@@ -332,7 +302,7 @@ int main(void)
 	struct pollfd pfd;
 	struct nlmsghdr *incoming_msg;
 	struct cn_msg	*incoming_cn_msg;
-	struct hv_ku_msg *hv_msg;
+	struct hv_kvp_msg *hv_msg;
 	char	*p;
 	char	*key_value;
 	char	*key_name;
@@ -370,9 +340,11 @@ int main(void)
 	message = (struct cn_msg *)kvp_send_buffer;
 	message->id.idx = CN_KVP_IDX;
 	message->id.val = CN_KVP_VAL;
-	message->seq = KVP_REGISTER;
+
+	hv_msg = (struct hv_kvp_msg *)message->data;
+	hv_msg->kvp_hdr.operation = KVP_OP_REGISTER;
 	message->ack = 0;
-	message->len = 0;
+	message->len = sizeof(struct hv_kvp_msg);
 
 	len = netlink_send(fd, message);
 	if (len < 0) {
@@ -398,14 +370,15 @@ int main(void)
 
 		incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
 		incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
+		hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
 
-		switch (incoming_cn_msg->seq) {
-		case KVP_REGISTER:
+		switch (hv_msg->kvp_hdr.operation) {
+		case KVP_OP_REGISTER:
 			/*
 			 * Driver is registering with us; stash away the version
 			 * information.
 			 */
-			p = (char *)incoming_cn_msg->data;
+			p = (char *)hv_msg->body.kvp_version;
 			lic_version = malloc(strlen(p) + 1);
 			if (lic_version) {
 				strcpy(lic_version, p);
@@ -416,17 +389,15 @@ int main(void)
 			}
 			continue;
 
-		case KVP_KERNEL_GET:
-			break;
 		default:
-			continue;
+			break;
 		}
 
-		hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data;
-		key_name = (char *)hv_msg->kvp_key;
-		key_value = (char *)hv_msg->kvp_value;
+		hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
+		key_name = (char *)hv_msg->body.kvp_enum_data.data.key;
+		key_value = (char *)hv_msg->body.kvp_enum_data.data.value;
 
-		switch (hv_msg->kvp_index) {
+		switch (hv_msg->body.kvp_enum_data.index) {
 		case FullyQualifiedDomainName:
 			kvp_get_domain_name(key_value,
 					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
@@ -486,9 +457,8 @@ int main(void)
 
 		incoming_cn_msg->id.idx = CN_KVP_IDX;
 		incoming_cn_msg->id.val = CN_KVP_VAL;
-		incoming_cn_msg->seq = KVP_USER_SET;
 		incoming_cn_msg->ack = 0;
-		incoming_cn_msg->len = sizeof(struct hv_ku_msg);
+		incoming_cn_msg->len = sizeof(struct hv_kvp_msg);
 
 		len = netlink_send(fd, incoming_cn_msg);
 		if (len < 0) {
diff --git a/tools/kvm/.gitignore b/tools/kvm/.gitignore
new file mode 100644
index 0000000..60dd6db
--- /dev/null
+++ b/tools/kvm/.gitignore
@@ -0,0 +1,12 @@
+/lkvm
+/vm
+*.o
+*.d
+.cscope
+tags
+include/common-cmds.h
+tests/boot/boot_test.iso
+tests/boot/rootfs/
+guest/init
+guest/init_stage2
+KVMTOOLS-VERSION-FILE
diff --git a/tools/kvm/CREDITS-Git b/tools/kvm/CREDITS-Git
new file mode 100644
index 0000000..c2ddcb3
--- /dev/null
+++ b/tools/kvm/CREDITS-Git
@@ -0,0 +1,30 @@
+Most of the infrastructure that 'perf' uses here has been reused
+from the Git project, as of version:
+
+    66996ec: Sync with 1.6.2.4
+
+Here is an (incomplete!) list of main contributors to those files
+in util/* and elsewhere:
+
+ Alex Riesen
+ Christian Couder
+ Dmitry Potapov
+ Jeff King
+ Johannes Schindelin
+ Johannes Sixt
+ Junio C Hamano
+ Linus Torvalds
+ Matthias Kestenholz
+ Michal Ostrowski
+ Miklos Vajna
+ Petr Baudis
+ Pierre Habouzit
+ René Scharfe
+ Samuel Tardieu
+ Shawn O. Pearce
+ Steffen Prohaska
+ Steve Haslam
+
+Thanks guys!
+
+The full history of the files can be found in the upstream Git commits.
diff --git a/tools/kvm/Documentation/kernel-debugging.txt b/tools/kvm/Documentation/kernel-debugging.txt
new file mode 100644
index 0000000..98b9438
--- /dev/null
+++ b/tools/kvm/Documentation/kernel-debugging.txt
@@ -0,0 +1,15 @@
+This document explains how to debug a guests' kernel using KGDB.
+
+1. Run the guest:
+        'lkvm run -k [vmlinuz] -p "kgdboc=ttyS1 kgdbwait" --tty 1'
+
+And see which PTY got assigned to ttyS1 (you'll see:
+'  Info: Assigned terminal 1 to pty /dev/pts/X').
+
+2. Run GDB on the host:
+        'gdb [vmlinuz]'
+
+3. Connect to the guest (from within GDB):
+        'target remote /dev/pty/X'
+
+4. Start debugging! (enter 'continue' to continue boot).
diff --git a/tools/kvm/Documentation/kvm-balloon.txt b/tools/kvm/Documentation/kvm-balloon.txt
new file mode 100644
index 0000000..efc0a87
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-balloon.txt
@@ -0,0 +1,24 @@
+lkvm-balloon(1)
+================
+
+NAME
+----
+lkvm-balloon - Inflate or deflate the virtio balloon
+
+SYNOPSIS
+--------
+[verse]
+'lkvm balloon [command] [size] [instance]'
+
+DESCRIPTION
+-----------
+The command inflates or deflates the virtio balloon located in the
+specified instance.
+For a list of running instances see 'lkvm list'.
+
+Command can be either 'inflate' or 'deflate'. Inflate increases the
+size of the balloon, thus decreasing the amount of virtual RAM available
+for the guest. Deflation returns previously inflated memory back to the
+guest.
+
+size is specified in Mb.
diff --git a/tools/kvm/Documentation/kvm-debug.txt b/tools/kvm/Documentation/kvm-debug.txt
new file mode 100644
index 0000000..a8eb2c0
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-debug.txt
@@ -0,0 +1,16 @@
+lkvm-debug(1)
+================
+
+NAME
+----
+lkvm-debug - Print debug information from a running instance
+
+SYNOPSIS
+--------
+[verse]
+'lkvm debug [instance]'
+
+DESCRIPTION
+-----------
+The command prints debug information from a running instance.
+For a list of running instances see 'lkvm list'.
diff --git a/tools/kvm/Documentation/kvm-list.txt b/tools/kvm/Documentation/kvm-list.txt
new file mode 100644
index 0000000..a245607
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-list.txt
@@ -0,0 +1,16 @@
+lkvm-list(1)
+================
+
+NAME
+----
+lkvm-list - Print a list of running instances on the host.
+
+SYNOPSIS
+--------
+[verse]
+'lkvm list'
+
+DESCRIPTION
+-----------
+This command prints a list of running instances on the host which
+belong to the user who currently ran 'lkvm list'.
diff --git a/tools/kvm/Documentation/kvm-pause.txt b/tools/kvm/Documentation/kvm-pause.txt
new file mode 100644
index 0000000..1ea2a23
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-pause.txt
@@ -0,0 +1,16 @@
+lkvm-pause(1)
+================
+
+NAME
+----
+lkvm-pause - Pause the virtual machine
+
+SYNOPSIS
+--------
+[verse]
+'lkvm pause [instance]'
+
+DESCRIPTION
+-----------
+The command pauses a virtual machine.
+For a list of running instances see 'lkvm list'.
diff --git a/tools/kvm/Documentation/kvm-resume.txt b/tools/kvm/Documentation/kvm-resume.txt
new file mode 100644
index 0000000..a36c4df
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-resume.txt
@@ -0,0 +1,16 @@
+lkvm-resume(1)
+================
+
+NAME
+----
+lkvm-resume - Resume the virtual machine
+
+SYNOPSIS
+--------
+[verse]
+'lkvm resume [instance]'
+
+DESCRIPTION
+-----------
+The command resumes a virtual machine.
+For a list of running instances see 'lkvm list'.
diff --git a/tools/kvm/Documentation/kvm-run.txt b/tools/kvm/Documentation/kvm-run.txt
new file mode 100644
index 0000000..8ddf470
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-run.txt
@@ -0,0 +1,62 @@
+lkvm-run(1)
+================
+
+NAME
+----
+lkvm-run - Start the virtual machine
+
+SYNOPSIS
+--------
+[verse]
+'lkvm run' [-k <kernel image> | --kernel <kernel image>]
+
+DESCRIPTION
+-----------
+The command starts a virtual machine.
+
+OPTIONS
+-------
+-m::
+--mem=::
+	Virtual machine memory size in MiB.
+
+-p::
+--params::
+	Additional kernel command line arguments.
+
+-r::
+--initrd=::
+	Initial RAM disk image.
+
+-k::
+--kernel=::
+	The virtual machine kernel.
+
+--dev=::
+	KVM device file.
+
+-i::
+--image=::
+	A disk image file.
+
+-s::
+--single-step::
+	Enable single stepping.
+
+-g::
+--ioport-debug::
+	Enable ioport debugging.
+
+-c::
+--enable-virtio-console::
+	Enable the virtual IO console.
+
+--cpus::
+	The number of virtual CPUs to run.
+
+--debug::
+	Enable debug messages.
+
+SEE ALSO
+--------
+linkkvm:
diff --git a/tools/kvm/Documentation/kvm-sandbox.txt b/tools/kvm/Documentation/kvm-sandbox.txt
new file mode 100644
index 0000000..2d7f558
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-sandbox.txt
@@ -0,0 +1,16 @@
+lkvm-sandbox(1)
+================
+
+NAME
+----
+lkvm-sandbox - Run a command in a sandboxed guest
+
+SYNOPSIS
+--------
+[verse]
+'lkvm sandbox ['lkvm run' arguments] -- [sandboxed command]'
+
+DESCRIPTION
+-----------
+The sandboxed command will run in a guest as part of it's init
+command.
diff --git a/tools/kvm/Documentation/kvm-setup.txt b/tools/kvm/Documentation/kvm-setup.txt
new file mode 100644
index 0000000..4b6e331
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-setup.txt
@@ -0,0 +1,15 @@
+lkvm-setup(1)
+================
+
+NAME
+----
+lkvm-setup - Setup a new virtual machine
+
+SYNOPSIS
+--------
+[verse]
+'lkvm setup <name>'
+
+DESCRIPTION
+-----------
+The command setups a virtual machine.
diff --git a/tools/kvm/Documentation/kvm-stat.txt b/tools/kvm/Documentation/kvm-stat.txt
new file mode 100644
index 0000000..101ce7a
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-stat.txt
@@ -0,0 +1,19 @@
+lkvm-stat(1)
+================
+
+NAME
+----
+lkvm-stat - Print statistics about a running instance
+
+SYNOPSIS
+--------
+[verse]
+'lkvm [command] [-n instance] [-p instance pid] [--all]'
+
+DESCRIPTION
+-----------
+The command prints statistics about a running instance.
+For a list of running instances see 'lkvm list'.
+
+Commands:
+ --memory, -m	Display memory statistics
diff --git a/tools/kvm/Documentation/kvm-stop.txt b/tools/kvm/Documentation/kvm-stop.txt
new file mode 100644
index 0000000..6e4bc83
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-stop.txt
@@ -0,0 +1,16 @@
+lkvm-stop(1)
+================
+
+NAME
+----
+lkvm-stop - Stop a running instance
+
+SYNOPSIS
+--------
+[verse]
+'lkvm stop [instance]'
+
+DESCRIPTION
+-----------
+The command stops a running instance.
+For a list of running instances see 'lkvm list'.
diff --git a/tools/kvm/Documentation/kvm-version.txt b/tools/kvm/Documentation/kvm-version.txt
new file mode 100644
index 0000000..41003d2
--- /dev/null
+++ b/tools/kvm/Documentation/kvm-version.txt
@@ -0,0 +1,21 @@
+lkvm-version(1)
+================
+
+NAME
+----
+lkvm-version - Print the version of the kernel tree kvm tools
+was built on.
+
+SYNOPSIS
+--------
+[verse]
+'lkvm version'
+
+DESCRIPTION
+-----------
+The command prints the version of the kernel that was used to build
+kvm tools.
+
+Note that the version is not the version of the kernel which is currently
+running on the host, but is the version of the kernel tree from which kvm
+tools was built.
diff --git a/tools/kvm/Documentation/virtio-console.txt b/tools/kvm/Documentation/virtio-console.txt
new file mode 100644
index 0000000..4a58d56
--- /dev/null
+++ b/tools/kvm/Documentation/virtio-console.txt
@@ -0,0 +1,41 @@
+General
+--------
+
+virtio-console as the name implies is a console over virtio transport. Here is
+a simple head to head comparison of the virtio-console vs regular 8250 console:
+
+8250 serial console:
+
+ - Requires CONFIG_SERIAL_8250=y and CONFIG_SERIAL_8250_CONSOLE=y kernel configs,
+which are enabled almost everywhere.
+ - Doesn't require guest-side changes.
+ - Compatible with older guests.
+
+virtio-console:
+
+ - Requires CONFIG_VIRTIO_CONSOLE=y (along with all other virtio dependencies),
+which got enabled only in recent kernels (but not all of them).
+ - Much faster.
+ - Consumes less processing resources.
+ - Requires guest-side changes.
+
+Enabling virtio-console
+------------------------
+
+First, make sure guest kernel is built with CONFIG_VIRTIO_CONSOLE=y. Once this
+is done, the following has to be done inside guest image:
+
+ - Add the following line to /etc/inittab:
+	'hvc0:2345:respawn:/sbin/agetty -L 9600 hvc0'
+ - Add 'hvc0' to /etc/securetty (so you could actually log on)
+ - Start the guest with '--console virtio'
+
+Common errors
+--------------
+
+Q: I don't see anything on the screen!
+A: Make sure CONFIG_VIRTIO_CONSOLE=y is enabled in the *guest* kernel, also
+make sure you've updated /etc/inittab
+
+Q: It won't accept my username/password, but I enter them correctly!
+A: You didn't add 'hvc0' to /etc/securetty
diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
new file mode 100644
index 0000000..cfa5547
--- /dev/null
+++ b/tools/kvm/Makefile
@@ -0,0 +1,425 @@
+#
+# Define WERROR=0 to disable -Werror.
+#
+
+ifeq ($(strip $(V)),)
+	E = @echo
+	Q = @
+else
+	E = @\#
+	Q =
+endif
+ifneq ($(I), )
+	KINCL_PATH=$(I)
+else
+	KINCL_PATH=../..
+endif
+export E Q KINCL_PATH
+
+include config/utilities.mak
+include config/feature-tests.mak
+
+FIND	:= find
+CSCOPE	:= cscope
+TAGS	:= ctags
+
+PROGRAM	:= lkvm
+PROGRAM_ALIAS := vm
+
+GUEST_INIT := guest/init
+GUEST_INIT_S2 := guest/init_stage2
+
+OBJS	+= builtin-balloon.o
+OBJS	+= builtin-debug.o
+OBJS	+= builtin-help.o
+OBJS	+= builtin-list.o
+OBJS	+= builtin-stat.o
+OBJS	+= builtin-pause.o
+OBJS	+= builtin-resume.o
+OBJS	+= builtin-run.o
+OBJS	+= builtin-setup.o
+OBJS	+= builtin-stop.o
+OBJS	+= builtin-version.o
+OBJS	+= disk/core.o
+OBJS	+= framebuffer.o
+OBJS	+= guest_compat.o
+OBJS	+= hw/rtc.o
+OBJS	+= hw/serial.o
+OBJS	+= ioport.o
+OBJS	+= kvm-cpu.o
+OBJS	+= kvm.o
+OBJS	+= main.o
+OBJS	+= mmio.o
+OBJS	+= pci.o
+OBJS	+= term.o
+OBJS	+= virtio/blk.o
+OBJS	+= virtio/console.o
+OBJS	+= virtio/core.o
+OBJS	+= virtio/net.o
+OBJS	+= virtio/rng.o
+OBJS    += virtio/balloon.o
+OBJS	+= virtio/pci.o
+OBJS	+= virtio/trans.o
+OBJS	+= disk/blk.o
+OBJS	+= disk/qcow.o
+OBJS	+= disk/raw.o
+OBJS	+= ioeventfd.o
+OBJS	+= net/uip/core.o
+OBJS	+= net/uip/arp.o
+OBJS	+= net/uip/icmp.o
+OBJS	+= net/uip/ipv4.o
+OBJS	+= net/uip/tcp.o
+OBJS	+= net/uip/udp.o
+OBJS	+= net/uip/buf.o
+OBJS	+= net/uip/csum.o
+OBJS	+= net/uip/dhcp.o
+OBJS	+= kvm-cmd.o
+OBJS	+= util/rbtree.o
+OBJS	+= util/threadpool.o
+OBJS	+= util/parse-options.o
+OBJS	+= util/rbtree-interval.o
+OBJS	+= util/strbuf.o
+OBJS	+= util/read-write.o
+OBJS	+= util/util.o
+OBJS	+= virtio/9p.o
+OBJS	+= virtio/9p-pdu.o
+OBJS	+= hw/vesa.o
+OBJS	+= hw/pci-shmem.o
+OBJS	+= kvm-ipc.o
+OBJS	+= builtin-sandbox.o
+
+# Additional ARCH settings for x86
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+                  -e s/arm.*/arm/ -e s/sa110/arm/ \
+                  -e s/s390x/s390/ -e s/parisc64/parisc/ \
+                  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+                  -e s/sh[234].*/sh/ )
+
+uname_M      := $(shell uname -m | sed -e s/i.86/i386/)
+ifeq ($(uname_M),i386)
+	ARCH         := x86
+	DEFINES      += -DCONFIG_X86_32
+endif
+ifeq ($(uname_M),x86_64)
+	ARCH         := x86
+	DEFINES      += -DCONFIG_X86_64
+endif
+
+LIBFDT_SRC = fdt.o fdt_ro.o fdt_wip.o fdt_sw.o fdt_rw.o fdt_strerror.o
+LIBFDT_OBJS = $(patsubst %,../../scripts/dtc/libfdt/%,$(LIBFDT_SRC))
+
+### Arch-specific stuff
+
+#x86
+ifeq ($(ARCH),x86)
+	DEFINES += -DCONFIG_X86
+	OBJS	+= x86/cpuid.o
+	OBJS	+= x86/interrupt.o
+	OBJS	+= x86/ioport.o
+	OBJS	+= x86/irq.o
+	OBJS	+= x86/kvm.o
+	OBJS	+= x86/kvm-cpu.o
+	OBJS	+= x86/mptable.o
+	OBJS	+= hw/i8042.o
+# Exclude BIOS object files from header dependencies.
+	OTHEROBJS	+= x86/bios.o
+	OTHEROBJS	+= x86/bios/bios-rom.o
+	ARCH_INCLUDE := x86/include
+endif
+# POWER/ppc:  Actually only support ppc64 currently.
+ifeq ($(uname_M), ppc64)
+	DEFINES += -DCONFIG_PPC
+	OBJS	+= powerpc/ioport.o
+	OBJS	+= powerpc/irq.o
+	OBJS	+= powerpc/kvm.o
+	OBJS	+= powerpc/cpu_info.o
+	OBJS	+= powerpc/kvm-cpu.o
+	OBJS	+= powerpc/spapr_hcall.o
+	OBJS	+= powerpc/spapr_rtas.o
+	OBJS	+= powerpc/spapr_hvcons.o
+	OBJS	+= powerpc/spapr_pci.o
+	OBJS	+= powerpc/xics.o
+# We use libfdt, but it's sometimes not packaged 64bit.  It's small too,
+# so just build it in:
+	CFLAGS 	+= -I../../scripts/dtc/libfdt
+	OTHEROBJS	+= $(LIBFDT_OBJS)
+	ARCH_INCLUDE := powerpc/include
+	CFLAGS 	+= -m64
+endif
+
+###
+
+ifeq (,$(ARCH_INCLUDE))
+	UNSUPP_ERR = @echo "This architecture is not supported in kvmtool." && exit 1
+else
+	UNSUPP_ERR =
+endif
+
+###
+
+# Detect optional features.
+# On a given system, some libs may link statically, some may not; so, check
+# both and only build those that link!
+
+FLAGS_BFD := $(CFLAGS) -lbfd
+ifeq ($(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)),y)
+	CFLAGS_DYNOPT	+= -DCONFIG_HAS_BFD
+	OBJS_DYNOPT	+= symbol.o
+	LIBS_DYNOPT	+= -lbfd
+endif
+ifeq ($(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD) -static),y)
+	CFLAGS_STATOPT	+= -DCONFIG_HAS_BFD
+	OBJS_STATOPT	+= symbol.o
+	LIBS_STATOPT	+= -lbfd
+endif
+
+FLAGS_VNCSERVER := $(CFLAGS) -lvncserver
+ifeq ($(call try-cc,$(SOURCE_VNCSERVER),$(FLAGS_VNCSERVER)),y)
+	OBJS_DYNOPT	+= ui/vnc.o
+	CFLAGS_DYNOPT	+= -DCONFIG_HAS_VNCSERVER
+	LIBS_DYNOPT	+= -lvncserver
+endif
+ifeq ($(call try-cc,$(SOURCE_VNCSERVER),$(FLAGS_VNCSERVER) -static),y)
+	OBJS_STATOPT	+= ui/vnc.o
+	CFLAGS_STATOPT	+= -DCONFIG_HAS_VNCSERVER
+	LIBS_STATOPT	+= -lvncserver
+endif
+
+FLAGS_SDL := $(CFLAGS) -lSDL
+ifeq ($(call try-cc,$(SOURCE_SDL),$(FLAGS_SDL)),y)
+	OBJS_DYNOPT	+= ui/sdl.o
+	CFLAGS_DYNOPT	+= -DCONFIG_HAS_SDL
+	LIBS_DYNOPT	+= -lSDL
+endif
+ifeq ($(call try-cc,$(SOURCE_SDL),$(FLAGS_SDL) -static), y)
+	OBJS_STATOPT	+= ui/sdl.o
+	CFLAGS_STATOPT	+= -DCONFIG_HAS_SDL
+	LIBS_STATOPT	+= -lSDL
+endif
+
+FLAGS_ZLIB := $(CFLAGS) -lz
+ifeq ($(call try-cc,$(SOURCE_ZLIB),$(FLAGS_ZLIB)),y)
+	CFLAGS_DYNOPT	+= -DCONFIG_HAS_ZLIB
+	LIBS_DYNOPT	+= -lz
+endif
+ifeq ($(call try-cc,$(SOURCE_ZLIB),$(FLAGS_ZLIB) -static),y)
+	CFLAGS_STATOPT	+= -DCONFIG_HAS_ZLIB
+	LIBS_STATOPT	+= -lz
+endif
+
+FLAGS_AIO := $(CFLAGS) -laio
+ifeq ($(call try-cc,$(SOURCE_AIO),$(FLAGS_AIO)),y)
+	CFLAGS_DYNOPT	+= -DCONFIG_HAS_AIO
+	LIBS_DYNOPT	+= -laio
+endif
+ifeq ($(call try-cc,$(SOURCE_AIO),$(FLAGS_AIO) -static),y)
+	CFLAGS_STATOPT	+= -DCONFIG_HAS_AIO
+	LIBS_STATOPT	+= -laio
+endif
+
+###
+
+LIBS	+= -lrt
+LIBS	+= -lpthread
+LIBS	+= -lutil
+
+
+DEPS	:= $(patsubst %.o,%.d,$(OBJS))
+
+DEFINES	+= -D_FILE_OFFSET_BITS=64
+DEFINES	+= -D_GNU_SOURCE
+DEFINES	+= -DKVMTOOLS_VERSION='"$(KVMTOOLS_VERSION)"'
+DEFINES	+= -DBUILD_ARCH='"$(ARCH)"'
+
+KVM_INCLUDE := include
+CFLAGS	+= $(CPPFLAGS) $(DEFINES) -I$(KVM_INCLUDE) -I$(ARCH_INCLUDE) -I$(KINCL_PATH)/include -I$(KINCL_PATH)/arch/$(ARCH)/include/ -O2 -fno-strict-aliasing -g
+
+WARNINGS += -Wall
+WARNINGS += -Wcast-align
+WARNINGS += -Wformat=2
+WARNINGS += -Winit-self
+WARNINGS += -Wmissing-declarations
+WARNINGS += -Wmissing-prototypes
+WARNINGS += -Wnested-externs
+WARNINGS += -Wno-system-headers
+WARNINGS += -Wold-style-definition
+WARNINGS += -Wredundant-decls
+WARNINGS += -Wsign-compare
+WARNINGS += -Wstrict-prototypes
+WARNINGS += -Wundef
+WARNINGS += -Wvolatile-register-var
+WARNINGS += -Wwrite-strings
+
+CFLAGS	+= $(WARNINGS)
+
+# Some targets may use 'external' sources that don't build totally cleanly.
+CFLAGS_EASYGOING := $(CFLAGS)
+
+ifneq ($(WERROR),0)
+	CFLAGS += -Werror
+endif
+
+all: arch_support_check $(PROGRAM) $(PROGRAM_ALIAS) $(GUEST_INIT) $(GUEST_INIT_S2)
+
+arch_support_check:
+	$(UNSUPP_ERR)
+
+KVMTOOLS-VERSION-FILE:
+	@$(SHELL_PATH) util/KVMTOOLS-VERSION-GEN $(OUTPUT)
+-include $(OUTPUT)KVMTOOLS-VERSION-FILE
+
+# When building -static all objects are built with appropriate flags, which
+# may differ between static & dynamic .o.  The objects are separated into
+# .o and .static.o.  See the %.o: %.c rules below.
+#
+# $(OTHEROBJS) are things that do not get substituted like this.
+#
+STATIC_OBJS = $(patsubst %.o,%.static.o,$(OBJS) $(OBJS_STATOPT))
+
+$(PROGRAM)-static:  $(DEPS) $(STATIC_OBJS) $(OTHEROBJS)
+	$(E) "  LINK    " $@
+	$(Q) $(CC) -static $(CFLAGS) $(STATIC_OBJS) $(OTHEROBJS) $(LIBS) $(LIBS_STATOPT) -o $@
+
+$(PROGRAM): $(DEPS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS)
+	$(E) "  LINK    " $@
+	$(Q) $(CC) $(CFLAGS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(LIBS) $(LIBS_DYNOPT) -o $@
+
+$(PROGRAM_ALIAS): $(PROGRAM)
+	$(E) "  LN      " $@
+	$(Q) ln -f $(PROGRAM) $@
+
+$(GUEST_INIT): guest/init.c
+	$(E) "  LINK    " $@
+	$(Q) $(CC) -static guest/init.c -o $@
+
+$(GUEST_INIT_S2): guest/init_stage2.c
+	$(E) "  LINK    " $@
+	$(Q) $(CC) -static guest/init_stage2.c -o $@
+
+$(DEPS):
+
+util/rbtree.d: ../../lib/rbtree.c
+	$(Q) $(CC) -M -MT util/rbtree.o $(CFLAGS) $< -o $@
+
+%.d: %.c
+	$(Q) $(CC) -M -MT $(patsubst %.d,%.o,$@) $(CFLAGS) $< -o $@
+
+# The header file common-cmds.h is needed for compilation of builtin-help.c.
+builtin-help.d: $(KVM_INCLUDE)/common-cmds.h
+
+$(OBJS):
+
+# This rule relaxes the -Werror on libfdt, since for now it still has
+# a bunch of warnings. :(
+../../scripts/dtc/libfdt/%.o: ../../scripts/dtc/libfdt/%.c
+	$(E) "  CC      " $@
+	$(Q) $(CC) -c $(CFLAGS_EASYGOING) $< -o $@
+
+util/rbtree.static.o util/rbtree.o: ../../lib/rbtree.c
+	$(E) "  CC      " $@
+	$(Q) $(CC) -c $(CFLAGS) $< -o $@
+
+%.static.o: %.c
+	$(E) "  CC      " $@
+	$(Q) $(CC) -c $(CFLAGS) $(CFLAGS_STATOPT)  $< -o $@
+
+%.o: %.c
+	$(E) "  CC      " $@
+	$(Q) $(CC) -c $(CFLAGS) $(CFLAGS_DYNOPT) $< -o $@
+
+
+$(KVM_INCLUDE)/common-cmds.h: util/generate-cmdlist.sh command-list.txt
+
+$(KVM_INCLUDE)/common-cmds.h: $(wildcard Documentation/kvm-*.txt)
+	$(E) "  GEN     " $@
+	$(Q) util/generate-cmdlist.sh > $@+ && mv $@+ $@
+
+#
+# BIOS assembly weirdness
+#
+BIOS_CFLAGS += -m32
+BIOS_CFLAGS += -march=i386
+BIOS_CFLAGS += -mregparm=3
+
+BIOS_CFLAGS += -fno-stack-protector
+BIOS_CFLAGS += -I../../arch/$(ARCH)
+
+x86/bios.o: x86/bios/bios.bin x86/bios/bios-rom.h
+
+x86/bios/bios.bin.elf: x86/bios/entry.S x86/bios/e820.c x86/bios/int10.c x86/bios/int15.c x86/bios/rom.ld.S
+	$(E) "  CC       x86/bios/memcpy.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/memcpy.c -o x86/bios/memcpy.o
+	$(E) "  CC       x86/bios/e820.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/e820.c -o x86/bios/e820.o
+	$(E) "  CC       x86/bios/int10.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int10.c -o x86/bios/int10.o
+	$(E) "  CC       x86/bios/int15.o"
+	$(Q) $(CC) -include code16gcc.h $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/int15.c -o x86/bios/int15.o
+	$(E) "  CC       x86/bios/entry.o"
+	$(Q) $(CC) $(CFLAGS) $(BIOS_CFLAGS) -c -s x86/bios/entry.S -o x86/bios/entry.o
+	$(E) "  LD      " $@
+	$(Q) ld -T x86/bios/rom.ld.S -o x86/bios/bios.bin.elf x86/bios/memcpy.o x86/bios/entry.o x86/bios/e820.o x86/bios/int10.o x86/bios/int15.o
+
+x86/bios/bios.bin: x86/bios/bios.bin.elf
+	$(E) "  OBJCOPY " $@
+	$(Q) objcopy -O binary -j .text x86/bios/bios.bin.elf x86/bios/bios.bin
+
+x86/bios/bios-rom.o: x86/bios/bios-rom.S x86/bios/bios.bin x86/bios/bios-rom.h
+	$(E) "  CC      " $@
+	$(Q) $(CC) -c $(CFLAGS) x86/bios/bios-rom.S -o x86/bios/bios-rom.o
+
+x86/bios/bios-rom.h: x86/bios/bios.bin.elf
+	$(E) "  NM      " $@
+	$(Q) cd x86/bios && sh gen-offsets.sh > bios-rom.h && cd ..
+
+check: all
+	$(MAKE) -C tests
+	./$(PROGRAM) run tests/pit/tick.bin
+	./$(PROGRAM) run -d tests/boot/boot_test.iso -p "init=init"
+.PHONY: check
+
+clean:
+	$(E) "  CLEAN"
+	$(Q) rm -f x86/bios/*.bin
+	$(Q) rm -f x86/bios/*.elf
+	$(Q) rm -f x86/bios/*.o
+	$(Q) rm -f x86/bios/bios-rom.h
+	$(Q) rm -f tests/boot/boot_test.iso
+	$(Q) rm -rf tests/boot/rootfs/
+	$(Q) rm -f $(DEPS) $(OBJS) $(OTHEROBJS) $(OBJS_DYNOPT) $(STATIC_OBJS) $(PROGRAM) $(PROGRAM_ALIAS) $(PROGRAM)-static $(GUEST_INIT) $(GUEST_INIT_S2)
+	$(Q) rm -f cscope.*
+	$(Q) rm -f tags
+	$(Q) rm -f TAGS
+	$(Q) rm -f $(KVM_INCLUDE)/common-cmds.h
+	$(Q) rm -f KVMTOOLS-VERSION-FILE
+.PHONY: clean
+
+KVM_DEV	?= /dev/kvm
+
+$(KVM_DEV):
+	$(E) "  MKNOD " $@
+	$(Q) mknod $@ char 10 232
+
+devices: $(KVM_DEV)
+.PHONY: devices
+
+TAGS:
+	$(E) "  GEN" $@
+	$(Q) $(RM) -f TAGS
+	$(Q) $(FIND) . -name '*.[hcS]' -print | xargs etags -a
+.PHONY: TAGS
+
+tags:
+	$(E) "  GEN" $@
+	$(Q) $(RM) -f tags
+	$(Q) $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
+.PHONY: tags
+
+cscope:
+	$(E) "  GEN" $@
+	$(Q) $(FIND) . -name '*.[hcS]' -print > cscope.files
+	$(Q) $(CSCOPE) -bkqu
+.PHONY: cscope
+
+# Deps
+-include $(DEPS)
diff --git a/tools/kvm/README b/tools/kvm/README
new file mode 100644
index 0000000..d626b77
--- /dev/null
+++ b/tools/kvm/README
@@ -0,0 +1,109 @@
+Native Linux KVM tool
+=====================
+The goal of this tool is to provide a clean, from-scratch, lightweight
+KVM host tool implementation that can boot Linux guest images (just a
+hobby, won't be big and professional like QEMU) with no BIOS
+dependencies and with only the minimal amount of legacy device
+emulation.
+
+It's great as a learning tool if you want to get your feet wet in
+virtualization land: it's only 5 KLOC of clean C code that can already
+boot a guest Linux image.
+
+Right now it can boot a Linux image and provide you output via a serial
+console, over the host terminal, i.e. you can use it to boot a guest
+Linux image in a terminal or over ssh and log into the guest without
+much guest or host side setup work needed.
+
+1. To try out the tool, clone the git repository:
+
+  git clone git://github.com/penberg/linux-kvm.git
+
+or alternatively, if you already have a kernel source tree:
+
+  git remote add kvm-tool git://github.com/penberg/linux-kvm.git
+  git remote update
+  git checkout -b kvm-tool/master kvm-tool
+
+2. Compile the tool:
+
+  cd tools/kvm && make
+
+3. Download a raw userspace image:
+
+  wget http://wiki.qemu.org/download/linux-0.2.img.bz2 && bunzip2
+linux-0.2.img.bz2
+
+4. The guest kernel has to be built with the following configuration:
+
+ - For the default console output:
+	CONFIG_SERIAL_8250=y
+	CONFIG_SERIAL_8250_CONSOLE=y
+
+ - For running 32bit images on 64bit hosts:
+	CONFIG_IA32_EMULATION=y
+
+ - Proper FS options according to image FS (e.g. CONFIG_EXT2_FS, CONFIG_EXT4_FS).
+
+ - For all virtio devices listed below:
+	CONFIG_VIRTIO=y
+	CONFIG_VIRTIO_RING=y
+	CONFIG_VIRTIO_PCI=y
+
+ - For virtio-blk devices (--disk, -d):
+	CONFIG_VIRTIO_BLK=y
+
+ - For virtio-net devices ([--network, -n] virtio):
+	CONFIG_VIRTIO_NET=y
+
+ - For virtio-9p devices (--virtio-9p):
+	CONFIG_NET_9P=y
+	CONFIG_NET_9P_VIRTIO=y
+	CONFIG_9P_FS=y
+
+ - For virtio-balloon device (--balloon):
+	CONFIG_VIRTIO_BALLOON=y
+
+ - For virtio-console device (--console virtio):
+	CONFIG_VIRTIO_CONSOLE=y
+
+ - For virtio-rng device (--rng):
+	CONFIG_HW_RANDOM_VIRTIO=y
+
+
+5. And finally, launch the hypervisor:
+
+  ./lkvm run --disk linux-0.2.img \
+	    --kernel ../../arch/x86/boot/bzImage \
+or
+
+  sudo ./lkvm run --disk linux-0.2.img \
+		 --kernel ../../arch/x86/boot/bzImage \
+		 --network virtio
+
+The tool has been written by Pekka Enberg, Cyrill Gorcunov, Asias He,
+Sasha Levin and Prasad Joshi. Special thanks to Avi Kivity for his help
+on KVM internals and Ingo Molnar for all-around support and encouragement!
+
+See the following thread for original discussion for motivation of this
+project:
+
+http://thread.gmane.org/gmane.linux.kernel/962051/focus=962620
+
+Build dependencies
+=====================
+For deb based systems:
+32-bit:
+sudo apt-get install build-essential
+64-bit:
+sudo apt-get install build-essential libc6-dev-i386
+
+For rpm based systems:
+32-bit:
+yum install glibc-devel
+64-bit:
+yum install glibc-devel glibc-static
+
+On 64-bit Arch Linux make sure the multilib repository is enabled in your
+/etc/pacman.conf and run
+pacman -Sy lib32-glibc
diff --git a/tools/kvm/builtin-balloon.c b/tools/kvm/builtin-balloon.c
new file mode 100644
index 0000000..5bd2291
--- /dev/null
+++ b/tools/kvm/builtin-balloon.c
@@ -0,0 +1,80 @@
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-balloon.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm.h>
+#include <kvm/kvm-ipc.h>
+
+static const char *instance_name;
+static u64 inflate;
+static u64 deflate;
+
+static const char * const balloon_usage[] = {
+	"lkvm balloon [-n name] [-p pid] [-i amount] [-d amount]",
+	NULL
+};
+
+static const struct option balloon_options[] = {
+	OPT_GROUP("Instance options:"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_GROUP("Balloon options:"),
+	OPT_U64('i', "inflate", &inflate, "Amount to inflate"),
+	OPT_U64('d', "deflate", &deflate, "Amount to deflate"),
+	OPT_END(),
+};
+
+void kvm_balloon_help(void)
+{
+	usage_with_options(balloon_usage, balloon_options);
+}
+
+static void parse_balloon_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, balloon_options, balloon_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_balloon_help();
+	}
+}
+
+int kvm_cmd_balloon(int argc, const char **argv, const char *prefix)
+{
+	int instance;
+	int r;
+	int amount;
+
+	parse_balloon_options(argc, argv);
+
+	if (inflate == 0 && deflate == 0)
+		kvm_balloon_help();
+
+	if (instance_name == NULL)
+		kvm_balloon_help();
+
+	instance = kvm__get_sock_by_instance(instance_name);
+
+	if (instance <= 0)
+		die("Failed locating instance");
+
+	if (inflate)
+		amount = inflate;
+	else if (deflate)
+		amount = -deflate;
+	else
+		kvm_balloon_help();
+
+	r = kvm_ipc__send_msg(instance, KVM_IPC_BALLOON,
+			sizeof(amount), (u8 *)&amount);
+
+	close(instance);
+
+	if (r < 0)
+		return -1;
+
+	return 0;
+}
diff --git a/tools/kvm/builtin-debug.c b/tools/kvm/builtin-debug.c
new file mode 100644
index 0000000..20e27ff
--- /dev/null
+++ b/tools/kvm/builtin-debug.c
@@ -0,0 +1,103 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-debug.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
+#include <kvm/read-write.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#define BUFFER_SIZE 100
+
+static bool all;
+static int nmi = -1;
+static bool dump;
+static const char *instance_name;
+
+static const char * const debug_usage[] = {
+	"lkvm debug [--all] [-n name] [-d] [-m vcpu]",
+	NULL
+};
+
+static const struct option debug_options[] = {
+	OPT_GROUP("General options:"),
+	OPT_BOOLEAN('d', "dump", &dump, "Generate a debug dump from guest"),
+	OPT_INTEGER('m', "nmi", &nmi, "Generate NMI on VCPU"),
+	OPT_GROUP("Instance options:"),
+	OPT_BOOLEAN('a', "all", &all, "Debug all instances"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_END()
+};
+
+static void parse_debug_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, debug_options, debug_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_debug_help();
+	}
+}
+
+void kvm_debug_help(void)
+{
+	usage_with_options(debug_usage, debug_options);
+}
+
+static int do_debug(const char *name, int sock)
+{
+	char buff[BUFFER_SIZE];
+	struct debug_cmd_params cmd = {.dbg_type = 0};
+	int r;
+
+	if (dump)
+		cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_DUMP;
+
+	if (nmi != -1) {
+		cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_NMI;
+		cmd.cpu = nmi;
+	}
+
+	r = kvm_ipc__send_msg(sock, KVM_IPC_DEBUG, sizeof(cmd), (u8 *)&cmd);
+	if (r < 0)
+		return r;
+
+	if (!dump)
+		return 0;
+
+	do {
+		r = xread(sock, buff, BUFFER_SIZE);
+		if (r < 0)
+			return 0;
+		printf("%.*s", r, buff);
+	} while (r > 0);
+
+	return 0;
+}
+
+int kvm_cmd_debug(int argc, const char **argv, const char *prefix)
+{
+	parse_debug_options(argc, argv);
+	int instance;
+	int r;
+
+	if (all)
+		return kvm__enumerate_instances(do_debug);
+
+	if (instance_name == NULL)
+		kvm_debug_help();
+
+	instance = kvm__get_sock_by_instance(instance_name);
+
+	if (instance <= 0)
+		die("Failed locating instance");
+
+	r = do_debug(instance_name, instance);
+
+	close(instance);
+
+	return r;
+}
diff --git a/tools/kvm/builtin-help.c b/tools/kvm/builtin-help.c
new file mode 100644
index 0000000..5970fb7
--- /dev/null
+++ b/tools/kvm/builtin-help.c
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <string.h>
+
+/* user defined headers */
+#include <common-cmds.h>
+
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-help.h>
+#include <kvm/kvm.h>
+
+
+const char kvm_usage_string[] =
+	"lkvm COMMAND [ARGS]";
+
+const char kvm_more_info_string[] =
+	"See 'lkvm help COMMAND' for more information on a specific command.";
+
+
+static void list_common_cmds_help(void)
+{
+	unsigned int i, longest = 0;
+
+	for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
+		if (longest < strlen(common_cmds[i].name))
+			longest = strlen(common_cmds[i].name);
+	}
+
+	puts(" The most commonly used lkvm commands are:");
+	for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
+		printf("   %-*s   ", longest, common_cmds[i].name);
+		puts(common_cmds[i].help);
+	}
+}
+
+static void kvm_help(void)
+{
+	printf("\n To start a simple non-privileged shell run '%s run'\n\n"
+		"usage: %s\n\n", KVM_BINARY_NAME, kvm_usage_string);
+	list_common_cmds_help();
+	printf("\n %s\n\n", kvm_more_info_string);
+}
+
+
+static void help_cmd(const char *cmd)
+{
+	struct cmd_struct *p;
+	p = kvm_get_command(kvm_commands, cmd);
+	if (!p)
+		kvm_help();
+	else if (p->help)
+		p->help();
+}
+
+int kvm_cmd_help(int argc, const char **argv, const char *prefix)
+{
+	if (!argv || !*argv) {
+		kvm_help();
+		return 0;
+	}
+	help_cmd(argv[0]);
+	return 0;
+}
diff --git a/tools/kvm/builtin-list.c b/tools/kvm/builtin-list.c
new file mode 100644
index 0000000..9299f17
--- /dev/null
+++ b/tools/kvm/builtin-list.c
@@ -0,0 +1,149 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-list.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
+
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <fcntl.h>
+
+static bool run;
+static bool rootfs;
+
+static const char * const list_usage[] = {
+	"lkvm list",
+	NULL
+};
+
+static const struct option list_options[] = {
+	OPT_GROUP("General options:"),
+	OPT_BOOLEAN('i', "run", &run, "List running instances"),
+	OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"),
+	OPT_END()
+};
+
+#define KVM_INSTANCE_RUNNING	"running"
+#define KVM_INSTANCE_PAUSED	"paused"
+#define KVM_INSTANCE_SHUTOFF	"shut off"
+
+void kvm_list_help(void)
+{
+	usage_with_options(list_usage, list_options);
+}
+
+static pid_t get_pid(int sock)
+{
+	pid_t pid;
+	int r;
+
+	r = kvm_ipc__send(sock, KVM_IPC_PID);
+	if (r < 0)
+		return r;
+
+	r = read(sock, &pid, sizeof(pid));
+	if (r < 0)
+		return r;
+
+	return pid;
+}
+
+int get_vmstate(int sock)
+{
+	int vmstate;
+	int r;
+
+	r = kvm_ipc__send(sock, KVM_IPC_VMSTATE);
+	if (r < 0)
+		return r;
+
+	r = read(sock, &vmstate, sizeof(vmstate));
+	if (r < 0)
+		return r;
+
+	return vmstate;
+
+}
+
+static int print_guest(const char *name, int sock)
+{
+	pid_t pid;
+	int vmstate;
+
+	pid = get_pid(sock);
+	vmstate = get_vmstate(sock);
+
+	if ((int)pid < 0 || vmstate < 0)
+		return -1;
+
+	if (vmstate == KVM_VMSTATE_PAUSED)
+		printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_PAUSED);
+	else
+		printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_RUNNING);
+
+	return 0;
+}
+
+static int kvm_list_running_instances(void)
+{
+	return kvm__enumerate_instances(print_guest);
+}
+
+static int kvm_list_rootfs(void)
+{
+	DIR *dir;
+	struct dirent *dirent;
+
+	dir = opendir(kvm__get_dir());
+	if (dir == NULL)
+		return -1;
+
+	while ((dirent = readdir(dir))) {
+		if (dirent->d_type == DT_DIR &&
+			strcmp(dirent->d_name, ".") &&
+			strcmp(dirent->d_name, ".."))
+			printf("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF);
+	}
+
+	return 0;
+}
+
+static void parse_setup_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, list_options, list_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_list_help();
+	}
+}
+
+int kvm_cmd_list(int argc, const char **argv, const char *prefix)
+{
+	int r;
+
+	parse_setup_options(argc, argv);
+
+	if (!run && !rootfs)
+		run = rootfs = true;
+
+	printf("%6s %-20s %s\n", "PID", "NAME", "STATE");
+	printf("------------------------------------\n");
+
+	if (run) {
+		r = kvm_list_running_instances();
+		if (r < 0)
+			perror("Error listing instances");
+	}
+
+	if (rootfs) {
+		r = kvm_list_rootfs();
+		if (r < 0)
+			perror("Error listing rootfs");
+	}
+
+	return 0;
+}
diff --git a/tools/kvm/builtin-pause.c b/tools/kvm/builtin-pause.c
new file mode 100644
index 0000000..c08595a
--- /dev/null
+++ b/tools/kvm/builtin-pause.c
@@ -0,0 +1,88 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-pause.h>
+#include <kvm/builtin-list.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+static bool all;
+static const char *instance_name;
+
+static const char * const pause_usage[] = {
+	"lkvm pause [--all] [-n name]",
+	NULL
+};
+
+static const struct option pause_options[] = {
+	OPT_GROUP("General options:"),
+	OPT_BOOLEAN('a', "all", &all, "Pause all instances"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_END()
+};
+
+static void parse_pause_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, pause_options, pause_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_pause_help();
+	}
+}
+
+void kvm_pause_help(void)
+{
+	usage_with_options(pause_usage, pause_options);
+}
+
+static int do_pause(const char *name, int sock)
+{
+	int r;
+	int vmstate;
+
+	vmstate = get_vmstate(sock);
+	if (vmstate < 0)
+		return vmstate;
+	if (vmstate == KVM_VMSTATE_PAUSED) {
+		printf("Guest %s is already paused.\n", name);
+		return 0;
+	}
+
+	r = kvm_ipc__send(sock, KVM_IPC_PAUSE);
+	if (r)
+		return r;
+
+	printf("Guest %s paused\n", name);
+
+	return 0;
+}
+
+int kvm_cmd_pause(int argc, const char **argv, const char *prefix)
+{
+	int instance;
+	int r;
+
+	parse_pause_options(argc, argv);
+
+	if (all)
+		return kvm__enumerate_instances(do_pause);
+
+	if (instance_name == NULL)
+		kvm_pause_help();
+
+	instance = kvm__get_sock_by_instance(instance_name);
+
+	if (instance <= 0)
+		die("Failed locating instance");
+
+	r = do_pause(instance_name, instance);
+
+	close(instance);
+
+	return r;
+}
diff --git a/tools/kvm/builtin-resume.c b/tools/kvm/builtin-resume.c
new file mode 100644
index 0000000..0e954b4
--- /dev/null
+++ b/tools/kvm/builtin-resume.c
@@ -0,0 +1,88 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-resume.h>
+#include <kvm/builtin-list.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+static bool all;
+static const char *instance_name;
+
+static const char * const resume_usage[] = {
+	"lkvm resume [--all] [-n name]",
+	NULL
+};
+
+static const struct option resume_options[] = {
+	OPT_GROUP("General options:"),
+	OPT_BOOLEAN('a', "all", &all, "Resume all instances"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_END()
+};
+
+static void parse_resume_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, resume_options, resume_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_resume_help();
+	}
+}
+
+void kvm_resume_help(void)
+{
+	usage_with_options(resume_usage, resume_options);
+}
+
+static int do_resume(const char *name, int sock)
+{
+	int r;
+	int vmstate;
+
+	vmstate = get_vmstate(sock);
+	if (vmstate < 0)
+		return vmstate;
+	if (vmstate == KVM_VMSTATE_RUNNING) {
+		printf("Guest %s is still running.\n", name);
+		return 0;
+	}
+
+	r = kvm_ipc__send(sock, KVM_IPC_RESUME);
+	if (r)
+		return r;
+
+	printf("Guest %s resumed\n", name);
+
+	return 0;
+}
+
+int kvm_cmd_resume(int argc, const char **argv, const char *prefix)
+{
+	int instance;
+	int r;
+
+	parse_resume_options(argc, argv);
+
+	if (all)
+		return kvm__enumerate_instances(do_resume);
+
+	if (instance_name == NULL)
+		kvm_resume_help();
+
+	instance = kvm__get_sock_by_instance(instance_name);
+
+	if (instance <= 0)
+		die("Failed locating instance");
+
+	r = do_resume(instance_name, instance);
+
+	close(instance);
+
+	return r;
+}
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
new file mode 100644
index 0000000..466169e
--- /dev/null
+++ b/tools/kvm/builtin-run.c
@@ -0,0 +1,1343 @@
+#include "kvm/builtin-run.h"
+
+#include "kvm/builtin-setup.h"
+#include "kvm/virtio-balloon.h"
+#include "kvm/virtio-console.h"
+#include "kvm/parse-options.h"
+#include "kvm/8250-serial.h"
+#include "kvm/framebuffer.h"
+#include "kvm/disk-image.h"
+#include "kvm/threadpool.h"
+#include "kvm/virtio-blk.h"
+#include "kvm/virtio-net.h"
+#include "kvm/virtio-rng.h"
+#include "kvm/ioeventfd.h"
+#include "kvm/virtio-9p.h"
+#include "kvm/barrier.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/ioport.h"
+#include "kvm/symbol.h"
+#include "kvm/i8042.h"
+#include "kvm/mutex.h"
+#include "kvm/term.h"
+#include "kvm/util.h"
+#include "kvm/strbuf.h"
+#include "kvm/vesa.h"
+#include "kvm/irq.h"
+#include "kvm/kvm.h"
+#include "kvm/pci.h"
+#include "kvm/rtc.h"
+#include "kvm/sdl.h"
+#include "kvm/vnc.h"
+#include "kvm/guest_compat.h"
+#include "kvm/pci-shmem.h"
+#include "kvm/kvm-ipc.h"
+#include "kvm/builtin-debug.h"
+
+#include <linux/types.h>
+#include <linux/err.h>
+
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#define DEFAULT_KVM_DEV		"/dev/kvm"
+#define DEFAULT_CONSOLE		"serial"
+#define DEFAULT_NETWORK		"user"
+#define DEFAULT_HOST_ADDR	"192.168.33.1"
+#define DEFAULT_GUEST_ADDR	"192.168.33.15"
+#define DEFAULT_GUEST_MAC	"02:15:15:15:15:15"
+#define DEFAULT_HOST_MAC	"02:01:01:01:01:01"
+#define DEFAULT_SCRIPT		"none"
+const char *DEFAULT_SANDBOX_FILENAME = "guest/sandbox.sh";
+
+#define MB_SHIFT		(20)
+#define KB_SHIFT		(10)
+#define GB_SHIFT		(30)
+#define MIN_RAM_SIZE_MB		(64ULL)
+#define MIN_RAM_SIZE_BYTE	(MIN_RAM_SIZE_MB << MB_SHIFT)
+
+struct kvm *kvm;
+struct kvm_cpu **kvm_cpus;
+__thread struct kvm_cpu *current_kvm_cpu;
+
+static u64 ram_size;
+static u8  image_count;
+static u8 num_net_devices;
+static bool virtio_rng;
+static const char *kernel_cmdline;
+static const char *kernel_filename;
+static const char *vmlinux_filename;
+static const char *initrd_filename;
+static const char *image_filename[MAX_DISK_IMAGES];
+static const char *console;
+static const char *dev;
+static const char *network;
+static const char *host_ip;
+static const char *guest_ip;
+static const char *guest_mac;
+static const char *host_mac;
+static const char *script;
+static const char *guest_name;
+static const char *sandbox;
+static const char *hugetlbfs_path;
+static const char *custom_rootfs_name = "default";
+static struct virtio_net_params *net_params;
+static bool single_step;
+static bool readonly_image[MAX_DISK_IMAGES];
+static bool vnc;
+static bool sdl;
+static bool balloon;
+static bool using_rootfs;
+static bool custom_rootfs;
+static bool no_net;
+static bool no_dhcp;
+extern bool ioport_debug;
+static int  kvm_run_wrapper;
+extern int  active_console;
+extern int  debug_iodelay;
+
+bool do_debug_print = false;
+
+static int nrcpus;
+static int vidmode = -1;
+
+static const char * const run_usage[] = {
+	"lkvm run [<options>] [<kernel image>]",
+	NULL
+};
+
+enum {
+	KVM_RUN_DEFAULT,
+	KVM_RUN_SANDBOX,
+};
+
+void kvm_run_set_wrapper_sandbox(void)
+{
+	kvm_run_wrapper = KVM_RUN_SANDBOX;
+}
+
+static int img_name_parser(const struct option *opt, const char *arg, int unset)
+{
+	char *sep;
+	struct stat st;
+	char path[PATH_MAX];
+
+	if (stat(arg, &st) == 0 &&
+	    S_ISDIR(st.st_mode)) {
+		char tmp[PATH_MAX];
+
+		if (using_rootfs)
+			die("Please use only one rootfs directory atmost");
+
+		if (realpath(arg, tmp) == 0 ||
+		    virtio_9p__register(kvm, tmp, "/dev/root") < 0)
+			die("Unable to initialize virtio 9p");
+		using_rootfs = 1;
+		return 0;
+	}
+
+	snprintf(path, PATH_MAX, "%s%s", kvm__get_dir(), arg);
+
+	if (stat(path, &st) == 0 &&
+	    S_ISDIR(st.st_mode)) {
+		char tmp[PATH_MAX];
+
+		if (using_rootfs)
+			die("Please use only one rootfs directory atmost");
+
+		if (realpath(path, tmp) == 0 ||
+		    virtio_9p__register(kvm, tmp, "/dev/root") < 0)
+			die("Unable to initialize virtio 9p");
+		if (virtio_9p__register(kvm, "/", "hostfs") < 0)
+			die("Unable to initialize virtio 9p");
+		kvm_setup_resolv(arg);
+		using_rootfs = custom_rootfs = 1;
+		custom_rootfs_name = arg;
+		return 0;
+	}
+
+	if (image_count >= MAX_DISK_IMAGES)
+		die("Currently only 4 images are supported");
+
+	image_filename[image_count] = arg;
+	sep = strstr(arg, ",");
+	if (sep) {
+		if (strcmp(sep + 1, "ro") == 0)
+			readonly_image[image_count] = 1;
+		*sep = 0;
+	}
+
+	image_count++;
+
+	return 0;
+}
+
+static int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, int unset)
+{
+	char *tag_name;
+	char tmp[PATH_MAX];
+
+	/*
+	 * 9p dir can be of the form dirname,tag_name or
+	 * just dirname. In the later case we use the
+	 * default tag name
+	 */
+	tag_name = strstr(arg, ",");
+	if (tag_name) {
+		*tag_name = '\0';
+		tag_name++;
+	}
+	if (realpath(arg, tmp)) {
+		if (virtio_9p__register(kvm, tmp, tag_name) < 0)
+			die("Unable to initialize virtio 9p");
+	} else
+		die("Failed resolving 9p path");
+	return 0;
+}
+
+static int tty_parser(const struct option *opt, const char *arg, int unset)
+{
+	int tty = atoi(arg);
+
+	term_set_tty(tty);
+
+	return 0;
+}
+
+static inline void str_to_mac(const char *str, char *mac)
+{
+	sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+		mac, mac+1, mac+2, mac+3, mac+4, mac+5);
+}
+static int set_net_param(struct virtio_net_params *p, const char *param,
+				const char *val)
+{
+	if (strcmp(param, "guest_mac") == 0) {
+		str_to_mac(val, p->guest_mac);
+	} else if (strcmp(param, "mode") == 0) {
+		if (!strncmp(val, "user", 4)) {
+			int i;
+
+			for (i = 0; i < num_net_devices; i++)
+				if (net_params[i].mode == NET_MODE_USER)
+					die("Only one usermode network device allowed at a time");
+			p->mode = NET_MODE_USER;
+		} else if (!strncmp(val, "tap", 3)) {
+			p->mode = NET_MODE_TAP;
+		} else if (!strncmp(val, "none", 4)) {
+			no_net = 1;
+			return -1;
+		} else
+			die("Unkown network mode %s, please use user, tap or none", network);
+	} else if (strcmp(param, "script") == 0) {
+		p->script = strdup(val);
+	} else if (strcmp(param, "guest_ip") == 0) {
+		p->guest_ip = strdup(val);
+	} else if (strcmp(param, "host_ip") == 0) {
+		p->host_ip = strdup(val);
+	} else if (strcmp(param, "vhost") == 0) {
+		p->vhost = atoi(val);
+	} else if (strcmp(param, "fd") == 0) {
+		p->fd = atoi(val);
+	}
+
+	return 0;
+}
+
+static int netdev_parser(const struct option *opt, const char *arg, int unset)
+{
+	struct virtio_net_params p;
+	char *buf = NULL, *cmd = NULL, *cur = NULL;
+	bool on_cmd = true;
+
+	if (arg) {
+		buf = strdup(arg);
+		if (buf == NULL)
+			die("Failed allocating new net buffer");
+		cur = strtok(buf, ",=");
+	}
+
+	p = (struct virtio_net_params) {
+		.guest_ip	= DEFAULT_GUEST_ADDR,
+		.host_ip	= DEFAULT_HOST_ADDR,
+		.script		= DEFAULT_SCRIPT,
+		.mode		= NET_MODE_TAP,
+	};
+
+	str_to_mac(DEFAULT_GUEST_MAC, p.guest_mac);
+	p.guest_mac[5] += num_net_devices;
+
+	while (cur) {
+		if (on_cmd) {
+			cmd = cur;
+		} else {
+			if (set_net_param(&p, cmd, cur) < 0)
+				goto done;
+		}
+		on_cmd = !on_cmd;
+
+		cur = strtok(NULL, ",=");
+	};
+
+	num_net_devices++;
+
+	net_params = realloc(net_params, num_net_devices * sizeof(*net_params));
+	if (net_params == NULL)
+		die("Failed adding new network device");
+
+	net_params[num_net_devices - 1] = p;
+
+done:
+	free(buf);
+	return 0;
+}
+
+static int shmem_parser(const struct option *opt, const char *arg, int unset)
+{
+	const u64 default_size = SHMEM_DEFAULT_SIZE;
+	const u64 default_phys_addr = SHMEM_DEFAULT_ADDR;
+	const char *default_handle = SHMEM_DEFAULT_HANDLE;
+	struct shmem_info *si = malloc(sizeof(struct shmem_info));
+	u64 phys_addr;
+	u64 size;
+	char *handle = NULL;
+	int create = 0;
+	const char *p = arg;
+	char *next;
+	int base = 10;
+	int verbose = 0;
+
+	const int skip_pci = strlen("pci:");
+	if (verbose)
+		pr_info("shmem_parser(%p,%s,%d)", opt, arg, unset);
+	/* parse out optional addr family */
+	if (strcasestr(p, "pci:")) {
+		p += skip_pci;
+	} else if (strcasestr(p, "mem:")) {
+		die("I can't add to E820 map yet.\n");
+	}
+	/* parse out physical addr */
+	base = 10;
+	if (strcasestr(p, "0x"))
+		base = 16;
+	phys_addr = strtoll(p, &next, base);
+	if (next == p && phys_addr == 0) {
+		pr_info("shmem: no physical addr specified, using default.");
+		phys_addr = default_phys_addr;
+	}
+	if (*next != ':' && *next != '\0')
+		die("shmem: unexpected chars after phys addr.\n");
+	if (*next == '\0')
+		p = next;
+	else
+		p = next + 1;
+	/* parse out size */
+	base = 10;
+	if (strcasestr(p, "0x"))
+		base = 16;
+	size = strtoll(p, &next, base);
+	if (next == p && size == 0) {
+		pr_info("shmem: no size specified, using default.");
+		size = default_size;
+	}
+	/* look for [KMGkmg][Bb]*  uses base 2. */
+	int skip_B = 0;
+	if (strspn(next, "KMGkmg")) {	/* might have a prefix */
+		if (*(next + 1) == 'B' || *(next + 1) == 'b')
+			skip_B = 1;
+		switch (*next) {
+		case 'K':
+		case 'k':
+			size = size << KB_SHIFT;
+			break;
+		case 'M':
+		case 'm':
+			size = size << MB_SHIFT;
+			break;
+		case 'G':
+		case 'g':
+			size = size << GB_SHIFT;
+			break;
+		default:
+			die("shmem: bug in detecting size prefix.");
+			break;
+		}
+		next += 1 + skip_B;
+	}
+	if (*next != ':' && *next != '\0') {
+		die("shmem: unexpected chars after phys size. <%c><%c>\n",
+		    *next, *p);
+	}
+	if (*next == '\0')
+		p = next;
+	else
+		p = next + 1;
+	/* parse out optional shmem handle */
+	const int skip_handle = strlen("handle=");
+	next = strcasestr(p, "handle=");
+	if (*p && next) {
+		if (p != next)
+			die("unexpected chars before handle\n");
+		p += skip_handle;
+		next = strchrnul(p, ':');
+		if (next - p) {
+			handle = malloc(next - p + 1);
+			strncpy(handle, p, next - p);
+			handle[next - p] = '\0';	/* just in case. */
+		}
+		if (*next == '\0')
+			p = next;
+		else
+			p = next + 1;
+	}
+	/* parse optional create flag to see if we should create shm seg. */
+	if (*p && strcasestr(p, "create")) {
+		create = 1;
+		p += strlen("create");
+	}
+	if (*p != '\0')
+		die("shmem: unexpected trailing chars\n");
+	if (handle == NULL) {
+		handle = malloc(strlen(default_handle) + 1);
+		strcpy(handle, default_handle);
+	}
+	if (verbose) {
+		pr_info("shmem: phys_addr = %llx", phys_addr);
+		pr_info("shmem: size      = %llx", size);
+		pr_info("shmem: handle    = %s", handle);
+		pr_info("shmem: create    = %d", create);
+	}
+
+	si->phys_addr = phys_addr;
+	si->size = size;
+	si->handle = handle;
+	si->create = create;
+	pci_shmem__register_mem(si);	/* ownership of si, etc. passed on. */
+	return 0;
+}
+
+static const struct option options[] = {
+	OPT_GROUP("Basic options:"),
+	OPT_STRING('\0', "name", &guest_name, "guest name",
+			"A name for the guest"),
+	OPT_INTEGER('c', "cpus", &nrcpus, "Number of CPUs"),
+	OPT_U64('m', "mem", &ram_size, "Virtual machine memory size in MiB."),
+	OPT_CALLBACK('\0', "shmem", NULL,
+		     "[pci:]<addr>:<size>[:handle=<handle>][:create]",
+		     "Share host shmem with guest via pci device",
+		     shmem_parser),
+	OPT_CALLBACK('d', "disk", NULL, "image or rootfs_dir", "Disk image or rootfs directory", img_name_parser),
+	OPT_BOOLEAN('\0', "balloon", &balloon, "Enable virtio balloon"),
+	OPT_BOOLEAN('\0', "vnc", &vnc, "Enable VNC framebuffer"),
+	OPT_BOOLEAN('\0', "sdl", &sdl, "Enable SDL framebuffer"),
+	OPT_BOOLEAN('\0', "rng", &virtio_rng, "Enable virtio Random Number Generator"),
+	OPT_CALLBACK('\0', "9p", NULL, "dir_to_share,tag_name",
+		     "Enable virtio 9p to share files between host and guest", virtio_9p_rootdir_parser),
+	OPT_STRING('\0', "console", &console, "serial, virtio or hv",
+			"Console to use"),
+	OPT_STRING('\0', "dev", &dev, "device_file", "KVM device file"),
+	OPT_CALLBACK('\0', "tty", NULL, "tty id",
+		     "Remap guest TTY into a pty on the host",
+		     tty_parser),
+	OPT_STRING('\0', "sandbox", &sandbox, "script",
+			"Run this script when booting into custom rootfs"),
+	OPT_STRING('\0', "hugetlbfs", &hugetlbfs_path, "path", "Hugetlbfs path"),
+
+	OPT_GROUP("Kernel options:"),
+	OPT_STRING('k', "kernel", &kernel_filename, "kernel",
+			"Kernel to boot in virtual machine"),
+	OPT_STRING('i', "initrd", &initrd_filename, "initrd",
+			"Initial RAM disk image"),
+	OPT_STRING('p', "params", &kernel_cmdline, "params",
+			"Kernel command line arguments"),
+
+	OPT_GROUP("Networking options:"),
+	OPT_CALLBACK_DEFAULT('n', "network", NULL, "network params",
+		     "Create a new guest NIC",
+		     netdev_parser, NULL),
+	OPT_BOOLEAN('\0', "no-dhcp", &no_dhcp, "Disable kernel DHCP in rootfs mode"),
+
+	OPT_GROUP("BIOS options:"),
+	OPT_INTEGER('\0', "vidmode", &vidmode,
+		    "Video mode"),
+
+	OPT_GROUP("Debug options:"),
+	OPT_BOOLEAN('\0', "debug", &do_debug_print,
+			"Enable debug messages"),
+	OPT_BOOLEAN('\0', "debug-single-step", &single_step,
+			"Enable single stepping"),
+	OPT_BOOLEAN('\0', "debug-ioport", &ioport_debug,
+			"Enable ioport debugging"),
+	OPT_INTEGER('\0', "debug-iodelay", &debug_iodelay,
+			"Delay IO by millisecond"),
+	OPT_END()
+};
+
+/*
+ * Serialize debug printout so that the output of multiple vcpus does not
+ * get mixed up:
+ */
+static int printout_done;
+
+static void handle_sigusr1(int sig)
+{
+	struct kvm_cpu *cpu = current_kvm_cpu;
+	int fd = kvm_cpu__get_debug_fd();
+
+	if (!cpu || cpu->needs_nmi)
+		return;
+
+	dprintf(fd, "\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id);
+	kvm_cpu__show_registers(cpu);
+	kvm_cpu__show_code(cpu);
+	kvm_cpu__show_page_tables(cpu);
+	fflush(stdout);
+	printout_done = 1;
+	mb();
+}
+
+/* Pause/resume the guest using SIGUSR2 */
+static int is_paused;
+
+static void handle_pause(int fd, u32 type, u32 len, u8 *msg)
+{
+	if (WARN_ON(len))
+		return;
+
+	if (type == KVM_IPC_RESUME && is_paused) {
+		kvm->vm_state = KVM_VMSTATE_RUNNING;
+		kvm__continue();
+	} else if (type == KVM_IPC_PAUSE && !is_paused) {
+		kvm->vm_state = KVM_VMSTATE_PAUSED;
+		kvm__pause();
+	} else {
+		return;
+	}
+
+	is_paused = !is_paused;
+}
+
+static void handle_vmstate(int fd, u32 type, u32 len, u8 *msg)
+{
+	int r = 0;
+
+	if (type == KVM_IPC_VMSTATE)
+		r = write(fd, &kvm->vm_state, sizeof(kvm->vm_state));
+
+	if (r < 0)
+		pr_warning("Failed sending VMSTATE");
+}
+
+static void handle_debug(int fd, u32 type, u32 len, u8 *msg)
+{
+	int i;
+	struct debug_cmd_params *params;
+	u32 dbg_type;
+	u32 vcpu;
+
+	if (WARN_ON(type != KVM_IPC_DEBUG || len != sizeof(*params)))
+		return;
+
+	params = (void *)msg;
+	dbg_type = params->dbg_type;
+	vcpu = params->cpu;
+
+	if (dbg_type & KVM_DEBUG_CMD_TYPE_NMI) {
+		if ((int)vcpu >= kvm->nrcpus)
+			return;
+
+		kvm_cpus[vcpu]->needs_nmi = 1;
+		pthread_kill(kvm_cpus[vcpu]->thread, SIGUSR1);
+	}
+
+	if (!(dbg_type & KVM_DEBUG_CMD_TYPE_DUMP))
+		return;
+
+	for (i = 0; i < nrcpus; i++) {
+		struct kvm_cpu *cpu = kvm_cpus[i];
+
+		if (!cpu)
+			continue;
+
+		printout_done = 0;
+
+		kvm_cpu__set_debug_fd(fd);
+		pthread_kill(cpu->thread, SIGUSR1);
+		/*
+		 * Wait for the vCPU to dump state before signalling
+		 * the next thread. Since this is debug code it does
+		 * not matter that we are burning CPU time a bit:
+		 */
+		while (!printout_done)
+			mb();
+	}
+
+	close(fd);
+
+	serial8250__inject_sysrq(kvm);
+}
+
+static void handle_sigalrm(int sig)
+{
+	kvm__arch_periodic_poll(kvm);
+}
+
+static void handle_stop(int fd, u32 type, u32 len, u8 *msg)
+{
+	if (WARN_ON(type != KVM_IPC_STOP || len))
+		return;
+
+	kvm_cpu__reboot();
+}
+
+static void *kvm_cpu_thread(void *arg)
+{
+	current_kvm_cpu		= arg;
+
+	if (kvm_cpu__start(current_kvm_cpu))
+		goto panic_kvm;
+
+	return (void *) (intptr_t) 0;
+
+panic_kvm:
+	fprintf(stderr, "KVM exit reason: %u (\"%s\")\n",
+		current_kvm_cpu->kvm_run->exit_reason,
+		kvm_exit_reasons[current_kvm_cpu->kvm_run->exit_reason]);
+	if (current_kvm_cpu->kvm_run->exit_reason == KVM_EXIT_UNKNOWN)
+		fprintf(stderr, "KVM exit code: 0x%Lu\n",
+			current_kvm_cpu->kvm_run->hw.hardware_exit_reason);
+
+	kvm_cpu__set_debug_fd(STDOUT_FILENO);
+	kvm_cpu__show_registers(current_kvm_cpu);
+	kvm_cpu__show_code(current_kvm_cpu);
+	kvm_cpu__show_page_tables(current_kvm_cpu);
+
+	return (void *) (intptr_t) 1;
+}
+
+static char kernel[PATH_MAX];
+
+static const char *host_kernels[] = {
+	"/boot/vmlinuz",
+	"/boot/bzImage",
+	NULL
+};
+
+static const char *default_kernels[] = {
+	"./bzImage",
+	"arch/" BUILD_ARCH "/boot/bzImage",
+	"../../arch/" BUILD_ARCH "/boot/bzImage",
+	NULL
+};
+
+static const char *default_vmlinux[] = {
+	"vmlinux",
+	"../../../vmlinux",
+	"../../vmlinux",
+	NULL
+};
+
+static void kernel_usage_with_options(void)
+{
+	const char **k;
+	struct utsname uts;
+
+	fprintf(stderr, "Fatal: could not find default kernel image in:\n");
+	k = &default_kernels[0];
+	while (*k) {
+		fprintf(stderr, "\t%s\n", *k);
+		k++;
+	}
+
+	if (uname(&uts) < 0)
+		return;
+
+	k = &host_kernels[0];
+	while (*k) {
+		if (snprintf(kernel, PATH_MAX, "%s-%s", *k, uts.release) < 0)
+			return;
+		fprintf(stderr, "\t%s\n", kernel);
+		k++;
+	}
+	fprintf(stderr, "\nPlease see '%s run --help' for more options.\n\n",
+		KVM_BINARY_NAME);
+}
+
+static u64 host_ram_size(void)
+{
+	long page_size;
+	long nr_pages;
+
+	nr_pages	= sysconf(_SC_PHYS_PAGES);
+	if (nr_pages < 0) {
+		pr_warning("sysconf(_SC_PHYS_PAGES) failed");
+		return 0;
+	}
+
+	page_size	= sysconf(_SC_PAGE_SIZE);
+	if (page_size < 0) {
+		pr_warning("sysconf(_SC_PAGE_SIZE) failed");
+		return 0;
+	}
+
+	return (nr_pages * page_size) >> MB_SHIFT;
+}
+
+/*
+ * If user didn't specify how much memory it wants to allocate for the guest,
+ * avoid filling the whole host RAM.
+ */
+#define RAM_SIZE_RATIO		0.8
+
+static u64 get_ram_size(int nr_cpus)
+{
+	u64 available;
+	u64 ram_size;
+
+	ram_size	= 64 * (nr_cpus + 3);
+
+	available	= host_ram_size() * RAM_SIZE_RATIO;
+	if (!available)
+		available = MIN_RAM_SIZE_MB;
+
+	if (ram_size > available)
+		ram_size	= available;
+
+	return ram_size;
+}
+
+static const char *find_kernel(void)
+{
+	const char **k;
+	struct stat st;
+	struct utsname uts;
+
+	k = &default_kernels[0];
+	while (*k) {
+		if (stat(*k, &st) < 0 || !S_ISREG(st.st_mode)) {
+			k++;
+			continue;
+		}
+		strncpy(kernel, *k, PATH_MAX);
+		return kernel;
+	}
+
+	if (uname(&uts) < 0)
+		return NULL;
+
+	k = &host_kernels[0];
+	while (*k) {
+		if (snprintf(kernel, PATH_MAX, "%s-%s", *k, uts.release) < 0)
+			return NULL;
+
+		if (stat(kernel, &st) < 0 || !S_ISREG(st.st_mode)) {
+			k++;
+			continue;
+		}
+		return kernel;
+
+	}
+	return NULL;
+}
+
+static const char *find_vmlinux(void)
+{
+	const char **vmlinux;
+
+	vmlinux = &default_vmlinux[0];
+	while (*vmlinux) {
+		struct stat st;
+
+		if (stat(*vmlinux, &st) < 0 || !S_ISREG(st.st_mode)) {
+			vmlinux++;
+			continue;
+		}
+		return *vmlinux;
+	}
+	return NULL;
+}
+
+void kvm_run_help(void)
+{
+	usage_with_options(run_usage, options);
+}
+
+static int kvm_custom_stage2(void)
+{
+	char tmp[PATH_MAX], dst[PATH_MAX], *src;
+	const char *rootfs = custom_rootfs_name;
+	int r;
+
+	src = realpath("guest/init_stage2", NULL);
+	if (src == NULL)
+		return -ENOMEM;
+
+	snprintf(tmp, PATH_MAX, "%s%s/virt/init_stage2", kvm__get_dir(), rootfs);
+	remove(tmp);
+
+	snprintf(dst, PATH_MAX, "/host/%s", src);
+	r = symlink(dst, tmp);
+	free(src);
+
+	return r;
+}
+
+static int kvm_run_set_sandbox(void)
+{
+	const char *guestfs_name = custom_rootfs_name;
+	char path[PATH_MAX], script[PATH_MAX], *tmp;
+
+	snprintf(path, PATH_MAX, "%s%s/virt/sandbox.sh", kvm__get_dir(), guestfs_name);
+
+	remove(path);
+
+	if (sandbox == NULL)
+		return 0;
+
+	tmp = realpath(sandbox, NULL);
+	if (tmp == NULL)
+		return -ENOMEM;
+
+	snprintf(script, PATH_MAX, "/host/%s", tmp);
+	free(tmp);
+
+	return symlink(script, path);
+}
+
+static void kvm_write_sandbox_cmd_exactly(int fd, const char *arg)
+{
+	const char *single_quote;
+
+	if (!*arg) { /* zero length string */
+		if (write(fd, "''", 2) <= 0)
+			die("Failed writing sandbox script");
+		return;
+	}
+
+	while (*arg) {
+		single_quote = strchrnul(arg, '\'');
+
+		/* write non-single-quote string as #('string') */
+		if (arg != single_quote) {
+			if (write(fd, "'", 1) <= 0 ||
+			    write(fd, arg, single_quote - arg) <= 0 ||
+			    write(fd, "'", 1) <= 0)
+				die("Failed writing sandbox script");
+		}
+
+		/* write single quote as #("'") */
+		if (*single_quote) {
+			if (write(fd, "\"'\"", 3) <= 0)
+				die("Failed writing sandbox script");
+		} else
+			break;
+
+		arg = single_quote + 1;
+	}
+}
+
+static void kvm_run_write_sandbox_cmd(const char **argv, int argc)
+{
+	const char script_hdr[] = "#! /bin/bash\n\n";
+	int fd;
+
+	remove(sandbox);
+
+	fd = open(sandbox, O_RDWR | O_CREAT, 0777);
+	if (fd < 0)
+		die("Failed creating sandbox script");
+
+	if (write(fd, script_hdr, sizeof(script_hdr) - 1) <= 0)
+		die("Failed writing sandbox script");
+
+	while (argc) {
+		kvm_write_sandbox_cmd_exactly(fd, argv[0]);
+		if (argc - 1)
+			if (write(fd, " ", 1) <= 0)
+				die("Failed writing sandbox script");
+		argv++;
+		argc--;
+	}
+	if (write(fd, "\n", 1) <= 0)
+		die("Failed writing sandbox script");
+
+	close(fd);
+}
+
+static int kvm_cmd_run_init(int argc, const char **argv)
+{
+	static char real_cmdline[2048], default_name[20];
+	struct framebuffer *fb = NULL;
+	unsigned int nr_online_cpus;
+	int max_cpus, recommended_cpus;
+	int i, r;
+
+	signal(SIGALRM, handle_sigalrm);
+	kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug);
+	signal(SIGUSR1, handle_sigusr1);
+	kvm_ipc__register_handler(KVM_IPC_PAUSE, handle_pause);
+	kvm_ipc__register_handler(KVM_IPC_RESUME, handle_pause);
+	kvm_ipc__register_handler(KVM_IPC_STOP, handle_stop);
+	kvm_ipc__register_handler(KVM_IPC_VMSTATE, handle_vmstate);
+
+	nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+
+	while (argc != 0) {
+		argc = parse_options(argc, argv, options, run_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION |
+				PARSE_OPT_KEEP_DASHDASH);
+		if (argc != 0) {
+			/* Cusrom options, should have been handled elsewhere */
+			if (strcmp(argv[0], "--") == 0) {
+				if (kvm_run_wrapper == KVM_RUN_SANDBOX) {
+					sandbox = DEFAULT_SANDBOX_FILENAME;
+					kvm_run_write_sandbox_cmd(argv+1, argc-1);
+					break;
+				}
+			}
+
+			if ((kvm_run_wrapper == KVM_RUN_DEFAULT && kernel_filename) ||
+				(kvm_run_wrapper == KVM_RUN_SANDBOX && sandbox)) {
+				fprintf(stderr, "Cannot handle parameter: "
+						"%s\n", argv[0]);
+				usage_with_options(run_usage, options);
+				return EINVAL;
+			}
+			if (kvm_run_wrapper == KVM_RUN_SANDBOX) {
+				/*
+				 * first unhandled parameter is treated as
+				 * sandbox command
+				 */
+				sandbox = DEFAULT_SANDBOX_FILENAME;
+				kvm_run_write_sandbox_cmd(argv, argc);
+			} else {
+				/*
+				 * first unhandled parameter is treated as a kernel
+				 * image
+				 */
+				kernel_filename = argv[0];
+			}
+			argv++;
+			argc--;
+		}
+
+	}
+
+	if (!kernel_filename)
+		kernel_filename = find_kernel();
+
+	if (!kernel_filename) {
+		kernel_usage_with_options();
+		return EINVAL;
+	}
+
+	vmlinux_filename = find_vmlinux();
+
+	if (nrcpus == 0)
+		nrcpus = nr_online_cpus;
+
+	if (!ram_size)
+		ram_size	= get_ram_size(nrcpus);
+
+	if (ram_size < MIN_RAM_SIZE_MB)
+		die("Not enough memory specified: %lluMB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB);
+
+	if (ram_size > host_ram_size())
+		pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB", ram_size, host_ram_size());
+
+	ram_size <<= MB_SHIFT;
+
+	if (!dev)
+		dev = DEFAULT_KVM_DEV;
+
+	if (!console)
+		console = DEFAULT_CONSOLE;
+
+	if (!strncmp(console, "virtio", 6))
+		active_console  = CONSOLE_VIRTIO;
+	else if (!strncmp(console, "serial", 6))
+		active_console  = CONSOLE_8250;
+	else if (!strncmp(console, "hv", 2))
+		active_console = CONSOLE_HV;
+	else
+		pr_warning("No console!");
+
+	if (!host_ip)
+		host_ip = DEFAULT_HOST_ADDR;
+
+	if (!guest_ip)
+		guest_ip = DEFAULT_GUEST_ADDR;
+
+	if (!guest_mac)
+		guest_mac = DEFAULT_GUEST_MAC;
+
+	if (!host_mac)
+		host_mac = DEFAULT_HOST_MAC;
+
+	if (!script)
+		script = DEFAULT_SCRIPT;
+
+	term_init();
+
+	if (!guest_name) {
+		if (custom_rootfs) {
+			guest_name = custom_rootfs_name;
+		} else {
+			sprintf(default_name, "guest-%u", getpid());
+			guest_name = default_name;
+		}
+	}
+
+	kvm = kvm__init(dev, hugetlbfs_path, ram_size, guest_name);
+	if (IS_ERR(kvm)) {
+		r = PTR_ERR(kvm);
+		goto fail;
+	}
+
+	kvm->single_step = single_step;
+
+	r = ioeventfd__init(kvm);
+	if (r < 0) {
+		pr_err("ioeventfd__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	max_cpus = kvm__max_cpus(kvm);
+	recommended_cpus = kvm__recommended_cpus(kvm);
+
+	if (nrcpus > max_cpus) {
+		printf("  # Limit the number of CPUs to %d\n", max_cpus);
+		nrcpus = max_cpus;
+	} else if (nrcpus > recommended_cpus) {
+		printf("  # Warning: The maximum recommended amount of VCPUs"
+			" is %d\n", recommended_cpus);
+	}
+
+	kvm->nrcpus = nrcpus;
+
+	/* Alloc one pointer too many, so array ends up 0-terminated */
+	kvm_cpus = calloc(nrcpus + 1, sizeof(void *));
+	if (!kvm_cpus)
+		die("Couldn't allocate array for %d CPUs", nrcpus);
+
+	r = irq__init(kvm);
+	if (r < 0) {
+		pr_err("irq__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	r = pci__init(kvm);
+	if (r < 0) {
+		pr_err("pci__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	r = ioport__init(kvm);
+	if (r < 0) {
+		pr_err("ioport__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	/*
+	 * vidmode should be either specified
+	 * either set by default
+	 */
+	if (vnc || sdl) {
+		if (vidmode == -1)
+			vidmode = 0x312;
+	} else {
+		vidmode = 0;
+	}
+
+	memset(real_cmdline, 0, sizeof(real_cmdline));
+	kvm__arch_set_cmdline(real_cmdline, vnc || sdl);
+
+	if (strlen(real_cmdline) > 0)
+		strcat(real_cmdline, " ");
+
+	if (kernel_cmdline)
+		strlcat(real_cmdline, kernel_cmdline, sizeof(real_cmdline));
+
+	if (!using_rootfs && !image_filename[0] && !initrd_filename) {
+		char tmp[PATH_MAX];
+
+		kvm_setup_create_new(custom_rootfs_name);
+		kvm_setup_resolv(custom_rootfs_name);
+
+		snprintf(tmp, PATH_MAX, "%s%s", kvm__get_dir(), "default");
+		if (virtio_9p__register(kvm, tmp, "/dev/root") < 0)
+			die("Unable to initialize virtio 9p");
+		if (virtio_9p__register(kvm, "/", "hostfs") < 0)
+			die("Unable to initialize virtio 9p");
+		using_rootfs = custom_rootfs = 1;
+	}
+
+	if (using_rootfs) {
+		strcat(real_cmdline, " root=/dev/root rw rootflags=rw,trans=virtio,version=9p2000.L rootfstype=9p");
+		if (custom_rootfs) {
+			kvm_run_set_sandbox();
+
+			strcat(real_cmdline, " init=/virt/init");
+
+			if (!no_dhcp)
+				strcat(real_cmdline, "  ip=dhcp");
+			if (kvm_custom_stage2())
+				die("Failed linking stage 2 of init.");
+		}
+	} else if (!strstr(real_cmdline, "root=")) {
+		strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline));
+	}
+
+	if (image_count) {
+		kvm->nr_disks = image_count;
+		kvm->disks = disk_image__open_all(image_filename, readonly_image, image_count);
+		if (IS_ERR(kvm->disks)) {
+			r = PTR_ERR(kvm->disks);
+			pr_err("disk_image__open_all() failed with error %ld\n",
+					PTR_ERR(kvm->disks));
+			goto fail;
+		}
+	}
+
+	printf("  # %s run -k %s -m %Lu -c %d --name %s\n", KVM_BINARY_NAME,
+		kernel_filename, ram_size / 1024 / 1024, nrcpus, guest_name);
+
+	if (!kvm__load_kernel(kvm, kernel_filename, initrd_filename,
+				real_cmdline, vidmode))
+		die("unable to load kernel %s", kernel_filename);
+
+	kvm->vmlinux = vmlinux_filename;
+	r = symbol_init(kvm);
+	if (r < 0)
+		pr_debug("symbol_init() failed with error %d\n", r);
+
+	ioport__setup_arch();
+
+	r = rtc__init(kvm);
+	if (r < 0) {
+		pr_err("rtc__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	r = serial8250__init(kvm);
+	if (r < 0) {
+		pr_err("serial__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	r = virtio_blk__init(kvm);
+	if (r < 0) {
+		pr_err("virtio_blk__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	if (active_console == CONSOLE_VIRTIO)
+		virtio_console__init(kvm);
+
+	if (virtio_rng)
+		virtio_rng__init(kvm);
+
+	if (balloon)
+		virtio_bln__init(kvm);
+
+	if (!network)
+		network = DEFAULT_NETWORK;
+
+	virtio_9p__init(kvm);
+
+	for (i = 0; i < num_net_devices; i++) {
+		net_params[i].kvm = kvm;
+		virtio_net__init(&net_params[i]);
+	}
+
+	if (num_net_devices == 0 && no_net == 0) {
+		struct virtio_net_params net_params;
+
+		net_params = (struct virtio_net_params) {
+			.guest_ip	= guest_ip,
+			.host_ip	= host_ip,
+			.kvm		= kvm,
+			.script		= script,
+			.mode		= NET_MODE_USER,
+		};
+		str_to_mac(guest_mac, net_params.guest_mac);
+		str_to_mac(host_mac, net_params.host_mac);
+
+		virtio_net__init(&net_params);
+	}
+
+	kvm__init_ram(kvm);
+
+#ifdef CONFIG_X86
+	kbd__init(kvm);
+#endif
+
+	pci_shmem__init(kvm);
+
+	if (vnc || sdl) {
+		fb = vesa__init(kvm);
+		if (IS_ERR(fb)) {
+			pr_err("vesa__init() failed with error %ld\n", PTR_ERR(fb));
+			goto fail;
+		}
+	}
+
+	if (vnc && fb) {
+		r = vnc__init(fb);
+		if (r < 0) {
+			pr_err("vnc__init() failed with error %d\n", r);
+			goto fail;
+		}
+	}
+
+	if (sdl && fb) {
+		sdl__init(fb);
+		if (r < 0) {
+			pr_err("sdl__init() failed with error %d\n", r);
+			goto fail;
+		}
+	}
+
+	r = fb__start();
+	if (r < 0) {
+		pr_err("fb__init() failed with error %d\n", r);
+		goto fail;
+	}
+
+	/* Device init all done; firmware init must
+	 * come after this (it may set up device trees etc.)
+	 */
+
+	kvm__start_timer(kvm);
+
+	kvm__arch_setup_firmware(kvm);
+	if (r < 0) {
+		pr_err("kvm__arch_setup_firmware() failed with error %d\n", r);
+		goto fail;
+	}
+
+	for (i = 0; i < nrcpus; i++) {
+		kvm_cpus[i] = kvm_cpu__init(kvm, i);
+		if (!kvm_cpus[i])
+			die("unable to initialize KVM VCPU");
+	}
+
+	thread_pool__init(nr_online_cpus);
+fail:
+	return r;
+}
+
+static int kvm_cmd_run_work(void)
+{
+	int i, r = -1;
+	void *ret = NULL;
+
+	for (i = 0; i < nrcpus; i++) {
+		if (pthread_create(&kvm_cpus[i]->thread, NULL, kvm_cpu_thread, kvm_cpus[i]) != 0)
+			die("unable to create KVM VCPU thread");
+	}
+
+	/* Only VCPU #0 is going to exit by itself when shutting down */
+	if (pthread_join(kvm_cpus[0]->thread, &ret) != 0)
+		r = 0;
+
+	kvm_cpu__delete(kvm_cpus[0]);
+	kvm_cpus[0] = NULL;
+
+	for (i = 1; i < nrcpus; i++) {
+		if (kvm_cpus[i]->is_running) {
+			pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT);
+			if (pthread_join(kvm_cpus[i]->thread, &ret) != 0)
+				die("pthread_join");
+			kvm_cpu__delete(kvm_cpus[i]);
+		}
+		if (ret == NULL)
+			r = 0;
+	}
+
+	return r;
+}
+
+static void kvm_cmd_run_exit(int guest_ret)
+{
+	int r = 0;
+
+	compat__print_all_messages();
+
+	r = symbol_exit(kvm);
+	if (r < 0)
+		pr_warning("symbol_exit() failed with error %d\n", r);
+
+	r = irq__exit(kvm);
+	if (r < 0)
+		pr_warning("irq__exit() failed with error %d\n", r);
+
+	fb__stop();
+
+	r = virtio_blk__exit(kvm);
+	if (r < 0)
+		pr_warning("virtio_blk__exit() failed with error %d\n", r);
+
+	r = virtio_rng__exit(kvm);
+	if (r < 0)
+		pr_warning("virtio_rng__exit() failed with error %d\n", r);
+
+	r = disk_image__close_all(kvm->disks, image_count);
+	if (r < 0)
+		pr_warning("disk_image__close_all() failed with error %d\n", r);
+
+	r = serial8250__exit(kvm);
+	if (r < 0)
+		pr_warning("serial8250__exit() failed with error %d\n", r);
+
+	r = rtc__exit(kvm);
+	if (r < 0)
+		pr_warning("rtc__exit() failed with error %d\n", r);
+
+	r = kvm__arch_free_firmware(kvm);
+	if (r < 0)
+		pr_warning("kvm__arch_free_firmware() failed with error %d\n", r);
+
+	r = ioport__exit(kvm);
+	if (r < 0)
+		pr_warning("ioport__exit() failed with error %d\n", r);
+
+	r = ioeventfd__exit(kvm);
+	if (r < 0)
+		pr_warning("ioeventfd__exit() failed with error %d\n", r);
+
+	r = pci__exit(kvm);
+	if (r < 0)
+		pr_warning("pci__exit() failed with error %d\n", r);
+
+	r = kvm__exit(kvm);
+	if (r < 0)
+		pr_warning("pci__exit() failed with error %d\n", r);
+
+	free(kvm_cpus);
+
+	if (guest_ret == 0)
+		printf("\n  # KVM session ended normally.\n");
+}
+
+int kvm_cmd_run(int argc, const char **argv, const char *prefix)
+{
+	int r, ret = -EFAULT;
+
+	r = kvm_cmd_run_init(argc, argv);
+	if (r < 0)
+		return r;
+
+	ret = kvm_cmd_run_work();
+	kvm_cmd_run_exit(ret);
+
+	return ret;
+}
diff --git a/tools/kvm/builtin-sandbox.c b/tools/kvm/builtin-sandbox.c
new file mode 100644
index 0000000..433f536
--- /dev/null
+++ b/tools/kvm/builtin-sandbox.c
@@ -0,0 +1,9 @@
+#include "kvm/builtin-sandbox.h"
+#include "kvm/builtin-run.h"
+
+int kvm_cmd_sandbox(int argc, const char **argv, const char *prefix)
+{
+	kvm_run_set_wrapper_sandbox();
+
+	return kvm_cmd_run(argc, argv, prefix);
+}
diff --git a/tools/kvm/builtin-setup.c b/tools/kvm/builtin-setup.c
new file mode 100644
index 0000000..232aa60
--- /dev/null
+++ b/tools/kvm/builtin-setup.c
@@ -0,0 +1,232 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-setup.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+static const char *instance_name;
+
+static const char * const setup_usage[] = {
+	"lkvm setup [name]",
+	NULL
+};
+
+static const struct option setup_options[] = {
+	OPT_END()
+};
+
+static void parse_setup_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, setup_options, setup_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0 && instance_name)
+			kvm_setup_help();
+		else
+			instance_name = argv[0];
+		argv++;
+		argc--;
+	}
+}
+
+void kvm_setup_help(void)
+{
+	printf("\n%s setup creates a new rootfs under %s.\n"
+		"This can be used later by the '-d' parameter of '%s run'.\n",
+		KVM_BINARY_NAME, kvm__get_dir(), KVM_BINARY_NAME);
+	usage_with_options(setup_usage, setup_options);
+}
+
+static int copy_file(const char *from, const char *to)
+{
+	int in_fd, out_fd;
+	void *src, *dst;
+	struct stat st;
+	int err = -1;
+
+	in_fd = open(from, O_RDONLY);
+	if (in_fd < 0)
+		return err;
+
+	if (fstat(in_fd, &st) < 0)
+		goto error_close_in;
+
+	out_fd = open(to, O_RDWR | O_CREAT | O_TRUNC, st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
+	if (out_fd < 0)
+		goto error_close_in;
+
+	src = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, in_fd, 0);
+	if (src == MAP_FAILED)
+		goto error_close_out;
+
+	if (ftruncate(out_fd, st.st_size) < 0)
+		goto error_munmap_src;
+
+	dst = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, out_fd, 0);
+	if (dst == MAP_FAILED)
+		goto error_munmap_src;
+
+	memcpy(dst, src, st.st_size);
+
+	if (fsync(out_fd) < 0)
+		goto error_munmap_dst;
+
+	err = 0;
+
+error_munmap_dst:
+	munmap(dst, st.st_size);
+error_munmap_src:
+	munmap(src, st.st_size);
+error_close_out:
+	close(out_fd);
+error_close_in:
+	close(in_fd);
+
+	return err;
+}
+
+static const char *guestfs_dirs[] = {
+	"/dev",
+	"/etc",
+	"/home",
+	"/host",
+	"/proc",
+	"/root",
+	"/sys",
+	"/tmp",
+	"/var",
+	"/var/lib",
+	"/virt",
+};
+
+static const char *guestfs_symlinks[] = {
+	"/bin",
+	"/lib",
+	"/lib64",
+	"/sbin",
+	"/usr",
+	"/etc/ld.so.conf",
+};
+
+static int copy_init(const char *guestfs_name)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "%s%s/virt/init", kvm__get_dir(), guestfs_name);
+
+	return copy_file("guest/init", path);
+}
+
+static int copy_passwd(const char *guestfs_name)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "%s%s/etc/passwd", kvm__get_dir(), guestfs_name);
+
+	return copy_file("guest/passwd", path);
+}
+
+static int make_guestfs_symlink(const char *guestfs_name, const char *path)
+{
+	char target[PATH_MAX];
+	char name[PATH_MAX];
+
+	snprintf(name, PATH_MAX, "%s%s%s", kvm__get_dir(), guestfs_name, path);
+
+	snprintf(target, PATH_MAX, "/host%s", path);
+
+	return symlink(target, name);
+}
+
+static int make_dir(const char *dir)
+{
+	char name[PATH_MAX];
+
+	snprintf(name, PATH_MAX, "%s%s", kvm__get_dir(), dir);
+
+	return mkdir(name, 0777);
+}
+
+static void make_guestfs_dir(const char *guestfs_name, const char *dir)
+{
+	char name[PATH_MAX];
+
+	snprintf(name, PATH_MAX, "%s%s", guestfs_name, dir);
+
+	make_dir(name);
+}
+
+void kvm_setup_resolv(const char *guestfs_name)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "%s%s/etc/resolv.conf", kvm__get_dir(), guestfs_name);
+
+	copy_file("/etc/resolv.conf", path);
+}
+
+static int do_setup(const char *guestfs_name)
+{
+	unsigned int i;
+	int ret;
+
+	ret = make_dir(guestfs_name);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(guestfs_dirs); i++)
+		make_guestfs_dir(guestfs_name, guestfs_dirs[i]);
+
+	for (i = 0; i < ARRAY_SIZE(guestfs_symlinks); i++) {
+		make_guestfs_symlink(guestfs_name, guestfs_symlinks[i]);
+	}
+
+	ret = copy_init(guestfs_name);
+	if (ret < 0)
+		return ret;
+
+	return copy_passwd(guestfs_name);
+}
+
+int kvm_setup_create_new(const char *guestfs_name)
+{
+	return do_setup(guestfs_name);
+}
+
+int kvm_cmd_setup(int argc, const char **argv, const char *prefix)
+{
+	int r;
+
+	parse_setup_options(argc, argv);
+
+	if (instance_name == NULL)
+		kvm_setup_help();
+
+	r = do_setup(instance_name);
+	if (r == 0)
+		printf("A new rootfs '%s' has been created in '%s%s'.\n\n"
+			"You can now start it by running the following command:\n\n"
+			"  %s run -d %s\n",
+			instance_name, kvm__get_dir(), instance_name,
+			KVM_BINARY_NAME,instance_name);
+	else
+		printf("Unable to create rootfs in %s%s: %s\n",
+			kvm__get_dir(), instance_name, strerror(errno));
+
+	return r;
+}
diff --git a/tools/kvm/builtin-stat.c b/tools/kvm/builtin-stat.c
new file mode 100644
index 0000000..ffd72e8
--- /dev/null
+++ b/tools/kvm/builtin-stat.c
@@ -0,0 +1,127 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-stat.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
+
+#include <sys/select.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#include <linux/virtio_balloon.h>
+
+static bool mem;
+static bool all;
+static const char *instance_name;
+
+static const char * const stat_usage[] = {
+	"lkvm stat [command] [--all] [-n name]",
+	NULL
+};
+
+static const struct option stat_options[] = {
+	OPT_GROUP("Commands options:"),
+	OPT_BOOLEAN('m', "memory", &mem, "Display memory statistics"),
+	OPT_GROUP("Instance options:"),
+	OPT_BOOLEAN('a', "all", &all, "All instances"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_END()
+};
+
+static void parse_stat_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, stat_options, stat_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_stat_help();
+	}
+}
+
+void kvm_stat_help(void)
+{
+	usage_with_options(stat_usage, stat_options);
+}
+
+static int do_memstat(const char *name, int sock)
+{
+	struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
+	fd_set fdset;
+	struct timeval t = { .tv_sec = 1 };
+	int r;
+	u8 i;
+
+	FD_ZERO(&fdset);
+	FD_SET(sock, &fdset);
+	r = kvm_ipc__send(sock, KVM_IPC_STAT);
+	if (r < 0)
+		return r;
+
+	r = select(1, &fdset, NULL, NULL, &t);
+	if (r < 0) {
+		pr_err("Could not retrieve mem stats from %s", name);
+		return r;
+	}
+	r = read(sock, &stats, sizeof(stats));
+	if (r < 0)
+		return r;
+
+	printf("\n\n\t*** Guest memory statistics ***\n\n");
+	for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
+		switch (stats[i].tag) {
+		case VIRTIO_BALLOON_S_SWAP_IN:
+			printf("The amount of memory that has been swapped in (in bytes):");
+			break;
+		case VIRTIO_BALLOON_S_SWAP_OUT:
+			printf("The amount of memory that has been swapped out to disk (in bytes):");
+			break;
+		case VIRTIO_BALLOON_S_MAJFLT:
+			printf("The number of major page faults that have occurred:");
+			break;
+		case VIRTIO_BALLOON_S_MINFLT:
+			printf("The number of minor page faults that have occurred:");
+			break;
+		case VIRTIO_BALLOON_S_MEMFREE:
+			printf("The amount of memory not being used for any purpose (in bytes):");
+			break;
+		case VIRTIO_BALLOON_S_MEMTOT:
+			printf("The total amount of memory available (in bytes):");
+			break;
+		}
+		printf("%llu\n", stats[i].val);
+	}
+	printf("\n");
+
+	return 0;
+}
+
+int kvm_cmd_stat(int argc, const char **argv, const char *prefix)
+{
+	int instance;
+	int r = 0;
+
+	parse_stat_options(argc, argv);
+
+	if (!mem)
+		usage_with_options(stat_usage, stat_options);
+
+	if (mem && all)
+		return kvm__enumerate_instances(do_memstat);
+
+	if (instance_name == NULL)
+		kvm_stat_help();
+
+	instance = kvm__get_sock_by_instance(instance_name);
+
+	if (instance <= 0)
+		die("Failed locating instance");
+
+	if (mem)
+		r = do_memstat(instance_name, instance);
+
+	close(instance);
+
+	return r;
+}
diff --git a/tools/kvm/builtin-stop.c b/tools/kvm/builtin-stop.c
new file mode 100644
index 0000000..6067630
--- /dev/null
+++ b/tools/kvm/builtin-stop.c
@@ -0,0 +1,70 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-stop.h>
+#include <kvm/kvm.h>
+#include <kvm/parse-options.h>
+#include <kvm/kvm-ipc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+static bool all;
+static const char *instance_name;
+
+static const char * const stop_usage[] = {
+	"lkvm stop [--all] [-n name]",
+	NULL
+};
+
+static const struct option stop_options[] = {
+	OPT_GROUP("General options:"),
+	OPT_BOOLEAN('a', "all", &all, "Stop all instances"),
+	OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
+	OPT_END()
+};
+
+static void parse_stop_options(int argc, const char **argv)
+{
+	while (argc != 0) {
+		argc = parse_options(argc, argv, stop_options, stop_usage,
+				PARSE_OPT_STOP_AT_NON_OPTION);
+		if (argc != 0)
+			kvm_stop_help();
+	}
+}
+
+void kvm_stop_help(void)
+{
+	usage_with_options(stop_usage, stop_options);
+}
+
+static int do_stop(const char *name, int sock)
+{
+	return kvm_ipc__send(sock, KVM_IPC_STOP);
+}
+
+int kvm_cmd_stop(int argc, const char **argv, const char *prefix)
+{
+	int instance;
+	int r;
+
+	parse_stop_options(argc, argv);
+
+	if (all)
+		return kvm__enumerate_instances(do_stop);
+
+	if (instance_name == NULL)
+		kvm_stop_help();
+
+	instance = kvm__get_sock_by_instance(instance_name);
+
+	if (instance <= 0)
+		die("Failed locating instance");
+
+	r = do_stop(instance_name, instance);
+
+	close(instance);
+
+	return r;
+}
diff --git a/tools/kvm/builtin-version.c b/tools/kvm/builtin-version.c
new file mode 100644
index 0000000..b8bb859
--- /dev/null
+++ b/tools/kvm/builtin-version.c
@@ -0,0 +1,15 @@
+#include <kvm/util.h>
+#include <kvm/kvm-cmd.h>
+#include <kvm/builtin-version.h>
+#include <kvm/kvm.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+int kvm_cmd_version(int argc, const char **argv, const char *prefix)
+{
+	printf("kvm tool %s\n", KVMTOOLS_VERSION);
+
+	return 0;
+}
diff --git a/tools/kvm/code16gcc.h b/tools/kvm/code16gcc.h
new file mode 100644
index 0000000..d93e480
--- /dev/null
+++ b/tools/kvm/code16gcc.h
@@ -0,0 +1,15 @@
+/*
+ * code16gcc.h
+ *
+ * This file is -include'd when compiling 16-bit C code.
+ * Note: this asm() needs to be emitted before gcc emits any code.
+ * Depending on gcc version, this requires -fno-unit-at-a-time or
+ * -fno-toplevel-reorder.
+ *
+ * Hopefully gcc will eventually have a real -m16 option so we can
+ * drop this hack long term.
+ */
+
+#ifndef __ASSEMBLY__
+asm(".code16gcc");
+#endif
diff --git a/tools/kvm/command-list.txt b/tools/kvm/command-list.txt
new file mode 100644
index 0000000..d93597d
--- /dev/null
+++ b/tools/kvm/command-list.txt
@@ -0,0 +1,15 @@
+#
+# List of known perf commands.
+# command name			category [deprecated] [common]
+#
+lkvm-run			mainporcelain common
+lkvm-setup			mainporcelain common
+lkvm-pause			common
+lkvm-resume			common
+lkvm-version			common
+lkvm-list			common
+lkvm-debug			common
+lkvm-balloon			common
+lkvm-stop			common
+lkvm-stat			common
+lkvm-sandbox			common
diff --git a/tools/kvm/config/feature-tests.mak b/tools/kvm/config/feature-tests.mak
new file mode 100644
index 0000000..be9ebc0
--- /dev/null
+++ b/tools/kvm/config/feature-tests.mak
@@ -0,0 +1,168 @@
+define SOURCE_HELLO
+#include <stdio.h>
+int main(void)
+{
+	return puts(\"hi\");
+}
+endef
+
+ifndef NO_DWARF
+define SOURCE_DWARF
+#include <dwarf.h>
+#include <elfutils/libdw.h>
+#include <elfutils/version.h>
+#ifndef _ELFUTILS_PREREQ
+#error
+#endif
+
+int main(void)
+{
+	Dwarf *dbg = dwarf_begin(0, DWARF_C_READ);
+	return (long)dbg;
+}
+endef
+endif
+
+define SOURCE_LIBELF
+#include <libelf.h>
+
+int main(void)
+{
+	Elf *elf = elf_begin(0, ELF_C_READ, 0);
+	return (long)elf;
+}
+endef
+
+define SOURCE_GLIBC
+#include <gnu/libc-version.h>
+
+int main(void)
+{
+	const char *version = gnu_get_libc_version();
+	return (long)version;
+}
+endef
+
+define SOURCE_ELF_MMAP
+#include <libelf.h>
+int main(void)
+{
+	Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0);
+	return (long)elf;
+}
+endef
+
+ifndef NO_NEWT
+define SOURCE_NEWT
+#include <newt.h>
+
+int main(void)
+{
+	newtInit();
+	newtCls();
+	return newtFinished();
+}
+endef
+endif
+
+ifndef NO_LIBPERL
+define SOURCE_PERL_EMBED
+#include <EXTERN.h>
+#include <perl.h>
+
+int main(void)
+{
+perl_alloc();
+return 0;
+}
+endef
+endif
+
+ifndef NO_LIBPYTHON
+define SOURCE_PYTHON_VERSION
+#include <Python.h>
+#if PY_VERSION_HEX >= 0x03000000
+	#error
+#endif
+int main(void){}
+endef
+define SOURCE_PYTHON_EMBED
+#include <Python.h>
+int main(void)
+{
+	Py_Initialize();
+	return 0;
+}
+endef
+endif
+
+define SOURCE_BFD
+#include <bfd.h>
+
+int main(void)
+{
+	bfd_demangle(0, 0, 0);
+	return 0;
+}
+endef
+
+define SOURCE_CPLUS_DEMANGLE
+extern char *cplus_demangle(const char *, int);
+
+int main(void)
+{
+	cplus_demangle(0, 0);
+	return 0;
+}
+endef
+
+define SOURCE_STRLCPY
+#include <stdlib.h>
+extern size_t strlcpy(char *dest, const char *src, size_t size);
+
+int main(void)
+{
+	strlcpy(NULL, NULL, 0);
+	return 0;
+}
+endef
+
+define SOURCE_VNCSERVER
+#include <rfb/rfb.h>
+
+int main(void)
+{
+	rfbIsActive((void *)0);
+	return 0;
+}
+endef
+
+define SOURCE_SDL
+#include <SDL/SDL.h>
+
+int main(void)
+{
+	SDL_Init(SDL_INIT_VIDEO);
+	return 0;
+}
+endef
+
+define SOURCE_ZLIB
+#include <zlib.h>
+
+int main(void)
+{
+	inflateInit2(NULL, 0);
+	return 0;
+}
+endef
+
+define SOURCE_AIO
+#include <libaio.h>
+
+int main(void)
+{
+	io_setup(0, NULL);
+	return 0;
+}
+endef
diff --git a/tools/kvm/config/utilities.mak b/tools/kvm/config/utilities.mak
new file mode 100644
index 0000000..8046182
--- /dev/null
+++ b/tools/kvm/config/utilities.mak
@@ -0,0 +1,188 @@
+# This allows us to work with the newline character:
+define newline
+
+
+endef
+newline := $(newline)
+
+# nl-escape
+#
+# Usage: escape = $(call nl-escape[,escape])
+#
+# This is used as the common way to specify
+# what should replace a newline when escaping
+# newlines; the default is a bizarre string.
+#
+nl-escape = $(or $(1),m822df3020w6a44id34bt574ctac44eb9f4n)
+
+# escape-nl
+#
+# Usage: escaped-text = $(call escape-nl,text[,escape])
+#
+# GNU make's $(shell ...) function converts to a
+# single space each newline character in the output
+# produced during the expansion; this may not be
+# desirable.
+#
+# The only solution is to change each newline into
+# something that won't be converted, so that the
+# information can be recovered later with
+# $(call unescape-nl...)
+#
+escape-nl = $(subst $(newline),$(call nl-escape,$(2)),$(1))
+
+# unescape-nl
+#
+# Usage: text = $(call unescape-nl,escaped-text[,escape])
+#
+# See escape-nl.
+#
+unescape-nl = $(subst $(call nl-escape,$(2)),$(newline),$(1))
+
+# shell-escape-nl
+#
+# Usage: $(shell some-command | $(call shell-escape-nl[,escape]))
+#
+# Use this to escape newlines from within a shell call;
+# the default escape is a bizarre string.
+#
+# NOTE: The escape is used directly as a string constant
+#       in an `awk' program that is delimited by shell
+#       single-quotes, so be wary of the characters
+#       that are chosen.
+#
+define shell-escape-nl
+awk 'NR==1 {t=$$0} NR>1 {t=t "$(nl-escape)" $$0} END {printf t}'
+endef
+
+# shell-unescape-nl
+#
+# Usage: $(shell some-command | $(call shell-unescape-nl[,escape]))
+#
+# Use this to unescape newlines from within a shell call;
+# the default escape is a bizarre string.
+#
+# NOTE: The escape is used directly as an extended regular
+#       expression constant in an `awk' program that is
+#       delimited by shell single-quotes, so be wary
+#       of the characters that are chosen.
+#
+# (The bash shell has a bug where `{gsub(...),...}' is
+#  misinterpreted as a brace expansion; this can be
+#  overcome by putting a space between `{' and `gsub').
+#
+define shell-unescape-nl
+awk 'NR==1 {t=$$0} NR>1 {t=t "\n" $$0} END { gsub(/$(nl-escape)/,"\n",t); printf t }'
+endef
+
+# escape-for-shell-sq
+#
+# Usage: embeddable-text = $(call escape-for-shell-sq,text)
+#
+# This function produces text that is suitable for
+# embedding in a shell string that is delimited by
+# single-quotes.
+#
+escape-for-shell-sq =  $(subst ','\'',$(1))
+
+# shell-sq
+#
+# Usage: single-quoted-and-escaped-text = $(call shell-sq,text)
+#
+shell-sq = '$(escape-for-shell-sq)'
+
+# shell-wordify
+#
+# Usage: wordified-text = $(call shell-wordify,text)
+#
+# For instance:
+#
+#  |define text
+#  |hello
+#  |world
+#  |endef
+#  |
+#  |target:
+#  |	echo $(call shell-wordify,$(text))
+#
+# At least GNU make gets confused by expanding a newline
+# within the context of a command line of a makefile rule
+# (this is in constrast to a `$(shell ...)' function call,
+# which can handle it just fine).
+#
+# This function avoids the problem by producing a string
+# that works as a shell word, regardless of whether or
+# not it contains a newline.
+#
+# If the text to be wordified contains a newline, then
+# an intrictate shell command substitution is constructed
+# to render the text as a single line; when the shell
+# processes the resulting escaped text, it transforms
+# it into the original unescaped text.
+#
+# If the text does not contain a newline, then this function
+# produces the same results as the `$(shell-sq)' function.
+#
+shell-wordify = $(if $(findstring $(newline),$(1)),$(_sw-esc-nl),$(shell-sq))
+define _sw-esc-nl
+"$$(echo $(call escape-nl,$(shell-sq),$(2)) | $(call shell-unescape-nl,$(2)))"
+endef
+
+# is-absolute
+#
+# Usage: bool-value = $(call is-absolute,path)
+#
+is-absolute = $(shell echo $(shell-sq) | grep ^/ -q && echo y)
+
+# lookup
+#
+# Usage: absolute-executable-path-or-empty = $(call lookup,path)
+#
+# (It's necessary to use `sh -c' because GNU make messes up by
+#  trying too hard and getting things wrong).
+#
+lookup = $(call unescape-nl,$(shell sh -c $(_l-sh)))
+_l-sh = $(call shell-sq,command -v $(shell-sq) | $(call shell-escape-nl,))
+
+# is-executable
+#
+# Usage: bool-value = $(call is-executable,path)
+#
+# (It's necessary to use `sh -c' because GNU make messes up by
+#  trying too hard and getting things wrong).
+#
+is-executable = $(call _is-executable-helper,$(shell-sq))
+_is-executable-helper = $(shell sh -c $(_is-executable-sh))
+_is-executable-sh = $(call shell-sq,test -f $(1) -a -x $(1) && echo y)
+
+# get-executable
+#
+# Usage: absolute-executable-path-or-empty = $(call get-executable,path)
+#
+# The goal is to get an absolute path for an executable;
+# the `command -v' is defined by POSIX, but it's not
+# necessarily very portable, so it's only used if
+# relative path resolution is requested, as determined
+# by the presence of a leading `/'.
+#
+get-executable = $(if $(1),$(if $(is-absolute),$(_ge-abspath),$(lookup)))
+_ge-abspath = $(if $(is-executable),$(1))
+
+# get-supplied-or-default-executable
+#
+# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
+#
+define get-executable-or-default
+$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
+endef
+_ge_attempt = $(or $(get-executable),$(_gea_warn),$(call _gea_err,$(2)))
+_gea_warn = $(warning The path '$(1)' is not executable.)
+_gea_err  = $(if $(1),$(error Please set '$(1)' appropriately))
+
+# try-cc
+# Usage: option = $(call try-cc, source-to-build, cc-options)
+try-cc = $(shell sh -c						  \
+	'TMP="$(OUTPUT)$(TMPOUT).$$$$";				  \
+	 echo "$(1)" |						  \
+	 $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \
+	 rm -f "$$TMP"')
diff --git a/tools/kvm/disk/blk.c b/tools/kvm/disk/blk.c
new file mode 100644
index 0000000..72c1722
--- /dev/null
+++ b/tools/kvm/disk/blk.c
@@ -0,0 +1,42 @@
+#include "kvm/disk-image.h"
+
+#include <linux/err.h>
+
+/*
+ * raw image and blk dev are similar, so reuse raw image ops.
+ */
+static struct disk_image_operations blk_dev_ops = {
+	.read_sector		= raw_image__read_sector,
+	.write_sector		= raw_image__write_sector,
+	.close			= raw_image__close,
+};
+
+struct disk_image *blkdev__probe(const char *filename, struct stat *st)
+{
+	u64 size;
+	int fd, r;
+
+	if (!S_ISBLK(st->st_mode))
+		return ERR_PTR(-EINVAL);
+
+	/*
+	 * Be careful! We are opening host block device!
+	 * Open it readonly since we do not want to break user's data on disk.
+	 */
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
+		return ERR_PTR(fd);
+
+	if (ioctl(fd, BLKGETSIZE64, &size) < 0) {
+		r = -errno;
+		close(fd);
+		return ERR_PTR(r);
+	}
+
+	/*
+	 * FIXME: This will not work on 32-bit host because we can not
+	 * mmap large disk. There is not enough virtual address space
+	 * in 32-bit host. However, this works on 64-bit host.
+	 */
+	return disk_image__new(fd, size, &blk_dev_ops, DISK_IMAGE_MMAP);
+}
diff --git a/tools/kvm/disk/core.c b/tools/kvm/disk/core.c
new file mode 100644
index 0000000..ed338e7
--- /dev/null
+++ b/tools/kvm/disk/core.c
@@ -0,0 +1,260 @@
+#include "kvm/disk-image.h"
+#include "kvm/qcow.h"
+#include "kvm/virtio-blk.h"
+
+#include <linux/err.h>
+#include <sys/eventfd.h>
+#include <sys/poll.h>
+
+#define AIO_MAX 32
+
+int debug_iodelay;
+
+#ifdef CONFIG_HAS_AIO
+static void *disk_image__thread(void *param)
+{
+	struct disk_image *disk = param;
+	struct io_event event[AIO_MAX];
+	struct timespec notime = {0};
+	int nr, i;
+	u64 dummy;
+
+	while (read(disk->evt, &dummy, sizeof(dummy)) > 0) {
+		nr = io_getevents(disk->ctx, 1, ARRAY_SIZE(event), event, &notime);
+		for (i = 0; i < nr; i++)
+			disk->disk_req_cb(event[i].data, event[i].res);
+	}
+
+	return NULL;
+}
+#endif
+
+struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int use_mmap)
+{
+	struct disk_image *disk;
+	int r;
+
+	disk = malloc(sizeof *disk);
+	if (!disk)
+		return ERR_PTR(-ENOMEM);
+
+	*disk = (struct disk_image) {
+		.fd	= fd,
+		.size	= size,
+		.ops	= ops,
+	};
+
+	if (use_mmap == DISK_IMAGE_MMAP) {
+		/*
+		 * The write to disk image will be discarded
+		 */
+		disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
+		if (disk->priv == MAP_FAILED) {
+			r = -errno;
+			free(disk);
+			return ERR_PTR(r);
+		}
+	}
+
+#ifdef CONFIG_HAS_AIO
+	if (disk) {
+		pthread_t thread;
+
+		disk->evt = eventfd(0, 0);
+		io_setup(AIO_MAX, &disk->ctx);
+		r = pthread_create(&thread, NULL, disk_image__thread, disk);
+		if (r) {
+			r = -errno;
+			free(disk);
+			return ERR_PTR(r);
+		}
+	}
+#endif
+	return disk;
+}
+
+struct disk_image *disk_image__open(const char *filename, bool readonly)
+{
+	struct disk_image *disk;
+	struct stat st;
+	int fd;
+
+	if (stat(filename, &st) < 0)
+		return ERR_PTR(-errno);
+
+	/* blk device ?*/
+	disk = blkdev__probe(filename, &st);
+	if (!IS_ERR_OR_NULL(disk))
+		return disk;
+
+	fd = open(filename, readonly ? O_RDONLY : O_RDWR);
+	if (fd < 0)
+		return ERR_PTR(fd);
+
+	/* qcow image ?*/
+	disk = qcow_probe(fd, true);
+	if (!IS_ERR_OR_NULL(disk)) {
+		pr_warning("Forcing read-only support for QCOW");
+		return disk;
+	}
+
+	/* raw image ?*/
+	disk = raw_image__probe(fd, &st, readonly);
+	if (!IS_ERR_OR_NULL(disk))
+		return disk;
+
+	if (close(fd) < 0)
+		pr_warning("close() failed");
+
+	return ERR_PTR(-ENOSYS);
+}
+
+struct disk_image **disk_image__open_all(const char **filenames, bool *readonly, int count)
+{
+	struct disk_image **disks;
+	int i;
+	void *err;
+
+	if (!count)
+		return ERR_PTR(-EINVAL);
+	if (count > MAX_DISK_IMAGES)
+		return ERR_PTR(-ENOSPC);
+
+	disks = calloc(count, sizeof(*disks));
+	if (!disks)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < count; i++) {
+		if (!filenames[i])
+			continue;
+
+		disks[i] = disk_image__open(filenames[i], readonly[i]);
+		if (IS_ERR_OR_NULL(disks[i])) {
+			pr_err("Loading disk image '%s' failed", filenames[i]);
+			err = disks[i];
+			goto error;
+		}
+	}
+
+	return disks;
+error:
+	for (i = 0; i < count; i++)
+		if (!IS_ERR_OR_NULL(disks[i]))
+			disk_image__close(disks[i]);
+
+	free(disks);
+	return err;
+}
+
+int disk_image__flush(struct disk_image *disk)
+{
+	if (disk->ops->flush)
+		return disk->ops->flush(disk);
+
+	return fsync(disk->fd);
+}
+
+int disk_image__close(struct disk_image *disk)
+{
+	/* If there was no disk image then there's nothing to do: */
+	if (!disk)
+		return 0;
+
+	if (disk->ops->close)
+		return disk->ops->close(disk);
+
+	if (close(disk->fd) < 0)
+		pr_warning("close() failed");
+
+	free(disk);
+
+	return 0;
+}
+
+int disk_image__close_all(struct disk_image **disks, int count)
+{
+	while (count)
+		disk_image__close(disks[--count]);
+
+	free(disks);
+
+	return 0;
+}
+
+/*
+ * Fill iov with disk data, starting from sector 'sector'.
+ * Return amount of bytes read.
+ */
+ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param)
+{
+	ssize_t total = 0;
+
+	if (debug_iodelay)
+		msleep(debug_iodelay);
+
+	if (disk->ops->read_sector) {
+		total = disk->ops->read_sector(disk, sector, iov, iovcount, param);
+		if (total < 0) {
+			pr_info("disk_image__read error: total=%ld\n", (long)total);
+			return total;
+		}
+	} else {
+		/* Do nothing */
+	}
+
+	if (!disk->async && disk->disk_req_cb)
+		disk->disk_req_cb(param, total);
+
+	return total;
+}
+
+/*
+ * Write iov to disk, starting from sector 'sector'.
+ * Return amount of bytes written.
+ */
+ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param)
+{
+	ssize_t total = 0;
+
+	if (debug_iodelay)
+		msleep(debug_iodelay);
+
+	if (disk->ops->write_sector) {
+		/*
+		 * Try writev based operation first
+		 */
+
+		total = disk->ops->write_sector(disk, sector, iov, iovcount, param);
+		if (total < 0) {
+			pr_info("disk_image__write error: total=%ld\n", (long)total);
+			return total;
+		}
+	} else {
+		/* Do nothing */
+	}
+
+	if (!disk->async && disk->disk_req_cb)
+		disk->disk_req_cb(param, total);
+
+	return total;
+}
+
+ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len)
+{
+	struct stat st;
+	int r;
+
+	r = fstat(disk->fd, &st);
+	if (r)
+		return r;
+
+	*len = snprintf(buffer, *len, "%llu%llu%llu", (u64)st.st_dev, (u64)st.st_rdev, (u64)st.st_ino);
+	return *len;
+}
+
+void disk_image__set_callback(struct disk_image *disk, void (*disk_req_cb)(void *param, long len))
+{
+	disk->disk_req_cb = disk_req_cb;
+}
diff --git a/tools/kvm/disk/qcow.c b/tools/kvm/disk/qcow.c
new file mode 100644
index 0000000..23f11f2
--- /dev/null
+++ b/tools/kvm/disk/qcow.c
@@ -0,0 +1,1529 @@
+#include "kvm/qcow.h"
+
+#include "kvm/disk-image.h"
+#include "kvm/read-write.h"
+#include "kvm/mutex.h"
+#include "kvm/util.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifdef CONFIG_HAS_ZLIB
+#include <zlib.h>
+#endif
+
+#include <linux/err.h>
+#include <linux/byteorder.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+static int update_cluster_refcount(struct qcow *q, u64 clust_idx, u16 append);
+static int qcow_write_refcount_table(struct qcow *q);
+static u64 qcow_alloc_clusters(struct qcow *q, u64 size, int update_ref);
+static void  qcow_free_clusters(struct qcow *q, u64 clust_start, u64 size);
+
+static inline int qcow_pwrite_sync(int fd,
+	void *buf, size_t count, off_t offset)
+{
+	if (pwrite_in_full(fd, buf, count, offset) < 0)
+		return -1;
+
+	return fdatasync(fd);
+}
+
+static int l2_table_insert(struct rb_root *root, struct qcow_l2_table *new)
+{
+	struct rb_node **link = &(root->rb_node), *parent = NULL;
+	u64 offset = new->offset;
+
+	/* search the tree */
+	while (*link) {
+		struct qcow_l2_table *t;
+
+		t = rb_entry(*link, struct qcow_l2_table, node);
+		if (!t)
+			goto error;
+
+		parent = *link;
+
+		if (t->offset > offset)
+			link = &(*link)->rb_left;
+		else if (t->offset < offset)
+			link = &(*link)->rb_right;
+		else
+			goto out;
+	}
+
+	/* add new node */
+	rb_link_node(&new->node, parent, link);
+	rb_insert_color(&new->node, root);
+out:
+	return 0;
+error:
+	return -1;
+}
+
+static struct qcow_l2_table *l2_table_lookup(struct rb_root *root, u64 offset)
+{
+	struct rb_node *link = root->rb_node;
+
+	while (link) {
+		struct qcow_l2_table *t;
+
+		t = rb_entry(link, struct qcow_l2_table, node);
+		if (!t)
+			goto out;
+
+		if (t->offset > offset)
+			link = link->rb_left;
+		else if (t->offset < offset)
+			link = link->rb_right;
+		else
+			return t;
+	}
+out:
+	return NULL;
+}
+
+static void l1_table_free_cache(struct qcow_l1_table *l1t)
+{
+	struct rb_root *r = &l1t->root;
+	struct list_head *pos, *n;
+	struct qcow_l2_table *t;
+
+	list_for_each_safe(pos, n, &l1t->lru_list) {
+		/* Remove cache table from the list and RB tree */
+		list_del(pos);
+		t = list_entry(pos, struct qcow_l2_table, list);
+		rb_erase(&t->node, r);
+
+		/* Free the cached node */
+		free(t);
+	}
+}
+
+static int qcow_l2_cache_write(struct qcow *q, struct qcow_l2_table *c)
+{
+	struct qcow_header *header = q->header;
+	u64 size;
+
+	if (!c->dirty)
+		return 0;
+
+	size = 1 << header->l2_bits;
+
+	if (qcow_pwrite_sync(q->fd, c->table,
+		size * sizeof(u64), c->offset) < 0)
+		return -1;
+
+	c->dirty = 0;
+
+	return 0;
+}
+
+static int cache_table(struct qcow *q, struct qcow_l2_table *c)
+{
+	struct qcow_l1_table *l1t = &q->table;
+	struct rb_root *r = &l1t->root;
+	struct qcow_l2_table *lru;
+
+	if (l1t->nr_cached == MAX_CACHE_NODES) {
+		/*
+		 * The node at the head of the list is least recently used
+		 * node. Remove it from the list and replaced with a new node.
+		 */
+		lru = list_first_entry(&l1t->lru_list, struct qcow_l2_table, list);
+
+		/* Remove the node from the cache */
+		rb_erase(&lru->node, r);
+		list_del_init(&lru->list);
+		l1t->nr_cached--;
+
+		/* Free the LRUed node */
+		free(lru);
+	}
+
+	/* Add new node in RB Tree: Helps in searching faster */
+	if (l2_table_insert(r, c) < 0)
+		goto error;
+
+	/* Add in LRU replacement list */
+	list_add_tail(&c->list, &l1t->lru_list);
+	l1t->nr_cached++;
+
+	return 0;
+error:
+	return -1;
+}
+
+static struct qcow_l2_table *l2_table_search(struct qcow *q, u64 offset)
+{
+	struct qcow_l1_table *l1t = &q->table;
+	struct qcow_l2_table *l2t;
+
+	l2t = l2_table_lookup(&l1t->root, offset);
+	if (!l2t)
+		return NULL;
+
+	/* Update the LRU state, by moving the searched node to list tail */
+	list_move_tail(&l2t->list, &l1t->lru_list);
+
+	return l2t;
+}
+
+/* Allocates a new node for caching L2 table */
+static struct qcow_l2_table *new_cache_table(struct qcow *q, u64 offset)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_l2_table *c;
+	u64 l2t_sz;
+	u64 size;
+
+	l2t_sz = 1 << header->l2_bits;
+	size   = sizeof(*c) + l2t_sz * sizeof(u64);
+	c      = calloc(1, size);
+	if (!c)
+		goto out;
+
+	c->offset = offset;
+	RB_CLEAR_NODE(&c->node);
+	INIT_LIST_HEAD(&c->list);
+out:
+	return c;
+}
+
+static inline u64 get_l1_index(struct qcow *q, u64 offset)
+{
+	struct qcow_header *header = q->header;
+
+	return offset >> (header->l2_bits + header->cluster_bits);
+}
+
+static inline u64 get_l2_index(struct qcow *q, u64 offset)
+{
+	struct qcow_header *header = q->header;
+
+	return (offset >> (header->cluster_bits)) & ((1 << header->l2_bits)-1);
+}
+
+static inline u64 get_cluster_offset(struct qcow *q, u64 offset)
+{
+	struct qcow_header *header = q->header;
+
+	return offset & ((1 << header->cluster_bits)-1);
+}
+
+static struct qcow_l2_table *qcow_read_l2_table(struct qcow *q, u64 offset)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_l2_table *l2t;
+	u64 size;
+
+	size = 1 << header->l2_bits;
+
+	/* search an entry for offset in cache */
+	l2t = l2_table_search(q, offset);
+	if (l2t)
+		return l2t;
+
+	/* allocate new node for caching l2 table */
+	l2t = new_cache_table(q, offset);
+	if (!l2t)
+		goto error;
+
+	/* table not cached: read from the disk */
+	if (pread_in_full(q->fd, l2t->table, size * sizeof(u64), offset) < 0)
+		goto error;
+
+	/* cache the table */
+	if (cache_table(q, l2t) < 0)
+		goto error;
+
+	return l2t;
+error:
+	free(l2t);
+	return NULL;
+}
+
+static int qcow_decompress_buffer(u8 *out_buf, int out_buf_size,
+	const u8 *buf, int buf_size)
+{
+#ifdef CONFIG_HAS_ZLIB
+	z_stream strm1, *strm = &strm1;
+	int ret, out_len;
+
+	memset(strm, 0, sizeof(*strm));
+
+	strm->next_in = (u8 *)buf;
+	strm->avail_in = buf_size;
+	strm->next_out = out_buf;
+	strm->avail_out = out_buf_size;
+
+	ret = inflateInit2(strm, -12);
+	if (ret != Z_OK)
+		return -1;
+
+	ret = inflate(strm, Z_FINISH);
+	out_len = strm->next_out - out_buf;
+	if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
+		out_len != out_buf_size) {
+		inflateEnd(strm);
+		return -1;
+	}
+
+	inflateEnd(strm);
+	return 0;
+#else
+	return -1;
+#endif
+}
+
+static ssize_t qcow1_read_cluster(struct qcow *q, u64 offset,
+	void *dst, u32 dst_len)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_l1_table *l1t = &q->table;
+	struct qcow_l2_table *l2t;
+	u64 clust_offset;
+	u64 clust_start;
+	u64 l2t_offset;
+	size_t length;
+	u64 l2t_size;
+	u64 l1_idx;
+	u64 l2_idx;
+	int coffset;
+	int csize;
+
+	l1_idx = get_l1_index(q, offset);
+	if (l1_idx >= l1t->table_size)
+		return -1;
+
+	clust_offset = get_cluster_offset(q, offset);
+	if (clust_offset >= q->cluster_size)
+		return -1;
+
+	length = q->cluster_size - clust_offset;
+	if (length > dst_len)
+		length = dst_len;
+
+	mutex_lock(&q->mutex);
+
+	l2t_offset = be64_to_cpu(l1t->l1_table[l1_idx]);
+	if (!l2t_offset)
+		goto zero_cluster;
+
+	l2t_size = 1 << header->l2_bits;
+
+	/* read and cache level 2 table */
+	l2t = qcow_read_l2_table(q, l2t_offset);
+	if (!l2t)
+		goto out_error;
+
+	l2_idx = get_l2_index(q, offset);
+	if (l2_idx >= l2t_size)
+		goto out_error;
+
+	clust_start = be64_to_cpu(l2t->table[l2_idx]);
+	if (clust_start & QCOW1_OFLAG_COMPRESSED) {
+		coffset = clust_start & q->cluster_offset_mask;
+		csize = clust_start >> (63 - q->header->cluster_bits);
+		csize &= (q->cluster_size - 1);
+
+		if (pread_in_full(q->fd, q->cluster_data, csize,
+				  coffset) < 0)
+			goto out_error;
+
+		if (qcow_decompress_buffer(q->cluster_cache, q->cluster_size,
+					q->cluster_data, csize) < 0)
+			goto out_error;
+
+		memcpy(dst, q->cluster_cache + clust_offset, length);
+		mutex_unlock(&q->mutex);
+	} else {
+		if (!clust_start)
+			goto zero_cluster;
+
+		mutex_unlock(&q->mutex);
+
+		if (pread_in_full(q->fd, dst, length,
+				  clust_start + clust_offset) < 0)
+			return -1;
+	}
+
+	return length;
+
+zero_cluster:
+	mutex_unlock(&q->mutex);
+	memset(dst, 0, length);
+	return length;
+
+out_error:
+	mutex_unlock(&q->mutex);
+	length = -1;
+	return -1;
+}
+
+static ssize_t qcow2_read_cluster(struct qcow *q, u64 offset,
+	void *dst, u32 dst_len)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_l1_table *l1t = &q->table;
+	struct qcow_l2_table *l2t;
+	u64 clust_offset;
+	u64 clust_start;
+	u64 l2t_offset;
+	size_t length;
+	u64 l2t_size;
+	u64 l1_idx;
+	u64 l2_idx;
+	int coffset;
+	int sector_offset;
+	int nb_csectors;
+	int csize;
+
+	l1_idx = get_l1_index(q, offset);
+	if (l1_idx >= l1t->table_size)
+		return -1;
+
+	clust_offset = get_cluster_offset(q, offset);
+	if (clust_offset >= q->cluster_size)
+		return -1;
+
+	length = q->cluster_size - clust_offset;
+	if (length > dst_len)
+		length = dst_len;
+
+	mutex_lock(&q->mutex);
+
+	l2t_offset = be64_to_cpu(l1t->l1_table[l1_idx]);
+
+	l2t_offset &= ~QCOW2_OFLAG_COPIED;
+	if (!l2t_offset)
+		goto zero_cluster;
+
+	l2t_size = 1 << header->l2_bits;
+
+	/* read and cache level 2 table */
+	l2t = qcow_read_l2_table(q, l2t_offset);
+	if (!l2t)
+		goto out_error;
+
+	l2_idx = get_l2_index(q, offset);
+	if (l2_idx >= l2t_size)
+		goto out_error;
+
+	clust_start = be64_to_cpu(l2t->table[l2_idx]);
+	if (clust_start & QCOW2_OFLAG_COMPRESSED) {
+		coffset = clust_start & q->cluster_offset_mask;
+		nb_csectors = ((clust_start >> q->csize_shift)
+			& q->csize_mask) + 1;
+		sector_offset = coffset & (SECTOR_SIZE - 1);
+		csize = nb_csectors * SECTOR_SIZE - sector_offset;
+
+		if (pread_in_full(q->fd, q->cluster_data,
+				  nb_csectors * SECTOR_SIZE,
+				  coffset & ~(SECTOR_SIZE - 1)) < 0) {
+			goto out_error;
+		}
+
+		if (qcow_decompress_buffer(q->cluster_cache, q->cluster_size,
+					q->cluster_data + sector_offset,
+					csize) < 0) {
+			goto out_error;
+		}
+
+		memcpy(dst, q->cluster_cache + clust_offset, length);
+		mutex_unlock(&q->mutex);
+	} else {
+		clust_start &= QCOW2_OFFSET_MASK;
+		if (!clust_start)
+			goto zero_cluster;
+
+		mutex_unlock(&q->mutex);
+
+		if (pread_in_full(q->fd, dst, length,
+				  clust_start + clust_offset) < 0)
+			return -1;
+	}
+
+	return length;
+
+zero_cluster:
+	mutex_unlock(&q->mutex);
+	memset(dst, 0, length);
+	return length;
+
+out_error:
+	mutex_unlock(&q->mutex);
+	length = -1;
+	return -1;
+}
+
+static ssize_t qcow_read_sector_single(struct disk_image *disk, u64 sector,
+	void *dst, u32 dst_len)
+{
+	struct qcow *q = disk->priv;
+	struct qcow_header *header = q->header;
+	u32 nr_read;
+	u64 offset;
+	char *buf;
+	u32 nr;
+
+	buf = dst;
+	nr_read = 0;
+
+	while (nr_read < dst_len) {
+		offset = sector << SECTOR_SHIFT;
+		if (offset >= header->size)
+			return -1;
+
+		if (q->version == QCOW1_VERSION)
+			nr = qcow1_read_cluster(q, offset, buf,
+				dst_len - nr_read);
+		else
+			nr = qcow2_read_cluster(q, offset, buf,
+				dst_len - nr_read);
+
+		if (nr <= 0)
+			return -1;
+
+		nr_read	+= nr;
+		buf	+= nr;
+		sector	+= (nr >> SECTOR_SHIFT);
+	}
+
+	return dst_len;
+}
+
+static ssize_t qcow_read_sector(struct disk_image *disk, u64 sector,
+				const struct iovec *iov, int iovcount, void *param)
+{
+	ssize_t nr, total = 0;
+
+	while (iovcount--) {
+		nr = qcow_read_sector_single(disk, sector, iov->iov_base, iov->iov_len);
+		if (nr != (ssize_t)iov->iov_len) {
+			pr_info("qcow_read_sector error: nr=%ld iov_len=%ld\n", (long)nr, (long)iov->iov_len);
+			return -1;
+		}
+
+		sector += iov->iov_len >> SECTOR_SHIFT;
+		total += nr;
+		iov++;
+	}
+
+	return total;
+}
+
+static void refcount_table_free_cache(struct qcow_refcount_table *rft)
+{
+	struct rb_root *r = &rft->root;
+	struct list_head *pos, *n;
+	struct qcow_refcount_block *t;
+
+	list_for_each_safe(pos, n, &rft->lru_list) {
+		list_del(pos);
+		t = list_entry(pos, struct qcow_refcount_block, list);
+		rb_erase(&t->node, r);
+
+		free(t);
+	}
+}
+
+static int refcount_block_insert(struct rb_root *root, struct qcow_refcount_block *new)
+{
+	struct rb_node **link = &(root->rb_node), *parent = NULL;
+	u64 offset = new->offset;
+
+	/* search the tree */
+	while (*link) {
+		struct qcow_refcount_block *t;
+
+		t = rb_entry(*link, struct qcow_refcount_block, node);
+		if (!t)
+			goto error;
+
+		parent = *link;
+
+		if (t->offset > offset)
+			link = &(*link)->rb_left;
+		else if (t->offset < offset)
+			link = &(*link)->rb_right;
+		else
+			goto out;
+	}
+
+	/* add new node */
+	rb_link_node(&new->node, parent, link);
+	rb_insert_color(&new->node, root);
+out:
+	return 0;
+error:
+	return -1;
+}
+
+static int write_refcount_block(struct qcow *q, struct qcow_refcount_block *rfb)
+{
+	if (!rfb->dirty)
+		return 0;
+
+	if (qcow_pwrite_sync(q->fd, rfb->entries,
+		rfb->size * sizeof(u16), rfb->offset) < 0)
+		return -1;
+
+	rfb->dirty = 0;
+
+	return 0;
+}
+
+static int cache_refcount_block(struct qcow *q, struct qcow_refcount_block *c)
+{
+	struct qcow_refcount_table *rft = &q->refcount_table;
+	struct rb_root *r = &rft->root;
+	struct qcow_refcount_block *lru;
+
+	if (rft->nr_cached == MAX_CACHE_NODES) {
+		lru = list_first_entry(&rft->lru_list, struct qcow_refcount_block, list);
+
+		rb_erase(&lru->node, r);
+		list_del_init(&lru->list);
+		rft->nr_cached--;
+
+		free(lru);
+	}
+
+	if (refcount_block_insert(r, c) < 0)
+		goto error;
+
+	list_add_tail(&c->list, &rft->lru_list);
+	rft->nr_cached++;
+
+	return 0;
+error:
+	return -1;
+}
+
+static struct qcow_refcount_block *new_refcount_block(struct qcow *q, u64 rfb_offset)
+{
+	struct qcow_refcount_block *rfb;
+
+	rfb = malloc(sizeof *rfb + q->cluster_size);
+	if (!rfb)
+		return NULL;
+
+	rfb->offset = rfb_offset;
+	rfb->size = q->cluster_size / sizeof(u16);
+	RB_CLEAR_NODE(&rfb->node);
+	INIT_LIST_HEAD(&rfb->list);
+
+	return rfb;
+}
+
+static struct qcow_refcount_block *refcount_block_lookup(struct rb_root *root, u64 offset)
+{
+	struct rb_node *link = root->rb_node;
+
+	while (link) {
+		struct qcow_refcount_block *t;
+
+		t = rb_entry(link, struct qcow_refcount_block, node);
+		if (!t)
+			goto out;
+
+		if (t->offset > offset)
+			link = link->rb_left;
+		else if (t->offset < offset)
+			link = link->rb_right;
+		else
+			return t;
+	}
+out:
+	return NULL;
+}
+
+static struct qcow_refcount_block *refcount_block_search(struct qcow *q, u64 offset)
+{
+	struct qcow_refcount_table *rft = &q->refcount_table;
+	struct qcow_refcount_block *rfb;
+
+	rfb = refcount_block_lookup(&rft->root, offset);
+	if (!rfb)
+		return NULL;
+
+	/* Update the LRU state, by moving the searched node to list tail */
+	list_move_tail(&rfb->list, &rft->lru_list);
+
+	return rfb;
+}
+
+static struct qcow_refcount_block *qcow_grow_refcount_block(struct qcow *q,
+	u64 clust_idx)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_refcount_table *rft = &q->refcount_table;
+	struct qcow_refcount_block *rfb;
+	u64 new_block_offset;
+	u64 rft_idx;
+
+	rft_idx = clust_idx >> (header->cluster_bits -
+		QCOW_REFCOUNT_BLOCK_SHIFT);
+
+	if (rft_idx >= rft->rf_size) {
+		pr_warning("Don't support grow refcount block table");
+		return NULL;
+	}
+
+	new_block_offset = qcow_alloc_clusters(q, q->cluster_size, 0);
+	if (new_block_offset < 0)
+		return NULL;
+
+	rfb = new_refcount_block(q, new_block_offset);
+	if (!rfb)
+		return NULL;
+
+	memset(rfb->entries, 0x00, q->cluster_size);
+	rfb->dirty = 1;
+
+	/* write refcount block */
+	if (write_refcount_block(q, rfb) < 0)
+		goto free_rfb;
+
+	if (cache_refcount_block(q, rfb) < 0)
+		goto free_rfb;
+
+	rft->rf_table[rft_idx] = cpu_to_be64(new_block_offset);
+	if (update_cluster_refcount(q, new_block_offset >>
+		    header->cluster_bits, 1) < 0)
+		goto recover_rft;
+
+	if (qcow_write_refcount_table(q) < 0)
+		goto recover_rft;
+
+	return rfb;
+
+recover_rft:
+	rft->rf_table[rft_idx] = 0;
+free_rfb:
+	free(rfb);
+	return NULL;
+}
+
+static struct qcow_refcount_block *qcow_read_refcount_block(struct qcow *q, u64 clust_idx)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_refcount_table *rft = &q->refcount_table;
+	struct qcow_refcount_block *rfb;
+	u64 rfb_offset;
+	u64 rft_idx;
+
+	rft_idx = clust_idx >> (header->cluster_bits - QCOW_REFCOUNT_BLOCK_SHIFT);
+	if (rft_idx >= rft->rf_size)
+		return ERR_PTR(-ENOSPC);
+
+	rfb_offset = be64_to_cpu(rft->rf_table[rft_idx]);
+	if (!rfb_offset)
+		return ERR_PTR(-ENOSPC);
+
+	rfb = refcount_block_search(q, rfb_offset);
+	if (rfb)
+		return rfb;
+
+	rfb = new_refcount_block(q, rfb_offset);
+	if (!rfb)
+		return NULL;
+
+	if (pread_in_full(q->fd, rfb->entries, rfb->size * sizeof(u16), rfb_offset) < 0)
+		goto error_free_rfb;
+
+	if (cache_refcount_block(q, rfb) < 0)
+		goto error_free_rfb;
+
+	return rfb;
+
+error_free_rfb:
+	free(rfb);
+
+	return NULL;
+}
+
+static u16 qcow_get_refcount(struct qcow *q, u64 clust_idx)
+{
+	struct qcow_refcount_block *rfb = NULL;
+	struct qcow_header *header = q->header;
+	u64 rfb_idx;
+
+	rfb = qcow_read_refcount_block(q, clust_idx);
+	if (PTR_ERR(rfb) == -ENOSPC)
+		return 0;
+	else if (IS_ERR_OR_NULL(rfb)) {
+		pr_warning("Error while reading refcount table");
+		return -1;
+	}
+
+	rfb_idx = clust_idx & (((1ULL <<
+		(header->cluster_bits - QCOW_REFCOUNT_BLOCK_SHIFT)) - 1));
+
+	if (rfb_idx >= rfb->size) {
+		pr_warning("L1: refcount block index out of bounds");
+		return -1;
+	}
+
+	return be16_to_cpu(rfb->entries[rfb_idx]);
+}
+
+static int update_cluster_refcount(struct qcow *q, u64 clust_idx, u16 append)
+{
+	struct qcow_refcount_block *rfb = NULL;
+	struct qcow_header *header = q->header;
+	u16 refcount;
+	u64 rfb_idx;
+
+	rfb = qcow_read_refcount_block(q, clust_idx);
+	if (PTR_ERR(rfb) == -ENOSPC) {
+		rfb = qcow_grow_refcount_block(q, clust_idx);
+		if (!rfb) {
+			pr_warning("error while growing refcount table");
+			return -1;
+		}
+	} else if (IS_ERR_OR_NULL(rfb)) {
+		pr_warning("error while reading refcount table");
+		return -1;
+	}
+
+	rfb_idx = clust_idx & (((1ULL <<
+		(header->cluster_bits - QCOW_REFCOUNT_BLOCK_SHIFT)) - 1));
+	if (rfb_idx >= rfb->size) {
+		pr_warning("refcount block index out of bounds");
+		return -1;
+	}
+
+	refcount = be16_to_cpu(rfb->entries[rfb_idx]) + append;
+	rfb->entries[rfb_idx] = cpu_to_be16(refcount);
+	rfb->dirty = 1;
+
+	/* write refcount block */
+	if (write_refcount_block(q, rfb) < 0) {
+		pr_warning("refcount block index out of bounds");
+		return -1;
+	}
+
+	/* update free_clust_idx since refcount becomes zero */
+	if (!refcount && clust_idx < q->free_clust_idx)
+		q->free_clust_idx = clust_idx;
+
+	return 0;
+}
+
+static void  qcow_free_clusters(struct qcow *q, u64 clust_start, u64 size)
+{
+	struct qcow_header *header = q->header;
+	u64 start, end, offset;
+
+	start = clust_start & ~(q->cluster_size - 1);
+	end = (clust_start + size - 1) & ~(q->cluster_size - 1);
+	for (offset = start; offset <= end; offset += q->cluster_size)
+		update_cluster_refcount(q, offset >> header->cluster_bits, -1);
+}
+
+/*
+ * Allocate clusters according to the size. Find a postion that
+ * can satisfy the size. free_clust_idx is initialized to zero and
+ * Record last position.
+ */
+static u64 qcow_alloc_clusters(struct qcow *q, u64 size, int update_ref)
+{
+	struct qcow_header *header = q->header;
+	u16 clust_refcount;
+	u32 clust_idx = 0, i;
+	u64 clust_num;
+
+	clust_num = (size + (q->cluster_size - 1)) >> header->cluster_bits;
+
+again:
+	for (i = 0; i < clust_num; i++) {
+		clust_idx = q->free_clust_idx++;
+		clust_refcount = qcow_get_refcount(q, clust_idx);
+		if (clust_refcount < 0)
+			return -1;
+		else if (clust_refcount > 0)
+			goto again;
+	}
+
+	clust_idx++;
+
+	if (update_ref)
+		for (i = 0; i < clust_num; i++)
+			if (update_cluster_refcount(q,
+				clust_idx - clust_num + i, 1))
+				return -1;
+
+	return (clust_idx - clust_num) << header->cluster_bits;
+}
+
+static int qcow_write_l1_table(struct qcow *q)
+{
+	struct qcow_l1_table *l1t = &q->table;
+	struct qcow_header *header = q->header;
+
+	if (qcow_pwrite_sync(q->fd, l1t->l1_table,
+		l1t->table_size * sizeof(u64),
+		header->l1_table_offset) < 0)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Get l2 table. If the table has been copied, read table directly.
+ * If the table exists, allocate a new cluster and copy the table
+ * to the new cluster.
+ */
+static int get_cluster_table(struct qcow *q, u64 offset,
+	struct qcow_l2_table **result_l2t, u64 *result_l2_index)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_l1_table *l1t = &q->table;
+	struct qcow_l2_table *l2t;
+	u64 l1t_idx;
+	u64 l2t_offset;
+	u64 l2t_idx;
+	u64 l2t_size;
+	u64 l2t_new_offset;
+
+	l2t_size = 1 << header->l2_bits;
+
+	l1t_idx = get_l1_index(q, offset);
+	if (l1t_idx >= l1t->table_size)
+		return -1;
+
+	l2t_idx = get_l2_index(q, offset);
+	if (l2t_idx >= l2t_size)
+		return -1;
+
+	l2t_offset = be64_to_cpu(l1t->l1_table[l1t_idx]);
+	if (l2t_offset & QCOW2_OFLAG_COPIED) {
+		l2t_offset &= ~QCOW2_OFLAG_COPIED;
+		l2t = qcow_read_l2_table(q, l2t_offset);
+		if (!l2t)
+			goto error;
+	} else {
+		l2t_new_offset = qcow_alloc_clusters(q,
+			l2t_size*sizeof(u64), 1);
+
+		if (l2t_new_offset < 0)
+			goto error;
+
+		l2t = new_cache_table(q, l2t_new_offset);
+		if (!l2t)
+			goto free_cluster;
+
+		if (l2t_offset) {
+			l2t = qcow_read_l2_table(q, l2t_offset);
+			if (!l2t)
+				goto free_cache;
+		} else
+			memset(l2t->table, 0x00, l2t_size * sizeof(u64));
+
+		/* write l2 table */
+		l2t->dirty = 1;
+		if (qcow_l2_cache_write(q, l2t) < 0)
+			goto free_cache;
+
+		/* cache l2 table */
+		if (cache_table(q, l2t))
+			goto free_cache;
+
+		/* update the l1 talble */
+		l1t->l1_table[l1t_idx] = cpu_to_be64(l2t_new_offset
+			| QCOW2_OFLAG_COPIED);
+		if (qcow_write_l1_table(q)) {
+			pr_warning("Update l1 table error");
+			goto free_cache;
+		}
+
+		/* free old cluster */
+		qcow_free_clusters(q, l2t_offset, q->cluster_size);
+	}
+
+	*result_l2t = l2t;
+	*result_l2_index = l2t_idx;
+
+	return 0;
+
+free_cache:
+	free(l2t);
+
+free_cluster:
+	qcow_free_clusters(q, l2t_new_offset, q->cluster_size);
+
+error:
+	return -1;
+}
+
+/*
+ * If the cluster has been copied, write data directly. If not,
+ * read the original data and write it to the new cluster with
+ * modification.
+ */
+static ssize_t qcow_write_cluster(struct qcow *q, u64 offset,
+		void *buf, u32 src_len)
+{
+	struct qcow_l2_table *l2t;
+	u64 clust_new_start;
+	u64 clust_start;
+	u64 clust_flags;
+	u64 clust_off;
+	u64 l2t_idx;
+	u64 len;
+
+	l2t = NULL;
+
+	clust_off = get_cluster_offset(q, offset);
+	if (clust_off >= q->cluster_size)
+		return -1;
+
+	len = q->cluster_size - clust_off;
+	if (len > src_len)
+		len = src_len;
+
+	mutex_lock(&q->mutex);
+
+	if (get_cluster_table(q, offset, &l2t, &l2t_idx)) {
+		pr_warning("Get l2 table error");
+		goto error;
+	}
+
+	clust_start = be64_to_cpu(l2t->table[l2t_idx]);
+	clust_flags = clust_start & QCOW2_OFLAGS_MASK;
+
+	clust_start &= QCOW2_OFFSET_MASK;
+	if (!(clust_flags & QCOW2_OFLAG_COPIED)) {
+		clust_new_start	= qcow_alloc_clusters(q, q->cluster_size, 1);
+		if (clust_new_start < 0) {
+			pr_warning("Cluster alloc error");
+			goto error;
+		}
+
+		offset &= ~(q->cluster_size - 1);
+
+		/* if clust_start is not zero, read the original data*/
+		if (clust_start) {
+			mutex_unlock(&q->mutex);
+			if (qcow2_read_cluster(q, offset, q->copy_buff,
+				q->cluster_size) < 0) {
+				pr_warning("Read copy cluster error");
+				qcow_free_clusters(q, clust_new_start,
+					q->cluster_size);
+				return -1;
+			}
+			mutex_lock(&q->mutex);
+		} else
+			memset(q->copy_buff, 0x00, q->cluster_size);
+
+		memcpy(q->copy_buff + clust_off, buf, len);
+
+		 /* Write actual data */
+		if (pwrite_in_full(q->fd, q->copy_buff, q->cluster_size,
+			clust_new_start) < 0)
+			goto free_cluster;
+
+		/* update l2 table*/
+		l2t->table[l2t_idx] = cpu_to_be64(clust_new_start
+			| QCOW2_OFLAG_COPIED);
+		l2t->dirty = 1;
+
+		if (qcow_l2_cache_write(q, l2t))
+			goto free_cluster;
+
+		/* free old cluster*/
+		if (clust_flags & QCOW2_OFLAG_COMPRESSED) {
+			int size;
+			size = ((clust_start >> q->csize_shift) &
+				q->csize_mask) + 1;
+			size *= 512;
+			clust_start &= q->cluster_offset_mask;
+			clust_start &= ~511;
+
+			qcow_free_clusters(q, clust_start, size);
+		} else if (clust_start)
+			qcow_free_clusters(q, clust_start, q->cluster_size);
+
+	} else {
+		/* Write actual data */
+		if (pwrite_in_full(q->fd, buf, len,
+			clust_start + clust_off) < 0)
+			goto error;
+	}
+	mutex_unlock(&q->mutex);
+	return len;
+
+free_cluster:
+	qcow_free_clusters(q, clust_new_start, q->cluster_size);
+
+error:
+	mutex_unlock(&q->mutex);
+	return -1;
+}
+
+static ssize_t qcow_write_sector_single(struct disk_image *disk, u64 sector, void *src, u32 src_len)
+{
+	struct qcow *q = disk->priv;
+	struct qcow_header *header = q->header;
+	u32 nr_written;
+	char *buf;
+	u64 offset;
+	ssize_t nr;
+
+	buf		= src;
+	nr_written	= 0;
+	offset		= sector << SECTOR_SHIFT;
+
+	while (nr_written < src_len) {
+		if (offset >= header->size)
+			return -1;
+
+		nr = qcow_write_cluster(q, offset, buf, src_len - nr_written);
+		if (nr < 0)
+			return -1;
+
+		nr_written	+= nr;
+		buf		+= nr;
+		offset		+= nr;
+	}
+
+	return nr_written;
+}
+
+static ssize_t qcow_write_sector(struct disk_image *disk, u64 sector,
+				const struct iovec *iov, int iovcount, void *param)
+{
+	ssize_t nr, total = 0;
+
+	while (iovcount--) {
+		nr = qcow_write_sector_single(disk, sector, iov->iov_base, iov->iov_len);
+		if (nr != (ssize_t)iov->iov_len) {
+			pr_info("qcow_write_sector error: nr=%ld iov_len=%ld\n", (long)nr, (long)iov->iov_len);
+			return -1;
+		}
+
+		sector	+= iov->iov_len >> SECTOR_SHIFT;
+		iov++;
+		total	+= nr;
+	}
+
+	return total;
+}
+
+static int qcow_disk_flush(struct disk_image *disk)
+{
+	struct qcow *q = disk->priv;
+	struct qcow_refcount_table *rft;
+	struct list_head *pos, *n;
+	struct qcow_l1_table *l1t;
+
+	l1t = &q->table;
+	rft = &q->refcount_table;
+
+	mutex_lock(&q->mutex);
+
+	list_for_each_safe(pos, n, &rft->lru_list) {
+		struct qcow_refcount_block *c = list_entry(pos, struct qcow_refcount_block, list);
+
+		if (write_refcount_block(q, c) < 0)
+			goto error_unlock;
+	}
+
+	list_for_each_safe(pos, n, &l1t->lru_list) {
+		struct qcow_l2_table *c = list_entry(pos, struct qcow_l2_table, list);
+
+		if (qcow_l2_cache_write(q, c) < 0)
+			goto error_unlock;
+	}
+
+	if (qcow_write_l1_table < 0)
+		goto error_unlock;
+
+	mutex_unlock(&q->mutex);
+
+	return fsync(disk->fd);
+
+error_unlock:
+	mutex_unlock(&q->mutex);
+	return -1;
+}
+
+static int qcow_disk_close(struct disk_image *disk)
+{
+	struct qcow *q;
+
+	if (!disk)
+		return 0;
+
+	q = disk->priv;
+
+	refcount_table_free_cache(&q->refcount_table);
+	l1_table_free_cache(&q->table);
+	free(q->copy_buff);
+	free(q->cluster_data);
+	free(q->cluster_cache);
+	free(q->refcount_table.rf_table);
+	free(q->table.l1_table);
+	free(q->header);
+	free(q);
+
+	return 0;
+}
+
+static struct disk_image_operations qcow_disk_readonly_ops = {
+	.read_sector		= qcow_read_sector,
+	.close			= qcow_disk_close,
+};
+
+static struct disk_image_operations qcow_disk_ops = {
+	.read_sector		= qcow_read_sector,
+	.write_sector		= qcow_write_sector,
+	.flush			= qcow_disk_flush,
+	.close			= qcow_disk_close,
+};
+
+static int qcow_read_refcount_table(struct qcow *q)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_refcount_table *rft = &q->refcount_table;
+
+	rft->rf_size = (header->refcount_table_size * q->cluster_size)
+		/ sizeof(u64);
+
+	rft->rf_table = calloc(rft->rf_size, sizeof(u64));
+	if (!rft->rf_table)
+		return -1;
+
+	rft->root = RB_ROOT;
+	INIT_LIST_HEAD(&rft->lru_list);
+
+	return pread_in_full(q->fd, rft->rf_table, sizeof(u64) * rft->rf_size, header->refcount_table_offset);
+}
+
+static int qcow_write_refcount_table(struct qcow *q)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_refcount_table *rft = &q->refcount_table;
+
+	return qcow_pwrite_sync(q->fd, rft->rf_table,
+		rft->rf_size * sizeof(u64), header->refcount_table_offset);
+}
+
+static int qcow_read_l1_table(struct qcow *q)
+{
+	struct qcow_header *header = q->header;
+	struct qcow_l1_table *table = &q->table;
+
+	table->table_size	= header->l1_size;
+
+	table->l1_table	= calloc(table->table_size, sizeof(u64));
+	if (!table->l1_table)
+		return -1;
+
+	return pread_in_full(q->fd, table->l1_table, sizeof(u64) * table->table_size, header->l1_table_offset);
+}
+
+static void *qcow2_read_header(int fd)
+{
+	struct qcow2_header_disk f_header;
+	struct qcow_header *header;
+
+	header = malloc(sizeof(struct qcow_header));
+	if (!header)
+		return NULL;
+
+	if (pread_in_full(fd, &f_header, sizeof(struct qcow2_header_disk), 0) < 0) {
+		free(header);
+		return NULL;
+	}
+
+	be32_to_cpus(&f_header.magic);
+	be32_to_cpus(&f_header.version);
+	be64_to_cpus(&f_header.backing_file_offset);
+	be32_to_cpus(&f_header.backing_file_size);
+	be32_to_cpus(&f_header.cluster_bits);
+	be64_to_cpus(&f_header.size);
+	be32_to_cpus(&f_header.crypt_method);
+	be32_to_cpus(&f_header.l1_size);
+	be64_to_cpus(&f_header.l1_table_offset);
+	be64_to_cpus(&f_header.refcount_table_offset);
+	be32_to_cpus(&f_header.refcount_table_clusters);
+	be32_to_cpus(&f_header.nb_snapshots);
+	be64_to_cpus(&f_header.snapshots_offset);
+
+	*header		= (struct qcow_header) {
+		.size			= f_header.size,
+		.l1_table_offset	= f_header.l1_table_offset,
+		.l1_size		= f_header.l1_size,
+		.cluster_bits		= f_header.cluster_bits,
+		.l2_bits		= f_header.cluster_bits - 3,
+		.refcount_table_offset	= f_header.refcount_table_offset,
+		.refcount_table_size	= f_header.refcount_table_clusters,
+	};
+
+	return header;
+}
+
+static struct disk_image *qcow2_probe(int fd, bool readonly)
+{
+	struct disk_image *disk_image;
+	struct qcow_l1_table *l1t;
+	struct qcow_header *h;
+	struct qcow *q;
+
+	q = calloc(1, sizeof(struct qcow));
+	if (!q)
+		return NULL;
+
+	mutex_init(&q->mutex);
+	q->fd = fd;
+
+	l1t = &q->table;
+
+	l1t->root = RB_ROOT;
+	INIT_LIST_HEAD(&l1t->lru_list);
+
+	h = q->header = qcow2_read_header(fd);
+	if (!h)
+		goto free_qcow;
+
+	q->version = QCOW2_VERSION;
+	q->csize_shift = (62 - (q->header->cluster_bits - 8));
+	q->csize_mask = (1 << (q->header->cluster_bits - 8)) - 1;
+	q->cluster_offset_mask = (1LL << q->csize_shift) - 1;
+	q->cluster_size = 1 << q->header->cluster_bits;
+
+	q->copy_buff = malloc(q->cluster_size);
+	if (!q->copy_buff) {
+		pr_warning("copy buff malloc error");
+		goto free_header;
+	}
+
+	q->cluster_data = malloc(q->cluster_size);
+	if (!q->cluster_data) {
+		pr_warning("cluster data malloc error");
+		goto free_copy_buff;
+	}
+
+	q->cluster_cache = malloc(q->cluster_size);
+	if (!q->cluster_cache) {
+		pr_warning("cluster cache malloc error");
+		goto free_cluster_data;
+	}
+
+	if (qcow_read_l1_table(q) < 0)
+		goto free_cluster_cache;
+
+	if (qcow_read_refcount_table(q) < 0)
+		goto free_l1_table;
+
+	/*
+	 * Do not use mmap use read/write instead
+	 */
+	if (readonly)
+		disk_image = disk_image__new(fd, h->size, &qcow_disk_readonly_ops, DISK_IMAGE_REGULAR);
+	else
+		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_REGULAR);
+
+	if (IS_ERR_OR_NULL(disk_image))
+		goto free_refcount_table;
+
+	disk_image->async = 0;
+	disk_image->priv = q;
+
+	return disk_image;
+
+free_refcount_table:
+	if (q->refcount_table.rf_table)
+		free(q->refcount_table.rf_table);
+free_l1_table:
+	if (q->table.l1_table)
+		free(q->table.l1_table);
+free_cluster_cache:
+	if (q->cluster_cache)
+		free(q->cluster_cache);
+free_cluster_data:
+	if (q->cluster_data)
+		free(q->cluster_data);
+free_copy_buff:
+	if (q->copy_buff)
+		free(q->copy_buff);
+free_header:
+	if (q->header)
+		free(q->header);
+free_qcow:
+	if (q)
+		free(q);
+
+	return NULL;
+}
+
+static bool qcow2_check_image(int fd)
+{
+	struct qcow2_header_disk f_header;
+
+	if (pread_in_full(fd, &f_header, sizeof(struct qcow2_header_disk), 0) < 0)
+		return false;
+
+	be32_to_cpus(&f_header.magic);
+	be32_to_cpus(&f_header.version);
+
+	if (f_header.magic != QCOW_MAGIC)
+		return false;
+
+	if (f_header.version != QCOW2_VERSION)
+		return false;
+
+	return true;
+}
+
+static void *qcow1_read_header(int fd)
+{
+	struct qcow1_header_disk f_header;
+	struct qcow_header *header;
+
+	header = malloc(sizeof(struct qcow_header));
+	if (!header)
+		return NULL;
+
+	if (pread_in_full(fd, &f_header, sizeof(struct qcow1_header_disk), 0) < 0) {
+		free(header);
+		return NULL;
+	}
+
+	be32_to_cpus(&f_header.magic);
+	be32_to_cpus(&f_header.version);
+	be64_to_cpus(&f_header.backing_file_offset);
+	be32_to_cpus(&f_header.backing_file_size);
+	be32_to_cpus(&f_header.mtime);
+	be64_to_cpus(&f_header.size);
+	be32_to_cpus(&f_header.crypt_method);
+	be64_to_cpus(&f_header.l1_table_offset);
+
+	*header		= (struct qcow_header) {
+		.size			= f_header.size,
+		.l1_table_offset	= f_header.l1_table_offset,
+		.l1_size		= f_header.size / ((1 << f_header.l2_bits) * (1 << f_header.cluster_bits)),
+		.cluster_bits		= f_header.cluster_bits,
+		.l2_bits		= f_header.l2_bits,
+	};
+
+	return header;
+}
+
+static struct disk_image *qcow1_probe(int fd, bool readonly)
+{
+	struct disk_image *disk_image;
+	struct qcow_l1_table *l1t;
+	struct qcow_header *h;
+	struct qcow *q;
+
+	q = calloc(1, sizeof(struct qcow));
+	if (!q)
+		return NULL;
+
+	mutex_init(&q->mutex);
+	q->fd = fd;
+
+	l1t = &q->table;
+
+	l1t->root = RB_ROOT;
+	INIT_LIST_HEAD(&l1t->lru_list);
+
+	h = q->header = qcow1_read_header(fd);
+	if (!h)
+		goto free_qcow;
+
+	q->version = QCOW1_VERSION;
+	q->cluster_size = 1 << q->header->cluster_bits;
+	q->cluster_offset_mask = (1LL << (63 - q->header->cluster_bits)) - 1;
+	q->free_clust_idx = 0;
+
+	q->cluster_data = malloc(q->cluster_size);
+	if (!q->cluster_data) {
+		pr_warning("cluster data malloc error");
+		goto free_header;
+	}
+
+	q->cluster_cache = malloc(q->cluster_size);
+	if (!q->cluster_cache) {
+		pr_warning("cluster cache malloc error");
+		goto free_cluster_data;
+	}
+
+	if (qcow_read_l1_table(q) < 0)
+		goto free_cluster_cache;
+
+	/*
+	 * Do not use mmap use read/write instead
+	 */
+	if (readonly)
+		disk_image = disk_image__new(fd, h->size, &qcow_disk_readonly_ops, DISK_IMAGE_REGULAR);
+	else
+		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_REGULAR);
+
+	if (!disk_image)
+		goto free_l1_table;
+
+	disk_image->async = 1;
+	disk_image->priv = q;
+
+	return disk_image;
+
+free_l1_table:
+	if (q->table.l1_table)
+		free(q->table.l1_table);
+free_cluster_cache:
+	if (q->cluster_cache)
+		free(q->cluster_cache);
+free_cluster_data:
+	if (q->cluster_data)
+		free(q->cluster_data);
+free_header:
+	if (q->header)
+		free(q->header);
+free_qcow:
+	if (q)
+		free(q);
+
+	return NULL;
+}
+
+static bool qcow1_check_image(int fd)
+{
+	struct qcow1_header_disk f_header;
+
+	if (pread_in_full(fd, &f_header, sizeof(struct qcow1_header_disk), 0) < 0)
+		return false;
+
+	be32_to_cpus(&f_header.magic);
+	be32_to_cpus(&f_header.version);
+
+	if (f_header.magic != QCOW_MAGIC)
+		return false;
+
+	if (f_header.version != QCOW1_VERSION)
+		return false;
+
+	return true;
+}
+
+struct disk_image *qcow_probe(int fd, bool readonly)
+{
+	if (qcow1_check_image(fd))
+		return qcow1_probe(fd, readonly);
+
+	if (qcow2_check_image(fd))
+		return qcow2_probe(fd, readonly);
+
+	return NULL;
+}
diff --git a/tools/kvm/disk/raw.c b/tools/kvm/disk/raw.c
new file mode 100644
index 0000000..d2df814
--- /dev/null
+++ b/tools/kvm/disk/raw.c
@@ -0,0 +1,141 @@
+#include "kvm/disk-image.h"
+
+#include <linux/err.h>
+
+#ifdef CONFIG_HAS_AIO
+#include <libaio.h>
+#endif
+
+ssize_t raw_image__read_sector(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param)
+{
+	u64 offset = sector << SECTOR_SHIFT;
+
+#ifdef CONFIG_HAS_AIO
+	struct iocb iocb;
+
+	return aio_preadv(disk->ctx, &iocb, disk->fd, iov, iovcount, offset,
+				disk->evt, param);
+#else
+	return preadv_in_full(disk->fd, iov, iovcount, offset);
+#endif
+}
+
+ssize_t raw_image__write_sector(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param)
+{
+	u64 offset = sector << SECTOR_SHIFT;
+
+#ifdef CONFIG_HAS_AIO
+	struct iocb iocb;
+
+	return aio_pwritev(disk->ctx, &iocb, disk->fd, iov, iovcount, offset,
+				disk->evt, param);
+#else
+	return pwritev_in_full(disk->fd, iov, iovcount, offset);
+#endif
+}
+
+ssize_t raw_image__read_sector_mmap(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param)
+{
+	u64 offset = sector << SECTOR_SHIFT;
+	ssize_t total = 0;
+
+	while (iovcount--) {
+		memcpy(iov->iov_base, disk->priv + offset, iov->iov_len);
+
+		sector	+= iov->iov_len >> SECTOR_SHIFT;
+		offset	+= iov->iov_len;
+		total	+= iov->iov_len;
+		iov++;
+	}
+
+	return total;
+}
+
+ssize_t raw_image__write_sector_mmap(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param)
+{
+	u64 offset = sector << SECTOR_SHIFT;
+	ssize_t total = 0;
+
+	while (iovcount--) {
+		memcpy(disk->priv + offset, iov->iov_base, iov->iov_len);
+
+		sector	+= iov->iov_len >> SECTOR_SHIFT;
+		offset	+= iov->iov_len;
+		total	+= iov->iov_len;
+		iov++;
+	}
+
+	return total;
+}
+
+int raw_image__close(struct disk_image *disk)
+{
+	int ret = 0;
+
+	if (disk->priv != MAP_FAILED)
+		ret = munmap(disk->priv, disk->size);
+
+	close(disk->evt);
+
+#ifdef CONFIG_HAS_VIRTIO
+	io_destroy(disk->ctx);
+#endif
+
+	return ret;
+}
+
+/*
+ * multiple buffer based disk image operations
+ */
+static struct disk_image_operations raw_image_regular_ops = {
+	.read_sector	= raw_image__read_sector,
+	.write_sector	= raw_image__write_sector,
+};
+
+struct disk_image_operations ro_ops = {
+	.read_sector	= raw_image__read_sector_mmap,
+	.write_sector	= raw_image__write_sector_mmap,
+	.close		= raw_image__close,
+};
+
+struct disk_image_operations ro_ops_nowrite = {
+	.read_sector	= raw_image__read_sector,
+};
+
+struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
+{
+	struct disk_image *disk;
+
+	if (readonly) {
+		/*
+		 * Use mmap's MAP_PRIVATE to implement non-persistent write
+		 * FIXME: This does not work on 32-bit host.
+		 */
+		struct disk_image *disk;
+
+		disk = disk_image__new(fd, st->st_size, &ro_ops, DISK_IMAGE_MMAP);
+		if (IS_ERR_OR_NULL(disk)) {
+			disk = disk_image__new(fd, st->st_size, &ro_ops_nowrite, DISK_IMAGE_REGULAR);
+#ifdef CONFIG_HAS_AIO
+			if (!IS_ERR_OR_NULL(disk))
+				disk->async = 1;
+#endif
+		}
+
+		return disk;
+	} else {
+		/*
+		 * Use read/write instead of mmap
+		 */
+		disk = disk_image__new(fd, st->st_size, &raw_image_regular_ops, DISK_IMAGE_REGULAR);
+#ifdef CONFIG_HAS_AIO
+		if (!IS_ERR_OR_NULL(disk))
+			disk->async = 1;
+#endif
+		return disk;
+	}
+}
diff --git a/tools/kvm/framebuffer.c b/tools/kvm/framebuffer.c
new file mode 100644
index 0000000..e15b717
--- /dev/null
+++ b/tools/kvm/framebuffer.c
@@ -0,0 +1,75 @@
+#include "kvm/framebuffer.h"
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+static LIST_HEAD(framebuffers);
+
+struct framebuffer *fb__register(struct framebuffer *fb)
+{
+	INIT_LIST_HEAD(&fb->node);
+	list_add(&fb->node, &framebuffers);
+
+	return fb;
+}
+
+int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
+{
+	if (fb->nr_targets >= FB_MAX_TARGETS)
+		return -ENOSPC;
+
+	fb->targets[fb->nr_targets++] = ops;
+
+	return 0;
+}
+
+static int start_targets(struct framebuffer *fb)
+{
+	unsigned long i;
+
+	for (i = 0; i < fb->nr_targets; i++) {
+		struct fb_target_operations *ops = fb->targets[i];
+		int err = 0;
+
+		if (ops->start)
+			err = ops->start(fb);
+
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+int fb__start(void)
+{
+	struct framebuffer *fb;
+
+	list_for_each_entry(fb, &framebuffers, node) {
+		int err;
+
+		err = start_targets(fb);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+void fb__stop(void)
+{
+	struct framebuffer *fb;
+
+	list_for_each_entry(fb, &framebuffers, node) {
+		u32 i;
+
+		for (i = 0; i < fb->nr_targets; i++)
+			if (fb->targets[i]->stop)
+				fb->targets[i]->stop(fb);
+
+		munmap(fb->mem, fb->mem_size);
+	}
+}
diff --git a/tools/kvm/guest/init.c b/tools/kvm/guest/init.c
new file mode 100644
index 0000000..032a261
--- /dev/null
+++ b/tools/kvm/guest/init.c
@@ -0,0 +1,38 @@
+/*
+ * This is a simple init for shared rootfs guests. This part should be limited
+ * to doing mounts and running stage 2 of the init process.
+ */
+#include <sys/mount.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+static int run_process(char *filename)
+{
+	char *new_argv[] = { filename, NULL };
+	char *new_env[] = { "TERM=linux", NULL };
+
+	return execve(filename, new_argv, new_env);
+}
+
+static void do_mounts(void)
+{
+	mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L");
+	mount("", "/sys", "sysfs", 0, NULL);
+	mount("proc", "/proc", "proc", 0, NULL);
+	mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
+}
+
+int main(int argc, char *argv[])
+{
+	puts("Mounting...");
+
+	do_mounts();
+
+	run_process("/virt/init_stage2");
+
+	printf("Init failed: %s\n", strerror(errno));
+
+	return 0;
+}
diff --git a/tools/kvm/guest/init_stage2.c b/tools/kvm/guest/init_stage2.c
new file mode 100644
index 0000000..5f93894
--- /dev/null
+++ b/tools/kvm/guest/init_stage2.c
@@ -0,0 +1,55 @@
+/*
+ * This is a stage 2 of the init. This part should do all the heavy
+ * lifting such as setting up the console and calling /bin/sh.
+ */
+#include <sys/mount.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <linux/reboot.h>
+
+static int run_process(char *filename)
+{
+	char *new_argv[] = { filename, NULL };
+	char *new_env[] = { "TERM=linux", NULL };
+
+	return execve(filename, new_argv, new_env);
+}
+
+static int run_process_sandbox(char *filename)
+{
+	char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
+	char *new_env[] = { "TERM=linux", NULL };
+
+	return execve(filename, new_argv, new_env);
+}
+
+int main(int argc, char *argv[])
+{
+	pid_t child;
+	int status;
+
+	/* get session leader */
+	setsid();
+
+	/* set controlling terminal */
+	ioctl(0, TIOCSCTTY, 1);
+
+	child = fork();
+	if (child < 0) {
+		printf("Fatal: fork() failed with %d\n", child);
+		return 0;
+	} else if (child == 0) {
+		if (access("/virt/sandbox.sh", R_OK) == 0)
+			run_process_sandbox("/bin/sh");
+		else
+			run_process("/bin/sh");
+	} else {
+		waitpid(child, &status, 0);
+	}
+
+	reboot(LINUX_REBOOT_CMD_RESTART);
+
+	return 0;
+}
diff --git a/tools/kvm/guest/passwd b/tools/kvm/guest/passwd
new file mode 100644
index 0000000..eb85a55
--- /dev/null
+++ b/tools/kvm/guest/passwd
@@ -0,0 +1 @@
+root:x:0:0:root:/root:/bin/sh
diff --git a/tools/kvm/guest_compat.c b/tools/kvm/guest_compat.c
new file mode 100644
index 0000000..43b9035
--- /dev/null
+++ b/tools/kvm/guest_compat.c
@@ -0,0 +1,99 @@
+#include "kvm/guest_compat.h"
+
+#include "kvm/mutex.h"
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+struct compat_message {
+	int id;
+	char *title;
+	char *desc;
+
+	struct list_head list;
+};
+
+static int id;
+static DEFINE_MUTEX(compat_mtx);
+static LIST_HEAD(messages);
+
+static void compat__free(struct compat_message *msg)
+{
+	free(msg->title);
+	free(msg->desc);
+	free(msg);
+}
+
+int compat__add_message(const char *title, const char *desc)
+{
+	struct compat_message *msg;
+	int msg_id;
+
+	msg = malloc(sizeof(*msg));
+	if (msg == NULL)
+		goto cleanup;
+
+	msg->title = strdup(title);
+	msg->desc = strdup(desc);
+
+	if (msg->title == NULL || msg->desc == NULL)
+		goto cleanup;
+
+	mutex_lock(&compat_mtx);
+
+	msg->id = msg_id = id++;
+	list_add_tail(&msg->list, &messages);
+
+	mutex_unlock(&compat_mtx);
+
+	return msg_id;
+
+cleanup:
+	if (msg)
+		compat__free(msg);
+
+	return -ENOMEM;
+}
+
+int compat__remove_message(int id)
+{
+	struct compat_message *pos, *n;
+
+	mutex_lock(&compat_mtx);
+
+	list_for_each_entry_safe(pos, n, &messages, list) {
+		if (pos->id == id) {
+			list_del(&pos->list);
+			compat__free(pos);
+
+			mutex_unlock(&compat_mtx);
+
+			return 0;
+		}
+	}
+
+	mutex_unlock(&compat_mtx);
+
+	return -ENOENT;
+}
+
+int compat__print_all_messages(void)
+{
+	mutex_lock(&compat_mtx);
+
+	while (!list_empty(&messages)) {
+		struct compat_message *msg;
+
+		msg = list_first_entry(&messages, struct compat_message, list);
+
+		printf("\n\n*** Compatibility Warning ***\n\n\t%s\n\n%s\n",
+			msg->title, msg->desc);
+
+		list_del(&msg->list);
+		compat__free(msg);
+	}
+
+	mutex_unlock(&compat_mtx);
+
+	return 0;
+}
diff --git a/tools/kvm/hw/i8042.c b/tools/kvm/hw/i8042.c
new file mode 100644
index 0000000..3a36425
--- /dev/null
+++ b/tools/kvm/hw/i8042.c
@@ -0,0 +1,348 @@
+#include "kvm/read-write.h"
+#include "kvm/ioport.h"
+#include "kvm/mutex.h"
+#include "kvm/util.h"
+#include "kvm/term.h"
+#include "kvm/kvm.h"
+#include "kvm/i8042.h"
+#include "kvm/kvm-cpu.h"
+
+#include <stdint.h>
+
+/*
+ * IRQs
+ */
+#define KBD_IRQ			1
+#define AUX_IRQ			12
+
+/*
+ * Registers
+ */
+#define I8042_DATA_REG		0x60
+#define I8042_COMMAND_REG	0x64
+
+/*
+ * Commands
+ */
+#define I8042_CMD_CTL_RCTR	0x20
+#define I8042_CMD_CTL_WCTR	0x60
+#define I8042_CMD_AUX_LOOP	0xD3
+#define I8042_CMD_AUX_SEND	0xD4
+#define I8042_CMD_AUX_TEST	0xA9
+#define I8042_CMD_AUX_DISABLE	0xA7
+#define I8042_CMD_AUX_ENABLE	0xA8
+#define I8042_CMD_SYSTEM_RESET	0xFE
+
+#define RESPONSE_ACK		0xFA
+
+#define MODE_DISABLE_AUX	0x20
+
+#define AUX_ENABLE_REPORTING	0x20
+#define AUX_SCALING_FLAG	0x10
+#define AUX_DEFAULT_RESOLUTION	0x2
+#define AUX_DEFAULT_SAMPLE	100
+
+/*
+ * Status register bits
+ */
+#define I8042_STR_AUXDATA	0x20
+#define I8042_STR_KEYLOCK	0x10
+#define I8042_STR_CMDDAT	0x08
+#define I8042_STR_MUXERR	0x04
+#define I8042_STR_OBF		0x01
+
+#define KBD_MODE_KBD_INT	0x01
+#define KBD_MODE_SYS		0x02
+
+#define QUEUE_SIZE		128
+
+/*
+ * This represents the current state of the PS/2 keyboard system,
+ * including the AUX device (the mouse)
+ */
+struct kbd_state {
+	struct kvm		*kvm;
+
+	char			kq[QUEUE_SIZE];	/* Keyboard queue */
+	int			kread, kwrite;	/* Indexes into the queue */
+	int			kcount;		/* number of elements in queue */
+
+	char			mq[QUEUE_SIZE];
+	int			mread, mwrite;
+	int			mcount;
+
+	u8			mstatus;	/* Mouse status byte */
+	u8			mres;		/* Current mouse resolution */
+	u8			msample;	/* Current mouse samples/second */
+
+	u8			mode;		/* i8042 mode register */
+	u8			status;		/* i8042 status register */
+	/*
+	 * Some commands (on port 0x64) have arguments;
+	 * we store the command here while we wait for the argument
+	 */
+	u32			write_cmd;
+};
+
+static struct kbd_state		state;
+
+/*
+ * If there are packets to be read, set the appropriate IRQs high
+ */
+static void kbd_update_irq(void)
+{
+	u8 klevel = 0;
+	u8 mlevel = 0;
+
+	/* First, clear the kbd and aux output buffer full bits */
+	state.status &= ~(I8042_STR_OBF | I8042_STR_AUXDATA);
+
+	if (state.kcount > 0) {
+		state.status |= I8042_STR_OBF;
+		klevel = 1;
+	}
+
+	/* Keyboard has higher priority than mouse */
+	if (klevel == 0 && state.mcount != 0) {
+		state.status |= I8042_STR_OBF | I8042_STR_AUXDATA;
+		mlevel = 1;
+	}
+
+	kvm__irq_line(state.kvm, KBD_IRQ, klevel);
+	kvm__irq_line(state.kvm, AUX_IRQ, mlevel);
+}
+
+/*
+ * Add a byte to the mouse queue, then set IRQs
+ */
+void mouse_queue(u8 c)
+{
+	if (state.mcount >= QUEUE_SIZE)
+		return;
+
+	state.mq[state.mwrite++ % QUEUE_SIZE] = c;
+
+	state.mcount++;
+	kbd_update_irq();
+}
+
+/*
+ * Add a byte to the keyboard queue, then set IRQs
+ */
+void kbd_queue(u8 c)
+{
+	if (state.kcount >= QUEUE_SIZE)
+		return;
+
+	state.kq[state.kwrite++ % QUEUE_SIZE] = c;
+
+	state.kcount++;
+	kbd_update_irq();
+}
+
+static void kbd_write_command(struct kvm *kvm, u8 val)
+{
+	switch (val) {
+	case I8042_CMD_CTL_RCTR:
+		kbd_queue(state.mode);
+		break;
+	case I8042_CMD_CTL_WCTR:
+	case I8042_CMD_AUX_SEND:
+	case I8042_CMD_AUX_LOOP:
+		state.write_cmd = val;
+		break;
+	case I8042_CMD_AUX_TEST:
+		/* 0 means we're a normal PS/2 mouse */
+		mouse_queue(0);
+		break;
+	case I8042_CMD_AUX_DISABLE:
+		state.mode |= MODE_DISABLE_AUX;
+		break;
+	case I8042_CMD_AUX_ENABLE:
+		state.mode &= ~MODE_DISABLE_AUX;
+		break;
+	case I8042_CMD_SYSTEM_RESET:
+		kvm_cpu__reboot();
+		break;
+	default:
+		break;
+	}
+}
+
+/*
+ * Called when the OS reads from port 0x60 (PS/2 data)
+ */
+static u32 kbd_read_data(void)
+{
+	u32 ret;
+	int i;
+
+	if (state.kcount != 0) {
+		/* Keyboard data gets read first */
+		ret = state.kq[state.kread++ % QUEUE_SIZE];
+		state.kcount--;
+		kvm__irq_line(state.kvm, KBD_IRQ, 0);
+		kbd_update_irq();
+	} else if (state.mcount > 0) {
+		/* Followed by the mouse */
+		ret = state.mq[state.mread++ % QUEUE_SIZE];
+		state.mcount--;
+		kvm__irq_line(state.kvm, AUX_IRQ, 0);
+		kbd_update_irq();
+	} else if (state.kcount == 0) {
+		i = state.kread - 1;
+		if (i < 0)
+			i = QUEUE_SIZE;
+		ret = state.kq[i];
+	}
+	return ret;
+}
+
+/*
+ * Called when the OS read from port 0x64, the command port
+ */
+static u32 kbd_read_status(void)
+{
+	return (u32)state.status;
+}
+
+/*
+ * Called when the OS writes to port 0x60 (data port)
+ * Things written here are generally arguments to commands previously
+ * written to port 0x64 and stored in state.write_cmd
+ */
+static void kbd_write_data(u32 val)
+{
+	switch (state.write_cmd) {
+	case I8042_CMD_CTL_WCTR:
+		state.mode = val;
+		kbd_update_irq();
+		break;
+	case I8042_CMD_AUX_LOOP:
+		mouse_queue(val);
+		mouse_queue(RESPONSE_ACK);
+		break;
+	case I8042_CMD_AUX_SEND:
+		/* The OS wants to send a command to the mouse */
+		mouse_queue(RESPONSE_ACK);
+		switch (val) {
+		case 0xe6:
+			/* set scaling = 1:1 */
+			state.mstatus &= ~AUX_SCALING_FLAG;
+			break;
+		case 0xe8:
+			/* set resolution */
+			state.mres = val;
+			break;
+		case 0xe9:
+			/* Report mouse status/config */
+			mouse_queue(state.mstatus);
+			mouse_queue(state.mres);
+			mouse_queue(state.msample);
+			break;
+		case 0xf2:
+			/* send ID */
+			mouse_queue(0); /* normal mouse */
+			break;
+		case 0xf3:
+			/* set sample rate */
+			state.msample = val;
+			break;
+		case 0xf4:
+			/* enable reporting */
+			state.mstatus |= AUX_ENABLE_REPORTING;
+			break;
+		case 0xf5:
+			state.mstatus &= ~AUX_ENABLE_REPORTING;
+			break;
+		case 0xf6:
+			/* set defaults, just fall through to reset */
+		case 0xff:
+			/* reset */
+			state.mstatus = 0x0;
+			state.mres = AUX_DEFAULT_RESOLUTION;
+			state.msample = AUX_DEFAULT_SAMPLE;
+			break;
+		default:
+			break;
+	}
+	break;
+	case 0:
+		/* Just send the ID */
+		kbd_queue(RESPONSE_ACK);
+		kbd_queue(0xab);
+		kbd_queue(0x41);
+		kbd_update_irq();
+		break;
+	default:
+		/* Yeah whatever */
+		break;
+	}
+	state.write_cmd = 0;
+}
+
+static void kbd_reset(void)
+{
+	state = (struct kbd_state) {
+		.status		= I8042_STR_MUXERR | I8042_STR_CMDDAT | I8042_STR_KEYLOCK, /* 0x1c */
+		.mode		= KBD_MODE_KBD_INT | KBD_MODE_SYS, /* 0x3 */
+		.mres		= AUX_DEFAULT_RESOLUTION,
+		.msample	= AUX_DEFAULT_SAMPLE,
+	};
+}
+
+/*
+ * Called when the OS has written to one of the keyboard's ports (0x60 or 0x64)
+ */
+static bool kbd_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	switch (port) {
+	case I8042_COMMAND_REG: {
+		u8 value = kbd_read_status();
+		ioport__write8(data, value);
+		break;
+	}
+	case I8042_DATA_REG: {
+		u32 value = kbd_read_data();
+		ioport__write32(data, value);
+		break;
+	}
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static bool kbd_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	switch (port) {
+	case I8042_COMMAND_REG: {
+		u8 value = ioport__read8(data);
+		kbd_write_command(kvm, value);
+		break;
+	}
+	case I8042_DATA_REG: {
+		u32 value = ioport__read32(data);
+		kbd_write_data(value);
+		break;
+	}
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static struct ioport_operations kbd_ops = {
+	.io_in		= kbd_in,
+	.io_out		= kbd_out,
+};
+
+void kbd__init(struct kvm *kvm)
+{
+	kbd_reset();
+	state.kvm = kvm;
+	ioport__register(I8042_DATA_REG, &kbd_ops, 2, NULL);
+	ioport__register(I8042_COMMAND_REG, &kbd_ops, 2, NULL);
+}
diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
new file mode 100644
index 0000000..ac2d264
--- /dev/null
+++ b/tools/kvm/hw/pci-shmem.c
@@ -0,0 +1,268 @@
+#include "kvm/pci-shmem.h"
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/irq.h"
+#include "kvm/kvm.h"
+#include "kvm/pci.h"
+#include "kvm/util.h"
+#include "kvm/ioport.h"
+#include "kvm/ioeventfd.h"
+
+#include <linux/kvm.h>
+#include <linux/byteorder.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+static struct pci_device_header pci_shmem_pci_device = {
+	.vendor_id	= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+	.device_id	= cpu_to_le16(0x1110),
+	.header_type	= PCI_HEADER_TYPE_NORMAL,
+	.class[2]	= 0xFF,	/* misc pci device */
+	.status		= cpu_to_le16(PCI_STATUS_CAP_LIST),
+	.capabilities	= (void *)&pci_shmem_pci_device.msix - (void *)&pci_shmem_pci_device,
+	.msix.cap	= PCI_CAP_ID_MSIX,
+	.msix.ctrl	= cpu_to_le16(1),
+	.msix.table_offset = cpu_to_le32(1),		/* Use BAR 1 */
+	.msix.pba_offset = cpu_to_le32(0x1001),		/* Use BAR 1 */
+};
+
+/* registers for the Inter-VM shared memory device */
+enum ivshmem_registers {
+	INTRMASK = 0,
+	INTRSTATUS = 4,
+	IVPOSITION = 8,
+	DOORBELL = 12,
+};
+
+static struct shmem_info *shmem_region;
+static u16 ivshmem_registers;
+static int local_fd;
+static u32 local_id;
+static u64 msix_block;
+static u64 msix_pba;
+static struct msix_table msix_table[2];
+
+int pci_shmem__register_mem(struct shmem_info *si)
+{
+	if (shmem_region == NULL) {
+		shmem_region = si;
+	} else {
+		pr_warning("only single shmem currently avail. ignoring.\n");
+		free(si);
+	}
+	return 0;
+}
+
+static bool shmem_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	u16 offset = port - ivshmem_registers;
+
+	switch (offset) {
+	case INTRMASK:
+		break;
+	case INTRSTATUS:
+		break;
+	case IVPOSITION:
+		ioport__write32(data, local_id);
+		break;
+	case DOORBELL:
+		break;
+	};
+
+	return true;
+}
+
+static bool shmem_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	u16 offset = port - ivshmem_registers;
+
+	switch (offset) {
+	case INTRMASK:
+		break;
+	case INTRSTATUS:
+		break;
+	case IVPOSITION:
+		break;
+	case DOORBELL:
+		break;
+	};
+
+	return true;
+}
+
+static struct ioport_operations shmem_pci__io_ops = {
+	.io_in	= shmem_pci__io_in,
+	.io_out	= shmem_pci__io_out,
+};
+
+static void callback_mmio_msix(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
+{
+	void *mem;
+
+	if (addr - msix_block < 0x1000)
+		mem = &msix_table;
+	else
+		mem = &msix_pba;
+
+	if (is_write)
+		memcpy(mem + addr - msix_block, data, len);
+	else
+		memcpy(data, mem + addr - msix_block, len);
+}
+
+/*
+ * Return an irqfd which can be used by other guests to signal this guest
+ * whenever they need to poke it
+ */
+int pci_shmem__get_local_irqfd(struct kvm *kvm)
+{
+	int fd, gsi, r;
+	struct kvm_irqfd irqfd;
+
+	if (local_fd == 0) {
+		fd = eventfd(0, 0);
+		if (fd < 0)
+			return fd;
+
+		if (pci_shmem_pci_device.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE)) {
+			gsi = irq__add_msix_route(kvm, &msix_table[0].msg);
+		} else {
+			gsi = pci_shmem_pci_device.irq_line;
+		}
+
+		irqfd = (struct kvm_irqfd) {
+			.fd = fd,
+			.gsi = gsi,
+		};
+
+		r = ioctl(kvm->vm_fd, KVM_IRQFD, &irqfd);
+		if (r < 0)
+			return r;
+
+		local_fd = fd;
+	}
+
+	return local_fd;
+}
+
+/*
+ * Connect a new client to ivshmem by adding the appropriate datamatch
+ * to the DOORBELL
+ */
+int pci_shmem__add_client(struct kvm *kvm, u32 id, int fd)
+{
+	struct kvm_ioeventfd ioevent;
+
+	ioevent = (struct kvm_ioeventfd) {
+		.addr		= ivshmem_registers + DOORBELL,
+		.len		= sizeof(u32),
+		.datamatch	= id,
+		.fd		= fd,
+		.flags		= KVM_IOEVENTFD_FLAG_PIO | KVM_IOEVENTFD_FLAG_DATAMATCH,
+	};
+
+	return ioctl(kvm->vm_fd, KVM_IOEVENTFD, &ioevent);
+}
+
+/*
+ * Remove a client connected to ivshmem by removing the appropriate datamatch
+ * from the DOORBELL
+ */
+int pci_shmem__remove_client(struct kvm *kvm, u32 id)
+{
+	struct kvm_ioeventfd ioevent;
+
+	ioevent = (struct kvm_ioeventfd) {
+		.addr		= ivshmem_registers + DOORBELL,
+		.len		= sizeof(u32),
+		.datamatch	= id,
+		.flags		= KVM_IOEVENTFD_FLAG_PIO
+				| KVM_IOEVENTFD_FLAG_DATAMATCH
+				| KVM_IOEVENTFD_FLAG_DEASSIGN,
+	};
+
+	return ioctl(kvm->vm_fd, KVM_IOEVENTFD, &ioevent);
+}
+
+static void *setup_shmem(const char *key, size_t len, int creating)
+{
+	int fd;
+	int rtn;
+	void *mem;
+	int flag = O_RDWR;
+
+	if (creating)
+		flag |= O_CREAT;
+
+	fd = shm_open(key, flag, S_IRUSR | S_IWUSR);
+	if (fd < 0) {
+		pr_warning("Failed to open shared memory file %s\n", key);
+		return NULL;
+	}
+
+	if (creating) {
+		rtn = ftruncate(fd, (off_t) len);
+		if (rtn < 0)
+			pr_warning("Can't ftruncate(fd,%zu)\n", len);
+	}
+	mem = mmap(NULL, len,
+		   PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NORESERVE, fd, 0);
+	if (mem == MAP_FAILED) {
+		pr_warning("Failed to mmap shared memory file");
+		mem = NULL;
+	}
+	close(fd);
+
+	return mem;
+}
+
+int pci_shmem__init(struct kvm *kvm)
+{
+	u8 dev, line, pin;
+	char *mem;
+	int r;
+
+	if (shmem_region == 0)
+		return 0;
+
+	/* Register good old INTx */
+	if (irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, &dev, &pin, &line) < 0)
+		return 0;
+
+	pci_shmem_pci_device.irq_pin = pin;
+	pci_shmem_pci_device.irq_line = line;
+
+	/* Register MMIO space for MSI-X */
+	r = ioport__register(IOPORT_EMPTY, &shmem_pci__io_ops, IOPORT_SIZE, NULL);
+	if (r < 0)
+		return r;
+	ivshmem_registers = (u16)r;
+
+	msix_block = pci_get_io_space_block(0x1010);
+	kvm__register_mmio(kvm, msix_block, 0x1010, false, callback_mmio_msix, NULL);
+
+	/*
+	 * This registers 3 BARs:
+	 *
+	 * 0 - ivshmem registers
+	 * 1 - MSI-X MMIO space
+	 * 2 - Shared memory block
+	 */
+	pci_shmem_pci_device.bar[0] = cpu_to_le32(ivshmem_registers | PCI_BASE_ADDRESS_SPACE_IO);
+	pci_shmem_pci_device.bar_size[0] = shmem_region->size;
+	pci_shmem_pci_device.bar[1] = cpu_to_le32(msix_block | PCI_BASE_ADDRESS_SPACE_MEMORY);
+	pci_shmem_pci_device.bar_size[1] = 0x1010;
+	pci_shmem_pci_device.bar[2] = cpu_to_le32(shmem_region->phys_addr | PCI_BASE_ADDRESS_SPACE_MEMORY);
+	pci_shmem_pci_device.bar_size[2] = shmem_region->size;
+
+	pci__register(&pci_shmem_pci_device, dev);
+
+	/* Open shared memory and plug it into the guest */
+	mem = setup_shmem(shmem_region->handle, shmem_region->size,
+				shmem_region->create);
+	if (mem == NULL)
+		return 0;
+	kvm__register_mem(kvm, shmem_region->phys_addr, shmem_region->size,
+			  mem);
+	return 1;
+}
diff --git a/tools/kvm/hw/rtc.c b/tools/kvm/hw/rtc.c
new file mode 100644
index 0000000..b4f9f1f
--- /dev/null
+++ b/tools/kvm/hw/rtc.c
@@ -0,0 +1,137 @@
+#include "kvm/rtc.h"
+
+#include "kvm/ioport.h"
+#include "kvm/kvm.h"
+
+#include <time.h>
+
+/*
+ * MC146818 RTC registers
+ */
+#define RTC_SECONDS			0x00
+#define RTC_SECONDS_ALARM		0x01
+#define RTC_MINUTES			0x02
+#define RTC_MINUTES_ALARM		0x03
+#define RTC_HOURS			0x04
+#define RTC_HOURS_ALARM			0x05
+#define RTC_DAY_OF_WEEK			0x06
+#define RTC_DAY_OF_MONTH		0x07
+#define RTC_MONTH			0x08
+#define RTC_YEAR			0x09
+
+#define RTC_REG_A			0x0A
+#define RTC_REG_B			0x0B
+#define RTC_REG_C			0x0C
+#define RTC_REG_D			0x0D
+
+struct rtc_device {
+	u8			cmos_idx;
+	u8			cmos_data[128];
+};
+
+static struct rtc_device	rtc;
+
+static inline unsigned char bin2bcd(unsigned val)
+{
+	return ((val / 10) << 4) + val % 10;
+}
+
+static bool cmos_ram_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	struct tm *tm;
+	time_t ti;
+
+	time(&ti);
+
+	tm = gmtime(&ti);
+
+	switch (rtc.cmos_idx) {
+	case RTC_SECONDS:
+		ioport__write8(data, bin2bcd(tm->tm_sec));
+		break;
+	case RTC_MINUTES:
+		ioport__write8(data, bin2bcd(tm->tm_min));
+		break;
+	case RTC_HOURS:
+		ioport__write8(data, bin2bcd(tm->tm_hour));
+		break;
+	case RTC_DAY_OF_WEEK:
+		ioport__write8(data, bin2bcd(tm->tm_wday + 1));
+		break;
+	case RTC_DAY_OF_MONTH:
+		ioport__write8(data, bin2bcd(tm->tm_mday));
+		break;
+	case RTC_MONTH:
+		ioport__write8(data, bin2bcd(tm->tm_mon + 1));
+		break;
+	case RTC_YEAR:
+		ioport__write8(data, bin2bcd(tm->tm_year));
+		break;
+	default:
+		ioport__write8(data, rtc.cmos_data[rtc.cmos_idx]);
+		break;
+	}
+
+	return true;
+}
+
+static bool cmos_ram_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	switch (rtc.cmos_idx) {
+	case RTC_REG_C:
+	case RTC_REG_D:
+		/* Read-only */
+		break;
+	default:
+		rtc.cmos_data[rtc.cmos_idx] = ioport__read8(data);
+		break;
+	}
+
+	return true;
+}
+
+static struct ioport_operations cmos_ram_data_ioport_ops = {
+	.io_out		= cmos_ram_data_out,
+	.io_in		= cmos_ram_data_in,
+};
+
+static bool cmos_ram_index_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	u8 value = ioport__read8(data);
+
+	kvm->nmi_disabled	= value & (1UL << 7);
+	rtc.cmos_idx		= value & ~(1UL << 7);
+
+	return true;
+}
+
+static struct ioport_operations cmos_ram_index_ioport_ops = {
+	.io_out		= cmos_ram_index_out,
+};
+
+int rtc__init(struct kvm *kvm)
+{
+	int r = 0;
+
+	/* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */
+	r = ioport__register(0x0070, &cmos_ram_index_ioport_ops, 1, NULL);
+	if (r < 0)
+		return r;
+
+	r = ioport__register(0x0071, &cmos_ram_data_ioport_ops, 1, NULL);
+	if (r < 0) {
+		ioport__unregister(0x0071);
+		return r;
+	}
+
+	return r;
+}
+
+int rtc__exit(struct kvm *kvm)
+{
+	/* PORT 0070-007F - CMOS RAM/RTC (REAL TIME CLOCK) */
+	ioport__unregister(0x0070);
+	ioport__unregister(0x0071);
+
+	return 0;
+}
\ No newline at end of file
diff --git a/tools/kvm/hw/serial.c b/tools/kvm/hw/serial.c
new file mode 100644
index 0000000..852aea4
--- /dev/null
+++ b/tools/kvm/hw/serial.c
@@ -0,0 +1,447 @@
+#include "kvm/8250-serial.h"
+
+#include "kvm/read-write.h"
+#include "kvm/ioport.h"
+#include "kvm/mutex.h"
+#include "kvm/util.h"
+#include "kvm/term.h"
+#include "kvm/kvm.h"
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <pthread.h>
+
+/*
+ * This fakes a U6_16550A. The fifo len needs to be 64 as the kernel
+ * expects that for autodetection.
+ */
+#define FIFO_LEN		64
+#define FIFO_MASK		(FIFO_LEN - 1)
+
+#define UART_IIR_TYPE_BITS	0xc0
+
+struct serial8250_device {
+	pthread_mutex_t		mutex;
+	u8			id;
+
+	u16			iobase;
+	u8			irq;
+	u8			irq_state;
+	int			txcnt;
+	int			rxcnt;
+	int			rxdone;
+	char			txbuf[FIFO_LEN];
+	char			rxbuf[FIFO_LEN];
+
+	u8			dll;
+	u8			dlm;
+	u8			iir;
+	u8			ier;
+	u8			fcr;
+	u8			lcr;
+	u8			mcr;
+	u8			lsr;
+	u8			msr;
+	u8			scr;
+};
+
+#define SERIAL_REGS_SETTING \
+	.iir			= UART_IIR_NO_INT, \
+	.lsr			= UART_LSR_TEMT | UART_LSR_THRE, \
+	.msr			= UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS, \
+	.mcr			= UART_MCR_OUT2,
+
+static struct serial8250_device devices[] = {
+	/* ttyS0 */
+	[0]	= {
+		.mutex			= PTHREAD_MUTEX_INITIALIZER,
+
+		.id			= 0,
+		.iobase			= 0x3f8,
+		.irq			= 4,
+
+		SERIAL_REGS_SETTING
+	},
+	/* ttyS1 */
+	[1]	= {
+		.mutex			= PTHREAD_MUTEX_INITIALIZER,
+
+		.id			= 1,
+		.iobase			= 0x2f8,
+		.irq			= 3,
+
+		SERIAL_REGS_SETTING
+	},
+	/* ttyS2 */
+	[2]	= {
+		.mutex			= PTHREAD_MUTEX_INITIALIZER,
+
+		.id			= 2,
+		.iobase			= 0x3e8,
+		.irq			= 4,
+
+		SERIAL_REGS_SETTING
+	},
+	/* ttyS3 */
+	[3]	= {
+		.mutex			= PTHREAD_MUTEX_INITIALIZER,
+
+		.id			= 3,
+		.iobase			= 0x2e8,
+		.irq			= 3,
+
+		SERIAL_REGS_SETTING
+	},
+};
+
+static void serial8250_flush_tx(struct serial8250_device *dev)
+{
+	dev->lsr |= UART_LSR_TEMT | UART_LSR_THRE;
+
+	if (dev->txcnt) {
+		term_putc(CONSOLE_8250, dev->txbuf, dev->txcnt, dev->id);
+		dev->txcnt = 0;
+	}
+}
+
+static void serial8250_update_irq(struct kvm *kvm, struct serial8250_device *dev)
+{
+	u8 iir = 0;
+
+	/* Handle clear rx */
+	if (dev->lcr & UART_FCR_CLEAR_RCVR) {
+		dev->lcr &= ~UART_FCR_CLEAR_RCVR;
+		dev->rxcnt = dev->rxdone = 0;
+		dev->lsr &= ~UART_LSR_DR;
+	}
+
+	/* Handle clear tx */
+	if (dev->lcr & UART_FCR_CLEAR_XMIT) {
+		dev->lcr &= ~UART_FCR_CLEAR_XMIT;
+		dev->txcnt = 0;
+		dev->lsr |= UART_LSR_TEMT | UART_LSR_THRE;
+	}
+
+	/* Data ready and rcv interrupt enabled ? */
+	if ((dev->ier & UART_IER_RDI) && (dev->lsr & UART_LSR_DR))
+		iir |= UART_IIR_RDI;
+
+	/* Transmitter empty and interrupt enabled ? */
+	if ((dev->ier & UART_IER_THRI) && (dev->lsr & UART_LSR_TEMT))
+		iir |= UART_IIR_THRI;
+
+	/* Now update the irq line, if necessary */
+	if (!iir) {
+		dev->iir = UART_IIR_NO_INT;
+		if (dev->irq_state)
+			kvm__irq_line(kvm, dev->irq, 0);
+	} else {
+		dev->iir = iir;
+		if (!dev->irq_state)
+			kvm__irq_line(kvm, dev->irq, 1);
+	}
+	dev->irq_state = iir;
+
+	/*
+	 * If the kernel disabled the tx interrupt, we know that there
+	 * is nothing more to transmit, so we can reset our tx logic
+	 * here.
+	 */
+	if (!(dev->ier & UART_IER_THRI))
+		serial8250_flush_tx(dev);
+}
+
+#define SYSRQ_PENDING_NONE		0
+#define SYSRQ_PENDING_BREAK		1
+
+static int sysrq_pending;
+
+static void serial8250__sysrq(struct kvm *kvm, struct serial8250_device *dev)
+{
+	dev->lsr |= UART_LSR_DR | UART_LSR_BI;
+	dev->rxbuf[dev->rxcnt++] = 'p';
+	sysrq_pending	= SYSRQ_PENDING_NONE;
+}
+
+static void serial8250__receive(struct kvm *kvm, struct serial8250_device *dev,
+				bool handle_sysrq)
+{
+	int c;
+
+	/*
+	 * If the guest transmitted a full fifo, we clear the
+	 * TEMT/THRE bits to let the kernel escape from the 8250
+	 * interrupt handler. We come here only once a ms, so that
+	 * should give the kernel the desired pause. That also flushes
+	 * the tx fifo to the terminal.
+	 */
+	serial8250_flush_tx(dev);
+
+	if (dev->mcr & UART_MCR_LOOP)
+		return;
+
+	if ((dev->lsr & UART_LSR_DR) || dev->rxcnt)
+		return;
+
+	if (handle_sysrq && sysrq_pending) {
+		serial8250__sysrq(kvm, dev);
+		return;
+	}
+
+	while (term_readable(CONSOLE_8250, dev->id) &&
+	       dev->rxcnt < FIFO_LEN) {
+
+		c = term_getc(CONSOLE_8250, dev->id);
+
+		if (c < 0)
+			break;
+		dev->rxbuf[dev->rxcnt++] = c;
+		dev->lsr |= UART_LSR_DR;
+	}
+}
+
+void serial8250__update_consoles(struct kvm *kvm)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); i++) {
+		struct serial8250_device *dev = &devices[i];
+
+		mutex_lock(&dev->mutex);
+
+		/* Restrict sysrq injection to the first port */
+		serial8250__receive(kvm, dev, i == 0);
+
+		serial8250_update_irq(kvm, dev);
+
+		mutex_unlock(&dev->mutex);
+	}
+}
+
+void serial8250__inject_sysrq(struct kvm *kvm)
+{
+	sysrq_pending	= SYSRQ_PENDING_BREAK;
+}
+
+static struct serial8250_device *find_device(u16 port)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); i++) {
+		struct serial8250_device *dev = &devices[i];
+
+		if (dev->iobase == (port & ~0x7))
+			return dev;
+	}
+	return NULL;
+}
+
+static bool serial8250_out(struct ioport *ioport, struct kvm *kvm, u16 port,
+			   void *data, int size)
+{
+	struct serial8250_device *dev;
+	u16 offset;
+	bool ret = true;
+	char *addr = data;
+
+	dev = find_device(port);
+	if (!dev)
+		return false;
+
+	mutex_lock(&dev->mutex);
+
+	offset = port - dev->iobase;
+
+	switch (offset) {
+	case UART_TX:
+		if (dev->lcr & UART_LCR_DLAB) {
+			dev->dll = ioport__read8(data);
+			break;
+		}
+
+		/* Loopback mode */
+		if (dev->mcr & UART_MCR_LOOP) {
+			if (dev->rxcnt < FIFO_LEN) {
+				dev->rxbuf[dev->rxcnt++] = *addr;
+				dev->lsr |= UART_LSR_DR;
+			}
+			break;
+		}
+
+		if (dev->txcnt < FIFO_LEN) {
+			dev->txbuf[dev->txcnt++] = *addr;
+			dev->lsr &= ~UART_LSR_TEMT;
+			if (dev->txcnt == FIFO_LEN / 2)
+				dev->lsr &= ~UART_LSR_THRE;
+		} else {
+			/* Should never happpen */
+			dev->lsr &= ~(UART_LSR_TEMT | UART_LSR_THRE);
+		}
+		break;
+	case UART_IER:
+		if (!(dev->lcr & UART_LCR_DLAB))
+			dev->ier = ioport__read8(data) & 0x0f;
+		else
+			dev->dlm = ioport__read8(data);
+		break;
+	case UART_FCR:
+		dev->fcr = ioport__read8(data);
+		break;
+	case UART_LCR:
+		dev->lcr = ioport__read8(data);
+		break;
+	case UART_MCR:
+		dev->mcr = ioport__read8(data);
+		break;
+	case UART_LSR:
+		/* Factory test */
+		break;
+	case UART_MSR:
+		/* Not used */
+		break;
+	case UART_SCR:
+		dev->scr = ioport__read8(data);
+		break;
+	default:
+		ret = false;
+		break;
+	}
+
+	serial8250_update_irq(kvm, dev);
+
+	mutex_unlock(&dev->mutex);
+
+	return ret;
+}
+
+static void serial8250_rx(struct serial8250_device *dev, void *data)
+{
+	if (dev->rxdone == dev->rxcnt)
+		return;
+
+	/* Break issued ? */
+	if (dev->lsr & UART_LSR_BI) {
+		dev->lsr &= ~UART_LSR_BI;
+		ioport__write8(data, 0);
+		return;
+	}
+
+	ioport__write8(data, dev->rxbuf[dev->rxdone++]);
+	if (dev->rxcnt == dev->rxdone) {
+		dev->lsr &= ~UART_LSR_DR;
+		dev->rxcnt = dev->rxdone = 0;
+	}
+}
+
+static bool serial8250_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	struct serial8250_device *dev;
+	u16 offset;
+	bool ret = true;
+
+	dev = find_device(port);
+	if (!dev)
+		return false;
+
+	mutex_lock(&dev->mutex);
+
+	offset = port - dev->iobase;
+
+	switch (offset) {
+	case UART_RX:
+		if (dev->lcr & UART_LCR_DLAB)
+			ioport__write8(data, dev->dll);
+		else
+			serial8250_rx(dev, data);
+		break;
+	case UART_IER:
+		if (dev->lcr & UART_LCR_DLAB)
+			ioport__write8(data, dev->dlm);
+		else
+			ioport__write8(data, dev->ier);
+		break;
+	case UART_IIR:
+		ioport__write8(data, dev->iir | UART_IIR_TYPE_BITS);
+		break;
+	case UART_LCR:
+		ioport__write8(data, dev->lcr);
+		break;
+	case UART_MCR:
+		ioport__write8(data, dev->mcr);
+		break;
+	case UART_LSR:
+		ioport__write8(data, dev->lsr);
+		break;
+	case UART_MSR:
+		ioport__write8(data, dev->msr);
+		break;
+	case UART_SCR:
+		ioport__write8(data, dev->scr);
+		break;
+	default:
+		ret = false;
+		break;
+	}
+
+	serial8250_update_irq(kvm, dev);
+
+	mutex_unlock(&dev->mutex);
+
+	return ret;
+}
+
+static struct ioport_operations serial8250_ops = {
+	.io_in		= serial8250_in,
+	.io_out		= serial8250_out,
+};
+
+static int serial8250__device_init(struct kvm *kvm, struct serial8250_device *dev)
+{
+	int r;
+
+	r = ioport__register(dev->iobase, &serial8250_ops, 8, NULL);
+	kvm__irq_line(kvm, dev->irq, 0);
+
+	return r;
+}
+
+int serial8250__init(struct kvm *kvm)
+{
+	unsigned int i, j;
+	int r = 0;
+
+	for (i = 0; i < ARRAY_SIZE(devices); i++) {
+		struct serial8250_device *dev = &devices[i];
+
+		r = serial8250__device_init(kvm, dev);
+		if (r < 0)
+			goto cleanup;
+	}
+
+	return r;
+cleanup:
+	for (j = 0; j <= i; j++) {
+		struct serial8250_device *dev = &devices[j];
+
+		ioport__unregister(dev->iobase);
+	}
+
+	return r;
+}
+
+int serial8250__exit(struct kvm *kvm)
+{
+	unsigned int i;
+	int r;
+
+	for (i = 0; i < ARRAY_SIZE(devices); i++) {
+		struct serial8250_device *dev = &devices[i];
+
+		r = ioport__unregister(dev->iobase);
+		if (r < 0)
+			return r;
+	}
+
+	return 0;
+}
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
new file mode 100644
index 0000000..757f0a2
--- /dev/null
+++ b/tools/kvm/hw/vesa.c
@@ -0,0 +1,85 @@
+#include "kvm/vesa.h"
+
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/framebuffer.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/ioport.h"
+#include "kvm/util.h"
+#include "kvm/irq.h"
+#include "kvm/kvm.h"
+#include "kvm/pci.h"
+
+#include <linux/byteorder.h>
+#include <sys/mman.h>
+#include <linux/err.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+static bool vesa_pci_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	return true;
+}
+
+static bool vesa_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	return true;
+}
+
+static struct ioport_operations vesa_io_ops = {
+	.io_in			= vesa_pci_io_in,
+	.io_out			= vesa_pci_io_out,
+};
+
+static struct pci_device_header vesa_pci_device = {
+	.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+	.device_id		= cpu_to_le16(PCI_DEVICE_ID_VESA),
+	.header_type		= PCI_HEADER_TYPE_NORMAL,
+	.revision_id		= 0,
+	.class[2]		= 0x03,
+	.subsys_vendor_id	= cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+	.subsys_id		= cpu_to_le16(PCI_SUBSYSTEM_ID_VESA),
+	.bar[1]			= cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY),
+	.bar_size[1]		= VESA_MEM_SIZE,
+};
+
+static struct framebuffer vesafb;
+
+struct framebuffer *vesa__init(struct kvm *kvm)
+{
+	u16 vesa_base_addr;
+	u8 dev, line, pin;
+	char *mem;
+	int r;
+
+	r = irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line);
+	if (r < 0)
+		return ERR_PTR(r);
+
+	r = ioport__register(IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL);
+	if (r < 0)
+		return ERR_PTR(r);
+
+	vesa_pci_device.irq_pin		= pin;
+	vesa_pci_device.irq_line	= line;
+	vesa_base_addr			= (u16)r;
+	vesa_pci_device.bar[0]		= cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO);
+	pci__register(&vesa_pci_device, dev);
+
+	mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
+	if (mem == MAP_FAILED)
+		ERR_PTR(-errno);
+
+	kvm__register_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem);
+
+	vesafb = (struct framebuffer) {
+		.width			= VESA_WIDTH,
+		.height			= VESA_HEIGHT,
+		.depth			= VESA_BPP,
+		.mem			= mem,
+		.mem_addr		= VESA_MEM_ADDR,
+		.mem_size		= VESA_MEM_SIZE,
+	};
+	return fb__register(&vesafb);
+}
diff --git a/tools/kvm/include/asm/hweight.h b/tools/kvm/include/asm/hweight.h
new file mode 100644
index 0000000..1a43977
--- /dev/null
+++ b/tools/kvm/include/asm/hweight.h
@@ -0,0 +1,8 @@
+#ifndef _KVM_ASM_HWEIGHT_H_
+#define _KVM_ASM_HWEIGHT_H_
+
+#include <linux/types.h>
+unsigned int hweight32(unsigned int w);
+unsigned long hweight64(__u64 w);
+
+#endif /* _KVM_ASM_HWEIGHT_H_ */
diff --git a/tools/kvm/include/bios/memcpy.h b/tools/kvm/include/bios/memcpy.h
new file mode 100644
index 0000000..e021044
--- /dev/null
+++ b/tools/kvm/include/bios/memcpy.h
@@ -0,0 +1,9 @@
+#ifndef KVM_BIOS_MEMCPY_H
+#define KVM_BIOS_MEMCPY_H
+
+#include <linux/types.h>
+#include <stddef.h>
+
+void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len);
+
+#endif /* KVM_BIOS_MEMCPY_H */
diff --git a/tools/kvm/include/kvm/8250-serial.h b/tools/kvm/include/kvm/8250-serial.h
new file mode 100644
index 0000000..df8ef53
--- /dev/null
+++ b/tools/kvm/include/kvm/8250-serial.h
@@ -0,0 +1,11 @@
+#ifndef KVM__8250_SERIAL_H
+#define KVM__8250_SERIAL_H
+
+struct kvm;
+
+int serial8250__init(struct kvm *kvm);
+int serial8250__exit(struct kvm *kvm);
+void serial8250__update_consoles(struct kvm *kvm);
+void serial8250__inject_sysrq(struct kvm *kvm);
+
+#endif /* KVM__8250_SERIAL_H */
diff --git a/tools/kvm/include/kvm/apic.h b/tools/kvm/include/kvm/apic.h
new file mode 100644
index 0000000..2129997
--- /dev/null
+++ b/tools/kvm/include/kvm/apic.h
@@ -0,0 +1,17 @@
+#ifndef KVM_APIC_H_
+#define KVM_APIC_H_
+
+#include <asm/apicdef.h>
+
+/*
+ * APIC, IOAPIC stuff
+ */
+#define APIC_BASE_ADDR_STEP	0x00400000
+#define IOAPIC_BASE_ADDR_STEP	0x00100000
+
+#define APIC_ADDR(apic)		(APIC_DEFAULT_PHYS_BASE + apic * APIC_BASE_ADDR_STEP)
+#define IOAPIC_ADDR(ioapic)	(IO_APIC_DEFAULT_PHYS_BASE + ioapic * IOAPIC_BASE_ADDR_STEP)
+
+#define KVM_APIC_VERSION	0x14 /* xAPIC */
+
+#endif /* KVM_APIC_H_ */
diff --git a/tools/kvm/include/kvm/brlock.h b/tools/kvm/include/kvm/brlock.h
new file mode 100644
index 0000000..bd1d882
--- /dev/null
+++ b/tools/kvm/include/kvm/brlock.h
@@ -0,0 +1,41 @@
+#ifndef KVM__BRLOCK_H
+#define KVM__BRLOCK_H
+
+#include "kvm/kvm.h"
+#include "kvm/barrier.h"
+
+/*
+ * brlock is a lock which is very cheap for reads, but very expensive
+ * for writes.
+ * This lock will be used when updates are very rare and reads are common.
+ * This lock is currently implemented by stopping the guest while
+ * performing the updates. We assume that the only threads whichread from
+ * the locked data are VCPU threads, and the only writer isn't a VCPU thread.
+ */
+
+#ifndef barrier
+#define barrier()		__asm__ __volatile__("": : :"memory")
+#endif
+
+#ifdef KVM_BRLOCK_DEBUG
+
+#include "kvm/rwsem.h"
+
+DECLARE_RWSEM(brlock_sem);
+
+#define br_read_lock()		down_read(&brlock_sem);
+#define br_read_unlock()	up_read(&brlock_sem);
+
+#define br_write_lock()		down_write(&brlock_sem);
+#define br_write_unlock()	up_write(&brlock_sem);
+
+#else
+
+#define br_read_lock()		barrier()
+#define br_read_unlock()	barrier()
+
+#define br_write_lock()		kvm__pause()
+#define br_write_unlock()	kvm__continue()
+#endif
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-balloon.h b/tools/kvm/include/kvm/builtin-balloon.h
new file mode 100644
index 0000000..77ee656
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-balloon.h
@@ -0,0 +1,9 @@
+#ifndef KVM__BALLOON_H
+#define KVM__BALLOON_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_balloon(int argc, const char **argv, const char *prefix);
+void kvm_balloon_help(void) NORETURN;
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-debug.h b/tools/kvm/include/kvm/builtin-debug.h
new file mode 100644
index 0000000..6105a8c
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-debug.h
@@ -0,0 +1,18 @@
+#ifndef KVM__DEBUG_H
+#define KVM__DEBUG_H
+
+#include <kvm/util.h>
+#include <linux/types.h>
+
+#define KVM_DEBUG_CMD_TYPE_DUMP	(1 << 0)
+#define KVM_DEBUG_CMD_TYPE_NMI	(1 << 1)
+
+struct debug_cmd_params {
+	u32 dbg_type;
+	u32 cpu;
+};
+
+int kvm_cmd_debug(int argc, const char **argv, const char *prefix);
+void kvm_debug_help(void) NORETURN;
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-help.h b/tools/kvm/include/kvm/builtin-help.h
new file mode 100644
index 0000000..2946743
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-help.h
@@ -0,0 +1,6 @@
+#ifndef __KVM_HELP_H__
+#define __KVM_HELP_H__
+
+int kvm_cmd_help(int argc, const char **argv, const char *prefix);
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-list.h b/tools/kvm/include/kvm/builtin-list.h
new file mode 100644
index 0000000..47029ca
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-list.h
@@ -0,0 +1,10 @@
+#ifndef KVM__LIST_H
+#define KVM__LIST_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_list(int argc, const char **argv, const char *prefix);
+void kvm_list_help(void) NORETURN;
+int get_vmstate(int sock);
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-pause.h b/tools/kvm/include/kvm/builtin-pause.h
new file mode 100644
index 0000000..84aaee3
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-pause.h
@@ -0,0 +1,9 @@
+#ifndef KVM__PAUSE_H
+#define KVM__PAUSE_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_pause(int argc, const char **argv, const char *prefix);
+void kvm_pause_help(void) NORETURN;
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-resume.h b/tools/kvm/include/kvm/builtin-resume.h
new file mode 100644
index 0000000..7de999b
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-resume.h
@@ -0,0 +1,9 @@
+#ifndef KVM__RESUME_H
+#define KVM__RESUME_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_resume(int argc, const char **argv, const char *prefix);
+void kvm_resume_help(void) NORETURN;
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-run.h b/tools/kvm/include/kvm/builtin-run.h
new file mode 100644
index 0000000..91521a5
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-run.h
@@ -0,0 +1,11 @@
+#ifndef __KVM_RUN_H__
+#define __KVM_RUN_H__
+
+#include <kvm/util.h>
+
+int kvm_cmd_run(int argc, const char **argv, const char *prefix);
+void kvm_run_help(void) NORETURN;
+
+void kvm_run_set_wrapper_sandbox(void);
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-sandbox.h b/tools/kvm/include/kvm/builtin-sandbox.h
new file mode 100644
index 0000000..98cd6be
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-sandbox.h
@@ -0,0 +1,6 @@
+#ifndef KVM__SANDBOX_H
+#define KVM__SANDBOX_H
+
+int kvm_cmd_sandbox(int argc, const char **argv, const char *prefix);
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-setup.h b/tools/kvm/include/kvm/builtin-setup.h
new file mode 100644
index 0000000..4a8d7ee
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-setup.h
@@ -0,0 +1,11 @@
+#ifndef KVM__SETUP_H
+#define KVM__SETUP_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_setup(int argc, const char **argv, const char *prefix);
+void kvm_setup_help(void) NORETURN;
+int kvm_setup_create_new(const char *guestfs_name);
+void kvm_setup_resolv(const char *guestfs_name);
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-stat.h b/tools/kvm/include/kvm/builtin-stat.h
new file mode 100644
index 0000000..4fecb37
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-stat.h
@@ -0,0 +1,9 @@
+#ifndef KVM__STAT_H
+#define KVM__STAT_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_stat(int argc, const char **argv, const char *prefix);
+void kvm_stat_help(void) NORETURN;
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-stop.h b/tools/kvm/include/kvm/builtin-stop.h
new file mode 100644
index 0000000..b26b275
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-stop.h
@@ -0,0 +1,9 @@
+#ifndef KVM__STOP_H
+#define KVM__STOP_H
+
+#include <kvm/util.h>
+
+int kvm_cmd_stop(int argc, const char **argv, const char *prefix);
+void kvm_stop_help(void) NORETURN;
+
+#endif
diff --git a/tools/kvm/include/kvm/builtin-version.h b/tools/kvm/include/kvm/builtin-version.h
new file mode 100644
index 0000000..83cac4d
--- /dev/null
+++ b/tools/kvm/include/kvm/builtin-version.h
@@ -0,0 +1,6 @@
+#ifndef KVM__VERSION_H
+#define KVM__VERSION_H
+
+int kvm_cmd_version(int argc, const char **argv, const char *prefix);
+
+#endif
diff --git a/tools/kvm/include/kvm/compiler.h b/tools/kvm/include/kvm/compiler.h
new file mode 100644
index 0000000..2013a83
--- /dev/null
+++ b/tools/kvm/include/kvm/compiler.h
@@ -0,0 +1,10 @@
+#ifndef KVM_COMPILER_H_
+#define KVM_COMPILER_H_
+
+#ifndef __compiletime_error
+# define __compiletime_error(message)
+#endif
+
+#define notrace __attribute__((no_instrument_function))
+
+#endif /* KVM_COMPILER_H_ */
diff --git a/tools/kvm/include/kvm/disk-image.h b/tools/kvm/include/kvm/disk-image.h
new file mode 100644
index 0000000..a0b61bf
--- /dev/null
+++ b/tools/kvm/include/kvm/disk-image.h
@@ -0,0 +1,81 @@
+#ifndef KVM__DISK_IMAGE_H
+#define KVM__DISK_IMAGE_H
+
+#include "kvm/read-write.h"
+#include "kvm/util.h"
+
+#include <linux/types.h>
+#include <linux/fs.h>	/* for BLKGETSIZE64 */
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <sys/uio.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define SECTOR_SHIFT		9
+#define SECTOR_SIZE		(1UL << SECTOR_SHIFT)
+
+enum {
+	DISK_IMAGE_REGULAR,
+	DISK_IMAGE_MMAP,
+};
+
+#define MAX_DISK_IMAGES         4
+
+struct disk_image;
+
+struct disk_image_operations {
+	ssize_t (*read_sector)(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param);
+	ssize_t (*write_sector)(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param);
+	int (*flush)(struct disk_image *disk);
+	int (*close)(struct disk_image *disk);
+};
+
+struct disk_image {
+	int				fd;
+	u64				size;
+	struct disk_image_operations	*ops;
+	void				*priv;
+	void				*disk_req_cb_param;
+	void				(*disk_req_cb)(void *param, long len);
+	bool				async;
+	int				evt;
+#ifdef CONFIG_HAS_AIO
+	io_context_t			ctx;
+#endif
+};
+
+struct disk_image *disk_image__open(const char *filename, bool readonly);
+struct disk_image **disk_image__open_all(const char **filenames, bool *readonly, int count);
+struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int mmap);
+int disk_image__close(struct disk_image *disk);
+int disk_image__close_all(struct disk_image **disks, int count);
+int disk_image__flush(struct disk_image *disk);
+ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param);
+ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iovec *iov,
+				int iovcount, void *param);
+ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len);
+
+struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly);
+struct disk_image *blkdev__probe(const char *filename, struct stat *st);
+
+ssize_t raw_image__read_sector(struct disk_image *disk, u64 sector,
+				const struct iovec *iov, int iovcount, void *param);
+ssize_t raw_image__write_sector(struct disk_image *disk, u64 sector,
+				const struct iovec *iov, int iovcount, void *param);
+ssize_t raw_image__read_sector_mmap(struct disk_image *disk, u64 sector,
+				const struct iovec *iov, int iovcount, void *param);
+ssize_t raw_image__write_sector_mmap(struct disk_image *disk, u64 sector,
+				const struct iovec *iov, int iovcount, void *param);
+int raw_image__close(struct disk_image *disk);
+void disk_image__set_callback(struct disk_image *disk, void (*disk_req_cb)(void *param, long len));
+#endif /* KVM__DISK_IMAGE_H */
diff --git a/tools/kvm/include/kvm/e820.h b/tools/kvm/include/kvm/e820.h
new file mode 100644
index 0000000..15f62cc
--- /dev/null
+++ b/tools/kvm/include/kvm/e820.h
@@ -0,0 +1,13 @@
+#ifndef KVM_E820_H
+#define KVM_E820_H
+
+#include <linux/types.h>
+#include <kvm/bios.h>
+
+#define SMAP    0x534d4150      /* ASCII "SMAP" */
+
+struct biosregs;
+
+extern bioscall void e820_query_map(struct biosregs *regs);
+
+#endif /* KVM_E820_H */
diff --git a/tools/kvm/include/kvm/framebuffer.h b/tools/kvm/include/kvm/framebuffer.h
new file mode 100644
index 0000000..dc5022c
--- /dev/null
+++ b/tools/kvm/include/kvm/framebuffer.h
@@ -0,0 +1,35 @@
+#ifndef KVM__FRAMEBUFFER_H
+#define KVM__FRAMEBUFFER_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+struct framebuffer;
+
+struct fb_target_operations {
+	int (*start)(struct framebuffer *fb);
+	int (*stop)(struct framebuffer *fb);
+};
+
+#define FB_MAX_TARGETS			2
+
+struct framebuffer {
+	struct list_head		node;
+
+	u32				width;
+	u32				height;
+	u8				depth;
+	char				*mem;
+	u64				mem_addr;
+	u64				mem_size;
+
+	unsigned long			nr_targets;
+	struct fb_target_operations	*targets[FB_MAX_TARGETS];
+};
+
+struct framebuffer *fb__register(struct framebuffer *fb);
+int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops);
+int fb__start(void);
+void fb__stop(void);
+
+#endif /* KVM__FRAMEBUFFER_H */
diff --git a/tools/kvm/include/kvm/guest_compat.h b/tools/kvm/include/kvm/guest_compat.h
new file mode 100644
index 0000000..ae7abbd
--- /dev/null
+++ b/tools/kvm/include/kvm/guest_compat.h
@@ -0,0 +1,9 @@
+#ifndef KVM__GUEST_COMPAT_H
+#define KVM__GUEST_COMPAT_H
+
+int compat__print_all_messages(void);
+int compat__remove_message(int id);
+int compat__add_message(const char *title, const char *description);
+
+
+#endif
\ No newline at end of file
diff --git a/tools/kvm/include/kvm/i8042.h b/tools/kvm/include/kvm/i8042.h
new file mode 100644
index 0000000..13f18e2
--- /dev/null
+++ b/tools/kvm/include/kvm/i8042.h
@@ -0,0 +1,12 @@
+#ifndef KVM__PCKBD_H
+#define KVM__PCKBD_H
+
+#include <linux/types.h>
+
+struct kvm;
+
+void mouse_queue(u8 c);
+void kbd_queue(u8 c);
+void kbd__init(struct kvm *kvm);
+
+#endif
diff --git a/tools/kvm/include/kvm/ioeventfd.h b/tools/kvm/include/kvm/ioeventfd.h
new file mode 100644
index 0000000..ec70aa5
--- /dev/null
+++ b/tools/kvm/include/kvm/ioeventfd.h
@@ -0,0 +1,27 @@
+#ifndef KVM__IOEVENTFD_H
+#define KVM__IOEVENTFD_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <sys/eventfd.h>
+
+struct kvm;
+
+struct ioevent {
+	u64			io_addr;
+	u8			io_len;
+	void			(*fn)(struct kvm *kvm, void *ptr);
+	struct kvm		*fn_kvm;
+	void			*fn_ptr;
+	int			fd;
+	u64			datamatch;
+
+	struct list_head	list;
+};
+
+int ioeventfd__init(struct kvm *kvm);
+int ioeventfd__exit(struct kvm *kvm);
+int ioeventfd__add_event(struct ioevent *ioevent);
+int ioeventfd__del_event(u64 addr, u64 datamatch);
+
+#endif
diff --git a/tools/kvm/include/kvm/ioport.h b/tools/kvm/include/kvm/ioport.h
new file mode 100644
index 0000000..ced8cf5
--- /dev/null
+++ b/tools/kvm/include/kvm/ioport.h
@@ -0,0 +1,69 @@
+#ifndef KVM__IOPORT_H
+#define KVM__IOPORT_H
+
+#include "kvm/rbtree-interval.h"
+
+#include <stdbool.h>
+#include <limits.h>
+#include <asm/types.h>
+#include <linux/types.h>
+#include <linux/byteorder.h>
+
+/* some ports we reserve for own use */
+#define IOPORT_DBG			0xe0
+#define IOPORT_START			0x6200
+#define IOPORT_SIZE			0x400
+
+#define IOPORT_EMPTY			USHRT_MAX
+
+struct kvm;
+
+struct ioport {
+	struct rb_int_node		node;
+	struct ioport_operations	*ops;
+	void				*priv;
+};
+
+struct ioport_operations {
+	bool (*io_in)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size);
+	bool (*io_out)(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size);
+};
+
+void ioport__setup_arch(void);
+
+int ioport__register(u16 port, struct ioport_operations *ops, int count, void *param);
+int ioport__unregister(u16 port);
+int ioport__init(struct kvm *kvm);
+int ioport__exit(struct kvm *kvm);
+
+static inline u8 ioport__read8(u8 *data)
+{
+	return *data;
+}
+/* On BE platforms, PCI I/O is byteswapped, i.e. LE, so swap back. */
+static inline u16 ioport__read16(u16 *data)
+{
+	return le16_to_cpu(*data);
+}
+
+static inline u32 ioport__read32(u32 *data)
+{
+	return le32_to_cpu(*data);
+}
+
+static inline void ioport__write8(u8 *data, u8 value)
+{
+	*data		 = value;
+}
+
+static inline void ioport__write16(u16 *data, u16 value)
+{
+	*data		 = cpu_to_le16(value);
+}
+
+static inline void ioport__write32(u32 *data, u32 value)
+{
+	*data		 = cpu_to_le32(value);
+}
+
+#endif /* KVM__IOPORT_H */
diff --git a/tools/kvm/include/kvm/irq.h b/tools/kvm/include/kvm/irq.h
new file mode 100644
index 0000000..43fecaf
--- /dev/null
+++ b/tools/kvm/include/kvm/irq.h
@@ -0,0 +1,33 @@
+#ifndef KVM__IRQ_H
+#define KVM__IRQ_H
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+#include <linux/kvm.h>
+
+#include "kvm/msi.h"
+
+struct kvm;
+
+struct irq_line {
+	u8			line;
+	struct list_head	node;
+};
+
+struct pci_dev {
+	struct rb_node		node;
+	u32			id;
+	u8			pin;
+	struct list_head	lines;
+};
+
+int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line);
+
+struct rb_node *irq__get_pci_tree(void);
+
+int irq__init(struct kvm *kvm);
+int irq__exit(struct kvm *kvm);
+int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg);
+
+#endif
diff --git a/tools/kvm/include/kvm/kvm-cmd.h b/tools/kvm/include/kvm/kvm-cmd.h
new file mode 100644
index 0000000..0a73bce
--- /dev/null
+++ b/tools/kvm/include/kvm/kvm-cmd.h
@@ -0,0 +1,17 @@
+#ifndef __KVM_CMD_H__
+#define __KVM_CMD_H__
+
+struct cmd_struct {
+	const char *cmd;
+	int (*fn)(int, const char **, const char *);
+	void (*help)(void);
+	int option;
+};
+
+extern struct cmd_struct kvm_commands[];
+struct cmd_struct *kvm_get_command(struct cmd_struct *command,
+                const char *cmd);
+
+int handle_command(struct cmd_struct *command, int argc, const char **argv);
+
+#endif
diff --git a/tools/kvm/include/kvm/kvm-cpu.h b/tools/kvm/include/kvm/kvm-cpu.h
new file mode 100644
index 0000000..d4448f6
--- /dev/null
+++ b/tools/kvm/include/kvm/kvm-cpu.h
@@ -0,0 +1,24 @@
+#ifndef KVM__KVM_CPU_H
+#define KVM__KVM_CPU_H
+
+#include "kvm/kvm-cpu-arch.h"
+#include <stdbool.h>
+
+struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id);
+void kvm_cpu__delete(struct kvm_cpu *vcpu);
+void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu);
+void kvm_cpu__setup_cpuid(struct kvm_cpu *vcpu);
+void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu);
+void kvm_cpu__run(struct kvm_cpu *vcpu);
+void kvm_cpu__reboot(void);
+int kvm_cpu__start(struct kvm_cpu *cpu);
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu);
+
+int kvm_cpu__get_debug_fd(void);
+void kvm_cpu__set_debug_fd(int fd);
+void kvm_cpu__show_code(struct kvm_cpu *vcpu);
+void kvm_cpu__show_registers(struct kvm_cpu *vcpu);
+void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu);
+void kvm_cpu__arch_nmi(struct kvm_cpu *cpu);
+
+#endif /* KVM__KVM_CPU_H */
diff --git a/tools/kvm/include/kvm/kvm-ipc.h b/tools/kvm/include/kvm/kvm-ipc.h
new file mode 100644
index 0000000..aefffa4
--- /dev/null
+++ b/tools/kvm/include/kvm/kvm-ipc.h
@@ -0,0 +1,24 @@
+#ifndef KVM__IPC_H_
+#define KVM__IPC_H_
+
+#include <linux/types.h>
+
+enum {
+	KVM_IPC_BALLOON	= 1,
+	KVM_IPC_DEBUG	= 2,
+	KVM_IPC_STAT	= 3,
+	KVM_IPC_PAUSE	= 4,
+	KVM_IPC_RESUME	= 5,
+	KVM_IPC_STOP	= 6,
+	KVM_IPC_PID	= 7,
+	KVM_IPC_VMSTATE	= 8,
+};
+
+int kvm_ipc__register_handler(u32 type, void (*cb)(int fd, u32 type, u32 len, u8 *msg));
+int kvm_ipc__start(int sock);
+int kvm_ipc__stop(void);
+
+int kvm_ipc__send(int fd, u32 type);
+int kvm_ipc__send_msg(int fd, u32 type, u32 len, u8 *msg);
+
+#endif
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
new file mode 100644
index 0000000..7870118
--- /dev/null
+++ b/tools/kvm/include/kvm/kvm.h
@@ -0,0 +1,92 @@
+#ifndef KVM__KVM_H
+#define KVM__KVM_H
+
+#include "kvm/kvm-arch.h"
+
+#include <stdbool.h>
+#include <linux/types.h>
+#include <time.h>
+#include <signal.h>
+
+#define SIGKVMEXIT		(SIGRTMIN + 0)
+#define SIGKVMPAUSE		(SIGRTMIN + 1)
+
+#define KVM_PID_FILE_PATH	"/.kvm-tools/"
+#define HOME_DIR		getenv("HOME")
+#define KVM_BINARY_NAME		"lkvm"
+
+#define PAGE_SIZE (sysconf(_SC_PAGE_SIZE))
+
+#define DEFINE_KVM_EXT(ext)		\
+	.name = #ext,			\
+	.code = ext
+
+enum {
+	KVM_VMSTATE_RUNNING,
+	KVM_VMSTATE_PAUSED,
+};
+
+struct kvm_ext {
+	const char *name;
+	int code;
+};
+
+void kvm__set_dir(const char *fmt, ...);
+const char *kvm__get_dir(void);
+
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name);
+int kvm__recommended_cpus(struct kvm *kvm);
+int kvm__max_cpus(struct kvm *kvm);
+void kvm__init_ram(struct kvm *kvm);
+int kvm__exit(struct kvm *kvm);
+bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
+			const char *initrd_filename, const char *kernel_cmdline, u16 vidmode);
+void kvm__start_timer(struct kvm *kvm);
+void kvm__stop_timer(struct kvm *kvm);
+void kvm__irq_line(struct kvm *kvm, int irq, int level);
+void kvm__irq_trigger(struct kvm *kvm, int irq);
+bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count);
+bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write);
+int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr);
+int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool coalesce,
+			void (*mmio_fn)(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
+			void *ptr);
+bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr);
+void kvm__pause(void);
+void kvm__continue(void);
+void kvm__notify_paused(void);
+int kvm__get_sock_by_instance(const char *name);
+int kvm__enumerate_instances(int (*callback)(const char *name, int pid));
+void kvm__remove_socket(const char *name);
+
+void kvm__arch_set_cmdline(char *cmdline, bool video);
+void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size);
+void kvm__arch_delete_ram(struct kvm *kvm);
+int kvm__arch_setup_firmware(struct kvm *kvm);
+int kvm__arch_free_firmware(struct kvm *kvm);
+bool kvm__arch_cpu_supports_vm(void);
+void kvm__arch_periodic_poll(struct kvm *kvm);
+
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline);
+bool load_bzimage(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline, u16 vidmode);
+
+/*
+ * Debugging
+ */
+void kvm__dump_mem(struct kvm *kvm, unsigned long addr, unsigned long size);
+
+extern const char *kvm_exit_reasons[];
+
+static inline bool host_ptr_in_ram(struct kvm *kvm, void *p)
+{
+	return kvm->ram_start <= p && p < (kvm->ram_start + kvm->ram_size);
+}
+
+static inline void *guest_flat_to_host(struct kvm *kvm, unsigned long offset)
+{
+	return kvm->ram_start + offset;
+}
+
+bool kvm__supports_extension(struct kvm *kvm, unsigned int extension);
+
+#endif /* KVM__KVM_H */
diff --git a/tools/kvm/include/kvm/msi.h b/tools/kvm/include/kvm/msi.h
new file mode 100644
index 0000000..885eb5b
--- /dev/null
+++ b/tools/kvm/include/kvm/msi.h
@@ -0,0 +1,10 @@
+#ifndef LKVM_MSI_H
+#define LKVM_MSI_H
+
+struct msi_msg {
+	u32	address_lo;	/* low 32 bits of msi message address */
+	u32	address_hi;	/* high 32 bits of msi message address */
+	u32	data;		/* 16 bits of msi message data */
+};
+
+#endif /* LKVM_MSI_H */
diff --git a/tools/kvm/include/kvm/mutex.h b/tools/kvm/include/kvm/mutex.h
new file mode 100644
index 0000000..3286cea
--- /dev/null
+++ b/tools/kvm/include/kvm/mutex.h
@@ -0,0 +1,33 @@
+#ifndef KVM__MUTEX_H
+#define KVM__MUTEX_H
+
+#include <pthread.h>
+
+#include "kvm/util.h"
+
+/*
+ * Kernel-alike mutex API - to make it easier for kernel developers
+ * to write user-space code! :-)
+ */
+
+#define DEFINE_MUTEX(mutex) pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
+
+static inline void mutex_init(pthread_mutex_t *mutex)
+{
+	if (pthread_mutex_init(mutex, NULL) != 0)
+		die("unexpected pthread_mutex_init() failure!");
+}
+
+static inline void mutex_lock(pthread_mutex_t *mutex)
+{
+	if (pthread_mutex_lock(mutex) != 0)
+		die("unexpected pthread_mutex_lock() failure!");
+}
+
+static inline void mutex_unlock(pthread_mutex_t *mutex)
+{
+	if (pthread_mutex_unlock(mutex) != 0)
+		die("unexpected pthread_mutex_unlock() failure!");
+}
+
+#endif /* KVM__MUTEX_H */
diff --git a/tools/kvm/include/kvm/parse-options.h b/tools/kvm/include/kvm/parse-options.h
new file mode 100644
index 0000000..7886ff7
--- /dev/null
+++ b/tools/kvm/include/kvm/parse-options.h
@@ -0,0 +1,214 @@
+#ifndef __PARSE_OPTIONS_H__
+#define __PARSE_OPTIONS_H__
+
+#include <inttypes.h>
+#include <kvm/util.h>
+
+enum parse_opt_type {
+	/* special types */
+	OPTION_END,
+	OPTION_ARGUMENT,
+	OPTION_GROUP,
+	/* options with no arguments */
+	OPTION_BIT,
+	OPTION_BOOLEAN,
+	OPTION_INCR,
+	OPTION_SET_UINT,
+	OPTION_SET_PTR,
+	/* options with arguments (usually) */
+	OPTION_STRING,
+	OPTION_INTEGER,
+	OPTION_LONG,
+	OPTION_CALLBACK,
+	OPTION_U64,
+	OPTION_UINTEGER,
+};
+
+enum parse_opt_flags {
+	PARSE_OPT_KEEP_DASHDASH = 1,
+	PARSE_OPT_STOP_AT_NON_OPTION = 2,
+	PARSE_OPT_KEEP_ARGV0 = 4,
+	PARSE_OPT_KEEP_UNKNOWN = 8,
+	PARSE_OPT_NO_INTERNAL_HELP = 16,
+};
+
+enum parse_opt_option_flags {
+	PARSE_OPT_OPTARG  = 1,
+	PARSE_OPT_NOARG   = 2,
+	PARSE_OPT_NONEG   = 4,
+	PARSE_OPT_HIDDEN  = 8,
+	PARSE_OPT_LASTARG_DEFAULT = 16,
+};
+
+struct option;
+typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
+/*
+ * `type`::
+ *   holds the type of the option, you must have an OPTION_END last in your
+ *   array.
+ *
+ * `short_name`::
+ *   the character to use as a short option name, '\0' if none.
+ *
+ * `long_name`::
+ *   the long option name, without the leading dashes, NULL if none.
+ *
+ * `value`::
+ *   stores pointers to the values to be filled.
+ *
+ * `argh`::
+ *   token to explain the kind of argument this option wants. Keep it
+ *   homogenous across the repository.
+ *
+ * `help`::
+ *   the short help associated to what the option does.
+ *   Must never be NULL (except for OPTION_END).
+ *   OPTION_GROUP uses this pointer to store the group header.
+ *
+ * `flags`::
+ *   mask of parse_opt_option_flags.
+ *   PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs)
+ *   PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
+ *   PARSE_OPT_NONEG: says that this option cannot be negated
+ *   PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in
+ *                    the long one.
+ *
+ * `callback`::
+ *   pointer to the callback to use for OPTION_CALLBACK.
+ *
+ * `defval`::
+ *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
+ *   OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
+ *   the value when met.
+ *   CALLBACKS can use it like they want.
+ */
+struct option {
+enum parse_opt_type type;
+int short_name;
+const char *long_name;
+void *value;
+const char *argh;
+const char *help;
+
+int flags;
+parse_opt_cb *callback;
+intptr_t defval;
+};
+
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+#define check_vtype(v, type) \
+	(BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v)
+
+#define OPT_INTEGER(s, l, v, h)             \
+{                                           \
+	.type = OPTION_INTEGER,             \
+	.short_name = (s),                  \
+	.long_name = (l),                   \
+	.value = check_vtype(v, int *),     \
+	.help = (h)                         \
+}
+
+#define OPT_U64(s, l, v, h)                 \
+{                                           \
+	.type = OPTION_U64,                 \
+	.short_name = (s),                  \
+	.long_name = (l),                   \
+	.value = check_vtype(v, u64 *),     \
+	.help = (h)                         \
+}
+
+#define OPT_STRING(s, l, v, a, h)           \
+{                                           \
+	.type = OPTION_STRING,              \
+	.short_name = (s),                  \
+	.long_name = (l),                   \
+	.value = check_vtype(v, const char **), (a), \
+	.help = (h)                         \
+}
+
+#define OPT_BOOLEAN(s, l, v, h)             \
+{                                           \
+	.type = OPTION_BOOLEAN,             \
+	.short_name = (s),                  \
+	.long_name = (l),                   \
+	.value = check_vtype(v, bool *),    \
+	.help = (h)                         \
+}
+
+#define OPT_INCR(s, l, v, h)                \
+{                                           \
+	.type = OPTION_INCR,	            \
+	.short_name = (s),                  \
+	.long_name = (l),                   \
+	.value = check_vtype(v, int *),     \
+	.help = (h)                         \
+}
+
+#define OPT_GROUP(h)                        \
+{                                           \
+	.type = OPTION_GROUP,               \
+	.help = (h)                         \
+}
+
+#define OPT_CALLBACK(s, l, v, a, h, f)      \
+{					    \
+	.type = OPTION_CALLBACK,	    \
+	.short_name = (s),		    \
+	.long_name = (l),		    \
+	.value = (v),			    \
+	(a),				    \
+	.help = (h),			    \
+	.callback = (f)			    \
+}
+
+#define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
+{					    \
+	.type = OPTION_CALLBACK,	    \
+	.short_name = (s),		    \
+	.long_name = (l),		    \
+	.value = (v),			    \
+	(a),				    \
+	.help = (h),			    \
+	.callback = (f),		    \
+	.flags = PARSE_OPT_NOARG	    \
+}
+
+#define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
+{					    \
+	.type = OPTION_CALLBACK,	    \
+	.short_name = (s),		    \
+	.long_name = (l),		    \
+	.value = (v), (a),		    \
+	.help = (h),			    \
+	.callback = (f),		    \
+	.defval = (intptr_t)d,		    \
+	.flags = PARSE_OPT_LASTARG_DEFAULT  \
+}
+
+#define OPT_END() { .type = OPTION_END }
+
+enum {
+	PARSE_OPT_HELP = -1,
+	PARSE_OPT_DONE,
+	PARSE_OPT_UNKNOWN,
+};
+
+/*
+ * It's okay for the caller to consume argv/argc in the usual way.
+ * Other fields of that structure are private to parse-options and should not
+ * be modified in any way.
+ **/
+struct parse_opt_ctx_t {
+	const char **argv;
+	const char **out;
+	int argc, cpidx;
+	const char *opt;
+	int flags;
+};
+
+/* global functions */
+void usage_with_options(const char * const *usagestr,
+		const struct option *opts) NORETURN;
+int parse_options(int argc, const char **argv, const struct option *options,
+		const char * const usagestr[], int flags);
+#endif
diff --git a/tools/kvm/include/kvm/pci-shmem.h b/tools/kvm/include/kvm/pci-shmem.h
new file mode 100644
index 0000000..599ab37
--- /dev/null
+++ b/tools/kvm/include/kvm/pci-shmem.h
@@ -0,0 +1,28 @@
+#ifndef KVM__PCI_SHMEM_H
+#define KVM__PCI_SHMEM_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#define SHMEM_DEFAULT_SIZE (16 << MB_SHIFT)
+#define SHMEM_DEFAULT_ADDR (0xc8000000)
+#define SHMEM_DEFAULT_HANDLE "/kvm_shmem"
+
+struct kvm;
+struct shmem_info;
+
+struct shmem_info {
+	u64 phys_addr;
+	u64 size;
+	char *handle;
+	int create;
+};
+
+int pci_shmem__init(struct kvm *self);
+int pci_shmem__register_mem(struct shmem_info *si);
+
+int pci_shmem__get_local_irqfd(struct kvm *kvm);
+int pci_shmem__add_client(struct kvm *kvm, u32 id, int fd);
+int pci_shmem__remove_client(struct kvm *kvm, u32 id);
+
+#endif
diff --git a/tools/kvm/include/kvm/pci.h b/tools/kvm/include/kvm/pci.h
new file mode 100644
index 0000000..7903723
--- /dev/null
+++ b/tools/kvm/include/kvm/pci.h
@@ -0,0 +1,95 @@
+#ifndef KVM__PCI_H
+#define KVM__PCI_H
+
+#include <linux/types.h>
+#include <linux/kvm.h>
+#include <linux/pci_regs.h>
+#include <endian.h>
+
+#include "kvm/kvm.h"
+#include "kvm/msi.h"
+
+#define PCI_MAX_DEVICES			256
+/*
+ * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1.
+ * ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for
+ * details.
+ */
+#define PCI_CONFIG_ADDRESS	0xcf8
+#define PCI_CONFIG_DATA		0xcfc
+#define PCI_CONFIG_BUS_FORWARD	0xcfa
+#define PCI_IO_SIZE		0x100
+
+union pci_config_address {
+	struct {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+		unsigned	reg_offset	: 2;		/* 1  .. 0  */
+		unsigned	register_number	: 6;		/* 7  .. 2  */
+		unsigned	function_number	: 3;		/* 10 .. 8  */
+		unsigned	device_number	: 5;		/* 15 .. 11 */
+		unsigned	bus_number	: 8;		/* 23 .. 16 */
+		unsigned	reserved	: 7;		/* 30 .. 24 */
+		unsigned	enable_bit	: 1;		/* 31       */
+#else
+		unsigned	enable_bit	: 1;		/* 31       */
+		unsigned	reserved	: 7;		/* 30 .. 24 */
+		unsigned	bus_number	: 8;		/* 23 .. 16 */
+		unsigned	device_number	: 5;		/* 15 .. 11 */
+		unsigned	function_number	: 3;		/* 10 .. 8  */
+		unsigned	register_number	: 6;		/* 7  .. 2  */
+		unsigned	reg_offset	: 2;		/* 1  .. 0  */
+#endif
+	};
+	u32 w;
+};
+
+struct msix_table {
+	struct msi_msg msg;
+	u32 ctrl;
+};
+
+struct msix_cap {
+	u8 cap;
+	u8 next;
+	u16 ctrl;
+	u32 table_offset;
+	u32 pba_offset;
+};
+
+struct pci_device_header {
+	u16		vendor_id;
+	u16		device_id;
+	u16		command;
+	u16		status;
+	u8		revision_id;
+	u8		class[3];
+	u8		cacheline_size;
+	u8		latency_timer;
+	u8		header_type;
+	u8		bist;
+	u32		bar[6];
+	u32		card_bus;
+	u16		subsys_vendor_id;
+	u16		subsys_id;
+	u32		exp_rom_bar;
+	u8		capabilities;
+	u8		reserved1[3];
+	u32		reserved2;
+	u8		irq_line;
+	u8		irq_pin;
+	u8		min_gnt;
+	u8		max_lat;
+	struct msix_cap msix;
+	u8		empty[136]; /* Rest of PCI config space */
+	u32		bar_size[6];
+} __attribute__((packed));
+
+int pci__init(struct kvm *kvm);
+int pci__exit(struct kvm *kvm);
+int pci__register(struct pci_device_header *dev, u8 dev_num);
+struct pci_device_header *pci__find_dev(u8 dev_num);
+u32 pci_get_io_space_block(u32 size);
+void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size);
+void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size);
+
+#endif /* KVM__PCI_H */
diff --git a/tools/kvm/include/kvm/qcow.h b/tools/kvm/include/kvm/qcow.h
new file mode 100644
index 0000000..e032a1e
--- /dev/null
+++ b/tools/kvm/include/kvm/qcow.h
@@ -0,0 +1,133 @@
+#ifndef KVM__QCOW_H
+#define KVM__QCOW_H
+
+#include "kvm/mutex.h"
+
+#include <linux/types.h>
+#include <stdbool.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+
+#define QCOW_MAGIC		(('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
+
+#define QCOW1_VERSION		1
+#define QCOW2_VERSION		2
+
+#define QCOW1_OFLAG_COMPRESSED	(1ULL << 63)
+
+#define QCOW2_OFLAG_COPIED	(1ULL << 63)
+#define QCOW2_OFLAG_COMPRESSED	(1ULL << 62)
+
+#define QCOW2_OFLAGS_MASK	(QCOW2_OFLAG_COPIED|QCOW2_OFLAG_COMPRESSED)
+
+#define QCOW2_OFFSET_MASK	(~QCOW2_OFLAGS_MASK)
+
+#define MAX_CACHE_NODES         32
+
+struct qcow_l2_table {
+	u64				offset;
+	struct rb_node			node;
+	struct list_head		list;
+	u8				dirty;
+	u64				table[];
+};
+
+struct qcow_l1_table {
+	u32				table_size;
+	u64				*l1_table;
+
+	/* Level2 caching data structures */
+	struct rb_root			root;
+	struct list_head		lru_list;
+	int				nr_cached;
+};
+
+#define QCOW_REFCOUNT_BLOCK_SHIFT	1
+
+struct qcow_refcount_block {
+	u64				offset;
+	struct rb_node			node;
+	struct list_head		list;
+	u64				size;
+	u8				dirty;
+	u16				entries[];
+};
+
+struct qcow_refcount_table {
+	u32				rf_size;
+	u64				*rf_table;
+
+	/* Refcount block caching data structures */
+	struct rb_root			root;
+	struct list_head		lru_list;
+	int				nr_cached;
+};
+
+struct qcow_header {
+	u64				size;	/* in bytes */
+	u64				l1_table_offset;
+	u32				l1_size;
+	u8				cluster_bits;
+	u8				l2_bits;
+	u64				refcount_table_offset;
+	u32				refcount_table_size;
+};
+
+struct qcow {
+	pthread_mutex_t			mutex;
+	struct qcow_header		*header;
+	struct qcow_l1_table		table;
+	struct qcow_refcount_table	refcount_table;
+	int				fd;
+	int				csize_shift;
+	int				csize_mask;
+	u32				version;
+	u64				cluster_size;
+	u64				cluster_offset_mask;
+	u64				free_clust_idx;
+	void				*cluster_cache;
+	void				*cluster_data;
+	void				*copy_buff;
+};
+
+struct qcow1_header_disk {
+	u32				magic;
+	u32				version;
+
+	u64				backing_file_offset;
+	u32 				backing_file_size;
+	u32				mtime;
+
+	u64				size;	/* in bytes */
+
+	u8				cluster_bits;
+	u8				l2_bits;
+	u32				crypt_method;
+
+	u64				l1_table_offset;
+};
+
+struct qcow2_header_disk {
+	u32				magic;
+	u32				version;
+
+	u64				backing_file_offset;
+	u32				backing_file_size;
+
+	u32				cluster_bits;
+	u64				size;	/* in bytes */
+	u32				crypt_method;
+
+	u32				l1_size;
+	u64				l1_table_offset;
+
+	u64				refcount_table_offset;
+	u32				refcount_table_clusters;
+
+	u32				nb_snapshots;
+	u64				snapshots_offset;
+};
+
+struct disk_image *qcow_probe(int fd, bool readonly);
+
+#endif /* KVM__QCOW_H */
diff --git a/tools/kvm/include/kvm/rbtree-interval.h b/tools/kvm/include/kvm/rbtree-interval.h
new file mode 100644
index 0000000..13245ba
--- /dev/null
+++ b/tools/kvm/include/kvm/rbtree-interval.h
@@ -0,0 +1,28 @@
+#ifndef KVM__INTERVAL_RBTREE_H
+#define KVM__INTERVAL_RBTREE_H
+
+#include <linux/rbtree.h>
+#include <linux/types.h>
+
+#define RB_INT_INIT(l, h) (struct rb_int_node){.low = l, .high = h}
+#define rb_int(n) rb_entry(n, struct rb_int_node, node)
+
+struct rb_int_node {
+	struct rb_node	node;
+	u64		low;
+	u64		high;
+
+	/* max_high will store the highest high of it's 2 children. */
+	u64		max_high;
+};
+
+/* Return the rb_int_node interval in which 'point' is located. */
+struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point);
+
+/* Return the rb_int_node in which start:len is located. */
+struct rb_int_node *rb_int_search_range(struct rb_root *root, u64 low, u64 high);
+
+int rb_int_insert(struct rb_root *root, struct rb_int_node *data);
+void rb_int_erase(struct rb_root *root, struct rb_int_node *node);
+
+#endif
diff --git a/tools/kvm/include/kvm/read-write.h b/tools/kvm/include/kvm/read-write.h
new file mode 100644
index 0000000..67571f9
--- /dev/null
+++ b/tools/kvm/include/kvm/read-write.h
@@ -0,0 +1,43 @@
+#ifndef KVM_READ_WRITE_H
+#define KVM_READ_WRITE_H
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#ifdef CONFIG_HAS_AIO
+#include <libaio.h>
+#endif
+
+ssize_t xread(int fd, void *buf, size_t count);
+ssize_t xwrite(int fd, const void *buf, size_t count);
+
+ssize_t read_in_full(int fd, void *buf, size_t count);
+ssize_t write_in_full(int fd, const void *buf, size_t count);
+
+ssize_t xpread(int fd, void *buf, size_t count, off_t offset);
+ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset);
+
+ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset);
+ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset);
+
+ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt);
+ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt);
+
+ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt);
+ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt);
+
+ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+
+ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset);
+
+#ifdef CONFIG_HAS_AIO
+int aio_preadv(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt,
+		off_t offset, int ev, void *param);
+int aio_pwritev(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt,
+		off_t offset, int ev, void *param);
+#endif
+
+#endif /* KVM_READ_WRITE_H */
diff --git a/tools/kvm/include/kvm/rtc.h b/tools/kvm/include/kvm/rtc.h
new file mode 100644
index 0000000..6aa9299
--- /dev/null
+++ b/tools/kvm/include/kvm/rtc.h
@@ -0,0 +1,9 @@
+#ifndef KVM__RTC_H
+#define KVM__RTC_H
+
+struct kvm;
+
+int rtc__init(struct kvm *kvm);
+int rtc__exit(struct kvm *kvm);
+
+#endif /* KVM__RTC_H */
diff --git a/tools/kvm/include/kvm/rwsem.h b/tools/kvm/include/kvm/rwsem.h
new file mode 100644
index 0000000..75a22f8
--- /dev/null
+++ b/tools/kvm/include/kvm/rwsem.h
@@ -0,0 +1,39 @@
+#ifndef KVM__RWSEM_H
+#define KVM__RWSEM_H
+
+#include <pthread.h>
+
+#include "kvm/util.h"
+
+/*
+ * Kernel-alike rwsem API - to make it easier for kernel developers
+ * to write user-space code! :-)
+ */
+
+#define DECLARE_RWSEM(sem) pthread_rwlock_t sem = PTHREAD_RWLOCK_INITIALIZER
+
+static inline void down_read(pthread_rwlock_t *rwsem)
+{
+	if (pthread_rwlock_rdlock(rwsem) != 0)
+		die("unexpected pthread_rwlock_rdlock() failure!");
+}
+
+static inline void down_write(pthread_rwlock_t *rwsem)
+{
+	if (pthread_rwlock_wrlock(rwsem) != 0)
+		die("unexpected pthread_rwlock_wrlock() failure!");
+}
+
+static inline void up_read(pthread_rwlock_t *rwsem)
+{
+	if (pthread_rwlock_unlock(rwsem) != 0)
+		die("unexpected pthread_rwlock_unlock() failure!");
+}
+
+static inline void up_write(pthread_rwlock_t *rwsem)
+{
+	if (pthread_rwlock_unlock(rwsem) != 0)
+		die("unexpected pthread_rwlock_unlock() failure!");
+}
+
+#endif /* KVM__RWSEM_H */
diff --git a/tools/kvm/include/kvm/sdl.h b/tools/kvm/include/kvm/sdl.h
new file mode 100644
index 0000000..36e5986
--- /dev/null
+++ b/tools/kvm/include/kvm/sdl.h
@@ -0,0 +1,22 @@
+#ifndef KVM__SDL_H
+#define KVM__SDL_H
+
+#include "kvm/util.h"
+
+struct framebuffer;
+
+#ifdef CONFIG_HAS_SDL
+int sdl__init(struct framebuffer *fb);
+int sdl__exit(struct framebuffer *fb);
+#else
+static inline void sdl__init(struct framebuffer *fb)
+{
+	die("SDL support not compiled in. (install the SDL-dev[el] package)");
+}
+static inline void sdl__exit(struct framebuffer *fb)
+{
+	die("SDL support not compiled in. (install the SDL-dev[el] package)");
+}
+#endif
+
+#endif /* KVM__SDL_H */
diff --git a/tools/kvm/include/kvm/segment.h b/tools/kvm/include/kvm/segment.h
new file mode 100644
index 0000000..9387a82
--- /dev/null
+++ b/tools/kvm/include/kvm/segment.h
@@ -0,0 +1,21 @@
+#ifndef KVM_SEGMENT_H
+#define KVM_SEGMENT_H
+
+#include <linux/types.h>
+
+static inline u32 segment_to_flat(u16 selector, u16 offset)
+{
+	return ((u32)selector << 4) + (u32) offset;
+}
+
+static inline u16 flat_to_seg16(u32 address)
+{
+	return address >> 4;
+}
+
+static inline u16 flat_to_off16(u32 address, u32 segment)
+{
+	return address - (segment << 4);
+}
+
+#endif /* KVM_SEGMENT_H */
diff --git a/tools/kvm/include/kvm/strbuf.h b/tools/kvm/include/kvm/strbuf.h
new file mode 100644
index 0000000..8fdef7e
--- /dev/null
+++ b/tools/kvm/include/kvm/strbuf.h
@@ -0,0 +1,19 @@
+#ifndef __STRBUF_H__
+#define __STRBUF_H__
+
+#include <sys/types.h>
+#include <string.h>
+
+int prefixcmp(const char *str, const char *prefix);
+
+extern size_t strlcat(char *dest, const char *src, size_t count);
+
+/* some inline functions */
+
+static inline const char *skip_prefix(const char *str, const char *prefix)
+{
+	size_t len = strlen(prefix);
+	return strncmp(str, prefix, len) ? NULL : str + len;
+}
+
+#endif
diff --git a/tools/kvm/include/kvm/symbol.h b/tools/kvm/include/kvm/symbol.h
new file mode 100644
index 0000000..725bbaf
--- /dev/null
+++ b/tools/kvm/include/kvm/symbol.h
@@ -0,0 +1,30 @@
+#ifndef KVM__SYMBOL_H
+#define KVM__SYMBOL_H
+
+#include <stddef.h>
+#include <string.h>
+
+struct kvm;
+
+#define SYMBOL_DEFAULT_UNKNOWN "<unknown>"
+
+#ifdef CONFIG_HAS_BFD
+
+int symbol_init(struct kvm *kvm);
+int symbol_exit(struct kvm *kvm);
+char *symbol_lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size);
+
+#else
+
+static inline int symbol_init(struct kvm *kvm) { return 0; }
+static inline char *symbol_lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size)
+{
+	char *s = strncpy(sym, SYMBOL_DEFAULT_UNKNOWN, size);
+	sym[size - 1] = '\0';
+	return s;
+}
+static inline int symbol_exit(struct kvm *kvm) { return 0; }
+
+#endif
+
+#endif /* KVM__SYMBOL_H */
diff --git a/tools/kvm/include/kvm/term.h b/tools/kvm/include/kvm/term.h
new file mode 100644
index 0000000..a6a9822
--- /dev/null
+++ b/tools/kvm/include/kvm/term.h
@@ -0,0 +1,20 @@
+#ifndef KVM__TERM_H
+#define KVM__TERM_H
+
+#include <sys/uio.h>
+#include <stdbool.h>
+
+#define CONSOLE_8250	1
+#define CONSOLE_VIRTIO	2
+#define CONSOLE_HV	3
+
+int term_putc_iov(int who, struct iovec *iov, int iovcnt, int term);
+int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term);
+int term_putc(int who, char *addr, int cnt, int term);
+int term_getc(int who, int term);
+
+bool term_readable(int who, int term);
+void term_set_tty(int term);
+void term_init(void);
+
+#endif /* KVM__TERM_H */
diff --git a/tools/kvm/include/kvm/threadpool.h b/tools/kvm/include/kvm/threadpool.h
new file mode 100644
index 0000000..768239f
--- /dev/null
+++ b/tools/kvm/include/kvm/threadpool.h
@@ -0,0 +1,37 @@
+#ifndef KVM__THREADPOOL_H
+#define KVM__THREADPOOL_H
+
+#include "kvm/mutex.h"
+
+#include <linux/list.h>
+
+struct kvm;
+
+typedef void (*kvm_thread_callback_fn_t)(struct kvm *kvm, void *data);
+
+struct thread_pool__job {
+	kvm_thread_callback_fn_t	callback;
+	struct kvm			*kvm;
+	void				*data;
+
+	int				signalcount;
+	pthread_mutex_t			mutex;
+
+	struct list_head		queue;
+};
+
+static inline void thread_pool__init_job(struct thread_pool__job *job, struct kvm *kvm, kvm_thread_callback_fn_t callback, void *data)
+{
+	*job = (struct thread_pool__job) {
+		.kvm		= kvm,
+		.callback	= callback,
+		.data		= data,
+		.mutex		= PTHREAD_MUTEX_INITIALIZER,
+	};
+}
+
+int thread_pool__init(unsigned long thread_count);
+
+void thread_pool__do_job(struct thread_pool__job *job);
+
+#endif
diff --git a/tools/kvm/include/kvm/types.h b/tools/kvm/include/kvm/types.h
new file mode 100644
index 0000000..0cbc5fb
--- /dev/null
+++ b/tools/kvm/include/kvm/types.h
@@ -0,0 +1,7 @@
+#ifndef KVM_TYPES_H
+#define KVM_TYPES_H
+
+/* FIXME: include/linux/if_tun.h and include/linux/if_ether.h complains */
+#define __be16 u16
+
+#endif /* KVM_TYPES_H */
diff --git a/tools/kvm/include/kvm/uip.h b/tools/kvm/include/kvm/uip.h
new file mode 100644
index 0000000..4497f6a
--- /dev/null
+++ b/tools/kvm/include/kvm/uip.h
@@ -0,0 +1,358 @@
+#ifndef KVM__UIP_H
+#define KVM__UIP_H
+
+#include "linux/types.h"
+#include "kvm/mutex.h"
+
+#include <netinet/in.h>
+#include <sys/uio.h>
+
+#define UIP_BUF_STATUS_FREE	0
+#define UIP_BUF_STATUS_INUSE	1
+#define UIP_BUF_STATUS_USED	2
+
+#define UIP_ETH_P_IP		0X0800
+#define UIP_ETH_P_ARP		0X0806
+
+#define UIP_IP_VER_4		0X40
+#define UIP_IP_HDR_LEN		0X05
+#define UIP_IP_TTL		0X40
+#define UIP_IP_P_UDP		0X11
+#define UIP_IP_P_TCP		0X06
+#define UIP_IP_P_ICMP		0X01
+
+#define UIP_TCP_HDR_LEN		0x50
+#define UIP_TCP_WIN_SIZE	14600
+#define UIP_TCP_FLAG_FIN	1
+#define UIP_TCP_FLAG_SYN	2
+#define UIP_TCP_FLAG_RST	4
+#define UIP_TCP_FLAG_PSH	8
+#define UIP_TCP_FLAG_ACK	16
+#define UIP_TCP_FLAG_URG	32
+
+#define UIP_BOOTP_VENDOR_SPECIFIC_LEN	64
+#define UIP_BOOTP_MAX_PAYLOAD_LEN	300
+#define UIP_DHCP_VENDOR_SPECIFIC_LEN	312
+#define UIP_DHCP_PORT_SERVER		67
+#define UIP_DHCP_PORT_CLIENT		68
+#define UIP_DHCP_MACPAD_LEN		10
+#define UIP_DHCP_HOSTNAME_LEN		64
+#define UIP_DHCP_FILENAME_LEN		128
+#define UIP_DHCP_MAGIC_COOKIE		0x63825363
+#define UIP_DHCP_MAGIC_COOKIE_LEN	4
+#define UIP_DHCP_LEASE_TIME		0x00003840
+#define UIP_DHCP_MAX_PAYLOAD_LEN	(UIP_BOOTP_MAX_PAYLOAD_LEN - UIP_BOOTP_VENDOR_SPECIFIC_LEN +  UIP_DHCP_VENDOR_SPECIFIC_LEN)
+#define UIP_DHCP_OPTION_LEN		(UIP_DHCP_VENDOR_SPECIFIC_LEN - UIP_DHCP_MAGIC_COOKIE_LEN)
+#define UIP_DHCP_DISCOVER		1
+#define UIP_DHCP_OFFER			2
+#define UIP_DHCP_REQUEST		3
+#define UIP_DHCP_ACK			5
+#define UIP_DHCP_MAX_DNS_SERVER_NR	3
+#define UIP_DHCP_MAX_DOMAIN_NAME_LEN	256
+#define UIP_DHCP_TAG_MSG_TYPE		53
+#define UIP_DHCP_TAG_MSG_TYPE_LEN	1
+#define UIP_DHCP_TAG_SERVER_ID		54
+#define UIP_DHCP_TAG_SERVER_ID_LEN	4
+#define UIP_DHCP_TAG_LEASE_TIME		51
+#define UIP_DHCP_TAG_LEASE_TIME_LEN	4
+#define UIP_DHCP_TAG_SUBMASK		1
+#define UIP_DHCP_TAG_SUBMASK_LEN	4
+#define UIP_DHCP_TAG_ROUTER		3
+#define UIP_DHCP_TAG_ROUTER_LEN		4
+#define UIP_DHCP_TAG_ROOT		17
+#define UIP_DHCP_TAG_ROOT_LEN		4
+#define UIP_DHCP_TAG_DNS_SERVER		6
+#define UIP_DHCP_TAG_DNS_SERVER_LEN	4
+#define UIP_DHCP_TAG_DOMAIN_NAME	15
+#define UIP_DHCP_TAG_END		255
+
+/*
+ * IP package maxium len == 64 KBytes
+ * IP header == 20 Bytes
+ * TCP header == 20 Bytes
+ * UDP header == 8 Bytes
+ */
+#define UIP_MAX_TCP_PAYLOAD	(64*1024 - 20 - 20 - 1)
+#define UIP_MAX_UDP_PAYLOAD	(64*1024 - 20 -  8 - 1)
+
+struct uip_eth_addr {
+	u8 addr[6];
+};
+
+struct uip_eth {
+	struct uip_eth_addr dst;
+	struct uip_eth_addr src;
+	u16 type;
+} __attribute__((packed));
+
+struct uip_arp {
+	struct uip_eth eth;
+	u16 hwtype;
+	u16 proto;
+	u8 hwlen;
+	u8 protolen;
+	u16 op;
+	struct uip_eth_addr smac;
+	u32 sip;
+	struct uip_eth_addr dmac;
+	u32 dip;
+} __attribute__((packed));
+
+struct uip_ip {
+	struct uip_eth eth;
+	u8 vhl;
+	u8 tos;
+	/*
+	 * len = IP hdr +  IP payload
+	 */
+	u16 len;
+	u16 id;
+	u16 flgfrag;
+	u8 ttl;
+	u8 proto;
+	u16 csum;
+	u32 sip;
+	u32 dip;
+} __attribute__((packed));
+
+struct uip_icmp {
+	struct uip_ip ip;
+	u8 type;
+	u8 code;
+	u16 csum;
+	u16 id;
+	u16 seq;
+} __attribute__((packed));
+
+struct uip_udp {
+	/*
+	 * FIXME: IP Options (IP hdr len > 20 bytes) are not supported
+	 */
+	struct uip_ip ip;
+	u16 sport;
+	u16 dport;
+	/*
+	 * len = UDP hdr +  UDP payload
+	 */
+	u16 len;
+	u16 csum;
+	u8 payload[0];
+} __attribute__((packed));
+
+struct uip_tcp {
+	/*
+	 * FIXME: IP Options (IP hdr len > 20 bytes) are not supported
+	 */
+	struct uip_ip ip;
+	u16 sport;
+	u16 dport;
+	u32 seq;
+	u32 ack;
+	u8  off;
+	u8  flg;
+	u16 win;
+	u16 csum;
+	u16 urgent;
+} __attribute__((packed));
+
+struct uip_pseudo_hdr {
+	u32 sip;
+	u32 dip;
+	u8 zero;
+	u8 proto;
+	u16 len;
+} __attribute__((packed));
+
+struct uip_dhcp {
+	struct uip_udp udp;
+	u8 msg_type;
+	u8 hardware_type;
+	u8 hardware_len;
+	u8 hops;
+	u32 id;
+	u16 time;
+	u16 flg;
+	u32 client_ip;
+	u32 your_ip;
+	u32 server_ip;
+	u32 agent_ip;
+	struct uip_eth_addr client_mac;
+	u8 pad[UIP_DHCP_MACPAD_LEN];
+	u8 server_hostname[UIP_DHCP_HOSTNAME_LEN];
+	u8 boot_filename[UIP_DHCP_FILENAME_LEN];
+	u32 magic_cookie;
+	u8 option[UIP_DHCP_OPTION_LEN];
+} __attribute__((packed));
+
+struct uip_info {
+	struct list_head udp_socket_head;
+	struct list_head tcp_socket_head;
+	pthread_mutex_t udp_socket_lock;
+	pthread_mutex_t tcp_socket_lock;
+	struct uip_eth_addr guest_mac;
+	struct uip_eth_addr host_mac;
+	pthread_cond_t buf_free_cond;
+	pthread_cond_t buf_used_cond;
+	struct list_head buf_head;
+	pthread_mutex_t buf_lock;
+	pthread_t udp_thread;
+	int udp_epollfd;
+	int buf_free_nr;
+	int buf_used_nr;
+	u32 guest_ip;
+	u32 guest_netmask;
+	u32 host_ip;
+	u32 dns_ip[UIP_DHCP_MAX_DNS_SERVER_NR];
+	char *domain_name;
+	u32 buf_nr;
+};
+
+struct uip_buf {
+	struct list_head list;
+	struct uip_info *info;
+	int vnet_len;
+	int eth_len;
+	int status;
+	char *vnet;
+	char *eth;
+	int id;
+};
+
+struct uip_udp_socket {
+	struct sockaddr_in addr;
+	struct list_head list;
+	pthread_mutex_t *lock;
+	u32 dport, sport;
+	u32 dip, sip;
+	int fd;
+};
+
+struct uip_tcp_socket {
+	struct sockaddr_in addr;
+	struct list_head list;
+	struct uip_info *info;
+	pthread_mutex_t *lock;
+	pthread_t thread;
+	u32 dport, sport;
+	u32 guest_acked;
+	/*
+	 * Initial Sequence Number
+	 */
+	u32 isn_server;
+	u32 isn_guest;
+	u32 ack_server;
+	u32 seq_server;
+	int write_done;
+	int read_done;
+	u32 dip, sip;
+	u8 *payload;
+	int fd;
+};
+
+struct uip_tx_arg {
+	struct virtio_net_hdr *vnet;
+	struct uip_info *info;
+	struct uip_eth *eth;
+	int vnet_len;
+	int eth_len;
+};
+
+static inline u16 uip_ip_hdrlen(struct uip_ip *ip)
+{
+	return (ip->vhl & 0x0f) * 4;
+}
+
+static inline u16 uip_ip_len(struct uip_ip *ip)
+{
+	return htons(ip->len);
+}
+
+static inline u16 uip_udp_hdrlen(struct uip_udp *udp)
+{
+	return 8;
+}
+
+static inline u16 uip_udp_len(struct uip_udp *udp)
+{
+	return ntohs(udp->len);
+}
+
+static inline u16 uip_tcp_hdrlen(struct uip_tcp *tcp)
+{
+	return (tcp->off >> 4) * 4;
+}
+
+static inline u16 uip_tcp_len(struct uip_tcp *tcp)
+{
+	struct uip_ip *ip;
+
+	ip = &tcp->ip;
+
+	return uip_ip_len(ip) - uip_ip_hdrlen(ip);
+}
+
+static inline u16 uip_tcp_payloadlen(struct uip_tcp *tcp)
+{
+	return uip_tcp_len(tcp) - uip_tcp_hdrlen(tcp);
+}
+
+static inline u8 *uip_tcp_payload(struct uip_tcp *tcp)
+{
+	return (u8 *)&tcp->sport + uip_tcp_hdrlen(tcp);
+}
+
+static inline bool uip_tcp_is_syn(struct uip_tcp *tcp)
+{
+	return (tcp->flg & UIP_TCP_FLAG_SYN) != 0;
+}
+
+static inline bool uip_tcp_is_fin(struct uip_tcp *tcp)
+{
+	return (tcp->flg & UIP_TCP_FLAG_FIN) != 0;
+}
+
+static inline u32 uip_tcp_isn(struct uip_tcp *tcp)
+{
+	return ntohl(tcp->seq);
+}
+
+static inline u32 uip_tcp_isn_alloc(void)
+{
+	/*
+	 * FIXME: should increase every 4ms
+	 */
+	return 10000000;
+}
+
+static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
+{
+	return sizeof(*eth);
+}
+
+int uip_tx(struct iovec *iov, u16 out, struct uip_info *info);
+int uip_rx(struct iovec *iov, u16 in, struct uip_info *info);
+int uip_init(struct uip_info *info);
+
+int uip_tx_do_ipv4_udp_dhcp(struct uip_tx_arg *arg);
+int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
+int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg);
+int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg);
+int uip_tx_do_ipv4(struct uip_tx_arg *arg);
+int uip_tx_do_arp(struct uip_tx_arg *arg);
+
+u16 uip_csum_icmp(struct uip_icmp *icmp);
+u16 uip_csum_udp(struct uip_udp *udp);
+u16 uip_csum_tcp(struct uip_tcp *tcp);
+u16 uip_csum_ip(struct uip_ip *ip);
+
+struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
+struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf);
+struct uip_buf *uip_buf_get_used(struct uip_info *info);
+struct uip_buf *uip_buf_get_free(struct uip_info *info);
+struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg);
+
+int uip_udp_make_pkg(struct uip_info *info, struct uip_udp_socket *sk, struct uip_buf *buf, u8 *payload, int payload_len);
+bool uip_udp_is_dhcp(struct uip_udp *udp);
+
+int uip_dhcp_get_dns(struct uip_info *info);
+#endif /* KVM__UIP_H */
diff --git a/tools/kvm/include/kvm/util.h b/tools/kvm/include/kvm/util.h
new file mode 100644
index 0000000..dabf544
--- /dev/null
+++ b/tools/kvm/include/kvm/util.h
@@ -0,0 +1,95 @@
+#include <linux/stringify.h>
+
+#ifndef KVM__UTIL_H
+#define KVM__UTIL_H
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/*
+ * Some bits are stolen from perf tool :)
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <linux/types.h>
+
+#ifdef __GNUC__
+#define NORETURN __attribute__((__noreturn__))
+#else
+#define NORETURN
+#ifndef __attribute__
+#define __attribute__(x)
+#endif
+#endif
+
+extern bool do_debug_print;
+
+#define PROT_RW (PROT_READ|PROT_WRITE)
+#define MAP_ANON_NORESERVE (MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE)
+
+extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern void die_perror(const char *s) NORETURN;
+extern int pr_err(const char *err, ...) __attribute__((format (printf, 1, 2)));
+extern void pr_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
+extern void pr_info(const char *err, ...) __attribute__((format (printf, 1, 2)));
+extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
+
+#define pr_debug(fmt, ...)						\
+	do {								\
+		if (do_debug_print)					\
+			pr_info("(%s) %s:%d: " fmt, __FILE__,		\
+				__func__, __LINE__, ##__VA_ARGS__);	\
+	} while (0)
+
+
+#define BUILD_BUG_ON(condition)	((void)sizeof(char[1 - 2*!!(condition)]))
+
+#ifndef BUG_ON_HANDLER
+# define BUG_ON_HANDLER(condition)					\
+	do {								\
+		if ((condition)) {					\
+			pr_err("BUG at %s:%d", __FILE__, __LINE__);	\
+			raise(SIGABRT);					\
+		}							\
+	} while (0)
+#endif
+
+#define BUG_ON(condition)	BUG_ON_HANDLER((condition))
+
+#define DIE_IF(cnd)						\
+do {								\
+	if (cnd)						\
+	die(" at (" __FILE__ ":" __stringify(__LINE__) "): "	\
+		__stringify(cnd) "\n");				\
+} while (0)
+
+#define WARN_ON(condition) ({					\
+	int __ret_warn_on = !!(condition);			\
+	if (__ret_warn_on)					\
+		pr_warning("(%s) %s:%d: failed condition: %s",	\
+				__FILE__, __func__, __LINE__,	\
+				__stringify(condition));	\
+	__ret_warn_on;						\
+})
+
+#define MSECS_TO_USECS(s) ((s) * 1000)
+
+/* Millisecond sleep */
+static inline void msleep(unsigned int msecs)
+{
+	usleep(MSECS_TO_USECS(msecs));
+}
+
+void *mmap_hugetlbfs(const char *htlbfs_path, u64 size);
+
+#endif /* KVM__UTIL_H */
diff --git a/tools/kvm/include/kvm/vesa.h b/tools/kvm/include/kvm/vesa.h
new file mode 100644
index 0000000..ac041d9
--- /dev/null
+++ b/tools/kvm/include/kvm/vesa.h
@@ -0,0 +1,18 @@
+#ifndef KVM__VESA_H
+#define KVM__VESA_H
+
+#include <linux/types.h>
+
+#define VESA_WIDTH	640
+#define VESA_HEIGHT	480
+
+#define VESA_MEM_ADDR	0xd0000000
+#define VESA_MEM_SIZE	(4*VESA_WIDTH*VESA_HEIGHT)
+#define VESA_BPP	32
+
+struct kvm;
+struct biosregs;
+
+struct framebuffer *vesa__init(struct kvm *self);
+
+#endif
diff --git a/tools/kvm/include/kvm/virtio-9p.h b/tools/kvm/include/kvm/virtio-9p.h
new file mode 100644
index 0000000..ac3dc45
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-9p.h
@@ -0,0 +1,74 @@
+#ifndef KVM__VIRTIO_9P_H
+#define KVM__VIRTIO_9P_H
+#include "kvm/virtio.h"
+#include "kvm/pci.h"
+#include "kvm/threadpool.h"
+#include "kvm/virtio-trans.h"
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <linux/list.h>
+
+#define NUM_VIRT_QUEUES		1
+#define VIRTQUEUE_NUM		128
+#define	VIRTIO_P9_DEFAULT_TAG	"kvm_9p"
+#define VIRTIO_P9_HDR_LEN	(sizeof(u32)+sizeof(u8)+sizeof(u16))
+#define VIRTIO_P9_MAX_FID	256
+#define VIRTIO_P9_VERSION_DOTL	"9P2000.L"
+#define MAX_TAG_LEN		32
+
+struct p9_msg {
+	u32			size;
+	u8			cmd;
+	u16			tag;
+	u8			msg[0];
+} __attribute__((packed));
+
+struct p9_fid {
+	u32			fid;
+	u32			uid;
+	u8			is_dir;
+	char			abs_path[PATH_MAX];
+	char			*path;
+	DIR			*dir;
+	int			fd;
+};
+
+struct p9_dev_job {
+	struct virt_queue	*vq;
+	struct p9_dev		*p9dev;
+	struct thread_pool__job job_id;
+};
+
+struct p9_dev {
+	struct list_head	list;
+	struct virtio_trans	vtrans;
+
+	struct virtio_9p_config	*config;
+	u32			features;
+
+	/* virtio queue */
+	struct virt_queue	vqs[NUM_VIRT_QUEUES];
+	struct p9_dev_job	jobs[NUM_VIRT_QUEUES];
+	struct p9_fid		fids[VIRTIO_P9_MAX_FID];
+	char			root_dir[PATH_MAX];
+};
+
+struct p9_pdu {
+	u32			queue_head;
+	size_t			read_offset;
+	size_t			write_offset;
+	u16			out_iov_cnt;
+	u16			in_iov_cnt;
+	struct iovec		in_iov[VIRTQUEUE_NUM];
+	struct iovec		out_iov[VIRTQUEUE_NUM];
+};
+
+struct kvm;
+
+int virtio_9p__register(struct kvm *kvm, const char *root, const char *tag_name);
+int virtio_9p__init(struct kvm *kvm);
+int virtio_p9_pdu_readf(struct p9_pdu *pdu, const char *fmt, ...);
+int virtio_p9_pdu_writef(struct p9_pdu *pdu, const char *fmt, ...);
+
+#endif
diff --git a/tools/kvm/include/kvm/virtio-balloon.h b/tools/kvm/include/kvm/virtio-balloon.h
new file mode 100644
index 0000000..eb49fd4
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-balloon.h
@@ -0,0 +1,8 @@
+#ifndef KVM__BLN_VIRTIO_H
+#define KVM__BLN_VIRTIO_H
+
+struct kvm;
+
+void virtio_bln__init(struct kvm *kvm);
+
+#endif /* KVM__BLN_VIRTIO_H */
diff --git a/tools/kvm/include/kvm/virtio-blk.h b/tools/kvm/include/kvm/virtio-blk.h
new file mode 100644
index 0000000..12e59b6
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-blk.h
@@ -0,0 +1,12 @@
+#ifndef KVM__BLK_VIRTIO_H
+#define KVM__BLK_VIRTIO_H
+
+#include "kvm/disk-image.h"
+
+struct kvm;
+
+int virtio_blk__init(struct kvm *kvm);
+int virtio_blk__exit(struct kvm *kvm);
+void virtio_blk_complete(void *param, long len);
+
+#endif /* KVM__BLK_VIRTIO_H */
diff --git a/tools/kvm/include/kvm/virtio-console.h b/tools/kvm/include/kvm/virtio-console.h
new file mode 100644
index 0000000..50d8653
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-console.h
@@ -0,0 +1,9 @@
+#ifndef KVM__CONSOLE_VIRTIO_H
+#define KVM__CONSOLE_VIRTIO_H
+
+struct kvm;
+
+void virtio_console__init(struct kvm *kvm);
+void virtio_console__inject_interrupt(struct kvm *kvm);
+
+#endif /* KVM__CONSOLE_VIRTIO_H */
diff --git a/tools/kvm/include/kvm/virtio-net.h b/tools/kvm/include/kvm/virtio-net.h
new file mode 100644
index 0000000..a3219b6
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-net.h
@@ -0,0 +1,23 @@
+#ifndef KVM__VIRTIO_NET_H
+#define KVM__VIRTIO_NET_H
+
+struct kvm;
+
+struct virtio_net_params {
+	const char *guest_ip;
+	const char *host_ip;
+	const char *script;
+	char guest_mac[6];
+	char host_mac[6];
+	struct kvm *kvm;
+	int mode;
+	int vhost;
+	int fd;
+};
+
+void virtio_net__init(const struct virtio_net_params *params);
+
+#define NET_MODE_USER	0
+#define NET_MODE_TAP	1
+
+#endif /* KVM__VIRTIO_NET_H */
diff --git a/tools/kvm/include/kvm/virtio-pci-dev.h b/tools/kvm/include/kvm/virtio-pci-dev.h
new file mode 100644
index 0000000..e692bdd
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-pci-dev.h
@@ -0,0 +1,37 @@
+#ifndef VIRTIO_PCI_DEV_H_
+#define VIRTIO_PCI_DEV_H_
+
+#include <linux/virtio_ids.h>
+
+/*
+ * Virtio PCI device constants and resources
+ * they do use (such as irqs and pins).
+ */
+
+#define PCI_DEVICE_ID_VIRTIO_NET		0x1000
+#define PCI_DEVICE_ID_VIRTIO_BLK		0x1001
+#define PCI_DEVICE_ID_VIRTIO_CONSOLE		0x1003
+#define PCI_DEVICE_ID_VIRTIO_RNG		0x1004
+#define PCI_DEVICE_ID_VIRTIO_BLN		0x1005
+#define PCI_DEVICE_ID_VIRTIO_P9			0x1009
+#define PCI_DEVICE_ID_VESA			0x2000
+#define PCI_DEVICE_ID_PCI_SHMEM			0x0001
+
+#define PCI_VENDOR_ID_REDHAT_QUMRANET		0x1af4
+#define PCI_VENDOR_ID_PCI_SHMEM			0x0001
+#define PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET	0x1af4
+
+#define PCI_SUBSYSTEM_ID_VESA			0x0004
+#define PCI_SUBSYSTEM_ID_PCI_SHMEM		0x0001
+
+#define PCI_CLASS_BLK				0x018000
+#define PCI_CLASS_NET				0x020000
+#define PCI_CLASS_CONSOLE			0x078000
+/*
+ * 0xFF Device does not fit in any defined classes
+ */
+#define PCI_CLASS_RNG				0xff0000
+#define PCI_CLASS_BLN				0xff0000
+#define PCI_CLASS_P9				0xff0000
+
+#endif /* VIRTIO_PCI_DEV_H_ */
diff --git a/tools/kvm/include/kvm/virtio-pci.h b/tools/kvm/include/kvm/virtio-pci.h
new file mode 100644
index 0000000..7133314
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-pci.h
@@ -0,0 +1,49 @@
+#ifndef KVM__VIRTIO_PCI_H
+#define KVM__VIRTIO_PCI_H
+
+#include "kvm/pci.h"
+#include "kvm/virtio-trans.h"
+
+#include <linux/types.h>
+
+#define VIRTIO_PCI_MAX_VQ	3
+#define VIRTIO_PCI_MAX_CONFIG	1
+
+struct kvm;
+
+struct virtio_pci_ioevent_param {
+	struct virtio_trans	*vtrans;
+	u32			vq;
+};
+
+struct virtio_pci {
+	struct pci_device_header pci_hdr;
+	void			*dev;
+
+	u16			base_addr;
+	u8			status;
+	u8			isr;
+
+	/* MSI-X */
+	u16			config_vector;
+	u32			config_gsi;
+	u32			vq_vector[VIRTIO_PCI_MAX_VQ];
+	u32			gsis[VIRTIO_PCI_MAX_VQ];
+	u32			msix_io_block;
+	u64			msix_pba;
+	struct msix_table	msix_table[VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG];
+
+	/* virtio queue */
+	u16			queue_selector;
+	struct virtio_pci_ioevent_param ioeventfds[VIRTIO_PCI_MAX_VQ];
+};
+
+int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
+			int device_id, int subsys_id, int class);
+int virtio_pci__exit(struct kvm *kvm, struct virtio_trans *vtrans);
+int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq);
+int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans);
+
+struct virtio_trans_ops *virtio_pci__get_trans_ops(void);
+
+#endif
diff --git a/tools/kvm/include/kvm/virtio-rng.h b/tools/kvm/include/kvm/virtio-rng.h
new file mode 100644
index 0000000..b585b37
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-rng.h
@@ -0,0 +1,9 @@
+#ifndef KVM__RNG_VIRTIO_H
+#define KVM__RNG_VIRTIO_H
+
+struct kvm;
+
+int virtio_rng__init(struct kvm *kvm);
+int virtio_rng__exit(struct kvm *kvm);
+
+#endif /* KVM__RNG_VIRTIO_H */
diff --git a/tools/kvm/include/kvm/virtio-trans.h b/tools/kvm/include/kvm/virtio-trans.h
new file mode 100644
index 0000000..f2e433f
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio-trans.h
@@ -0,0 +1,44 @@
+#ifndef KVM__VIRTIO_TRANS_H
+#define KVM__VIRTIO_TRANS_H
+
+#include "kvm/kvm.h"
+
+enum virtio_trans_type {
+	VIRTIO_PCI,
+};
+
+struct virtio_trans;
+
+struct virtio_ops {
+	void (*set_config)(struct kvm *kvm, void *dev, u8 data, u32 offset);
+	u8 (*get_config)(struct kvm *kvm, void *dev, u32 offset);
+
+	u32 (*get_host_features)(struct kvm *kvm, void *dev);
+	void (*set_guest_features)(struct kvm *kvm, void *dev, u32 features);
+
+	int (*init_vq)(struct kvm *kvm, void *dev, u32 vq, u32 pfn);
+	int (*notify_vq)(struct kvm *kvm, void *dev, u32 vq);
+	int (*get_pfn_vq)(struct kvm *kvm, void *dev, u32 vq);
+	int (*get_size_vq)(struct kvm *kvm, void *dev, u32 vq);
+	void (*notify_vq_gsi)(struct kvm *kvm, void *dev, u32 vq, u32 gsi);
+	void (*notify_vq_eventfd)(struct kvm *kvm, void *dev, u32 vq, u32 efd);
+};
+
+struct virtio_trans_ops {
+	int (*init)(struct kvm *kvm, struct virtio_trans *vtrans, void *dev, int device_id,
+			int subsys_id, int class);
+	int (*uninit)(struct kvm *kvm, struct virtio_trans *vtrans);
+	int (*signal_vq)(struct kvm *kvm, struct virtio_trans *virtio_trans, u32 queueid);
+	int (*signal_config)(struct kvm *kvm, struct virtio_trans *virtio_trans);
+};
+
+struct virtio_trans {
+	void			*virtio;
+	enum virtio_trans_type	type;
+	struct virtio_trans_ops	*trans_ops;
+	struct virtio_ops	*virtio_ops;
+};
+
+int virtio_trans_init(struct virtio_trans *vtrans, enum virtio_trans_type type);
+
+#endif
\ No newline at end of file
diff --git a/tools/kvm/include/kvm/virtio.h b/tools/kvm/include/kvm/virtio.h
new file mode 100644
index 0000000..610f4d0
--- /dev/null
+++ b/tools/kvm/include/kvm/virtio.h
@@ -0,0 +1,67 @@
+#ifndef KVM__VIRTIO_H
+#define KVM__VIRTIO_H
+
+#include <linux/virtio_ring.h>
+#include <linux/virtio_pci.h>
+
+#include <linux/types.h>
+#include <sys/uio.h>
+
+#include "kvm/kvm.h"
+
+#define VIRTIO_IRQ_LOW		0
+#define VIRTIO_IRQ_HIGH		1
+
+#define VIRTIO_PCI_O_CONFIG	0
+#define VIRTIO_PCI_O_MSIX	1
+
+struct virt_queue {
+	struct vring	vring;
+	u32		pfn;
+	/* The last_avail_idx field is an index to ->ring of struct vring_avail.
+	   It's where we assume the next request index is at.  */
+	u16		last_avail_idx;
+	u16		last_used_signalled;
+};
+
+static inline u16 virt_queue__pop(struct virt_queue *queue)
+{
+	return queue->vring.avail->ring[queue->last_avail_idx++ % queue->vring.num];
+}
+
+static inline struct vring_desc *virt_queue__get_desc(struct virt_queue *queue, u16 desc_ndx)
+{
+	return &queue->vring.desc[desc_ndx];
+}
+
+static inline bool virt_queue__available(struct virt_queue *vq)
+{
+	if (!vq->vring.avail)
+		return 0;
+
+	vring_avail_event(&vq->vring) = vq->last_avail_idx;
+	return vq->vring.avail->idx !=  vq->last_avail_idx;
+}
+
+/*
+ * Warning: on 32-bit hosts, shifting pfn left may cause a truncation of pfn values
+ * higher than 4GB - thus, pointing to the wrong area in guest virtual memory space
+ * and breaking the virt queue which owns this pfn.
+ */
+static inline void *guest_pfn_to_host(struct kvm *kvm, u32 pfn)
+{
+	return guest_flat_to_host(kvm, (unsigned long)pfn << VIRTIO_PCI_QUEUE_ADDR_SHIFT);
+}
+
+
+struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, u32 head, u32 len);
+
+bool virtio_queue__should_signal(struct virt_queue *vq);
+u16 virt_queue__get_iov(struct virt_queue *vq, struct iovec iov[], u16 *out, u16 *in, struct kvm *kvm);
+u16 virt_queue__get_head_iov(struct virt_queue *vq, struct iovec iov[], u16 *out, u16 *in, u16 head, struct kvm *kvm);
+u16 virt_queue__get_inout_iov(struct kvm *kvm, struct virt_queue *queue,
+			      struct iovec in_iov[], struct iovec out_iov[],
+			      u16 *in, u16 *out);
+int virtio__get_dev_specific_field(int offset, bool msix, u32 *config_off);
+
+#endif /* KVM__VIRTIO_H */
diff --git a/tools/kvm/include/kvm/vnc.h b/tools/kvm/include/kvm/vnc.h
new file mode 100644
index 0000000..3278c07
--- /dev/null
+++ b/tools/kvm/include/kvm/vnc.h
@@ -0,0 +1,20 @@
+#ifndef KVM__VNC_H
+#define KVM__VNC_H
+
+struct framebuffer;
+
+#ifdef CONFIG_HAS_VNCSERVER
+int vnc__init(struct framebuffer *fb);
+int vnc__exit(struct framebuffer *fb);
+#else
+static inline int vnc__init(struct framebuffer *fb)
+{
+	return 0;
+}
+static inline int vnc__exit(struct framebuffer *fb)
+{
+	return 0;
+}
+#endif
+
+#endif /* KVM__VNC_H */
diff --git a/tools/kvm/include/linux/bitops.h b/tools/kvm/include/linux/bitops.h
new file mode 100644
index 0000000..56448b7
--- /dev/null
+++ b/tools/kvm/include/linux/bitops.h
@@ -0,0 +1,33 @@
+#ifndef _KVM_LINUX_BITOPS_H_
+#define _KVM_LINUX_BITOPS_H_
+
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <asm/hweight.h>
+
+#define BITS_PER_LONG __WORDSIZE
+#define BITS_PER_BYTE           8
+#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+
+static inline void set_bit(int nr, unsigned long *addr)
+{
+	addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
+}
+
+static inline void clear_bit(int nr, unsigned long *addr)
+{
+	addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
+}
+
+static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
+{
+	return ((1UL << (nr % BITS_PER_LONG)) &
+		(((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
+}
+
+static inline unsigned long hweight_long(unsigned long w)
+{
+	return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
+}
+
+#endif
diff --git a/tools/kvm/include/linux/byteorder.h b/tools/kvm/include/linux/byteorder.h
new file mode 100644
index 0000000..c490de8
--- /dev/null
+++ b/tools/kvm/include/linux/byteorder.h
@@ -0,0 +1,7 @@
+#ifndef __BYTE_ORDER_H__
+#define __BYTE_ORDER_H__
+
+#include <asm/byteorder.h>
+#include <linux/byteorder/generic.h>
+
+#endif
diff --git a/tools/kvm/include/linux/compiler.h b/tools/kvm/include/linux/compiler.h
new file mode 100644
index 0000000..b9c5346
--- /dev/null
+++ b/tools/kvm/include/linux/compiler.h
@@ -0,0 +1,19 @@
+#ifndef _PERF_LINUX_COMPILER_H_
+#define _PERF_LINUX_COMPILER_H_
+
+#ifndef __always_inline
+#define __always_inline	inline
+#endif
+#define __user
+
+#ifndef __attribute_const__
+#define __attribute_const__
+#endif
+
+#define __used		__attribute__((__unused__))
+#define __iomem
+#define __force
+#define __must_check
+#define unlikely
+
+#endif
diff --git a/tools/kvm/include/linux/kernel.h b/tools/kvm/include/linux/kernel.h
new file mode 100644
index 0000000..d2ec4a3
--- /dev/null
+++ b/tools/kvm/include/linux/kernel.h
@@ -0,0 +1,39 @@
+
+#ifndef KVM__LINUX_KERNEL_H_
+#define KVM__LINUX_KERNEL_H_
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define ALIGN(x,a)		__ALIGN_MASK(x,(typeof(x))(a)-1)
+#define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask))
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:	the pointer to the member.
+ * @type:	the type of the container struct this is embedded in.
+ * @member:	the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({			\
+	const typeof(((type *)0)->member) * __mptr = (ptr);	\
+	(type *)((char *)__mptr - offsetof(type, member)); })
+#endif
+
+#define min(x, y) ({				\
+	typeof(x) _min1 = (x);			\
+	typeof(y) _min2 = (y);			\
+	(void) (&_min1 == &_min2);		\
+	_min1 < _min2 ? _min1 : _min2; })
+
+#define max(x, y) ({				\
+	typeof(x) _max1 = (x);			\
+	typeof(y) _max2 = (y);			\
+	(void) (&_max1 == &_max2);		\
+	_max1 > _max2 ? _max1 : _max2; })
+
+#endif
diff --git a/tools/kvm/include/linux/module.h b/tools/kvm/include/linux/module.h
new file mode 100644
index 0000000..0e4c6a3
--- /dev/null
+++ b/tools/kvm/include/linux/module.h
@@ -0,0 +1,6 @@
+#ifndef KVM__LINUX_MODULE_H
+#define KVM__LINUX_MODULE_H
+
+#define EXPORT_SYMBOL(name)
+
+#endif
diff --git a/tools/kvm/include/linux/prefetch.h b/tools/kvm/include/linux/prefetch.h
new file mode 100644
index 0000000..62f6788
--- /dev/null
+++ b/tools/kvm/include/linux/prefetch.h
@@ -0,0 +1,6 @@
+#ifndef KVM__LINUX_PREFETCH_H
+#define KVM__LINUX_PREFETCH_H
+
+static inline void prefetch(void *a __attribute__((unused))) { }
+
+#endif
diff --git a/tools/kvm/include/linux/types.h b/tools/kvm/include/linux/types.h
new file mode 100644
index 0000000..5e20f10
--- /dev/null
+++ b/tools/kvm/include/linux/types.h
@@ -0,0 +1,51 @@
+#ifndef LINUX_TYPES_H
+#define LINUX_TYPES_H
+
+#include <kvm/compiler.h>
+#define __SANE_USERSPACE_TYPES__	/* For PPC64, to get LL64 types */
+#include <asm/types.h>
+
+typedef __u64 u64;
+typedef __s64 s64;
+
+typedef __u32 u32;
+typedef __s32 s32;
+
+typedef __u16 u16;
+typedef __s16 s16;
+
+typedef __u8  u8;
+typedef __s8  s8;
+
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+struct hlist_head {
+	struct hlist_node *first;
+};
+
+struct hlist_node {
+	struct hlist_node *next, **pprev;
+};
+
+#endif /* LINUX_TYPES_H */
diff --git a/tools/kvm/ioeventfd.c b/tools/kvm/ioeventfd.c
new file mode 100644
index 0000000..9b328cd
--- /dev/null
+++ b/tools/kvm/ioeventfd.c
@@ -0,0 +1,209 @@
+#include <sys/epoll.h>
+#include <sys/ioctl.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <linux/kernel.h>
+#include <linux/kvm.h>
+#include <linux/types.h>
+
+#include "kvm/ioeventfd.h"
+#include "kvm/kvm.h"
+#include "kvm/util.h"
+
+#define IOEVENTFD_MAX_EVENTS	20
+
+static struct	epoll_event events[IOEVENTFD_MAX_EVENTS];
+static int	epoll_fd, epoll_stop_fd;
+static LIST_HEAD(used_ioevents);
+static bool	ioeventfd_avail;
+
+static void *ioeventfd__thread(void *param)
+{
+	u64 tmp = 1;
+
+	for (;;) {
+		int nfds, i;
+
+		nfds = epoll_wait(epoll_fd, events, IOEVENTFD_MAX_EVENTS, -1);
+		for (i = 0; i < nfds; i++) {
+			struct ioevent *ioevent;
+
+			if (events[i].data.fd == epoll_stop_fd)
+				goto done;
+
+			ioevent = events[i].data.ptr;
+
+			if (read(ioevent->fd, &tmp, sizeof(tmp)) < 0)
+				die("Failed reading event");
+
+			ioevent->fn(ioevent->fn_kvm, ioevent->fn_ptr);
+		}
+	}
+
+done:
+	tmp = 1;
+	tmp = write(epoll_stop_fd, &tmp, sizeof(tmp));
+
+	return NULL;
+}
+
+static int ioeventfd__start(void)
+{
+	pthread_t thread;
+
+	if (!ioeventfd_avail)
+		return -ENOSYS;
+
+	return pthread_create(&thread, NULL, ioeventfd__thread, NULL);
+}
+
+int ioeventfd__init(struct kvm *kvm)
+{
+	struct epoll_event epoll_event = {.events = EPOLLIN};
+	int r;
+
+	ioeventfd_avail = kvm__supports_extension(kvm, KVM_CAP_IOEVENTFD);
+	if (!ioeventfd_avail)
+		return 1; /* Not fatal, but let caller determine no-go. */
+
+	epoll_fd = epoll_create(IOEVENTFD_MAX_EVENTS);
+	if (epoll_fd < 0)
+		return -errno;
+
+	epoll_stop_fd = eventfd(0, 0);
+	epoll_event.data.fd = epoll_stop_fd;
+
+	r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, epoll_stop_fd, &epoll_event);
+	if (r < 0)
+		goto cleanup;
+
+	r = ioeventfd__start();
+	if (r < 0)
+		goto cleanup;
+
+	r = 0;
+
+	return r;
+
+cleanup:
+	close(epoll_stop_fd);
+	close(epoll_fd);
+
+	return r;
+}
+
+int ioeventfd__exit(struct kvm *kvm)
+{
+	u64 tmp = 1;
+	int r;
+
+	if (!ioeventfd_avail)
+		return 0;
+
+	r = write(epoll_stop_fd, &tmp, sizeof(tmp));
+	if (r < 0)
+		return r;
+
+	r = read(epoll_stop_fd, &tmp, sizeof(tmp));
+	if (r < 0)
+		return r;
+
+	close(epoll_fd);
+	close(epoll_stop_fd);
+
+	return 0;
+}
+
+int ioeventfd__add_event(struct ioevent *ioevent)
+{
+	struct kvm_ioeventfd kvm_ioevent;
+	struct epoll_event epoll_event;
+	struct ioevent *new_ioevent;
+	int event, r;
+
+	if (!ioeventfd_avail)
+		return -ENOSYS;
+
+	new_ioevent = malloc(sizeof(*new_ioevent));
+	if (new_ioevent == NULL)
+		return -ENOMEM;
+
+	*new_ioevent = *ioevent;
+	event = new_ioevent->fd;
+
+	kvm_ioevent = (struct kvm_ioeventfd) {
+		.addr			= ioevent->io_addr,
+		.len			= ioevent->io_len,
+		.datamatch		= ioevent->datamatch,
+		.fd			= event,
+		.flags			= KVM_IOEVENTFD_FLAG_PIO | KVM_IOEVENTFD_FLAG_DATAMATCH,
+	};
+
+	r = ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent);
+	if (r) {
+		r = -errno;
+		goto cleanup;
+	}
+
+	epoll_event = (struct epoll_event) {
+		.events			= EPOLLIN,
+		.data.ptr		= new_ioevent,
+	};
+
+	r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event, &epoll_event);
+	if (r) {
+		r = -errno;
+		goto cleanup;
+	}
+
+	list_add_tail(&new_ioevent->list, &used_ioevents);
+
+	return 0;
+
+cleanup:
+	free(new_ioevent);
+	return r;
+}
+
+int ioeventfd__del_event(u64 addr, u64 datamatch)
+{
+	struct kvm_ioeventfd kvm_ioevent;
+	struct ioevent *ioevent;
+	u8 found = 0;
+
+	if (!ioeventfd_avail)
+		return -ENOSYS;
+
+	list_for_each_entry(ioevent, &used_ioevents, list) {
+		if (ioevent->io_addr == addr) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found == 0 || ioevent == NULL)
+		return -ENOENT;
+
+	kvm_ioevent = (struct kvm_ioeventfd) {
+		.addr			= ioevent->io_addr,
+		.len			= ioevent->io_len,
+		.datamatch		= ioevent->datamatch,
+		.flags			= KVM_IOEVENTFD_FLAG_PIO
+					| KVM_IOEVENTFD_FLAG_DEASSIGN
+					| KVM_IOEVENTFD_FLAG_DATAMATCH,
+	};
+
+	ioctl(ioevent->fn_kvm->vm_fd, KVM_IOEVENTFD, &kvm_ioevent);
+
+	epoll_ctl(epoll_fd, EPOLL_CTL_DEL, ioevent->fd, NULL);
+
+	list_del(&ioevent->list);
+
+	close(ioevent->fd);
+	free(ioevent);
+
+	return 0;
+}
diff --git a/tools/kvm/ioport.c b/tools/kvm/ioport.c
new file mode 100644
index 0000000..662a78b
--- /dev/null
+++ b/tools/kvm/ioport.c
@@ -0,0 +1,195 @@
+#include "kvm/ioport.h"
+
+#include "kvm/kvm.h"
+#include "kvm/util.h"
+#include "kvm/brlock.h"
+#include "kvm/rbtree-interval.h"
+#include "kvm/mutex.h"
+
+#include <linux/kvm.h>	/* for KVM_EXIT_* */
+#include <linux/types.h>
+
+#include <stdbool.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ioport_node(n) rb_entry(n, struct ioport, node)
+
+DEFINE_MUTEX(ioport_mutex);
+
+static u16			free_io_port_idx; /* protected by ioport_mutex */
+
+static struct rb_root		ioport_tree = RB_ROOT;
+bool				ioport_debug;
+
+static u16 ioport__find_free_port(void)
+{
+	u16 free_port;
+
+	mutex_lock(&ioport_mutex);
+	free_port = IOPORT_START + free_io_port_idx * IOPORT_SIZE;
+	free_io_port_idx++;
+	mutex_unlock(&ioport_mutex);
+
+	return free_port;
+}
+
+static struct ioport *ioport_search(struct rb_root *root, u64 addr)
+{
+	struct rb_int_node *node;
+
+	node = rb_int_search_single(root, addr);
+	if (node == NULL)
+		return NULL;
+
+	return ioport_node(node);
+}
+
+static int ioport_insert(struct rb_root *root, struct ioport *data)
+{
+	return rb_int_insert(root, &data->node);
+}
+
+static void ioport_remove(struct rb_root *root, struct ioport *data)
+{
+	rb_int_erase(root, &data->node);
+}
+
+int ioport__register(u16 port, struct ioport_operations *ops, int count, void *param)
+{
+	struct ioport *entry;
+	int r;
+
+	br_write_lock();
+	if (port == IOPORT_EMPTY)
+		port = ioport__find_free_port();
+
+	entry = ioport_search(&ioport_tree, port);
+	if (entry) {
+		pr_warning("ioport re-registered: %x", port);
+		rb_int_erase(&ioport_tree, &entry->node);
+	}
+
+	entry = malloc(sizeof(*entry));
+	if (entry == NULL)
+		return -ENOMEM;
+
+	*entry = (struct ioport) {
+		.node	= RB_INT_INIT(port, port + count),
+		.ops	= ops,
+		.priv	= param,
+	};
+
+	r = ioport_insert(&ioport_tree, entry);
+	if (r < 0) {
+		free(entry);
+		br_write_unlock();
+		return r;
+	}
+	br_write_unlock();
+
+	return port;
+}
+
+int ioport__unregister(u16 port)
+{
+	struct ioport *entry;
+	int r;
+
+	br_write_lock();
+
+	r = -ENOENT;
+	entry = ioport_search(&ioport_tree, port);
+	if (!entry)
+		goto done;
+
+	ioport_remove(&ioport_tree, entry);
+
+	free(entry);
+
+	r = 0;
+
+done:
+	br_write_unlock();
+
+	return r;
+}
+
+static void ioport__unregister_all(void)
+{
+	struct ioport *entry;
+	struct rb_node *rb;
+	struct rb_int_node *rb_node;
+
+	rb = rb_first(&ioport_tree);
+	while (rb) {
+		rb_node = rb_int(rb);
+		entry = ioport_node(rb_node);
+		ioport_remove(&ioport_tree, entry);
+		free(entry);
+		rb = rb_first(&ioport_tree);
+	}
+}
+
+static const char *to_direction(int direction)
+{
+	if (direction == KVM_EXIT_IO_IN)
+		return "IN";
+	else
+		return "OUT";
+}
+
+static void ioport_error(u16 port, void *data, int direction, int size, u32 count)
+{
+	fprintf(stderr, "IO error: %s port=%x, size=%d, count=%u\n", to_direction(direction), port, size, count);
+}
+
+bool kvm__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
+{
+	struct ioport_operations *ops;
+	bool ret = false;
+	struct ioport *entry;
+	void *ptr = data;
+
+	br_read_lock();
+	entry = ioport_search(&ioport_tree, port);
+	if (!entry)
+		goto error;
+
+	ops	= entry->ops;
+
+	while (count--) {
+		if (direction == KVM_EXIT_IO_IN && ops->io_in)
+				ret = ops->io_in(entry, kvm, port, ptr, size);
+		else if (ops->io_out)
+				ret = ops->io_out(entry, kvm, port, ptr, size);
+
+		ptr += size;
+	}
+
+	br_read_unlock();
+
+	if (!ret)
+		goto error;
+
+	return true;
+error:
+	br_read_unlock();
+
+	if (ioport_debug)
+		ioport_error(port, data, direction, size, count);
+
+	return !ioport_debug;
+}
+
+int ioport__init(struct kvm *kvm)
+{
+	return 0;
+}
+
+int ioport__exit(struct kvm *kvm)
+{
+	ioport__unregister_all();
+	return 0;
+}
diff --git a/tools/kvm/kvm-cmd.c b/tools/kvm/kvm-cmd.c
new file mode 100644
index 0000000..2520b08
--- /dev/null
+++ b/tools/kvm/kvm-cmd.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/* user defined header files */
+#include "kvm/builtin-debug.h"
+#include "kvm/builtin-pause.h"
+#include "kvm/builtin-resume.h"
+#include "kvm/builtin-balloon.h"
+#include "kvm/builtin-list.h"
+#include "kvm/builtin-version.h"
+#include "kvm/builtin-setup.h"
+#include "kvm/builtin-stop.h"
+#include "kvm/builtin-stat.h"
+#include "kvm/builtin-help.h"
+#include "kvm/builtin-sandbox.h"
+#include "kvm/kvm-cmd.h"
+#include "kvm/builtin-run.h"
+#include "kvm/util.h"
+
+struct cmd_struct kvm_commands[] = {
+	{ "pause",	kvm_cmd_pause,		kvm_pause_help,		0 },
+	{ "resume",	kvm_cmd_resume,		kvm_resume_help,	0 },
+	{ "debug",	kvm_cmd_debug,		kvm_debug_help,		0 },
+	{ "balloon",	kvm_cmd_balloon,	kvm_balloon_help,	0 },
+	{ "list",	kvm_cmd_list,		kvm_list_help,		0 },
+	{ "version",	kvm_cmd_version,	NULL,			0 },
+	{ "--version",	kvm_cmd_version,	NULL,			0 },
+	{ "stop",	kvm_cmd_stop,		kvm_stop_help,		0 },
+	{ "stat",	kvm_cmd_stat,		kvm_stat_help,		0 },
+	{ "help",	kvm_cmd_help,		NULL,			0 },
+	{ "setup",	kvm_cmd_setup,		kvm_setup_help,		0 },
+	{ "run",	kvm_cmd_run,		kvm_run_help,		0 },
+	{ "sandbox",	kvm_cmd_sandbox,	kvm_run_help,		0 },
+	{ NULL,		NULL,			NULL,			0 },
+};
+
+/*
+ * kvm_get_command: Searches the command in an array of the commands and
+ * returns a pointer to cmd_struct if a match is found.
+ *
+ * Input parameters:
+ * command: Array of possible commands. The last entry in the array must be
+ *          NULL.
+ * cmd: A string command to search in the array
+ *
+ * Return Value:
+ * NULL: If the cmd is not matched with any of the command in the command array
+ * p: Pointer to cmd_struct of the matching command
+ */
+struct cmd_struct *kvm_get_command(struct cmd_struct *command,
+		const char *cmd)
+{
+	struct cmd_struct *p = command;
+
+	while (p->cmd) {
+		if (!strcmp(p->cmd, cmd))
+			return p;
+		p++;
+	}
+	return NULL;
+}
+
+int handle_command(struct cmd_struct *command, int argc, const char **argv)
+{
+	struct cmd_struct *p;
+	const char *prefix = NULL;
+	int ret = 0;
+
+	if (!argv || !*argv) {
+		p = kvm_get_command(command, "help");
+		BUG_ON(!p);
+		return p->fn(argc, argv, prefix);
+	}
+
+	p = kvm_get_command(command, argv[0]);
+	if (!p) {
+		p = kvm_get_command(command, "help");
+		BUG_ON(!p);
+		p->fn(0, NULL, prefix);
+		return EINVAL;
+	}
+
+	ret = p->fn(argc - 1, &argv[1], prefix);
+	if (ret < 0) {
+		if (errno == EPERM)
+			die("Permission error - are you root?");
+	}
+
+	return ret;
+}
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
new file mode 100644
index 0000000..12791dd
--- /dev/null
+++ b/tools/kvm/kvm-cpu.c
@@ -0,0 +1,175 @@
+#include "kvm/kvm-cpu.h"
+
+#include "kvm/symbol.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+extern struct kvm_cpu **kvm_cpus;
+extern __thread struct kvm_cpu *current_kvm_cpu;
+
+void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu)
+{
+	struct kvm_guest_debug debug = {
+		.control	= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP,
+	};
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_GUEST_DEBUG, &debug) < 0)
+		pr_warning("KVM_SET_GUEST_DEBUG failed");
+}
+
+void kvm_cpu__run(struct kvm_cpu *vcpu)
+{
+	int err;
+
+	if (!vcpu->is_running)
+		return;
+
+	err = ioctl(vcpu->vcpu_fd, KVM_RUN, 0);
+	if (err < 0 && (errno != EINTR && errno != EAGAIN))
+		die_perror("KVM_RUN failed");
+}
+
+static void kvm_cpu_signal_handler(int signum)
+{
+	if (signum == SIGKVMEXIT) {
+		if (current_kvm_cpu && current_kvm_cpu->is_running) {
+			current_kvm_cpu->is_running = false;
+			kvm__continue();
+		}
+	} else if (signum == SIGKVMPAUSE) {
+		current_kvm_cpu->paused = 1;
+	}
+}
+
+static void kvm_cpu__handle_coalesced_mmio(struct kvm_cpu *cpu)
+{
+	if (cpu->ring) {
+		while (cpu->ring->first != cpu->ring->last) {
+			struct kvm_coalesced_mmio *m;
+			m = &cpu->ring->coalesced_mmio[cpu->ring->first];
+			kvm_cpu__emulate_mmio(cpu->kvm,
+					      m->phys_addr,
+					      m->data,
+					      m->len,
+					      1);
+			cpu->ring->first = (cpu->ring->first + 1) % KVM_COALESCED_MMIO_MAX;
+		}
+	}
+}
+
+void kvm_cpu__reboot(void)
+{
+	int i;
+
+	/* The kvm_cpus array contains a null pointer in the last location */
+	for (i = 0; ; i++) {
+		if (kvm_cpus[i])
+			pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT);
+		else
+			break;
+	}
+}
+
+int kvm_cpu__start(struct kvm_cpu *cpu)
+{
+	sigset_t sigset;
+
+	sigemptyset(&sigset);
+	sigaddset(&sigset, SIGALRM);
+
+	pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+
+	signal(SIGKVMEXIT, kvm_cpu_signal_handler);
+	signal(SIGKVMPAUSE, kvm_cpu_signal_handler);
+
+	kvm_cpu__reset_vcpu(cpu);
+
+	if (cpu->kvm->single_step)
+		kvm_cpu__enable_singlestep(cpu);
+
+	while (cpu->is_running) {
+		if (cpu->paused) {
+			kvm__notify_paused();
+			cpu->paused = 0;
+		}
+
+		if (cpu->needs_nmi) {
+			kvm_cpu__arch_nmi(cpu);
+			cpu->needs_nmi = 0;
+		}
+
+		kvm_cpu__run(cpu);
+
+		switch (cpu->kvm_run->exit_reason) {
+		case KVM_EXIT_UNKNOWN:
+			break;
+		case KVM_EXIT_DEBUG:
+			kvm_cpu__show_registers(cpu);
+			kvm_cpu__show_code(cpu);
+			break;
+		case KVM_EXIT_IO: {
+			bool ret;
+
+			ret = kvm_cpu__emulate_io(cpu->kvm,
+						  cpu->kvm_run->io.port,
+						  (u8 *)cpu->kvm_run +
+						  cpu->kvm_run->io.data_offset,
+						  cpu->kvm_run->io.direction,
+						  cpu->kvm_run->io.size,
+						  cpu->kvm_run->io.count);
+
+			if (!ret)
+				goto panic_kvm;
+			break;
+		}
+		case KVM_EXIT_MMIO: {
+			bool ret;
+
+			/*
+			 * If we had MMIO exit, coalesced ring should be processed
+			 * *before* processing the exit itself
+			 */
+			kvm_cpu__handle_coalesced_mmio(cpu);
+
+			ret = kvm_cpu__emulate_mmio(cpu->kvm,
+						    cpu->kvm_run->mmio.phys_addr,
+						    cpu->kvm_run->mmio.data,
+						    cpu->kvm_run->mmio.len,
+						    cpu->kvm_run->mmio.is_write);
+
+			if (!ret)
+				goto panic_kvm;
+			break;
+		}
+		case KVM_EXIT_INTR:
+			if (cpu->is_running)
+				break;
+			goto exit_kvm;
+		case KVM_EXIT_SHUTDOWN:
+			goto exit_kvm;
+		default: {
+			bool ret;
+
+			ret = kvm_cpu__handle_exit(cpu);
+			if (!ret)
+				goto panic_kvm;
+			break;
+		}
+		}
+		kvm_cpu__handle_coalesced_mmio(cpu);
+	}
+
+exit_kvm:
+	return 0;
+
+panic_kvm:
+	return 1;
+}
diff --git a/tools/kvm/kvm-ipc.c b/tools/kvm/kvm-ipc.c
new file mode 100644
index 0000000..257c806c
--- /dev/null
+++ b/tools/kvm/kvm-ipc.c
@@ -0,0 +1,231 @@
+#include "kvm/kvm-ipc.h"
+#include "kvm/rwsem.h"
+#include "kvm/read-write.h"
+#include "kvm/util.h"
+
+#include <sys/epoll.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/eventfd.h>
+
+struct kvm_ipc_head {
+	u32 type;
+	u32 len;
+};
+
+#define KVM_IPC_MAX_MSGS 16
+
+static void (*msgs[KVM_IPC_MAX_MSGS])(int fd, u32 type, u32 len, u8 *msg);
+static DECLARE_RWSEM(msgs_rwlock);
+static int epoll_fd, server_fd, stop_fd;
+static pthread_t thread;
+
+int kvm_ipc__register_handler(u32 type, void (*cb)(int fd, u32 type, u32 len, u8 *msg))
+{
+	if (type >= KVM_IPC_MAX_MSGS)
+		return -ENOSPC;
+
+	down_write(&msgs_rwlock);
+	msgs[type] = cb;
+	up_write(&msgs_rwlock);
+
+	return 0;
+}
+
+int kvm_ipc__send(int fd, u32 type)
+{
+	struct kvm_ipc_head head = {.type = type, .len = 0,};
+
+	if (write_in_full(fd, &head, sizeof(head)) < 0)
+		return -1;
+
+	return 0;
+}
+
+int kvm_ipc__send_msg(int fd, u32 type, u32 len, u8 *msg)
+{
+	struct kvm_ipc_head head = {.type = type, .len = len,};
+
+	if (write_in_full(fd, &head, sizeof(head)) < 0)
+		return -1;
+
+	if (write_in_full(fd, msg, len) < 0)
+		return -1;
+
+	return 0;
+}
+
+static int kvm_ipc__handle(int fd, u32 type, u32 len, u8 *data)
+{
+	void (*cb)(int fd, u32 type, u32 len, u8 *msg);
+
+	if (type >= KVM_IPC_MAX_MSGS)
+		return -ENOSPC;
+
+	down_read(&msgs_rwlock);
+	cb = msgs[type];
+	up_read(&msgs_rwlock);
+
+	if (cb == NULL) {
+		pr_warning("No device handles type %u\n", type);
+		return -ENODEV;
+	}
+
+	cb(fd, type, len, data);
+
+	return 0;
+}
+
+static int kvm_ipc__new_conn(int fd)
+{
+	int client;
+	struct epoll_event ev;
+
+	client = accept(fd, NULL, NULL);
+	if (client < 0)
+		return -1;
+
+	ev.events = EPOLLIN | EPOLLRDHUP;
+	ev.data.fd = client;
+	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev) < 0) {
+		close(client);
+		return -1;
+	}
+
+	return client;
+}
+
+static void kvm_ipc__close_conn(int fd)
+{
+	epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
+	close(fd);
+}
+
+static int kvm_ipc__receive(int fd)
+{
+	struct kvm_ipc_head head;
+	u8 *msg = NULL;
+	u32 n;
+
+	n = read(fd, &head, sizeof(head));
+	if (n != sizeof(head))
+		goto done;
+
+	msg = malloc(head.len);
+	if (msg == NULL)
+		goto done;
+
+	n = read_in_full(fd, msg, head.len);
+	if (n != head.len)
+		goto done;
+
+	kvm_ipc__handle(fd, head.type, head.len, msg);
+
+	return 0;
+
+done:
+	free(msg);
+	return -1;
+}
+
+static void *kvm_ipc__thread(void *param)
+{
+	struct epoll_event event;
+
+	for (;;) {
+		int nfds;
+
+		nfds = epoll_wait(epoll_fd, &event, 1, -1);
+		if (nfds > 0) {
+			int fd = event.data.fd;
+
+			if (fd == stop_fd && event.events & EPOLLIN) {
+				break;
+			} else if (fd == server_fd) {
+				int client, r;
+
+				client = kvm_ipc__new_conn(fd);
+				/*
+				 * Handle multiple IPC cmd at a time
+				 */
+				do {
+					r = kvm_ipc__receive(client);
+				} while	(r == 0);
+
+			} else if (event.events && (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) {
+				kvm_ipc__close_conn(fd);
+			} else {
+				kvm_ipc__receive(fd);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+int kvm_ipc__start(int sock)
+{
+	int ret;
+	struct epoll_event ev = {0};
+
+	server_fd = sock;
+
+	epoll_fd = epoll_create(KVM_IPC_MAX_MSGS);
+	if (epoll_fd < 0) {
+		ret = epoll_fd;
+		goto err;
+	}
+
+	ev.events = EPOLLIN | EPOLLET;
+	ev.data.fd = sock;
+	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock, &ev) < 0) {
+		pr_err("Failed starting IPC thread");
+		ret = -EFAULT;
+		goto err_epoll;
+	}
+
+	stop_fd = eventfd(0, 0);
+	if (stop_fd < 0) {
+		ret = stop_fd;
+		goto err_epoll;
+	}
+
+	ev.events = EPOLLIN | EPOLLET;
+	ev.data.fd = stop_fd;
+	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, stop_fd, &ev) < 0) {
+		pr_err("Failed adding stop event to epoll");
+		ret = -EFAULT;
+		goto err_stop;
+	}
+
+	if (pthread_create(&thread, NULL, kvm_ipc__thread, NULL) != 0) {
+		pr_err("Failed starting IPC thread");
+		ret = -EFAULT;
+		goto err_stop;
+	}
+
+	return 0;
+
+err_stop:
+	close(stop_fd);
+err_epoll:
+	close(epoll_fd);
+err:
+	return ret;
+}
+
+int kvm_ipc__stop(void)
+{
+	u64 val = 1;
+	int ret;
+
+	ret = write(stop_fd, &val, sizeof(val));
+	if (ret < 0)
+		return ret;
+
+	close(server_fd);
+	close(epoll_fd);
+
+	return ret;
+}
diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c
new file mode 100644
index 0000000..99bcef4
--- /dev/null
+++ b/tools/kvm/kvm.c
@@ -0,0 +1,587 @@
+#include "kvm/kvm.h"
+#include "kvm/read-write.h"
+#include "kvm/util.h"
+#include "kvm/mutex.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/kvm-ipc.h"
+
+#include <linux/kvm.h>
+#include <linux/err.h>
+
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/eventfd.h>
+#include <asm/unistd.h>
+#include <dirent.h>
+
+#define DEFINE_KVM_EXIT_REASON(reason) [reason] = #reason
+
+const char *kvm_exit_reasons[] = {
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_UNKNOWN),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_EXCEPTION),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_IO),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_HYPERCALL),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_DEBUG),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_HLT),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_MMIO),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_IRQ_WINDOW_OPEN),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_SHUTDOWN),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_FAIL_ENTRY),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_INTR),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_SET_TPR),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_TPR_ACCESS),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_S390_SIEIC),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_S390_RESET),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_DCR),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_NMI),
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_INTERNAL_ERROR),
+#ifdef CONFIG_PPC64
+	DEFINE_KVM_EXIT_REASON(KVM_EXIT_PAPR_HCALL),
+#endif
+};
+
+extern struct kvm *kvm;
+extern struct kvm_cpu **kvm_cpus;
+static int pause_event;
+static DEFINE_MUTEX(pause_lock);
+extern struct kvm_ext kvm_req_ext[];
+
+static char kvm_dir[PATH_MAX];
+
+static int set_dir(const char *fmt, va_list args)
+{
+	char tmp[PATH_MAX];
+
+	vsnprintf(tmp, sizeof(tmp), fmt, args);
+
+	mkdir(tmp, 0777);
+
+	if (!realpath(tmp, kvm_dir))
+		return -errno;
+
+	strcat(kvm_dir, "/");
+
+	return 0;
+}
+
+void kvm__set_dir(const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	set_dir(fmt, args);
+	va_end(args);
+}
+
+const char *kvm__get_dir(void)
+{
+	return kvm_dir;
+}
+
+bool kvm__supports_extension(struct kvm *kvm, unsigned int extension)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, extension);
+	if (ret < 0)
+		return false;
+
+	return ret;
+}
+
+static int kvm__check_extensions(struct kvm *kvm)
+{
+	int i;
+
+	for (i = 0; ; i++) {
+		if (!kvm_req_ext[i].name)
+			break;
+		if (!kvm__supports_extension(kvm, kvm_req_ext[i].code)) {
+			pr_err("Unsuppored KVM extension detected: %s",
+				kvm_req_ext[i].name);
+			return -i;
+		}
+	}
+
+	return 0;
+}
+
+static struct kvm *kvm__new(void)
+{
+	struct kvm *kvm = calloc(1, sizeof(*kvm));
+	if (!kvm)
+		return ERR_PTR(-ENOMEM);
+
+	kvm->sys_fd = -1;
+	kvm->vm_fd = -1;
+
+	return kvm;
+}
+
+#define KVM_SOCK_SUFFIX		".sock"
+#define KVM_SOCK_SUFFIX_LEN	((ssize_t)sizeof(KVM_SOCK_SUFFIX) - 1)
+
+static int kvm__create_socket(struct kvm *kvm)
+{
+	char full_name[PATH_MAX];
+	unsigned int s;
+	struct sockaddr_un local;
+	int len, r;
+
+	if (!kvm->name)
+		return -EINVAL;
+
+	sprintf(full_name, "%s/%s%s", kvm__get_dir(), kvm->name,
+			KVM_SOCK_SUFFIX);
+	if (access(full_name, F_OK) == 0) {
+		pr_err("Socket file %s already exist", full_name);
+		return -EEXIST;
+	}
+
+	s = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (s < 0)
+		return s;
+	local.sun_family = AF_UNIX;
+	strcpy(local.sun_path, full_name);
+	len = strlen(local.sun_path) + sizeof(local.sun_family);
+	r = bind(s, (struct sockaddr *)&local, len);
+	if (r < 0)
+		goto fail;
+
+	r = listen(s, 5);
+	if (r < 0)
+		goto fail;
+
+	return s;
+
+fail:
+	close(s);
+	return r;
+}
+
+void kvm__remove_socket(const char *name)
+{
+	char full_name[PATH_MAX];
+
+	sprintf(full_name, "%s/%s%s", kvm__get_dir(), name, KVM_SOCK_SUFFIX);
+	unlink(full_name);
+}
+
+int kvm__get_sock_by_instance(const char *name)
+{
+	int s, len, r;
+	char sock_file[PATH_MAX];
+	struct sockaddr_un local;
+
+	sprintf(sock_file, "%s/%s%s", kvm__get_dir(), name, KVM_SOCK_SUFFIX);
+	s = socket(AF_UNIX, SOCK_STREAM, 0);
+
+	local.sun_family = AF_UNIX;
+	strcpy(local.sun_path, sock_file);
+	len = strlen(local.sun_path) + sizeof(local.sun_family);
+
+	r = connect(s, &local, len);
+	if (r < 0 && errno == ECONNREFUSED) {
+		/* Tell the user clean ghost socket file */
+		pr_err("\"%s\" could be a ghost socket file, please remove it",
+				sock_file);
+		return r;
+	} else if (r < 0) {
+		return r;
+	}
+
+	return s;
+}
+
+int kvm__enumerate_instances(int (*callback)(const char *name, int fd))
+{
+	int sock;
+	DIR *dir;
+	struct dirent entry, *result;
+	int ret = 0;
+
+	dir = opendir(kvm__get_dir());
+	if (!dir)
+		return -errno;
+
+	for (;;) {
+		readdir_r(dir, &entry, &result);
+		if (result == NULL)
+			break;
+		if (entry.d_type == DT_SOCK) {
+			ssize_t name_len = strlen(entry.d_name);
+			char *p;
+
+			if (name_len <= KVM_SOCK_SUFFIX_LEN)
+				continue;
+
+			p = &entry.d_name[name_len - KVM_SOCK_SUFFIX_LEN];
+			if (memcmp(KVM_SOCK_SUFFIX, p, KVM_SOCK_SUFFIX_LEN))
+				continue;
+
+			*p = 0;
+			sock = kvm__get_sock_by_instance(entry.d_name);
+			if (sock < 0)
+				continue;
+			ret = callback(entry.d_name, sock);
+			close(sock);
+			if (ret < 0)
+				break;
+		}
+	}
+
+	closedir(dir);
+
+	return ret;
+}
+
+int kvm__exit(struct kvm *kvm)
+{
+	kvm__stop_timer(kvm);
+
+	kvm__arch_delete_ram(kvm);
+	kvm_ipc__stop();
+	kvm__remove_socket(kvm->name);
+	free(kvm->name);
+	free(kvm);
+
+	return 0;
+}
+
+/*
+ * Note: KVM_SET_USER_MEMORY_REGION assumes that we don't pass overlapping
+ * memory regions to it. Therefore, be careful if you use this function for
+ * registering memory regions for emulating hardware.
+ */
+int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr)
+{
+	struct kvm_userspace_memory_region mem;
+	int ret;
+
+	mem = (struct kvm_userspace_memory_region) {
+		.slot			= kvm->mem_slots++,
+		.guest_phys_addr	= guest_phys,
+		.memory_size		= size,
+		.userspace_addr		= (unsigned long)userspace_addr,
+	};
+
+	ret = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &mem);
+	if (ret < 0)
+		return -errno;
+
+	return 0;
+}
+
+int kvm__recommended_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_NR_VCPUS);
+	if (ret <= 0)
+		/*
+		 * api.txt states that if KVM_CAP_NR_VCPUS does not exist,
+		 * assume 4.
+		 */
+		return 4;
+
+	return ret;
+}
+
+static void kvm__pid(int fd, u32 type, u32 len, u8 *msg)
+{
+	pid_t pid = getpid();
+	int r = 0;
+
+	if (type == KVM_IPC_PID)
+		r = write(fd, &pid, sizeof(pid));
+
+	if (r < 0)
+		pr_warning("Failed sending PID");
+}
+
+/*
+ * The following hack should be removed once 'x86: Raise the hard
+ * VCPU count limit' makes it's way into the mainline.
+ */
+#ifndef KVM_CAP_MAX_VCPUS
+#define KVM_CAP_MAX_VCPUS 66
+#endif
+
+int kvm__max_cpus(struct kvm *kvm)
+{
+	int ret;
+
+	ret = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_MAX_VCPUS);
+	if (ret <= 0)
+		ret = kvm__recommended_cpus(kvm);
+
+	return ret;
+}
+
+struct kvm *kvm__init(const char *kvm_dev, const char *hugetlbfs_path, u64 ram_size, const char *name)
+{
+	struct kvm *kvm;
+	int ret;
+
+	if (!kvm__arch_cpu_supports_vm()) {
+		pr_err("Your CPU does not support hardware virtualization");
+		ret = -ENOSYS;
+		goto err;
+	}
+
+	kvm = kvm__new();
+	if (IS_ERR(kvm))
+		return kvm;
+
+	kvm->sys_fd = open(kvm_dev, O_RDWR);
+	if (kvm->sys_fd < 0) {
+		if (errno == ENOENT)
+			pr_err("'%s' not found. Please make sure your kernel has CONFIG_KVM "
+			       "enabled and that the KVM modules are loaded.", kvm_dev);
+		else if (errno == ENODEV)
+			pr_err("'%s' KVM driver not available.\n  # (If the KVM "
+			       "module is loaded then 'dmesg' may offer further clues "
+			       "about the failure.)", kvm_dev);
+		else
+			pr_err("Could not open %s: ", kvm_dev);
+
+		ret = -errno;
+		goto err_free;
+	}
+
+	ret = ioctl(kvm->sys_fd, KVM_GET_API_VERSION, 0);
+	if (ret != KVM_API_VERSION) {
+		pr_err("KVM_API_VERSION ioctl");
+		ret = -errno;
+		goto err_sys_fd;
+	}
+
+	kvm->vm_fd = ioctl(kvm->sys_fd, KVM_CREATE_VM, 0);
+	if (kvm->vm_fd < 0) {
+		ret = kvm->vm_fd;
+		goto err_sys_fd;
+	}
+
+	kvm->name = strdup(name);
+	if (!kvm->name) {
+		ret = -ENOMEM;
+		goto err_vm_fd;
+	}
+
+	if (kvm__check_extensions(kvm)) {
+		pr_err("A required KVM extention is not supported by OS");
+		ret = -ENOSYS;
+		goto err_vm_fd;
+	}
+
+	kvm__arch_init(kvm, hugetlbfs_path, ram_size);
+
+	ret = kvm_ipc__start(kvm__create_socket(kvm));
+	if (ret < 0) {
+		pr_err("Starting ipc failed.");
+		goto err_vm_fd;
+	}
+
+	ret = kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid);
+	if (ret < 0) {
+		pr_err("Register ipc handler failed.");
+		goto err_ipc;
+	}
+
+	return kvm;
+
+err_ipc:
+	kvm_ipc__stop();
+err_vm_fd:
+	close(kvm->vm_fd);
+err_sys_fd:
+	close(kvm->sys_fd);
+err_free:
+	free(kvm);
+err:
+	return ERR_PTR(ret);
+}
+
+/* RFC 1952 */
+#define GZIP_ID1		0x1f
+#define GZIP_ID2		0x8b
+#define CPIO_MAGIC		"0707"
+/* initrd may be gzipped, or a plain cpio */
+static bool initrd_check(int fd)
+{
+	unsigned char id[4];
+
+	if (read_in_full(fd, id, ARRAY_SIZE(id)) < 0)
+		return false;
+
+	if (lseek(fd, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	return (id[0] == GZIP_ID1 && id[1] == GZIP_ID2) ||
+		!memcmp(id, CPIO_MAGIC, 4);
+}
+
+bool kvm__load_kernel(struct kvm *kvm, const char *kernel_filename,
+		const char *initrd_filename, const char *kernel_cmdline, u16 vidmode)
+{
+	bool ret;
+	int fd_kernel = -1, fd_initrd = -1;
+
+	fd_kernel = open(kernel_filename, O_RDONLY);
+	if (fd_kernel < 0)
+		die("Unable to open kernel %s", kernel_filename);
+
+	if (initrd_filename) {
+		fd_initrd = open(initrd_filename, O_RDONLY);
+		if (fd_initrd < 0)
+			die("Unable to open initrd %s", initrd_filename);
+
+		if (!initrd_check(fd_initrd))
+			die("%s is not an initrd", initrd_filename);
+	}
+
+	ret = load_bzimage(kvm, fd_kernel, fd_initrd, kernel_cmdline, vidmode);
+
+	if (ret)
+		goto found_kernel;
+
+	pr_warning("%s is not a bzImage. Trying to load it as a flat binary...", kernel_filename);
+
+	ret = load_flat_binary(kvm, fd_kernel, fd_initrd, kernel_cmdline);
+
+	if (ret)
+		goto found_kernel;
+
+	if (initrd_filename)
+		close(fd_initrd);
+	close(fd_kernel);
+
+	die("%s is not a valid bzImage or flat binary", kernel_filename);
+
+found_kernel:
+	if (initrd_filename)
+		close(fd_initrd);
+	close(fd_kernel);
+
+	return ret;
+}
+
+#define TIMER_INTERVAL_NS 1000000	/* 1 msec */
+
+/*
+ * This function sets up a timer that's used to inject interrupts from the
+ * userspace hypervisor into the guest at periodical intervals. Please note
+ * that clock interrupt, for example, is not handled here.
+ */
+void kvm__start_timer(struct kvm *kvm)
+{
+	struct itimerspec its;
+	struct sigevent sev;
+
+	memset(&sev, 0, sizeof(struct sigevent));
+	sev.sigev_value.sival_int	= 0;
+	sev.sigev_notify		= SIGEV_THREAD_ID;
+	sev.sigev_signo			= SIGALRM;
+	sev._sigev_un._tid		= syscall(__NR_gettid);
+
+	if (timer_create(CLOCK_REALTIME, &sev, &kvm->timerid) < 0)
+		die("timer_create()");
+
+	its.it_value.tv_sec		= TIMER_INTERVAL_NS / 1000000000;
+	its.it_value.tv_nsec		= TIMER_INTERVAL_NS % 1000000000;
+	its.it_interval.tv_sec		= its.it_value.tv_sec;
+	its.it_interval.tv_nsec		= its.it_value.tv_nsec;
+
+	if (timer_settime(kvm->timerid, 0, &its, NULL) < 0)
+		die("timer_settime()");
+}
+
+void kvm__stop_timer(struct kvm *kvm)
+{
+	if (kvm->timerid)
+		if (timer_delete(kvm->timerid) < 0)
+			die("timer_delete()");
+
+	kvm->timerid = 0;
+}
+
+void kvm__dump_mem(struct kvm *kvm, unsigned long addr, unsigned long size)
+{
+	unsigned char *p;
+	unsigned long n;
+
+	size &= ~7; /* mod 8 */
+	if (!size)
+		return;
+
+	p = guest_flat_to_host(kvm, addr);
+
+	for (n = 0; n < size; n += 8) {
+		if (!host_ptr_in_ram(kvm, p + n))
+			break;
+
+		printf("  0x%08lx: %02x %02x %02x %02x  %02x %02x %02x %02x\n",
+			addr + n, p[n + 0], p[n + 1], p[n + 2], p[n + 3],
+				  p[n + 4], p[n + 5], p[n + 6], p[n + 7]);
+	}
+}
+
+void kvm__pause(void)
+{
+	int i, paused_vcpus = 0;
+
+	/* Check if the guest is running */
+	if (!kvm_cpus[0] || kvm_cpus[0]->thread == 0)
+		return;
+
+	mutex_lock(&pause_lock);
+
+	pause_event = eventfd(0, 0);
+	if (pause_event < 0)
+		die("Failed creating pause notification event");
+	for (i = 0; i < kvm->nrcpus; i++)
+		pthread_kill(kvm_cpus[i]->thread, SIGKVMPAUSE);
+
+	while (paused_vcpus < kvm->nrcpus) {
+		u64 cur_read;
+
+		if (read(pause_event, &cur_read, sizeof(cur_read)) < 0)
+			die("Failed reading pause event");
+		paused_vcpus += cur_read;
+	}
+	close(pause_event);
+}
+
+void kvm__continue(void)
+{
+	/* Check if the guest is running */
+	if (!kvm_cpus[0] || kvm_cpus[0]->thread == 0)
+		return;
+
+	mutex_unlock(&pause_lock);
+}
+
+void kvm__notify_paused(void)
+{
+	u64 p = 1;
+
+	if (write(pause_event, &p, sizeof(p)) < 0)
+		die("Failed notifying of paused VCPU.");
+
+	mutex_lock(&pause_lock);
+	mutex_unlock(&pause_lock);
+}
diff --git a/tools/kvm/main.c b/tools/kvm/main.c
new file mode 100644
index 0000000..05bc82c
--- /dev/null
+++ b/tools/kvm/main.c
@@ -0,0 +1,19 @@
+#include "kvm/kvm.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* user defined header files */
+#include <kvm/kvm-cmd.h>
+
+static int handle_kvm_command(int argc, char **argv)
+{
+	return handle_command(kvm_commands, argc, (const char **) &argv[0]);
+}
+
+int main(int argc, char *argv[])
+{
+	kvm__set_dir("%s/%s", HOME_DIR, KVM_PID_FILE_PATH);
+
+	return handle_kvm_command(argc - 1, &argv[1]);
+}
diff --git a/tools/kvm/mmio.c b/tools/kvm/mmio.c
new file mode 100644
index 0000000..7760a7f
--- /dev/null
+++ b/tools/kvm/mmio.c
@@ -0,0 +1,137 @@
+#include "kvm/kvm.h"
+#include "kvm/rbtree-interval.h"
+#include "kvm/brlock.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+#include <linux/kvm.h>
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include <linux/err.h>
+#include <errno.h>
+
+#define mmio_node(n) rb_entry(n, struct mmio_mapping, node)
+
+struct mmio_mapping {
+	struct rb_int_node	node;
+	void			(*mmio_fn)(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr);
+	void			*ptr;
+};
+
+static struct rb_root mmio_tree = RB_ROOT;
+
+static struct mmio_mapping *mmio_search(struct rb_root *root, u64 addr, u64 len)
+{
+	struct rb_int_node *node;
+
+	node = rb_int_search_range(root, addr, addr + len);
+	if (node == NULL)
+		return NULL;
+
+	return mmio_node(node);
+}
+
+/* Find lowest match, Check for overlap */
+static struct mmio_mapping *mmio_search_single(struct rb_root *root, u64 addr)
+{
+	struct rb_int_node *node;
+
+	node = rb_int_search_single(root, addr);
+	if (node == NULL)
+		return NULL;
+
+	return mmio_node(node);
+}
+
+static int mmio_insert(struct rb_root *root, struct mmio_mapping *data)
+{
+	return rb_int_insert(root, &data->node);
+}
+
+static const char *to_direction(u8 is_write)
+{
+	if (is_write)
+		return "write";
+
+	return "read";
+}
+
+int kvm__register_mmio(struct kvm *kvm, u64 phys_addr, u64 phys_addr_len, bool coalesce,
+			void (*mmio_fn)(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr),
+			void *ptr)
+{
+	struct mmio_mapping *mmio;
+	struct kvm_coalesced_mmio_zone zone;
+	int ret;
+
+	mmio = malloc(sizeof(*mmio));
+	if (mmio == NULL)
+		return -ENOMEM;
+
+	*mmio = (struct mmio_mapping) {
+		.node = RB_INT_INIT(phys_addr, phys_addr + phys_addr_len),
+		.mmio_fn = mmio_fn,
+		.ptr	= ptr,
+	};
+
+	if (coalesce) {
+		zone = (struct kvm_coalesced_mmio_zone) {
+			.addr	= phys_addr,
+			.size	= phys_addr_len,
+		};
+		ret = ioctl(kvm->vm_fd, KVM_REGISTER_COALESCED_MMIO, &zone);
+		if (ret < 0) {
+			free(mmio);
+			return -errno;
+		}
+	}
+	br_write_lock();
+	ret = mmio_insert(&mmio_tree, mmio);
+	br_write_unlock();
+
+	return ret;
+}
+
+bool kvm__deregister_mmio(struct kvm *kvm, u64 phys_addr)
+{
+	struct mmio_mapping *mmio;
+	struct kvm_coalesced_mmio_zone zone;
+
+	br_write_lock();
+	mmio = mmio_search_single(&mmio_tree, phys_addr);
+	if (mmio == NULL) {
+		br_write_unlock();
+		return false;
+	}
+
+	zone = (struct kvm_coalesced_mmio_zone) {
+		.addr	= phys_addr,
+		.size	= 1,
+	};
+	ioctl(kvm->vm_fd, KVM_UNREGISTER_COALESCED_MMIO, &zone);
+
+	rb_int_erase(&mmio_tree, &mmio->node);
+	br_write_unlock();
+
+	free(mmio);
+	return true;
+}
+
+bool kvm__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+{
+	struct mmio_mapping *mmio;
+
+	br_read_lock();
+	mmio = mmio_search(&mmio_tree, phys_addr, len);
+
+	if (mmio)
+		mmio->mmio_fn(phys_addr, data, len, is_write, mmio->ptr);
+	else
+		fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n",
+			to_direction(is_write), phys_addr, len);
+	br_read_unlock();
+
+	return true;
+}
diff --git a/tools/kvm/net/uip/arp.c b/tools/kvm/net/uip/arp.c
new file mode 100644
index 0000000..98423da
--- /dev/null
+++ b/tools/kvm/net/uip/arp.c
@@ -0,0 +1,30 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_arp(struct uip_tx_arg *arg)
+{
+	struct uip_arp *arp, *arp2;
+	struct uip_info *info;
+	struct uip_buf *buf;
+
+	info = arg->info;
+	buf = uip_buf_clone(arg);
+
+	arp	 = (struct uip_arp *)(arg->eth);
+	arp2	 = (struct uip_arp *)(buf->eth);
+
+	/*
+	 * ARP replay code: 2
+	 */
+	arp2->op   = htons(0x2);
+	arp2->dmac = arp->smac;
+	arp2->dip  = arp->sip;
+
+	if (arp->dip == htonl(info->host_ip)) {
+		arp2->smac = info->host_mac;
+		arp2->sip = htonl(info->host_ip);
+
+		uip_buf_set_used(info, buf);
+	}
+
+	return 0;
+}
diff --git a/tools/kvm/net/uip/buf.c b/tools/kvm/net/uip/buf.c
new file mode 100644
index 0000000..5e564a9
--- /dev/null
+++ b/tools/kvm/net/uip/buf.c
@@ -0,0 +1,114 @@
+#include "kvm/uip.h"
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+struct uip_buf *uip_buf_get_used(struct uip_info *info)
+{
+	struct uip_buf *buf;
+	bool found = false;
+
+	mutex_lock(&info->buf_lock);
+
+	while (!(info->buf_used_nr > 0))
+		pthread_cond_wait(&info->buf_used_cond, &info->buf_lock);
+
+	list_for_each_entry(buf, &info->buf_head, list) {
+		if (buf->status == UIP_BUF_STATUS_USED) {
+			/*
+			 * Set status to INUSE immediately to prevent
+			 * someone from using this buf until we free it
+			 */
+			buf->status = UIP_BUF_STATUS_INUSE;
+			info->buf_used_nr--;
+			found = true;
+			break;
+		}
+	}
+
+	mutex_unlock(&info->buf_lock);
+
+	return found ? buf : NULL;
+}
+
+struct uip_buf *uip_buf_get_free(struct uip_info *info)
+{
+	struct uip_buf *buf;
+	bool found = false;
+
+	mutex_lock(&info->buf_lock);
+
+	while (!(info->buf_free_nr > 0))
+		pthread_cond_wait(&info->buf_free_cond, &info->buf_lock);
+
+	list_for_each_entry(buf, &info->buf_head, list) {
+		if (buf->status == UIP_BUF_STATUS_FREE) {
+			/*
+			 * Set status to INUSE immediately to prevent
+			 * someone from using this buf until we free it
+			 */
+			buf->status = UIP_BUF_STATUS_INUSE;
+			info->buf_free_nr--;
+			found = true;
+			break;
+		}
+	}
+
+	mutex_unlock(&info->buf_lock);
+
+	return found ? buf : NULL;
+}
+
+struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf)
+{
+	mutex_lock(&info->buf_lock);
+
+	buf->status = UIP_BUF_STATUS_USED;
+	info->buf_used_nr++;
+	pthread_cond_signal(&info->buf_used_cond);
+
+	mutex_unlock(&info->buf_lock);
+
+	return buf;
+}
+
+struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf)
+{
+	mutex_lock(&info->buf_lock);
+
+	buf->status = UIP_BUF_STATUS_FREE;
+	info->buf_free_nr++;
+	pthread_cond_signal(&info->buf_free_cond);
+
+	mutex_unlock(&info->buf_lock);
+
+	return buf;
+}
+
+struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg)
+{
+	struct uip_buf *buf;
+	struct uip_eth *eth2;
+	struct uip_info *info;
+
+	info = arg->info;
+
+	/*
+	 * Get buffer from device to guest
+	 */
+	buf = uip_buf_get_free(info);
+
+	/*
+	 * Clone buffer
+	 */
+	memcpy(buf->vnet, arg->vnet, arg->vnet_len);
+	memcpy(buf->eth, arg->eth, arg->eth_len);
+	buf->vnet_len	= arg->vnet_len;
+	buf->eth_len	= arg->eth_len;
+
+	eth2		= (struct uip_eth *)buf->eth;
+	eth2->src	= info->host_mac;
+	eth2->dst	= arg->eth->src;
+
+	return buf;
+}
diff --git a/tools/kvm/net/uip/core.c b/tools/kvm/net/uip/core.c
new file mode 100644
index 0000000..2e7603c
--- /dev/null
+++ b/tools/kvm/net/uip/core.c
@@ -0,0 +1,190 @@
+#include "kvm/mutex.h"
+#include "kvm/uip.h"
+
+#include <linux/virtio_net.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+int uip_tx(struct iovec *iov, u16 out, struct uip_info *info)
+{
+	struct virtio_net_hdr *vnet;
+	struct uip_tx_arg arg;
+	int eth_len, vnet_len;
+	struct uip_eth *eth;
+	u8 *buf = NULL;
+	u16 proto;
+	int i;
+
+	/*
+	 * Buffer from guest to device
+	 */
+	vnet_len = iov[0].iov_len;
+	vnet	 = iov[0].iov_base;
+
+	eth_len	 = iov[1].iov_len;
+	eth	 = iov[1].iov_base;
+
+	/*
+	 * In case, ethernet frame is in more than one iov entry.
+	 * Copy iov buffer into one linear buffer.
+	 */
+	if (out > 2) {
+		eth_len = 0;
+		for (i = 1; i < out; i++)
+			eth_len += iov[i].iov_len;
+
+		buf = malloc(eth_len);
+		if (!buf)
+			return -1;
+
+		eth = (struct uip_eth *)buf;
+		for (i = 1; i < out; i++) {
+			memcpy(buf, iov[i].iov_base, iov[i].iov_len);
+			buf += iov[i].iov_len;
+		}
+	}
+
+	memset(&arg, 0, sizeof(arg));
+
+	arg.vnet_len = vnet_len;
+	arg.eth_len = eth_len;
+	arg.info = info;
+	arg.vnet = vnet;
+	arg.eth = eth;
+
+	/*
+	 * Check package type
+	 */
+	proto = ntohs(eth->type);
+
+	switch (proto) {
+	case UIP_ETH_P_ARP:
+		uip_tx_do_arp(&arg);
+		break;
+	case UIP_ETH_P_IP:
+		uip_tx_do_ipv4(&arg);
+		break;
+	default:
+		break;
+	}
+
+	if (out > 2 && buf)
+		free(eth);
+
+	return vnet_len + eth_len;
+}
+
+int uip_rx(struct iovec *iov, u16 in, struct uip_info *info)
+{
+	struct virtio_net_hdr *vnet;
+	struct uip_eth *eth;
+	struct uip_buf *buf;
+	int vnet_len;
+	int eth_len;
+	char *p;
+	int len;
+	int cnt;
+	int i;
+
+	/*
+	 * Sleep until there is a buffer for guest
+	 */
+	buf = uip_buf_get_used(info);
+
+	/*
+	 * Fill device to guest buffer, vnet hdr fisrt
+	 */
+	vnet_len = iov[0].iov_len;
+	vnet = iov[0].iov_base;
+	if (buf->vnet_len > vnet_len) {
+		len = -1;
+		goto out;
+	}
+	memcpy(vnet, buf->vnet, buf->vnet_len);
+
+	/*
+	 * Then, the real eth data
+	 * Note: Be sure buf->eth_len is not bigger than the buffer len that guest provides
+	 */
+	cnt = buf->eth_len;
+	p = buf->eth;
+	for (i = 1; i < in; i++) {
+		eth_len = iov[i].iov_len;
+		eth = iov[i].iov_base;
+		if (cnt > eth_len) {
+			memcpy(eth, p, eth_len);
+			cnt -= eth_len;
+			p += eth_len;
+		} else {
+			memcpy(eth, p, cnt);
+			cnt -= cnt;
+			break;
+		}
+	}
+
+	if (cnt) {
+		pr_warning("uip_rx error");
+		len = -1;
+		goto out;
+	}
+
+	len = buf->vnet_len + buf->eth_len;
+
+out:
+	uip_buf_set_free(info, buf);
+	return len;
+}
+
+int uip_init(struct uip_info *info)
+{
+	struct list_head *udp_socket_head;
+	struct list_head *tcp_socket_head;
+	struct list_head *buf_head;
+	struct uip_buf *buf;
+	int buf_nr;
+	int i;
+
+	udp_socket_head	= &info->udp_socket_head;
+	tcp_socket_head	= &info->tcp_socket_head;
+	buf_head	= &info->buf_head;
+	buf_nr		= info->buf_nr;
+
+	INIT_LIST_HEAD(udp_socket_head);
+	INIT_LIST_HEAD(tcp_socket_head);
+	INIT_LIST_HEAD(buf_head);
+
+	pthread_mutex_init(&info->udp_socket_lock, NULL);
+	pthread_mutex_init(&info->tcp_socket_lock, NULL);
+	pthread_mutex_init(&info->buf_lock, NULL);
+
+	pthread_cond_init(&info->buf_used_cond, NULL);
+	pthread_cond_init(&info->buf_free_cond, NULL);
+
+
+	for (i = 0; i < buf_nr; i++) {
+		buf = malloc(sizeof(*buf));
+		memset(buf, 0, sizeof(*buf));
+
+		buf->status	= UIP_BUF_STATUS_FREE;
+		buf->info	= info;
+		buf->id		= i;
+		list_add_tail(&buf->list, buf_head);
+	}
+
+	list_for_each_entry(buf, buf_head, list) {
+		buf->vnet	= malloc(sizeof(struct virtio_net_hdr));
+		buf->vnet_len	= sizeof(struct virtio_net_hdr);
+		buf->eth	= malloc(1024*64 + sizeof(struct uip_pseudo_hdr));
+		buf->eth_len	= 1024*64 + sizeof(struct uip_pseudo_hdr);
+
+		memset(buf->vnet, 0, buf->vnet_len);
+		memset(buf->eth, 0, buf->eth_len);
+	}
+
+	info->buf_free_nr = buf_nr;
+	info->buf_used_nr = 0;
+
+	uip_dhcp_get_dns(info);
+
+	return 0;
+}
diff --git a/tools/kvm/net/uip/csum.c b/tools/kvm/net/uip/csum.c
new file mode 100644
index 0000000..7ca8bad
--- /dev/null
+++ b/tools/kvm/net/uip/csum.c
@@ -0,0 +1,92 @@
+#include "kvm/uip.h"
+
+static u16 uip_csum(u16 csum, u8 *addr, u16 count)
+{
+	long sum = csum;
+
+	while (count > 1) {
+		sum	+= *(u16 *)addr;
+		addr	+= 2;
+		count	-= 2;
+	}
+
+	if (count > 0)
+		sum += *(unsigned char *)addr;
+
+	while (sum>>16)
+		sum = (sum & 0xffff) + (sum >> 16);
+
+	return ~sum;
+}
+
+u16 uip_csum_ip(struct uip_ip *ip)
+{
+	return uip_csum(0, &ip->vhl, uip_ip_hdrlen(ip));
+}
+
+u16 uip_csum_icmp(struct uip_icmp *icmp)
+{
+	struct uip_ip *ip;
+
+	ip = &icmp->ip;
+	return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */
+}
+
+u16 uip_csum_udp(struct uip_udp *udp)
+{
+	struct uip_pseudo_hdr hdr;
+	struct uip_ip *ip;
+	int udp_len;
+	u8 *pad;
+
+	ip	  = &udp->ip;
+
+	hdr.sip   = ip->sip;
+	hdr.dip	  = ip->dip;
+	hdr.zero  = 0;
+	hdr.proto = ip->proto;
+	hdr.len   = udp->len;
+
+	udp_len	  = uip_udp_len(udp);
+
+	if (udp_len % 2) {
+		pad = (u8 *)&udp->sport + udp_len;
+		*pad = 0;
+		memcpy((u8 *)&udp->sport + udp_len + 1, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&udp->sport, udp_len + 1 + sizeof(hdr));
+	} else {
+		memcpy((u8 *)&udp->sport + udp_len, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&udp->sport, udp_len + sizeof(hdr));
+	}
+
+}
+
+u16 uip_csum_tcp(struct uip_tcp *tcp)
+{
+	struct uip_pseudo_hdr hdr;
+	struct uip_ip *ip;
+	u16 tcp_len;
+	u8 *pad;
+
+	ip	  = &tcp->ip;
+	tcp_len   = ntohs(ip->len) - uip_ip_hdrlen(ip);
+
+	hdr.sip   = ip->sip;
+	hdr.dip	  = ip->dip;
+	hdr.zero  = 0;
+	hdr.proto = ip->proto;
+	hdr.len   = htons(tcp_len);
+
+	if (tcp_len > UIP_MAX_TCP_PAYLOAD + 20)
+		pr_warning("tcp_len(%d) is too large", tcp_len);
+
+	if (tcp_len % 2) {
+		pad = (u8 *)&tcp->sport + tcp_len;
+		*pad = 0;
+		memcpy((u8 *)&tcp->sport + tcp_len + 1, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&tcp->sport, tcp_len + 1 + sizeof(hdr));
+	} else {
+		memcpy((u8 *)&tcp->sport + tcp_len, &hdr, sizeof(hdr));
+		return uip_csum(0, (u8 *)&tcp->sport, tcp_len + sizeof(hdr));
+	}
+}
diff --git a/tools/kvm/net/uip/dhcp.c b/tools/kvm/net/uip/dhcp.c
new file mode 100644
index 0000000..e91a7c7
--- /dev/null
+++ b/tools/kvm/net/uip/dhcp.c
@@ -0,0 +1,203 @@
+#include "kvm/uip.h"
+
+#include <arpa/inet.h>
+
+#define EMPTY_ADDR "0.0.0.0"
+
+static inline bool uip_dhcp_is_discovery(struct uip_dhcp *dhcp)
+{
+	return (dhcp->option[2] == UIP_DHCP_DISCOVER &&
+		dhcp->option[1] == UIP_DHCP_TAG_MSG_TYPE_LEN &&
+		dhcp->option[0] == UIP_DHCP_TAG_MSG_TYPE);
+}
+
+static inline bool uip_dhcp_is_request(struct uip_dhcp *dhcp)
+{
+	return (dhcp->option[2] == UIP_DHCP_REQUEST &&
+		dhcp->option[1] == UIP_DHCP_TAG_MSG_TYPE_LEN &&
+		dhcp->option[0] == UIP_DHCP_TAG_MSG_TYPE);
+}
+
+bool uip_udp_is_dhcp(struct uip_udp *udp)
+{
+	struct uip_dhcp *dhcp;
+
+	if (ntohs(udp->sport) != UIP_DHCP_PORT_CLIENT ||
+	    ntohs(udp->dport) != UIP_DHCP_PORT_SERVER)
+		return false;
+
+	dhcp = (struct uip_dhcp *)udp;
+
+	if (ntohl(dhcp->magic_cookie) != UIP_DHCP_MAGIC_COOKIE)
+		return false;
+
+	return true;
+}
+
+int uip_dhcp_get_dns(struct uip_info *info)
+{
+	char key[256], val[256];
+	struct in_addr addr;
+	int ret = -1;
+	int n = 0;
+	FILE *fp;
+	u32 ip;
+
+	fp = fopen("/etc/resolv.conf", "r");
+	if (!fp)
+		goto out;
+
+	while (!feof(fp)) {
+		if (fscanf(fp, "%s %s\n", key, val) != 2)
+			continue;
+		if (strncmp("domain", key, 6) == 0)
+			info->domain_name = strndup(val, UIP_DHCP_MAX_DOMAIN_NAME_LEN);
+		else if (strncmp("nameserver", key, 10) == 0) {
+			if (!inet_aton(val, &addr))
+				continue;
+			ip = ntohl(addr.s_addr);
+			if (n < UIP_DHCP_MAX_DNS_SERVER_NR)
+				info->dns_ip[n++] = ip;
+			ret = 0;
+		}
+	}
+
+out:
+	fclose(fp);
+	return ret;
+}
+
+static int uip_dhcp_fill_option_name_and_server(struct uip_info *info, u8 *opt, int i)
+{
+	u8 domain_name_len;
+	u32 *addr;
+	int n;
+
+	if (info->domain_name) {
+		domain_name_len	= strlen(info->domain_name);
+		opt[i++]	= UIP_DHCP_TAG_DOMAIN_NAME;
+		opt[i++]	= domain_name_len;
+		memcpy(&opt[i], info->domain_name, domain_name_len);
+		i		+= domain_name_len;
+	}
+
+	for (n = 0; n < UIP_DHCP_MAX_DNS_SERVER_NR; n++) {
+		if (info->dns_ip[n] == 0)
+			continue;
+		opt[i++]	= UIP_DHCP_TAG_DNS_SERVER;
+		opt[i++]	= UIP_DHCP_TAG_DNS_SERVER_LEN;
+		addr		= (u32 *)&opt[i];
+		*addr		= htonl(info->dns_ip[n]);
+		i		+= UIP_DHCP_TAG_DNS_SERVER_LEN;
+	}
+
+	return i;
+}
+static int uip_dhcp_fill_option(struct uip_info *info, struct uip_dhcp *dhcp, int reply_msg_type)
+{
+	int i = 0;
+	u32 *addr;
+	u8 *opt;
+
+	opt		= dhcp->option;
+
+	opt[i++]	= UIP_DHCP_TAG_MSG_TYPE;
+	opt[i++]	= UIP_DHCP_TAG_MSG_TYPE_LEN;
+	opt[i++]	= reply_msg_type;
+
+	opt[i++]	= UIP_DHCP_TAG_SERVER_ID;
+	opt[i++]	= UIP_DHCP_TAG_SERVER_ID_LEN;
+	addr		= (u32 *)&opt[i];
+	*addr		= htonl(info->host_ip);
+	i		+= UIP_DHCP_TAG_SERVER_ID_LEN;
+
+	opt[i++]	= UIP_DHCP_TAG_LEASE_TIME;
+	opt[i++]	= UIP_DHCP_TAG_LEASE_TIME_LEN;
+	addr		= (u32 *)&opt[i];
+	*addr		= htonl(UIP_DHCP_LEASE_TIME);
+	i		+= UIP_DHCP_TAG_LEASE_TIME_LEN;
+
+	opt[i++]	= UIP_DHCP_TAG_SUBMASK;
+	opt[i++]	= UIP_DHCP_TAG_SUBMASK_LEN;
+	addr		= (u32 *)&opt[i];
+	*addr		= htonl(info->guest_netmask);
+	i		+= UIP_DHCP_TAG_SUBMASK_LEN;
+
+	opt[i++]	= UIP_DHCP_TAG_ROUTER;
+	opt[i++]	= UIP_DHCP_TAG_ROUTER_LEN;
+	addr		= (u32 *)&opt[i];
+	*addr		= htonl(info->host_ip);
+	i		+= UIP_DHCP_TAG_ROUTER_LEN;
+
+	opt[i++]	= UIP_DHCP_TAG_ROOT;
+	opt[i++]	= strlen(EMPTY_ADDR);
+	addr		= (u32 *)&opt[i];
+	strncpy((void *) addr, EMPTY_ADDR, strlen(EMPTY_ADDR));
+	i		+= strlen(EMPTY_ADDR);
+
+	i 		= uip_dhcp_fill_option_name_and_server(info, opt, i);
+
+	opt[i++]	= UIP_DHCP_TAG_END;
+
+	return 0;
+}
+
+static int uip_dhcp_make_pkg(struct uip_info *info, struct uip_udp_socket *sk, struct uip_buf *buf, u8 reply_msg_type)
+{
+	struct uip_dhcp *dhcp;
+
+	dhcp		= (struct uip_dhcp *)buf->eth;
+
+	dhcp->msg_type	= 2;
+	dhcp->client_ip	= 0;
+	dhcp->your_ip	= htonl(info->guest_ip);
+	dhcp->server_ip	= htonl(info->host_ip);
+	dhcp->agent_ip	= 0;
+
+	uip_dhcp_fill_option(info, dhcp, reply_msg_type);
+
+	sk->sip		= htonl(info->guest_ip);
+	sk->dip		= htonl(info->host_ip);
+	sk->sport	= htons(UIP_DHCP_PORT_CLIENT);
+	sk->dport	= htons(UIP_DHCP_PORT_SERVER);
+
+	return 0;
+}
+
+int uip_tx_do_ipv4_udp_dhcp(struct uip_tx_arg *arg)
+{
+	struct uip_udp_socket sk;
+	struct uip_dhcp *dhcp;
+	struct uip_info *info;
+	struct uip_buf *buf;
+	u8 reply_msg_type;
+
+	dhcp = (struct uip_dhcp *)arg->eth;
+
+	if (uip_dhcp_is_discovery(dhcp))
+		reply_msg_type = UIP_DHCP_OFFER;
+	else if (uip_dhcp_is_request(dhcp))
+		reply_msg_type = UIP_DHCP_ACK;
+	else
+		return -1;
+
+	buf = uip_buf_clone(arg);
+	info = arg->info;
+
+	/*
+	 * Cook DHCP pkg
+	 */
+	uip_dhcp_make_pkg(info, &sk, buf, reply_msg_type);
+
+	/*
+	 * Cook UDP pkg
+	 */
+	uip_udp_make_pkg(info, &sk, buf, NULL, UIP_DHCP_MAX_PAYLOAD_LEN);
+
+	/*
+	 * Send data received from socket to guest
+	 */
+	uip_buf_set_used(info, buf);
+
+	return 0;
+}
diff --git a/tools/kvm/net/uip/icmp.c b/tools/kvm/net/uip/icmp.c
new file mode 100644
index 0000000..233297c
--- /dev/null
+++ b/tools/kvm/net/uip/icmp.c
@@ -0,0 +1,29 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg)
+{
+	struct uip_ip *ip, *ip2;
+	struct uip_icmp *icmp2;
+	struct uip_buf *buf;
+
+	buf		= uip_buf_clone(arg);
+
+	icmp2		= (struct uip_icmp *)(buf->eth);
+	ip2		= (struct uip_ip *)(buf->eth);
+	ip		= (struct uip_ip *)(arg->eth);
+
+	ip2->sip	= ip->dip;
+	ip2->dip	= ip->sip;
+	ip2->csum	= 0;
+	/*
+	 * ICMP reply: 0
+	 */
+	icmp2->type	= 0;
+	icmp2->csum	= 0;
+	ip2->csum	= uip_csum_ip(ip2);
+	icmp2->csum	= uip_csum_icmp(icmp2);
+
+	uip_buf_set_used(arg->info, buf);
+
+	return 0;
+}
diff --git a/tools/kvm/net/uip/ipv4.c b/tools/kvm/net/uip/ipv4.c
new file mode 100644
index 0000000..58373fd
--- /dev/null
+++ b/tools/kvm/net/uip/ipv4.c
@@ -0,0 +1,29 @@
+#include "kvm/uip.h"
+
+int uip_tx_do_ipv4(struct uip_tx_arg *arg)
+{
+	struct uip_ip *ip;
+
+	ip = (struct uip_ip *)(arg->eth);
+
+	if (uip_ip_hdrlen(ip) != 20) {
+		pr_warning("IP header length is not 20 bytes");
+		return -1;
+	}
+
+	switch (ip->proto) {
+	case UIP_IP_P_ICMP:
+		uip_tx_do_ipv4_icmp(arg);
+		break;
+	case UIP_IP_P_TCP:
+		uip_tx_do_ipv4_tcp(arg);
+		break;
+	case UIP_IP_P_UDP:
+		uip_tx_do_ipv4_udp(arg);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
diff --git a/tools/kvm/net/uip/tcp.c b/tools/kvm/net/uip/tcp.c
new file mode 100644
index 0000000..586a45c
--- /dev/null
+++ b/tools/kvm/net/uip/tcp.c
@@ -0,0 +1,317 @@
+#include "kvm/uip.h"
+
+#include <linux/virtio_net.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+static int uip_tcp_socket_close(struct uip_tcp_socket *sk, int how)
+{
+	shutdown(sk->fd, how);
+
+	if (sk->write_done && sk->read_done) {
+		shutdown(sk->fd, SHUT_RDWR);
+		close(sk->fd);
+
+		mutex_lock(sk->lock);
+		list_del(&sk->list);
+		mutex_unlock(sk->lock);
+
+		free(sk);
+	}
+
+	return 0;
+}
+
+static struct uip_tcp_socket *uip_tcp_socket_find(struct uip_tx_arg *arg, u32 sip, u32 dip, u16 sport, u16 dport)
+{
+	struct list_head *sk_head;
+	pthread_mutex_t *sk_lock;
+	struct uip_tcp_socket *sk;
+
+	sk_head = &arg->info->tcp_socket_head;
+	sk_lock = &arg->info->tcp_socket_lock;
+
+	mutex_lock(sk_lock);
+	list_for_each_entry(sk, sk_head, list) {
+		if (sk->sip == sip && sk->dip == dip && sk->sport == sport && sk->dport == dport) {
+			mutex_unlock(sk_lock);
+			return sk;
+		}
+	}
+	mutex_unlock(sk_lock);
+
+	return NULL;
+}
+
+static struct uip_tcp_socket *uip_tcp_socket_alloc(struct uip_tx_arg *arg, u32 sip, u32 dip, u16 sport, u16 dport)
+{
+	struct list_head *sk_head;
+	struct uip_tcp_socket *sk;
+	pthread_mutex_t *sk_lock;
+	struct uip_tcp *tcp;
+	struct uip_ip *ip;
+	int ret;
+
+	tcp = (struct uip_tcp *)arg->eth;
+	ip = (struct uip_ip *)arg->eth;
+
+	sk_head = &arg->info->tcp_socket_head;
+	sk_lock = &arg->info->tcp_socket_lock;
+
+	sk = malloc(sizeof(*sk));
+	memset(sk, 0, sizeof(*sk));
+
+	sk->lock			= sk_lock;
+	sk->info			= arg->info;
+
+	sk->fd				= socket(AF_INET, SOCK_STREAM, 0);
+	sk->addr.sin_family		= AF_INET;
+	sk->addr.sin_addr.s_addr	= dip;
+	sk->addr.sin_port		= dport;
+
+	ret = connect(sk->fd, (struct sockaddr *)&sk->addr, sizeof(sk->addr));
+	if (ret) {
+		free(sk);
+		return NULL;
+	}
+
+	sk->sip		= ip->sip;
+	sk->dip		= ip->dip;
+	sk->sport	= tcp->sport;
+	sk->dport	= tcp->dport;
+
+	mutex_lock(sk_lock);
+	list_add_tail(&sk->list, sk_head);
+	mutex_unlock(sk_lock);
+
+	return sk;
+}
+
+static int uip_tcp_payload_send(struct uip_tcp_socket *sk, u8 flag, u16 payload_len)
+{
+	struct uip_info *info;
+	struct uip_eth *eth2;
+	struct uip_tcp *tcp2;
+	struct uip_buf *buf;
+	struct uip_ip *ip2;
+
+	info		= sk->info;
+
+	/*
+	 * Get free buffer to send data to guest
+	 */
+	buf		= uip_buf_get_free(info);
+
+	/*
+	 * Cook a ethernet frame
+	 */
+	tcp2		= (struct uip_tcp *)buf->eth;
+	eth2		= (struct uip_eth *)buf->eth;
+	ip2		= (struct uip_ip *)buf->eth;
+
+	eth2->src	= info->host_mac;
+	eth2->dst	= info->guest_mac;
+	eth2->type	= htons(UIP_ETH_P_IP);
+
+	ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
+	ip2->tos	= 0;
+	ip2->id		= 0;
+	ip2->flgfrag	= 0;
+	ip2->ttl	= UIP_IP_TTL;
+	ip2->proto	= UIP_IP_P_TCP;
+	ip2->csum	= 0;
+	ip2->sip	= sk->dip;
+	ip2->dip	= sk->sip;
+
+	tcp2->sport	= sk->dport;
+	tcp2->dport	= sk->sport;
+	tcp2->seq	= htonl(sk->seq_server);
+	tcp2->ack	= htonl(sk->ack_server);
+	/*
+	 * Diable TCP options, tcp hdr len equals 20 bytes
+	 */
+	tcp2->off	= UIP_TCP_HDR_LEN;
+	tcp2->flg	= flag;
+	tcp2->win	= htons(UIP_TCP_WIN_SIZE);
+	tcp2->csum	= 0;
+	tcp2->urgent	= 0;
+
+	if (payload_len > 0)
+		memcpy(uip_tcp_payload(tcp2), sk->payload, payload_len);
+
+	ip2->len	= htons(uip_tcp_hdrlen(tcp2) + payload_len + uip_ip_hdrlen(ip2));
+	ip2->csum	= uip_csum_ip(ip2);
+	tcp2->csum	= uip_csum_tcp(tcp2);
+
+	/*
+	 * virtio_net_hdr
+	 */
+	buf->vnet_len	= sizeof(struct virtio_net_hdr);
+	memset(buf->vnet, 0, buf->vnet_len);
+
+	buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);
+
+	/*
+	 * Increase server seq
+	 */
+	sk->seq_server  += payload_len;
+
+	/*
+	 * Send data received from socket to guest
+	 */
+	uip_buf_set_used(info, buf);
+
+	return 0;
+}
+
+static void *uip_tcp_socket_thread(void *p)
+{
+	struct uip_tcp_socket *sk;
+	u8 *payload;
+	int ret;
+
+	sk = p;
+
+	payload = malloc(UIP_MAX_TCP_PAYLOAD);
+	sk->payload = payload;
+	if (!sk->payload)
+		goto out;
+
+	while (1) {
+
+		ret = read(sk->fd, payload, UIP_MAX_TCP_PAYLOAD);
+
+		if (ret <= 0 || ret > UIP_MAX_TCP_PAYLOAD)
+			goto out;
+
+		uip_tcp_payload_send(sk, UIP_TCP_FLAG_ACK, ret);
+
+	}
+
+out:
+	/*
+	 * Close server to guest TCP connection
+	 */
+	uip_tcp_socket_close(sk, SHUT_RD);
+
+	uip_tcp_payload_send(sk, UIP_TCP_FLAG_FIN | UIP_TCP_FLAG_ACK, 0);
+	sk->seq_server += 1;
+
+	sk->read_done = 1;
+
+	free(sk->payload);
+	pthread_exit(NULL);
+
+	return NULL;
+}
+
+static int uip_tcp_socket_receive(struct uip_tcp_socket *sk)
+{
+	if (sk->thread == 0)
+		return pthread_create(&sk->thread, NULL, uip_tcp_socket_thread, (void *)sk);
+
+	return 0;
+}
+
+static int uip_tcp_socket_send(struct uip_tcp_socket *sk, struct uip_tcp *tcp)
+{
+	int len;
+	int ret;
+	u8 *payload;
+
+	if (sk->write_done)
+		return 0;
+
+	payload = uip_tcp_payload(tcp);
+	len = uip_tcp_payloadlen(tcp);
+
+	ret = write(sk->fd, payload, len);
+	if (ret != len)
+		pr_warning("tcp send error");
+
+	return ret;
+}
+
+int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg)
+{
+	struct uip_tcp_socket *sk;
+	struct uip_tcp *tcp;
+	struct uip_ip *ip;
+	int ret;
+
+	tcp = (struct uip_tcp *)arg->eth;
+	ip = (struct uip_ip *)arg->eth;
+
+	/*
+	 * Guest is trying to start a TCP session, let's fake SYN-ACK to guest
+	 */
+	if (uip_tcp_is_syn(tcp)) {
+		sk = uip_tcp_socket_alloc(arg, ip->sip, ip->dip, tcp->sport, tcp->dport);
+		if (!sk)
+			return -1;
+
+		/*
+		 * Setup ISN number
+		 */
+		sk->isn_guest  = uip_tcp_isn(tcp);
+		sk->isn_server = uip_tcp_isn_alloc();
+
+		sk->seq_server = sk->isn_server;
+		sk->ack_server = sk->isn_guest + 1;
+		uip_tcp_payload_send(sk, UIP_TCP_FLAG_SYN | UIP_TCP_FLAG_ACK, 0);
+		sk->seq_server += 1;
+
+		/*
+		 * Start receive thread for data from remote to guest
+		 */
+		uip_tcp_socket_receive(sk);
+
+		goto out;
+	}
+
+	/*
+	 * Find socket we have allocated
+	 */
+	sk = uip_tcp_socket_find(arg, ip->sip, ip->dip, tcp->sport, tcp->dport);
+	if (!sk)
+		return -1;
+
+	sk->guest_acked = ntohl(tcp->ack);
+
+	if (uip_tcp_is_fin(tcp)) {
+		if (sk->write_done)
+			goto out;
+
+		sk->write_done = 1;
+		sk->ack_server += 1;
+		uip_tcp_payload_send(sk, UIP_TCP_FLAG_ACK, 0);
+
+		/*
+		 * Close guest to server TCP connection
+		 */
+		uip_tcp_socket_close(sk, SHUT_WR);
+
+		goto out;
+	}
+
+	/*
+	 * Ignore guest to server frames with zero tcp payload
+	 */
+	if (uip_tcp_payloadlen(tcp) == 0)
+		goto out;
+
+	/*
+	 * Sent out TCP data to remote host
+	 */
+	ret = uip_tcp_socket_send(sk, tcp);
+	if (ret < 0)
+		return -1;
+	/*
+	 * Send ACK to guest imediately
+	 */
+	sk->ack_server += ret;
+	uip_tcp_payload_send(sk, UIP_TCP_FLAG_ACK, 0);
+
+out:
+	return 0;
+}
diff --git a/tools/kvm/net/uip/udp.c b/tools/kvm/net/uip/udp.c
new file mode 100644
index 0000000..d4518b2
--- /dev/null
+++ b/tools/kvm/net/uip/udp.c
@@ -0,0 +1,236 @@
+#include "kvm/uip.h"
+
+#include <linux/virtio_net.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include <fcntl.h>
+
+#define UIP_UDP_MAX_EVENTS 1000
+
+static struct uip_udp_socket *uip_udp_socket_find(struct uip_tx_arg *arg, u32 sip, u32 dip, u16 sport, u16 dport)
+{
+	struct list_head *sk_head;
+	struct uip_udp_socket *sk;
+	pthread_mutex_t *sk_lock;
+	struct epoll_event ev;
+	int flags;
+	int ret;
+
+	sk_head = &arg->info->udp_socket_head;
+	sk_lock = &arg->info->udp_socket_lock;
+
+	/*
+	 * Find existing sk
+	 */
+	mutex_lock(sk_lock);
+	list_for_each_entry(sk, sk_head, list) {
+		if (sk->sip == sip && sk->dip == dip && sk->sport == sport && sk->dport == dport) {
+			mutex_unlock(sk_lock);
+			return sk;
+		}
+	}
+	mutex_unlock(sk_lock);
+
+	/*
+	 * Allocate new one
+	 */
+	sk = malloc(sizeof(*sk));
+	memset(sk, 0, sizeof(*sk));
+
+	sk->lock = sk_lock;
+
+	sk->fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sk->fd < 0)
+		goto out;
+
+	/*
+	 * Set non-blocking
+	 */
+	flags = fcntl(sk->fd, F_GETFL, 0);
+	flags |= O_NONBLOCK;
+	fcntl(sk->fd, F_SETFL, flags);
+
+	/*
+	 * Add sk->fd to epoll_wait
+	 */
+	ev.events	= EPOLLIN;
+	ev.data.fd	= sk->fd;
+	ev.data.ptr	= sk;
+	if (arg->info->udp_epollfd <= 0)
+		arg->info->udp_epollfd = epoll_create(UIP_UDP_MAX_EVENTS);
+	ret = epoll_ctl(arg->info->udp_epollfd, EPOLL_CTL_ADD, sk->fd, &ev);
+	if (ret == -1)
+		pr_warning("epoll_ctl error");
+
+	sk->addr.sin_family	 = AF_INET;
+	sk->addr.sin_addr.s_addr = dip;
+	sk->addr.sin_port	 = dport;
+
+	sk->sip			 = sip;
+	sk->dip			 = dip;
+	sk->sport		 = sport;
+	sk->dport		 = dport;
+
+	mutex_lock(sk_lock);
+	list_add_tail(&sk->list, sk_head);
+	mutex_unlock(sk_lock);
+
+	return sk;
+
+out:
+	free(sk);
+	return NULL;
+}
+
+static int uip_udp_socket_send(struct uip_udp_socket *sk, struct uip_udp *udp)
+{
+	int len;
+	int ret;
+
+	len = ntohs(udp->len) - uip_udp_hdrlen(udp);
+
+	ret = sendto(sk->fd, udp->payload, len, 0, (struct sockaddr *)&sk->addr, sizeof(sk->addr));
+	if (ret != len)
+		return -1;
+
+	return 0;
+}
+
+int uip_udp_make_pkg(struct uip_info *info, struct uip_udp_socket *sk, struct uip_buf *buf, u8* payload, int payload_len)
+{
+	struct uip_eth *eth2;
+	struct uip_udp *udp2;
+	struct uip_ip *ip2;
+
+	/*
+	 * Cook a ethernet frame
+	 */
+	udp2		= (struct uip_udp *)(buf->eth);
+	eth2		= (struct uip_eth *)buf->eth;
+	ip2		= (struct uip_ip *)(buf->eth);
+
+	eth2->src	= info->host_mac;
+	eth2->dst	= info->guest_mac;
+	eth2->type	= htons(UIP_ETH_P_IP);
+
+	ip2->vhl	= UIP_IP_VER_4 | UIP_IP_HDR_LEN;
+	ip2->tos	= 0;
+	ip2->id		= 0;
+	ip2->flgfrag	= 0;
+	ip2->ttl	= UIP_IP_TTL;
+	ip2->proto	= UIP_IP_P_UDP;
+	ip2->csum	= 0;
+
+	ip2->sip	= sk->dip;
+	ip2->dip	= sk->sip;
+	udp2->sport	= sk->dport;
+	udp2->dport	= sk->sport;
+
+	udp2->len	= htons(payload_len + uip_udp_hdrlen(udp2));
+	udp2->csum	= 0;
+
+	if (payload)
+		memcpy(udp2->payload, payload, payload_len);
+
+	ip2->len	= udp2->len + htons(uip_ip_hdrlen(ip2));
+	ip2->csum	= uip_csum_ip(ip2);
+	udp2->csum	= uip_csum_udp(udp2);
+
+	/*
+	 * virtio_net_hdr
+	 */
+	buf->vnet_len	= sizeof(struct virtio_net_hdr);
+	memset(buf->vnet, 0, buf->vnet_len);
+
+	buf->eth_len	= ntohs(ip2->len) + uip_eth_hdrlen(&ip2->eth);
+
+	return 0;
+}
+
+static void *uip_udp_socket_thread(void *p)
+{
+	struct epoll_event events[UIP_UDP_MAX_EVENTS];
+	struct uip_udp_socket *sk;
+	struct uip_info *info;
+	struct uip_buf *buf;
+	int payload_len;
+	u8 *payload;
+	int nfds;
+	int i;
+
+	info = p;
+
+	do {
+		payload = malloc(UIP_MAX_UDP_PAYLOAD);
+	} while (!payload);
+
+	while (1) {
+		nfds = epoll_wait(info->udp_epollfd, events, UIP_UDP_MAX_EVENTS, -1);
+
+		if (nfds == -1)
+			continue;
+
+		for (i = 0; i < nfds; i++) {
+
+			sk = events[i].data.ptr;
+			payload_len = recvfrom(sk->fd, payload, UIP_MAX_UDP_PAYLOAD, 0, NULL, NULL);
+			if (payload_len < 0)
+				continue;
+
+			/*
+			 * Get free buffer to send data to guest
+			 */
+			buf = uip_buf_get_free(info);
+
+			uip_udp_make_pkg(info, sk, buf, payload, payload_len);
+
+			/*
+			 * Send data received from socket to guest
+			 */
+			uip_buf_set_used(info, buf);
+		}
+	}
+
+	free(payload);
+	pthread_exit(NULL);
+	return NULL;
+}
+
+int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg)
+{
+	struct uip_udp_socket *sk;
+	struct uip_info *info;
+	struct uip_udp *udp;
+	struct uip_ip *ip;
+	int ret;
+
+	udp	= (struct uip_udp *)(arg->eth);
+	ip	= (struct uip_ip *)(arg->eth);
+	info	= arg->info;
+
+	if (uip_udp_is_dhcp(udp)) {
+		uip_tx_do_ipv4_udp_dhcp(arg);
+		return 0;
+	}
+
+	/*
+	 * Find socket we have allocated before, otherwise allocate one
+	 */
+	sk = uip_udp_socket_find(arg, ip->sip, ip->dip, udp->sport, udp->dport);
+	if (!sk)
+		return -1;
+
+	/*
+	 * Send out UDP data to remote host
+	 */
+	ret = uip_udp_socket_send(sk, udp);
+	if (ret)
+		return -1;
+
+	if (!info->udp_thread)
+		pthread_create(&info->udp_thread, NULL, uip_udp_socket_thread, (void *)info);
+
+	return 0;
+}
diff --git a/tools/kvm/pci.c b/tools/kvm/pci.c
new file mode 100644
index 0000000..38f4778
--- /dev/null
+++ b/tools/kvm/pci.c
@@ -0,0 +1,213 @@
+#include "kvm/pci.h"
+#include "kvm/ioport.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+
+#include <linux/err.h>
+#include <assert.h>
+
+#define PCI_BAR_OFFSET(b)		(offsetof(struct pci_device_header, bar[b]))
+
+static struct pci_device_header		*pci_devices[PCI_MAX_DEVICES];
+
+static union pci_config_address		pci_config_address;
+
+/* This is within our PCI gap - in an unused area.
+ * Note this is a PCI *bus address*, is used to assign BARs etc.!
+ * (That's why it can still 32bit even with 64bit guests-- 64bit
+ * PCI isn't currently supported.)
+ */
+static u32 io_space_blocks		= KVM_PCI_MMIO_AREA;
+
+u32 pci_get_io_space_block(u32 size)
+{
+	u32 block = io_space_blocks;
+	io_space_blocks += size;
+
+	return block;
+}
+
+static void *pci_config_address_ptr(u16 port)
+{
+	unsigned long offset;
+	void *base;
+
+	offset	= port - PCI_CONFIG_ADDRESS;
+	base	= &pci_config_address;
+
+	return base + offset;
+}
+
+static bool pci_config_address_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	void *p = pci_config_address_ptr(port);
+
+	memcpy(p, data, size);
+
+	return true;
+}
+
+static bool pci_config_address_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	void *p = pci_config_address_ptr(port);
+
+	memcpy(data, p, size);
+
+	return true;
+}
+
+static struct ioport_operations pci_config_address_ops = {
+	.io_in	= pci_config_address_in,
+	.io_out	= pci_config_address_out,
+};
+
+static bool pci_device_exists(u8 bus_number, u8 device_number, u8 function_number)
+{
+	struct pci_device_header *dev;
+
+	if (pci_config_address.bus_number != bus_number)
+		return false;
+
+	if (pci_config_address.function_number != function_number)
+		return false;
+
+	if (device_number >= PCI_MAX_DEVICES)
+		return false;
+
+	dev = pci_devices[device_number];
+
+	return dev != NULL;
+}
+
+static bool pci_config_data_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	/*
+	 * If someone accesses PCI configuration space offsets that are not
+	 * aligned to 4 bytes, it uses ioports to signify that.
+	 */
+	pci_config_address.reg_offset = port - PCI_CONFIG_DATA;
+
+	pci__config_wr(kvm, pci_config_address, data, size);
+
+	return true;
+}
+
+static bool pci_config_data_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	/*
+	 * If someone accesses PCI configuration space offsets that are not
+	 * aligned to 4 bytes, it uses ioports to signify that.
+	 */
+	pci_config_address.reg_offset = port - PCI_CONFIG_DATA;
+
+	pci__config_rd(kvm, pci_config_address, data, size);
+
+	return true;
+}
+
+static struct ioport_operations pci_config_data_ops = {
+	.io_in	= pci_config_data_in,
+	.io_out	= pci_config_data_out,
+};
+
+void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size)
+{
+	u8 dev_num;
+
+	dev_num	= addr.device_number;
+
+	if (pci_device_exists(0, dev_num, 0)) {
+		unsigned long offset;
+
+		offset = addr.w & 0xff;
+		if (offset < sizeof(struct pci_device_header)) {
+			void *p = pci_devices[dev_num];
+			u8 bar = (offset - PCI_BAR_OFFSET(0)) / (sizeof(u32));
+			u32 sz = PCI_IO_SIZE;
+
+			if (bar < 6 && pci_devices[dev_num]->bar_size[bar])
+				sz = pci_devices[dev_num]->bar_size[bar];
+
+			/*
+			 * If the kernel masks the BAR it would expect to find the
+			 * size of the BAR there next time it reads from it.
+			 * When the kernel got the size it would write the address
+			 * back.
+			 */
+			if (*(u32 *)(p + offset)) {
+				/* See if kernel tries to mask one of the BARs */
+				if ((offset >= PCI_BAR_OFFSET(0)) &&
+				    (offset <= PCI_BAR_OFFSET(6)) &&
+				    (ioport__read32(data)  == 0xFFFFFFFF))
+					memcpy(p + offset, &sz, sizeof(sz));
+				    else
+					memcpy(p + offset, data, size);
+			}
+		}
+	}
+}
+
+void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size)
+{
+	u8 dev_num;
+
+	dev_num	= addr.device_number;
+
+	if (pci_device_exists(0, dev_num, 0)) {
+		unsigned long offset;
+
+		offset = addr.w & 0xff;
+		if (offset < sizeof(struct pci_device_header)) {
+			void *p = pci_devices[dev_num];
+
+			memcpy(data, p + offset, size);
+		} else {
+			memset(data, 0x00, size);
+		}
+	} else {
+		memset(data, 0xff, size);
+	}
+}
+
+int pci__register(struct pci_device_header *dev, u8 dev_num)
+{
+	if (dev_num >= PCI_MAX_DEVICES)
+		return -ENOSPC;
+
+	pci_devices[dev_num] = dev;
+
+	return 0;
+}
+
+struct pci_device_header *pci__find_dev(u8 dev_num)
+{
+	if (dev_num >= PCI_MAX_DEVICES)
+		return ERR_PTR(-EOVERFLOW);
+
+	return pci_devices[dev_num];
+}
+
+int pci__init(struct kvm *kvm)
+{
+	int r;
+
+	r = ioport__register(PCI_CONFIG_DATA + 0, &pci_config_data_ops, 4, NULL);
+	if (r < 0)
+		return r;
+
+	r = ioport__register(PCI_CONFIG_ADDRESS + 0, &pci_config_address_ops, 4, NULL);
+	if (r < 0) {
+		ioport__unregister(PCI_CONFIG_DATA);
+		return r;
+	}
+
+	return 0;
+}
+
+int pci__exit(struct kvm *kvm)
+{
+	ioport__unregister(PCI_CONFIG_DATA);
+	ioport__unregister(PCI_CONFIG_ADDRESS);
+
+	return 0;
+}
diff --git a/tools/kvm/powerpc/cpu_info.c b/tools/kvm/powerpc/cpu_info.c
new file mode 100644
index 0000000..c364b74
--- /dev/null
+++ b/tools/kvm/powerpc/cpu_info.c
@@ -0,0 +1,83 @@
+/*
+ * PPC CPU identification
+ *
+ * This is a very simple "host CPU info" struct to get us going.
+ * For the little host information we need, I don't want to grub about
+ * parsing stuff in /proc/device-tree so just match host PVR to differentiate
+ * PPC970 and POWER7 (which is all that's currently supported).
+ *
+ * Qemu does something similar but this is MUCH simpler!
+ *
+ * Copyright 2012 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "cpu_info.h"
+#include "kvm/util.h"
+
+/* POWER7 */
+
+/*
+ * Basic set of pages for POWER7.  It actually supports more but there were some
+ * limitations as to which may be advertised to the guest.  FIXME when this
+ * settles down -- for now use basic set:
+ */
+static u32 power7_page_sizes_prop[] = {0xc, 0x0, 0x1, 0xc, 0x0, 0x18, 0x100, 0x1, 0x18, 0x0};
+/* POWER7 has 1T segments, so advertise these */
+static u32 power7_segment_sizes_prop[] = {0x1c, 0x28, 0xffffffff, 0xffffffff};
+
+static struct cpu_info cpu_power7_info = {
+	"POWER7",
+	power7_page_sizes_prop, sizeof(power7_page_sizes_prop),
+	power7_segment_sizes_prop, sizeof(power7_segment_sizes_prop),
+	32, 		/* SLB size */
+	512000000, 	/* TB frequency */
+	128,		/* d-cache block size */
+	128,		/* i-cache block size */
+	CPUINFO_FLAG_DFP | CPUINFO_FLAG_VSX | CPUINFO_FLAG_VMX
+};
+
+/* PPC970/G5 */
+
+static u32 g5_page_sizes_prop[] = {0xc, 0x0, 0x1, 0xc, 0x0, 0x18, 0x100, 0x1, 0x18, 0x0};
+
+static struct cpu_info cpu_970_info = {
+	"G5",
+	g5_page_sizes_prop, sizeof(g5_page_sizes_prop),
+	0 /* Null = no segment sizes prop, use defaults */, 0,
+	0, 		/* SLB size default */
+	33333333, 	/* TB frequency */
+	128,		/* d-cache block size */
+	128,		/* i-cache block size */
+	CPUINFO_FLAG_VMX
+};
+
+/* This is a default catchall for 'no match' on PVR: */
+static struct cpu_info cpu_dummy_info = { "unknown", 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static struct pvr_info host_pvr_info[] = {
+	{ 0xffffffff, 0x0f000003, &cpu_power7_info },
+	{ 0xffff0000, 0x003f0000, &cpu_power7_info },
+	{ 0xffff0000, 0x004a0000, &cpu_power7_info },
+	{ 0xffff0000, 0x00390000, &cpu_970_info },
+	{ 0xffff0000, 0x003c0000, &cpu_970_info },
+        { 0xffff0000, 0x00440000, &cpu_970_info },
+        { 0xffff0000, 0x00450000, &cpu_970_info },
+};
+
+struct cpu_info *find_cpu_info(u32 pvr)
+{
+	unsigned int i;
+	for (i = 0; i < sizeof(host_pvr_info)/sizeof(struct pvr_info); i++) {
+		if ((pvr & host_pvr_info[i].pvr_mask) ==
+		    host_pvr_info[i].pvr) {
+			return host_pvr_info[i].cpu_info;
+		}
+	}
+	/* Didn't find anything? Rut-ro. */
+	pr_warning("Host CPU unsupported by kvmtool\n");
+	return &cpu_dummy_info;
+}
diff --git a/tools/kvm/powerpc/cpu_info.h b/tools/kvm/powerpc/cpu_info.h
new file mode 100644
index 0000000..4a43ed5
--- /dev/null
+++ b/tools/kvm/powerpc/cpu_info.h
@@ -0,0 +1,43 @@
+/*
+ * PPC CPU identification
+ *
+ * Copyright 2012 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef CPU_INFO_H
+#define CPU_INFO_H
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+struct cpu_info {
+	const char	*name;
+	u32 		*page_sizes_prop;
+	u32		page_sizes_prop_len;
+	u32 		*segment_sizes_prop;
+	u32		segment_sizes_prop_len;
+	u32		slb_size;
+	u32		tb_freq;
+	u32		d_bsize;
+	u32		i_bsize;
+	u32		flags;
+};
+
+struct pvr_info {
+	u32		pvr_mask;
+	u32		pvr;
+	struct cpu_info *cpu_info;
+};
+
+/* Misc capabilities/CPU properties */
+#define CPUINFO_FLAG_DFP	0x00000001
+#define CPUINFO_FLAG_VMX	0x00000002
+#define CPUINFO_FLAG_VSX	0x00000004
+
+struct cpu_info *find_cpu_info(u32 pvr);
+
+#endif
diff --git a/tools/kvm/powerpc/include/kvm/barrier.h b/tools/kvm/powerpc/include/kvm/barrier.h
new file mode 100644
index 0000000..bc7d179
--- /dev/null
+++ b/tools/kvm/powerpc/include/kvm/barrier.h
@@ -0,0 +1,6 @@
+#ifndef _KVM_BARRIER_H_
+#define _KVM_BARRIER_H_
+
+#include <asm/system.h>
+
+#endif /* _KVM_BARRIER_H_ */
diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h
new file mode 100644
index 0000000..c7620b2
--- /dev/null
+++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h
@@ -0,0 +1,88 @@
+/*
+ * PPC64 architecture-specific definitions
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef KVM__KVM_ARCH_H
+#define KVM__KVM_ARCH_H
+
+#include <stdbool.h>
+#include <linux/types.h>
+#include <time.h>
+
+/*
+ * MMIO lives after RAM, but it'd be nice if it didn't constantly move.
+ * Choose a suitably high address, e.g. 63T...  This limits RAM size.
+ */
+#define PPC_MMIO_START			0x3F0000000000UL
+#define PPC_MMIO_SIZE			0x010000000000UL
+
+#define KERNEL_LOAD_ADDR        	0x0000000000000000
+#define KERNEL_START_ADDR       	0x0000000000000000
+#define KERNEL_SECONDARY_START_ADDR     0x0000000000000060
+#define INITRD_LOAD_ADDR        	0x0000000002800000
+
+#define FDT_MAX_SIZE            	0x10000
+#define RTAS_MAX_SIZE           	0x10000
+
+#define TIMEBASE_FREQ           	512000000ULL
+
+#define KVM_MMIO_START			PPC_MMIO_START
+
+/*
+ * This is the address that pci_get_io_space_block() starts allocating
+ * from.  Note that this is a PCI bus address.
+ */
+#define KVM_PCI_MMIO_AREA		0x1000000
+
+struct spapr_phb;
+
+struct kvm {
+	int			sys_fd;		/* For system ioctls(), i.e. /dev/kvm */
+	int			vm_fd;		/* For VM ioctls() */
+	timer_t			timerid;	/* Posix timer for interrupts */
+
+	int			nrcpus;		/* Number of cpus to run */
+
+	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
+
+	u64			ram_size;
+	void			*ram_start;
+
+	u64			sdr1;
+	u32			pvr;
+
+	bool			nmi_disabled;
+
+	bool			single_step;
+
+	const char		*vmlinux;
+	struct disk_image       **disks;
+	int                     nr_disks;
+	unsigned long		rtas_gra;
+	unsigned long		rtas_size;
+	unsigned long		fdt_gra;
+	unsigned long		initrd_gra;
+	unsigned long		initrd_size;
+	char			*name;
+	int			vm_state;
+	struct icp_state	*icp;
+	struct spapr_phb	*phb;
+};
+
+/* Helper for the various bits of code that generate FDT nodes */
+#define _FDT(exp)							\
+	do {								\
+		int ret = (exp);					\
+		if (ret < 0) {						\
+			die("Error creating device tree: %s: %s\n",	\
+			    #exp, fdt_strerror(ret));			\
+		}							\
+	} while (0)
+
+#endif /* KVM__KVM_ARCH_H */
diff --git a/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h b/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h
new file mode 100644
index 0000000..7520c04
--- /dev/null
+++ b/tools/kvm/powerpc/include/kvm/kvm-cpu-arch.h
@@ -0,0 +1,76 @@
+/*
+ * PPC64 cpu-specific definitions
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef KVM__KVM_CPU_ARCH_H
+#define KVM__KVM_CPU_ARCH_H
+
+/* Architecture-specific kvm_cpu definitions. */
+
+#include <linux/kvm.h>	/* for struct kvm_regs */
+#include <stdbool.h>
+#include <pthread.h>
+
+#define MSR_SF		(1UL<<63)
+#define MSR_HV		(1UL<<60)
+#define MSR_VEC		(1UL<<25)
+#define MSR_VSX		(1UL<<23)
+#define MSR_POW		(1UL<<18)
+#define MSR_EE		(1UL<<15)
+#define MSR_PR		(1UL<<14)
+#define MSR_FP		(1UL<<13)
+#define MSR_ME		(1UL<<12)
+#define MSR_FE0		(1UL<<11)
+#define MSR_SE		(1UL<<10)
+#define MSR_BE		(1UL<<9)
+#define MSR_FE1		(1UL<<8)
+#define MSR_IR		(1UL<<5)
+#define MSR_DR		(1UL<<4)
+#define MSR_PMM		(1UL<<2)
+#define MSR_RI		(1UL<<1)
+#define MSR_LE		(1UL<<0)
+
+#define POWER7_EXT_IRQ	0
+
+struct kvm;
+
+struct kvm_cpu {
+	pthread_t		thread;		/* VCPU thread */
+
+	unsigned long		cpu_id;
+
+	struct kvm		*kvm;		/* parent KVM */
+	int			vcpu_fd;	/* For VCPU ioctls() */
+	struct kvm_run		*kvm_run;
+
+	struct kvm_regs		regs;
+	struct kvm_sregs	sregs;
+	struct kvm_fpu		fpu;
+
+	u8			is_running;
+	u8			paused;
+	u8			needs_nmi;
+	/*
+	 * Although PPC KVM doesn't yet support coalesced MMIO, generic code
+	 * needs this in our kvm_cpu:
+	 */
+	struct kvm_coalesced_mmio_ring  *ring;
+};
+
+void kvm_cpu__irq(struct kvm_cpu *vcpu, int pin, int level);
+
+/* This is never actually called on PPC. */
+static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
+{
+	return false;
+}
+
+bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write);
+
+#endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/tools/kvm/powerpc/ioport.c b/tools/kvm/powerpc/ioport.c
new file mode 100644
index 0000000..a8e4dc3
--- /dev/null
+++ b/tools/kvm/powerpc/ioport.c
@@ -0,0 +1,18 @@
+/*
+ * PPC64 ioport platform setup.  There isn't any! :-)
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "kvm/ioport.h"
+
+#include <stdlib.h>
+
+void ioport__setup_arch(void)
+{
+	/* PPC has no legacy ioports to set up */
+}
diff --git a/tools/kvm/powerpc/irq.c b/tools/kvm/powerpc/irq.c
new file mode 100644
index 0000000..7da4012
--- /dev/null
+++ b/tools/kvm/powerpc/irq.c
@@ -0,0 +1,75 @@
+/*
+ * PPC64 IRQ routines
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "kvm/irq.h"
+#include "kvm/kvm.h"
+#include "kvm/util.h"
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+#include <linux/kvm.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "kvm/pci.h"
+
+#include "xics.h"
+#include "spapr_pci.h"
+
+#define XICS_IRQS               1024
+
+/*
+ * FIXME: The code in this file assumes an SPAPR guest, using XICS.  Make
+ * generic & cope with multiple PPC platform types.
+ */
+
+static int pci_devs = 0;
+
+int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
+{
+	if (pci_devs >= PCI_MAX_DEVICES)
+		die("Hit PCI device limit!\n");
+
+	*num = pci_devs++;
+
+	*pin = 1;
+	/*
+	 * Have I said how nasty I find this?  Line should be dontcare... PHB
+	 * should determine which CPU/XICS IRQ to fire.
+	 */
+	*line = xics_alloc_irqnum();
+	return 0;
+}
+
+int irq__init(struct kvm *kvm)
+{
+	/*
+	 * kvm->nr_cpus is now valid; for /now/, pass
+	 * this to xics_system_init(), which assumes servers
+	 * are numbered 0..nrcpus.  This may not really be true,
+	 * but it is OK currently.
+	 */
+	kvm->icp = xics_system_init(XICS_IRQS, kvm->nrcpus);
+	return 0;
+}
+
+int irq__exit(struct kvm *kvm)
+{
+	return 0;
+}
+
+int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg)
+{
+	die(__FUNCTION__);
+	return 0;
+}
diff --git a/tools/kvm/powerpc/kvm-cpu.c b/tools/kvm/powerpc/kvm-cpu.c
new file mode 100644
index 0000000..2505c69
--- /dev/null
+++ b/tools/kvm/powerpc/kvm-cpu.c
@@ -0,0 +1,291 @@
+/*
+ * PPC64 processor support
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "kvm/kvm-cpu.h"
+
+#include "kvm/symbol.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+
+#include "spapr.h"
+#include "spapr_pci.h"
+#include "xics.h"
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <assert.h>
+
+static int debug_fd;
+
+void kvm_cpu__set_debug_fd(int fd)
+{
+	debug_fd = fd;
+}
+
+int kvm_cpu__get_debug_fd(void)
+{
+	return debug_fd;
+}
+
+static struct kvm_cpu *kvm_cpu__new(struct kvm *kvm)
+{
+	struct kvm_cpu *vcpu;
+
+	vcpu		= calloc(1, sizeof *vcpu);
+	if (!vcpu)
+		return NULL;
+
+	vcpu->kvm	= kvm;
+
+	return vcpu;
+}
+
+void kvm_cpu__delete(struct kvm_cpu *vcpu)
+{
+	free(vcpu);
+}
+
+struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id)
+{
+	struct kvm_cpu *vcpu;
+	int mmap_size;
+	struct kvm_enable_cap papr_cap = { .cap = KVM_CAP_PPC_PAPR };
+
+	vcpu		= kvm_cpu__new(kvm);
+	if (!vcpu)
+		return NULL;
+
+	vcpu->cpu_id	= cpu_id;
+
+	vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
+	if (vcpu->vcpu_fd < 0)
+		die_perror("KVM_CREATE_VCPU ioctl");
+
+	mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
+	if (mmap_size < 0)
+		die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
+
+	vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0);
+	if (vcpu->kvm_run == MAP_FAILED)
+		die("unable to mmap vcpu fd");
+
+	if (ioctl(vcpu->vcpu_fd, KVM_ENABLE_CAP, &papr_cap) < 0)
+		die("unable to enable PAPR capability");
+
+	/*
+	 * We start all CPUs, directing non-primary threads into the kernel's
+	 * secondary start point.  When we come to support SLOF, we will start
+	 * only one and SLOF will RTAS call us to ask for others to be
+	 * started.  (FIXME: make more generic & interface with whichever
+	 * firmware a platform may be using.)
+	 */
+	vcpu->is_running = true;
+
+	/* Register with IRQ controller (FIXME, assumes XICS) */
+	xics_cpu_register(vcpu);
+
+	return vcpu;
+}
+
+static void kvm_cpu__setup_fpu(struct kvm_cpu *vcpu)
+{
+	/* Don't have to do anything, there's no expected FPU state. */
+}
+
+static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu)
+{
+	/*
+	 * FIXME: This assumes PPC64 and Linux guest.  It doesn't use the
+	 * OpenFirmware entry method, but instead the "embedded" entry which
+	 * passes the FDT address directly.
+	 */
+	struct kvm_regs *r = &vcpu->regs;
+
+	if (vcpu->cpu_id == 0) {
+		r->pc = KERNEL_START_ADDR;
+		r->gpr[3] = vcpu->kvm->fdt_gra;
+		r->gpr[5] = 0;
+	} else {
+		r->pc = KERNEL_SECONDARY_START_ADDR;
+		r->gpr[3] = vcpu->cpu_id;
+	}
+	r->msr = 0x8000000000001000UL; /* 64bit, non-HV, ME */
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_REGS, &vcpu->regs) < 0)
+		die_perror("KVM_SET_REGS failed");
+}
+
+static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu)
+{
+	/*
+	 * Some sregs setup to initialise SDR1/PVR/HIOR on PPC64 SPAPR
+	 * platforms using PR KVM.  (Technically, this is all ignored on
+	 * SPAPR HV KVM.)  Different setup is required for non-PV non-SPAPR
+	 * platforms!  (FIXME.)
+	 */
+	struct kvm_sregs sregs;
+	struct kvm_one_reg reg = {};
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	sregs.u.s.sdr1 = vcpu->kvm->sdr1;
+	sregs.pvr = vcpu->kvm->pvr;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &sregs) < 0)
+		die("KVM_SET_SREGS failed");
+
+	reg.id = KVM_ONE_REG_PPC_HIOR;
+	reg.u.reg64 = 0;
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
+		die("KVM_SET_ONE_REG failed");
+}
+
+/**
+ * kvm_cpu__reset_vcpu - reset virtual CPU to a known state
+ */
+void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
+{
+	kvm_cpu__setup_regs(vcpu);
+	kvm_cpu__setup_sregs(vcpu);
+	kvm_cpu__setup_fpu(vcpu);
+}
+
+/* kvm_cpu__irq - set KVM's IRQ flag on this vcpu */
+void kvm_cpu__irq(struct kvm_cpu *vcpu, int pin, int level)
+{
+	unsigned int virq = level ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
+
+	/* FIXME: POWER-specific */
+	if (pin != POWER7_EXT_IRQ)
+		return;
+	if (ioctl(vcpu->vcpu_fd, KVM_INTERRUPT, &virq) < 0)
+		pr_warning("Could not KVM_INTERRUPT.");
+}
+
+void kvm_cpu__arch_nmi(struct kvm_cpu *cpu)
+{
+}
+
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
+{
+	bool ret = true;
+	struct kvm_run *run = vcpu->kvm_run;
+	switch(run->exit_reason) {
+	case KVM_EXIT_PAPR_HCALL:
+		run->papr_hcall.ret = spapr_hypercall(vcpu, run->papr_hcall.nr,
+						      (target_ulong*)run->papr_hcall.args);
+		break;
+	default:
+		ret = false;
+	}
+	return ret;
+}
+
+bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+{
+	/*
+	 * FIXME: This function will need to be split in order to support
+	 * various PowerPC platforms/PHB types, etc.  It currently assumes SPAPR
+	 * PPC64 guest.
+	 */
+	bool ret = false;
+
+	if ((phys_addr >= SPAPR_PCI_WIN_START) &&
+	    (phys_addr < SPAPR_PCI_WIN_END)) {
+		ret = spapr_phb_mmio(kvm, phys_addr, data, len, is_write);
+	} else {
+		pr_warning("MMIO %s unknown address %llx (size %d)!\n",
+			   is_write ? "write to" : "read from",
+			   phys_addr, len);
+	}
+	return ret;
+}
+
+#define CONDSTR_BIT(m, b) (((m) & MSR_##b) ? #b" " : "")
+
+void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
+{
+	struct kvm_regs regs;
+	struct kvm_sregs sregs;
+	int r;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &regs) < 0)
+		die("KVM_GET_REGS failed");
+        if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	dprintf(debug_fd, "\n Registers:\n");
+	dprintf(debug_fd, " NIP:   %016llx  MSR:   %016llx "
+		"( %s%s%s%s%s%s%s%s%s%s%s%s)\n",
+		regs.pc, regs.msr,
+		CONDSTR_BIT(regs.msr, SF),
+		CONDSTR_BIT(regs.msr, HV), /* ! */
+		CONDSTR_BIT(regs.msr, VEC),
+		CONDSTR_BIT(regs.msr, VSX),
+		CONDSTR_BIT(regs.msr, EE),
+		CONDSTR_BIT(regs.msr, PR),
+		CONDSTR_BIT(regs.msr, FP),
+		CONDSTR_BIT(regs.msr, ME),
+		CONDSTR_BIT(regs.msr, IR),
+		CONDSTR_BIT(regs.msr, DR),
+		CONDSTR_BIT(regs.msr, RI),
+		CONDSTR_BIT(regs.msr, LE));
+	dprintf(debug_fd, " CTR:   %016llx  LR:    %016llx  CR:   %08llx\n",
+		regs.ctr, regs.lr, regs.cr);
+	dprintf(debug_fd, " SRR0:  %016llx  SRR1:  %016llx  XER:  %016llx\n",
+		regs.srr0, regs.srr1, regs.xer);
+	dprintf(debug_fd, " SPRG0: %016llx  SPRG1: %016llx\n",
+		regs.sprg0, regs.sprg1);
+	dprintf(debug_fd, " SPRG2: %016llx  SPRG3: %016llx\n",
+		regs.sprg2, regs.sprg3);
+	dprintf(debug_fd, " SPRG4: %016llx  SPRG5: %016llx\n",
+		regs.sprg4, regs.sprg5);
+	dprintf(debug_fd, " SPRG6: %016llx  SPRG7: %016llx\n",
+		regs.sprg6, regs.sprg7);
+	dprintf(debug_fd, " GPRs:\n ");
+	for (r = 0; r < 32; r++) {
+		dprintf(debug_fd, "%016llx  ", regs.gpr[r]);
+		if ((r & 3) == 3)
+			dprintf(debug_fd, "\n ");
+	}
+	dprintf(debug_fd, "\n");
+
+	/* FIXME: Assumes SLB-based (book3s) guest */
+	for (r = 0; r < 32; r++) {
+		dprintf(debug_fd, " SLB%02d  %016llx %016llx\n", r,
+			sregs.u.s.ppc64.slb[r].slbe,
+			sregs.u.s.ppc64.slb[r].slbv);
+	}
+	dprintf(debug_fd, "----------\n");
+}
+
+void kvm_cpu__show_code(struct kvm_cpu *vcpu)
+{
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &vcpu->regs) < 0)
+		die("KVM_GET_REGS failed");
+
+	/* FIXME: Dump/disassemble some code...! */
+
+	dprintf(debug_fd, "\n Stack:\n");
+	dprintf(debug_fd,   " ------\n");
+	/* Only works in real mode: */
+	kvm__dump_mem(vcpu->kvm, vcpu->regs.gpr[1], 32);
+}
+
+void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
+{
+	/* Does nothing yet */
+}
diff --git a/tools/kvm/powerpc/kvm.c b/tools/kvm/powerpc/kvm.c
new file mode 100644
index 0000000..cbc0d8f
--- /dev/null
+++ b/tools/kvm/powerpc/kvm.c
@@ -0,0 +1,460 @@
+/*
+ * PPC64 (SPAPR) platform support
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * Portions of FDT setup borrowed from QEMU, copyright 2010 David Gibson, IBM
+ * Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "kvm/kvm.h"
+#include "kvm/util.h"
+#include "libfdt.h"
+#include "cpu_info.h"
+
+#include "spapr.h"
+#include "spapr_hvcons.h"
+#include "spapr_pci.h"
+
+#include <linux/kvm.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <asm/unistd.h>
+#include <errno.h>
+
+#include <linux/byteorder.h>
+
+#define HPT_ORDER 24
+
+#define HUGETLBFS_PATH "/var/lib/hugetlbfs/global/pagesize-16MB/"
+
+#define PHANDLE_XICP		0x00001111
+
+static char kern_cmdline[2048];
+
+struct kvm_ext kvm_req_ext[] = {
+	{ DEFINE_KVM_EXT(KVM_CAP_PPC_UNSET_IRQ) },
+	{ DEFINE_KVM_EXT(KVM_CAP_PPC_IRQ_LEVEL) },
+	{ 0, 0 }
+};
+
+static uint32_t mfpvr(void)
+{
+	uint32_t r;
+	asm volatile ("mfpvr %0" : "=r"(r));
+	return r;
+}
+
+bool kvm__arch_cpu_supports_vm(void)
+{
+	return true;
+}
+
+void kvm__init_ram(struct kvm *kvm)
+{
+	u64	phys_start, phys_size;
+	void	*host_mem;
+
+	phys_start = 0;
+	phys_size  = kvm->ram_size;
+	host_mem   = kvm->ram_start;
+
+	/*
+	 * We put MMIO at PPC_MMIO_START, high up.  Make sure that this doesn't
+	 * crash into the end of RAM -- on PPC64 at least, this is so high
+	 * (63TB!) that this is unlikely.
+	 */
+	if (phys_size >= PPC_MMIO_START)
+		die("Too much memory (%lld, what a nice problem): "
+		    "overlaps MMIO!\n",
+		    phys_size);
+
+	kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+}
+
+void kvm__arch_set_cmdline(char *cmdline, bool video)
+{
+	/* We don't need anything unusual in here. */
+}
+
+/* Architecture-specific KVM init */
+void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+{
+	int cap_ppc_rma;
+	unsigned long hpt;
+
+	kvm->ram_size		= ram_size;
+
+	/*
+	 * Currently, HV-mode PPC64 SPAPR requires that we map from hugetlfs.
+	 * Allow a 'default' option to assist.
+	 * PR-mode does not require this.
+	 */
+	if (hugetlbfs_path) {
+		if (!strcmp(hugetlbfs_path, "default"))
+			hugetlbfs_path = HUGETLBFS_PATH;
+		kvm->ram_start = mmap_hugetlbfs(hugetlbfs_path, kvm->ram_size);
+	} else {
+		kvm->ram_start = mmap(0, kvm->ram_size, PROT_READ | PROT_WRITE,
+				      MAP_ANON | MAP_PRIVATE,
+				      -1, 0);
+	}
+	if (kvm->ram_start == MAP_FAILED)
+		die("Couldn't map %lld bytes for RAM (%d)\n",
+		    kvm->ram_size, errno);
+
+	/* FDT goes at top of memory, RTAS just below */
+	kvm->fdt_gra = kvm->ram_size - FDT_MAX_SIZE;
+	/* FIXME: Not all PPC systems have RTAS */
+	kvm->rtas_gra = kvm->fdt_gra - RTAS_MAX_SIZE;
+	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+
+	/* FIXME:  SPAPR-PR specific; allocate a guest HPT. */
+	if (posix_memalign((void **)&hpt, (1<<HPT_ORDER), (1<<HPT_ORDER)))
+		die("Can't allocate %d bytes for HPT\n", (1<<HPT_ORDER));
+
+	kvm->sdr1 = ((hpt + 0x3ffffULL) & ~0x3ffffULL) | (HPT_ORDER-18);
+
+	kvm->pvr = mfpvr();
+
+	/* FIXME: This is book3s-specific */
+	cap_ppc_rma = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_PPC_RMA);
+	if (cap_ppc_rma == 2)
+		die("Need contiguous RMA allocation on this hardware, "
+		    "which is not yet supported.");
+
+	/* Do these before FDT setup, IRQ setup, etc. */
+	/* FIXME: SPAPR-specific */
+	hypercall_init();
+	register_core_rtas();
+	/* Now that hypercalls are initialised, register a couple for the console: */
+	spapr_hvcons_init();
+	spapr_create_phb(kvm, "pci", SPAPR_PCI_BUID,
+			 SPAPR_PCI_MEM_WIN_ADDR,
+			 SPAPR_PCI_MEM_WIN_SIZE,
+			 SPAPR_PCI_IO_WIN_ADDR,
+			 SPAPR_PCI_IO_WIN_SIZE);
+}
+
+void kvm__arch_delete_ram(struct kvm *kvm)
+{
+	munmap(kvm->ram_start, kvm->ram_size);
+}
+
+void kvm__irq_trigger(struct kvm *kvm, int irq)
+{
+	kvm__irq_line(kvm, irq, 1);
+	kvm__irq_line(kvm, irq, 0);
+}
+
+void kvm__arch_periodic_poll(struct kvm *kvm)
+{
+	/* FIXME: Should register callbacks to platform-specific polls */
+	spapr_hvcons_poll(kvm);
+}
+
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline)
+{
+	void *p;
+	void *k_start;
+	void *i_start;
+	int nr;
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR);
+
+	while ((nr = read(fd_kernel, p, 65536)) > 0)
+		p += nr;
+
+	pr_info("Loaded kernel to 0x%x (%ld bytes)", KERNEL_LOAD_ADDR, p-k_start);
+
+	if (fd_initrd != -1) {
+		if (lseek(fd_initrd, 0, SEEK_SET) < 0)
+			die_perror("lseek");
+
+		if (p-k_start > INITRD_LOAD_ADDR)
+			die("Kernel overlaps initrd!");
+
+		/* Round up kernel size to 8byte alignment, and load initrd right after. */
+		i_start = p = guest_flat_to_host(kvm, INITRD_LOAD_ADDR);
+
+		while (((nr = read(fd_initrd, p, 65536)) > 0) &&
+		       p < (kvm->ram_start + kvm->ram_size))
+			p += nr;
+
+		if (p >= (kvm->ram_start + kvm->ram_size))
+			die("initrd too big to contain in guest RAM.\n");
+
+		pr_info("Loaded initrd to 0x%x (%ld bytes)",
+			INITRD_LOAD_ADDR, p-i_start);
+		kvm->initrd_gra = INITRD_LOAD_ADDR;
+		kvm->initrd_size = p-i_start;
+	} else {
+		kvm->initrd_size = 0;
+	}
+	strncpy(kern_cmdline, kernel_cmdline, 2048);
+	kern_cmdline[2047] = '\0';
+
+	return true;
+}
+
+bool load_bzimage(struct kvm *kvm, int fd_kernel,
+		  int fd_initrd, const char *kernel_cmdline, u16 vidmode)
+{
+	/* We don't support bzImages. */
+	return false;
+}
+
+#define SMT_THREADS 4
+
+/*
+ * Set up the FDT for the kernel: This function is currently fairly SPAPR-heavy,
+ * and whilst most PPC targets will require CPU/memory nodes, others like RTAS
+ * should eventually be added separately.
+ */
+static void setup_fdt(struct kvm *kvm)
+{
+	uint64_t 	mem_reg_property[] = { 0, cpu_to_be64(kvm->ram_size) };
+	int 		smp_cpus = kvm->nrcpus;
+	uint32_t	int_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
+	char 		hypertas_prop_kvm[] = "hcall-pft\0hcall-term\0"
+		"hcall-dabr\0hcall-interrupt\0hcall-tce\0hcall-vio\0"
+		"hcall-splpar\0hcall-bulk";
+	int 		i, j;
+	char 		cpu_name[30];
+	u8		staging_fdt[FDT_MAX_SIZE];
+	struct cpu_info *cpu_info = find_cpu_info(kvm->pvr);
+
+	/* Generate an appropriate DT at kvm->fdt_gra */
+	void *fdt_dest = guest_flat_to_host(kvm, kvm->fdt_gra);
+	void *fdt = staging_fdt;
+
+	_FDT(fdt_create(fdt, FDT_MAX_SIZE));
+	_FDT(fdt_finish_reservemap(fdt));
+
+	_FDT(fdt_begin_node(fdt, ""));
+
+	_FDT(fdt_property_string(fdt, "device_type", "chrp"));
+	_FDT(fdt_property_string(fdt, "model", "IBM pSeries (kvmtool)"));
+	_FDT(fdt_property_cell(fdt, "#address-cells", 0x2));
+	_FDT(fdt_property_cell(fdt, "#size-cells", 0x2));
+
+	/* RTAS */
+	_FDT(fdt_begin_node(fdt, "rtas"));
+	/* This is what the kernel uses to switch 'We're an LPAR'! */
+        _FDT(fdt_property(fdt, "ibm,hypertas-functions", hypertas_prop_kvm,
+                           sizeof(hypertas_prop_kvm)));
+	_FDT(fdt_property_cell(fdt, "linux,rtas-base", kvm->rtas_gra));
+	_FDT(fdt_property_cell(fdt, "linux,rtas-entry", kvm->rtas_gra));
+	_FDT(fdt_property_cell(fdt, "rtas-size", kvm->rtas_size));
+	/* Now add properties for all RTAS tokens: */
+	if (spapr_rtas_fdt_setup(kvm, fdt))
+		die("Couldn't create RTAS FDT properties\n");
+
+	_FDT(fdt_end_node(fdt));
+
+	/* /chosen */
+	_FDT(fdt_begin_node(fdt, "chosen"));
+	/* cmdline */
+	_FDT(fdt_property_string(fdt, "bootargs", kern_cmdline));
+	/* Initrd */
+	if (kvm->initrd_size != 0) {
+		uint32_t ird_st_prop = cpu_to_be32(kvm->initrd_gra);
+		uint32_t ird_end_prop = cpu_to_be32(kvm->initrd_gra +
+						    kvm->initrd_size);
+		_FDT(fdt_property(fdt, "linux,initrd-start",
+				   &ird_st_prop, sizeof(ird_st_prop)));
+		_FDT(fdt_property(fdt, "linux,initrd-end",
+				   &ird_end_prop, sizeof(ird_end_prop)));
+	}
+
+	/*
+	 * stdout-path: This is assuming we're using the HV console.  Also, the
+	 * address is hardwired until we do a VIO bus.
+	 */
+	_FDT(fdt_property_string(fdt, "linux,stdout-path",
+				 "/vdevice/vty@30000000"));
+	_FDT(fdt_end_node(fdt));
+
+	/*
+	 * Memory: We don't alloc. a separate RMA yet.  If we ever need to
+	 * (CAP_PPC_RMA == 2) then have one memory node for 0->RMAsize, and
+	 * another RMAsize->endOfMem.
+	 */
+	_FDT(fdt_begin_node(fdt, "memory@0"));
+	_FDT(fdt_property_string(fdt, "device_type", "memory"));
+	_FDT(fdt_property(fdt, "reg", mem_reg_property,
+			  sizeof(mem_reg_property)));
+	_FDT(fdt_end_node(fdt));
+
+	/* CPUs */
+	_FDT(fdt_begin_node(fdt, "cpus"));
+	_FDT(fdt_property_cell(fdt, "#address-cells", 0x1));
+	_FDT(fdt_property_cell(fdt, "#size-cells", 0x0));
+
+	for (i = 0; i < smp_cpus; i += SMT_THREADS) {
+		int32_t pft_size_prop[] = { 0, HPT_ORDER };
+		uint32_t servers_prop[SMT_THREADS];
+		uint32_t gservers_prop[SMT_THREADS * 2];
+		int threads = (smp_cpus - i) >= SMT_THREADS ? SMT_THREADS :
+			smp_cpus - i;
+
+		sprintf(cpu_name, "PowerPC,%s@%d", cpu_info->name, i);
+		_FDT(fdt_begin_node(fdt, cpu_name));
+		sprintf(cpu_name, "PowerPC,%s", cpu_info->name);
+		_FDT(fdt_property_string(fdt, "name", cpu_name));
+		_FDT(fdt_property_string(fdt, "device_type", "cpu"));
+
+		_FDT(fdt_property_cell(fdt, "reg", i));
+		_FDT(fdt_property_cell(fdt, "cpu-version", kvm->pvr));
+
+		_FDT(fdt_property_cell(fdt, "dcache-block-size", cpu_info->d_bsize));
+		_FDT(fdt_property_cell(fdt, "icache-block-size", cpu_info->i_bsize));
+
+		_FDT(fdt_property_cell(fdt, "timebase-frequency", cpu_info->tb_freq));
+		/* Lies, but safeish lies! */
+		_FDT(fdt_property_cell(fdt, "clock-frequency", 0xddbab200));
+
+		if (cpu_info->slb_size)
+			_FDT(fdt_property_cell(fdt, "ibm,slb-size", cpu_info->slb_size));
+		/*
+		 * HPT size is hardwired; KVM currently fixes it at 16MB but the
+		 * moment that changes we'll need to read it out of the kernel.
+		 */
+		_FDT(fdt_property(fdt, "ibm,pft-size", pft_size_prop,
+				  sizeof(pft_size_prop)));
+
+		_FDT(fdt_property_string(fdt, "status", "okay"));
+		_FDT(fdt_property(fdt, "64-bit", NULL, 0));
+		/* A server for each thread in this core */
+		for (j = 0; j < SMT_THREADS; j++) {
+			servers_prop[j] = cpu_to_be32(i+j);
+			/*
+			 * Hack borrowed from QEMU, direct the group queues back
+			 * to cpu 0:
+			 */
+			gservers_prop[j*2] = cpu_to_be32(i+j);
+			gservers_prop[j*2 + 1] = 0;
+		}
+		_FDT(fdt_property(fdt, "ibm,ppc-interrupt-server#s",
+				   servers_prop, threads * sizeof(uint32_t)));
+		_FDT(fdt_property(fdt, "ibm,ppc-interrupt-gserver#s",
+				  gservers_prop,
+				  threads * 2 * sizeof(uint32_t)));
+		if (cpu_info->page_sizes_prop)
+			_FDT(fdt_property(fdt, "ibm,segment-page-sizes",
+					  cpu_info->page_sizes_prop,
+					  cpu_info->page_sizes_prop_len));
+		if (cpu_info->segment_sizes_prop)
+			_FDT(fdt_property(fdt, "ibm,processor-segment-sizes",
+					  cpu_info->segment_sizes_prop,
+					  cpu_info->segment_sizes_prop_len));
+		/* VSX / DFP options: */
+		if (cpu_info->flags & CPUINFO_FLAG_VMX)
+			_FDT(fdt_property_cell(fdt, "ibm,vmx",
+					       (cpu_info->flags &
+						CPUINFO_FLAG_VSX) ? 2 : 1));
+		if (cpu_info->flags & CPUINFO_FLAG_DFP)
+			_FDT(fdt_property_cell(fdt, "ibm,dfp", 0x1));
+		_FDT(fdt_end_node(fdt));
+	}
+	_FDT(fdt_end_node(fdt));
+
+	/* IRQ controller */
+	_FDT(fdt_begin_node(fdt, "interrupt-controller@0"));
+
+	_FDT(fdt_property_string(fdt, "device_type",
+				 "PowerPC-External-Interrupt-Presentation"));
+	_FDT(fdt_property_string(fdt, "compatible", "IBM,ppc-xicp"));
+	_FDT(fdt_property_cell(fdt, "reg", 0));
+	_FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
+	_FDT(fdt_property(fdt, "ibm,interrupt-server-ranges",
+			   int_server_ranges_prop,
+			   sizeof(int_server_ranges_prop)));
+	_FDT(fdt_property_cell(fdt, "#interrupt-cells", 2));
+	_FDT(fdt_property_cell(fdt, "linux,phandle", PHANDLE_XICP));
+	_FDT(fdt_property_cell(fdt, "phandle", PHANDLE_XICP));
+	_FDT(fdt_end_node(fdt));
+
+	/*
+	 * VIO: See comment in linux,stdout-path; we don't yet represent a VIO
+	 * bus/address allocation so addresses are hardwired here.
+	 */
+	_FDT(fdt_begin_node(fdt, "vdevice"));
+	_FDT(fdt_property_cell(fdt, "#address-cells", 0x1));
+	_FDT(fdt_property_cell(fdt, "#size-cells", 0x0));
+	_FDT(fdt_property_string(fdt, "device_type", "vdevice"));
+	_FDT(fdt_property_string(fdt, "compatible", "IBM,vdevice"));
+	_FDT(fdt_begin_node(fdt, "vty@30000000"));
+	_FDT(fdt_property_string(fdt, "name", "vty"));
+	_FDT(fdt_property_string(fdt, "device_type", "serial"));
+	_FDT(fdt_property_string(fdt, "compatible", "hvterm1"));
+	_FDT(fdt_property_cell(fdt, "reg", 0x30000000));
+	_FDT(fdt_end_node(fdt));
+	_FDT(fdt_end_node(fdt));
+
+	/* Finalise: */
+	_FDT(fdt_end_node(fdt)); /* Root node */
+	_FDT(fdt_finish(fdt));
+
+	_FDT(fdt_open_into(fdt, fdt_dest, FDT_MAX_SIZE));
+
+	/* PCI */
+	if (spapr_populate_pci_devices(kvm, PHANDLE_XICP, fdt_dest))
+		die("Fail populating PCI device nodes");
+
+	_FDT(fdt_add_mem_rsv(fdt_dest, kvm->rtas_gra, kvm->rtas_size));
+	_FDT(fdt_pack(fdt_dest));
+}
+
+/**
+ * kvm__arch_setup_firmware
+ */
+int kvm__arch_setup_firmware(struct kvm *kvm)
+{
+	/*
+	 * Set up RTAS stub.  All it is is a single hypercall:
+	 *  0:   7c 64 1b 78     mr      r4,r3
+	 *  4:   3c 60 00 00     lis     r3,0
+	 *  8:   60 63 f0 00     ori     r3,r3,61440
+	 *  c:   44 00 00 22     sc      1
+	 * 10:   4e 80 00 20     blr
+	 */
+	uint32_t *rtas = guest_flat_to_host(kvm, kvm->rtas_gra);
+
+	rtas[0] = 0x7c641b78;
+	rtas[1] = 0x3c600000;
+	rtas[2] = 0x6063f000;
+	rtas[3] = 0x44000022;
+	rtas[4] = 0x4e800020;
+	kvm->rtas_size = 20;
+
+	pr_info("Set up %ld bytes of RTAS at 0x%lx\n",
+		kvm->rtas_size, kvm->rtas_gra);
+
+	/* Load SLOF */
+
+	/* Init FDT */
+	setup_fdt(kvm);
+
+	return 0;
+}
+
+int kvm__arch_free_firmware(struct kvm *kvm)
+{
+	return 0;
+}
diff --git a/tools/kvm/powerpc/spapr.h b/tools/kvm/powerpc/spapr.h
new file mode 100644
index 0000000..0537f88
--- /dev/null
+++ b/tools/kvm/powerpc/spapr.h
@@ -0,0 +1,93 @@
+/*
+ * SPAPR definitions and declarations
+ *
+ * Borrowed heavily from QEMU's spapr.h,
+ * Copyright (c) 2010 David Gibson, IBM Corporation.
+ *
+ * Modifications by Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#if !defined(__HW_SPAPR_H__)
+#define __HW_SPAPR_H__
+
+#include <inttypes.h>
+
+/* We need some of the H_ hcall defs, but they're __KERNEL__ only. */
+#define __KERNEL__
+#include <asm/hvcall.h>
+#undef __KERNEL__
+
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+
+typedef unsigned long target_ulong;
+typedef uintptr_t target_phys_addr_t;
+
+/*
+ * The hcalls above are standardized in PAPR and implemented by pHyp
+ * as well.
+ *
+ * We also need some hcalls which are specific to qemu / KVM-on-POWER.
+ * So far we just need one for H_RTAS, but in future we'll need more
+ * for extensions like virtio.  We put those into the 0xf000-0xfffc
+ * range which is reserved by PAPR for "platform-specific" hcalls.
+ */
+#define KVMPPC_HCALL_BASE       0xf000
+#define KVMPPC_H_RTAS           (KVMPPC_HCALL_BASE + 0x0)
+#define KVMPPC_HCALL_MAX        KVMPPC_H_RTAS
+
+#define DEBUG_SPAPR_HCALLS
+
+#ifdef DEBUG_SPAPR_HCALLS
+#define hcall_dprintf(fmt, ...) \
+    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define hcall_dprintf(fmt, ...) \
+    do { } while (0)
+#endif
+
+typedef target_ulong (*spapr_hcall_fn)(struct kvm_cpu *vcpu,
+				       target_ulong opcode,
+                                       target_ulong *args);
+
+void hypercall_init(void);
+void register_core_rtas(void);
+
+void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
+target_ulong spapr_hypercall(struct kvm_cpu *vcpu, target_ulong opcode,
+                             target_ulong *args);
+
+int spapr_rtas_fdt_setup(struct kvm *kvm, void *fdt);
+
+static inline uint32_t rtas_ld(struct kvm *kvm, target_ulong phys, int n)
+{
+	return *((uint32_t *)guest_flat_to_host(kvm, phys + 4*n));
+}
+
+static inline void rtas_st(struct kvm *kvm, target_ulong phys, int n, uint32_t val)
+{
+	*((uint32_t *)guest_flat_to_host(kvm, phys + 4*n)) = val;
+}
+
+typedef void (*spapr_rtas_fn)(struct kvm_cpu *vcpu, uint32_t token,
+                              uint32_t nargs, target_ulong args,
+                              uint32_t nret, target_ulong rets);
+void spapr_rtas_register(const char *name, spapr_rtas_fn fn);
+target_ulong spapr_rtas_call(struct kvm_cpu *vcpu,
+                             uint32_t token, uint32_t nargs, target_ulong args,
+                             uint32_t nret, target_ulong rets);
+
+#define SPAPR_PCI_BUID          0x800000020000001ULL
+#define SPAPR_PCI_MEM_WIN_ADDR  (KVM_MMIO_START + 0xA0000000)
+#define SPAPR_PCI_MEM_WIN_SIZE  0x20000000
+#define SPAPR_PCI_IO_WIN_ADDR   (SPAPR_PCI_MEM_WIN_ADDR + SPAPR_PCI_MEM_WIN_SIZE)
+#define SPAPR_PCI_IO_WIN_SIZE	0x2000000
+
+#define SPAPR_PCI_WIN_START	SPAPR_PCI_MEM_WIN_ADDR
+#define SPAPR_PCI_WIN_END	(SPAPR_PCI_IO_WIN_ADDR + SPAPR_PCI_IO_WIN_SIZE)
+
+#endif /* !defined (__HW_SPAPR_H__) */
diff --git a/tools/kvm/powerpc/spapr_hcall.c b/tools/kvm/powerpc/spapr_hcall.c
new file mode 100644
index 0000000..ff1d63a
--- /dev/null
+++ b/tools/kvm/powerpc/spapr_hcall.c
@@ -0,0 +1,134 @@
+/*
+ * SPAPR hypercalls
+ *
+ * Borrowed heavily from QEMU's spapr_hcall.c,
+ * Copyright (c) 2010 David Gibson, IBM Corporation.
+ *
+ * Copyright (c) 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "spapr.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
+static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX -
+					     KVMPPC_HCALL_BASE + 1];
+
+static target_ulong h_set_dabr(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args)
+{
+	/* FIXME:  Implement this for -PR.  (-HV does this in kernel.) */
+	return H_HARDWARE;
+}
+
+static target_ulong h_rtas(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args)
+{
+	target_ulong rtas_r3 = args[0];
+	/*
+	 * Pointer read from phys mem; these ptrs cannot be MMIO (!) so just
+	 * reference guest RAM directly.
+	 */
+	uint32_t token, nargs, nret;
+
+	token = rtas_ld(vcpu->kvm, rtas_r3, 0);
+	nargs = rtas_ld(vcpu->kvm, rtas_r3, 1);
+	nret  = rtas_ld(vcpu->kvm, rtas_r3, 2);
+
+	return spapr_rtas_call(vcpu, token, nargs, rtas_r3 + 12,
+			       nret, rtas_r3 + 12 + 4*nargs);
+}
+
+static target_ulong h_logical_load(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args)
+{
+	/* SLOF will require these, though kernel doesn't. */
+	die(__PRETTY_FUNCTION__);
+	return H_PARAMETER;
+}
+
+static target_ulong h_logical_store(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args)
+{
+	/* SLOF will require these, though kernel doesn't. */
+	die(__PRETTY_FUNCTION__);
+	return H_PARAMETER;
+}
+
+static target_ulong h_logical_icbi(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args)
+{
+	/* KVM will trap this in the kernel.  Die if it misses. */
+	die(__PRETTY_FUNCTION__);
+	return H_SUCCESS;
+}
+
+static target_ulong h_logical_dcbf(struct kvm_cpu *vcpu, target_ulong opcode, target_ulong *args)
+{
+	/* KVM will trap this in the kernel.  Die if it misses. */
+	die(__PRETTY_FUNCTION__);
+	return H_SUCCESS;
+}
+
+void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
+{
+	spapr_hcall_fn *slot;
+
+	if (opcode <= MAX_HCALL_OPCODE) {
+		assert((opcode & 0x3) == 0);
+
+		slot = &papr_hypercall_table[opcode / 4];
+	} else {
+		assert((opcode >= KVMPPC_HCALL_BASE) &&
+		       (opcode <= KVMPPC_HCALL_MAX));
+
+		slot = &kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE];
+	}
+
+	assert(!(*slot) || (fn == *slot));
+	*slot = fn;
+}
+
+target_ulong spapr_hypercall(struct kvm_cpu *vcpu, target_ulong opcode,
+			     target_ulong *args)
+{
+	if ((opcode <= MAX_HCALL_OPCODE)
+	    && ((opcode & 0x3) == 0)) {
+		spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];
+
+		if (fn) {
+			return fn(vcpu, opcode, args);
+		}
+	} else if ((opcode >= KVMPPC_HCALL_BASE) &&
+		   (opcode <= KVMPPC_HCALL_MAX)) {
+		spapr_hcall_fn fn = kvmppc_hypercall_table[opcode -
+							   KVMPPC_HCALL_BASE];
+
+		if (fn) {
+			return fn(vcpu, opcode, args);
+		}
+	}
+
+	hcall_dprintf("Unimplemented hcall 0x%lx\n", opcode);
+	return H_FUNCTION;
+}
+
+void hypercall_init(void)
+{
+	/* hcall-dabr */
+	spapr_register_hypercall(H_SET_DABR, h_set_dabr);
+
+	spapr_register_hypercall(H_LOGICAL_CI_LOAD, h_logical_load);
+	spapr_register_hypercall(H_LOGICAL_CI_STORE, h_logical_store);
+	spapr_register_hypercall(H_LOGICAL_CACHE_LOAD, h_logical_load);
+	spapr_register_hypercall(H_LOGICAL_CACHE_STORE, h_logical_store);
+	spapr_register_hypercall(H_LOGICAL_ICBI, h_logical_icbi);
+	spapr_register_hypercall(H_LOGICAL_DCBF, h_logical_dcbf);
+
+	/* KVM-PPC specific hcalls */
+	spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
+}
diff --git a/tools/kvm/powerpc/spapr_hvcons.c b/tools/kvm/powerpc/spapr_hvcons.c
new file mode 100644
index 0000000..511dbe1
--- /dev/null
+++ b/tools/kvm/powerpc/spapr_hvcons.c
@@ -0,0 +1,102 @@
+/*
+ * SPAPR HV console
+ *
+ * Borrowed lightly from QEMU's spapr_vty.c, Copyright (c) 2010 David Gibson,
+ * IBM Corporation.
+ *
+ * Copyright (c) 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "kvm/term.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+#include "spapr.h"
+#include "spapr_hvcons.h"
+
+#include <stdio.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <linux/byteorder.h>
+
+union hv_chario {
+	struct {
+		uint64_t char0_7;
+		uint64_t char8_15;
+	} a;
+	uint8_t buf[16];
+};
+
+static unsigned long h_put_term_char(struct kvm_cpu *vcpu, unsigned long opcode, unsigned long *args)
+{
+	/* To do: Read register from args[0], and check it. */
+	unsigned long len = args[1];
+	union hv_chario data;
+	struct iovec iov;
+
+	if (len > 16) {
+		return H_PARAMETER;
+	}
+	data.a.char0_7 = cpu_to_be64(args[2]);
+	data.a.char8_15 = cpu_to_be64(args[3]);
+
+	iov.iov_base = data.buf;
+	iov.iov_len = len;
+	do {
+		int ret;
+
+		ret = term_putc_iov(CONSOLE_HV, &iov, 1, 0);
+		if (ret < 0) {
+			die("term_putc_iov error %d!\n", errno);
+		}
+		iov.iov_base += ret;
+		iov.iov_len -= ret;
+	} while (iov.iov_len > 0);
+
+	return H_SUCCESS;
+}
+
+
+static unsigned long h_get_term_char(struct kvm_cpu *vcpu, unsigned long opcode, unsigned long *args)
+{
+	/* To do: Read register from args[0], and check it. */
+	unsigned long *len = args + 0;
+	unsigned long *char0_7 = args + 1;
+	unsigned long *char8_15 = args + 2;
+	union hv_chario data;
+	struct iovec iov;
+
+	if (term_readable(CONSOLE_HV, 0)) {
+		iov.iov_base = data.buf;
+		iov.iov_len = 16;
+
+		*len = term_getc_iov(CONSOLE_HV, &iov, 1, 0);
+		*char0_7 = be64_to_cpu(data.a.char0_7);
+		*char8_15 = be64_to_cpu(data.a.char8_15);
+	} else {
+		*len = 0;
+	}
+
+	return H_SUCCESS;
+}
+
+void spapr_hvcons_poll(struct kvm *kvm)
+{
+	if (term_readable(CONSOLE_HV, 0)) {
+		/*
+		 * We can inject an IRQ to guest here if we want.  The guest
+		 * will happily poll, though, so not required.
+		 */
+	}
+}
+
+void spapr_hvcons_init(void)
+{
+	spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
+	spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
+}
diff --git a/tools/kvm/powerpc/spapr_hvcons.h b/tools/kvm/powerpc/spapr_hvcons.h
new file mode 100644
index 0000000..d3e4414
--- /dev/null
+++ b/tools/kvm/powerpc/spapr_hvcons.h
@@ -0,0 +1,19 @@
+/*
+ * SPAPR HV console
+ *
+ * Copyright (c) 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef spapr_hvcons_H
+#define spapr_hvcons_H
+
+#include "kvm/kvm.h"
+
+void spapr_hvcons_init(void);
+void spapr_hvcons_poll(struct kvm *kvm);
+
+#endif
diff --git a/tools/kvm/powerpc/spapr_pci.c b/tools/kvm/powerpc/spapr_pci.c
new file mode 100644
index 0000000..f9d29f0
--- /dev/null
+++ b/tools/kvm/powerpc/spapr_pci.c
@@ -0,0 +1,423 @@
+/*
+ * SPAPR PHB emulation, RTAS interface to PCI config space, device tree nodes
+ * for enumerated devices.
+ *
+ * Borrowed heavily from QEMU's spapr_pci.c,
+ * Copyright (c) 2011 Alexey Kardashevskiy, IBM Corporation.
+ * Copyright (c) 2011 David Gibson, IBM Corporation.
+ *
+ * Modifications copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "spapr.h"
+#include "spapr_pci.h"
+#include "kvm/util.h"
+#include "kvm/pci.h"
+#include "libfdt.h"
+
+#include <linux/pci_regs.h>
+#include <linux/byteorder.h>
+
+
+/* #define DEBUG_PHB yes */
+#ifdef DEBUG_PHB
+#define phb_dprintf(fmt, ...)					\
+	do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define phb_dprintf(fmt, ...)			\
+	do { } while (0)
+#endif
+
+static const uint32_t bars[] = {
+	PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1,
+	PCI_BASE_ADDRESS_2, PCI_BASE_ADDRESS_3,
+	PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5
+	/*, PCI_ROM_ADDRESS*/
+};
+
+#define PCI_NUM_REGIONS		7
+
+/* Macros to operate with address in OF binding to PCI */
+#define b_x(x, p, l)	(((x) & ((1<<(l))-1)) << (p))
+#define b_n(x)		b_x((x), 31, 1) /* 0 if relocatable */
+#define b_p(x)		b_x((x), 30, 1) /* 1 if prefetchable */
+#define b_t(x)		b_x((x), 29, 1) /* 1 if the address is aliased */
+#define b_ss(x)		b_x((x), 24, 2) /* the space code */
+#define b_bbbbbbbb(x)	b_x((x), 16, 8) /* bus number */
+#define b_ddddd(x)	b_x((x), 11, 5) /* device number */
+#define b_fff(x)	b_x((x), 8, 3)	/* function number */
+#define b_rrrrrrrr(x)	b_x((x), 0, 8)	/* register number */
+
+#define SS_M64		3
+#define SS_M32		2
+#define SS_IO		1
+#define SS_CONFIG	0
+
+
+static struct spapr_phb phb;
+
+
+static void rtas_ibm_read_pci_config(struct kvm_cpu *vcpu,
+				     uint32_t token, uint32_t nargs,
+				     target_ulong args,
+				     uint32_t nret, target_ulong rets)
+{
+	uint32_t val = 0;
+	uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2);
+	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
+	struct pci_device_header *dev = pci__find_dev(addr.device_number);
+	uint32_t size = rtas_ld(vcpu->kvm, args, 3);
+
+	if (buid != phb.buid || !dev || (size > 4)) {
+		phb_dprintf("- cfgRd buid 0x%lx cfg addr 0x%x size %d not found\n",
+			    buid, addr.w, size);
+
+		rtas_st(vcpu->kvm, rets, 0, -1);
+		return;
+	}
+	pci__config_rd(vcpu->kvm, addr, &val, size);
+	/* It appears this wants a byteswapped result... */
+	switch (size) {
+	case 4:
+		val = le32_to_cpu(val);
+		break;
+	case 2:
+		val = le16_to_cpu(val>>16);
+		break;
+	case 1:
+		val = val >> 24;
+		break;
+	}
+	phb_dprintf("- cfgRd buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
+		    buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
+		    addr.register_number, val);
+
+	rtas_st(vcpu->kvm, rets, 0, 0);
+	rtas_st(vcpu->kvm, rets, 1, val);
+}
+
+static void rtas_read_pci_config(struct kvm_cpu *vcpu,
+				 uint32_t token, uint32_t nargs,
+				 target_ulong args,
+				 uint32_t nret, target_ulong rets)
+{
+	uint32_t val;
+	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
+	struct pci_device_header *dev = pci__find_dev(addr.device_number);
+	uint32_t size = rtas_ld(vcpu->kvm, args, 1);
+
+	if (!dev || (size > 4)) {
+		rtas_st(vcpu->kvm, rets, 0, -1);
+		return;
+	}
+	pci__config_rd(vcpu->kvm, addr, &val, size);
+	switch (size) {
+	case 4:
+		val = le32_to_cpu(val);
+		break;
+	case 2:
+		val = le16_to_cpu(val>>16); /* We're yuck-endian. */
+		break;
+	case 1:
+		val = val >> 24;
+		break;
+	}
+	phb_dprintf("- cfgRd addr 0x%x size %d, val 0x%x\n", addr.w, size, val);
+	rtas_st(vcpu->kvm, rets, 0, 0);
+	rtas_st(vcpu->kvm, rets, 1, val);
+}
+
+static void rtas_ibm_write_pci_config(struct kvm_cpu *vcpu,
+				      uint32_t token, uint32_t nargs,
+				      target_ulong args,
+				      uint32_t nret, target_ulong rets)
+{
+	uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2);
+	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
+	struct pci_device_header *dev = pci__find_dev(addr.device_number);
+	uint32_t size = rtas_ld(vcpu->kvm, args, 3);
+	uint32_t val = rtas_ld(vcpu->kvm, args, 4);
+
+	if (buid != phb.buid || !dev || (size > 4)) {
+		phb_dprintf("- cfgWr buid 0x%lx cfg addr 0x%x/%d error (val 0x%x)\n",
+			    buid, addr.w, size, val);
+
+		rtas_st(vcpu->kvm, rets, 0, -1);
+		return;
+	}
+	phb_dprintf("- cfgWr buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
+		    buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
+		    addr.register_number, val);
+	switch (size) {
+	case 4:
+		val = le32_to_cpu(val);
+		break;
+	case 2:
+		val = le16_to_cpu(val) << 16;
+		break;
+	case 1:
+		val = val >> 24;
+		break;
+	}
+	pci__config_wr(vcpu->kvm, addr, &val, size);
+	rtas_st(vcpu->kvm, rets, 0, 0);
+}
+
+static void rtas_write_pci_config(struct kvm_cpu *vcpu,
+				  uint32_t token, uint32_t nargs,
+				  target_ulong args,
+				  uint32_t nret, target_ulong rets)
+{
+	union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
+	struct pci_device_header *dev = pci__find_dev(addr.device_number);
+	uint32_t size = rtas_ld(vcpu->kvm, args, 1);
+	uint32_t val = rtas_ld(vcpu->kvm, args, 2);
+
+	if (!dev || (size > 4)) {
+		rtas_st(vcpu->kvm, rets, 0, -1);
+		return;
+	}
+
+	phb_dprintf("- cfgWr addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
+		    addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
+		    addr.register_number, val);
+	switch (size) {
+	case 4:
+		val = le32_to_cpu(val);
+		break;
+	case 2:
+		val = le16_to_cpu(val) << 16;
+		break;
+	case 1:
+		val = val >> 24;
+		break;
+	}
+	pci__config_wr(vcpu->kvm, addr, &val, size);
+	rtas_st(vcpu->kvm, rets, 0, 0);
+}
+
+void spapr_create_phb(struct kvm *kvm,
+		      const char *busname, uint64_t buid,
+		      uint64_t mem_win_addr, uint64_t mem_win_size,
+		      uint64_t io_win_addr, uint64_t io_win_size)
+{
+	/*
+	 * Since kvmtool doesn't really have any concept of buses etc.,
+	 * there's nothing to register here.  Just register RTAS.
+	 */
+	spapr_rtas_register("read-pci-config", rtas_read_pci_config);
+	spapr_rtas_register("write-pci-config", rtas_write_pci_config);
+	spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config);
+	spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config);
+
+	phb.buid = buid;
+	phb.mem_addr = mem_win_addr;
+	phb.mem_size = mem_win_size;
+	phb.io_addr  = io_win_addr;
+	phb.io_size  = io_win_size;
+
+	kvm->phb = &phb;
+}
+
+static uint32_t bar_to_ss(unsigned long bar)
+{
+	if ((bar & PCI_BASE_ADDRESS_SPACE) ==
+	    PCI_BASE_ADDRESS_SPACE_IO)
+		return SS_IO;
+	else if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64)
+		return SS_M64;
+	else
+		return SS_M32;
+}
+
+static unsigned long bar_to_addr(unsigned long bar)
+{
+	if ((bar & PCI_BASE_ADDRESS_SPACE) ==
+	    PCI_BASE_ADDRESS_SPACE_IO)
+		return bar & PCI_BASE_ADDRESS_IO_MASK;
+	else
+		return bar & PCI_BASE_ADDRESS_MEM_MASK;
+}
+
+int spapr_populate_pci_devices(struct kvm *kvm,
+			       uint32_t xics_phandle,
+			       void *fdt)
+{
+	int bus_off, node_off = 0, devid, fn, i, n, devices;
+	char nodename[256];
+	struct {
+		uint32_t hi;
+		uint64_t addr;
+		uint64_t size;
+	} __attribute__((packed)) reg[PCI_NUM_REGIONS + 1],
+		  assigned_addresses[PCI_NUM_REGIONS];
+	uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
+	struct {
+		uint32_t hi;
+		uint64_t child;
+		uint64_t parent;
+		uint64_t size;
+	} __attribute__((packed)) ranges[] = {
+		{
+			cpu_to_be32(b_ss(1)), cpu_to_be64(0),
+			cpu_to_be64(phb.io_addr),
+			cpu_to_be64(phb.io_size),
+		},
+		{
+			cpu_to_be32(b_ss(2)), cpu_to_be64(0),
+			cpu_to_be64(phb.mem_addr),
+			cpu_to_be64(phb.mem_size),
+		},
+	};
+	uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 };
+	uint32_t interrupt_map_mask[] = {
+		cpu_to_be32(b_ddddd(-1)|b_fff(-1)), 0x0, 0x0, 0x0};
+	uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7];
+
+	/* Start populating the FDT */
+	sprintf(nodename, "pci@%" PRIx64, phb.buid);
+	bus_off = fdt_add_subnode(fdt, 0, nodename);
+	if (bus_off < 0) {
+		die("error making bus subnode, %s\n", fdt_strerror(bus_off));
+		return bus_off;
+	}
+
+	/* Write PHB properties */
+	_FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci"));
+	_FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB"));
+	_FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3));
+	_FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2));
+	_FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));
+	_FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));
+	_FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));
+	_FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges)));
+	_FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
+	_FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask",
+			 &interrupt_map_mask, sizeof(interrupt_map_mask)));
+
+	/* Populate PCI devices and allocate IRQs */
+	devices = 0;
+
+	for (devid = 0; devid < PCI_MAX_DEVICES; devid++) {
+		uint32_t *irqmap = interrupt_map[devices];
+		struct pci_device_header *hdr = pci__find_dev(devid);
+
+		if (!hdr)
+			continue;
+
+		fn = 0; /* kvmtool doesn't yet do multifunction devices */
+
+		sprintf(nodename, "pci@%u,%u", devid, fn);
+
+		/* Allocate interrupt from the map */
+		if (devid > SPAPR_PCI_NUM_LSI)	{
+			die("Unexpected behaviour in spapr_populate_pci_devices,"
+			    "wrong devid %u\n", devid);
+		}
+		irqmap[0] = cpu_to_be32(b_ddddd(devid)|b_fff(fn));
+		irqmap[1] = 0;
+		irqmap[2] = 0;
+		irqmap[3] = 0;
+		irqmap[4] = cpu_to_be32(xics_phandle);
+		/*
+		 * This is nasty; the PCI devs are set up such that their own
+		 * header's irq_line indicates the direct XICS IRQ number to
+		 * use.  There REALLY needs to be a hierarchical system in place
+		 * to 'raise' an IRQ on the bridge which indexes/looks up which
+		 * XICS IRQ to fire.
+		 */
+		irqmap[5] = cpu_to_be32(hdr->irq_line);
+		irqmap[6] = cpu_to_be32(0x8);
+
+		/* Add node to FDT */
+		node_off = fdt_add_subnode(fdt, bus_off, nodename);
+		if (node_off < 0) {
+			die("error making node subnode, %s\n", fdt_strerror(bus_off));
+			return node_off;
+		}
+
+		_FDT(fdt_setprop_cell(fdt, node_off, "vendor-id",
+				      le16_to_cpu(hdr->vendor_id)));
+		_FDT(fdt_setprop_cell(fdt, node_off, "device-id",
+				      le16_to_cpu(hdr->device_id)));
+		_FDT(fdt_setprop_cell(fdt, node_off, "revision-id",
+				      hdr->revision_id));
+		_FDT(fdt_setprop_cell(fdt, node_off, "class-code",
+				      hdr->class[0] | (hdr->class[1] << 8) | (hdr->class[2] << 16)));
+		_FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id",
+				      le16_to_cpu(hdr->subsys_id)));
+		_FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id",
+				      le16_to_cpu(hdr->subsys_vendor_id)));
+
+		/* Config space region comes first */
+		reg[0].hi = cpu_to_be32(
+			b_n(0) |
+			b_p(0) |
+			b_t(0) |
+			b_ss(SS_CONFIG) |
+			b_bbbbbbbb(0) |
+			b_ddddd(devid) |
+			b_fff(fn));
+		reg[0].addr = 0;
+		reg[0].size = 0;
+
+		n = 0;
+		/* Six BARs, no ROM supported, addresses are 32bit */
+		for (i = 0; i < 6; ++i) {
+			if (0 == hdr->bar[i]) {
+				continue;
+			}
+
+			reg[n+1].hi = cpu_to_be32(
+				b_n(0) |
+				b_p(0) |
+				b_t(0) |
+				b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
+				b_bbbbbbbb(0) |
+				b_ddddd(devid) |
+				b_fff(fn) |
+				b_rrrrrrrr(bars[i]));
+			reg[n+1].addr = 0;
+			reg[n+1].size = cpu_to_be64(hdr->bar_size[i]);
+
+			assigned_addresses[n].hi = cpu_to_be32(
+				b_n(1) |
+				b_p(0) |
+				b_t(0) |
+				b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
+				b_bbbbbbbb(0) |
+				b_ddddd(devid) |
+				b_fff(fn) |
+				b_rrrrrrrr(bars[i]));
+
+			/*
+			 * Writing zeroes to assigned_addresses causes the guest kernel to
+			 * reassign BARs
+			 */
+			assigned_addresses[n].addr = cpu_to_be64(bar_to_addr(le32_to_cpu(hdr->bar[i])));
+			assigned_addresses[n].size = reg[n+1].size;
+
+			++n;
+		}
+		_FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1)));
+		_FDT(fdt_setprop(fdt, node_off, "assigned-addresses",
+				 assigned_addresses,
+				 sizeof(assigned_addresses[0])*(n)));
+		_FDT(fdt_setprop_cell(fdt, node_off, "interrupts",
+				      hdr->irq_pin));
+
+		/* We don't set ibm,dma-window property as we don't have an IOMMU. */
+
+		++devices;
+	}
+
+	/* Write interrupt map */
+	_FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
+			 devices * sizeof(interrupt_map[0])));
+
+	return 0;
+}
diff --git a/tools/kvm/powerpc/spapr_pci.h b/tools/kvm/powerpc/spapr_pci.h
new file mode 100644
index 0000000..48b221c
--- /dev/null
+++ b/tools/kvm/powerpc/spapr_pci.h
@@ -0,0 +1,57 @@
+/*
+ * SPAPR PHB definitions
+ *
+ * Modifications by Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef SPAPR_PCI_H
+#define SPAPR_PCI_H
+
+#include "kvm/kvm.h"
+#include "spapr.h"
+#include <inttypes.h>
+
+/* With XICS, we can easily accomodate 1 IRQ per PCI device. */
+
+#define SPAPR_PCI_NUM_LSI 256
+
+struct spapr_phb {
+	uint64_t buid;
+	uint64_t mem_addr;
+	uint64_t mem_size;
+	uint64_t io_addr;
+	uint64_t io_size;
+};
+
+void spapr_create_phb(struct kvm *kvm,
+                      const char *busname, uint64_t buid,
+                      uint64_t mem_win_addr, uint64_t mem_win_size,
+                      uint64_t io_win_addr, uint64_t io_win_size);
+
+int spapr_populate_pci_devices(struct kvm *kvm,
+                               uint32_t xics_phandle,
+                               void *fdt);
+
+static inline bool spapr_phb_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+{
+	if ((phys_addr >= SPAPR_PCI_IO_WIN_ADDR) &&
+	    (phys_addr < SPAPR_PCI_IO_WIN_ADDR +
+	     SPAPR_PCI_IO_WIN_SIZE)) {
+		return kvm__emulate_io(kvm, phys_addr - SPAPR_PCI_IO_WIN_ADDR,
+				       data, is_write ? KVM_EXIT_IO_OUT :
+				       KVM_EXIT_IO_IN,
+				       len, 1);
+	} else if ((phys_addr >= SPAPR_PCI_MEM_WIN_ADDR) &&
+		   (phys_addr < SPAPR_PCI_MEM_WIN_ADDR +
+		    SPAPR_PCI_MEM_WIN_SIZE)) {
+		return kvm__emulate_mmio(kvm, phys_addr - SPAPR_PCI_MEM_WIN_ADDR,
+					 data, len, is_write);
+	}
+	return false;
+}
+
+#endif
diff --git a/tools/kvm/powerpc/spapr_rtas.c b/tools/kvm/powerpc/spapr_rtas.c
new file mode 100644
index 0000000..14a3462
--- /dev/null
+++ b/tools/kvm/powerpc/spapr_rtas.c
@@ -0,0 +1,229 @@
+/*
+ * SPAPR base RTAS calls
+ *
+ * Borrowed heavily from QEMU's spapr_rtas.c
+ * Copyright (c) 2010-2011 David Gibson, IBM Corporation.
+ *
+ * Modifications copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+#include "kvm/util.h"
+#include "kvm/term.h"
+#include "libfdt.h"
+
+#include "spapr.h"
+
+#include <stdio.h>
+#include <assert.h>
+
+#define TOKEN_BASE      0x2000
+#define TOKEN_MAX       0x100
+
+#define RTAS_CONSOLE
+
+static struct rtas_call {
+	const char *name;
+	spapr_rtas_fn fn;
+} rtas_table[TOKEN_MAX];
+
+struct rtas_call *rtas_next = rtas_table;
+
+
+static void rtas_display_character(struct kvm_cpu *vcpu,
+                                   uint32_t token, uint32_t nargs,
+                                   target_ulong args,
+                                   uint32_t nret, target_ulong rets)
+{
+	char c = rtas_ld(vcpu->kvm, args, 0);
+	term_putc(CONSOLE_HV, &c, 1, 0);
+	rtas_st(vcpu->kvm, rets, 0, 0);
+}
+
+#ifdef RTAS_CONSOLE
+static void rtas_put_term_char(struct kvm_cpu *vcpu,
+			       uint32_t token, uint32_t nargs,
+			       target_ulong args,
+			       uint32_t nret, target_ulong rets)
+{
+	char c = rtas_ld(vcpu->kvm, args, 0);
+	term_putc(CONSOLE_HV, &c, 1, 0);
+	rtas_st(vcpu->kvm, rets, 0, 0);
+}
+
+static void rtas_get_term_char(struct kvm_cpu *vcpu,
+			       uint32_t token, uint32_t nargs,
+			       target_ulong args,
+			       uint32_t nret, target_ulong rets)
+{
+	int c;
+	if (term_readable(CONSOLE_HV, 0) &&
+	    (c = term_getc(CONSOLE_HV, 0)) >= 0) {
+		rtas_st(vcpu->kvm, rets, 0, 0);
+		rtas_st(vcpu->kvm, rets, 1, c);
+	} else {
+		rtas_st(vcpu->kvm, rets, 0, -2);
+	}
+}
+#endif
+
+static void rtas_get_time_of_day(struct kvm_cpu *vcpu,
+                                 uint32_t token, uint32_t nargs,
+                                 target_ulong args,
+                                 uint32_t nret, target_ulong rets)
+{
+	struct tm tm;
+	time_t tnow;
+
+	if (nret != 8) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	tnow = time(NULL);
+	/* Guest time is currently not offset in any way. */
+	gmtime_r(&tnow, &tm);
+
+	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
+	rtas_st(vcpu->kvm, rets, 1, tm.tm_year + 1900);
+	rtas_st(vcpu->kvm, rets, 2, tm.tm_mon + 1);
+	rtas_st(vcpu->kvm, rets, 3, tm.tm_mday);
+	rtas_st(vcpu->kvm, rets, 4, tm.tm_hour);
+	rtas_st(vcpu->kvm, rets, 5, tm.tm_min);
+	rtas_st(vcpu->kvm, rets, 6, tm.tm_sec);
+	rtas_st(vcpu->kvm, rets, 7, 0);
+}
+
+static void rtas_set_time_of_day(struct kvm_cpu *vcpu,
+                                 uint32_t token, uint32_t nargs,
+                                 target_ulong args,
+                                 uint32_t nret, target_ulong rets)
+{
+	pr_warning("%s called; TOD set ignored.\n", __FUNCTION__);
+}
+
+static void rtas_power_off(struct kvm_cpu *vcpu,
+                           uint32_t token, uint32_t nargs, target_ulong args,
+                           uint32_t nret, target_ulong rets)
+{
+	if (nargs != 2 || nret != 1) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+	kvm_cpu__reboot();
+}
+
+static void rtas_query_cpu_stopped_state(struct kvm_cpu *vcpu,
+                                         uint32_t token, uint32_t nargs,
+                                         target_ulong args,
+                                         uint32_t nret, target_ulong rets)
+{
+	if (nargs != 1 || nret != 2) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	/*
+	 * Can read id = rtas_ld(vcpu->kvm, args, 0), but
+	 * we currently start all CPUs.  So just return true.
+	 */
+	rtas_st(vcpu->kvm, rets, 0, 0);
+	rtas_st(vcpu->kvm, rets, 1, 2);
+}
+
+static void rtas_start_cpu(struct kvm_cpu *vcpu,
+                           uint32_t token, uint32_t nargs,
+                           target_ulong args,
+                           uint32_t nret, target_ulong rets)
+{
+	die(__FUNCTION__);
+}
+
+target_ulong spapr_rtas_call(struct kvm_cpu *vcpu,
+                             uint32_t token, uint32_t nargs, target_ulong args,
+                             uint32_t nret, target_ulong rets)
+{
+	if ((token >= TOKEN_BASE)
+	    && ((token - TOKEN_BASE) < TOKEN_MAX)) {
+		struct rtas_call *call = rtas_table + (token - TOKEN_BASE);
+
+		if (call->fn) {
+			call->fn(vcpu, token, nargs, args, nret, rets);
+			return H_SUCCESS;
+		}
+	}
+
+	/*
+	 * HACK: Some Linux early debug code uses RTAS display-character,
+	 * but assumes the token value is 0xa (which it is on some real
+	 * machines) without looking it up in the device tree.  This
+	 * special case makes this work
+	 */
+	if (token == 0xa) {
+		rtas_display_character(vcpu, 0xa, nargs, args, nret, rets);
+		return H_SUCCESS;
+	}
+
+	hcall_dprintf("Unknown RTAS token 0x%x\n", token);
+	rtas_st(vcpu->kvm, rets, 0, -3);
+	return H_PARAMETER;
+}
+
+void spapr_rtas_register(const char *name, spapr_rtas_fn fn)
+{
+	assert(rtas_next < (rtas_table + TOKEN_MAX));
+
+	rtas_next->name = name;
+	rtas_next->fn = fn;
+
+	rtas_next++;
+}
+
+/*
+ * This is called from the context of an open /rtas node, in order to add
+ * properties for the rtas call tokens.
+ */
+int spapr_rtas_fdt_setup(struct kvm *kvm, void *fdt)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < TOKEN_MAX; i++) {
+		struct rtas_call *call = &rtas_table[i];
+
+		if (!call->fn) {
+			continue;
+		}
+
+		ret = fdt_property_cell(fdt, call->name, i + TOKEN_BASE);
+
+		if (ret < 0) {
+			pr_warning("Couldn't add rtas token for %s: %s\n",
+				   call->name, fdt_strerror(ret));
+			return ret;
+		}
+
+	}
+	return 0;
+}
+
+void register_core_rtas(void)
+{
+	spapr_rtas_register("display-character", rtas_display_character);
+	spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
+	spapr_rtas_register("set-time-of-day", rtas_set_time_of_day);
+	spapr_rtas_register("power-off", rtas_power_off);
+	spapr_rtas_register("query-cpu-stopped-state",
+			    rtas_query_cpu_stopped_state);
+	spapr_rtas_register("start-cpu", rtas_start_cpu);
+#ifdef RTAS_CONSOLE
+	/* These are unused: We do console I/O via hcalls, not rtas. */
+	spapr_rtas_register("put-term-char", rtas_put_term_char);
+	spapr_rtas_register("get-term-char", rtas_get_term_char);
+#endif
+}
diff --git a/tools/kvm/powerpc/xics.c b/tools/kvm/powerpc/xics.c
new file mode 100644
index 0000000..2d70d3c
--- /dev/null
+++ b/tools/kvm/powerpc/xics.c
@@ -0,0 +1,514 @@
+/*
+ * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
+ *
+ * Borrowed heavily from QEMU's xics.c,
+ * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
+ *
+ * Modifications copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "spapr.h"
+#include "xics.h"
+#include "kvm/util.h"
+
+#include <stdio.h>
+#include <malloc.h>
+
+
+/* #define DEBUG_XICS yes */
+#ifdef DEBUG_XICS
+#define xics_dprintf(fmt, ...)					\
+	do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define xics_dprintf(fmt, ...)			\
+	do { } while (0)
+#endif
+
+/*
+ * ICP: Presentation layer
+ */
+
+struct icp_server_state {
+	uint32_t xirr;
+	uint8_t pending_priority;
+	uint8_t mfrr;
+	struct kvm_cpu *cpu;
+};
+
+#define XICS_IRQ_OFFSET 16
+#define XISR_MASK	0x00ffffff
+#define CPPR_MASK	0xff000000
+
+#define XISR(ss)   (((ss)->xirr) & XISR_MASK)
+#define CPPR(ss)   (((ss)->xirr) >> 24)
+
+struct ics_state;
+
+struct icp_state {
+	unsigned long nr_servers;
+	struct icp_server_state *ss;
+	struct ics_state *ics;
+};
+
+static void ics_reject(struct ics_state *ics, int nr);
+static void ics_resend(struct ics_state *ics);
+static void ics_eoi(struct ics_state *ics, int nr);
+
+static inline void cpu_irq_raise(struct kvm_cpu *vcpu)
+{
+	xics_dprintf("INT1[%p]\n", vcpu);
+	kvm_cpu__irq(vcpu, POWER7_EXT_IRQ, 1);
+}
+
+static inline void cpu_irq_lower(struct kvm_cpu *vcpu)
+{
+	xics_dprintf("INT0[%p]\n", vcpu);
+	kvm_cpu__irq(vcpu, POWER7_EXT_IRQ, 0);
+}
+
+static void icp_check_ipi(struct icp_state *icp, int server)
+{
+	struct icp_server_state *ss = icp->ss + server;
+
+	if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
+		return;
+	}
+
+	if (XISR(ss)) {
+		ics_reject(icp->ics, XISR(ss));
+	}
+
+	ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
+	ss->pending_priority = ss->mfrr;
+	cpu_irq_raise(ss->cpu);
+}
+
+static void icp_resend(struct icp_state *icp, int server)
+{
+	struct icp_server_state *ss = icp->ss + server;
+
+	if (ss->mfrr < CPPR(ss)) {
+		icp_check_ipi(icp, server);
+	}
+	ics_resend(icp->ics);
+}
+
+static void icp_set_cppr(struct icp_state *icp, int server, uint8_t cppr)
+{
+	struct icp_server_state *ss = icp->ss + server;
+	uint8_t old_cppr;
+	uint32_t old_xisr;
+
+	old_cppr = CPPR(ss);
+	ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
+
+	if (cppr < old_cppr) {
+		if (XISR(ss) && (cppr <= ss->pending_priority)) {
+			old_xisr = XISR(ss);
+			ss->xirr &= ~XISR_MASK; /* Clear XISR */
+			cpu_irq_lower(ss->cpu);
+			ics_reject(icp->ics, old_xisr);
+		}
+	} else {
+		if (!XISR(ss)) {
+			icp_resend(icp, server);
+		}
+	}
+}
+
+static void icp_set_mfrr(struct icp_state *icp, int nr, uint8_t mfrr)
+{
+	struct icp_server_state *ss = icp->ss + nr;
+
+	ss->mfrr = mfrr;
+	if (mfrr < CPPR(ss)) {
+		icp_check_ipi(icp, nr);
+	}
+}
+
+static uint32_t icp_accept(struct icp_server_state *ss)
+{
+	uint32_t xirr;
+
+	cpu_irq_lower(ss->cpu);
+	xirr = ss->xirr;
+	ss->xirr = ss->pending_priority << 24;
+	return xirr;
+}
+
+static void icp_eoi(struct icp_state *icp, int server, uint32_t xirr)
+{
+	struct icp_server_state *ss = icp->ss + server;
+
+	ics_eoi(icp->ics, xirr & XISR_MASK);
+	/* Send EOI -> ICS */
+	ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
+	if (!XISR(ss)) {
+		icp_resend(icp, server);
+	}
+}
+
+static void icp_irq(struct icp_state *icp, int server, int nr, uint8_t priority)
+{
+	struct icp_server_state *ss = icp->ss + server;
+	xics_dprintf("icp_irq(nr %d, server %d, prio 0x%x)\n", nr, server, priority);
+	if ((priority >= CPPR(ss))
+	    || (XISR(ss) && (ss->pending_priority <= priority))) {
+		xics_dprintf("reject %d, CPPR 0x%x, XISR 0x%x, pprio 0x%x, prio 0x%x\n",
+			     nr, CPPR(ss), XISR(ss), ss->pending_priority, priority);
+		ics_reject(icp->ics, nr);
+	} else {
+		if (XISR(ss)) {
+			xics_dprintf("reject %d, CPPR 0x%x, XISR 0x%x, pprio 0x%x, prio 0x%x\n",
+				     nr, CPPR(ss), XISR(ss), ss->pending_priority, priority);
+			ics_reject(icp->ics, XISR(ss));
+		}
+		ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
+		ss->pending_priority = priority;
+		cpu_irq_raise(ss->cpu);
+	}
+}
+
+/*
+ * ICS: Source layer
+ */
+
+struct ics_irq_state {
+	int server;
+	uint8_t priority;
+	uint8_t saved_priority;
+	int rejected:1;
+	int masked_pending:1;
+};
+
+struct ics_state {
+	unsigned int nr_irqs;
+	unsigned int offset;
+	struct ics_irq_state *irqs;
+	struct icp_state *icp;
+};
+
+static int ics_valid_irq(struct ics_state *ics, uint32_t nr)
+{
+	return (nr >= ics->offset)
+		&& (nr < (ics->offset + ics->nr_irqs));
+}
+
+static void ics_set_irq_msi(struct ics_state *ics, int srcno, int val)
+{
+	struct ics_irq_state *irq = ics->irqs + srcno;
+
+	if (val) {
+		if (irq->priority == 0xff) {
+			xics_dprintf(" irq pri ff, masked pending\n");
+			irq->masked_pending = 1;
+		} else	{
+			icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
+		}
+	}
+}
+
+static void ics_reject_msi(struct ics_state *ics, int nr)
+{
+	struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
+
+	irq->rejected = 1;
+}
+
+static void ics_resend_msi(struct ics_state *ics)
+{
+	unsigned int i;
+
+	for (i = 0; i < ics->nr_irqs; i++) {
+		struct ics_irq_state *irq = ics->irqs + i;
+
+		/* FIXME: filter by server#? */
+		if (irq->rejected) {
+			irq->rejected = 0;
+			if (irq->priority != 0xff) {
+				icp_irq(ics->icp, irq->server, i + ics->offset, irq->priority);
+			}
+		}
+	}
+}
+
+static void ics_write_xive_msi(struct ics_state *ics, int nr, int server,
+			       uint8_t priority)
+{
+	struct ics_irq_state *irq = ics->irqs + nr - ics->offset;
+
+	irq->server = server;
+	irq->priority = priority;
+	xics_dprintf("ics_write_xive_msi(nr %d, server %d, pri 0x%x)\n", nr, server, priority);
+
+	if (!irq->masked_pending || (priority == 0xff)) {
+		return;
+	}
+
+	irq->masked_pending = 0;
+	icp_irq(ics->icp, server, nr, priority);
+}
+
+static void ics_reject(struct ics_state *ics, int nr)
+{
+	ics_reject_msi(ics, nr);
+}
+
+static void ics_resend(struct ics_state *ics)
+{
+	ics_resend_msi(ics);
+}
+
+static void ics_eoi(struct ics_state *ics, int nr)
+{
+}
+
+/*
+ * Exported functions
+ */
+
+static int allocated_irqnum = XICS_IRQ_OFFSET;
+
+/*
+ * xics_alloc_irqnum(): This is hacky.  The problem boils down to the PCI device
+ * code which just calls kvm__irq_line( .. pcidev->pci_hdr.irq_line ..) at will.
+ * Each PCI device's IRQ line is allocated by irq__register_device() (which
+ * allocates an IRQ AND allocates a.. PCI device num..).
+ *
+ * In future I'd like to at least mimic some kind of 'upstream IRQ controller'
+ * whereby PCI devices let their PHB know when they want to IRQ, and that
+ * percolates up.
+ *
+ * For now, allocate a REAL xics irq number and (via irq__register_device) push
+ * that into the config space.	8 bits only though!
+ */
+int xics_alloc_irqnum(void)
+{
+	int irq = allocated_irqnum++;
+
+	if (irq > 255)
+		die("Huge numbers of IRQs aren't supported with the daft kvmtool IRQ system.");
+
+	return irq;
+}
+
+static target_ulong h_cppr(struct kvm_cpu *vcpu,
+			   target_ulong opcode, target_ulong *args)
+{
+	target_ulong cppr = args[0];
+
+	xics_dprintf("h_cppr(%lx)\n", cppr);
+	icp_set_cppr(vcpu->kvm->icp, vcpu->cpu_id, cppr);
+	return H_SUCCESS;
+}
+
+static target_ulong h_ipi(struct kvm_cpu *vcpu,
+			  target_ulong opcode, target_ulong *args)
+{
+	target_ulong server = args[0];
+	target_ulong mfrr = args[1];
+
+	xics_dprintf("h_ipi(%lx, %lx)\n", server, mfrr);
+	if (server >= vcpu->kvm->icp->nr_servers) {
+		return H_PARAMETER;
+	}
+
+	icp_set_mfrr(vcpu->kvm->icp, server, mfrr);
+	return H_SUCCESS;
+}
+
+static target_ulong h_xirr(struct kvm_cpu *vcpu,
+			   target_ulong opcode, target_ulong *args)
+{
+	uint32_t xirr = icp_accept(vcpu->kvm->icp->ss + vcpu->cpu_id);
+
+	xics_dprintf("h_xirr() = %x\n", xirr);
+	args[0] = xirr;
+	return H_SUCCESS;
+}
+
+static target_ulong h_eoi(struct kvm_cpu *vcpu,
+			  target_ulong opcode, target_ulong *args)
+{
+	target_ulong xirr = args[0];
+
+	xics_dprintf("h_eoi(%lx)\n", xirr);
+	icp_eoi(vcpu->kvm->icp, vcpu->cpu_id, xirr);
+	return H_SUCCESS;
+}
+
+static void rtas_set_xive(struct kvm_cpu *vcpu, uint32_t token,
+			  uint32_t nargs, target_ulong args,
+			  uint32_t nret, target_ulong rets)
+{
+	struct ics_state *ics = vcpu->kvm->icp->ics;
+	uint32_t nr, server, priority;
+
+	if ((nargs != 3) || (nret != 1)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	nr = rtas_ld(vcpu->kvm, args, 0);
+	server = rtas_ld(vcpu->kvm, args, 1);
+	priority = rtas_ld(vcpu->kvm, args, 2);
+
+	xics_dprintf("rtas_set_xive(%x,%x,%x)\n", nr, server, priority);
+	if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
+	    || (priority > 0xff)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	ics_write_xive_msi(ics, nr, server, priority);
+
+	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
+}
+
+static void rtas_get_xive(struct kvm_cpu *vcpu, uint32_t token,
+			  uint32_t nargs, target_ulong args,
+			  uint32_t nret, target_ulong rets)
+{
+	struct ics_state *ics = vcpu->kvm->icp->ics;
+	uint32_t nr;
+
+	if ((nargs != 1) || (nret != 3)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	nr = rtas_ld(vcpu->kvm, args, 0);
+
+	if (!ics_valid_irq(ics, nr)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
+	rtas_st(vcpu->kvm, rets, 1, ics->irqs[nr - ics->offset].server);
+	rtas_st(vcpu->kvm, rets, 2, ics->irqs[nr - ics->offset].priority);
+}
+
+static void rtas_int_off(struct kvm_cpu *vcpu, uint32_t token,
+			 uint32_t nargs, target_ulong args,
+			 uint32_t nret, target_ulong rets)
+{
+	struct ics_state *ics = vcpu->kvm->icp->ics;
+	uint32_t nr;
+
+	if ((nargs != 1) || (nret != 1)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	nr = rtas_ld(vcpu->kvm, args, 0);
+
+	if (!ics_valid_irq(ics, nr)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	/* ME: QEMU wrote xive_msi here, in #if 0.  Deleted. */
+
+	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
+}
+
+static void rtas_int_on(struct kvm_cpu *vcpu, uint32_t token,
+			uint32_t nargs, target_ulong args,
+			uint32_t nret, target_ulong rets)
+{
+	struct ics_state *ics = vcpu->kvm->icp->ics;
+	uint32_t nr;
+
+	if ((nargs != 1) || (nret != 1)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	nr = rtas_ld(vcpu->kvm, args, 0);
+
+	if (!ics_valid_irq(ics, nr)) {
+		rtas_st(vcpu->kvm, rets, 0, -3);
+		return;
+	}
+
+	/* ME: QEMU wrote xive_msi here, in #if 0.  Deleted. */
+
+	rtas_st(vcpu->kvm, rets, 0, 0); /* Success */
+}
+
+void xics_cpu_register(struct kvm_cpu *vcpu)
+{
+	if (vcpu->cpu_id < vcpu->kvm->icp->nr_servers)
+		vcpu->kvm->icp->ss[vcpu->cpu_id].cpu = vcpu;
+	else
+		die("Setting invalid server for cpuid %ld\n", vcpu->cpu_id);
+}
+
+struct icp_state *xics_system_init(unsigned int nr_irqs, unsigned int nr_cpus)
+{
+	int max_server_num;
+	unsigned int i;
+	struct icp_state *icp;
+	struct ics_state *ics;
+
+	max_server_num = nr_cpus;
+
+	icp = malloc(sizeof(*icp));
+	icp->nr_servers = max_server_num + 1;
+	icp->ss = malloc(icp->nr_servers*sizeof(struct icp_server_state));
+
+	for (i = 0; i < icp->nr_servers; i++) {
+		icp->ss[i].xirr = 0;
+		icp->ss[i].pending_priority = 0;
+		icp->ss[i].cpu = 0;
+		icp->ss[i].mfrr = 0xff;
+	}
+
+	/*
+	 * icp->ss[env->cpu_index].cpu is set by CPUs calling in to
+	 * xics_cpu_register().
+	 */
+
+	ics = malloc(sizeof(*ics));
+	ics->nr_irqs = nr_irqs;
+	ics->offset = XICS_IRQ_OFFSET;
+	ics->irqs = malloc(nr_irqs * sizeof(struct ics_irq_state));
+
+	icp->ics = ics;
+	ics->icp = icp;
+
+	for (i = 0; i < nr_irqs; i++) {
+		ics->irqs[i].server = 0;
+		ics->irqs[i].priority = 0xff;
+		ics->irqs[i].saved_priority = 0xff;
+		ics->irqs[i].rejected = 0;
+		ics->irqs[i].masked_pending = 0;
+	}
+
+	spapr_register_hypercall(H_CPPR, h_cppr);
+	spapr_register_hypercall(H_IPI, h_ipi);
+	spapr_register_hypercall(H_XIRR, h_xirr);
+	spapr_register_hypercall(H_EOI, h_eoi);
+
+	spapr_rtas_register("ibm,set-xive", rtas_set_xive);
+	spapr_rtas_register("ibm,get-xive", rtas_get_xive);
+	spapr_rtas_register("ibm,int-off", rtas_int_off);
+	spapr_rtas_register("ibm,int-on", rtas_int_on);
+
+	return icp;
+}
+
+void kvm__irq_line(struct kvm *kvm, int irq, int level)
+{
+	/*
+	 * Route event to ICS, which routes to ICP, which eventually does a
+	 * kvm_cpu__irq(vcpu, POWER7_EXT_IRQ, 1)
+	 */
+	xics_dprintf("Raising IRQ %d -> %d\n", irq, level);
+	ics_set_irq_msi(kvm->icp->ics, irq - kvm->icp->ics->offset, level);
+}
diff --git a/tools/kvm/powerpc/xics.h b/tools/kvm/powerpc/xics.h
new file mode 100644
index 0000000..144915b
--- /dev/null
+++ b/tools/kvm/powerpc/xics.h
@@ -0,0 +1,23 @@
+/*
+ * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
+ *
+ * Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef XICS_H
+#define XICS_H
+
+#define XICS_IPI        0x2
+
+struct kvm_cpu;
+struct icp_state;
+
+struct icp_state *xics_system_init(unsigned int nr_irqs, unsigned int nr_cpus);
+void xics_cpu_register(struct kvm_cpu *vcpu);
+int xics_alloc_irqnum(void);
+
+#endif
diff --git a/tools/kvm/symbol.c b/tools/kvm/symbol.c
new file mode 100644
index 0000000..b76d98b
--- /dev/null
+++ b/tools/kvm/symbol.c
@@ -0,0 +1,131 @@
+#include "kvm/symbol.h"
+
+#include "kvm/kvm.h"
+
+#include <linux/err.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <bfd.h>
+
+static bfd *abfd;
+
+int symbol_init(struct kvm *kvm)
+{
+	int ret = 0;
+
+	if (!kvm->vmlinux)
+		return -EINVAL;
+
+	bfd_init();
+
+	abfd = bfd_openr(kvm->vmlinux, NULL);
+	if (abfd == NULL) {
+		bfd_error_type err = bfd_get_error();
+
+		switch (err) {
+		case bfd_error_no_memory:
+			ret = -ENOMEM;
+			break;
+		case bfd_error_invalid_target:
+			ret = -EINVAL;
+			break;
+		default:
+			ret = -EFAULT;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name)
+{
+	int i, ret;
+
+	ret = -ENOENT;
+
+	for (i = 0; i < nr_symbols; i++) {
+		asymbol *symbol = symbols[i];
+
+		if (!strcmp(bfd_asymbol_name(symbol), symbol_name))
+			return symbol;
+	}
+
+	return ERR_PTR(ret);
+}
+
+char *symbol_lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size)
+{
+	const char *filename;
+	bfd_vma sym_offset;
+	bfd_vma sym_start;
+	asection *section;
+	unsigned int line;
+	const char *func;
+	long symtab_size;
+	asymbol *symbol;
+	asymbol **syms;
+	int nr_syms, ret;
+
+	ret = -ENOENT;
+	if (!abfd)
+		goto not_found;
+
+	if (!bfd_check_format(abfd, bfd_object))
+		goto not_found;
+
+	symtab_size = bfd_get_symtab_upper_bound(abfd);
+	if (!symtab_size)
+		goto not_found;
+
+	ret = -ENOMEM;
+	syms = malloc(symtab_size);
+	if (!syms)
+		goto not_found;
+
+	nr_syms = bfd_canonicalize_symtab(abfd, syms);
+
+	ret = -ENOENT;
+	section = bfd_get_section_by_name(abfd, ".debug_aranges");
+	if (!section)
+		goto not_found;
+
+	if (!bfd_find_nearest_line(abfd, section, NULL, addr, &filename, &func, &line))
+		goto not_found;
+
+	if (!func)
+		goto not_found;
+
+	symbol = lookup(syms, nr_syms, func);
+	if (IS_ERR(symbol))
+		goto not_found;
+
+	sym_start = bfd_asymbol_value(symbol);
+
+	sym_offset = addr - sym_start;
+
+	snprintf(sym, size, "%s+%llx (%s:%i)", func, (long long) sym_offset, filename, line);
+
+	sym[size - 1] = '\0';
+
+	free(syms);
+
+	return sym;
+
+not_found:
+	return ERR_PTR(ret);
+}
+
+int symbol_exit(struct kvm *kvm)
+{
+	bfd_boolean ret = TRUE;
+
+	if (abfd)
+		ret = bfd_close(abfd);
+
+	if (ret == TRUE)
+		return 0;
+
+	return -EFAULT;
+}
diff --git a/tools/kvm/term.c b/tools/kvm/term.c
new file mode 100644
index 0000000..cc0c5a5
--- /dev/null
+++ b/tools/kvm/term.c
@@ -0,0 +1,166 @@
+#include <poll.h>
+#include <stdbool.h>
+#include <termios.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/uio.h>
+#include <signal.h>
+#include <pty.h>
+#include <utmp.h>
+
+#include "kvm/read-write.h"
+#include "kvm/term.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+
+#define TERM_FD_IN      0
+#define TERM_FD_OUT     1
+
+extern struct kvm *kvm;
+static struct termios	orig_term;
+
+int term_escape_char	= 0x01; /* ctrl-a is used for escape */
+bool term_got_escape	= false;
+
+int active_console;
+
+int term_fds[4][2];
+
+int term_getc(int who, int term)
+{
+	unsigned char c;
+
+	if (who != active_console)
+		return -1;
+	if (read_in_full(term_fds[term][TERM_FD_IN], &c, 1) < 0)
+		return -1;
+
+	if (term_got_escape) {
+		term_got_escape = false;
+		if (c == 'x')
+			kvm_cpu__reboot();
+		if (c == term_escape_char)
+			return c;
+	}
+
+	if (c == term_escape_char) {
+		term_got_escape = true;
+		return -1;
+	}
+
+	return c;
+}
+
+int term_putc(int who, char *addr, int cnt, int term)
+{
+	int ret;
+
+	if (who != active_console)
+		return -1;
+
+	while (cnt--) {
+		ret = write(term_fds[term][TERM_FD_OUT], addr++, 1);
+		if (ret < 0)
+			return 0;
+	}
+
+	return cnt;
+}
+
+int term_getc_iov(int who, struct iovec *iov, int iovcnt, int term)
+{
+	int c;
+
+	if (who != active_console)
+		return 0;
+
+	c = term_getc(who, term);
+
+	if (c < 0)
+		return 0;
+
+	*((char *)iov[TERM_FD_IN].iov_base)	= (char)c;
+
+	return sizeof(char);
+}
+
+int term_putc_iov(int who, struct iovec *iov, int iovcnt, int term)
+{
+	if (who != active_console)
+		return 0;
+
+	return writev(term_fds[term][TERM_FD_OUT], iov, iovcnt);
+}
+
+bool term_readable(int who, int term)
+{
+	struct pollfd pollfd = (struct pollfd) {
+		.fd	= term_fds[term][TERM_FD_IN],
+		.events	= POLLIN,
+		.revents = 0,
+	};
+
+	if (who != active_console)
+		return false;
+
+	return poll(&pollfd, 1, 0) > 0;
+}
+
+static void term_cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < 4; i++)
+		tcsetattr(term_fds[i][TERM_FD_IN], TCSANOW, &orig_term);
+}
+
+static void term_sig_cleanup(int sig)
+{
+	term_cleanup();
+	signal(sig, SIG_DFL);
+	raise(sig);
+}
+
+void term_set_tty(int term)
+{
+	struct termios orig_term;
+	int master, slave;
+	char new_pty[PATH_MAX];
+
+	if (tcgetattr(STDIN_FILENO, &orig_term) < 0)
+		die("unable to save initial standard input settings");
+
+	orig_term.c_lflag &= ~(ICANON | ECHO | ISIG);
+
+	if (openpty(&master, &slave, new_pty, &orig_term, NULL) < 0)
+		return;
+
+	close(slave);
+
+	pr_info("Assigned terminal %d to pty %s\n", term, new_pty);
+
+	term_fds[term][TERM_FD_IN] = term_fds[term][TERM_FD_OUT] = master;
+}
+
+void term_init(void)
+{
+	struct termios term;
+	int i;
+
+	if (tcgetattr(STDIN_FILENO, &orig_term) < 0)
+		die("unable to save initial standard input settings");
+
+	term = orig_term;
+	term.c_lflag &= ~(ICANON | ECHO | ISIG);
+	tcsetattr(STDIN_FILENO, TCSANOW, &term);
+
+	for (i = 0; i < 4; i++)
+		if (term_fds[i][TERM_FD_IN] == 0) {
+			term_fds[i][TERM_FD_IN] = STDIN_FILENO;
+			term_fds[i][TERM_FD_OUT] = STDOUT_FILENO;
+		}
+
+	signal(SIGTERM, term_sig_cleanup);
+	atexit(term_cleanup);
+}
diff --git a/tools/kvm/tests/Makefile b/tools/kvm/tests/Makefile
new file mode 100644
index 0000000..cad14ec
--- /dev/null
+++ b/tools/kvm/tests/Makefile
@@ -0,0 +1,19 @@
+all: kernel pit boot
+
+kernel:
+	$(MAKE) -C kernel
+.PHONY: kernel
+
+pit:
+	$(MAKE) -C pit
+.PHONY: pit
+
+boot:
+	$(MAKE) -C boot
+.PHONY: boot
+
+clean:
+	$(MAKE) -C kernel clean
+	$(MAKE) -C pit clean
+	$(MAKE) -C boot clean
+.PHONY: clean
diff --git a/tools/kvm/tests/boot/Makefile b/tools/kvm/tests/boot/Makefile
new file mode 100644
index 0000000..40cba68
--- /dev/null
+++ b/tools/kvm/tests/boot/Makefile
@@ -0,0 +1,13 @@
+NAME	:= init
+
+OBJ	:= $(NAME).o
+
+all: $(.o)
+	rm -rf rootfs
+	mkdir rootfs
+	gcc -static init.c -o rootfs/init
+	mkisofs rootfs > boot_test.iso
+
+clean:
+	rm -rf rootfs boot_test.iso
+.PHONY: clean
diff --git a/tools/kvm/tests/boot/init.c b/tools/kvm/tests/boot/init.c
new file mode 100644
index 0000000..094f8ba
--- /dev/null
+++ b/tools/kvm/tests/boot/init.c
@@ -0,0 +1,11 @@
+#include <linux/reboot.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+	puts("hello, KVM guest!\r");
+
+	reboot(LINUX_REBOOT_CMD_RESTART);
+
+	return 0;
+}
diff --git a/tools/kvm/tests/kernel/.gitignore b/tools/kvm/tests/kernel/.gitignore
new file mode 100644
index 0000000..d0cd209
--- /dev/null
+++ b/tools/kvm/tests/kernel/.gitignore
@@ -0,0 +1,2 @@
+kernel.bin
+kernel.elf
diff --git a/tools/kvm/tests/kernel/Makefile b/tools/kvm/tests/kernel/Makefile
new file mode 100644
index 0000000..c7dd8da
--- /dev/null
+++ b/tools/kvm/tests/kernel/Makefile
@@ -0,0 +1,20 @@
+NAME	:= kernel
+
+BIN	:= $(NAME).bin
+ELF	:= $(NAME).elf
+OBJ	:= $(NAME).o
+
+all: $(BIN)
+
+$(BIN): $(ELF)
+	objcopy -O binary $< $@
+
+$(ELF): $(OBJ)
+	ld -Ttext=0x00 -nostdlib -static $< -o $@
+
+%.o: %.S
+	gcc -nostdinc -c $< -o $@
+
+clean:
+	rm -f $(BIN) $(ELF) $(OBJ)
+.PHONY: clean
diff --git a/tools/kvm/tests/kernel/README b/tools/kvm/tests/kernel/README
new file mode 100644
index 0000000..2923777
--- /dev/null
+++ b/tools/kvm/tests/kernel/README
@@ -0,0 +1,16 @@
+Compiling
+---------
+
+You can simply type:
+
+  $ make
+
+to build a 16-bit binary that uses the i8086 instruction set.
+
+Disassembling
+-------------
+
+Use the "-m i8086" command line option with objdump to make sure it knows we're
+dealing with i8086 instruction set:
+
+  $ objdump -d -m i8086 i8086.elf
diff --git a/tools/kvm/tests/kernel/kernel.S b/tools/kvm/tests/kernel/kernel.S
new file mode 100644
index 0000000..2824b64
--- /dev/null
+++ b/tools/kvm/tests/kernel/kernel.S
@@ -0,0 +1,8 @@
+	.code16gcc
+	.text
+	.globl  _start
+	.type   _start, @function
+_start:
+	# "This is probably the largest possible kernel that is bug free." -- Avi Kivity
+	1:
+	jmp 1b
diff --git a/tools/kvm/tests/pit/.gitignore b/tools/kvm/tests/pit/.gitignore
new file mode 100644
index 0000000..43f0aa8
--- /dev/null
+++ b/tools/kvm/tests/pit/.gitignore
@@ -0,0 +1,2 @@
+*.bin
+*.elf
diff --git a/tools/kvm/tests/pit/Makefile b/tools/kvm/tests/pit/Makefile
new file mode 100644
index 0000000..2fae9b2
--- /dev/null
+++ b/tools/kvm/tests/pit/Makefile
@@ -0,0 +1,20 @@
+NAME	:= tick
+
+BIN	:= $(NAME).bin
+ELF	:= $(NAME).elf
+OBJ	:= $(NAME).o
+
+all: $(BIN)
+
+$(BIN): $(ELF)
+	objcopy -O binary $< $@
+
+$(ELF): $(OBJ)
+	ld -Ttext=0x00 -nostdlib -static $< -o $@
+
+%.o: %.S
+	gcc -nostdinc -c $< -o $@
+
+clean:
+	rm -f $(BIN) $(ELF) $(OBJ)
+.PHONY: clean
diff --git a/tools/kvm/tests/pit/README b/tools/kvm/tests/pit/README
new file mode 100644
index 0000000..2923777
--- /dev/null
+++ b/tools/kvm/tests/pit/README
@@ -0,0 +1,16 @@
+Compiling
+---------
+
+You can simply type:
+
+  $ make
+
+to build a 16-bit binary that uses the i8086 instruction set.
+
+Disassembling
+-------------
+
+Use the "-m i8086" command line option with objdump to make sure it knows we're
+dealing with i8086 instruction set:
+
+  $ objdump -d -m i8086 i8086.elf
diff --git a/tools/kvm/tests/pit/tick.S b/tools/kvm/tests/pit/tick.S
new file mode 100644
index 0000000..b9e5a80
--- /dev/null
+++ b/tools/kvm/tests/pit/tick.S
@@ -0,0 +1,109 @@
+#define IO_PIC		0x20
+#define IRQ_OFFSET	32
+#define IO_PIT		0x40
+#define TIMER_FREQ	1193182
+#define TIMER_DIV(x)	((TIMER_FREQ+(x)/2)/(x))
+
+/*
+ * hpa noted:
+ *
+ * 0xe0..0xef are "motherboard specific", but 0xe9 is
+ * used for Bochs debugging and 0xed is the Phoenix-reserved
+ * delay port
+ */
+#define DBG_PORT	0xe0
+
+#define TEST_COUNT	0x0200
+
+	.code16gcc
+	.text
+	.globl	_start
+	.type	_start, @function
+_start:
+/*
+ * fill up noop handlers
+ */
+	xorw	%ax, %ax
+	xorw	%di, %di
+	movw	%ax, %es
+	movw	$256, %cx
+fill_noop_idt:
+	movw	$noop_handler, %es:(%di)
+	movw	%cs, %es:2(%di)
+	add	$4, %di
+	loop	fill_noop_idt
+
+set_idt:
+	movw	$timer_isr, %es:(IRQ_OFFSET*4)
+	movw	%cs, %es:(IRQ_OFFSET*4+2)
+
+set_pic:
+	# ICW1
+	mov	$0x11, %al
+	mov	$(IO_PIC), %dx
+	out	%al,%dx
+	# ICW2
+	mov	$(IRQ_OFFSET), %al
+	mov	$(IO_PIC+1), %dx
+	out	%al, %dx
+	# ICW3
+	mov	$0x00, %al
+	mov	$(IO_PIC+1), %dx
+	out	%al, %dx
+	# ICW4
+	mov	$0x3, %al
+	mov	$(IO_PIC+1), %dx
+	out	%al, %dx
+
+set_pit:
+	# set 8254 mode
+	mov	$(IO_PIT+3), %dx
+	mov	$0x34, %al
+	outb	%al, %dx
+	# set 8254 freq 1KHz
+	mov	$(IO_PIT), %dx
+	movb	$(TIMER_DIV(1000) % 256), %al
+	outb	%al, %dx
+	movb	$(TIMER_DIV(1000) / 256), %al
+	outb	%al, %dx
+
+enable_irq0:
+	mov	$0xfe, %al
+	mov	$(IO_PIC+1), %dx
+	out	%al, %dx
+	sti
+loop:
+	1:
+	jmp	1b
+
+test_ok:
+	mov	$0x3f8,%dx
+	cs lea	msg2, %si
+	mov	$(msg2_end-msg2), %cx
+	cs rep/outsb
+
+	/* not a valid port to force exit */
+	outb	%al, $DBG_PORT
+
+timer_isr:
+	cli
+	pushaw
+	pushfw
+	mov	$0x3f8,%dx
+	mov	$0x2e, %al	# .
+	out	%al,%dx
+	decw	count
+	jz	test_ok
+	popfw
+	popaw
+	iretw
+
+noop_handler:
+	iretw
+
+count:
+	.word	TEST_COUNT
+
+msg2:
+	.asciz "\nTest OK\n"
+msg2_end:
diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c
new file mode 100644
index 0000000..fa5d9c8
--- /dev/null
+++ b/tools/kvm/ui/sdl.c
@@ -0,0 +1,303 @@
+#include "kvm/sdl.h"
+
+#include "kvm/framebuffer.h"
+#include "kvm/i8042.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/kvm-cpu.h"
+
+#include <SDL/SDL.h>
+#include <pthread.h>
+#include <signal.h>
+
+#define FRAME_RATE		25
+
+#define SCANCODE_UNKNOWN      0
+#define SCANCODE_NORMAL       1
+#define SCANCODE_ESCAPED      2
+#define SCANCODE_KEY_PAUSE    3
+#define SCANCODE_KEY_PRNTSCRN 4
+
+struct set2_scancode {
+	u8 code;
+	u8 type;
+};
+
+#define DEFINE_SC(_code) {\
+	.code = _code,\
+	.type = SCANCODE_NORMAL,\
+}
+
+/* escaped scancodes */
+#define DEFINE_ESC(_code) {\
+	.code = _code,\
+	.type = SCANCODE_ESCAPED,\
+}
+
+static const struct set2_scancode const keymap[256] = {
+	[9]	= DEFINE_SC(0x76),	/* <esc> */
+	[10]	= DEFINE_SC(0x16),	/* 1 */
+	[11]	= DEFINE_SC(0x1e),	/* 2 */
+	[12]	= DEFINE_SC(0x26),	/* 3 */
+	[13]	= DEFINE_SC(0x25),	/* 4 */
+	[14]	= DEFINE_SC(0x2e),	/* 5 */
+	[15]	= DEFINE_SC(0x36),	/* 6 */
+	[16]	= DEFINE_SC(0x3d),	/* 7 */
+	[17]	= DEFINE_SC(0x3e),	/* 8 */
+	[18]	= DEFINE_SC(0x46),	/* 9 */
+	[19]	= DEFINE_SC(0x45),	/* 9 */
+	[20]	= DEFINE_SC(0x4e),	/* - */
+	[21]	= DEFINE_SC(0x55),	/* + */
+	[22]	= DEFINE_SC(0x66),	/* <backspace> */
+	[23]	= DEFINE_SC(0x0d),	/* <tab> */
+	[24]	= DEFINE_SC(0x15),	/* q */
+	[25]	= DEFINE_SC(0x1d),	/* w */
+	[26]	= DEFINE_SC(0x24),	/* e */
+	[27]	= DEFINE_SC(0x2d),	/* r */
+	[28]	= DEFINE_SC(0x2c),	/* t */
+	[29]	= DEFINE_SC(0x35),	/* y */
+	[30]	= DEFINE_SC(0x3c),	/* u */
+	[31]	= DEFINE_SC(0x43),	/* i */
+	[32]	= DEFINE_SC(0x44),	/* o */
+	[33]	= DEFINE_SC(0x4d),	/* p */
+	[34]	= DEFINE_SC(0x54),	/* [ */
+	[35]	= DEFINE_SC(0x5b),	/* ] */
+	[36]	= DEFINE_SC(0x5a),	/* <enter> */
+	[37]	= DEFINE_SC(0x14),	/* <left ctrl> */
+	[38]	= DEFINE_SC(0x1c),	/* a */
+	[39]	= DEFINE_SC(0x1b),	/* s */
+	[40]	= DEFINE_SC(0x23),	/* d */
+	[41]	= DEFINE_SC(0x2b),	/* f */
+	[42]	= DEFINE_SC(0x34),	/* g */
+	[43]	= DEFINE_SC(0x33),	/* h */
+	[44]	= DEFINE_SC(0x3b),	/* j */
+	[45]	= DEFINE_SC(0x42),	/* k */
+	[46]	= DEFINE_SC(0x4b),	/* l */
+	[47]	= DEFINE_SC(0x4c),	/* ; */
+	[48]	= DEFINE_SC(0x52),	/* ' */
+	[49]	= DEFINE_SC(0x0e),	/* ` */
+	[50]	= DEFINE_SC(0x12),	/* <left shift> */
+	[51]	= DEFINE_SC(0x5d),	/* \ */
+	[52]	= DEFINE_SC(0x1a),	/* z */
+	[53]	= DEFINE_SC(0x22),	/* x */
+	[54]	= DEFINE_SC(0x21),	/* c */
+	[55]	= DEFINE_SC(0x2a),	/* v */
+	[56]	= DEFINE_SC(0x32),	/* b */
+	[57]	= DEFINE_SC(0x31),	/* n */
+	[58]	= DEFINE_SC(0x3a),	/* m */
+	[59]	= DEFINE_SC(0x41),	/* < */
+	[60]	= DEFINE_SC(0x49),	/* > */
+	[61]	= DEFINE_SC(0x4a),	/* / */
+	[62]	= DEFINE_SC(0x59),	/* <right shift> */
+	[63]	= DEFINE_SC(0x7c),	/* keypad * */
+	[64]	= DEFINE_SC(0x11),	/* <left alt> */
+	[65]	= DEFINE_SC(0x29),	/* <space> */
+
+	[67]	= DEFINE_SC(0x05),	/* <F1> */
+	[68]	= DEFINE_SC(0x06),	/* <F2> */
+	[69]	= DEFINE_SC(0x04),	/* <F3> */
+	[70]	= DEFINE_SC(0x0c),	/* <F4> */
+	[71]	= DEFINE_SC(0x03),	/* <F5> */
+	[72]	= DEFINE_SC(0x0b),	/* <F6> */
+	[73]	= DEFINE_SC(0x83),	/* <F7> */
+	[74]	= DEFINE_SC(0x0a),	/* <F8> */
+	[75]	= DEFINE_SC(0x01),	/* <F9> */
+	[76]	= DEFINE_SC(0x09),	/* <F10> */
+
+	[79]	= DEFINE_SC(0x6c),	/* keypad 7 */
+	[80]	= DEFINE_SC(0x75),	/* keypad 8 */
+	[81]	= DEFINE_SC(0x7d),	/* keypad 9 */
+	[82]	= DEFINE_SC(0x7b),	/* keypad - */
+	[83]	= DEFINE_SC(0x6b),	/* keypad 4 */
+	[84]	= DEFINE_SC(0x73),	/* keypad 5 */
+	[85]	= DEFINE_SC(0x74),	/* keypad 6 */
+	[86]	= DEFINE_SC(0x79),	/* keypad + */
+	[87]	= DEFINE_SC(0x69),	/* keypad 1 */
+	[88]	= DEFINE_SC(0x72),	/* keypad 2 */
+	[89]	= DEFINE_SC(0x7a),	/* keypad 3 */
+	[90]	= DEFINE_SC(0x70),	/* keypad 0 */
+	[91]	= DEFINE_SC(0x71),	/* keypad . */
+
+	[94]	= DEFINE_SC(0x61),	/* <INT 1> */
+	[95]	= DEFINE_SC(0x78),	/* <F11> */
+	[96]	= DEFINE_SC(0x07),	/* <F12> */
+
+	[104]	= DEFINE_ESC(0x5a),	/* keypad <enter> */
+	[105]	= DEFINE_ESC(0x14),	/* <right ctrl> */
+	[106]	= DEFINE_ESC(0x4a),	/* keypad / */
+	[108]	= DEFINE_ESC(0x11),	/* <right alt> */
+	[110]	= DEFINE_ESC(0x6c),	/* <home> */
+	[111]	= DEFINE_ESC(0x75),	/* <up> */
+	[112]	= DEFINE_ESC(0x7d),	/* <pag up> */
+	[113]	= DEFINE_ESC(0x6b),	/* <left> */
+	[114]	= DEFINE_ESC(0x74),	/* <right> */
+	[115]	= DEFINE_ESC(0x69),	/* <end> */
+	[116]	= DEFINE_ESC(0x72),	/* <down> */
+	[117]	= DEFINE_ESC(0x7a),	/* <pag down> */
+	[118]	= DEFINE_ESC(0x70),	/* <ins> */
+	[119]	= DEFINE_ESC(0x71),	/* <delete> */
+};
+static bool running, done;
+
+static const struct set2_scancode *to_code(u8 scancode)
+{
+	return &keymap[scancode];
+}
+
+static void key_press(const struct set2_scancode *sc)
+{
+	switch (sc->type) {
+	case SCANCODE_ESCAPED:
+		kbd_queue(0xe0);
+		/* fallthrough */
+	case SCANCODE_NORMAL:
+		kbd_queue(sc->code);
+		break;
+	case SCANCODE_KEY_PAUSE:
+		kbd_queue(0xe1);
+		kbd_queue(0x14);
+		kbd_queue(0x77);
+		kbd_queue(0xe1);
+		kbd_queue(0xf0);
+		kbd_queue(0x14);
+		kbd_queue(0x77);
+		break;
+	case SCANCODE_KEY_PRNTSCRN:
+		kbd_queue(0xe0);
+		kbd_queue(0x12);
+		kbd_queue(0xe0);
+		kbd_queue(0x7c);
+		break;
+	}
+}
+
+static void key_release(const struct set2_scancode *sc)
+{
+	switch (sc->type) {
+	case SCANCODE_ESCAPED:
+		kbd_queue(0xe0);
+		/* fallthrough */
+	case SCANCODE_NORMAL:
+		kbd_queue(0xf0);
+		kbd_queue(sc->code);
+		break;
+	case SCANCODE_KEY_PAUSE:
+		/* nothing to do */
+		break;
+	case SCANCODE_KEY_PRNTSCRN:
+		kbd_queue(0xe0);
+		kbd_queue(0xf0);
+		kbd_queue(0x7c);
+		kbd_queue(0xe0);
+		kbd_queue(0xf0);
+		kbd_queue(0x12);
+		break;
+	}
+}
+
+static void *sdl__thread(void *p)
+{
+	Uint32 rmask, gmask, bmask, amask;
+	struct framebuffer *fb = p;
+	SDL_Surface *guest_screen;
+	SDL_Surface *screen;
+	SDL_Event ev;
+	Uint32 flags;
+
+	if (SDL_Init(SDL_INIT_VIDEO) != 0)
+		die("Unable to initialize SDL");
+
+	rmask = 0x000000ff;
+	gmask = 0x0000ff00;
+	bmask = 0x00ff0000;
+	amask = 0x00000000;
+
+	guest_screen = SDL_CreateRGBSurfaceFrom(fb->mem, fb->width, fb->height, fb->depth, fb->width * fb->depth / 8, rmask, gmask, bmask, amask);
+	if (!guest_screen)
+		die("Unable to create SDL RBG surface");
+
+	flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_DOUBLEBUF;
+
+	SDL_WM_SetCaption("KVM tool", "KVM tool");
+
+	screen = SDL_SetVideoMode(fb->width, fb->height, fb->depth, flags);
+	if (!screen)
+		die("Unable to set SDL video mode");
+
+	SDL_EnableKeyRepeat(200, 50);
+
+	while (running) {
+		SDL_BlitSurface(guest_screen, NULL, screen, NULL);
+		SDL_Flip(screen);
+
+		while (SDL_PollEvent(&ev)) {
+			switch (ev.type) {
+			case SDL_KEYDOWN: {
+				const struct set2_scancode *sc = to_code(ev.key.keysym.scancode);
+				if (sc->type == SCANCODE_UNKNOWN) {
+					pr_warning("key '%d' not found in keymap", ev.key.keysym.scancode);
+					break;
+				}
+				key_press(sc);
+				break;
+			}
+			case SDL_KEYUP: {
+				const struct set2_scancode *sc = to_code(ev.key.keysym.scancode);
+				if (sc->type == SCANCODE_UNKNOWN)
+					break;
+				key_release(sc);
+				break;
+			}
+			case SDL_QUIT:
+				goto exit;
+			}
+		}
+
+		SDL_Delay(1000 / FRAME_RATE);
+	}
+
+	if (running == false && done == false) {
+		done = true;
+		return NULL;
+	}
+exit:
+	kvm_cpu__reboot();
+
+	return NULL;
+}
+
+static int sdl__start(struct framebuffer *fb)
+{
+	pthread_t thread;
+
+	running = true;
+
+	if (pthread_create(&thread, NULL, sdl__thread, fb) != 0)
+		return -1;
+
+	return 0;
+}
+
+static int sdl__stop(struct framebuffer *fb)
+{
+	running = false;
+	while (done == false)
+		sleep(0);
+
+	return 0;
+}
+
+static struct fb_target_operations sdl_ops = {
+	.start	= sdl__start,
+	.start	= sdl__stop,
+};
+
+int sdl__init(struct framebuffer *fb)
+{
+	return fb__attach(fb, &sdl_ops);
+}
+
+int sdl__exit(struct framebuffer *fb)
+{
+	return sdl__stop(fb);
+}
diff --git a/tools/kvm/ui/vnc.c b/tools/kvm/ui/vnc.c
new file mode 100644
index 0000000..91254c5
--- /dev/null
+++ b/tools/kvm/ui/vnc.c
@@ -0,0 +1,230 @@
+#include "kvm/vnc.h"
+
+#include "kvm/framebuffer.h"
+#include "kvm/i8042.h"
+
+#include <linux/types.h>
+#include <rfb/keysym.h>
+#include <rfb/rfb.h>
+#include <pthread.h>
+
+#define VESA_QUEUE_SIZE		128
+#define VESA_IRQ		14
+
+/*
+ * This "6000" value is pretty much the result of experimentation
+ * It seems that around this value, things update pretty smoothly
+ */
+#define VESA_UPDATE_TIME	6000
+
+/*
+ * We can map the letters and numbers without a fuss,
+ * but the other characters not so much.
+ */
+static char letters[26] = {
+	0x1c, 0x32, 0x21, 0x23, 0x24, /* a-e */
+	0x2b, 0x34, 0x33, 0x43, 0x3b, /* f-j */
+	0x42, 0x4b, 0x3a, 0x31, 0x44, /* k-o */
+	0x4d, 0x15, 0x2d, 0x1b, 0x2c, /* p-t */
+	0x3c, 0x2a, 0x1d, 0x22, 0x35, /* u-y */
+	0x1a,
+};
+
+static rfbScreenInfoPtr server;
+static char num[10] = {
+	0x45, 0x16, 0x1e, 0x26, 0x2e, 0x23, 0x36, 0x3d, 0x3e, 0x46,
+};
+
+/*
+ * This is called when the VNC server receives a key event
+ * The reason this function is such a beast is that we have
+ * to convert from ASCII characters (which is what VNC gets)
+ * to PC keyboard scancodes, which is what Linux expects to
+ * get from its keyboard. ASCII and the scancode set don't
+ * really seem to mesh in any good way beyond some basics with
+ * the letters and numbers.
+ */
+static void kbd_handle_key(rfbBool down, rfbKeySym key, rfbClientPtr cl)
+{
+	char tosend = 0;
+
+	if (key >= 0x41 && key <= 0x5a)
+		key += 0x20; /* convert to lowercase */
+
+	if (key >= 0x61 && key <= 0x7a) /* a-z */
+		tosend = letters[key - 0x61];
+
+	if (key >= 0x30 && key <= 0x39)
+		tosend = num[key - 0x30];
+
+	switch (key) {
+	case XK_Insert:		kbd_queue(0xe0);	tosend = 0x70;	break;
+	case XK_Delete:		kbd_queue(0xe0);	tosend = 0x71;	break;
+	case XK_Up:		kbd_queue(0xe0);	tosend = 0x75;	break;
+	case XK_Down:		kbd_queue(0xe0);	tosend = 0x72;	break;
+	case XK_Left:		kbd_queue(0xe0);	tosend = 0x6b;	break;
+	case XK_Right:		kbd_queue(0xe0);	tosend = 0x74;	break;
+	case XK_Page_Up:	kbd_queue(0xe0);	tosend = 0x7d;	break;
+	case XK_Page_Down:	kbd_queue(0xe0);	tosend = 0x7a;	break;
+	case XK_Home:		kbd_queue(0xe0);	tosend = 0x6c;	break;
+	case XK_BackSpace:	tosend = 0x66;		break;
+	case XK_Tab:		tosend = 0x0d;		break;
+	case XK_Return:		tosend = 0x5a;		break;
+	case XK_Escape:		tosend = 0x76;		break;
+	case XK_End:		tosend = 0x69;		break;
+	case XK_Shift_L:	tosend = 0x12;		break;
+	case XK_Shift_R:	tosend = 0x59;		break;
+	case XK_Control_R:	kbd_queue(0xe0);
+	case XK_Control_L:	tosend = 0x14;		break;
+	case XK_Alt_R:		kbd_queue(0xe0);
+	case XK_Alt_L:		tosend = 0x11;		break;
+	case XK_quoteleft:	tosend = 0x0e;		break;
+	case XK_minus:		tosend = 0x4e;		break;
+	case XK_equal:		tosend = 0x55;		break;
+	case XK_bracketleft:	tosend = 0x54;		break;
+	case XK_bracketright:	tosend = 0x5b;		break;
+	case XK_backslash:	tosend = 0x5d;		break;
+	case XK_Caps_Lock:	tosend = 0x58;		break;
+	case XK_semicolon:	tosend = 0x4c;		break;
+	case XK_quoteright:	tosend = 0x52;		break;
+	case XK_comma:		tosend = 0x41;		break;
+	case XK_period:		tosend = 0x49;		break;
+	case XK_slash:		tosend = 0x4a;		break;
+	case XK_space:		tosend = 0x29;		break;
+
+	/*
+	 * This is where I handle the shifted characters.
+	 * They don't really map nicely the way A-Z maps to a-z,
+	 * so I'm doing it manually
+	 */
+	case XK_exclam:		tosend = 0x16;		break;
+	case XK_quotedbl:	tosend = 0x52;		break;
+	case XK_numbersign:	tosend = 0x26;		break;
+	case XK_dollar:		tosend = 0x25;		break;
+	case XK_percent:	tosend = 0x2e;		break;
+	case XK_ampersand:	tosend = 0x3d;		break;
+	case XK_parenleft:	tosend = 0x46;		break;
+	case XK_parenright:	tosend = 0x45;		break;
+	case XK_asterisk:	tosend = 0x3e;		break;
+	case XK_plus:		tosend = 0x55;		break;
+	case XK_colon:		tosend = 0x4c;		break;
+	case XK_less:		tosend = 0x41;		break;
+	case XK_greater:	tosend = 0x49;		break;
+	case XK_question:	tosend = 0x4a;		break;
+	case XK_at:		tosend = 0x1e;		break;
+	case XK_asciicircum:	tosend = 0x36;		break;
+	case XK_underscore:	tosend = 0x4e;		break;
+	case XK_braceleft:	tosend = 0x54;		break;
+	case XK_braceright:	tosend = 0x5b;		break;
+	case XK_bar:		tosend = 0x5d;		break;
+	case XK_asciitilde:	tosend = 0x0e;		break;
+	default:		break;
+	}
+
+	/*
+	 * If this is a "key up" event (the user has released the key, we
+	 * need to send 0xf0 first.
+	 */
+	if (!down && tosend != 0x0)
+		kbd_queue(0xf0);
+
+	if (tosend)
+		kbd_queue(tosend);
+}
+
+/* The previous X and Y coordinates of the mouse */
+static int xlast, ylast = -1;
+
+/*
+ * This function is called by the VNC server whenever a mouse event occurs.
+ */
+static void kbd_handle_ptr(int buttonMask, int x, int y, rfbClientPtr cl)
+{
+	int dx, dy;
+	char b1 = 0x8;
+
+	/* The VNC mask and the PS/2 button encoding are the same */
+	b1 |= buttonMask;
+
+	if (xlast >= 0 && ylast >= 0) {
+		/* The PS/2 mouse sends deltas, not absolutes */
+		dx = x - xlast;
+		dy = ylast - y;
+
+		/* Set overflow bits if needed */
+		if (dy > 255)
+			b1 |= 0x80;
+		if (dx > 255)
+			b1 |= 0x40;
+
+		/* Set negative bits if needed */
+		if (dy < 0)
+			b1 |= 0x20;
+		if (dx < 0)
+			b1 |= 0x10;
+
+		mouse_queue(b1);
+		mouse_queue(dx);
+		mouse_queue(dy);
+	}
+
+	xlast = x;
+	ylast = y;
+	rfbDefaultPtrAddEvent(buttonMask, x, y, cl);
+}
+
+static void *vnc__thread(void *p)
+{
+	struct framebuffer *fb = p;
+	/*
+	 * Make a fake argc and argv because the getscreen function
+	 * seems to want it.
+	 */
+	char argv[1][1] = {{0}};
+	int argc = 1;
+
+	server = rfbGetScreen(&argc, (char **) argv, fb->width, fb->height, 8, 3, 4);
+	server->frameBuffer		= fb->mem;
+	server->alwaysShared		= TRUE;
+	server->kbdAddEvent		= kbd_handle_key;
+	server->ptrAddEvent		= kbd_handle_ptr;
+	rfbInitServer(server);
+
+	while (rfbIsActive(server)) {
+		rfbMarkRectAsModified(server, 0, 0, fb->width, fb->height);
+		rfbProcessEvents(server, server->deferUpdateTime * VESA_UPDATE_TIME);
+	}
+	return NULL;
+}
+
+static int vnc__start(struct framebuffer *fb)
+{
+	pthread_t thread;
+
+	if (pthread_create(&thread, NULL, vnc__thread, fb) != 0)
+		return -1;
+
+	return 0;
+}
+
+static int vnc__stop(struct framebuffer *fb)
+{
+	rfbShutdownServer(server, TRUE);
+
+	return 0;
+}
+
+static struct fb_target_operations vnc_ops = {
+	.start	= vnc__start,
+	.stop	= vnc__stop,
+};
+
+int vnc__init(struct framebuffer *fb)
+{
+	return fb__attach(fb, &vnc_ops);
+}
+
+int vnc__exit(struct framebuffer *fb)
+{
+	return vnc__stop(fb);
+}
\ No newline at end of file
diff --git a/tools/kvm/util/KVMTOOLS-VERSION-GEN b/tools/kvm/util/KVMTOOLS-VERSION-GEN
new file mode 100755
index 0000000..1af9d6c
--- /dev/null
+++ b/tools/kvm/util/KVMTOOLS-VERSION-GEN
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+if [ $# -eq 1 ]  ; then
+	OUTPUT=$1
+fi
+
+GVF=${OUTPUT}KVMTOOLS-VERSION-FILE
+
+LF='
+'
+
+# First check if there is a .git to get the version from git describe
+# otherwise try to get the version from the kernel makefile
+if test -d ../../.git -o -f ../../.git &&
+	VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
+	case "$VN" in
+	*$LF*) (exit 1) ;;
+	v[0-9]*)
+		git update-index -q --refresh
+		test -z "$(git diff-index --name-only HEAD --)" ||
+		VN="$VN-dirty" ;;
+	esac
+then
+	VN=$(echo "$VN" | sed -e 's/-/./g');
+else
+	VN=$(MAKEFLAGS= make -sC ../.. kernelversion)
+fi
+
+VN=$(expr "$VN" : v*'\(.*\)')
+
+if test -r $GVF
+then
+	VC=$(sed -e 's/^KVMTOOLS_VERSION = //' <$GVF)
+else
+	VC=unset
+fi
+test "$VN" = "$VC" || {
+	echo >&2 "KVMTOOLS_VERSION = $VN"
+	echo "KVMTOOLS_VERSION = $VN" >$GVF
+}
diff --git a/tools/kvm/util/generate-cmdlist.sh b/tools/kvm/util/generate-cmdlist.sh
new file mode 100755
index 0000000..c8be0bd
--- /dev/null
+++ b/tools/kvm/util/generate-cmdlist.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+echo "/* Automatically generated by $0 */
+struct cmdname_help
+{
+    char name[16];
+    char help[80];
+};
+
+static struct cmdname_help common_cmds[] = {"
+
+sed -n 's/^lkvm-\([^ \t]*\).*common/\1/p' command-list.txt |
+while read cmd
+do
+	 # TODO following sed command should be fixed
+     sed -n '/^NAME/,/^lkvm-'"$cmd"'/ {
+		 /NAME/d
+		 /--/d
+		 s/.*kvm-'"$cmd"' - \(.*\)/  {"'"$cmd"'", "\1"},/
+	     p
+	 }' "Documentation/kvm-$cmd.txt"
+done
+echo "};"
diff --git a/tools/kvm/util/kvm-ifup-vbr0 b/tools/kvm/util/kvm-ifup-vbr0
new file mode 100755
index 0000000..a91c37f
--- /dev/null
+++ b/tools/kvm/util/kvm-ifup-vbr0
@@ -0,0 +1,6 @@
+#!/bin/sh
+switch=vbr0
+/sbin/ifconfig $1 0.0.0.0 up
+/usr/sbin/brctl addif ${switch} $1
+/usr/sbin/brctl setfd ${switch} 0
+/usr/sbin/brctl stp ${switch} off
diff --git a/tools/kvm/util/parse-options.c b/tools/kvm/util/parse-options.c
new file mode 100644
index 0000000..9a1bbee
--- /dev/null
+++ b/tools/kvm/util/parse-options.c
@@ -0,0 +1,577 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <stdbool.h>
+
+/* user defined includes */
+#include <linux/types.h>
+#include <kvm/util.h>
+#include <kvm/parse-options.h>
+#include <kvm/strbuf.h>
+
+#define OPT_SHORT 1
+#define OPT_UNSET 2
+
+static int opterror(const struct option *opt, const char *reason, int flags)
+{
+	if (flags & OPT_SHORT)
+		return pr_err("switch `%c' %s", opt->short_name, reason);
+	if (flags & OPT_UNSET)
+		return pr_err("option `no-%s' %s", opt->long_name, reason);
+	return pr_err("option `%s' %s", opt->long_name, reason);
+}
+
+static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
+		int flags, const char **arg)
+{
+	if (p->opt) {
+		*arg = p->opt;
+		p->opt = NULL;
+	} else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
+				**(p->argv + 1) == '-')) {
+		*arg = (const char *)opt->defval;
+	} else if (p->argc > 1) {
+		p->argc--;
+		*arg = *++p->argv;
+	} else
+		return opterror(opt, "requires a value", flags);
+	return 0;
+}
+
+static int readnum(const struct option *opt, int flags,
+		   const char *str, char **end)
+{
+	switch (opt->type) {
+	case OPTION_INTEGER:
+		*(int *)opt->value = strtol(str, end, 0);
+		break;
+	case OPTION_UINTEGER:
+		*(unsigned int *)opt->value = strtol(str, end, 0);
+		break;
+	case OPTION_LONG:
+		*(long *)opt->value = strtol(str, end, 0);
+		break;
+	case OPTION_U64:
+		*(u64 *)opt->value = strtoull(str, end, 0);
+		break;
+	default:
+		return opterror(opt, "invalid numeric conversion", flags);
+	}
+
+	return 0;
+}
+
+static int get_value(struct parse_opt_ctx_t *p,
+		const struct option *opt, int flags)
+{
+	const char *s, *arg = NULL;
+	const int unset = flags & OPT_UNSET;
+
+	if (unset && p->opt)
+		return opterror(opt, "takes no value", flags);
+	if (unset && (opt->flags & PARSE_OPT_NONEG))
+		return opterror(opt, "isn't available", flags);
+
+	if (!(flags & OPT_SHORT) && p->opt) {
+		switch (opt->type) {
+		case OPTION_CALLBACK:
+			if (!(opt->flags & PARSE_OPT_NOARG))
+				break;
+		/* FALLTHROUGH */
+		case OPTION_BOOLEAN:
+		case OPTION_INCR:
+		case OPTION_BIT:
+		case OPTION_SET_UINT:
+		case OPTION_SET_PTR:
+			return opterror(opt, "takes no value", flags);
+		case OPTION_END:
+		case OPTION_ARGUMENT:
+		case OPTION_GROUP:
+		case OPTION_STRING:
+		case OPTION_INTEGER:
+		case OPTION_UINTEGER:
+		case OPTION_LONG:
+		case OPTION_U64:
+		default:
+			break;
+		}
+	}
+
+	switch (opt->type) {
+	case OPTION_BIT:
+		if (unset)
+			*(int *)opt->value &= ~opt->defval;
+		else
+			*(int *)opt->value |= opt->defval;
+		return 0;
+
+	case OPTION_BOOLEAN:
+		*(bool *)opt->value = unset ? false : true;
+		return 0;
+
+	case OPTION_INCR:
+		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
+		return 0;
+
+	case OPTION_SET_UINT:
+		*(unsigned int *)opt->value = unset ? 0 : opt->defval;
+		return 0;
+
+	case OPTION_SET_PTR:
+		*(void **)opt->value = unset ? NULL : (void *)opt->defval;
+		return 0;
+
+	case OPTION_STRING:
+		if (unset)
+			*(const char **)opt->value = NULL;
+		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
+			*(const char **)opt->value = (const char *)opt->defval;
+		else
+			return get_arg(p, opt, flags,
+					(const char **)opt->value);
+		return 0;
+
+	case OPTION_CALLBACK:
+		if (unset)
+			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
+		if (opt->flags & PARSE_OPT_NOARG)
+			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
+		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
+			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
+		if (get_arg(p, opt, flags, &arg))
+			return -1;
+		return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
+
+	case OPTION_INTEGER:
+		if (unset) {
+			*(int *)opt->value = 0;
+			return 0;
+		}
+		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+			*(int *)opt->value = opt->defval;
+			return 0;
+		}
+		if (get_arg(p, opt, flags, &arg))
+			return -1;
+		return readnum(opt, flags, arg, (char **)&s);
+
+	case OPTION_UINTEGER:
+		if (unset) {
+			*(unsigned int *)opt->value = 0;
+			return 0;
+		}
+		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+			*(unsigned int *)opt->value = opt->defval;
+			return 0;
+		}
+		if (get_arg(p, opt, flags, &arg))
+			return -1;
+		return readnum(opt, flags, arg, (char **)&s);
+
+	case OPTION_LONG:
+		if (unset) {
+			*(long *)opt->value = 0;
+			return 0;
+		}
+		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+			*(long *)opt->value = opt->defval;
+			return 0;
+		}
+		if (get_arg(p, opt, flags, &arg))
+			return -1;
+		return readnum(opt, flags, arg, (char **)&s);
+
+	case OPTION_U64:
+		if (unset) {
+			*(u64 *)opt->value = 0;
+			return 0;
+		}
+		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+			*(u64 *)opt->value = opt->defval;
+			return 0;
+		}
+		if (get_arg(p, opt, flags, &arg))
+			return -1;
+		return readnum(opt, flags, arg, (char **)&s);
+
+	case OPTION_END:
+	case OPTION_ARGUMENT:
+	case OPTION_GROUP:
+	default:
+		die("should not happen, someone must be hit on the forehead");
+	}
+}
+
+#define USAGE_OPTS_WIDTH 24
+#define USAGE_GAP         2
+
+static int usage_with_options_internal(const char * const *usagestr,
+		const struct option *opts, int full)
+{
+	if (!usagestr)
+		return PARSE_OPT_HELP;
+
+	fprintf(stderr, "\n usage: %s\n", *usagestr++);
+	while (*usagestr && **usagestr)
+		fprintf(stderr, "    or: %s\n", *usagestr++);
+	while (*usagestr) {
+		fprintf(stderr, "%s%s\n",
+				**usagestr ? "    " : "",
+				*usagestr);
+		usagestr++;
+	}
+
+	if (opts->type != OPTION_GROUP)
+		fputc('\n', stderr);
+
+	for (; opts->type != OPTION_END; opts++) {
+		size_t pos;
+		int pad;
+
+		if (opts->type == OPTION_GROUP) {
+			fputc('\n', stderr);
+			if (*opts->help)
+				fprintf(stderr, "%s\n", opts->help);
+			continue;
+		}
+		if (!full && (opts->flags & PARSE_OPT_HIDDEN))
+			continue;
+
+		pos = fprintf(stderr, "    ");
+		if (opts->short_name)
+			pos += fprintf(stderr, "-%c", opts->short_name);
+		else
+			pos += fprintf(stderr, "    ");
+
+		if (opts->long_name && opts->short_name)
+			pos += fprintf(stderr, ", ");
+		if (opts->long_name)
+			pos += fprintf(stderr, "--%s", opts->long_name);
+
+		switch (opts->type) {
+		case OPTION_ARGUMENT:
+			break;
+		case OPTION_LONG:
+		case OPTION_U64:
+		case OPTION_INTEGER:
+		case OPTION_UINTEGER:
+			if (opts->flags & PARSE_OPT_OPTARG)
+				if (opts->long_name)
+					pos += fprintf(stderr, "[=<n>]");
+				else
+					pos += fprintf(stderr, "[<n>]");
+			else
+				pos += fprintf(stderr, " <n>");
+			break;
+		case OPTION_CALLBACK:
+			if (opts->flags & PARSE_OPT_NOARG)
+				break;
+		/* FALLTHROUGH */
+		case OPTION_STRING:
+			if (opts->argh) {
+				if (opts->flags & PARSE_OPT_OPTARG)
+					if (opts->long_name)
+						pos += fprintf(stderr, "[=<%s>]", opts->argh);
+					else
+						pos += fprintf(stderr, "[<%s>]", opts->argh);
+				else
+					pos += fprintf(stderr, " <%s>", opts->argh);
+			} else {
+				if (opts->flags & PARSE_OPT_OPTARG)
+					if (opts->long_name)
+						pos += fprintf(stderr, "[=...]");
+					else
+						pos += fprintf(stderr, "[...]");
+				else
+					pos += fprintf(stderr, " ...");
+			}
+				break;
+		default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
+		case OPTION_END:
+		case OPTION_GROUP:
+		case OPTION_BIT:
+		case OPTION_BOOLEAN:
+		case OPTION_INCR:
+		case OPTION_SET_UINT:
+		case OPTION_SET_PTR:
+			break;
+		}
+		if (pos <= USAGE_OPTS_WIDTH)
+			pad = USAGE_OPTS_WIDTH - pos;
+		else {
+			fputc('\n', stderr);
+			pad = USAGE_OPTS_WIDTH;
+		}
+		fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
+	}
+	fputc('\n', stderr);
+
+	return PARSE_OPT_HELP;
+}
+
+void usage_with_options(const char * const *usagestr,
+		const struct option *opts)
+{
+	usage_with_options_internal(usagestr, opts, 0);
+	exit(129);
+}
+
+static void check_typos(const char *arg, const struct option *options)
+{
+	if (strlen(arg) < 3)
+		return;
+
+	if (!prefixcmp(arg, "no-")) {
+		pr_err("did you mean `--%s` (with two dashes ?)", arg);
+		exit(129);
+	}
+
+	for (; options->type != OPTION_END; options++) {
+		if (!options->long_name)
+			continue;
+		if (!prefixcmp(options->long_name, arg)) {
+			pr_err("did you mean `--%s` (with two dashes ?)", arg);
+			exit(129);
+		}
+	}
+}
+
+static int parse_options_usage(const char * const *usagestr,
+		const struct option *opts)
+{
+	return usage_with_options_internal(usagestr, opts, 0);
+}
+
+static int parse_short_opt(struct parse_opt_ctx_t *p,
+        const struct option *options)
+{
+	for (; options->type != OPTION_END; options++) {
+		if (options->short_name == *p->opt) {
+			p->opt = p->opt[1] ? p->opt + 1 : NULL;
+			return get_value(p, options, OPT_SHORT);
+		}
+	}
+	return -2;
+}
+
+static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
+		const struct option *options)
+{
+	const char *arg_end = strchr(arg, '=');
+	const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
+	int abbrev_flags = 0, ambiguous_flags = 0;
+
+	if (!arg_end)
+		arg_end = arg + strlen(arg);
+
+	for (; options->type != OPTION_END; options++) {
+		const char *rest;
+		int flags = 0;
+
+		if (!options->long_name)
+			continue;
+
+		rest = skip_prefix(arg, options->long_name);
+		if (options->type == OPTION_ARGUMENT) {
+			if (!rest)
+				continue;
+			if (*rest == '=')
+				return opterror(options, "takes no value",
+						flags);
+			if (*rest)
+				continue;
+			p->out[p->cpidx++] = arg - 2;
+			return 0;
+		}
+		if (!rest) {
+			/* abbreviated? */
+			if (!strncmp(options->long_name, arg, arg_end - arg)) {
+is_abbreviated:
+				if (abbrev_option) {
+					/*
+					 * If this is abbreviated, it is
+					 * ambiguous. So when there is no
+					 * exact match later, we need to
+					 * error out.
+					 */
+					ambiguous_option = abbrev_option;
+					ambiguous_flags = abbrev_flags;
+				}
+				if (!(flags & OPT_UNSET) && *arg_end)
+					p->opt = arg_end + 1;
+				abbrev_option = options;
+				abbrev_flags = flags;
+				continue;
+			}
+			/* negated and abbreviated very much? */
+			if (!prefixcmp("no-", arg)) {
+				flags |= OPT_UNSET;
+				goto is_abbreviated;
+			}
+			/* negated? */
+			if (strncmp(arg, "no-", 3))
+				continue;
+			flags |= OPT_UNSET;
+			rest = skip_prefix(arg + 3, options->long_name);
+			/* abbreviated and negated? */
+			if (!rest && !prefixcmp(options->long_name, arg + 3))
+				goto is_abbreviated;
+			if (!rest)
+				continue;
+		}
+		if (*rest) {
+			if (*rest != '=')
+				continue;
+			p->opt = rest + 1;
+		}
+		return get_value(p, options, flags);
+	}
+
+	if (ambiguous_option)
+		return pr_err("Ambiguous option: %s "
+				"(could be --%s%s or --%s%s)",
+				arg,
+				(ambiguous_flags & OPT_UNSET) ?  "no-" : "",
+				ambiguous_option->long_name,
+				(abbrev_flags & OPT_UNSET) ?  "no-" : "",
+				abbrev_option->long_name);
+	if (abbrev_option)
+		return get_value(p, abbrev_option, abbrev_flags);
+	return -2;
+}
+
+
+static void parse_options_start(struct parse_opt_ctx_t *ctx, int argc,
+		const char **argv, int flags)
+{
+	memset(ctx, 0, sizeof(*ctx));
+	ctx->argc = argc;
+	ctx->argv = argv;
+	ctx->out  = argv;
+	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
+	ctx->flags = flags;
+	if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
+			(flags & PARSE_OPT_STOP_AT_NON_OPTION))
+		die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
+}
+
+static int parse_options_end(struct parse_opt_ctx_t *ctx)
+{
+	memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
+	ctx->out[ctx->cpidx + ctx->argc] = NULL;
+	return ctx->cpidx + ctx->argc;
+}
+
+
+static int parse_options_step(struct parse_opt_ctx_t *ctx,
+		const struct option *options, const char * const usagestr[])
+{
+	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
+
+	/* we must reset ->opt, unknown short option leave it dangling */
+	ctx->opt = NULL;
+
+	for (; ctx->argc; ctx->argc--, ctx->argv++) {
+		const char *arg = ctx->argv[0];
+
+		if (*arg != '-' || !arg[1]) {
+			if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
+				break;
+			ctx->out[ctx->cpidx++] = ctx->argv[0];
+			continue;
+		}
+
+		if (arg[1] != '-') {
+			ctx->opt = arg + 1;
+			if (internal_help && *ctx->opt == 'h')
+				return parse_options_usage(usagestr, options);
+			switch (parse_short_opt(ctx, options)) {
+			case -1:
+				return parse_options_usage(usagestr, options);
+			case -2:
+				goto unknown;
+			default:
+				break;
+			}
+			if (ctx->opt)
+				check_typos(arg + 1, options);
+			while (ctx->opt) {
+				if (internal_help && *ctx->opt == 'h')
+					return parse_options_usage(usagestr,
+							options);
+				switch (parse_short_opt(ctx, options)) {
+				case -1:
+					return parse_options_usage(usagestr,
+							options);
+				case -2:
+					/* fake a short option thing to hide
+					 * the fact that we may have
+					 * started to parse aggregated stuff
+					 *
+					 * This is leaky, too bad.
+					 */
+					ctx->argv[0] = strdup(ctx->opt - 1);
+					*(char *)ctx->argv[0] = '-';
+					goto unknown;
+				default:
+					break;
+				}
+			}
+			continue;
+		}
+
+		if (!arg[2]) { /* "--" */
+			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
+				ctx->argc--;
+				ctx->argv++;
+			}
+			break;
+		}
+
+		if (internal_help && !strcmp(arg + 2, "help-all"))
+			return usage_with_options_internal(usagestr, options,
+					1);
+		if (internal_help && !strcmp(arg + 2, "help"))
+			return parse_options_usage(usagestr, options);
+		switch (parse_long_opt(ctx, arg + 2, options)) {
+		case -1:
+			return parse_options_usage(usagestr, options);
+		case -2:
+			goto unknown;
+		default:
+			break;
+		}
+		continue;
+unknown:
+		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
+			return PARSE_OPT_UNKNOWN;
+		ctx->out[ctx->cpidx++] = ctx->argv[0];
+		ctx->opt = NULL;
+	}
+	return PARSE_OPT_DONE;
+}
+
+int parse_options(int argc, const char **argv, const struct option *options,
+		const char * const usagestr[], int flags)
+{
+	struct parse_opt_ctx_t ctx;
+
+	parse_options_start(&ctx, argc, argv, flags);
+	switch (parse_options_step(&ctx, options, usagestr)) {
+	case PARSE_OPT_HELP:
+		exit(129);
+	case PARSE_OPT_DONE:
+		break;
+	default: /* PARSE_OPT_UNKNOWN */
+		if (ctx.argv[0][1] == '-') {
+			pr_err("unknown option `%s'", ctx.argv[0] + 2);
+		} else {
+			pr_err("unknown switch `%c'", *ctx.opt);
+		}
+		usage_with_options(usagestr, options);
+	}
+
+	return parse_options_end(&ctx);
+}
diff --git a/tools/kvm/util/rbtree-interval.c b/tools/kvm/util/rbtree-interval.c
new file mode 100644
index 0000000..f9bf4b8
--- /dev/null
+++ b/tools/kvm/util/rbtree-interval.c
@@ -0,0 +1,89 @@
+#include <kvm/rbtree-interval.h>
+#include <stddef.h>
+#include <errno.h>
+
+struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point)
+{
+	struct rb_node *node = root->rb_node;
+	struct rb_node *lowest = NULL;
+
+	while (node) {
+		struct rb_int_node *cur = rb_int(node);
+
+		if (node->rb_left && (rb_int(node->rb_left)->max_high > point)) {
+			node = node->rb_left;
+		} else if (cur->low <= point && cur->high > point) {
+			lowest = node;
+			break;
+		} else if (point > cur->low) {
+			node = node->rb_right;
+		} else {
+			break;
+		}
+	}
+
+	if (lowest == NULL)
+		return NULL;
+
+	return rb_int(lowest);
+}
+
+struct rb_int_node *rb_int_search_range(struct rb_root *root, u64 low, u64 high)
+{
+	struct rb_int_node *range;
+
+	range = rb_int_search_single(root, low);
+	if (range == NULL)
+		return NULL;
+
+	/* We simply verify that 'high' is smaller than the end of the range where 'low' is located */
+	if (range->high < high)
+		return NULL;
+
+	return range;
+}
+
+static void update_node_max_high(struct rb_node *node, void *arg)
+{
+	struct rb_int_node *i_node = rb_int(node);
+
+	i_node->max_high = i_node->high;
+
+	if (node->rb_left)
+		i_node->max_high = max(i_node->max_high, rb_int(node->rb_left)->max_high);
+	if (node->rb_right)
+		i_node->max_high = max(i_node->max_high, rb_int(node->rb_right)->max_high);
+}
+
+int rb_int_insert(struct rb_root *root, struct rb_int_node *i_node)
+{
+	struct rb_node **node = &(root->rb_node), *parent = NULL;
+
+	while (*node) {
+		int result = i_node->low - rb_int(*node)->low;
+
+		parent = *node;
+		if (result < 0)
+			node	= &((*node)->rb_left);
+		else if (result > 0)
+			node	= &((*node)->rb_right);
+		else
+			return -EEXIST;
+	}
+
+	rb_link_node(&i_node->node, parent, node);
+	rb_insert_color(&i_node->node, root);
+
+	rb_augment_insert(&i_node->node, update_node_max_high, NULL);
+	return 0;
+}
+
+void rb_int_erase(struct rb_root *root, struct rb_int_node *node)
+{
+	struct rb_node *deepest;
+
+	deepest = rb_augment_erase_begin(&node->node);
+	rb_erase(&node->node, root);
+	rb_augment_erase_end(deepest, update_node_max_high, NULL);
+
+}
diff --git a/tools/kvm/util/read-write.c b/tools/kvm/util/read-write.c
new file mode 100644
index 0000000..55473ba
--- /dev/null
+++ b/tools/kvm/util/read-write.c
@@ -0,0 +1,344 @@
+#include "kvm/read-write.h"
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+/* Same as read(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xread(int fd, void *buf, size_t count)
+{
+	ssize_t nr;
+
+restart:
+	nr = read(fd, buf, count);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+/* Same as write(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xwrite(int fd, const void *buf, size_t count)
+{
+	ssize_t nr;
+
+restart:
+	nr = write(fd, buf, count);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+ssize_t read_in_full(int fd, void *buf, size_t count)
+{
+	ssize_t total = 0;
+	char *p = buf;
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xread(fd, p, count);
+		if (nr <= 0) {
+			if (total > 0)
+				return total;
+
+			return -1;
+		}
+
+		count -= nr;
+		total += nr;
+		p += nr;
+	}
+
+	return total;
+}
+
+ssize_t write_in_full(int fd, const void *buf, size_t count)
+{
+	const char *p = buf;
+	ssize_t total = 0;
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xwrite(fd, p, count);
+		if (nr < 0)
+			return -1;
+		if (nr == 0) {
+			errno = ENOSPC;
+			return -1;
+		}
+		count -= nr;
+		total += nr;
+		p += nr;
+	}
+
+	return total;
+}
+
+/* Same as pread(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xpread(int fd, void *buf, size_t count, off_t offset)
+{
+	ssize_t nr;
+
+restart:
+	nr = pread(fd, buf, count, offset);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+/* Same as pwrite(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+	ssize_t nr;
+
+restart:
+	nr = pwrite(fd, buf, count, offset);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset)
+{
+	ssize_t total = 0;
+	char *p = buf;
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xpread(fd, p, count, offset);
+		if (nr <= 0) {
+			if (total > 0)
+				return total;
+
+			return -1;
+		}
+
+		count -= nr;
+		total += nr;
+		p += nr;
+		offset += nr;
+	}
+
+	return total;
+}
+
+ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset)
+{
+	const char *p = buf;
+	ssize_t total = 0;
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xpwrite(fd, p, count, offset);
+		if (nr < 0)
+			return -1;
+		if (nr == 0) {
+			errno = ENOSPC;
+			return -1;
+		}
+		count -= nr;
+		total += nr;
+		p += nr;
+		offset += nr;
+	}
+
+	return total;
+}
+
+/* Same as readv(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt)
+{
+	ssize_t nr;
+
+restart:
+	nr = readv(fd, iov, iovcnt);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+/* Same as writev(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt)
+{
+	ssize_t nr;
+
+restart:
+	nr = writev(fd, iov, iovcnt);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+static inline ssize_t get_iov_size(const struct iovec *iov, int iovcnt)
+{
+	size_t size = 0;
+	while (iovcnt--)
+		size += (iov++)->iov_len;
+
+	return size;
+}
+
+static inline void shift_iovec(const struct iovec **iov, int *iovcnt,
+				size_t nr, ssize_t *total, size_t *count, off_t *offset)
+{
+	while (nr >= (*iov)->iov_len) {
+		nr -= (*iov)->iov_len;
+		*total += (*iov)->iov_len;
+		*count -= (*iov)->iov_len;
+		if (offset)
+			*offset += (*iov)->iov_len;
+		(*iovcnt)--;
+		(*iov)++;
+	}
+}
+
+ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt)
+{
+	ssize_t total = 0;
+	size_t count = get_iov_size(iov, iovcnt);
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xreadv(fd, iov, iovcnt);
+		if (nr <= 0) {
+			if (total > 0)
+				return total;
+
+			return -1;
+		}
+
+		shift_iovec(&iov, &iovcnt, nr, &total, &count, NULL);
+	}
+
+	return total;
+}
+
+ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt)
+{
+	ssize_t total = 0;
+	size_t count = get_iov_size(iov, iovcnt);
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xwritev(fd, iov, iovcnt);
+		if (nr < 0)
+			return -1;
+		if (nr == 0) {
+			errno = ENOSPC;
+			return -1;
+		}
+
+		shift_iovec(&iov, &iovcnt, nr, &total, &count, NULL);
+	}
+
+	return total;
+}
+
+/* Same as preadv(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+	ssize_t nr;
+
+restart:
+	nr = preadv(fd, iov, iovcnt, offset);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+/* Same as pwritev(2) except that this function never returns EAGAIN or EINTR. */
+ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+	ssize_t nr;
+
+restart:
+	nr = pwritev(fd, iov, iovcnt, offset);
+	if ((nr < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+		goto restart;
+
+	return nr;
+}
+
+ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+	ssize_t total = 0;
+	size_t count = get_iov_size(iov, iovcnt);
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xpreadv(fd, iov, iovcnt, offset);
+		if (nr <= 0) {
+			if (total > 0)
+				return total;
+
+			return -1;
+		}
+
+		shift_iovec(&iov, &iovcnt, nr, &total, &count, &offset);
+	}
+
+	return total;
+}
+
+ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset)
+{
+	ssize_t total = 0;
+	size_t count = get_iov_size(iov, iovcnt);
+
+	while (count > 0) {
+		ssize_t nr;
+
+		nr = xpwritev(fd, iov, iovcnt, offset);
+		if (nr < 0)
+			return -1;
+		if (nr == 0) {
+			errno = ENOSPC;
+			return -1;
+		}
+
+		shift_iovec(&iov, &iovcnt, nr, &total, &count, &offset);
+	}
+
+	return total;
+}
+
+#ifdef CONFIG_HAS_AIO
+int aio_pwritev(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt,
+		off_t offset, int ev, void *param)
+{
+	struct iocb *ios[1] = { iocb };
+
+	io_prep_pwritev(iocb, fd, iov, iovcnt, offset);
+	io_set_eventfd(iocb, ev);
+	iocb->data = param;
+
+	return io_submit(ctx, 1, ios);
+}
+
+int aio_preadv(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt,
+		off_t offset, int ev, void *param)
+{
+	struct iocb *ios[1] = { iocb };
+
+	io_prep_preadv(iocb, fd, iov, iovcnt, offset);
+	io_set_eventfd(iocb, ev);
+	iocb->data = param;
+
+	return io_submit(ctx, 1, ios);
+}
+#endif
\ No newline at end of file
diff --git a/tools/kvm/util/set_private_br.sh b/tools/kvm/util/set_private_br.sh
new file mode 100755
index 0000000..49867dd
--- /dev/null
+++ b/tools/kvm/util/set_private_br.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Author: Amos Kong <kongjianjun@gmail.com>
+# Date: Apr 14, 2011
+# Description: this script is used to create/delete a private bridge,
+# launch a dhcp server on the bridge by dnsmasq.
+#
+# @ ./set_private_br.sh $bridge_name $subnet_prefix
+# @ ./set_private_br.sh vbr0 192.168.33
+
+brname='vbr0'
+subnet='192.168.33'
+
+add_br()
+{
+    echo "add new private bridge: $brname"
+    /usr/sbin/brctl addbr $brname
+    echo 1 > /proc/sys/net/ipv6/conf/$brname/disable_ipv6
+    echo 1 > /proc/sys/net/ipv4/ip_forward
+    /usr/sbin/brctl stp $brname on
+    /usr/sbin/brctl setfd $brname 0
+    ifconfig $brname $subnet.1
+    ifconfig $brname up
+    # Add forward rule, then guest can access public network
+    iptables -t nat -A POSTROUTING -s $subnet.254/24 ! -d $subnet.254/24 -j MASQUERADE
+    /etc/init.d/dnsmasq stop
+    /etc/init.d/tftpd-hpa stop 2>/dev/null
+    dnsmasq --strict-order --bind-interfaces --listen-address $subnet.1 --dhcp-range $subnet.1,$subnet.254 $tftp_cmd
+}
+
+del_br()
+{
+    echo "cleanup bridge setup"
+    kill -9 `pgrep dnsmasq|tail -1`
+    ifconfig $brname down
+    /usr/sbin/brctl delbr $brname
+    iptables -t nat -D POSTROUTING -s $subnet.254/24 ! -d $subnet.254/24 -j MASQUERADE
+}
+
+
+if [ $# = 0 ]; then
+    del_br 2>/dev/null
+    exit
+fi
+if [ $# > 1 ]; then
+    brname="$1"
+fi
+if [ $# = 2 ]; then
+    subnet="$2"
+fi
+add_br
diff --git a/tools/kvm/util/strbuf.c b/tools/kvm/util/strbuf.c
new file mode 100644
index 0000000..6632a14
--- /dev/null
+++ b/tools/kvm/util/strbuf.c
@@ -0,0 +1,39 @@
+
+/* user defined headers */
+#include <kvm/util.h>
+#include <kvm/strbuf.h>
+
+int prefixcmp(const char *str, const char *prefix)
+{
+	for (; ; str++, prefix++) {
+		if (!*prefix)
+			return 0;
+		else if (*str != *prefix)
+			return (unsigned char)*prefix - (unsigned char)*str;
+	}
+}
+
+/**
+ * strlcat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The size of the destination buffer.
+ */
+size_t strlcat(char *dest, const char *src, size_t count)
+{
+	size_t dsize = strlen(dest);
+	size_t len = strlen(src);
+	size_t res = dsize + len;
+
+	DIE_IF(dsize >= count);
+
+	dest += dsize;
+	count -= dsize;
+	if (len >= count)
+		len = count - 1;
+
+	memcpy(dest, src, len);
+	dest[len] = 0;
+
+	return res;
+}
diff --git a/tools/kvm/util/threadpool.c b/tools/kvm/util/threadpool.c
new file mode 100644
index 0000000..bafbcd7
--- /dev/null
+++ b/tools/kvm/util/threadpool.c
@@ -0,0 +1,145 @@
+#include "kvm/threadpool.h"
+#include "kvm/mutex.h"
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <pthread.h>
+#include <stdbool.h>
+
+static pthread_mutex_t	job_mutex	= PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t	thread_mutex	= PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t	job_cond	= PTHREAD_COND_INITIALIZER;
+
+static LIST_HEAD(head);
+
+static pthread_t	*threads;
+static long		threadcount;
+
+static struct thread_pool__job *thread_pool__job_pop_locked(void)
+{
+	struct thread_pool__job *job;
+
+	if (list_empty(&head))
+		return NULL;
+
+	job = list_first_entry(&head, struct thread_pool__job, queue);
+	list_del(&job->queue);
+
+	return job;
+}
+
+static void thread_pool__job_push_locked(struct thread_pool__job *job)
+{
+	list_add_tail(&job->queue, &head);
+}
+
+static struct thread_pool__job *thread_pool__job_pop(void)
+{
+	struct thread_pool__job *job;
+
+	mutex_lock(&job_mutex);
+	job = thread_pool__job_pop_locked();
+	mutex_unlock(&job_mutex);
+	return job;
+}
+
+static void thread_pool__job_push(struct thread_pool__job *job)
+{
+	mutex_lock(&job_mutex);
+	thread_pool__job_push_locked(job);
+	mutex_unlock(&job_mutex);
+}
+
+static void thread_pool__handle_job(struct thread_pool__job *job)
+{
+	while (job) {
+		job->callback(job->kvm, job->data);
+
+		mutex_lock(&job->mutex);
+
+		if (--job->signalcount > 0)
+			/* If the job was signaled again while we were working */
+			thread_pool__job_push(job);
+
+		mutex_unlock(&job->mutex);
+
+		job = thread_pool__job_pop();
+	}
+}
+
+static void thread_pool__threadfunc_cleanup(void *param)
+{
+	mutex_unlock(&job_mutex);
+}
+
+static void *thread_pool__threadfunc(void *param)
+{
+	pthread_cleanup_push(thread_pool__threadfunc_cleanup, NULL);
+
+	for (;;) {
+		struct thread_pool__job *curjob;
+
+		mutex_lock(&job_mutex);
+		while ((curjob = thread_pool__job_pop_locked()) == NULL)
+			pthread_cond_wait(&job_cond, &job_mutex);
+		mutex_unlock(&job_mutex);
+
+		thread_pool__handle_job(curjob);
+	}
+
+	pthread_cleanup_pop(0);
+
+	return NULL;
+}
+
+static int thread_pool__addthread(void)
+{
+	int res;
+	void *newthreads;
+
+	mutex_lock(&thread_mutex);
+	newthreads = realloc(threads, (threadcount + 1) * sizeof(pthread_t));
+	if (newthreads == NULL) {
+		mutex_unlock(&thread_mutex);
+		return -1;
+	}
+
+	threads = newthreads;
+
+	res = pthread_create(threads + threadcount, NULL,
+			     thread_pool__threadfunc, NULL);
+
+	if (res == 0)
+		threadcount++;
+	mutex_unlock(&thread_mutex);
+
+	return res;
+}
+
+int thread_pool__init(unsigned long thread_count)
+{
+	unsigned long i;
+
+	for (i = 0; i < thread_count; i++)
+		if (thread_pool__addthread() < 0)
+			return i;
+
+	return i;
+}
+
+void thread_pool__do_job(struct thread_pool__job *job)
+{
+	struct thread_pool__job *jobinfo = job;
+
+	if (jobinfo == NULL || jobinfo->callback == NULL)
+		return;
+
+	mutex_lock(&jobinfo->mutex);
+	if (jobinfo->signalcount++ == 0)
+		thread_pool__job_push(job);
+	mutex_unlock(&jobinfo->mutex);
+
+	mutex_lock(&job_mutex);
+	pthread_cond_signal(&job_cond);
+	mutex_unlock(&job_mutex);
+}
diff --git a/tools/kvm/util/util.c b/tools/kvm/util/util.c
new file mode 100644
index 0000000..e7feebc
--- /dev/null
+++ b/tools/kvm/util/util.c
@@ -0,0 +1,115 @@
+/*
+ * Taken from perf which in turn take it from GIT
+ */
+
+#include "kvm/util.h"
+
+#include <linux/magic.h>	/* For HUGETLBFS_MAGIC */
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+
+static void report(const char *prefix, const char *err, va_list params)
+{
+	char msg[1024];
+	vsnprintf(msg, sizeof(msg), err, params);
+	fprintf(stderr, " %s%s\n", prefix, msg);
+}
+
+static NORETURN void die_builtin(const char *err, va_list params)
+{
+	report(" Fatal: ", err, params);
+	exit(128);
+}
+
+static void error_builtin(const char *err, va_list params)
+{
+	report(" Error: ", err, params);
+}
+
+static void warn_builtin(const char *warn, va_list params)
+{
+	report(" Warning: ", warn, params);
+}
+
+static void info_builtin(const char *info, va_list params)
+{
+	report(" Info: ", info, params);
+}
+
+void die(const char *err, ...)
+{
+	va_list params;
+
+	va_start(params, err);
+	die_builtin(err, params);
+	va_end(params);
+}
+
+int pr_err(const char *err, ...)
+{
+	va_list params;
+
+	va_start(params, err);
+	error_builtin(err, params);
+	va_end(params);
+	return -1;
+}
+
+void pr_warning(const char *warn, ...)
+{
+	va_list params;
+
+	va_start(params, warn);
+	warn_builtin(warn, params);
+	va_end(params);
+}
+
+void pr_info(const char *info, ...)
+{
+	va_list params;
+
+	va_start(params, info);
+	info_builtin(info, params);
+	va_end(params);
+}
+
+void die_perror(const char *s)
+{
+	perror(s);
+	exit(1);
+}
+
+void *mmap_hugetlbfs(const char *htlbfs_path, u64 size)
+{
+	char mpath[PATH_MAX];
+	int fd;
+	struct statfs sfs;
+	void *addr;
+	unsigned long blk_size;
+
+	if (statfs(htlbfs_path, &sfs) < 0)
+		die("Can't stat %s\n", htlbfs_path);
+
+	if ((unsigned int)sfs.f_type != HUGETLBFS_MAGIC)
+		die("%s is not hugetlbfs!\n", htlbfs_path);
+
+	blk_size = (unsigned long)sfs.f_bsize;
+	if (sfs.f_bsize == 0 || blk_size > size) {
+		die("Can't use hugetlbfs pagesize %ld for mem size %lld\n",
+		    blk_size, size);
+	}
+
+	snprintf(mpath, PATH_MAX, "%s/kvmtoolXXXXXX", htlbfs_path);
+	fd = mkstemp(mpath);
+	if (fd < 0)
+		die("Can't open %s for hugetlbfs map\n", mpath);
+	unlink(mpath);
+	if (ftruncate(fd, size) < 0)
+		die("Can't ftruncate for mem mapping size %lld\n",
+		    size);
+	addr = mmap(NULL, size, PROT_RW, MAP_PRIVATE, fd, 0);
+	close(fd);
+
+	return addr;
+}
diff --git a/tools/kvm/virtio/9p-pdu.c b/tools/kvm/virtio/9p-pdu.c
new file mode 100644
index 0000000..b9ce8ce
--- /dev/null
+++ b/tools/kvm/virtio/9p-pdu.c
@@ -0,0 +1,287 @@
+#include "kvm/util.h"
+#include "kvm/virtio-9p.h"
+
+#include <endian.h>
+#include <stdint.h>
+
+#include <linux/compiler.h>
+#include <net/9p/9p.h>
+
+static void virtio_p9_pdu_read(struct p9_pdu *pdu, void *data, size_t size)
+{
+	size_t len;
+	int i, copied = 0;
+	u16 iov_cnt = pdu->out_iov_cnt;
+	size_t offset = pdu->read_offset;
+	struct iovec *iov = pdu->out_iov;
+
+	for (i = 0; i < iov_cnt && size; i++) {
+		if (offset >= iov[i].iov_len) {
+			offset -= iov[i].iov_len;
+			continue;
+		} else {
+			len = MIN(iov[i].iov_len - offset, size);
+			memcpy(data, iov[i].iov_base + offset, len);
+			size -= len;
+			data += len;
+			offset = 0;
+			copied += len;
+		}
+	}
+	pdu->read_offset += copied;
+}
+
+static void virtio_p9_pdu_write(struct p9_pdu *pdu,
+				const void *data, size_t size)
+{
+	size_t len;
+	int i, copied = 0;
+	u16 iov_cnt = pdu->in_iov_cnt;
+	size_t offset = pdu->write_offset;
+	struct iovec *iov = pdu->in_iov;
+
+	for (i = 0; i < iov_cnt && size; i++) {
+		if (offset >= iov[i].iov_len) {
+			offset -= iov[i].iov_len;
+			continue;
+		} else {
+			len = MIN(iov[i].iov_len - offset, size);
+			memcpy(iov[i].iov_base + offset, data, len);
+			size -= len;
+			data += len;
+			offset = 0;
+			copied += len;
+		}
+	}
+	pdu->write_offset += copied;
+}
+
+static void virtio_p9_wstat_free(struct p9_wstat *stbuf)
+{
+	free(stbuf->name);
+	free(stbuf->uid);
+	free(stbuf->gid);
+	free(stbuf->muid);
+}
+
+static int virtio_p9_decode(struct p9_pdu *pdu, const char *fmt, va_list ap)
+{
+	int retval = 0;
+	const char *ptr;
+
+	for (ptr = fmt; *ptr; ptr++) {
+		switch (*ptr) {
+		case 'b':
+		{
+			int8_t *val = va_arg(ap, int8_t *);
+			virtio_p9_pdu_read(pdu, val, sizeof(*val));
+		}
+		break;
+		case 'w':
+		{
+			int16_t le_val;
+			int16_t *val = va_arg(ap, int16_t *);
+			virtio_p9_pdu_read(pdu, &le_val, sizeof(le_val));
+			*val = le16toh(le_val);
+		}
+		break;
+		case 'd':
+		{
+			int32_t le_val;
+			int32_t *val = va_arg(ap, int32_t *);
+			virtio_p9_pdu_read(pdu, &le_val, sizeof(le_val));
+			*val = le32toh(le_val);
+		}
+		break;
+		case 'q':
+		{
+			int64_t le_val;
+			int64_t *val = va_arg(ap, int64_t *);
+			virtio_p9_pdu_read(pdu, &le_val, sizeof(le_val));
+			*val = le64toh(le_val);
+		}
+		break;
+		case 's':
+		{
+			int16_t len;
+			char **str = va_arg(ap, char **);
+
+			virtio_p9_pdu_readf(pdu, "w", &len);
+			*str = malloc(len + 1);
+			if (*str == NULL) {
+				retval = ENOMEM;
+				break;
+			}
+			virtio_p9_pdu_read(pdu, *str, len);
+			(*str)[len] = 0;
+		}
+		break;
+		case 'Q':
+		{
+			struct p9_qid *qid = va_arg(ap, struct p9_qid *);
+			retval = virtio_p9_pdu_readf(pdu, "bdq",
+						     &qid->type, &qid->version,
+						     &qid->path);
+		}
+		break;
+		case 'S':
+		{
+			struct p9_wstat *stbuf = va_arg(ap, struct p9_wstat *);
+			memset(stbuf, 0, sizeof(struct p9_wstat));
+			stbuf->n_uid = stbuf->n_gid = stbuf->n_muid = -1;
+			retval = virtio_p9_pdu_readf(pdu, "wwdQdddqssss",
+						&stbuf->size, &stbuf->type,
+						&stbuf->dev, &stbuf->qid,
+						&stbuf->mode, &stbuf->atime,
+						&stbuf->mtime, &stbuf->length,
+						&stbuf->name, &stbuf->uid,
+						&stbuf->gid, &stbuf->muid);
+			if (retval)
+				virtio_p9_wstat_free(stbuf);
+		}
+		break;
+		case 'I':
+		{
+			struct p9_iattr_dotl *p9attr = va_arg(ap,
+						       struct p9_iattr_dotl *);
+
+			retval = virtio_p9_pdu_readf(pdu, "ddddqqqqq",
+						     &p9attr->valid,
+						     &p9attr->mode,
+						     &p9attr->uid,
+						     &p9attr->gid,
+						     &p9attr->size,
+						     &p9attr->atime_sec,
+						     &p9attr->atime_nsec,
+						     &p9attr->mtime_sec,
+						     &p9attr->mtime_nsec);
+		}
+		break;
+		default:
+			retval = EINVAL;
+			break;
+		}
+	}
+	return retval;
+}
+
+static int virtio_p9_pdu_encode(struct p9_pdu *pdu, const char *fmt, va_list ap)
+{
+	int retval = 0;
+	const char *ptr;
+
+	for (ptr = fmt; *ptr; ptr++) {
+		switch (*ptr) {
+		case 'b':
+		{
+			int8_t val = va_arg(ap, int);
+			virtio_p9_pdu_write(pdu, &val, sizeof(val));
+		}
+		break;
+		case 'w':
+		{
+			int16_t val = htole16(va_arg(ap, int));
+			virtio_p9_pdu_write(pdu, &val, sizeof(val));
+		}
+		break;
+		case 'd':
+		{
+			int32_t val = htole32(va_arg(ap, int32_t));
+			virtio_p9_pdu_write(pdu, &val, sizeof(val));
+		}
+		break;
+		case 'q':
+		{
+			int64_t val = htole64(va_arg(ap, int64_t));
+			virtio_p9_pdu_write(pdu, &val, sizeof(val));
+		}
+		break;
+		case 's':
+		{
+			uint16_t len = 0;
+			const char *s = va_arg(ap, char *);
+			if (s)
+				len = MIN(strlen(s), USHRT_MAX);
+			virtio_p9_pdu_writef(pdu, "w", len);
+			virtio_p9_pdu_write(pdu, s, len);
+		}
+		break;
+		case 'Q':
+		{
+			struct p9_qid *qid = va_arg(ap, struct p9_qid *);
+			retval = virtio_p9_pdu_writef(pdu, "bdq",
+						      qid->type, qid->version,
+						      qid->path);
+		}
+		break;
+		case 'S':
+		{
+			struct p9_wstat *stbuf = va_arg(ap, struct p9_wstat *);
+			retval = virtio_p9_pdu_writef(pdu, "wwdQdddqssss",
+						stbuf->size, stbuf->type,
+						stbuf->dev, &stbuf->qid,
+						stbuf->mode, stbuf->atime,
+						stbuf->mtime, stbuf->length,
+						stbuf->name, stbuf->uid,
+						stbuf->gid, stbuf->muid);
+		}
+		break;
+		case 'A':
+		{
+			struct p9_stat_dotl *stbuf = va_arg(ap,
+						      struct p9_stat_dotl *);
+			retval  = virtio_p9_pdu_writef(pdu,
+						       "qQdddqqqqqqqqqqqqqqq",
+						       stbuf->st_result_mask,
+						       &stbuf->qid,
+						       stbuf->st_mode,
+						       stbuf->st_uid,
+						       stbuf->st_gid,
+						       stbuf->st_nlink,
+						       stbuf->st_rdev,
+						       stbuf->st_size,
+						       stbuf->st_blksize,
+						       stbuf->st_blocks,
+						       stbuf->st_atime_sec,
+						       stbuf->st_atime_nsec,
+						       stbuf->st_mtime_sec,
+						       stbuf->st_mtime_nsec,
+						       stbuf->st_ctime_sec,
+						       stbuf->st_ctime_nsec,
+						       stbuf->st_btime_sec,
+						       stbuf->st_btime_nsec,
+						       stbuf->st_gen,
+						       stbuf->st_data_version);
+		}
+		break;
+		default:
+			retval = EINVAL;
+			break;
+		}
+	}
+	return retval;
+}
+
+int virtio_p9_pdu_readf(struct p9_pdu *pdu, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	ret = virtio_p9_decode(pdu, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
+
+int virtio_p9_pdu_writef(struct p9_pdu *pdu, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	ret = virtio_p9_pdu_encode(pdu, fmt, ap);
+	va_end(ap);
+
+	return ret;
+}
diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c
new file mode 100644
index 0000000..28f5ed7
--- /dev/null
+++ b/tools/kvm/virtio/9p.c
@@ -0,0 +1,1326 @@
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/ioport.h"
+#include "kvm/util.h"
+#include "kvm/threadpool.h"
+#include "kvm/irq.h"
+#include "kvm/virtio-9p.h"
+#include "kvm/guest_compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/vfs.h>
+
+#include <linux/virtio_ring.h>
+#include <linux/virtio_9p.h>
+#include <net/9p/9p.h>
+
+static LIST_HEAD(devs);
+static int compat_id = -1;
+
+/* Warning: Immediately use value returned from this function */
+static const char *rel_to_abs(struct p9_dev *p9dev,
+			      const char *path, char *abs_path)
+{
+	sprintf(abs_path, "%s/%s", p9dev->root_dir, path);
+
+	return abs_path;
+}
+
+static void stat2qid(struct stat *st, struct p9_qid *qid)
+{
+	*qid = (struct p9_qid) {
+		.path		= st->st_ino,
+		.version	= st->st_mtime,
+	};
+
+	if (S_ISDIR(st->st_mode))
+		qid->type	|= P9_QTDIR;
+}
+
+static void close_fid(struct p9_dev *p9dev, u32 fid)
+{
+	if (p9dev->fids[fid].fd > 0) {
+		close(p9dev->fids[fid].fd);
+		p9dev->fids[fid].fd = -1;
+	}
+	if (p9dev->fids[fid].dir) {
+		closedir(p9dev->fids[fid].dir);
+		p9dev->fids[fid].dir = NULL;
+	}
+	p9dev->fids[fid].fid = P9_NOFID;
+}
+
+static void virtio_p9_set_reply_header(struct p9_pdu *pdu, u32 size)
+{
+	u8 cmd;
+	u16 tag;
+
+	pdu->read_offset = sizeof(u32);
+	virtio_p9_pdu_readf(pdu, "bw", &cmd, &tag);
+	pdu->write_offset = 0;
+	/* cmd + 1 is the reply message */
+	virtio_p9_pdu_writef(pdu, "dbw", size, cmd + 1, tag);
+}
+
+static u16 virtio_p9_update_iov_cnt(struct iovec iov[], u32 count, int iov_cnt)
+{
+	int i;
+	u32 total = 0;
+	for (i = 0; (i < iov_cnt) && (total < count); i++) {
+		if (total + iov[i].iov_len > count) {
+			/* we don't need this iov fully */
+			iov[i].iov_len -= ((total + iov[i].iov_len) - count);
+			i++;
+			break;
+		}
+		total += iov[i].iov_len;
+	}
+	return i;
+}
+
+static void virtio_p9_error_reply(struct p9_dev *p9dev,
+				  struct p9_pdu *pdu, int err, u32 *outlen)
+{
+	u16 tag;
+
+	pdu->write_offset = VIRTIO_P9_HDR_LEN;
+	virtio_p9_pdu_writef(pdu, "d", err);
+	*outlen = pdu->write_offset;
+
+	/* read the tag from input */
+	pdu->read_offset = sizeof(u32) + sizeof(u8);
+	virtio_p9_pdu_readf(pdu, "w", &tag);
+
+	/* Update the header */
+	pdu->write_offset = 0;
+	virtio_p9_pdu_writef(pdu, "dbw", *outlen, P9_RLERROR, tag);
+}
+
+static void virtio_p9_version(struct p9_dev *p9dev,
+			      struct p9_pdu *pdu, u32 *outlen)
+{
+	u32 msize;
+	char *version;
+	virtio_p9_pdu_readf(pdu, "ds", &msize, &version);
+	/*
+	 * reply with the same msize the client sent us
+	 * Error out if the request is not for 9P2000.L
+	 */
+	if (!strcmp(version, VIRTIO_P9_VERSION_DOTL))
+		virtio_p9_pdu_writef(pdu, "ds", msize, version);
+	else
+		virtio_p9_pdu_writef(pdu, "ds", msize, "unknown");
+
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	free(version);
+	return;
+}
+
+static void virtio_p9_clunk(struct p9_dev *p9dev,
+			    struct p9_pdu *pdu, u32 *outlen)
+{
+	u32 fid;
+
+	virtio_p9_pdu_readf(pdu, "d", &fid);
+	close_fid(p9dev, fid);
+
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+}
+
+/*
+ * FIXME!! Need to map to protocol independent value. Upstream
+ * 9p also have the same BUG
+ */
+static int virtio_p9_openflags(int flags)
+{
+	flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT | O_DIRECT);
+	flags |= O_NOFOLLOW;
+	return flags;
+}
+
+static void virtio_p9_open(struct p9_dev *p9dev,
+			   struct p9_pdu *pdu, u32 *outlen)
+{
+	u32 fid, flags;
+	struct stat st;
+	struct p9_qid qid;
+	struct p9_fid *new_fid;
+
+
+	virtio_p9_pdu_readf(pdu, "dd", &fid, &flags);
+	new_fid = &p9dev->fids[fid];
+
+	if (lstat(new_fid->abs_path, &st) < 0)
+		goto err_out;
+
+	stat2qid(&st, &qid);
+
+	if (new_fid->is_dir) {
+		new_fid->dir = opendir(new_fid->abs_path);
+		if (!new_fid->dir)
+			goto err_out;
+	} else {
+		new_fid->fd  = open(new_fid->abs_path,
+				    virtio_p9_openflags(flags));
+		if (new_fid->fd < 0)
+			goto err_out;
+	}
+	/* FIXME!! need ot send proper iounit  */
+	virtio_p9_pdu_writef(pdu, "Qd", &qid, 0);
+
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_create(struct p9_dev *p9dev,
+			     struct p9_pdu *pdu, u32 *outlen)
+{
+	int fd, ret;
+	char *name;
+	struct stat st;
+	struct p9_qid qid;
+	struct p9_fid *dfid;
+	char full_path[PATH_MAX];
+	u32 dfid_val, flags, mode, gid;
+
+	virtio_p9_pdu_readf(pdu, "dsddd", &dfid_val,
+			    &name, &flags, &mode, &gid);
+	dfid = &p9dev->fids[dfid_val];
+
+	flags = virtio_p9_openflags(flags);
+
+	sprintf(full_path, "%s/%s", dfid->abs_path, name);
+	fd = open(full_path, flags | O_CREAT, mode);
+	if (fd < 0)
+		goto err_out;
+	close_fid(p9dev, dfid_val);
+	dfid->fd = fd;
+
+	if (lstat(full_path, &st) < 0)
+		goto err_out;
+
+	ret = chmod(full_path, mode & 0777);
+	if (ret < 0)
+		goto err_out;
+
+	ret = lchown(full_path, dfid->uid, gid);
+	if (ret < 0)
+		goto err_out;
+
+	sprintf(dfid->path, "%s/%s", dfid->path, name);
+	stat2qid(&st, &qid);
+	virtio_p9_pdu_writef(pdu, "Qd", &qid, 0);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	free(name);
+	return;
+err_out:
+	free(name);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_mkdir(struct p9_dev *p9dev,
+			    struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	char *name;
+	struct stat st;
+	struct p9_qid qid;
+	struct p9_fid *dfid;
+	char full_path[PATH_MAX];
+	u32 dfid_val, mode, gid;
+
+	virtio_p9_pdu_readf(pdu, "dsdd", &dfid_val,
+			    &name, &mode, &gid);
+	dfid = &p9dev->fids[dfid_val];
+
+	sprintf(full_path, "%s/%s", dfid->abs_path, name);
+	ret = mkdir(full_path, mode);
+	if (ret < 0)
+		goto err_out;
+
+	if (lstat(full_path, &st) < 0)
+		goto err_out;
+
+	ret = chmod(full_path, mode & 0777);
+	if (ret < 0)
+		goto err_out;
+
+	ret = lchown(full_path, dfid->uid, gid);
+	if (ret < 0)
+		goto err_out;
+
+	stat2qid(&st, &qid);
+	virtio_p9_pdu_writef(pdu, "Qd", &qid, 0);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	free(name);
+	return;
+err_out:
+	free(name);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_walk(struct p9_dev *p9dev,
+			   struct p9_pdu *pdu, u32 *outlen)
+{
+	u8 i;
+	u16 nwqid;
+	u16 nwname;
+	struct p9_qid wqid;
+	struct p9_fid *new_fid;
+	u32 fid_val, newfid_val;
+
+
+	virtio_p9_pdu_readf(pdu, "ddw", &fid_val, &newfid_val, &nwname);
+	new_fid	= &p9dev->fids[newfid_val];
+
+	nwqid = 0;
+	if (nwname) {
+		struct p9_fid *fid = &p9dev->fids[fid_val];
+
+		strcpy(new_fid->path, fid->path);
+		/* skip the space for count */
+		pdu->write_offset += sizeof(u16);
+		for (i = 0; i < nwname; i++) {
+			struct stat st;
+			char tmp[PATH_MAX] = {0};
+			char full_path[PATH_MAX];
+			char *str;
+
+			virtio_p9_pdu_readf(pdu, "s", &str);
+
+			/* Format the new path we're 'walk'ing into */
+			sprintf(tmp, "%s/%s", new_fid->path, str);
+
+			free(str);
+
+			if (lstat(rel_to_abs(p9dev, tmp, full_path), &st) < 0)
+				goto err_out;
+
+			stat2qid(&st, &wqid);
+			new_fid->is_dir = S_ISDIR(st.st_mode);
+			strcpy(new_fid->path, tmp);
+			new_fid->fid = newfid_val;
+			new_fid->uid = fid->uid;
+			nwqid++;
+			virtio_p9_pdu_writef(pdu, "Q", &wqid);
+		}
+	} else {
+		/*
+		 * update write_offset so our outlen get correct value
+		 */
+		pdu->write_offset += sizeof(u16);
+		new_fid->is_dir = p9dev->fids[fid_val].is_dir;
+		strcpy(new_fid->path, p9dev->fids[fid_val].path);
+		new_fid->fid	= newfid_val;
+		new_fid->uid    = p9dev->fids[fid_val].uid;
+	}
+	*outlen = pdu->write_offset;
+	pdu->write_offset = VIRTIO_P9_HDR_LEN;
+	virtio_p9_pdu_writef(pdu, "d", nwqid);
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_attach(struct p9_dev *p9dev,
+			     struct p9_pdu *pdu, u32 *outlen)
+{
+	int i;
+	char *uname;
+	char *aname;
+	struct stat st;
+	struct p9_qid qid;
+	struct p9_fid *fid;
+	u32 fid_val, afid, uid;
+
+	virtio_p9_pdu_readf(pdu, "ddssd", &fid_val, &afid,
+			    &uname, &aname, &uid);
+
+	free(uname);
+	free(aname);
+
+	/* Reset everything */
+	for (i = 0; i < VIRTIO_P9_MAX_FID; i++)
+		p9dev->fids[i].fid = P9_NOFID;
+
+	if (lstat(p9dev->root_dir, &st) < 0)
+		goto err_out;
+
+	stat2qid(&st, &qid);
+
+	fid = &p9dev->fids[fid_val];
+	fid->fid = fid_val;
+	fid->uid = uid;
+	fid->is_dir = 1;
+	strcpy(fid->path, "/");
+
+	virtio_p9_pdu_writef(pdu, "Q", &qid);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_fill_stat(struct p9_dev *p9dev,
+				struct stat *st, struct p9_stat_dotl *statl)
+{
+	memset(statl, 0, sizeof(*statl));
+	statl->st_mode = st->st_mode;
+	statl->st_nlink = st->st_nlink;
+	statl->st_uid = st->st_uid;
+	statl->st_gid = st->st_gid;
+	statl->st_rdev = st->st_rdev;
+	statl->st_size = st->st_size;
+	statl->st_blksize = st->st_blksize;
+	statl->st_blocks = st->st_blocks;
+	statl->st_atime_sec = st->st_atime;
+	statl->st_atime_nsec = st->st_atim.tv_nsec;
+	statl->st_mtime_sec = st->st_mtime;
+	statl->st_mtime_nsec = st->st_mtim.tv_nsec;
+	statl->st_ctime_sec = st->st_ctime;
+	statl->st_ctime_nsec = st->st_ctim.tv_nsec;
+	/* Currently we only support BASIC fields in stat */
+	statl->st_result_mask = P9_STATS_BASIC;
+	stat2qid(st, &statl->qid);
+}
+
+static void virtio_p9_read(struct p9_dev *p9dev,
+			   struct p9_pdu *pdu, u32 *outlen)
+{
+	u64 offset;
+	u32 fid_val;
+	u16 iov_cnt;
+	void *iov_base;
+	size_t iov_len;
+	u32 count, rcount;
+	struct p9_fid *fid;
+
+
+	rcount = 0;
+	virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
+	fid = &p9dev->fids[fid_val];
+
+	iov_base = pdu->in_iov[0].iov_base;
+	iov_len  = pdu->in_iov[0].iov_len;
+	iov_cnt  = pdu->in_iov_cnt;
+	pdu->in_iov[0].iov_base += VIRTIO_P9_HDR_LEN + sizeof(u32);
+	pdu->in_iov[0].iov_len -= VIRTIO_P9_HDR_LEN + sizeof(u32);
+	pdu->in_iov_cnt = virtio_p9_update_iov_cnt(pdu->in_iov,
+						   count,
+						   pdu->in_iov_cnt);
+	rcount = preadv(fid->fd, pdu->in_iov,
+			pdu->in_iov_cnt, offset);
+	if (rcount > count)
+		rcount = count;
+	/*
+	 * Update the iov_base back, so that rest of
+	 * pdu_writef works correctly.
+	 */
+	pdu->in_iov[0].iov_base = iov_base;
+	pdu->in_iov[0].iov_len  = iov_len;
+	pdu->in_iov_cnt         = iov_cnt;
+
+	pdu->write_offset = VIRTIO_P9_HDR_LEN;
+	virtio_p9_pdu_writef(pdu, "d", rcount);
+	*outlen = pdu->write_offset + rcount;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+}
+
+static int virtio_p9_dentry_size(struct dirent *dent)
+{
+	/*
+	 * Size of each dirent:
+	 * qid(13) + offset(8) + type(1) + name_len(2) + name
+	 */
+	return 24 + strlen(dent->d_name);
+}
+
+static void virtio_p9_readdir(struct p9_dev *p9dev,
+			      struct p9_pdu *pdu, u32 *outlen)
+{
+	u32 fid_val;
+	u32 count, rcount;
+	struct stat st;
+	struct p9_fid *fid;
+	struct dirent *dent;
+	char full_path[PATH_MAX];
+	u64 offset, old_offset;
+
+	rcount = 0;
+	virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
+	fid = &p9dev->fids[fid_val];
+
+	if (!fid->is_dir) {
+		errno = -EINVAL;
+		goto err_out;
+	}
+
+	/* Move the offset specified */
+	seekdir(fid->dir, offset);
+
+	old_offset = offset;
+	/* If reading a dir, fill the buffer with p9_stat entries */
+	dent = readdir(fid->dir);
+
+	/* Skip the space for writing count */
+	pdu->write_offset += sizeof(u32);
+	while (dent) {
+		u32 read;
+		struct p9_qid qid;
+
+		if ((rcount + virtio_p9_dentry_size(dent)) > count) {
+			/* seek to the previous offset and return */
+			seekdir(fid->dir, old_offset);
+			break;
+		}
+		old_offset = dent->d_off;
+		lstat(rel_to_abs(p9dev, dent->d_name, full_path), &st);
+		stat2qid(&st, &qid);
+		read = pdu->write_offset;
+		virtio_p9_pdu_writef(pdu, "Qqbs", &qid, dent->d_off,
+				     dent->d_type, dent->d_name);
+		rcount += pdu->write_offset - read;
+		dent = readdir(fid->dir);
+	}
+
+	pdu->write_offset = VIRTIO_P9_HDR_LEN;
+	virtio_p9_pdu_writef(pdu, "d", rcount);
+	*outlen = pdu->write_offset + rcount;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+
+static void virtio_p9_getattr(struct p9_dev *p9dev,
+			      struct p9_pdu *pdu, u32 *outlen)
+{
+	u32 fid_val;
+	struct stat st;
+	u64 request_mask;
+	struct p9_fid *fid;
+	struct p9_stat_dotl statl;
+
+	virtio_p9_pdu_readf(pdu, "dq", &fid_val, &request_mask);
+	fid = &p9dev->fids[fid_val];
+	if (lstat(fid->abs_path, &st) < 0)
+		goto err_out;
+
+	virtio_p9_fill_stat(p9dev, &st, &statl);
+	virtio_p9_pdu_writef(pdu, "A", &statl);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+/* FIXME!! from linux/fs.h */
+/*
+ * Attribute flags.  These should be or-ed together to figure out what
+ * has been changed!
+ */
+#define ATTR_MODE	(1 << 0)
+#define ATTR_UID	(1 << 1)
+#define ATTR_GID	(1 << 2)
+#define ATTR_SIZE	(1 << 3)
+#define ATTR_ATIME	(1 << 4)
+#define ATTR_MTIME	(1 << 5)
+#define ATTR_CTIME	(1 << 6)
+#define ATTR_ATIME_SET	(1 << 7)
+#define ATTR_MTIME_SET	(1 << 8)
+#define ATTR_FORCE	(1 << 9) /* Not a change, but a change it */
+#define ATTR_ATTR_FLAG	(1 << 10)
+#define ATTR_KILL_SUID	(1 << 11)
+#define ATTR_KILL_SGID	(1 << 12)
+#define ATTR_FILE	(1 << 13)
+#define ATTR_KILL_PRIV	(1 << 14)
+#define ATTR_OPEN	(1 << 15) /* Truncating from open(O_TRUNC) */
+#define ATTR_TIMES_SET	(1 << 16)
+
+#define ATTR_MASK    127
+
+static void virtio_p9_setattr(struct p9_dev *p9dev,
+			      struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret = 0;
+	u32 fid_val;
+	struct p9_fid *fid;
+	struct p9_iattr_dotl p9attr;
+
+	virtio_p9_pdu_readf(pdu, "dI", &fid_val, &p9attr);
+	fid = &p9dev->fids[fid_val];
+
+	if (p9attr.valid & ATTR_MODE) {
+		ret = chmod(fid->abs_path, p9attr.mode);
+		if (ret < 0)
+			goto err_out;
+	}
+	if (p9attr.valid & (ATTR_ATIME | ATTR_MTIME)) {
+		struct timespec times[2];
+		if (p9attr.valid & ATTR_ATIME) {
+			if (p9attr.valid & ATTR_ATIME_SET) {
+				times[0].tv_sec = p9attr.atime_sec;
+				times[0].tv_nsec = p9attr.atime_nsec;
+			} else {
+				times[0].tv_nsec = UTIME_NOW;
+			}
+		} else {
+			times[0].tv_nsec = UTIME_OMIT;
+		}
+		if (p9attr.valid & ATTR_MTIME) {
+			if (p9attr.valid & ATTR_MTIME_SET) {
+				times[1].tv_sec = p9attr.mtime_sec;
+				times[1].tv_nsec = p9attr.mtime_nsec;
+			} else {
+				times[1].tv_nsec = UTIME_NOW;
+			}
+		} else
+			times[1].tv_nsec = UTIME_OMIT;
+
+		ret = utimensat(-1, fid->abs_path, times, AT_SYMLINK_NOFOLLOW);
+		if (ret < 0)
+			goto err_out;
+	}
+	/*
+	 * If the only valid entry in iattr is ctime we can call
+	 * chown(-1,-1) to update the ctime of the file
+	 */
+	if ((p9attr.valid & (ATTR_UID | ATTR_GID)) ||
+	    ((p9attr.valid & ATTR_CTIME)
+	     && !((p9attr.valid & ATTR_MASK) & ~ATTR_CTIME))) {
+		if (!(p9attr.valid & ATTR_UID))
+			p9attr.uid = -1;
+
+		if (!(p9attr.valid & ATTR_GID))
+			p9attr.gid = -1;
+
+		ret = lchown(fid->abs_path, p9attr.uid, p9attr.gid);
+		if (ret < 0)
+			goto err_out;
+	}
+	if (p9attr.valid & (ATTR_SIZE)) {
+		ret = truncate(fid->abs_path, p9attr.size);
+		if (ret < 0)
+			goto err_out;
+	}
+	*outlen = VIRTIO_P9_HDR_LEN;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_write(struct p9_dev *p9dev,
+			    struct p9_pdu *pdu, u32 *outlen)
+{
+
+	u64 offset;
+	u32 fid_val;
+	u32 count;
+	ssize_t res;
+	u16 iov_cnt;
+	void *iov_base;
+	size_t iov_len;
+	struct p9_fid *fid;
+	/* u32 fid + u64 offset + u32 count */
+	int twrite_size = sizeof(u32) + sizeof(u64) + sizeof(u32);
+
+	virtio_p9_pdu_readf(pdu, "dqd", &fid_val, &offset, &count);
+	fid = &p9dev->fids[fid_val];
+
+	iov_base = pdu->out_iov[0].iov_base;
+	iov_len  = pdu->out_iov[0].iov_len;
+	iov_cnt  = pdu->out_iov_cnt;
+
+	/* Adjust the iovec to skip the header and meta data */
+	pdu->out_iov[0].iov_base += (sizeof(struct p9_msg) + twrite_size);
+	pdu->out_iov[0].iov_len -=  (sizeof(struct p9_msg) + twrite_size);
+	pdu->out_iov_cnt = virtio_p9_update_iov_cnt(pdu->out_iov, count,
+						    pdu->out_iov_cnt);
+	res = pwritev(fid->fd, pdu->out_iov, pdu->out_iov_cnt, offset);
+	/*
+	 * Update the iov_base back, so that rest of
+	 * pdu_readf works correctly.
+	 */
+	pdu->out_iov[0].iov_base = iov_base;
+	pdu->out_iov[0].iov_len  = iov_len;
+	pdu->out_iov_cnt         = iov_cnt;
+
+	if (res < 0)
+		goto err_out;
+	virtio_p9_pdu_writef(pdu, "d", res);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_remove(struct p9_dev *p9dev,
+			       struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	u32 fid_val;
+	struct p9_fid *fid;
+
+	virtio_p9_pdu_readf(pdu, "d", &fid_val);
+	fid = &p9dev->fids[fid_val];
+
+	ret = remove(fid->abs_path);
+	if (ret < 0)
+		goto err_out;
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_rename(struct p9_dev *p9dev,
+			       struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	u32 fid_val, new_fid_val;
+	struct p9_fid *fid, *new_fid;
+	char full_path[PATH_MAX], *new_name;
+
+	virtio_p9_pdu_readf(pdu, "dds", &fid_val, &new_fid_val, &new_name);
+	fid = &p9dev->fids[fid_val];
+	new_fid = &p9dev->fids[new_fid_val];
+
+	sprintf(full_path, "%s/%s", new_fid->abs_path, new_name);
+	ret = rename(fid->abs_path, full_path);
+	if (ret < 0)
+		goto err_out;
+	close_fid(p9dev, fid_val);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_readlink(struct p9_dev *p9dev,
+			       struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	u32 fid_val;
+	struct p9_fid *fid;
+	char target_path[PATH_MAX];
+
+	virtio_p9_pdu_readf(pdu, "d", &fid_val);
+	fid = &p9dev->fids[fid_val];
+
+	memset(target_path, 0, PATH_MAX);
+	ret = readlink(fid->abs_path, target_path, PATH_MAX - 1);
+	if (ret < 0)
+		goto err_out;
+
+	virtio_p9_pdu_writef(pdu, "s", target_path);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_statfs(struct p9_dev *p9dev,
+			     struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	u64 fsid;
+	u32 fid_val;
+	struct p9_fid *fid;
+	struct statfs stat_buf;
+
+	virtio_p9_pdu_readf(pdu, "d", &fid_val);
+	fid = &p9dev->fids[fid_val];
+
+	ret = statfs(fid->abs_path, &stat_buf);
+	if (ret < 0)
+		goto err_out;
+	/* FIXME!! f_blocks needs update based on client msize */
+	fsid = (unsigned int) stat_buf.f_fsid.__val[0] |
+		(unsigned long long)stat_buf.f_fsid.__val[1] << 32;
+	virtio_p9_pdu_writef(pdu, "ddqqqqqqd", stat_buf.f_type,
+			     stat_buf.f_bsize, stat_buf.f_blocks,
+			     stat_buf.f_bfree, stat_buf.f_bavail,
+			     stat_buf.f_files, stat_buf.f_ffree,
+			     fsid, stat_buf.f_namelen);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_mknod(struct p9_dev *p9dev,
+			    struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	char *name;
+	struct stat st;
+	struct p9_fid *dfid;
+	struct p9_qid qid;
+	char full_path[PATH_MAX];
+	u32 fid_val, mode, major, minor, gid;
+
+	virtio_p9_pdu_readf(pdu, "dsdddd", &fid_val, &name, &mode,
+			    &major, &minor, &gid);
+
+	dfid = &p9dev->fids[fid_val];
+	sprintf(full_path, "%s/%s", dfid->abs_path, name);
+	ret = mknod(full_path, mode, makedev(major, minor));
+	if (ret < 0)
+		goto err_out;
+
+	if (lstat(full_path, &st) < 0)
+		goto err_out;
+
+	ret = chmod(full_path, mode & 0777);
+	if (ret < 0)
+		goto err_out;
+
+	ret = lchown(full_path, dfid->uid, gid);
+	if (ret < 0)
+		goto err_out;
+
+	stat2qid(&st, &qid);
+	virtio_p9_pdu_writef(pdu, "Q", &qid);
+	free(name);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	free(name);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_fsync(struct p9_dev *p9dev,
+			    struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	struct p9_fid *fid;
+	u32 fid_val, datasync;
+
+	virtio_p9_pdu_readf(pdu, "dd", &fid_val, &datasync);
+	fid = &p9dev->fids[fid_val];
+
+	if (datasync)
+		ret = fdatasync(fid->fd);
+	else
+		ret = fsync(fid->fd);
+	if (ret < 0)
+		goto err_out;
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_symlink(struct p9_dev *p9dev,
+			      struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	struct stat st;
+	u32 fid_val, gid;
+	struct p9_qid qid;
+	struct p9_fid *dfid;
+	char new_name[PATH_MAX];
+	char *old_path, *name;
+
+	virtio_p9_pdu_readf(pdu, "dssd", &fid_val, &name, &old_path, &gid);
+
+	dfid = &p9dev->fids[fid_val];
+	sprintf(new_name, "%s/%s", dfid->abs_path, name);
+	ret = symlink(old_path, new_name);
+	if (ret < 0)
+		goto err_out;
+
+	if (lstat(new_name, &st) < 0)
+		goto err_out;
+
+	ret = lchown(new_name, dfid->uid, gid);
+	if (ret < 0)
+		goto err_out;
+
+	stat2qid(&st, &qid);
+	virtio_p9_pdu_writef(pdu, "Q", &qid);
+	free(name);
+	free(old_path);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	free(name);
+	free(old_path);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_link(struct p9_dev *p9dev,
+			   struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	char *name;
+	u32 fid_val, dfid_val;
+	struct p9_fid *dfid, *fid;
+	char full_path[PATH_MAX];
+
+	virtio_p9_pdu_readf(pdu, "dds", &dfid_val, &fid_val, &name);
+
+	dfid = &p9dev->fids[dfid_val];
+	fid =  &p9dev->fids[fid_val];
+	sprintf(full_path, "%s/%s", dfid->abs_path, name);
+	ret = link(fid->abs_path, full_path);
+	if (ret < 0)
+		goto err_out;
+	free(name);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	free(name);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+
+}
+
+static void virtio_p9_lock(struct p9_dev *p9dev,
+			   struct p9_pdu *pdu, u32 *outlen)
+{
+	u8 ret;
+	u32 fid_val;
+	struct p9_flock flock;
+
+	virtio_p9_pdu_readf(pdu, "dbdqqds", &fid_val, &flock.type,
+			    &flock.flags, &flock.start, &flock.length,
+			    &flock.proc_id, &flock.client_id);
+
+	/* Just return success */
+	ret = P9_LOCK_SUCCESS;
+	virtio_p9_pdu_writef(pdu, "d", ret);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	free(flock.client_id);
+	return;
+}
+
+static void virtio_p9_getlock(struct p9_dev *p9dev,
+			      struct p9_pdu *pdu, u32 *outlen)
+{
+	u32 fid_val;
+	struct p9_getlock glock;
+	virtio_p9_pdu_readf(pdu, "dbqqds", &fid_val, &glock.type,
+			    &glock.start, &glock.length, &glock.proc_id,
+			    &glock.client_id);
+
+	/* Just return success */
+	glock.type = F_UNLCK;
+	virtio_p9_pdu_writef(pdu, "bqqds", glock.type,
+			     glock.start, glock.length, glock.proc_id,
+			     glock.client_id);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	free(glock.client_id);
+	return;
+}
+
+static int virtio_p9_ancestor(char *path, char *ancestor)
+{
+	int size = strlen(ancestor);
+	if (!strncmp(path, ancestor, size)) {
+		/*
+		 * Now check whether ancestor is a full name or
+		 * or directory component and not just part
+		 * of a name.
+		 */
+		if (path[size] == '\0' || path[size] == '/')
+			return 1;
+	}
+	return 0;
+}
+
+static void virtio_p9_fix_path(char *fid_path, char *old_name, char *new_name)
+{
+	char tmp_name[PATH_MAX];
+	size_t rp_sz = strlen(old_name);
+
+	if (rp_sz == strlen(fid_path)) {
+		/* replace the full name */
+		strcpy(fid_path, new_name);
+		return;
+	}
+	/* save the trailing path details */
+	strcpy(tmp_name, fid_path + rp_sz);
+	sprintf(fid_path, "%s%s", new_name, tmp_name);
+	return;
+}
+
+static void virtio_p9_renameat(struct p9_dev *p9dev,
+			       struct p9_pdu *pdu, u32 *outlen)
+{
+	int i, ret;
+	char *old_name, *new_name;
+	u32 old_dfid_val, new_dfid_val;
+	struct p9_fid *old_dfid, *new_dfid;
+	char old_full_path[PATH_MAX], new_full_path[PATH_MAX];
+
+
+	virtio_p9_pdu_readf(pdu, "dsds", &old_dfid_val, &old_name,
+			    &new_dfid_val, &new_name);
+
+	old_dfid = &p9dev->fids[old_dfid_val];
+	new_dfid = &p9dev->fids[new_dfid_val];
+
+	sprintf(old_full_path, "%s/%s", old_dfid->abs_path, old_name);
+	sprintf(new_full_path, "%s/%s", new_dfid->abs_path, new_name);
+	ret = rename(old_full_path, new_full_path);
+	if (ret < 0)
+		goto err_out;
+	/*
+	 * Now fix path in other fids, if the renamed path is part of
+	 * that.
+	 */
+	for (i = 0; i < VIRTIO_P9_MAX_FID; i++) {
+		if (p9dev->fids[i].fid != P9_NOFID &&
+		    virtio_p9_ancestor(p9dev->fids[i].path, old_name)) {
+			virtio_p9_fix_path(p9dev->fids[i].path, old_name,
+					   new_name);
+		}
+	}
+	free(old_name);
+	free(new_name);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	free(old_name);
+	free(new_name);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_unlinkat(struct p9_dev *p9dev,
+			       struct p9_pdu *pdu, u32 *outlen)
+{
+	int ret;
+	char *name;
+	u32 fid_val, flags;
+	struct p9_fid *fid;
+	char full_path[PATH_MAX];
+
+	virtio_p9_pdu_readf(pdu, "dsd", &fid_val, &name, &flags);
+	fid = &p9dev->fids[fid_val];
+
+	sprintf(full_path, "%s/%s", fid->abs_path, name);
+	ret = remove(full_path);
+	if (ret < 0)
+		goto err_out;
+	free(name);
+	*outlen = pdu->write_offset;
+	virtio_p9_set_reply_header(pdu, *outlen);
+	return;
+err_out:
+	free(name);
+	virtio_p9_error_reply(p9dev, pdu, errno, outlen);
+	return;
+}
+
+static void virtio_p9_eopnotsupp(struct p9_dev *p9dev,
+				 struct p9_pdu *pdu, u32 *outlen)
+{
+	return virtio_p9_error_reply(p9dev, pdu, EOPNOTSUPP, outlen);
+}
+
+typedef void p9_handler(struct p9_dev *p9dev,
+			struct p9_pdu *pdu, u32 *outlen);
+
+/* FIXME should be removed when merging with latest linus tree */
+#define P9_TRENAMEAT 74
+#define P9_TUNLINKAT 76
+
+static p9_handler *virtio_9p_dotl_handler [] = {
+	[P9_TREADDIR]     = virtio_p9_readdir,
+	[P9_TSTATFS]      = virtio_p9_statfs,
+	[P9_TGETATTR]     = virtio_p9_getattr,
+	[P9_TSETATTR]     = virtio_p9_setattr,
+	[P9_TXATTRWALK]   = virtio_p9_eopnotsupp,
+	[P9_TXATTRCREATE] = virtio_p9_eopnotsupp,
+	[P9_TMKNOD]       = virtio_p9_mknod,
+	[P9_TLOCK]        = virtio_p9_lock,
+	[P9_TGETLOCK]     = virtio_p9_getlock,
+	[P9_TRENAMEAT]    = virtio_p9_renameat,
+	[P9_TREADLINK]    = virtio_p9_readlink,
+	[P9_TUNLINKAT]    = virtio_p9_unlinkat,
+	[P9_TMKDIR]       = virtio_p9_mkdir,
+	[P9_TVERSION]     = virtio_p9_version,
+	[P9_TLOPEN]       = virtio_p9_open,
+	[P9_TATTACH]      = virtio_p9_attach,
+	[P9_TWALK]        = virtio_p9_walk,
+	[P9_TCLUNK]       = virtio_p9_clunk,
+	[P9_TFSYNC]       = virtio_p9_fsync,
+	[P9_TREAD]        = virtio_p9_read,
+	[P9_TFLUSH]       = virtio_p9_eopnotsupp,
+	[P9_TLINK]        = virtio_p9_link,
+	[P9_TSYMLINK]     = virtio_p9_symlink,
+	[P9_TLCREATE]     = virtio_p9_create,
+	[P9_TWRITE]       = virtio_p9_write,
+	[P9_TREMOVE]      = virtio_p9_remove,
+	[P9_TRENAME]      = virtio_p9_rename,
+};
+
+static struct p9_pdu *virtio_p9_pdu_init(struct kvm *kvm, struct virt_queue *vq)
+{
+	struct p9_pdu *pdu = calloc(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+
+	/* skip the pdu header p9_msg */
+	pdu->read_offset  = VIRTIO_P9_HDR_LEN;
+	pdu->write_offset = VIRTIO_P9_HDR_LEN;
+	pdu->queue_head  = virt_queue__get_inout_iov(kvm, vq, pdu->in_iov,
+						     pdu->out_iov,
+						     &pdu->in_iov_cnt,
+						     &pdu->out_iov_cnt);
+	return pdu;
+}
+
+static u8 virtio_p9_get_cmd(struct p9_pdu *pdu)
+{
+	struct p9_msg *msg;
+	/*
+	 * we can peek directly into pdu for a u8
+	 * value. The host endianess won't be an issue
+	 */
+	msg = pdu->out_iov[0].iov_base;
+	return msg->cmd;
+}
+
+static bool virtio_p9_do_io_request(struct kvm *kvm, struct p9_dev_job *job)
+{
+	u8 cmd;
+	u32 len = 0;
+	p9_handler *handler;
+	struct p9_dev *p9dev;
+	struct virt_queue *vq;
+	struct p9_pdu *p9pdu;
+
+	vq = job->vq;
+	p9dev = job->p9dev;
+
+	p9pdu = virtio_p9_pdu_init(kvm, vq);
+	cmd = virtio_p9_get_cmd(p9pdu);
+
+	if ((cmd >= ARRAY_SIZE(virtio_9p_dotl_handler)) ||
+	    !virtio_9p_dotl_handler[cmd])
+		handler = virtio_p9_eopnotsupp;
+	else
+		handler = virtio_9p_dotl_handler[cmd];
+
+	handler(p9dev, p9pdu, &len);
+	virt_queue__set_used_elem(vq, p9pdu->queue_head, len);
+	free(p9pdu);
+	return true;
+}
+
+static void virtio_p9_do_io(struct kvm *kvm, void *param)
+{
+	struct p9_dev_job *job = (struct p9_dev_job *)param;
+	struct p9_dev *p9dev   = job->p9dev;
+	struct virt_queue *vq  = job->vq;
+
+	while (virt_queue__available(vq)) {
+		virtio_p9_do_io_request(kvm, job);
+		p9dev->vtrans.trans_ops->signal_vq(kvm, &p9dev->vtrans, vq - p9dev->vqs);
+	}
+}
+
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
+{
+	struct p9_dev *p9dev = dev;
+
+	((u8 *)(p9dev->config))[offset] = data;
+}
+
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	struct p9_dev *p9dev = dev;
+
+	return ((u8 *)(p9dev->config))[offset];
+}
+
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	return 1 << VIRTIO_9P_MOUNT_TAG;
+}
+
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	struct p9_dev *p9dev = dev;
+
+	p9dev->features = features;
+}
+
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct p9_dev *p9dev = dev;
+	struct p9_dev_job *job;
+	struct virt_queue *queue;
+	void *p;
+
+	compat__remove_message(compat_id);
+
+	queue			= &p9dev->vqs[vq];
+	queue->pfn		= pfn;
+	p			= guest_pfn_to_host(kvm, queue->pfn);
+	job			= &p9dev->jobs[vq];
+
+	vring_init(&queue->vring, VIRTQUEUE_NUM, p, VIRTIO_PCI_VRING_ALIGN);
+
+	*job			= (struct p9_dev_job) {
+		.vq			= queue,
+		.p9dev			= p9dev,
+	};
+	thread_pool__init_job(&job->job_id, kvm, virtio_p9_do_io, job);
+
+	return 0;
+}
+
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct p9_dev *p9dev = dev;
+
+	thread_pool__do_job(&p9dev->jobs[vq].job_id);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct p9_dev *p9dev = dev;
+
+	return p9dev->vqs[vq].pfn;
+}
+
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTQUEUE_NUM;
+}
+
+struct virtio_ops p9_dev_virtio_ops = (struct virtio_ops) {
+	.set_config		= set_config,
+	.get_config		= get_config,
+	.get_host_features	= get_host_features,
+	.set_guest_features	= set_guest_features,
+	.init_vq		= init_vq,
+	.notify_vq		= notify_vq,
+	.get_pfn_vq		= get_pfn_vq,
+	.get_size_vq		= get_size_vq,
+};
+
+int virtio_9p__init(struct kvm *kvm)
+{
+	struct p9_dev *p9dev;
+
+	list_for_each_entry(p9dev, &devs, list) {
+		virtio_trans_init(&p9dev->vtrans, VIRTIO_PCI);
+		p9dev->vtrans.trans_ops->init(kvm, &p9dev->vtrans, p9dev,
+					PCI_DEVICE_ID_VIRTIO_P9, VIRTIO_ID_9P, PCI_CLASS_P9);
+		p9dev->vtrans.virtio_ops = &p9_dev_virtio_ops;
+	}
+
+	return 0;
+}
+
+int virtio_9p__register(struct kvm *kvm, const char *root, const char *tag_name)
+{
+	struct p9_dev *p9dev;
+	u32 i, root_len;
+	int err = 0;
+
+	p9dev = calloc(1, sizeof(*p9dev));
+	if (!p9dev)
+		return -ENOMEM;
+
+	if (!tag_name)
+		tag_name = VIRTIO_P9_DEFAULT_TAG;
+
+	p9dev->config = calloc(1, sizeof(*p9dev->config) + strlen(tag_name) + 1);
+	if (p9dev->config == NULL) {
+		err = -ENOMEM;
+		goto free_p9dev;
+	}
+
+	strcpy(p9dev->root_dir, root);
+	root_len = strlen(root);
+	/*
+	 * We prefix the full path in all fids, This allows us to get the
+	 * absolute path of an fid without playing with strings.
+	 */
+	for (i = 0; i < VIRTIO_P9_MAX_FID; i++) {
+		strcpy(p9dev->fids[i].abs_path, root);
+		p9dev->fids[i].path = p9dev->fids[i].abs_path + root_len;
+	}
+	p9dev->config->tag_len = strlen(tag_name);
+	if (p9dev->config->tag_len > MAX_TAG_LEN) {
+		err = -EINVAL;
+		goto free_p9dev_config;
+	}
+
+	memcpy(&p9dev->config->tag, tag_name, strlen(tag_name));
+
+	list_add(&p9dev->list, &devs);
+
+	if (compat_id != -1)
+		compat_id = compat__add_message("virtio-9p device was not detected",
+						"While you have requested a virtio-9p device, "
+						"the guest kernel did not initialize it.\n"
+						"Please make sure that the guest kernel was "
+						"compiled with CONFIG_NET_9P_VIRTIO=y enabled "
+						"in its .config");
+
+	return err;
+
+free_p9dev_config:
+	free(p9dev->config);
+free_p9dev:
+	free(p9dev);
+	return err;
+}
diff --git a/tools/kvm/virtio/balloon.c b/tools/kvm/virtio/balloon.c
new file mode 100644
index 0000000..09044d0
--- /dev/null
+++ b/tools/kvm/virtio/balloon.c
@@ -0,0 +1,275 @@
+#include "kvm/virtio-balloon.h"
+
+#include "kvm/virtio-pci-dev.h"
+
+#include "kvm/virtio.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/pci.h"
+#include "kvm/threadpool.h"
+#include "kvm/guest_compat.h"
+#include "kvm/virtio-trans.h"
+#include "kvm/kvm-ipc.h"
+
+#include <linux/virtio_ring.h>
+#include <linux/virtio_balloon.h>
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <sys/eventfd.h>
+
+#define NUM_VIRT_QUEUES		3
+#define VIRTIO_BLN_QUEUE_SIZE	128
+#define VIRTIO_BLN_INFLATE	0
+#define VIRTIO_BLN_DEFLATE	1
+#define VIRTIO_BLN_STATS	2
+
+struct bln_dev {
+	struct list_head	list;
+	struct virtio_trans	vtrans;
+
+	u32			features;
+
+	/* virtio queue */
+	struct virt_queue	vqs[NUM_VIRT_QUEUES];
+	struct thread_pool__job	jobs[NUM_VIRT_QUEUES];
+
+	struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
+	struct virtio_balloon_stat *cur_stat;
+	u32			cur_stat_head;
+	u16			stat_count;
+	int			stat_waitfd;
+
+	struct virtio_balloon_config config;
+};
+
+static struct bln_dev bdev;
+extern struct kvm *kvm;
+static int compat_id = -1;
+
+static bool virtio_bln_do_io_request(struct kvm *kvm, struct bln_dev *bdev, struct virt_queue *queue)
+{
+	struct iovec iov[VIRTIO_BLN_QUEUE_SIZE];
+	unsigned int len = 0;
+	u16 out, in, head;
+	u32 *ptrs, i;
+
+	head	= virt_queue__get_iov(queue, iov, &out, &in, kvm);
+	ptrs	= iov[0].iov_base;
+	len	= iov[0].iov_len / sizeof(u32);
+
+	for (i = 0 ; i < len ; i++) {
+		void *guest_ptr;
+
+		guest_ptr = guest_flat_to_host(kvm, ptrs[i] << VIRTIO_BALLOON_PFN_SHIFT);
+		if (queue == &bdev->vqs[VIRTIO_BLN_INFLATE]) {
+			madvise(guest_ptr, 1 << VIRTIO_BALLOON_PFN_SHIFT, MADV_DONTNEED);
+			bdev->config.actual++;
+		} else if (queue == &bdev->vqs[VIRTIO_BLN_DEFLATE]) {
+			bdev->config.actual--;
+		}
+	}
+
+	virt_queue__set_used_elem(queue, head, len);
+
+	return true;
+}
+
+static bool virtio_bln_do_stat_request(struct kvm *kvm, struct bln_dev *bdev, struct virt_queue *queue)
+{
+	struct iovec iov[VIRTIO_BLN_QUEUE_SIZE];
+	u16 out, in, head;
+	struct virtio_balloon_stat *stat;
+	u64 wait_val = 1;
+
+	head = virt_queue__get_iov(queue, iov, &out, &in, kvm);
+	stat = iov[0].iov_base;
+
+	/* Initial empty stat buffer */
+	if (bdev->cur_stat == NULL) {
+		bdev->cur_stat = stat;
+		bdev->cur_stat_head = head;
+
+		return true;
+	}
+
+	memcpy(bdev->stats, stat, iov[0].iov_len);
+
+	bdev->stat_count = iov[0].iov_len / sizeof(struct virtio_balloon_stat);
+	bdev->cur_stat = stat;
+	bdev->cur_stat_head = head;
+
+	if (write(bdev->stat_waitfd, &wait_val, sizeof(wait_val)) <= 0)
+		return -EFAULT;
+
+	return 1;
+}
+
+static void virtio_bln_do_io(struct kvm *kvm, void *param)
+{
+	struct virt_queue *vq = param;
+
+	if (vq == &bdev.vqs[VIRTIO_BLN_STATS]) {
+		virtio_bln_do_stat_request(kvm, &bdev, vq);
+		bdev.vtrans.trans_ops->signal_vq(kvm, &bdev.vtrans, VIRTIO_BLN_STATS);
+		return;
+	}
+
+	while (virt_queue__available(vq)) {
+		virtio_bln_do_io_request(kvm, &bdev, vq);
+		bdev.vtrans.trans_ops->signal_vq(kvm, &bdev.vtrans, vq - bdev.vqs);
+	}
+}
+
+static int virtio_bln__collect_stats(void)
+{
+	u64 tmp;
+
+	virt_queue__set_used_elem(&bdev.vqs[VIRTIO_BLN_STATS], bdev.cur_stat_head,
+				  sizeof(struct virtio_balloon_stat));
+	bdev.vtrans.trans_ops->signal_vq(kvm, &bdev.vtrans, VIRTIO_BLN_STATS);
+
+	if (read(bdev.stat_waitfd, &tmp, sizeof(tmp)) <= 0)
+		return -EFAULT;
+
+	return 0;
+}
+
+static void virtio_bln__print_stats(int fd, u32 type, u32 len, u8 *msg)
+{
+	int r;
+
+	if (WARN_ON(type != KVM_IPC_STAT || len))
+		return;
+
+	if (virtio_bln__collect_stats() < 0)
+		return;
+
+	r = write(fd, bdev.stats, sizeof(bdev.stats));
+	if (r < 0)
+		pr_warning("Failed sending memory stats");
+}
+
+static void handle_mem(int fd, u32 type, u32 len, u8 *msg)
+{
+	int mem;
+
+	if (WARN_ON(type != KVM_IPC_BALLOON || len != sizeof(int)))
+		return;
+
+	mem = *(int *)msg;
+	if (mem > 0) {
+		bdev.config.num_pages += 256 * mem;
+	} else if (mem < 0) {
+		if (bdev.config.num_pages < (u32)(256 * (-mem)))
+			return;
+
+		bdev.config.num_pages += 256 * mem;
+	}
+
+	/* Notify that the configuration space has changed */
+	bdev.vtrans.trans_ops->signal_config(kvm, &bdev.vtrans);
+}
+
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
+{
+	struct bln_dev *bdev = dev;
+
+	((u8 *)(&bdev->config))[offset] = data;
+}
+
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	struct bln_dev *bdev = dev;
+
+	return ((u8 *)(&bdev->config))[offset];
+}
+
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	return 1 << VIRTIO_BALLOON_F_STATS_VQ;
+}
+
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	struct bln_dev *bdev = dev;
+
+	bdev->features = features;
+}
+
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct bln_dev *bdev = dev;
+	struct virt_queue *queue;
+	void *p;
+
+	compat__remove_message(compat_id);
+
+	queue			= &bdev->vqs[vq];
+	queue->pfn		= pfn;
+	p			= guest_pfn_to_host(kvm, queue->pfn);
+
+	thread_pool__init_job(&bdev->jobs[vq], kvm, virtio_bln_do_io, queue);
+	vring_init(&queue->vring, VIRTIO_BLN_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
+
+	return 0;
+}
+
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct bln_dev *bdev = dev;
+
+	thread_pool__do_job(&bdev->jobs[vq]);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct bln_dev *bdev = dev;
+
+	return bdev->vqs[vq].pfn;
+}
+
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTIO_BLN_QUEUE_SIZE;
+}
+
+struct virtio_ops bln_dev_virtio_ops = (struct virtio_ops) {
+	.set_config		= set_config,
+	.get_config		= get_config,
+	.get_host_features	= get_host_features,
+	.set_guest_features	= set_guest_features,
+	.init_vq		= init_vq,
+	.notify_vq		= notify_vq,
+	.get_pfn_vq		= get_pfn_vq,
+	.get_size_vq		= get_size_vq,
+};
+
+void virtio_bln__init(struct kvm *kvm)
+{
+	kvm_ipc__register_handler(KVM_IPC_BALLOON, handle_mem);
+	kvm_ipc__register_handler(KVM_IPC_STAT, virtio_bln__print_stats);
+
+	bdev.stat_waitfd	= eventfd(0, 0);
+	memset(&bdev.config, 0, sizeof(struct virtio_balloon_config));
+
+	virtio_trans_init(&bdev.vtrans, VIRTIO_PCI);
+	bdev.vtrans.trans_ops->init(kvm, &bdev.vtrans, &bdev, PCI_DEVICE_ID_VIRTIO_BLN,
+					VIRTIO_ID_BALLOON, PCI_CLASS_BLN);
+	bdev.vtrans.virtio_ops = &bln_dev_virtio_ops;
+
+	if (compat_id != -1)
+		compat_id = compat__add_message("virtio-balloon device was not detected",
+						"While you have requested a virtio-balloon device, "
+						"the guest kernel did not initialize it.\n"
+						"Please make sure that the guest kernel was "
+						"compiled with CONFIG_VIRTIO_BALLOON=y enabled "
+						"in its .config");
+}
diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c
new file mode 100644
index 0000000..c230dd4
--- /dev/null
+++ b/tools/kvm/virtio/blk.c
@@ -0,0 +1,290 @@
+#include "kvm/virtio-blk.h"
+
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/disk-image.h"
+#include "kvm/mutex.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/pci.h"
+#include "kvm/threadpool.h"
+#include "kvm/ioeventfd.h"
+#include "kvm/guest_compat.h"
+#include "kvm/virtio-pci.h"
+#include "kvm/virtio.h"
+#include "kvm/virtio-trans.h"
+
+#include <linux/virtio_ring.h>
+#include <linux/virtio_blk.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <pthread.h>
+
+#define VIRTIO_BLK_MAX_DEV		4
+
+/*
+ * the header and status consume too entries
+ */
+#define DISK_SEG_MAX			(VIRTIO_BLK_QUEUE_SIZE - 2)
+#define VIRTIO_BLK_QUEUE_SIZE		128
+#define NUM_VIRT_QUEUES			1
+
+struct blk_dev_req {
+	struct virt_queue		*vq;
+	struct blk_dev			*bdev;
+	struct iovec			iov[VIRTIO_BLK_QUEUE_SIZE];
+	u16				out, in, head;
+	struct kvm			*kvm;
+};
+
+struct blk_dev {
+	pthread_mutex_t			mutex;
+	pthread_mutex_t			req_mutex;
+
+	struct list_head		list;
+	struct list_head		req_list;
+
+	struct virtio_trans		vtrans;
+	struct virtio_blk_config	blk_config;
+	struct disk_image		*disk;
+	u32				features;
+
+	struct virt_queue		vqs[NUM_VIRT_QUEUES];
+	struct blk_dev_req		reqs[VIRTIO_BLK_QUEUE_SIZE];
+};
+
+static LIST_HEAD(bdevs);
+static int compat_id = -1;
+
+void virtio_blk_complete(void *param, long len)
+{
+	struct blk_dev_req *req = param;
+	struct blk_dev *bdev = req->bdev;
+	int queueid = req->vq - bdev->vqs;
+	u8 *status;
+
+	/* status */
+	status	= req->iov[req->out + req->in - 1].iov_base;
+	*status	= (len < 0) ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK;
+
+	mutex_lock(&bdev->mutex);
+	virt_queue__set_used_elem(req->vq, req->head, len);
+	mutex_unlock(&bdev->mutex);
+
+	if (virtio_queue__should_signal(&bdev->vqs[queueid]))
+		bdev->vtrans.trans_ops->signal_vq(req->kvm, &bdev->vtrans, queueid);
+}
+
+static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
+{
+	struct virtio_blk_outhdr *req_hdr;
+	ssize_t block_cnt;
+	struct blk_dev *bdev;
+	struct iovec *iov;
+	u16 out, in;
+
+	block_cnt	= -1;
+	bdev		= req->bdev;
+	iov		= req->iov;
+	out		= req->out;
+	in		= req->in;
+	req_hdr		= iov[0].iov_base;
+
+	switch (req_hdr->type) {
+	case VIRTIO_BLK_T_IN:
+		block_cnt	= disk_image__read(bdev->disk, req_hdr->sector, iov + 1,
+					in + out - 2, req);
+		break;
+	case VIRTIO_BLK_T_OUT:
+		block_cnt	= disk_image__write(bdev->disk, req_hdr->sector, iov + 1,
+					in + out - 2, req);
+		break;
+	case VIRTIO_BLK_T_FLUSH:
+		block_cnt       = disk_image__flush(bdev->disk);
+		virtio_blk_complete(req, block_cnt);
+		break;
+	case VIRTIO_BLK_T_GET_ID:
+		block_cnt	= VIRTIO_BLK_ID_BYTES;
+		disk_image__get_serial(bdev->disk, (iov + 1)->iov_base, &block_cnt);
+		virtio_blk_complete(req, block_cnt);
+		break;
+	default:
+		pr_warning("request type %d", req_hdr->type);
+		block_cnt	= -1;
+		break;
+	}
+}
+
+static void virtio_blk_do_io(struct kvm *kvm, struct virt_queue *vq, struct blk_dev *bdev)
+{
+	struct blk_dev_req *req;
+	u16 head;
+
+	while (virt_queue__available(vq)) {
+		head		= virt_queue__pop(vq);
+		req		= &bdev->reqs[head];
+		req->head	= virt_queue__get_head_iov(vq, req->iov, &req->out, &req->in, head, kvm);
+		req->vq		= vq;
+
+		virtio_blk_do_io_request(kvm, req);
+	}
+}
+
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
+{
+	struct blk_dev *bdev = dev;
+
+	((u8 *)(&bdev->blk_config))[offset] = data;
+}
+
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	struct blk_dev *bdev = dev;
+
+	return ((u8 *)(&bdev->blk_config))[offset];
+}
+
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	return	1UL << VIRTIO_BLK_F_SEG_MAX
+		| 1UL << VIRTIO_BLK_F_FLUSH
+		| 1UL << VIRTIO_RING_F_EVENT_IDX
+		| 1UL << VIRTIO_RING_F_INDIRECT_DESC;
+}
+
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	struct blk_dev *bdev = dev;
+
+	bdev->features = features;
+}
+
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct blk_dev *bdev = dev;
+	struct virt_queue *queue;
+	void *p;
+
+	compat__remove_message(compat_id);
+
+	queue			= &bdev->vqs[vq];
+	queue->pfn		= pfn;
+	p			= guest_pfn_to_host(kvm, queue->pfn);
+
+	vring_init(&queue->vring, VIRTIO_BLK_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
+
+	return 0;
+}
+
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct blk_dev *bdev = dev;
+
+	virtio_blk_do_io(kvm, &bdev->vqs[vq], bdev);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct blk_dev *bdev = dev;
+
+	return bdev->vqs[vq].pfn;
+}
+
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTIO_BLK_QUEUE_SIZE;
+}
+
+static struct virtio_ops blk_dev_virtio_ops = (struct virtio_ops) {
+	.set_config		= set_config,
+	.get_config		= get_config,
+	.get_host_features	= get_host_features,
+	.set_guest_features	= set_guest_features,
+	.init_vq		= init_vq,
+	.notify_vq		= notify_vq,
+	.get_pfn_vq		= get_pfn_vq,
+	.get_size_vq		= get_size_vq,
+};
+
+static int virtio_blk__init_one(struct kvm *kvm, struct disk_image *disk)
+{
+	struct blk_dev *bdev;
+	unsigned int i;
+
+	if (!disk)
+		return -EINVAL;
+
+	bdev = calloc(1, sizeof(struct blk_dev));
+	if (bdev == NULL)
+		return -ENOMEM;
+
+	*bdev = (struct blk_dev) {
+		.mutex			= PTHREAD_MUTEX_INITIALIZER,
+		.req_mutex		= PTHREAD_MUTEX_INITIALIZER,
+		.disk			= disk,
+		.blk_config		= (struct virtio_blk_config) {
+			.capacity	= disk->size / SECTOR_SIZE,
+			.seg_max	= DISK_SEG_MAX,
+		},
+	};
+
+	virtio_trans_init(&bdev->vtrans, VIRTIO_PCI);
+	bdev->vtrans.trans_ops->init(kvm, &bdev->vtrans, bdev, PCI_DEVICE_ID_VIRTIO_BLK,
+					VIRTIO_ID_BLOCK, PCI_CLASS_BLK);
+	bdev->vtrans.virtio_ops = &blk_dev_virtio_ops;
+
+	list_add_tail(&bdev->list, &bdevs);
+
+	for (i = 0; i < ARRAY_SIZE(bdev->reqs); i++) {
+		bdev->reqs[i].bdev	= bdev;
+		bdev->reqs[i].kvm	= kvm;
+	}
+
+	disk_image__set_callback(bdev->disk, virtio_blk_complete);
+
+	if (compat_id != -1)
+		compat_id = compat__add_message("virtio-blk device was not detected",
+						"While you have requested a virtio-blk device, "
+						"the guest kernel did not initialize it.\n"
+						"Please make sure that the guest kernel was "
+						"compiled with CONFIG_VIRTIO_BLK=y enabled "
+						"in its .config");
+	return 0;
+}
+
+static int virtio_blk__exit_one(struct kvm *kvm, struct blk_dev *bdev)
+{
+	list_del(&bdev->list);
+	free(bdev);
+
+	return 0;
+}
+
+int virtio_blk__init(struct kvm *kvm)
+{
+	int i, r = 0;
+
+	for (i = 0; i < kvm->nr_disks; i++) {
+		r = virtio_blk__init_one(kvm, kvm->disks[i]);
+		if (r < 0)
+			goto cleanup;
+	}
+
+	return 0;
+cleanup:
+	return virtio_blk__exit(kvm);
+}
+
+int virtio_blk__exit(struct kvm *kvm)
+{
+	while (!list_empty(&bdevs)) {
+		struct blk_dev *bdev;
+
+		bdev = list_first_entry(&bdevs, struct blk_dev, list);
+		virtio_blk__exit_one(kvm, bdev);
+	}
+
+	return 0;
+}
diff --git a/tools/kvm/virtio/console.c b/tools/kvm/virtio/console.c
new file mode 100644
index 0000000..245cebb
--- /dev/null
+++ b/tools/kvm/virtio/console.c
@@ -0,0 +1,203 @@
+#include "kvm/virtio-console.h"
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/disk-image.h"
+#include "kvm/virtio.h"
+#include "kvm/ioport.h"
+#include "kvm/util.h"
+#include "kvm/term.h"
+#include "kvm/mutex.h"
+#include "kvm/kvm.h"
+#include "kvm/pci.h"
+#include "kvm/threadpool.h"
+#include "kvm/irq.h"
+#include "kvm/guest_compat.h"
+#include "kvm/virtio-trans.h"
+
+#include <linux/virtio_console.h>
+#include <linux/virtio_ring.h>
+#include <linux/virtio_blk.h>
+
+#include <sys/uio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define VIRTIO_CONSOLE_QUEUE_SIZE	128
+#define VIRTIO_CONSOLE_NUM_QUEUES	2
+#define VIRTIO_CONSOLE_RX_QUEUE		0
+#define VIRTIO_CONSOLE_TX_QUEUE		1
+
+struct con_dev {
+	pthread_mutex_t			mutex;
+
+	struct virtio_trans		vtrans;
+	struct virt_queue		vqs[VIRTIO_CONSOLE_NUM_QUEUES];
+	struct virtio_console_config	config;
+	u32				features;
+
+	struct thread_pool__job		jobs[VIRTIO_CONSOLE_NUM_QUEUES];
+};
+
+static struct con_dev cdev = {
+	.mutex				= PTHREAD_MUTEX_INITIALIZER,
+
+	.config = {
+		.cols			= 80,
+		.rows			= 24,
+		.max_nr_ports		= 1,
+	},
+};
+
+static int compat_id = -1;
+
+/*
+ * Interrupts are injected for hvc0 only.
+ */
+static void virtio_console__inject_interrupt_callback(struct kvm *kvm, void *param)
+{
+	struct iovec iov[VIRTIO_CONSOLE_QUEUE_SIZE];
+	struct virt_queue *vq;
+	u16 out, in;
+	u16 head;
+	int len;
+
+	mutex_lock(&cdev.mutex);
+
+	vq = param;
+
+	if (term_readable(CONSOLE_VIRTIO, 0) && virt_queue__available(vq)) {
+		head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
+		len = term_getc_iov(CONSOLE_VIRTIO, iov, in, 0);
+		virt_queue__set_used_elem(vq, head, len);
+		cdev.vtrans.trans_ops->signal_vq(kvm, &cdev.vtrans, vq - cdev.vqs);
+	}
+
+	mutex_unlock(&cdev.mutex);
+}
+
+void virtio_console__inject_interrupt(struct kvm *kvm)
+{
+	thread_pool__do_job(&cdev.jobs[VIRTIO_CONSOLE_RX_QUEUE]);
+}
+
+static void virtio_console_handle_callback(struct kvm *kvm, void *param)
+{
+	struct iovec iov[VIRTIO_CONSOLE_QUEUE_SIZE];
+	struct virt_queue *vq;
+	u16 out, in;
+	u16 head;
+	u32 len;
+
+	vq = param;
+
+	/*
+	 * The current Linux implementation polls for the buffer
+	 * to be used, rather than waiting for an interrupt.
+	 * So there is no need to inject an interrupt for the tx path.
+	 */
+
+	while (virt_queue__available(vq)) {
+		head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
+		len = term_putc_iov(CONSOLE_VIRTIO, iov, out, 0);
+		virt_queue__set_used_elem(vq, head, len);
+	}
+
+}
+
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
+{
+	struct con_dev *cdev = dev;
+
+	((u8 *)(&cdev->config))[offset] = data;
+}
+
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	struct con_dev *cdev = dev;
+
+	return ((u8 *)(&cdev->config))[offset];
+}
+
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	return 0;
+}
+
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	/* Unused */
+}
+
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct virt_queue *queue;
+	void *p;
+
+	BUG_ON(vq >= VIRTIO_CONSOLE_NUM_QUEUES);
+
+	compat__remove_message(compat_id);
+
+	queue			= &cdev.vqs[vq];
+	queue->pfn		= pfn;
+	p			= guest_pfn_to_host(kvm, queue->pfn);
+
+	vring_init(&queue->vring, VIRTIO_CONSOLE_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
+
+	if (vq == VIRTIO_CONSOLE_TX_QUEUE)
+		thread_pool__init_job(&cdev.jobs[vq], kvm, virtio_console_handle_callback, queue);
+	else if (vq == VIRTIO_CONSOLE_RX_QUEUE)
+		thread_pool__init_job(&cdev.jobs[vq], kvm, virtio_console__inject_interrupt_callback, queue);
+
+	return 0;
+}
+
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct con_dev *cdev = dev;
+
+	thread_pool__do_job(&cdev->jobs[vq]);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct con_dev *cdev = dev;
+
+	return cdev->vqs[vq].pfn;
+}
+
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTIO_CONSOLE_QUEUE_SIZE;
+}
+
+static struct virtio_ops con_dev_virtio_ops = (struct virtio_ops) {
+	.set_config		= set_config,
+	.get_config		= get_config,
+	.get_host_features	= get_host_features,
+	.set_guest_features	= set_guest_features,
+	.init_vq		= init_vq,
+	.notify_vq		= notify_vq,
+	.get_pfn_vq		= get_pfn_vq,
+	.get_size_vq		= get_size_vq,
+};
+
+void virtio_console__init(struct kvm *kvm)
+{
+	virtio_trans_init(&cdev.vtrans, VIRTIO_PCI);
+
+	cdev.vtrans.trans_ops->init(kvm, &cdev.vtrans, &cdev, PCI_DEVICE_ID_VIRTIO_CONSOLE,
+					VIRTIO_ID_CONSOLE, PCI_CLASS_CONSOLE);
+	cdev.vtrans.virtio_ops = &con_dev_virtio_ops;
+
+	if (compat_id != -1)
+		compat_id = compat__add_message("virtio-console device was not detected",
+						"While you have requested a virtio-console device, "
+						"the guest kernel did not initialize it.\n"
+						"Please make sure that the guest kernel was "
+						"compiled with CONFIG_VIRTIO_CONSOLE=y enabled "
+						"in its .config");
+}
diff --git a/tools/kvm/virtio/core.c b/tools/kvm/virtio/core.c
new file mode 100644
index 0000000..c68572c
--- /dev/null
+++ b/tools/kvm/virtio/core.c
@@ -0,0 +1,158 @@
+#include <linux/virtio_ring.h>
+#include <linux/types.h>
+#include <sys/uio.h>
+
+#include "kvm/barrier.h"
+
+#include "kvm/kvm.h"
+#include "kvm/virtio.h"
+
+struct vring_used_elem *virt_queue__set_used_elem(struct virt_queue *queue, u32 head, u32 len)
+{
+	struct vring_used_elem *used_elem;
+
+	used_elem	= &queue->vring.used->ring[queue->vring.used->idx % queue->vring.num];
+	used_elem->id	= head;
+	used_elem->len	= len;
+
+	/*
+	 * Use wmb to assure that used elem was updated with head and len.
+	 * We need a wmb here since we can't advance idx unless we're ready
+	 * to pass the used element to the guest.
+	 */
+	wmb();
+	queue->vring.used->idx++;
+
+	/*
+	 * Use wmb to assure used idx has been increased before we signal the guest.
+	 * Without a wmb here the guest may ignore the queue since it won't see
+	 * an updated idx.
+	 */
+	wmb();
+
+	return used_elem;
+}
+
+/*
+ * Each buffer in the virtqueues is actually a chain of descriptors.  This
+ * function returns the next descriptor in the chain, or vq->vring.num if we're
+ * at the end.
+ */
+static unsigned next_desc(struct vring_desc *desc,
+			  unsigned int i, unsigned int max)
+{
+	unsigned int next;
+
+	/* If this descriptor says it doesn't chain, we're done. */
+	if (!(desc[i].flags & VRING_DESC_F_NEXT))
+		return max;
+
+	/* Check they're not leading us off end of descriptors. */
+	next = desc[i].next;
+	/* Make sure compiler knows to grab that: we don't want it changing! */
+	wmb();
+
+	return next;
+}
+
+u16 virt_queue__get_head_iov(struct virt_queue *vq, struct iovec iov[], u16 *out, u16 *in, u16 head, struct kvm *kvm)
+{
+	struct vring_desc *desc;
+	u16 idx;
+	u16 max;
+
+	idx = head;
+	*out = *in = 0;
+	max = vq->vring.num;
+	desc = vq->vring.desc;
+
+	if (desc[idx].flags & VRING_DESC_F_INDIRECT) {
+		max = desc[idx].len / sizeof(struct vring_desc);
+		desc = guest_flat_to_host(kvm, desc[idx].addr);
+		idx = 0;
+	}
+
+	do {
+		/* Grab the first descriptor, and check it's OK. */
+		iov[*out + *in].iov_len = desc[idx].len;
+		iov[*out + *in].iov_base = guest_flat_to_host(kvm, desc[idx].addr);
+		/* If this is an input descriptor, increment that count. */
+		if (desc[idx].flags & VRING_DESC_F_WRITE)
+			(*in)++;
+		else
+			(*out)++;
+	} while ((idx = next_desc(desc, idx, max)) != max);
+
+	return head;
+}
+
+u16 virt_queue__get_iov(struct virt_queue *vq, struct iovec iov[], u16 *out, u16 *in, struct kvm *kvm)
+{
+	u16 head;
+
+	head = virt_queue__pop(vq);
+
+	return virt_queue__get_head_iov(vq, iov, out, in, head, kvm);
+}
+
+/* in and out are relative to guest */
+u16 virt_queue__get_inout_iov(struct kvm *kvm, struct virt_queue *queue,
+			      struct iovec in_iov[], struct iovec out_iov[],
+			      u16 *in, u16 *out)
+{
+	struct vring_desc *desc;
+	u16 head, idx;
+
+	idx = head = virt_queue__pop(queue);
+	*out = *in = 0;
+	do {
+		desc = virt_queue__get_desc(queue, idx);
+		if (desc->flags & VRING_DESC_F_WRITE) {
+			in_iov[*in].iov_base = guest_flat_to_host(kvm,
+								  desc->addr);
+			in_iov[*in].iov_len = desc->len;
+			(*in)++;
+		} else {
+			out_iov[*out].iov_base = guest_flat_to_host(kvm,
+								    desc->addr);
+			out_iov[*out].iov_len = desc->len;
+			(*out)++;
+		}
+		if (desc->flags & VRING_DESC_F_NEXT)
+			idx = desc->next;
+		else
+			break;
+	} while (1);
+
+	return head;
+}
+
+int virtio__get_dev_specific_field(int offset, bool msix, u32 *config_off)
+{
+	if (msix) {
+		if (offset < 4)
+			return VIRTIO_PCI_O_MSIX;
+		else
+			offset -= 4;
+	}
+
+	*config_off = offset;
+
+	return VIRTIO_PCI_O_CONFIG;
+}
+
+bool virtio_queue__should_signal(struct virt_queue *vq)
+{
+	u16 old_idx, new_idx, event_idx;
+
+	old_idx		= vq->last_used_signalled;
+	new_idx		= vq->vring.used->idx;
+	event_idx	= vring_used_event(&vq->vring);
+
+	if (vring_need_event(event_idx, new_idx, old_idx)) {
+		vq->last_used_signalled = new_idx;
+		return true;
+	}
+
+	return false;
+}
diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
new file mode 100644
index 0000000..5e29708
--- /dev/null
+++ b/tools/kvm/virtio/net.c
@@ -0,0 +1,547 @@
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/virtio-net.h"
+#include "kvm/virtio.h"
+#include "kvm/types.h"
+#include "kvm/mutex.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/irq.h"
+#include "kvm/uip.h"
+#include "kvm/guest_compat.h"
+#include "kvm/virtio-trans.h"
+
+#include <linux/vhost.h>
+#include <linux/virtio_net.h>
+#include <linux/if_tun.h>
+#include <linux/types.h>
+
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/eventfd.h>
+
+#define VIRTIO_NET_QUEUE_SIZE		128
+#define VIRTIO_NET_NUM_QUEUES		2
+#define VIRTIO_NET_RX_QUEUE		0
+#define VIRTIO_NET_TX_QUEUE		1
+
+struct net_dev;
+
+extern struct kvm *kvm;
+
+struct net_dev_operations {
+	int (*rx)(struct iovec *iov, u16 in, struct net_dev *ndev);
+	int (*tx)(struct iovec *iov, u16 in, struct net_dev *ndev);
+};
+
+struct net_dev {
+	pthread_mutex_t			mutex;
+	struct virtio_trans		vtrans;
+	struct list_head		list;
+
+	struct virt_queue		vqs[VIRTIO_NET_NUM_QUEUES];
+	struct virtio_net_config	config;
+	u32				features;
+
+	pthread_t			io_rx_thread;
+	pthread_mutex_t			io_rx_lock;
+	pthread_cond_t			io_rx_cond;
+
+	pthread_t			io_tx_thread;
+	pthread_mutex_t			io_tx_lock;
+	pthread_cond_t			io_tx_cond;
+
+	int				vhost_fd;
+	int				tap_fd;
+	char				tap_name[IFNAMSIZ];
+
+	int				mode;
+
+	struct uip_info			info;
+	struct net_dev_operations	*ops;
+	struct kvm			*kvm;
+};
+
+static LIST_HEAD(ndevs);
+static int compat_id = -1;
+
+static void *virtio_net_rx_thread(void *p)
+{
+	struct iovec iov[VIRTIO_NET_QUEUE_SIZE];
+	struct virt_queue *vq;
+	struct kvm *kvm;
+	struct net_dev *ndev = p;
+	u16 out, in;
+	u16 head;
+	int len;
+
+	kvm	= ndev->kvm;
+	vq	= &ndev->vqs[VIRTIO_NET_RX_QUEUE];
+
+	while (1) {
+		mutex_lock(&ndev->io_rx_lock);
+		if (!virt_queue__available(vq))
+			pthread_cond_wait(&ndev->io_rx_cond, &ndev->io_rx_lock);
+		mutex_unlock(&ndev->io_rx_lock);
+
+		while (virt_queue__available(vq)) {
+			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
+			len = ndev->ops->rx(iov, in, ndev);
+			virt_queue__set_used_elem(vq, head, len);
+
+			/* We should interrupt guest right now, otherwise latency is huge. */
+			if (virtio_queue__should_signal(&ndev->vqs[VIRTIO_NET_RX_QUEUE]))
+				ndev->vtrans.trans_ops->signal_vq(kvm, &ndev->vtrans,
+								VIRTIO_NET_RX_QUEUE);
+		}
+	}
+
+	pthread_exit(NULL);
+	return NULL;
+
+}
+
+static void *virtio_net_tx_thread(void *p)
+{
+	struct iovec iov[VIRTIO_NET_QUEUE_SIZE];
+	struct virt_queue *vq;
+	struct kvm *kvm;
+	struct net_dev *ndev = p;
+	u16 out, in;
+	u16 head;
+	int len;
+
+	kvm	= ndev->kvm;
+	vq	= &ndev->vqs[VIRTIO_NET_TX_QUEUE];
+
+	while (1) {
+		mutex_lock(&ndev->io_tx_lock);
+		if (!virt_queue__available(vq))
+			pthread_cond_wait(&ndev->io_tx_cond, &ndev->io_tx_lock);
+		mutex_unlock(&ndev->io_tx_lock);
+
+		while (virt_queue__available(vq)) {
+			head = virt_queue__get_iov(vq, iov, &out, &in, kvm);
+			len = ndev->ops->tx(iov, out, ndev);
+			virt_queue__set_used_elem(vq, head, len);
+		}
+
+		if (virtio_queue__should_signal(&ndev->vqs[VIRTIO_NET_TX_QUEUE]))
+			ndev->vtrans.trans_ops->signal_vq(kvm, &ndev->vtrans, VIRTIO_NET_TX_QUEUE);
+	}
+
+	pthread_exit(NULL);
+
+	return NULL;
+
+}
+
+static void virtio_net_handle_callback(struct kvm *kvm, struct net_dev *ndev, int queue)
+{
+	switch (queue) {
+	case VIRTIO_NET_TX_QUEUE:
+		mutex_lock(&ndev->io_tx_lock);
+		pthread_cond_signal(&ndev->io_tx_cond);
+		mutex_unlock(&ndev->io_tx_lock);
+		break;
+	case VIRTIO_NET_RX_QUEUE:
+		mutex_lock(&ndev->io_rx_lock);
+		pthread_cond_signal(&ndev->io_rx_cond);
+		mutex_unlock(&ndev->io_rx_lock);
+		break;
+	default:
+		pr_warning("Unknown queue index %u", queue);
+	}
+}
+
+static bool virtio_net__tap_init(const struct virtio_net_params *params,
+					struct net_dev *ndev)
+{
+	int sock = socket(AF_INET, SOCK_STREAM, 0);
+	int pid, status, offload, hdr_len;
+	struct sockaddr_in sin = {0};
+	struct ifreq ifr;
+
+	/* Did the user already gave us the FD? */
+	if (params->fd) {
+		ndev->tap_fd = params->fd;
+		return 1;
+	}
+
+	ndev->tap_fd = open("/dev/net/tun", O_RDWR);
+	if (ndev->tap_fd < 0) {
+		pr_warning("Unable to open /dev/net/tun");
+		goto fail;
+	}
+
+	memset(&ifr, 0, sizeof(ifr));
+	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+	if (ioctl(ndev->tap_fd, TUNSETIFF, &ifr) < 0) {
+		pr_warning("Config tap device error. Are you root?");
+		goto fail;
+	}
+
+	strncpy(ndev->tap_name, ifr.ifr_name, sizeof(ndev->tap_name));
+
+	if (ioctl(ndev->tap_fd, TUNSETNOCSUM, 1) < 0) {
+		pr_warning("Config tap device TUNSETNOCSUM error");
+		goto fail;
+	}
+
+	hdr_len = sizeof(struct virtio_net_hdr);
+	if (ioctl(ndev->tap_fd, TUNSETVNETHDRSZ, &hdr_len) < 0)
+		pr_warning("Config tap device TUNSETVNETHDRSZ error");
+
+	offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_UFO;
+	if (ioctl(ndev->tap_fd, TUNSETOFFLOAD, offload) < 0) {
+		pr_warning("Config tap device TUNSETOFFLOAD error");
+		goto fail;
+	}
+
+	if (strcmp(params->script, "none")) {
+		pid = fork();
+		if (pid == 0) {
+			execl(params->script, params->script, ndev->tap_name, NULL);
+			_exit(1);
+		} else {
+			waitpid(pid, &status, 0);
+			if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
+				pr_warning("Fail to setup tap by %s", params->script);
+				goto fail;
+			}
+		}
+	} else {
+		memset(&ifr, 0, sizeof(ifr));
+		strncpy(ifr.ifr_name, ndev->tap_name, sizeof(ndev->tap_name));
+		sin.sin_addr.s_addr = inet_addr(params->host_ip);
+		memcpy(&(ifr.ifr_addr), &sin, sizeof(ifr.ifr_addr));
+		ifr.ifr_addr.sa_family = AF_INET;
+		if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
+			pr_warning("Could not set ip address on tap device");
+			goto fail;
+		}
+	}
+
+	memset(&ifr, 0, sizeof(ifr));
+	strncpy(ifr.ifr_name, ndev->tap_name, sizeof(ndev->tap_name));
+	ioctl(sock, SIOCGIFFLAGS, &ifr);
+	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+	if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
+		pr_warning("Could not bring tap device up");
+
+	close(sock);
+
+	return 1;
+
+fail:
+	if (sock >= 0)
+		close(sock);
+	if (ndev->tap_fd >= 0)
+		close(ndev->tap_fd);
+
+	return 0;
+}
+
+static void virtio_net__io_thread_init(struct kvm *kvm, struct net_dev *ndev)
+{
+	pthread_mutex_init(&ndev->io_tx_lock, NULL);
+	pthread_mutex_init(&ndev->io_rx_lock, NULL);
+
+	pthread_cond_init(&ndev->io_tx_cond, NULL);
+	pthread_cond_init(&ndev->io_rx_cond, NULL);
+
+	pthread_create(&ndev->io_tx_thread, NULL, virtio_net_tx_thread, ndev);
+	pthread_create(&ndev->io_rx_thread, NULL, virtio_net_rx_thread, ndev);
+}
+
+static inline int tap_ops_tx(struct iovec *iov, u16 out, struct net_dev *ndev)
+{
+	return writev(ndev->tap_fd, iov, out);
+}
+
+static inline int tap_ops_rx(struct iovec *iov, u16 in, struct net_dev *ndev)
+{
+	return readv(ndev->tap_fd, iov, in);
+}
+
+static inline int uip_ops_tx(struct iovec *iov, u16 out, struct net_dev *ndev)
+{
+	return uip_tx(iov, out, &ndev->info);
+}
+
+static inline int uip_ops_rx(struct iovec *iov, u16 in, struct net_dev *ndev)
+{
+	return uip_rx(iov, in, &ndev->info);
+}
+
+static struct net_dev_operations tap_ops = {
+	.rx	= tap_ops_rx,
+	.tx	= tap_ops_tx,
+};
+
+static struct net_dev_operations uip_ops = {
+	.rx	= uip_ops_rx,
+	.tx	= uip_ops_tx,
+};
+
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
+{
+	struct net_dev *ndev = dev;
+
+	((u8 *)(&ndev->config))[offset] = data;
+}
+
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	struct net_dev *ndev = dev;
+
+	return ((u8 *)(&ndev->config))[offset];
+}
+
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	return 1UL << VIRTIO_NET_F_MAC
+		| 1UL << VIRTIO_NET_F_CSUM
+		| 1UL << VIRTIO_NET_F_HOST_UFO
+		| 1UL << VIRTIO_NET_F_HOST_TSO4
+		| 1UL << VIRTIO_NET_F_HOST_TSO6
+		| 1UL << VIRTIO_NET_F_GUEST_UFO
+		| 1UL << VIRTIO_NET_F_GUEST_TSO4
+		| 1UL << VIRTIO_NET_F_GUEST_TSO6
+		| 1UL << VIRTIO_RING_F_EVENT_IDX
+		| 1UL << VIRTIO_RING_F_INDIRECT_DESC;
+}
+
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	struct net_dev *ndev = dev;
+
+	ndev->features = features;
+}
+
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct vhost_vring_state state = { .index = vq };
+	struct vhost_vring_addr addr;
+	struct net_dev *ndev = dev;
+	struct virt_queue *queue;
+	void *p;
+	int r;
+
+	compat__remove_message(compat_id);
+
+	queue		= &ndev->vqs[vq];
+	queue->pfn	= pfn;
+	p		= guest_pfn_to_host(kvm, queue->pfn);
+
+	vring_init(&queue->vring, VIRTIO_NET_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
+
+	if (ndev->vhost_fd == 0)
+		return 0;
+
+	state.num = queue->vring.num;
+	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_NUM, &state);
+	if (r < 0)
+		die_perror("VHOST_SET_VRING_NUM failed");
+	state.num = 0;
+	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_BASE, &state);
+	if (r < 0)
+		die_perror("VHOST_SET_VRING_BASE failed");
+
+	addr = (struct vhost_vring_addr) {
+		.index = vq,
+		.desc_user_addr = (u64)(unsigned long)queue->vring.desc,
+		.avail_user_addr = (u64)(unsigned long)queue->vring.avail,
+		.used_user_addr = (u64)(unsigned long)queue->vring.used,
+	};
+
+	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_ADDR, &addr);
+	if (r < 0)
+		die_perror("VHOST_SET_VRING_ADDR failed");
+
+	return 0;
+}
+
+static void notify_vq_gsi(struct kvm *kvm, void *dev, u32 vq, u32 gsi)
+{
+	struct net_dev *ndev = dev;
+	struct kvm_irqfd irq;
+	struct vhost_vring_file file;
+	int r;
+
+	if (ndev->vhost_fd == 0)
+		return;
+
+	irq = (struct kvm_irqfd) {
+		.gsi	= gsi,
+		.fd	= eventfd(0, 0),
+	};
+	file = (struct vhost_vring_file) {
+		.index	= vq,
+		.fd	= irq.fd,
+	};
+
+	r = ioctl(kvm->vm_fd, KVM_IRQFD, &irq);
+	if (r < 0)
+		die_perror("KVM_IRQFD failed");
+
+	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_CALL, &file);
+	if (r < 0)
+		die_perror("VHOST_SET_VRING_CALL failed");
+	file.fd = ndev->tap_fd;
+	r = ioctl(ndev->vhost_fd, VHOST_NET_SET_BACKEND, &file);
+	if (r != 0)
+		die("VHOST_NET_SET_BACKEND failed %d", errno);
+
+}
+
+static void notify_vq_eventfd(struct kvm *kvm, void *dev, u32 vq, u32 efd)
+{
+	struct net_dev *ndev = dev;
+	struct vhost_vring_file file = {
+		.index	= vq,
+		.fd	= efd,
+	};
+	int r;
+
+	if (ndev->vhost_fd == 0)
+		return;
+
+	r = ioctl(ndev->vhost_fd, VHOST_SET_VRING_KICK, &file);
+	if (r < 0)
+		die_perror("VHOST_SET_VRING_KICK failed");
+}
+
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct net_dev *ndev = dev;
+
+	virtio_net_handle_callback(kvm, ndev, vq);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct net_dev *ndev = dev;
+
+	return ndev->vqs[vq].pfn;
+}
+
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTIO_NET_QUEUE_SIZE;
+}
+
+static struct virtio_ops net_dev_virtio_ops = (struct virtio_ops) {
+	.set_config		= set_config,
+	.get_config		= get_config,
+	.get_host_features	= get_host_features,
+	.set_guest_features	= set_guest_features,
+	.init_vq		= init_vq,
+	.notify_vq		= notify_vq,
+	.get_pfn_vq		= get_pfn_vq,
+	.get_size_vq		= get_size_vq,
+	.notify_vq_gsi		= notify_vq_gsi,
+	.notify_vq_eventfd	= notify_vq_eventfd,
+};
+
+static void virtio_net__vhost_init(struct kvm *kvm, struct net_dev *ndev)
+{
+	u64 features = 1UL << VIRTIO_RING_F_EVENT_IDX;
+	struct vhost_memory *mem;
+	int r;
+
+	ndev->vhost_fd = open("/dev/vhost-net", O_RDWR);
+	if (ndev->vhost_fd < 0)
+		die_perror("Failed openning vhost-net device");
+
+	mem = malloc(sizeof(*mem) + sizeof(struct vhost_memory_region));
+	if (mem == NULL)
+		die("Failed allocating memory for vhost memory map");
+
+	mem->nregions = 1;
+	mem->regions[0] = (struct vhost_memory_region) {
+		.guest_phys_addr	= 0,
+		.memory_size		= kvm->ram_size,
+		.userspace_addr		= (unsigned long)kvm->ram_start,
+	};
+
+	r = ioctl(ndev->vhost_fd, VHOST_SET_OWNER);
+	if (r != 0)
+		die_perror("VHOST_SET_OWNER failed");
+
+	r = ioctl(ndev->vhost_fd, VHOST_SET_FEATURES, &features);
+	if (r != 0)
+		die_perror("VHOST_SET_FEATURES failed");
+	r = ioctl(ndev->vhost_fd, VHOST_SET_MEM_TABLE, mem);
+	if (r != 0)
+		die_perror("VHOST_SET_MEM_TABLE failed");
+	free(mem);
+}
+
+void virtio_net__init(const struct virtio_net_params *params)
+{
+	int i;
+	struct net_dev *ndev;
+
+	if (!params)
+		return;
+
+	ndev = calloc(1, sizeof(struct net_dev));
+	if (ndev == NULL)
+		die("Failed allocating ndev");
+
+	list_add_tail(&ndev->list, &ndevs);
+
+	ndev->kvm = params->kvm;
+
+	mutex_init(&ndev->mutex);
+	ndev->config.status = VIRTIO_NET_S_LINK_UP;
+
+	for (i = 0 ; i < 6 ; i++) {
+		ndev->config.mac[i]		= params->guest_mac[i];
+		ndev->info.guest_mac.addr[i]	= params->guest_mac[i];
+		ndev->info.host_mac.addr[i]	= params->host_mac[i];
+	}
+
+	ndev->mode = params->mode;
+	if (ndev->mode == NET_MODE_TAP) {
+		if (!virtio_net__tap_init(params, ndev))
+			die_perror("You have requested a TAP device, but creation of one has"
+					"failed because:");
+		ndev->ops = &tap_ops;
+	} else {
+		ndev->info.host_ip		= ntohl(inet_addr(params->host_ip));
+		ndev->info.guest_ip		= ntohl(inet_addr(params->guest_ip));
+		ndev->info.guest_netmask	= ntohl(inet_addr("255.255.255.0"));
+		ndev->info.buf_nr		= 20,
+		uip_init(&ndev->info);
+		ndev->ops = &uip_ops;
+	}
+
+	virtio_trans_init(&ndev->vtrans, VIRTIO_PCI);
+	ndev->vtrans.trans_ops->init(kvm, &ndev->vtrans, ndev, PCI_DEVICE_ID_VIRTIO_NET,
+					VIRTIO_ID_NET, PCI_CLASS_NET);
+	ndev->vtrans.virtio_ops = &net_dev_virtio_ops;
+
+	if (params->vhost)
+		virtio_net__vhost_init(params->kvm, ndev);
+	else
+		virtio_net__io_thread_init(params->kvm, ndev);
+
+	if (compat_id != -1)
+		compat_id = compat__add_message("virtio-net device was not detected",
+						"While you have requested a virtio-net device, "
+						"the guest kernel did not initialize it.\n"
+						"Please make sure that the guest kernel was "
+						"compiled with CONFIG_VIRTIO_NET=y enabled "
+						"in its .config");
+}
diff --git a/tools/kvm/virtio/pci.c b/tools/kvm/virtio/pci.c
new file mode 100644
index 0000000..5a3cad8
--- /dev/null
+++ b/tools/kvm/virtio/pci.c
@@ -0,0 +1,380 @@
+#include "kvm/virtio-pci.h"
+
+#include "kvm/ioport.h"
+#include "kvm/kvm.h"
+#include "kvm/virtio-pci-dev.h"
+#include "kvm/irq.h"
+#include "kvm/virtio.h"
+#include "kvm/ioeventfd.h"
+#include "kvm/virtio-trans.h"
+
+#include <linux/virtio_pci.h>
+#include <linux/byteorder.h>
+#include <string.h>
+
+struct virtio_trans_ops *virtio_pci__get_trans_ops(void)
+{
+	static struct virtio_trans_ops virtio_pci_trans = (struct virtio_trans_ops) {
+		.signal_vq	= virtio_pci__signal_vq,
+		.signal_config	= virtio_pci__signal_config,
+		.init		= virtio_pci__init,
+		.uninit		= virtio_pci__exit,
+	};
+	return &virtio_pci_trans;
+};
+
+static void virtio_pci__ioevent_callback(struct kvm *kvm, void *param)
+{
+	struct virtio_pci_ioevent_param *ioeventfd = param;
+	struct virtio_pci *vpci = ioeventfd->vtrans->virtio;
+
+	ioeventfd->vtrans->virtio_ops->notify_vq(kvm, vpci->dev, ioeventfd->vq);
+}
+
+static int virtio_pci__init_ioeventfd(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
+{
+	struct ioevent ioevent;
+	struct virtio_pci *vpci = vtrans->virtio;
+	int r;
+
+	vpci->ioeventfds[vq] = (struct virtio_pci_ioevent_param) {
+		.vtrans		= vtrans,
+		.vq		= vq,
+	};
+
+	ioevent = (struct ioevent) {
+		.io_addr	= vpci->base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
+		.io_len		= sizeof(u16),
+		.fn		= virtio_pci__ioevent_callback,
+		.fn_ptr		= &vpci->ioeventfds[vq],
+		.datamatch	= vq,
+		.fn_kvm		= kvm,
+		.fd		= eventfd(0, 0),
+	};
+
+	r = ioeventfd__add_event(&ioevent);
+	if (r)
+		return r;
+
+	if (vtrans->virtio_ops->notify_vq_eventfd)
+		vtrans->virtio_ops->notify_vq_eventfd(kvm, vpci->dev, vq, ioevent.fd);
+
+	return 0;
+}
+
+static inline bool virtio_pci__msix_enabled(struct virtio_pci *vpci)
+{
+	return vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_ENABLE);
+}
+
+static bool virtio_pci__specific_io_in(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
+					void *data, int size, int offset)
+{
+	u32 config_offset;
+	struct virtio_pci *vpci = vtrans->virtio;
+	int type = virtio__get_dev_specific_field(offset - 20,
+							virtio_pci__msix_enabled(vpci),
+							&config_offset);
+	if (type == VIRTIO_PCI_O_MSIX) {
+		switch (offset) {
+		case VIRTIO_MSI_CONFIG_VECTOR:
+			ioport__write16(data, vpci->config_vector);
+			break;
+		case VIRTIO_MSI_QUEUE_VECTOR:
+			ioport__write16(data, vpci->vq_vector[vpci->queue_selector]);
+			break;
+		};
+
+		return true;
+	} else if (type == VIRTIO_PCI_O_CONFIG) {
+		u8 cfg;
+
+		cfg = vtrans->virtio_ops->get_config(kvm, vpci->dev, config_offset);
+		ioport__write8(data, cfg);
+		return true;
+	}
+
+	return false;
+}
+
+static bool virtio_pci__io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	unsigned long offset;
+	bool ret = true;
+	struct virtio_trans *vtrans;
+	struct virtio_pci *vpci;
+	u32 val;
+
+	vtrans = ioport->priv;
+	vpci = vtrans->virtio;
+	offset = port - vpci->base_addr;
+
+	switch (offset) {
+	case VIRTIO_PCI_HOST_FEATURES:
+		val = vtrans->virtio_ops->get_host_features(kvm, vpci->dev);
+		ioport__write32(data, val);
+		break;
+	case VIRTIO_PCI_QUEUE_PFN:
+		val = vtrans->virtio_ops->get_pfn_vq(kvm, vpci->dev, vpci->queue_selector);
+		ioport__write32(data, val);
+		break;
+	case VIRTIO_PCI_QUEUE_NUM:
+		val = vtrans->virtio_ops->get_size_vq(kvm, vpci->dev, vpci->queue_selector);
+		ioport__write16(data, val);
+		break;
+	case VIRTIO_PCI_STATUS:
+		ioport__write8(data, vpci->status);
+		break;
+	case VIRTIO_PCI_ISR:
+		ioport__write8(data, vpci->isr);
+		kvm__irq_line(kvm, vpci->pci_hdr.irq_line, VIRTIO_IRQ_LOW);
+		vpci->isr = VIRTIO_IRQ_LOW;
+		break;
+	default:
+		ret = virtio_pci__specific_io_in(kvm, vtrans, port, data, size, offset);
+		break;
+	};
+
+	return ret;
+}
+
+static bool virtio_pci__specific_io_out(struct kvm *kvm, struct virtio_trans *vtrans, u16 port,
+					void *data, int size, int offset)
+{
+	struct virtio_pci *vpci = vtrans->virtio;
+	u32 config_offset, gsi, vec;
+	int type = virtio__get_dev_specific_field(offset - 20, virtio_pci__msix_enabled(vpci),
+							&config_offset);
+	if (type == VIRTIO_PCI_O_MSIX) {
+		switch (offset) {
+		case VIRTIO_MSI_CONFIG_VECTOR:
+			vec = vpci->config_vector = ioport__read16(data);
+
+			gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg);
+
+			vpci->config_gsi = gsi;
+			break;
+		case VIRTIO_MSI_QUEUE_VECTOR:
+			vec = vpci->vq_vector[vpci->queue_selector] = ioport__read16(data);
+
+			gsi = irq__add_msix_route(kvm, &vpci->msix_table[vec].msg);
+			vpci->gsis[vpci->queue_selector] = gsi;
+			if (vtrans->virtio_ops->notify_vq_gsi)
+				vtrans->virtio_ops->notify_vq_gsi(kvm, vpci->dev,
+							vpci->queue_selector, gsi);
+			break;
+		};
+
+		return true;
+	} else if (type == VIRTIO_PCI_O_CONFIG) {
+		vtrans->virtio_ops->set_config(kvm, vpci->dev, *(u8 *)data, config_offset);
+
+		return true;
+	}
+
+	return false;
+}
+
+static bool virtio_pci__io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	unsigned long offset;
+	bool ret = true;
+	struct virtio_trans *vtrans;
+	struct virtio_pci *vpci;
+	u32 val;
+
+	vtrans = ioport->priv;
+	vpci = vtrans->virtio;
+	offset = port - vpci->base_addr;
+
+	switch (offset) {
+	case VIRTIO_PCI_GUEST_FEATURES:
+		val = ioport__read32(data);
+		vtrans->virtio_ops->set_guest_features(kvm, vpci->dev, val);
+		break;
+	case VIRTIO_PCI_QUEUE_PFN:
+		val = ioport__read32(data);
+		virtio_pci__init_ioeventfd(kvm, vtrans, vpci->queue_selector);
+		vtrans->virtio_ops->init_vq(kvm, vpci->dev, vpci->queue_selector, val);
+		break;
+	case VIRTIO_PCI_QUEUE_SEL:
+		vpci->queue_selector = ioport__read16(data);
+		break;
+	case VIRTIO_PCI_QUEUE_NOTIFY:
+		val = ioport__read16(data);
+		vtrans->virtio_ops->notify_vq(kvm, vpci->dev, val);
+		break;
+	case VIRTIO_PCI_STATUS:
+		vpci->status = ioport__read8(data);
+		break;
+	default:
+		ret = virtio_pci__specific_io_out(kvm, vtrans, port, data, size, offset);
+		break;
+	};
+
+	return ret;
+}
+
+static struct ioport_operations virtio_pci__io_ops = {
+	.io_in	= virtio_pci__io_in,
+	.io_out	= virtio_pci__io_out,
+};
+
+static void callback_mmio_table(u64 addr, u8 *data, u32 len, u8 is_write, void *ptr)
+{
+	struct virtio_pci *vpci = ptr;
+	void *table;
+	u32 offset;
+
+	if (addr > vpci->msix_io_block + PCI_IO_SIZE) {
+		table	= &vpci->msix_pba;
+		offset	= vpci->msix_io_block + PCI_IO_SIZE;
+	} else {
+		table	= &vpci->msix_table;
+		offset	= vpci->msix_io_block;
+	}
+
+	if (is_write)
+		memcpy(table + addr - offset, data, len);
+	else
+		memcpy(data, table + addr - offset, len);
+}
+
+int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_trans *vtrans, u32 vq)
+{
+	struct virtio_pci *vpci = vtrans->virtio;
+	int tbl = vpci->vq_vector[vq];
+
+	if (virtio_pci__msix_enabled(vpci)) {
+		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
+
+			vpci->msix_pba |= 1 << tbl;
+			return 0;
+		}
+
+		kvm__irq_trigger(kvm, vpci->gsis[vq]);
+	} else {
+		vpci->isr = VIRTIO_IRQ_HIGH;
+		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
+	}
+	return 0;
+}
+
+int virtio_pci__signal_config(struct kvm *kvm, struct virtio_trans *vtrans)
+{
+	struct virtio_pci *vpci = vtrans->virtio;
+	int tbl = vpci->config_vector;
+
+	if (virtio_pci__msix_enabled(vpci)) {
+		if (vpci->pci_hdr.msix.ctrl & cpu_to_le16(PCI_MSIX_FLAGS_MASKALL) ||
+		    vpci->msix_table[tbl].ctrl & cpu_to_le16(PCI_MSIX_ENTRY_CTRL_MASKBIT)) {
+
+			vpci->msix_pba |= 1 << tbl;
+			return 0;
+		}
+
+		kvm__irq_trigger(kvm, vpci->config_gsi);
+	} else {
+		vpci->isr = VIRTIO_PCI_ISR_CONFIG;
+		kvm__irq_trigger(kvm, vpci->pci_hdr.irq_line);
+	}
+
+	return 0;
+}
+
+int virtio_pci__init(struct kvm *kvm, struct virtio_trans *vtrans, void *dev,
+			int device_id, int subsys_id, int class)
+{
+	struct virtio_pci *vpci = vtrans->virtio;
+	u8 pin, line, ndev;
+	int r;
+
+	vpci->dev = dev;
+	vpci->msix_io_block = pci_get_io_space_block(PCI_IO_SIZE * 2);
+
+	r = ioport__register(IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vtrans);
+	if (r < 0)
+		return r;
+
+	vpci->base_addr = (u16)r;
+	r = kvm__register_mmio(kvm, vpci->msix_io_block, PCI_IO_SIZE, false, callback_mmio_table, vpci);
+	if (r < 0)
+		goto free_ioport;
+
+	vpci->pci_hdr = (struct pci_device_header) {
+		.vendor_id		= cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
+		.device_id		= cpu_to_le16(device_id),
+		.header_type		= PCI_HEADER_TYPE_NORMAL,
+		.revision_id		= 0,
+		.class[0]		= class & 0xff,
+		.class[1]		= (class >> 8) & 0xff,
+		.class[2]		= (class >> 16) & 0xff,
+		.subsys_vendor_id	= cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET),
+		.subsys_id		= cpu_to_le16(subsys_id),
+		.bar[0]			= cpu_to_le32(vpci->base_addr
+							| PCI_BASE_ADDRESS_SPACE_IO),
+		.bar[1]			= cpu_to_le32(vpci->msix_io_block
+							| PCI_BASE_ADDRESS_SPACE_MEMORY),
+		.status			= cpu_to_le16(PCI_STATUS_CAP_LIST),
+		.capabilities		= (void *)&vpci->pci_hdr.msix - (void *)&vpci->pci_hdr,
+		.bar_size[0]		= IOPORT_SIZE,
+		.bar_size[1]		= PCI_IO_SIZE,
+		.bar_size[3]		= PCI_IO_SIZE,
+	};
+
+	vpci->pci_hdr.msix.cap = PCI_CAP_ID_MSIX;
+	vpci->pci_hdr.msix.next = 0;
+	/*
+	 * We at most have VIRTIO_PCI_MAX_VQ entries for virt queue,
+	 * VIRTIO_PCI_MAX_CONFIG entries for config.
+	 *
+	 * To quote the PCI spec:
+	 *
+	 * System software reads this field to determine the
+	 * MSI-X Table Size N, which is encoded as N-1.
+	 * For example, a returned value of "00000000011"
+	 * indicates a table size of 4.
+	 */
+	vpci->pci_hdr.msix.ctrl = cpu_to_le16(VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG - 1);
+
+	/*
+	 * Both table and PBA could be mapped on the same BAR, but for now
+	 * we're not in short of BARs
+	 */
+	vpci->pci_hdr.msix.table_offset = cpu_to_le32(1); /* Use BAR 1 */
+	vpci->pci_hdr.msix.pba_offset = cpu_to_le32(1 | PCI_IO_SIZE); /* Use BAR 3 */
+	vpci->config_vector = 0;
+
+	r = irq__register_device(subsys_id, &ndev, &pin, &line);
+	if (r < 0)
+		goto free_mmio;
+
+	vpci->pci_hdr.irq_pin	= pin;
+	vpci->pci_hdr.irq_line	= line;
+	r = pci__register(&vpci->pci_hdr, ndev);
+	if (r < 0)
+		goto free_ioport;
+
+	return 0;
+
+free_mmio:
+	kvm__deregister_mmio(kvm, vpci->msix_io_block);
+free_ioport:
+	ioport__unregister(vpci->base_addr);
+	return r;
+}
+
+int virtio_pci__exit(struct kvm *kvm, struct virtio_trans *vtrans)
+{
+	struct virtio_pci *vpci = vtrans->virtio;
+	int i;
+
+	kvm__deregister_mmio(kvm, vpci->msix_io_block);
+	ioport__unregister(vpci->base_addr);
+
+	for (i = 0; i < VIRTIO_PCI_MAX_VQ; i++)
+		ioeventfd__del_event(vpci->base_addr + VIRTIO_PCI_QUEUE_NOTIFY, i);
+
+	return 0;
+}
\ No newline at end of file
diff --git a/tools/kvm/virtio/rng.c b/tools/kvm/virtio/rng.c
new file mode 100644
index 0000000..a942ebd
--- /dev/null
+++ b/tools/kvm/virtio/rng.c
@@ -0,0 +1,203 @@
+#include "kvm/virtio-rng.h"
+
+#include "kvm/virtio-pci-dev.h"
+
+#include "kvm/virtio.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+#include "kvm/threadpool.h"
+#include "kvm/guest_compat.h"
+#include "kvm/virtio-trans.h"
+
+#include <linux/virtio_ring.h>
+#include <linux/virtio_rng.h>
+
+#include <linux/list.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pthread.h>
+#include <linux/kernel.h>
+
+#define NUM_VIRT_QUEUES		1
+#define VIRTIO_RNG_QUEUE_SIZE	128
+
+struct rng_dev_job {
+	struct virt_queue	*vq;
+	struct rng_dev		*rdev;
+	struct thread_pool__job	job_id;
+};
+
+struct rng_dev {
+	struct list_head	list;
+	struct virtio_trans	vtrans;
+
+	int			fd;
+
+	/* virtio queue */
+	struct virt_queue	vqs[NUM_VIRT_QUEUES];
+	struct rng_dev_job	jobs[NUM_VIRT_QUEUES];
+};
+
+static LIST_HEAD(rdevs);
+static int compat_id = -1;
+
+static void set_config(struct kvm *kvm, void *dev, u8 data, u32 offset)
+{
+	/* Unused */
+}
+
+static u8 get_config(struct kvm *kvm, void *dev, u32 offset)
+{
+	/* Unused */
+	return 0;
+}
+
+static u32 get_host_features(struct kvm *kvm, void *dev)
+{
+	/* Unused */
+	return 0;
+}
+
+static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
+{
+	/* Unused */
+}
+
+static bool virtio_rng_do_io_request(struct kvm *kvm, struct rng_dev *rdev, struct virt_queue *queue)
+{
+	struct iovec iov[VIRTIO_RNG_QUEUE_SIZE];
+	unsigned int len = 0;
+	u16 out, in, head;
+
+	head	= virt_queue__get_iov(queue, iov, &out, &in, kvm);
+	len	= readv(rdev->fd, iov, in);
+
+	virt_queue__set_used_elem(queue, head, len);
+
+	return true;
+}
+
+static void virtio_rng_do_io(struct kvm *kvm, void *param)
+{
+	struct rng_dev_job *job	= param;
+	struct virt_queue *vq	= job->vq;
+	struct rng_dev *rdev	= job->rdev;
+
+	while (virt_queue__available(vq))
+		virtio_rng_do_io_request(kvm, rdev, vq);
+
+	rdev->vtrans.trans_ops->signal_vq(kvm, &rdev->vtrans, vq - rdev->vqs);
+}
+
+static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 pfn)
+{
+	struct rng_dev *rdev = dev;
+	struct virt_queue *queue;
+	struct rng_dev_job *job;
+	void *p;
+
+	compat__remove_message(compat_id);
+
+	queue		= &rdev->vqs[vq];
+	queue->pfn	= pfn;
+	p		= guest_pfn_to_host(kvm, queue->pfn);
+
+	job = &rdev->jobs[vq];
+
+	vring_init(&queue->vring, VIRTIO_RNG_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
+
+	*job = (struct rng_dev_job) {
+		.vq	= queue,
+		.rdev	= rdev,
+	};
+
+	thread_pool__init_job(&job->job_id, kvm, virtio_rng_do_io, job);
+
+	return 0;
+}
+
+static int notify_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct rng_dev *rdev = dev;
+
+	thread_pool__do_job(&rdev->jobs[vq].job_id);
+
+	return 0;
+}
+
+static int get_pfn_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	struct rng_dev *rdev = dev;
+
+	return rdev->vqs[vq].pfn;
+}
+
+static int get_size_vq(struct kvm *kvm, void *dev, u32 vq)
+{
+	return VIRTIO_RNG_QUEUE_SIZE;
+}
+
+static struct virtio_ops rng_dev_virtio_ops = (struct virtio_ops) {
+	.set_config		= set_config,
+	.get_config		= get_config,
+	.get_host_features	= get_host_features,
+	.set_guest_features	= set_guest_features,
+	.init_vq		= init_vq,
+	.notify_vq		= notify_vq,
+	.get_pfn_vq		= get_pfn_vq,
+	.get_size_vq		= get_size_vq,
+};
+
+int virtio_rng__init(struct kvm *kvm)
+{
+	struct rng_dev *rdev;
+	int r;
+
+	rdev = malloc(sizeof(*rdev));
+	if (rdev == NULL)
+		return -ENOMEM;
+
+	rdev->fd = open("/dev/urandom", O_RDONLY);
+	if (rdev->fd < 0) {
+		r = rdev->fd;
+		goto cleanup;
+	}
+
+	virtio_trans_init(&rdev->vtrans, VIRTIO_PCI);
+	r = rdev->vtrans.trans_ops->init(kvm, &rdev->vtrans, rdev, PCI_DEVICE_ID_VIRTIO_RNG,
+					VIRTIO_ID_RNG, PCI_CLASS_RNG);
+	if (r < 0)
+		goto cleanup;
+
+	rdev->vtrans.virtio_ops = &rng_dev_virtio_ops;
+
+	list_add_tail(&rdev->list, &rdevs);
+
+	if (compat_id != -1)
+		compat_id = compat__add_message("virtio-rng device was not detected",
+						"While you have requested a virtio-rng device, "
+						"the guest kernel did not initialize it.\n"
+						"Please make sure that the guest kernel was "
+						"compiled with CONFIG_HW_RANDOM_VIRTIO=y enabled "
+						"in its .config");
+	return 0;
+cleanup:
+	close(rdev->fd);
+	free(rdev);
+
+	return r;
+}
+
+int virtio_rng__exit(struct kvm *kvm)
+{
+	struct rng_dev *rdev, *tmp;
+
+	list_for_each_entry_safe(rdev, tmp, &rdevs, list) {
+		list_del(&rdev->list);
+		rdev->vtrans.trans_ops->uninit(kvm, &rdev->vtrans);
+		free(rdev);
+	}
+
+	return 0;
+}
diff --git a/tools/kvm/virtio/trans.c b/tools/kvm/virtio/trans.c
new file mode 100644
index 0000000..cd4fc7e
--- /dev/null
+++ b/tools/kvm/virtio/trans.c
@@ -0,0 +1,24 @@
+#include "kvm/virtio-trans.h"
+
+#include "kvm/virtio-pci.h"
+#include "kvm/util.h"
+
+#include <stdlib.h>
+
+int virtio_trans_init(struct virtio_trans *vtrans, enum virtio_trans_type type)
+{
+	void *trans;
+
+	switch (type) {
+	case VIRTIO_PCI:
+		trans = calloc(sizeof(struct virtio_pci), 1);
+		if (!trans)
+			return -ENOMEM;
+		vtrans->virtio = trans;
+		vtrans->trans_ops = virtio_pci__get_trans_ops();
+	default:
+		return -1;
+	};
+
+	return 0;
+}
\ No newline at end of file
diff --git a/tools/kvm/x86/bios.c b/tools/kvm/x86/bios.c
new file mode 100644
index 0000000..0f1bd85
--- /dev/null
+++ b/tools/kvm/x86/bios.c
@@ -0,0 +1,174 @@
+#include "kvm/kvm.h"
+#include "kvm/boot-protocol.h"
+#include "kvm/e820.h"
+#include "kvm/interrupt.h"
+#include "kvm/util.h"
+
+#include <string.h>
+#include <asm/e820.h>
+
+#include "bios/bios-rom.h"
+
+struct irq_handler {
+	unsigned long		address;
+	unsigned int		irq;
+	void			*handler;
+	size_t			size;
+};
+
+#define BIOS_IRQ_PA_ADDR(name)	(MB_BIOS_BEGIN + BIOS_OFFSET__##name)
+#define BIOS_IRQ_FUNC(name)	((char *)&bios_rom[BIOS_OFFSET__##name])
+#define BIOS_IRQ_SIZE(name)	(BIOS_ENTRY_SIZE(BIOS_OFFSET__##name))
+
+#define DEFINE_BIOS_IRQ_HANDLER(_irq, _handler)			\
+	{							\
+		.irq		= _irq,				\
+		.address	= BIOS_IRQ_PA_ADDR(_handler),	\
+		.handler	= BIOS_IRQ_FUNC(_handler),	\
+		.size		= BIOS_IRQ_SIZE(_handler),	\
+	}
+
+static struct irq_handler bios_irq_handlers[] = {
+	DEFINE_BIOS_IRQ_HANDLER(0x10, bios_int10),
+	DEFINE_BIOS_IRQ_HANDLER(0x15, bios_int15),
+};
+
+static void setup_irq_handler(struct kvm *kvm, struct irq_handler *handler)
+{
+	struct real_intr_desc intr_desc;
+	void *p;
+
+	p = guest_flat_to_host(kvm, handler->address);
+	memcpy(p, handler->handler, handler->size);
+
+	intr_desc = (struct real_intr_desc) {
+		.segment	= REAL_SEGMENT(MB_BIOS_BEGIN),
+		.offset		= handler->address - MB_BIOS_BEGIN,
+	};
+
+	DIE_IF((handler->address - MB_BIOS_BEGIN) > 0xffffUL);
+
+	interrupt_table__set(&kvm->interrupt_table, &intr_desc, handler->irq);
+}
+
+/**
+ * e820_setup - setup some simple E820 memory map
+ * @kvm - guest system descriptor
+ */
+static void e820_setup(struct kvm *kvm)
+{
+	struct e820map *e820;
+	struct e820entry *mem_map;
+	unsigned int i = 0;
+
+	e820		= guest_flat_to_host(kvm, E820_MAP_START);
+	mem_map		= e820->map;
+
+	mem_map[i++]	= (struct e820entry) {
+		.addr		= REAL_MODE_IVT_BEGIN,
+		.size		= EBDA_START - REAL_MODE_IVT_BEGIN,
+		.type		= E820_RAM,
+	};
+	mem_map[i++]	= (struct e820entry) {
+		.addr		= EBDA_START,
+		.size		= VGA_RAM_BEGIN - EBDA_START,
+		.type		= E820_RESERVED,
+	};
+	mem_map[i++]	= (struct e820entry) {
+		.addr		= MB_BIOS_BEGIN,
+		.size		= MB_BIOS_END - MB_BIOS_BEGIN,
+		.type		= E820_RESERVED,
+	};
+	if (kvm->ram_size < KVM_32BIT_GAP_START) {
+		mem_map[i++]	= (struct e820entry) {
+			.addr		= BZ_KERNEL_START,
+			.size		= kvm->ram_size - BZ_KERNEL_START,
+			.type		= E820_RAM,
+		};
+	} else {
+		mem_map[i++]	= (struct e820entry) {
+			.addr		= BZ_KERNEL_START,
+			.size		= KVM_32BIT_GAP_START - BZ_KERNEL_START,
+			.type		= E820_RAM,
+		};
+		mem_map[i++]	= (struct e820entry) {
+			.addr		= KVM_32BIT_MAX_MEM_SIZE,
+			.size		= kvm->ram_size - KVM_32BIT_MAX_MEM_SIZE,
+			.type		= E820_RAM,
+		};
+	}
+
+	BUG_ON(i > E820_X_MAX);
+
+	e820->nr_map = i;
+}
+
+static void setup_vga_rom(struct kvm *kvm)
+{
+	u16 *mode;
+	void *p;
+
+	p = guest_flat_to_host(kvm, VGA_ROM_OEM_STRING);
+	memset(p, 0, VGA_ROM_OEM_STRING_SIZE);
+	strncpy(p, "KVM VESA", VGA_ROM_OEM_STRING_SIZE);
+
+	mode = guest_flat_to_host(kvm, VGA_ROM_MODES);
+	mode[0]	= 0x0112;
+	mode[1] = 0xffff;
+}
+
+/**
+ * setup_bios - inject BIOS into guest memory
+ * @kvm - guest system descriptor
+ */
+void setup_bios(struct kvm *kvm)
+{
+	unsigned long address = MB_BIOS_BEGIN;
+	struct real_intr_desc intr_desc;
+	unsigned int i;
+	void *p;
+
+	/*
+	 * before anything else -- clean some known areas
+	 * we definitely don't want any trash here
+	 */
+	p = guest_flat_to_host(kvm, BDA_START);
+	memset(p, 0, BDA_END - BDA_START);
+
+	p = guest_flat_to_host(kvm, EBDA_START);
+	memset(p, 0, EBDA_END - EBDA_START);
+
+	p = guest_flat_to_host(kvm, MB_BIOS_BEGIN);
+	memset(p, 0, MB_BIOS_END - MB_BIOS_BEGIN);
+
+	p = guest_flat_to_host(kvm, VGA_ROM_BEGIN);
+	memset(p, 0, VGA_ROM_END - VGA_ROM_BEGIN);
+
+	/* just copy the bios rom into the place */
+	p = guest_flat_to_host(kvm, MB_BIOS_BEGIN);
+	memcpy(p, bios_rom, bios_rom_size);
+
+	/* E820 memory map must be present */
+	e820_setup(kvm);
+
+	/* VESA needs own tricks */
+	setup_vga_rom(kvm);
+
+	/*
+	 * Setup a *fake* real mode vector table, it has only
+	 * one real handler which does just iret
+	 */
+	address = BIOS_IRQ_PA_ADDR(bios_intfake);
+	intr_desc = (struct real_intr_desc) {
+		.segment	= REAL_SEGMENT(MB_BIOS_BEGIN),
+		.offset		= address - MB_BIOS_BEGIN,
+	};
+	interrupt_table__setup(&kvm->interrupt_table, &intr_desc);
+
+	for (i = 0; i < ARRAY_SIZE(bios_irq_handlers); i++)
+		setup_irq_handler(kvm, &bios_irq_handlers[i]);
+
+	/* we almost done */
+	p = guest_flat_to_host(kvm, 0);
+	interrupt_table__copy(&kvm->interrupt_table, p, REAL_INTR_SIZE);
+}
diff --git a/tools/kvm/x86/bios/.gitignore b/tools/kvm/x86/bios/.gitignore
new file mode 100644
index 0000000..1f0080b
--- /dev/null
+++ b/tools/kvm/x86/bios/.gitignore
@@ -0,0 +1,3 @@
+bios-rom.bin
+bios-rom.bin.elf
+bios-rom.h
diff --git a/tools/kvm/x86/bios/bios-rom.S b/tools/kvm/x86/bios/bios-rom.S
new file mode 100644
index 0000000..3269ce9
--- /dev/null
+++ b/tools/kvm/x86/bios/bios-rom.S
@@ -0,0 +1,12 @@
+#include <kvm/assembly.h>
+
+	.org 0
+#ifdef CONFIG_X86_64
+	.code64
+#else
+	.code32
+#endif
+
+GLOBAL(bios_rom)
+	.incbin "x86/bios/bios.bin"
+END(bios_rom)
diff --git a/tools/kvm/x86/bios/e820.c b/tools/kvm/x86/bios/e820.c
new file mode 100644
index 0000000..a9bca29
--- /dev/null
+++ b/tools/kvm/x86/bios/e820.c
@@ -0,0 +1,72 @@
+#include "kvm/e820.h"
+
+#include "kvm/segment.h"
+#include "kvm/bios.h"
+
+#include <asm/processor-flags.h>
+#include <asm/e820.h>
+
+static inline void set_fs(u16 seg)
+{
+	asm volatile("movw %0,%%fs" : : "rm" (seg));
+}
+
+static inline u8 rdfs8(unsigned long addr)
+{
+	u8 v;
+
+	asm volatile("addr32 movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
+
+	return v;
+}
+
+static inline u32 rdfs32(unsigned long addr)
+{
+	u32 v;
+
+	asm volatile("addr32 movl %%fs:%1,%0" : "=q" (v) : "m" (*(u32 *)addr));
+
+	return v;
+}
+
+bioscall void e820_query_map(struct biosregs *regs)
+{
+	struct e820map *e820;
+	u32 map_size;
+	u16 fs_seg;
+	u32 ndx;
+
+	e820		= (struct e820map *)E820_MAP_START;
+	fs_seg		= flat_to_seg16(E820_MAP_START);
+	set_fs(fs_seg);
+
+	ndx		= regs->ebx;
+
+	map_size	= rdfs32(flat_to_off16((u32)&e820->nr_map, fs_seg));
+
+	if (ndx < map_size) {
+		u32 start;
+		unsigned int i;
+		u8 *p;
+
+		fs_seg	= flat_to_seg16(E820_MAP_START);
+		set_fs(fs_seg);
+
+		start	= (u32)&e820->map[ndx];
+
+		p	= (void *) regs->edi;
+
+		for (i = 0; i < sizeof(struct e820entry); i++)
+			*p++	= rdfs8(flat_to_off16(start + i, fs_seg));
+	}
+
+	regs->eax	= SMAP;
+	regs->ecx	= sizeof(struct e820entry);
+	regs->ebx	= ++ndx;
+
+	/* Clear CF to indicate success.  */
+	regs->eflags	&= ~X86_EFLAGS_CF;
+
+	if (ndx >= map_size)
+		regs->ebx	= 0;	/* end of map */
+}
diff --git a/tools/kvm/x86/bios/entry.S b/tools/kvm/x86/bios/entry.S
new file mode 100644
index 0000000..85056e9
--- /dev/null
+++ b/tools/kvm/x86/bios/entry.S
@@ -0,0 +1,92 @@
+/*
+ * Our pretty trivial BIOS emulation
+ */
+
+#include <kvm/bios.h>
+#include <kvm/assembly.h>
+
+	.org 0
+	.code16gcc
+
+#define EFLAGS_CF	(1 << 0)
+
+#include "macro.S"
+
+/* If you change these macros, remember to update 'struct biosregs' */
+.macro SAVE_BIOSREGS
+	pushl	%fs
+	pushl	%es
+	pushl	%ds
+	pushl	%edi
+	pushl	%esi
+	pushl	%ebp
+	pushl	%esp
+	pushl	%edx
+	pushl	%ecx
+	pushl	%ebx
+	pushl	%eax
+.endm
+
+.macro RESTORE_BIOSREGS
+	popl	%eax
+	popl	%ebx
+	popl	%ecx
+	popl	%edx
+	popl	%esp
+	popl	%ebp
+	popl	%esi
+	popl	%edi
+	popl	%ds
+	popl	%es
+	popl	%fs
+.endm
+
+/*
+ * fake interrupt handler, nothing can be faster ever
+ */
+ENTRY(bios_intfake)
+	/*
+	 * Set CF to indicate failure. We don't want callers to think that the
+	 * interrupt handler succeeded and then treat the return values in
+	 * registers as valid data.
+	 */
+	orl	$EFLAGS_CF, 0x4(%esp)
+
+	IRET
+ENTRY_END(bios_intfake)
+
+/*
+ * int 10 - video - service
+ */
+ENTRY(bios_int10)
+	SAVE_BIOSREGS
+
+	movl		%esp, %eax
+	/* this is way easier than doing it in assembly */
+	/* just push all the regs and jump to a C handler */
+	call	int10_handler
+
+	RESTORE_BIOSREGS
+
+	/* Clear CF to indicate success.  */
+	andl	$~EFLAGS_CF, 0x4(%esp)
+
+	IRET
+ENTRY_END(bios_int10)
+
+ENTRY(bios_int15)
+	SAVE_BIOSREGS
+
+	movl	%esp, %eax
+	call	int15_handler
+
+	RESTORE_BIOSREGS
+
+	IRET
+ENTRY_END(bios_int15)
+
+GLOBAL(__locals)
+
+#include "local.S"
+
+END(__locals)
diff --git a/tools/kvm/x86/bios/gen-offsets.sh b/tools/kvm/x86/bios/gen-offsets.sh
new file mode 100644
index 0000000..8771bbe
--- /dev/null
+++ b/tools/kvm/x86/bios/gen-offsets.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+echo "/* Autogenerated file, don't edit */"
+echo "#ifndef BIOS_OFFSETS_H"
+echo "#define BIOS_OFFSETS_H"
+
+echo ""
+echo "#define BIOS_ENTRY_SIZE(name) (name##_end - name)"
+echo ""
+
+nm bios.bin.elf | grep ' [Tt] ' | awk '{ print "#define BIOS_OFFSET__" $3 " 0x" $1; }'
+
+echo ""
+echo "#endif"
diff --git a/tools/kvm/x86/bios/int10.c b/tools/kvm/x86/bios/int10.c
new file mode 100644
index 0000000..7cc0b3f
--- /dev/null
+++ b/tools/kvm/x86/bios/int10.c
@@ -0,0 +1,110 @@
+#include "kvm/segment.h"
+#include "kvm/bios.h"
+#include "kvm/vesa.h"
+
+#include "bios/memcpy.h"
+
+#include <boot/vesa.h>
+
+static far_ptr gen_far_ptr(unsigned int pa)
+{
+	far_ptr ptr;
+
+	ptr.seg = (pa >> 4);
+	ptr.off = pa - (ptr.seg << 4);
+
+	return ptr;
+}
+
+static inline void outb(unsigned short port, unsigned char val)
+{
+	asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
+}
+
+/*
+ * It's probably much more useful to make this print to the serial
+ * line rather than print to a non-displayed VGA memory
+ */
+static inline void int10_putchar(struct biosregs *args)
+{
+	u8 al = args->eax & 0xFF;
+
+	outb(0x3f8, al);
+}
+
+static void vbe_get_mode(struct biosregs *args)
+{
+	struct vesa_mode_info *info = (struct vesa_mode_info *) args->edi;
+
+	*info = (struct vesa_mode_info) {
+		.mode_attr		= 0xd9, /* 11011011 */
+		.logical_scan		= VESA_WIDTH*4,
+		.h_res			= VESA_WIDTH,
+		.v_res			= VESA_HEIGHT,
+		.bpp			= VESA_BPP,
+		.memory_layout		= 6,
+		.memory_planes		= 1,
+		.lfb_ptr		= VESA_MEM_ADDR,
+		.rmask			= 8,
+		.gmask			= 8,
+		.bmask			= 8,
+		.resv_mask		= 8,
+		.resv_pos		= 24,
+		.bpos			= 16,
+		.gpos			= 8,
+	};
+}
+
+static void vbe_get_info(struct biosregs *args)
+{
+	struct vesa_general_info *infop = (struct vesa_general_info *) args->edi;
+	struct vesa_general_info info;
+
+	info = (struct vesa_general_info) {
+		.signature		= VESA_MAGIC,
+		.version		= 0x102,
+		.vendor_string		= gen_far_ptr(VGA_ROM_BEGIN),
+		.capabilities		= 0x10,
+		.video_mode_ptr		= gen_far_ptr(VGA_ROM_MODES),
+		.total_memory		= (4 * VESA_WIDTH * VESA_HEIGHT) / 0x10000,
+	};
+
+	memcpy16(args->es, infop, args->ds, &info, sizeof(info));
+}
+
+#define VBE_STATUS_OK		0x004F
+
+static void int10_vesa(struct biosregs *args)
+{
+	u8 al;
+
+	al = args->eax & 0xff;
+
+	switch (al) {
+	case 0x00:
+		vbe_get_info(args);
+		break;
+	case 0x01:
+		vbe_get_mode(args);
+		break;
+	}
+
+	args->eax = VBE_STATUS_OK;
+}
+
+bioscall void int10_handler(struct biosregs *args)
+{
+	u8 ah;
+
+	ah = (args->eax & 0xff00) >> 8;
+
+	switch (ah) {
+	case 0x0e:
+		int10_putchar(args);
+		break;
+	case 0x4f:
+		int10_vesa(args);
+		break;
+	}
+
+}
diff --git a/tools/kvm/x86/bios/int15.c b/tools/kvm/x86/bios/int15.c
new file mode 100644
index 0000000..faf5343
--- /dev/null
+++ b/tools/kvm/x86/bios/int15.c
@@ -0,0 +1,18 @@
+#include "kvm/bios.h"
+
+#include "kvm/e820.h"
+
+#include <asm/processor-flags.h>
+
+bioscall void int15_handler(struct biosregs *regs)
+{
+	switch (regs->eax) {
+	case 0xe820:
+		e820_query_map(regs);
+		break;
+	default:
+		/* Set CF to indicate failure.  */
+		regs->eflags	|= X86_EFLAGS_CF;
+		break;
+	}
+}
diff --git a/tools/kvm/x86/bios/local.S b/tools/kvm/x86/bios/local.S
new file mode 100644
index 0000000..f2cdbf4
--- /dev/null
+++ b/tools/kvm/x86/bios/local.S
@@ -0,0 +1,7 @@
+/*
+ * Local variables for almost every BIOS irq handler
+ * Must be put somewhere inside irq handler body
+ */
+__CALLER_SS:		.int  0
+__CALLER_SP:		.long 0
+__CALLER_CLOBBER:	.long 0
diff --git a/tools/kvm/x86/bios/macro.S b/tools/kvm/x86/bios/macro.S
new file mode 100644
index 0000000..0d5e567e
--- /dev/null
+++ b/tools/kvm/x86/bios/macro.S
@@ -0,0 +1,25 @@
+/*
+ * handy BIOS macros
+ */
+
+/*
+ * switch to BIOS stack
+ */
+.macro stack_swap
+	movw %ss, %cs:(__CALLER_SS)
+	movl %esp, %cs:(__CALLER_SP)
+	movl %edx, %cs:(__CALLER_CLOBBER)
+	movw $MB_BIOS_SS, %dx
+	movw %dx, %ss
+	movw $MB_BIOS_SP, %sp
+	movl %cs:(__CALLER_CLOBBER), %edx
+.endm
+
+/*
+ * restore the original stack
+ */
+.macro stack_restore
+	movl %cs:(__CALLER_SP), %esp
+	movw %cs:(__CALLER_SS), %ss
+.endm
+
diff --git a/tools/kvm/x86/bios/memcpy.c b/tools/kvm/x86/bios/memcpy.c
new file mode 100644
index 0000000..40b9b65
--- /dev/null
+++ b/tools/kvm/x86/bios/memcpy.c
@@ -0,0 +1,23 @@
+#include "bios/memcpy.h"
+
+/*
+ *  Copy memory area in 16-bit real mode.
+ */
+void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len)
+{
+	__asm__ __volatile__ (
+		"pushw	%%ds				\n"
+		"pushw	%%es				\n"
+		"movw	%[src_seg], %%ds		\n"
+		"movw	%[dst_seg], %%es		\n"
+		"rep movsb %%ds:(%%si), %%es:(%%di)	\n"
+		"popw	%%es				\n"
+		"popw	%%ds				\n"
+		:
+		: "S"(src),
+		  "D"(dst),
+		  "c"(len),
+		  [src_seg] "r"(src_seg),
+		  [dst_seg] "r"(dst_seg)
+		: "cc", "memory");
+}
diff --git a/tools/kvm/x86/bios/rom.ld.S b/tools/kvm/x86/bios/rom.ld.S
new file mode 100644
index 0000000..98c53aa
--- /dev/null
+++ b/tools/kvm/x86/bios/rom.ld.S
@@ -0,0 +1,10 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+
+SECTIONS {
+	. = 0;
+	.text : {
+		*(.text)
+	}
+}
+
diff --git a/tools/kvm/x86/cpuid.c b/tools/kvm/x86/cpuid.c
new file mode 100644
index 0000000..75f3b4d
--- /dev/null
+++ b/tools/kvm/x86/cpuid.c
@@ -0,0 +1,55 @@
+#include "kvm/kvm-cpu.h"
+
+#include "kvm/kvm.h"
+#include "kvm/util.h"
+
+#include <sys/ioctl.h>
+#include <stdlib.h>
+
+#define CPUID_FUNC_PERFMON		0x0A
+
+#define	MAX_KVM_CPUID_ENTRIES		100
+
+static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid)
+{
+	unsigned int i;
+
+	/*
+	 * Filter CPUID functions that are not supported by the hypervisor.
+	 */
+	for (i = 0; i < kvm_cpuid->nent; i++) {
+		struct kvm_cpuid_entry2 *entry = &kvm_cpuid->entries[i];
+
+		switch (entry->function) {
+		case 6:
+			/* Clear presence of IA32_ENERGY_PERF_BIAS */
+			entry->ecx = entry->ecx & ~(1 << 3);
+			break;
+		case CPUID_FUNC_PERFMON:
+			entry->eax = 0x00; /* disable it */
+			break;
+		default:
+			/* Keep the CPUID function as -is */
+			break;
+		};
+	}
+}
+
+void kvm_cpu__setup_cpuid(struct kvm_cpu *vcpu)
+{
+	struct kvm_cpuid2 *kvm_cpuid;
+
+	kvm_cpuid = calloc(1, sizeof(*kvm_cpuid) +
+				MAX_KVM_CPUID_ENTRIES * sizeof(*kvm_cpuid->entries));
+
+	kvm_cpuid->nent = MAX_KVM_CPUID_ENTRIES;
+	if (ioctl(vcpu->kvm->sys_fd, KVM_GET_SUPPORTED_CPUID, kvm_cpuid) < 0)
+		die_perror("KVM_GET_SUPPORTED_CPUID failed");
+
+	filter_cpuid(kvm_cpuid);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_CPUID2, kvm_cpuid) < 0)
+		die_perror("KVM_SET_CPUID2 failed");
+
+	free(kvm_cpuid);
+}
diff --git a/tools/kvm/x86/include/kvm/assembly.h b/tools/kvm/x86/include/kvm/assembly.h
new file mode 100644
index 0000000..e70baab
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/assembly.h
@@ -0,0 +1,24 @@
+#ifndef ASSEMBLY_H_
+#define ASSEMBLY_H_
+
+#define __ALIGN	.p2align 4, 0x90
+#define ENTRY(name)	\
+	__ALIGN;	\
+	.globl name;	\
+	name:
+
+#define GLOBAL(name)	\
+	.globl name;	\
+	name:
+
+#define ENTRY_END(name)	GLOBAL(name##_end)
+#define END(name)	GLOBAL(name##_end)
+
+/*
+ * gas produces size override prefix with which
+ * we are unhappy, lets make it hardcoded for
+ * 16 bit mode
+ */
+#define IRET	.byte 0xcf
+
+#endif /* ASSEMBLY_H_ */
diff --git a/tools/kvm/x86/include/kvm/barrier.h b/tools/kvm/x86/include/kvm/barrier.h
new file mode 100644
index 0000000..480276f
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/barrier.h
@@ -0,0 +1,16 @@
+#ifndef _KVM_BARRIER_H_
+#define _KVM_BARRIER_H_
+
+/*
+ * asm/system.h cannot be #included standalone on 32-bit x86 yet.
+ *
+ * Provide the dependencies here - we can drop these wrappers once
+ * the header is fixed upstream:
+ */
+#include <stdbool.h>
+#include <linux/stringify.h>
+#include <linux/bitops.h>
+#include <asm/alternative.h>
+#include <asm/system.h>
+
+#endif /* _KVM_BARRIER_H_ */
diff --git a/tools/kvm/x86/include/kvm/bios-export.h b/tools/kvm/x86/include/kvm/bios-export.h
new file mode 100644
index 0000000..23825aa
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/bios-export.h
@@ -0,0 +1,13 @@
+#ifndef BIOS_EXPORT_H_
+#define BIOS_EXPORT_H_
+
+struct kvm;
+
+extern char bios_rom[0];
+extern char bios_rom_end[0];
+
+#define bios_rom_size		(bios_rom_end - bios_rom)
+
+extern void setup_bios(struct kvm *kvm);
+
+#endif /* BIOS_EXPORT_H_ */
diff --git a/tools/kvm/x86/include/kvm/bios.h b/tools/kvm/x86/include/kvm/bios.h
new file mode 100644
index 0000000..de569bc
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/bios.h
@@ -0,0 +1,88 @@
+#ifndef BIOS_H_
+#define BIOS_H_
+
+/*
+ * X86-32 Memory Map (typical)
+ *					start      end
+ * Real Mode Interrupt Vector Table	0x00000000 0x000003FF
+ * BDA area				0x00000400 0x000004FF
+ * Conventional Low Memory		0x00000500 0x0009FBFF
+ * EBDA area				0x0009FC00 0x0009FFFF
+ * VIDEO RAM				0x000A0000 0x000BFFFF
+ * VIDEO ROM (BIOS)			0x000C0000 0x000C7FFF
+ * Motherboard BIOS			0x000F0000 0x000FFFFF
+ * Extended Memory			0x00100000 0xFEBFFFFF
+ * Reserved (configs, ACPI, PnP, etc)	0xFEC00000 0xFFFFFFFF
+ */
+
+#define REAL_MODE_IVT_BEGIN		0x00000000
+#define REAL_MODE_IVT_END		0x000003ff
+
+#define BDA_START			0x00000400
+#define BDA_END				0x000004ff
+
+#define EBDA_START			0x0009fc00
+#define EBDA_END			0x0009ffff
+
+#define E820_MAP_START			EBDA_START
+
+#define MB_BIOS_BEGIN			0x000f0000
+#define MB_BIOS_END			0x000fffff
+
+#define VGA_RAM_BEGIN			0x000a0000
+#define VGA_RAM_END			0x000bffff
+
+#define VGA_ROM_BEGIN			0x000c0000
+#define VGA_ROM_OEM_STRING		VGA_ROM_BEGIN
+#define VGA_ROM_OEM_STRING_SIZE		16
+#define VGA_ROM_MODES			(VGA_ROM_OEM_STRING + VGA_ROM_OEM_STRING_SIZE)
+#define VGA_ROM_MODES_SIZE		32
+#define VGA_ROM_END			0x000c7fff
+
+/* we handle one page only */
+#define VGA_RAM_SEG			(VGA_RAM_BEGIN >> 4)
+#define VGA_PAGE_SIZE			0x007d0 /* 80x25 */
+
+/* real mode interrupt vector table */
+#define REAL_INTR_BASE			REAL_MODE_IVT_BEGIN
+#define REAL_INTR_VECTORS		256
+
+/*
+ * BIOS stack must be at absolute predefined memory address
+ * We reserve 64 bytes for BIOS stack
+ */
+#define MB_BIOS_SS			0xfff7
+#define MB_BIOS_SP			0x40
+
+/*
+ * When interfere with assembler code we need to be sure how
+ * arguments are passed in real mode.
+ */
+#define bioscall __attribute__((regparm(3)))
+
+#ifndef __ASSEMBLER__
+
+#include <linux/types.h>
+
+struct biosregs {
+	u32			eax;
+	u32			ebx;
+	u32			ecx;
+	u32			edx;
+	u32			esp;
+	u32			ebp;
+	u32			esi;
+	u32			edi;
+	u32			ds;
+	u32			es;
+	u32			fs;
+	u32			eip;
+	u32			eflags;
+};
+
+extern bioscall void int10_handler(struct biosregs *regs);
+extern bioscall void int15_handler(struct biosregs *regs);
+
+#endif
+
+#endif /* BIOS_H_ */
diff --git a/tools/kvm/x86/include/kvm/boot-protocol.h b/tools/kvm/x86/include/kvm/boot-protocol.h
new file mode 100644
index 0000000..85b637f
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/boot-protocol.h
@@ -0,0 +1,16 @@
+/*
+ * Linux boot protocol specifics
+ */
+
+#ifndef BOOT_PROTOCOL_H_
+#define BOOT_PROTOCOL_H_
+
+/*
+ * The protected mode kernel part of a modern bzImage is loaded
+ * at 1 MB by default.
+ */
+#define BZ_DEFAULT_SETUP_SECTS		4
+#define BZ_KERNEL_START			0x100000UL
+#define INITRD_START			0x1000000UL
+
+#endif /* BOOT_PROTOCOL_H_ */
diff --git a/tools/kvm/x86/include/kvm/cpufeature.h b/tools/kvm/x86/include/kvm/cpufeature.h
new file mode 100644
index 0000000..bc4abbb
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/cpufeature.h
@@ -0,0 +1,41 @@
+#ifndef KVM__CPUFEATURE_H
+#define KVM__CPUFEATURE_H
+
+#define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
+#define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
+#define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
+
+#define CPUID_VENDOR_AMD_1   0x68747541 /* "Auth" */
+#define CPUID_VENDOR_AMD_2   0x69746e65 /* "enti" */
+#define CPUID_VENDOR_AMD_3   0x444d4163 /* "cAMD" */
+
+/*
+ * CPUID flags we need to deal with
+ */
+#define KVM__X86_FEATURE_VMX		5	/* Hardware virtualization */
+#define KVM__X86_FEATURE_SVM		2	/* Secure virtual machine */
+#define KVM__X86_FEATURE_XSAVE		26	/* XSAVE/XRSTOR/XSETBV/XGETBV */
+
+#define cpu_feature_disable(reg, feature)	\
+	((reg) & ~(1 << (feature)))
+#define cpu_feature_enable(reg, feature)	\
+	((reg) |  (1 << (feature)))
+
+struct cpuid_regs {
+	u32	eax;
+	u32	ebx;
+	u32	ecx;
+	u32	edx;
+};
+
+static inline void host_cpuid(struct cpuid_regs *regs)
+{
+	asm volatile("cpuid"
+		: "=a" (regs->eax),
+		  "=b" (regs->ebx),
+		  "=c" (regs->ecx),
+		  "=d" (regs->edx)
+		: "0" (regs->eax), "2" (regs->ecx));
+}
+
+#endif /* KVM__CPUFEATURE_H */
diff --git a/tools/kvm/x86/include/kvm/interrupt.h b/tools/kvm/x86/include/kvm/interrupt.h
new file mode 100644
index 0000000..00c7ed7
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/interrupt.h
@@ -0,0 +1,26 @@
+#ifndef KVM__INTERRUPT_H
+#define KVM__INTERRUPT_H
+
+#include <linux/types.h>
+#include "kvm/bios.h"
+#include "kvm/bios-export.h"
+
+struct real_intr_desc {
+	u16 offset;
+	u16 segment;
+} __attribute__((packed));
+
+#define REAL_SEGMENT_SHIFT	4
+#define REAL_SEGMENT(addr)	((addr) >> REAL_SEGMENT_SHIFT)
+#define REAL_OFFSET(addr)	((addr) & ((1 << REAL_SEGMENT_SHIFT) - 1))
+#define REAL_INTR_SIZE		(REAL_INTR_VECTORS * sizeof(struct real_intr_desc))
+
+struct interrupt_table {
+	struct real_intr_desc entries[REAL_INTR_VECTORS];
+};
+
+void interrupt_table__copy(struct interrupt_table *itable, void *dst, unsigned int size);
+void interrupt_table__setup(struct interrupt_table *itable, struct real_intr_desc *entry);
+void interrupt_table__set(struct interrupt_table *itable, struct real_intr_desc *entry, unsigned int num);
+
+#endif /* KVM__INTERRUPT_H */
diff --git a/tools/kvm/x86/include/kvm/kvm-arch.h b/tools/kvm/x86/include/kvm/kvm-arch.h
new file mode 100644
index 0000000..31c0fb8
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/kvm-arch.h
@@ -0,0 +1,65 @@
+#ifndef KVM__KVM_ARCH_H
+#define KVM__KVM_ARCH_H
+
+#include "kvm/interrupt.h"
+#include "kvm/segment.h"
+
+#include <stdbool.h>
+#include <linux/types.h>
+#include <time.h>
+
+/*
+ * The hole includes VESA framebuffer and PCI memory.
+ */
+#define KVM_32BIT_MAX_MEM_SIZE  (1ULL << 32)
+#define KVM_32BIT_GAP_SIZE	(768 << 20)
+#define KVM_32BIT_GAP_START	(KVM_32BIT_MAX_MEM_SIZE - KVM_32BIT_GAP_SIZE)
+
+#define KVM_MMIO_START		KVM_32BIT_GAP_START
+
+/* This is the address that pci_get_io_space_block() starts allocating
+ * from.  Note that this is a PCI bus address (though same on x86).
+ */
+#define KVM_PCI_MMIO_AREA	(KVM_MMIO_START + 0x1000000)
+
+struct kvm {
+	int			sys_fd;		/* For system ioctls(), i.e. /dev/kvm */
+	int			vm_fd;		/* For VM ioctls() */
+	timer_t			timerid;	/* Posix timer for interrupts */
+
+	int			nrcpus;		/* Number of cpus to run */
+
+	u32			mem_slots;	/* for KVM_SET_USER_MEMORY_REGION */
+
+	u64			ram_size;
+	void			*ram_start;
+
+	bool			nmi_disabled;
+
+	bool			single_step;
+
+	u16			boot_selector;
+	u16			boot_ip;
+	u16			boot_sp;
+
+	struct interrupt_table	interrupt_table;
+
+	const char		*vmlinux;
+	struct disk_image       **disks;
+	int                     nr_disks;
+
+	char			*name;
+
+	int			vm_state;
+};
+
+static inline void *guest_flat_to_host(struct kvm *kvm, unsigned long offset); /* In kvm.h */
+
+static inline void *guest_real_to_host(struct kvm *kvm, u16 selector, u16 offset)
+{
+	unsigned long flat = segment_to_flat(selector, offset);
+
+	return guest_flat_to_host(kvm, flat);
+}
+
+#endif /* KVM__KVM_ARCH_H */
diff --git a/tools/kvm/x86/include/kvm/kvm-cpu-arch.h b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
new file mode 100644
index 0000000..198efe6
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/kvm-cpu-arch.h
@@ -0,0 +1,49 @@
+#ifndef KVM__KVM_CPU_ARCH_H
+#define KVM__KVM_CPU_ARCH_H
+
+/* Architecture-specific kvm_cpu definitions. */
+
+#include <linux/kvm.h>	/* for struct kvm_regs */
+#include "kvm/kvm.h"	/* for kvm__emulate_{mm}io() */
+#include <stdbool.h>
+#include <pthread.h>
+
+struct kvm;
+
+struct kvm_cpu {
+	pthread_t		thread;		/* VCPU thread */
+
+	unsigned long		cpu_id;
+
+	struct kvm		*kvm;		/* parent KVM */
+	int			vcpu_fd;	/* For VCPU ioctls() */
+	struct kvm_run		*kvm_run;
+
+	struct kvm_regs		regs;
+	struct kvm_sregs	sregs;
+	struct kvm_fpu		fpu;
+
+	struct kvm_msrs		*msrs;		/* dynamically allocated */
+
+	u8			is_running;
+	u8			paused;
+	u8			needs_nmi;
+
+	struct kvm_coalesced_mmio_ring	*ring;
+};
+
+/*
+ * As these are such simple wrappers, let's have them in the header so they'll
+ * be cheaper to call:
+ */
+static inline bool kvm_cpu__emulate_io(struct kvm *kvm, u16 port, void *data, int direction, int size, u32 count)
+{
+	return kvm__emulate_io(kvm, port, data, direction, size, count);
+}
+
+static inline bool kvm_cpu__emulate_mmio(struct kvm *kvm, u64 phys_addr, u8 *data, u32 len, u8 is_write)
+{
+	return kvm__emulate_mmio(kvm, phys_addr, data, len, is_write);
+}
+
+#endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/tools/kvm/x86/include/kvm/mptable.h b/tools/kvm/x86/include/kvm/mptable.h
new file mode 100644
index 0000000..9e3cfa6
--- /dev/null
+++ b/tools/kvm/x86/include/kvm/mptable.h
@@ -0,0 +1,9 @@
+#ifndef KVM_MPTABLE_H_
+#define KVM_MPTABLE_H_
+
+struct kvm;
+
+int mptable__init(struct kvm *kvm);
+int mptable__exit(struct kvm *kvm);
+
+#endif /* KVM_MPTABLE_H_ */
diff --git a/tools/kvm/x86/interrupt.c b/tools/kvm/x86/interrupt.c
new file mode 100644
index 0000000..7d47869
--- /dev/null
+++ b/tools/kvm/x86/interrupt.c
@@ -0,0 +1,28 @@
+#include "kvm/interrupt.h"
+
+#include "kvm/util.h"
+
+#include <string.h>
+
+void interrupt_table__copy(struct interrupt_table *itable, void *dst, unsigned int size)
+{
+	if (size < sizeof(itable->entries))
+		die("An attempt to overwrite host memory");
+
+	memcpy(dst, itable->entries, sizeof(itable->entries));
+}
+
+void interrupt_table__setup(struct interrupt_table *itable, struct real_intr_desc *entry)
+{
+	unsigned int i;
+
+	for (i = 0; i < REAL_INTR_VECTORS; i++)
+		itable->entries[i] = *entry;
+}
+
+void interrupt_table__set(struct interrupt_table *itable,
+				struct real_intr_desc *entry, unsigned int num)
+{
+	if (num < REAL_INTR_VECTORS)
+		itable->entries[num] = *entry;
+}
diff --git a/tools/kvm/x86/ioport.c b/tools/kvm/x86/ioport.c
new file mode 100644
index 0000000..8a91bf2
--- /dev/null
+++ b/tools/kvm/x86/ioport.c
@@ -0,0 +1,59 @@
+#include "kvm/ioport.h"
+
+#include <stdlib.h>
+
+static bool debug_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	exit(EXIT_SUCCESS);
+}
+
+static struct ioport_operations debug_ops = {
+	.io_out		= debug_io_out,
+};
+
+static bool dummy_io_in(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	return true;
+}
+
+static bool dummy_io_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data, int size)
+{
+	return true;
+}
+
+static struct ioport_operations dummy_read_write_ioport_ops = {
+	.io_in		= dummy_io_in,
+	.io_out		= dummy_io_out,
+};
+
+static struct ioport_operations dummy_write_only_ioport_ops = {
+	.io_out		= dummy_io_out,
+};
+
+void ioport__setup_arch(void)
+{
+	/* Legacy ioport setup */
+
+	/* 0x0020 - 0x003F - 8259A PIC 1 */
+	ioport__register(0x0020, &dummy_read_write_ioport_ops, 2, NULL);
+
+	/* PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) */
+	ioport__register(0x0040, &dummy_read_write_ioport_ops, 4, NULL);
+
+	/* 0x00A0 - 0x00AF - 8259A PIC 2 */
+	ioport__register(0x00A0, &dummy_read_write_ioport_ops, 2, NULL);
+
+	/* PORT 00E0-00EF are 'motherboard specific' so we use them for our
+	   internal debugging purposes.  */
+	ioport__register(IOPORT_DBG, &debug_ops, 1, NULL);
+
+	/* PORT 00ED - DUMMY PORT FOR DELAY??? */
+	ioport__register(0x00ED, &dummy_write_only_ioport_ops, 1, NULL);
+
+	/* 0x00F0 - 0x00FF - Math co-processor */
+	ioport__register(0x00F0, &dummy_write_only_ioport_ops, 2, NULL);
+
+	/* PORT 03D4-03D5 - COLOR VIDEO - CRT CONTROL REGISTERS */
+	ioport__register(0x03D4, &dummy_read_write_ioport_ops, 1, NULL);
+	ioport__register(0x03D5, &dummy_write_only_ioport_ops, 1, NULL);
+}
diff --git a/tools/kvm/x86/irq.c b/tools/kvm/x86/irq.c
new file mode 100644
index 0000000..dc07f28
--- /dev/null
+++ b/tools/kvm/x86/irq.c
@@ -0,0 +1,229 @@
+#include "kvm/irq.h"
+#include "kvm/kvm.h"
+#include "kvm/util.h"
+
+#include <linux/types.h>
+#include <linux/rbtree.h>
+#include <linux/list.h>
+#include <linux/kvm.h>
+#include <sys/ioctl.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#define IRQ_MAX_GSI			64
+#define IRQCHIP_MASTER			0
+#define IRQCHIP_SLAVE			1
+#define IRQCHIP_IOAPIC			2
+
+static u8		next_line	= 5;
+static u8		next_dev	= 1;
+static struct rb_root	pci_tree	= RB_ROOT;
+
+/* First 24 GSIs are routed between IRQCHIPs and IOAPICs */
+static u32 gsi = 24;
+
+struct kvm_irq_routing *irq_routing;
+
+static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin)
+{
+	if (gsi >= IRQ_MAX_GSI)
+		return -ENOSPC;
+
+	irq_routing->entries[irq_routing->nr++] =
+		(struct kvm_irq_routing_entry) {
+			.gsi = gsi,
+			.type = type,
+			.u.irqchip.irqchip = irqchip,
+			.u.irqchip.pin = pin,
+		};
+
+	return 0;
+}
+
+static struct pci_dev *search(struct rb_root *root, u32 id)
+{
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct pci_dev *data = rb_entry(node, struct pci_dev, node);
+		int result;
+
+		result = id - data->id;
+
+		if (result < 0)
+			node = node->rb_left;
+		else if (result > 0)
+			node = node->rb_right;
+		else
+			return data;
+	}
+	return NULL;
+}
+
+static int insert(struct rb_root *root, struct pci_dev *data)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+	/* Figure out where to put new node */
+	while (*new) {
+		struct pci_dev *this	= container_of(*new, struct pci_dev, node);
+		int result		= data->id - this->id;
+
+		parent = *new;
+		if (result < 0)
+			new = &((*new)->rb_left);
+		else if (result > 0)
+			new = &((*new)->rb_right);
+		else
+			return -EEXIST;
+	}
+
+	/* Add new node and rebalance tree. */
+	rb_link_node(&data->node, parent, new);
+	rb_insert_color(&data->node, root);
+
+	return 0;
+}
+
+int irq__register_device(u32 dev, u8 *num, u8 *pin, u8 *line)
+{
+	struct pci_dev *node;
+	int r;
+
+	node = search(&pci_tree, dev);
+
+	if (!node) {
+		/* We haven't found a node - First device of it's kind */
+		node = malloc(sizeof(*node));
+		if (node == NULL)
+			return -ENOMEM;
+
+		*node = (struct pci_dev) {
+			.id	= dev,
+			/*
+			 * PCI supports only INTA#,B#,C#,D# per device.
+			 * A#,B#,C#,D# are allowed for multifunctional
+			 * devices so stick with A# for our single
+			 * function devices.
+			 */
+			.pin	= 1,
+		};
+
+		INIT_LIST_HEAD(&node->lines);
+
+		r = insert(&pci_tree, node);
+		if (r) {
+			free(node);
+			return r;
+		}
+	}
+
+	if (node) {
+		/* This device already has a pin assigned, give out a new line and device id */
+		struct irq_line *new = malloc(sizeof(*new));
+		if (new == NULL)
+			return -ENOMEM;
+
+		new->line	= next_line++;
+		*line		= new->line;
+		*pin		= node->pin;
+		*num		= next_dev++;
+
+		list_add(&new->node, &node->lines);
+
+		return 0;
+	}
+
+	return -EFAULT;
+}
+
+int irq__init(struct kvm *kvm)
+{
+	int i, r;
+
+	irq_routing = calloc(sizeof(struct kvm_irq_routing) +
+			IRQ_MAX_GSI * sizeof(struct kvm_irq_routing_entry), 1);
+	if (irq_routing == NULL)
+		return -ENOMEM;
+
+	/* Hook first 8 GSIs to master IRQCHIP */
+	for (i = 0; i < 8; i++)
+		if (i != 2)
+			irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_MASTER, i);
+
+	/* Hook next 8 GSIs to slave IRQCHIP */
+	for (i = 8; i < 16; i++)
+		irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_SLAVE, i - 8);
+
+	/* Last but not least, IOAPIC */
+	for (i = 0; i < 24; i++) {
+		if (i == 0)
+			irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, 2);
+		else if (i != 2)
+			irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, i);
+	}
+
+	r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing);
+	if (r) {
+		free(irq_routing);
+		return errno;
+	}
+
+	return 0;
+}
+
+int irq__exit(struct kvm *kvm)
+{
+	struct rb_node *ent;
+
+	free(irq_routing);
+
+	ent = rb_first(&pci_tree);
+	for (;;) {
+		struct pci_dev *dev;
+		struct rb_node *next;
+		struct irq_line *line;
+		struct list_head *node, *tmp;
+
+		if (!ent)
+			break;
+
+		next = rb_next(ent);
+
+		dev = rb_entry(ent, struct pci_dev, node);
+		list_for_each_safe(node, tmp, &dev->lines) {
+			line = list_entry(node, struct irq_line, node);
+			free(line);
+		}
+		free(dev);
+		ent = next;
+	}
+
+	return 0;
+}
+
+int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg)
+{
+	int r;
+
+	irq_routing->entries[irq_routing->nr++] =
+		(struct kvm_irq_routing_entry) {
+			.gsi = gsi,
+			.type = KVM_IRQ_ROUTING_MSI,
+			.u.msi.address_hi = msg->address_hi,
+			.u.msi.address_lo = msg->address_lo,
+			.u.msi.data = msg->data,
+		};
+
+	r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing);
+	if (r)
+		return r;
+
+	return gsi++;
+}
+
+struct rb_node *irq__get_pci_tree(void)
+{
+	return rb_first(&pci_tree);
+}
diff --git a/tools/kvm/x86/kvm-cpu.c b/tools/kvm/x86/kvm-cpu.c
new file mode 100644
index 0000000..2b3d973
--- /dev/null
+++ b/tools/kvm/x86/kvm-cpu.c
@@ -0,0 +1,425 @@
+#include "kvm/kvm-cpu.h"
+
+#include "kvm/symbol.h"
+#include "kvm/util.h"
+#include "kvm/kvm.h"
+
+#include <asm/msr-index.h>
+#include <asm/apicdef.h>
+#include <linux/err.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+static int debug_fd;
+
+void kvm_cpu__set_debug_fd(int fd)
+{
+	debug_fd = fd;
+}
+
+int kvm_cpu__get_debug_fd(void)
+{
+	return debug_fd;
+}
+
+static inline bool is_in_protected_mode(struct kvm_cpu *vcpu)
+{
+	return vcpu->sregs.cr0 & 0x01;
+}
+
+static inline u64 ip_to_flat(struct kvm_cpu *vcpu, u64 ip)
+{
+	u64 cs;
+
+	/*
+	 * NOTE! We should take code segment base address into account here.
+	 * Luckily it's usually zero because Linux uses flat memory model.
+	 */
+	if (is_in_protected_mode(vcpu))
+		return ip;
+
+	cs = vcpu->sregs.cs.selector;
+
+	return ip + (cs << 4);
+}
+
+static inline u32 selector_to_base(u16 selector)
+{
+	/*
+	 * KVM on Intel requires 'base' to be 'selector * 16' in real mode.
+	 */
+	return (u32)selector << 4;
+}
+
+static struct kvm_cpu *kvm_cpu__new(struct kvm *kvm)
+{
+	struct kvm_cpu *vcpu;
+
+	vcpu = calloc(1, sizeof(*vcpu));
+	if (!vcpu)
+		return NULL;
+
+	vcpu->kvm = kvm;
+
+	return vcpu;
+}
+
+void kvm_cpu__delete(struct kvm_cpu *vcpu)
+{
+	if (vcpu->msrs)
+		free(vcpu->msrs);
+
+	free(vcpu);
+}
+
+static int kvm_cpu__set_lint(struct kvm_cpu *vcpu)
+{
+	struct local_apic lapic;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_LAPIC, &lapic))
+		return -1;
+
+	lapic.lvt_lint0.delivery_mode = APIC_MODE_EXTINT;
+	lapic.lvt_lint1.delivery_mode = APIC_MODE_NMI;
+
+	return ioctl(vcpu->vcpu_fd, KVM_SET_LAPIC, &lapic);
+}
+
+struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id)
+{
+	struct kvm_cpu *vcpu;
+	int mmap_size;
+	int coalesced_offset;
+
+	vcpu = kvm_cpu__new(kvm);
+	if (!vcpu)
+		return NULL;
+
+	vcpu->cpu_id = cpu_id;
+
+	vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
+	if (vcpu->vcpu_fd < 0)
+		die_perror("KVM_CREATE_VCPU ioctl");
+
+	mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
+	if (mmap_size < 0)
+		die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
+
+	vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0);
+	if (vcpu->kvm_run == MAP_FAILED)
+		die("unable to mmap vcpu fd");
+
+	coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_COALESCED_MMIO);
+	if (coalesced_offset)
+		vcpu->ring = (void *)vcpu->kvm_run + (coalesced_offset * PAGE_SIZE);
+
+	if (kvm_cpu__set_lint(vcpu))
+		die_perror("KVM_SET_LAPIC failed");
+
+	vcpu->is_running = true;
+
+	return vcpu;
+}
+
+static struct kvm_msrs *kvm_msrs__new(size_t nmsrs)
+{
+	struct kvm_msrs *vcpu = calloc(1, sizeof(*vcpu) + (sizeof(struct kvm_msr_entry) * nmsrs));
+
+	if (!vcpu)
+		die("out of memory");
+
+	return vcpu;
+}
+
+#define KVM_MSR_ENTRY(_index, _data)	\
+	(struct kvm_msr_entry) { .index = _index, .data = _data }
+
+static void kvm_cpu__setup_msrs(struct kvm_cpu *vcpu)
+{
+	unsigned long ndx = 0;
+
+	vcpu->msrs = kvm_msrs__new(100);
+
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_CS,	0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_ESP,	0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_SYSENTER_EIP,	0x0);
+#ifdef CONFIG_X86_64
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_STAR,			0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_CSTAR,			0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_KERNEL_GS_BASE,		0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_SYSCALL_MASK,		0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_LSTAR,			0x0);
+#endif
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_TSC,		0x0);
+	vcpu->msrs->entries[ndx++] = KVM_MSR_ENTRY(MSR_IA32_MISC_ENABLE,
+						MSR_IA32_MISC_ENABLE_FAST_STRING);
+
+	vcpu->msrs->nmsrs = ndx;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_MSRS, vcpu->msrs) < 0)
+		die_perror("KVM_SET_MSRS failed");
+}
+
+static void kvm_cpu__setup_fpu(struct kvm_cpu *vcpu)
+{
+	vcpu->fpu = (struct kvm_fpu) {
+		.fcw	= 0x37f,
+		.mxcsr	= 0x1f80,
+	};
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_FPU, &vcpu->fpu) < 0)
+		die_perror("KVM_SET_FPU failed");
+}
+
+static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu)
+{
+	vcpu->regs = (struct kvm_regs) {
+		/* We start the guest in 16-bit real mode  */
+		.rflags	= 0x0000000000000002ULL,
+
+		.rip	= vcpu->kvm->boot_ip,
+		.rsp	= vcpu->kvm->boot_sp,
+		.rbp	= vcpu->kvm->boot_sp,
+	};
+
+	if (vcpu->regs.rip > USHRT_MAX)
+		die("ip 0x%llx is too high for real mode", (u64)vcpu->regs.rip);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_REGS, &vcpu->regs) < 0)
+		die_perror("KVM_SET_REGS failed");
+}
+
+static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu)
+{
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
+		die_perror("KVM_GET_SREGS failed");
+
+	vcpu->sregs.cs.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.cs.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.ss.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.ss.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.ds.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.ds.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.es.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.es.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.fs.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.fs.base	= selector_to_base(vcpu->kvm->boot_selector);
+	vcpu->sregs.gs.selector	= vcpu->kvm->boot_selector;
+	vcpu->sregs.gs.base	= selector_to_base(vcpu->kvm->boot_selector);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &vcpu->sregs) < 0)
+		die_perror("KVM_SET_SREGS failed");
+}
+
+/**
+ * kvm_cpu__reset_vcpu - reset virtual CPU to a known state
+ */
+void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
+{
+	kvm_cpu__setup_cpuid(vcpu);
+	kvm_cpu__setup_sregs(vcpu);
+	kvm_cpu__setup_regs(vcpu);
+	kvm_cpu__setup_fpu(vcpu);
+	kvm_cpu__setup_msrs(vcpu);
+}
+
+bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
+{
+	return false;
+}
+
+static void print_dtable(const char *name, struct kvm_dtable *dtable)
+{
+	dprintf(debug_fd, " %s                 %016llx  %08hx\n",
+		name, (u64) dtable->base, (u16) dtable->limit);
+}
+
+static void print_segment(const char *name, struct kvm_segment *seg)
+{
+	dprintf(debug_fd, " %s       %04hx      %016llx  %08x  %02hhx    %x %x   %x  %x %x %x %x\n",
+		name, (u16) seg->selector, (u64) seg->base, (u32) seg->limit,
+		(u8) seg->type, seg->present, seg->dpl, seg->db, seg->s, seg->l, seg->g, seg->avl);
+}
+
+void kvm_cpu__show_registers(struct kvm_cpu *vcpu)
+{
+	unsigned long cr0, cr2, cr3;
+	unsigned long cr4, cr8;
+	unsigned long rax, rbx, rcx;
+	unsigned long rdx, rsi, rdi;
+	unsigned long rbp,  r8,  r9;
+	unsigned long r10, r11, r12;
+	unsigned long r13, r14, r15;
+	unsigned long rip, rsp;
+	struct kvm_sregs sregs;
+	unsigned long rflags;
+	struct kvm_regs regs;
+	int i;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &regs) < 0)
+		die("KVM_GET_REGS failed");
+
+	rflags = regs.rflags;
+
+	rip = regs.rip; rsp = regs.rsp;
+	rax = regs.rax; rbx = regs.rbx; rcx = regs.rcx;
+	rdx = regs.rdx; rsi = regs.rsi; rdi = regs.rdi;
+	rbp = regs.rbp; r8  = regs.r8;  r9  = regs.r9;
+	r10 = regs.r10; r11 = regs.r11; r12 = regs.r12;
+	r13 = regs.r13; r14 = regs.r14; r15 = regs.r15;
+
+	dprintf(debug_fd, "\n Registers:\n");
+	dprintf(debug_fd,   " ----------\n");
+	dprintf(debug_fd, " rip: %016lx   rsp: %016lx flags: %016lx\n", rip, rsp, rflags);
+	dprintf(debug_fd, " rax: %016lx   rbx: %016lx   rcx: %016lx\n", rax, rbx, rcx);
+	dprintf(debug_fd, " rdx: %016lx   rsi: %016lx   rdi: %016lx\n", rdx, rsi, rdi);
+	dprintf(debug_fd, " rbp: %016lx    r8: %016lx    r9: %016lx\n", rbp, r8,  r9);
+	dprintf(debug_fd, " r10: %016lx   r11: %016lx   r12: %016lx\n", r10, r11, r12);
+	dprintf(debug_fd, " r13: %016lx   r14: %016lx   r15: %016lx\n", r13, r14, r15);
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
+		die("KVM_GET_REGS failed");
+
+	cr0 = sregs.cr0; cr2 = sregs.cr2; cr3 = sregs.cr3;
+	cr4 = sregs.cr4; cr8 = sregs.cr8;
+
+	dprintf(debug_fd, " cr0: %016lx   cr2: %016lx   cr3: %016lx\n", cr0, cr2, cr3);
+	dprintf(debug_fd, " cr4: %016lx   cr8: %016lx\n", cr4, cr8);
+	dprintf(debug_fd, "\n Segment registers:\n");
+	dprintf(debug_fd,   " ------------------\n");
+	dprintf(debug_fd, " register  selector  base              limit     type  p dpl db s l g avl\n");
+	print_segment("cs ", &sregs.cs);
+	print_segment("ss ", &sregs.ss);
+	print_segment("ds ", &sregs.ds);
+	print_segment("es ", &sregs.es);
+	print_segment("fs ", &sregs.fs);
+	print_segment("gs ", &sregs.gs);
+	print_segment("tr ", &sregs.tr);
+	print_segment("ldt", &sregs.ldt);
+	print_dtable("gdt", &sregs.gdt);
+	print_dtable("idt", &sregs.idt);
+
+	dprintf(debug_fd, "\n APIC:\n");
+	dprintf(debug_fd,   " -----\n");
+	dprintf(debug_fd, " efer: %016llx  apic base: %016llx  nmi: %s\n",
+		(u64) sregs.efer, (u64) sregs.apic_base,
+		(vcpu->kvm->nmi_disabled ? "disabled" : "enabled"));
+
+	dprintf(debug_fd, "\n Interrupt bitmap:\n");
+	dprintf(debug_fd,   " -----------------\n");
+	for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++)
+		dprintf(debug_fd, " %016llx", (u64) sregs.interrupt_bitmap[i]);
+	dprintf(debug_fd, "\n");
+}
+
+#define MAX_SYM_LEN 128
+
+void kvm_cpu__show_code(struct kvm_cpu *vcpu)
+{
+	unsigned int code_bytes = 64;
+	unsigned int code_prologue = 43;
+	unsigned int code_len = code_bytes;
+	char sym[MAX_SYM_LEN] = SYMBOL_DEFAULT_UNKNOWN, *psym;
+	unsigned char c;
+	unsigned int i;
+	u8 *ip;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_REGS, &vcpu->regs) < 0)
+		die("KVM_GET_REGS failed");
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	ip = guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip) - code_prologue);
+
+	dprintf(debug_fd, "\n Code:\n");
+	dprintf(debug_fd,   " -----\n");
+
+	psym = symbol_lookup(vcpu->kvm, vcpu->regs.rip, sym, MAX_SYM_LEN);
+	if (IS_ERR(psym))
+		dprintf(debug_fd,
+			"Warning: symbol_lookup() failed to find symbol "
+			"with error: %ld\n", PTR_ERR(psym));
+
+	dprintf(debug_fd, " rip: [<%016lx>] %s\n\n", (unsigned long) vcpu->regs.rip, sym);
+
+	for (i = 0; i < code_len; i++, ip++) {
+		if (!host_ptr_in_ram(vcpu->kvm, ip))
+			break;
+
+		c = *ip;
+
+		if (ip == guest_flat_to_host(vcpu->kvm, ip_to_flat(vcpu, vcpu->regs.rip)))
+			dprintf(debug_fd, " <%02x>", c);
+		else
+			dprintf(debug_fd, " %02x", c);
+	}
+
+	dprintf(debug_fd, "\n");
+
+	dprintf(debug_fd, "\n Stack:\n");
+	dprintf(debug_fd,   " ------\n");
+	kvm__dump_mem(vcpu->kvm, vcpu->regs.rsp, 32);
+}
+
+void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
+{
+	u64 *pte1;
+	u64 *pte2;
+	u64 *pte3;
+	u64 *pte4;
+
+	if (!is_in_protected_mode(vcpu))
+		return;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &vcpu->sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	pte4 = guest_flat_to_host(vcpu->kvm, vcpu->sregs.cr3);
+	if (!host_ptr_in_ram(vcpu->kvm, pte4))
+		return;
+
+	pte3 = guest_flat_to_host(vcpu->kvm, (*pte4 & ~0xfff));
+	if (!host_ptr_in_ram(vcpu->kvm, pte3))
+		return;
+
+	pte2 = guest_flat_to_host(vcpu->kvm, (*pte3 & ~0xfff));
+	if (!host_ptr_in_ram(vcpu->kvm, pte2))
+		return;
+
+	pte1 = guest_flat_to_host(vcpu->kvm, (*pte2 & ~0xfff));
+	if (!host_ptr_in_ram(vcpu->kvm, pte1))
+		return;
+
+	dprintf(debug_fd, "Page Tables:\n");
+	if (*pte2 & (1 << 7))
+		dprintf(debug_fd, " pte4: %016llx   pte3: %016llx"
+			"   pte2: %016llx\n",
+			*pte4, *pte3, *pte2);
+	else
+		dprintf(debug_fd, " pte4: %016llx  pte3: %016llx   pte2: %016"
+			"llx   pte1: %016llx\n",
+			*pte4, *pte3, *pte2, *pte1);
+}
+
+void kvm_cpu__arch_nmi(struct kvm_cpu *cpu)
+{
+	struct kvm_lapic_state klapic;
+	struct local_apic *lapic = (void *)&klapic;
+
+	if (ioctl(cpu->vcpu_fd, KVM_GET_LAPIC, &klapic) != 0)
+		return;
+
+	if (lapic->lvt_lint1.mask)
+		return;
+
+	if (lapic->lvt_lint1.delivery_mode != APIC_MODE_NMI)
+		return;
+
+	ioctl(cpu->vcpu_fd, KVM_NMI);
+}
diff --git a/tools/kvm/x86/kvm.c b/tools/kvm/x86/kvm.c
new file mode 100644
index 0000000..10a1212
--- /dev/null
+++ b/tools/kvm/x86/kvm.c
@@ -0,0 +1,385 @@
+#include "kvm/kvm.h"
+#include "kvm/boot-protocol.h"
+#include "kvm/cpufeature.h"
+#include "kvm/interrupt.h"
+#include "kvm/mptable.h"
+#include "kvm/util.h"
+#include "kvm/8250-serial.h"
+#include "kvm/virtio-console.h"
+
+#include <asm/bootparam.h>
+#include <linux/kvm.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+struct kvm_ext kvm_req_ext[] = {
+	{ DEFINE_KVM_EXT(KVM_CAP_COALESCED_MMIO) },
+	{ DEFINE_KVM_EXT(KVM_CAP_SET_TSS_ADDR) },
+	{ DEFINE_KVM_EXT(KVM_CAP_PIT2) },
+	{ DEFINE_KVM_EXT(KVM_CAP_USER_MEMORY) },
+	{ DEFINE_KVM_EXT(KVM_CAP_IRQ_ROUTING) },
+	{ DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) },
+	{ DEFINE_KVM_EXT(KVM_CAP_HLT) },
+	{ DEFINE_KVM_EXT(KVM_CAP_IRQ_INJECT_STATUS) },
+	{ DEFINE_KVM_EXT(KVM_CAP_EXT_CPUID) },
+	{ 0, 0 }
+};
+
+bool kvm__arch_cpu_supports_vm(void)
+{
+	struct cpuid_regs regs;
+	u32 eax_base;
+	int feature;
+
+	regs	= (struct cpuid_regs) {
+		.eax		= 0x00,
+	};
+	host_cpuid(&regs);
+
+	switch (regs.ebx) {
+	case CPUID_VENDOR_INTEL_1:
+		eax_base	= 0x00;
+		feature		= KVM__X86_FEATURE_VMX;
+		break;
+
+	case CPUID_VENDOR_AMD_1:
+		eax_base	= 0x80000000;
+		feature		= KVM__X86_FEATURE_SVM;
+		break;
+
+	default:
+		return false;
+	}
+
+	regs	= (struct cpuid_regs) {
+		.eax		= eax_base,
+	};
+	host_cpuid(&regs);
+
+	if (regs.eax < eax_base + 0x01)
+		return false;
+
+	regs	= (struct cpuid_regs) {
+		.eax		= eax_base + 0x01
+	};
+	host_cpuid(&regs);
+
+	return regs.ecx & (1 << feature);
+}
+
+/*
+ * Allocating RAM size bigger than 4GB requires us to leave a gap
+ * in the RAM which is used for PCI MMIO, hotplug, and unconfigured
+ * devices (see documentation of e820_setup_gap() for details).
+ *
+ * If we're required to initialize RAM bigger than 4GB, we will create
+ * a gap between 0xe0000000 and 0x100000000 in the guest virtual mem space.
+ */
+
+void kvm__init_ram(struct kvm *kvm)
+{
+	u64	phys_start, phys_size;
+	void	*host_mem;
+
+	if (kvm->ram_size < KVM_32BIT_GAP_START) {
+		/* Use a single block of RAM for 32bit RAM */
+
+		phys_start = 0;
+		phys_size  = kvm->ram_size;
+		host_mem   = kvm->ram_start;
+
+		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+	} else {
+		/* First RAM range from zero to the PCI gap: */
+
+		phys_start = 0;
+		phys_size  = KVM_32BIT_GAP_START;
+		host_mem   = kvm->ram_start;
+
+		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+
+		/* Second RAM range from 4GB to the end of RAM: */
+
+		phys_start = KVM_32BIT_MAX_MEM_SIZE;
+		phys_size  = kvm->ram_size - phys_start;
+		host_mem   = kvm->ram_start + phys_start;
+
+		kvm__register_mem(kvm, phys_start, phys_size, host_mem);
+	}
+}
+
+/* Arch-specific commandline setup */
+void kvm__arch_set_cmdline(char *cmdline, bool video)
+{
+	strcpy(cmdline, "noapic noacpi pci=conf1 reboot=k panic=1 i8042.direct=1 "
+				"i8042.dumbkbd=1 i8042.nopnp=1");
+	if (video)
+		strcat(cmdline, " video=vesafb console=tty0");
+	else
+		strcat(cmdline, " console=ttyS0 earlyprintk=serial i8042.noaux=1");
+}
+
+/* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */
+static void *mmap_anon_or_hugetlbfs(const char *hugetlbfs_path, u64 size)
+{
+	if (hugetlbfs_path)
+		/*
+		 * We don't /need/ to map guest RAM from hugetlbfs, but we do so
+		 * if the user specifies a hugetlbfs path.
+		 */
+		return mmap_hugetlbfs(hugetlbfs_path, size);
+	else
+		return mmap(NULL, size, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
+}
+
+/* Architecture-specific KVM init */
+void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
+{
+	struct kvm_pit_config pit_config = { .flags = 0, };
+	int ret;
+
+	ret = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, 0xfffbd000);
+	if (ret < 0)
+		die_perror("KVM_SET_TSS_ADDR ioctl");
+
+	ret = ioctl(kvm->vm_fd, KVM_CREATE_PIT2, &pit_config);
+	if (ret < 0)
+		die_perror("KVM_CREATE_PIT2 ioctl");
+
+	if (ram_size < KVM_32BIT_GAP_START) {
+		kvm->ram_size = ram_size;
+		kvm->ram_start = mmap_anon_or_hugetlbfs(hugetlbfs_path, ram_size);
+	} else {
+		kvm->ram_start = mmap_anon_or_hugetlbfs(hugetlbfs_path, ram_size + KVM_32BIT_GAP_SIZE);
+		kvm->ram_size = ram_size + KVM_32BIT_GAP_SIZE;
+		if (kvm->ram_start != MAP_FAILED)
+			/*
+			 * We mprotect the gap (see kvm__init_ram() for details) PROT_NONE so that
+			 * if we accidently write to it, we will know.
+			 */
+			mprotect(kvm->ram_start + KVM_32BIT_GAP_START, KVM_32BIT_GAP_SIZE, PROT_NONE);
+	}
+	if (kvm->ram_start == MAP_FAILED)
+		die("out of memory");
+
+	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
+
+	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
+	if (ret < 0)
+		die_perror("KVM_CREATE_IRQCHIP ioctl");
+}
+
+void kvm__arch_delete_ram(struct kvm *kvm)
+{
+	munmap(kvm->ram_start, kvm->ram_size);
+}
+
+void kvm__irq_line(struct kvm *kvm, int irq, int level)
+{
+	struct kvm_irq_level irq_level;
+
+	irq_level	= (struct kvm_irq_level) {
+		{
+			.irq		= irq,
+		},
+		.level		= level,
+	};
+
+	if (ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level) < 0)
+		die_perror("KVM_IRQ_LINE failed");
+}
+
+void kvm__irq_trigger(struct kvm *kvm, int irq)
+{
+	kvm__irq_line(kvm, irq, 1);
+	kvm__irq_line(kvm, irq, 0);
+}
+
+#define BOOT_LOADER_SELECTOR	0x1000
+#define BOOT_LOADER_IP		0x0000
+#define BOOT_LOADER_SP		0x8000
+#define BOOT_CMDLINE_OFFSET	0x20000
+
+#define BOOT_PROTOCOL_REQUIRED	0x206
+#define LOAD_HIGH		0x01
+
+int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline)
+{
+	void *p;
+	int nr;
+
+	/*
+	 * Some architectures may support loading an initrd alongside the flat kernel,
+	 * but we do not.
+	 */
+	if (fd_initrd != -1)
+		pr_warning("Loading initrd with flat binary not supported.");
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
+
+	while ((nr = read(fd_kernel, p, 65536)) > 0)
+		p += nr;
+
+	kvm->boot_selector	= BOOT_LOADER_SELECTOR;
+	kvm->boot_ip		= BOOT_LOADER_IP;
+	kvm->boot_sp		= BOOT_LOADER_SP;
+
+	return true;
+}
+
+static const char *BZIMAGE_MAGIC = "HdrS";
+
+bool load_bzimage(struct kvm *kvm, int fd_kernel,
+		  int fd_initrd, const char *kernel_cmdline, u16 vidmode)
+{
+	struct boot_params *kern_boot;
+	unsigned long setup_sects;
+	struct boot_params boot;
+	size_t cmdline_size;
+	ssize_t setup_size;
+	void *p;
+	int nr;
+
+	/*
+	 * See Documentation/x86/boot.txt for details no bzImage on-disk and
+	 * memory layout.
+	 */
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	if (read(fd_kernel, &boot, sizeof(boot)) != sizeof(boot))
+		return false;
+
+	if (memcmp(&boot.hdr.header, BZIMAGE_MAGIC, strlen(BZIMAGE_MAGIC)))
+		return false;
+
+	if (boot.hdr.version < BOOT_PROTOCOL_REQUIRED)
+		die("Too old kernel");
+
+	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
+		die_perror("lseek");
+
+	if (!boot.hdr.setup_sects)
+		boot.hdr.setup_sects = BZ_DEFAULT_SETUP_SECTS;
+	setup_sects = boot.hdr.setup_sects + 1;
+
+	setup_size = setup_sects << 9;
+	p = guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, BOOT_LOADER_IP);
+
+	/* copy setup.bin to mem*/
+	if (read(fd_kernel, p, setup_size) != setup_size)
+		die_perror("read");
+
+	/* copy vmlinux.bin to BZ_KERNEL_START*/
+	p = guest_flat_to_host(kvm, BZ_KERNEL_START);
+
+	while ((nr = read(fd_kernel, p, 65536)) > 0)
+		p += nr;
+
+	p = guest_flat_to_host(kvm, BOOT_CMDLINE_OFFSET);
+	if (kernel_cmdline) {
+		cmdline_size = strlen(kernel_cmdline) + 1;
+		if (cmdline_size > boot.hdr.cmdline_size)
+			cmdline_size = boot.hdr.cmdline_size;
+
+		memset(p, 0, boot.hdr.cmdline_size);
+		memcpy(p, kernel_cmdline, cmdline_size - 1);
+	}
+
+	kern_boot	= guest_real_to_host(kvm, BOOT_LOADER_SELECTOR, 0x00);
+
+	kern_boot->hdr.cmd_line_ptr	= BOOT_CMDLINE_OFFSET;
+	kern_boot->hdr.type_of_loader	= 0xff;
+	kern_boot->hdr.heap_end_ptr	= 0xfe00;
+	kern_boot->hdr.loadflags	|= CAN_USE_HEAP;
+	kern_boot->hdr.vid_mode		= vidmode;
+
+	/*
+	 * Read initrd image into guest memory
+	 */
+	if (fd_initrd >= 0) {
+		struct stat initrd_stat;
+		unsigned long addr;
+
+		if (fstat(fd_initrd, &initrd_stat))
+			die_perror("fstat");
+
+		addr = boot.hdr.initrd_addr_max & ~0xfffff;
+		for (;;) {
+			if (addr < BZ_KERNEL_START)
+				die("Not enough memory for initrd");
+			else if (addr < (kvm->ram_size - initrd_stat.st_size))
+				break;
+			addr -= 0x100000;
+		}
+
+		p = guest_flat_to_host(kvm, addr);
+		nr = read(fd_initrd, p, initrd_stat.st_size);
+		if (nr != initrd_stat.st_size)
+			die("Failed to read initrd");
+
+		kern_boot->hdr.ramdisk_image	= addr;
+		kern_boot->hdr.ramdisk_size	= initrd_stat.st_size;
+	}
+
+	kvm->boot_selector = BOOT_LOADER_SELECTOR;
+	/*
+	 * The real-mode setup code starts at offset 0x200 of a bzImage. See
+	 * Documentation/x86/boot.txt for details.
+	 */
+	kvm->boot_ip = BOOT_LOADER_IP + 0x200;
+	kvm->boot_sp = BOOT_LOADER_SP;
+
+	return true;
+}
+
+/**
+ * kvm__arch_setup_firmware - inject BIOS into guest system memory
+ * @kvm - guest system descriptor
+ *
+ * This function is a main routine where we poke guest memory
+ * and install BIOS there.
+ */
+int kvm__arch_setup_firmware(struct kvm *kvm)
+{
+	int r;
+
+	/* standart minimal configuration */
+	setup_bios(kvm);
+
+	/* FIXME: SMP, ACPI and friends here */
+
+	/* MP table */
+	r = mptable__init(kvm);
+
+	return r;
+}
+
+int kvm__arch_free_firmware(struct kvm *kvm)
+{
+	int r;
+
+	/* MP table */
+	r = mptable__exit(kvm);
+
+	return r;
+}
+
+void kvm__arch_periodic_poll(struct kvm *kvm)
+{
+	serial8250__update_consoles(kvm);
+	virtio_console__inject_interrupt(kvm);
+}
diff --git a/tools/kvm/x86/mptable.c b/tools/kvm/x86/mptable.c
new file mode 100644
index 0000000..12bdcf8
--- /dev/null
+++ b/tools/kvm/x86/mptable.c
@@ -0,0 +1,287 @@
+#include "kvm/kvm.h"
+#include "kvm/bios.h"
+#include "kvm/apic.h"
+#include "kvm/mptable.h"
+#include "kvm/util.h"
+#include "kvm/irq.h"
+
+#include <linux/kernel.h>
+#include <string.h>
+
+#include <asm/mpspec_def.h>
+#include <linux/types.h>
+
+/*
+ * FIXME: please make sure the addresses borrowed
+ * for apic/ioapic never overlaped! We need a global
+ * tracker of system resources (including io, mmio,
+ * and friends).
+ */
+
+static unsigned int mpf_checksum(unsigned char *mp, int len)
+{
+	unsigned int sum = 0;
+
+	while (len--)
+		sum += *mp++;
+
+	return sum & 0xFF;
+}
+
+static unsigned int gen_cpu_flag(unsigned int cpu, unsigned int ncpu)
+{
+	/* sets enabled/disabled | BSP/AP processor */
+	return ( (cpu < ncpu) ? CPU_ENABLED       : 0) |
+		((cpu == 0)   ? CPU_BOOTPROCESSOR : 0x00);
+}
+
+#define MPTABLE_SIG_FLOATING	"_MP_"
+#define MPTABLE_OEM		"KVMCPU00"
+#define MPTABLE_PRODUCTID	"0.1         "
+#define MPTABLE_PCIBUSTYPE	"PCI   "
+#define MPTABLE_ISABUSTYPE	"ISA   "
+
+#define MPTABLE_STRNCPY(d, s)	memcpy(d, s, sizeof(d))
+
+/* It should be more than enough */
+#define MPTABLE_MAX_SIZE	(32 << 20)
+
+/*
+ * Too many cpus will require x2apic mode
+ * and rather ACPI support so we limit it
+ * here for a while.
+ */
+#define MPTABLE_MAX_CPUS	255
+
+static void mptable_add_irq_src(struct mpc_intsrc *mpc_intsrc,
+				u16 srcbusid,	u16 srcbusirq,
+				u16 dstapic,	u16 dstirq)
+{
+	*mpc_intsrc = (struct mpc_intsrc) {
+		.type		= MP_INTSRC,
+		.irqtype	= mp_INT,
+		.irqflag	= MP_IRQDIR_DEFAULT,
+		.srcbus		= srcbusid,
+		.srcbusirq	= srcbusirq,
+		.dstapic	= dstapic,
+		.dstirq		= dstirq
+	};
+}
+
+/**
+ * mptable_setup - create mptable and fill guest memory with it
+ */
+int mptable__init(struct kvm *kvm)
+{
+	unsigned long real_mpc_table, real_mpf_intel, size;
+	struct mpf_intel *mpf_intel;
+	struct mpc_table *mpc_table;
+	struct mpc_cpu *mpc_cpu;
+	struct mpc_bus *mpc_bus;
+	struct mpc_ioapic *mpc_ioapic;
+	struct mpc_intsrc *mpc_intsrc;
+	struct rb_node *pci_tree;
+
+	const int pcibusid = 0;
+	const int isabusid = 1;
+
+	unsigned int i, nentries = 0, ncpus = kvm->nrcpus;
+	unsigned int ioapicid;
+	void *last_addr;
+
+	/* That is where MP table will be in guest memory */
+	real_mpc_table = ALIGN(MB_BIOS_BEGIN + bios_rom_size, 16);
+
+	if (ncpus > MPTABLE_MAX_CPUS) {
+		pr_warning("Too many cpus: %d limited to %d",
+			ncpus, MPTABLE_MAX_CPUS);
+		ncpus = MPTABLE_MAX_CPUS;
+	}
+
+	mpc_table = calloc(1, MPTABLE_MAX_SIZE);
+	if (!mpc_table)
+		return -ENOMEM;
+
+	MPTABLE_STRNCPY(mpc_table->signature,	MPC_SIGNATURE);
+	MPTABLE_STRNCPY(mpc_table->oem,		MPTABLE_OEM);
+	MPTABLE_STRNCPY(mpc_table->productid,	MPTABLE_PRODUCTID);
+
+	mpc_table->spec		= 4;
+	mpc_table->lapic	= APIC_ADDR(0);
+	mpc_table->oemcount	= ncpus; /* will be updated again at end */
+
+	/*
+	 * CPUs enumeration. Technically speaking we should
+	 * ask either host or HV for apic version supported
+	 * but for a while we simply put some random value
+	 * here.
+	 */
+	mpc_cpu = (void *)&mpc_table[1];
+	for (i = 0; i < ncpus; i++) {
+		mpc_cpu->type		= MP_PROCESSOR;
+		mpc_cpu->apicid		= i;
+		mpc_cpu->apicver	= KVM_APIC_VERSION;
+		mpc_cpu->cpuflag	= gen_cpu_flag(i, ncpus);
+		mpc_cpu->cpufeature	= 0x600; /* some default value */
+		mpc_cpu->featureflag	= 0x201; /* some default value */
+		mpc_cpu++;
+	}
+
+	last_addr = (void *)mpc_cpu;
+	nentries += ncpus;
+
+	/*
+	 * PCI buses.
+	 * FIXME: Some callback here to obtain real number
+	 * of PCI buses present in system.
+	 */
+	mpc_bus		= last_addr;
+	mpc_bus->type	= MP_BUS;
+	mpc_bus->busid	= pcibusid;
+	MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_PCIBUSTYPE);
+
+	last_addr = (void *)&mpc_bus[1];
+	nentries++;
+
+	/*
+	 * ISA bus.
+	 * FIXME: Same issue as for PCI bus.
+	 */
+	mpc_bus		= last_addr;
+	mpc_bus->type	= MP_BUS;
+	mpc_bus->busid	= isabusid;
+	MPTABLE_STRNCPY(mpc_bus->bustype, MPTABLE_ISABUSTYPE);
+
+	last_addr = (void *)&mpc_bus[1];
+	nentries++;
+
+	/*
+	 * IO-APIC chip.
+	 */
+	ioapicid		= ncpus + 1;
+	mpc_ioapic		= last_addr;
+	mpc_ioapic->type	= MP_IOAPIC;
+	mpc_ioapic->apicid	= ioapicid;
+	mpc_ioapic->apicver	= KVM_APIC_VERSION;
+	mpc_ioapic->flags	= MPC_APIC_USABLE;
+	mpc_ioapic->apicaddr	= IOAPIC_ADDR(0);
+
+	last_addr = (void *)&mpc_ioapic[1];
+	nentries++;
+
+	/*
+	 * IRQ sources.
+	 *
+	 * FIXME: Same issue as with buses. We definitely
+	 * need kind of collector routine which enumerate
+	 * resources used first and pass them here.
+	 * At moment we know we have only virtio block device
+	 * and virtio console but this is g00berfish.
+	 *
+	 * Also note we use PCI irqs here, no for ISA bus yet.
+	 */
+
+	for (pci_tree = irq__get_pci_tree(); pci_tree; pci_tree = rb_next(pci_tree)) {
+		struct pci_dev *dev = rb_entry(pci_tree, struct pci_dev, node);
+		struct irq_line *irq_line;
+
+		list_for_each_entry(irq_line, &dev->lines, node) {
+			unsigned char srcbusirq;
+
+			srcbusirq = (dev->id << 2) | (dev->pin - 1);
+
+			mpc_intsrc = last_addr;
+
+			mptable_add_irq_src(mpc_intsrc, pcibusid, srcbusirq, ioapicid, irq_line->line);
+			last_addr = (void *)&mpc_intsrc[1];
+			nentries++;
+		}
+	}
+
+	/*
+	 * Local IRQs assignment (LINT0, LINT1)
+	 */
+	mpc_intsrc		= last_addr;
+	mpc_intsrc->type	= MP_LINTSRC;
+	mpc_intsrc->irqtype	= mp_ExtINT;
+	mpc_intsrc->irqtype	= mp_INT;
+	mpc_intsrc->irqflag	= MP_IRQDIR_DEFAULT;
+	mpc_intsrc->srcbus	= isabusid;
+	mpc_intsrc->srcbusirq	= 0;
+	mpc_intsrc->dstapic	= 0; /* FIXME: BSP apic */
+	mpc_intsrc->dstirq	= 0; /* LINT0 */
+
+	last_addr = (void *)&mpc_intsrc[1];
+	nentries++;
+
+	mpc_intsrc		= last_addr;
+	mpc_intsrc->type	= MP_LINTSRC;
+	mpc_intsrc->irqtype	= mp_NMI;
+	mpc_intsrc->irqflag	= MP_IRQDIR_DEFAULT;
+	mpc_intsrc->srcbus	= isabusid;
+	mpc_intsrc->srcbusirq	= 0;
+	mpc_intsrc->dstapic	= 0; /* FIXME: BSP apic */
+	mpc_intsrc->dstirq	= 1; /* LINT1 */
+
+	last_addr = (void *)&mpc_intsrc[1];
+	nentries++;
+
+	/*
+	 * Floating MP table finally.
+	 */
+	real_mpf_intel	= ALIGN((unsigned long)last_addr - (unsigned long)mpc_table, 16);
+	mpf_intel	= (void *)((unsigned long)mpc_table + real_mpf_intel);
+
+	MPTABLE_STRNCPY(mpf_intel->signature, MPTABLE_SIG_FLOATING);
+	mpf_intel->length	= 1;
+	mpf_intel->specification= 4;
+	mpf_intel->physptr	= (unsigned int)real_mpc_table;
+	mpf_intel->checksum	= -mpf_checksum((unsigned char *)mpf_intel, sizeof(*mpf_intel));
+
+	/*
+	 * No last_addr inclrement here please, we need last
+	 * active position here to compute table size.
+	 */
+
+	/*
+	 * Don't forget to update header in fixed table.
+	*/
+	mpc_table->oemcount	= nentries;
+	mpc_table->length	= last_addr - (void *)mpc_table;
+	mpc_table->checksum	= -mpf_checksum((unsigned char *)mpc_table, mpc_table->length);
+
+
+	/*
+	 * We will copy the whole table, no need to separate
+	 * floating structure and table itkvm.
+	 */
+	size = (unsigned long)mpf_intel + sizeof(*mpf_intel) - (unsigned long)mpc_table;
+
+	/*
+	 * The finial check -- never get out of system bios
+	 * area. Lets also check for allocated memory overrun,
+	 * in real it's late but still usefull.
+	 */
+
+	if (size > (unsigned long)(MB_BIOS_END - bios_rom_size) ||
+	    size > MPTABLE_MAX_SIZE) {
+		free(mpc_table);
+		pr_err("MP table is too big");
+
+		return -E2BIG;
+	}
+
+	/*
+	 * OK, it is time to move it to guest memory.
+	 */
+	memcpy(guest_flat_to_host(kvm, real_mpc_table), mpc_table, size);
+
+	free(mpc_table);
+
+	return 0;
+}
+
+int mptable__exit(struct kvm *kvm)
+{
+	return 0;
+}
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index 4626a39..ca600e0 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -1,3 +1,10 @@
+OUTPUT := ./
+ifeq ("$(origin O)", "command line")
+  ifneq ($(O),)
+	OUTPUT := $(O)/
+  endif
+endif
+
 MAN1_TXT= \
 	$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
 		$(wildcard perf-*.txt)) \
@@ -6,10 +13,11 @@ MAN5_TXT=
 MAN7_TXT=
 
 MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
-MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
-MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
+_MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
+_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
 
-DOC_HTML=$(MAN_HTML)
+MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML))
+MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML))
 
 ARTICLES =
 # with their own formatting rules.
@@ -18,11 +26,17 @@ API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technica
 SP_ARTICLES += $(API_DOCS)
 SP_ARTICLES += technical/api-index
 
-DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
+_DOC_HTML = $(_MAN_HTML)
+_DOC_HTML+=$(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
+DOC_HTML=$(addprefix $(OUTPUT),$(_DOC_HTML))
 
-DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
-DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT))
-DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
+_DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT))
+_DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT))
+_DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT))
+
+DOC_MAN1=$(addprefix $(OUTPUT),$(_DOC_MAN1))
+DOC_MAN5=$(addprefix $(OUTPUT),$(_DOC_MAN5))
+DOC_MAN7=$(addprefix $(OUTPUT),$(_DOC_MAN7))
 
 # Make the path relative to DESTDIR, not prefix
 ifndef DESTDIR
@@ -150,9 +164,9 @@ man1: $(DOC_MAN1)
 man5: $(DOC_MAN5)
 man7: $(DOC_MAN7)
 
-info: perf.info perfman.info
+info: $(OUTPUT)perf.info $(OUTPUT)perfman.info
 
-pdf: user-manual.pdf
+pdf: $(OUTPUT)user-manual.pdf
 
 install: install-man
 
@@ -166,7 +180,7 @@ install-man: man
 
 install-info: info
 	$(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
-	$(INSTALL) -m 644 perf.info perfman.info $(DESTDIR)$(infodir)
+	$(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir)
 	if test -r $(DESTDIR)$(infodir)/dir; then \
 	  $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perf.info ;\
 	  $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perfman.info ;\
@@ -176,7 +190,7 @@ install-info: info
 
 install-pdf: pdf
 	$(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir)
-	$(INSTALL) -m 644 user-manual.pdf $(DESTDIR)$(pdfdir)
+	$(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir)
 
 #install-html: html
 #	'$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir)
@@ -189,14 +203,14 @@ install-pdf: pdf
 #
 # Determine "include::" file references in asciidoc files.
 #
-doc.dep : $(wildcard *.txt) build-docdep.perl
+$(OUTPUT)doc.dep : $(wildcard *.txt) build-docdep.perl
 	$(QUIET_GEN)$(RM) $@+ $@ && \
 	$(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \
 	mv $@+ $@
 
--include doc.dep
+-include $(OUPTUT)doc.dep
 
-cmds_txt = cmds-ancillaryinterrogators.txt \
+_cmds_txt = cmds-ancillaryinterrogators.txt \
 	cmds-ancillarymanipulators.txt \
 	cmds-mainporcelain.txt \
 	cmds-plumbinginterrogators.txt \
@@ -205,32 +219,36 @@ cmds_txt = cmds-ancillaryinterrogators.txt \
 	cmds-synchelpers.txt \
 	cmds-purehelpers.txt \
 	cmds-foreignscminterface.txt
+cmds_txt=$(addprefix $(OUTPUT),$(_cmds_txt))
 
-$(cmds_txt): cmd-list.made
+$(cmds_txt): $(OUTPUT)cmd-list.made
 
-cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
+$(OUTPUT)cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
 	$(QUIET_GEN)$(RM) $@ && \
 	$(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \
 	date >$@
 
 clean:
-	$(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7
-	$(RM) *.texi *.texi+ *.texi++ perf.info perfman.info
-	$(RM) howto-index.txt howto/*.html doc.dep
-	$(RM) technical/api-*.html technical/api-index.txt
-	$(RM) $(cmds_txt) *.made
-
-$(MAN_HTML): %.html : %.txt
+	$(RM) $(MAN_XML) $(addsuffix +,$(MAN_XML))
+	$(RM) $(MAN_HTML) $(addsuffix +,$(MAN_HTML))
+	$(RM) $(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7)
+	$(RM) $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++
+	$(RM) $(OUTPUT)perf.info $(OUTPUT)perfman.info
+	$(RM) $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep
+	$(RM) $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt
+	$(RM) $(cmds_txt) $(OUTPUT)*.made
+
+$(MAN_HTML): $(OUTPUT)%.html : %.txt
 	$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
 	$(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \
 		$(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \
 	mv $@+ $@
 
-%.1 %.5 %.7 : %.xml
+$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
 	$(QUIET_XMLTO)$(RM) $@ && \
-	xmlto -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+	xmlto -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
 
-%.xml : %.txt
+$(OUTPUT)%.xml : %.txt
 	$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
 	$(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \
 		$(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \
@@ -239,25 +257,25 @@ $(MAN_HTML): %.html : %.txt
 XSLT = docbook.xsl
 XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css
 
-user-manual.html: user-manual.xml
+$(OUTPUT)user-manual.html: $(OUTPUT)user-manual.xml
 	$(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $<
 
-perf.info: user-manual.texi
-	$(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi
+$(OUTPUT)perf.info: $(OUTPUT)user-manual.texi
+	$(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ $(OUTPUT)user-manual.texi
 
-user-manual.texi: user-manual.xml
+$(OUTPUT)user-manual.texi: $(OUTPUT)user-manual.xml
 	$(QUIET_DB2TEXI)$(RM) $@+ $@ && \
-	$(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \
+	$(DOCBOOK2X_TEXI) $(OUTPUT)user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \
 	$(PERL_PATH) fix-texi.perl <$@++ >$@+ && \
 	rm $@++ && \
 	mv $@+ $@
 
-user-manual.pdf: user-manual.xml
+$(OUTPUT)user-manual.pdf: $(OUTPUT)user-manual.xml
 	$(QUIET_DBLATEX)$(RM) $@+ $@ && \
 	$(DBLATEX) -o $@+ -p /etc/asciidoc/dblatex/asciidoc-dblatex.xsl -s /etc/asciidoc/dblatex/asciidoc-dblatex.sty $< && \
 	mv $@+ $@
 
-perfman.texi: $(MAN_XML) cat-texi.perl
+$(OUTPUT)perfman.texi: $(MAN_XML) cat-texi.perl
 	$(QUIET_DB2TEXI)$(RM) $@+ $@ && \
 	($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --encoding=UTF-8 \
 		--to-stdout $(xml) &&) true) > $@++ && \
@@ -265,7 +283,7 @@ perfman.texi: $(MAN_XML) cat-texi.perl
 	rm $@++ && \
 	mv $@+ $@
 
-perfman.info: perfman.texi
+$(OUTPUT)perfman.info: $(OUTPUT)perfman.texi
 	$(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $*.texi
 
 $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml
diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt
index d6b2a4f..c7f5f55 100644
--- a/tools/perf/Documentation/perf-lock.txt
+++ b/tools/perf/Documentation/perf-lock.txt
@@ -8,7 +8,7 @@ perf-lock - Analyze lock events
 SYNOPSIS
 --------
 [verse]
-'perf lock' {record|report|trace}
+'perf lock' {record|report|script|info}
 
 DESCRIPTION
 -----------
@@ -20,10 +20,13 @@ and statistics with this 'perf lock' command.
   produces the file "perf.data" which contains tracing
   results of lock events.
 
-  'perf lock trace' shows raw lock events.
-
   'perf lock report' reports statistical data.
 
+  'perf lock script' shows raw lock events.
+
+  'perf lock info' shows metadata like threads or addresses
+  of lock instances.
+
 COMMON OPTIONS
 --------------
 
@@ -47,6 +50,17 @@ REPORT OPTIONS
         Sorting key. Possible values: acquired (default), contended,
         wait_total, wait_max, wait_min.
 
+INFO OPTIONS
+------------
+
+-t::
+--threads::
+	dump thread list in perf.data
+
+-m::
+--map::
+	dump map of lock instances (address:name table)
+
 SEE ALSO
 --------
 linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 2780d9c..be88378 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -78,6 +78,8 @@ OPTIONS
 -F::
 --funcs::
 	Show available functions in given module or kernel.
+	With -x/--exec, can also list functions in a user space executable
+	/ shared library.
 
 --filter=FILTER::
 	(Only for --vars and --funcs) Set filter. FILTER is a combination of glob
@@ -98,6 +100,11 @@ OPTIONS
 --max-probes::
 	Set the maximum number of probe points for an event. Default is 128.
 
+-x::
+--exec=PATH::
+	Specify path to the executable or shared library file for user
+	space tracing. Can also be used with --funcs option.
+
 PROBE SYNTAX
 ------------
 Probe points are defined by following syntax.
@@ -182,6 +189,13 @@ Delete all probes on schedule().
 
  ./perf probe --del='schedule*'
 
+Add probes at zfree() function on /bin/zsh
+
+ ./perf probe -x /bin/zsh zfree
+
+Add probes at malloc() function on libc
+
+ ./perf probe -x /lib/libc.so.6 malloc
 
 SEE ALSO
 --------
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 2937f7e..ff9a66e 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -58,6 +58,10 @@ OPTIONS
 --tid=::
         Record events on existing thread ID.
 
+-u::
+--uid=::
+        Record events in threads owned by uid. Name or number.
+
 -r::
 --realtime=::
 	Collect data with this RT SCHED_FIFO priority.
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 2f6cef4..e9cbfcd 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,7 +115,7 @@ OPTIONS
 -f::
 --fields::
         Comma separated list of fields to print. Options are:
-        comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr.
+        comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff.
         Field list can be prepended with the type, trace, sw or hw,
         to indicate to which event type the field list applies.
         e.g., -f sw:comm,tid,time,ip,sym  and -f trace:time,cpu,trace
@@ -200,6 +200,9 @@ OPTIONS
 	It currently includes: cpu and numa topology of the host system.
 	It can only be used with the perf script report mode.
 
+--show-kernel-path::
+	Try to resolve the path of [kernel.kallsyms]
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index b1a5bbb..ab1454e 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -78,6 +78,10 @@ Default is to monitor all CPUS.
 --tid=<tid>::
         Profile events on existing thread ID.
 
+-u::
+--uid=::
+        Record events in threads owned by uid. Name or number.
+
 -r <priority>::
 --realtime=<priority>::
 	Collect data with this RT SCHED_FIFO priority.
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 7c12650..64df5de 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -61,7 +61,7 @@ ifeq ($(ARCH),x86_64)
 	ifeq (${IS_X86_64}, 1)
 		RAW_ARCH := x86_64
 		ARCH_CFLAGS := -DARCH_X86_64
-		ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S
+		ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
 	endif
 endif
 
@@ -359,8 +359,10 @@ BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
 ifeq ($(RAW_ARCH),x86_64)
 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o
 endif
 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
 BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
@@ -792,7 +794,6 @@ help:
 	@echo '  quick-install-html	- install the html documentation quickly'
 	@echo ''
 	@echo 'Perf maintainer targets:'
-	@echo '  distclean		- alias to clean'
 	@echo '  clean			- clean all binary objects and build output'
 
 doc:
diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
index f7781c6..a09bece 100644
--- a/tools/perf/bench/bench.h
+++ b/tools/perf/bench/bench.h
@@ -4,6 +4,7 @@
 extern int bench_sched_messaging(int argc, const char **argv, const char *prefix);
 extern int bench_sched_pipe(int argc, const char **argv, const char *prefix);
 extern int bench_mem_memcpy(int argc, const char **argv, const char *prefix __used);
+extern int bench_mem_memset(int argc, const char **argv, const char *prefix);
 
 #define BENCH_FORMAT_DEFAULT_STR	"default"
 #define BENCH_FORMAT_DEFAULT		0
diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm-def.h b/tools/perf/bench/mem-memcpy-x86-64-asm-def.h
index d588b87..d66ab79 100644
--- a/tools/perf/bench/mem-memcpy-x86-64-asm-def.h
+++ b/tools/perf/bench/mem-memcpy-x86-64-asm-def.h
@@ -2,3 +2,11 @@
 MEMCPY_FN(__memcpy,
 	"x86-64-unrolled",
 	"unrolled memcpy() in arch/x86/lib/memcpy_64.S")
+
+MEMCPY_FN(memcpy_c,
+	"x86-64-movsq",
+	"movsq-based memcpy() in arch/x86/lib/memcpy_64.S")
+
+MEMCPY_FN(memcpy_c_e,
+	"x86-64-movsb",
+	"movsb-based memcpy() in arch/x86/lib/memcpy_64.S")
diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm.S b/tools/perf/bench/mem-memcpy-x86-64-asm.S
index 185a96d..fcd9cf0 100644
--- a/tools/perf/bench/mem-memcpy-x86-64-asm.S
+++ b/tools/perf/bench/mem-memcpy-x86-64-asm.S
@@ -1,4 +1,8 @@
-
+#define memcpy MEMCPY /* don't hide glibc's memcpy() */
+#define altinstr_replacement text
+#define globl p2align 4; .globl
+#define Lmemcpy_c globl memcpy_c; memcpy_c
+#define Lmemcpy_c_e globl memcpy_c_e; memcpy_c_e
 #include "../../../arch/x86/lib/memcpy_64.S"
 /*
  * We need to provide note.GNU-stack section, saying that we want
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index db82021..7155722 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -5,7 +5,6 @@
  *
  * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
  */
-#include <ctype.h>
 
 #include "../perf.h"
 #include "../util/util.h"
@@ -24,6 +23,7 @@
 
 static const char	*length_str	= "1MB";
 static const char	*routine	= "default";
+static int		iterations	= 1;
 static bool		use_clock;
 static int		clock_fd;
 static bool		only_prefault;
@@ -35,6 +35,8 @@ static const struct option options[] = {
 		    "available unit: B, MB, GB (upper and lower)"),
 	OPT_STRING('r', "routine", &routine, "default",
 		    "Specify routine to copy"),
+	OPT_INTEGER('i', "iterations", &iterations,
+		    "repeat memcpy() invocation this number of times"),
 	OPT_BOOLEAN('c', "clock", &use_clock,
 		    "Use CPU clock for measuring"),
 	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
@@ -121,6 +123,7 @@ static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault)
 {
 	u64 clock_start = 0ULL, clock_end = 0ULL;
 	void *src = NULL, *dst = NULL;
+	int i;
 
 	alloc_mem(&src, &dst, len);
 
@@ -128,7 +131,8 @@ static u64 do_memcpy_clock(memcpy_t fn, size_t len, bool prefault)
 		fn(dst, src, len);
 
 	clock_start = get_clock();
-	fn(dst, src, len);
+	for (i = 0; i < iterations; ++i)
+		fn(dst, src, len);
 	clock_end = get_clock();
 
 	free(src);
@@ -140,6 +144,7 @@ static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
 {
 	struct timeval tv_start, tv_end, tv_diff;
 	void *src = NULL, *dst = NULL;
+	int i;
 
 	alloc_mem(&src, &dst, len);
 
@@ -147,7 +152,8 @@ static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
 		fn(dst, src, len);
 
 	BUG_ON(gettimeofday(&tv_start, NULL));
-	fn(dst, src, len);
+	for (i = 0; i < iterations; ++i)
+		fn(dst, src, len);
 	BUG_ON(gettimeofday(&tv_end, NULL));
 
 	timersub(&tv_end, &tv_start, &tv_diff);
diff --git a/tools/perf/bench/mem-memset-arch.h b/tools/perf/bench/mem-memset-arch.h
new file mode 100644
index 0000000..a040fa7
--- /dev/null
+++ b/tools/perf/bench/mem-memset-arch.h
@@ -0,0 +1,12 @@
+
+#ifdef ARCH_X86_64
+
+#define MEMSET_FN(fn, name, desc)		\
+	extern void *fn(void *, int, size_t);
+
+#include "mem-memset-x86-64-asm-def.h"
+
+#undef MEMSET_FN
+
+#endif
+
diff --git a/tools/perf/bench/mem-memset-x86-64-asm-def.h b/tools/perf/bench/mem-memset-x86-64-asm-def.h
new file mode 100644
index 0000000..a71dff9
--- /dev/null
+++ b/tools/perf/bench/mem-memset-x86-64-asm-def.h
@@ -0,0 +1,12 @@
+
+MEMSET_FN(__memset,
+	"x86-64-unrolled",
+	"unrolled memset() in arch/x86/lib/memset_64.S")
+
+MEMSET_FN(memset_c,
+	"x86-64-stosq",
+	"movsq-based memset() in arch/x86/lib/memset_64.S")
+
+MEMSET_FN(memset_c_e,
+	"x86-64-stosb",
+	"movsb-based memset() in arch/x86/lib/memset_64.S")
diff --git a/tools/perf/bench/mem-memset-x86-64-asm.S b/tools/perf/bench/mem-memset-x86-64-asm.S
new file mode 100644
index 0000000..9e5af89
--- /dev/null
+++ b/tools/perf/bench/mem-memset-x86-64-asm.S
@@ -0,0 +1,13 @@
+#define memset MEMSET /* don't hide glibc's memset() */
+#define altinstr_replacement text
+#define globl p2align 4; .globl
+#define Lmemset_c globl memset_c; memset_c
+#define Lmemset_c_e globl memset_c_e; memset_c_e
+#include "../../../arch/x86/lib/memset_64.S"
+
+/*
+ * We need to provide note.GNU-stack section, saying that we want
+ * NOT executable stack. Otherwise the final linking will assume that
+ * the ELF stack should not be restricted at all and set it RWX.
+ */
+.section .note.GNU-stack,"",@progbits
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c
new file mode 100644
index 0000000..e907918
--- /dev/null
+++ b/tools/perf/bench/mem-memset.c
@@ -0,0 +1,297 @@
+/*
+ * mem-memset.c
+ *
+ * memset: Simple memory set in various ways
+ *
+ * Trivial clone of mem-memcpy.c.
+ */
+
+#include "../perf.h"
+#include "../util/util.h"
+#include "../util/parse-options.h"
+#include "../util/header.h"
+#include "bench.h"
+#include "mem-memset-arch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#define K 1024
+
+static const char	*length_str	= "1MB";
+static const char	*routine	= "default";
+static int		iterations	= 1;
+static bool		use_clock;
+static int		clock_fd;
+static bool		only_prefault;
+static bool		no_prefault;
+
+static const struct option options[] = {
+	OPT_STRING('l', "length", &length_str, "1MB",
+		    "Specify length of memory to copy. "
+		    "available unit: B, MB, GB (upper and lower)"),
+	OPT_STRING('r', "routine", &routine, "default",
+		    "Specify routine to copy"),
+	OPT_INTEGER('i', "iterations", &iterations,
+		    "repeat memset() invocation this number of times"),
+	OPT_BOOLEAN('c', "clock", &use_clock,
+		    "Use CPU clock for measuring"),
+	OPT_BOOLEAN('o', "only-prefault", &only_prefault,
+		    "Show only the result with page faults before memset()"),
+	OPT_BOOLEAN('n', "no-prefault", &no_prefault,
+		    "Show only the result without page faults before memset()"),
+	OPT_END()
+};
+
+typedef void *(*memset_t)(void *, int, size_t);
+
+struct routine {
+	const char *name;
+	const char *desc;
+	memset_t fn;
+};
+
+static const struct routine routines[] = {
+	{ "default",
+	  "Default memset() provided by glibc",
+	  memset },
+#ifdef ARCH_X86_64
+
+#define MEMSET_FN(fn, name, desc) { name, desc, fn },
+#include "mem-memset-x86-64-asm-def.h"
+#undef MEMSET_FN
+
+#endif
+
+	{ NULL,
+	  NULL,
+	  NULL   }
+};
+
+static const char * const bench_mem_memset_usage[] = {
+	"perf bench mem memset <options>",
+	NULL
+};
+
+static struct perf_event_attr clock_attr = {
+	.type		= PERF_TYPE_HARDWARE,
+	.config		= PERF_COUNT_HW_CPU_CYCLES
+};
+
+static void init_clock(void)
+{
+	clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0);
+
+	if (clock_fd < 0 && errno == ENOSYS)
+		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
+	else
+		BUG_ON(clock_fd < 0);
+}
+
+static u64 get_clock(void)
+{
+	int ret;
+	u64 clk;
+
+	ret = read(clock_fd, &clk, sizeof(u64));
+	BUG_ON(ret != sizeof(u64));
+
+	return clk;
+}
+
+static double timeval2double(struct timeval *ts)
+{
+	return (double)ts->tv_sec +
+		(double)ts->tv_usec / (double)1000000;
+}
+
+static void alloc_mem(void **dst, size_t length)
+{
+	*dst = zalloc(length);
+	if (!dst)
+		die("memory allocation failed - maybe length is too large?\n");
+}
+
+static u64 do_memset_clock(memset_t fn, size_t len, bool prefault)
+{
+	u64 clock_start = 0ULL, clock_end = 0ULL;
+	void *dst = NULL;
+	int i;
+
+	alloc_mem(&dst, len);
+
+	if (prefault)
+		fn(dst, -1, len);
+
+	clock_start = get_clock();
+	for (i = 0; i < iterations; ++i)
+		fn(dst, i, len);
+	clock_end = get_clock();
+
+	free(dst);
+	return clock_end - clock_start;
+}
+
+static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault)
+{
+	struct timeval tv_start, tv_end, tv_diff;
+	void *dst = NULL;
+	int i;
+
+	alloc_mem(&dst, len);
+
+	if (prefault)
+		fn(dst, -1, len);
+
+	BUG_ON(gettimeofday(&tv_start, NULL));
+	for (i = 0; i < iterations; ++i)
+		fn(dst, i, len);
+	BUG_ON(gettimeofday(&tv_end, NULL));
+
+	timersub(&tv_end, &tv_start, &tv_diff);
+
+	free(dst);
+	return (double)((double)len / timeval2double(&tv_diff));
+}
+
+#define pf (no_prefault ? 0 : 1)
+
+#define print_bps(x) do {					\
+		if (x < K)					\
+			printf(" %14lf B/Sec", x);		\
+		else if (x < K * K)				\
+			printf(" %14lfd KB/Sec", x / K);	\
+		else if (x < K * K * K)				\
+			printf(" %14lf MB/Sec", x / K / K);	\
+		else						\
+			printf(" %14lf GB/Sec", x / K / K / K); \
+	} while (0)
+
+int bench_mem_memset(int argc, const char **argv,
+		     const char *prefix __used)
+{
+	int i;
+	size_t len;
+	double result_bps[2];
+	u64 result_clock[2];
+
+	argc = parse_options(argc, argv, options,
+			     bench_mem_memset_usage, 0);
+
+	if (use_clock)
+		init_clock();
+
+	len = (size_t)perf_atoll((char *)length_str);
+
+	result_clock[0] = result_clock[1] = 0ULL;
+	result_bps[0] = result_bps[1] = 0.0;
+
+	if ((s64)len <= 0) {
+		fprintf(stderr, "Invalid length:%s\n", length_str);
+		return 1;
+	}
+
+	/* same to without specifying either of prefault and no-prefault */
+	if (only_prefault && no_prefault)
+		only_prefault = no_prefault = false;
+
+	for (i = 0; routines[i].name; i++) {
+		if (!strcmp(routines[i].name, routine))
+			break;
+	}
+	if (!routines[i].name) {
+		printf("Unknown routine:%s\n", routine);
+		printf("Available routines...\n");
+		for (i = 0; routines[i].name; i++) {
+			printf("\t%s ... %s\n",
+			       routines[i].name, routines[i].desc);
+		}
+		return 1;
+	}
+
+	if (bench_format == BENCH_FORMAT_DEFAULT)
+		printf("# Copying %s Bytes ...\n\n", length_str);
+
+	if (!only_prefault && !no_prefault) {
+		/* show both of results */
+		if (use_clock) {
+			result_clock[0] =
+				do_memset_clock(routines[i].fn, len, false);
+			result_clock[1] =
+				do_memset_clock(routines[i].fn, len, true);
+		} else {
+			result_bps[0] =
+				do_memset_gettimeofday(routines[i].fn,
+						len, false);
+			result_bps[1] =
+				do_memset_gettimeofday(routines[i].fn,
+						len, true);
+		}
+	} else {
+		if (use_clock) {
+			result_clock[pf] =
+				do_memset_clock(routines[i].fn,
+						len, only_prefault);
+		} else {
+			result_bps[pf] =
+				do_memset_gettimeofday(routines[i].fn,
+						len, only_prefault);
+		}
+	}
+
+	switch (bench_format) {
+	case BENCH_FORMAT_DEFAULT:
+		if (!only_prefault && !no_prefault) {
+			if (use_clock) {
+				printf(" %14lf Clock/Byte\n",
+					(double)result_clock[0]
+					/ (double)len);
+				printf(" %14lf Clock/Byte (with prefault)\n ",
+					(double)result_clock[1]
+					/ (double)len);
+			} else {
+				print_bps(result_bps[0]);
+				printf("\n");
+				print_bps(result_bps[1]);
+				printf(" (with prefault)\n");
+			}
+		} else {
+			if (use_clock) {
+				printf(" %14lf Clock/Byte",
+					(double)result_clock[pf]
+					/ (double)len);
+			} else
+				print_bps(result_bps[pf]);
+
+			printf("%s\n", only_prefault ? " (with prefault)" : "");
+		}
+		break;
+	case BENCH_FORMAT_SIMPLE:
+		if (!only_prefault && !no_prefault) {
+			if (use_clock) {
+				printf("%lf %lf\n",
+					(double)result_clock[0] / (double)len,
+					(double)result_clock[1] / (double)len);
+			} else {
+				printf("%lf %lf\n",
+					result_bps[0], result_bps[1]);
+			}
+		} else {
+			if (use_clock) {
+				printf("%lf\n", (double)result_clock[pf]
+					/ (double)len);
+			} else
+				printf("%lf\n", result_bps[pf]);
+		}
+		break;
+	default:
+		/* reaching this means there's some disaster: */
+		die("unknown format: %d\n", bench_format);
+		break;
+	}
+
+	return 0;
+}
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c
index fcb9626..b0e74ab 100644
--- a/tools/perf/builtin-bench.c
+++ b/tools/perf/builtin-bench.c
@@ -52,6 +52,9 @@ static struct bench_suite mem_suites[] = {
 	{ "memcpy",
 	  "Simple memory copy in various ways",
 	  bench_mem_memcpy },
+	{ "memset",
+	  "Simple memory set in various ways",
+	  bench_mem_memset },
 	suite_all,
 	{ NULL,
 	  NULL,
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 2296c39..12c8148 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -922,12 +922,12 @@ static const struct option info_options[] = {
 	OPT_BOOLEAN('t', "threads", &info_threads,
 		    "dump thread list in perf.data"),
 	OPT_BOOLEAN('m', "map", &info_map,
-		    "map of lock instances (name:address table)"),
+		    "map of lock instances (address:name table)"),
 	OPT_END()
 };
 
 static const char * const lock_usage[] = {
-	"perf lock [<options>] {record|trace|report}",
+	"perf lock [<options>] {record|report|script|info}",
 	NULL
 };
 
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index fb85661..c14d9c5 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -54,11 +54,12 @@ static struct {
 	bool show_ext_vars;
 	bool show_funcs;
 	bool mod_events;
+	bool uprobes;
 	int nevents;
 	struct perf_probe_event events[MAX_PROBES];
 	struct strlist *dellist;
 	struct line_range line_range;
-	const char *target_module;
+	const char *target;
 	int max_probe_points;
 	struct strfilter *filter;
 } params;
@@ -75,6 +76,7 @@ static int parse_probe_event(const char *str)
 		return -1;
 	}
 
+	pev->uprobes = params.uprobes;
 	/* Parse a perf-probe command into event */
 	ret = parse_perf_probe_command(str, pev);
 	pr_debug("%d arguments\n", pev->nargs);
@@ -125,6 +127,27 @@ static int opt_del_probe_event(const struct option *opt __used,
 	return 0;
 }
 
+static int opt_set_target(const struct option *opt, const char *str,
+			int unset __used)
+{
+	int ret = -ENOENT;
+
+	if  (str && !params.target) {
+		if (!strcmp(opt->long_name, "exec"))
+			params.uprobes = true;
+#ifdef DWARF_SUPPORT
+		else if (!strcmp(opt->long_name, "module"))
+			params.uprobes = false;
+#endif
+		else
+			return ret;
+
+		params.target = str;
+		ret = 0;
+	}
+	return ret;
+}
+
 #ifdef DWARF_SUPPORT
 static int opt_show_lines(const struct option *opt __used,
 			  const char *str, int unset __used)
@@ -246,9 +269,9 @@ static const struct option options[] = {
 		   "file", "vmlinux pathname"),
 	OPT_STRING('s', "source", &symbol_conf.source_prefix,
 		   "directory", "path to kernel source"),
-	OPT_STRING('m', "module", &params.target_module,
-		   "modname|path",
-		   "target module name (for online) or path (for offline)"),
+	OPT_CALLBACK('m', "module", NULL, "modname|path",
+		"target module name (for online) or path (for offline)",
+		opt_set_target),
 #endif
 	OPT__DRY_RUN(&probe_event_dry_run),
 	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -260,6 +283,8 @@ static const struct option options[] = {
 		     "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
 		     "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
 		     opt_set_filter),
+	OPT_CALLBACK('x', "exec", NULL, "executable|path",
+			"target executable name or path", opt_set_target),
 	OPT_END()
 };
 
@@ -310,6 +335,10 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 			pr_err("  Error: Don't use --list with --funcs.\n");
 			usage_with_options(probe_usage, options);
 		}
+		if (params.uprobes) {
+			pr_warning("  Error: Don't use --list with --exec.\n");
+			usage_with_options(probe_usage, options);
+		}
 		ret = show_perf_probe_events();
 		if (ret < 0)
 			pr_err("  Error: Failed to show event list. (%d)\n",
@@ -333,8 +362,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 		if (!params.filter)
 			params.filter = strfilter__new(DEFAULT_FUNC_FILTER,
 						       NULL);
-		ret = show_available_funcs(params.target_module,
-					   params.filter);
+		ret = show_available_funcs(params.target, params.filter,
+					params.uprobes);
 		strfilter__delete(params.filter);
 		if (ret < 0)
 			pr_err("  Error: Failed to show functions."
@@ -343,7 +372,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 	}
 
 #ifdef DWARF_SUPPORT
-	if (params.show_lines) {
+	if (params.show_lines && !params.uprobes) {
 		if (params.mod_events) {
 			pr_err("  Error: Don't use --line with"
 			       " --add/--del.\n");
@@ -354,7 +383,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 			usage_with_options(probe_usage, options);
 		}
 
-		ret = show_line_range(&params.line_range, params.target_module);
+		ret = show_line_range(&params.line_range, params.target);
 		if (ret < 0)
 			pr_err("  Error: Failed to show lines. (%d)\n", ret);
 		return ret;
@@ -371,7 +400,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 
 		ret = show_available_vars(params.events, params.nevents,
 					  params.max_probe_points,
-					  params.target_module,
+					  params.target,
 					  params.filter,
 					  params.show_ext_vars);
 		strfilter__delete(params.filter);
@@ -393,7 +422,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
 	if (params.nevents) {
 		ret = add_perf_probe_events(params.events, params.nevents,
 					    params.max_probe_points,
-					    params.target_module,
+					    params.target,
 					    params.force_add);
 		if (ret < 0) {
 			pr_err("  Error: Failed to add events. (%d)\n", ret);
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 0abfb18..f8d9a54 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -44,6 +44,7 @@ struct perf_record {
 	struct perf_evlist	*evlist;
 	struct perf_session	*session;
 	const char		*progname;
+	const char		*uid_str;
 	int			output;
 	unsigned int		page_size;
 	int			realtime_prio;
@@ -385,7 +386,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 {
 	struct stat st;
 	int flags;
-	int err, output;
+	int err, output, feat;
 	unsigned long waking = 0;
 	const bool forks = argc > 0;
 	struct machine *machine;
@@ -452,8 +453,14 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 
 	rec->session = session;
 
-	if (!rec->no_buildid)
-		perf_header__set_feat(&session->header, HEADER_BUILD_ID);
+	for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++)
+		perf_header__set_feat(&session->header, feat);
+
+	if (rec->no_buildid)
+		perf_header__clear_feat(&session->header, HEADER_BUILD_ID);
+
+	if (!have_tracepoints(&evsel_list->entries))
+		perf_header__clear_feat(&session->header, HEADER_TRACE_INFO);
 
 	if (!rec->file_new) {
 		err = perf_session__read_header(session, output);
@@ -461,22 +468,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
 			goto out_delete_session;
 	}
 
-	if (have_tracepoints(&evsel_list->entries))
-		perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
-
-	perf_header__set_feat(&session->header, HEADER_HOSTNAME);
-	perf_header__set_feat(&session->header, HEADER_OSRELEASE);
-	perf_header__set_feat(&session->header, HEADER_ARCH);
-	perf_header__set_feat(&session->header, HEADER_CPUDESC);
-	perf_header__set_feat(&session->header, HEADER_NRCPUS);
-	perf_header__set_feat(&session->header, HEADER_EVENT_DESC);
-	perf_header__set_feat(&session->header, HEADER_CMDLINE);
-	perf_header__set_feat(&session->header, HEADER_VERSION);
-	perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY);
-	perf_header__set_feat(&session->header, HEADER_TOTAL_MEM);
-	perf_header__set_feat(&session->header, HEADER_NUMA_TOPOLOGY);
-	perf_header__set_feat(&session->header, HEADER_CPUID);
-
 	if (forks) {
 		err = perf_evlist__prepare_workload(evsel_list, opts, argv);
 		if (err < 0) {
@@ -727,6 +718,7 @@ const struct option record_options[] = {
 	OPT_CALLBACK('G', "cgroup", &record.evlist, "name",
 		     "monitor event in cgroup name only",
 		     parse_cgroups),
+	OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"),
 	OPT_END()
 };
 
@@ -748,7 +740,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
 	argc = parse_options(argc, argv, record_options, record_usage,
 			    PARSE_OPT_STOP_AT_NON_OPTION);
 	if (!argc && rec->opts.target_pid == -1 && rec->opts.target_tid == -1 &&
-		!rec->opts.system_wide && !rec->opts.cpu_list)
+		!rec->opts.system_wide && !rec->opts.cpu_list && !rec->uid_str)
 		usage_with_options(record_usage, record_options);
 
 	if (rec->force && rec->append_file) {
@@ -788,11 +780,17 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
 		goto out_symbol_exit;
 	}
 
+	rec->opts.uid = parse_target_uid(rec->uid_str, rec->opts.target_tid,
+					 rec->opts.target_pid);
+	if (rec->uid_str != NULL && rec->opts.uid == UINT_MAX - 1)
+		goto out_free_fd;
+
 	if (rec->opts.target_pid != -1)
 		rec->opts.target_tid = rec->opts.target_pid;
 
 	if (perf_evlist__create_maps(evsel_list, rec->opts.target_pid,
-				     rec->opts.target_tid, rec->opts.cpu_list) < 0)
+				     rec->opts.target_tid, rec->opts.uid,
+				     rec->opts.cpu_list) < 0)
 		usage_with_options(record_usage, record_options);
 
 	list_for_each_entry(pos, &evsel_list->entries, node) {
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index bb68ddf..d4ce733 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -40,6 +40,7 @@ enum perf_output_field {
 	PERF_OUTPUT_SYM             = 1U << 8,
 	PERF_OUTPUT_DSO             = 1U << 9,
 	PERF_OUTPUT_ADDR            = 1U << 10,
+	PERF_OUTPUT_SYMOFFSET       = 1U << 11,
 };
 
 struct output_option {
@@ -57,6 +58,7 @@ struct output_option {
 	{.str = "sym",   .field = PERF_OUTPUT_SYM},
 	{.str = "dso",   .field = PERF_OUTPUT_DSO},
 	{.str = "addr",  .field = PERF_OUTPUT_ADDR},
+	{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
 };
 
 /* default set to maintain compatibility with current format */
@@ -193,6 +195,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
 		       "to symbols.\n");
 		return -EINVAL;
 	}
+	if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
+		pr_err("Display of offsets requested but symbol is not"
+		       "selected.\n");
+		return -EINVAL;
+	}
 	if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
 		pr_err("Display of DSO requested but neither sample IP nor "
 			   "sample address\nis selected. Hence, no addresses to convert "
@@ -300,10 +307,17 @@ static void print_sample_start(struct perf_sample *sample,
 		} else
 			evname = __event_name(attr->type, attr->config);
 
-		printf("%s: ", evname ? evname : "(unknown)");
+		printf("%s: ", evname ? evname : "[unknown]");
 	}
 }
 
+static bool is_bts_event(struct perf_event_attr *attr)
+{
+	return ((attr->type == PERF_TYPE_HARDWARE) &&
+		(attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
+		(attr->sample_period == 1));
+}
+
 static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
 {
 	if ((attr->type == PERF_TYPE_SOFTWARE) &&
@@ -312,6 +326,9 @@ static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
 	     (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
 		return true;
 
+	if (is_bts_event(attr))
+		return true;
+
 	return false;
 }
 
@@ -323,7 +340,6 @@ static void print_sample_addr(union perf_event *event,
 {
 	struct addr_location al;
 	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-	const char *symname, *dsoname;
 
 	printf("%16" PRIx64, sample->addr);
 
@@ -343,22 +359,46 @@ static void print_sample_addr(union perf_event *event,
 		al.sym = map__find_symbol(al.map, al.addr, NULL);
 
 	if (PRINT_FIELD(SYM)) {
-		if (al.sym && al.sym->name)
-			symname = al.sym->name;
+		printf(" ");
+		if (PRINT_FIELD(SYMOFFSET))
+			symbol__fprintf_symname_offs(al.sym, &al, stdout);
 		else
-			symname = "";
-
-		printf(" %16s", symname);
+			symbol__fprintf_symname(al.sym, stdout);
 	}
 
 	if (PRINT_FIELD(DSO)) {
-		if (al.map && al.map->dso && al.map->dso->name)
-			dsoname = al.map->dso->name;
-		else
-			dsoname = "";
+		printf(" (");
+		map__fprintf_dsoname(al.map, stdout);
+		printf(")");
+	}
+}
 
-		printf(" (%s)", dsoname);
+static void print_sample_bts(union perf_event *event,
+			     struct perf_sample *sample,
+			     struct perf_evsel *evsel,
+			     struct machine *machine,
+			     struct thread *thread)
+{
+	struct perf_event_attr *attr = &evsel->attr;
+
+	/* print branch_from information */
+	if (PRINT_FIELD(IP)) {
+		if (!symbol_conf.use_callchain)
+			printf(" ");
+		else
+			printf("\n");
+		perf_event__print_ip(event, sample, machine, evsel,
+				     PRINT_FIELD(SYM), PRINT_FIELD(DSO),
+				     PRINT_FIELD(SYMOFFSET));
 	}
+
+	printf(" => ");
+
+	/* print branch_to information */
+	if (PRINT_FIELD(ADDR))
+		print_sample_addr(event, sample, machine, thread, attr);
+
+	printf("\n");
 }
 
 static void process_event(union perf_event *event __unused,
@@ -374,6 +414,11 @@ static void process_event(union perf_event *event __unused,
 
 	print_sample_start(sample, thread, attr);
 
+	if (is_bts_event(attr)) {
+		print_sample_bts(event, sample, evsel, machine, thread);
+		return;
+	}
+
 	if (PRINT_FIELD(TRACE))
 		print_trace_event(sample->cpu, sample->raw_data,
 				  sample->raw_size);
@@ -387,7 +432,8 @@ static void process_event(union perf_event *event __unused,
 		else
 			printf("\n");
 		perf_event__print_ip(event, sample, machine, evsel,
-				     PRINT_FIELD(SYM), PRINT_FIELD(DSO));
+				     PRINT_FIELD(SYM), PRINT_FIELD(DSO),
+				     PRINT_FIELD(SYMOFFSET));
 	}
 
 	printf("\n");
@@ -1097,7 +1143,10 @@ static const struct option options[] = {
 	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
 		    "Look for files with symbols relative to this directory"),
 	OPT_CALLBACK('f', "fields", NULL, "str",
-		     "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
+		     "comma separated output fields prepend with 'type:'. "
+		     "Valid types: hw,sw,trace,raw. "
+		     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
+		     "addr,symoff",
 		     parse_output_fields),
 	OPT_BOOLEAN('a', "all-cpus", &system_wide,
 		     "system-wide collection from all CPUs"),
@@ -1106,6 +1155,9 @@ static const struct option options[] = {
 		   "only display events for these comms"),
 	OPT_BOOLEAN('I', "show-info", &show_full_info,
 		    "display extended information from perf.data file"),
+	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
+		    "Show the path of [kernel.kallsyms]"),
+
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f5d2a63..d14b37a 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -576,6 +576,8 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
 		fprintf(output, " # %8.3f CPUs utilized          ",
 			avg / avg_stats(&walltime_nsecs_stats));
+	else
+		fprintf(output, "                                   ");
 }
 
 /* used for get_ratio_color() */
@@ -844,12 +846,18 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
 
 		fprintf(output, " # %8.3f GHz                    ", ratio);
 	} else if (runtime_nsecs_stats[cpu].n != 0) {
+		char unit = 'M';
+
 		total = avg_stats(&runtime_nsecs_stats[cpu]);
 
 		if (total)
 			ratio = 1000.0 * avg / total;
+		if (ratio < 0.001) {
+			ratio *= 1000;
+			unit = 'K';
+		}
 
-		fprintf(output, " # %8.3f M/sec                  ", ratio);
+		fprintf(output, " # %8.3f %c/sec                  ", ratio, unit);
 	} else {
 		fprintf(output, "                                   ");
 	}
@@ -1201,7 +1209,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
 	if (target_pid != -1)
 		target_tid = target_pid;
 
-	evsel_list->threads = thread_map__new(target_pid, target_tid);
+	evsel_list->threads = thread_map__new(target_pid, target_tid, UINT_MAX);
 	if (evsel_list->threads == NULL) {
 		pr_err("Problems finding threads of monitor\n");
 		usage_with_options(stat_usage, options);
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 3854e86..70c4eb2 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -15,6 +15,8 @@
 #include "util/thread_map.h"
 #include "../../include/linux/hw_breakpoint.h"
 
+#include <sys/mman.h>
+
 static int vmlinux_matches_kallsyms_filter(struct map *map __used, struct symbol *sym)
 {
 	bool *visited = symbol__priv(sym);
@@ -276,7 +278,7 @@ static int test__open_syscall_event(void)
 		return -1;
 	}
 
-	threads = thread_map__new(-1, getpid());
+	threads = thread_map__new(-1, getpid(), UINT_MAX);
 	if (threads == NULL) {
 		pr_debug("thread_map__new\n");
 		return -1;
@@ -342,7 +344,7 @@ static int test__open_syscall_event_on_all_cpus(void)
 		return -1;
 	}
 
-	threads = thread_map__new(-1, getpid());
+	threads = thread_map__new(-1, getpid(), UINT_MAX);
 	if (threads == NULL) {
 		pr_debug("thread_map__new\n");
 		return -1;
@@ -490,7 +492,7 @@ static int test__basic_mmap(void)
 		expected_nr_events[i] = random() % 257;
 	}
 
-	threads = thread_map__new(-1, getpid());
+	threads = thread_map__new(-1, getpid(), UINT_MAX);
 	if (threads == NULL) {
 		pr_debug("thread_map__new\n");
 		return -1;
@@ -1054,7 +1056,7 @@ static int test__PERF_RECORD(void)
 	 * we're monitoring, the one forked there.
 	 */
 	err = perf_evlist__create_maps(evlist, opts.target_pid,
-				       opts.target_tid, opts.cpu_list);
+				       opts.target_tid, UINT_MAX, opts.cpu_list);
 	if (err < 0) {
 		pr_debug("Not enough memory to create thread/cpu maps\n");
 		goto out_delete_evlist;
@@ -1296,6 +1298,173 @@ out:
 	return (err < 0 || errs > 0) ? -1 : 0;
 }
 
+
+#if defined(__x86_64__) || defined(__i386__)
+
+#define barrier() asm volatile("" ::: "memory")
+
+static u64 rdpmc(unsigned int counter)
+{
+	unsigned int low, high;
+
+	asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter));
+
+	return low | ((u64)high) << 32;
+}
+
+static u64 rdtsc(void)
+{
+	unsigned int low, high;
+
+	asm volatile("rdtsc" : "=a" (low), "=d" (high));
+
+	return low | ((u64)high) << 32;
+}
+
+static u64 mmap_read_self(void *addr)
+{
+	struct perf_event_mmap_page *pc = addr;
+	u32 seq, idx, time_mult = 0, time_shift = 0;
+	u64 count, cyc = 0, time_offset = 0, enabled, running, delta;
+
+	do {
+		seq = pc->lock;
+		barrier();
+
+		enabled = pc->time_enabled;
+		running = pc->time_running;
+
+		if (enabled != running) {
+			cyc = rdtsc();
+			time_mult = pc->time_mult;
+			time_shift = pc->time_shift;
+			time_offset = pc->time_offset;
+		}
+
+		idx = pc->index;
+		count = pc->offset;
+		if (idx)
+			count += rdpmc(idx - 1);
+
+		barrier();
+	} while (pc->lock != seq);
+
+	if (enabled != running) {
+		u64 quot, rem;
+
+		quot = (cyc >> time_shift);
+		rem = cyc & ((1 << time_shift) - 1);
+		delta = time_offset + quot * time_mult +
+			((rem * time_mult) >> time_shift);
+
+		enabled += delta;
+		if (idx)
+			running += delta;
+
+		quot = count / running;
+		rem = count % running;
+		count = quot * enabled + (rem * enabled) / running;
+	}
+
+	return count;
+}
+
+/*
+ * If the RDPMC instruction faults then signal this back to the test parent task:
+ */
+static void segfault_handler(int sig __used, siginfo_t *info __used, void *uc __used)
+{
+	exit(-1);
+}
+
+static int __test__rdpmc(void)
+{
+	long page_size = sysconf(_SC_PAGE_SIZE);
+	volatile int tmp = 0;
+	u64 i, loops = 1000;
+	int n;
+	int fd;
+	void *addr;
+	struct perf_event_attr attr = {
+		.type = PERF_TYPE_HARDWARE,
+		.config = PERF_COUNT_HW_INSTRUCTIONS,
+		.exclude_kernel = 1,
+	};
+	u64 delta_sum = 0;
+        struct sigaction sa;
+
+	sigfillset(&sa.sa_mask);
+	sa.sa_sigaction = segfault_handler;
+	sigaction(SIGSEGV, &sa, NULL);
+
+	fprintf(stderr, "\n\n");
+
+	fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
+	if (fd < 0) {
+		die("Error: sys_perf_event_open() syscall returned "
+		    "with %d (%s)\n", fd, strerror(errno));
+	}
+
+	addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0);
+	if (addr == (void *)(-1)) {
+		die("Error: mmap() syscall returned "
+		    "with (%s)\n", strerror(errno));
+	}
+
+	for (n = 0; n < 6; n++) {
+		u64 stamp, now, delta;
+
+		stamp = mmap_read_self(addr);
+
+		for (i = 0; i < loops; i++)
+			tmp++;
+
+		now = mmap_read_self(addr);
+		loops *= 10;
+
+		delta = now - stamp;
+		fprintf(stderr, "%14d: %14Lu\n", n, (long long)delta);
+
+		delta_sum += delta;
+	}
+
+	munmap(addr, page_size);
+	close(fd);
+
+	fprintf(stderr, "   ");
+
+	if (!delta_sum)
+		return -1;
+
+	return 0;
+}
+
+static int test__rdpmc(void)
+{
+	int status = 0;
+	int wret = 0;
+	int ret;
+	int pid;
+
+	pid = fork();
+	if (pid < 0)
+		return -1;
+
+	if (!pid) {
+		ret = __test__rdpmc();
+
+		exit(ret);
+	}
+
+	wret = waitpid(pid, &status, 0);
+	if (wret < 0 || status)
+		return -1;
+
+	return 0;
+}
+
+#endif
+
 static struct test {
 	const char *desc;
 	int (*func)(void);
@@ -1320,6 +1489,12 @@ static struct test {
 		.desc = "parse events tests",
 		.func = test__parse_events,
 	},
+#if defined(__x86_64__) || defined(__i386__)
+	{
+		.desc = "x86 rdpmc test",
+		.func = test__rdpmc,
+	},
+#endif
 	{
 		.desc = "Validate PERF_RECORD_* events & perf_sample fields",
 		.func = test__PERF_RECORD,
@@ -1412,7 +1587,5 @@ int cmd_test(int argc, const char **argv, const char *prefix __used)
 	if (symbol__init() < 0)
 		return -1;
 
-	setup_pager();
-
 	return __cmd_test(argc, argv);
 }
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index dd162aa..d869b21 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -64,7 +64,6 @@
 #include <linux/unistd.h>
 #include <linux/types.h>
 
-
 void get_term_dimensions(struct winsize *ws)
 {
 	char *s = getenv("LINES");
@@ -544,10 +543,20 @@ static void perf_top__sort_new_samples(void *arg)
 
 static void *display_thread_tui(void *arg)
 {
+	struct perf_evsel *pos;
 	struct perf_top *top = arg;
 	const char *help = "For a higher level overview, try: perf top --sort comm,dso";
 
 	perf_top__sort_new_samples(top);
+
+	/*
+	 * Initialize the uid_filter_str, in the future the TUI will allow
+	 * Zooming in/out UIDs. For now juse use whatever the user passed
+	 * via --uid.
+	 */
+	list_for_each_entry(pos, &top->evlist->entries, node)
+		pos->hists.uid_filter_str = top->uid_str;
+
 	perf_evlist__tui_browse_hists(top->evlist, help,
 				      perf_top__sort_new_samples,
 				      top, top->delay_secs);
@@ -956,7 +965,7 @@ static int __cmd_top(struct perf_top *top)
 	if (ret)
 		goto out_delete;
 
-	if (top->target_tid != -1)
+	if (top->target_tid != -1 || top->uid != UINT_MAX)
 		perf_event__synthesize_thread_map(&top->tool, top->evlist->threads,
 						  perf_event__process,
 						  &top->session->host_machine);
@@ -1096,6 +1105,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 		.delay_secs	     = 2,
 		.target_pid	     = -1,
 		.target_tid	     = -1,
+		.uid		     = UINT_MAX,
 		.freq		     = 1000, /* 1 KHz */
 		.sample_id_all_avail = true,
 		.mmap_pages	     = 128,
@@ -1169,6 +1179,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 		    "Display raw encoding of assembly instructions (default)"),
 	OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
 		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
+	OPT_STRING('u', "uid", &top.uid_str, "user", "user to profile"),
 	OPT_END()
 	};
 
@@ -1194,6 +1205,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 
 	setup_browser(false);
 
+	top.uid = parse_target_uid(top.uid_str, top.target_tid, top.target_pid);
+	if (top.uid_str != NULL && top.uid == UINT_MAX - 1)
+		goto out_delete_evlist;
+
 	/* CPU and PID are mutually exclusive */
 	if (top.target_tid > 0 && top.cpu_list) {
 		printf("WARNING: PID switch overriding CPU\n");
@@ -1205,7 +1220,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 		top.target_tid = top.target_pid;
 
 	if (perf_evlist__create_maps(top.evlist, top.target_pid,
-				     top.target_tid, top.cpu_list) < 0)
+				     top.target_tid, top.uid, top.cpu_list) < 0)
 		usage_with_options(top_usage, options);
 
 	if (!top.evlist->nr_entries &&
@@ -1269,6 +1284,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
 
 	status = __cmd_top(&top);
 
+out_delete_evlist:
 	perf_evlist__delete(top.evlist);
 
 	return status;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 64f8bee..92af168 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -188,6 +188,7 @@ void pthread__unblock_sigwinch(void);
 struct perf_record_opts {
 	pid_t	     target_pid;
 	pid_t	     target_tid;
+	uid_t	     uid;
 	bool	     call_graph;
 	bool	     group;
 	bool	     inherit_stat;
diff --git a/tools/perf/python/twatch.py b/tools/perf/python/twatch.py
index df638c4..b11cca5 100755
--- a/tools/perf/python/twatch.py
+++ b/tools/perf/python/twatch.py
@@ -19,7 +19,7 @@ def main():
 	cpus = perf.cpu_map()
 	threads = perf.thread_map()
 	evsel = perf.evsel(task = 1, comm = 1, mmap = 0,
-			   wakeup_events = 1, sample_period = 1,
+			   wakeup_events = 1, watermark = 1,
 			   sample_id_all = 1,
 			   sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU | perf.SAMPLE_TID)
 	evsel.open(cpus = cpus, threads = threads);
diff --git a/tools/perf/scripts/perl/bin/ibs-record b/tools/perf/scripts/perl/bin/ibs-record
new file mode 100644
index 0000000..dc5f4d2
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/ibs-record
@@ -0,0 +1,23 @@
+#! /bin/bash
+
+while [ "${1+defined}" ]; do
+    case $1 in
+	ibs_op|ibs_fetch)
+	    EVENT=$1
+	    shift
+	    break
+	    ;;
+	-*)
+	    REC_OPT+=($1)
+	    shift
+	    ;;
+	*)
+	    echo $0 "$@" >&2
+	    echo "Invalid option: $1" >&2
+	    echo "perf script ibs [ibs_op|ibs_fetch] [-c <period>]" >&2
+	    exit 1
+	    ;;
+    esac
+done
+
+perf record -e ${EVENT:-ibs_op}:r0 -c 100000 -R -a "${REC_OPT[@]}" "$@"
diff --git a/tools/perf/scripts/perl/bin/ibs-report b/tools/perf/scripts/perl/bin/ibs-report
new file mode 100644
index 0000000..f44e69d
--- /dev/null
+++ b/tools/perf/scripts/perl/bin/ibs-report
@@ -0,0 +1,6 @@
+#! /bin/bash
+
+# description: collect and display AMD IBS samples
+# args: [ibs_op|ibs_fetch] [-c period]
+
+perf script -s "$PERF_EXEC_PATH"/scripts/perl/ibs.pl "$@"
diff --git a/tools/perf/scripts/perl/ibs.pl b/tools/perf/scripts/perl/ibs.pl
new file mode 100644
index 0000000..caee32f
--- /dev/null
+++ b/tools/perf/scripts/perl/ibs.pl
@@ -0,0 +1,47 @@
+#
+# ibs.pl - perf script for AMD Instruction Based Sampling
+#
+# Copyright (C) 2011 Advanced Micro Devices, Inc., Robert Richter
+#
+# For licencing details see kernel-base/COPYING
+#
+# description: collect and display AMD IBS samples
+# args: [ibs_op|ibs_fetch] [-c period]
+#
+# examples:
+#
+#  perf script ibs ibs_op <command>
+#  perf script ibs ibs_fetch <command>
+#  perf script record ibs ibs_op -c 500000 <command>
+#  perf script report ibs
+#  perf script record ibs ibs_op -c 500000 <command> | perf script report ibs
+#
+
+# Packed byte string args of process_event():
+#
+# $event:	union perf_event	util/event.h
+# $attr:	struct perf_event_attr	linux/perf_event.h
+# $sample:	struct perf_sample	util/event.h
+# $raw_data:	perf_sample->raw_data	util/event.h
+
+sub process_event
+{
+	my ($event, $attr, $sample, $raw_data) = @_;
+
+	my ($type)		= (unpack("LSS", $event))[0];
+	my ($sample_type)	= (unpack("LLQQQQQLLQQ", $attr))[4];
+	my ($cpu, $raw_size)	= (unpack("QLLQQQQQLL", $sample))[8, 9];
+	my ($caps, @ibs_data)	= unpack("LQ*", $raw_data);
+
+	return if (!$raw_size);		# no raw data
+
+	if (scalar(@ibs_data) ==  3) {
+	        printf("IBS_FETCH sample on cpu%d\tIBS0: 0x%016x IBS1: 0x%016x IBS2:0x%016x\n",
+		       $cpu, @ibs_data);
+	} else {
+	        printf("IBS_OP sample on cpu%d\t" .
+		       "\t IBS0: 0x%016x IBS1: 0x%016x IBS2: 0x%016x\n" .
+		       "\tIBS3: 0x%016x IBS4: 0x%016x IBS5: 0x%016x IBS6: 0x%016x\n",
+		       cpu, @ibs_data);
+	}
+}
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 6893eec..adc72f0 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -166,6 +166,17 @@ out:
 	return cpus;
 }
 
+size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp)
+{
+	int i;
+	size_t printed = fprintf(fp, "%d cpu%s: ",
+				 map->nr, map->nr > 1 ? "s" : "");
+	for (i = 0; i < map->nr; ++i)
+		printed += fprintf(fp, "%s%d", i ? ", " : "", map->map[i]);
+
+	return printed + fprintf(fp, "\n");
+}
+
 struct cpu_map *cpu_map__dummy_new(void)
 {
 	struct cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int));
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 072c0a3..c415185 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -1,6 +1,8 @@
 #ifndef __PERF_CPUMAP_H
 #define __PERF_CPUMAP_H
 
+#include <stdio.h>
+
 struct cpu_map {
 	int nr;
 	int map[];
@@ -10,4 +12,6 @@ struct cpu_map *cpu_map__new(const char *cpu_list);
 struct cpu_map *cpu_map__dummy_new(void);
 void cpu_map__delete(struct cpu_map *map);
 
+size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
+
 #endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3f16e08..a57a8cf 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -97,9 +97,9 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
 	++evlist->nr_entries;
 }
 
-static void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
-					  struct list_head *list,
-					  int nr_entries)
+void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
+				   struct list_head *list,
+				   int nr_entries)
 {
 	list_splice_tail(list, &evlist->entries);
 	evlist->nr_entries += nr_entries;
@@ -594,14 +594,14 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 }
 
 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
-			     pid_t target_tid, const char *cpu_list)
+			     pid_t target_tid, uid_t uid, const char *cpu_list)
 {
-	evlist->threads = thread_map__new(target_pid, target_tid);
+	evlist->threads = thread_map__new(target_pid, target_tid, uid);
 
 	if (evlist->threads == NULL)
 		return -1;
 
-	if (cpu_list == NULL && target_tid != -1)
+	if (uid != UINT_MAX || (cpu_list == NULL && target_tid != -1))
 		evlist->cpus = cpu_map__dummy_new();
 	else
 		evlist->cpus = cpu_map__new(cpu_list);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 8922aee..1b4282b 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -107,7 +107,7 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
 }
 
 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
-			     pid_t target_tid, const char *cpu_list);
+			     pid_t tid, uid_t uid, const char *cpu_list);
 void perf_evlist__delete_maps(struct perf_evlist *evlist);
 int perf_evlist__set_filters(struct perf_evlist *evlist);
 
@@ -117,4 +117,9 @@ u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist);
 
 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
+
+void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
+				   struct list_head *list,
+				   int nr_entries);
+
 #endif /* __PERF_EVLIST_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7132ee8..9a11f9e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -536,7 +536,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
 	}
 
 	if (type & PERF_SAMPLE_READ) {
-		fprintf(stderr, "PERF_SAMPLE_READ is unsuported for now\n");
+		fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n");
 		return -1;
 	}
 
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ecd7f4d..626eb90 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -988,6 +988,73 @@ done:
 	return ret;
 }
 
+#define EVENT_SOURCE_DEVICE_PATH "/sys/bus/event_source/devices/"
+
+/*
+ * File format:
+ *
+ * struct pmu_mappings {
+ *	u32	pmu_num;
+ *	struct pmu_map {
+ *		u32	type;
+ *		char	name[];
+ *	}[pmu_num];
+ * };
+ */
+
+static int write_pmu_mappings(int fd, struct perf_header *h __used,
+			      struct perf_evlist *evlist __used)
+{
+	char path[MAXPATHLEN];
+	DIR *dir;
+	struct dirent *dent;
+	FILE *fp;
+	char *line = NULL;
+	off_t offset = lseek(fd, 0, SEEK_CUR);
+	size_t ignore;
+	u32 pmu_num = 0;
+	u32 type;
+
+	dir = opendir(EVENT_SOURCE_DEVICE_PATH);
+	if (!dir)
+		return -1;
+
+	/* write real pmu_num later */
+	do_write(fd, &pmu_num, sizeof(pmu_num));
+
+	while ((dent = readdir(dir))) {
+		if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+			continue;
+		snprintf(path, sizeof(path), "%s%s/type",
+			 EVENT_SOURCE_DEVICE_PATH, dent->d_name);
+		fp = fopen(path, "r");
+		if (!fp)
+			continue;
+		if (getline(&line, &ignore, fp) < 0) {
+			fclose(fp);
+			continue;
+		}
+		fclose(fp);
+		type = atoi(line);
+		if (!type)
+			continue;
+		pmu_num++;
+		do_write(fd, &type, sizeof(type));
+		do_write_string(fd, dent->d_name);
+	}
+
+	free(line);
+	closedir(dir);
+
+	if (pwrite(fd, &pmu_num, sizeof(pmu_num), offset) != sizeof(pmu_num)) {
+		/* discard all */
+		lseek(fd, offset, SEEK_SET);
+		return -1;
+	}
+
+	return 0;
+}
+
 /*
  * default get_cpuid(): nothing gets recorded
  * actual implementation must be in arch/$(ARCH)/util/header.c
@@ -1305,25 +1372,229 @@ static void print_cpuid(struct perf_header *ph, int fd, FILE *fp)
 	free(str);
 }
 
+static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp)
+{
+	const char *delimiter = "# pmu mappings: ";
+	char *name;
+	int ret;
+	u32 pmu_num;
+	u32 type;
+
+	ret = read(fd, &pmu_num, sizeof(pmu_num));
+	if (ret != sizeof(pmu_num))
+		goto error;
+
+	if (!pmu_num)
+		goto error;
+
+	while (pmu_num--) {
+		if (read(fd, &type, sizeof(type)) != sizeof(type))
+			goto error;
+		name = do_read_string(fd, ph);
+		fprintf(fp, "%s%s = %" PRIu32, delimiter, name, type);
+		free(name);
+		delimiter = ", ";
+	}
+
+	fprintf(fp, "\n");
+
+	return;
+error:
+	fprintf(fp, "# pmu mappings: not available\n");
+}
+
+static int __event_process_build_id(struct build_id_event *bev,
+				    char *filename,
+				    struct perf_session *session)
+{
+	int err = -1;
+	struct list_head *head;
+	struct machine *machine;
+	u16 misc;
+	struct dso *dso;
+	enum dso_kernel_type dso_type;
+
+	machine = perf_session__findnew_machine(session, bev->pid);
+	if (!machine)
+		goto out;
+
+	misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+	switch (misc) {
+	case PERF_RECORD_MISC_KERNEL:
+		dso_type = DSO_TYPE_KERNEL;
+		head = &machine->kernel_dsos;
+		break;
+	case PERF_RECORD_MISC_GUEST_KERNEL:
+		dso_type = DSO_TYPE_GUEST_KERNEL;
+		head = &machine->kernel_dsos;
+		break;
+	case PERF_RECORD_MISC_USER:
+	case PERF_RECORD_MISC_GUEST_USER:
+		dso_type = DSO_TYPE_USER;
+		head = &machine->user_dsos;
+		break;
+	default:
+		goto out;
+	}
+
+	dso = __dsos__findnew(head, filename);
+	if (dso != NULL) {
+		char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+		dso__set_build_id(dso, &bev->build_id);
+
+		if (filename[0] == '[')
+			dso->kernel = dso_type;
+
+		build_id__sprintf(dso->build_id, sizeof(dso->build_id),
+				  sbuild_id);
+		pr_debug("build id event received for %s: %s\n",
+			 dso->long_name, sbuild_id);
+	}
+
+	err = 0;
+out:
+	return err;
+}
+
+static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
+						 int input, u64 offset, u64 size)
+{
+	struct perf_session *session = container_of(header, struct perf_session, header);
+	struct {
+		struct perf_event_header   header;
+		u8			   build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
+		char			   filename[0];
+	} old_bev;
+	struct build_id_event bev;
+	char filename[PATH_MAX];
+	u64 limit = offset + size;
+
+	while (offset < limit) {
+		ssize_t len;
+
+		if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev))
+			return -1;
+
+		if (header->needs_swap)
+			perf_event_header__bswap(&old_bev.header);
+
+		len = old_bev.header.size - sizeof(old_bev);
+		if (read(input, filename, len) != len)
+			return -1;
+
+		bev.header = old_bev.header;
+
+		/*
+		 * As the pid is the missing value, we need to fill
+		 * it properly. The header.misc value give us nice hint.
+		 */
+		bev.pid	= HOST_KERNEL_ID;
+		if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER ||
+		    bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL)
+			bev.pid	= DEFAULT_GUEST_KERNEL_ID;
+
+		memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id));
+		__event_process_build_id(&bev, filename, session);
+
+		offset += bev.header.size;
+	}
+
+	return 0;
+}
+
+static int perf_header__read_build_ids(struct perf_header *header,
+				       int input, u64 offset, u64 size)
+{
+	struct perf_session *session = container_of(header, struct perf_session, header);
+	struct build_id_event bev;
+	char filename[PATH_MAX];
+	u64 limit = offset + size, orig_offset = offset;
+	int err = -1;
+
+	while (offset < limit) {
+		ssize_t len;
+
+		if (read(input, &bev, sizeof(bev)) != sizeof(bev))
+			goto out;
+
+		if (header->needs_swap)
+			perf_event_header__bswap(&bev.header);
+
+		len = bev.header.size - sizeof(bev);
+		if (read(input, filename, len) != len)
+			goto out;
+		/*
+		 * The a1645ce1 changeset:
+		 *
+		 * "perf: 'perf kvm' tool for monitoring guest performance from host"
+		 *
+		 * Added a field to struct build_id_event that broke the file
+		 * format.
+		 *
+		 * Since the kernel build-id is the first entry, process the
+		 * table using the old format if the well known
+		 * '[kernel.kallsyms]' string for the kernel build-id has the
+		 * first 4 characters chopped off (where the pid_t sits).
+		 */
+		if (memcmp(filename, "nel.kallsyms]", 13) == 0) {
+			if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1)
+				return -1;
+			return perf_header__read_build_ids_abi_quirk(header, input, offset, size);
+		}
+
+		__event_process_build_id(&bev, filename, session);
+
+		offset += bev.header.size;
+	}
+	err = 0;
+out:
+	return err;
+}
+
+static int process_trace_info(struct perf_file_section *section __unused,
+			      struct perf_header *ph __unused,
+			      int feat __unused, int fd)
+{
+	trace_report(fd, false);
+	return 0;
+}
+
+static int process_build_id(struct perf_file_section *section,
+			    struct perf_header *ph,
+			    int feat __unused, int fd)
+{
+	if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
+		pr_debug("Failed to read buildids, continuing...\n");
+	return 0;
+}
+
 struct feature_ops {
 	int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
 	void (*print)(struct perf_header *h, int fd, FILE *fp);
+	int (*process)(struct perf_file_section *section,
+		       struct perf_header *h, int feat, int fd);
 	const char *name;
 	bool full_only;
 };
 
 #define FEAT_OPA(n, func) \
 	[n] = { .name = #n, .write = write_##func, .print = print_##func }
+#define FEAT_OPP(n, func) \
+	[n] = { .name = #n, .write = write_##func, .print = print_##func, \
+		.process = process_##func }
 #define FEAT_OPF(n, func) \
-	[n] = { .name = #n, .write = write_##func, .print = print_##func, .full_only = true }
+	[n] = { .name = #n, .write = write_##func, .print = print_##func, \
+		.full_only = true }
 
 /* feature_ops not implemented: */
 #define print_trace_info		NULL
 #define print_build_id			NULL
 
 static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
-	FEAT_OPA(HEADER_TRACE_INFO,	trace_info),
-	FEAT_OPA(HEADER_BUILD_ID,	build_id),
+	FEAT_OPP(HEADER_TRACE_INFO,	trace_info),
+	FEAT_OPP(HEADER_BUILD_ID,	build_id),
 	FEAT_OPA(HEADER_HOSTNAME,	hostname),
 	FEAT_OPA(HEADER_OSRELEASE,	osrelease),
 	FEAT_OPA(HEADER_VERSION,	version),
@@ -1336,6 +1607,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
 	FEAT_OPA(HEADER_CMDLINE,	cmdline),
 	FEAT_OPF(HEADER_CPU_TOPOLOGY,	cpu_topology),
 	FEAT_OPF(HEADER_NUMA_TOPOLOGY,	numa_topology),
+	FEAT_OPA(HEADER_PMU_MAPPINGS,	pmu_mappings),
 };
 
 struct header_print_data {
@@ -1689,156 +1961,6 @@ int perf_file_header__read(struct perf_file_header *header,
 	return 0;
 }
 
-static int __event_process_build_id(struct build_id_event *bev,
-				    char *filename,
-				    struct perf_session *session)
-{
-	int err = -1;
-	struct list_head *head;
-	struct machine *machine;
-	u16 misc;
-	struct dso *dso;
-	enum dso_kernel_type dso_type;
-
-	machine = perf_session__findnew_machine(session, bev->pid);
-	if (!machine)
-		goto out;
-
-	misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-
-	switch (misc) {
-	case PERF_RECORD_MISC_KERNEL:
-		dso_type = DSO_TYPE_KERNEL;
-		head = &machine->kernel_dsos;
-		break;
-	case PERF_RECORD_MISC_GUEST_KERNEL:
-		dso_type = DSO_TYPE_GUEST_KERNEL;
-		head = &machine->kernel_dsos;
-		break;
-	case PERF_RECORD_MISC_USER:
-	case PERF_RECORD_MISC_GUEST_USER:
-		dso_type = DSO_TYPE_USER;
-		head = &machine->user_dsos;
-		break;
-	default:
-		goto out;
-	}
-
-	dso = __dsos__findnew(head, filename);
-	if (dso != NULL) {
-		char sbuild_id[BUILD_ID_SIZE * 2 + 1];
-
-		dso__set_build_id(dso, &bev->build_id);
-
-		if (filename[0] == '[')
-			dso->kernel = dso_type;
-
-		build_id__sprintf(dso->build_id, sizeof(dso->build_id),
-				  sbuild_id);
-		pr_debug("build id event received for %s: %s\n",
-			 dso->long_name, sbuild_id);
-	}
-
-	err = 0;
-out:
-	return err;
-}
-
-static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
-						 int input, u64 offset, u64 size)
-{
-	struct perf_session *session = container_of(header, struct perf_session, header);
-	struct {
-		struct perf_event_header   header;
-		u8			   build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
-		char			   filename[0];
-	} old_bev;
-	struct build_id_event bev;
-	char filename[PATH_MAX];
-	u64 limit = offset + size;
-
-	while (offset < limit) {
-		ssize_t len;
-
-		if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev))
-			return -1;
-
-		if (header->needs_swap)
-			perf_event_header__bswap(&old_bev.header);
-
-		len = old_bev.header.size - sizeof(old_bev);
-		if (read(input, filename, len) != len)
-			return -1;
-
-		bev.header = old_bev.header;
-
-		/*
-		 * As the pid is the missing value, we need to fill
-		 * it properly. The header.misc value give us nice hint.
-		 */
-		bev.pid	= HOST_KERNEL_ID;
-		if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER ||
-		    bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL)
-			bev.pid	= DEFAULT_GUEST_KERNEL_ID;
-
-		memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id));
-		__event_process_build_id(&bev, filename, session);
-
-		offset += bev.header.size;
-	}
-
-	return 0;
-}
-
-static int perf_header__read_build_ids(struct perf_header *header,
-				       int input, u64 offset, u64 size)
-{
-	struct perf_session *session = container_of(header, struct perf_session, header);
-	struct build_id_event bev;
-	char filename[PATH_MAX];
-	u64 limit = offset + size, orig_offset = offset;
-	int err = -1;
-
-	while (offset < limit) {
-		ssize_t len;
-
-		if (read(input, &bev, sizeof(bev)) != sizeof(bev))
-			goto out;
-
-		if (header->needs_swap)
-			perf_event_header__bswap(&bev.header);
-
-		len = bev.header.size - sizeof(bev);
-		if (read(input, filename, len) != len)
-			goto out;
-		/*
-		 * The a1645ce1 changeset:
-		 *
-		 * "perf: 'perf kvm' tool for monitoring guest performance from host"
-		 *
-		 * Added a field to struct build_id_event that broke the file
-		 * format.
-		 *
-		 * Since the kernel build-id is the first entry, process the
-		 * table using the old format if the well known
-		 * '[kernel.kallsyms]' string for the kernel build-id has the
-		 * first 4 characters chopped off (where the pid_t sits).
-		 */
-		if (memcmp(filename, "nel.kallsyms]", 13) == 0) {
-			if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1)
-				return -1;
-			return perf_header__read_build_ids_abi_quirk(header, input, offset, size);
-		}
-
-		__event_process_build_id(&bev, filename, session);
-
-		offset += bev.header.size;
-	}
-	err = 0;
-out:
-	return err;
-}
-
 static int perf_file_section__process(struct perf_file_section *section,
 				      struct perf_header *ph,
 				      int feat, int fd, void *data __used)
@@ -1854,19 +1976,10 @@ static int perf_file_section__process(struct perf_file_section *section,
 		return 0;
 	}
 
-	switch (feat) {
-	case HEADER_TRACE_INFO:
-		trace_report(fd, false);
-		break;
-	case HEADER_BUILD_ID:
-		if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
-			pr_debug("Failed to read buildids, continuing...\n");
-		break;
-	default:
-		break;
-	}
+	if (!feat_ops[feat].process)
+		return 0;
 
-	return 0;
+	return feat_ops[feat].process(section, ph, feat, fd);
 }
 
 static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index ac4ec95..9b4d407 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -11,6 +11,7 @@
 
 enum {
 	HEADER_RESERVED		= 0,	/* always cleared */
+	HEADER_FIRST_FEATURE	= 1,
 	HEADER_TRACE_INFO	= 1,
 	HEADER_BUILD_ID,
 
@@ -26,6 +27,7 @@ enum {
 	HEADER_EVENT_DESC,
 	HEADER_CPU_TOPOLOGY,
 	HEADER_NUMA_TOPOLOGY,
+	HEADER_PMU_MAPPINGS,
 
 	HEADER_LAST_FEATURE,
 	HEADER_FEAT_BITS	= 256,
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index f55f0a8d..0d48613 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -55,6 +55,7 @@ struct hists {
 	u64			nr_entries;
 	const struct thread	*thread_filter;
 	const struct dso	*dso_filter;
+	const char		*uid_filter_str;
 	pthread_mutex_t		lock;
 	struct events_stats	stats;
 	u64			event_stream;
diff --git a/tools/perf/util/include/asm/dwarf2.h b/tools/perf/util/include/asm/dwarf2.h
index bb4198e..afe3819 100644
--- a/tools/perf/util/include/asm/dwarf2.h
+++ b/tools/perf/util/include/asm/dwarf2.h
@@ -2,10 +2,12 @@
 #ifndef PERF_DWARF2_H
 #define PERF_DWARF2_H
 
-/* dwarf2.h ... dummy header file for including arch/x86/lib/memcpy_64.S */
+/* dwarf2.h ... dummy header file for including arch/x86/lib/mem{cpy,set}_64.S */
 
 #define CFI_STARTPROC
 #define CFI_ENDPROC
+#define CFI_REMEMBER_STATE
+#define CFI_RESTORE_STATE
 
 #endif	/* PERF_DWARF2_H */
 
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h
index 62cdee7..f1584833 100644
--- a/tools/perf/util/include/linux/bitops.h
+++ b/tools/perf/util/include/linux/bitops.h
@@ -15,7 +15,7 @@
 	     (bit) = find_next_bit((addr), (size), (bit) + 1))
 
 /* same as for_each_set_bit() but use bit as value to start with */
-#define for_each_set_bit_cont(bit, addr, size) \
+#define for_each_set_bit_from(bit, addr, size) \
 	for ((bit) = find_next_bit((addr), (size), (bit));	\
 	     (bit) < (size);					\
 	     (bit) = find_next_bit((addr), (size), (bit) + 1))
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 316aa0a..dea6d1c 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -212,6 +212,21 @@ size_t map__fprintf(struct map *self, FILE *fp)
 		       self->start, self->end, self->pgoff, self->dso->name);
 }
 
+size_t map__fprintf_dsoname(struct map *map, FILE *fp)
+{
+	const char *dsoname;
+
+	if (map && map->dso && (map->dso->name || map->dso->long_name)) {
+		if (symbol_conf.show_kernel_path && map->dso->long_name)
+			dsoname = map->dso->long_name;
+		else if (map->dso->name)
+			dsoname = map->dso->name;
+	} else
+		dsoname = "[unknown]";
+
+	return fprintf(fp, "%s", dsoname);
+}
+
 /*
  * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
  * map->dso->adjust_symbols==1 for ET_EXEC-like cases.
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 2b8017f..b100c20 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -118,6 +118,7 @@ void map__delete(struct map *self);
 struct map *map__clone(struct map *self);
 int map__overlap(struct map *l, struct map *r);
 size_t map__fprintf(struct map *self, FILE *fp);
+size_t map__fprintf_dsoname(struct map *map, FILE *fp);
 
 int map__load(struct map *self, symbol_filter_t filter);
 struct symbol *map__find_symbol(struct map *self,
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index b029296..4944b6d 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -687,7 +687,7 @@ parse_symbolic_event(const char **strp, struct perf_event_attr *attr)
 }
 
 static enum event_result
-parse_raw_event(const char **strp, struct perf_event_attr *attr)
+parse_raw_config(const char **strp, struct perf_event_attr *attr)
 {
 	const char *str = *strp;
 	u64 config;
@@ -702,7 +702,6 @@ parse_raw_event(const char **strp, struct perf_event_attr *attr)
 			return EVT_FAILED;
 
 		*strp = end;
-		attr->type = PERF_TYPE_RAW;
 		attr->config = config;
 		return EVT_HANDLED;
 	}
@@ -710,6 +709,83 @@ parse_raw_event(const char **strp, struct perf_event_attr *attr)
 }
 
 static enum event_result
+parse_raw_event(const char **strp, struct perf_event_attr *attr)
+{
+	if (parse_raw_config(strp, attr) != EVT_HANDLED)
+		return EVT_FAILED;
+
+	attr->type = PERF_TYPE_RAW;
+	return EVT_HANDLED;
+}
+
+#define EVENT_SOURCE_DIR "/sys/bus/event_source/devices"
+
+static u64 read_sysfs_entry(const char *path)
+{
+	char buf[19];
+	int fd;
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	if (read(fd, buf, sizeof(buf)) < 0) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+	return atoll(buf);
+}
+
+static u64 get_pmu_type(const char *pmu_name)
+{
+	char evt_path[MAXPATHLEN];
+
+	snprintf(evt_path, MAXPATHLEN, "%s/%s/type", EVENT_SOURCE_DIR,
+		 pmu_name);
+
+	return read_sysfs_entry(evt_path);
+}
+
+static u64 get_pmu_event_config(const char *pmu_name, const char *evt_name)
+{
+	char evt_path[MAXPATHLEN];
+
+	snprintf(evt_path, MAXPATHLEN, "%s/%s/events/%s", EVENT_SOURCE_DIR,
+		 pmu_name, evt_name);
+
+	return read_sysfs_entry(evt_path);
+}
+
+static enum event_result
+parse_sysfs_event(const char **strp, struct perf_event_attr *attr)
+{
+	char *pmu_name, *evt_name;
+	u64 type, config;
+
+	pmu_name = strchr(*strp, ':');
+	if (!pmu_name)
+		return EVT_FAILED;
+	pmu_name = strndup(*strp, pmu_name - *strp);
+	type = get_pmu_type(pmu_name);
+	if ((int)type < 0)
+		return EVT_FAILED;
+	attr->type = type;
+
+	evt_name = strchr(*strp, ':') + 1;
+	config = get_pmu_event_config(pmu_name, evt_name);
+	*strp += strlen(pmu_name) + 1; /* + 1 for the ':' */
+
+	if ((int)config < 0)
+		return parse_raw_config(strp, attr);
+
+	attr->config = config;
+	*strp += strlen(evt_name);
+	return EVT_HANDLED;
+}
+
+static enum event_result
 parse_numeric_event(const char **strp, struct perf_event_attr *attr)
 {
 	const char *str = *strp;
@@ -800,6 +876,10 @@ parse_event_symbols(struct perf_evlist *evlist, const char **str,
 {
 	enum event_result ret;
 
+	ret = parse_sysfs_event(str, attr);
+	if (ret != EVT_FAILED)
+		goto modifier;
+
 	ret = parse_tracepoint_event(evlist, str, attr);
 	if (ret != EVT_FAILED)
 		goto modifier;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 29cb654..c1183fd 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -45,6 +45,7 @@
 #include "trace-event.h"	/* For __unused */
 #include "probe-event.h"
 #include "probe-finder.h"
+#include "session.h"
 
 #define MAX_CMDLEN 256
 #define MAX_PROBE_ARGS 128
@@ -71,6 +72,8 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
 }
 
 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
+static int convert_name_to_addr(struct perf_probe_event *pev,
+				const char *exec);
 static struct machine machine;
 
 /* Initialize symbol maps and path of vmlinux/modules */
@@ -171,6 +174,31 @@ const char *kernel_get_module_path(const char *module)
 	return (dso) ? dso->long_name : NULL;
 }
 
+static int init_user_exec(void)
+{
+	int ret = 0;
+
+	symbol_conf.try_vmlinux_path = false;
+	symbol_conf.sort_by_name = true;
+	ret = symbol__init();
+	if (ret < 0)
+		pr_debug("Failed to init symbol map.\n");
+
+	return ret;
+}
+
+static int convert_to_perf_probe_point(struct probe_trace_point *tp,
+					struct perf_probe_point *pp)
+{
+	pp->function = strdup(tp->symbol);
+	if (pp->function == NULL)
+		return -ENOMEM;
+	pp->offset = tp->offset;
+	pp->retprobe = tp->retprobe;
+
+	return 0;
+}
+
 #ifdef DWARF_SUPPORT
 /* Open new debuginfo of given module */
 static struct debuginfo *open_debuginfo(const char *module)
@@ -225,10 +253,7 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
 	if (ret <= 0) {
 		pr_debug("Failed to find corresponding probes from "
 			 "debuginfo. Use kprobe event information.\n");
-		pp->function = strdup(tp->symbol);
-		if (pp->function == NULL)
-			return -ENOMEM;
-		pp->offset = tp->offset;
+		return convert_to_perf_probe_point(tp, pp);
 	}
 	pp->retprobe = tp->retprobe;
 
@@ -273,12 +298,22 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
 /* Try to find perf_probe_event with debuginfo */
 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 					  struct probe_trace_event **tevs,
-					  int max_tevs, const char *module)
+					  int max_tevs, const char *target)
 {
 	bool need_dwarf = perf_probe_event_need_dwarf(pev);
-	struct debuginfo *dinfo = open_debuginfo(module);
+	struct debuginfo *dinfo;
 	int ntevs, ret = 0;
 
+	if (pev->uprobes) {
+		if (need_dwarf) {
+			pr_warning("Debuginfo-analysis is not yet supported"
+					" with -x/--exec option.\n");
+			return -ENOSYS;
+		}
+		return convert_name_to_addr(pev, target);
+	}
+
+	dinfo = open_debuginfo(target);
 	if (!dinfo) {
 		if (need_dwarf) {
 			pr_warning("Failed to open debuginfo file.\n");
@@ -295,9 +330,9 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 
 	if (ntevs > 0) {	/* Succeeded to find trace events */
 		pr_debug("find %d probe_trace_events.\n", ntevs);
-		if (module)
+		if (target)
 			ret = add_module_to_probe_trace_events(*tevs, ntevs,
-							       module);
+							       target);
 		return ret < 0 ? ret : ntevs;
 	}
 
@@ -604,23 +639,20 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
 		pr_err("Failed to find symbol %s in kernel.\n", tp->symbol);
 		return -ENOENT;
 	}
-	pp->function = strdup(tp->symbol);
-	if (pp->function == NULL)
-		return -ENOMEM;
-	pp->offset = tp->offset;
-	pp->retprobe = tp->retprobe;
-
-	return 0;
+	return convert_to_perf_probe_point(tp, pp);
 }
 
 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 				struct probe_trace_event **tevs __unused,
-				int max_tevs __unused, const char *mod __unused)
+				int max_tevs __unused, const char *target)
 {
 	if (perf_probe_event_need_dwarf(pev)) {
 		pr_warning("Debuginfo-analysis is not supported.\n");
 		return -ENOSYS;
 	}
+	if (pev->uprobes)
+		return convert_name_to_addr(pev, target);
+
 	return 0;
 }
 
@@ -885,6 +917,11 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 		return -EINVAL;
 	}
 
+	if (pev->uprobes && !pp->function) {
+		semantic_error("No function specified for uprobes");
+		return -EINVAL;
+	}
+
 	if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
 		semantic_error("Offset/Line/Lazy pattern can't be used with "
 			       "return probe.\n");
@@ -894,6 +931,11 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
 		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
 		 pp->lazy_line);
+
+	if (pev->uprobes && perf_probe_event_need_dwarf(pev)) {
+		semantic_error("no dwarf based probes for uprobes.");
+		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -1342,11 +1384,18 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
 	if (buf == NULL)
 		return NULL;
 
-	len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
-			 tp->retprobe ? 'r' : 'p',
-			 tev->group, tev->event,
-			 tp->module ?: "", tp->module ? ":" : "",
-			 tp->symbol, tp->offset);
+	if (tev->uprobes)
+		len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s:%s",
+				 tp->retprobe ? 'r' : 'p',
+				 tev->group, tev->event,
+				 tp->module, tp->symbol);
+	else
+		len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
+				 tp->retprobe ? 'r' : 'p',
+				 tev->group, tev->event,
+				 tp->module ?: "", tp->module ? ":" : "",
+				 tp->symbol, tp->offset);
+
 	if (len <= 0)
 		goto error;
 
@@ -1365,7 +1414,7 @@ error:
 }
 
 static int convert_to_perf_probe_event(struct probe_trace_event *tev,
-				       struct perf_probe_event *pev)
+			       struct perf_probe_event *pev, bool is_kprobe)
 {
 	char buf[64] = "";
 	int i, ret;
@@ -1377,7 +1426,11 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev,
 		return -ENOMEM;
 
 	/* Convert trace_point to probe_point */
-	ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
+	if (is_kprobe)
+		ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
+	else
+		ret = convert_to_perf_probe_point(&tev->point, &pev->point);
+
 	if (ret < 0)
 		return ret;
 
@@ -1473,7 +1526,26 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
 	memset(tev, 0, sizeof(*tev));
 }
 
-static int open_kprobe_events(bool readwrite)
+static void print_warn_msg(const char *file, bool is_kprobe)
+{
+
+	if (errno == ENOENT) {
+		const char *config;
+
+		if (!is_kprobe)
+			config = "CONFIG_UPROBE_EVENTS";
+		else
+			config = "CONFIG_KPROBE_EVENTS";
+
+		pr_warning("%s file does not exist - please rebuild kernel"
+				" with %s.\n", file, config);
+	} else
+		pr_warning("Failed to open %s file: %s\n", file,
+				strerror(errno));
+}
+
+static int open_probe_events(const char *trace_file, bool readwrite,
+				bool is_kprobe)
 {
 	char buf[PATH_MAX];
 	const char *__debugfs;
@@ -1485,27 +1557,30 @@ static int open_kprobe_events(bool readwrite)
 		return -ENOENT;
 	}
 
-	ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
+	ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file);
 	if (ret >= 0) {
 		pr_debug("Opening %s write=%d\n", buf, readwrite);
 		if (readwrite && !probe_event_dry_run)
 			ret = open(buf, O_RDWR, O_APPEND);
 		else
 			ret = open(buf, O_RDONLY, 0);
-	}
-
-	if (ret < 0) {
-		if (errno == ENOENT)
-			pr_warning("kprobe_events file does not exist - please"
-				 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
-		else
-			pr_warning("Failed to open kprobe_events file: %s\n",
-				   strerror(errno));
+			if (ret < 0)
+				print_warn_msg(buf, is_kprobe);
 	}
 	return ret;
 }
 
-/* Get raw string list of current kprobe_events */
+static int open_kprobe_events(bool readwrite)
+{
+	return open_probe_events("tracing/kprobe_events", readwrite, true);
+}
+
+static int open_uprobe_events(bool readwrite)
+{
+	return open_probe_events("tracing/uprobe_events", readwrite, false);
+}
+
+/* Get raw string list of current kprobe_events  or uprobe_events */
 static struct strlist *get_probe_trace_command_rawlist(int fd)
 {
 	int ret, idx;
@@ -1570,36 +1645,26 @@ static int show_perf_probe_event(struct perf_probe_event *pev)
 	return ret;
 }
 
-/* List up current perf-probe events */
-int show_perf_probe_events(void)
+static int __show_perf_probe_events(int fd, bool is_kprobe)
 {
-	int fd, ret;
+	int ret = 0;
 	struct probe_trace_event tev;
 	struct perf_probe_event pev;
 	struct strlist *rawlist;
 	struct str_node *ent;
 
-	setup_pager();
-	ret = init_vmlinux();
-	if (ret < 0)
-		return ret;
-
 	memset(&tev, 0, sizeof(tev));
 	memset(&pev, 0, sizeof(pev));
 
-	fd = open_kprobe_events(false);
-	if (fd < 0)
-		return fd;
-
 	rawlist = get_probe_trace_command_rawlist(fd);
-	close(fd);
 	if (!rawlist)
 		return -ENOENT;
 
 	strlist__for_each(ent, rawlist) {
 		ret = parse_probe_trace_command(ent->s, &tev);
 		if (ret >= 0) {
-			ret = convert_to_perf_probe_event(&tev, &pev);
+			ret = convert_to_perf_probe_event(&tev, &pev,
+								is_kprobe);
 			if (ret >= 0)
 				ret = show_perf_probe_event(&pev);
 		}
@@ -1609,6 +1674,31 @@ int show_perf_probe_events(void)
 			break;
 	}
 	strlist__delete(rawlist);
+	return ret;
+}
+
+/* List up current perf-probe events */
+int show_perf_probe_events(void)
+{
+	int fd, ret;
+
+	setup_pager();
+	fd = open_kprobe_events(false);
+	if (fd < 0)
+		return fd;
+
+	ret = init_vmlinux();
+	if (ret < 0)
+		return ret;
+
+	ret = __show_perf_probe_events(fd, true);
+	close(fd);
+
+	fd = open_uprobe_events(false);
+	if (fd >= 0) {
+		ret = __show_perf_probe_events(fd, false);
+		close(fd);
+	}
 
 	return ret;
 }
@@ -1718,7 +1808,10 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	const char *event, *group;
 	struct strlist *namelist;
 
-	fd = open_kprobe_events(true);
+	if (pev->uprobes)
+		fd = open_uprobe_events(true);
+	else
+		fd = open_kprobe_events(true);
 	if (fd < 0)
 		return fd;
 	/* Get current event names */
@@ -1729,7 +1822,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	}
 
 	ret = 0;
-	printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
+	printf("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
 	for (i = 0; i < ntevs; i++) {
 		tev = &tevs[i];
 		if (pev->event)
@@ -1784,7 +1877,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 
 	if (ret >= 0) {
 		/* Show how to use the event. */
-		printf("\nYou can now use it on all perf tools, such as:\n\n");
+		printf("\nYou can now use it in all perf tools, such as:\n\n");
 		printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
 			 tev->event);
 	}
@@ -1796,14 +1889,14 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 					  struct probe_trace_event **tevs,
-					  int max_tevs, const char *module)
+					  int max_tevs, const char *target)
 {
 	struct symbol *sym;
 	int ret = 0, i;
 	struct probe_trace_event *tev;
 
 	/* Convert perf_probe_event with debuginfo */
-	ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module);
+	ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target);
 	if (ret != 0)
 		return ret;	/* Found in debuginfo or got an error */
 
@@ -1819,8 +1912,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 		goto error;
 	}
 
-	if (module) {
-		tev->point.module = strdup(module);
+	if (target) {
+		tev->point.module = strdup(target);
 		if (tev->point.module == NULL) {
 			ret = -ENOMEM;
 			goto error;
@@ -1830,6 +1923,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 	tev->point.offset = pev->point.offset;
 	tev->point.retprobe = pev->point.retprobe;
 	tev->nargs = pev->nargs;
+	tev->uprobes = pev->uprobes;
 	if (tev->nargs) {
 		tev->args = zalloc(sizeof(struct probe_trace_arg)
 				   * tev->nargs);
@@ -1860,6 +1954,9 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 		}
 	}
 
+	if (pev->uprobes)
+		return 1;
+
 	/* Currently just checking function name from symbol map */
 	sym = __find_kernel_function_by_name(tev->point.symbol, NULL);
 	if (!sym) {
@@ -1884,17 +1981,21 @@ struct __event_package {
 };
 
 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
-			  int max_tevs, const char *module, bool force_add)
+			  int max_tevs, const char *target, bool force_add)
 {
-	int i, j, ret;
+	int i, j, ret = 0;
 	struct __event_package *pkgs;
 
 	pkgs = zalloc(sizeof(struct __event_package) * npevs);
 	if (pkgs == NULL)
 		return -ENOMEM;
 
-	/* Init vmlinux path */
-	ret = init_vmlinux();
+	if (!pevs->uprobes)
+		/* Init vmlinux path */
+		ret = init_vmlinux();
+	else
+		ret = init_user_exec();
+
 	if (ret < 0) {
 		free(pkgs);
 		return ret;
@@ -1907,7 +2008,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
 		ret  = convert_to_probe_trace_events(pkgs[i].pev,
 						     &pkgs[i].tevs,
 						     max_tevs,
-						     module);
+						     target);
 		if (ret < 0)
 			goto end;
 		pkgs[i].ntevs = ret;
@@ -1959,30 +2060,22 @@ static int __del_trace_probe_event(int fd, struct str_node *ent)
 		goto error;
 	}
 
-	printf("Remove event: %s\n", ent->s);
+	printf("Removed event: %s\n", ent->s);
 	return 0;
 error:
 	pr_warning("Failed to delete event: %s\n", strerror(-ret));
 	return ret;
 }
 
-static int del_trace_probe_event(int fd, const char *group,
-				  const char *event, struct strlist *namelist)
+static int del_trace_probe_event(int fd, const char *buf,
+						  struct strlist *namelist)
 {
-	char buf[128];
 	struct str_node *ent, *n;
-	int found = 0, ret = 0;
-
-	ret = e_snprintf(buf, 128, "%s:%s", group, event);
-	if (ret < 0) {
-		pr_err("Failed to copy event.\n");
-		return ret;
-	}
+	int ret = -1;
 
 	if (strpbrk(buf, "*?")) { /* Glob-exp */
 		strlist__for_each_safe(ent, n, namelist)
 			if (strglobmatch(ent->s, buf)) {
-				found++;
 				ret = __del_trace_probe_event(fd, ent);
 				if (ret < 0)
 					break;
@@ -1991,40 +2084,41 @@ static int del_trace_probe_event(int fd, const char *group,
 	} else {
 		ent = strlist__find(namelist, buf);
 		if (ent) {
-			found++;
 			ret = __del_trace_probe_event(fd, ent);
 			if (ret >= 0)
 				strlist__remove(namelist, ent);
 		}
 	}
-	if (found == 0 && ret >= 0)
-		pr_info("Info: Event \"%s\" does not exist.\n", buf);
-
 	return ret;
 }
 
 int del_perf_probe_events(struct strlist *dellist)
 {
-	int fd, ret = 0;
+	int ret = -1, ufd = -1, kfd = -1;
+	char buf[128];
 	const char *group, *event;
 	char *p, *str;
 	struct str_node *ent;
-	struct strlist *namelist;
-
-	fd = open_kprobe_events(true);
-	if (fd < 0)
-		return fd;
+	struct strlist *namelist = NULL, *unamelist = NULL;
 
 	/* Get current event names */
-	namelist = get_probe_trace_event_names(fd, true);
-	if (namelist == NULL)
-		return -EINVAL;
+	kfd = open_kprobe_events(true);
+	if (kfd < 0)
+		return kfd;
+	namelist = get_probe_trace_event_names(kfd, true);
+
+	ufd = open_uprobe_events(true);
+	if (ufd >= 0)
+		unamelist = get_probe_trace_event_names(ufd, true);
+
+	if (namelist == NULL && unamelist == NULL)
+		goto error;
 
 	strlist__for_each(ent, dellist) {
 		str = strdup(ent->s);
 		if (str == NULL) {
 			ret = -ENOMEM;
-			break;
+			goto error;
 		}
 		pr_debug("Parsing: %s\n", str);
 		p = strchr(str, ':');
@@ -2036,17 +2130,40 @@ int del_perf_probe_events(struct strlist *dellist)
 			group = "*";
 			event = str;
 		}
+
+		ret = e_snprintf(buf, 128, "%s:%s", group, event);
+		if (ret < 0) {
+			pr_err("Failed to copy event.");
+			free(str);
+			goto error;
+		}
+
 		pr_debug("Group: %s, Event: %s\n", group, event);
-		ret = del_trace_probe_event(fd, group, event, namelist);
+		if (namelist)
+			ret = del_trace_probe_event(kfd, buf, namelist);
+		if (unamelist && ret != 0)
+			ret = del_trace_probe_event(ufd, buf, unamelist);
+
 		free(str);
-		if (ret < 0)
-			break;
+		if (ret != 0)
+			pr_info("Info: Event \"%s\" does not exist.\n", buf);
+	}
+
+error:
+	if (kfd >= 0) {
+		if (namelist)
+			strlist__delete(namelist);
+		close(kfd);
 	}
-	strlist__delete(namelist);
-	close(fd);
 
+	if (ufd >= 0) {
+		if (unamelist)
+			strlist__delete(unamelist);
+		close(ufd);
+	}
 	return ret;
 }
+
 /* TODO: don't use a global variable for filter ... */
 static struct strfilter *available_func_filter;
 
@@ -2063,13 +2180,24 @@ static int filter_available_functions(struct map *map __unused,
 	return 1;
 }
 
-int show_available_funcs(const char *module, struct strfilter *_filter)
+static int __show_available_funcs(struct map *map)
+{
+	if (map__load(map, filter_available_functions)) {
+		pr_err("Failed to load map.\n");
+		return -EINVAL;
+	}
+	if (!dso__sorted_by_name(map->dso, map->type))
+		dso__sort_by_name(map->dso, map->type);
+
+	dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
+	return 0;
+}
+
+static int available_kernel_funcs(const char *module)
 {
 	struct map *map;
 	int ret;
 
-	setup_pager();
-
 	ret = init_vmlinux();
 	if (ret < 0)
 		return ret;
@@ -2079,14 +2207,123 @@ int show_available_funcs(const char *module, struct strfilter *_filter)
 		pr_err("Failed to find %s map.\n", (module) ? : "kernel");
 		return -EINVAL;
 	}
+	return __show_available_funcs(map);
+}
+
+static int available_user_funcs(const char *target)
+{
+	struct map *map;
+	int ret;
+
+	ret = init_user_exec();
+	if (ret < 0)
+		return ret;
+
+	map = dso__new_map(target);
+	ret = __show_available_funcs(map);
+	dso__delete(map->dso);
+	map__delete(map);
+	return ret;
+}
+
+int show_available_funcs(const char *target, struct strfilter *_filter,
+					bool user)
+{
+	setup_pager();
 	available_func_filter = _filter;
+
+	if (!user)
+		return available_kernel_funcs(target);
+
+	return available_user_funcs(target);
+}
+
+/*
+ * uprobe_events only accepts address:
+ * Convert function and any offset to address
+ */
+static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
+{
+	struct perf_probe_point *pp = &pev->point;
+	struct symbol *sym;
+	struct map *map = NULL;
+	char *function = NULL, *name = NULL;
+	int ret = -EINVAL;
+	unsigned long long vaddr = 0;
+
+	if (!pp->function)
+		goto out;
+
+	function = strdup(pp->function);
+	if (!function) {
+		pr_warning("Failed to allocate memory by strdup.\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	name = realpath(exec, NULL);
+	if (!name) {
+		pr_warning("Cannot find realpath for %s.\n", exec);
+		goto out;
+	}
+	map = dso__new_map(name);
+	if (!map) {
+		pr_warning("Cannot find appropriate DSO for %s.\n", exec);
+		goto out;
+	}
+	available_func_filter = strfilter__new(function, NULL);
 	if (map__load(map, filter_available_functions)) {
 		pr_err("Failed to load map.\n");
 		return -EINVAL;
 	}
-	if (!dso__sorted_by_name(map->dso, map->type))
-		dso__sort_by_name(map->dso, map->type);
 
-	dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
-	return 0;
+	sym = map__find_symbol_by_name(map, function, NULL);
+	if (!sym) {
+		pr_warning("Cannot find %s in DSO %s\n", function, exec);
+		goto out;
+	}
+
+	if (map->start > sym->start)
+		vaddr = map->start;
+	vaddr += sym->start + pp->offset + map->pgoff;
+	pp->offset = 0;
+
+	if (!pev->event) {
+		pev->event = function;
+		function = NULL;
+	}
+	if (!pev->group) {
+		char *ptr1, *ptr2;
+
+		pev->group = zalloc(sizeof(char *) * 64);
+		ptr1 = strdup(basename(exec));
+		if (ptr1) {
+			ptr2 = strpbrk(ptr1, "-._");
+			if (ptr2)
+				*ptr2 = '\0';
+			e_snprintf(pev->group, 64, "%s_%s", PERFPROBE_GROUP,
+					ptr1);
+			free(ptr1);
+		}
+	}
+	free(pp->function);
+	pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS);
+	if (!pp->function) {
+		ret = -ENOMEM;
+		pr_warning("Failed to allocate memory by zalloc.\n");
+		goto out;
+	}
+	e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr);
+	ret = 0;
+
+out:
+	if (map) {
+		dso__delete(map->dso);
+		map__delete(map);
+	}
+	if (function)
+		free(function);
+	if (name)
+		free(name);
+	return ret;
 }
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index a7dee83..f9f3de8 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -7,7 +7,7 @@
 
 extern bool probe_event_dry_run;
 
-/* kprobe-tracer tracing point */
+/* kprobe-tracer and uprobe-tracer tracing point */
 struct probe_trace_point {
 	char		*symbol;	/* Base symbol */
 	char		*module;	/* Module name */
@@ -21,7 +21,7 @@ struct probe_trace_arg_ref {
 	long				offset;	/* Offset value */
 };
 
-/* kprobe-tracer tracing argument */
+/* kprobe-tracer and uprobe-tracer tracing argument */
 struct probe_trace_arg {
 	char				*name;	/* Argument name */
 	char				*value;	/* Base value */
@@ -29,12 +29,13 @@ struct probe_trace_arg {
 	struct probe_trace_arg_ref	*ref;	/* Referencing offset */
 };
 
-/* kprobe-tracer tracing event (point + arg) */
+/* kprobe-tracer and uprobe-tracer tracing event (point + arg) */
 struct probe_trace_event {
 	char				*event;	/* Event name */
 	char				*group;	/* Group name */
 	struct probe_trace_point	point;	/* Trace point */
 	int				nargs;	/* Number of args */
+	bool				uprobes;	/* uprobes only */
 	struct probe_trace_arg		*args;	/* Arguments */
 };
 
@@ -70,6 +71,7 @@ struct perf_probe_event {
 	char			*group;	/* Group name */
 	struct perf_probe_point	point;	/* Probe point */
 	int			nargs;	/* Number of arguments */
+	bool			uprobes;
 	struct perf_probe_arg	*args;	/* Arguments */
 };
 
@@ -129,8 +131,8 @@ extern int show_line_range(struct line_range *lr, const char *module);
 extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
 			       int max_probe_points, const char *module,
 			       struct strfilter *filter, bool externs);
-extern int show_available_funcs(const char *module, struct strfilter *filter);
-
+extern int show_available_funcs(const char *module, struct strfilter *filter,
+				bool user);
 
 /* Maximum index number of event-name postfix */
 #define MAX_EVENT_INDEX	1024
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 5d73262..67dc4ae 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -30,7 +30,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include <ctype.h>
 #include <dwarf-regs.h>
 
 #include <linux/bitops.h>
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 9dd47a4..e03b58a 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -425,14 +425,14 @@ struct pyrf_thread_map {
 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
 				 PyObject *args, PyObject *kwargs)
 {
-	static char *kwlist[] = { "pid", "tid", NULL };
-	int pid = -1, tid = -1;
+	static char *kwlist[] = { "pid", "tid", "uid", NULL };
+	int pid = -1, tid = -1, uid = UINT_MAX;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
-					 kwlist, &pid, &tid))
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
+					 kwlist, &pid, &tid, &uid))
 		return -1;
 
-	pthreads->threads = thread_map__new(pid, tid);
+	pthreads->threads = thread_map__new(pid, tid, uid);
 	if (pthreads->threads == NULL)
 		return -1;
 	return 0;
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 0b2a487..c2623c6 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <errno.h>
 
 #include "../../perf.h"
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b5ca255..552c1c5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1293,10 +1293,9 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 
 void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
 			  struct machine *machine, struct perf_evsel *evsel,
-			  int print_sym, int print_dso)
+			  int print_sym, int print_dso, int print_symoffset)
 {
 	struct addr_location al;
-	const char *symname, *dsoname;
 	struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
 	struct callchain_cursor_node *node;
 
@@ -1324,20 +1323,13 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
 
 			printf("\t%16" PRIx64, node->ip);
 			if (print_sym) {
-				if (node->sym && node->sym->name)
-					symname = node->sym->name;
-				else
-					symname = "";
-
-				printf(" %s", symname);
+				printf(" ");
+				symbol__fprintf_symname(node->sym, stdout);
 			}
 			if (print_dso) {
-				if (node->map && node->map->dso && node->map->dso->name)
-					dsoname = node->map->dso->name;
-				else
-					dsoname = "";
-
-				printf(" (%s)", dsoname);
+				printf(" (");
+				map__fprintf_dsoname(al.map, stdout);
+				printf(")");
 			}
 			printf("\n");
 
@@ -1347,21 +1339,18 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
 	} else {
 		printf("%16" PRIx64, sample->ip);
 		if (print_sym) {
-			if (al.sym && al.sym->name)
-				symname = al.sym->name;
+			printf(" ");
+			if (print_symoffset)
+				symbol__fprintf_symname_offs(al.sym, &al,
+							     stdout);
 			else
-				symname = "";
-
-			printf(" %s", symname);
+				symbol__fprintf_symname(al.sym, stdout);
 		}
 
 		if (print_dso) {
-			if (al.map && al.map->dso && al.map->dso->name)
-				dsoname = al.map->dso->name;
-			else
-				dsoname = "";
-
-			printf(" (%s)", dsoname);
+			printf(" (");
+			map__fprintf_dsoname(al.map, stdout);
+			printf(")");
 		}
 	}
 }
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 37bc383..c8d9017 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -147,7 +147,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 
 void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
 			  struct machine *machine, struct perf_evsel *evsel,
-			  int print_sym, int print_dso);
+			  int print_sym, int print_dso, int print_symoffset);
 
 int perf_session__cpu_bitmap(struct perf_session *session,
 			     const char *cpu_list, unsigned long *cpu_bitmap);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 0975438..d519ce6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -263,6 +263,28 @@ static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
 		       sym->name);
 }
 
+size_t symbol__fprintf_symname_offs(const struct symbol *sym,
+				    const struct addr_location *al, FILE *fp)
+{
+	unsigned long offset;
+	size_t length;
+
+	if (sym && sym->name) {
+		length = fprintf(fp, "%s", sym->name);
+		if (al) {
+			offset = al->addr - sym->start;
+			length += fprintf(fp, "+0x%lx", offset);
+		}
+		return length;
+	} else
+		return fprintf(fp, "[unknown]");
+}
+
+size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
+{
+	return symbol__fprintf_symname_offs(sym, NULL, fp);
+}
+
 void dso__set_long_name(struct dso *dso, char *name)
 {
 	if (name == NULL)
@@ -2761,3 +2783,11 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
 
 	return ret;
 }
+
+struct map *dso__new_map(const char *name)
+{
+	struct dso *dso = dso__new(name);
+	struct map *map = map__new2(0, dso, MAP__FUNCTION);
+
+	return map;
+}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 123c2e1..b62bc22 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -70,6 +70,7 @@ struct symbol_conf {
 	unsigned short	priv_size;
 	unsigned short	nr_events;
 	bool		try_vmlinux_path,
+			show_kernel_path,
 			use_modules,
 			sort_by_name,
 			show_nr_samples,
@@ -218,6 +219,7 @@ void dso__set_long_name(struct dso *dso, char *name);
 void dso__set_build_id(struct dso *dso, void *build_id);
 void dso__read_running_kernel_build_id(struct dso *dso,
 				       struct machine *machine);
+struct map *dso__new_map(const char *name);
 struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
 				u64 addr);
 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
@@ -241,6 +243,9 @@ void machines__destroy_guest_kernel_maps(struct rb_root *machines);
 
 int symbol__init(void);
 void symbol__exit(void);
+size_t symbol__fprintf_symname_offs(const struct symbol *sym,
+				    const struct addr_location *al, FILE *fp);
+size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
 
 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index a5df131..3d4b6c5 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -1,6 +1,11 @@
 #include <dirent.h>
+#include <limits.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include "thread_map.h"
 
 /* Skip "." and ".." directories */
@@ -23,7 +28,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
 	sprintf(name, "/proc/%d/task", pid);
 	items = scandir(name, &namelist, filter, NULL);
 	if (items <= 0)
-                return NULL;
+		return NULL;
 
 	threads = malloc(sizeof(*threads) + sizeof(pid_t) * items);
 	if (threads != NULL) {
@@ -51,10 +56,99 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
 	return threads;
 }
 
-struct thread_map *thread_map__new(pid_t pid, pid_t tid)
+struct thread_map *thread_map__new_by_uid(uid_t uid)
+{
+	DIR *proc;
+	int max_threads = 32, items, i;
+	char path[256];
+	struct dirent dirent, *next, **namelist = NULL;
+	struct thread_map *threads = malloc(sizeof(*threads) +
+					    max_threads * sizeof(pid_t));
+	if (threads == NULL)
+		goto out;
+
+	proc = opendir("/proc");
+	if (proc == NULL)
+		goto out_free_threads;
+
+	threads->nr = 0;
+
+	while (!readdir_r(proc, &dirent, &next) && next) {
+		char *end;
+		bool grow = false;
+		struct stat st;
+		pid_t pid = strtol(dirent.d_name, &end, 10);
+
+		if (*end) /* only interested in proper numerical dirents */
+			continue;
+
+		snprintf(path, sizeof(path), "/proc/%s", dirent.d_name);
+
+		if (stat(path, &st) != 0)
+			continue;
+
+		if (st.st_uid != uid)
+			continue;
+
+		snprintf(path, sizeof(path), "/proc/%d/task", pid);
+		items = scandir(path, &namelist, filter, NULL);
+		if (items <= 0)
+			goto out_free_closedir;
+
+		while (threads->nr + items >= max_threads) {
+			max_threads *= 2;
+			grow = true;
+		}
+
+		if (grow) {
+			struct thread_map *tmp;
+
+			tmp = realloc(threads, (sizeof(*threads) +
+						max_threads * sizeof(pid_t)));
+			if (tmp == NULL)
+				goto out_free_namelist;
+
+			threads = tmp;
+		}
+
+		for (i = 0; i < items; i++)
+			threads->map[threads->nr + i] = atoi(namelist[i]->d_name);
+
+		for (i = 0; i < items; i++)
+			free(namelist[i]);
+		free(namelist);
+
+		threads->nr += items;
+	}
+
+out_closedir:
+	closedir(proc);
+out:
+	return threads;
+
+out_free_threads:
+	free(threads);
+	return NULL;
+
+out_free_namelist:
+	for (i = 0; i < items; i++)
+		free(namelist[i]);
+	free(namelist);
+
+out_free_closedir:
+	free(threads);
+	threads = NULL;
+	goto out_closedir;
+}
+
+struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid)
 {
 	if (pid != -1)
 		return thread_map__new_by_pid(pid);
+
+	if (tid == -1 && uid != UINT_MAX)
+		return thread_map__new_by_uid(uid);
+
 	return thread_map__new_by_tid(tid);
 }
 
@@ -62,3 +156,14 @@ void thread_map__delete(struct thread_map *threads)
 {
 	free(threads);
 }
+
+size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
+{
+	int i;
+	size_t printed = fprintf(fp, "%d thread%s: ",
+				 threads->nr, threads->nr > 1 ? "s" : "");
+	for (i = 0; i < threads->nr; ++i)
+		printed += fprintf(fp, "%s%d", i ? ", " : "", threads->map[i]);
+
+	return printed + fprintf(fp, "\n");
+}
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index 3cb9073..c75ddba 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -2,6 +2,7 @@
 #define __PERF_THREAD_MAP_H
 
 #include <sys/types.h>
+#include <stdio.h>
 
 struct thread_map {
 	int nr;
@@ -10,6 +11,10 @@ struct thread_map {
 
 struct thread_map *thread_map__new_by_pid(pid_t pid);
 struct thread_map *thread_map__new_by_tid(pid_t tid);
-struct thread_map *thread_map__new(pid_t pid, pid_t tid);
+struct thread_map *thread_map__new_by_uid(uid_t uid);
+struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
 void thread_map__delete(struct thread_map *threads);
+
+size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
+
 #endif	/* __PERF_THREAD_MAP_H */
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index 500471d..e4370ca 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -75,6 +75,9 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
 	else if (top->target_tid != -1)
 		ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %d",
 				top->target_tid);
+	else if (top->uid_str != NULL)
+		ret += SNPRINTF(bf + ret, size - ret, " (uid: %s",
+				top->uid_str);
 	else
 		ret += SNPRINTF(bf + ret, size - ret, " (all");
 
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index a248f3c..def3e53 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -24,6 +24,7 @@ struct perf_top {
 	int		   print_entries, count_filter, delay_secs;
 	int		   freq;
 	pid_t		   target_pid, target_tid;
+	uid_t		   uid;
 	bool		   hide_kernel_symbols, hide_user_symbols, zero;
 	bool		   system_wide;
 	bool		   use_tui, use_stdio;
@@ -45,6 +46,7 @@ struct perf_top {
 	int		   realtime_prio;
 	int		   sym_pcnt_filter;
 	const char	   *sym_filter;
+	const char	   *uid_str;
 };
 
 size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 1a8d4dc..e0a4f65 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -25,7 +25,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <errno.h>
 
 #include "../perf.h"
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index f55cc3a..b9592e0 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -33,7 +33,6 @@
 #include <pthread.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <ctype.h>
 #include <errno.h>
 
 #include "../perf.h"
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index a3fdf55..18ae6c1 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -22,7 +22,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
 #include <errno.h>
 
 #include "../perf.h"
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c
index e81aef1..bfba049 100644
--- a/tools/perf/util/ui/browsers/hists.c
+++ b/tools/perf/util/ui/browsers/hists.c
@@ -839,6 +839,9 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size,
 	nr_events = convert_unit(nr_events, &unit);
 	printed = snprintf(bf, size, "Events: %lu%c %s", nr_events, unit, ev_name);
 
+	if (self->uid_filter_str)
+		printed += snprintf(bf + printed, size - printed,
+				    ", UID: %s", self->uid_filter_str);
 	if (thread)
 		printed += snprintf(bf + printed, size - printed,
 				    ", Thread: %s(%d)",
diff --git a/tools/perf/util/ui/browsers/map.c b/tools/perf/util/ui/browsers/map.c
index 6905bcc..eca6575 100644
--- a/tools/perf/util/ui/browsers/map.c
+++ b/tools/perf/util/ui/browsers/map.c
@@ -3,9 +3,9 @@
 #include <newt.h>
 #include <inttypes.h>
 #include <sys/ttydefaults.h>
-#include <ctype.h>
 #include <string.h>
 #include <linux/bitops.h>
+#include "../../util.h"
 #include "../../debug.h"
 #include "../../symbol.h"
 #include "../browser.h"
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c
index d76d1c0..d0c0139 100644
--- a/tools/perf/util/usage.c
+++ b/tools/perf/util/usage.c
@@ -7,6 +7,7 @@
  * Copyright (C) Linus Torvalds, 2005
  */
 #include "util.h"
+#include "debug.h"
 
 static void report(const char *prefix, const char *err, va_list params)
 {
@@ -81,3 +82,41 @@ void warning(const char *warn, ...)
 	warn_routine(warn, params);
 	va_end(params);
 }
+
+uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid)
+{
+	struct passwd pwd, *result;
+	char buf[1024];
+
+	if (str == NULL)
+		return UINT_MAX;
+
+	/* CPU and PID are mutually exclusive */
+	if (tid > 0 || pid > 0) {
+		ui__warning("PID/TID switch overriding UID\n");
+		sleep(1);
+		return UINT_MAX;
+	}
+
+	getpwnam_r(str, &pwd, buf, sizeof(buf), &result);
+
+	if (result == NULL) {
+		char *endptr;
+		int uid = strtol(str, &endptr, 10);
+
+		if (*endptr != '\0') {
+			ui__error("Invalid user %s\n", str);
+			return UINT_MAX - 1;
+		}
+
+		getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
+
+		if (result == NULL) {
+			ui__error("Problems obtaining information for user %s\n",
+				  str);
+			return UINT_MAX - 1;
+		}
+	}
+
+	return result->pw_uid;
+}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index ecf9898..232d17e 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -245,6 +245,8 @@ struct perf_event_attr;
 
 void event_attr_init(struct perf_event_attr *attr);
 
+uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid);
+
 #define _STR(x) #x
 #define STR(x) _STR(x)
 
diff --git a/tools/slub/slabinfo.c b/tools/slub/slabinfo.c
deleted file mode 100644
index 164cbcf..0000000
--- a/tools/slub/slabinfo.c
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*
- * Slabinfo: Tool to get reports about slabs
- *
- * (C) 2007 sgi, Christoph Lameter
- * (C) 2011 Linux Foundation, Christoph Lameter
- *
- * Compile with:
- *
- * gcc -o slabinfo slabinfo.c
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <strings.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <getopt.h>
-#include <regex.h>
-#include <errno.h>
-
-#define MAX_SLABS 500
-#define MAX_ALIASES 500
-#define MAX_NODES 1024
-
-struct slabinfo {
-	char *name;
-	int alias;
-	int refs;
-	int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
-	int hwcache_align, object_size, objs_per_slab;
-	int sanity_checks, slab_size, store_user, trace;
-	int order, poison, reclaim_account, red_zone;
-	unsigned long partial, objects, slabs, objects_partial, objects_total;
-	unsigned long alloc_fastpath, alloc_slowpath;
-	unsigned long free_fastpath, free_slowpath;
-	unsigned long free_frozen, free_add_partial, free_remove_partial;
-	unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
-	unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
-	unsigned long deactivate_to_head, deactivate_to_tail;
-	unsigned long deactivate_remote_frees, order_fallback;
-	unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail;
-	unsigned long alloc_node_mismatch, deactivate_bypass;
-	unsigned long cpu_partial_alloc, cpu_partial_free;
-	int numa[MAX_NODES];
-	int numa_partial[MAX_NODES];
-} slabinfo[MAX_SLABS];
-
-struct aliasinfo {
-	char *name;
-	char *ref;
-	struct slabinfo *slab;
-} aliasinfo[MAX_ALIASES];
-
-int slabs = 0;
-int actual_slabs = 0;
-int aliases = 0;
-int alias_targets = 0;
-int highest_node = 0;
-
-char buffer[4096];
-
-int show_empty = 0;
-int show_report = 0;
-int show_alias = 0;
-int show_slab = 0;
-int skip_zero = 1;
-int show_numa = 0;
-int show_track = 0;
-int show_first_alias = 0;
-int validate = 0;
-int shrink = 0;
-int show_inverted = 0;
-int show_single_ref = 0;
-int show_totals = 0;
-int sort_size = 0;
-int sort_active = 0;
-int set_debug = 0;
-int show_ops = 0;
-int show_activity = 0;
-
-/* Debug options */
-int sanity = 0;
-int redzone = 0;
-int poison = 0;
-int tracking = 0;
-int tracing = 0;
-
-int page_size;
-
-regex_t pattern;
-
-static void fatal(const char *x, ...)
-{
-	va_list ap;
-
-	va_start(ap, x);
-	vfprintf(stderr, x, ap);
-	va_end(ap);
-	exit(EXIT_FAILURE);
-}
-
-static void usage(void)
-{
-	printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.\n\n"
-		"slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
-		"-a|--aliases           Show aliases\n"
-		"-A|--activity          Most active slabs first\n"
-		"-d<options>|--debug=<options> Set/Clear Debug options\n"
-		"-D|--display-active    Switch line format to activity\n"
-		"-e|--empty             Show empty slabs\n"
-		"-f|--first-alias       Show first alias\n"
-		"-h|--help              Show usage information\n"
-		"-i|--inverted          Inverted list\n"
-		"-l|--slabs             Show slabs\n"
-		"-n|--numa              Show NUMA information\n"
-		"-o|--ops		Show kmem_cache_ops\n"
-		"-s|--shrink            Shrink slabs\n"
-		"-r|--report		Detailed report on single slabs\n"
-		"-S|--Size              Sort by size\n"
-		"-t|--tracking          Show alloc/free information\n"
-		"-T|--Totals            Show summary information\n"
-		"-v|--validate          Validate slabs\n"
-		"-z|--zero              Include empty slabs\n"
-		"-1|--1ref              Single reference\n"
-		"\nValid debug options (FZPUT may be combined)\n"
-		"a / A          Switch on all debug options (=FZUP)\n"
-		"-              Switch off all debug options\n"
-		"f / F          Sanity Checks (SLAB_DEBUG_FREE)\n"
-		"z / Z          Redzoning\n"
-		"p / P          Poisoning\n"
-		"u / U          Tracking\n"
-		"t / T          Tracing\n"
-	);
-}
-
-static unsigned long read_obj(const char *name)
-{
-	FILE *f = fopen(name, "r");
-
-	if (!f)
-		buffer[0] = 0;
-	else {
-		if (!fgets(buffer, sizeof(buffer), f))
-			buffer[0] = 0;
-		fclose(f);
-		if (buffer[strlen(buffer)] == '\n')
-			buffer[strlen(buffer)] = 0;
-	}
-	return strlen(buffer);
-}
-
-
-/*
- * Get the contents of an attribute
- */
-static unsigned long get_obj(const char *name)
-{
-	if (!read_obj(name))
-		return 0;
-
-	return atol(buffer);
-}
-
-static unsigned long get_obj_and_str(const char *name, char **x)
-{
-	unsigned long result = 0;
-	char *p;
-
-	*x = NULL;
-
-	if (!read_obj(name)) {
-		x = NULL;
-		return 0;
-	}
-	result = strtoul(buffer, &p, 10);
-	while (*p == ' ')
-		p++;
-	if (*p)
-		*x = strdup(p);
-	return result;
-}
-
-static void set_obj(struct slabinfo *s, const char *name, int n)
-{
-	char x[100];
-	FILE *f;
-
-	snprintf(x, 100, "%s/%s", s->name, name);
-	f = fopen(x, "w");
-	if (!f)
-		fatal("Cannot write to %s\n", x);
-
-	fprintf(f, "%d\n", n);
-	fclose(f);
-}
-
-static unsigned long read_slab_obj(struct slabinfo *s, const char *name)
-{
-	char x[100];
-	FILE *f;
-	size_t l;
-
-	snprintf(x, 100, "%s/%s", s->name, name);
-	f = fopen(x, "r");
-	if (!f) {
-		buffer[0] = 0;
-		l = 0;
-	} else {
-		l = fread(buffer, 1, sizeof(buffer), f);
-		buffer[l] = 0;
-		fclose(f);
-	}
-	return l;
-}
-
-
-/*
- * Put a size string together
- */
-static int store_size(char *buffer, unsigned long value)
-{
-	unsigned long divisor = 1;
-	char trailer = 0;
-	int n;
-
-	if (value > 1000000000UL) {
-		divisor = 100000000UL;
-		trailer = 'G';
-	} else if (value > 1000000UL) {
-		divisor = 100000UL;
-		trailer = 'M';
-	} else if (value > 1000UL) {
-		divisor = 100;
-		trailer = 'K';
-	}
-
-	value /= divisor;
-	n = sprintf(buffer, "%ld",value);
-	if (trailer) {
-		buffer[n] = trailer;
-		n++;
-		buffer[n] = 0;
-	}
-	if (divisor != 1) {
-		memmove(buffer + n - 2, buffer + n - 3, 4);
-		buffer[n-2] = '.';
-		n++;
-	}
-	return n;
-}
-
-static void decode_numa_list(int *numa, char *t)
-{
-	int node;
-	int nr;
-
-	memset(numa, 0, MAX_NODES * sizeof(int));
-
-	if (!t)
-		return;
-
-	while (*t == 'N') {
-		t++;
-		node = strtoul(t, &t, 10);
-		if (*t == '=') {
-			t++;
-			nr = strtoul(t, &t, 10);
-			numa[node] = nr;
-			if (node > highest_node)
-				highest_node = node;
-		}
-		while (*t == ' ')
-			t++;
-	}
-}
-
-static void slab_validate(struct slabinfo *s)
-{
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	set_obj(s, "validate", 1);
-}
-
-static void slab_shrink(struct slabinfo *s)
-{
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	set_obj(s, "shrink", 1);
-}
-
-int line = 0;
-
-static void first_line(void)
-{
-	if (show_activity)
-		printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL\n");
-	else
-		printf("Name                   Objects Objsize    Space "
-			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n");
-}
-
-/*
- * Find the shortest alias of a slab
- */
-static struct aliasinfo *find_one_alias(struct slabinfo *find)
-{
-	struct aliasinfo *a;
-	struct aliasinfo *best = NULL;
-
-	for(a = aliasinfo;a < aliasinfo + aliases; a++) {
-		if (a->slab == find &&
-			(!best || strlen(best->name) < strlen(a->name))) {
-				best = a;
-				if (strncmp(a->name,"kmall", 5) == 0)
-					return best;
-			}
-	}
-	return best;
-}
-
-static unsigned long slab_size(struct slabinfo *s)
-{
-	return 	s->slabs * (page_size << s->order);
-}
-
-static unsigned long slab_activity(struct slabinfo *s)
-{
-	return 	s->alloc_fastpath + s->free_fastpath +
-		s->alloc_slowpath + s->free_slowpath;
-}
-
-static void slab_numa(struct slabinfo *s, int mode)
-{
-	int node;
-
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	if (!highest_node) {
-		printf("\n%s: No NUMA information available.\n", s->name);
-		return;
-	}
-
-	if (skip_zero && !s->slabs)
-		return;
-
-	if (!line) {
-		printf("\n%-21s:", mode ? "NUMA nodes" : "Slab");
-		for(node = 0; node <= highest_node; node++)
-			printf(" %4d", node);
-		printf("\n----------------------");
-		for(node = 0; node <= highest_node; node++)
-			printf("-----");
-		printf("\n");
-	}
-	printf("%-21s ", mode ? "All slabs" : s->name);
-	for(node = 0; node <= highest_node; node++) {
-		char b[20];
-
-		store_size(b, s->numa[node]);
-		printf(" %4s", b);
-	}
-	printf("\n");
-	if (mode) {
-		printf("%-21s ", "Partial slabs");
-		for(node = 0; node <= highest_node; node++) {
-			char b[20];
-
-			store_size(b, s->numa_partial[node]);
-			printf(" %4s", b);
-		}
-		printf("\n");
-	}
-	line++;
-}
-
-static void show_tracking(struct slabinfo *s)
-{
-	printf("\n%s: Kernel object allocation\n", s->name);
-	printf("-----------------------------------------------------------------------\n");
-	if (read_slab_obj(s, "alloc_calls"))
-		printf("%s", buffer);
-	else
-		printf("No Data\n");
-
-	printf("\n%s: Kernel object freeing\n", s->name);
-	printf("------------------------------------------------------------------------\n");
-	if (read_slab_obj(s, "free_calls"))
-		printf("%s", buffer);
-	else
-		printf("No Data\n");
-
-}
-
-static void ops(struct slabinfo *s)
-{
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	if (read_slab_obj(s, "ops")) {
-		printf("\n%s: kmem_cache operations\n", s->name);
-		printf("--------------------------------------------\n");
-		printf("%s", buffer);
-	} else
-		printf("\n%s has no kmem_cache operations\n", s->name);
-}
-
-static const char *onoff(int x)
-{
-	if (x)
-		return "On ";
-	return "Off";
-}
-
-static void slab_stats(struct slabinfo *s)
-{
-	unsigned long total_alloc;
-	unsigned long total_free;
-	unsigned long total;
-
-	if (!s->alloc_slab)
-		return;
-
-	total_alloc = s->alloc_fastpath + s->alloc_slowpath;
-	total_free = s->free_fastpath + s->free_slowpath;
-
-	if (!total_alloc)
-		return;
-
-	printf("\n");
-	printf("Slab Perf Counter       Alloc     Free %%Al %%Fr\n");
-	printf("--------------------------------------------------\n");
-	printf("Fastpath             %8lu %8lu %3lu %3lu\n",
-		s->alloc_fastpath, s->free_fastpath,
-		s->alloc_fastpath * 100 / total_alloc,
-		s->free_fastpath * 100 / total_free);
-	printf("Slowpath             %8lu %8lu %3lu %3lu\n",
-		total_alloc - s->alloc_fastpath, s->free_slowpath,
-		(total_alloc - s->alloc_fastpath) * 100 / total_alloc,
-		s->free_slowpath * 100 / total_free);
-	printf("Page Alloc           %8lu %8lu %3lu %3lu\n",
-		s->alloc_slab, s->free_slab,
-		s->alloc_slab * 100 / total_alloc,
-		s->free_slab * 100 / total_free);
-	printf("Add partial          %8lu %8lu %3lu %3lu\n",
-		s->deactivate_to_head + s->deactivate_to_tail,
-		s->free_add_partial,
-		(s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc,
-		s->free_add_partial * 100 / total_free);
-	printf("Remove partial       %8lu %8lu %3lu %3lu\n",
-		s->alloc_from_partial, s->free_remove_partial,
-		s->alloc_from_partial * 100 / total_alloc,
-		s->free_remove_partial * 100 / total_free);
-
-	printf("Cpu partial list     %8lu %8lu %3lu %3lu\n",
-		s->cpu_partial_alloc, s->cpu_partial_free,
-		s->cpu_partial_alloc * 100 / total_alloc,
-		s->cpu_partial_free * 100 / total_free);
-
-	printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n",
-		s->deactivate_remote_frees, s->free_frozen,
-		s->deactivate_remote_frees * 100 / total_alloc,
-		s->free_frozen * 100 / total_free);
-
-	printf("Total                %8lu %8lu\n\n", total_alloc, total_free);
-
-	if (s->cpuslab_flush)
-		printf("Flushes %8lu\n", s->cpuslab_flush);
-
-	total = s->deactivate_full + s->deactivate_empty +
-			s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
-
-	if (total) {
-		printf("\nSlab Deactivation             Ocurrences  %%\n");
-		printf("-------------------------------------------------\n");
-		printf("Slab full                     %7lu  %3lu%%\n",
-			s->deactivate_full, (s->deactivate_full * 100) / total);
-		printf("Slab empty                    %7lu  %3lu%%\n",
-			s->deactivate_empty, (s->deactivate_empty * 100) / total);
-		printf("Moved to head of partial list %7lu  %3lu%%\n",
-			s->deactivate_to_head, (s->deactivate_to_head * 100) / total);
-		printf("Moved to tail of partial list %7lu  %3lu%%\n",
-			s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
-		printf("Deactivation bypass           %7lu  %3lu%%\n",
-			s->deactivate_bypass, (s->deactivate_bypass * 100) / total);
-		printf("Refilled from foreign frees   %7lu  %3lu%%\n",
-			s->alloc_refill, (s->alloc_refill * 100) / total);
-		printf("Node mismatch                 %7lu  %3lu%%\n",
-			s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
-	}
-
-	if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail)
-		printf("\nCmpxchg_double Looping\n------------------------\n");
-		printf("Locked Cmpxchg Double redos   %lu\nUnlocked Cmpxchg Double redos %lu\n",
-			s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
-}
-
-static void report(struct slabinfo *s)
-{
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	printf("\nSlabcache: %-20s  Aliases: %2d Order : %2d Objects: %lu\n",
-		s->name, s->aliases, s->order, s->objects);
-	if (s->hwcache_align)
-		printf("** Hardware cacheline aligned\n");
-	if (s->cache_dma)
-		printf("** Memory is allocated in a special DMA zone\n");
-	if (s->destroy_by_rcu)
-		printf("** Slabs are destroyed via RCU\n");
-	if (s->reclaim_account)
-		printf("** Reclaim accounting active\n");
-
-	printf("\nSizes (bytes)     Slabs              Debug                Memory\n");
-	printf("------------------------------------------------------------------------\n");
-	printf("Object : %7d  Total  : %7ld   Sanity Checks : %s  Total: %7ld\n",
-			s->object_size, s->slabs, onoff(s->sanity_checks),
-			s->slabs * (page_size << s->order));
-	printf("SlabObj: %7d  Full   : %7ld   Redzoning     : %s  Used : %7ld\n",
-			s->slab_size, s->slabs - s->partial - s->cpu_slabs,
-			onoff(s->red_zone), s->objects * s->object_size);
-	printf("SlabSiz: %7d  Partial: %7ld   Poisoning     : %s  Loss : %7ld\n",
-			page_size << s->order, s->partial, onoff(s->poison),
-			s->slabs * (page_size << s->order) - s->objects * s->object_size);
-	printf("Loss   : %7d  CpuSlab: %7d   Tracking      : %s  Lalig: %7ld\n",
-			s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user),
-			(s->slab_size - s->object_size) * s->objects);
-	printf("Align  : %7d  Objects: %7d   Tracing       : %s  Lpadd: %7ld\n",
-			s->align, s->objs_per_slab, onoff(s->trace),
-			((page_size << s->order) - s->objs_per_slab * s->slab_size) *
-			s->slabs);
-
-	ops(s);
-	show_tracking(s);
-	slab_numa(s, 1);
-	slab_stats(s);
-}
-
-static void slabcache(struct slabinfo *s)
-{
-	char size_str[20];
-	char dist_str[40];
-	char flags[20];
-	char *p = flags;
-
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	if (actual_slabs == 1) {
-		report(s);
-		return;
-	}
-
-	if (skip_zero && !show_empty && !s->slabs)
-		return;
-
-	if (show_empty && s->slabs)
-		return;
-
-	store_size(size_str, slab_size(s));
-	snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
-						s->partial, s->cpu_slabs);
-
-	if (!line++)
-		first_line();
-
-	if (s->aliases)
-		*p++ = '*';
-	if (s->cache_dma)
-		*p++ = 'd';
-	if (s->hwcache_align)
-		*p++ = 'A';
-	if (s->poison)
-		*p++ = 'P';
-	if (s->reclaim_account)
-		*p++ = 'a';
-	if (s->red_zone)
-		*p++ = 'Z';
-	if (s->sanity_checks)
-		*p++ = 'F';
-	if (s->store_user)
-		*p++ = 'U';
-	if (s->trace)
-		*p++ = 'T';
-
-	*p = 0;
-	if (show_activity) {
-		unsigned long total_alloc;
-		unsigned long total_free;
-
-		total_alloc = s->alloc_fastpath + s->alloc_slowpath;
-		total_free = s->free_fastpath + s->free_slowpath;
-
-		printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld\n",
-			s->name, s->objects,
-			total_alloc, total_free,
-			total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
-			total_free ? (s->free_fastpath * 100 / total_free) : 0,
-			s->order_fallback, s->order, s->cmpxchg_double_fail,
-			s->cmpxchg_double_cpu_fail);
-	}
-	else
-		printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
-			s->name, s->objects, s->object_size, size_str, dist_str,
-			s->objs_per_slab, s->order,
-			s->slabs ? (s->partial * 100) / s->slabs : 100,
-			s->slabs ? (s->objects * s->object_size * 100) /
-				(s->slabs * (page_size << s->order)) : 100,
-			flags);
-}
-
-/*
- * Analyze debug options. Return false if something is amiss.
- */
-static int debug_opt_scan(char *opt)
-{
-	if (!opt || !opt[0] || strcmp(opt, "-") == 0)
-		return 1;
-
-	if (strcasecmp(opt, "a") == 0) {
-		sanity = 1;
-		poison = 1;
-		redzone = 1;
-		tracking = 1;
-		return 1;
-	}
-
-	for ( ; *opt; opt++)
-		switch (*opt) {
-		case 'F' : case 'f':
-			if (sanity)
-				return 0;
-			sanity = 1;
-			break;
-		case 'P' : case 'p':
-			if (poison)
-				return 0;
-			poison = 1;
-			break;
-
-		case 'Z' : case 'z':
-			if (redzone)
-				return 0;
-			redzone = 1;
-			break;
-
-		case 'U' : case 'u':
-			if (tracking)
-				return 0;
-			tracking = 1;
-			break;
-
-		case 'T' : case 't':
-			if (tracing)
-				return 0;
-			tracing = 1;
-			break;
-		default:
-			return 0;
-		}
-	return 1;
-}
-
-static int slab_empty(struct slabinfo *s)
-{
-	if (s->objects > 0)
-		return 0;
-
-	/*
-	 * We may still have slabs even if there are no objects. Shrinking will
-	 * remove them.
-	 */
-	if (s->slabs != 0)
-		set_obj(s, "shrink", 1);
-
-	return 1;
-}
-
-static void slab_debug(struct slabinfo *s)
-{
-	if (strcmp(s->name, "*") == 0)
-		return;
-
-	if (sanity && !s->sanity_checks) {
-		set_obj(s, "sanity", 1);
-	}
-	if (!sanity && s->sanity_checks) {
-		if (slab_empty(s))
-			set_obj(s, "sanity", 0);
-		else
-			fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name);
-	}
-	if (redzone && !s->red_zone) {
-		if (slab_empty(s))
-			set_obj(s, "red_zone", 1);
-		else
-			fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name);
-	}
-	if (!redzone && s->red_zone) {
-		if (slab_empty(s))
-			set_obj(s, "red_zone", 0);
-		else
-			fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name);
-	}
-	if (poison && !s->poison) {
-		if (slab_empty(s))
-			set_obj(s, "poison", 1);
-		else
-			fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name);
-	}
-	if (!poison && s->poison) {
-		if (slab_empty(s))
-			set_obj(s, "poison", 0);
-		else
-			fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name);
-	}
-	if (tracking && !s->store_user) {
-		if (slab_empty(s))
-			set_obj(s, "store_user", 1);
-		else
-			fprintf(stderr, "%s not empty cannot enable tracking\n", s->name);
-	}
-	if (!tracking && s->store_user) {
-		if (slab_empty(s))
-			set_obj(s, "store_user", 0);
-		else
-			fprintf(stderr, "%s not empty cannot disable tracking\n", s->name);
-	}
-	if (tracing && !s->trace) {
-		if (slabs == 1)
-			set_obj(s, "trace", 1);
-		else
-			fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name);
-	}
-	if (!tracing && s->trace)
-		set_obj(s, "trace", 1);
-}
-
-static void totals(void)
-{
-	struct slabinfo *s;
-
-	int used_slabs = 0;
-	char b1[20], b2[20], b3[20], b4[20];
-	unsigned long long max = 1ULL << 63;
-
-	/* Object size */
-	unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
-
-	/* Number of partial slabs in a slabcache */
-	unsigned long long min_partial = max, max_partial = 0,
-				avg_partial, total_partial = 0;
-
-	/* Number of slabs in a slab cache */
-	unsigned long long min_slabs = max, max_slabs = 0,
-				avg_slabs, total_slabs = 0;
-
-	/* Size of the whole slab */
-	unsigned long long min_size = max, max_size = 0,
-				avg_size, total_size = 0;
-
-	/* Bytes used for object storage in a slab */
-	unsigned long long min_used = max, max_used = 0,
-				avg_used, total_used = 0;
-
-	/* Waste: Bytes used for alignment and padding */
-	unsigned long long min_waste = max, max_waste = 0,
-				avg_waste, total_waste = 0;
-	/* Number of objects in a slab */
-	unsigned long long min_objects = max, max_objects = 0,
-				avg_objects, total_objects = 0;
-	/* Waste per object */
-	unsigned long long min_objwaste = max,
-				max_objwaste = 0, avg_objwaste,
-				total_objwaste = 0;
-
-	/* Memory per object */
-	unsigned long long min_memobj = max,
-				max_memobj = 0, avg_memobj,
-				total_objsize = 0;
-
-	/* Percentage of partial slabs per slab */
-	unsigned long min_ppart = 100, max_ppart = 0,
-				avg_ppart, total_ppart = 0;
-
-	/* Number of objects in partial slabs */
-	unsigned long min_partobj = max, max_partobj = 0,
-				avg_partobj, total_partobj = 0;
-
-	/* Percentage of partial objects of all objects in a slab */
-	unsigned long min_ppartobj = 100, max_ppartobj = 0,
-				avg_ppartobj, total_ppartobj = 0;
-
-
-	for (s = slabinfo; s < slabinfo + slabs; s++) {
-		unsigned long long size;
-		unsigned long used;
-		unsigned long long wasted;
-		unsigned long long objwaste;
-		unsigned long percentage_partial_slabs;
-		unsigned long percentage_partial_objs;
-
-		if (!s->slabs || !s->objects)
-			continue;
-
-		used_slabs++;
-
-		size = slab_size(s);
-		used = s->objects * s->object_size;
-		wasted = size - used;
-		objwaste = s->slab_size - s->object_size;
-
-		percentage_partial_slabs = s->partial * 100 / s->slabs;
-		if (percentage_partial_slabs > 100)
-			percentage_partial_slabs = 100;
-
-		percentage_partial_objs = s->objects_partial * 100
-							/ s->objects;
-
-		if (percentage_partial_objs > 100)
-			percentage_partial_objs = 100;
-
-		if (s->object_size < min_objsize)
-			min_objsize = s->object_size;
-		if (s->partial < min_partial)
-			min_partial = s->partial;
-		if (s->slabs < min_slabs)
-			min_slabs = s->slabs;
-		if (size < min_size)
-			min_size = size;
-		if (wasted < min_waste)
-			min_waste = wasted;
-		if (objwaste < min_objwaste)
-			min_objwaste = objwaste;
-		if (s->objects < min_objects)
-			min_objects = s->objects;
-		if (used < min_used)
-			min_used = used;
-		if (s->objects_partial < min_partobj)
-			min_partobj = s->objects_partial;
-		if (percentage_partial_slabs < min_ppart)
-			min_ppart = percentage_partial_slabs;
-		if (percentage_partial_objs < min_ppartobj)
-			min_ppartobj = percentage_partial_objs;
-		if (s->slab_size < min_memobj)
-			min_memobj = s->slab_size;
-
-		if (s->object_size > max_objsize)
-			max_objsize = s->object_size;
-		if (s->partial > max_partial)
-			max_partial = s->partial;
-		if (s->slabs > max_slabs)
-			max_slabs = s->slabs;
-		if (size > max_size)
-			max_size = size;
-		if (wasted > max_waste)
-			max_waste = wasted;
-		if (objwaste > max_objwaste)
-			max_objwaste = objwaste;
-		if (s->objects > max_objects)
-			max_objects = s->objects;
-		if (used > max_used)
-			max_used = used;
-		if (s->objects_partial > max_partobj)
-			max_partobj = s->objects_partial;
-		if (percentage_partial_slabs > max_ppart)
-			max_ppart = percentage_partial_slabs;
-		if (percentage_partial_objs > max_ppartobj)
-			max_ppartobj = percentage_partial_objs;
-		if (s->slab_size > max_memobj)
-			max_memobj = s->slab_size;
-
-		total_partial += s->partial;
-		total_slabs += s->slabs;
-		total_size += size;
-		total_waste += wasted;
-
-		total_objects += s->objects;
-		total_used += used;
-		total_partobj += s->objects_partial;
-		total_ppart += percentage_partial_slabs;
-		total_ppartobj += percentage_partial_objs;
-
-		total_objwaste += s->objects * objwaste;
-		total_objsize += s->objects * s->slab_size;
-	}
-
-	if (!total_objects) {
-		printf("No objects\n");
-		return;
-	}
-	if (!used_slabs) {
-		printf("No slabs\n");
-		return;
-	}
-
-	/* Per slab averages */
-	avg_partial = total_partial / used_slabs;
-	avg_slabs = total_slabs / used_slabs;
-	avg_size = total_size / used_slabs;
-	avg_waste = total_waste / used_slabs;
-
-	avg_objects = total_objects / used_slabs;
-	avg_used = total_used / used_slabs;
-	avg_partobj = total_partobj / used_slabs;
-	avg_ppart = total_ppart / used_slabs;
-	avg_ppartobj = total_ppartobj / used_slabs;
-
-	/* Per object object sizes */
-	avg_objsize = total_used / total_objects;
-	avg_objwaste = total_objwaste / total_objects;
-	avg_partobj = total_partobj * 100 / total_objects;
-	avg_memobj = total_objsize / total_objects;
-
-	printf("Slabcache Totals\n");
-	printf("----------------\n");
-	printf("Slabcaches : %3d      Aliases  : %3d->%-3d Active: %3d\n",
-			slabs, aliases, alias_targets, used_slabs);
-
-	store_size(b1, total_size);store_size(b2, total_waste);
-	store_size(b3, total_waste * 100 / total_used);
-	printf("Memory used: %6s   # Loss   : %6s   MRatio:%6s%%\n", b1, b2, b3);
-
-	store_size(b1, total_objects);store_size(b2, total_partobj);
-	store_size(b3, total_partobj * 100 / total_objects);
-	printf("# Objects  : %6s   # PartObj: %6s   ORatio:%6s%%\n", b1, b2, b3);
-
-	printf("\n");
-	printf("Per Cache    Average         Min         Max       Total\n");
-	printf("---------------------------------------------------------\n");
-
-	store_size(b1, avg_objects);store_size(b2, min_objects);
-	store_size(b3, max_objects);store_size(b4, total_objects);
-	printf("#Objects  %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_slabs);store_size(b2, min_slabs);
-	store_size(b3, max_slabs);store_size(b4, total_slabs);
-	printf("#Slabs    %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_partial);store_size(b2, min_partial);
-	store_size(b3, max_partial);store_size(b4, total_partial);
-	printf("#PartSlab %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-	store_size(b1, avg_ppart);store_size(b2, min_ppart);
-	store_size(b3, max_ppart);
-	store_size(b4, total_partial * 100  / total_slabs);
-	printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_partobj);store_size(b2, min_partobj);
-	store_size(b3, max_partobj);
-	store_size(b4, total_partobj);
-	printf("PartObjs  %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
-	store_size(b3, max_ppartobj);
-	store_size(b4, total_partobj * 100 / total_objects);
-	printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_size);store_size(b2, min_size);
-	store_size(b3, max_size);store_size(b4, total_size);
-	printf("Memory    %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_used);store_size(b2, min_used);
-	store_size(b3, max_used);store_size(b4, total_used);
-	printf("Used      %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-
-	store_size(b1, avg_waste);store_size(b2, min_waste);
-	store_size(b3, max_waste);store_size(b4, total_waste);
-	printf("Loss      %10s  %10s  %10s  %10s\n",
-			b1,	b2,	b3,	b4);
-
-	printf("\n");
-	printf("Per Object   Average         Min         Max\n");
-	printf("---------------------------------------------\n");
-
-	store_size(b1, avg_memobj);store_size(b2, min_memobj);
-	store_size(b3, max_memobj);
-	printf("Memory    %10s  %10s  %10s\n",
-			b1,	b2,	b3);
-	store_size(b1, avg_objsize);store_size(b2, min_objsize);
-	store_size(b3, max_objsize);
-	printf("User      %10s  %10s  %10s\n",
-			b1,	b2,	b3);
-
-	store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
-	store_size(b3, max_objwaste);
-	printf("Loss      %10s  %10s  %10s\n",
-			b1,	b2,	b3);
-}
-
-static void sort_slabs(void)
-{
-	struct slabinfo *s1,*s2;
-
-	for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
-		for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
-			int result;
-
-			if (sort_size)
-				result = slab_size(s1) < slab_size(s2);
-			else if (sort_active)
-				result = slab_activity(s1) < slab_activity(s2);
-			else
-				result = strcasecmp(s1->name, s2->name);
-
-			if (show_inverted)
-				result = -result;
-
-			if (result > 0) {
-				struct slabinfo t;
-
-				memcpy(&t, s1, sizeof(struct slabinfo));
-				memcpy(s1, s2, sizeof(struct slabinfo));
-				memcpy(s2, &t, sizeof(struct slabinfo));
-			}
-		}
-	}
-}
-
-static void sort_aliases(void)
-{
-	struct aliasinfo *a1,*a2;
-
-	for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
-		for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
-			char *n1, *n2;
-
-			n1 = a1->name;
-			n2 = a2->name;
-			if (show_alias && !show_inverted) {
-				n1 = a1->ref;
-				n2 = a2->ref;
-			}
-			if (strcasecmp(n1, n2) > 0) {
-				struct aliasinfo t;
-
-				memcpy(&t, a1, sizeof(struct aliasinfo));
-				memcpy(a1, a2, sizeof(struct aliasinfo));
-				memcpy(a2, &t, sizeof(struct aliasinfo));
-			}
-		}
-	}
-}
-
-static void link_slabs(void)
-{
-	struct aliasinfo *a;
-	struct slabinfo *s;
-
-	for (a = aliasinfo; a < aliasinfo + aliases; a++) {
-
-		for (s = slabinfo; s < slabinfo + slabs; s++)
-			if (strcmp(a->ref, s->name) == 0) {
-				a->slab = s;
-				s->refs++;
-				break;
-			}
-		if (s == slabinfo + slabs)
-			fatal("Unresolved alias %s\n", a->ref);
-	}
-}
-
-static void alias(void)
-{
-	struct aliasinfo *a;
-	char *active = NULL;
-
-	sort_aliases();
-	link_slabs();
-
-	for(a = aliasinfo; a < aliasinfo + aliases; a++) {
-
-		if (!show_single_ref && a->slab->refs == 1)
-			continue;
-
-		if (!show_inverted) {
-			if (active) {
-				if (strcmp(a->slab->name, active) == 0) {
-					printf(" %s", a->name);
-					continue;
-				}
-			}
-			printf("\n%-12s <- %s", a->slab->name, a->name);
-			active = a->slab->name;
-		}
-		else
-			printf("%-20s -> %s\n", a->name, a->slab->name);
-	}
-	if (active)
-		printf("\n");
-}
-
-
-static void rename_slabs(void)
-{
-	struct slabinfo *s;
-	struct aliasinfo *a;
-
-	for (s = slabinfo; s < slabinfo + slabs; s++) {
-		if (*s->name != ':')
-			continue;
-
-		if (s->refs > 1 && !show_first_alias)
-			continue;
-
-		a = find_one_alias(s);
-
-		if (a)
-			s->name = a->name;
-		else {
-			s->name = "*";
-			actual_slabs--;
-		}
-	}
-}
-
-static int slab_mismatch(char *slab)
-{
-	return regexec(&pattern, slab, 0, NULL, 0);
-}
-
-static void read_slab_dir(void)
-{
-	DIR *dir;
-	struct dirent *de;
-	struct slabinfo *slab = slabinfo;
-	struct aliasinfo *alias = aliasinfo;
-	char *p;
-	char *t;
-	int count;
-
-	if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
-		fatal("SYSFS support for SLUB not active\n");
-
-	dir = opendir(".");
-	while ((de = readdir(dir))) {
-		if (de->d_name[0] == '.' ||
-			(de->d_name[0] != ':' && slab_mismatch(de->d_name)))
-				continue;
-		switch (de->d_type) {
-		   case DT_LNK:
-			alias->name = strdup(de->d_name);
-			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
-
-			if (count < 0)
-				fatal("Cannot read symlink %s\n", de->d_name);
-
-			buffer[count] = 0;
-			p = buffer + count;
-			while (p > buffer && p[-1] != '/')
-				p--;
-			alias->ref = strdup(p);
-			alias++;
-			break;
-		   case DT_DIR:
-			if (chdir(de->d_name))
-				fatal("Unable to access slab %s\n", slab->name);
-			slab->name = strdup(de->d_name);
-			slab->alias = 0;
-			slab->refs = 0;
-			slab->aliases = get_obj("aliases");
-			slab->align = get_obj("align");
-			slab->cache_dma = get_obj("cache_dma");
-			slab->cpu_slabs = get_obj("cpu_slabs");
-			slab->destroy_by_rcu = get_obj("destroy_by_rcu");
-			slab->hwcache_align = get_obj("hwcache_align");
-			slab->object_size = get_obj("object_size");
-			slab->objects = get_obj("objects");
-			slab->objects_partial = get_obj("objects_partial");
-			slab->objects_total = get_obj("objects_total");
-			slab->objs_per_slab = get_obj("objs_per_slab");
-			slab->order = get_obj("order");
-			slab->partial = get_obj("partial");
-			slab->partial = get_obj_and_str("partial", &t);
-			decode_numa_list(slab->numa_partial, t);
-			free(t);
-			slab->poison = get_obj("poison");
-			slab->reclaim_account = get_obj("reclaim_account");
-			slab->red_zone = get_obj("red_zone");
-			slab->sanity_checks = get_obj("sanity_checks");
-			slab->slab_size = get_obj("slab_size");
-			slab->slabs = get_obj_and_str("slabs", &t);
-			decode_numa_list(slab->numa, t);
-			free(t);
-			slab->store_user = get_obj("store_user");
-			slab->trace = get_obj("trace");
-			slab->alloc_fastpath = get_obj("alloc_fastpath");
-			slab->alloc_slowpath = get_obj("alloc_slowpath");
-			slab->free_fastpath = get_obj("free_fastpath");
-			slab->free_slowpath = get_obj("free_slowpath");
-			slab->free_frozen= get_obj("free_frozen");
-			slab->free_add_partial = get_obj("free_add_partial");
-			slab->free_remove_partial = get_obj("free_remove_partial");
-			slab->alloc_from_partial = get_obj("alloc_from_partial");
-			slab->alloc_slab = get_obj("alloc_slab");
-			slab->alloc_refill = get_obj("alloc_refill");
-			slab->free_slab = get_obj("free_slab");
-			slab->cpuslab_flush = get_obj("cpuslab_flush");
-			slab->deactivate_full = get_obj("deactivate_full");
-			slab->deactivate_empty = get_obj("deactivate_empty");
-			slab->deactivate_to_head = get_obj("deactivate_to_head");
-			slab->deactivate_to_tail = get_obj("deactivate_to_tail");
-			slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
-			slab->order_fallback = get_obj("order_fallback");
-			slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail");
-			slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail");
-			slab->cpu_partial_alloc = get_obj("cpu_partial_alloc");
-			slab->cpu_partial_free = get_obj("cpu_partial_free");
-			slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
-			slab->deactivate_bypass = get_obj("deactivate_bypass");
-			chdir("..");
-			if (slab->name[0] == ':')
-				alias_targets++;
-			slab++;
-			break;
-		   default :
-			fatal("Unknown file type %lx\n", de->d_type);
-		}
-	}
-	closedir(dir);
-	slabs = slab - slabinfo;
-	actual_slabs = slabs;
-	aliases = alias - aliasinfo;
-	if (slabs > MAX_SLABS)
-		fatal("Too many slabs\n");
-	if (aliases > MAX_ALIASES)
-		fatal("Too many aliases\n");
-}
-
-static void output_slabs(void)
-{
-	struct slabinfo *slab;
-
-	for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
-
-		if (slab->alias)
-			continue;
-
-
-		if (show_numa)
-			slab_numa(slab, 0);
-		else if (show_track)
-			show_tracking(slab);
-		else if (validate)
-			slab_validate(slab);
-		else if (shrink)
-			slab_shrink(slab);
-		else if (set_debug)
-			slab_debug(slab);
-		else if (show_ops)
-			ops(slab);
-		else if (show_slab)
-			slabcache(slab);
-		else if (show_report)
-			report(slab);
-	}
-}
-
-struct option opts[] = {
-	{ "aliases", 0, NULL, 'a' },
-	{ "activity", 0, NULL, 'A' },
-	{ "debug", 2, NULL, 'd' },
-	{ "display-activity", 0, NULL, 'D' },
-	{ "empty", 0, NULL, 'e' },
-	{ "first-alias", 0, NULL, 'f' },
-	{ "help", 0, NULL, 'h' },
-	{ "inverted", 0, NULL, 'i'},
-	{ "numa", 0, NULL, 'n' },
-	{ "ops", 0, NULL, 'o' },
-	{ "report", 0, NULL, 'r' },
-	{ "shrink", 0, NULL, 's' },
-	{ "slabs", 0, NULL, 'l' },
-	{ "track", 0, NULL, 't'},
-	{ "validate", 0, NULL, 'v' },
-	{ "zero", 0, NULL, 'z' },
-	{ "1ref", 0, NULL, '1'},
-	{ NULL, 0, NULL, 0 }
-};
-
-int main(int argc, char *argv[])
-{
-	int c;
-	int err;
-	char *pattern_source;
-
-	page_size = getpagesize();
-
-	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
-						opts, NULL)) != -1)
-		switch (c) {
-		case '1':
-			show_single_ref = 1;
-			break;
-		case 'a':
-			show_alias = 1;
-			break;
-		case 'A':
-			sort_active = 1;
-			break;
-		case 'd':
-			set_debug = 1;
-			if (!debug_opt_scan(optarg))
-				fatal("Invalid debug option '%s'\n", optarg);
-			break;
-		case 'D':
-			show_activity = 1;
-			break;
-		case 'e':
-			show_empty = 1;
-			break;
-		case 'f':
-			show_first_alias = 1;
-			break;
-		case 'h':
-			usage();
-			return 0;
-		case 'i':
-			show_inverted = 1;
-			break;
-		case 'n':
-			show_numa = 1;
-			break;
-		case 'o':
-			show_ops = 1;
-			break;
-		case 'r':
-			show_report = 1;
-			break;
-		case 's':
-			shrink = 1;
-			break;
-		case 'l':
-			show_slab = 1;
-			break;
-		case 't':
-			show_track = 1;
-			break;
-		case 'v':
-			validate = 1;
-			break;
-		case 'z':
-			skip_zero = 0;
-			break;
-		case 'T':
-			show_totals = 1;
-			break;
-		case 'S':
-			sort_size = 1;
-			break;
-
-		default:
-			fatal("%s: Invalid option '%c'\n", argv[0], optopt);
-
-	}
-
-	if (!show_slab && !show_alias && !show_track && !show_report
-		&& !validate && !shrink && !set_debug && !show_ops)
-			show_slab = 1;
-
-	if (argc > optind)
-		pattern_source = argv[optind];
-	else
-		pattern_source = ".*";
-
-	err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
-	if (err)
-		fatal("%s: Invalid pattern '%s' code %d\n",
-			argv[0], pattern_source, err);
-	read_slab_dir();
-	if (show_alias)
-		alias();
-	else
-	if (show_totals)
-		totals();
-	else {
-		link_slabs();
-		rename_slabs();
-		sort_slabs();
-		output_slabs();
-	}
-	return 0;
-}
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 62a134d..00c75c4 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -2601,7 +2601,7 @@ sub config_bisect {
     # read directly what we want to check
     my %config_check;
     open (IN, $output_config)
-	or dodie "faied to open $output_config";
+	or dodie "failed to open $output_config";
 
     while (<IN>) {
 	if (/^((CONFIG\S*)=.*)/) {
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 4ec8401..1c7ab0f 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,10 +1,15 @@
-TARGETS = breakpoints
+TARGETS = breakpoints vm kcmp
 
 all:
 	for TARGET in $(TARGETS); do \
 		make -C $$TARGET; \
 	done;
 
+run_tests: all
+	for TARGET in $(TARGETS); do \
+		make -C $$TARGET run_tests; \
+	done;
+
 clean:
 	for TARGET in $(TARGETS); do \
 		make -C $$TARGET clean; \
diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile
index f362722..9312780 100644
--- a/tools/testing/selftests/breakpoints/Makefile
+++ b/tools/testing/selftests/breakpoints/Makefile
@@ -11,10 +11,13 @@ endif
 
 all:
 ifeq ($(ARCH),x86)
-	gcc breakpoint_test.c -o run_test
+	gcc breakpoint_test.c -o breakpoint_test
 else
 	echo "Not an x86 target, can't build breakpoints selftests"
 endif
 
+run_tests:
+	./breakpoint_test
+
 clean:
-	rm -fr run_test
+	rm -fr breakpoint_test
diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile
new file mode 100644
index 0000000..dc79b86
--- /dev/null
+++ b/tools/testing/selftests/kcmp/Makefile
@@ -0,0 +1,29 @@
+uname_M := $(shell uname -m 2>/dev/null || echo not)
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/)
+ifeq ($(ARCH),i386)
+        ARCH := X86
+	CFLAGS := -DCONFIG_X86_32 -D__i386__
+endif
+ifeq ($(ARCH),x86_64)
+	ARCH := X86
+	CFLAGS := -DCONFIG_X86_64 -D__x86_64__
+endif
+
+CFLAGS += -I../../../../arch/x86/include/generated/
+CFLAGS += -I../../../../include/
+CFLAGS += -I../../../../usr/include/
+CFLAGS += -I../../../../arch/x86/include/
+
+all:
+ifeq ($(ARCH),X86)
+	gcc $(CFLAGS) kcmp_test.c -o run_test
+else
+	echo "Not an x86 target, can't build kcmp selftest"
+endif
+
+run-tests: all
+	./kcmp_test
+
+clean:
+	rm -fr ./run_test
+	rm -fr ./test-file
diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c
new file mode 100644
index 0000000..358cc6b
--- /dev/null
+++ b/tools/testing/selftests/kcmp/kcmp_test.c
@@ -0,0 +1,94 @@
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <limits.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <linux/unistd.h>
+#include <linux/kcmp.h>
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+static long sys_kcmp(int pid1, int pid2, int type, int fd1, int fd2)
+{
+	return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2);
+}
+
+int main(int argc, char **argv)
+{
+	const char kpath[] = "kcmp-test-file";
+	int pid1, pid2;
+	int fd1, fd2;
+	int status;
+
+	fd1 = open(kpath, O_RDWR | O_CREAT | O_TRUNC, 0644);
+	pid1 = getpid();
+
+	if (fd1 < 0) {
+		perror("Can't create file");
+		exit(1);
+	}
+
+	pid2 = fork();
+	if (pid2 < 0) {
+		perror("fork failed");
+		exit(1);
+	}
+
+	if (!pid2) {
+		int pid2 = getpid();
+		int ret;
+
+		fd2 = open(kpath, O_RDWR, 0644);
+		if (fd2 < 0) {
+			perror("Can't open file");
+			exit(1);
+		}
+
+		/* An example of output and arguments */
+		printf("pid1: %6d pid2: %6d FD: %2ld FILES: %2ld VM: %2ld "
+		       "FS: %2ld SIGHAND: %2ld IO: %2ld SYSVSEM: %2ld "
+		       "INV: %2ld\n",
+		       pid1, pid2,
+		       sys_kcmp(pid1, pid2, KCMP_FILE,		fd1, fd2),
+		       sys_kcmp(pid1, pid2, KCMP_FILES,		0, 0),
+		       sys_kcmp(pid1, pid2, KCMP_VM,		0, 0),
+		       sys_kcmp(pid1, pid2, KCMP_FS,		0, 0),
+		       sys_kcmp(pid1, pid2, KCMP_SIGHAND,	0, 0),
+		       sys_kcmp(pid1, pid2, KCMP_IO,		0, 0),
+		       sys_kcmp(pid1, pid2, KCMP_SYSVSEM,	0, 0),
+
+			/* This one should fail */
+		       sys_kcmp(pid1, pid2, KCMP_TYPES + 1,	0, 0));
+
+		/* This one should return same fd */
+		ret = sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd1);
+		if (ret) {
+			printf("FAIL: 0 expected but %d returned\n", ret);
+			ret = -1;
+		} else
+			printf("PASS: 0 returned as expected\n");
+
+		/* Compare with self */
+		ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0);
+		if (ret) {
+			printf("FAIL: 0 expected but %li returned\n", ret);
+			ret = -1;
+		} else
+			printf("PASS: 0 returned as expected\n");
+
+		exit(ret);
+	}
+
+	waitpid(pid2, &status, P_ALL);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/run_tests b/tools/testing/selftests/run_tests
deleted file mode 100644
index 320718a..0000000
--- a/tools/testing/selftests/run_tests
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-TARGETS=breakpoints
-
-for TARGET in $TARGETS
-do
-	$TARGET/run_test
-done
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
new file mode 100644
index 0000000..b336b24
--- /dev/null
+++ b/tools/testing/selftests/vm/Makefile
@@ -0,0 +1,14 @@
+# Makefile for vm selftests
+
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -Wall -Wextra
+
+all: hugepage-mmap hugepage-shm  map_hugetlb
+%: %.c
+	$(CC) $(CFLAGS) -o $@ $^
+
+run_tests: all
+	/bin/sh ./run_vmtests
+
+clean:
+	$(RM) hugepage-mmap hugepage-shm  map_hugetlb
diff --git a/tools/testing/selftests/vm/hugepage-mmap.c b/tools/testing/selftests/vm/hugepage-mmap.c
new file mode 100644
index 0000000..a10f310
--- /dev/null
+++ b/tools/testing/selftests/vm/hugepage-mmap.c
@@ -0,0 +1,92 @@
+/*
+ * hugepage-mmap:
+ *
+ * Example of using huge page memory in a user application using the mmap
+ * system call.  Before running this application, make sure that the
+ * administrator has mounted the hugetlbfs filesystem (on some directory
+ * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
+ * example, the app is requesting memory of size 256MB that is backed by
+ * huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages.  That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required.  If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define FILE_NAME "huge/hugepagefile"
+#define LENGTH (256UL*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_SHARED | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_SHARED)
+#endif
+
+static void check_bytes(char *addr)
+{
+	printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+static void write_bytes(char *addr)
+{
+	unsigned long i;
+
+	for (i = 0; i < LENGTH; i++)
+		*(addr + i) = (char)i;
+}
+
+static int read_bytes(char *addr)
+{
+	unsigned long i;
+
+	check_bytes(addr);
+	for (i = 0; i < LENGTH; i++)
+		if (*(addr + i) != (char)i) {
+			printf("Mismatch at %lu\n", i);
+			return 1;
+		}
+	return 0;
+}
+
+int main(void)
+{
+	void *addr;
+	int fd, ret;
+
+	fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
+	if (fd < 0) {
+		perror("Open failed");
+		exit(1);
+	}
+
+	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
+	if (addr == MAP_FAILED) {
+		perror("mmap");
+		unlink(FILE_NAME);
+		exit(1);
+	}
+
+	printf("Returned address is %p\n", addr);
+	check_bytes(addr);
+	write_bytes(addr);
+	ret = read_bytes(addr);
+
+	munmap(addr, LENGTH);
+	close(fd);
+	unlink(FILE_NAME);
+
+	return ret;
+}
diff --git a/tools/testing/selftests/vm/hugepage-shm.c b/tools/testing/selftests/vm/hugepage-shm.c
new file mode 100644
index 0000000..0d0ef4f
--- /dev/null
+++ b/tools/testing/selftests/vm/hugepage-shm.c
@@ -0,0 +1,100 @@
+/*
+ * hugepage-shm:
+ *
+ * Example of using huge page memory in a user application using Sys V shared
+ * memory system calls.  In this example the app is requesting 256MB of
+ * memory that is backed by huge pages.  The application uses the flag
+ * SHM_HUGETLB in the shmget system call to inform the kernel that it is
+ * requesting huge pages.
+ *
+ * For the ia64 architecture, the Linux kernel reserves Region number 4 for
+ * huge pages.  That means that if one requires a fixed address, a huge page
+ * aligned address starting with 0x800000... will be required.  If a fixed
+ * address is not required, the kernel will select an address in the proper
+ * range.
+ * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
+ *
+ * Note: The default shared memory limit is quite low on many kernels,
+ * you may need to increase it via:
+ *
+ * echo 268435456 > /proc/sys/kernel/shmmax
+ *
+ * This will increase the maximum size per shared memory segment to 256MB.
+ * The other limit that you will hit eventually is shmall which is the
+ * total amount of shared memory in pages. To set it to 16GB on a system
+ * with a 4kB pagesize do:
+ *
+ * echo 4194304 > /proc/sys/kernel/shmall
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/mman.h>
+
+#ifndef SHM_HUGETLB
+#define SHM_HUGETLB 04000
+#endif
+
+#define LENGTH (256UL*1024*1024)
+
+#define dprintf(x)  printf(x)
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define SHMAT_FLAGS (SHM_RND)
+#else
+#define ADDR (void *)(0x0UL)
+#define SHMAT_FLAGS (0)
+#endif
+
+int main(void)
+{
+	int shmid;
+	unsigned long i;
+	char *shmaddr;
+
+	shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
+	if (shmid < 0) {
+		perror("shmget");
+		exit(1);
+	}
+	printf("shmid: 0x%x\n", shmid);
+
+	shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
+	if (shmaddr == (char *)-1) {
+		perror("Shared memory attach failure");
+		shmctl(shmid, IPC_RMID, NULL);
+		exit(2);
+	}
+	printf("shmaddr: %p\n", shmaddr);
+
+	dprintf("Starting the writes:\n");
+	for (i = 0; i < LENGTH; i++) {
+		shmaddr[i] = (char)(i);
+		if (!(i % (1024 * 1024)))
+			dprintf(".");
+	}
+	dprintf("\n");
+
+	dprintf("Starting the Check...");
+	for (i = 0; i < LENGTH; i++)
+		if (shmaddr[i] != (char)i) {
+			printf("\nIndex %lu mismatched\n", i);
+			exit(3);
+		}
+	dprintf("Done.\n");
+
+	if (shmdt((const void *)shmaddr) != 0) {
+		perror("Detach failure");
+		shmctl(shmid, IPC_RMID, NULL);
+		exit(4);
+	}
+
+	shmctl(shmid, IPC_RMID, NULL);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/vm/map_hugetlb.c b/tools/testing/selftests/vm/map_hugetlb.c
new file mode 100644
index 0000000..ac56639
--- /dev/null
+++ b/tools/testing/selftests/vm/map_hugetlb.c
@@ -0,0 +1,79 @@
+/*
+ * Example of using hugepage memory in a user application using the mmap
+ * system call with MAP_HUGETLB flag.  Before running this program make
+ * sure the administrator has allocated enough default sized huge pages
+ * to cover the 256 MB allocation.
+ *
+ * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000... will need to be
+ * specified.  Specifying a fixed address is not required on ppc64, i386
+ * or x86_64.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define LENGTH (256UL*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+
+#ifndef MAP_HUGETLB
+#define MAP_HUGETLB 0x40000 /* arch specific */
+#endif
+
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define ADDR (void *)(0x8000000000000000UL)
+#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
+#else
+#define ADDR (void *)(0x0UL)
+#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
+#endif
+
+static void check_bytes(char *addr)
+{
+	printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+static void write_bytes(char *addr)
+{
+	unsigned long i;
+
+	for (i = 0; i < LENGTH; i++)
+		*(addr + i) = (char)i;
+}
+
+static int read_bytes(char *addr)
+{
+	unsigned long i;
+
+	check_bytes(addr);
+	for (i = 0; i < LENGTH; i++)
+		if (*(addr + i) != (char)i) {
+			printf("Mismatch at %lu\n", i);
+			return 1;
+		}
+	return 0;
+}
+
+int main(void)
+{
+	void *addr;
+	int ret;
+
+	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
+	if (addr == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+
+	printf("Returned address is %p\n", addr);
+	check_bytes(addr);
+	write_bytes(addr);
+	ret = read_bytes(addr);
+
+	munmap(addr, LENGTH);
+
+	return ret;
+}
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests
new file mode 100644
index 0000000..8b40bd5
--- /dev/null
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -0,0 +1,77 @@
+#!/bin/bash
+#please run as root
+
+#we need 256M, below is the size in kB
+needmem=262144
+mnt=./huge
+
+#get pagesize and freepages from /proc/meminfo
+while read name size unit; do
+	if [ "$name" = "HugePages_Free:" ]; then
+		freepgs=$size
+	fi
+	if [ "$name" = "Hugepagesize:" ]; then
+		pgsize=$size
+	fi
+done < /proc/meminfo
+
+#set proper nr_hugepages
+if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then
+	nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
+	needpgs=`expr $needmem / $pgsize`
+	if [ $freepgs -lt $needpgs ]; then
+		lackpgs=$(( $needpgs - $freepgs ))
+		echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
+		if [ $? -ne 0 ]; then
+			echo "Please run this test as root"
+			exit 1
+		fi
+	fi
+else
+	echo "no hugetlbfs support in kernel?"
+	exit 1
+fi
+
+mkdir $mnt
+mount -t hugetlbfs none $mnt
+
+echo "--------------------"
+echo "runing hugepage-mmap"
+echo "--------------------"
+./hugepage-mmap
+if [ $? -ne 0 ]; then
+	echo "[FAIL]"
+else
+	echo "[PASS]"
+fi
+
+shmmax=`cat /proc/sys/kernel/shmmax`
+shmall=`cat /proc/sys/kernel/shmall`
+echo 268435456 > /proc/sys/kernel/shmmax
+echo 4194304 > /proc/sys/kernel/shmall
+echo "--------------------"
+echo "runing hugepage-shm"
+echo "--------------------"
+./hugepage-shm
+if [ $? -ne 0 ]; then
+	echo "[FAIL]"
+else
+	echo "[PASS]"
+fi
+echo $shmmax > /proc/sys/kernel/shmmax
+echo $shmall > /proc/sys/kernel/shmall
+
+echo "--------------------"
+echo "runing map_hugetlb"
+echo "--------------------"
+./map_hugetlb
+if [ $? -ne 0 ]; then
+	echo "[FAIL]"
+else
+	echo "[PASS]"
+fi
+
+#cleanup
+umount $mnt
+rm -rf $mnt
+echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
diff --git a/tools/vm/Makefile b/tools/vm/Makefile
new file mode 100644
index 0000000..8e30e5c
--- /dev/null
+++ b/tools/vm/Makefile
@@ -0,0 +1,11 @@
+# Makefile for vm tools
+
+CC = $(CROSS_COMPILE)gcc
+CFLAGS = -Wall -Wextra
+
+all: page-types slabinfo
+%: %.c
+	$(CC) $(CFLAGS) -o $@ $^
+
+clean:
+	$(RM) page-types slabinfo
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
new file mode 100644
index 0000000..7dab7b25
--- /dev/null
+++ b/tools/vm/page-types.c
@@ -0,0 +1,1102 @@
+/*
+ * page-types: Tool for querying page flags
+ *
+ * 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; version 2.
+ *
+ * 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 find a copy of v2 of the GNU General Public License somewhere on
+ * your Linux system; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) 2009 Intel corporation
+ *
+ * Authors: Wu Fengguang <fengguang.wu@intel.com>
+ */
+
+#define _LARGEFILE64_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <getopt.h>
+#include <limits.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/mount.h>
+#include <sys/statfs.h>
+#include "../../include/linux/magic.h"
+
+
+#ifndef MAX_PATH
+# define MAX_PATH 256
+#endif
+
+#ifndef STR
+# define _STR(x) #x
+# define STR(x) _STR(x)
+#endif
+
+/*
+ * pagemap kernel ABI bits
+ */
+
+#define PM_ENTRY_BYTES      sizeof(uint64_t)
+#define PM_STATUS_BITS      3
+#define PM_STATUS_OFFSET    (64 - PM_STATUS_BITS)
+#define PM_STATUS_MASK      (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
+#define PM_STATUS(nr)       (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK)
+#define PM_PSHIFT_BITS      6
+#define PM_PSHIFT_OFFSET    (PM_STATUS_OFFSET - PM_PSHIFT_BITS)
+#define PM_PSHIFT_MASK      (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET)
+#define PM_PSHIFT(x)        (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK)
+#define PM_PFRAME_MASK      ((1LL << PM_PSHIFT_OFFSET) - 1)
+#define PM_PFRAME(x)        ((x) & PM_PFRAME_MASK)
+
+#define PM_PRESENT          PM_STATUS(4LL)
+#define PM_SWAP             PM_STATUS(2LL)
+
+
+/*
+ * kernel page flags
+ */
+
+#define KPF_BYTES		8
+#define PROC_KPAGEFLAGS		"/proc/kpageflags"
+
+/* copied from kpageflags_read() */
+#define KPF_LOCKED		0
+#define KPF_ERROR		1
+#define KPF_REFERENCED		2
+#define KPF_UPTODATE		3
+#define KPF_DIRTY		4
+#define KPF_LRU			5
+#define KPF_ACTIVE		6
+#define KPF_SLAB		7
+#define KPF_WRITEBACK		8
+#define KPF_RECLAIM		9
+#define KPF_BUDDY		10
+
+/* [11-20] new additions in 2.6.31 */
+#define KPF_MMAP		11
+#define KPF_ANON		12
+#define KPF_SWAPCACHE		13
+#define KPF_SWAPBACKED		14
+#define KPF_COMPOUND_HEAD	15
+#define KPF_COMPOUND_TAIL	16
+#define KPF_HUGE		17
+#define KPF_UNEVICTABLE		18
+#define KPF_HWPOISON		19
+#define KPF_NOPAGE		20
+#define KPF_KSM			21
+#define KPF_THP			22
+
+/* [32-] kernel hacking assistances */
+#define KPF_RESERVED		32
+#define KPF_MLOCKED		33
+#define KPF_MAPPEDTODISK	34
+#define KPF_PRIVATE		35
+#define KPF_PRIVATE_2		36
+#define KPF_OWNER_PRIVATE	37
+#define KPF_ARCH		38
+#define KPF_UNCACHED		39
+
+/* [48-] take some arbitrary free slots for expanding overloaded flags
+ * not part of kernel API
+ */
+#define KPF_READAHEAD		48
+#define KPF_SLOB_FREE		49
+#define KPF_SLUB_FROZEN		50
+#define KPF_SLUB_DEBUG		51
+
+#define KPF_ALL_BITS		((uint64_t)~0ULL)
+#define KPF_HACKERS_BITS	(0xffffULL << 32)
+#define KPF_OVERLOADED_BITS	(0xffffULL << 48)
+#define BIT(name)		(1ULL << KPF_##name)
+#define BITS_COMPOUND		(BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL))
+
+static const char * const page_flag_names[] = {
+	[KPF_LOCKED]		= "L:locked",
+	[KPF_ERROR]		= "E:error",
+	[KPF_REFERENCED]	= "R:referenced",
+	[KPF_UPTODATE]		= "U:uptodate",
+	[KPF_DIRTY]		= "D:dirty",
+	[KPF_LRU]		= "l:lru",
+	[KPF_ACTIVE]		= "A:active",
+	[KPF_SLAB]		= "S:slab",
+	[KPF_WRITEBACK]		= "W:writeback",
+	[KPF_RECLAIM]		= "I:reclaim",
+	[KPF_BUDDY]		= "B:buddy",
+
+	[KPF_MMAP]		= "M:mmap",
+	[KPF_ANON]		= "a:anonymous",
+	[KPF_SWAPCACHE]		= "s:swapcache",
+	[KPF_SWAPBACKED]	= "b:swapbacked",
+	[KPF_COMPOUND_HEAD]	= "H:compound_head",
+	[KPF_COMPOUND_TAIL]	= "T:compound_tail",
+	[KPF_HUGE]		= "G:huge",
+	[KPF_UNEVICTABLE]	= "u:unevictable",
+	[KPF_HWPOISON]		= "X:hwpoison",
+	[KPF_NOPAGE]		= "n:nopage",
+	[KPF_KSM]		= "x:ksm",
+	[KPF_THP]		= "t:thp",
+
+	[KPF_RESERVED]		= "r:reserved",
+	[KPF_MLOCKED]		= "m:mlocked",
+	[KPF_MAPPEDTODISK]	= "d:mappedtodisk",
+	[KPF_PRIVATE]		= "P:private",
+	[KPF_PRIVATE_2]		= "p:private_2",
+	[KPF_OWNER_PRIVATE]	= "O:owner_private",
+	[KPF_ARCH]		= "h:arch",
+	[KPF_UNCACHED]		= "c:uncached",
+
+	[KPF_READAHEAD]		= "I:readahead",
+	[KPF_SLOB_FREE]		= "P:slob_free",
+	[KPF_SLUB_FROZEN]	= "A:slub_frozen",
+	[KPF_SLUB_DEBUG]	= "E:slub_debug",
+};
+
+
+static const char * const debugfs_known_mountpoints[] = {
+	"/sys/kernel/debug",
+	"/debug",
+	0,
+};
+
+/*
+ * data structures
+ */
+
+static int		opt_raw;	/* for kernel developers */
+static int		opt_list;	/* list pages (in ranges) */
+static int		opt_no_summary;	/* don't show summary */
+static pid_t		opt_pid;	/* process to walk */
+
+#define MAX_ADDR_RANGES	1024
+static int		nr_addr_ranges;
+static unsigned long	opt_offset[MAX_ADDR_RANGES];
+static unsigned long	opt_size[MAX_ADDR_RANGES];
+
+#define MAX_VMAS	10240
+static int		nr_vmas;
+static unsigned long	pg_start[MAX_VMAS];
+static unsigned long	pg_end[MAX_VMAS];
+
+#define MAX_BIT_FILTERS	64
+static int		nr_bit_filters;
+static uint64_t		opt_mask[MAX_BIT_FILTERS];
+static uint64_t		opt_bits[MAX_BIT_FILTERS];
+
+static int		page_size;
+
+static int		pagemap_fd;
+static int		kpageflags_fd;
+
+static int		opt_hwpoison;
+static int		opt_unpoison;
+
+static char		hwpoison_debug_fs[MAX_PATH+1];
+static int		hwpoison_inject_fd;
+static int		hwpoison_forget_fd;
+
+#define HASH_SHIFT	13
+#define HASH_SIZE	(1 << HASH_SHIFT)
+#define HASH_MASK	(HASH_SIZE - 1)
+#define HASH_KEY(flags)	(flags & HASH_MASK)
+
+static unsigned long	total_pages;
+static unsigned long	nr_pages[HASH_SIZE];
+static uint64_t		page_flags[HASH_SIZE];
+
+
+/*
+ * helper functions
+ */
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define min_t(type, x, y) ({			\
+	type __min1 = (x);			\
+	type __min2 = (y);			\
+	__min1 < __min2 ? __min1 : __min2; })
+
+#define max_t(type, x, y) ({			\
+	type __max1 = (x);			\
+	type __max2 = (y);			\
+	__max1 > __max2 ? __max1 : __max2; })
+
+static unsigned long pages2mb(unsigned long pages)
+{
+	return (pages * page_size) >> 20;
+}
+
+static void fatal(const char *x, ...)
+{
+	va_list ap;
+
+	va_start(ap, x);
+	vfprintf(stderr, x, ap);
+	va_end(ap);
+	exit(EXIT_FAILURE);
+}
+
+static int checked_open(const char *pathname, int flags)
+{
+	int fd = open(pathname, flags);
+
+	if (fd < 0) {
+		perror(pathname);
+		exit(EXIT_FAILURE);
+	}
+
+	return fd;
+}
+
+/*
+ * pagemap/kpageflags routines
+ */
+
+static unsigned long do_u64_read(int fd, char *name,
+				 uint64_t *buf,
+				 unsigned long index,
+				 unsigned long count)
+{
+	long bytes;
+
+	if (index > ULONG_MAX / 8)
+		fatal("index overflow: %lu\n", index);
+
+	if (lseek(fd, index * 8, SEEK_SET) < 0) {
+		perror(name);
+		exit(EXIT_FAILURE);
+	}
+
+	bytes = read(fd, buf, count * 8);
+	if (bytes < 0) {
+		perror(name);
+		exit(EXIT_FAILURE);
+	}
+	if (bytes % 8)
+		fatal("partial read: %lu bytes\n", bytes);
+
+	return bytes / 8;
+}
+
+static unsigned long kpageflags_read(uint64_t *buf,
+				     unsigned long index,
+				     unsigned long pages)
+{
+	return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages);
+}
+
+static unsigned long pagemap_read(uint64_t *buf,
+				  unsigned long index,
+				  unsigned long pages)
+{
+	return do_u64_read(pagemap_fd, "/proc/pid/pagemap", buf, index, pages);
+}
+
+static unsigned long pagemap_pfn(uint64_t val)
+{
+	unsigned long pfn;
+
+	if (val & PM_PRESENT)
+		pfn = PM_PFRAME(val);
+	else
+		pfn = 0;
+
+	return pfn;
+}
+
+
+/*
+ * page flag names
+ */
+
+static char *page_flag_name(uint64_t flags)
+{
+	static char buf[65];
+	int present;
+	int i, j;
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+		present = (flags >> i) & 1;
+		if (!page_flag_names[i]) {
+			if (present)
+				fatal("unknown flag bit %d\n", i);
+			continue;
+		}
+		buf[j++] = present ? page_flag_names[i][0] : '_';
+	}
+
+	return buf;
+}
+
+static char *page_flag_longname(uint64_t flags)
+{
+	static char buf[1024];
+	int i, n;
+
+	for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+		if (!page_flag_names[i])
+			continue;
+		if ((flags >> i) & 1)
+			n += snprintf(buf + n, sizeof(buf) - n, "%s,",
+					page_flag_names[i] + 2);
+	}
+	if (n)
+		n--;
+	buf[n] = '\0';
+
+	return buf;
+}
+
+
+/*
+ * page list and summary
+ */
+
+static void show_page_range(unsigned long voffset,
+			    unsigned long offset, uint64_t flags)
+{
+	static uint64_t      flags0;
+	static unsigned long voff;
+	static unsigned long index;
+	static unsigned long count;
+
+	if (flags == flags0 && offset == index + count &&
+	    (!opt_pid || voffset == voff + count)) {
+		count++;
+		return;
+	}
+
+	if (count) {
+		if (opt_pid)
+			printf("%lx\t", voff);
+		printf("%lx\t%lx\t%s\n",
+				index, count, page_flag_name(flags0));
+	}
+
+	flags0 = flags;
+	index  = offset;
+	voff   = voffset;
+	count  = 1;
+}
+
+static void show_page(unsigned long voffset,
+		      unsigned long offset, uint64_t flags)
+{
+	if (opt_pid)
+		printf("%lx\t", voffset);
+	printf("%lx\t%s\n", offset, page_flag_name(flags));
+}
+
+static void show_summary(void)
+{
+	int i;
+
+	printf("             flags\tpage-count       MB"
+		"  symbolic-flags\t\t\tlong-symbolic-flags\n");
+
+	for (i = 0; i < ARRAY_SIZE(nr_pages); i++) {
+		if (nr_pages[i])
+			printf("0x%016llx\t%10lu %8lu  %s\t%s\n",
+				(unsigned long long)page_flags[i],
+				nr_pages[i],
+				pages2mb(nr_pages[i]),
+				page_flag_name(page_flags[i]),
+				page_flag_longname(page_flags[i]));
+	}
+
+	printf("             total\t%10lu %8lu\n",
+			total_pages, pages2mb(total_pages));
+}
+
+
+/*
+ * page flag filters
+ */
+
+static int bit_mask_ok(uint64_t flags)
+{
+	int i;
+
+	for (i = 0; i < nr_bit_filters; i++) {
+		if (opt_bits[i] == KPF_ALL_BITS) {
+			if ((flags & opt_mask[i]) == 0)
+				return 0;
+		} else {
+			if ((flags & opt_mask[i]) != opt_bits[i])
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+static uint64_t expand_overloaded_flags(uint64_t flags)
+{
+	/* SLOB/SLUB overload several page flags */
+	if (flags & BIT(SLAB)) {
+		if (flags & BIT(PRIVATE))
+			flags ^= BIT(PRIVATE) | BIT(SLOB_FREE);
+		if (flags & BIT(ACTIVE))
+			flags ^= BIT(ACTIVE) | BIT(SLUB_FROZEN);
+		if (flags & BIT(ERROR))
+			flags ^= BIT(ERROR) | BIT(SLUB_DEBUG);
+	}
+
+	/* PG_reclaim is overloaded as PG_readahead in the read path */
+	if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM))
+		flags ^= BIT(RECLAIM) | BIT(READAHEAD);
+
+	return flags;
+}
+
+static uint64_t well_known_flags(uint64_t flags)
+{
+	/* hide flags intended only for kernel hacker */
+	flags &= ~KPF_HACKERS_BITS;
+
+	/* hide non-hugeTLB compound pages */
+	if ((flags & BITS_COMPOUND) && !(flags & BIT(HUGE)))
+		flags &= ~BITS_COMPOUND;
+
+	return flags;
+}
+
+static uint64_t kpageflags_flags(uint64_t flags)
+{
+	flags = expand_overloaded_flags(flags);
+
+	if (!opt_raw)
+		flags = well_known_flags(flags);
+
+	return flags;
+}
+
+/* verify that a mountpoint is actually a debugfs instance */
+static int debugfs_valid_mountpoint(const char *debugfs)
+{
+	struct statfs st_fs;
+
+	if (statfs(debugfs, &st_fs) < 0)
+		return -ENOENT;
+	else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
+		return -ENOENT;
+
+	return 0;
+}
+
+/* find the path to the mounted debugfs */
+static const char *debugfs_find_mountpoint(void)
+{
+	const char **ptr;
+	char type[100];
+	FILE *fp;
+
+	ptr = debugfs_known_mountpoints;
+	while (*ptr) {
+		if (debugfs_valid_mountpoint(*ptr) == 0) {
+			strcpy(hwpoison_debug_fs, *ptr);
+			return hwpoison_debug_fs;
+		}
+		ptr++;
+	}
+
+	/* give up and parse /proc/mounts */
+	fp = fopen("/proc/mounts", "r");
+	if (fp == NULL)
+		perror("Can't open /proc/mounts for read");
+
+	while (fscanf(fp, "%*s %"
+		      STR(MAX_PATH)
+		      "s %99s %*s %*d %*d\n",
+		      hwpoison_debug_fs, type) == 2) {
+		if (strcmp(type, "debugfs") == 0)
+			break;
+	}
+	fclose(fp);
+
+	if (strcmp(type, "debugfs") != 0)
+		return NULL;
+
+	return hwpoison_debug_fs;
+}
+
+/* mount the debugfs somewhere if it's not mounted */
+
+static void debugfs_mount(void)
+{
+	const char **ptr;
+
+	/* see if it's already mounted */
+	if (debugfs_find_mountpoint())
+		return;
+
+	ptr = debugfs_known_mountpoints;
+	while (*ptr) {
+		if (mount(NULL, *ptr, "debugfs", 0, NULL) == 0) {
+			/* save the mountpoint */
+			strcpy(hwpoison_debug_fs, *ptr);
+			break;
+		}
+		ptr++;
+	}
+
+	if (*ptr == NULL) {
+		perror("mount debugfs");
+		exit(EXIT_FAILURE);
+	}
+}
+
+/*
+ * page actions
+ */
+
+static void prepare_hwpoison_fd(void)
+{
+	char buf[MAX_PATH + 1];
+
+	debugfs_mount();
+
+	if (opt_hwpoison && !hwpoison_inject_fd) {
+		snprintf(buf, MAX_PATH, "%s/hwpoison/corrupt-pfn",
+			hwpoison_debug_fs);
+		hwpoison_inject_fd = checked_open(buf, O_WRONLY);
+	}
+
+	if (opt_unpoison && !hwpoison_forget_fd) {
+		snprintf(buf, MAX_PATH, "%s/hwpoison/unpoison-pfn",
+			hwpoison_debug_fs);
+		hwpoison_forget_fd = checked_open(buf, O_WRONLY);
+	}
+}
+
+static int hwpoison_page(unsigned long offset)
+{
+	char buf[100];
+	int len;
+
+	len = sprintf(buf, "0x%lx\n", offset);
+	len = write(hwpoison_inject_fd, buf, len);
+	if (len < 0) {
+		perror("hwpoison inject");
+		return len;
+	}
+	return 0;
+}
+
+static int unpoison_page(unsigned long offset)
+{
+	char buf[100];
+	int len;
+
+	len = sprintf(buf, "0x%lx\n", offset);
+	len = write(hwpoison_forget_fd, buf, len);
+	if (len < 0) {
+		perror("hwpoison forget");
+		return len;
+	}
+	return 0;
+}
+
+/*
+ * page frame walker
+ */
+
+static int hash_slot(uint64_t flags)
+{
+	int k = HASH_KEY(flags);
+	int i;
+
+	/* Explicitly reserve slot 0 for flags 0: the following logic
+	 * cannot distinguish an unoccupied slot from slot (flags==0).
+	 */
+	if (flags == 0)
+		return 0;
+
+	/* search through the remaining (HASH_SIZE-1) slots */
+	for (i = 1; i < ARRAY_SIZE(page_flags); i++, k++) {
+		if (!k || k >= ARRAY_SIZE(page_flags))
+			k = 1;
+		if (page_flags[k] == 0) {
+			page_flags[k] = flags;
+			return k;
+		}
+		if (page_flags[k] == flags)
+			return k;
+	}
+
+	fatal("hash table full: bump up HASH_SHIFT?\n");
+	exit(EXIT_FAILURE);
+}
+
+static void add_page(unsigned long voffset,
+		     unsigned long offset, uint64_t flags)
+{
+	flags = kpageflags_flags(flags);
+
+	if (!bit_mask_ok(flags))
+		return;
+
+	if (opt_hwpoison)
+		hwpoison_page(offset);
+	if (opt_unpoison)
+		unpoison_page(offset);
+
+	if (opt_list == 1)
+		show_page_range(voffset, offset, flags);
+	else if (opt_list == 2)
+		show_page(voffset, offset, flags);
+
+	nr_pages[hash_slot(flags)]++;
+	total_pages++;
+}
+
+#define KPAGEFLAGS_BATCH	(64 << 10)	/* 64k pages */
+static void walk_pfn(unsigned long voffset,
+		     unsigned long index,
+		     unsigned long count)
+{
+	uint64_t buf[KPAGEFLAGS_BATCH];
+	unsigned long batch;
+	long pages;
+	unsigned long i;
+
+	while (count) {
+		batch = min_t(unsigned long, count, KPAGEFLAGS_BATCH);
+		pages = kpageflags_read(buf, index, batch);
+		if (pages == 0)
+			break;
+
+		for (i = 0; i < pages; i++)
+			add_page(voffset + i, index + i, buf[i]);
+
+		index += pages;
+		count -= pages;
+	}
+}
+
+#define PAGEMAP_BATCH	(64 << 10)
+static void walk_vma(unsigned long index, unsigned long count)
+{
+	uint64_t buf[PAGEMAP_BATCH];
+	unsigned long batch;
+	unsigned long pages;
+	unsigned long pfn;
+	unsigned long i;
+
+	while (count) {
+		batch = min_t(unsigned long, count, PAGEMAP_BATCH);
+		pages = pagemap_read(buf, index, batch);
+		if (pages == 0)
+			break;
+
+		for (i = 0; i < pages; i++) {
+			pfn = pagemap_pfn(buf[i]);
+			if (pfn)
+				walk_pfn(index + i, pfn, 1);
+		}
+
+		index += pages;
+		count -= pages;
+	}
+}
+
+static void walk_task(unsigned long index, unsigned long count)
+{
+	const unsigned long end = index + count;
+	unsigned long start;
+	int i = 0;
+
+	while (index < end) {
+
+		while (pg_end[i] <= index)
+			if (++i >= nr_vmas)
+				return;
+		if (pg_start[i] >= end)
+			return;
+
+		start = max_t(unsigned long, pg_start[i], index);
+		index = min_t(unsigned long, pg_end[i], end);
+
+		assert(start < index);
+		walk_vma(start, index - start);
+	}
+}
+
+static void add_addr_range(unsigned long offset, unsigned long size)
+{
+	if (nr_addr_ranges >= MAX_ADDR_RANGES)
+		fatal("too many addr ranges\n");
+
+	opt_offset[nr_addr_ranges] = offset;
+	opt_size[nr_addr_ranges] = min_t(unsigned long, size, ULONG_MAX-offset);
+	nr_addr_ranges++;
+}
+
+static void walk_addr_ranges(void)
+{
+	int i;
+
+	kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
+
+	if (!nr_addr_ranges)
+		add_addr_range(0, ULONG_MAX);
+
+	for (i = 0; i < nr_addr_ranges; i++)
+		if (!opt_pid)
+			walk_pfn(0, opt_offset[i], opt_size[i]);
+		else
+			walk_task(opt_offset[i], opt_size[i]);
+
+	close(kpageflags_fd);
+}
+
+
+/*
+ * user interface
+ */
+
+static const char *page_flag_type(uint64_t flag)
+{
+	if (flag & KPF_HACKERS_BITS)
+		return "(r)";
+	if (flag & KPF_OVERLOADED_BITS)
+		return "(o)";
+	return "   ";
+}
+
+static void usage(void)
+{
+	int i, j;
+
+	printf(
+"page-types [options]\n"
+"            -r|--raw                   Raw mode, for kernel developers\n"
+"            -d|--describe flags        Describe flags\n"
+"            -a|--addr    addr-spec     Walk a range of pages\n"
+"            -b|--bits    bits-spec     Walk pages with specified bits\n"
+"            -p|--pid     pid           Walk process address space\n"
+#if 0 /* planned features */
+"            -f|--file    filename      Walk file address space\n"
+#endif
+"            -l|--list                  Show page details in ranges\n"
+"            -L|--list-each             Show page details one by one\n"
+"            -N|--no-summary            Don't show summary info\n"
+"            -X|--hwpoison              hwpoison pages\n"
+"            -x|--unpoison              unpoison pages\n"
+"            -h|--help                  Show this usage message\n"
+"flags:\n"
+"            0x10                       bitfield format, e.g.\n"
+"            anon                       bit-name, e.g.\n"
+"            0x10,anon                  comma-separated list, e.g.\n"
+"addr-spec:\n"
+"            N                          one page at offset N (unit: pages)\n"
+"            N+M                        pages range from N to N+M-1\n"
+"            N,M                        pages range from N to M-1\n"
+"            N,                         pages range from N to end\n"
+"            ,M                         pages range from 0 to M-1\n"
+"bits-spec:\n"
+"            bit1,bit2                  (flags & (bit1|bit2)) != 0\n"
+"            bit1,bit2=bit1             (flags & (bit1|bit2)) == bit1\n"
+"            bit1,~bit2                 (flags & (bit1|bit2)) == bit1\n"
+"            =bit1,bit2                 flags == (bit1|bit2)\n"
+"bit-names:\n"
+	);
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+		if (!page_flag_names[i])
+			continue;
+		printf("%16s%s", page_flag_names[i] + 2,
+				 page_flag_type(1ULL << i));
+		if (++j > 3) {
+			j = 0;
+			putchar('\n');
+		}
+	}
+	printf("\n                                   "
+		"(r) raw mode bits  (o) overloaded bits\n");
+}
+
+static unsigned long long parse_number(const char *str)
+{
+	unsigned long long n;
+
+	n = strtoll(str, NULL, 0);
+
+	if (n == 0 && str[0] != '0')
+		fatal("invalid name or number: %s\n", str);
+
+	return n;
+}
+
+static void parse_pid(const char *str)
+{
+	FILE *file;
+	char buf[5000];
+
+	opt_pid = parse_number(str);
+
+	sprintf(buf, "/proc/%d/pagemap", opt_pid);
+	pagemap_fd = checked_open(buf, O_RDONLY);
+
+	sprintf(buf, "/proc/%d/maps", opt_pid);
+	file = fopen(buf, "r");
+	if (!file) {
+		perror(buf);
+		exit(EXIT_FAILURE);
+	}
+
+	while (fgets(buf, sizeof(buf), file) != NULL) {
+		unsigned long vm_start;
+		unsigned long vm_end;
+		unsigned long long pgoff;
+		int major, minor;
+		char r, w, x, s;
+		unsigned long ino;
+		int n;
+
+		n = sscanf(buf, "%lx-%lx %c%c%c%c %llx %x:%x %lu",
+			   &vm_start,
+			   &vm_end,
+			   &r, &w, &x, &s,
+			   &pgoff,
+			   &major, &minor,
+			   &ino);
+		if (n < 10) {
+			fprintf(stderr, "unexpected line: %s\n", buf);
+			continue;
+		}
+		pg_start[nr_vmas] = vm_start / page_size;
+		pg_end[nr_vmas] = vm_end / page_size;
+		if (++nr_vmas >= MAX_VMAS) {
+			fprintf(stderr, "too many VMAs\n");
+			break;
+		}
+	}
+	fclose(file);
+}
+
+static void parse_file(const char *name)
+{
+}
+
+static void parse_addr_range(const char *optarg)
+{
+	unsigned long offset;
+	unsigned long size;
+	char *p;
+
+	p = strchr(optarg, ',');
+	if (!p)
+		p = strchr(optarg, '+');
+
+	if (p == optarg) {
+		offset = 0;
+		size   = parse_number(p + 1);
+	} else if (p) {
+		offset = parse_number(optarg);
+		if (p[1] == '\0')
+			size = ULONG_MAX;
+		else {
+			size = parse_number(p + 1);
+			if (*p == ',') {
+				if (size < offset)
+					fatal("invalid range: %lu,%lu\n",
+							offset, size);
+				size -= offset;
+			}
+		}
+	} else {
+		offset = parse_number(optarg);
+		size   = 1;
+	}
+
+	add_addr_range(offset, size);
+}
+
+static void add_bits_filter(uint64_t mask, uint64_t bits)
+{
+	if (nr_bit_filters >= MAX_BIT_FILTERS)
+		fatal("too much bit filters\n");
+
+	opt_mask[nr_bit_filters] = mask;
+	opt_bits[nr_bit_filters] = bits;
+	nr_bit_filters++;
+}
+
+static uint64_t parse_flag_name(const char *str, int len)
+{
+	int i;
+
+	if (!*str || !len)
+		return 0;
+
+	if (len <= 8 && !strncmp(str, "compound", len))
+		return BITS_COMPOUND;
+
+	for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) {
+		if (!page_flag_names[i])
+			continue;
+		if (!strncmp(str, page_flag_names[i] + 2, len))
+			return 1ULL << i;
+	}
+
+	return parse_number(str);
+}
+
+static uint64_t parse_flag_names(const char *str, int all)
+{
+	const char *p    = str;
+	uint64_t   flags = 0;
+
+	while (1) {
+		if (*p == ',' || *p == '=' || *p == '\0') {
+			if ((*str != '~') || (*str == '~' && all && *++str))
+				flags |= parse_flag_name(str, p - str);
+			if (*p != ',')
+				break;
+			str = p + 1;
+		}
+		p++;
+	}
+
+	return flags;
+}
+
+static void parse_bits_mask(const char *optarg)
+{
+	uint64_t mask;
+	uint64_t bits;
+	const char *p;
+
+	p = strchr(optarg, '=');
+	if (p == optarg) {
+		mask = KPF_ALL_BITS;
+		bits = parse_flag_names(p + 1, 0);
+	} else if (p) {
+		mask = parse_flag_names(optarg, 0);
+		bits = parse_flag_names(p + 1, 0);
+	} else if (strchr(optarg, '~')) {
+		mask = parse_flag_names(optarg, 1);
+		bits = parse_flag_names(optarg, 0);
+	} else {
+		mask = parse_flag_names(optarg, 0);
+		bits = KPF_ALL_BITS;
+	}
+
+	add_bits_filter(mask, bits);
+}
+
+static void describe_flags(const char *optarg)
+{
+	uint64_t flags = parse_flag_names(optarg, 0);
+
+	printf("0x%016llx\t%s\t%s\n",
+		(unsigned long long)flags,
+		page_flag_name(flags),
+		page_flag_longname(flags));
+}
+
+static const struct option opts[] = {
+	{ "raw"       , 0, NULL, 'r' },
+	{ "pid"       , 1, NULL, 'p' },
+	{ "file"      , 1, NULL, 'f' },
+	{ "addr"      , 1, NULL, 'a' },
+	{ "bits"      , 1, NULL, 'b' },
+	{ "describe"  , 1, NULL, 'd' },
+	{ "list"      , 0, NULL, 'l' },
+	{ "list-each" , 0, NULL, 'L' },
+	{ "no-summary", 0, NULL, 'N' },
+	{ "hwpoison"  , 0, NULL, 'X' },
+	{ "unpoison"  , 0, NULL, 'x' },
+	{ "help"      , 0, NULL, 'h' },
+	{ NULL        , 0, NULL, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+	int c;
+
+	page_size = getpagesize();
+
+	while ((c = getopt_long(argc, argv,
+				"rp:f:a:b:d:lLNXxh", opts, NULL)) != -1) {
+		switch (c) {
+		case 'r':
+			opt_raw = 1;
+			break;
+		case 'p':
+			parse_pid(optarg);
+			break;
+		case 'f':
+			parse_file(optarg);
+			break;
+		case 'a':
+			parse_addr_range(optarg);
+			break;
+		case 'b':
+			parse_bits_mask(optarg);
+			break;
+		case 'd':
+			describe_flags(optarg);
+			exit(0);
+		case 'l':
+			opt_list = 1;
+			break;
+		case 'L':
+			opt_list = 2;
+			break;
+		case 'N':
+			opt_no_summary = 1;
+			break;
+		case 'X':
+			opt_hwpoison = 1;
+			prepare_hwpoison_fd();
+			break;
+		case 'x':
+			opt_unpoison = 1;
+			prepare_hwpoison_fd();
+			break;
+		case 'h':
+			usage();
+			exit(0);
+		default:
+			usage();
+			exit(1);
+		}
+	}
+
+	if (opt_list && opt_pid)
+		printf("voffset\t");
+	if (opt_list == 1)
+		printf("offset\tlen\tflags\n");
+	if (opt_list == 2)
+		printf("offset\tflags\n");
+
+	walk_addr_ranges();
+
+	if (opt_list == 1)
+		show_page_range(0, 0, 0);  /* drain the buffer */
+
+	if (opt_no_summary)
+		return 0;
+
+	if (opt_list)
+		printf("\n\n");
+
+	show_summary();
+
+	return 0;
+}
diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
new file mode 100644
index 0000000..164cbcf
--- /dev/null
+++ b/tools/vm/slabinfo.c
@@ -0,0 +1,1393 @@
+/*
+ * Slabinfo: Tool to get reports about slabs
+ *
+ * (C) 2007 sgi, Christoph Lameter
+ * (C) 2011 Linux Foundation, Christoph Lameter
+ *
+ * Compile with:
+ *
+ * gcc -o slabinfo slabinfo.c
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <strings.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <regex.h>
+#include <errno.h>
+
+#define MAX_SLABS 500
+#define MAX_ALIASES 500
+#define MAX_NODES 1024
+
+struct slabinfo {
+	char *name;
+	int alias;
+	int refs;
+	int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu;
+	int hwcache_align, object_size, objs_per_slab;
+	int sanity_checks, slab_size, store_user, trace;
+	int order, poison, reclaim_account, red_zone;
+	unsigned long partial, objects, slabs, objects_partial, objects_total;
+	unsigned long alloc_fastpath, alloc_slowpath;
+	unsigned long free_fastpath, free_slowpath;
+	unsigned long free_frozen, free_add_partial, free_remove_partial;
+	unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill;
+	unsigned long cpuslab_flush, deactivate_full, deactivate_empty;
+	unsigned long deactivate_to_head, deactivate_to_tail;
+	unsigned long deactivate_remote_frees, order_fallback;
+	unsigned long cmpxchg_double_cpu_fail, cmpxchg_double_fail;
+	unsigned long alloc_node_mismatch, deactivate_bypass;
+	unsigned long cpu_partial_alloc, cpu_partial_free;
+	int numa[MAX_NODES];
+	int numa_partial[MAX_NODES];
+} slabinfo[MAX_SLABS];
+
+struct aliasinfo {
+	char *name;
+	char *ref;
+	struct slabinfo *slab;
+} aliasinfo[MAX_ALIASES];
+
+int slabs = 0;
+int actual_slabs = 0;
+int aliases = 0;
+int alias_targets = 0;
+int highest_node = 0;
+
+char buffer[4096];
+
+int show_empty = 0;
+int show_report = 0;
+int show_alias = 0;
+int show_slab = 0;
+int skip_zero = 1;
+int show_numa = 0;
+int show_track = 0;
+int show_first_alias = 0;
+int validate = 0;
+int shrink = 0;
+int show_inverted = 0;
+int show_single_ref = 0;
+int show_totals = 0;
+int sort_size = 0;
+int sort_active = 0;
+int set_debug = 0;
+int show_ops = 0;
+int show_activity = 0;
+
+/* Debug options */
+int sanity = 0;
+int redzone = 0;
+int poison = 0;
+int tracking = 0;
+int tracing = 0;
+
+int page_size;
+
+regex_t pattern;
+
+static void fatal(const char *x, ...)
+{
+	va_list ap;
+
+	va_start(ap, x);
+	vfprintf(stderr, x, ap);
+	va_end(ap);
+	exit(EXIT_FAILURE);
+}
+
+static void usage(void)
+{
+	printf("slabinfo 4/15/2011. (c) 2007 sgi/(c) 2011 Linux Foundation.\n\n"
+		"slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
+		"-a|--aliases           Show aliases\n"
+		"-A|--activity          Most active slabs first\n"
+		"-d<options>|--debug=<options> Set/Clear Debug options\n"
+		"-D|--display-active    Switch line format to activity\n"
+		"-e|--empty             Show empty slabs\n"
+		"-f|--first-alias       Show first alias\n"
+		"-h|--help              Show usage information\n"
+		"-i|--inverted          Inverted list\n"
+		"-l|--slabs             Show slabs\n"
+		"-n|--numa              Show NUMA information\n"
+		"-o|--ops		Show kmem_cache_ops\n"
+		"-s|--shrink            Shrink slabs\n"
+		"-r|--report		Detailed report on single slabs\n"
+		"-S|--Size              Sort by size\n"
+		"-t|--tracking          Show alloc/free information\n"
+		"-T|--Totals            Show summary information\n"
+		"-v|--validate          Validate slabs\n"
+		"-z|--zero              Include empty slabs\n"
+		"-1|--1ref              Single reference\n"
+		"\nValid debug options (FZPUT may be combined)\n"
+		"a / A          Switch on all debug options (=FZUP)\n"
+		"-              Switch off all debug options\n"
+		"f / F          Sanity Checks (SLAB_DEBUG_FREE)\n"
+		"z / Z          Redzoning\n"
+		"p / P          Poisoning\n"
+		"u / U          Tracking\n"
+		"t / T          Tracing\n"
+	);
+}
+
+static unsigned long read_obj(const char *name)
+{
+	FILE *f = fopen(name, "r");
+
+	if (!f)
+		buffer[0] = 0;
+	else {
+		if (!fgets(buffer, sizeof(buffer), f))
+			buffer[0] = 0;
+		fclose(f);
+		if (buffer[strlen(buffer)] == '\n')
+			buffer[strlen(buffer)] = 0;
+	}
+	return strlen(buffer);
+}
+
+
+/*
+ * Get the contents of an attribute
+ */
+static unsigned long get_obj(const char *name)
+{
+	if (!read_obj(name))
+		return 0;
+
+	return atol(buffer);
+}
+
+static unsigned long get_obj_and_str(const char *name, char **x)
+{
+	unsigned long result = 0;
+	char *p;
+
+	*x = NULL;
+
+	if (!read_obj(name)) {
+		x = NULL;
+		return 0;
+	}
+	result = strtoul(buffer, &p, 10);
+	while (*p == ' ')
+		p++;
+	if (*p)
+		*x = strdup(p);
+	return result;
+}
+
+static void set_obj(struct slabinfo *s, const char *name, int n)
+{
+	char x[100];
+	FILE *f;
+
+	snprintf(x, 100, "%s/%s", s->name, name);
+	f = fopen(x, "w");
+	if (!f)
+		fatal("Cannot write to %s\n", x);
+
+	fprintf(f, "%d\n", n);
+	fclose(f);
+}
+
+static unsigned long read_slab_obj(struct slabinfo *s, const char *name)
+{
+	char x[100];
+	FILE *f;
+	size_t l;
+
+	snprintf(x, 100, "%s/%s", s->name, name);
+	f = fopen(x, "r");
+	if (!f) {
+		buffer[0] = 0;
+		l = 0;
+	} else {
+		l = fread(buffer, 1, sizeof(buffer), f);
+		buffer[l] = 0;
+		fclose(f);
+	}
+	return l;
+}
+
+
+/*
+ * Put a size string together
+ */
+static int store_size(char *buffer, unsigned long value)
+{
+	unsigned long divisor = 1;
+	char trailer = 0;
+	int n;
+
+	if (value > 1000000000UL) {
+		divisor = 100000000UL;
+		trailer = 'G';
+	} else if (value > 1000000UL) {
+		divisor = 100000UL;
+		trailer = 'M';
+	} else if (value > 1000UL) {
+		divisor = 100;
+		trailer = 'K';
+	}
+
+	value /= divisor;
+	n = sprintf(buffer, "%ld",value);
+	if (trailer) {
+		buffer[n] = trailer;
+		n++;
+		buffer[n] = 0;
+	}
+	if (divisor != 1) {
+		memmove(buffer + n - 2, buffer + n - 3, 4);
+		buffer[n-2] = '.';
+		n++;
+	}
+	return n;
+}
+
+static void decode_numa_list(int *numa, char *t)
+{
+	int node;
+	int nr;
+
+	memset(numa, 0, MAX_NODES * sizeof(int));
+
+	if (!t)
+		return;
+
+	while (*t == 'N') {
+		t++;
+		node = strtoul(t, &t, 10);
+		if (*t == '=') {
+			t++;
+			nr = strtoul(t, &t, 10);
+			numa[node] = nr;
+			if (node > highest_node)
+				highest_node = node;
+		}
+		while (*t == ' ')
+			t++;
+	}
+}
+
+static void slab_validate(struct slabinfo *s)
+{
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	set_obj(s, "validate", 1);
+}
+
+static void slab_shrink(struct slabinfo *s)
+{
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	set_obj(s, "shrink", 1);
+}
+
+int line = 0;
+
+static void first_line(void)
+{
+	if (show_activity)
+		printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL\n");
+	else
+		printf("Name                   Objects Objsize    Space "
+			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n");
+}
+
+/*
+ * Find the shortest alias of a slab
+ */
+static struct aliasinfo *find_one_alias(struct slabinfo *find)
+{
+	struct aliasinfo *a;
+	struct aliasinfo *best = NULL;
+
+	for(a = aliasinfo;a < aliasinfo + aliases; a++) {
+		if (a->slab == find &&
+			(!best || strlen(best->name) < strlen(a->name))) {
+				best = a;
+				if (strncmp(a->name,"kmall", 5) == 0)
+					return best;
+			}
+	}
+	return best;
+}
+
+static unsigned long slab_size(struct slabinfo *s)
+{
+	return 	s->slabs * (page_size << s->order);
+}
+
+static unsigned long slab_activity(struct slabinfo *s)
+{
+	return 	s->alloc_fastpath + s->free_fastpath +
+		s->alloc_slowpath + s->free_slowpath;
+}
+
+static void slab_numa(struct slabinfo *s, int mode)
+{
+	int node;
+
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	if (!highest_node) {
+		printf("\n%s: No NUMA information available.\n", s->name);
+		return;
+	}
+
+	if (skip_zero && !s->slabs)
+		return;
+
+	if (!line) {
+		printf("\n%-21s:", mode ? "NUMA nodes" : "Slab");
+		for(node = 0; node <= highest_node; node++)
+			printf(" %4d", node);
+		printf("\n----------------------");
+		for(node = 0; node <= highest_node; node++)
+			printf("-----");
+		printf("\n");
+	}
+	printf("%-21s ", mode ? "All slabs" : s->name);
+	for(node = 0; node <= highest_node; node++) {
+		char b[20];
+
+		store_size(b, s->numa[node]);
+		printf(" %4s", b);
+	}
+	printf("\n");
+	if (mode) {
+		printf("%-21s ", "Partial slabs");
+		for(node = 0; node <= highest_node; node++) {
+			char b[20];
+
+			store_size(b, s->numa_partial[node]);
+			printf(" %4s", b);
+		}
+		printf("\n");
+	}
+	line++;
+}
+
+static void show_tracking(struct slabinfo *s)
+{
+	printf("\n%s: Kernel object allocation\n", s->name);
+	printf("-----------------------------------------------------------------------\n");
+	if (read_slab_obj(s, "alloc_calls"))
+		printf("%s", buffer);
+	else
+		printf("No Data\n");
+
+	printf("\n%s: Kernel object freeing\n", s->name);
+	printf("------------------------------------------------------------------------\n");
+	if (read_slab_obj(s, "free_calls"))
+		printf("%s", buffer);
+	else
+		printf("No Data\n");
+
+}
+
+static void ops(struct slabinfo *s)
+{
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	if (read_slab_obj(s, "ops")) {
+		printf("\n%s: kmem_cache operations\n", s->name);
+		printf("--------------------------------------------\n");
+		printf("%s", buffer);
+	} else
+		printf("\n%s has no kmem_cache operations\n", s->name);
+}
+
+static const char *onoff(int x)
+{
+	if (x)
+		return "On ";
+	return "Off";
+}
+
+static void slab_stats(struct slabinfo *s)
+{
+	unsigned long total_alloc;
+	unsigned long total_free;
+	unsigned long total;
+
+	if (!s->alloc_slab)
+		return;
+
+	total_alloc = s->alloc_fastpath + s->alloc_slowpath;
+	total_free = s->free_fastpath + s->free_slowpath;
+
+	if (!total_alloc)
+		return;
+
+	printf("\n");
+	printf("Slab Perf Counter       Alloc     Free %%Al %%Fr\n");
+	printf("--------------------------------------------------\n");
+	printf("Fastpath             %8lu %8lu %3lu %3lu\n",
+		s->alloc_fastpath, s->free_fastpath,
+		s->alloc_fastpath * 100 / total_alloc,
+		s->free_fastpath * 100 / total_free);
+	printf("Slowpath             %8lu %8lu %3lu %3lu\n",
+		total_alloc - s->alloc_fastpath, s->free_slowpath,
+		(total_alloc - s->alloc_fastpath) * 100 / total_alloc,
+		s->free_slowpath * 100 / total_free);
+	printf("Page Alloc           %8lu %8lu %3lu %3lu\n",
+		s->alloc_slab, s->free_slab,
+		s->alloc_slab * 100 / total_alloc,
+		s->free_slab * 100 / total_free);
+	printf("Add partial          %8lu %8lu %3lu %3lu\n",
+		s->deactivate_to_head + s->deactivate_to_tail,
+		s->free_add_partial,
+		(s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc,
+		s->free_add_partial * 100 / total_free);
+	printf("Remove partial       %8lu %8lu %3lu %3lu\n",
+		s->alloc_from_partial, s->free_remove_partial,
+		s->alloc_from_partial * 100 / total_alloc,
+		s->free_remove_partial * 100 / total_free);
+
+	printf("Cpu partial list     %8lu %8lu %3lu %3lu\n",
+		s->cpu_partial_alloc, s->cpu_partial_free,
+		s->cpu_partial_alloc * 100 / total_alloc,
+		s->cpu_partial_free * 100 / total_free);
+
+	printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n",
+		s->deactivate_remote_frees, s->free_frozen,
+		s->deactivate_remote_frees * 100 / total_alloc,
+		s->free_frozen * 100 / total_free);
+
+	printf("Total                %8lu %8lu\n\n", total_alloc, total_free);
+
+	if (s->cpuslab_flush)
+		printf("Flushes %8lu\n", s->cpuslab_flush);
+
+	total = s->deactivate_full + s->deactivate_empty +
+			s->deactivate_to_head + s->deactivate_to_tail + s->deactivate_bypass;
+
+	if (total) {
+		printf("\nSlab Deactivation             Ocurrences  %%\n");
+		printf("-------------------------------------------------\n");
+		printf("Slab full                     %7lu  %3lu%%\n",
+			s->deactivate_full, (s->deactivate_full * 100) / total);
+		printf("Slab empty                    %7lu  %3lu%%\n",
+			s->deactivate_empty, (s->deactivate_empty * 100) / total);
+		printf("Moved to head of partial list %7lu  %3lu%%\n",
+			s->deactivate_to_head, (s->deactivate_to_head * 100) / total);
+		printf("Moved to tail of partial list %7lu  %3lu%%\n",
+			s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
+		printf("Deactivation bypass           %7lu  %3lu%%\n",
+			s->deactivate_bypass, (s->deactivate_bypass * 100) / total);
+		printf("Refilled from foreign frees   %7lu  %3lu%%\n",
+			s->alloc_refill, (s->alloc_refill * 100) / total);
+		printf("Node mismatch                 %7lu  %3lu%%\n",
+			s->alloc_node_mismatch, (s->alloc_node_mismatch * 100) / total);
+	}
+
+	if (s->cmpxchg_double_fail || s->cmpxchg_double_cpu_fail)
+		printf("\nCmpxchg_double Looping\n------------------------\n");
+		printf("Locked Cmpxchg Double redos   %lu\nUnlocked Cmpxchg Double redos %lu\n",
+			s->cmpxchg_double_fail, s->cmpxchg_double_cpu_fail);
+}
+
+static void report(struct slabinfo *s)
+{
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	printf("\nSlabcache: %-20s  Aliases: %2d Order : %2d Objects: %lu\n",
+		s->name, s->aliases, s->order, s->objects);
+	if (s->hwcache_align)
+		printf("** Hardware cacheline aligned\n");
+	if (s->cache_dma)
+		printf("** Memory is allocated in a special DMA zone\n");
+	if (s->destroy_by_rcu)
+		printf("** Slabs are destroyed via RCU\n");
+	if (s->reclaim_account)
+		printf("** Reclaim accounting active\n");
+
+	printf("\nSizes (bytes)     Slabs              Debug                Memory\n");
+	printf("------------------------------------------------------------------------\n");
+	printf("Object : %7d  Total  : %7ld   Sanity Checks : %s  Total: %7ld\n",
+			s->object_size, s->slabs, onoff(s->sanity_checks),
+			s->slabs * (page_size << s->order));
+	printf("SlabObj: %7d  Full   : %7ld   Redzoning     : %s  Used : %7ld\n",
+			s->slab_size, s->slabs - s->partial - s->cpu_slabs,
+			onoff(s->red_zone), s->objects * s->object_size);
+	printf("SlabSiz: %7d  Partial: %7ld   Poisoning     : %s  Loss : %7ld\n",
+			page_size << s->order, s->partial, onoff(s->poison),
+			s->slabs * (page_size << s->order) - s->objects * s->object_size);
+	printf("Loss   : %7d  CpuSlab: %7d   Tracking      : %s  Lalig: %7ld\n",
+			s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user),
+			(s->slab_size - s->object_size) * s->objects);
+	printf("Align  : %7d  Objects: %7d   Tracing       : %s  Lpadd: %7ld\n",
+			s->align, s->objs_per_slab, onoff(s->trace),
+			((page_size << s->order) - s->objs_per_slab * s->slab_size) *
+			s->slabs);
+
+	ops(s);
+	show_tracking(s);
+	slab_numa(s, 1);
+	slab_stats(s);
+}
+
+static void slabcache(struct slabinfo *s)
+{
+	char size_str[20];
+	char dist_str[40];
+	char flags[20];
+	char *p = flags;
+
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	if (actual_slabs == 1) {
+		report(s);
+		return;
+	}
+
+	if (skip_zero && !show_empty && !s->slabs)
+		return;
+
+	if (show_empty && s->slabs)
+		return;
+
+	store_size(size_str, slab_size(s));
+	snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
+						s->partial, s->cpu_slabs);
+
+	if (!line++)
+		first_line();
+
+	if (s->aliases)
+		*p++ = '*';
+	if (s->cache_dma)
+		*p++ = 'd';
+	if (s->hwcache_align)
+		*p++ = 'A';
+	if (s->poison)
+		*p++ = 'P';
+	if (s->reclaim_account)
+		*p++ = 'a';
+	if (s->red_zone)
+		*p++ = 'Z';
+	if (s->sanity_checks)
+		*p++ = 'F';
+	if (s->store_user)
+		*p++ = 'U';
+	if (s->trace)
+		*p++ = 'T';
+
+	*p = 0;
+	if (show_activity) {
+		unsigned long total_alloc;
+		unsigned long total_free;
+
+		total_alloc = s->alloc_fastpath + s->alloc_slowpath;
+		total_free = s->free_fastpath + s->free_slowpath;
+
+		printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d %4ld %4ld\n",
+			s->name, s->objects,
+			total_alloc, total_free,
+			total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0,
+			total_free ? (s->free_fastpath * 100 / total_free) : 0,
+			s->order_fallback, s->order, s->cmpxchg_double_fail,
+			s->cmpxchg_double_cpu_fail);
+	}
+	else
+		printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
+			s->name, s->objects, s->object_size, size_str, dist_str,
+			s->objs_per_slab, s->order,
+			s->slabs ? (s->partial * 100) / s->slabs : 100,
+			s->slabs ? (s->objects * s->object_size * 100) /
+				(s->slabs * (page_size << s->order)) : 100,
+			flags);
+}
+
+/*
+ * Analyze debug options. Return false if something is amiss.
+ */
+static int debug_opt_scan(char *opt)
+{
+	if (!opt || !opt[0] || strcmp(opt, "-") == 0)
+		return 1;
+
+	if (strcasecmp(opt, "a") == 0) {
+		sanity = 1;
+		poison = 1;
+		redzone = 1;
+		tracking = 1;
+		return 1;
+	}
+
+	for ( ; *opt; opt++)
+		switch (*opt) {
+		case 'F' : case 'f':
+			if (sanity)
+				return 0;
+			sanity = 1;
+			break;
+		case 'P' : case 'p':
+			if (poison)
+				return 0;
+			poison = 1;
+			break;
+
+		case 'Z' : case 'z':
+			if (redzone)
+				return 0;
+			redzone = 1;
+			break;
+
+		case 'U' : case 'u':
+			if (tracking)
+				return 0;
+			tracking = 1;
+			break;
+
+		case 'T' : case 't':
+			if (tracing)
+				return 0;
+			tracing = 1;
+			break;
+		default:
+			return 0;
+		}
+	return 1;
+}
+
+static int slab_empty(struct slabinfo *s)
+{
+	if (s->objects > 0)
+		return 0;
+
+	/*
+	 * We may still have slabs even if there are no objects. Shrinking will
+	 * remove them.
+	 */
+	if (s->slabs != 0)
+		set_obj(s, "shrink", 1);
+
+	return 1;
+}
+
+static void slab_debug(struct slabinfo *s)
+{
+	if (strcmp(s->name, "*") == 0)
+		return;
+
+	if (sanity && !s->sanity_checks) {
+		set_obj(s, "sanity", 1);
+	}
+	if (!sanity && s->sanity_checks) {
+		if (slab_empty(s))
+			set_obj(s, "sanity", 0);
+		else
+			fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name);
+	}
+	if (redzone && !s->red_zone) {
+		if (slab_empty(s))
+			set_obj(s, "red_zone", 1);
+		else
+			fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name);
+	}
+	if (!redzone && s->red_zone) {
+		if (slab_empty(s))
+			set_obj(s, "red_zone", 0);
+		else
+			fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name);
+	}
+	if (poison && !s->poison) {
+		if (slab_empty(s))
+			set_obj(s, "poison", 1);
+		else
+			fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name);
+	}
+	if (!poison && s->poison) {
+		if (slab_empty(s))
+			set_obj(s, "poison", 0);
+		else
+			fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name);
+	}
+	if (tracking && !s->store_user) {
+		if (slab_empty(s))
+			set_obj(s, "store_user", 1);
+		else
+			fprintf(stderr, "%s not empty cannot enable tracking\n", s->name);
+	}
+	if (!tracking && s->store_user) {
+		if (slab_empty(s))
+			set_obj(s, "store_user", 0);
+		else
+			fprintf(stderr, "%s not empty cannot disable tracking\n", s->name);
+	}
+	if (tracing && !s->trace) {
+		if (slabs == 1)
+			set_obj(s, "trace", 1);
+		else
+			fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name);
+	}
+	if (!tracing && s->trace)
+		set_obj(s, "trace", 1);
+}
+
+static void totals(void)
+{
+	struct slabinfo *s;
+
+	int used_slabs = 0;
+	char b1[20], b2[20], b3[20], b4[20];
+	unsigned long long max = 1ULL << 63;
+
+	/* Object size */
+	unsigned long long min_objsize = max, max_objsize = 0, avg_objsize;
+
+	/* Number of partial slabs in a slabcache */
+	unsigned long long min_partial = max, max_partial = 0,
+				avg_partial, total_partial = 0;
+
+	/* Number of slabs in a slab cache */
+	unsigned long long min_slabs = max, max_slabs = 0,
+				avg_slabs, total_slabs = 0;
+
+	/* Size of the whole slab */
+	unsigned long long min_size = max, max_size = 0,
+				avg_size, total_size = 0;
+
+	/* Bytes used for object storage in a slab */
+	unsigned long long min_used = max, max_used = 0,
+				avg_used, total_used = 0;
+
+	/* Waste: Bytes used for alignment and padding */
+	unsigned long long min_waste = max, max_waste = 0,
+				avg_waste, total_waste = 0;
+	/* Number of objects in a slab */
+	unsigned long long min_objects = max, max_objects = 0,
+				avg_objects, total_objects = 0;
+	/* Waste per object */
+	unsigned long long min_objwaste = max,
+				max_objwaste = 0, avg_objwaste,
+				total_objwaste = 0;
+
+	/* Memory per object */
+	unsigned long long min_memobj = max,
+				max_memobj = 0, avg_memobj,
+				total_objsize = 0;
+
+	/* Percentage of partial slabs per slab */
+	unsigned long min_ppart = 100, max_ppart = 0,
+				avg_ppart, total_ppart = 0;
+
+	/* Number of objects in partial slabs */
+	unsigned long min_partobj = max, max_partobj = 0,
+				avg_partobj, total_partobj = 0;
+
+	/* Percentage of partial objects of all objects in a slab */
+	unsigned long min_ppartobj = 100, max_ppartobj = 0,
+				avg_ppartobj, total_ppartobj = 0;
+
+
+	for (s = slabinfo; s < slabinfo + slabs; s++) {
+		unsigned long long size;
+		unsigned long used;
+		unsigned long long wasted;
+		unsigned long long objwaste;
+		unsigned long percentage_partial_slabs;
+		unsigned long percentage_partial_objs;
+
+		if (!s->slabs || !s->objects)
+			continue;
+
+		used_slabs++;
+
+		size = slab_size(s);
+		used = s->objects * s->object_size;
+		wasted = size - used;
+		objwaste = s->slab_size - s->object_size;
+
+		percentage_partial_slabs = s->partial * 100 / s->slabs;
+		if (percentage_partial_slabs > 100)
+			percentage_partial_slabs = 100;
+
+		percentage_partial_objs = s->objects_partial * 100
+							/ s->objects;
+
+		if (percentage_partial_objs > 100)
+			percentage_partial_objs = 100;
+
+		if (s->object_size < min_objsize)
+			min_objsize = s->object_size;
+		if (s->partial < min_partial)
+			min_partial = s->partial;
+		if (s->slabs < min_slabs)
+			min_slabs = s->slabs;
+		if (size < min_size)
+			min_size = size;
+		if (wasted < min_waste)
+			min_waste = wasted;
+		if (objwaste < min_objwaste)
+			min_objwaste = objwaste;
+		if (s->objects < min_objects)
+			min_objects = s->objects;
+		if (used < min_used)
+			min_used = used;
+		if (s->objects_partial < min_partobj)
+			min_partobj = s->objects_partial;
+		if (percentage_partial_slabs < min_ppart)
+			min_ppart = percentage_partial_slabs;
+		if (percentage_partial_objs < min_ppartobj)
+			min_ppartobj = percentage_partial_objs;
+		if (s->slab_size < min_memobj)
+			min_memobj = s->slab_size;
+
+		if (s->object_size > max_objsize)
+			max_objsize = s->object_size;
+		if (s->partial > max_partial)
+			max_partial = s->partial;
+		if (s->slabs > max_slabs)
+			max_slabs = s->slabs;
+		if (size > max_size)
+			max_size = size;
+		if (wasted > max_waste)
+			max_waste = wasted;
+		if (objwaste > max_objwaste)
+			max_objwaste = objwaste;
+		if (s->objects > max_objects)
+			max_objects = s->objects;
+		if (used > max_used)
+			max_used = used;
+		if (s->objects_partial > max_partobj)
+			max_partobj = s->objects_partial;
+		if (percentage_partial_slabs > max_ppart)
+			max_ppart = percentage_partial_slabs;
+		if (percentage_partial_objs > max_ppartobj)
+			max_ppartobj = percentage_partial_objs;
+		if (s->slab_size > max_memobj)
+			max_memobj = s->slab_size;
+
+		total_partial += s->partial;
+		total_slabs += s->slabs;
+		total_size += size;
+		total_waste += wasted;
+
+		total_objects += s->objects;
+		total_used += used;
+		total_partobj += s->objects_partial;
+		total_ppart += percentage_partial_slabs;
+		total_ppartobj += percentage_partial_objs;
+
+		total_objwaste += s->objects * objwaste;
+		total_objsize += s->objects * s->slab_size;
+	}
+
+	if (!total_objects) {
+		printf("No objects\n");
+		return;
+	}
+	if (!used_slabs) {
+		printf("No slabs\n");
+		return;
+	}
+
+	/* Per slab averages */
+	avg_partial = total_partial / used_slabs;
+	avg_slabs = total_slabs / used_slabs;
+	avg_size = total_size / used_slabs;
+	avg_waste = total_waste / used_slabs;
+
+	avg_objects = total_objects / used_slabs;
+	avg_used = total_used / used_slabs;
+	avg_partobj = total_partobj / used_slabs;
+	avg_ppart = total_ppart / used_slabs;
+	avg_ppartobj = total_ppartobj / used_slabs;
+
+	/* Per object object sizes */
+	avg_objsize = total_used / total_objects;
+	avg_objwaste = total_objwaste / total_objects;
+	avg_partobj = total_partobj * 100 / total_objects;
+	avg_memobj = total_objsize / total_objects;
+
+	printf("Slabcache Totals\n");
+	printf("----------------\n");
+	printf("Slabcaches : %3d      Aliases  : %3d->%-3d Active: %3d\n",
+			slabs, aliases, alias_targets, used_slabs);
+
+	store_size(b1, total_size);store_size(b2, total_waste);
+	store_size(b3, total_waste * 100 / total_used);
+	printf("Memory used: %6s   # Loss   : %6s   MRatio:%6s%%\n", b1, b2, b3);
+
+	store_size(b1, total_objects);store_size(b2, total_partobj);
+	store_size(b3, total_partobj * 100 / total_objects);
+	printf("# Objects  : %6s   # PartObj: %6s   ORatio:%6s%%\n", b1, b2, b3);
+
+	printf("\n");
+	printf("Per Cache    Average         Min         Max       Total\n");
+	printf("---------------------------------------------------------\n");
+
+	store_size(b1, avg_objects);store_size(b2, min_objects);
+	store_size(b3, max_objects);store_size(b4, total_objects);
+	printf("#Objects  %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_slabs);store_size(b2, min_slabs);
+	store_size(b3, max_slabs);store_size(b4, total_slabs);
+	printf("#Slabs    %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_partial);store_size(b2, min_partial);
+	store_size(b3, max_partial);store_size(b4, total_partial);
+	printf("#PartSlab %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+	store_size(b1, avg_ppart);store_size(b2, min_ppart);
+	store_size(b3, max_ppart);
+	store_size(b4, total_partial * 100  / total_slabs);
+	printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_partobj);store_size(b2, min_partobj);
+	store_size(b3, max_partobj);
+	store_size(b4, total_partobj);
+	printf("PartObjs  %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
+	store_size(b3, max_ppartobj);
+	store_size(b4, total_partobj * 100 / total_objects);
+	printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_size);store_size(b2, min_size);
+	store_size(b3, max_size);store_size(b4, total_size);
+	printf("Memory    %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_used);store_size(b2, min_used);
+	store_size(b3, max_used);store_size(b4, total_used);
+	printf("Used      %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+
+	store_size(b1, avg_waste);store_size(b2, min_waste);
+	store_size(b3, max_waste);store_size(b4, total_waste);
+	printf("Loss      %10s  %10s  %10s  %10s\n",
+			b1,	b2,	b3,	b4);
+
+	printf("\n");
+	printf("Per Object   Average         Min         Max\n");
+	printf("---------------------------------------------\n");
+
+	store_size(b1, avg_memobj);store_size(b2, min_memobj);
+	store_size(b3, max_memobj);
+	printf("Memory    %10s  %10s  %10s\n",
+			b1,	b2,	b3);
+	store_size(b1, avg_objsize);store_size(b2, min_objsize);
+	store_size(b3, max_objsize);
+	printf("User      %10s  %10s  %10s\n",
+			b1,	b2,	b3);
+
+	store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
+	store_size(b3, max_objwaste);
+	printf("Loss      %10s  %10s  %10s\n",
+			b1,	b2,	b3);
+}
+
+static void sort_slabs(void)
+{
+	struct slabinfo *s1,*s2;
+
+	for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) {
+		for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
+			int result;
+
+			if (sort_size)
+				result = slab_size(s1) < slab_size(s2);
+			else if (sort_active)
+				result = slab_activity(s1) < slab_activity(s2);
+			else
+				result = strcasecmp(s1->name, s2->name);
+
+			if (show_inverted)
+				result = -result;
+
+			if (result > 0) {
+				struct slabinfo t;
+
+				memcpy(&t, s1, sizeof(struct slabinfo));
+				memcpy(s1, s2, sizeof(struct slabinfo));
+				memcpy(s2, &t, sizeof(struct slabinfo));
+			}
+		}
+	}
+}
+
+static void sort_aliases(void)
+{
+	struct aliasinfo *a1,*a2;
+
+	for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) {
+		for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) {
+			char *n1, *n2;
+
+			n1 = a1->name;
+			n2 = a2->name;
+			if (show_alias && !show_inverted) {
+				n1 = a1->ref;
+				n2 = a2->ref;
+			}
+			if (strcasecmp(n1, n2) > 0) {
+				struct aliasinfo t;
+
+				memcpy(&t, a1, sizeof(struct aliasinfo));
+				memcpy(a1, a2, sizeof(struct aliasinfo));
+				memcpy(a2, &t, sizeof(struct aliasinfo));
+			}
+		}
+	}
+}
+
+static void link_slabs(void)
+{
+	struct aliasinfo *a;
+	struct slabinfo *s;
+
+	for (a = aliasinfo; a < aliasinfo + aliases; a++) {
+
+		for (s = slabinfo; s < slabinfo + slabs; s++)
+			if (strcmp(a->ref, s->name) == 0) {
+				a->slab = s;
+				s->refs++;
+				break;
+			}
+		if (s == slabinfo + slabs)
+			fatal("Unresolved alias %s\n", a->ref);
+	}
+}
+
+static void alias(void)
+{
+	struct aliasinfo *a;
+	char *active = NULL;
+
+	sort_aliases();
+	link_slabs();
+
+	for(a = aliasinfo; a < aliasinfo + aliases; a++) {
+
+		if (!show_single_ref && a->slab->refs == 1)
+			continue;
+
+		if (!show_inverted) {
+			if (active) {
+				if (strcmp(a->slab->name, active) == 0) {
+					printf(" %s", a->name);
+					continue;
+				}
+			}
+			printf("\n%-12s <- %s", a->slab->name, a->name);
+			active = a->slab->name;
+		}
+		else
+			printf("%-20s -> %s\n", a->name, a->slab->name);
+	}
+	if (active)
+		printf("\n");
+}
+
+
+static void rename_slabs(void)
+{
+	struct slabinfo *s;
+	struct aliasinfo *a;
+
+	for (s = slabinfo; s < slabinfo + slabs; s++) {
+		if (*s->name != ':')
+			continue;
+
+		if (s->refs > 1 && !show_first_alias)
+			continue;
+
+		a = find_one_alias(s);
+
+		if (a)
+			s->name = a->name;
+		else {
+			s->name = "*";
+			actual_slabs--;
+		}
+	}
+}
+
+static int slab_mismatch(char *slab)
+{
+	return regexec(&pattern, slab, 0, NULL, 0);
+}
+
+static void read_slab_dir(void)
+{
+	DIR *dir;
+	struct dirent *de;
+	struct slabinfo *slab = slabinfo;
+	struct aliasinfo *alias = aliasinfo;
+	char *p;
+	char *t;
+	int count;
+
+	if (chdir("/sys/kernel/slab") && chdir("/sys/slab"))
+		fatal("SYSFS support for SLUB not active\n");
+
+	dir = opendir(".");
+	while ((de = readdir(dir))) {
+		if (de->d_name[0] == '.' ||
+			(de->d_name[0] != ':' && slab_mismatch(de->d_name)))
+				continue;
+		switch (de->d_type) {
+		   case DT_LNK:
+			alias->name = strdup(de->d_name);
+			count = readlink(de->d_name, buffer, sizeof(buffer)-1);
+
+			if (count < 0)
+				fatal("Cannot read symlink %s\n", de->d_name);
+
+			buffer[count] = 0;
+			p = buffer + count;
+			while (p > buffer && p[-1] != '/')
+				p--;
+			alias->ref = strdup(p);
+			alias++;
+			break;
+		   case DT_DIR:
+			if (chdir(de->d_name))
+				fatal("Unable to access slab %s\n", slab->name);
+			slab->name = strdup(de->d_name);
+			slab->alias = 0;
+			slab->refs = 0;
+			slab->aliases = get_obj("aliases");
+			slab->align = get_obj("align");
+			slab->cache_dma = get_obj("cache_dma");
+			slab->cpu_slabs = get_obj("cpu_slabs");
+			slab->destroy_by_rcu = get_obj("destroy_by_rcu");
+			slab->hwcache_align = get_obj("hwcache_align");
+			slab->object_size = get_obj("object_size");
+			slab->objects = get_obj("objects");
+			slab->objects_partial = get_obj("objects_partial");
+			slab->objects_total = get_obj("objects_total");
+			slab->objs_per_slab = get_obj("objs_per_slab");
+			slab->order = get_obj("order");
+			slab->partial = get_obj("partial");
+			slab->partial = get_obj_and_str("partial", &t);
+			decode_numa_list(slab->numa_partial, t);
+			free(t);
+			slab->poison = get_obj("poison");
+			slab->reclaim_account = get_obj("reclaim_account");
+			slab->red_zone = get_obj("red_zone");
+			slab->sanity_checks = get_obj("sanity_checks");
+			slab->slab_size = get_obj("slab_size");
+			slab->slabs = get_obj_and_str("slabs", &t);
+			decode_numa_list(slab->numa, t);
+			free(t);
+			slab->store_user = get_obj("store_user");
+			slab->trace = get_obj("trace");
+			slab->alloc_fastpath = get_obj("alloc_fastpath");
+			slab->alloc_slowpath = get_obj("alloc_slowpath");
+			slab->free_fastpath = get_obj("free_fastpath");
+			slab->free_slowpath = get_obj("free_slowpath");
+			slab->free_frozen= get_obj("free_frozen");
+			slab->free_add_partial = get_obj("free_add_partial");
+			slab->free_remove_partial = get_obj("free_remove_partial");
+			slab->alloc_from_partial = get_obj("alloc_from_partial");
+			slab->alloc_slab = get_obj("alloc_slab");
+			slab->alloc_refill = get_obj("alloc_refill");
+			slab->free_slab = get_obj("free_slab");
+			slab->cpuslab_flush = get_obj("cpuslab_flush");
+			slab->deactivate_full = get_obj("deactivate_full");
+			slab->deactivate_empty = get_obj("deactivate_empty");
+			slab->deactivate_to_head = get_obj("deactivate_to_head");
+			slab->deactivate_to_tail = get_obj("deactivate_to_tail");
+			slab->deactivate_remote_frees = get_obj("deactivate_remote_frees");
+			slab->order_fallback = get_obj("order_fallback");
+			slab->cmpxchg_double_cpu_fail = get_obj("cmpxchg_double_cpu_fail");
+			slab->cmpxchg_double_fail = get_obj("cmpxchg_double_fail");
+			slab->cpu_partial_alloc = get_obj("cpu_partial_alloc");
+			slab->cpu_partial_free = get_obj("cpu_partial_free");
+			slab->alloc_node_mismatch = get_obj("alloc_node_mismatch");
+			slab->deactivate_bypass = get_obj("deactivate_bypass");
+			chdir("..");
+			if (slab->name[0] == ':')
+				alias_targets++;
+			slab++;
+			break;
+		   default :
+			fatal("Unknown file type %lx\n", de->d_type);
+		}
+	}
+	closedir(dir);
+	slabs = slab - slabinfo;
+	actual_slabs = slabs;
+	aliases = alias - aliasinfo;
+	if (slabs > MAX_SLABS)
+		fatal("Too many slabs\n");
+	if (aliases > MAX_ALIASES)
+		fatal("Too many aliases\n");
+}
+
+static void output_slabs(void)
+{
+	struct slabinfo *slab;
+
+	for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
+
+		if (slab->alias)
+			continue;
+
+
+		if (show_numa)
+			slab_numa(slab, 0);
+		else if (show_track)
+			show_tracking(slab);
+		else if (validate)
+			slab_validate(slab);
+		else if (shrink)
+			slab_shrink(slab);
+		else if (set_debug)
+			slab_debug(slab);
+		else if (show_ops)
+			ops(slab);
+		else if (show_slab)
+			slabcache(slab);
+		else if (show_report)
+			report(slab);
+	}
+}
+
+struct option opts[] = {
+	{ "aliases", 0, NULL, 'a' },
+	{ "activity", 0, NULL, 'A' },
+	{ "debug", 2, NULL, 'd' },
+	{ "display-activity", 0, NULL, 'D' },
+	{ "empty", 0, NULL, 'e' },
+	{ "first-alias", 0, NULL, 'f' },
+	{ "help", 0, NULL, 'h' },
+	{ "inverted", 0, NULL, 'i'},
+	{ "numa", 0, NULL, 'n' },
+	{ "ops", 0, NULL, 'o' },
+	{ "report", 0, NULL, 'r' },
+	{ "shrink", 0, NULL, 's' },
+	{ "slabs", 0, NULL, 'l' },
+	{ "track", 0, NULL, 't'},
+	{ "validate", 0, NULL, 'v' },
+	{ "zero", 0, NULL, 'z' },
+	{ "1ref", 0, NULL, '1'},
+	{ NULL, 0, NULL, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+	int c;
+	int err;
+	char *pattern_source;
+
+	page_size = getpagesize();
+
+	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
+						opts, NULL)) != -1)
+		switch (c) {
+		case '1':
+			show_single_ref = 1;
+			break;
+		case 'a':
+			show_alias = 1;
+			break;
+		case 'A':
+			sort_active = 1;
+			break;
+		case 'd':
+			set_debug = 1;
+			if (!debug_opt_scan(optarg))
+				fatal("Invalid debug option '%s'\n", optarg);
+			break;
+		case 'D':
+			show_activity = 1;
+			break;
+		case 'e':
+			show_empty = 1;
+			break;
+		case 'f':
+			show_first_alias = 1;
+			break;
+		case 'h':
+			usage();
+			return 0;
+		case 'i':
+			show_inverted = 1;
+			break;
+		case 'n':
+			show_numa = 1;
+			break;
+		case 'o':
+			show_ops = 1;
+			break;
+		case 'r':
+			show_report = 1;
+			break;
+		case 's':
+			shrink = 1;
+			break;
+		case 'l':
+			show_slab = 1;
+			break;
+		case 't':
+			show_track = 1;
+			break;
+		case 'v':
+			validate = 1;
+			break;
+		case 'z':
+			skip_zero = 0;
+			break;
+		case 'T':
+			show_totals = 1;
+			break;
+		case 'S':
+			sort_size = 1;
+			break;
+
+		default:
+			fatal("%s: Invalid option '%c'\n", argv[0], optopt);
+
+	}
+
+	if (!show_slab && !show_alias && !show_track && !show_report
+		&& !validate && !shrink && !set_debug && !show_ops)
+			show_slab = 1;
+
+	if (argc > optind)
+		pattern_source = argv[optind];
+	else
+		pattern_source = ".*";
+
+	err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB);
+	if (err)
+		fatal("%s: Invalid pattern '%s' code %d\n",
+			argv[0], pattern_source, err);
+	read_slab_dir();
+	if (show_alias)
+		alias();
+	else
+	if (show_totals)
+		totals();
+	else {
+		link_slabs();
+		rename_slabs();
+		sort_slabs();
+		output_slabs();
+	}
+	return 0;
+}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index a91f980..51ca2ad 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -289,15 +289,15 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
 	 */
 	idx = srcu_read_lock(&kvm->srcu);
 	spin_lock(&kvm->mmu_lock);
+
 	kvm->mmu_notifier_seq++;
 	need_tlb_flush = kvm_unmap_hva(kvm, address) | kvm->tlbs_dirty;
-	spin_unlock(&kvm->mmu_lock);
-	srcu_read_unlock(&kvm->srcu, idx);
-
 	/* we've to flush the tlb before the pages can be freed */
 	if (need_tlb_flush)
 		kvm_flush_remote_tlbs(kvm);
 
+	spin_unlock(&kvm->mmu_lock);
+	srcu_read_unlock(&kvm->srcu, idx);
 }
 
 static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
@@ -335,12 +335,12 @@ static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
 	for (; start < end; start += PAGE_SIZE)
 		need_tlb_flush |= kvm_unmap_hva(kvm, start);
 	need_tlb_flush |= kvm->tlbs_dirty;
-	spin_unlock(&kvm->mmu_lock);
-	srcu_read_unlock(&kvm->srcu, idx);
-
 	/* we've to flush the tlb before the pages can be freed */
 	if (need_tlb_flush)
 		kvm_flush_remote_tlbs(kvm);
+
+	spin_unlock(&kvm->mmu_lock);
+	srcu_read_unlock(&kvm->srcu, idx);
 }
 
 static void kvm_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn,
@@ -378,13 +378,14 @@ static int kvm_mmu_notifier_clear_flush_young(struct mmu_notifier *mn,
 
 	idx = srcu_read_lock(&kvm->srcu);
 	spin_lock(&kvm->mmu_lock);
-	young = kvm_age_hva(kvm, address);
-	spin_unlock(&kvm->mmu_lock);
-	srcu_read_unlock(&kvm->srcu, idx);
 
+	young = kvm_age_hva(kvm, address);
 	if (young)
 		kvm_flush_remote_tlbs(kvm);
 
+	spin_unlock(&kvm->mmu_lock);
+	srcu_read_unlock(&kvm->srcu, idx);
+
 	return young;
 }
 
